diff --git a/dist/assets/css/all.css b/dist/assets/css/all.css new file mode 100644 index 0000000000..59bca3d6de --- /dev/null +++ b/dist/assets/css/all.css @@ -0,0 +1,4 @@ +/*! normalize.css v1.1.0 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}button,html,input,select,textarea{font-family:sans-serif}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ol,nav ul{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure,form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0} +;code[class*=language-],pre[class*=language-],textarea{color:#222;font-family:Inconsolata,Consolas,Monaco,Andale Mono,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;font-size:1em!important}pre[class*=language-]{position:relative;padding:.5em 1em;margin:.5em 0 0 -.5em;border-left:.5em solid #afafaf;background-color:#fff;background-image:-webkit-linear-gradient(transparent 50%,rgba(69,142,209,.06) 0);background-image:-o-linear-gradient(transparent 50%,rgba(69,142,209,.06) 50%);background-image:-webkit-gradient(linear,left top,left bottom,color-stop(50%,transparent),color-stop(50%,rgba(69,142,209,.06)));background-image:linear-gradient(transparent 50%,rgba(69,142,209,.06) 0);-webkit-background-size:2.9em 2.9em;background-size:2.9em 2.9em;-webkit-background-origin:content-box;background-origin:content-box;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{margin-bottom:1em}:not(pre)>code[class*=language-]{position:relative;padding:.2em;border-radius:.3em;color:#333;border:1px solid rgba(0,0,0,.1)}:not(pre)>code[class*=language-]:after,pre[class*=language-]:after{right:.75em;left:auto}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#a0a0a0}.token.punctuation{color:#666}.token.boolean,.token.constant,.token.function-name,.token.number,.token.property,.token.symbol,.token.tag{color:#dc3787}.token.attr-name,.token.builtin,.token.function,.token.selector,.token.string{color:#00a1d3}.token.entity,.token.operator,.token.url,.token.variable{color:#a67f59;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.class-name,.token.keyword{color:#704f21}.token.important,.token.regex{color:#e90}.language-css .token.string,.style .token.string{color:#a67f59;background:hsla(0,0%,100%,.5)}.token.important{font-weight:400}.token.entity{cursor:help}.namespace{opacity:.7}@media screen and (max-width:767px){pre[class*=language-]:after,pre[class*=language-]:before{bottom:14px;-webkit-box-shadow:none;box-shadow:none}}.token.cr:before,.token.lf:before,.token.tab:not(:empty):before{color:#e0d7d1}pre.line-numbers{padding-left:3.8em;counter-reset:linenumber}pre.line-numbers,pre.line-numbers>code{position:relative}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows>span{pointer-events:none;display:block;counter-increment:linenumber}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right} +;button,html,input,select{color:#222}textarea{line-height:1.45em;padding:.5em 1em;border:none}body{font-size:1em;line-height:1.4}::-moz-selection{background:#b3d4fc;text-shadow:none}::selection{background:#b3d4fc;text-shadow:none}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}img{vertical-align:middle}img.med_left{width:300px;float:left}img.med_right{width:300px;float:right}img.small_left{width:200px;float:left}img.smaller_left{width:140px;float:left}img.small_right{width:200px;float:right}img.smaller_right{width:140px;float:right}img.small_center{width:200px;margin-left:250px}img.small{width:160px}img.med{width:400px}img.med_center{width:400px;margin-left:150px}fieldset{border:0;margin:0;padding:0}textarea{resize:vertical}.tagline{display:none}#home-page .home{pointer-events:none}#home-page .home a{pointer-events:all}#lockup>a{position:relative;display:block;width:200px;height:90px}#logo_image{position:absolute;top:0}#menu,#menu.top_menu{list-style:none;font-family:Montserrat,sans-serif;width:100%;margin:0 0 1em;padding:0;height:100%;font-size:1.3em}#menu.top_menu li{display:inline}#home-sketch{position:absolute;top:0;left:0;z-index:-2}@media screen and (max-width:780px){.sidebar-menu{clear:both;max-height:0;-webkit-transition:max-height .4s ease-out;-o-transition:max-height .4s ease-out;transition:max-height .4s ease-out;overflow:hidden}.sidebar-menu-nav-element{width:91vw}.sidebar-menu a{display:block;text-align:center;padding-bottom:.11em;border-bottom:.11em dashed transparent}.sidebar-menu-icon{top:2rem;cursor:pointer;float:right;padding:28px 20px;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;margin-bottom:5rem}.sidebar-menu-icon .sidebar-nav-icon{background:#ed225d;display:block;height:2px;position:relative;-webkit-transition:background .4s ease-out;-o-transition:background .4s ease-out;transition:background .4s ease-out;width:18px}.sidebar-menu-icon .sidebar-nav-icon:after,.sidebar-menu-icon .sidebar-nav-icon:before{background:#ed225d;content:"";display:block;height:100%;position:absolute;-webkit-transition:all .4s ease-out;-o-transition:all .4s ease-out;transition:all .4s ease-out;width:100%}.sidebar-menu-icon .sidebar-nav-icon:before{top:5px}.sidebar-menu-icon .sidebar-nav-icon:after{top:-5px}.sidebar-menu-btn{display:none}.sidebar-menu-btn:checked~.sidebar-menu{max-height:475px}.sidebar-menu-btn:checked~.sidebar-menu-icon .sidebar-nav-icon{background:transparent}.sidebar-menu-btn:checked~.sidebar-menu-icon .sidebar-nav-icon:before{-webkit-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg);top:0}.sidebar-menu-btn:checked~.sidebar-menu-icon .sidebar-nav-icon:after{-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg);top:0}}.sidebar-menu-btn{display:none}#home-sketch-frame{position:fixed;width:100%;height:100%;left:0;top:0;z-index:-2;overflow:hidden;pointer-events:all;border:0}#credits{position:fixed;bottom:0;left:0;z-index:2;padding:1em;font-size:.7em}#skip-to-content{position:absolute;left:0;top:40px;z-index:5;background-color:#ed225d;color:#fff;width:auto;height:50px;border:none;outline-style:none;text-align:center;font-size:25px;padding:5px;opacity:0}#skip-to-content:focus{opacity:1}.button_box{padding:.4em .6em;margin:.5em 0;font-family:Montserrat,sans-serif;display:inline-block}.button_box,.download_box{border:1px solid #ed225d;color:#333}.download_box{padding:.4em;margin:0 1.75em 0 0;width:18.65em;float:left;height:7.45em;position:relative}.button_box:hover,.download_box:hover{border:1px solid #ed225d;background:#ed225d;color:#fff}.download_box.half_box{width:10.83em;margin-right:1.75em;float:left}.download_box.half_box.last_box{margin-right:0}.download_box .download_name{font-size:1em;margin:0;padding-bottom:.3em;border-bottom:.09em dashed #ed225d;line-height:1.2;font-family:Montserrat,sans-serif;display:block}.download_box:hover .download_name{-webkit-text-stroke-width:0;border-bottom-color:#fff}.download_box p{font-size:.65em;margin:0;position:absolute;bottom:1em}.download_box svg{height:.65em;width:.65em;position:absolute;bottom:3.5em}.download_box:hover svg{fill:#fff}.download_box h4+p{display:block}#download-page .link_group{width:100%;margin-bottom:3em}.download_box{margin-top:1em}.support div.download_box{margin-top:1em;margin-bottom:1em}#download-page .support p{font-size:.8em;position:static;margin-top:.3em}#slideshow{margin:1em 0}#slideshow p{font-size:.8em;color:#ababab;line-height:1.2em;margin-top:.5em}.extra{color:#fff;position:absolute;bottom:.65em;right:.9em;font-weight:700;-ms-transform:rotate(-12deg);-webkit-transform:rotate(-12deg);-o-transform:rotate(-12deg);transform:rotate(-12deg);font-size:.8em}#get-started-page .edit_space{position:relative;-webkit-box-ordinal-group:4;-webkit-order:3;-ms-flex-order:3;order:3;margin-bottom:4.8125em}#get-started-page .edit_space .copy_button{color:#2d7bb6;border-color:rgba(45,123,182,.25);float:right;margin:1.5em 0 1.5em .5em;background:hsla(0,0%,100%,.7);position:absolute;z-index:2;left:31.33em;top:-1.5em}@media (max-width:780px){#get-started-page .edit_space .copy_button{left:6.44em}}@media (max-width:600px){#get-started-page .edit_space .copy_button{left:5.91em}}#examples-page .column{margin-bottom:2em}#reference-page main h1{float:left}.reference-group h2{font-size:1.5em}.reference-group h3{font-size:1em;font-family:Montserrat,sans-serif;margin-top:.5em}div.reference-group{display:inline-block}div.reference-subgroups{margin:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}div.reference-subgroup{width:11em;margin-bottom:1em}#reference-page .params table p{display:inline;font-size:inherit}#reference-page .param-optional{color:#afafaf}#item{width:100%}#item h2{margin:.777em 0 0;font-size:1.444em;font-weight:inherit;font-family:Inconsolata,consolas,monospace;color:#00a1d3}#item h3{font-size:1.33em;margin:1em 0 0}#item ul{margin-top:.5em}#item li{margin-bottom:1em}.description{clear:both;display:block;width:100%}.syntax pre{width:100%}.item-wrapper,.list-wrapper{float:left;outline:none}.paramname{display:inline-block;min-width:25%;margin-right:1%;font-size:1.2em}.paramtype p{display:inline;font-size:1em}.paramtype{font-size:1.2em;width:73%;vertical-align:top}#library-page .group-name,.paramtype{display:inline-block}#library-page .group-name:hover{color:#ed225d}.example div{position:relative}.example-content .example_code{position:relative;left:1em;padding-top:0;margin-top:1rem;border:none;width:30.5em;max-width:100%}.example-content .example_code.norender{left:0;margin-left:0}.example-content .edit_space{position:absolute;top:0;left:0;margin-top:-.5em;width:100%;pointer-events:none}.example-content .edit_space *{pointer-events:auto}.example-content .edit_space ul{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;position:relative;pointer-events:none}.example-content .edit_space ul li button{font-family:Montserrat,sans-serif;font-size:1em;color:#ccc;border:1px solid hsla(0,0%,78.4%,.15);background:transparent;outline:none;margin-top:.25em}.example-content .edit_space ul li button:hover,.example_container.editing ul li button{color:#2d7bb6;border-color:rgba(45,123,182,.25)}.example-content .edit_space .edit_area{position:absolute;top:.5em;left:120px;width:30.5em;display:none;font-family:monospace;padding:1.5em .5em .5em;font-size:15pt}.display_button{margin-bottom:2em;font-family:Montserrat,sans-serif;font-size:1em;color:#2d7bb6;border:1px solid rgba(45,123,182,.25);background:transparent;outline:none}.example-content .example_container{width:36em;max-width:100%;border-top:.09em dashed #333;padding-top:.5em;margin-top:2em;min-height:120px;height:-webkit-calc(110% + 20px);height:calc(110% + 20px);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.example-content .example_container:first-of-type{margin-top:1em}@media (max-width:600px){.example-content .example_code{margin-top:.2rem;left:.5rem}.example-content .example_container{width:100%;min-height:220px;height:-webkit-calc(110% + 120px);height:calc(110% + 120px);display:block}.example-content .edit_space .edit_area{top:-webkit-calc(120px + 1em);top:calc(120px + 1em);left:0;width:100%;padding:.5em}.example_container button{top:124px}.description{margin-top:3rem}.edit_button{left:0}.reset_button{left:2.58em}.copy_button{left:5.91em}}form{pointer-events:all}#search_button{background:url(../img/search.png) 100% no-repeat}#search input[type=search],#search input[type=text]{border:1px solid hsla(0,0%,78.4%,.5);font-family:Montserrat,sans-serif;font-size:2.25em;width:9.75em}#search .twitter-typeahead .tt-hint,#search ::-webkit-input-placeholder{color:#ccc}:-moz-placeholder,:-ms-input-placeholder,::-moz-placeholder{color:#ccc}#search input[type=text]:focus{color:#2d7bb6;outline-color:#2d7bb6;outline-width:1px;outline-style:solid}#search .twitter-typeahead .tt-dropdown-menu{background-color:#fff}#search .twitter-typeahead .tt-suggestion.tt-cursor{color:#333;background-color:#eee}#search .twitter-typeahead .tt-suggestion p{margin:0}#search .twitter-typeahead .tt-suggestion p .small{font-size:12px;color:#666}#search{float:right}#search .twitter-typeahead .tt-dropdown-menu{border:1px solid rgba(0,0,0,.2);padding:.5em;max-height:200px;overflow-y:auto;font-size:1em;line-height:1.4em}#search .twitter-typeahead .tt-suggestion{padding:3px 20px;line-height:24px;cursor:pointer}#search .twitter-typeahead .empty-message{padding:8px 20px 1px;font-size:14px;line-height:24px}#search_button{float:right}a.code.core{color:#333}a.code.addon{color:#704f21}#contribute-item{font-size:.75em;text-align:left;display:inline-block;width:320px;height:250px;float:left;border:1px solid #ed225d;margin:0 25px 25px 0;position:relative}.contribute-item-container{position:absolute;z-index:20;margin:0;padding:10px}.container{height:100px;position:relative;background:#fff;margin-top:1.5em}#infoi,#navi{width:100%;height:100%;position:absolute;top:0;left:0}#infoi{z-index:10}h3.contribute-title{font-size:1.33em;margin:0 0 27px;padding-bottom:.3em;border-bottom:.09em dashed #ed225d}.label{position:relative}.label .nounderline img{margin:.5em 0 0}.label h3{color:#fff;position:absolute;top:0;margin:1em}.label:hover h3{color:#ed225d}h3{font-size:1.33em;margin:1em 0 0}.bullet-list{padding:0 0 0 40px;list-style:disc}#libraries-page .label h3{background-color:#000;padding:0 5px}#learn-page .label .nounderline img{height:-webkit-fit-content;height:-moz-fit-content;height:fit-content}#learn-page .info{display:inline-block}#exampleDisplay,#exampleEditor,#exampleFrame{width:36em;border:none}#exampleDisplay{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-flow:column;-ms-flex-flow:column;flex-flow:column}#popupExampleFrame{position:fixed;top:0;left:0;right:0;bottom:0;z-index:1000;border:none}#exampleDisplay button{color:#2d7bb6;border-color:rgba(45,123,182,.25);float:right;margin:.5em 0 0 .5em;background:hsla(0,0%,100%,.7);position:absolute;left:0;z-index:2}#exampleDisplay .edit_button{left:25.42em;top:-2.5em}#exampleDisplay .reset_button{left:28em;top:-2.5em}#exampleDisplay .copy_button{left:31.33em;top:-2.5em}#exampleDisplay button:hover{background:#fff}#exampleDisplay .edit_space{position:relative;-webkit-box-ordinal-group:4;-webkit-order:3;-ms-flex-order:3;order:3}#exampleDisplay #exampleFrame{height:22em;-webkit-box-ordinal-group:3;-webkit-order:2;-ms-flex-order:2;order:2}#exampleDisplay #exampleEditor{height:500em;width:710px;overflow:hidden;margin-top:.5em;color:#222;font-family:Inconsolata,consolas,monospace;font-size:1em;background-color:#fff;line-height:1em;-webkit-box-ordinal-group:5;-webkit-order:4;-ms-flex-order:4;order:4}#exampleDisplay #exampleEditor .ace_gutter-cell{background-image:none;padding-left:10px;overflow:hidden;background-color:#afafaf}#exampleDisplay #exampleEditor .ace_gutter-cell.ace_info{background-color:#d7e5f5}#exampleDisplay #exampleEditor .ace_gutter-cell.ace_warning{background-color:gold;color:#fff}#exampleDisplay #exampleEditor .ace_gutter-cell.ace_error{background-color:tomato;color:#fff}#exampleDisplay #exampleEditor .ace_numeric,#exampleDisplay #exampleEditor .ace_tag{color:#dc3787}#exampleDisplay #exampleEditor .ace_attribute-name,#exampleDisplay #exampleEditor .ace_class,#exampleDisplay #exampleEditor .ace_type{color:#704f21}#exampleDisplay #exampleEditor .ace_function,#exampleDisplay #exampleEditor .ace_keyword,#exampleDisplay #exampleEditor .ace_support{color:#00a1d3}#exampleDisplay #exampleEditor .ace_comment{color:#a0a0a0}#exampleDisplay #exampleEditor .ace_string{color:#a67f59}#exampleDisplay #exampleEditor .ace_operator{color:#333}#exampleDisplay #exampleEditor .ace_regexp{color:#e90}#exampleDisplay #exampleEditor .ace-gutter,#exampleDisplay #exampleEditor .ace-gutter-layer{color:#333}#exampleDisplay #exampleEditor .ace_folding-enabled{width:10px!important;color:#333}.attribution{background-color:#eee;font-size:15px;padding:10px;margin:30px 0}#featuring{margin-bottom:1em}#showcase-page .showcase-intro h1{font:italic 900 14.5vw Montserrat,sans-serif;color:#ed225d;text-align:left;text-transform:uppercase}#showcase-page .showcase-intro p{font:400 1.4rem Montserrat,sans-serif;line-height:1.5em}#showcase-page .project-page h2,#showcase-page .showcase-featured h2{font:italic 900 2rem Montserrat,sans-serif;color:#ed225d;letter-spacing:.05rem}#showcase-page ul.left-column,#showcase-page ul.links,#showcase-page ul.project-tags,#showcase-page ul.right-column{list-style:none}#showcase-page img[alt]{font-size:.9rem}#showcase-page .showcase-featured{margin-top:15%}#showcase-page .showcase-featured h3.title{font:italic 900 1rem Montserrat,sans-serif}#showcase-page .showcase-featured p.credit{font:500 1rem Montserrat,sans-serif}#showcase-page .showcase-featured p.description{font-size:1em;margin-bottom:.5rem}#showcase-page .nominate{margin-top:1.5em;display:inline-block}#showcase-page .nominate a,#showcase-page .nominate a:visited{padding:.4em .5em;position:relative;top:0;left:0;border:2px solid #ed225d;-webkit-box-shadow:4px 4px 0 #ed225d;box-shadow:4px 4px 0 #ed225d;font:1.5rem Montserrat,sans-serif;color:#ed225d;letter-spacing:.02rem;-webkit-transition:all .3s;-o-transition:all .3s;transition:all .3s}@media (max-width:500px){#showcase-page .nominate a,#showcase-page .nominate a:visited{padding:.4em .3em;font:1.3rem Montserrat,sans-serif}}#showcase-page .nominate a:hover{top:4px;left:4px;-webkit-box-shadow:none;box-shadow:none}#showcase-page .showcase-featured a,#showcase-page .showcase-featured a:visited{font-size:1.2rem;color:#ed225d;letter-spacing:.02rem;line-height:1.5}#showcase-page .showcase-featured a:after{content:" →"}#showcase-page .showcase-featured a.tag:after{content:""}#showcase-page .showcase-featured .no-arrow-link:after{content:" "}#showcase-page .showcase-featured .no-arrow-link:hover{text-decoration:none;padding:none;border:none}.project-info{margin-top:1em}ul.project-tags a{line-height:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;font-size:.5em;margin:0}h3.title{margin-top:3em}#showcase-page ul.project-tags li{margin:5px;display:inline-block}h2.featuring{margin-top:0}#showcase-page a.tag{display:inline-block;padding:6px 14px;background-color:#ffe8e8;border-radius:27px;font:.7rem Montserrat,sans-serif;color:#333}#showcase-page ul.project-tags li{margin:0}#showcase-page{margin-top:3em}#showcase-page .project-page h2{line-height:1.4}@media (min-width:720px){#showcase-page .showcase-intro h1{font:italic 900 6.35vw Montserrat,sans-serif}#showcase-page .showcase-intro p{line-height:1.75em;font-size:1em}#showcase-page .project-metadata{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}#showcase-page .project-resources{margin-left:3rem}#showcase-page .project-a{width:90%;float:right;display:inline-block;clear:both}#showcase-page .half-image{width:48%}}#showcase-page .project-metadata{margin-top:3%}#showcase-page .project-metadata section h3{color:#ed225d;font:700 italic 1rem Montserrat,sans-serif}#showcase-page .project-resources ul.links{font:500 .7rem Montserrat,sans-serif;letter-spacing:.01rem;line-height:1.5;margin:.5rem 0}#showcase-page .project-credit{font:italic 700 1.25rem Montserrat,sans-serif}#showcase-page .project-credit p{margin:.5rem 0}#showcase-page .creator-from,#showcase-page .note{font-size:.7rem}#showcase-page .qa-group{margin-bottom:2em}#showcase-page .project-q{margin-left:0;display:inline-block;clear:both;font:900 1.2rem Montserrat,sans-serif;line-height:1.5}#showcase-page code{font-size:1.1rem}#teach-page .case-list a:hover{border-bottom:none}#teach-page .heading{font:400 1.4rem Montserrat,sans-serif;color:#000;line-height:1.2em;padding-bottom:.4em;border-bottom:4px dotted #ed225d}#teach-page h3.title{margin-top:3em}#teach-page .search-filter{display:inline}#teach-page .search-filter label{display:inline-block;font:italic 900 1rem Montserrat,sans-serif;padding:6px 12px;text-align:left;white-space:nowrap;color:#ed225d;margin-bottom:.6em;margin-top:1.2em;border:1px solid #ed225d;cursor:pointer}#teach-page .search-filter label:hover{color:#fff;background-color:#ed225d}#teach-page .search-filter input[type=checkbox]{display:absolute;position:absolute;opacity:0}#teach-page ul.filters p.filter-title{font:400 .83rem Montserrat,sans-serif;color:#ed225d;height:50px;padding-top:20px;background:none;background-color:none;-webkit-box-shadow:none;box-shadow:none;display:inline-block;border:none;clear:both}#teach-page ul.filters li{display:inline;list-style:none;width:100%}#teach-page ul.filters li label{display:inline-block;border-radius:25px;font:200 .7rem Montserrat,sans-serif;color:#000;white-space:nowrap;margin:3px 0;-webkit-transition:.2s;-o-transition:.2s;transition:.2s;background:#fafafa;padding:6px 12px;cursor:pointer}#teach-page ul.filters li label:before{display:inline-block;padding:2px}#teach-page ul.filters li label:hover{color:#ed225d;background:#ffe8e8}#teach-page ul.filters li input[type=checkbox]:checked+label{color:#fff;background:#ed225d}#teach-page ul.filters li input[type=checkbox]{display:absolute;position:absolute;opacity:0}#teach-page ul.filters li.clear{display:block;clear:both}#teach-page .filter-panel{background-color:#fff;max-height:0;overflow:hidden;-webkit-transition:max-height .2s ease-out;-o-transition:max-height .2s ease-out;transition:max-height .2s ease-out;margin-bottom:.8em;padding:0 0 .4em}#teach-page .filter-panel p{margin:0;color:#333;font-size:.83em;height:50px;padding-top:20px;-webkit-transition:all .5s ease-in-out;-o-transition:all .5s ease-in-out;transition:all .5s ease-in-out}#teach-page .teach-intro p{font:400 1.2rem Times,sans-serif;line-height:1.5em}#teach-page .modal-title{margin-left:1em;margin-right:1em;font:400 1rem Montserrat,sans-serif;color:#ed225d;line-height:1.2em}#teach-page ul.cases li.clear{display:block;clear:both;margin-top:1em;margin-bottom:1.2em}#teach-page img{margin-bottom:1.4em}#teach-page img[alt]{font:.6rem Montserrat,sans-serif;color:#bababa}#teach-page .close{position:relative;color:#ffc7c7;float:right;font-size:40px;font-weight:700;margin-right:.4em;margin-top:.4em;cursor:pointer}#teach-page .close:hover,.close:focus{color:#ed225d;text-decoration:none;cursor:pointer}#teach-page .case label{margin:2px;padding:5px 8px;display:inline-block;border-radius:25px;font:.7rem Montserrat,sans-serif;color:#aaa;white-space:nowrap;color:#fff;background:#ed225d}#teach-page .modal-body::-webkit-scrollbar{width:5px;height:5px;border-radius:10px}#teach-page .modal-body::-webkit-scrollbar-track{background:#f1f1f1}#teach-page .modal-body::-webkit-scrollbar-thumb{background:#ffe8e8}#teach-page .case{margin-left:2em;margin-right:2em}#teach-page .case span{color:#ed225d;font:900 1.4rem Montserrat,sans-serif}#teach-page .case p.lead-name{font:900 Italic 1.2rem Montserrat,sans-serif;color:#ed225d;line-height:1.4em;border-bottom:1.4em}#teach-page .case .speech{position:relative;font:200 Italic .8rem Montserrat,sans-serif;color:#000;background:#ffe8e8;padding:.5em 1.2em;border-radius:.4em;border-bottom:none;margin-bottom:2em;margin-top:1em}#teach-page .case .speech:after{content:"";position:absolute;top:0;left:8%;width:0;height:0;border:10px solid transparent;border-bottom-color:#ffe8e8;border-top:0;margin-left:-10px;margin-top:-10px}#teach-page .case p.subtitle{font:400 1rem Montserrat,sans-serif;color:#ed225d}#teach-page .case p,#teach-page .case p.subtitle{line-height:1.4em;border-bottom:.1em dashed rgba(237,34,93,.15)}#teach-page .case p{font:400 1rem Times,sans-serif;color:#000}#teach-page .modal-footer,#teach-page .modal-header{margin-bottom:.8em}#teach-page .modal-body:-webkit-scrollbar{display:none}#teach-page .modal{display:none;position:fixed;z-index:100;width:100%;height:100%;top:0;left:0;right:0;overflow:auto;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;background-color:rgba(255,232,232,.5)}#teach-page .modal-content{position:fixed;background:#fff;top:2%;left:2%;right:2%;bottom:2%;margin:auto;border:1.2px solid #ffe8e8;max-width:740px;-webkit-box-shadow:10px 100px 30px -17px rgba(237,34,93,.5);box-shadow:10px 100px 30px -17px rgba(237,34,93,.5);-webkit-box-shadow:10px 100px 20px -17px rgba(237,34,93,.5);box-shadow:10px 100px 20px -17px rgba(237,34,93,.5);-webkit-box-shadow:10px 20px 10px -17px rgba(237,34,93,.5);box-shadow:10px 20px 10px -17px rgba(237,34,93,.5)}#teach-page .modal-body{margin:auto;height:85%;width:95%;overflow-y:auto}#teach-page .results-wrapper{width:100%;outline:none;background:#fff}#teach-page .results-wrapper ul li.case-list a.myBtn{overflow:hidden;text-overflow:ellipsis}#teach-page .case-list{margin-bottom:.8em;padding-bottom:.4em;font:400 1rem Times,sans-serif;line-height:1.2em;border-bottom:.1em dashed #ffe8e8}*,:after,:before{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}html{font-size:1.25em}body{margin:0;background-color:#fff;font-family:Times;font-weight:400;line-height:1.45;color:#333}p{font-size:1.2em;margin:.5em 0}.freeze{overflow:hidden}#menu li a:focus:active,#menu li a:focus:hover,#menu li a:link,#menu li a:visited{color:#ed225d;background:transparent;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}a:link,a:visited{color:#2d7bb6;text-decoration:none}#reference a:hover,a:active,a:hover{color:#ed225d;text-decoration:none;padding-bottom:.11em;border-bottom:.11em dashed #ed225d;-webkit-transition:border-bottom 30ms linear;-o-transition:border-bottom 30ms linear;transition:border-bottom 30ms linear}a.nounderline:hover{border:none}a.here{color:#ed225d;text-decoration:none;padding-bottom:.1em;border-bottom:transparent;border-bottom-color:#ed225d}.highlight{background-color:rgba(237,34,93,.15)}.container>div:first-of-type{margin-top:2em}h1,h2,h3,h4,h5{margin:1.414em 0 .5em;font-weight:inherit;line-height:1.2;font-family:Montserrat,sans-serif}h1{font-size:2.25em;margin:0}h2{font-size:1.5em;margin:1em 0 0}.code{font-family:Inconsolata,consolas,monospace}#backlink{margin:1.2em .444em 0 0;font-family:Montserrat,sans-serif;float:right}#backlink a{color:#afafaf}#backlink a:hover{color:#ed225d;border-bottom:none}#promo,#promo:visited{width:100%;background:#98fb98;margin:0;text-align:center;padding:.4em 0;background:#74ffb7;background:-webkit-radial-gradient(circle,#74ffb7 0,#8afff2 100%);background:-o-radial-gradient(circle,#74ffb7 0,#8afff2 100%);background:radial-gradient(circle,#74ffb7 0,#8afff2 100%);font-family:Montserrat,sans-serif;color:#ed225d!important}#promo:hover{background:#ed225d;color:#fff!important}#promo-link{margin:0!important;padding:0}#family a:link,#family a:visited{margin:.4em}#family a:active,#family a:hover{margin:.4em;border:none}#family{position:absolute;z-index:9999;top:0;left:0;width:100%;overflow:none;margin:0;border-bottom:1px solid rgba(51,51,51,.5);-webkit-box-shadow:0 0 10px #333;box-shadow:0 0 10px #333;background-color:hsla(0,0%,100%,.85)}#processing-sites{margin:.375em 0}#processing-sites li{list-style:none;display:inline-block;margin:0}#processing-sites li:first-child{margin-left:2em}#processing-sites li:last-child{float:right;margin-right:2em}.code-snippet{margin:0 0 0 1em;width:90%;clear:both}.column-span{margin:0 0 0 1em;padding:0;float:left;max-width:100%}.method_description p{margin-top:0}main{padding:0}.spacer{clear:both}ul{margin:0;padding:0;list-style:none}ol{font-size:1.2em}li{margin:0;padding:0}ul.list_view{margin:.5em 0 0 1em;padding:0;list-style:disc;list-style-position:outside;font-size:1.2em}ol ul.list_view{font-size:1em}ul.inside{margin:0 0 0 2em;padding:0;list-style:disc;list-style-position:inside}.image-row img{width:48%;height:14.3%}.image-row img+img{float:right;margin-right:0;margin-bottom:.25em}img,main div img{margin:.5em .5em 0 0;width:100%}p+img{margin-top:0}.video{width:100%}#lockup{position:absolute;top:-5.75em;left:1.25em;height:0;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#lockup object{margin:0;padding:0;border:none}#lockup a:focus{outline:0}.logo{padding:0;border:none;margin:0 0 .4em;height:4.5em;width:9.75em}#lockup p{color:#ed225d;font-size:.7em;font-family:Montserrat,sans-serif;margin:.5em 0 0 8.5em}#lockup a:link{border:transparent;height:4.5em;width:9.75em}.caption{margin-bottom:2.5em}.caption p,.caption span{text-align:right;font-size:.7em;font-family:Montserrat,sans-serif;padding-top:.25em}footer{clear:both;border-top:.1em dashed #ed225d;margin:2em 0}.videoWrapper{position:relative;padding-bottom:56.25%;height:0;margin-top:.5em}.videoWrapper iframe{position:absolute;top:0;left:0;width:100%;height:100%}.ir{background-color:transparent;border:0;overflow:hidden;*text-indent:-9999px}.ir:before{content:"";display:block;width:0;height:150%}.hidden{display:none!important;visibility:hidden}.sr-only{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only.focusable:active,.sr-only.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:after,.clearfix:before{content:" ";display:table}.clearfix:after{clear:both}.clearfix{*zoom:1}#notMobile-message{display:none;-webkit-box-ordinal-group:2;-webkit-order:1;-ms-flex-order:1;order:1}#asterisk-design-element,#isMobile-displayButton,.separator-design-element{display:none}.pointerevents #asterisk-design-element,.pointerevents .separator-design-element{pointer-events:none;display:inline-block}@media (min-width:780px){.container{width:49em!important;margin:11.5em auto}main{width:36em;padding:0!important}footer{width:48em}}@media (min-width:780px){.container{margin:11.5em auto;width:100%;padding:.8em 0 0;height:auto;min-height:100%}#home-page{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:row;-ms-flex-wrap:row;flex-wrap:row}main{padding:0 1em 0 0}#family,.small,footer,small{font-size:.7em}footer{clear:both}#i18n-btn{position:absolute;top:4em;right:1em}#i18n-btn a,#menu{font-family:Montserrat,sans-serif}#menu{list-style:none;margin:0 .75em 0 -1.85em;width:7.3em;height:100%;border-top:transparent;border-bottom:transparent;padding:0;font-size:.83em;z-index:100;position:relative;top:0}#menu li{float:none;margin:0 0 1em;text-align:right}#menu li:nth-child(11){margin-top:3em;padding-top:.5em}.left-column{width:48%;float:left;margin-bottom:40px}.right-column{width:48%;float:right;margin-right:0;margin-bottom:.25em}.narrow-left-column{width:32%;float:left}.wide-right-column{width:64%;float:right;margin-right:0;margin-bottom:.25em}.book{font-size:.7em}.column_0,.column_1,.column_2{float:left;width:11.333em}.column_0,.column_1{margin-right:1em}#collection-list-nav{width:100%;clear:both;border-bottom:1px dashed rgba(0,0,0,.2)}#collection-list-categories{font-family:Montserrat,sans-serif;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;margin:1em 0 1.5em}#collection-list-categories ul{-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1}#collection-list{margin:0}.group-name.first{margin-top:0!important}.column.group-name{margin-bottom:1em}#library-page .group-name{margin:2em 0 .5em}#library-page .column{margin-top:1em}#list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-bottom:1em}}@media (max-width:780px){.tagline{display:none!important}#family{display:none}#i18n-btn{position:absolute;top:.5em;right:.7em;z-index:10}#search{float:left;margin-bottom:1em}#search,#search input[type=text]{width:100%}#search input[type=search],#search input[type=text]{font-size:1.5em}#lockup{position:absolute;top:2em;left:1em}.column-span{margin:0;padding:0 1em;float:left}#menu,#menu.top_menu{margin:6em 0 .5em;font-size:1.3em}#menu li{display:inline-block}#menu li:last-child a:after{content:""}#menu li a:after{content:","}#contribute-item:first-child{margin-left:0}.download_box{width:96%}.download_box.half_box{width:46%;margin-right:4%;float:left}#etc_list{font-size:1.2em;margin-top:1em}#asterisk-design-element,.separator-design-element{display:none!important;pointer-events:none}pre[class*=language-]{padding:.5em;width:100%}code{word-wrap:break-word;word-break:break-all}#credits{position:relative!important;z-index:2;margin-top:-7em;padding:0 2em 3em 1em;font-size:.5em;float:right;width:100%;text-align:right}#credits,#home-sketch-frame{display:none}#exampleDisplay,#exampleDisplay #exampleEditor,#exampleFrame{width:100%}#exampleDisplay .edit_button{left:-.58em}#exampleDisplay .reset_button{left:3em}#exampleDisplay .copy_button{left:6.44em}#exampleEditor{margin-top:3em}.small,footer,small{font-size:.5em}.paramtype{width:96%}}@media (max-width:400px){#i18n{margin-top:.75em!important}body{margin-top:-.75em!important}}iframe{border:none;width:100%}.iframe-container{overflow:hidden;position:relative}.iframe-container iframe{border:0;height:100%;left:0;position:absolute;top:0;width:100%}.cnv_div{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.cnv_div>*{width:100px;height:auto}#i18n-buttons{margin:0;background:#fff}#i18n-buttons li{list-style:none;display:inline-block;margin-left:.5em}#i18n-btn a{border:none;outline:none;font-size:.7em;color:#696969;z-index:5}#i18n-btn a:hover{color:#ed225d}#i18n-btn a.disabled{color:#ed225d;cursor:default}#asterisk-design-element{position:fixed;z-index:-1;opacity:.6;pointer-events:none}.separator-design-element{width:.33em;height:.33em;margin:0 .09em .18em;display:inline-block;overflow:hidden;text-indent:-100%;background:transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOCIgaGVpZ2h0PSIyOCI+PHBhdGggZD0iTTE2LjkgMTAuM2w4LjUtMi42IDEuNyA1LjItOC41IDIuOSA1LjMgNy41LTQuNCAzLjItNS42LTcuMy01LjQgNy4xTDQuMiAyM2w1LjMtNy4yLTguNi0zLjIgMS43LTUuMiA4LjYgMi44VjEuNEgxN3Y4Ljl6IiBmaWxsPSIjZWQyMjVkIiBzdHJva2U9IiNlZDIyNWQiLz48L3N2Zz4=");-webkit-background-size:.33em .33em;background-size:.33em}#home-page #asterisk-design-element{bottom:-8%;right:20%;height:12em;width:12em;opacity:1}#examples-page #asterisk-design-element,#learn-page #asterisk-design-element,#other-content-types-page #asterisk-design-element{bottom:-14%;left:-20%;height:25em;width:25em;-webkit-transform:rotate(-1deg);-ms-transform:rotate(-1deg);-o-transform:rotate(-1deg);transform:rotate(-1deg)}#books-page #asterisk-design-element,#libraries-page #asterisk-design-element{bottom:-19%;right:-16%;height:28em;width:28em;-webkit-transform:rotate(2deg);-ms-transform:rotate(2deg);-o-transform:rotate(2deg);transform:rotate(2deg)}#community-page #asterisk-design-element,#get-started-page #asterisk-design-element{top:10%;right:-20%;height:30em;width:30em;-webkit-transform:rotate(2deg);-ms-transform:rotate(2deg);-o-transform:rotate(2deg);transform:rotate(2deg)}#download-page #asterisk-design-element,#reference-page #asterisk-design-element{top:7%;left:1%;height:10em;width:10em;-webkit-transform:rotate(-21deg);-ms-transform:rotate(-21deg);-o-transform:rotate(-21deg);transform:rotate(-21deg)}.email-octopus-email-address{color:#ed225d;text-decoration:none;padding-bottom:.11em;outline:none;border:none;border-bottom:.11em dashed #ed225d;-webkit-transition:border-bottom 30ms linear;-o-transition:border-bottom 30ms linear;transition:border-bottom 30ms linear;width:13em}.email-octopus-form-row-hp{position:absolute;left:-5000px}.email-octopus-form-row button{border:1px solid #ed225d;color:#ed225d;padding:.4em .6em;margin:1em 0 0;font-family:Montserrat,sans-serif;display:block}.email-octopus-form-row button:hover{background-color:#ed225d;color:#fff}.email-octopus-email-address::-webkit-input-placeholder{color:#ababab}.email-octopus-email-address:-moz-placeholder,.email-octopus-email-address::-moz-placeholder{color:#ababab}.email-octopus-email-address:-ms-input-placeholder{color:#ababab}@media (min-width:720px){.email-octopus-email-address{width:16em}.email-octopus-form-row button{margin:0 0 0 .5em;display:inline}} +/*# sourceMappingURL=maps/all.css.map */ \ No newline at end of file diff --git a/dist/assets/css/maps/all.css.map b/dist/assets/css/maps/all.css.map new file mode 100644 index 0000000000..d3dc28567d --- /dev/null +++ b/dist/assets/css/maps/all.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../all.css"],"names":[],"mappings":"AAAA,4DAA4D,AAU5D,sFAYI,aAAe,CAClB,AAMD,mBAGI,qBAAsB,CACtB,eAAiB,CACjB,MAAS,CACZ,AAOD,sBACI,aAAc,AACd,QAAU,CACb,AAOD,SACI,YAAc,CACjB,AAaD,KACI,eAAgB,AAChB,8BAA+B,AAC/B,yBAA2B,CAC9B,AAOD,kCAKI,sBAAwB,CAC3B,AAkBD,QACI,mBAAqB,CACxB,AAMD,iBAEI,SAAW,CACd,AAYD,GACI,cAAe,AACf,cAAiB,CACpB,AAED,GAEI,cAAiB,CACpB,AAED,GACI,iBAAkB,AAClB,YAAc,CACjB,AAED,GACI,cAAe,AACf,eAAiB,CACpB,AAED,GACI,gBAAkB,AAClB,eAAiB,CACpB,AAED,GACI,gBAAkB,AAClB,eAAiB,CACpB,AAMD,YACI,wBAA0B,CAC7B,AAMD,SAEI,eAAkB,CACrB,AAED,WACI,eAAiB,CACpB,AAMD,IACI,iBAAmB,CACtB,AAOD,GACI,4BAA6B,AAC7B,+BAAwB,AAAxB,uBAAwB,AACxB,QAAU,CACb,AAMD,KACI,gBAAiB,AACjB,UAAY,CACf,AAMD,MAEI,YAAc,CACjB,AAMD,kBAII,4BAA8B,CAC9B,kCAAuC,AACvC,aAAe,CAClB,AAMD,IACI,gBAAiB,AACjB,qBAAsB,AACtB,oBAAsB,CACzB,AAMD,EACI,WAAa,CAChB,AAMD,iBAEI,WAAY,AACZ,YAAc,CACjB,AAMD,MACI,aAAe,CAClB,AAMD,QAEI,cAAe,AACf,cAAe,AACf,kBAAmB,AACnB,uBAAyB,CAC5B,AAED,IACI,SAAY,CACf,AAED,IACI,aAAgB,CACnB,AAUD,cAII,YAAc,CACjB,AAED,GACI,iBAAmB,CACtB,AAMD,WAGI,kBAAoB,CACvB,AAMD,cAEI,gBAAiB,AACjB,qBAAuB,CAC1B,AAWD,IACI,SAAU,AACV,8BAAgC,CACnC,AAMD,eACI,eAAiB,CACpB,AAsBD,YACI,QAAU,CACb,AAMD,SACI,wBAA0B,AAC1B,aAAc,AACd,0BAA+B,CAClC,AAQD,OACI,SAAU,AACV,UAAW,AACX,mBAAoB,CACpB,gBAAmB,CACtB,AASD,6BAII,eAAgB,AAChB,SAAU,AACV,wBAAyB,CACzB,qBAAwB,CAC3B,AAOD,aAEI,kBAAoB,CACvB,AASD,cAEI,mBAAqB,CACxB,AAYD,oEAII,0BAA2B,AAC3B,eAAgB,CAChB,gBAAmB,CACtB,AAMD,sCAEI,cAAgB,CACnB,AASD,uCAEI,8BAAuB,AAAvB,2BAAuB,AAAvB,sBAAuB,AACvB,UAAW,CACX,YAAc,CACd,UAAa,CAChB,AAQD,mBACI,6BAA8B,AAC9B,4BAA6B,AAC7B,+BAAgC,AAChC,sBAAwB,CAC3B,AAOD,+FAEI,uBAAyB,CAC5B,AAMD,iDAEI,SAAU,AACV,SAAW,CACd,AAOD,SACI,cAAe,AACf,kBAAoB,CACvB,AAUD,MACI,yBAA0B,AAC1B,gBAAkB,CACrB;CAAA,AAWD,sDAGE,WAAY,AACZ,8DAKc,AACd,cAAe,AACf,gBAAiB,AACjB,gBAAiB,AACjB,oBAAqB,AACrB,kBAAmB,AACnB,gBAAiB,AACjB,cAAe,AACf,WAAY,AACZ,qBAAsB,AACtB,kBAAmB,AACnB,iBAAkB,AAClB,aAAc,AACd,uBAA0B,CAC3B,AAGD,sBACE,kBAAkB,AAClB,iBAAqB,AACrB,sBAAyB,AACzB,+BAAiC,AACjC,sBAAuB,AAEvB,iFAAyF,AAGzF,8EAAoF,AACpF,gIAAiF,AAAjF,yEAAiF,AACjF,oCAA6B,AAA7B,4BAA6B,AAC7B,sCAA8B,AAA9B,8BAA8B,AAE9B,aAAc,CAIf,AAMD,uDAEE,iBAAmB,CACpB,AAGD,iCACE,kBAAkB,AAClB,aAAc,AAKd,mBAAqB,AACrB,WAAY,AACZ,+BAAqC,CACtC,AAGD,mEAEE,YAAc,AACd,SAAW,CACZ,AAGD,8EAKE,aAAe,CAChB,AAED,mBACE,UAAY,CACb,AAED,2GAOE,aAAe,CAChB,AAED,8EAKE,aAAe,CAChB,AAED,yDAIE,cAAe,AACf,6BAAqC,CACtC,AAED,iEAIE,aAAe,CAChB,AAED,8BAEE,UAAY,CACb,AACD,iDAEE,cAAe,AACf,6BAAqC,CACtC,AAED,iBACE,eAAoB,CACrB,AAED,cACE,WAAa,CACd,AAED,WACE,UAAY,CACb,AAED,oCACE,yDAEE,YAAY,AACZ,wBAAwB,AAExB,eAAgB,CACjB,CAEF,AAGD,gEAGE,aAAe,CAChB,AAED,iBAEE,mBAAoB,AACpB,wBAA0B,CAC3B,AAED,uCALE,iBAAmB,CAOpB,AAED,iCACE,kBAAmB,AACnB,oBAAqB,AACrB,MAAO,AACP,eAAgB,AAChB,YAAa,AACb,UAAW,AACX,oBAAqB,AACrB,4BAA6B,AAE7B,yBAA0B,AAC1B,sBAAuB,AACvB,qBAAsB,AACtB,gBAAkB,CAEnB,AAED,wBACE,oBAAqB,AACrB,cAAe,AACf,4BAA8B,CAC/B,AAED,+BACE,4BAA6B,AAC7B,WAAY,AACZ,cAAe,AACf,mBAAqB,AACrB,gBAAkB,CACnB;CAAA,AAaD,yBAIE,UAAY,CACb,AAED,SACE,mBAAoB,AACpB,iBAA6B,AAC7B,WAAa,CACd,AAED,KACE,cAAe,AACf,eAAiB,CAClB,AAQD,iBACE,mBAAoB,AACpB,gBAAkB,CACnB,AAED,YACE,mBAAoB,AACpB,gBAAkB,CACnB,AAMD,GACE,cAAe,AACf,WAAY,AACZ,SAAU,AACV,0BAA2B,AAC3B,aAAc,AACd,SAAW,CACZ,AAMD,IACE,qBAAuB,CACxB,AAED,aACE,YAAa,AACb,UAAY,CACb,AAED,cACE,YAAa,AACb,WAAa,CACd,AAED,eACE,YAAa,AACb,UAAY,CACb,AAED,iBACE,YAAa,AACb,UAAY,CACb,AAED,gBACE,YAAa,AACb,WAAa,CACd,AAED,kBACE,YAAa,AACb,WAAa,CACd,AAED,iBACE,YAAa,AACb,iBAAmB,CACpB,AAED,UACE,WAAa,CACd,AAED,QACE,WAAa,CACd,AAED,eACE,YAAa,AACb,iBAAmB,CACpB,AAMD,SACE,SAAU,AACV,SAAU,AACV,SAAW,CACZ,AAMD,SACE,eAAiB,CAClB,AAOD,SACE,YAAc,CACf,AAED,iBACE,mBAAqB,CACtB,AAED,mBACE,kBAAoB,CACrB,AAED,UACE,kBAAmB,AACnB,cAAe,AACf,YAAa,AACb,WAAa,CACd,AAED,YACE,kBAAmB,AACnB,KAAO,CACR,AAED,qBAEE,gBAAiB,AACjB,kCAAsC,AACtC,WAAY,AACZ,eAAkB,AAClB,UAAW,AACX,YAAa,AACb,eAAiB,CAClB,AAED,kBACE,cAAgB,CACjB,AAED,aACE,kBAAmB,AACnB,MAAO,AACP,OAAQ,AACR,UAAY,CACb,AAID,oCACE,cACE,WAAY,AACZ,aAAc,AACd,2CAAqC,AAArC,sCAAqC,AAArC,mCAAqC,AACrC,eAAiB,CAClB,AAED,0BACE,UAAY,CACb,AAED,gBACE,cAAe,AACf,kBAAmB,AACnB,qBAAuB,AACvB,sCAAyC,CAC1C,AAED,mBACE,SAAU,AACV,eAAgB,AAChB,YAAa,AACb,kBAAmB,AACnB,kBAAmB,AACnB,yBAAkB,AAAlB,sBAAkB,AAAlB,qBAAkB,AAAlB,iBAAkB,AAClB,kBAAoB,CACrB,AAED,qCACE,mBAAoB,AACpB,cAAe,AACf,WAAY,AACZ,kBAAmB,AACnB,2CAAqC,AAArC,sCAAqC,AAArC,mCAAqC,AACrC,UAAY,CACb,AAED,uFAEE,mBAAoB,AACpB,WAAY,AACZ,cAAe,AACf,YAAa,AACb,kBAAmB,AACnB,oCAA8B,AAA9B,+BAA8B,AAA9B,4BAA8B,AAC9B,UAAY,CACb,AAED,4CACE,OAAS,CACV,AAED,2CACE,QAAU,CACX,AAED,kBACE,YAAc,CACf,AAED,wCACE,gBAAkB,CACnB,AAED,+DACE,sBAAwB,CACzB,AAED,sEACE,iCAA0B,AAA1B,6BAA0B,AAA1B,4BAA0B,AAA1B,yBAA0B,AAC1B,KAAO,CACR,AAED,qEACE,gCAAyB,AAAzB,4BAAyB,AAAzB,2BAAyB,AAAzB,wBAAyB,AACzB,KAAO,CACR,CACF,AAED,kBACE,YAAc,CACf,AAID,mBACE,eAAgB,AAChB,WAAY,AACZ,YAAa,AACb,OAAQ,AACR,MAAO,AACP,WAAY,AACZ,gBAAiB,AACjB,mBAAoB,AACpB,QAAU,CACX,AAED,SACE,eAAgB,AAChB,SAAU,AACV,OAAQ,AACR,UAAW,AACX,YAAa,AACb,cAAiB,CAClB,AAED,iBACE,kBAAmB,AACnB,OAAU,AACV,SAAU,AACV,UAAW,AACX,yBAA0B,AAC1B,WAAa,AACb,WAAY,AACZ,YAAa,AACb,YAAa,AACb,mBAAoB,AACpB,kBAAmB,AACnB,eAAgB,AAChB,YAAa,AACb,SAAW,CACZ,AAED,uBACE,SAAW,CACZ,AAQD,YAEE,kBAAqB,AACrB,cAAgB,AAEhB,kCAAsC,AACtC,oBAAsB,CACvB,AAED,0BARE,yBAA0B,AAG1B,UAAY,CAcb,AATD,cAEE,aAAe,AACf,oBAAqB,AACrB,cAAe,AACf,WAAY,AAEZ,cAAe,AACf,iBAAmB,CACpB,AAED,sCAEE,yBAA0B,AAC1B,mBAAoB,AACpB,UAAe,CAChB,AAED,uBACE,cAAe,AACf,oBAAqB,AACrB,UAAY,CACb,AAED,gCACE,cAAgB,CACjB,AAED,6BACE,cAAe,AACf,SAAU,AACV,oBAAsB,AAEtB,mCAA6B,AAC7B,gBAAiB,AACjB,kCAAsC,AACtC,aAAe,CAChB,AAED,mCACE,4BAA6B,AAC7B,wBAA0B,CAC3B,AAED,gBACE,gBAAkB,AAClB,SAAU,AACV,kBAAmB,AACnB,UAAY,CACb,AAED,kBACE,aAAe,AACf,YAAc,AACd,kBAAmB,AACnB,YAAc,CACf,AAED,wBACE,SAAY,CACb,AAED,mBACE,aAAe,CAChB,AAED,2BACE,WAAY,AACZ,iBAAmB,CACpB,AAED,cACE,cAAgB,CACjB,AAED,0BACE,eAAgB,AAChB,iBAAmB,CACpB,AAED,0BACE,eAAiB,AACjB,gBAAiB,AACjB,eAAkB,CACnB,AAED,WACE,YAAc,CACf,AAED,aACE,eAAiB,AACjB,cAAe,AACf,kBAAmB,AACnB,eAAkB,CACnB,AAED,OACE,WAAa,AACb,kBAAmB,AACnB,aAAe,AACf,WAAa,AACb,gBAAkB,AAClB,6BAA8B,AAC9B,iCAAkC,AAClC,4BAA0B,AAA1B,yBAA0B,AAC1B,cAAiB,CAClB,AAOD,8BACE,kBAAmB,AACnB,4BAAS,AAAT,gBAAS,AAAT,iBAAS,AAAT,QAAS,AACT,sBAAwB,CACzB,AACD,2CACE,cAAe,AACf,kCAAuC,AACvC,YAAa,AACb,0BAA4B,AAC5B,8BAAqC,AACrC,kBAAmB,AACnB,UAAW,AACX,aAAc,AACd,UAAY,CACb,AAED,yBACE,2CACE,WAAa,CACd,CACF,AACD,yBACE,2CACE,WAAa,CACd,CACF,AAOD,uBACE,iBAAmB,CACpB,AAQD,wBACE,UAAY,CACb,AAED,oBACE,eAAiB,CAClB,AAED,oBACE,cAAe,AACf,kCAAsC,AACtC,eAAkB,CACnB,AAED,oBACE,oBAAsB,CACvB,AAED,wBACE,SAAU,AACV,oBAAc,AAAd,qBAAc,AAAd,oBAAc,AAAd,aAAc,AACd,8BAAoB,AAApB,6BAAoB,AAApB,2BAAoB,AAApB,uBAAoB,AAApB,mBAAoB,AACpB,uBAAgB,AAAhB,mBAAgB,AAAhB,cAAgB,CACjB,AACD,uBACE,WAAY,AACZ,iBAAmB,CACpB,AAED,gCASE,eAAgB,AAChB,iBAAmB,CACpB,AAED,gCACE,aAAe,CAChB,AAED,MACE,UAAY,CACb,AAED,SACE,kBAAsB,AACtB,kBAAmB,AACnB,oBAAqB,AACrB,2CAAgD,AAChD,aAAe,CAChB,AAED,SACE,iBAAkB,AAClB,cAAkB,CACnB,AAED,SACE,eAAkB,CACnB,AAED,SACE,iBAAmB,CACpB,AAED,aACE,WAAY,AACZ,cAAe,AACf,UAAY,CACb,AAED,YACE,UAAY,CACb,AAED,4BAEE,WAAY,AACZ,YAAc,CACf,AAED,WACE,qBAAsB,AACtB,cAAe,AACf,gBAAiB,AACjB,eAAiB,CAClB,AAED,aACE,eAAgB,AAChB,aAAe,CAChB,AAED,WAEE,gBAAiB,AACjB,UAAW,AACX,kBAAoB,CACrB,AAED,qCANE,oBAAsB,CAQvB,AAED,gCACE,aAAe,CAChB,AAID,aACE,iBAAmB,CACpB,AAED,+BACE,kBAAmB,AACnB,SAAU,AACV,cAAe,AACf,gBAAiB,AACjB,YAAa,AACb,aAAc,AACd,cAAgB,CACjB,AAED,wCACE,OAAU,AACV,aAAe,CAChB,AAED,6BACE,kBAAmB,AACnB,MAAO,AACP,OAAQ,AACR,iBAAmB,AACnB,WAAY,AACZ,mBAAqB,CACtB,AAED,+BACE,mBAAqB,CACtB,AAED,gCACE,oBAAc,AAAd,qBAAc,AAAd,oBAAc,AAAd,aAAc,AACd,8BAA4B,AAA5B,8BAA4B,AAA5B,mCAA4B,AAA5B,+BAA4B,AAA5B,2BAA4B,AAC5B,kBAAmB,AACnB,mBAAqB,CACtB,AAED,0CACE,kCAAsC,AACtC,cAAe,AACf,WAAY,AACZ,sCAA4C,AAC5C,uBAAwB,AACxB,aAAc,AACd,gBAAmB,CACpB,AAED,wFAEE,cAAe,AACf,iCAAuC,CACxC,AAED,wCACE,kBAAmB,AACnB,SAAW,AACX,WAAY,AACZ,aAAc,AAEd,aAAc,AACd,sBAAuB,AACvB,wBAAiC,AACjC,cAAgB,CACjB,AAED,gBACE,kBAAmB,AACnB,kCAAsC,AACtC,cAAe,AACf,cAAe,AACf,sCAA2C,AAC3C,uBAAwB,AACxB,YAAc,CACf,AAED,oCACE,WAAY,AACZ,eAAgB,AAEhB,6BAAuB,AACvB,iBAAmB,AACnB,eAAgB,AAChB,iBAAkB,AAClB,iCAAgC,AAAhC,yBAAgC,AAChC,oBAAc,AAAd,qBAAc,AAAd,oBAAc,AAAd,YAAc,CACf,AAED,kDACE,cAAgB,CACjB,AAGD,yBACE,+BACE,iBAAmB,AACnB,UAAa,CACd,AAED,oCACE,WAAY,AACZ,iBAAkB,AAClB,kCAAiC,AAAjC,0BAAiC,AACjC,aAAe,CAChB,AAED,wCACE,8BAAuB,AAAvB,sBAAuB,AACvB,OAAQ,AACR,WAAY,AACZ,YAAe,CAChB,AAED,0BACE,SAAW,CACZ,AAED,aACE,eAAiB,CAClB,AAED,aACE,MAAQ,CACT,AAED,cACE,WAAa,CACd,AAED,aACE,WAAa,CACd,CACF,AAED,KACE,kBAAoB,CACrB,AAED,eACE,gDAAkD,CACnD,AAED,oDAEE,qCAA2C,AAC3C,kCAAsC,AACtC,iBAAkB,AAClB,YAAc,CACf,AAED,wEAEE,UAAY,CACb,AAED,4DAGE,UAAY,CACb,AAED,+BACE,cAAe,AACf,sBAAuB,AACvB,kBAAmB,AACnB,mBAAqB,CACtB,AAED,6CACE,qBAAuB,CAKxB,AAED,oDACE,WAAY,AACZ,qBAAuB,CACxB,AAED,4CACE,QAAU,CACX,AAED,mDACE,eAAgB,AAChB,UAAY,CACb,AAED,QACE,WAAa,CACd,AAED,6CACE,gCAAqC,AACrC,aAAe,AACf,iBAAkB,AAClB,gBAAiB,AACjB,cAAe,AACf,iBAAmB,CACpB,AAED,0CACE,iBAAkB,AAClB,iBAAkB,AAClB,cAAgB,CACjB,AAED,0CACE,qBAA2B,AAC3B,eAAgB,AAChB,gBAAkB,CACnB,AAED,eACE,WAAa,CACd,AAED,YACE,UAAY,CACb,AAED,aACE,aAAe,CAChB,AAcD,iBACE,gBAAkB,AAClB,gBAAiB,AACjB,qBAAsB,AACtB,YAAa,AACb,aAAc,AACd,WAAY,AACZ,yBAA0B,AAC1B,qBAAsB,AACtB,iBAAmB,CACpB,AAED,2BACE,kBAAmB,AACnB,WAAY,AACZ,SAAU,AACV,YAAc,CACf,AAED,WAEE,aAAc,AACd,kBAAmB,AACnB,gBAAkB,AAClB,gBAAkB,CACnB,AAED,aAEE,WAAY,AACZ,YAAa,AACb,kBAAmB,AACnB,MAAO,AACP,MAAQ,CACT,AAED,OACE,UAAY,CACb,AAED,oBACE,iBAAkB,AAClB,gBAAmB,AACnB,oBAAsB,AAEtB,kCAA6B,CAC9B,AAQD,OACE,iBAAmB,CACpB,AAED,wBACE,eAAoB,CACrB,AAED,UACE,WAAa,AACb,kBAAmB,AACnB,MAAO,AACP,UAAY,CACb,AAED,gBACE,aAAe,CAChB,AAED,GACE,iBAAkB,AAClB,cAAkB,CACnB,AAED,aACE,mBAAoB,AACpB,eAAiB,CAClB,AAED,0BACE,sBAAwB,AACxB,aAAgB,CACjB,AAED,oCACE,2BAAoB,AAApB,wBAAoB,AAApB,kBAAoB,CACrB,AAED,kBACE,oBAAsB,CACvB,AAED,6CAGE,WAAY,AACZ,WAAa,CACd,AAED,gBACE,oBAAc,AAAd,qBAAc,AAAd,oBAAc,AAAd,aAAc,AACd,4BAAkB,AAAlB,6BAAkB,AAAlB,yBAAkB,AAAlB,qBAAkB,AAAlB,gBAAkB,CACnB,AAED,mBACE,eAAgB,AAChB,MAAO,AACP,OAAQ,AACR,QAAS,AACT,SAAU,AACV,aAAc,AACd,WAAa,CACd,AAED,uBACE,cAAe,AACf,kCAAuC,AACvC,YAAa,AACb,qBAAwB,AACxB,8BAAqC,AACrC,kBAAmB,AACnB,OAAQ,AACR,SAAW,CACZ,AAED,6BACE,aAAc,AACd,UAAY,CACb,AAED,8BACE,UAAW,AACX,UAAY,CACb,AAED,6BACE,aAAc,AACd,UAAY,CACb,AAED,6BACE,eAAiB,CAClB,AAED,4BACE,kBAAmB,AACnB,4BAAS,AAAT,gBAAS,AAAT,iBAAS,AAAT,OAAS,CACV,AAED,8BACE,YAAa,AACb,4BAAS,AAAT,gBAAS,AAAT,iBAAS,AAAT,OAAS,CACV,AAED,+BACE,aAAc,AACd,YAAa,AACb,gBAAiB,AACjB,gBAAkB,AAClB,WAAY,AACZ,2CAAgD,AAChD,cAAe,AACf,sBAAuB,AACvB,gBAAiB,AACjB,4BAAS,AAAT,gBAAS,AAAT,iBAAS,AAAT,OAAS,CACV,AAED,gDACE,sBAAuB,AACvB,kBAAmB,AACnB,gBAAiB,AACjB,wBAA0B,CAC3B,AAED,yDACE,wBAA0B,CAC3B,AAED,4DACE,sBAA0B,AAC1B,UAAe,CAChB,AAED,0DACE,wBAA0B,AAC1B,UAAe,CAChB,AAMD,oFAEE,aAAe,CAEhB,AAKD,sIAGE,aAAe,CAEhB,AAKD,qIAGE,aAAe,CAEhB,AAKD,4CACE,aAAe,CAEhB,AAKD,2CACE,aAAe,CAEhB,AAED,6CACE,UAAY,CACb,AAID,2CACE,UAAY,CAEb,AAMD,4FACE,UAAY,CACb,AAED,oDACE,qBAAuB,AACvB,UAAY,CACb,AAED,aACE,sBAAuB,AACvB,eAAgB,AAChB,aAAc,AACd,aAA0B,CAC3B,AAOD,WACE,iBAAmB,CACpB,AAED,kCACE,6CAAiD,AACjD,cAAe,AACf,gBAAiB,AACjB,wBAA0B,CAC3B,AAED,iCACE,sCAA0C,AAC1C,iBAAmB,CACpB,AAED,qEAEE,2CAA+C,AAC/C,cAAe,AACf,qBAAwB,CACzB,AAED,oHAIE,eAAiB,CAClB,AAED,wBACE,eAAkB,CACnB,AAED,kCACE,cAAgB,CACjB,AAED,2CACE,0CAA+C,CAChD,AAED,2CACE,mCAAwC,CACzC,AAED,gDACE,cAAe,AACf,mBAAsB,CACvB,AAED,yBACE,iBAAkB,AAClB,oBAAsB,CACvB,AAED,8DAEE,kBAAqB,AACrB,kBAAmB,AACnB,MAAS,AACT,OAAU,AACV,yBAA0B,AAC1B,qCAA8B,AAA9B,6BAA8B,AAE9B,kCAAsC,AACtC,cAAe,AACf,sBAAwB,AACxB,2BAAqB,AAArB,sBAAqB,AAArB,kBAAqB,CACtB,AAED,yBACE,8DAEE,kBAAqB,AACrB,iCAAsC,CACvC,CACF,AAED,iCACE,QAAS,AACT,SAAU,AACV,wBAAiB,AAAjB,eAAiB,CAClB,AAED,gFAEE,iBAAkB,AAClB,cAAe,AACf,sBAAwB,AACxB,eAAiB,CAClB,AAED,0CACE,YAAc,CACf,AACD,8CACE,UAAY,CACb,AACD,uDACE,WAAa,CACd,AAED,uDACE,qBAAsB,AACtB,aAAc,AACd,WAAa,CACd,AAED,cACE,cAAgB,CACjB,AAED,kBACE,cAAe,AACf,oBAAqB,AACrB,qBAAsB,AACtB,oBAAc,AAAd,aAAc,AACd,uBAAwB,AACxB,mBAAgB,AAAhB,eAAgB,AAChB,eAAiB,AACjB,QAAY,CACb,AACD,SACE,cAAgB,CACjB,AACD,kCACE,WAAY,AACZ,oBAAsB,CACvB,AACD,aACE,YAAgB,CACjB,AACD,qBACE,qBAAsB,AACtB,iBAAkB,AAClB,yBAA0B,AAC1B,mBAAoB,AACpB,iCAAsC,AACtC,UAAY,CACb,AACD,kCACE,QAAY,CACb,AAqBD,eACE,cAAgB,CACjB,AAED,gCACE,eAAiB,CAClB,AAED,yBAME,kCACE,4CAAiD,CAClD,AAED,iCACE,mBAAoB,AACpB,aAAe,CAChB,AAED,iCACE,oBAAc,AAAd,qBAAc,AAAd,oBAAc,AAAd,YAAc,CACf,AAED,kCACE,gBAAkB,CACnB,AAED,0BACE,UAAW,AACX,YAAa,AACb,qBAAsB,AACtB,UAAY,CACb,AAED,2BACE,SAAW,CACZ,CACF,AAED,iCACE,aAAe,CAChB,AAED,4CACE,cAAe,AACf,0CAAgD,CACjD,AAED,2CACE,qCAA0C,AAC1C,sBAAwB,AACxB,gBAAiB,AACjB,cAAiB,CAClB,AAED,+BACE,6CAAmD,CACpD,AAED,iCACE,cAAiB,CAClB,AAMD,kDACE,eAAkB,CACnB,AAED,yBACE,iBAAmB,CACpB,AAED,0BACE,cAAgB,AAChB,qBAAsB,AACtB,WAAY,AAKZ,sCAA0C,AAC1C,eAAiB,CAClB,AAED,oBACE,gBAAkB,CACnB,AAOD,+BACE,kBAAoB,CACrB,AAED,qBACE,sCAA0C,AAC1C,WAAa,AACb,kBAAmB,AACnB,oBAAqB,AACrB,gCAAkC,CACnC,AAED,qBACE,cAAgB,CACjB,AAID,2BACE,cAAgB,CACjB,AAED,iCACE,qBAAsB,AACtB,2CAA+C,AAC/C,iBAAkB,AAClB,gBAAiB,AACjB,mBAAoB,AACpB,cAAe,AAEf,mBAAoB,AACpB,iBAAkB,AAClB,yBAA0B,AAM1B,cAAgB,CAHjB,AAOD,uCACE,WAAa,AACb,wBAA0B,CAC3B,AAGD,gDACE,iBAAkB,AAKlB,kBAAmB,AACnB,SAAW,CALZ,AASD,sCACE,sCAA2C,AAC3C,cAAe,AACf,YAAa,AACb,iBAAiB,AACjB,gBAAiB,AACjB,sBAAuB,AACvB,wBAAiB,AAAjB,gBAAiB,AACjB,qBAAsB,AACtB,YAAa,AACb,UAAY,CAEb,AAKD,0BACE,eAAgB,AAChB,gBAAiB,AACjB,UAAY,CACb,AAED,gCACI,qBAAsB,AACtB,mBAAoB,AACpB,qCAA0C,AAM1C,WAAa,AACb,mBAAoB,AACpB,aAAgB,AAChB,uBAAgB,AAAhB,kBAAgB,AAAhB,eAAgB,AAChB,mBAAoB,AAIpB,iBAAkB,AAClB,cAAgB,CAJnB,AAOD,uCACI,qBAAsB,AACtB,WAAyB,CAC5B,AAED,sCACI,cAAe,AACf,kBAAoB,CAGtB,AAEF,6DACI,WAAa,AACb,kBAAoB,CAEvB,AAED,+CACE,iBAAkB,AAClB,kBAAmB,AACnB,SAAW,CACZ,AAGD,gCACE,cAAe,AACf,UAAY,CAEb,AAKD,0BAEE,sBAAwB,AACxB,aAAc,AACd,gBAAiB,AACjB,2CAAqC,AAArC,sCAAqC,AAArC,mCAAqC,AACrC,mBAAqB,AACrB,gBAAqB,CAEtB,AAID,4BACE,SAAU,AACV,WAAY,AACZ,gBAAiB,AACjB,YAAa,AACb,iBAAiB,AACjB,uCAAiC,AAAjC,kCAAiC,AAAjC,8BAAiC,CAClC,AAID,2BACE,iCAAqC,AACrC,iBAAmB,CACpB,AAKD,yBAEE,gBAAiB,AACjB,iBAAkB,AAElB,oCAAwC,AACxC,cAAe,AACf,iBAAmB,CAEpB,AAED,8BACE,cAAe,AACf,WAAY,AACZ,eAAgB,AAChB,mBAAqB,CACtB,AAGD,gBACE,mBAAqB,CACtB,AAED,qBACE,iCAAsC,AACtC,aAAe,CAEhB,AAED,mBACE,kBAAmB,AACnB,cAAe,AACf,YAAa,AACb,eAAgB,AAChB,gBAAkB,AAClB,kBAAmB,AACnB,gBAAiB,AACjB,cAAe,CAChB,AAED,sCACE,cAAe,AACf,qBAAsB,AACtB,cAAgB,CACjB,AAED,wBAGE,WAAgB,AAChB,gBAAiB,AACjB,qBAAsB,AACtB,mBAAoB,AACpB,iCAAsC,AACtC,WAAe,AACf,mBAAoB,AACpB,WAAa,AACb,kBAAoB,CACrB,AAID,2CAEE,UAAW,AACX,WAAY,AACZ,kBAAoB,CACrB,AAED,iDACE,kBAAoB,CACrB,AAED,iDACE,kBAAoB,CACrB,AAID,kBACE,gBAAiB,AACjB,gBAAiB,CAClB,AAED,uBACE,cAAe,AACf,qCAA0C,CAC3C,AAGD,8BACE,6CAAiD,AACjD,cAAe,AACf,kBAAmB,AACnB,mBAAqB,CACtB,AAED,0BAEE,kBAAmB,AACnB,4CAAgD,AAChD,WAAa,AACb,mBAAoB,AACpB,mBAAqB,AACrB,mBAAoB,AACpB,mBAAoB,AACpB,kBAAmB,AACnB,cAAgB,CAGjB,AAED,gCACE,WAAY,AACZ,kBAAmB,AACnB,MAAO,AACP,QAAS,AACT,QAAS,AACT,SAAU,AAEV,8BAA6B,AAA7B,4BAA6B,AAC7B,aAAc,AACd,kBAAmB,AACnB,gBAAkB,CACnB,AAED,6BAEE,oCAAwC,AACxC,aAAe,CAGhB,AAED,iDAJE,kBAAmB,AACnB,6CAAoD,CAUrD,AAPD,oBACE,+BAAmC,AACnC,UAAa,CAKd,AAQD,oDAEE,kBAAqB,CACtB,AAOD,0CACE,YAAc,CACf,AAGD,mBACE,aAAc,AACd,eAAgB,AAChB,YAAa,AACb,WAAY,AACZ,YAAa,AACb,MAAM,AACN,OAAO,AACP,QAAQ,AACR,cAAe,AACf,8BAAuB,AAAvB,2BAAuB,AAAvB,sBAAuB,AACvB,qCAA2C,CAE5C,AAED,2BACE,eAAgB,AAChB,gBAAkB,AAClB,OAAQ,AACR,QAAS,AACT,SAAU,AACV,UAAW,AACX,YAAa,AACb,2BAA4B,AAC5B,gBAAiB,AACjB,4DAAyD,AAAzD,oDAAyD,AACzD,4DAAyD,AAAzD,oDAAyD,AACzD,2DAAwD,AAAxD,kDAAwD,CACzD,AAED,wBAEE,YAAa,AACb,WAAY,AACZ,UAAW,AACX,eAAiB,CAElB,AAED,6BACE,WAAY,AACZ,aAAc,AACd,eAAkB,CAYnB,AAED,qDAEE,gBAAiB,AACjB,sBAAwB,CAEzB,AAED,uBAEE,mBAAqB,AACrB,oBAAqB,AAErB,+BAAqC,AACrC,kBAAmB,AAEnB,iCAAoC,CAErC,AAQD,iBAGE,2BAA4B,AAC5B,8BAA+B,AAC/B,qBAAuB,CACxB,AAED,KACE,gBAAkB,CACnB,AAED,KACE,SAAU,AACV,sBAAuB,AACvB,kBAAqB,AACrB,gBAAiB,AACjB,iBAAkB,AAClB,UAAY,CACb,AAED,EACE,gBAAiB,AACjB,aAAgB,CACjB,AAED,QACE,eAAiB,CAClB,AAID,kFAIE,cAAe,AAKf,uBAAwB,AACxB,2BAA4B,AAC5B,yBAA0B,AAE1B,sBAAuB,AACvB,qBAAsB,AACtB,gBAAkB,CACnB,AAID,iBAEE,cAAe,AACf,oBAAsB,CAEvB,AAED,oCAGE,cAAe,AACf,qBAAsB,AACtB,qBAAuB,AAEvB,mCAA6B,AAC7B,6CAAsC,AAAtC,wCAAsC,AAAtC,oCAAsC,CACvC,AAED,oBACE,WAAa,CACd,AAED,OACE,cAAe,AACf,qBAAsB,AACtB,oBAAsB,AACtB,0BAA2B,AAC3B,2BAA6B,CAC9B,AAED,WACE,oCAA0C,CAC3C,AAED,6BACE,cAAgB,CACjB,AAED,eAKE,sBAA0B,AAC1B,oBAAqB,AACrB,gBAAiB,AACjB,iCAAsC,CACvC,AAED,GACE,iBAAkB,AAElB,QAAU,CACX,AAED,GACE,gBAAiB,AAEjB,cAAkB,CACnB,AAED,MACE,0CAAgD,CACjD,AAED,UACE,wBAA0B,AAC1B,kCAAsC,AACtC,WAAa,CACd,AAED,YACE,aAAe,CAChB,AAED,kBACE,cAAe,AACf,kBAAoB,CACrB,AAQD,sBAEE,WAAY,AACZ,mBAAsB,AAEtB,SAAU,AACV,kBAAmB,AACnB,eAAiB,AACjB,mBAA+B,AAC/B,kEAIE,AAJF,6DAIE,AAJF,0DAIE,AACF,kCAAsC,AACtC,uBAA0B,CAC3B,AAED,aACE,mBAAoB,AACpB,oBAAwB,CACzB,AAED,YACE,mBAAqB,AACrB,SAAW,CACZ,AAED,iCAEE,WAAc,CACf,AAED,iCAEE,YAAc,AACd,WAAa,CACd,AAED,QACE,kBAAmB,AACnB,aAAc,AACd,MAAO,AACP,OAAQ,AAER,WAAY,AAGZ,cAAe,AACf,SAAU,AACV,0CAA2C,AAC3C,iCAAsC,AAEtC,yBAA8B,AAC9B,oCAA4C,CAE7C,AAED,kBACE,eAAkB,CACnB,AAED,qBACE,gBAAiB,AACjB,qBAAsB,AACtB,QAAU,CACX,AAED,iCACE,eAAiB,CAClB,AAED,gCACE,YAAa,AACb,gBAAkB,CACnB,AAED,cACE,iBAAkB,AAClB,UAAW,AACX,UAAY,CACb,AAED,aACE,iBAAkB,AAClB,UAAW,AACX,WAAY,AACZ,cAAgB,CACjB,AAED,sBACE,YAAc,CACf,AAED,KACE,SAAW,CACZ,AAED,QACE,UAAY,CACb,AAED,GACE,SAAU,AACV,UAAW,AACX,eAAiB,CAClB,AAED,GACE,eAAiB,CAClB,AAED,GACE,SAAU,AACV,SAAW,CACZ,AAED,aACE,oBAAsB,AACtB,UAAW,AACX,gBAAiB,AACjB,4BAA6B,AAC7B,eAAiB,CAClB,AAED,gBACE,aAAe,CAChB,AAED,UACE,iBAAkB,AAClB,UAAW,AACX,gBAAiB,AACjB,0BAA4B,CAC7B,AAED,eACE,UAAW,AACX,YAAc,CACf,AAED,mBACE,YAAa,AACb,eAAgB,AAChB,mBAAsB,CACvB,AAED,iBAEE,qBAAwB,AACxB,UAAY,CACb,AAED,MACE,YAAc,CACf,AAED,OACE,UAAY,CACb,AAED,QACE,kBAAmB,AACnB,YAAa,AACb,YAAa,AACb,SAAY,AACZ,2BAA4B,AAC5B,yBAA0B,AAE1B,sBAAuB,AACvB,qBAAsB,AACtB,gBAAkB,CACnB,AAED,eACE,SAAU,AACV,UAAW,AACX,WAAa,CACd,AAED,gBACE,SAAW,CACZ,AAED,MAEE,UAAW,AACX,YAAa,AACb,gBAAqB,AACrB,aAAc,AACd,YAAc,CACf,AAED,UACE,cAAe,AACf,eAAiB,AACjB,kCAAsC,AACtC,qBAAwB,CACzB,AAED,eACE,mBAAoB,AACpB,aAAc,AACd,YAAc,CACf,AAED,SACE,mBAAqB,CACtB,AAED,yBAEE,iBAAkB,AAClB,eAAiB,AACjB,kCAAsC,AACtC,iBAAoB,CACrB,AAED,OACE,WAAY,AAEZ,+BAA0B,AAC1B,YAAc,CACf,AAED,cACE,kBAAmB,AACnB,sBAAuB,AACvB,SAAU,AACV,eAAkB,CACnB,AACD,qBACE,kBAAmB,AACnB,MAAO,AACP,OAAQ,AACR,WAAY,AACZ,WAAa,CACd,AAUD,IACE,6BAA8B,AAC9B,SAAU,AACV,gBAAiB,CAEjB,mBAAsB,CACvB,AAED,WACE,WAAY,AACZ,cAAe,AACf,QAAS,AACT,WAAa,CACd,AAMD,QACE,uBAAyB,AACzB,iBAAmB,CACpB,AAMD,SACE,SAAU,AACV,mBAAoB,AACpB,WAAY,AACZ,YAAa,AACb,gBAAiB,AACjB,UAAW,AACX,kBAAmB,AACnB,SAAW,CACZ,AAOD,mDAEE,UAAW,AACX,YAAa,AACb,SAAU,AACV,iBAAkB,AAClB,gBAAiB,AACjB,UAAY,CACb,AAMD,WACE,iBAAmB,CACpB,AAcD,iCAEE,YAAa,AAEb,aAAe,CAEhB,AAED,gBACE,UAAY,CACb,AAOD,WACE,MAAS,CACV,AAMD,mBACE,aAAc,AACd,4BAAS,AAAT,gBAAS,AAAT,iBAAS,AAAT,OAAS,CACV,AAMD,2EAEE,YAAc,CACf,AAED,iFAEE,oBAAqB,AACrB,oBAAsB,CACvB,AAED,yBACE,WACE,qBAAuB,AACvB,kBAAoB,CACrB,AACD,KACE,WAAY,AACZ,mBAAsB,CACvB,AACD,OACE,UAAY,CACb,CACF,AAED,yBACE,WACE,mBAAoB,AACpB,WAAY,AACZ,iBAAqB,AACrB,YAAa,AACb,eAAiB,CAClB,AACD,WACE,oBAAc,AAAd,qBAAc,AAAd,oBAAc,AAAd,aAAc,AACd,sBAAe,AAAf,kBAAe,AAAf,aAAe,CAChB,AACD,KACE,iBAAmB,CACpB,AACD,4BAIE,cAAiB,CAClB,AACD,OACE,UAAY,CAEb,AACD,UACE,kBAAmB,AACnB,QAAW,AACX,SAAW,CACZ,AAID,kBAFE,iCAAsC,CAiBvC,AAfD,MACE,gBAAiB,AAEjB,yBAA2B,AAE3B,YAAa,AACb,YAAa,AAEb,uBAAwB,AACxB,0BAA2B,AAC3B,UAAW,AACX,gBAAkB,AAClB,YAAa,AACb,kBAAmB,AACnB,KAAO,CACR,AACD,SACE,WAAY,AACZ,eAAkB,AAClB,gBAAkB,CACnB,AASD,uBACE,eAAgB,AAChB,gBAAmB,CAEpB,AACD,aACE,UAAW,AACX,WAAY,AACZ,kBAAoB,CACrB,AACD,cACE,UAAW,AACX,YAAa,AACb,eAAgB,AAChB,mBAAsB,CACvB,AACD,oBACE,UAAW,AACX,UAAY,CACb,AACD,mBACE,UAAW,AACX,YAAa,AACb,eAAgB,AAChB,mBAAsB,CACvB,AACD,MACE,cAAiB,CAClB,AACD,8BAGE,WAAY,AACZ,cAAgB,CACjB,AACD,oBAEE,gBAAkB,CACnB,AACD,qBACE,WAAY,AACZ,WAAY,AACZ,uCAA6C,CAC9C,AAED,4BACE,kCAAsC,AACtC,oBAAc,AAAd,qBAAc,AAAd,oBAAc,AAAd,aAAc,AACd,8BAAoB,AAApB,6BAAoB,AAApB,2BAAoB,AAApB,uBAAoB,AAApB,mBAAoB,AACpB,kBAAsB,CACvB,AACD,+BACE,mBAAQ,AAAR,eAAQ,AAAR,WAAQ,AAAR,MAAQ,CACT,AACD,iBACE,QAAU,CACX,AACD,kBACE,sBAAyB,CAC1B,AACD,mBACE,iBAAmB,CACpB,AAED,0BACE,iBAAsB,CACvB,AACD,sBACE,cAAgB,CACjB,AACD,MACE,oBAAc,AAAd,qBAAc,AAAd,oBAAc,AAAd,aAAc,AACd,8BAAoB,AAApB,6BAAoB,AAApB,2BAAoB,AAApB,uBAAoB,AAApB,mBAAoB,AACpB,uBAAgB,AAAhB,mBAAgB,AAAhB,eAAgB,AAChB,iBAAmB,CACpB,CACF,AAED,yBACE,SACE,sBAAyB,CAC1B,AAED,QACE,YAAc,CACf,AAED,UACE,kBAAmB,AACnB,SAAW,AACX,WAAa,AACb,UAAY,CACb,AAED,QAEE,WAAY,AACZ,iBAAmB,CACpB,AAED,iCALE,UAAY,CAOb,AAED,oDAEE,eAAiB,CAClB,AAED,QACE,kBAAmB,AACnB,QAAS,AACT,QAAU,CACX,AACD,aACE,SAAS,AACT,cAAe,AACf,UAAY,CACb,AACD,qBAEE,kBAAsB,AACtB,eAAiB,CAClB,AACD,SACE,oBAAsB,CACvB,AAED,4BACE,UAAY,CACb,AAED,iBACE,WAAa,CACd,AAED,6BACE,aAAiB,CAClB,AACD,cACE,SAAW,CACZ,AACD,uBACE,UAAW,AACX,gBAAiB,AACjB,UAAY,CACb,AACD,UACE,gBAAiB,AACjB,cAAgB,CACjB,AACD,mDAEE,uBAAyB,AACzB,mBAAqB,CACtB,AACD,sBACE,aAAqB,AACrB,UAAY,CACb,AAED,KACE,qBAAsB,AACtB,oBAAsB,CACvB,AACD,SACE,4BAA8B,AAC9B,UAAW,AACX,gBAAiB,AACjB,sBAAuB,AACvB,eAAiB,AACjB,YAAa,AACb,WAAY,AACZ,gBAAkB,CAGnB,AACD,4BAHE,YAAc,CAMf,AACD,6DAGE,UAAY,CACb,AACD,6BACE,WAAc,CACf,AACD,8BACE,QAAU,CACX,AACD,6BACE,WAAa,CACd,AACD,eACE,cAAgB,CACjB,AACD,oBAGE,cAAiB,CAClB,AACD,WACE,SAAW,CACZ,CACF,AAED,yBACE,MACE,0BAA8B,CAC/B,AACD,KACE,2BAA+B,CAChC,CACF,AAED,OACE,YAAa,AACb,UAAY,CACb,AAED,kBACE,gBAAiB,AACjB,iBAAmB,CACpB,AAED,yBACE,SAAU,AACV,YAAa,AACb,OAAQ,AACR,kBAAmB,AACnB,MAAO,AACP,UAAY,CACb,AAED,SAIE,2BAAqB,AAArB,4BAAqB,AAArB,2BAAqB,AAArB,oBAAqB,AACrB,4BAAuB,AAAvB,6BAAuB,AAAvB,8BAAuB,AAAvB,0BAAuB,AAAvB,qBAAuB,CACxB,AAED,WACE,YAAa,AACb,WAAa,CACd,AAQD,cACE,SAAU,AACV,eAAkB,CACnB,AAED,iBACE,gBAAiB,AACjB,qBAAsB,AACtB,gBAAmB,CACpB,AAED,YACE,YAAa,AACb,aAAc,AACd,eAAiB,AACjB,cAAe,AACf,SAAW,CACZ,AAED,kBACE,aAAe,CAChB,AAED,qBACE,cAAe,AACf,cAAgB,CACjB,AAUD,yBACE,eAAgB,AAChB,WAAY,AACZ,WAAa,AACb,mBAAqB,CACtB,AAID,0BACE,YAAc,AACd,aAAe,AACf,qBAA+B,AAC/B,qBAAsB,AACtB,gBAAiB,AACjB,kBAAmB,AACnB,6WACoY,AACpY,oCAAwB,AAAxB,qBAAwB,CACzB,AAED,oCACE,WAAY,AACZ,UAAW,AACX,YAAa,AACb,WAAY,AACZ,SAAW,CACZ,AAED,gIAGE,YAAa,AACb,UAAW,AACX,YAAa,AACb,WAAY,AACZ,gCAAiC,AAEjC,4BAA6B,AAC7B,2BAA4B,AAC5B,uBAAyB,CAC1B,AAED,8EAEE,YAAa,AACb,WAAY,AACZ,YAAa,AACb,WAAY,AACZ,+BAAgC,AAEhC,2BAA4B,AAC5B,0BAA2B,AAC3B,sBAAwB,CACzB,AAED,oFAEE,QAAS,AACT,WAAY,AACZ,YAAa,AACb,WAAY,AACZ,+BAAgC,AAEhC,2BAA4B,AAC5B,0BAA2B,AAC3B,sBAAwB,CACzB,AAED,iFAEE,OAAQ,AACR,QAAS,AACT,YAAa,AACb,WAAY,AACZ,iCAAkC,AAElC,6BAA8B,AAC9B,4BAA6B,AAC7B,wBAA0B,CAC3B,AAED,6BACE,cAAe,AACf,qBAAsB,AACtB,qBAAuB,AACvB,aAAc,AAGd,YAA6B,AAA7B,mCAA6B,AAC7B,6CAAsC,AAAtC,wCAAsC,AAAtC,qCAAsC,AACtC,UAAY,CACb,AAED,2BACE,kBAAmB,AACnB,YAAc,CACf,AAED,+BACE,yBAA0B,AAC1B,cAAe,AACf,kBAAqB,AACrB,eAAkB,AAClB,kCAAsC,AACtC,aAAe,CAChB,AAED,qCACE,yBAA0B,AAC1B,UAAa,CACd,AAED,wDACE,aAAe,CAChB,AAID,6FACE,aAAe,CAChB,AACD,mDACE,aAAe,CAChB,AAED,yBACE,6BACE,UAAY,CACb,AAED,+BAEE,kBAAmB,AACnB,cAAgB,CACjB,CACF","file":"../all.css","sourcesContent":["/*! normalize.css v1.1.0 | MIT License | git.io/normalize */\r\n\r\n/* ==========================================================================\r\n HTML5 display definitions\r\n ========================================================================== */\r\n\r\n/**\r\n * Correct `block` display not defined in IE 6/7/8/9 and Firefox 3.\r\n */\r\n\r\narticle,\r\naside,\r\ndetails,\r\nfigcaption,\r\nfigure,\r\nfooter,\r\nheader,\r\nhgroup,\r\nmain,\r\nnav,\r\nsection,\r\nsummary {\r\n display: block;\r\n}\r\n\r\n/**\r\n * Correct `inline-block` display not defined in IE 6/7/8/9 and Firefox 3.\r\n */\r\n\r\naudio,\r\ncanvas,\r\nvideo {\r\n display: inline-block;\r\n *display: inline;\r\n *zoom: 1;\r\n}\r\n\r\n/**\r\n * Prevent modern browsers from displaying `audio` without controls.\r\n * Remove excess height in iOS 5 devices.\r\n */\r\n\r\naudio:not([controls]) {\r\n display: none;\r\n height: 0;\r\n}\r\n\r\n/**\r\n * Address styling not present in IE 7/8/9, Firefox 3, and Safari 4.\r\n * Known issue: no IE 6 support.\r\n */\r\n\r\n[hidden] {\r\n display: none;\r\n}\r\n\r\n/* ==========================================================================\r\n Base\r\n ========================================================================== */\r\n\r\n/**\r\n * 1. Correct text resizing oddly in IE 6/7 when body `font-size` is set using\r\n * `em` units.\r\n * 2. Prevent iOS text size adjust after orientation change, without disabling\r\n * user zoom.\r\n */\r\n\r\nhtml {\r\n font-size: 100%; /* 1 */\r\n -webkit-text-size-adjust: 100%; /* 2 */\r\n -ms-text-size-adjust: 100%; /* 2 */\r\n}\r\n\r\n/**\r\n * Address `font-family` inconsistency between `textarea` and other form\r\n * elements.\r\n */\r\n\r\nhtml,\r\nbutton,\r\ninput,\r\nselect,\r\ntextarea {\r\n font-family: sans-serif;\r\n}\r\n\r\n/**\r\n * Address margins handled incorrectly in IE 6/7.\r\n */\r\n\r\nbody {\r\n margin: 0;\r\n}\r\n\r\n/* ==========================================================================\r\n Links\r\n ========================================================================== */\r\n\r\n/**\r\n * Address `outline` inconsistency between Chrome and other browsers.\r\n */\r\n\r\na:focus {\r\n outline: thin dotted;\r\n}\r\n\r\n/**\r\n * Improve readability when focused and also mouse hovered in all browsers.\r\n */\r\n\r\na:active,\r\na:hover {\r\n outline: 0;\r\n}\r\n\r\n/* ==========================================================================\r\n Typography\r\n ========================================================================== */\r\n\r\n/**\r\n * Address font sizes and margins set differently in IE 6/7.\r\n * Address font sizes within `section` and `article` in Firefox 4+, Safari 5,\r\n * and Chrome.\r\n */\r\n\r\nh1 {\r\n font-size: 2em;\r\n margin: 0.67em 0;\r\n}\r\n\r\nh2 {\r\n font-size: 1.5em;\r\n margin: 0.83em 0;\r\n}\r\n\r\nh3 {\r\n font-size: 1.17em;\r\n margin: 1em 0;\r\n}\r\n\r\nh4 {\r\n font-size: 1em;\r\n margin: 1.33em 0;\r\n}\r\n\r\nh5 {\r\n font-size: 0.83em;\r\n margin: 1.67em 0;\r\n}\r\n\r\nh6 {\r\n font-size: 0.67em;\r\n margin: 2.33em 0;\r\n}\r\n\r\n/**\r\n * Address styling not present in IE 7/8/9, Safari 5, and Chrome.\r\n */\r\n\r\nabbr[title] {\r\n border-bottom: 1px dotted;\r\n}\r\n\r\n/**\r\n * Address style set to `bolder` in Firefox 3+, Safari 4/5, and Chrome.\r\n */\r\n\r\nb,\r\nstrong {\r\n font-weight: bold;\r\n}\r\n\r\nblockquote {\r\n margin: 1em 40px;\r\n}\r\n\r\n/**\r\n * Address styling not present in Safari 5 and Chrome.\r\n */\r\n\r\ndfn {\r\n font-style: italic;\r\n}\r\n\r\n/**\r\n * Address differences between Firefox and other browsers.\r\n * Known issue: no IE 6/7 normalization.\r\n */\r\n\r\nhr {\r\n -moz-box-sizing: content-box;\r\n box-sizing: content-box;\r\n height: 0;\r\n}\r\n\r\n/**\r\n * Address styling not present in IE 6/7/8/9.\r\n */\r\n\r\nmark {\r\n background: #ff0;\r\n color: #000;\r\n}\r\n\r\n/**\r\n * Address margins set differently in IE 6/7.\r\n */\r\n\r\np,\r\npre {\r\n margin: 1em 0;\r\n}\r\n\r\n/**\r\n * Correct font family set oddly in IE 6, Safari 4/5, and Chrome.\r\n */\r\n\r\ncode,\r\nkbd,\r\npre,\r\nsamp {\r\n font-family: monospace, serif;\r\n _font-family: 'courier new', monospace;\r\n font-size: 1em;\r\n}\r\n\r\n/**\r\n * Improve readability of pre-formatted text in all browsers.\r\n */\r\n\r\npre {\r\n white-space: pre;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n}\r\n\r\n/**\r\n * Address CSS quotes not supported in IE 6/7.\r\n */\r\n\r\nq {\r\n quotes: none;\r\n}\r\n\r\n/**\r\n * Address `quotes` property not supported in Safari 4.\r\n */\r\n\r\nq:before,\r\nq:after {\r\n content: '';\r\n content: none;\r\n}\r\n\r\n/**\r\n * Address inconsistent and variable font size in all browsers.\r\n */\r\n\r\nsmall {\r\n font-size: 80%;\r\n}\r\n\r\n/**\r\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\r\n */\r\n\r\nsub,\r\nsup {\r\n font-size: 75%;\r\n line-height: 0;\r\n position: relative;\r\n vertical-align: baseline;\r\n}\r\n\r\nsup {\r\n top: -0.5em;\r\n}\r\n\r\nsub {\r\n bottom: -0.25em;\r\n}\r\n\r\n/* ==========================================================================\r\n Lists\r\n ========================================================================== */\r\n\r\n/**\r\n * Address margins set differently in IE 6/7.\r\n */\r\n\r\ndl,\r\nmenu,\r\nol,\r\nul {\r\n margin: 1em 0;\r\n}\r\n\r\ndd {\r\n margin: 0 0 0 40px;\r\n}\r\n\r\n/**\r\n * Address paddings set differently in IE 6/7.\r\n */\r\n\r\nmenu,\r\nol,\r\nul {\r\n padding: 0 0 0 40px;\r\n}\r\n\r\n/**\r\n * Correct list images handled incorrectly in IE 7.\r\n */\r\n\r\nnav ul,\r\nnav ol {\r\n list-style: none;\r\n list-style-image: none;\r\n}\r\n\r\n/* ==========================================================================\r\n Embedded content\r\n ========================================================================== */\r\n\r\n/**\r\n * 1. Remove border when inside `a` element in IE 6/7/8/9 and Firefox 3.\r\n * 2. Improve image quality when scaled in IE 7.\r\n */\r\n\r\nimg {\r\n border: 0; /* 1 */\r\n -ms-interpolation-mode: bicubic; /* 2 */\r\n}\r\n\r\n/**\r\n * Correct overflow displayed oddly in IE 9.\r\n */\r\n\r\nsvg:not(:root) {\r\n overflow: hidden;\r\n}\r\n\r\n/* ==========================================================================\r\n Figures\r\n ========================================================================== */\r\n\r\n/**\r\n * Address margin not present in IE 6/7/8/9, Safari 5, and Opera 11.\r\n */\r\n\r\nfigure {\r\n margin: 0;\r\n}\r\n\r\n/* ==========================================================================\r\n Forms\r\n ========================================================================== */\r\n\r\n/**\r\n * Correct margin displayed oddly in IE 6/7.\r\n */\r\n\r\nform {\r\n margin: 0;\r\n}\r\n\r\n/**\r\n * Define consistent border, margin, and padding.\r\n */\r\n\r\nfieldset {\r\n border: 1px solid #c0c0c0;\r\n margin: 0 2px;\r\n padding: 0.35em 0.625em 0.75em;\r\n}\r\n\r\n/**\r\n * 1. Correct color not being inherited in IE 6/7/8/9.\r\n * 2. Correct text not wrapping in Firefox 3.\r\n * 3. Correct alignment displayed oddly in IE 6/7.\r\n */\r\n\r\nlegend {\r\n border: 0; /* 1 */\r\n padding: 0;\r\n white-space: normal; /* 2 */\r\n *margin-left: -7px; /* 3 */\r\n}\r\n\r\n/**\r\n * 1. Correct font size not being inherited in all browsers.\r\n * 2. Address margins set differently in IE 6/7, Firefox 3+, Safari 5,\r\n * and Chrome.\r\n * 3. Improve appearance and consistency in all browsers.\r\n */\r\n\r\nbutton,\r\ninput,\r\nselect,\r\ntextarea {\r\n font-size: 100%; /* 1 */\r\n margin: 0; /* 2 */\r\n vertical-align: baseline; /* 3 */\r\n *vertical-align: middle; /* 3 */\r\n}\r\n\r\n/**\r\n * Address Firefox 3+ setting `line-height` on `input` using `!important` in\r\n * the UA stylesheet.\r\n */\r\n\r\nbutton,\r\ninput {\r\n line-height: normal;\r\n}\r\n\r\n/**\r\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\r\n * All other form control elements do not inherit `text-transform` values.\r\n * Correct `button` style inheritance in Chrome, Safari 5+, and IE 6+.\r\n * Correct `select` style inheritance in Firefox 4+ and Opera.\r\n */\r\n\r\nbutton,\r\nselect {\r\n text-transform: none;\r\n}\r\n\r\n/**\r\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\r\n * and `video` controls.\r\n * 2. Correct inability to style clickable `input` types in iOS.\r\n * 3. Improve usability and consistency of cursor style between image-type\r\n * `input` and others.\r\n * 4. Remove inner spacing in IE 7 without affecting normal text inputs.\r\n * Known issue: inner spacing remains in IE 6.\r\n */\r\n\r\nbutton,\r\nhtml input[type=\"button\"], /* 1 */\r\ninput[type=\"reset\"],\r\ninput[type=\"submit\"] {\r\n -webkit-appearance: button; /* 2 */\r\n cursor: pointer; /* 3 */\r\n *overflow: visible; /* 4 */\r\n}\r\n\r\n/**\r\n * Re-set default cursor for disabled elements.\r\n */\r\n\r\nbutton[disabled],\r\nhtml input[disabled] {\r\n cursor: default;\r\n}\r\n\r\n/**\r\n * 1. Address box sizing set to content-box in IE 8/9.\r\n * 2. Remove excess padding in IE 8/9.\r\n * 3. Remove excess padding in IE 7.\r\n * Known issue: excess padding remains in IE 6.\r\n */\r\n\r\ninput[type=\"checkbox\"],\r\ninput[type=\"radio\"] {\r\n box-sizing: border-box; /* 1 */\r\n padding: 0; /* 2 */\r\n *height: 13px; /* 3 */\r\n *width: 13px; /* 3 */\r\n}\r\n\r\n/**\r\n * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.\r\n * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome\r\n * (include `-moz` to future-proof).\r\n */\r\n\r\ninput[type=\"search\"] {\r\n -webkit-appearance: textfield; /* 1 */\r\n -moz-box-sizing: content-box;\r\n -webkit-box-sizing: content-box; /* 2 */\r\n box-sizing: content-box;\r\n}\r\n\r\n/**\r\n * Remove inner padding and search cancel button in Safari 5 and Chrome\r\n * on OS X.\r\n */\r\n\r\ninput[type=\"search\"]::-webkit-search-cancel-button,\r\ninput[type=\"search\"]::-webkit-search-decoration {\r\n -webkit-appearance: none;\r\n}\r\n\r\n/**\r\n * Remove inner padding and border in Firefox 3+.\r\n */\r\n\r\nbutton::-moz-focus-inner,\r\ninput::-moz-focus-inner {\r\n border: 0;\r\n padding: 0;\r\n}\r\n\r\n/**\r\n * 1. Remove default vertical scrollbar in IE 6/7/8/9.\r\n * 2. Improve readability and alignment in all browsers.\r\n */\r\n\r\ntextarea {\r\n overflow: auto; /* 1 */\r\n vertical-align: top; /* 2 */\r\n}\r\n\r\n/* ==========================================================================\r\n Tables\r\n ========================================================================== */\r\n\r\n/**\r\n * Remove most spacing between table cells.\r\n */\r\n\r\ntable {\r\n border-collapse: collapse;\r\n border-spacing: 0;\r\n}\r\n;/* http://prismjs.com/download.html?themes=prism-coy&languages=markup+css+css-extras+clike+javascript+java&plugins=line-numbers */\r\n\r\n/*\r\n\r\n * p5.js highlighting based on the prism.js Coy theme for JavaScript, CoffeeScript, CSS and HTML\r\n * Based on https://github.com/tshedor/workshop-wp-theme (Example: http://workshop.kansan.com/category/sessions/basics or http://workshop.timshedor.com/category/sessions/basics);\r\n * @author Tim Shedor\r\n\r\n*/\r\n\r\ncode[class*=\"language-\"],\r\npre[class*=\"language-\"],\r\ntextarea {\r\n color: #222;\r\n font-family:\r\n 'Inconsolata',\r\n Consolas,\r\n Monaco,\r\n 'Andale Mono',\r\n monospace;\r\n direction: ltr;\r\n text-align: left;\r\n white-space: pre;\r\n word-spacing: normal;\r\n word-break: normal;\r\n -moz-tab-size: 4;\r\n -o-tab-size: 4;\r\n tab-size: 4;\r\n -webkit-hyphens: none;\r\n -moz-hyphens: none;\r\n -ms-hyphens: none;\r\n hyphens: none;\r\n font-size: 1em !important;\r\n}\r\n\r\n/* Code blocks */\r\npre[class*=\"language-\"] {\r\n position:relative;\r\n padding: 0.5em 1.0em;\r\n margin: 0.5em 0 0 -0.5em;\r\n border-left: 0.5em solid #AFAFAF; /* coy og blue 10px solid 358ccb */\r\n background-color: #fff; /* coy og white #fdfdfd */\r\n /* lines */\r\n background-image: -webkit-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.06) 50%);\r\n background-image: -moz-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.06) 50%);\r\n background-image: -ms-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.06) 50%);\r\n background-image: -o-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.06) 50%);\r\n background-image: linear-gradient(transparent 50%, rgba(69, 142, 209, 0.06) 50%);\r\n background-size: 2.9em 2.9em; /* adjusts height of alternating lines */\r\n background-origin:content-box;\r\n /* set overflow to just let the code roll */\r\n overflow:auto;\r\n /* or uncomment this to let an inner vertical scroll be triggered,\r\n but be generous as to when\r\n max-height:36em; */\r\n}\r\n\r\ncode[class*=\"language\"] {\r\n}\r\n\r\n\r\n:not(pre) > code[class*=\"language-\"],\r\npre[class*=\"language-\"] {\r\n margin-bottom: 1em;\r\n}\r\n\r\n/* Inline code */\r\n:not(pre) > code[class*=\"language-\"] {\r\n position:relative;\r\n padding: .2em;\r\n -webkit-border-radius: 0.3em;\r\n -moz-border-radius: 0.3em;\r\n -ms-border-radius: 0.3em;\r\n -o-border-radius: 0.3em;\r\n border-radius: 0.3em;\r\n color: #333;\r\n border: 1px solid rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n\r\n:not(pre) > code[class*=\"language-\"]:after,\r\npre[class*=\"language-\"]:after {\r\n right: 0.75em;\r\n left: auto;\r\n}\r\n\r\n/* code colors */\r\n.token.comment,\r\n.token.block-comment,\r\n.token.prolog,\r\n.token.doctype,\r\n.token.cdata {\r\n color: #A0A0A0; /* light gray */ /* 727272 898189 919191 A0A0A0 AFAFAF BEBEBE coy og: #7D8B99; */\r\n}\r\n\r\n.token.punctuation {\r\n color: #666; /* darker gray */ /* og coy 5F6364 */\r\n}\r\n\r\n.token.property,\r\n.token.tag,\r\n.token.boolean,\r\n.token.number,\r\n.token.function-name,\r\n.token.constant,\r\n.token.symbol {\r\n color: #DC3787; /* not p5 pink, but related */ /* og coy c92c2c a reddish color */\r\n}\r\n\r\n.token.selector,\r\n.token.attr-name,\r\n.token.string,\r\n.token.function,\r\n.token.builtin {\r\n color: #00A1D3; /* blue */ /* 877923 */ /* og coy 2f9c0a - green */\r\n}\r\n\r\n.token.operator,\r\n.token.entity,\r\n.token.url,\r\n.token.variable {\r\n color: #a67f59; /* og coy a67f59 a light brown */\r\n background: rgba(255, 255, 255, 0.5);\r\n}\r\n\r\n.token.atrule,\r\n.token.attr-value,\r\n.token.keyword,\r\n.token.class-name {\r\n color: #704F21; /* 9F944F brown */ /* og coy #1990b8 blue */\r\n}\r\n\r\n.token.regex,\r\n.token.important {\r\n color: #e90; /* og coy e90 orange */\r\n}\r\n.language-css .token.string,\r\n.style .token.string {\r\n color: #a67f59; /* og coy a67f59 a light brown */\r\n background: rgba(255, 255, 255, 0.5);\r\n}\r\n\r\n.token.important {\r\n font-weight: normal;\r\n}\r\n\r\n.token.entity {\r\n cursor: help;\r\n}\r\n\r\n.namespace {\r\n opacity: .7;\r\n}\r\n\r\n@media screen and (max-width:767px){\r\n pre[class*=\"language-\"]:before,\r\n pre[class*=\"language-\"]:after {\r\n bottom:14px;\r\n -webkit-box-shadow:none;\r\n -moz-box-shadow:none;\r\n box-shadow:none;\r\n }\r\n\r\n}\r\n\r\n/* Plugin styles */\r\n.token.tab:not(:empty):before,\r\n.token.cr:before,\r\n.token.lf:before {\r\n color: #e0d7d1; /* og coy very light brown */\r\n}\r\n\r\npre.line-numbers {\r\n position: relative;\r\n padding-left: 3.8em;\r\n counter-reset: linenumber;\r\n}\r\n\r\npre.line-numbers > code {\r\n position: relative;\r\n}\r\n\r\n.line-numbers .line-numbers-rows {\r\n position: absolute;\r\n pointer-events: none;\r\n top: 0;\r\n font-size: 100%;\r\n left: -3.8em;\r\n width: 3em; /* works for line-numbers below 1000 lines */\r\n letter-spacing: -1px;\r\n border-right: 1px solid #999;\r\n\r\n -webkit-user-select: none;\r\n -moz-user-select: none;\r\n -ms-user-select: none;\r\n user-select: none;\r\n\r\n}\r\n\r\n.line-numbers-rows > span {\r\n pointer-events: none;\r\n display: block;\r\n counter-increment: linenumber;\r\n}\r\n\r\n.line-numbers-rows > span:before {\r\n content: counter(linenumber);\r\n color: #999;\r\n display: block;\r\n padding-right: 0.8em;\r\n text-align: right;\r\n}\r\n;/*\r\n * HTML5 Boilerplate\r\n *\r\n * What follows is the result of much research on cross-browser styling.\r\n * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,\r\n * Kroc Camen, and the H5BP dev community and team.\r\n */\r\n\r\n/* ==========================================================================\r\n Base styles: opinionated defaults\r\n ========================================================================== */\r\n\r\nhtml,\r\nbutton,\r\ninput,\r\nselect {\r\n color: #222;\r\n}\r\n\r\ntextarea {\r\n line-height: 1.45em;\r\n padding: 0.5em 1em 0.5em 1em;\r\n border: none;\r\n}\r\n\r\nbody {\r\n font-size: 1em;\r\n line-height: 1.4;\r\n}\r\n\r\n/*\r\n * Remove text-shadow in selection highlight: h5bp.com/i\r\n * These selection rule sets have to be separate.\r\n * Customize the background color to match your design.\r\n */\r\n\r\n::-moz-selection {\r\n background: #b3d4fc;\r\n text-shadow: none;\r\n}\r\n\r\n::selection {\r\n background: #b3d4fc;\r\n text-shadow: none;\r\n}\r\n\r\n/*\r\n * A better looking default horizontal rule\r\n */\r\n\r\nhr {\r\n display: block;\r\n height: 1px;\r\n border: 0;\r\n border-top: 1px solid #ccc;\r\n margin: 1em 0;\r\n padding: 0;\r\n}\r\n\r\n/*\r\n * Remove the gap between images and the bottom of their containers: h5bp.com/i/440\r\n */\r\n\r\nimg {\r\n vertical-align: middle;\r\n}\r\n\r\nimg.med_left {\r\n width: 300px;\r\n float: left;\r\n}\r\n\r\nimg.med_right {\r\n width: 300px;\r\n float: right;\r\n}\r\n\r\nimg.small_left {\r\n width: 200px;\r\n float: left;\r\n}\r\n\r\nimg.smaller_left {\r\n width: 140px;\r\n float: left;\r\n}\r\n\r\nimg.small_right {\r\n width: 200px;\r\n float: right;\r\n}\r\n\r\nimg.smaller_right {\r\n width: 140px;\r\n float: right;\r\n}\r\n\r\nimg.small_center {\r\n width: 200px;\r\n margin-left: 250px;\r\n}\r\n\r\nimg.small {\r\n width: 160px;\r\n}\r\n\r\nimg.med {\r\n width: 400px;\r\n}\r\n\r\nimg.med_center {\r\n width: 400px;\r\n margin-left: 150px;\r\n}\r\n\r\n/*\r\n * Remove default fieldset styles.\r\n */\r\n\r\nfieldset {\r\n border: 0;\r\n margin: 0;\r\n padding: 0;\r\n}\r\n\r\n/*\r\n * Allow only vertical resizing of textareas.\r\n */\r\n\r\ntextarea {\r\n resize: vertical;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n HOMEPAGE\r\n //////////////////////////////////////////////////\r\n*/\r\n.tagline {\r\n display: none;\r\n}\r\n\r\n#home-page .home {\r\n pointer-events: none;\r\n}\r\n\r\n#home-page .home a {\r\n pointer-events: all;\r\n}\r\n\r\n#lockup > a {\r\n position: relative;\r\n display: block;\r\n width: 200px;\r\n height: 90px;\r\n}\r\n\r\n#logo_image {\r\n position: absolute;\r\n top: 0;\r\n}\r\n\r\n#menu.top_menu,\r\n#menu {\r\n list-style: none;\r\n font-family: 'Montserrat', sans-serif;\r\n width: 100%;\r\n margin: 0 0 1em 0;\r\n padding: 0;\r\n height: 100%;\r\n font-size: 1.3em;\r\n}\r\n\r\n#menu.top_menu li {\r\n display: inline;\r\n}\r\n\r\n#home-sketch {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n z-index: -2;\r\n}\r\n\r\n/* <======== Styling for responsive menu bar ========> */\r\n\r\n@media screen and (max-width: 780px) {\r\n .sidebar-menu {\r\n clear: both;\r\n max-height: 0;\r\n transition: max-height 0.4s ease-out;\r\n overflow: hidden;\r\n }\r\n\r\n .sidebar-menu-nav-element {\r\n width: 91vw;\r\n }\r\n\r\n .sidebar-menu a {\r\n display: block;\r\n text-align: center;\r\n padding-bottom: 0.11em;\r\n border-bottom: 0.11em dashed transparent;\r\n }\r\n\r\n .sidebar-menu-icon {\r\n top: 2rem;\r\n cursor: pointer;\r\n float: right;\r\n padding: 28px 20px;\r\n position: relative;\r\n user-select: none;\r\n margin-bottom: 5rem;\r\n }\r\n\r\n .sidebar-menu-icon .sidebar-nav-icon {\r\n background: #ed225d;\r\n display: block;\r\n height: 2px;\r\n position: relative;\r\n transition: background 0.4s ease-out;\r\n width: 18px;\r\n }\r\n\r\n .sidebar-menu-icon .sidebar-nav-icon:before,\r\n .sidebar-menu-icon .sidebar-nav-icon:after {\r\n background: #ed225d;\r\n content: '';\r\n display: block;\r\n height: 100%;\r\n position: absolute;\r\n transition: all 0.4s ease-out;\r\n width: 100%;\r\n }\r\n\r\n .sidebar-menu-icon .sidebar-nav-icon:before {\r\n top: 5px;\r\n }\r\n\r\n .sidebar-menu-icon .sidebar-nav-icon:after {\r\n top: -5px;\r\n }\r\n\r\n .sidebar-menu-btn {\r\n display: none;\r\n }\r\n\r\n .sidebar-menu-btn:checked ~ .sidebar-menu {\r\n max-height: 475px;\r\n }\r\n\r\n .sidebar-menu-btn:checked ~ .sidebar-menu-icon .sidebar-nav-icon {\r\n background: transparent;\r\n }\r\n\r\n .sidebar-menu-btn:checked ~ .sidebar-menu-icon .sidebar-nav-icon:before {\r\n transform: rotate(-45deg);\r\n top: 0;\r\n }\r\n\r\n .sidebar-menu-btn:checked ~ .sidebar-menu-icon .sidebar-nav-icon:after {\r\n transform: rotate(45deg);\r\n top: 0;\r\n }\r\n}\r\n\r\n.sidebar-menu-btn {\r\n display: none;\r\n}\r\n\r\n/* <=================================================> */\r\n\r\n#home-sketch-frame {\r\n position: fixed;\r\n width: 100%;\r\n height: 100%;\r\n left: 0;\r\n top: 0;\r\n z-index: -2;\r\n overflow: hidden;\r\n pointer-events: all;\r\n border: 0;\r\n}\r\n\r\n#credits {\r\n position: fixed;\r\n bottom: 0;\r\n left: 0;\r\n z-index: 2;\r\n padding: 1em;\r\n font-size: 0.7em;\r\n}\r\n\r\n#skip-to-content {\r\n position: absolute;\r\n left: 0px;\r\n top: 40px;\r\n z-index: 5;\r\n background-color: #ed225d;\r\n color: white;\r\n width: auto;\r\n height: 50px;\r\n border: none;\r\n outline-style: none;\r\n text-align: center;\r\n font-size: 25px;\r\n padding: 5px;\r\n opacity: 0;\r\n}\r\n\r\n#skip-to-content:focus {\r\n opacity: 1;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n DOWNLOAD PAGE\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n.button_box {\r\n border: 1px solid #ed225d;\r\n padding: 0.4em 0.6em;\r\n margin: 0.5em 0;\r\n color: #333;\r\n font-family: 'Montserrat', sans-serif;\r\n display: inline-block;\r\n}\r\n\r\n.download_box {\r\n border: 1px solid #ed225d;\r\n padding: 0.4em;\r\n margin: 0 1.75em 0 0;\r\n width: 18.65em;\r\n float: left;\r\n color: #333;\r\n height: 7.45em;\r\n position: relative;\r\n}\r\n\r\n.download_box:hover,\r\n.button_box:hover {\r\n border: 1px solid #ed225d;\r\n background: #ed225d;\r\n color: #ffffff;\r\n}\r\n\r\n.download_box.half_box {\r\n width: 10.83em;\r\n margin-right: 1.75em;\r\n float: left;\r\n}\r\n\r\n.download_box.half_box.last_box {\r\n margin-right: 0;\r\n}\r\n\r\n.download_box .download_name {\r\n font-size: 1em;\r\n margin: 0;\r\n padding-bottom: 0.3em;\r\n border-bottom: 0.09em dashed;\r\n border-bottom-color: #ed225d;\r\n line-height: 1.2;\r\n font-family: 'Montserrat', sans-serif;\r\n display: block;\r\n}\r\n\r\n.download_box:hover .download_name {\r\n -webkit-text-stroke-width: 0;\r\n border-bottom-color: #fff;\r\n}\r\n\r\n.download_box p {\r\n font-size: 0.65em;\r\n margin: 0;\r\n position: absolute;\r\n bottom: 1em;\r\n}\r\n\r\n.download_box svg {\r\n height: 0.65em;\r\n width: 0.65em;\r\n position: absolute;\r\n bottom: 3.5em;\r\n}\r\n\r\n.download_box:hover svg {\r\n fill: white;\r\n}\r\n\r\n.download_box h4 + p {\r\n display: block;\r\n}\r\n\r\n#download-page .link_group {\r\n width: 100%;\r\n margin-bottom: 3em;\r\n}\r\n\r\n.download_box {\r\n margin-top: 1em;\r\n}\r\n\r\n.support div.download_box {\r\n margin-top: 1em;\r\n margin-bottom: 1em;\r\n}\r\n\r\n#download-page .support p {\r\n font-size: 0.8em;\r\n position: static;\r\n margin-top: 0.3em;\r\n}\r\n\r\n#slideshow {\r\n margin: 1em 0;\r\n}\r\n\r\n#slideshow p {\r\n font-size: 0.8em;\r\n color: #ababab;\r\n line-height: 1.2em;\r\n margin-top: 0.5em;\r\n}\r\n\r\n.extra {\r\n color: white;\r\n position: absolute;\r\n bottom: 0.65em;\r\n right: 0.9em;\r\n font-weight: bold;\r\n -ms-transform: rotate(-12deg);\r\n -webkit-transform: rotate(-12deg);\r\n transform: rotate(-12deg);\r\n font-size: 0.8em;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n GET STARTED\r\n //////////////////////////////////////////////////\r\n*/\r\n#get-started-page .edit_space {\r\n position: relative;\r\n order: 3;\r\n margin-bottom: 4.8125em;\r\n}\r\n#get-started-page .edit_space .copy_button{\r\n color: #2d7bb6;\r\n border-color: rgba(45, 123, 182, 0.25);\r\n float: right;\r\n margin: 1.5em 0 1.5em 0.5em;\r\n background: rgba(255, 255, 255, 0.7);\r\n position: absolute;\r\n z-index: 2;\r\n left: 31.33em;\r\n top: -1.5em;\r\n}\r\n/* To make get-started-page responsive */\r\n@media (max-width: 780px) {\r\n #get-started-page .edit_space .copy_button{\r\n left: 6.44em;\r\n }\r\n}\r\n@media (max-width: 600px) {\r\n #get-started-page .edit_space .copy_button{\r\n left: 5.91em;\r\n }\r\n}\r\n/*\r\n //////////////////////////////////////////////////\r\n EXAMPLES\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n#examples-page .column {\r\n margin-bottom: 2em;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n REFERENCE\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n#reference-page main h1 {\r\n float: left;\r\n}\r\n\r\n.reference-group h2 {\r\n font-size: 1.5em;\r\n}\r\n\r\n.reference-group h3 {\r\n font-size: 1em;\r\n font-family: 'Montserrat', sans-serif;\r\n margin-top: 0.5em;\r\n}\r\n\r\ndiv.reference-group {\r\n display: inline-block;\r\n}\r\n\r\ndiv.reference-subgroups {\r\n margin: 0;\r\n display: flex;\r\n flex-direction: row;\r\n flex-wrap: wrap;\r\n}\r\ndiv.reference-subgroup {\r\n width: 11em;\r\n margin-bottom: 1em;\r\n}\r\n\r\n#reference-page .params table p {\r\n /* Recently-added support for Markdown means that every parameter\r\n * description is wrapped in a paragraph element. (Previously, they weren't\r\n * wrapped in any kind of element.)\r\n *\r\n * We may eventually want to display paragraphs as blocks, so that we\r\n * can have lengthy descriptions for parameters, but for now we'll\r\n * keep our pre-existing behavior and essentially make paragraphs\r\n * \"invisible\" by rendering them inline. */\r\n display: inline;\r\n font-size: inherit;\r\n}\r\n\r\n#reference-page .param-optional {\r\n color: #afafaf;\r\n}\r\n\r\n#item {\r\n width: 100%;\r\n}\r\n\r\n#item h2 {\r\n margin: 0.777em 0 0 0;\r\n font-size: 1.444em;\r\n font-weight: inherit;\r\n font-family: 'Inconsolata', consolas, monospace;\r\n color: #00a1d3;\r\n}\r\n\r\n#item h3 {\r\n font-size: 1.33em;\r\n margin: 1em 0 0 0;\r\n}\r\n\r\n#item ul {\r\n margin-top: 0.5em;\r\n}\r\n\r\n#item li {\r\n margin-bottom: 1em;\r\n}\r\n\r\n.description {\r\n clear: both;\r\n display: block;\r\n width: 100%;\r\n}\r\n\r\n.syntax pre {\r\n width: 100%;\r\n}\r\n\r\n.item-wrapper,\r\n.list-wrapper {\r\n float: left;\r\n outline: none;\r\n}\r\n\r\n.paramname {\r\n display: inline-block;\r\n min-width: 25%;\r\n margin-right: 1%;\r\n font-size: 1.2em;\r\n}\r\n\r\n.paramtype p {\r\n display: inline;\r\n font-size: 1em;\r\n}\r\n\r\n.paramtype {\r\n display: inline-block;\r\n font-size: 1.2em;\r\n width: 73%;\r\n vertical-align: top;\r\n}\r\n\r\n#library-page .group-name {\r\n display: inline-block;\r\n}\r\n\r\n#library-page .group-name:hover {\r\n color: #ed225d;\r\n}\r\n\r\n/* EXAMPLES IN REF */\r\n\r\n.example div {\r\n position: relative;\r\n}\r\n\r\n.example-content .example_code {\r\n position: relative;\r\n left: 1em;\r\n padding-top: 0;\r\n margin-top: 1rem;\r\n border: none;\r\n width: 30.5em;\r\n max-width: 100%;\r\n}\r\n\r\n.example-content .example_code.norender {\r\n left: 0px;\r\n margin-left: 0;\r\n}\r\n\r\n.example-content .edit_space {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n margin-top: -0.5em;\r\n width: 100%;\r\n pointer-events: none;\r\n}\r\n\r\n.example-content .edit_space * {\r\n pointer-events: auto;\r\n}\r\n\r\n.example-content .edit_space ul {\r\n display: flex;\r\n flex-direction: row-reverse;\r\n position: relative;\r\n pointer-events: none;\r\n}\r\n\r\n.example-content .edit_space ul li button {\r\n font-family: 'Montserrat', sans-serif;\r\n font-size: 1em;\r\n color: #ccc;\r\n border: 1px solid rgba(200, 200, 200, 0.15);\r\n background: transparent;\r\n outline: none;\r\n margin-top: 0.25em;\r\n}\r\n\r\n.example-content .edit_space ul li button:hover,\r\n.example_container.editing ul li button {\r\n color: #2d7bb6;\r\n border-color: rgba(45, 123, 182, 0.25);\r\n}\r\n\r\n.example-content .edit_space .edit_area {\r\n position: absolute;\r\n top: 0.5em;\r\n left: 120px;\r\n width: 30.5em;\r\n padding-top: 1.5rem;\r\n display: none;\r\n font-family: monospace;\r\n padding: 1.5em 0.5em 0.5em 0.5em;\r\n font-size: 15pt;\r\n}\r\n\r\n.display_button {\r\n margin-bottom: 2em;\r\n font-family: 'Montserrat', sans-serif;\r\n font-size: 1em;\r\n color: #2d7bb6;\r\n border: 1px solid rgba(45, 123, 182, 0.25);\r\n background: transparent;\r\n outline: none;\r\n}\r\n\r\n.example-content .example_container {\r\n width: 36em;\r\n max-width: 100%;\r\n border-top: 0.09em dashed;\r\n border-top-color: #333;\r\n padding-top: 0.5em;\r\n margin-top: 2em;\r\n min-height: 120px;\r\n height: calc(100% * 1.1 + 20px);\r\n display: flex;\r\n}\r\n\r\n.example-content .example_container:first-of-type {\r\n margin-top: 1em;\r\n}\r\n\r\n/*to make ref example responsive*/\r\n@media (max-width: 600px) {\r\n .example-content .example_code {\r\n margin-top: 0.2rem;\r\n left: 0.5rem;\r\n }\r\n\r\n .example-content .example_container {\r\n width: 100%;\r\n min-height: 220px;\r\n height: calc(100% * 1.1 + 120px);\r\n display: block;\r\n }\r\n\r\n .example-content .edit_space .edit_area {\r\n top: calc(120px + 1em);\r\n left: 0;\r\n width: 100%;\r\n padding: 0.5em;\r\n }\r\n\r\n .example_container button {\r\n top: 124px;\r\n }\r\n\r\n .description {\r\n margin-top: 3rem;\r\n }\r\n\r\n .edit_button {\r\n left: 0;\r\n }\r\n\r\n .reset_button {\r\n left: 2.58em;\r\n }\r\n\r\n .copy_button {\r\n left: 5.91em;\r\n }\r\n}\r\n\r\nform {\r\n pointer-events: all;\r\n}\r\n\r\n#search_button {\r\n background: url(../img/search.png) 100% no-repeat;\r\n}\r\n\r\n#search input[type='text'],\r\n#search input[type='search'] {\r\n border: 1px solid rgba(200, 200, 200, 0.5);\r\n font-family: 'Montserrat', sans-serif;\r\n font-size: 2.25em;\r\n width: 9.75em;\r\n}\r\n\r\n#search ::-webkit-input-placeholder,\r\n#search .twitter-typeahead .tt-hint {\r\n color: #ccc;\r\n}\r\n\r\n:-moz-placeholder,\r\n::-moz-placeholder,\r\n:-ms-input-placeholder {\r\n color: #ccc;\r\n}\r\n\r\n#search input[type='text']:focus {\r\n color: #2d7bb6;\r\n outline-color: #2d7bb6;\r\n outline-width: 1px;\r\n outline-style: solid;\r\n}\r\n\r\n#search .twitter-typeahead .tt-dropdown-menu {\r\n background-color: #fff;\r\n border: 1px solid rgba(0, 0, 0, 0.2);\r\n overflow-y: auto;\r\n font-size: 1em;\r\n line-height: 1.4em;\r\n}\r\n\r\n#search .twitter-typeahead .tt-suggestion.tt-cursor {\r\n color: #333;\r\n background-color: #eee;\r\n}\r\n\r\n#search .twitter-typeahead .tt-suggestion p {\r\n margin: 0;\r\n}\r\n\r\n#search .twitter-typeahead .tt-suggestion p .small {\r\n font-size: 12px;\r\n color: #666;\r\n}\r\n\r\n#search {\r\n float: right;\r\n}\r\n\r\n#search .twitter-typeahead .tt-dropdown-menu {\r\n border: 1px solid rgba(0, 0, 0, 0.2);\r\n padding: 0.5em;\r\n max-height: 200px;\r\n overflow-y: auto;\r\n font-size: 1em;\r\n line-height: 1.4em;\r\n}\r\n\r\n#search .twitter-typeahead .tt-suggestion {\r\n padding: 3px 20px;\r\n line-height: 24px;\r\n cursor: pointer;\r\n}\r\n\r\n#search .twitter-typeahead .empty-message {\r\n padding: 8px 20px 1px 20px;\r\n font-size: 14px;\r\n line-height: 24px;\r\n}\r\n\r\n#search_button {\r\n float: right;\r\n}\r\n\r\na.code.core {\r\n color: #333;\r\n}\r\n\r\na.code.addon {\r\n color: #704f21;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n CONTRIBUTORS FORM\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n Contributors\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n#contribute-item {\r\n font-size: 0.75em;\r\n text-align: left;\r\n display: inline-block;\r\n width: 320px;\r\n height: 250px;\r\n float: left;\r\n border: 1px solid #ed225d;\r\n margin: 0 25px 25px 0;\r\n position: relative;\r\n}\r\n\r\n.contribute-item-container {\r\n position: absolute;\r\n z-index: 20;\r\n margin: 0;\r\n padding: 10px;\r\n}\r\n\r\n.container {\r\n /* width: 100px;*/\r\n height: 100px;\r\n position: relative;\r\n background: white;\r\n margin-top: 1.5em; /* temp promo */\r\n}\r\n\r\n#navi,\r\n#infoi {\r\n width: 100%;\r\n height: 100%;\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n}\r\n\r\n#infoi {\r\n z-index: 10;\r\n}\r\n\r\nh3.contribute-title {\r\n font-size: 1.33em;\r\n margin: 0 0 27px 0;\r\n padding-bottom: 0.3em;\r\n border-bottom: 0.09em dashed;\r\n border-bottom-color: #ed225d;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n LIBRARIES / LEARN\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n.label {\r\n position: relative;\r\n}\r\n\r\n.label .nounderline img {\r\n margin: 0.5em 0 0 0;\r\n}\r\n\r\n.label h3 {\r\n color: white;\r\n position: absolute;\r\n top: 0;\r\n margin: 1em;\r\n}\r\n\r\n.label:hover h3 {\r\n color: #ed225d;\r\n}\r\n\r\nh3 {\r\n font-size: 1.33em;\r\n margin: 1em 0 0 0;\r\n}\r\n\r\n.bullet-list {\r\n padding: 0 0 0 40px;\r\n list-style: disc;\r\n}\r\n\r\n#libraries-page .label h3{\r\n background-color: black;\r\n padding:0px 5px;\r\n}\r\n\r\n#learn-page .label .nounderline img {\r\n height: fit-content;\r\n}\r\n\r\n#learn-page .info {\r\n display: inline-block;\r\n}\r\n\r\n#exampleDisplay,\r\n#exampleFrame,\r\n#exampleEditor {\r\n width: 36em;\r\n border: none;\r\n}\r\n\r\n#exampleDisplay {\r\n display: flex;\r\n flex-flow: column;\r\n}\r\n\r\n#popupExampleFrame {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n z-index: 1000;\r\n border: none;\r\n}\r\n\r\n#exampleDisplay button {\r\n color: #2d7bb6;\r\n border-color: rgba(45, 123, 182, 0.25);\r\n float: right;\r\n margin: 0.5em 0 0 0.5em;\r\n background: rgba(255, 255, 255, 0.7);\r\n position: absolute;\r\n left: 0;\r\n z-index: 2;\r\n}\r\n\r\n#exampleDisplay .edit_button {\r\n left: 25.42em;\r\n top: -2.5em;\r\n}\r\n\r\n#exampleDisplay .reset_button {\r\n left: 28em;\r\n top: -2.5em;\r\n}\r\n\r\n#exampleDisplay .copy_button {\r\n left: 31.33em;\r\n top: -2.5em;\r\n}\r\n\r\n#exampleDisplay button:hover {\r\n background: #fff;\r\n}\r\n\r\n#exampleDisplay .edit_space {\r\n position: relative;\r\n order: 3;\r\n}\r\n\r\n#exampleDisplay #exampleFrame {\r\n height: 22em;\r\n order: 2;\r\n}\r\n\r\n#exampleDisplay #exampleEditor {\r\n height: 500em;\r\n width: 710px;\r\n overflow: hidden;\r\n margin-top: 0.5em;\r\n color: #222;\r\n font-family: 'Inconsolata', consolas, monospace;\r\n font-size: 1em;\r\n background-color: #fff;\r\n line-height: 1em;\r\n order: 4;\r\n}\r\n\r\n#exampleDisplay #exampleEditor .ace_gutter-cell {\r\n background-image: none;\r\n padding-left: 10px;\r\n overflow: hidden;\r\n background-color: #afafaf;\r\n}\r\n\r\n#exampleDisplay #exampleEditor .ace_gutter-cell.ace_info {\r\n background-color: #d7e5f5;\r\n}\r\n\r\n#exampleDisplay #exampleEditor .ace_gutter-cell.ace_warning {\r\n background-color: #ffd700;\r\n color: #ffffff;\r\n}\r\n\r\n#exampleDisplay #exampleEditor .ace_gutter-cell.ace_error {\r\n background-color: #ff6347;\r\n color: #ffffff;\r\n}\r\n\r\n/* property, tag, boolean,\r\n number, function-name, constant,\r\n symbol */\r\n\r\n#exampleDisplay #exampleEditor .ace_numeric,\r\n#exampleDisplay #exampleEditor .ace_tag {\r\n color: #dc3787;\r\n /* not p5 pink, but related */\r\n}\r\n\r\n/* atrule, attr-value, keyword,\r\n class-name */\r\n\r\n#exampleDisplay #exampleEditor .ace_type,\r\n#exampleDisplay #exampleEditor .ace_class,\r\n#exampleDisplay #exampleEditor .ace_attribute-name {\r\n color: #704f21;\r\n /* darker brown */\r\n}\r\n\r\n/* selector, attr-name,\r\nfunction, builtin */\r\n\r\n#exampleDisplay #exampleEditor .ace_function,\r\n#exampleDisplay #exampleEditor .ace_keyword,\r\n#exampleDisplay #exampleEditor .ace_support {\r\n color: #00a1d3;\r\n /* not p5 blue, but related */\r\n}\r\n\r\n/* comment, block-comment, prolog,\r\n doctype, cdata */\r\n\r\n#exampleDisplay #exampleEditor .ace_comment {\r\n color: #a0a0a0;\r\n /* light gray */\r\n}\r\n\r\n/* operator, entity, url,\r\nvariable */\r\n\r\n#exampleDisplay #exampleEditor .ace_string {\r\n color: #a67f59;\r\n /* og coy a67f59 a light brown */\r\n}\r\n\r\n#exampleDisplay #exampleEditor .ace_operator {\r\n color: #333;\r\n}\r\n\r\n/* regex, important */\r\n\r\n#exampleDisplay #exampleEditor .ace_regexp {\r\n color: #e90;\r\n /* og coy e90 orange */\r\n}\r\n\r\n#exampleDisplay #exampleEditor .ace-gutter {\r\n color: #333;\r\n}\r\n\r\n#exampleDisplay #exampleEditor .ace-gutter-layer {\r\n color: #333;\r\n}\r\n\r\n#exampleDisplay #exampleEditor .ace_folding-enabled {\r\n width: 10px !important;\r\n color: #333;\r\n}\r\n\r\n.attribution {\r\n background-color: #eee;\r\n font-size: 15px;\r\n padding: 10px;\r\n margin: 30px 0px 30px 0px;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n SHOWCASE\r\n //////////////////////////////////////////////////\r\n*/\r\n#featuring {\r\n margin-bottom: 1em;\r\n}\r\n\r\n#showcase-page .showcase-intro h1 {\r\n font: italic 900 14.5vw 'Montserrat', sans-serif;\r\n color: #ed225d;\r\n text-align: left;\r\n text-transform: uppercase;\r\n}\r\n\r\n#showcase-page .showcase-intro p {\r\n font: 400 1.4rem 'Montserrat', sans-serif;\r\n line-height: 1.5em;\r\n}\r\n\r\n#showcase-page .showcase-featured h2,\r\n#showcase-page .project-page h2 {\r\n font: italic 900 2rem 'Montserrat', sans-serif;\r\n color: #ed225d;\r\n letter-spacing: 0.05rem;\r\n}\r\n\r\n#showcase-page ul.left-column,\r\n#showcase-page ul.right-column,\r\n#showcase-page ul.project-tags,\r\n#showcase-page ul.links {\r\n list-style: none;\r\n}\r\n\r\n#showcase-page img[alt] {\r\n font-size: 0.9rem;\r\n}\r\n\r\n#showcase-page .showcase-featured {\r\n margin-top: 15%;\r\n}\r\n\r\n#showcase-page .showcase-featured h3.title {\r\n font: italic 900 1rem 'Montserrat', sans-serif;\r\n}\r\n\r\n#showcase-page .showcase-featured p.credit {\r\n font: 500 1rem 'Montserrat', sans-serif;\r\n}\r\n\r\n#showcase-page .showcase-featured p.description {\r\n font-size: 1em;\r\n margin-bottom: 0.5rem;\r\n}\r\n\r\n#showcase-page .nominate {\r\n margin-top: 1.5em;\r\n display: inline-block;\r\n}\r\n\r\n#showcase-page .nominate a,\r\n#showcase-page .nominate a:visited {\r\n padding: 0.4em 0.5em;\r\n position: relative;\r\n top: 0px;\r\n left: 0px;\r\n border: solid #ed225d 2px;\r\n box-shadow: 4px 4px 0 #ed225d;\r\n\r\n font: 1.5rem 'Montserrat', sans-serif;\r\n color: #ed225d;\r\n letter-spacing: 0.02rem;\r\n transition: all 0.3s;\r\n}\r\n\r\n@media (max-width: 500px) {\r\n #showcase-page .nominate a,\r\n #showcase-page .nominate a:visited {\r\n padding: 0.4em 0.3em;\r\n font: 1.3rem 'Montserrat', sans-serif;\r\n }\r\n}\r\n\r\n#showcase-page .nominate a:hover {\r\n top: 4px;\r\n left: 4px;\r\n box-shadow: none;\r\n}\r\n\r\n#showcase-page .showcase-featured a,\r\n#showcase-page .showcase-featured a:visited {\r\n font-size: 1.2rem;\r\n color: #ed225d;\r\n letter-spacing: 0.02rem;\r\n line-height: 1.5;\r\n}\r\n\r\n#showcase-page .showcase-featured a::after {\r\n content: ' →';\r\n}\r\n#showcase-page .showcase-featured a.tag::after {\r\n content: '';\r\n}\r\n#showcase-page .showcase-featured .no-arrow-link::after {\r\n content: ' ';\r\n}\r\n\r\n#showcase-page .showcase-featured .no-arrow-link:hover {\r\n text-decoration: none;\r\n padding: none;\r\n border: none;\r\n}\r\n\r\n.project-info {\r\n margin-top: 1em;\r\n}\r\n\r\nul.project-tags a {\r\n line-height: 0;\r\n display: -webkit-box;\r\n display: -webkit-flex;\r\n display: flex;\r\n -webkit-flex-wrap: wrap;\r\n flex-wrap: wrap;\r\n font-size: 0.5em;\r\n margin: 0px;\r\n}\r\nh3.title {\r\n margin-top: 3em;\r\n}\r\n#showcase-page ul.project-tags li {\r\n margin: 5px;\r\n display: inline-block;\r\n}\r\nh2.featuring {\r\n margin-top: 0px;\r\n}\r\n#showcase-page a.tag {\r\n display: inline-block;\r\n padding: 6px 14px;\r\n background-color: #ffe8e8;\r\n border-radius: 27px;\r\n font: 0.7rem 'Montserrat', sans-serif;\r\n color: #333;\r\n}\r\n#showcase-page ul.project-tags li {\r\n margin: 0px;\r\n}\r\n/*\r\n //////////////////////////////////////////////////\r\n SHOWCASE - FEATURED PROJECT PAGE\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n/* Link style for mobile and tablet screens (no :hover state) */\r\n/*\r\n@media (max-width: 991.98px){\r\n #showcase-page .project-page a, #showcase-page .project-page a:visited {\r\n color:#ED225D;\r\n text-decoration: none;\r\n padding-bottom: 0.11em;\r\n border-bottom: 0.11em dashed;\r\n border-bottom-color: #ED225D;\r\n transition: border-bottom 30ms linear;\r\n }\r\n}\r\n*/\r\n\r\n#showcase-page{\r\n margin-top: 3em;\r\n}\r\n\r\n#showcase-page .project-page h2 {\r\n line-height: 1.4;\r\n}\r\n\r\n@media (min-width: 720px) {\r\n /* for desktop/tablet:\r\n * - two columns, one each for resources & authors\r\n * - indent answer paragraphs in q & a\r\n */\r\n\r\n #showcase-page .showcase-intro h1 {\r\n font: italic 900 6.35vw 'Montserrat', sans-serif;\r\n }\r\n\r\n #showcase-page .showcase-intro p {\r\n line-height: 1.75em;\r\n font-size: 1em;\r\n }\r\n\r\n #showcase-page .project-metadata {\r\n display: flex;\r\n }\r\n\r\n #showcase-page .project-resources {\r\n margin-left: 3rem;\r\n }\r\n\r\n #showcase-page .project-a {\r\n width: 90%;\r\n float: right;\r\n display: inline-block;\r\n clear: both;\r\n }\r\n\r\n #showcase-page .half-image {\r\n width: 48%;\r\n }\r\n}\r\n\r\n#showcase-page .project-metadata {\r\n margin-top: 3%;\r\n}\r\n\r\n#showcase-page .project-metadata section h3 {\r\n color: #ed225d;\r\n font: bold italic 1rem 'Montserrat', sans-serif;\r\n}\r\n\r\n#showcase-page .project-resources ul.links {\r\n font: 500 0.7rem 'Montserrat', sans-serif;\r\n letter-spacing: 0.01rem;\r\n line-height: 1.5;\r\n margin: 0.5rem 0;\r\n}\r\n\r\n#showcase-page .project-credit {\r\n font: italic bold 1.25rem 'Montserrat', sans-serif;\r\n}\r\n\r\n#showcase-page .project-credit p {\r\n margin: 0.5rem 0;\r\n}\r\n\r\n#showcase-page .note {\r\n font-size: 0.7rem;\r\n}\r\n\r\n#showcase-page .creator-from {\r\n font-size: 0.7rem;\r\n}\r\n\r\n#showcase-page .qa-group{\r\n margin-bottom: 2em;\r\n}\r\n\r\n#showcase-page .project-q {\r\n margin-left: 0%;\r\n display: inline-block;\r\n clear: both;\r\n /*\r\n font-size: 1.2rem;\r\n font-weight: 900;\r\n */\r\n font: 900 1.2rem 'Montserrat', sans-serif;\r\n line-height: 1.5;\r\n}\r\n\r\n#showcase-page code {\r\n font-size: 1.1rem;\r\n}\r\n\r\n\r\n/* ==========================================================================\r\n Teach Page\r\n ========================================================================== */\r\n\r\n#teach-page .case-list a:hover {\r\n border-bottom: none;\r\n}\r\n\r\n#teach-page .heading {\r\n font: 400 1.4rem \"Montserrat\", sans-serif;\r\n color: black;\r\n line-height: 1.2em;\r\n padding-bottom: .4em;\r\n border-bottom: 4px dotted #ed225d;\r\n}\r\n\r\n#teach-page h3.title{\r\n margin-top: 3em;\r\n}\r\n\r\n/*search-filter label*/\r\n\r\n#teach-page .search-filter {\r\n display: inline;\r\n}\r\n\r\n#teach-page .search-filter label {\r\n display: inline-block;\r\n font: italic 900 1rem \"Montserrat\", sans-serif;\r\n padding: 6px 12px;\r\n text-align: left;\r\n white-space: nowrap;\r\n color: #ed225d;\r\n /*transition: .2s; */\r\n margin-bottom: .6em;\r\n margin-top: 1.2em;\r\n border: 1px solid #ed225d;\r\n\r\n\r\n}\r\n\r\n#teach-page .search-filter label {\r\n cursor: pointer;\r\n}\r\n\r\n\r\n#teach-page .search-filter label:hover {\r\n color: white;\r\n background-color: #ed225d;\r\n}\r\n\r\n\r\n#teach-page .search-filter input[type=\"checkbox\"] {\r\n display: absolute;\r\n}\r\n\r\n\r\n#teach-page .search-filter input[type=\"checkbox\"] {\r\n position: absolute;\r\n opacity: 0;\r\n}\r\n\r\n\r\n#teach-page ul.filters p.filter-title {\r\n font: 400 0.83rem \"Montserrat\", sans-serif;\r\n color: #ed225d;\r\n height: 50px;\r\n padding-top:20px;\r\n background: none;\r\n background-color: none;\r\n box-shadow: none;\r\n display: inline-block;\r\n border: none;\r\n clear: both;\r\n\r\n}\r\n\r\n\r\n\r\n\r\n#teach-page ul.filters li {\r\n display: inline;\r\n list-style: none;\r\n width: 100%;\r\n}\r\n\r\n#teach-page ul.filters li label {\r\n display: inline-block;\r\n border-radius: 25px;\r\n font: 200 0.7rem \"Montserrat\", sans-serif;\r\n /*font-style: normal;\r\n font-variant: normal;\r\n text-rendering: auto;\r\n -webkit-font-smoothing: antialiased;*/\r\n\r\n color: black;\r\n white-space: nowrap;\r\n margin: 3px 0px;\r\n transition: .2s;\r\n background: #fafafa;\r\n}\r\n\r\n#teach-page ul.filters li label {\r\n padding: 6px 12px;\r\n cursor: pointer;\r\n}\r\n\r\n#teach-page ul.filters li label::before {\r\n display: inline-block;\r\n padding: 2px 2px 2px 2px; /*padding among labels*/\r\n}\r\n\r\n#teach-page ul.filters li label:hover {\r\n color: #ed225d;\r\n background: #ffe8e8;\r\n /*transform: translateY(2px);*/\r\n\r\n }\r\n\r\n#teach-page ul.filters li input[type=\"checkbox\"]:checked + label {\r\n color: white;\r\n background: #ed225d;\r\n\r\n}\r\n\r\n#teach-page ul.filters li input[type=\"checkbox\"] {\r\n display: absolute;\r\n position: absolute;\r\n opacity: 0;\r\n}\r\n\r\n\r\n#teach-page ul.filters li.clear{\r\n display: block;\r\n clear: both;\r\n\r\n}\r\n\r\n\r\n/*Filter Panel*/\r\n\r\n#teach-page .filter-panel {\r\n padding: 0px;\r\n background-color: white;\r\n max-height: 0;\r\n overflow: hidden;\r\n transition: max-height 0.2s ease-out;\r\n margin-bottom: 0.8em;\r\n padding-bottom: .4em;\r\n\r\n}\r\n\r\n\r\n\r\n#teach-page .filter-panel p {\r\n margin: 0;\r\n color: #333;\r\n font-size: .83em;\r\n height: 50px;\r\n padding-top:20px;\r\n transition: all 0.5s ease-in-out;\r\n}\r\n\r\n\r\n /*p5 workshop and class title*/\r\n#teach-page .teach-intro p {\r\n font: 400 1.2rem \"Times\", sans-serif;\r\n line-height: 1.5em;\r\n}\r\n\r\n\r\n/*modal box*/\r\n\r\n#teach-page .modal-title{\r\n\r\n margin-left: 1em;\r\n margin-right: 1em;\r\n\r\n font: 400 1rem \"Montserrat\", sans-serif;\r\n color: #ed225d;\r\n line-height: 1.2em;\r\n\r\n}\r\n\r\n#teach-page ul.cases li.clear{\r\n display: block;\r\n clear: both;\r\n margin-top: 1em;\r\n margin-bottom: 1.2em;\r\n}\r\n\r\n\r\n#teach-page img{\r\n margin-bottom: 1.4em;\r\n}\r\n\r\n#teach-page img[alt]{\r\n font: 0.6rem \"Montserrat\", sans-serif;\r\n color: #bababa;\r\n\r\n}\r\n\r\n#teach-page .close {\r\n position: relative;\r\n color: #ffc7c7;\r\n float: right;\r\n font-size: 40px;\r\n font-weight: bold;\r\n margin-right: .4em;\r\n margin-top: .4em;\r\n cursor:pointer;\r\n}\r\n\r\n#teach-page .close:hover, .close:focus {\r\n color: #ed225d;\r\n text-decoration: none;\r\n cursor: pointer;\r\n}\r\n\r\n#teach-page .case label{\r\n margin-left: 1em;\r\n margin-right: 1em;\r\n margin: 2px 2px;\r\n padding: 5px 8px;\r\n display: inline-block;\r\n border-radius: 25px;\r\n font: 0.7rem \"Montserrat\", sans-serif;\r\n color: #aaaaaa;\r\n white-space: nowrap;\r\n color: white;\r\n background: #ed225d;\r\n}\r\n\r\n/*modal scrollbar*/\r\n\r\n#teach-page .modal-body::-webkit-scrollbar {\r\n\r\n width: 5px;\r\n height: 5px;\r\n border-radius: 10px;\r\n}\r\n\r\n#teach-page .modal-body::-webkit-scrollbar-track {\r\n background: #f1f1f1;\r\n}\r\n\r\n#teach-page .modal-body::-webkit-scrollbar-thumb {\r\n background: #ffe8e8;\r\n}\r\n\r\n/*modal contents*/\r\n\r\n#teach-page .case{\r\n margin-left: 2em;\r\n margin-right:2em;\r\n}\r\n\r\n#teach-page .case span {\r\n color: #ed225d;\r\n font: 900 1.4rem \"Montserrat\", sans-serif;\r\n}\r\n\r\n\r\n#teach-page .case p.lead-name{\r\n font: 900 Italic 1.2rem \"Montserrat\", sans-serif;\r\n color: #ed225d;\r\n line-height: 1.4em;\r\n border-bottom: 1.4em;\r\n}\r\n\r\n#teach-page .case .speech{\r\n\r\n position: relative;\r\n font: 200 Italic .8rem \"Montserrat\", sans-serif;\r\n color: black; /*#aaaaaa; */\r\n background: #ffe8e8;\r\n padding: 0.5em 1.2em;\r\n border-radius: .4em;\r\n border-bottom: none;\r\n margin-bottom: 2em;\r\n margin-top: 1em;\r\n\r\n\r\n}\r\n\r\n#teach-page .case .speech::after {\r\n content: '';\r\n position: absolute;\r\n top: 0;\r\n left: 8%;\r\n width: 0;\r\n height: 0;\r\n border: 10px solid transparent;\r\n border-bottom-color: #ffe8e8;\r\n border-top: 0;\r\n margin-left: -10px;\r\n margin-top: -10px;\r\n}\r\n\r\n#teach-page .case p.subtitle{\r\n\r\n font: 400 1rem \"Montserrat\", sans-serif;\r\n color: #ed225d;\r\n line-height: 1.4em;\r\n border-bottom: 0.1em dashed rgba(237, 34, 93, 0.15);\r\n}\r\n\r\n#teach-page .case p{\r\n font: 400 1rem \"Times\", sans-serif;\r\n color: black;\r\n line-height: 1.4em;\r\n\r\n border-bottom: 0.1em dashed rgba(237, 34, 93, 0.15);\r\n\r\n}\r\n\r\n#teach-page .modal-header{\r\n\r\n margin-bottom: 0.8em;\r\n}\r\n\r\n\r\n#teach-page .modal-footer{\r\n\r\n margin-bottom: 0.8em;\r\n}\r\n\r\n/*#teach-page .modal-body p{\r\n border-bottom: 0.1em dashed rgba(237, 34, 93, 0.15);\r\n\r\n}*/\r\n\r\n#teach-page .modal-body:-webkit-scrollbar{\r\n display: none;\r\n}\r\n\r\n\r\n#teach-page .modal {\r\n display: none; /* Hidden by default */\r\n position: fixed; /* Stay in place */\r\n z-index: 100;\r\n width: 100%;\r\n height: 100%;\r\n top:0;\r\n left:0;\r\n right:0;\r\n overflow: auto;\r\n box-sizing: border-box;\r\n background-color: rgba(255, 232, 232, 0.5); /* Fallback color */\r\n\r\n}\r\n\r\n#teach-page .modal-content{\r\n position: fixed;\r\n background: white;\r\n top: 2%;\r\n left: 2%;\r\n right: 2%;\r\n bottom: 2%;\r\n margin: auto; /*keep centered*/\r\n border: 1.2px solid #ffe8e8;\r\n max-width: 740px;\r\n box-shadow: 10px 100px 30px -17px rgba(237, 34, 93, 0.5);\r\n box-shadow: 10px 100px 20px -17px rgba(237, 34, 93, 0.5);\r\n box-shadow: 10px 20px 10px -17px rgba(237, 34, 93, 0.5);\r\n}\r\n\r\n#teach-page .modal-body{\r\n\r\n margin: auto;\r\n height: 85%;\r\n width: 95%;\r\n overflow-y: auto;\r\n\r\n}\r\n\r\n#teach-page .results-wrapper{\r\n width: 100%;\r\n outline: none;\r\n background: white;\r\n /*background: white;\r\n background: #fafafa;*/\r\n /*border: solid white 1px;*/\r\n /*background: -webkit-linear-gradient(to bottom, white, #fafafa);\r\n background: linear-gradient(to bottom, white, #fafafa);*/\r\n /*border: 1px solid #ffe8e8;*/\r\n /*box-shadow: 10px 100px 30px -17px rgba(237, 34, 93, 0.5);\r\n box-shadow: 10px 100px 20px -17px rgba(255, 232, 232, 0.5);\r\n box-shadow: 10px 20px 10px -17px rgba(237, 34, 93, 0.5);*/\r\n\r\n\r\n}\r\n\r\n#teach-page .results-wrapper ul li.case-list a.myBtn {\r\n\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n\r\n}\r\n\r\n#teach-page .case-list{\r\n\r\n margin-bottom: 0.8em;\r\n padding-bottom: .4em;\r\n\r\n font: 400 1.0rem \"Times\", sans-serif;\r\n line-height: 1.2em;\r\n\r\n border-bottom: 0.1em dashed #ffe8e8;\r\n\r\n}\r\n\r\n/* ==========================================================================\r\n Author's custom styles\r\n ========================================================================== */\r\n\r\n/* apply a natural box layout model to all elements */\r\n\r\n*,\r\n*:before,\r\n*:after {\r\n -moz-box-sizing: border-box;\r\n -webkit-box-sizing: border-box;\r\n box-sizing: border-box;\r\n}\r\n\r\nhtml {\r\n font-size: 1.25em;\r\n}\r\n\r\nbody {\r\n margin: 0;\r\n background-color: #fff;\r\n font-family: 'Times';\r\n font-weight: 400;\r\n line-height: 1.45;\r\n color: #333;\r\n}\r\n\r\np {\r\n font-size: 1.2em;\r\n margin: 0.5em 0;\r\n}\r\n\r\n.freeze {\r\n overflow: hidden;\r\n}\r\n\r\n/* menu links */\r\n\r\n#menu li a:link,\r\n#menu li a:visited,\r\n#menu li a:focus:active,\r\n#menu li a:focus:hover {\r\n color: #ed225d;\r\n /* gray #333;\r\n og p5 pink #ED225D;\r\n blue #2D7BB6 (a lighter Processing blue — it's our take on it) */\r\n /*outline: none !important; keep on for accessibility */\r\n background: transparent;\r\n -webkit-touch-callout: none;\r\n -webkit-user-select: none;\r\n -khtml-user-select: none;\r\n -moz-user-select: none;\r\n -ms-user-select: none;\r\n user-select: none;\r\n}\r\n\r\n/* body links */\r\n\r\na:link,\r\na:visited {\r\n color: #2d7bb6;\r\n text-decoration: none;\r\n /*outline: none !important; keep on for accessibility */\r\n}\r\n\r\na:active,\r\na:hover,\r\n#reference a:hover {\r\n color: #ed225d;\r\n text-decoration: none;\r\n padding-bottom: 0.11em;\r\n border-bottom: 0.11em dashed;\r\n border-bottom-color: #ed225d;\r\n transition: border-bottom 30ms linear;\r\n}\r\n\r\na.nounderline:hover {\r\n border: none;\r\n}\r\n\r\na.here {\r\n color: #ed225d;\r\n text-decoration: none;\r\n padding-bottom: 0.1em;\r\n border-bottom: transparent;\r\n border-bottom-color: #ed225d;\r\n}\r\n\r\n.highlight {\r\n background-color: rgba(237, 34, 93, 0.15);\r\n}\r\n\r\n.container > div:first-of-type {\r\n margin-top: 2em;\r\n}\r\n\r\nh1,\r\nh2,\r\nh3,\r\nh4,\r\nh5 {\r\n margin: 1.414em 0 0.5em 0;\r\n font-weight: inherit;\r\n line-height: 1.2;\r\n font-family: 'Montserrat', sans-serif;\r\n}\r\n\r\nh1 {\r\n font-size: 2.25em;\r\n /* 2.369em */\r\n margin: 0;\r\n}\r\n\r\nh2 {\r\n font-size: 1.5em;\r\n /* 1.777em */\r\n margin: 1em 0 0 0;\r\n}\r\n\r\n.code {\r\n font-family: 'Inconsolata', consolas, monospace;\r\n}\r\n\r\n#backlink {\r\n margin: 1.2em 0.444em 0 0;\r\n font-family: 'Montserrat', sans-serif;\r\n float: right;\r\n}\r\n\r\n#backlink a {\r\n color: #afafaf;\r\n}\r\n\r\n#backlink a:hover {\r\n color: #ed225d;\r\n border-bottom: none;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n HEADER\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n#promo,\r\n#promo:visited {\r\n width: 100%;\r\n background: palegreen;\r\n padding: 0;\r\n margin: 0;\r\n text-align: center;\r\n padding: 0.4em 0;\r\n background: rgb(116, 255, 183);\r\n background: radial-gradient(\r\n circle,\r\n rgba(116, 255, 183, 1) 0%,\r\n rgba(138, 255, 242, 1) 100%\r\n );\r\n font-family: 'Montserrat', sans-serif;\r\n color: #ed225d !important;\r\n}\r\n\r\n#promo:hover {\r\n background: #ed225d;\r\n color: white !important;\r\n}\r\n\r\n#promo-link {\r\n margin: 0 !important;\r\n padding: 0;\r\n}\r\n\r\n#family a:link,\r\n#family a:visited {\r\n margin: 0.4em;\r\n}\r\n\r\n#family a:hover,\r\n#family a:active {\r\n margin: 0.4em;\r\n border: none;\r\n}\r\n\r\n#family {\r\n position: absolute;\r\n z-index: 9999;\r\n top: 0;\r\n left: 0;\r\n /*padding: 0.5em 2em;*/\r\n width: 100%;\r\n /* 96, 100% if fixed*/\r\n border-bottom: 1px solid;\r\n overflow: none;\r\n margin: 0;\r\n border-bottom-color: rgba(51, 51, 51, 0.5);\r\n -webkit-box-shadow: 0px 0px 10px #333;\r\n -moz-box-shadow: 0px 0px 10px #333;\r\n box-shadow: 0px 0px 10px #333;\r\n background-color: rgba(255, 255, 255, 0.85);\r\n /* */\r\n}\r\n\r\n#processing-sites {\r\n margin: 0.375em 0;\r\n}\r\n\r\n#processing-sites li {\r\n list-style: none;\r\n display: inline-block;\r\n margin: 0;\r\n}\r\n\r\n#processing-sites li:first-child {\r\n margin-left: 2em;\r\n}\r\n\r\n#processing-sites li:last-child {\r\n float: right;\r\n margin-right: 2em;\r\n}\r\n\r\n.code-snippet {\r\n margin: 0 0 0 1em;\r\n width: 90%;\r\n clear: both;\r\n}\r\n\r\n.column-span {\r\n margin: 0 0 0 1em;\r\n padding: 0;\r\n float: left;\r\n max-width: 100%;\r\n}\r\n\r\n.method_description p {\r\n margin-top: 0;\r\n}\r\n\r\nmain {\r\n padding: 0;\r\n}\r\n\r\n.spacer {\r\n clear: both;\r\n}\r\n\r\nul {\r\n margin: 0;\r\n padding: 0;\r\n list-style: none;\r\n}\r\n\r\nol {\r\n font-size: 1.2em;\r\n}\r\n\r\nli {\r\n margin: 0;\r\n padding: 0;\r\n}\r\n\r\nul.list_view {\r\n margin: 0.5em 0 0 1em;\r\n padding: 0;\r\n list-style: disc;\r\n list-style-position: outside;\r\n font-size: 1.2em;\r\n}\r\n\r\nol ul.list_view {\r\n font-size: 1em;\r\n}\r\n\r\nul.inside {\r\n margin: 0 0 0 2em;\r\n padding: 0;\r\n list-style: disc;\r\n list-style-position: inside;\r\n}\r\n\r\n.image-row img {\r\n width: 48%;\r\n height: 14.3%;\r\n}\r\n\r\n.image-row img + img {\r\n float: right;\r\n margin-right: 0;\r\n margin-bottom: 0.25em;\r\n}\r\n\r\nimg,\r\nmain div img {\r\n margin: 0.5em 0.5em 0 0;\r\n width: 100%;\r\n}\r\n\r\np + img {\r\n margin-top: 0;\r\n}\r\n\r\n.video {\r\n width: 100%;\r\n}\r\n\r\n#lockup {\r\n position: absolute;\r\n top: -5.75em;\r\n left: 1.25em;\r\n height: 0px;\r\n -webkit-touch-callout: none;\r\n -webkit-user-select: none;\r\n -khtml-user-select: none;\r\n -moz-user-select: none;\r\n -ms-user-select: none;\r\n user-select: none;\r\n}\r\n\r\n#lockup object {\r\n margin: 0;\r\n padding: 0;\r\n border: none;\r\n}\r\n\r\n#lockup a:focus {\r\n outline: 0;\r\n}\r\n\r\n.logo {\r\n margin: 0;\r\n padding: 0;\r\n border: none;\r\n margin-bottom: 0.4em;\r\n height: 4.5em;\r\n width: 9.75em;\r\n}\r\n\r\n#lockup p {\r\n color: #ed225d;\r\n font-size: 0.7em;\r\n font-family: 'Montserrat', sans-serif;\r\n margin: 0.5em 0 0 8.5em;\r\n}\r\n\r\n#lockup a:link {\r\n border: transparent;\r\n height: 4.5em;\r\n width: 9.75em;\r\n}\r\n\r\n.caption {\r\n margin-bottom: 2.5em;\r\n}\r\n\r\n.caption span,\r\n.caption p {\r\n text-align: right;\r\n font-size: 0.7em;\r\n font-family: 'Montserrat', sans-serif;\r\n padding-top: 0.25em;\r\n}\r\n\r\nfooter {\r\n clear: both;\r\n border-top: 0.1em dashed;\r\n border-top-color: #ed225d;\r\n margin: 2em 0;\r\n}\r\n\r\n.videoWrapper {\r\n position: relative;\r\n padding-bottom: 56.25%; /* 16:9 */\r\n height: 0;\r\n margin-top: 0.5em;\r\n}\r\n.videoWrapper iframe {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n}\r\n\r\n/* ==========================================================================\r\n Helper classes\r\n ========================================================================== */\r\n\r\n/*\r\n * Image replacement\r\n */\r\n\r\n.ir {\r\n background-color: transparent;\r\n border: 0;\r\n overflow: hidden;\r\n /* IE 6/7 fallback */\r\n *text-indent: -9999px;\r\n}\r\n\r\n.ir:before {\r\n content: '';\r\n display: block;\r\n width: 0;\r\n height: 150%;\r\n}\r\n\r\n/*\r\n * Hide from both screenreaders and browsers: h5bp.com/u\r\n */\r\n\r\n.hidden {\r\n display: none !important;\r\n visibility: hidden;\r\n}\r\n\r\n/*\r\n * Hide only visually, but have it available for screenreaders: h5bp.com/v\r\n */\r\n\r\n.sr-only {\r\n border: 0;\r\n clip: rect(0 0 0 0);\r\n height: 1px;\r\n margin: -1px;\r\n overflow: hidden;\r\n padding: 0;\r\n position: absolute;\r\n width: 1px;\r\n}\r\n\r\n/*\r\n * Extends the .visuallyhidden class to allow the element to be focusable\r\n * when navigated to via the keyboard: h5bp.com/p\r\n */\r\n\r\n.sr-only.focusable:active,\r\n.sr-only.focusable:focus {\r\n clip: auto;\r\n height: auto;\r\n margin: 0;\r\n overflow: visible;\r\n position: static;\r\n width: auto;\r\n}\r\n\r\n/*\r\n * Hide visually and from screenreaders, but maintain layout\r\n */\r\n\r\n.invisible {\r\n visibility: hidden;\r\n}\r\n\r\n/*\r\n * Clearfix: contain floats\r\n *\r\n * For modern browsers\r\n * 1. The space content is one way to avoid an Opera bug when the\r\n * `contenteditable` attribute is included anywhere else in the document.\r\n * Otherwise it causes space to appear at the top and bottom of elements\r\n * that receive the `clearfix` class.\r\n * 2. The use of `table` rather than `block` is only necessary if using\r\n * `:before` to contain the top-margins of child elements.\r\n */\r\n\r\n.clearfix:before,\r\n.clearfix:after {\r\n content: ' ';\r\n /* 1 */\r\n display: table;\r\n /* 2 */\r\n}\r\n\r\n.clearfix:after {\r\n clear: both;\r\n}\r\n\r\n/*\r\n * For IE 6/7 only\r\n * Include this rule to trigger hasLayout and contain floats.\r\n */\r\n\r\n.clearfix {\r\n *zoom: 1;\r\n}\r\n\r\n/* ==========================================================================\r\n Responsive design\r\n ========================================================================== */\r\n\r\n#notMobile-message {\r\n display: none;\r\n order: 1;\r\n}\r\n\r\n#isMobile-displayButton {\r\n display: none;\r\n}\r\n\r\n#asterisk-design-element,\r\n.separator-design-element {\r\n display: none;\r\n}\r\n\r\n.pointerevents #asterisk-design-element,\r\n.pointerevents .separator-design-element {\r\n pointer-events: none;\r\n display: inline-block;\r\n}\r\n\r\n@media (min-width: 780px) {\r\n .container {\r\n width: 49em !important;\r\n margin: 11.5em auto; /* temp promo, 10.0em */\r\n }\r\n main {\r\n width: 36em;\r\n padding: 0 !important;\r\n }\r\n footer {\r\n width: 48em;\r\n }\r\n}\r\n\r\n@media (min-width: 780px) {\r\n .container {\r\n margin: 11.5em auto; /* temp promo, 10.0em */\r\n width: 100%;\r\n padding: 0.8em 0 0 0;\r\n height: auto;\r\n min-height: 100%;\r\n }\r\n #home-page {\r\n display: flex;\r\n flex-wrap: row;\r\n }\r\n main {\r\n padding: 0 1em 0 0;\r\n }\r\n small,\r\n .small,\r\n footer,\r\n #family {\r\n font-size: 0.7em;\r\n }\r\n footer {\r\n clear: both;\r\n /*margin: 4em 0 2em -.75em;*/\r\n }\r\n #i18n-btn {\r\n position: absolute;\r\n top: 4.0em; /* temp promo, 2.5em */\r\n right: 1em;\r\n }\r\n #i18n-btn a {\r\n font-family: 'Montserrat', sans-serif;\r\n }\r\n #menu {\r\n list-style: none;\r\n font-family: 'Montserrat', sans-serif;\r\n margin: 0 0.75em 0 -1.85em;\r\n /* margin-right: 0.75em; */\r\n width: 7.3em;\r\n height: 100%;\r\n /*float:left;*/\r\n border-top: transparent;\r\n border-bottom: transparent;\r\n padding: 0;\r\n font-size: 0.83em;\r\n z-index: 100;\r\n position: relative;\r\n top: 0;\r\n }\r\n #menu li {\r\n float: none;\r\n margin: 0 0 1em 0;\r\n text-align: right;\r\n }\r\n /* #menu li:last-child {\r\n margin: 0;\r\n } */\r\n /* #menu .other-link::after {\r\n content:\"\\2192\";\r\n margin-right: -0.98em;\r\n content:\" »\";\r\n } */\r\n #menu li:nth-child(11) {\r\n margin-top: 3em;\r\n padding-top: 0.5em;\r\n /*border-top: 0.06em solid rgba(51,51,51,0.25);*/\r\n }\r\n .left-column {\r\n width: 48%;\r\n float: left;\r\n margin-bottom: 40px;\r\n }\r\n .right-column {\r\n width: 48%;\r\n float: right;\r\n margin-right: 0;\r\n margin-bottom: 0.25em;\r\n }\r\n .narrow-left-column {\r\n width: 32%;\r\n float: left;\r\n }\r\n .wide-right-column {\r\n width: 64%;\r\n float: right;\r\n margin-right: 0;\r\n margin-bottom: 0.25em;\r\n }\r\n .book {\r\n font-size: 0.7em;\r\n }\r\n .column_0,\r\n .column_1,\r\n .column_2 {\r\n float: left;\r\n width: 11.333em;\r\n }\r\n .column_0,\r\n .column_1 {\r\n margin-right: 1em;\r\n }\r\n #collection-list-nav {\r\n width: 100%;\r\n clear: both;\r\n border-bottom: 1px dashed rgba(0, 0, 0, 0.2);\r\n }\r\n\r\n #collection-list-categories {\r\n font-family: 'Montserrat', sans-serif;\r\n display: flex;\r\n flex-direction: row;\r\n margin: 1em 0 1.5em 0;\r\n }\r\n #collection-list-categories ul {\r\n flex: 1;\r\n }\r\n #collection-list {\r\n margin: 0;\r\n }\r\n .group-name.first {\r\n margin-top: 0 !important;\r\n }\r\n .column.group-name {\r\n margin-bottom: 1em;\r\n }\r\n\r\n #library-page .group-name {\r\n margin: 2em 0 0.5em 0;\r\n }\r\n #library-page .column {\r\n margin-top: 1em;\r\n }\r\n #list {\r\n display: flex;\r\n flex-direction: row;\r\n flex-wrap: wrap;\r\n margin-bottom: 1em;\r\n }\r\n}\r\n\r\n@media (max-width: 780px) {\r\n .tagline {\r\n display: none !important;\r\n }\r\n\r\n #family {\r\n display: none;\r\n }\r\n\r\n #i18n-btn {\r\n position: absolute;\r\n top: 0.5em;\r\n right: 0.7em;\r\n z-index: 10;\r\n }\r\n\r\n #search {\r\n width: 100%;\r\n float: left;\r\n margin-bottom: 1em;\r\n }\r\n\r\n #search input[type='text'] {\r\n width: 100%;\r\n }\r\n\r\n #search input[type='text'],\r\n #search input[type='search'] {\r\n font-size: 1.5em;\r\n }\r\n\r\n #lockup {\r\n position: absolute;\r\n top: 2em;\r\n left: 1em;\r\n }\r\n .column-span {\r\n margin:0;\r\n padding: 0 1em;\r\n float: left;\r\n }\r\n #menu.top_menu,\r\n #menu {\r\n margin: 6em 0 0.5em 0;\r\n font-size: 1.3em;\r\n }\r\n #menu li {\r\n display: inline-block;\r\n }\r\n\r\n #menu li:nth-last-child(1) a::after {\r\n content: '';\r\n }\r\n\r\n #menu li a::after {\r\n content: ',';\r\n }\r\n\r\n #contribute-item:first-child {\r\n margin-left: 0px;\r\n }\r\n .download_box {\r\n width: 96%;\r\n }\r\n .download_box.half_box {\r\n width: 46%;\r\n margin-right: 4%;\r\n float: left;\r\n }\r\n #etc_list {\r\n font-size: 1.2em;\r\n margin-top: 1em;\r\n }\r\n #asterisk-design-element,\r\n .separator-design-element {\r\n display: none !important;\r\n pointer-events: none;\r\n }\r\n pre[class*='language-'] {\r\n padding: 0.5em 0.5em;\r\n width: 100%;\r\n }\r\n\r\n code {\r\n word-wrap: break-word;\r\n word-break: break-all;\r\n }\r\n #credits {\r\n position: relative !important;\r\n z-index: 2;\r\n margin-top: -7em;\r\n padding: 0 2em 3em 1em;\r\n font-size: 0.5em;\r\n float: right;\r\n width: 100%;\r\n text-align: right;\r\n display: none;\r\n /* HIDDEN SKETCH */\r\n }\r\n #home-sketch-frame {\r\n display: none;\r\n /* HIDDEN SKETCH */\r\n }\r\n #exampleDisplay,\r\n #exampleFrame,\r\n #exampleDisplay #exampleEditor {\r\n width: 100%;\r\n }\r\n #exampleDisplay .edit_button {\r\n left: -0.58em;\r\n }\r\n #exampleDisplay .reset_button {\r\n left: 3em;\r\n }\r\n #exampleDisplay .copy_button {\r\n left: 6.44em;\r\n }\r\n #exampleEditor {\r\n margin-top: 3em;\r\n }\r\n small,\r\n .small,\r\n footer {\r\n font-size: 0.5em;\r\n }\r\n .paramtype {\r\n width: 96%;\r\n }\r\n}\r\n\r\n@media (max-width: 400px) {\r\n #i18n {\r\n margin-top: 0.75em !important;\r\n }\r\n body {\r\n margin-top: -0.75em !important;\r\n }\r\n}\r\n\r\niframe {\r\n border: none;\r\n width: 100%;\r\n}\r\n\r\n.iframe-container {\r\n overflow: hidden;\r\n position: relative;\r\n}\r\n\r\n.iframe-container iframe {\r\n border: 0;\r\n height: 100%;\r\n left: 0;\r\n position: absolute;\r\n top: 0;\r\n width: 100%;\r\n}\r\n\r\n.cnv_div {\r\n /* This ensures that all canvases and additional html elements (if any) from\r\n * the example code snippets are only 100px wide rather than covering the\r\n * entire page, which potentially obscures the example code. */\r\n display: inline-flex;\r\n flex-direction: column;\r\n}\r\n\r\n.cnv_div > * {\r\n width: 100px;\r\n height: auto;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n LANGUAGE BUTTONS\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n#i18n-buttons {\r\n margin: 0;\r\n background: white;\r\n}\r\n\r\n#i18n-buttons li {\r\n list-style: none;\r\n display: inline-block;\r\n margin-left: 0.5em;\r\n}\r\n\r\n#i18n-btn a {\r\n border: none;\r\n outline: none;\r\n font-size: 0.7em;\r\n color: #696969;\r\n z-index: 5;\r\n}\r\n\r\n#i18n-btn a:hover {\r\n color: #ed225d;\r\n}\r\n\r\n#i18n-btn a.disabled {\r\n color: #ed225d;\r\n cursor: default;\r\n}\r\n\r\n/*\r\n //////////////////////////////////////////////////\r\n ASTERISKS\r\n //////////////////////////////////////////////////\r\n*/\r\n\r\n/* constants for the asterisk */\r\n\r\n#asterisk-design-element {\r\n position: fixed;\r\n z-index: -1;\r\n opacity: 0.6;\r\n pointer-events: none;\r\n}\r\n\r\n/* variations for asterisks on pages */\r\n\r\n.separator-design-element {\r\n width: 0.33em;\r\n height: 0.33em;\r\n margin: 0 0.09em 0.18em 0.09em;\r\n display: inline-block;\r\n overflow: hidden;\r\n text-indent: -100%;\r\n background: transparent\r\n url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyOCIgaGVpZ2h0PSIyOCIgdmlld0JveD0iMCAwIDI4IDI4Ij48cGF0aCBkPSJNMTYuOSAxMC4zbDguNS0yLjYgMS43IDUuMiAtOC41IDIuOSA1LjMgNy41IC00LjQgMy4yIC01LjYtNy4zTDguNSAyNi4zbC00LjMtMy4zIDUuMy03LjJMMC45IDEyLjZsMS43LTUuMiA4LjYgMi44VjEuNGg1LjhWMTAuM3oiIHN0eWxlPSJmaWxsOiNFRDIyNUQ7c3Ryb2tlOiNFRDIyNUQiLz48L3N2Zz4=');\r\n background-size: 0.33em;\r\n}\r\n\r\n#home-page #asterisk-design-element {\r\n bottom: -8%;\r\n right: 20%;\r\n height: 12em;\r\n width: 12em;\r\n opacity: 1;\r\n}\r\n\r\n#learn-page #asterisk-design-element,\r\n#examples-page #asterisk-design-element,\r\n#other-content-types-page #asterisk-design-element {\r\n bottom: -14%;\r\n left: -20%;\r\n height: 25em;\r\n width: 25em;\r\n -webkit-transform: rotate(-1deg);\r\n -moz-transform: rotate(-1deg);\r\n -ms-transform: rotate(-1deg);\r\n -o-transform: rotate(-1deg);\r\n transform: rotate(-1deg);\r\n}\r\n\r\n#libraries-page #asterisk-design-element,\r\n#books-page #asterisk-design-element {\r\n bottom: -19%;\r\n right: -16%;\r\n height: 28em;\r\n width: 28em;\r\n -webkit-transform: rotate(2deg);\r\n -moz-transform: rotate(2deg);\r\n -ms-transform: rotate(2deg);\r\n -o-transform: rotate(2deg);\r\n transform: rotate(2deg);\r\n}\r\n\r\n#get-started-page #asterisk-design-element,\r\n#community-page #asterisk-design-element {\r\n top: 10%;\r\n right: -20%;\r\n height: 30em;\r\n width: 30em;\r\n -webkit-transform: rotate(2deg);\r\n -moz-transform: rotate(2deg);\r\n -ms-transform: rotate(2deg);\r\n -o-transform: rotate(2deg);\r\n transform: rotate(2deg);\r\n}\r\n\r\n#reference-page #asterisk-design-element,\r\n#download-page #asterisk-design-element {\r\n top: 7%;\r\n left: 1%;\r\n height: 10em;\r\n width: 10em;\r\n -webkit-transform: rotate(-21deg);\r\n -moz-transform: rotate(-21deg);\r\n -ms-transform: rotate(-21deg);\r\n -o-transform: rotate(-21deg);\r\n transform: rotate(-21deg);\r\n}\r\n\r\n.email-octopus-email-address {\r\n color: #ed225d;\r\n text-decoration: none;\r\n padding-bottom: 0.11em;\r\n outline: none;\r\n border: none;\r\n border-bottom: 0.11em dashed;\r\n border-bottom-color: #ed225d;\r\n transition: border-bottom 30ms linear;\r\n width: 13em;\r\n}\r\n\r\n.email-octopus-form-row-hp {\r\n position: absolute;\r\n left: -5000px;\r\n}\r\n\r\n.email-octopus-form-row button {\r\n border: 1px solid #ed225d;\r\n color: #ed225d;\r\n padding: 0.4em 0.6em;\r\n margin: 1em 0 0 0;\r\n font-family: 'Montserrat', sans-serif;\r\n display: block;\r\n}\r\n\r\n.email-octopus-form-row button:hover {\r\n background-color: #ed225d;\r\n color: white;\r\n}\r\n\r\n.email-octopus-email-address::-webkit-input-placeholder {\r\n color: #ababab;\r\n}\r\n.email-octopus-email-address::-moz-placeholder {\r\n color: #ababab;\r\n}\r\n.email-octopus-email-address:-moz-placeholder {\r\n color: #ababab;\r\n}\r\n.email-octopus-email-address:-ms-input-placeholder {\r\n color: #ababab;\r\n}\r\n\r\n@media (min-width: 720px) {\r\n .email-octopus-email-address {\r\n width: 16em;\r\n }\r\n\r\n .email-octopus-form-row button {\r\n margin: 0;\r\n margin-left: 0.5em;\r\n display: inline;\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/dist/assets/examples/assets/360video_256crop_v2.mp4 b/dist/assets/examples/assets/360video_256crop_v2.mp4 new file mode 100644 index 0000000000..e64ba0d13c Binary files /dev/null and b/dist/assets/examples/assets/360video_256crop_v2.mp4 differ diff --git a/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_01.mp3 b/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_01.mp3 new file mode 100644 index 0000000000..9653a67bb6 Binary files /dev/null and b/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_01.mp3 differ diff --git a/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_01.ogg b/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_01.ogg new file mode 100644 index 0000000000..ddb329fc15 Binary files /dev/null and b/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_01.ogg differ diff --git a/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_02.mp3 b/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_02.mp3 new file mode 100644 index 0000000000..b113049905 Binary files /dev/null and b/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_02.mp3 differ diff --git a/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_02.ogg b/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_02.ogg new file mode 100644 index 0000000000..77d530a2df Binary files /dev/null and b/dist/assets/examples/assets/Damscray_-_Dancing_Tiger_02.ogg differ diff --git a/dist/assets/examples/assets/Damscray_DancingTiger.mp3 b/dist/assets/examples/assets/Damscray_DancingTiger.mp3 new file mode 100644 index 0000000000..b113049905 Binary files /dev/null and b/dist/assets/examples/assets/Damscray_DancingTiger.mp3 differ diff --git a/dist/assets/examples/assets/Damscray_DancingTiger.ogg b/dist/assets/examples/assets/Damscray_DancingTiger.ogg new file mode 100644 index 0000000000..77d530a2df Binary files /dev/null and b/dist/assets/examples/assets/Damscray_DancingTiger.ogg differ diff --git a/dist/assets/examples/assets/LeagueGothic-Regular.otf b/dist/assets/examples/assets/LeagueGothic-Regular.otf new file mode 100644 index 0000000000..6cd753faf8 Binary files /dev/null and b/dist/assets/examples/assets/LeagueGothic-Regular.otf differ diff --git a/dist/assets/examples/assets/SourceSansPro-Regular.otf b/dist/assets/examples/assets/SourceSansPro-Regular.otf new file mode 100644 index 0000000000..38941ae72f Binary files /dev/null and b/dist/assets/examples/assets/SourceSansPro-Regular.otf differ diff --git a/dist/assets/examples/assets/basic.frag b/dist/assets/examples/assets/basic.frag new file mode 100644 index 0000000000..e6bc05d861 --- /dev/null +++ b/dist/assets/examples/assets/basic.frag @@ -0,0 +1,22 @@ +// casey conchinha - @kcconch ( https://github.com/kcconch ) +// louise lessel - @louiselessel ( https://github.com/louiselessel ) +// more p5.js + shader examples: https://itp-xstory.github.io/p5js-shaders/ +// this is a modification of a shader by adam ferriss +// https://github.com/aferriss/p5jsShaderExamples/tree/gh-pages/2_texture-coordinates/2-1_basic + +precision mediump float; + +// this is the same variable we declared in the vertex shader +// we need to declare it here too! +varying vec2 vTexCoord; + +void main() { + + // copy the vTexCoord + // vTexCoord is a value that goes from 0.0 - 1.0 depending on the pixels location + // we can use it to access every pixel on the screen + vec2 coord = vTexCoord; + + // x values for red, y values for green, both for blue + gl_FragColor = vec4(coord.x, coord.y, (coord.x+coord.y), 1.0 ); +} diff --git a/dist/assets/examples/assets/basic.vert b/dist/assets/examples/assets/basic.vert new file mode 100644 index 0000000000..df069583a8 --- /dev/null +++ b/dist/assets/examples/assets/basic.vert @@ -0,0 +1,26 @@ +// vert file and comments from adam ferriss +// https://github.com/aferriss/p5jsShaderExamples + +// our vertex data +attribute vec3 aPosition; + +// our texcoordinates +attribute vec2 aTexCoord; + +// this is a variable that will be shared with the fragment shader +// we will assign the attribute texcoords to the varying texcoords to move them from the vert shader to the frag shader +// it can be called whatever you want but often people prefiv it with 'v' to indicate that it is a varying +varying vec2 vTexCoord; + +void main() { + + // copy the texture coordinates + vTexCoord = aTexCoord; + + // copy the position data into a vec4, using 1.0 as the w component + vec4 positionVec4 = vec4(aPosition, 1.0); + positionVec4.xy = positionVec4.xy * 2.0 - 1.0; + + // send the vertex information on to the fragment shader + gl_Position = positionVec4; +} diff --git a/dist/assets/examples/assets/beat.mp3 b/dist/assets/examples/assets/beat.mp3 new file mode 100644 index 0000000000..3e5802604c Binary files /dev/null and b/dist/assets/examples/assets/beat.mp3 differ diff --git a/dist/assets/examples/assets/beat.ogg b/dist/assets/examples/assets/beat.ogg new file mode 100644 index 0000000000..c13f86a41f Binary files /dev/null and b/dist/assets/examples/assets/beat.ogg differ diff --git a/dist/assets/examples/assets/beatbox.mp3 b/dist/assets/examples/assets/beatbox.mp3 new file mode 100644 index 0000000000..23fb92eb71 Binary files /dev/null and b/dist/assets/examples/assets/beatbox.mp3 differ diff --git a/dist/assets/examples/assets/beatbox.ogg b/dist/assets/examples/assets/beatbox.ogg new file mode 100644 index 0000000000..b2593a6340 Binary files /dev/null and b/dist/assets/examples/assets/beatbox.ogg differ diff --git a/dist/assets/examples/assets/brush.png b/dist/assets/examples/assets/brush.png new file mode 100644 index 0000000000..f3390e3501 Binary files /dev/null and b/dist/assets/examples/assets/brush.png differ diff --git a/dist/assets/examples/assets/bubbles.csv b/dist/assets/examples/assets/bubbles.csv new file mode 100644 index 0000000000..88ac4c1b72 --- /dev/null +++ b/dist/assets/examples/assets/bubbles.csv @@ -0,0 +1,5 @@ +x,y,diameter,name +160,103,43.19838,Happy +372,137,52.42526,Sad +273,235,61.14072,Joyous +121,179,44.758068,Melancholy \ No newline at end of file diff --git a/dist/assets/examples/assets/bubbles.json b/dist/assets/examples/assets/bubbles.json new file mode 100644 index 0000000000..173b118dd4 --- /dev/null +++ b/dist/assets/examples/assets/bubbles.json @@ -0,0 +1,20 @@ +{ + "bubbles": [ + { + "position": { + "x": 160, + "y": 103 + }, + "diameter": 43.19838, + "label": "Happy" + }, + { + "position": { + "x": 372, + "y": 137 + }, + "diameter": 52.42526, + "label": "Sad" + } + ] +} diff --git a/dist/assets/examples/assets/bx-spring.mp3 b/dist/assets/examples/assets/bx-spring.mp3 new file mode 100644 index 0000000000..4a955ab7fa Binary files /dev/null and b/dist/assets/examples/assets/bx-spring.mp3 differ diff --git a/dist/assets/examples/assets/bx-spring.ogg b/dist/assets/examples/assets/bx-spring.ogg new file mode 100644 index 0000000000..b01abee927 Binary files /dev/null and b/dist/assets/examples/assets/bx-spring.ogg differ diff --git a/dist/assets/examples/assets/cat.jpg b/dist/assets/examples/assets/cat.jpg new file mode 100644 index 0000000000..6fd0221988 Binary files /dev/null and b/dist/assets/examples/assets/cat.jpg differ diff --git a/dist/assets/examples/assets/concrete-tunnel.mp3 b/dist/assets/examples/assets/concrete-tunnel.mp3 new file mode 100644 index 0000000000..1bfbd4f8f8 Binary files /dev/null and b/dist/assets/examples/assets/concrete-tunnel.mp3 differ diff --git a/dist/assets/examples/assets/concrete-tunnel.ogg b/dist/assets/examples/assets/concrete-tunnel.ogg new file mode 100644 index 0000000000..be5f66b72c Binary files /dev/null and b/dist/assets/examples/assets/concrete-tunnel.ogg differ diff --git a/dist/assets/examples/assets/doorbell.mp3 b/dist/assets/examples/assets/doorbell.mp3 new file mode 100644 index 0000000000..44b6367916 Binary files /dev/null and b/dist/assets/examples/assets/doorbell.mp3 differ diff --git a/dist/assets/examples/assets/doorbell.ogg b/dist/assets/examples/assets/doorbell.ogg new file mode 100644 index 0000000000..e816288c97 Binary files /dev/null and b/dist/assets/examples/assets/doorbell.ogg differ diff --git a/dist/assets/examples/assets/drum.mp3 b/dist/assets/examples/assets/drum.mp3 new file mode 100644 index 0000000000..9cd8727617 Binary files /dev/null and b/dist/assets/examples/assets/drum.mp3 differ diff --git a/dist/assets/examples/assets/drum.ogg b/dist/assets/examples/assets/drum.ogg new file mode 100644 index 0000000000..5061a1b319 Binary files /dev/null and b/dist/assets/examples/assets/drum.ogg differ diff --git a/dist/assets/examples/assets/fingers.mov b/dist/assets/examples/assets/fingers.mov new file mode 100644 index 0000000000..a9cbbbe3ea Binary files /dev/null and b/dist/assets/examples/assets/fingers.mov differ diff --git a/dist/assets/examples/assets/fingers.webm b/dist/assets/examples/assets/fingers.webm new file mode 100644 index 0000000000..8fb81cfd15 Binary files /dev/null and b/dist/assets/examples/assets/fingers.webm differ diff --git a/dist/assets/examples/assets/large-dark-plate.mp3 b/dist/assets/examples/assets/large-dark-plate.mp3 new file mode 100644 index 0000000000..b9a15cbed7 Binary files /dev/null and b/dist/assets/examples/assets/large-dark-plate.mp3 differ diff --git a/dist/assets/examples/assets/large-dark-plate.ogg b/dist/assets/examples/assets/large-dark-plate.ogg new file mode 100644 index 0000000000..40115377e5 Binary files /dev/null and b/dist/assets/examples/assets/large-dark-plate.ogg differ diff --git a/dist/assets/examples/assets/lucky_dragons_-_power_melody.mp3 b/dist/assets/examples/assets/lucky_dragons_-_power_melody.mp3 new file mode 100644 index 0000000000..c54c70c01a Binary files /dev/null and b/dist/assets/examples/assets/lucky_dragons_-_power_melody.mp3 differ diff --git a/dist/assets/examples/assets/lucky_dragons_-_power_melody.ogg b/dist/assets/examples/assets/lucky_dragons_-_power_melody.ogg new file mode 100644 index 0000000000..1e5b9e7abc Binary files /dev/null and b/dist/assets/examples/assets/lucky_dragons_-_power_melody.ogg differ diff --git a/dist/assets/examples/assets/mask.png b/dist/assets/examples/assets/mask.png new file mode 100644 index 0000000000..a6737489b9 Binary files /dev/null and b/dist/assets/examples/assets/mask.png differ diff --git a/dist/assets/examples/assets/moonwalk.jpg b/dist/assets/examples/assets/moonwalk.jpg new file mode 100644 index 0000000000..36cc6c060e Binary files /dev/null and b/dist/assets/examples/assets/moonwalk.jpg differ diff --git a/dist/assets/examples/assets/parrot-bw.png b/dist/assets/examples/assets/parrot-bw.png new file mode 100644 index 0000000000..cbc6a868d1 Binary files /dev/null and b/dist/assets/examples/assets/parrot-bw.png differ diff --git a/dist/assets/examples/assets/parrot-color.png b/dist/assets/examples/assets/parrot-color.png new file mode 100644 index 0000000000..5addae8d3a Binary files /dev/null and b/dist/assets/examples/assets/parrot-color.png differ diff --git a/dist/assets/examples/assets/particle_texture.png b/dist/assets/examples/assets/particle_texture.png new file mode 100644 index 0000000000..0852c88e1d Binary files /dev/null and b/dist/assets/examples/assets/particle_texture.png differ diff --git a/dist/assets/examples/assets/rover.png b/dist/assets/examples/assets/rover.png new file mode 100644 index 0000000000..a597279130 Binary files /dev/null and b/dist/assets/examples/assets/rover.png differ diff --git a/dist/assets/examples/assets/rover_wide.jpg b/dist/assets/examples/assets/rover_wide.jpg new file mode 100644 index 0000000000..793781a3be Binary files /dev/null and b/dist/assets/examples/assets/rover_wide.jpg differ diff --git a/dist/assets/examples/assets/small-plate.mp3 b/dist/assets/examples/assets/small-plate.mp3 new file mode 100644 index 0000000000..656e154a5f Binary files /dev/null and b/dist/assets/examples/assets/small-plate.mp3 differ diff --git a/dist/assets/examples/assets/small-plate.ogg b/dist/assets/examples/assets/small-plate.ogg new file mode 100644 index 0000000000..7b70d3349d Binary files /dev/null and b/dist/assets/examples/assets/small-plate.ogg differ diff --git a/dist/assets/examples/assets/texture.frag b/dist/assets/examples/assets/texture.frag new file mode 100644 index 0000000000..c74ce3f42f --- /dev/null +++ b/dist/assets/examples/assets/texture.frag @@ -0,0 +1,84 @@ +// casey conchinha - @kcconch ( https://github.com/kcconch ) +// louise lessel - @louiselessel ( https://github.com/louiselessel ) +// more p5.js + shader examples: https://itp-xstory.github.io/p5js-shaders/ +// rotate/tile functions from example by patricio gonzalez vivo +// @patriciogv ( patriciogonzalezvivo.com ) + +#ifdef GL_ES +precision mediump float; +#endif + +#define PI 3.14159265358979323846 + +uniform vec2 resolution; +uniform float time; +uniform vec2 mouse; + +vec2 rotate2D (vec2 _st, float _angle) { + _st -= 0.5; + _st = mat2(cos(_angle),-sin(_angle), + sin(_angle),cos(_angle)) * _st; + _st += 0.5; + return _st; +} + +vec2 tile (vec2 _st, float _zoom) { + _st *= _zoom; + return fract(_st); +} + +vec2 rotateTilePattern(vec2 _st){ + + // Scale the coordinate system by 2x2 + _st *= 2.0; + + // Give each cell an index number + // according to its position + float index = 0.0; + index += step(1., mod(_st.x,2.0)); + index += step(1., mod(_st.y,2.0))*2.0; + + // | + // 2 | 3 + // | + //-------------- + // | + // 0 | 1 + // | + + // Make each cell between 0.0 - 1.0 + _st = fract(_st); + + // Rotate each cell according to the index + if(index == 1.0){ + // Rotate cell 1 by 90 degrees + _st = rotate2D(_st,PI*0.5); + } else if(index == 2.0){ + // Rotate cell 2 by -90 degrees + _st = rotate2D(_st,PI*-0.5); + } else if(index == 3.0){ + // Rotate cell 3 by 180 degrees + _st = rotate2D(_st,PI); + } + + return _st; +} + +float concentricCircles(in vec2 st, in vec2 radius, in float res, in float scale) { + float dist = distance(st,radius); + float pct = floor(dist*res)/scale; + return pct; +} + +void main (void) { + vec2 st = gl_FragCoord.xy/resolution.xy; + vec2 mst = gl_FragCoord.xy/mouse.xy; + float mdist= distance(vec2(1.0,1.0), mst); + + float dist = distance(st,vec2(sin(time/10.0),cos(time/10.0))); + st = tile(st,10.0); + + st = rotate2D(st,dist/(mdist/5.0)*PI*2.0); + + gl_FragColor = vec4(vec3(concentricCircles(st, vec2(0.0,0.0), 5.0, 5.0),concentricCircles(st, vec2(0.0,0.0), 10.0, 10.0),concentricCircles(st, vec2(0.0,0.0), 20.0, 10.0)),1.0); +} diff --git a/dist/assets/examples/assets/texture.vert b/dist/assets/examples/assets/texture.vert new file mode 100644 index 0000000000..5dd95c9b31 --- /dev/null +++ b/dist/assets/examples/assets/texture.vert @@ -0,0 +1,15 @@ +// vert file and comments from adam ferriss +// https://github.com/aferriss/p5jsShaderExamples + +// our vertex data +attribute vec3 aPosition; + +void main() { + + // copy the position data into a vec4, using 1.0 as the w component + vec4 positionVec4 = vec4(aPosition, 1.0); + positionVec4.xy = positionVec4.xy * 2.0 - 1.0; + + // send the vertex information on to the fragment shader + gl_Position = positionVec4; +} diff --git a/dist/assets/examples/assets/uniforms.frag b/dist/assets/examples/assets/uniforms.frag new file mode 100644 index 0000000000..bf2ad1bc5d --- /dev/null +++ b/dist/assets/examples/assets/uniforms.frag @@ -0,0 +1,77 @@ +// casey conchinha - @kcconch ( https://github.com/kcconch ) +// louise lessel - @louiselessel ( https://github.com/louiselessel ) +// more p5.js + shader examples: https://itp-xstory.github.io/p5js-shaders/ +// this is a modification of a shader by adam ferriss +// https://github.com/aferriss/p5jsShaderExamples/tree/gh-pages/5_shapes/5-3_polygon + +precision mediump float; + +// these are known as preprocessor directive +// essentially we are just declaring some variables that wont change +// you can think of them just like const variables + +#define PI 3.14159265359 +#define TWO_PI 6.28318530718 + +// we need the sketch resolution to perform some calculations +uniform vec2 resolution; +uniform float time; +uniform float mouse; + +// this is a function that turns an rgb value that goes from 0 - 255 into 0.0 - 1.0 +vec3 rgb(float r, float g, float b){ + return vec3(r / 255.0, g / 255.0, b / 255.0); +} + +vec4 poly(float x, float y, float size, float sides, float rotation, vec3 col){ + // get our coordinates + vec2 coord = gl_FragCoord.xy; + + // move the coordinates to where we want to draw the shape + vec2 pos = vec2(x,y) - coord; + + // calculate the angle of a pixel relative to our position + float angle = atan( pos.x, pos.y) + PI + rotation; + + // calculate the size of our shape + float radius = TWO_PI / sides; + + // this is the function that controls our shapes appearance + // i pulled it from the book of shaders shapes page https://thebookofshaders.com/07/ + // essentially what we are doing here is computing a circle with length(pos) and manipulating it's shape with the cos() function + // this technique is really powerful and can be used to create all sorts of different shapes + // for instance, try changing cos() to sin() + float d = cos(floor(0.5 + angle / radius) * radius - angle) * length(pos); + + // restrict our shape to black and white and set it's size + // we use the smoothstep function to get a nice soft edge + d = 1.0 - smoothstep(size*0.5, size*0.5+1.0, d); + + // return the color with the shape as the alpha channel + return vec4(col, d); +} + + +void main() { + + vec2 center = resolution * 1.0; // draw the shape at the center of the screen + float size = resolution.y * 0.5; // make the shape a quarter of the screen height + float sides = mod(floor(mouse), 7.0) + 3.0; // slowly increase the sides, when it reaches 10 sides, go back down to 3 + float rotation = time; // rotation is in radians, but for time it doesnt really matter + + // lets make our shape in the center of the screen. We have to subtract half of it's width and height just like in p5 + float x = center.x ; + float y = center.y ; + + // a color for the shape + vec3 grn = rgb(200.0, 240.0, 200.0); + + // call our shape function with poly(x, y, sz, sides, rotation, color); + vec4 poly = poly(center.x , center.y, size, sides, rotation, grn); + + // mix the polygon with the opposite of the green color according to the shapes alpha + poly.rgb = mix(1.0 - grn, poly.rgb, poly.a); + + // render to screen + gl_FragColor = vec4(poly.rgb, 1.0); +} diff --git a/dist/assets/examples/assets/uniforms.vert b/dist/assets/examples/assets/uniforms.vert new file mode 100644 index 0000000000..568a87edd2 --- /dev/null +++ b/dist/assets/examples/assets/uniforms.vert @@ -0,0 +1,19 @@ +// vert file and comments from adam ferriss +// https://github.com/aferriss/p5jsShaderExamples + +attribute vec3 aPosition; +attribute vec2 aTexCoord; + +void main() { + + // copy the position data into a vec4, using 1.0 as the w component + vec4 positionVec4 = vec4(aPosition, 1.0); + + // scale the rect by two, and move it to the center of the screen + // if we don't do this, it will appear with its bottom left corner in the center of the sketch + // try commenting this line out to see what happens + positionVec4.xy = positionVec4.xy * 2.0 - 1.0; + + // send the vertex information on to the fragment shader + gl_Position = positionVec4; +} diff --git a/dist/assets/examples/assets/webcam.frag b/dist/assets/examples/assets/webcam.frag new file mode 100644 index 0000000000..ada0949d9a --- /dev/null +++ b/dist/assets/examples/assets/webcam.frag @@ -0,0 +1,34 @@ +// casey conchinha - @kcconch ( https://github.com/kcconch ) +// louise lessel - @louiselessel ( https://github.com/louiselessel ) +// more p5.js + shader examples: https://itp-xstory.github.io/p5js-shaders/ + +precision mediump float; + +// grab texcoords from vert shader +varying vec2 vTexCoord; + +// our texture coming from p5 +uniform sampler2D tex0; + + +void main() { + vec2 uv = vTexCoord; + + // the texture is loaded upside down and backwards by default so lets flip it + uv.y = 1.0 - uv.y; + + vec4 tex = texture2D(tex0, uv); + + float gray = (tex.r + tex.g + tex.b) / 3.0; + + float res = 20.0; + float scl = res / (10.0); + + float threshR = (fract(floor(tex.r*res)/scl)*scl) * gray ; + float threshG = (fract(floor(tex.g*res)/scl)*scl) * gray ; + float threshB = (fract(floor(tex.b*res)/scl)*scl) * gray ; + vec3 thresh = vec3(threshR, threshG, threshB); + + // render the output + gl_FragColor = vec4(thresh, 1.0); +} diff --git a/dist/assets/examples/assets/webcam.vert b/dist/assets/examples/assets/webcam.vert new file mode 100644 index 0000000000..c04d96c34a --- /dev/null +++ b/dist/assets/examples/assets/webcam.vert @@ -0,0 +1,21 @@ +// vert file and comments from adam ferriss +// https://github.com/aferriss/p5jsShaderExamples + +// our vertex data +attribute vec3 aPosition; +attribute vec2 aTexCoord; + +// lets get texcoords just for fun! +varying vec2 vTexCoord; + +void main() { + // copy the texcoords + vTexCoord = aTexCoord; + + // copy the position data into a vec4, using 1.0 as the w component + vec4 positionVec4 = vec4(aPosition, 1.0); + positionVec4.xy = positionVec4.xy * 2.0 - 1.0; + + // send the vertex information on to the fragment shader + gl_Position = positionVec4; +} diff --git a/dist/assets/examples/en/00_Structure/00_Statements_and_Comments.js b/dist/assets/examples/en/00_Structure/00_Statements_and_Comments.js new file mode 100644 index 0000000000..8b8d81e5b1 --- /dev/null +++ b/dist/assets/examples/en/00_Structure/00_Statements_and_Comments.js @@ -0,0 +1,20 @@ +/* + * @name Comments and Statements + * @arialabel Mustard yellow background + * @description Statements are the elements that make up programs. The ";" (semi-colon) symbol is used to end statements. It is called the "statement terminator". Comments are used for making notes to help people better understand programs. A comment begins with two forward slashes ("//"). (ported from https://processing.org/examples/statementscomments.html) + */ +// The createCanvas function is a statement that tells the computer +// how large to make the window. +// Each function statement has zero or more parameters. +// Parameters are data passed into the function +// and are used as values for telling the computer what to do. +function setup() { + createCanvas(710, 400); +} + +// The background function is a statement that tells the computer +// which color (or gray value) to make the background of the display window +function draw() { + background(204, 153, 0); +} + diff --git a/dist/assets/examples/en/00_Structure/01_Coordinates.js b/dist/assets/examples/en/00_Structure/01_Coordinates.js new file mode 100644 index 0000000000..76e304461d --- /dev/null +++ b/dist/assets/examples/en/00_Structure/01_Coordinates.js @@ -0,0 +1,40 @@ +/* + * @name Coordinates + * @arialabel Black background with a orange outline of a square in the middle and a blue line across at the top ⅓ point of the square + * @description All shapes drawn to the screen have a position that is + * specified as a coordinate. All coordinates are measured as the distance from + * the origin in units of pixels. The origin [0, 0] is the coordinate in the + * upper left of the window and the coordinate in the lower right is [width-1, + * height-1]. + */ +function setup() { + // Sets the screen to be 720 pixels wide and 400 pixels high + createCanvas(720, 400); +} + +function draw() { + // Set the background to black and turn off the fill color + background(0); + noFill(); + + // The two parameters of the point() method each specify + // coordinates. + // The first parameter is the x-coordinate and the second is the Y + stroke(255); + point(width * 0.5, height * 0.5); + point(width * 0.5, height * 0.25); + + // Coordinates are used for drawing all shapes, not just points. + // Parameters for different functions are used for different + // purposes. For example, the first two parameters to line() + // specify the coordinates of the first endpoint and the second + // two parameters specify the second endpoint + stroke(0, 153, 255); + line(0, height * 0.33, width, height * 0.33); + + // By default, the first two parameters to rect() are the + // coordinates of the upper-left corner and the second pair + // is the width and height + stroke(255, 153, 0); + rect(width * 0.25, height * 0.1, width * 0.5, height * 0.8); +} diff --git a/dist/assets/examples/en/00_Structure/02_Width_and_Height.js b/dist/assets/examples/en/00_Structure/02_Width_and_Height.js new file mode 100644 index 0000000000..a80a682a4b --- /dev/null +++ b/dist/assets/examples/en/00_Structure/02_Width_and_Height.js @@ -0,0 +1,21 @@ +/* + * @name Width and Height + * @arialabel Pattern of grey and green horizontal lines. The left half also has white vertical lines. The left half is broken up into two triangular shapes, one which is predominately green stripes, and one which is white with the white stripes + * @description The 'width' and 'height' variables contain the + * width and height of the display window as defined in the createCanvas() + * function. + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(127); + noStroke(); + for (let i = 0; i < height; i += 20) { + fill(129, 206, 15); + rect(0, i, width, 10); + fill(255); + rect(i, 0, 10, height); + } +} diff --git a/dist/assets/examples/en/00_Structure/03_Setup_and_Draw.js b/dist/assets/examples/en/00_Structure/03_Setup_and_Draw.js new file mode 100644 index 0000000000..ec48063635 --- /dev/null +++ b/dist/assets/examples/en/00_Structure/03_Setup_and_Draw.js @@ -0,0 +1,28 @@ +/* + * @name Setup and Draw + * @arialabel Animated horizontal white line on a black background that moves from the bottom to the top of the screen + * @description The code inside the draw() function runs continuously from top + * to bottom until the program is stopped. + */ +let y = 100; + +// The statements in the setup() function +// execute once when the program begins +function setup() { + // createCanvas must be the first statement + createCanvas(720, 400); + stroke(255); // Set line drawing color to white + frameRate(30); +} +// The statements in draw() are executed until the +// program is stopped. Each statement is executed in +// sequence and after the last line is read, the first +// line is executed again. +function draw() { + background(0); // Set the background to black + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/en/00_Structure/04_No_Loop.js b/dist/assets/examples/en/00_Structure/04_No_Loop.js new file mode 100644 index 0000000000..48e0095d7e --- /dev/null +++ b/dist/assets/examples/en/00_Structure/04_No_Loop.js @@ -0,0 +1,31 @@ +/* + * @name No Loop + * @arialabel Horizontal white line across the middle of a black background + * @description The noLoop() function causes draw() to only execute once. + * Without calling noLoop(), the code inside draw() is run continually. + */ +let y; + +// The statements in the setup() function +// execute once when the program begins +function setup() { + // createCanvas should be the first statement + createCanvas(720, 400); + stroke(255); // Set line drawing color to white + noLoop(); + + y = height * 0.5; +} + +// The statements in draw() are executed until the +// program is stopped. Each statement is executed in +// sequence and after the last line is read, the first +// line is executed again. +function draw() { + background(0); // Set the background to black + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/en/00_Structure/05_Loop.js b/dist/assets/examples/en/00_Structure/05_Loop.js new file mode 100644 index 0000000000..a624d8520f --- /dev/null +++ b/dist/assets/examples/en/00_Structure/05_Loop.js @@ -0,0 +1,27 @@ +/* + * @name Loop + * @arialabel Horizontal white line on a black background that moves from the bottom to the top of the screen parallel to the x-axis + * @description The code inside the draw() function runs continuously from top + * to bottom until the program is stopped. + */ +let y = 100; + +// The statements in the setup() function +// execute once when the program begins +function setup() { + createCanvas(720, 400); // Size must be the first statement + stroke(255); // Set line drawing color to white + frameRate(30); +} +// The statements in draw() are executed until the +// program is stopped. Each statement is executed in +// sequence and after the last line is read, the first +// line is executed again. +function draw() { + background(0); // Set the background to black + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/en/00_Structure/06_Redraw.js b/dist/assets/examples/en/00_Structure/06_Redraw.js new file mode 100644 index 0000000000..6a05360b92 --- /dev/null +++ b/dist/assets/examples/en/00_Structure/06_Redraw.js @@ -0,0 +1,34 @@ +/* + * @name Redraw + * @arialabel Horizontal white line across a black background that moves higher on the screen with each mouse click + * @description The redraw() function makes draw() execute once. In this example, + * draw() is executed once every time the mouse is clicked. + */ + +let y; + +// The statements in the setup() function +// execute once when the program begins +function setup() { + createCanvas(720, 400); + stroke(255); + noLoop(); + y = height * 0.5; +} + +// The statements in draw() are executed until the +// program is stopped. Each statement is executed in +// sequence and after the last line is read, the first +// line is executed again. +function draw() { + background(0); + y = y - 4; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} + +function mousePressed() { + redraw(); +} diff --git a/dist/assets/examples/en/00_Structure/07_Functions.js b/dist/assets/examples/en/00_Structure/07_Functions.js new file mode 100644 index 0000000000..648915c01d --- /dev/null +++ b/dist/assets/examples/en/00_Structure/07_Functions.js @@ -0,0 +1,29 @@ +/* + *@name Functions + *@arialabel Three targets are created in the shape of black circles. There is a gradient from white to black from the center of the circle to the outer edge. + *@description The drawTarget() function makes it easy to draw many distinct + *targets. Each call to drawTarget() specifies the position, size, and number of + *rings for each target. + */ + +function setup() { + createCanvas(720, 400); + background(51); + noStroke(); + noLoop(); +} + +function draw() { + drawTarget(width * 0.25, height * 0.4, 200, 4); + drawTarget(width * 0.5, height * 0.5, 300, 10); + drawTarget(width * 0.75, height * 0.3, 120, 6); +} + +function drawTarget(xloc, yloc, size, num) { + const grayvalues = 255 / num; + const steps = size / num; + for (let i = 0; i < num; i++) { + fill(i * grayvalues); + ellipse(xloc, yloc, size - i * steps, size - i * steps); + } +} diff --git a/dist/assets/examples/en/00_Structure/08_Recursion.js b/dist/assets/examples/en/00_Structure/08_Recursion.js new file mode 100644 index 0000000000..4f0b211912 --- /dev/null +++ b/dist/assets/examples/en/00_Structure/08_Recursion.js @@ -0,0 +1,36 @@ +/* + *@name Recursion + *@arialabel Grey circle with two grey circles across its middle. Each of these two grey circles have more grey circles across its middle. This pattern continues until no more can be drawn within them. + *@description A demonstration of recursion, which means functions call themselves. + * A recursive function must have a terminating condition, without which it will + * go into an infinite loop. Notice how the drawCircle() function calls itself + * at the end of its block. It continues to do this until the variable "level" is + * equal to 1. + */ + +function setup() { + createCanvas(720, 560); + noStroke(); + noLoop(); +} + +function draw() { + drawCircle(width / 2, 280, 6); +} + +function drawCircle(x, radius, level) { + // 'level' is the variable that terminates the recursion once it reaches + // a certain value (here, 1). If a terminating condition is not + // specified, a recursive function keeps calling itself again and again + // until it runs out of stack space - not a favourable outcome! + const tt = (126 * level) / 4.0; + fill(tt); + ellipse(x, height / 2, radius * 2, radius * 2); + if (level > 1) { + // 'level' decreases by 1 at every step and thus makes the terminating condition + // attainable + level = level - 1; + drawCircle(x - radius / 2, radius / 2, level); + drawCircle(x + radius / 2, radius / 2, level); + } +} diff --git a/dist/assets/examples/en/00_Structure/09_Create_Graphics.js b/dist/assets/examples/en/00_Structure/09_Create_Graphics.js new file mode 100644 index 0000000000..a786f0c06c --- /dev/null +++ b/dist/assets/examples/en/00_Structure/09_Create_Graphics.js @@ -0,0 +1,30 @@ +/* + * @name Create Graphics + * @arialabel Black background with a very dark grey rectangle in the middle. The user’s mouse draws in white but not on the center rectangle. + * @description Creates and returns a new p5.Renderer object. Use this + * class if you need to draw into an off-screen graphics buffer. The two parameters + * define the width and height in pixels. + */ + +let pg; + +function setup() { + createCanvas(710, 400); + pg = createGraphics(400, 250); +} + +function draw() { + fill(0, 12); + rect(0, 0, width, height); + fill(255); + noStroke(); + ellipse(mouseX, mouseY, 60, 60); + + pg.background(51); + pg.noFill(); + pg.stroke(255); + pg.ellipse(mouseX - 150, mouseY - 75, 60, 60); + + //Draw the offscreen buffer to the screen with image() + image(pg, 150, 75); +} diff --git a/dist/assets/examples/en/01_Form/00_Points_and_Lines.js b/dist/assets/examples/en/01_Form/00_Points_and_Lines.js new file mode 100644 index 0000000000..4aeb06e69f --- /dev/null +++ b/dist/assets/examples/en/01_Form/00_Points_and_Lines.js @@ -0,0 +1,37 @@ +/* + * @name Points and Lines + * @arialabel White outline of a square on a black background + * @description Points and lines can be used to draw basic geometry. + * Change the value of the variable 'd' to scale the form. The four + * variables set the positions based on the value of 'd'. + */ +function setup() { + let d = 70; + let p1 = d; + let p2 = p1 + d; + let p3 = p2 + d; + let p4 = p3 + d; + + // Sets the screen to be 720 pixels wide and 400 pixels high + createCanvas(720, 400); + background(0); + noSmooth(); + + translate(140, 0); + + // Draw gray box + stroke(153); + line(p3, p3, p2, p3); + line(p2, p3, p2, p2); + line(p2, p2, p3, p2); + line(p3, p2, p3, p3); + + // Draw white points + stroke(255); + point(p1, p1); + point(p1, p3); + point(p2, p4); + point(p3, p1); + point(p4, p2); + point(p4, p4); +} diff --git a/dist/assets/examples/en/01_Form/01_Shape_Primitives.js b/dist/assets/examples/en/01_Form/01_Shape_Primitives.js new file mode 100644 index 0000000000..b7726f42ca --- /dev/null +++ b/dist/assets/examples/en/01_Form/01_Shape_Primitives.js @@ -0,0 +1,32 @@ +/* + * @name Shape Primitives + * @arialabel From left to right: a grey triangle, a darker grey square, a light grey trapezoid, a white circle, a light grey triangle, and a white half circle, on a black background + * @description The basic shape primitive functions are triangle(), + * rect(), quad(), ellipse(), and arc(). Squares are made with rect() + * and circles are made with ellipse(). Each of these functions requires + * a number of parameters to determine the shape's position and size. + */ +function setup() { + // Sets the screen to be 720 pixels wide and 400 pixels high + createCanvas(720, 400); + background(0); + noStroke(); + + fill(204); + triangle(18, 18, 18, 360, 81, 360); + + fill(102); + rect(81, 81, 63, 63); + + fill(204); + quad(189, 18, 216, 18, 216, 360, 144, 360); + + fill(255); + ellipse(252, 144, 72, 72); + + fill(204); + triangle(288, 18, 351, 360, 288, 360); + + fill(255); + arc(479, 300, 280, 280, PI, TWO_PI); +} diff --git a/dist/assets/examples/en/01_Form/02_Pie_Chart.js b/dist/assets/examples/en/01_Form/02_Pie_Chart.js new file mode 100644 index 0000000000..b95d3b6b43 --- /dev/null +++ b/dist/assets/examples/en/01_Form/02_Pie_Chart.js @@ -0,0 +1,35 @@ +/* + * @name Pie Chart + * @arialabel Pie chart on a grey background with the different slices of the pie chart in various shades of grey + * @description Uses the arc() function to generate a pie chart from the data + * stored in an array. + */ +let angles = [30, 10, 45, 35, 60, 38, 75, 67]; + +function setup() { + createCanvas(720, 400); + noStroke(); + noLoop(); // Run once and stop +} + +function draw() { + background(100); + pieChart(300, angles); +} + +function pieChart(diameter, data) { + let lastAngle = 0; + for (let i = 0; i < data.length; i++) { + let gray = map(i, 0, data.length, 0, 255); + fill(gray); + arc( + width / 2, + height / 2, + diameter, + diameter, + lastAngle, + lastAngle + radians(angles[i]) + ); + lastAngle += radians(angles[i]); + } +} diff --git a/dist/assets/examples/en/01_Form/03_Regular_Polygon.js b/dist/assets/examples/en/01_Form/03_Regular_Polygon.js new file mode 100644 index 0000000000..d84740c2fd --- /dev/null +++ b/dist/assets/examples/en/01_Form/03_Regular_Polygon.js @@ -0,0 +1,44 @@ +/* + * @name Regular Polygon + * @arialabel Three white shapes with black outlines on a grey background rotating. From left to right, a triangle, icosagon, and a heptagon + * @description What is your favorite? Pentagon? Hexagon? Heptagon? No? + * What about the icosagon? The polygon() function created for this example is + * capable of drawing any regular polygon. Try placing different numbers into + * the polygon() function calls within draw() to explore. + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + polygon(0, 0, 82, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + polygon(0, 0, 80, 20); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + polygon(0, 0, 70, 7); + pop(); +} + +function polygon(x, y, radius, npoints) { + let angle = TWO_PI / npoints; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius; + let sy = y + sin(a) * radius; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/en/01_Form/04_Star.js b/dist/assets/examples/en/01_Form/04_Star.js new file mode 100644 index 0000000000..e8dbb998c2 --- /dev/null +++ b/dist/assets/examples/en/01_Form/04_Star.js @@ -0,0 +1,47 @@ +/* + * @name Star + * @arialabel Grey background with three white shapes rotating with black outlines. From left to right, a 3-pointed star, a 40-pointed shape, and a 5-pointed star + * @description The star() function created for this example is capable of + * drawing a wide range of different forms. Try placing different numbers + * into the star() function calls within draw() to explore. + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + star(0, 0, 5, 70, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + star(0, 0, 80, 100, 40); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + star(0, 0, 30, 70, 5); + pop(); +} + +function star(x, y, radius1, radius2, npoints) { + let angle = TWO_PI / npoints; + let halfAngle = angle / 2.0; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius2; + let sy = y + sin(a) * radius2; + vertex(sx, sy); + sx = x + cos(a + halfAngle) * radius1; + sy = y + sin(a + halfAngle) * radius1; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/en/01_Form/05_Triangle_Strip.js b/dist/assets/examples/en/01_Form/05_Triangle_Strip.js new file mode 100644 index 0000000000..be5a1d2807 --- /dev/null +++ b/dist/assets/examples/en/01_Form/05_Triangle_Strip.js @@ -0,0 +1,39 @@ +/* + * @name Triangle Strip + * @arialabel A ring of white triangles form a heptagon on the grey background. When a user drags their mouse from left to right, the number of triangles increase and create a smoother, circular ring + * @description Example by Ira Greenberg. Generate a closed ring using the + * vertex() function and beginShape(TRIANGLE_STRIP) mode. The outsideRadius + * and insideRadius variables control ring's radii respectively. + */ +let x; +let y; +let outsideRadius = 150; +let insideRadius = 100; + +function setup() { + createCanvas(720, 400); + background(204); + x = width / 2; + y = height / 2; +} + +function draw() { + background(204); + + let numPoints = int(map(mouseX, 0, width, 6, 60)); + let angle = 0; + let angleStep = 180.0 / numPoints; + + beginShape(TRIANGLE_STRIP); + for (let i = 0; i <= numPoints; i++) { + let px = x + cos(radians(angle)) * outsideRadius; + let py = y + sin(radians(angle)) * outsideRadius; + angle += angleStep; + vertex(px, py); + px = x + cos(radians(angle)) * insideRadius; + py = y + sin(radians(angle)) * insideRadius; + vertex(px, py); + angle += angleStep; + } + endShape(); +} diff --git a/dist/assets/examples/en/01_Form/06_Bezier.js b/dist/assets/examples/en/01_Form/06_Bezier.js new file mode 100644 index 0000000000..cef3778da3 --- /dev/null +++ b/dist/assets/examples/en/01_Form/06_Bezier.js @@ -0,0 +1,29 @@ +/* + * @name Bezier + * @arialabel 10 lines in a bezier curve formation. The bottom of the curve does not move but as the user’s mouse moves, the top of the curve follows the left and right movement + * @description The first two parameters for the bezier() function specify the + * first point in the curve and the last two parameters specify the last point. + * The middle parameters set the control points that define the shape of the + * curve. + */ +function setup() { + createCanvas(720, 400); + stroke(255); + noFill(); +} + +function draw() { + background(0); + for (let i = 0; i < 200; i += 20) { + bezier( + mouseX - i / 2.0, + 40 + i, + 410, + 20, + 440, + 300, + 240 - i / 16.0, + 300 + i / 8.0 + ); + } +} diff --git a/dist/assets/examples/en/01_Form/07_3D_Primitives.js b/dist/assets/examples/en/01_Form/07_3D_Primitives.js new file mode 100644 index 0000000000..89a93fc57f --- /dev/null +++ b/dist/assets/examples/en/01_Form/07_3D_Primitives.js @@ -0,0 +1,31 @@ +/* + * @name 3D Primitives + * @arialabel Grey background with a dark grey cube in the bottom left corner and a white outlined sphere in the bottom right corner + * @frame 720,400 (optional) + * @description Placing mathematically 3D objects in synthetic space. + * The box() and sphere() functions take at least one parameter to specify their + * size. These shapes are positioned using the translate() function. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(100); + + noStroke(); + fill(50); + push(); + translate(-275, 175); + rotateY(1.25); + rotateX(-0.9); + box(100); + pop(); + + noFill(); + stroke(255); + push(); + translate(500, height * 0.35, -200); + sphere(300); + pop(); +} diff --git a/dist/assets/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart.js b/dist/assets/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart.js new file mode 100644 index 0000000000..dcbf6dfd29 --- /dev/null +++ b/dist/assets/examples/en/01_Form/08_Trig_Wheels_and_Pie_Chart.js @@ -0,0 +1,89 @@ +/* + * @name Trig Wheels and Pie Chart + * @arialabel Two circles on a white background. One circle has slices of various colors. One circle is comprised of rectangles spiraled into a circle shape in a rainbow gradient + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to create +a trig color wheel and a visualization of a population age data as a +pie chart.
+ Functions are +created for the canvas setup, trig color wheel, drawslice, and pie +chart. The size of the slices are determined as well as their color +range. The pie chart is separated by definitive color per value +whereas the trig color wheel has a fixed slice amount with a range +color fill. +*/ + +function setup() { + createCanvas(400, 400); + colorMode(HSB); + angleMode(DEGREES); + + //vars for color wheel center point + let x = width / 2; + let y = height / 2 + 100; + colorWheel(x, y, 100); //slide 11 + + noStroke(); + pieChartPop(200, 100); //slide 12 +} + +//**** slide 12 pie chart trig demo +function pieChartPop(x, y) { + let [total, child, young, adult, senior, elder] = [577, 103, 69, + 122, 170, 113 + ]; + let startValue = 0; + let range = 0; + + //child slice + range = child / total; + drawSlice("blue", x, y, 200, startValue, startValue + range); + startValue += range; + //young slice + range = young / total; + drawSlice("orange", x, y, 200, startValue, startValue + range); + startValue += range; + //adult slice + range = adult / total; + drawSlice("green", x, y, 200, startValue, startValue + range); + startValue += range; + //senior slice + range = senior / total; + drawSlice("tan", x, y, 200, startValue, startValue + range); + startValue += range; + //elder slice + range = elder / total; + drawSlice("pink", x, y, 200, startValue, startValue + range); + startValue += range; + +} + +/** + * drawSlice - draw colored arc based on angle percentages. slide 13 + * Adjust angles so that 0% starts at top (actually -90). + * @param {color} fColor - fill color + * @param {number} x - center x + * @param {number} y - center y + * @param {number} d - diameter + * @param {float} percent1 - starting percentage + * @param {float} percent2 - ending percentage + */ +function drawSlice(fColor, x, y, d, percent1, percent2) { + fill(fColor); + arc(x, y, d, d, -90 + percent1 * 360, -90 + percent2 * 360); +} + +//**** slide 11 trig demo +function colorWheel(x, y, rad) { + strokeWeight(10); + strokeCap(SQUARE); + + //Iterate 360 degrees of lines, +10deg per turn + for (let a = 0; a < 360; a += 10) { + stroke(a, 150, 200); //hue based on a + //radius is 100, angle is a degrees + line(x, y, x + rad * cos(a), + y + rad * sin(a)); + } +} diff --git a/dist/assets/examples/en/02_Data/00_Variables.js b/dist/assets/examples/en/02_Data/00_Variables.js new file mode 100644 index 0000000000..95b750da04 --- /dev/null +++ b/dist/assets/examples/en/02_Data/00_Variables.js @@ -0,0 +1,38 @@ +/* + * @name Variables + * @arialabel Black background with three sets of grey lines that form rectangles. + * @description Variables are used for storing values. In this example, change + * the values of variables to affect the composition. + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(153); + strokeWeight(4); + strokeCap(SQUARE); + + let a = 50; + let b = 120; + let c = 180; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); +} diff --git a/dist/assets/examples/en/02_Data/01_True_and_False.js b/dist/assets/examples/en/02_Data/01_True_and_False.js new file mode 100644 index 0000000000..d86f218d15 --- /dev/null +++ b/dist/assets/examples/en/02_Data/01_True_and_False.js @@ -0,0 +1,32 @@ +/* + * @name True and False + * @arialabel Black background with vertical white lines on the left half and horizontal white lines on the right half + * @description A Boolean variable has only two possible values: true or false. + * It is common to use Booleans with control statements to determine the flow + * of a program. In this example, when the boolean value "b" is true, vertical + * lines are drawn and when the boolean value "b" is false, horizontal + * lines are drawn. + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + + let b = false; + let d = 20; + let middle = width / 2; + + for (let i = d; i <= width; i += d) { + b = i < middle; + + if (b === true) { + // Vertical line + line(i, d, i, height - d); + } + + if (b === false) { + // Horizontal line + line(middle, i - middle + d, width - d, i - middle + d); + } + } +} diff --git a/dist/assets/examples/en/02_Data/03_Variable_Scope.js b/dist/assets/examples/en/02_Data/03_Variable_Scope.js new file mode 100644 index 0000000000..a58724046a --- /dev/null +++ b/dist/assets/examples/en/02_Data/03_Variable_Scope.js @@ -0,0 +1,49 @@ +/* + * @name Variable Scope + * @arialabel Black background with vertical white lines condensed on the left side + * @description Variables have a global or function "scope". For example, + * variables declared within either the setup() or draw() functions may be + * only used in these functions. Global variables, variables declared outside + * of setup() and draw(), may be used anywhere within the program. If a function + * variable is declared with the same name as a global variable, the program + * will use the function variable to make its calculations within the current + * scope. + */ +let a = 80; // Create a global variable "a" + +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + noLoop(); +} + +function draw() { + // Draw a line using the global variable "a" + line(a, 0, a, height); + + // Use a local variable a in for loop + for (let a = 120; a < 200; a += 3) { + line(a, 0, a, height); + } + + // Make a call to the custom function drawAnotherLine() + drawAnotherLine(); + + // Make a call to the custom function drawYetAnotherLine() + drawYetAnotherLine(); +} + +function drawAnotherLine() { + // Create a new variable "a" local to this function + let a = 320; + // Draw a line using the local variable "a" + line(a, 0, a, height); +} + +function drawYetAnotherLine() { + // Because no new local variable "a" is set, + // this line draws using the original global + // variable "a" which is set to the value 20. + line(a + 3, 0, a + 3, height); +} diff --git a/dist/assets/examples/en/02_Data/04_Numbers.js b/dist/assets/examples/en/02_Data/04_Numbers.js new file mode 100644 index 0000000000..b786a524b5 --- /dev/null +++ b/dist/assets/examples/en/02_Data/04_Numbers.js @@ -0,0 +1,32 @@ +/* + * @name Numbers + * @arialabel A black background with one white vertical line on the top half and one on the bottom. Both lines move from the left to the right of the screen with the top vertical line moving faster than the bottom. + * @frame 720,400 + * @description Numbers can be written with or without decimals. An integer + * (more commonly called an int) is a number without a decimal point. A float + * is a floating-point number, which means it is a number that has a decimal + * place. + */ +let a = 0; // Create a global variable "a" of type Number +let b = 0; // Create a global variable "b" of type Number + +function setup() { + createCanvas(720, 400); + stroke(255); +} + +function draw() { + background(0); + + a = a + 1; // Increment a with an integer + b = b + 0.2; //Increment b with a float + line(a, 0, a, height / 2); + line(b, height / 2, b, height); + + if (a > width) { + a = 0; + } + if (b > width) { + b = 0; + } +} diff --git a/dist/assets/examples/en/03_Arrays/00_Array.js b/dist/assets/examples/en/03_Arrays/00_Array.js new file mode 100644 index 0000000000..0c245ea30f --- /dev/null +++ b/dist/assets/examples/en/03_Arrays/00_Array.js @@ -0,0 +1,45 @@ +/* + * @name Array + * @arialabel Vertical lines are graphed across a white background to visualize the values of a cosine curve + * @description An array is a list of data. Each piece of data in an array + * is identified by an index number representing its position in + * the array. Arrays are zero based, which means that the first + * element in the array is [0], the second element is [1], and so on. + * In this example, an array named "coswave" is created and + * filled with the cosine values. This data is displayed three + * separate ways on the screen. + */ +let coswave = []; + +function setup() { + createCanvas(720, 360); + for (let i = 0; i < width; i++) { + let amount = map(i, 0, width, 0, PI); + coswave[i] = abs(cos(amount)); + } + background(255); + noLoop(); +} + +function draw() { + let y1 = 0; + let y2 = height / 3; + for (let i = 0; i < width; i += 3) { + stroke(coswave[i] * 255); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = y1 + y1; + for (let i = 0; i < width; i += 3) { + stroke((coswave[i] * 255) / 4); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = height; + for (let i = 0; i < width; i += 3) { + stroke(255 - coswave[i] * 255); + line(i, y1, i, y2); + } +} diff --git a/dist/assets/examples/en/03_Arrays/01_Array_2d.js b/dist/assets/examples/en/03_Arrays/01_Array_2d.js new file mode 100644 index 0000000000..82f04efe9a --- /dev/null +++ b/dist/assets/examples/en/03_Arrays/01_Array_2d.js @@ -0,0 +1,39 @@ +/* + * @name Array 2D + * @arialabel A grid of dots drawn on a black background. Dots closer to the center are darker in color and dots further away from the center are whiter in color + * @description Demonstrates the syntax for creating a two-dimensional (2D) + * array. Values in a 2D array are accessed through two index values. + * 2D arrays are useful for storing images. In this example, each dot + * is colored in relation to its distance from the center of the image. + */ +let distances = []; +let maxDistance; +let spacer; + +function setup() { + createCanvas(720, 360); + maxDistance = dist(width / 2, height / 2, width, height); + for (let x = 0; x < width; x++) { + distances[x] = []; // create nested array + for (let y = 0; y < height; y++) { + let distance = dist(width / 2, height / 2, x, y); + distances[x][y] = (distance / maxDistance) * 255; + } + } + spacer = 10; + noLoop(); // Run once and stop +} + +function draw() { + background(0); + // This embedded loop skips over values in the arrays based on + // the spacer variable, so there are more values in the array + // than are drawn here. Change the value of the spacer variable + // to change the density of the points + for (let x = 0; x < width; x += spacer) { + for (let y = 0; y < height; y += spacer) { + stroke(distances[x][y]); + point(x + spacer / 2, y + spacer / 2); + } + } +} diff --git a/dist/assets/examples/en/03_Arrays/02_Array_Objects.js b/dist/assets/examples/en/03_Arrays/02_Array_Objects.js new file mode 100644 index 0000000000..cae5bc765e --- /dev/null +++ b/dist/assets/examples/en/03_Arrays/02_Array_Objects.js @@ -0,0 +1,72 @@ +/* + * @name Array Objects + * @arialabel Small white circles all over a black background that move side to side and sometimes collide and bounce off of each other + * @description Demonstrates the syntax for creating an array of custom objects. + */ + +class Module { + constructor(xOff, yOff, x, y, speed, unit) { + this.xOff = xOff; + this.yOff = yOff; + this.x = x; + this.y = y; + this.speed = speed; + this.unit = unit; + this.xDir = 1; + this.yDir = 1; + } + + // Custom method for updating the variables + update() { + this.x = this.x + this.speed * this.xDir; + if (this.x >= this.unit || this.x <= 0) { + this.xDir *= -1; + this.x = this.x + 1 * this.xDir; + this.y = this.y + 1 * this.yDir; + } + if (this.y >= this.unit || this.y <= 0) { + this.yDir *= -1; + this.y = this.y + 1 * this.yDir; + } + } + + // Custom method for drawing the object + draw() { + fill(255); + ellipse(this.xOff + this.x, this.yOff + this.y, 6, 6); + } +} + +let unit = 40; +let count; +let mods = []; + +function setup() { + createCanvas(720, 360); + noStroke(); + let wideCount = width / unit; + let highCount = height / unit; + count = wideCount * highCount; + + let index = 0; + for (let y = 0; y < highCount; y++) { + for (let x = 0; x < wideCount; x++) { + mods[index++] = new Module( + x * unit, + y * unit, + unit / 2, + unit / 2, + random(0.05, 0.8), + unit + ); + } + } +} + +function draw() { + background(0); + for (let i = 0; i < count; i++) { + mods[i].update(); + mods[i].draw(); + } +} diff --git a/dist/assets/examples/en/03_Arrays/03_Walk_Over_2dArray.js b/dist/assets/examples/en/03_Arrays/03_Walk_Over_2dArray.js new file mode 100644 index 0000000000..b8e6d5431d --- /dev/null +++ b/dist/assets/examples/en/03_Arrays/03_Walk_Over_2dArray.js @@ -0,0 +1,86 @@ +/* + * @name Walk Over 2dArray + * @arialabel 20 phrases in black text are arranged on a black background with 4 phrases in a row, 5 rows total + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to display 2D array contents on the canvas +using regular for and for-of loops in multiple different ways.
+ A function is created for the canvas, the 2D + array (Friend Array) is initialized and walked over using nested + loops in different ways. Variables x and y are used to place the + array item on the canvas in the form of 2D array. + The final nested loop is used to initialize 2D + array (Fish Array) with random Integers (fish ages). +*/ + + +//"use strict"; //catch some common coding errors + + +/** + * setup : + */ +function setup() { + createCanvas(400, 600); + //create 2D array, slide 4 + let friendArray = [ + ["Nona", "mac & cheese", "orange", "Eid al-fitr"], + ["Marylin", "ice cream", "blue", "Halloween"], + ["Rashaad", "garbage plates", "turquoise", "Christmas"], + ["Ava", "sushi", "pink", "New Years"] + ]; + friendArray.push(["Xavier", "Louisiana creole", "red", "their birthday"]); + + //walking 2D array, slide 6 + let y = 20; // Start row based on text size of 20 + for (let f = 0; f < friendArray.length; f++) { // outer array + let x = 10; // Start item in this row + for (let t = 0; t < friendArray[f].length; t++) { //inner + text(friendArray[f][t], x, y); + x += textWidth(friendArray[f][t]) + 20; //place next item + } + y += 28; // place next row + } + + //walking 2D array, variation on slide 6 + //with embedded arithmetic for y + // + for (let f = 0; f < friendArray.length; f++) { // outer array + let x = 10; // Start item in this row + for (let t = 0; t < friendArray[f].length; t++) { //inner + //y is v-padding + LCV * v-spacing + text(friendArray[f][t], x, 200 + f * 28); + x += textWidth(friendArray[f][t]) + 20; //place next item + } + } + + //walking 2D array, slide 7 + //need to use x and y variables to manage canvas placement + y = 400; + for (let friend of friendArray) { + let x = 10; // Start item in this row + console.log("x and y", x, y); + console.log("friend:", friend); + for (let item of friend) { + console.log("item & x:", item, x); + text(item, x, y); + x += textWidth(item) + 20; //place next item + } + y += 28; // place next row + } + + //slide 9, creating 2D array: schools of fish ages + console.log("\n *** Fish ages in 2D ***"); + const schools = []; + //4 schools of fish + for (let t = 0; t < 4; t++) { + schools[t] = []; //initialize this school + console.log("schools[t]?", t, schools[t]); + + // Add 10 randomized ages to the array + for (let a = 0; a < 10; a++) { + schools[t].push(round(random(1, 5))); + } + } + console.log(schools); + } diff --git a/dist/assets/examples/en/04_Control/00_Iteration.js b/dist/assets/examples/en/04_Control/00_Iteration.js new file mode 100644 index 0000000000..6d51a4c860 --- /dev/null +++ b/dist/assets/examples/en/04_Control/00_Iteration.js @@ -0,0 +1,42 @@ +/* + * @name Iteration + * @arialabel White bars on the top half of the screen intersect with thin lines on the left and dark grey bars on the right + * @description Iteration with a "for" structure to construct repetitive forms. + */ +let y; +let num = 14; + +function setup() { + createCanvas(720, 360); + background(102); + noStroke(); + + // Draw white bars + fill(255); + y = 60; + for (let i = 0; i < num / 3; i++) { + rect(50, y, 475, 10); + y += 20; + } + + // Gray bars + fill(51); + y = 40; + for (let i = 0; i < num; i++) { + rect(405, y, 30, 10); + y += 20; + } + y = 50; + for (let i = 0; i < num; i++) { + rect(425, y, 30, 10); + y += 20; + } + + // Thin lines + y = 45; + fill(0); + for (let i = 0; i < num - 1; i++) { + rect(120, y, 40, 1); + y += 20; + } +} diff --git a/dist/assets/examples/en/04_Control/01_Embedded_Iteration.js b/dist/assets/examples/en/04_Control/01_Embedded_Iteration.js new file mode 100644 index 0000000000..ff7b852a8e --- /dev/null +++ b/dist/assets/examples/en/04_Control/01_Embedded_Iteration.js @@ -0,0 +1,22 @@ +/* + * @name Embedded Iteration + * @arialabel Rays emerge from the center of the screen to the edges. There is also a square grid of white circles over the window + * @description Embedding "for" structures allows repetition in two dimensions. + */ +function setup() { + createCanvas(720, 360); + background(0); + noStroke(); + + let gridSize = 35; + + for (let x = gridSize; x <= width - gridSize; x += gridSize) { + for (let y = gridSize; y <= height - gridSize; y += gridSize) { + noStroke(); + fill(255); + rect(x - 1, y - 1, 3, 3); + stroke(255, 50); + line(x, y, width / 2, height / 2); + } + } +} diff --git a/dist/assets/examples/en/04_Control/02_Conditionals_1.js b/dist/assets/examples/en/04_Control/02_Conditionals_1.js new file mode 100644 index 0000000000..e3b6b582f1 --- /dev/null +++ b/dist/assets/examples/en/04_Control/02_Conditionals_1.js @@ -0,0 +1,27 @@ +/* + * @name Conditionals 1 + * @arialabel Pattern of alternating long and short lines + * @description Conditions are like questions. + * They allow a program to decide to take one action if + * the answer to a question is true or to do another action + * if the answer to the question is false. + * The questions asked within a program are always logical + * or relational statements. For example, if the variable 'i' is + * equal to zero then draw a line. + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 10; i < width; i += 10) { + // If 'i' divides by 20 with no remainder draw the first line + // else draw the second line + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + } else { + stroke(153); + line(i, 20, i, 180); + } + } +} diff --git a/dist/assets/examples/en/04_Control/03_Conditionals_2.js b/dist/assets/examples/en/04_Control/03_Conditionals_2.js new file mode 100644 index 0000000000..a84c2ba04a --- /dev/null +++ b/dist/assets/examples/en/04_Control/03_Conditionals_2.js @@ -0,0 +1,29 @@ +/* + * @name Conditionals 2 + * @arialabel The top half of the window has spaced out vertical lines. The bottom half of the window has more condensed vertical lines + * @description We extend the language of conditionals from the previous + * example by adding the keyword "else". This allows conditionals + * to ask two or more sequential questions, each with a different + * action. + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 2; i < width - 2; i += 4) { + // If 'i' divides by 20 with no remainder + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + // If 'i' divides by 10 with no remainder + } else if (i % 10 === 0) { + stroke(153); + line(i, 20, i, 180); + // If neither of the above two conditions are met + // then draw this line + } else { + stroke(102); + line(i, height / 2, i, height - 20); + } + } +} diff --git a/dist/assets/examples/en/04_Control/04_Logical_Operators.js b/dist/assets/examples/en/04_Control/04_Logical_Operators.js new file mode 100644 index 0000000000..7cc4decc76 --- /dev/null +++ b/dist/assets/examples/en/04_Control/04_Logical_Operators.js @@ -0,0 +1,43 @@ +/* + * @name Logical Operators + * @arialabel Horizontal black lines across half of a grey background. Part of these lines are shifted left and there are vertical lines of dots above and below this + * @description The logical operators for AND (&&) and OR (||) are used to + * combine simple relational statements into more complex expressions. + * The NOT (!) operator is used to negate a boolean statement. + */ +let test = false; + +function setup() { + createCanvas(720, 360); + background(126); + + for (let i = 5; i <= height; i += 5) { + // Logical AND + stroke(0); + if (i > 35 && i < 100) { + line(width / 4, i, width / 2, i); + test = false; + } + + // Logical OR + stroke(76); + if (i <= 35 || i >= 100) { + line(width / 2, i, width, i); + test = true; + } + + // Testing if a boolean value is "true" + // The expression "if(test)" is equivalent to "if(test == true)" + if (test) { + stroke(0); + point(width / 3, i); + } + + // Testing if a boolean value is "false" + // The expression "if(!test)" is equivalent to "if(test == false)" + if (!test) { + stroke(255); + point(width / 4, i); + } + } +} diff --git a/dist/assets/examples/en/04_Control/05_Logical_Operators_2.js b/dist/assets/examples/en/04_Control/05_Logical_Operators_2.js new file mode 100644 index 0000000000..17b32a83a6 --- /dev/null +++ b/dist/assets/examples/en/04_Control/05_Logical_Operators_2.js @@ -0,0 +1,92 @@ +/* + * @name Logical Operators 2 + * @arialabel Squares travel diagonally across the screen when a rectangle on the screen is pressed + * @frame 400,400 + * @description contributed by + Prof WM Harris, How + to create Xboxes with one global variable and create conditions with + boolean variables and boolean expressions by utilizing Boolean + operators ||, &&, and ! to do boundary checking.
+ Functions + are created for both the canvas set up as well as the creation of + the boxes. Background color is dependent on the location of the + boxes in the canvas space. When mouse button and key are pressed + simultaneously, the “where” text and box color changes to cyan, + but if the mouse button is clicked alone then the animation will + start. When q or Q are pressed the text “Did you type q or Q?” + will change to blue, else it will be purple. If the mouse is placed + within the orange box containing the text, “withinRect” then the + shape will turn pink. + */ + + +//1 coordinate for everything :) +let where = 0; //control boxes' positions + +function setup() { + createCanvas(400, 400); +} + +function draw() { + //similar to slide 4 use of OR, || + //to set bg color of canvas + if ((where < 0) || (where > height)) { + background("beige"); + } else { + background("chocolate"); + } + + //similar to slide 4 use of AND, && + //to set fill color of box & text + if (mouseIsPressed && keyIsPressed) { + fill("cyan"); + } else { + fill(255); + } + + //boxL + rect(where, where, 40); + + //boxR, pad x coordinate for size of box + rect(width - where - 40, where, 40); + + //Move the boxes + where = where + 1; + + //Show the value of where the boxes are + text("where is " + where, 150, 30); + + //testing not, ! and or, || operators + if (!(key === "q" || key === "Q")) { + fill("purple"); + } else { + fill("dodgerBlue"); + } + //Show the current key value + text("Did you type a q or Q? " + key, 150, 70); + + //*** Boundary checking *** + //Is the mouse within rect boundary? + //left, right, top, bottom + let withinRect = (mouseX >= 150) && + (mouseX <= 150 + 100) && + (mouseY >= 300) && + (mouseY <= 300 + 40); + //fill color based on value of withinRect + if (withinRect) { + fill("pink"); + } else { + fill("orange"); + } + //draw the rect + rect(150, 300, 100, 40); + //show withinRect value as label on rect + fill(0); + text("withinRect " + withinRect, 160, 320); +} + +//boxes restart +function mousePressed() { + //Reset boxes back up and above the canvas + where = -50; +} \ No newline at end of file diff --git a/dist/assets/examples/en/04_Control/06_Conditional_Shapes.js b/dist/assets/examples/en/04_Control/06_Conditional_Shapes.js new file mode 100644 index 0000000000..f3562640ee --- /dev/null +++ b/dist/assets/examples/en/04_Control/06_Conditional_Shapes.js @@ -0,0 +1,49 @@ +/* + * @name Conditional Shapes + * @arialabel The middle of the window is white and the user’s mouse draws red dots within it. The side edges of the window are beige and as the user’s mouse travels up and down the edges, orange squares with a red border are drawn up and down the center of the window + * @frame 400,400 + * @description contributed by + Prof WM Harris, How + to draw different shapes mid canvas depending on the mouse position.
+ Functions + are created for the main canvas set up with the markers on the left and + right hand sides. One is also created for the location of the mouse + regarding the canvas and the markers. If the mouse is within the + outer left hand beige rectangle, then the shape of circle is drawn + down the center of the canvas. If the mouse is within the outer right + hand beige rectangle, then the shape of square is drawn down the + center of the canvas. +*/ +function setup() { + createCanvas(400, 400); + strokeWeight(3); + //center squares to match circles + rectMode(CENTER); + + //draw rects to mark far sides + noStroke(); + fill("beige"); + rect(5, height / 2, 10, height); + rect(width - 5, height / 2, 10, height); + fill("orange"); + stroke("brown"); + + } + + function draw() { + point(mouseX, mouseY); + + //if (test) {doThis; } + //test: mouseX on far left of canvas + //doThis: draw a circle at mouseY + if (mouseX < 10) { + circle(width / 2, mouseY, 20); + } + + //test: mouseX on far right of canvas + //doThis: draw a square at mouseY + if (mouseX > width - 10) { + square(width / 2, mouseY, 20); + } + + } diff --git a/dist/assets/examples/en/05_Image/00_Load_and_Display_Image.js b/dist/assets/examples/en/05_Image/00_Load_and_Display_Image.js new file mode 100644 index 0000000000..2d4c70b8a8 --- /dev/null +++ b/dist/assets/examples/en/05_Image/00_Load_and_Display_Image.js @@ -0,0 +1,23 @@ +/* + * @name Load and Display Image + * @arialabel An astronaut on a planet with the same image in a smaller size in the bottom left quarter + * @description Images can be loaded and displayed to the screen at their + * actual size or any other size. + *

To run this example locally, you will need an + * image file, and a running + * local server.

+ + */ +let img; // Declare variable 'img'. + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // Load the image +} + +function draw() { + // Displays the image at its actual size at point (0,0) + image(img, 0, 0); + // Displays the image at point (0, height/2) at half size + image(img, 0, height / 2, img.width / 2, img.height / 2); +} diff --git a/dist/assets/examples/en/05_Image/01_Background_Image.js b/dist/assets/examples/en/05_Image/01_Background_Image.js new file mode 100644 index 0000000000..32a6af747c --- /dev/null +++ b/dist/assets/examples/en/05_Image/01_Background_Image.js @@ -0,0 +1,32 @@ +/* + * @name Background Image + * @arialabel An astronaut on a planet with a horizontal yellow line traveling from the top to the bottom of the image + * @description This example presents the fastest way to load a + * background image. To load an image as the background, + * it must be the same width and height as the program. + *

To run this example locally, you will need an + * image file, and a running + * local server.

+ */ +let bg; +let y = 0; + +function setup() { + // The background image must be the same size as the parameters + // into the createCanvas() method. In this program, the size of + // the image is 720x400 pixels. + bg = loadImage('assets/moonwalk.jpg'); + createCanvas(720, 400); +} + +function draw() { + background(bg); + + stroke(226, 204, 0); + line(0, y, width, y); + + y++; + if (y > height) { + y = 0; + } +} diff --git a/dist/assets/examples/en/05_Image/02_Transparency.js b/dist/assets/examples/en/05_Image/02_Transparency.js new file mode 100644 index 0000000000..8a12536041 --- /dev/null +++ b/dist/assets/examples/en/05_Image/02_Transparency.js @@ -0,0 +1,26 @@ +/* + * @name Transparency + * @arialabel An astronaut on planet as the background with a slightly transparent version of this image on top that moves with the horizontal direction of the user’s mouse + * @description Move the pointer left and right across the image to change its + * position. This program overlays one image over another by modifying the + * alpha value of the image with the tint() function. + *

To run this example locally, you will need an + * image file, and a running + * local server.

+ */ +let img; +let offset = 0; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // Load an image into the program +} + +function draw() { + image(img, 0, 0); // Display at full opacity + let dx = mouseX - img.width / 2 - offset; + offset += dx * easing; + tint(255, 127); // Display at half opacity + image(img, offset, 0); +} diff --git a/dist/assets/examples/en/05_Image/03_Alpha_Mask.js b/dist/assets/examples/en/05_Image/03_Alpha_Mask.js new file mode 100644 index 0000000000..477fc3bf89 --- /dev/null +++ b/dist/assets/examples/en/05_Image/03_Alpha_Mask.js @@ -0,0 +1,29 @@ +/* + * @name Alpha Mask + * @arialabel An astronaut on a planet as the background with a slightly transparent version of this image on top that moves with the horizontal direction of the user’s mouse. Both have a light blue gradient on the right side. + * @description Loads a "mask" for an image to specify the transparency in + * different parts of the image. The two images are blended together using + * the mask() method of p5.Image. + *

To run this example locally, you will need two + * image files, and a running + * local server.

+ */ +let img; +let imgMask; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); + imgMask = loadImage('assets/mask.png'); +} + +function setup() { + createCanvas(720, 400); + img.mask(imgMask); + imageMode(CENTER); +} + +function draw() { + background(0, 102, 153); + image(img, width / 2, height / 2); + image(img, mouseX, mouseY); +} diff --git a/dist/assets/examples/en/05_Image/04_Create_Image.js b/dist/assets/examples/en/05_Image/04_Create_Image.js new file mode 100644 index 0000000000..cd2e0b9ec0 --- /dev/null +++ b/dist/assets/examples/en/05_Image/04_Create_Image.js @@ -0,0 +1,26 @@ +/* + * @name Create Image + * @arialabel Black background with a blue gradient square on the left. Another blue gradient square follows the user’s mouse as it moves + * @description The createImage() function provides a fresh buffer of pixels to + * play with. This example creates an image gradient. + */ +let img; // Declare variable 'img'. + +function setup() { + createCanvas(720, 400); + img = createImage(230, 230); + img.loadPixels(); + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + let a = map(y, 0, img.height, 255, 0); + img.set(x, y, [0, 153, 204, a]); + } + } + img.updatePixels(); +} + +function draw() { + background(0); + image(img, 90, 80); + image(img, mouseX - img.width / 2, mouseY - img.height / 2); +} diff --git a/dist/assets/examples/en/05_Image/05_Pointillism.js b/dist/assets/examples/en/05_Image/05_Pointillism.js new file mode 100644 index 0000000000..22c60611c0 --- /dev/null +++ b/dist/assets/examples/en/05_Image/05_Pointillism.js @@ -0,0 +1,35 @@ +/* + * @name Pointillism + * @arialabel Dots generate on the screen. As the user’s mouse moves left the dots become smaller and as the user’s mouse moves right, the dots become bigger. The colors of the dots are dependent on an image of choice + * @description By Dan Shiffman. Mouse horizontal location controls size of + * dots. Creates a simple pointillist effect using ellipses colored according + * to pixels in an image. + *

To run this example locally, you will need an + * image file, and a running + * local server.

+ */ +let img; +let smallPoint, largePoint; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 400); + smallPoint = 4; + largePoint = 40; + imageMode(CENTER); + noStroke(); + background(255); + img.loadPixels(); +} + +function draw() { + let pointillize = map(mouseX, 0, width, smallPoint, largePoint); + let x = floor(random(img.width)); + let y = floor(random(img.height)); + let pix = img.get(x, y); + fill(pix, 128); + ellipse(x, y, pointillize, pointillize); +} diff --git a/dist/assets/examples/en/05_Image/06_Blur.js b/dist/assets/examples/en/05_Image/06_Blur.js new file mode 100644 index 0000000000..f2992b49ba --- /dev/null +++ b/dist/assets/examples/en/05_Image/06_Blur.js @@ -0,0 +1,90 @@ +/* + * @name Blur + * @arialabel Astronaut rendered in black and white on the left and a blurred version of the image on the right + * @description A low-pass filter that blurs an image. This program analyzes every pixel in an image and blends it with all the neighboring pixels to blur the image. + *

This example is ported from the Blur example + * on the Processing website + */ +// to consider all neighboring pixels we use a 3x3 array +// and normalize these values +// v is the normalized value +let v = 1.0 / 9.0; +// kernel is the 3x3 matrix of normalized values +let kernel = [[ v, v, v ], [ v, v, v ], [ v, v, v ]]; + +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// if loadImage() is called in setup(), the image won't appear +// since noLoop() restricts draw() to execute only once +// (one execution of draw() is not enough time for the image to load), +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover.png"); +} + +// setup() runs once after preload +function setup() { + // create canvas + createCanvas(710, 400); + // noLoop() makes draw() run only once, not in a loop + noLoop(); +} + + +// draw() runs after setup(), normally on a loop +// in this case it runs only once, because of noDraw() +function draw() { + // place the original image on the upper left corner + image(img, 0, 0); + + // create a new image, same dimensions as img + edgeImg = createImage(img.width, img.height); + + // load its pixels + edgeImg.loadPixels(); + + // two for() loops, to iterate in x axis and y axis + // since the kernel assumes that the pixel + // has pixels above, under, left, and right + // we need to skip the first and last column and row + // x then goes from 1 to width - 1 + // y then goes from 1 to height - 1 + for (let x = 1; x < img.width; x++) { + for (let y = 1; y < img.height; y++) { + // kernel sum for the current pixel starts as 0 + let sum = 0; + + // kx, ky variables for iterating over the kernel + // kx, ky have three different values: -1, 0, 1 + for (kx = -1; kx <= 1; kx++) { + for (ky = -1; ky <= 1; ky++) { + let xpos = x + kx; + let ypos = y + ky; + + // since our image is grayscale, + // RGB values are identical + // we retrieve the red value for this example + // (green and blue work as well) + let val = red(img.get(xpos, ypos)); + + // accumulate the kernel sum + // kernel is a 3x3 matrix + // kx and ky have values -1, 0, 1 + // if we add 1 to kx and ky, we get 0, 1, 2 + // with that we can use it to iterate over kernel + // and calculate the accumulated sum + sum += kernel[kx+1][ky+1] * val; + } + } + + // set the value of the edgeImg pixel to the kernel sum + edgeImg.set(x, y, color(sum)); + } + } + // updatePixels() to write the changes on edgeImg + edgeImg.updatePixels(); + + // draw edgeImg at the right of the original image + image(edgeImg, img.width, 0); +} \ No newline at end of file diff --git a/dist/assets/examples/en/05_Image/07_EdgeDetection.js b/dist/assets/examples/en/05_Image/07_EdgeDetection.js new file mode 100644 index 0000000000..5a8fb552ae --- /dev/null +++ b/dist/assets/examples/en/05_Image/07_EdgeDetection.js @@ -0,0 +1,94 @@ +/* + * @name Edge Detection + * @arialabel Astronaut rendered in black and white on the left and a highly sharpened version of the image on the right + * @description A high-pass filter sharpens an image. This program analyzes every pixel in an image in relation to the neighboring pixels to sharpen the image. + *

This example is ported from the Edge Detection example + * on the Processing website + */ +// this program analyzes every pixel in an image +// in relation to the neighbouring pixels +// to sharpen the image + +// to consider all neighboring pixels we use a 3x3 array +// and normalize these values +// kernel is the 3x3 matrix of normalized values +let kernel = [[-1, -1, -1 ], [ -1, 9, -1 ], [-1, -1, -1 ]]; + +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// if loadImage() is called in setup(), the image won't appear +// since noLoop() restricts draw() to execute only once +// (one execution of draw() is not enough time for the image to load), +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover.png"); +} + +// setup() runs after preload, once() +function setup() { + // create canvas + createCanvas(710, 400); + // noLoop() makes draw() run only once, not in a loop + noLoop(); +} + +// draw() runs after setup(), normally on a loop +// in this case it runs only once, because of noDraw() +function draw() { + + // place the original image on the upper left corner + image(img, 0, 0); + + // create a new image, same dimensions as img + edgeImg = createImage(img.width, img.height); + + // load its pixels + edgeImg.loadPixels(); + + + // two for() loops, to iterate in x axis and y axis + // since the kernel assumes that the pixel + // has pixels above, under, left, and right + // we need to skip the first and last column and row + // x then goes from 1 to width - 1 + // y then goes from 1 to height - 1 + + for (let x = 1; x < img.width - 1; x++) { + for (let y = 1; y < img.height - 1; y++) { + // kernel sum for the current pixel starts as 0 + let sum = 0; + + // kx, ky variables for iterating over the kernel + // kx, ky have three different values: -1, 0, 1 + for (kx = -1; kx <= 1; kx++) { + for (ky = -1; ky <= 1; ky++) { + + let xpos = x + kx; + let ypos = y + ky; + let pos = (y + ky)*img.width + (x + kx); + // since our image is grayscale, + // RGB values are identical + // we retrieve the red value for this example + let val = red(img.get(xpos, ypos)); + // accumulate the kernel sum + // kernel is a 3x3 matrix + // kx and ky have values -1, 0, 1 + // if we add 1 to kx and ky, we get 0, 1, 2 + // with that we can use it to iterate over kernel + // and calculate the accumulated sum + sum += kernel[ky+1][kx+1] * val; + } + } + + // set the pixel value of the edgeImg + edgeImg.set(x, y, color(sum, sum, sum)); + } + } + + // updatePixels() to write the changes on edgeImg + edgeImg.updatePixels(); + + // draw edgeImg at the right of the original image + image(edgeImg, img.width, 0); +} \ No newline at end of file diff --git a/dist/assets/examples/en/05_Image/08_Brightness.js b/dist/assets/examples/en/05_Image/08_Brightness.js new file mode 100644 index 0000000000..c3f5e66f28 --- /dev/null +++ b/dist/assets/examples/en/05_Image/08_Brightness.js @@ -0,0 +1,64 @@ +/* + * @name Brightness + * @arialabel Astronaut rendered in black and white is covered with a black screen. The user’s mouse acts as a flashlight and parts of the image are illuminated as the user’s mouse travels over + * @description This program adjusts the brightness of a part of the image by calculating the distance of each pixel to the mouse. + *

This example is ported from the Brightness example + * on the Processing website + */ +// This program adjusts the brightness +// of a part of the image by +// calculating the distance of +// each pixel to the mouse. +let img; +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover_wide.jpg"); +} +// setup() runs after preload, once() +function setup() { + createCanvas(710, 400); + pixelDensity(1); + frameRate(30); +} + +function draw() { + image(img,0,0); + // Only need to load the pixels[] array once, because we're only + // manipulating pixels[] inside draw(), not drawing shapes. + loadPixels(); + // We must also call loadPixels() on the PImage since we are going to read its pixels. + img.loadPixels(); + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++ ) { + // Calculate the 1D location from a 2D grid + let loc = (x + y*img.width)*4; + // Get the R,G,B values from image + let r,g,b; + r = img.pixels[loc]; + // g = img.pixels[loc+1]; + // b = img.pixels[loc+2]; + // Calculate an amount to change brightness based on proximity to the mouse + // The closer the pixel is to the mouse, the lower the value of "distance" + let maxdist = 50;//dist(0,0,width,height); + let d = dist(x, y, mouseX, mouseY); + let adjustbrightness = 255*(maxdist-d)/maxdist; + r += adjustbrightness; + // g += adjustbrightness; + // b += adjustbrightness; + // Constrain RGB to make sure they are within 0-255 color range + r = constrain(r, 0, 255); + // g = constrain(g, 0, 255); + // b = constrain(b, 0, 255); + // Make a new color and set pixel in the window + let pixloc = (y*width + x)*4; + pixels[pixloc] = r; + pixels[pixloc+1] = r; + pixels[pixloc+2] = r; + pixels[pixloc+3] = 255; // Always have to set alpha + } + } + updatePixels(); +} \ No newline at end of file diff --git a/dist/assets/examples/en/05_Image/09_Convolution.js b/dist/assets/examples/en/05_Image/09_Convolution.js new file mode 100644 index 0000000000..4b9af4343d --- /dev/null +++ b/dist/assets/examples/en/05_Image/09_Convolution.js @@ -0,0 +1,92 @@ +/* + * @name Convolution + * @arialabel An astronaut on a planet. As the user’s mouse moves, a square section increasing the sharpness of the image also moves + * @description Applies a convolution matrix to a portion of an image. Move mouse to apply filter to different parts of the image. This example is a port of Dan Shiffman's example for Processing. Original comments written by Dan unless otherwise specified. + *

To run this example locally, you will need an + * image file, and a running + * local server.

+ */ + +let img; +let w = 80; + +// It's possible to convolve the image with many different +// matrices to produce different effects. This is a high-pass +// filter; it accentuates the edges. +const matrix = [ [ -1, -1, -1 ], + [ -1, 9, -1 ], + [ -1, -1, -1 ] ]; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 400); + img.loadPixels(); + + // pixelDensity(1) for not scaling pixel density to display density + // for more information, check the reference of pixelDensity() + pixelDensity(1); +} + +function draw() { + // We're only going to process a portion of the image + // so let's set the whole image as the background first + background(img); + + // Calculate the small rectangle we will process + const xstart = constrain(mouseX - w/2, 0, img.width); + const ystart = constrain(mouseY - w/2, 0, img.height); + const xend = constrain(mouseX + w/2, 0, img.width); + const yend = constrain(mouseY + w/2, 0, img.height); + const matrixsize = 3; + + loadPixels(); + // Begin our loop for every pixel in the smaller image + for (let x = xstart; x < xend; x++) { + for (let y = ystart; y < yend; y++ ) { + let c = convolution(x, y, matrix, matrixsize, img); + + // retrieve the RGBA values from c and update pixels() + let loc = (x + y*img.width) * 4; + pixels[loc] = red(c); + pixels[loc + 1] = green(c); + pixels[loc + 2] = blue(c); + pixels[loc + 3] = alpha(c); + } + } + updatePixels(); +} + +function convolution(x, y, matrix, matrixsize, img) { + let rtotal = 0.0; + let gtotal = 0.0; + let btotal = 0.0; + const offset = Math.floor(matrixsize / 2); + for (let i = 0; i < matrixsize; i++){ + for (let j = 0; j < matrixsize; j++){ + + // What pixel are we testing + const xloc = (x + i - offset); + const yloc = (y + j - offset); + let loc = (xloc + img.width * yloc) * 4; + + // Make sure we haven't walked off our image, we could do better here + loc = constrain(loc, 0 , img.pixels.length - 1); + + // Calculate the convolution + // retrieve RGB values + rtotal += (img.pixels[loc]) * matrix[i][j]; + gtotal += (img.pixels[loc + 1]) * matrix[i][j]; + btotal += (img.pixels[loc + 2]) * matrix[i][j]; + } + } + // Make sure RGB is within range + rtotal = constrain(rtotal, 0, 255); + gtotal = constrain(gtotal, 0, 255); + btotal = constrain(btotal, 0, 255); + + // Return the resulting color + return color(rtotal, gtotal, btotal); +} \ No newline at end of file diff --git a/dist/assets/examples/en/05_Image/10_Copy_Method.js b/dist/assets/examples/en/05_Image/10_Copy_Method.js new file mode 100644 index 0000000000..eb9966e40e --- /dev/null +++ b/dist/assets/examples/en/05_Image/10_Copy_Method.js @@ -0,0 +1,21 @@ +/* + * @name Copy() method + * @arialabel Parrot rendered in black and white. The user’s cursor is a paint brush and as the user presses and holds on the image, the area becomes colored + * @frame 600,400 + * @description An example of how to simulate coloring image with the copy() method. + */ +let draft, ready; +function preload() { + ready = loadImage("assets/parrot-color.png"); + draft = loadImage("assets/parrot-bw.png"); +} +function setup() { + createCanvas(600, 400); + noCursor(); + cursor("assets/brush.png", 20, -10); + image(ready, 0, 0); + image(draft, 0, 0); +} +function mouseDragged() { + copy(ready, mouseX, mouseY, 20, 20, mouseX, mouseY, 20, 20); +} diff --git a/dist/assets/examples/en/07_Color/00_Hue.js b/dist/assets/examples/en/07_Color/00_Hue.js new file mode 100644 index 0000000000..7ea8fc1cbc --- /dev/null +++ b/dist/assets/examples/en/07_Color/00_Hue.js @@ -0,0 +1,26 @@ +/* + * @name Hue + * @arialabel Vertical bars of color appear in a gradient pattern as the user drags their mouse across the screen + * @description Hue is the color reflected from or transmitted through an + * object and is typically referred to as the name of the color (red, blue, + * yellow, etc.) Move the cursor vertically over each bar to alter its hue. + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, height, height, height); + noStroke(); + background(0); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(mouseY, height, height); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/en/07_Color/01_Saturation.js b/dist/assets/examples/en/07_Color/01_Saturation.js new file mode 100644 index 0000000000..27ff14d3f8 --- /dev/null +++ b/dist/assets/examples/en/07_Color/01_Saturation.js @@ -0,0 +1,26 @@ +/* + * @name Saturation + * @arialabel Vertical bars of color appear in a gradient rainbow pattern as the user drags their mouse across the screen. The saturation of these bars change as the user’s mouse drags through + * @description Saturation is the strength or purity of the color and + * represents the amount of gray in proportion to the hue. A "saturated" + * color is pure and an "unsaturated" color has a large percentage of gray. + * Move the cursor vertically over each bar to alter its saturation. + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, width, height, 100); + noStroke(); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(barX, mouseY, 66); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/en/07_Color/02_Brightness.js b/dist/assets/examples/en/07_Color/02_Brightness.js new file mode 100644 index 0000000000..e94eb2cd2e --- /dev/null +++ b/dist/assets/examples/en/07_Color/02_Brightness.js @@ -0,0 +1,47 @@ +/* + * @name Brightness + * @arialabel A black and white photograph of an astronaut on the moon covered by black. The mouse acts as a light and a circular area of the photograph is illuminated where the mouse hovers + * @description By Dan Shiffman. This program adjusts the brightness of a part + * of the image by calculating the distance of each pixel to the mouse. + *

To run this example locally, you will need + * at least an image file and a running local server.

+ */ +let img; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 200); + pixelDensity(1); + img.loadPixels(); + loadPixels(); +} + +function draw() { + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + // Calculate the 1D location from a 2D grid + let loc = (x + y * img.width) * 4; + // Get the R,G,B values from image + let r, g, b; + r = img.pixels[loc]; + // Calculate an amount to change brightness based on proximity to the mouse + let maxdist = 50; + let d = dist(x, y, mouseX, mouseY); + let adjustbrightness = (255 * (maxdist - d)) / maxdist; + r += adjustbrightness; + // Constrain RGB to make sure they are within 0-255 color range + r = constrain(r, 0, 255); + // Make a new color and set pixel in the window + //color c = color(r, g, b); + let pixloc = (y * width + x) * 4; + pixels[pixloc] = r; + pixels[pixloc + 1] = r; + pixels[pixloc + 2] = r; + pixels[pixloc + 3] = 255; + } + } + updatePixels(); +} diff --git a/dist/assets/examples/en/07_Color/03_Color_Variables.js b/dist/assets/examples/en/07_Color/03_Color_Variables.js new file mode 100644 index 0000000000..5c211264dc --- /dev/null +++ b/dist/assets/examples/en/07_Color/03_Color_Variables.js @@ -0,0 +1,41 @@ +/* + * @name Color Variables + * @arialabel Two squares on a brown background. Both squares are made up of two squares in a larger square. On the left, the outer square is burnt umber, the middle square is golden, and the center square is orange. On the right, the outer square is orange, the middle is burnt umber, and the middle is golden + * @description (Homage to Albers.) This example creates variables for colors + * that may be referred to in the program by a name, rather than a number. + */ +function setup() { + createCanvas(710, 400); + noStroke(); + background(51, 0, 0); + + let inside = color(204, 102, 0); + let middle = color(204, 153, 0); + let outside = color(153, 51, 0); + + // These statements are equivalent to the statements above. + // Programmers may use the format they prefer. + //let inside = color('#CC6600'); + //let middle = color('#CC9900'); + //let outside = color('#993300'); + + push(); + translate(80, 80); + fill(outside); + rect(0, 0, 200, 200); + fill(middle); + rect(40, 60, 120, 120); + fill(inside); + rect(60, 90, 80, 80); + pop(); + + push(); + translate(360, 80); + fill(inside); + rect(0, 0, 200, 200); + fill(outside); + rect(40, 60, 120, 120); + fill(middle); + rect(60, 90, 80, 80); + pop(); +} diff --git a/dist/assets/examples/en/07_Color/04_Relativity.js b/dist/assets/examples/en/07_Color/04_Relativity.js new file mode 100644 index 0000000000..ebeaa83a33 --- /dev/null +++ b/dist/assets/examples/en/07_Color/04_Relativity.js @@ -0,0 +1,35 @@ +/* + * @name Relativity + * @arialabel 4 vertical stripes in grey, blue, green, and orange. They are displayed in a different order on the top half of the screen compared to the bottom half and this causes the colors to be perceived differently + * @description Each color is perceived in relation to other colors. The top + * and bottom bars each contain the same component colors, but a different + * display order causes individual colors to appear differently. + */ +let a, b, c, d, e; + +function setup() { + createCanvas(710, 400); + noStroke(); + a = color(165, 167, 20); + b = color(77, 86, 59); + c = color(42, 106, 105); + d = color(165, 89, 20); + e = color(146, 150, 127); + noLoop(); // Draw only one time +} + +function draw() { + drawBand(a, b, c, d, e, 0, width / 128); + drawBand(c, a, d, b, e, height / 2, width / 128); +} + +function drawBand(v, w, x, y, z, ypos, barWidth) { + let num = 5; + let colorOrder = [v, w, x, y, z]; + for (let i = 0; i < width; i += barWidth * num) { + for (let j = 0; j < num; j++) { + fill(colorOrder[j]); + rect(i + j * barWidth, ypos, barWidth, height / 2); + } + } +} diff --git a/dist/assets/examples/en/07_Color/05_Linear_Gradient.js b/dist/assets/examples/en/07_Color/05_Linear_Gradient.js new file mode 100644 index 0000000000..6e1b589d04 --- /dev/null +++ b/dist/assets/examples/en/07_Color/05_Linear_Gradient.js @@ -0,0 +1,53 @@ +/* + * @name Linear Gradient + * @arialabel The background is white on the left and right sides and gradients to a black at the center. There are two long rectangles on the background gradient. The top rectangle has orange on the top of the rectangle and gradients to blue on the bottom. The bottom rectangle starts with blue on the left side and gradients to orange on the right + * @description The lerpColor() function is useful for interpolating between + * two colors. + */ +// Constants +const Y_AXIS = 1; +const X_AXIS = 2; +let b1, b2, c1, c2; + +function setup() { + createCanvas(710, 400); + + // Define colors + b1 = color(255); + b2 = color(0); + c1 = color(204, 102, 0); + c2 = color(0, 102, 153); + + noLoop(); +} + +function draw() { + // Background + setGradient(0, 0, width / 2, height, b1, b2, X_AXIS); + setGradient(width / 2, 0, width / 2, height, b2, b1, X_AXIS); + // Foreground + setGradient(50, 90, 540, 80, c1, c2, Y_AXIS); + setGradient(50, 190, 540, 80, c2, c1, X_AXIS); +} + +function setGradient(x, y, w, h, c1, c2, axis) { + noFill(); + + if (axis === Y_AXIS) { + // Top to bottom gradient + for (let i = y; i <= y + h; i++) { + let inter = map(i, y, y + h, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(x, i, x + w, i); + } + } else if (axis === X_AXIS) { + // Left to right gradient + for (let i = x; i <= x + w; i++) { + let inter = map(i, x, x + w, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(i, y, i, y + h); + } + } +} diff --git a/dist/assets/examples/en/07_Color/06_Radial_Gradient.js b/dist/assets/examples/en/07_Color/06_Radial_Gradient.js new file mode 100644 index 0000000000..0882cb7ccb --- /dev/null +++ b/dist/assets/examples/en/07_Color/06_Radial_Gradient.js @@ -0,0 +1,34 @@ +/* + * @name Radial Gradient + * @arialabel Three circles on a black background. The middle circle is completely visible but the user can only see half of the other two. There is a gradiant from the center of the circle to the outer edge that changes every second + * @description Draws a series of concentric circles to create a gradient + * from one color to another. + */ +let dim; + +function setup() { + createCanvas(710, 400); + dim = width / 2; + background(0); + colorMode(HSB, 360, 100, 100); + noStroke(); + ellipseMode(RADIUS); + frameRate(1); +} + +function draw() { + background(0); + for (let x = 0; x <= width; x += dim) { + drawGradient(x, height / 2); + } +} + +function drawGradient(x, y) { + let radius = dim / 2; + let h = random(0, 360); + for (let r = radius; r > 0; --r) { + fill(h, 90, 90); + ellipse(x, y, r, r); + h = (h + 1) % 360; + } +} diff --git a/dist/assets/examples/en/07_Color/07_Lerp_Color.js b/dist/assets/examples/en/07_Color/07_Lerp_Color.js new file mode 100644 index 0000000000..6bdf1d46eb --- /dev/null +++ b/dist/assets/examples/en/07_Color/07_Lerp_Color.js @@ -0,0 +1,50 @@ +/* + * @name Lerp Color + * @arialabel Four piles of triangles in random sizes: red, maroon, purple, and blue. The triangles move around within their pile to form different designs + * @description Loop random shapes, + * lerp color from red to blue. + */ +function setup() { + createCanvas(720, 400); + background(255); + noStroke(); +} + +function draw() { + background(255); + from = color(255, 0, 0, 0.2 * 255); + to = color(0, 0, 255, 0.2 * 255); + c1 = lerpColor(from, to, 0.33); + c2 = lerpColor(from, to, 0.66); + for (let i = 0; i < 15; i++) { + fill(from); + quad( + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height) + ); + fill(c1); + quad( + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height) + ); + fill(c2); + quad( + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height) + ); + fill(to); + quad( + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height) + ); + } + frameRate(5); +} diff --git a/dist/assets/examples/en/08_Math/00_incrementdecrement.js b/dist/assets/examples/en/08_Math/00_incrementdecrement.js new file mode 100644 index 0000000000..082922a048 --- /dev/null +++ b/dist/assets/examples/en/08_Math/00_incrementdecrement.js @@ -0,0 +1,43 @@ +/* + * @name Increment Decrement + * @arialabel Two black gradient rectangles on the bottom right and top left of the screen travel horizontally to the other side and leave a gradient grey path behind + * @description Writing "a++" is equivalent to "a = a + 1". + * Writing "a--" is equivalent to "a = a - 1". + */ +let a; +let b; +let direction; + +function setup() { + createCanvas(710, 400); + colorMode(RGB, width); + a = 0; + b = width; + direction = true; + frameRate(30); +} + +function draw() { + a++; + if (a > width) { + a = 0; + direction = !direction; + } + if (direction === true) { + stroke(a); + } else { + stroke(width - a); + } + line(a, 0, a, height / 2); + + b--; + if (b < 0) { + b = width; + } + if (direction == true) { + stroke(width - b); + } else { + stroke(b); + } + line(b, height / 2 + 1, b, height); +} diff --git a/dist/assets/examples/en/08_Math/01_operatorprecedence.js b/dist/assets/examples/en/08_Math/01_operatorprecedence.js new file mode 100644 index 0000000000..c42516635f --- /dev/null +++ b/dist/assets/examples/en/08_Math/01_operatorprecedence.js @@ -0,0 +1,55 @@ +/* + * @name Operator Precedence + * @arialabel Grey background with two rectangles outlined in white on the left, and white vertical lines on the top and bottom + * @description If you don't explicitly state the order in which an + * expression is evaluated, they are evaluated based on the operator + * precedence. For example, in the statement "4+2*8", the 2 will + * first be multiplied by 8 and then the result will be added to 4. + * This is because the "*" has a higher precedence than the "+". To avoid + * ambiguity in reading the program, it is recommended that is statement + * is written as "4+(2*8)". The order of evaluation can be controlled + * through placement of parenthesis in the code. A table of operator + * precedence follows below. + */ +// The highest precedence is at the top of the list and +// the lowest is at the bottom. +// Multiplicative: * / % +// Additive: + - +// Relational: < > <= >= +// Equality: == != +// Logical AND: && +// Logical OR: || +// Assignment: = += -= *= /= %= +function setup() { + createCanvas(710, 400); + background(51); + noFill(); + stroke(51); + + stroke(204); + for (let i = 0; i < width - 20; i += 4) { + // The 30 is added to 70 and then evaluated + // if it is greater than the current value of "i" + // For clarity, write as "if (i > (30 + 70)) {" + if (i > 30 + 70) { + line(i, 0, i, 50); + } + } + + stroke(255); + // The 2 is multiplied by the 8 and the result is added to the 4 + // For clarity, write as "rect(5 + (2 * 8), 0, 90, 20);" + rect(4 + 2 * 8, 52, 290, 48); + rect((4 + 2) * 8, 100, 290, 49); + + stroke(153); + for (let i = 0; i < width; i += 2) { + // The relational statements are evaluated + // first, and then the logical AND statements and + // finally the logical OR. For clarity, write as: + // "if(((i > 20) && (i < 50)) || ((i > 100) && (i < width-20))) {" + if ((i > 20 && i < 50) || (i > 100 && i < width - 20)) { + line(i, 151, i, height - 1); + } + } +} diff --git a/dist/assets/examples/en/08_Math/02_distance1d.js b/dist/assets/examples/en/08_Math/02_distance1d.js new file mode 100644 index 0000000000..0238a94c36 --- /dev/null +++ b/dist/assets/examples/en/08_Math/02_distance1d.js @@ -0,0 +1,66 @@ +/* + * @name Distance 1D + * @arialabel One thin grey bar and wider grey bar travel on the top half of the screen, and another set of these two bars travel on the bottom half. The bars change speed and direction as the user’s mouse moves across the screen + * @description Move the mouse left and right to control + * the speed and direction of the moving shapes. + */ +let xpos1; +let xpos2; +let xpos3; +let xpos4; +let thin = 8; +let thick = 36; + +function setup() { + createCanvas(710, 400); + noStroke(); + xpos1 = width / 2; + xpos2 = width / 2; + xpos3 = width / 2; + xpos4 = width / 2; +} + +function draw() { + background(0); + + let mx = mouseX * 0.4 - width / 5.0; + + fill(102); + rect(xpos2, 0, thick, height / 2); + fill(204); + rect(xpos1, 0, thin, height / 2); + fill(102); + rect(xpos4, height / 2, thick, height / 2); + fill(204); + rect(xpos3, height / 2, thin, height / 2); + + xpos1 += mx / 16; + xpos2 += mx / 64; + xpos3 -= mx / 16; + xpos4 -= mx / 64; + + if (xpos1 < -thin) { + xpos1 = width; + } + if (xpos1 > width) { + xpos1 = -thin; + } + if (xpos2 < -thick) { + xpos2 = width; + } + if (xpos2 > width) { + xpos2 = -thick; + } + if (xpos3 < -thin) { + xpos3 = width; + } + if (xpos3 > width) { + xpos3 = -thin; + } + if (xpos4 < -thick) { + xpos4 = width; + } + if (xpos4 > width) { + xpos4 = -thick; + } +} diff --git a/dist/assets/examples/en/08_Math/03_distance2d.js b/dist/assets/examples/en/08_Math/03_distance2d.js new file mode 100644 index 0000000000..951edbd803 --- /dev/null +++ b/dist/assets/examples/en/08_Math/03_distance2d.js @@ -0,0 +1,26 @@ +/* + * @name Distance 2D + * @arialabel The user’s mouse creates a gradient of circles that decrease in size the closer they are to the mouse as it moves across the screen + * @description Move the mouse across the image to obscure + * and reveal the matrix. Measures the distance from the mouse + * to each circle and sets the size proportionally. + */ +let max_distance; + +function setup() { + createCanvas(710, 400); + noStroke(); + max_distance = dist(0, 0, width, height); +} + +function draw() { + background(0); + + for (let i = 0; i <= width; i += 20) { + for (let j = 0; j <= height; j += 20) { + let size = dist(mouseX, mouseY, i, j); + size = (size / max_distance) * 66; + ellipse(i, j, size, size); + } + } +} diff --git a/dist/assets/examples/en/08_Math/04_sine.js b/dist/assets/examples/en/08_Math/04_sine.js new file mode 100644 index 0000000000..3e8a4733d8 --- /dev/null +++ b/dist/assets/examples/en/08_Math/04_sine.js @@ -0,0 +1,28 @@ +/* + * @name Sine + * @arialabel Three yellow circles grow larger and smaller on a black background + * @description Smoothly scaling size with the sin() function. + */ +let diameter; +let angle = 0; + +function setup() { + createCanvas(710, 400); + diameter = height - 10; + noStroke(); + fill(255, 204, 0); +} + +function draw() { + background(0); + + let d1 = 10 + (sin(angle) * diameter) / 2 + diameter / 2; + let d2 = 10 + (sin(angle + PI / 2) * diameter) / 2 + diameter / 2; + let d3 = 10 + (sin(angle + PI) * diameter) / 2 + diameter / 2; + + ellipse(0, height / 2, d1, d1); + ellipse(width / 2, height / 2, d2, d2); + ellipse(width, height / 2, d3, d3); + + angle += 0.02; +} diff --git a/dist/assets/examples/en/08_Math/05_sincosine.js b/dist/assets/examples/en/08_Math/05_sincosine.js new file mode 100644 index 0000000000..9577d762d8 --- /dev/null +++ b/dist/assets/examples/en/08_Math/05_sincosine.js @@ -0,0 +1,44 @@ +/* + * @name Sine Cosine + * @arialabel Two blue and two yellow circles move side to side on each side of a white square + * @description Linear movement with sin() and cos(). + * Numbers between 0 and 2π (2π which angles roughly 6.28) + * are put into these functions and numbers between -1 and 1 are returned. + * These values are then scaled to produce larger movements. + */ +let angle1 = 0; +let angle2 = 0; +let scalar = 70; + +function setup() { + createCanvas(710, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(0); + + let ang1 = radians(angle1); + let ang2 = radians(angle2); + + let x1 = width / 2 + scalar * cos(ang1); + let x2 = width / 2 + scalar * cos(ang2); + + let y1 = height / 2 + scalar * sin(ang1); + let y2 = height / 2 + scalar * sin(ang2); + + fill(255); + rect(width * 0.5, height * 0.5, 140, 140); + + fill(0, 102, 153); + ellipse(x1, height * 0.5 - 120, scalar, scalar); + ellipse(x2, height * 0.5 + 120, scalar, scalar); + + fill(255, 204, 0); + ellipse(width * 0.5 - 120, y1, scalar, scalar); + ellipse(width * 0.5 + 120, y2, scalar, scalar); + + angle1 += 2; + angle2 += 3; +} diff --git a/dist/assets/examples/en/08_Math/06_sinewave.js b/dist/assets/examples/en/08_Math/06_sinewave.js new file mode 100644 index 0000000000..728c16284f --- /dev/null +++ b/dist/assets/examples/en/08_Math/06_sinewave.js @@ -0,0 +1,49 @@ +/* + * @name Sine Wave + * @arialabel White circles line up to form a sine wave that moves across the black screen + * @description Render a simple sine wave. + * Original by Daniel Shiffman. + */ + +let xspacing = 16; // Distance between each horizontal location +let w; // Width of entire wave +let theta = 0.0; // Start angle at 0 +let amplitude = 75.0; // Height of wave +let period = 500.0; // How many pixels before the wave repeats +let dx; // Value for incrementing x +let yvalues; // Using an array to store height values for the wave + +function setup() { + createCanvas(710, 400); + w = width + 16; + dx = (TWO_PI / period) * xspacing; + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // Increment theta (try different values for + // 'angular velocity' here) + theta += 0.02; + + // For every x value, calculate a y value with sine function + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = sin(x) * amplitude; + x += dx; + } +} + +function renderWave() { + noStroke(); + fill(255); + // A simple way to draw the wave with an ellipse at each location + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, height / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/en/08_Math/07_additivewave.js b/dist/assets/examples/en/08_Math/07_additivewave.js new file mode 100644 index 0000000000..0ab818066e --- /dev/null +++ b/dist/assets/examples/en/08_Math/07_additivewave.js @@ -0,0 +1,71 @@ +/* + * @name Additive Wave + * @arialabel Slightly opaque white circles line up to form waves that moves ross the black screen + * @description Create a more complex wave by adding two waves together. + * Original by Daniel Shiffman + */ +let xspacing = 8; // Distance between each horizontal location +let w; // Width of entire wave +let maxwaves = 4; // total # of waves to add together + +let theta = 0.0; +let amplitude = new Array(maxwaves); // Height of wave +// Value for incrementing X, to be calculated +// as a function of period and xspacing +let dx = new Array(maxwaves); +// Using an array to store height values +// for the wave (not entirely necessary) +let yvalues; + +function setup() { + createCanvas(710, 400); + frameRate(30); + colorMode(RGB, 255, 255, 255, 100); + w = width + 16; + + for (let i = 0; i < maxwaves; i++) { + amplitude[i] = random(10, 30); + let period = random(100, 300); // Num pixels before wave repeats + dx[i] = (TWO_PI / period) * xspacing; + } + + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // Increment theta (try different values + // for 'angular velocity' here + theta += 0.02; + + // Set all height values to zero + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = 0; + } + + // Accumulate wave height values + for (let j = 0; j < maxwaves; j++) { + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + // Every other wave is cosine instead of sine + if (j % 2 == 0) yvalues[i] += sin(x) * amplitude[j]; + else yvalues[i] += cos(x) * amplitude[j]; + x += dx[j]; + } + } +} + +function renderWave() { + // A simple way to draw the wave with an ellipse at each location + noStroke(); + fill(255, 50); + ellipseMode(CENTER); + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, width / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/en/08_Math/08_polartocartesian.js b/dist/assets/examples/en/08_Math/08_polartocartesian.js new file mode 100644 index 0000000000..6c2dff4b81 --- /dev/null +++ b/dist/assets/examples/en/08_Math/08_polartocartesian.js @@ -0,0 +1,45 @@ +/* + * @name PolarToCartesian + * @arialabel Grey circle travels faster and faster in a circle path on a black background + * @description Convert a polar coordinate (r,θ) + * to cartesian (x,y): x = r cos(θ), y = r sin(θ) + * Original by Daniel Shiffman. + */ +let r; + +// Angle and angular velocity, accleration +let theta; +let theta_vel; +let theta_acc; + +function setup() { + createCanvas(710, 400); + + // Initialize all values + r = height * 0.45; + theta = 0; + theta_vel = 0; + theta_acc = 0.0001; +} + +function draw() { + background(0); + + // Translate the origin point to the center of the screen + translate(width / 2, height / 2); + + // Convert polar to cartesian + let x = r * cos(theta); + let y = r * sin(theta); + + // Draw the ellipse at the cartesian coordinate + ellipseMode(CENTER); + noStroke(); + fill(200); + ellipse(x, y, 32, 32); + + // Apply acceleration and velocity to angle + // (r remains static in this example) + theta_vel += theta_acc; + theta += theta_vel; +} diff --git a/dist/assets/examples/en/08_Math/09_arctangent.js b/dist/assets/examples/en/08_Math/09_arctangent.js new file mode 100644 index 0000000000..83a135efe9 --- /dev/null +++ b/dist/assets/examples/en/08_Math/09_arctangent.js @@ -0,0 +1,46 @@ +/* + * @name Arctangent + * @arialabel Three white circles have smaller green circles within them resembling eyes where the pupil, represented by the green circle, looks in the direction of where the user’s mouse is + * @description Move the mouse to change the direction of the eyes.
The atan2() function computes the angle from each eye to the cursor. + */ +let e1, e2, e3; + +function setup() { + createCanvas(720, 400); + noStroke(); + e1 = new Eye(250, 16, 120); + e2 = new Eye(164, 185, 80); + e3 = new Eye(420, 230, 220); +} + +function draw() { + background(102); + e1.update(mouseX, mouseY); + e2.update(mouseX, mouseY); + e3.update(mouseX, mouseY); + e1.display(); + e2.display(); + e3.display(); +} + +function Eye(tx, ty, ts) { + this.x = tx; + this.y = ty; + this.size = ts; + this.angle = 0; + + this.update = function(mx, my) { + this.angle = atan2(my - this.y, mx - this.x); + }; + + this.display = function() { + push(); + translate(this.x, this.y); + fill(255); + ellipse(0, 0, this.size, this.size); + rotate(this.angle); + fill(153, 204, 0); + ellipse(this.size / 4, 0, this.size / 2, this.size / 2); + pop(); + }; +} diff --git a/dist/assets/examples/en/08_Math/10_Interpolate.js b/dist/assets/examples/en/08_Math/10_Interpolate.js new file mode 100644 index 0000000000..e6b1c5c55b --- /dev/null +++ b/dist/assets/examples/en/08_Math/10_Interpolate.js @@ -0,0 +1,35 @@ +/* + * @name Linear Interpolation + * @arialabel White circle follows the user’s mouse around the screen + * @frame 720, 400 + * @description Move the mouse across the screen and the symbol will follow. + * Between drawing each frame of the animation, the ellipse moves part + * of the distance (0.05) from its current position toward the cursor using + * the lerp() function. + * This is the same as the Easing under input only with lerp() instead.. + */ + +let x = 0; +let y = 0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(51); + + // lerp() calculates a number between two numbers at a specific increment. + // The amt parameter is the amount to interpolate between the two values + // where 0.0 equal to the first point, 0.1 is very near the first point, 0.5 + // is half-way in between, etc. + + // Here we are moving 5% of the way to the mouse location each frame + x = lerp(x, mouseX, 0.05); + y = lerp(y, mouseY, 0.05); + + fill(255); + stroke(255); + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/en/08_Math/11_doubleRandom.js b/dist/assets/examples/en/08_Math/11_doubleRandom.js new file mode 100644 index 0000000000..946d268673 --- /dev/null +++ b/dist/assets/examples/en/08_Math/11_doubleRandom.js @@ -0,0 +1,25 @@ +/* + * @name Double Random + * @arialabel Little white dots clump around the horizontal axis on the middle of the screen and change positions every second between being more condensed and scattered + * @frame 720,400 (optional) + * @description Using two random() calls and the point() + * function to create an irregular sawtooth line. + * Original by by Ira Greenberg. + */ +let totalPts = 300; +let steps = totalPts + 1; + +function setup() { + createCanvas(710, 400); + stroke(255); + frameRate(1); +} + +function draw() { + background(0); + let rand = 0; + for (let i = 1; i < steps; i++) { + point((width / steps) * i, height / 2 + random(-rand, rand)); + rand += random(-5, 5); + } +} diff --git a/dist/assets/examples/en/08_Math/12_random.js b/dist/assets/examples/en/08_Math/12_random.js new file mode 100644 index 0000000000..0d150abf10 --- /dev/null +++ b/dist/assets/examples/en/08_Math/12_random.js @@ -0,0 +1,20 @@ +/* + * @name Random + * @arialabel Various shades of grey bars change patterns randomly every half a second + * @description Random numbers create the basis of this image. + * Each time the program is loaded the result is different. + */ +function setup() { + createCanvas(710, 400); + background(0); + strokeWeight(20); + frameRate(2); +} + +function draw() { + for (let i = 0; i < width; i++) { + let r = random(255); + stroke(r); + line(i, 0, i, height); + } +} diff --git a/dist/assets/examples/en/08_Math/13_noise1D.js b/dist/assets/examples/en/08_Math/13_noise1D.js new file mode 100644 index 0000000000..12d20b9a6b --- /dev/null +++ b/dist/assets/examples/en/08_Math/13_noise1D.js @@ -0,0 +1,32 @@ +/* + * @name Noise1D + * @arialabel White circle travels side to side based on perlin noise + * @description Using 1D Perlin Noise to assign location. + */ +let xoff = 0.0; +let xincrement = 0.01; + +function setup() { + createCanvas(710, 400); + background(0); + noStroke(); +} + +function draw() { + // Create an alpha blended background + fill(0, 10); + rect(0, 0, width, height); + + //let n = random(0,width); // Try this line instead of noise + + // Get a noise value based on xoff and scale + // it according to the window's width + let n = noise(xoff) * width; + + // With each cycle, increment xoff + xoff += xincrement; + + // Draw the ellipse at the value produced by perlin noise + fill(200); + ellipse(n, height / 2, 64, 64); +} diff --git a/dist/assets/examples/en/08_Math/14_noisewave.js b/dist/assets/examples/en/08_Math/14_noisewave.js new file mode 100644 index 0000000000..b953310739 --- /dev/null +++ b/dist/assets/examples/en/08_Math/14_noisewave.js @@ -0,0 +1,43 @@ +/* + * @name Noise Wave + * @arialabel Wave shapes are generated by perlin noise + * @description Using Perlin Noise to generate a wave-like pattern. + * Original by Daniel Shiffman. + */ +let yoff = 0.0; // 2nd dimension of perlin noise + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(51); + + fill(255); + // We are going to draw a polygon out of the wave points + beginShape(); + + let xoff = 0; // Option #1: 2D Noise + // let xoff = yoff; // Option #2: 1D Noise + + // Iterate over horizontal pixels + for (let x = 0; x <= width; x += 10) { + // Calculate a y value according to noise, map to + + // Option #1: 2D Noise + let y = map(noise(xoff, yoff), 0, 1, 200, 300); + + // Option #2: 1D Noise + // let y = map(noise(xoff), 0, 1, 200,300); + + // Set the vertex + vertex(x, y); + // Increment x dimension for noise + xoff += 0.05; + } + // increment y dimension for noise + yoff += 0.01; + vertex(width, height); + vertex(0, height); + endShape(CLOSE); +} diff --git a/dist/assets/examples/en/08_Math/15_Noise2D.js b/dist/assets/examples/en/08_Math/15_Noise2D.js new file mode 100644 index 0000000000..be75543d2b --- /dev/null +++ b/dist/assets/examples/en/08_Math/15_Noise2D.js @@ -0,0 +1,43 @@ +/* + * @name Noise2D + * @arialabel Two gradient, perlin noises, one on the left and one on the right + * @frame 710,400 (optional) + * @description Create a 2D noise with different parameters. + * + */ + +let noiseVal; +let noiseScale = 0.02; + +function setup() { + createCanvas(640, 360); +} + +function draw() { + background(0); + // Draw the left half of image + for (let y = 0; y < height - 30; y++) { + for (let x = 0; x < width / 2; x++) { + // noiseDetail of the pixels octave count and falloff value + noiseDetail(2, 0.2); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + // Draw the right half of image + for (let y = 0; y < height - 30; y++) { + for (let x = width / 2; x < width; x++) { + // noiseDetail of the pixels octave count and falloff value + noiseDetail(5, 0.5); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + //Show the details of two partitions + textSize(18); + fill(255, 255, 255); + text('Noise2D with 2 octaves and 0.2 falloff', 10, 350); + text('Noise2D with 1 octaves and 0.7 falloff', 330, 350); +} diff --git a/dist/assets/examples/en/08_Math/16_Noise3D.js b/dist/assets/examples/en/08_Math/16_Noise3D.js new file mode 100644 index 0000000000..82ccbe67ea --- /dev/null +++ b/dist/assets/examples/en/08_Math/16_Noise3D.js @@ -0,0 +1,49 @@ +/* + * @name Noise3D + * @arialabel Gradient noise + * @frame 710,400 (optional) + * @description Using 3D noise to create simple animated texture. + */ + +let noiseVal; +//Increment x by 0.01 +let x_increment = 0.01; +//Increment z by 0.02 every draw() cycle +let z_increment = 0.02; + +//Offset values +let z_off, y_off, x_off; + +function setup() { + //Create the Canvas + createCanvas(640, 360); + //Define frame rate + frameRate(20); + //Initial value of z_off + z_off = 0; +} + +function draw() { + x_off = 0; + y_off = 0; + //Make the background black + background(0); + //Adjust the noice detail + noiseDetail(8, 0.65); + + //For each x,y calculate noice value + for (let y = 0; y < height; y++) { + x_off += x_increment; + y_off = 0; + + for (let x = 0; x < width; x++) { + //Calculate and Draw each pixel + noiseVal = noise(x_off, y_off, z_off); + stroke(noiseVal * 255); + y_off += x_increment; + point(x, y); + } + } + + z_off += z_increment; +} diff --git a/dist/assets/examples/en/08_Math/17_Randomchords.js b/dist/assets/examples/en/08_Math/17_Randomchords.js new file mode 100644 index 0000000000..94c3de0a1d --- /dev/null +++ b/dist/assets/examples/en/08_Math/17_Randomchords.js @@ -0,0 +1,36 @@ +/* + * @name Random Chords + * @arialabel Random lines are drawn from one side of a circle to the other until it looks like a shaded sphere + * @description Accumulates random chords of a circle. Each chord in translucent + * so they accumulate to give the illusion of a shaded sphere. + * Contributed by Aatish Bhatia, inspired by Anders Hoff + */ + +function setup() { + createCanvas(400, 400); + background(255, 255, 255); + + // translucent stroke using alpha value + stroke(0, 0, 0, 15); +} + +function draw() { + // draw two random chords each frame + randomChord(); + randomChord(); +} + +function randomChord() { + // find a random point on a circle + let angle1 = random(0, 2 * PI); + let xpos1 = 200 + 200 * cos(angle1); + let ypos1 = 200 + 200 * sin(angle1); + + // find another random point on the circle + let angle2 = random(0, 2 * PI); + let xpos2 = 200 + 200 * cos(angle2); + let ypos2 = 200 + 200 * sin(angle2); + + // draw a line between them + line(xpos1, ypos1, xpos2, ypos2); +} diff --git a/dist/assets/examples/en/08_Math/18_randomGaussian.js b/dist/assets/examples/en/08_Math/18_randomGaussian.js new file mode 100644 index 0000000000..144450623c --- /dev/null +++ b/dist/assets/examples/en/08_Math/18_randomGaussian.js @@ -0,0 +1,27 @@ +/* + * @name Random Gaussian + * @arialabel Translucent white circles are drawn in a line left and right multiple times until they overlap to form a white streak + * @frame 720,400 + * @description This sketch draws ellipses with x and y locations tied to a gaussian distribution of random numbers. + * (ported from https://processing.org/examples/randomgaussian.html) + */ + + function setup() { + createCanvas(720, 400); + background(0); + } + + function draw() { + + // Get a gaussian random number w/ mean of 0 and standard deviation of 1.0 + let val = randomGaussian(); + + let sd = 60; // Define a standard deviation + let mean = width/2; // Define a mean value (middle of the screen along the x-axis) + let x = ( val * sd ) + mean; // Scale the gaussian random number by standard deviation and mean + + noStroke(); + fill(255, 10); + ellipse(x, height/2, 32, 32); // Draw an ellipse at our "normal" random location + } + diff --git a/dist/assets/examples/en/08_Math/19_Map.js b/dist/assets/examples/en/08_Math/19_Map.js new file mode 100644 index 0000000000..feeed43c2a --- /dev/null +++ b/dist/assets/examples/en/08_Math/19_Map.js @@ -0,0 +1,23 @@ +/* + * @name Map + * @arialabel Red circle grows larger and turns more yellow as the user’s mouse moves right on the screen and does the opposite as the user’s mouse moves left + * @description Use the map() function to take any number and scale it to a + * new number that is more useful for the project that you are working on. + * For example, use the numbers from the mouse position to control the size or color of a shape. + * In this example, the mouse’s x-coordinate (numbers between 0 and 360) are scaled to new numbers + * to define the color and size of a circle. + */ +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(0); + // Scale the mouseX value from 0 to 720 to a range between 0 and 175 + let c = map(mouseX, 0, width, 0, 175); + // Scale the mouseX value from 0 to 720 to a range between 40 and 300 + let d = map(mouseX, 0, width, 40, 300); + fill(255, c, 0); + ellipse(width/2, height/2, d, d); +} diff --git a/dist/assets/examples/en/08_Math/20_Graphing2DEquations.js b/dist/assets/examples/en/08_Math/20_Graphing2DEquations.js new file mode 100644 index 0000000000..1e22963abd --- /dev/null +++ b/dist/assets/examples/en/08_Math/20_Graphing2DEquations.js @@ -0,0 +1,53 @@ +/** + * @name Graphing 2D Equations + * @arialabel Rays in a black and white pattern swirl together as the user’s mouse moves right and unswirl as the user’s mouse moves left + * @frame 710, 400 + * @description Graphics the following equation: sin(n cos(r) + 5θ) where n is a function of horizontal mouse location. Original by Daniel Shiffman + */ +function setup() { + createCanvas(710, 400); + pixelDensity(1); +} + +function draw() { + loadPixels(); + let n = (mouseX * 10.0) / width; + const w = 16.0; // 2D space width + const h = 16.0; // 2D space height + const dx = w / width; // Increment x this amount per pixel + const dy = h / height; // Increment y this amount per pixel + let x = -w / 2; // Start x at -1 * width / 2 + let y; + + let r; + let theta; + let val; + + let bw; //variable to store grayscale + let i; + let j; + let cols = width; + let rows = height; + + for (i = 0; i < cols; i += 1) { + y = -h / 2; + for (j = 0; j < rows; j += 1) { + r = sqrt(x * x + y * y); // Convert cartesian to polar + theta = atan2(y, x); // Convert cartesian to polar + // Compute 2D polar coordinate function + val = sin(n * cos(r) + 5 * theta); // Results in a value between -1 and 1 + //var val = cos(r); // Another simple function + //var val = sin(theta); // Another simple function + bw = color(((val + 1) * 255) / 2); + index = 4 * (i + j * width); + pixels[index] = red(bw); + pixels[index + 1] = green(bw); + pixels[index + 2] = blue(bw); + pixels[index + 3] = alpha(bw); + + y += dy; + } + x += dx; + } + updatePixels(); +} diff --git a/dist/assets/examples/en/08_Math/21_parametricEquation.js b/dist/assets/examples/en/08_Math/21_parametricEquation.js new file mode 100644 index 0000000000..d52dbfdc0a --- /dev/null +++ b/dist/assets/examples/en/08_Math/21_parametricEquation.js @@ -0,0 +1,45 @@ +/* + * @name Parametric Equations + * @arialabel Black vertical lines travel in a spiral pattern in a 3D space + * @description A parametric equation is where x and y + * coordinates are both written in terms of another letter. This is + * called a parameter and is usually given in the letter t or θ. + * The inspiration was taken from the YouTube channel of Alexander Miller. + */ + +function setup(){ + createCanvas(720,400); +} + +// the parameter at which x and y depends is usually taken as either t or symbol of theta +let t = 0; +function draw(){ + background('#fff'); + translate(width/2,height/2); + stroke('#0f0f0f'); + strokeWeight(1.5); + //loop for adding 100 lines + for(let i = 0;i<100;i++){ + line(x1(t+i),y1(t+i),x2(t+i)+20,y2(t+i)+20); + } + t+=0.15; +} +// function to change initial x co-ordinate of the line +function x1(t){ + return sin(t/10)*125+sin(t/20)*125+sin(t/30)*125; +} + +// function to change initial y co-ordinate of the line +function y1(t){ + return cos(t/10)*125+cos(t/20)*125+cos(t/30)*125; +} + +// function to change final x co-ordinate of the line +function x2(t){ + return sin(t/15)*125+sin(t/25)*125+sin(t/35)*125; +} + +// function to change final y co-ordinate of the line +function y2(t){ + return cos(t/15)*125+cos(t/25)*125+cos(t/35)*125; +} \ No newline at end of file diff --git a/dist/assets/examples/en/09_Simulate/00_Forces.js b/dist/assets/examples/en/09_Simulate/00_Forces.js new file mode 100644 index 0000000000..224dbdaf27 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/00_Forces.js @@ -0,0 +1,149 @@ +/* + * @name Forces + * @arialabel 9 grey balls drop from the top of the window and slow down as they reach the bottom half of the screen which is dark grey in color. Their change in speed mimics objects slowing down due to water resistance + * @description Demonstration of multiple force acting on bodies + * (natureofcode.com) + */ +// Demonstration of multiple force acting on +// bodies (Mover class) +// Bodies experience gravity continuously +// Bodies experience fluid resistance when in "water" + +// Five moving bodies +let movers = []; + +// Liquid +let liquid; + +function setup() { + createCanvas(640, 360); + reset(); + // Create liquid object + liquid = new Liquid(0, height / 2, width, height / 2, 0.1); +} + +function draw() { + background(127); + + // Draw water + liquid.display(); + + for (let i = 0; i < movers.length; i++) { + + // Is the Mover in the liquid? + if (liquid.contains(movers[i])) { + // Calculate drag force + let dragForce = liquid.calculateDrag(movers[i]); + // Apply drag force to Mover + movers[i].applyForce(dragForce); + } + + // Gravity is scaled by mass here! + let gravity = createVector(0, 0.1 * movers[i].mass); + // Apply gravity + movers[i].applyForce(gravity); + + // Update and display + movers[i].update(); + movers[i].display(); + movers[i].checkEdges(); + } + +} + + +function mousePressed() { + reset(); +} + +// Restart all the Mover objects randomly +function reset() { + for (let i = 0; i < 9; i++) { + movers[i] = new Mover(random(0.5, 3), 40 + i * 70, 0); + } +} + +let Liquid = function(x, y, w, h, c) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + this.c = c; +}; + +// Is the Mover in the Liquid? +Liquid.prototype.contains = function(m) { + let l = m.position; + return l.x > this.x && l.x < this.x + this.w && + l.y > this.y && l.y < this.y + this.h; +}; + +// Calculate drag force +Liquid.prototype.calculateDrag = function(m) { + // Magnitude is coefficient * speed squared + let speed = m.velocity.mag(); + let dragMagnitude = this.c * speed * speed; + + // Direction is inverse of velocity + let dragForce = m.velocity.copy(); + dragForce.mult(-1); + + // Scale according to magnitude + // dragForce.setMag(dragMagnitude); + dragForce.normalize(); + dragForce.mult(dragMagnitude); + return dragForce; +}; + +Liquid.prototype.display = function() { + noStroke(); + fill(50); + rect(this.x, this.y, this.w, this.h); +}; + +function Mover(m, x, y) { + this.mass = m; + this.position = createVector(x, y); + this.velocity = createVector(0, 0); + this.acceleration = createVector(0, 0); +} + +// Newton's 2nd law: F = M * A +// or A = F / M +Mover.prototype.applyForce = function(force) { + let f = p5.Vector.div(force, this.mass); + this.acceleration.add(f); +}; + +Mover.prototype.update = function() { + // Velocity changes according to acceleration + this.velocity.add(this.acceleration); + // position changes by velocity + this.position.add(this.velocity); + // We must clear acceleration each frame + this.acceleration.mult(0); +}; + +Mover.prototype.display = function() { + stroke(0); + strokeWeight(2); + fill(255,127); + ellipse(this.position.x, this.position.y, this.mass * 16, this.mass * 16); +}; + +// Bounce off bottom of window +Mover.prototype.checkEdges = function() { + if (this.position.y > (height - this.mass * 8)) { + // A little dampening when hitting the bottom + this.velocity.y *= -0.9; + this.position.y = (height - this.mass * 8); + } +}; + + + + + + + + diff --git a/dist/assets/examples/en/09_Simulate/01_ParticleSystem.js b/dist/assets/examples/en/09_Simulate/01_ParticleSystem.js new file mode 100644 index 0000000000..6cfe27a74a --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/01_ParticleSystem.js @@ -0,0 +1,70 @@ +/* + * @name Particle System + * @arialabel Light grey circles flowing out from a point like a sparkler + * @description This is a basic Particle System + * (natureofcode.com) + */ +let system; + +function setup() { + createCanvas(720, 400); + system = new ParticleSystem(createVector(width / 2, 50)); +} + +function draw() { + background(51); + system.addParticle(); + system.run(); +} + +// A simple Particle class +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// Method to update position +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// Method to display +Particle.prototype.display = function() { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// Is the particle still useful? +Particle.prototype.isDead = function(){ + return this.lifespan < 0; +}; + +let ParticleSystem = function(position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin)); +}; + +ParticleSystem.prototype.run = function() { + for (let i = this.particles.length-1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; diff --git a/dist/assets/examples/en/09_Simulate/02_Flocking.js b/dist/assets/examples/en/09_Simulate/02_Flocking.js new file mode 100644 index 0000000000..832b1d60f4 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/02_Flocking.js @@ -0,0 +1,230 @@ +/* + * @name Flocking + * @arialabel Groups of little grey triangles moving across a darker grey background + * @description Demonstration of Craig Reynolds' "Flocking" behavior. + * See: http://www.red3d.com/cwr/ + * Rules: Cohesion, Separation, Alignment + * (from natureofcode.com). + * Drag mouse to add boids into the system. + */ + + +let flock; + +function setup() { + createCanvas(640, 360); + createP("Drag the mouse to generate new boids."); + + flock = new Flock(); + // Add an initial set of boids into the system + for (let i = 0; i < 100; i++) { + let b = new Boid(width / 2,height / 2); + flock.addBoid(b); + } +} + +function draw() { + background(51); + flock.run(); +} + +// Add a new boid into the System +function mouseDragged() { + flock.addBoid(new Boid(mouseX, mouseY)); +} + +// The Nature of Code +// Daniel Shiffman +// http://natureofcode.com + +// Flock object +// Does very little, simply manages the array of all the boids + +function Flock() { + // An array for all the boids + this.boids = []; // Initialize the array +} + +Flock.prototype.run = function() { + for (let i = 0; i < this.boids.length; i++) { + this.boids[i].run(this.boids); // Passing the entire list of boids to each boid individually + } +} + +Flock.prototype.addBoid = function(b) { + this.boids.push(b); +} + +// The Nature of Code +// Daniel Shiffman +// http://natureofcode.com + +// Boid class +// Methods for Separation, Cohesion, Alignment added + +function Boid(x, y) { + this.acceleration = createVector(0, 0); + this.velocity = createVector(random(-1, 1), random(-1, 1)); + this.position = createVector(x, y); + this.r = 3.0; + this.maxspeed = 3; // Maximum speed + this.maxforce = 0.05; // Maximum steering force +} + +Boid.prototype.run = function(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); +} + +Boid.prototype.applyForce = function(force) { + // We could add mass here if we want A = F / M + this.acceleration.add(force); +} + +// We accumulate a new acceleration each time based on three rules +Boid.prototype.flock = function(boids) { + let sep = this.separate(boids); // Separation + let ali = this.align(boids); // Alignment + let coh = this.cohesion(boids); // Cohesion + // Arbitrarily weight these forces + sep.mult(1.5); + ali.mult(1.0); + coh.mult(1.0); + // Add the force vectors to acceleration + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); +} + +// Method to update location +Boid.prototype.update = function() { + // Update velocity + this.velocity.add(this.acceleration); + // Limit speed + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // Reset accelertion to 0 each cycle + this.acceleration.mult(0); +} + +// A method that calculates and applies a steering force towards a target +// STEER = DESIRED MINUS VELOCITY +Boid.prototype.seek = function(target) { + let desired = p5.Vector.sub(target,this.position); // A vector pointing from the location to the target + // Normalize desired and scale to maximum speed + desired.normalize(); + desired.mult(this.maxspeed); + // Steering = Desired minus Velocity + let steer = p5.Vector.sub(desired,this.velocity); + steer.limit(this.maxforce); // Limit to maximum steering force + return steer; +} + +Boid.prototype.render = function() { + // Draw a triangle rotated in the direction of velocity + let theta = this.velocity.heading() + radians(90); + fill(127); + stroke(200); + push(); + translate(this.position.x, this.position.y); + rotate(theta); + beginShape(); + vertex(0, -this.r * 2); + vertex(-this.r, this.r * 2); + vertex(this.r, this.r * 2); + endShape(CLOSE); + pop(); +} + +// Wraparound +Boid.prototype.borders = function() { + if (this.position.x < -this.r) this.position.x = width + this.r; + if (this.position.y < -this.r) this.position.y = height + this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height + this.r) this.position.y = -this.r; +} + +// Separation +// Method checks for nearby boids and steers away +Boid.prototype.separate = function(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // For every boid in the system, check if it's too close + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) + if ((d > 0) && (d < desiredseparation)) { + // Calculate vector pointing away from neighbor + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // Weight by distance + steer.add(diff); + count++; // Keep track of how many + } + } + // Average -- divide by how many + if (count > 0) { + steer.div(count); + } + + // As long as the vector is greater than 0 + if (steer.mag() > 0) { + // Implement Reynolds: Steering = Desired - Velocity + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; +} + +// Alignment +// For every nearby boid in the system, calculate the average velocity +Boid.prototype.align = function(boids) { + let neighbordist = 50; + let sum = createVector(0,0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } +} + +// Cohesion +// For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location +Boid.prototype.cohesion = function(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // Start with empty vector to accumulate all locations + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // Add location + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // Steer towards the location + } else { + return createVector(0, 0); + } +} + + diff --git a/dist/assets/examples/en/09_Simulate/03_WolframCA.js b/dist/assets/examples/en/09_Simulate/03_WolframCA.js new file mode 100644 index 0000000000..15f5030d4e --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/03_WolframCA.js @@ -0,0 +1,74 @@ +/* + * @name Wolfram CA + * @arialabel 1-dimensional cellular automata is depicted which is a pyramid shape with a design consisting of white squares that create a pixelated look + * @description Simple demonstration of a Wolfram 1-dimensional cellular automata + * (natureofcode.com) + */ + +let w = 10; +// An array of 0s and 1s +let cells; + + // We arbitrarily start with just the middle cell having a state of "1" +let generation = 0; + +// An array to store the ruleset, for example {0,1,1,0,1,1,0,1} +let ruleset = [0, 1, 0, 1, 1, 0, 1, 0]; + +function setup() { + createCanvas(640, 400); + cells = Array(floor(width / w)); + for (let i = 0; i < cells.length; i++) { + cells[i] = 0; + } + cells[cells.length/2] = 1; + +} + +function draw() { + for (let i = 0; i < cells.length; i++) { + if (cells[i] === 1) { + fill(200); + } else { + fill(51); + noStroke(); + rect(i * w, generation * w, w, w); + } + } + if (generation < height/w) { + generate(); + } +} + +// The process of creating the new generation +function generate() { + // First we create an empty array for the new values + let nextgen = Array(cells.length); + // For every spot, determine new state by examing current state, and neighbor states + // Ignore edges that only have one neighor + for (let i = 1; i < cells.length-1; i++) { + let left = cells[i-1]; // Left neighbor state + let me = cells[i]; // Current state + let right = cells[i+1]; // Right neighbor state + nextgen[i] = rules(left, me, right); // Compute next generation state based on ruleset + } + // The current generation is the new generation + cells = nextgen; + generation++; +} + + +// Implementing the Wolfram rules +// Could be improved and made more concise, but here we can explicitly see what is going on for each case +function rules(a, b, c) { + if (a == 1 && b == 1 && c == 1) return ruleset[0]; + if (a == 1 && b == 1 && c == 0) return ruleset[1]; + if (a == 1 && b == 0 && c == 1) return ruleset[2]; + if (a == 1 && b == 0 && c == 0) return ruleset[3]; + if (a == 0 && b == 1 && c == 1) return ruleset[4]; + if (a == 0 && b == 1 && c == 0) return ruleset[5]; + if (a == 0 && b == 0 && c == 1) return ruleset[6]; + if (a == 0 && b == 0 && c == 0) return ruleset[7]; + return 0; +} + diff --git a/dist/assets/examples/en/09_Simulate/04_GameOfLife.js b/dist/assets/examples/en/09_Simulate/04_GameOfLife.js new file mode 100644 index 0000000000..166a4a18c1 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/04_GameOfLife.js @@ -0,0 +1,95 @@ +/* + * @name Game of Life + * @arialabel Grid of white squares on a black background with some squares flickering between white and black to generate random patterns + * @description A basic implementation of John Conway's Game of Life CA + * (natureofcode.com) + */ + +let w; +let columns; +let rows; +let board; +let next; + +function setup() { + createCanvas(720, 400); + w = 20; + // Calculate columns and rows + columns = floor(width / w); + rows = floor(height / w); + // Wacky way to make a 2D array is JS + board = new Array(columns); + for (let i = 0; i < columns; i++) { + board[i] = new Array(rows); + } + // Going to use multiple 2D arrays and swap them + next = new Array(columns); + for (i = 0; i < columns; i++) { + next[i] = new Array(rows); + } + init(); +} + +function draw() { + background(255); + generate(); + for ( let i = 0; i < columns;i++) { + for ( let j = 0; j < rows;j++) { + if ((board[i][j] == 1)) fill(0); + else fill(255); + stroke(0); + rect(i * w, j * w, w-1, w-1); + } + } + +} + +// reset board when mouse is pressed +function mousePressed() { + init(); +} + +// Fill board randomly +function init() { + for (let i = 0; i < columns; i++) { + for (let j = 0; j < rows; j++) { + // Lining the edges with 0s + if (i == 0 || j == 0 || i == columns-1 || j == rows-1) board[i][j] = 0; + // Filling the rest randomly + else board[i][j] = floor(random(2)); + next[i][j] = 0; + } + } +} + +// The process of creating the new generation +function generate() { + + // Loop through every spot in our 2D array and check spots neighbors + for (let x = 1; x < columns - 1; x++) { + for (let y = 1; y < rows - 1; y++) { + // Add up all the states in a 3x3 surrounding grid + let neighbors = 0; + for (let i = -1; i <= 1; i++) { + for (let j = -1; j <= 1; j++) { + neighbors += board[x+i][y+j]; + } + } + + // A little trick to subtract the current cell's state since + // we added it in the above loop + neighbors -= board[x][y]; + // Rules of Life + if ((board[x][y] == 1) && (neighbors < 2)) next[x][y] = 0; // Loneliness + else if ((board[x][y] == 1) && (neighbors > 3)) next[x][y] = 0; // Overpopulation + else if ((board[x][y] == 0) && (neighbors == 3)) next[x][y] = 1; // Reproduction + else next[x][y] = board[x][y]; // Stasis + } + } + + // Swap! + let temp = board; + board = next; + next = temp; +} + diff --git a/dist/assets/examples/en/09_Simulate/05_MultipleParticleSystems.js b/dist/assets/examples/en/09_Simulate/05_MultipleParticleSystems.js new file mode 100644 index 0000000000..9a84cf67dd --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/05_MultipleParticleSystems.js @@ -0,0 +1,139 @@ +/* + * @name Multiple Particle Systems + * @arialabel When the user clicks anywhere on the black background, a particle system begins where light grey circles flow out from the point like a sparkler + * @description Click the mouse to generate a burst of particles at mouse location.
Each burst is one instance of a particle system with Particles and CrazyParticles (a subclass of Particle).
Note use of Inheritance and Polymorphism here.
+ * Original by Daniel Shiffman. + */ +let systems; + +function setup() { + createCanvas(710, 400); + systems = []; +} + +function draw() { + background(51); + background(0); + for (i = 0; i < systems.length; i++) { + systems[i].run(); + systems[i].addParticle(); + } + if (systems.length == 0) { + fill(255); + textAlign(CENTER); + textSize(32); + text("click mouse to add particle systems", width / 2, height / 2); + } +} + +function mousePressed() { + this.p = new ParticleSystem(createVector(mouseX, mouseY)); + systems.push(p); +} + +// A simple Particle class +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255.0; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// Method to update position +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// Method to display +Particle.prototype.display = function () { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// Is the particle still useful? +Particle.prototype.isDead = function () { + if (this.lifespan < 0) { + return true; + } else { + return false; + } +}; + +let ParticleSystem = function (position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function () { + // Add either a Particle or CrazyParticle to the system + if (int(random(0, 2)) == 0) { + p = new Particle(this.origin); + } + else { + p = new CrazyParticle(this.origin); + } + this.particles.push(p); +}; + +ParticleSystem.prototype.run = function () { + for (let i = this.particles.length - 1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; + +// A subclass of Particle + +function CrazyParticle(origin) { + // Call the parent constructor, making sure (using Function#call) + // that "this" is set correctly during the call + Particle.call(this, origin); + + // Initialize our added properties + this.theta = 0.0; +}; + +// Create a Crazy.prototype object that inherits from Particle.prototype. +// Note: A common error here is to use "new Particle()" to create the +// Crazy.prototype. That's incorrect for several reasons, not least +// that we don't have anything to give Particle for the "origin" +// argument. The correct place to call Particle is above, where we call +// it from Crazy. +CrazyParticle.prototype = Object.create(Particle.prototype); // See note below + +// Set the "constructor" property to refer to CrazyParticle +CrazyParticle.prototype.constructor = CrazyParticle; + +// Notice we don't have the method run() here; it is inherited from Particle + +// This update() method overrides the parent class update() method +CrazyParticle.prototype.update=function() { + Particle.prototype.update.call(this); + // Increment rotation based on horizontal velocity + this.theta += (this.velocity.x * this.velocity.mag()) / 10.0; +} + +// This display() method overrides the parent class display() method +CrazyParticle.prototype.display=function() { + // Render the ellipse just like in a regular particle + Particle.prototype.display.call(this); + // Then add a rotating line + push(); + translate(this.position.x, this.position.y); + rotate(this.theta); + stroke(255, this.lifespan); + line(0, 0, 25, 0); + pop(); +} diff --git a/dist/assets/examples/en/09_Simulate/06_Spirograph.js b/dist/assets/examples/en/09_Simulate/06_Spirograph.js new file mode 100644 index 0000000000..4d503a631a --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/06_Spirograph.js @@ -0,0 +1,74 @@ + +/* + * @name Spirograph + * @arialabel A spirograph is created by interlocking black circle outlines rotating around each other on a grey background. When the user clicks the space bar, the background turns white and paths of circles of various sizes in an indigo color are visible + * @description This sketch uses simple transformations to create a + * Spirograph-like effect with interlocking circles (called sines). + * Press the spacebar to switch between tracing and showing the underlying geometry.
+ * Example created by R. Luke DuBois.
+ * http://en.wikipedia.org/wiki/Spirograph + */ +let NUMSINES = 20; // how many of these things can we do at once? +let sines = new Array(NUMSINES); // an array to hold all the current angles +let rad; // an initial radius value for the central sine +let i; // a counter variable + +// play with these to get a sense of what's going on: +let fund = 0.005; // the speed of the central sine +let ratio = 1; // what multiplier for speed is each additional sine? +let alpha = 50; // how opaque is the tracing system + +let trace = false; // are we tracing? + +function setup() { + createCanvas(710, 400); + + rad = height / 4; // compute radius for central circle + background(204); // clear the screen + + for (let i = 0; i + * Example created by R. Luke DuBois.
+ * https://en.wikipedia.org/wiki/L-system + */ +// TURTLE STUFF: +let x, y; // the current position of the turtle +let currentangle = 0; // which way the turtle is pointing +let step = 20; // how much the turtle moves with each 'F' +let angle = 90; // how much the turtle turns with a '-' or '+' + +// LINDENMAYER STUFF (L-SYSTEMS) +let thestring = 'A'; // "axiom" or start of the string +let numloops = 5; // how many iterations to pre-compute +let therules = []; // array for rules +therules[0] = ['A', '-BF+AFA+FB-']; // first rule +therules[1] = ['B', '+AF-BFB-FA+']; // second rule + +let whereinstring = 0; // where in the L-system are we? + +function setup() { + createCanvas(710, 400); + background(255); + stroke(0, 0, 0, 255); + + // start the x and y position at lower-left corner + x = 0; + y = height-1; + + // COMPUTE THE L-SYSTEM + for (let i = 0; i < numloops; i++) { + thestring = lindenmayer(thestring); + } +} + +function draw() { + + // draw the current character in the string: + drawIt(thestring[whereinstring]); + + // increment the point for where we're reading the string. + // wrap around at the end. + whereinstring++; + if (whereinstring > thestring.length-1) whereinstring = 0; + +} + +// interpret an L-system +function lindenmayer(s) { + let outputstring = ''; // start a blank output string + + // iterate through 'therules' looking for symbol matches: + for (let i = 0; i < s.length; i++) { + let ismatch = 0; // by default, no match + for (let j = 0; j < therules.length; j++) { + if (s[i] == therules[j][0]) { + outputstring += therules[j][1]; // write substitution + ismatch = 1; // we have a match, so don't copy over symbol + break; // get outta this for() loop + } + } + // if nothing matches, just copy the symbol over. + if (ismatch == 0) outputstring+= s[i]; + } + + return outputstring; // send out the modified string +} + +// this is a custom function that draws turtle commands +function drawIt(k) { + + if (k=='F') { // draw forward + // polar to cartesian based on step and currentangle: + let x1 = x + step*cos(radians(currentangle)); + let y1 = y + step*sin(radians(currentangle)); + line(x, y, x1, y1); // connect the old and the new + + // update the turtle's position: + x = x1; + y = y1; + } else if (k == '+') { + currentangle += angle; // turn left + } else if (k == '-') { + currentangle -= angle; // turn right + } + + // give me some random color values: + let r = random(128, 255); + let g = random(0, 192); + let b = random(0, 50); + let a = random(50, 100); + + // pick a gaussian (D&D) distribution for the radius: + let radius = 0; + radius += random(0, 15); + radius += random(0, 15); + radius += random(0, 15); + radius = radius / 3; + + // draw the stuff: + fill(r, g, b, a); + ellipse(x, y, radius, radius); +} \ No newline at end of file diff --git a/dist/assets/examples/en/09_Simulate/08_Spring.js b/dist/assets/examples/en/09_Simulate/08_Spring.js new file mode 100644 index 0000000000..e3d363a32a --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/08_Spring.js @@ -0,0 +1,93 @@ +/* + * @name Spring + * @arialabel Light grey horizontal rectangle on a black vertical rectangle on a grey background. The user can move the horizontal rectangle up and down. Upon releasing the horizontal rectangle, the system moves like a spring and the vertical rectangle expands and compresses as the horizontal rectangle moves up and down. + * @frame 710, 400 + * @description Click, drag, and release the horizontal bar to start the spring. + */ +// Spring drawing constants for top bar +let springHeight = 32, + left, + right, + maxHeight = 200, + minHeight = 100, + over = false, + move = false; + +// Spring simulation constants +let M = 0.8, // Mass + K = 0.2, // Spring constant + D = 0.92, // Damping + R = 150; // Rest position + +// Spring simulation variables +let ps = R, // Position + vs = 0.0, // Velocity + as = 0, // Acceleration + f = 0; // Force + +function setup() { + createCanvas(710, 400); + rectMode(CORNERS); + noStroke(); + left = width / 2 - 100; + right = width / 2 + 100; +} + +function draw() { + background(102); + updateSpring(); + drawSpring(); +} + +function drawSpring() { + // Draw base + fill(0.2); + let baseWidth = 0.5 * ps + -8; + rect(width / 2 - baseWidth, ps + springHeight, width / 2 + baseWidth, height); + + // Set color and draw top bar + if (over || move) { + fill(255); + } else { + fill(204); + } + + rect(left, ps, right, ps + springHeight); +} + +function updateSpring() { + // Update the spring position + if ( !move ) { + f = -K * ( ps - R ); // f=-ky + as = f / M; // Set the acceleration, f=ma == a=f/m + vs = D * (vs + as); // Set the velocity + ps = ps + vs; // Updated position + } + + if (abs(vs) < 0.1) { + vs = 0.0; + } + + // Test if mouse if over the top bar + if (mouseX > left && mouseX < right && mouseY > ps && mouseY < ps + springHeight) { + over = true; + } else { + over = false; + } + + // Set and constrain the position of top bar + if (move) { + ps = mouseY - springHeight / 2; + ps = constrain(ps, minHeight, maxHeight); + } +} + +function mousePressed() { + if (over) { + move = true; + } +} + +function mouseReleased() { + move = false; +} diff --git a/dist/assets/examples/en/09_Simulate/09_Springs.js b/dist/assets/examples/en/09_Simulate/09_Springs.js new file mode 100644 index 0000000000..17bb191922 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/09_Springs.js @@ -0,0 +1,148 @@ +/* + * @name Springs + * @arialabel Three white circles on a dark grey background. The user can drag each circle and the circle springs back and forth till finally settling in the original position + * @frame 710,400 + * @description Move the mouse over one of the circles and click to re-position. + * When you release the mouse, it will snap back into position. + * Each circle has a slightly different behavior. + * (ported from https://processing.org/examples/springs.html) + */ +let num = 3; +let springs = []; + +function setup() { + createCanvas(710, 400); + noStroke(); + + springs[0] = new Spring(240, 260, 40, 0.98, 8.0, 0.1, springs, 0); + springs[1] = new Spring(320, 210, 120, 0.95, 9.0, 0.1, springs, 1); + springs[2] = new Spring(180, 170, 200, 0.90, 9.9, 0.1, springs, 2); +} + +function draw() { + background(51); + + for (let i = 0; i < num; i++) { + springs[i].update(); + springs[i].display(); + } +} + +function mousePressed() { + for (let i = 0; i < num; i++) { + springs[i].pressed(); + } +} + +function mouseReleased() { + for (let i = 0; i < num; i++) { + springs[i].released(); + } +} + +// Spring class +function Spring (_x, _y, _s, _d, _m, _k_in, _others, _id) { + // Screen values + // this.xpos = _x; + // this.ypos = _y; + + this.x_pos = _x; + this.y_pos= _y; + + this.size = 20; + this.size = _s; + + this.over = false; + this.move = false; + + // Spring simulation constants + this.mass = _m; // Mass + this.k = 0.2; // Spring constant + this.k = _k_in; + this.damp = _d; // Damping + this.rest_posx = _x; // Rest position X + this.rest_posy = _y; // Rest position Y + + // Spring simulation variables + //float pos = 20.0; // Position + this.velx = 0.0; // X Velocity + this.vely = 0.0; // Y Velocity + this.accel = 0; // Acceleration + this.force = 0; // Force + + this.friends = _others; + this.id = _id; + + this.update = function() { + + if (this.move) { + this.rest_posy = mouseY; + this.rest_posx = mouseX; + } + + this.force = -this.k * (this.y_pos - this.rest_posy); // f=-ky + this.accel = this.force / this.mass; // Set the acceleration, f=ma == a=f/m + this.vely = this.damp * (this.vely + this.accel); // Set the velocity + this.y_pos = this.y_pos + this.vely; // Updated position + + + this.force = -this.k * (this.x_pos - this.rest_posx); // f=-ky + this.accel = this.force / this.mass; // Set the acceleration, f=ma == a=f/m + this.velx = this.damp * (this.velx + this.accel); // Set the velocity + this.x_pos = this.x_pos + this.velx; // Updated position + + + if ((this.overEvent() || this.move) && !(this.otherOver()) ) { + this.over = true; + } else { + this.over = false; + } + } + + // Test to see if mouse is over this spring + this.overEvent = function() { + let disX = this.x_pos - mouseX; + let disY = this.y_pos - mouseY; + let dis = createVector(disX, disY); + if (dis.mag() < this.size / 2 ) { + return true; + } else { + return false; + } + } + + // Make sure no other springs are active + this.otherOver = function() { + for (let i = 0; i < num; i++) { + if (i != this.id) { + if (this.friends[i].over == true) { + return true; + } + } + } + return false; + } + + this.display = function() { + if (this.over) { + fill(153); + } else { + fill(255); + } + ellipse(this.x_pos, this.y_pos, this.size, this.size); + } + + this.pressed = function() { + if (this.over) { + this.move = true; + } else { + this.move = false; + } + } + + this.released = function() { + this.move = false; + this.rest_posx = this.y_pos; + this.rest_posy = this.y_pos; + } +}; \ No newline at end of file diff --git a/dist/assets/examples/en/09_Simulate/10_SoftBody.js b/dist/assets/examples/en/09_Simulate/10_SoftBody.js new file mode 100644 index 0000000000..32a9d665e3 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/10_SoftBody.js @@ -0,0 +1,111 @@ +/* + * @name Soft Body + * @arialabel White pentagon on a black screen that morphs into a blob as it follows the user’s mouse + * @description Original example by Ira Greenberg. + *

Softbody dynamics simulation using curveVertex() and curveTightness(). + */ +// center point +let centerX = 0.0, centerY = 0.0; + +let radius = 45, rotAngle = -90; +let accelX = 0.0, accelY = 0.0; +let deltaX = 0.0, deltaY = 0.0; +let springing = 0.0009, damping = 0.98; + +//corner nodes +let nodes = 5; + +//zero fill arrays +let nodeStartX = []; +let nodeStartY = []; +let nodeX = []; +let nodeY = []; +let angle = []; +let frequency = []; + +// soft-body dynamics +let organicConstant = 1.0; + +function setup() { + createCanvas(710, 400); + + //center shape in window + centerX = width / 2; + centerY = height / 2; + + //initialize arrays to 0 + for (let i = 0; i < nodes; i++){ + nodeStartX[i] = 0; + nodeStartY[i] = 0; + nodeY[i] = 0; + nodeY[i] = 0; + angle[i] = 0; + } + + // iniitalize frequencies for corner nodes + for (let i = 0; i < nodes; i++){ + frequency[i] = random(5, 12); + } + + noStroke(); + frameRate(30); +} + +function draw() { + //fade background + fill(0, 100); + rect(0, 0, width, height); + drawShape(); + moveShape(); +} + +function drawShape() { + // calculate node starting locations + for (let i = 0; i < nodes; i++){ + nodeStartX[i] = centerX + cos(radians(rotAngle)) * radius; + nodeStartY[i] = centerY + sin(radians(rotAngle)) * radius; + rotAngle += 360.0 / nodes; + } + + // draw polygon + curveTightness(organicConstant); + fill(255); + beginShape(); + for (let i = 0; i < nodes; i++){ + curveVertex(nodeX[i], nodeY[i]); + } + for (let i = 0; i < nodes-1; i++){ + curveVertex(nodeX[i], nodeY[i]); + } + endShape(CLOSE); +} + +function moveShape() { + //move center point + deltaX = mouseX - centerX; + deltaY = mouseY - centerY; + + // create springing effect + deltaX *= springing; + deltaY *= springing; + accelX += deltaX; + accelY += deltaY; + + // move predator's center + centerX += accelX; + centerY += accelY; + + // slow down springing + accelX *= damping; + accelY *= damping; + + // change curve tightness + organicConstant = 1 - ((abs(accelX) + abs(accelY)) * 0.1); + + //move nodes + for (let i = 0; i < nodes; i++){ + nodeX[i] = nodeStartX[i] + sin(radians(angle[i])) * (accelX * 2); + nodeY[i] = nodeStartY[i] + sin(radians(angle[i])) * (accelY * 2); + angle[i] += frequency[i]; + } +} diff --git a/dist/assets/examples/en/09_Simulate/11_SmokeParticleSystem.js b/dist/assets/examples/en/09_Simulate/11_SmokeParticleSystem.js new file mode 100644 index 0000000000..e298313b34 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/11_SmokeParticleSystem.js @@ -0,0 +1,181 @@ +/* + * @name SmokeParticles + * @arialabel White circle gives off smoke on the middle of the bottom of the screen. The smoke blows in the direction of the user’s mouse as it moves side to side. There is a white arrow on the top that also points to the side where the user’s mouse is + * @description a port of Dan Shiffman's SmokeParticleSystem example originally + * for Processing. Creates smokey particles :p + */ + +// texture for the particle +let particle_texture = null; + +// variable holding our particle system +let ps = null; + +function preload() { + particle_texture = loadImage("assets/particle_texture.png"); +} + +function setup() { + + //set the canvas size + createCanvas(640, 360); + + //initialize our particle system + ps = new ParticleSystem(0, createVector(width / 2, height - 60), particle_texture); +} + +function draw() { + background(0); + + let dx = map(mouseX, 0, width, -0.2, 0.2); + let wind = createVector(dx, 0); + + ps.applyForce(wind); + ps.run(); + for (let i = 0; i < 2; i++) { + ps.addParticle(); + } + + // Draw an arrow representing the wind force + drawVector(wind, createVector(width / 2, 50, 0), 500); +} + +/** + * This function draws an arrow showing the direction our "wind" is blowing. + */ +function drawVector(v, loc, scale){ + push(); + let arrowsize = 4; + translate(loc.x, loc.y); + stroke(255); + rotate(v.heading()); + + let len = v.mag() * scale; + line(0, 0, len,0); + line(len, 0, len-arrowsize, +arrowsize / 2); + line(len, 0, len-arrowsize, -arrowsize / 2); + pop(); +} +//========= PARTICLE SYSTEM =========== + +/** + * A basic particle system class + * @param num the number of particles + * @param v the origin of the particle system + * @param img_ a texture for each particle in the system + * @constructor + */ +let ParticleSystem = function(num, v, img_) { + + this.particles = []; + this.origin = v.copy(); // we make sure to copy the vector value in case we accidentally mutate the original by accident + this.img = img_ + for(let i = 0; i < num; ++i){ + this.particles.push(new Particle(this.origin, this.img)); + } +}; + +/** + * This function runs the entire particle system. + */ +ParticleSystem.prototype.run = function() { + + // cache length of the array we're going to loop into a variable + // You may see .length in a for loop, from time to time but + // we cache it here because otherwise the length is re-calculated for each iteration of a loop + let len = this.particles.length; + + //loop through and run particles + for (let i = len - 1; i >= 0; i--) { + let particle = this.particles[i]; + particle.run(); + + // if the particle is dead, we remove it. + // javascript arrays don't have a "remove" function but "splice" works just as well. + // we feed it an index to start at, then how many numbers from that point to remove. + if (particle.isDead()) { + this.particles.splice(i, 1); + } + } +} + +/** + * Method to add a force vector to all particles currently in the system + * @param dir a p5.Vector describing the direction of the force. + */ +ParticleSystem.prototype.applyForce = function(dir) { + let len = this.particles.length; + for(let i = 0; i < len; ++i){ + this.particles[i].applyForce(dir); + } +} + +/** + * Adds a new particle to the system at the origin of the system and with + * the originally set texture. + */ +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin, this.img)); +} + +//========= PARTICLE =========== +/** + * A simple Particle class, renders the particle as an image + */ +let Particle = function (pos, img_) { + this.loc = pos.copy(); + + let vx = randomGaussian() * 0.3; + let vy = randomGaussian() * 0.3 - 1.0; + + this.vel = createVector(vx, vy); + this.acc = createVector(); + this.lifespan = 100.0; + this.texture = img_; +} + +/** + * Simulataneously updates and displays a particle. + */ +Particle.prototype.run = function() { + this.update(); + this.render(); +} + +/** + * A function to display a particle + */ +Particle.prototype.render = function() { + imageMode(CENTER); + tint(255, this.lifespan); + image(this.texture, this.loc.x, this.loc.y); +} + +/** + * A method to apply a force vector to a particle. + */ +Particle.prototype.applyForce = function(f) { + this.acc.add(f); +} + +/** + * This method checks to see if the particle has reached the end of it's lifespan, + * if it has, return true, otherwise return false. + */ +Particle.prototype.isDead = function () { + if (this.lifespan <= 0.0) { + return true; + } else { + return false; + } +} + +/** + * This method updates the position of the particle. + */ +Particle.prototype.update = function() { + this.vel.add(this.acc); + this.loc.add(this.vel); + this.lifespan -= 2.5; + this.acc.mult(0); +} diff --git a/dist/assets/examples/en/09_Simulate/12_BrownianMotion.js b/dist/assets/examples/en/09_Simulate/12_BrownianMotion.js new file mode 100644 index 0000000000..a9e0404a80 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/12_BrownianMotion.js @@ -0,0 +1,47 @@ +/* + * @name Brownian Motion + * @arialabel A continuous white line draws squiggles on a grey background + * @description Recording random movement as a continuous line. + * Port of original example from the Processing examples page. + */ + +let num = 2000; +let range = 6; + +let ax = []; +let ay = []; + + +function setup() { + createCanvas(710, 400); + for ( let i = 0; i < num; i++ ) { + ax[i] = width / 2; + ay[i] = height / 2; + } + frameRate(30); +} + +function draw() { + background(51); + + // Shift all elements 1 place to the left + for ( let i = 1; i < num; i++ ) { + ax[i - 1] = ax[i]; + ay[i - 1] = ay[i]; + } + + // Put a new value at the end of the array + ax[num - 1] += random(-range, range); + ay[num - 1] += random(-range, range); + + // Constrain all points to the screen + ax[num - 1] = constrain(ax[num - 1], 0, width); + ay[num - 1] = constrain(ay[num - 1], 0, height); + + // Draw a line connecting the points + for ( let j = 1; j < num; j++ ) { + let val = j / num * 204.0 + 51; + stroke(val); + line(ax[j - 1], ay[j - 1], ax[j], ay[j]); + } +} \ No newline at end of file diff --git a/dist/assets/examples/en/09_Simulate/13_Chain.js b/dist/assets/examples/en/09_Simulate/13_Chain.js new file mode 100644 index 0000000000..15988d2478 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/13_Chain.js @@ -0,0 +1,56 @@ +/* + * @name Chain + * @arialabel Two slightly opaque white circles connected by a white line. The user’s mouse moves the top of the string and the circles follow but are also affected by gravity. + * @description One mass is attached to the mouse position and the other is attached the position of the other mass. The gravity in the environment pulls down on both. + * Ported from the Processing Examples page. + */ +let s1, s2; +let gravity = 9.0; +let mass = 2.0; + +function setup() { + createCanvas(720, 400); + fill(255, 126); + // Inputs: x, y, mass, gravity + s1 = new Spring2D(0.0, width / 2, mass, gravity); + s2 = new Spring2D(0.0, width / 2, mass, gravity); +} + +function draw() { + background(0); + s1.update(mouseX, mouseY); + s1.display(mouseX, mouseY); + s2.update(s1.x, s1.y); + s2.display(s1.x, s1.y); +} + +function Spring2D(xpos, ypos, m, g) { + this.x = xpos;// The x- and y-coordinates + this.y = ypos; + this.vx = 0; // The x- and y-axis velocities + this.vy = 0; + this.mass = m; + this.gravity = g; + this.radius = 30; + this.stiffness = 0.2; + this.damping = 0.7; + + this.update = function(targetX, targetY) { + let forceX = (targetX - this.x) * this.stiffness; + let ax = forceX / this.mass; + this.vx = this.damping * (this.vx + ax); + this.x += this.vx; + let forceY = (targetY - this.y) * this.stiffness; + forceY += this.gravity; + let ay = forceY / this.mass; + this.vy = this.damping * (this.vy + ay); + this.y += this.vy; + } + + this.display = function(nx, ny) { + noStroke(); + ellipse(this.x, this.y, this.radius * 2, this.radius * 2); + stroke(255); + line(this.x, this.y, nx, ny); + } +} \ No newline at end of file diff --git a/dist/assets/examples/en/09_Simulate/14_SnowflakeParticleSystem.js b/dist/assets/examples/en/09_Simulate/14_SnowflakeParticleSystem.js new file mode 100644 index 0000000000..ac3fc46f9a --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/14_SnowflakeParticleSystem.js @@ -0,0 +1,64 @@ +/* + * @name Snowflakes + * @arialabel White snowflakes fall in a random pattern from the top of a red background + * @description Particle system simulating the motion of falling snowflakes. + * Uses an array of objects to hold the snowflake particles. + * Contributed by Aatish Bhatia. + */ + +let snowflakes = []; // array to hold snowflake objects + +function setup() { + createCanvas(400, 600); + fill(240); + noStroke(); +} + +function draw() { + background('brown'); + let t = frameCount / 60; // update time + + // create a random number of snowflakes each frame + for (let i = 0; i < random(5); i++) { + snowflakes.push(new snowflake()); // append snowflake object + } + + // loop through snowflakes with a for..of loop + for (let flake of snowflakes) { + flake.update(t); // update snowflake position + flake.display(); // draw snowflake + } +} + +// snowflake class +function snowflake() { + // initialize coordinates + this.posX = 0; + this.posY = random(-50, 0); + this.initialangle = random(0, 2 * PI); + this.size = random(2, 5); + + // radius of snowflake spiral + // chosen so the snowflakes are uniformly spread out in area + this.radius = sqrt(random(pow(width / 2, 2))); + + this.update = function(time) { + // x position follows a circle + let w = 0.6; // angular speed + let angle = w * time + this.initialangle; + this.posX = width / 2 + this.radius * sin(angle); + + // different size snowflakes fall at slightly different y speeds + this.posY += pow(this.size, 0.5); + + // delete snowflake if past end of screen + if (this.posY > height) { + let index = snowflakes.indexOf(this); + snowflakes.splice(index, 1); + } + }; + + this.display = function() { + ellipse(this.posX, this.posY, this.size); + }; +} diff --git a/dist/assets/examples/en/09_Simulate/15_penrose_tiles.js b/dist/assets/examples/en/09_Simulate/15_penrose_tiles.js new file mode 100644 index 0000000000..c5b5cd0f3f --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/15_penrose_tiles.js @@ -0,0 +1,126 @@ +/* + * @name Penrose Tiles + * @arialabel A penrose tile pattern is created by white rhombi being drawn on a black background + * @frame 710,400 + * @description This is a port by David Blitz of the "Penrose Tile" example from processing.org/examples + */ + +let ds; + +function setup() { + createCanvas(710, 400); + ds = new PenroseLSystem(); + //please, play around with the following line + ds.simulate(5); +} + +function draw() { + background(0); + ds.render(); +} + +function PenroseLSystem() { + this.steps = 0; + + //these are axiom and rules for the penrose rhombus l-system + //a reference would be cool, but I couldn't find a good one + this.axiom = "[X]++[X]++[X]++[X]++[X]"; + this.ruleW = "YF++ZF----XF[-YF----WF]++"; + this.ruleX = "+YF--ZF[---WF--XF]+"; + this.ruleY = "-WF++XF[+++YF++ZF]-"; + this.ruleZ = "--YF++++WF[+ZF++++XF]--XF"; + + //please play around with the following two lines + this.startLength = 460.0; + this.theta = TWO_PI / 10.0; //36 degrees, try TWO_PI / 6.0, ... + this.reset(); +} + +PenroseLSystem.prototype.simulate = function (gen) { + while (this.getAge() < gen) { + this.iterate(this.production); + } +} + +PenroseLSystem.prototype.reset = function () { + this.production = this.axiom; + this.drawLength = this.startLength; + this.generations = 0; + } + +PenroseLSystem.prototype.getAge = function () { + return this.generations; + } + +//apply substitution rules to create new iteration of production string +PenroseLSystem.prototype.iterate = function() { + let newProduction = ""; + + for(let i=0; i < this.production.length; ++i) { + let step = this.production.charAt(i); + //if current character is 'W', replace current character + //by corresponding rule + if (step == 'W') { + newProduction = newProduction + this.ruleW; + } + else if (step == 'X') { + newProduction = newProduction + this.ruleX; + } + else if (step == 'Y') { + newProduction = newProduction + this.ruleY; + } + else if (step == 'Z') { + newProduction = newProduction + this.ruleZ; + } + else { + //drop all 'F' characters, don't touch other + //characters (i.e. '+', '-', '[', ']' + if (step != 'F') { + newProduction = newProduction + step; + } + } + } + + this.drawLength = this.drawLength * 0.5; + this.generations++; + this.production = newProduction; +} + +//convert production string to a turtle graphic +PenroseLSystem.prototype.render = function () { + translate(width / 2, height / 2); + + this.steps += 20; + if(this.steps > this.production.length) { + this.steps = this.production.length; + } + + for(let i=0; iRecursive Tree Example for Processing. + */ +let theta; + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(0); + frameRate(30); + stroke(255); + // Let's pick an angle 0 to 90 degrees based on the mouse position + let a = (mouseX / width) * 90; + // Convert it to radians + theta = radians(a); + // Start the tree from the bottom of the screen + translate(width/2,height); + // Draw a line 120 pixels + line(0,0,0,-120); + // Move to the end of that line + translate(0,-120); + // Start the recursive branching! + branch(120); + +} + +function branch(h) { + // Each branch will be 2/3rds the size of the previous one + h *= 0.66; + + // All recursive functions must have an exit condition!!!! + // Here, ours is when the length of the branch is 2 pixels or less + if (h > 2) { + push(); // Save the current state of transformation (i.e. where are we now) + rotate(theta); // Rotate by theta + line(0, 0, 0, -h); // Draw the branch + translate(0, -h); // Move to the end of the branch + branch(h); // Ok, now call myself to draw two new branches!! + pop(); // Whenever we get back here, we "pop" in order to restore the previous matrix state + + // Repeat the same thing, only branch off to the "left" this time! + push(); + rotate(-theta); + line(0, 0, 0, -h); + translate(0, -h); + branch(h); + pop(); + } +} diff --git a/dist/assets/examples/en/09_Simulate/17_Mandelbrot.js b/dist/assets/examples/en/09_Simulate/17_Mandelbrot.js new file mode 100644 index 0000000000..dc7ae43320 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/17_Mandelbrot.js @@ -0,0 +1,87 @@ +/* + * @name The Mandelbrot Set + * @arialabel A fractal that roughly resembles a series of heart-shaped disks, to which smaller disks are attached and consists of a connected set + * @description Simple rendering of the Mandelbrot set. + * Based on Daniel Shiffman's Mandelbrot Example for Processing. + */ + +function setup() { + createCanvas(710, 400); + pixelDensity(1); + noLoop(); +} + +function draw() { + background(0); + + // Establish a range of values on the complex plane + // A different range will allow us to "zoom" in or out on the fractal + + // It all starts with the width, try higher or lower values + const w = 4; + const h = (w * height) / width; + + // Start at negative half the width and height + const xmin = -w/2; + const ymin = -h/2; + + // Make sure we can write to the pixels[] array. + // Only need to do this once since we don't do any other drawing. + loadPixels(); + + // Maximum number of iterations for each point on the complex plane + const maxiterations = 100; + + // x goes from xmin to xmax + const xmax = xmin + w; + // y goes from ymin to ymax + const ymax = ymin + h; + + // Calculate amount we increment x,y for each pixel + const dx = (xmax - xmin) / (width); + const dy = (ymax - ymin) / (height); + + // Start y + let y = ymin; + for (let j = 0; j < height; j++) { + // Start x + let x = xmin; + for (let i = 0; i < width; i++) { + + // Now we test, as we iterate z = z^2 + cm does z tend towards infinity? + let a = x; + let b = y; + let n = 0; + while (n < maxiterations) { + const aa = a * a; + const bb = b * b; + const twoab = 2.0 * a * b; + a = aa - bb + x; + b = twoab + y; + // Infinty in our finite world is simple, let's just consider it 16 + if (dist(aa, bb, 0, 0) > 16) { + break; // Bail + } + n++; + } + + // We color each pixel based on how long it takes to get to infinity + // If we never got there, let's pick the color black + const pix = (i+j*width)*4; + const norm = map(n, 0, maxiterations, 0, 1); + let bright = map(sqrt(norm), 0, 1, 0, 255); + if (n == maxiterations) { + bright = 0; + } else { + // Gosh, we could make fancy colors here if we wanted + pixels[pix + 0] = bright; + pixels[pix + 1] = bright; + pixels[pix + 2] = bright; + pixels[pix + 3] = 255; + } + x += dx; + } + y += dy; + } + updatePixels(); +} diff --git a/dist/assets/examples/en/09_Simulate/18_Koch.js b/dist/assets/examples/en/09_Simulate/18_Koch.js new file mode 100644 index 0000000000..4d5c2ec3d1 --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/18_Koch.js @@ -0,0 +1,142 @@ +/* + * @name Koch Curve + * @arialabel Koch snowflake is created by a single horizontal white line on a black background that then morphs into a triangle in the middle, and then each side of the triangle also becomes two more triangles, and this repeats 5 times + * @description Renders a simple fractal, the Koch snowflake. Each recursive level is drawn in sequence. + * By Daniel Shiffman + */ + +let k; + +function setup() { + createCanvas(710, 400); + frameRate(1); // Animate slowly + k = new KochFractal(); +} + +function draw() { + background(0); + // Draws the snowflake! + k.render(); + // Iterate + k.nextLevel(); + // Let's not do it more than 5 times. . . + if (k.getCount() > 5) { + k.restart(); + } +} + +// A class to describe one line segment in the fractal +// Includes methods to calculate midp5.Vectors along the line according to the Koch algorithm + +class KochLine { + constructor(a,b) { + // Two p5.Vectors, + // start is the "left" p5.Vector and + // end is the "right p5.Vector + this.start = a.copy(); + this.end = b.copy(); + } + + display() { + stroke(255); + line(this.start.x, this.start.y, this.end.x, this.end.y); + } + + kochA() { + return this.start.copy(); + } + + // This is easy, just 1/3 of the way + kochB() { + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + v.add(this.start); + return v; + } + + // More complicated, have to use a little trig to figure out where this p5.Vector is! + kochC() { + let a = this.start.copy(); // Start at the beginning + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + a.add(v); // Move to point B + v.rotate(-PI/3); // Rotate 60 degrees + a.add(v); // Move to point C + return a; + } + + // Easy, just 2/3 of the way + kochD() { + let v = p5.Vector.sub(this.end, this.start); + v.mult(2/3.0); + v.add(this.start); + return v; + } + + kochE() { + return this.end.copy(); + } +} + +// A class to manage the list of line segments in the snowflake pattern + +class KochFractal { + constructor() { + this.start = createVector(0,height-20); // A p5.Vector for the start + this.end = createVector(width,height-20); // A p5.Vector for the end + this.lines = []; // An array to keep track of all the lines + this.count = 0; + this.restart(); + } + + nextLevel() { + // For every line that is in the arraylist + // create 4 more lines in a new arraylist + this.lines = this.iterate(this.lines); + this.count++; + } + + restart() { + this.count = 0; // Reset count + this.lines = []; // Empty the array list + this.lines.push(new KochLine(this.start,this.end)); // Add the initial line (from one end p5.Vector to the other) + } + + getCount() { + return this.count; + } + + // This is easy, just draw all the lines + render() { + for(let i = 0; i < this.lines.length; i++) { + this.lines[i].display(); + } + } + + // This is where the **MAGIC** happens + // Step 1: Create an empty arraylist + // Step 2: For every line currently in the arraylist + // - calculate 4 line segments based on Koch algorithm + // - add all 4 line segments into the new arraylist + // Step 3: Return the new arraylist and it becomes the list of line segments for the structure + + // As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . . + iterate(before) { + let now = []; // Create emtpy list + for(let i = 0; i < this.lines.length; i++) { + let l = this.lines[i]; + // Calculate 5 koch p5.Vectors (done for us by the line object) + let a = l.kochA(); + let b = l.kochB(); + let c = l.kochC(); + let d = l.kochD(); + let e = l.kochE(); + // Make line segments between all the p5.Vectors and add them + now.push(new KochLine(a,b)); + now.push(new KochLine(b,c)); + now.push(new KochLine(c,d)); + now.push(new KochLine(d,e)); + } + return now; + } +} diff --git a/dist/assets/examples/en/09_Simulate/19_Bubblesort.js b/dist/assets/examples/en/09_Simulate/19_Bubblesort.js new file mode 100644 index 0000000000..89e1079ede --- /dev/null +++ b/dist/assets/examples/en/09_Simulate/19_Bubblesort.js @@ -0,0 +1,68 @@ +/* + * @name Bubble Sort + * @arialabel Dark grey bars of different heights on a light grey background are sorted from tallest to shortest from the right to the left side of the screen + * @description Sorts the randomly distributed bars + * according to their height in ascending order + * while simulating the whole sorting process. + * Took references from Coding Challenge by The Coding Train. + */ + +let values = []; +let i = 0; +let j = 0; + +// The statements in the setup() function +// execute once when the program begins +// The array is filled with random values in setup() function. +function setup() { + createCanvas(720, 400); + for(let i = 0;i values[j+1]){ + values[j] = values[j+1]; + values[j+1] = temp; + } + j++; + + if(j>=values.length-i-1){ + j = 0; + i++; + } + } + else{ + noLoop(); + } + } +} + +// The simulateSorting() function helps in animating +// the whole bubble sort algorithm +// by drawing the rectangles using values +// in the array as the length of the rectangle. +function simulateSorting(){ + for(let i = 0;i= width || this.xPos <= 0){ + this.xSpeed*=-1; + } + } +} + +function setup() { + createCanvas(720, 400); + createP("Keep the mouse clicked").style('color','#ffffff'); + createP("to check whether the bricks").style('color','#ffffff'); + createP("are moving at same speed or not").style('color','#ffffff'); +} + +// creating two bricks of +// colors white and black +let brick1 = new Brick("white",100); +let brick2 = new Brick("black",250); + +// +brick1.setSpeed(); +brick2.setSpeed(); + +function draw () { + background(0); + if(mouseIsPressed){ + background(50); + } + brick1.createBrick(); + brick1.moveBrick(); + if(!mouseIsPressed){ + createBars(); + } + brick2.createBrick(); + brick2.moveBrick(); +} + +// this function creates the black and +// white bars across the screen +function createBars() { + let len = 12; + for(let i = 0;i width) + this.xSpeed*=-1; + if(this.y < 0 || this.y > height) + this.ySpeed*=-1; + this.x+=this.xSpeed; + this.y+=this.ySpeed; + } + +// this function creates the connections(lines) +// between particles which are less than a certain distance apart + joinParticles(particles) { + particles.forEach(element =>{ + let dis = dist(this.x,this.y,element.x,element.y); + if(dis<85) { + stroke('rgba(255,255,255,0.04)'); + line(this.x,this.y,element.x,element.y); + } + }); + } +} + +// an array to add multiple particles +let particles = []; + +function setup() { + createCanvas(720, 400); + for(let i = 0;i
+ * Quicksort is a divide-and-conquer algorithm: it + * performs sorting by dividing the original array into + * smaller subarrays and solving them independently, + * loosely speaking. It involves picking an element of + * the array as the pivot element and partitioning the + * given array around the picked pivot.
+ * Partitioning refers to arranging the given array(or + * subarray) in such a way that all elements to the left + * of the pivot element are smaller than it and all + * elements to its right are larger than it. Thus, we have + * a reference point from where we proceed to sort the + * left and right 'halves' of the array, and eventually + * arrive at an array sorted in ascending order. + * + * More
+ */ + +// width of each bar is taken as 8. +let values = []; +// The array 'states' helps in identifying the pivot index +// at every step, and also the subarray which is being sorted +// at any given time. +let states = []; + +// The setup() function is called once when the program +// starts. Here, we fill the array 'values' with random values +// and the array 'states' with a value of -1 for each position. +function setup() { + createCanvas(710, 400); + for(let i = 0; i < width/8; i++) { + values.push(random(height)); + states.push(-1); + } + quickSort(0, values.length - 1); +} + +// The statements in draw() function are executed continuously +// until the program is stopped. Each statement is executed +// sequentially and after the last line is read, the first +// line is executed again. +function draw() { + background(140); + for(let i = 0; i < values.length; i++) { + // color coding + if (states[i] == 0) { + // color for the bar at the pivot index + fill('#E0777D'); + } else if (states[i] == 1) { + // color for the bars being sorted currently + fill('#D6FFB7'); + } else { + fill(255); + } + rect(i * 8, height - values[i], 8, values[i]); + } +} + +async function quickSort(start, end) { + if (start > end) { // Nothing to sort! + return; + } + // partition() returns the index of the pivot element. + // Once partition() is executed, all elements to the + // left of the pivot element are smaller than it and + // all elements to its right are larger than it. + let index = await partition(start, end); + // restore original state + states[index] = -1; + await Promise.all( + [quickSort(start, index - 1), + quickSort(index + 1, end) + ]); +} + +// We have chosen the element at the last index as +// the pivot element, but we could've made different +// choices, e.g. take the first element as pivot. +async function partition(start, end) { + for (let i = start; i < end; i++) { + // identify the elements being considered currently + states[i] = 1; + } + // Quicksort algorithm + let pivotIndex = start; + // make pivot index distinct + states[pivotIndex] = 0; + let pivotElement = values[end]; + for (let i = start; i < end; i++) { + if (values[i] < pivotElement) { + await swap(i, pivotIndex); + states[pivotIndex] = -1; + pivotIndex++; + states[pivotIndex] = 0; + } + } + await swap(end, pivotIndex); + for (let i = start; i < end; i++) { + // restore original state + if (i != pivotIndex) { + states[i] = -1; + } + } + return pivotIndex; +} + +// swaps elements of 'values' at indices 'i' and 'j' +async function swap(i, j) { + // adjust the pace of the simulation by changing the + // value + await sleep(25); + let temp = values[i]; + values[i] = values[j]; + values[j] = temp; +} + +// custom helper function to deliberately slow down +// the sorting process and make visualization easy +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} \ No newline at end of file diff --git a/dist/assets/examples/en/10_Interaction/10_Tickle.js b/dist/assets/examples/en/10_Interaction/10_Tickle.js new file mode 100644 index 0000000000..a47d2bc4a0 --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/10_Tickle.js @@ -0,0 +1,49 @@ +/* + * @name Tickle + * @arialabel The word “tickle” in black is on a light gray background. As the user hovers the word, the word shakes and moves as if being tickled + * @description The word "tickle" jitters when the cursor hovers over. + * Sometimes, it can be tickled off the screen. + */ +let message = 'tickle', + font, + bounds, // holds x, y, w, h of the text's bounding box + fontsize = 60, + x, + y; // x and y coordinates of the text + +function preload() { + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // set up the font + textFont(font); + textSize(fontsize); + + // get the width and height of the text so we can center it initially + bounds = font.textBounds(message, 0, 0, fontsize); + x = width / 2 - bounds.w / 2; + y = height / 2 - bounds.h / 2; +} + +function draw() { + background(204, 120); + + // write the text in black and get its bounding box + fill(0); + text(message, x, y); + bounds = font.textBounds(message, x, y, fontsize); + + // check if the mouse is inside the bounding box and tickle if so + if ( + mouseX >= bounds.x && + mouseX <= bounds.x + bounds.w && + mouseY >= bounds.y && + mouseY <= bounds.y + bounds.h + ) { + x += random(-5, 5); + y += random(-5, 5); + } +} diff --git a/dist/assets/examples/en/10_Interaction/11_WeightLine.js b/dist/assets/examples/en/10_Interaction/11_WeightLine.js new file mode 100644 index 0000000000..eb39963d8c --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/11_WeightLine.js @@ -0,0 +1,56 @@ +/* + * @name Weight Line + * @arialabel Light yellow background and the user’s mouse draws lines of various shades and thicknesses as it hovers over the background + * @frame 710,400 + * @description contributed by + Prof WM Harris, using the random function with events to color/weight a line
+ How to use the random function with events to color/ weight a line + dependent on mouse location, left mouse button clicks, character key types, and + random key releases.
+ Functions are created for both the canvas set up as well as the creation of + the line. Depending on the action taken by the user the line can + vary in width and color. Left mouse button clicks result in a color + change to blue, while the typing of any character key will change + the color to turquoise, each resulting in a variable stroke weight; + the width of the former will be between 0 – 1 while the width of + the latter will be 0 – 5. The release of any key will result in a + random hue, saturation, and brightness change to the line. + */ + + +function setup() { + createCanvas(400, 400); + background("beige"); + colorMode(HSB); + } + + function draw() { + //Line from prev pt to current pt + //of mouse position + line(mouseX, mouseY, pmouseX, pmouseY); + } + + //listen when we click the mouse + function mouseClicked() { + //weights 0 to 1 + stroke("slateBlue"); + strokeWeight(random()); + + //what if want weights 0 to .4? + //strokeWeight( random(.4) ); + } + + //listen when we release *any* key + function keyReleased() { + //color hue values between 20 and 145 + //saturation 0 to 100 + //brightness 80 to 100 + stroke(random(20, 145), random(100), random(80, 100)); + } + + //listen for only character keys + function keyTyped() { + //weights 0 to 5 + stroke("turquoise"); + strokeWeight(random(5)); + } \ No newline at end of file diff --git a/dist/assets/examples/en/10_Interaction/20_Follow1.js b/dist/assets/examples/en/10_Interaction/20_Follow1.js new file mode 100644 index 0000000000..ebce244abc --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/20_Follow1.js @@ -0,0 +1,38 @@ +/* + * @name Follow 1 + * @arialabel Circle connected to a long oval. The user’s mouse is attached to the end of the oval. When the mouse moves, the oval and circle moves with it. + * @frame 710,400 + * @description A line segment is pushed and pulled by the cursor. + * Based on code from Keith Peters. + */ +let x = 100, + y = 100, + angle1 = 0.0, + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + x = mouseX - cos(angle1) * segLength; + y = mouseY - sin(angle1) * segLength; + + segment(x, y, angle1); + ellipse(x, y, 20, 20); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/en/10_Interaction/21_Follow2.js b/dist/assets/examples/en/10_Interaction/21_Follow2.js new file mode 100644 index 0000000000..6a25565488 --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/21_Follow2.js @@ -0,0 +1,40 @@ +/* + * @name Follow 2 + * @arialabel Two long ovals connected at the end. The user’s mouse is attached to the end of one of the ovals and when the mouse moves, the two ovals move as well + * @frame 710,400 + * @description A two-segmented arm follows the cursor position. The relative + * angle between the segments is calculated with atan2() and the position + * calculated with sin() and cos(). Based on code from Keith Peters. + */ +let x = [0, 0], + y = [0, 0], + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + dragSegment(1, x[0], y[0]); +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/en/10_Interaction/22_Follow3.js b/dist/assets/examples/en/10_Interaction/22_Follow3.js new file mode 100644 index 0000000000..0057e748e6 --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/22_Follow3.js @@ -0,0 +1,48 @@ +/* + * @name Follow 3 + * @arialabel Long segmented snake shape follows the user’s mouse as it moves + * @frame 710,400 + * @description A segmented line follows the mouse. The relative angle from + * each segment to the next is calculated with atan2() and the position of + * the next is calculated with sin() and cos(). Based on code from Keith Peters. + */ +let x = [], + y = [], + segNum = 20, + segLength = 18; + +for (let i = 0; i < segNum; i++) { + x[i] = 0; + y[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(9); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/en/10_Interaction/23_snake.js b/dist/assets/examples/en/10_Interaction/23_snake.js new file mode 100644 index 0000000000..6a213d5eef --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/23_snake.js @@ -0,0 +1,173 @@ +/* + * @name Snake game + * @arialabel Snake game where a snake represented by a long white oval on a black background is controlled by the i,j,k,l keys. Users use these keys to move the snake to not hit the sides of the window and to eat a small white circle which represents food and allows the snake to grow. + * @description The famous snake game! Once you click run, click anywhere + * inside the black area, and control the snake using i j k and l. Don't let + * the snake hit itself or the wall!
+ * Example created by Prashant Gupta + */ + +// the snake is divided into small segments, which are drawn and edited on each 'draw' call +let numSegments = 10; +let direction = 'right'; + +const xStart = 0; //starting x coordinate for snake +const yStart = 250; //starting y coordinate for snake +const diff = 10; + +let xCor = []; +let yCor = []; + +let xFruit = 0; +let yFruit = 0; +let scoreElem; + +function setup() { + scoreElem = createDiv('Score = 0'); + scoreElem.position(20, 20); + scoreElem.id = 'score'; + scoreElem.style('color', 'white'); + + createCanvas(500, 500); + frameRate(15); + stroke(255); + strokeWeight(10); + updateFruitCoordinates(); + + for (let i = 0; i < numSegments; i++) { + xCor.push(xStart + i * diff); + yCor.push(yStart); + } +} + +function draw() { + background(0); + for (let i = 0; i < numSegments - 1; i++) { + line(xCor[i], yCor[i], xCor[i + 1], yCor[i + 1]); + } + updateSnakeCoordinates(); + checkGameStatus(); + checkForFruit(); +} + +/* + The segments are updated based on the direction of the snake. + All segments from 0 to n-1 are just copied over to 1 till n, i.e. segment 0 + gets the value of segment 1, segment 1 gets the value of segment 2, and so on, + and this results in the movement of the snake. + + The last segment is added based on the direction in which the snake is going, + if it's going left or right, the last segment's x coordinate is increased by a + predefined value 'diff' than its second to last segment. And if it's going up + or down, the segment's y coordinate is affected. +*/ +function updateSnakeCoordinates() { + for (let i = 0; i < numSegments - 1; i++) { + xCor[i] = xCor[i + 1]; + yCor[i] = yCor[i + 1]; + } + switch (direction) { + case 'right': + xCor[numSegments - 1] = xCor[numSegments - 2] + diff; + yCor[numSegments - 1] = yCor[numSegments - 2]; + break; + case 'up': + xCor[numSegments - 1] = xCor[numSegments - 2]; + yCor[numSegments - 1] = yCor[numSegments - 2] - diff; + break; + case 'left': + xCor[numSegments - 1] = xCor[numSegments - 2] - diff; + yCor[numSegments - 1] = yCor[numSegments - 2]; + break; + case 'down': + xCor[numSegments - 1] = xCor[numSegments - 2]; + yCor[numSegments - 1] = yCor[numSegments - 2] + diff; + break; + } +} + +/* + I always check the snake's head position xCor[xCor.length - 1] and + yCor[yCor.length - 1] to see if it touches the game's boundaries + or if the snake hits itself. +*/ +function checkGameStatus() { + if ( + xCor[xCor.length - 1] > width || + xCor[xCor.length - 1] < 0 || + yCor[yCor.length - 1] > height || + yCor[yCor.length - 1] < 0 || + checkSnakeCollision() + ) { + noLoop(); + const scoreVal = parseInt(scoreElem.html().substring(8)); + scoreElem.html('Game ended! Your score was : ' + scoreVal); + } +} + +/* + If the snake hits itself, that means the snake head's (x,y) coordinate + has to be the same as one of its own segment's (x,y) coordinate. +*/ +function checkSnakeCollision() { + const snakeHeadX = xCor[xCor.length - 1]; + const snakeHeadY = yCor[yCor.length - 1]; + for (let i = 0; i < xCor.length - 1; i++) { + if (xCor[i] === snakeHeadX && yCor[i] === snakeHeadY) { + return true; + } + } +} + +/* + Whenever the snake consumes a fruit, I increment the number of segments, + and just insert the tail segment again at the start of the array (basically + I add the last segment again at the tail, thereby extending the tail) +*/ +function checkForFruit() { + point(xFruit, yFruit); + if (xCor[xCor.length - 1] === xFruit && yCor[yCor.length - 1] === yFruit) { + const prevScore = parseInt(scoreElem.html().substring(8)); + scoreElem.html('Score = ' + (prevScore + 1)); + xCor.unshift(xCor[0]); + yCor.unshift(yCor[0]); + numSegments++; + updateFruitCoordinates(); + } +} + +function updateFruitCoordinates() { + /* + The complex math logic is because I wanted the point to lie + in between 100 and width-100, and be rounded off to the nearest + number divisible by 10, since I move the snake in multiples of 10. + */ + + xFruit = floor(random(10, (width - 100) / 10)) * 10; + yFruit = floor(random(10, (height - 100) / 10)) * 10; +} + +function keyPressed() { + switch (keyCode) { + case 74: + if (direction !== 'right') { + direction = 'left'; + } + break; + case 76: + if (direction !== 'left') { + direction = 'right'; + } + break; + case 73: + if (direction !== 'down') { + direction = 'up'; + } + break; + case 75: + if (direction !== 'up') { + direction = 'down'; + } + break; + } +} diff --git a/dist/assets/examples/en/10_Interaction/24_Wavemaker.js b/dist/assets/examples/en/10_Interaction/24_Wavemaker.js new file mode 100644 index 0000000000..50d3d2061e --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/24_Wavemaker.js @@ -0,0 +1,38 @@ +/* + * @name Wavemaker + * @arialabel Water like waves of neon green lines moving in circular patterns. The user’s mouse can change the direction of the current in the waves + * @description This illustrates how waves (like water waves) emerge + * from particles oscillating in place. Move your mouse to direct the wave. + * Contributed by Aatish Bhatia, inspired by Orbiters by Dave Whyte. + */ + +let t = 0; // time variable + +function setup() { + createCanvas(600, 600); + noStroke(); + fill(40, 200, 40); +} + +function draw() { + background(10, 10); // translucent background (creates trails) + + // make a x and y grid of ellipses + for (let x = 0; x <= width; x = x + 30) { + for (let y = 0; y <= height; y = y + 30) { + // starting point of each circle depends on mouse position + const xAngle = map(mouseX, 0, width, -4 * PI, 4 * PI, true); + const yAngle = map(mouseY, 0, height, -4 * PI, 4 * PI, true); + // and also varies based on the particle's location + const angle = xAngle * (x / width) + yAngle * (y / height); + + // each particle moves in a circle + const myX = x + 20 * cos(2 * PI * t + angle); + const myY = y + 20 * sin(2 * PI * t + angle); + + ellipse(myX, myY, 10); // draw particle + } + } + + t = t + 0.01; // update time +} diff --git a/dist/assets/examples/en/10_Interaction/25_reach1.js b/dist/assets/examples/en/10_Interaction/25_reach1.js new file mode 100644 index 0000000000..36a039008b --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/25_reach1.js @@ -0,0 +1,58 @@ +/* + * @name Reach 1 + * @arialabel Two long ovals connected at the end. The user’s mouse is attached to the end of one of the ovals and when the mouse moves, the two ovals move as well. However, the end of the other oval is permanently attached to the middle of the background. + * @frame 710,400 + * @description The arm follows the position of the mouse by calculating the + * angles with atan2(). Based on code from Keith Peters. + */ +let segLength = 80, + x, + y, + x2, + y2; + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x = width / 2; + y = height / 2; + x2 = x; + y2 = y; +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + + tx = mouseX - cos(angle1) * segLength; + ty = mouseY - sin(angle1) * segLength; + dx = tx - x2; + dy = ty - y2; + angle2 = atan2(dy, dx); + x = x2 + cos(angle2) * segLength; + y = y2 + sin(angle2) * segLength; + + segment(x, y, angle1); + segment(x2, y2, angle2); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/en/10_Interaction/26_reach2.js b/dist/assets/examples/en/10_Interaction/26_reach2.js new file mode 100644 index 0000000000..4143ef5c97 --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/26_reach2.js @@ -0,0 +1,66 @@ +/* + * @name Reach 2 + * @arialabel Grey triangle segmented and attached to the bottom of the black screen. The tip of the triangle follows the direction of the user’s mouse + * @frame 710,400 + * @description The arm follows the position of the mouse by calculating the + * angles with atan2(). Based on code from Keith Peters. + */ +let numSegments = 10, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x[x.length - 1] = width / 2; // Set base x-coordinate + y[x.length - 1] = height; // Set base y-coordinate +} + +function draw() { + background(0); + + reachSegment(0, mouseX, mouseY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/en/10_Interaction/27_reach3.js b/dist/assets/examples/en/10_Interaction/27_reach3.js new file mode 100644 index 0000000000..133b1479b9 --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/27_reach3.js @@ -0,0 +1,82 @@ +/* + * @name Reach 3 + * @arialabel Grey triangle segmented and attached to the bottom of the black screen. The tip of the triangle follows the direction of a grey circular donut shape that is also bouncing around the screen + * @frame 710,400 + * @description The arm follows the position of the ball by calculating the + * angles with atan2(). Based on code from Keith Peters. + */ +let numSegments = 8, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY, + ballX = 50, + ballY = 50, + ballXDirection = 1, + ballYDirection = -1; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + noFill(); + + x[x.length - 1] = width / 2; // Set base x-coordinate + y[x.length - 1] = height; // Set base y-coordinate +} + +function draw() { + background(0); + + strokeWeight(20); + ballX = ballX + 1.0 * ballXDirection; + ballY = ballY + 0.8 * ballYDirection; + if (ballX > width - 25 || ballX < 25) { + ballXDirection *= -1; + } + if (ballY > height - 25 || ballY < 25) { + ballYDirection *= -1; + } + ellipse(ballX, ballY, 30, 30); + + reachSegment(0, ballX, ballY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/en/10_Interaction/28_ArduinoSensor.js b/dist/assets/examples/en/10_Interaction/28_ArduinoSensor.js new file mode 100644 index 0000000000..09cd07dfde --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/28_ArduinoSensor.js @@ -0,0 +1,37 @@ +/* + * @name Arduino sensor data via WebJack + * @description WebJack is a way to read data from an Arduino (and other sources) + * using audio -- it basically turns your Arduino into an audio modem. + * + * https://github.com/publiclab/webjack + * + * Note: WebJack and p5-webjack libraries must be added to your index.html as follows: + *
<script src="https://webjack.io/dist/webjack.js"></script>
+ *
<script src="https://jywarren.github.io/p5-webjack/lib.js"></script>
+ * + * Working example: https://editor.p5js.org/jywarren/sketches/rkztwSt8M + * + * Testing audio: https://www.youtube.com/watch?v=GtJW1Dlt3cg + * Load this sketch onto an Arduino: + * https://create.arduino.cc/editor/jywarren/023158d8-be51-4c78-99ff-36c63126b554/preview + * Arduino will output audio from pin 3 + ground. Use microphone or an audio cable. + */ + +function setup() { + createCanvas(400, 400); + noStroke(); + fill('#ff00aa22'); + receiveSensorData(handleData); +} + +function handleData(data, connection) { + + console.log(data); // output the values to log + // data[0] is the 1st value, data[1] 2nd, etc. + + // draw stuff! Browse http://p5js.org/reference/ + background('#ddd'); + ellipse(100, 200, data[0]+10, data[0]+10); + + // connection.send('send data back to the Arduino if its listening'); +} diff --git a/dist/assets/examples/en/10_Interaction/29_kaleidoscope.js b/dist/assets/examples/en/10_Interaction/29_kaleidoscope.js new file mode 100644 index 0000000000..8eec6dcdc6 --- /dev/null +++ b/dist/assets/examples/en/10_Interaction/29_kaleidoscope.js @@ -0,0 +1,73 @@ +/* + * @name Kaleidoscope + * @arialabel User draws thick black lines on the grey background and it is mirrored 5 times in a circle like a kaleidoscope + * @description A kaleidoscope is an optical instrument with two or more reflecting surfaces tilted to each other in an angle. This example tries to replicate the behavior of a kaleidoscope. Set the number of reflections at the symmetry variable and start drawing on the screen. Adjust the brush size with the help of the slider. The clear screen as it says clears the screen. The save button will download a .jpg file of the art that you have created. + */ +// Symmetry corresponding to the number of reflections. Change the number for different number of reflections +let symmetry = 6; + +let angle = 360 / symmetry; +let saveButton, clearButton, mouseButton, keyboardButton; +let slider; + +function setup() { + createCanvas(710, 710); + angleMode(DEGREES); + background(127); + + // Creating the save button for the file + saveButton = createButton('save'); + saveButton.mousePressed(saveFile); + + // Creating the clear screen button + clearButton = createButton('clear'); + clearButton.mousePressed(clearScreen); + + // Creating the button for Full Screen + fullscreenButton = createButton('Full Screen'); + fullscreenButton.mousePressed(screenFull); + + // Setting up the slider for the thickness of the brush + brushSizeSlider = createButton('Brush Size Slider'); + sizeSlider = createSlider(1, 32, 4, 0.1); +} + +// Save File Function +function saveFile() { + save('design.jpg'); +} + +// Clear Screen function +function clearScreen() { + background(127); +} + +// Full Screen Function +function screenFull() { + let fs = fullscreen(); + fullscreen(!fs); +} + +function draw() { + translate(width / 2, height / 2); + + if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) { + let mx = mouseX - width / 2; + let my = mouseY - height / 2; + let pmx = pmouseX - width / 2; + let pmy = pmouseY - height / 2; + + if (mouseIsPressed) { + for (let i = 0; i < symmetry; i++) { + rotate(angle); + let sw = sizeSlider.value(); + strokeWeight(sw); + line(mx, my, pmx, pmy); + push(); + scale(1, -1); + line(mx, my, pmx, pmy); + pop(); + } + } + } +} diff --git a/dist/assets/examples/en/11_Objects/01_Objects.js b/dist/assets/examples/en/11_Objects/01_Objects.js new file mode 100644 index 0000000000..d299c1ab88 --- /dev/null +++ b/dist/assets/examples/en/11_Objects/01_Objects.js @@ -0,0 +1,40 @@ +/* + * @name Objects + * @arialabel Small white circle on dark navy background that moves in small amounts in various directions by a small amount by itself like it is jittering + * @description Create a Jitter class, instantiate an object, + * and move it around the screen. Adapted from Getting Started with + * Processing by Casey Reas and Ben Fry. + */ + +let bug; // Declare object + +function setup() { + createCanvas(710, 400); + // Create object + bug = new Jitter(); +} + +function draw() { + background(50, 89, 100); + bug.move(); + bug.display(); +} + +// Jitter class +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/en/11_Objects/02_Multiple_Objects.js b/dist/assets/examples/en/11_Objects/02_Multiple_Objects.js new file mode 100644 index 0000000000..734a6aae3f --- /dev/null +++ b/dist/assets/examples/en/11_Objects/02_Multiple_Objects.js @@ -0,0 +1,51 @@ +/* + * @name Multiple Objects + * @arialabel Four small white circles places randomly on a dark navy background that move in small amounts in various directions by itself like they are jittering + * @description Create a Jitter class, instantiate multiple objects, + * and move it around the screen. + */ + +let bug1; // Declare objects +let bug2; +let bug3; +let bug4; + +function setup() { + createCanvas(710, 400); + // Create object + bug1 = new Jitter(); + bug2 = new Jitter(); + bug3 = new Jitter(); + bug4 = new Jitter(); +} + +function draw() { + background(50, 89, 100); + bug1.move(); + bug1.display(); + bug2.move(); + bug2.display(); + bug3.move(); + bug3.display(); + bug4.move(); + bug4.display(); +} + +// Jitter class +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/en/11_Objects/03_Objects_Array.js b/dist/assets/examples/en/11_Objects/03_Objects_Array.js new file mode 100644 index 0000000000..c9a5dd335f --- /dev/null +++ b/dist/assets/examples/en/11_Objects/03_Objects_Array.js @@ -0,0 +1,43 @@ +/* + * @name Array of Objects + * @arialabel Multiple sizes of small white circles placed randomly on a dark navy background that move in small amounts in various directions by itself like they are jittering + * @description Create a Jitter class, instantiate an array of objects + * and move them around the screen. + */ + +let bugs = []; // array of Jitter objects + +function setup() { + createCanvas(710, 400); + // Create objects + for (let i = 0; i < 50; i++) { + bugs.push(new Jitter()); + } +} + +function draw() { + background(50, 89, 100); + for (let i = 0; i < bugs.length; i++) { + bugs[i].move(); + bugs[i].display(); + } +} + +// Jitter class +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/en/11_Objects/03_Objects_Optional_Arguments.js b/dist/assets/examples/en/11_Objects/03_Objects_Optional_Arguments.js new file mode 100644 index 0000000000..2adbd9a7b8 --- /dev/null +++ b/dist/assets/examples/en/11_Objects/03_Objects_Optional_Arguments.js @@ -0,0 +1,66 @@ +/* + * @name Objects 2 + * @arialabel 4 sets of vertical white lines that form rectangles of different sizes on a black background. They move around as the user’s mouse moves + * @description Ported from example by hbarragan. Move the cursor across the + * image to change the speed and positions of the geometry. The class MRect + * defines a group of lines. + */ + +let r1, r2, r3, r4; + +function setup() { +createCanvas(710, 400); +fill(255, 204); +noStroke(); +r1 = new MRect(1, 134.0, 0.532, 0.1 * height, 10.0, 60.0); +r2 = new MRect(2, 44.0, 0.166, 0.3 * height, 5.0, 50.0); +r3 = new MRect(2, 58.0, 0.332, 0.4 * height, 10.0, 35.0); +r4 = new MRect(1, 120.0, 0.0498, 0.9 * height, 15.0, 60.0); +} + +function draw() { +background(0); + +r1.display(); +r2.display(); +r3.display(); +r4.display(); + +r1.move(mouseX - width / 2, mouseY + height * 0.1, 30); +r2.move((mouseX + width * 0.05) % width, mouseY + height * 0.025, 20); +r3.move(mouseX / 4, mouseY - height * 0.025, 40); +r4.move(mouseX - width / 2, height - mouseY, 50); +} + +class MRect { + constructor(iw, ixp, ih, iyp, id, it) { + this.w = iw; // single bar width + this.xpos = ixp; // rect xposition + this.h = ih; // rect height + this.ypos = iyp; // rect yposition + this.d = id; // single bar distance + this.t = it; // number of bars + } + + move(posX, posY, damping) { + let dif = this.ypos - posY; + if (abs(dif) > 1) { + this.ypos -= dif / damping; + } + dif = this.xpos - posX; + if (abs(dif) > 1) { + this.xpos -= dif / damping; + } + } + + display() { + for (let i = 0; i < this.t; i++) { + rect( + this.xpos + i * (this.d + this.w), + this.ypos, + this.w, + height * this.h + ); + } + } +} diff --git a/dist/assets/examples/en/11_Objects/04_Inheritance.js b/dist/assets/examples/en/11_Objects/04_Inheritance.js new file mode 100644 index 0000000000..9e47eb9630 --- /dev/null +++ b/dist/assets/examples/en/11_Objects/04_Inheritance.js @@ -0,0 +1,71 @@ +/* @name Inheritance + * @arialabel Two white circles connected and spinning around each other anti-clockwise with a black line behind that is spinning clockwise + * @description A class can be defined using another class as a + * foundation. In object-oriented programming terminology, one class can + * inherit fields and methods from another. An object that inherits from + * another is called a subclass, and the object it inherits from is called + * a superclass. A subclass extends the superclass. + */ +let spots, arm; + +function setup() { +createCanvas(640, 360); +arm = new SpinArm(width/2, height/2, 0.01); +spots = new SpinSpots(width/2, height/2, -0.02, 90.0); +} + +function draw() { +background(204); +arm.update(); +arm.display(); +spots.update(); +spots.display(); +} + +class Spin { +constructor(x, y, s) { + this.x = x; + this.y = y; + this.speed = s; + this.angle = 0.0; +} + +update() { + this.angle += this.speed; +} +} + +class SpinArm extends Spin { +constructor(x, y, s) { + super(x, y, s) +} + +display() { + strokeWeight(1); + stroke(0); + push(); + translate(this.x, this.y); + this.angle += this.speed; + rotate(this.angle); + line(0, 0, 165, 0); + pop(); +} +} + +class SpinSpots extends Spin { +constructor(x, y, s, d) { + super(x, y, s) + this.dim = d; +} + +display() { + noStroke(); + push(); + translate(this.x, this.y); + this.angle += this.speed; + rotate(this.angle); + ellipse(-this.dim/2, 0, this.dim, this.dim); + ellipse(this.dim/2, 0, this.dim, this.dim); + pop(); +} +} diff --git a/dist/assets/examples/en/11_Objects/05_Composite_Objects.js b/dist/assets/examples/en/11_Objects/05_Composite_Objects.js new file mode 100644 index 0000000000..1fd5313ea9 --- /dev/null +++ b/dist/assets/examples/en/11_Objects/05_Composite_Objects.js @@ -0,0 +1,100 @@ +/* @name Composite Objects + * @arialabel Two white egg shapes that totter side to side. There is a grey circle within each egg that expands larger until it is off the screen + * @description An object can include several other objects. + * Creating such composite objects is a good way to use the principles + * of modularity and build higher levels of abstraction within a program. + */ +let er1, er2; + +function setup() { +createCanvas(640, 360); +er1 = new EggRing(width * 0.45, height * 0.5, 0.1, 120); +er2 = new EggRing(width * 0.65, height * 0.8, 0.05, 180); +} + +function draw() { +background(0); +er1.transmit(); +er2.transmit(); +} + +class Egg { +constructor(xpos, ypos, t, s) { + this.x = xpos; + this.y = ypos; + this.tilt = t; + this.scalar = s / 100.0; + this.angle = 0.0; +} + +wobble() { + this.tilt = cos(this.angle) / 8; + this.angle += 0.1; +} + +display() { + noStroke(); + fill(255); + push(); + translate(this.x, this.y); + rotate(this.tilt); + scale(this.scalar); + beginShape(); + vertex(0, -100); + bezierVertex(25, -100, 40, -65, 40, -40); + bezierVertex(40, -15, 25, 0, 0, 0); + bezierVertex(-25, 0, -40, -15, -40, -40); + bezierVertex(-40, -65, -25, -100, 0, -100); + endShape(); + pop(); +} +} + +class Ring { +start(xpos, ypos) { + this.x = xpos; + this.y = ypos; + this.on = true; + this.diameter = 1; +} + +grow() { + if (this.on == true) { + this.diameter += 0.5; + if (this.diameter > width * 2) { + this.diameter = 0.0; + } + } + } + +display() { + if (this.on == true) { + noFill(); + strokeWeight(4); + stroke(155, 153); + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} +} + +class EggRing { +constructor(x, y, t, sp) { + this.x = x; + this.y = y; + this.t = t; + this.sp = sp; + this.circle = new Ring(); + this.ovoid = new Egg(this.x, this.y, this.t, this.sp); + this.circle.start(this.x, this.y - this.sp/2); +} + +transmit() { + this.ovoid.wobble(); + this.ovoid.display(); + this.circle.grow(); + this.circle.display(); + if (circle.on == false) { + circle.on = true; + } +} +} diff --git a/dist/assets/examples/en/11_Objects/06_Car_Instances.js b/dist/assets/examples/en/11_Objects/06_Car_Instances.js new file mode 100644 index 0000000000..8e10eb089e --- /dev/null +++ b/dist/assets/examples/en/11_Objects/06_Car_Instances.js @@ -0,0 +1,83 @@ +/* + * @name Car Instances + * @arialabel Vertical pale sage background with three rectangles--blue, yellow, and grey--moving across the screen horizontally at different speeds + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to create three instances of Car Class and +invoke class methods.
+ A function is created for the canvas setup, and +3 car instances are initialized with different colors and canvas +positions. The speed of each car is set by passing value to the +instance’s start method. A second function calls class methods to +display and move the cars. +*/ +class Car { + /* Constructor expects parameters for + fill color, x and y coordinates that + will be used to initialize class properties. + */ + constructor(cColor, x, y) { + this.color = cColor; + this.doors = 4; + this.isConvertible = false; + this.x = x; + this.y = y; + this.speed = 0; + } + + start(speed) { // method expects parameter! + this.speed = speed; + } + + display() { // method! + fill(this.color); + rect(this.x, this.y, 20, 10); + } + + move() { // method! + this.x += this.speed; + // Wrap x around boundaries + if (this.x < -20) { + this.x = width; + } else if (this.x > width) { + this.x = -20; + } + } +} //end class Car + +let rav4; +let charger; +let nova; + +function setup() { + createCanvas(200, 400); + /* Construct the 3 Cars */ + //constructor expects cColor, x, y + rav4 = new Car("silver", 100, 300); + charger = new Car("gold", 0, 200); + nova = new Car("blue", 200, 100); + nova.doors = 2; //update nova's doors property + + console.log("rav4", rav4); + console.log("charger", charger); + console.log("nova", nova); + + //call start methods of Car instances + //the start method expects a number for speed + rav4.start(2.3); + charger.start(-4); + nova.start(random(-1, 1)); +} + +function draw() { + background("beige"); + + //display and move all 3 Cars + rav4.display(); + charger.display(); + nova.display(); + + rav4.move(); + charger.move(); + nova.move(); +} diff --git a/dist/assets/examples/en/12_Lights/02_Directional.js b/dist/assets/examples/en/12_Lights/02_Directional.js new file mode 100644 index 0000000000..2b6a74bb7b --- /dev/null +++ b/dist/assets/examples/en/12_Lights/02_Directional.js @@ -0,0 +1,28 @@ +/* + * @name Directional + * @arialabel Two spheres on both sides of a black screen that is lit by the mouse which acts as a light source. You can move this light source by moving your mouse to shine on different parts of the sphere and create different shadows + * @frame 710,400 + * @description Move the mouse to change the direction of the light. + * Directional light comes from one direction and is stronger when hitting a + * surface squarely and weaker if it hits at a a gentle angle. After hitting a + * surface, a directional light scatters in all directions. + */ +const radius = 200; + +function setup() { + createCanvas(710, 400, WEBGL); + noStroke(); + fill(200); +} + +function draw() { + noStroke(); + background(0); + const dirY = (mouseY / height - 0.5) * 4; + const dirX = (mouseX / width - 0.5) * 4; + directionalLight(204, 204, 204, dirX, dirY, 1); + translate(-1.5 * radius, 0, 0); + sphere(radius); + translate(3 * radius, 0, 0); + sphere(radius); +} diff --git a/dist/assets/examples/en/12_Lights/05_Mixture.js b/dist/assets/examples/en/12_Lights/05_Mixture.js new file mode 100644 index 0000000000..70b3461a4f --- /dev/null +++ b/dist/assets/examples/en/12_Lights/05_Mixture.js @@ -0,0 +1,45 @@ +/* + * @name Mixture + * @arialabel Cube where we can see three sides, one blue and two forest green on a black background. An orange light shines where your mouse is when it is placed in the cube + * @frame 710,400 (optional) + * @description Display a box with three different kinds of lights. + */ +function setup() { + createCanvas(710, 400, WEBGL); + noStroke(); +} + +function draw() { + background(0); + + // ambient light + ambientLight(0, 255/4, 0); + + // to set the light position, + // think of the world's coordinate as: + // -width/2,-height/2 -------- width/2,-height/2 + // | | + // | 0,0 | + // | | + // -width/2,height/2--------width/2,height/2 + + // blue directional light from the left + directionalLight(0, 0, 255, -1, 0, 0); + + // calculate distance from center to mouseX + let lightX = mouseX - width / 2; + let lightY = mouseY - height / 2; + + // red spotlight + // axis located at lightX, lightY, 500 + // axis direction of light: 0, 0, -1 + spotLight(255, 0, 0, lightX, lightY, 500, 0, 0, -1); + + // rotate on X axis + rotateX(-PI/4); + // rotate on Y axis + rotateY(PI/4); + + // place box on (0, 0, 0), size 100 + box(100); +} diff --git a/dist/assets/examples/en/13_Motion/01_non_orthogonal_reflection.js b/dist/assets/examples/en/13_Motion/01_non_orthogonal_reflection.js new file mode 100644 index 0000000000..3f07f8e469 --- /dev/null +++ b/dist/assets/examples/en/13_Motion/01_non_orthogonal_reflection.js @@ -0,0 +1,111 @@ +/* + * @name Non Orthogonal Reflection + * @arialabel A white circle bounces around a black screen and on a grey slanted floor leaving a white streak behind it. The grey slanted floor changes every couple of frames + * @frame 710,400 (optional) + * @description This is a port by David Blitz of the "Reflection 1" example from processing.org/examples + */ + +//Position of left hand side of floor +let base1; + +//Position of right hand side of floor +let base2; +//Length of floor +//let baseLength; + +// Variables related to moving ball +let position; +let velocity; +let r = 6; +let speed = 3.5; + +function setup() { + createCanvas(710, 400); + + fill(128); + base1 = createVector(0, height - 150); + base2 = createVector(width, height); + //createGround(); + + //start ellipse at middle top of screen + position = createVector(width / 2, 0); + + //calculate initial random velocity + velocity = p5.Vector.random2D(); + velocity.mult(speed); +} + +function draw() { + //draw background + fill(0, 12); + noStroke(); + rect(0, 0, width, height); + + //draw base + fill(200); + quad(base1.x, base1.y, base2.x, base2.y, base2.x, height, 0, height); + + //calculate base top normal + let baseDelta = p5.Vector.sub(base2, base1); + baseDelta.normalize(); + let normal = createVector(-baseDelta.y, baseDelta.x); + let intercept = p5.Vector.dot(base1, normal); + + //draw ellipse + noStroke(); + fill(255); + ellipse(position.x, position.y, r * 2, r * 2); + + //move ellipse + position.add(velocity); + + //normalized incidence vector + incidence = p5.Vector.mult(velocity, -1); + incidence.normalize(); + + // detect and handle collision with base + if (p5.Vector.dot(normal, position) > intercept) { + //calculate dot product of incident vector and base top + let dot = incidence.dot(normal); + + //calculate reflection vector + //assign reflection vector to direction vector + velocity.set( + 2 * normal.x * dot - incidence.x, + 2 * normal.y * dot - incidence.y, + 0 + ); + velocity.mult(speed); + + // draw base top normal at collision point + stroke(255, 128, 0); + line( + position.x, + position.y, + position.x - normal.x * 100, + position.y - normal.y * 100 + ); + } + //} + + // detect boundary collision + // right + if (position.x > width - r) { + position.x = width - r; + velocity.x *= -1; + } + // left + if (position.x < r) { + position.x = r; + velocity.x *= -1; + } + // top + if (position.y < r) { + position.y = r; + velocity.y *= -1; + + //randomize base top + base1.y = random(height - 100, height); + base2.y = random(height - 100, height); + } +} diff --git a/dist/assets/examples/en/13_Motion/02_Linear_Motion.js b/dist/assets/examples/en/13_Motion/02_Linear_Motion.js new file mode 100644 index 0000000000..f76560d1de --- /dev/null +++ b/dist/assets/examples/en/13_Motion/02_Linear_Motion.js @@ -0,0 +1,25 @@ +/* + * @name Linear + * @arialabel Horizontal white line on a black background traveling from the bottom to the top of the screen parallel to the x axis + * @frame 720,400 + * @description Changing a variable to create a moving line. + * When the line moves off the edge of the window, + * the variable is set to 0, which places the line back at the bottom of the screen. + */ + +let a; + +function setup() { + createCanvas(720, 400); + stroke(255); + a = height / 2; +} + +function draw() { + background(51); + line(0, a, width, a); + a = a - 0.5; + if (a < 0) { + a = height; + } +} diff --git a/dist/assets/examples/en/13_Motion/03_Bounce.js b/dist/assets/examples/en/13_Motion/03_Bounce.js new file mode 100644 index 0000000000..1267f8cfec --- /dev/null +++ b/dist/assets/examples/en/13_Motion/03_Bounce.js @@ -0,0 +1,45 @@ +/* + * @name Bounce + * @arialabel White circle moving on a grey background. When it hits the edge of the background window, it changes it’s direction + * @frame 720,400 + * @description When the shape hits the edge of the window, it reverses its direction. + */ + +let rad = 60; // Width of the shape +let xpos, ypos; // Starting position of shape + +let xspeed = 2.8; // Speed of the shape +let yspeed = 2.2; // Speed of the shape + +let xdirection = 1; // Left or Right +let ydirection = 1; // Top to Bottom + +function setup() { + createCanvas(720, 400); + noStroke(); + frameRate(30); + ellipseMode(RADIUS); + // Set the starting position of the shape + xpos = width / 2; + ypos = height / 2; +} + +function draw() { + background(102); + + // Update the position of the shape + xpos = xpos + xspeed * xdirection; + ypos = ypos + yspeed * ydirection; + + // Test to see if the shape exceeds the boundaries of the screen + // If it does, reverse its direction by multiplying by -1 + if (xpos > width - rad || xpos < rad) { + xdirection *= -1; + } + if (ypos > height - rad || ypos < rad) { + ydirection *= -1; + } + + // Draw the shape + ellipse(xpos, ypos, rad, rad); +} diff --git a/dist/assets/examples/en/13_Motion/04_Bouncy_Bubbles.js b/dist/assets/examples/en/13_Motion/04_Bouncy_Bubbles.js new file mode 100644 index 0000000000..2dba410120 --- /dev/null +++ b/dist/assets/examples/en/13_Motion/04_Bouncy_Bubbles.js @@ -0,0 +1,96 @@ +/* + * @name Bouncy Bubbles + * @arialabel Grey circles of varying sizes bounce off the sides of the canvas and each other, eventually settling on the bottom of the screen + * @frame 720,400 + * @description based on code from Keith Peters. Multiple-object collision.. + */ + +let numBalls = 13; +let spring = 0.05; +let gravity = 0.03; +let friction = -0.9; +let balls = []; + +function setup() { + createCanvas(720, 400); + for (let i = 0; i < numBalls; i++) { + balls[i] = new Ball( + random(width), + random(height), + random(30, 70), + i, + balls + ); + } + noStroke(); + fill(255, 204); +} + +function draw() { + background(0); + balls.forEach(ball => { + ball.collide(); + ball.move(); + ball.display(); + }); +} + +class Ball { + constructor(xin, yin, din, idin, oin) { + this.x = xin; + this.y = yin; + this.vx = 0; + this.vy = 0; + this.diameter = din; + this.id = idin; + this.others = oin; + } + + collide() { + for (let i = this.id + 1; i < numBalls; i++) { + // console.log(others[i]); + let dx = this.others[i].x - this.x; + let dy = this.others[i].y - this.y; + let distance = sqrt(dx * dx + dy * dy); + let minDist = this.others[i].diameter / 2 + this.diameter / 2; + // console.log(distance); + //console.log(minDist); + if (distance < minDist) { + //console.log("2"); + let angle = atan2(dy, dx); + let targetX = this.x + cos(angle) * minDist; + let targetY = this.y + sin(angle) * minDist; + let ax = (targetX - this.others[i].x) * spring; + let ay = (targetY - this.others[i].y) * spring; + this.vx -= ax; + this.vy -= ay; + this.others[i].vx += ax; + this.others[i].vy += ay; + } + } + } + + move() { + this.vy += gravity; + this.x += this.vx; + this.y += this.vy; + if (this.x + this.diameter / 2 > width) { + this.x = width - this.diameter / 2; + this.vx *= friction; + } else if (this.x - this.diameter / 2 < 0) { + this.x = this.diameter / 2; + this.vx *= friction; + } + if (this.y + this.diameter / 2 > height) { + this.y = height - this.diameter / 2; + this.vy *= friction; + } else if (this.y - this.diameter / 2 < 0) { + this.y = this.diameter / 2; + this.vy *= friction; + } + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/en/13_Motion/05_Brownian.js b/dist/assets/examples/en/13_Motion/05_Brownian.js new file mode 100644 index 0000000000..0860f72479 --- /dev/null +++ b/dist/assets/examples/en/13_Motion/05_Brownian.js @@ -0,0 +1,53 @@ +/* + * @name Brownian Motion + * @arialabel A continuous white line draws squiggles on a grey background, forming a random pattern + * @description Recording random movement as a continuous line. + * (ported from https://processing.org/examples/brownian.html) + */ + +let num = 2000; +let range = 6; + +// global variable +let i; + +let ax = []; +let ay = []; + +function setup() +{ + createCanvas(640, 360); + for(i = 0; i < num; i++) { + ax[i] = width/2; + ay[i] = height/2; + } + frameRate(30); +} + +function draw() +{ + background(51); + + // Shift all elements 1 place to the left + for( i = 1; i < num; i++) { + ax[i-1] = ax[i]; + ay[i-1] = ay[i]; + } + + // Put a new value at the end of the array + ax[num-1] += random(-range, range); + ay[num-1] += random(-range, range); + + // Constrain all points to the screen + ax[num-1] = constrain(ax[num-1], 0, width); + ay[num-1] = constrain(ay[num-1], 0, height); + + // Draw a line connecting the points + for( i=1; i -50; x -= 10) { + square.push(createVector(x, 50)); + } + // Left side + for (let y = 50; y > -50; y -= 10) { + square.push(createVector(-50, y)); + } +} + +function draw() { + background(51); + + // We will keep how far the vertices are from their target + let totalDistance = 0; + + // Look at each vertex + for (let i = 0; i < circle.length; i++) { + let v1; + // Are we lerping to the circle or square? + if (state) { + v1 = circle[i]; + } else { + v1 = square[i]; + } + // Get the vertex we will draw + let v2 = morph[i]; + // Lerp to the target + v2.lerp(v1, 0.1); + // Check how far we are from target + totalDistance += p5.Vector.dist(v1, v2); + } + + // If all the vertices are close, switch shape + if (totalDistance < 0.1) { + state = !state; + } + + // Draw relative to center + translate(width / 2, height / 2); + strokeWeight(4); + // Draw a polygon that makes up all the vertices + beginShape(); + noFill(); + stroke(255); + + morph.forEach(v => { + vertex(v.x, v.y); + }); + endShape(CLOSE); +} diff --git a/dist/assets/examples/en/13_Motion/07_Circle_Collision.js b/dist/assets/examples/en/13_Motion/07_Circle_Collision.js new file mode 100644 index 0000000000..3833e4210e --- /dev/null +++ b/dist/assets/examples/en/13_Motion/07_Circle_Collision.js @@ -0,0 +1,146 @@ +/* + * @name Circle Collision + * @arialabel One large light grey circle and one small grey circle collide and bounce off each other as they bounce off each other and off the edges of the dark grey background + * @frame 710,400 (optional) + * @description This is a port of the "Circle Collision" example from processing.org/examples
This example uses vectors for better visualization of physical Quantity + */ +class Ball { + constructor(x, y, r) { + this.position = new p5.Vector(x, y); + this.velocity = p5.Vector.random2D(); + this.velocity.mult(3); + this.r = r; + this.m = r * 0.1; + } + update() { + this.position.add(this.velocity); + } + + checkBoundaryCollision() { + if (this.position.x > width - this.r) { + this.position.x = width - this.r; + this.velocity.x *= -1; + } else if (this.position.x < this.r) { + this.position.x = this.r; + this.velocity.x *= -1; + } else if (this.position.y > height - this.r) { + this.position.y = height - this.r; + this.velocity.y *= -1; + } else if (this.position.y < this.r) { + this.position.y = this.r; + this.velocity.y *= -1; + } + } + + checkCollision(other) { + // Get distances between the balls components + let distanceVect = p5.Vector.sub(other.position, this.position); + + // Calculate magnitude of the vector separating the balls + let distanceVectMag = distanceVect.mag(); + + // Minimum distance before they are touching + let minDistance = this.r + other.r; + + if (distanceVectMag < minDistance) { + let distanceCorrection = (minDistance - distanceVectMag) / 2.0; + let d = distanceVect.copy(); + let correctionVector = d.normalize().mult(distanceCorrection); + other.position.add(correctionVector); + this.position.sub(correctionVector); + + // get angle of distanceVect + let theta = distanceVect.heading(); + // precalculate trig values + let sine = sin(theta); + let cosine = cos(theta); + + /* bTemp will hold rotated ball this.positions. You + just need to worry about bTemp[1] this.position*/ + let bTemp = [new p5.Vector(), new p5.Vector()]; + + /* this ball's this.position is relative to the other + so you can use the vector between them (bVect) as the + reference point in the rotation expressions. + bTemp[0].this.position.x and bTemp[0].this.position.y will initialize + automatically to 0.0, which is what you want + since b[1] will rotate around b[0] */ + bTemp[1].x = cosine * distanceVect.x + sine * distanceVect.y; + bTemp[1].y = cosine * distanceVect.y - sine * distanceVect.x; + + // rotate Temporary velocities + let vTemp = [new p5.Vector(), new p5.Vector()]; + + vTemp[0].x = cosine * this.velocity.x + sine * this.velocity.y; + vTemp[0].y = cosine * this.velocity.y - sine * this.velocity.x; + vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y; + vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x; + + /* Now that velocities are rotated, you can use 1D + conservation of momentum equations to calculate + the final this.velocity along the x-axis. */ + let vFinal = [new p5.Vector(), new p5.Vector()]; + + // final rotated this.velocity for b[0] + vFinal[0].x = + ((this.m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / + (this.m + other.m); + vFinal[0].y = vTemp[0].y; + + // final rotated this.velocity for b[0] + vFinal[1].x = + ((other.m - this.m) * vTemp[1].x + 2 * this.m * vTemp[0].x) / + (this.m + other.m); + vFinal[1].y = vTemp[1].y; + + // hack to avoid clumping + bTemp[0].x += vFinal[0].x; + bTemp[1].x += vFinal[1].x; + + /* Rotate ball this.positions and velocities back + Reverse signs in trig expressions to rotate + in the opposite direction */ + // rotate balls + let bFinal = [new p5.Vector(), new p5.Vector()]; + + bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y; + bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x; + bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y; + bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x; + + // update balls to screen this.position + other.position.x = this.position.x + bFinal[1].x; + other.position.y = this.position.y + bFinal[1].y; + + this.position.add(bFinal[0]); + + // update velocities + this.velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y; + this.velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x; + other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y; + other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x; + } + } + + display() { + noStroke(); + fill(204); + ellipse(this.position.x, this.position.y, this.r * 2, this.r * 2); + } +} +let balls = [new Ball(100, 400, 20), new Ball(700, 400, 80)]; +console.log(balls); +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(51); + for (let i = 0; i < balls.length; i++) { + let b = balls[i]; + b.update(); + b.display(); + b.checkBoundaryCollision(); + balls[0].checkCollision(balls[1]); + } +} diff --git a/dist/assets/examples/en/13_Motion/08_Moving_On_Curves.js b/dist/assets/examples/en/13_Motion/08_Moving_On_Curves.js new file mode 100644 index 0000000000..02c87c5c5f --- /dev/null +++ b/dist/assets/examples/en/13_Motion/08_Moving_On_Curves.js @@ -0,0 +1,48 @@ +/* + * @name Moving On Curves + * @arialabel White circle travels across the grey screen on the curve y=x^4. It leaves behind an outline of its path + * @frame 720,400 + * @description In this example, the circles moves along the curve y = x^4. + * Click the mouse to have it move to a new position. + */ + +let beginX = 20.0; // Initial x-coordinate +let beginY = 10.0; // Initial y-coordinate +let endX = 570.0; // Final x-coordinate +let endY = 320.0; // Final y-coordinate +let distX; // X-axis distance to move +let distY; // Y-axis distance to move +let exponent = 4; // Determines the curve +let x = 0.0; // Current x-coordinate +let y = 0.0; // Current y-coordinate +let step = 0.01; // Size of each step along the path +let pct = 0.0; // Percentage traveled (0.0 to 1.0) + +function setup() { + createCanvas(720, 400); + noStroke(); + distX = endX - beginX; + distY = endY - beginY; +} + +function draw() { + fill(0, 2); + rect(0, 0, width, height); + pct += step; + if (pct < 1.0) { + x = beginX + pct * distX; + y = beginY + pow(pct, exponent) * distY; + } + fill(255); + ellipse(x, y, 20, 20); +} + +function mousePressed() { + pct = 0.0; + beginX = x; + beginY = y; + endX = mouseX; + endY = mouseY; + distX = endX - beginX; + distY = endY - beginY; +} diff --git a/dist/assets/examples/en/15_Instance_Mode/01_Instantiating.js b/dist/assets/examples/en/15_Instance_Mode/01_Instantiating.js new file mode 100644 index 0000000000..07163bdb99 --- /dev/null +++ b/dist/assets/examples/en/15_Instance_Mode/01_Instantiating.js @@ -0,0 +1,36 @@ +/* + * @name Instantiation + * @arialabel White square in the upper left quadrant on black background + * @description Create a p5 instance, which keeps all variables + * out of the global scope of your page. + */ +let sketch = function(p) { + let x = 100; + let y = 100; + + p.setup = function() { + p.createCanvas(700, 410); + }; + + p.draw = function() { + p.background(0); + p.fill(255); + p.rect(x, y, 50, 50); + }; +}; + +let myp5 = new p5(sketch); + +// Compare to "global mode" +// let x = 100; +// let y = 100; + +// function setup() { +// createCanvas(200,200); +// } + +// function draw() { +// background(0); +// fill(255); +// ellipse(x,y,50,50); +// } diff --git a/dist/assets/examples/en/15_Instance_Mode/02_Instance_Container.js b/dist/assets/examples/en/15_Instance_Mode/02_Instance_Container.js new file mode 100644 index 0000000000..9675fdeaaf --- /dev/null +++ b/dist/assets/examples/en/15_Instance_Mode/02_Instance_Container.js @@ -0,0 +1,94 @@ +/* + * @norender + * @name Instance Container + * @description Optionally, you can specify a default container for the canvas + * and any other elements to append to with a second argument. You can give the + * ID of an element in your html, or an html node itself. + * + * Here are three different options for selecting a container + * DOM element. All DOM elements (canvas, buttons, divs, etc) created by p5 + * will be attached to the DOM element specified as the second argument to the + * p5() call. + */ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dist/assets/examples/en/16_Dom/03_Input_Button.js b/dist/assets/examples/en/16_Dom/03_Input_Button.js new file mode 100644 index 0000000000..f82a84d456 --- /dev/null +++ b/dist/assets/examples/en/16_Dom/03_Input_Button.js @@ -0,0 +1,39 @@ +/* + * @name Input and Button + * @arialabel “What is your name?” is written in the top left of the window with a text input box and a submit button under. After inputting text and submitting, the text submitted is generated multiple times to cover the background in a random formation in various shades of cyan. + * @description Input text and click the button to see it affect the the canvas. + */ +let input, button, greeting; + +function setup() { + // create canvas + createCanvas(710, 400); + + input = createInput(); + input.position(20, 65); + + button = createButton('submit'); + button.position(input.x + input.width, 65); + button.mousePressed(greet); + + greeting = createElement('h2', 'what is your name?'); + greeting.position(20, 5); + + textAlign(CENTER); + textSize(50); +} + +function greet() { + const name = input.value(); + greeting.html('hello ' + name + '!'); + input.value(''); + + for (let i = 0; i < 200; i++) { + push(); + fill(random(255), 255, 255); + translate(random(width), random(height)); + rotate(random(2 * PI)); + text(name, 0, 0); + pop(); + } +} diff --git a/dist/assets/examples/en/16_Dom/04_Slider.js b/dist/assets/examples/en/16_Dom/04_Slider.js new file mode 100644 index 0000000000..1628b88653 --- /dev/null +++ b/dist/assets/examples/en/16_Dom/04_Slider.js @@ -0,0 +1,31 @@ +/* + * @name Slider + * @arialabel The background starts off in a vibrant shade of purple with three sliders in the upper left corner labeled red, green, and blue. The user can drag each slider and the color of the background will change accordingly with the increase or decrease of each of these three colors. + * @description Move the sliders to control the R, G, B values of the background. + */ +let rSlider, gSlider, bSlider; + +function setup() { + // create canvas + createCanvas(710, 400); + textSize(15); + noStroke(); + + // create sliders + rSlider = createSlider(0, 255, 100); + rSlider.position(20, 20); + gSlider = createSlider(0, 255, 0); + gSlider.position(20, 50); + bSlider = createSlider(0, 255, 255); + bSlider.position(20, 80); +} + +function draw() { + const r = rSlider.value(); + const g = gSlider.value(); + const b = bSlider.value(); + background(r, g, b); + text('red', rSlider.x * 2 + rSlider.width, 35); + text('green', gSlider.x * 2 + gSlider.width, 65); + text('blue', bSlider.x * 2 + bSlider.width, 95); +} diff --git a/dist/assets/examples/en/16_Dom/07_Modify_DOM.js b/dist/assets/examples/en/16_Dom/07_Modify_DOM.js new file mode 100644 index 0000000000..40cd500b35 --- /dev/null +++ b/dist/assets/examples/en/16_Dom/07_Modify_DOM.js @@ -0,0 +1,55 @@ +/* + * @name Modifying the DOM + * @arialabel Words in black font jittering on a white background + * @frame 710,300 + * @description Create DOM elements and modify their properties every time + * draw() is called. + */ +let dancingWords = []; + +class DanceSpan { + constructor(element, x, y) { + element.position(x, y); + this.element = element; + this.x = x; + this.y = y; + } + + brownian() { + this.x += random(-6, 6); + this.y += random(-6, 6); + this.element.position(this.x, this.y); + } +} + +function setup() { + // This paragraph is created aside of the main block of code. + // It's to differentiate the creation of an element from its + // selection. Selected elements don't need to be created by + // p5js, they can be just plain HTML. + createP( + 'I learn in this Letter, that Don Peter of Aragon, ' + + ' comes this night to Messina' + ).addClass('text').hide(); + + // This line grabs the paragraph just created, but it would + // also grab any other elements with class 'text' in the HTML + // page. + const texts = selectAll('.text'); + + for (let i = 0; i < texts.length; i++) { + const paragraph = texts[i].html(); + const words = paragraph.split(' '); + for (let j = 0; j < words.length; j++) { + const spannedWord = createSpan(words[j]); + const dw = new DanceSpan(spannedWord, random(600), random(200)); + dancingWords.push(dw); + } + } +} + +function draw() { + for (let i = 0; i < dancingWords.length; i++) { + dancingWords[i].brownian(); + } +} diff --git a/dist/assets/examples/en/16_Dom/08_Video.js b/dist/assets/examples/en/16_Dom/08_Video.js new file mode 100644 index 0000000000..2b39aeadc8 --- /dev/null +++ b/dist/assets/examples/en/16_Dom/08_Video.js @@ -0,0 +1,30 @@ +/* + * @name Video + * @arialabel Video of fingers walking + * @frame 710,250 + * @description Load a video with multiple formats and toggle between playing + * and paused with a button press. + */ +let playing = false; +let fingers; +let button; + +function setup() { + noCanvas(); + // specify multiple formats for different browsers + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + button = createButton('play'); + button.mousePressed(toggleVid); // attach button listener +} + +// plays or pauses the video depending on current state +function toggleVid() { + if (playing) { + fingers.pause(); + button.html('play'); + } else { + fingers.loop(); + button.html('pause'); + } + playing = !playing; +} diff --git a/dist/assets/examples/en/16_Dom/09_Video_Canvas.js b/dist/assets/examples/en/16_Dom/09_Video_Canvas.js new file mode 100644 index 0000000000..42f867fe31 --- /dev/null +++ b/dist/assets/examples/en/16_Dom/09_Video_Canvas.js @@ -0,0 +1,28 @@ +/* + * @name Video Canvas + * @arialabel grey background with two identical videos playing. One in color and one in black and white. + * @description Load a video with multiple formats and draw it to the canvas. + * To run this example locally, you will need a running + * local server. + */ +let fingers; + +function setup() { + createCanvas(710, 400); + // specify multiple formats for different browsers + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.hide(); // by default video shows up in separate dom + // element. hide it and draw it to the canvas + // instead +} + +function draw() { + background(150); + image(fingers, 10, 10); // draw the video frame to canvas + filter(GRAY); + image(fingers, 150, 150); // draw a second copy to canvas +} + +function mousePressed() { + fingers.loop(); // set the video to loop and start playing +} diff --git a/dist/assets/examples/en/16_Dom/10_Video_Pixels.js b/dist/assets/examples/en/16_Dom/10_Video_Pixels.js new file mode 100644 index 0000000000..2d3b4681cb --- /dev/null +++ b/dist/assets/examples/en/16_Dom/10_Video_Pixels.js @@ -0,0 +1,33 @@ +/* + * @name Video Pixels + * @arialabel Video is turned into black circles to look like pixels. Pixel size increases as the user’s mouse is dragged to the right and decreases as the user’s mouse is dragged to the left + * @frame 320,240 + * @description Load a video, manipulate its pixels and draw to canvas. + * To run this example locally, you will need a running + * local server. + */ +let fingers; + +function setup() { + createCanvas(320, 240); + // specify multiple formats for different browsers + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.loop(); + fingers.hide(); + noStroke(); + fill(0); +} + +function draw() { + background(255); + fingers.loadPixels(); + const stepSize = round(constrain(mouseX / 8, 6, 32)); + for (let y = 0; y < height; y += stepSize) { + for (let x = 0; x < width; x += stepSize) { + const i = y * width + x; + const darkness = (255 - fingers.pixels[i * 4]) / 255; + const radius = stepSize * darkness; + ellipse(x, y, radius, radius); + } + } +} diff --git a/dist/assets/examples/en/16_Dom/11_Capture.js b/dist/assets/examples/en/16_Dom/11_Capture.js new file mode 100644 index 0000000000..8368132b19 --- /dev/null +++ b/dist/assets/examples/en/16_Dom/11_Capture.js @@ -0,0 +1,23 @@ +/* + * @name Video Capture + * @arialabel Takes feed from the user’s computer camera and displays it in the window + * @frame 710,240 + * @description Capture video from the webcam and display + * on the canvas as well with invert filter. Note that by + * default the capture feed shows up, too. You can hide the + * feed by uncommenting the capture.hide() line. + */ +let capture; + +function setup() { + createCanvas(390, 240); + capture = createCapture(VIDEO); + capture.size(320, 240); + //capture.hide(); +} + +function draw() { + background(255); + image(capture, 0, 0, 320, 240); + filter(INVERT); +} diff --git a/dist/assets/examples/en/16_Dom/12_Drop.js b/dist/assets/examples/en/16_Dom/12_Drop.js new file mode 100644 index 0000000000..f2a515a333 --- /dev/null +++ b/dist/assets/examples/en/16_Dom/12_Drop.js @@ -0,0 +1,34 @@ +/* + * @name Drop + * @arialabel Empty grey canvas that displays an image if it is dragged from the user’s computer to the grey canvas + * @description Drag an image file onto the canvas to see it displayed. + */ + +function setup() { + // create canvas + const c = createCanvas(710, 400); + background(100); + // Add an event for when a file is dropped onto the canvas + c.drop(gotFile); +} + +function draw() { + fill(255); + noStroke(); + textSize(24); + textAlign(CENTER); + text('Drag an image file onto the canvas.', width / 2, height / 2); + noLoop(); +} + +function gotFile(file) { + // If it's an image file + if (file.type === 'image') { + // Create an image DOM element but don't show it + const img = createImg(file.data).hide(); + // Draw the image onto the canvas + image(img, 0, 0, width, height); + } else { + console.log('Not an image file!'); + } +} diff --git a/dist/assets/examples/en/16_Dom/13_DOM_Form_Elements.js b/dist/assets/examples/en/16_Dom/13_DOM_Form_Elements.js new file mode 100644 index 0000000000..a08ef5dc15 --- /dev/null +++ b/dist/assets/examples/en/16_Dom/13_DOM_Form_Elements.js @@ -0,0 +1,153 @@ +/* + * @name DOM Form Elements + * @arialabel Light yellow box with “checked” written with form elements such as checking boxes, sliders, and empty text input below + * @frame 600,400 + * @description contributed by + Prof WM Harris, How to use p5 DOM form elements to create a slider, +button, checkbox, radio group, select menu, and entry field.
+Functions are created that include: the canvas +setup, checkbox creation with text, text box with text that projects +typed text onto canvas, slider with button, three selections which +project a rectangle in different areas on the canvas depending on +selection, and a drop down menu with font change. +*/ + +/* global variables */ +//p5 DOM form elements +let slider1; +let button1; +let checkbox1; +let radio1; +let select1; +let entry1; + +function setup() { + createCanvas(200, 200); + background("beige"); + + checkbox1 = createCheckbox("Check me"); + + createP(); //spacer with

tag + + createSpan("What's your name? "); //label for entry1 + // createInput([value], [type]) + // type: "text" (default), "number", + // "date", "password", "email", etc. + entry1 = createInput(); + //If text in the entry field changes, call + //the entryCallback function. + entry1.changed(entryCallback); + + createP(); //spacer with

tag + + //createSlider(min, max, [value], [step]) + slider1 = createSlider(10, 200); + + button1 = createButton("Press me"); //, "pressed"); + //Assign callback fcn for button1 + //when user clicks mouse on it + button1.mouseClicked(button1Clicked); + + createP(); //spacer with

tag + + radio1 = createRadio(); + + //.option([value], [contentLabel]) + //If 1 param, it's both content AND + //value. Values treated as strings. + radio1.option(1, "cranberries"); + radio1.option(2, "almonds"); + radio1.option(3, "gouda"); + + radio1.value("1"); //set init value + + createP(); //spacer with

tag + + select1 = createSelect(); + //.option([contentValue],[value]) + //If 1 param, it's both content AND + //value. Values treated as strings. + select1.option("Sans-serif"); + select1.option("Serif"); + select1.option("Fantasy"); + //If changed, call select1Changed + select1.changed(select1Changed); +} + +function draw() { + //get value from slider 1 + let gray = slider1.value(); + fill(gray); + + //If mouse in corner, turn on checkbox1 + if ((mouseX < width / 3) && + (mouseY < height / 3)) { + checkbox1.checked(true); + } + //Is checkbox1 checked? Say so. + if (checkbox1.checked()) { + text("CHECKED", 20, 40); + } + + switch (radio1.value()) { + //radio value is always a string + case "1": + rect(0, 0, width, 50); + break; + case "2": + rect(0, 70, width, 50); + break; + case "3": + rect(0, 140, width, 50); + break; + } +} + +//callback fcn for button1 +function button1Clicked() { + //reset slider value to 200 + slider1.value(200); +} + + +//callback fcn for select1 +function select1Changed() { + switch (select1.value()) { + case "Sans-serif": + textFont("sans-serif"); + break; + case "Serif": + textFont("serif"); + break; + case "Fantasy": + textFont("fantasy"); + break; + } +} + +//callback function for entry1 +function entryCallback() { + for (let i = 0; i < 25; i++) { + text(entry1.value(), random(width), + random(height)); + } + +} + +function mouseClicked() { + console.log("button1?", button1.value()); + console.log("checkbox1?", checkbox1.value()); + //Update .value of either? No visible change + //to a button or checkbox + checkbox1.value("Check again"); + button1.value("clicked?"); +} + +function keyTyped() { + switch (key) { + case "r": + //move slider1 value to 100 + slider1.value(100); + break; + } +} \ No newline at end of file diff --git a/dist/assets/examples/en/17_Drawing/00_Continuous_Lines.js b/dist/assets/examples/en/17_Drawing/00_Continuous_Lines.js new file mode 100644 index 0000000000..564c8cab35 --- /dev/null +++ b/dist/assets/examples/en/17_Drawing/00_Continuous_Lines.js @@ -0,0 +1,16 @@ +/* + * @name Continuous Lines + * @arialabel Thin white line draws on a dark grey background as the user clicks and drags their mouse + * @description Click and drag the mouse to draw a line. + */ +function setup() { + createCanvas(710, 400); + background(102); +} + +function draw() { + stroke(255); + if (mouseIsPressed === true) { + line(mouseX, mouseY, pmouseX, pmouseY); + } +} diff --git a/dist/assets/examples/en/17_Drawing/01_Pattern.js b/dist/assets/examples/en/17_Drawing/01_Pattern.js new file mode 100644 index 0000000000..5f32d33ae2 --- /dev/null +++ b/dist/assets/examples/en/17_Drawing/01_Pattern.js @@ -0,0 +1,28 @@ +/* + * @name Patterns + * @arialabel Continuous circles draw on a dark grey background as you move your mouse. The circles get bigger as you move your mouse faster and smaller as you move your mouse slower + * @description Move the cursor over the image to draw with a software tool + * which responds to the speed of the mouse. + */ +function setup() { + createCanvas(710, 400); + background(102); +} + +function draw() { + // Call the variableEllipse() method and send it the + // parameters for the current mouse position + // and the previous mouse position + variableEllipse(mouseX, mouseY, pmouseX, pmouseY); +} + +// The simple method variableEllipse() was created specifically +// for this program. It calculates the speed of the mouse +// and draws a small ellipse if the mouse is moving slowly +// and draws a large ellipse if the mouse is moving quickly + +function variableEllipse(x, y, px, py) { + let speed = abs(x - px) + abs(y - py); + stroke(speed); + ellipse(x, y, speed, speed); +} diff --git a/dist/assets/examples/en/17_Drawing/02_Pulses.js b/dist/assets/examples/en/17_Drawing/02_Pulses.js new file mode 100644 index 0000000000..2eec4a1736 --- /dev/null +++ b/dist/assets/examples/en/17_Drawing/02_Pulses.js @@ -0,0 +1,32 @@ +/* + * @name Pulses + * @arialabel Continuous black flowers with a white circle center draw on a dark grey background as you move your mouse. The circles get bigger as you move your mouse faster and smaller as you move your mouse slower. When you stop your mouse, the last flower rotates slightly. + * @description Software drawing instruments can follow a rhythm or abide by + * rules independent of drawn gestures. This is a form of collaborative drawing + * in which the draftsperson controls some aspects of the image and the software + * controls others. + */ +let angle = 0; + +function setup() { + createCanvas(710, 400); + background(102); + noStroke(); + fill(0, 102); +} + +function draw() { + // Draw only when mouse is pressed + if (mouseIsPressed === true) { + angle += 5; + let val = cos(radians(angle)) * 12.0; + for (let a = 0; a < 360; a += 75) { + let xoff = cos(radians(a)) * val; + let yoff = sin(radians(a)) * val; + fill(0); + ellipse(mouseX + xoff, mouseY + yoff, val, val); + } + fill(255); + ellipse(mouseX, mouseY, 2, 2); + } +} diff --git a/dist/assets/examples/en/18_Transform/00_Translate.js b/dist/assets/examples/en/18_Transform/00_Translate.js new file mode 100644 index 0000000000..dede423e77 --- /dev/null +++ b/dist/assets/examples/en/18_Transform/00_Translate.js @@ -0,0 +1,41 @@ +/* + * @name Translate + * @arialabel Two squares one white one black travel horizontally across a grey background. The black square moves faster than the white + * @description The translate() function allows objects to be + * moved to any location within the window. The first parameter + * sets the x-axis offset and the second parameter sets the + * y-axis offset. This example shows how transforms accumulate. + */ + +let x = 0; +let y = 0; +let dim = 80.0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(102); + // Animate by increasing our x value + x = x + 0.8; + // If the shape goes off the canvas, reset the position + if (x > width + dim) { + x = -dim; + } + + // Even though our rect command draws the shape with its + // center at the origin, translate moves it to the new + // x and y position + translate(x, height / 2 - dim / 2); + fill(255); + rect(-dim / 2, -dim / 2, dim, dim); + + // Transforms accumulate. Notice how this rect moves + // twice as fast as the other, but it has the same + // parameter for the x-axis value + translate(x, dim); + fill(0); + rect(-dim / 2, -dim / 2, dim, dim); +} diff --git a/dist/assets/examples/en/18_Transform/01_Scale.js b/dist/assets/examples/en/18_Transform/01_Scale.js new file mode 100644 index 0000000000..2ddafda414 --- /dev/null +++ b/dist/assets/examples/en/18_Transform/01_Scale.js @@ -0,0 +1,47 @@ +/* + * @name Scale + * @arialabel Two squares one white and one black grow and shrink on a grey background + * @description Paramenters for the scale() function are values + * specified as decimal percentages. For example, the method + * call scale(2.0) will increase the dimension of the shape by + * 200 percent. Objects always scale from the origin. This example + * shows how transforms accumulate and also how scale and translate + * interact depending on their order. + */ + +let a = 0.0; +let s = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + //Draw all rectangles from their center as opposed to + // the default upper left corner + rectMode(CENTER); +} + +function draw() { + background(102); + + //Slowly increase 'a' and then animate 's' with + //a smooth cyclical motion by finding the cosine of 'a' + a = a + 0.04; + s = cos(a) * 2; + + //Translate our rectangle from the origin to the middle of + //the canvas, then scale it with 's' + translate(width / 2, height / 2); + scale(s); + fill(51); + rect(0, 0, 50, 50); + + //Translate and scale are accumulating, so this translate + //moves the second rectangle further right than the first + //and the scale is getting doubled. Note that cosine is + //making 's' both negative and positive, thus it cycles + //from left to right. + translate(75, 0); + fill(255); + scale(s); + rect(0, 0, 50, 50); +} diff --git a/dist/assets/examples/en/18_Transform/02_Rotate.js b/dist/assets/examples/en/18_Transform/02_Rotate.js new file mode 100644 index 0000000000..b6a465e67e --- /dev/null +++ b/dist/assets/examples/en/18_Transform/02_Rotate.js @@ -0,0 +1,44 @@ +/* + * @name Rotate + * @arialabel White square on a dark grey background rotates side to side + * @description Rotating a square around the Z axis. + * To get the results you expect, send the rotate function angle + * parameters that are values between 0 and PI*2 (TWO_PI which is + * roughly 6.28). If you prefer to think about angles as degrees + * (0-360), you can use the radians() method to convert your values. + * For example: rotate(radians(90)) is identical to the statement + * rotate(PI/2). In this example, every even numbered second a jitter + * is added to the rotation. During odd seconds, rotation moves CW and + * CCW at the speed determined by the last jitter value. + */ + +let angle = 0.0; +let jitter = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255); + //Draw the rectangle from the center and it will also be the + //rotate around that center + rectMode(CENTER); +} + +function draw() { + background(51); + + // during even-numbered seconds (0, 2, 4, 6...) add jitter to + // the rotation + if (second() % 2 === 0) { + jitter = random(-0.1, 0.1); + } + //increase the angle value using the most recent jitter value + angle = angle + jitter; + //use cosine to get a smooth CW and CCW motion when not jittering + let c = cos(angle); + //move the shape to the center of the canvas + translate(width / 2, height / 2); + //apply the final rotation + rotate(c); + rect(0, 0, 180, 180); +} diff --git a/dist/assets/examples/en/18_Transform/03_Arm.js b/dist/assets/examples/en/18_Transform/03_Arm.js new file mode 100644 index 0000000000..d6a282449d --- /dev/null +++ b/dist/assets/examples/en/18_Transform/03_Arm.js @@ -0,0 +1,50 @@ +/* + * @name Arm + * @arialabel Two ovals connected at the end to form an arm shape. One end is fixed at the center of the black background. The arm shape moves in a circular motion as the mouse moves around the screen + * @description This example uses transform matrices to create + * an arm. The angle of each segment is controlled with the + * mouseX and mouseY position. The transformations applied to + * the first segment are also applied to the second segment + * because they are inside the same push() and + * pop() matrix group. + */ + +let x, y; +let angle1 = 0.0; +let angle2 = 0.0; +let segLength = 100; + +function setup() { + createCanvas(720, 400); + strokeWeight(30); + + //Stroke with a semi-transparent white + stroke(255, 160); + + //Position the "shoulder" of the arm in the center of the canvas + x = width * 0.5; + y = height * 0.5; +} + +function draw() { + background(0); + + //Change the angle of the segments according to the mouse positions + angle1 = (mouseX / float(width) - 0.5) * -TWO_PI; + angle2 = (mouseY / float(height) - 0.5) * PI; + + //use push and pop to "contain" the transforms. Note that + // even though we draw the segments using a custom function, + // the transforms still accumulate + push(); + segment(x, y, angle1); + segment(segLength, 0, angle2); + pop(); +} + +//a custom function for drawing segments +function segment(x, y, a) { + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); +} diff --git a/dist/assets/examples/en/19_Typography/00_Letters.js b/dist/assets/examples/en/19_Typography/00_Letters.js new file mode 100644 index 0000000000..acbfe5588f --- /dev/null +++ b/dist/assets/examples/en/19_Typography/00_Letters.js @@ -0,0 +1,65 @@ +/* + * @name Letters + * @arialabel Letters and characters on a grey background. All are white except the vowels are pink. + * @description Letters can be drawn to the screen by loading a font, setting + * its characteristics and then drawing the letters. This example uses a for + * loop and unicode reference numbers to automatically fill the canvas with + * characters in a grid. Vowels are selected and given a specific fill color. + */ +let font, + fontsize = 32; + +function preload() { + // Ensure the .ttf or .otf font stored in the assets directory + // is loaded before setup() and draw() are called + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // Set text characteristics + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // Set the gap between letters and the left and top margin + let gap = 52; + let margin = 10; + translate(margin * 4, margin * 4); + + // Set the counter to start at the character you want + // in this case 35, which is the # symbol + let counter = 35; + + // Loop as long as there is space on the canvas + for (let y = 0; y < height - gap; y += gap) { + for (let x = 0; x < width - gap; x += gap) { + // Use the counter to retrieve individual letters by their Unicode number + let letter = char(counter); + + // Add different color to the vowels and other characters + if ( + letter === 'A' || + letter === 'E' || + letter === 'I' || + letter === 'O' || + letter === 'U' + ) { + fill('#ed225d'); + } else { + fill(255); + } + + // Draw the letter to the screen + text(letter, x, y); + + // Increment the counter + counter++; + } + } +} diff --git a/dist/assets/examples/en/19_Typography/01_Words.js b/dist/assets/examples/en/19_Typography/01_Words.js new file mode 100644 index 0000000000..8304e785dd --- /dev/null +++ b/dist/assets/examples/en/19_Typography/01_Words.js @@ -0,0 +1,60 @@ +/* + * @name Words + * @arialabel Three columns of the words “ichi,” “ni,” “san,” and “shi” gradienting from black to white on a gray background. The first column is right aligned, the middle column is center aligned, and the left column is left aligned + * @description The text() function is used for writing words to the screen. + * The words can be aligned left, center, or right with the textAlign() + * function, and like with shapes, words can be colored with fill(). + */ +let font, + fontsize = 40; + +function preload() { + // Ensure the .ttf or .otf font stored in the assets directory + // is loaded before setup() and draw() are called + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // Set text characteristics + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // Align the text to the right + // and run drawWords() in the left third of the canvas + textAlign(RIGHT); + drawWords(width * 0.25); + + // Align the text in the center + // and run drawWords() in the middle of the canvas + textAlign(CENTER); + drawWords(width * 0.5); + + // Align the text to the left + // and run drawWords() in the right third of the canvas + textAlign(LEFT); + drawWords(width * 0.75); +} + +function drawWords(x) { + // The text() function needs three parameters: + // the text to draw, the horizontal position, + // and the vertical position + fill(0); + text('ichi', x, 80); + + fill(65); + text('ni', x, 150); + + fill(190); + text('san', x, 220); + + fill(255); + text('shi', x, 290); +} diff --git a/dist/assets/examples/en/19_Typography/02_Text_Rotation.js b/dist/assets/examples/en/19_Typography/02_Text_Rotation.js new file mode 100644 index 0000000000..69d49bec03 --- /dev/null +++ b/dist/assets/examples/en/19_Typography/02_Text_Rotation.js @@ -0,0 +1,63 @@ +/* + * @name Text Rotation + * @arialabel Three white lines on a black screen. One at 45 degrees, one at 270 degrees, and one line that turns clockwise and the degree label changes as the line turns. + * @description Draws letters to the screen and rotates them at different angles. + * (ported from https://processing.org/examples/textrotation.html) + */ + +let font, + fontsize = 32; + +let angleRotate = 0.0; + +function setup() { + createCanvas(710, 400); + background(0); + + // Ensure the .ttf or .otf font stored in the assets directory + // is loaded before setup() and draw() are called + font = loadFont('assets/SourceSansPro-Regular.otf'); + + // Set text characteristics + textFont(font); +} + +function draw() { + background(0); + + strokeWeight(1); + stroke(153); + + push(); + let angle1 = radians(45); + translate(100, 180); + rotate(angle1); + // Draw the letter to the screen + text("45 DEGREES", 0, 0); + line(0, 0, 150, 0); + pop(); + + push(); + let angle2 = radians(270); + translate(200, 180); + rotate(angle2); + // Draw the letter to the screen + text("270 DEGREES", 0, 0); + line(0, 0, 150, 0); + pop(); + + push(); + translate(440, 180); + rotate(radians(angleRotate)); + text(int(angleRotate) % 360 + " DEGREES ", 0, 0); + line(0, 0, 150, 0); + pop(); + + angleRotate += 0.25; + + stroke(255, 0, 0); + strokeWeight(4); + point(100, 180); + point(200, 180); + point(440, 180); +} diff --git a/dist/assets/examples/en/20_3D/00_geometries.js b/dist/assets/examples/en/20_3D/00_geometries.js new file mode 100644 index 0000000000..09afb9a92e --- /dev/null +++ b/dist/assets/examples/en/20_3D/00_geometries.js @@ -0,0 +1,61 @@ +/* + * @name Geometries + * @arialabel Six 3D shapes in neon gradient rotating on a white background. Shapes include cube, cylinder, ring, pyramid, sphere, and a plane. + * @description There are six 3D primitives in p5 now. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + + translate(-240, -100, 0); + normalMaterial(); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + plane(70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + box(70, 70, 70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cylinder(70, 70); + pop(); + + translate(-240 * 2, 200, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cone(70, 70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + torus(70, 20); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + sphere(70); + pop(); +} diff --git a/dist/assets/examples/en/20_3D/01_sine_cosine_in_3D.js b/dist/assets/examples/en/20_3D/01_sine_cosine_in_3D.js new file mode 100644 index 0000000000..3eb4293d6c --- /dev/null +++ b/dist/assets/examples/en/20_3D/01_sine_cosine_in_3D.js @@ -0,0 +1,29 @@ +/* + * @name Sine Cosine in 3D + * @arialabel Geometric spheres moving in different spiral shapes in a 3D space + * @description Sine, cosine and push / pop could be applied in 3D as well. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + rotateY(frameCount * 0.01); + + for (let j = 0; j < 5; j++) { + push(); + for (let i = 0; i < 80; i++) { + translate( + sin(frameCount * 0.001 + j) * 100, + sin(frameCount * 0.001 + j) * 100, + i * 0.1 + ); + rotateZ(frameCount * 0.002); + push(); + sphere(8, 6, 4); + pop(); + } + pop(); + } +} diff --git a/dist/assets/examples/en/20_3D/02_multiple_lights.js b/dist/assets/examples/en/20_3D/02_multiple_lights.js new file mode 100644 index 0000000000..7a9689965e --- /dev/null +++ b/dist/assets/examples/en/20_3D/02_multiple_lights.js @@ -0,0 +1,31 @@ +/* + * @name Multiple Lights + * @arialabel Rotating iridescent cube on the left of the screen and an iridescent sphere on the right. The user’s mouse acts as a light illuminating the shapes and can control the direction of the light + * @description All types of lights could be used in one sketch. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(50); + directionalLight(255, 0, 0, 0.25, 0.25, 0); + pointLight(0, 0, 255, locX, locY, 250); + + push(); + translate(-width / 4, 0, 0); + rotateZ(frameCount * 0.02); + rotateX(frameCount * 0.02); + specularMaterial(250); + box(100, 100, 100); + pop(); + + translate(width / 4, 0, 0); + ambientMaterial(250); + sphere(120, 64); +} diff --git a/dist/assets/examples/en/20_3D/03_materials.js b/dist/assets/examples/en/20_3D/03_materials.js new file mode 100644 index 0000000000..c2c6e0bfca --- /dev/null +++ b/dist/assets/examples/en/20_3D/03_materials.js @@ -0,0 +1,66 @@ +/* + * @name Materials + * @arialabel Four rings and one cube of various materials rotate on a black background. As the user’s mouse moves across the window, the position of the light changes. + * @description There are five types of materials supported. + * They respond to light differently. + * Move your mouse to change the light position. + */ +let img; +function setup() { + createCanvas(710, 400, WEBGL); + img = loadImage('assets/cat.jpg'); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(60, 60, 60); + pointLight(255, 255, 255, locX, locY, 100); + + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + texture(img); + box(80); + pop(); + + push(); + translate(-width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + fill(250, 0, 0); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + normalMaterial(); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(-width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + ambientMaterial(250); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + specularMaterial(250); + torus(80, 20, 64, 64); + pop(); +} diff --git a/dist/assets/examples/en/20_3D/04_textures.js b/dist/assets/examples/en/20_3D/04_textures.js new file mode 100644 index 0000000000..87d08f2f57 --- /dev/null +++ b/dist/assets/examples/en/20_3D/04_textures.js @@ -0,0 +1,41 @@ +/* + * @name Textures + * @arialabel One sphere and one cube rotating on a white background. The sphere is covered with a video display and the cube is covered with an image. + * @description Images and videos are supported for texture. + */ +// video source: https://vimeo.com/90312869 +let img; +let vid; +let theta = 0; + +function setup() { + createCanvas(710, 400, WEBGL); + + img = loadImage('assets/cat.jpg'); + vid = createVideo(['assets/360video_256crop_v2.mp4']); + vid.elt.muted = true; + vid.loop(); + vid.hide(); +} + +function draw() { + background(250); + translate(-220, 0, 0); + push(); + rotateZ(theta * mouseX * 0.001); + rotateX(theta * mouseX * 0.001); + rotateY(theta * mouseX * 0.001); + //pass image as texture + texture(vid); + sphere(150); + pop(); + translate(440, 0, 0); + push(); + rotateZ(theta * 0.1); + rotateX(theta * 0.1); + rotateY(theta * 0.1); + texture(img); + box(100, 100, 100); + pop(); + theta += 0.05; +} diff --git a/dist/assets/examples/en/20_3D/05_ray_casting.js b/dist/assets/examples/en/20_3D/05_ray_casting.js new file mode 100644 index 0000000000..e3a2515ca5 --- /dev/null +++ b/dist/assets/examples/en/20_3D/05_ray_casting.js @@ -0,0 +1,101 @@ +/* + * @name Ray Casting + * @arialabel White square in the middle of a screen split diagonally between light pink and dark pink. The white square is a back wall and the pinks form 4 other walls. The user’s mouse controls a circle which turns into a 3D bump as it moves along the walls close to the front. + * @description Original example by Jonathan Watson. + *

Detecting the position of the mouse in 3D space with ray casting. + */ +const objects = []; +let eyeZ; + +function setup() { + createCanvas(710, 400, WEBGL); + + eyeZ = height / 2 / tan((30 * PI) / 180); // The default distance the camera is away from the origin. + + objects.push(new IntersectPlane(1, 0, 0, -100, 0, 0)); // Left wall + objects.push(new IntersectPlane(1, 0, 0, 100, 0, 0)); // Right wall + objects.push(new IntersectPlane(0, 1, 0, 0, -100, 0)); // Bottom wall + objects.push(new IntersectPlane(0, 1, 0, 0, 100, 0)); // Top wall + objects.push(new IntersectPlane(0, 0, 1, 0, 0, 0)); // Back wall + + noStroke(); + ambientMaterial(250); +} + +function draw() { + background(0); + + // Lights + pointLight(255, 255, 255, 0, 0, 400); + ambientLight(244, 122, 158); + + // Left wall + push(); + translate(-100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // Right wall + push(); + translate(100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // Bottom wall + push(); + translate(0, 100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + // Top wall + push(); + translate(0, -100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + plane(200, 200); // Back wall + + const x = mouseX - width / 2; + const y = mouseY - height / 2; + + const Q = createVector(0, 0, eyeZ); // A point on the ray and the default position of the camera. + const v = createVector(x, y, -eyeZ); // The direction vector of the ray. + + let intersect; // The point of intersection between the ray and a plane. + let closestLambda = eyeZ * 10; // The draw distance. + + for (let x = 0; x < objects.length; x += 1) { + let object = objects[x]; + let lambda = object.getLambda(Q, v); // The value of lambda where the ray intersects the object + + if (lambda < closestLambda && lambda > 0) { + // Find the position of the intersection of the ray and the object. + intersect = p5.Vector.add(Q, p5.Vector.mult(v, lambda)); + closestLambda = lambda; + } + } + + // Cursor + push(); + translate(intersect); + fill(237, 34, 93); + sphere(10); + pop(); +} + +// Class for a plane that extends to infinity. +class IntersectPlane { + constructor(n1, n2, n3, p1, p2, p3) { + this.normal = createVector(n1, n2, n3); // The normal vector of the plane + this.point = createVector(p1, p2, p3); // A point on the plane + this.d = this.point.dot(this.normal); + } + + getLambda(Q, v) { + return (-this.d - this.normal.dot(Q)) / this.normal.dot(v); + } +} diff --git a/dist/assets/examples/en/20_3D/07_orbit_control.js b/dist/assets/examples/en/20_3D/07_orbit_control.js new file mode 100644 index 0000000000..7ae75b1650 --- /dev/null +++ b/dist/assets/examples/en/20_3D/07_orbit_control.js @@ -0,0 +1,37 @@ +/* + * @name Orbit Control + * @arialabel Users can click on the screen and drag to move themselves around a 3D space. It consists of a white background with columns of purple cubes and green pyramids arched in curves. + * @description Orbit control allows you to drag and move around the world. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + let radius = width * 1.5; + + //drag to move the world. + orbitControl(); + + normalMaterial(); + translate(0, 0, -600); + for (let i = 0; i <= 12; i++) { + for (let j = 0; j <= 12; j++) { + push(); + let a = (j / 12) * PI; + let b = (i / 12) * PI; + translate( + sin(2 * a) * radius * sin(b), + (cos(b) * radius) / 2, + cos(2 * a) * radius * sin(b) + ); + if (j % 2 === 0) { + cone(30, 30); + } else { + box(30, 30, 30); + } + pop(); + } + } +} diff --git a/dist/assets/examples/en/20_3D/08_basic_shader.js b/dist/assets/examples/en/20_3D/08_basic_shader.js new file mode 100644 index 0000000000..bf531490d2 --- /dev/null +++ b/dist/assets/examples/en/20_3D/08_basic_shader.js @@ -0,0 +1,28 @@ +/* + * @name Basic Shader + * @arialabel Background with a cyan to purple gradient + * @description This is a basic example showing how to load shaders in p5.js. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + +// this variable will hold our shader object +let theShader; + +function preload(){ + // load the shader + theShader = loadShader('assets/basic.vert', 'assets/basic.frag'); +} + +function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); +} + +function draw() { + // shader() sets the active shader with our shader + shader(theShader); + + // rect gives us some geometry on the screen + rect(0,0,width, height); +} diff --git a/dist/assets/examples/en/20_3D/09_shader_as_a_texture.js b/dist/assets/examples/en/20_3D/09_shader_as_a_texture.js new file mode 100644 index 0000000000..ba67dd8e89 --- /dev/null +++ b/dist/assets/examples/en/20_3D/09_shader_as_a_texture.js @@ -0,0 +1,69 @@ +/* + * @name Shader as a Texture + * @arialabel Sphere broken up into a square grid with a gradient in each grid. + * @description Shaders can be applied to 2D/3D shapes as textures. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + + // this variable will hold our shader object + let theShader; + // this variable will hold our createGraphics layer + let shaderTexture; + + let theta = 0; + + let x; + let y; + let outsideRadius = 200; + let insideRadius = 100; + + function preload(){ + // load the shader + theShader = loadShader('assets/texture.vert','assets/texture.frag'); + } + + function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); + + // initialize the createGraphics layers + shaderTexture = createGraphics(710, 400, WEBGL); + + // turn off the createGraphics layers stroke + shaderTexture.noStroke(); + + x = -50; + y = 0; + } + + function draw() { + + // instead of just setting the active shader we are passing it to the createGraphics layer + shaderTexture.shader(theShader); + + // here we're using setUniform() to send our uniform values to the shader + theShader.setUniform("resolution", [width, height]); + theShader.setUniform("time", millis() / 1000.0); + theShader.setUniform("mouse", [mouseX, map(mouseY, 0, height, height, 0)]); + + // passing the shaderTexture layer geometry to render on + shaderTexture.rect(0,0,width,height); + + background(255); + + // pass the shader as a texture + texture(shaderTexture); + + translate(-150, 0, 0); + push(); + rotateZ(theta * mouseX * 0.0001); + rotateX(theta * mouseX * 0.0001); + rotateY(theta * mouseX * 0.0001); + theta += 0.05; + sphere(125); + pop(); + + // passing a fifth parameter to ellipse for smooth edges in 3D + ellipse(260,0,200,200,100); + } diff --git a/dist/assets/examples/en/20_3D/10_passing_shader_uniforms.js b/dist/assets/examples/en/20_3D/10_passing_shader_uniforms.js new file mode 100644 index 0000000000..c01ea5da83 --- /dev/null +++ b/dist/assets/examples/en/20_3D/10_passing_shader_uniforms.js @@ -0,0 +1,34 @@ +/* + * @name Passing Shader Uniforms + * @arialabel Sage green shape in the middle of a dark purple background. As the user’s mouse moves left, the shape has less sides and as the user’s mouse moves right, the shape has more sides + * @description Uniforms are the way in which information is passed from p5 to the shader. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + + // this variable will hold our shader object + let theShader; + + function preload(){ + // load the shader + theShader = loadShader('assets/uniforms.vert', 'assets/uniforms.frag'); + } + + function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); + } + + function draw() { + // shader() sets the active shader with our shader + shader(theShader); + + // lets send the resolution, mouse, and time to our shader + // before sending mouse + time we modify the data so it's more easily usable by the shader + theShader.setUniform('resolution', [width, height]); + theShader.setUniform('mouse', map(mouseX, 0, width, 0, 7)); + theShader.setUniform('time', frameCount * 0.01); + + // rect gives us some geometry on the screen + rect(0,0,width, height); + } diff --git a/dist/assets/examples/en/20_3D/11_shader_using_webcam.js b/dist/assets/examples/en/20_3D/11_shader_using_webcam.js new file mode 100644 index 0000000000..b54a51c9a4 --- /dev/null +++ b/dist/assets/examples/en/20_3D/11_shader_using_webcam.js @@ -0,0 +1,38 @@ +/* + * @name Shader Using Webcam + * @arialabel Neon texture added to the scene displayed by the user’s built-in webcam + * @description The webcam can be passed to shaders as a texture. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + + // this variable will hold our shader object + let theShader; + // this variable will hold our webcam video + let cam; + + function preload(){ + // load the shader + theShader = loadShader('assets/webcam.vert', 'assets/webcam.frag'); + } + + function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); + + cam = createCapture(VIDEO); + cam.size(710, 400); + + cam.hide(); + } + + function draw() { + // shader() sets the active shader with our shader + shader(theShader); + + // passing cam as a texture + theShader.setUniform('tex0', cam); + + // rect gives us some geometry on the screen + rect(0,0,width,height); + } diff --git a/dist/assets/examples/en/21_Input/00_Clock.js b/dist/assets/examples/en/21_Input/00_Clock.js new file mode 100644 index 0000000000..c95fac761c --- /dev/null +++ b/dist/assets/examples/en/21_Input/00_Clock.js @@ -0,0 +1,63 @@ +/* + * @name Clock + * @arialabel Functioning pink clock on a grey background + * @description The current time can be read with the second(), + * minute(), and hour() functions. In this example, sin() and + * cos() values are used to set the position of the hands. + */ +let cx, cy; +let secondsRadius; +let minutesRadius; +let hoursRadius; +let clockDiameter; + +function setup() { + createCanvas(720, 400); + stroke(255); + + let radius = min(width, height) / 2; + secondsRadius = radius * 0.71; + minutesRadius = radius * 0.6; + hoursRadius = radius * 0.5; + clockDiameter = radius * 1.7; + + cx = width / 2; + cy = height / 2; +} + +function draw() { + background(230); + + // Draw the clock background + noStroke(); + fill(244, 122, 158); + ellipse(cx, cy, clockDiameter + 25, clockDiameter + 25); + fill(237, 34, 93); + ellipse(cx, cy, clockDiameter, clockDiameter); + + // Angles for sin() and cos() start at 3 o'clock; + // subtract HALF_PI to make them start at the top + let s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI; + let m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; + let h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI; + + // Draw the hands of the clock + stroke(255); + strokeWeight(1); + line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius); + strokeWeight(2); + line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius); + strokeWeight(4); + line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius); + + // Draw the minute ticks + strokeWeight(2); + beginShape(POINTS); + for (let a = 0; a < 360; a += 6) { + let angle = radians(a); + let x = cx + cos(angle) * secondsRadius; + let y = cy + sin(angle) * secondsRadius; + vertex(x, y); + } + endShape(); +} diff --git a/dist/assets/examples/en/21_Input/01_Constrain.js b/dist/assets/examples/en/21_Input/01_Constrain.js new file mode 100644 index 0000000000..f2e4ace449 --- /dev/null +++ b/dist/assets/examples/en/21_Input/01_Constrain.js @@ -0,0 +1,37 @@ +/* + * @name Constrain + * @arialabel Pink rectangle on a grey background. A user uses their mouse to move a white circle within the pink rectangle + * @description Move the mouse across the screen to move + * the circle. The program constrains the circle to its box. + */ +let mx = 1; +let my = 1; +let easing = 0.05; +let radius = 24; +let edge = 100; +let inner = edge + radius; + +function setup() { + createCanvas(720, 400); + noStroke(); + ellipseMode(RADIUS); + rectMode(CORNERS); +} + +function draw() { + background(230); + + if (abs(mouseX - mx) > 0.1) { + mx = mx + (mouseX - mx) * easing; + } + if (abs(mouseY - my) > 0.1) { + my = my + (mouseY - my) * easing; + } + + mx = constrain(mx, inner, width - inner); + my = constrain(my, inner, height - inner); + fill(237, 34, 93); + rect(edge, edge, width - edge, height - edge); + fill(255); + ellipse(mx, my, radius, radius); +} diff --git a/dist/assets/examples/en/21_Input/02_Easing.js b/dist/assets/examples/en/21_Input/02_Easing.js new file mode 100644 index 0000000000..79d78921bc --- /dev/null +++ b/dist/assets/examples/en/21_Input/02_Easing.js @@ -0,0 +1,31 @@ +/* + * @name Easing + * @arialabel Pink background with a white circle that the user can move around by hovering over the circle + * @description Move the mouse across the screen and the symbol + * will follow. Between drawing each frame of the animation, the + * program calculates the difference between the position of the + * symbol and the cursor. If the distance is larger than 1 pixel, + * the symbol moves part of the distance (0.05) from its current + * position toward the cursor. + */ +let x = 1; +let y = 1; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(237, 34, 93); + let targetX = mouseX; + let dx = targetX - x; + x += dx * easing; + + let targetY = mouseY; + let dy = targetY - y; + y += dy * easing; + + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/en/21_Input/03_Keyboard.js b/dist/assets/examples/en/21_Input/03_Keyboard.js new file mode 100644 index 0000000000..450a7ffb44 --- /dev/null +++ b/dist/assets/examples/en/21_Input/03_Keyboard.js @@ -0,0 +1,39 @@ +/* + * @name Keyboard + * @arialabel Each letter on the keyboard draws a different color rectangle on the grey screen when pressed + * @description Click on the image to give it focus and + * press the letter keys to create forms in time and space. + * Each key has a unique identifying number. These numbers + * can be used to position shapes in space. + */ +let rectWidth; + +function setup() { + createCanvas(720, 400); + noStroke(); + background(230); + rectWidth = width / 4; +} + +function draw() { + // keep draw() here to continue looping while waiting for keys +} + +function keyPressed() { + let keyIndex = -1; + if (key >= 'a' && key <= 'z') { + keyIndex = key.charCodeAt(0) - 'a'.charCodeAt(0); + } + if (keyIndex === -1) { + // If it's not a letter key, clear the screen + background(230); + } else { + // It's a letter key, fill a rectangle + randFill_r = Math.floor(Math.random() * 255 + 1); + randFill_g = Math.floor(Math.random() * 255 + 1); + randFill_b = Math.floor(Math.random() * 255 + 1); + fill(randFill_r, randFill_g, randFill_b); + let x = map(keyIndex, 0, 25, 0, width - rectWidth); + rect(x, 0, rectWidth, height); + } +} diff --git a/dist/assets/examples/en/21_Input/04_Milliseconds.js b/dist/assets/examples/en/21_Input/04_Milliseconds.js new file mode 100644 index 0000000000..2076f3e112 --- /dev/null +++ b/dist/assets/examples/en/21_Input/04_Milliseconds.js @@ -0,0 +1,23 @@ +/* + * @name Milliseconds + * @arialabel Background broken down in bars of various shades of grey. The fill of some of the bars randomly changes every millisecond to other shades of grey. + * @description A millisecond is 1/1000 of a second. Processing keeps track of the number of milliseconds a + * program has run. By modifying this number with the modulo(%) operator, different patterns in time are created. (ported from https://processing.org/examples/milliseconds.html) + */ + +let scale; + +function setup() { + createCanvas(720, 400); + noStroke(); + scale = width/20; +} + +function draw() { + let i; + for ( i = 0; i < scale; i++) { + colorMode(RGB, (i+1) * scale * 10); + fill(millis()%((i+1) * scale * 10)); + rect(i*scale, 0, scale, height); + } +} \ No newline at end of file diff --git a/dist/assets/examples/en/21_Input/05_Mouse1D.js b/dist/assets/examples/en/21_Input/05_Mouse1D.js new file mode 100644 index 0000000000..412dc4c466 --- /dev/null +++ b/dist/assets/examples/en/21_Input/05_Mouse1D.js @@ -0,0 +1,25 @@ +/* + * @name Mouse 1D + * @arialabel Two fuschia squares on a grey background. As the user’s mouse moves to the left of the window, the fuschia square on the left increases to fill up the left half of the window as the right square disappears and vice versa as the user’s mouse moves right. + * @description Move the mouse left and right to + * shift the balance. The "mouseX" variable is used + * to control both the size and color of the rectangles. + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + + let r1 = map(mouseX, 0, width, 0, height); + let r2 = height - r1; + + fill(237, 34, 93, r1); + rect(width / 2 + r1 / 2, height / 2, r1, r1); + + fill(237, 34, 93, r2); + rect(width / 2 - r2 / 2, height / 2, r2, r2); +} diff --git a/dist/assets/examples/en/21_Input/06_Mouse2D.js b/dist/assets/examples/en/21_Input/06_Mouse2D.js new file mode 100644 index 0000000000..4998706a06 --- /dev/null +++ b/dist/assets/examples/en/21_Input/06_Mouse2D.js @@ -0,0 +1,21 @@ +/* + * @name Mouse 2D + * @arialabel Two fuschia squares on a grey background. As the user’s mouse moves left, the squares rotate around each other in the left direction and vice versa as the user’s mouse moves right + * @description Moving the mouse changes the position and + * size of each box. + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + fill(244, 122, 158); + rect(mouseX, height / 2, mouseY / 2 + 10, mouseY / 2 + 10); + fill(237, 34, 93); + let inverseX = width - mouseX; + let inverseY = height - mouseY; + rect(inverseX, height / 2, inverseY / 2 + 10, inverseY / 2 + 10); +} diff --git a/dist/assets/examples/en/21_Input/07_Mouse_Functions.js b/dist/assets/examples/en/21_Input/07_Mouse_Functions.js new file mode 100644 index 0000000000..c2c5c4d2fb --- /dev/null +++ b/dist/assets/examples/en/21_Input/07_Mouse_Functions.js @@ -0,0 +1,67 @@ +/* + * @name Mouse Functions + * @arialabel Fuschia background with a slightly opaque white square. The user can click on the square, which turns it white, and drag it around the background. + * @description Click on the box and drag it across the screen. + */ +let bx; +let by; +let boxSize = 75; +let overBox = false; +let locked = false; +let xOffset = 0.0; +let yOffset = 0.0; + +function setup() { + createCanvas(720, 400); + bx = width / 2.0; + by = height / 2.0; + rectMode(RADIUS); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + // Test if the cursor is over the box + if ( + mouseX > bx - boxSize && + mouseX < bx + boxSize && + mouseY > by - boxSize && + mouseY < by + boxSize + ) { + overBox = true; + if (!locked) { + stroke(255); + fill(244, 122, 158); + } + } else { + stroke(156, 39, 176); + fill(244, 122, 158); + overBox = false; + } + + // Draw the box + rect(bx, by, boxSize, boxSize); +} + +function mousePressed() { + if (overBox) { + locked = true; + fill(255, 255, 255); + } else { + locked = false; + } + xOffset = mouseX - bx; + yOffset = mouseY - by; +} + +function mouseDragged() { + if (locked) { + bx = mouseX - xOffset; + by = mouseY - yOffset; + } +} + +function mouseReleased() { + locked = false; +} diff --git a/dist/assets/examples/en/21_Input/08_Mouse_Signals.js b/dist/assets/examples/en/21_Input/08_Mouse_Signals.js new file mode 100644 index 0000000000..2b61304295 --- /dev/null +++ b/dist/assets/examples/en/21_Input/08_Mouse_Signals.js @@ -0,0 +1,53 @@ +/* + * @name Mouse Signals + * @arialabel Three rows: fuschia on the top and bottom rows and white in the middle row. The top row tracks the x-coordinates of the mouse, the middle row tracks the y-coordinates, and the bottom row tracks whether or not the mouse is pressed. + * @description Move and click the mouse to generate signals. + * The top row is the signal from "mouseX", the middle row is + * the signal from "mouseY", and the bottom row is the signal + * from "mouseIsPressed". + */ +let xvals = []; +let yvals = []; +let bvals = []; + +function setup() { + createCanvas(720, 400); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + for (let i = 1; i < width; i++) { + xvals[i - 1] = xvals[i]; + yvals[i - 1] = yvals[i]; + bvals[i - 1] = bvals[i]; + } + // Add the new values to the end of the array + xvals[width - 1] = mouseX; + yvals[width - 1] = mouseY; + + if (mouseIsPressed) { + bvals[width - 1] = 0; + } else { + bvals[width - 1] = 255; + } + + fill(255); + noStroke(); + rect(0, height / 3, width, height / 3 + 1); + + for (let i = 1; i < width; i++) { + stroke(255); + point(i, xvals[i] / 3); + stroke(0); + point(i, height / 3 + yvals[i] / 3); + stroke(255); + line( + i, + (2 * height) / 3 + bvals[i] / 3, + i, + (2 * height) / 3 + bvals[i - 1] / 3 + ); + } +} diff --git a/dist/assets/examples/en/21_Input/09_MouseIsPressed.js b/dist/assets/examples/en/21_Input/09_MouseIsPressed.js new file mode 100644 index 0000000000..bc0a51a843 --- /dev/null +++ b/dist/assets/examples/en/21_Input/09_MouseIsPressed.js @@ -0,0 +1,21 @@ +/* + * @name Mouse Press + * @arialabel User draws pink crosses on a grey background and can change the cross color to white by clicking the mouse. + * @description Move the mouse to position the shape. + * Press the mouse button to invert the color. + */ +function setup() { + createCanvas(720, 400); + background(230); + strokeWeight(2); +} + +function draw() { + if (mouseIsPressed) { + stroke(255); + } else { + stroke(237, 34, 93); + } + line(mouseX - 66, mouseY, mouseX + 66, mouseY); + line(mouseX, mouseY - 66, mouseX, mouseY + 66); +} diff --git a/dist/assets/examples/en/21_Input/10_Rollover.js b/dist/assets/examples/en/21_Input/10_Rollover.js new file mode 100644 index 0000000000..449bda1689 --- /dev/null +++ b/dist/assets/examples/en/21_Input/10_Rollover.js @@ -0,0 +1,80 @@ +/* + * @name Rollover + * @arialabel Black square and white circle on grey background. The background turns black as the user’s mouth hovers over the black square and the background turns white as the user’s mouth hovers over the white square. + * @description Roll over the colored squares in the center of the image to change the color of the outside rectangle. + *

This example is ported from the Rollover example + * on the Processing website + */ +let squareX, squareY; // Position of square button +let circleX, circleY; // Position of circle button +let squareSize = 90; // Width/height of square +let circleSize = 93; // Diameter of circle + +let squareColor; +let circleColor; +let baseColor; + +let squareOver = false; +let circleOver = false; + +function setup() { + createCanvas(710, 400); + squareColor = color(0); + circleColor = color(255); + baseColor = color(102); + circleX = width/2+circleSize/2+10; + circleY = height/2; + squareX = width/2-squareSize-10; + squareY = height/2-squareSize/2; +} + +function draw() { + update(mouseX, mouseY); + + noStroke(); + if (squareOver) { + background(squareColor); + } else if (circleOver) { + background(circleColor); + } else { + background(baseColor); + } + + stroke(255); + fill(squareColor); + square(squareX, squareY, squareSize); + stroke(0); + fill(circleColor); + circle(circleX, circleY, circleSize); +} + +function update(x, y) { + if( overCircle(circleX, circleY, circleSize) ) { + circleOver = true; + squareOver = false; + } else if ( overSquare(squareX, squareY, squareSize) ) { + squareOver = true; + circleOver = false; + } else { + circleOver = squareOver = false; + } +} + +function overSquare(x, y, size) { + if (mouseX >= x && mouseX <= x+size && + mouseY >= y && mouseY <= y+size) { + return true; + } else { + return false; + } +} + +function overCircle(x, y, diameter) { + const disX = x - mouseX; + const disY = y - mouseY; + if(sqrt(sq(disX) + sq(disY)) < diameter/2 ) { + return true; + } else { + return false; + } +} \ No newline at end of file diff --git a/dist/assets/examples/en/21_Input/11_Storing_Input.js b/dist/assets/examples/en/21_Input/11_Storing_Input.js new file mode 100644 index 0000000000..4e76fded22 --- /dev/null +++ b/dist/assets/examples/en/21_Input/11_Storing_Input.js @@ -0,0 +1,39 @@ +/* + * @name Storing Input + * @arialabel User draws white circles on a fuschia background. Circles fade in color as the next circle is drawn. + * @description Move the mouse across the screen to + * change the position of the circles. The positions + * of the mouse are recorded into an array and played + * back every frame. Between each frame, the newest + * value are added to the end of each array and the + * oldest value is deleted. + */ +let num = 60; +let mx = []; +let my = []; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255, 153); + for (let i = 0; i < num; i++) { + mx.push(i); + my.push(i); + } +} + +function draw() { + background(237, 34, 93); + + // Cycle through the array, using a different entry on each frame. + // Using modulo (%) like this is faster than moving all the values over. + let which = frameCount % num; + mx[which] = mouseX; + my[which] = mouseY; + + for (let i = 0; i < num; i++) { + // which+1 is the smallest (the oldest in the array) + let index = (which + 1 + i) % num; + ellipse(mx[index], my[index], i, i); + } +} diff --git a/dist/assets/examples/en/22_Advanced_Data/00_Load_Saved_JSON.js b/dist/assets/examples/en/22_Advanced_Data/00_Load_Saved_JSON.js new file mode 100644 index 0000000000..7aab438794 --- /dev/null +++ b/dist/assets/examples/en/22_Advanced_Data/00_Load_Saved_JSON.js @@ -0,0 +1,105 @@ +/* + * @name Load Saved JSON + * @arialabel When the user clicks on the screen, a small white circle appears with a label + * @description Create a Bubble class, instantiate multiple bubbles using data from + * a JSON file, and display results on the screen. + * Because the web browsers differ in where they save files, we do not make use of + * saveJSON, unlike the Processing example.

+ * Based on Daniel Shiffman's LoadSaveJSON Example for Processing. + */ + +// Bubble class +class Bubble { + constructor(x, y, diameter, name) { + this.x = x; + this.y = y; + this.diameter = diameter; + this.radius = diameter / 2; + this.name = name; + + this.over = false; + } + + // Check if mouse is over the bubble + rollover(px, py) { + let d = dist(px, py, this.x, this.y); + this.over = d < this.radius; + } + + // Display the Bubble + display() { + stroke(0); + strokeWeight(0.8); + noFill(); + ellipse(this.x, this.y, this.diameter, this.diameter); + if (this.over) { + fill(0); + textAlign(CENTER); + text(this.name, this.x, this.y + this.radius + 20); + } + } +} + +let data = {}; // Global object to hold results from the loadJSON call +let bubbles = []; // Global array to hold all bubble objects + +// Put any asynchronous data loading in preload to complete before "setup" is run +function preload() { + data = loadJSON('assets/bubbles.json'); +} + +// Convert saved Bubble data into Bubble Objects +function loadData() { + let bubbleData = data['bubbles']; + for (let i = 0; i < bubbleData.length; i++) { + // Get each object in the array + let bubble = bubbleData[i]; + // Get a position object + let position = bubble['position']; + // Get x,y from position + let x = position['x']; + let y = position['y']; + + // Get diameter and label + let diameter = bubble['diameter']; + let label = bubble['label']; + + // Put object in array + bubbles.push(new Bubble(x, y, diameter, label)); + } +} + +// Create a new Bubble each time the mouse is clicked. +function mousePressed() { + // Add diameter and label to bubble + let diameter = random(40, 80); + let label = 'New Label'; + + // Append the new JSON bubble object to the array + bubbles.push(new Bubble(mouseX, mouseY, diameter, label)); + + // Prune Bubble Count if there are too many + if (bubbles.length > 10) { + bubbles.shift(); // remove first item from array + } +} + +function setup() { + createCanvas(640, 360); + loadData(); +} + +function draw() { + background(255); + + // Display all bubbles + for (let i = 0; i < bubbles.length; i++) { + bubbles[i].display(); + bubbles[i].rollover(mouseX, mouseY); + } + + // Label directions at bottom + textAlign(LEFT); + fill(0); + text('Click to add bubbles.', 10, height - 10); +} diff --git a/dist/assets/examples/en/22_Advanced_Data/01_Load_Saved_Table.js b/dist/assets/examples/en/22_Advanced_Data/01_Load_Saved_Table.js new file mode 100644 index 0000000000..3cd098bd82 --- /dev/null +++ b/dist/assets/examples/en/22_Advanced_Data/01_Load_Saved_Table.js @@ -0,0 +1,111 @@ +/* + * @name Load Saved Table + * @arialabel Four white circles with labels + * @description Create a Bubble class, instantiate multiple bubbles using data from + * a csv file, and display results on the screen. + * Because the web browsers differ in where they save files, we do not make use of + * + * Based on Daniel Shiffman's LoadSaveTable Example for Processing. + */ + +// Bubble class +class Bubble { + constructor(x, y, diameter, name) { + this.x = x; + this.y = y; + this.diameter = diameter; + this.radius = diameter / 2; + this.name = name; + + this.over = false; + } + + // Check if mouse is over the bubble + rollover(px, py) { + let d = dist(px, py, this.x, this.y); + this.over = d < this.radius; + } + + // Display the Bubble + display() { + stroke(0); + strokeWeight(0.8); + noFill(); + ellipse(this.x, this.y, this.diameter, this.diameter); + if (this.over) { + fill(0); + textAlign(CENTER); + text(this.name, this.x, this.y + this.radius + 20); + } + } +} + +let table; // Global object to hold results from the loadTable call +let bubbles = []; // Global array to hold all bubble objects + +// Put any asynchronous data loading in preload to complete before "setup" is run +function preload() { + table = loadTable("assets/bubbles.csv", "header"); +} + +// Convert saved Bubble data into Bubble Objects +function loadData() { + const bubbleData = table.getRows(); + // The size of the array of Bubble objects is determined by the total number of rows in the CSV + const length = table.getRowCount(); + + for (let i = 0; i < length; i++) { + // Get position, diameter, name, + const x = bubbleData[i].getNum("x"); + const y = bubbleData[i].getNum("y"); + const diameter = bubbleData[i].getNum("diameter"); + const name = bubbleData[i].getString("name"); + + // Put object in array + bubbles.push(new Bubble(x, y, diameter, name)); + } +} + +// Create a new Bubble each time the mouse is clicked. +function mousePressed() { + // Create a new row + let row = table.addRow(); + + let name = "New Bubble"; + let diameter = random(40, 80); + + // Set the values of that row + row.setNum("x", mouseX); + row.setNum("y", mouseY); + row.setNum("diameter", diameter); + row.setString("name", name); + + bubbles.push(new Bubble(mouseX, mouseY, diameter, name)); + + // If the table has more than 10 rows + if (table.getRowCount() > 10) { + // Delete the oldest row + table.removeRow(0); + bubbles.shift(); + } +} + +function setup() { + createCanvas(640, 360); + loadData(); +} + +function draw() { + background(255); + + // Display all bubbles + for (let i = 0; i < bubbles.length; i++) { + bubbles[i].display(); + bubbles[i].rollover(mouseX, mouseY); + } + + // Label directions at bottom + textAlign(LEFT); + fill(0); + text("Click to add bubbles.", 10, height - 10); +} diff --git a/dist/assets/examples/en/33_Sound/00_Load_and_Play_Sound.js b/dist/assets/examples/en/33_Sound/00_Load_and_Play_Sound.js new file mode 100644 index 0000000000..93b5855ec8 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/00_Load_and_Play_Sound.js @@ -0,0 +1,26 @@ +/* + * @name Load and Play Sound + * @arialabel Red screen turns green when the user clicks on it and plays music + * @description Load sound during preload(). Play a sound when canvas is clicked. + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server. + */ +let song; + +function setup() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); + createCanvas(720, 200); + background(255, 0, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() returns a boolean + song.stop(); + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/en/33_Sound/01_Preload_Sound.js b/dist/assets/examples/en/33_Sound/01_Preload_Sound.js new file mode 100644 index 0000000000..ff8034c009 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/01_Preload_Sound.js @@ -0,0 +1,35 @@ +/* + * @name Preload SoundFile + * @arialabel On page load, a green screen plays music. When the user clicks on it, the screen turns red and stops playing music + * @description Call loadSound() during preload() to ensure that the + * sound is completely loaded before setup() is called. It's best to always + * call loadSound() in preload(), otherwise sounds won't necessarily be loaded + * by the time you want to play them in your sketch. + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server. + */ + +let song; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); // song is ready to play during setup() because it was loaded during preload + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() returns a boolean + song.pause(); // .play() will resume from .pause() position + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/en/33_Sound/02_soundFormats.js b/dist/assets/examples/en/33_Sound/02_soundFormats.js new file mode 100644 index 0000000000..536efe0506 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/02_soundFormats.js @@ -0,0 +1,55 @@ +/** + * @name soundFormats + * @arialabel On page load, a green screen plays music. When the user clicks on it, the screen turns red and stops playing music + * @description

Technically, due to patent issues, there is no single + * sound format that is supported by all web browsers. While + * mp3 is supported across the + * latest versions of major browsers on OS X and Windows, for example, + * it may not be available on some less mainstream operating systems and + * browsers.

+ * + *

To ensure full compatibility, you can include the same sound file + * in multiple formats, e.g. 'sound.mp3' and 'sound.ogg'. (Ogg is an + * open source alternative to mp3.) You can convert audio files + * into web friendly formats for free online at media.io

. + * + *

The soundFormats() method tells loadSound which formats + * we have included with our sketch. Then, loadSound will + * attempt to load the first format that is supported by the + * client's web browser.

+ * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let song; + +function preload() { + // we have included both an .ogg file and an .mp3 file + soundFormats('ogg', 'mp3'); + + // if mp3 is not supported by this browser, + // loadSound will load the ogg file + // we have included with our sketch + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + + // song loaded during preload(), ready to play in setup() + song.play(); + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() returns a boolean + song.pause(); + background(255, 0, 0); + } else { + song.play(); // playback will resume from the pause position + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/en/33_Sound/03_Play_Mode.js b/dist/assets/examples/en/33_Sound/03_Play_Mode.js new file mode 100644 index 0000000000..f011f6bec1 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/03_Play_Mode.js @@ -0,0 +1,43 @@ +/* + * @name Play Mode + * @arialabel Yellow screen plays music when user clicks on it + * @description + *

In 'sustain' mode, the sound will overlap with itself. + * In 'restart' mode it will stop and then start again. + * Click mouse to play a sound file. + * Trigger lots of sounds at once! Press any key to change playmode.

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let playMode = 'sustain'; +let sample; + +function setup() { + createCanvas(710, 50); + soundFormats('mp3', 'ogg'); + sample = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3'); +} + +function draw() { + background(255, 255, 0); + let str = 'Click here to play! Press key to toggle play mode.'; + str += ' Current Play Mode: ' + playMode + '.'; + text(str, 10, height / 2); +} + +function mouseClicked() { + sample.play(); +} +function keyPressed(k) { + togglePlayMode(); +} + +function togglePlayMode() { + if (playMode === 'sustain') { + playMode = 'restart'; + } else { + playMode = 'sustain'; + } + sample.playMode(playMode); +} diff --git a/dist/assets/examples/en/33_Sound/04_Pan_SoundFile.js b/dist/assets/examples/en/33_Sound/04_Pan_SoundFile.js new file mode 100644 index 0000000000..e35f75a29c --- /dev/null +++ b/dist/assets/examples/en/33_Sound/04_Pan_SoundFile.js @@ -0,0 +1,35 @@ +/* + * @name Pan Sound + * @arialabel User moves a white ball on black screen, sound effect plays when the user clicks the screen and the sound comes out more of the speaker closer to the side the ball is on + * @description

Click mouse to play the sound. + * Ball position follows mouse and correlates to panning of sound.

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ * + */ +let ball = {}; +let soundFile; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beatbox.ogg'); +} + +function setup() { + createCanvas(710, 100); +} + +function draw() { + background(0); + ball.x = constrain(mouseX, 0, width); + ellipse(ball.x, height / 2, 100, 100); +} + +function mousePressed() { + // map the ball's x location to a panning degree + // between -1.0 (left) and 1.0 (right) + let panning = map(ball.x, 0, width, -1.0, 1.0); + soundFile.pan(panning); + soundFile.play(); +} diff --git a/dist/assets/examples/en/33_Sound/05_Sound_Effect.js b/dist/assets/examples/en/33_Sound/05_Sound_Effect.js new file mode 100644 index 0000000000..fd0cf56081 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/05_Sound_Effect.js @@ -0,0 +1,70 @@ +/* + * @name Sound Effect + * @arialabel Grey circle on a white screen that plays a doorbell sound when pressed on + * @description

Play a sound effect when the mouse is clicked inside the circle.

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +// Adapted from Learning Processing by Daniel Shiffman +// http://www.learningprocessing.com +// Doorbell sample by Corsica_S via freesound.org, +// Creative Commons BY 3.0 + +// A Class to describe a "doorbell" (really a button) +class Doorbell { + constructor(x_, y_, r_) { + // Location and size + this.x = x_; + this.y = y_; + this.r = r_; + } + // Is a point inside the doorbell? (used for mouse rollover, etc.) + contains(mx, my) { + return dist(mx, my, this.x, this.y) < this.r; + } + + // Show the doorbell (hardcoded colors, could be improved) + display(mx, my) { + if (this.contains(mx, my)) { + fill(100); + } else { + fill(175); + } + stroke(0); + strokeWeight(4); + ellipseMode(RADIUS); + ellipse(this.x, this.y, this.r, this.r); + } +} + +// A sound file object +let dingdong; + +// A doorbell object (that will trigger the sound) +let doorbell; + +function setup() { + createCanvas(200, 200); + + // Load the sound file. + // We have included both an MP3 and an OGG version. + soundFormats('mp3', 'ogg'); + dingdong = loadSound('assets/doorbell.mp3'); + + // Create a new doorbell + doorbell = new Doorbell(width / 2, height / 2, 32); +} + +function draw() { + background(255); + // Show the doorbell + doorbell.display(mouseX, mouseY); +} + +function mousePressed() { + // If the user clicks on the doorbell, play the sound! + if (doorbell.contains(mouseX, mouseY)) { + dingdong.play(); + } +} diff --git a/dist/assets/examples/en/33_Sound/06_Manipulate_Sound.js b/dist/assets/examples/en/33_Sound/06_Manipulate_Sound.js new file mode 100644 index 0000000000..9ad41eb08e --- /dev/null +++ b/dist/assets/examples/en/33_Sound/06_Manipulate_Sound.js @@ -0,0 +1,50 @@ +/* + * @name Playback Rate + * @arialabel Two grey circles on a light grey background that move as the user moves their mouse and plays different noises based on their distance from each other + * @description

Load a SoundFile and map its playback rate to + * mouseY, volume to mouseX. Playback rate is the speed with + * which the web audio context processings the sound file information. + * Slower rates not only increase the duration of the sound, but also + * decrease the pitch because it is being played back at a slower frequency.

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +// A sound file object +let song; + +function preload() { + // Load a sound file + song = loadSound('assets/Damscray_DancingTiger.mp3'); +} + +function setup() { + createCanvas(710, 400); + + // Loop the sound forever + // (well, at least until stop() is called) + song.loop(); +} + +function draw() { + background(200); + + // Set the volume to a range between 0 and 1.0 + let volume = map(mouseX, 0, width, 0, 1); + volume = constrain(volume, 0, 1); + song.amp(volume); + + // Set the rate to a range between 0.1 and 4 + // Changing the rate alters the pitch + let speed = map(mouseY, 0.1, height, 0, 2); + speed = constrain(speed, 0.01, 4); + song.rate(speed); + + // Draw some circles to show what is going on + stroke(0); + fill(51, 100); + ellipse(mouseX, 100, 48, 48); + stroke(0); + fill(51, 100); + ellipse(100, mouseY, 48, 48); +} diff --git a/dist/assets/examples/en/33_Sound/07_Amplitude_Analysis.js b/dist/assets/examples/en/33_Sound/07_Amplitude_Analysis.js new file mode 100644 index 0000000000..2b24248613 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/07_Amplitude_Analysis.js @@ -0,0 +1,51 @@ +/** + * @name Measuring Amplitude + * @arialabel Grey circle that increases and decreases in size based on the amplitude of the music playing + * @description

Analyze the amplitude of sound with + * p5.Amplitude.

+ * + *

Amplitude is the magnitude of vibration. Sound is vibration, + * so its amplitude is is closely related to volume / loudness.

+ * + *

The getLevel() method takes an array + * of amplitude values collected over a small period of time (1024 samples). + * Then it returns the Root Mean Square (RMS) of these values.

+ * + *

The original amplitude values for digital audio are between -1.0 and 1.0. + * But the RMS will always be positive, because it is squared. + * And, rather than use instantanous amplitude readings that are sampled at a rate + * of 44,100 times per second, the RMS is an average over time (1024 samples, in this case), + * which better represents how we hear amplitude. + *

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let song, analyzer; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); + + // create a new Amplitude analyzer + analyzer = new p5.Amplitude(); + + // Patch the input to an volume analyzer + analyzer.setInput(song); +} + +function draw() { + background(255); + + // Get the average (root mean square) amplitude + let rms = analyzer.getLevel(); + fill(127); + stroke(0); + + // Draw an ellipse with size based on volume + ellipse(width / 2, height / 2, 10 + rms * 200, 10 + rms * 200); +} diff --git a/dist/assets/examples/en/33_Sound/08_Noise_Envelope.js b/dist/assets/examples/en/33_Sound/08_Noise_Envelope.js new file mode 100644 index 0000000000..4c4d89905f --- /dev/null +++ b/dist/assets/examples/en/33_Sound/08_Noise_Envelope.js @@ -0,0 +1,55 @@ +/** + * @name Noise Drum Envelope + * @arialabel Lime green rectangle rises from the bottom of a black screen when the screen is clicked on and plays a sound effect + * @description

White Noise is a random audio signal with equal energy + * at every part of the frequency spectrum

+ * + *

An Envelope is a series of fades, defined + * as time / value pairs.

+ * + *

In this example, the p5.Env + * will be used to "play" the p5.Noise like a drum by controlling its output + * amplitude. A p5.Amplitude will get the level of all sound in the sketch, and + * we'll use this value to draw a green rectangle that shows the envelope + * in action.

+ *

To run this example locally, you will need the + * p5.sound library and a + * sound file.

+ */ +let noise, env, analyzer; + +function setup() { + createCanvas(710, 200); + noise = new p5.Noise(); // other types include 'brown' and 'pink' + noise.start(); + + // multiply noise volume by 0 + // (keep it quiet until we're ready to make noise!) + noise.amp(0); + + env = new p5.Env(); + // set attackTime, decayTime, sustainRatio, releaseTime + env.setADSR(0.001, 0.1, 0.2, 0.1); + // set attackLevel, releaseLevel + env.setRange(1, 0); + + // p5.Amplitude will analyze all sound in the sketch + // unless the setInput() method is used to specify an input. + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // get volume reading from the p5.Amplitude analyzer + let level = analyzer.getLevel(); + + // use level to draw a green rectangle + let levelHeight = map(level, 0, 0.4, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); +} + +function mousePressed() { + env.play(noise); +} diff --git a/dist/assets/examples/en/33_Sound/09_Note_Envelope.js b/dist/assets/examples/en/33_Sound/09_Note_Envelope.js new file mode 100644 index 0000000000..844105a528 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/09_Note_Envelope.js @@ -0,0 +1,62 @@ +/** + * @name Note Envelope + * @arialabel Red bars rise on the screen based on the amplitude and the note played + * @description

An Envelope is a series of fades, defined + * as time / value pairs. In this example, the envelope + * will be used to "play" a note by controlling the output + * amplitude of an oscillator.

+ * The p5.Oscillator sends its output through + * an internal Web Audio GainNode (p5.Oscillator.output). + * By default, that node has a constant value of 0.5. It can + * be reset with the osc.amp() method. Or, in this example, an + * Envelope takes control of that node, turning the amplitude + * up and down like a volume knob.

+ *

To run this example locally, you will need the + * p5.sound library and a + * sound file.

+ */ +let osc, envelope, fft; + +let scaleArray = [60, 62, 64, 65, 67, 69, 71, 72]; +let note = 0; + +function setup() { + createCanvas(710, 200); + osc = new p5.SinOsc(); + + // Instantiate the envelope + envelope = new p5.Env(); + + // set attackTime, decayTime, sustainRatio, releaseTime + envelope.setADSR(0.001, 0.5, 0.1, 0.5); + + // set attackLevel, releaseLevel + envelope.setRange(1, 0); + + osc.start(); + + fft = new p5.FFT(); + noStroke(); +} + +function draw() { + background(20); + + if (frameCount % 60 === 0 || frameCount === 1) { + let midiValue = scaleArray[note]; + let freqValue = midiToFreq(midiValue); + osc.freq(freqValue); + + envelope.play(osc, 0, 0.1); + note = (note + 1) % scaleArray.length; + } + + // plot FFT.analyze() frequency analysis on the canvas + let spectrum = fft.analyze(); + for (let i = 0; i < spectrum.length / 20; i++) { + fill(spectrum[i], spectrum[i] / 10, 0); + let x = map(i, 0, spectrum.length / 20, 0, width); + let h = map(spectrum[i], 0, 255, 0, height); + rect(x, height, spectrum.length / 20, -h); + } +} diff --git a/dist/assets/examples/en/33_Sound/10_Oscillator_Waveform.js b/dist/assets/examples/en/33_Sound/10_Oscillator_Waveform.js new file mode 100644 index 0000000000..ccc4e8086d --- /dev/null +++ b/dist/assets/examples/en/33_Sound/10_Oscillator_Waveform.js @@ -0,0 +1,41 @@ +/* + * @name Oscillator Frequency + * @arialabel The wavelength travels across the screen and as the user’s mouse moves left, the wavelength is longer and the frequency is slower and both increase as the mouse moves right + * @description

Control an Oscillator and view the waveform using FFT. + * MouseX is mapped to frequency, mouseY is mapped to amplitude.

+ *

To run this example locally, you will need the + * p5.sound library and a + * sound file.

+ */ +let osc, fft; + +function setup() { + createCanvas(720, 256); + + osc = new p5.TriOsc(); // set frequency and type + osc.amp(0.5); + + fft = new p5.FFT(); + osc.start(); +} + +function draw() { + background(255); + + let waveform = fft.waveform(); // analyze the waveform + beginShape(); + strokeWeight(5); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, height, 0); + vertex(x, y); + } + endShape(); + + // change oscillator frequency based on mouseX + let freq = map(mouseX, 0, width, 40, 880); + osc.freq(freq); + + let amp = map(mouseY, 0, height, 1, 0.01); + osc.amp(amp); +} diff --git a/dist/assets/examples/en/33_Sound/11_Live_Input.js b/dist/assets/examples/en/33_Sound/11_Live_Input.js new file mode 100644 index 0000000000..091302632a --- /dev/null +++ b/dist/assets/examples/en/33_Sound/11_Live_Input.js @@ -0,0 +1,37 @@ +/** + * @name Mic Input + * @arialabel Grey circle rises from the bottom of the screen based on the amplitude of the user’s audio input into their mic + * @description

Get audio input from your computer's microphone. + * Make noise to float the ellipse.

+ *

Note: p5.AudioIn contains its own p5.Amplitude object, + * so you can call getLevel on p5.AudioIn without + * creating a p5.Amplitude.

+ *

To run this example locally, you will need the + * p5.sound library + * and a running local server.

+ */ +let mic; + +function setup() { + createCanvas(710, 200); + + // Create an Audio input + mic = new p5.AudioIn(); + + // start the Audio Input. + // By default, it does not .connect() (to the computer speakers) + mic.start(); +} + +function draw() { + background(200); + + // Get the overall volume (between 0 and 1.0) + let vol = mic.getLevel(); + fill(127); + stroke(0); + + // Draw an ellipse with height based on volume + let h = map(vol, 0, 1, height, 0); + ellipse(width / 2, h - 25, 50, 50); +} diff --git a/dist/assets/examples/en/33_Sound/12_FFT_Spectrum.js b/dist/assets/examples/en/33_Sound/12_FFT_Spectrum.js new file mode 100644 index 0000000000..46c7b05c6e --- /dev/null +++ b/dist/assets/examples/en/33_Sound/12_FFT_Spectrum.js @@ -0,0 +1,31 @@ +/** + * @name Frequency Spectrum + * @arialabel Audio waves are graphed on a grey screen based on the user’s audio input into their mic + * @description

Visualize the frequency spectrum of live audio input.

+ *

To run this example locally, you will need the + * p5.sound library + * and a running local server.

+ */ +let mic, fft; + +function setup() { + createCanvas(710, 400); + noFill(); + + mic = new p5.AudioIn(); + mic.start(); + fft = new p5.FFT(); + fft.setInput(mic); +} + +function draw() { + background(200); + + let spectrum = fft.analyze(); + + beginShape(); + for (i = 0; i < spectrum.length; i++) { + vertex(i, map(spectrum[i], 0, 255, height, 0)); + } + endShape(); +} diff --git a/dist/assets/examples/en/33_Sound/13_Mic_Threshold.js b/dist/assets/examples/en/33_Sound/13_Mic_Threshold.js new file mode 100644 index 0000000000..9cf48ef5f7 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/13_Mic_Threshold.js @@ -0,0 +1,50 @@ +/** + * @name Mic Threshold + * @arialabel Black rectangle is drawn on the bottom of a bar based on the amplitude of the user’s audio input. At a certain minimum amplitude, grey squares are randomly drawn on the right side of the screen + * @description

Trigger an event (draw a rectangle) when the Audio Input + * volume surpasses a threshold.

+ *

To run this example locally, you will need the + * p5.sound library + * and a running local server.

+ */ +// Adapted from Learning Processing, Daniel Shiffman +// learningprocessing.com +let input; +let analyzer; + +function setup() { + createCanvas(710, 200); + background(255); + + // Create an Audio input + input = new p5.AudioIn(); + + input.start(); +} + +function draw() { + // Get the overall volume (between 0 and 1.0) + let volume = input.getLevel(); + + // If the volume > 0.1, a rect is drawn at a random location. + // The louder the volume, the larger the rectangle. + let threshold = 0.1; + if (volume > threshold) { + stroke(0); + fill(0, 100); + rect(random(40, width), random(height), volume * 50, volume * 50); + } + + // Graph the overall potential volume, w/ a line at the threshold + let y = map(volume, 0, 1, height, 0); + let ythreshold = map(threshold, 0, 1, height, 0); + + noStroke(); + fill(175); + rect(0, 0, 20, height); + // Then draw a rectangle on the graph, sized according to volume + fill(0); + rect(0, y, 20, y); + stroke(0); + line(0, ythreshold, 19, ythreshold); +} diff --git a/dist/assets/examples/en/33_Sound/14_Filter_LowPass.js b/dist/assets/examples/en/33_Sound/14_Filter_LowPass.js new file mode 100644 index 0000000000..4eaadf5a10 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/14_Filter_LowPass.js @@ -0,0 +1,63 @@ +/** + * @name Filter LowPass + * @arialabel The lowpass filter changes intensity as the user’s mouse moves left and right on the screen + * @description Apply a p5.LowPass filter to a p5.SoundFile. + * Visualize the sound with FFT. + * Map mouseX to the the filter's cutoff frequency + * and mouseY to resonance/width of the a BandPass filter + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let soundFile; +let fft; + +let filter, filterFreq, filterRes; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beat'); +} + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + // loop the sound file + soundFile.loop(); + + filter = new p5.LowPass(); + + // Disconnect soundfile from master output. + // Then, connect it to the filter, so that we only hear the filtered sound + soundFile.disconnect(); + soundFile.connect(filter); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // Map mouseX to a the cutoff frequency from the lowest + // frequency (10Hz) to the highest (22050Hz) that humans can hear + filterFreq = map(mouseX, 0, width, 10, 22050); + + // Map mouseY to resonance (volume boost) at the cutoff frequency + filterRes = map(mouseY, 0, height, 15, 5); + + // set filter parameters + filter.set(filterFreq, filterRes); + + // Draw every value in the FFT spectrum analysis where + // x = lowest (10Hz) to highest (22050Hz) frequencies, + // h = energy (amplitude / volume) at that frequency + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/en/33_Sound/15_Filter_BandPass.js b/dist/assets/examples/en/33_Sound/15_Filter_BandPass.js new file mode 100644 index 0000000000..35d10b146a --- /dev/null +++ b/dist/assets/examples/en/33_Sound/15_Filter_BandPass.js @@ -0,0 +1,52 @@ +/** + * @name Filter BandPass + * @arialabel The bandpass filter changes intensity as the user’s mouse moves left and right on the screen + * @description Apply a p5.BandPass filter to white noise. + * Visualize the sound with FFT. + * Map mouseX to the bandpass frequency + * and mouseY to resonance/width of the a BandPass filter + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let noise; +let fft; +let filter, filterFreq, filterWidth; + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + filter = new p5.BandPass(); + + noise = new p5.Noise(); + + noise.disconnect(); // Disconnect soundfile from master output... + filter.process(noise); // ...and connect to filter so we'll only hear BandPass. + noise.start(); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // Map mouseX to a bandpass freq from the FFT spectrum range: 10Hz - 22050Hz + filterFreq = map(mouseX, 0, width, 10, 22050); + // Map mouseY to resonance/width + filterWidth = map(mouseY, 0, height, 0, 90); + // set filter parameters + filter.set(filterFreq, filterWidth); + + // Draw every value in the FFT spectrum analysis where + // x = lowest (10Hz) to highest (22050Hz) frequencies, + // h = energy / amplitude at that frequency + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/en/33_Sound/16_Delay.js b/dist/assets/examples/en/33_Sound/16_Delay.js new file mode 100644 index 0000000000..15e2336106 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/16_Delay.js @@ -0,0 +1,57 @@ +/** + * @name Delay + * @arialabel When the user clicks their mouse on the black screen, music plays, and a lime green rectangle appears from the bottom at a height level correlating with the amplitude of the sound as it plays + * @description + * Click the mouse to hear the p5.Delay process a SoundFile. + * MouseX controls the p5.Delay Filter Frequency. + * MouseY controls both the p5.Delay Time and Resonance. + * Visualize the resulting sound's volume with an Amplitude object. + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ + +let soundFile, analyzer, delay; + +function preload() { + soundFormats('ogg', 'mp3'); + soundFile = loadSound('assets/beatbox.mp3'); +} + +function setup() { + createCanvas(710, 400); + + soundFile.disconnect(); // so we'll only hear delay + + delay = new p5.Delay(); + delay.process(soundFile, 0.12, 0.7, 2300); + delay.setType('pingPong'); // a stereo effect + + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // get volume reading from the p5.Amplitude analyzer + let level = analyzer.getLevel(); + + // use level to draw a green rectangle + let levelHeight = map(level, 0, 0.1, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); + + let filterFreq = map(mouseX, 0, width, 60, 15000); + filterFreq = constrain(filterFreq, 60, 15000); + let filterRes = map(mouseY, 0, height, 3, 0.01); + filterRes = constrain(filterRes, 0.01, 3); + delay.filter(filterFreq, filterRes); + let delTime = map(mouseY, 0, width, 0.2, 0.01); + delTime = constrain(delTime, 0.01, 0.2); + delay.delayTime(delTime); +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/en/33_Sound/17_Reverb.js b/dist/assets/examples/en/33_Sound/17_Reverb.js new file mode 100644 index 0000000000..b8e297253f --- /dev/null +++ b/dist/assets/examples/en/33_Sound/17_Reverb.js @@ -0,0 +1,37 @@ +/** + * @name Reverb + * @arialabel When the user clicks on the black screen, sound with reverb is played + * @description Reverb gives depth and perceived space to a sound. Here, + * noise is processed with reverb. + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let sound, reverb; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/Damscray_DancingTiger'); + + // disconnect the default connection + // so that we only hear the sound via the reverb.process + soundFile.disconnect(); +} + +function setup() { + createCanvas(720, 100); + background(0); + + reverb = new p5.Reverb(); + + // sonnects soundFile to reverb with a + // reverbTime of 6 seconds, decayRate of 0.2% + reverb.process(soundFile, 6, 0.2); + + reverb.amp(4); // turn it up! +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/en/33_Sound/18_Convolution_Reverb.js b/dist/assets/examples/en/33_Sound/18_Convolution_Reverb.js new file mode 100644 index 0000000000..2e40973ed2 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/18_Convolution_Reverb.js @@ -0,0 +1,88 @@ +/** + * @name Convolution Reverb + * @arialabel Sound with reverb plays when the user clicks the screen and lime green bars appear based on the amplitude of the sound + * @description

The p5.Convolver can recreate the sound of actual + * spaces using convolution. Convolution takes an Impulse Response, + * (the sound of a room reverberating), and uses that to + * recreate the sound of that space.

Click to play a sound through + * convolution. Every time you click, the sound is convolved with + * a different Impulse Response. To hear the Impulse Response itself, + * press any key.

+ * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server. + * These convolution samples are Creative Commons BY + * + * recordinghopkins

+ */ +let sound, env, cVerb, fft; +let currentIR = 0; +let rawImpulse; + +function preload() { + // we have included both MP3 and OGG versions of all the impulses/sounds + soundFormats('ogg', 'mp3'); + + // create a p5.Convolver + cVerb = createConvolver('assets/bx-spring'); + + // add Impulse Responses to cVerb.impulses array, in addition to bx-spring + cVerb.addImpulse('assets/small-plate'); + cVerb.addImpulse('assets/drum'); + cVerb.addImpulse('assets/beatbox'); + cVerb.addImpulse('assets/concrete-tunnel'); + + // load a sound that will be processed by the p5.ConvultionReverb + sound = loadSound('assets/Damscray_DancingTiger'); +} + +function setup() { + createCanvas(710, 400); + rawImpulse = loadSound('assets/' + cVerb.impulses[currentIR].name); + + // disconnect from master output... + sound.disconnect(); + // ... and process with cVerb + // so that we only hear the reverb + cVerb.process(sound); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + fill(0, 255, 40); + + let spectrum = fft.analyze(); + + // Draw every value in the frequencySpectrum array as a rectangle + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} + +function mousePressed() { + // cycle through the array of cVerb.impulses + currentIR++; + if (currentIR >= cVerb.impulses.length) { + currentIR = 0; + } + cVerb.toggleImpulse(currentIR); + + // play the sound through the impulse + sound.play(); + + // display the current Impulse Response name (the filepath) + println('Convolution Impulse Response: ' + cVerb.impulses[currentIR].name); + + rawImpulse.setPath('assets/' + cVerb.impulses[currentIR].name); +} + +// play the impulse (without convolution) +function keyPressed() { + rawImpulse.play(); +} diff --git a/dist/assets/examples/en/33_Sound/19_Record_Save.js b/dist/assets/examples/en/33_Sound/19_Record_Save.js new file mode 100644 index 0000000000..a7d8af4a38 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/19_Record_Save.js @@ -0,0 +1,59 @@ +/** + * @name Record Save Audio + * @arialabel The user clicks the grey screen to begin recording audio input through their mic. When recording the screen turns red. The user clicks their mouse again to end recording and the screen turns green. If the user clicks their mouse again the audio recording is saved to their downloads as a wav file + * @description Record a sound, play it back and save + * it as a .wav file to the client's computer. + * We need three objects: a p5.AudioIn (mic / sound source), + * p5.SoundRecorder (records the sound), and a + * p5.SoundFile (play back / save). + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let mic, recorder, soundFile; + +let state = 0; // mousePress will increment from Record, to Stop, to Play + +function setup() { + createCanvas(400, 400); + background(200); + fill(0); + text('Enable mic and click the mouse to begin recording', 20, 20); + + // create an audio in + mic = new p5.AudioIn(); + + // users must manually enable their browser microphone for recording to work properly! + mic.start(); + + // create a sound recorder + recorder = new p5.SoundRecorder(); + + // connect the mic to the recorder + recorder.setInput(mic); + + // create an empty sound file that we will use to playback the recording + soundFile = new p5.SoundFile(); +} + +function mousePressed() { + // use the '.enabled' boolean to make sure user enabled the mic (otherwise we'd record silence) + if (state === 0 && mic.enabled) { + // Tell recorder to record to a p5.SoundFile which we will use for playback + recorder.record(soundFile); + + background(255, 0, 0); + text('Recording now! Click to stop.', 20, 20); + state++; + } else if (state === 1) { + recorder.stop(); // stop recorder, and send the result to soundFile + + background(0, 255, 0); + text('Recording stopped. Click to play & save', 20, 20); + state++; + } else if (state === 2) { + soundFile.play(); // play the result! + saveSound(soundFile, 'mySound.wav'); // save file + state++; + } +} diff --git a/dist/assets/examples/en/33_Sound/21_FreqModulation.js b/dist/assets/examples/en/33_Sound/21_FreqModulation.js new file mode 100644 index 0000000000..bd128b7fc7 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/21_FreqModulation.js @@ -0,0 +1,149 @@ +/** + * @name Frequency Modulation + * @arialabel White sound waves on black background change as the user moves their mouse. Labels of modulator frequency and amplitude change as the user moves their mouse too. There is also a label of carrier frequency at 220 Hz + * @description

Frequency Modulation is a powerful form of synthesis. + * In its simplest form, FM involves two oscillators, referred + * to as the carrier and the modulator. As the modulator's waveform oscillates + * between some minimum and maximum amplitude value, that momentary value + * is added to ("modulates") the frequency of the carrier.

+ *

The carrier is typically set to oscillate at an audible frequency + * that we perceive as a pitch—in this case, it is a sine wave oscilaltor at 220Hz, + * equivalent to an "A3" note. The carrier is connected to master output by default + * (this is the case for all p5.Oscillators).

+ *

We will disconnect the modulator from master output, + * and instead connect to the frequency of the carrier: + * carrier.freq(modulator). This adds the output amplitude of the + * modulator to the frequency of the carrier.

+ *

+ * Modulation Depth describes how much the carrier frequency will modulate. + * It is based on the amplitude of the modulator. + * The modulator produces a continuous stream of amplitude values that we will add + * to the carrier frequency. An amplitude of zero means silence, so the modulation will + * have no effect. An amplitude of 1.0 scales the range of output values + * between +1.0 and -1.0. That is the standard range for sound that gets sent to + * your speakers, but in FM we are instead sending the modulator's output to the carrier frequency, + * where we'd barely notice the +1Hz / -1Hz modulation. + * So we will typically increase the amplitude ("depth") of the modulator to numbers much higher than what + * we might send to our speakers.

+ *

Modulation Frequency is the speed of modulation. When the modulation frequency is lower + * than 20Hz, we stop hearing its frequency as pitch, and start to hear it as a beating rhythm. + * For example, try 7.5Hz at a depth of 20 to mimic the "vibrato" effect of an operatic vocalist. + * The term for this is Low Frequency Oscillator, or LFO. Modulators set to higher frequencies can + * also produce interesting effects, especially when the frequency has a harmonic relationship + * to the carrier signal. For example, listen to what happens when the modulator's frequency is + * half or twice that of the carrier. This is the basis for FM Synthesis, developed by John Chowning + * in the 1960s, which came to revolutionize synthesis in the 1980s and is often used to synthesize + * brass and bell-like sounds. + * + *

In this example,

+ * - MouseX controls the modulation depth (the amplitude of the modulator) from -150 to 150. + * When the modulator's amplitude is set to 0 (in the middle), notice how the modulation + * has no effect. The greater (the absolute value of) the number, the greater the effect. + * If the modulator waveform is symetrical like a square [], sine ~ + * or triangle /\, the negative amplitude will be the same as positive amplitude. + * But in this example, the modulator is an asymetrical sawtooth wave, shaped like this /. + * When we multiply it by a negative number, it goes backwards like this \. To best + * observe the difference, try lowering the frequency. + *

+ *

- MouseY controls the frequency of the modulator from 0 to 112 Hz. + * Try comparing modulation frequencies below the audible range (which starts around 20hz), + * and above it, especially in a harmonic relationship to the carrier frequency (which is 220hz, so + * try half that, 1/3, 1/4 etc...). + * + *

You will need to include the + * p5.sound library + * for this example to work in your own project.

+ */ + +let carrier; // this is the oscillator we will hear +let modulator; // this oscillator will modulate the frequency of the carrier + +let analyzer; // we'll use this visualize the waveform + +// the carrier frequency pre-modulation +let carrierBaseFreq = 220; + +// min/max ranges for modulator +let modMaxFreq = 112; +let modMinFreq = 0; +let modMaxDepth = 150; +let modMinDepth = -150; + +function setup() { + let cnv = createCanvas(800, 400); + noFill(); + + carrier = new p5.Oscillator('sine'); + carrier.amp(0); // set amplitude + carrier.freq(carrierBaseFreq); // set frequency + carrier.start(); // start oscillating + + // try changing the type to 'square', 'sine' or 'triangle' + modulator = new p5.Oscillator('sawtooth'); + modulator.start(); + + // add the modulator's output to modulate the carrier's frequency + modulator.disconnect(); + carrier.freq(modulator); + + // create an FFT to analyze the audio + analyzer = new p5.FFT(); + + // fade carrier in/out on mouseover / touch start + toggleAudio(cnv); +} + +function draw() { + background(30); + + // map mouseY to modulator freq between a maximum and minimum frequency + let modFreq = map(mouseY, height, 0, modMinFreq, modMaxFreq); + modulator.freq(modFreq); + + // change the amplitude of the modulator + // negative amp reverses the sawtooth waveform, and sounds percussive + // + let modDepth = map(mouseX, 0, width, modMinDepth, modMaxDepth); + modulator.amp(modDepth); + + // analyze the waveform + waveform = analyzer.waveform(); + + // draw the shape of the waveform + stroke(255); + strokeWeight(10); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); + + strokeWeight(1); + // add a note about what's happening + text('Modulator Frequency: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text( + 'Modulator Amplitude (Modulation Depth): ' + modDepth.toFixed(3), + 20, + 40 + ); + text( + 'Carrier Frequency (pre-modulation): ' + carrierBaseFreq + ' Hz', + width / 2, + 20 + ); +} + +// helper function to toggle sound +function toggleAudio(cnv) { + cnv.mouseOver(function() { + carrier.amp(1.0, 0.01); + }); + cnv.touchStarted(function() { + carrier.amp(1.0, 0.01); + }); + cnv.mouseOut(function() { + carrier.amp(0.0, 1.0); + }); +} diff --git a/dist/assets/examples/en/33_Sound/22_AmplitudeModulation.js b/dist/assets/examples/en/33_Sound/22_AmplitudeModulation.js new file mode 100644 index 0000000000..e66ae8aa70 --- /dev/null +++ b/dist/assets/examples/en/33_Sound/22_AmplitudeModulation.js @@ -0,0 +1,96 @@ +/** + * @name Amplitude Modulation + * @arialabel White sound waves on black background change as the user moves their mouse. Labels of modulator frequency and amplitude change as the user moves their mouse too + * @description

Amplitude Modulation involves two oscillators, referred + * to as the carrier and the modulator, where the modulator controls + * the carrier's amplitude.

+ * + *

The carrier is typically set at an audible frequency (i.e. 440 Hz) + * and connected to master output by default. The carrier.amp is + * set to zero because we will have the modulator control its amplitude.

+ * + *

The modulator is disconnected from master output. Instead, it is connected + * to the amplitude of the Carrier, like this: carrier.amp(modulator).

+ * + *

In this example...

+ *

- MouseX controls the amplitude of the modulator + * from 0 to 1. When the modulator's amplitude is set to 0, the + * amplitude modulation has no effect.

+ * + *

- MouseY controls the frequency of the modulator from 0 to 20hz. + * This range is lower frequencies than humans can hear, and we perceive the + * modulation as a rhythm. This range can simulate effects such as Tremolo. + * Ring Modulation is a type of Amplitude Modulation where the original + * carrier signal is not present, and often involves modulation at a faster + * frequency.

+ * + *

You will need to include the + * p5.sound library + * for this example to work in your own project.

+ */ +let carrier; // this is the oscillator we will hear +let modulator; // this oscillator will modulate the amplitude of the carrier +let fft; // we'll visualize the waveform + +function setup() { + createCanvas(800, 400); + noFill(); + background(30); // alpha + + carrier = new p5.Oscillator(); // connects to master output by default + carrier.freq(340); + carrier.amp(0); + // carrier's amp is 0 by default, giving our modulator total control + + carrier.start(); + + modulator = new p5.Oscillator('triangle'); + modulator.disconnect(); // disconnect the modulator from master output + modulator.freq(5); + modulator.amp(1); + modulator.start(); + + // Modulate the carrier's amplitude with the modulator + // Optionally, we can scale the signal. + carrier.amp(modulator.scale(-1, 1, 1, -1)); + + // create an fft to analyze the audio + fft = new p5.FFT(); +} + +function draw() { + background(30, 30, 30, 100); // alpha + + // map mouseY to moodulator freq between 0 and 20hz + let modFreq = map(mouseY, 0, height, 20, 0); + modulator.freq(modFreq); + + let modAmp = map(mouseX, 0, width, 0, 1); + modulator.amp(modAmp, 0.01); // fade time of 0.1 for smooth fading + + // analyze the waveform + waveform = fft.waveform(); + + // draw the shape of the waveform + drawWaveform(); + + drawText(modFreq, modAmp); +} + +function drawWaveform() { + stroke(240); + strokeWeight(4); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); +} + +function drawText(modFreq, modAmp) { + strokeWeight(1); + text('Modulator Frequency: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text('Modulator Amplitude: ' + modAmp.toFixed(3), 20, 40); +} diff --git a/dist/assets/examples/en/35_Mobile/00_Acceleration_Ball_Bounce.js b/dist/assets/examples/en/35_Mobile/00_Acceleration_Ball_Bounce.js new file mode 100644 index 0000000000..0942148573 --- /dev/null +++ b/dist/assets/examples/en/35_Mobile/00_Acceleration_Ball_Bounce.js @@ -0,0 +1,58 @@ +/* + * @name Acceleration Ball Bounce + * @description Move an ellipse around based on accelerationX and accelerationY values, and bounces when touch the edge of the canvas. + */ + +// Position Variables +let x = 0; +let y = 0; + +// Speed - Velocity +let vx = 0; +let vy = 0; + +// Acceleration +let ax = 0; +let ay = 0; + +let vMultiplier = 0.007; +let bMultiplier = 0.6; + +function setup() { + createCanvas(displayWidth, displayHeight); + fill(0); +} + +function draw() { + background(255); + ballMove(); + ellipse(x, y, 30, 30); +} + +function ballMove() { + ax = accelerationX; + ay = accelerationY; + + vx = vx + ay; + vy = vy + ax; + y = y + vy * vMultiplier; + x = x + vx * vMultiplier; + + // Bounce when touch the edge of the canvas + if (x < 0) { + x = 0; + vx = -vx * bMultiplier; + } + if (y < 0) { + y = 0; + vy = -vy * bMultiplier; + } + if (x > width - 20) { + x = width - 20; + vx = -vx * bMultiplier; + } + if (y > height - 20) { + y = height - 20; + vy = -vy * bMultiplier; + } +} diff --git a/dist/assets/examples/en/35_Mobile/01_Simple_Draw.js b/dist/assets/examples/en/35_Mobile/01_Simple_Draw.js new file mode 100644 index 0000000000..80cddb8562 --- /dev/null +++ b/dist/assets/examples/en/35_Mobile/01_Simple_Draw.js @@ -0,0 +1,15 @@ +/* + * @name Simple Draw + * @description Touch to draw on the screen using mouseX, mouseY, pmouseX, and pmouseY values. + */ + +function setup() { + createCanvas(displayWidth, displayHeight); + strokeWeight(10); + stroke(0); +} + +function touchMoved() { + line(mouseX, mouseY, pmouseX, pmouseY); + return false; +} diff --git a/dist/assets/examples/en/35_Mobile/02_Acceleration_Color.js b/dist/assets/examples/en/35_Mobile/02_Acceleration_Color.js new file mode 100644 index 0000000000..a7183d1def --- /dev/null +++ b/dist/assets/examples/en/35_Mobile/02_Acceleration_Color.js @@ -0,0 +1,24 @@ +/* + * @name Acceleration Color + * @description Use deviceMoved() to detect when the device is rotated. The background RGB color values are mapped to accelerationX, accelerationY, and accelerationZ values. + */ + +let r, g, b; + +function setup() { + createCanvas(displayWidth, displayHeight); + r = random(50, 255); + g = random(0, 200); + b = random(50, 255); +} + +function draw() { + background(r, g, b); + console.log('draw'); +} + +function deviceMoved() { + r = map(accelerationX, -90, 90, 100, 175); + g = map(accelerationY, -90, 90, 100, 200); + b = map(accelerationZ, -90, 90, 100, 200); +} diff --git a/dist/assets/examples/en/35_Mobile/03_Shake_Ball_Bounce.js b/dist/assets/examples/en/35_Mobile/03_Shake_Ball_Bounce.js new file mode 100644 index 0000000000..5d2880dbe7 --- /dev/null +++ b/dist/assets/examples/en/35_Mobile/03_Shake_Ball_Bounce.js @@ -0,0 +1,114 @@ +/* + * @name Shake Ball Bounce + * @description Create a Ball class, instantiate multiple objects, move it around the screen, and bounce when touch the edge of the canvas. + * Detect shake event based on total change in accelerationX and accelerationY and speed up or slow down objects based on detection. + */ + +let balls = []; + +let threshold = 30; +let accChangeX = 0; +let accChangeY = 0; +let accChangeT = 0; + +function setup() { + createCanvas(displayWidth, displayHeight); + + for (let i = 0; i < 20; i++) { + balls.push(new Ball()); + } +} + +function draw() { + background(0); + + for (let i = 0; i < balls.length; i++) { + balls[i].move(); + balls[i].display(); + } + + checkForShake(); +} + +function checkForShake() { + // Calculate total change in accelerationX and accelerationY + accChangeX = abs(accelerationX - pAccelerationX); + accChangeY = abs(accelerationY - pAccelerationY); + accChangeT = accChangeX + accChangeY; + // If shake + if (accChangeT >= threshold) { + for (let i = 0; i < balls.length; i++) { + balls[i].shake(); + balls[i].turn(); + } + } + // If not shake + else { + for (let i = 0; i < balls.length; i++) { + balls[i].stopShake(); + balls[i].turn(); + balls[i].move(); + } + } +} + +// Ball class +class Ball { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.xspeed = random(-2, 2); + this.yspeed = random(-2, 2); + this.oxspeed = this.xspeed; + this.oyspeed = this.yspeed; + this.direction = 0.7; + } + + move() { + this.x += this.xspeed * this.direction; + this.y += this.yspeed * this.direction; + } + + // Bounce when touch the edge of the canvas + turn() { + if (this.x < 0) { + this.x = 0; + this.direction = -this.direction; + } else if (this.y < 0) { + this.y = 0; + this.direction = -this.direction; + } else if (this.x > width - 20) { + this.x = width - 20; + this.direction = -this.direction; + } else if (this.y > height - 20) { + this.y = height - 20; + this.direction = -this.direction; + } + } + + // Add to xspeed and yspeed based on + // the change in accelerationX value + shake() { + this.xspeed += random(5, accChangeX / 3); + this.yspeed += random(5, accChangeX / 3); + } + + // Gradually slows down + stopShake() { + if (this.xspeed > this.oxspeed) { + this.xspeed -= 0.6; + } else { + this.xspeed = this.oxspeed; + } + if (this.yspeed > this.oyspeed) { + this.yspeed -= 0.6; + } else { + this.yspeed = this.oyspeed; + } + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/en/35_Mobile/04_Tilted_3D_Box.js b/dist/assets/examples/en/35_Mobile/04_Tilted_3D_Box.js new file mode 100644 index 0000000000..ea39b5414f --- /dev/null +++ b/dist/assets/examples/en/35_Mobile/04_Tilted_3D_Box.js @@ -0,0 +1,15 @@ +/* + * @name Tilted 3D Box + * @description Use mobile to tilt a box + */ +function setup() { + createCanvas(displayWidth, displayHeight, WEBGL); +} + +function draw() { + background(250); + normalMaterial(); + rotateX(accelerationX * 0.01); + rotateY(accelerationY * 0.01); + box(100, 100, 100); +} diff --git a/dist/assets/examples/en/90_Hello_P5/01_shapes.js b/dist/assets/examples/en/90_Hello_P5/01_shapes.js new file mode 100644 index 0000000000..122ac85697 --- /dev/null +++ b/dist/assets/examples/en/90_Hello_P5/01_shapes.js @@ -0,0 +1,29 @@ +/* + * @name Simple Shapes + * @arialabel Grey canvas with 4 pink shapes: a circle, a rectangle, a triangle, and a flower + * @description This examples includes a circle, square, triangle, and a flower. + */ +function setup() { + // Create the canvas + createCanvas(720, 400); + background(200); + + // Set colors + fill(204, 101, 192, 127); + stroke(127, 63, 120); + + // A rectangle + rect(40, 120, 120, 40); + // An ellipse + ellipse(240, 240, 80, 80); + // A triangle + triangle(300, 100, 320, 100, 310, 80); + + // A design for a simple flower + translate(580, 200); + noStroke(); + for (let i = 0; i < 10; i ++) { + ellipse(0, 30, 20, 80); + rotate(PI/5); + } +} diff --git a/dist/assets/examples/en/90_Hello_P5/02_interactivity.js b/dist/assets/examples/en/90_Hello_P5/02_interactivity.js new file mode 100644 index 0000000000..1b478af003 --- /dev/null +++ b/dist/assets/examples/en/90_Hello_P5/02_interactivity.js @@ -0,0 +1,38 @@ +/* + * @name Interactivity 1 + * @arialabel Dark grey background with a colored circle in the middle that changes color when clicked ons + * @frame 720,425 + * @description The circle changes color when you click on it. + */ + +// for red, green, and blue color values +let r, g, b; + +function setup() { + createCanvas(720, 400); + // Pick colors randomly + r = random(255); + g = random(255); + b = random(255); +} + +function draw() { + background(127); + // Draw a circle + strokeWeight(2); + stroke(r, g, b); + fill(r, g, b, 127); + ellipse(360, 200, 200, 200); +} + +// When the user clicks the mouse +function mousePressed() { + // Check if mouse is inside the circle + let d = dist(mouseX, mouseY, 360, 200); + if (d < 100) { + // Pick new random color values + r = random(255); + g = random(255); + b = random(255); + } +} diff --git a/dist/assets/examples/en/90_Hello_P5/03_interactivity.js b/dist/assets/examples/en/90_Hello_P5/03_interactivity.js new file mode 100644 index 0000000000..86218e4b4d --- /dev/null +++ b/dist/assets/examples/en/90_Hello_P5/03_interactivity.js @@ -0,0 +1,27 @@ +/* + * @name Interactivity 2 + * @arialabel Dark grey background with a colored circle in the middle that changes color as the user drags a slider on the bottom + * @frame 720,425 + * @description The circle changes color when you move the slider. + */ + +// A HTML range slider +let slider; + +function setup() { + createCanvas(720, 400); + // hue, saturation, and brightness + colorMode(HSB, 255); + // slider has a range between 0 and 255 with a starting value of 127 + slider = createSlider(0, 255, 127); +} + +function draw() { + background(127); + strokeWeight(2); + + // Set the hue according to the slider + stroke(slider.value(), 255, 255); + fill(slider.value(), 255, 255, 127); + ellipse(360, 200, 200, 200); +} \ No newline at end of file diff --git a/dist/assets/examples/en/90_Hello_P5/04_animate.js b/dist/assets/examples/en/90_Hello_P5/04_animate.js new file mode 100644 index 0000000000..75ec783002 --- /dev/null +++ b/dist/assets/examples/en/90_Hello_P5/04_animate.js @@ -0,0 +1,34 @@ +/* + * @name Animation + * @arialabel Light grey background with a dark grey circle that is traveling up from the middle of the bottom of the screen as it moves slightly side-to-side + * @description The circle moves. + */ +// Where is the circle +let x, y; + +function setup() { + createCanvas(720, 400); + // Starts in the middle + x = width / 2; + y = height; +} + +function draw() { + background(200); + + // Draw a circle + stroke(50); + fill(100); + ellipse(x, y, 24, 24); + + // Jiggling randomly on the horizontal axis + x = x + random(-1, 1); + // Moving up at a constant speed + y = y - 1; + + // Reset to the bottom + if (y < 0) { + y = height; + } +} + diff --git a/dist/assets/examples/en/90_Hello_P5/04_flocking.js b/dist/assets/examples/en/90_Hello_P5/04_flocking.js new file mode 100644 index 0000000000..7e1ff4812f --- /dev/null +++ b/dist/assets/examples/en/90_Hello_P5/04_flocking.js @@ -0,0 +1,186 @@ +/* + * @name Flocking + * @arialabel Light grey circles on a dark grey background that travel across the screen in flocks or groups + * @description Demonstration of Craig Reynolds' "Flocking" behavior.
+ * (Rules: Cohesion, Separation, Alignment.)
+ * From natureofcode.com. + */ +let boids = []; + +function setup() { + createCanvas(720, 400); + + // Add an initial set of boids into the system + for (let i = 0; i < 100; i++) { + boids[i] = new Boid(random(width), random(height)); + } +} + +function draw() { + background(51); + // Run all the boids + for (let i = 0; i < boids.length; i++) { + boids[i].run(boids); + } +} + +// Boid class +// Methods for Separation, Cohesion, Alignment added +class Boid { + constructor(x, y) { + this.acceleration = createVector(0, 0); + this.velocity = p5.Vector.random2D(); + this.position = createVector(x, y); + this.r = 3.0; + this.maxspeed = 3; // Maximum speed + this.maxforce = 0.05; // Maximum steering force + } + + run(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); + } + + // Forces go into acceleration + applyForce(force) { + this.acceleration.add(force); + } + + // We accumulate a new acceleration each time based on three rules + flock(boids) { + let sep = this.separate(boids); // Separation + let ali = this.align(boids); // Alignment + let coh = this.cohesion(boids); // Cohesion + // Arbitrarily weight these forces + sep.mult(2.5); + ali.mult(1.0); + coh.mult(1.0); + // Add the force vectors to acceleration + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); + } + + // Method to update location + update() { + // Update velocity + this.velocity.add(this.acceleration); + // Limit speed + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // Reset acceleration to 0 each cycle + this.acceleration.mult(0); + } + + // A method that calculates and applies a steering force towards a target + // STEER = DESIRED MINUS VELOCITY + seek(target) { + let desired = p5.Vector.sub(target, this.position); // A vector pointing from the location to the target + // Normalize desired and scale to maximum speed + desired.normalize(); + desired.mult(this.maxspeed); + // Steering = Desired minus Velocity + let steer = p5.Vector.sub(desired, this.velocity); + steer.limit(this.maxforce); // Limit to maximum steering force + return steer; + } + + // Draw boid as a circle + render() { + fill(127, 127); + stroke(200); + ellipse(this.position.x, this.position.y, 16, 16); + } + + // Wraparound + borders() { + if (this.position.x < -this.r) this.position.x = width + this.r; + if (this.position.y < -this.r) this.position.y = height + this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height + this.r) this.position.y = -this.r; + } + + // Separation + // Method checks for nearby boids and steers away + separate(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // For every boid in the system, check if it's too close + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) + if ((d > 0) && (d < desiredseparation)) { + // Calculate vector pointing away from neighbor + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // Weight by distance + steer.add(diff); + count++; // Keep track of how many + } + } + // Average -- divide by how many + if (count > 0) { + steer.div(count); + } + + // As long as the vector is greater than 0 + if (steer.mag() > 0) { + // Implement Reynolds: Steering = Desired - Velocity + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; + } + + // Alignment + // For every nearby boid in the system, calculate the average velocity + align(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } + } + + // Cohesion + // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location + cohesion(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // Start with empty vector to accumulate all locations + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // Add location + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // Steer towards the location + } else { + return createVector(0, 0); + } + } +} + diff --git a/dist/assets/examples/en/90_Hello_P5/05_weather.js b/dist/assets/examples/en/90_Hello_P5/05_weather.js new file mode 100644 index 0000000000..429d25ac65 --- /dev/null +++ b/dist/assets/examples/en/90_Hello_P5/05_weather.js @@ -0,0 +1,72 @@ +/* + * @name Weather + * @arialabel Uses weather from Metweather website to control a blue arrow and grey circle on the screen. The blue arrow is in a white circle on the bottom left corner and points in the direction of the wind. The small dark grey circle is on a grey background and moves in the window’s direction + * @frame 720,280 + * @description This example grabs JSON weather data from www.metaweather.com. +*/ + +// A wind direction vector +let wind; +// Circle position +let position; + +function setup() { + createCanvas(720, 200); + // Request the data from metaweather.com + let url = 'https://cors-anywhere.herokuapp.com/https://www.metaweather.com/api/location/2459115/'; + loadJSON(url,gotWeather); + // Circle starts in the middle + position = createVector(width/2, height/2); + // wind starts as (0,0) + wind = createVector(); +} + +function draw() { + background(200); + + // This section draws an arrow pointing in the direction of wind + push(); + translate(32, height - 32); + // Rotate by the wind's angle + rotate(wind.heading() + PI/2); + noStroke(); + fill(255); + ellipse(0, 0, 48, 48); + + stroke(45, 123, 182); + strokeWeight(3); + line(0, -16, 0, 16); + + noStroke(); + fill(45, 123, 182); + triangle(0, -18, -6, -10, 6, -10); + pop(); + + // Move in the wind's direction + position.add(wind); + + stroke(0); + fill(51); + ellipse(position.x, position.y, 16, 16); + + if (position.x > width) position.x = 0; + if (position.x < 0) position.x = width; + if (position.y > height) position.y = 0; + if (position.y < 0) position.y = height; +} + +function gotWeather(weather) { + let weather_today = weather.consolidated_weather[0] + // Get the angle (convert to radians) + let angle = radians(Number(weather_today.wind_direction)); + // Get the wind speed + let windmag = Number(weather_today.wind_speed); + + // Display as HTML elements + let temperatureDiv = createDiv(floor(weather_today.the_temp) + '°C'); + let windDiv = createDiv("WIND " + windmag + " MPH"); + + // Make a vector + wind = p5.Vector.fromAngle(angle); +} + diff --git a/dist/assets/examples/en/90_Hello_P5/06_drawing.js b/dist/assets/examples/en/90_Hello_P5/06_drawing.js new file mode 100644 index 0000000000..6ca6c97e50 --- /dev/null +++ b/dist/assets/examples/en/90_Hello_P5/06_drawing.js @@ -0,0 +1,133 @@ +/* +* @name Drawing +* @arialabel When the user clicks and drags on the light grey background, the user draws a pattern of dark grey circles connected by dark grey lines which also disappears after a bit. +* @description Generative painting program. +*/ + +// All the paths +let paths = []; +// Are we painting? +let painting = false; +// How long until the next circle +let next = 0; +// Where are we now and where were we? +let current; +let previous; + +function setup() { + createCanvas(720, 400); + current = createVector(0,0); + previous = createVector(0,0); +}; + +function draw() { + background(200); + + // If it's time for a new point + if (millis() > next && painting) { + + // Grab mouse position + current.x = mouseX; + current.y = mouseY; + + // New particle's force is based on mouse movement + let force = p5.Vector.sub(current, previous); + force.mult(0.05); + + // Add new particle + paths[paths.length - 1].add(current, force); + + // Schedule next circle + next = millis() + random(100); + + // Store mouse values + previous.x = current.x; + previous.y = current.y; + } + + // Draw all paths + for( let i = 0; i < paths.length; i++) { + paths[i].update(); + paths[i].display(); + } +} + +// Start it up +function mousePressed() { + next = 0; + painting = true; + previous.x = mouseX; + previous.y = mouseY; + paths.push(new Path()); +} + +// Stop +function mouseReleased() { + painting = false; +} + +// A Path is a list of particles +class Path { + constructor() { + this.particles = []; + this.hue = random(100); + } + + add(position, force) { + // Add a new particle with a position, force, and hue + this.particles.push(new Particle(position, force, this.hue)); + } + + // Display plath + update() { + for (let i = 0; i < this.particles.length; i++) { + this.particles[i].update(); + } + } + + // Display plath + display() { + // Loop through backwards + for (let i = this.particles.length - 1; i >= 0; i--) { + // If we shold remove it + if (this.particles[i].lifespan <= 0) { + this.particles.splice(i, 1); + // Otherwise, display it + } else { + this.particles[i].display(this.particles[i+1]); + } + } + + } +} + +// Particles along the path +class Particle { + constructor(position, force, hue) { + this.position = createVector(position.x, position.y); + this.velocity = createVector(force.x, force.y); + this.drag = 0.95; + this.lifespan = 255; + } + + update() { + // Move it + this.position.add(this.velocity); + // Slow it down + this.velocity.mult(this.drag); + // Fade it out + this.lifespan--; + } + + // Draw particle and connect it with a line + // Draw a line to another + display(other) { + stroke(0, this.lifespan); + fill(0, this.lifespan/2); + ellipse(this.position.x,this.position.y, 8, 8); + // If we need to draw a line + if (other) { + line(this.position.x, this.position.y, other.position.x, other.position.y); + } + } +} diff --git a/dist/assets/examples/en/90_Hello_P5/07_song.js b/dist/assets/examples/en/90_Hello_P5/07_song.js new file mode 100644 index 0000000000..a43e43363e --- /dev/null +++ b/dist/assets/examples/en/90_Hello_P5/07_song.js @@ -0,0 +1,120 @@ +/* + * @name Song + * @arialabel Grey background divided into 7 vertical rectangles. When the user hovers, the rectangle turns dark grey. When the user clicks, each rectangle turns cyan and plays a different note. + * @frame 720, 430 + * @description Play a song. + * You will need to include the + * p5.sound + * library for this example to work in your own project. + */ +// The midi notes of a scale +let notes = [ 60, 62, 64, 65, 67, 69, 71]; + +// For automatically playing the song +let index = 0; +let song = [ + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 200, display: "G" }, + { note: 1, duration: 200, display: "A" }, + { note: 2, duration: 200, display: "B" }, + { note: 3, duration: 200, display: "C" }, + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 400, display: "G" }, + { note: 0, duration: 400, display: "G" } +]; +let trigger = 0; +let autoplay = false; +let osc; + +function setup() { + createCanvas(720, 400); + let div = createDiv("Click to play notes or ") + div.id("instructions"); + let button = createButton("play song automatically."); + button.parent("instructions"); + // Trigger automatically playing + button.mousePressed(function() { + if (!autoplay) { + index = 0; + autoplay = true; + } + }); + + // A triangle oscillator + osc = new p5.TriOsc(); + // Start silent + osc.start(); + osc.amp(0); +} + +// A function to play a note +function playNote(note, duration) { + osc.freq(midiToFreq(note)); + // Fade it in + osc.fade(0.5,0.2); + + // If we sest a duration, fade it out + if (duration) { + setTimeout(function() { + osc.fade(0,0.2); + }, duration-50); + } +} + +function draw() { + + // If we are autoplaying and it's time for the next note + if (autoplay && millis() > trigger){ + playNote(notes[song[index].note], song[index].duration); + trigger = millis() + song[index].duration; + // Move to the next note + index ++; + // We're at the end, stop autoplaying. + } else if (index >= song.length) { + autoplay = false; + } + + + // Draw a keyboard + + // The width for each key + let w = width / notes.length; + for (let i = 0; i < notes.length; i++) { + let x = i * w; + // If the mouse is over the key + if (mouseX > x && mouseX < x + w && mouseY < height) { + // If we're clicking + if (mouseIsPressed) { + fill(100,255,200); + // Or just rolling over + } else { + fill(127); + } + } else { + fill(200); + } + + // Or if we're playing the song, let's highlight it too + if (autoplay && i === song[index-1].note) { + fill(100,255,200); + } + + // Draw the key + rect(x, 0, w-1, height-1); + } + +} + +// When we click +function mousePressed(event) { + if(event.button == 0 && event.clientX < width && event.clientY < height) { + // Map mouse to the key index + let key = floor(map(mouseX, 0, width, 0, notes.length)); + playNote(notes[key]); + } +} + +// Fade it out when we release +function mouseReleased() { + osc.fade(0,0.5); +} diff --git a/dist/assets/examples/es/00_Structure/00_Statements_and_Comments.js b/dist/assets/examples/es/00_Structure/00_Statements_and_Comments.js new file mode 100644 index 0000000000..8469f369b7 --- /dev/null +++ b/dist/assets/examples/es/00_Structure/00_Statements_and_Comments.js @@ -0,0 +1,19 @@ +/* + * @name Comments and Statements + * @description Statements are the elements that make up programs. The ";" (semi-colon) symbol is used to end statements. It is called the "statement * terminator". Comments are used for making notes to help people better understand programs. A comment begins with two forward slashes ("//"). (ported from https://processing.org/examples/statementscomments.html) + */ +// The createCanvas function is a statement that tells the computer +// how large to make the window. +// Each function statement has zero or more parameters. +// Parameters are data passed into the function +// and are used as values for telling the computer what to do. +function setup() { + createCanvas(710, 400); +} + +// The background function is a statement that tells the computer +// which color (or gray value) to make the background of the display window +function draw() { + background(204, 153, 0); +} + diff --git a/dist/assets/examples/es/00_Structure/01_Coordinates.js b/dist/assets/examples/es/00_Structure/01_Coordinates.js new file mode 100644 index 0000000000..d38351aa8c --- /dev/null +++ b/dist/assets/examples/es/00_Structure/01_Coordinates.js @@ -0,0 +1,37 @@ +/* + * @name Coordenadas + * @description Todas las formas dibujadas en la pantalla tienen una posición que es + * especificada como una coordenada. Todas las coordenadas son medidas como una distancia desde el origen, usando el pixel como unidad de medida. + * El origen [0, 0] es la coordenada en la esquina superior izquierda de la ventana y la coordenada de la esquina inferior derecha es [ancho-1, altura-1]. + */ +function setup() { + // Definir lienzo de 720 pixeles de ancho y 400 pixeles de alto + createCanvas(720, 400); +} + +function draw() { + // Definir el color del fondo como negro + // y definir que las figuras sean pintadas sin relleno + background(0); + noFill(); + + // Los dos parámetros del método point() especifican coordenadas. + // El primer parámetro es la coordenada x y el segundo es la y. + stroke(255); + point(width * 0.5, height * 0.5); + point(width * 0.5, height * 0.25); + + // Las coordenadas se usan para dibujar figuras, no solo puntos. + // Los parámetros de las funciones son usados para múltiples + // propósitos. Por ejemplo, los dos primeros parámetros + // de line() especifican las coordenadas del primer extremo + //y los siguientes dos parámetros del segundo extremo. + stroke(0, 153, 255); + line(0, height * 0.33, width, height * 0.33); + + // Por defecto, los dos primeros parámetros de rect() son + // las coordenadas de la esquina superior izquierda y el + // segundo par son el ancho y el alto. + stroke(255, 153, 0); + rect(width * 0.25, height * 0.1, width * 0.5, height * 0.8); +} diff --git a/dist/assets/examples/es/00_Structure/02_Width_and_Height.js b/dist/assets/examples/es/00_Structure/02_Width_and_Height.js new file mode 100644 index 0000000000..02df6efe69 --- /dev/null +++ b/dist/assets/examples/es/00_Structure/02_Width_and_Height.js @@ -0,0 +1,19 @@ +/* + * @name width y height + * @description Las variables 'width' (ancho) y 'height' (altura) contienen + * el ancho y la altura del lienzo, como fue definido en la función createCanvas(). + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(127); + noStroke(); + for (let i = 0; i < height; i += 20) { + fill(129, 206, 15); + rect(0, i, width, 10); + fill(255); + rect(i, 0, 10, height); + } +} diff --git a/dist/assets/examples/es/00_Structure/03_Setup_and_Draw.js b/dist/assets/examples/es/00_Structure/03_Setup_and_Draw.js new file mode 100644 index 0000000000..1c4b247351 --- /dev/null +++ b/dist/assets/examples/es/00_Structure/03_Setup_and_Draw.js @@ -0,0 +1,28 @@ +/* + * @name Setup y Draw + * @description El código dentro de la función draw() corre continuamente de arriba + * a a bajo hasta que el programa es parado. + */ +let y = 100; + +// Las instrucciones dentro de la función setup() +// se ejecutan una vez, al principio del programa +function setup() { + // createCanvas() debe ser la primera instrucción + createCanvas(720, 400); + stroke(255); // Hacer que el color de trazado sea blanco + frameRate(30); +} + +// Las instrucciones en draw() son ejecutadas hasta que +// el programa es parado. Cada instrucción es ejecutada +// en orden y luego de que la última línea es leída, +// se vuelve a ejecutar draw() desde el principio +function draw() { + background(0); // Hacer que el color del fondo sea negro + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/es/00_Structure/04_No_Loop.js b/dist/assets/examples/es/00_Structure/04_No_Loop.js new file mode 100644 index 0000000000..4c56f21a70 --- /dev/null +++ b/dist/assets/examples/es/00_Structure/04_No_Loop.js @@ -0,0 +1,30 @@ +/* + * @name No Loop + * @description La función noLoop() hace que draw() se ejecuta solo una vez. + * Sin ejecutar noLoop(), el código dentro de draw() es ejecutado continuamente. + */ +let y; + +// The statements in the setup() function +// execute once when the program begins +function setup() { + // createCanvas should be the first statement + createCanvas(720, 400); + stroke(255); // Set line drawing color to white + noLoop(); + + y = height * 0.5; +} + +// Las instrucciones en draw() son ejecutadas hasta que +// el programa es parado. Cada instrucción es ejecutada +// en orden y luego de que la última línea es leída, +// se vuelve a ejecutar draw() desde el principio +function draw() { + background(0); // Set the background to black + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/es/00_Structure/05_Loop.js b/dist/assets/examples/es/00_Structure/05_Loop.js new file mode 100644 index 0000000000..c8a3e298e9 --- /dev/null +++ b/dist/assets/examples/es/00_Structure/05_Loop.js @@ -0,0 +1,26 @@ +/* + * @name Bucle + * @description El código dentro de la función draw() corre continuamente de arriba a abajo hasta que el prorgrama para. + */ +let y = 100; + +// Las instrucciones dentro de la función setup() +// se ejecutan una vez, cuando el programa empieza +function setup() { + createCanvas(720, 400); // El tamaño debe ser la primera instrucción + stroke(255); // Definir que el color del trazado sea blanco + frameRate(30); +} + +// Las instrucciones en draw() son ejecutadas hasta que +// el programa es parado. Cada instrucción es ejecutada +// en orden y luego de que la última línea es leída, +// se vuelve a ejecutar draw() desde el principio +function draw() { + background(0); // Definir que el color del fondo sea negro + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/es/00_Structure/06_Redraw.js b/dist/assets/examples/es/00_Structure/06_Redraw.js new file mode 100644 index 0000000000..0cb9bbbfe2 --- /dev/null +++ b/dist/assets/examples/es/00_Structure/06_Redraw.js @@ -0,0 +1,33 @@ +/* + * @name Redraw + * @description La función redraw() hace que draw() se ejecute una vez. En este ejemplo, + * draw() se ejecutado una vez cada vez que el ratón hace click. + */ + +let y; + +// Las instrucciones dentro de la función setup() +// se ejecutan una vez, cuando el programa se inicia +function setup() { + createCanvas(720, 400); + stroke(255); + noLoop(); + y = height * 0.5; +} + +// Las instrucciones en draw() son ejecutadas hasta que +// el programa es parado. Cada instrucción es ejecutada +// en orden y luego de que la última línea es leída, +// se vuelve a ejecutar draw() desde el principio +function draw() { + background(0); + y = y - 4; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} + +function mousePressed() { + redraw(); +} diff --git a/dist/assets/examples/es/00_Structure/07_Functions.js b/dist/assets/examples/es/00_Structure/07_Functions.js new file mode 100644 index 0000000000..157494342e --- /dev/null +++ b/dist/assets/examples/es/00_Structure/07_Functions.js @@ -0,0 +1,28 @@ +/* + *@name Funciones + *@description La función drawTarget() hace fácil dibujar muchas dianas distintos. + * Cada llamada a drawTarget() especifica la posición, tamaño y número de + * anillos por cada diana. + */ + +function setup() { + createCanvas(720, 400); + background(51); + noStroke(); + noLoop(); +} + +function draw() { + drawTarget(width * 0.25, height * 0.4, 200, 4); + drawTarget(width * 0.5, height * 0.5, 300, 10); + drawTarget(width * 0.75, height * 0.3, 120, 6); +} + +function drawTarget(xloc, yloc, size, num) { + const grayvalues = 255 / num; + const steps = size / num; + for (let i = 0; i < num; i++) { + fill(i * grayvalues); + ellipse(xloc, yloc, size - i * steps, size - i * steps); + } +} diff --git a/dist/assets/examples/es/00_Structure/08_Recursion.js b/dist/assets/examples/es/00_Structure/08_Recursion.js new file mode 100644 index 0000000000..ce0befd0ee --- /dev/null +++ b/dist/assets/examples/es/00_Structure/08_Recursion.js @@ -0,0 +1,27 @@ +/* + *@name Recursión + *@description Una demonstración de recursión, que significa funciones llamándose a sí mismas. + * Fíjate cómo la función drawCircle() se llama a sí misma al final del bloque de código. + * Continúa haciéndolo hasta que la variable "level" es igual a 1. + */ + +function setup() { + createCanvas(720, 560); + noStroke(); + noLoop(); +} + +function draw() { + drawCircle(width / 2, 280, 6); +} + +function drawCircle(x, radius, level) { + const tt = (126 * level) / 4.0; + fill(tt); + ellipse(x, height / 2, radius * 2, radius * 2); + if (level > 1) { + level = level - 1; + drawCircle(x - radius / 2, radius / 2, level); + drawCircle(x + radius / 2, radius / 2, level); + } +} diff --git a/dist/assets/examples/es/00_Structure/09_Create_Graphics.js b/dist/assets/examples/es/00_Structure/09_Create_Graphics.js new file mode 100644 index 0000000000..88085349e2 --- /dev/null +++ b/dist/assets/examples/es/00_Structure/09_Create_Graphics.js @@ -0,0 +1,29 @@ +/* + * @name createGraphics + * @description Crea y retorna un nuevo objeto p5.Renderer. Usa esta + * clase si necesitas dibujar en un buffer gráfico fuera-de-pantalla. Los dos parámetros + * definen el ancho y la altura en pixeles. + */ + +let pg; + +function setup() { + createCanvas(710, 400); + pg = createGraphics(400, 250); +} + +function draw() { + fill(0, 12); + rect(0, 0, width, height); + fill(255); + noStroke(); + ellipse(mouseX, mouseY, 60, 60); + + pg.background(51); + pg.noFill(); + pg.stroke(255); + pg.ellipse(mouseX - 150, mouseY - 75, 60, 60); + + //El buffer fuera de pantalla es dibujado en la pantalla con image() + image(pg, 150, 75); +} diff --git a/dist/assets/examples/es/01_Form/00_Points_and_Lines.js b/dist/assets/examples/es/01_Form/00_Points_and_Lines.js new file mode 100644 index 0000000000..4e5b1d64c8 --- /dev/null +++ b/dist/assets/examples/es/01_Form/00_Points_and_Lines.js @@ -0,0 +1,36 @@ +/* + * @name Puntos y líneas + * @description Puntos y líneas pueden ser usados para dibujar geometría básica. + * Cambia el valor de la variable 'd' para escalar la figura. Las cuatro + * variables definen las posiciones basadas en el valor de 'd'. + */ +function setup() { + let d = 70; + let p1 = d; + let p2 = p1 + d; + let p3 = p2 + d; + let p4 = p3 + d; + + // Define el lienzo de 720 pixeles de ancho y 400 de alto + createCanvas(720, 400); + background(0); + noSmooth(); + + translate(140, 0); + + // Dibuja una caja gris + stroke(153); + line(p3, p3, p2, p3); + line(p2, p3, p2, p2); + line(p2, p2, p3, p2); + line(p3, p2, p3, p3); + + // Dibuja puntos blancos + stroke(255); + point(p1, p1); + point(p1, p3); + point(p2, p4); + point(p3, p1); + point(p4, p2); + point(p4, p4); +} diff --git a/dist/assets/examples/es/01_Form/01_Shape_Primitives.js b/dist/assets/examples/es/01_Form/01_Shape_Primitives.js new file mode 100644 index 0000000000..dd3ebaedac --- /dev/null +++ b/dist/assets/examples/es/01_Form/01_Shape_Primitives.js @@ -0,0 +1,31 @@ +/* + * @name Figuras primitivas + * @description Las funciones primitivas de figuras básicas son triangle(), + * rect(), quad(), ellipse() y arc(). Rectángulos y cuadrados se construyen con rect() + * y círculos y elipses con ellipse(). Cada una de estas funciones requiere + * un número de parámetros para determinar la posición y tamaño de la figura. + */ +function setup() { + // Define un lienzo de 720 pixeles de ancho y 400 de alto + createCanvas(720, 400); + background(0); + noStroke(); + + fill(204); + triangle(18, 18, 18, 360, 81, 360); + + fill(102); + rect(81, 81, 63, 63); + + fill(204); + quad(189, 18, 216, 18, 216, 360, 144, 360); + + fill(255); + ellipse(252, 144, 72, 72); + + fill(204); + triangle(288, 18, 351, 360, 288, 360); + + fill(255); + arc(479, 300, 280, 280, PI, TWO_PI); +} diff --git a/dist/assets/examples/es/01_Form/02_Pie_Chart.js b/dist/assets/examples/es/01_Form/02_Pie_Chart.js new file mode 100644 index 0000000000..7b85112b04 --- /dev/null +++ b/dist/assets/examples/es/01_Form/02_Pie_Chart.js @@ -0,0 +1,33 @@ +/* + * @name Gráfico de sectores + * @description Usa la función arc() para generar un gráfico de sectores de los datos contenidos en un arreglo + */ +let angles = [30, 10, 45, 35, 60, 38, 75, 67]; + +function setup() { + createCanvas(720, 400); + noStroke(); + noLoop(); // Corre una vez y luego para. +} + +function draw() { + background(100); + pieChart(300, angles); +} + +function pieChart(diameter, data) { + let lastAngle = 0; + for (let i = 0; i < data.length; i++) { + let gray = map(i, 0, data.length, 0, 255); + fill(gray); + arc( + width / 2, + height / 2, + diameter, + diameter, + lastAngle, + lastAngle + radians(angles[i]) + ); + lastAngle += radians(angles[i]); + } +} diff --git a/dist/assets/examples/es/01_Form/03_Regular_Polygon.js b/dist/assets/examples/es/01_Form/03_Regular_Polygon.js new file mode 100644 index 0000000000..9e8e34facf --- /dev/null +++ b/dist/assets/examples/es/01_Form/03_Regular_Polygon.js @@ -0,0 +1,43 @@ +/* + * @name Polígono regular + * @description ¿Cuál es tu favorito? ¿Pentágono? ¿Hexágono? ¿Heptágono? ¿No? + * ¿O el icoságono? La función polygon() creada para este ejemplo es + * capaz de dibujar cualquier polígono regular. Trata con distintos números en los paráemtros de + * la función polygon() dentro de draw() para explorar. + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + polygon(0, 0, 82, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + polygon(0, 0, 80, 20); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + polygon(0, 0, 70, 7); + pop(); +} + +function polygon(x, y, radius, npoints) { + let angle = TWO_PI / npoints; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius; + let sy = y + sin(a) * radius; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/es/01_Form/04_Star.js b/dist/assets/examples/es/01_Form/04_Star.js new file mode 100644 index 0000000000..e63b1d93c8 --- /dev/null +++ b/dist/assets/examples/es/01_Form/04_Star.js @@ -0,0 +1,46 @@ +/* + * @name Estrella + * @description La función star() creada para este ejemplo es capaz de + * dibujar una gran grama de figuras. Prueba poniendo distintos números en los parámetros de + * la función star() dentro de draw() para explorar. + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + star(0, 0, 5, 70, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + star(0, 0, 80, 100, 40); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + star(0, 0, 30, 70, 5); + pop(); +} + +function star(x, y, radius1, radius2, npoints) { + let angle = TWO_PI / npoints; + let halfAngle = angle / 2.0; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius2; + let sy = y + sin(a) * radius2; + vertex(sx, sy); + sx = x + cos(a + halfAngle) * radius1; + sy = y + sin(a + halfAngle) * radius1; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/es/01_Form/05_Triangle_Strip.js b/dist/assets/examples/es/01_Form/05_Triangle_Strip.js new file mode 100644 index 0000000000..2a75c76898 --- /dev/null +++ b/dist/assets/examples/es/01_Form/05_Triangle_Strip.js @@ -0,0 +1,38 @@ +/* + * @name Tira de triángulos + * @description Ejemplo por Ira Greenberg. Genera un anillo cerrado usando la + * función vertex() y el modo beginShape(TRIANGLE_STRIP). Las variables outsideRadius + * e insideRadius controlan los radios externo e interno del anillo, respectivamente. + */ +let x; +let y; +let outsideRadius = 150; +let insideRadius = 100; + +function setup() { + createCanvas(720, 400); + background(204); + x = width / 2; + y = height / 2; +} + +function draw() { + background(204); + + let numPoints = int(map(mouseX, 0, width, 6, 60)); + let angle = 0; + let angleStep = 180.0 / numPoints; + + beginShape(TRIANGLE_STRIP); + for (let i = 0; i <= numPoints; i++) { + let px = x + cos(radians(angle)) * outsideRadius; + let py = y + sin(radians(angle)) * outsideRadius; + angle += angleStep; + vertex(px, py); + px = x + cos(radians(angle)) * insideRadius; + py = y + sin(radians(angle)) * insideRadius; + vertex(px, py); + angle += angleStep; + } + endShape(); +} diff --git a/dist/assets/examples/es/01_Form/06_Bezier.js b/dist/assets/examples/es/01_Form/06_Bezier.js new file mode 100644 index 0000000000..69be92268d --- /dev/null +++ b/dist/assets/examples/es/01_Form/06_Bezier.js @@ -0,0 +1,27 @@ +/* + * @name Bezier + * @description Los primeros dos parámetros de la función bezier() especifican + * el primer punto en la curva y los últimos dos parámetros especifican el último punto. + * Los parámetros de al medio definen los puntos de control que definen la figura de la curva. + */ +function setup() { + createCanvas(720, 400); + stroke(255); + noFill(); +} + +function draw() { + background(0); + for (let i = 0; i < 200; i += 20) { + bezier( + mouseX - i / 2.0, + 40 + i, + 410, + 20, + 440, + 300, + 240 - i / 16.0, + 300 + i / 8.0 + ); + } +} diff --git a/dist/assets/examples/es/01_Form/07_3D_Primitives.js b/dist/assets/examples/es/01_Form/07_3D_Primitives.js new file mode 100644 index 0000000000..5a0740519e --- /dev/null +++ b/dist/assets/examples/es/01_Form/07_3D_Primitives.js @@ -0,0 +1,30 @@ +/* + * @name Primitivas 3D + * @frame 720,400 (optional) + * @description Ubicar matemáticamente objetos 3D en un espacio sintétito. + * Las funciones box() y sphere() toman al menos un parámetro para especificar su + * tamaño. Estas figuras son posicionadas usando la función translate(). + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(100); + + noStroke(); + fill(50); + push(); + translate(-275, 175); + rotateY(1.25); + rotateX(-0.9); + box(100); + pop(); + + noFill(); + stroke(255); + push(); + translate(500, height * 0.35, -200); + sphere(300); + pop(); +} diff --git a/dist/assets/examples/es/01_Form/08_Trig_Wheels_and_Pie_Chart.js b/dist/assets/examples/es/01_Form/08_Trig_Wheels_and_Pie_Chart.js new file mode 100644 index 0000000000..20597a112e --- /dev/null +++ b/dist/assets/examples/es/01_Form/08_Trig_Wheels_and_Pie_Chart.js @@ -0,0 +1,88 @@ +/* + * @name Trig Wheels and Pie Chart + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to create +a trig color wheel and a visualization of a population age data as a +pie chart.
+ Functions are +created for the canvas setup, trig color wheel, drawslice, and pie +chart. The size of the slices are determined as well as their color +range. The pie chart is separated by definitive color per value +whereas the trig color wheel has a fixed slice amount with a range +color fill. +*/ + +function setup() { + createCanvas(400, 400); + colorMode(HSB); + angleMode(DEGREES); + + //vars for color wheel center point + let x = width / 2; + let y = height / 2 + 100; + colorWheel(x, y, 100); //slide 11 + + noStroke(); + pieChartPop(200, 100); //slide 12 +} + +//**** slide 12 pie chart trig demo +function pieChartPop(x, y) { + let [total, child, young, adult, senior, elder] = [577, 103, 69, + 122, 170, 113 + ]; + let startValue = 0; + let range = 0; + + //child slice + range = child / total; + drawSlice("blue", x, y, 200, startValue, startValue + range); + startValue += range; + //young slice + range = young / total; + drawSlice("orange", x, y, 200, startValue, startValue + range); + startValue += range; + //adult slice + range = adult / total; + drawSlice("green", x, y, 200, startValue, startValue + range); + startValue += range; + //senior slice + range = senior / total; + drawSlice("tan", x, y, 200, startValue, startValue + range); + startValue += range; + //elder slice + range = elder / total; + drawSlice("pink", x, y, 200, startValue, startValue + range); + startValue += range; + +} + +/** + * drawSlice - draw colored arc based on angle percentages. slide 13 + * Adjust angles so that 0% starts at top (actually -90). + * @param {color} fColor - fill color + * @param {number} x - center x + * @param {number} y - center y + * @param {number} d - diameter + * @param {float} percent1 - starting percentage + * @param {float} percent2 - ending percentage + */ +function drawSlice(fColor, x, y, d, percent1, percent2) { + fill(fColor); + arc(x, y, d, d, -90 + percent1 * 360, -90 + percent2 * 360); +} + +//**** slide 11 trig demo +function colorWheel(x, y, rad) { + strokeWeight(10); + strokeCap(SQUARE); + + //Iterate 360 degrees of lines, +10deg per turn + for (let a = 0; a < 360; a += 10) { + stroke(a, 150, 200); //hue based on a + //radius is 100, angle is a degrees + line(x, y, x + rad * cos(a), + y + rad * sin(a)); + } +} diff --git a/dist/assets/examples/es/02_Data/00_Variables.js b/dist/assets/examples/es/02_Data/00_Variables.js new file mode 100644 index 0000000000..5b4b2b4e1b --- /dev/null +++ b/dist/assets/examples/es/02_Data/00_Variables.js @@ -0,0 +1,37 @@ +/* + * @name Variables + * @description Las variables son usadas para almacenar valores. En este ejemplo, cambia + * los valores de las variables para cambiar la composición. + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(153); + strokeWeight(4); + strokeCap(SQUARE); + + let a = 50; + let b = 120; + let c = 180; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); +} diff --git a/dist/assets/examples/es/02_Data/01_True_and_False.js b/dist/assets/examples/es/02_Data/01_True_and_False.js new file mode 100644 index 0000000000..2cecea384c --- /dev/null +++ b/dist/assets/examples/es/02_Data/01_True_and_False.js @@ -0,0 +1,30 @@ +/* + * @name True y False + * @description Una variable de tipo Boolean tiene solo dos valores posibles: true (verdadero) o false (falso). + * Es común usar booleanos con instrucciones de control para determinar el flujo + * de un programa. En este ejemplo, cuando el valor booleano "x" es verdadero, se dibujan + * líneas negras verticales y cuando el valor booleano "x" es falso, se dibujan líneas grises horizontales. + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + + let b = false; + let d = 20; + let middle = width / 2; + + for (let i = d; i <= width; i += d) { + b = i < middle; + + if (b === true) { + // Línea vertical + line(i, d, i, height - d); + } + + if (b === false) { + // Línea horizontal + line(middle, i - middle + d, width - d, i - middle + d); + } + } +} diff --git a/dist/assets/examples/es/02_Data/03_Variable_Scope.js b/dist/assets/examples/es/02_Data/03_Variable_Scope.js new file mode 100644 index 0000000000..3da8554047 --- /dev/null +++ b/dist/assets/examples/es/02_Data/03_Variable_Scope.js @@ -0,0 +1,48 @@ +/* + * @name Alcance de variabless + * @description Las variables tienen un alcance global o local. Por ejemplo, + * las variables declaradas dentro de las funciones setup() o draw() solamente pueden + * ser usadas dentro de esas funciones. Las variables globales, esto es, variables declaradas fuera de setup() y + * draw(), pueden ser usadas en cualquier parte del programa. Si una variable local + * es declarada con el mismo nombre que una variable global, el programa usará + * el valor local para hacer sus cálculos dentro de la función. + * Las variables son localizadas dentro de cada bloque, el espacio entre llaves { y }. + */ +let a = 80; // Crea una variable global "a" + +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + noLoop(); +} + +function draw() { + // Dibuja una línea usando la variable global "a" + line(a, 0, a, height); + + // Crea una nueva variable local "a" al for() + for (let a = 120; a < 200; a += 3) { + line(a, 0, a, height); + } + + // Llamada a la función drawAnotherLine() + drawAnotherLine(); + + // Llamada a la función drawYetAnotherLine() + drawYetAnotherLine(); +} + +function drawAnotherLine() { + // Crea una nueva variable local "a" de este método + let a = 320; + // Dibuja una línea usando la variable local "a" + line(a, 0, a, height); +} + +function drawYetAnotherLine() { + // Como no definimos una nueva variable local "a", + // esta línea se dibuja usando la variable global original + // "a" que tiene un valor de 20. + line(a + 3, 0, a + 3, height); +} diff --git a/dist/assets/examples/es/02_Data/04_Numbers.js b/dist/assets/examples/es/02_Data/04_Numbers.js new file mode 100644 index 0000000000..9ac71d676b --- /dev/null +++ b/dist/assets/examples/es/02_Data/04_Numbers.js @@ -0,0 +1,30 @@ +/* + * @name Números + * @frame 720,400 + * @description Los números pueden ser escritos con o sin decimales. Un número * entero (más comúnmente conocido como int por el inglés integer) es un + * número sin fracción decimal. Un número de punto flotante (conocido como float + * por el inglés floating-point number) es un número con fracción decimal. + */ +let a = 0; // Crea una variable global "a" de tipo Number +let b = 0; // Crea una variable global "b" de tipo Number + +function setup() { + createCanvas(720, 400); + stroke(255); +} + +function draw() { + background(0); + + a = a + 1; // Incrementar a con un int + b = b + 0.2; //Incrementar b con un float + line(a, 0, a, height / 2); + line(b, height / 2, b, height); + + if (a > width) { + a = 0; + } + if (b > width) { + b = 0; + } +} diff --git a/dist/assets/examples/es/03_Arrays/00_Array.js b/dist/assets/examples/es/03_Arrays/00_Array.js new file mode 100644 index 0000000000..cb374a5534 --- /dev/null +++ b/dist/assets/examples/es/03_Arrays/00_Array.js @@ -0,0 +1,44 @@ +/* + * @name Arreglo + * @description Un arreglo es una lista de datos. Cada dato en un arreglo + * es idenfiticado por un número de índice, representando su posición en + * el arreglo. Los arreglos son indexados en cero, lo que significa que + * el primer elemento en el arreglo es [0], el segundo es [1], y así. + * En este ejemplo, un arregllo llamado "coswav" es creado y + * llenado con valores de la función coseno. Estos datos son mostrados + * de tres maneras diferentes en pantalla. + */ +let coswave = []; + +function setup() { + createCanvas(720, 360); + for (let i = 0; i < width; i++) { + let amount = map(i, 0, width, 0, PI); + coswave[i] = abs(cos(amount)); + } + background(255); + noLoop(); +} + +function draw() { + let y1 = 0; + let y2 = height / 3; + for (let i = 0; i < width; i += 3) { + stroke(coswave[i] * 255); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = y1 + y1; + for (let i = 0; i < width; i += 3) { + stroke((coswave[i] * 255) / 4); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = height; + for (let i = 0; i < width; i += 3) { + stroke(255 - coswave[i] * 255); + line(i, y1, i, y2); + } +} diff --git a/dist/assets/examples/es/03_Arrays/01_Array_2d.js b/dist/assets/examples/es/03_Arrays/01_Array_2d.js new file mode 100644 index 0000000000..144d3d9c81 --- /dev/null +++ b/dist/assets/examples/es/03_Arrays/01_Array_2d.js @@ -0,0 +1,39 @@ +/* + * @name Arreglo 2D + * @description Demuestra la sintaxis para crear un arreglo + de dos dimensiones (2D). + * Se accede a los valores en un arreglo 2D a través de dos valores de índice. + * Los arreglos 2D son útiles para almacenar imágenes. En este ejemplo, cada punto + * es coloreado en relación a su distancia del centro de la imagen. + */ +let distances = []; +let maxDistance; +let spacer; + +function setup() { + createCanvas(720, 360); + maxDistance = dist(width / 2, height / 2, width, height); + for (let x = 0; x < width; x++) { + distances[x] = []; // Crear un arreglo anidado + for (let y = 0; y < height; y++) { + let distance = dist(width / 2, height / 2, x, y); + distances[x][y] = (distance / maxDistance) * 255; + } + } + spacer = 10; + noLoop(); // Correr draw() una vez y luego parar +} + +function draw() { + background(0); + // Este loop anidado recorre los valores en los arreglos basado + // en la variable spacer, así que hay más valores en el arreglo + // que los que dibujamos. Cambia el valor de la variable spacer + // para cambiar la densidad de los puntos. + for (let x = 0; x < width; x += spacer) { + for (let y = 0; y < height; y += spacer) { + stroke(distances[x][y]); + point(x + spacer / 2, y + spacer / 2); + } + } +} diff --git a/dist/assets/examples/es/03_Arrays/02_Array_Objects.js b/dist/assets/examples/es/03_Arrays/02_Array_Objects.js new file mode 100644 index 0000000000..dd67e8e45b --- /dev/null +++ b/dist/assets/examples/es/03_Arrays/02_Array_Objects.js @@ -0,0 +1,71 @@ +/* + * @name Arreglo de objetos + * @description Demuestra la sintaxis para crear un arreglo de objetos definidos por el programador. + */ + +class Module { + constructor(xOff, yOff, x, y, speed, unit) { + this.xOff = xOff; + this.yOff = yOff; + this.x = x; + this.y = y; + this.speed = speed; + this.unit = unit; + this.xDir = 1; + this.yDir = 1; + } + + // Método personalizado para refrescar las variables + update() { + this.x = this.x + this.speed * this.xDir; + if (this.x >= this.unit || this.x <= 0) { + this.xDir *= -1; + this.x = this.x + 1 * this.xDir; + this.y = this.y + 1 * this.yDir; + } + if (this.y >= this.unit || this.y <= 0) { + this.yDir *= -1; + this.y = this.y + 1 * this.yDir; + } + } + + // Método personalizado para dibujar el objeto + draw() { + fill(255); + ellipse(this.xOff + this.x, this.yOff + this.y, 6, 6); + } +} + +let unit = 40; +let count; +let mods = []; + +function setup() { + createCanvas(720, 360); + noStroke(); + let wideCount = width / unit; + let highCount = height / unit; + count = wideCount * highCount; + + let index = 0; + for (let y = 0; y < highCount; y++) { + for (let x = 0; x < wideCount; x++) { + mods[index++] = new Module( + x * unit, + y * unit, + unit / 2, + unit / 2, + random(0.05, 0.8), + unit + ); + } + } +} + +function draw() { + background(0); + for (let i = 0; i < count; i++) { + mods[i].update(); + mods[i].draw(); + } +} diff --git a/dist/assets/examples/es/03_Arrays/03_Walk_Over_2dArray.js b/dist/assets/examples/es/03_Arrays/03_Walk_Over_2dArray.js new file mode 100644 index 0000000000..e5577e7383 --- /dev/null +++ b/dist/assets/examples/es/03_Arrays/03_Walk_Over_2dArray.js @@ -0,0 +1,85 @@ +/* + * @name Walk Over 2dArray + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to display 2D array contents on the canvas +using regular for and for-of loops in multiple different ways.
+ A function is created for the canvas, the 2D + array (Friend Array) is initialized and walked over using nested + loops in different ways. Variables x and y are used to place the + array item on the canvas in the form of 2D array. + The final nested loop is used to initialize 2D + array (Fish Array) with random Integers (fish ages). +*/ + + +//"use strict"; //catch some common coding errors + + +/** + * setup : + */ +function setup() { + createCanvas(400, 600); + //create 2D array, slide 4 + let friendArray = [ + ["Nona", "mac & cheese", "orange", "Eid al-fitr"], + ["Marylin", "ice cream", "blue", "Halloween"], + ["Rashaad", "garbage plates", "turquoise", "Christmas"], + ["Ava", "sushi", "pink", "New Years"] + ]; + friendArray.push(["Xavier", "Louisiana creole", "red", "their birthday"]); + + //walking 2D array, slide 6 + let y = 20; // Start row based on text size of 20 + for (let f = 0; f < friendArray.length; f++) { // outer array + let x = 10; // Start item in this row + for (let t = 0; t < friendArray[f].length; t++) { //inner + text(friendArray[f][t], x, y); + x += textWidth(friendArray[f][t]) + 20; //place next item + } + y += 28; // place next row + } + + //walking 2D array, variation on slide 6 + //with embedded arithmetic for y + // + for (let f = 0; f < friendArray.length; f++) { // outer array + let x = 10; // Start item in this row + for (let t = 0; t < friendArray[f].length; t++) { //inner + //y is v-padding + LCV * v-spacing + text(friendArray[f][t], x, 200 + f * 28); + x += textWidth(friendArray[f][t]) + 20; //place next item + } + } + + //walking 2D array, slide 7 + //need to use x and y variables to manage canvas placement + y = 400; + for (let friend of friendArray) { + let x = 10; // Start item in this row + console.log("x and y", x, y); + console.log("friend:", friend); + for (let item of friend) { + console.log("item & x:", item, x); + text(item, x, y); + x += textWidth(item) + 20; //place next item + } + y += 28; // place next row + } + + //slide 9, creating 2D array: schools of fish ages + console.log("\n *** Fish ages in 2D ***"); + const schools = []; + //4 schools of fish + for (let t = 0; t < 4; t++) { + schools[t] = []; //initialize this school + console.log("schools[t]?", t, schools[t]); + + // Add 10 randomized ages to the array + for (let a = 0; a < 10; a++) { + schools[t].push(round(random(1, 5))); + } + } + console.log(schools); + } diff --git a/dist/assets/examples/es/04_Control/00_Iteration.js b/dist/assets/examples/es/04_Control/00_Iteration.js new file mode 100644 index 0000000000..39cb8ac76d --- /dev/null +++ b/dist/assets/examples/es/04_Control/00_Iteration.js @@ -0,0 +1,41 @@ +/* + * @name Iteración + * @description Iteración con una estructura "for" para construir figuras repetitivas. + */ +let y; +let num = 14; + +function setup() { + createCanvas(720, 360); + background(102); + noStroke(); + + // Dibujar barras blancas + fill(255); + y = 60; + for (let i = 0; i < num / 3; i++) { + rect(50, y, 475, 10); + y += 20; + } + + // Barras grises + fill(51); + y = 40; + for (let i = 0; i < num; i++) { + rect(405, y, 30, 10); + y += 20; + } + y = 50; + for (let i = 0; i < num; i++) { + rect(425, y, 30, 10); + y += 20; + } + + // Líneas delgadas + y = 45; + fill(0); + for (let i = 0; i < num - 1; i++) { + rect(120, y, 40, 1); + y += 20; + } +} diff --git a/dist/assets/examples/es/04_Control/01_Embedded_Iteration.js b/dist/assets/examples/es/04_Control/01_Embedded_Iteration.js new file mode 100644 index 0000000000..b1e58b0628 --- /dev/null +++ b/dist/assets/examples/es/04_Control/01_Embedded_Iteration.js @@ -0,0 +1,21 @@ +/* + * @name Iteración anidada + * @description Anidar estructuras "for" permite repetición en dos dimensiones. + */ +function setup() { + createCanvas(720, 360); + background(0); + noStroke(); + + let gridSize = 35; + + for (let x = gridSize; x <= width - gridSize; x += gridSize) { + for (let y = gridSize; y <= height - gridSize; y += gridSize) { + noStroke(); + fill(255); + rect(x - 1, y - 1, 3, 3); + stroke(255, 50); + line(x, y, width / 2, height / 2); + } + } +} diff --git a/dist/assets/examples/es/04_Control/02_Conditionals_1.js b/dist/assets/examples/es/04_Control/02_Conditionals_1.js new file mode 100644 index 0000000000..f101596663 --- /dev/null +++ b/dist/assets/examples/es/04_Control/02_Conditionals_1.js @@ -0,0 +1,26 @@ +/* + * @name Condicionales 1 + * @description Las condiciones son como preguntas. + * Permiten que un programa decida ejecutar una acción + * si la respuesta a una pregunta es afirmativa o hacer otra + * acción si la respuesta a la pregunta es negativa. + * Las preguntas formuladas dentro de un programa son siempre + * instrucciones lógicas o relacionales. Por ejemplo, si la + * variable 'i' es igual a cero, entonces dibuja una línea. + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 10; i < width; i += 10) { + // Si 'i' divide a 20 sin resto, dibuja la primera línea + // en caso contrario, dibuja la segunda línea + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + } else { + stroke(153); + line(i, 20, i, 180); + } + } +} diff --git a/dist/assets/examples/es/04_Control/03_Conditionals_2.js b/dist/assets/examples/es/04_Control/03_Conditionals_2.js new file mode 100644 index 0000000000..b2324c682c --- /dev/null +++ b/dist/assets/examples/es/04_Control/03_Conditionals_2.js @@ -0,0 +1,29 @@ +/* + * @name Condicionales 2 + * @description Extendemos el lenguaje de los condicionales + * del ejemplo anterior añadiendo la palabra clave "else". + * Esto permite construir condicionales que preguntan + * dos o más preguntas en secuencia, cada una con una acción + * asociada. + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 2; i < width - 2; i += 4) { + // Si 'i' divide a 20 sin resto + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + // Si 'i' divide a 10 sin resto + } else if (i % 10 === 0) { + stroke(153); + line(i, 20, i, 180); + // Si ninguna de las condiciones anteriores es cierta, + // entonces dibuja esta línea + } else { + stroke(102); + line(i, height / 2, i, height - 20); + } + } +} diff --git a/dist/assets/examples/es/04_Control/04_Logical_Operators.js b/dist/assets/examples/es/04_Control/04_Logical_Operators.js new file mode 100644 index 0000000000..dd03f26d67 --- /dev/null +++ b/dist/assets/examples/es/04_Control/04_Logical_Operators.js @@ -0,0 +1,42 @@ +/* + * @name Operadores lógicos + * @description Los operadores lógicos AND (&&) y OR (||), (Y y Ó, respectivamente),son usados para + * combinar instrucciones relacionales simples en expresiones más complejas + * El operador NOT (!), NO, es usado para negar una declaración de carácter boolean. + */ +let test = false; + +function setup() { + createCanvas(720, 360); + background(126); + + for (let i = 5; i <= height; i += 5) { + // Y lógico + stroke(0); + if (i > 35 && i < 100) { + line(width / 4, i, width / 2, i); + test = false; + } + + // Ó lógico + stroke(76); + if (i <= 35 || i >= 100) { + line(width / 2, i, width, i); + test = true; + } + + // Probando si un valor boolean es "verdadero" + // La expresión "if(test)" es equivalente a "if(test == true)" + if (test) { + stroke(0); + point(width / 3, i); + } + + // Probando si un valor boolean es "falso" + // La expresión "if(!test)" es equivalente a "if(test == false)" + if (!test) { + stroke(255); + point(width / 4, i); + } + } +} diff --git a/dist/assets/examples/es/04_Control/05_Logical_Operators_2.js b/dist/assets/examples/es/04_Control/05_Logical_Operators_2.js new file mode 100644 index 0000000000..2684feb956 --- /dev/null +++ b/dist/assets/examples/es/04_Control/05_Logical_Operators_2.js @@ -0,0 +1,91 @@ +/* + * @name Logical Operators 2 + * @frame 400,400 + * @description contributed by + Prof WM Harris, How + to create Xboxes with one global variable and create conditions with + boolean variables and boolean expressions by utilizing Boolean + operators ||, &&, and ! to do boundary checking.
+ Functions + are created for both the canvas set up as well as the creation of + the boxes. Background color is dependent on the location of the + boxes in the canvas space. When mouse button and key are pressed + simultaneously, the “where” text and box color changes to cyan, + but if the mouse button is clicked alone then the animation will + start. When q or Q are pressed the text “Did you type q or Q?” + will change to blue, else it will be purple. If the mouse is placed + within the orange box containing the text, “withinRect” then the + shape will turn pink. + */ + + +//1 coordinate for everything :) +let where = 0; //control boxes' positions + +function setup() { + createCanvas(400, 400); +} + +function draw() { + //similar to slide 4 use of OR, || + //to set bg color of canvas + if ((where < 0) || (where > height)) { + background("beige"); + } else { + background("chocolate"); + } + + //similar to slide 4 use of AND, && + //to set fill color of box & text + if (mouseIsPressed && keyIsPressed) { + fill("cyan"); + } else { + fill(255); + } + + //boxL + rect(where, where, 40); + + //boxR, pad x coordinate for size of box + rect(width - where - 40, where, 40); + + //Move the boxes + where = where + 1; + + //Show the value of where the boxes are + text("where is " + where, 150, 30); + + //testing not, ! and or, || operators + if (!(key === "q" || key === "Q")) { + fill("purple"); + } else { + fill("dodgerBlue"); + } + //Show the current key value + text("Did you type a q or Q? " + key, 150, 70); + + //*** Boundary checking *** + //Is the mouse within rect boundary? + //left, right, top, bottom + let withinRect = (mouseX >= 150) && + (mouseX <= 150 + 100) && + (mouseY >= 300) && + (mouseY <= 300 + 40); + //fill color based on value of withinRect + if (withinRect) { + fill("pink"); + } else { + fill("orange"); + } + //draw the rect + rect(150, 300, 100, 40); + //show withinRect value as label on rect + fill(0); + text("withinRect " + withinRect, 160, 320); +} + +//boxes restart +function mousePressed() { + //Reset boxes back up and above the canvas + where = -50; +} \ No newline at end of file diff --git a/dist/assets/examples/es/04_Control/06_Conditional_Shapes.js b/dist/assets/examples/es/04_Control/06_Conditional_Shapes.js new file mode 100644 index 0000000000..8d544e9081 --- /dev/null +++ b/dist/assets/examples/es/04_Control/06_Conditional_Shapes.js @@ -0,0 +1,48 @@ +/* + * @name Conditional Shapes + * @frame 400,400 + * @description contributed by + Prof WM Harris, How + to draw different shapes mid canvas depending on the mouse position.
+ Functions + are created for the main canvas set up with the markers on the left and + right hand sides. One is also created for the location of the mouse + regarding the canvas and the markers. If the mouse is within the + outer left hand beige rectangle, then the shape of circle is drawn + down the center of the canvas. If the mouse is within the outer right + hand beige rectangle, then the shape of square is drawn down the + center of the canvas. +*/ +function setup() { + createCanvas(400, 400); + strokeWeight(3); + //center squares to match circles + rectMode(CENTER); + + //draw rects to mark far sides + noStroke(); + fill("beige"); + rect(5, height / 2, 10, height); + rect(width - 5, height / 2, 10, height); + fill("orange"); + stroke("brown"); + + } + + function draw() { + point(mouseX, mouseY); + + //if (test) {doThis; } + //test: mouseX on far left of canvas + //doThis: draw a circle at mouseY + if (mouseX < 10) { + circle(width / 2, mouseY, 20); + } + + //test: mouseX on far right of canvas + //doThis: draw a square at mouseY + if (mouseX > width - 10) { + square(width / 2, mouseY, 20); + } + + } diff --git a/dist/assets/examples/es/05_Image/00_Load_and_Display_Image.js b/dist/assets/examples/es/05_Image/00_Load_and_Display_Image.js new file mode 100644 index 0000000000..a7ef6fd310 --- /dev/null +++ b/dist/assets/examples/es/05_Image/00_Load_and_Display_Image.js @@ -0,0 +1,21 @@ +/* + * @name Cargar y mostrar imagen + * @description Las imágenes pueden ser cargadas y mostradas en la pantalla en su tamaño original o cualquier otro. + *

Para correr este ejemplo localmente, necesitarás un archivo de imagen + * y un + * servidor local.

corriendo. + */ + +let img; // Declarar variable 'img'. + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // Cargar la imagen +} + +function draw() { + // Muestra la imagen en su tamaño original en la posición (0,0) + image(img, 0, 0); + // Muestra la imagen en la posición (0, height/2) a la mitad del tamaño + image(img, 0, height / 2, img.width / 2, img.height / 2); +} diff --git a/dist/assets/examples/es/05_Image/01_Background_Image.js b/dist/assets/examples/es/05_Image/01_Background_Image.js new file mode 100644 index 0000000000..9d55cbd1f9 --- /dev/null +++ b/dist/assets/examples/es/05_Image/01_Background_Image.js @@ -0,0 +1,31 @@ +/* + * @name Imagen de fondo + * @description Este ejemplo presenta la manera más rápida de cargar una + * imagen de fondo. Para cargar una imagen como fondo, + * idebe tener el mismo ancho y altura que el programa. + *

Para correr este ejemplo localmente, necesitarás un archivo de imagen + * y un + * servidor local.

corriendo. + */ + +let bg; +let y = 0; + +function setup() { + // La imagen de fondo debe tener el mismo tamaño que el lienzo, según el método createCanvas(). + // En este programa, el tamaño de la imagen es de 720x400 pixels. + bg = loadImage('assets/moonwalk.jpg'); + createCanvas(720, 400); +} + +function draw() { + background(bg); + + stroke(226, 204, 0); + line(0, y, width, y); + + y++; + if (y > height) { + y = 0; + } +} diff --git a/dist/assets/examples/es/05_Image/02_Transparency.js b/dist/assets/examples/es/05_Image/02_Transparency.js new file mode 100644 index 0000000000..a0a191e6ad --- /dev/null +++ b/dist/assets/examples/es/05_Image/02_Transparency.js @@ -0,0 +1,24 @@ +/* + * @name Transparencia + * @description Mueve el cursor de izquierda a derecha a lo largo de la imagen para cambiar su + * posición. Este program superpone una imagen sobre otra, modificando el valor alpha de la imagen con la función tint(). + *

Para correr este ejemplo localmente, necesitarás un archivo de imagen + * y un + * servidor local.

corriendo. + */ +let img; +let offset = 0; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // Cargar una imagen al programa +} + +function draw() { + image(img, 0, 0); // Mostrar al máximo de opacidad + let dx = mouseX - img.width / 2 - offset; + offset += dx * easing; + tint(255, 127); // Mostrar a media opacidad + image(img, offset, 0); +} diff --git a/dist/assets/examples/es/05_Image/03_Alpha_Mask.js b/dist/assets/examples/es/05_Image/03_Alpha_Mask.js new file mode 100644 index 0000000000..ed747c4428 --- /dev/null +++ b/dist/assets/examples/es/05_Image/03_Alpha_Mask.js @@ -0,0 +1,28 @@ +/* + * @name Alpha Mask + * @description Loads a "mask" for an image to specify the transparency in + * different parts of the image. The two images are blended together using + * the mask() method of p5.Image. + *

Para correr este ejemplo localmente, necesitarás un archivo de imagen + * y un + * servidor local.

corriendo. + */ +let img; +let imgMask; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); + imgMask = loadImage('assets/mask.png'); +} + +function setup() { + createCanvas(720, 400); + img.mask(imgMask); + imageMode(CENTER); +} + +function draw() { + background(0, 102, 153); + image(img, width / 2, height / 2); + image(img, mouseX, mouseY); +} diff --git a/dist/assets/examples/es/05_Image/04_Create_Image.js b/dist/assets/examples/es/05_Image/04_Create_Image.js new file mode 100644 index 0000000000..fca9f40817 --- /dev/null +++ b/dist/assets/examples/es/05_Image/04_Create_Image.js @@ -0,0 +1,25 @@ +/* + * @name Crear una imagen + * @description La función createImage() provee un buffer fresco de pixeles para experimentar. + * Este ejemplo crea un gradiente de imagen. + */ +let img; // Declarar variable 'img'. + +function setup() { + createCanvas(720, 400); + img = createImage(230, 230); + img.loadPixels(); + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + let a = map(y, 0, img.height, 255, 0); + img.set(x, y, [0, 153, 204, a]); + } + } + img.updatePixels(); +} + +function draw() { + background(0); + image(img, 90, 80); + image(img, mouseX - img.width / 2, mouseY - img.height / 2); +} diff --git a/dist/assets/examples/es/05_Image/05_Pointillism.js b/dist/assets/examples/es/05_Image/05_Pointillism.js new file mode 100644 index 0000000000..64d29a6919 --- /dev/null +++ b/dist/assets/examples/es/05_Image/05_Pointillism.js @@ -0,0 +1,33 @@ +/* + * @name Puntillismo + * @description Por Dan Shiffman. La posición horizontal del ratón controla el tamaño de + * los puntos. Crea un efecto puntillista simple usando elipses coloreadas según los pixeles en una imagen. + *

Para correr este ejemplo localmente, necesitarás un archivo de imagen + * y un + * servidor local.

corriendo. + */ +let img; +let smallPoint, largePoint; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 400); + smallPoint = 4; + largePoint = 40; + imageMode(CENTER); + noStroke(); + background(255); + img.loadPixels(); +} + +function draw() { + let pointillize = map(mouseX, 0, width, smallPoint, largePoint); + let x = floor(random(img.width)); + let y = floor(random(img.height)); + let pix = img.get(x, y); + fill(pix, 128); + ellipse(x, y, pointillize, pointillize); +} diff --git a/dist/assets/examples/es/05_Image/06_Blur.js b/dist/assets/examples/es/05_Image/06_Blur.js new file mode 100644 index 0000000000..2374bc0345 --- /dev/null +++ b/dist/assets/examples/es/05_Image/06_Blur.js @@ -0,0 +1,89 @@ +/* + * @name Blur + * @description A low-pass filter that blurs an image. This program analyzes every pixel in an image and blends it with all the neighboring pixels to blur the image. + *

This example is ported from the Blur example + * on the Processing website + */ +// to consider all neighboring pixels we use a 3x3 array +// and normalize these values +// v is the normalized value +let v = 1.0 / 9.0; +// kernel is the 3x3 matrix of normalized values +let kernel = [[ v, v, v ], [ v, v, v ], [ v, v, v ]]; + +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// if loadImage() is called in setup(), the image won't appear +// since noLoop() restricts draw() to execute only once +// (one execution of draw() is not enough time for the image to load), +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover.png"); +} + +// setup() runs once after preload +function setup() { + // create canvas + createCanvas(710, 400); + // noLoop() makes draw() run only once, not in a loop + noLoop(); +} + + +// draw() runs after setup(), normally on a loop +// in this case it runs only once, because of noDraw() +function draw() { + // place the original image on the upper left corner + image(img, 0, 0); + + // create a new image, same dimensions as img + edgeImg = createImage(img.width, img.height); + + // load its pixels + edgeImg.loadPixels(); + + // two for() loops, to iterate in x axis and y axis + // since the kernel assumes that the pixel + // has pixels above, under, left, and right + // we need to skip the first and last column and row + // x then goes from 1 to width - 1 + // y then goes from 1 to height - 1 + for (let x = 1; x < img.width; x++) { + for (let y = 1; y < img.height; y++) { + // kernel sum for the current pixel starts as 0 + let sum = 0; + + // kx, ky variables for iterating over the kernel + // kx, ky have three different values: -1, 0, 1 + for (kx = -1; kx <= 1; kx++) { + for (ky = -1; ky <= 1; ky++) { + let xpos = x + kx; + let ypos = y + ky; + + // since our image is grayscale, + // RGB values are identical + // we retrieve the red value for this example + // (green and blue work as well) + let val = red(img.get(xpos, ypos)); + + // accumulate the kernel sum + // kernel is a 3x3 matrix + // kx and ky have values -1, 0, 1 + // if we add 1 to kx and ky, we get 0, 1, 2 + // with that we can use it to iterate over kernel + // and calculate the accumulated sum + sum += kernel[kx+1][ky+1] * val; + } + } + + // set the value of the edgeImg pixel to the kernel sum + edgeImg.set(x, y, color(sum)); + } + } + // updatePixels() to write the changes on edgeImg + edgeImg.updatePixels(); + + // draw edgeImg at the right of the original image + image(edgeImg, img.width, 0); +} \ No newline at end of file diff --git a/dist/assets/examples/es/05_Image/07_EdgeDetection.js b/dist/assets/examples/es/05_Image/07_EdgeDetection.js new file mode 100644 index 0000000000..2c0509d44b --- /dev/null +++ b/dist/assets/examples/es/05_Image/07_EdgeDetection.js @@ -0,0 +1,93 @@ +/* + * @name Edge Detection + * @description A high-pass filter sharpens an image. This program analyzes every pixel in an image in relation to the neighboring pixels to sharpen the image. + *

This example is ported from the Edge Detection example + * on the Processing website + */ +// this program analyzes every pixel in an image +// in relation to the neighbouring pixels +// to sharpen the image + +// to consider all neighboring pixels we use a 3x3 array +// and normalize these values +// kernel is the 3x3 matrix of normalized values +let kernel = [[-1, -1, -1 ], [ -1, 9, -1 ], [-1, -1, -1 ]]; + +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// if loadImage() is called in setup(), the image won't appear +// since noLoop() restricts draw() to execute only once +// (one execution of draw() is not enough time for the image to load), +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover.png"); +} + +// setup() runs after preload, once() +function setup() { + // create canvas + createCanvas(710, 400); + // noLoop() makes draw() run only once, not in a loop + noLoop(); +} + +// draw() runs after setup(), normally on a loop +// in this case it runs only once, because of noDraw() +function draw() { + + // place the original image on the upper left corner + image(img, 0, 0); + + // create a new image, same dimensions as img + edgeImg = createImage(img.width, img.height); + + // load its pixels + edgeImg.loadPixels(); + + + // two for() loops, to iterate in x axis and y axis + // since the kernel assumes that the pixel + // has pixels above, under, left, and right + // we need to skip the first and last column and row + // x then goes from 1 to width - 1 + // y then goes from 1 to height - 1 + + for (let x = 1; x < img.width - 1; x++) { + for (let y = 1; y < img.height - 1; y++) { + // kernel sum for the current pixel starts as 0 + let sum = 0; + + // kx, ky variables for iterating over the kernel + // kx, ky have three different values: -1, 0, 1 + for (kx = -1; kx <= 1; kx++) { + for (ky = -1; ky <= 1; ky++) { + + let xpos = x + kx; + let ypos = y + ky; + let pos = (y + ky)*img.width + (x + kx); + // since our image is grayscale, + // RGB values are identical + // we retrieve the red value for this example + let val = red(img.get(xpos, ypos)); + // accumulate the kernel sum + // kernel is a 3x3 matrix + // kx and ky have values -1, 0, 1 + // if we add 1 to kx and ky, we get 0, 1, 2 + // with that we can use it to iterate over kernel + // and calculate the accumulated sum + sum += kernel[ky+1][kx+1] * val; + } + } + + // set the pixel value of the edgeImg + edgeImg.set(x, y, color(sum, sum, sum)); + } + } + + // updatePixels() to write the changes on edgeImg + edgeImg.updatePixels(); + + // draw edgeImg at the right of the original image + image(edgeImg, img.width, 0); +} diff --git a/dist/assets/examples/es/05_Image/08_Brightness.js b/dist/assets/examples/es/05_Image/08_Brightness.js new file mode 100644 index 0000000000..3c58a98876 --- /dev/null +++ b/dist/assets/examples/es/05_Image/08_Brightness.js @@ -0,0 +1,63 @@ +/* + * @name Brightness + * @description This program adjusts the brightness of a part of the image by calculating the distance of each pixel to the mouse. + *

This example is ported from the Brightness example + * on the Processing website + */ +// This program adjusts the brightness +// of a part of the image by +// calculating the distance of +// each pixel to the mouse. +let img; +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover_wide.jpg"); +} +// setup() runs after preload, once() +function setup() { + createCanvas(710, 400); + pixelDensity(1); + frameRate(30); +} + +function draw() { + image(img,0,0); + // Only need to load the pixels[] array once, because we're only + // manipulating pixels[] inside draw(), not drawing shapes. + loadPixels(); + // We must also call loadPixels() on the PImage since we are going to read its pixels. + img.loadPixels(); + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++ ) { + // Calculate the 1D location from a 2D grid + let loc = (x + y*img.width)*4; + // Get the R,G,B values from image + let r,g,b; + r = img.pixels[loc]; + // g = img.pixels[loc+1]; + // b = img.pixels[loc+2]; + // Calculate an amount to change brightness based on proximity to the mouse + // The closer the pixel is to the mouse, the lower the value of "distance" + let maxdist = 50;//dist(0,0,width,height); + let d = dist(x, y, mouseX, mouseY); + let adjustbrightness = 255*(maxdist-d)/maxdist; + r += adjustbrightness; + // g += adjustbrightness; + // b += adjustbrightness; + // Constrain RGB to make sure they are within 0-255 color range + r = constrain(r, 0, 255); + // g = constrain(g, 0, 255); + // b = constrain(b, 0, 255); + // Make a new color and set pixel in the window + let pixloc = (y*width + x)*4; + pixels[pixloc] = r; + pixels[pixloc+1] = r; + pixels[pixloc+2] = r; + pixels[pixloc+3] = 255; // Always have to set alpha + } + } + updatePixels(); +} \ No newline at end of file diff --git a/dist/assets/examples/es/05_Image/09_Convolution.js b/dist/assets/examples/es/05_Image/09_Convolution.js new file mode 100644 index 0000000000..eb953c6729 --- /dev/null +++ b/dist/assets/examples/es/05_Image/09_Convolution.js @@ -0,0 +1,91 @@ +/* + * @name Convolution + * @description Applies a convolution matrix to a portion of an image. Move mouse to apply filter to different parts of the image. This example is a port of Dan Shiffman's example for Processing. Original comments written by Dan unless otherwise specified. + *

To run this example locally, you will need an + * image file, and a running + * local server.

+ */ + +let img; +let w = 80; + +// It's possible to convolve the image with many different +// matrices to produce different effects. This is a high-pass +// filter; it accentuates the edges. +const matrix = [ [ -1, -1, -1 ], + [ -1, 9, -1 ], + [ -1, -1, -1 ] ]; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 400); + img.loadPixels(); + + // pixelDensity(1) for not scaling pixel density to display density + // for more information, check the reference of pixelDensity() + pixelDensity(1); +} + +function draw() { + // We're only going to process a portion of the image + // so let's set the whole image as the background first + background(img); + + // Calculate the small rectangle we will process + const xstart = constrain(mouseX - w/2, 0, img.width); + const ystart = constrain(mouseY - w/2, 0, img.height); + const xend = constrain(mouseX + w/2, 0, img.width); + const yend = constrain(mouseY + w/2, 0, img.height); + const matrixsize = 3; + + loadPixels(); + // Begin our loop for every pixel in the smaller image + for (let x = xstart; x < xend; x++) { + for (let y = ystart; y < yend; y++ ) { + let c = convolution(x, y, matrix, matrixsize, img); + + // retrieve the RGBA values from c and update pixels() + let loc = (x + y*img.width) * 4; + pixels[loc] = red(c); + pixels[loc + 1] = green(c); + pixels[loc + 2] = blue(c); + pixels[loc + 3] = alpha(c); + } + } + updatePixels(); +} + +function convolution(x, y, matrix, matrixsize, img) { + let rtotal = 0.0; + let gtotal = 0.0; + let btotal = 0.0; + const offset = Math.floor(matrixsize / 2); + for (let i = 0; i < matrixsize; i++){ + for (let j = 0; j < matrixsize; j++){ + + // What pixel are we testing + const xloc = (x + i - offset); + const yloc = (y + j - offset); + let loc = (xloc + img.width * yloc) * 4; + + // Make sure we haven't walked off our image, we could do better here + loc = constrain(loc, 0 , img.pixels.length - 1); + + // Calculate the convolution + // retrieve RGB values + rtotal += (img.pixels[loc]) * matrix[i][j]; + gtotal += (img.pixels[loc + 1]) * matrix[i][j]; + btotal += (img.pixels[loc + 2]) * matrix[i][j]; + } + } + // Make sure RGB is within range + rtotal = constrain(rtotal, 0, 255); + gtotal = constrain(gtotal, 0, 255); + btotal = constrain(btotal, 0, 255); + + // Return the resulting color + return color(rtotal, gtotal, btotal); +} \ No newline at end of file diff --git a/dist/assets/examples/es/05_Image/10_Copy_Method.js b/dist/assets/examples/es/05_Image/10_Copy_Method.js new file mode 100644 index 0000000000..8d7db11f81 --- /dev/null +++ b/dist/assets/examples/es/05_Image/10_Copy_Method.js @@ -0,0 +1,20 @@ +/* + * @name Método copy() + * @frame 600,400 + * @description Un ejemplo de cómo simular colorear una imagen con el método copy(). + */ +let draft, ready; +function preload() { + ready = loadImage("assets/parrot-color.png"); + draft = loadImage("assets/parrot-bw.png"); +} +function setup() { + createCanvas(600, 400); + noCursor(); + cursor("assets/brush.png", 20, -10); + image(ready, 0, 0); + image(draft, 0, 0); +} +function mouseDragged() { + copy(ready, mouseX, mouseY, 20, 20, mouseX, mouseY, 20, 20); +} diff --git a/dist/assets/examples/es/07_Color/00_Hue.js b/dist/assets/examples/es/07_Color/00_Hue.js new file mode 100644 index 0000000000..7f017b3733 --- /dev/null +++ b/dist/assets/examples/es/07_Color/00_Hue.js @@ -0,0 +1,26 @@ +/* + * @name Tinte + * @description El tinte es el color reflejado o transmitidio + * a través de un objecto y es típicamente nombrado como + * el nombre del color (rojo, azul, amarillo, etc). + * Mueve el cursor verticalmente sobre cada barra para alterar su tinte. + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, height, height, height); + noStroke(); + background(0); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(mouseY, height, height); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/es/07_Color/01_Saturation.js b/dist/assets/examples/es/07_Color/01_Saturation.js new file mode 100644 index 0000000000..c7728a7978 --- /dev/null +++ b/dist/assets/examples/es/07_Color/01_Saturation.js @@ -0,0 +1,25 @@ +/* + * @name Saturación + * @description La saturación es la fuerza o pureza del color y + * representa la cantidad de gris en proporción al tinte. + * Un color "saturado" es puro y uno "insaturado" tiene un gran porcentaje de gris. + * Mueve el cursor verticalmente sobre cada barra para alterar su saturación. + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, width, height, 100); + noStroke(); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(barX, mouseY, 66); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/es/07_Color/02_Brightness.js b/dist/assets/examples/es/07_Color/02_Brightness.js new file mode 100644 index 0000000000..475142942a --- /dev/null +++ b/dist/assets/examples/es/07_Color/02_Brightness.js @@ -0,0 +1,46 @@ +/* + * @name Brillo + * @description Por Dan Shiffman. Este programa ajusta el brillo de una parte de + * la imagen, calculando la distancia de cada pixel al ratón. + *

Para correr este ejemplo localmente, necesitarás al menos un archivo de imagen + * y un servidor local corriendo.

+ */ +let img; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 200); + pixelDensity(1); + img.loadPixels(); + loadPixels(); +} + +function draw() { + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + // Calcular la posición 1D de una matriz 2D + let loc = (x + y * img.width) * 4; + // Obtener los valores R,G,B de una imagen + let r, g, b; + r = img.pixels[loc]; + // Calcular una cantidad a cambiar de brillo basado en la proximidad al ratón + let maxdist = 50; + let d = dist(x, y, mouseX, mouseY); + let adjustbrightness = (255 * (maxdist - d)) / maxdist; + r += adjustbrightness; + // Limitar RGB para asegurarse de estar dentro del rango 0-255 de color + r = constrain(r, 0, 255); + // Hacer un nuevo color y definir el pixel en la ventana + //color c = color(r, g, b); + let pixloc = (y * width + x) * 4; + pixels[pixloc] = r; + pixels[pixloc + 1] = r; + pixels[pixloc + 2] = r; + pixels[pixloc + 3] = 255; + } + } + updatePixels(); +} diff --git a/dist/assets/examples/es/07_Color/03_Color_Variables.js b/dist/assets/examples/es/07_Color/03_Color_Variables.js new file mode 100644 index 0000000000..f13cd859aa --- /dev/null +++ b/dist/assets/examples/es/07_Color/03_Color_Variables.js @@ -0,0 +1,40 @@ +/* + * @name Variables de color + * @description (Homenajen a Albers.) Este ejemplo crea variables de colores + * que pueden ser referenciadas en el programa por un nombre, en vez de un número. + */ +function setup() { + createCanvas(710, 400); + noStroke(); + background(51, 0, 0); + + let inside = color(204, 102, 0); + let middle = color(204, 153, 0); + let outside = color(153, 51, 0); + + // Estas instrucciones son equivalentes a las de arriba. + // Los programadores pueden usar el formato que prefieran. + //color inside = #CC6600; + //color middle = #CC9900; + //color outside = #993300; + + push(); + translate(80, 80); + fill(outside); + rect(0, 0, 200, 200); + fill(middle); + rect(40, 60, 120, 120); + fill(inside); + rect(60, 90, 80, 80); + pop(); + + push(); + translate(360, 80); + fill(inside); + rect(0, 0, 200, 200); + fill(outside); + rect(40, 60, 120, 120); + fill(middle); + rect(60, 90, 80, 80); + pop(); +} diff --git a/dist/assets/examples/es/07_Color/04_Relativity.js b/dist/assets/examples/es/07_Color/04_Relativity.js new file mode 100644 index 0000000000..64b6555506 --- /dev/null +++ b/dist/assets/examples/es/07_Color/04_Relativity.js @@ -0,0 +1,34 @@ +/* + * @name Relatividad + * @description Cada colores es percibido en relación a los otros colores. Las barras superiores e inferiores + * contienen los mismos componentes de color, pero con un distinto orden causa que + * los colores individuales aparezcan como distintos. + */ +let a, b, c, d, e; + +function setup() { + createCanvas(710, 400); + noStroke(); + a = color(165, 167, 20); + b = color(77, 86, 59); + c = color(42, 106, 105); + d = color(165, 89, 20); + e = color(146, 150, 127); + noLoop(); // Ejecutar draw() solo una vez +} + +function draw() { + drawBand(a, b, c, d, e, 0, width / 128); + drawBand(c, a, d, b, e, height / 2, width / 128); +} + +function drawBand(v, w, x, y, z, ypos, barWidth) { + let num = 5; + let colorOrder = [v, w, x, y, z]; + for (let i = 0; i < width; i += barWidth * num) { + for (let j = 0; j < num; j++) { + fill(colorOrder[j]); + rect(i + j * barWidth, ypos, barWidth, height / 2); + } + } +} diff --git a/dist/assets/examples/es/07_Color/05_Linear_Gradient.js b/dist/assets/examples/es/07_Color/05_Linear_Gradient.js new file mode 100644 index 0000000000..29fbefabf9 --- /dev/null +++ b/dist/assets/examples/es/07_Color/05_Linear_Gradient.js @@ -0,0 +1,52 @@ +/* + * @name Gradiente linear + * @description La función lerpColor() es útil para interpolar entre + * dos colores. + */ +// Constantes +const Y_AXIS = 1; +const X_AXIS = 2; +let b1, b2, c1, c2; + +function setup() { + createCanvas(710, 400); + + // Definir colores + b1 = color(255); + b2 = color(0); + c1 = color(204, 102, 0); + c2 = color(0, 102, 153); + + noLoop(); +} + +function draw() { + // Fondo + setGradient(0, 0, width / 2, height, b1, b2, X_AXIS); + setGradient(width / 2, 0, width / 2, height, b2, b1, X_AXIS); + // Frente + setGradient(50, 90, 540, 80, c1, c2, Y_AXIS); + setGradient(50, 190, 540, 80, c2, c1, X_AXIS); +} + +function setGradient(x, y, w, h, c1, c2, axis) { + noFill(); + + if (axis === Y_AXIS) { + // Gradiente de arriba a abajo + for (let i = y; i <= y + h; i++) { + let inter = map(i, y, y + h, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(x, i, x + w, i); + } + } else if (axis === X_AXIS) { + // Gradiente de izquierda a derecha + for (let i = x; i <= x + w; i++) { + let inter = map(i, x, x + w, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(i, y, i, y + h); + } + } +} diff --git a/dist/assets/examples/es/07_Color/06_Radial_Gradient.js b/dist/assets/examples/es/07_Color/06_Radial_Gradient.js new file mode 100644 index 0000000000..e100618494 --- /dev/null +++ b/dist/assets/examples/es/07_Color/06_Radial_Gradient.js @@ -0,0 +1,33 @@ +/* + * @name Gradiente radial + * @description Dibuja una serie de círculos concéntros para crear un gradiente + * de un color a otro. + */ +let dim; + +function setup() { + createCanvas(710, 400); + dim = width / 2; + background(0); + colorMode(HSB, 360, 100, 100); + noStroke(); + ellipseMode(RADIUS); + frameRate(1); +} + +function draw() { + background(0); + for (let x = 0; x <= width; x += dim) { + drawGradient(x, height / 2); + } +} + +function drawGradient(x, y) { + let radius = dim / 2; + let h = random(0, 360); + for (let r = radius; r > 0; --r) { + fill(h, 90, 90); + ellipse(x, y, r, r); + h = (h + 1) % 360; + } +} diff --git a/dist/assets/examples/es/07_Color/07_Lerp_Color.js b/dist/assets/examples/es/07_Color/07_Lerp_Color.js new file mode 100644 index 0000000000..69bb8f24ce --- /dev/null +++ b/dist/assets/examples/es/07_Color/07_Lerp_Color.js @@ -0,0 +1,49 @@ +/* + * @name Interpolación de color + * @description Crea figuras aleatorias, + * interpola su color de rojo a azul. + */ +function setup() { + createCanvas(720, 400); + background(255); + noStroke(); +} + +function draw() { + background(255); + from = color(255, 0, 0, 0.2 * 255); + to = color(0, 0, 255, 0.2 * 255); + c1 = lerpColor(from, to, 0.33); + c2 = lerpColor(from, to, 0.66); + for (let i = 0; i < 15; i++) { + fill(from); + quad( + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height) + ); + fill(c1); + quad( + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height) + ); + fill(c2); + quad( + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height) + ); + fill(to); + quad( + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height) + ); + } + frameRate(5); +} diff --git a/dist/assets/examples/es/08_Math/00_incrementdecrement.js b/dist/assets/examples/es/08_Math/00_incrementdecrement.js new file mode 100644 index 0000000000..8456e6486b --- /dev/null +++ b/dist/assets/examples/es/08_Math/00_incrementdecrement.js @@ -0,0 +1,42 @@ +/* + * @name Incremento y decremento + * @description Escribir "a++" es equivalente a"a = a + 1". + * Escribir "a--" es equivalente a "a = a - 1". + */ +let a; +let b; +let direction; + +function setup() { + createCanvas(710, 400); + colorMode(RGB, width); + a = 0; + b = width; + direction = true; + frameRate(30); +} + +function draw() { + a++; + if (a > width) { + a = 0; + direction = !direction; + } + if (direction === true) { + stroke(a); + } else { + stroke(width - a); + } + line(a, 0, a, height / 2); + + b--; + if (b < 0) { + b = width; + } + if (direction === true) { + stroke(width - b); + } else { + stroke(b); + } + line(b, height / 2 + 1, b, height); +} diff --git a/dist/assets/examples/es/08_Math/01_operatorprecedence.js b/dist/assets/examples/es/08_Math/01_operatorprecedence.js new file mode 100644 index 0000000000..c2d92dac05 --- /dev/null +++ b/dist/assets/examples/es/08_Math/01_operatorprecedence.js @@ -0,0 +1,54 @@ +/* + * @name Precedencia de operadores + * @description Si no defines explicitamente el orden en que una + * expresión es evaluada, son evaluadas basándose en la precedencia de operador. + * Por ejemplo, en la instrucción "4+2*8", el 2 será + * primero multiplicado por 8 y luego el resultado será sumado a 4. + * Esto ocurre porque el "*" tiene una precedencia más alta que el "+". Para evitar + * ambigüedad al leer el programa, se recomienda escribir esta instrucción + * como "4+(2*8)". El orden de evaluación puede ser controlado por + * la ubicación de paréntesis en el código. Una tabla de precedencia + * de operadores sigue a continuación. + */ +// La precedencia más alta está al principio de esta lista y +// la más baja al final. +// Multiplicativo: * / % +// Aditivo: + - +// Relacional: < > <= >= +// Igualdad: == != +// AND lógico: && +// OR lógico: || +// Asignación: = += -= *= /= %= +function setup() { + createCanvas(710, 400); + background(51); + noFill(); + stroke(51); + + stroke(204); + for (let i = 0; i < width - 20; i += 4) { + // El 30 es sumado a 70 y luego se evalúa + // si esto es mayor al valor actual de "i" + // Por claridad, escribe "if (i > (30 + 70)) {" + if (i > 30 + 70) { + line(i, 0, i, 50); + } + } + + stroke(255); + // El 2 es multiplicado por 8 y el resultado es sumado a el 4 + // Por claridad, escribe "rect(5 + (2 * 8), 0, 90, 20);" + rect(4 + 2 * 8, 52, 290, 48); + rect((4 + 2) * 8, 100, 290, 49); + + stroke(153); + for (let i = 0; i < width; i += 2) { + // Las instrucciones relacionales son evaluadas + // primero, y luego las declaraciones lógicas AND y + // finalmente el OR lógico. Por claridad, escribe: + // "if(((i > 20) && (i < 50)) || ((i > 100) && (i < width-20))) {" + if ((i > 20 && i < 50) || (i > 100 && i < width - 20)) { + line(i, 151, i, height - 1); + } + } +} diff --git a/dist/assets/examples/es/08_Math/02_distance1d.js b/dist/assets/examples/es/08_Math/02_distance1d.js new file mode 100644 index 0000000000..70e494b6c1 --- /dev/null +++ b/dist/assets/examples/es/08_Math/02_distance1d.js @@ -0,0 +1,65 @@ +/* + * @name Distancia 1D + * @description Mueve el ratón hacia la izquierda y derecha para controlar + * la velocidad y la dirección de las figuras moviéndose. + */ +let xpos1; +let xpos2; +let xpos3; +let xpos4; +let thin = 8; +let thick = 36; + +function setup() { + createCanvas(710, 400); + noStroke(); + xpos1 = width / 2; + xpos2 = width / 2; + xpos3 = width / 2; + xpos4 = width / 2; +} + +function draw() { + background(0); + + let mx = mouseX * 0.4 - width / 5.0; + + fill(102); + rect(xpos2, 0, thick, height / 2); + fill(204); + rect(xpos1, 0, thin, height / 2); + fill(102); + rect(xpos4, height / 2, thick, height / 2); + fill(204); + rect(xpos3, height / 2, thin, height / 2); + + xpos1 += mx / 16; + xpos2 += mx / 64; + xpos3 -= mx / 16; + xpos4 -= mx / 64; + + if (xpos1 < -thin) { + xpos1 = width; + } + if (xpos1 > width) { + xpos1 = -thin; + } + if (xpos2 < -thick) { + xpos2 = width; + } + if (xpos2 > width) { + xpos2 = -thick; + } + if (xpos3 < -thin) { + xpos3 = width; + } + if (xpos3 > width) { + xpos3 = -thin; + } + if (xpos4 < -thick) { + xpos4 = width; + } + if (xpos4 > width) { + xpos4 = -thick; + } +} diff --git a/dist/assets/examples/es/08_Math/03_distance2d.js b/dist/assets/examples/es/08_Math/03_distance2d.js new file mode 100644 index 0000000000..90268132a4 --- /dev/null +++ b/dist/assets/examples/es/08_Math/03_distance2d.js @@ -0,0 +1,24 @@ +/* + * @name Distancia 2D + * @description Mueve el ratón a lo largo de la imagen para oscurecer + * y revelar la matriz. Mide la distancia desde el ratón hasta cada cuadrado y define su tamaño proporcionalmente. + */ +let max_distance; + +function setup() { + createCanvas(710, 400); + noStroke(); + max_distance = dist(0, 0, width, height); +} + +function draw() { + background(0); + + for (let i = 0; i <= width; i += 20) { + for (let j = 0; j <= height; j += 20) { + let size = dist(mouseX, mouseY, i, j); + size = (size / max_distance) * 66; + ellipse(i, j, size, size); + } + } +} diff --git a/dist/assets/examples/es/08_Math/04_sine.js b/dist/assets/examples/es/08_Math/04_sine.js new file mode 100644 index 0000000000..4749a1be59 --- /dev/null +++ b/dist/assets/examples/es/08_Math/04_sine.js @@ -0,0 +1,27 @@ +/* + * @name Seno + * @description Escala suavemente el tamaño con la función seno sin(). + */ +let diameter; +let angle = 0; + +function setup() { + createCanvas(710, 400); + diameter = height - 10; + noStroke(); + fill(255, 204, 0); +} + +function draw() { + background(0); + + let d1 = 10 + sin(angle) * (diameter / 2) + diameter / 2; + let d2 = 10 + sin(angle + PI / 2) * (diameter / 2) + diameter / 2; + let d3 = 10 + sin(angle + PI) * (diameter / 2) + diameter / 2; + + ellipse(0, height / 2, d1, d1); + ellipse(width / 2, height / 2, d2, d2); + ellipse(width, height / 2, d3, d3); + + angle += 0.02; +} diff --git a/dist/assets/examples/es/08_Math/05_sincosine.js b/dist/assets/examples/es/08_Math/05_sincosine.js new file mode 100644 index 0000000000..c903521c5d --- /dev/null +++ b/dist/assets/examples/es/08_Math/05_sincosine.js @@ -0,0 +1,43 @@ +/* + * @name Seno y coseno + * @description Movimiento lineal con las funciones sin() y cos(). + * Números entre 0 y PI*2 + * son usados como argumento para estas funciones, que retornan números -1 y 1. + * Estos valores son luego escalados para producir movimientos de mayor magnitud. + */ +let angle1 = 0; +let angle2 = 0; +let scalar = 70; + +function setup() { + createCanvas(710, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(0); + + let ang1 = radians(angle1); + let ang2 = radians(angle2); + + let x1 = width / 2 + scalar * cos(ang1); + let x2 = width / 2 + scalar * cos(ang2); + + let y1 = height / 2 + scalar * sin(ang1); + let y2 = height / 2 + scalar * sin(ang2); + + fill(255); + rect(width * 0.5, height * 0.5, 140, 140); + + fill(0, 102, 153); + ellipse(x1, height * 0.5 - 120, scalar, scalar); + ellipse(x2, height * 0.5 + 120, scalar, scalar); + + fill(255, 204, 0); + ellipse(width * 0.5 - 120, y1, scalar, scalar); + ellipse(width * 0.5 + 120, y2, scalar, scalar); + + angle1 += 2; + angle2 += 3; +} diff --git a/dist/assets/examples/es/08_Math/06_sinewave.js b/dist/assets/examples/es/08_Math/06_sinewave.js new file mode 100644 index 0000000000..072e2b5c70 --- /dev/null +++ b/dist/assets/examples/es/08_Math/06_sinewave.js @@ -0,0 +1,48 @@ +/* + * @name Onda sinusoidal + * @description Dibuja una onda sinusoidal simple. + * Original por Daniel Shiffman. + */ + +let xspacing = 16; // Distancia entre posiciones horizontales +let w; // Ancho de la onda entera +let theta = 0.0; // Ángulo inicial en 0 +let amplitude = 75.0; // Altura de la onda +let period = 500.0; // Cantidad de pixeles antes de que la onda se repita +let dx; // Valor de incremento en eje x +let yvalues; // Uso de un arreglo para guardar los valores de altura de la onda + +function setup() { + createCanvas(710, 400); + w = width + 16; + dx = (TWO_PI / period) * xspacing; + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // Incrementar theta (prueba valores distintos de + // 'velocidad angular' aquí + theta += 0.02; + + // Por cada valor de x, calcula un valor de y con la función sin() + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = sin(x) * amplitude; + x += dx; + } +} + +function renderWave() { + noStroke(); + fill(255); + // Una manera simple de dibujar la onda con una elipse en cada punto + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, height / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/es/08_Math/07_additivewave.js b/dist/assets/examples/es/08_Math/07_additivewave.js new file mode 100644 index 0000000000..884ba5eec6 --- /dev/null +++ b/dist/assets/examples/es/08_Math/07_additivewave.js @@ -0,0 +1,70 @@ +/* + * @name Onda aditiva + * @description Crea una onda más compleja sumando otras dos ondas. + * Original por Daniel Shiffman + */ +let xspacing = 8; // Distancia entre cada posición en eje x +let w; // Ancho de la onda +let maxwaves = 4; // número total de ondas a sumarse + +let theta = 0.0; +let amplitude = new Array(maxwaves); // Altura de la onda +// Valor para incrementar x, a ser calculado como +// una función de periodo y espaciado en x +let dx = new Array(maxwaves); +// Uso de un arreglo para almacenar los valores de altura +// de la onda (no es del todo necesario) +let yvalues; + +function setup() { + createCanvas(710, 400); + frameRate(30); + colorMode(RGB, 255, 255, 255, 100); + w = width + 16; + + for (let i = 0; i < maxwaves; i++) { + amplitude[i] = random(10, 30); + let period = random(100, 300); // Número de pixeles antes que la onda se repita + dx[i] = (TWO_PI / period) * xspacing; + } + + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // Incrementar theta (pruebas otros valores + // de 'velocidad angular' aquí + theta += 0.02; + + // Hacer cero todos los valores de altura + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = 0; + } + + // Valores acumulados de altura de onda + for (let j = 0; j < maxwaves; j++) { + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + // Cada otra onda es coseno en vez de seno + if (j % 2 == 0) yvalues[i] += sin(x) * amplitude[j]; + else yvalues[i] += cos(x) * amplitude[j]; + x += dx[j]; + } + } +} + +function renderWave() { + // Una manera simple de dibujar la onda, con una elipse en cada punto + noStroke(); + fill(255, 50); + ellipseMode(CENTER); + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, width / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/es/08_Math/08_polartocartesian.js b/dist/assets/examples/es/08_Math/08_polartocartesian.js new file mode 100644 index 0000000000..f9c7bd8d1d --- /dev/null +++ b/dist/assets/examples/es/08_Math/08_polartocartesian.js @@ -0,0 +1,44 @@ +/* + * @name Polar a cartesiano + * @description Convierte una coordenada polar (r,theta) + * a cartesiana (x,y): x = r*cos(theta), y = r*sin(theta) + * Original por Daniel Shiffman. + */ +let r; + +// Ángulo, velocidad angular, aceleración angular +let theta; +let theta_vel; +let theta_acc; + +function setup() { + createCanvas(710, 400); + + // Inicializar todos los valores + r = height * 0.45; + theta = 0; + theta_vel = 0; + theta_acc = 0.0001; +} + +function draw() { + background(0); + + // Traslada el punto de origen al centro del lienzo + translate(width / 2, height / 2); + + // Convierte de polar a cartesiano + let x = r * cos(theta); + let y = r * sin(theta); + + // Dibuja la elipse en la coordenada cartesiana + ellipseMode(CENTER); + noStroke(); + fill(200); + ellipse(x, y, 32, 32); + + // Applica aceleración y velocidad al ángulo + // (r permance estático en este ejemplo) + theta_vel += theta_acc; + theta += theta_vel; +} diff --git a/dist/assets/examples/es/08_Math/09_arctangent.js b/dist/assets/examples/es/08_Math/09_arctangent.js new file mode 100644 index 0000000000..7c695d57c7 --- /dev/null +++ b/dist/assets/examples/es/08_Math/09_arctangent.js @@ -0,0 +1,45 @@ +/* + * @name Arcotangente + * @description Mueve el ratón para cambiar la dirección de los ojos.
La función atan2() calcula el ángulo entre cada ojo y el cursor. + */ +let e1, e2, e3; + +function setup() { + createCanvas(720, 400); + noStroke(); + e1 = new Eye(250, 16, 120); + e2 = new Eye(164, 185, 80); + e3 = new Eye(420, 230, 220); +} + +function draw() { + background(102); + e1.update(mouseX, mouseY); + e2.update(mouseX, mouseY); + e3.update(mouseX, mouseY); + e1.display(); + e2.display(); + e3.display(); +} + +function Eye(tx, ty, ts) { + this.x = tx; + this.y = ty; + this.size = ts; + this.angle = 0; + + this.update = function(mx, my) { + this.angle = atan2(my - this.y, mx - this.x); + }; + + this.display = function() { + push(); + translate(this.x, this.y); + fill(255); + ellipse(0, 0, this.size, this.size); + rotate(this.angle); + fill(153, 204, 0); + ellipse(this.size / 4, 0, this.size / 2, this.size / 2); + pop(); + }; +} diff --git a/dist/assets/examples/es/08_Math/10_Interpolate.js b/dist/assets/examples/es/08_Math/10_Interpolate.js new file mode 100644 index 0000000000..58505b4a24 --- /dev/null +++ b/dist/assets/examples/es/08_Math/10_Interpolate.js @@ -0,0 +1,34 @@ +/* + * @name Interpolación Lineal + * @frame 720, 400 + * @description Mueve el ratón a través de la pantalla y el símbolo le seguirá. + * Entre cada fotograma de la animación, la elipse se mueve parte + * de la distancia (0,05) desde su posición actual hacia el cursor + * usando la función lerp(). + * Esto es equivalente al uso de Easing en la sección Input, sólo que con lerp() en su lugar... + */ + +let x = 0; +let y = 0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(51); + + // lerp() calcula un número entre dos números en un incremento específico. + // El parámetro amt (amount) es la cantidad a interpolar entre los dos valores + // donde 0,0 es igual al primer punto, 0,1 está muy cerca del primer punto, 0,5 + // está a mitad de camino, etc. + + // Aquí estamos moviendo el 5% del camino hacia la ubicación del ratón en cada fotograma + x = lerp(x, mouseX, 0.05); + y = lerp(y, mouseY, 0.05); + + fill(255); + stroke(255); + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/es/08_Math/11_doubleRandom.js b/dist/assets/examples/es/08_Math/11_doubleRandom.js new file mode 100644 index 0000000000..323b84fc1e --- /dev/null +++ b/dist/assets/examples/es/08_Math/11_doubleRandom.js @@ -0,0 +1,24 @@ +/* + * @name Doble aleatorio + * @frame 720,400 (optional) + * @description Usando dos llamadas a la función random() y a la función point() + * crea una línea diente de sierra irregular. + * Original por Ira Greenberg. + */ +let totalPts = 300; +let steps = totalPts + 1; + +function setup() { + createCanvas(710, 400); + stroke(255); + frameRate(1); +} + +function draw() { + background(0); + let rand = 0; + for (let i = 1; i < steps; i++) { + point((width / steps) * i, height / 2 + random(-rand, rand)); + rand += random(-5, 5); + } +} diff --git a/dist/assets/examples/es/08_Math/12_random.js b/dist/assets/examples/es/08_Math/12_random.js new file mode 100644 index 0000000000..cf79183556 --- /dev/null +++ b/dist/assets/examples/es/08_Math/12_random.js @@ -0,0 +1,19 @@ +/* + * @name Aleatorio + * @description Los números aleatorios son la base de esta imagen. + * Cada vez que el programa es ejecutado, el resultado es distinto. + */ +function setup() { + createCanvas(710, 400); + background(0); + strokeWeight(20); + frameRate(2); +} + +function draw() { + for (let i = 0; i < width; i++) { + let r = random(255); + stroke(r); + line(i, 0, i, height); + } +} diff --git a/dist/assets/examples/es/08_Math/13_noise1D.js b/dist/assets/examples/es/08_Math/13_noise1D.js new file mode 100644 index 0000000000..ad16c996f5 --- /dev/null +++ b/dist/assets/examples/es/08_Math/13_noise1D.js @@ -0,0 +1,31 @@ +/* + * @name Ruido 1D + * @description Uso de ruido Perlin 1D para asignar ubicación. + */ +let xoff = 0.0; +let xincrement = 0.01; + +function setup() { + createCanvas(710, 400); + background(0); + noStroke(); +} + +function draw() { + // Crear un fondo traslúcido + fill(0, 10); + rect(0, 0, width, height); + + //let n = random(0,width); // Prueba esta línea en vez del ruido (noise) + + // Obtener un valor de ruido basado en xoff y escalarlo + // según el ancho de la ventana + let n = noise(xoff) * width; + + // Incrementar xoff en cada ciclo + xoff += xincrement; + + // Dibujar la elipse en la coordenada producida por el ruido Perlin + fill(200); + ellipse(n, height / 2, 64, 64); +} diff --git a/dist/assets/examples/es/08_Math/14_noisewave.js b/dist/assets/examples/es/08_Math/14_noisewave.js new file mode 100644 index 0000000000..ac8cfeed84 --- /dev/null +++ b/dist/assets/examples/es/08_Math/14_noisewave.js @@ -0,0 +1,42 @@ +/* + * @name Onda de ruido + * @description Uso de ruido Perlin para generar un patrón tipo onda. + * Original por Daniel Shiffman. + */ +let yoff = 0.0; // Segunda dimensión del ruido Perlin + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(51); + + fill(255); + // Dibujaremos un polígono a partir de los puntos de la onda + beginShape(); + + let xoff = 0; // Opción #1: ruido 2D + // let xoff = yoff; // Opción #2: ruido 1D + + // Iterar sobre los pixeles horizontales + for (let x = 0; x <= width; x += 10) { + // Calcular un valor de y según el ruido, escalar según + + // Opción #1: ruido 2D + let y = map(noise(xoff, yoff), 0, 1, 200, 300); + + // Opción #2: ruido 1D + // let y = map(noise(xoff), 0, 1, 200,300); + + // Definir el vértice + vertex(x, y); + // Incrementar la dimensión x para el ruido + xoff += 0.05; + } + // Incrementar la dimensión y para el ruido + yoff += 0.01; + vertex(width, height); + vertex(0, height); + endShape(CLOSE); +} diff --git a/dist/assets/examples/es/08_Math/15_Noise2D.js b/dist/assets/examples/es/08_Math/15_Noise2D.js new file mode 100644 index 0000000000..9640287af8 --- /dev/null +++ b/dist/assets/examples/es/08_Math/15_Noise2D.js @@ -0,0 +1,42 @@ +/* + * @name Ruido 2D + * @frame 710,400 (optional) + * @description Crear un ruido 2D con parámetros diferentes. + * + */ + +let noiseVal; +let noiseScale = 0.02; + +function setup() { + createCanvas(640, 360); +} + +function draw() { + background(0); + // Dibujar la mitad izquierda de la imagen + for (let y = 0; y < height - 30; y++) { + for (let x = 0; x < width / 2; x++) { + // noiceDetail (detalle del ruido) del número de octavas y valor de caída de los píxeles + noiseDetail(2, 0.2); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + // Dibujar la mitad derecha de la imagen + for (let y = 0; y < height - 30; y++) { + for (let x = width / 2; x < width; x++) { + // noiceDetail (detalle del ruido) del número de octavas y valor de caída de los píxeles + noiseDetail(5, 0.5); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + //Mostrar los detalles de las dos particiones + textSize(18); + fill(255, 255, 255); + text('Noice2D with 2 octaves and 0.2 falloff', 10, 350); + text('Noice2D with 1 octaves and 0.7 falloff', 330, 350); +} diff --git a/dist/assets/examples/es/08_Math/16_Noise3D.js b/dist/assets/examples/es/08_Math/16_Noise3D.js new file mode 100644 index 0000000000..9153f0b794 --- /dev/null +++ b/dist/assets/examples/es/08_Math/16_Noise3D.js @@ -0,0 +1,47 @@ +/* + * @name Ruido 3D + * @frame 710,400 (optional) + * @description Uso de ruido 3D para crear una simple textura animada. + */ +let noiseVal; +//Incrementar x en 0,01 +let x_increment = 0.01; +//Incrementar z en 0.02 cada ciclo de draw() +let z_increment = 0.02; + +//Valores de desviación +let z_off, y_off, x_off; + +function setup() { + //Crear el Lienzo + createCanvas(640, 360); + //Definir la velocidad de cuadro + frameRate(20); + //Valor inicial de z_off + z_off = 0; +} + +function draw() { + x_off = 0; + y_off = 0; + //Hacer que el fondo sea negro + background(0); + //Ajustar el detalle del ruido + noiseDetail(8, 0.65); + + //Para cada x,y calcular el valor del ruido + for (let y = 0; y < height; y++) { + x_off += x_increment; + y_off = 0; + + for (let x = 0; x < width; x++) { + //Calcular y dibujar cada píxel + noiseVal = noise(x_off, y_off, z_off); + stroke(noiseVal * 255); + y_off += x_increment; + point(x, y); + } + } + + z_off += z_increment; +} diff --git a/dist/assets/examples/es/08_Math/17_Randomchords.js b/dist/assets/examples/es/08_Math/17_Randomchords.js new file mode 100644 index 0000000000..600d27afb5 --- /dev/null +++ b/dist/assets/examples/es/08_Math/17_Randomchords.js @@ -0,0 +1,34 @@ +/* + * @name Cuerdas Aleatorias + * @description Acumula cuerdas al azar de un círculo. Cada cuerda es translúcida, + * de modo que se acumulan para dar la ilusión de una esfera sombreada. + * Contribución de Aatish Bhatia, inspirado en Anders Hoff + */ +function setup() { + createCanvas(400, 400); + background(255, 255, 255); + + // trazo translúcido usando el valor alfa + stroke(0, 0, 0, 15); +} + +function draw() { + // trazar dos cuerdas al azar en cada cuadro + randomChord(); + randomChord(); +} + +function randomChord() { + // encontrar un punto aleatorio en un círculo + let angle1 = random(0, 2 * PI); + let xpos1 = 200 + 200 * cos(angle1); + let ypos1 = 200 + 200 * sin(angle1); + + // encontrar otro punto aleatorio en el círculo + let angle2 = random(0, 2 * PI); + let xpos2 = 200 + 200 * cos(angle2); + let ypos2 = 200 + 200 * sin(angle2); + + // trazar una línea entre ellos + line(xpos1, ypos1, xpos2, ypos2); +} diff --git a/dist/assets/examples/es/08_Math/18_Map.js b/dist/assets/examples/es/08_Math/18_Map.js new file mode 100644 index 0000000000..1d293e8a20 --- /dev/null +++ b/dist/assets/examples/es/08_Math/18_Map.js @@ -0,0 +1,22 @@ +/* + * @name Mapear + * @description Utiliza la función map() para tomar cualquier número y escalarlo a un + * nuevo número que sea más útil para el proyecto en el que estés trabajando. + * Por ejemplo, usa los números de la posición del ratón para controlar el tamaño o el color de una figura. + * En este ejemplo, la coordenada x del ratón (números entre 0 y 360) se escalan a nuevos números + * para definir el color y el tamaño de un círculo. + */ +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(0); + // Escala el valor de mouseX de 0 a 720 a un rango entre 0 y 175 + let c = map(mouseX, 0, width, 0, 175); + // Escala el valor de mouseX de 0 a 720 a un rango entre 40 y 300 + let d = map(mouseX, 0, width, 40, 300); + fill(255, c, 0); + ellipse(width/2, height/2, d, d); +} diff --git a/dist/assets/examples/es/08_Math/19_parametricEquation.js b/dist/assets/examples/es/08_Math/19_parametricEquation.js new file mode 100644 index 0000000000..6470ef5ed1 --- /dev/null +++ b/dist/assets/examples/es/08_Math/19_parametricEquation.js @@ -0,0 +1,45 @@ +/* + * @name Ecuaciones Paramétricas + * @description Una ecuación paramétrica es una en la cual las coordenadas x e y + * están escritas en términos de otra variable. + * Esto se llama un parámetro y se suele dar en la letra t o θ. + * La inspiración se tomó del canal de YouTube de Alexander Miller. + */ + +function setup(){ + createCanvas(720,400); +} + +// el parámetro del que dependen x e y +// se suele designar con la letra t o el símbolo de theta +let t = 0; +function draw(){ + background('#fff'); + translate(width/2,height/2); + stroke('#0f0f0f'); + strokeWeight(1.5); + //bucle para añadir 100 líneas + for(let i = 0;i<100;i++){ + line(x1(t+i),y1(t+i),x2(t+i)+20,y2(t+i)+20); + } + t+=0.15; +} +// función para cambiar la coordenada inicial x de la línea +function x1(t){ + return sin(t/10)*125+sin(t/20)*125+sin(t/30)*125; +} + +// función para cambiar la coordenada y inicial de la línea +function y1(t){ + return cos(t/10)*125+cos(t/20)*125+cos(t/30)*125; +} + +// función para cambiar la coordenada x final de la línea +function x2(t){ + return sin(t/15)*125+sin(t/25)*125+sin(t/35)*125; +} + +// función para cambiar la coordenada final de la línea +function y2(t){ + return cos(t/15)*125+cos(t/25)*125+cos(t/35)*125; +} diff --git a/dist/assets/examples/es/08_Math/20_Graphing2DEquations.js b/dist/assets/examples/es/08_Math/20_Graphing2DEquations.js new file mode 100644 index 0000000000..450f33c8ce --- /dev/null +++ b/dist/assets/examples/es/08_Math/20_Graphing2DEquations.js @@ -0,0 +1,52 @@ +/** + * @name Graphing 2D Equations + * @frame 710, 400 + * @description Graphics the following equation: sin(n*cos(r) + 5*theta) where n is a function of horizontal mouse location. Original by Daniel Shiffman + */ +function setup() { + createCanvas(710, 400); + pixelDensity(1); +} + +function draw() { + loadPixels(); + let n = (mouseX * 10.0) / width; + const w = 16.0; // 2D space width + const h = 16.0; // 2D space height + const dx = w / width; // Increment x this amount per pixel + const dy = h / height; // Increment y this amount per pixel + let x = -w / 2; // Start x at -1 * width / 2 + let y; + + let r; + let theta; + let val; + + let bw; //variable to store grayscale + let i; + let j; + let cols = width; + let rows = height; + + for (i = 0; i < cols; i += 1) { + y = -h / 2; + for (j = 0; j < rows; j += 1) { + r = sqrt(x * x + y * y); // Convert cartesian to polar + theta = atan2(y, x); // Convert cartesian to polar + // Compute 2D polar coordinate function + val = sin(n * cos(r) + 5 * theta); // Results in a value between -1 and 1 + //var val = cos(r); // Another simple function + //var val = sin(theta); // Another simple function + bw = color(((val + 1) * 255) / 2); + index = 4 * (i + j * width); + pixels[index] = red(bw); + pixels[index + 1] = green(bw); + pixels[index + 2] = blue(bw); + pixels[index + 3] = alpha(bw); + + y += dy; + } + x += dx; + } + updatePixels(); +} diff --git a/dist/assets/examples/es/08_Math/21_parametricEquation.js b/dist/assets/examples/es/08_Math/21_parametricEquation.js new file mode 100644 index 0000000000..83c1a3c336 --- /dev/null +++ b/dist/assets/examples/es/08_Math/21_parametricEquation.js @@ -0,0 +1,44 @@ +/* + * @name Parametric Equations + * @description A parametric equation is where x and y + * coordinates are both written in terms of another letter. This is + * called a parameter and is usually given in the letter t or θ. + * The inspiration was taken from the YouTube channel of Alexander Miller. + */ + +function setup(){ + createCanvas(720,400); +} + +// the parameter at which x and y depends is usually taken as either t or symbol of theta +let t = 0; +function draw(){ + background('#fff'); + translate(width/2,height/2); + stroke('#0f0f0f'); + strokeWeight(1.5); + //loop for adding 100 lines + for(let i = 0;i<100;i++){ + line(x1(t+i),y1(t+i),x2(t+i)+20,y2(t+i)+20); + } + t+=0.15; +} +// function to change initial x co-ordinate of the line +function x1(t){ + return sin(t/10)*125+sin(t/20)*125+sin(t/30)*125; +} + +// function to change initial y co-ordinate of the line +function y1(t){ + return cos(t/10)*125+cos(t/20)*125+cos(t/30)*125; +} + +// function to change final x co-ordinate of the line +function x2(t){ + return sin(t/15)*125+sin(t/25)*125+sin(t/35)*125; +} + +// function to change final y co-ordinate of the line +function y2(t){ + return cos(t/15)*125+cos(t/25)*125+cos(t/35)*125; +} \ No newline at end of file diff --git a/dist/assets/examples/es/09_Simulate/00_Forces.js b/dist/assets/examples/es/09_Simulate/00_Forces.js new file mode 100644 index 0000000000..480688a7af --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/00_Forces.js @@ -0,0 +1,140 @@ +/* + * @name Fuerzas + * @description Demostración de múltiples fuerzas actuando en cuerpos + * (natureofcode.com) + */ +// Demonstración de múltiples fuerzas acutando en +// cuerpos (con clase Mover) +// cuerpos sujetos continuamente a gravedad +// cuerpos sujetos a resistencia de fluidos cuando están en el "agua" + +// Cinco cuerpos en movimiento +let movers = []; + +// Líquido +let liquid; + +function setup() { + createCanvas(640, 360); + reset(); + // Crear objeto líquido + liquid = new Liquid(0, height / 2, width, height / 2, 0.1); +} + +function draw() { + background(127); + + // Dibujar el agua + liquid.display(); + + for (let i = 0; i < movers.length; i++) { + + // ¿Está el objeto Mover dentro del objeto líquido? + if (liquid.contains(movers[i])) { + // Calcular fuerza de arrastre + let dragForce = liquid.calculateDrag(movers[i]); + // Aplicar fuerza de arrastre a Mover + movers[i].applyForce(dragForce); + } + + // Aquí se escala la gravedad según la masa + let gravity = createVector(0, 0.1*movers[i].mass); + // Aplicar gravedad + movers[i].applyForce(gravity); + + // Refrescar y mostrar + movers[i].update(); + movers[i].display(); + movers[i].checkEdges(); + } + +} + + +function mousePressed() { + reset(); +} + +// Reiniciar todos los objetos Mover aleatoriamente +function reset() { + for (let i = 0; i < 9; i++) { + movers[i] = new Mover(random(0.5, 3), 40 + i * 70, 0); + } +} + +let Liquid = function(x, y, w, h, c) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + this.c = c; +}; + +// ¿Está el objeto Mover dentro del objeto líquido? +Liquid.prototype.contains = function(m) { + let l = m.position; + return l.x > this.x && l.x < this.x + this.w && + l.y > this.y && l.y < this.y + this.h; +}; + +// Calcular fuerza de arrastre +Liquid.prototype.calculateDrag = function(m) { + // Magnitud es coeficiente * velocidad al cuadrado + let speed = m.velocity.mag(); + let dragMagnitude = this.c * speed * speed; + + // Dirección es el inverso de la velocidad + let dragForce = m.velocity.copy(); + dragForce.mult(-1); + + // Escalar según magnitud + // dragForce.setMag(dragMagnitude); + dragForce.normalize(); + dragForce.mult(dragMagnitude); + return dragForce; +}; + +Liquid.prototype.display = function() { + noStroke(); + fill(50); + rect(this.x, this.y, this.w, this.h); +}; + +function Mover(m, x, y) { + this.mass = m; + this.position = createVector(x, y); + this.velocity = createVector(0, 0); + this.acceleration = createVector(0, 0); +} + +// Segunda ley de Newton: F = M * A +// ó A = F / M +Mover.prototype.applyForce = function(force) { + let f = p5.Vector.div(force,this.mass); + this.acceleration.add(f); +}; + +Mover.prototype.update = function() { + // La velocidad es cambiada según la aceleración + this.velocity.add(this.acceleration); + // La posición es cambiada según la velocidad + this.position.add(this.velocity); + // Borrar aceleración en cada cuadro + this.acceleration.mult(0); +}; + +Mover.prototype.display = function() { + stroke(0); + strokeWeight(2); + fill(255, 127); + ellipse(this.position.x, this.position.y, this.mass * 16, this.mass * 16); +}; + +// Rebotar contra la parte inferior de la ventana +Mover.prototype.checkEdges = function() { + if (this.position.y > (height - this.mass * 8)) { + // Un poco de amortiguamiento al rebotar contra el fondo + this.velocity.y *= -0.9; + this.position.y = (height - this.mass * 8); + } +}; diff --git a/dist/assets/examples/es/09_Simulate/01_ParticleSystem.js b/dist/assets/examples/es/09_Simulate/01_ParticleSystem.js new file mode 100644 index 0000000000..dc994bf66f --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/01_ParticleSystem.js @@ -0,0 +1,73 @@ +/* + * @name Sistema de partículas + * @description Este es un sistema básico de partículas + * (natureofcode.com) + */ +let system; + +function setup() { + createCanvas(720, 400); + system = new ParticleSystem(createVector(width / 2, 50)); +} + +function draw() { + background(51); + system.addParticle(); + system.run(); +} + +// Una clase simple de partícula (Particle) +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255.0; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// Método para refrescar posición +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// Método para mostrar en lienzo +Particle.prototype.display = function() { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// ¿La partícula todavía es útil? +Particle.prototype.isDead = function(){ + if (this.lifespan < 0) { + return true; + } else { + return false; + } +}; + +let ParticleSystem = function(position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin)); +}; + +ParticleSystem.prototype.run = function() { + for (let i = this.particles.length-1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; diff --git a/dist/assets/examples/es/09_Simulate/02_Flocking.js b/dist/assets/examples/es/09_Simulate/02_Flocking.js new file mode 100644 index 0000000000..0c2e5a4518 --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/02_Flocking.js @@ -0,0 +1,229 @@ +/* + * @name Flocking + * @description Demostración del comportamiento "Flocking" de Craig Reynolds. + *Ver: http://www.red3d.com/cwr/ + * Reglas: cohesión, separación, alineamiento + * (de natureofcode.com). + * Arrastra el mouse para añadir boids al sistema. + */ + + +let flock; + +let text; + +function setup() { + createCanvas(640, 360); + createP("Drag the mouse to generate new boids."); + + flock = new Flock(); + // Añade un conjunto inicial de boids al sistema + for (let i = 0; i < 100; i++) { + let b = new Boid(width / 2,height / 2); + flock.addBoid(b); + } +} + +function draw() { + background(51); + flock.run(); +} + +// Añade un nuevo boid al sistema +function mouseDragged() { + flock.addBoid(new Boid(mouseX, mouseY)); +} + +// The Nature of Code +// Daniel Shiffman +// http://natureofcode.com + +// Objeto Flock +// Hace pocas cosas, simplemente administra el arreglo de todos los boids + +function Flock() { + // Un arreglo para todos los boids + this.boids = []; // Inicializar el arreglo +} + +Flock.prototype.run = function() { + for (let i = 0; i < this.boids.length; i++) { + this.boids[i].run(this.boids); // Pasar la lista entera de boids a cada boid de forma individual + } +} + +Flock.prototype.addBoid = function(b) { + this.boids.push(b); +} + +// The Nature of Code +// Daniel Shiffman +// http://natureofcode.com + +// Clase Boid +// Métodos para Separación, Cohesión, alineamiento + +function Boid(x, y) { + this.acceleration = createVector(0, 0); + this.velocity = createVector(random(-1, 1),random(-1, 1)); + this.position = createVector(x,y); + this.r = 3.0; + this.maxspeed = 3; // Velocidad máxima + this.maxforce = 0.05; // Fuerza de viraje máxima +} + +Boid.prototype.run = function(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); +} + +Boid.prototype.applyForce = function(force) { + // Posibilidad de agregar masa aquí si queremos A = F / M + this.acceleration.add(force); +} + +// Acumular una nueva aceleración cada vez basado en tres reglas +Boid.prototype.flock = function(boids) { + let sep = this.separate(boids); // Separación + let ali = this.align(boids); // Alineamiento + let coh = this.cohesion(boids); // Cohesión + // Dar un peso arbitrario a cada fuerza + sep.mult(1.5); + ali.mult(1.0); + coh.mult(1.0); + // Suma los vectores de fuerza a la aceleración + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); +} + +// Método para actualizar ubicación +Boid.prototype.update = function() { + // Refrescar velocidad + this.velocity.add(this.acceleration); + // Limitar velocidad + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // Resetear acceleración a 0 en cada ciclo + this.acceleration.mult(0); +} + +// Un método que calcula y aplica una fuerza de viraje hacia una posición objetivo +// VIRAJE = DESEADO - VELOCIDAD +Boid.prototype.seek = function(target) { + let desired = p5.Vector.sub(target, this.position); // Un vector apuntando desde la ubicación hacia el objetivo + // Normalizar deseado y escalar según velocidad máxima + desired.normalize(); + desired.mult(this.maxspeed); + // Viraje = Deseado - Velocidad + let steer = p5.Vector.sub(desired, this.velocity); + steer.limit(this.maxforce); // Limita al máximo de fuerza de viraje + return steer; +} + +Boid.prototype.render = function() { + // Dibuja un triángulo rotado en la dirección de la velocidad + let theta = this.velocity.heading() + radians(90); + fill(127); + stroke(200); + push(); + translate(this.position.x, this.position.y); + rotate(theta); + beginShape(); + vertex(0, -this.r * 2); + vertex(-this.r, this.r * 2); + vertex(this.r, this.r * 2); + endShape(CLOSE); + pop(); +} + +// Wraparound, salir por un borde y aparecer por el contrario +Boid.prototype.borders = function() { + if (this.position.x < -this.r) this.position.x = width +this.r; + if (this.position.y < -this.r) this.position.y = height+this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height+ this.r) this.position.y = -this.r; +} + +// Separación +// Método que revisa los boids cercanos y vira para alejarse de ellos +Boid.prototype.separate = function(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // Por cada boid en el sistema, revisa si está muy cerca + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + // Si la distancia es mayor a 0 y menor que una cantidad arbitraria (0 cuando eres tú mismo) + if ((d > 0) && (d < desiredseparation)) { + // Calcular el vector apuntando a alejarse del vecino + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // Peso por distancia + steer.add(diff); + count++; // Mantener registro de cantidad + } + } + // Promedio -- divide por la cantidad + if (count > 0) { + steer.div(count); + } + + // Mientras el vector sea mayor a 0 + if (steer.mag() > 0) { + // Implementa Reynolds: Viraje = Deseado - Velocidad + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; +} + +// Alineamiento +// Para cada boid cercano en el sistema, calcula la velocidad promedio +Boid.prototype.align = function(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } +} + +// Cohesión +// Para la ubicación promedio (centro) de todos los boids cercanos, calcula el vector de viraje hacia esa ubicación. +Boid.prototype.cohesion = function(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // Empieza con un vector vacío para acumular todas las posiciones + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // Añada posición + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // Vira hacia la posición + } else { + return createVector(0, 0); + } +} diff --git a/dist/assets/examples/es/09_Simulate/03_WolframCA.js b/dist/assets/examples/es/09_Simulate/03_WolframCA.js new file mode 100644 index 0000000000..8c5f41ed70 --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/03_WolframCA.js @@ -0,0 +1,72 @@ +/* + * @name Wolfram CA + * @description Demostración simple de un autómata celular Wolfram unidimensional + * (natureofcode.com) + */ + +let w = 10; +// Arreglo de 1s y 0s +let cells; + + // Arbitrariamente inicializar con solo la célula del medio teniendo un estado de "1" +let generation = 0; + +// Arreglo para almacenar el conjunto de reglas, por ejemplo {0,1,1,0,1,1,0,1} +let ruleset = [0, 1, 0, 1, 1, 0, 1, 0]; + +function setup() { + createCanvas(640, 400); + cells = Array(floor(width / w)); + for (let i = 0; i < cells.length; i++) { + cells[i] = 0; + } + cells[cells.length/2] = 1; + +} + +function draw() { + for (let i = 0; i < cells.length; i++) { + if (cells[i] === 1) { + fill(200); + } else { + fill(51); + noStroke(); + rect(i * w, generation * w, w, w); + } + } + if (generation < height / w) { + generate(); + } +} + +// El proceso de crear una nueva generación +function generate() { + //Primero crear un arreglo vacío para los nuevos valores + let nextgen = Array(cells.length); + // Por cada lugar, determinar el nuevo estado según el examen del estado actual y de los estados vecinos + // Ignorar bordes que solo tienen un vecino + for (let i = 1; i < cells.length-1; i++) { + let left = cells[i-1]; // Estado del vecino izquierdo + let me = cells[i]; // Estado actual + let right = cells[i+1]; // Estado del vecino derecho + nextgen[i] = rules(left, me, right); // Calcular el estado siguiente generación basado en el conjunto de reglas + } + // La generación actual es la nueva generación + cells = nextgen; + generation++; +} + + +// Implementar las reglas Wolfram +// Puede ser mejorado y más conciso, pero aquí podemos revisar explicitamente lo que está pasando en cada caso +function rules(a, b, c) { + if (a == 1 && b == 1 && c == 1) return ruleset[0]; + if (a == 1 && b == 1 && c == 0) return ruleset[1]; + if (a == 1 && b == 0 && c == 1) return ruleset[2]; + if (a == 1 && b == 0 && c == 0) return ruleset[3]; + if (a == 0 && b == 1 && c == 1) return ruleset[4]; + if (a == 0 && b == 1 && c == 0) return ruleset[5]; + if (a == 0 && b == 0 && c == 1) return ruleset[6]; + if (a == 0 && b == 0 && c == 0) return ruleset[7]; + return 0; +} diff --git a/dist/assets/examples/es/09_Simulate/04_GameOfLife.js b/dist/assets/examples/es/09_Simulate/04_GameOfLife.js new file mode 100644 index 0000000000..eb1602008b --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/04_GameOfLife.js @@ -0,0 +1,93 @@ +/* + * @name Juego de la vida + * @description Una implementación básica del "Juego de la vida" de John Conway + * (natureofcode.com) + */ + +let w; +let columns; +let rows; +let board; +let next; + +function setup() { + createCanvas(720, 400); + w = 20; + // Calcular columnas y filas + columns = floor(width / w); + rows = floor(height / w); + // Forma extraña de hacer un arreglo 2D en JS + board = new Array(columns); + for (let i = 0; i < columns; i++) { + board[i] = new Array(rows); + } + // Usar múltiples arreglos 2D e intercambiarlos + next = new Array(columns); + for (i = 0; i < columns; i++) { + next[i] = new Array(rows); + } + init(); +} + +function draw() { + background(255); + generate(); + for ( let i = 0; i < columns;i++) { + for ( let j = 0; j < rows;j++) { + if ((board[i][j] == 1)) fill(0); + else fill(255); + stroke(0); + rect(i * w, j * w, w - 1, w - 1); + } + } + +} + +// Resetear tablero cuando el ratón es presionado +function mousePressed() { + init(); +} + +// Llenar tablero aleatoriamente +function init() { + for (let i = 0; i < columns; i++) { + for (let j = 0; j < rows; j++) { + // Llenar bordes con 0s + if (i == 0 || j == 0 || i == columns-1 || j == rows-1) board[i][j] = 0; + // Llenar el resto aleatoriamente + else board[i][j] = floor(random(2)); + next[i][j] = 0; + } + } +} + +// El proceso de crear una nueva generación +function generate() { + + // Recorrer cada lugar de nuestro arreglo 2D y revisar lugares vecinos + for (let x = 1; x < columns - 1; x++) { + for (let y = 1; y < rows - 1; y++) { + // Sumar todos los estados en la grilla 3x3 vecina + let neighbors = 0; + for (let i = -1; i <= 1; i++) { + for (let j = -1; j <= 1; j++) { + neighbors += board[x+i][y+j]; + } + } + + // Un pequeño truco para restar el estado actual de la célula ya que + // lo sumamos en el bucle anterior + neighbors -= board[x][y]; + // Reglas de vida + if ((board[x][y] == 1) && (neighbors < 2)) next[x][y] = 0; // Soledad + else if ((board[x][y] == 1) && (neighbors > 3)) next[x][y] = 0; // Sobrepoblación + else if ((board[x][y] == 0) && (neighbors == 3)) next[x][y] = 1; // Reproducción + else next[x][y] = board[x][y]; // Stasis + } + } + + // Intercambiar! + let temp = board; + board = next; + next = temp; +} diff --git a/dist/assets/examples/es/09_Simulate/05_MultipleParticleSystems.js b/dist/assets/examples/es/09_Simulate/05_MultipleParticleSystems.js new file mode 100644 index 0000000000..3b46f544de --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/05_MultipleParticleSystems.js @@ -0,0 +1,136 @@ +/* + * @name Múltiples sistemas de partículas + * @description Hacer click con el ratón para generar una ráfaga de partículas en la posición del ratón.
Cada ráfaga es una instancia de un sistema de partículas con objetos Particle y CrazyParticle (una subclase de Particle).
Notar el uso de Herencia y Polimorfismo.
+ * Original por Daniel Shiffman. + */ +let systems; + +function setup() { + createCanvas(710, 400); + systems = []; +} + +function draw() { + background(51); + background(0); + for (i = 0; i < systems.length; i++) { + systems[i].run(); + systems[i].addParticle(); + } + if (systems.length == 0) { + fill(255); + textAlign(CENTER); + textSize(32); + text("click mouse to add particle systems", width / 2, height / 2); + } +} + +function mousePressed() { + this.p = new ParticleSystem(createVector(mouseX, mouseY)); + systems.push(p); +} + +// Una clase simple de Particle +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255.0; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// Método para actualizar posición +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// Método para mostrar en pantalla +Particle.prototype.display = function () { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// ¿Sigue siendo útil la partícula? +Particle.prototype.isDead = function () { + if (this.lifespan < 0) { + return true; + } else { + return false; + } +}; + +let ParticleSystem = function (position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function () { + // Añadir o una Particle o una CrazyParticle al sistema + if (int(random(0, 2)) == 0) { + p = new Particle(this.origin); + } + else { + p = new CrazyParticle(this.origin); + } + this.particles.push(p); +}; + +ParticleSystem.prototype.run = function () { + for (let i = this.particles.length - 1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; + +// Una subclase de Particle +function CrazyParticle(origin) { + // Llamar al constructor padre, asegurándose (usando Función#llamada) + // que "this" está configurado correctamente durante la llamada + Particle.call(this, origin); + + // Inicializar nustras propiedades añadidas + this.theta = 0.0; +}; + +// Crear un objeto Crazy.prototype que hereda de Particle.prototype. +// Nota: un error común aquí es usar "new Particle()" para crear el +// Crazy.prototype. Es incorrecto por muchas razones, +// como que no tenemos qué darle a Particle para el argumento de "origin" +// El lugar correcto para llamar a Particle es arriba, donde lo llamamos desde Crazy. +CrazyParticle.prototype = Object.create(Particle.prototype); // Ver nota abajo + +// Set the "constructor" property to refer to CrazyParticle +CrazyParticle.prototype.constructor = CrazyParticle; + +// Notice we don't have the method run() here; it is inherited from Particle + +// This update() method overrides the parent class update() method +CrazyParticle.prototype.update=function() { + Particle.prototype.update.call(this); + // Incrementar rotación basado en la velocidad horizontal + this.theta += (this.velocity.x * this.velocity.mag()) / 10.0; +} + +// Este método display() anula el método display() de la clase padre +CrazyParticle.prototype.display=function() { + // Render de la elipse como una partícula regular + Particle.prototype.display.call(this); + // Añadir línea giratoria + push(); + translate(this.position.x, this.position.y); + rotate(this.theta); + stroke(255, this.lifespan); + line(0, 0, 25, 0); + pop(); +} diff --git a/dist/assets/examples/es/09_Simulate/06_Spirograph.js b/dist/assets/examples/es/09_Simulate/06_Spirograph.js new file mode 100644 index 0000000000..a13780f4ac --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/06_Spirograph.js @@ -0,0 +1,73 @@ + +/* + * @name Espirógrafo + * @description Este bosquejo usa transformaciones siples para crear un + * efecto tipo espirógrafo con partículas entrelazadas(llamadas sinusoides). + * Presiona la barra espaciadora para alternar entre dibujar y mostrar la geometría subyacente.
+ * Ejemplo creado por R. Luke DuBois.
+ * http://en.wikipedia.org/wiki/Spirograph + */ +let NUMSINES = 20; // cuántas partículas podemos hacer al mismo tiempo? +let sines = new Array(NUMSINES); // un arreglo para almacenar todos los ángulos actuales +let rad; // un valor de radio inicial para la sinusoide central +let i; // una variable contador + +// juega con estos valores para entender lo que está pasando: +let fund = 0.005; // la velocidad de la sinusoide central +let ratio = 1; // ¿cuál es el multiplicador de velocidad por cada sinusoide adicional? +let alpha = 50; // cuán opaco es el sistema de trazado + +let trace = false; // ¿estamos trazando? + +function setup() { + createCanvas(710, 400); + + rad = height / 4; // calcular radio del círculo central + background(204); // limpiar la pantalla + + for (let i = 0; i < sines.length; i++) { + sines[i] = PI; // inicializar cada uno en dirección norte + } +} + +function draw() { + if (!trace) { + background(204); // limpiar pantalla si es necesario + stroke(0, 255); // lápiz negro + noFill(); // sin relleno + } + + // ACCION PRINCIPAL + push(); // empezar una matriz de transformación + translate(width / 2, height / 2); // mover al centro de la pantalla + + for (let i = 0; i < sines.length; i++) { + let erad = 0; // radio del "punto" pequeño dentro del círculo... este es el "lápiz" para trazar + // configuración de trazado + if (trace) { + stroke(0, 0, 255 * (float(i) / sines.length), alpha); // azul + fill(0, 0, 255, alpha / 2); // también azul + erad = 5.0 * (1.0 - float(i) / sines.length); // ancho del lápiz dependerá de la sinusoide + } + let radius = rad / (i + 1); // radio del círculo + rotate(sines[i]); // rotar círculo + if (!trace) ellipse(0, 0, radius * 2, radius * 2); // si estamos simulando, dibujar la sinusoide + push(); // subir un nivel + translate(0, radius); // moverse al borde de la sinusoide + if (!trace) ellipse(0, 0, 5, 5); // dibujar un círculo pequeño + if (trace) ellipse(0, 0, erad, erad); // dibujar con erad si estamos trazando + pop(); // bajar un nivel + translate(0, radius); // moverse a la posición de la siguiente sinusoide + sines[i] = (sines[i] + (fund + (fund * i * ratio))) % TWO_PI; // actualizar ángulo basado en la fundamental + } + + pop(); // bajar a la transformación final + +} + +function keyReleased() { + if (key==' ') { + trace = !trace; + background(255); + } +} diff --git a/dist/assets/examples/es/09_Simulate/07_LSystems.js b/dist/assets/examples/es/09_Simulate/07_LSystems.js new file mode 100644 index 0000000000..dfcfc40d79 --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/07_LSystems.js @@ -0,0 +1,106 @@ +/* + * @name Sístemas-L + * @description Este bosquejo crea un dibujo automatizado basado en un sistema Lindenmayer + * o sistema-L. Los sistemas-L son utilizados a menudo en gráfica procedural para hacer + * patrones naturales, geométricos o de tipo fractal.
+ * Ejemplo creado por R. Luke DuBois.
+ * https://en.wikipedia.org/wiki/L-system + */ +// SECCIÓN TORTUGA: +let x, y; // la posición actual de la tortuga +let currentangle = 0; // hacia dónde apunta la tortuga +let step = 20; // cuánto se mueve la tortuga en cada 'F' +let angle = 90; // cuánto gira la tortuga con un '-' or '+' + +// SECCIÓN LINDENMAYER (SISTEMAS-L) +let thestring = 'A'; // "axioma" o inicio de la cadena +let numloops = 5; // cuántas iteraciones a pre-computar +let therules = []; // arreglo para las reglas +therules[0] = ['A', '-BF+AFA+FB-']; // primera regla +therules[1] = ['B', '+AF-BFB-FA+']; // segunda regla + +let whereinstring = 0; // dónde estamos en el sistema-L + +function setup() { + createCanvas(710, 400); + background(255); + stroke(0, 0, 0, 255); + + // inicializar la posición x e y en la esquina inferior izquierda + x = 0; + y = height - 1; + + // CALCULAR EL SISTEMA-L + for (let i = 0; i < numloops; i++) { + thestring = lindenmayer(thestring); + } +} + +function draw() { + + // dibujar el caracter actual en la pantalla + drawIt(thestring[whereinstring]); + + // incrementar el punto de donde leemos la cadena. + // si sobrepasamos el final, volver al inicio. + whereinstring++; + if (whereinstring > thestring.length - 1) whereinstring = 0; + +} + +// interpretar un sistema-L +function lindenmayer(s) { + let outputstring = ''; // inicializar una cadena de salida en blanco + + // iterar a lo largo de las 'reglas' buscando coincidencias de símbolo: + for (let i = 0; i < s.length; i++) { + let ismatch = 0; // por defecto, sin coincidencia + for (let j = 0; j < therules.length; j++) { + if (s[i] == therules[j][0]) { + outputstring += therules[j][1]; //escribir substitución + ismatch = 1; //si tenemos una coincidencia, no copiemos el símbolo + break; // salir de este bucle for() + } + } + // si nada coincide, simplemente copia el símbolo. + if (ismatch == 0) outputstring += s[i]; + } + + return outputstring; // enviar la cadena modificada +} + +// esta es una función que dibuja los comandos de la tortuga +function drawIt(k) { + + if (k=='F') { // dibujar hacia adelante + // de polar a cartesiano basado en paso y ángulo actual: + let x1 = x + step * cos(radians(currentangle)); + let y1 = y + step * sin(radians(currentangle)); + line(x, y, x1, y1); // conectar el anterior y el nuevo + + // actualizar la posición de la tortuga: + x = x1; + y = y1; + } else if (k == '+') { + currentangle += angle; // doblar hacia la izquierda + } else if (k == '-') { + currentangle -= angle; // doblar hacia la derecha + } + + // valores aleatorios de color: + let r = random(128, 255); + let g = random(0, 192); + let b = random(0, 50); + let a = random(50, 100); + + // escoger una distribución gaussiana (D&D) para el radio: + let radius = 0; + radius += random(0, 15); + radius += random(0, 15); + radius += random(0, 15); + radius = radius / 3; + + // dibujar: + fill(r, g, b, a); + ellipse(x, y, radius, radius); +} diff --git a/dist/assets/examples/es/09_Simulate/08_Spring.js b/dist/assets/examples/es/09_Simulate/08_Spring.js new file mode 100644 index 0000000000..887c1849bd --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/08_Spring.js @@ -0,0 +1,92 @@ +/* + * @name Resorte + * @frame 710, 400 + * @description Haz click, arrastra y suelta la barra horizontal para inicializar el resorte. + */ +// Constantes de dibujo de resorte para la barra superior +let springHeight = 32, + left, + right, + maxHeight = 200, + minHeight = 100, + over = false, + move = false; + +// Constantes de simulación de resorte +let M = 0.8, // Masa + K = 0.2, // Constante de resorte + D = 0.92, // Amortiguamiento + R = 150; // Posición de reposo + +// variables de simulación de resorte +let ps = R, // Posición + vs = 0.0, // Velocidad + as = 0, // Aceleración + f = 0; // Fuerza + +function setup() { + createCanvas(710, 400); + rectMode(CORNERS); + noStroke(); + left = width / 2 - 100; + right = width / 2 + 100; +} + +function draw() { + background(102); + updateSpring(); + drawSpring(); +} + +function drawSpring() { + // Dibujar la base + fill(0.2); + let baseWidth = 0.5 * ps + -8; + rect(width/2 - baseWidth, ps + springHeight, width/2 + baseWidth, height); + + // Definir color y dibujar barra superior + if (over || move) { + fill(255); + } else { + fill(204); + } + + rect(left, ps, right, ps + springHeight); +} + +function updateSpring() { + // Actualizar posición del resorte + if ( !move ) { + f = -K * ( ps - R ); // f=-ky + as = f / M; // Definir la aceleración, f=ma == a=f/m + vs = D * (vs + as); // Definir la velocidad + ps = ps + vs; // Actualizar posición + } + + if (abs(vs) < 0.1) { + vs = 0.0; + } + + // Comprobar si el ratón está sobre la barra superior + if (mouseX > left && mouseX < right && mouseY > ps && mouseY < ps + springHeight) { + over = true; + } else { + over = false; + } + + // Definir y limitar la posición de la barra superior + if (move) { + ps = mouseY - springHeight / 2; + ps = constrain(ps, minHeight, maxHeight); + } +} + +function mousePressed() { + if (over) { + move = true; + } +} + +function mouseReleased() { + move = false; +} diff --git a/dist/assets/examples/es/09_Simulate/09_Springs.js b/dist/assets/examples/es/09_Simulate/09_Springs.js new file mode 100644 index 0000000000..3e4d422831 --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/09_Springs.js @@ -0,0 +1,147 @@ +/* + * @name Resortes + * @frame 710,400 + * @description Mueve el ratón sobre uno de los círculos y haz clic para reposicionarlo. + * Cuando sueltes el ratón, se volverá a colocar en su posición. + * Cada círculo tiene un comportamiento ligeramente diferente. + * (puerto de https://processing.org/examples/springs.html) + */ +let num = 3; +let springs = []; + +function setup() { + createCanvas(710, 400); + noStroke(); + + springs[0] = new Spring(240, 260, 40, 0.98, 8.0, 0.1, springs, 0); + springs[1] = new Spring(320, 210, 120, 0.95, 9.0, 0.1, springs, 1); + springs[2] = new Spring(180, 170, 200, 0.90, 9.9, 0.1, springs, 2); +} + +function draw() { + background(51); + + for (let i = 0; i < num; i++) { + springs[i].update(); + springs[i].display(); + } +} + +function mousePressed() { + for (let i = 0; i < num; i++) { + springs[i].pressed(); + } +} + +function mouseReleased() { + for (let i = 0; i < num; i++) { + springs[i].released(); + } +} + +// Spring class +function Spring (_x, _y, _s, _d, _m, _k_in, _others, _id) { + // Screen values + // this.xpos = _x; + // this.ypos = _y; + + this.x_pos = _x; + this.y_pos= _y; + + this.size = 20; + this.size = _s; + + this.over = false; + this.move = false; + + // Spring simulation constants + this.mass = _m; // Mass + this.k = 0.2; // Spring constant + this.k = _k_in; + this.damp = _d; // Damping + this.rest_posx = _x; // Rest position X + this.rest_posy = _y; // Rest position Y + + // Spring simulation variables + //float pos = 20.0; // Position + this.velx = 0.0; // X Velocity + this.vely = 0.0; // Y Velocity + this.accel = 0; // Acceleration + this.force = 0; // Force + + this.friends = _others; + this.id = _id; + + this.update = function() { + + if (this.move) { + this.rest_posy = mouseY; + this.rest_posx = mouseX; + } + + this.force = -this.k * (this.y_pos - this.rest_posy); // f=-ky + this.accel = this.force / this.mass; // Set the acceleration, f=ma == a=f/m + this.vely = this.damp * (this.vely + this.accel); // Set the velocity + this.y_pos = this.y_pos + this.vely; // Updated position + + + this.force = -this.k * (this.x_pos - this.rest_posx); // f=-ky + this.accel = this.force / this.mass; // Set the acceleration, f=ma == a=f/m + this.velx = this.damp * (this.velx + this.accel); // Set the velocity + this.x_pos = this.x_pos + this.velx; // Updated position + + + if ((this.overEvent() || this.move) && !(this.otherOver()) ) { + this.over = true; + } else { + this.over = false; + } + } + + // Test to see if mouse is over this spring + this.overEvent = function() { + let disX = this.x_pos - mouseX; + let disY = this.y_pos - mouseY; + let dis = createVector(disX, disY); + if (dis.mag() < this.size / 2 ) { + return true; + } else { + return false; + } + } + + // Make sure no other springs are active + this.otherOver = function() { + for (let i=0; i < num; i++) { + if (i != this.id) { + if (this.friends[i].over == true) { + return true; + } + } + } + return false; + } + + this.display = function() { + if (this.over) { + fill(153); + } else { + fill(255); + } + ellipse(this.x_pos, this.y_pos, this.size, this.size); + } + + this.pressed = function() { + if (this.over) { + this.move = true; + } else { + this.move = false; + } + } + + this.released = function() { + this.move = false; + this.rest_posx = this.y_pos; + this.rest_posy = this.y_pos; + } +}; diff --git a/dist/assets/examples/es/09_Simulate/10_SoftBody.js b/dist/assets/examples/es/09_Simulate/10_SoftBody.js new file mode 100644 index 0000000000..a6a34f9d14 --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/10_SoftBody.js @@ -0,0 +1,110 @@ +/* + * @name Cuerpo blando + * @description Ejemplo original por Ira Greenberg. + *

Simulación de dinámica de cuerpo blando usando curveVertex() y curveTightness(). + */ +// Punto central +let centerX = 0.0, centerY = 0.0; + +let radius = 45, rotAngle = -90; +let accelX = 0.0, accelY = 0.0; +let deltaX = 0.0, deltaY = 0.0; +let springing = 0.0009, damping = 0.98; + +// nodos esquina +let nodes = 5; + +// Arreglos vacíos +let nodeStartX = []; +let nodeStartY = []; +let nodeX = []; +let nodeY = []; +let angle = []; +let frequency = []; + +// Dinámica de cuerpo blando +let organicConstant = 1.0; + +function setup() { + createCanvas(710, 400); + + // centrar la figura en la ventana + centerX = width / 2; + centerY = height / 2; + + //inicializar arreglos a 0 + for (let i=0; i.length dentro un bucle for + // pero lo guardamos acá porque en caso contrario, estaríamos recalculando el largo en cada iteración del bucle for + let len = this.particles.length; + + // iterar sobre todas las partículas y hacerlas correr con el método run() + for (let i = len - 1; i >= 0; i--) { + let particle = this.particles[i]; + particle.run(); + + // si la partícula está muerta, la removemos. + // los arreglos en javascript no poseen una función "remover", pero "splice" funciona. + // le damos como parámetro un lugar dónde empezar, y luego especificamos cuántas casillas desde aquí son removidas. + if (particle.isDead()) { + this.particles.splice(i, 1); + } + } +} + +/** + * Método para añadir un vector fuerza a todas las partículas actualmente en el sistema + * @param dir un p5.Vector que describe la dirección de la fuerza. + */ +ParticleSystem.prototype.applyForce = function(dir) { + let len = this.particles.length; + for(let i = 0; i < len; ++i){ + this.particles[i].applyForce(dir); + } +} + +/** + * Agrega una nueva partícula en el origen del sistema y con la textura definida originalmente. + */ +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin, this.img)); +} + +//========= PARTÍCULA =========== +/** + * Una clase simple de Particle, hace render de la partícula como una imagen + */ +let Particle = function (pos, img_) { + this.loc = pos.copy(); + + let vx = randomGaussian() * 0.3; + let vy = randomGaussian() * 0.3 - 1.0; + + this.vel = createVector(vx, vy); + this.acc = createVector(); + this.lifespan = 100.0; + this.texture = img_; +} + +/** + * Actualiza y muestra simultáneamente una partícula + */ +Particle.prototype.run = function() { + this.update(); + this.render(); +} + +/** + * Una función para mostrar en pantalla una partícula + */ +Particle.prototype.render = function() { + imageMode(CENTER); + tint(255, this.lifespan); + image(this.texture, this.loc.x, this.loc.y); +} + +/** + * Un método para aplicar un vector fuerza a una partícula. + */ +Particle.prototype.applyForce = function(f) { + this.acc.add(f); +} + +/** + * Este método revisa si la partícula ha llegado al fin de su vida, + * si lo ha hecho, devuelve true, en otro caso devuelve false. + */ +Particle.prototype.isDead = function () { + if (this.lifespan <= 0.0) { + return true; + } else { + return false; + } +} + +/** + * Este método actualiza la posición de la partícula. + */ +Particle.prototype.update = function() { + this.vel.add(this.acc); + this.loc.add(this.vel); + this.lifespan -= 2.5; + this.acc.mult(0); +} diff --git a/dist/assets/examples/es/09_Simulate/12_BrownianMotion.js b/dist/assets/examples/es/09_Simulate/12_BrownianMotion.js new file mode 100644 index 0000000000..0db56957c8 --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/12_BrownianMotion.js @@ -0,0 +1,46 @@ +/* + * @name Movimiento browniano + * @description Grabar movimiento aleatorio como una líena continua. + * Puerto de un ejemplo original para Processing. + */ + +let num = 2000; +let range = 6; + +let ax = []; +let ay = []; + + +function setup() { + createCanvas(710, 400); + for ( let i = 0; i < num; i++ ) { + ax[i] = width / 2; + ay[i] = height / 2; + } + frameRate(30); +} + +function draw() { + background(51); + + // Mover todos los elementos un lugar a la izquierda + for ( let i = 1; i < num; i++ ) { + ax[i - 1] = ax[i]; + ay[i - 1] = ay[i]; + } + + // Poner un nuevo valor al final del arreglo + ax[num - 1] += random(-range, range); + ay[num - 1] += random(-range, range); + + // Limitar la posición de todos los puntos a estar dentro de la pantalla + ax[num - 1] = constrain(ax[num - 1], 0, width); + ay[num - 1] = constrain(ay[num - 1], 0, height); + + // Dibujar una línea conectando los puntos + for ( let j = 1; j < num; j++ ) { + let val = j / num * 204.0 + 51; + stroke(val); + line(ax[j - 1], ay[j - 1], ax[j], ay[j]); + } +} diff --git a/dist/assets/examples/es/09_Simulate/13_Chain.js b/dist/assets/examples/es/09_Simulate/13_Chain.js new file mode 100644 index 0000000000..5431f7e3fe --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/13_Chain.js @@ -0,0 +1,55 @@ +/* + * @name Cadena + * @description Una masa está unida a la posición del ratón y la otra está unida a la posición de la otra masa. La gravedad en el ambiente tira de ambas hacia abajo. + * Puerto de un ejemplo original para Processing. + */ +let s1, s2; +let gravity = 9.0; +let mass = 2.0; + +function setup() { + createCanvas(720, 400); + fill(255, 126); + // Inputs: x, y, mass, gravity + s1 = new Spring2D(0.0, width / 2, mass, gravity); + s2 = new Spring2D(0.0, width / 2, mass, gravity); +} + +function draw() { + background(0); + s1.update(mouseX, mouseY); + s1.display(mouseX, mouseY); + s2.update(s1.x, s1.y); + s2.display(s1.x, s1.y); +} + +function Spring2D(xpos, ypos, m, g) { + this.x = xpos;// The x- and y-coordinates + this.y = ypos; + this.vx = 0; // The x- and y-axis velocities + this.vy = 0; + this.mass = m; + this.gravity = g; + this.radius = 30; + this.stiffness = 0.2; + this.damping = 0.7; + + this.update = function(targetX, targetY) { + let forceX = (targetX - this.x) * this.stiffness; + let ax = forceX / this.mass; + this.vx = this.damping * (this.vx + ax); + this.x += this.vx; + let forceY = (targetY - this.y) * this.stiffness; + forceY += this.gravity; + let ay = forceY / this.mass; + this.vy = this.damping * (this.vy + ay); + this.y += this.vy; + } + + this.display = function(nx, ny) { + noStroke(); + ellipse(this.x, this.y, this.radius * 2, this.radius * 2); + stroke(255); + line(this.x, this.y, nx, ny); + } +} \ No newline at end of file diff --git a/dist/assets/examples/es/09_Simulate/14_SnowflakeParticleSystem.js b/dist/assets/examples/es/09_Simulate/14_SnowflakeParticleSystem.js new file mode 100644 index 0000000000..b8c1c7f9e5 --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/14_SnowflakeParticleSystem.js @@ -0,0 +1,63 @@ +/* + * @name Copos de Nieve + * @description Sistema de partículas que simula el movimiento de copos de nieve cayendo. + * Utiliza un arreglo de objetos para almacenar las particulas de copos de nieve. + * Contribución de Aatish Bhatia. + */ + +let snowflakes = []; // array to hold snowflake objects + +function setup() { + createCanvas(400, 600); + fill(240); + noStroke(); +} + +function draw() { + background('brown'); + let t = frameCount / 60; // update time + + // create a random number of snowflakes each frame + for (let i = 0; i < random(5); i++) { + snowflakes.push(new snowflake()); // append snowflake object + } + + // loop through snowflakes with a for..of loop + for (let flake of snowflakes) { + flake.update(t); // update snowflake position + flake.display(); // draw snowflake + } +} + +// snowflake class +function snowflake() { + // initialize coordinates + this.posX = 0; + this.posY = random(-50, 0); + this.initialangle = random(0, 2 * PI); + this.size = random(2, 5); + + // radius of snowflake spiral + // chosen so the snowflakes are uniformly spread out in area + this.radius = sqrt(random(pow(width / 2, 2))); + + this.update = function(time) { + // x position follows a circle + let w = 0.6; // angular speed + let angle = w * time + this.initialangle; + this.posX = width / 2 + this.radius * sin(angle); + + // different size snowflakes fall at slightly different y speeds + this.posY += pow(this.size, 0.5); + + // delete snowflake if past end of screen + if (this.posY > height) { + let index = snowflakes.indexOf(this); + snowflakes.splice(index, 1); + } + }; + + this.display = function() { + ellipse(this.posX, this.posY, this.size); + }; +} diff --git a/dist/assets/examples/es/09_Simulate/15_penrose_tiles.js b/dist/assets/examples/es/09_Simulate/15_penrose_tiles.js new file mode 100644 index 0000000000..7bd12af7ae --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/15_penrose_tiles.js @@ -0,0 +1,123 @@ +/* + * @name Baldosas de Penrose + * @frame 710,400 + * @description Este es un puerto de David Blitz del ejemplo "Baldosa de Penrose" de processing.org/examples + */ + +let ds; + +function setup() { + createCanvas(710, 400); + ds = new PenroseLSystem(); + //please, play around with the following line + ds.simulate(5); +} + +function draw() { + background(0); + ds.render(); +} + +function PenroseLSystem() { + this.steps = 0; + + //these are axiom and rules for the penrose rhombus l-system + //a reference would be cool, but I couldn't find a good one + this.axiom = "[X]++[X]++[X]++[X]++[X]"; + this.ruleW = "YF++ZF----XF[-YF----WF]++"; + this.ruleX = "+YF--ZF[---WF--XF]+"; + this.ruleY = "-WF++XF[+++YF++ZF]-"; + this.ruleZ = "--YF++++WF[+ZF++++XF]--XF"; + + //please play around with the following two lines + this.startLength = 460.0; + this.theta = TWO_PI / 10.0; //36 degrees, try TWO_PI / 6.0, ... + this.reset(); +} + +PenroseLSystem.prototype.simulate = function (gen) { + while (this.getAge() < gen) { + this.iterate(this.production); + } +} + +PenroseLSystem.prototype.reset = function () { + this.production = this.axiom; + this.drawLength = this.startLength; + this.generations = 0; +} + +PenroseLSystem.prototype.getAge = function () { + return this.generations; +} + +//apply substitution rules to create new iteration of production string +PenroseLSystem.prototype.iterate = function() { + let newProduction = ""; + + for(let i=0; i < this.production.length; ++i) { + let step = this.production.charAt(i); + //if current character is 'W', replace current character + //by corresponding rule + if (step == 'W') { + newProduction = newProduction + this.ruleW; + } + else if (step == 'X') { + newProduction = newProduction + this.ruleX; + } + else if (step == 'Y') { + newProduction = newProduction + this.ruleY; + } + else if (step == 'Z') { + newProduction = newProduction + this.ruleZ; + } + else { + //drop all 'F' characters, don't touch other + //characters (i.e. '+', '-', '[', ']' + if (step != 'F') { + newProduction = newProduction + step; + } + } + } + + this.drawLength = this.drawLength * 0.5; + this.generations++; + this.production = newProduction; +} + +//convert production string to a turtle graphic +PenroseLSystem.prototype.render = function () { + translate(width / 2, height / 2); + + this.steps += 20; + if(this.steps > this.production.length) { + this.steps = this.production.length; + } + + for(let i=0; i < this.steps; ++i) { + let step = this.production.charAt(i); + + //'W', 'X', 'Y', 'Z' symbols don't actually correspond to a turtle action + if( step == 'F') { + stroke(255, 60); + for(let j=0; j < this.repeats; j++) { + line(0, 0, 0, -this.drawLength); + noFill(); + translate(0, -this.drawLength); + } + this.repeats = 1; + } + else if (step == '+') { + rotate(this.theta); + } + else if (step == '-') { + rotate(-this.theta); + } + else if (step == '[') { + push(); + } + else if (step == ']') { + pop(); + } + } +} diff --git a/dist/assets/examples/es/09_Simulate/16_Recursive_Tree.js b/dist/assets/examples/es/09_Simulate/16_Recursive_Tree.js new file mode 100644 index 0000000000..dbdf584a9f --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/16_Recursive_Tree.js @@ -0,0 +1,55 @@ +/* + * @name Árbol Recursivo + * @description Representa una estructura simple en forma de árbol a través de la recursión. + * El ángulo de ramificación se calcula en función de la posición horizontal del ratón. + * Mueve el ratón hacia la izquierda y la derecha para cambiar el ángulo. + * Basado en el Ejemplo de Árbol Recursivo de Daniel Shiffman para Processing. + */ +let theta; + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(0); + frameRate(30); + stroke(255); + // Let's pick an angle 0 to 90 degrees based on the mouse position + let a = (mouseX / width) * 90; + // Convert it to radians + theta = radians(a); + // Start the tree from the bottom of the screen + translate(width/2,height); + // Draw a line 120 pixels + line(0,0,0,-120); + // Move to the end of that line + translate(0,-120); + // Start the recursive branching! + branch(120); + +} + +function branch(h) { + // Each branch will be 2/3rds the size of the previous one + h *= 0.66; + + // All recursive functions must have an exit condition!!!! + // Here, ours is when the length of the branch is 2 pixels or less + if (h > 2) { + push(); // Save the current state of transformation (i.e. where are we now) + rotate(theta); // Rotate by theta + line(0, 0, 0, -h); // Draw the branch + translate(0, -h); // Move to the end of the branch + branch(h); // Ok, now call myself to draw two new branches!! + pop(); // Whenever we get back here, we "pop" in order to restore the previous matrix state + + // Repeat the same thing, only branch off to the "left" this time! + push(); + rotate(-theta); + line(0, 0, 0, -h); + translate(0, -h); + branch(h); + pop(); + } +} diff --git a/dist/assets/examples/es/09_Simulate/17_Mandelbrot.js b/dist/assets/examples/es/09_Simulate/17_Mandelbrot.js new file mode 100644 index 0000000000..39582e83f1 --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/17_Mandelbrot.js @@ -0,0 +1,86 @@ +/* + * @name El Conjunto de Mandelbrot + * @description Renderización simple del conjunto de Mandelbrot. + * Basado en el trabajo para Processing de Daniel Shiffman Ejemplo de Mandelbrot. + */ + +function setup() { + createCanvas(710, 400); + pixelDensity(1); + noLoop(); +} + +function draw() { + background(0); + + // Establish a range of values on the complex plane + // A different range will allow us to "zoom" in or out on the fractal + + // It all starts with the width, try higher or lower values + const w = 4; + const h = (w * height) / width; + + // Start at negative half the width and height + const xmin = -w/2; + const ymin = -h/2; + + // Make sure we can write to the pixels[] array. + // Only need to do this once since we don't do any other drawing. + loadPixels(); + + // Maximum number of iterations for each point on the complex plane + const maxiterations = 100; + + // x goes from xmin to xmax + const xmax = xmin + w; + // y goes from ymin to ymax + const ymax = ymin + h; + + // Calculate amount we increment x,y for each pixel + const dx = (xmax - xmin) / (width); + const dy = (ymax - ymin) / (height); + + // Start y + let y = ymin; + for (let j = 0; j < height; j++) { + // Start x + let x = xmin; + for (let i = 0; i < width; i++) { + + // Now we test, as we iterate z = z^2 + cm does z tend towards infinity? + let a = x; + let b = y; + let n = 0; + while (n < maxiterations) { + const aa = a * a; + const bb = b * b; + const twoab = 2.0 * a * b; + a = aa - bb + x; + b = twoab + y; + // Infinty in our finite world is simple, let's just consider it 16 + if (dist(aa, bb, 0, 0) > 16) { + break; // Bail + } + n++; + } + + // We color each pixel based on how long it takes to get to infinity + // If we never got there, let's pick the color black + const pix = (i+j*width)*4; + const norm = map(n, 0, maxiterations, 0, 1); + let bright = map(sqrt(norm), 0, 1, 0, 255); + if (n == maxiterations) { + bright = 0; + } else { + // Gosh, we could make fancy colors here if we wanted + pixels[pix + 0] = bright; + pixels[pix + 1] = bright; + pixels[pix + 2] = bright; + pixels[pix + 3] = 255; + } + x += dx; + } + y += dy; + } + updatePixels(); +} diff --git a/dist/assets/examples/es/09_Simulate/18_Koch.js b/dist/assets/examples/es/09_Simulate/18_Koch.js new file mode 100644 index 0000000000..f09f5d4a8a --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/18_Koch.js @@ -0,0 +1,141 @@ +/* + * @name Curva Koch + * @description Renderización de un fractal simple: el copo de nieve de Koch. Cada nivel recursivo se dibuja en secuencia. + * Por Daniel Shiffman. + */ + +let k; + +function setup() { + createCanvas(710, 400); + frameRate(1); // Animate slowly + k = new KochFractal(); +} + +function draw() { + background(0); + // Draws the snowflake! + k.render(); + // Iterate + k.nextLevel(); + // Let's not do it more than 5 times. . . + if (k.getCount() > 5) { + k.restart(); + } +} + +// A class to describe one line segment in the fractal +// Includes methods to calculate midp5.Vectors along the line according to the Koch algorithm + +class KochLine { + constructor(a,b) { + // Two p5.Vectors, + // start is the "left" p5.Vector and + // end is the "right p5.Vector + this.start = a.copy(); + this.end = b.copy(); + } + + display() { + stroke(255); + line(this.start.x, this.start.y, this.end.x, this.end.y); + } + + kochA() { + return this.start.copy(); + } + + // This is easy, just 1/3 of the way + kochB() { + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + v.add(this.start); + return v; + } + + // More complicated, have to use a little trig to figure out where this p5.Vector is! + kochC() { + let a = this.start.copy(); // Start at the beginning + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + a.add(v); // Move to point B + v.rotate(-PI/3); // Rotate 60 degrees + a.add(v); // Move to point C + return a; + } + + // Easy, just 2/3 of the way + kochD() { + let v = p5.Vector.sub(this.end, this.start); + v.mult(2/3.0); + v.add(this.start); + return v; + } + + kochE() { + return this.end.copy(); + } +} + +// A class to manage the list of line segments in the snowflake pattern + +class KochFractal { + constructor() { + this.start = createVector(0,height-20); // A p5.Vector for the start + this.end = createVector(width,height-20); // A p5.Vector for the end + this.lines = []; // An array to keep track of all the lines + this.count = 0; + this.restart(); + } + + nextLevel() { + // For every line that is in the arraylist + // create 4 more lines in a new arraylist + this.lines = this.iterate(this.lines); + this.count++; + } + + restart() { + this.count = 0; // Reset count + this.lines = []; // Empty the array list + this.lines.push(new KochLine(this.start,this.end)); // Add the initial line (from one end p5.Vector to the other) + } + + getCount() { + return this.count; + } + + // This is easy, just draw all the lines + render() { + for(let i = 0; i < this.lines.length; i++) { + this.lines[i].display(); + } + } + + // This is where the **MAGIC** happens + // Step 1: Create an empty arraylist + // Step 2: For every line currently in the arraylist + // - calculate 4 line segments based on Koch algorithm + // - add all 4 line segments into the new arraylist + // Step 3: Return the new arraylist and it becomes the list of line segments for the structure + + // As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . . + iterate(before) { + let now = []; // Create emtpy list + for(let i = 0; i < this.lines.length; i++) { + let l = this.lines[i]; + // Calculate 5 koch p5.Vectors (done for us by the line object) + let a = l.kochA(); + let b = l.kochB(); + let c = l.kochC(); + let d = l.kochD(); + let e = l.kochE(); + // Make line segments between all the p5.Vectors and add them + now.push(new KochLine(a,b)); + now.push(new KochLine(b,c)); + now.push(new KochLine(c,d)); + now.push(new KochLine(d,e)); + } + return now; + } +} diff --git a/dist/assets/examples/es/09_Simulate/19_Bubblesort.js b/dist/assets/examples/es/09_Simulate/19_Bubblesort.js new file mode 100644 index 0000000000..188b065864 --- /dev/null +++ b/dist/assets/examples/es/09_Simulate/19_Bubblesort.js @@ -0,0 +1,67 @@ +/* + * @name Ordenamiento de Burbuja + * @description Ordena las barras distribuidas aleatoriamente + * según su altura en orden ascendente mientras simula todo el + * proceso de clasificación. + * Se usaron referencias del 'Coding Challenge' de 'The Coding Train'. + */ + +let values = []; +let i = 0; +let j = 0; + +// The statements in the setup() function +// execute once when the program begins +// The array is filled with random values in setup() function. +function setup() { + createCanvas(720, 400); + for(let i = 0;i values[j+1]){ + values[j] = values[j+1]; + values[j+1] = temp; + } + j++; + + if(j>=values.length-i-1){ + j = 0; + i++; + } + } + else{ + noLoop(); + } + } +} + +// The simulateSorting() function helps in animating +// the whole bubble sort algorithm +// by drawing the rectangles using values +// in the array as the length of the rectangle. +function simulateSorting(){ + for(let i = 0;i= width || this.xPos <= 0){ + this.xSpeed*=-1; + } + } +} + +function setup() { + createCanvas(720, 400); + createP("Keep the mouse clicked").style('color','#ffffff'); + createP("to check whether the bricks").style('color','#ffffff'); + createP("are moving at same speed or not").style('color','#ffffff'); +} + +// creating two bricks of +// colors white and black +let brick1 = new Brick("white",100); +let brick2 = new Brick("black",250); + +// +brick1.setSpeed(); +brick2.setSpeed(); + +function draw () { + background(0); + if(mouseIsPressed){ + background(50); + } + brick1.createBrick(); + brick1.moveBrick(); + if(!mouseIsPressed){ + createBars(); + } + brick2.createBrick(); + brick2.moveBrick(); +} + +// this function creates the black and +// white bars across the screen +function createBars() { + let len = 12; + for(let i = 0;i width) + this.xSpeed*=-1; + if(this.y < 0 || this.y > height) + this.ySpeed*=-1; + this.x+=this.xSpeed; + this.y+=this.ySpeed; + } + +// this function creates the connections(lines) +// between particles which are less than a certain distance apart + joinParticles(paraticles) { + particles.forEach(element =>{ + let dis = dist(this.x,this.y,element.x,element.y); + if(dis<85) { + stroke('rgba(255,255,255,0.04)'); + line(this.x,this.y,element.x,element.y); + } + }); + } +} + +// an array to add multiple particles +let particles = []; + +function setup() { + createCanvas(720, 400); + for(let i = 0;i
+ * Quicksort is a divide-and-conquer algorithm: it + * performs sorting by dividing the original array into + * smaller subarrays and solving them independently, + * loosely speaking. It involves picking an element of + * the array as the pivot element and partitioning the + * given array around the picked pivot.
+ * Partitioning refers to arranging the given array(or + * subarray) in such a way that all elements to the left + * of the pivot element are smaller than it and all + * elements to its right are larger than it. Thus, we have + * a reference point from where we proceed to sort the + * left and right 'halves' of the array, and eventually + * arrive at an array sorted in ascending order. + * + * More
+ */ + +// width of each bar is taken as 8. +let values = []; +// The array 'states' helps in identifying the pivot index +// at every step, and also the subarray which is being sorted +// at any given time. +let states = []; + +// The setup() function is called once when the program +// starts. Here, we fill the array 'values' with random values +// and the array 'states' with a value of -1 for each position. +function setup() { + createCanvas(710, 400); + for(let i = 0; i < width/8; i++) { + values.push(random(height)); + states.push(-1); + } + quickSort(0, values.length - 1); +} + +// The statements in draw() function are executed continuously +// until the program is stopped. Each statement is executed +// sequentially and after the last line is read, the first +// line is executed again. +function draw() { + background(140); + for(let i = 0; i < values.length; i++) { + // color coding + if (states[i] == 0) { + // color for the bar at the pivot index + fill('#E0777D'); + } else if (states[i] == 1) { + // color for the bars being sorted currently + fill('#D6FFB7'); + } else { + fill(255); + } + rect(i * 8, height - values[i], 8, values[i]); + } +} + +async function quickSort(start, end) { + if (start > end) { // Nothing to sort! + return; + } + // partition() returns the index of the pivot element. + // Once partition() is executed, all elements to the + // left of the pivot element are smaller than it and + // all elements to its right are larger than it. + let index = await partition(start, end); + // restore original state + states[index] = -1; + await Promise.all( + [quickSort(start, index - 1), + quickSort(index + 1, end) + ]); +} + +// We have chosen the element at the last index as +// the pivot element, but we could've made different +// choices, e.g. take the first element as pivot. +async function partition(start, end) { + for (let i = start; i < end; i++) { + // identify the elements being considered currently + states[i] = 1; + } + // Quicksort algorithm + let pivotIndex = start; + // make pivot index distinct + states[pivotIndex] = 0; + let pivotElement = values[end]; + for (let i = start; i < end; i++) { + if (values[i] < pivotElement) { + await swap(i, pivotIndex); + states[pivotIndex] = -1; + pivotIndex++; + states[pivotIndex] = 0; + } + } + await swap(end, pivotIndex); + for (let i = start; i < end; i++) { + // restore original state + if (i != pivotIndex) { + states[i] = -1; + } + } + return pivotIndex; +} + +// swaps elements of 'values' at indices 'i' and 'j' +async function swap(i, j) { + // adjust the pace of the simulation by changing the + // value + await sleep(25); + let temp = values[i]; + values[i] = values[j]; + values[j] = temp; +} + +// custom helper function to deliberately slow down +// the sorting process and make visualization easy +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} \ No newline at end of file diff --git a/dist/assets/examples/es/10_Interaction/10_Tickle.js b/dist/assets/examples/es/10_Interaction/10_Tickle.js new file mode 100644 index 0000000000..f7b58375da --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/10_Tickle.js @@ -0,0 +1,48 @@ +/* + * @name Cosquillas + * @description La palabra "tickle" se mueve cuando el cursor está sobre ella. + * A veces, puede ser incluso arrastrada fuera de la pantalla. + */ +let message = 'tickle', + font, + bounds, // almacena la posición, ancho y alto de la caja contenedora del texto + fontsize = 60, + x, + y; // coordenadas x e y del texto + +function preload() { + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // definir la fuente del texto + textFont(font); + textSize(fontsize); + + // obtener ancho y alto del texto para centrarlo inicialmente + bounds = font.textBounds(message, 0, 0, fontsize); + x = width / 2 - bounds.w / 2; + y = height / 2 - bounds.h / 2; +} + +function draw() { + background(204, 120); + + // escribir el texto con negro y obtener su caja contenedora + fill(0); + text(message, x, y); + bounds = font.textBounds(message, x, y, fontsize); + + // revisar si el ratón está dentro de la caja contenedora y moverse si es así + if ( + mouseX >= bounds.x && + mouseX <= bounds.x + bounds.w && + mouseY >= bounds.y && + mouseY <= bounds.y + bounds.h + ) { + x += random(-5, 5); + y += random(-5, 5); + } +} diff --git a/dist/assets/examples/es/10_Interaction/11_WeightLine.js b/dist/assets/examples/es/10_Interaction/11_WeightLine.js new file mode 100644 index 0000000000..a455dcb781 --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/11_WeightLine.js @@ -0,0 +1,55 @@ +/* + * @name Weight Line + * @frame 710,400 + * @description contributed by + Prof WM Harris, using the random function with events to color/weight a line
+ How to use the random function with events to color/ weight a line + dependent on mouse location, left mouse button clicks, character key types, and + random key releases.
+ Functions are created for both the canvas set up as well as the creation of + the line. Depending on the action taken by the user the line can + vary in width and color. Left mouse button clicks result in a color + change to blue, while the typing of any character key will change + the color to turquoise, each resulting in a variable stroke weight; + the width of the former will be between 0 – 1 while the width of + the latter will be 0 – 5. The release of any key will result in a + random hue, saturation, and brightness change to the line. + */ + + +function setup() { + createCanvas(400, 400); + background("beige"); + colorMode(HSB); + } + + function draw() { + //Line from prev pt to current pt + //of mouse position + line(mouseX, mouseY, pmouseX, pmouseY); + } + + //listen when we click the mouse + function mouseClicked() { + //weights 0 to 1 + stroke("slateBlue"); + strokeWeight(random()); + + //what if want weights 0 to .4? + //strokeWeight( random(.4) ); + } + + //listen when we release *any* key + function keyReleased() { + //color hue values between 20 and 145 + //saturation 0 to 100 + //brightness 80 to 100 + stroke(random(20, 145), random(100), random(80, 100)); + } + + //listen for only character keys + function keyTyped() { + //weights 0 to 5 + stroke("turquoise"); + strokeWeight(random(5)); + } \ No newline at end of file diff --git a/dist/assets/examples/es/10_Interaction/20_Follow1.js b/dist/assets/examples/es/10_Interaction/20_Follow1.js new file mode 100644 index 0000000000..e4197e4674 --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/20_Follow1.js @@ -0,0 +1,37 @@ +/* + * @name Seguir 1 + * @frame 710,400 + * @description Un segmento de línea es empujado y tirado por el cursor. + * Basado en código de Keith Peters. + */ +let x = 100, + y = 100, + angle1 = 0.0, + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + x = mouseX - cos(angle1) * segLength; + y = mouseY - sin(angle1) * segLength; + + segment(x, y, angle1); + ellipse(x, y, 20, 20); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/es/10_Interaction/21_Follow2.js b/dist/assets/examples/es/10_Interaction/21_Follow2.js new file mode 100644 index 0000000000..b68d484d3c --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/21_Follow2.js @@ -0,0 +1,39 @@ +/* + * @name Seguir 2 + * @frame 710,400 + * @description Un brazo de dos segmentos sigue la posición del cursor. El ángulo relativo + * entre los segmentos es calculado con la función atan2() y la posición es + * calculada con sin() y cos(). Basado en código de Keith Peters. + */ +let x = [0, 0], + y = [0, 0], + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + dragSegment(1, x[0], y[0]); +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/es/10_Interaction/22_Follow3.js b/dist/assets/examples/es/10_Interaction/22_Follow3.js new file mode 100644 index 0000000000..0c58475589 --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/22_Follow3.js @@ -0,0 +1,47 @@ +/* + * @name Seguir 3 + * @frame 710,400 + * @description Una línea segmentada sigue al ratón. El ángulo relativo de + * cada segmento al siguiente es calculado con la función atan2() y la posición + * del siguiente es calculado con sin() y cos(). Basado en código de Keith Peters. + */ +let x = [], + y = [], + segNum = 20, + segLength = 18; + +for (let i = 0; i < segNum; i++) { + x[i] = 0; + y[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(9); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/es/10_Interaction/23_snake.js b/dist/assets/examples/es/10_Interaction/23_snake.js new file mode 100644 index 0000000000..66d5f5d256 --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/23_snake.js @@ -0,0 +1,176 @@ +/* + * @name Juego de Serpiente + * @description El famoso juego de Serpiente! Después de hacer click en run/ejecutar, haz click en cualquier parte + * dentro del área negra, y controla la serpiente usando i,j,k,l. No dejes que + * la serpiente choque contra sí misma o la pared.
+ * Ejemplo creado por Prashant Gupta + */ + +// La serpiente se divide en pequeños segmentos, los que son dibujados y editados en cada ejecución de draw() +let numeroSegmentos = 10; +let direccion = 'derecha'; + +const xInicio = 0; //coordenada x de partida de la serpiente +const yInicio = 250; //coordenada y de partida de la serpiente +const diferencia = 10; + +let xCuerpo = []; +let yCuerpo = []; + +let xFruta = 0; +let yFruta = 0; +let elementoPuntaje; + +function setup() { + elementoPuntaje = createDiv('Puntaje = 0'); + elementoPuntaje.position(20, 20); + elementoPuntaje.id = 'puntaje'; + elementoPuntaje.style('color', 'white'); + + createCanvas(500, 500); + frameRate(15); + stroke(255); + strokeWeight(10); + actualizarCoordenadasFruta(); + + for (let i = 0; i < numeroSegmentos; i++) { + xCuerpo.push(xInicio + i * diferencia); + yCuerpo.push(yInicio); + } +} + +function draw() { + background(0); + for (let i = 0; i < numeroSegmentos - 1; i++) { + line(xCuerpo[i], yCuerpo[i], xCuerpo[i + 1], yCuerpo[i + 1]); + } + actualizarCoordenadasSerpiente(); + comprobarEstadoJuego(); + comprobarFruta(); +} + +/* + Los segmentos son actualizados en la dirección de la serpiente. + Todos los segmentos entre 0 y n-1 son copiados al rango 1 hasta n, por ejemplo, el segmento 0 recibe el valor del segmento 1, el segmento 1 recibe el +vallor del segmento 2, y así, esto resulta en el movimiento de la serpiente. + + El último segmento es añadido según la dirección de movimiento de la serpiente, + si está yendo hacia izquierda o derecha, la coordenada x del último segmento + es igual a sumar un valor predefinido como 'diferencia' al valor del penúltimo + segmento. Y si está yendo hacia arriba o abajo, la coordenada y es afectada. + } + +*/ +function actualizarCoordenadasSerpiente() { + for (let i = 0; i < numeroSegmentos - 1; i++) { + xCuerpo[i] = xCuerpo[i + 1]; + yCuerpo[i] = yCuerpo[i + 1]; + } + switch (direccion) { + case 'derecha': + xCuerpo[numeroSegmentos - 1] = xCuerpo[numeroSegmentos - 2] + diferencia; + yCuerpo[numeroSegmentos - 1] = yCuerpo[numeroSegmentos - 2]; + break; + case 'arriba': + xCuerpo[numeroSegmentos - 1] = xCuerpo[numeroSegmentos - 2]; + yCuerpo[numeroSegmentos - 1] = yCuerpo[numeroSegmentos - 2] - diferencia; + break; + case 'izquierda': + xCuerpo[numeroSegmentos - 1] = xCuerpo[numeroSegmentos - 2] - diferencia; + yCuerpo[numeroSegmentos - 1] = yCuerpo[numeroSegmentos - 2]; + break; + case 'abajo': + xCuerpo[numeroSegmentos - 1] = xCuerpo[numeroSegmentos - 2]; + yCuerpo[numeroSegmentos - 1] = yCuerpo[numeroSegmentos - 2] + diferencia; + break; + } +} + +/* + Siempre reviso la posición de la cabeza de la serpiente + xCuerpo[xCuerpo.length - 1] e yCuerpo[yCuerpo.length - 1] para revisar si toca + los bordes del juego o si la serpiente se estrelló contra sí misma. +*/ +function comprobarEstadoJuego() { + if ( + xCuerpo[xCuerpo.length - 1] > width || + xCuerpo[xCuerpo.length - 1] < 0 || + yCuerpo[yCuerpo.length - 1] > height || + yCuerpo[yCuerpo.length - 1] < 0 || + detectarColision() + ) { + noLoop(); + const puntajeValor = parseInt(elementoPuntaje.html().substring(8)); + elementoPuntaje.html('Juego finalizado! Tu puntaje fue: ' + puntajeValor); + } +} + +/* + Si la serpiente se estrella contra sí misma, esto significa que la coordenada + (x,y) tiene que ser igual a la de un segmento propio. +*/ +function detectarColision() { + const cabezaSerpienteX = xCuerpo[xCuerpo.length - 1]; + const cabezaSerpienteY = yCuerpo[yCuerpo.length - 1]; + for (let i = 0; i < xCuerpo.length - 1; i++) { + if (xCuerpo[i] === cabezaSerpienteX && yCuerpo[i] === cabezaSerpienteY) { + return true; + } + } +} + +/* + Cada vez que la serpiente consume una fruta, incremento el número de segmentos, + y simplemente inserto este segmento de cola nuevamente al principio del arreglo + (básicamente añado el último segmento a la cola, con lo que la alargo). +*/ +function comprobarFruta() { + point(xFruta, yFruta); + if ( + xCuerpo[xCuerpo.length - 1] === xFruta && + yCuerpo[yCuerpo.length - 1] === yFruta + ) { + const prevScore = parseInt(elementoPuntaje.html().substring(8)); + elementoPuntaje.html('Score = ' + (prevScore + 1)); + xCuerpo.unshift(xCuerpo[0]); + yCuerpo.unshift(yCuerpo[0]); + numeroSegmentos++; + actualizarCoordenadasFruta(); + } +} + +function actualizarCoordenadasFruta() { + /* + Hice matemática compleja porque quería que el punto estuviera + entre 100 y width-100, y que fuera aproximado al número divisible + por 10 más cercano, ya que muevo la serpiente en múltiplos de 10. + */ + + xFruta = floor(random(10, (width - 100) / 10)) * 10; + yFruta = floor(random(10, (height - 100) / 10)) * 10; +} + +function keyPressed() { + switch (keyCode) { + case 74: + if (direccion !== 'derecha') { + direccion = 'izquierda'; + } + break; + case 76: + if (direccion !== 'izquierda') { + direccion = 'derecha'; + } + break; + case 73: + if (direccion !== 'abajo') { + direccion = 'arriba'; + } + break; + case 75: + if (direccion !== 'arriba') { + direccion = 'abajo'; + } + break; + } +} diff --git a/dist/assets/examples/es/10_Interaction/24_Wavemaker.js b/dist/assets/examples/es/10_Interaction/24_Wavemaker.js new file mode 100644 index 0000000000..bee0fde1ae --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/24_Wavemaker.js @@ -0,0 +1,37 @@ +/* + * @name Wavemaker + * @description Este ejemplo ilustra cómo las olas (como las del mar) emergen + * a partir de partículas oscilando en su lugar. Mueve el ratón para dirigir la ola. + * Contribución por Aatish Bhatia, inspirada en Orbiters por Dave Whyte. + */ + +let t = 0; // variable de tiempo + +function setup() { + createCanvas(600, 600); + noStroke(); + fill(40, 200, 40); +} + +function draw() { + background(10, 10); // fondo translúcido (crea estelas) + + // grilla de elipses + for (let x = 0; x <= width; x = x + 30) { + for (let y = 0; y <= height; y = y + 30) { + // punto de partida de cada círculo depende de posición del ratón + const anguloX = map(mouseX, 0, width, -4 * PI, 4 * PI, true); + const anguloY = map(mouseY, 0, height, -4 * PI, 4 * PI, true); + // y también varía según la posición de la partícula + const angulo = anguloX * (x / width) + anguloY * (y / height); + + // cada partícula se mueve en forma circular + const myX = x + 20 * cos(2 * PI * t + angulo); + const myY = y + 20 * sin(2 * PI * t + angulo); + + ellipse(myX, myY, 10); // dibujar partícula + } + } + + t = t + 0.01; // actualizar tiempo +} diff --git a/dist/assets/examples/es/10_Interaction/25_reach1.js b/dist/assets/examples/es/10_Interaction/25_reach1.js new file mode 100644 index 0000000000..01475decdc --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/25_reach1.js @@ -0,0 +1,57 @@ +/* + * @name Alcanzar 1 + * @frame 710,400 + * @description El brazo sigue la posición del ratón mediante el cálculo de los + * ángulos con atan2(). Basado en código de Keith Peters. + */ +let segLength = 80, + x, + y, + x2, + y2; + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x = width / 2; + y = height / 2; + x2 = x; + y2 = y; +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + + tx = mouseX - cos(angle1) * segLength; + ty = mouseY - sin(angle1) * segLength; + dx = tx - x2; + dy = ty - y2; + angle2 = atan2(dy, dx); + x = x2 + cos(angle2) * segLength; + y = y2 + sin(angle2) * segLength; + + segment(x, y, angle1); + segment(x2, y2, angle2); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/es/10_Interaction/26_reach2.js b/dist/assets/examples/es/10_Interaction/26_reach2.js new file mode 100644 index 0000000000..c701af1bb8 --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/26_reach2.js @@ -0,0 +1,65 @@ +/* + * @name Alcanzar 2 + * @frame 710,400 + * @description El brazo sigue la posición del ratón mediante el cálculo de los + * ángulos con atan2(). Basado en código de Keith Peters. + */ +let numSegments = 10, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x[x.length - 1] = width / 2; // Definir base del eje x + y[x.length - 1] = height; // Definir base del eje y +} + +function draw() { + background(0); + + reachSegment(0, mouseX, mouseY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/es/10_Interaction/27_reach3.js b/dist/assets/examples/es/10_Interaction/27_reach3.js new file mode 100644 index 0000000000..c7f033cc41 --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/27_reach3.js @@ -0,0 +1,81 @@ +/* + * @name Alcanzar 3 + * @frame 710,400 + * @description El brazo sigue la posición de la pelota mediante el cálculo de los + * ángulos con atan2(). Basado en código de Keith Peters. + */ +let numSegments = 8, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY, + ballX = 50, + ballY = 50, + ballXDirection = 1, + ballYDirection = -1; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + noFill(); + + x[x.length - 1] = width / 2; // Definir base del eje x + y[x.length - 1] = height; // Definir base del eje y +} + +function draw() { + background(0); + + strokeWeight(20); + ballX = ballX + 1.0 * ballXDirection; + ballY = ballY + 0.8 * ballYDirection; + if (ballX > width - 25 || ballX < 25) { + ballXDirection *= -1; + } + if (ballY > height - 25 || ballY < 25) { + ballYDirection *= -1; + } + ellipse(ballX, ballY, 30, 30); + + reachSegment(0, ballX, ballY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/es/10_Interaction/28_ArduinoSensor.js b/dist/assets/examples/es/10_Interaction/28_ArduinoSensor.js new file mode 100644 index 0000000000..55e5b0c7b0 --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/28_ArduinoSensor.js @@ -0,0 +1,36 @@ +/* + * @name Datos de un sensor Arduino vía WebJack + * @description WebJack es una forma de leer datos de un Arduino (y otras fuentes) + * usando audio... básicamente convierte tu Arduino en un modem de audio. + * + * https://github.com/publiclab/webjack + * + * Importante: Las bibliotecas WebJack y p5-webjack deben ser agregadas a tu index.html de la siguiente manera: + *
<script src="https://webjack.io/dist/webjack.js"></script>
+ *
<script src="https://jywarren.github.io/p5-webjack/lib.js"></script>
+ * + * Ejemplo práctico: https://editor.p5js.org/jywarren/sketches/rkztwSt8M + * + * Audio de prueba https://www.youtube.com/watch?v=GtJW1Dlt3cg + * Carga este lienzo en un Arduino: + * https://create.arduino.cc/editor/jywarren/023158d8-be51-4c78-99ff-36c63126b554/preview + * Arduino emitirá el audio desde el pin 3 + tierra. Usa el micrófono o un cable de audio. + */ + +function setup() { + createCanvas(400, 400); + noStroke(); + fill('#ff00aa22'); + receiveSensorData(handleData); +} + +function handleData(data) { + + console.log(data); // emitir los valores a registrar + // data[0] es el primer valor, data[1] el segundo, etc. + + // Dibuja! Navega http://p5js.org/reference/ + background('#ddd'); + ellipse(100, 200, data[0]+10, data[0]+10); + +} diff --git a/dist/assets/examples/es/10_Interaction/29_kaleidoscope.js b/dist/assets/examples/es/10_Interaction/29_kaleidoscope.js new file mode 100644 index 0000000000..ff372e7aea --- /dev/null +++ b/dist/assets/examples/es/10_Interaction/29_kaleidoscope.js @@ -0,0 +1,73 @@ +/* + * @name Caleidoscopio + * @description Un caleidoscopio es un instrumento óptico con dos o más superficies reflectantes inclinadas entre sí en ángulo. Este ejemplo intenta replicar el comportamiento de un caleidoscopio. Establezca el número de reflexiones en la variable de simetría y comience a dibujar en la pantalla. Ajuste el tamaño del pincel con la ayuda del control deslizante. La pantalla clara como dice borra la pantalla. El botón Guardar descargará un archivo .jpg del arte que ha creado. + */ +// Simetría correspondiente al número de reflejos. +// Cambia el valor para obtener un número diferente de reflexiones +let symmetry = 6; + +let angle = 360 / symmetry; +let saveButton, clearButton, mouseButton, keyboardButton; +let slider; + +function setup() { + createCanvas(710, 710); + angleMode(DEGREES); + background(127); + + // Creando el botón para guardar para el archivo + saveButton = createButton('save'); + saveButton.mousePressed(saveFile); + + // Creando el botón para borrar la pantalla + clearButton = createButton('clear'); + clearButton.mousePressed(clearScreen); + + // Creando el botón para la pantalla completa + fullscreenButton = createButton('Full Screen'); + fullscreenButton.mousePressed(screenFull); + + // Configurando el deslizador para el grosor del pincel + brushSizeSlider = createButton('Brush Size Slider'); + sizeSlider = createSlider(1, 32, 4, 0.1); +} + +// Función para guardar el archivo +function saveFile() { + save('design.jpg'); +} + +// Función para limpiar la pantalla +function clearScreen() { + background(127); +} + +// Función para pantalla completa +function screenFull() { + let fs = fullscreen(); + fullscreen(!fs); +} + +function draw() { + translate(width / 2, height / 2); + + if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) { + let mx = mouseX - width / 2; + let my = mouseY - height / 2; + let pmx = pmouseX - width / 2; + let pmy = pmouseY - height / 2; + + if (mouseIsPressed) { + for (let i = 0; i < symmetry; i++) { + rotate(angle); + let sw = sizeSlider.value(); + strokeWeight(sw); + line(mx, my, pmx, pmy); + push(); + scale(1, -1); + line(mx, my, pmx, pmy); + pop(); + } + } + } +} diff --git a/dist/assets/examples/es/11_Objects/01_Objects.js b/dist/assets/examples/es/11_Objects/01_Objects.js new file mode 100644 index 0000000000..56812fc6b1 --- /dev/null +++ b/dist/assets/examples/es/11_Objects/01_Objects.js @@ -0,0 +1,39 @@ +/* + * @name Objetos + * @description Crea una clase Jitter, instancia un objeto, + * y lo mueve en la pantalla. Adaptado del libro "Getting Started with + * Processing" por Casey Reas y Ben Fry. + */ + +let bug; // declarar objeto + +function setup() { + createCanvas(710, 400); + // crear objeto + bug = new Jitter(); +} + +function draw() { + background(50, 89, 100); + bug.move(); + bug.display(); +} + +// clase Jitter +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/es/11_Objects/02_Multiple_Objects.js b/dist/assets/examples/es/11_Objects/02_Multiple_Objects.js new file mode 100644 index 0000000000..1f1f042973 --- /dev/null +++ b/dist/assets/examples/es/11_Objects/02_Multiple_Objects.js @@ -0,0 +1,44 @@ +/* + * @name Múltiples objetos + * @description Crea una clase Jitter, instancia múltiples objetos, y los mueve en la pantalla. + */ + +function setup() { + createCanvas(710, 400); + // crear objetos + bug1 = new Jitter(); + bug2 = new Jitter(); + bug3 = new Jitter(); + bug4 = new Jitter(); +} + +function draw() { + background(50, 89, 100); + bug1.move(); + bug1.display(); + bug2.move(); + bug2.display(); + bug3.move(); + bug3.display(); + bug4.move(); + bug4.display(); +} + +// clase Jitter +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/es/11_Objects/03_Objects_Array.js b/dist/assets/examples/es/11_Objects/03_Objects_Array.js new file mode 100644 index 0000000000..4a8ec9d6a6 --- /dev/null +++ b/dist/assets/examples/es/11_Objects/03_Objects_Array.js @@ -0,0 +1,41 @@ +/* + * @name Arreglo de objetos + * @description Crea una clase Jitter, instancia múltiples objetos, y los mueve en la pantalla. + */ + +let bugs = []; //arreglo de objetos Jitter + +function setup() { + createCanvas(710, 400); + // Crear objetos + for (let i = 0; i < 50; i++) { + bugs.push(new Jitter()); + } +} + +function draw() { + background(50, 89, 100); + for (let i = 0; i < bugs.length; i++) { + bugs[i].move(); + bugs[i].display(); + } +} + +// clase Jitter +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/es/11_Objects/03_Objects_Optional_Arguments.js b/dist/assets/examples/es/11_Objects/03_Objects_Optional_Arguments.js new file mode 100644 index 0000000000..a25a0842b2 --- /dev/null +++ b/dist/assets/examples/es/11_Objects/03_Objects_Optional_Arguments.js @@ -0,0 +1,65 @@ +/* + * @name Objetos 2 + * @description Puerto de un ejemplo por hbarragan. Mueve el cursor sobre la + * imagen para cambiar la velocidad y las posiciones de la geometría. La clase MRect + * define un grupo de líneas. + */ + +let r1, r2, r3, r4; + +function setup() { + createCanvas(710, 400); + fill(255, 204); + noStroke(); + r1 = new MRect(1, 134.0, 0.532, 0.1 * height, 10.0, 60.0); + r2 = new MRect(2, 44.0, 0.166, 0.3 * height, 5.0, 50.0); + r3 = new MRect(2, 58.0, 0.332, 0.4 * height, 10.0, 35.0); + r4 = new MRect(1, 120.0, 0.0498, 0.9 * height, 15.0, 60.0); +} + +function draw() { + background(0); + + r1.display(); + r2.display(); + r3.display(); + r4.display(); + + r1.move(mouseX - width / 2, mouseY + height * 0.1, 30); + r2.move((mouseX + width * 0.05) % width, mouseY + height * 0.025, 20); + r3.move(mouseX / 4, mouseY - height * 0.025, 40); + r4.move(mouseX - width / 2, height - mouseY, 50); +} + +class MRect { + constructor(iw, ixp, ih, iyp, id, it) { + this.w = iw; // ancho de una barra + this.xpos = ixp; // posición x del rectángulo + this.h = ih; // altura del rectángulo + this.ypos = iyp; // posición y del rectángulo + this.d = id; // distancia de una barra + this.t = it; // número de barras + } + + move(posX, posY, damping) { + let dif = this.ypos - posY; + if (abs(dif) > 1) { + this.ypos -= dif / damping; + } + dif = this.xpos - posX; + if (abs(dif) > 1) { + this.xpos -= dif / damping; + } + } + + display() { + for (let i = 0; i < this.t; i++) { + rect( + this.xpos + i * (this.d + this.w), + this.ypos, + this.w, + height * this.h + ); + } + } +} diff --git a/dist/assets/examples/es/11_Objects/04_Inheritance.js b/dist/assets/examples/es/11_Objects/04_Inheritance.js new file mode 100644 index 0000000000..b1a0af4203 --- /dev/null +++ b/dist/assets/examples/es/11_Objects/04_Inheritance.js @@ -0,0 +1,70 @@ +/* @name Herencia + * @description Una clase puede ser definida usando otra clase como base. + * En la terminología de la programación orientada a objetos, una clase + * puede heredar campos y métodos de otra. Un objeto que hereda + * de otro se llama subclase, y el objeto del que hereda se + * llama superclase. Una subclase extiende la superclase. + */ +let spots, arm; + +function setup() { + createCanvas(640, 360); + arm = new SpinArm(width/2, height/2, 0.01); + spots = new SpinSpots(width/2, height/2, -0.02, 90.0); +} + +function draw() { + background(204); + arm.update(); + arm.display(); + spots.update(); + spots.display(); +} + +class Spin { + constructor(x, y, s) { + this.x = x; + this.y = y; + this.speed = s; + this.angle = 0.0; + } + + update() { + this.angle += this.speed; + } +} + +class SpinArm extends Spin { + constructor(x, y, s) { + super(x, y, s) + } + + display() { + strokeWeight(1); + stroke(0); + push(); + translate(this.x, this.y); + this.angle += this.speed; + rotate(this.angle); + line(0, 0, 165, 0); + pop(); + } +} + +class SpinSpots extends Spin { + constructor(x, y, s, d) { + super(x, y, s) + this.dim = d; + } + + display() { + noStroke(); + push(); + translate(this.x, this.y); + this.angle += this.speed; + rotate(this.angle); + ellipse(-this.dim/2, 0, this.dim, this.dim); + ellipse(this.dim/2, 0, this.dim, this.dim); + pop(); + } +} \ No newline at end of file diff --git a/dist/assets/examples/es/11_Objects/05_Composite_Objects.js b/dist/assets/examples/es/11_Objects/05_Composite_Objects.js new file mode 100644 index 0000000000..dc794fb519 --- /dev/null +++ b/dist/assets/examples/es/11_Objects/05_Composite_Objects.js @@ -0,0 +1,99 @@ +/* @name Objetos Compuestos + * @description Un objeto puede incluir varios otros objetos. + * La creación de tales objetos compuestos es una buena manera de usar los principios + * de modularidad y construir niveles más altos de abstracción dentro de un programa. + */ +let er1, er2; + +function setup() { + createCanvas(640, 360); + er1 = new EggRing(width*0.45, height*0.5, 0.1, 120); + er2 = new EggRing(width*0.65, height*0.8, 0.05, 180); +} + +function draw() { + background(0); + er1.transmit(); + er2.transmit(); +} + +class Egg { + constructor(xpos, ypos, t, s) { + this.x = xpos; + this.y = ypos; + this.tilt = t; + this.scalar = s / 100.0; + this.angle = 0.0; + } + + wobble() { + this.tilt = cos(this.angle) / 8; + this.angle += 0.1; + } + + display() { + noStroke(); + fill(255); + push(); + translate(this.x, this.y); + rotate(this.tilt); + scale(this.scalar); + beginShape(); + vertex(0, -100); + bezierVertex(25, -100, 40, -65, 40, -40); + bezierVertex(40, -15, 25, 0, 0, 0); + bezierVertex(-25, 0, -40, -15, -40, -40); + bezierVertex(-40, -65, -25, -100, 0, -100); + endShape(); + pop(); + } +} + +class Ring { + start(xpos, ypos) { + this.x = xpos; + this.y = ypos; + this.on = true; + this.diameter = 1; + } + + grow() { + if (this.on == true) { + this.diameter += 0.5; + if (this.diameter > width*2) { + this.diameter = 0.0; + } + } + } + + display() { + if (this.on == true) { + noFill(); + strokeWeight(4); + stroke(155, 153); + ellipse(this.x, this.y, this.diameter, this.diameter); + } + } +} + +class EggRing { + constructor(x, y, t, sp) { + this.x = x; + this.y = y; + this.t = t; + this.sp = sp; + this.circle = new Ring(); + this.ovoid = new Egg(this.x, this.y, this.t, this.sp); + this.circle.start(this.x, this.y - this.sp/2); + } + + transmit() { + this.ovoid.wobble(); + this.ovoid.display(); + this.circle.grow(); + this.circle.display(); + if (this.circle.on == false) { + this.circle.on = true; + } + } +} diff --git a/dist/assets/examples/es/11_Objects/06_Car_Instances.js b/dist/assets/examples/es/11_Objects/06_Car_Instances.js new file mode 100644 index 0000000000..1966f9c8e3 --- /dev/null +++ b/dist/assets/examples/es/11_Objects/06_Car_Instances.js @@ -0,0 +1,82 @@ +/* + * @name Car Instances + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to create three instances of Car Class and +invoke class methods.
+ A function is created for the canvas setup, and +3 car instances are initialized with different colors and canvas +positions. The speed of each car is set by passing value to the +instance’s start method. A second function calls class methods to +display and move the cars. +*/ +class Car { + /* Constructor expects parameters for + fill color, x and y coordinates that + will be used to initialize class properties. + */ + constructor(cColor, x, y) { + this.color = cColor; + this.doors = 4; + this.isConvertible = false; + this.x = x; + this.y = y; + this.speed = 0; + } + + start(speed) { // method expects parameter! + this.speed = speed; + } + + display() { // method! + fill(this.color); + rect(this.x, this.y, 20, 10); + } + + move() { // method! + this.x += this.speed; + // Wrap x around boundaries + if (this.x < -20) { + this.x = width; + } else if (this.x > width) { + this.x = -20; + } + } +} //end class Car + +let rav4; +let charger; +let nova; + +function setup() { + createCanvas(200, 400); + /* Construct the 3 Cars */ + //constructor expects cColor, x, y + rav4 = new Car("silver", 100, 300); + charger = new Car("gold", 0, 200); + nova = new Car("blue", 200, 100); + nova.doors = 2; //update nova's doors property + + console.log("rav4", rav4); + console.log("charger", charger); + console.log("nova", nova); + + //call start methods of Car instances + //the start method expects a number for speed + rav4.start(2.3); + charger.start(-4); + nova.start(random(-1, 1)); +} + +function draw() { + background("beige"); + + //display and move all 3 Cars + rav4.display(); + charger.display(); + nova.display(); + + rav4.move(); + charger.move(); + nova.move(); +} diff --git a/dist/assets/examples/es/12_Lights/02_Directional.js b/dist/assets/examples/es/12_Lights/02_Directional.js new file mode 100644 index 0000000000..228a87f06d --- /dev/null +++ b/dist/assets/examples/es/12_Lights/02_Directional.js @@ -0,0 +1,27 @@ +/* + * @name Direccional + * @frame 710,400 + * @description Mueve el ratón para cambiar la dirección de la luz. + * La luz direccional proviene de una dirección y es de mayor intensidad cuando incide sobre + * una superficie perpendicularmente y más suave sobre un ángulo menor. Después de incidir sobre la + * superficie, una luz direccional se dispersa en todas direcciones. + */ +const radius = 200; + +function setup() { + createCanvas(710, 400, WEBGL); + noStroke(); + fill(200); +} + +function draw() { + noStroke(); + background(0); + const dirY = (mouseY / height - 0.5) * 4; + const dirX = (mouseX / width - 0.5) * 4; + directionalLight(204, 204, 204, dirX, dirY, 1); + translate(-1.5 * radius, 0, 0); + sphere(radius); + translate(3 * radius, 0, 0); + sphere(radius); +} diff --git a/dist/assets/examples/es/12_Lights/05_Mixture.js b/dist/assets/examples/es/12_Lights/05_Mixture.js new file mode 100644 index 0000000000..4f6c794f2a --- /dev/null +++ b/dist/assets/examples/es/12_Lights/05_Mixture.js @@ -0,0 +1,44 @@ +/* + * @name Mezcla + * @frame 710,400 (optional) + * @description Muestra una caja con tres tipos diferentes de luces. + */ +function setup() { + createCanvas(710, 400, WEBGL); + noStroke(); +} + +function draw() { + background(0); + + // ambient light + ambientLight(0, 255/4, 0); + + // to set the light position, + // think of the world's coordinate as: + // -width/2,-height/2 -------- width/2,-height/2 + // | | + // | 0,0 | + // | | + // -width/2,height/2--------width/2,height/2 + + // blue directional light from the left + directionalLight(0, 0, 255, -1, 0, 0); + + // calculate distance from center to mouseX + let lightX = mouseX - width / 2; + let lightY = mouseY - height / 2; + + // red spotlight + // axis located at lightX, lightY, 500 + // axis direction of light: 0, 0, -1 + spotLight(255, 0, 0, lightX, lightY, 500, 0, 0, -1); + + // rotate on X axis + rotateX(-PI/4); + // rotate on Y axis + rotateY(PI/4); + + // place box on (0, 0, 0), size 100 + box(100); +} diff --git a/dist/assets/examples/es/13_Motion/01_non_orthogonal_reflection.js b/dist/assets/examples/es/13_Motion/01_non_orthogonal_reflection.js new file mode 100644 index 0000000000..453bd272f1 --- /dev/null +++ b/dist/assets/examples/es/13_Motion/01_non_orthogonal_reflection.js @@ -0,0 +1,110 @@ +/* + * @name Reflejo no ortogonal + * @frame 710,400 (optional) + * @description Este es un puerto de David Blitz del ejemplo "Reflection 1" en processing.org/examples + */ + +//Posición del lado izquierdo del suelo +let base1; + +//Posición del lado derecho del suelo +let base2; +//La longitud del suelo +//let baseLength; + +// Variables relacionadas con el movimiento de la bola +let position; +let velocity; +let r = 6; +let speed = 3.5; + +function setup() { + createCanvas(710, 400); + + fill(128); + base1 = createVector(0, height - 150); + base2 = createVector(width, height); + //createGround(); + + //Empezar la elipse en el centro de la parte superior de la pantalla + position = createVector(width / 2, 0); + + //Calcular la velocidad aleatoria inicial + velocity = p5.Vector.random2D(); + velocity.mult(speed); +} + +function draw() { + //dibujar el fondo + fill(0, 12); + noStroke(); + rect(0, 0, width, height); + + //dibujar la base + fill(200); + quad(base1.x, base1.y, base2.x, base2.y, base2.x, height, 0, height); + + //calcular la normal a la base superior + let baseDelta = p5.Vector.sub(base2, base1); + baseDelta.normalize(); + let normal = createVector(-baseDelta.y, baseDelta.x); + let intercept = p5.Vector.dot(base1, normal); + + //dibujar elipse + noStroke(); + fill(255); + ellipse(position.x, position.y, r * 2, r * 2); + + //mover elipse + position.add(velocity); + + //vector de incidencia normalizado + incidence = p5.Vector.mult(velocity, -1); + incidence.normalize(); + + // detectar y gestionar la colisión con la base + if (p5.Vector.dot(normal, position) > intercept) { + //calcular el producto escalar del vector incidente y la parte superior de la base + let dot = incidence.dot(normal); + + //calcular el vector del reflejo + //asignar el vector de reflejo al vector de dirección + velocity.set( + 2 * normal.x * dot - incidence.x, + 2 * normal.y * dot - incidence.y, + 0 + ); + velocity.mult(speed); + + // dibujar la base superior normal en el punto de colisión + stroke(255, 128, 0); + line( + position.x, + position.y, + position.x - normal.x * 100, + position.y - normal.y * 100 + ); + } + //} + + // detectar la colisión límite + // derecha + if (position.x > width - r) { + position.x = width - r; + velocity.x *= -1; + } + // izquierda + if (position.x < r) { + position.x = r; + velocity.x *= -1; + } + // arriba + if (position.y < r) { + position.y = r; + velocity.y *= -1; + + //aleatorizar la parte superior de la base + base1.y = random(height - 100, height); + base2.y = random(height - 100, height); + } +} diff --git a/dist/assets/examples/es/13_Motion/02_Linear_Motion.js b/dist/assets/examples/es/13_Motion/02_Linear_Motion.js new file mode 100644 index 0000000000..8ba05fdc00 --- /dev/null +++ b/dist/assets/examples/es/13_Motion/02_Linear_Motion.js @@ -0,0 +1,24 @@ +/* + * @name Lineal + * @frame 720,400 + * @description Cambiar una variable para crear una línea en movimiento. + * Cuando la línea se mueve fuera del borde de la ventana, + * la variable se pone a 0, lo que coloca la línea de nuevo en la parte inferior de la pantalla. + */ + +let a; + +function setup() { + createCanvas(720, 400); + stroke(255); + a = height / 2; +} + +function draw() { + background(51); + line(0, a, width, a); + a = a - 0.5; + if (a < 0) { + a = height; + } +} diff --git a/dist/assets/examples/es/13_Motion/03_Bounce.js b/dist/assets/examples/es/13_Motion/03_Bounce.js new file mode 100644 index 0000000000..363084c6ad --- /dev/null +++ b/dist/assets/examples/es/13_Motion/03_Bounce.js @@ -0,0 +1,44 @@ +/* + * @name Rebote + * @frame 720,400 + * @description Cuando la forma golpea el borde de la ventana, invierte su dirección. + */ + +let rad = 60; // El ancho de la forma +let xpos, ypos; // Posición inicial de la forma + +let xspeed = 2.8; // La velocidad de la forma +let yspeed = 2.2; // La velocidad de la forma + +let xdirection = 1; // Izquierda o derecha +let ydirection = 1; // De arriba a abajo + +function setup() { + createCanvas(720, 400); + noStroke(); + frameRate(30); + ellipseMode(RADIUS); + // Establecer la posición de partida de la forma + xpos = width / 2; + ypos = height / 2; +} + +function draw() { + background(102); + + // Actualizar la posición de la forma + xpos = xpos + xspeed * xdirection; + ypos = ypos + yspeed * ydirection; + + // Prueba para ver si la forma excede los límites de la pantalla + // Si lo hace, invierta su dirección multiplicando por -1 + if (xpos > width - rad || xpos < rad) { + xdirection *= -1; + } + if (ypos > height - rad || ypos < rad) { + ydirection *= -1; + } + + // Dibuja la forma + ellipse(xpos, ypos, rad, rad); +} diff --git a/dist/assets/examples/es/13_Motion/04_Bouncy_Bubbles.js b/dist/assets/examples/es/13_Motion/04_Bouncy_Bubbles.js new file mode 100644 index 0000000000..febbe5ace3 --- /dev/null +++ b/dist/assets/examples/es/13_Motion/04_Bouncy_Bubbles.js @@ -0,0 +1,95 @@ +/* + * @name Burbujas Saltarinas + * @frame 720,400 + * @description basado en el código de Keith Peters. Colisión de múltiples objetos... + */ + +let numBalls = 13; +let spring = 0.05; +let gravity = 0.03; +let friction = -0.9; +let balls = []; + +function setup() { + createCanvas(720, 400); + for (let i = 0; i < numBalls; i++) { + balls[i] = new Ball( + random(width), + random(height), + random(30, 70), + i, + balls + ); + } + noStroke(); + fill(255, 204); +} + +function draw() { + background(0); + balls.forEach(ball => { + ball.collide(); + ball.move(); + ball.display(); + }); +} + +class Ball { + constructor(xin, yin, din, idin, oin) { + this.x = xin; + this.y = yin; + this.vx = 0; + this.vy = 0; + this.diameter = din; + this.id = idin; + this.others = oin; + } + + collide() { + for (let i = this.id + 1; i < numBalls; i++) { + // console.log(others[i]); + let dx = this.others[i].x - this.x; + let dy = this.others[i].y - this.y; + let distance = sqrt(dx * dx + dy * dy); + let minDist = this.others[i].diameter / 2 + this.diameter / 2; + // console.log(distance); + //console.log(minDist); + if (distance < minDist) { + //console.log("2"); + let angle = atan2(dy, dx); + let targetX = this.x + cos(angle) * minDist; + let targetY = this.y + sin(angle) * minDist; + let ax = (targetX - this.others[i].x) * spring; + let ay = (targetY - this.others[i].y) * spring; + this.vx -= ax; + this.vy -= ay; + this.others[i].vx += ax; + this.others[i].vy += ay; + } + } + } + + move() { + this.vy += gravity; + this.x += this.vx; + this.y += this.vy; + if (this.x + this.diameter / 2 > width) { + this.x = width - this.diameter / 2; + this.vx *= friction; + } else if (this.x - this.diameter / 2 < 0) { + this.x = this.diameter / 2; + this.vx *= friction; + } + if (this.y + this.diameter / 2 > height) { + this.y = height - this.diameter / 2; + this.vy *= friction; + } else if (this.y - this.diameter / 2 < 0) { + this.y = this.diameter / 2; + this.vy *= friction; + } + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/es/13_Motion/05_Morph.js b/dist/assets/examples/es/13_Motion/05_Morph.js new file mode 100644 index 0000000000..8830647539 --- /dev/null +++ b/dist/assets/examples/es/13_Motion/05_Morph.js @@ -0,0 +1,93 @@ +/* + * @name Transformar + * @frame 720,400 + * @description Cambiar una forma por otra interpolando vértices de uno a otro. + */ + +// Dos ArrayList para almacenar los vértices de dos geometrías +// Este ejemplo asume que cada forma tendrá el mismo número de vértices +// es decir, el tamaño de cada ArrayList será el mismo +let circle = []; +let square = []; + +// Un ArrayList para un tercer conjunto de vértices, los que dibujaremos +// en la ventana +let morph = []; + +// Esta variable booleana controlará si estamos transformando en un círculo o un cuadrado +let state = false; + +function setup() { + createCanvas(720, 400); + + // Crear un círculo usando vectores que apunten desde el centro + for (let angle = 0; angle < 360; angle += 9) { + // Ten en cuenta que no estamos empezando desde 0 para que coincida con + // la trayectoria de un círculo. + let v = p5.Vector.fromAngle(radians(angle - 135)); + v.mult(100); + circle.push(v); + // Llenemos el ArrayList de transformación con PVectores en blanco mientras estamos en ello. + morph.push(createVector()); + } + + // Un cuadrado es un montón de vértices a lo largo de líneas rectas + // La parte superior del cuadrado + for (let x = -50; x < 50; x += 10) { + square.push(createVector(x, -50)); + } + // Lado derecho + for (let y = -50; y < 50; y += 10) { + square.push(createVector(50, y)); + } + // Parte inferior + for (let x = 50; x > -50; x -= 10) { + square.push(createVector(x, 50)); + } + // Lado izquierdo + for (let y = 50; y > -50; y -= 10) { + square.push(createVector(-50, y)); + } +} + +function draw() { + background(51); + + // Guardaremos la distancia de los vértices de su objetivo + let totalDistance = 0; + + // Mira cada vértice + for (let i = 0; i < circle.length; i++) { + let v1; + // ¿Estamos yendo hacia el círculo o hacia el cuadrado? + if (state) { + v1 = circle[i]; + } else { + v1 = square[i]; + } + // Consigue el vértice que dibujaremos + let v2 = morph[i]; + // Transiciona hacia el objetivo... + v2.lerp(v1, 0.1); + // Comprueba lo lejos que estamos del objetivo + totalDistance += p5.Vector.dist(v1, v2); + } + + // Si todos los vértices están cerca, cambia de forma + if (totalDistance < 0.1) { + state = !state; + } + + // Dibuja relativo al centro + translate(width / 2, height / 2); + strokeWeight(4); + // Dibuja un polígono compuesto de todos los vértices + beginShape(); + noFill(); + stroke(255); + + morph.forEach(v => { + vertex(v.x, v.y); + }); + endShape(CLOSE); +} diff --git a/dist/assets/examples/es/13_Motion/06_Moving_On_Curves.js b/dist/assets/examples/es/13_Motion/06_Moving_On_Curves.js new file mode 100644 index 0000000000..67e9fff123 --- /dev/null +++ b/dist/assets/examples/es/13_Motion/06_Moving_On_Curves.js @@ -0,0 +1,47 @@ +/* + * @name Moviéndose por Curvas + * @frame 720,400 + * @description En este ejemplo, los círculos se mueven a lo largo de la curva y = x^4. + * Haz clic con el ratón para que se mueva a una nueva posición. + */ + +let beginX = 20.0; // Coordenada X inicial +let beginY = 10.0; // Coordenada Y inicial +let endX = 570.0; // Coordenada X final +let endY = 320.0; // Coordenada Y final +let distX; // Distancia a moverse en el eje X +let distY; // Distancia a moverse en el eje Y +let exponent = 4; // Determina la curva +let x = 0.0; // Coordenada X actual +let y = 0.0; // Coordenada Y actual +let step = 0.01; // Tamaño de cada paso a lo largo del camino +let pct = 0.0; // Porcentaje viajado (0.0 a 1.0) + +function setup() { + createCanvas(720, 400); + noStroke(); + distX = endX - beginX; + distY = endY - beginY; +} + +function draw() { + fill(0, 2); + rect(0, 0, width, height); + pct += step; + if (pct < 1.0) { + x = beginX + pct * distX; + y = beginY + pow(pct, exponent) * distY; + } + fill(255); + ellipse(x, y, 20, 20); +} + +function mousePressed() { + pct = 0.0; + beginX = x; + beginY = y; + endX = mouseX; + endY = mouseY; + distX = endX - beginX; + distY = endY - beginY; +} diff --git a/dist/assets/examples/es/13_Motion/07_Circle_Collision.js b/dist/assets/examples/es/13_Motion/07_Circle_Collision.js new file mode 100644 index 0000000000..876bc23d6e --- /dev/null +++ b/dist/assets/examples/es/13_Motion/07_Circle_Collision.js @@ -0,0 +1,145 @@ +/* + * @name Circle Collision + * @frame 710,400 (optional) + * @description This is a port of the "Circle Collision" example from processing.org/examples
This example uses vectors for better visualization of physical Quantity + */ +class Ball { + constructor(x, y, r) { + this.position = new p5.Vector(x, y); + this.velocity = p5.Vector.random2D(); + this.velocity.mult(3); + this.r = r; + this.m = r * 0.1; + } + update() { + this.position.add(this.velocity); + } + + checkBoundaryCollision() { + if (this.position.x > width - this.r) { + this.position.x = width - this.r; + this.velocity.x *= -1; + } else if (this.position.x < this.r) { + this.position.x = this.r; + this.velocity.x *= -1; + } else if (this.position.y > height - this.r) { + this.position.y = height - this.r; + this.velocity.y *= -1; + } else if (this.position.y < this.r) { + this.position.y = this.r; + this.velocity.y *= -1; + } + } + + checkCollision(other) { + // Get distances between the balls components + let distanceVect = p5.Vector.sub(other.position, this.position); + + // Calculate magnitude of the vector separating the balls + let distanceVectMag = distanceVect.mag(); + + // Minimum distance before they are touching + let minDistance = this.r + other.r; + + if (distanceVectMag < minDistance) { + let distanceCorrection = (minDistance - distanceVectMag) / 2.0; + let d = distanceVect.copy(); + let correctionVector = d.normalize().mult(distanceCorrection); + other.position.add(correctionVector); + this.position.sub(correctionVector); + + // get angle of distanceVect + let theta = distanceVect.heading(); + // precalculate trig values + let sine = sin(theta); + let cosine = cos(theta); + + /* bTemp will hold rotated ball this.positions. You + just need to worry about bTemp[1] this.position*/ + let bTemp = [new p5.Vector(), new p5.Vector()]; + + /* this ball's this.position is relative to the other + so you can use the vector between them (bVect) as the + reference point in the rotation expressions. + bTemp[0].this.position.x and bTemp[0].this.position.y will initialize + automatically to 0.0, which is what you want + since b[1] will rotate around b[0] */ + bTemp[1].x = cosine * distanceVect.x + sine * distanceVect.y; + bTemp[1].y = cosine * distanceVect.y - sine * distanceVect.x; + + // rotate Temporary velocities + let vTemp = [new p5.Vector(), new p5.Vector()]; + + vTemp[0].x = cosine * this.velocity.x + sine * this.velocity.y; + vTemp[0].y = cosine * this.velocity.y - sine * this.velocity.x; + vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y; + vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x; + + /* Now that velocities are rotated, you can use 1D + conservation of momentum equations to calculate + the final this.velocity along the x-axis. */ + let vFinal = [new p5.Vector(), new p5.Vector()]; + + // final rotated this.velocity for b[0] + vFinal[0].x = + ((this.m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / + (this.m + other.m); + vFinal[0].y = vTemp[0].y; + + // final rotated this.velocity for b[0] + vFinal[1].x = + ((other.m - this.m) * vTemp[1].x + 2 * this.m * vTemp[0].x) / + (this.m + other.m); + vFinal[1].y = vTemp[1].y; + + // hack to avoid clumping + bTemp[0].x += vFinal[0].x; + bTemp[1].x += vFinal[1].x; + + /* Rotate ball this.positions and velocities back + Reverse signs in trig expressions to rotate + in the opposite direction */ + // rotate balls + let bFinal = [new p5.Vector(), new p5.Vector()]; + + bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y; + bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x; + bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y; + bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x; + + // update balls to screen this.position + other.position.x = this.position.x + bFinal[1].x; + other.position.y = this.position.y + bFinal[1].y; + + this.position.add(bFinal[0]); + + // update velocities + this.velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y; + this.velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x; + other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y; + other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x; + } + } + + display() { + noStroke(); + fill(204); + ellipse(this.position.x, this.position.y, this.r * 2, this.r * 2); + } +} +let balls = [new Ball(100, 400, 20), new Ball(700, 400, 80)]; +console.log(balls); +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(51); + for (let i = 0; i < balls.length; i++) { + let b = balls[i]; + b.update(); + b.display(); + b.checkBoundaryCollision(); + balls[0].checkCollision(balls[1]); + } +} diff --git a/dist/assets/examples/es/13_Motion/08_Moving_On_Curves.js b/dist/assets/examples/es/13_Motion/08_Moving_On_Curves.js new file mode 100644 index 0000000000..4c347c7e00 --- /dev/null +++ b/dist/assets/examples/es/13_Motion/08_Moving_On_Curves.js @@ -0,0 +1,47 @@ +/* + * @name Moving On Curves + * @frame 720,400 + * @description In this example, the circles moves along the curve y = x^4. + * Click the mouse to have it move to a new position. + */ + +let beginX = 20.0; // Initial x-coordinate +let beginY = 10.0; // Initial y-coordinate +let endX = 570.0; // Final x-coordinate +let endY = 320.0; // Final y-coordinate +let distX; // X-axis distance to move +let distY; // Y-axis distance to move +let exponent = 4; // Determines the curve +let x = 0.0; // Current x-coordinate +let y = 0.0; // Current y-coordinate +let step = 0.01; // Size of each step along the path +let pct = 0.0; // Percentage traveled (0.0 to 1.0) + +function setup() { + createCanvas(720, 400); + noStroke(); + distX = endX - beginX; + distY = endY - beginY; +} + +function draw() { + fill(0, 2); + rect(0, 0, width, height); + pct += step; + if (pct < 1.0) { + x = beginX + pct * distX; + y = beginY + pow(pct, exponent) * distY; + } + fill(255); + ellipse(x, y, 20, 20); +} + +function mousePressed() { + pct = 0.0; + beginX = x; + beginY = y; + endX = mouseX; + endY = mouseY; + distX = endX - beginX; + distY = endY - beginY; +} diff --git a/dist/assets/examples/es/15_Instance_Mode/01_Instantiating.js b/dist/assets/examples/es/15_Instance_Mode/01_Instantiating.js new file mode 100644 index 0000000000..6d0b837984 --- /dev/null +++ b/dist/assets/examples/es/15_Instance_Mode/01_Instantiating.js @@ -0,0 +1,35 @@ +/* + * @name Instaciación + * @description Crear una instancia de p5, que mantiene todas las variables + * fuera del scope global de tu página. + */ +let sketch = function(p) { + let x = 100; + let y = 100; + + p.setup = function() { + p.createCanvas(700, 410); + }; + + p.draw = function() { + p.background(0); + p.fill(255); + p.rect(x, y, 50, 50); + }; +}; + +let myp5 = new p5(sketch); + +// Compara con el "modo global" +// let x = 100; +// let y = 100; + +// function setup() { +// createCanvas(200,200); +// } + +// function draw() { +// background(0); +// fill(255); +// ellipse(x,y,50,50); +// } diff --git a/dist/assets/examples/es/15_Instance_Mode/02_Instance_Container.js b/dist/assets/examples/es/15_Instance_Mode/02_Instance_Container.js new file mode 100644 index 0000000000..e30f50fab1 --- /dev/null +++ b/dist/assets/examples/es/15_Instance_Mode/02_Instance_Container.js @@ -0,0 +1,92 @@ +/* + * @norender + * @name Contenedor de instancia + * @description Opcionalmente, puedes especificar un contenedor por defecto para el lienzo + * y otros elementos que anexes con un segundo argumento. Puedes darle la ID + * de un elemento en tu código html, o incluso un nodo html. + * + * Aquí hay tres opciones diferentes Para seleccionar un elemento contenedor de DOM. + * Todos los elementos DOM (lienzos, botones, divisiones, etc) creados por p5 + * serán adjuntados al elemento DOM especificado como el segundo argumento de la llamada a la función p5(). + */ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dist/assets/examples/es/16_Dom/03_Input_Button.js b/dist/assets/examples/es/16_Dom/03_Input_Button.js new file mode 100644 index 0000000000..28751d883e --- /dev/null +++ b/dist/assets/examples/es/16_Dom/03_Input_Button.js @@ -0,0 +1,38 @@ +/* + * @name Entrada y botón + * @description Ingresa texto y haz click en el botón para ver cómo afecta al lienzo + */ +let input, button, greeting; + +function setup() { + // crear un lienzo + createCanvas(710, 400); + + input = createInput(); + input.position(20, 65); + + button = createButton('submit'); + button.position(150, 65); + button.mousePressed(greet); + + greeting = createElement('h2', 'what is your name?'); + greeting.position(20, 5); + + textAlign(CENTER); + textSize(50); +} + +function greet() { + const name = input.value(); + greeting.html('hello ' + name + '!'); + input.value(''); + + for (let i = 0; i < 200; i++) { + push(); + fill(random(255), 255, 255); + translate(random(width), random(height)); + rotate(random(2 * PI)); + text(name, 0, 0); + pop(); + } +} diff --git a/dist/assets/examples/es/16_Dom/04_Slider.js b/dist/assets/examples/es/16_Dom/04_Slider.js new file mode 100644 index 0000000000..041fedfb73 --- /dev/null +++ b/dist/assets/examples/es/16_Dom/04_Slider.js @@ -0,0 +1,30 @@ +/* + * @name Barra deslizante + * @description Mueve las barras deslizantes para controlar los valores de color RGB del fondo. + */ +let rSlider, gSlider, bSlider; + +function setup() { + // crear lienzo + createCanvas(710, 400); + textSize(15); + noStroke(); + + // crear barras deslizantes + rSlider = createSlider(0, 255, 100); + rSlider.position(20, 20); + gSlider = createSlider(0, 255, 0); + gSlider.position(20, 50); + bSlider = createSlider(0, 255, 255); + bSlider.position(20, 80); +} + +function draw() { + const r = rSlider.value(); + const g = gSlider.value(); + const b = bSlider.value(); + background(r, g, b); + text('red', 165, 35); + text('green', 165, 65); + text('blue', 165, 95); +} diff --git a/dist/assets/examples/es/16_Dom/07_Modify_DOM.js b/dist/assets/examples/es/16_Dom/07_Modify_DOM.js new file mode 100644 index 0000000000..f4728582a9 --- /dev/null +++ b/dist/assets/examples/es/16_Dom/07_Modify_DOM.js @@ -0,0 +1,51 @@ +/* + * @name Modificar el DOM + * @frame 710,300 + * @description Crea elementos DOM y modifica sus propiedades cada vez que draw() es llamado + */ +let dancingWords = []; + +class DanceSpan { + constructor(element, x, y) { + element.position(x, y); + this.element = element; + this.x = x; + this.y = y; + } + + brownian() { + this.x += random(-6, 6); + this.y += random(-6, 6); + this.element.position(this.x, this.y); + } +} + +function setup() { + // Este párrafo es creado aparte del bloque principal de código. + // Es para diferenciar entre la creación de un elemento y su selección. + // Los elementos seleccionados no necesitan ser creados por p5js, pueden ser HTML plano. + createP( + 'I learn in this Letter, that Don Peter of Arragon, ' + + ' comes this night to Messina' + ).addClass('text').hide(); + + // Esta línea toma el párrafo recién creado, pero podría también + // tomar otros elementos de la clase 'text' en la página HTML. + const texts = selectAll('.text'); + + for (let i = 0; i < texts.length; i++) { + const paragraph = texts[i].html(); + const words = paragraph.split(' '); + for (let j = 0; j < words.length; j++) { + const spannedWord = createSpan(words[j]); + const dw = new DanceSpan(spannedWord, random(600), random(200)); + dancingWords.push(dw); + } + } +} + +function draw() { + for (let i = 0; i < dancingWords.length; i++) { + dancingWords[i].brownian(); + } +} diff --git a/dist/assets/examples/es/16_Dom/08_Video.js b/dist/assets/examples/es/16_Dom/08_Video.js new file mode 100644 index 0000000000..155de71b40 --- /dev/null +++ b/dist/assets/examples/es/16_Dom/08_Video.js @@ -0,0 +1,28 @@ +/* + * @name Video + * @frame 710,250 + * @description Carga un video con múltiples formatos y alterna entre reproducir y pausar al presionar un botón. + */ +let playing = false; +let fingers; +let button; + +function setup() { + noCanvas(); + // especificar múltiples formatos para distintos navegadores + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + button = createButton('play'); + button.mousePressed(toggleVid); // adjuntar un listener al botón +} + +// reproduce o pausa el video dependiendo de su estado actual +function toggleVid() { + if (playing) { + fingers.pause(); + button.html('play'); + } else { + fingers.loop(); + button.html('pause'); + } + playing = !playing; +} diff --git a/dist/assets/examples/es/16_Dom/09_Video_Canvas.js b/dist/assets/examples/es/16_Dom/09_Video_Canvas.js new file mode 100644 index 0000000000..684d8dfcd6 --- /dev/null +++ b/dist/assets/examples/es/16_Dom/09_Video_Canvas.js @@ -0,0 +1,26 @@ +/* + * @name Lienzo y video + * @description Cargar un video en múltiples formatos y dibújalo en el lienzo. + * Para correr este ejemplo localmente, necesitarás correr un + * servidor local. + */ +let fingers; + +function setup() { + createCanvas(710, 400); + // especificar múltiples formatos para diferentes navegadores + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.hide(); // por defecto el video aparece en un elemento dom separado. + // escóndelo y dibújalo en el lienzo en vez de eso. +} + +function draw() { + background(150); + image(fingers, 10, 10); // dibuja el cuadro del video en el lienzo. + filter(GRAY); + image(fingers, 150, 150); // dibuja una segunda copia en el lienzo. +} + +function mousePressed() { + fingers.loop(); // configurar el video para empezar a reproducirse en bucle +} diff --git a/dist/assets/examples/es/16_Dom/10_Video_Pixels.js b/dist/assets/examples/es/16_Dom/10_Video_Pixels.js new file mode 100644 index 0000000000..f722ee9ef4 --- /dev/null +++ b/dist/assets/examples/es/16_Dom/10_Video_Pixels.js @@ -0,0 +1,32 @@ +/* + * @name Pixeles de video + * @frame 320,240 + * @description Cargar un video, manipula sus pixeles y dibújalo en el lienzo. + * Para correr este ejemplo localmente, necesitarás correr un + * servidor local. + */ +let fingers; + +function setup() { + createCanvas(320, 240); + // especifica múltples formatos para distintos navegadores + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.loop(); + fingers.hide(); + noStroke(); + fill(0); +} + +function draw() { + background(255); + fingers.loadPixels(); + const stepSize = round(constrain(mouseX / 8, 6, 32)); + for (let y = 0; y < height; y += stepSize) { + for (let x = 0; x < width; x += stepSize) { + const i = y * width + x; + const darkness = (255 - fingers.pixels[i * 4]) / 255; + const radius = stepSize * darkness; + ellipse(x, y, radius, radius); + } + } +} diff --git a/dist/assets/examples/es/16_Dom/11_Capture.js b/dist/assets/examples/es/16_Dom/11_Capture.js new file mode 100644 index 0000000000..1ce429c057 --- /dev/null +++ b/dist/assets/examples/es/16_Dom/11_Capture.js @@ -0,0 +1,24 @@ +/* + * @name Captura de video + * @frame 710,240 + * @description Captura video desde la webcam, muéstralo + * en el lienzo con un filtro de inversión. Fíjate que por defecto la + * captura también aparece. Puedes esconderla + * si quitas el comentario a la línea de código capture.hide(). + * Para correr este ejemplo localmente, necesitarás correr un + * servidor local. + */ +let capture; + +function setup() { + createCanvas(390, 240); + capture = createCapture(VIDEO); + capture.size(320, 240); + //capture.hide(); +} + +function draw() { + background(255); + image(capture, 0, 0, 320, 240); + filter(INVERT); +} diff --git a/dist/assets/examples/es/16_Dom/12_Drop.js b/dist/assets/examples/es/16_Dom/12_Drop.js new file mode 100644 index 0000000000..ac8c66455b --- /dev/null +++ b/dist/assets/examples/es/16_Dom/12_Drop.js @@ -0,0 +1,33 @@ +/* + * @name Arrojar + * @description Toma un archivo de imagen y arrójalo sobre el lienzo para mostrarlo. + */ + +function setup() { + // crear el lienzo + const c = createCanvas(710, 400); + background(100); + // añadir un evento para cuando un archivo sea arrojado al lienzo + c.drop(gotFile); +} + +function draw() { + fill(255); + noStroke(); + textSize(24); + textAlign(CENTER); + text('Drag an image file onto the canvas.', width / 2, height / 2); + noLoop(); +} + +function gotFile(file) { + // si es un archivo de imagen + if (file.type === 'image') { + // crear un elemento de imagen DOM, pero sin mostrarlo + const img = createImg(file.data).hide(); + // dibujar la imagen en el lienzo + image(img, 0, 0, width, height); + } else { + println('Not an image file!'); + } +} diff --git a/dist/assets/examples/es/16_Dom/13_DOM_Form_Elements.js b/dist/assets/examples/es/16_Dom/13_DOM_Form_Elements.js new file mode 100644 index 0000000000..d83dfdc13e --- /dev/null +++ b/dist/assets/examples/es/16_Dom/13_DOM_Form_Elements.js @@ -0,0 +1,152 @@ +/* + * @name DOM Form Elements + * @frame 600,400 + * @description contributed by + Prof WM Harris, How to use p5 DOM form elements to create a slider, +button, checkbox, radio group, select menu, and entry field.
+Functions are created that include: the canvas +setup, checkbox creation with text, text box with text that projects +typed text onto canvas, slider with button, three selections which +project a rectangle in different areas on the canvas depending on +selection, and a drop down menu with font change. +*/ + +/* global variables */ +//p5 DOM form elements +let slider1; +let button1; +let checkbox1; +let radio1; +let select1; +let entry1; + +function setup() { + createCanvas(200, 200); + background("beige"); + + checkbox1 = createCheckbox("Check me"); + + createP(); //spacer with

tag + + createSpan("What's your name? "); //label for entry1 + // createInput([value], [type]) + // type: "text" (default), "number", + // "date", "password", "email", etc. + entry1 = createInput(); + //If text in the entry field changes, call + //the entryCallback function. + entry1.changed(entryCallback); + + createP(); //spacer with

tag + + //createSlider(min, max, [value], [step]) + slider1 = createSlider(10, 200); + + button1 = createButton("Press me"); //, "pressed"); + //Assign callback fcn for button1 + //when user clicks mouse on it + button1.mouseClicked(button1Clicked); + + createP(); //spacer with

tag + + radio1 = createRadio(); + + //.option([value], [contentLabel]) + //If 1 param, it's both content AND + //value. Values treated as strings. + radio1.option(1, "cranberries"); + radio1.option(2, "almonds"); + radio1.option(3, "gouda"); + + radio1.value("1"); //set init value + + createP(); //spacer with

tag + + select1 = createSelect(); + //.option([contentValue],[value]) + //If 1 param, it's both content AND + //value. Values treated as strings. + select1.option("Sans-serif"); + select1.option("Serif"); + select1.option("Fantasy"); + //If changed, call select1Changed + select1.changed(select1Changed); +} + +function draw() { + //get value from slider 1 + let gray = slider1.value(); + fill(gray); + + //If mouse in corner, turn on checkbox1 + if ((mouseX < width / 3) && + (mouseY < height / 3)) { + checkbox1.checked(true); + } + //Is checkbox1 checked? Say so. + if (checkbox1.checked()) { + text("CHECKED", 20, 40); + } + + switch (radio1.value()) { + //radio value is always a string + case "1": + rect(0, 0, width, 50); + break; + case "2": + rect(0, 70, width, 50); + break; + case "3": + rect(0, 140, width, 50); + break; + } +} + +//callback fcn for button1 +function button1Clicked() { + //reset slider value to 200 + slider1.value(200); +} + + +//callback fcn for select1 +function select1Changed() { + switch (select1.value()) { + case "Sans-serif": + textFont("sans-serif"); + break; + case "Serif": + textFont("serif"); + break; + case "Fantasy": + textFont("fantasy"); + break; + } +} + +//callback function for entry1 +function entryCallback() { + for (let i = 0; i < 25; i++) { + text(entry1.value(), random(width), + random(height)); + } + +} + +function mouseClicked() { + console.log("button1?", button1.value()); + console.log("checkbox1?", checkbox1.value()); + //Update .value of either? No visible change + //to a button or checkbox + checkbox1.value("Check again"); + button1.value("clicked?"); +} + +function keyTyped() { + switch (key) { + case "r": + //move slider1 value to 100 + slider1.value(100); + break; + } +} diff --git a/dist/assets/examples/es/17_Drawing/00_Continuous_Lines.js b/dist/assets/examples/es/17_Drawing/00_Continuous_Lines.js new file mode 100644 index 0000000000..f0a598656f --- /dev/null +++ b/dist/assets/examples/es/17_Drawing/00_Continuous_Lines.js @@ -0,0 +1,15 @@ +/* + * @name Líneas continuas + * @description Haga clic y arrastre el mouse para dibujar una línea. + */ +function setup() { + createCanvas(710, 400); + background(102); +} + +function draw() { + stroke(255); + if (mouseIsPressed === true) { + line(mouseX, mouseY, pmouseX, pmouseY); + } +} diff --git a/dist/assets/examples/es/17_Drawing/01_Pattern.js b/dist/assets/examples/es/17_Drawing/01_Pattern.js new file mode 100644 index 0000000000..5f3401737d --- /dev/null +++ b/dist/assets/examples/es/17_Drawing/01_Pattern.js @@ -0,0 +1,26 @@ +/* + * @name Patrones + * @description Mueva el cursor sobre la imagen para dibujar con una herramienta + * de software que responda a la velocidad del mouse. + */ +function setup() { + createCanvas(710, 400); + background(102); +} + +function draw() { + // Llame al método variableEllipse () y envíele los parámetros + // para la posición actual del mouse y la posición anterior del mouse + variableEllipse(mouseX, mouseY, pmouseX, pmouseY); +} + +// El método simple variableEllipse () fue creado específicamente +// para este programa. Calcula la velocidad del mouse +// y dibuja una pequeña elipse si el mouse se mueve lentamente +// y dibuja una elipse grande si el mouse se mueve rápidamente + +function variableEllipse(x, y, px, py) { + let speed = abs(x - px) + abs(y - py); + stroke(speed); + ellipse(x, y, speed, speed); +} diff --git a/dist/assets/examples/es/17_Drawing/02_Pulses.js b/dist/assets/examples/es/17_Drawing/02_Pulses.js new file mode 100644 index 0000000000..b808a4ece0 --- /dev/null +++ b/dist/assets/examples/es/17_Drawing/02_Pulses.js @@ -0,0 +1,31 @@ +/* + * @name Pulsos + * @description Los instrumentos de dibujo de software pueden seguir un ritmo o + * cumplir las reglas independientemente de los gestos dibujados. Esta es una + * forma de dibujo colaborativo en el que el dibujante controla algunos aspectos + * de la imagen y el software controla a los demás. + */ +let angle = 0; + +function setup() { + createCanvas(710, 400); + background(102); + noStroke(); + fill(0, 102); +} + +function draw() { + // Dibujar solo cuando se presiona el mouse + if (mouseIsPressed === true) { + angle += 5; + let val = cos(radians(angle)) * 12.0; + for (let a = 0; a < 360; a += 75) { + let xoff = cos(radians(a)) * val; + let yoff = sin(radians(a)) * val; + fill(0); + ellipse(mouseX + xoff, mouseY + yoff, val, val); + } + fill(255); + ellipse(mouseX, mouseY, 2, 2); + } +} diff --git a/dist/assets/examples/es/18_Transform/00_Translate.js b/dist/assets/examples/es/18_Transform/00_Translate.js new file mode 100644 index 0000000000..015400b453 --- /dev/null +++ b/dist/assets/examples/es/18_Transform/00_Translate.js @@ -0,0 +1,40 @@ +/* + * @name Translate + * @description La función translate() (del inglés trasladar) permite que + * los objetos sean movidos a cualquier ubicación dentro de la + * ventana. El primer parámetro define la cantidad en el eje x + * y el segundo paráemtro en el eye y. Este ejemplo muestra cómo las + * transformadas se acumulan. + */ + +let x = 0; +let y = 0; +let dim = 80.0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(102); + // Animar al incrementar nuestor valor x + x = x + 0.8; + // Si la figura se sale del lienzo, reinicia la posición + if (x > width + dim) { + x = -dim; + } + + // Aunque nuestro comando rect() dibuja la figura con su centro + // en el origen, translate() lo mueve a una nueva posición x,y + translate(x, height / 2 - dim / 2); + fill(255); + rect(-dim / 2, -dim / 2, dim, dim); + + // Las transformaciones se acumulan. Observa cómo este rect se mueve + // al doble de velocidad que el otro, a pesar de que tiene el mismo + // parámetro para el valor de x. + translate(x, dim); + fill(0); + rect(-dim / 2, -dim / 2, dim, dim); +} diff --git a/dist/assets/examples/es/18_Transform/01_Scale.js b/dist/assets/examples/es/18_Transform/01_Scale.js new file mode 100644 index 0000000000..65863eb539 --- /dev/null +++ b/dist/assets/examples/es/18_Transform/01_Scale.js @@ -0,0 +1,47 @@ +/* + * @name Escalar + * @description Los parámetros de la función scale() (del inglés escalar) + * son valores especificados como porcentajes decimales. Por ejemplo, + * ejecutar scale(2.0) aumentará la dimensión de la digura en un + * 200 por ciento. Los objetos siempre se escalan desde el origen. + * Este ejemplo muestra cómo las transformaciones se acumulan y + * también cómo scale() y translate() interactúan dependiendo de su + * orden. + */ + +let a = 0.0; +let s = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + // Dibuja todos los rectángulos desde su centro, en vez de + // la esquina superior izquierda, que es la forma por defecto. + rectMode(CENTER); +} + +function draw() { + background(102); + + // Lentamente aumenta 'a' y luego anima 's' con un movimiento + // cíclico suave mediante el cálculo de coseno de 'a' + a = a + 0.04; + s = cos(a) * 2; + + // Traslada nuestro rectángulo desde el origen hacia el centro + // del lienzo, luego escálalo con 's' + translate(width / 2, height / 2); + scale(s); + fill(51); + rect(0, 0, 50, 50); + + // Traslación y escalamiento son acumulativos, por lo que esta + // esta traslación mueve el segundo rectángulo más a la derecha del + // primero y el escalamiento es doblado. Observa que el coseno + // está haciendo que 's' sea tanto positivo como negativo, + // por lo que oscila entre izquierda y derecha. + translate(75, 0); + fill(255); + scale(s); + rect(0, 0, 50, 50); +} diff --git a/dist/assets/examples/es/18_Transform/02_Rotate.js b/dist/assets/examples/es/18_Transform/02_Rotate.js new file mode 100644 index 0000000000..dd73728a23 --- /dev/null +++ b/dist/assets/examples/es/18_Transform/02_Rotate.js @@ -0,0 +1,48 @@ +/* + * @name Rotate + * @description Rotar un cuadrado en torno al eje Z + Si prefieres usar grados (0-360) para medir los ángulos, puede usas el + * método radians() para convertir tus valores a radianes + * For example: scale(radians(90)) is identical to the statement + * scale(PI/2). In this example, every even numbered second a jitter + * is added to the rotation. During odd seconds rotation moves CW and + * CCW at the speed determined by the last jitter value. + * Para obtener los resultados que esperas, usa ángulos de la función + * rotate() (del inglés rotar) con valores entre 0 y PI*2 (TWO_PI que + * es aproximadamente 6.28) + * + * + * + */ + +let angulo = 0.0; +let jitter = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255); + // Dibuja el rectánglo desde el centro y también hará que + //la rotación sea en torno al centro + rectMode(CENTER); +} + +function draw() { + background(51); + + // Durante los segundos pares (0, 2, 4, 6...), añade jitter a + // la rotación + if (second() % 2 === 0) { + jitter = random(-0.1, 0.1); + } + //increase the angle value using the most recent jitter value + angulo = angulo + jitter; + // Usa coseno para obtener un movimiento suave a favor y en contra + // de las manecillas del reloj cuando no esté haciendo jittering + let c = cos(angulo); + // Mueve la figura al centro del lienzo + translate(width / 2, height / 2); + // Aplica la rotación final + rotate(c); + rect(0, 0, 180, 180); +} diff --git a/dist/assets/examples/es/18_Transform/03_Arm.js b/dist/assets/examples/es/18_Transform/03_Arm.js new file mode 100644 index 0000000000..524cffb67e --- /dev/null +++ b/dist/assets/examples/es/18_Transform/03_Arm.js @@ -0,0 +1,48 @@ +/* + * @name Brazo + * @description Este ejemplo usa matrices de transformación para crear + * un brazo. El ángulo de cada segmento es controlado con la posición + * de mouseX y mouseY. Las transformaciones aplicadas al primer segmento + * son aplicadas al segundo segmento porque están dentro del mismo grupo + * de matrices push() y pop() + */ + +let x, y; +let angulo1 = 0.0; +let angulo2 = 0.0; +let largoSegmento = 100; + +function setup() { + createCanvas(720, 400); + strokeWeight(30); + + // Trazo blanco semi-transparente + stroke(255, 160); + + // Posición del "hombro" del brazo en el centro del lienzo + x = width * 0.5; + y = height * 0.5; +} + +function draw() { + background(0); + + //Modifica el ángulo de los segmentos según la posición del ratón + angulo1 = (mouseX / float(width) - 0.5) * -TWO_PI; + angulo2 = (mouseY / float(height) - 0.5) * PI; + + // Usa push y pop para "contener" las transformaciones. Nota que + // aunque dibujamos los segmentos usando una función de fabricación propia, + // las transformaciones igualmente se acumulan. + push(); + segmento(x, y, angulo1); + segmento(largoSegmento, 0, angulo2); + pop(); +} + +// una función de fabricación propia para dibujar segmentos +function segmento(x, y, a) { + translate(x, y); + rotate(a); + line(0, 0, largoSegmento, 0); +} diff --git a/dist/assets/examples/es/19_Typography/00_Letters.js b/dist/assets/examples/es/19_Typography/00_Letters.js new file mode 100644 index 0000000000..44d4f2a7ee --- /dev/null +++ b/dist/assets/examples/es/19_Typography/00_Letters.js @@ -0,0 +1,64 @@ +/* + * @name Letters + * @description Letters can be drawn to the screen by loading a font, setting + * its characteristics and then drawing the letters. This example uses a for + * loop and unicode reference numbers to automatically fill the canvas with + * characters in a grid. Vowels are selected and given a specific fill color. + */ +let font, + fontsize = 32; + +function preload() { + // Ensure the .ttf or .otf font stored in the assets directory + // is loaded before setup() and draw() are called + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // Set text characteristics + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // Set the gap between letters and the left and top margin + let gap = 52; + let margin = 10; + translate(margin * 4, margin * 4); + + // Set the counter to start at the character you want + // in this case 35, which is the # symbol + let counter = 35; + + // Loop as long as there is space on the canvas + for (y = 0; y < height - gap; y += gap) { + for (x = 0; x < width - gap; x += gap) { + // Use the counter to retrieve individual letters by their Unicode number + let letter = char(counter); + + // Add different color to the vowels and other characters + if ( + letter === 'A' || + letter === 'E' || + letter === 'I' || + letter === 'O' || + letter === 'U' + ) { + fill('#ed225d'); + } else { + fill(255); + } + + // Draw the letter to the screen + text(letter, x, y); + + // Increment the counter + counter++; + } + } +} diff --git a/dist/assets/examples/es/19_Typography/01_Words.js b/dist/assets/examples/es/19_Typography/01_Words.js new file mode 100644 index 0000000000..d76271f2b8 --- /dev/null +++ b/dist/assets/examples/es/19_Typography/01_Words.js @@ -0,0 +1,59 @@ +/* + * @name Words + * @description The text() function is used for writing words to the screen. + * The words can be aligned left, center, or right with the textAlign() + * function, and like with shapes, words can be colored with fill(). + */ +let font, + fontsize = 40; + +function preload() { + // Ensure the .ttf or .otf font stored in the assets directory + // is loaded before setup() and draw() are called + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // Set text characteristics + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // Align the text to the right + // and run drawWords() in the left third of the canvas + textAlign(RIGHT); + drawWords(width * 0.25); + + // Align the text in the center + // and run drawWords() in the middle of the canvas + textAlign(CENTER); + drawWords(width * 0.5); + + // Align the text to the left + // and run drawWords() in the right third of the canvas + textAlign(LEFT); + drawWords(width * 0.75); +} + +function drawWords(x) { + // The text() function needs three parameters: + // the text to draw, the horizontal position, + // and the vertical position + fill(0); + text('ichi', x, 80); + + fill(65); + text('ni', x, 150); + + fill(190); + text('san', x, 220); + + fill(255); + text('shi', x, 290); +} diff --git a/dist/assets/examples/es/19_Typography/02_Text_Rotation.js b/dist/assets/examples/es/19_Typography/02_Text_Rotation.js new file mode 100644 index 0000000000..fdfd7d31a5 --- /dev/null +++ b/dist/assets/examples/es/19_Typography/02_Text_Rotation.js @@ -0,0 +1,62 @@ +/* + * @name Text Rotation + * @description Draws letters to the screen and rotates them at different angles. + * (ported from https://processing.org/examples/textrotation.html) + */ + +let font, + fontsize = 32; + +let angleRotate = 0.0; + +function setup() { + createCanvas(710, 400); + background(0); + + // Ensure the .ttf or .otf font stored in the assets directory + // is loaded before setup() and draw() are called + font = loadFont('assets/SourceSansPro-Regular.otf'); + + // Set text characteristics + textFont(font); +} + +function draw() { + background(0); + + strokeWeight(1); + stroke(153); + + push(); + let angle1 = radians(45); + translate(100, 180); + rotate(angle1); + // Draw the letter to the screen + text("45 DEGREES", 0, 0); + line(0, 0, 150, 0); + pop(); + + push(); + let angle2 = radians(270); + translate(200, 180); + rotate(angle2); + // Draw the letter to the screen + text("270 DEGREES", 0, 0); + line(0, 0, 150, 0); + pop(); + + push(); + translate(440, 180); + rotate(radians(angleRotate)); + text(int(angleRotate) % 360 + " DEGREES ", 0, 0); + line(0, 0, 150, 0); + pop(); + + angleRotate += 0.25; + + stroke(255, 0, 0); + strokeWeight(4); + point(100, 180); + point(200, 180); + point(440, 180); +} diff --git a/dist/assets/examples/es/20_3D/00_geometries.js b/dist/assets/examples/es/20_3D/00_geometries.js new file mode 100644 index 0000000000..c417a19da6 --- /dev/null +++ b/dist/assets/examples/es/20_3D/00_geometries.js @@ -0,0 +1,54 @@ +/* + * @name Geometrías + * @description Existen seis figuras 3D primitivas en p5 en este momento. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + translate(-250 * 2.5, 0, 0); + normalMaterial(); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + plane(80); + pop(); + translate(250, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + box(80, 80, 80); + pop(); + translate(250, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cylinder(80, 80); + pop(); + translate(250, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cone(80, 80); + pop(); + translate(250, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + torus(80, 20); + pop(); + translate(250, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + sphere(80); + pop(); +} diff --git a/dist/assets/examples/es/20_3D/01_sine_cosine_in_3D.js b/dist/assets/examples/es/20_3D/01_sine_cosine_in_3D.js new file mode 100644 index 0000000000..07def6643d --- /dev/null +++ b/dist/assets/examples/es/20_3D/01_sine_cosine_in_3D.js @@ -0,0 +1,28 @@ +/* + * @name Seno Coseno en 3D + * @description Seno, coseno, "push" y "pop" pueden ser utilizados también en 3D. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + rotateY(frameCount * 0.01); + + for (let j = 0; j < 5; j++) { + push(); + for (let i = 0; i < 80; i++) { + translate( + sin(frameCount * 0.001 + j) * 100, + sin(frameCount * 0.001 + j) * 100, + i * 0.1 + ); + rotateZ(frameCount * 0.002); + push(); + sphere(8, 6, 4); + pop(); + } + pop(); + } +} diff --git a/dist/assets/examples/es/20_3D/02_multiple_lights.js b/dist/assets/examples/es/20_3D/02_multiple_lights.js new file mode 100644 index 0000000000..21abbdc73c --- /dev/null +++ b/dist/assets/examples/es/20_3D/02_multiple_lights.js @@ -0,0 +1,30 @@ +/* + * @name Múltiples luces + * @description Se pueden usar todos los tipos de luces usados en un mismo bosquejo. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(50); + directionalLight(255, 0, 0, 0.25, 0.25, 0); + pointLight(0, 0, 255, locX, locY, 250); + + push(); + translate(-width / 4, 0, 0); + rotateZ(frameCount * 0.02); + rotateX(frameCount * 0.02); + specularMaterial(250); + box(100, 100, 100); + pop(); + + translate(width / 4, 0, 0); + ambientMaterial(250); + sphere(120, 64); +} diff --git a/dist/assets/examples/es/20_3D/03_materials.js b/dist/assets/examples/es/20_3D/03_materials.js new file mode 100644 index 0000000000..fdec1e6057 --- /dev/null +++ b/dist/assets/examples/es/20_3D/03_materials.js @@ -0,0 +1,65 @@ +/* + * @name Materiales + * @description Existen cinco tipos de materiales soportados. + * Reaccionan de distintas formas a la luz. + * Mueve tu ratón para cambiar la posición de la luz. + */ +let img; +function setup() { + createCanvas(710, 400, WEBGL); + img = loadImage('assets/cat.jpg'); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(60, 60, 60); + pointLight(255, 255, 255, locX, locY, 100); + + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + texture(img); + box(80); + pop(); + + push(); + translate(-width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + fill(250, 0, 0); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + normalMaterial(); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(-width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + ambientMaterial(250); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + specularMaterial(250); + torus(80, 20, 64, 64); + pop(); +} diff --git a/dist/assets/examples/es/20_3D/04_textures.js b/dist/assets/examples/es/20_3D/04_textures.js new file mode 100644 index 0000000000..3b89088a22 --- /dev/null +++ b/dist/assets/examples/es/20_3D/04_textures.js @@ -0,0 +1,40 @@ +/* + * @name Texturas + * @description Tanto imágenes como videos pueden ser usados como texturas. + */ +// fuente del video: https://vimeo.com/90312869 +let img; +let vid; +let theta = 0; + +function setup() { + createCanvas(710, 400, WEBGL); + + img = loadImage('assets/cat.jpg'); + vid = createVideo(['assets/360video_256crop_v2.mp4']); + vid.elt.muted = true; + vid.loop(); + vid.hide(); +} + +function draw() { + background(250); + translate(-220, 0, 0); + push(); + rotateZ(theta * mouseX * 0.001); + rotateX(theta * mouseX * 0.001); + rotateY(theta * mouseX * 0.001); + //pasar una imagen como textura + texture(vid); + sphere(150); + pop(); + translate(440, 0, 0); + push(); + rotateZ(theta * 0.1); + rotateX(theta * 0.1); + rotateY(theta * 0.1); + texture(img); + box(100, 100, 100); + pop(); + theta += 0.05; +} diff --git a/dist/assets/examples/es/20_3D/05_ray_casting.js b/dist/assets/examples/es/20_3D/05_ray_casting.js new file mode 100644 index 0000000000..98906dcb28 --- /dev/null +++ b/dist/assets/examples/es/20_3D/05_ray_casting.js @@ -0,0 +1,100 @@ +/* + * @name Ray Casting + * @description Original example by Jonathan Watson. + *

Detecting the position of the mouse in 3D space with ray casting. + */ +const objects = []; +let eyeZ; + +function setup() { + createCanvas(710, 400, WEBGL); + + eyeZ = height / 2 / tan((30 * PI) / 180); // The default distance the camera is away from the origin. + + objects.push(new IntersectPlane(1, 0, 0, -100, 0, 0)); // Left wall + objects.push(new IntersectPlane(1, 0, 0, 100, 0, 0)); // Right wall + objects.push(new IntersectPlane(0, 1, 0, 0, -100, 0)); // Bottom wall + objects.push(new IntersectPlane(0, 1, 0, 0, 100, 0)); // Top wall + objects.push(new IntersectPlane(0, 0, 1, 0, 0, 0)); // Back wall + + noStroke(); + ambientMaterial(250); +} + +function draw() { + background(0); + + // Lights + pointLight(255, 255, 255, 0, 0, 400); + ambientLight(244, 122, 158); + + // Left wall + push(); + translate(-100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // Right wall + push(); + translate(100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // Bottom wall + push(); + translate(0, 100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + // Top wall + push(); + translate(0, -100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + plane(200, 200); // Back wall + + const x = mouseX - width / 2; + const y = mouseY - height / 2; + + const Q = createVector(0, 0, eyeZ); // A point on the ray and the default position of the camera. + const v = createVector(x, y, -eyeZ); // The direction vector of the ray. + + let intersect; // The point of intersection between the ray and a plane. + let closestLambda = eyeZ * 10; // The draw distance. + + for (let x = 0; x < objects.length; x += 1) { + let object = objects[x]; + let lambda = object.getLambda(Q, v); // The value of lambda where the ray intersects the object + + if (lambda < closestLambda && lambda > 0) { + // Find the position of the intersection of the ray and the object. + intersect = p5.Vector.add(Q, p5.Vector.mult(v, lambda)); + closestLambda = lambda; + } + } + + // Cursor + push(); + translate(intersect); + fill(237, 34, 93); + sphere(10); + pop(); +} + +// Class for a plane that extends to infinity. +class IntersectPlane { + constructor(n1, n2, n3, p1, p2, p3) { + this.normal = createVector(n1, n2, n3); // The normal vector of the plane + this.point = createVector(p1, p2, p3); // A point on the plane + this.d = this.point.dot(this.normal); + } + + getLambda(Q, v) { + return (-this.d - this.normal.dot(Q)) / this.normal.dot(v); + } +} diff --git a/dist/assets/examples/es/20_3D/07_orbit_control.js b/dist/assets/examples/es/20_3D/07_orbit_control.js new file mode 100644 index 0000000000..fea8ffecde --- /dev/null +++ b/dist/assets/examples/es/20_3D/07_orbit_control.js @@ -0,0 +1,36 @@ +/* + * @name Control de órbita + * @description El control de órbita te permite arrastrar y mover alrededor del mundo. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + let radius = width * 1.5; + + //arrastra para mover el mundo. + orbitControl(); + + normalMaterial(); + translate(0, 0, -600); + for (let i = 0; i <= 12; i++) { + for (let j = 0; j <= 12; j++) { + push(); + let a = (j / 12) * PI; + let b = (i / 12) * PI; + translate( + sin(2 * a) * radius * sin(b), + (cos(b) * radius) / 2, + cos(2 * a) * radius * sin(b) + ); + if (j % 2 === 0) { + cone(30, 30); + } else { + box(30, 30, 30); + } + pop(); + } + } +} diff --git a/dist/assets/examples/es/20_3D/08_basic_shader.js b/dist/assets/examples/es/20_3D/08_basic_shader.js new file mode 100644 index 0000000000..32610c79e4 --- /dev/null +++ b/dist/assets/examples/es/20_3D/08_basic_shader.js @@ -0,0 +1,27 @@ +/* + * @name Basic Shader + * @description This is a basic example showing how to load shaders in p5.js. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + +// this variable will hold our shader object +let theShader; + +function preload(){ + // load the shader + theShader = loadShader('assets/basic.vert', 'assets/basic.frag'); +} + +function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); +} + +function draw() { + // shader() sets the active shader with our shader + shader(theShader); + + // rect gives us some geometry on the screen + rect(0,0,width, height); +} diff --git a/dist/assets/examples/es/20_3D/09_shader_as_a_texture.js b/dist/assets/examples/es/20_3D/09_shader_as_a_texture.js new file mode 100644 index 0000000000..7bffbab11b --- /dev/null +++ b/dist/assets/examples/es/20_3D/09_shader_as_a_texture.js @@ -0,0 +1,68 @@ +/* + * @name Shader as a Texture + * @description Shaders can be applied to 2D/3D shapes as textures. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + + // this variable will hold our shader object + let theShader; + // this variable will hold our createGraphics layer + let shaderTexture; + + let theta = 0; + + let x; + let y; + let outsideRadius = 200; + let insideRadius = 100; + + function preload(){ + // load the shader + theShader = loadShader('assets/texture.vert','assets/texture.frag'); + } + + function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); + + // initialize the createGraphics layers + shaderTexture = createGraphics(710, 400, WEBGL); + + // turn off the createGraphics layers stroke + shaderTexture.noStroke(); + + x = -50; + y = 0; + } + + function draw() { + + // instead of just setting the active shader we are passing it to the createGraphics layer + shaderTexture.shader(theShader); + + // here we're using setUniform() to send our uniform values to the shader + theShader.setUniform("resolution", [width, height]); + theShader.setUniform("time", millis() / 1000.0); + theShader.setUniform("mouse", [mouseX, map(mouseY, 0, height, height, 0)]); + + // passing the shaderTexture layer geometry to render on + shaderTexture.rect(0,0,width,height); + + background(255); + + // pass the shader as a texture + texture(shaderTexture); + + translate(-150, 0, 0); + push(); + rotateZ(theta * mouseX * 0.0001); + rotateX(theta * mouseX * 0.0001); + rotateY(theta * mouseX * 0.0001); + theta += 0.05; + sphere(125); + pop(); + + // passing a fifth parameter to ellipse for smooth edges in 3D + ellipse(260,0,200,200,100); + } diff --git a/dist/assets/examples/es/20_3D/10_passing_shader_uniforms.js b/dist/assets/examples/es/20_3D/10_passing_shader_uniforms.js new file mode 100644 index 0000000000..3d6dc2ec1b --- /dev/null +++ b/dist/assets/examples/es/20_3D/10_passing_shader_uniforms.js @@ -0,0 +1,33 @@ +/* + * @name Passing Shader Uniforms + * @description Uniforms are the way in which information is passed from p5 to the shader. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + + // this variable will hold our shader object + let theShader; + + function preload(){ + // load the shader + theShader = loadShader('assets/uniforms.vert', 'assets/uniforms.frag'); + } + + function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); + } + + function draw() { + // shader() sets the active shader with our shader + shader(theShader); + + // lets send the resolution, mouse, and time to our shader + // before sending mouse + time we modify the data so it's more easily usable by the shader + theShader.setUniform('resolution', [width, height]); + theShader.setUniform('mouse', map(mouseX, 0, width, 0, 7)); + theShader.setUniform('time', frameCount * 0.01); + + // rect gives us some geometry on the screen + rect(0,0,width, height); + } diff --git a/dist/assets/examples/es/20_3D/11_shader_using_webcam.js b/dist/assets/examples/es/20_3D/11_shader_using_webcam.js new file mode 100644 index 0000000000..a3ed382cff --- /dev/null +++ b/dist/assets/examples/es/20_3D/11_shader_using_webcam.js @@ -0,0 +1,37 @@ +/* + * @name Shader Using Webcam + * @description The webcam can be passed to shaders as a texture. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + + // this variable will hold our shader object + let theShader; + // this variable will hold our webcam video + let cam; + + function preload(){ + // load the shader + theShader = loadShader('assets/webcam.vert', 'assets/webcam.frag'); + } + + function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); + + cam = createCapture(VIDEO); + cam.size(710, 400); + + cam.hide(); + } + + function draw() { + // shader() sets the active shader with our shader + shader(theShader); + + // passing cam as a texture + theShader.setUniform('tex0', cam); + + // rect gives us some geometry on the screen + rect(0,0,width,height); + } diff --git a/dist/assets/examples/es/21_Input/00_Clock.js b/dist/assets/examples/es/21_Input/00_Clock.js new file mode 100644 index 0000000000..5603db0f3e --- /dev/null +++ b/dist/assets/examples/es/21_Input/00_Clock.js @@ -0,0 +1,62 @@ +/* + * @name Clock + * @description The current time can be read with the second(), + * minute(), and hour() functions. In this example, sin() and + * cos() values are used to set the position of the hands. + */ +let cx, cy; +let secondsRadius; +let minutesRadius; +let hoursRadius; +let clockDiameter; + +function setup() { + createCanvas(720, 400); + stroke(255); + + let radius = min(width, height) / 2; + secondsRadius = radius * 0.71; + minutesRadius = radius * 0.6; + hoursRadius = radius * 0.5; + clockDiameter = radius * 1.7; + + cx = width / 2; + cy = height / 2; +} + +function draw() { + background(230); + + // Draw the clock background + noStroke(); + fill(244, 122, 158); + ellipse(cx, cy, clockDiameter + 25, clockDiameter + 25); + fill(237, 34, 93); + ellipse(cx, cy, clockDiameter, clockDiameter); + + // Angles for sin() and cos() start at 3 o'clock; + // subtract HALF_PI to make them start at the top + let s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI; + let m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; + let h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI; + + // Draw the hands of the clock + stroke(255); + strokeWeight(1); + line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius); + strokeWeight(2); + line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius); + strokeWeight(4); + line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius); + + // Draw the minute ticks + strokeWeight(2); + beginShape(POINTS); + for (let a = 0; a < 360; a += 6) { + let angle = radians(a); + let x = cx + cos(angle) * secondsRadius; + let y = cy + sin(angle) * secondsRadius; + vertex(x, y); + } + endShape(); +} diff --git a/dist/assets/examples/es/21_Input/01_Constrain.js b/dist/assets/examples/es/21_Input/01_Constrain.js new file mode 100644 index 0000000000..36a08abd31 --- /dev/null +++ b/dist/assets/examples/es/21_Input/01_Constrain.js @@ -0,0 +1,36 @@ +/* + * @name Constrain + * @description Move the mouse across the screen to move + * the circle. The program constrains the circle to its box. + */ +let mx = 1; +let my = 1; +let easing = 0.05; +let radius = 24; +let edge = 100; +let inner = edge + radius; + +function setup() { + createCanvas(720, 400); + noStroke(); + ellipseMode(RADIUS); + rectMode(CORNERS); +} + +function draw() { + background(230); + + if (abs(mouseX - mx) > 0.1) { + mx = mx + (mouseX - mx) * easing; + } + if (abs(mouseY - my) > 0.1) { + my = my + (mouseY - my) * easing; + } + + mx = constrain(mx, inner, width - inner); + my = constrain(my, inner, height - inner); + fill(237, 34, 93); + rect(edge, edge, width - edge, height - edge); + fill(255); + ellipse(mx, my, radius, radius); +} diff --git a/dist/assets/examples/es/21_Input/02_Easing.js b/dist/assets/examples/es/21_Input/02_Easing.js new file mode 100644 index 0000000000..6fe01dc1b0 --- /dev/null +++ b/dist/assets/examples/es/21_Input/02_Easing.js @@ -0,0 +1,30 @@ +/* + * @name Easing + * @description Move the mouse across the screen and the symbol + * will follow. Between drawing each frame of the animation, the + * program calculates the difference between the position of the + * symbol and the cursor. If the distance is larger than 1 pixel, + * the symbol moves part of the distance (0.05) from its current + * position toward the cursor. + */ +let x = 1; +let y = 1; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(237, 34, 93); + let targetX = mouseX; + let dx = targetX - x; + x += dx * easing; + + let targetY = mouseY; + let dy = targetY - y; + y += dy * easing; + + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/es/21_Input/03_Keyboard.js b/dist/assets/examples/es/21_Input/03_Keyboard.js new file mode 100644 index 0000000000..c7b50f99a3 --- /dev/null +++ b/dist/assets/examples/es/21_Input/03_Keyboard.js @@ -0,0 +1,38 @@ +/* + * @name Keyboard + * @description Click on the image to give it focus and + * press the letter keys to create forms in time and space. + * Each key has a unique identifying number. These numbers + * can be used to position shapes in space. + */ +let rectWidth; + +function setup() { + createCanvas(720, 400); + noStroke(); + background(230); + rectWidth = width / 4; +} + +function draw() { + // keep draw() here to continue looping while waiting for keys +} + +function keyPressed() { + let keyIndex = -1; + if (key >= 'a' && key <= 'z') { + keyIndex = key.charCodeAt(0) - 'a'.charCodeAt(0); + } + if (keyIndex === -1) { + // If it's not a letter key, clear the screen + background(230); + } else { + // It's a letter key, fill a rectangle + randFill_r = Math.floor(Math.random() * 255 + 1); + randFill_g = Math.floor(Math.random() * 255 + 1); + randFill_b = Math.floor(Math.random() * 255 + 1); + fill(randFill_r, randFill_g, randFill_b); + let x = map(keyIndex, 0, 25, 0, width - rectWidth); + rect(x, 0, rectWidth, height); + } +} diff --git a/dist/assets/examples/es/21_Input/04_Mouse1D.js b/dist/assets/examples/es/21_Input/04_Mouse1D.js new file mode 100644 index 0000000000..eb613fbab9 --- /dev/null +++ b/dist/assets/examples/es/21_Input/04_Mouse1D.js @@ -0,0 +1,24 @@ +/* + * @name Mouse 1D + * @description Move the mouse left and right to + * shift the balance. The "mouseX" variable is used + * to control both the size and color of the rectangles. + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + + let r1 = map(mouseX, 0, width, 0, height); + let r2 = height - r1; + + fill(237, 34, 93, r1); + rect(width / 2 + r1 / 2, height / 2, r1, r1); + + fill(237, 34, 93, r2); + rect(width / 2 - r2 / 2, height / 2, r2, r2); +} diff --git a/dist/assets/examples/es/21_Input/05_Mouse2D.js b/dist/assets/examples/es/21_Input/05_Mouse2D.js new file mode 100644 index 0000000000..efc623adae --- /dev/null +++ b/dist/assets/examples/es/21_Input/05_Mouse2D.js @@ -0,0 +1,20 @@ +/* + * @name Mouse 2D + * @description Moving the mouse changes the position and + * size of each box. + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + fill(244, 122, 158); + rect(mouseX, height / 2, mouseY / 2 + 10, mouseY / 2 + 10); + fill(237, 34, 93); + let inverseX = width - mouseX; + let inverseY = height - mouseY; + rect(inverseX, height / 2, inverseY / 2 + 10, inverseY / 2 + 10); +} diff --git a/dist/assets/examples/es/21_Input/06_MouseIsPressed.js b/dist/assets/examples/es/21_Input/06_MouseIsPressed.js new file mode 100644 index 0000000000..27279e99b0 --- /dev/null +++ b/dist/assets/examples/es/21_Input/06_MouseIsPressed.js @@ -0,0 +1,20 @@ +/* + * @name Mouse Press + * @description Move the mouse to position the shape. + * Press the mouse button to invert the color. + */ +function setup() { + createCanvas(720, 400); + background(230); + strokeWeight(2); +} + +function draw() { + if (mouseIsPressed) { + stroke(255); + } else { + stroke(237, 34, 93); + } + line(mouseX - 66, mouseY, mouseX + 66, mouseY); + line(mouseX, mouseY - 66, mouseX, mouseY + 66); +} diff --git a/dist/assets/examples/es/21_Input/07_Mouse_Functions.js b/dist/assets/examples/es/21_Input/07_Mouse_Functions.js new file mode 100644 index 0000000000..ad1acdc7b2 --- /dev/null +++ b/dist/assets/examples/es/21_Input/07_Mouse_Functions.js @@ -0,0 +1,66 @@ +/* + * @name Mouse Functions + * @description Click on the box and drag it across the screen. + */ +let bx; +let by; +let boxSize = 75; +let overBox = false; +let locked = false; +let xOffset = 0.0; +let yOffset = 0.0; + +function setup() { + createCanvas(720, 400); + bx = width / 2.0; + by = height / 2.0; + rectMode(RADIUS); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + // Test if the cursor is over the box + if ( + mouseX > bx - boxSize && + mouseX < bx + boxSize && + mouseY > by - boxSize && + mouseY < by + boxSize + ) { + overBox = true; + if (!locked) { + stroke(255); + fill(244, 122, 158); + } + } else { + stroke(156, 39, 176); + fill(244, 122, 158); + overBox = false; + } + + // Draw the box + rect(bx, by, boxSize, boxSize); +} + +function mousePressed() { + if (overBox) { + locked = true; + fill(255, 255, 255); + } else { + locked = false; + } + xOffset = mouseX - bx; + yOffset = mouseY - by; +} + +function mouseDragged() { + if (locked) { + bx = mouseX - xOffset; + by = mouseY - yOffset; + } +} + +function mouseReleased() { + locked = false; +} diff --git a/dist/assets/examples/es/21_Input/08_Mouse_Signals.js b/dist/assets/examples/es/21_Input/08_Mouse_Signals.js new file mode 100644 index 0000000000..8847fe8f1c --- /dev/null +++ b/dist/assets/examples/es/21_Input/08_Mouse_Signals.js @@ -0,0 +1,52 @@ +/* + * @name Mouse Signals + * @description Move and click the mouse to generate signals. + * The top row is the signal from "mouseX", the middle row is + * the signal from "mouseY", and the bottom row is the signal + * from "mouseIsPressed". + */ +let xvals = []; +let yvals = []; +let bvals = []; + +function setup() { + createCanvas(720, 400); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + for (let i = 1; i < width; i++) { + xvals[i - 1] = xvals[i]; + yvals[i - 1] = yvals[i]; + bvals[i - 1] = bvals[i]; + } + // Add the new values to the end of the array + xvals[width - 1] = mouseX; + yvals[width - 1] = mouseY; + + if (mouseIsPressed) { + bvals[width - 1] = 0; + } else { + bvals[width - 1] = 255; + } + + fill(255); + noStroke(); + rect(0, height / 3, width, height / 3 + 1); + + for (let i = 1; i < width; i++) { + stroke(255); + point(i, xvals[i] / 3); + stroke(0); + point(i, height / 3 + yvals[i] / 3); + stroke(255); + line( + i, + (2 * height) / 3 + bvals[i] / 3, + i, + (2 * height) / 3 + bvals[i - 1] / 3 + ); + } +} diff --git a/dist/assets/examples/es/21_Input/09_Storing_Input.js b/dist/assets/examples/es/21_Input/09_Storing_Input.js new file mode 100644 index 0000000000..563ff80759 --- /dev/null +++ b/dist/assets/examples/es/21_Input/09_Storing_Input.js @@ -0,0 +1,38 @@ +/* + * @name Storing Input + * @description Move the mouse across the screen to + * change the position of the circles. The positions + * of the mouse are recorded into an array and played + * back every frame. Between each frame, the newest + * value are added to the end of each array and the + * oldest value is deleted. + */ +let num = 60; +let mx = []; +let my = []; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255, 153); + for (let i = 0; i < num; i++) { + mx.push(i); + my.push(i); + } +} + +function draw() { + background(237, 34, 93); + + // Cycle through the array, using a different entry on each frame. + // Using modulo (%) like this is faster than moving all the values over. + let which = frameCount % num; + mx[which] = mouseX; + my[which] = mouseY; + + for (let i = 0; i < num; i++) { + // which+1 is the smallest (the oldest in the array) + let index = (which + 1 + i) % num; + ellipse(mx[index], my[index], i, i); + } +} diff --git a/dist/assets/examples/es/21_Input/10_Rollover.js b/dist/assets/examples/es/21_Input/10_Rollover.js new file mode 100644 index 0000000000..09ebd6648c --- /dev/null +++ b/dist/assets/examples/es/21_Input/10_Rollover.js @@ -0,0 +1,79 @@ +/* + * @name Rollover + * @description Roll over the colored squares in the center of the image to change the color of the outside rectangle. + *

This example is ported from the Rollover example + * on the Processing website + */ +let squareX, squareY; // Position of square button +let circleX, circleY; // Position of circle button +let squareSize = 90; // Width/height of square +let circleSize = 93; // Diameter of circle + +let squareColor; +let circleColor; +let baseColor; + +let squareOver = false; +let circleOver = false; + +function setup() { + createCanvas(710, 400); + squareColor = color(0); + circleColor = color(255); + baseColor = color(102); + circleX = width/2+circleSize/2+10; + circleY = height/2; + squareX = width/2-squareSize-10; + squareY = height/2-squareSize/2; +} + +function draw() { + update(mouseX, mouseY); + + noStroke(); + if (squareOver) { + background(squareColor); + } else if (circleOver) { + background(circleColor); + } else { + background(baseColor); + } + + stroke(255); + fill(squareColor); + square(squareX, squareY, squareSize); + stroke(0); + fill(circleColor); + circle(circleX, circleY, circleSize); +} + +function update(x, y) { + if( overCircle(circleX, circleY, circleSize) ) { + circleOver = true; + squareOver = false; + } else if ( overSquare(squareX, squareY, squareSize) ) { + squareOver = true; + circleOver = false; + } else { + circleOver = squareOver = false; + } +} + +function overSquare(x, y, size) { + if (mouseX >= x && mouseX <= x+size && + mouseY >= y && mouseY <= y+size) { + return true; + } else { + return false; + } +} + +function overCircle(x, y, diameter) { + const disX = x - mouseX; + const disY = y - mouseY; + if(sqrt(sq(disX) + sq(disY)) < diameter/2 ) { + return true; + } else { + return false; + } +} \ No newline at end of file diff --git a/dist/assets/examples/es/21_Input/11_Storing_Input.js b/dist/assets/examples/es/21_Input/11_Storing_Input.js new file mode 100644 index 0000000000..563ff80759 --- /dev/null +++ b/dist/assets/examples/es/21_Input/11_Storing_Input.js @@ -0,0 +1,38 @@ +/* + * @name Storing Input + * @description Move the mouse across the screen to + * change the position of the circles. The positions + * of the mouse are recorded into an array and played + * back every frame. Between each frame, the newest + * value are added to the end of each array and the + * oldest value is deleted. + */ +let num = 60; +let mx = []; +let my = []; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255, 153); + for (let i = 0; i < num; i++) { + mx.push(i); + my.push(i); + } +} + +function draw() { + background(237, 34, 93); + + // Cycle through the array, using a different entry on each frame. + // Using modulo (%) like this is faster than moving all the values over. + let which = frameCount % num; + mx[which] = mouseX; + my[which] = mouseY; + + for (let i = 0; i < num; i++) { + // which+1 is the smallest (the oldest in the array) + let index = (which + 1 + i) % num; + ellipse(mx[index], my[index], i, i); + } +} diff --git a/dist/assets/examples/es/22_Advanced_Data/00_Load_Saved_JSON.js b/dist/assets/examples/es/22_Advanced_Data/00_Load_Saved_JSON.js new file mode 100644 index 0000000000..7d3e8f4b66 --- /dev/null +++ b/dist/assets/examples/es/22_Advanced_Data/00_Load_Saved_JSON.js @@ -0,0 +1,104 @@ +/* + * @name Load Saved JSON + * @description Create a Bubble class, instantiate multiple bubbles using data from + * a JSON file, and display results on the screen. + * Because the web browsers differ in where they save files, we do not make use of + * saveJSON, unlike the Processing example.

+ * Based on Daniel Shiffman's LoadSaveJSON Example for Processing. + */ + +// Bubble class +class Bubble { + constructor(x, y, diameter, name) { + this.x = x; + this.y = y; + this.diameter = diameter; + this.radius = diameter / 2; + this.name = name; + + this.over = false; + } + + // Check if mouse is over the bubble + rollover(px, py) { + let d = dist(px, py, this.x, this.y); + this.over = d < this.radius; + } + + // Display the Bubble + display() { + stroke(0); + strokeWeight(0.8); + noFill(); + ellipse(this.x, this.y, this.diameter, this.diameter); + if (this.over) { + fill(0); + textAlign(CENTER); + text(this.name, this.x, this.y + this.radius + 20); + } + } +} + +let data = {}; // Global object to hold results from the loadJSON call +let bubbles = []; // Global array to hold all bubble objects + +// Put any asynchronous data loading in preload to complete before "setup" is run +function preload() { + data = loadJSON('assets/bubbles.json'); +} + +// Convert saved Bubble data into Bubble Objects +function loadData() { + let bubbleData = data['bubbles']; + for (let i = 0; i < bubbleData.length; i++) { + // Get each object in the array + let bubble = bubbleData[i]; + // Get a position object + let position = bubble['position']; + // Get x,y from position + let x = position['x']; + let y = position['y']; + + // Get diameter and label + let diameter = bubble['diameter']; + let label = bubble['label']; + + // Put object in array + bubbles.push(new Bubble(x, y, diameter, label)); + } +} + +// Create a new Bubble each time the mouse is clicked. +function mousePressed() { + // Add diameter and label to bubble + let diameter = random(40, 80); + let label = 'New Label'; + + // Append the new JSON bubble object to the array + bubbles.push(new Bubble(mouseX, mouseY, diameter, label)); + + // Prune Bubble Count if there are too many + if (bubbles.length > 10) { + bubbles.shift(); // remove first item from array + } +} + +function setup() { + createCanvas(640, 360); + loadData(); +} + +function draw() { + background(255); + + // Display all bubbles + for (let i = 0; i < bubbles.length; i++) { + bubbles[i].display(); + bubbles[i].rollover(mouseX, mouseY); + } + + // Label directions at bottom + textAlign(LEFT); + fill(0); + text('Click to add bubbles.', 10, height - 10); +} diff --git a/dist/assets/examples/es/22_Advanced_Data/01_Load_Saved_Table.js b/dist/assets/examples/es/22_Advanced_Data/01_Load_Saved_Table.js new file mode 100644 index 0000000000..8536abcccc --- /dev/null +++ b/dist/assets/examples/es/22_Advanced_Data/01_Load_Saved_Table.js @@ -0,0 +1,110 @@ +/* + * @name Load Saved Table + * @description Create a Bubble class, instantiate multiple bubbles using data from + * a csv file, and display results on the screen. + * Because the web browsers differ in where they save files, we do not make use of + * + * Based on Daniel Shiffman's LoadSaveTable Example for Processing. + */ + +// Bubble class +class Bubble { + constructor(x, y, diameter, name) { + this.x = x; + this.y = y; + this.diameter = diameter; + this.radius = diameter / 2; + this.name = name; + + this.over = false; + } + + // Check if mouse is over the bubble + rollover(px, py) { + let d = dist(px, py, this.x, this.y); + this.over = d < this.radius; + } + + // Display the Bubble + display() { + stroke(0); + strokeWeight(0.8); + noFill(); + ellipse(this.x, this.y, this.diameter, this.diameter); + if (this.over) { + fill(0); + textAlign(CENTER); + text(this.name, this.x, this.y + this.radius + 20); + } + } +} + +let table; // Global object to hold results from the loadTable call +let bubbles = []; // Global array to hold all bubble objects + +// Put any asynchronous data loading in preload to complete before "setup" is run +function preload() { + table = loadTable("assets/bubbles.csv", "header"); +} + +// Convert saved Bubble data into Bubble Objects +function loadData() { + const bubbleData = table.getRows(); + // The size of the array of Bubble objects is determined by the total number of rows in the CSV + const length = table.getRowCount(); + + for (let i = 0; i < length; i++) { + // Get position, diameter, name, + const x = bubbleData[i].getNum("x"); + const y = bubbleData[i].getNum("y"); + const diameter = bubbleData[i].getNum("diameter"); + const name = bubbleData[i].getString("name"); + + // Put object in array + bubbles.push(new Bubble(x, y, diameter, name)); + } +} + +// Create a new Bubble each time the mouse is clicked. +function mousePressed() { + // Create a new row + let row = table.addRow(); + + let name = "New Bubble"; + let diameter = random(40, 80); + + // Set the values of that row + row.setNum("x", mouseX); + row.setNum("y", mouseY); + row.setNum("diameter", diameter); + row.setString("name", name); + + bubbles.push(new Bubble(mouseX, mouseY, diameter, name)); + + // If the table has more than 10 rows + if (table.getRowCount() > 10) { + // Delete the oldest row + table.removeRow(0); + bubbles.shift(); + } +} + +function setup() { + createCanvas(640, 360); + loadData(); +} + +function draw() { + background(255); + + // Display all bubbles + for (let i = 0; i < bubbles.length; i++) { + bubbles[i].display(); + bubbles[i].rollover(mouseX, mouseY); + } + + // Label directions at bottom + textAlign(LEFT); + fill(0); + text("Click to add bubbles.", 10, height - 10); +} diff --git a/dist/assets/examples/es/33_Sound/00_Load_and_Play_Sound.js b/dist/assets/examples/es/33_Sound/00_Load_and_Play_Sound.js new file mode 100644 index 0000000000..5497898f68 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/00_Load_and_Play_Sound.js @@ -0,0 +1,25 @@ +/* + * @name Cargar y reproducir sonido + * @description Carga de sonido durante preload(). Reproducir un sonido cuando se hace click en el lienzo. + *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +let song; + +function setup() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); + createCanvas(720, 200); + background(255, 0, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() retorna una variable booleana + song.stop(); + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/es/33_Sound/01_Preload_Sound.js b/dist/assets/examples/es/33_Sound/01_Preload_Sound.js new file mode 100644 index 0000000000..22b5ed0f1d --- /dev/null +++ b/dist/assets/examples/es/33_Sound/01_Preload_Sound.js @@ -0,0 +1,34 @@ +/* + * @name Precargar archivo de sonido + * @description Llamar a loadSound() durante preload() para asegurar que el + * sonido esté completamente cargado antes de llamar a setup(). Es mejor siempre + * llamar a loadSound() dentro de preload(), si no podría pasar que los sonidos no estén cargados + * al momento de querer reproducirlos en tu bosquejo. + * + *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ + +let song; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); // la canción está lista para ser reproducida durante setup() porque fue cargada durante preload() + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() retorna una variable booleana + song.pause(); // .play() continuará la reproducción desde la posición definida por .pause() + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/es/33_Sound/02_soundFormats.js b/dist/assets/examples/es/33_Sound/02_soundFormats.js new file mode 100644 index 0000000000..d3e7c53224 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/02_soundFormats.js @@ -0,0 +1,53 @@ +/** + * @name Formatos de sonido + * @description

Técnicamente, por problemas de patente, no existe un único + * formato de sonido que sea soportado por todos los navegadores web. Mientras que el + * mp3 es soportado a lo largo de las + * últimas versiones de los más populares navegadores en OS X y Windows, por ejemplo, + * puede no estar disponible en algunos sistemas operativos o navegadmores menos comunes.

+ * + *

Para asegurarse de tener total compatibilidad, puedes incluir el mismo archivo de sonido + * en múltiples formatos, por ejemplo 'sound.mp3' y 'sound.ogg'. (Ogg es una + * alternativa al mp3 de código abierto.) Puedes convertir archivos de audio + * en formatos amigables con la web de forma gratuita en media.io

. + * + *

El método soundFormats() le dice a loadSound() cuáles formatos + * hemos incluido en nuestro bosquejo. Entonces, loadSound() + * tratará de cargar el primer formato que sea soportado por + * el navegador web del cliente.

+ * + *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ + +let song; + +function preload() { + // hemos incluido un archivo .ogg y otro .mp3 + soundFormats('ogg', 'mp3'); + + // si mp3 no es soportado por este navegador, + // loadSound() cargará el archivo ogg + // que hemos incluido con nuestro bosquejo + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + + // canción cargada durante preload(), lista para ser reproducida durante setup() + song.play(); + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() retorna una variable booleana + song.pause(); + background(255, 0, 0); + } else { + song.play(); // la reproducción continuará desde el instante en que fue pausado. + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/es/33_Sound/03_Play_Mode.js b/dist/assets/examples/es/33_Sound/03_Play_Mode.js new file mode 100644 index 0000000000..478ee963a7 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/03_Play_Mode.js @@ -0,0 +1,42 @@ +/* + * @name Modo de reproducción + * @description + *

En el modo 'sustain', el sonido se superpone consigo mismo. + * En el modo 'restart', parará y comenzará de nuevo + * Haz click para reproducir un archivo de audio. + * Gatilla muchos sonidos al mismo tiempo. Presiona cualquier tecla para cambiar el modo de reproducción.

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +let playMode = 'sustain'; +let sample; + +function setup() { + createCanvas(710, 50); + soundFormats('mp3', 'ogg'); + sample = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3'); +} + +function draw() { + background(255, 255, 0); + let str = 'Click here to play! Press key to toggle play mode.'; + str += ' Current Play Mode: ' + playMode + '.'; + text(str, 10, height / 2); +} + +function mouseClicked() { + sample.play(); +} +function keyPressed(k) { + togglePlayMode(); +} + +function togglePlayMode() { + if (playMode === 'sustain') { + playMode = 'restart'; + } else { + playMode = 'sustain'; + } + sample.playMode(playMode); +} diff --git a/dist/assets/examples/es/33_Sound/04_Pan_SoundFile.js b/dist/assets/examples/es/33_Sound/04_Pan_SoundFile.js new file mode 100644 index 0000000000..2b5f659a62 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/04_Pan_SoundFile.js @@ -0,0 +1,33 @@ +/* + * @name Paneo + * @description

Haz click para reproducir el sonido. + * La pelota sigue la posición del ratón y se correlaciona con el paneo del sonido.

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +let ball = {}; +let soundFile; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beatbox.ogg'); +} + +function setup() { + createCanvas(710, 100); +} + +function draw() { + background(0); + ball.x = constrain(mouseX, 0, width); + ellipse(ball.x, height / 2, 100, 100); +} + +function mousePressed() { + // mapear la posición x de la pelota a un ángulo de paneo + // entre -1.0 (izquierda) y 1.0 (derecha) + let panning = map(ball.x, 0, width, -1.0, 1.0); + soundFile.pan(panning); + soundFile.play(); +} diff --git a/dist/assets/examples/es/33_Sound/05_Sound_Effect.js b/dist/assets/examples/es/33_Sound/05_Sound_Effect.js new file mode 100644 index 0000000000..dc50db7bbc --- /dev/null +++ b/dist/assets/examples/es/33_Sound/05_Sound_Effect.js @@ -0,0 +1,70 @@ +/* + * @name Efecto de sonido + * @description

Reproduce un efecto de sonido cuando el ratón hace click dentro del círculo.

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +// Adaptado de "Learning Processing" de Daniel Shiffman +// http://www.learningprocessing.com +// Sample de timbre por Corsica_S via freesound.org, +// Creative Commons BY 3.0 + +// una clase para describir un "timbre" (realmente un botón) +class Doorbell { + constructor(x_, y_, r_) { + // posición y tamaño + this.x = x_; + this.y = y_; + this.r = r_; + } + + // ¿hay un punto dentro del timbre?(usado para "rollover" del ratón) + contains(mx, my) { + return dist(mx, my, this.x, this.y) < this.r; + } + + // muestra el timbre (colores arbitrarios, podría ser mejorado) + display(mx, my) { + if (this.contains(mx, my)) { + fill(100); + } else { + fill(175); + } + stroke(0); + strokeWeight(4); + ellipseMode(RADIUS); + ellipse(this.x, this.y, this.r, this.r); + } +} + +// Un objeto archivo de sonido +let dingdong; + +// un objeto timbre (doorbell), que gatillará el sonido +let doorbell; + +function setup() { + createCanvas(200, 200); + + // cargar el archivo de sonido + // hemos incluido versiones MP3 y OGG. + soundFormats('mp3', 'ogg'); + dingdong = loadSound('assets/doorbell.mp3'); + + // crear un nuevo timbre + doorbell = new Doorbell(width / 2, height / 2, 32); +} + +function draw() { + background(255); + // muestra el timbre + doorbell.display(mouseX, mouseY); +} + +function mousePressed() { + // si el usuario hace click en el timbre, reproduce el sonido + if (doorbell.contains(mouseX, mouseY)) { + dingdong.play(); + } +} diff --git a/dist/assets/examples/es/33_Sound/06_Manipulate_Sound.js b/dist/assets/examples/es/33_Sound/06_Manipulate_Sound.js new file mode 100644 index 0000000000..b38c9dcb34 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/06_Manipulate_Sound.js @@ -0,0 +1,50 @@ +/* + * @name Tasa de reproducción + * @description

Cargar un archivo de sonido y mapear su tasa de reproducción a la posición y del ratón + * y el volumen a la posición x, mouseY y mouseX respectivamente. + * La tasa de reproducción es la velocidad con que + * el contexto web de audio procesa la información del archivo de sonido. + * Tasas más bajas no solo prolongan la duración del sonido, sino que también + * disminuyen la altura (pitch) porque la reproducción es realizada a menor frecuencia.

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +// un objeto de archivo de sonido +let song; + +function preload() { + // cargar un archivo de sonido + song = loadSound('assets/Damscray_DancingTiger.mp3'); +} + +function setup() { + createCanvas(710, 400); + + // repite el sonido en bucle por siempre + // (bueno, al menos hasta que se llame a stop()) + song.loop(); +} + +function draw() { + background(200); + + // definir el volumen a un rango entre 0 y 1.0 + let volume = map(mouseX, 0, width, 0, 1); + volume = constrain(volume, 0, 1); + song.amp(volume); + + // define la tasa a un rango entre 0.1 y 4 + // cambiar la tasa altera la altura del sonido (pitch) + let speed = map(mouseY, 0.1, height, 0, 2); + speed = constrain(speed, 0.01, 4); + song.rate(speed); + + // dibuja algunas círculos para mostrar lo que está pasando + stroke(0); + fill(51, 100); + ellipse(mouseX, 100, 48, 48); + stroke(0); + fill(51, 100); + ellipse(100, mouseY, 48, 48); +} diff --git a/dist/assets/examples/es/33_Sound/07_Amplitude_Analysis.js b/dist/assets/examples/es/33_Sound/07_Amplitude_Analysis.js new file mode 100644 index 0000000000..6d15329043 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/07_Amplitude_Analysis.js @@ -0,0 +1,50 @@ +/** + * @name Midiendo la amplitud + * @description

Analiza la amplitud del sonido con + * p5.Amplitude.

+ * + *

La amplitud es la magnitud de la vibración. El sonido es vibración, + * así que la amplitiud se relaciona fuertemente al volumen (loudness).

+ * + *

El métodogetLevel() toma un arreglo de valores de amplitud + * almacenados en un pequeño periodo de tiempo(1024 samples). + * Retorna el Root Mean Square (RMS) de estos valores.

+ * + *

Los valores originales de amplitud para audio digital están entre -1.0 y 1.0. + * No obstante, el valor RMS siempre será positivo, porque está elevado al cuadrado. + * Además, en vez de usar lecturas de amplitud instantáneas que son sampleadas a una tasa de + * 44,100 veces por segundo, RMS es un promedio en el tiempo (1024 samples, en este caso), + * lo que representa de mejor manera cómo nosotros escuchamos la amplitud. + *

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +let song, analyzer; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); + + // crea un nuevo analizador de amplitud + analyzer = new p5.Amplitude(); + + // Conecta la entrada al analizador de amplitud + analyzer.setInput(song); +} + +function draw() { + background(255); + + // Obtén la amplitud RMS (root mean square) + let rms = analyzer.getLevel(); + fill(127); + stroke(0); + + // Dibuja una elipse con su tamaño proporcional al volumen + ellipse(width / 2, height / 2, 10 + rms * 200, 10 + rms * 200); +} diff --git a/dist/assets/examples/es/33_Sound/08_Noise_Envelope.js b/dist/assets/examples/es/33_Sound/08_Noise_Envelope.js new file mode 100644 index 0000000000..4b62c70987 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/08_Noise_Envelope.js @@ -0,0 +1,52 @@ +/** + * @name Tambor con envolvente y ruido + * @description

El ruido blanco es una señal de audio aleatoria con igual energía + * en cada parte del espectro de frecuencia

+ * + *

Una envolvente es una serie de fundidos, definidos como pares de tiempo/valor.

+ * + *

En este ejemplo, el objeto p5.Env + * será usado para "tocar" el objeto p5.Noise como un tambor, por medio de controlar su amplitud de salida. + * Un objeto p5.Amplitude nos dará el nivel de todo el sonido en el bosquejo, y + * usaremos este valor para dibujar un rectángulo verde que muestra la envolvente en acción

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * y un archivo de audio. + */ +let noise, env, analyzer; + +function setup() { + createCanvas(710, 200); + noise = new p5.Noise(); // otros tipos incluyen ruido café (brown) y rosado (pink) + noise.start(); + + // multiplica el volumen del ruido por 0 + // (¡mantenlo callado hasta que estemos listos para hacer ruido!) + noise.amp(0); + + env = new p5.Env(); + // define el tiempo de ataque, el tiempo de decaimiento, la razón de "sustain" y el tiempo de "release" + env.setADSR(0.001, 0.1, 0.2, 0.1); + // configurar el nivel de ataque y de "release" + env.setRange(1, 0); + + // El objeto p5.Amplitude() analizará todo el sonido en el bosquejo + // a menos que el métodosetInput() sea usado para especificar la señal de entrada + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // obtener lectura de volumen del analizador p5.Amplitude + let level = analyzer.getLevel(); + + // usar el nivel para dibujar un rectángulo verde + let levelHeight = map(level, 0, 0.4, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); +} + +function mousePressed() { + env.play(noise); +} diff --git a/dist/assets/examples/es/33_Sound/09_Note_Envelope.js b/dist/assets/examples/es/33_Sound/09_Note_Envelope.js new file mode 100644 index 0000000000..cade65804d --- /dev/null +++ b/dist/assets/examples/es/33_Sound/09_Note_Envelope.js @@ -0,0 +1,61 @@ +/** + * @name Envolvente de nota + * @description

Una envolvente es una serie de fundidos, definidos como + * pares tiempo/valor. En este ejemplo, la envolvente + * será usada para "tocar" una nota al controlar la + * amplitud de salida de un oscilador.

+ * El objeto p5.Oscillator() envía su señal de salida a través de + * un nodo de ganancia (GainNode) de tipo Web Audio interno (p5.Oscillator.output). + * Por defecto, ese nodo tiene un valor constante de 0.5. + * Puede ser redefinido con el método osc.amp(). O, como en este ejemplo, con una + * envolvente que toma control de ese nodo, subiendo y bajando + * la amplitud como una perilla de volumen.

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * y un archivo de audio. + */ +let osc, envelope, fft; + +let scaleArray = [60, 62, 64, 65, 67, 69, 71, 72]; +let note = 0; + +function setup() { + createCanvas(710, 200); + osc = new p5.SinOsc(); + + // instanciar la envolvente + envelope = new p5.Env(); + + // definir el tiempo de ataque, de decaimiento, la razón de "sustain" y el tiempo de "release" + envelope.setADSR(0.001, 0.5, 0.1, 0.5); + + // definir el nivel de ataque y de "release" + envelope.setRange(1, 0); + + osc.start(); + + fft = new p5.FFT(); + noStroke(); +} + +function draw() { + background(20); + + if (frameCount % 60 === 0 || frameCount === 1) { + let midiValue = scaleArray[note]; + let freqValue = midiToFreq(midiValue); + osc.freq(freqValue); + + envelope.play(osc, 0, 0.1); + note = (note + 1) % scaleArray.length; + } + + // graficar el análisis de frecuencia de FFT.analyze() en el lienzo + let spectrum = fft.analyze(); + for (let i = 0; i < spectrum.length / 20; i++) { + fill(spectrum[i], spectrum[i] / 10, 0); + let x = map(i, 0, spectrum.length / 20, 0, width); + let h = map(spectrum[i], 0, 255, 0, height); + rect(x, height, spectrum.length / 20, -h); + } +} diff --git a/dist/assets/examples/es/33_Sound/10_Oscillator_Waveform.js b/dist/assets/examples/es/33_Sound/10_Oscillator_Waveform.js new file mode 100644 index 0000000000..a1d1e3d999 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/10_Oscillator_Waveform.js @@ -0,0 +1,41 @@ +/* + * @name Frecuencia de oscilador + * @description

Controla un oscilador y observa la forma de onda usando FFT. + * La posición horizontal del ratón (mouseX) es mapeada a la frecuencia, y la vertical (mouseY) a la amplitud.

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * y un archivo de audio. + */ +let osc, fft; + +function setup() { + createCanvas(720, 256); + + osc = new p5.TriOsc(); // definir frecuencia y tipo + osc.amp(0.5); + + fft = new p5.FFT(); + osc.start(); +} + +function draw() { + background(255); + + let waveform = fft.waveform(); // analiza la forma de onda + beginShape(); + strokeWeight(5); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, height, 0); + vertex(x, y); + } + endShape(); + + // cambia la frecuencia del oscilador según mouseX + let freq = map(mouseX, 0, width, 40, 880); + osc.freq(freq); + + // cambia la amplitud del oscilador según mouseY + let amp = map(mouseY, 0, height, 1, 0.01); + osc.amp(amp); +} diff --git a/dist/assets/examples/es/33_Sound/11_Live_Input.js b/dist/assets/examples/es/33_Sound/11_Live_Input.js new file mode 100644 index 0000000000..75e30ff273 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/11_Live_Input.js @@ -0,0 +1,36 @@ +/** + * @name Entrada de micrófono + * @description

Obtén una entrada de audio desde el micrófono de tu computador. + * Haz ruido para hacer que la elipse flote.

+ *

Nota: p5.AudioIn contiene su propio objeto p5.Amplitude, + * así que puedes llamar a getLevel() en p5.AudioIn() sin + * crear un objeto p5.Amplitude().

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +let mic; + +function setup() { + createCanvas(710, 200); + + // crea una entrada de audio + mic = new p5.AudioIn(); + + // inicia la entrada de audio + // por defecto, no la conecta (.connect()) a los parlantes del computador. + mic.start(); +} + +function draw() { + background(200); + + // obtén el volumen general (entre 0.0 y 1.0) + let vol = mic.getLevel(); + fill(127); + stroke(0); + + // dibuja una elipse con altura según el volumen + let h = map(vol, 0, 1, height, 0); + ellipse(width / 2, h - 25, 50, 50); +} diff --git a/dist/assets/examples/es/33_Sound/12_FFT_Spectrum.js b/dist/assets/examples/es/33_Sound/12_FFT_Spectrum.js new file mode 100644 index 0000000000..7b7379cbfe --- /dev/null +++ b/dist/assets/examples/es/33_Sound/12_FFT_Spectrum.js @@ -0,0 +1,30 @@ +/** + * @name Espectro de frecuencia + * @description

Visualia el espectro de frecuencia de la entrada de audio en vivo.

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +let mic, fft; + +function setup() { + createCanvas(710, 400); + noFill(); + + mic = new p5.AudioIn(); + mic.start(); + fft = new p5.FFT(); + fft.setInput(mic); +} + +function draw() { + background(200); + + let spectrum = fft.analyze(); + + beginShape(); + for (i = 0; i < spectrum.length; i++) { + vertex(i, map(spectrum[i], 0, 255, height, 0)); + } + endShape(); +} diff --git a/dist/assets/examples/es/33_Sound/13_Mic_Threshold.js b/dist/assets/examples/es/33_Sound/13_Mic_Threshold.js new file mode 100644 index 0000000000..f3283cfac2 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/13_Mic_Threshold.js @@ -0,0 +1,49 @@ +/** + * @name Umbral de micrófono + * @description

Gatilla un evento (dibujar un rectángulo) cuando el volumen de la entrada + * de audio sobrepasa un umbral.

+ *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +// Adaptado de "Learning Processing" por Daniel Shiffman +// learningprocessing.com +let input; +let analyzer; + +function setup() { + createCanvas(710, 200); + background(255); + + // crea una entrada de audio + input = new p5.AudioIn(); + + input.start(); +} + +function draw() { + // obtén el volumen general (entre 0.0 y 1.0) + let volume = input.getLevel(); + + // si volume > 0.1, se dibuja un rectángulo en una posición aleatoria. + // a mayor volumen, más grande el rectángulo. + let threshold = 0.1; + if (volume > threshold) { + stroke(0); + fill(0, 100); + rect(random(40, width), random(height), volume * 50, volume * 50); + } + + // grafica el volumen potencial general, con una línea en el umbral + let y = map(volume, 0, 1, height, 0); + let ythreshold = map(threshold, 0, 1, height, 0); + + noStroke(); + fill(175); + rect(0, 0, 20, height); + // luego dibuja un rectángulo en el gráfico, con su tamaño acorde al volumen + fill(0); + rect(0, y, 20, y); + stroke(0); + line(0, ythreshold, 19, ythreshold); +} diff --git a/dist/assets/examples/es/33_Sound/14_Filter_LowPass.js b/dist/assets/examples/es/33_Sound/14_Filter_LowPass.js new file mode 100644 index 0000000000..1017aa3f0d --- /dev/null +++ b/dist/assets/examples/es/33_Sound/14_Filter_LowPass.js @@ -0,0 +1,62 @@ +/** + * @name Filtro pasabajos + * @description Aplica un filtro pasabajos (p5.LowPass) a un archivo de audio (p5.SoundFile). + * Visualiza el sonido con FFT. + * Mapea la posición horizontal del ratón (mouseX) a la frecuencia de corte del filtro + * y la vertical (mouseY) a la razón resonancia/ancho de un filtro pasabanda. + * + *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +let soundFile; +let fft; + +let filter, filterFreq, filterRes; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beat'); +} + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + // reproduce el archivo de sonido en bucle + soundFile.loop(); + + filter = new p5.LowPass(); + + // desconecta el archivo de audio de la salida maestra. + // luego, conéctalo al filtro, para que solo escuchemos el sonido filtrado + soundFile.disconnect(); + soundFile.connect(filter); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // Mapea la posición horizontal del ratón (mouseX) a la frecuencia de corte desde + // la frecuencia más grave (10Hz) a la más aguda (22050Hz) que los humanos escuchan + filterFreq = map(mouseX, 0, width, 10, 22050); + + // Mapea la posición vertical del ratón (mouseY) a la resonancia (aumento de volumen) en la frecuencia de corte + filterRes = map(mouseY, 0, height, 15, 5); + + // define los parámetros del filtro + filter.set(filterFreq, filterRes); + + // dibuja cada lugar en el análisis de espectro FFT donde + // x = frecuencia más grave (10Hz) a la más aguda (22050Hz), + // h = energía (amplitud / volumen) en esa frecuencia + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/es/33_Sound/15_Filter_BandPass.js b/dist/assets/examples/es/33_Sound/15_Filter_BandPass.js new file mode 100644 index 0000000000..59223b268a --- /dev/null +++ b/dist/assets/examples/es/33_Sound/15_Filter_BandPass.js @@ -0,0 +1,51 @@ +/** + * @name Filtro pasabanda + * @description Aplica un filtro pasabanda (p5.BandPass) a ruido blanco. + * Visualiza el sonido con FFT. + * Mapea la posición horizontal del ratón (mouseX) a la frecuencia de pasabanda + * y la vertical (mouseY) a la razón resonancia/ancho del filtro pasabanda + * + *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +let noise; +let fft; +let filter, filterFreq, filterWidth; + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + filter = new p5.BandPass(); + + noise = new p5.Noise(); + + noise.disconnect(); // desconecta el archivo de sonido de la salida maestra + filter.process(noise); // y conéctalo al filtro para solo escuchar el sonido filtrado por el filtro pasabanda + noise.start(); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // mapea la posición horizontal del ratón (mouseX) a una frecuencia de pasabanda dentro del rango del espectro FFT: 10Hz - 22050Hz + filterFreq = map(mouseX, 0, width, 10, 22050); + // mapea la posición vertical del ratón (mouseY) a la razón resonancia/ancho + filterWidth = map(mouseY, 0, height, 0, 90); + // definir los parámetros del filtor + filter.set(filterFreq, filterWidth); + + // Dibuja cada valor en el análisis de espectro FFT donde + // x = frecuencia más grave (10Hz) a más aguda (22050Hz), + // h = energía / amplitud en esa frecuencia + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/es/33_Sound/16_Delay.js b/dist/assets/examples/es/33_Sound/16_Delay.js new file mode 100644 index 0000000000..d374129f33 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/16_Delay.js @@ -0,0 +1,56 @@ +/** + * @name Delay + * @description + * Haz click para escuchar cómo el objeto (p5.Delay) procesa un archivo de audio. + * La posición horizontal del ratón (mouseX) controla la frecuencia de filtrado del objeto p5.Delay. + * La posición vertical del ratón (mouseY) controla tanto el tiempo de retraso como la resonancia del objeto p5.Delay. + * Visualiza el volumen resultante del sonido con un objeto Amplitude. + * + *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ + +let soundFile, analyzer, delay; + +function preload() { + soundFormats('ogg', 'mp3'); + soundFile = loadSound('assets/beatbox.mp3'); +} + +function setup() { + createCanvas(710, 400); + + soundFile.disconnect(); // para que solo escuchemos el delay + + delay = new p5.Delay(); + delay.process(soundFile, 0.12, 0.7, 2300); + delay.setType('pingPong'); // un tipo de efecto stereo + + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // obtener una lectura de volumen del analizador p5.Amplitude + let level = analyzer.getLevel(); + + // usar el nivel para dibujar un rectángulo verde + let levelHeight = map(level, 0, 0.1, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); + + let filterFreq = map(mouseX, 0, width, 60, 15000); + filterFreq = constrain(filterFreq, 60, 15000); + let filterRes = map(mouseY, 0, height, 3, 0.01); + filterRes = constrain(filterRes, 0.01, 3); + delay.filter(filterFreq, filterRes); + let delTime = map(mouseY, 0, width, 0.2, 0.01); + delTime = constrain(delTime, 0.01, 0.2); + delay.delayTime(delTime); +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/es/33_Sound/17_Reverb.js b/dist/assets/examples/es/33_Sound/17_Reverb.js new file mode 100644 index 0000000000..ee829fbfef --- /dev/null +++ b/dist/assets/examples/es/33_Sound/17_Reverb.js @@ -0,0 +1,37 @@ +/** + * @name Reverb + * @description El reverb le da profundidad y sensación de espacio a un sonido. Aquí, + * estamos procesando ruido con reverb. + * + *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ + +let sound, reverb; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/Damscray_DancingTiger'); + + // desconectar la conexión por defecto + // para solor escuchar el sonido a través de reverb.process() + soundFile.disconnect(); +} + +function setup() { + createCanvas(720, 100); + background(0); + + reverb = new p5.Reverb(); + + // conectar el archivo de audio al reverb, con un + // tiempo de reverb de 6 segundos, y una tasa de decaimiento de 0.2% + reverb.process(soundFile, 6, 0.2); + + reverb.amp(4); // ¡súbele el volumen! +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/es/33_Sound/18_Convolution_Reverb.js b/dist/assets/examples/es/33_Sound/18_Convolution_Reverb.js new file mode 100644 index 0000000000..c1960577a3 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/18_Convolution_Reverb.js @@ -0,0 +1,86 @@ +/** + * @name Reverb de convolución + * @description

El objeto p5.Convolver puede recrear el sonido de un espacio + * real usando convolución. La convolución toma una respuesta al impulso, + * (el sonido de un espacio reverberando), y usa eso para recrear el sonido en ese espacio + *

Haz click para reproducir el sonido convolucionado + * Cada vez que haces click, el sonido es convolucionado con + * una respuesta al impulso diferente. Para escuchar la respuesta al impulso, presiona cualquier tecla.

+ * + *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + * Estos samples de convolución son Creative Commons BY + * + * recordinghopkins

+ */ +let sound, env, cVerb, fft; +let currentIR = 0; +let rawImpulse; + +function preload() { + // hemos incluido versiones MP3 y OGG de todos los impulsos y sonidos + soundFormats('ogg', 'mp3'); + + // crear un objeto p5.Convolver + cVerb = createConvolver('assets/bx-spring'); + + // añadir respuestas al impulso al arreglo cVerb.impulses, además del ya agregado bx-spring + cVerb.addImpulse('assets/small-plate'); + cVerb.addImpulse('assets/drum'); + cVerb.addImpulse('assets/beatbox'); + cVerb.addImpulse('assets/concrete-tunnel'); + + // cargar un sonido que será procesado por el objeto p5.ConvultionReverb + sound = loadSound('assets/Damscray_DancingTiger'); +} + +function setup() { + createCanvas(710, 400); + rawImpulse = loadSound('assets/' + cVerb.impulses[currentIR].name); + + // desconectar de la salida maestra + sound.disconnect(); + // y procesarlo con cVerb + // para que solo escuchemos el reverb + cVerb.process(sound); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + fill(0, 255, 40); + + let spectrum = fft.analyze(); + + // dibuja cada valor en el arreglo de espectro de frecuencia como un rectángulo + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} + +function mousePressed() { + // recorre el arreglo cVerb.impulses + currentIR++; + if (currentIR >= cVerb.impulses.length) { + currentIR = 0; + } + cVerb.toggleImpulse(currentIR); + + // reproduce el sonido a través del impulso + sound.play(); + + // muestra en pantalla el nombre de la respuesta al impulso actual (el nombre del archivo) + println('Convolution Impulse Response: ' + cVerb.impulses[currentIR].name); + + rawImpulse.setPath('assets/' + cVerb.impulses[currentIR].name); +} + +// reproduce el impulso (sin convolución) +function keyPressed() { + rawImpulse.play(); +} diff --git a/dist/assets/examples/es/33_Sound/19_Record_Save.js b/dist/assets/examples/es/33_Sound/19_Record_Save.js new file mode 100644 index 0000000000..41e8577c0f --- /dev/null +++ b/dist/assets/examples/es/33_Sound/19_Record_Save.js @@ -0,0 +1,58 @@ +/** + * @name Graba y almacena audio + * @description Graba un sonido, reprodúcelo y almacénalo como + * un archivo .wav file en el computador cliente. + * Necesitamos tres objetos: un p5.AudioIn (micrófono / fuente de sonido), + * p5.SoundRecorder (graba el sonido), y un + * p5.SoundFile (reproduce / almacena). + *

Para correr localmente este ejemplo, necesitarás la + * biblioteca p5.sound + * un archivo de audio y correr un servidor local. + */ +let mic, recorder, soundFile; + +let state = 0; // presionar el ratón cambiará el estado de grabar, a parar y a reproducir + +function setup() { + createCanvas(400, 400); + background(200); + fill(0); + text('Enable mic and click the mouse to begin recording', 20, 20); + + // crear una entrada de audio + mic = new p5.AudioIn(); + + // los usuarios deben manualmente permitir en su navegador que el micrófono funcione para que la grabación funcione de manera correcta + mic.start(); + + // crear un nuevo grabador de sonido + recorder = new p5.SoundRecorder(); + + // conectar el micrófono al grabador + recorder.setInput(mic); + + // crear un archivo de audio vacío que será usado para la reproducción de la grabación + soundFile = new p5.SoundFile(); +} + +function mousePressed() { + // usar el booleano '.enabled' (permitido) para asegurarse que el micrófono haya sido habilitado por el usuario (si no grabaríamos silencio) + if (state === 0 && mic.enabled) { + // indicar al grabador que grabe en el objeto p5.SoundFile, que usaremos para la reproducción + recorder.record(soundFile); + + background(255, 0, 0); + text('Recording now! Click to stop.', 20, 20); + state++; + } else if (state === 1) { + recorder.stop(); // parar el grabador, y enviar el resultado al archivo de audio soundFile + + background(0, 255, 0); + text('Recording stopped. Click to play & save', 20, 20); + state++; + } else if (state === 2) { + soundFile.play(); // reproduce el sonido + saveSound(soundFile, 'mySound.wav'); // almacena el archivo + state++; + } +} diff --git a/dist/assets/examples/es/33_Sound/21_FreqModulation.js b/dist/assets/examples/es/33_Sound/21_FreqModulation.js new file mode 100644 index 0000000000..ff8a0554d3 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/21_FreqModulation.js @@ -0,0 +1,147 @@ +/** + * @name Modulación en frecuencia + * @description

La modulación en frecuencia (FM) es una poderosa forma de síntesis. + * En su forma más simple , la FM involucra dos osciladores, referidos + * como la portadora y la modulante. Mientras la onda modulante oscila + * entre algún valor mínimo y maximo de amplitud, el valor momentáneo + * es sumado a ("modula") la frecuencia de la portadora.

+ *

La portadora es típicamente definida para oscilar a una frecuencia audible + * que percibimos como una altura — en este caso, es un oscilador sinusoidal a 220 Hz, + * equivalenta a una nota "A3". La portadora es conectada a la salida maestra por defecto + * (este es el caso para todos los objetos p5.Oscillator).

+ *

Nosotros desconectaremos la modulante de la salida maestra, + * y la conectaremos a la frecuencia de la portadora: + * carrier.freq(modulator). Esto suma la amplitud de salida de la moduante + * a la frecuencia de la portadora.

+ *

+ * La profundida de modulación describe cúanto será modulada la frecuencia de la portadora. + * Está basada en la amplitud de la modulante. + * La modulante produce un torrente continuo de valores de amplitud que sumaremos + * a la frecuencia de la portadora. Una amplitud nula (0) significa silencio, así que la modulación no tendría efecto. + * Una amplitud de 1.0 escala el rango de los valores de salida + * entre +1.0 y -1.0. Este es el rango estándar de sonido que es enviado a tus parlantes, + * pero en FM estamos enviando la salida de la modulante a la frecuencia de la portadora, + * donde casi no notaríamosla modulación +1Hz / -1Hz. + * Es por eso que típicamente aumentamos la amplitud (profundidad) de la modulante a números a muchos más altos + * que los que enviaríamos a nuestros parlantes.

+ *

La frecuencia de modulación es la velocidad de la modulación. Cuando la frecuencia de modulación es menor a + * 20Hz, dejamos de escuchar su frecuencia como una altura, y empezamos a escucharla como un ritmo pulsante. + * Por ejemplo, prueba 7.5Hz a una profundidad de 20 para imitar el efecto "vibrato" de un vocalista de ópera. + * El térmio par esto es un oscilador de baja frecuencia (LFO, Low Frequency Oscillator). Las modulantes configuradas a frecuencias más altas + * pueden también producir efectos interesantes, especialmente cuando la frecuencia tiene una relación harmónica + * con la señal portadora. Por ejemplo, escucha lo que sucede cuando la frecuencia modulante es + * la mitad o el doble de la portadora. Esto es la base de la síntesis FM, desarrollada por John Chowning + * en los años 1960s, lo que revolucionó la síntesis en los años 1980s y es a menudo utilizada para sintesizar sonidos de instrumentos metálicos de viento y campanas. + * + *

En este ejemplo,

+ * - la posición horizontal del ratón (mouseX) controla la profundidad de la modulación (la amplituda de la modulante) entre -150 y 150. + * Cuando la amplitud de la modulante es anulada (0) en la mitad del lienzo, date cuenta cómo la modulación + * no tiene efecto. A mayor (aplicando valor absoluto) el número, mayor el efecto. + * Si la forma de onda de la modulante es simétrica como una onda cuadrada [], sinusoidal ~ + * o triangular /\, la amplitud negativa será la misma que la amplitud positiva. + * Pero en este ejemplo, la modulante es una onda diente de sierra asimétrica, con una forma así /. + * Cuando la multiplicamos por un número negativo, se invierte así \. + * Para observar mejor la diferencia, baja la frecuencia. + *

+ *

- La posición vertical del ratón (mouseY) controla la frecuencia de la modulante entre 0 y 112 Hz. + * Prueba comparando frecuencias de modulación bajo el rango audible (que empieza en torno a los 20 Hz), + * y sobre él, especialmente en relación armónica a la frecuencia de la portadora (que es de 220hz, así que + * prueba con la mitad, 1/3, 1/4 etc...). + * + *

Necesitarás incluir la + * biblioteca p5.sound + * para que este ejemplo funcione en tu proyecto propio.

+ */ + +let carrier; // este es el oscilador que escucharemos, la portadora +let modulator; // este oscilador modulará la frecuencia de la portadora + +let analyzer; // lo usaremos para visualizar la forma de onda + +// la frecuencia de la portadora antes de ser modulada +let carrierBaseFreq = 220; + +// rangos mínimo y máximo para la modulante +let modMaxFreq = 112; +let modMinFreq = 0; +let modMaxDepth = 150; +let modMinDepth = -150; + +function setup() { + let cnv = createCanvas(800, 400); + noFill(); + + carrier = new p5.Oscillator('sine'); + carrier.amp(0); // definir la amplitud + carrier.freq(carrierBaseFreq); // definir la frecuencia + carrier.start(); // empezar a oscilar + + // prueba a cambiar el tipo a 'square', 'sine' or 'triangle' + modulator = new p5.Oscillator('sawtooth'); + modulator.start(); + + // suma la salida de la modulante para modular la frecuencia de la portadora + modulator.disconnect(); + carrier.freq(modulator); + + // crea una FFT para analizar el audio + analyzer = new p5.FFT(); + + // prende o apaga la portadora según si el ratón está sobre el botón de inicio o lo presiona + toggleAudio(cnv); +} + +function draw() { + background(30); + + // mapea la posición vertical del ratón (mouseY) a la frecuencia modulante entre las frecuencias mínima y máxima + let modFreq = map(mouseY, height, 0, modMinFreq, modMaxFreq); + modulator.freq(modFreq); + + // cambia la amplitud de la modulante + // la amplitud negativa pone en reversa la forma de onda diente de sierra, suena percusiva + // + let modDepth = map(mouseX, 0, width, modMinDepth, modMaxDepth); + modulator.amp(modDepth); + + // analiza la forma de onda + waveform = analyzer.waveform(); + + // dibuja la forma de onda + stroke(255); + strokeWeight(10); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); + + strokeWeight(1); + // añade una nota sobre lo que está pasando + text('Frecuencia modulante: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text( + 'Amplitud modulante (profundidad de modulación): ' + modDepth.toFixed(3), + 20, + 40 + ); + text( + 'Frecuencia portadora (antes de la modulación): ' + carrierBaseFreq + ' Hz', + width / 2, + 20 + ); +} + +// función de ayuda para prender y apagar el sonido +function toggleAudio(cnv) { + cnv.mouseOver(function() { + carrier.amp(1.0, 0.01); + }); + cnv.touchStarted(function() { + carrier.amp(1.0, 0.01); + }); + cnv.mouseOut(function() { + carrier.amp(0.0, 1.0); + }); +} diff --git a/dist/assets/examples/es/33_Sound/22_AmplitudeModulation.js b/dist/assets/examples/es/33_Sound/22_AmplitudeModulation.js new file mode 100644 index 0000000000..18065a4d07 --- /dev/null +++ b/dist/assets/examples/es/33_Sound/22_AmplitudeModulation.js @@ -0,0 +1,95 @@ +/** + * @name Modulación en amplitud + * @description

La modulación en amplitud involucra dos osciladores, referidos como + * la portadora (carrier) y la modulante, donde la modulante controla la amplitud de la portadora.

+ * + *

La portadora es típicamente definida a una frecuencia audible (por ejemplo, 440 Hz) + * y conectada a la salida maestra por defecto. La amplitud de la portadora (carrier.amp) es anulada (0) + * porque así la modulante tiene total control sobre su amplitud.

+ * + *

La modulante es desconectada de la salida maestra. En vez de eso, es conectada + * a la amplitud de la portadora, así: carrier.amp(modulator).

+ * + *

En este ejemplo:

+ *

- la posición horizontal del ratón (mouseX) contrla la amplitud de la modulante + * entre 0 y 1. Cuando la amplitud modulante es hecha 0, la + * modulación en amplitud no hace efecto.

+ * + *

- La posición vertical del ratón (mouseY) controla la frecuencia de la modulante entre 0 y 20 Hz. + * Este rango es más grave que las frecuencias que los humanos pueden escuchar, y percibimos la + * modulación como un ritmo. Este rango simula un efecto conocido como tremolo. + * La modulación en anillo (ring modulation) es un tipo de modulación en amplitud donde la + * señal portadora original no está presente, y a menudo involucra modulación a una mayor + * frecuencia.

+ * + *

Necesitarás incluir la + * biblioteca p5.sound + * para que este ejemplo funcione en tu proyecto propio.

+ */ + +let carrier; // este es el oscilador que escucharemos +let modulator; // este oscilador modulará la amplitud de la portadora +let fft; // visualizaremos la forma de onda + +function setup() { + createCanvas(800, 400); + noFill(); + background(30); // alpha + + carrier = new p5.Oscillator(); // se conecta la salida a la salida maestra por defecto + carrier.freq(340); + carrier.amp(0); + // la amplitud de la portadora es 0 por defecto, dándole así a a la modulante control total + + carrier.start(); + + modulator = new p5.Oscillator('triangle'); + modulator.disconnect(); // desconecta la moduladora de la salida maestra + modulator.freq(5); + modulator.amp(1); + modulator.start(); + + // modula la ampltiud de la portadora con la modulante + // opcionalmente, podemos escalar la señal + carrier.amp(modulator.scale(-1, 1, 1, -1)); + + // crea una FFT para analizar el audio + fft = new p5.FFT(); +} + +function draw() { + background(30, 30, 30, 100); // alpha + + // mapea la posición vertical del ratón (mouseY) a la frecuencia de la modulante entre 0 y 20 Hz + let modFreq = map(mouseY, 0, height, 20, 0); + modulator.freq(modFreq); + + let modAmp = map(mouseX, 0, width, 0, 1); + modulator.amp(modAmp, 0.01); // tiempo de transición de 0.1 para mayor suavidad + + // analiza la forma de onda + waveform = fft.waveform(); + + // dibuja la forma de onda + drawWaveform(); + + drawText(modFreq, modAmp); +} + +function drawWaveform() { + stroke(240); + strokeWeight(4); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); +} + +function drawText(modFreq, modAmp) { + strokeWeight(1); + text('Modulator Frequency: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text('Modulator Amplitude: ' + modAmp.toFixed(3), 20, 40); +} diff --git a/dist/assets/examples/es/35_Mobile/00_Acceleration_Ball_Bounce.js b/dist/assets/examples/es/35_Mobile/00_Acceleration_Ball_Bounce.js new file mode 100644 index 0000000000..50d34cc00b --- /dev/null +++ b/dist/assets/examples/es/35_Mobile/00_Acceleration_Ball_Bounce.js @@ -0,0 +1,58 @@ +/* + * @name Pelota rebote aceleración + * @description Mueve una elipse basado en los valores de aceleración en x y en y (accelerationX, accelerationY) y rebota cuando toca el borde del lienzo. + */ + +// variables de posición +let x = 0; +let y = 0; + +// velocidad +let vx = 0; +let vy = 0; + +// aceleración +let ax = 0; +let ay = 0; + +let vMultiplier = 0.007; +let bMultiplier = 0.6; + +function setup() { + createCanvas(displayWidth, displayHeight); + fill(0); +} + +function draw() { + background(255); + ballMove(); + ellipse(x, y, 30, 30); +} + +function ballMove() { + ax = accelerationX; + ay = accelerationY; + + vx = vx + ay; + vy = vy + ax; + y = y + vy * vMultiplier; + x = x + vx * vMultiplier; + + // rebotar cuando tocar el borde del lienzo + if (x < 0) { + x = 0; + vx = -vx * bMultiplier; + } + if (y < 0) { + y = 0; + vy = -vy * bMultiplier; + } + if (x > width - 20) { + x = width - 20; + vx = -vx * bMultiplier; + } + if (y > height - 20) { + y = height - 20; + vy = -vy * bMultiplier; + } +} diff --git a/dist/assets/examples/es/35_Mobile/01_Simple_Draw.js b/dist/assets/examples/es/35_Mobile/01_Simple_Draw.js new file mode 100644 index 0000000000..5fbfc95364 --- /dev/null +++ b/dist/assets/examples/es/35_Mobile/01_Simple_Draw.js @@ -0,0 +1,15 @@ +/* + * @name Dibujo simple + * @description Toca para dibujar en la pantalla usando los valores de posición x e y de toque actual y anterior (mouseX, mouseY, pmouseX, pmouseY). + */ + +function setup() { + createCanvas(displayWidth, displayHeight); + strokeWeight(10); + stroke(0); +} + +function touchMoved() { + line(mouseX, mouseY, pmouseX, pmouseY); + return false; +} diff --git a/dist/assets/examples/es/35_Mobile/02_Acceleration_Color.js b/dist/assets/examples/es/35_Mobile/02_Acceleration_Color.js new file mode 100644 index 0000000000..35f9498c6b --- /dev/null +++ b/dist/assets/examples/es/35_Mobile/02_Acceleration_Color.js @@ -0,0 +1,24 @@ +/* + * @name Aceleración y color + * @description Usar la función deviceMoved() para detectar la rotación del dispositivo. Los valores RGB del fondo son mapeados a los valores de aceleración en los ejes x, y,z (accelerationX, accelerationY,accelerationZ). + */ + +let r, g, b; + +function setup() { + createCanvas(displayWidth, displayHeight); + r = random(50, 255); + g = random(0, 200); + b = random(50, 255); +} + +function draw() { + background(r, g, b); + console.log('draw'); +} + +function deviceMoved() { + r = map(accelerationX, -90, 90, 100, 175); + g = map(accelerationY, -90, 90, 100, 200); + b = map(accelerationZ, -90, 90, 100, 200); +} diff --git a/dist/assets/examples/es/35_Mobile/03_Shake_Ball_Bounce.js b/dist/assets/examples/es/35_Mobile/03_Shake_Ball_Bounce.js new file mode 100644 index 0000000000..9e49ffe0b7 --- /dev/null +++ b/dist/assets/examples/es/35_Mobile/03_Shake_Ball_Bounce.js @@ -0,0 +1,114 @@ +/* + * @name Pelota rebote agitar + * @description Crea una clase Ball, instancia múltiples objetos, múevelos alrededor de la pantalla, que reboten cuando toquen el borde del lienzo. + * Detectar el evento agitar basado en el cambio total de aceleración en los ejes x e y (accelerationX, accelerationY) y aumenta o disminuye su velocidad basado en la detección. + */ + +let balls = []; + +let threshold = 30; +let accChangeX = 0; +let accChangeY = 0; +let accChangeT = 0; + +function setup() { + createCanvas(displayWidth, displayHeight); + + for (let i = 0; i < 20; i++) { + balls.push(new Ball()); + } +} + +function draw() { + background(0); + + for (let i = 0; i < balls.length; i++) { + balls[i].move(); + balls[i].display(); + } + + checkForShake(); +} + +function checkForShake() { + // Calcular cambio total de aceleración en x e y, (accelerationX, accelerationY) + accChangeX = abs(accelerationX - pAccelerationX); + accChangeY = abs(accelerationY - pAccelerationY); + accChangeT = accChangeX + accChangeY; + // Si hay agitamiento + if (accChangeT >= threshold) { + for (let i = 0; i < balls.length; i++) { + balls[i].shake(); + balls[i].turn(); + } + } + // Si no hay + else { + for (let i = 0; i < balls.length; i++) { + balls[i].stopShake(); + balls[i].turn(); + balls[i].move(); + } + } +} + +// clase Ball +class Ball { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.xspeed = random(-2, 2); + this.yspeed = random(-2, 2); + this.oxspeed = this.xspeed; + this.oyspeed = this.yspeed; + this.direction = 0.7; + } + + move() { + this.x += this.xspeed * this.direction; + this.y += this.yspeed * this.direction; + } + + // Rebota cuando toca el borde del lienzo + turn() { + if (this.x < 0) { + this.x = 0; + this.direction = -this.direction; + } else if (this.y < 0) { + this.y = 0; + this.direction = -this.direction; + } else if (this.x > width - 20) { + this.x = width - 20; + this.direction = -this.direction; + } else if (this.y > height - 20) { + this.y = height - 20; + this.direction = -this.direction; + } + } + + // Cambia la velocidad en x e y (xspeed, yspeed) según + // el cambio en el valor de la aceleración en x, accelerationX + shake() { + this.xspeed += random(5, accChangeX / 3); + this.yspeed += random(5, accChangeX / 3); + } + + // Desacelera gradualmente + stopShake() { + if (this.xspeed > this.oxspeed) { + this.xspeed -= 0.6; + } else { + this.xspeed = this.oxspeed; + } + if (this.yspeed > this.oyspeed) { + this.yspeed -= 0.6; + } else { + this.yspeed = this.oyspeed; + } + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/es/35_Mobile/04_Tilted_3D_Box.js b/dist/assets/examples/es/35_Mobile/04_Tilted_3D_Box.js new file mode 100644 index 0000000000..3abf35da45 --- /dev/null +++ b/dist/assets/examples/es/35_Mobile/04_Tilted_3D_Box.js @@ -0,0 +1,15 @@ +/* + * @name Caja 3D + * @description Usar dispositivo móvil para inclinar una caja + */ +function setup() { + createCanvas(displayWidth, displayHeight, WEBGL); +} + +function draw() { + background(250); + normalMaterial(); + rotateX(accelerationX * 0.01); + rotateY(accelerationY * 0.01); + box(100, 100, 100); +} diff --git a/dist/assets/examples/es/90_Hello_P5/01_shapes.js b/dist/assets/examples/es/90_Hello_P5/01_shapes.js new file mode 100644 index 0000000000..35fc294b57 --- /dev/null +++ b/dist/assets/examples/es/90_Hello_P5/01_shapes.js @@ -0,0 +1,28 @@ +/* + * @name Figuras simples + * @description Este ejemplo incluye una elipse, un rectángulo, un triángulo y una flor. + */ +function setup() { + // crear el lienzo + createCanvas(720, 400); + background(200); + + // Definir colores + fill(204, 101, 192, 127); + stroke(127, 63, 120); + + // Un rectángulo + rect(40, 120, 120, 40); + // Una elipse + ellipse(240, 240, 80, 80); + // Un triángulo + triangle(300, 100, 320, 100, 310, 80); + + // Un diseño de una flor simple + translate(580, 200); + noStroke(); + for (let i = 0; i < 10; i ++) { + ellipse(0, 30, 20, 80); + rotate(PI/5); + } +} diff --git a/dist/assets/examples/es/90_Hello_P5/02_interactivity.js b/dist/assets/examples/es/90_Hello_P5/02_interactivity.js new file mode 100644 index 0000000000..24bdb12b30 --- /dev/null +++ b/dist/assets/examples/es/90_Hello_P5/02_interactivity.js @@ -0,0 +1,37 @@ +/* + * @name Interactividad 1 + * @frame 720,425 + * @description El círculo cambia de color cuando ahces click en él. + */ + +// variables para los valores de rojo, verde y azul (r, g, b) +let r, g, b; + +function setup() { + createCanvas(720, 400); + // colores aleatorios + r = random(255); + g = random(255); + b = random(255); +} + +function draw() { + background(127); + // dibujar el círculo + strokeWeight(2); + stroke(r, g, b); + fill(r, g, b, 127); + ellipse(360, 200, 200, 200); +} + +// cuando el usuario hace click +function mousePressed() { + // revisar si el ratón está dentro del círculo + let d = dist(mouseX, mouseY, 360, 200); + if (d < 100) { + // escoger nuevos colores aleatorios + r = random(255); + g = random(255); + b = random(255); + } +} diff --git a/dist/assets/examples/es/90_Hello_P5/03_interactivity.js b/dist/assets/examples/es/90_Hello_P5/03_interactivity.js new file mode 100644 index 0000000000..4fa554c275 --- /dev/null +++ b/dist/assets/examples/es/90_Hello_P5/03_interactivity.js @@ -0,0 +1,26 @@ +/* + * @name Interactividad 2 + * @frame 720,425 + * @description El círculo cambia de color cuando mueves la barra deslizante. + */ + +// Una barra deslizante de rango HTML +let slider; + +function setup() { + createCanvas(720, 400); + // Tinte, saturación, brillo + colorMode(HSB, 255); + // La barra deslizante tiene un valor entre 0 y 255 con un valor inicial de 127 + slider = createSlider(0, 255, 127); +} + +function draw() { + background(127); + strokeWeight(2); + + // Definir el tinte según la barra deslizante + stroke(slider.value(), 255, 255); + fill(slider.value(), 255, 255, 127); + ellipse(360, 200, 200, 200); +} diff --git a/dist/assets/examples/es/90_Hello_P5/04_animate.js b/dist/assets/examples/es/90_Hello_P5/04_animate.js new file mode 100644 index 0000000000..32d81aa18e --- /dev/null +++ b/dist/assets/examples/es/90_Hello_P5/04_animate.js @@ -0,0 +1,32 @@ +/* + * @name Animación + * @description El círculo se mueve + */ +// posición del círculo +let x, y; + +function setup() { + createCanvas(720, 400); + // empieza en el centro + x = width / 2; + y = height; +} + +function draw() { + background(200); + + // dibujar el círculo + stroke(50); + fill(100); + ellipse(x, y, 24, 24); + + // moverse aleatoriamente en el eje x + x = x + random(-1, 1); + // mover hacia arriba a velocidad constante + y = y - 1; + + // reset al fondo + if (y < 0) { + y = height; + } +} diff --git a/dist/assets/examples/es/90_Hello_P5/04_flocking.js b/dist/assets/examples/es/90_Hello_P5/04_flocking.js new file mode 100644 index 0000000000..15198abaf5 --- /dev/null +++ b/dist/assets/examples/es/90_Hello_P5/04_flocking.js @@ -0,0 +1,184 @@ +/* + * @name Flocking + * @description Demostración del comportamiento "Flocking" según Craig Reynolds.
+ * (Reglas: cohesión, separación, alineamiento.)
+ * Extraído de natureofcode.com. + */ +let boids = []; + +function setup() { + createCanvas(720, 400); + + // Agregar un conjunto inicial de boids al sistema + for (let i = 0; i < 100; i++) { + boids[i] = new Boid(random(width), random(height)); + } +} + +function draw() { + background(51); + // Ejecutar todos los boids + for (let i = 0; i < boids.length; i++) { + boids[i].run(boids); + } +} + +// clase Boid +// Métodos para separación, cohesión y alineamiento +class Boid { + constructor(x,y) { + this.acceleration = createVector(0, 0); + this.velocity = p5.Vector.random2D(); + this.position = createVector(x, y); + this.r = 3.0; + this.maxspeed = 3; // velocidad máxima + this.maxforce = 0.05; // fuerza máxima de viraje + } + + run(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); + } + + // las fuerzas son añadidas a la aceleración + applyForce(force) { + this.acceleration.add(force); + } + + // acumulamos una nueva aceleración cada vez que el tiempo pasa, basado en tres reglas + flock(boids) { + let sep = this.separate(boids); // separación + let ali = this.align(boids); // alineamiento + let coh = this.cohesion(boids); // cohesión + // darle un peso arbitrario a las fuerzas + sep.mult(2.5); + ali.mult(1.0); + coh.mult(1.0); + // añade los vectores de fuerza a la aceleración + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); + } + + // método para actualizar ubicación + update() { + // actualizar velocidad + this.velocity.add(this.acceleration); + // limitar velocidad + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // resetear aceleración a 0 en cada ciclo + this.acceleration.mult(0); + } + + // un método que aplica y calcula una fuera de viraje a un objetivo + // viraje = deseado - velocidad + seek(target) { + let desired = p5.Vector.sub(target, this.position); // un vector apuntanto desde la ubicación y hacia el objetivo + // normalizar deseado y escalar a velocidad máxima + desired.normalize(); + desired.mult(this.maxspeed); + // viraje = deseado menos velocidad + let steer = p5.Vector.sub(desired, this.velocity); + steer.limit(this.maxforce); // limitar a la fuerza máxima de viraje + return steer; + } + + // dibujar el boid como un círculo + render() { + fill(127, 127); + stroke(200); + ellipse(this.position.x, this.position.y, 16, 16); + } + + // wraparound, si se llega a un borde, aparecer por el borde opuesto + borders() { + if (this.position.x < -this.r) this.position.x = width + this.r; + if (this.position.y < -this.r) this.position.y = height + this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height + this.r) this.position.y = -this.r; + } + + // separación + // método que revisa si hay boids cercanos y vira para alejarse de ellos + separate(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // por cada boid en el sistema, revisar si está muy cerca + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + // si la distancia es mayor a 0 y menor que un tamaño arbitrario (0 cuando es sí mismo) + if ((d > 0) && (d < desiredseparation)) { + // calcular vector apuntando para alejarse del vecino + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // peso según distancia + steer.add(diff); + count++; // contar cuántos + } + } + // promedio -- dividir por la cantidad + if (count > 0) { + steer.div(count); + } + + // mientas el vector sea mayor que 0 + if (steer.mag() > 0) { + // implementar Reynolds: viraje = deseado - velocidad + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; + } + + // alineamiento + // por cada boid cercano en el sistema, calcular la velocidad promedio + align(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } + } + + // cohesión + // Para la ubicación promedio (centro) de todos los boids vecinos, calcular el vector de viraje hacia esa ubicación + cohesion(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // empezar con un vector vacío para acumular todas las ubicaciones + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // Agregar ubicación + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // Virar hacia la ubicación + } else { + return createVector(0, 0); + } + } +} diff --git a/dist/assets/examples/es/90_Hello_P5/05_weather.js b/dist/assets/examples/es/90_Hello_P5/05_weather.js new file mode 100644 index 0000000000..0745826388 --- /dev/null +++ b/dist/assets/examples/es/90_Hello_P5/05_weather.js @@ -0,0 +1,72 @@ +/* + * @name Clima + * @frame 720,280 + * @description Este ejemplo usa datos de clima en formato JSON desde www.metaweather.com. +*/ + +// un vector de dirección de viento +let wind; +// posición del círculo +let position; + +function setup() { + createCanvas(720, 200); + // pedir datos a metaweather.com + let url = 'https://cors-anywhere.herokuapp.com/https://www.metaweather.com/api/location/2459115/'; + loadJSON(url, gotWeather); + // el círculo empieza en el centro + position = createVector(width/2, height/2); + // el viento empieza en (0, 0) + wind = createVector(); +} + +function draw() { + background(200); + + // esta sección dibuja una flecha apuntando en la dirección del viento + push(); + translate(32, height - 32); + // rotar según el ángulo del viento + rotate(wind.heading() + PI/2); + noStroke(); + fill(255); + ellipse(0, 0, 48, 48); + + stroke(45, 123, 182); + strokeWeight(3); + line(0, -16, 0, 16); + + noStroke(); + fill(45, 123, 182); + triangle(0, -18, -6, -10, 6, -10); + pop(); + + // mover en la dirección del viento + position.add(wind); + + stroke(0); + fill(51); + ellipse(position.x, position.y, 16, 16); + + if (position.x > width) position.x = 0; + if (position.x < 0) position.x = width; + if (position.y > height) position.y = 0; + if (position.y < 0) position.y = height; + + +} + +function gotWeather(weather) { + let weather_today = weather.consolidated_weather[0] + // obtener el ángulo (convertir a radianes) + let angle = radians(Number(weather_today.wind_direction)); + // obtener la velocidad del viento + let windmag = Number(weather_today.wind_speed); + + // mostrar como elementos HTML + let temperatureDiv = createDiv(floor(weather_today.the_temp) + '°C'); + let windDiv = createDiv("WIND " + windmag + " MPH"); + + // hacer un vector + wind = p5.Vector.fromAngle(angle); +} diff --git a/dist/assets/examples/es/90_Hello_P5/06_drawing.js b/dist/assets/examples/es/90_Hello_P5/06_drawing.js new file mode 100644 index 0000000000..e5a7521a39 --- /dev/null +++ b/dist/assets/examples/es/90_Hello_P5/06_drawing.js @@ -0,0 +1,133 @@ +/* +* @name Dibujar +* @description Programa de pintura generativa. +*/ + +// todos los caminos +let paths = []; +// si estamos pintando o no +let painting = false; +// cuánto tiempo pasa antes de hacer el siguiente círculo +let next = 0; +// dónde estamos ahora y donde estuvimos antes +let current; +let previous; + +function setup() { + createCanvas(720, 400); + current = createVector(0,0); + previous = createVector(0,0); +}; + +function draw() { + background(200); + + // si es tiempo de hacer un nuevo punto + if (millis() > next && painting) { + + // obtener posición del ratón + current.x = mouseX; + current.y = mouseY; + + // la fuerza de la nueva partícula depende del movimiento del ratón + let force = p5.Vector.sub(current, previous); + force.mult(0.05); + + // añadir nueva partícula + paths[paths.length - 1].add(current, force); + + // programar el siguiente círculo + next = millis() + random(100); + + // Guardar las posiciones del ratón + previous.x = current.x; + previous.y = current.y; + } + + // dibujar todos los caminos + for( let i = 0; i < paths.length; i++) { + paths[i].update(); + paths[i].display(); + } +} + +// empezar +function mousePressed() { + next = 0; + painting = true; + previous.x = mouseX; + previous.y = mouseY; + paths.push(new Path()); +} + +// parar +function mouseReleased() { + painting = false; +} + +// un camino Path es una lista de partículas +class Path { + constructor() { + this.particles = []; + this.hue = random(100); + } + + add(position, force) { + // agregar una nueva partícula con una posición, fuerza y tinte + this.particles.push(new Particle(position, force, this.hue)); + } + + // mostrar camino + update() { + for (let i = 0; i < this.particles.length; i++) { + this.particles[i].update(); + } + } + + // mostrar camino + display() { + + // iterar sobre el camino de atrás hacia adelante + for (let i = this.particles.length - 1; i >= 0; i--) { + // si debemos removerlo + if (this.particles[i].lifespan <= 0) { + this.particles.splice(i, 1); + // si no, mostrarlo en pantalla + } else { + this.particles[i].display(this.particles[i+1]); + } + } + } +} + +// partículas en el camino +class Particle { + constructor(position, force, hue) { + this.position = createVector(position.x, position.y); + this.velocity = createVector(force.x, force.y); + this.drag = 0.95; + this.lifespan = 255; + } + + update() { + // muévela + this.position.add(this.velocity); + // disminuye su velocidad + this.velocity.mult(this.drag); + // hazla más transparente + this.lifespan--; + } + + // dibujar una partícula y conectarla con una línea + // dibuja una línea a otra + display(other) { + stroke(0, this.lifespan); + fill(0, this.lifespan/2); + ellipse(this.position.x,this.position.y, 8, 8); + // si necesitamos dibujar otra línea + if (other) { + line(this.position.x, this.position.y, other.position.x, other.position.y); + } + } +} + diff --git a/dist/assets/examples/es/90_Hello_P5/07_song.js b/dist/assets/examples/es/90_Hello_P5/07_song.js new file mode 100644 index 0000000000..f0fe774272 --- /dev/null +++ b/dist/assets/examples/es/90_Hello_P5/07_song.js @@ -0,0 +1,120 @@ +/* + * @name Canción + * @frame 720, 430 + * @description Toca una canción. + * Necesitarás incluir la + * biblioteca p5.sound + * a este ejemplo para que corra en tu máquina. +*/ + +// las notas midi de una escala +let notes = [ 60, 62, 64, 65, 67, 69, 71]; + +// para tocar la canción de forma automática +let index = 0; +let song = [ + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 200, display: "G" }, + { note: 1, duration: 200, display: "A" }, + { note: 2, duration: 200, display: "B" }, + { note: 3, duration: 200, display: "C" }, + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 400, display: "G" }, + { note: 0, duration: 400, display: "G" } +]; +let trigger = 0; +let autoplay = false; +let osc; + +function setup() { + createCanvas(720, 400); + let div = createDiv("Haz click para tocar las notas") + div.id("instructions"); + let button = createButton("toca la canción automáticamente."); + button.parent("instructions"); + // gatillar la reproducción automática + button.mousePressed(function() { + if (!autoplay) { + index = 0; + autoplay = true; + } + }); + + // un oscilador de onda triangular + osc = new p5.TriOsc(); + // empezar en silencio + osc.start(); + osc.amp(0); +} + +// una función para tocar una nota +function playNote(note, duration) { + osc.freq(midiToFreq(note)); + // aparición gradual + osc.fade(0.5,0.2); + + // si definimos una duración, apagar gradualmente + if (duration) { + setTimeout(function() { + osc.fade(0,0.2); + }, duration-50); + } +} + +function draw() { + + // Si estamos tocando automáticamente y es tiempo de tocar la siguiente nota + if (autoplay && millis() > trigger){ + playNote(notes[song[index].note], song[index].duration); + trigger = millis() + song[index].duration; + // ir a la siguiente nota + index ++; + // cuando llegamos al final, dejar de tocar en automático + } else if (index >= song.length) { + autoplay = false; + } + + + // dibujar un teclado + + // el ancho de cada tecla + let w = width / notes.length; + for (let i = 0; i < notes.length; i++) { + let x = i * w; + // si el ratón está sobre la tecla + if (mouseX > x && mouseX < x + w && mouseY < height) { + // si estamos haciendo click + if (mouseIsPressed) { + fill(100,255,200); + // o solamente estamos sobre ella + } else { + fill(127); + } + } else { + fill(200); + } + + // si estamos tocando la canción, resaltemos + if (autoplay && i === song[index-1].note) { + fill(100,255,200); + } + + // dibujar la tecla + rect(x, 0, w-1, height-1); + } + +} + +// cuando hacemos click +function mousePressed(event) { + if(event.button == 0 && event.clientX < width && event.clientY < height) { + // mapear el ratón al índice de la tecla + let key = floor(map(mouseX, 0, width, 0, notes.length)); + playNote(notes[key]); + } +} + +// Disminuye gradualmente cuando soltamos el botón del ratón +function mouseReleased() { + osc.fade(0,0.5); +} diff --git a/dist/assets/examples/example.html b/dist/assets/examples/example.html new file mode 100644 index 0000000000..e093b6ba56 --- /dev/null +++ b/dist/assets/examples/example.html @@ -0,0 +1,19 @@ + + + + + + + + +
+ + + diff --git a/dist/assets/examples/hi/00_Structure/00_Coordinates.js b/dist/assets/examples/hi/00_Structure/00_Coordinates.js new file mode 100644 index 0000000000..fe8eb5b4a8 --- /dev/null +++ b/dist/assets/examples/hi/00_Structure/00_Coordinates.js @@ -0,0 +1,39 @@ +/* + * @name निर्देशांक + * @description स्क्रीन पर खींची गई सभी आकृतियों में एक स्थिति होती है जो है + * एक समन्वय के रूप में निर्दिष्ट। सभी निर्देशांकों को से दूरी के रूप में मापा जाता है + * पिक्सेल की इकाइयों में उत्पत्ति। मूल [0, 0] में निर्देशांक है + * खिड़की के ऊपरी बाएँ और निचले दाएँ में निर्देशांक [चौड़ाई -1, + * ऊंचाई -1]। + */ +function setup() { + // Sets the screen to be 720 pixels wide and 400 pixels high + createCanvas(720, 400); +} + +function draw() { + // Set the background to black and turn off the fill color + background(0); + noFill(); + + // The two parameters of the point() method each specify + // coordinates. + // The first parameter is the x-coordinate and the second is the Y + stroke(255); + point(width * 0.5, height * 0.5); + point(width * 0.5, height * 0.25); + + // Coordinates are used for drawing all shapes, not just points. + // Parameters for different functions are used for different + // purposes. For example, the first two parameters to line() + // specify the coordinates of the first endpoint and the second + // two parameters specify the second endpoint + stroke(0, 153, 255); + line(0, height * 0.33, width, height * 0.33); + + // By default, the first two parameters to rect() are the + // coordinates of the upper-left corner and the second pair + // is the width and height + stroke(255, 153, 0); + rect(width * 0.25, height * 0.1, width * 0.5, height * 0.8); +} diff --git a/dist/assets/examples/hi/00_Structure/01_Width_and_Height.js b/dist/assets/examples/hi/00_Structure/01_Width_and_Height.js new file mode 100644 index 0000000000..550c70eb9c --- /dev/null +++ b/dist/assets/examples/hi/00_Structure/01_Width_and_Height.js @@ -0,0 +1,20 @@ +/* + * @name चौड़ाई और ऊंचाई + * @description 'चौड़ाई' और 'ऊंचाई' चर में शामिल हैं + * createCanvas () में परिभाषित डिस्प्ले विंडो की चौड़ाई और ऊंचाई + * समारोह। + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(127); + noStroke(); + for (let i = 0; i < height; i += 20) { + fill(129, 206, 15); + rect(0, i, width, 10); + fill(255); + rect(i, 0, 10, height); + } +} diff --git a/dist/assets/examples/hi/00_Structure/02_Setup_and_Draw.js b/dist/assets/examples/hi/00_Structure/02_Setup_and_Draw.js new file mode 100644 index 0000000000..5838e8aab9 --- /dev/null +++ b/dist/assets/examples/hi/00_Structure/02_Setup_and_Draw.js @@ -0,0 +1,27 @@ +/* + * @name सेटअप और ड्रा + * @description ड्रा () फ़ंक्शन के अंदर का कोड ऊपर से लगातार चलता है + * कार्यक्रम बंद होने तक नीचे तक। + */ +let y = 100; + +// The statements in the setup() function +// execute once when the program begins +function setup() { + // createCanvas must be the first statement + createCanvas(720, 400); + stroke(255); // Set line drawing color to white + frameRate(30); +} +// The statements in draw() are executed until the +// program is stopped. Each statement is executed in +// sequence and after the last line is read, the first +// line is executed again. +function draw() { + background(0); // Set the background to black + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/hi/00_Structure/03_No_Loop.js b/dist/assets/examples/hi/00_Structure/03_No_Loop.js new file mode 100644 index 0000000000..dd7f0f0dd6 --- /dev/null +++ b/dist/assets/examples/hi/00_Structure/03_No_Loop.js @@ -0,0 +1,30 @@ +/* + * @name और ड्रा + * @description ड्रा () फ़ंक्शन + * योजना बनने तक तक। + */ +let y; + +// The statements in the setup() function +// execute once when the program begins +function setup() { + // createCanvas should be the first statement + createCanvas(720, 400); + stroke(255); // Set line drawing color to white + noLoop(); + + y = height * 0.5; +} + +// The statements in draw() are executed until the +// program is stopped. Each statement is executed in +// sequence and after the last line is read, the first +// line is executed again. +function draw() { + background(0); // Set the background to black + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/hi/00_Structure/04_Loop.js b/dist/assets/examples/hi/00_Structure/04_Loop.js new file mode 100644 index 0000000000..5edeb7c0bb --- /dev/null +++ b/dist/assets/examples/hi/00_Structure/04_Loop.js @@ -0,0 +1,26 @@ +/* + * @name लूप + * @description ड्रा () फ़ंक्शन के अंदर का कोड ऊपर से लगातार चलता है + * कार्यक्रम बंद होने तक नीचे तक। + */ +let y = 100; + +// The statements in the setup() function +// execute once when the program begins +function setup() { + createCanvas(720, 400); // Size must be the first statement + stroke(255); // Set line drawing color to white + frameRate(30); +} +// The statements in draw() are executed until the +// program is stopped. Each statement is executed in +// sequence and after the last line is read, the first +// line is executed again. +function draw() { + background(0); // Set the background to black + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/hi/00_Structure/05_Redraw.js b/dist/assets/examples/hi/00_Structure/05_Redraw.js new file mode 100644 index 0000000000..5ed2d392e6 --- /dev/null +++ b/dist/assets/examples/hi/00_Structure/05_Redraw.js @@ -0,0 +1,33 @@ +/* + * @name रेड्रा + * @description रेड्रा () फ़ंक्शन ड्रा () को एक बार निष्पादित करता है। इस उदाहरण में, + * ड्रा () को हर बार माउस क्लिक करने पर एक बार निष्पादित किया जाता है। + */ + +let y; + +// The statements in the setup() function +// execute once when the program begins +function setup() { + createCanvas(720, 400); + stroke(255); + noLoop(); + y = height * 0.5; +} + +// The statements in draw() are executed until the +// program is stopped. Each statement is executed in +// sequence and after the last line is read, the first +// line is executed again. +function draw() { + background(0); + y = y - 4; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} + +function mousePressed() { + redraw(); +} diff --git a/dist/assets/examples/hi/00_Structure/06_Functions.js b/dist/assets/examples/hi/00_Structure/06_Functions.js new file mode 100644 index 0000000000..60f420429f --- /dev/null +++ b/dist/assets/examples/hi/00_Structure/06_Functions.js @@ -0,0 +1,28 @@ +/* + *@name कार्य + *@description DrawTarget () फ़ंक्शन कई अलग-अलग आकर्षित करना आसान बनाता है + *लक्ष्य। DrawTarget () के लिए प्रत्येक कॉल की स्थिति, आकार और संख्या निर्दिष्ट करता है + * प्रत्येक लक्ष्य के लिए बजता है। + */ + +function setup() { + createCanvas(720, 400); + background(51); + noStroke(); + noLoop(); +} + +function draw() { + drawTarget(width * 0.25, height * 0.4, 200, 4); + drawTarget(width * 0.5, height * 0.5, 300, 10); + drawTarget(width * 0.75, height * 0.3, 120, 6); +} + +function drawTarget(xloc, yloc, size, num) { + const grayvalues = 255 / num; + const steps = size / num; + for (let i = 0; i < num; i++) { + fill(i * grayvalues); + ellipse(xloc, yloc, size - i * steps, size - i * steps); + } +} diff --git a/dist/assets/examples/hi/00_Structure/07_Recursion.js b/dist/assets/examples/hi/00_Structure/07_Recursion.js new file mode 100644 index 0000000000..cc8ec10c88 --- /dev/null +++ b/dist/assets/examples/hi/00_Structure/07_Recursion.js @@ -0,0 +1,27 @@ +/* + *@name रिकर्सन + *@description रिकर्सन का एक प्रदर्शन, जिसका अर्थ है कि फ़ंक्शन स्वयं को कॉल करते हैं। + * ध्यान दें कि कैसे drawCircle () फ़ंक्शन अपने ब्लॉक के अंत में खुद को कॉल करता है। + * यह तब तक करना जारी रखता है जब तक कि चर "स्तर" 1 के बराबर न हो जाए। + */ + +function setup() { + createCanvas(720, 560); + noStroke(); + noLoop(); +} + +function draw() { + drawCircle(width / 2, 280, 6); +} + +function drawCircle(x, radius, level) { + const tt = (126 * level) / 4.0; + fill(tt); + ellipse(x, height / 2, radius * 2, radius * 2); + if (level > 1) { + level = level - 1; + drawCircle(x - radius / 2, radius / 2, level); + drawCircle(x + radius / 2, radius / 2, level); + } +} diff --git a/dist/assets/examples/hi/00_Structure/08_Create_Graphics.js b/dist/assets/examples/hi/00_Structure/08_Create_Graphics.js new file mode 100644 index 0000000000..883b19db79 --- /dev/null +++ b/dist/assets/examples/hi/00_Structure/08_Create_Graphics.js @@ -0,0 +1,29 @@ +/* + * @name ग्राफिक्स बनाएं + * @description एक नया p5.Renderer ऑब्जेक्ट बनाता और लौटाता है। इस का उपयोग करें + * वर्ग यदि आपको ऑफ-स्क्रीन ग्राफिक्स बफर में आकर्षित करने की आवश्यकता है। दो पैरामीटर + * पिक्सल में चौड़ाई और ऊंचाई को परिभाषित करें। + */ + +let pg; + +function setup() { + createCanvas(710, 400); + pg = createGraphics(400, 250); +} + +function draw() { + fill(0, 12); + rect(0, 0, width, height); + fill(255); + noStroke(); + ellipse(mouseX, mouseY, 60, 60); + + pg.background(51); + pg.noFill(); + pg.stroke(255); + pg.ellipse(mouseX - 150, mouseY - 75, 60, 60); + + //Draw the offscreen buffer to the screen with image() + image(pg, 150, 75); +} diff --git a/dist/assets/examples/hi/01_Form/00_Points_and_Lines.js b/dist/assets/examples/hi/01_Form/00_Points_and_Lines.js new file mode 100644 index 0000000000..c68ade9622 --- /dev/null +++ b/dist/assets/examples/hi/01_Form/00_Points_and_Lines.js @@ -0,0 +1,36 @@ +/* + * @name अंक और रेखाएं + * @description पॉइंट्स और लाइन्स का इस्तेमाल बेसिक ज्योमेट्री ड्रा करने के लिए किया जा सकता है। + * फॉर्म को स्केल करने के लिए वेरिएबल 'd' का मान बदलें। चार + * चर 'डी' के मान के आधार पर स्थिति निर्धारित करते हैं। + */ +function setup() { + let d = 70; + let p1 = d; + let p2 = p1 + d; + let p3 = p2 + d; + let p4 = p3 + d; + + // स्क्रीन को 720 पिक्सल चौड़ा और 400 पिक्सल ऊंचा सेट करता है + createCanvas(720, 400); + background(0); + noSmooth(); + + translate(140, 0); + + // ग्रे बॉक्स बनाएं + stroke(153); + line(p3, p3, p2, p3); + line(p2, p3, p2, p2); + line(p2, p2, p3, p2); + line(p3, p2, p3, p3); + + // सफेद बिंदु बनाएं + stroke(255); + point(p1, p1); + point(p1, p3); + point(p2, p4); + point(p3, p1); + point(p4, p2); + point(p4, p4); +} diff --git a/dist/assets/examples/hi/01_Form/01_Shape_Primitives.js b/dist/assets/examples/hi/01_Form/01_Shape_Primitives.js new file mode 100644 index 0000000000..b70f7e404c --- /dev/null +++ b/dist/assets/examples/hi/01_Form/01_Shape_Primitives.js @@ -0,0 +1,31 @@ +/* + * @name शेप प्रिमिटिव्स + * @description मूल आकार के आदिम कार्य triangle() हैं, + * rect(), quad(), ellipse(), और arc()। वर्ग रेक्ट के साथ बने होते हैं () + * और ellipse() से बनाए जाते हैं। इन कार्यों में से प्रत्येक की आवश्यकता है + * आकार की स्थिति और आकार निर्धारित करने के लिए कई पैरामीटर। + */ +function setup() { + // स्क्रीन को 720 पिक्सल चौड़ा और 400 पिक्सल ऊंचा सेट करता है + createCanvas(720, 400); + background(0); + noStroke(); + + fill(204); + triangle(18, 18, 18, 360, 81, 360); + + fill(102); + rect(81, 81, 63, 63); + + fill(204); + quad(189, 18, 216, 18, 216, 360, 144, 360); + + fill(255); + ellipse(252, 144, 72, 72); + + fill(204); + triangle(288, 18, 351, 360, 288, 360); + + fill(255); + arc(479, 300, 280, 280, PI, TWO_PI); +} diff --git a/dist/assets/examples/hi/01_Form/02_Pie_Chart.js b/dist/assets/examples/hi/01_Form/02_Pie_Chart.js new file mode 100644 index 0000000000..1240e9dda2 --- /dev/null +++ b/dist/assets/examples/hi/01_Form/02_Pie_Chart.js @@ -0,0 +1,34 @@ +/* + * @name पाई चार्ट + * @description डेटा से पाई चार्ट बनाने के लिए arc() फ़ंक्शन का उपयोग करता है + * एक सरणी में संग्रहीत। + */ +let angles = [30, 10, 45, 35, 60, 38, 75, 67]; + +function setup() { + createCanvas(720, 400); + noStroke(); + noLoop(); // एक बार दौड़ें और रुकें +} + +function draw() { + background(100); + pieChart(300, angles); +} + +function pieChart(diameter, data) { + let lastAngle = 0; + for (let i = 0; i < data.length; i++) { + let gray = map(i, 0, data.length, 0, 255); + fill(gray); + arc( + width / 2, + height / 2, + diameter, + diameter, + lastAngle, + lastAngle + radians(angles[i]) + ); + lastAngle += radians(angles[i]); + } +} diff --git a/dist/assets/examples/hi/01_Form/03_Regular_Polygon.js b/dist/assets/examples/hi/01_Form/03_Regular_Polygon.js new file mode 100644 index 0000000000..7409757cf7 --- /dev/null +++ b/dist/assets/examples/hi/01_Form/03_Regular_Polygon.js @@ -0,0 +1,43 @@ +/* + * @name नियमित बहुभुज + * @description आपका पसंदीदा क्या है? पेंटागन? षट्भुज? हेप्टागन? नहीं न? + *आइकोसैगन के बारे में क्या? इस उदाहरण के लिए बनाया गया polygon() फ़ंक्शन है + * किसी भी नियमित बहुभुज को खींचने में सक्षम। अलग-अलग नंबरों को रखने का प्रयास करें Try + * polygon() फ़ंक्शन कॉल के भीतर draw() का पता लगाने के लिए। + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + polygon(0, 0, 82, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + polygon(0, 0, 80, 20); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + polygon(0, 0, 70, 7); + pop(); +} + +function polygon(x, y, radius, npoints) { + let angle = TWO_PI / npoints; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius; + let sy = y + sin(a) * radius; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/hi/01_Form/04_Star.js b/dist/assets/examples/hi/01_Form/04_Star.js new file mode 100644 index 0000000000..c07641104b --- /dev/null +++ b/dist/assets/examples/hi/01_Form/04_Star.js @@ -0,0 +1,46 @@ +/* + * @name स्टार + * @description इस उदाहरण के लिए बनाया गया star() फ़ंक्शन सक्षम है + * विभिन्न रूपों की एक विस्तृत श्रृंखला को चित्रित करना। अलग-अलग नंबर रखने की कोशिश करें + * star() फ़ंक्शन कॉल में draw() का पता लगाने के लिए +*/ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + star(0, 0, 5, 70, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + star(0, 0, 80, 100, 40); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + star(0, 0, 30, 70, 5); + pop(); +} + +function star(x, y, radius1, radius2, npoints) { + let angle = TWO_PI / npoints; + let halfAngle = angle / 2.0; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius2; + let sy = y + sin(a) * radius2; + vertex(sx, sy); + sx = x + cos(a + halfAngle) * radius1; + sy = y + sin(a + halfAngle) * radius1; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/hi/01_Form/05_Triangle_Strip.js b/dist/assets/examples/hi/01_Form/05_Triangle_Strip.js new file mode 100644 index 0000000000..dc9c9009bc --- /dev/null +++ b/dist/assets/examples/hi/01_Form/05_Triangle_Strip.js @@ -0,0 +1,38 @@ +/* + *@name त्रिभुज पट्टी + * @description उदाहरण इरा ग्रीनबर्ग द्वारा। का उपयोग करके एक बंद रिंग उत्पन्न करें + * vertex() फ़ंक्शन और beginShape (TRIANGLE_STRIP) मोड। बाहरी त्रिज्या + * और इनसाइडरेडियस वेरिएबल्स क्रमशः रिंग की त्रिज्या को नियंत्रित करते हैं। + */ +let x; +let y; +let outsideRadius = 150; +let insideRadius = 100; + +function setup() { + createCanvas(720, 400); + background(204); + x = width / 2; + y = height / 2; +} + +function draw() { + background(204); + + let numPoints = int(map(mouseX, 0, width, 6, 60)); + let angle = 0; + let angleStep = 180.0 / numPoints; + + beginShape(TRIANGLE_STRIP); + for (let i = 0; i <= numPoints; i++) { + let px = x + cos(radians(angle)) * outsideRadius; + let py = y + sin(radians(angle)) * outsideRadius; + angle += angleStep; + vertex(px, py); + px = x + cos(radians(angle)) * insideRadius; + py = y + sin(radians(angle)) * insideRadius; + vertex(px, py); + angle += angleStep; + } + endShape(); +} diff --git a/dist/assets/examples/hi/01_Form/06_Bezier.js b/dist/assets/examples/hi/01_Form/06_Bezier.js new file mode 100644 index 0000000000..864c4c0021 --- /dev/null +++ b/dist/assets/examples/hi/01_Form/06_Bezier.js @@ -0,0 +1,28 @@ +/* + * @name बेज़ियर + * @description bezier() फ़ंक्शन के लिए पहले दो पैरामीटर निर्दिष्ट करते हैं + * वक्र में पहला बिंदु और अंतिम दो पैरामीटर अंतिम बिंदु निर्दिष्ट करते हैं। + * मध्य पैरामीटर नियंत्रण बिंदु निर्धारित करते हैं जो आकार को परिभाषित करते हैं + * वक्र। + */ +function setup() { + createCanvas(720, 400); + stroke(255); + noFill(); +} + +function draw() { + background(0); + for (let i = 0; i < 200; i += 20) { + bezier( + mouseX - i / 2.0, + 40 + i, + 410, + 20, + 440, + 300, + 240 - i / 16.0, + 300 + i / 8.0 + ); + } +} diff --git a/dist/assets/examples/hi/01_Form/07_3D_Primitives.js b/dist/assets/examples/hi/01_Form/07_3D_Primitives.js new file mode 100644 index 0000000000..d1d7735646 --- /dev/null +++ b/dist/assets/examples/hi/01_Form/07_3D_Primitives.js @@ -0,0 +1,30 @@ +/* + * @name ३डी प्रिमिटिव्स + * @frame 720,400 (वैकल्पिक) + * @description गणितीय रूप से 3D ऑब्जेक्ट को सिंथेटिक स्पेस में रखना। + * box() और sphere() फ़ंक्शन उनके निर्दिष्ट करने के लिए कम से कम एक पैरामीटर लेते हैं + * आकार। इन आकृतियों को translate() फ़ंक्शन का उपयोग करके स्थित किया जाता है। + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(100); + + noStroke(); + fill(50); + push(); + translate(-275, 175); + rotateY(1.25); + rotateX(-0.9); + box(100); + pop(); + + noFill(); + stroke(255); + push(); + translate(500, height * 0.35, -200); + sphere(300); + pop(); +} diff --git a/dist/assets/examples/hi/02_Data/00_Variables.js b/dist/assets/examples/hi/02_Data/00_Variables.js new file mode 100644 index 0000000000..97d0dd49a5 --- /dev/null +++ b/dist/assets/examples/hi/02_Data/00_Variables.js @@ -0,0 +1,37 @@ +/* + * @name चर + * @description वेरिएबल्स का उपयोग वैल्यू स्टोर करने के लिए किया जाता है। इस उदाहरण में, बदलें + * रचना को प्रभावित करने के लिए चर के मान। + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(153); + strokeWeight(4); + strokeCap(SQUARE); + + let a = 50; + let b = 120; + let c = 180; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); +} diff --git a/dist/assets/examples/hi/02_Data/01_True_and_False.js b/dist/assets/examples/hi/02_Data/01_True_and_False.js new file mode 100644 index 0000000000..380d2f53e2 --- /dev/null +++ b/dist/assets/examples/hi/02_Data/01_True_and_False.js @@ -0,0 +1,31 @@ +/* + * @name सही और गलत + * @description एक बूलियन वैरिएबल के केवल दो संभावित मान हैं: सही या गलत। + * प्रवाह को निर्धारित करने के लिए नियंत्रण कथनों के साथ बूलियन का उपयोग करना आम है + * एक कार्यक्रम का। इस उदाहरण में, जब बूलियन मान "बी" सत्य है, लंबवत + * रेखाएँ खींची जाती हैं और जब बूलियन मान "बी" गलत होता है, क्षैतिज + *रेखाएँ खींची जाती हैं। + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + + let b = false; + let d = 20; + let middle = width / 2; + + for (let i = d; i <= width; i += d) { + b = i < middle; + + if (b === true) { + // ऊर्ध्वाधर रेखा + line(i, d, i, height - d); + } + + if (b === false) { + // क्षैतिज रेखा + line(middle, i - middle + d, width - d, i - middle + d); + } + } +} diff --git a/dist/assets/examples/hi/02_Data/03_Variable_Scope.js b/dist/assets/examples/hi/02_Data/03_Variable_Scope.js new file mode 100644 index 0000000000..c365807ae2 --- /dev/null +++ b/dist/assets/examples/hi/02_Data/03_Variable_Scope.js @@ -0,0 +1,48 @@ +/* + * @name परिवर्तनीय दायरा + * @description वेरिएबल्स का एक ग्लोबल या फंक्शन "स्कोप" होता है। उदाहरण के लिए, + * या तो setup() या draw() फ़ंक्शन के भीतर घोषित चर हो सकते हैं + * केवल इन कार्यों में उपयोग किया जाता है। वैश्विक चर, बाहर घोषित चर + * setup() और draw(), कार्यक्रम के भीतर कहीं भी इस्तेमाल किया जा सकता है। यदि एक समारोह + * वैरिएबल को ग्लोबल वैरिएबल के समान नाम से घोषित किया जाता है, प्रोग्राम + * वर्तमान के भीतर अपनी गणना करने के लिए फ़ंक्शन चर का उपयोग करेगा + * गुंजाइश। + */ +let a = 80; // एक वैश्विक चर "ए" बनाएं + +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + noLoop(); +} + +function draw() { + // वैश्विक चर "ए" का उपयोग करके एक रेखा खींचें + line(a, 0, a, height); + + // लूप के लिए स्थानीय चर a का उपयोग करें + for (let a = 120; a < 200; a += 3) { + line(a, 0, a, height); + } + + // कस्टम फ़ंक्शन को कॉल करें drawAnotherLine () + drawAnotherLine(); + + // कस्टम फ़ंक्शन पर कॉल करें drawYetAnotherLine () + drawYetAnotherLine(); +} + +function drawAnotherLine() { + // इस फ़ंक्शन के लिए एक नया चर "ए" स्थानीय बनाएं + let a = 320; + // स्थानीय चर "ए" का उपयोग करके एक रेखा खींचें + line(a, 0, a, height); +} + +function drawYetAnotherLine() { + // क्योंकि कोई नया स्थानीय चर "ए" सेट नहीं है, + // यह रेखा मूल वैश्विक का उपयोग करके खींची गई है + // चर "ए" जो मान 20 पर सेट है। + line(a + 3, 0, a + 3, height); +} diff --git a/dist/assets/examples/hi/02_Data/04_Numbers.js b/dist/assets/examples/hi/02_Data/04_Numbers.js new file mode 100644 index 0000000000..1d91c2c94a --- /dev/null +++ b/dist/assets/examples/hi/02_Data/04_Numbers.js @@ -0,0 +1,31 @@ +/* + * @name नंबर + * @frame 720,400 + * @description नंबर को दशमलव के साथ या बिना लिखा जा सकता है। पूर्णांक + * (आमतौर पर एक इंट कहा जाता है) एक दशमलव बिंदु के बिना एक संख्या है। एक फ्लोट + * एक फ़्लोटिंग-पॉइंट नंबर है, जिसका अर्थ है कि यह एक संख्या है जिसमें दशमलव है + * जगह। + */ +let a = 0; // एक वैश्विक चर "ए" प्रकार की संख्या बनाएं +let b = 0; // संख्या प्रकार का एक वैश्विक चर "बी" बनाएं + +function setup() { + createCanvas(720, 400); + stroke(255); +} + +function draw() { + background(0); + + a = a + 1; // एक पूर्णांक के साथ वृद्धि करें + b = b + 0.2; // वृद्धि बी एक फ्लोट के साथ + line(a, 0, a, height / 2); + line(b, height / 2, b, height); + + if (a > width) { + a = 0; + } + if (b > width) { + b = 0; + } +} diff --git a/dist/assets/examples/hi/03_Arrays/00_Array.js b/dist/assets/examples/hi/03_Arrays/00_Array.js new file mode 100644 index 0000000000..31de72acce --- /dev/null +++ b/dist/assets/examples/hi/03_Arrays/00_Array.js @@ -0,0 +1,44 @@ +/* + * @name ऐरे + * @description एक सरणी डेटा की एक सूची है। एक सरणी में डेटा का प्रत्येक टुकड़ा + * को एक सूचकांक संख्या द्वारा पहचाना जाता है जो इसकी स्थिति का प्रतिनिधित्व करता है + * सरणी। Arrays शून्य आधारित हैं, जिसका अर्थ है कि पहला + * सरणी में तत्व [0] है, दूसरा तत्व [1] है, और इसी तरह। + * इस उदाहरण में, "coswave" नामक एक सरणी बनाई गई है और + * कोसाइन मूल्यों से भरा हुआ। यह डेटा तीन प्रदर्शित होता है + * स्क्रीन पर अलग तरीके। + */ +let coswave = []; + +function setup() { + createCanvas(720, 360); + for (let i = 0; i < width; i++) { + let amount = map(i, 0, width, 0, PI); + coswave[i] = abs(cos(amount)); + } + background(255); + noLoop(); +} + +function draw() { + let y1 = 0; + let y2 = height / 3; + for (let i = 0; i < width; i += 3) { + stroke(coswave[i] * 255); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = y1 + y1; + for (let i = 0; i < width; i += 3) { + stroke((coswave[i] * 255) / 4); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = height; + for (let i = 0; i < width; i += 3) { + stroke(255 - coswave[i] * 255); + line(i, y1, i, y2); + } +} diff --git a/dist/assets/examples/hi/03_Arrays/01_Array_2d.js b/dist/assets/examples/hi/03_Arrays/01_Array_2d.js new file mode 100644 index 0000000000..eb166bc468 --- /dev/null +++ b/dist/assets/examples/hi/03_Arrays/01_Array_2d.js @@ -0,0 +1,38 @@ +/* + * @name ऐरे 2D + * @description द्वि-आयामी (2D) बनाने के लिए सिंटैक्स प्रदर्शित करता है + * सरणी। 2D सरणी में मानों को दो अनुक्रमणिका मानों के माध्यम से एक्सेस किया जाता है। + * 2D सरणियाँ छवियों को संग्रहीत करने के लिए उपयोगी हैं। इस उदाहरण में, प्रत्येक बिंदु + * छवि के केंद्र से इसकी दूरी के संबंध में रंगीन है। + */ +let distances = []; +let maxDistance; +let spacer; + +function setup() { + createCanvas(720, 360); + maxDistance = dist(width / 2, height / 2, width, height); + for (let x = 0; x < width; x++) { + distances[x] = []; // create nested array + for (let y = 0; y < height; y++) { + let distance = dist(width / 2, height / 2, x, y); + distances[x][y] = (distance / maxDistance) * 255; + } + } + spacer = 10; + noLoop(); // Run once and stop +} + +function draw() { + background(0); + // यह एम्बेडेड लूप के आधार पर सरणियों में मूल्यों पर छोड़ देता है + // स्पेसर चर, इसलिए सरणी में अधिक मान हैं + // यहाँ से खींचे गए हैं। स्पेसर वैरिएबल का मान बदलें of + // बिंदुओं के घनत्व को बदलने के लिए + for (let x = 0; x < width; x += spacer) { + for (let y = 0; y < height; y += spacer) { + stroke(distances[x][y]); + point(x + spacer / 2, y + spacer / 2); + } + } +} diff --git a/dist/assets/examples/hi/03_Arrays/02_Array_Objects.js b/dist/assets/examples/hi/03_Arrays/02_Array_Objects.js new file mode 100644 index 0000000000..fda498ef6d --- /dev/null +++ b/dist/assets/examples/hi/03_Arrays/02_Array_Objects.js @@ -0,0 +1,71 @@ +/* + * @name ऐरे ऑब्जेक्ट्स + * @description कस्टम ऑब्जेक्ट्स की एक सरणी बनाने के लिए सिंटैक्स प्रदर्शित करता है। + */ + +class Module { + constructor(xOff, yOff, x, y, speed, unit) { + this.xOff = xOff; + this.yOff = yOff; + this.x = x; + this.y = y; + this.speed = speed; + this.unit = unit; + this.xDir = 1; + this.yDir = 1; + } + + // चर को अद्यतन करने के लिए कस्टम विधि + update() { + this.x = this.x + this.speed * this.xDir; + if (this.x >= this.unit || this.x <= 0) { + this.xDir *= -1; + this.x = this.x + 1 * this.xDir; + this.y = this.y + 1 * this.yDir; + } + if (this.y >= this.unit || this.y <= 0) { + this.yDir *= -1; + this.y = this.y + 1 * this.yDir; + } + } + + // वस्तु को खींचने के लिए कस्टम विधि + draw() { + fill(255); + ellipse(this.xOff + this.x, this.yOff + this.y, 6, 6); + } +} + +let unit = 40; +let count; +let mods = []; + +function setup() { + createCanvas(720, 360); + noStroke(); + let wideCount = width / unit; + let highCount = height / unit; + count = wideCount * highCount; + + let index = 0; + for (let y = 0; y < highCount; y++) { + for (let x = 0; x < wideCount; x++) { + mods[index++] = new Module( + x * unit, + y * unit, + unit / 2, + unit / 2, + random(0.05, 0.8), + unit + ); + } + } +} + +function draw() { + background(0); + for (let i = 0; i < count; i++) { + mods[i].update(); + mods[i].draw(); + } +} diff --git a/dist/assets/examples/hi/04_Control/00_Iteration.js b/dist/assets/examples/hi/04_Control/00_Iteration.js new file mode 100644 index 0000000000..4902a49afc --- /dev/null +++ b/dist/assets/examples/hi/04_Control/00_Iteration.js @@ -0,0 +1,41 @@ +/* + * @name पुनरावृत्ति + * @description पुनरावृत्ति रूपों के निर्माण के लिए "के लिए" संरचना के साथ पुनरावृत्ति। + */ +let y; +let num = 14; + +function setup() { + createCanvas(720, 360); + background(102); + noStroke(); + + // सफेद सलाखों को ड्रा करें + fill(255); + y = 60; + for (let i = 0; i < num / 3; i++) { + rect(50, y, 475, 10); + y += 20; + } + + // ग्रे बार + fill(51); + y = 40; + for (let i = 0; i < num; i++) { + rect(405, y, 30, 10); + y += 20; + } + y = 50; + for (let i = 0; i < num; i++) { + rect(425, y, 30, 10); + y += 20; + } + + // पतली रेखाएं + y = 45; + fill(0); + for (let i = 0; i < num - 1; i++) { + rect(120, y, 40, 1); + y += 20; + } +} diff --git a/dist/assets/examples/hi/04_Control/01_Embedded_Iteration.js b/dist/assets/examples/hi/04_Control/01_Embedded_Iteration.js new file mode 100644 index 0000000000..15183ca09d --- /dev/null +++ b/dist/assets/examples/hi/04_Control/01_Embedded_Iteration.js @@ -0,0 +1,21 @@ +/* +* @name एंबेडेड इटरेशन +* @description "के लिए" संरचनाओं को एम्बेड करना दो आयामों में पुनरावृत्ति की अनुमति देता है। +*/ +function setup() { + createCanvas(720, 360); + background(0); + noStroke(); + + let gridSize = 35; + + for (let x = gridSize; x <= width - gridSize; x += gridSize) { + for (let y = gridSize; y <= height - gridSize; y += gridSize) { + noStroke(); + fill(255); + rect(x - 1, y - 1, 3, 3); + stroke(255, 50); + line(x, y, width / 2, height / 2); + } + } +} diff --git a/dist/assets/examples/hi/04_Control/02_Conditionals_1.js b/dist/assets/examples/hi/04_Control/02_Conditionals_1.js new file mode 100644 index 0000000000..f4f2ba09af --- /dev/null +++ b/dist/assets/examples/hi/04_Control/02_Conditionals_1.js @@ -0,0 +1,26 @@ +/* + * @name सशर्त 1 + * @description शर्तें सवालों की तरह हैं। + * वे एक कार्यक्रम को एक कार्रवाई करने का निर्णय लेने की अनुमति देते हैं यदि + * किसी प्रश्न का उत्तर सत्य है या कोई अन्य क्रिया करना + * यदि प्रश्न का उत्तर गलत है। + * एक कार्यक्रम के भीतर पूछे जाने वाले प्रश्न हमेशा तार्किक होते हैं + * या संबंधपरक बयान। उदाहरण के लिए, यदि चर 'i' is + * शून्य के बराबर फिर एक रेखा खींचे। + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 10; i < width; i += 10) { + // यदि 'i' को 20 से विभाजित किया जाता है और कोई शेष नहीं है तो पहली पंक्ति बनाएं + // अन्यथा दूसरी पंक्ति बनाएं + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + } else { + stroke(153); + line(i, 20, i, 180); + } + } +} diff --git a/dist/assets/examples/hi/04_Control/03_Conditionals_2.js b/dist/assets/examples/hi/04_Control/03_Conditionals_2.js new file mode 100644 index 0000000000..2e8f855364 --- /dev/null +++ b/dist/assets/examples/hi/04_Control/03_Conditionals_2.js @@ -0,0 +1,28 @@ +/* + * @name सशर्त 2 + * @description हम पिछले से सशर्त की भाषा का विस्तार करते हैं + * उदाहरण "और" कीवर्ड जोड़कर। यह सशर्त अनुमति देता है + * दो या दो से अधिक क्रमिक प्रश्न पूछने के लिए, प्रत्येक एक अलग के साथ + * क्रिया। + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 2; i < width - 2; i += 4) { + // यदि 'i' को 20 से विभाजित किया जाता है और कोई शेषफल नहीं है + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + // यदि 'i' को 10 से विभाजित किया जाता है और कोई शेषफल नहीं है + } else if (i % 10 === 0) { + stroke(153); + line(i, 20, i, 180); + // यदि उपरोक्त दो शर्तों में से कोई भी पूरा नहीं हुआ है + // फिर इस लाइन को ड्रा करें + } else { + stroke(102); + line(i, height / 2, i, height - 20); + } + } +} diff --git a/dist/assets/examples/hi/04_Control/04_Logical_Operators.js b/dist/assets/examples/hi/04_Control/04_Logical_Operators.js new file mode 100644 index 0000000000..804c7fdcb8 --- /dev/null +++ b/dist/assets/examples/hi/04_Control/04_Logical_Operators.js @@ -0,0 +1,42 @@ +/* + * @name लॉजिकल ऑपरेटर्स + * @description AND (&&) और OR (||) के लिए तार्किक ऑपरेटरों का उपयोग किया जाता है + * सरल संबंधपरक कथनों को अधिक जटिल अभिव्यक्तियों में संयोजित करें। + * NOT (!) ऑपरेटर का उपयोग बूलियन स्टेटमेंट को नकारने के लिए किया जाता है। + */ +let test = false; + +function setup() { + createCanvas(720, 360); + background(126); + + for (let i = 5; i <= height; i += 5) { + // तार्किक और + stroke(0); + if (i > 35 && i < 100) { + line(width / 4, i, width / 2, i); + test = false; + } + + // तार्किक OR + stroke(76); + if (i <= 35 || i >= 100) { + line(width / 2, i, width, i); + test = true; + } + + // परीक्षण करें कि क्या बूलियन मान "सत्य" है + // अभिव्यक्ति "अगर (परीक्षण)" "अगर (परीक्षण == सत्य)" के बराबर है + if (test) { + stroke(0); + point(width / 3, i); + } + + // परीक्षण करें कि क्या बूलियन मान "गलत" है + // अभिव्यक्ति "if(!test)" बराबर है "if(test == false)" + if (!test) { + stroke(255); + point(width / 4, i); + } + } +} diff --git a/dist/assets/examples/hi/05_Image/00_Load_and_Display_Image.js b/dist/assets/examples/hi/05_Image/00_Load_and_Display_Image.js new file mode 100644 index 0000000000..e11491f400 --- /dev/null +++ b/dist/assets/examples/hi/05_Image/00_Load_and_Display_Image.js @@ -0,0 +1,21 @@ +/* + * @name लोड और डिस्प्ले इमेज + * @description छवियों को लोड किया जा सकता है और स्क्रीन पर प्रदर्शित किया जा सकता है + * वास्तविक आकार या कोई अन्य आकार। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको एक की आवश्यकता होगी + * छवि फ़ाइल, और चल रही + * स्थानीय सर्वर.

+ */ +let img; // वैरिएबल 'img' घोषित करें। + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // छवि लोड करें +} + +function draw() { + // छवि को उसके वास्तविक आकार में बिंदु (0,0) पर प्रदर्शित करता है + image(img, 0, 0); + // आधे आकार में छवि को बिंदु (0, ऊंचाई / 2) पर प्रदर्शित करता है + image(img, 0, height / 2, img.width / 2, img.height / 2); +} diff --git a/dist/assets/examples/hi/05_Image/01_Background_Image.js b/dist/assets/examples/hi/05_Image/01_Background_Image.js new file mode 100644 index 0000000000..58b70942a2 --- /dev/null +++ b/dist/assets/examples/hi/05_Image/01_Background_Image.js @@ -0,0 +1,31 @@ +/* + * @name पृष्ठभूमि छवि + * @description यह उदाहरण लोड करने का सबसे तेज़ तरीका प्रस्तुत करता है a + * पृष्ठभूमि छवि। एक छवि को पृष्ठभूमि के रूप में लोड करने के लिए, + * यह कार्यक्रम के समान चौड़ाई और ऊंचाई का होना चाहिए। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको एक की आवश्यकता होगी + * छवि फ़ाइल, और चल रही + * स्थानीय सर्वर.

+ */ +let bg; +let y = 0; + +function setup() { + // पृष्ठभूमि की छवि मापदंडों के समान आकार की होनी चाहिए + // createCanvas () विधि में। इस कार्यक्रम में, का आकार + // इमेज 720x400 पिक्सल है। + bg = loadImage('assets/moonwalk.jpg'); + createCanvas(720, 400); +} + +function draw() { + background(bg); + + stroke(226, 204, 0); + line(0, y, width, y); + + y++; + if (y > height) { + y = 0; + } +} diff --git a/dist/assets/examples/hi/05_Image/02_Transparency.js b/dist/assets/examples/hi/05_Image/02_Transparency.js new file mode 100644 index 0000000000..a2befe2d72 --- /dev/null +++ b/dist/assets/examples/hi/05_Image/02_Transparency.js @@ -0,0 +1,25 @@ +/* + * @name पारदर्शिता + * @description चित्र पर पॉइंटर को बाएँ और दाएँ घुमाएँ ताकि वह बदल जाए + * पद। यह प्रोग्राम एक छवि को दूसरे के ऊपर संशोधित करके ओवरले करता है + * tint() फ़ंक्शन के साथ छवि का अल्फा मान। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको एक की आवश्यकता होगी + * छवि फ़ाइल, और चल रही + * स्थानीय सर्वर.

+ */ +let img; +let offset = 0; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // प्रोग्राम में एक छवि लोड करें +} + +function draw() { + image(img, 0, 0); // पूर्ण अस्पष्टता पर प्रदर्शित करें + let dx = mouseX - img.width / 2 - offset; + offset += dx * easing; + tint(255, 127); // आधी अस्पष्टता पर प्रदर्शित करें + image(img, offset, 0); +} diff --git a/dist/assets/examples/hi/05_Image/03_Alpha_Mask.js b/dist/assets/examples/hi/05_Image/03_Alpha_Mask.js new file mode 100644 index 0000000000..a15cf7e9a8 --- /dev/null +++ b/dist/assets/examples/hi/05_Image/03_Alpha_Mask.js @@ -0,0 +1,28 @@ +/* + * @name अल्फा मास्क + * @description में पारदर्शिता निर्दिष्ट करने के लिए एक छवि के लिए "मास्क" लोड करता है + * छवि के विभिन्न भाग। दो छवियों को एक साथ मिश्रित कर रहे हैं + * mask() p5.Image की विधि। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको दो की आवश्यकता होगी + * छवि फ़ाइलें, और चल रहे + * स्थानीय सर्वर.

+ */ +let img; +let imgMask; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); + imgMask = loadImage('assets/mask.png'); +} + +function setup() { + createCanvas(720, 400); + img.mask(imgMask); + imageMode(CENTER); +} + +function draw() { + background(0, 102, 153); + image(img, width / 2, height / 2); + image(img, mouseX, mouseY); +} diff --git a/dist/assets/examples/hi/05_Image/04_Create_Image.js b/dist/assets/examples/hi/05_Image/04_Create_Image.js new file mode 100644 index 0000000000..f9a7e8afd5 --- /dev/null +++ b/dist/assets/examples/hi/05_Image/04_Create_Image.js @@ -0,0 +1,25 @@ +/* + * @name इमेज बनाएं + * @description createImage() फ़ंक्शन पिक्सेल का एक ताज़ा बफर प्रदान करता है + * सोचना। यह उदाहरण एक छवि ढाल बनाता है। + */ +let img; // वैरिएबल 'img' घोषित करें। + +function setup() { + createCanvas(720, 400); + img = createImage(230, 230); + img.loadPixels(); + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + let a = map(y, 0, img.height, 255, 0); + img.set(x, y, [0, 153, 204, a]); + } + } + img.updatePixels(); +} + +function draw() { + background(0); + image(img, 90, 80); + image(img, mouseX - img.width / 2, mouseY - img.height / 2); +} diff --git a/dist/assets/examples/hi/05_Image/05_Pointillism.js b/dist/assets/examples/hi/05_Image/05_Pointillism.js new file mode 100644 index 0000000000..0ba91bad34 --- /dev/null +++ b/dist/assets/examples/hi/05_Image/05_Pointillism.js @@ -0,0 +1,34 @@ +/* + * @name पॉइंटिलिज्म + * @description डैन शिफमैन द्वारा। माउस क्षैतिज स्थान का आकार नियंत्रित करता है + * डॉट्स। रंग के अनुसार दीर्घवृत्त का उपयोग करके एक साधारण पॉइंटिलिस्ट प्रभाव बनाता है + * एक छवि में पिक्सेल के लिए। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको एक की आवश्यकता होगी + * छवि फ़ाइल, और चल रही + * स्थानीय सर्वर.

+ */ +let img; +let smallPoint, largePoint; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 400); + smallPoint = 4; + largePoint = 40; + imageMode(CENTER); + noStroke(); + background(255); + img.loadPixels(); +} + +function draw() { + let pointillize = map(mouseX, 0, width, smallPoint, largePoint); + let x = floor(random(img.width)); + let y = floor(random(img.height)); + let pix = img.get(x, y); + fill(pix, 128); + ellipse(x, y, pointillize, pointillize); +} diff --git a/dist/assets/examples/hi/07_Color/00_Hue.js b/dist/assets/examples/hi/07_Color/00_Hue.js new file mode 100644 index 0000000000..773f2a48b6 --- /dev/null +++ b/dist/assets/examples/hi/07_Color/00_Hue.js @@ -0,0 +1,25 @@ +/* + * @name ह्यू + * @description Hue वह रंग है जो a . से परावर्तित या प्रसारित होता है + * वस्तु और आमतौर पर रंग के नाम के रूप में जाना जाता है (लाल, नीला, + * पीला, आदि।) रंग बदलने के लिए कर्सर को प्रत्येक बार पर लंबवत ले जाएं। + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, height, height, height); + noStroke(); + background(0); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(mouseY, height, height); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/hi/07_Color/01_Saturation.js b/dist/assets/examples/hi/07_Color/01_Saturation.js new file mode 100644 index 0000000000..7894327066 --- /dev/null +++ b/dist/assets/examples/hi/07_Color/01_Saturation.js @@ -0,0 +1,25 @@ +/* + * @name संतृप्ति + * @description संतृप्ति रंग की ताकत या शुद्धता है और + * रंग के अनुपात में ग्रे की मात्रा का प्रतिनिधित्व करता है। एक "संतृप्त" + * रंग शुद्ध होता है और "असंतृप्त" रंग में ग्रे का एक बड़ा प्रतिशत होता है। + * इसकी संतृप्ति को बदलने के लिए कर्सर को प्रत्येक पट्टी पर लंबवत ले जाएँ। + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, width, height, 100); + noStroke(); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(barX, mouseY, 66); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/hi/07_Color/02_Brightness.js b/dist/assets/examples/hi/07_Color/02_Brightness.js new file mode 100644 index 0000000000..de0e03ace6 --- /dev/null +++ b/dist/assets/examples/hi/07_Color/02_Brightness.js @@ -0,0 +1,46 @@ +/* + * @name चमक + * @description डैन शिफमैन द्वारा। यह प्रोग्राम एक हिस्से की चमक को समायोजित करता है + * माउस से प्रत्येक पिक्सेल की दूरी की गणना करके छवि का। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको आवश्यकता होगी + * कम से कम एक छवि फ़ाइल और चल रहे स्थानीय सर्वर

+ */ +let img; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 200); + pixelDensity(1); + img.loadPixels(); + loadPixels(); +} + +function draw() { + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + // Calculate the 1D location from a 2D grid + let loc = (x + y * img.width) * 4; + // Get the R,G,B values from image + let r, g, b; + r = img.pixels[loc]; + // Calculate an amount to change brightness based on proximity to the mouse + let maxdist = 50; + let d = dist(x, y, mouseX, mouseY); + let adjustbrightness = (255 * (maxdist - d)) / maxdist; + r += adjustbrightness; + // Constrain RGB to make sure they are within 0-255 color range + r = constrain(r, 0, 255); + // Make a new color and set pixel in the window + //color c = color(r, g, b); + let pixloc = (y * width + x) * 4; + pixels[pixloc] = r; + pixels[pixloc + 1] = r; + pixels[pixloc + 2] = r; + pixels[pixloc + 3] = 255; + } + } + updatePixels(); +} diff --git a/dist/assets/examples/hi/07_Color/03_Color_Variables.js b/dist/assets/examples/hi/07_Color/03_Color_Variables.js new file mode 100644 index 0000000000..2a58ef7125 --- /dev/null +++ b/dist/assets/examples/hi/07_Color/03_Color_Variables.js @@ -0,0 +1,39 @@ +/* + * @name रंग चर + * @description (अलबर्स को श्रद्धांजलि।) यह उदाहरण रंगों के लिए चर बनाता है + * जिसे कार्यक्रम में एक संख्या के बजाय एक नाम से संदर्भित किया जा सकता है। + */ +function setup() { + createCanvas(710, 400); + noStroke(); + background(51, 0, 0); + + let inside = color(204, 102, 0); + let middle = color(204, 153, 0); + let outside = color(153, 51, 0); + + // ये बयान ऊपर दिए गए बयानों के बराबर हैं। + // प्रोग्रामर अपने पसंदीदा प्रारूप का उपयोग कर सकते हैं। + // अंदर जाने दें = रंग ('# CC6600'); + // चलो मध्य = रंग ('# CC9900'); + // बाहर जाने दें = रंग ('#993300'); + push(); + translate(80, 80); + fill(outside); + rect(0, 0, 200, 200); + fill(middle); + rect(40, 60, 120, 120); + fill(inside); + rect(60, 90, 80, 80); + pop(); + + push(); + translate(360, 80); + fill(inside); + rect(0, 0, 200, 200); + fill(outside); + rect(40, 60, 120, 120); + fill(middle); + rect(60, 90, 80, 80); + pop(); +} diff --git a/dist/assets/examples/hi/07_Color/04_Relativity.js b/dist/assets/examples/hi/07_Color/04_Relativity.js new file mode 100644 index 0000000000..fb654bd192 --- /dev/null +++ b/dist/assets/examples/hi/07_Color/04_Relativity.js @@ -0,0 +1,34 @@ +/* + * @name सापेक्षता + * @description प्रत्येक रंग अन्य रंगों के संबंध में माना जाता है। चोटी + * और नीचे की सलाखों में प्रत्येक में समान घटक रंग होते हैं, लेकिन एक अलग + * डिस्प्ले ऑर्डर के कारण अलग-अलग रंग अलग-अलग दिखाई देते हैं। + */ +let a, b, c, d, e; + +function setup() { + createCanvas(710, 400); + noStroke(); + a = color(165, 167, 20); + b = color(77, 86, 59); + c = color(42, 106, 105); + d = color(165, 89, 20); + e = color(146, 150, 127); + noLoop(); // केवल एक बार ड्रा करें +} + +function draw() { + drawBand(a, b, c, d, e, 0, width / 128); + drawBand(c, a, d, b, e, height / 2, width / 128); +} + +function drawBand(v, w, x, y, z, ypos, barWidth) { + let num = 5; + let colorOrder = [v, w, x, y, z]; + for (let i = 0; i < width; i += barWidth * num) { + for (let j = 0; j < num; j++) { + fill(colorOrder[j]); + rect(i + j * barWidth, ypos, barWidth, height / 2); + } + } +} diff --git a/dist/assets/examples/hi/07_Color/05_Linear_Gradient.js b/dist/assets/examples/hi/07_Color/05_Linear_Gradient.js new file mode 100644 index 0000000000..16fc43adcc --- /dev/null +++ b/dist/assets/examples/hi/07_Color/05_Linear_Gradient.js @@ -0,0 +1,52 @@ +/* + * @name रैखिक ढाल + * @description lerpColor () फ़ंक्शन के बीच इंटरपोल करने के लिए उपयोगी है + * दो रंग। + */ +// स्थिरांक +const Y_AXIS = 1; +const X_AXIS = 2; +let b1, b2, c1, c2; + +function setup() { + createCanvas(710, 400); + + // रंगों को परिभाषित करें + b1 = color(255); + b2 = color(0); + c1 = color(204, 102, 0); + c2 = color(0, 102, 153); + + noLoop(); +} + +function draw() { + // पृष्ठभूमि + setGradient(0, 0, width / 2, height, b1, b2, X_AXIS); + setGradient(width / 2, 0, width / 2, height, b2, b1, X_AXIS); + // अग्रभूमि + setGradient(50, 90, 540, 80, c1, c2, Y_AXIS); + setGradient(50, 190, 540, 80, c2, c1, X_AXIS); +} + +function setGradient(x, y, w, h, c1, c2, axis) { + noFill(); + + if (axis === Y_AXIS) { + // ऊपर से नीचे की ओर ढाल + for (let i = y; i <= y + h; i++) { + let inter = map(i, y, y + h, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(x, i, x + w, i); + } + } else if (axis === X_AXIS) { + // बाएं से दाएं ढाल + for (let i = x; i <= x + w; i++) { + let inter = map(i, x, x + w, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(i, y, i, y + h); + } + } +} diff --git a/dist/assets/examples/hi/07_Color/06_Radial_Gradient.js b/dist/assets/examples/hi/07_Color/06_Radial_Gradient.js new file mode 100644 index 0000000000..a4bb1da4b6 --- /dev/null +++ b/dist/assets/examples/hi/07_Color/06_Radial_Gradient.js @@ -0,0 +1,33 @@ +/* + * @name रेडियल ग्रेडिएंट + * @description एक ढाल बनाने के लिए संकेंद्रित वृत्तों की एक श्रृंखला बनाता है + * एक रंग से दूसरे रंग में। + */ +let dim; + +function setup() { + createCanvas(710, 400); + dim = width / 2; + background(0); + colorMode(HSB, 360, 100, 100); + noStroke(); + ellipseMode(RADIUS); + frameRate(1); +} + +function draw() { + background(0); + for (let x = 0; x <= width; x += dim) { + drawGradient(x, height / 2); + } +} + +function drawGradient(x, y) { + let radius = dim / 2; + let h = random(0, 360); + for (let r = radius; r > 0; --r) { + fill(h, 90, 90); + ellipse(x, y, r, r); + h = (h + 1) % 360; + } +} diff --git a/dist/assets/examples/hi/07_Color/07_Lerp_Color.js b/dist/assets/examples/hi/07_Color/07_Lerp_Color.js new file mode 100644 index 0000000000..51338784c4 --- /dev/null +++ b/dist/assets/examples/hi/07_Color/07_Lerp_Color.js @@ -0,0 +1,49 @@ +/* + * @name Lerp Color + * @description लूप यादृच्छिक आकार, + * लाल से नीले रंग में लाल रंग का रंग। + */ +function setup() { + createCanvas(720, 400); + background(255); + noStroke(); +} + +function draw() { + background(255); + from = color(255, 0, 0, 0.2 * 255); + to = color(0, 0, 255, 0.2 * 255); + c1 = lerpColor(from, to, 0.33); + c2 = lerpColor(from, to, 0.66); + for (let i = 0; i < 15; i++) { + fill(from); + quad( + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height) + ); + fill(c1); + quad( + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height) + ); + fill(c2); + quad( + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height) + ); + fill(to); + quad( + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height) + ); + } + frameRate(5); +} diff --git a/dist/assets/examples/hi/08_Math/00_incrementdecrement.js b/dist/assets/examples/hi/08_Math/00_incrementdecrement.js new file mode 100644 index 0000000000..bb34253b2f --- /dev/null +++ b/dist/assets/examples/hi/08_Math/00_incrementdecrement.js @@ -0,0 +1,42 @@ +/* + * @name वेतन वृद्धि + * @description "a++" लिखना "a = a + 1" के बराबर है। + * "ए--" लिखना "ए = ए -1" के बराबर है। + */ +let a; +let b; +let direction; + +function setup() { + createCanvas(710, 400); + colorMode(RGB, width); + a = 0; + b = width; + direction = true; + frameRate(30); +} + +function draw() { + a++; + if (a > width) { + a = 0; + direction = !direction; + } + if (direction === true) { + stroke(a); + } else { + stroke(width - a); + } + line(a, 0, a, height / 2); + + b--; + if (b < 0) { + b = width; + } + if (direction == true) { + stroke(width - b); + } else { + stroke(b); + } + line(b, height / 2 + 1, b, height); +} diff --git a/dist/assets/examples/hi/08_Math/01_operatorprecedence.js b/dist/assets/examples/hi/08_Math/01_operatorprecedence.js new file mode 100644 index 0000000000..3fd05af720 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/01_operatorprecedence.js @@ -0,0 +1,54 @@ +/* + * @name ऑपरेटर वरीयता + * @description यदि आप स्पष्ट रूप से उस क्रम का उल्लेख नहीं करते हैं जिसमें a + * अभिव्यक्ति का मूल्यांकन किया जाता है, उनका मूल्यांकन ऑपरेटर के आधार पर किया जाता है + * वरीयता। उदाहरण के लिए, "4+2*8" कथन में, 2 होगा + * पहले 8 से गुणा करें और फिर परिणाम 4 में जोड़ दिया जाएगा। + * ऐसा इसलिए है क्योंकि "*" की "+" की तुलना में अधिक प्राथमिकता है। कन्नी काटना + * कार्यक्रम को पढ़ने में अस्पष्टता, यह अनुशंसा की जाती है कि कथन है + * को "4+(2*8)" लिखा जाता है। मूल्यांकन के क्रम को नियंत्रित किया जा सकता है + * कोड में कोष्ठक लगाने के माध्यम से। ऑपरेटर की एक तालिका + * वरीयता नीचे दी गई है। + */ +// सर्वोच्च प्राथमिकता सूची में सबसे ऊपर है और +// सबसे नीचे सबसे नीचे है। +// गुणक: * /% +// योजक: + - +// संबंधपरक: <> <= >= +// समानता: ==!= +// तार्किक और: && +// तार्किक या: || +// असाइनमेंट: = += -= *= /= %= +function setup() { + createCanvas(710, 400); + background(51); + noFill(); + stroke(51); + + stroke(204); + for (let i = 0; i < width - 20; i += 4) { + // 30 को 70 में जोड़ा जाता है और फिर मूल्यांकन किया जाता है + // यदि यह "i" के वर्तमान मान से अधिक है + // स्पष्टता के लिए, "if (i> (30 + 70)) {" के रूप में लिखें + if (i > 30 + 70) { + line(i, 0, i, 50); + } + } + + stroke(255); + // 2 को 8 से गुणा किया जाता है और परिणाम 4 . में जोड़ा जाता है + // स्पष्टता के लिए, "रेक्ट (5 + (2 * 8), 0, 90, 20);" के रूप में लिखें। + rect(4 + 2 * 8, 52, 290, 48); + rect((4 + 2) * 8, 100, 290, 49); + + stroke(153); + for (let i = 0; i < width; i += 2) { + // संबंधपरक बयानों का मूल्यांकन किया जाता है + // पहले, और फिर तार्किक और कथन और + // अंत में तार्किक OR. स्पष्टता के लिए, इस प्रकार लिखें: + // "अगर (((i> 20) && (i <50)) || ((i> 100) && (i <चौड़ाई-20))) {" + if ((i > 20 && i < 50) || (i > 100 && i < width - 20)) { + line(i, 151, i, height - 1); + } + } +} diff --git a/dist/assets/examples/hi/08_Math/02_distance1d.js b/dist/assets/examples/hi/08_Math/02_distance1d.js new file mode 100644 index 0000000000..29d8ff66c6 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/02_distance1d.js @@ -0,0 +1,65 @@ +/* + * @name दूरी 1डी + * @description नियंत्रित करने के लिए माउस को बाएँ और दाएँ घुमाएँ + * चलती आकृतियों की गति और दिशा। + */ +let xpos1; +let xpos2; +let xpos3; +let xpos4; +let thin = 8; +let thick = 36; + +function setup() { + createCanvas(710, 400); + noStroke(); + xpos1 = width / 2; + xpos2 = width / 2; + xpos3 = width / 2; + xpos4 = width / 2; +} + +function draw() { + background(0); + + let mx = mouseX * 0.4 - width / 5.0; + + fill(102); + rect(xpos2, 0, thick, height / 2); + fill(204); + rect(xpos1, 0, thin, height / 2); + fill(102); + rect(xpos4, height / 2, thick, height / 2); + fill(204); + rect(xpos3, height / 2, thin, height / 2); + + xpos1 += mx / 16; + xpos2 += mx / 64; + xpos3 -= mx / 16; + xpos4 -= mx / 64; + + if (xpos1 < -thin) { + xpos1 = width; + } + if (xpos1 > width) { + xpos1 = -thin; + } + if (xpos2 < -thick) { + xpos2 = width; + } + if (xpos2 > width) { + xpos2 = -thick; + } + if (xpos3 < -thin) { + xpos3 = width; + } + if (xpos3 > width) { + xpos3 = -thin; + } + if (xpos4 < -thick) { + xpos4 = width; + } + if (xpos4 > width) { + xpos4 = -thick; + } +} diff --git a/dist/assets/examples/hi/08_Math/03_distance2d.js b/dist/assets/examples/hi/08_Math/03_distance2d.js new file mode 100644 index 0000000000..8d7c79aa76 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/03_distance2d.js @@ -0,0 +1,25 @@ +/* + * @name दूरी 2डी + * @description छवि पर माउस को अस्पष्ट करने के लिए ले जाएं + * और मैट्रिक्स प्रकट करें। माउस से दूरी मापता है + * प्रत्येक सर्कल के लिए और आनुपातिक रूप से आकार निर्धारित करता है। + */ +let max_distance; + +function setup() { + createCanvas(710, 400); + noStroke(); + max_distance = dist(0, 0, width, height); +} + +function draw() { + background(0); + + for (let i = 0; i <= width; i += 20) { + for (let j = 0; j <= height; j += 20) { + let size = dist(mouseX, mouseY, i, j); + size = (size / max_distance) * 66; + ellipse(i, j, size, size); + } + } +} diff --git a/dist/assets/examples/hi/08_Math/04_sine.js b/dist/assets/examples/hi/08_Math/04_sine.js new file mode 100644 index 0000000000..f9ba5e1b2a --- /dev/null +++ b/dist/assets/examples/hi/08_Math/04_sine.js @@ -0,0 +1,27 @@ + /* + *@name साइन + * @description sin() फ़ंक्शन के साथ आसानी से स्केलिंग आकार। + */ +let diameter; +let angle = 0; + +function setup() { + createCanvas(710, 400); + diameter = height - 10; + noStroke(); + fill(255, 204, 0); +} + +function draw() { + background(0); + + let d1 = 10 + (sin(angle) * diameter) / 2 + diameter / 2; + let d2 = 10 + (sin(angle + PI / 2) * diameter) / 2 + diameter / 2; + let d3 = 10 + (sin(angle + PI) * diameter) / 2 + diameter / 2; + + ellipse(0, height / 2, d1, d1); + ellipse(width / 2, height / 2, d2, d2); + ellipse(width, height / 2, d3, d3); + + angle += 0.02; +} diff --git a/dist/assets/examples/hi/08_Math/05_sincosine.js b/dist/assets/examples/hi/08_Math/05_sincosine.js new file mode 100644 index 0000000000..91062f6520 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/05_sincosine.js @@ -0,0 +1,43 @@ +/* + * @name साइन कोसाइन + * @description लीनियर मूवमेंट विथ sin() और cos()। + * 0 और PI*2 के बीच की संख्या (TWO_PI जिसका कोण लगभग 6.28 है) + * इन कार्यों में डाल दिया जाता है और -1 और 1 के बीच की संख्या वापस कर दी जाती है। + * इन मूल्यों को तब बड़े आंदोलनों का उत्पादन करने के लिए बढ़ाया जाता है। + */ +let angle1 = 0; +let angle2 = 0; +let scalar = 70; + +function setup() { + createCanvas(710, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(0); + + let ang1 = radians(angle1); + let ang2 = radians(angle2); + + let x1 = width / 2 + scalar * cos(ang1); + let x2 = width / 2 + scalar * cos(ang2); + + let y1 = height / 2 + scalar * sin(ang1); + let y2 = height / 2 + scalar * sin(ang2); + + fill(255); + rect(width * 0.5, height * 0.5, 140, 140); + + fill(0, 102, 153); + ellipse(x1, height * 0.5 - 120, scalar, scalar); + ellipse(x2, height * 0.5 + 120, scalar, scalar); + + fill(255, 204, 0); + ellipse(width * 0.5 - 120, y1, scalar, scalar); + ellipse(width * 0.5 + 120, y2, scalar, scalar); + + angle1 += 2; + angle2 += 3; +} diff --git a/dist/assets/examples/hi/08_Math/06_sinewave.js b/dist/assets/examples/hi/08_Math/06_sinewave.js new file mode 100644 index 0000000000..0ec43a3c7e --- /dev/null +++ b/dist/assets/examples/hi/08_Math/06_sinewave.js @@ -0,0 +1,48 @@ +/* + * @name साइन वेव + * @description एक साधारण साइन वेव रेंडर करें। + * डैनियल शिफमैन द्वारा मूल। + */ + +let xspacing = 16; // प्रत्येक क्षैतिज स्थान के बीच की दूरी +let w; // पूरी लहर की चौड़ाई +let theta = 0.0; // 0 . पर कोण प्रारंभ करें +let amplitude = 75.0; // लहर की ऊंचाई +let period = 500.0; // वेव रिपीट होने से पहले कितने पिक्सेल होते हैं +let dx; // एक्स बढ़ाने के लिए मूल्य +let yvalues; // तरंग के लिए ऊंचाई मानों को संग्रहीत करने के लिए एक सरणी का उपयोग करना + +function setup() { + createCanvas(710, 400); + w = width + 16; + dx = (TWO_PI / period) * xspacing; + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // वृद्धि थीटा (के लिए विभिन्न मूल्यों का प्रयास करें values + // 'कोणीय वेग' यहाँ) + theta += 0.02; + + // प्रत्येक x मान के लिए, साइन फ़ंक्शन के साथ y मान की गणना करें + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = sin(x) * amplitude; + x += dx; + } +} + +function renderWave() { + noStroke(); + fill(255); + // प्रत्येक स्थान पर एक अंडाकार के साथ लहर खींचने का एक आसान तरीका simple + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, height / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/hi/08_Math/07_additivewave.js b/dist/assets/examples/hi/08_Math/07_additivewave.js new file mode 100644 index 0000000000..9ca17de600 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/07_additivewave.js @@ -0,0 +1,70 @@ +/* + * @name Additive Wave + * @description दो तरंगों को एक साथ जोड़कर अधिक जटिल तरंग बनाएं। + * डैनियल शिफमैन द्वारा मूल + */ +let xspacing = 8; // प्रत्येक क्षैतिज स्थान के बीच की दूरी +let w; // पूरी लहर की चौड़ाई +let maxwaves = 4; // कुल # तरंगों को एक साथ जोड़ने के लिए + +let theta = 0.0; +let amplitude = new Array(maxwaves); // लहर की ऊंचाई +// एक्स बढ़ाने के लिए मूल्य, गणना की जानी है +// अवधि और xspacing के एक समारोह के रूप में +let dx = new Array(maxwaves); +// ऊंचाई मूल्यों को संग्रहीत करने के लिए एक सरणी का उपयोग करना +// लहर के लिए (पूरी तरह से आवश्यक नहीं) +let yvalues; + +function setup() { + createCanvas(710, 400); + frameRate(30); + colorMode(RGB, 255, 255, 255, 100); + w = width + 16; + + for (let i = 0; i < maxwaves; i++) { + amplitude[i] = random(10, 30); + let period = random(100, 300); // तरंग दोहराने से पहले पिक्सेल की संख्या before + dx[i] = (TWO_PI / period) * xspacing; + } + + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // वृद्धि थीटा (विभिन्न मूल्यों का प्रयास करें + // यहां 'कोणीय वेग' के लिए + theta += 0.02; + + // सभी ऊंचाई मानों को शून्य पर सेट करें + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = 0; + } + + // तरंग ऊंचाई मान संचित करें + for (let j = 0; j < maxwaves; j++) { + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + // हर दूसरी लहर साइन के बजाय कोसाइन है + if (j % 2 == 0) yvalues[i] += sin(x) * amplitude[j]; + else yvalues[i] += cos(x) * amplitude[j]; + x += dx[j]; + } + } +} + +function renderWave() { + // प्रत्येक स्थान पर एक अंडाकार के साथ लहर खींचने का एक आसान तरीका simple + noStroke(); + fill(255, 50); + ellipseMode(CENTER); + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, width / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/hi/08_Math/08_polartocartesian.js b/dist/assets/examples/hi/08_Math/08_polartocartesian.js new file mode 100644 index 0000000000..0939f7e3c6 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/08_polartocartesian.js @@ -0,0 +1,44 @@ +/* + * @name PolarToCartesian + * @description एक ध्रुवीय निर्देशांक परिवर्तित करें (r, थीटा) + * कार्तीय (x, y) के लिए: x = rcos (थीटा) y = rsin (थीटा) + * डैनियल शिफमैन द्वारा मूल। + */ +let r; + +// कोण और कोणीय वेग, त्वरण +let theta; +let theta_vel; +let theta_acc; + +function setup() { + createCanvas(710, 400); + + // सभी मूल्यों को प्रारंभ करें + r = height * 0.45; + theta = 0; + theta_vel = 0; + theta_acc = 0.0001; +} + +function draw() { + background(0); + + // मूल बिंदु को स्क्रीन के केंद्र में अनुवाद करें + translate(width / 2, height / 2); + + // ध्रुवीय को कार्टेशियन में बदलें + let x = r * cos(theta); + let y = r * sin(theta); + + // कार्तीय निर्देशांक पर दीर्घवृत्त ड्रा करें + ellipseMode(CENTER); + noStroke(); + fill(200); + ellipse(x, y, 32, 32); + + // कोण पर त्वरण और वेग लागू करें + // (r इस उदाहरण में स्थिर रहता है) + theta_vel += theta_acc; + theta += theta_vel; +} diff --git a/dist/assets/examples/hi/08_Math/09_arctangent.js b/dist/assets/examples/hi/08_Math/09_arctangent.js new file mode 100644 index 0000000000..4d352779e7 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/09_arctangent.js @@ -0,0 +1,45 @@ +/* + * @name आर्कटिक + * @description आंखों की दिशा बदलने के लिए माउस ले जाएं।
atan2() फ़ंक्शन प्रत्येक आंख से कर्सर तक के कोण की गणना करता है। + */ +let e1, e2, e3; + +function setup() { + createCanvas(720, 400); + noStroke(); + e1 = new Eye(250, 16, 120); + e2 = new Eye(164, 185, 80); + e3 = new Eye(420, 230, 220); +} + +function draw() { + background(102); + e1.update(mouseX, mouseY); + e2.update(mouseX, mouseY); + e3.update(mouseX, mouseY); + e1.display(); + e2.display(); + e3.display(); +} + +function Eye(tx, ty, ts) { + this.x = tx; + this.y = ty; + this.size = ts; + this.angle = 0; + + this.update = function(mx, my) { + this.angle = atan2(my - this.y, mx - this.x); + }; + + this.display = function() { + push(); + translate(this.x, this.y); + fill(255); + ellipse(0, 0, this.size, this.size); + rotate(this.angle); + fill(153, 204, 0); + ellipse(this.size / 4, 0, this.size / 2, this.size / 2); + pop(); + }; +} diff --git a/dist/assets/examples/hi/08_Math/10_Interpolate.js b/dist/assets/examples/hi/08_Math/10_Interpolate.js new file mode 100644 index 0000000000..a52d1c30a3 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/10_Interpolate.js @@ -0,0 +1,34 @@ +/* + * @name रैखिक इंटरपोलेशन + * @frame 720, 400 + * @description माउस को स्क्रीन पर ले जाएँ और सिंबल उसके पीछे आ जाएगा। + * एनीमेशन के प्रत्येक फ्रेम को खींचने के बीच, दीर्घवृत्त भाग जाता है + * दूरी (0.05) की वर्तमान स्थिति से कर्सर की ओर का उपयोग कर + * lerp () फ़ंक्शन। + * यह केवल lerp() के साथ इनपुट के तहत ईजिंग जैसा ही है .. + */ + +let x = 0; +let y = 0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(51); + + // lerp () एक विशिष्ट वेतन वृद्धि पर दो संख्याओं के बीच की संख्या की गणना करता है। + // एएमटी पैरामीटर दो मानों के बीच प्रक्षेपित करने की राशि है + // जहां 0.0 पहले बिंदु के बराबर है, 0.1 पहले बिंदु के बहुत करीब है, 0.5 + // बीच में आधा रास्ता है, आदि। + + // यहां हम प्रत्येक फ्रेम में 5% रास्ते को माउस स्थान पर ले जा रहे हैं + x = lerp(x, mouseX, 0.05); + y = lerp(y, mouseY, 0.05); + + fill(255); + stroke(255); + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/hi/08_Math/11_doubleRandom.js b/dist/assets/examples/hi/08_Math/11_doubleRandom.js new file mode 100644 index 0000000000..e14d61e213 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/11_doubleRandom.js @@ -0,0 +1,24 @@ +/* + * @name डबल रैंडम + * @frame 720,400 (वैकल्पिक) + * @description दो random() कॉल और point() का उपयोग करना + * अनियमित चूरा रेखा बनाने का कार्य। + * मूल ईरा ग्रीनबर्ग द्वारा। + */ +let totalPts = 300; +let steps = totalPts + 1; + +function setup() { + createCanvas(710, 400); + stroke(255); + frameRate(1); +} + +function draw() { + background(0); + let rand = 0; + for (let i = 1; i < steps; i++) { + point((width / steps) * i, height / 2 + random(-rand, rand)); + rand += random(-5, 5); + } +} diff --git a/dist/assets/examples/hi/08_Math/12_random.js b/dist/assets/examples/hi/08_Math/12_random.js new file mode 100644 index 0000000000..20262af6f4 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/12_random.js @@ -0,0 +1,19 @@ +/* + * @name रैंडम + * @description रैंडम नंबर इस इमेज का आधार बनाते हैं। + * हर बार प्रोग्राम लोड होने पर परिणाम अलग होता है। + */ +function setup() { + createCanvas(710, 400); + background(0); + strokeWeight(20); + frameRate(2); +} + +function draw() { + for (let i = 0; i < width; i++) { + let r = random(255); + stroke(r); + line(i, 0, i, height); + } +} diff --git a/dist/assets/examples/hi/08_Math/13_noise1D.js b/dist/assets/examples/hi/08_Math/13_noise1D.js new file mode 100644 index 0000000000..6e42276175 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/13_noise1D.js @@ -0,0 +1,31 @@ +/* + * @name Noise1D + * @description स्थान निर्दिष्ट करने के लिए 1D Perlin Noise का उपयोग करना। + */ +let xoff = 0.0; +let xincrement = 0.01; + +function setup() { + createCanvas(710, 400); + background(0); + noStroke(); +} + +function draw() { + // एक अल्फा ब्लेंडेड बैकग्राउंड बनाएं + fill(0, 10); + rect(0, 0, width, height); + + // चलो n = यादृच्छिक (0, चौड़ाई); // शोर के बजाय इस लाइन को आजमाएं + + // xoff और स्केल के आधार पर शोर मान प्राप्त करें + // यह खिड़की की चौड़ाई के अनुसार है + let n = noise(xoff) * width; + + // प्रत्येक चक्र के साथ, वृद्धि xoff + xoff += xincrement; + + // पर्लिन शोर द्वारा उत्पन्न मूल्य पर दीर्घवृत्त को ड्रा करें + fill(200); + ellipse(n, height / 2, 64, 64); +} diff --git a/dist/assets/examples/hi/08_Math/14_noisewave.js b/dist/assets/examples/hi/08_Math/14_noisewave.js new file mode 100644 index 0000000000..24402452a1 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/14_noisewave.js @@ -0,0 +1,42 @@ +/* + * @name शोर लहर + * @description तरंग जैसा पैटर्न उत्पन्न करने के लिए पर्लिन शोर का उपयोग करना। + * डैनियल शिफमैन द्वारा मूल। + */ +let yoff = 0.0; // पर्लिन शोर का दूसरा आयाम + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(51); + + fill(255); + // हम तरंग बिंदुओं से एक बहुभुज बनाने जा रहे हैं + beginShape(); + + let xoff = 0; // विकल्प # 1: 2D शोर + // चलो xoff = yoff; // विकल्प # 2: 1D शोर + + // क्षैतिज पिक्सेल पर पुनरावृति + for (let x = 0; x <= width; x += 10) { + // शोर के अनुसार y मान की गणना करें, मानचित्र करें + + // विकल्प # 1: 2D शोर + let y = map(noise(xoff, yoff), 0, 1, 200, 300); + + // विकल्प # 2: 1D शोर + // चलो y = नक्शा (शोर (xoff), 0, 1, 200,300); + + // शीर्ष सेट करें + vertex(x, y); + // शोर के लिए वृद्धि x आयाम + xoff += 0.05; + } + // शोर के लिए वृद्धि y आयाम + yoff += 0.01; + vertex(width, height); + vertex(0, height); + endShape(CLOSE); +} diff --git a/dist/assets/examples/hi/08_Math/15_Noise2D.js b/dist/assets/examples/hi/08_Math/15_Noise2D.js new file mode 100644 index 0000000000..0c9dcf85ba --- /dev/null +++ b/dist/assets/examples/hi/08_Math/15_Noise2D.js @@ -0,0 +1,41 @@ +/* + * @name Noise2D + * @frame 710,400 (वैकल्पिक) + * @description विभिन्न मापदंडों के साथ एक 2D शोर बनाएँ। + * + */ +let noiseVal; +let noiseScale = 0.02; + +function setup() { + createCanvas(640, 360); +} + +function draw() { + background(0); + // छवि का बायां आधा भाग बनाएं + for (let y = 0; y < height - 30; y++) { + for (let x = 0; x < width / 2; x++) { + // पिक्सल ऑक्टेव काउंट और फॉलऑफ वैल्यू का noiceDetail + noiseDetail(2, 0.2); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + // छवि का दाहिना आधा भाग बनाएं + for (let y = 0; y < height - 30; y++) { + for (let x = width / 2; x < width; x++) { + // पिक्सल ऑक्टेव काउंट और फॉलऑफ वैल्यू का noiceDetail + noiseDetail(5, 0.5); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + // दो विभाजनों का विवरण दिखाएं + textSize(18); + fill(255, 255, 255); + text('Noice2D with 2 octaves and 0.2 falloff', 10, 350); + text('Noice2D with 1 octaves and 0.7 falloff', 330, 350); +} diff --git a/dist/assets/examples/hi/08_Math/16_Noise3D.js b/dist/assets/examples/hi/08_Math/16_Noise3D.js new file mode 100644 index 0000000000..beeb77b3f4 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/16_Noise3D.js @@ -0,0 +1,48 @@ +/* + * @name Noise3D + * @frame 710,400 (वैकल्पिक) + * @description सरल एनिमेटेड बनावट बनाने के लिए 3D शोर का उपयोग करना। + */ + +let noiseVal; +// वृद्धि x 0.01 +let x_increment = 0.01; +// प्रत्येक draw() चक्र में ०.०२ से z बढ़ाएँ +let z_increment = 0.02; + +// ऑफसेट मान +let z_off, y_off, x_off; + +function setup() { + // कैनवास बनाएं + createCanvas(640, 360); + // फ्रेम दर को परिभाषित करें + frameRate(20); + // z_off का प्रारंभिक मान + z_off = 0; +} + +function draw() { + x_off = 0; + y_off = 0; + // बैकग्राउंड को काला करें + background(0); + // नोटिस विवरण समायोजित करें + noiseDetail(8, 0.65); + + // प्रत्येक x, y के लिए नोइस मान की गणना करें + for (let y = 0; y < height; y++) { + x_off += x_increment; + y_off = 0; + + for (let x = 0; x < width; x++) { + // प्रत्येक पिक्सेल की गणना और ड्रा करें + noiseVal = noise(x_off, y_off, z_off); + stroke(noiseVal * 255); + y_off += x_increment; + point(x, y); + } + } + + z_off += z_increment; +} diff --git a/dist/assets/examples/hi/08_Math/17_Randomchords.js b/dist/assets/examples/hi/08_Math/17_Randomchords.js new file mode 100644 index 0000000000..b3bc8184de --- /dev/null +++ b/dist/assets/examples/hi/08_Math/17_Randomchords.js @@ -0,0 +1,35 @@ +/* + * @name रैंडम कॉर्ड्स + * @description एक वृत्त की यादृच्छिक जीवाओं को संचित करता है। पारभासी में प्रत्येक राग + * इसलिए वे एक छायांकित गोले का भ्रम देने के लिए जमा होते हैं। + * आतिश भाटिया द्वारा योगदान, एंडर्स हॉफ से प्रेरित + */ + +function setup() { + createCanvas(400, 400); + background(255, 255, 255); + + // अल्फा मान का उपयोग करके पारभासी स्ट्रोक + stroke(0, 0, 0, 15); +} + +function draw() { + // प्रत्येक फ्रेम में दो यादृच्छिक तार बनाएं + randomChord(); + randomChord(); +} + +function randomChord() { + // एक सर्कल पर एक यादृच्छिक बिंदु खोजें + let angle1 = random(0, 2 * PI); + let xpos1 = 200 + 200 * cos(angle1); + let ypos1 = 200 + 200 * sin(angle1); + + // सर्कल पर एक और यादृच्छिक बिंदु खोजें + let angle2 = random(0, 2 * PI); + let xpos2 = 200 + 200 * cos(angle2); + let ypos2 = 200 + 200 * sin(angle2); + + // उनके बीच एक रेखा खींचें + line(xpos1, ypos1, xpos2, ypos2); +} diff --git a/dist/assets/examples/hi/08_Math/18_Map.js b/dist/assets/examples/hi/08_Math/18_Map.js new file mode 100644 index 0000000000..c032d2ced6 --- /dev/null +++ b/dist/assets/examples/hi/08_Math/18_Map.js @@ -0,0 +1,22 @@ +/* + * @name नक्शा + * @description किसी भी संख्या को लेने के लिए map() फ़ंक्शन का उपयोग करें और इसे स्केल करें a + * नया नंबर जो उस प्रोजेक्ट के लिए अधिक उपयोगी है जिस पर आप काम कर रहे हैं। + * उदाहरण के लिए, किसी आकृति के आकार या रंग को नियंत्रित करने के लिए माउस की स्थिति से संख्याओं का उपयोग करें। + * इस उदाहरण में, माउस के x-निर्देशांक (0 और 360 के बीच की संख्या) को नए नंबरों तक बढ़ाया जाता है + * एक सर्कल के रंग और आकार को परिभाषित करने के लिए। + */ +function setup() { + createCanvas(640, 400); + noStroke(); +} + +function draw() { + background(0); + // माउसएक्स मान को 0 से 640 तक 0 और 175 . के बीच की सीमा तक स्केल करें + let c = map(mouseX, 0, width, 0, 175); + // माउसएक्स मान को 0 से 640 तक 40 और 300 के बीच की सीमा तक स्केल करें + let d = map(mouseX, 0, width, 40, 300); + fill(255, c, 0); + ellipse(width/2, height/2, d, d); +} diff --git a/dist/assets/examples/hi/08_Math/19_parametricEquation.js b/dist/assets/examples/hi/08_Math/19_parametricEquation.js new file mode 100644 index 0000000000..c4459068ef --- /dev/null +++ b/dist/assets/examples/hi/08_Math/19_parametricEquation.js @@ -0,0 +1,44 @@ +/* + * @name पैरामीट्रिक समीकरण + * @description एक पैरामीट्रिक समीकरण है जहाँ x और y + * निर्देशांक दोनों एक दूसरे अक्षर के रूप में लिखे गए हैं। यह है + * एक पैरामीटर कहा जाता है और आमतौर पर अक्षर t या में दिया जाता है। + * इसकी प्रेरणा एलेक्जेंडर मिलर के यूट्यूब चैनल से ली गई है। + */ + +function setup(){ + createCanvas(720,400); +} + +// वह पैरामीटर जिस पर x और y निर्भर करते हैं, आमतौर पर या तो t या थीटा के प्रतीक के रूप में लिया जाता है +let t = 0; +function draw(){ + background('#fff'); + translate(width/2,height/2); + stroke('#0f0f0f'); + strokeWeight(1.5); + //loop for adding 100 lines + for(let i = 0;i<100;i++){ + line(x1(t+i),y1(t+i),x2(t+i)+20,y2(t+i)+20); + } + t+=0.15; +} +// लाइन के प्रारंभिक x समन्वय को बदलने के लिए कार्य +function x1(t){ + return sin(t/10)*125+sin(t/20)*125+sin(t/30)*125; +} + +// लाइन के प्रारंभिक y समन्वय को बदलने के लिए कार्य change +function y1(t){ + return cos(t/10)*125+cos(t/20)*125+cos(t/30)*125; +} + +// लाइन के अंतिम x समन्वय को बदलने के लिए कार्य +function x2(t){ + return sin(t/15)*125+sin(t/25)*125+sin(t/35)*125; +} + +// लाइन के अंतिम y समन्वय को बदलने के लिए कार्य +function y2(t){ + return cos(t/15)*125+cos(t/25)*125+cos(t/35)*125; +} \ No newline at end of file diff --git a/dist/assets/examples/hi/09_Simulate/00_Forces.js b/dist/assets/examples/hi/09_Simulate/00_Forces.js new file mode 100644 index 0000000000..60d9de27a4 --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/00_Forces.js @@ -0,0 +1,148 @@ +/* + * @name बल + * @description निकायों पर अभिनय करने वाले कई बल का प्रदर्शन + * (natureofcode.com) + */ +// कई बल अभिनय का प्रदर्शन +// निकायों (प्रस्तावक वर्ग) +// शरीर लगातार गुरुत्वाकर्षण का अनुभव करते हैं +// जब "पानी" में निकायों को द्रव प्रतिरोध का अनुभव होता है + +// पांच गतिमान पिंड +let movers = []; + +// तरल +let liquid; + +function setup() { + createCanvas(640, 360); + reset(); + // तरल वस्तु बनाएं + liquid = new Liquid(0, height / 2, width, height / 2, 0.1); +} + +function draw() { + background(127); + + // पानी खींचो + liquid.display(); + + for (let i = 0; i < movers.length; i++) { + + // क्या प्रस्तावक तरल में है? + if (liquid.contains(movers[i])) { + // ड्रैग फोर्स की गणना करें + let dragForce = liquid.calculateDrag(movers[i]); + // मूवर पर ड्रैग फोर्स लागू करें + movers[i].applyForce(dragForce); + } + + // यहाँ द्रव्यमान द्वारा गुरुत्वाकर्षण को बढ़ाया जाता है! + let gravity = createVector(0, 0.1 * movers[i].mass); + // गुरुत्वाकर्षण लागू करें + movers[i].applyForce(gravity); + + // अद्यतन और प्रदर्शित करें + movers[i].update(); + movers[i].display(); + movers[i].checkEdges(); + } + +} + + +function mousePressed() { + reset(); +} + +// सभी मूवर ऑब्जेक्ट को बेतरतीब ढंग से पुनरारंभ करें +function reset() { + for (let i = 0; i < 9; i++) { + movers[i] = new Mover(random(0.5, 3), 40 + i * 70, 0); + } +} + +let Liquid = function(x, y, w, h, c) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + this.c = c; +}; + +// तरल में प्रस्तावक है? +Liquid.prototype.contains = function(m) { + let l = m.position; + return l.x > this.x && l.x < this.x + this.w && + l.y > this.y && l.y < this.y + this.h; +}; + +// ड्रैग फोर्स की गणना करें +Liquid.prototype.calculateDrag = function(m) { + // परिमाण गुणांक है * गति चुकता + let speed = m.velocity.mag(); + let dragMagnitude = this.c * speed * speed; + + // दिशा वेग के विपरीत है + let dragForce = m.velocity.copy(); + dragForce.mult(-1); + + // परिमाण के अनुसार पैमाना + // ड्रैगफोर्स.सेटमैग (ड्रैगमैग्निट्यूड); + dragForce.normalize(); + dragForce.mult(dragMagnitude); + return dragForce; +}; + +Liquid.prototype.display = function() { + noStroke(); + fill(50); + rect(this.x, this.y, this.w, this.h); +}; + +function Mover(m, x, y) { + this.mass = m; + this.position = createVector(x, y); + this.velocity = createVector(0, 0); + this.acceleration = createVector(0, 0); +} + +// न्यूटन का दूसरा नियम: F = M * A +// या ए = एफ / एम +Mover.prototype.applyForce = function(force) { + let f = p5.Vector.div(force, this.mass); + this.acceleration.add(f); +}; + +Mover.prototype.update = function() { + // त्वरण के अनुसार वेग बदलता है + this.velocity.add(this.acceleration); + // स्थिति वेग से बदलती है + this.position.add(this.velocity); + // हमें प्रत्येक फ्रेम में त्वरण को साफ करना चाहिए + this.acceleration.mult(0); +}; + +Mover.prototype.display = function() { + stroke(0); + strokeWeight(2); + fill(255,127); + ellipse(this.position.x, this.position.y, this.mass * 16, this.mass * 16); +}; + +// विंडो के नीचे से बाउंस करें +Mover.prototype.checkEdges = function() { + if (this.position.y > (height - this.mass * 8)) { + // नीचे से टकराते समय थोड़ा भीगना + this.velocity.y *= -0.9; + this.position.y = (height - this.mass * 8); + } +}; + + + + + + + + diff --git a/dist/assets/examples/hi/09_Simulate/01_ParticleSystem.js b/dist/assets/examples/hi/09_Simulate/01_ParticleSystem.js new file mode 100644 index 0000000000..c271b73916 --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/01_ParticleSystem.js @@ -0,0 +1,69 @@ +/* + * @name कण प्रणाली + * @description यह एक मूल कण प्रणाली है + * (natureofcode.com) + */ +let system; + +function setup() { + createCanvas(720, 400); + system = new ParticleSystem(createVector(width / 2, 50)); +} + +function draw() { + background(51); + system.addParticle(); + system.run(); +} + +// एक साधारण कण वर्ग +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// स्थिति को अद्यतन करने की विधि +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// प्रदर्शित करने की विधि +Particle.prototype.display = function() { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// क्या कण अभी भी उपयोगी है? +Particle.prototype.isDead = function(){ + return this.lifespan < 0; +}; + +let ParticleSystem = function(position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin)); +}; + +ParticleSystem.prototype.run = function() { + for (let i = this.particles.length-1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; diff --git a/dist/assets/examples/hi/09_Simulate/02_Flocking.js b/dist/assets/examples/hi/09_Simulate/02_Flocking.js new file mode 100644 index 0000000000..c40524fca7 --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/02_Flocking.js @@ -0,0 +1,229 @@ +/* + * @name झुंड + * @description क्रेग रेनॉल्ड्स के "झुंड" व्यवहार का प्रदर्शन। + * देखें: http://www.red3d.com/cwr/ + * नियम: सामंजस्य, पृथक्करण, संरेखण + * (natureofcode.com से)। + * सिस्टम में बोड्स जोड़ने के लिए माउस को ड्रैग करें। + */ + + +let flock; + +function setup() { + createCanvas(640, 360); + createP("Drag the mouse to generate new boids."); + + flock = new Flock(); + // सिस्टम में बोलियों का एक प्रारंभिक सेट जोड़ें + for (let i = 0; i < 100; i++) { + let b = new Boid(width / 2,height / 2); + flock.addBoid(b); + } +} + +function draw() { + background(51); + flock.run(); +} + +// सिस्टम में एक नया बोड जोड़ें +function mouseDragged() { + flock.addBoid(new Boid(mouseX, mouseY)); +} + +// कोड की प्रकृति +// डैनियल शिफमैन +// http://natureofcode.com + +// झुंड वस्तु +// बहुत कम करता है, बस सभी बोलियों की सरणी का प्रबंधन करता है + +function Flock() { + // सभी बोलियों के लिए एक सरणी + this.boids = []; // सरणी को इनिशियलाइज़ करें +} + +Flock.prototype.run = function() { + for (let i = 0; i < this.boids.length; i++) { + this.boids[i].run(this.boids); // प्रत्येक बोली को व्यक्तिगत रूप से बोलियों की पूरी सूची पास करना + } +} + +Flock.prototype.addBoid = function(b) { + this.boids.push(b); +} + +// कोड की प्रकृति +// डैनियल शिफमैन +// http://natureofcode.com + +// बोएड क्लास +// पृथक्करण, सामंजस्य, संरेखण के तरीके जोड़े गए + +function Boid(x, y) { + this.acceleration = createVector(0, 0); + this.velocity = createVector(random(-1, 1), random(-1, 1)); + this.position = createVector(x, y); + this.r = 3.0; + this.maxspeed = 3; // अधिकतम गति + this.maxforce = 0.05; // अधिकतम स्टीयरिंग बल +} + +Boid.prototype.run = function(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); +} + +Boid.prototype.applyForce = function(force) { + // यदि हम A = F / M . चाहते हैं तो हम यहाँ द्रव्यमान जोड़ सकते हैं + this.acceleration.add(force); +} + +// हम हर बार तीन नियमों के आधार पर एक नया त्वरण जमा करते हैं +Boid.prototype.flock = function(boids) { + let sep = this.separate(boids); // पृथक्करण + let ali = this.align(boids); // संरेखण + let coh = this.cohesion(boids); // सामंजस्य + // मनमाने ढंग से इन ताकतों को तौलें + sep.mult(1.5); + ali.mult(1.0); + coh.mult(1.0); + // बल वैक्टर को त्वरण में जोड़ें + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); +} + +// स्थान अपडेट करने की विधि +Boid.prototype.update = function() { + // वेग अपडेट करें + this.velocity.add(this.acceleration); + // सीमा गति + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // त्वरण को प्रत्येक चक्र में 0 पर रीसेट करें + this.acceleration.mult(0); +} + +// एक विधि जो एक लक्ष्य की ओर एक स्टीयरिंग बल की गणना और लागू करती है +// स्टीयर = वांछित माइनस वेलोसिटी +Boid.prototype.seek = function(target) { + let desired = p5.Vector.sub(target,this.position); // स्थान से लक्ष्य की ओर इशारा करते हुए एक वेक्टर + // वांछित और स्केल को अधिकतम गति के लिए सामान्यीकृत करें + desired.normalize(); + desired.mult(this.maxspeed); + // संचालन = वांछित शून्य वेग + let steer = p5.Vector.sub(desired,this.velocity); + steer.limit(this.maxforce); // अधिकतम स्टीयरिंग बल तक सीमित करें + return steer; +} + +Boid.prototype.render = function() { + // वेग की दिशा में घुमाया गया एक त्रिभुज बनाएं + let theta = this.velocity.heading() + radians(90); + fill(127); + stroke(200); + push(); + translate(this.position.x, this.position.y); + rotate(theta); + beginShape(); + vertex(0, -this.r * 2); + vertex(-this.r, this.r * 2); + vertex(this.r, this.r * 2); + endShape(CLOSE); + pop(); +} + +// चारों ओर लपेट दो +Boid.prototype.borders = function() { + if (this.position.x < -this.r) this.position.x = width + this.r; + if (this.position.y < -this.r) this.position.y = height + this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height + this.r) this.position.y = -this.r; +} + +// पृथक्करण +// विधि आस-पास के boids के लिए जाँच करता है और दूर चला जाता है +Boid.prototype.separate = function(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // सिस्टम में प्रत्येक बोड के लिए, जांचें कि क्या यह बहुत करीब है + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + // यदि दूरी 0 से अधिक है और मनमानी राशि से कम है (0 जब आप स्वयं हों) + if ((d > 0) && (d < desiredseparation)) { + // पड़ोसी से दूर की ओर इशारा करते हुए वेक्टर की गणना करें + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // दूरी से वजन + steer.add(diff); + count++; // कितने का ट्रैक रखें + } + } + // औसत -- कितने से विभाजित करें + if (count > 0) { + steer.div(count); + } + + // जब तक वेक्टर 0 . से बड़ा है + if (steer.mag() > 0) { + // रेनॉल्ड्स को लागू करें: संचालन = वांछित - वेग + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; +} + +// संरेखण +// सिस्टम में प्रत्येक पास के बोड के लिए, औसत वेग की गणना करें +Boid.prototype.align = function(boids) { + let neighbordist = 50; + let sum = createVector(0,0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } +} + +// सामंजस्य +// आस-पास के सभी बोड्स के औसत स्थान (अर्थात केंद्र) के लिए, उस स्थान की ओर स्टीयरिंग वेक्टर की गणना करें +Boid.prototype.cohesion = function(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // सभी स्थानों को जमा करने के लिए खाली वेक्टर से शुरू करें + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // स्थान जोड़ना + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // स्थान की ओर बढ़ें + } else { + return createVector(0, 0); + } +} + + diff --git a/dist/assets/examples/hi/09_Simulate/03_WolframCA.js b/dist/assets/examples/hi/09_Simulate/03_WolframCA.js new file mode 100644 index 0000000000..fd36eb4880 --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/03_WolframCA.js @@ -0,0 +1,73 @@ +/* + * @name वोल्फ्राम सीए + * @description वुल्फराम 1-आयामी सेलुलर ऑटोमेटा का सरल प्रदर्शन + * (natureofcode.com) + */ + +let w = 10; +// 0s और 1s की एक सरणी +let cells; + +// हम मनमाने ढंग से "1" की स्थिति वाले केवल मध्य सेल से शुरू करते हैं +let generation = 0; + +// नियम सेट को स्टोर करने के लिए एक सरणी, उदाहरण के लिए {0,1,1,0,1,1,0,1} +let ruleset = [0, 1, 0, 1, 1, 0, 1, 0]; + +function setup() { + createCanvas(640, 400); + cells = Array(floor(width / w)); + for (let i = 0; i < cells.length; i++) { + cells[i] = 0; + } + cells[cells.length/2] = 1; + +} + +function draw() { + for (let i = 0; i < cells.length; i++) { + if (cells[i] === 1) { + fill(200); + } else { + fill(51); + noStroke(); + rect(i * w, generation * w, w, w); + } + } + if (generation < height/w) { + generate(); + } +} + +// नई पीढ़ी बनाने की प्रक्रिया +function generate() { + // पहले हम नए मूल्यों के लिए एक खाली सरणी बनाते हैं + let nextgen = Array(cells.length); + // प्रत्येक स्थान के लिए, वर्तमान स्थिति और पड़ोसी राज्यों की जांच करके नए राज्य का निर्धारण करें + // किनारों को अनदेखा करें जिनमें केवल एक पड़ोसी हो + for (let i = 1; i < cells.length-1; i++) { + let left = cells[i-1]; // वाम पड़ोसी राज्य + let me = cells[i]; // वर्तमान स्थिति + let right = cells[i+1]; // सही पड़ोसी राज्य + nextgen[i] = rules(left, me, right); // नियमों के आधार पर अगली पीढ़ी की स्थिति की गणना करें + } + // वर्तमान पीढ़ी नई पीढ़ी है + cells = nextgen; + generation++; +} + + +// वोल्फ्राम नियमों को लागू करना +// सुधार किया जा सकता है और अधिक संक्षिप्त बनाया जा सकता है, लेकिन यहां हम स्पष्ट रूप से देख सकते हैं कि प्रत्येक मामले के लिए क्या चल रहा है +function rules(a, b, c) { + if (a == 1 && b == 1 && c == 1) return ruleset[0]; + if (a == 1 && b == 1 && c == 0) return ruleset[1]; + if (a == 1 && b == 0 && c == 1) return ruleset[2]; + if (a == 1 && b == 0 && c == 0) return ruleset[3]; + if (a == 0 && b == 1 && c == 1) return ruleset[4]; + if (a == 0 && b == 1 && c == 0) return ruleset[5]; + if (a == 0 && b == 0 && c == 1) return ruleset[6]; + if (a == 0 && b == 0 && c == 0) return ruleset[7]; + return 0; +} + diff --git a/dist/assets/examples/hi/09_Simulate/04_GameOfLife.js b/dist/assets/examples/hi/09_Simulate/04_GameOfLife.js new file mode 100644 index 0000000000..6da1a7670d --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/04_GameOfLife.js @@ -0,0 +1,93 @@ + /* + * @name Game of Life + * @description जॉन कॉनवे के गेम ऑफ लाइफ सीए का एक बुनियादी कार्यान्वयन + * (natureofcode.com) + */ +let w; +let columns; +let rows; +let board; +let next; + +function setup() { + createCanvas(720, 400); + w = 20; + // कॉलम और पंक्तियों की गणना करें + columns = floor(width / w); + rows = floor(height / w); + // 2D सरणी बनाने का निराला तरीका JS है + board = new Array(columns); + for (let i = 0; i < columns; i++) { + board[i] = new Array(rows); + } + // कई 2D सरणियों का उपयोग करने जा रहे हैं और उन्हें स्वैप करें + next = new Array(columns); + for (i = 0; i < columns; i++) { + next[i] = new Array(rows); + } + init(); +} + +function draw() { + background(255); + generate(); + for ( let i = 0; i < columns;i++) { + for ( let j = 0; j < rows;j++) { + if ((board[i][j] == 1)) fill(0); + else fill(255); + stroke(0); + rect(i * w, j * w, w-1, w-1); + } + } + +} + +// माउस दबाए जाने पर बोर्ड को रीसेट करें +function mousePressed() { + init(); +} + +// बेतरतीब ढंग से बोर्ड भरें +function init() { + for (let i = 0; i < columns; i++) { + for (let j = 0; j < rows; j++) { + // किनारों को 0s . के साथ पंक्तिबद्ध करना + if (i == 0 || j == 0 || i == columns-1 || j == rows-1) board[i][j] = 0; + // बाकी को बेतरतीब ढंग से भरना + else board[i][j] = floor(random(2)); + next[i][j] = 0; + } + } +} + +// नई पीढ़ी बनाने की प्रक्रिया +function generate() { + +// हमारे 2D सरणी में प्रत्येक स्थान के माध्यम से लूप करें और स्पॉट पड़ोसियों की जाँच करें + for (let x = 1; x < columns - 1; x++) { + for (let y = 1; y < rows - 1; y++) { + // सभी राज्यों को 3x3 आसपास के ग्रिड में जोड़ें + let neighbors = 0; + for (let i = -1; i <= 1; i++) { + for (let j = -1; j <= 1; j++) { + neighbors += board[x+i][y+j]; + } + } + + // वर्तमान सेल की स्थिति को घटाने के लिए एक छोटी सी चाल + // हमने इसे उपरोक्त लूप में जोड़ा है + neighbors -= board[x][y]; + // Rules of Life + if ((board[x][y] == 1) && (neighbors < 2)) next[x][y] = 0; // तनहाई + else if ((board[x][y] == 1) && (neighbors > 3)) next[x][y] = 0; // अधिक आबादी वाला + else if ((board[x][y] == 0) && (neighbors == 3)) next[x][y] = 1; //पुन: उत्पन्न करें + else next[x][y] = board[x][y]; // ठहराव + } + } + + // स्वैप करें! + let temp = board; + board = next; + next = temp; +} + diff --git a/dist/assets/examples/hi/09_Simulate/05_MultipleParticleSystems.js b/dist/assets/examples/hi/09_Simulate/05_MultipleParticleSystems.js new file mode 100644 index 0000000000..04456e7f3e --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/05_MultipleParticleSystems.js @@ -0,0 +1,138 @@ +/* + * @name मल्टीपल पार्टिकल सिस्टम + * @description माउस स्थान पर कणों का एक विस्फोट उत्पन्न करने के लिए माउस पर क्लिक करें।
प्रत्येक फट कण और क्रेज़ीपार्टिकल्स (कण का एक उपवर्ग) के साथ एक कण प्रणाली का एक उदाहरण है।
यहां वंशानुक्रम और बहुरूपता के उपयोग पर ध्यान दें।
+ * डैनियल शिफमैन द्वारा मूल। + */ +let systems; + +function setup() { + createCanvas(710, 400); + systems = []; +} + +function draw() { + background(51); + background(0); + for (i = 0; i < systems.length; i++) { + systems[i].run(); + systems[i].addParticle(); + } + if (systems.length == 0) { + fill(255); + textAlign(CENTER); + textSize(32); + text("click mouse to add particle systems", width / 2, height / 2); + } +} + +function mousePressed() { + this.p = new ParticleSystem(createVector(mouseX, mouseY)); + systems.push(p); +} + +// एक साधारण कण वर्ग +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255.0; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// स्थिति को अद्यतन करने की विधि +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// प्रदर्शित करने की विधि +Particle.prototype.display = function () { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// क्या कण अभी भी उपयोगी है? +Particle.prototype.isDead = function () { + if (this.lifespan < 0) { + return true; + } else { + return false; + } +}; + +let ParticleSystem = function (position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function () { + // सिस्टम में या तो एक कण या क्रेजीपार्टिकल जोड़ें + if (int(random(0, 2)) == 0) { + p = new Particle(this.origin); + } + else { + p = new CrazyParticle(this.origin); + } + this.particles.push(p); +}; + +ParticleSystem.prototype.run = function () { + for (let i = this.particles.length - 1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; + +// कण का एक उपवर्ग + +function CrazyParticle(origin) { + // सुनिश्चित करें कि पैरेंट कंस्ट्रक्टर को कॉल करें (फ़ंक्शन # कॉल का उपयोग करके) + // कि "यह" कॉल के दौरान सही ढंग से सेट है + Particle.call(this, origin); + + // हमारे जोड़े गए गुणों को प्रारंभ करें + this.theta = 0.0; +}; + +// एक क्रेजी.प्रोटोटाइप ऑब्जेक्ट बनाएं जो पार्टिकल.प्रोटोटाइप से विरासत में मिले। +// नोट: यहां एक सामान्य त्रुटि "नया कण ()" बनाने के लिए उपयोग करना है +// क्रेजी.प्रोटोटाइप। यह कई कारणों से गलत है, कम से कम +// कि हमारे पास "मूल" के लिए कण देने के लिए कुछ भी नहीं है +// बहस। पार्टिकल को कॉल करने का सही स्थान ऊपर है, जहां हम कॉल करते हैं +// यह पागल से। +CrazyParticle.prototype = Object.create(Particle.prototype); // नीचे दिए गए नोट देखें + +// क्रेजीपार्टिकल को संदर्भित करने के लिए "कन्स्ट्रक्टर" संपत्ति सेट करें +CrazyParticle.prototype.constructor = CrazyParticle; + +// ध्यान दें कि हमारे पास यहां रन () विधि नहीं है; यह कण से विरासत में मिला है + +// यह अद्यतन () विधि मूल वर्ग अद्यतन () विधि को ओवरराइड करती है +CrazyParticle.prototype.update=function() { + Particle.prototype.update.call(this); + // क्षैतिज वेग के आधार पर वृद्धि रोटेशन + this.theta += (this.velocity.x * this.velocity.mag()) / 10.0; +} + +// यह डिस्प्ले () मेथड पैरेंट क्लास डिस्प्ले () मेथड को ओवरराइड करता है +CrazyParticle.prototype.display=function() { + // एक नियमित कण की तरह ही दीर्घवृत्त को प्रस्तुत करें + Particle.prototype.display.call(this); + // फिर एक घूर्णन रेखा जोड़ें + push(); + translate(this.position.x, this.position.y); + rotate(this.theta); + stroke(255, this.lifespan); + line(0, 0, 25, 0); + pop(); +} diff --git a/dist/assets/examples/hi/09_Simulate/06_Spirograph.js b/dist/assets/examples/hi/09_Simulate/06_Spirograph.js new file mode 100644 index 0000000000..0401c344d4 --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/06_Spirograph.js @@ -0,0 +1,73 @@ + +/* + * @name स्पाइरोग्राफ + * @description यह स्केच a . बनाने के लिए सरल परिवर्तनों का उपयोग करता है + * इंटरलॉकिंग सर्कल (साइन कहा जाता है) के साथ स्पाइरोग्राफ जैसा प्रभाव। + * ट्रेसिंग और अंतर्निहित ज्यामिति दिखाने के बीच स्विच करने के लिए स्पेसबार दबाएं।
+ * उदाहरण R द्वारा बनाया गया है। ल्यूक डुबोइस.
+ * http://en.wikipedia.org/wiki/Spirograph + */ +let NUMSINES = 20; // इनमें से कितनी चीजें हम एक साथ कर सकते हैं? +let sines = new Array(NUMSINES); // सभी मौजूदा कोणों को पकड़ने के लिए एक सरणी +let rad; // केंद्रीय साइन के लिए एक प्रारंभिक त्रिज्या मान +let i; // एक काउंटर चर + +// क्या हो रहा है इसका अंदाजा लगाने के लिए इनके साथ खेलें: +let fund = 0.005; // केंद्रीय साइन की गति +let ratio = 1; // गति के लिए कौन सा गुणक प्रत्येक अतिरिक्त ज्या है? +let alpha = 50; // ट्रेसिंग सिस्टम कितना अपारदर्शी है + +let trace = false; // क्या हम ट्रेस कर रहे हैं? + +function setup() { + createCanvas(710, 400); + + rad = height / 4; // केंद्रीय सर्कल के लिए त्रिज्या की गणना करें + background(204); // स्क्रीन साफ़ करें + + for (let i = 0; i + * उदाहरण R द्वारा बनाया गया है। ल्यूक डुबोइस.
+ * https://en.wikipedia.org/wiki/L-system + */ +// कछुआ सामान: +let x, y; // कछुए की वर्तमान स्थिति +let currentangle = 0; // कछुआ किस ओर इशारा कर रहा है +let step = 20; // प्रत्येक 'एफ' के साथ कछुआ कितना चलता है +let angle = 90; // कछुआ '-' या '+' से कितना मुड़ता है + +// लिंडेनमेयर स्टफ (एल-सिस्टम) +let thestring = 'A'; // "स्वयंसिद्ध" या स्ट्रिंग की शुरुआत +let numloops = 5; // पूर्व-गणना करने के लिए कितने पुनरावृत्तियों +let therules = []; // नियमों के लिए सरणी +therules[0] = ['A', '-BF+AFA+FB-']; // पहला नियम +therules[1] = ['B', '+AF-BFB-FA+']; // दूसरा नियम + +let whereinstring = 0; // एल-सिस्टम में हम कहां हैं? + +function setup() { + createCanvas(710, 400); + background(255); + stroke(0, 0, 0, 255); + + // निचले-बाएँ कोने पर x और y स्थिति शुरू करें + x = 0; + y = height-1; + + // एल-सिस्टम की गणना करें + for (let i = 0; i < numloops; i++) { + thestring = lindenmayer(thestring); + } +} + +function draw() { + + // स्ट्रिंग में वर्तमान वर्ण बनाएं: + drawIt(thestring[whereinstring]); + + // उस बिंदु को बढ़ाएं जहां हम स्ट्रिंग पढ़ रहे हैं। + // अंत में चारों ओर लपेटें। + whereinstring++; + if (whereinstring > thestring.length-1) whereinstring = 0; + +} + +// एल-सिस्टम की व्याख्या करें +function lindenmayer(s) { + let outputstring = ''; // एक खाली आउटपुट स्ट्रिंग शुरू करें + + // प्रतीक मिलान की तलाश में 'थेरुल्स' के माध्यम से पुनरावृति करें: + for (let i = 0; i < s.length; i++) { + let ismatch = 0; // डिफ़ॉल्ट रूप से, कोई मिलान नहीं + for (let j = 0; j < therules.length; j++) { + if (s[i] == therules[j][0]) { + outputstring += therules[j][1]; // प्रतिस्थापन लिखें + ismatch = 1; // हमारे पास एक मैच है, इसलिए प्रतीक पर कॉपी न करें + break; // इसके लिए () लूप से बाहर निकलें + } + } + // अगर कुछ भी मेल नहीं खाता है, तो बस प्रतीक को कॉपी करें। + if (ismatch == 0) outputstring+= s[i]; + } + + return outputstring; // संशोधित स्ट्रिंग भेजें +} + +// यह एक कस्टम फ़ंक्शन है जो टर्टल कमांड खींचता है +function drawIt(k) { + + if (k=='F') { // आगे बढ़ें + // स्टेप और करंट एंगल के आधार पर ध्रुवीय से कार्टेशियन: + let x1 = x + step*cos(radians(currentangle)); + let y1 = y + step*sin(radians(currentangle)); + line(x, y, x1, y1); // पुराने और नए को कनेक्ट करें + + // कछुए की स्थिति को अपडेट करें: + x = x1; + y = y1; + } else if (k == '+') { + currentangle += angle; // बांए मुड़िए + } else if (k == '-') { + currentangle -= angle; // दांए मुड़िए + } + + // मुझे कुछ यादृच्छिक रंग मान दें: + let r = random(128, 255); + let g = random(0, 192); + let b = random(0, 50); + let a = random(50, 100); + + // त्रिज्या के लिए एक गाऊसी (डी एंड डी) वितरण चुनें: + let radius = 0; + radius += random(0, 15); + radius += random(0, 15); + radius += random(0, 15); + radius = radius / 3; + + // सामान ड्रा करें: + fill(r, g, b, a); + ellipse(x, y, radius, radius); +} \ No newline at end of file diff --git a/dist/assets/examples/hi/09_Simulate/08_Spring.js b/dist/assets/examples/hi/09_Simulate/08_Spring.js new file mode 100644 index 0000000000..a88e27454a --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/08_Spring.js @@ -0,0 +1,92 @@ +/* + * @name वसंत + * @frame 710, 400 + * @description वसंत शुरू करने के लिए क्षैतिज पट्टी पर क्लिक करें, खींचें और छोड़ें। + */ +// शीर्ष बार के लिए स्प्रिंग ड्राइंग स्थिरांक +let springHeight = 32, + left, + right, + maxHeight = 200, + minHeight = 100, + over = false, + move = false; + +// स्प्रिंग सिमुलेशन स्थिरांक +let M = 0.8, // द्रव्यमान + K = 0.2, // वसंत निरंतर + D = 0.92, // भिगोना + R = 150; // स्थिति को विश्राम दें + +// स्प्रिंग सिमुलेशन चर +let ps = R, // पद + vs = 0.0, // वेग + as = 0, // त्वरण + f = 0; // बल + +function setup() { + createCanvas(710, 400); + rectMode(CORNERS); + noStroke(); + left = width / 2 - 100; + right = width / 2 + 100; +} + +function draw() { + background(102); + updateSpring(); + drawSpring(); +} + +function drawSpring() { + // ड्रा बेस + fill(0.2); + let baseWidth = 0.5 * ps + -8; + rect(width / 2 - baseWidth, ps + springHeight, width / 2 + baseWidth, height); + + // रंग सेट करें और शीर्ष पट्टी बनाएं + if (over || move) { + fill(255); + } else { + fill(204); + } + + rect(left, ps, right, ps + springHeight); +} + +function updateSpring() { + // वसंत की स्थिति को अपडेट करें + if ( !move ) { + f = -K * ( ps - R ); // f=-ky + as = f / M; // त्वरण सेट करें, f=ma == a=f/m + vs = D * (vs + as); // वेग सेट करें + ps = ps + vs; // अद्यतन स्थिति + } + + if (abs(vs) < 0.1) { + vs = 0.0; + } + + // परीक्षण करें कि क्या माउस शीर्ष बार पर है + if (mouseX > left && mouseX < right && mouseY > ps && mouseY < ps + springHeight) { + over = true; + } else { + over = false; + } + + // शीर्ष बार की स्थिति को सेट और विवश करें + if (move) { + ps = mouseY - springHeight / 2; + ps = constrain(ps, minHeight, maxHeight); + } +} + +function mousePressed() { + if (over) { + move = true; + } +} + +function mouseReleased() { + move = false; +} diff --git a/dist/assets/examples/hi/09_Simulate/09_Springs.js b/dist/assets/examples/hi/09_Simulate/09_Springs.js new file mode 100644 index 0000000000..94bbc8133b --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/09_Springs.js @@ -0,0 +1,147 @@ +/* + * @name स्प्रिंग्स + * @frame 710,400 + * @description माउस को किसी एक सर्कल के ऊपर ले जाएं और फिर से स्थिति में लाने के लिए क्लिक करें। + * जब आप माउस को छोड़ते हैं, तो यह वापस स्थिति में आ जाएगा। + * प्रत्येक मंडली का व्यवहार थोड़ा अलग होता है। + * (https://processing.org/examples/springs.html से पोर्ट किया गया) + */ +let num = 3; +let springs = []; + +function setup() { + createCanvas(710, 400); + noStroke(); + + springs[0] = new Spring(240, 260, 40, 0.98, 8.0, 0.1, springs, 0); + springs[1] = new Spring(320, 210, 120, 0.95, 9.0, 0.1, springs, 1); + springs[2] = new Spring(180, 170, 200, 0.90, 9.9, 0.1, springs, 2); +} + +function draw() { + background(51); + + for (let i = 0; i < num; i++) { + springs[i].update(); + springs[i].display(); + } +} + +function mousePressed() { + for (let i = 0; i < num; i++) { + springs[i].pressed(); + } +} + +function mouseReleased() { + for (let i = 0; i < num; i++) { + springs[i].released(); + } +} + +// स्प्रिंग क्लास +function Spring (_x, _y, _s, _d, _m, _k_in, _others, _id) { +// स्क्रीन मान + // यह। एक्सपोस = _x; + // this.ypos = _y; + + this.x_pos = _x; + this.y_pos= _y; + + this.size = 20; + this.size = _s; + + this.over = false; + this.move = false; + + // स्प्रिंग सिमुलेशन स्थिरांक + this.mass = _m; // द्रव्यमान + this.k = 0.2; // वसंत निरंतर + this.k = _k_in; + this.damp = _d; // भिगोना + this.rest_posx = _x; // आराम की स्थिति X + this.rest_posy = _y; // आराम की स्थिति Y + + // स्प्रिंग सिमुलेशन चर + // फ्लोट पॉज़ = 20.0; // पद + this.velx = 0.0; // एक्स वेग + this.vely = 0.0; // वाई वेग + this.accel = 0; // त्वरण + this.force = 0; // बल + + this.friends = _others; + this.id = _id; + + this.update = function() { + + if (this.move) { + this.rest_posy = mouseY; + this.rest_posx = mouseX; + } + + this.force = -this.k * (this.y_pos - this.rest_posy); // f=-ky + this.accel = this.force / this.mass; // त्वरण सेट करें, f=ma == a=f/m + this.vely = this.damp * (this.vely + this.accel); // वेग सेट करें + this.y_pos = this.y_pos + this.vely; // अद्यतन स्थिति + + + this.force = -this.k * (this.x_pos - this.rest_posx); // f=-ky + this.accel = this.force / this.mass; // त्वरण सेट करें, f=ma == a=f/m + this.velx = this.damp * (this.velx + this.accel); // वेग सेट करें + this.x_pos = this.x_pos + this.velx; // अद्यतन स्थिति + + + if ((this.overEvent() || this.move) && !(this.otherOver()) ) { + this.over = true; + } else { + this.over = false; + } + } + + // यह देखने के लिए परीक्षण करें कि क्या माउस इस वसंत के ऊपर है + this.overEvent = function() { + let disX = this.x_pos - mouseX; + let disY = this.y_pos - mouseY; + let dis = createVector(disX, disY); + if (dis.mag() < this.size / 2 ) { + return true; + } else { + return false; + } + } + + // सुनिश्चित करें कि कोई अन्य स्प्रिंग सक्रिय नहीं है + this.otherOver = function() { + for (let i = 0; i < num; i++) { + if (i != this.id) { + if (this.friends[i].over == true) { + return true; + } + } + } + return false; + } + + this.display = function() { + if (this.over) { + fill(153); + } else { + fill(255); + } + ellipse(this.x_pos, this.y_pos, this.size, this.size); + } + + this.pressed = function() { + if (this.over) { + this.move = true; + } else { + this.move = false; + } + } + + this.released = function() { + this.move = false; + this.rest_posx = this.y_pos; + this.rest_posy = this.y_pos; + } +}; \ No newline at end of file diff --git a/dist/assets/examples/hi/09_Simulate/10_SoftBody.js b/dist/assets/examples/hi/09_Simulate/10_SoftBody.js new file mode 100644 index 0000000000..fb69999bdd --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/10_SoftBody.js @@ -0,0 +1,110 @@ +/* + * @name शीतल शरीर + * @description इरा ग्रीनबर्ग द्वारा मूल उदाहरण। + *

कर्ववर्टेक्स () और कर्वटाइटनेस () का उपयोग करके सॉफ्टबॉडी डायनेमिक्स सिमुलेशन। + */ +// केंद्र बिंदु +let centerX = 0.0, centerY = 0.0; + +let radius = 45, rotAngle = -90; +let accelX = 0.0, accelY = 0.0; +let deltaX = 0.0, deltaY = 0.0; +let springing = 0.0009, damping = 0.98; + +// कोने के नोड्स +let nodes = 5; + +// शून्य भरण सरणियाँ +let nodeStartX = []; +let nodeStartY = []; +let nodeX = []; +let nodeY = []; +let angle = []; +let frequency = []; + +// सॉफ्ट-बॉडी डायनामिक्स +let organicConstant = 1.0; + +function setup() { + createCanvas(710, 400); + + // विंडो में केंद्र का आकार + centerX = width / 2; + centerY = height / 2; + + // सरणियों को 0 . पर इनिशियलाइज़ करें + for (let i = 0; i < nodes; i++){ + nodeStartX[i] = 0; + nodeStartY[i] = 0; + nodeY[i] = 0; + nodeY[i] = 0; + angle[i] = 0; + } + + // कोने के नोड्स के लिए आवृत्तियों को प्रारंभ करें + for (let i = 0; i < nodes; i++){ + frequency[i] = random(5, 12); + } + + noStroke(); + frameRate(30); +} + +function draw() { + // फीका पृष्ठभूमि + fill(0, 100); + rect(0, 0, width, height); + drawShape(); + moveShape(); +} + +function drawShape() { + // नोड के शुरुआती स्थानों की गणना करें + for (let i = 0; i < nodes; i++){ + nodeStartX[i] = centerX + cos(radians(rotAngle)) * radius; + nodeStartY[i] = centerY + sin(radians(rotAngle)) * radius; + rotAngle += 360.0 / nodes; + } + + // बहुभुज बनाएं + curveTightness(organicConstant); + fill(255); + beginShape(); + for (let i = 0; i < nodes; i++){ + curveVertex(nodeX[i], nodeY[i]); + } + for (let i = 0; i < nodes-1; i++){ + curveVertex(nodeX[i], nodeY[i]); + } + endShape(CLOSE); +} + +function moveShape() { + // केंद्र बिंदु ले जाएँ + deltaX = mouseX - centerX; + deltaY = mouseY - centerY; + + // स्प्रिंग इफेक्ट बनाएं + deltaX *= springing; + deltaY *= springing; + accelX += deltaX; + accelY += deltaY; + + // शिकारी के केंद्र को स्थानांतरित करें + centerX += accelX; + centerY += accelY; + + // स्प्रिंगिंग को धीमा करें + accelX *= damping; + accelY *= damping; + + // वक्र की जकड़न बदलें + organicConstant = 1 - ((abs(accelX) + abs(accelY)) * 0.1); + + // नोड्स ले जाएँ + for (let i = 0; i < nodes; i++){ + nodeX[i] = nodeStartX[i] + sin(radians(angle[i])) * (accelX * 2); + nodeY[i] = nodeStartY[i] + sin(radians(angle[i])) * (accelY * 2); + angle[i] += frequency[i]; + } +} diff --git a/dist/assets/examples/hi/09_Simulate/11_SmokeParticleSystem.js b/dist/assets/examples/hi/09_Simulate/11_SmokeParticleSystem.js new file mode 100644 index 0000000000..259275ac0b --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/11_SmokeParticleSystem.js @@ -0,0 +1,178 @@ +/* + * @name स्मोकपार्टिकल्स + * @description डैन शिफमैन के स्मोकपार्टिकल सिस्टम उदाहरण का एक पोर्ट मूल रूप से वर्णन करें + * प्रसंस्करण के लिए। धुएँ के रंग के कण बनाता है :p + */ + +// कण के लिए बनावट +let particle_texture = null; + +// हमारे कण प्रणाली को धारण करने वाला चर +let ps = null; + +function preload() { + particle_texture = loadImage("assets/particle_texture.png"); +} + +function setup() { + + // कैनवास का आकार निर्धारित करें + createCanvas(640, 360); + + // हमारे कण प्रणाली को इनिशियलाइज़ करें + ps = new ParticleSystem(0, createVector(width / 2, height - 60), particle_texture); +} + +function draw() { + background(0); + + let dx = map(mouseX, 0, width, -0.2, 0.2); + let wind = createVector(dx, 0); + + ps.applyForce(wind); + ps.run(); + for (let i = 0; i < 2; i++) { + ps.addParticle(); + } + + // वायु शक्ति का प्रतिनिधित्व करने वाला एक तीर खींचें + drawVector(wind, createVector(width / 2, 50, 0), 500); +} + +/** + * यह फ़ंक्शन हमारी "हवा" की दिशा को दर्शाने वाला एक तीर खींचता है। + */ +function drawVector(v, loc, scale){ + push(); + let arrowsize = 4; + translate(loc.x, loc.y); + stroke(255); + rotate(v.heading()); + + let len = v.mag() * scale; + line(0, 0, len,0); + line(len, 0, len-arrowsize, +arrowsize / 2); + line(len, 0, len-arrowsize, -arrowsize / 2); + pop(); +} +//========= कण प्रणाली ========== + +/** + * एक बुनियादी कण प्रणाली वर्ग + * @param num कणों की संख्या + * @param v कण प्रणाली की उत्पत्ति + * @param img_ सिस्टम में प्रत्येक कण के लिए एक बनावट + * @constructor + */ +let ParticleSystem = function(num, v, img_) { + + this.particles = []; + this.origin = v.copy(); // यदि हम गलती से मूल को गलती से बदल देते हैं, तो हम वेक्टर मान की प्रतिलिपि बनाना सुनिश्चित करते हैं + this.img = img_ + for(let i = 0; i < num; ++i){ + this.particles.push(new Particle(this.origin, this.img)); + } +}; + +/** + * यह फ़ंक्शन पूरे कण प्रणाली को चलाता है। + */ +ParticleSystem.prototype.run = function() { + + // उस सरणी की कैश लंबाई जिसे हम एक चर में लूप करने जा रहे हैं + // आप समय-समय पर लूप के लिए .length देख सकते हैं लेकिन + // हम इसे यहां कैश करते हैं क्योंकि अन्यथा लूप के प्रत्येक पुनरावृत्ति के लिए लंबाई की फिर से गणना की जाती है + let len = this.particles.length; + + // लूप के माध्यम से और कणों को चलाएं + for (let i = len - 1; i >= 0; i--) { + let particle = this.particles[i]; + particle.run(); + + // यदि कण मर चुका है, तो हम इसे हटा देते हैं। + // जावास्क्रिप्ट सरणियों में "निकालें" फ़ंक्शन नहीं है, लेकिन "स्प्लिस" भी काम करता है। + // हम इसे शुरू करने के लिए एक सूचकांक खिलाते हैं, फिर उस बिंदु से कितनी संख्या को निकालना है। + if (particle.isDead()) { + this.particles.splice(i, 1); + } + } +} + +/** + * सिस्टम में वर्तमान में मौजूद सभी कणों में एक बल वेक्टर जोड़ने की विधि + * @param dir a p5.बल की दिशा का वर्णन करने वाला सदिश। + */ +ParticleSystem.prototype.applyForce = function(dir) { + let len = this.particles.length; + for(let i = 0; i < len; ++i){ + this.particles[i].applyForce(dir); + } +} + +/** + * सिस्टम के मूल में और साथ में सिस्टम में एक नया कण जोड़ता है + * मूल रूप से सेट बनावट। + */ +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin, this.img)); +} + +//========= कण ========== +/** + * एक साधारण कण वर्ग, कण को एक छवि के रूप में प्रस्तुत करता है + */ +let Particle = function (pos, img_) { + this.loc = pos.copy(); + + let vx = randomGaussian() * 0.3; + let vy = randomGaussian() * 0.3 - 1.0; + + this.vel = createVector(vx, vy); + this.acc = createVector(); + this.lifespan = 100.0; + this.texture = img_; +} + +// साथ ही एक कण को अपडेट और प्रदर्शित करें। +Particle.prototype.run = function() { + this.update(); + this.render(); +} + +/** + * एक कण प्रदर्शित करने के लिए एक समारोह + */ +Particle.prototype.render = function() { + imageMode(CENTER); + tint(255, this.lifespan); + image(this.texture, this.loc.x, this.loc.y); +} + +/** + * किसी कण पर बल सदिश लगाने की एक विधि। + */ +Particle.prototype.applyForce = function(f) { + this.acc.add(f); +} + +/** + * यह विधि यह देखने के लिए जाँच करती है कि क्या कण अपने जीवन काल के अंत तक पहुँच गया है, + * यदि यह है, तो सत्य लौटाएँ, अन्यथा असत्य लौटाएँ। + */ +Particle.prototype.isDead = function () { + if (this.lifespan <= 0.0) { + return true; + } else { + return false; + } +} + +/** + * यह विधि कण की स्थिति को अद्यतन करती है। + */ +Particle.prototype.update = function() { + this.vel.add(this.acc); + this.loc.add(this.vel); + this.lifespan -= 2.5; + this.acc.mult(0); +} diff --git a/dist/assets/examples/hi/09_Simulate/12_BrownianMotion.js b/dist/assets/examples/hi/09_Simulate/12_BrownianMotion.js new file mode 100644 index 0000000000..307b816bf5 --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/12_BrownianMotion.js @@ -0,0 +1,45 @@ +/* + * @name ब्राउनियन मोशन + * @description एक सतत लाइन के रूप में यादृच्छिक गति को रिकॉर्ड करना। + * प्रसंस्करण उदाहरण पृष्ठ से मूल उदाहरण का पोर्ट। + */ +let num = 2000; +let range = 6; + +let ax = []; +let ay = []; + + +function setup() { + createCanvas(710, 400); + for ( let i = 0; i < num; i++ ) { + ax[i] = width / 2; + ay[i] = height / 2; + } + frameRate(30); +} + +function draw() { + background(51); + + // सभी तत्वों को 1 स्थान पर बाईं ओर शिफ्ट करें + for ( let i = 1; i < num; i++ ) { + ax[i - 1] = ax[i]; + ay[i - 1] = ay[i]; + } + + // सरणी के अंत में एक नया मान डालें + ax[num - 1] += random(-range, range); + ay[num - 1] += random(-range, range); + + // स्क्रीन पर सभी बिंदुओं को रोकें + ax[num - 1] = constrain(ax[num - 1], 0, width); + ay[num - 1] = constrain(ay[num - 1], 0, height); + + // बिंदुओं को जोड़ने वाली एक रेखा खींचें + for ( let j = 1; j < num; j++ ) { + let val = j / num * 204.0 + 51; + stroke(val); + line(ax[j - 1], ay[j - 1], ax[j], ay[j]); + } +} \ No newline at end of file diff --git a/dist/assets/examples/hi/09_Simulate/13_Chain.js b/dist/assets/examples/hi/09_Simulate/13_Chain.js new file mode 100644 index 0000000000..63cfc80984 --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/13_Chain.js @@ -0,0 +1,55 @@ +/* + * @name चैन + * @description एक द्रव्यमान माउस की स्थिति से जुड़ा होता है और दूसरा दूसरे द्रव्यमान की स्थिति से जुड़ा होता है। वातावरण में गुरुत्वाकर्षण दोनों को नीचे खींचता है। + * प्रसंस्करण उदाहरण पृष्ठ से पोर्ट किया गया। + */ +let s1, s2; +let gravity = 9.0; +let mass = 2.0; + +function setup() { + createCanvas(720, 400); + fill(255, 126); + // इनपुट: x, y, द्रव्यमान, गुरुत्वाकर्षण + s1 = new Spring2D(0.0, width / 2, mass, gravity); + s2 = new Spring2D(0.0, width / 2, mass, gravity); +} + +function draw() { + background(0); + s1.update(mouseX, mouseY); + s1.display(mouseX, mouseY); + s2.update(s1.x, s1.y); + s2.display(s1.x, s1.y); +} + +function Spring2D(xpos, ypos, m, g) { + this.x = xpos; // x- और y-निर्देशांक + this.y = ypos; + this.vx = 0; // x- और y-अक्ष वेग + this.vy = 0; + this.mass = m; + this.gravity = g; + this.radius = 30; + this.stiffness = 0.2; + this.damping = 0.7; + + this.update = function(targetX, targetY) { + let forceX = (targetX - this.x) * this.stiffness; + let ax = forceX / this.mass; + this.vx = this.damping * (this.vx + ax); + this.x += this.vx; + let forceY = (targetY - this.y) * this.stiffness; + forceY += this.gravity; + let ay = forceY / this.mass; + this.vy = this.damping * (this.vy + ay); + this.y += this.vy; + } + + this.display = function(nx, ny) { + noStroke(); + ellipse(this.x, this.y, this.radius * 2, this.radius * 2); + stroke(255); + line(this.x, this.y, nx, ny); + } +} \ No newline at end of file diff --git a/dist/assets/examples/hi/09_Simulate/14_SnowflakeParticleSystem.js b/dist/assets/examples/hi/09_Simulate/14_SnowflakeParticleSystem.js new file mode 100644 index 0000000000..192a7b72b0 --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/14_SnowflakeParticleSystem.js @@ -0,0 +1,63 @@ +/* + * @name स्नोफ्लेक्स + * @description पार्टिकल सिस्टम बर्फ के टुकड़े गिरने की गति का अनुकरण करता है। + * स्नोफ्लेक कणों को धारण करने के लिए वस्तुओं की एक सरणी का उपयोग करता है। + * आतिश भाटिया द्वारा योगदान दिया गया। + */ + +let snowflakes = []; // स्नोफ्लेक वस्तुओं को रखने के लिए सरणी + +function setup() { + createCanvas(400, 600); + fill(240); + noStroke(); +} + +function draw() { + background('brown'); + let t = frameCount / 60; // समय सुधारें + + // प्रत्येक फ्रेम में यादृच्छिक संख्या में स्नोफ्लेक्स बनाएं + for (let i = 0; i < random(5); i++) { + snowflakes.push(new snowflake()); // स्नोफ्लेक ऑब्जेक्ट संलग्न करें + } + + // लूप के लिए स्नोफ्लेक्स के माध्यम से लूप के लिए लूप + for (let flake of snowflakes) { + flake.update(t); // स्नोफ्लेक स्थिति अपडेट करें + flake.display(); // स्नोफ्लेक ड्रा करें + } +} + +// स्नोफ्लेक क्लास +function snowflake() { + // निर्देशांक आरंभ करें + this.posX = 0; + this.posY = random(-50, 0); + this.initialangle = random(0, 2 * PI); + this.size = random(2, 5); + + // स्नोफ्लेक सर्पिल की त्रिज्या + // चुना गया ताकि बर्फ के टुकड़े समान रूप से क्षेत्र में फैले हों + this.radius = sqrt(random(pow(width / 2, 2))); + + this.update = function(time) { + // x स्थिति एक सर्कल का अनुसरण करती है + let w = 0.6; // कोणीय गति + let angle = w * time + this.initialangle; + this.posX = width / 2 + this.radius * sin(angle); + + // अलग-अलग आकार के बर्फ के टुकड़े थोड़े अलग y गति से गिरते हैं + this.posY += pow(this.size, 0.5); + + // स्क्रीन के पिछले छोर पर बर्फ के टुकड़े को हटा दें + if (this.posY > height) { + let index = snowflakes.indexOf(this); + snowflakes.splice(index, 1); + } + }; + + this.display = function() { + ellipse(this.posX, this.posY, this.size); + }; +} diff --git a/dist/assets/examples/hi/09_Simulate/15_penrose_tiles.js b/dist/assets/examples/hi/09_Simulate/15_penrose_tiles.js new file mode 100644 index 0000000000..b911fea01a --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/15_penrose_tiles.js @@ -0,0 +1,125 @@ +/* + * @name पेनरोज़ टाइलें + * @frame 710,400 + * @description यह प्रोसेसिंग.org/examples से "पेनरोज़ टाइल" उदाहरण के डेविड ब्लिट्ज का एक पोर्ट है + */ + +let ds; + +function setup() { + createCanvas(710, 400); + ds = new PenroseLSystem(); + // कृपया, निम्न पंक्ति के साथ खेलें + ds.simulate(5); +} + +function draw() { + background(0); + ds.render(); +} + +function PenroseLSystem() { + this.steps = 0; + + // ये पेनरोज़ रोम्बस एल-सिस्टम के लिए स्वयंसिद्ध और नियम हैं + // एक संदर्भ अच्छा होगा, लेकिन मुझे एक अच्छा नहीं मिला + this.axiom = "[X]++[X]++[X]++[X]++[X]"; + this.ruleW = "YF++ZF----XF[-YF----WF]++"; + this.ruleX = "+YF--ZF[---WF--XF]+"; + this.ruleY = "-WF++XF[+++YF++ZF]-"; + this.ruleZ = "--YF++++WF[+ZF++++XF]--XF"; + + // कृपया निम्नलिखित दो पंक्तियों के साथ खेलें + this.startLength = 460.0; + this.theta = TWO_PI / 10.0; // 36 डिग्री, TWO_PI / 6.0 आज़माएं, ... + this.reset(); +} + +PenroseLSystem.prototype.simulate = function (gen) { + while (this.getAge() < gen) { + this.iterate(this.production); + } +} + +PenroseLSystem.prototype.reset = function () { + this.production = this.axiom; + this.drawLength = this.startLength; + this.generations = 0; + } + +PenroseLSystem.prototype.getAge = function () { + return this.generations; + } + +// उत्पादन स्ट्रिंग का नया पुनरावृत्ति बनाने के लिए प्रतिस्थापन नियम लागू करें +PenroseLSystem.prototype.iterate = function() { + let newProduction = ""; + + for(let i=0; i < this.production.length; ++i) { + let step = this.production.charAt(i); + // यदि वर्तमान वर्ण 'W' है, तो वर्तमान वर्ण को बदलें + // संबंधित नियम के अनुसार + if (step == 'W') { + newProduction = newProduction + this.ruleW; + } + else if (step == 'X') { + newProduction = newProduction + this.ruleX; + } + else if (step == 'Y') { + newProduction = newProduction + this.ruleY; + } + else if (step == 'Z') { + newProduction = newProduction + this.ruleZ; + } + else { + // सभी 'एफ' वर्णों को छोड़ दें, अन्य को स्पर्श न करें + // वर्ण (यानी '+', '-', '[', ']' + if (step != 'F') { + newProduction = newProduction + step; + } + } + } + + this.drawLength = this.drawLength * 0.5; + this.generations++; + this.production = newProduction; +} + +// प्रोडक्शन स्ट्रिंग को टर्टल ग्राफिक में बदलें +PenroseLSystem.prototype.render = function () { + translate(width / 2, height / 2); + + this.steps += 20; + if(this.steps > this.production.length) { + this.steps = this.production.length; + } + + for(let i=0; iरिकर्सिव ट्री उदाहरण पर आधारित। + */ +let theta; + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(0); + frameRate(30); + stroke(255); + // आइए माउस की स्थिति के आधार पर 0 से 90 डिग्री का कोण चुनें + let a = (mouseX / width) * 90; + // इसे रेडियन में बदलें + theta = radians(a); + // स्क्रीन के नीचे से पेड़ शुरू करें + translate(width/2,height); + // 120 पिक्सल की एक लाइन बनाएं + line(0,0,0,-120); + // उस लाइन के अंत में जाएँ + translate(0,-120); + // रिकर्सिव ब्रांचिंग शुरू करें! + branch(120); + +} + +function branch(h) { + // प्रत्येक शाखा पिछले एक के आकार का 2/3 होगा + h *= 0.66; + + // सभी पुनरावर्ती कार्यों में बाहर निकलने की स्थिति होनी चाहिए !!!! + // यहाँ, हमारा है जब शाखा की लंबाई 2 पिक्सेल या उससे कम है + if (h > 2) { + push(); // परिवर्तन की वर्तमान स्थिति को बचाएं (अर्थात अब हम कहां हैं) + rotate(theta); // थीटा द्वारा घुमाएं + line(0, 0, 0, -h); // शाखा ड्रा करें + translate(0, -h); // शाखा के अंत में ले जाएँ + branch(h); // ठीक है, अब दो नई शाखाएँ बनाने के लिए खुद को बुलाएँ !! + pop(); // जब भी हम यहां वापस आते हैं, तो हम पिछली मैट्रिक्स स्थिति को पुनर्स्थापित करने के लिए "पॉप" करते हैं + + // एक ही बात दोहराएं, इस बार केवल "बाईं ओर" शाखा बंद करें! + push(); + rotate(-theta); + line(0, 0, 0, -h); + translate(0, -h); + branch(h); + pop(); + } +} diff --git a/dist/assets/examples/hi/09_Simulate/17_Mandelbrot.js b/dist/assets/examples/hi/09_Simulate/17_Mandelbrot.js new file mode 100644 index 0000000000..b775652b5e --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/17_Mandelbrot.js @@ -0,0 +1,86 @@ +/* + * @name मंडेलब्रॉट सेत + * @description मैंडलब्रॉट सेट का सरल प्रतिपादन। + * प्रोसेसिंग के लिए डेनियल शिफमैन के Mandelbrot उदाहरण पर आधारित। + */ + +function setup() { + createCanvas(710, 400); + pixelDensity(1); + noLoop(); +} + +function draw() { + background(0); + + // जटिल तल पर मूल्यों की एक श्रृंखला स्थापित करें + // एक अलग रेंज हमें फ्रैक्टल पर "ज़ूम" करने की अनुमति देगा + + // यह सब चौड़ाई से शुरू होता है, उच्च या निम्न मानों का प्रयास करें + const w = 4; + const h = (w * height) / width; + + // चौड़ाई और ऊंचाई के नकारात्मक आधे से शुरू करें + const xmin = -w/2; + const ymin = -h/2; + + // सुनिश्चित करें कि हम पिक्सल [] सरणी में लिख सकते हैं। + // केवल एक बार ऐसा करने की आवश्यकता है क्योंकि हम कोई अन्य ड्राइंग नहीं करते हैं। + loadPixels(); + + // जटिल विमान पर प्रत्येक बिंदु के लिए पुनरावृत्तियों की अधिकतम संख्या + const maxiterations = 100; + + // x xmin से xmax तक जाता है + const xmax = xmin + w; + // y ymin से ymax . तक जाता है + const ymax = ymin + h; + + // गणना करें कि हम प्रत्येक पिक्सेल के लिए x, y में वृद्धि करते हैं + const dx = (xmax - xmin) / (width); + const dy = (ymax - ymin) / (height); + + // प्रारंभ करें + let y = ymin; + for (let j = 0; j < height; j++) { + // एक्स शुरू करें + let x = xmin; + for (let i = 0; i < width; i++) { + + // अब हम परीक्षण करते हैं, जैसा कि हम z = z^2 + cm को पुनरावृत्त करते हैं, क्या z अनंत की ओर जाता है? + let a = x; + let b = y; + let n = 0; + while (n < maxiterations) { + const aa = a * a; + const bb = b * b; + const twoab = 2.0 * a * b; + a = aa - bb + x; + b = twoab + y; + // हमारी सीमित दुनिया में अनंत सरल है, आइए इसे 16 . पर विचार करें + if (dist(aa, bb, 0, 0) > 16) { + break; // टूटना + } + n++; + } + + // हम प्रत्येक पिक्सेल को इस आधार पर रंगते हैं कि अनंत तक पहुंचने में कितना समय लगता है + // अगर हम वहां कभी नहीं पहुंचे, तो आइए काले रंग को चुनें + const pix = (i+j*width)*4; + const norm = map(n, 0, maxiterations, 0, 1); + let bright = map(sqrt(norm), 0, 1, 0, 255); + if (n == maxiterations) { + bright = 0; + } else { + // भगवान, अगर हम चाहते तो हम यहाँ फैंसी रंग बना सकते थे + pixels[pix + 0] = bright; + pixels[pix + 1] = bright; + pixels[pix + 2] = bright; + pixels[pix + 3] = 255; + } + x += dx; + } + y += dy; + } + updatePixels(); +} diff --git a/dist/assets/examples/hi/09_Simulate/18_Koch.js b/dist/assets/examples/hi/09_Simulate/18_Koch.js new file mode 100644 index 0000000000..a6dd65a99a --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/18_Koch.js @@ -0,0 +1,140 @@ +/* + * @name कोच कर्व + * @description एक साधारण फ्रैक्टल, कोच स्नोफ्लेक प्रस्तुत करता है। प्रत्येक पुनरावर्ती स्तर क्रम में तैयार किया गया है। + * डैनियल शिफमैन द्वारा + */ +let k; + +function setup() { + createCanvas(710, 400); + frameRate(1); // धीरे-धीरे चेतन करें + k = new KochFractal(); +} + +function draw() { + background(0); + // बर्फ के टुकड़े खींचता है! + k.render(); + // पुनरावृति + k.nextLevel(); + // आइए इसे 5 बार से अधिक न करें। . . + if (k.getCount() > 5) { + k.restart(); + } +} + +// भग्न में एक रेखा खंड का वर्णन करने के लिए एक वर्ग +// कोच एल्गोरिथ्म के अनुसार लाइन के साथ midp5.Vectors की गणना करने के तरीके शामिल हैं + +class KochLine { + constructor(a,b) { + // दो p5.Vectors, + // प्रारंभ "बाएं" p5 है। वेक्टर और + // अंत "सही p5.Vector" है + this.start = a.copy(); + this.end = b.copy(); + } + + display() { + stroke(255); + line(this.start.x, this.start.y, this.end.x, this.end.y); + } + + kochA() { + return this.start.copy(); + } + + // यह आसान है, रास्ते का सिर्फ 1/3 + kochB() { + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + v.add(this.start); + return v; + } + + // अधिक जटिल, यह पता लगाने के लिए थोड़ा ट्रिगर का उपयोग करना होगा कि यह p5.Vector कहाँ है! + kochC() { + let a = this.start.copy(); // शुरुआत में शुरू करें + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + a.add(v); // बिंदु बी पर ले जाएँ + v.rotate(-PI/3); // 60 डिग्री घुमाएँate + a.add(v); // बिंदु C . पर जाएँ + return a; + } + + // आसान, रास्ते का सिर्फ 2/3 + kochD() { + let v = p5.Vector.sub(this.end, this.start); + v.mult(2/3.0); + v.add(this.start); + return v; + } + + kochE() { + return this.end.copy(); + } +} + +// स्नोफ्लेक पैटर्न में लाइन सेगमेंट की सूची को प्रबंधित करने के लिए एक वर्ग + +class KochFractal { + constructor() { + this.start = createVector(0,height-20); // एक p5. शुरुआत के लिए वेक्टर + this.end = createVector(width,height-20); // एक p5। अंत के लिए वेक्टर + this.lines = []; // सभी लाइनों का ट्रैक रखने के लिए एक सरणी + this.count = 0; + this.restart(); + } + + nextLevel() { + // प्रत्येक पंक्ति के लिए जो सरणी सूची में है + // एक नई सरणी सूची में 4 और लाइनें बनाएं + this.lines = this.iterate(this.lines); + this.count++; + } + + restart() { + this.count = 0; // रीसेट गिनती + this.lines = []; // सरणी सूची खाली करें + this.lines.push(new KochLine(this.start,this.end)); // प्रारंभिक पंक्ति जोड़ें (एक छोर p5.Vector से दूसरे तक) + } + + getCount() { + return this.count; + } + + // यह आसान है, बस सभी रेखाएँ खींचें + render() { + for(let i = 0; i < this.lines.length; i++) { + this.lines[i].display(); + } + } + + // यहां जादू पैदा होता है + // चरण 1: एक खाली सरणी सूची बनाएं + // चरण 2: वर्तमान में सरणी सूची में प्रत्येक पंक्ति के लिए + // - कोच एल्गोरिथम के आधार पर 4 लाइन सेगमेंट की गणना करें + // - सभी 4 लाइन सेगमेंट को नई सरणी सूची में जोड़ें + // चरण 3: नई सरणी सूची लौटाएं और यह संरचना के लिए रेखा खंडों की सूची बन जाती है + + // जैसा कि हम इसे बार-बार करते हैं, प्रत्येक पंक्ति 4 पंक्तियों में टूट जाती है, जो 4 पंक्तियों में टूट जाती है, और इसी तरह। . . + iterate(before) { + let now = []; // खाली सूची बनाएं + for(let i = 0; i < this.lines.length; i++) { + let l = this.lines[i]; + // 5 koch p5.Vectors की गणना करें (लाइन ऑब्जेक्ट द्वारा हमारे लिए किया गया) + let a = l.kochA(); + let b = l.kochB(); + let c = l.kochC(); + let d = l.kochD(); + let e = l.kochE(); + // सभी p5.Vectors के बीच लाइन सेगमेंट बनाएं और उन्हें जोड़ें + now.push(new KochLine(a,b)); + now.push(new KochLine(b,c)); + now.push(new KochLine(c,d)); + now.push(new KochLine(d,e)); + } + return now; + } +} diff --git a/dist/assets/examples/hi/09_Simulate/19_Bubblesort.js b/dist/assets/examples/hi/09_Simulate/19_Bubblesort.js new file mode 100644 index 0000000000..a3ce18d07a --- /dev/null +++ b/dist/assets/examples/hi/09_Simulate/19_Bubblesort.js @@ -0,0 +1,67 @@ +/* + * @name बबल सॉर्ट + * @description बेतरतीब ढंग से वितरित बार को क्रमबद्ध करता है + *ऊंचाई के अनुसार आरोही क्रम में + * पूरी छँटाई प्रक्रिया का अनुकरण करते हुए। + * द कोडिंग ट्रेन द्वारा कोडिंग चैलेंज से संदर्भ लिया। + */ + +let values = []; +let i = 0; +let j = 0; + +// सेटअप () फ़ंक्शन में बयान +// प्रोग्राम शुरू होने पर एक बार निष्पादित करें +// सरणी सेटअप () फ़ंक्शन में यादृच्छिक मानों से भरी हुई है। +function setup() { + createCanvas(720, 400); + for(let i = 0;i values[j+1]){ + values[j] = values[j+1]; + values[j+1] = temp; + } + j++; + + if(j>=values.length-i-1){ + j = 0; + i++; + } + } + else{ + noLoop(); + } + } +} + +// सिम्युलेटसॉर्टिंग () फ़ंक्शन एनिमेट करने में मदद करता है +// पूरे बबल सॉर्ट एल्गोरिथ्म +// मानों का उपयोग करके आयतों को खींचकर +// सरणी में आयत की लंबाई के रूप में। +function simulateSorting(){ + for(let i = 0;i= width || this.xPos <= 0){ + this.xSpeed*=-1; + } + } +} + +function setup() { + createCanvas(720, 400); + createP("Keep the mouse clicked").style('color','#ffffff'); + createP("to check whether the bricks").style('color','#ffffff'); + createP("are moving at same speed or not").style('color','#ffffff'); +} + +// की दो ईंटें बनाना +// रंग सफेद और काला +let brick1 = new Brick("white",100); +let brick2 = new Brick("black",250); + +// +brick1.setSpeed(); +brick2.setSpeed(); + +function draw () { + background(0); + if(mouseIsPressed){ + background(50); + } + brick1.createBrick(); + brick1.moveBrick(); + if(!mouseIsPressed){ + createBars(); + } + brick2.createBrick(); + brick2.moveBrick(); +} + +// यह फ़ंक्शन काला बनाता है और +// स्क्रीन पर सफेद पट्टियां +function createBars() { + let len = 12; + for(let i = 0;i width) + this.xSpeed*=-1; + if(this.y < 0 || this.y > height) + this.ySpeed*=-1; + this.x+=this.xSpeed; + this.y+=this.ySpeed; + } + +// यह फ़ंक्शन कनेक्शन बनाता है (लाइनें) +// कणों के बीच जो एक निश्चित दूरी से कम दूरी पर हैं + joinParticles(paraticles) { + particles.forEach(element =>{ + let dis = dist(this.x,this.y,element.x,element.y); + if(dis<85) { + stroke('rgba(255,255,255,0.04)'); + line(this.x,this.y,element.x,element.y); + } + }); + } +} + +// कई कणों को जोड़ने के लिए एक सरणी +let particles = []; + +function setup() { + createCanvas(720, 400); + for(let i = 0;i= bounds.x && + mouseX <= bounds.x + bounds.w && + mouseY >= bounds.y && + mouseY <= bounds.y + bounds.h + ) { + x += random(-5, 5); + y += random(-5, 5); + } +} diff --git a/dist/assets/examples/hi/10_Interaction/20_Follow1.js b/dist/assets/examples/hi/10_Interaction/20_Follow1.js new file mode 100644 index 0000000000..3cead9f911 --- /dev/null +++ b/dist/assets/examples/hi/10_Interaction/20_Follow1.js @@ -0,0 +1,37 @@ +/* + * @name फॉलो 1 + * @frame 710,400 + * @description एक रेखा खंड को कर्सर द्वारा धकेला और खींचा जाता है। + * कीथ पीटर्स के कोड के आधार पर। + */ +let x = 100, + y = 100, + angle1 = 0.0, + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + x = mouseX - cos(angle1) * segLength; + y = mouseY - sin(angle1) * segLength; + + segment(x, y, angle1); + ellipse(x, y, 20, 20); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/hi/10_Interaction/21_Follow2.js b/dist/assets/examples/hi/10_Interaction/21_Follow2.js new file mode 100644 index 0000000000..8d14e12aeb --- /dev/null +++ b/dist/assets/examples/hi/10_Interaction/21_Follow2.js @@ -0,0 +1,39 @@ +/* + * @name फॉलो 2 + * @frame 710,400 + * @description दो खंडों वाली भुजा कर्सर की स्थिति का अनुसरण करती है। संबंधी + * खंडों के बीच के कोण की गणना atan2 () और स्थिति के साथ की जाती है + * sin() और cos() के साथ गणना की गई। कीथ पीटर्स के कोड के आधार पर। + */ +let x = [0, 0], + y = [0, 0], + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + dragSegment(1, x[0], y[0]); +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/hi/10_Interaction/22_Follow3.js b/dist/assets/examples/hi/10_Interaction/22_Follow3.js new file mode 100644 index 0000000000..f8f91dc665 --- /dev/null +++ b/dist/assets/examples/hi/10_Interaction/22_Follow3.js @@ -0,0 +1,47 @@ +/* + * @name फॉलो 3 + * @frame 710,400 + * @description एक खंडित रेखा माउस का अनुसरण करती है। से आपेक्षिक कोण + * अगले से प्रत्येक खंड की गणना atan2 () और की स्थिति के साथ की जाती है + * अगले की गणना sin() और cos() के साथ की जाती है। कीथ पीटर्स के कोड के आधार पर। + */ +let x = [], + y = [], + segNum = 20, + segLength = 18; + +for (let i = 0; i < segNum; i++) { + x[i] = 0; + y[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(9); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/hi/10_Interaction/23_snake.js b/dist/assets/examples/hi/10_Interaction/23_snake.js new file mode 100644 index 0000000000..ddaa719564 --- /dev/null +++ b/dist/assets/examples/hi/10_Interaction/23_snake.js @@ -0,0 +1,172 @@ +/* + * @name सांप का खेल + * @description प्रसिद्ध सांप का खेल! रन पर क्लिक करने के बाद, कहीं भी क्लिक करें + * काले क्षेत्र के अंदर, और i j k और l का उपयोग करके सांप को नियंत्रित करें। मत जाने दो + *सांप खुद को या दीवार से टकराया!
+ * उदाहरण प्रशांत गुप्ता द्वारा बनाया गया + */ + +// सांप को छोटे-छोटे खंडों में विभाजित किया जाता है, जिन्हें प्रत्येक 'ड्रा' कॉल पर खींचा और संपादित किया जाता है +let numSegments = 10; +let direction = 'right'; + +const xStart = 0; // सांप के लिए x निर्देशांक शुरू करना +const yStart = 250; // सांप के लिए y समन्वय शुरू करना +const diff = 10; + +let xCor = []; +let yCor = []; + +let xFruit = 0; +let yFruit = 0; +let scoreElem; + +function setup() { + scoreElem = createDiv('Score = 0'); + scoreElem.position(20, 20); + scoreElem.id = 'score'; + scoreElem.style('color', 'white'); + + createCanvas(500, 500); + frameRate(15); + stroke(255); + strokeWeight(10); + updateFruitCoordinates(); + + for (let i = 0; i < numSegments; i++) { + xCor.push(xStart + i * diff); + yCor.push(yStart); + } +} + +function draw() { + background(0); + for (let i = 0; i < numSegments - 1; i++) { + line(xCor[i], yCor[i], xCor[i + 1], yCor[i + 1]); + } + updateSnakeCoordinates(); + checkGameStatus(); + checkForFruit(); +} + +/* + साँप की दिशा के आधार पर खंडों को अद्यतन किया जाता है। + 0 से n-1 तक के सभी खंडों को 1 से n तक कॉपी किया जाता है, अर्थात खंड 0 + खंड 1 का मान प्राप्त करता है, खंड 1 को खंड 2 का मान मिलता है, और इसी तरह, + और इसके परिणामस्वरूप सांप की गति होती है। + + सांप जिस दिशा में जा रहा है, उसके आधार पर अंतिम खंड जोड़ा जाता है, + यदि यह बाएँ या दाएँ जा रहा है, तो अंतिम खंड का x निर्देशांक a . से बढ़ जाता है + इसके दूसरे से अंतिम खंड की तुलना में पूर्वनिर्धारित मान 'diff'। और अगर यह ऊपर जा रहा है + या नीचे, खंड का y निर्देशांक प्रभावित होता है। +*/ +function updateSnakeCoordinates() { + for (let i = 0; i < numSegments - 1; i++) { + xCor[i] = xCor[i + 1]; + yCor[i] = yCor[i + 1]; + } + switch (direction) { + case 'right': + xCor[numSegments - 1] = xCor[numSegments - 2] + diff; + yCor[numSegments - 1] = yCor[numSegments - 2]; + break; + case 'up': + xCor[numSegments - 1] = xCor[numSegments - 2]; + yCor[numSegments - 1] = yCor[numSegments - 2] - diff; + break; + case 'left': + xCor[numSegments - 1] = xCor[numSegments - 2] - diff; + yCor[numSegments - 1] = yCor[numSegments - 2]; + break; + case 'down': + xCor[numSegments - 1] = xCor[numSegments - 2]; + yCor[numSegments - 1] = yCor[numSegments - 2] + diff; + break; + } +} + +/* + मैं हमेशा सांप के सिर की स्थिति की जांच करता हूं xCor[xCor.length - 1] और + yCor[yCor.length - 1] यह देखने के लिए कि क्या यह खेल की सीमाओं को छूता है + या अगर सांप खुद को मारता है। +*/ +function checkGameStatus() { + if ( + xCor[xCor.length - 1] > width || + xCor[xCor.length - 1] < 0 || + yCor[yCor.length - 1] > height || + yCor[yCor.length - 1] < 0 || + checkSnakeCollision() + ) { + noLoop(); + const scoreVal = parseInt(scoreElem.html().substring(8)); + scoreElem.html('Game ended! Your score was : ' + scoreVal); + } +} + +/* + यदि सांप खुद को मारता है, तो इसका मतलब है कि सांप का सिर (x,y) समन्वय करता है + अपने स्वयं के खंड (x, y) निर्देशांक में से एक के समान होना चाहिए। +*/ +function checkSnakeCollision() { + const snakeHeadX = xCor[xCor.length - 1]; + const snakeHeadY = yCor[yCor.length - 1]; + for (let i = 0; i < xCor.length - 1; i++) { + if (xCor[i] === snakeHeadX && yCor[i] === snakeHeadY) { + return true; + } + } +} + +/* + जब भी सांप फल खाता है, मैं खंडों की संख्या बढ़ा देता हूं, + और सरणी की शुरुआत में फिर से पूंछ खंड डालें (मूल रूप से + मैं अंतिम खंड को फिर से पूंछ में जोड़ता हूं, जिससे पूंछ का विस्तार होता है) +*/ +function checkForFruit() { + point(xFruit, yFruit); + if (xCor[xCor.length - 1] === xFruit && yCor[yCor.length - 1] === yFruit) { + const prevScore = parseInt(scoreElem.html().substring(8)); + scoreElem.html('Score = ' + (prevScore + 1)); + xCor.unshift(xCor[0]); + yCor.unshift(yCor[0]); + numSegments++; + updateFruitCoordinates(); + } +} + +function updateFruitCoordinates() { + /* + जटिल गणित तर्क इसलिए है क्योंकि मैं चाहता था कि बिंदु झूठ बोलें + १०० और चौड़ाई १०० के बीच में, और निकटतम तक पूर्णांकित किया जाए + संख्या १० से विभाज्य है, क्योंकि मैं साँप को १० के गुणकों में घुमाता हूँ। + */ + + xFruit = floor(random(10, (width - 100) / 10)) * 10; + yFruit = floor(random(10, (height - 100) / 10)) * 10; +} + +function keyPressed() { + switch (keyCode) { + case 74: + if (direction !== 'right') { + direction = 'left'; + } + break; + case 76: + if (direction !== 'left') { + direction = 'right'; + } + break; + case 73: + if (direction !== 'down') { + direction = 'up'; + } + break; + case 75: + if (direction !== 'up') { + direction = 'down'; + } + break; + } +} diff --git a/dist/assets/examples/hi/10_Interaction/24_Wavemaker.js b/dist/assets/examples/hi/10_Interaction/24_Wavemaker.js new file mode 100644 index 0000000000..2e1c847268 --- /dev/null +++ b/dist/assets/examples/hi/10_Interaction/24_Wavemaker.js @@ -0,0 +1,37 @@ +/* + * @name वेवमेकर + * @description यह दर्शाता है कि कैसे लहरें (जैसे पानी की लहरें) उभरती हैं + * जगह-जगह दोलन करने वाले कणों से। तरंग को निर्देशित करने के लिए अपने माउस को ले जाएं। + * डेव व्हाईट के Orbiters से प्रेरित आतिश भाटिया द्वारा योगदान दिया गया। + */ + +let t = 0; // समय चर + +function setup() { + createCanvas(600, 600); + noStroke(); + fill(40, 200, 40); +} + +function draw() { + background(10, 10); // पारभासी पृष्ठभूमि (ट्रेल्स बनाता है) + + // दीर्घवृत्त का x और y ग्रिड बनाएं + for (let x = 0; x <= width; x = x + 30) { + for (let y = 0; y <= height; y = y + 30) { + // प्रत्येक सर्कल का प्रारंभिक बिंदु माउस की स्थिति पर निर्भर करता है + const xAngle = map(mouseX, 0, width, -4 * PI, 4 * PI, true); + const yAngle = map(mouseY, 0, height, -4 * PI, 4 * PI, true); + // और कण के स्थान के आधार पर भी बदलता रहता है + const angle = xAngle * (x / width) + yAngle * (y / height); + + // प्रत्येक कण एक वृत्त में चलता है + const myX = x + 20 * cos(2 * PI * t + angle); + const myY = y + 20 * sin(2 * PI * t + angle); + + ellipse(myX, myY, 10); // कण खींचे + } + } + + t = t + 0.01; // समय सुधारें +} diff --git a/dist/assets/examples/hi/10_Interaction/25_reach1.js b/dist/assets/examples/hi/10_Interaction/25_reach1.js new file mode 100644 index 0000000000..6aac76c662 --- /dev/null +++ b/dist/assets/examples/hi/10_Interaction/25_reach1.js @@ -0,0 +1,57 @@ +/* + * @name रीच 1 + * @frame 710,400 + * @description हाथ की गणना करके माउस की स्थिति का अनुसरण करता है + * atan2 () के साथ कोण। कीथ पीटर्स के कोड के आधार पर। + */ +let segLength = 80, + x, + y, + x2, + y2; + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x = width / 2; + y = height / 2; + x2 = x; + y2 = y; +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + + tx = mouseX - cos(angle1) * segLength; + ty = mouseY - sin(angle1) * segLength; + dx = tx - x2; + dy = ty - y2; + angle2 = atan2(dy, dx); + x = x2 + cos(angle2) * segLength; + y = y2 + sin(angle2) * segLength; + + segment(x, y, angle1); + segment(x2, y2, angle2); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/hi/10_Interaction/26_reach2.js b/dist/assets/examples/hi/10_Interaction/26_reach2.js new file mode 100644 index 0000000000..b821b66c42 --- /dev/null +++ b/dist/assets/examples/hi/10_Interaction/26_reach2.js @@ -0,0 +1,65 @@ +/* + * @name रीच 2 + * @frame 710,400 + * @description हाथ की गणना करके माउस की स्थिति का अनुसरण करता है + * atan2 () के साथ कोण। कीथ पीटर्स के कोड के आधार पर। + */ +let numSegments = 10, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x[x.length - 1] = width / 2; // बेस एक्स-कोऑर्डिनेट सेट करें + y[x.length - 1] = height; // आधार y- निर्देशांक सेट करें +} + +function draw() { + background(0); + + reachSegment(0, mouseX, mouseY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/hi/10_Interaction/27_reach3.js b/dist/assets/examples/hi/10_Interaction/27_reach3.js new file mode 100644 index 0000000000..d5b58c9b3c --- /dev/null +++ b/dist/assets/examples/hi/10_Interaction/27_reach3.js @@ -0,0 +1,81 @@ +/* + * @name पहुंच ३ + * @frame 710,400 + * @description हाथ की गणना करके गेंद की स्थिति का अनुसरण करता है + * atan2 () के साथ कोण। कीथ पीटर्स के कोड के आधार पर। + */ +let numSegments = 8, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY, + ballX = 50, + ballY = 50, + ballXDirection = 1, + ballYDirection = -1; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + noFill(); + + x[x.length - 1] = width / 2; // बेस एक्स-कोऑर्डिनेट सेट करें + y[x.length - 1] = height; // आधार y- निर्देशांक सेट करें +} + +function draw() { + background(0); + + strokeWeight(20); + ballX = ballX + 1.0 * ballXDirection; + ballY = ballY + 0.8 * ballYDirection; + if (ballX > width - 25 || ballX < 25) { + ballXDirection *= -1; + } + if (ballY > height - 25 || ballY < 25) { + ballYDirection *= -1; + } + ellipse(ballX, ballY, 30, 30); + + reachSegment(0, ballX, ballY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/hi/10_Interaction/28_ArduinoSensor.js b/dist/assets/examples/hi/10_Interaction/28_ArduinoSensor.js new file mode 100644 index 0000000000..a9f42313ec --- /dev/null +++ b/dist/assets/examples/hi/10_Interaction/28_ArduinoSensor.js @@ -0,0 +1,37 @@ +/* + * @name Arduino सेंसर डेटा WebJack के माध्यम से + * @description WebJack एक Arduino (और अन्य स्रोतों) से डेटा पढ़ने का एक तरीका है + * ऑडियो का उपयोग करना - यह मूल रूप से आपके Arduino को एक ऑडियो मॉडेम में बदल देता है। + * + * https://github.com/publiclab/webjack + * + * नोट: WebJack और p5-webjack लाइब्रेरी को आपके index.html में निम्नानुसार जोड़ा जाना चाहिए: + *
<script src="https://webjack.io/dist/webjack.js"></script>
+ *
<script src="https://jywarren.github.io/p5-webjack/lib.js"></script>
+  *
+  * कार्य उदाहरण: https://editor.p5js.org/jywarren/sketches/rkztwSt8M
+  *
+  * परीक्षण ऑडियो: https://www.youtube.com/watch?v=GtJW1Dlt3cg
+  * इस स्केच को एक Arduino पर लोड करें:
+  * https://create.arduino.cc/editor/jywarren/023158d8-be51-4c78-99ff-36c63126b554/preview
+  * Arduino पिन 3 + ग्राउंड से ऑडियो आउटपुट करेगा। माइक्रोफ़ोन या ऑडियो केबल का उपयोग करें।
+  */
+
+function setup() { 
+  createCanvas(400, 400);
+  noStroke();
+  fill('#ff00aa22');
+  receiveSensorData(handleData);
+}
+
+function handleData(data, connection) {
+
+  console.log(data); // output the values to log
+  // data[0] is the 1st value, data[1] 2nd, etc.
+
+  // draw stuff! Browse http://p5js.org/reference/
+  background('#ddd');
+  ellipse(100, 200, data[0]+10, data[0]+10);
+
+  // connection.send('send data back to the Arduino if its listening');
+}
diff --git a/dist/assets/examples/hi/10_Interaction/29_kaleidoscope.js b/dist/assets/examples/hi/10_Interaction/29_kaleidoscope.js
new file mode 100644
index 0000000000..700f15c810
--- /dev/null
+++ b/dist/assets/examples/hi/10_Interaction/29_kaleidoscope.js
@@ -0,0 +1,72 @@
+/*
+  * @name बहुरूपदर्शक
+  * @description एक बहुरूपदर्शक एक ऑप्टिकल उपकरण है जिसमें दो या दो से अधिक परावर्तक सतहें एक कोण में एक दूसरे की ओर झुकी होती हैं। यह उदाहरण एक बहुरूपदर्शक के व्यवहार को दोहराने का प्रयास करता है। समरूपता चर पर प्रतिबिंबों की संख्या निर्धारित करें और स्क्रीन पर चित्र बनाना शुरू करें। स्लाइडर की सहायता से ब्रश का आकार समायोजित करें। स्पष्ट स्क्रीन, जैसा कि यह कहती है, स्क्रीन को साफ़ करती है। सेव बटन आपके द्वारा बनाई गई कला की एक .jpg फ़ाइल डाउनलोड करेगा।
+  */
+// प्रतिबिंबों की संख्या के अनुरूप समरूपता। विभिन्न संख्या में परावर्तनों के लिए संख्या बदलें
+let symmetry = 6;   
+
+let angle = 360 / symmetry;
+let saveButton, clearButton, mouseButton, keyboardButton;
+let slider;
+
+function setup() { 
+  createCanvas(710, 710);
+  angleMode(DEGREES);
+  background(127);
+
+  // फाइल के लिए सेव बटन बनाना
+  saveButton = createButton('save');
+  saveButton.mousePressed(saveFile);
+
+  // स्पष्ट स्क्रीन बटन बनाना
+  clearButton = createButton('clear');
+  clearButton.mousePressed(clearScreen);
+
+  // पूर्ण स्क्रीन के लिए बटन बनाना
+  fullscreenButton = createButton('Full Screen');
+  fullscreenButton.mousePressed(screenFull);
+
+  // ब्रश की मोटाई के लिए स्लाइडर सेट करना
+  brushSizeSlider = createButton('Brush Size Slider');
+  sizeSlider = createSlider(1, 32, 4, 0.1);
+}
+
+// फ़ाइल फ़ंक्शन सहेजें
+function saveFile() {
+  save('design.jpg');
+}
+
+// साफ़ स्क्रीन फ़ंक्शन
+function clearScreen() {
+  background(127);
+}
+
+// फुल स्क्रीन फंक्शन
+function screenFull() {
+  let fs = fullscreen();
+  fullscreen(!fs);
+}
+
+function draw() {
+  translate(width / 2, height / 2);
+
+  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
+    let mx = mouseX - width / 2;
+    let my = mouseY - height / 2;
+    let pmx = pmouseX - width / 2;
+    let pmy = pmouseY - height / 2;
+    
+    if (mouseIsPressed) {
+      for (let i = 0; i < symmetry; i++) {
+        rotate(angle);
+        let sw = sizeSlider.value();
+        strokeWeight(sw);
+        line(mx, my, pmx, pmy);
+        push();
+        scale(1, -1);
+        line(mx, my, pmx, pmy);
+        pop();
+      }
+    }
+  }
+}
diff --git a/dist/assets/examples/hi/11_Objects/01_Objects.js b/dist/assets/examples/hi/11_Objects/01_Objects.js
new file mode 100644
index 0000000000..bed1f8973e
--- /dev/null
+++ b/dist/assets/examples/hi/11_Objects/01_Objects.js
@@ -0,0 +1,39 @@
+/*
+  * @name वस्तु
+  * @description एक जिटर क्लास बनाएं, किसी ऑब्जेक्ट को इंस्टेंट करें,
+  * और इसे स्क्रीन के चारों ओर ले जाएँ। के साथ आरंभ करने से अनुकूलित
+  * केसी रियास और बेन फ्राई द्वारा प्रसंस्करण।
+  */
+
+let bug; // ऑब्जेक्ट घोषित करें
+
+function setup() {
+  createCanvas(710, 400);
+  // ऑब्जेक्ट बनाएं
+  bug = new Jitter();
+}
+
+function draw() {
+  background(50, 89, 100);
+  bug.move();
+  bug.display();
+}
+
+// Jitter class
+class Jitter {
+  constructor() {
+    this.x = random(width);
+    this.y = random(height);
+    this.diameter = random(10, 30);
+    this.speed = 1;
+  }
+
+  move() {
+    this.x += random(-this.speed, this.speed);
+    this.y += random(-this.speed, this.speed);
+  }
+
+  display() {
+    ellipse(this.x, this.y, this.diameter, this.diameter);
+  }
+}
diff --git a/dist/assets/examples/hi/11_Objects/02_Multiple_Objects.js b/dist/assets/examples/hi/11_Objects/02_Multiple_Objects.js
new file mode 100644
index 0000000000..0f2e561ca3
--- /dev/null
+++ b/dist/assets/examples/hi/11_Objects/02_Multiple_Objects.js
@@ -0,0 +1,50 @@
+/*
+  * @name वस्तुओं का नाम दें
+  * @description एक जिटर क्लास बनाएं, कई ऑब्जेक्ट्स को इंस्टेंट करें,
+  * और इसे स्क्रीन के चारों ओर ले जाएँ।
+  */
+
+let bug1; // वस्तुओं की घोषणा करें
+let bug2;
+let bug3;
+let bug4;
+
+function setup() {
+  createCanvas(710, 400);
+  // ऑब्जेक्ट बनाएं
+  bug1 = new Jitter();
+  bug2 = new Jitter();
+  bug3 = new Jitter();
+  bug4 = new Jitter();
+}
+
+function draw() {
+  background(50, 89, 100);
+  bug1.move();
+  bug1.display();
+  bug2.move();
+  bug2.display();
+  bug3.move();
+  bug3.display();
+  bug4.move();
+  bug4.display();
+}
+
+// जिटर क्लास
+class Jitter {
+  constructor() {
+    this.x = random(width);
+    this.y = random(height);
+    this.diameter = random(10, 30);
+    this.speed = 1;
+  }
+
+  move() {
+    this.x += random(-this.speed, this.speed);
+    this.y += random(-this.speed, this.speed);
+  }
+
+  display() {
+    ellipse(this.x, this.y, this.diameter, this.diameter);
+  }
+}
diff --git a/dist/assets/examples/hi/11_Objects/03_Objects_Array.js b/dist/assets/examples/hi/11_Objects/03_Objects_Array.js
new file mode 100644
index 0000000000..92a979d22e
--- /dev/null
+++ b/dist/assets/examples/hi/11_Objects/03_Objects_Array.js
@@ -0,0 +1,42 @@
+/*
+  * @name वस्तुओं की सरणी
+  * @description एक जिटर क्लास बनाएं, वस्तुओं की एक सरणी को इंस्टेंट करें
+  * और उन्हें स्क्रीन के चारों ओर ले जाएँ।
+  */
+
+let bugs = []; // जिटर ऑब्जेक्ट्स की सरणी
+
+function setup() {
+  createCanvas(710, 400);
+  // ऑब्जेक्ट बनाएं
+  for (let i = 0; i < 50; i++) {
+    bugs.push(new Jitter());
+  }
+}
+
+function draw() {
+  background(50, 89, 100);
+  for (let i = 0; i < bugs.length; i++) {
+    bugs[i].move();
+    bugs[i].display();
+  }
+}
+
+// जिटर क्लास
+class Jitter {
+  constructor() {
+    this.x = random(width);
+    this.y = random(height);
+    this.diameter = random(10, 30);
+    this.speed = 1;
+  }
+
+  move() {
+    this.x += random(-this.speed, this.speed);
+    this.y += random(-this.speed, this.speed);
+  }
+
+  display() {
+    ellipse(this.x, this.y, this.diameter, this.diameter);
+  }
+}
diff --git a/dist/assets/examples/hi/11_Objects/03_Objects_Optional_Arguments.js b/dist/assets/examples/hi/11_Objects/03_Objects_Optional_Arguments.js
new file mode 100644
index 0000000000..79a2de8448
--- /dev/null
+++ b/dist/assets/examples/hi/11_Objects/03_Objects_Optional_Arguments.js
@@ -0,0 +1,65 @@
+/*
+  * @name वस्तु 2
+  * @description उदाहरण के लिए hbarragan द्वारा पोर्ट किया गया। कर्सर को इसके पार ले जाएँ
+  * छवि ज्यामिति की गति और स्थिति को बदलने के लिए। कक्षा MRect
+  * लाइनों के समूह को परिभाषित करता है।
+  */
+
+let r1, r2, r3, r4;
+
+function setup() {
+  createCanvas(710, 400);
+  fill(255, 204);
+  noStroke();
+  r1 = new MRect(1, 134.0, 0.532, 0.1 * height, 10.0, 60.0);
+  r2 = new MRect(2, 44.0, 0.166, 0.3 * height, 5.0, 50.0);
+  r3 = new MRect(2, 58.0, 0.332, 0.4 * height, 10.0, 35.0);
+  r4 = new MRect(1, 120.0, 0.0498, 0.9 * height, 15.0, 60.0);
+}
+
+function draw() {
+  background(0);
+
+  r1.display();
+  r2.display();
+  r3.display();
+  r4.display();
+
+  r1.move(mouseX - width / 2, mouseY + height * 0.1, 30);
+  r2.move((mouseX + width * 0.05) % width, mouseY + height * 0.025, 20);
+  r3.move(mouseX / 4, mouseY - height * 0.025, 40);
+  r4.move(mouseX - width / 2, height - mouseY, 50);
+}
+
+class MRect {
+  constructor(iw, ixp, ih, iyp, id, it) {
+    this.w = iw; // सिंगल बार चौड़ाई
+    this.xpos = ixp; // रेक्ट एक्सपोजिशन
+    this.h = ih; // रेक्ट ऊंचाई
+    this.ypos = iyp; // रेक्ट योपोजिशन
+    this.d = id; // सिंगल बार दूरी
+    this.t = it; // बार की संख्या
+  }
+
+  move(posX, posY, damping) {
+    let dif = this.ypos - posY;
+    if (abs(dif) > 1) {
+      this.ypos -= dif / damping;
+    }
+    dif = this.xpos - posX;
+    if (abs(dif) > 1) {
+      this.xpos -= dif / damping;
+    }
+  }
+
+  display() {
+    for (let i = 0; i < this.t; i++) {
+      rect(
+        this.xpos + i * (this.d + this.w),
+        this.ypos,
+        this.w,
+        height * this.h
+      );
+    }
+  }
+}
diff --git a/dist/assets/examples/hi/11_Objects/04_Inheritance.js b/dist/assets/examples/hi/11_Objects/04_Inheritance.js
new file mode 100644
index 0000000000..9fddbcd0e9
--- /dev/null
+++ b/dist/assets/examples/hi/11_Objects/04_Inheritance.js
@@ -0,0 +1,71 @@
+/*  @name वंशानुक्रम
+  * @description एक वर्ग को दूसरे वर्ग का उपयोग करके परिभाषित किया जा सकता है a
+  * नींव। वस्तु-उन्मुख प्रोग्रामिंग शब्दावली में, एक वर्ग कर सकता है
+  * फ़ील्ड और विधियों को दूसरे से प्राप्त करें। एक वस्तु जो विरासत में मिलती है
+  * दूसरे को उपवर्ग कहा जाता है, और जिस वस्तु से इसे विरासत में मिला है उसे कहा जाता है
+  * एक सुपरक्लास। एक उपवर्ग सुपरक्लास का विस्तार करता है।
+  */
+let spots, arm;
+
+function setup() {
+  createCanvas(640, 360);
+  arm = new SpinArm(width/2, height/2, 0.01);
+  spots = new SpinSpots(width/2, height/2, -0.02, 90.0);
+}
+
+function draw() {
+  background(204);
+  arm.update();
+  arm.display();
+  spots.update();
+  spots.display();
+}
+
+class SpinArm {
+  constructor(x, y, s) {
+    this.x = x;
+    this.y = y;
+    this.speed = s;
+    this.angle = 0.0;
+  }
+
+  update() {
+    this.angle += this.speed;
+  }
+
+  display() {
+    strokeWeight(1);
+    stroke(0);
+    push();
+    translate(this.x, this.y);
+    this.angle += this.speed;
+    rotate(this.angle);
+    line(0, 0, 165, 0);
+    pop();
+  }
+}
+
+class SpinSpots {
+  constructor(x, y, s, d) {
+    this.x = x;
+    this.y = y;
+    this.speed = s;
+    this.dim = d;
+    this.angle = 0.0;
+  }
+
+  update() {
+    this.angle += this.speed;
+  }
+
+  display() {
+    noStroke();
+    push();
+    translate(this.x, this.y);
+    this.angle += this.speed;
+    rotate(this.angle);
+    ellipse(-this.dim/2, 0, this.dim, this.dim);
+    ellipse(this.dim/2, 0, this.dim, this.dim);
+    pop();
+  }
+}
diff --git a/dist/assets/examples/hi/11_Objects/05_Composite_Objects.js b/dist/assets/examples/hi/11_Objects/05_Composite_Objects.js
new file mode 100644
index 0000000000..f13f7df52f
--- /dev/null
+++ b/dist/assets/examples/hi/11_Objects/05_Composite_Objects.js
@@ -0,0 +1,99 @@
+/*  @name समग्र वस्तु
+  * @description एक ऑब्जेक्ट में कई अन्य ऑब्जेक्ट शामिल हो सकते हैं।
+  * इस तरह की मिश्रित वस्तुओं का निर्माण सिद्धांतों का उपयोग करने का एक अच्छा तरीका है
+  * प्रतिरूपकता और एक कार्यक्रम के भीतर अमूर्तता के उच्च स्तर का निर्माण।
+  */
+let er1, er2;
+
+function setup() {
+  createCanvas(640, 360);
+  er1 = new EggRing(width*0.45, height*0.5, 0.1, 120);
+  er2 = new EggRing(width*0.65, height*0.8, 0.05, 180);
+}
+
+function draw() {
+  background(0);
+  er1.transmit();
+  er2.transmit();
+}
+
+class Egg {
+  constructor(xpos, ypos, t, s) {
+    this.x = xpos;
+    this.y = ypos;
+    this.tilt = t;
+    this.scalar = s / 100.0;
+    this.angle = 0.0;
+  }
+
+  wobble() {
+    this.tilt = cos(this.angle) / 8;
+    this.angle += 0.1;
+  }
+
+  display() {
+    noStroke();
+    fill(255);
+    push();
+    translate(this.x, this.y);
+    rotate(this.tilt);
+    scale(this.scalar);
+    beginShape();
+    vertex(0, -100);
+    bezierVertex(25, -100, 40, -65, 40, -40);
+    bezierVertex(40, -15, 25, 0, 0, 0);
+    bezierVertex(-25, 0, -40, -15, -40, -40);
+    bezierVertex(-40, -65, -25, -100, 0, -100);
+    endShape();
+    pop();
+  }
+}
+
+class Ring {
+  start(xpos, ypos) {
+    this.x = xpos;
+    this.y = ypos;
+    this.on = true;
+    this.diameter = 1;
+  }
+
+  grow() {
+    if (this.on == true) {
+      this.diameter += 0.5;
+      if (this.diameter > width*2) {
+        this.diameter = 0.0;
+      }
+    }
+  }
+
+  display() {
+    if (this.on == true) {
+      noFill();
+      strokeWeight(4);
+      stroke(155, 153);
+      ellipse(this.x, this.y, this.diameter, this.diameter);
+    }
+  }
+}
+
+class EggRing {
+  constructor(x, y, t, sp) {
+    this.x = x;
+    this.y = y;
+    this.t = t;
+    this.sp = sp;
+    this.circle = new Ring();
+    this.ovoid = new Egg(this.x, this.y, this.t, this.sp);
+    this.circle.start(this.x, this.y - this.sp/2);
+  }
+
+  transmit() {
+    this.ovoid.wobble();
+    this.ovoid.display();
+    this.circle.grow();
+    this.circle.display();
+    if (circle.on == false) {
+      circle.on = true;
+    }
+  }
+}
diff --git a/dist/assets/examples/hi/12_Lights/02_Directional.js b/dist/assets/examples/hi/12_Lights/02_Directional.js
new file mode 100644
index 0000000000..d3c6242edc
--- /dev/null
+++ b/dist/assets/examples/hi/12_Lights/02_Directional.js
@@ -0,0 +1,27 @@
+/*
+  * @name दिशात्मक
+  * @frame 710,400
+  * @description प्रकाश की दिशा बदलने के लिए माउस ले जाएँ।
+  * दिशात्मक प्रकाश एक दिशा से आता है और हिट करने पर मजबूत होता है
+  * सतह वर्गाकार और कमजोर अगर यह एक कोमल कोण से टकराती है। मारने के बाद
+  * सतह, एक दिशात्मक प्रकाश सभी दिशाओं में बिखरता है।
+  */
+const radius = 200;
+
+function setup() {
+  createCanvas(710, 400, WEBGL);
+  noStroke();
+  fill(200);
+}
+
+function draw() {
+  noStroke();
+  background(0);
+  const dirY = (mouseY / height - 0.5) * 4;
+  const dirX = (mouseX / width - 0.5) * 4;
+  directionalLight(204, 204, 204, dirX, dirY, 1);
+  translate(-1.5 * radius, 0, 0);
+  sphere(radius);
+  translate(3 * radius, 0, 0);
+  sphere(radius);
+}
diff --git a/dist/assets/examples/hi/12_Lights/05_Mixture.js b/dist/assets/examples/hi/12_Lights/05_Mixture.js
new file mode 100644
index 0000000000..2b99d66f1f
--- /dev/null
+++ b/dist/assets/examples/hi/12_Lights/05_Mixture.js
@@ -0,0 +1,26 @@
+/*
+  * @name मिश्रण
+  * @frame 710,400 (वैकल्पिक)
+  * @description तीन अलग-अलग प्रकार की रोशनी वाला एक बॉक्स प्रदर्शित करें।
+  */
+function setup() {
+  createCanvas(710, 400, WEBGL);
+  noStroke();
+}
+
+function draw() {
+  background(0);
+
+  // दाईं ओर नारंगी बिंदु प्रकाश
+  pointLight(150, 100, 0, 500, 0, 200);
+
+  // बाईं ओर से नीली दिशात्मक रोशनी
+  directionalLight(0, 102, 255, -1, 0, 0);
+
+  // सामने से पीला स्पॉटलाइट
+  pointLight(255, 255, 109, 0, 0, 300);
+
+  rotateY(map(mouseX, 0, width, 0, PI));
+  rotateX(map(mouseY, 0, height, 0, PI));
+  box(200);
+}
diff --git a/dist/assets/examples/hi/13_Motion/01_non_orthogonal_reflection.js b/dist/assets/examples/hi/13_Motion/01_non_orthogonal_reflection.js
new file mode 100644
index 0000000000..ac8f5cfc29
--- /dev/null
+++ b/dist/assets/examples/hi/13_Motion/01_non_orthogonal_reflection.js
@@ -0,0 +1,110 @@
+/*
+  * @name नॉन ऑर्थोगोनल रिफ्लेक्शन
+  * @frame 710,400 (वैकल्पिक)
+  * @description यह प्रोसेसिंग.org/examples से "प्रतिबिंब 1" उदाहरण के डेविड ब्लिट्ज का एक पोर्ट है
+  */
+
+// फर्श के बाएं हाथ की स्थिति
+let base1;
+
+// फर्श के दाहिने हाथ की स्थिति
+let base2;
+// फर्श की लंबाई
+// बेसलेंथ दें;
+
+// चलती गेंद से संबंधित चर
+let position;
+let velocity;
+let r = 6;
+let speed = 3.5;
+
+function setup() {
+  createCanvas(710, 400);
+
+  fill(128);
+  base1 = createVector(0, height - 150);
+  base2 = createVector(width, height);
+   //createGround();
+
+   // स्क्रीन के मध्य शीर्ष पर अंडाकार प्रारंभ करें
+  position = createVector(width / 2, 0);
+
+  // प्रारंभिक यादृच्छिक वेग की गणना करें
+  velocity = p5.Vector.random2D();
+  velocity.mult(speed);
+}
+
+function draw() {
+  // ड्रा बैकग्राउंड
+  fill(0, 12);
+  noStroke();
+  rect(0, 0, width, height);
+
+  // ड्रा बेस
+  fill(200);
+  quad(base1.x, base1.y, base2.x, base2.y, base2.x, height, 0, height);
+
+  // बेस टॉप नॉर्मल की गणना करें
+  let baseDelta = p5.Vector.sub(base2, base1);
+  baseDelta.normalize();
+  let normal = createVector(-baseDelta.y, baseDelta.x);
+  let intercept = p5.Vector.dot(base1, normal);
+
+  // दीर्घवृत्त खींचें
+  noStroke();
+  fill(255);
+  ellipse(position.x, position.y, r * 2, r * 2);
+
+  // दीर्घवृत्त ले जाएँ
+  position.add(velocity);
+
+  // सामान्यीकृत घटना वेक्टर
+  incidence = p5.Vector.mult(velocity, -1);
+  incidence.normalize();
+
+  // बेस के साथ टकराव का पता लगाएं और संभालें
+  if (p5.Vector.dot(normal, position) > intercept) {
+    // घटना वेक्टर और बेस टॉप के डॉट उत्पाद की गणना करें
+    let dot = incidence.dot(normal);
+
+    // प्रतिबिंब वेक्टर की गणना करें
+    // दिशा वेक्टर को प्रतिबिंब वेक्टर असाइन करें
+    velocity.set(
+      2 * normal.x * dot - incidence.x,
+      2 * normal.y * dot - incidence.y,
+      0
+    );
+    velocity.mult(speed);
+
+    // टकराव बिंदु पर आधार शीर्ष सामान्य बनाएं
+    stroke(255, 128, 0);
+    line(
+      position.x,
+      position.y,
+      position.x - normal.x * 100,
+      position.y - normal.y * 100
+    );
+  }
+  //}
+
+  // सीमा टकराव का पता लगाएं
+  // सही
+  if (position.x > width - r) {
+    position.x = width - r;
+    velocity.x *= -1;
+  }
+  // बाएं
+  if (position.x < r) {
+    position.x = r;
+    velocity.x *= -1;
+  }
+  // ऊपर
+  if (position.y < r) {
+    position.y = r;
+    velocity.y *= -1;
+
+    // बेस टॉप को रैंडमाइज करें
+    base1.y = random(height - 100, height);
+    base2.y = random(height - 100, height);
+  }
+}
diff --git a/dist/assets/examples/hi/13_Motion/02_Linear_Motion.js b/dist/assets/examples/hi/13_Motion/02_Linear_Motion.js
new file mode 100644
index 0000000000..bd57d50460
--- /dev/null
+++ b/dist/assets/examples/hi/13_Motion/02_Linear_Motion.js
@@ -0,0 +1,24 @@
+/*
+  * @name रैखिक
+  * @frame 720,400
+  * @description मूविंग लाइन बनाने के लिए वेरिएबल को बदलना।
+  * जब रेखा खिड़की के किनारे से हटती है,
+  * वेरिएबल को 0 पर सेट किया जाता है, जो लाइन को स्क्रीन के निचले हिस्से में वापस रखता है।
+  */
+
+let a;
+
+function setup() {
+  createCanvas(720, 400);
+  stroke(255);
+  a = height / 2;
+}
+
+function draw() {
+  background(51);
+  line(0, a, width, a);
+  a = a - 0.5;
+  if (a < 0) {
+    a = height;
+  }
+}
diff --git a/dist/assets/examples/hi/13_Motion/03_Bounce.js b/dist/assets/examples/hi/13_Motion/03_Bounce.js
new file mode 100644
index 0000000000..7b7f678f88
--- /dev/null
+++ b/dist/assets/examples/hi/13_Motion/03_Bounce.js
@@ -0,0 +1,44 @@
+/*
+  * @name उछाल
+  * @frame 720,400
+  * @description जब आकृति खिड़की के किनारे से टकराती है, तो वह अपनी दिशा उलट देती है।
+  */
+
+let rad = 60; // आकार की चौड़ाई
+let xpos, ypos; // आकार की प्रारंभिक स्थिति
+
+let xspeed = 2.8; // आकार की गति
+let yspeed = 2.2; // आकार की गति
+
+let xdirection = 1; // बायें या दायें
+let ydirection = 1; // ऊपर से नीचे
+
+function setup() {
+  createCanvas(720, 400);
+  noStroke();
+  frameRate(30);
+  ellipseMode(RADIUS);
+  // आकृति की प्रारंभिक स्थिति निर्धारित करें
+  xpos = width / 2;
+  ypos = height / 2;
+}
+
+function draw() {
+  background(102);
+
+  // आकृति की स्थिति को अपडेट करें
+  xpos = xpos + xspeed * xdirection;
+  ypos = ypos + yspeed * ydirection;
+
+   // यह देखने के लिए परीक्षण करें कि क्या आकार स्क्रीन की सीमाओं से अधिक है
+   // यदि ऐसा होता है, तो -1 . से गुणा करके इसकी दिशा उलट दें
+  if (xpos > width - rad || xpos < rad) {
+    xdirection *= -1;
+  }
+  if (ypos > height - rad || ypos < rad) {
+    ydirection *= -1;
+  }
+
+  // आकृति बनाएं
+  ellipse(xpos, ypos, rad, rad);
+}
diff --git a/dist/assets/examples/hi/13_Motion/04_Bouncy_Bubbles.js b/dist/assets/examples/hi/13_Motion/04_Bouncy_Bubbles.js
new file mode 100644
index 0000000000..6fa76833fc
--- /dev/null
+++ b/dist/assets/examples/hi/13_Motion/04_Bouncy_Bubbles.js
@@ -0,0 +1,95 @@
+/*
+  * @name उछाल वाले बुलबुले
+  * @frame 720,400
+  * @description कीथ पीटर्स के कोड पर आधारित विवरण। एकाधिक-वस्तु टकराव ..
+  */
+
+let numBalls = 13;
+let spring = 0.05;
+let gravity = 0.03;
+let friction = -0.9;
+let balls = [];
+
+function setup() {
+  createCanvas(720, 400);
+  for (let i = 0; i < numBalls; i++) {
+    balls[i] = new Ball(
+      random(width),
+      random(height),
+      random(30, 70),
+      i,
+      balls
+    );
+  }
+  noStroke();
+  fill(255, 204);
+}
+
+function draw() {
+  background(0);
+  balls.forEach(ball => {
+    ball.collide();
+    ball.move();
+    ball.display();
+  });
+}
+
+class Ball {
+  constructor(xin, yin, din, idin, oin) {
+    this.x = xin;
+    this.y = yin;
+    this.vx = 0;
+    this.vy = 0;
+    this.diameter = din;
+    this.id = idin;
+    this.others = oin;
+  }
+
+  collide() {
+    for (let i = this.id + 1; i < numBalls; i++) {
+      // कंसोल.लॉग (अन्य [i]);
+      let dx = this.others[i].x - this.x;
+      let dy = this.others[i].y - this.y;
+      let distance = sqrt(dx * dx + dy * dy);
+      let minDist = this.others[i].diameter / 2 + this.diameter / 2;
+       // कंसोल.लॉग (दूरी);
+       // कंसोल.लॉग (मिनडिस्ट);
+      if (distance < minDist) {
+        // कंसोल.लॉग ("2");
+        let angle = atan2(dy, dx);
+        let targetX = this.x + cos(angle) * minDist;
+        let targetY = this.y + sin(angle) * minDist;
+        let ax = (targetX - this.others[i].x) * spring;
+        let ay = (targetY - this.others[i].y) * spring;
+        this.vx -= ax;
+        this.vy -= ay;
+        this.others[i].vx += ax;
+        this.others[i].vy += ay;
+      }
+    }
+  }
+
+  move() {
+    this.vy += gravity;
+    this.x += this.vx;
+    this.y += this.vy;
+    if (this.x + this.diameter / 2 > width) {
+      this.x = width - this.diameter / 2;
+      this.vx *= friction;
+    } else if (this.x - this.diameter / 2 < 0) {
+      this.x = this.diameter / 2;
+      this.vx *= friction;
+    }
+    if (this.y + this.diameter / 2 > height) {
+      this.y = height - this.diameter / 2;
+      this.vy *= friction;
+    } else if (this.y - this.diameter / 2 < 0) {
+      this.y = this.diameter / 2;
+      this.vy *= friction;
+    }
+  }
+
+  display() {
+    ellipse(this.x, this.y, this.diameter, this.diameter);
+  }
+}
diff --git a/dist/assets/examples/hi/13_Motion/05_Morph.js b/dist/assets/examples/hi/13_Motion/05_Morph.js
new file mode 100644
index 0000000000..cca26800e3
--- /dev/null
+++ b/dist/assets/examples/hi/13_Motion/05_Morph.js
@@ -0,0 +1,93 @@
+/*
+  * @name मॉर्फ
+  * @frame 720,400
+  * @description शीर्षों को एक से दूसरे में प्रक्षेपित करके एक आकृति को दूसरी आकृति में बदलना।
+  */
+
+// दो ऐरेलिस्ट दो आकृतियों के लिए कोने को स्टोर करने के लिए
+// यह उदाहरण मानता है कि प्रत्येक आकृति में समान होगा
+// कोने की संख्या, यानी प्रत्येक ArrayList का आकार समान होगा
+let circle = [];
+let square = [];
+
+// एक तीसरे सेट के लिए एक ऐरेलिस्ट, जिसे हम चित्रित करेंगे
+// खिड़की में
+let morph = [];
+
+// यह बूलियन चर नियंत्रित करेगा यदि हम किसी वृत्त या वर्ग में रूपांतरित कर रहे हैं
+let state = false;
+
+function setup() {
+  createCanvas(720, 400);
+
+// केंद्र से इंगित करने वाले वैक्टर का उपयोग करके एक सर्कल बनाएं
+  for (let angle = 0; angle < 360; angle += 9) {
+    // ध्यान दें कि मिलान करने के लिए हम 0 से शुरू नहीं कर रहे हैं
+     // एक सर्कल का पथ।
+    let v = p5.Vector.fromAngle(radians(angle - 135));
+    v.mult(100);
+    circle.push(v);
+    // जब हम इस पर होते हैं तो खाली PVectors के साथ morph ArrayList को भरते हैं
+    morph.push(createVector());
+  }
+
+   // एक वर्ग सीधी रेखाओं के साथ कोने का एक गुच्छा है
+   // वर्ग के ऊपर
+  for (let x = -50; x < 50; x += 10) {
+    square.push(createVector(x, -50));
+  }
+  // दाईं ओर
+  for (let y = -50; y < 50; y += 10) {
+    square.push(createVector(50, y));
+  }
+  // तल
+  for (let x = 50; x > -50; x -= 10) {
+    square.push(createVector(x, 50));
+  }
+  // बाईं तरफ
+  for (let y = 50; y > -50; y -= 10) {
+    square.push(createVector(-50, y));
+  }
+}
+
+function draw() {
+  background(51);
+
+  // हम रखेंगे कि उनके लक्ष्य से कोने कितनी दूर हैं
+  let totalDistance = 0;
+
+  // प्रत्येक शीर्ष को देखें
+  for (let i = 0; i < circle.length; i++) {
+    let v1;
+    // क्या हम वृत्त या वर्ग की ओर झुक रहे हैं?
+    if (state) {
+      v1 = circle[i];
+    } else {
+      v1 = square[i];
+    }
+    // वह शीर्ष प्राप्त करें जिसे हम खींचेंगे
+    let v2 = morph[i];
+    // लक्ष्य के लिए Lerp
+    v2.lerp(v1, 0.1);
+    // जांचें कि हम लक्ष्य से कितनी दूर हैं
+    totalDistance += p5.Vector.dist(v1, v2);
+  }
+
+  // यदि सभी कोने करीब हैं, तो आकार बदलें
+  if (totalDistance < 0.1) {
+    state = !state;
+  }
+
+  // केंद्र के सापेक्ष ड्रा करें
+  translate(width / 2, height / 2);
+  strokeWeight(4);
+  // एक बहुभुज बनाएं जो सभी शीर्षों को बनाता है
+  beginShape();
+  noFill();
+  stroke(255);
+
+  morph.forEach(v => {
+    vertex(v.x, v.y);
+  });
+  endShape(CLOSE);
+}
diff --git a/dist/assets/examples/hi/13_Motion/06_Moving_On_Curves.js b/dist/assets/examples/hi/13_Motion/06_Moving_On_Curves.js
new file mode 100644
index 0000000000..8d8c22bfd4
--- /dev/null
+++ b/dist/assets/examples/hi/13_Motion/06_Moving_On_Curves.js
@@ -0,0 +1,47 @@
+/*
+  * @name मूविंग ऑन कर्व्स
+  * @frame 720,400
+  * @description इस उदाहरण में, वृत्त वक्र y = x^4 के अनुदिश चलते हैं।
+  * माउस को नई स्थिति में ले जाने के लिए उस पर क्लिक करें।
+  */
+
+let beginX = 20.0; // वर्तमान x-निर्देशांक
+let beginY = 10.0; // प्रारंभिक y-निर्देशांक
+let endX = 570.0; // वर्तमान x-निर्देशांक
+let endY = 320.0; // अंतिम y-निर्देशांक
+let distX; // एक्स-अक्ष दूरी को स्थानांतरित करने के लिए
+let distY; // वाई-अक्ष दूरी को स्थानांतरित करने के लिए
+let exponent = 4; // वक्र निर्धारित करता है
+let x = 0.0; // वर्तमान x-निर्देशांक
+let y = 0.0; // वर्तमान y-निर्देशांक
+let step = 0.01; // पथ के साथ प्रत्येक चरण का आकार
+let pct = 0.0; // यात्रा का प्रतिशत (0.0 से 1.0)
+
+function setup() {
+  createCanvas(720, 400);
+  noStroke();
+  distX = endX - beginX;
+  distY = endY - beginY;
+}
+
+function draw() {
+  fill(0, 2);
+  rect(0, 0, width, height);
+  pct += step;
+  if (pct < 1.0) {
+    x = beginX + pct * distX;
+    y = beginY + pow(pct, exponent) * distY;
+  }
+  fill(255);
+  ellipse(x, y, 20, 20);
+}
+
+function mousePressed() {
+  pct = 0.0;
+  beginX = x;
+  beginY = y;
+  endX = mouseX;
+  endY = mouseY;
+  distX = endX - beginX;
+  distY = endY - beginY;
+}
diff --git a/dist/assets/examples/hi/15_Instance_Mode/01_Instantiating.js b/dist/assets/examples/hi/15_Instance_Mode/01_Instantiating.js
new file mode 100644
index 0000000000..1b779c4742
--- /dev/null
+++ b/dist/assets/examples/hi/15_Instance_Mode/01_Instantiating.js
@@ -0,0 +1,35 @@
+/*
+  * @name इंस्टेंटेशन
+  * @description एक p5 इंस्टेंस बनाएं, जो सभी वेरिएबल को बनाए रखता है
+  * आपके पेज के वैश्विक दायरे से बाहर।
+  */
+let sketch = function(p) {
+  let x = 100;
+  let y = 100;
+
+  p.setup = function() {
+    p.createCanvas(700, 410);
+  };
+
+  p.draw = function() {
+    p.background(0);
+    p.fill(255);
+    p.rect(x, y, 50, 50);
+  };
+};
+
+let myp5 = new p5(sketch);
+
+// Compare to "global mode"
+// let x = 100;
+// let y = 100;
+
+// function setup() {
+//   createCanvas(200,200);
+// }
+
+// function draw() {
+//   background(0);
+//   fill(255);
+//   ellipse(x,y,50,50);
+// }
diff --git a/dist/assets/examples/hi/15_Instance_Mode/02_Instance_Container.js b/dist/assets/examples/hi/15_Instance_Mode/02_Instance_Container.js
new file mode 100644
index 0000000000..a20622ef84
--- /dev/null
+++ b/dist/assets/examples/hi/15_Instance_Mode/02_Instance_Container.js
@@ -0,0 +1,94 @@
+/*
+  * @norender
+  * @name इंस्टेंस कंटेनर
+  * @description वैकल्पिक रूप से, आप कैनवास के लिए एक डिफ़ॉल्ट कंटेनर निर्दिष्ट कर सकते हैं
+  * और किसी अन्य तत्व को दूसरे तर्क के साथ जोड़ने के लिए। आप दे सकते हैं
+  * आपके html में किसी तत्व की आईडी, या स्वयं एक html नोड।
+  *
+  * कंटेनर चुनने के लिए यहां तीन अलग-अलग विकल्प दिए गए हैं
+  * डोम तत्व। p5 द्वारा बनाए गए सभी DOM तत्व (कैनवास, बटन, डिव, आदि)
+  * को दूसरे तर्क के रूप में निर्दिष्ट DOM तत्व से जोड़ा जाएगा
+  * p5 () कॉल।
+  */
+
+
+
+  
+
+
+  
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dist/assets/examples/hi/16_Dom/03_Input_Button.js b/dist/assets/examples/hi/16_Dom/03_Input_Button.js new file mode 100644 index 0000000000..0af112c0f5 --- /dev/null +++ b/dist/assets/examples/hi/16_Dom/03_Input_Button.js @@ -0,0 +1,41 @@ +/* + * @name इनपुट और बटन + * @description आपको शामिल करना होगा + * p5.dom लाइब्रेरी + * इस उदाहरण के लिए अपने स्वयं के प्रोजेक्ट में काम करने के लिए।

+ * इनपुट टेक्स्ट और यह देखने के लिए बटन पर क्लिक करें कि यह कैनवास को प्रभावित करता है। + */ +let input, button, greeting; + +function setup() { + // कैनवास बनाएं + createCanvas(710, 400); + + input = createInput(); + input.position(20, 65); + + button = createButton('submit'); + button.position(input.x + input.width, 65); + button.mousePressed(greet); + + greeting = createElement('h2', 'what is your name?'); + greeting.position(20, 5); + + textAlign(CENTER); + textSize(50); +} + +function greet() { + const name = input.value(); + greeting.html('hello ' + name + '!'); + input.value(''); + + for (let i = 0; i < 200; i++) { + push(); + fill(random(255), 255, 255); + translate(random(width), random(height)); + rotate(random(2 * PI)); + text(name, 0, 0); + pop(); + } +} diff --git a/dist/assets/examples/hi/16_Dom/04_Slider.js b/dist/assets/examples/hi/16_Dom/04_Slider.js new file mode 100644 index 0000000000..a952164025 --- /dev/null +++ b/dist/assets/examples/hi/16_Dom/04_Slider.js @@ -0,0 +1,33 @@ +/* + * @name स्लाइडर + * @description आपको शामिल करना होगा + * p5.dom लाइब्रेरी + * इस उदाहरण के लिए अपने स्वयं के प्रोजेक्ट में काम करने के लिए।

+ * पृष्ठभूमि के आर, जी, बी मूल्यों को नियंत्रित करने के लिए स्लाइडर्स को स्थानांतरित करें। + */ +let rSlider, gSlider, bSlider; + +function setup() { + // create canvas + createCanvas(710, 400); + textSize(15); + noStroke(); + + // create sliders + rSlider = createSlider(0, 255, 100); + rSlider.position(20, 20); + gSlider = createSlider(0, 255, 0); + gSlider.position(20, 50); + bSlider = createSlider(0, 255, 255); + bSlider.position(20, 80); +} + +function draw() { + const r = rSlider.value(); + const g = gSlider.value(); + const b = bSlider.value(); + background(r, g, b); + text('red', rSlider.x * 2 + rSlider.width, 35); + text('green', gSlider.x * 2 + gSlider.width, 65); + text('blue', bSlider.x * 2 + bSlider.width, 95); +} diff --git a/dist/assets/examples/hi/16_Dom/07_Modify_DOM.js b/dist/assets/examples/hi/16_Dom/07_Modify_DOM.js new file mode 100644 index 0000000000..8bbc81cabb --- /dev/null +++ b/dist/assets/examples/hi/16_Dom/07_Modify_DOM.js @@ -0,0 +1,56 @@ +/* + * @name डोम को संशोधित करना + * @frame 710,300 + * @description

DOM एलिमेंट बनाएं और हर बार उनके गुणों को संशोधित करें + * draw() कहा जाता है। आपको शामिल करने की आवश्यकता होगी + * p5.dom लाइब्रेरी + * इस उदाहरण के लिए अपने स्वयं के प्रोजेक्ट में काम करने के लिए।

+ */ +let dancingWords = []; + +class DanceSpan { + constructor(element, x, y) { + element.position(x, y); + this.element = element; + this.x = x; + this.y = y; + } + + brownian() { + this.x += random(-6, 6); + this.y += random(-6, 6); + this.element.position(this.x, this.y); + } +} + +function setup() { + // यह पैराग्राफ कोड के मुख्य ब्लॉक से अलग बनाया गया है। + // यह किसी तत्व के निर्माण को उसके . से अलग करना है + // चयन। चयनित तत्वों को बनाने की आवश्यकता नहीं है + // p5js, वे सिर्फ सादा HTML हो सकते हैं। + createP( + 'I learn in this Letter, that Don Peter of Aragon, ' + + ' comes this night to Messina' + ).addClass('text').hide(); + + // यह लाइन अभी बनाए गए पैराग्राफ को पकड़ लेती है, लेकिन यह but + // HTML में वर्ग 'पाठ' के साथ किसी अन्य तत्व को भी पकड़ें + // पृष्ठ। + const texts = selectAll('.text'); + + for (let i = 0; i < texts.length; i++) { + const paragraph = texts[i].html(); + const words = paragraph.split(' '); + for (let j = 0; j < words.length; j++) { + const spannedWord = createSpan(words[j]); + const dw = new DanceSpan(spannedWord, random(600), random(200)); + dancingWords.push(dw); + } + } +} + +function draw() { + for (let i = 0; i < dancingWords.length; i++) { + dancingWords[i].brownian(); + } +} diff --git a/dist/assets/examples/hi/16_Dom/08_Video.js b/dist/assets/examples/hi/16_Dom/08_Video.js new file mode 100644 index 0000000000..fb0c95966d --- /dev/null +++ b/dist/assets/examples/hi/16_Dom/08_Video.js @@ -0,0 +1,32 @@ +/* + * @name वीडियो + * @frame 710,250 + * @description

एक वीडियो को कई फ़ॉर्मैट में लोड करें और खेलने के बीच टॉगल करें + * और एक बटन प्रेस के साथ रुक गया। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको कम से कम की आवश्यकता होगी + * एक वीडियो फ़ाइल, और + * p5.dom लाइब्रेरी

+ */ +let playing = false; +let fingers; +let button; + +function setup() { + noCanvas(); + // specify multiple formats for different browsers + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + button = createButton('play'); + button.mousePressed(toggleVid); // attach button listener +} + +// plays or pauses the video depending on current state +function toggleVid() { + if (playing) { + fingers.pause(); + button.html('play'); + } else { + fingers.loop(); + button.html('pause'); + } + playing = !playing; +} diff --git a/dist/assets/examples/hi/16_Dom/09_Video_Canvas.js b/dist/assets/examples/hi/16_Dom/09_Video_Canvas.js new file mode 100644 index 0000000000..a6e8a0854d --- /dev/null +++ b/dist/assets/examples/hi/16_Dom/09_Video_Canvas.js @@ -0,0 +1,28 @@ +/* + * @name वीडियो कैनवास + * @description

एक वीडियो को कई फ़ॉर्मैट में लोड करें और उसे कैनवास पर ड्रा करें।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.dom लाइब्रेरी + * कम से कम एक वीडियो फ़ाइल, और एक चालू स्थानीय सर्वर + */ +let fingers; + +function setup() { + createCanvas(710, 400); + // विभिन्न ब्राउज़रों के लिए कई प्रारूप निर्दिष्ट करें + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.hide(); // डिफ़ॉल्ट रूप से वीडियो अलग डोम में दिखाई देता है + // तत्व। इसे छुपाएं और इसे कैनवास पर खींचें + // बजाय +} + +function draw() { + background(150); + image(fingers, 10, 10); // वीडियो फ्रेम को कैनवास पर ड्रा करें + filter(GRAY); + image(fingers, 150, 150); // कैनवास पर दूसरी कॉपी बनाएं +} + +function mousePressed() { + fingers.loop(); // वीडियो को लूप में सेट करें और खेलना शुरू करें +} diff --git a/dist/assets/examples/hi/16_Dom/10_Video_Pixels.js b/dist/assets/examples/hi/16_Dom/10_Video_Pixels.js new file mode 100644 index 0000000000..05d323e875 --- /dev/null +++ b/dist/assets/examples/hi/16_Dom/10_Video_Pixels.js @@ -0,0 +1,33 @@ +/* + * @name वीडियो पिक्सल + * @frame 320,240 + * @description

वीडियो लोड करें, उसके पिक्सल में हेरफेर करें और कैनवास पर ड्रा करें। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.dom लाइब्रेरी + * कम से कम एक वीडियो फ़ाइल, और एक चालू स्थानीय सर्वर + */ +let fingers; + +function setup() { + createCanvas(320, 240); + // specify multiple formats for different browsers + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.loop(); + fingers.hide(); + noStroke(); + fill(0); +} + +function draw() { + background(255); + fingers.loadPixels(); + const stepSize = round(constrain(mouseX / 8, 6, 32)); + for (let y = 0; y < height; y += stepSize) { + for (let x = 0; x < width; x += stepSize) { + const i = y * width + x; + const darkness = (255 - fingers.pixels[i * 4]) / 255; + const radius = stepSize * darkness; + ellipse(x, y, radius, radius); + } + } +} diff --git a/dist/assets/examples/hi/16_Dom/11_Capture.js b/dist/assets/examples/hi/16_Dom/11_Capture.js new file mode 100644 index 0000000000..43d1a84590 --- /dev/null +++ b/dist/assets/examples/hi/16_Dom/11_Capture.js @@ -0,0 +1,25 @@ +/* + * @name वीडियो कैप्चर + * @frame 710,240 + * @description

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.dom लाइब्रेरी + * कम से कम एक वीडियो फ़ाइल, और एक चालू स्थानीय सर्वर

+ * वेबकैम से वीडियो कैप्चर करें और प्रदर्शित करें + * कैनवास पर और साथ ही इनवर्ट फिल्टर के साथ। ध्यान दें कि द्वारा + * डिफॉल्ट कैप्चर फीड भी दिखाई देता है। आप छुपा सकते हैं + * capture.hide() लाइन को अनकम्मेंट करके फीड करें। + */ +let capture; + +function setup() { + createCanvas(390, 240); + capture = createCapture(VIDEO); + capture.size(320, 240); + //capture.hide(); +} + +function draw() { + background(255); + image(capture, 0, 0, 320, 240); + filter(INVERT); +} diff --git a/dist/assets/examples/hi/16_Dom/12_Drop.js b/dist/assets/examples/hi/16_Dom/12_Drop.js new file mode 100644 index 0000000000..b60a3d4fa3 --- /dev/null +++ b/dist/assets/examples/hi/16_Dom/12_Drop.js @@ -0,0 +1,36 @@ +/* + * @name छोड़ देना + * @description आपको शामिल करना होगा + * p5.dom लाइब्रेरी + * इस उदाहरण के लिए अपने स्वयं के प्रोजेक्ट में काम करने के लिए।

+ * एक छवि फ़ाइल को प्रदर्शित करने के लिए उसे कैनवास पर खींचें। + */ + +function setup() { + // कैनवास बनाएं + const c = createCanvas(710, 400); + background(100); + // जब कोई फ़ाइल कैनवास पर गिराई जाती है, तो उसके लिए एक ईवेंट जोड़ें + c.drop(gotFile); +} + +function draw() { + fill(255); + noStroke(); + textSize(24); + textAlign(CENTER); + text('Drag an image file onto the canvas.', width / 2, height / 2); + noLoop(); +} + +function gotFile(file) { + // यदि यह एक छवि फ़ाइल है + if (file.type === 'image') { + // एक छवि DOM तत्व बनाएं, लेकिन इसे न दिखाएं + const img = createImg(file.data).hide(); + // कैनवास पर चित्र बनाएं + image(img, 0, 0, width, height); + } else { + console.log('Not an image file!'); + } +} diff --git a/dist/assets/examples/hi/17_Drawing/00_Continuous_Lines.js b/dist/assets/examples/hi/17_Drawing/00_Continuous_Lines.js new file mode 100644 index 0000000000..242a7ccf9a --- /dev/null +++ b/dist/assets/examples/hi/17_Drawing/00_Continuous_Lines.js @@ -0,0 +1,15 @@ +/* +* @name सतत रेखा +* @description एक रेखा खींचने के लिए माउस को क्लिक करें और खींचें। +*/ +function setup() { + createCanvas(710, 400); + background(102); +} + +function draw() { + stroke(255); + if (mouseIsPressed === true) { + line(mouseX, mouseY, pmouseX, pmouseY); + } +} diff --git a/dist/assets/examples/hi/17_Drawing/01_Pattern.js b/dist/assets/examples/hi/17_Drawing/01_Pattern.js new file mode 100644 index 0000000000..baef5d6f14 --- /dev/null +++ b/dist/assets/examples/hi/17_Drawing/01_Pattern.js @@ -0,0 +1,27 @@ +/* + * @name पैटर्न + * @description सॉफ़्टवेयर टूल से चित्र बनाने के लिए कर्सर को छवि पर ले जाएं + * जो माउस की गति के प्रति प्रतिक्रिया करता है। + */ +function setup() { + createCanvas(710, 400); + background(102); +} + +function draw() { + // variableEllipse() विधि को कॉल करें और इसे भेजें + // वर्तमान माउस स्थिति के लिए पैरामीटर + // और पिछली माउस स्थिति + variableEllipse(mouseX, mouseY, pmouseX, pmouseY); +} + +// सरल विधि variableEllipse() विशेष रूप से बनाई गई थी +// इस कार्यक्रम के लिए। यह माउस की गति की गणना करता है +// और यदि माउस धीरे-धीरे आगे बढ़ रहा है तो एक छोटा दीर्घवृत्त खींचता है +// और यदि माउस तेजी से आगे बढ़ रहा है तो एक बड़ा दीर्घवृत्त खींचता है + +function variableEllipse(x, y, px, py) { + let speed = abs(x - px) + abs(y - py); + stroke(speed); + ellipse(x, y, speed, speed); +} diff --git a/dist/assets/examples/hi/17_Drawing/02_Pulses.js b/dist/assets/examples/hi/17_Drawing/02_Pulses.js new file mode 100644 index 0000000000..6ac965a816 --- /dev/null +++ b/dist/assets/examples/hi/17_Drawing/02_Pulses.js @@ -0,0 +1,31 @@ +/* + * @name दालें + * @description सॉफ्टवेयर ड्राइंग इंस्ट्रूमेंट्स एक लय का अनुसरण कर सकते हैं या इसका पालन कर सकते हैं + * खींचे गए इशारों से स्वतंत्र नियम। यह सहयोगी आरेखण का एक रूप है + * जिसमें ड्राफ्ट्सपर्सन इमेज और सॉफ्टवेयर के कुछ पहलुओं को नियंत्रित करता है + *दूसरों को नियंत्रित करता है। + */ +let angle = 0; + +function setup() { + createCanvas(710, 400); + background(102); + noStroke(); + fill(0, 102); +} + +function draw() { + // तभी ड्रा करें जब माउस दबाया जाए + if (mouseIsPressed === true) { + angle += 5; + let val = cos(radians(angle)) * 12.0; + for (let a = 0; a < 360; a += 75) { + let xoff = cos(radians(a)) * val; + let yoff = sin(radians(a)) * val; + fill(0); + ellipse(mouseX + xoff, mouseY + yoff, val, val); + } + fill(255); + ellipse(mouseX, mouseY, 2, 2); + } +} diff --git a/dist/assets/examples/hi/18_Transform/00_Translate.js b/dist/assets/examples/hi/18_Transform/00_Translate.js new file mode 100644 index 0000000000..4284790624 --- /dev/null +++ b/dist/assets/examples/hi/18_Transform/00_Translate.js @@ -0,0 +1,39 @@ +/* + * @name अनुवाद + * @description translate() फ़ंक्शन वस्तुओं को होने की अनुमति देता है + * खिड़की के भीतर किसी भी स्थान पर ले जाया गया। पहला पैरामीटर + * एक्स-अक्ष ऑफसेट सेट करता है और दूसरा पैरामीटर सेट करता है + * वाई-अक्ष ऑफसेट। यह उदाहरण दिखाता है कि परिवर्तन कैसे जमा होते हैं। + */ +let x = 0; +let y = 0; +let dim = 80.0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(102); + // Animate by increasing our x value + x = x + 0.8; + // If the shape goes off the canvas, reset the position + if (x > width + dim) { + x = -dim; + } + + // Even though our rect command draws the shape with its + // center at the origin, translate moves it to the new + // x and y position + translate(x, height / 2 - dim / 2); + fill(255); + rect(-dim / 2, -dim / 2, dim, dim); + + // Transforms accumulate. Notice how this rect moves + // twice as fast as the other, but it has the same + // parameter for the x-axis value + translate(x, dim); + fill(0); + rect(-dim / 2, -dim / 2, dim, dim); +} diff --git a/dist/assets/examples/hi/18_Transform/01_Scale.js b/dist/assets/examples/hi/18_Transform/01_Scale.js new file mode 100644 index 0000000000..57c1cf140f --- /dev/null +++ b/dist/assets/examples/hi/18_Transform/01_Scale.js @@ -0,0 +1,46 @@ +/* + * @name स्केल + * @description scale() फ़ंक्शन के लिए पैरामीटर मान हैं + * दशमलव प्रतिशत के रूप में निर्दिष्ट। उदाहरण के लिए, विधि + * कॉल स्केल (2.0) आकार के आयाम को बढ़ा देगा + * 200 प्रतिशत। वस्तुएं हमेशा मूल से मापी जाती हैं। यह उदाहरण + * दिखाता है कि परिवर्तन कैसे जमा होते हैं और यह भी कि कैसे पैमाने और अनुवाद and + * उनके आदेश के आधार पर बातचीत करें। + */ + +let a = 0.0; +let s = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + //Draw all rectangles from their center as opposed to + // the default upper left corner + rectMode(CENTER); +} + +function draw() { + background(102); + + //Slowly increase 'a' and then animate 's' with + //a smooth cyclical motion by finding the cosine of 'a' + a = a + 0.04; + s = cos(a) * 2; + + //Translate our rectangle from the origin to the middle of + //the canvas, then scale it with 's' + translate(width / 2, height / 2); + scale(s); + fill(51); + rect(0, 0, 50, 50); + + //Translate and scale are accumulating, so this translate + //moves the second rectangle further right than the first + //and the scale is getting doubled. Note that cosine is + //making 's' both negative and positive, thus it cycles + //from left to right. + translate(75, 0); + fill(255); + scale(s); + rect(0, 0, 50, 50); +} diff --git a/dist/assets/examples/hi/18_Transform/02_Rotate.js b/dist/assets/examples/hi/18_Transform/02_Rotate.js new file mode 100644 index 0000000000..eb91de39aa --- /dev/null +++ b/dist/assets/examples/hi/18_Transform/02_Rotate.js @@ -0,0 +1,43 @@ +/* + * @name घुमाएँ + * @description Z अक्ष के चारों ओर एक वर्ग को घुमाते हुए। + * अपेक्षित परिणाम प्राप्त करने के लिए, रोटेट फंक्शन एंगल भेजें + * पैरामीटर जो 0 और PI*2 के बीच के मान हैं (TWO_PI जो है + * मोटे तौर पर 6.28)। यदि आप कोणों को डिग्री के रूप में सोचना पसंद करते हैं + * (0-360), आप अपने मूल्यों को परिवर्तित करने के लिए radians() विधि का उपयोग कर सकते हैं। + * उदाहरण के लिए: घुमाएं (radians(90)) कथन के समान है + * घुमाएँ (पीआई / 2)। इस उदाहरण में, प्रत्येक सम संख्या वाला दूसरा एक जिटर + * रोटेशन में जोड़ा जाता है। विषम सेकंड के दौरान, घुमाव CW को गति देता है और + * सीसीडब्ल्यू अंतिम जिटर मूल्य द्वारा निर्धारित गति पर। + */ + +let angle = 0.0; +let jitter = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255); + // केंद्र से आयत बनाएं और यह भी होगा + // उस केंद्र के चारों ओर घुमाएं + rectMode(CENTER); +} + +function draw() { + background(51); + + // सम-संख्या वाले सेकंड (0, 2, 4, 6...) के दौरान घबराना जोड़ें + // रोटेशन + if (second() % 2 === 0) { + jitter = random(-0.1, 0.1); + } + // सबसे हालिया जिटर वैल्यू का उपयोग करके कोण मान बढ़ाएं + angle = angle + jitter; + // घबराहट न होने पर एक सहज CW और CCW गति प्राप्त करने के लिए कोसाइन का उपयोग करें + let c = cos(angle); + // आकार को कैनवास के केंद्र में ले जाएं + translate(width / 2, height / 2); + // अंतिम रोटेशन लागू करें + rotate(c); + rect(0, 0, 180, 180); +} diff --git a/dist/assets/examples/hi/18_Transform/03_Arm.js b/dist/assets/examples/hi/18_Transform/03_Arm.js new file mode 100644 index 0000000000..85278c6dfe --- /dev/null +++ b/dist/assets/examples/hi/18_Transform/03_Arm.js @@ -0,0 +1,49 @@ +/* + * @name आर्म + * @description यह उदाहरण बनाने के लिए ट्रांसफ़ॉर्म मैट्रिसेस का उपयोग करता है + * एक हाथ। प्रत्येक खंड के कोण को द्वारा नियंत्रित किया जाता है + * माउसएक्स और माउसवाई स्थिति। पर लागू किए गए परिवर्तन + * पहला खंड दूसरे खंड पर भी लागू होता है + * क्योंकि वे एक ही push() और . के अंदर हैं + * pop() मैट्रिक्स समूह। + */ + +let x, y; +let angle1 = 0.0; +let angle2 = 0.0; +let segLength = 100; + +function setup() { + createCanvas(720, 400); + strokeWeight(30); + + // अर्ध-पारदर्शी सफेद के साथ स्ट्रोक + stroke(255, 160); + + // हाथ के "कंधे" को कैनवास के केंद्र में रखें + x = width * 0.5; + y = height * 0.5; +} + +function draw() { + background(0); + + // माउस की स्थिति के अनुसार खंडों के कोण को बदलें + angle1 = (mouseX / float(width) - 0.5) * -TWO_PI; + angle2 = (mouseY / float(height) - 0.5) * PI; + + // ट्रांसफ़ॉर्म को "शामिल" करने के लिए पुश और पॉप का उपयोग करें। ध्यान दें कि + // भले ही हम एक कस्टम फ़ंक्शन का उपयोग करके सेगमेंट बनाते हैं, + // परिवर्तन अभी भी जमा होते हैं + push(); + segment(x, y, angle1); + segment(segLength, 0, angle2); + pop(); +} + +// सेगमेंट ड्राइंग के लिए एक कस्टम फ़ंक्शन +function segment(x, y, a) { + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); +} diff --git a/dist/assets/examples/hi/19_Typography/00_Letters.js b/dist/assets/examples/hi/19_Typography/00_Letters.js new file mode 100644 index 0000000000..4438894f30 --- /dev/null +++ b/dist/assets/examples/hi/19_Typography/00_Letters.js @@ -0,0 +1,64 @@ +/* + * @name पत्र + * @description पत्र एक फ़ॉन्ट लोड करके स्क्रीन पर खींचा जा सकता है, सेटिंग + * इसकी विशेषताएँ और फिर अक्षर खींचना। यह उदाहरण for . का उपयोग करता है + * कैनवास को स्वचालित रूप से भरने के लिए लूप और यूनिकोड संदर्भ संख्या + * एक ग्रिड में वर्ण। स्वरों का चयन किया जाता है और एक विशिष्ट भरण रंग दिया जाता है। + */ +let font, + fontsize = 32; + +function preload() { + // सुनिश्चित करें कि .ttf या .otf फ़ॉन्ट संपत्ति निर्देशिका में संग्रहीत है + // सेटअप से पहले लोड किया जाता है setup() और draw() कहा जाता है + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // टेक्स्ट विशेषताओं को सेट करें + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // अक्षरों और बाएँ और शीर्ष हाशिये के बीच की खाई को सेट करें + let gap = 52; + let margin = 10; + translate(margin * 4, margin * 4); + + // अपने इच्छित चरित्र पर शुरू करने के लिए काउंटर सेट करें + // इस मामले में 35, जो # प्रतीक . है + let counter = 35; + + // जब तक कैनवास पर जगह है तब तक लूप करें + for (let y = 0; y < height - gap; y += gap) { + for (let x = 0; x < width - gap; x += gap) { + // उनके यूनिकोड नंबर द्वारा अलग-अलग अक्षरों को पुनः प्राप्त करने के लिए काउंटर का उपयोग करें + let letter = char(counter); + + // स्वरों और अन्य वर्णों में अलग-अलग रंग जोड़ें + if ( + letter === 'A' || + letter === 'E' || + letter === 'I' || + letter === 'O' || + letter === 'U' + ) { + fill('#ed225d'); + } else { + fill(255); + } + + // पत्र को स्क्रीन पर ड्रा करें + text(letter, x, y); + + // काउंटर बढ़ाएँ + counter++; + } + } +} diff --git a/dist/assets/examples/hi/19_Typography/01_Words.js b/dist/assets/examples/hi/19_Typography/01_Words.js new file mode 100644 index 0000000000..df116b4f7e --- /dev/null +++ b/dist/assets/examples/hi/19_Typography/01_Words.js @@ -0,0 +1,59 @@ +/* + * @name शब्द + * @description text() फ़ंक्शन का उपयोग स्क्रीन पर शब्द लिखने के लिए किया जाता है। + * शब्दों को textAlign() के साथ बाएं, केंद्र या दाएं संरेखित किया जा सकता है + * फ़ंक्शन, और आकृतियों की तरह, शब्दों को fill() के साथ रंगा जा सकता है। + */ +let font, + fontsize = 40; + +function preload() { + // सुनिश्चित करें कि .ttf या .otf फ़ॉन्ट संपत्ति निर्देशिका में संग्रहीत है + // सेटअप से पहले लोड किया जाता है setup() और draw() कहा जाता है + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // टेक्स्ट विशेषताओं को सेट करें + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // टेक्स्ट को दाईं ओर संरेखित करें + // और कैनवास के बाएँ तीसरे भाग में drawWords () चलाएँ + textAlign(RIGHT); + drawWords(width * 0.25); + + // पाठ को केंद्र में संरेखित करें + // और कैनवास के बीच में drawWords() चलाएँ + textAlign(CENTER); + drawWords(width * 0.5); + + // टेक्स्ट को बाईं ओर संरेखित करें + // और कैनवास के दाहिने तीसरे भाग में drawWords () चलाएँ + textAlign(LEFT); + drawWords(width * 0.75); +} + +function drawWords(x) { + // text() फ़ंक्शन को तीन मापदंडों की आवश्यकता होती है: + // आकर्षित करने के लिए पाठ, क्षैतिज स्थिति, + // और ऊर्ध्वाधर स्थिति + fill(0); + text('ichi', x, 80); + + fill(65); + text('ni', x, 150); + + fill(190); + text('san', x, 220); + + fill(255); + text('shi', x, 290); +} diff --git a/dist/assets/examples/hi/20_3D/00_geometries.js b/dist/assets/examples/hi/20_3D/00_geometries.js new file mode 100644 index 0000000000..1bc949fbee --- /dev/null +++ b/dist/assets/examples/hi/20_3D/00_geometries.js @@ -0,0 +1,60 @@ +/* + * @name ज्यामिति + * @description अब p5 में छह 3D प्रिमिटिव हैं। + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + + translate(-240, -100, 0); + normalMaterial(); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + plane(70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + box(70, 70, 70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cylinder(70, 70); + pop(); + + translate(-240 * 2, 200, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cone(70, 70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + torus(70, 20); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + sphere(70); + pop(); +} diff --git a/dist/assets/examples/hi/20_3D/01_sine_cosine_in_3D.js b/dist/assets/examples/hi/20_3D/01_sine_cosine_in_3D.js new file mode 100644 index 0000000000..963c1f0040 --- /dev/null +++ b/dist/assets/examples/hi/20_3D/01_sine_cosine_in_3D.js @@ -0,0 +1,28 @@ +/* + * @name 3D में साइन कोसाइन + * @description साइन, कोसाइन और पुश/पॉप को 3D में भी लागू किया जा सकता है। + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + rotateY(frameCount * 0.01); + + for (let j = 0; j < 5; j++) { + push(); + for (let i = 0; i < 80; i++) { + translate( + sin(frameCount * 0.001 + j) * 100, + sin(frameCount * 0.001 + j) * 100, + i * 0.1 + ); + rotateZ(frameCount * 0.002); + push(); + sphere(8, 6, 4); + pop(); + } + pop(); + } +} diff --git a/dist/assets/examples/hi/20_3D/02_multiple_lights.js b/dist/assets/examples/hi/20_3D/02_multiple_lights.js new file mode 100644 index 0000000000..66bf5d45c5 --- /dev/null +++ b/dist/assets/examples/hi/20_3D/02_multiple_lights.js @@ -0,0 +1,30 @@ +/* + * @name मल्टीपल लाइट्स + * @description एक स्केच में सभी प्रकार की रोशनी का उपयोग किया जा सकता है। + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(50); + directionalLight(255, 0, 0, 0.25, 0.25, 0); + pointLight(0, 0, 255, locX, locY, 250); + + push(); + translate(-width / 4, 0, 0); + rotateZ(frameCount * 0.02); + rotateX(frameCount * 0.02); + specularMaterial(250); + box(100, 100, 100); + pop(); + + translate(width / 4, 0, 0); + ambientMaterial(250); + sphere(120, 64); +} diff --git a/dist/assets/examples/hi/20_3D/03_materials.js b/dist/assets/examples/hi/20_3D/03_materials.js new file mode 100644 index 0000000000..662d8d2cf2 --- /dev/null +++ b/dist/assets/examples/hi/20_3D/03_materials.js @@ -0,0 +1,65 @@ +/* + * @name सामग्री + * @description पांच प्रकार की सामग्री समर्थित हैं। + * वे प्रकाश के प्रति अलग तरह से प्रतिक्रिया करते हैं। + * प्रकाश की स्थिति बदलने के लिए अपने माउस को घुमाएँ। + */ +let img; +function setup() { + createCanvas(710, 400, WEBGL); + img = loadImage('assets/cat.jpg'); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(60, 60, 60); + pointLight(255, 255, 255, locX, locY, 100); + + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + texture(img); + box(80); + pop(); + + push(); + translate(-width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + fill(250, 0, 0); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + normalMaterial(); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(-width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + ambientMaterial(250); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + specularMaterial(250); + torus(80, 20, 64, 64); + pop(); +} diff --git a/dist/assets/examples/hi/20_3D/04_textures.js b/dist/assets/examples/hi/20_3D/04_textures.js new file mode 100644 index 0000000000..ea6d50b791 --- /dev/null +++ b/dist/assets/examples/hi/20_3D/04_textures.js @@ -0,0 +1,40 @@ +/* + * @name बनावट + * @description चित्र और वीडियो बनावट के लिए समर्थित हैं। + */ +// वीडियो स्रोत: https://vimeo.com/90312869 +let img; +let vid; +let theta = 0; + +function setup() { + createCanvas(710, 400, WEBGL); + + img = loadImage('assets/cat.jpg'); + vid = createVideo(['assets/360video_256crop_v2.mp4']); + vid.elt.muted = true; + vid.loop(); + vid.hide(); +} + +function draw() { + background(250); + translate(-220, 0, 0); + push(); + rotateZ(theta * mouseX * 0.001); + rotateX(theta * mouseX * 0.001); + rotateY(theta * mouseX * 0.001); + //pass image as texture + texture(vid); + sphere(150); + pop(); + translate(440, 0, 0); + push(); + rotateZ(theta * 0.1); + rotateX(theta * 0.1); + rotateY(theta * 0.1); + texture(img); + box(100, 100, 100); + pop(); + theta += 0.05; +} diff --git a/dist/assets/examples/hi/20_3D/05_ray_casting.js b/dist/assets/examples/hi/20_3D/05_ray_casting.js new file mode 100644 index 0000000000..1d1e6e5c66 --- /dev/null +++ b/dist/assets/examples/hi/20_3D/05_ray_casting.js @@ -0,0 +1,100 @@ +/* + * @name रे कास्टिंग + * @description जोनाथन वाटसन द्वारा मूल उदाहरण। + *

रे कास्टिंग के साथ 3डी स्पेस में माउस की स्थिति का पता लगाना। + */ +const objects = []; +let eyeZ; + +function setup() { + createCanvas(710, 400, WEBGL); + + eyeZ = height / 2 / tan((30 * PI) / 180); // डिफ़ॉल्ट दूरी कैमरा मूल से दूर है। + + objects.push(new IntersectPlane(1, 0, 0, -100, 0, 0)); // बाईं दीवार + objects.push(new IntersectPlane(1, 0, 0, 100, 0, 0)); // दाहिनी दीवार + objects.push(new IntersectPlane(0, 1, 0, 0, -100, 0)); // नीचे की दीवार + objects.push(new IntersectPlane(0, 1, 0, 0, 100, 0)); // शीर्ष दीवार + objects.push(new IntersectPlane(0, 0, 1, 0, 0, 0)); // पीछे की दीवार + + noStroke(); + ambientMaterial(250); +} + +function draw() { + background(0); + + // रोशनी + pointLight(255, 255, 255, 0, 0, 400); + ambientLight(244, 122, 158); + + // बाईं दीवार + push(); + translate(-100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // दाहिनी दीवार + push(); + translate(100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // नीचे की दीवार + push(); + translate(0, 100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + // शीर्ष दीवार + push(); + translate(0, -100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + plane(200, 200); // पीछे की दीवार + + const x = mouseX - width / 2; + const y = mouseY - height / 2; + + const Q = createVector(0, 0, eyeZ); // किरण पर एक बिंदु और कैमरे की डिफ़ॉल्ट स्थिति। + const v = createVector(x, y, -eyeZ); // किरण की दिशा वेक्टर। + + let intersect; // किरण और समतल के बीच का प्रतिच्छेदन बिंदु। + let closestLambda = eyeZ * 10; // ड्रा दूरी। + + for (let x = 0; x < objects.length; x += 1) { + let object = objects[x]; + let lambda = object.getLambda(Q, v); // लैम्ब्डा का मान जहां किरण वस्तु को काटती है + + if (lambda < closestLambda && lambda > 0) { + // किरण और वस्तु के प्रतिच्छेदन की स्थिति का पता लगाएं। + intersect = p5.Vector.add(Q, p5.Vector.mult(v, lambda)); + closestLambda = lambda; + } + } + + // कर्सर + push(); + translate(intersect); + fill(237, 34, 93); + sphere(10); + pop(); +} + +// एक विमान के लिए कक्षा जो अनंत तक फैली हुई है। +class IntersectPlane { + constructor(n1, n2, n3, p1, p2, p3) { + this.normal = createVector(n1, n2, n3); // विमान का सामान्य वेक्टर + this.point = createVector(p1, p2, p3); // विमान पर एक बिंदु + this.d = this.point.dot(this.normal); + } + + getLambda(Q, v) { + return (-this.d - this.normal.dot(Q)) / this.normal.dot(v); + } +} diff --git a/dist/assets/examples/hi/20_3D/07_orbit_control.js b/dist/assets/examples/hi/20_3D/07_orbit_control.js new file mode 100644 index 0000000000..e68b4b8efe --- /dev/null +++ b/dist/assets/examples/hi/20_3D/07_orbit_control.js @@ -0,0 +1,36 @@ +/* + * @name कक्षा नियंत्रण + * @description कक्षा नियंत्रण आपको दुनिया भर में खींचने और स्थानांतरित करने की अनुमति देता है। + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + let radius = width * 1.5; + + // दुनिया को स्थानांतरित करने के लिए खींचें। + orbitControl(); + + normalMaterial(); + translate(0, 0, -600); + for (let i = 0; i <= 12; i++) { + for (let j = 0; j <= 12; j++) { + push(); + let a = (j / 12) * PI; + let b = (i / 12) * PI; + translate( + sin(2 * a) * radius * sin(b), + (cos(b) * radius) / 2, + cos(2 * a) * radius * sin(b) + ); + if (j % 2 === 0) { + cone(30, 30); + } else { + box(30, 30, 30); + } + pop(); + } + } +} diff --git a/dist/assets/examples/hi/20_3D/08_basic_shader.js b/dist/assets/examples/hi/20_3D/08_basic_shader.js new file mode 100644 index 0000000000..b9dbbb6d6f --- /dev/null +++ b/dist/assets/examples/hi/20_3D/08_basic_shader.js @@ -0,0 +1,27 @@ +/* + * @name बेसिक शेडर + * @description यह एक बुनियादी उदाहरण है जिसमें दिखाया गया है कि p5.js में शेडर्स को कैसे लोड किया जाए। + *
p5.js में शेडर्स का उपयोग करने के बारे में अधिक जानने के लिए: p5.js Shaders + */ + +// यह वेरिएबल हमारे शेडर ऑब्जेक्ट को होल्ड करेगा +let theShader; + +function preload(){ + // शेडर लोड करें + theShader = loadShader('assets/basic.vert', 'assets/basic.frag'); +} + +function setup() { + // शेडर्स को काम करने के लिए WEBGL मोड की आवश्यकता होती है + createCanvas(710, 400, WEBGL); + noStroke(); +} + +function draw() { + // shader() हमारे शेडर के साथ सक्रिय शेडर सेट करता है + shader(theShader); + + // रेक्ट हमें स्क्रीन पर कुछ ज्योमेट्री देता है + rect(0,0,width, height); +} diff --git a/dist/assets/examples/hi/20_3D/09_shader_as_a_texture.js b/dist/assets/examples/hi/20_3D/09_shader_as_a_texture.js new file mode 100644 index 0000000000..0c10b5e341 --- /dev/null +++ b/dist/assets/examples/hi/20_3D/09_shader_as_a_texture.js @@ -0,0 +1,68 @@ +/* + * @name शेडर एक बनावट के रूप में + * @description Shaders को बनावट के रूप में 2D/3D आकृतियों पर लागू किया जा सकता है। + *
p5.js में शेडर्स का उपयोग करने के बारे में अधिक जानने के लिए: p5.js Shaders + */ + + // यह वेरिएबल हमारे शेडर ऑब्जेक्ट को होल्ड करेगा + let theShader; + // यह वेरिएबल हमारी createGraphics लेयर को होल्ड करेगा + let shaderTexture; + + let theta = 0; + + let x; + let y; + let outsideRadius = 200; + let insideRadius = 100; + + function preload(){ + // शेडर लोड करें + theShader = loadShader('assets/texture.vert','assets/texture.frag'); + } + + function setup() { + // शेडर्स को काम करने के लिए WEBGL मोड की आवश्यकता होती है + createCanvas(710, 400, WEBGL); + noStroke(); + + // createGraphics लेयर्स को इनिशियलाइज़ करें + shaderTexture = createGraphics(710, 400, WEBGL); + + // createGraphics लेयर्स स्ट्रोक को बंद करें + shaderTexture.noStroke(); + + x = -50; + y = 0; + } + + function draw() { + + // केवल सक्रिय शेडर को सेट करने के बजाय हम इसे createGraphics लेयर में पास कर रहे हैं + shaderTexture.shader(theShader); + + // यहां हम अपने समान मूल्यों को शेडर में भेजने के लिए setUniform () का उपयोग कर रहे हैं + theShader.setUniform("resolution", [width, height]); + theShader.setUniform("time", millis() / 1000.0); + theShader.setUniform("mouse", [mouseX, map(mouseY, 0, height, height, 0)]); + + // रेंडर करने के लिए shaderTexture लेयर ज्योमेट्री पास करना + shaderTexture.rect(0,0,width,height); + + background(255); + + // शेडर को एक बनावट के रूप में पास करें + texture(shaderTexture); + + translate(-150, 0, 0); + push(); + rotateZ(theta * mouseX * 0.0001); + rotateX(theta * mouseX * 0.0001); + rotateY(theta * mouseX * 0.0001); + theta += 0.05; + sphere(125); + pop(); + + // 3D में चिकने किनारों के लिए दीर्घवृत्त के लिए पाँचवाँ पैरामीटर पास करना + ellipse(260,0,200,200,100); + } diff --git a/dist/assets/examples/hi/20_3D/10_passing_shader_uniforms.js b/dist/assets/examples/hi/20_3D/10_passing_shader_uniforms.js new file mode 100644 index 0000000000..24275c1322 --- /dev/null +++ b/dist/assets/examples/hi/20_3D/10_passing_shader_uniforms.js @@ -0,0 +1,33 @@ +/* + * @name पासिंग शेडर यूनिफॉर्म + * @description यूनिफ़ॉर्म वह तरीका है जिससे जानकारी को p5 से शेडर तक पहुँचाया जाता है। + *
p5.js में शेडर्स का उपयोग करने के बारे में अधिक जानने के लिए: p5.js Shaders + */ + + // यह वेरिएबल हमारे शेडर ऑब्जेक्ट को होल्ड करेगा + let theShader; + + function preload(){ + // शेडर लोड करें + theShader = loadShader('assets/uniforms.vert', 'assets/uniforms.frag'); + } + + function setup() { + // शेडर्स को काम करने के लिए WEBGL मोड की आवश्यकता होती है + createCanvas(710, 400, WEBGL); + noStroke(); + } + + function draw() { + // शेडर () हमारे शेडर के साथ सक्रिय शेडर सेट करता है + shader(theShader); + + // हमारे शेडर को रिज़ॉल्यूशन, माउस और समय भेजें + // माउस + समय भेजने से पहले हम डेटा को संशोधित करते हैं ताकि यह शेडर द्वारा अधिक आसानी से उपयोग किया जा सके + theShader.setUniform('resolution', [width, height]); + theShader.setUniform('mouse', map(mouseX, 0, width, 0, 7)); + theShader.setUniform('time', frameCount * 0.01); + + // रेक्ट हमें स्क्रीन पर कुछ ज्योमेट्री देता है + rect(0,0,width, height); + } diff --git a/dist/assets/examples/hi/20_3D/11_shader_using_webcam.js b/dist/assets/examples/hi/20_3D/11_shader_using_webcam.js new file mode 100644 index 0000000000..09de5a744b --- /dev/null +++ b/dist/assets/examples/hi/20_3D/11_shader_using_webcam.js @@ -0,0 +1,37 @@ +/* + * @name Shader वेबकैम का उपयोग कर रहा है + * @description वेबकैम को टेक्सचर के रूप में शेडर्स को पास किया जा सकता है। + *
p5.js में शेडर्स का उपयोग करने के बारे में अधिक जानने के लिए: p5.js Shaders + */ + + // यह वेरिएबल हमारे शेडर ऑब्जेक्ट को होल्ड करेगा + let theShader; + // यह वेरिएबल हमारे वेबकैम वीडियो को होल्ड करेगा + let cam; + + function preload(){ + // शेडर लोड करें + theShader = loadShader('assets/webcam.vert', 'assets/webcam.frag'); + } + + function setup() { + // शेडर्स को काम करने के लिए WEBGL मोड की आवश्यकता होती है + createCanvas(710, 400, WEBGL); + noStroke(); + + cam = createCapture(VIDEO); + cam.size(710, 400); + + cam.hide(); + } + + function draw() { + // shader() हमारे शेडर के साथ सक्रिय शेडर सेट करता है + shader(theShader); + + // एक बनावट के रूप में कैम पास करना + theShader.setUniform('tex0', cam); + + // रेक्ट हमें स्क्रीन पर कुछ ज्योमेट्री देता है + rect(0,0,width,height); + } diff --git a/dist/assets/examples/hi/21_Input/00_Clock.js b/dist/assets/examples/hi/21_Input/00_Clock.js new file mode 100644 index 0000000000..b5bbb269b0 --- /dev/null +++ b/dist/assets/examples/hi/21_Input/00_Clock.js @@ -0,0 +1,62 @@ +/* + * @name घड़ी + * @description वर्तमान समय को second() के साथ पढ़ा जा सकता है, + * minute(), और hour() फ़ंक्शन। इस उदाहरण में, sin() और + * cos () मानों का उपयोग हाथों की स्थिति निर्धारित करने के लिए किया जाता है। + */ +let cx, cy; +let secondsRadius; +let minutesRadius; +let hoursRadius; +let clockDiameter; + +function setup() { + createCanvas(720, 400); + stroke(255); + + let radius = min(width, height) / 2; + secondsRadius = radius * 0.71; + minutesRadius = radius * 0.6; + hoursRadius = radius * 0.5; + clockDiameter = radius * 1.7; + + cx = width / 2; + cy = height / 2; +} + +function draw() { + background(230); + + // घड़ी की पृष्ठभूमि बनाएं + noStroke(); + fill(244, 122, 158); + ellipse(cx, cy, clockDiameter + 25, clockDiameter + 25); + fill(237, 34, 93); + ellipse(cx, cy, clockDiameter, clockDiameter); + + // पाप के sin() और cos() 3 बजे शुरू होते हैं; + // शीर्ष पर प्रारंभ करने के लिए HALF_PI घटाएं + let s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI; + let m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; + let h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI; + + // घड़ी की सुई खींचे + stroke(255); + strokeWeight(1); + line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius); + strokeWeight(2); + line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius); + strokeWeight(4); + line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius); + + // मिनट टिक ड्रा करें + strokeWeight(2); + beginShape(POINTS); + for (let a = 0; a < 360; a += 6) { + let angle = radians(a); + let x = cx + cos(angle) * secondsRadius; + let y = cy + sin(angle) * secondsRadius; + vertex(x, y); + } + endShape(); +} diff --git a/dist/assets/examples/hi/21_Input/01_Constrain.js b/dist/assets/examples/hi/21_Input/01_Constrain.js new file mode 100644 index 0000000000..1ce4a66b38 --- /dev/null +++ b/dist/assets/examples/hi/21_Input/01_Constrain.js @@ -0,0 +1,36 @@ +/* + * @name बाधा + * @description माउस को स्क्रीन पर घुमाने के लिए ले जाएँ + * वृत्त। कार्यक्रम सर्कल को उसके बॉक्स में सीमित करता है। + */ +let mx = 1; +let my = 1; +let easing = 0.05; +let radius = 24; +let edge = 100; +let inner = edge + radius; + +function setup() { + createCanvas(720, 400); + noStroke(); + ellipseMode(RADIUS); + rectMode(CORNERS); +} + +function draw() { + background(230); + + if (abs(mouseX - mx) > 0.1) { + mx = mx + (mouseX - mx) * easing; + } + if (abs(mouseY - my) > 0.1) { + my = my + (mouseY - my) * easing; + } + + mx = constrain(mx, inner, width - inner); + my = constrain(my, inner, height - inner); + fill(237, 34, 93); + rect(edge, edge, width - edge, height - edge); + fill(255); + ellipse(mx, my, radius, radius); +} diff --git a/dist/assets/examples/hi/21_Input/02_Easing.js b/dist/assets/examples/hi/21_Input/02_Easing.js new file mode 100644 index 0000000000..ca7ced8dd5 --- /dev/null +++ b/dist/assets/examples/hi/21_Input/02_Easing.js @@ -0,0 +1,30 @@ +/* + * @name आसान + * @description माउस को स्क्रीन और सिंबल पर ले जाएं + * का पालन करेंगे। एनीमेशन के प्रत्येक फ्रेम को खींचने के बीच, + * कार्यक्रम की स्थिति के बीच अंतर की गणना करता है + * प्रतीक और कर्सर। यदि दूरी 1 पिक्सेल से बड़ी है, + * प्रतीक अपनी धारा से कुछ दूरी (0.05) को आगे बढ़ाता है + * कर्सर की ओर स्थिति। + */ +let x = 1; +let y = 1; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(237, 34, 93); + let targetX = mouseX; + let dx = targetX - x; + x += dx * easing; + + let targetY = mouseY; + let dy = targetY - y; + y += dy * easing; + + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/hi/21_Input/03_Keyboard.js b/dist/assets/examples/hi/21_Input/03_Keyboard.js new file mode 100644 index 0000000000..5309d3e81e --- /dev/null +++ b/dist/assets/examples/hi/21_Input/03_Keyboard.js @@ -0,0 +1,38 @@ +/* + * @name कीबोर्ड + * @description इमेज को फोकस करने के लिए उस पर क्लिक करें और + * समय और स्थान में फ़ॉर्म बनाने के लिए अक्षर कुंजियाँ दबाएँ। + * प्रत्येक कुंजी की एक विशिष्ट पहचान संख्या होती है। ये नंबर + * अंतरिक्ष में आकृतियों की स्थिति के लिए इस्तेमाल किया जा सकता है। + */ +let rectWidth; + +function setup() { + createCanvas(720, 400); + noStroke(); + background(230); + rectWidth = width / 4; +} + +function draw() { + // चाबियों की प्रतीक्षा करते हुए लूपिंग जारी रखने के लिए यहां draw() रखें +} + +function keyPressed() { + let keyIndex = -1; + if (key >= 'a' && key <= 'z') { + keyIndex = key.charCodeAt(0) - 'a'.charCodeAt(0); + } + if (keyIndex === -1) { + // यदि यह एक अक्षर कुंजी नहीं है, तो स्क्रीन को साफ़ करें + background(230); + } else { + // यह एक अक्षर कुंजी है, एक आयत भरें + randFill_r = Math.floor(Math.random() * 255 + 1); + randFill_g = Math.floor(Math.random() * 255 + 1); + randFill_b = Math.floor(Math.random() * 255 + 1); + fill(randFill_r, randFill_g, randFill_b); + let x = map(keyIndex, 0, 25, 0, width - rectWidth); + rect(x, 0, rectWidth, height); + } +} diff --git a/dist/assets/examples/hi/21_Input/04_Mouse1D.js b/dist/assets/examples/hi/21_Input/04_Mouse1D.js new file mode 100644 index 0000000000..6471fcf6ec --- /dev/null +++ b/dist/assets/examples/hi/21_Input/04_Mouse1D.js @@ -0,0 +1,24 @@ +/* + * @name माउस 1D + * @description माउस को बाएँ और दाएँ ले जाएँ + * संतुलन शिफ्ट करें। "माउसएक्स" चर का उपयोग किया जाता है + * आयतों के आकार और रंग दोनों को नियंत्रित करने के लिए। + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + + let r1 = map(mouseX, 0, width, 0, height); + let r2 = height - r1; + + fill(237, 34, 93, r1); + rect(width / 2 + r1 / 2, height / 2, r1, r1); + + fill(237, 34, 93, r2); + rect(width / 2 - r2 / 2, height / 2, r2, r2); +} diff --git a/dist/assets/examples/hi/21_Input/05_Mouse2D.js b/dist/assets/examples/hi/21_Input/05_Mouse2D.js new file mode 100644 index 0000000000..16d0eea4ec --- /dev/null +++ b/dist/assets/examples/hi/21_Input/05_Mouse2D.js @@ -0,0 +1,20 @@ +/* + * @name माउस 2D + * @description माउस को हिलाने से स्थिति बदल जाती है और + * प्रत्येक बॉक्स का आकार। + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + fill(244, 122, 158); + rect(mouseX, height / 2, mouseY / 2 + 10, mouseY / 2 + 10); + fill(237, 34, 93); + let inverseX = width - mouseX; + let inverseY = height - mouseY; + rect(inverseX, height / 2, inverseY / 2 + 10, inverseY / 2 + 10); +} diff --git a/dist/assets/examples/hi/21_Input/06_MouseIsPressed.js b/dist/assets/examples/hi/21_Input/06_MouseIsPressed.js new file mode 100644 index 0000000000..0a780f3f2a --- /dev/null +++ b/dist/assets/examples/hi/21_Input/06_MouseIsPressed.js @@ -0,0 +1,20 @@ +/* + * @name माउस प्रेस + * @description माउस को शेप में लाने के लिए मूव करें। + * रंग बदलने के लिए माउस बटन दबाएं। + */ +function setup() { + createCanvas(720, 400); + background(230); + strokeWeight(2); +} + +function draw() { + if (mouseIsPressed) { + stroke(255); + } else { + stroke(237, 34, 93); + } + line(mouseX - 66, mouseY, mouseX + 66, mouseY); + line(mouseX, mouseY - 66, mouseX, mouseY + 66); +} diff --git a/dist/assets/examples/hi/21_Input/07_Mouse_Functions.js b/dist/assets/examples/hi/21_Input/07_Mouse_Functions.js new file mode 100644 index 0000000000..bb9a876331 --- /dev/null +++ b/dist/assets/examples/hi/21_Input/07_Mouse_Functions.js @@ -0,0 +1,66 @@ +/* + * @name माउस फंक्शन्स + * @description बॉक्स पर क्लिक करें और इसे स्क्रीन पर खींचें। + */ +let bx; +let by; +let boxSize = 75; +let overBox = false; +let locked = false; +let xOffset = 0.0; +let yOffset = 0.0; + +function setup() { + createCanvas(720, 400); + bx = width / 2.0; + by = height / 2.0; + rectMode(RADIUS); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + // परीक्षण करें कि क्या कर्सर बॉक्स के ऊपर है + if ( + mouseX > bx - boxSize && + mouseX < bx + boxSize && + mouseY > by - boxSize && + mouseY < by + boxSize + ) { + overBox = true; + if (!locked) { + stroke(255); + fill(244, 122, 158); + } + } else { + stroke(156, 39, 176); + fill(244, 122, 158); + overBox = false; + } + + // बॉक्स को ड्रा करें + rect(bx, by, boxSize, boxSize); +} + +function mousePressed() { + if (overBox) { + locked = true; + fill(255, 255, 255); + } else { + locked = false; + } + xOffset = mouseX - bx; + yOffset = mouseY - by; +} + +function mouseDragged() { + if (locked) { + bx = mouseX - xOffset; + by = mouseY - yOffset; + } +} + +function mouseReleased() { + locked = false; +} diff --git a/dist/assets/examples/hi/21_Input/08_Mouse_Signals.js b/dist/assets/examples/hi/21_Input/08_Mouse_Signals.js new file mode 100644 index 0000000000..858640b4ec --- /dev/null +++ b/dist/assets/examples/hi/21_Input/08_Mouse_Signals.js @@ -0,0 +1,52 @@ +/* + * @name माउस सिग्नल + * @description सिग्नल जेनरेट करने के लिए माउस को मूव करें और क्लिक करें। + * शीर्ष पंक्ति "माउसएक्स" से संकेत है, मध्य पंक्ति है + * "माउसवाई" से संकेत, और नीचे की पंक्ति संकेत है + * "mouseIsPressed" से। + */ +let xvals = []; +let yvals = []; +let bvals = []; + +function setup() { + createCanvas(720, 400); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + for (let i = 1; i < width; i++) { + xvals[i - 1] = xvals[i]; + yvals[i - 1] = yvals[i]; + bvals[i - 1] = bvals[i]; + } + // सरणी के अंत में नए मान जोड़ें + xvals[width - 1] = mouseX; + yvals[width - 1] = mouseY; + + if (mouseIsPressed) { + bvals[width - 1] = 0; + } else { + bvals[width - 1] = 255; + } + + fill(255); + noStroke(); + rect(0, height / 3, width, height / 3 + 1); + + for (let i = 1; i < width; i++) { + stroke(255); + point(i, xvals[i] / 3); + stroke(0); + point(i, height / 3 + yvals[i] / 3); + stroke(255); + line( + i, + (2 * height) / 3 + bvals[i] / 3, + i, + (2 * height) / 3 + bvals[i - 1] / 3 + ); + } +} diff --git a/dist/assets/examples/hi/21_Input/09_Storing_Input.js b/dist/assets/examples/hi/21_Input/09_Storing_Input.js new file mode 100644 index 0000000000..aca6bafec1 --- /dev/null +++ b/dist/assets/examples/hi/21_Input/09_Storing_Input.js @@ -0,0 +1,38 @@ +/* + * @name भंडारण इनपुट + * @description माउस को स्क्रीन पर ले जाएँ + * मंडलियों की स्थिति बदलें। पदों + * माउस को एक ऐरे में रिकॉर्ड किया जाता है और खेला जाता है + * हर फ्रेम वापस। प्रत्येक फ्रेम के बीच, नवीनतम + * मान प्रत्येक सरणी के अंत में जोड़ा जाता है और + * सबसे पुराना मान हटा दिया गया है। + */ +let num = 60; +let mx = []; +let my = []; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255, 153); + for (let i = 0; i < num; i++) { + mx.push(i); + my.push(i); + } +} + +function draw() { + background(237, 34, 93); + + // प्रत्येक फ्रेम पर एक अलग प्रविष्टि का उपयोग करके, सरणी के माध्यम से साइकिल चलाएं। + // इस तरह से मोडुलो (%) का उपयोग करना सभी मूल्यों को खत्म करने की तुलना में तेज़ है। + let which = frameCount % num; + mx[which] = mouseX; + my[which] = mouseY; + + for (let i = 0; i < num; i++) { + // कौन सा+1 सबसे छोटा है (सरणी में सबसे पुराना) + let index = (which + 1 + i) % num; + ellipse(mx[index], my[index], i, i); + } +} diff --git a/dist/assets/examples/hi/22_Advanced_Data/00_Load_Saved_JSON.js b/dist/assets/examples/hi/22_Advanced_Data/00_Load_Saved_JSON.js new file mode 100644 index 0000000000..7a260da550 --- /dev/null +++ b/dist/assets/examples/hi/22_Advanced_Data/00_Load_Saved_JSON.js @@ -0,0 +1,104 @@ +/* + * @name लोड सेव किया गया JSON + * @description बबल क्लास बनाएं, डेटा का उपयोग करके कई बबल को इंस्टेंट करें + * एक JSON फ़ाइल, और स्क्रीन पर परिणाम प्रदर्शित करें। + * क्योंकि वेब ब्राउजर फाइलों को सेव करने में भिन्न होते हैं, हम इसका उपयोग नहीं करते हैं + * saveJSON, प्रोसेसिंग उदाहरण के विपरीत।

+ * प्रोसेसिंग के लिए डेनियल शिफमैन के LoadSaveJSON उदाहरण पर आधारित। + */ + +// बबल क्लास +class Bubble { + constructor(x, y, diameter, name) { + this.x = x; + this.y = y; + this.diameter = diameter; + this.radius = diameter / 2; + this.name = name; + + this.over = false; + } + + // जांचें कि क्या माउस बुलबुले के ऊपर है + rollover(px, py) { + let d = dist(px, py, this.x, this.y); + this.over = d < this.radius; + } + + // बबल प्रदर्शित करें + display() { + stroke(0); + strokeWeight(0.8); + noFill(); + ellipse(this.x, this.y, this.diameter, this.diameter); + if (this.over) { + fill(0); + textAlign(CENTER); + text(this.name, this.x, this.y + this.radius + 20); + } + } +} + +let data = {}; // loadJSON कॉल से परिणाम धारण करने के लिए वैश्विक वस्तु +let bubbles = []; // सभी बबल ऑब्जेक्ट्स को होल्ड करने के लिए ग्लोबल ऐरे + +// "सेटअप" चलाने से पहले किसी भी एसिंक्रोनस डेटा लोडिंग को प्रीलोड में रखें +function preload() { + data = loadJSON('assets/bubbles.json'); +} + +// सहेजे गए बबल डेटा को बबल ऑब्जेक्ट में बदलें +function loadData() { + let bubbleData = data['bubbles']; + for (let i = 0; i < bubbleData.length; i++) { + // प्रत्येक वस्तु को सरणी में प्राप्त करें + let bubble = bubbleData[i]; + // एक स्थिति वस्तु प्राप्त करें + let position = bubble['position']; + // स्थिति से x, y प्राप्त करें + let x = position['x']; + let y = position['y']; + + // व्यास और लेबल प्राप्त करें + let diameter = bubble['diameter']; + let label = bubble['label']; + + // ऑब्जेक्ट को सरणी में रखें + bubbles.push(new Bubble(x, y, diameter, label)); + } +} + +// हर बार माउस क्लिक करने पर एक नया बबल बनाएं। +function mousePressed() { + // बबल में व्यास और लेबल जोड़ें + let diameter = random(40, 80); + let label = 'New Label'; + + // नई JSON बबल ऑब्जेक्ट को सरणी में जोड़ें + bubbles.push(new Bubble(mouseX, mouseY, diameter, label)); + + // यदि बहुत अधिक हैं तो बबल काउंट प्रून करें + if (bubbles.length > 10) { + bubbles.shift(); // सरणी से पहले आइटम को हटा दें + } +} + +function setup() { + createCanvas(640, 360); + loadData(); +} + +function draw() { + background(255); + + // सभी बुलबुले प्रदर्शित करें + for (let i = 0; i < bubbles.length; i++) { + bubbles[i].display(); + bubbles[i].rollover(mouseX, mouseY); + } + + // नीचे की ओर लेबल निर्देश + textAlign(LEFT); + fill(0); + text('Click to add bubbles.', 10, height - 10); +} diff --git a/dist/assets/examples/hi/33_Sound/00_Load_and_Play_Sound.js b/dist/assets/examples/hi/33_Sound/00_Load_and_Play_Sound.js new file mode 100644 index 0000000000..28f63363dc --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/00_Load_and_Play_Sound.js @@ -0,0 +1,25 @@ +/* + * @name लोड और प्ले साउंड + * @description प्रीलोड के दौरान ध्वनि लोड करें ()। कैनवास पर क्लिक करने पर ध्वनि बजाएं। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर + */ +let song; + +function setup() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); + createCanvas(720, 200); + background(255, 0, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying () एक बूलियन लौटाता है + song.stop(); + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/hi/33_Sound/01_Preload_Sound.js b/dist/assets/examples/hi/33_Sound/01_Preload_Sound.js new file mode 100644 index 0000000000..55e1af05c2 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/01_Preload_Sound.js @@ -0,0 +1,34 @@ +/* + * @name प्रीलोड साउंडफाइल + * @description loadsound() के दौरान preload() कॉल करें यह सुनिश्चित करने के लिए कि + * setup() कहे जाने से पहले ध्वनि पूरी तरह से भरी हुई है। यह हमेशा के लिए सबसे अच्छा है + * preload() में loadsound() को कॉल करें, अन्यथा ध्वनियों को लोड करने की आवश्यकता नहीं होगी + * जब तक आप उन्हें अपने स्केच में खेलना चाहें। + * + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर + */ + +let song; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); // गाना सेटअप के दौरान चलने के लिए तैयार है () क्योंकि यह प्रीलोड के दौरान लोड किया गया था + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying () एक बूलियन लौटाता है + song.pause(); // .play() .pause() स्थिति से फिर से शुरू होगा + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/hi/33_Sound/02_soundFormats.js b/dist/assets/examples/hi/33_Sound/02_soundFormats.js new file mode 100644 index 0000000000..2af9a6bebe --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/02_soundFormats.js @@ -0,0 +1,54 @@ +/** + * @name ध्वनि प्रारूप + * @description

तकनीकी रूप से, पेटेंट मुद्दों के कारण, कोई एकल नहीं है + * ध्वनि प्रारूप जो सभी वेब ब्राउज़र द्वारा समर्थित है। जबकि + * mp3 समर्थित है पर + * OS X और Windows पर प्रमुख ब्राउज़रों के नवीनतम संस्करण, उदाहरण के लिए, + * यह कुछ कम मुख्यधारा के ऑपरेटिंग सिस्टम पर उपलब्ध नहीं हो सकता है और + * ब्राउज़र।

+ * + *

पूर्ण संगतता सुनिश्चित करने के लिए, आप समान ध्वनि फ़ाइल शामिल कर सकते हैं + * कई स्वरूपों में, उदा। 'sound.mp3' और 'sound.ogg'। (ओग एक है + * एमपी3 का ओपन सोर्स विकल्प।) आप ऑडियो फाइलों को कन्वर्ट कर सकते हैं + * वेब अनुकूल प्रारूपों में media.io

। + * + *

soundformats() विधि लोडसाउंड को बताती है कि कौन से प्रारूप हैं + * हमने अपने स्केच के साथ शामिल किया है। फिर, लोडसाउंड होगा + * द्वारा समर्थित पहले प्रारूप को लोड करने का प्रयास + * क्लाइंट का वेब ब्राउज़र।

+ * + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर< /पी> + */ +let song; + +function preload() { + // we have included both an .ogg file and an .mp3 file + soundFormats('ogg', 'mp3'); + + // if mp3 is not supported by this browser, + // loadSound will load the ogg file + // we have included with our sketch + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + + // song loaded during preload(), ready to play in setup() + song.play(); + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() returns a boolean + song.pause(); + background(255, 0, 0); + } else { + song.play(); // playback will resume from the pause position + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/hi/33_Sound/03_Play_Mode.js b/dist/assets/examples/hi/33_Sound/03_Play_Mode.js new file mode 100644 index 0000000000..443b324633 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/03_Play_Mode.js @@ -0,0 +1,42 @@ +/* + * @name प्ले मोड + * @description + *

'सस्टेनेबल' मोड में, ध्वनि अपने आप ओवरलैप हो जाएगी। + * 'पुनरारंभ' मोड में यह रुक जाएगा और फिर से शुरू होगा। + * ध्वनि फ़ाइल चलाने के लिए माउस क्लिक करें। + * एक बार में बहुत सारी आवाज़ें ट्रिगर करें! प्लेमोड बदलने के लिए कोई भी कुंजी दबाएं।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर< /पी> + */ +let playMode = 'sustain'; +let sample; + +function setup() { + createCanvas(710, 50); + soundFormats('mp3', 'ogg'); + sample = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3'); +} + +function draw() { + background(255, 255, 0); + let str = 'Click here to play! Press key to toggle play mode.'; + str += ' Current Play Mode: ' + playMode + '.'; + text(str, 10, height / 2); +} + +function mouseClicked() { + sample.play(); +} +function keyPressed(k) { + togglePlayMode(); +} + +function togglePlayMode() { + if (playMode === 'sustain') { + playMode = 'restart'; + } else { + playMode = 'sustain'; + } + sample.playMode(playMode); +} diff --git a/dist/assets/examples/hi/33_Sound/04_Pan_SoundFile.js b/dist/assets/examples/hi/33_Sound/04_Pan_SoundFile.js new file mode 100644 index 0000000000..3751f0fd68 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/04_Pan_SoundFile.js @@ -0,0 +1,34 @@ +/* + * @name पैन साउंड + * @description

ध्वनि चलाने के लिए माउस क्लिक करें। + * गेंद की स्थिति माउस का अनुसरण करती है और ध्वनि की पैनिंग से संबंधित होती है।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर< /पी> + * + */ +let ball = {}; +let soundFile; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beatbox.ogg'); +} + +function setup() { + createCanvas(710, 100); +} + +function draw() { + background(0); + ball.x = constrain(mouseX, 0, width); + ellipse(ball.x, height / 2, 100, 100); +} + +function mousePressed() { + // गेंद के x स्थान को पैनिंग डिग्री पर मैप करें + // -1.0 (बाएं) और 1.0 (दाएं) के बीच + let panning = map(ball.x, 0, width, -1.0, 1.0); + soundFile.pan(panning); + soundFile.play(); +} diff --git a/dist/assets/examples/hi/33_Sound/05_Sound_Effect.js b/dist/assets/examples/hi/33_Sound/05_Sound_Effect.js new file mode 100644 index 0000000000..70d99f136f --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/05_Sound_Effect.js @@ -0,0 +1,69 @@ +/* + * @name ध्वनि प्रभाव + * @description

माउस को सर्कल के अंदर क्लिक करने पर ध्वनि प्रभाव चलाएं।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर

+ */ +// डैनियल शिफमैन द्वारा लर्निंग प्रोसेसिंग से अनुकूलित from +// http://www.learningprocessing.com +// डोरबेल का नमूना Corsica_S द्वारा freesound.org के माध्यम से, +// क्रिएटिव कॉमन्स BY 3.0 + +// एक "डोरबेल" (वास्तव में एक बटन) का वर्णन करने के लिए एक वर्ग +class Doorbell { + constructor(x_, y_, r_) { + // स्थान और आकार + this.x = x_; + this.y = y_; + this.r = r_; + } + // दरवाजे की घंटी के अंदर एक बिंदु है? (माउस रोलओवर आदि के लिए प्रयुक्त) + contains(mx, my) { + return dist(mx, my, this.x, this.y) < this.r; + } + + // डोरबेल दिखाएं (हार्डकोडेड रंग, बेहतर किया जा सकता है) + display(mx, my) { + if (this.contains(mx, my)) { + fill(100); + } else { + fill(175); + } + stroke(0); + strokeWeight(4); + ellipseMode(RADIUS); + ellipse(this.x, this.y, this.r, this.r); + } +} + +// एक ध्वनि फ़ाइल वस्तु +let dingdong; + +// एक डोरबेल ऑब्जेक्ट (जो ध्वनि को ट्रिगर करेगा) +let doorbell; + +function setup() { + createCanvas(200, 200); + + // ध्वनि फ़ाइल लोड करें। + // हमने एक एमपी3 और एक ओजीजी संस्करण दोनों को शामिल किया है। + soundFormats('mp3', 'ogg'); + dingdong = loadSound('assets/doorbell.mp3'); + + // एक नया डोरबेल बनाएं + doorbell = new Doorbell(width / 2, height / 2, 32); +} + +function draw() { + background(255); + // दरवाजे की घंटी दिखाओ + doorbell.display(mouseX, mouseY); +} + +function mousePressed() { + // यदि उपयोगकर्ता दरवाजे की घंटी पर क्लिक करता है, तो ध्वनि बजाएं! + if (doorbell.contains(mouseX, mouseY)) { + dingdong.play(); + } +} diff --git a/dist/assets/examples/hi/33_Sound/06_Manipulate_Sound.js b/dist/assets/examples/hi/33_Sound/06_Manipulate_Sound.js new file mode 100644 index 0000000000..3a6f0e8677 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/06_Manipulate_Sound.js @@ -0,0 +1,49 @@ +/* + * @name प्लेबैक दर + * @description

एक साउंडफाइल लोड करें और इसकी प्लेबैक दर को इस पर मैप करें + * माउसवाई, वॉल्यूम टू माउसएक्स। प्लेबैक दर गति के साथ है + * जो वेब ऑडियो संदर्भ ध्वनि फ़ाइल जानकारी को संसाधित करता है। + * धीमी दरें न केवल ध्वनि की अवधि को बढ़ाती हैं, बल्कि + * पिच को कम करें क्योंकि इसे धीमी आवृत्ति पर वापस खेला जा रहा है।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर< /p> + */ +// एक ध्वनि फ़ाइल वस्तु +let song; + +function preload() { + // एक ध्वनि फ़ाइल लोड करें + song = loadSound('assets/Damscray_DancingTiger.mp3'); +} + +function setup() { + createCanvas(710, 400); + + // ध्वनि को हमेशा के लिए लूप करें + // (ठीक है, कम से कम स्टॉप () कहा जाता है) + song.loop(); +} + +function draw() { + background(200); + + // वॉल्यूम को 0 और 1.0 . के बीच की सीमा पर सेट करें + let volume = map(mouseX, 0, width, 0, 1); + volume = constrain(volume, 0, 1); + song.amp(volume); + + // दर को 0.1 और 4 . के बीच की सीमा पर सेट करें + // दर बदलने से पिच बदल जाती है + let speed = map(mouseY, 0.1, height, 0, 2); + speed = constrain(speed, 0.01, 4); + song.rate(speed); + + // क्या हो रहा है यह दिखाने के लिए कुछ मंडल बनाएं + stroke(0); + fill(51, 100); + ellipse(mouseX, 100, 48, 48); + stroke(0); + fill(51, 100); + ellipse(100, mouseY, 48, 48); +} diff --git a/dist/assets/examples/hi/33_Sound/07_Amplitude_Analysis.js b/dist/assets/examples/hi/33_Sound/07_Amplitude_Analysis.js new file mode 100644 index 0000000000..01dec46bc8 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/07_Amplitude_Analysis.js @@ -0,0 +1,50 @@ +/** + * @name मापने वाला आयाम + * @description

ध्वनि के आयाम का विश्लेषण करें + * p5.आयाम।

+ * + *

आयाम कंपन का परिमाण है। ध्वनि कंपन है, + * इसलिए इसका आयाम आयतन / प्रबलता से निकटता से संबंधित है।

+ * + *

getLevel() विधि एक सरणी लेती है + * एक छोटी अवधि (1024 नमूने) में एकत्र किए गए आयाम मानों का। + * फिर यह इन मानों का रूट मीन स्क्वायर (RMS) लौटाता है।

+ * + *

डिजिटल ऑडियो के लिए मूल आयाम मान -1.0 और 1.0 के बीच हैं। + * लेकिन आरएमएस हमेशा सकारात्मक रहेगा, क्योंकि यह चुकता है। + * और, तात्कालिक आयाम रीडिंग का उपयोग करने के बजाय, जिन्हें एक दर पर नमूना लिया जाता है + * प्रति सेकंड ४४,१०० बार, आरएमएस समय के साथ औसत है (इस मामले में १०२४ नमूने), + * जो बेहतर ढंग से दर्शाता है कि हम आयाम कैसे सुनते हैं। + *

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर

+ */ +let song, analyzer; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); + + // create a new Amplitude analyzer + analyzer = new p5.Amplitude(); + + // Patch the input to an volume analyzer + analyzer.setInput(song); +} + +function draw() { + background(255); + + // Get the average (root mean square) amplitude + let rms = analyzer.getLevel(); + fill(127); + stroke(0); + + // Draw an ellipse with size based on volume + ellipse(width / 2, height / 2, 10 + rms * 200, 10 + rms * 200); +} diff --git a/dist/assets/examples/hi/33_Sound/08_Noise_Envelope.js b/dist/assets/examples/hi/33_Sound/08_Noise_Envelope.js new file mode 100644 index 0000000000..e92d67f842 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/08_Noise_Envelope.js @@ -0,0 +1,54 @@ +/** + * @name शोर ड्रम लिफाफा + * @description

श्वेत शोर समान ऊर्जा वाला एक यादृच्छिक ऑडियो संकेत है + * फ़्रीक्वेंसी स्पेक्ट्रम के हर हिस्से पर

+ * + *

एक लिफाफा फीका पड़ने की एक श्रृंखला है, परिभाषित + * समय / मान जोड़े के रूप में।

+ * + *

इस उदाहरण में, p5.Env + * p5 को "प्ले" करने के लिए इस्तेमाल किया जाएगा। इसके आउटपुट को नियंत्रित करके ड्रम की तरह शोर + * आयाम। A p5. आयाम स्केच में सभी ध्वनि का स्तर प्राप्त करेगा, और + * हम इस मान का उपयोग एक हरे रंग का आयत बनाने के लिए करेंगे जो लिफाफा दिखाता है + * कार्रवाई में।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी और a + * ध्वनि फ़ाइल।

+ */ +let noise, env, analyzer; + +function setup() { + createCanvas(710, 200); + noise = new p5.Noise(); // अन्य प्रकारों में 'भूरा' और 'गुलाबी' शामिल हैं + noise.start(); + + // शोर की मात्रा को 0 . से गुणा करें + // (जब तक हम शोर करने के लिए तैयार न हों तब तक इसे शांत रखें!) + noise.amp(0); + + env = new p5.Env(); + // सेट अटैकटाइम, डिकेटाइम, सस्टेनरैटियो, रिलीजटाइम + env.setADSR(0.001, 0.1, 0.2, 0.1); + // अटैकलेवल सेट करें, रिलीजलेवल + env.setRange(1, 0); + + // p5. आयाम स्केच में सभी ध्वनि का विश्लेषण करेगा + // जब तक कि इनपुट निर्दिष्ट करने के लिए setInput () विधि का उपयोग नहीं किया जाता है। + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // p5 से वॉल्यूम रीडिंग प्राप्त करें। आयाम विश्लेषक + let level = analyzer.getLevel(); + + // हरे रंग की आयत बनाने के लिए स्तर का उपयोग करें + let levelHeight = map(level, 0, 0.4, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); +} + +function mousePressed() { + env.play(noise); +} diff --git a/dist/assets/examples/hi/33_Sound/09_Note_Envelope.js b/dist/assets/examples/hi/33_Sound/09_Note_Envelope.js new file mode 100644 index 0000000000..1c2ba4bcf6 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/09_Note_Envelope.js @@ -0,0 +1,61 @@ +/** + * @name नोट लिफाफा + * @description

एक लिफाफा फीका पड़ने की एक श्रृंखला है, परिभाषित + * समय / मूल्य जोड़े के रूप में। इस उदाहरण में, लिफाफा + * आउटपुट को नियंत्रित करके किसी नोट को "प्ले" करने के लिए उपयोग किया जाएगा + * एक थरथरानवाला का आयाम।

+ * p5.Oscillator इसके माध्यम से अपना आउटपुट भेजता है + * एक आंतरिक वेब ऑडियो GainNode (p5.Oscillator.output)। + * डिफ़ॉल्ट रूप से, उस नोड का निरंतर मान 0.5 होता है। यह + * osc.amp() विधि से रीसेट करें। या, इस उदाहरण में, an + * लिफाफा आयाम को मोड़ते हुए उस नोड को नियंत्रित करता है + * वॉल्यूम नॉब की तरह ऊपर और नीचे।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी और a + * ध्वनि फ़ाइल।

+ */ +let osc, envelope, fft; + +let scaleArray = [60, 62, 64, 65, 67, 69, 71, 72]; +let note = 0; + +function setup() { + createCanvas(710, 200); + osc = new p5.SinOsc(); + + // लिफाफे को तुरंत चालू करें + envelope = new p5.Env(); + + // सेट अटैकटाइम, डिकेटाइम, सस्टेनरैटियो, रिलीजटाइम + envelope.setADSR(0.001, 0.5, 0.1, 0.5); + + // अटैकलेवल सेट करें, रिलीजलेवल + envelope.setRange(1, 0); + + osc.start(); + + fft = new p5.FFT(); + noStroke(); +} + +function draw() { + background(20); + + if (frameCount % 60 === 0 || frameCount === 1) { + let midiValue = scaleArray[note]; + let freqValue = midiToFreq(midiValue); + osc.freq(freqValue); + + envelope.play(osc, 0, 0.1); + note = (note + 1) % scaleArray.length; + } + + // प्लॉट FFT.analyze () कैनवास पर आवृत्ति विश्लेषण + let spectrum = fft.analyze(); + for (let i = 0; i < spectrum.length / 20; i++) { + fill(spectrum[i], spectrum[i] / 10, 0); + let x = map(i, 0, spectrum.length / 20, 0, width); + let h = map(spectrum[i], 0, 255, 0, height); + rect(x, height, spectrum.length / 20, -h); + } +} diff --git a/dist/assets/examples/hi/33_Sound/10_Oscillator_Waveform.js b/dist/assets/examples/hi/33_Sound/10_Oscillator_Waveform.js new file mode 100644 index 0000000000..6b49a56e49 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/10_Oscillator_Waveform.js @@ -0,0 +1,40 @@ +/* + * @name थरथरानवाला आवृत्ति + * @description

ऑसिलेटर को नियंत्रित करें और FFT का उपयोग करके तरंग देखें। + * माउसएक्स को फ़्रीक्वेंसी से मैप किया जाता है, माउसवाई को एम्पलीट्यूड में मैप किया जाता है।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी और a + * ध्वनि फ़ाइल।

+ */ +let osc, fft; + +function setup() { + createCanvas(720, 256); + + osc = new p5.TriOsc(); // आवृत्ति और प्रकार सेट करें + osc.amp(0.5); + + fft = new p5.FFT(); + osc.start(); +} + +function draw() { + background(255); + + let waveform = fft.waveform(); // तरंग का विश्लेषण करें + beginShape(); + strokeWeight(5); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, height, 0); + vertex(x, y); + } + endShape(); + + // माउसएक्स के आधार पर थरथरानवाला आवृत्ति बदलें + let freq = map(mouseX, 0, width, 40, 880); + osc.freq(freq); + + let amp = map(mouseY, 0, height, 1, 0.01); + osc.amp(amp); +} diff --git a/dist/assets/examples/hi/33_Sound/11_Live_Input.js b/dist/assets/examples/hi/33_Sound/11_Live_Input.js new file mode 100644 index 0000000000..b8cb836bb8 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/11_Live_Input.js @@ -0,0 +1,36 @@ +/** + * @name Mic Input + * @description

Get audio input from your computer's microphone. + * Make noise to float the ellipse.

+ *

Note: p5.AudioIn contains its own p5.Amplitude object, + * so you can call getLevel on p5.AudioIn without + * creating a p5.Amplitude.

+ *

To run this example locally, you will need the + * p5.sound library + * and a running local server.

+ */ +let mic; + +function setup() { + createCanvas(710, 200); + + // एक ऑडियो इनपुट बनाएं + mic = new p5.AudioIn(); + + // ऑडियो इनपुट शुरू करें। + // डिफ़ॉल्ट रूप से, यह .connect() (कंप्यूटर स्पीकर के लिए) नहीं करता है + mic.start(); +} + +function draw() { + background(200); + + // कुल मात्रा प्राप्त करें (0 और 1.0 के बीच) + let vol = mic.getLevel(); + fill(127); + stroke(0); + + // आयतन के आधार पर ऊंचाई के साथ एक दीर्घवृत्त बनाएं + let h = map(vol, 0, 1, height, 0); + ellipse(width / 2, h - 25, 50, 50); +} diff --git a/dist/assets/examples/hi/33_Sound/12_FFT_Spectrum.js b/dist/assets/examples/hi/33_Sound/12_FFT_Spectrum.js new file mode 100644 index 0000000000..098e1247c8 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/12_FFT_Spectrum.js @@ -0,0 +1,30 @@ +/** + * @name फ्रीक्वेंसी स्पेक्ट्रम Spec + * @description

लाइव ऑडियो इनपुट के फ़्रीक्वेंसी स्पेक्ट्रम की कल्पना करें।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * और एक चालू स्थानीय सर्वर

+ */ +let mic, fft; + +function setup() { + createCanvas(710, 400); + noFill(); + + mic = new p5.AudioIn(); + mic.start(); + fft = new p5.FFT(); + fft.setInput(mic); +} + +function draw() { + background(200); + + let spectrum = fft.analyze(); + + beginShape(); + for (i = 0; i < spectrum.length; i++) { + vertex(i, map(spectrum[i], 0, 255, height, 0)); + } + endShape(); +} diff --git a/dist/assets/examples/hi/33_Sound/13_Mic_Threshold.js b/dist/assets/examples/hi/33_Sound/13_Mic_Threshold.js new file mode 100644 index 0000000000..341215ba1b --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/13_Mic_Threshold.js @@ -0,0 +1,49 @@ +/** + * @name माइक थ्रेशोल्ड + * @description

ऑडियो इनपुट होने पर एक ईवेंट ट्रिगर करें (एक आयत बनाएं)) + * वॉल्यूम एक सीमा से अधिक है।

+ *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * और एक चालू स्थानीय सर्वर

+ */ +// लर्निंग प्रोसेसिंग से अनुकूलित, डैनियल शिफमैन +// Learningprocessing.com +let input; +let analyzer; + +function setup() { + createCanvas(710, 200); + background(255); + + // एक ऑडियो इनपुट बनाएं + input = new p5.AudioIn(); + + input.start(); +} + +function draw() { + // कुल मात्रा प्राप्त करें (0 और 1.0 के बीच) + let volume = input.getLevel(); + + // यदि वॉल्यूम> 0.1, एक यादृच्छिक स्थान पर एक रेक्ट खींचा जाता है। + // वॉल्यूम जितना बड़ा होगा, आयत उतना ही बड़ा होगा। + let threshold = 0.1; + if (volume > threshold) { + stroke(0); + fill(0, 100); + rect(random(40, width), random(height), volume * 50, volume * 50); + } + + // थ्रेशोल्ड पर समग्र संभावित आयतन, w / एक रेखा का ग्राफ़ + let y = map(volume, 0, 1, height, 0); + let ythreshold = map(threshold, 0, 1, height, 0); + + noStroke(); + fill(175); + rect(0, 0, 20, height); + // फिर ग्राफ़ पर एक आयत बनाएं, जिसका आकार आयतन के अनुसार हो + fill(0); + rect(0, y, 20, y); + stroke(0); + line(0, ythreshold, 19, ythreshold); +} diff --git a/dist/assets/examples/hi/33_Sound/14_Filter_LowPass.js b/dist/assets/examples/hi/33_Sound/14_Filter_LowPass.js new file mode 100644 index 0000000000..0480b4b3ea --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/14_Filter_LowPass.js @@ -0,0 +1,62 @@ +/** + * @name फ़िल्टर लोपास + * @description p5.LowPass फ़िल्टर को p5.SoundFile पर लागू करें। + * एफएफटी के साथ ध्वनि की कल्पना करें। + * फ़िल्टर की कटऑफ आवृत्ति के लिए माउसX को मैप करें + * और माउसवाई बैंडपास फिल्टर की प्रतिध्वनि/चौड़ाई के लिएY + * + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर

+ */ +let soundFile; +let fft; + +let filter, filterFreq, filterRes; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beat'); +} + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + // loop the sound file + soundFile.loop(); + + filter = new p5.LowPass(); + + // मास्टर आउटपुट से साउंडफाइल को डिस्कनेक्ट करें। + // फिर, इसे फ़िल्टर से कनेक्ट करें, ताकि हम केवल फ़िल्टर की गई ध्वनि सुन सकें + soundFile.disconnect(); + soundFile.connect(filter); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // माउसX को न्यूनतम से कटऑफ आवृत्ति पर मैप करें + // आवृत्ति (10 हर्ट्ज) से उच्चतम (22050 हर्ट्ज) जो मनुष्य सुन सकते हैं + filterFreq = map(mouseX, 0, width, 10, 22050); + + // मानचित्र माउसY कटऑफ आवृत्ति पर प्रतिध्वनि (वॉल्यूम बूस्ट) के लिए + filterRes = map(mouseY, 0, height, 15, 5); + + // set filter parameters + filter.set(filterFreq, filterRes); + + // एफएफटी स्पेक्ट्रम विश्लेषण में हर मूल्य ड्रा करें जहां + // x = निम्नतम (10 हर्ट्ज) से उच्चतम (22050 हर्ट्ज) आवृत्तियों, + // h = उस आवृत्ति पर ऊर्जा (आयाम / आयतन) + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/hi/33_Sound/15_Filter_BandPass.js b/dist/assets/examples/hi/33_Sound/15_Filter_BandPass.js new file mode 100644 index 0000000000..7285e2d040 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/15_Filter_BandPass.js @@ -0,0 +1,51 @@ +/** + * @name फ़िल्टर बैंडपास + * @description सफेद शोर के लिए p5.BandPass फ़िल्टर लागू करें। + * एफएफटी के साथ ध्वनि की कल्पना करें। + * मैप माउसX को बैंडपास फ़्रीक्वेंसी के लिए + * और माउसवाई बैंडपास फिल्टर की प्रतिध्वनि/चौड़ाई के लिएY + * + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर

+ */ +let noise; +let fft; +let filter, filterFreq, filterWidth; + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + filter = new p5.BandPass(); + + noise = new p5.Noise(); + + noise.disconnect(); // मास्टर आउटपुट से साउंडफाइल को डिस्कनेक्ट करें ... + filter.process(noise); // ... और फ़िल्टर से कनेक्ट करें ताकि हम केवल बैंडपास सुन सकें। + noise.start(); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // FFT स्पेक्ट्रम रेंज से एक बैंडपास फ्रीक के लिए माउसX को मैप करें: 10Hz - 22050Hz + filterFreq = map(mouseX, 0, width, 10, 22050); + // मानचित्र माउसY प्रतिध्वनि/चौड़ाई के लिए + filterWidth = map(mouseY, 0, height, 0, 90); + // फ़िल्टर पैरामीटर सेट करें + filter.set(filterFreq, filterWidth); + + // एफएफटी स्पेक्ट्रम विश्लेषण में हर मूल्य ड्रा करें जहां + // x = निम्नतम (10 हर्ट्ज) से उच्चतम (22050 हर्ट्ज) आवृत्तियों, + // एच = उस आवृत्ति पर ऊर्जा / आयाम + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/hi/33_Sound/16_Delay.js b/dist/assets/examples/hi/33_Sound/16_Delay.js new file mode 100644 index 0000000000..fd24f0cbe4 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/16_Delay.js @@ -0,0 +1,56 @@ +/** + * @name देरी + * @description + * p5 सुनने के लिए माउस क्लिक करें। साउंडफाइल को प्रोसेस करने में देरी करें। + * MouseX p5.Delay फ़िल्टर फ़्रीक्वेंसी को नियंत्रित करता है। + * MouseY p5.Delay Time और Resonance दोनों को नियंत्रित करता है। + * एक आयाम वस्तु के साथ परिणामी ध्वनि की मात्रा की कल्पना करें। + * + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर

+ */ + +let soundFile, analyzer, delay; + +function preload() { + soundFormats('ogg', 'mp3'); + soundFile = loadSound('assets/beatbox.mp3'); +} + +function setup() { + createCanvas(710, 400); + + soundFile.disconnect(); // तो हम केवल देरी सुनेंगे + + delay = new p5.Delay(); + delay.process(soundFile, 0.12, 0.7, 2300); + delay.setType('pingPong'); // एक स्टीरियो प्रभाव + + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // p5 से वॉल्यूम रीडिंग प्राप्त करें। आयाम विश्लेषक + let level = analyzer.getLevel(); + + // हरे रंग की आयत बनाने के लिए स्तर का उपयोग करें + let levelHeight = map(level, 0, 0.1, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); + + let filterFreq = map(mouseX, 0, width, 60, 15000); + filterFreq = constrain(filterFreq, 60, 15000); + let filterRes = map(mouseY, 0, height, 3, 0.01); + filterRes = constrain(filterRes, 0.01, 3); + delay.filter(filterFreq, filterRes); + let delTime = map(mouseY, 0, width, 0.2, 0.01); + delTime = constrain(delTime, 0.01, 0.2); + delay.delayTime(delTime); +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/hi/33_Sound/17_Reverb.js b/dist/assets/examples/hi/33_Sound/17_Reverb.js new file mode 100644 index 0000000000..26e7713d4c --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/17_Reverb.js @@ -0,0 +1,36 @@ +/** + * @name रेवरब + * @description Reverb ध्वनि को गहराई और कथित स्थान देता है। यहाँ, + * शोर reverb के साथ संसाधित किया जाता है। + * + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर

+ */ +let sound, reverb; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/Damscray_DancingTiger'); + + // डिफ़ॉल्ट कनेक्शन को डिस्कनेक्ट करें + // ताकि हम केवल ध्वनि को reverb.process के माध्यम से सुनें + soundFile.disconnect(); +} + +function setup() { + createCanvas(720, 100); + background(0); + + reverb = new p5.Reverb(); + + // सोननेक्ट्स साउंडफाइल a with के साथ रीवरब करने के लिए + // reverb 6 सेकंड का समय, 0.2% की क्षय दर + reverb.process(soundFile, 6, 0.2); + + reverb.amp(4); // और बढ़ाओ! +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/hi/33_Sound/18_Convolution_Reverb.js b/dist/assets/examples/hi/33_Sound/18_Convolution_Reverb.js new file mode 100644 index 0000000000..43390c4ac5 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/18_Convolution_Reverb.js @@ -0,0 +1,87 @@ +/** + * @name कनवल्शन रेवरब + * @description

p5.Convolver वास्तविक ध्वनि को फिर से बना सकता है + * कनवल्शन का उपयोग करके रिक्त स्थान। कनवल्शन एक आवेग प्रतिक्रिया लेता है, + * (एक कमरे की आवाज़ गूंजती है), और इसका उपयोग करता है + * उस स्थान की ध्वनि को फिर से बनाएं।

किसी ध्वनि को चलाने के लिए क्लिक करें + * संकल्प। हर बार जब आप क्लिक करते हैं, तो ध्वनि संकुचित हो जाती है + * एक अलग आवेग प्रतिक्रिया। इंपल्स रिस्पांस को ही सुनने के लिए, + * कोई भी कुंजी दबाएं।

+ * + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर। + * ये कनवल्शन नमूने Creative Commons BY . हैं + * + * रिकॉर्डिंगहॉपकिंस

+ */ +let sound, env, cVerb, fft; +let currentIR = 0; +let rawImpulse; + +function preload() { + // हमने सभी आवेगों / ध्वनियों के एमपी 3 और ओजीजी दोनों संस्करणों को शामिल किया है + soundFormats('ogg', 'mp3'); + + // एक p5.Convolver बनाएं + cVerb = createConvolver('assets/bx-spring'); + + // bx-spring के अलावा cVerb.impulses ऐरे में इंपल्स रिस्पॉन्स जोड़ें + cVerb.addImpulse('assets/small-plate'); + cVerb.addImpulse('assets/drum'); + cVerb.addImpulse('assets/beatbox'); + cVerb.addImpulse('assets/concrete-tunnel'); + + // एक ध्वनि लोड करें जिसे p5.ConvultionReverb द्वारा संसाधित किया जाएगा + sound = loadSound('assets/Damscray_DancingTiger'); +} + +function setup() { + createCanvas(710, 400); + rawImpulse = loadSound('assets/' + cVerb.impulses[currentIR].name); + + // मास्टर आउटपुट से डिस्कनेक्ट करें ... + sound.disconnect(); + // ... और cVerb . के साथ प्रक्रिया करें + // ताकि हम केवल reverb सुनें + cVerb.process(sound); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + fill(0, 255, 40); + + let spectrum = fft.analyze(); + + // फ़्रीक्वेंसीस्पेक्ट्रम सरणी में प्रत्येक मान को आयत के रूप में ड्रा करें + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} + +function mousePressed() { + // cVerb.impulses की सरणी के माध्यम से चक्र + currentIR++; + if (currentIR >= cVerb.impulses.length) { + currentIR = 0; + } + cVerb.toggleImpulse(currentIR); + + // आवेग के माध्यम से ध्वनि बजाएं + sound.play(); + + // वर्तमान आवेग प्रतिक्रिया नाम प्रदर्शित करें (फ़ाइलपथ) + println('Convolution Impulse Response: ' + cVerb.impulses[currentIR].name); + + rawImpulse.setPath('assets/' + cVerb.impulses[currentIR].name); +} + +// आवेग खेलें (बिना दृढ़ संकल्प के) +function keyPressed() { + rawImpulse.play(); +} diff --git a/dist/assets/examples/hi/33_Sound/19_Record_Save.js b/dist/assets/examples/hi/33_Sound/19_Record_Save.js new file mode 100644 index 0000000000..9cee1ee715 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/19_Record_Save.js @@ -0,0 +1,58 @@ +/** + * @name रिकॉर्ड ऑडियो सहेजें + * @description एक ध्वनि रिकॉर्ड करें, इसे वापस चलाएं और सहेजें + * यह क्लाइंट के कंप्यूटर पर .wav फ़ाइल के रूप में। + * हमें तीन वस्तुओं की आवश्यकता है: एक p5.ऑडियोइन (माइक / ध्वनि स्रोत), + * p5.SoundRecorder (ध्वनि रिकॉर्ड करता है), और a + * p5.SoundFile (प्ले बैक / सेव)। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.sound लाइब्रेरी + * एक ध्वनि फ़ाइल, और एक चल रहा स्थानीय सर्वर

+ */ +let mic, recorder, soundFile; + +let state = 0; // माउसप्रेस रिकॉर्ड, स्टॉप, प्ले से बढ़ेगा + +function setup() { + createCanvas(400, 400); + background(200); + fill(0); + text('Enable mic and click the mouse to begin recording', 20, 20); + + // में एक ऑडियो बनाएं + mic = new p5.AudioIn(); + + // उपयोगकर्ताओं को ठीक से काम करने के लिए रिकॉर्डिंग के लिए अपने ब्राउज़र माइक्रोफ़ोन को मैन्युअल रूप से सक्षम करना होगा! + mic.start(); + + // एक साउंड रिकॉर्डर बनाएं + recorder = new p5.SoundRecorder(); + + // माइक को रिकॉर्डर से कनेक्ट करें + recorder.setInput(mic); + + // एक खाली ध्वनि फ़ाइल बनाएं जिसका उपयोग हम रिकॉर्डिंग को प्लेबैक करने के लिए करेंगे + soundFile = new p5.SoundFile(); +} + +function mousePressed() { + // यह सुनिश्चित करने के लिए '.सक्षम' बूलियन का उपयोग करें कि उपयोगकर्ता ने माइक को सक्षम किया है (अन्यथा हम मौन रिकॉर्ड करेंगे) + if (state === 0 && mic.enabled) { + // रिकॉर्डर को p5.SoundFile पर रिकॉर्ड करने के लिए कहें, जिसका उपयोग हम प्लेबैक के लिए करेंगे + recorder.record(soundFile); + + background(255, 0, 0); + text('Recording now! Click to stop.', 20, 20); + state++; + } else if (state === 1) { + recorder.stop(); // रिकॉर्डर को रोकें, और परिणाम को साउंडफाइल पर भेजें + + background(0, 255, 0); + text('Recording stopped. Click to play & save', 20, 20); + state++; + } else if (state === 2) { + soundFile.play(); // परिणाम खेलें! + saveSound(soundFile, 'mySound.wav'); // फाइल सुरक्षित करें + state++; + } +} diff --git a/dist/assets/examples/hi/33_Sound/21_FreqModulation.js b/dist/assets/examples/hi/33_Sound/21_FreqModulation.js new file mode 100644 index 0000000000..1fb84a8ea0 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/21_FreqModulation.js @@ -0,0 +1,148 @@ +/** + * @name फ़्रीक्वेंसी मॉडुलन + * @description

फ़्रीक्वेंसी मॉडुलन संश्लेषण का एक शक्तिशाली रूप है। + * अपने सरलतम रूप में, FM में दो ऑसिलेटर शामिल होते हैं, जिन्हें संदर्भित किया जाता है + * वाहक और न्यूनाधिक के रूप में। जैसा कि न्यूनाधिक का तरंग दोलन करता है + * कुछ न्यूनतम और अधिकतम आयाम मान के बीच, वह क्षणिक मान + * वाहक की आवृत्ति ("मॉड्यूलेट") में जोड़ा जाता है।

+ *

वाहक को आमतौर पर श्रव्य आवृत्ति पर दोलन करने के लिए सेट किया जाता है + * जिसे हम एक पिच के रूप में देखते हैं - इस मामले में, यह 220Hz पर एक साइन वेव थरथरानवाला है, + * "A3" नोट के बराबर। वाहक डिफ़ॉल्ट रूप से मास्टर आउटपुट से जुड़ा होता है + * (यह सभी p5.Oscillators के लिए मामला है)।

+ *

हम मास्टर आउटपुट से मॉड्यूलेटर को डिस्कनेक्ट करेंगे, + * और इसके बजाय वाहक की आवृत्ति से कनेक्ट करें: + * carrier.freq(modulator). यह के आउटपुट आयाम को जोड़ता है + * वाहक की आवृत्ति के लिए न्यूनाधिक।

+ *

+ * मॉड्यूलेशन गहराई बताती है कि वाहक आवृत्ति कितनी संशोधित करेगी। + * यह न्यूनाधिक के आयाम पर आधारित है। + * न्यूनाधिक आयाम मानों की एक सतत धारा उत्पन्न करता है जिसे हम जोड़ेंगे + * वाहक आवृत्ति के लिए। शून्य के आयाम का अर्थ है मौन, इसलिए मॉडुलन होगा + *कोई प्रभाव नहीं पड़ता। 1.0 का एक आयाम आउटपुट मानों की सीमा को मापता है + * +1.0 और -1.0 के बीच। ध्वनि के लिए यह मानक श्रेणी है जिसे भेजा जाता है + * आपके स्पीकर, लेकिन FM में हम इसके बजाय मॉड्यूलेटर के आउटपुट को कैरियर फ़्रीक्वेंसी पर भेज रहे हैं, + * जहां हम मुश्किल से +1Hz / -1Hz मॉडुलन को नोटिस करेंगे। + * तो हम आम तौर पर न्यूनाधिक के आयाम ("गहराई") को बढ़ाकर संख्याओं की तुलना में बहुत अधिक करेंगे + * हम अपने वक्ताओं को भेज सकते हैं।

+ *

मॉड्यूलेशन फ़्रीक्वेंसी मॉडुलन की गति है। जब मॉडुलन आवृत्ति कम होती है + * 20 हर्ट्ज से अधिक, हम इसकी आवृत्ति को पिच के रूप में सुनना बंद कर देते हैं, और इसे धड़कन की लय के रूप में सुनना शुरू कर देते हैं। + * उदाहरण के लिए, एक ऑपरेटिव गायक के "वाइब्रेटो" प्रभाव की नकल करने के लिए 20 की गहराई पर 7.5 हर्ट्ज़ आज़माएं। + * इसके लिए शब्द लो फ़्रीक्वेंसी ऑसिलेटर या एलएफओ है। उच्च आवृत्तियों पर सेट किए गए मॉड्यूलेटर कर सकते हैं + * दिलचस्प प्रभाव भी पैदा करते हैं, खासकर जब आवृत्ति का हार्मोनिक संबंध होता है + * वाहक संकेत के लिए। उदाहरण के लिए, सुनें कि क्या होता है जब न्यूनाधिक की आवृत्ति होती है + * वाहक का आधा या दोगुना। यह जॉन चाउनिंग द्वारा विकसित एफएम सिंथेसिस का आधार है + * 1960 के दशक में, जो 1980 के दशक में संश्लेषण में क्रांति लाने के लिए आया था और अक्सर इसका उपयोग संश्लेषण के लिए किया जाता है + * पीतल और घंटी जैसी आवाजें। + * + *

इस उदाहरण में,

+ * - माउसएक्स -150 से 150 तक मॉड्यूलेशन गहराई (मॉड्यूलेटर का आयाम) को नियंत्रित करता है। + * जब मॉड्यूलेटर का आयाम 0 (बीच में) पर सेट होता है, तो ध्यान दें कि मॉड्यूलेशन कैसे होता है + *कोई प्रभाव नहीं पड़ता। संख्या जितनी अधिक (पूर्ण मान) होगी, प्रभाव उतना ही अधिक होगा। + * यदि मॉड्यूलेटर तरंग एक वर्ग [] की तरह सममित है, तो साइन ~ + * या त्रिभुज /\, ऋणात्मक आयाम धनात्मक आयाम के समान होगा। + * लेकिन इस उदाहरण में, न्यूनाधिक एक विषम चूरा तरंग है, जिसका आकार इस प्रकार है /। + * जब हम इसे किसी ऋणात्मक संख्या से गुणा करते हैं, तो यह इस प्रकार पीछे की ओर जाती है। सबसे अच्छा के लिए + * अंतर देखें, आवृत्ति कम करने का प्रयास करें। + *

+ *

- MouseY न्यूनाधिक की आवृत्ति को 0 से 112 Hz तक नियंत्रित करता है। + * श्रव्य सीमा के नीचे मॉड्यूलेशन आवृत्तियों की तुलना करने का प्रयास करें (जो लगभग 20 हर्ट्ज से शुरू होता है), + * और इसके ऊपर, विशेष रूप से वाहक आवृत्ति के लिए एक हार्मोनिक संबंध में (जो कि 220hz है, इसलिए + * आधा प्रयास करें, 1/3, 1/4 आदि...)। + * + *

आपको इसमें शामिल करना होगा + * p5.sound लाइब्रेरी + * इस उदाहरण के लिए अपने स्वयं के प्रोजेक्ट में काम करने के लिए।

+ */ + +let carrier; // यह थरथरानवाला है जिसे हम सुनेंगे +let modulator; // यह थरथरानवाला वाहक की आवृत्ति को नियंत्रित करेगा + +let analyzer; // हम इसका उपयोग तरंग की कल्पना करेंगे + +// वाहक आवृत्ति पूर्व-मॉड्यूलेशन +let carrierBaseFreq = 220; + +// न्यूनाधिक के लिए न्यूनतम/अधिकतम रेंजmax +let modMaxFreq = 112; +let modMinFreq = 0; +let modMaxDepth = 150; +let modMinDepth = -150; + +function setup() { + let cnv = createCanvas(800, 400); + noFill(); + + carrier = new p5.Oscillator('sine'); + carrier.amp(0); // आयाम सेट करें + carrier.freq(carrierBaseFreq); // आवृत्ति सेट करें + carrier.start(); // हिलना शुरू करें + + // प्रकार को 'वर्ग', 'साइन' या 'त्रिकोण' में बदलने का प्रयास करें + modulator = new p5.Oscillator('sawtooth'); + modulator.start(); + + // वाहक की आवृत्ति को संशोधित करने के लिए मॉड्यूलेटर का आउटपुट जोड़ें + modulator.disconnect(); + carrier.freq(modulator); + + // ऑडियो का विश्लेषण करने के लिए एक FFT बनाएं + analyzer = new p5.FFT(); + + // माउसओवर / टच स्टार्ट पर वाहक को अंदर / बाहर फीका करें + toggleAudio(cnv); +} + +function draw() { + background(30); + + // मैप माउसY अधिकतम और न्यूनतम आवृत्ति के बीच न्यूनाधिक आवृत्ति के लिए + let modFreq = map(mouseY, height, 0, modMinFreq, modMaxFreq); + modulator.freq(modFreq); + + // न्यूनाधिक के आयाम को बदलें + // नकारात्मक amp चूरा तरंग को उलट देता है, और टक्कर लगता है + // + let modDepth = map(mouseX, 0, width, modMinDepth, modMaxDepth); + modulator.amp(modDepth); + + // तरंग का विश्लेषण करें + waveform = analyzer.waveform(); + + // तरंग का आकार बनाएं + stroke(255); + strokeWeight(10); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); + + strokeWeight(1); + // क्या हो रहा है इसके बारे में एक नोट जोड़ें + text('Modulator Frequency: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text( + 'Modulator Amplitude (Modulation Depth): ' + modDepth.toFixed(3), + 20, + 40 + ); + text( + 'Carrier Frequency (pre-modulation): ' + carrierBaseFreq + ' Hz', + width / 2, + 20 + ); +} + +// ध्वनि को टॉगल करने के लिए सहायक कार्य +function toggleAudio(cnv) { + cnv.mouseOver(function() { + carrier.amp(1.0, 0.01); + }); + cnv.touchStarted(function() { + carrier.amp(1.0, 0.01); + }); + cnv.mouseOut(function() { + carrier.amp(0.0, 1.0); + }); +} diff --git a/dist/assets/examples/hi/33_Sound/22_AmplitudeModulation.js b/dist/assets/examples/hi/33_Sound/22_AmplitudeModulation.js new file mode 100644 index 0000000000..c9b15f7003 --- /dev/null +++ b/dist/assets/examples/hi/33_Sound/22_AmplitudeModulation.js @@ -0,0 +1,95 @@ +/** + * @name आयाम मॉडुलन + * @description

एम्पलीट्यूड मॉड्यूलेशन में दो ऑसिलेटर शामिल होते हैं, जिन्हें संदर्भित किया जाता है + * वाहक और न्यूनाधिक के रूप में, जहाँ न्यूनाधिक नियंत्रित करता है + * वाहक का आयाम।

+ * + *

वाहक आमतौर पर एक श्रव्य आवृत्ति (यानी 440 हर्ट्ज) पर सेट होता है + * और डिफ़ॉल्ट रूप से मास्टर आउटपुट से जुड़ा है। वाहक.amp है + * शून्य पर सेट करें क्योंकि हमारे पास मॉड्यूलेटर इसके आयाम को नियंत्रित करेगा।

+ * + *

मॉड्यूलेटर मास्टर आउटपुट से डिस्कनेक्ट हो गया है। इसके बजाय, यह जुड़ा हुआ है + * कैरियर के आयाम तक, इस तरह:वाहक.amp(मॉड्यूलेटर)।

+ * + *

इस उदाहरण में...

+ *

- MouseX न्यूनाधिक के आयाम को नियंत्रित करता है + * 0 से 1 तक। जब न्यूनाधिक का आयाम 0 पर सेट होता है, तो + * आयाम मॉडुलन का कोई प्रभाव नहीं पड़ता है।

+ * + *

- MouseY न्यूनाधिक की आवृत्ति को 0 से 20hz तक नियंत्रित करता है। + * यह रेंज मनुष्यों की तुलना में कम आवृत्तियों की है, और हम अनुभव करते हैं + * एक लय के रूप में मॉडुलन। यह श्रेणी ट्रेमोलो जैसे प्रभावों का अनुकरण कर सकती है। + * रिंग मॉड्यूलेशन एक प्रकार का एम्प्लीट्यूड मॉड्यूलेशन है जहां मूल + * वाहक संकेत मौजूद नहीं है, और अक्सर तेजी से मॉडुलन शामिल होता है + * आवृत्ति।

+ * + *

आपको इसमें शामिल करना होगा + * p5.sound लाइब्रेरी + * इस उदाहरण के लिए अपने स्वयं के प्रोजेक्ट में काम करने के लिए।

+ */ +let carrier; // यह थरथरानवाला है जिसे हम सुनेंगे +let modulator; // यह थरथरानवाला वाहक के आयाम को संशोधित करेगा +let fft; // हम तरंग की कल्पना करेंगे + +function setup() { + createCanvas(800, 400); + noFill(); + background(30); // अल्फा + + carrier = new p5.Oscillator(); // डिफ़ॉल्ट रूप से मास्टर आउटपुट से जुड़ता है + carrier.freq(340); + carrier.amp(0); + // वाहक का amp डिफ़ॉल्ट रूप से 0 है, हमारे न्यूनाधिक को कुल नियंत्रण देता है + + carrier.start(); + + modulator = new p5.Oscillator('triangle'); + modulator.disconnect(); // मास्टर आउटपुट से मॉड्यूलेटर को डिस्कनेक्ट करें + modulator.freq(5); + modulator.amp(1); + modulator.start(); + + // न्यूनाधिक के साथ वाहक के आयाम को संशोधित करें + // वैकल्पिक रूप से, हम सिग्नल को स्केल कर सकते हैं। + carrier.amp(modulator.scale(-1, 1, 1, -1)); + + // ऑडियो का विश्लेषण करने के लिए एक fft बनाएं + fft = new p5.FFT(); +} + +function draw() { + background(30, 30, 30, 100); // अल्फा + + // माउसY को 0 और 20hz के बीच मूड्यूलेटर फ़्रीक में मैप करें + let modFreq = map(mouseY, 0, height, 20, 0); + modulator.freq(modFreq); + + let modAmp = map(mouseX, 0, width, 0, 1); + modulator.amp(modAmp, 0.01); // चिकनी लुप्त होती के लिए 0.1 का फीका समय fade + + // तरंग का विश्लेषण करें + waveform = fft.waveform(); + + // तरंग का आकार बनाएं + drawWaveform(); + + drawText(modFreq, modAmp); +} + +function drawWaveform() { + stroke(240); + strokeWeight(4); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); +} + +function drawText(modFreq, modAmp) { + strokeWeight(1); + text('Modulator Frequency: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text('Modulator Amplitude: ' + modAmp.toFixed(3), 20, 40); +} diff --git a/dist/assets/examples/hi/35_Mobile/00_Acceleration_Ball_Bounce.js b/dist/assets/examples/hi/35_Mobile/00_Acceleration_Ball_Bounce.js new file mode 100644 index 0000000000..1f5c186208 --- /dev/null +++ b/dist/assets/examples/hi/35_Mobile/00_Acceleration_Ball_Bounce.js @@ -0,0 +1,58 @@ +/* + * @name एक्सेलेरेशन बॉल बाउंस + * @description त्वरणX और त्वरणY मानों के आधार पर एक दीर्घवृत्त को इधर-उधर घुमाएँ, और कैनवास के किनारे को छूने पर उछलता है। + */ + +// स्थिति चर +let x = 0; +let y = 0; + +// गति वेग +let vx = 0; +let vy = 0; + +// त्वरण +let ax = 0; +let ay = 0; + +let vMultiplier = 0.007; +let bMultiplier = 0.6; + +function setup() { + createCanvas(displayWidth, displayHeight); + fill(0); +} + +function draw() { + background(255); + ballMove(); + ellipse(x, y, 30, 30); +} + +function ballMove() { + ax = accelerationX; + ay = accelerationY; + + vx = vx + ay; + vy = vy + ax; + y = y + vy * vMultiplier; + x = x + vx * vMultiplier; + + // कैनवास के किनारे को छूने पर उछलें + if (x < 0) { + x = 0; + vx = -vx * bMultiplier; + } + if (y < 0) { + y = 0; + vy = -vy * bMultiplier; + } + if (x > width - 20) { + x = width - 20; + vx = -vx * bMultiplier; + } + if (y > height - 20) { + y = height - 20; + vy = -vy * bMultiplier; + } +} diff --git a/dist/assets/examples/hi/35_Mobile/01_Simple_Draw.js b/dist/assets/examples/hi/35_Mobile/01_Simple_Draw.js new file mode 100644 index 0000000000..b558da7f27 --- /dev/null +++ b/dist/assets/examples/hi/35_Mobile/01_Simple_Draw.js @@ -0,0 +1,15 @@ +/* + * @name सिंपल ड्रा + * @description mouseX, mouseY, pmouseX, और pmouseY मानों का उपयोग करके स्क्रीन पर ड्रा करने के लिए स्पर्श करें। + */ + +function setup() { + createCanvas(displayWidth, displayHeight); + strokeWeight(10); + stroke(0); +} + +function touchMoved() { + line(mouseX, mouseY, pmouseX, pmouseY); + return false; +} diff --git a/dist/assets/examples/hi/35_Mobile/02_Acceleration_Color.js b/dist/assets/examples/hi/35_Mobile/02_Acceleration_Color.js new file mode 100644 index 0000000000..25ce60604f --- /dev/null +++ b/dist/assets/examples/hi/35_Mobile/02_Acceleration_Color.js @@ -0,0 +1,24 @@ +/* + * @name त्वरण रंग + * @description डिवाइस को घुमाए जाने का पता लगाने के लिए deviceMoved() का उपयोग करें। पृष्ठभूमि आरजीबी रंग मान एक्सेलेरेशन एक्स, एक्सेलेरेशन वाई, और एक्सेलेरेशन जेड मानों पर मैप किए जाते हैं। + */ + +let r, g, b; + +function setup() { + createCanvas(displayWidth, displayHeight); + r = random(50, 255); + g = random(0, 200); + b = random(50, 255); +} + +function draw() { + background(r, g, b); + console.log('draw'); +} + +function deviceMoved() { + r = map(accelerationX, -90, 90, 100, 175); + g = map(accelerationY, -90, 90, 100, 200); + b = map(accelerationZ, -90, 90, 100, 200); +} diff --git a/dist/assets/examples/hi/35_Mobile/03_Shake_Ball_Bounce.js b/dist/assets/examples/hi/35_Mobile/03_Shake_Ball_Bounce.js new file mode 100644 index 0000000000..a2ccf26b51 --- /dev/null +++ b/dist/assets/examples/hi/35_Mobile/03_Shake_Ball_Bounce.js @@ -0,0 +1,114 @@ +/* + * @name शेक बॉल बाउंस + * @description एक बॉल क्लास बनाएं, कई ऑब्जेक्ट्स को इंस्टेंट करें, इसे स्क्रीन के चारों ओर घुमाएं, और कैनवास के किनारे को छूने पर बाउंस करें। + * त्वरणX और त्वरण में कुल परिवर्तन के आधार पर शेक घटना का पता लगाएं और पता लगाने के आधार पर वस्तुओं को गति दें या धीमा करें। + */ + +let balls = []; + +let threshold = 30; +let accChangeX = 0; +let accChangeY = 0; +let accChangeT = 0; + +function setup() { + createCanvas(displayWidth, displayHeight); + + for (let i = 0; i < 20; i++) { + balls.push(new Ball()); + } +} + +function draw() { + background(0); + + for (let i = 0; i < balls.length; i++) { + balls[i].move(); + balls[i].display(); + } + + checkForShake(); +} + +function checkForShake() { + // Calculate total change in accelerationX and accelerationY + accChangeX = abs(accelerationX - pAccelerationX); + accChangeY = abs(accelerationY - pAccelerationY); + accChangeT = accChangeX + accChangeY; + // If shake + if (accChangeT >= threshold) { + for (let i = 0; i < balls.length; i++) { + balls[i].shake(); + balls[i].turn(); + } + } + // If not shake + else { + for (let i = 0; i < balls.length; i++) { + balls[i].stopShake(); + balls[i].turn(); + balls[i].move(); + } + } +} + +// Ball class +class Ball { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.xspeed = random(-2, 2); + this.yspeed = random(-2, 2); + this.oxspeed = this.xspeed; + this.oyspeed = this.yspeed; + this.direction = 0.7; + } + + move() { + this.x += this.xspeed * this.direction; + this.y += this.yspeed * this.direction; + } + + // Bounce when touch the edge of the canvas + turn() { + if (this.x < 0) { + this.x = 0; + this.direction = -this.direction; + } else if (this.y < 0) { + this.y = 0; + this.direction = -this.direction; + } else if (this.x > width - 20) { + this.x = width - 20; + this.direction = -this.direction; + } else if (this.y > height - 20) { + this.y = height - 20; + this.direction = -this.direction; + } + } + + // Add to xspeed and yspeed based on + // the change in accelerationX value + shake() { + this.xspeed += random(5, accChangeX / 3); + this.yspeed += random(5, accChangeX / 3); + } + + // Gradually slows down + stopShake() { + if (this.xspeed > this.oxspeed) { + this.xspeed -= 0.6; + } else { + this.xspeed = this.oxspeed; + } + if (this.yspeed > this.oyspeed) { + this.yspeed -= 0.6; + } else { + this.yspeed = this.oyspeed; + } + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/hi/35_Mobile/04_Tilted_3D_Box.js b/dist/assets/examples/hi/35_Mobile/04_Tilted_3D_Box.js new file mode 100644 index 0000000000..45e5b29d63 --- /dev/null +++ b/dist/assets/examples/hi/35_Mobile/04_Tilted_3D_Box.js @@ -0,0 +1,15 @@ +/* + * @name झुका हुआ 3D बॉक्स + * @description बॉक्स को झुकाने के लिए मोबाइल का इस्तेमाल करें + */ +function setup() { + createCanvas(displayWidth, displayHeight, WEBGL); +} + +function draw() { + background(250); + normalMaterial(); + rotateX(accelerationX * 0.01); + rotateY(accelerationY * 0.01); + box(100, 100, 100); +} diff --git a/dist/assets/examples/hi/90_Hello_P5/01_shapes.js b/dist/assets/examples/hi/90_Hello_P5/01_shapes.js new file mode 100644 index 0000000000..7b7702c953 --- /dev/null +++ b/dist/assets/examples/hi/90_Hello_P5/01_shapes.js @@ -0,0 +1,28 @@ +/* + * @name सरल आकार + * @description इस उदाहरण में एक वृत्त, वर्ग, त्रिभुज और एक फूल शामिल है। + */ +function setup() { + // कैनवास बनाएं + createCanvas(720, 400); + background(200); + + // रंग सेट करें + fill(204, 101, 192, 127); + stroke(127, 63, 120); + + // एक चतुर्भुज + rect(40, 120, 120, 40); + // एक दीर्घवृत्त + ellipse(240, 240, 80, 80); + // एक त्रिभुज + triangle(300, 100, 320, 100, 310, 80); + + // एक साधारण फूल के लिए एक डिजाइन + translate(580, 200); + noStroke(); + for (let i = 0; i < 10; i ++) { + ellipse(0, 30, 20, 80); + rotate(PI/5); + } +} diff --git a/dist/assets/examples/hi/90_Hello_P5/02_interactivity.js b/dist/assets/examples/hi/90_Hello_P5/02_interactivity.js new file mode 100644 index 0000000000..9d2c07f1f3 --- /dev/null +++ b/dist/assets/examples/hi/90_Hello_P5/02_interactivity.js @@ -0,0 +1,40 @@ +/* + * @name अन्तरक्रियाशीलता 1 + * @frame 720,425 + * @description जब आप इस पर क्लिक करते हैं तो सर्कल का रंग बदल जाता है। + *

इस उदाहरण को स्थानीय रूप से चलाने के लिए, आपको इसकी आवश्यकता होगी + * p5.dom लाइब्रेरी। + *

+ */ + +// लाल, और रंग के रंग के लिए +let r, g, b; + +function setup() { + createCanvas(720, 400); + // बेतरतीब ढंग से रंग चुनें + r = random(255); + g = random(255); + b = random(255); +} + +function draw() { + background(127); + // एक चक्र बनाएं + strokeWeight(2); + stroke(r, g, b); + fill(r, g, b, 127); + ellipse(360, 200, 200, 200); +} + +// जब उपयोगकर्ता माउस पर क्लिक करता है +function mousePressed() { + // जांचें कि क्या माउस सर्कल के अंदर है + let d = dist(mouseX, mouseY, 360, 200); + if (d < 100) { + // नए यादृच्छिक रंग मान चुनें + r = random(255); + g = random(255); + b = random(255); + } +} diff --git a/dist/assets/examples/hi/90_Hello_P5/03_interactivity.js b/dist/assets/examples/hi/90_Hello_P5/03_interactivity.js new file mode 100644 index 0000000000..ffed52fa11 --- /dev/null +++ b/dist/assets/examples/hi/90_Hello_P5/03_interactivity.js @@ -0,0 +1,29 @@ +/* + * @name अन्तरक्रियाशीलता 2 + * @frame 720,425 + * @description जब आप स्लाइडर को घुमाते हैं तो वृत्त का रंग बदल जाता है। + * आपको शामिल करने की आवश्यकता होगी + * p5.dom लाइब्रेरी + * इस उदाहरण के लिए अपने स्वयं के प्रोजेक्ट में काम करने के लिए। + */ + +// एक HTML रेंज स्लाइडर +let slider; + +function setup() { + createCanvas(720, 400); + // रंग, संतृप्ति और चमक + colorMode(HSB, 255); + // स्लाइडर में 0 और 255 के बीच की सीमा होती है, जिसका शुरुआती मान 127 . होता है + slider = createSlider(0, 255, 127); +} + +function draw() { + background(127); + strokeWeight(2); + + // स्लाइडर के अनुसार रंग सेट करें + stroke(slider.value(), 255, 255); + fill(slider.value(), 255, 255, 127); + ellipse(360, 200, 200, 200); +} \ No newline at end of file diff --git a/dist/assets/examples/hi/90_Hello_P5/04_animate.js b/dist/assets/examples/hi/90_Hello_P5/04_animate.js new file mode 100644 index 0000000000..0657f9e729 --- /dev/null +++ b/dist/assets/examples/hi/90_Hello_P5/04_animate.js @@ -0,0 +1,33 @@ +/* + * @name एनिमेशन + * @description सर्कल चलता है। + */ +// सर्कल कहां है +let x, y; + +function setup() { + createCanvas(720, 400); + // बीच में शुरू होता है + x = width / 2; + y = height; +} + +function draw() { + background(200); + + // एक चक्र बनाएं + stroke(50); + fill(100); + ellipse(x, y, 24, 24); + + // क्षैतिज अक्ष पर बेतरतीब ढंग से झूलना + x = x + random(-1, 1); + // निरंतर गति से ऊपर जा रहा है + y = y - 1; + + // नीचे की ओर रीसेट करें + if (y < 0) { + y = height; + } +} + diff --git a/dist/assets/examples/hi/90_Hello_P5/04_flocking.js b/dist/assets/examples/hi/90_Hello_P5/04_flocking.js new file mode 100644 index 0000000000..8b3b5a9dfd --- /dev/null +++ b/dist/assets/examples/hi/90_Hello_P5/04_flocking.js @@ -0,0 +1,185 @@ +/* + * @name झुंड + * @description क्रेग रेनॉल्ड्स के "फ्लॉकिंग" व्यवहार का प्रदर्शन।
+ * (नियम: सामंजस्य, पृथक्करण, संरेखण।)
+ * natureofcode.com से। + */ +let boids = []; + +function setup() { + createCanvas(720, 400); + + // सिस्टम में बोलियों का एक प्रारंभिक सेट जोड़ें + for (let i = 0; i < 100; i++) { + boids[i] = new Boid(random(width), random(height)); + } +} + +function draw() { + background(51); + // सभी बोड्स चलाएं + for (let i = 0; i < boids.length; i++) { + boids[i].run(boids); + } +} + +// बोईड क्लास +// पृथक्करण, सामंजस्य, संरेखण के तरीके जोड़े गए +class Boid { + constructor(x, y) { + this.acceleration = createVector(0, 0); + this.velocity = p5.Vector.random2D(); + this.position = createVector(x, y); + this.r = 3.0; + this.maxspeed = 3; // अधिकतम गति + this.maxforce = 0.05; // अधिकतम स्टीयरिंग बल + } + + run(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); + } + + // बल त्वरण में जाते हैं + applyForce(force) { + this.acceleration.add(force); + } + + // हम हर बार तीन नियमों के आधार पर एक नया त्वरण जमा करते हैं + flock(boids) { + let sep = this.separate(boids); // पृथक्करण + let ali = this.align(boids); // संरेखण + let coh = this.cohesion(boids); // सामंजस्य + // मनमाने ढंग से इन ताकतों को तौलें + sep.mult(2.5); + ali.mult(1.0); + coh.mult(1.0); + // बल वैक्टर को त्वरण में जोड़ें + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); + } + + // स्थान अपडेट करने की विधि + update() { + // वेग अपडेट करें + this.velocity.add(this.acceleration); + // सीमा गति + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // प्रत्येक चक्र में त्वरण को 0 पर रीसेट करें + this.acceleration.mult(0); + } + + // एक विधि जो एक लक्ष्य की ओर एक स्टीयरिंग बल की गणना और लागू करती है + // स्टीयर = वांछित माइनस वेलोसिटी + seek(target) { + let desired = p5.Vector.sub(target, this.position); // स्थान से लक्ष्य की ओर इशारा करते हुए एक वेक्टर + // वांछित और स्केल को अधिकतम गति के लिए सामान्यीकृत करें + desired.normalize(); + desired.mult(this.maxspeed); + // संचालन = वांछित शून्य वेग + let steer = p5.Vector.sub(desired, this.velocity); + steer.limit(this.maxforce); // अधिकतम स्टीयरिंग बल तक सीमित करें + return steer; + } + + // एक सर्कल के रूप में बोइड ड्रा करें + render() { + fill(127, 127); + stroke(200); + ellipse(this.position.x, this.position.y, 16, 16); + } + + // चारों ओर लपेट दो + borders() { + if (this.position.x < -this.r) this.position.x = width + this.r; + if (this.position.y < -this.r) this.position.y = height + this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height + this.r) this.position.y = -this.r; + } + + // पृथक्करण + // विधि आस-पास के boids के लिए जाँच करता है और दूर चला जाता है + separate(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // सिस्टम में प्रत्येक बोड के लिए, जांचें कि क्या यह बहुत करीब है + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + // यदि दूरी 0 से अधिक है और मनमानी राशि से कम है (0 जब आप स्वयं हों) + if ((d > 0) && (d < desiredseparation)) { + // पड़ोसी से दूर की ओर इशारा करते हुए वेक्टर की गणना करें + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // दूरी से वजन + steer.add(diff); + count++; // कितने का ट्रैक रखें + } + } + // औसत -- कितने से विभाजित करें + if (count > 0) { + steer.div(count); + } + + // जब तक वेक्टर 0 . से बड़ा है + if (steer.mag() > 0) { + // रेनॉल्ड्स को लागू करें: संचालन = वांछित - वेग + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; + } + + // संरेखण + // सिस्टम में प्रत्येक आस-पास के बोड के लिए, औसत वेग की गणना करें + align(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } + } + + // सामंजस्य + // आस-पास के सभी बोड्स के औसत स्थान (अर्थात केंद्र) के लिए, उस स्थान की ओर स्टीयरिंग वेक्टर की गणना करें + cohesion(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // सभी स्थानों को जमा करने के लिए खाली वेक्टर से शुरू करें + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // स्थान जोड़ना + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // स्थान की ओर बढ़ें + } else { + return createVector(0, 0); + } + } +} + diff --git a/dist/assets/examples/hi/90_Hello_P5/05_weather.js b/dist/assets/examples/hi/90_Hello_P5/05_weather.js new file mode 100644 index 0000000000..24f5f25472 --- /dev/null +++ b/dist/assets/examples/hi/90_Hello_P5/05_weather.js @@ -0,0 +1,73 @@ +/* + * @name मौसम + * @frame 720,280 + * @description यह उदाहरण apixu.com से JSON मौसम डेटा प्राप्त करता है। + * आपको शामिल करने की आवश्यकता होगी + * p5.dom लाइब्रेरी + * इस उदाहरण के लिए अपने स्वयं के प्रोजेक्ट में काम करने के लिए। +*/ + +// एक हवा की दिशा वेक्टर +let wind; +// सर्कल की स्थिति +let position; + +function setup() { + createCanvas(720, 200); + // apixu.com से डेटा का अनुरोध करें + let url = 'https://api.apixu.com/v1/current.json?key=513d8003c8b348f1a2461629162106&q=NYC'; + loadJSON(url, gotWeather); + // सर्कल बीच में शुरू होता है + position = createVector(width/2, height/2); + // हवा शुरू होती है (0,0) + wind = createVector(); +} + +function draw() { + background(200); + + // यह खंड हवा की दिशा की ओर इशारा करते हुए एक तीर खींचता है + push(); + translate(32, height - 32); + // हवा के कोण से घुमाएं + rotate(wind.heading() + PI/2); + noStroke(); + fill(255); + ellipse(0, 0, 48, 48); + + stroke(45, 123, 182); + strokeWeight(3); + line(0, -16, 0, 16); + + noStroke(); + fill(45, 123, 182); + triangle(0, -18, -6, -10, 6, -10); + pop(); + + // हवा की दिशा में आगे बढ़ें + position.add(wind); + + stroke(0); + fill(51); + ellipse(position.x, position.y, 16, 16); + + if (position.x > width) position.x = 0; + if (position.x < 0) position.x = width; + if (position.y > height) position.y = 0; + if (position.y < 0) position.y = height; +} + +function gotWeather(weather) { + + // कोण प्राप्त करें (रेडियन में कनवर्ट करें) + let angle = radians(Number(weather.current.wind_degree)); + // हवा की गति प्राप्त करें + let windmag = Number(weather.current.wind_mph); + + // HTML तत्वों के रूप में प्रदर्शित करें + let temperatureDiv = createDiv(floor(weather.current.temp_f) + '°'); + let windDiv = createDiv("WIND " + windmag + " MPH"); + + // एक वेक्टर बनाएं + wind = p5.Vector.fromAngle(angle); +} diff --git a/dist/assets/examples/hi/90_Hello_P5/06_drawing.js b/dist/assets/examples/hi/90_Hello_P5/06_drawing.js new file mode 100644 index 0000000000..336fcde85a --- /dev/null +++ b/dist/assets/examples/hi/90_Hello_P5/06_drawing.js @@ -0,0 +1,132 @@ +/* +* @name ड्राइंग +* @description जनरेटिव पेंटिंग प्रोग्राम। +*/ + +// सभी पथ +let paths = []; +// क्या हम पेंटिंग कर रहे हैं? +let painting = false; +// अगले सर्कल तक कब तक +let next = 0; +// अब हम कहाँ हैं और हम कहाँ थे? +let current; +let previous; + +function setup() { + createCanvas(720, 400); + current = createVector(0,0); + previous = createVector(0,0); +}; + +function draw() { + background(200); + + // यदि यह एक नए बिंदु के लिए समय है + if (millis() > next && painting) { + + // माउस की स्थिति को पकड़ो + current.x = mouseX; + current.y = mouseY; + + // नए कण का बल माउस की गति पर आधारित होता है + let force = p5.Vector.sub(current, previous); + force.mult(0.05); + + // नया कण जोड़ें + paths[paths.length - 1].add(current, force); + + // अगले सर्कल को शेड्यूल करें + next = millis() + random(100); + + // माउस मूल्यों को स्टोर करें + previous.x = current.x; + previous.y = current.y; + } + + // सभी पथ बनाएं + for( let i = 0; i < paths.length; i++) { + paths[i].update(); + paths[i].display(); + } +} + +// इसे शुरू करो +function mousePressed() { + next = 0; + painting = true; + previous.x = mouseX; + previous.y = mouseY; + paths.push(new Path()); +} + +// रुकें +function mouseReleased() { + painting = false; +} + +// पथ कणों की एक सूची है +class Path { + constructor() { + this.particles = []; + this.hue = random(100); + } + + add(position, force) { + // स्थिति, बल और रंग के साथ एक नया कण जोड़ें + this.particles.push(new Particle(position, force, this.hue)); + } + + // डिस्प्ले प्लाथ + update() { + for (let i = 0; i < this.particles.length; i++) { + this.particles[i].update(); + } + } + + // डिस्प्ले प्लाथ + display() { + // पीछे की ओर से लूप करें + for (let i = this.particles.length - 1; i >= 0; i--) { + // अगर हम इसे हटा देते हैं + if (this.particles[i].lifespan <= 0) { + this.particles.splice(i, 1); + // अन्यथा, इसे प्रदर्शित करें + } else { + this.particles[i].display(this.particles[i+1]); + } + } + + } +} + +// पथ के साथ कण +class Particle { + constructor(position, force, hue) { + this.position = createVector(position.x, position.y); + this.velocity = createVector(force.x, force.y); + this.drag = 0.95; + this.lifespan = 255; + } + + update() { + // इसे हटाएं + this.position.add(this.velocity); + // इसे धीमा करें + this.velocity.mult(this.drag); + // इसे फीका करें + this.lifespan--; + } + + // कण ड्रा करें और इसे एक लाइन से कनेक्ट करें + // दूसरे के लिए एक रेखा खींचें + display(other) { + stroke(0, this.lifespan); + fill(0, this.lifespan/2); + ellipse(this.position.x,this.position.y, 8, 8); + // यदि हमें एक रेखा खींचने की आवश्यकता है + if (other) { + line(this.position.x, this.position.y, other.position.x, other.position.y); + } + } +} diff --git a/dist/assets/examples/hi/90_Hello_P5/07_song.js b/dist/assets/examples/hi/90_Hello_P5/07_song.js new file mode 100644 index 0000000000..6f4a741a26 --- /dev/null +++ b/dist/assets/examples/hi/90_Hello_P5/07_song.js @@ -0,0 +1,119 @@ +/* + * @name गीत + * @frame 720, 430 + * @description एक गाना बजाएं। + * आपको शामिल करने की आवश्यकता होगी + * p5.sound + * पुस्तकालय इस उदाहरण के लिए अपने स्वयं के प्रोजेक्ट में काम करने के लिए। + */ +// एक पैमाने के मिडी नोट +let notes = [ 60, 62, 64, 65, 67, 69, 71]; + +// स्वचालित रूप से गाना बजाने के लिए +let index = 0; +let song = [ + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 200, display: "G" }, + { note: 1, duration: 200, display: "A" }, + { note: 2, duration: 200, display: "B" }, + { note: 3, duration: 200, display: "C" }, + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 400, display: "G" }, + { note: 0, duration: 400, display: "G" } +]; +let trigger = 0; +let autoplay = false; +let osc; + +function setup() { + createCanvas(720, 400); + let div = createDiv("Click to play notes or ") + div.id("instructions"); + let button = createButton("play song automatically."); + button.parent("instructions"); + // ट्रिगर स्वचालित रूप से खेल रहा है + button.mousePressed(function() { + if (!autoplay) { + index = 0; + autoplay = true; + } + }); + + // एक त्रिकोण थरथरानवाला + osc = new p5.TriOsc(); + // शुरू करें + osc.start(); + osc.amp(0); +} + +// एक नोट खेलने के लिए एक समारोह +function playNote(note, duration) { + osc.freq(midiToFreq(note)); + // इसे फीका करें + osc.fade(0.5,0.2); + + // यदि हम एक अवधि निर्धारित करते हैं, तो इसे फीका कर दें + if (duration) { + setTimeout(function() { + osc.fade(0,0.2); + }, duration-50); + } +} + +function draw() { + + // यदि हम ऑटोप्ले कर रहे हैं और यह अगले नोट के लिए समय है + if (autoplay && millis() > trigger){ + playNote(notes[song[index].note], song[index].duration); + trigger = millis() + song[index].duration; + // अगले नोट पर जाएं + index ++; + // हम अंत में हैं, ऑटोप्ले करना बंद करें। + } else if (index >= song.length) { + autoplay = false; + } + + + // एक कीबोर्ड बनाएं + + // प्रत्येक कुंजी की चौड़ाई + let w = width / notes.length; + for (let i = 0; i < notes.length; i++) { + let x = i * w; + // यदि माउस कुंजी के ऊपर है + if (mouseX > x && mouseX < x + w && mouseY < height) { + // अगर हम क्लिक कर रहे हैं + if (mouseIsPressed) { + fill(100,255,200); + // या बस लुढ़कना + } else { + fill(127); + } + } else { + fill(200); + } + + // या अगर हम गाना बजा रहे हैं, तो इसे भी हाइलाइट करें + if (autoplay && i === song[index-1].note) { + fill(100,255,200); + } + + // कुंजी ड्रा करें + rect(x, 0, w-1, height-1); + } + +} + +// जब हम क्लिक करते हैं +function mousePressed(event) { + if(event.button == 0 && event.clientX < width && event.clientY < height) { + // माउस को प्रमुख इंडेक्स पर मैप करें + let key = floor(map(mouseX, 0, width, 0, notes.length)); + playNote(notes[key]); + } +} + +// जब हम रिलीज करते हैं तो इसे फीका कर दें +function mouseReleased() { + osc.fade(0,0.5); +} diff --git a/dist/assets/examples/ko/00_Structure/00_Statements_and_Comments.js b/dist/assets/examples/ko/00_Structure/00_Statements_and_Comments.js new file mode 100644 index 0000000000..36a4d268b6 --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/00_Statements_and_Comments.js @@ -0,0 +1,22 @@ +/* + * @name 스테이트멘트와 코멘트 + * @description 스테이트멘트는 프로그램을 형성하는 작은 단위의 문장입니다. 스테이트멘트의 끝은 ";" (세미콜론)를 사용합니다. + * 이 것을 "스테이트멘트 종결 기호" ("statement * terminator")이라고 합니다. 반면에 코멘트는 + * 더욱 편리한 이해를 위해 사용하는 일종의 메모입니다. 코멘트는 두 개의 슬래시 ("//")로 시작합니다. + * (https://processing.org/examples/statementscomments.html에서 옮김) + */ + +// createCanvas 함수는 컴퓨터에게 만들 윈도의 크기를 지정하는 함수 스테이트멘트입니다. +// 함수 스테이트멘트는 0개 이상의 인자 (parameter)가 있읍니다. +// 인자들는 함수에 사용되는 데이터며, 인자들의 값으로 컴퓨터의 행동을 지정합니다. + +function setup() { + createCanvas(710, 400); +} + +// background 함수는 컴퓨터에게 만들 위토의 배경색 (또는 회색도)를 +// 지정하는 함수 스테이트멘트입니다. +function draw() { + background(204, 153, 0); +} + diff --git a/dist/assets/examples/ko/00_Structure/01_Coordinates.js b/dist/assets/examples/ko/00_Structure/01_Coordinates.js new file mode 100644 index 0000000000..a356a75f66 --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/01_Coordinates.js @@ -0,0 +1,34 @@ +/* + * @name 좌표 + * @description 모든 도형들은 좌표값으로 지정된 화면 위치에 나타납니다. + * 모든 좌표값은 원점으로부터의 거리를 픽셀 단위로 측정합니다. + * 원점 [0,0]는 화면 좌측 상단의 좌표이며, 우측 하단의 좌표는 [너비-1, 높이-1]에 해당합니다. + */ + +function setup() { + // 캔버스 크기를 너비 720픽셀, 높이 720픽셀로 설정 + createCanvas(720, 400); +} + +function draw() { + // 배경색을 검정색(0)으로 지정, noFill()로 면채우기 기능 해제 + background(0); + noFill(); + + // point()의 괄호 안 두 인수로 좌표값 지정 + // 첫번째 인수는 x값을, 두번째 인수는 y값 의미 + stroke(255); + point(width * 0.5, height * 0.5); + point(width * 0.5, height * 0.25); + + // 좌표를 활용해 점 뿐 아니라 모든 도형을 그릴 수 있습니다. + // 각 함수별 괄호에 적힌 매개변수들은 각기 다른 목적을 위해 사용됩니다. + // 예를들어 line()함수에 쓰인 처음 두 매개변수들은 각각 첫번째 그리고 두번째 끝점을 지정합니다. + stroke(0, 153, 255); + line(0, height * 0.33, width, height * 0.33); + + // rect()함수의 처음 두 매개변수는 상단 모서리의 좌표값을 의미하고, + // 그 다음 두 매개변수는 너비와 높이를 지정합니다. + stroke(255, 153, 0); + rect(width * 0.25, height * 0.1, width * 0.5, height * 0.8); +} diff --git a/dist/assets/examples/ko/00_Structure/02_Width_and_Height.js b/dist/assets/examples/ko/00_Structure/02_Width_and_Height.js new file mode 100644 index 0000000000..76eb7551a6 --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/02_Width_and_Height.js @@ -0,0 +1,19 @@ +/* + * @name 너비와 높이 + * @description '너비(width)'와 '높이(height)' 변수들은 createCanvas() 함수에 따라 + * 정의된, 윈도우 화면의 너비 및 높이 값을 담습니다. + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(127); + noStroke(); + for (let i = 0; i < height; i += 20) { + fill(129, 206, 15); + rect(0, i, width, 10); + fill(255); + rect(i, 0, 10, height); + } +} diff --git a/dist/assets/examples/ko/00_Structure/03_Setup_and_Draw.js b/dist/assets/examples/ko/00_Structure/03_Setup_and_Draw.js new file mode 100644 index 0000000000..d91d046988 --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/03_Setup_and_Draw.js @@ -0,0 +1,25 @@ +/* + * @name 설정하고 그리기 + * @description draw()함수 속의 코드들은 위에서 아래 방향으로 + * 실행되며, 프로그램이 멈출 때까지 계속해서 반복됩니다. + */ +let y = 100; + +// setup()함수 속 선언문은 프로그램 시작시 한번 실행됩니다. +function setup() { + // createCanvas가 그 첫 선언문입니다. + createCanvas(720, 400); + stroke(255); // 선색을 흰색(255)으로 지정 + frameRate(30); +} +// draw() 함수 속 선언문들은 프로그램이 멈출 때까지 계속해서 실행됩니다. +// 각 선언문은 위에서 아래 방향으로 순차적으로 실행되며, +// 마지막 선언문 실행을 마친 뒤에는 상단의 첫 선언문으로 되돌아갑니다. +function draw() { + background(0); // 배경색을 검정색(0)으로 지정 + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/ko/00_Structure/04_No_Loop.js b/dist/assets/examples/ko/00_Structure/04_No_Loop.js new file mode 100644 index 0000000000..2f50b6f2f5 --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/04_No_Loop.js @@ -0,0 +1,28 @@ +/* + * @name 루프 중단 + * @description noLoop()함수는 draw()함수를 반복없이 단 한번만 실행되도록 합니다. + * noLoop()를 호출하지 않는다면 draw()함수는 계속해서 반복 실행될 것입니다. + */ +let y; + +// setup()함수 속 선언문은 프로그램 시작시 한번 실행됩니다. +function setup() { + // createCanvas가 그 첫 선언문입니다. + createCanvas(720, 400); + stroke(255); // 윤곽선을 흰색(255)으로 지정 + noLoop(); + + y = height * 0.5; +} + +// 아래의 draw()함수에 포함된 선언문들은 프로그램 실행이 멈출 때까지 계속해서 실행됩니다. +// 각 선언문은 위에서 아래 방향으로 순차적으로 실행되며, +// 마지막 선언문 실행을 마친 뒤에는 상단의 첫 선언문으로 되돌아갑니다. +function draw() { + background(0); // 배경색을 검정색(0)으로 지정 + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/ko/00_Structure/05_Loop.js b/dist/assets/examples/ko/00_Structure/05_Loop.js new file mode 100644 index 0000000000..bbf684de22 --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/05_Loop.js @@ -0,0 +1,24 @@ +/* + * @name 루프 + * @description draw()함수 속 코드들은 위에서 아래 방향으로 + * 실행되며, 이는 프로그램이 멈출 때까지 계속해서 반복됩니다. + */ +let y = 100; + +// setup()함수 속 선언문은 프로그램 시작시 한번 실행됩니다. +function setup() { + createCanvas(720, 400); // 첫 선언문으로 캔버스 크기를 지정합니다. + stroke(255); // 선색을 흰색(255)로 지정 + frameRate(30); +} +// 아래의 draw()함수 속 선언문들은 프로그램 실행이 멈출 때까지 계속해서 실행됩니다. +// 각 선언문은 위에서 아래 방향으로 순차적으로 실행되며, +// 마지막 선언문 실행을 마친 뒤에는 상단의 첫 선언문으로 되돌아갑니다. +function draw() { + background(0); // 배경색을 검정색(0)으로 지정 + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/ko/00_Structure/06_Redraw.js b/dist/assets/examples/ko/00_Structure/06_Redraw.js new file mode 100644 index 0000000000..2fd28df755 --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/06_Redraw.js @@ -0,0 +1,31 @@ +/* + * @name 다시 그리기 + * @description redraw()함수는 draw()함수를 재실행합니다. + * 이 예제에서 draw()는 마우스가 클릭될 때마다 매번 재실행됩니다. + */ + +let y; + +// setup()함수 속 선언문들은 프로그램 시작시 한번 실행됩니다. +function setup() { + createCanvas(720, 400); + stroke(255); + noLoop(); + y = height * 0.5; +} + +// 아래의 draw()함수에 포함된 선언문들은 프로그램 실행이 멈출 때까지 계속해서 실행됩니다. +// 각 선언문은 위에서 아래 방향으로 순차적으로 실행되며, +// 마지막 선언문 실행을 마친 뒤에는 상단의 첫 선언문으로 되돌아갑니다. +function draw() { + background(0); + y = y - 4; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} + +function mousePressed() { + redraw(); +} diff --git a/dist/assets/examples/ko/00_Structure/07_Functions.js b/dist/assets/examples/ko/00_Structure/07_Functions.js new file mode 100644 index 0000000000..47f31593aa --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/07_Functions.js @@ -0,0 +1,27 @@ +/* + *@name 그 외 함수들 + *@description 각 drawTarget()함수로 과녁판 형상의 도형 여러개를 쉽게 만들 수 있습니다. + *호출된 drawTarget()함수들은 각기 다른 과녁판 도형의 위치, 크기 그리고 고리 개수를 지정합니다. + */ + +function setup() { + createCanvas(720, 400); + background(51); + noStroke(); + noLoop(); +} + +function draw() { + drawTarget(width * 0.25, height * 0.4, 200, 4); + drawTarget(width * 0.5, height * 0.5, 300, 10); + drawTarget(width * 0.75, height * 0.3, 120, 6); +} + +function drawTarget(xloc, yloc, size, num) { + const grayvalues = 255 / num; + const steps = size / num; + for (let i = 0; i < num; i++) { + fill(i * grayvalues); + ellipse(xloc, yloc, size - i * steps, size - i * steps); + } +} diff --git a/dist/assets/examples/ko/00_Structure/08_Recursion.js b/dist/assets/examples/ko/00_Structure/08_Recursion.js new file mode 100644 index 0000000000..9833a01bae --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/08_Recursion.js @@ -0,0 +1,27 @@ +/* + *@name 재귀 함수 + *@description 재귀 함수는 자기 자신을 다시 호출하는 함수를 말합니다. + * drawCircle()함수가 블록 말미에 그 자신을 다시 호출하는 것을 볼 수 있습니다. + * 이 경우, drawCircle()함수의 변수인 "level"의 값이 1과 같아질 때까지 계속해서 재호출됩니다. + */ + +function setup() { + createCanvas(720, 400); + noStroke(); + noLoop(); +} + +function draw() { + drawCircle(width / 2, 280, 6); +} + +function drawCircle(x, radius, level) { + const tt = (126 * level) / 4.0; + fill(tt); + ellipse(x, height / 2, radius * 2, radius * 2); + if (level > 1) { + level = level - 1; + drawCircle(x - radius / 2, radius / 2, level); + drawCircle(x + radius / 2, radius / 2, level); + } +} diff --git a/dist/assets/examples/ko/00_Structure/09_Create_Graphics.js b/dist/assets/examples/ko/00_Structure/09_Create_Graphics.js new file mode 100644 index 0000000000..36b3ab0ae5 --- /dev/null +++ b/dist/assets/examples/ko/00_Structure/09_Create_Graphics.js @@ -0,0 +1,29 @@ +/* + * @name 그래픽 만들기 + * @description 새로운 p5.Renderer 객체를 만들고 반환합니다. + * 아래의 클래스는 특정 사각 스크린의 바깥 영역에 그래픽 버퍼를 만드는 데에 사용됩니다. + * 두 인수들은 사각 스크린의 너비와 높이값을 픽셀 단위로 각각 지정합니다. + */ + +let pg; + +function setup() { + createCanvas(710, 400); + pg = createGraphics(400, 250); +} + +function draw() { + fill(0, 12); + rect(0, 0, width, height); + fill(255); + noStroke(); + ellipse(mouseX, mouseY, 60, 60); + + pg.background(51); + pg.noFill(); + pg.stroke(255); + pg.ellipse(mouseX - 150, mouseY - 75, 60, 60); + + //image() 선언문으로 사각 스크린 바깥에 위치한 그래픽 버퍼를 그립니다. + image(pg, 150, 75); +} diff --git a/dist/assets/examples/ko/01_Form/00_Points_and_Lines.js b/dist/assets/examples/ko/01_Form/00_Points_and_Lines.js new file mode 100644 index 0000000000..a7e1028623 --- /dev/null +++ b/dist/assets/examples/ko/01_Form/00_Points_and_Lines.js @@ -0,0 +1,36 @@ +/* + * @name 점과 선 + * @description 점과 선을 활용하여 기본적인 기하 형태를 그릴 수 있습니다. + * 도형의 크기 조정을 위해 변수인 'd'값을 바꿔보세요. + * 4개의 변수들은 d값을 기준으로 위치값을 설정합니다. + */ +function setup() { + let d = 70; + let p1 = d; + let p2 = p1 + d; + let p3 = p2 + d; + let p4 = p3 + d; + + // 캔버스 크기를 너비 720픽셀, 높이 720픽셀로 설정 + createCanvas(720, 400); + background(0); + noSmooth(); + + translate(140, 0); + + // 회색의 사각형 그리기 + stroke(153); + line(p3, p3, p2, p3); + line(p2, p3, p2, p2); + line(p2, p2, p3, p2); + line(p3, p2, p3, p3); + + // 흰색 점들 그리기 + stroke(255); + point(p1, p1); + point(p1, p3); + point(p2, p4); + point(p3, p1); + point(p4, p2); + point(p4, p4); +} diff --git a/dist/assets/examples/ko/01_Form/01_Shape_Primitives.js b/dist/assets/examples/ko/01_Form/01_Shape_Primitives.js new file mode 100644 index 0000000000..3a6a3d26e3 --- /dev/null +++ b/dist/assets/examples/ko/01_Form/01_Shape_Primitives.js @@ -0,0 +1,31 @@ +/* + * @name 기본 조형 + * @description 기본 조형을 그리는 함수로는 triangle(), + * rect(), quad(), ellipse(), 그리고 arc()가 있습니다. 사각형은 rect()로, + * 원형은 ellipse()로 만들 수 있습니다. 도형의 위치와 크기 조정을 위해 + * 각 함수들의 괄호 안 인수들을 반드시 지정해야합니다. + */ +function setup() { + // 캔버스 크기를 너비 720픽셀, 높이 720픽셀로 설정 + createCanvas(720, 400); + background(0); + noStroke(); + + fill(204); + triangle(18, 18, 18, 360, 81, 360); + + fill(102); + rect(81, 81, 63, 63); + + fill(204); + quad(189, 18, 216, 18, 216, 360, 144, 360); + + fill(255); + ellipse(252, 144, 72, 72); + + fill(204); + triangle(288, 18, 351, 360, 288, 360); + + fill(255); + arc(479, 300, 280, 280, PI, TWO_PI); +} diff --git a/dist/assets/examples/ko/01_Form/02_Pie_Chart.js b/dist/assets/examples/ko/01_Form/02_Pie_Chart.js new file mode 100644 index 0000000000..248006533f --- /dev/null +++ b/dist/assets/examples/ko/01_Form/02_Pie_Chart.js @@ -0,0 +1,33 @@ +/* + * @name 파이형 차트 + * @description arc()함수를 사용하여 배열에 저장된 데이터로 파이형 차트를 생성해보세요. + */ +let angles = [30, 10, 45, 35, 60, 38, 75, 67]; + +function setup() { + createCanvas(720, 400); + noStroke(); + noLoop(); // 프로그램 시작시 한 번 실행 뒤 멈추기 +} + +function draw() { + background(100); + pieChart(300, angles); +} + +function pieChart(diameter, data) { + let lastAngle = 0; + for (let i = 0; i < data.length; i++) { + let gray = map(i, 0, data.length, 0, 255); + fill(gray); + arc( + width / 2, + height / 2, + diameter, + diameter, + lastAngle, + lastAngle + radians(angles[i]) + ); + lastAngle += radians(angles[i]); + } +} diff --git a/dist/assets/examples/ko/01_Form/03_Regular_Polygon.js b/dist/assets/examples/ko/01_Form/03_Regular_Polygon.js new file mode 100644 index 0000000000..0fd70871c0 --- /dev/null +++ b/dist/assets/examples/ko/01_Form/03_Regular_Polygon.js @@ -0,0 +1,42 @@ +/* + * @name 정다각형 + * @description 가장 좋아하는 정다각형이 있나요? 오각형? 육각형? 칠각형? 아니면, 이십각형은요? + * 이 예제에서 소개하는 polygon()함수는 그 어떠한 정다각형도 그릴 수 있습니다. + * draw()함수 내에 호출된 polygon() 안에 다양한 숫자를 넣어 탐구해보세요. + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + polygon(0, 0, 82, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + polygon(0, 0, 80, 20); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + polygon(0, 0, 70, 7); + pop(); +} + +function polygon(x, y, radius, npoints) { + let angle = TWO_PI / npoints; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius; + let sy = y + sin(a) * radius; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/ko/01_Form/04_Star.js b/dist/assets/examples/ko/01_Form/04_Star.js new file mode 100644 index 0000000000..7e98f1d2b4 --- /dev/null +++ b/dist/assets/examples/ko/01_Form/04_Star.js @@ -0,0 +1,45 @@ +/* + * @name 별모양 + * @description 이 예제에서 소개하는 star()함수는 여러가지 다양한 모양을 그립니다. + * draw()함수 내에 호출된 polygon() 안에 다양한 숫자를 넣어 탐구해보세요. + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + star(0, 0, 5, 70, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + star(0, 0, 80, 100, 40); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + star(0, 0, 30, 70, 5); + pop(); +} + +function star(x, y, radius1, radius2, npoints) { + let angle = TWO_PI / npoints; + let halfAngle = angle / 2.0; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius2; + let sy = y + sin(a) * radius2; + vertex(sx, sy); + sx = x + cos(a + halfAngle) * radius1; + sy = y + sin(a + halfAngle) * radius1; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/ko/01_Form/05_Triangle_Strip.js b/dist/assets/examples/ko/01_Form/05_Triangle_Strip.js new file mode 100644 index 0000000000..62308eea3d --- /dev/null +++ b/dist/assets/examples/ko/01_Form/05_Triangle_Strip.js @@ -0,0 +1,38 @@ +/* + * @name 삼각형 고리 + * @description 이라 그린버그(Ira Greenberg) 제작 예제. vertex()함수와 + * beginShape(TRIANGLE_STRIP) 모드를 이용하여 닫힌 고리를 하나 생성하세요. + * outsideRadius와 insideRadius 변수를 이용하여 각 고리의 지름(radius)을 조정할 수 있습니다. + */ +let x; +let y; +let outsideRadius = 150; +let insideRadius = 100; + +function setup() { + createCanvas(720, 400); + background(204); + x = width / 2; + y = height / 2; +} + +function draw() { + background(204); + + let numPoints = int(map(mouseX, 0, width, 6, 60)); + let angle = 0; + let angleStep = 180.0 / numPoints; + + beginShape(TRIANGLE_STRIP); + for (let i = 0; i <= numPoints; i++) { + let px = x + cos(radians(angle)) * outsideRadius; + let py = y + sin(radians(angle)) * outsideRadius; + angle += angleStep; + vertex(px, py); + px = x + cos(radians(angle)) * insideRadius; + py = y + sin(radians(angle)) * insideRadius; + vertex(px, py); + angle += angleStep; + } + endShape(); +} diff --git a/dist/assets/examples/ko/01_Form/06_Bezier.js b/dist/assets/examples/ko/01_Form/06_Bezier.js new file mode 100644 index 0000000000..8e779bb045 --- /dev/null +++ b/dist/assets/examples/ko/01_Form/06_Bezier.js @@ -0,0 +1,26 @@ +/* + * @name 베지어 곡선 + * @description bezier()함수의 처음 두 매개변수들은 각각 곡선의 시작점과 끝점을 지정합니다. + * 중간의 인수들은 곡선의 모양을 조정하는 '조정점(control point)'들입니다. + */ +function setup() { + createCanvas(720, 400); + stroke(255); + noFill(); +} + +function draw() { + background(0); + for (let i = 0; i < 200; i += 20) { + bezier( + mouseX - i / 2.0, + 40 + i, + 410, + 20, + 440, + 300, + 240 - i / 16.0, + 300 + i / 8.0 + ); + } +} diff --git a/dist/assets/examples/ko/01_Form/07_3D_Primitives.js b/dist/assets/examples/ko/01_Form/07_3D_Primitives.js new file mode 100644 index 0000000000..06204637be --- /dev/null +++ b/dist/assets/examples/ko/01_Form/07_3D_Primitives.js @@ -0,0 +1,30 @@ +/* + * @name 3D 기본 조형 + * @frame 720,400 (optional) + * @description 3D 객체를 합성 공간 속에 수학적으로 배치하기. + * box()와 sphere()함수는 최소 한 개의 매개변수를 사용하여 객체의 크기를 조정합니다. + * 도형의 위치는 translate()함수를 통해 조정할 수 있습니다. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(100); + + noStroke(); + fill(50); + push(); + translate(-275, 175); + rotateY(1.25); + rotateX(-0.9); + box(100); + pop(); + + noFill(); + stroke(255); + push(); + translate(500, height * 0.35, -200); + sphere(300); + pop(); +} diff --git a/dist/assets/examples/ko/01_Form/08_Trig_Wheels_and_Pie_Chart.js b/dist/assets/examples/ko/01_Form/08_Trig_Wheels_and_Pie_Chart.js new file mode 100644 index 0000000000..0f0b07a2fa --- /dev/null +++ b/dist/assets/examples/ko/01_Form/08_Trig_Wheels_and_Pie_Chart.js @@ -0,0 +1,85 @@ +/* + * @name 단위원과 파이 차트 + * @frame 400,400 + * @description 해리스 교수 ( + Prof WM Harris,)의 기고 예시, '삼각함수 컬러 휠 만드는 법과 인구 연령 데이터로 파이차트 그리기' + (How to create a trig color wheel and a visualization of a population age data as a pie chart). +
+ 켄바스 설정, 삼각함수 컬러 휠, 휠 조각 그리기와 파이차트를 위한 함수르 만듭니다. 컬러 휠 조각들의 크기와 + 색상범위 (color range)를 정합니다. 파이차트는 값에 따라 색깔로 나누어지는 반면, 삼각함수 컬러 휠은 조각의 수가 + 고정되어있고 색상 범위로 나누어집니다. +*/ + +function setup() { + createCanvas(400, 400); + colorMode(HSB); + angleMode(DEGREES); + + //색깔 컬러 휠 중점을 위한 + let x = width / 2; + let y = height / 2 + 100; + colorWheel(x, y, 100); //slide 11 + + noStroke(); + pieChartPop(200, 100); //slide 12 +} + +//**** slide 12 pie chart trig demo +function pieChartPop(x, y) { + let [total, child, young, adult, senior, elder] = [577, 103, 69, + 122, 170, 113 + ]; + let startValue = 0; + let range = 0; + + //child slice + range = child / total; + drawSlice("blue", x, y, 200, startValue, startValue + range); + startValue += range; + //young slice + range = young / total; + drawSlice("orange", x, y, 200, startValue, startValue + range); + startValue += range; + //adult slice + range = adult / total; + drawSlice("green", x, y, 200, startValue, startValue + range); + startValue += range; + //senior slice + range = senior / total; + drawSlice("tan", x, y, 200, startValue, startValue + range); + startValue += range; + //elder slice + range = elder / total; + drawSlice("pink", x, y, 200, startValue, startValue + range); + startValue += range; + +} + +/** + * drawSlice - draw colored arc based on angle percentages. slide 13 + * Adjust angles so that 0% starts at top (actually -90). + * @param {color} fColor - fill color + * @param {number} x - center x + * @param {number} y - center y + * @param {number} d - diameter + * @param {float} percent1 - starting percentage + * @param {float} percent2 - ending percentage + */ +function drawSlice(fColor, x, y, d, percent1, percent2) { + fill(fColor); + arc(x, y, d, d, -90 + percent1 * 360, -90 + percent2 * 360); +} + +//**** slide 11 trig demo +function colorWheel(x, y, rad) { + strokeWeight(10); + strokeCap(SQUARE); + + //Iterate 360 degrees of lines, +10deg per turn + for (let a = 0; a < 360; a += 10) { + stroke(a, 150, 200); //hue based on a + //radius is 100, angle is a degrees + line(x, y, x + rad * cos(a), + y + rad * sin(a)); + } +} diff --git a/dist/assets/examples/ko/02_Data/00_Variables.js b/dist/assets/examples/ko/02_Data/00_Variables.js new file mode 100644 index 0000000000..faeb3bc6c3 --- /dev/null +++ b/dist/assets/examples/ko/02_Data/00_Variables.js @@ -0,0 +1,36 @@ +/* + * @name 변수 + * @description 변수는 값을 저장하는 데에 사용됩니다. 예제의 변수값을 바꿔 구성을 바꿔보세요. + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(153); + strokeWeight(4); + strokeCap(SQUARE); + + let a = 50; + let b = 120; + let c = 180; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); +} diff --git a/dist/assets/examples/ko/02_Data/01_True_and_False.js b/dist/assets/examples/ko/02_Data/01_True_and_False.js new file mode 100644 index 0000000000..4ebc9f2224 --- /dev/null +++ b/dist/assets/examples/ko/02_Data/01_True_and_False.js @@ -0,0 +1,30 @@ +/* + * @name 참과 거짓 + * @description 불리언(Boolean) 변수는 오직 'true(참)'과 'false(거짓)'이라는 두 개의 값만 갖습니다. + * 불리언과 함께 제어문을 사용하여 프로그램의 흐름을 조정하는 것이 일반적인 방식입니다. + * 이 예제에서는, b값이 'true(참)'일 때 세로선들이 그려지고 + * b값이 'false(거짓)'일 때 가로선들이 그려집니다. + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + + let b = false; + let d = 20; + let middle = width / 2; + + for (let i = d; i <= width; i += d) { + b = i < middle; + + if (b === true) { + // 세로선 + line(i, d, i, height - d); + } + + if (b === false) { + // 가로선 + line(middle, i - middle + d, width - d, i - middle + d); + } + } +} diff --git a/dist/assets/examples/ko/02_Data/03_Variable_Scope.js b/dist/assets/examples/ko/02_Data/03_Variable_Scope.js new file mode 100644 index 0000000000..a9cd27632c --- /dev/null +++ b/dist/assets/examples/ko/02_Data/03_Variable_Scope.js @@ -0,0 +1,45 @@ +/* + * @name 변수 범위 + * @description 변수는 '전역(global) 변수'로서 선언되거나, 그 적용 범위를 조정하여 '지역(local) 변수'로 사용할 수 있습니다. + * 예를 들어, setup() 및 draw()함수 안에 선언된 변수들은 해당 함수들의 범위 내에서만 사용되는 '지역 변수'가 됩니다. + * '전역 변수'의 경우, setup() 및 draw()함수 범위 외에서도 사용 가능합니다. + * 어떤 함수의 '지역 변수'가 '전역 변수'와 동일한 이름으로 선언된 경우, + * 이 변수는 해당 함수에 한해 지역 변수로서 처리됩니다. + */ +let a = 80; // 전역 변수 "a" 생성하기 + +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + noLoop(); +} + +function draw() { + // 전역 변수 a를 사용하여 선 그리기 + line(a, 0, a, height); + + // 반복문 안에 지역 변수 a를 사용하기 + for (let a = 120; a < 200; a += 3) { + line(a, 0, a, height); + } + + // 사용자가 만든 함수 drawAnotherLine() 호출하기 + drawAnotherLine(); + + // 사용자가 만든 함수 drawYetAnotherLine() 호출하기 + drawYetAnotherLine(); +} + +function drawAnotherLine() { + // 이 함수에 대한 지역 변수로서 새로운 a 선언하기 + let a = 320; + // 지역 변수 a를 사용하여 선 그리기 line(a, 0, a, height); + line(a, 0, a, height); +} + +function drawYetAnotherLine() { + // 새로운 지역 변수 a를 선언하지 않았으므로, + // 이 선은 위에서 선언된 전역 변수 a(값 80)를 사용하여 그려집니다. + line(a + 3, 0, a + 3, height); +} diff --git a/dist/assets/examples/ko/02_Data/04_Numbers.js b/dist/assets/examples/ko/02_Data/04_Numbers.js new file mode 100644 index 0000000000..43d081fa5f --- /dev/null +++ b/dist/assets/examples/ko/02_Data/04_Numbers.js @@ -0,0 +1,30 @@ +/* + * @name 숫자값 + * @frame 720,400 + * @description 숫자값은 소수점과 함께, 또는 소수점없이 사용할 수 있습니다. + * 보통 "int"라 불리는 정수(integer)는 소수점이 없는 숫자를 말합니다. + * "float"는 소수점 이하 자릿수를 갖는 부동소수점 숫자를 말합니다. + */ +let a = 0; // "a"를 숫자형 전역 변수로 선언 +let b = 0; // "b"를 숫자형 전역 변수로 선언 + +function setup() { + createCanvas(720, 400); + stroke(255); +} + +function draw() { + background(0); + + a = a + 1; // a를 정수 단위로 증가 + b = b + 0.2; // b를 부동소수점수 단위로 증가 + line(a, 0, a, height / 2); + line(b, height / 2, b, height); + + if (a > width) { + a = 0; + } + if (b > width) { + b = 0; + } +} diff --git a/dist/assets/examples/ko/03_Arrays/00_Array.js b/dist/assets/examples/ko/03_Arrays/00_Array.js new file mode 100644 index 0000000000..4f624aaaa8 --- /dev/null +++ b/dist/assets/examples/ko/03_Arrays/00_Array.js @@ -0,0 +1,42 @@ +/* + * @name 배열 + * @description 배열은 데이터의 리스트를 말합니다. 배열 속 각 데이터는 + * 배열에서의 위치를 나타내는 색인(index) 번호로 식별됩니다. 배열의 시작은 0을 기준으로 합니다. + * 따라서, 배열의 첫 번째 데이터는 [0]이고 두 번째 데이터는 [1]로 식별됩니다. + * 이 예제에서는 "coswave"라는 배열을 만들고, 이를 코사인 값으로 채웁니다. + * 데이터는 실행 화면상 세 가지의 다른 방법으로 표현됩니다. + */ +let coswave = []; + +function setup() { + createCanvas(720, 360); + for (let i = 0; i < width; i++) { + let amount = map(i, 0, width, 0, PI); + coswave[i] = abs(cos(amount)); + } + background(255); + noLoop(); +} + +function draw() { + let y1 = 0; + let y2 = height / 3; + for (let i = 0; i < width; i += 3) { + stroke(coswave[i] * 255); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = y1 + y1; + for (let i = 0; i < width; i += 3) { + stroke((coswave[i] * 255) / 4); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = height; + for (let i = 0; i < width; i += 3) { + stroke(255 - coswave[i] * 255); + line(i, y1, i, y2); + } +} diff --git a/dist/assets/examples/ko/03_Arrays/01_Array_2d.js b/dist/assets/examples/ko/03_Arrays/01_Array_2d.js new file mode 100644 index 0000000000..1d7885502d --- /dev/null +++ b/dist/assets/examples/ko/03_Arrays/01_Array_2d.js @@ -0,0 +1,37 @@ +/* + * @name 2D 배열 + * @description 2차원(2D) 배열 작성을 위한 구문입니다. + * 2D 배열의 값은 두 개의 색인(index)값을 통해 가져올 수 있습니다. + * 2D 배열은 이미지를 저장하는 데에 유용합니다. + * 이 예제에서 각 점의 색상은 이미지 중심으로부터의 거리에 따라 지정됩니다. + */ +let distances = []; +let maxDistance; +let spacer; + +function setup() { + createCanvas(720, 360); + maxDistance = dist(width / 2, height / 2, width, height); + for (let x = 0; x < width; x++) { + distances[x] = []; // 중첩 배열 만들기 + for (let y = 0; y < height; y++) { + let distance = dist(width / 2, height / 2, x, y); + distances[x][y] = (distance / maxDistance) * 255; + } + } + spacer = 10; + noLoop(); // 한번 실행 후 멈추기 +} + +function draw() { + background(0); + // 이 함수에 내장된 반복문은 앞서 선언된 spacer변수에 따라 배열값 사이의 간격을 생성하게 됩니다. + // 따라서, 이 함수로 그려진 것보다 더 많은 값이 배열에 있는 셈입니다. + // spacer변수의 값을 변경하여 점들 간의 밀도를 조정해보세요. + for (let x = 0; x < width; x += spacer) { + for (let y = 0; y < height; y += spacer) { + stroke(distances[x][y]); + point(x + spacer / 2, y + spacer / 2); + } + } +} diff --git a/dist/assets/examples/ko/03_Arrays/02_Array_Objects.js b/dist/assets/examples/ko/03_Arrays/02_Array_Objects.js new file mode 100644 index 0000000000..70ba8f8073 --- /dev/null +++ b/dist/assets/examples/ko/03_Arrays/02_Array_Objects.js @@ -0,0 +1,71 @@ +/* + * @name 객체 배열 + * @description 사용자가 정의한 객체 배열을 만듭니다. + */ + +class Module { + constructor(xOff, yOff, x, y, speed, unit) { + this.xOff = xOff; + this.yOff = yOff; + this.x = x; + this.y = y; + this.speed = speed; + this.unit = unit; + this.xDir = 1; + this.yDir = 1; + } + + // 사용자 정의한 메소드를 통해 변수들을 업데이트합니다. + update() { + this.x = this.x + this.speed * this.xDir; + if (this.x >= this.unit || this.x <= 0) { + this.xDir *= -1; + this.x = this.x + 1 * this.xDir; + this.y = this.y + 1 * this.yDir; + } + if (this.y >= this.unit || this.y <= 0) { + this.yDir *= -1; + this.y = this.y + 1 * this.yDir; + } + } + + // 사용자가 정의한 메소드를 통해 객체를 그립니다. + draw() { + fill(255); + ellipse(this.xOff + this.x, this.yOff + this.y, 6, 6); + } +} + +let unit = 40; +let count; +let mods = []; + +function setup() { + createCanvas(720, 360); + noStroke(); + let wideCount = width / unit; + let highCount = height / unit; + count = wideCount * highCount; + + let index = 0; + for (let y = 0; y < highCount; y++) { + for (let x = 0; x < wideCount; x++) { + mods[index++] = new Module( + x * unit, + y * unit, + unit / 2, + unit / 2, + random(0.05, 0.8), + unit + ); + } + } +} + +function draw() { + background(0); + for (let i = 0; i < count; i++) { + mods[i].update(); + mods[i].draw(); + } +} diff --git a/dist/assets/examples/ko/03_Arrays/03_Walk_Over_2dArray.js b/dist/assets/examples/ko/03_Arrays/03_Walk_Over_2dArray.js new file mode 100644 index 0000000000..e5577e7383 --- /dev/null +++ b/dist/assets/examples/ko/03_Arrays/03_Walk_Over_2dArray.js @@ -0,0 +1,85 @@ +/* + * @name Walk Over 2dArray + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to display 2D array contents on the canvas +using regular for and for-of loops in multiple different ways.
+ A function is created for the canvas, the 2D + array (Friend Array) is initialized and walked over using nested + loops in different ways. Variables x and y are used to place the + array item on the canvas in the form of 2D array. + The final nested loop is used to initialize 2D + array (Fish Array) with random Integers (fish ages). +*/ + + +//"use strict"; //catch some common coding errors + + +/** + * setup : + */ +function setup() { + createCanvas(400, 600); + //create 2D array, slide 4 + let friendArray = [ + ["Nona", "mac & cheese", "orange", "Eid al-fitr"], + ["Marylin", "ice cream", "blue", "Halloween"], + ["Rashaad", "garbage plates", "turquoise", "Christmas"], + ["Ava", "sushi", "pink", "New Years"] + ]; + friendArray.push(["Xavier", "Louisiana creole", "red", "their birthday"]); + + //walking 2D array, slide 6 + let y = 20; // Start row based on text size of 20 + for (let f = 0; f < friendArray.length; f++) { // outer array + let x = 10; // Start item in this row + for (let t = 0; t < friendArray[f].length; t++) { //inner + text(friendArray[f][t], x, y); + x += textWidth(friendArray[f][t]) + 20; //place next item + } + y += 28; // place next row + } + + //walking 2D array, variation on slide 6 + //with embedded arithmetic for y + // + for (let f = 0; f < friendArray.length; f++) { // outer array + let x = 10; // Start item in this row + for (let t = 0; t < friendArray[f].length; t++) { //inner + //y is v-padding + LCV * v-spacing + text(friendArray[f][t], x, 200 + f * 28); + x += textWidth(friendArray[f][t]) + 20; //place next item + } + } + + //walking 2D array, slide 7 + //need to use x and y variables to manage canvas placement + y = 400; + for (let friend of friendArray) { + let x = 10; // Start item in this row + console.log("x and y", x, y); + console.log("friend:", friend); + for (let item of friend) { + console.log("item & x:", item, x); + text(item, x, y); + x += textWidth(item) + 20; //place next item + } + y += 28; // place next row + } + + //slide 9, creating 2D array: schools of fish ages + console.log("\n *** Fish ages in 2D ***"); + const schools = []; + //4 schools of fish + for (let t = 0; t < 4; t++) { + schools[t] = []; //initialize this school + console.log("schools[t]?", t, schools[t]); + + // Add 10 randomized ages to the array + for (let a = 0; a < 10; a++) { + schools[t].push(round(random(1, 5))); + } + } + console.log(schools); + } diff --git a/dist/assets/examples/ko/04_Control/00_Iteration.js b/dist/assets/examples/ko/04_Control/00_Iteration.js new file mode 100644 index 0000000000..7f96ebc7c7 --- /dev/null +++ b/dist/assets/examples/ko/04_Control/00_Iteration.js @@ -0,0 +1,41 @@ +/* + * @name for 반복문 + * @description "for" 구조를 사용하여 반복 형식을 만듭니다. + */ +let y; +let num = 14; + +function setup() { + createCanvas(720, 360); + background(102); + noStroke(); + + // 흰색 막대기들 그리기 + fill(255); + y = 60; + for (let i = 0; i < num / 3; i++) { + rect(50, y, 475, 10); + y += 20; + } + + // 회색 막대기들 + fill(51); + y = 40; + for (let i = 0; i < num; i++) { + rect(405, y, 30, 10); + y += 20; + } + y = 50; + for (let i = 0; i < num; i++) { + rect(425, y, 30, 10); + y += 20; + } + + // 얇은 선들 + y = 45; + fill(0); + for (let i = 0; i < num - 1; i++) { + rect(120, y, 40, 1); + y += 20; + } +} diff --git a/dist/assets/examples/ko/04_Control/01_Embedded_Iteration.js b/dist/assets/examples/ko/04_Control/01_Embedded_Iteration.js new file mode 100644 index 0000000000..33c571bb01 --- /dev/null +++ b/dist/assets/examples/ko/04_Control/01_Embedded_Iteration.js @@ -0,0 +1,21 @@ +/* + * @name for 내장 반복문 + * @description "for" 반복문 구조를 이중 사용하여 2차원 도형을 반복할 수 있습니다. + */ +function setup() { + createCanvas(720, 360); + background(0); + noStroke(); + + let gridSize = 35; + + for (let x = gridSize; x <= width - gridSize; x += gridSize) { + for (let y = gridSize; y <= height - gridSize; y += gridSize) { + noStroke(); + fill(255); + rect(x - 1, y - 1, 3, 3); + stroke(255, 50); + line(x, y, width / 2, height / 2); + } + } +} diff --git a/dist/assets/examples/ko/04_Control/02_Conditionals_1.js b/dist/assets/examples/ko/04_Control/02_Conditionals_1.js new file mode 100644 index 0000000000..8de20977a9 --- /dev/null +++ b/dist/assets/examples/ko/04_Control/02_Conditionals_1.js @@ -0,0 +1,24 @@ +/* + * @name 조건문 1 + * @description 조건문은 마치 질문과도 같습니다. + * 프로그램은 조건문이 던지는 질문이 참인지 거짓인지에 따라 + * 특정 선언문의 실행 여부를 결정합니다. + * 조건문으로 던지는 질문들은 언제나 논리 또는 관계 선언문의 형식을 갖습니다. + * 이 예제의 경우, 변수 i가 0이라는 조건이 충족될시 선이 그려집니다. + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 10; i < width; i += 10) { + // i가 20으로 나누어 떨어진다면, 첫번째 선을 그린다. + // 그렇지 않을 경우, 두번째 선을 그린다. + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + } else { + stroke(153); + line(i, 20, i, 180); + } + } +} diff --git a/dist/assets/examples/ko/04_Control/03_Conditionals_2.js b/dist/assets/examples/ko/04_Control/03_Conditionals_2.js new file mode 100644 index 0000000000..bde90ef016 --- /dev/null +++ b/dist/assets/examples/ko/04_Control/03_Conditionals_2.js @@ -0,0 +1,27 @@ +/* + * @name 조건문 2 + * @description 조건문 1 예제에 "else"라는 키워드를 더해 조건문의 문법을 확장해봅시다. + * "else"를 사용하면 연속하여 2개 이상의 질문을 던질 수 있습니다. + * 이 때, 각각의 질문은 서로 다른 행위를 요청할 수 있습니다. + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 2; i < width - 2; i += 4) { + // i가 20으로 나누어 떨어질 경우 + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + // i가 10으로 나누어 떨어질 경우 + } else if (i % 10 === 0) { + stroke(153); + line(i, 20, i, 180); + // 위의 두 조건 모두 충족하지 않을 경우 + // 이 선을 그린다. + } else { + stroke(102); + line(i, height / 2, i, height - 20); + } + } +} diff --git a/dist/assets/examples/ko/04_Control/04_Logical_Operators.js b/dist/assets/examples/ko/04_Control/04_Logical_Operators.js new file mode 100644 index 0000000000..4f3436dce7 --- /dev/null +++ b/dist/assets/examples/ko/04_Control/04_Logical_Operators.js @@ -0,0 +1,42 @@ +/* + * @name 논리적 연산자 + * @description 논리 연산자인 AND (&&) 와 OR (||) 는 + * 간단한 관계 선언문에 좀 더 복잡한 조건을 더할 때 쓰입니다. + * NOT (!) 연산자는 불리언 선언문을 부정할 때 쓰입니다. + */ +let test = false; + +function setup() { + createCanvas(720, 360); + background(126); + + for (let i = 5; i <= height; i += 5) { + // 논리적 연산자 AND + stroke(0); + if (i > 35 && i < 100) { + line(width / 4, i, width / 2, i); + test = false; + } + + // 논리적 연산자 OR + stroke(76); + if (i <= 35 || i >= 100) { + line(width / 2, i, width, i); + test = true; + } + + // 불리언 값이 참(true)인지 여부를 테스트 + // "if(test)"이 "if(test == true)"와 동일한지 여부를 확인 + if (test) { + stroke(0); + point(width / 3, i); + } + + // 불리언 값이 거짓(false)인지 여부를 테스트 + // "if(!test)"이 "if(test == false)"와 동일한지 여부를 확인 + if (!test) { + stroke(255); + point(width / 4, i); + } + } +} diff --git a/dist/assets/examples/ko/04_Control/05_Logical_Operators_2.js b/dist/assets/examples/ko/04_Control/05_Logical_Operators_2.js new file mode 100644 index 0000000000..2684feb956 --- /dev/null +++ b/dist/assets/examples/ko/04_Control/05_Logical_Operators_2.js @@ -0,0 +1,91 @@ +/* + * @name Logical Operators 2 + * @frame 400,400 + * @description contributed by + Prof WM Harris, How + to create Xboxes with one global variable and create conditions with + boolean variables and boolean expressions by utilizing Boolean + operators ||, &&, and ! to do boundary checking.
+ Functions + are created for both the canvas set up as well as the creation of + the boxes. Background color is dependent on the location of the + boxes in the canvas space. When mouse button and key are pressed + simultaneously, the “where” text and box color changes to cyan, + but if the mouse button is clicked alone then the animation will + start. When q or Q are pressed the text “Did you type q or Q?” + will change to blue, else it will be purple. If the mouse is placed + within the orange box containing the text, “withinRect” then the + shape will turn pink. + */ + + +//1 coordinate for everything :) +let where = 0; //control boxes' positions + +function setup() { + createCanvas(400, 400); +} + +function draw() { + //similar to slide 4 use of OR, || + //to set bg color of canvas + if ((where < 0) || (where > height)) { + background("beige"); + } else { + background("chocolate"); + } + + //similar to slide 4 use of AND, && + //to set fill color of box & text + if (mouseIsPressed && keyIsPressed) { + fill("cyan"); + } else { + fill(255); + } + + //boxL + rect(where, where, 40); + + //boxR, pad x coordinate for size of box + rect(width - where - 40, where, 40); + + //Move the boxes + where = where + 1; + + //Show the value of where the boxes are + text("where is " + where, 150, 30); + + //testing not, ! and or, || operators + if (!(key === "q" || key === "Q")) { + fill("purple"); + } else { + fill("dodgerBlue"); + } + //Show the current key value + text("Did you type a q or Q? " + key, 150, 70); + + //*** Boundary checking *** + //Is the mouse within rect boundary? + //left, right, top, bottom + let withinRect = (mouseX >= 150) && + (mouseX <= 150 + 100) && + (mouseY >= 300) && + (mouseY <= 300 + 40); + //fill color based on value of withinRect + if (withinRect) { + fill("pink"); + } else { + fill("orange"); + } + //draw the rect + rect(150, 300, 100, 40); + //show withinRect value as label on rect + fill(0); + text("withinRect " + withinRect, 160, 320); +} + +//boxes restart +function mousePressed() { + //Reset boxes back up and above the canvas + where = -50; +} \ No newline at end of file diff --git a/dist/assets/examples/ko/04_Control/06_Conditional_Shapes.js b/dist/assets/examples/ko/04_Control/06_Conditional_Shapes.js new file mode 100644 index 0000000000..8d544e9081 --- /dev/null +++ b/dist/assets/examples/ko/04_Control/06_Conditional_Shapes.js @@ -0,0 +1,48 @@ +/* + * @name Conditional Shapes + * @frame 400,400 + * @description contributed by + Prof WM Harris, How + to draw different shapes mid canvas depending on the mouse position.
+ Functions + are created for the main canvas set up with the markers on the left and + right hand sides. One is also created for the location of the mouse + regarding the canvas and the markers. If the mouse is within the + outer left hand beige rectangle, then the shape of circle is drawn + down the center of the canvas. If the mouse is within the outer right + hand beige rectangle, then the shape of square is drawn down the + center of the canvas. +*/ +function setup() { + createCanvas(400, 400); + strokeWeight(3); + //center squares to match circles + rectMode(CENTER); + + //draw rects to mark far sides + noStroke(); + fill("beige"); + rect(5, height / 2, 10, height); + rect(width - 5, height / 2, 10, height); + fill("orange"); + stroke("brown"); + + } + + function draw() { + point(mouseX, mouseY); + + //if (test) {doThis; } + //test: mouseX on far left of canvas + //doThis: draw a circle at mouseY + if (mouseX < 10) { + circle(width / 2, mouseY, 20); + } + + //test: mouseX on far right of canvas + //doThis: draw a square at mouseY + if (mouseX > width - 10) { + square(width / 2, mouseY, 20); + } + + } diff --git a/dist/assets/examples/ko/05_Image/00_Load_and_Display_Image.js b/dist/assets/examples/ko/05_Image/00_Load_and_Display_Image.js new file mode 100644 index 0000000000..5111273db6 --- /dev/null +++ b/dist/assets/examples/ko/05_Image/00_Load_and_Display_Image.js @@ -0,0 +1,19 @@ +/* + * @name 이미지 불러오기 및 보이기 + * @description 이미지를 실제 또는 다른 크기로 지정하여 화면상 불러오고 보이게 할 수 있습니다. + *

로컬 프로젝트에서 이 예제를 실행하려면, 이미지 파일을 준비하시고 + * 로컬 서버를 작동시키세요.

+ */ +let img; // 변수 'img' 선언 + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // 이미지 불러오기 +} + +function draw() { + // 이미지를 화면상 좌표 (0,0) 위치에 실제 크기로 보이게 한다. + image(img, 0, 0); + // 이미지를 화면상 좌표 (0,높이/2) 위치에 절반 크기로 보이게 한다. + image(img, 0, height / 2, img.width / 2, img.height / 2); +} diff --git a/dist/assets/examples/ko/05_Image/01_Background_Image.js b/dist/assets/examples/ko/05_Image/01_Background_Image.js new file mode 100644 index 0000000000..c261f4c2eb --- /dev/null +++ b/dist/assets/examples/ko/05_Image/01_Background_Image.js @@ -0,0 +1,30 @@ +/* + * @name 배경 이미지 + * @description 이 예제는 배경 이미지를 불러오는 가장 빠른 방법을 소개합니다. + * 이미지 파일을 배경으로 쓰기 위해선, 이미지의 너비와 높이를 + * 프로그램 화면 크기와 동일하게 맞추면 됩니다. + *

로컬 프로젝트에서 이 예제를 실행하려면, 이미지 파일을 준비하시고 + * 로컬 서버를 작동시키세요.

+ */ +let bg; +let y = 0; + +function setup() { + // 이미지 파일을 배경으로 쓰기 위해, createCanvas() 메소드의 인수에 + // 이미지 크기와 동일한 사이즈를 기입하면 됩니다. + // 이 예제의 경우, 이미지 크기는 720x400 픽셀입니다. + bg = loadImage('assets/moonwalk.jpg'); + createCanvas(720, 400); +} + +function draw() { + background(bg); + + stroke(226, 204, 0); + line(0, y, width, y); + + y++; + if (y > height) { + y = 0; + } +} diff --git a/dist/assets/examples/ko/05_Image/02_Transparency.js b/dist/assets/examples/ko/05_Image/02_Transparency.js new file mode 100644 index 0000000000..54e54acdb5 --- /dev/null +++ b/dist/assets/examples/ko/05_Image/02_Transparency.js @@ -0,0 +1,23 @@ +/* + * @name 투명도 + * @description 마우스 포인터를 좌우로 움직여 이미지의 위치를 옮겨보세요. + * 이 예제의 경우, tint()함수로 알파값이 수정된 이미지를 원본 이미지에 위에 겹쳐 보여줍니다. + *

로컬 프로젝트에서 이 예제를 실행하려면, 이미지 파일을 준비하시고 + * 로컬 서버를 작동시키세요.

+ */ +let img; +let offset = 0; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // 프로그램상 이미지 불러오기 +} + +function draw() { + image(img, 0, 0); // 이미지를 투명도 100%로 보이게하기 + let dx = mouseX - img.width / 2 - offset; + offset += dx * easing; + tint(255, 127); // 이미지를 투명도 50%로 보이게하기 + image(img, offset, 0); +} diff --git a/dist/assets/examples/ko/05_Image/03_Alpha_Mask.js b/dist/assets/examples/ko/05_Image/03_Alpha_Mask.js new file mode 100644 index 0000000000..ad500307c6 --- /dev/null +++ b/dist/assets/examples/ko/05_Image/03_Alpha_Mask.js @@ -0,0 +1,26 @@ +/* + * @name 알파 마스크 + * @description 이미지 일부의 투명도를 설정하기 위해 마스크를 불러옵니다. + * 이미지와 마스크는 p5.Image의 mask() 메소드를 통해 합쳐집니다. + *

로컬 프로젝트에서 이 예제를 실행하려면, 이미지 파일을 준비하시고 + * 로컬 서버를 작동시키세요.

+ */ +let img; +let imgMask; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); + imgMask = loadImage('assets/mask.png'); +} + +function setup() { + createCanvas(720, 400); + img.mask(imgMask); + imageMode(CENTER); +} + +function draw() { + background(0, 102, 153); + image(img, width / 2, height / 2); + image(img, mouseX, mouseY); +} diff --git a/dist/assets/examples/ko/05_Image/04_Create_Image.js b/dist/assets/examples/ko/05_Image/04_Create_Image.js new file mode 100644 index 0000000000..a051fcb02e --- /dev/null +++ b/dist/assets/examples/ko/05_Image/04_Create_Image.js @@ -0,0 +1,25 @@ +/* + * @name 이미지 만들기 + * @description createImage() 함수로 재밌는 픽셀 버퍼를 만들 수 있습니다. + * 이 예제는 그래디언트 이미지를 만듭니다. + */ +let img; // 'img' 변수 선언하기 + +function setup() { + createCanvas(720, 400); + img = createImage(230, 230); + img.loadPixels(); + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + let a = map(y, 0, img.height, 255, 0); + img.set(x, y, [0, 153, 204, a]); + } + } + img.updatePixels(); +} + +function draw() { + background(0); + image(img, 90, 80); + image(img, mouseX - img.width / 2, mouseY - img.height / 2); +} diff --git a/dist/assets/examples/ko/05_Image/05_Pointillism.js b/dist/assets/examples/ko/05_Image/05_Pointillism.js new file mode 100644 index 0000000000..edd9562e6c --- /dev/null +++ b/dist/assets/examples/ko/05_Image/05_Pointillism.js @@ -0,0 +1,32 @@ +/* + * @name 점묘법 + * @description 제작: 다니엘 쉬프만(Dan Shiffman). 마우스의 가로 위치는 점의 크기를 조정합니다. + * 픽셀에 따라 색칠된 원형(ellipse)으로 간단한 점묘법 효과를 만듭니다. + *

로컬 프로젝트에서 이 예제를 실행하려면, 이미지 파일을 준비하시고 + * 로컬 서버를 작동시키세요.

+ */ +let img; +let smallPoint, largePoint; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 400); + smallPoint = 4; + largePoint = 40; + imageMode(CENTER); + noStroke(); + background(255); + img.loadPixels(); +} + +function draw() { + let pointillize = map(mouseX, 0, width, smallPoint, largePoint); + let x = floor(random(img.width)); + let y = floor(random(img.height)); + let pix = img.get(x, y); + fill(pix, 128); + ellipse(x, y, pointillize, pointillize); +} diff --git a/dist/assets/examples/ko/05_Image/06_Blur.js b/dist/assets/examples/ko/05_Image/06_Blur.js new file mode 100644 index 0000000000..2374bc0345 --- /dev/null +++ b/dist/assets/examples/ko/05_Image/06_Blur.js @@ -0,0 +1,89 @@ +/* + * @name Blur + * @description A low-pass filter that blurs an image. This program analyzes every pixel in an image and blends it with all the neighboring pixels to blur the image. + *

This example is ported from the Blur example + * on the Processing website + */ +// to consider all neighboring pixels we use a 3x3 array +// and normalize these values +// v is the normalized value +let v = 1.0 / 9.0; +// kernel is the 3x3 matrix of normalized values +let kernel = [[ v, v, v ], [ v, v, v ], [ v, v, v ]]; + +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// if loadImage() is called in setup(), the image won't appear +// since noLoop() restricts draw() to execute only once +// (one execution of draw() is not enough time for the image to load), +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover.png"); +} + +// setup() runs once after preload +function setup() { + // create canvas + createCanvas(710, 400); + // noLoop() makes draw() run only once, not in a loop + noLoop(); +} + + +// draw() runs after setup(), normally on a loop +// in this case it runs only once, because of noDraw() +function draw() { + // place the original image on the upper left corner + image(img, 0, 0); + + // create a new image, same dimensions as img + edgeImg = createImage(img.width, img.height); + + // load its pixels + edgeImg.loadPixels(); + + // two for() loops, to iterate in x axis and y axis + // since the kernel assumes that the pixel + // has pixels above, under, left, and right + // we need to skip the first and last column and row + // x then goes from 1 to width - 1 + // y then goes from 1 to height - 1 + for (let x = 1; x < img.width; x++) { + for (let y = 1; y < img.height; y++) { + // kernel sum for the current pixel starts as 0 + let sum = 0; + + // kx, ky variables for iterating over the kernel + // kx, ky have three different values: -1, 0, 1 + for (kx = -1; kx <= 1; kx++) { + for (ky = -1; ky <= 1; ky++) { + let xpos = x + kx; + let ypos = y + ky; + + // since our image is grayscale, + // RGB values are identical + // we retrieve the red value for this example + // (green and blue work as well) + let val = red(img.get(xpos, ypos)); + + // accumulate the kernel sum + // kernel is a 3x3 matrix + // kx and ky have values -1, 0, 1 + // if we add 1 to kx and ky, we get 0, 1, 2 + // with that we can use it to iterate over kernel + // and calculate the accumulated sum + sum += kernel[kx+1][ky+1] * val; + } + } + + // set the value of the edgeImg pixel to the kernel sum + edgeImg.set(x, y, color(sum)); + } + } + // updatePixels() to write the changes on edgeImg + edgeImg.updatePixels(); + + // draw edgeImg at the right of the original image + image(edgeImg, img.width, 0); +} \ No newline at end of file diff --git a/dist/assets/examples/ko/05_Image/07_EdgeDetection.js b/dist/assets/examples/ko/05_Image/07_EdgeDetection.js new file mode 100644 index 0000000000..5eff38c2d2 --- /dev/null +++ b/dist/assets/examples/ko/05_Image/07_EdgeDetection.js @@ -0,0 +1,93 @@ +/* + * @name Edge Detection + * @description A high-pass filter sharpens an image. This program analyzes every pixel in an image in relation to the neighboring pixels to sharpen the image. + *

This example is ported from the Edge Detection example + * on the Processing website + */ +// this program analyzes every pixel in an image +// in relation to the neighbouring pixels +// to sharpen the image + +// to consider all neighboring pixels we use a 3x3 array +// and normalize these values +// kernel is the 3x3 matrix of normalized values +let kernel = [[-1, -1, -1 ], [ -1, 9, -1 ], [-1, -1, -1 ]]; + +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// if loadImage() is called in setup(), the image won't appear +// since noLoop() restricts draw() to execute only once +// (one execution of draw() is not enough time for the image to load), +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover.png"); +} + +// setup() runs after preload, once() +function setup() { + // create canvas + createCanvas(710, 400); + // noLoop() makes draw() run only once, not in a loop + noLoop(); +} + +// draw() runs after setup(), normally on a loop +// in this case it runs only once, because of noDraw() +function draw() { + + // place the original image on the upper left corner + image(img, 0, 0); + + // create a new image, same dimensions as img + edgeImg = createImage(img.width, img.height); + + // load its pixels + edgeImg.loadPixels(); + + + // two for() loops, to iterate in x axis and y axis + // since the kernel assumes that the pixel + // has pixels above, under, left, and right + // we need to skip the first and last column and row + // x then goes from 1 to width - 1 + // y then goes from 1 to height - 1 + + for (let x = 1; x < img.width - 1; x++) { + for (let y = 1; y < img.height - 1; y++) { + // kernel sum for the current pixel starts as 0 + let sum = 0; + + // kx, ky variables for iterating over the kernel + // kx, ky have three different values: -1, 0, 1 + for (kx = -1; kx <= 1; kx++) { + for (ky = -1; ky <= 1; ky++) { + + let xpos = x + kx; + let ypos = y + ky; + let pos = (y + ky)*img.width + (x + kx); + // since our image is grayscale, + // RGB values are identical + // we retrieve the red value for this example + let val = red(img.get(xpos, ypos)); + // accumulate the kernel sum + // kernel is a 3x3 matrix + // kx and ky have values -1, 0, 1 + // if we add 1 to kx and ky, we get 0, 1, 2 + // with that we can use it to iterate over kernel + // and calculate the accumulated sum + sum += kernel[ky+1][kx+1] * val; + } + } + + // set the pixel value of the edgeImg + edgeImg.set(x, y, color(sum, sum, sum)); + } + } + + // updatePixels() to write the changes on edgeImg + edgeImg.updatePixels(); + + // draw edgeImg at the right of the original image + image(edgeImg, img.width, 0); +} \ No newline at end of file diff --git a/dist/assets/examples/ko/05_Image/08_Brightness.js b/dist/assets/examples/ko/05_Image/08_Brightness.js new file mode 100644 index 0000000000..3c58a98876 --- /dev/null +++ b/dist/assets/examples/ko/05_Image/08_Brightness.js @@ -0,0 +1,63 @@ +/* + * @name Brightness + * @description This program adjusts the brightness of a part of the image by calculating the distance of each pixel to the mouse. + *

This example is ported from the Brightness example + * on the Processing website + */ +// This program adjusts the brightness +// of a part of the image by +// calculating the distance of +// each pixel to the mouse. +let img; +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover_wide.jpg"); +} +// setup() runs after preload, once() +function setup() { + createCanvas(710, 400); + pixelDensity(1); + frameRate(30); +} + +function draw() { + image(img,0,0); + // Only need to load the pixels[] array once, because we're only + // manipulating pixels[] inside draw(), not drawing shapes. + loadPixels(); + // We must also call loadPixels() on the PImage since we are going to read its pixels. + img.loadPixels(); + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++ ) { + // Calculate the 1D location from a 2D grid + let loc = (x + y*img.width)*4; + // Get the R,G,B values from image + let r,g,b; + r = img.pixels[loc]; + // g = img.pixels[loc+1]; + // b = img.pixels[loc+2]; + // Calculate an amount to change brightness based on proximity to the mouse + // The closer the pixel is to the mouse, the lower the value of "distance" + let maxdist = 50;//dist(0,0,width,height); + let d = dist(x, y, mouseX, mouseY); + let adjustbrightness = 255*(maxdist-d)/maxdist; + r += adjustbrightness; + // g += adjustbrightness; + // b += adjustbrightness; + // Constrain RGB to make sure they are within 0-255 color range + r = constrain(r, 0, 255); + // g = constrain(g, 0, 255); + // b = constrain(b, 0, 255); + // Make a new color and set pixel in the window + let pixloc = (y*width + x)*4; + pixels[pixloc] = r; + pixels[pixloc+1] = r; + pixels[pixloc+2] = r; + pixels[pixloc+3] = 255; // Always have to set alpha + } + } + updatePixels(); +} \ No newline at end of file diff --git a/dist/assets/examples/ko/05_Image/09_Convolution.js b/dist/assets/examples/ko/05_Image/09_Convolution.js new file mode 100644 index 0000000000..eb953c6729 --- /dev/null +++ b/dist/assets/examples/ko/05_Image/09_Convolution.js @@ -0,0 +1,91 @@ +/* + * @name Convolution + * @description Applies a convolution matrix to a portion of an image. Move mouse to apply filter to different parts of the image. This example is a port of Dan Shiffman's example for Processing. Original comments written by Dan unless otherwise specified. + *

To run this example locally, you will need an + * image file, and a running + * local server.

+ */ + +let img; +let w = 80; + +// It's possible to convolve the image with many different +// matrices to produce different effects. This is a high-pass +// filter; it accentuates the edges. +const matrix = [ [ -1, -1, -1 ], + [ -1, 9, -1 ], + [ -1, -1, -1 ] ]; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 400); + img.loadPixels(); + + // pixelDensity(1) for not scaling pixel density to display density + // for more information, check the reference of pixelDensity() + pixelDensity(1); +} + +function draw() { + // We're only going to process a portion of the image + // so let's set the whole image as the background first + background(img); + + // Calculate the small rectangle we will process + const xstart = constrain(mouseX - w/2, 0, img.width); + const ystart = constrain(mouseY - w/2, 0, img.height); + const xend = constrain(mouseX + w/2, 0, img.width); + const yend = constrain(mouseY + w/2, 0, img.height); + const matrixsize = 3; + + loadPixels(); + // Begin our loop for every pixel in the smaller image + for (let x = xstart; x < xend; x++) { + for (let y = ystart; y < yend; y++ ) { + let c = convolution(x, y, matrix, matrixsize, img); + + // retrieve the RGBA values from c and update pixels() + let loc = (x + y*img.width) * 4; + pixels[loc] = red(c); + pixels[loc + 1] = green(c); + pixels[loc + 2] = blue(c); + pixels[loc + 3] = alpha(c); + } + } + updatePixels(); +} + +function convolution(x, y, matrix, matrixsize, img) { + let rtotal = 0.0; + let gtotal = 0.0; + let btotal = 0.0; + const offset = Math.floor(matrixsize / 2); + for (let i = 0; i < matrixsize; i++){ + for (let j = 0; j < matrixsize; j++){ + + // What pixel are we testing + const xloc = (x + i - offset); + const yloc = (y + j - offset); + let loc = (xloc + img.width * yloc) * 4; + + // Make sure we haven't walked off our image, we could do better here + loc = constrain(loc, 0 , img.pixels.length - 1); + + // Calculate the convolution + // retrieve RGB values + rtotal += (img.pixels[loc]) * matrix[i][j]; + gtotal += (img.pixels[loc + 1]) * matrix[i][j]; + btotal += (img.pixels[loc + 2]) * matrix[i][j]; + } + } + // Make sure RGB is within range + rtotal = constrain(rtotal, 0, 255); + gtotal = constrain(gtotal, 0, 255); + btotal = constrain(btotal, 0, 255); + + // Return the resulting color + return color(rtotal, gtotal, btotal); +} \ No newline at end of file diff --git a/dist/assets/examples/ko/05_Image/10_Copy_Method.js b/dist/assets/examples/ko/05_Image/10_Copy_Method.js new file mode 100644 index 0000000000..2002d34dfe --- /dev/null +++ b/dist/assets/examples/ko/05_Image/10_Copy_Method.js @@ -0,0 +1,20 @@ +/* + * @name Copy() method + * @frame 600,400 + * @description An example of how to simulate coloring image with the copy() method. + */ +let draft, ready; +function preload() { + ready = loadImage("assets/parrot-color.png"); + draft = loadImage("assets/parrot-bw.png"); +} +function setup() { + createCanvas(600, 400); + noCursor(); + cursor("assets/brush.png", 20, -10); + image(ready, 0, 0); + image(draft, 0, 0); +} +function mouseDragged() { + copy(ready, mouseX, mouseY, 20, 20, mouseX, mouseY, 20, 20); +} diff --git a/dist/assets/examples/ko/07_Color/00_Hue.js b/dist/assets/examples/ko/07_Color/00_Hue.js new file mode 100644 index 0000000000..3719823704 --- /dev/null +++ b/dist/assets/examples/ko/07_Color/00_Hue.js @@ -0,0 +1,25 @@ +/* + * @name 색조 + * @description 색조는 오브젝트에 반사되거나 이를 통해 전달된 색상을 말하며, + * 일반적으로 색상명(빨강, 파랑, 노랑 등)으로 불립니다. + * 마우스 커서를 세로축으로 움직여 막대기의 색조를 변경해 보세요. + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, height, height, height); + noStroke(); + background(0); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(mouseY, height, height); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/ko/07_Color/01_Saturation.js b/dist/assets/examples/ko/07_Color/01_Saturation.js new file mode 100644 index 0000000000..0e9cb3fff6 --- /dev/null +++ b/dist/assets/examples/ko/07_Color/01_Saturation.js @@ -0,0 +1,24 @@ +/* + * @name 채도 + * @description 채도는 회색이 차지하는 비율에 따른, 색조의 짙음 또는 맑음 정도를 말합니다. + * 포화된 색은 맑고, 불포화된 색은 높은 비율의 회색조를 갖습니다. + * 마우스 커서를 세로축으로 움직여 막대기의 채도를 변경해 보세요. + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, width, height, 100); + noStroke(); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(barX, mouseY, 66); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/ko/07_Color/02_Brightness.js b/dist/assets/examples/ko/07_Color/02_Brightness.js new file mode 100644 index 0000000000..7f7bcb99ed --- /dev/null +++ b/dist/assets/examples/ko/07_Color/02_Brightness.js @@ -0,0 +1,46 @@ +/* + * @name 밝기 + * @description 제작: 다니엘 쉬프만(Dan Shiffman). 마우스와 각 픽셀 간의 거리값을 + * 계산하여 이미지 일부의 밝기를 조정합니다. + *

로컬 컴퓨터에서 이 예제를 실행하려면, 이미지 파일을 준비하시고 + * 로컬 서버를 작동시키세요.

+ */ +let img; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 200); + pixelDensity(1); + img.loadPixels(); + loadPixels(); +} + +function draw() { + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + // 2D 그리드로부터 1차원 위치 계산 + let loc = (x + y * img.width) * 4; + // 이미지에서 R,G,B값 받기 + let r, g, b; + r = img.pixels[loc]; + // 마우스와의 거리에 따라 변경할 밝기 계산 + let maxdist = 50; + let d = dist(x, y, mouseX, mouseY); + let adjustbrightness = (255 * (maxdist - d)) / maxdist; + r += adjustbrightness; + // RGB의 색상 범위가 0-255에 국한되도록 설정 + r = constrain(r, 0, 255); + // 새로운 색상 생성 후 화면에 픽셀 위치 고정 + //color c = color(r, g, b); + let pixloc = (y * width + x) * 4; + pixels[pixloc] = r; + pixels[pixloc + 1] = r; + pixels[pixloc + 2] = r; + pixels[pixloc + 3] = 255; + } + } + updatePixels(); +} diff --git a/dist/assets/examples/ko/07_Color/03_Color_Variables.js b/dist/assets/examples/ko/07_Color/03_Color_Variables.js new file mode 100644 index 0000000000..5c3aa3d911 --- /dev/null +++ b/dist/assets/examples/ko/07_Color/03_Color_Variables.js @@ -0,0 +1,40 @@ +/* + * @name 색상 변수 + * @description (Albers에게 바칩니다.) 이 예제는 색상 조정을 위한 변수 생성 방법을 다룹니다. + * 이 때, 변수들은 숫자가 아닌 특정 명칭으로 지정됩니다. + */ +function setup() { + createCanvas(710, 400); + noStroke(); + background(51, 0, 0); + + let inside = color(204, 102, 0); + let middle = color(204, 153, 0); + let outside = color(153, 51, 0); + + // 아래의 변수 선언문은 위의 선언문들과 동일합니다. + // 둘 중 원하는 형식을 사용하면 됩니다. + //let inside = color('#CC6600'); + //let middle = color('#CC9900'); + //let outside = color('#993300'); + + push(); + translate(80, 80); + fill(outside); + rect(0, 0, 200, 200); + fill(middle); + rect(40, 60, 120, 120); + fill(inside); + rect(60, 90, 80, 80); + pop(); + + push(); + translate(360, 80); + fill(inside); + rect(0, 0, 200, 200); + fill(outside); + rect(40, 60, 120, 120); + fill(middle); + rect(60, 90, 80, 80); + pop(); +} diff --git a/dist/assets/examples/ko/07_Color/04_Relativity.js b/dist/assets/examples/ko/07_Color/04_Relativity.js new file mode 100644 index 0000000000..f54aef95d9 --- /dev/null +++ b/dist/assets/examples/ko/07_Color/04_Relativity.js @@ -0,0 +1,34 @@ +/* + * @name 상대성 + * @description 각 색상은 다른 색상과의 관계 속에서 인식됩니다. + * 상단과 하단의 막대기들은 둘 다 동일한 색상 요소들을 갖지만, + * 색상 요소들의 배열에 따라 마치 다른 색조를 갖는 듯 보입니다. + */ +let a, b, c, d, e; + +function setup() { + createCanvas(710, 400); + noStroke(); + a = color(165, 167, 20); + b = color(77, 86, 59); + c = color(42, 106, 105); + d = color(165, 89, 20); + e = color(146, 150, 127); + noLoop(); // 반복없이 한번만 그리기 +} + +function draw() { + drawBand(a, b, c, d, e, 0, width / 128); + drawBand(c, a, d, b, e, height / 2, width / 128); +} + +function drawBand(v, w, x, y, z, ypos, barWidth) { + let num = 5; + let colorOrder = [v, w, x, y, z]; + for (let i = 0; i < width; i += barWidth * num) { + for (let j = 0; j < num; j++) { + fill(colorOrder[j]); + rect(i + j * barWidth, ypos, barWidth, height / 2); + } + } +} diff --git a/dist/assets/examples/ko/07_Color/05_Linear_Gradient.js b/dist/assets/examples/ko/07_Color/05_Linear_Gradient.js new file mode 100644 index 0000000000..95c2feb2ca --- /dev/null +++ b/dist/assets/examples/ko/07_Color/05_Linear_Gradient.js @@ -0,0 +1,51 @@ +/* + * @name 선형 그래디언트 + * @description lerpColor() 함수는 두 가지 색상을 보간하는 데에 쓰입니다. + */ +// 상수 +const Y_AXIS = 1; +const X_AXIS = 2; +let b1, b2, c1, c2; + +function setup() { + createCanvas(710, 400); + + // 색상 정의하기 + b1 = color(255); + b2 = color(0); + c1 = color(204, 102, 0); + c2 = color(0, 102, 153); + + noLoop(); +} + +function draw() { + // 배경 + setGradient(0, 0, width / 2, height, b1, b2, X_AXIS); + setGradient(width / 2, 0, width / 2, height, b2, b1, X_AXIS); + // 전경 + setGradient(50, 90, 540, 80, c1, c2, Y_AXIS); + setGradient(50, 190, 540, 80, c2, c1, X_AXIS); +} + +function setGradient(x, y, w, h, c1, c2, axis) { + noFill(); + + if (axis === Y_AXIS) { + // 위에서 아래 방향 그래디언트 + for (let i = y; i <= y + h; i++) { + let inter = map(i, y, y + h, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(x, i, x + w, i); + } + } else if (axis === X_AXIS) { + // 왼쪽에서 오른쪽 방향 그래디언트 + for (let i = x; i <= x + w; i++) { + let inter = map(i, x, x + w, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(i, y, i, y + h); + } + } +} diff --git a/dist/assets/examples/ko/07_Color/06_Radial_Gradient.js b/dist/assets/examples/ko/07_Color/06_Radial_Gradient.js new file mode 100644 index 0000000000..ce2df1dde5 --- /dev/null +++ b/dist/assets/examples/ko/07_Color/06_Radial_Gradient.js @@ -0,0 +1,32 @@ +/* + * @name 방사형 그래디언트 + * @description 동심원을 그려 한 색상이 다른 색상으로 퍼지는 듯한 효과를 만듭니다. + */ +let dim; + +function setup() { + createCanvas(710, 400); + dim = width / 2; + background(0); + colorMode(HSB, 360, 100, 100); + noStroke(); + ellipseMode(RADIUS); + frameRate(1); +} + +function draw() { + background(0); + for (let x = 0; x <= width; x += dim) { + drawGradient(x, height / 2); + } +} + +function drawGradient(x, y) { + let radius = dim / 2; + let h = random(0, 360); + for (let r = radius; r > 0; --r) { + fill(h, 90, 90); + ellipse(x, y, r, r); + h = (h + 1) % 360; + } +} diff --git a/dist/assets/examples/ko/07_Color/07_Lerp_Color.js b/dist/assets/examples/ko/07_Color/07_Lerp_Color.js new file mode 100644 index 0000000000..0c1324183f --- /dev/null +++ b/dist/assets/examples/ko/07_Color/07_Lerp_Color.js @@ -0,0 +1,49 @@ +/* + * @name 선형 보간(lerp) 색상 + * @description 무작위의 도형을 반복하고, + * 빨강색과 파란색을 선형적으로 보간합니다. + */ +function setup() { + createCanvas(720, 400); + background(255); + noStroke(); +} + +function draw() { + background(255); + from = color(255, 0, 0, 0.2 * 255); + to = color(0, 0, 255, 0.2 * 255); + c1 = lerpColor(from, to, 0.33); + c2 = lerpColor(from, to, 0.66); + for (let i = 0; i < 15; i++) { + fill(from); + quad( + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height) + ); + fill(c1); + quad( + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height) + ); + fill(c2); + quad( + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height) + ); + fill(to); + quad( + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height) + ); + } + frameRate(5); +} diff --git a/dist/assets/examples/ko/08_Math/00_incrementdecrement.js b/dist/assets/examples/ko/08_Math/00_incrementdecrement.js new file mode 100644 index 0000000000..2fa2db7120 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/00_incrementdecrement.js @@ -0,0 +1,42 @@ +/* + * @name 증가와 감소 + * @description "a++"는 "a = a + 1"와 같은 표현입니다. + * "a--"는 "a = a - 1"과 같은 표현입니다. + */ +let a; +let b; +let direction; + +function setup() { + createCanvas(710, 400); + colorMode(RGB, width); + a = 0; + b = width; + direction = true; + frameRate(30); +} + +function draw() { + a++; + if (a > width) { + a = 0; + direction = !direction; + } + if (direction === true) { + stroke(a); + } else { + stroke(width - a); + } + line(a, 0, a, height / 2); + + b--; + if (b < 0) { + b = width; + } + if (direction == true) { + stroke(width - b); + } else { + stroke(b); + } + line(b, height / 2 + 1, b, height); +} diff --git a/dist/assets/examples/ko/08_Math/01_operatorprecedence.js b/dist/assets/examples/ko/08_Math/01_operatorprecedence.js new file mode 100644 index 0000000000..0f7e3a8028 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/01_operatorprecedence.js @@ -0,0 +1,51 @@ +/* + * @name 연산자 우선 순위 + * @description 연산자의 실행 순서를 명시하는 경우를 제외하고, 모든 선언문은 연산자 우선 순위에 따라 + * 처리됩니다. 예를 들어, 수식 "4+2*8"는 2에 8을 먼저 곱하고, 그 결과값에 4를 더합니다. + * 이는 "*"이 "+"보다 연산 우선 순위를 갖기 때문입니다. + * 혼동을 방지하기 위해 "4+(2*8)"라 쓰는 편을 권장하기도 합니다. + * 이처럼, 코드 내에 괄호를 사용하여 처리 순서를 명시할 수 있습니다. + * 연산자 우선 순위는 다음과 같습니다. + */ +// 처리 순위가 높은 연산자는 목록 상단에, +// 가장 낲은 연산자는 목록 하단에 적힙니다. +// 곱하기 연산자: * / % +// 증감 연산자: + - +// 비교 연산자: < > <= >= +// 등호 연산자: == != +// 논리 연산자 AND: && +// 논리 연산자 OR: || +// 할당 연산자: = += -= *= /= %= +function setup() { + createCanvas(710, 400); + background(51); + noFill(); + stroke(51); + + stroke(204); + for (let i = 0; i < width - 20; i += 4) { + // 70이 30을 더한 결과값이 + // 현재 "i"값보다 큰 지의 여부를 평가 + // 처리 순서를 명확히하고자 "if (i > (30 + 70)) {"로 작성 + if (i > 30 + 70) { + line(i, 0, i, 50); + } + } + + stroke(255); + // 2와 8을 곱한 뒤, 그 결과값에 4를 더함 + // 처리 순서를 명확히하고자, "rect(5 + (2 * 8), 0, 90, 20);"로 작성 + rect(4 + 2 * 8, 52, 290, 48); + rect((4 + 2) * 8, 100, 290, 49); + + stroke(153); + for (let i = 0; i < width; i += 2) { + // 비교 선언문을 가장 먼저 처리한 뒤, + // 다음으로 논리 연산자 AND, 마지막으로 논리 연산자 OR 순으로 처리. + // 처리 순서를 명확히하고자 다음과 같이 작성: + // "if(((i > 20) && (i < 50)) || ((i > 100) && (i < width-20))) {" + if ((i > 20 && i < 50) || (i > 100 && i < width - 20)) { + line(i, 151, i, height - 1); + } + } +} diff --git a/dist/assets/examples/ko/08_Math/02_distance1d.js b/dist/assets/examples/ko/08_Math/02_distance1d.js new file mode 100644 index 0000000000..36e93c6904 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/02_distance1d.js @@ -0,0 +1,64 @@ +/* + * @name 1D 거리 + * @description 마우스를 좌우로 움직여, 화면 속 도형의 움직임 속도와 방향을 조정해보세요. + */ +let xpos1; +let xpos2; +let xpos3; +let xpos4; +let thin = 8; +let thick = 36; + +function setup() { + createCanvas(710, 400); + noStroke(); + xpos1 = width / 2; + xpos2 = width / 2; + xpos3 = width / 2; + xpos4 = width / 2; +} + +function draw() { + background(0); + + let mx = mouseX * 0.4 - width / 5.0; + + fill(102); + rect(xpos2, 0, thick, height / 2); + fill(204); + rect(xpos1, 0, thin, height / 2); + fill(102); + rect(xpos4, height / 2, thick, height / 2); + fill(204); + rect(xpos3, height / 2, thin, height / 2); + + xpos1 += mx / 16; + xpos2 += mx / 64; + xpos3 -= mx / 16; + xpos4 -= mx / 64; + + if (xpos1 < -thin) { + xpos1 = width; + } + if (xpos1 > width) { + xpos1 = -thin; + } + if (xpos2 < -thick) { + xpos2 = width; + } + if (xpos2 > width) { + xpos2 = -thick; + } + if (xpos3 < -thin) { + xpos3 = width; + } + if (xpos3 > width) { + xpos3 = -thin; + } + if (xpos4 < -thick) { + xpos4 = width; + } + if (xpos4 > width) { + xpos4 = -thick; + } +} diff --git a/dist/assets/examples/ko/08_Math/03_distance2d.js b/dist/assets/examples/ko/08_Math/03_distance2d.js new file mode 100644 index 0000000000..3fa5d7efa0 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/03_distance2d.js @@ -0,0 +1,24 @@ +/* + * @name 2D 거리 + * @description 이미지 위로 마우스를 움직여, 매트릭스를 흐리게 또는 뚜렷하게 만들어보세요. + * 각 타원과 마우스 간의 거리에 비례하여 원형의 크기가 조정됩니다. + */ +let max_distance; + +function setup() { + createCanvas(710, 400); + noStroke(); + max_distance = dist(0, 0, width, height); +} + +function draw() { + background(0); + + for (let i = 0; i <= width; i += 20) { + for (let j = 0; j <= height; j += 20) { + let size = dist(mouseX, mouseY, i, j); + size = (size / max_distance) * 66; + ellipse(i, j, size, size); + } + } +} diff --git a/dist/assets/examples/ko/08_Math/04_sine.js b/dist/assets/examples/ko/08_Math/04_sine.js new file mode 100644 index 0000000000..6f55c094fe --- /dev/null +++ b/dist/assets/examples/ko/08_Math/04_sine.js @@ -0,0 +1,27 @@ +/* + * @name 사인 + * @description sin() 함수로 도형의 크기를 부드럽게 조정합니다. + */ +let diameter; +let angle = 0; + +function setup() { + createCanvas(710, 400); + diameter = height - 10; + noStroke(); + fill(255, 204, 0); +} + +function draw() { + background(0); + + let d1 = 10 + (sin(angle) * diameter) / 2 + diameter / 2; + let d2 = 10 + (sin(angle + PI / 2) * diameter) / 2 + diameter / 2; + let d3 = 10 + (sin(angle + PI) * diameter) / 2 + diameter / 2; + + ellipse(0, height / 2, d1, d1); + ellipse(width / 2, height / 2, d2, d2); + ellipse(width, height / 2, d3, d3); + + angle += 0.02; +} diff --git a/dist/assets/examples/ko/08_Math/05_sincosine.js b/dist/assets/examples/ko/08_Math/05_sincosine.js new file mode 100644 index 0000000000..431daec574 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/05_sincosine.js @@ -0,0 +1,43 @@ +/* + * @name 사인 코사인 + * @description sin()와 cos() 함수를 이용한 선형적 움직임입니다. + * 0과 PI*2 사이의 숫자(TWO_PI의 경우, 약 6.28)를 위의 함수에 넣으면 + * -1과 1 사이의 값이 반환됩니다. + * 이러한 반환값은 더 큰 움직임을 만드는 한 척도로서 쓰입니다. + */ +let angle1 = 0; +let angle2 = 0; +let scalar = 70; + +function setup() { + createCanvas(710, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(0); + + let ang1 = radians(angle1); + let ang2 = radians(angle2); + + let x1 = width / 2 + scalar * cos(ang1); + let x2 = width / 2 + scalar * cos(ang2); + + let y1 = height / 2 + scalar * sin(ang1); + let y2 = height / 2 + scalar * sin(ang2); + + fill(255); + rect(width * 0.5, height * 0.5, 140, 140); + + fill(0, 102, 153); + ellipse(x1, height * 0.5 - 120, scalar, scalar); + ellipse(x2, height * 0.5 + 120, scalar, scalar); + + fill(255, 204, 0); + ellipse(width * 0.5 - 120, y1, scalar, scalar); + ellipse(width * 0.5 + 120, y2, scalar, scalar); + + angle1 += 2; + angle2 += 3; +} diff --git a/dist/assets/examples/ko/08_Math/06_sinewave.js b/dist/assets/examples/ko/08_Math/06_sinewave.js new file mode 100644 index 0000000000..a3dbc919b5 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/06_sinewave.js @@ -0,0 +1,47 @@ +/* + * @name 사인파 + * @description 간단한 사인파를 만듭니다. + * 원본 제작: 다니엘 쉬프만(Daniel Shiffman) + */ + +let xspacing = 16; // 각 도형들 간의 가로 거리 +let w; // 전체 파형의 너비 +let theta = 0.0; // 시작 각도 0 +let amplitude = 75.0; // 파형의 높이 +let period = 500.0; // 파형이 반복되기 전까지 생성되는 픽셀 개수 +let dx; // x 증가값 +let yvalues; // 파형의 최고 높이를 저장하기 위한 배열 + +function setup() { + createCanvas(710, 400); + w = width + 16; + dx = (TWO_PI / period) * xspacing; + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // 세타값(theta) 증가 (다른 값을 넣어 각속도를 조정해보세요) + theta += 0.02; + + // 매 x값마다 싸인 함수를 이용해 y값을 계산 + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = sin(x) * amplitude; + x += dx; + } +} + +function renderWave() { + noStroke(); + fill(255); + // 각 위치에 지정된 타원형으로 파형을 그릴 수 있는 간단한 방법 + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, height / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/ko/08_Math/07_additivewave.js b/dist/assets/examples/ko/08_Math/07_additivewave.js new file mode 100644 index 0000000000..4efea302ea --- /dev/null +++ b/dist/assets/examples/ko/08_Math/07_additivewave.js @@ -0,0 +1,67 @@ +/* + * @name 파형 추가 + * @description 두 개의 파형을 합쳐 좀 더 복잡한 파도 모양을 만듭니다. + * 원본 제작: 다니엘 쉬프만(Daniel Shiffman) + */ +let xspacing = 8; // 각 타원 간 가로 거리 +let w; // 전체 파형의 너비 +let maxwaves = 4; // 더해진 파형들의 전체 개수 + +let theta = 0.0; +let amplitude = new Array(maxwaves); // 파형의 높이 +// X를 증가하는 값으로, period와 xspacing로 계산됨 +let dx = new Array(maxwaves); +// 파형의 최고 높이를 저장하기 위한 배열 (반드시 필요한 건 아님) +let yvalues; + +function setup() { + createCanvas(710, 400); + frameRate(30); + colorMode(RGB, 255, 255, 255, 100); + w = width + 16; + + for (let i = 0; i < maxwaves; i++) { + amplitude[i] = random(10, 30); + let period = random(100, 300); // 파형이 반복되기 전까지 생성되는 픽셀 갯수 + dx[i] = (TWO_PI / period) * xspacing; + } + + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // 세타값(theta) 증가 (다른 값을 넣어 각속도를 조정해보세요) + theta += 0.02; + + // 모든 높이값을 0으로 설정 + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = 0; + } + + // 파형 높이값 축적하기 + for (let j = 0; j < maxwaves; j++) { + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + // 매번 모든 파형들은 싸인 대신 코싸인으로 처리 + if (j % 2 == 0) yvalues[i] += sin(x) * amplitude[j]; + else yvalues[i] += cos(x) * amplitude[j]; + x += dx[j]; + } + } +} + +function renderWave() { + // 각 위치에 지정된 타원형으로 파형을 그릴 수 있는 간단한 방법 + noStroke(); + fill(255, 50); + ellipseMode(CENTER); + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, width / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/ko/08_Math/08_polartocartesian.js b/dist/assets/examples/ko/08_Math/08_polartocartesian.js new file mode 100644 index 0000000000..834cad7159 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/08_polartocartesian.js @@ -0,0 +1,44 @@ +/* + * @name 극좌표를 직교 좌표로 + * @description 극좌표(지름 r, 세타 theta)를 직교 좌표(x,y)로 변환 + * : x = rcos(theta) y = rsin(theta) + * 원본 제작: 다니엘 쉬프만(Daniel Shiffman) + */ +let r; + +// 각도, 각속도, 가속 +let theta; +let theta_vel; +let theta_acc; + +function setup() { + createCanvas(710, 400); + + // 모든값 초기화 + r = height * 0.45; + theta = 0; + theta_vel = 0; + theta_acc = 0.0001; +} + +function draw() { + background(0); + + // 원점을 화면 중간 위치에 해당하는 좌표값으로 설정 + translate(width / 2, height / 2); + + // 극좌표를 직교 좌표로 변환 + let x = r * cos(theta); + let y = r * sin(theta); + + // 직교 좌표에서 타원 그리기 + ellipseMode(CENTER); + noStroke(); + fill(200); + ellipse(x, y, 32, 32); + + // 가속도와 속도를 각도에 적용하기 + // (이 예제에서 r은 고정됩니다.) + theta_vel += theta_acc; + theta += theta_vel; +} diff --git a/dist/assets/examples/ko/08_Math/09_arctangent.js b/dist/assets/examples/ko/08_Math/09_arctangent.js new file mode 100644 index 0000000000..21c053b7fd --- /dev/null +++ b/dist/assets/examples/ko/08_Math/09_arctangent.js @@ -0,0 +1,45 @@ +/* + * @name 아크탄젠트 + * @description 마우스를 움직여 눈의 방향을 바꿔보세요.
atan2()함수는 마우스 커서와 눈의 각도를 계산합니다. + */ +let e1, e2, e3; + +function setup() { + createCanvas(720, 400); + noStroke(); + e1 = new Eye(250, 16, 120); + e2 = new Eye(164, 185, 80); + e3 = new Eye(420, 230, 220); +} + +function draw() { + background(102); + e1.update(mouseX, mouseY); + e2.update(mouseX, mouseY); + e3.update(mouseX, mouseY); + e1.display(); + e2.display(); + e3.display(); +} + +function Eye(tx, ty, ts) { + this.x = tx; + this.y = ty; + this.size = ts; + this.angle = 0; + + this.update = function(mx, my) { + this.angle = atan2(my - this.y, mx - this.x); + }; + + this.display = function() { + push(); + translate(this.x, this.y); + fill(255); + ellipse(0, 0, this.size, this.size); + rotate(this.angle); + fill(153, 204, 0); + ellipse(this.size / 4, 0, this.size / 2, this.size / 2); + pop(); + }; +} diff --git a/dist/assets/examples/ko/08_Math/10_Interpolate.js b/dist/assets/examples/ko/08_Math/10_Interpolate.js new file mode 100644 index 0000000000..1659c1ce3c --- /dev/null +++ b/dist/assets/examples/ko/08_Math/10_Interpolate.js @@ -0,0 +1,32 @@ +/* + * @name 선형 보간법 + * @frame 720, 400 + * @description 화면 위로 마우스를 움직이면 타원이 따라옵니다. + * 애니메이션의 매 프레임 사이에, 타원은 현재 위치에서 커서를 향해 지정된 거리(0.05)의 일부만큼 움직입니다. + * 이는 lerp() 함수를 사용하여 구현된 것입니다. + * 이 예제는 이징(Easing) 예제와 동일한 효과를 만들지만, lerp()만으로 구현한다는 점에서 다릅니다. + */ + +let x = 0; +let y = 0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(51); + + // lerp()는 특정 값만큼 증가하는 두 개의 숫자로부터 그 결과값을 계산합니다. + // amt인수는 이 두 개의 숫자를 선형적으로 결정하는데, + // 0.0은 처음 위치, 0.1은 첫번째 점과 아주 가까운 위치, 0.5는 앞의 두 점의 중간 위치인 식입니다. + + // 매 프레임마다 마우스 위치를 향해 5%의 거리를 움직이도록 합니다. + x = lerp(x, mouseX, 0.05); + y = lerp(y, mouseY, 0.05); + + fill(255); + stroke(255); + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/ko/08_Math/11_doubleRandom.js b/dist/assets/examples/ko/08_Math/11_doubleRandom.js new file mode 100644 index 0000000000..de03e23121 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/11_doubleRandom.js @@ -0,0 +1,24 @@ +/* + * @name 이중 랜덤 + * @frame 720,400 (optional) + * @description random() 호출과 point()함수를 이중으로 사용하여 + * 불규칙한 톱니 모양의 선을 만듭니다. + * 원본 제작: 이라 그린버그(Ira Greenberg) + */ +let totalPts = 300; +let steps = totalPts + 1; + +function setup() { + createCanvas(710, 400); + stroke(255); + frameRate(1); +} + +function draw() { + background(0); + let rand = 0; + for (let i = 1; i < steps; i++) { + point((width / steps) * i, height / 2 + random(-rand, rand)); + rand += random(-5, 5); + } +} diff --git a/dist/assets/examples/ko/08_Math/12_random.js b/dist/assets/examples/ko/08_Math/12_random.js new file mode 100644 index 0000000000..558f3beebf --- /dev/null +++ b/dist/assets/examples/ko/08_Math/12_random.js @@ -0,0 +1,19 @@ +/* + * @name 랜덤 + * @description 난수(random number)에 근간을 둔 이미지입니다. + * 프로그램이 불러오기될 때마다 결과가 달라집니다. + */ +function setup() { + createCanvas(710, 400); + background(0); + strokeWeight(20); + frameRate(2); +} + +function draw() { + for (let i = 0; i < width; i++) { + let r = random(255); + stroke(r); + line(i, 0, i, height); + } +} diff --git a/dist/assets/examples/ko/08_Math/13_noise1D.js b/dist/assets/examples/ko/08_Math/13_noise1D.js new file mode 100644 index 0000000000..5ef5783292 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/13_noise1D.js @@ -0,0 +1,31 @@ +/* + * @name 1D 노이즈 + * @description 1차원 펄린 노이즈를 사용해 위치를 지정합니다. + */ +let xoff = 0.0; +let xincrement = 0.01; + +function setup() { + createCanvas(710, 400); + background(0); + noStroke(); +} + +function draw() { + // 알파값이 섞인 배경 생성 + fill(0, 10); + rect(0, 0, width, height); + + //let n = random(0,width); // 노이즈 대신 이 코드를 사용할 수 있습니다. + + // xoff로 노이즈값을 지정하고 + // 화면의 너비에 따라 크기 조정 + let n = noise(xoff) * width; + + // 매 사이클마다 xoff만큼 증가 + xoff += xincrement; + + // 펄린 노이즈가 생성한 값으로 타원 그리기 + fill(200); + ellipse(n, height / 2, 64, 64); +} diff --git a/dist/assets/examples/ko/08_Math/14_noisewave.js b/dist/assets/examples/ko/08_Math/14_noisewave.js new file mode 100644 index 0000000000..557ef533c1 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/14_noisewave.js @@ -0,0 +1,42 @@ +/* + * @name 노이즈 파형 + * @description 펄린 노이즈를 사용하여 파도같은 패턴을 만듭니다. + * 원본 제작: 다니엘 쉬프만(Daniel Shiffman) + */ +let yoff = 0.0; // 펄린 노이즈의 2차원 + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(51); + + fill(255); + // 파형의 점들을 이용한 다각형 그리기 + beginShape(); + + let xoff = 0; // 옵션 #1: 2D 노이즈 + // let xoff = yoff; // 옵션 #2: 1D 노이즈 + + // 가로 픽셀들에 반복 + for (let x = 0; x <= width; x += 10) { + // y값을 노이즈에 따라 계산, 다음에 매핑(map)하기 + + // 옵션 #1: 2D 노이즈 + let y = map(noise(xoff, yoff), 0, 1, 200, 300); + + // 옵션 #2: 1D 노이즈 + // let y = map(noise(xoff), 0, 1, 200,300); + + // 버텍스 설정하기 + vertex(x, y); + // 노이즈의 x차원 증가하기 + xoff += 0.05; + } + // 노이즈의 y차원 증가하기 + yoff += 0.01; + vertex(width, height); + vertex(0, height); + endShape(CLOSE); +} diff --git a/dist/assets/examples/ko/08_Math/15_Noise2D.js b/dist/assets/examples/ko/08_Math/15_Noise2D.js new file mode 100644 index 0000000000..cba42f1384 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/15_Noise2D.js @@ -0,0 +1,42 @@ +/* + * @name 2D 노이즈 + * @frame 710,400 (선택 사항) + * @description 여러 인수를 사용하여 2D 노이즈를 만들어보세요. + * + */ + +let noiseVal; +let noiseScale = 0.02; + +function setup() { + createCanvas(640, 360); +} + +function draw() { + background(0); + // 이미지의 좌측 절반 그리기 + for (let y = 0; y < height - 30; y++) { + for (let x = 0; x < width / 2; x++) { + // noiceDetail, 픽셀 옥타브와 번짐 정도 + noiseDetail(2, 0.2); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + // 이미지의 우측 절반 그리기 + for (let y = 0; y < height - 30; y++) { + for (let x = width / 2; x < width; x++) { + // noiceDetail, 픽셀 옥타브와 번짐 정도 + noiseDetail(5, 0.5); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + //두 화면의 디테일 구성하기 + textSize(18); + fill(255, 255, 255); + text('2옥타브와 0.2 번짐 정도의 2D 노이즈', 10, 350); + text('1옥타브와 0.7 번짐 정도의 2D 노이즈', 330, 350); +} diff --git a/dist/assets/examples/ko/08_Math/16_Noise3D.js b/dist/assets/examples/ko/08_Math/16_Noise3D.js new file mode 100644 index 0000000000..d060e0311b --- /dev/null +++ b/dist/assets/examples/ko/08_Math/16_Noise3D.js @@ -0,0 +1,48 @@ +/* + * @name 3D 노이즈 + * @frame 710,400 (선택 사항) + * @description 3D 노이즈를 사용하여 간단한 동적 텍스처를 만듭니다. + */ + +let noiseVal; +//x를 0.01씩 증가 +let x_increment = 0.01; +//draw()함수 사이클마다 z를 0.02씩 증가 +let z_increment = 0.02; + +//Offset values +let z_off, y_off, x_off; + +function setup() { + //캔버스 만들기 + createCanvas(640, 360); + //프레임 속도 조정 + frameRate(20); + //z_off의 초기값 + z_off = 0; +} + +function draw() { + x_off = 0; + y_off = 0; + //배경을 검정색으로 설정 + background(0); + //노이즈 디테일 조정 + noiseDetail(8, 0.65); + + //매 x,y마다 노이즈값 계산 + for (let y = 0; y < height; y++) { + x_off += x_increment; + y_off = 0; + + for (let x = 0; x < width; x++) { + //각 픽셀을 계산하고 그리기 + noiseVal = noise(x_off, y_off, z_off); + stroke(noiseVal * 255); + y_off += x_increment; + point(x, y); + } + } + + z_off += z_increment; +} diff --git a/dist/assets/examples/ko/08_Math/17_Randomchords.js b/dist/assets/examples/ko/08_Math/17_Randomchords.js new file mode 100644 index 0000000000..a77fad280a --- /dev/null +++ b/dist/assets/examples/ko/08_Math/17_Randomchords.js @@ -0,0 +1,35 @@ +/* + * @name 랜덤 선들 + * @description 원형을 그리는 무작위의 선들을 축적합니다. + * 불투명하게 처리된 선들이 축적될수록 마치 명암이 적용된 구처럼 보입니다. + * 기여: 애티쉬 바티아(Aatish Bhatia), 앤더스 호프(Anders Hoff)로부터 영감을 받음. + */ + +function setup() { + createCanvas(400, 400); + background(255, 255, 255); + + // 알파값을 활용하여 선의 불투명도를 조정 + stroke(0, 0, 0, 15); +} + +function draw() { + // 매 프레임마다 두 개의 선을 무작위로 그리기 + randomChord(); + randomChord(); +} + +function randomChord() { + // 원형 위 점 하나를 무작위로 찾기 + let angle1 = random(0, 2 * PI); + let xpos1 = 200 + 200 * cos(angle1); + let ypos1 = 200 + 200 * sin(angle1); + + // 원형 위 또다른 점 하나를 무작위로 찾기 + let angle2 = random(0, 2 * PI); + let xpos2 = 200 + 200 * cos(angle2); + let ypos2 = 200 + 200 * sin(angle2); + + // 둘 사이에 선을 긋기 + line(xpos1, ypos1, xpos2, ypos2); +} diff --git a/dist/assets/examples/ko/08_Math/18_Map.js b/dist/assets/examples/ko/08_Math/18_Map.js new file mode 100644 index 0000000000..df4f840974 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/18_Map.js @@ -0,0 +1,21 @@ +/* + * @name 매핑(map) + * @description map()함수를 통해 그 어떠한 숫자든 여러분의 프로젝트에 더 많은 도움을 줄 + * 숫자로 매핑할 수 있습니다. + * 예를 들어, 마우스 위치값을 사용하여 도형의 크기와 색상을 조정할 수 있습니다. + * 이 예제에서는 마우스의 x 좌표(0과 360사이의 숫자)가 원형의 색상과 크기를 정의하는 새로운 숫자들로 처리됩니다. + */ +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(0); + // 0부터 720에 이르는 mouseX 값을 0부터 175의 범위로 조정 + let c = map(mouseX, 0, width, 0, 175); + // 0부터 720에 이르는 mouseX 값을 40부터 300의 범위로 조정 + let d = map(mouseX, 0, width, 40, 300); + fill(255, c, 0); + ellipse(width/2, height/2, d, d); +} diff --git a/dist/assets/examples/ko/08_Math/19_parametricEquation.js b/dist/assets/examples/ko/08_Math/19_parametricEquation.js new file mode 100644 index 0000000000..553b4ea135 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/19_parametricEquation.js @@ -0,0 +1,43 @@ +/* + * @name 매개변수 방정식 + * @description 매개변수 방정식은 x와 y 좌표값이 다른 문자로서 표기된 식을 말합니다. + * 이러한 문자를 매개변수라 부르며, 일반적으로 t 또는 θ로 표기됩니다. + * 알렉산더 밀러(Alexander Miller)의 유투브 채널로부터 영감을 얻었습니다. + */ + +function setup(){ + createCanvas(720,400); +} + +// x와 y의 매개변수는 일반적으로 세타(theta)를 뜻하는 't' 또는 그 기호(θ)로 표기됩니다. +let t = 0; +function draw(){ + background('#fff'); + translate(width/2,height/2); + stroke('#0f0f0f'); + strokeWeight(1.5); + //100개의 선 추가를 위한 반복문 + for(let i = 0;i<100;i++){ + line(x1(t+i),y1(t+i),x2(t+i)+20,y2(t+i)+20); + } + t+=0.15; +} +// 선의 초기 x 좌표값을 변경하는 함수 +function x1(t){ + return sin(t/10)*125+sin(t/20)*125+sin(t/30)*125; +} + +// 선의 초기 y 좌표값을 변경하는 함수 +function y1(t){ + return cos(t/10)*125+cos(t/20)*125+cos(t/30)*125; +} + +// 선의 최종 x 좌표값을 변경하는 함수 +function x2(t){ + return sin(t/15)*125+sin(t/25)*125+sin(t/35)*125; +} + +// 선의 최종 y 좌표값을 변경하는 함수 +function y2(t){ + return cos(t/15)*125+cos(t/25)*125+cos(t/35)*125; +} \ No newline at end of file diff --git a/dist/assets/examples/ko/08_Math/20_Graphing2DEquations.js b/dist/assets/examples/ko/08_Math/20_Graphing2DEquations.js new file mode 100644 index 0000000000..af71814bbb --- /dev/null +++ b/dist/assets/examples/ko/08_Math/20_Graphing2DEquations.js @@ -0,0 +1,52 @@ +/** + * @name Graphing 2D Equations + * @frame 710, 400 + * @description Graphics the following equation: sin(n cos(r) + 5θ) where n is a function of horizontal mouse location. Original by Daniel Shiffman + */ +function setup() { + createCanvas(710, 400); + pixelDensity(1); +} + +function draw() { + loadPixels(); + let n = (mouseX * 10.0) / width; + const w = 16.0; // 2D space width + const h = 16.0; // 2D space height + const dx = w / width; // Increment x this amount per pixel + const dy = h / height; // Increment y this amount per pixel + let x = -w / 2; // Start x at -1 * width / 2 + let y; + + let r; + let theta; + let val; + + let bw; //variable to store grayscale + let i; + let j; + let cols = width; + let rows = height; + + for (i = 0; i < cols; i += 1) { + y = -h / 2; + for (j = 0; j < rows; j += 1) { + r = sqrt(x * x + y * y); // Convert cartesian to polar + theta = atan2(y, x); // Convert cartesian to polar + // Compute 2D polar coordinate function + val = sin(n * cos(r) + 5 * theta); // Results in a value between -1 and 1 + //var val = cos(r); // Another simple function + //var val = sin(theta); // Another simple function + bw = color(((val + 1) * 255) / 2); + index = 4 * (i + j * width); + pixels[index] = red(bw); + pixels[index + 1] = green(bw); + pixels[index + 2] = blue(bw); + pixels[index + 3] = alpha(bw); + + y += dy; + } + x += dx; + } + updatePixels(); +} diff --git a/dist/assets/examples/ko/08_Math/21_parametricEquation.js b/dist/assets/examples/ko/08_Math/21_parametricEquation.js new file mode 100644 index 0000000000..83c1a3c336 --- /dev/null +++ b/dist/assets/examples/ko/08_Math/21_parametricEquation.js @@ -0,0 +1,44 @@ +/* + * @name Parametric Equations + * @description A parametric equation is where x and y + * coordinates are both written in terms of another letter. This is + * called a parameter and is usually given in the letter t or θ. + * The inspiration was taken from the YouTube channel of Alexander Miller. + */ + +function setup(){ + createCanvas(720,400); +} + +// the parameter at which x and y depends is usually taken as either t or symbol of theta +let t = 0; +function draw(){ + background('#fff'); + translate(width/2,height/2); + stroke('#0f0f0f'); + strokeWeight(1.5); + //loop for adding 100 lines + for(let i = 0;i<100;i++){ + line(x1(t+i),y1(t+i),x2(t+i)+20,y2(t+i)+20); + } + t+=0.15; +} +// function to change initial x co-ordinate of the line +function x1(t){ + return sin(t/10)*125+sin(t/20)*125+sin(t/30)*125; +} + +// function to change initial y co-ordinate of the line +function y1(t){ + return cos(t/10)*125+cos(t/20)*125+cos(t/30)*125; +} + +// function to change final x co-ordinate of the line +function x2(t){ + return sin(t/15)*125+sin(t/25)*125+sin(t/35)*125; +} + +// function to change final y co-ordinate of the line +function y2(t){ + return cos(t/15)*125+cos(t/25)*125+cos(t/35)*125; +} \ No newline at end of file diff --git a/dist/assets/examples/ko/09_Simulate/00_Forces.js b/dist/assets/examples/ko/09_Simulate/00_Forces.js new file mode 100644 index 0000000000..ee8b1df54a --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/00_Forces.js @@ -0,0 +1,147 @@ +/* + * @name 힘 + * @description 바디 객체에 작용하는 여러가지 물리학적 힘 + * (natureofcode.com) + */ +// 바디에 적용되는 여러가지 물리학적 힘(Mover 클래스) +// 바디는 중력을 끊임없이 경험합니다. +// 바디는 물 속에서 유체 저항을 경험합니다. + +// 5개의 움직이는 형체 +let movers = []; + +// Liquid +let liquid; + +function setup() { + createCanvas(640, 360); + reset(); + // liquid(액체) 객체 생성 + liquid = new Liquid(0, height / 2, width, height / 2, 0.1); +} + +function draw() { + background(127); + + // 물 그리기 + liquid.display(); + + for (let i = 0; i < movers.length; i++) { + + // Mover가 액체인가요? + if (liquid.contains(movers[i])) { + // 항력 계산하기 + let dragForce = liquid.calculateDrag(movers[i]); + // Mover에 항력 적용하기 + movers[i].applyForce(dragForce); + } + + // 중력은 여기서 mass(질량)에 따라 결정됩니다! + let gravity = createVector(0, 0.1 * movers[i].mass); + // 중력 적용하기 + movers[i].applyForce(gravity); + + // 업데이트하고 화면에 보이기(display) + movers[i].update(); + movers[i].display(); + movers[i].checkEdges(); + } + +} + + +function mousePressed() { + reset(); +} + +// 모든 Mover 오브젝트들을 무작위로 재시작하기 +function reset() { + for (let i = 0; i < 9; i++) { + movers[i] = new Mover(random(0.5, 3), 40 + i * 70, 0); + } +} + +let Liquid = function(x, y, w, h, c) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + this.c = c; +}; + +// Mover가 액체인가요? +Liquid.prototype.contains = function(m) { + let l = m.position; + return l.x > this.x && l.x < this.x + this.w && + l.y > this.y && l.y < this.y + this.h; +}; + +// 항력 계산하기 +Liquid.prototype.calculateDrag = function(m) { + // Magnitue(크기) = 계수 * speed(속도)의 제곱 + let speed = m.velocity.mag(); + let dragMagnitude = this.c * speed * speed; + + // 방향은 속도와 반대쪽으로 + let dragForce = m.velocity.copy(); + dragForce.mult(-1); + + // 힘의 크기에 따라 조정하기 + // dragForce.setMag(dragMagnitude); + dragForce.normalize(); + dragForce.mult(dragMagnitude); + return dragForce; +}; + +Liquid.prototype.display = function() { + noStroke(); + fill(50); + rect(this.x, this.y, this.w, this.h); +}; + +function Mover(m, x, y) { + this.mass = m; + this.position = createVector(x, y); + this.velocity = createVector(0, 0); + this.acceleration = createVector(0, 0); +} + +// 뉴턴(Newton)의 두번째 법칙: F = M * A +// 또는 A = F / M +Mover.prototype.applyForce = function(force) { + let f = p5.Vector.div(force, this.mass); + this.acceleration.add(f); +}; + +Mover.prototype.update = function() { + // 가속도에 따라 변하는 속도 + this.velocity.add(this.acceleration); + // 속도에 따라 변하는 위치 + this.position.add(this.velocity); + // 매 프레임마다 가속도 초기화 + this.acceleration.mult(0); +}; + +Mover.prototype.display = function() { + stroke(0); + strokeWeight(2); + fill(255,127); + ellipse(this.position.x, this.position.y, this.mass * 16, this.mass * 16); +}; + +// 바닥면에서 튀어오르기 +Mover.prototype.checkEdges = function() { + if (this.position.y > (height - this.mass * 8)) { + // 바닥면에 닿을 때 약간의 완충 현상 발생 + this.velocity.y *= -0.9; + this.position.y = (height - this.mass * 8); + } +}; + + + + + + + + diff --git a/dist/assets/examples/ko/09_Simulate/01_ParticleSystem.js b/dist/assets/examples/ko/09_Simulate/01_ParticleSystem.js new file mode 100644 index 0000000000..81ea5dd585 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/01_ParticleSystem.js @@ -0,0 +1,69 @@ +/* + * @name 파티클 시스템 + * @description 이 예제는 기초적인 파티클 시스템을 다룹니다. + * (natureofcode.com) + */ +let system; + +function setup() { + createCanvas(720, 400); + system = new ParticleSystem(createVector(width / 2, 50)); +} + +function draw() { + background(51); + system.addParticle(); + system.run(); +} + +// 간단한 파티클 클래스 +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// 위치 업데이트를 위한 메소드 +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// 화면에 보이기 위한 메소드 +Particle.prototype.display = function() { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// 파티클이 여전히 쓸만한가요? +Particle.prototype.isDead = function(){ + return this.lifespan < 0; +}; + +let ParticleSystem = function(position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin)); +}; + +ParticleSystem.prototype.run = function() { + for (let i = this.particles.length-1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; diff --git a/dist/assets/examples/ko/09_Simulate/02_Flocking.js b/dist/assets/examples/ko/09_Simulate/02_Flocking.js new file mode 100644 index 0000000000..55fa0b262b --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/02_Flocking.js @@ -0,0 +1,229 @@ +/* + * @name 플로킹 + * @description 크레이그 레이놀즈(Craig Reynolds)의 "군집(Flocking)" 행위를 묘사합니다. + * 참고: http://www.red3d.com/cwr/ + * 규칙: 응집, 분리, 정렬 + * (출처: natureofcode.com). + * 마우스를 드래그하여 시스템에 개체(boid)를 더해보세요. + */ + + +let flock; + +function setup() { + createCanvas(640, 360); + createP("Drag the mouse to generate new boids."); + + flock = new Flock(); + // 시스템에 초기 개체(boid) 더하기 + for (let i = 0; i < 100; i++) { + let b = new Boid(width / 2,height / 2); + flock.addBoid(b); + } +} + +function draw() { + background(51); + flock.run(); +} + +// 시스템에 새로운 개체 더하기 +function mouseDragged() { + flock.addBoid(new Boid(mouseX, mouseY)); +} + +// The Nature of Code +// 다니엘 쉬프만(Daniel Shiffman) +// http://natureofcode.com + +// Flock 객체는 +// 모든 개체(boid)의 배열을 관리하는, 간단한 작업을 수행합니다. + +function Flock() { + // 모든 개체의 배열 + this.boids = []; // 배열 초기화 +} + +Flock.prototype.run = function() { + for (let i = 0; i < this.boids.length; i++) { + this.boids[i].run(this.boids); // 전체 보이즈 개체 목록을 각 개체에 보내기 + } +} + +Flock.prototype.addBoid = function(b) { + this.boids.push(b); +} + +// The Nature of Code +// 다니엘 쉬프만(Daniel Shiffman) +// http://natureofcode.com + +// Boid(개체) 클래스 +// 응집(cohesion), 분리(seperation), 정렬(alignment)을 위한 메소드 추가 + +function Boid(x, y) { + this.acceleration = createVector(0, 0); + this.velocity = createVector(random(-1, 1), random(-1, 1)); + this.position = createVector(x, y); + this.r = 3.0; + this.maxspeed = 3; // 최대 속도 + this.maxforce = 0.05; // 최대 조타력 +} + +Boid.prototype.run = function(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); +} + +Boid.prototype.applyForce = function(force) { + // A = F / M 으로 계산하고 싶다면, 여기에 질량을 더하면 됩니다. + this.acceleration.add(force); +} + +// 3가지 규칙에 따라 매번 새로운 가속도를 만듭니다. +Boid.prototype.flock = function(boids) { + let sep = this.separate(boids); // 분리 + let ali = this.align(boids); // 정렬 + let coh = this.cohesion(boids); // 응집 + // 세 힘들을 임의로 가중하기 + sep.mult(1.5); + ali.mult(1.0); + coh.mult(1.0); + // 가속도에 force 벡터 더하기 + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); +} + +// 위치 업데이트를 위한 메소드 +Boid.prototype.update = function() { + // 속도 업데이트 + this.velocity.add(this.acceleration); + // 속도 제한 + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // 매 사이클마다 가속도를 0으로 리셋 + this.acceleration.mult(0); +} + +// 특정 목표점을 향한 조타력을 계산하고 적용하는 메소드 +// STEER(조타력) = DESIRED(목표점) - VELOCITY(속도) +Boid.prototype.seek = function(target) { + let desired = p5.Vector.sub(target,this.position); // 현위치에서 목표점을 가리키는 벡터 + // desired를 표준화하고 최대 속도로 조정 + desired.normalize(); + desired.mult(this.maxspeed); + // Steering = Desired minus Velocity + let steer = p5.Vector.sub(desired,this.velocity); + steer.limit(this.maxforce); // 최대 조타력으로 제한 + return steer; +} + +Boid.prototype.render = function() { + // 속도의 방향에 따라 회전하는 삼각형 그리기 + let theta = this.velocity.heading() + radians(90); + fill(127); + stroke(200); + push(); + translate(this.position.x, this.position.y); + rotate(theta); + beginShape(); + vertex(0, -this.r * 2); + vertex(-this.r, this.r * 2); + vertex(this.r, this.r * 2); + endShape(CLOSE); + pop(); +} + +// Wraparound +Boid.prototype.borders = function() { + if (this.position.x < -this.r) this.position.x = width + this.r; + if (this.position.y < -this.r) this.position.y = height + this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height + this.r) this.position.y = -this.r; +} + +// 분리 Seperation +// 인근의 개체를 확인하고 이로부터 거리를 유지하며 조타하게 만드는 메소드 +Boid.prototype.separate = function(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // 매 개체가 시스템에 생성될 때마다, 서로 너무 가까운 위치에 있는지 여부를 확인 + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + // 만약 그 거리가 0보다 크고 임의의 값보다 작다면(0은 개체의 현위치) + if ((d > 0) && (d < desiredseparation)) { + // 인근의 개체로부터 떨어진 지점을 향하는 벡터 계산 + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // 거리에 따른 가중 + steer.add(diff); + count++; // 개체수 카운트 + } + } + // 평균 -- 얼마로 나눌 것인가 + if (count > 0) { + steer.div(count); + } + + // 벡터가 0보다 크다면, + if (steer.mag() > 0) { + // 레이놀즈의 공식 Steering = Desired - Velocity을 적용한다. + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; +} + +// 배열 Alignment +// 서로 인근에 있는 모든 개체에 대한 평균 속도 계산 +Boid.prototype.align = function(boids) { + let neighbordist = 50; + let sum = createVector(0,0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } +} + +// 응집 Cohesion +// 서로 인근에 있는 모든 개체의 평균 위치값(예: 중앙)에 대해, 이 지점을 향한 조타 벡터값 계산 +Boid.prototype.cohesion = function(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // 빈 벡터값으로 시작하여 모든 위치들을 축적 + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position,boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // 위치 추가 + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // 해당 위치를 향해 조타 + } else { + return createVector(0, 0); + } +} + + diff --git a/dist/assets/examples/ko/09_Simulate/03_WolframCA.js b/dist/assets/examples/ko/09_Simulate/03_WolframCA.js new file mode 100644 index 0000000000..6472f7d97f --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/03_WolframCA.js @@ -0,0 +1,73 @@ +/* + * @name 울프램 셀룰러 오토마타 + * @description 1차원 셀룰러 오토마타(cellular automata) 간단하게 구현하기. + * (natureofcode.com) + */ + +let w = 10; +// 0과 1들의 배열 +let cells; + + // "1"의 상태를 갖는 중간 셀과 함께 시작합니다. +let generation = 0; + +// {0,1,1,0,1,1,0,1}과 같은 규칙 묶음(ruleset)을 저장하는 배열 +let ruleset = [0, 1, 0, 1, 1, 0, 1, 0]; + +function setup() { + createCanvas(640, 400); + cells = Array(floor(width / w)); + for (let i = 0; i < cells.length; i++) { + cells[i] = 0; + } + cells[cells.length/2] = 1; + +} + +function draw() { + for (let i = 0; i < cells.length; i++) { + if (cells[i] === 1) { + fill(200); + } else { + fill(51); + noStroke(); + rect(i * w, generation * w, w, w); + } + } + if (generation < height/w) { + generate(); + } +} + +// 새로운 세대(generation) 생성 과정 +function generate() { + // 먼저, 새로운 값을 위한 빈 배열을 만듭니다. + let nextgen = Array(cells.length); + // 매 셀마다 현재 상태를 확인하여 새로운 상태를 결정하고 이 둘을 이웃하게 만듭니다. + // 모서리에 위치하여 한 개의 이웃만을 가진 상태는 무시합니다. + for (let i = 1; i < cells.length-1; i++) { + let left = cells[i-1]; // 좌측 이웃 상태 + let me = cells[i]; // 현재 상태 + let right = cells[i+1]; // 우측 이웃 상태 + nextgen[i] = rules(left, me, right); // 다음 세대 상태를 규칙 묶음(ruleset)에 의거하여 계산 + } + // 현재 상태가 새로운 세대가 됩니다. + cells = nextgen; + generation++; +} + + +// 울프램 규칙 구현하기 +// 더 향상되거나 간결해질 수도 있지만, 여기서 각 사례별로 어떤 일이 일어나는지 명확히 볼 수 있습니다. +function rules(a, b, c) { + if (a == 1 && b == 1 && c == 1) return ruleset[0]; + if (a == 1 && b == 1 && c == 0) return ruleset[1]; + if (a == 1 && b == 0 && c == 1) return ruleset[2]; + if (a == 1 && b == 0 && c == 0) return ruleset[3]; + if (a == 0 && b == 1 && c == 1) return ruleset[4]; + if (a == 0 && b == 1 && c == 0) return ruleset[5]; + if (a == 0 && b == 0 && c == 1) return ruleset[6]; + if (a == 0 && b == 0 && c == 0) return ruleset[7]; + return 0; +} + diff --git a/dist/assets/examples/ko/09_Simulate/04_GameOfLife.js b/dist/assets/examples/ko/09_Simulate/04_GameOfLife.js new file mode 100644 index 0000000000..d203b1a791 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/04_GameOfLife.js @@ -0,0 +1,95 @@ +/* + * @name 라이프 게임 + * @description 존 콘웨이(John Conway)의 라이프 게임 셀룰러 오토마타 + * (Game of Life Cellular Automata)의 기초적 구현 + * (natureofcode.com) + */ + +let w; +let columns; +let rows; +let board; +let next; + +function setup() { + createCanvas(720, 400); + w = 20; + // 행렬 계산하기 + columns = floor(width / w); + rows = floor(height / w); + // JS를 사용하여 요상한 2D 배열 만들기 + board = new Array(columns); + for (let i = 0; i < columns; i++) { + board[i] = new Array(rows); + } + // 복수의 2D 배열을 만들고 바꾸기 + next = new Array(columns); + for (i = 0; i < columns; i++) { + next[i] = new Array(rows); + } + init(); +} + +function draw() { + background(255); + generate(); + for ( let i = 0; i < columns;i++) { + for ( let j = 0; j < rows;j++) { + if ((board[i][j] == 1)) fill(0); + else fill(255); + stroke(0); + rect(i * w, j * w, w-1, w-1); + } + } + +} + +// 마우스 버튼 클릭시 보드 리셋하기 +function mousePressed() { + init(); +} + +// 무작위로 보드 채우기 +function init() { + for (let i = 0; i < columns; i++) { + for (let j = 0; j < rows; j++) { + // 0으로 모서리 테두리 그리기 + if (i == 0 || j == 0 || i == columns-1 || j == rows-1) board[i][j] = 0; + // 나머지는 무작위로 채우기 + else board[i][j] = floor(random(2)); + next[i][j] = 0; + } + } +} + +// 새로운 세대 생성하는 과정 +function generate() { + + // 2D 배열 상 모든 셀들을 걸쳐 반복하며 각 셀별 이웃 확인하기 + for (let x = 1; x < columns - 1; x++) { + for (let y = 1; y < rows - 1; y++) { + // 3x3의 주변 그리드에 모든 상태들을 더하여 넣기 + let neighbors = 0; + for (let i = -1; i <= 1; i++) { + for (let j = -1; j <= 1; j++) { + neighbors += board[x+i][y+j]; + } + } + + // 위의 반복을 통해 모든 셀들의 현재 상태를 계산해 넣었으므로, + // 이 계산을 빼주는 요령 + neighbors -= board[x][y]; + // 라이프 규칙 + if ((board[x][y] == 1) && (neighbors < 2)) next[x][y] = 0; // 외로움 + else if ((board[x][y] == 1) && (neighbors > 3)) next[x][y] = 0; // 인구과잉 + else if ((board[x][y] == 0) && (neighbors == 3)) next[x][y] = 1; // 재생산 + else next[x][y] = board[x][y]; // 균형 + } + } + + // 바꾸기! + let temp = board; + board = next; + next = temp; +} + diff --git a/dist/assets/examples/ko/09_Simulate/05_MultipleParticleSystems.js b/dist/assets/examples/ko/09_Simulate/05_MultipleParticleSystems.js new file mode 100644 index 0000000000..2c7cb25c9d --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/05_MultipleParticleSystems.js @@ -0,0 +1,137 @@ +/* + * @name 멀티플 파티클 시스템 + * @description 마우스를 클릭한 위치에서 파티클이 폭발적으로 생성되도록 만들어보세요.
매 폭발은 Particle 클래스의 하위 클래스인 Particles와 CrazyParticles + * 의 한 인스턴스에 해당합니다.
클래스 상속과 다형 사용에 대한 방법을 확인해보세요.
+ * 원본 제작: 다니엘 쉬프만(Daniel Shiffman) + */ +let systems; + +function setup() { + createCanvas(710, 400); + systems = []; +} + +function draw() { + background(51); + background(0); + for (i = 0; i < systems.length; i++) { + systems[i].run(); + systems[i].addParticle(); + } + if (systems.length == 0) { + fill(255); + textAlign(CENTER); + textSize(32); + text("click mouse to add particle systems", width / 2, height / 2); + } +} + +function mousePressed() { + this.p = new ParticleSystem(createVector(mouseX, mouseY)); + systems.push(p); +} + +// 간단한 파티클 클래스 +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255.0; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// 위치 업데이트를 위한 메소드 +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// 화면에 보이기 위한 메소드 +Particle.prototype.display = function () { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// 파티클이 여전히 쓸만한가요? +Particle.prototype.isDead = function () { + if (this.lifespan < 0) { + return true; + } else { + return false; + } +}; + +let ParticleSystem = function (position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function () { + // Particle 또는 CrazyParticle을 시스템에 더하기 + if (int(random(0, 2)) == 0) { + p = new Particle(this.origin); + } + else { + p = new CrazyParticle(this.origin); + } + this.particles.push(p); +}; + +ParticleSystem.prototype.run = function () { + for (let i = this.particles.length - 1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; + +// Particle의 하위 클래스 + +function CrazyParticle(origin) { + // 부모 생성자(constructor) 만들기 + // 이 때, Function#call을 사용하여 "this"가 올바르게 설정되었는지 확인합니다. + Particle.call(this, origin); + + // 더해진 속성들 초기화하기 + this.theta = 0.0; +}; + +// Particle.prototype을 상속하는 Crazy.prototype 오브젝트 만들기 +// 주의: 여기서 자주 발생하는 실수는, Crazy.prototype을 만들기 위해 새로운 "particle()"함수를 쓰는 것입니다. +// 이는 여러가지 이유로 적당하지 않은데, 특히 Particle에 "origin" 인수를 제공할 게 없다는 점에서 그렇습니다. +// Particle은 위와 같이 Crazy에서 호출하면 됩니다. +CrazyParticle.prototype = Object.create(Particle.prototype); // 아래의 주석을 보세요. + +// "constructor(생성자)" 속성이 CrazyParticle을 참조하게 설정하기 +CrazyParticle.prototype.constructor = CrazyParticle; + +// 여기서 우리는 run()메소드를 쓰지 않습니다. Particle로부터 상속되었기 때문입니다. + +// 이 update() 메소드는 부모 클래스의 update() 메소드를 오버라이드합니다. +CrazyParticle.prototype.update=function() { + Particle.prototype.update.call(this); + // 가로 속도에 따라 회전값 증가하기 + this.theta += (this.velocity.x * this.velocity.mag()) / 10.0; +} + +// 이 display() 메소드는 부모 클래스의 display() 메소드를 오버라이드합니다. +CrazyParticle.prototype.display=function() { + // 타원형을 일반적인 파티클처럼 렌더링하기 + Particle.prototype.display.call(this); + // 그 다음, 회전하는 선들 더하기 + push(); + translate(this.position.x, this.position.y); + rotate(this.theta); + stroke(255, this.lifespan); + line(0, 0, 25, 0); + pop(); +} diff --git a/dist/assets/examples/ko/09_Simulate/06_Spirograph.js b/dist/assets/examples/ko/09_Simulate/06_Spirograph.js new file mode 100644 index 0000000000..bdbb38b12e --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/06_Spirograph.js @@ -0,0 +1,73 @@ + +/* + * @name 스피로그래프 + * @description 일명 싸인이라 불리는 서로 맞물린 원형들을 이용하여, + * 스피로그래프와 같은 효과를 만드는 간단한 변형 예제를 소개합니다. + * 스페이스바를 눌러 스피로그래프 화면이나, 이것의 기하 궤도 추적 화면으로 전환해보세요.
+ * 이 예제는 R. Luke DuBois가 제작하였습니다.
+ * http://en.wikipedia.org/wiki/Spirograph + */ +let NUMSINES = 20; // 얼마나 싸인을 많은 동시에 그릴 건가요? +let sines = new Array(NUMSINES); // 현재 각도들을 모두 저장하는 배열 +let rad; // 중심 싸인의 초기 반지름값 +let i; // 카운터 변수 + +// 아래의 값들을 갖고 놀며 어떤 일이 일어나는 건지 감잡아 보세요! +let fund = 0.005; // 중심 싸인의 속도 +let ratio = 1; // 더해진 각 싸인은 속도에 몇을 곱하나요? +let alpha = 50; // 궤도 추적 시스템의 투명도 + +let trace = false; // 추적 중인가요? + +function setup() { + createCanvas(710, 400); + + rad = height / 4; // 중심 원의 반지름 계산 + background(204); // 화면 비우기 + + for (let i = 0; i + * 제작: R. Luke DuBois
+ * https://en.wikipedia.org/wiki/L-system + */ +// 거북이: +let x, y; // 거북이의 현재 위치 +let currentangle = 0; // 거북이가 가리키는 방향w +let step = 20; // 매 'F'마다 거북이가 움직이는 크기 +let angle = 90; // '-' 또는 '+'에 따라 거북이가 회전하는 크기 + +// 린덴마이어 시스템(L-SYSTEMS) +let thestring = 'A'; // 공리, 또는 문자열의 시작 +let numloops = 5; // 전처리할 반복문 개수 +let therules = []; // 규칙 배열 +therules[0] = ['A', '-BF+AFA+FB-']; // 첫 번째 규칙 +therules[1] = ['B', '+AF-BFB-FA+']; // 두 번째 규칙 + +let whereinstring = 0; // L-시스템 상 현재 위치? + +function setup() { + createCanvas(710, 400); + background(255); + stroke(0, 0, 0, 255); + + // 좌측 하단 코너에서 x와 y 위치 시작 + x = 0; + y = height-1; + + // L-시스템 처리하기 + for (let i = 0; i < numloops; i++) { + thestring = lindenmayer(thestring); + } +} + +function draw() { + + // 현재의 문자를 문자열로 그리기: + drawIt(thestring[whereinstring]); + + // 문자열을 읽는 지점 증가하기 + // 마지막에 wrap around + whereinstring++; + if (whereinstring > thestring.length-1) whereinstring = 0; + +} + +// L-시스템 해석하기 +function lindenmayer(s) { + let outputstring = ''; // 빈 출력 문자열 시작하기 + + // 'therules'를 반복하여 일치하는 기호 찾기: + for (let i = 0; i < s.length; i++) { + let ismatch = 0; // 기본값으로, 일치하는 기호 없음 + for (let j = 0; j < therules.length; j++) { + if (s[i] == therules[j][0]) { + outputstring += therules[j][1]; // 대체내용 작성 + ismatch = 1; // 일치하는 기호가 있으므로 복사하지 않음 + break; // for() 반복문 나오기 + } + } + // 일치하는 기호가 없으면 복사 + if (ismatch == 0) outputstring+= s[i]; + } + + return outputstring; // 수정된 문자열 전송 +} + +// 아래는 거북이를 그리는 사용자 정의 함수입니다. +function drawIt(k) { + + if (k=='F') { // 앞으로 그리기 + // step과 currentangle을 기준으로, 극좌표에서 직교 좌표로 변환하기: + let x1 = x + step*cos(radians(currentangle)); + let y1 = y + step*sin(radians(currentangle)); + line(x, y, x1, y1); // 이전의 것과 새로운 것을 연결 + + // 거북이의 위치 업데이트: + x = x1; + y = y1; + } else if (k == '+') { + currentangle += angle; // 왼쪽으로 돌기 + } else if (k == '-') { + currentangle -= angle; // 오른쪽으로 돌기 + } + + // 무작위의 색상값을 주세요: + let r = random(128, 255); + let g = random(0, 192); + let b = random(0, 50); + let a = random(50, 100); + + // 반지름에 대한 가우스 분포(D&D) 선택하기: + let radius = 0; + radius += random(0, 15); + radius += random(0, 15); + radius += random(0, 15); + radius = radius / 3; + + // 그리기: + fill(r, g, b, a); + ellipse(x, y, radius, radius); +} \ No newline at end of file diff --git a/dist/assets/examples/ko/09_Simulate/08_Spring.js b/dist/assets/examples/ko/09_Simulate/08_Spring.js new file mode 100644 index 0000000000..6338d32ea5 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/08_Spring.js @@ -0,0 +1,92 @@ +/* + * @name 용수철 + * @frame 710, 400 + * @description 수평 막대를 클릭하고 드래그한 뒤 놓으면 용수철 효과를 볼 수 있습니다. + */ +// 상단의 막대기를 위한 용수철(spring) 그리기 +let springHeight = 32, + left, + right, + maxHeight = 200, + minHeight = 100, + over = false, + move = false; + +// 용수철 시뮬레이션 상수들 +let M = 0.8, // Mass(질량) + K = 0.2, // 용수철(spring) 상수 + D = 0.92, // Damping(감쇠) + R = 150; // Rest Position(놓인 위치) + +// 용수철 시뮬레이션 변수들 +let ps = R, // 위치 + vs = 0.0, // 속도 + as = 0, // 가속도 + f = 0; // 힘 + +function setup() { + createCanvas(710, 400); + rectMode(CORNERS); + noStroke(); + left = width / 2 - 100; + right = width / 2 + 100; +} + +function draw() { + background(102); + updateSpring(); + drawSpring(); +} + +function drawSpring() { + // 바탕 그리기 + fill(0.2); + let baseWidth = 0.5 * ps + -8; + rect(width / 2 - baseWidth, ps + springHeight, width / 2 + baseWidth, height); + + // 상단 막대기의 색상 설정하고 그리기 + if (over || move) { + fill(255); + } else { + fill(204); + } + + rect(left, ps, right, ps + springHeight); +} + +function updateSpring() { + // 용수철(spring) 위치 업데이트 + if ( !move ) { + f = -K * ( ps - R ); // f=-ky + as = f / M; // 가속도 설정, f=ma == a=f/m + vs = D * (vs + as); // 속도 설정 + ps = ps + vs; // 업데이트된 위치 + } + + if (abs(vs) < 0.1) { + vs = 0.0; + } + + // 마우스가 상단 막대기 위에 있는지 여부 테스트 + if (mouseX > left && mouseX < right && mouseY > ps && mouseY < ps + springHeight) { + over = true; + } else { + over = false; + } + + // 상단 막대기의 위치 설정 및 제한 + if (move) { + ps = mouseY - springHeight / 2; + ps = constrain(ps, minHeight, maxHeight); + } +} + +function mousePressed() { + if (over) { + move = true; + } +} + +function mouseReleased() { + move = false; +} diff --git a/dist/assets/examples/ko/09_Simulate/09_Springs.js b/dist/assets/examples/ko/09_Simulate/09_Springs.js new file mode 100644 index 0000000000..bca9c5c5c5 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/09_Springs.js @@ -0,0 +1,148 @@ +/* + * @name 용수철들 + * @frame 710,400 + * @description 마우스로 원형 하나를 클릭해 재배치해보세요. + * 마우스 클릭을 놓으면 원위치로 되돌아갑니다. + * 각 원형은 조금씩 다른 행동을 보입니다. + * (https://processing.org/examples/springs.html에서 옮김) + */ +let num = 3; +let springs = []; + +function setup() { + createCanvas(710, 400); + noStroke(); + + springs[0] = new Spring(240, 260, 40, 0.98, 8.0, 0.1, springs, 0); + springs[1] = new Spring(320, 210, 120, 0.95, 9.0, 0.1, springs, 1); + springs[2] = new Spring(180, 170, 200, 0.90, 9.9, 0.1, springs, 2); +} + +function draw() { + background(51); + + for (let i = 0; i < num; i++) { + springs[i].update(); + springs[i].display(); + } +} + +function mousePressed() { + for (let i = 0; i < num; i++) { + springs[i].pressed(); + } +} + +function mouseReleased() { + for (let i = 0; i < num; i++) { + springs[i].released(); + } +} + +// 용수철(Spring) 클래스 +function Spring (_x, _y, _s, _d, _m, _k_in, _others, _id) { + // 화면상 위치값들 + // this.xpos = _x; + // this.ypos = _y; + + this.x_pos = _x; + this.y_pos= _y; + + this.size = 20; + this.size = _s; + + this.over = false; + this.move = false; + + // 용수철 시뮬레이션 상수들 + this.mass = _m; // Mass(질량) + this.k = 0.2; // Spring constant + this.k = _k_in; + this.damp = _d; // Damping(감쇠) + this.rest_posx = _x; // 놓인 위치 X + this.rest_posy = _y; // 놓인 위치 Y + + // 용수철 시뮬레이션 변수들 + //float pos = 20.0; // 위치 + this.velx = 0.0; // X 속도 + this.vely = 0.0; // Y 속도 + this.accel = 0; // 가속도 + this.force = 0; // 힘 + + this.friends = _others; + this.id = _id; + + this.update = function() { + + if (this.move) { + this.rest_posy = mouseY; + this.rest_posx = mouseX; + } + + this.force = -this.k * (this.y_pos - this.rest_posy); // f=-ky + this.accel = this.force / this.mass; // 가속도 설정하기, f=ma == a=f/m + this.vely = this.damp * (this.vely + this.accel); // 속도 설정하기 + this.y_pos = this.y_pos + this.vely; // 업데이트된 위치 + + + this.force = -this.k * (this.x_pos - this.rest_posx); // f=-ky + this.accel = this.force / this.mass; // 가속도 설정하기, f=ma == a=f/m + this.velx = this.damp * (this.velx + this.accel); // 속도 설정하기 + this.x_pos = this.x_pos + this.velx; // 업데이트된 위치 + + + + if ((this.overEvent() || this.move) && !(this.otherOver()) ) { + this.over = true; + } else { + this.over = false; + } + } + + // 마우스가 이 용수철 위에 있는지의 여부 테스트 + this.overEvent = function() { + let disX = this.x_pos - mouseX; + let disY = this.y_pos - mouseY; + let dis = createVector(disX, disY); + if (dis.mag() < this.size / 2 ) { + return true; + } else { + return false; + } + } + + // 다른 용수철이 움직이지 않도록 처리 + this.otherOver = function() { + for (let i = 0; i < num; i++) { + if (i != this.id) { + if (this.friends[i].over == true) { + return true; + } + } + } + return false; + } + + this.display = function() { + if (this.over) { + fill(153); + } else { + fill(255); + } + ellipse(this.x_pos, this.y_pos, this.size, this.size); + } + + this.pressed = function() { + if (this.over) { + this.move = true; + } else { + this.move = false; + } + } + + this.released = function() { + this.move = false; + this.rest_posx = this.y_pos; + this.rest_posy = this.y_pos; + } +}; \ No newline at end of file diff --git a/dist/assets/examples/ko/09_Simulate/10_SoftBody.js b/dist/assets/examples/ko/09_Simulate/10_SoftBody.js new file mode 100644 index 0000000000..48d8eebeab --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/10_SoftBody.js @@ -0,0 +1,110 @@ +/* + * @name 소프트 바디 + * @description 원본 제작: 이라 그린버그(Ira Greenberg) + *

curveVertex() 와 curveTightness()를 사용한 소프트 바디 역학 시뮬레이션. + */ +// 중심점 +let centerX = 0.0, centerY = 0.0; + +let radius = 45, rotAngle = -90; +let accelX = 0.0, accelY = 0.0; +let deltaX = 0.0, deltaY = 0.0; +let springing = 0.0009, damping = 0.98; + +// 모서리의 노드들 +let nodes = 5; + +// 빈 배열 +let nodeStartX = []; +let nodeStartY = []; +let nodeX = []; +let nodeY = []; +let angle = []; +let frequency = []; + +// 소프트 바디 역학 +let organicConstant = 1.0; + +function setup() { + createCanvas(710, 400); + + // 화면상의 중심 도형 + centerX = width / 2; + centerY = height / 2; + + // 배열을 0으로 초기화 + for (let i = 0; i < nodes; i++){ + nodeStartX[i] = 0; + nodeStartY[i] = 0; + nodeY[i] = 0; + nodeY[i] = 0; + angle[i] = 0; + } + + // 모서리 노드들의 빈도수 초기화 + for (let i = 0; i < nodes; i++){ + frequency[i] = random(5, 12); + } + + noStroke(); + frameRate(30); +} + +function draw() { + // 배경 사라지게하기 + fill(0, 100); + rect(0, 0, width, height); + drawShape(); + moveShape(); +} + +function drawShape() { + // 노드 시작 위치 계산 + for (let i = 0; i < nodes; i++){ + nodeStartX[i] = centerX + cos(radians(rotAngle)) * radius; + nodeStartY[i] = centerY + sin(radians(rotAngle)) * radius; + rotAngle += 360.0 / nodes; + } + + // 다각형 그리기 + curveTightness(organicConstant); + fill(255); + beginShape(); + for (let i = 0; i < nodes; i++){ + curveVertex(nodeX[i], nodeY[i]); + } + for (let i = 0; i < nodes-1; i++){ + curveVertex(nodeX[i], nodeY[i]); + } + endShape(CLOSE); +} + +function moveShape() { + // 중심점 옮기기 + deltaX = mouseX - centerX; + deltaY = mouseY - centerY; + + // 스프링같은 효과 만들기 + deltaX *= springing; + deltaY *= springing; + accelX += deltaX; + accelY += deltaY; + + // 프레데터(predator)의 중심 옮기기 + centerX += accelX; + centerY += accelY; + + // 스프링같은 효과 감쇠하기 + accelX *= damping; + accelY *= damping; + + // 커브의 탄성 바꾸기 + organicConstant = 1 - ((abs(accelX) + abs(accelY)) * 0.1); + + // 노드 옮기기 + for (let i = 0; i < nodes; i++){ + nodeX[i] = nodeStartX[i] + sin(radians(angle[i])) * (accelX * 2); + nodeY[i] = nodeStartY[i] + sin(radians(angle[i])) * (accelY * 2); + angle[i] += frequency[i]; + } +} diff --git a/dist/assets/examples/ko/09_Simulate/11_SmokeParticleSystem.js b/dist/assets/examples/ko/09_Simulate/11_SmokeParticleSystem.js new file mode 100644 index 0000000000..1a2c3168f2 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/11_SmokeParticleSystem.js @@ -0,0 +1,182 @@ +/* + * @name 연기 파티클 + * @description 다니엘 쉬프만(Dan Shiffman)이 프로세싱(Processing)을 위해 제작한 + * 연기 파티클 시스템(SmokeParticleSystem) 예제를 옮겨왔습니다. + * 마치 연기와 같은 파티클을 만들어볼까요 :p + */ + +// 파티클 텍스쳐 +let particle_texture = null; + +// 파티클 시스템을 담는 변수 +let ps = null; + +function preload() { + particle_texture = loadImage("assets/particle_texture.png"); +} + +function setup() { + + // 캔버스 사이즈 설정 + createCanvas(640, 360); + + // 파티클 시스템 초기화 + ps = new ParticleSystem(0, createVector(width / 2, height - 60), particle_texture); +} + +function draw() { + background(0); + + let dx = map(mouseX, 0, width, -0.2, 0.2); + let wind = createVector(dx, 0); + + ps.applyForce(wind); + ps.run(); + for (let i = 0; i < 2; i++) { + ps.addParticle(); + } + + // 바람의 힘을 뜻하는 화살표 그리기 + drawVector(wind, createVector(width / 2, 50, 0), 500); +} + +/** + * 이 함수는 "wind(바람)"이 부는 방향을 나타낸 화살표를 그립니다. + */ +function drawVector(v, loc, scale){ + push(); + let arrowsize = 4; + translate(loc.x, loc.y); + stroke(255); + rotate(v.heading()); + + let len = v.mag() * scale; + line(0, 0, len,0); + line(len, 0, len-arrowsize, +arrowsize / 2); + line(len, 0, len-arrowsize, -arrowsize / 2); + pop(); +} +//========= 파티클 시스템 =========== + +/** + * 기본적인 파티클 시스템 클래스 + * @param num 파티클 개수를 나타내는 매개 변수 + * @param v 파티클 시스템의 원점을 나타내는 매개 변수 + * @param img_ 시스템 상 각 파티클의 텍스쳐를 나타내는 매개 변수 + * @constructor 생성자 + */ +let ParticleSystem = function(num, v, img_) { + + this.particles = []; + this.origin = v.copy(); // 실수로 원래 벡터값(origin)을 바꾼 경우를 대비하여, 벡터값을 복사합니다. + this.img = img_ + for(let i = 0; i < num; ++i){ + this.particles.push(new Particle(this.origin, this.img)); + } +}; + +/** + * 이 함수는 전체 파티클 시스템을 실행합니다. + */ +ParticleSystem.prototype.run = function() { + + // 변수들에 반복할, 숨겨진 배열 길이 + // for 반복문에 .length가 표시 될 수 있지만, 매 반복마다 그 길이가 + // 다시 계산되기 때문에 여기에 숨깁니다. + let len = this.particles.length; + + //파티클 반복 및 실행 + for (let i = len - 1; i >= 0; i--) { + let particle = this.particles[i]; + particle.run(); + + // 파티클이 죽을 경우, 제거(remove)합니다. + // 자바스크립트의 배열에는 "remove" 기능이 없지만, + // 대신 동일한 기능을 수행하는 "splice"를 사용할 수 있습니다. + // 제거를 시작할 지점에 인덱스를 넣고, 해당 지점부터 몇 개를 제거할 지 넣을 수 있습니다. + if (particle.isDead()) { + this.particles.splice(i, 1); + } + } +} + +/** + * 현재 시스템의 존재하는 모든 파티클에 힘 벡터를 추가하는 메소드 + * @param dir 힘의 방향을 묘사하는 p5.Vector 매개 변수 + */ +ParticleSystem.prototype.applyForce = function(dir) { + let len = this.particles.length; + for(let i = 0; i < len; ++i){ + this.particles[i].applyForce(dir); + } +} + +/** + * 본래 지정된 텍스쳐와 동일한 텍스쳐의 파티클을 시스템 원점에 추가 + */ +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin, this.img)); +} + + +//========= 파티클 =========== +/** + * 파티클을 이미지로 렌더링하는 간단한 파티클 클래스 + */ +let Particle = function (pos, img_) { + this.loc = pos.copy(); + + let vx = randomGaussian() * 0.3; + let vy = randomGaussian() * 0.3 - 1.0; + + this.vel = createVector(vx, vy); + this.acc = createVector(); + this.lifespan = 100.0; + this.texture = img_; +} + +/** + * 파티클을 업데이트하는 동시에 보이게 하기 + */ +Particle.prototype.run = function() { + this.update(); + this.render(); +} + +/** + * 파티클을 화면에 보이게하는 메소드 + */ +Particle.prototype.render = function() { + imageMode(CENTER); + tint(255, this.lifespan); + image(this.texture, this.loc.x, this.loc.y); +} + +/** + * 파티클에 힘 벡터를 적용하는 메소드 + */ +Particle.prototype.applyForce = function(f) { + this.acc.add(f); +} + +/** + * 파티클의 lifespan(수명)이 끝나가는지 여부를 확인하는 메소드 + * 만약 끝나간다면 true(참)을, 그렇지 않다면 false(거짓)을 반환 + */ +Particle.prototype.isDead = function () { + if (this.lifespan <= 0.0) { + return true; + } else { + return false; + } +} + +/** + * 파티클의 위치를 업데이트하는 메소드 + */ +Particle.prototype.update = function() { + this.vel.add(this.acc); + this.loc.add(this.vel); + this.lifespan -= 2.5; + this.acc.mult(0); +} diff --git a/dist/assets/examples/ko/09_Simulate/12_BrownianMotion.js b/dist/assets/examples/ko/09_Simulate/12_BrownianMotion.js new file mode 100644 index 0000000000..a9f1959558 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/12_BrownianMotion.js @@ -0,0 +1,46 @@ +/* + * @name 브라운 운동 + * @description 무작위의 움직임을 연속된 선으로서 기록합니다. + * 프로세싱(Processing) 공식 웹사이트의 '예제' 페이지상 원본 예제를 p5.js로 옮겨왔습니다. + */ + +let num = 2000; +let range = 6; + +let ax = []; +let ay = []; + + +function setup() { + createCanvas(710, 400); + for ( let i = 0; i < num; i++ ) { + ax[i] = width / 2; + ay[i] = height / 2; + } + frameRate(30); +} + +function draw() { + background(51); + + // 모든 요소들을 좌측으로 1자리 이동 + for ( let i = 1; i < num; i++ ) { + ax[i - 1] = ax[i]; + ay[i - 1] = ay[i]; + } + + // 배열의 끝에 새로운 값 넣기 + ax[num - 1] += random(-range, range); + ay[num - 1] += random(-range, range); + + // 모든 점들을 화면에 제한 + ax[num - 1] = constrain(ax[num - 1], 0, width); + ay[num - 1] = constrain(ay[num - 1], 0, height); + + // 점들을 잇는 선 그리기 + for ( let j = 1; j < num; j++ ) { + let val = j / num * 204.0 + 51; + stroke(val); + line(ax[j - 1], ay[j - 1], ax[j], ay[j]); + } +} \ No newline at end of file diff --git a/dist/assets/examples/ko/09_Simulate/13_Chain.js b/dist/assets/examples/ko/09_Simulate/13_Chain.js new file mode 100644 index 0000000000..3a1aa01fa2 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/13_Chain.js @@ -0,0 +1,56 @@ +/* + * @name 사슬 + * @description 한 도형은 마우스 커서 위치에, 다른 하나는 이 도형의 위치에 붙어 따라옵니다. + * 화면에는 중력이 작용하여 두 도형을 아래 방향으로 끌어당깁니다. + * 프로세싱(Processing) 공식 웹사이트의 '예제' 페이지상 원본 예제를 p5.js로 옮겨왔습니다. + */ +let s1, s2; +let gravity = 9.0; +let mass = 2.0; + +function setup() { + createCanvas(720, 400); + fill(255, 126); + // 입력: x, y, mass(질량), gravity(중력) + s1 = new Spring2D(0.0, width / 2, mass, gravity); + s2 = new Spring2D(0.0, width / 2, mass, gravity); +} + +function draw() { + background(0); + s1.update(mouseX, mouseY); + s1.display(mouseX, mouseY); + s2.update(s1.x, s1.y); + s2.display(s1.x, s1.y); +} + +function Spring2D(xpos, ypos, m, g) { + this.x = xpos;// x 와 y 좌표 + this.y = ypos; + this.vx = 0; // x축과 y축 속도 + this.vy = 0; + this.mass = m; + this.gravity = g; + this.radius = 30; + this.stiffness = 0.2; + this.damping = 0.7; + + this.update = function(targetX, targetY) { + let forceX = (targetX - this.x) * this.stiffness; + let ax = forceX / this.mass; + this.vx = this.damping * (this.vx + ax); + this.x += this.vx; + let forceY = (targetY - this.y) * this.stiffness; + forceY += this.gravity; + let ay = forceY / this.mass; + this.vy = this.damping * (this.vy + ay); + this.y += this.vy; + } + + this.display = function(nx, ny) { + noStroke(); + ellipse(this.x, this.y, this.radius * 2, this.radius * 2); + stroke(255); + line(this.x, this.y, nx, ny); + } +} \ No newline at end of file diff --git a/dist/assets/examples/ko/09_Simulate/14_SnowflakeParticleSystem.js b/dist/assets/examples/ko/09_Simulate/14_SnowflakeParticleSystem.js new file mode 100644 index 0000000000..0b33293e32 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/14_SnowflakeParticleSystem.js @@ -0,0 +1,63 @@ +/* + * @name 눈송이 파티클 + * @description 이 파티클 시스템은 마치 떨어지는 눈송이같은 모션을 시뮬레이션합니다. + * 눈송이 파티클을 담는 객체 배열을 사용합니다. + * 기여: 애티쉬 바티아(Aatish Bhatia) + */ + +let snowflakes = []; // 눈송이 객체를 담는 배열 + +function setup() { + createCanvas(400, 600); + fill(240); + noStroke(); +} + +function draw() { + background('brown'); + let t = frameCount / 60; // 시간 업데이트 + + // 매 프라임마다 무작위 개수의 눈송이 생성 + for (let i = 0; i < random(5); i++) { + snowflakes.push(new snowflake()); // 눈송이 객체 추가 + } + + // for 반복문을 사용하여 눈송이 반복 + for (let flake of snowflakes) { + flake.update(t); // 눈송이 위치 업데이트 + flake.display(); // 눈송이 그리기 + } +} + +// snowflake 클래스 +function snowflake() { + // 좌표값 초기화 + this.posX = 0; + this.posY = random(-50, 0); + this.initialangle = random(0, 2 * PI); + this.size = random(2, 5); + + // 방사형 눈송이의 반지름 + // 눈송이를 화면에 고루 퍼뜨리기 위해 선택 + this.radius = sqrt(random(pow(width / 2, 2))); + + this.update = function(time) { + // 원형을 따라다니는 x 위치 + let w = 0.6; // 각속도 + let angle = w * time + this.initialangle; + this.posX = width / 2 + this.radius * sin(angle); + + // 크기가 다른 눈송이가 미묘하게 다른 y 속도로 떨어집니다. + this.posY += pow(this.size, 0.5); + + // 화면 하단을 지나친 눈송이는 삭제 + if (this.posY > height) { + let index = snowflakes.indexOf(this); + snowflakes.splice(index, 1); + } + }; + + this.display = function() { + ellipse(this.posX, this.posY, this.size); + }; +} diff --git a/dist/assets/examples/ko/09_Simulate/15_penrose_tiles.js b/dist/assets/examples/ko/09_Simulate/15_penrose_tiles.js new file mode 100644 index 0000000000..71c5f5bd0b --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/15_penrose_tiles.js @@ -0,0 +1,125 @@ +/* + * @name 펜로즈 타일 + * @frame 710,400 + * @description 이 예제는 데이비드 블리츠(David Blitz)가 processing.org/examples의 "펜로즈 타일(Penrose Tile)" 예제를 p5.js로 옮겨온 것입니다. + */ + +let ds; + +function setup() { + createCanvas(710, 400); + ds = new PenroseLSystem(); + //다음의 줄과 함께 놀아보세요! + ds.simulate(5); +} + +function draw() { + background(0); + ds.render(); +} + +function PenroseLSystem() { + this.steps = 0; + + //아래는 펜로즈 마름모 L-시스템의 공리와 규칙들입니다. + //레퍼런스가 있다면 좋겠지만, 좋은 사례를 찾지 못했습니다. + this.axiom = "[X]++[X]++[X]++[X]++[X]"; + this.ruleW = "YF++ZF----XF[-YF----WF]++"; + this.ruleX = "+YF--ZF[---WF--XF]+"; + this.ruleY = "-WF++XF[+++YF++ZF]-"; + this.ruleZ = "--YF++++WF[+ZF++++XF]--XF"; + + //아래의 두 줄과 함께 놀아보세요! + this.startLength = 460.0; + this.theta = TWO_PI / 10.0; //36도, TWO_PI / 6.0도을 넣어보세요, ... + this.reset(); +} + +PenroseLSystem.prototype.simulate = function (gen) { + while (this.getAge() < gen) { + this.iterate(this.production); + } +} + +PenroseLSystem.prototype.reset = function () { + this.production = this.axiom; + this.drawLength = this.startLength; + this.generations = 0; + } + +PenroseLSystem.prototype.getAge = function () { + return this.generations; + } + +//대체 규칙을 적용하여, 문자열의 새로운 반복 생성 +PenroseLSystem.prototype.iterate = function() { + let newProduction = ""; + + for(let i=0; i < this.production.length; ++i) { + let step = this.production.charAt(i); + // 현재 문자가 'W'이면, + // 이 현재 문자를 규칙에 맞게 대체합니다. + if (step == 'W') { + newProduction = newProduction + this.ruleW; + } + else if (step == 'X') { + newProduction = newProduction + this.ruleX; + } + else if (step == 'Y') { + newProduction = newProduction + this.ruleY; + } + else if (step == 'Z') { + newProduction = newProduction + this.ruleZ; + } + else { + // 모든 'F'를 drop 삭제하되, + // 여타 문자들(예. '+', '-', '[', ']')은 건들지 않는다. + if (step != 'F') { + newProduction = newProduction + step; + } + } + } + + this.drawLength = this.drawLength * 0.5; + this.generations++; + this.production = newProduction; +} + +//문자열을 거북이 그래픽으로 변환 +PenroseLSystem.prototype.render = function () { + translate(width / 2, height / 2); + + this.steps += 20; + if(this.steps > this.production.length) { + this.steps = this.production.length; + } + + for(let i=0; i재귀 나무 예제 에서 p5.js로 옮겨왔습니다. + */ +let theta; + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(0); + frameRate(30); + stroke(255); + // 마우스 위치에 따라 0부터 90도 중 각도 한 개를 골라볼까요! + let a = (mouseX / width) * 90; + // 이를 라디안 값으로 전환합니다. + theta = radians(a); + // 화면 하단에서 나무 시작하기 + translate(width/2,height); + // 120픽셀 길이의 선 그리기 + line(0,0,0,-120); + // 위의 선의 끝 지점으로 이동하기 + translate(0,-120); + // 나뭇가지의 재귀적 분기 시작하기! + branch(120); + +} + +function branch(h) { + // 각각의 나뭇가지 크기는 이전 가지의 2/3에 해당합니다. + h *= 0.66; + + // 모든 재귀 함수에는 종료(exit) 조건이 있어야합니다!!! + // 이 예제의 경우, 나뭇 가지의 길이가 2픽셀과 같거나 적을 때 입니다. + if (h > 2) { + push(); // 현재의 변형 상태를 저장 (즉, 현재 상태) + rotate(theta); // theta(세타)값으로 회전하기 + line(0, 0, 0, -h); // 나뭇가지 그리기 + translate(0, -h); // 나뭇가지의 끝 지점으로 이동하기 + branch(h); // 자, 이제 자기 자신을 호출하여 2개의 새로운 나뭇가지를 그릴게요! + pop(); // 이 지점에 도달할 때 마다, 이전 매트릭스 상태를 복원하기 위해 "pop(팝)"합니다. + + // 같은 내용을 반복하되, 이번에는 "왼쪽"으로만 가지가 분기하도록 만듭니다! + push(); + rotate(-theta); + line(0, 0, 0, -h); + translate(0, -h); + branch(h); + pop(); + } +} diff --git a/dist/assets/examples/ko/09_Simulate/17_Mandelbrot.js b/dist/assets/examples/ko/09_Simulate/17_Mandelbrot.js new file mode 100644 index 0000000000..6b41ae6ab4 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/17_Mandelbrot.js @@ -0,0 +1,86 @@ +/* + * @name 망델브로 집합 + * @description 망델브로(Mandelbrot) 집합을 간단히 렌더링합니다. + * 다니엘 쉬프만(Daniel Shiffman)의 프로세싱(Processing)을 위한 망델브로 예제에서 옮겨왔습니다. + */ + +function setup() { + createCanvas(710, 400); + pixelDensity(1); + noLoop(); +} + +function draw() { + background(0); + + // 복잡한 평면 위에서 값의 범위를 설정 + // 설정된 범위에 따라 프랙탈을 줌인 또는 줌아웃할 수 있습니다. + + // 모든 것은 너비값에서 시작합니다. 더 크거나 적은 값을 시도해보세요. + const w = 4; + const h = (w * height) / width; + + // 너비와 높이의 음의 절반에서 시작 + const xmin = -w/2; + const ymin = -h/2; + + // pixels[] 배열에 쓸 수 있는지 확인합니다. + // 다른 드로잉을 하지 않으므로, 이 작업은 한번만 수행합니다. + loadPixels(); + + // 복잡한 평면 위의 각 점마다 반복할 수 있는 최대 횟수 + const maxiterations = 100; + + // x는 xmin에서 xmax로 이동 + const xmax = xmin + w; + // y는 ymin에서 ymax로 이동 + const ymax = ymin + h; + + // 각 픽셀마다 x,y를 증가하는 양 계산 + const dx = (xmax - xmin) / (width); + const dy = (ymax - ymin) / (height); + + // y 시작 + let y = ymin; + for (let j = 0; j < height; j++) { + // x 시작 + let x = xmin; + for (let i = 0; i < width; i++) { + + // 이제, 우리가 z = z^2 + cm 를 반복 할 때 z가 무한대로 향하나요? + let a = x; + let b = y; + let n = 0; + while (n < maxiterations) { + const aa = a * a; + const bb = b * b; + const twoab = 2.0 * a * b; + a = aa - bb + x; + b = twoab + y; + // 이 유한한 세상에서의 무한대 개념은 간단합니다. 여기서는 그냥 16이라 설정하지요. + if (dist(aa, bb, 0, 0) > 16) { + break; + } + n++; + } + + // 무한대에 도달하기까지 걸리는 시간을 기준으로 각 픽셀에 색상을 지정합니다. + // 도달하지 못할 경우, 검정색으로 지정합니다. + const pix = (i+j*width)*4; + const norm = map(n, 0, maxiterations, 0, 1); + let bright = map(sqrt(norm), 0, 1, 0, 255); + if (n == maxiterations) { + bright = 0; + } else { + // 원한다면 여기서 좀 더 화려한 색상을 만들 수 있습니다. + pixels[pix + 0] = bright; + pixels[pix + 1] = bright; + pixels[pix + 2] = bright; + pixels[pix + 3] = 255; + } + x += dx; + } + y += dy; + } + updatePixels(); +} diff --git a/dist/assets/examples/ko/09_Simulate/18_Koch.js b/dist/assets/examples/ko/09_Simulate/18_Koch.js new file mode 100644 index 0000000000..3b36472477 --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/18_Koch.js @@ -0,0 +1,141 @@ +/* + * @name 코흐 곡선 + * @description 간단한 코흐 곡선 즉, 눈송이형 프랙탈을 만듭니다. + * 각각의 재귀 단계는 순차적으로 그려집니다. + * 제작: 다니엘 쉬프만(Daniel Shiffman) + */ + +let k; + +function setup() { + createCanvas(710, 400); + frameRate(1); // 천천히 움직이기 + k = new KochFractal(); +} + +function draw() { + background(0); + // 눈송이 그리기! + k.render(); + // 반복하기 + k.nextLevel(); + // 5회를 초과하진 않습니다... + if (k.getCount() > 5) { + k.restart(); + } +} + +// 선 하나를 프랙탈로 표현해주는 클래스 +// midp5.Vectors가 코크 알고리즘에 의거하여 선을 계산하는 메소드를 포함합니다. + +class KochLine { + constructor(a,b) { + // 두개의 p5.Vectors, + // 시작은 "왼쪽" p5.Vector이고 + // 끝은 "오른쪽" p5.Vector입니다. + this.start = a.copy(); + this.end = b.copy(); + } + + display() { + stroke(255); + line(this.start.x, this.start.y, this.end.x, this.end.y); + } + + kochA() { + return this.start.copy(); + } + + // 쉽지요? 여기까지 전체 내용의 1/3을 진행했어요. + kochB() { + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + v.add(this.start); + return v; + } + + // 약간 복잡한데요, 이 p5의 위치를 알아내기 위해 약간의 삼각법을 사용합니다! + kochC() { + let a = this.start.copy(); // Start at the beginning + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + a.add(v); // 점 B로 이동하기 + v.rotate(-PI/3); // 60도 회전하기 + a.add(v); // 점 C로 이동하기 + return a; + } + + // 쉽지요? 여기까지 전체 내용의 2/3을 진행했어요. + kochD() { + let v = p5.Vector.sub(this.end, this.start); + v.mult(2/3.0); + v.add(this.start); + return v; + } + + kochE() { + return this.end.copy(); + } +} + +//눈송이 패턴을 갖는 선분들을 배열로 관리하는 클래스입니다. +class KochFractal { + constructor() { + this.start = createVector(0,height-20); // 시작점 p5.Vector + this.end = createVector(width,height-20); // 끝점 p5.Vector + this.lines = []; // 모든 선분을 추적하는 배열 + this.count = 0; + this.restart(); + } + + nextLevel() { + // 배열에 담긴 각각의 선분들에 대해 + // 4개의 선분들을 추가한, 새로운 배열을 만듭니다. + this.lines = this.iterate(this.lines); + this.count++; + } + + restart() { + this.count = 0; // 카운트 리셋하기 + this.lines = []; // 배열 비우기 + this.lines.push(new KochLine(this.start,this.end)); // 초기 선분 더하기(하나의 끝점 p5.Vector에서 다른 p5.Vector로) + } + + getCount() { + return this.count; + } + + // 이 부분도 쉽습니다. 모든 선들을 그리는 함수이지요. + render() { + for(let i = 0; i < this.lines.length; i++) { + this.lines[i].display(); + } + } + + // 이제부터 **마법**이 시작됩니다. + // 1단계: 빈 배열 목록을 새로 생성합니다. + // 2단계: 배열 목록에 현재 담긴 모든 선들에 대하여, + // - 코흐 알고리즘에 따라 선분 4개를 계산하고, + // - 이 4개의 선분들을 모두 새로운 배열 목록에 더합니다. + // 3단계: 새로운 배열 목록이 반환되고, 이 새 목록은 전체 구조의 선분들에 대한 목록이 됩니다. + + // 위의 단계를 반복하면, 모든 선들이 4개의 다른 선으로 분할되고, 또 그 선들은 다시 4개의 선들로 끊임없이 분할되는 식입니다. + iterate(before) { + let now = []; // 빈 배열 생성하기 + for(let i = 0; i < this.lines.length; i++) { + let l = this.lines[i]; + // 5개의 코흐 p5.Vector 계산 (선 객체를 통해 계산) + let a = l.kochA(); + let b = l.kochB(); + let c = l.kochC(); + let d = l.kochD(); + let e = l.kochE(); + // 모든 p5.Vector 사이에 선분을 만들고 추가하기 + now.push(new KochLine(a,b)); + now.push(new KochLine(b,c)); + now.push(new KochLine(c,d)); + now.push(new KochLine(d,e)); + } + return now; + } +} diff --git a/dist/assets/examples/ko/09_Simulate/19_Bubblesort.js b/dist/assets/examples/ko/09_Simulate/19_Bubblesort.js new file mode 100644 index 0000000000..bff2f5a7bf --- /dev/null +++ b/dist/assets/examples/ko/09_Simulate/19_Bubblesort.js @@ -0,0 +1,66 @@ +/* + * @name 버블 정렬 + * @description 전체 정렬 과정을 시뮬레이션하면서, + * 무작위로 분포된 막대들을 그 높이에 따라 오름차순으로 정렬합니다. + * 코딩 트레인(Coding Train)의 코딩 챌린지(Coding Challenge)를 참조하였습니다. + */ + +let values = []; +let i = 0; +let j = 0; + +// setup() 함수 속 명령문들은 +// 프로그램 시작시 한 번 실행됩니다. +// 배열은 setup()함수를 통해 임의의 값들로 채워집니다. +function setup() { + createCanvas(720, 400); + for(let i = 0;i values[j+1]){ + values[j] = values[j+1]; + values[j+1] = temp; + } + j++; + + if(j>=values.length-i-1){ + j = 0; + i++; + } + } + else{ + noLoop(); + } + } +} + +// simulateSorting() 함수는 버블 정렬 알고리즘에 +// 애니메이션을 적용합니다. +// 이 함수는 배열의 값을 사각형 길이로 치환해 +// 사각형을 그립니다. +function simulateSorting(){ + for(let i = 0;i= width || this.xPos <= 0){ + this.xSpeed*=-1; + } + } +} + +function setup() { + createCanvas(720, 400); + createP("Keep the mouse clicked").style('color','#ffffff'); + createP("to check whether the bricks").style('color','#ffffff'); + createP("are moving at same speed or not").style('color','#ffffff'); +} + +// 두 개의 사각형을 각각 +// 흰색과 검정색으로 지정 +let brick1 = new Brick("white",100); +let brick2 = new Brick("black",250); + +// +brick1.setSpeed(); +brick2.setSpeed(); + +function draw () { + background(0); + if(mouseIsPressed){ + background(50); + } + brick1.createBrick(); + brick1.moveBrick(); + if(!mouseIsPressed){ + createBars(); + } + brick2.createBrick(); + brick2.moveBrick(); +} + +// 이 함수로 화면에 +// 검정색 및 흰색 막대기들을 생성하기 +function createBars() { + let len = 12; + for(let i = 0;i width) + this.xSpeed*=-1; + if(this.y < 0 || this.y > height) + this.ySpeed*=-1; + this.x+=this.xSpeed; + this.y+=this.ySpeed; + } + +// 이 함수는 특정 거리 안쪽에 위치한 파티클들 사이에 연결선을 만듭니다. + joinParticles(paraticles) { + particles.forEach(element =>{ + let dis = dist(this.x,this.y,element.x,element.y); + if(dis<85) { + stroke('rgba(255,255,255,0.04)'); + line(this.x,this.y,element.x,element.y); + } + }); + } +} + +// 복수의 파티클들을 추가하기 위한 배열 +let particles = []; + +function setup() { + createCanvas(720, 400); + for(let i = 0;i
+ * Quicksort is a divide-and-conquer algorithm: it + * performs sorting by dividing the original array into + * smaller subarrays and solving them independently, + * loosely speaking. It involves picking an element of + * the array as the pivot element and partitioning the + * given array around the picked pivot.
+ * Partitioning refers to arranging the given array(or + * subarray) in such a way that all elements to the left + * of the pivot element are smaller than it and all + * elements to its right are larger than it. Thus, we have + * a reference point from where we proceed to sort the + * left and right 'halves' of the array, and eventually + * arrive at an array sorted in ascending order. + * + * More
+ */ + +// width of each bar is taken as 8. +let values = []; +// The array 'states' helps in identifying the pivot index +// at every step, and also the subarray which is being sorted +// at any given time. +let states = []; + +// The setup() function is called once when the program +// starts. Here, we fill the array 'values' with random values +// and the array 'states' with a value of -1 for each position. +function setup() { + createCanvas(710, 400); + for(let i = 0; i < width/8; i++) { + values.push(random(height)); + states.push(-1); + } + quickSort(0, values.length - 1); +} + +// The statements in draw() function are executed continuously +// until the program is stopped. Each statement is executed +// sequentially and after the last line is read, the first +// line is executed again. +function draw() { + background(140); + for(let i = 0; i < values.length; i++) { + // color coding + if (states[i] == 0) { + // color for the bar at the pivot index + fill('#E0777D'); + } else if (states[i] == 1) { + // color for the bars being sorted currently + fill('#D6FFB7'); + } else { + fill(255); + } + rect(i * 8, height - values[i], 8, values[i]); + } +} + +async function quickSort(start, end) { + if (start > end) { // Nothing to sort! + return; + } + // partition() returns the index of the pivot element. + // Once partition() is executed, all elements to the + // left of the pivot element are smaller than it and + // all elements to its right are larger than it. + let index = await partition(start, end); + // restore original state + states[index] = -1; + await Promise.all( + [quickSort(start, index - 1), + quickSort(index + 1, end) + ]); +} + +// We have chosen the element at the last index as +// the pivot element, but we could've made different +// choices, e.g. take the first element as pivot. +async function partition(start, end) { + for (let i = start; i < end; i++) { + // identify the elements being considered currently + states[i] = 1; + } + // Quicksort algorithm + let pivotIndex = start; + // make pivot index distinct + states[pivotIndex] = 0; + let pivotElement = values[end]; + for (let i = start; i < end; i++) { + if (values[i] < pivotElement) { + await swap(i, pivotIndex); + states[pivotIndex] = -1; + pivotIndex++; + states[pivotIndex] = 0; + } + } + await swap(end, pivotIndex); + for (let i = start; i < end; i++) { + // restore original state + if (i != pivotIndex) { + states[i] = -1; + } + } + return pivotIndex; +} + +// swaps elements of 'values' at indices 'i' and 'j' +async function swap(i, j) { + // adjust the pace of the simulation by changing the + // value + await sleep(25); + let temp = values[i]; + values[i] = values[j]; + values[j] = temp; +} + +// custom helper function to deliberately slow down +// the sorting process and make visualization easy +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} \ No newline at end of file diff --git a/dist/assets/examples/ko/10_Interaction/10_Tickle.js b/dist/assets/examples/ko/10_Interaction/10_Tickle.js new file mode 100644 index 0000000000..829b9276fd --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/10_Tickle.js @@ -0,0 +1,48 @@ +/* + * @name 간질간질 + * @description 마우스 커서를 "tickle"에 올리면, 마치 간지럼을 타는듯 떨립니다. + * 너무 간지럽히면 화면 밖으로 튀어나갈 수도 있습니다 >_< + */ +let message = 'tickle', + font, + bounds, // 텍스트의 바운딩 박스에 대한 x, y, w, h값 + fontsize = 60, + x, + y; // 텍스트의 x 와 y 좌표 + +function preload() { + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // 폰트 설정 + textFont(font); + textSize(fontsize); + + // 초기화시 중앙 정렬을 위해 텍스트의 너비 및 높이값 받아오기 + bounds = font.textBounds(message, 0, 0, fontsize); + x = width / 2 - bounds.w / 2; + y = height / 2 - bounds.h / 2; +} + +function draw() { + background(204, 120); + + // 텍스트를 검정색으로 쓰고, 그 바운딩 박스 받아오기 + fill(0); + text(message, x, y); + bounds = font.textBounds(message, x, y, fontsize); + + // 마우스가 바운딩 박스 안에 있는지 확인하고, 안에 있다면 간질간질! + if ( + mouseX >= bounds.x && + mouseX <= bounds.x + bounds.w && + mouseY >= bounds.y && + mouseY <= bounds.y + bounds.h + ) { + x += random(-5, 5); + y += random(-5, 5); + } +} diff --git a/dist/assets/examples/ko/10_Interaction/11_WeightLine.js b/dist/assets/examples/ko/10_Interaction/11_WeightLine.js new file mode 100644 index 0000000000..a455dcb781 --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/11_WeightLine.js @@ -0,0 +1,55 @@ +/* + * @name Weight Line + * @frame 710,400 + * @description contributed by + Prof WM Harris, using the random function with events to color/weight a line
+ How to use the random function with events to color/ weight a line + dependent on mouse location, left mouse button clicks, character key types, and + random key releases.
+ Functions are created for both the canvas set up as well as the creation of + the line. Depending on the action taken by the user the line can + vary in width and color. Left mouse button clicks result in a color + change to blue, while the typing of any character key will change + the color to turquoise, each resulting in a variable stroke weight; + the width of the former will be between 0 – 1 while the width of + the latter will be 0 – 5. The release of any key will result in a + random hue, saturation, and brightness change to the line. + */ + + +function setup() { + createCanvas(400, 400); + background("beige"); + colorMode(HSB); + } + + function draw() { + //Line from prev pt to current pt + //of mouse position + line(mouseX, mouseY, pmouseX, pmouseY); + } + + //listen when we click the mouse + function mouseClicked() { + //weights 0 to 1 + stroke("slateBlue"); + strokeWeight(random()); + + //what if want weights 0 to .4? + //strokeWeight( random(.4) ); + } + + //listen when we release *any* key + function keyReleased() { + //color hue values between 20 and 145 + //saturation 0 to 100 + //brightness 80 to 100 + stroke(random(20, 145), random(100), random(80, 100)); + } + + //listen for only character keys + function keyTyped() { + //weights 0 to 5 + stroke("turquoise"); + strokeWeight(random(5)); + } \ No newline at end of file diff --git a/dist/assets/examples/ko/10_Interaction/20_Follow1.js b/dist/assets/examples/ko/10_Interaction/20_Follow1.js new file mode 100644 index 0000000000..c5b35b3a13 --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/20_Follow1.js @@ -0,0 +1,37 @@ +/* + * @name 따라다니기 1 + * @frame 710,400 + * @description 마우스 커서로 선분을 밀고 당깁니다. + * 이 예제는 키스 피터스(Keith Peters)가 제작한 코드를 기반으로 합니다. + */ +let x = 100, + y = 100, + angle1 = 0.0, + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + x = mouseX - cos(angle1) * segLength; + y = mouseY - sin(angle1) * segLength; + + segment(x, y, angle1); + ellipse(x, y, 20, 20); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/ko/10_Interaction/21_Follow2.js b/dist/assets/examples/ko/10_Interaction/21_Follow2.js new file mode 100644 index 0000000000..276ebaa52b --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/21_Follow2.js @@ -0,0 +1,39 @@ +/* + * @name 따라다니기 2 + * @frame 710,400 + * @description 팔 형상의 두 선분이 마우스 커서의 위치를 따라다닙니다. + * 선분들 사이의 상대 각도는 atan2()로, 그 위치는 sin()과 cos()로 계산됩니다. + * 이 예제는 키스 피터스(Keith Peters)가 제작한 코드를 기반으로 합니다. + */ +let x = [0, 0], + y = [0, 0], + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + dragSegment(1, x[0], y[0]); +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/ko/10_Interaction/22_Follow3.js b/dist/assets/examples/ko/10_Interaction/22_Follow3.js new file mode 100644 index 0000000000..7f585e572b --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/22_Follow3.js @@ -0,0 +1,47 @@ +/* + * @name 따라다니기 3 + * @frame 710,400 + * @description 선분이 마우스를 따라다닙니다. 한 선분의 다음 선분에 대한 상대 각도는 atan2()로, + * 다음 선분의 위치는 sin()과 cos()로 계산됩니다. + * 이 예제는 키스 피터스(Keith Peters)가 제작한 코드를 기반으로 합니다. + */ +let x = [], + y = [], + segNum = 20, + segLength = 18; + +for (let i = 0; i < segNum; i++) { + x[i] = 0; + y[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(9); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/ko/10_Interaction/23_snake.js b/dist/assets/examples/ko/10_Interaction/23_snake.js new file mode 100644 index 0000000000..10422434f6 --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/23_snake.js @@ -0,0 +1,168 @@ +/* + * @name 스네이크 게임 + * @description 그 유명한 스네이크 게임입니다! 실행(run)을 누르고, + * 검은 화면 위 아무 지점을 클릭한 뒤, i,j,k,l 키로 뱀을 조종할 수 있습니다. + * 뱀이 벽이나 자신의 몸에 닿지 않도록 하세요!
+ * 예제 제작: 프라샨트 굽타(Prashant Gupta) + */ + +// 뱀의 형상은 작은 조각(segment)들로 구성되는데, +// 이는 매 'draw' 호출에서 그려지고 수정됩니다. +let numSegments = 10; +let direction = 'right'; + +const xStart = 0; // 뱀의 시작 x좌표 +const yStart = 250; // 뱀의 시작 y좌표 +const diff = 10; + +let xCor = []; +let yCor = []; + +let xFruit = 0; +let yFruit = 0; +let scoreElem; + +function setup() { + scoreElem = createDiv('Score = 0'); + scoreElem.position(20, 20); + scoreElem.id = 'score'; + scoreElem.style('color', 'white'); + + createCanvas(500, 500); + frameRate(15); + stroke(255); + strokeWeight(10); + updateFruitCoordinates(); + + for (let i = 0; i < numSegments; i++) { + xCor.push(xStart + i * diff); + yCor.push(yStart); + } +} + +function draw() { + background(0); + for (let i = 0; i < numSegments - 1; i++) { + line(xCor[i], yCor[i], xCor[i + 1], yCor[i + 1]); + } + updateSnakeCoordinates(); + checkGameStatus(); + checkForFruit(); +} + +/* + 뱀의 방향에 따라, 뱀의 형상을 구성하는 작은 조각(segment)들의 위치가 업데이트됩니다. + 0에서 n-1까지의 모든 조각들은 n에 도달할 때까지 그 다음 조각의 위치를 복사합니다. + 예를 들어, segment 0은 segment 1의 값을 받고, segment 1은 segment 2의 값을 받습니다. 뱀은 이러한 과정을 통해 움직이는 것입니다. + 이 때, 마지막 조각(segment)은 뱀이 가는 방향에 따라 추가됩니다. + 뱀이 좌우로 움직일 때 가장 마지막 조각의 x값은, 마지막에서 두번째 조각의 x값보다 'diff'값만큼 증가합니다. + 뱀이 상하로 움직일 때는 가장 마지막 조각의 y값이 증가하는 식입니다. +*/ +function updateSnakeCoordinates() { + for (let i = 0; i < numSegments - 1; i++) { + xCor[i] = xCor[i + 1]; + yCor[i] = yCor[i + 1]; + } + switch (direction) { + case 'right': + xCor[numSegments - 1] = xCor[numSegments - 2] + diff; + yCor[numSegments - 1] = yCor[numSegments - 2]; + break; + case 'up': + xCor[numSegments - 1] = xCor[numSegments - 2]; + yCor[numSegments - 1] = yCor[numSegments - 2] - diff; + break; + case 'left': + xCor[numSegments - 1] = xCor[numSegments - 2] - diff; + yCor[numSegments - 1] = yCor[numSegments - 2]; + break; + case 'down': + xCor[numSegments - 1] = xCor[numSegments - 2]; + yCor[numSegments - 1] = yCor[numSegments - 2] + diff; + break; + } +} + +/* + 전 항상 뱀의 머리 위치인 xCor[xCor.length - 1]와 + yCor[yCor.length - 1]를 확인하여 뱀이 화면 경계나 자신의 몸에 닿는지를 본답니다. +*/ +function checkGameStatus() { + if ( + xCor[xCor.length - 1] > width || + xCor[xCor.length - 1] < 0 || + yCor[yCor.length - 1] > height || + yCor[yCor.length - 1] < 0 || + checkSnakeCollision() + ) { + noLoop(); + const scoreVal = parseInt(scoreElem.html().substring(8)); + scoreElem.html('Game ended! Your score was : ' + scoreVal); + } +} + +/* + 뱀이 자신의 몸에 닿았다는건 다시말해, 뱀의 머리의 (x,y)좌표가 + 조각(segment)들 중 한 (x,y)좌표와 일치한다는 것입니다. +*/ +function checkSnakeCollision() { + const snakeHeadX = xCor[xCor.length - 1]; + const snakeHeadY = yCor[yCor.length - 1]; + for (let i = 0; i < xCor.length - 1; i++) { + if (xCor[i] === snakeHeadX && yCor[i] === snakeHeadY) { + return true; + } + } +} + +/* + 뱀이 과일을 먹을 때마다 조각의 수가 증가하고, 배열의 시작에 꼬리 조각이 다시 삽입되도록 설정했습니다.(기본적으로, 마지막 조각을 꼬리 부분에 추가하여 꼬리를 늘리는 식이지요.) +*/ +function checkForFruit() { + point(xFruit, yFruit); + if (xCor[xCor.length - 1] === xFruit && yCor[yCor.length - 1] === yFruit) { + const prevScore = parseInt(scoreElem.html().substring(8)); + scoreElem.html('Score = ' + (prevScore + 1)); + xCor.unshift(xCor[0]); + yCor.unshift(yCor[0]); + numSegments++; + updateFruitCoordinates(); + } +} + +function updateFruitCoordinates() { + /* + 여기서 복잡한 연산 논리가 추가된 이유는 + 뱀이 10의 배수 단위로 움직이도록 설정했기 때문입니다. + 점을 너비 100과 -100 사이에 있도록 하고, + 그 위치값이 가장 가까운 10의 배수 숫자로 반올림되도록 처리하였습니다. + */ + + xFruit = floor(random(10, (width - 100) / 10)) * 10; + yFruit = floor(random(10, (height - 100) / 10)) * 10; +} + +function keyPressed() { + switch (keyCode) { + case 74: + if (direction !== 'right') { + direction = 'left'; + } + break; + case 76: + if (direction !== 'left') { + direction = 'right'; + } + break; + case 73: + if (direction !== 'down') { + direction = 'up'; + } + break; + case 75: + if (direction !== 'up') { + direction = 'down'; + } + break; + } +} diff --git a/dist/assets/examples/ko/10_Interaction/24_Wavemaker.js b/dist/assets/examples/ko/10_Interaction/24_Wavemaker.js new file mode 100644 index 0000000000..340cce3b3b --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/24_Wavemaker.js @@ -0,0 +1,38 @@ +/* + * @name 파도 만들기 + * @description 이 예제는 특정 위치에서 진동하는 파티클로 파도를 만드는 법을 다룹니다. + * 마우스를 움직여 파도의 방향을 바꿔보세요. + * 기여: 애티쉬 바티아(Aatish Bhatia), 제작: 댄 와이트(Dan Whyte) Orbiters + * 로부터 영감을 받았습니다. + */ + +let t = 0; // 시간 변수 + +function setup() { + createCanvas(600, 600); + noStroke(); + fill(40, 200, 40); +} + +function draw() { + background(10, 10); // 불투명한 배경화면(파티클의 꼬리 만들기) + + // 타원형으로 구성된 x와 y 그리드 만들기 + for (let x = 0; x <= width; x = x + 30) { + for (let y = 0; y <= height; y = y + 30) { + // 각 타원의 시작 점은 마우스 위치에 따라 달라집니다. + const xAngle = map(mouseX, 0, width, -4 * PI, 4 * PI, true); + const yAngle = map(mouseY, 0, height, -4 * PI, 4 * PI, true); + // 또, 파티클의 위치에 따라 달라집니다. + const angle = xAngle * (x / width) + yAngle * (y / height); + + // 각 파티클은 동그라미를 그리며 움직입니다. + const myX = x + 20 * cos(2 * PI * t + angle); + const myY = y + 20 * sin(2 * PI * t + angle); + + ellipse(myX, myY, 10); // 파티클로 그리기 + } + } + + t = t + 0.01; // 시간 업데이트 +} diff --git a/dist/assets/examples/ko/10_Interaction/25_reach1.js b/dist/assets/examples/ko/10_Interaction/25_reach1.js new file mode 100644 index 0000000000..483283d3da --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/25_reach1.js @@ -0,0 +1,57 @@ +/* + * @name 팔닿기 1 + * @frame 710,400 + * @description 팔 모양이 마우스 위치를 따라다닙니다. 팔의 각도는 atan2()로 계산됩니다. + * 이 예제는 키스 피터스(Keith Peters)가 제작한 코드를 기반으로 합니다. + */ +let segLength = 80, + x, + y, + x2, + y2; + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x = width / 2; + y = height / 2; + x2 = x; + y2 = y; +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + + tx = mouseX - cos(angle1) * segLength; + ty = mouseY - sin(angle1) * segLength; + dx = tx - x2; + dy = ty - y2; + angle2 = atan2(dy, dx); + x = x2 + cos(angle2) * segLength; + y = y2 + sin(angle2) * segLength; + + segment(x, y, angle1); + segment(x2, y2, angle2); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/ko/10_Interaction/26_reach2.js b/dist/assets/examples/ko/10_Interaction/26_reach2.js new file mode 100644 index 0000000000..d6b1ae8272 --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/26_reach2.js @@ -0,0 +1,65 @@ +/* + * @name 팔닿기 2 + * @frame 710,400 + * @description 팔 모양이 마우스 위치를 따라다닙니다. 팔의 각도는 atan2()로 계산됩니다. + * 이 예제는 키스 피터스(Keith Peters)가 제작한 코드를 기반으로 합니다. + */ +let numSegments = 10, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x[x.length - 1] = width / 2; // 기본 x좌표 설정 + y[x.length - 1] = height; // 기본 y좌표 설정 +} + +function draw() { + background(0); + + reachSegment(0, mouseX, mouseY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/ko/10_Interaction/27_reach3.js b/dist/assets/examples/ko/10_Interaction/27_reach3.js new file mode 100644 index 0000000000..fdf58bc952 --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/27_reach3.js @@ -0,0 +1,81 @@ +/* + * @name 팔닿기 3 + * @frame 710,400 + * @description 팔모양이 공의 위치를 따라다닙니다. 팔의 각도는 atan2()로 계산됩니다. + * 이 예제는 키스 피터스(Keith Peters)가 제작한 코드를 기반으로 합니다. + */ +let numSegments = 8, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY, + ballX = 50, + ballY = 50, + ballXDirection = 1, + ballYDirection = -1; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + noFill(); + + x[x.length - 1] = width / 2; // 기본 x좌표 설정 + y[x.length - 1] = height; // 기본 y좌표 설정 +} + +function draw() { + background(0); + + strokeWeight(20); + ballX = ballX + 1.0 * ballXDirection; + ballY = ballY + 0.8 * ballYDirection; + if (ballX > width - 25 || ballX < 25) { + ballXDirection *= -1; + } + if (ballY > height - 25 || ballY < 25) { + ballYDirection *= -1; + } + ellipse(ballX, ballY, 30, 30); + + reachSegment(0, ballX, ballY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/ko/10_Interaction/28_ArduinoSensor.js b/dist/assets/examples/ko/10_Interaction/28_ArduinoSensor.js new file mode 100644 index 0000000000..b4b1195d1b --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/28_ArduinoSensor.js @@ -0,0 +1,38 @@ +/* + * @name 웹잭과 아두이노 센서 데이터 + * @description 웹잭(WebJack)은 오디오를 사용하여 아두이노와 + * 다른 소스들로부터 데이터를 읽어오는 한 방식입니다. + * 기본적으로, 아두이노를 오디오 모뎀으로 변환합니다. + * + * https://github.com/publiclab/webjack + * + * 주의: 이 예제를 로컬 프로젝트에서 실행하려면, index.html 파일에 WebJack과 p5-webjack 라이브러리를 다음과같이 추가해야 합니다: + *
<script src="https://webjack.io/dist/webjack.js"></script>
+ *
<script src="https://jywarren.github.io/p5-webjack/lib.js"></script>
+ * + * 작동 예시: https://editor.p5js.org/jywarren/sketches/rkztwSt8M + * + * 오디오 테스팅: https://www.youtube.com/watch?v=GtJW1Dlt3cg + * 이 스케치를 아두이노로 불러오세요: + * https://create.arduino.cc/editor/jywarren/023158d8-be51-4c78-99ff-36c63126b554/preview + * 아두이노가 pin 3 + ground로부터 오디오를 출력할 것입니다. 마이크나 오디오 케이블을 사용하세요. + */ + +function setup() { + createCanvas(400, 400); + noStroke(); + fill('#ff00aa22'); + receiveSensorData(handleData); +} + +function handleData(data, connection) { + + console.log(data); // 값을 로그에 출력 + // data[0] = 첫번째 값, data[1] = 두번째 값 ... + + // 그려보세요! 참고: http://p5js.org/reference/ + background('#ddd'); + ellipse(100, 200, data[0]+10, data[0]+10); + + // connection.send('아두이노가 오디오리스닝 중이라면 아두이노로 데이터를 다시 전송하기'); +} diff --git a/dist/assets/examples/ko/10_Interaction/29_kaleidoscope.js b/dist/assets/examples/ko/10_Interaction/29_kaleidoscope.js new file mode 100644 index 0000000000..56b1b24cb7 --- /dev/null +++ b/dist/assets/examples/ko/10_Interaction/29_kaleidoscope.js @@ -0,0 +1,76 @@ +/* + * @name 만화경 + * @description +436/5000 +만화경은 두 개 이상의 반사면이 서로를 향해 비스듬히 기울어진 광학 기기를 말합니다. +이 예제는 만화경의 작동 원리를 복제하고 재현합니다. "대칭(symmetry)" 변수를 통해 반사 횟수를 조정하고 화면 위에 그림을 그려보세요. +슬라이더를 사용하여 브러시 크기를 조정할 수 있습니다. "clearButton"은 화면을 지웁니다. "saveButton" 버튼은 사용자가 만든 작품을 .jpg 파일로 다운로드합니다. +*/ +// 반사 횟수에 따른 대칭을 설정합니다. 반사 횟수를 조정해보세요. +let symmetry = 6; + +let angle = 360 / symmetry; +let saveButton, clearButton, mouseButton, keyboardButton; +let slider; + +function setup() { + createCanvas(710, 710); + angleMode(DEGREES); + background(127); + + // 파일 저장을 위한 saveButton 생성하기 + saveButton = createButton('save'); + saveButton.mousePressed(saveFile); + + // 화면 지우기를 위한 claerButton 생성하기 + clearButton = createButton('clear'); + clearButton.mousePressed(clearScreen); + + // 전체 화면 보기를 위한 fullscreenButton 생성하기 + fullscreenButton = createButton('Full Screen'); + fullscreenButton.mousePressed(screenFull); + + // 브러시 두께 조정을 위한 슬라이더 설정하기 + brushSizeSlider = createButton('Brush Size Slider'); + sizeSlider = createSlider(1, 32, 4, 0.1); +} + +// 파일 저장 함수 +function saveFile() { + save('design.jpg'); +} + +// 화면 지우기 함수 +function clearScreen() { + background(127); +} + +// 전체 화면 보기 함수 +function screenFull() { + let fs = fullscreen(); + fullscreen(!fs); +} + +function draw() { + translate(width / 2, height / 2); + + if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) { + let mx = mouseX - width / 2; + let my = mouseY - height / 2; + let pmx = pmouseX - width / 2; + let pmy = pmouseY - height / 2; + + if (mouseIsPressed) { + for (let i = 0; i < symmetry; i++) { + rotate(angle); + let sw = sizeSlider.value(); + strokeWeight(sw); + line(mx, my, pmx, pmy); + push(); + scale(1, -1); + line(mx, my, pmx, pmy); + pop(); + } + } + } +} diff --git a/dist/assets/examples/ko/11_Objects/01_Objects.js b/dist/assets/examples/ko/11_Objects/01_Objects.js new file mode 100644 index 0000000000..cffbe8d85c --- /dev/null +++ b/dist/assets/examples/ko/11_Objects/01_Objects.js @@ -0,0 +1,39 @@ +/* + * @name 객체 + * @description Jitter 클래스를 만들고, 객체를 인스턴스화하여 + * 화면 안에서 움직여보세요. 캐시 리스(Casey Reas) & 벤 프라이(Ben Fry) 저 Getting Started with + * Processing에서 옮김. + */ + +let bug; // 객체 선언하기 + +function setup() { + createCanvas(710, 400); + // 객체 생성하기 + bug = new Jitter(); +} + +function draw() { + background(50, 89, 100); + bug.move(); + bug.display(); +} + +// Jitter 클래스 +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/ko/11_Objects/02_Multiple_Objects.js b/dist/assets/examples/ko/11_Objects/02_Multiple_Objects.js new file mode 100644 index 0000000000..8a0a96a3f4 --- /dev/null +++ b/dist/assets/examples/ko/11_Objects/02_Multiple_Objects.js @@ -0,0 +1,50 @@ +/* + * @name 복수 객체 + * @description Jitter 클래스를 만들고, 복수의 객체를 인스턴스화하여 + * 화면 안에서 움직여보세요. + */ + +let bug1; // 객체들 선언하기 +let bug2; +let bug3; +let bug4; + +function setup() { + createCanvas(710, 400); + // 객체 생성하기 + bug1 = new Jitter(); + bug2 = new Jitter(); + bug3 = new Jitter(); + bug4 = new Jitter(); +} + +function draw() { + background(50, 89, 100); + bug1.move(); + bug1.display(); + bug2.move(); + bug2.display(); + bug3.move(); + bug3.display(); + bug4.move(); + bug4.display(); +} + +// Jitter 클래스 +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/ko/11_Objects/03_Objects_Array.js b/dist/assets/examples/ko/11_Objects/03_Objects_Array.js new file mode 100644 index 0000000000..2fac9f60b8 --- /dev/null +++ b/dist/assets/examples/ko/11_Objects/03_Objects_Array.js @@ -0,0 +1,42 @@ +/* + * @name 객체 배열 + * @description Jitter 클래스를 만들고, 객체 배열을 인스턴스화하여 + * 화면 안에서 움직여보세요. + */ + +let bugs = []; // Jitter 객체들의 배열 + +function setup() { + createCanvas(710, 400); + // 객체들 생성하기 + for (let i = 0; i < 50; i++) { + bugs.push(new Jitter()); + } +} + +function draw() { + background(50, 89, 100); + for (let i = 0; i < bugs.length; i++) { + bugs[i].move(); + bugs[i].display(); + } +} + +// Jitter 클래스 +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/ko/11_Objects/03_Objects_Optional_Arguments.js b/dist/assets/examples/ko/11_Objects/03_Objects_Optional_Arguments.js new file mode 100644 index 0000000000..25ffa5e70a --- /dev/null +++ b/dist/assets/examples/ko/11_Objects/03_Objects_Optional_Arguments.js @@ -0,0 +1,65 @@ +/* + * @name 객체 2 + * @description hbarragan 제작 예제에서 옮김. 이미지 위로 마우스를 움직여 + * 기하의 속도와 위치를 바꿔보세요. MRect 클래스가 선들의 군상을 정의합니다. + * defines a group of lines. + */ + +let r1, r2, r3, r4; + +function setup() { + createCanvas(710, 400); + fill(255, 204); + noStroke(); + r1 = new MRect(1, 134.0, 0.532, 0.1 * height, 10.0, 60.0); + r2 = new MRect(2, 44.0, 0.166, 0.3 * height, 5.0, 50.0); + r3 = new MRect(2, 58.0, 0.332, 0.4 * height, 10.0, 35.0); + r4 = new MRect(1, 120.0, 0.0498, 0.9 * height, 15.0, 60.0); +} + +function draw() { + background(0); + + r1.display(); + r2.display(); + r3.display(); + r4.display(); + + r1.move(mouseX - width / 2, mouseY + height * 0.1, 30); + r2.move((mouseX + width * 0.05) % width, mouseY + height * 0.025, 20); + r3.move(mouseX / 4, mouseY - height * 0.025, 40); + r4.move(mouseX - width / 2, height - mouseY, 50); +} + +class MRect { + constructor(iw, ixp, ih, iyp, id, it) { + this.w = iw; // 막대기 한 개 너비 + this.xpos = ixp; // rect의 x위치 + this.h = ih; // rect의 높이 + this.ypos = iyp; // rect의 y위치 + this.d = id; // 막대기 간 거리 + this.t = it; // 막대기 개수 + } + + move(posX, posY, damping) { + let dif = this.ypos - posY; + if (abs(dif) > 1) { + this.ypos -= dif / damping; + } + dif = this.xpos - posX; + if (abs(dif) > 1) { + this.xpos -= dif / damping; + } + } + + display() { + for (let i = 0; i < this.t; i++) { + rect( + this.xpos + i * (this.d + this.w), + this.ypos, + this.w, + height * this.h + ); + } + } +} diff --git a/dist/assets/examples/ko/11_Objects/04_Inheritance.js b/dist/assets/examples/ko/11_Objects/04_Inheritance.js new file mode 100644 index 0000000000..ab5a51bafa --- /dev/null +++ b/dist/assets/examples/ko/11_Objects/04_Inheritance.js @@ -0,0 +1,70 @@ +/* @name 상속 + * @description 다른 클래스에 기초하여 클래스를 정의할 수 있습니다. + * 객체 지향 프로그래밍 언어에서, 한 클래스는 다른 클래스의 필드와 메소드를 상속할 수 있습니다. + * 이처럼 다른 객체로부터 상속받는 객체를 하위 클래스라 하고, + * 상속하는 객체를 상위 클래스라고 합니다. + * 하위 클래스는 상위 클래스를 확장합니다. + */ +let spots, arm; + +function setup() { + createCanvas(640, 360); + arm = new SpinArm(width/2, height/2, 0.01); + spots = new SpinSpots(width/2, height/2, -0.02, 90.0); +} + +function draw() { + background(204); + arm.update(); + arm.display(); + spots.update(); + spots.display(); +} + +class Spin { + constructor(x, y, s) { + this.x = x; + this.y = y; + this.speed = s; + this.angle = 0.0; + } + + update() { + this.angle += this.speed; + } +} + +class SpinArm extends Spin { + constructor(x, y, s) { + super(x, y, s) + } + + display() { + strokeWeight(1); + stroke(0); + push(); + translate(this.x, this.y); + this.angle += this.speed; + rotate(this.angle); + line(0, 0, 165, 0); + pop(); + } +} + +class SpinSpots extends Spin { + constructor(x, y, s, d) { + super(x, y, s) + this.dim = d; + } + + display() { + noStroke(); + push(); + translate(this.x, this.y); + this.angle += this.speed; + rotate(this.angle); + ellipse(-this.dim/2, 0, this.dim, this.dim); + ellipse(this.dim/2, 0, this.dim, this.dim); + pop(); + } +} \ No newline at end of file diff --git a/dist/assets/examples/ko/11_Objects/05_Composite_Objects.js b/dist/assets/examples/ko/11_Objects/05_Composite_Objects.js new file mode 100644 index 0000000000..b1872b76bd --- /dev/null +++ b/dist/assets/examples/ko/11_Objects/05_Composite_Objects.js @@ -0,0 +1,98 @@ +/* @name 합성 객체 + * @description 한 객체는 여러 개의 다른 객체들을 담을 수 있습니다. + * 합성 객체를 생성하면 모듈화 원칙들을 활용하거나, 또 높은 수준의 추상을 구축하기에 좋습니다. + */ +let er1, er2; + +function setup() { + createCanvas(640, 360); + er1 = new EggRing(width*0.45, height*0.5, 0.1, 120); + er2 = new EggRing(width*0.65, height*0.8, 0.05, 180); +} + +function draw() { + background(0); + er1.transmit(); + er2.transmit(); +} + +class Egg { + constructor(xpos, ypos, t, s) { + this.x = xpos; + this.y = ypos; + this.tilt = t; + this.scalar = s / 100.0; + this.angle = 0.0; + } + + wobble() { + this.tilt = cos(this.angle) / 8; + this.angle += 0.1; + } + + display() { + noStroke(); + fill(255); + push(); + translate(this.x, this.y); + rotate(this.tilt); + scale(this.scalar); + beginShape(); + vertex(0, -100); + bezierVertex(25, -100, 40, -65, 40, -40); + bezierVertex(40, -15, 25, 0, 0, 0); + bezierVertex(-25, 0, -40, -15, -40, -40); + bezierVertex(-40, -65, -25, -100, 0, -100); + endShape(); + pop(); + } +} + +class Ring { + start(xpos, ypos) { + this.x = xpos; + this.y = ypos; + this.on = true; + this.diameter = 1; + } + + grow() { + if (this.on == true) { + this.diameter += 0.5; + if (this.diameter > width*2) { + this.diameter = 0.0; + } + } + } + + display() { + if (this.on == true) { + noFill(); + strokeWeight(4); + stroke(155, 153); + ellipse(this.x, this.y, this.diameter, this.diameter); + } + } +} + +class EggRing { + constructor(x, y, t, sp) { + this.x = x; + this.y = y; + this.t = t; + this.sp = sp; + this.circle = new Ring(); + this.ovoid = new Egg(this.x, this.y, this.t, this.sp); + this.circle.start(this.x, this.y - this.sp/2); + } + + transmit() { + this.ovoid.wobble(); + this.ovoid.display(); + this.circle.grow(); + this.circle.display(); + if (circle.on == false) { + circle.on = true; + } + } +} diff --git a/dist/assets/examples/ko/11_Objects/06_Car_Instances.js b/dist/assets/examples/ko/11_Objects/06_Car_Instances.js new file mode 100644 index 0000000000..1966f9c8e3 --- /dev/null +++ b/dist/assets/examples/ko/11_Objects/06_Car_Instances.js @@ -0,0 +1,82 @@ +/* + * @name Car Instances + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to create three instances of Car Class and +invoke class methods.
+ A function is created for the canvas setup, and +3 car instances are initialized with different colors and canvas +positions. The speed of each car is set by passing value to the +instance’s start method. A second function calls class methods to +display and move the cars. +*/ +class Car { + /* Constructor expects parameters for + fill color, x and y coordinates that + will be used to initialize class properties. + */ + constructor(cColor, x, y) { + this.color = cColor; + this.doors = 4; + this.isConvertible = false; + this.x = x; + this.y = y; + this.speed = 0; + } + + start(speed) { // method expects parameter! + this.speed = speed; + } + + display() { // method! + fill(this.color); + rect(this.x, this.y, 20, 10); + } + + move() { // method! + this.x += this.speed; + // Wrap x around boundaries + if (this.x < -20) { + this.x = width; + } else if (this.x > width) { + this.x = -20; + } + } +} //end class Car + +let rav4; +let charger; +let nova; + +function setup() { + createCanvas(200, 400); + /* Construct the 3 Cars */ + //constructor expects cColor, x, y + rav4 = new Car("silver", 100, 300); + charger = new Car("gold", 0, 200); + nova = new Car("blue", 200, 100); + nova.doors = 2; //update nova's doors property + + console.log("rav4", rav4); + console.log("charger", charger); + console.log("nova", nova); + + //call start methods of Car instances + //the start method expects a number for speed + rav4.start(2.3); + charger.start(-4); + nova.start(random(-1, 1)); +} + +function draw() { + background("beige"); + + //display and move all 3 Cars + rav4.display(); + charger.display(); + nova.display(); + + rav4.move(); + charger.move(); + nova.move(); +} diff --git a/dist/assets/examples/ko/12_Lights/02_Directional.js b/dist/assets/examples/ko/12_Lights/02_Directional.js new file mode 100644 index 0000000000..2e09a2c792 --- /dev/null +++ b/dist/assets/examples/ko/12_Lights/02_Directional.js @@ -0,0 +1,28 @@ +/* + * @name 디렉셔널 라이트 + * @frame 710,400 + * @description 마우스를 움직여 조명의 방향을 바꿔보세요. + * 디렉셔널 라이트는 한 방향에서 비롯되며 + * 표면에 직각으로 닿을 때 강한 빛을, + * 부드러운 각도로 닿았을 때 약한 빛을 보입니다. + * 디렉셔널 라이트는 표면에 닿으면 그 빛이 모든 방향으로 흩어집니다. + */ +const radius = 200; + +function setup() { + createCanvas(710, 400, WEBGL); + noStroke(); + fill(200); +} + +function draw() { + noStroke(); + background(0); + const dirY = (mouseY / height - 0.5) * 4; + const dirX = (mouseX / width - 0.5) * 4; + directionalLight(204, 204, 204, dirX, dirY, 1); + translate(-1.5 * radius, 0, 0); + sphere(radius); + translate(3 * radius, 0, 0); + sphere(radius); +} diff --git a/dist/assets/examples/ko/12_Lights/05_Mixture.js b/dist/assets/examples/ko/12_Lights/05_Mixture.js new file mode 100644 index 0000000000..d01c872f70 --- /dev/null +++ b/dist/assets/examples/ko/12_Lights/05_Mixture.js @@ -0,0 +1,26 @@ +/* + * @name 혼합 라이트 + * @frame 710,400 (optional) + * @description 세 개의 다른 조명과 함께 박스를 보여줍니다. + */ +function setup() { + createCanvas(710, 400, WEBGL); + noStroke(); +} + +function draw() { + background(0); + + // 우측에서 비추는 오렌지색 포인트 라이트 + pointLight(150, 100, 0, 500, 0, 200); + + // 좌측에서 비추는 파랑색 디렉셔널 라이트 + directionalLight(0, 102, 255, -1, 0, 0); + + // 정면에서 비추는 노랑색 스포트라이트 + pointLight(255, 255, 109, 0, 0, 300); + + rotateY(map(mouseX, 0, width, 0, PI)); + rotateX(map(mouseY, 0, height, 0, PI)); + box(200); +} diff --git a/dist/assets/examples/ko/13_Motion/01_non_orthogonal_reflection.js b/dist/assets/examples/ko/13_Motion/01_non_orthogonal_reflection.js new file mode 100644 index 0000000000..028d28ef51 --- /dev/null +++ b/dist/assets/examples/ko/13_Motion/01_non_orthogonal_reflection.js @@ -0,0 +1,110 @@ +/* + * @name 비직각 반사 + * @frame 710,400 (optional) + * @description 이 예제는 processing.org/examples의 "Reflection 1" 예제를 데이비드 블리츠(David Blitz)가 옮긴 것입니다. + */ + +// 바닥의 왼쪽 위치 +let base1; + +// 바닥의 오른쪽 위치 +let base2; +// 바닥의 길이 +//let baseLength; + +// 움직이는 공에 대한 변수들 +let position; +let velocity; +let r = 6; +let speed = 3.5; + +function setup() { + createCanvas(710, 400); + + fill(128); + base1 = createVector(0, height - 150); + base2 = createVector(width, height); + //createGround(); + + // 화면 중앙의 상단에서 타원형 시작 + position = createVector(width / 2, 0); + + // 초기 임의 속도 계산 + velocity = p5.Vector.random2D(); + velocity.mult(speed); +} + +function draw() { + // 배경 그리기 + fill(0, 12); + noStroke(); + rect(0, 0, width, height); + + // base(밑바닥) 그리기 + fill(200); + quad(base1.x, base1.y, base2.x, base2.y, base2.x, height, 0, height); + + // base(밑바닥) 상단의 normal(표준) 계산하기 + let baseDelta = p5.Vector.sub(base2, base1); + baseDelta.normalize(); + let normal = createVector(-baseDelta.y, baseDelta.x); + let intercept = p5.Vector.dot(base1, normal); + + // ellipse(타원) 그리기 + noStroke(); + fill(255); + ellipse(position.x, position.y, r * 2, r * 2); + + // 타원 움직이기 + position.add(velocity); + + // 표준화된 투사 벡터 + incidence = p5.Vector.mult(velocity, -1); + incidence.normalize(); + + // 밑바닥과의 충돌 감지하고 조정하기 + if (p5.Vector.dot(normal, position) > intercept) { + //투사 벡터와 밑바닥 상단의 dot(점) 계산 + let dot = incidence.dot(normal); + + // 반사 벡터 계산 + // 반사 벡터를 방향 벡터에 지정 + velocity.set( + 2 * normal.x * dot - incidence.x, + 2 * normal.y * dot - incidence.y, + 0 + ); + velocity.mult(speed); + + // 충돌 지점에서 밑바닥 상단 표준 그리기 + stroke(255, 128, 0); + line( + position.x, + position.y, + position.x - normal.x * 100, + position.y - normal.y * 100 + ); + } + //} + + // 경계면 충돌 감지 + // 우측 + if (position.x > width - r) { + position.x = width - r; + velocity.x *= -1; + } + // 좌측 + if (position.x < r) { + position.x = r; + velocity.x *= -1; + } + // 상단 + if (position.y < r) { + position.y = r; + velocity.y *= -1; + + // 밑바닥의 상단 임의화하기 + base1.y = random(height - 100, height); + base2.y = random(height - 100, height); + } +} diff --git a/dist/assets/examples/ko/13_Motion/02_Linear_Motion.js b/dist/assets/examples/ko/13_Motion/02_Linear_Motion.js new file mode 100644 index 0000000000..454e13377a --- /dev/null +++ b/dist/assets/examples/ko/13_Motion/02_Linear_Motion.js @@ -0,0 +1,24 @@ +/* + * @name 선형 + * @frame 720,400 + * @description 변수를 바꿔 움직이는 선을 만들어보세요. + * 선이 화면 상단 밖으로 나가면 변수는 0이 되어 + * 선의 위치를 화면의 하단으로 되돌립니다. + */ + +let a; + +function setup() { + createCanvas(720, 400); + stroke(255); + a = height / 2; +} + +function draw() { + background(51); + line(0, a, width, a); + a = a - 0.5; + if (a < 0) { + a = height; + } +} diff --git a/dist/assets/examples/ko/13_Motion/03_Bounce.js b/dist/assets/examples/ko/13_Motion/03_Bounce.js new file mode 100644 index 0000000000..c1a6b9ae7f --- /dev/null +++ b/dist/assets/examples/ko/13_Motion/03_Bounce.js @@ -0,0 +1,44 @@ +/* + * @name 바운스 + * @frame 720,400 + * @description 도형이 화면의 모서리에 닿으면 반대 방향으로 움직입니다. + */ + +let rad = 60; // 도형의 너비 +let xpos, ypos; // 도형의 시작점 + +let xspeed = 2.8; // 도형의 속도 +let yspeed = 2.2; // 도형의 속도 + +let xdirection = 1; // 왼쪽 또는 오른쪽 +let ydirection = 1; // 위 또는 아래 + +function setup() { + createCanvas(720, 400); + noStroke(); + frameRate(30); + ellipseMode(RADIUS); + // 도형의 시작점 설정 + xpos = width / 2; + ypos = height / 2; +} + +function draw() { + background(102); + + // 도형의 위치 업데이트 + xpos = xpos + xspeed * xdirection; + ypos = ypos + yspeed * ydirection; + + // 도형이 화면 경계를 넘어가는 지 테스트 + // 넘어갈 경우, -1을 곱하여 방향을 반대로 돌린다. + if (xpos > width - rad || xpos < rad) { + xdirection *= -1; + } + if (ypos > height - rad || ypos < rad) { + ydirection *= -1; + } + + // 도형 그리기 + ellipse(xpos, ypos, rad, rad); +} diff --git a/dist/assets/examples/ko/13_Motion/04_Bouncy_Bubbles.js b/dist/assets/examples/ko/13_Motion/04_Bouncy_Bubbles.js new file mode 100644 index 0000000000..108b83b8ba --- /dev/null +++ b/dist/assets/examples/ko/13_Motion/04_Bouncy_Bubbles.js @@ -0,0 +1,95 @@ +/* + * @name 버블 바운스 + * @frame 720,400 + * @description 이 예제는 키스 피터스(Keith Peters)가 제작한 복수-객체 충돌(Multiple-object collision) 예제 코드를 기반으로 합니다. + */ + +let numBalls = 13; +let spring = 0.05; +let gravity = 0.03; +let friction = -0.9; +let balls = []; + +function setup() { + createCanvas(720, 400); + for (let i = 0; i < numBalls; i++) { + balls[i] = new Ball( + random(width), + random(height), + random(30, 70), + i, + balls + ); + } + noStroke(); + fill(255, 204); +} + +function draw() { + background(0); + balls.forEach(ball => { + ball.collide(); + ball.move(); + ball.display(); + }); +} + +class Ball { + constructor(xin, yin, din, idin, oin) { + this.x = xin; + this.y = yin; + let vx = 0; + let vy = 0; + this.diameter = din; + this.id = idin; + this.others = oin; + } + + collide() { + for (let i = this.id + 1; i < numBalls; i++) { + // console.log(others[i]); + let dx = this.others[i].x - this.x; + let dy = this.others[i].y - this.y; + let distance = sqrt(dx * dx + dy * dy); + let minDist = this.others[i].diameter / 2 + this.diameter / 2; + // console.log(distance); + //console.log(minDist); + if (distance < minDist) { + //console.log("2"); + let angle = atan2(dy, dx); + let targetX = this.x + cos(angle) * minDist; + let targetY = this.y + sin(angle) * minDist; + let ax = (targetX - this.others[i].x) * spring; + let ay = (targetY - this.others[i].y) * spring; + vx -= ax; + vy -= ay; + this.others[i].vx += ax; + this.others[i].vy += ay; + } + } + } + + move() { + vy += gravity; + this.x += vx; + this.y += vy; + if (this.x + this.diameter / 2 > width) { + this.x = width - this.diameter / 2; + vx *= friction; + } else if (this.x - this.diameter / 2 < 0) { + this.x = this.diameter / 2; + vx *= friction; + } + if (this.y + this.diameter / 2 > height) { + this.y = height - this.diameter / 2; + vy *= friction; + } else if (this.y - this.diameter / 2 < 0) { + this.y = this.diameter / 2; + vy *= friction; + } + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/ko/13_Motion/05_Morph.js b/dist/assets/examples/ko/13_Motion/05_Morph.js new file mode 100644 index 0000000000..6a950d7d97 --- /dev/null +++ b/dist/assets/examples/ko/13_Motion/05_Morph.js @@ -0,0 +1,92 @@ +/* + * @name 변형(morph) + * @frame 720,400 + * @description 버텍스를 보간하여 한 모양에서 다른 모양으로 바꾸기 + */ + +// 두 도형의 버텍스들을 저장하는 두 개의 배열 리스트(ArrayList) +// 이 예제는 두 도형이 동일한 개수의 버텍스를 갖고 있다는 것을 전제합니다. +// 즉, 배열 리스트가 동일하다는 뜻입니다. +let circle = []; +let square = []; + +// 3번째 버텍스 묶음 저장을 위한 배열 리스트 +// 화면상 그려집니다. +let morph = []; + +// 이 불리언 변수는 원형이나 사각형으로 변형할지 여부를 결정합니다. +let state = false; + +function setup() { + createCanvas(720, 400); + + // 중심을 가리키는 벡터를 사용하여 원 그리기 + for (let angle = 0; angle < 360; angle += 9) { + // 주의: 원의 이동 경로와 상응하기 위해, 0에서 시작하지 않습니다. + let v = p5.Vector.fromAngle(radians(angle - 135)); + v.mult(100); + circle.push(v); + // morph 배열 리스트를 빈 PVector로 채웁니다. + morph.push(createVector()); + } + + // 사각형은 직선을 따라 이어진 여러 개의 버텍스입니다. + // 사각형 상단 + for (let x = -50; x < 50; x += 10) { + square.push(createVector(x, -50)); + } + // 사각형 우측 + for (let y = -50; y < 50; y += 10) { + square.push(createVector(50, y)); + } + // 사각형 하단 + for (let x = 50; x > -50; x -= 10) { + square.push(createVector(x, 50)); + } + // 사각형 좌측 + for (let y = 50; y > -50; y -= 10) { + square.push(createVector(-50, y)); + } +} + +function draw() { + background(51); + + // 이 버텍스들이 목표 대상으로부터 얼마나 멀리 있는지 확인 + let totalDistance = 0; + + // 각 버텍스 확인 + for (let i = 0; i < circle.length; i++) { + let v1; + // 원형이나 사각형으로 선형 보간합니까? + if (state) { + v1 = circle[i]; + } else { + v1 = square[i]; + } + // 그려질 버텍스 가져오기 + let v2 = morph[i]; + // 대상을 향해 선형 보간하기 + v2.lerp(v1, 0.1); + // 목표 대상으로부터 얼마나 멀리 있는지 확인 + totalDistance += p5.Vector.dist(v1, v2); + } + + // 모든 버텍스들이 가까워지면, 모양 전환 + if (totalDistance < 0.1) { + state = !state; + } + + // 중심을 기준으로 그리기 + translate(width / 2, height / 2); + strokeWeight(4); + // 모든 버텍스를 구성하는 다각형 그리기 + beginShape(); + noFill(); + stroke(255); + + morph.forEach(v => { + vertex(v.x, v.y); + }); + endShape(CLOSE); +} diff --git a/dist/assets/examples/ko/13_Motion/06_Moving_On_Curves.js b/dist/assets/examples/ko/13_Motion/06_Moving_On_Curves.js new file mode 100644 index 0000000000..0a65c143f6 --- /dev/null +++ b/dist/assets/examples/ko/13_Motion/06_Moving_On_Curves.js @@ -0,0 +1,47 @@ +/* + * @name 곡선 위 움직이기 + * @frame 720,400 + * @description 이 예제에서, 원들은 y = x^4 곡선을 따라 움직입니다. + * 마우스를 클릭하여 새로운 위치로 움직이도록 해보세요. + */ + +let beginX = 20.0; // 초기 x 좌표 +let beginY = 10.0; // 초기 y 좌표 +let endX = 570.0; // 최종 x 좌표 +let endY = 320.0; // 최종 y 좌표 +let distX; // 이동할 X축 거리 +let distY; // 이동할 Y축 거리 +let exponent = 4; // 곡선 결정 +let x = 0.0; // 현재 x 좌표 +let y = 0.0; // 현재 y 좌표 +let step = 0.01; // 경로를 따른 각 단계별 움직임 크기 +let pct = 0.0; // 이동 거리 비율 (0.0과 1.0 사이) + +function setup() { + createCanvas(720, 400); + noStroke(); + distX = endX - beginX; + distY = endY - beginY; +} + +function draw() { + fill(0, 2); + rect(0, 0, width, height); + pct += step; + if (pct < 1.0) { + x = beginX + pct * distX; + y = beginY + pow(pct, exponent) * distY; + } + fill(255); + ellipse(x, y, 20, 20); +} + +function mousePressed() { + pct = 0.0; + beginX = x; + beginY = y; + endX = mouseX; + endY = mouseY; + distX = endX - beginX; + distY = endY - beginY; +} diff --git a/dist/assets/examples/ko/13_Motion/07_Circle_Collision.js b/dist/assets/examples/ko/13_Motion/07_Circle_Collision.js new file mode 100644 index 0000000000..876bc23d6e --- /dev/null +++ b/dist/assets/examples/ko/13_Motion/07_Circle_Collision.js @@ -0,0 +1,145 @@ +/* + * @name Circle Collision + * @frame 710,400 (optional) + * @description This is a port of the "Circle Collision" example from processing.org/examples
This example uses vectors for better visualization of physical Quantity + */ +class Ball { + constructor(x, y, r) { + this.position = new p5.Vector(x, y); + this.velocity = p5.Vector.random2D(); + this.velocity.mult(3); + this.r = r; + this.m = r * 0.1; + } + update() { + this.position.add(this.velocity); + } + + checkBoundaryCollision() { + if (this.position.x > width - this.r) { + this.position.x = width - this.r; + this.velocity.x *= -1; + } else if (this.position.x < this.r) { + this.position.x = this.r; + this.velocity.x *= -1; + } else if (this.position.y > height - this.r) { + this.position.y = height - this.r; + this.velocity.y *= -1; + } else if (this.position.y < this.r) { + this.position.y = this.r; + this.velocity.y *= -1; + } + } + + checkCollision(other) { + // Get distances between the balls components + let distanceVect = p5.Vector.sub(other.position, this.position); + + // Calculate magnitude of the vector separating the balls + let distanceVectMag = distanceVect.mag(); + + // Minimum distance before they are touching + let minDistance = this.r + other.r; + + if (distanceVectMag < minDistance) { + let distanceCorrection = (minDistance - distanceVectMag) / 2.0; + let d = distanceVect.copy(); + let correctionVector = d.normalize().mult(distanceCorrection); + other.position.add(correctionVector); + this.position.sub(correctionVector); + + // get angle of distanceVect + let theta = distanceVect.heading(); + // precalculate trig values + let sine = sin(theta); + let cosine = cos(theta); + + /* bTemp will hold rotated ball this.positions. You + just need to worry about bTemp[1] this.position*/ + let bTemp = [new p5.Vector(), new p5.Vector()]; + + /* this ball's this.position is relative to the other + so you can use the vector between them (bVect) as the + reference point in the rotation expressions. + bTemp[0].this.position.x and bTemp[0].this.position.y will initialize + automatically to 0.0, which is what you want + since b[1] will rotate around b[0] */ + bTemp[1].x = cosine * distanceVect.x + sine * distanceVect.y; + bTemp[1].y = cosine * distanceVect.y - sine * distanceVect.x; + + // rotate Temporary velocities + let vTemp = [new p5.Vector(), new p5.Vector()]; + + vTemp[0].x = cosine * this.velocity.x + sine * this.velocity.y; + vTemp[0].y = cosine * this.velocity.y - sine * this.velocity.x; + vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y; + vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x; + + /* Now that velocities are rotated, you can use 1D + conservation of momentum equations to calculate + the final this.velocity along the x-axis. */ + let vFinal = [new p5.Vector(), new p5.Vector()]; + + // final rotated this.velocity for b[0] + vFinal[0].x = + ((this.m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / + (this.m + other.m); + vFinal[0].y = vTemp[0].y; + + // final rotated this.velocity for b[0] + vFinal[1].x = + ((other.m - this.m) * vTemp[1].x + 2 * this.m * vTemp[0].x) / + (this.m + other.m); + vFinal[1].y = vTemp[1].y; + + // hack to avoid clumping + bTemp[0].x += vFinal[0].x; + bTemp[1].x += vFinal[1].x; + + /* Rotate ball this.positions and velocities back + Reverse signs in trig expressions to rotate + in the opposite direction */ + // rotate balls + let bFinal = [new p5.Vector(), new p5.Vector()]; + + bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y; + bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x; + bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y; + bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x; + + // update balls to screen this.position + other.position.x = this.position.x + bFinal[1].x; + other.position.y = this.position.y + bFinal[1].y; + + this.position.add(bFinal[0]); + + // update velocities + this.velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y; + this.velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x; + other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y; + other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x; + } + } + + display() { + noStroke(); + fill(204); + ellipse(this.position.x, this.position.y, this.r * 2, this.r * 2); + } +} +let balls = [new Ball(100, 400, 20), new Ball(700, 400, 80)]; +console.log(balls); +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(51); + for (let i = 0; i < balls.length; i++) { + let b = balls[i]; + b.update(); + b.display(); + b.checkBoundaryCollision(); + balls[0].checkCollision(balls[1]); + } +} diff --git a/dist/assets/examples/ko/13_Motion/08_Moving_On_Curves.js b/dist/assets/examples/ko/13_Motion/08_Moving_On_Curves.js new file mode 100644 index 0000000000..4c347c7e00 --- /dev/null +++ b/dist/assets/examples/ko/13_Motion/08_Moving_On_Curves.js @@ -0,0 +1,47 @@ +/* + * @name Moving On Curves + * @frame 720,400 + * @description In this example, the circles moves along the curve y = x^4. + * Click the mouse to have it move to a new position. + */ + +let beginX = 20.0; // Initial x-coordinate +let beginY = 10.0; // Initial y-coordinate +let endX = 570.0; // Final x-coordinate +let endY = 320.0; // Final y-coordinate +let distX; // X-axis distance to move +let distY; // Y-axis distance to move +let exponent = 4; // Determines the curve +let x = 0.0; // Current x-coordinate +let y = 0.0; // Current y-coordinate +let step = 0.01; // Size of each step along the path +let pct = 0.0; // Percentage traveled (0.0 to 1.0) + +function setup() { + createCanvas(720, 400); + noStroke(); + distX = endX - beginX; + distY = endY - beginY; +} + +function draw() { + fill(0, 2); + rect(0, 0, width, height); + pct += step; + if (pct < 1.0) { + x = beginX + pct * distX; + y = beginY + pow(pct, exponent) * distY; + } + fill(255); + ellipse(x, y, 20, 20); +} + +function mousePressed() { + pct = 0.0; + beginX = x; + beginY = y; + endX = mouseX; + endY = mouseY; + distX = endX - beginX; + distY = endY - beginY; +} diff --git a/dist/assets/examples/ko/15_Instance_Mode/01_Instantiating.js b/dist/assets/examples/ko/15_Instance_Mode/01_Instantiating.js new file mode 100644 index 0000000000..2f5f4ae97a --- /dev/null +++ b/dist/assets/examples/ko/15_Instance_Mode/01_Instantiating.js @@ -0,0 +1,35 @@ +/* + * @name 인스턴스화 + * @description p5 인스턴스를 만들어, 해당 페이지의 모든 변수들이 + * 전역 범위에서 사용되지 않도록 합니다. + */ +let sketch = function(p) { + let x = 100; + let y = 100; + + p.setup = function() { + p.createCanvas(700, 410); + }; + + p.draw = function() { + p.background(0); + p.fill(255); + p.rect(x, y, 50, 50); + }; +}; + +let myp5 = new p5(sketch); + +// "전역 모드(global mode)"와 비교 +// let x = 100; +// let y = 100; + +// function setup() { +// createCanvas(200,200); +// } + +// function draw() { +// background(0); +// fill(255); +// ellipse(x,y,50,50); +// } diff --git a/dist/assets/examples/ko/15_Instance_Mode/02_Instance_Container.js b/dist/assets/examples/ko/15_Instance_Mode/02_Instance_Container.js new file mode 100644 index 0000000000..b5d6647f6e --- /dev/null +++ b/dist/assets/examples/ko/15_Instance_Mode/02_Instance_Container.js @@ -0,0 +1,92 @@ +/* + * @norender + * @name 인스턴스 컨테이너 + * @description 캔버스에 기본 컨테이너를 지정하거나, + * 두번째 인수로 추가될 수 있는 모든 요소를 지정할 수 있습니다. + * HTML의 요소 id나 HTML 노드 그 자체도 지원됩니다. + * 컨테이너 DOM 요소를 지정하는 세 가지 다른 방법이 있습니다. + * p5로 만들어진 모든 DOM 요소(캔버스, 버튼, div 등)는 + * p5()함수 호출시 두 번째 인수로 지정된 DOM 요소에 담기게 됩니다. + */ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dist/assets/examples/ko/16_Dom/03_Input_Button.js b/dist/assets/examples/ko/16_Dom/03_Input_Button.js new file mode 100644 index 0000000000..76549e0e51 --- /dev/null +++ b/dist/assets/examples/ko/16_Dom/03_Input_Button.js @@ -0,0 +1,41 @@ +/* + * @name 입력과 버튼 + * @description 로컬 프로젝트에서 이 예제를 실행하려면, + * p5.dom 라이브러리 + * 를 추가하면 됩니다.

+ * 텍스트를 입력하고 버튼을 클릭하면 어떤 효과가 캔버스에 나타나는지 보세요. + */ +let input, button, greeting; + +function setup() { + // 캔버스 생성하기 + createCanvas(710, 400); + + input = createInput(); + input.position(20, 65); + + button = createButton('submit'); + button.position(input.x + input.width, 65); + button.mousePressed(greet); + + greeting = createElement('h2', 'what is your name?'); + greeting.position(20, 5); + + textAlign(CENTER); + textSize(50); +} + +function greet() { + const name = input.value(); + greeting.html('hello ' + name + '!'); + input.value(''); + + for (let i = 0; i < 200; i++) { + push(); + fill(random(255), 255, 255); + translate(random(width), random(height)); + rotate(random(2 * PI)); + text(name, 0, 0); + pop(); + } +} diff --git a/dist/assets/examples/ko/16_Dom/04_Slider.js b/dist/assets/examples/ko/16_Dom/04_Slider.js new file mode 100644 index 0000000000..551a4687c4 --- /dev/null +++ b/dist/assets/examples/ko/16_Dom/04_Slider.js @@ -0,0 +1,33 @@ +/* + * @name 슬라이더 + * @description 로컬 프로젝트에서 이 예제를 실행하려면, + * p5.dom 라이브러리 + * 를 추가하면 됩니다.

+ * 슬라이더를 움직여 배경색의 R,G,B값을 조정해보세요. + */ +let rSlider, gSlider, bSlider; + +function setup() { + // 캔버스 생성하기 + createCanvas(710, 400); + textSize(15); + noStroke(); + + // 슬라이더 생성하기 + rSlider = createSlider(0, 255, 100); + rSlider.position(20, 20); + gSlider = createSlider(0, 255, 0); + gSlider.position(20, 50); + bSlider = createSlider(0, 255, 255); + bSlider.position(20, 80); +} + +function draw() { + const r = rSlider.value(); + const g = gSlider.value(); + const b = bSlider.value(); + background(r, g, b); + text('red', rSlider.x * 2 + rSlider.width, 35); + text('green', gSlider.x * 2 + gSlider.width, 65); + text('blue', bSlider.x * 2 + bSlider.width, 95); +} diff --git a/dist/assets/examples/ko/16_Dom/07_Modify_DOM.js b/dist/assets/examples/ko/16_Dom/07_Modify_DOM.js new file mode 100644 index 0000000000..dfbd9b7325 --- /dev/null +++ b/dist/assets/examples/ko/16_Dom/07_Modify_DOM.js @@ -0,0 +1,55 @@ +/* + * @name DOM 변경 + * @frame 710,300 + * @description

DOM 요소를 만들고 draw()함수가 매번 호출될 때마다 + * 그 속성들을 변경해보세요. 로컬 프로젝트에서 이 예제를 실행하려면, + * p5.dom 라이브러리 + * 를 추가하면 됩니다.

+ */ +let dancingWords = []; + +class DanceSpan { + constructor(element, x, y) { + element.position(x, y); + this.element = element; + this.x = x; + this.y = y; + } + + brownian() { + this.x += random(-6, 6); + this.y += random(-6, 6); + this.element.position(this.x, this.y); + } +} + +function setup() { + // 이 단락은 위의 주요 코드 블록의 부록으로서 작성됩니다. + // 아래의 코드들은 요소의 생성과 지정 기능을 구분합니다. + // 지정된 요소들은 p5js로 별도 생성될 필요가 없으며, + // 일반적인 HTML처럼 쓰일 수 있습니다. + createP( + 'I learn in this Letter, that Don Peter of Aragon, ' + + ' comes this night to Messina' + ).addClass('text').hide(); + + // 이 줄은 금방 생성된 '단락'을 받지만, + // 동시에 HTML 페이지상 'text' 클래스를 가진 다른 요소들을 받아오기도 합니다. + const texts = selectAll('.text'); + + for (let i = 0; i < texts.length; i++) { + const paragraph = texts[i].html(); + const words = paragraph.split(' '); + for (let j = 0; j < words.length; j++) { + const spannedWord = createSpan(words[j]); + const dw = new DanceSpan(spannedWord, random(600), random(200)); + dancingWords.push(dw); + } + } +} + +function draw() { + for (let i = 0; i < dancingWords.length; i++) { + dancingWords[i].brownian(); + } +} diff --git a/dist/assets/examples/ko/16_Dom/08_Video.js b/dist/assets/examples/ko/16_Dom/08_Video.js new file mode 100644 index 0000000000..76996c8430 --- /dev/null +++ b/dist/assets/examples/ko/16_Dom/08_Video.js @@ -0,0 +1,30 @@ +/* + * @name 비디오 + * @frame 710,250 + * @description

다양한 형식의 비디오를 불러오고 버튼을 눌러 재생 또는 일시 정지를 합니다. + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 비디오 파일이 필요하고, + * p5.dom 라이브러리를 추가하면 됩니다.

+ */ +let playing = false; +let fingers; +let button; + +function setup() { + noCanvas(); + // 여러 브라우저 지원을 위해 다양한 비디오 형식 지정 + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + button = createButton('play'); + button.mousePressed(toggleVid); // 버튼 리스너 붙이기 +} + +// 현재 상태에 따라 비디오를 재생 또는 일시 정지 +function toggleVid() { + if (playing) { + fingers.pause(); + button.html('play'); + } else { + fingers.loop(); + button.html('pause'); + } + playing = !playing; +} diff --git a/dist/assets/examples/ko/16_Dom/09_Video_Canvas.js b/dist/assets/examples/ko/16_Dom/09_Video_Canvas.js new file mode 100644 index 0000000000..02b9727715 --- /dev/null +++ b/dist/assets/examples/ko/16_Dom/09_Video_Canvas.js @@ -0,0 +1,27 @@ +/* + * @name 비디오 캔버스 + * @description

비디오를 다양한 형식으로 불러와 캔버스 위에 그릴 수 있도록 합니다.

+ *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 비디오 파일이 필요하고, + * p5.dom 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +let fingers; + +function setup() { + createCanvas(710, 400); + // 여러 브라우저 지원을 위해 다양한 비디오 형식 지정 + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.hide(); // 기본값으로, 비디오는 별개의 DOM 요소로 나타납니다. + // 이를 우선 숨긴 뒤, 캔버스에 그릴 수 있도록 해볼까요 +} + +function draw() { + background(150); + image(fingers, 10, 10); // 캔버스에 비디오 프레임 그리기 + filter(GRAY); + image(fingers, 150, 150); // 캔버스에 두번째 사본 그리기 +} + +function mousePressed() { + fingers.loop(); // 반복 재생 설정 및 비디오 재생 +} diff --git a/dist/assets/examples/ko/16_Dom/10_Video_Pixels.js b/dist/assets/examples/ko/16_Dom/10_Video_Pixels.js new file mode 100644 index 0000000000..10bd28beef --- /dev/null +++ b/dist/assets/examples/ko/16_Dom/10_Video_Pixels.js @@ -0,0 +1,33 @@ +/* + * @name 비디오 픽셀 + * @frame 320,240 + * @description

비디오를 불러와 픽셀을 조정하고 캔버스에 그려보세요. + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 비디오 파일이 필요하고, + * p5.dom 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +let fingers; + +function setup() { + createCanvas(320, 240); + // 여러 브라우저 지원을 위해 다양한 비디오 형식 지정 + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.loop(); + fingers.hide(); + noStroke(); + fill(0); +} + +function draw() { + background(255); + fingers.loadPixels(); + const stepSize = round(constrain(mouseX / 8, 6, 32)); + for (let y = 0; y < height; y += stepSize) { + for (let x = 0; x < width; x += stepSize) { + const i = y * width + x; + const darkness = (255 - fingers.pixels[i * 4]) / 255; + const radius = stepSize * darkness; + ellipse(x, y, radius, radius); + } + } +} diff --git a/dist/assets/examples/ko/16_Dom/11_Capture.js b/dist/assets/examples/ko/16_Dom/11_Capture.js new file mode 100644 index 0000000000..4c3457e2a3 --- /dev/null +++ b/dist/assets/examples/ko/16_Dom/11_Capture.js @@ -0,0 +1,25 @@ +/* + * @name 실시간 비디오 + * @frame 710,240 + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 비디오 파일이 필요하고, + * p5.dom 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.



+ * 웹캠을 통해 보여지는 실시간 비디오 화면을 캔버스 위에 그릴 수 있습니다. + * 반전 효과 필터도 적용할 수 있습니다. + * 실시간 비디오 화면은 기본값으로 캔버스 위에 나타납니다. + * 아래의 코드 중 capture.hide()의 주석 처리(//)를 해제하면 이 실시간 비디오 화면을 숨길 수 있습니다. + */ +let capture; + +function setup() { + createCanvas(390, 240); + capture = createCapture(VIDEO); + capture.size(320, 240); + //capture.hide(); +} + +function draw() { + background(255); + image(capture, 0, 0, 320, 240); + filter('INVERT'); +} diff --git a/dist/assets/examples/ko/16_Dom/12_Drop.js b/dist/assets/examples/ko/16_Dom/12_Drop.js new file mode 100644 index 0000000000..c3541c6d1f --- /dev/null +++ b/dist/assets/examples/ko/16_Dom/12_Drop.js @@ -0,0 +1,36 @@ +/* + * @name 드롭 기능 + * @description 여러분의 로컬 프로젝트에서 이 예제를 실행하려면, + * p5.dom 라이브러리 + * 를 추가하면 됩니다.

+ * 이미지 파일을 캔버스에 드래그 & 드롭하여 화면에 보이는지 확인해보세요. + */ + +function setup() { + // 캔버스 생성 + const c = createCanvas(710, 400); + background(100); + // 캔버스에 이미지 파일이 드롭될 때 이벤트 추가 + c.drop(gotFile); +} + +function draw() { + fill(255); + noStroke(); + textSize(24); + textAlign(CENTER); + text('Drag an image file onto the canvas.', width / 2, height / 2); + noLoop(); +} + +function gotFile(file) { + // 드롭된 파일이 이미지 파일이라면, + if (file.type === 'image') { + // 이미지 DOM 요소를 생성하되, 화면엔 띄우지 않는다. + const img = createImg(file.data).hide(); + // 이미지를 캔버스에 그린다. + image(img, 0, 0, width, height); + } else { + console.log('Not an image file!'); + } +} diff --git a/dist/assets/examples/ko/16_Dom/13_DOM_Form_Elements.js b/dist/assets/examples/ko/16_Dom/13_DOM_Form_Elements.js new file mode 100644 index 0000000000..d83dfdc13e --- /dev/null +++ b/dist/assets/examples/ko/16_Dom/13_DOM_Form_Elements.js @@ -0,0 +1,152 @@ +/* + * @name DOM Form Elements + * @frame 600,400 + * @description contributed by + Prof WM Harris, How to use p5 DOM form elements to create a slider, +button, checkbox, radio group, select menu, and entry field.
+Functions are created that include: the canvas +setup, checkbox creation with text, text box with text that projects +typed text onto canvas, slider with button, three selections which +project a rectangle in different areas on the canvas depending on +selection, and a drop down menu with font change. +*/ + +/* global variables */ +//p5 DOM form elements +let slider1; +let button1; +let checkbox1; +let radio1; +let select1; +let entry1; + +function setup() { + createCanvas(200, 200); + background("beige"); + + checkbox1 = createCheckbox("Check me"); + + createP(); //spacer with

tag + + createSpan("What's your name? "); //label for entry1 + // createInput([value], [type]) + // type: "text" (default), "number", + // "date", "password", "email", etc. + entry1 = createInput(); + //If text in the entry field changes, call + //the entryCallback function. + entry1.changed(entryCallback); + + createP(); //spacer with

tag + + //createSlider(min, max, [value], [step]) + slider1 = createSlider(10, 200); + + button1 = createButton("Press me"); //, "pressed"); + //Assign callback fcn for button1 + //when user clicks mouse on it + button1.mouseClicked(button1Clicked); + + createP(); //spacer with

tag + + radio1 = createRadio(); + + //.option([value], [contentLabel]) + //If 1 param, it's both content AND + //value. Values treated as strings. + radio1.option(1, "cranberries"); + radio1.option(2, "almonds"); + radio1.option(3, "gouda"); + + radio1.value("1"); //set init value + + createP(); //spacer with

tag + + select1 = createSelect(); + //.option([contentValue],[value]) + //If 1 param, it's both content AND + //value. Values treated as strings. + select1.option("Sans-serif"); + select1.option("Serif"); + select1.option("Fantasy"); + //If changed, call select1Changed + select1.changed(select1Changed); +} + +function draw() { + //get value from slider 1 + let gray = slider1.value(); + fill(gray); + + //If mouse in corner, turn on checkbox1 + if ((mouseX < width / 3) && + (mouseY < height / 3)) { + checkbox1.checked(true); + } + //Is checkbox1 checked? Say so. + if (checkbox1.checked()) { + text("CHECKED", 20, 40); + } + + switch (radio1.value()) { + //radio value is always a string + case "1": + rect(0, 0, width, 50); + break; + case "2": + rect(0, 70, width, 50); + break; + case "3": + rect(0, 140, width, 50); + break; + } +} + +//callback fcn for button1 +function button1Clicked() { + //reset slider value to 200 + slider1.value(200); +} + + +//callback fcn for select1 +function select1Changed() { + switch (select1.value()) { + case "Sans-serif": + textFont("sans-serif"); + break; + case "Serif": + textFont("serif"); + break; + case "Fantasy": + textFont("fantasy"); + break; + } +} + +//callback function for entry1 +function entryCallback() { + for (let i = 0; i < 25; i++) { + text(entry1.value(), random(width), + random(height)); + } + +} + +function mouseClicked() { + console.log("button1?", button1.value()); + console.log("checkbox1?", checkbox1.value()); + //Update .value of either? No visible change + //to a button or checkbox + checkbox1.value("Check again"); + button1.value("clicked?"); +} + +function keyTyped() { + switch (key) { + case "r": + //move slider1 value to 100 + slider1.value(100); + break; + } +} diff --git a/dist/assets/examples/ko/17_Drawing/00_Continuous_Lines.js b/dist/assets/examples/ko/17_Drawing/00_Continuous_Lines.js new file mode 100644 index 0000000000..aa89265d1d --- /dev/null +++ b/dist/assets/examples/ko/17_Drawing/00_Continuous_Lines.js @@ -0,0 +1,15 @@ +/* + * @name 연속된 선 + * @description 마우스를 클릭하고 드래그하여 선을 그려보세요. + */ +function setup() { + createCanvas(710, 400); + background(102);ㅌ +} + +function draw() { + stroke(255); + if (mouseIsPressed === true) { + line(mouseX, mouseY, pmouseX, pmouseY); + } +} diff --git a/dist/assets/examples/ko/17_Drawing/01_Pattern.js b/dist/assets/examples/ko/17_Drawing/01_Pattern.js new file mode 100644 index 0000000000..c1db5a64fd --- /dev/null +++ b/dist/assets/examples/ko/17_Drawing/01_Pattern.js @@ -0,0 +1,26 @@ +/* + * @name 패턴 + * @description 캔버스 위로 마우스를 움직여 드로잉할 수 있는 소프트웨어 툴입니다. + * 이 때, 드로잉은 마우스의 속도에 반응합니다. + */ +function setup() { + createCanvas(710, 400); + background(102); +} + +function draw() { + // variableEllipse()메소드를 호출하고, 여기에 + // 마우스의 현재 및 이전 위치를 담은 매개 변수를 보냅니다. + variableEllipse(mouseX, mouseY, pmouseX, pmouseY); +} + +// 이 간단한 메소드 variableEllipse()는 이 프로그램을 위해 +// 작성되었습니다. 메소드는 마우스의 속도를 계산하는데, +// 마우스가 천천히 움직이면 작은 타원을, +// 마우스가 빨리 움직이면 큰 타원을 그립니다. + +function variableEllipse(x, y, px, py) { + let speed = abs(x - px) + abs(y - py); + stroke(speed); + ellipse(x, y, speed, speed); +} diff --git a/dist/assets/examples/ko/17_Drawing/02_Pulses.js b/dist/assets/examples/ko/17_Drawing/02_Pulses.js new file mode 100644 index 0000000000..3b2e77f82d --- /dev/null +++ b/dist/assets/examples/ko/17_Drawing/02_Pulses.js @@ -0,0 +1,30 @@ +/* + * @name 율동 + * @description 드로잉 스포트웨어는 특정 리듬이나, 그려진 제스쳐로부터 독립된 규칙을 따를 수 있습니다. + * 이 예제의 경우, 협업 드로잉으로도 볼 수 있습니다. + * 사용자가 이미지의 일부를 조정하면 소프트웨어가 다른 일부를 조정하는 식입니다. + */ +let angle = 0; + +function setup() { + createCanvas(710, 400); + background(102); + noStroke(); + fill(0, 102); +} + +function draw() { + // 마우스가 클릭될 때만 그리기 + if (mouseIsPressed === true) { + angle += 5; + let val = cos(radians(angle)) * 12.0; + for (let a = 0; a < 360; a += 75) { + let xoff = cos(radians(a)) * val; + let yoff = sin(radians(a)) * val; + fill(0); + ellipse(mouseX + xoff, mouseY + yoff, val, val); + } + fill(255); + ellipse(mouseX, mouseY, 2, 2); + } +} diff --git a/dist/assets/examples/ko/18_Transform/00_Translate.js b/dist/assets/examples/ko/18_Transform/00_Translate.js new file mode 100644 index 0000000000..e535237377 --- /dev/null +++ b/dist/assets/examples/ko/18_Transform/00_Translate.js @@ -0,0 +1,39 @@ +/* + * @name 위치 이동(Translate) + * @description translate() 함수는 객체를 화면 내 어떤 위치로든 이동하게 합니다. + * 그 첫 번째 매개변수는 x축의 오프셋(offset)을, + * 두 번째 매개변수는 y축의 오프셋을 지정합니다. + * 이 예제는 이러한 이동들이 축적되는 것을 보여줍니다. + */ + +let x = 0; +let y = 0; +let dim = 80.0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(102); + // x값을 증가시켜 움직이게 만들기 + x = x + 0.8; + // 도형이 캔버스 밖으로 나가면, 위치를 리셋한다. + if (x > width + dim) { + x = -dim; + } + + // rect 명령어는 원점을 중심점으로 삼는 도형을 그리지만, + // translate(이동)은 이를 새로운 x와 y 위치로 옮깁니다. + translate(x, height / 2 - dim / 2); + fill(255); + rect(-dim / 2, -dim / 2, dim, dim); + + // translate(이동)은 축적됩니다. 이 rect가 다른 rect와 + // 동일한 x축값 매개변수를 가졌음에도 + // 두 배로 빠르게 움직이는 걸 볼 수 있습니다. + translate(x, dim); + fill(0); + rect(-dim / 2, -dim / 2, dim, dim); +} diff --git a/dist/assets/examples/ko/18_Transform/01_Scale.js b/dist/assets/examples/ko/18_Transform/01_Scale.js new file mode 100644 index 0000000000..0bfa5be461 --- /dev/null +++ b/dist/assets/examples/ko/18_Transform/01_Scale.js @@ -0,0 +1,45 @@ +/* + * @name 크기 조정(Scale) + * @description scale()함수의 매개변수는 10진수 백분율로 표현됩니다. + * 예를 들어, scale(2.0) 메소드 호출은 도형의 차원을 200 퍼센트 증가시킵니다. + * 오브젝트의 크기는 항상 원점을 기준으로 조정됩니다. + * 이 예제는 그러한 변형이 누적되는 양상과, 순서에 따라 scale과 translate이 + * 상호작용하는 것을 보여줍니다. + */ + +let a = 0.0; +let s = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + // 드로잉 시작 기본 위치인 상단 좌측 코너가 아닌, + // 화면 중앙에서 직사각형이 그려지도록 합니다. + rectMode(CENTER); +} + +function draw() { + background(102); + + // 'a'를 천천히 증가시킨 다음 'a'의 코사인을 찾아, + // 's'에 부드럽고 주기적인 애니메이션 효과를 줍니다. + a = a + 0.04; + s = cos(a) * 2; + + // 사각형의 위치를 원점에서 캔버스 중간으로 이동(translate)한 다음, + // 's'로 크기를 조정합니다. + translate(width / 2, height / 2); + scale(s); + fill(51); + rect(0, 0, 50, 50); + + // 위치 이동과 크기 조정은 누적됩니다. + // 따라서 이동된 두 번째 사각형은 첫 번째 사각형보다 + // 조금 더 오른쪽으로 이동하게 되고, 그 크기는 두배가 됩니다. + // 한편, 코사인은 's'가 음수와 양수를 오가도록 하는데, + // 이에 따라 사각형이 왼쪽과 오른쪽을 순환하게 됩니다. + translate(75, 0); + fill(255); + scale(s); + rect(0, 0, 50, 50); +} diff --git a/dist/assets/examples/ko/18_Transform/02_Rotate.js b/dist/assets/examples/ko/18_Transform/02_Rotate.js new file mode 100644 index 0000000000..d25d8de8f9 --- /dev/null +++ b/dist/assets/examples/ko/18_Transform/02_Rotate.js @@ -0,0 +1,42 @@ +/* + * @name 회전(Rotate) + * @description Z축을 기준으로 사각형 회전시킵니다. + * 원하는 결과를 얻기 위해, 0부터 PI*2(즉, TWO_PI, 약 6.28)에 해당하는, + * rotate 함수 속 각도 매개 변수를 보냅니다. + * 각도를 도(0-360) 단위로 표현하고 싶다면, radians() 메소드를 통해 변환하면 됩니다. + * 예: scale(radians(90))은 선언문 scale(PI/2)과 동일합니다. + * 이 예제에서, 모든 짝수 초마다 jitter(떨림)가 회전에 더해집니다. + * 홀수 초에는 마지막 jitter값으로 결정된 속도에 따라 + * 시계 방향 또는 반시계 방향으로 회전합니다. + */ + +let angle = 0.0; +let jitter = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255); + //중심으로부터 사각형을 그리고, + //사각형이 중심을 기준으로 회전하도록 만들기 + rectMode(CENTER); +} + +function draw() { + background(51); + + // 짝수 초(0, 2, 4, 6...)동안 회전에 + // jitter(떨림) 더하기 + if (second() % 2 === 0) { + jitter = random(-0.1, 0.1); + } + // 가장 마지막 jitter값을 사용해 각도값 증가시키기 + angle = angle + jitter; + // 떨림이 없는 경우, 코싸인을 사용해 부드러운 시계 방향 및 반시계 방향 모션 받기 + let c = cos(angle); + //도형을 캔버스의 중앙으로 이동시키기 + translate(width / 2, height / 2); + //최종 회전 적용하기 + rotate(c); + rect(0, 0, 180, 180); +} diff --git a/dist/assets/examples/ko/18_Transform/03_Arm.js b/dist/assets/examples/ko/18_Transform/03_Arm.js new file mode 100644 index 0000000000..b62f1dac02 --- /dev/null +++ b/dist/assets/examples/ko/18_Transform/03_Arm.js @@ -0,0 +1,47 @@ +/* + * @name 팔모양 + * @description 이 예제는 변형 행렬을 사용하여 팔모양을 만듭니다. + * 각 선분의 각도는 mouseX 및 mouseY 위치로 조정됩니다. + * 첫 번째 선분에 적용된 변형은 두 번째 선분에도 적용됩니다. + * 두 선분 모두 동일한 push() 및 pop() 행렬 그룹에 속하기 때문입니다. + */ + +let x, y; +let angle1 = 0.0; +let angle2 = 0.0; +let segLength = 100; + +function setup() { + createCanvas(720, 400); + strokeWeight(30); + + // 반투명한 선 그리기 + stroke(255, 160); + + // 팔의 "어깨" 위치를 캔버스 중앙에 위치시키기 + x = width * 0.5; + y = height * 0.5; +} + +function draw() { + background(0); + + // 마우스 위치에 따라 선분의 각도 바꾸기 + angle1 = (mouseX / float(width) - 0.5) * -TWO_PI; + angle2 = (mouseY / float(height) - 0.5) * PI; + + // push와 pop을 사용해 변형을 담기 + // 사용자 정의 함수를 사용해 선분을 그려도 + // 변형 내용이 축적되는 걸 볼 수 있습니다. + push(); + segment(x, y, angle1); + segment(segLength, 0, angle2); + pop(); +} + +// 선분을 그리기 위한 사용자 정의 함수 +function segment(x, y, a) { + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); +} diff --git a/dist/assets/examples/ko/19_Typography/00_Letters.js b/dist/assets/examples/ko/19_Typography/00_Letters.js new file mode 100644 index 0000000000..b965b233bc --- /dev/null +++ b/dist/assets/examples/ko/19_Typography/00_Letters.js @@ -0,0 +1,64 @@ +/* + * @name 글자 + * @description 폰트를 불러와 글자 속성을 정하면, 화면에 글자를 그릴 수 있습니다. + * 이 예제에서는 for 반복문과 유니코드 참조 번호를 사용하여, + * 그리드 속 글자들로 캔버스를 자동으로 채웁니다. + * 이 중, 모음들에만 특정 색상이 부여됩니다. + */ +let font, + fontsize = 32; + +function preload() { + // setup()과 draw()를 호출하기에 앞서, + // assets 파일 경로에 .ttf 또는 .otf 폰트가 저장 및 로드되었는지 확인하세요. + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // 텍스트 속성 설정 + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // 글자 간, 그리고 글자와 좌측 및 상단 간의 margin(여백) 설정 + let gap = 52; + let margin = 10; + translate(margin * 4, margin * 4); + + // 원하는 글자에서 시작하도록 카운터 설정 + // 이 예제에서는 유니코드 35, 즉 # 기호입니다. + let counter = 35; + + // 캔버스에 공간이 확보되는 한 반복하기 + for (let y = 0; y < height - gap; y += gap) { + for (let x = 0; x < width - gap; x += gap) { + // 카운터를 사용해 유니코드 번호로 개별 글자를 검색 + let letter = char(counter); + + // 모음과 기타 글자들에 각각 다른 색상 더하기 + if ( + letter === 'A' || + letter === 'E' || + letter === 'I' || + letter === 'O' || + letter === 'U' + ) { + fill('#ed225d'); + } else { + fill(255); + } + + // 화면에 글자 그리기 + text(letter, x, y); + + // 카운터 증가시키기 + counter++; + } + } +} diff --git a/dist/assets/examples/ko/19_Typography/01_Words.js b/dist/assets/examples/ko/19_Typography/01_Words.js new file mode 100644 index 0000000000..725cb82229 --- /dev/null +++ b/dist/assets/examples/ko/19_Typography/01_Words.js @@ -0,0 +1,58 @@ +/* + * @name 단어 + * @description text()함수는 화면에 단어를 쓸 때 사용됩니다. + * textAlign()함수로 단어들을 왼쪽, 가운데, 또는 오른쪽 정렬할 수 있으며, + * 도형과 마찬가지로, 단어들 역시 fill()로 그 색을 채울 수 있습니다. + */ +let font, + fontsize = 40; + +function preload() { + // setup()과 draw()를 호출하기에 앞서, + // assets 파일 경로에 .ttf 또는 .otf 폰트가 저장 및 로드되었는지 확인하세요. + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // 텍스트 속성 설정 + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // 텍스트를 오른쪽 정렬하고 + // 캔버스의 좌측 1/3 영역에서 drawWords() 실행하기 + textAlign(RIGHT); + drawWords(width * 0.25); + + // 텍스트를 가운데 정렬하고 + // 캔버스의 가운데 영역에서 drawWords() 실행하기 + textAlign(CENTER); + drawWords(width * 0.5); + + // 텍스트를 왼쪽 정렬하고 + // 캔버스의 우측 1/3 영역에서 drawWords() 실행하기 + textAlign(LEFT); + drawWords(width * 0.75); +} + +function drawWords(x) { + // text() 함수에는 세 개의 매개 변수가 필요합니다: + // 그려질 텍스트, 가로 위치, 그리고 세로 위치 + fill(0); + text('ichi', x, 80); + + fill(65); + text('ni', x, 150); + + fill(190); + text('san', x, 220); + + fill(255); + text('shi', x, 290); +} diff --git a/dist/assets/examples/ko/19_Typography/02_Text_Rotation.js b/dist/assets/examples/ko/19_Typography/02_Text_Rotation.js new file mode 100644 index 0000000000..5d6904eafe --- /dev/null +++ b/dist/assets/examples/ko/19_Typography/02_Text_Rotation.js @@ -0,0 +1,62 @@ +/* + * @name 텍스트 회전 + * @description 스크린에 글자를 그린 후, 다양한 각도로 회전시킵니다. + * (https://processing.org/examples/textrotation.html에서 옮김) + */ + +let font, +fontsize = 32; + +let angleRotate = 0.0; + +function setup() { + createCanvas(710, 400); + background(0); + + // setup()함수와 draw()함수를 부르기 전에 .ttf 또는 .otf 파일이 'assets' 주소에 + // 있을 것을 확안합니다 + font = loadFont('assets/SourceSansPro-Regular.otf'); + + // 텍스트의 특징을 정합니다 + textFont(font); +} + +function draw() { + background(0); + + strokeWeight(1); + stroke(153); + + push(); + let angle1 = radians(45); + translate(100, 180); + rotate(angle1); + // 스크린에 글짜를 그립니다 + text("45 DEGREES", 0, 0); + line(0, 0, 150, 0); + pop(); + + push(); + let angle2 = radians(270); + translate(200, 180); + rotate(angle2); + // 스크린에 글짜를 그립니다 + text("270 DEGREES", 0, 0); + line(0, 0, 150, 0); + pop(); + + push(); + translate(440, 180); + rotate(radians(angleRotate)); + text(int(angleRotate) % 360 + " DEGREES ", 0, 0); + line(0, 0, 150, 0); + pop(); + + angleRotate += 0.25; + + stroke(255, 0, 0); + strokeWeight(4); + point(100, 180); + point(200, 180); + point(440, 180); +} diff --git a/dist/assets/examples/ko/20_3D/00_geometries.js b/dist/assets/examples/ko/20_3D/00_geometries.js new file mode 100644 index 0000000000..59a9b03459 --- /dev/null +++ b/dist/assets/examples/ko/20_3D/00_geometries.js @@ -0,0 +1,60 @@ +/* + * @name 기하 + * @description 현재 p5에는 여섯 개의 3D 기초 조형이 있습니다. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + + translate(-240, -100, 0); + normalMaterial(); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + plane(70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + box(70, 70, 70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cylinder(70, 70); + pop(); + + translate(-240 * 2, 200, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cone(70, 70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + torus(70, 20); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + sphere(70); + pop(); +} diff --git a/dist/assets/examples/ko/20_3D/01_sine_cosine_in_3D.js b/dist/assets/examples/ko/20_3D/01_sine_cosine_in_3D.js new file mode 100644 index 0000000000..832ea9b8ff --- /dev/null +++ b/dist/assets/examples/ko/20_3D/01_sine_cosine_in_3D.js @@ -0,0 +1,28 @@ +/* + * @name 3D속 사인 코사인 + * @description 사인, 코사인, 그리고 push / pop 함수는 3D에도 적용됩니다. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + rotateY(frameCount * 0.01); + + for (let j = 0; j < 5; j++) { + push(); + for (let i = 0; i < 80; i++) { + translate( + sin(frameCount * 0.001 + j) * 100, + sin(frameCount * 0.001 + j) * 100, + i * 0.1 + ); + rotateZ(frameCount * 0.002); + push(); + sphere(8, 6, 4); + pop(); + } + pop(); + } +} diff --git a/dist/assets/examples/ko/20_3D/02_multiple_lights.js b/dist/assets/examples/ko/20_3D/02_multiple_lights.js new file mode 100644 index 0000000000..1491c79a43 --- /dev/null +++ b/dist/assets/examples/ko/20_3D/02_multiple_lights.js @@ -0,0 +1,30 @@ +/* + * @name 복수의 조명들 + * @description 한 스케치 위에 여러 종류의 조명을 사용할 수 있습니다. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(50); + directionalLight(255, 0, 0, 0.25, 0.25, 0); + pointLight(0, 0, 255, locX, locY, 250); + + push(); + translate(-width / 4, 0, 0); + rotateZ(frameCount * 0.02); + rotateX(frameCount * 0.02); + specularMaterial(250); + box(100, 100, 100); + pop(); + + translate(width / 4, 0, 0); + ambientMaterial(250); + sphere(120, 64); +} diff --git a/dist/assets/examples/ko/20_3D/03_materials.js b/dist/assets/examples/ko/20_3D/03_materials.js new file mode 100644 index 0000000000..571219eee0 --- /dev/null +++ b/dist/assets/examples/ko/20_3D/03_materials.js @@ -0,0 +1,65 @@ +/* + * @name 재질(Materials) + * @description 지원되는 재질은 다섯 가지 입니다. + * 각각은 조명에 다르게 반응합니다. + * 마우스를 움직여 빛의 위치를 바꿔보세요. + */ +let img; +function setup() { + createCanvas(710, 400, WEBGL); + img = loadImage('assets/cat.jpg'); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(60, 60, 60); + pointLight(255, 255, 255, locX, locY, 100); + + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + texture(img); + box(80); + pop(); + + push(); + translate(-width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + fill(250, 0, 0); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + normalMaterial(); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(-width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + ambientMaterial(250); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + specularMaterial(250); + torus(80, 20, 64, 64); + pop(); +} diff --git a/dist/assets/examples/ko/20_3D/04_textures.js b/dist/assets/examples/ko/20_3D/04_textures.js new file mode 100644 index 0000000000..54aafba4a6 --- /dev/null +++ b/dist/assets/examples/ko/20_3D/04_textures.js @@ -0,0 +1,40 @@ +/* + * @name 텍스처 + * @description 이미지와 비디오가 텍스처를 지원합니다. + */ +// 비디오 출처: https://vimeo.com/90312869 +let img; +let vid; +let theta = 0; + +function setup() { + createCanvas(710, 400, WEBGL); + + img = loadImage('assets/cat.jpg'); + vid = createVideo(['assets/360video_256crop_v2.mp4']); + vid.elt.muted = true; + vid.loop(); + vid.hide(); +} + +function draw() { + background(250); + translate(-220, 0, 0); + push(); + rotateZ(theta * mouseX * 0.001); + rotateX(theta * mouseX * 0.001); + rotateY(theta * mouseX * 0.001); + //이미지를 텍스처로 전달하기 + texture(vid); + sphere(150); + pop(); + translate(440, 0, 0); + push(); + rotateZ(theta * 0.1); + rotateX(theta * 0.1); + rotateY(theta * 0.1); + texture(img); + box(100, 100, 100); + pop(); + theta += 0.05; +} diff --git a/dist/assets/examples/ko/20_3D/05_ray_casting.js b/dist/assets/examples/ko/20_3D/05_ray_casting.js new file mode 100644 index 0000000000..ac4fc40e06 --- /dev/null +++ b/dist/assets/examples/ko/20_3D/05_ray_casting.js @@ -0,0 +1,100 @@ +/* + * @name 레이 캐스팅 + * @description 예제 원본: 조나단 왓슨(Jonathan Watson) 제작 + *

광선 투사(ray casting) 기능으로 3D 공간 속 마우스의 위치를 감지합니다. + */ +const objects = []; +let eyeZ; + +function setup() { + createCanvas(710, 400, WEBGL); + + eyeZ = height / 2 / tan((30 * PI) / 180); // 카메라가 원점에서 떨어진 기본 위치 + + objects.push(new IntersectPlane(1, 0, 0, -100, 0, 0)); // 왼쪽 벽 + objects.push(new IntersectPlane(1, 0, 0, 100, 0, 0)); // 오른쪽 벽 + objects.push(new IntersectPlane(0, 1, 0, 0, -100, 0)); // 바닥 + objects.push(new IntersectPlane(0, 1, 0, 0, 100, 0)); // 천장 + objects.push(new IntersectPlane(0, 0, 1, 0, 0, 0)); // 뒷면 벽 + + noStroke(); + ambientMaterial(250); +} + +function draw() { + background(0); + + // 조명들 + pointLight(255, 255, 255, 0, 0, 400); + ambientLight(244, 122, 158); + + // 왼쪽 벽 + push(); + translate(-100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // 오른쪽 벽 + push(); + translate(100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // 바닥 + push(); + translate(0, 100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + // 천장 + push(); + translate(0, -100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + plane(200, 200); // 뒷면 벽 + + const x = mouseX - width / 2; + const y = mouseY - height / 2; + + const Q = createVector(0, 0, eyeZ); // 광선 위의 점과 카메라의 기본 위치 + const v = createVector(x, y, -eyeZ); // 광선의 방향 벡터 + + let intersect; // 광선과 벽면의 교차점 + let closestLambda = eyeZ * 10; // 거리 그리기 + + for (let x = 0; x < objects.length; x += 1) { + let object = objects[x]; + let lambda = object.getLambda(Q, v); // 광선과 객체 간 교차점의 람다값 + + if (lambda < closestLambda && lambda > 0) { + // 광선과 객체의 교차점 위치 찾기 + intersect = p5.Vector.add(Q, p5.Vector.mult(v, lambda)); + closestLambda = lambda; + } + } + + // 커서 + push(); + translate(intersect); + fill(237, 34, 93); + sphere(10); + pop(); +} + +// 무한대로 확장하는 벽면 생성을 위한 클래스 +class IntersectPlane { + constructor(n1, n2, n3, p1, p2, p3) { + this.normal = createVector(n1, n2, n3); // 면의 기본 벡터 + this.point = createVector(p1, p2, p3); // 면 위의 점 + this.d = this.point.dot(this.normal); + } + + getLambda(Q, v) { + return (-this.d - this.normal.dot(Q)) / this.normal.dot(v); + } +} diff --git a/dist/assets/examples/ko/20_3D/07_orbit_control.js b/dist/assets/examples/ko/20_3D/07_orbit_control.js new file mode 100644 index 0000000000..7c45043100 --- /dev/null +++ b/dist/assets/examples/ko/20_3D/07_orbit_control.js @@ -0,0 +1,36 @@ +/* + * @name 궤도 제어 + * @description 궤도 제어(Orbit Control)를 사용해 월드를 드래그하거나 움직일 수 있습니다. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + let radius = width * 1.5; + + //월드를 움직이도록 드래그 + orbitControl(); + + normalMaterial(); + translate(0, 0, -600); + for (let i = 0; i <= 12; i++) { + for (let j = 0; j <= 12; j++) { + push(); + let a = (j / 12) * PI; + let b = (i / 12) * PI; + translate( + sin(2 * a) * radius * sin(b), + (cos(b) * radius) / 2, + cos(2 * a) * radius * sin(b) + ); + if (j % 2 === 0) { + cone(30, 30); + } else { + box(30, 30, 30); + } + pop(); + } + } +} diff --git a/dist/assets/examples/ko/20_3D/08_basic_shader.js b/dist/assets/examples/ko/20_3D/08_basic_shader.js new file mode 100644 index 0000000000..f335a266f8 --- /dev/null +++ b/dist/assets/examples/ko/20_3D/08_basic_shader.js @@ -0,0 +1,27 @@ +/* + * @name 셰이더 기초 + * @description p5.js에 셰이더를 불러오는 방법을 설명하는 기본 예제입니다. + *
p5.js로 셰이더를 사용하는 방법에 대해 더 알고 싶다면: p5.js Shaders + */ + +// 이 변수는 셰이더 객체를 담습니다. +let theShader; + +function preload(){ + // 셰이더 불러오기 + theShader = loadShader('assets/basic.vert', 'assets/basic.frag'); +} + +function setup() { + // 셰이더를 작동하기 위해 WEBGL 모드가 필요합니다. + createCanvas(710, 400, WEBGL); + noStroke(); +} + +function draw() { + // shader()는 활성화 셰이더를 theShader로 설정합니다. + shader(theShader); + + // rect()함수로 화면에 기하 추가하기 + rect(0,0,width, height); +} diff --git a/dist/assets/examples/ko/20_3D/09_shader_as_a_texture.js b/dist/assets/examples/ko/20_3D/09_shader_as_a_texture.js new file mode 100644 index 0000000000..3e12f552c7 --- /dev/null +++ b/dist/assets/examples/ko/20_3D/09_shader_as_a_texture.js @@ -0,0 +1,68 @@ +/* + * @name 셰이더로 텍스처 만들기 + * @description 셰이더는 2D/3D 도형에 텍스처로서 적용될 수 있습니다. + *
p5.js로 셰이더를 사용하는 방법에 대해 더 알고 싶다면: p5.js Shaders + */ + + // 이 변수는 셰이더 객체를 담습니다. + let theShader; + // 이 변수는 createGraphics 레이어를 담습니다. + let shaderTexture; + + let theta = 0; + + let x; + let y; + let outsideRadius = 200; + let insideRadius = 100; + + function preload(){ + // 셰이더 불러오기 + theShader = loadShader('assets/texture.vert','assets/texture.frag'); + } + + function setup() { + // 셰이더를 작동하기 위해 WEBGL 모드가 필요합니다. + createCanvas(710, 400, WEBGL); + noStroke(); + + // createGraphics 레이어 초기화하기 + shaderTexture = createGraphics(710, 400, WEBGL); + + // createGraphics 레이어의 테두리 없애기 + shaderTexture.noStroke(); + + x = -50; + y = 0; + } + + function draw() { + + // theShader를 활성화 셰이더로 설정하는 대신, createGraphics 레이어로 보냅니다. + shaderTexture.shader(theShader); + + // setUniform()를 사용하여 유니폼을 theShader로 보냅니다. + theShader.setUniform("resolution", [width, height]); + theShader.setUniform("time", millis() / 1000.0); + theShader.setUniform("mouse", [mouseX, map(mouseY, 0, height, height, 0)]); + + // shaderTexture 레이어 위 기하 형상의 렌더링을 위한 설정 + shaderTexture.rect(0,0,width,height); + + background(255); + + // 셰이더를 텍스쳐로서 설정하기 + texture(shaderTexture); + + translate(-150, 0, 0); + push(); + rotateZ(theta * mouseX * 0.0001); + rotateX(theta * mouseX * 0.0001); + rotateY(theta * mouseX * 0.0001); + theta += 0.05; + sphere(125); + pop(); + + // 5번째 매개변수를 3D 상의 부드러운 모서리 처리를 위한 값으로 보내기 + ellipse(260,0,200,200,100); + } diff --git a/dist/assets/examples/ko/20_3D/10_passing_shader_uniforms.js b/dist/assets/examples/ko/20_3D/10_passing_shader_uniforms.js new file mode 100644 index 0000000000..3b274aef49 --- /dev/null +++ b/dist/assets/examples/ko/20_3D/10_passing_shader_uniforms.js @@ -0,0 +1,34 @@ +/* + * @name 셰이더 유니폼 + * @description 유니폼(Uniform)을 통해 p5에서 셰이더로 정보를 전송합니다. + *
p5.js로 셰이더를 사용하는 방법에 대해 더 알고 싶다면: p5.js Shaders + */ + + // 이 변수는 셰이더 객체를 담습니다. + let theShader; + + function preload(){ + // 셰이더 불러오기 + theShader = loadShader('assets/uniforms.vert', 'assets/uniforms.frag'); + } + + function setup() { + // 셰이더를 작동하기 위해 WEBGL 모드가 필요합니다. + createCanvas(710, 400, WEBGL); + noStroke(); + } + + function draw() { + // shader()는 활성화 셰이더를 theShader로 설정합니다. + shader(theShader); + + // 마우스 + 데이터 수정 시간을 보내기에 앞서, + // 해상도, 마우스, 시간을 셰이더에 보냅니다. + // 이렇게 하면 셰이더에서 사용하기가 더 쉬워집니다. + theShader.setUniform('resolution', [width, height]); + theShader.setUniform('mouse', map(mouseX, 0, width, 0, 7)); + theShader.setUniform('time', frameCount * 0.01); + + // rect()함수로 화면에 기하 형상 추가하기 + rect(0,0,width, height); + } diff --git a/dist/assets/examples/ko/20_3D/11_shader_using_webcam.js b/dist/assets/examples/ko/20_3D/11_shader_using_webcam.js new file mode 100644 index 0000000000..0763b93fac --- /dev/null +++ b/dist/assets/examples/ko/20_3D/11_shader_using_webcam.js @@ -0,0 +1,37 @@ +/* + * @name 웹캠을 사용한 셰이더 + * @description 웹캠을 텍스처로서 셰이더에 보낼 수 있습니다. + *
p5.js로 셰이더를 사용하는 방법에 대해 더 알고 싶다면: p5.js Shaders + */ + + // 이 변수는 셰이더 객체를 담습니다. + let theShader; + // 이 변수는 웹캠 비디오를 담습니다. + let cam; + + function preload(){ + // 셰이더 불러오기 + theShader = loadShader('assets/webcam.vert', 'assets/webcam.frag'); + } + + function setup() { + // 셰이더 작동을 위해 WEBGL 모드가 필요합니다. + createCanvas(710, 400, WEBGL); + noStroke(); + + cam = createCapture(VIDEO); + cam.size(710, 400); + + cam.hide(); + } + + function draw() { + // shader()는 활성화 셰이더를 theShader로 설정합니다. + shader(theShader); + + // cam을 텍스처로 보내기 + theShader.setUniform('tex0', cam); + + // rect()함수로 화면에 기하 추가하기 + rect(0,0,width,height); + } diff --git a/dist/assets/examples/ko/21_Input/00_Clock.js b/dist/assets/examples/ko/21_Input/00_Clock.js new file mode 100644 index 0000000000..7d9b53c902 --- /dev/null +++ b/dist/assets/examples/ko/21_Input/00_Clock.js @@ -0,0 +1,62 @@ +/* + * @name 시계 + * @description second(), minute(), 그리고 hour()함수를 사용하여 + * 현재 시간을 읽어올 수 있습니다. + * 이 예제에서는 sin()과 cos()값이 시침, 분침, 초침의 위치를 정합니다. + */ +let cx, cy; +let secondsRadius; +let minutesRadius; +let hoursRadius; +let clockDiameter; + +function setup() { + createCanvas(720, 400); + stroke(255); + + let radius = min(width, height) / 2; + secondsRadius = radius * 0.71; + minutesRadius = radius * 0.6; + hoursRadius = radius * 0.5; + clockDiameter = radius * 1.7; + + cx = width / 2; + cy = height / 2; +} + +function draw() { + background(230); + + // 시계 배경 그리기 + noStroke(); + fill(244, 122, 158); + ellipse(cx, cy, clockDiameter + 25, clockDiameter + 25); + fill(237, 34, 93); + ellipse(cx, cy, clockDiameter, clockDiameter); + + // sin()과 cos()의 각도는 3시 정각에서 시작; + // HALF_PI를 뺄셈하여 상단에서부터 시작하도록 설정 + let s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI; + let m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; + let h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI; + + // 시계침들 그리기 + stroke(255); + strokeWeight(1); + line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius); + strokeWeight(2); + line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius); + strokeWeight(4); + line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius); + + // 분침 그리기 + strokeWeight(2); + beginShape(POINTS); + for (let a = 0; a < 360; a += 6) { + let angle = radians(a); + let x = cx + cos(angle) * secondsRadius; + let y = cy + sin(angle) * secondsRadius; + vertex(x, y); + } + endShape(); +} diff --git a/dist/assets/examples/ko/21_Input/01_Constrain.js b/dist/assets/examples/ko/21_Input/01_Constrain.js new file mode 100644 index 0000000000..5aff15a043 --- /dev/null +++ b/dist/assets/examples/ko/21_Input/01_Constrain.js @@ -0,0 +1,36 @@ +/* + * @name 제한 + * @description 화면 위로 마우스를 움직이면 동그라미가 움직이지만, + * 박스 안에서만 움직이도록 제한되어 있습니다. + */ +let mx = 1; +let my = 1; +let easing = 0.05; +let radius = 24; +let edge = 100; +let inner = edge + radius; + +function setup() { + createCanvas(720, 400); + noStroke(); + ellipseMode(RADIUS); + rectMode(CORNERS); +} + +function draw() { + background(230); + + if (abs(mouseX - mx) > 0.1) { + mx = mx + (mouseX - mx) * easing; + } + if (abs(mouseY - my) > 0.1) { + my = my + (mouseY - my) * easing; + } + + mx = constrain(mx, inner, width - inner); + my = constrain(my, inner, height - inner); + fill(237, 34, 93); + rect(edge, edge, width - edge, height - edge); + fill(255); + ellipse(mx, my, radius, radius); +} diff --git a/dist/assets/examples/ko/21_Input/02_Easing.js b/dist/assets/examples/ko/21_Input/02_Easing.js new file mode 100644 index 0000000000..d84bae3c2a --- /dev/null +++ b/dist/assets/examples/ko/21_Input/02_Easing.js @@ -0,0 +1,28 @@ +/* + * @name 이징(Easing) + * @description 화면 위로 마우스 커서를 움직이면 기호가 따라옵니다. + * 애니메이션의 매 프레임 사이에, 프로그램은 기호와 마우스 커서 간의 거리를 계산합니다. + * 만약 그 거리가 1픽셀보다 크다면, 기호는 현재 위치로부터 커서의 위치를 향해 + * 일정 거리(0.05)를 이동합니다. + */ +let x = 1; +let y = 1; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(237, 34, 93); + let targetX = mouseX; + let dx = targetX - x; + x += dx * easing; + + let targetY = mouseY; + let dy = targetY - y; + y += dy * easing; + + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/ko/21_Input/03_Keyboard.js b/dist/assets/examples/ko/21_Input/03_Keyboard.js new file mode 100644 index 0000000000..643e11c539 --- /dev/null +++ b/dist/assets/examples/ko/21_Input/03_Keyboard.js @@ -0,0 +1,38 @@ +/* + * @name 키보드 + * @description 이미지를 클릭하여 포커스를 주고 + * 키보드 입력을 통해 화면에 모양을 만듭니다. + * 각 자판은 고유의 식별 번호를 갖습니다. + * 이 번호들은 도형의 화면 상 위치를 정합니다. + */ +let rectWidth; + +function setup() { + createCanvas(720, 400); + noStroke(); + background(230); + rectWidth = width / 4; +} + +function draw() { + // draw()를 여기에 작성하여 키보드 입력을 기다리는 동안 반복되게 합니다. +} + +function keyPressed() { + let keyIndex = -1; + if (key >= 'a' && key <= 'z') { + keyIndex = key.charCodeAt(0) - 'a'.charCodeAt(0); + } + if (keyIndex === -1) { + // 글자 자판이 아닐 경우, 화면을 비웁니다. + background(230); + } else { + // 글자 자판일 경우, 사각면을 채웁니다. + randFill_r = Math.floor(Math.random() * 255 + 1); + randFill_g = Math.floor(Math.random() * 255 + 1); + randFill_b = Math.floor(Math.random() * 255 + 1); + fill(randFill_r, randFill_g, randFill_b); + let x = map(keyIndex, 0, 25, 0, width - rectWidth); + rect(x, 0, rectWidth, height); + } +} diff --git a/dist/assets/examples/ko/21_Input/04_Mouse1D.js b/dist/assets/examples/ko/21_Input/04_Mouse1D.js new file mode 100644 index 0000000000..0ca0d20e8e --- /dev/null +++ b/dist/assets/examples/ko/21_Input/04_Mouse1D.js @@ -0,0 +1,23 @@ +/* + * @name 1D 마우스 + * @description 마우스를 좌우로 움직여 균형점을 이동해보세요. + * mouseX 변수로 사각형의 크기와 색상 모두를 조정할 수 있습니다. + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + + let r1 = map(mouseX, 0, width, 0, height); + let r2 = height - r1; + + fill(237, 34, 93, r1); + rect(width / 2 + r1 / 2, height / 2, r1, r1); + + fill(237, 34, 93, r2); + rect(width / 2 - r2 / 2, height / 2, r2, r2); +} diff --git a/dist/assets/examples/ko/21_Input/05_Mouse2D.js b/dist/assets/examples/ko/21_Input/05_Mouse2D.js new file mode 100644 index 0000000000..72f1513be4 --- /dev/null +++ b/dist/assets/examples/ko/21_Input/05_Mouse2D.js @@ -0,0 +1,19 @@ +/* + * @name 2D 마우스 + * @description 마우스를 움직이면 각 상자의 위치와 크기가 바뀝니다. + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + fill(244, 122, 158); + rect(mouseX, height / 2, mouseY / 2 + 10, mouseY / 2 + 10); + fill(237, 34, 93); + let inverseX = width - mouseX; + let inverseY = height - mouseY; + rect(inverseX, height / 2, inverseY / 2 + 10, inverseY / 2 + 10); +} diff --git a/dist/assets/examples/ko/21_Input/06_MouseIsPressed.js b/dist/assets/examples/ko/21_Input/06_MouseIsPressed.js new file mode 100644 index 0000000000..b29e306fec --- /dev/null +++ b/dist/assets/examples/ko/21_Input/06_MouseIsPressed.js @@ -0,0 +1,20 @@ +/* + * @name 마우스 버튼 + * @description 마우스를 움직여 도형의 위치를 바꿔보세요. + * 마우스 버튼을 눌러 색을 반전시킬 수 있습니다. + */ +function setup() { + createCanvas(720, 400); + background(230); + strokeWeight(2); +} + +function draw() { + if (mouseIsPressed) { + stroke(255); + } else { + stroke(237, 34, 93); + } + line(mouseX - 66, mouseY, mouseX + 66, mouseY); + line(mouseX, mouseY - 66, mouseX, mouseY + 66); +} diff --git a/dist/assets/examples/ko/21_Input/07_Mouse_Functions.js b/dist/assets/examples/ko/21_Input/07_Mouse_Functions.js new file mode 100644 index 0000000000..659b8e8e27 --- /dev/null +++ b/dist/assets/examples/ko/21_Input/07_Mouse_Functions.js @@ -0,0 +1,66 @@ +/* + * @name 마우스 함수 + * @description 상자를 클릭한 뒤 화면 위에서 드래그 해보세요. + */ +let bx; +let by; +let boxSize = 75; +let overBox = false; +let locked = false; +let xOffset = 0.0; +let yOffset = 0.0; + +function setup() { + createCanvas(720, 400); + bx = width / 2.0; + by = height / 2.0; + rectMode(RADIUS); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + // 상자 위에 커서가 있는지를 테스트 + if ( + mouseX > bx - boxSize && + mouseX < bx + boxSize && + mouseY > by - boxSize && + mouseY < by + boxSize + ) { + overBox = true; + if (!locked) { + stroke(255); + fill(244, 122, 158); + } + } else { + stroke(156, 39, 176); + fill(244, 122, 158); + overBox = false; + } + + // 상자 그리기 + rect(bx, by, boxSize, boxSize); +} + +function mousePressed() { + if (overBox) { + locked = true; + fill(255, 255, 255); + } else { + locked = false; + } + xOffset = mouseX - bx; + yOffset = mouseY - by; +} + +function mouseDragged() { + if (locked) { + bx = mouseX - xOffset; + by = mouseY - yOffset; + } +} + +function mouseReleased() { + locked = false; +} diff --git a/dist/assets/examples/ko/21_Input/08_Mouse_Signals.js b/dist/assets/examples/ko/21_Input/08_Mouse_Signals.js new file mode 100644 index 0000000000..694d9e8aae --- /dev/null +++ b/dist/assets/examples/ko/21_Input/08_Mouse_Signals.js @@ -0,0 +1,51 @@ +/* + * @name 마우스 신호 + * @description 마우스를 움직이고 클릭하여 신호를 만들어보세요. + * 상단의 행은 "mouseX", 가운데 행은 "mouseY", + * 하단의 행은 "mouseIsPressed"에 대한 신호입니다. + */ +let xvals = []; +let yvals = []; +let bvals = []; + +function setup() { + createCanvas(720, 400); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + for (let i = 1; i < width; i++) { + xvals[i - 1] = xvals[i]; + yvals[i - 1] = yvals[i]; + bvals[i - 1] = bvals[i]; + } + // 배열의 마지막에 새로운 값들 더하기 + xvals[width - 1] = mouseX; + yvals[width - 1] = mouseY; + + if (mouseIsPressed) { + bvals[width - 1] = 0; + } else { + bvals[width - 1] = 255; + } + + fill(255); + noStroke(); + rect(0, height / 3, width, height / 3 + 1); + + for (let i = 1; i < width; i++) { + stroke(255); + point(i, xvals[i] / 3); + stroke(0); + point(i, height / 3 + yvals[i] / 3); + stroke(255); + line( + i, + (2 * height) / 3 + bvals[i] / 3, + i, + (2 * height) / 3 + bvals[i - 1] / 3 + ); + } +} diff --git a/dist/assets/examples/ko/21_Input/09_Storing_Input.js b/dist/assets/examples/ko/21_Input/09_Storing_Input.js new file mode 100644 index 0000000000..ea88476c2f --- /dev/null +++ b/dist/assets/examples/ko/21_Input/09_Storing_Input.js @@ -0,0 +1,36 @@ +/* + * @name 입력값 저장 + * @description 화면 위로 마우스를 움직여 원들의 위치를 바꿔보세요. + * 마우스의 위치값들은 배열에 기록되고 매 프레임마다 재생됩니다. + * 각 프레임이 재생되는 사이, 가장 새로운 값이 배열의 마지막에 더해지고 + * 가장 오래된 값은 삭제됩니다. + */ +let num = 60; +let mx = []; +let my = []; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255, 153); + for (let i = 0; i < num; i++) { + mx.push(i); + my.push(i); + } +} + +function draw() { + background(237, 34, 93); + + // 각 프레임마다 다른 입력값을 이용해 배열을 순환 + // 이처럼 모듈로(%)를 사용하면 모든 값들을 이동시키는 것보다 빠릅니다. + let which = frameCount % num; + mx[which] = mouseX; + my[which] = mouseY; + + for (let i = 0; i < num; i++) { + // which+1은 가장 작은 값 (동시에, 배열에서 가장 오래된 값) + let index = (which + 1 + i) % num; + ellipse(mx[index], my[index], i, i); + } +} diff --git a/dist/assets/examples/ko/21_Input/10_Rollover.js b/dist/assets/examples/ko/21_Input/10_Rollover.js new file mode 100644 index 0000000000..b5a6cf50c9 --- /dev/null +++ b/dist/assets/examples/ko/21_Input/10_Rollover.js @@ -0,0 +1,79 @@ +/* + * @name 롤오버 (Rollover) + * @description Roll over the colored squares in the center of the image to change the color of the outside rectangle. + *

This example is ported from the Rollover example + * on the Processing website + */ +let squareX, squareY; // 정사각형 버튼의 위치 +let circleX, circleY; // 원형 버튼의 위치 +let squareSize = 90; // 정사각형의 너비와 높이 +let circleSize = 93; // 원의 지름 + +let squareColor; +let circleColor; +let baseColor; + +let squareOver = false; +let circleOver = false; + +function setup() { + createCanvas(710, 400); + squareColor = color(0); + circleColor = color(255); + baseColor = color(102); + circleX = width/2+circleSize/2+10; + circleY = height/2; + squareX = width/2-squareSize-10; + squareY = height/2-squareSize/2; +} + +function draw() { + update(mouseX, mouseY); + + noStroke(); + if (squareOver) { + background(squareColor); + } else if (circleOver) { + background(circleColor); + } else { + background(baseColor); + } + + stroke(255); + fill(squareColor); + square(squareX, squareY, squareSize); + stroke(0); + fill(circleColor); + circle(circleX, circleY, circleSize); +} + +function update(x, y) { + if( overCircle(circleX, circleY, circleSize) ) { + circleOver = true; + squareOver = false; + } else if ( overSquare(squareX, squareY, squareSize) ) { + squareOver = true; + circleOver = false; + } else { + circleOver = squareOver = false; + } +} + +function overSquare(x, y, size) { + if (mouseX >= x && mouseX <= x+size && + mouseY >= y && mouseY <= y+size) { + return true; + } else { + return false; + } +} + +function overCircle(x, y, diameter) { + const disX = x - mouseX; + const disY = y - mouseY; + if(sqrt(sq(disX) + sq(disY)) < diameter/2 ) { + return true; + } else { + return false; + } +} \ No newline at end of file diff --git a/dist/assets/examples/ko/21_Input/11_Storing_Input.js b/dist/assets/examples/ko/21_Input/11_Storing_Input.js new file mode 100644 index 0000000000..563ff80759 --- /dev/null +++ b/dist/assets/examples/ko/21_Input/11_Storing_Input.js @@ -0,0 +1,38 @@ +/* + * @name Storing Input + * @description Move the mouse across the screen to + * change the position of the circles. The positions + * of the mouse are recorded into an array and played + * back every frame. Between each frame, the newest + * value are added to the end of each array and the + * oldest value is deleted. + */ +let num = 60; +let mx = []; +let my = []; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255, 153); + for (let i = 0; i < num; i++) { + mx.push(i); + my.push(i); + } +} + +function draw() { + background(237, 34, 93); + + // Cycle through the array, using a different entry on each frame. + // Using modulo (%) like this is faster than moving all the values over. + let which = frameCount % num; + mx[which] = mouseX; + my[which] = mouseY; + + for (let i = 0; i < num; i++) { + // which+1 is the smallest (the oldest in the array) + let index = (which + 1 + i) % num; + ellipse(mx[index], my[index], i, i); + } +} diff --git a/dist/assets/examples/ko/22_Advanced_Data/00_Load_Saved_JSON.js b/dist/assets/examples/ko/22_Advanced_Data/00_Load_Saved_JSON.js new file mode 100644 index 0000000000..e6eeba00c9 --- /dev/null +++ b/dist/assets/examples/ko/22_Advanced_Data/00_Load_Saved_JSON.js @@ -0,0 +1,104 @@ +/* + * @name 저장된 JSON 불러오기 + * @description Bubble 클래스를 만들고, JSON 파일의 데이터를 사용해 버블 여러 개를 인스턴스화합니다. + * 그리고, 그 결과물을 화면에 띄웁니다. + * 웹 브라우저마다 파일 저장 위치가 다르기 때문에, + * 프로세싱(Processing)의 예제와는 달리 saveJSON을 사용하지 않습니다.

+ * 다니엘 쉬프만(Daniel Shiffman) 제작 프로세싱(Processing)의 LoadSaveJSON 예제 참고 + */ + +// Bubble 클래스 +class Bubble { + constructor(x, y, diameter, name) { + this.x = x; + this.y = y; + this.diameter = diameter; + this.radius = diameter / 2; + this.name = name; + + this.over = false; + } + + // 마우스가 버블 위에 있는지 확인 + rollover(px, py) { + let d = dist(px, py, this.x, this.y); + this.over = d < this.radius; + } + + // 버블을 화면에 보이기 + display() { + stroke(0); + strokeWeight(0.8); + noFill(); + ellipse(this.x, this.y, this.diameter, this.diameter); + if (this.over) { + fill(0); + textAlign(CENTER); + text(this.name, this.x, this.y + this.radius + 20); + } + } +} + +let data = {}; // loadJSON 호출의 결과물을 담는 전역 객체 +let bubbles = []; // 모든 버블 객체를 담는 전역 배열 + +// 비동기 데이터 로딩을 preload에 담아 setup이 실행되기 전 완료시킴 +function preload() { + data = loadJSON('assets/bubbles.json'); +} + +// 저장된 Bubble 데이터를 Bubble 객체로 전환 +function loadData() { + let bubbleData = data['bubbles']; + for (let i = 0; i < bubbleData.length; i++) { + // 배열 속 각 객체 받아오기 + let bubble = bubbleData[i]; + // position 객체 받아오기 + let position = bubble['position']; + // 위치로부터 x,y 받아오기 + let x = position['x']; + let y = position['y']; + + // Get diameter and label + let diameter = bubble['diameter']; + let label = bubble['label']; + + // 배열에 객체 담기 + bubbles.push(new Bubble(x, y, diameter, label)); + } +} + +// 마우스가 클릭될 때마다 새로운 Bubble 만들기 +function mousePressed() { + // Bubble에 지름과 레이블 더하기 + let diameter = random(40, 80); + let label = 'New Label'; + + // 배열에 새로운 JSON bubble 객체 더하기 + bubbles.push(new Bubble(mouseX, mouseY, diameter, label)); + + // 버블이 너무 많을 경우 개수 제거하기 + if (bubbles.length > 10) { + bubbles.shift(); // 배열의 첫 번째 항목 제거하기 + } +} + +function setup() { + createCanvas(640, 360); + loadData(); +} + +function draw() { + background(255); + + // 모든 버블들 화면에 보이기 + for (let i = 0; i < bubbles.length; i++) { + bubbles[i].display(); + bubbles[i].rollover(mouseX, mouseY); + } + + // 하단에서의 레이블 방향들 + textAlign(LEFT); + fill(0); + text('Click to add bubbles.', 10, height - 10); +} diff --git a/dist/assets/examples/ko/22_Advanced_Data/01_Load_Saved_Table.js b/dist/assets/examples/ko/22_Advanced_Data/01_Load_Saved_Table.js new file mode 100644 index 0000000000..8536abcccc --- /dev/null +++ b/dist/assets/examples/ko/22_Advanced_Data/01_Load_Saved_Table.js @@ -0,0 +1,110 @@ +/* + * @name Load Saved Table + * @description Create a Bubble class, instantiate multiple bubbles using data from + * a csv file, and display results on the screen. + * Because the web browsers differ in where they save files, we do not make use of + * + * Based on Daniel Shiffman's LoadSaveTable Example for Processing. + */ + +// Bubble class +class Bubble { + constructor(x, y, diameter, name) { + this.x = x; + this.y = y; + this.diameter = diameter; + this.radius = diameter / 2; + this.name = name; + + this.over = false; + } + + // Check if mouse is over the bubble + rollover(px, py) { + let d = dist(px, py, this.x, this.y); + this.over = d < this.radius; + } + + // Display the Bubble + display() { + stroke(0); + strokeWeight(0.8); + noFill(); + ellipse(this.x, this.y, this.diameter, this.diameter); + if (this.over) { + fill(0); + textAlign(CENTER); + text(this.name, this.x, this.y + this.radius + 20); + } + } +} + +let table; // Global object to hold results from the loadTable call +let bubbles = []; // Global array to hold all bubble objects + +// Put any asynchronous data loading in preload to complete before "setup" is run +function preload() { + table = loadTable("assets/bubbles.csv", "header"); +} + +// Convert saved Bubble data into Bubble Objects +function loadData() { + const bubbleData = table.getRows(); + // The size of the array of Bubble objects is determined by the total number of rows in the CSV + const length = table.getRowCount(); + + for (let i = 0; i < length; i++) { + // Get position, diameter, name, + const x = bubbleData[i].getNum("x"); + const y = bubbleData[i].getNum("y"); + const diameter = bubbleData[i].getNum("diameter"); + const name = bubbleData[i].getString("name"); + + // Put object in array + bubbles.push(new Bubble(x, y, diameter, name)); + } +} + +// Create a new Bubble each time the mouse is clicked. +function mousePressed() { + // Create a new row + let row = table.addRow(); + + let name = "New Bubble"; + let diameter = random(40, 80); + + // Set the values of that row + row.setNum("x", mouseX); + row.setNum("y", mouseY); + row.setNum("diameter", diameter); + row.setString("name", name); + + bubbles.push(new Bubble(mouseX, mouseY, diameter, name)); + + // If the table has more than 10 rows + if (table.getRowCount() > 10) { + // Delete the oldest row + table.removeRow(0); + bubbles.shift(); + } +} + +function setup() { + createCanvas(640, 360); + loadData(); +} + +function draw() { + background(255); + + // Display all bubbles + for (let i = 0; i < bubbles.length; i++) { + bubbles[i].display(); + bubbles[i].rollover(mouseX, mouseY); + } + + // Label directions at bottom + textAlign(LEFT); + fill(0); + text("Click to add bubbles.", 10, height - 10); +} diff --git a/dist/assets/examples/ko/33_Sound/00_Load_and_Play_Sound.js b/dist/assets/examples/ko/33_Sound/00_Load_and_Play_Sound.js new file mode 100644 index 0000000000..c497516da3 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/00_Load_and_Play_Sound.js @@ -0,0 +1,25 @@ +/* + * @name 사운드 불러오기/재생 + * @description preload()중 사운드 불러오기. 캔버스가 클릭될 때마다 소리를 재생합니다. + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.



+ */ +let song; + +function setup() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); + createCanvas(720, 200); + background(255, 0, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying()은 불리언 값을 반환합니다. + song.stop(); + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/ko/33_Sound/01_Preload_Sound.js b/dist/assets/examples/ko/33_Sound/01_Preload_Sound.js new file mode 100644 index 0000000000..38120ffaaa --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/01_Preload_Sound.js @@ -0,0 +1,35 @@ +/* + * @name 사운드 파일 미리 불러오기 + * @description preload()에서 loadSound()를 호출하여, + * setup()이 호출되기 전에 미리 사운드 파일을 불러오도록 합니다. + * 이 때, preload()에서 loadSound()를 호출하는 것이 가장 좋은 방법입니다. + * 그렇지 않을 경우, 스케치에서 사운드 재생을 원하는 시점에 파일이 불러지지 않을 수 있습니다. + * + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ + +let song; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); // 이제 노래 파일이 setup()에서 재생될 준비가 되었습니다. + //preload에서 이미 한 차례 불러왔기 때문입니다. + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying()은 불리언 값을 반환합니다. + song.pause(); // .play()는 .pause() 지점에서 다시 시작합니다. + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/ko/33_Sound/02_soundFormats.js b/dist/assets/examples/ko/33_Sound/02_soundFormats.js new file mode 100644 index 0000000000..0cf8a92cdc --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/02_soundFormats.js @@ -0,0 +1,50 @@ +/** + * @name 사운드 파일 형식 + * @description

특허 문제로 인해, 모든 웹 브라우저가 지원하는 + * 단일의 사운드 파일 형식은 존재하지 않습니다. + * 예를 들어, + * mp3의 경우, OSX나 윈도우즈의 + * 주요 브라우저 최신 버전에서 지원하긴 하지만, 일부 운영 체제나 브라우저에서는 + * 사용하지 못할 수 있습니다.

+ * + *

사운드 파일의 완전한 호환성을 보장하기 위해, 동일한 사운드 파일을 + * 여러가지 형식으로 스케치에 포함시킬 수 있습니다. 'sound.mp3'나 'sound.ogg'가 그 예입니다. + * (Ogg는 mp3의 대안형 오픈 소스입니다.) media.io + * 에서 오디오 파일을 웹-친화적인 형식으로 무료 변환할 수 있습니다.

. + * + *

soundFormats() 메소드는 현재 스케치에 포함된 사운드 파일의 형식들을 loadSound에게 지정합니다. + * 그러면, loadSound는 지정된 형식들 중 클라이언트의 웹 브라우저가 지원하는 + * 첫번째 형식을 불러오도록 시도할 것입니다.

+ * + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

*/ +let song; + +function preload() { + // .ogg와 .mp3 파일 모두를 스케치에 포함시키기 + soundFormats('ogg', 'mp3'); + + // 만약 mp3를 이 브라우저가 지원하지 않는다면, + // loadSound는 스케치에 포함된 형식인 ogg 파일을 불러옵니다. + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + + // preload()중에 사운드 파일을 미리 불러와, setup()에서 재생할 수 있도록 준비 + song.play(); + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying()은 불리언 값을 반환합니다. + song.pause(); + background(255, 0, 0); + } else { + song.play(); // playback은 pause(일시정지) 지점에서 다시 재생합니다. + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/ko/33_Sound/03_Play_Mode.js b/dist/assets/examples/ko/33_Sound/03_Play_Mode.js new file mode 100644 index 0000000000..accdf51bc2 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/03_Play_Mode.js @@ -0,0 +1,42 @@ +/* + * @name 재생 모드 + * @description + *

'sustain' 모드에서는 사운드가 겹쳐서 재생됩니다. + * 'restart' 모드에서는 사운드가 멈췄다가 다시 재생합니다. + * 마우스 클릭으로 사운드 파일을 재생해보세요. + * 동시에 여러 사운드를 재생해보세요! 아무 자판을 눌러 재생 모드를 변경합니다.

+ *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +let playMode = 'sustain'; +let sample; + +function setup() { + createCanvas(710, 50); + soundFormats('mp3', 'ogg'); + sample = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3'); +} + +function draw() { + background(255, 255, 0); + let str = 'Click here to play! Press key to toggle play mode.'; + str += ' Current Play Mode: ' + playMode + '.'; + text(str, 10, height / 2); +} + +function mouseClicked() { + sample.play(); +} +function keyPressed(k) { + togglePlayMode(); +} + +function togglePlayMode() { + if (playMode === 'sustain') { + playMode = 'restart'; + } else { + playMode = 'sustain'; + } + sample.playMode(playMode); +} diff --git a/dist/assets/examples/ko/33_Sound/04_Pan_SoundFile.js b/dist/assets/examples/ko/33_Sound/04_Pan_SoundFile.js new file mode 100644 index 0000000000..0f07dd1a6a --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/04_Pan_SoundFile.js @@ -0,0 +1,34 @@ +/* + * @name 사운드 패닝 + * @description

마우스를 클릭해 사운드를 재생하세요. + * 공의 위치는 마우스의 위치와 더불어, 사운드의 패닝과도 관련됩니다.

+ *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ * + */ +let ball = {}; +let soundFile; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beatbox.ogg'); +} + +function setup() { + createCanvas(710, 100); +} + +function draw() { + background(0); + ball.x = constrain(mouseX, 0, width); + ellipse(ball.x, height / 2, 100, 100); +} + +function mousePressed() { + // 공의 x 위치를 패닝 각도에 맵핑하기 + // -1.0 (좌) 과 1.0 (우) 사이 + let panning = map(ball.x, 0, width, -1.0, 1.0); + soundFile.pan(panning); + soundFile.play(); +} diff --git a/dist/assets/examples/ko/33_Sound/05_Sound_Effect.js b/dist/assets/examples/ko/33_Sound/05_Sound_Effect.js new file mode 100644 index 0000000000..7f9b5e65a3 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/05_Sound_Effect.js @@ -0,0 +1,68 @@ +/* + * @name 사운드 효과 + * @description

마우스로 원 안쪽을 누르면 사운드 효과가 재생됩니다.

+ *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +// 다니엘 쉬프만(Daniel Shiffman)의 Learning Processing을 적용 +// http://www.learningprocessing.com +// 초인종 샘플 출처: freesound.org에서 Corsica_S 제작, +// Creative Commons BY 3.0 + +// "doorbell(초인종)"을 설명하는 클래스 (실제로 버튼처럼 작동) +class Doorbell { + constructor(x_, y_, r_) { + // 위치와 크기 + this.x = x_; + this.y = y_; + this.r = r_; + } + // doorbell 안에 마우스 점이 있나요? (마우스 롤오버 등에 사용) + contains(mx, my) { + return dist(mx, my, this.x, this.y) < this.r; + } + + // doorbell을 보여주세요. (색상 부분은 하드코딩이네요. 더 나은 방법이 있을거에요.) + display(mx, my) { + if (this.contains(mx, my)) { + fill(100); + } else { + fill(175); + } + stroke(0); + strokeWeight(4); + ellipse(this.x, this.y, this.r, this.r); + } +} + +// 사운드 파일 객체 +let dingdong; + +// 초인종 객체 (사운드를 트리거) +let doorbell; + +function setup() { + createCanvas(200, 200); + + // 사운드 파일 불러오기 + // 스케치에 MP3와 OGG 버전을 포함시킵니다. + soundFormats('mp3', 'ogg'); + dingdong = loadSound('assets/doorbell.mp3'); + + // 새로운 초인종 만들기 + doorbell = new Doorbell(width / 2, height / 2, 64); +} + +function draw() { + background(255); + // 초인종 보이기 + doorbell.display(mouseX, mouseY); +} + +function mousePressed() { + // 사용자가 초인종을 클릭하면, 사운드 재생하기! + if (doorbell.contains(mouseX, mouseY)) { + dingdong.play(); + } +} diff --git a/dist/assets/examples/ko/33_Sound/06_Manipulate_Sound.js b/dist/assets/examples/ko/33_Sound/06_Manipulate_Sound.js new file mode 100644 index 0000000000..5edc06eb21 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/06_Manipulate_Sound.js @@ -0,0 +1,48 @@ +/* + * @name 재생 속도 + * @description

사운드 파일을 불러와 재생 속도와 볼륨을 mouseY에 맵핑합니다. + * 여기서 재생 속도란, 웹 오디오가 사운드 파일 정보를 처리하는 속도를 말합니다. + * 재생 속도가 느리면 사운드의 지속 시간을 늘릴 뿐 아니라, + * 느린 주파수에서 재생되어 음고(pitch)를 감소시킵니다.

+ *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +// 사운드 파일 객체 +let song; + +function preload() { + // 사운드 파일 불러오기 + song = loadSound('assets/Damscray_DancingTiger.mp3'); +} + +function setup() { + createCanvas(710, 400); + + // 사운드 무한 반복하기 + // (뭐, 적어도 stop()이 호출되기 전까지요) + song.loop(); +} + +function draw() { + background(200); + + // 볼륨 범위를 0 과 1.0 사이로 설정 + let volume = map(mouseX, 0, width, 0, 1); + volume = constrain(volume, 0, 1); + song.amp(volume); + + // 재생 속도 범위를 0.1 과 4 사이로 설정 + // 재생 속도를 변경하면 음고 또한 달라집니다. + let speed = map(mouseY, 0.1, height, 0, 2); + speed = constrain(speed, 0.01, 4); + song.rate(speed); + + // 원을 그려 어떤 일이 일어나는지 확인하기 + stroke(0); + fill(51, 100); + ellipse(mouseX, 100, 48, 48); + stroke(0); + fill(51, 100); + ellipse(100, mouseY, 48, 48); +} diff --git a/dist/assets/examples/ko/33_Sound/07_Amplitude_Analysis.js b/dist/assets/examples/ko/33_Sound/07_Amplitude_Analysis.js new file mode 100644 index 0000000000..91c2e4e994 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/07_Amplitude_Analysis.js @@ -0,0 +1,47 @@ +/** + * @name 진폭 측정 + * @description

p5.Amplitude로 사운드의 진폭을 분석합니다.

+ * + *

진폭(amplitude)은 진동의 크기를 말합니다. + * 사운드는 진동이므로, 볼륨/음량과 밀접한 관계를 갖습니다.

+ * + *

getLevel() 메소드는 짧은 시간 동안 수집된 + * 진폭값(1024 샘플)을 배열에 담습니다. + * 그 다음, 이 값들의 제곱 평균 제곱근(RMS)을 반환합니다.

+ * + *

디지털 오디오의 본래 진폭값은 -1.0과 1.0 사이입니다. + * 하지만, RMS는 제곱이므로 항상 양수입니다. + * 또한, RMS는 초당 44,000배의 속도에서 샘플링된 순간 진폭 판독값을 사용하는 대신 + * 시간에 따른 평균값(이 경우, 1024 샘플)을 사용하여, 진폭을 듣는 방식을 더욱 잘 나타냅니다.

+ *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +let song, analyzer; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); + + // 새로운 진폭 분석기 생성 + analyzer = new p5.Amplitude(); + + // 볼륨 분석기에 입력값 패치하기 + analyzer.setInput(song); +} + +function draw() { + background(255); + + // 평균 진폭값(RMS) 받아오기 + let rms = analyzer.getLevel(); + fill(127); + stroke(0); + + // 볼륨과 비례한 크기의 타원 그리기 + ellipse(width / 2, height / 2, 10 + rms * 200, 10 + rms * 200); +} diff --git a/dist/assets/examples/ko/33_Sound/08_Noise_Envelope.js b/dist/assets/examples/ko/33_Sound/08_Noise_Envelope.js new file mode 100644 index 0000000000..2132861e7d --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/08_Noise_Envelope.js @@ -0,0 +1,50 @@ +/** + * @name 노이즈 드럼 엔벨로프 + * @description

 화이트 노이즈는 주파수 영역의 모든 부분에서 + * 동일한 에너지를 갖는, 임의의 오디오 신호입니다

+ *

엔벨로프(envelope)는 시간/값의 쌍으로 정의되는 + * 일련의 페이드를 말합니다.

+ *

이 예제에서는, p5.Env로 출력된 진폭을 제어하여 + * p5.Noise를 마치 드럼처럼 "재생"합니다. + * p5.Amplitude는 스케치에 포함된 모든 사운드들의 레벨을 가져오며, + * 작동 중인 엔벨로프를 이 값으로서 초록색 사각형으로 표현합니다.

+ *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 됩니다.

+ */ +let noise, env, analyzer; + +function setup() { + createCanvas(710, 200); + noise = new p5.Noise(); // 그 외 타입들은 '갈색'과 '분홍'을 포함 + noise.start(); + + // 노이즈 볼륨에 0 곱하기 + // (노이즈 재생 전까지 조용하기 위해서요!) + noise.amp(0); + + env = new p5.Env(); + // 어택 시간, 감쇠 시간, 지속 속도, 릴리즈 시간 설정 + env.setADSR(0.001, 0.1, 0.2, 0.1); + // 어택 레벨, 릴리즈 레벨 설정 + env.setRange(1, 0); + + // setInput()메소드로 입력값을 지정하지 않는 이상, + // p5.Amplitude는 스케치에 포함된 모든 사운드를 분석할 것입니다. + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // p5.Amplitude analyzer(분석 장치)로부터 볼륨 판독값 받아오기 + let level = analyzer.getLevel(); + + // 레벨값을 사용하여 초록색 사각형 그리기 + let levelHeight = map(level, 0, 0.4, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); +} + +function mousePressed() { + env.play(noise); +} diff --git a/dist/assets/examples/ko/33_Sound/09_Note_Envelope.js b/dist/assets/examples/ko/33_Sound/09_Note_Envelope.js new file mode 100644 index 0000000000..853814b982 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/09_Note_Envelope.js @@ -0,0 +1,59 @@ +/** + * @name 음계 엔벨로프 + * @description

엔벨로프(envelope)는 시간/값의 쌍으로 정의되는 + * 일련의 페이드를 말합니다. + * 이 예제에서 엔벨로프는 오실레이터의 출력 진폭을 제어하여 + * 음계를 "재생"하는 데 사용됩니다.

+ * p5.Oscillator은 내부 웹 오디오 GainNode(p5.Oscillator.output) + * 를 거쳐 그 출력 내용을 전송합니다. + * 이 노드는 기본값으로 상수 0.5를 갖는데, osc.amp()메소드로 재설정할 수 있습니다. + * 또는 이 예제에서처럼, 엔벨로프가 직접 노드를 제어하여 + * 마치 볼륨을 조정하듯 진폭을 조정할 수 있습니다.

+ *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 됩니다.

+ */ +let osc, envelope, fft; + +let scaleArray = [60, 62, 64, 65, 67, 69, 71, 72]; +let note = 0; + +function setup() { + createCanvas(710, 200); + osc = new p5.SinOsc(); + + // 엔벨로프 인스턴스화 + envelope = new p5.Env(); + + // 어택 시간, 감쇠 시간, 지속 속도, 릴리즈 시간 설정 + envelope.setADSR(0.001, 0.5, 0.1, 0.5); + + // 어택 레벨, 릴리즈 레벨 설정 + envelope.setRange(1, 0); + + osc.start(); + + fft = new p5.FFT(); + noStroke(); +} + +function draw() { + background(20); + + if (frameCount % 60 === 0 || frameCount === 1) { + let midiValue = scaleArray[note]; + let freqValue = midiToFreq(midiValue); + osc.freq(freqValue); + + envelope.play(osc, 0, 0.1); + note = (note + 1) % scaleArray.length; + } + + // 캔버스에 FFT.analyze() 주파수 분석 내용 기입 + let spectrum = fft.analyze(); + for (let i = 0; i < spectrum.length / 20; i++) { + fill(spectrum[i], spectrum[i] / 10, 0); + let x = map(i, 0, spectrum.length / 20, 0, width); + let h = map(spectrum[i], 0, 255, 0, height); + rect(x, height, spectrum.length / 20, -h); + } +} diff --git a/dist/assets/examples/ko/33_Sound/10_Oscillator_Waveform.js b/dist/assets/examples/ko/33_Sound/10_Oscillator_Waveform.js new file mode 100644 index 0000000000..434bd0a2b1 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/10_Oscillator_Waveform.js @@ -0,0 +1,39 @@ +/* + * @name 오실레이터 주파수 + * @description

FFT를 사용하여 오실레이터를 제어하고 그 파형을 봅니다. + * MouseX는 주파수에, mouseY는 진폭에 매핑됩니다.

+ *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 됩니다.

+ */ +let osc, fft; + +function setup() { + createCanvas(720, 256); + + osc = new p5.TriOsc(); // 주파수와 종류 설정 + osc.amp(0.5); + + fft = new p5.FFT(); + osc.start(); +} + +function draw() { + background(255); + + let waveform = fft.waveform(); // 파형 분석하기 + beginShape(); + strokeWeight(5); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, height, 0); + vertex(x, y); + } + endShape(); + + // 오실레이터 주파수를 mouseX에 따라 변경 + let freq = map(mouseX, 0, width, 40, 880); + osc.freq(freq); + + let amp = map(mouseY, 0, height, 1, 0.01); + osc.amp(amp); +} diff --git a/dist/assets/examples/ko/33_Sound/11_Live_Input.js b/dist/assets/examples/ko/33_Sound/11_Live_Input.js new file mode 100644 index 0000000000..dc3fefa8e4 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/11_Live_Input.js @@ -0,0 +1,33 @@ +/** + * @name 마이크 입력 + * @description

컴퓨터의 마이크를 통해 오디오 입력을 받습니다. + * 마이크에 소리를 내어 타원이 떠오르게 해보세요.

+ *

주의: p5.AudioIn에는 p5.Amplitude 객체가 포함되어, 별도의 + * p5.Amplitude를 생성하지 않고도 p5.AudioIn에서 getLevel을 호출할 수 있습니다.

+ * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

*/ +let mic; + +function setup() { + createCanvas(710, 200); + + // 오디오 입력 생성하기 + mic = new p5.AudioIn(); + + // 오디오 입력 시작하기 + // 그 기본값은 .connect()(즉, 컴퓨터 스피커에 연결)되지 "않은" 상태입니다. + mic.start(); +} + +function draw() { + background(200); + + // 전체 볼륨(0과 1.0 사이) 받아오기 + let vol = mic.getLevel(); + fill(127); + stroke(0); + + // 마이크 소리의 볼륨에 따라 떠있는 높이가 변하는 타원 그리기 + let h = map(vol, 0, 1, height, 0); + ellipse(width / 2, h - 25, 50, 50); +} diff --git a/dist/assets/examples/ko/33_Sound/12_FFT_Spectrum.js b/dist/assets/examples/ko/33_Sound/12_FFT_Spectrum.js new file mode 100644 index 0000000000..488985b5be --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/12_FFT_Spectrum.js @@ -0,0 +1,30 @@ +/** + * @name 주파수 스펙트럼 + * @description

실시간 오디오 입력을 통해 주파수 스펙트럼을 시각화합니다.

+ *

To run this example locally, you will need the + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +let mic, fft; + +function setup() { + createCanvas(710, 400); + noFill(); + + mic = new p5.AudioIn(); + mic.start(); + fft = new p5.FFT(); + fft.setInput(mic); +} + +function draw() { + background(200); + + let spectrum = fft.analyze(); + + beginShape(); + for (i = 0; i < spectrum.length; i++) { + vertex(i, map(spectrum[i], 0, 255, height, 0)); + } + endShape(); +} diff --git a/dist/assets/examples/ko/33_Sound/13_Mic_Threshold.js b/dist/assets/examples/ko/33_Sound/13_Mic_Threshold.js new file mode 100644 index 0000000000..46e98c93d5 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/13_Mic_Threshold.js @@ -0,0 +1,48 @@ +/** + * @name 마이크 임계값 + * @description

입력된 오디오의 볼륨이 임계값을 초과하면 + * 특정 이벤트(이 경우, 사각형 그리기)가 발생합니다.

+ * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +// 다니엘 쉬프만(Daniel Shiffman)저 Learning Processing을 적용 +// learningprocessing.com +let input; +let analyzer; + +function setup() { + createCanvas(710, 200); + background(255); + + // 오디오 입력 생성하기 + input = new p5.AudioIn(); + + input.start(); +} + +function draw() { + // 전체 볼륨(0과 1.0 사이) 받아오기 + let volume = input.getLevel(); + + // 만약 볼륨 > 0.1 이라면, 임의의 위치에 사각형 한 개가 그려집니다. + // 볼륨이 커질수록, 사각형도 커집니다. + let threshold = 0.1; + if (volume > threshold) { + stroke(0); + fill(0, 100); + rect(random(40, width), random(height), volume * 50, volume * 50); + } + + // 전체 볼륨 범위를 막대 그래프로 나타내고 임계값의 위치에는 선 하나 긋기 + let y = map(volume, 0, 1, height, 0); + let ythreshold = map(threshold, 0, 1, height, 0); + + noStroke(); + fill(175); + rect(0, 0, 20, height); + // 그 다음, 볼륨값을 보여주는 검정 사각형을 그래프 위에 그리기 + fill(0); + rect(0, y, 20, y); + stroke(0); + line(0, ythreshold, 19, ythreshold); +} diff --git a/dist/assets/examples/ko/33_Sound/14_Filter_LowPass.js b/dist/assets/examples/ko/33_Sound/14_Filter_LowPass.js new file mode 100644 index 0000000000..2b9f7f7c09 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/14_Filter_LowPass.js @@ -0,0 +1,59 @@ +/* + * @name 로우패스 필터 + * @description p5.SoundFile에 p5.LowPass 필터를 적용합니다. + * FFT를 사용해 사운드를 시각화해보세요. + * mouseX를 필터의 차단 주파수에, mouseY를 밴드패스 필터의 울림/폭에 맵핑합니다. + *

로컬 프로젝트에서 이 예제를 실행하려면 + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +let soundFile; +let fft; + +let filter, filterFreq, filterRes; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beat'); +} + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + // 사운드 파일 불러오기 + soundFile.loop(); + + filter = new p5.LowPass(); + + // 마스터 출력으로부터 사운드 파일 연결 해제 + // Then, connect it to the filter, so that we only hear the filtered sound + soundFile.disconnect(); + soundFile.connect(filter); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // mouseX를 FFT 스펙트럼 가청 범위(10Hz-22050Hz)에 해당하는 밴드패스 주파수에 맵핑하기 + filterFreq = map(mouseX, 0, width, 10, 22050); + + // mouseY를 울림/폭에 맵핑하기 + filterRes = map(mouseY, 0, height, 15, 5); + + // 필터 매개 변수들 설정 + filter.set(filterFreq, filterRes); + + // FFT 스펙트럼 분석 중 x와 h가 아래와 같은 모든 값들 그리기: + // x = 최저(10Hz)~최고(22050Hz) 주파수, + // h = 해당 주파수에서의 에너지 / 진폭 + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/ko/33_Sound/15_Filter_BandPass.js b/dist/assets/examples/ko/33_Sound/15_Filter_BandPass.js new file mode 100644 index 0000000000..37ad52651f --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/15_Filter_BandPass.js @@ -0,0 +1,51 @@ +/* + * @name 밴드패스 필터 + * @description 화이트 노이즈에 p5.BandPass 필터를 적용합니다. + * FFT를 사용해 사운드를 시각화해보세요. + * mouseX를 필터의 밴드패스(대역) 주파수에, mouseY를 밴드패스 필터의 울림/폭에 맵핑합니다. + *

로컬 프로젝트에서 이 예제를 실행하려면 + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +let noise; +let fft; +let filter, filterFreq, filterWidth; + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + filter = new p5.BandPass(); + + noise = new p5.Noise(); + + noise.disconnect(); // 마스터 출력과 사운드 파일 연결 해제... + filter.process(noise); // ...그리고 필터에 연결하여 밴드패스만 들리게하기 + + noise.start(); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // mouseX를 FFT 가청 스펙트럼 범위(10Hz-22050Hz)에 해당하는 밴드패스 주파수에 맵핑하기 + filterFreq = map(mouseX, 0, width, 10, 22050); + // mouseY를 울림/폭에 맵핑하기 + filterWidth = map(mouseY, 0, height, 0, 90); + // 필터 매개 변수들 설정 + filter.set(filterFreq, filterWidth); + + // FFT 스펙트럼 분석 중 x와 h가 아래와 같은 모든 값들 그리기: + // x = 최저(10Hz)~최고(22050Hz) 주파수, + // h = 해당 주파수에서의 에너지 / 진폭 + + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/ko/33_Sound/16_Delay.js b/dist/assets/examples/ko/33_Sound/16_Delay.js new file mode 100644 index 0000000000..f18120992f --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/16_Delay.js @@ -0,0 +1,56 @@ +/** + * @name 딜레이 필터 + * @description + * 마우스를 클릭하여 p5.Delay로 처리된 사운드 파일을 들어보세요. + * MouseX는 p5.Delay필터의 주파수를 조정합니다. + * MouseY는 p5.Delay필터의 시간과 울림 정도를 조정합니다. + * Amplitude(진폭) 객체로 출력된 사운드의 볼륨을 시각화해보세요. + * + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ + +let soundFile, analyzer, delay; + +function preload() { + soundFormats('ogg', 'mp3'); + soundFile = loadSound('assets/beatbox.mp3'); +} + +function setup() { + createCanvas(710, 400); + + soundFile.disconnect(); // 여기선 딜레이만 들을 수 있습니다. + + delay = new p5.Delay(); + delay.process(soundFile, 0.12, 0.7, 2300); + delay.setType('pingPong'); // 스테레오 효과 + + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // p5.Amplitude 분석 장치의 볼륨 판독 내용 받아오기 + let level = analyzer.getLevel(); + + // 레벨을 사용하여 초록색 사각형 그리기 + let levelHeight = map(level, 0, 0.1, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); + + let filterFreq = map(mouseX, 0, width, 60, 15000); + filterFreq = constrain(filterFreq, 60, 15000); + let filterRes = map(mouseY, 0, height, 3, 0.01); + filterRes = constrain(filterRes, 0.01, 3); + delay.filter(filterFreq, filterRes); + let delTime = map(mouseY, 0, width, 0.2, 0.01); + delTime = constrain(delTime, 0.01, 0.2); + delay.delayTime(delTime); +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/ko/33_Sound/17_Reverb.js b/dist/assets/examples/ko/33_Sound/17_Reverb.js new file mode 100644 index 0000000000..eefb7b69ad --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/17_Reverb.js @@ -0,0 +1,36 @@ +/* + * @name 리버브 + * @description 리버브(reverb)는 사운드에 깊이감과 공간감을 더합니다. + * 이 예제에서 노이즈는 reverb로 처리됩니다. + * + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +let sound, reverb; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/Damscray_DancingTiger'); + + // 기본값으로 설정된 연결 상태를 해제하여 + // reverb.process를 통해서만 사운드를 들을 수 있도록 처리합니다. + soundFile.disconnect(); +} + +function setup() { + createCanvas(720, 100); + background(0); + + reverb = new p5.Reverb(); + + // 6초의 reverbTime(리버브 시간)과 0.2%의 decayRate(감쇠 속도)를 갖는 + // 리버브에 사운드 파일 연결하기 + reverb.process(soundFile, 6, 0.2); + + reverb.amp(4); // 턴잇업! +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/ko/33_Sound/18_Convolution_Reverb.js b/dist/assets/examples/ko/33_Sound/18_Convolution_Reverb.js new file mode 100644 index 0000000000..91205a1cee --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/18_Convolution_Reverb.js @@ -0,0 +1,84 @@ +/* + * @name 컨볼루션 리버브 + * @description

The p5.Convolver + * p5.Convolver는 컨볼루션을 사용하여 실제 공간 사운드를 재현합니다. + * 컨볼루션은 임펄스 응답(즉, 반향하는 공간의 사운드)으로 해당 공간의 사운드를 재생성합니다. + * 컨볼루션으로 처리된 소리를 재생하려면 클릭하세요. + * 매번 클릭할 때마다, 서로 다른 임펄스 응답으로 재생성된 사운드를 들을 수 있습니다. + * 임펄스 응답만 재생하려면 아무 키나 누르세요. + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ * 컨볼루션 샘플들은 + * recordinghopkins가 제작한 크리에이티브 커먼즈(CC)입니다.

+ */ +let sound, env, cVerb, fft; +let currentIR = 0; +let rawImpulse; + +function preload() { + // 모든 임펄스/사운드들의 MP3 및 OGG 버전을 이 스케치에 포함시킵니다. + soundFormats('ogg', 'mp3'); + + // p5.Convolver 생성하기 + cVerb = createConvolver('assets/bx-spring'); + + // bx-spring에 더해, cVerb.impulses 배열에 임펄스 응답 추가하기 + cVerb.addImpulse('assets/small-plate'); + cVerb.addImpulse('assets/drum'); + cVerb.addImpulse('assets/beatbox'); + cVerb.addImpulse('assets/concrete-tunnel'); + + // p5.ConvultionReverb로 처리될 사운드 불러오기 + sound = loadSound('assets/Damscray_DancingTiger'); +} + +function setup() { + createCanvas(710, 400); + rawImpulse = loadSound('assets/' + cVerb.impulses[currentIR].name); + + // 마스터 출력으로부터 연결 해제하고... + sound.disconnect(); + // ... cVerb로 처리하여 + // 오직 리버브만 들을 수 있도록 합니다. + cVerb.process(sound); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + fill(0, 255, 40); + + let spectrum = fft.analyze(); + + // frequencySpectrum 배열에 있는 모든 값들을 사각형으로 그리기 + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} + +function mousePressed() { + // cVerb.impulses 배열 반복하기 + currentIR++; + if (currentIR >= cVerb.impulses.length) { + currentIR = 0; + } + cVerb.toggleImpulse(currentIR); + + // 임펄스를 거쳐 사운드 재생하기 + sound.play(); + + // 현재 임펄스 응답 이름 보이기(파일 경로) + println('Convolution Impulse Response: ' + cVerb.impulses[currentIR].name); + + rawImpulse.setPath('assets/' + cVerb.impulses[currentIR].name); +} + +// 임펄스 재생하기(컨볼루션 없이) +function keyPressed() { + rawImpulse.play(); +} diff --git a/dist/assets/examples/ko/33_Sound/19_Record_Save.js b/dist/assets/examples/ko/33_Sound/19_Record_Save.js new file mode 100644 index 0000000000..e694f0c482 --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/19_Record_Save.js @@ -0,0 +1,57 @@ +/** + * @name 오디오 녹음/저장 + * @description + * 사운드를 녹음하고 재생한 뒤, 클라이언트 컴퓨터에 .wav 파일로 저장하세요. + * 이 예제에서는 총 세 개의 객체가 필요합니다: p5.AudioIn(마이크/사운드 소스), + * p5.SoundRecorder(사운드 녹음), 그리고 p5.SoundFile(재생/저장) + *

로컬 프로젝트에서 이 예제를 실행하려면 적어도 한 개의 사운드 파일이 필요하고, + * p5.sound 라이브러리를 추가해야 되며, + * 로컬 서버를 작동시켜야 합니다.

+ */ +let mic, recorder, soundFile; + +let state = 0; // 마우스 버튼이 눌리면 녹음, 정지, 재생 순으로 상태가 변합니다. + +function setup() { + createCanvas(400, 400); + background(200); + fill(0); + text('Enable mic and click the mouse to begin recording', 20, 20); + + // AudioIn 생성하기 + mic = new p5.AudioIn(); + + // 녹음 기능을 제대로 작동시키려면, 사용자가 브라우저 마이크를 수동으로 활성화해야 됩니다! + mic.start(); + + // 사운드 녹음기 생성하기 + recorder = new p5.SoundRecorder(); + + // 마이크를 녹음기에 연결 + recorder.setInput(mic); + + // 녹음된 사운드를 재생할 빈 사운드 파일 생성 + soundFile = new p5.SoundFile(); +} + +function mousePressed() { + // '.enabled' 불리언을 사용하여 사용자의 마이크 활성화 여부 확인(그렇지 않을 경우, 침묵 상태를 녹음하게 됩니다!) + if (state === 0 && mic.enabled) { + // p5.SoundFile에 녹음하라고 녹음기에 지시하기. 이 파일은 녹음 사운드를 재생하는 데에 쓰입니다. + recorder.record(soundFile); + + background(255, 0, 0); + text('Recording now! Click to stop.', 20, 20); + state++; + } else if (state === 1) { + recorder.stop(); // 녹음기를 멈추고, 결과물을 soundFile에 보내기 + + background(0, 255, 0); + text('Recording stopped. Click to play & save', 20, 20); + state++; + } else if (state === 2) { + soundFile.play(); // 결과물 재생하기! + saveSound(soundFile, 'mySound.wav'); // 파일 저장하기 + state++; + } +} diff --git a/dist/assets/examples/ko/33_Sound/21_FreqModulation.js b/dist/assets/examples/ko/33_Sound/21_FreqModulation.js new file mode 100644 index 0000000000..27140d9a8f --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/21_FreqModulation.js @@ -0,0 +1,142 @@ +/** + * @name 주파수 변조(FM) + * @description

주파수 변조(Frequancy Modulator, FM)는 강력한 합성 방식입니다. + * 아주 간단히 말하자면, FM은 반송파와 변조기라는 두 개의 오실레이터를 포함합니다. + * 변조기의 파형이 최소 및 최대 진폭 값 사이에서 진동하면, 그 순간의 값이 반송파 주파수에 추가(즉, "변조")됩니다

+ *

반송파는, 우리가 일반적으로 음고(pitch)라 부르는, 가청 주파수에서 진동합니다. + * 이 예제의 경우, "A3"음과 동일한 220Hz의 사인파 오실레이터입니다. + * 모든 p5.Oscillator들은 그 기본값으로 반송파가 마스터 출력에 연결되어 있습니다. + *

이 예제에서 우리는 변조기를 마스터 출력과 연결 해제하고, + * 대신 다음을 사용하여 반송파 주파수에 연결합니다: carrier.freq(modulator). + * 이는 변조기의 출력 진폭을 반송파 주파수에 추가합니다.

+ *

+ * 변조 깊이는 반송파 주파수가 변조된 정도를 묘사합니다. + * 이는 변조기의 진폭을 기반으로 합니다. + * 변조기는 반송파 주파수에 추가될, 진폭 값들의 연속적인 스트림을 생성합니다. + * 진폭이 0이면 묵음이 발생하므로 변조가 적용되지 않습니다. + * 진폭이 1.0이면 출력값의 범위가 +1.0과 -1.0 사이로 조정됩니다. + * 이는 스피커로 전송되는 사운드의 표준 범위이기도 합니다. + * 하지만, FM에서는 변조기의 출력을 반송파 주파수로 전송하는데, + * 반송파 주파수에서는 + 1Hz / -1Hz 변조를 거의 찾아보기 힘듭니다. + * 따라서, 변조기의 진폭("깊이")을 스피커로 보내는 값보다 훨씬 높은 숫자로 증가시키는 게 일반적입니다.

+ *

변조 주파수는 변조 속도를 나타냅니다. + * 변조 주파수가 20Hz보다 낮으면, 우리는 주파수를 음고가 아닌 비트와 리듬으로서 듣게 됩니다. + * 예를 들어, 오페라 보컬의 "비브라토" 효과를 따라하고자, 깊이 20에서 7.5Hz를 시도해보세요. + * 이를 위한 용어는 저주파수 오실레이터(Low Frequency Oscillator, LFO)입니다. + * 더 높은 주파수로 설정된 변조기는 여러가지 흥미로운 효과들을 만들 수 있습니다. + * 특히, 주파수가 반송파 신호와 화음을 이룰 경우 그렇습니다. + * 그 예로, 변조기의 주파수가 반송파 주파수의 절반 또는 두 배일 때 발생하는 사운드를 들어세요. + * 이는 존 차우닝(John Chowning)이 1960년대에 개발한 "FM 합성" 개념의 근간이기도 합니다. + * FM 합성은 1980년대에 이르러 사운드 합성을 변혁시킨 바 있으며, 놋쇠나 종소리를 합성하는 데에 자주 사용됩니다. * + * + *

이 예제에서는,

+ * - MouseX가 변조 깊이(즉, 변조기의 진폭)를 -150부터 150까지 조정합니다. + * 변조기 진폭이 0(즉, 가운데)으로 설정되면, 아무런 변조 효과가 발생하지 않습니다. + * 숫자의 절대값이 커질수록, 효과가 커집니다. + * 변조기 파형이 마치 사각형 [], 싸인 ~ + * 또는 삼각형 /\과 같이 대칭일 경우, 음수의 진폭과 양수의 진폭은 동일합니다. + * 하지만 이 예제 속 변조기는 마치 이러한 모양 / 의 톱니처럼 생긴 비대칭적인 파형을 갖습니다. + * 여기에 음수를 곱하면, 파형이 마치 이러한 모양 \ 처럼 반대로 바뀝니다. + * 그 차이를 명확히 관찰하려면, 주파수를 낮춰보세요. + *

+ *

- MouseY는 변조기의 주파수를 0부터 112Hz까지 조정합니다. + * 가청 범위(약 20hz에서 시작) 이하 및 이상 영역에서의 변조기 주파수를 비교해보세요. + * 특히, 반송파 주파수(220hz이므로 1/2, 1/3, 1/4 등으로 나눠보세요)와 화음을 이루는 상태에서요! * + * + *

로컬 프로젝트에서 이 예제를 실행하려면, + * p5.sound 라이브러리 + * 를 추가해야 됩니다.

+ */ + +let carrier; // 이것이 바로 우리가 듣게될 오실레이터입니다. +let modulator; // 이 오실레이터가 반송파 주파수를 변조할 것입니다. + +let analyzer; // 이것을 사용해 파형을 시각화합니다. + +// 반송파 주파수 사전 변조 +let carrierBaseFreq = 220; + +// 변조기의 최저/최고 범위 +let modMaxFreq = 112; +let modMinFreq = 0; +let modMaxDepth = 150; +let modMinDepth = -150; + +function setup() { + let cnv = createCanvas(800, 400); + noFill(); + + carrier = new p5.Oscillator('sine'); + carrier.amp(0); // 진폭 설정 + carrier.freq(carrierBaseFreq); // 주파수 설정 + carrier.start(); // 오실레이팅 시작 + + // 종류를 'square(사각형)', 'sine(싸인)' 또는 'triangle(삼각형)'으로 바꿔보세요! + modulator = new p5.Oscillator('sawtooth'); + modulator.start(); + + // 반송파 주파수를 변조하기 위해 변조기의 출력값 더하기 + modulator.disconnect(); + carrier.freq(modulator); + + // 오디오 분석을 위해 FFT 생성하기 + analyzer = new p5.FFT(); + + // 마우스 오버 / 스타트 터치 시, 반송파 페이드 인/아웃 + toggleAudio(cnv); +} + +function draw() { + background(30); + + // 최대 및 최소 주파수 사이의 변조기 주파수에 mouseY를 매핑하기 + let modFreq = map(mouseY, height, 0, modMinFreq, modMaxFreq); + modulator.freq(modFreq); + + // 변조기의 진폭 바꾸기 + // 음수의 amp는 톱니 파형을 반대로 뒤집고, 두드리는 듯한 사운드를 만듭니다. + // + let modDepth = map(mouseX, 0, width, modMinDepth, modMaxDepth); + modulator.amp(modDepth); + + // 파형 분석하기 + waveform = analyzer.waveform(); + + // 파형 그리기 + stroke(255); + strokeWeight(10); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); + + strokeWeight(1); + // 어떤 일이 일어나는 지에 대한 설명을 추가합니다. + text('Modulator Frequency: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text( + 'Modulator Amplitude (Modulation Depth): ' + modDepth.toFixed(3), + 20, + 40 + ); + text( + 'Carrier Frequency (pre-modulation): ' + carrierBaseFreq + ' Hz', + width / 2, + 20 + ); +} + +// 사운드 토글을 위한 helper 함수 +function toggleAudio(cnv) { + cnv.mouseOver(function() { + carrier.amp(1.0, 0.01); + }); + cnv.touchStarted(function() { + carrier.amp(1.0, 0.01); + }); + cnv.mouseOut(function() { + carrier.amp(0.0, 1.0); + }); +} diff --git a/dist/assets/examples/ko/33_Sound/22_AmplitudeModulation.js b/dist/assets/examples/ko/33_Sound/22_AmplitudeModulation.js new file mode 100644 index 0000000000..a45481d22d --- /dev/null +++ b/dist/assets/examples/ko/33_Sound/22_AmplitudeModulation.js @@ -0,0 +1,91 @@ +/** + * @name 진폭 변조(AM) + * @description

진폭 변조(Amplitude Modulation, AM)은 + * 반송파와 변조기라는 두 개의 오실레이터를 포함하고, 이는 반송파의 진폭을 조정합니다.

+ * + *

반송파는 일반적으로 가청 주파수(예. 440Hz)에 설정됩니다. + * 그리고, 그 기본값으로 마스터 출력에 연결되어 있습니다.a + * carrier.amp는 0으로 설정되어 있는데, 이는 변조기로 진폭을 조정하기 위해서입니다.

+ * + *

이 예제에서 변조기는 마스터 출력과 연결이 해제되어 있습니다. + * 대신, 다음을 통해 반송파의 진폭에 연결되어 있습니다: carrier.amp(변조기).

+ * + *

이 예제에서는,

+ *

- MouseX가 변조기의 진폭을 0부터 1까지 조정합니다. + * 변조기 진폭이 0으로 설정되면, 아무런 변조 효과가 발생하지 않습니다.

+ * + *

- MouseY는 변조기의 주파수를 0부터 20hz까지 조정합니다. + * 이 범위는 인간이 들을 수 있는 주파수보다 낮으므로, 우리는 변조 사운드를 리듬으로서 듣게됩니다. + * 이 범위를 사용해 마치 풍금 소리와같은 효과를 만들 수 있습니다. + * 링 변조는 진폭 변조의 한 종류로, 원본 반송파 신호가 존재하지 않고, 더 빠른 주파수를 변조합니다.

+ * + *

로컬 프로젝트에서 이 예제를 실행하려면, + * p5.sound 라이브러리 + * 를 추가해야 됩니다.

+ */ +let carrier; // 이것이 바로 우리가 듣게될 오실레이터입니다. +let modulator; // 이 오실레이터가 반송파 주파수를 변조할 것입니다. +let fft; // 이것을 사용해 파형을 시각화합니다. + +function setup() { + createCanvas(800, 400); + noFill(); + background(30); // 알파값 + + carrier = new p5.Oscillator(); // 기본값으로, 마스터 출력에 연결된 상태입니다. + carrier.freq(340); + carrier.amp(0); + // 반송파의 amp는 기본값으로 0을 가져, 변조기에게 완전한 제어 권한을 부여합니다. + + carrier.start(); + + modulator = new p5.Oscillator('triangle'); + modulator.disconnect(); // 변조기를 마스터 출력과 연결 해제합니다. + modulator.freq(5); + modulator.amp(1); + modulator.start(); + + // 변조기를 사용해 반송파의 진폭을 변조하기 + // 추가적으로, 신호도 조정할 수 있습니다. + carrier.amp(modulator.scale(-1, 1, 1, -1)); + + // 오디오 분석을 위해 FFT 생성하기 + fft = new p5.FFT(); +} + +function draw() { + background(30, 30, 30, 100); // 알파값 + + // 0과 20hz 사이의 변조기 주파수에 mouseY를 매핑하기 + let modFreq = map(mouseY, 0, height, 20, 0); + modulator.freq(modFreq); + + let modAmp = map(mouseX, 0, width, 0, 1); + modulator.amp(modAmp, 0.01); // 페이드 타임을 0.1로 조정하여 페이딩을 부드럽게 만들기 + + // 파형 분석하기 + waveform = fft.waveform(); + + // 파형 그리기 + drawWaveform(); + + drawText(modFreq, modAmp); +} + +function drawWaveform() { + stroke(240); + strokeWeight(4); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); +} + +function drawText(modFreq, modAmp) { + strokeWeight(1); + text('Modulator Frequency: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text('Modulator Amplitude: ' + modAmp.toFixed(3), 20, 40); +} diff --git a/dist/assets/examples/ko/35_Mobile/00_Acceleration_Ball_Bounce.js b/dist/assets/examples/ko/35_Mobile/00_Acceleration_Ball_Bounce.js new file mode 100644 index 0000000000..83902a3de1 --- /dev/null +++ b/dist/assets/examples/ko/35_Mobile/00_Acceleration_Ball_Bounce.js @@ -0,0 +1,58 @@ +/* + * @name 가속도와 바운스 + * @description accelerationX와 accelerationY 값을 활용해 타원을 움직이고, 캔버스의 경계에 닿았을 때 튕기도록 만듭니다. + */ + +// 위치 변수들 +let x = 0; +let y = 0; + +// 속도 변수들 +let vx = 0; +let vy = 0; + +// 가속 변수들 +let ax = 0; +let ay = 0; + +let vMultiplier = 0.007; +let bMultiplier = 0.6; + +function setup() { + createCanvas(displayWidth, displayHeight); + fill(0); +} + +function draw() { + background(255); + ballMove(); + ellipse(x, y, 30, 30); +} + +function ballMove() { + ax = accelerationX; + ay = accelerationY; + + vx = vx + ay; + vy = vy + ax; + y = y + vy * vMultiplier; + x = x + vx * vMultiplier; + + // 캔버스의 경계에 닿았을 때 튕기기 + if (x < 0) { + x = 0; + vx = -vx * bMultiplier; + } + if (y < 0) { + y = 0; + vy = -vy * bMultiplier; + } + if (x > width - 20) { + x = width - 20; + vx = -vx * bMultiplier; + } + if (y > height - 20) { + y = height - 20; + vy = -vy * bMultiplier; + } +} diff --git a/dist/assets/examples/ko/35_Mobile/01_Simple_Draw.js b/dist/assets/examples/ko/35_Mobile/01_Simple_Draw.js new file mode 100644 index 0000000000..de4f128884 --- /dev/null +++ b/dist/assets/examples/ko/35_Mobile/01_Simple_Draw.js @@ -0,0 +1,15 @@ +/* + * @name 간단한 드로잉 + * @description mouseX, mouseY, pmouseX, pmouseY 값을 사용하여 스크린을 터치했을 때 그려지도록 합니다. + */ + +function setup() { + createCanvas(displayWidth, displayHeight); + strokeWeight(10); + stroke(0); +} + +function touchMoved() { + line(mouseX, mouseY, pmouseX, pmouseY); + return false; +} diff --git a/dist/assets/examples/ko/35_Mobile/02_Acceleration_Color.js b/dist/assets/examples/ko/35_Mobile/02_Acceleration_Color.js new file mode 100644 index 0000000000..cecd1bed76 --- /dev/null +++ b/dist/assets/examples/ko/35_Mobile/02_Acceleration_Color.js @@ -0,0 +1,24 @@ +/* + * @name 가속도 색상 + * @description deviceMoved()를 사용해 모바일 기기의 회전을 감지합니다. 배경의 RGB 색상값은 각각 accelerationX, accelerationY, accelerationZ 값에 매핑됩니다. + */ + +let r, g, b; + +function setup() { + createCanvas(displayWidth, displayHeight); + r = random(50, 255); + g = random(0, 200); + b = random(50, 255); +} + +function draw() { + background(r, g, b); + console.log('draw'); +} + +function deviceMoved() { + r = map(accelerationX, -90, 90, 100, 175); + g = map(accelerationY, -90, 90, 100, 200); + b = map(accelerationZ, -90, 90, 100, 200); +} diff --git a/dist/assets/examples/ko/35_Mobile/03_Shake_Ball_Bounce.js b/dist/assets/examples/ko/35_Mobile/03_Shake_Ball_Bounce.js new file mode 100644 index 0000000000..404fae8810 --- /dev/null +++ b/dist/assets/examples/ko/35_Mobile/03_Shake_Ball_Bounce.js @@ -0,0 +1,116 @@ +/* + * @name 흔들기와 바운스 + * @description Ball 클래스를 생성하고 복수의 객체를 인스턴스화한 뒤, 화면 위에서 움직여보세요. + * 공이 캔버스의 경계에 닿으면 튕깁니다. + * accelerationX와 accelerationY의 총 변화를 기반으로 흔들림을 감지하고, + * 그러한 감지를 기반으로 객체의 속도를 높이거나 줄입니다. + */ + +let balls = []; + +let threshold = 30; +let accChangeX = 0; +let accChangeY = 0; +let accChangeT = 0; + +function setup() { + createCanvas(displayWidth, displayHeight); + + for (let i = 0; i < 20; i++) { + balls.push(new Ball()); + } +} + +function draw() { + background(0); + + for (let i = 0; i < balls.length; i++) { + balls[i].move(); + balls[i].display(); + } + + checkForShake(); +} + +function checkForShake() { + // accelerationX와 accelerationY의 총 변화 계산 + accChangeX = abs(accelerationX - pAccelerationX); + accChangeY = abs(accelerationY - pAccelerationY); + accChangeT = accChangeX + accChangeY; + // 만약 흔들린다면, + if (accChangeT >= threshold) { + for (let i = 0; i < balls.length; i++) { + balls[i].shake(); + balls[i].turn(); + } + } + // 만약 흔들리지 않는다면, + else { + for (let i = 0; i < balls.length; i++) { + balls[i].stopShake(); + balls[i].turn(); + balls[i].move(); + } + } +} + +// Ball 클래스 +class Ball { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.xspeed = random(-2, 2); + this.yspeed = random(-2, 2); + this.oxspeed = this.xspeed; + this.oyspeed = this.yspeed; + this.direction = 0.7; + } + + move() { + this.x += this.xspeed * this.direction; + this.y += this.yspeed * this.direction; + } + + // 캔버스 경계에 닿았을 때 공 튀기기 + turn() { + if (this.x < 0) { + this.x = 0; + this.direction = -this.direction; + } else if (this.y < 0) { + this.y = 0; + this.direction = -this.direction; + } else if (this.x > width - 20) { + this.x = width - 20; + this.direction = -this.direction; + } else if (this.y > height - 20) { + this.y = height - 20; + this.direction = -this.direction; + } + } + + // accerlerationX 값의 변화를 기반으로 + // xspeed와 yspeed에 더하기 + shake() { + this.xspeed += random(5, accChangeX / 3); + this.yspeed += random(5, accChangeX / 3); + } + + // 점점 느려지기 + stopShake() { + if (this.xspeed > this.oxspeed) { + this.xspeed -= 0.6; + } else { + this.xspeed = this.oxspeed; + } + if (this.yspeed > this.oyspeed) { + this.yspeed -= 0.6; + } else { + this.yspeed = this.oyspeed; + } + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/ko/35_Mobile/04_Tilted_3D_Box.js b/dist/assets/examples/ko/35_Mobile/04_Tilted_3D_Box.js new file mode 100644 index 0000000000..7479b4c77c --- /dev/null +++ b/dist/assets/examples/ko/35_Mobile/04_Tilted_3D_Box.js @@ -0,0 +1,15 @@ +/* + * @name 기울어진 3D상자 + * @description 모바일 기기를 이용해 상자를 기울게 만듭니다. + */ +function setup() { + createCanvas(displayWidth, displayHeight, WEBGL); +} + +function draw() { + background(250); + normalMaterial(); + rotateX(accelerationX * 0.01); + rotateY(accelerationY * 0.01); + box(100, 100, 100); +} diff --git a/dist/assets/examples/ko/90_Hello_P5/01_shapes.js b/dist/assets/examples/ko/90_Hello_P5/01_shapes.js new file mode 100644 index 0000000000..308d10ed3e --- /dev/null +++ b/dist/assets/examples/ko/90_Hello_P5/01_shapes.js @@ -0,0 +1,28 @@ +/* + * @name 간단한 도형들 + * @description 이 예제는 원, 사각형, 삼각형, 그리고 꽃 모양을 포함합니다. + */ +function setup() { + // 캔버스 만들기 + createCanvas(720, 400); + background(200); + + // 색상 설정하기 + fill(204, 101, 192, 127); + stroke(127, 63, 120); + + // 사각형 한 개 + rect(40, 120, 120, 40); + // 타원 한 개 + ellipse(240, 240, 80, 80); + // 삼각형 한 개 + triangle(300, 100, 320, 100, 310, 80); + + // 간단한 꽃 그리기 + translate(580, 200); + noStroke(); + for (let i = 0; i < 10; i ++) { + ellipse(0, 30, 20, 80); + rotate(PI/5); + } +} diff --git a/dist/assets/examples/ko/90_Hello_P5/02_interactivity.js b/dist/assets/examples/ko/90_Hello_P5/02_interactivity.js new file mode 100644 index 0000000000..95c1733fec --- /dev/null +++ b/dist/assets/examples/ko/90_Hello_P5/02_interactivity.js @@ -0,0 +1,40 @@ +/* + * @name 인터랙티비티 1 + * @frame 720,425 + * @description 원을 클릭하면 색상이 바뀝니다. + *

로컬 프로젝트에서 이 예제를 실행하려면, + * p5.dom 라이브러리. + * 를 추가해야 됩니다.

+ */ + +// 빨강(r), 초록(g), 파랑(b) 색상값들 +let r, g, b; + +function setup() { + createCanvas(720, 400); + // 임의의 색상 고르기 + r = random(255); + g = random(255); + b = random(255); +} + +function draw() { + background(127); + // 원 그리기 + strokeWeight(2); + stroke(r, g, b); + fill(r, g, b, 127); + ellipse(360, 200, 200, 200); +} + +// 사용자가 마우스를 클릭했을 때, +function mousePressed() { + // 마우스가 원의 안쪽에 있는지 확인하기 + let d = dist(mouseX, mouseY, 360, 200); + if (d < 100) { + // 새로운 임의의 색상 고르기 + r = random(255); + g = random(255); + b = random(255); + } +} diff --git a/dist/assets/examples/ko/90_Hello_P5/03_interactivity.js b/dist/assets/examples/ko/90_Hello_P5/03_interactivity.js new file mode 100644 index 0000000000..6a64eec90a --- /dev/null +++ b/dist/assets/examples/ko/90_Hello_P5/03_interactivity.js @@ -0,0 +1,29 @@ +/* + * @name 인터랙티비티 2 + * @frame 720,425 + * @description 슬라이더를 움직이면 원의 색상이 바뀝니다. + * 로컬 프로젝트에서 이 예제를 실행하려면, + * p5.dom 라이브러리 + * 를 추가해야 됩니다. + */ + +// HTML 범위 슬라이더 +let slider; + +function setup() { + createCanvas(720, 400); + // 색조(H), 채도(S), 밝기(B) + colorMode(HSB, 255); + // 슬라이더의 범위를 0부터 255까지로, 그 시작값을 127로 설정하기 + slider = createSlider(0, 255, 127); +} + +function draw() { + background(127); + strokeWeight(2); + + // 슬라이더에 따라 채도 설정하기 + stroke(slider.value(), 255, 255); + fill(slider.value(), 255, 255, 127); + ellipse(360, 200, 200, 200); +} \ No newline at end of file diff --git a/dist/assets/examples/ko/90_Hello_P5/04_animate.js b/dist/assets/examples/ko/90_Hello_P5/04_animate.js new file mode 100644 index 0000000000..f746dd15ea --- /dev/null +++ b/dist/assets/examples/ko/90_Hello_P5/04_animate.js @@ -0,0 +1,33 @@ +/* + * @name 애니메이션 + * @description 원이 움직입니다. + */ +// 원의 위치를 알기 위해 +let x, y; + +function setup() { + createCanvas(720, 400); + // 화면 가운데에서 시작하기 + x = width / 2; + y = height; +} + +function draw() { + background(200); + + // 원 그리기 + stroke(50); + fill(100); + ellipse(x, y, 24, 24); + + // 가로축에서 무작위로 흔들리기 + x = x + random(-1, 1); + // 일정 속도로 위를 향해 움직이기 + y = y - 1; + + // 화면 하단으로 리셋 + if (y < 0) { + y = height; + } +} + diff --git a/dist/assets/examples/ko/90_Hello_P5/04_flocking.js b/dist/assets/examples/ko/90_Hello_P5/04_flocking.js new file mode 100644 index 0000000000..a5b5c9600b --- /dev/null +++ b/dist/assets/examples/ko/90_Hello_P5/04_flocking.js @@ -0,0 +1,186 @@ +/* + * @name 플로킹 + * @description 크레이그 레이놀즈(Craig Reynolds)의 + * "군집(Flocking)" 행위를 묘사합니다.
+ * (규칙: 응집, 분리, 정렬)
+ * (출처: natureofcode.com). + */ +let boids = []; + +function setup() { + createCanvas(720, 400); + + // 시스템에 초기 개체(boid) 더하기 + for (let i = 0; i < 100; i++) { + boids[i] = new Boid(random(width), random(height)); + } +} + +function draw() { + background(51); + // 모든 개체 실행하기 + for (let i = 0; i < boids.length; i++) { + boids[i].run(boids); + } +} + +// Boid 클래스 +// Separation(분리), Cohesion(응집), Alignment(정렬)을 위한 메소드 추가하기 +class Boid { + constructor(x, y) { + this.acceleration = createVector(0, 0); + this.velocity = p5.Vector.random2D(); + this.position = createVector(x, y); + this.r = 3.0; + this.maxspeed = 3; // 최고 속도 + this.maxforce = 0.05; // 최고 조타력 + } + + run(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); + } + + // Force는 acceleration에 담깁니다. + applyForce(force) { + this.acceleration.add(force); + } + + // 세 가지 규칙을 기반으로 새로운 accerlation(가속도)를 축적합니다. + flock(boids) { + let sep = this.separate(boids); // 분리 + let ali = this.align(boids); // 정렬 + let coh = this.cohesion(boids); // 응집 + // 세 힘들을 임의로 가중하기 + sep.mult(2.5); + ali.mult(1.0); + coh.mult(1.0); + // 가속도에 force 벡터 더하기 + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); + } + + // 위치 업데이트를 위한 메소드 + update() { + // 속도 업데이트 + this.velocity.add(this.acceleration); + // 속도 제한 + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // 매 사이클마다 acceleration을 0으로 리셋하기 + this.acceleration.mult(0); + } + + // 목표점을 향한 조타력을 계산하고 적용하는 메소드 + // STEER(조타력) = DESIRED(목표점) - VELOCITY(속도) + seek(target) { + let desired = p5.Vector.sub(target, this.position); // A vector pointing from the location to the target + // desired를 표준화하고 최대 속도로 조정 + desired.normalize(); + desired.mult(this.maxspeed); + // Steering = Desired minus Velocity + let steer = p5.Vector.sub(desired, this.velocity); + steer.limit(this.maxforce); // 최대 조타력으로 제한 + return steer; + } + + // 개체(boid)를 원형으로 그리기 + render() { + fill(127, 127); + stroke(200); + ellipse(this.position.x, this.position.y, 16, 16); + } + + // Wraparound + borders() { + if (this.position.x < -this.r) this.position.x = width + this.r; + if (this.position.y < -this.r) this.position.y = height + this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height + this.r) this.position.y = -this.r; + } + + // 분리 Seperation + // 인근의 개체를 확인하고 이로부터 거리를 유지하며 조타하게 만드는 메소드 + separate(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // 매 개체가 시스템에 생성될 때마다, 서로 너무 가까운 위치에 있는지 여부를 확인 + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + // 만약 그 거리가 0보다 크고 임의의 값보다 작다면(0은 개체의 현위치) + if ((d > 0) && (d < desiredseparation)) { + // 인근의 개체로부터 떨어진 지점을 향하는 벡터 계산 + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // 거리에 따른 가중 + steer.add(diff); + count++; // 개체수 카운트 + } + } + // 평균 -- 얼마로 나눌 것인가 + if (count > 0) { + steer.div(count); + } + + // 벡터가 0보다 크다면, + if (steer.mag() > 0) { + // 레이놀즈의 공식 Steering = Desired - Velocity을 적용한다. + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; + } + + // 배열 Alignment + // 서로 인근에 있는 모든 개체에 대한 평균 속도 계산 + align(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } + } + + // 응집 Cohesion + // 서로 인근에 있는 모든 개체의 평균 위치값(예: 중앙)에 대해, 이 지점을 향한 조타 벡터값 계산 + cohesion(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // 빈 벡터값으로 시작하여 모든 위치들을 축적 + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // 위치 추가 + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // 해당 위치를 향해 조타 + } else { + return createVector(0, 0); + } + } +} + diff --git a/dist/assets/examples/ko/90_Hello_P5/05_weather.js b/dist/assets/examples/ko/90_Hello_P5/05_weather.js new file mode 100644 index 0000000000..c37e41879a --- /dev/null +++ b/dist/assets/examples/ko/90_Hello_P5/05_weather.js @@ -0,0 +1,73 @@ +/* + * @name 날씨 + * @frame 720,280 + * @description 이 예제는 www.metaweather.com로부터 JSON 날씨 데이터를 받아옵니다. + * 로컬 프로젝트에서 이 예제를 실행하려면, + * p5.dom 라이브러리 + * 를 추가해야 됩니다. +*/ + +// 풍향 벡터 +let wind; +// 원의 위치 +let position; + +function setup() { + createCanvas(720, 200); + // www.metaweather.com에 데이터 요청하기 + let url = 'https://cors-anywhere.herokuapp.com/https://www.metaweather.com/api/location/2459115/'; + loadJSON(url, gotWeather); + // 화면의 가운데에서 원그리기 시작 + position = createVector(width/2, height/2); + // 바람은 (0,0)에서 시작 + wind = createVector(); +} + +function draw() { + background(200); + + // 이 섹션에서는 풍향을 나타내는 화살표를 그립니다. + push(); + translate(32, height - 32); + // 바람의 각도에 따라 회전하기 + rotate(wind.heading() + PI/2); + noStroke(); + fill(255); + ellipse(0, 0, 48, 48); + + stroke(45, 123, 182); + strokeWeight(3); + line(0, -16, 0, 16); + + noStroke(); + fill(45, 123, 182); + triangle(0, -18, -6, -10, 6, -10); + pop(); + + // 풍향에 따라 움직이기 + position.add(wind); + + stroke(0); + fill(51); + ellipse(position.x, position.y, 16, 16); + + if (position.x > width) position.x = 0; + if (position.x < 0) position.x = width; + if (position.y > height) position.y = 0; + if (position.y < 0) position.y = height; +} + +function gotWeather(weather) { + let weather_today = weather.consolidated_weather[0] + // 각도 받아오기 (래디언으로 변환) + let angle = radians(Number(weather_today.wind_direction)); + // 풍속 받아오기 + let windmag = Number(weather_today.wind_speed); + + // HTML요소로 화면에 보이기 + let temperatureDiv = createDiv(floor(weather_today.the_temp) + '°C'); + let windDiv = createDiv("WIND " + windmag + " MPH"); + + // 벡터 생성하기 + wind = p5.Vector.fromAngle(angle); +} diff --git a/dist/assets/examples/ko/90_Hello_P5/06_drawing.js b/dist/assets/examples/ko/90_Hello_P5/06_drawing.js new file mode 100644 index 0000000000..db309cbd67 --- /dev/null +++ b/dist/assets/examples/ko/90_Hello_P5/06_drawing.js @@ -0,0 +1,132 @@ +/* +* @name 드로잉 +* @description 제너레이티브 페인팅 프로그램입니다. +*/ + +// 모든 경로 +let paths = []; +// 지금 페인팅을 하고 있나요? +let painting = false; +// 다음 원까지 걸리는 시간 +let next = 0; +// 현재 및 이전 위치 +let current; +let previous; + +function setup() { + createCanvas(720, 400); + current = createVector(0,0); + previous = createVector(0,0); +}; + +function draw() { + background(200); + + // 새로운 점을 만들어 봅시다. + if (millis() > next && painting) { + + // 마우스 위치 받아오기 + current.x = mouseX; + current.y = mouseY; + + // 새로운 파티클의 힘은 마우스의 움직임에 기반을 둡니다. + let force = p5.Vector.sub(current, previous); + force.mult(0.05); + + // 새로운 파티클 더하기 + paths[paths.length - 1].add(current, force); + + // 다음 원의 시간 정하기 + next = millis() + random(100); + + // 더 많은 마우스값 저장하기 + previous.x = current.x; + previous.y = current.y; + } + + // 모든 경로 그리기 + for( let i = 0; i < paths.length; i++) { + paths[i].update(); + paths[i].display(); + } +} + +// 시작하기 +function mousePressed() { + next = 0; + painting = true; + previous.x = mouseX; + previous.y = mouseY; + paths.push(new Path()); +} + +// 정지 +function mouseReleased() { + painting = false; +} + +// Path(경로)는 파티클들의 목록입니다. +class Path { + constructor() { + this.particles = []; + this.hue = random(100); + } + + add(position, force) { + // 새로운 파티클을 그 위치, 힘, 색조값과 함께 추가하기 + this.particles.push(new Particle(position, force, this.hue)); + } + + // 파티클 길이 화면에 보이기 + update() { + for (let i = 0; i < this.particles.length; i++) { + this.particles[i].update(); + } + } + + // 파티클 길이 화면에 보이기 + display() { + // 뒤로 반복하기 + for (let i = this.particles.length - 1; i >= 0; i--) { + // 만약 제거해야 된다면, + if (this.particles[i].lifespan <= 0) { + this.particles.splice(i, 1); + // 그렇지 않다면, 화면에 보이기 + } else { + this.particles[i].display(this.particles[i+1]); + } + } + + } +} + +// 경로 위 파티클들 +class Particle { + constructor(position, force, hue) { + this.position = createVector(position.x, position.y); + this.velocity = createVector(force.x, force.y); + this.drag = 0.95; + this.lifespan = 255; + } + + update() { + // Move it + this.position.add(this.velocity); + // Slow it down + this.velocity.mult(this.drag); + // Fade it out + this.lifespan--; + } + + // 파티클을 그리고 선으로 잇기 + // 다른 파티클을 향해 선그리기 + display(other) { + stroke(0, this.lifespan); + fill(0, this.lifespan/2); + ellipse(this.position.x,this.position.y, 8, 8); + // 선을 그려야 한다면, + if (other) { + line(this.position.x, this.position.y, other.position.x, other.position.y); + } + } +} diff --git a/dist/assets/examples/ko/90_Hello_P5/07_song.js b/dist/assets/examples/ko/90_Hello_P5/07_song.js new file mode 100644 index 0000000000..2c3bbd65ab --- /dev/null +++ b/dist/assets/examples/ko/90_Hello_P5/07_song.js @@ -0,0 +1,118 @@ +/* + * @name 노래 + * @frame 720, 430 + * @description 노래를 재생하세요. + *

로컬 프로젝트에서 이 예제를 실행하려면, + * p5.Sound 라이브러리. + * 를 추가해야 됩니다.

+ */ +// MIDI 음계의 음표들 +let notes = [ 60, 62, 64, 65, 67, 69, 71]; + +let index = 0; +let song = [ + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 200, display: "G" }, + { note: 1, duration: 200, display: "A" }, + { note: 2, duration: 200, display: "B" }, + { note: 3, duration: 200, display: "C" }, + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 400, display: "G" }, + { note: 0, duration: 400, display: "G" } +]; +let trigger = 0; +let autoplay = false; +let osc; + +function setup() { + createCanvas(720, 400); + let div = createDiv("Click to play notes or ") + div.id("instructions"); + let button = createButton("play song automatically."); + button.parent("instructions"); + // 자동 재생 트리거하기 + button.mousePressed(function() { + if (!autoplay) { + index = 0; + autoplay = true; + } + }); + + // 삼각형 오실레이터 + osc = new p5.TriOsc(); + // 무음 시작 + osc.start(); + osc.amp(0); +} + +// 음표를 재생하기 위한 함수 +function playNote(note, duration) { + osc.freq(midiToFreq(note)); + // 음표를 페이드인하기 + osc.fade(0.5,0.2); + + // 만약 재생 시간을 설정한다면, 페이드 아웃 + if (duration) { + setTimeout(function() { + osc.fade(0,0.2); + }, duration-50); + } +} + +function draw() { + + // 만약 현재 자동 재생 중이고 다음 음표를 재생할 때가 되었다면, + if (autoplay && millis() > trigger){ + playNote(notes[song[index].note], song[index].duration); + trigger = millis() + song[index].duration; + // 다음 음표로 이동하기 + index ++; + // 끝에 다다랐다면, 자동 재생 중지 + } else if (index >= song.length) { + autoplay = false; + } + + + // 키보드 그리기 + + // 각 건반의 너비 + let w = width / notes.length; + for (let i = 0; i < notes.length; i++) { + let x = i * w; + // 마우스가 건반 위에 있다면, + if (mouseX > x && mouseX < x + w && mouseY < height) { + // 마우스를 클릭 중이라면, + if (mouseIsPressed) { + fill(100,255,200); + // 또는 마우스가 건반 위를 롤오버 중이라면, + } else { + fill(127); + } + } else { + fill(200); + } + + // 또는, 노래가 재생 중이라면 하이라이트를 줍니다. + if (autoplay && i === song[index-1].note) { + fill(100,255,200); + } + + // 건반 그리기 + rect(x, 0, w-1, height-1); + } + +} + +// 클릭하면, +function mousePressed(event) { + if(event.button == 0 && event.clientX < width && event.clientY < height) { + // 건반 인덱스에 마우스를 매핑하기 + let key = floor(map(mouseX, 0, width, 0, notes.length)); + playNote(notes[key]); + } +} + +// 마우스 버튼을 놓으면 페이드 아웃하기 +function mouseReleased() { + osc.fade(0,0.5); +} diff --git a/dist/assets/examples/zh-Hans/00_Structure/00_Statements_and_Comments.js b/dist/assets/examples/zh-Hans/00_Structure/00_Statements_and_Comments.js new file mode 100644 index 0000000000..8469f369b7 --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/00_Statements_and_Comments.js @@ -0,0 +1,19 @@ +/* + * @name Comments and Statements + * @description Statements are the elements that make up programs. The ";" (semi-colon) symbol is used to end statements. It is called the "statement * terminator". Comments are used for making notes to help people better understand programs. A comment begins with two forward slashes ("//"). (ported from https://processing.org/examples/statementscomments.html) + */ +// The createCanvas function is a statement that tells the computer +// how large to make the window. +// Each function statement has zero or more parameters. +// Parameters are data passed into the function +// and are used as values for telling the computer what to do. +function setup() { + createCanvas(710, 400); +} + +// The background function is a statement that tells the computer +// which color (or gray value) to make the background of the display window +function draw() { + background(204, 153, 0); +} + diff --git a/dist/assets/examples/zh-Hans/00_Structure/01_Coordinates.js b/dist/assets/examples/zh-Hans/00_Structure/01_Coordinates.js new file mode 100644 index 0000000000..5c58c6200a --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/01_Coordinates.js @@ -0,0 +1,29 @@ +/* + * @name 坐标 + * @description 绘制到屏幕上的所有形状都有一个指定为坐标的位置。所有的坐标都是以像素为单位,以距原点的距离来衡量的。原点 [0,0] 是窗口左上角的坐标,右下角的坐标是 [宽度-1, 高度-1] 。 + */ +function setup() { + // 制作一个 720 像素宽 400 像素高的画布。 + createCanvas(720, 400); +} + +function draw() { + // 将背景设置为黑色,关闭填色功能。 + background(0); + noFill(); + + // point() 函数的两个参数分别为指定的坐标。 + // 第一个参数是 x 坐标,第二个参数是 y 。 + stroke(255); + point(width * 0.5, height * 0.5); + point(width * 0.5, height * 0.25); + + // 坐标用于绘制所有形状,而不仅仅是点。 + // 不同功能的参数用于不同的目的。例如,line() 的前两个参数指定第一个端点的坐标,后两个参数指定第二个端点的坐标。 + stroke(0, 153, 255); + line(0, height * 0.33, width, height * 0.33); + + // 默认情况下,rect() 的前两个参数是左上角的坐标,后两个参数是宽度和高度。 + stroke(255, 153, 0); + rect(width * 0.25, height * 0.1, width * 0.5, height * 0.8); +} diff --git a/dist/assets/examples/zh-Hans/00_Structure/02_Width_and_Height.js b/dist/assets/examples/zh-Hans/00_Structure/02_Width_and_Height.js new file mode 100644 index 0000000000..5f1a891658 --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/02_Width_and_Height.js @@ -0,0 +1,18 @@ +/* + * @name Width 和 Height + * @description 'width'(宽度)和 'height'(高度)变量包含 createCanvas() 函数中定义的显示窗口的宽度和高度。 + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(127); + noStroke(); + for (let i = 0; i < height; i += 20) { + fill(129, 206, 15); + rect(0, i, width, 10); + fill(255); + rect(i, 0, 10, height); + } +} diff --git a/dist/assets/examples/zh-Hans/00_Structure/03_Setup_and_Draw.js b/dist/assets/examples/zh-Hans/00_Structure/03_Setup_and_Draw.js new file mode 100644 index 0000000000..db3ea56aff --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/03_Setup_and_Draw.js @@ -0,0 +1,22 @@ +/* + * @name Setup 与 Draw + * @description draw() 函数中的代码从上到下连续运行,直到程序停止。 + */ +let y = 100; + +// 程序开始时,setup() 函数中的语句执行一次。 +function setup() { + // createCanvas 必须是第一条语句 + createCanvas(720, 400); + stroke(255); // 将线条绘制颜色设置为白色 + frameRate(30); +} +// draw() 中的语句一直执行到程序停止为止。每个语句都按顺序执行,并且在读取最后一行之后,将再次执行第一行。 +function draw() { + background(0); // 将背景设置为黑色 + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/zh-Hans/00_Structure/04_No_Loop.js b/dist/assets/examples/zh-Hans/00_Structure/04_No_Loop.js new file mode 100644 index 0000000000..eccf5f6987 --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/04_No_Loop.js @@ -0,0 +1,26 @@ +/* + * @name No Loop + * @description noLoop() 函数使 draw() 只执行一次。 + *如果不调用 noLoop() ,draw() 内的代码会持续运行。 + */ +let y; + +// 程序开始时,setup() 函数中的语句执行一次。 +function setup() { + // createCanvas 必须是第一条语句 + createCanvas(720, 400); + stroke(255); // 线条绘制颜色设置为白色 + noLoop(); + + y = height * 0.5; +} + +// draw() 中的语句一直执行到程序停止为止。每个语句都按顺序执行,并且在读取最后一行之后,将再次执行第一行。 +function draw() { + background(0); // 将背景设置为黑色 + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/zh-Hans/00_Structure/05_Loop.js b/dist/assets/examples/zh-Hans/00_Structure/05_Loop.js new file mode 100644 index 0000000000..df288c8847 --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/05_Loop.js @@ -0,0 +1,21 @@ +/* + * @name Loop + * @description draw() 函数中的代码从上到下连续运行,直到程序停止。 + */ +let y = 100; + +// 程序开始时,setup() 函数中的语句执行一次。 +function setup() { + createCanvas(720, 400); // createCanvas 必须是第一条语句 + stroke(255); // 线条绘制颜色设置为白色 + frameRate(30); +} +// draw() 中的语句一直执行到程序停止为止。每个语句都按顺序执行,并且在读取最后一行之后,将再次执行第一行。 +function draw() { + background(0); // 将背景设置为黑色 + y = y - 1; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} diff --git a/dist/assets/examples/zh-Hans/00_Structure/06_Redraw.js b/dist/assets/examples/zh-Hans/00_Structure/06_Redraw.js new file mode 100644 index 0000000000..39b74e9afd --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/06_Redraw.js @@ -0,0 +1,28 @@ +/* + * @name Redraw + * @description redraw() 函数使 draw() 执行一次。在这个例子中,draw() 将在每次点击鼠标时执行一次。 + */ + +let y; + +// 程序开始时,setup() 函数中的语句执行一次。 +function setup() { + createCanvas(720, 400); + stroke(255); + noLoop(); + y = height * 0.5; +} + +// draw() 中的语句一直执行到程序停止为止。每个语句都按顺序执行,并且在读取最后一行之后,将再次执行第一行。. +function draw() { + background(0); + y = y - 4; + if (y < 0) { + y = height; + } + line(0, y, width, y); +} + +function mousePressed() { + redraw(); +} diff --git a/dist/assets/examples/zh-Hans/00_Structure/07_Functions.js b/dist/assets/examples/zh-Hans/00_Structure/07_Functions.js new file mode 100644 index 0000000000..de8f29d43a --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/07_Functions.js @@ -0,0 +1,26 @@ +/* + *@name 函数 + *@description drawTarget() 函数可以很容易绘制许多不同的目标。每次调用 drawTarget() 都会为每个目标指定环的位置,大小和数量。 + */ + +function setup() { + createCanvas(720, 400); + background(51); + noStroke(); + noLoop(); +} + +function draw() { + drawTarget(width * 0.25, height * 0.4, 200, 4); + drawTarget(width * 0.5, height * 0.5, 300, 10); + drawTarget(width * 0.75, height * 0.3, 120, 6); +} + +function drawTarget(xloc, yloc, size, num) { + const grayvalues = 255 / num; + const steps = size / num; + for (let i = 0; i < num; i++) { + fill(i * grayvalues); + ellipse(xloc, yloc, size - i * steps, size - i * steps); + } +} diff --git a/dist/assets/examples/zh-Hans/00_Structure/08_Recursion.js b/dist/assets/examples/zh-Hans/00_Structure/08_Recursion.js new file mode 100644 index 0000000000..6d5a4a36f0 --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/08_Recursion.js @@ -0,0 +1,27 @@ +/* + *@name 递归 + *@description 递归的一个演示,递归指的的是函数可以调用自身。 + * 注意 drawCircle() 函数是如何在代码块的末尾调用它自身的。 + * 它将继续这样执行直到变量 “level” 等于1。 + */ + +function setup() { + createCanvas(720, 560); + noStroke(); + noLoop(); +} + +function draw() { + drawCircle(width / 2, 280, 6); +} + +function drawCircle(x, radius, level) { + let tt = (126 * level) / 4.0; + fill(tt); + ellipse(x, height / 2, radius * 2, radius * 2); + if (level > 1) { + level = level - 1; + drawCircle(x - radius / 2, radius / 2, level); + drawCircle(x + radius / 2, radius / 2, level); + } +} diff --git a/dist/assets/examples/zh-Hans/00_Structure/09_Create_Graphics.js b/dist/assets/examples/zh-Hans/00_Structure/09_Create_Graphics.js new file mode 100644 index 0000000000..0c341efccc --- /dev/null +++ b/dist/assets/examples/zh-Hans/00_Structure/09_Create_Graphics.js @@ -0,0 +1,27 @@ +/* + * @name Create Graphics + * @description 创建并返回一个新的 p5.Renderer 对象。如果你需要绘制到屏幕外的图形缓冲区,请使用这个种类。这两个参数以像素为单位定义宽度和高度。 + */ + +let pg; + +function setup() { + createCanvas(710, 400); + pg = createGraphics(400, 250); +} + +function draw() { + fill(0, 12); + rect(0, 0, width, height); + fill(255); + noStroke(); + ellipse(mouseX, mouseY, 60, 60); + + pg.background(51); + pg.noFill(); + pg.stroke(255); + pg.ellipse(mouseX - 150, mouseY - 75, 60, 60); + + //使用 image() 将屏幕外的缓冲区绘制到屏幕上 + image(pg, 150, 75); +} diff --git a/dist/assets/examples/zh-Hans/01_Form/00_Points_and_Lines.js b/dist/assets/examples/zh-Hans/01_Form/00_Points_and_Lines.js new file mode 100644 index 0000000000..5344d4bf32 --- /dev/null +++ b/dist/assets/examples/zh-Hans/01_Form/00_Points_and_Lines.js @@ -0,0 +1,35 @@ +/* + * @name Points 与 Lines + * @description Points 与 lines 可用于绘制基本几何。 + * 更改变量 'd' 的值以缩放外形。这四个变量根据 'd' 的值设置位置。 + */ +function setup() { + let d = 70; + let p1 = d; + let p2 = p1 + d; + let p3 = p2 + d; + let p4 = p3 + d; + + // 将屏幕设置为720像素宽,400像素高 + createCanvas(720, 400); + background(0); + noSmooth(); + + translate(140, 0); + + // 绘制灰色的方块 + stroke(153); + line(p3, p3, p2, p3); + line(p2, p3, p2, p2); + line(p2, p2, p3, p2); + line(p3, p2, p3, p3); + + // 绘制白色的点 + stroke(255); + point(p1, p1); + point(p1, p3); + point(p2, p4); + point(p3, p1); + point(p4, p2); + point(p4, p4); +} diff --git a/dist/assets/examples/zh-Hans/01_Form/01_Shape_Primitives.js b/dist/assets/examples/zh-Hans/01_Form/01_Shape_Primitives.js new file mode 100644 index 0000000000..c53599d3f7 --- /dev/null +++ b/dist/assets/examples/zh-Hans/01_Form/01_Shape_Primitives.js @@ -0,0 +1,30 @@ +/* + * @name 基本形状 + * @description 基本形状的原始函数包括 triangle()、 + * rect(), quad()、ellipse() 和 arc()。 方块是通过 rect() 绘制, + * 圆形是通过 ellipse() 来绘制。每个功能都需要一些参数来确定形状的位置和大小。 + */ +function setup() { + // 将屏幕设置为720像素宽,400像素高 + createCanvas(720, 400); + background(0); + noStroke(); + + fill(204); + triangle(18, 18, 18, 360, 81, 360); + + fill(102); + rect(81, 81, 63, 63); + + fill(204); + quad(189, 18, 216, 18, 216, 360, 144, 360); + + fill(255); + ellipse(252, 144, 72, 72); + + fill(204); + triangle(288, 18, 351, 360, 288, 360); + + fill(255); + arc(479, 300, 280, 280, PI, TWO_PI); +} diff --git a/dist/assets/examples/zh-Hans/01_Form/02_Pie_Chart.js b/dist/assets/examples/zh-Hans/01_Form/02_Pie_Chart.js new file mode 100644 index 0000000000..3d22c015b2 --- /dev/null +++ b/dist/assets/examples/zh-Hans/01_Form/02_Pie_Chart.js @@ -0,0 +1,33 @@ +/* + * @name 饼状图 + * @description 使用 arc() 函数,将储存在数组中的数据生成一个饼状图。 + */ +let angles = [30, 10, 45, 35, 60, 38, 75, 67]; + +function setup() { + createCanvas(720, 400); + noStroke(); + noLoop(); // 执行一次之后停止 +} + +function draw() { + background(100); + pieChart(300, angles); +} + +function pieChart(diameter, data) { + let lastAngle = 0; + for (let i = 0; i < data.length; i++) { + let gray = map(i, 0, data.length, 0, 255); + fill(gray); + arc( + width / 2, + height / 2, + diameter, + diameter, + lastAngle, + lastAngle + radians(angles[i]) + ); + lastAngle += radians(angles[i]); + } +} diff --git a/dist/assets/examples/zh-Hans/01_Form/03_Regular_Polygon.js b/dist/assets/examples/zh-Hans/01_Form/03_Regular_Polygon.js new file mode 100644 index 0000000000..fd5c1b36fc --- /dev/null +++ b/dist/assets/examples/zh-Hans/01_Form/03_Regular_Polygon.js @@ -0,0 +1,41 @@ +/* + * @name 正多边形 + * @description 你最喜欢什么形状?五边形?六边形?七边形?都不对?那二十边形呢? + * 因此创建的 polygon() 函数能够绘制任何正多边形。在 draw() 内部,尝试将不同的数字放入 polygon() 以进行探索。 + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + polygon(0, 0, 82, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + polygon(0, 0, 80, 20); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + polygon(0, 0, 70, 7); + pop(); +} + +function polygon(x, y, radius, npoints) { + let angle = TWO_PI / npoints; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius; + let sy = y + sin(a) * radius; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/zh-Hans/01_Form/04_Star.js b/dist/assets/examples/zh-Hans/01_Form/04_Star.js new file mode 100644 index 0000000000..083b8a6b44 --- /dev/null +++ b/dist/assets/examples/zh-Hans/01_Form/04_Star.js @@ -0,0 +1,45 @@ +/* + * @name Star + * @description 此范例中创建的 star() 函数能够绘制各种不同的形式。 + * 在 draw() 内部,尝试将不同的数字放入 star() 以进行探索。 + */ +function setup() { + createCanvas(720, 400); +} + +function draw() { + background(102); + + push(); + translate(width * 0.2, height * 0.5); + rotate(frameCount / 200.0); + star(0, 0, 5, 70, 3); + pop(); + + push(); + translate(width * 0.5, height * 0.5); + rotate(frameCount / 50.0); + star(0, 0, 80, 100, 40); + pop(); + + push(); + translate(width * 0.8, height * 0.5); + rotate(frameCount / -100.0); + star(0, 0, 30, 70, 5); + pop(); +} + +function star(x, y, radius1, radius2, npoints) { + let angle = TWO_PI / npoints; + let halfAngle = angle / 2.0; + beginShape(); + for (let a = 0; a < TWO_PI; a += angle) { + let sx = x + cos(a) * radius2; + let sy = y + sin(a) * radius2; + vertex(sx, sy); + sx = x + cos(a + halfAngle) * radius1; + sy = y + sin(a + halfAngle) * radius1; + vertex(sx, sy); + } + endShape(CLOSE); +} diff --git a/dist/assets/examples/zh-Hans/01_Form/05_Triangle_Strip.js b/dist/assets/examples/zh-Hans/01_Form/05_Triangle_Strip.js new file mode 100644 index 0000000000..651ee3f8e6 --- /dev/null +++ b/dist/assets/examples/zh-Hans/01_Form/05_Triangle_Strip.js @@ -0,0 +1,37 @@ +/* + * @name Triangle Strip + * @description 由 Ira Greenberg 提供的范例。使用 vertex() 函数和 beginShape(TRIANGLE_STRIP) 模式生成闭环。 + * 这个 outsideRadius 和 insideRadius 变量分别控制环的内外半径。 + */ +let x; +let y; +let outsideRadius = 150; +let insideRadius = 100; + +function setup() { + createCanvas(720, 400); + background(204); + x = width / 2; + y = height / 2; +} + +function draw() { + background(204); + + let numPoints = int(map(mouseX, 0, width, 6, 60)); + let angle = 0; + let angleStep = 180.0 / numPoints; + + beginShape(TRIANGLE_STRIP); + for (let i = 0; i <= numPoints; i++) { + let px = x + cos(radians(angle)) * outsideRadius; + let py = y + sin(radians(angle)) * outsideRadius; + angle += angleStep; + vertex(px, py); + px = x + cos(radians(angle)) * insideRadius; + py = y + sin(radians(angle)) * insideRadius; + vertex(px, py); + angle += angleStep; + } + endShape(); +} diff --git a/dist/assets/examples/zh-Hans/01_Form/06_Bezier.js b/dist/assets/examples/zh-Hans/01_Form/06_Bezier.js new file mode 100644 index 0000000000..c5a9db14c0 --- /dev/null +++ b/dist/assets/examples/zh-Hans/01_Form/06_Bezier.js @@ -0,0 +1,26 @@ +/* + * @name Bezier + * @description bezier() 函数的前两个参数指定曲线中的第一个点,后两个参数指定最后一个点。 + * 中间的参数设置定义曲线形状的控制点。 + */ +function setup() { + createCanvas(720, 400); + stroke(255); + noFill(); +} + +function draw() { + background(0); + for (let i = 0; i < 200; i += 20) { + bezier( + mouseX - i / 2.0, + 40 + i, + 410, + 20, + 440, + 300, + 240 - i / 16.0, + 300 + i / 8.0 + ); + } +} diff --git a/dist/assets/examples/zh-Hans/01_Form/07_3D_Primitives.js b/dist/assets/examples/zh-Hans/01_Form/07_3D_Primitives.js new file mode 100644 index 0000000000..65740511da --- /dev/null +++ b/dist/assets/examples/zh-Hans/01_Form/07_3D_Primitives.js @@ -0,0 +1,30 @@ +/* + * @name 基本 3D 形状 + * @frame 720,400 (可选的) + * @description 将数学上的 3D 形体放置在合成空间中。 + * box() 和 sphere() 函数至少使用一个参数来指定它们的大小。 + * 这些形状的位置是由 translate() 函数来定义的。 + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(100); + + noStroke(); + fill(50); + push(); + translate(-275, 175); + rotateY(1.25); + rotateX(-0.9); + box(100); + pop(); + + noFill(); + stroke(255); + push(); + translate(500, height * 0.35, -200); + sphere(300); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/01_Form/08_Trig_Wheels_and_Pie_Chart.js b/dist/assets/examples/zh-Hans/01_Form/08_Trig_Wheels_and_Pie_Chart.js new file mode 100644 index 0000000000..20597a112e --- /dev/null +++ b/dist/assets/examples/zh-Hans/01_Form/08_Trig_Wheels_and_Pie_Chart.js @@ -0,0 +1,88 @@ +/* + * @name Trig Wheels and Pie Chart + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to create +a trig color wheel and a visualization of a population age data as a +pie chart.
+ Functions are +created for the canvas setup, trig color wheel, drawslice, and pie +chart. The size of the slices are determined as well as their color +range. The pie chart is separated by definitive color per value +whereas the trig color wheel has a fixed slice amount with a range +color fill. +*/ + +function setup() { + createCanvas(400, 400); + colorMode(HSB); + angleMode(DEGREES); + + //vars for color wheel center point + let x = width / 2; + let y = height / 2 + 100; + colorWheel(x, y, 100); //slide 11 + + noStroke(); + pieChartPop(200, 100); //slide 12 +} + +//**** slide 12 pie chart trig demo +function pieChartPop(x, y) { + let [total, child, young, adult, senior, elder] = [577, 103, 69, + 122, 170, 113 + ]; + let startValue = 0; + let range = 0; + + //child slice + range = child / total; + drawSlice("blue", x, y, 200, startValue, startValue + range); + startValue += range; + //young slice + range = young / total; + drawSlice("orange", x, y, 200, startValue, startValue + range); + startValue += range; + //adult slice + range = adult / total; + drawSlice("green", x, y, 200, startValue, startValue + range); + startValue += range; + //senior slice + range = senior / total; + drawSlice("tan", x, y, 200, startValue, startValue + range); + startValue += range; + //elder slice + range = elder / total; + drawSlice("pink", x, y, 200, startValue, startValue + range); + startValue += range; + +} + +/** + * drawSlice - draw colored arc based on angle percentages. slide 13 + * Adjust angles so that 0% starts at top (actually -90). + * @param {color} fColor - fill color + * @param {number} x - center x + * @param {number} y - center y + * @param {number} d - diameter + * @param {float} percent1 - starting percentage + * @param {float} percent2 - ending percentage + */ +function drawSlice(fColor, x, y, d, percent1, percent2) { + fill(fColor); + arc(x, y, d, d, -90 + percent1 * 360, -90 + percent2 * 360); +} + +//**** slide 11 trig demo +function colorWheel(x, y, rad) { + strokeWeight(10); + strokeCap(SQUARE); + + //Iterate 360 degrees of lines, +10deg per turn + for (let a = 0; a < 360; a += 10) { + stroke(a, 150, 200); //hue based on a + //radius is 100, angle is a degrees + line(x, y, x + rad * cos(a), + y + rad * sin(a)); + } +} diff --git a/dist/assets/examples/zh-Hans/02_Data/00_Variables.js b/dist/assets/examples/zh-Hans/02_Data/00_Variables.js new file mode 100644 index 0000000000..eb20a466c4 --- /dev/null +++ b/dist/assets/examples/zh-Hans/02_Data/00_Variables.js @@ -0,0 +1,36 @@ +/* + * @name 变量 + * @description 变量用于存储数值。在此示例中,更改变量的值以影响图形构成。 + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(153); + strokeWeight(4); + strokeCap(SQUARE); + + let a = 50; + let b = 120; + let c = 180; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); + + a = a + c; + b = height - b; + + line(a, b, a + c, b); + line(a, b + 10, a + c, b + 10); + line(a, b + 20, a + c, b + 20); + line(a, b + 30, a + c, b + 30); +} diff --git a/dist/assets/examples/zh-Hans/02_Data/01_True_and_False.js b/dist/assets/examples/zh-Hans/02_Data/01_True_and_False.js new file mode 100644 index 0000000000..43076b8f90 --- /dev/null +++ b/dist/assets/examples/zh-Hans/02_Data/01_True_and_False.js @@ -0,0 +1,29 @@ +/* + * @name True 和 False + * @description 布尔变量只有两个可能的值: true 或者 false。 + * 使用控制语句与布尔值来确定程序的流程是很常见的。 + * 在这个范例中, 当布尔值 “b” 为 true 时,绘制垂直线,当布尔值 “b” 为 false 时,绘制水平线。 + */ +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + + let b = false; + let d = 20; + let middle = width / 2; + + for (let i = d; i <= width; i += d) { + b = i < middle; + + if (b === true) { + // 垂直线 + line(i, d, i, height - d); + } + + if (b === false) { + // 水平线 + line(middle, i - middle + d, width - d, i - middle + d); + } + } +} diff --git a/dist/assets/examples/zh-Hans/02_Data/03_Variable_Scope.js b/dist/assets/examples/zh-Hans/02_Data/03_Variable_Scope.js new file mode 100644 index 0000000000..6ede5cf65b --- /dev/null +++ b/dist/assets/examples/zh-Hans/02_Data/03_Variable_Scope.js @@ -0,0 +1,46 @@ +/* + * @name 变量范围 + * @description 变量具有全局或函数“范围”。 + * 例如,在 setup() 或 draw() 函数中声明的变量只能在该函数内使用。 + * 全局变量,在 setup() 和 draw() 之外声明的变量,可以在程序中的任何地方使用。 + * 如果声明的函数变量与全局变量同名,那么程序将使用当前范围内所声明的函数变量进行计算。 + */ +let a = 80; // 创建一个全局变量"a" + +function setup() { + createCanvas(720, 400); + background(0); + stroke(255); + noLoop(); +} + +function draw() { + // 使用全局变量 “a” 绘制一条线 + line(a, 0, a, height); + + for (let a = 120; a < 200; a += 3) { + line(a, 0, a, height); + } + + let a = 300; + // 使用新的本地变量 “a” 画一条线 + line(a, 0, a, height); + + // 调用自定义函数 drawAnotherLine() + drawAnotherLine(); + + // 调用自定义函数 drawYetAnotherLine() + drawYetAnotherLine(); +} + +function drawAnotherLine() { + // 在此函数的本地创建一个新变量 “a” + let a = 320; + // 使用本地变量 “a” 画一条线 + line(a, 0, a, height); +} + +function drawYetAnotherLine() { + // 因为没有设置新的本地变量 “a”,所以该线使用设置为值 20 的原始全局变量 “a” 进行绘制 + line(a + 3, 0, a + 3, height); +} diff --git a/dist/assets/examples/zh-Hans/02_Data/04_Numbers.js b/dist/assets/examples/zh-Hans/02_Data/04_Numbers.js new file mode 100644 index 0000000000..527b88a06f --- /dev/null +++ b/dist/assets/examples/zh-Hans/02_Data/04_Numbers.js @@ -0,0 +1,31 @@ +/* + * @name Numbers + * @frame 720,400 + * @description Numbers can be written with or without decimals. An integer + * (more commonly called an int) is a number without a decimal point. A float + * is a floating-point number, which means it is a number that has a decimal + * place. + */ +let a = 0; // Create a global variable "a" of type Number +let b = 0; // Create a global variable "b" of type Number + +function setup() { + createCanvas(720, 400); + stroke(255); +} + +function draw() { + background(0); + + a = a + 1; // Increment a with an integer + b = b + 0.2; //Increment b with a float + line(a, 0, a, height/2); + line(b, height/2, b, height); + + if(a > width) { + a = 0; + } + if(b > width) { + b = 0; + } +} diff --git a/dist/assets/examples/zh-Hans/03_Arrays/00_Array.js b/dist/assets/examples/zh-Hans/03_Arrays/00_Array.js new file mode 100644 index 0000000000..b9fc89fe59 --- /dev/null +++ b/dist/assets/examples/zh-Hans/03_Arrays/00_Array.js @@ -0,0 +1,40 @@ +/* + * @name 数组 + * @description 数组是数据列表。数组中的每条数据由表示其在数组中的位置的索引号标识。 + * 数组基于零,这意味着数组中的第一个元素是[0],第二个元素是[1],依此类推。 + * 在此示例中,一个名为 “coswave” 的数组被创建并使用余弦值填充。此数据在屏幕上以三种不同的方式显示。 + */ +let coswave = []; + +function setup() { + createCanvas(720, 360); + for (let i = 0; i < width; i++) { + let amount = map(i, 0, width, 0, PI); + coswave[i] = abs(cos(amount)); + } + background(255); + noLoop(); +} + +function draw() { + let y1 = 0; + let y2 = height / 3; + for (let i = 0; i < width; i += 3) { + stroke(coswave[i] * 255); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = y1 + y1; + for (let i = 0; i < width; i += 3) { + stroke((coswave[i] * 255) / 4); + line(i, y1, i, y2); + } + + y1 = y2; + y2 = height; + for (let i = 0; i < width; i += 3) { + stroke(255 - coswave[i] * 255); + line(i, y1, i, y2); + } +} diff --git a/dist/assets/examples/zh-Hans/03_Arrays/01_Array_2d.js b/dist/assets/examples/zh-Hans/03_Arrays/01_Array_2d.js new file mode 100644 index 0000000000..7dc0479a56 --- /dev/null +++ b/dist/assets/examples/zh-Hans/03_Arrays/01_Array_2d.js @@ -0,0 +1,33 @@ +/* + * @name 2D 数组 + * @description 演示创建二维(2D)数组的句法。 2D 数组中的值是通过两个索引值来访问的。 + * 2D 阵列特别适用于对于存储图像。在该示例中,每个点是通过其相对于距图像中心的距离来进行着色的。 + */ +let distances = []; +let maxDistance; +let spacer; + +function setup() { + createCanvas(720, 360); + maxDistance = dist(width / 2, height / 2, width, height); + for (let x = 0; x < width; x++) { + distances[x] = []; // 创建嵌套数组 + for (let y = 0; y < height; y++) { + let distance = dist(width / 2, height / 2, x, y); + distances[x][y] = (distance / maxDistance) * 255; + } + } + spacer = 10; + noLoop(); // 执行一次之后停止 +} + +function draw() { + background(0); + // 这个嵌入式循环基于 spacer 变量跳过数组中的值,因此数组中的值多于此处绘制的值。更改 spacer 变量的值可以更改点的密度 + for (let x = 0; x < width; x += spacer) { + for (let y = 0; y < height; y += spacer) { + stroke(distances[x][y]); + point(x + spacer / 2, y + spacer / 2); + } + } +} diff --git a/dist/assets/examples/zh-Hans/03_Arrays/02_Array_Objects.js b/dist/assets/examples/zh-Hans/03_Arrays/02_Array_Objects.js new file mode 100644 index 0000000000..8197341d8e --- /dev/null +++ b/dist/assets/examples/zh-Hans/03_Arrays/02_Array_Objects.js @@ -0,0 +1,71 @@ +/* + * @name 数组对象 + * @description 演示创建自定义对象数组的句法。 + */ + +class Module { + constructor(xOff, yOff, x, y, speed, unit) { + this.xOff = xOff; + this.yOff = yOff; + this.x = x; + this.y = y; + this.speed = speed; + this.unit = unit; + this.xDir = 1; + this.yDir = 1; + } + + // Custom method for updating the variables + update() { + this.x = this.x + this.speed * this.xDir; + if (this.x >= this.unit || this.x <= 0) { + this.xDir *= -1; + this.x = this.x + 1 * this.xDir; + this.y = this.y + 1 * this.yDir; + } + if (this.y >= this.unit || this.y <= 0) { + this.yDir *= -1; + this.y = this.y + 1 * this.yDir; + } + } + + // Custom method for drawing the object + draw() { + fill(255); + ellipse(this.xOff + this.x, this.yOff + this.y, 6, 6); + } +} + +let unit = 40; +let count; +let mods = []; + +function setup() { + createCanvas(720, 360); + noStroke(); + let wideCount = width / unit; + let highCount = height / unit; + count = wideCount * highCount; + + let index = 0; + for (let y = 0; y < highCount; y++) { + for (let x = 0; x < wideCount; x++) { + mods[index++] = new Module( + x * unit, + y * unit, + unit / 2, + unit / 2, + random(0.05, 0.8), + unit + ); + } + } +} + +function draw() { + background(0); + for (let i = 0; i < count; i++) { + mods[i].update(); + mods[i].draw(); + } +} diff --git a/dist/assets/examples/zh-Hans/03_Arrays/03_Walk_Over_2dArray.js b/dist/assets/examples/zh-Hans/03_Arrays/03_Walk_Over_2dArray.js new file mode 100644 index 0000000000..e5577e7383 --- /dev/null +++ b/dist/assets/examples/zh-Hans/03_Arrays/03_Walk_Over_2dArray.js @@ -0,0 +1,85 @@ +/* + * @name Walk Over 2dArray + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to display 2D array contents on the canvas +using regular for and for-of loops in multiple different ways.
+ A function is created for the canvas, the 2D + array (Friend Array) is initialized and walked over using nested + loops in different ways. Variables x and y are used to place the + array item on the canvas in the form of 2D array. + The final nested loop is used to initialize 2D + array (Fish Array) with random Integers (fish ages). +*/ + + +//"use strict"; //catch some common coding errors + + +/** + * setup : + */ +function setup() { + createCanvas(400, 600); + //create 2D array, slide 4 + let friendArray = [ + ["Nona", "mac & cheese", "orange", "Eid al-fitr"], + ["Marylin", "ice cream", "blue", "Halloween"], + ["Rashaad", "garbage plates", "turquoise", "Christmas"], + ["Ava", "sushi", "pink", "New Years"] + ]; + friendArray.push(["Xavier", "Louisiana creole", "red", "their birthday"]); + + //walking 2D array, slide 6 + let y = 20; // Start row based on text size of 20 + for (let f = 0; f < friendArray.length; f++) { // outer array + let x = 10; // Start item in this row + for (let t = 0; t < friendArray[f].length; t++) { //inner + text(friendArray[f][t], x, y); + x += textWidth(friendArray[f][t]) + 20; //place next item + } + y += 28; // place next row + } + + //walking 2D array, variation on slide 6 + //with embedded arithmetic for y + // + for (let f = 0; f < friendArray.length; f++) { // outer array + let x = 10; // Start item in this row + for (let t = 0; t < friendArray[f].length; t++) { //inner + //y is v-padding + LCV * v-spacing + text(friendArray[f][t], x, 200 + f * 28); + x += textWidth(friendArray[f][t]) + 20; //place next item + } + } + + //walking 2D array, slide 7 + //need to use x and y variables to manage canvas placement + y = 400; + for (let friend of friendArray) { + let x = 10; // Start item in this row + console.log("x and y", x, y); + console.log("friend:", friend); + for (let item of friend) { + console.log("item & x:", item, x); + text(item, x, y); + x += textWidth(item) + 20; //place next item + } + y += 28; // place next row + } + + //slide 9, creating 2D array: schools of fish ages + console.log("\n *** Fish ages in 2D ***"); + const schools = []; + //4 schools of fish + for (let t = 0; t < 4; t++) { + schools[t] = []; //initialize this school + console.log("schools[t]?", t, schools[t]); + + // Add 10 randomized ages to the array + for (let a = 0; a < 10; a++) { + schools[t].push(round(random(1, 5))); + } + } + console.log(schools); + } diff --git a/dist/assets/examples/zh-Hans/04_Control/00_Iteration.js b/dist/assets/examples/zh-Hans/04_Control/00_Iteration.js new file mode 100644 index 0000000000..8b159065a0 --- /dev/null +++ b/dist/assets/examples/zh-Hans/04_Control/00_Iteration.js @@ -0,0 +1,41 @@ +/* + * @name 迭代 + * @description 用 “for” 结构迭代来构造重复的形式。 + */ +let y; +let num = 14; + +function setup() { + createCanvas(720, 360); + background(102); + noStroke(); + + // 画白条 + fill(255); + y = 60; + for (let i = 0; i < num / 3; i++) { + rect(50, y, 475, 10); + y += 20; + } + + // 灰条 + fill(51); + y = 40; + for (let i = 0; i < num; i++) { + rect(405, y, 30, 10); + y += 20; + } + y = 50; + for (let i = 0; i < num; i++) { + rect(425, y, 30, 10); + y += 20; + } + + // 细线 + y = 45; + fill(0); + for (let i = 0; i < num - 1; i++) { + rect(120, y, 40, 1); + y += 20; + } +} diff --git a/dist/assets/examples/zh-Hans/04_Control/01_Embedded_Iteration.js b/dist/assets/examples/zh-Hans/04_Control/01_Embedded_Iteration.js new file mode 100644 index 0000000000..5d6f06b7a9 --- /dev/null +++ b/dist/assets/examples/zh-Hans/04_Control/01_Embedded_Iteration.js @@ -0,0 +1,21 @@ +/* + * @name 嵌入式迭代 + * @description 嵌入 “for” 结构允许在两个维度上进行重复。 + */ +function setup() { + createCanvas(720, 360); + background(0); + noStroke(); + + let gridSize = 35; + + for (let x = gridSize; x <= width - gridSize; x += gridSize) { + for (let y = gridSize; y <= height - gridSize; y += gridSize) { + noStroke(); + fill(255); + rect(x - 1, y - 1, 3, 3); + stroke(255, 50); + line(x, y, width / 2, height / 2); + } + } +} diff --git a/dist/assets/examples/zh-Hans/04_Control/02_Conditionals_1.js b/dist/assets/examples/zh-Hans/04_Control/02_Conditionals_1.js new file mode 100644 index 0000000000..7b18dd559f --- /dev/null +++ b/dist/assets/examples/zh-Hans/04_Control/02_Conditionals_1.js @@ -0,0 +1,22 @@ +/* + * @name 条件 1 + * @description 条件就像问题。 + * 如果问题的答案为真值,它们允许程序决定采取一个动作;如果问题的答案为假值,则允许程序执行另一个动作。 + * 程序中提出的问题始终是逻辑或关系语句。例如,如果变量 'i' 等于零,则绘制一条线。 + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 10; i < width; i += 10) { + // If 'i' divides by 20 with no remainder draw the first line + // else draw the second line + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + } else { + stroke(153); + line(i, 20, i, 180); + } + } +} diff --git a/dist/assets/examples/zh-Hans/04_Control/03_Conditionals_2.js b/dist/assets/examples/zh-Hans/04_Control/03_Conditionals_2.js new file mode 100644 index 0000000000..07b7949161 --- /dev/null +++ b/dist/assets/examples/zh-Hans/04_Control/03_Conditionals_2.js @@ -0,0 +1,25 @@ +/* + * @name 条件 2 + * @description 我们通过添加关键字 “else” 来扩展前一个示例中的条件语言。 + * 这允许条件连续提出两个或更多个问题,每个问题都有不同的操作。 + */ +function setup() { + createCanvas(720, 360); + background(0); + + for (let i = 2; i < width - 2; i += 4) { + // 如果 'i' 除以 20 而没有余数 + if (i % 20 === 0) { + stroke(255); + line(i, 80, i, height / 2); + // 如果 'i' 除以 10 而没有余数 + } else if (i % 10 === 0) { + stroke(153); + line(i, 20, i, 180); + // 如果上述两个条件都不满足,则绘制这条线 + } else { + stroke(102); + line(i, height / 2, i, height - 20); + } + } +} diff --git a/dist/assets/examples/zh-Hans/04_Control/04_Logical_Operators.js b/dist/assets/examples/zh-Hans/04_Control/04_Logical_Operators.js new file mode 100644 index 0000000000..f4b5d1394c --- /dev/null +++ b/dist/assets/examples/zh-Hans/04_Control/04_Logical_Operators.js @@ -0,0 +1,41 @@ +/* + * @name 逻辑操作符 + * @description AND(&&)和 OR(||)的逻辑操作符被用于将简单的关系语句组合成更复杂的表达式 + * NOT (!) 操作符被用于否定布尔语句。 + */ +let test = false; + +function setup() { + createCanvas(720, 360); + background(126); + + for (let i = 5; i <= height; i += 5) { + // 逻辑 AND + stroke(0); + if (i > 35 && i < 100) { + line(width / 4, i, width / 2, i); + test = false; + } + + // 逻辑 OR + stroke(76); + if (i <= 35 || i >= 100) { + line(width / 2, i, width, i); + test = true; + } + + // 测试布尔值是否为 “true” + // 表达式 “if(test)” 等同于 "if(test == true)" + if (test) { + stroke(0); + point(width / 3, i); + } + + // 测试布尔值是否为 "false" + // 表达式 “if(test)” 等同于 "if(test == false)" + if (!test) { + stroke(255); + point(width / 4, i); + } + } +} diff --git a/dist/assets/examples/zh-Hans/04_Control/05_Logical_Operators_2.js b/dist/assets/examples/zh-Hans/04_Control/05_Logical_Operators_2.js new file mode 100644 index 0000000000..2684feb956 --- /dev/null +++ b/dist/assets/examples/zh-Hans/04_Control/05_Logical_Operators_2.js @@ -0,0 +1,91 @@ +/* + * @name Logical Operators 2 + * @frame 400,400 + * @description contributed by + Prof WM Harris, How + to create Xboxes with one global variable and create conditions with + boolean variables and boolean expressions by utilizing Boolean + operators ||, &&, and ! to do boundary checking.
+ Functions + are created for both the canvas set up as well as the creation of + the boxes. Background color is dependent on the location of the + boxes in the canvas space. When mouse button and key are pressed + simultaneously, the “where” text and box color changes to cyan, + but if the mouse button is clicked alone then the animation will + start. When q or Q are pressed the text “Did you type q or Q?” + will change to blue, else it will be purple. If the mouse is placed + within the orange box containing the text, “withinRect” then the + shape will turn pink. + */ + + +//1 coordinate for everything :) +let where = 0; //control boxes' positions + +function setup() { + createCanvas(400, 400); +} + +function draw() { + //similar to slide 4 use of OR, || + //to set bg color of canvas + if ((where < 0) || (where > height)) { + background("beige"); + } else { + background("chocolate"); + } + + //similar to slide 4 use of AND, && + //to set fill color of box & text + if (mouseIsPressed && keyIsPressed) { + fill("cyan"); + } else { + fill(255); + } + + //boxL + rect(where, where, 40); + + //boxR, pad x coordinate for size of box + rect(width - where - 40, where, 40); + + //Move the boxes + where = where + 1; + + //Show the value of where the boxes are + text("where is " + where, 150, 30); + + //testing not, ! and or, || operators + if (!(key === "q" || key === "Q")) { + fill("purple"); + } else { + fill("dodgerBlue"); + } + //Show the current key value + text("Did you type a q or Q? " + key, 150, 70); + + //*** Boundary checking *** + //Is the mouse within rect boundary? + //left, right, top, bottom + let withinRect = (mouseX >= 150) && + (mouseX <= 150 + 100) && + (mouseY >= 300) && + (mouseY <= 300 + 40); + //fill color based on value of withinRect + if (withinRect) { + fill("pink"); + } else { + fill("orange"); + } + //draw the rect + rect(150, 300, 100, 40); + //show withinRect value as label on rect + fill(0); + text("withinRect " + withinRect, 160, 320); +} + +//boxes restart +function mousePressed() { + //Reset boxes back up and above the canvas + where = -50; +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/04_Control/06_Conditional_Shapes.js b/dist/assets/examples/zh-Hans/04_Control/06_Conditional_Shapes.js new file mode 100644 index 0000000000..8d544e9081 --- /dev/null +++ b/dist/assets/examples/zh-Hans/04_Control/06_Conditional_Shapes.js @@ -0,0 +1,48 @@ +/* + * @name Conditional Shapes + * @frame 400,400 + * @description contributed by + Prof WM Harris, How + to draw different shapes mid canvas depending on the mouse position.
+ Functions + are created for the main canvas set up with the markers on the left and + right hand sides. One is also created for the location of the mouse + regarding the canvas and the markers. If the mouse is within the + outer left hand beige rectangle, then the shape of circle is drawn + down the center of the canvas. If the mouse is within the outer right + hand beige rectangle, then the shape of square is drawn down the + center of the canvas. +*/ +function setup() { + createCanvas(400, 400); + strokeWeight(3); + //center squares to match circles + rectMode(CENTER); + + //draw rects to mark far sides + noStroke(); + fill("beige"); + rect(5, height / 2, 10, height); + rect(width - 5, height / 2, 10, height); + fill("orange"); + stroke("brown"); + + } + + function draw() { + point(mouseX, mouseY); + + //if (test) {doThis; } + //test: mouseX on far left of canvas + //doThis: draw a circle at mouseY + if (mouseX < 10) { + circle(width / 2, mouseY, 20); + } + + //test: mouseX on far right of canvas + //doThis: draw a square at mouseY + if (mouseX > width - 10) { + square(width / 2, mouseY, 20); + } + + } diff --git a/dist/assets/examples/zh-Hans/05_Image/00_Load_and_Display_Image.js b/dist/assets/examples/zh-Hans/05_Image/00_Load_and_Display_Image.js new file mode 100644 index 0000000000..59b19f0c9e --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/00_Load_and_Display_Image.js @@ -0,0 +1,20 @@ +/* + * @name 加载(Load)和显示(Display)图像 + * @description 图像可以以原图大小或自定义大小被加载和显示。 + *

要在本地运行此范例,您需要一个图像文件,并运行在 + * 本地伺服器上。

+ + */ +let img; // 声明变量 'img' + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // 加载图像 +} + +function draw() { + // 在坐标(0, 0),显示原图大小的图像 + image(img, 0, 0); + // 在坐标(0, 高度/2),显示一半原图大小的图像 + image(img, 0, height / 2, img.width / 2, img.height / 2); +} diff --git a/dist/assets/examples/zh-Hans/05_Image/01_Background_Image.js b/dist/assets/examples/zh-Hans/05_Image/01_Background_Image.js new file mode 100644 index 0000000000..56961d73b8 --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/01_Background_Image.js @@ -0,0 +1,28 @@ +/* + * @name 背景图像 + * @description 此范例展示了最快加载背景图像的方法。 + * 若需将一张图像作为背景,它必须和程序有相同的宽度和高度。 + *

要在本地运行此示例,您需要一个图像文件,并运行在 + * 本地伺服器上。

+ */ +let bg; +let y = 0; + +function setup() { + // 背景图像的大小必须和 createCanvas() 函数中的参数一样。 + // 该图像大小为 720x400 像素。 + bg = loadImage('assets/moonwalk.jpg'); + createCanvas(720, 400); +} + +function draw() { + background(bg); + + stroke(226, 204, 0); + line(0, y, width, y); + + y++; + if (y > height) { + y = 0; + } +} diff --git a/dist/assets/examples/zh-Hans/05_Image/02_Transparency.js b/dist/assets/examples/zh-Hans/05_Image/02_Transparency.js new file mode 100644 index 0000000000..db8141aa46 --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/02_Transparency.js @@ -0,0 +1,23 @@ +/* + * @name 透明度 + * @description 左右移动指针(光标)来改变图像位置 + * 此程序为一张图像叠加在另一张上,通过tint() 函数来改变它的透明度值(alpha value)。 + *

要在本地运行此范例,您需要一个图像文件,并运行在 + * 本地伺服器上。

+ */ +let img; +let offset = 0; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + img = loadImage('assets/moonwalk.jpg'); // 加载图像 +} + +function draw() { + image(img, 0, 0); // 完全不透明 + let dx = mouseX - img.width / 2 - offset; + offset += dx * easing; + tint(255, 127); // 半透明 + image(img, offset, 0); +} diff --git a/dist/assets/examples/zh-Hans/05_Image/03_Alpha_Mask.js b/dist/assets/examples/zh-Hans/05_Image/03_Alpha_Mask.js new file mode 100644 index 0000000000..6e9f5ab201 --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/03_Alpha_Mask.js @@ -0,0 +1,28 @@ +/* + * @name 透明度遮罩 (Alpha Mask) + * @description 在图像上加载一个遮罩来改变图像中不同位置的透明度。 + * 通过拍p5.Image 中的mask() 函数来混合两张图像(图像和遮罩)。 + *

要在本地运行此范例,您需要一个图像文件,并运行在 + * 本地伺服器上。

+ */ +let img; +let imgMask; + +function preload() { + // 加载图像及图像遮罩 + img = loadImage('assets/moonwalk.jpg'); + imgMask = loadImage('assets/mask.png'); +} + +function setup() { + createCanvas(720, 400); + // mask() 函数将图像遮罩覆盖在图像上 + img.mask(imgMask); + imageMode(CENTER); +} + +function draw() { + background(0, 102, 153); + image(img, width / 2, height / 2); + image(img, mouseX, mouseY); +} diff --git a/dist/assets/examples/zh-Hans/05_Image/04_Create_Image.js b/dist/assets/examples/zh-Hans/05_Image/04_Create_Image.js new file mode 100644 index 0000000000..f9e6a1ee0e --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/04_Create_Image.js @@ -0,0 +1,30 @@ +/* + * @name 创建图像 + * @description createImage() 函数能让我们巧妙地操控一个像素缓冲区。 此范例创建了一个渐变图像。 + */ +let img; // 声明变量 'img' + +function setup() { + createCanvas(720, 400); + // 设置图像大小 230x230 像素 + img = createImage(230, 230); + + // 将显示窗口的像素资料加载到 pixels[] 数组里 + // 这函数必须在读写 pixels[] 之前被调用 + img.loadPixels(); + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + let a = map(y, 0, img.height, 255, 0); + // 使用 set() 设置该位置像素的颜色 + img.set(x, y, [0, 153, 204, a]); + } + } + // 使用 set() 后,必须调用updatePixels() 以使改变生效 + img.updatePixels(); +} + +function draw() { + background(0); + image(img, 90, 80); + image(img, mouseX - img.width / 2, mouseY - img.height / 2); +} diff --git a/dist/assets/examples/zh-Hans/05_Image/05_Pointillism.js b/dist/assets/examples/zh-Hans/05_Image/05_Pointillism.js new file mode 100644 index 0000000000..3e524f4276 --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/05_Pointillism.js @@ -0,0 +1,43 @@ +/* + * @name 点画(Pointillism) + * @description 作者:Dan Shiffman。 + * 鼠标水平位置控制点的大小,由左到右对应由小到大的点。 + * 通过带有原图像素颜色的椭圆创建出一副简单的点画。 + *

要在本地运行此范例,您需要一个图像文件,并运行在 + * 本地伺服器上。

+ */ +// 声明变量 'img', 'smallPoint', 'largePoing' +let img; +let smallPoint, largePoint; + +function preload() { + // 加载图像 + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 400); + // 设置最小点宽度为 4,最大点宽度为 40 + smallPoint = 4; + largePoint = 40; + imageMode(CENTER); + noStroke(); + // 设置背景颜色为白色 + background(255); + img.loadPixels(); +} + +function draw() { + // map() 函数根据鼠标水平位置, + // 将其在 [0, 画布宽度] 的数值对应到 [最小点宽度, 最大点宽度] ([4,40]) 之中, + // 对应的数值即为点的大小 + let pointillize = map(mouseX, 0, width, smallPoint, largePoint); + // 随机生成坐标 (x, y) + let x = floor(random(img.width)); + let y = floor(random(img.height)); + // 得到图像中坐标 (x, y) 的颜色 + let pix = img.get(x, y); + // fill(灰度值,透明度值) + fill(pix, 128); + ellipse(x, y, pointillize, pointillize); +} diff --git a/dist/assets/examples/zh-Hans/05_Image/06_Blur.js b/dist/assets/examples/zh-Hans/05_Image/06_Blur.js new file mode 100644 index 0000000000..2374bc0345 --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/06_Blur.js @@ -0,0 +1,89 @@ +/* + * @name Blur + * @description A low-pass filter that blurs an image. This program analyzes every pixel in an image and blends it with all the neighboring pixels to blur the image. + *

This example is ported from the Blur example + * on the Processing website + */ +// to consider all neighboring pixels we use a 3x3 array +// and normalize these values +// v is the normalized value +let v = 1.0 / 9.0; +// kernel is the 3x3 matrix of normalized values +let kernel = [[ v, v, v ], [ v, v, v ], [ v, v, v ]]; + +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// if loadImage() is called in setup(), the image won't appear +// since noLoop() restricts draw() to execute only once +// (one execution of draw() is not enough time for the image to load), +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover.png"); +} + +// setup() runs once after preload +function setup() { + // create canvas + createCanvas(710, 400); + // noLoop() makes draw() run only once, not in a loop + noLoop(); +} + + +// draw() runs after setup(), normally on a loop +// in this case it runs only once, because of noDraw() +function draw() { + // place the original image on the upper left corner + image(img, 0, 0); + + // create a new image, same dimensions as img + edgeImg = createImage(img.width, img.height); + + // load its pixels + edgeImg.loadPixels(); + + // two for() loops, to iterate in x axis and y axis + // since the kernel assumes that the pixel + // has pixels above, under, left, and right + // we need to skip the first and last column and row + // x then goes from 1 to width - 1 + // y then goes from 1 to height - 1 + for (let x = 1; x < img.width; x++) { + for (let y = 1; y < img.height; y++) { + // kernel sum for the current pixel starts as 0 + let sum = 0; + + // kx, ky variables for iterating over the kernel + // kx, ky have three different values: -1, 0, 1 + for (kx = -1; kx <= 1; kx++) { + for (ky = -1; ky <= 1; ky++) { + let xpos = x + kx; + let ypos = y + ky; + + // since our image is grayscale, + // RGB values are identical + // we retrieve the red value for this example + // (green and blue work as well) + let val = red(img.get(xpos, ypos)); + + // accumulate the kernel sum + // kernel is a 3x3 matrix + // kx and ky have values -1, 0, 1 + // if we add 1 to kx and ky, we get 0, 1, 2 + // with that we can use it to iterate over kernel + // and calculate the accumulated sum + sum += kernel[kx+1][ky+1] * val; + } + } + + // set the value of the edgeImg pixel to the kernel sum + edgeImg.set(x, y, color(sum)); + } + } + // updatePixels() to write the changes on edgeImg + edgeImg.updatePixels(); + + // draw edgeImg at the right of the original image + image(edgeImg, img.width, 0); +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/05_Image/07_EdgeDetection.js b/dist/assets/examples/zh-Hans/05_Image/07_EdgeDetection.js new file mode 100644 index 0000000000..2c0509d44b --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/07_EdgeDetection.js @@ -0,0 +1,93 @@ +/* + * @name Edge Detection + * @description A high-pass filter sharpens an image. This program analyzes every pixel in an image in relation to the neighboring pixels to sharpen the image. + *

This example is ported from the Edge Detection example + * on the Processing website + */ +// this program analyzes every pixel in an image +// in relation to the neighbouring pixels +// to sharpen the image + +// to consider all neighboring pixels we use a 3x3 array +// and normalize these values +// kernel is the 3x3 matrix of normalized values +let kernel = [[-1, -1, -1 ], [ -1, 9, -1 ], [-1, -1, -1 ]]; + +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// if loadImage() is called in setup(), the image won't appear +// since noLoop() restricts draw() to execute only once +// (one execution of draw() is not enough time for the image to load), +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover.png"); +} + +// setup() runs after preload, once() +function setup() { + // create canvas + createCanvas(710, 400); + // noLoop() makes draw() run only once, not in a loop + noLoop(); +} + +// draw() runs after setup(), normally on a loop +// in this case it runs only once, because of noDraw() +function draw() { + + // place the original image on the upper left corner + image(img, 0, 0); + + // create a new image, same dimensions as img + edgeImg = createImage(img.width, img.height); + + // load its pixels + edgeImg.loadPixels(); + + + // two for() loops, to iterate in x axis and y axis + // since the kernel assumes that the pixel + // has pixels above, under, left, and right + // we need to skip the first and last column and row + // x then goes from 1 to width - 1 + // y then goes from 1 to height - 1 + + for (let x = 1; x < img.width - 1; x++) { + for (let y = 1; y < img.height - 1; y++) { + // kernel sum for the current pixel starts as 0 + let sum = 0; + + // kx, ky variables for iterating over the kernel + // kx, ky have three different values: -1, 0, 1 + for (kx = -1; kx <= 1; kx++) { + for (ky = -1; ky <= 1; ky++) { + + let xpos = x + kx; + let ypos = y + ky; + let pos = (y + ky)*img.width + (x + kx); + // since our image is grayscale, + // RGB values are identical + // we retrieve the red value for this example + let val = red(img.get(xpos, ypos)); + // accumulate the kernel sum + // kernel is a 3x3 matrix + // kx and ky have values -1, 0, 1 + // if we add 1 to kx and ky, we get 0, 1, 2 + // with that we can use it to iterate over kernel + // and calculate the accumulated sum + sum += kernel[ky+1][kx+1] * val; + } + } + + // set the pixel value of the edgeImg + edgeImg.set(x, y, color(sum, sum, sum)); + } + } + + // updatePixels() to write the changes on edgeImg + edgeImg.updatePixels(); + + // draw edgeImg at the right of the original image + image(edgeImg, img.width, 0); +} diff --git a/dist/assets/examples/zh-Hans/05_Image/08_Brightness.js b/dist/assets/examples/zh-Hans/05_Image/08_Brightness.js new file mode 100644 index 0000000000..3c58a98876 --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/08_Brightness.js @@ -0,0 +1,63 @@ +/* + * @name Brightness + * @description This program adjusts the brightness of a part of the image by calculating the distance of each pixel to the mouse. + *

This example is ported from the Brightness example + * on the Processing website + */ +// This program adjusts the brightness +// of a part of the image by +// calculating the distance of +// each pixel to the mouse. +let img; +// preload() runs once, before setup() +// loadImage() needs to occur here instead of setup() +// preload() makes sure image is loaded before anything else occurs +function preload() { + // load the original image + img = loadImage("assets/rover_wide.jpg"); +} +// setup() runs after preload, once() +function setup() { + createCanvas(710, 400); + pixelDensity(1); + frameRate(30); +} + +function draw() { + image(img,0,0); + // Only need to load the pixels[] array once, because we're only + // manipulating pixels[] inside draw(), not drawing shapes. + loadPixels(); + // We must also call loadPixels() on the PImage since we are going to read its pixels. + img.loadPixels(); + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++ ) { + // Calculate the 1D location from a 2D grid + let loc = (x + y*img.width)*4; + // Get the R,G,B values from image + let r,g,b; + r = img.pixels[loc]; + // g = img.pixels[loc+1]; + // b = img.pixels[loc+2]; + // Calculate an amount to change brightness based on proximity to the mouse + // The closer the pixel is to the mouse, the lower the value of "distance" + let maxdist = 50;//dist(0,0,width,height); + let d = dist(x, y, mouseX, mouseY); + let adjustbrightness = 255*(maxdist-d)/maxdist; + r += adjustbrightness; + // g += adjustbrightness; + // b += adjustbrightness; + // Constrain RGB to make sure they are within 0-255 color range + r = constrain(r, 0, 255); + // g = constrain(g, 0, 255); + // b = constrain(b, 0, 255); + // Make a new color and set pixel in the window + let pixloc = (y*width + x)*4; + pixels[pixloc] = r; + pixels[pixloc+1] = r; + pixels[pixloc+2] = r; + pixels[pixloc+3] = 255; // Always have to set alpha + } + } + updatePixels(); +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/05_Image/09_Convolution.js b/dist/assets/examples/zh-Hans/05_Image/09_Convolution.js new file mode 100644 index 0000000000..eb953c6729 --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/09_Convolution.js @@ -0,0 +1,91 @@ +/* + * @name Convolution + * @description Applies a convolution matrix to a portion of an image. Move mouse to apply filter to different parts of the image. This example is a port of Dan Shiffman's example for Processing. Original comments written by Dan unless otherwise specified. + *

To run this example locally, you will need an + * image file, and a running + * local server.

+ */ + +let img; +let w = 80; + +// It's possible to convolve the image with many different +// matrices to produce different effects. This is a high-pass +// filter; it accentuates the edges. +const matrix = [ [ -1, -1, -1 ], + [ -1, 9, -1 ], + [ -1, -1, -1 ] ]; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 400); + img.loadPixels(); + + // pixelDensity(1) for not scaling pixel density to display density + // for more information, check the reference of pixelDensity() + pixelDensity(1); +} + +function draw() { + // We're only going to process a portion of the image + // so let's set the whole image as the background first + background(img); + + // Calculate the small rectangle we will process + const xstart = constrain(mouseX - w/2, 0, img.width); + const ystart = constrain(mouseY - w/2, 0, img.height); + const xend = constrain(mouseX + w/2, 0, img.width); + const yend = constrain(mouseY + w/2, 0, img.height); + const matrixsize = 3; + + loadPixels(); + // Begin our loop for every pixel in the smaller image + for (let x = xstart; x < xend; x++) { + for (let y = ystart; y < yend; y++ ) { + let c = convolution(x, y, matrix, matrixsize, img); + + // retrieve the RGBA values from c and update pixels() + let loc = (x + y*img.width) * 4; + pixels[loc] = red(c); + pixels[loc + 1] = green(c); + pixels[loc + 2] = blue(c); + pixels[loc + 3] = alpha(c); + } + } + updatePixels(); +} + +function convolution(x, y, matrix, matrixsize, img) { + let rtotal = 0.0; + let gtotal = 0.0; + let btotal = 0.0; + const offset = Math.floor(matrixsize / 2); + for (let i = 0; i < matrixsize; i++){ + for (let j = 0; j < matrixsize; j++){ + + // What pixel are we testing + const xloc = (x + i - offset); + const yloc = (y + j - offset); + let loc = (xloc + img.width * yloc) * 4; + + // Make sure we haven't walked off our image, we could do better here + loc = constrain(loc, 0 , img.pixels.length - 1); + + // Calculate the convolution + // retrieve RGB values + rtotal += (img.pixels[loc]) * matrix[i][j]; + gtotal += (img.pixels[loc + 1]) * matrix[i][j]; + btotal += (img.pixels[loc + 2]) * matrix[i][j]; + } + } + // Make sure RGB is within range + rtotal = constrain(rtotal, 0, 255); + gtotal = constrain(gtotal, 0, 255); + btotal = constrain(btotal, 0, 255); + + // Return the resulting color + return color(rtotal, gtotal, btotal); +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/05_Image/10_Copy_Method.js b/dist/assets/examples/zh-Hans/05_Image/10_Copy_Method.js new file mode 100644 index 0000000000..0e7f9431e5 --- /dev/null +++ b/dist/assets/examples/zh-Hans/05_Image/10_Copy_Method.js @@ -0,0 +1,20 @@ +/* + * @name Copy() 函数 + * @frame 600,400 + * @description 一个如何使用 copy() 函数模拟为图像着色的范例。 + */ +let draft, ready; +function preload() { + ready = loadImage("assets/parrot-color.png"); + draft = loadImage("assets/parrot-bw.png"); +} +function setup() { + createCanvas(600, 400); + noCursor(); + cursor("assets/brush.png", 20, -10); + image(ready, 0, 0); + image(draft, 0, 0); +} +function mouseDragged() { + copy(ready, mouseX, mouseY, 20, 20, mouseX, mouseY, 20, 20); +} diff --git a/dist/assets/examples/zh-Hans/07_Color/00_Hue.js b/dist/assets/examples/zh-Hans/07_Color/00_Hue.js new file mode 100644 index 0000000000..68cc84c57c --- /dev/null +++ b/dist/assets/examples/zh-Hans/07_Color/00_Hue.js @@ -0,0 +1,25 @@ +/* + * @name 色调 + * @description 色调是从物件反射或透过物件传播得到的颜色, + * 通常指颜色的名字(红色,蓝色,黄色等)。 + * 将光标在每个条形上垂直移动以更改其色调。 + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, height, height, height); + noStroke(); + background(0); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(mouseY, height, height); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/zh-Hans/07_Color/01_Saturation.js b/dist/assets/examples/zh-Hans/07_Color/01_Saturation.js new file mode 100644 index 0000000000..da8c42c364 --- /dev/null +++ b/dist/assets/examples/zh-Hans/07_Color/01_Saturation.js @@ -0,0 +1,24 @@ +/* + * @name 饱和度 + * @description 饱和度是颜色的强度或者纯度,代表与色调成比例的灰色量。 + * “饱和”的颜色是纯色;“不饱和”的颜色含有很大比例的灰色。 + * 将光标在每个条形上垂直移动以更改其饱和度。 + */ +const barWidth = 20; +let lastBar = -1; + +function setup() { + createCanvas(720, 400); + colorMode(HSB, width, height, 100); + noStroke(); +} + +function draw() { + let whichBar = mouseX / barWidth; + if (whichBar !== lastBar) { + let barX = whichBar * barWidth; + fill(barX, mouseY, 66); + rect(barX, 0, barWidth, height); + lastBar = whichBar; + } +} diff --git a/dist/assets/examples/zh-Hans/07_Color/02_Brightness.js b/dist/assets/examples/zh-Hans/07_Color/02_Brightness.js new file mode 100644 index 0000000000..41a66e8ad9 --- /dev/null +++ b/dist/assets/examples/zh-Hans/07_Color/02_Brightness.js @@ -0,0 +1,48 @@ +/* + * @name 亮度 + * @description 作者 Dan Shiffman。 + * 此程序通过计算每个像素距离光标的距离调整图像的局部亮度。 + *

+ * 要在本地运行此范例,您需要至少一个图像文件,并运行在 + * + * 本地伺服器 上。

+ */ +let img; + +function preload() { + img = loadImage('assets/moonwalk.jpg'); +} + +function setup() { + createCanvas(720, 200); + pixelDensity(1); + img.loadPixels(); + loadPixels(); +} + +function draw() { + for (let x = 0; x < img.width; x++) { + for (let y = 0; y < img.height; y++) { + // 通过 2D 网格计算1D位置 + let loc = (x + y * img.width) * 4; + // 从图像里获取 R,G,B 数值 + let r, g, b; + r = img.pixels[loc]; + // 根据距离光标的距离计算亮度改变的量 + let maxdist = 50; + let d = dist(x, y, mouseX, mouseY); + let adjustbrightness = (255 * (maxdist - d)) / maxdist; + r += adjustbrightness; + // 限制 RGB 以确保它们在 0-255 的颜色范围内 + r = constrain(r, 0, 255); + // 创建一个新颜色,并在窗口里设置像素 + //color c = color(r, g, b); + let pixloc = (y * width + x) * 4; + pixels[pixloc] = r; + pixels[pixloc + 1] = r; + pixels[pixloc + 2] = r; + pixels[pixloc + 3] = 255; + } + } + updatePixels(); +} diff --git a/dist/assets/examples/zh-Hans/07_Color/03_Color_Variables.js b/dist/assets/examples/zh-Hans/07_Color/03_Color_Variables.js new file mode 100644 index 0000000000..25d8149693 --- /dev/null +++ b/dist/assets/examples/zh-Hans/07_Color/03_Color_Variables.js @@ -0,0 +1,40 @@ +/* + * @name 颜色变量 + * @description (向 Albers 致敬。) 此范例为颜色们建立了变量。 + * 这样它们可以在程序中以名字指代,而非数字。 + */ +function setup() { + createCanvas(710, 400); + noStroke(); + background(51, 0, 0); + + let inside = color(204, 102, 0); + let middle = color(204, 153, 0); + let outside = color(153, 51, 0); + + // 以下语句与上面的语句等效。 + // 程序员可以选择他们喜欢的格式。 + //let inside = color('#CC6600'); + //let middle = color('#CC9900'); + //let outside = color('#993300'); + + push(); + translate(80, 80); + fill(outside); + rect(0, 0, 200, 200); + fill(middle); + rect(40, 60, 120, 120); + fill(inside); + rect(60, 90, 80, 80); + pop(); + + push(); + translate(360, 80); + fill(inside); + rect(0, 0, 200, 200); + fill(outside); + rect(40, 60, 120, 120); + fill(middle); + rect(60, 90, 80, 80); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/07_Color/04_Relativity.js b/dist/assets/examples/zh-Hans/07_Color/04_Relativity.js new file mode 100644 index 0000000000..ea4a4f9fc6 --- /dev/null +++ b/dist/assets/examples/zh-Hans/07_Color/04_Relativity.js @@ -0,0 +1,34 @@ +/* + * @name 相对性 + * @description 我们对每个颜色的感知都是相对于其他颜色而言的。 + * 上半部分和下半部分的条形具有相同的颜色构成,但是他们呈现每个颜色的顺序不同, + * 让同一个颜色看起来也不一样。 + */ +let a, b, c, d, e; + +function setup() { + createCanvas(710, 400); + noStroke(); + a = color(165, 167, 20); + b = color(77, 86, 59); + c = color(42, 106, 105); + d = color(165, 89, 20); + e = color(146, 150, 127); + noLoop(); // 只画一次 +} + +function draw() { + drawBand(a, b, c, d, e, 0, width / 128); + drawBand(c, a, d, b, e, height / 2, width / 128); +} + +function drawBand(v, w, x, y, z, ypos, barWidth) { + let num = 5; + let colorOrder = [v, w, x, y, z]; + for (let i = 0; i < width; i += barWidth * num) { + for (let j = 0; j < num; j++) { + fill(colorOrder[j]); + rect(i + j * barWidth, ypos, barWidth, height / 2); + } + } +} diff --git a/dist/assets/examples/zh-Hans/07_Color/05_Linear_Gradient.js b/dist/assets/examples/zh-Hans/07_Color/05_Linear_Gradient.js new file mode 100644 index 0000000000..2593d790c2 --- /dev/null +++ b/dist/assets/examples/zh-Hans/07_Color/05_Linear_Gradient.js @@ -0,0 +1,51 @@ +/* + * @name 线性渐变 + * @description lerpColor() 函数可用于在两个颜色之间插值。 + */ +// 常量 +const Y_AXIS = 1; +const X_AXIS = 2; +let b1, b2, c1, c2; + +function setup() { + createCanvas(710, 400); + + // 定义颜色 + b1 = color(255); + b2 = color(0); + c1 = color(204, 102, 0); + c2 = color(0, 102, 153); + + noLoop(); +} + +function draw() { + // 背景 + setGradient(0, 0, width / 2, height, b1, b2, X_AXIS); + setGradient(width / 2, 0, width / 2, height, b2, b1, X_AXIS); + // 前景 + setGradient(50, 90, 540, 80, c1, c2, Y_AXIS); + setGradient(50, 190, 540, 80, c2, c1, X_AXIS); +} + +function setGradient(x, y, w, h, c1, c2, axis) { + noFill(); + + if (axis === Y_AXIS) { + // 从上到下的渐变 + for (let i = y; i <= y + h; i++) { + let inter = map(i, y, y + h, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(x, i, x + w, i); + } + } else if (axis === X_AXIS) { + // 从左到右的渐变 + for (let i = x; i <= x + w; i++) { + let inter = map(i, x, x + w, 0, 1); + let c = lerpColor(c1, c2, inter); + stroke(c); + line(i, y, i, y + h); + } + } +} diff --git a/dist/assets/examples/zh-Hans/07_Color/06_Radial_Gradient.js b/dist/assets/examples/zh-Hans/07_Color/06_Radial_Gradient.js new file mode 100644 index 0000000000..bde099a6ff --- /dev/null +++ b/dist/assets/examples/zh-Hans/07_Color/06_Radial_Gradient.js @@ -0,0 +1,32 @@ +/* + * @name 径向渐变 + * @description 绘制一系列同心圆,创造出从一个颜色到另一个颜色到渐变效果。 + */ +let dim; + +function setup() { + createCanvas(710, 400); + dim = width / 2; + background(0); + colorMode(HSB, 360, 100, 100); + noStroke(); + ellipseMode(RADIUS); + frameRate(1); +} + +function draw() { + background(0); + for (let x = 0; x <= width; x += dim) { + drawGradient(x, height / 2); + } +} + +function drawGradient(x, y) { + let radius = dim / 2; + let h = random(0, 360); + for (let r = radius; r > 0; --r) { + fill(h, 90, 90); + ellipse(x, y, r, r); + h = (h + 1) % 360; + } +} diff --git a/dist/assets/examples/zh-Hans/07_Color/07_Lerp_Color.js b/dist/assets/examples/zh-Hans/07_Color/07_Lerp_Color.js new file mode 100644 index 0000000000..2cbb6ffc8d --- /dev/null +++ b/dist/assets/examples/zh-Hans/07_Color/07_Lerp_Color.js @@ -0,0 +1,48 @@ +/* + * @name 插值颜色 + * @description 随机循环形状,颜色从红色到蓝色。 + */ +function setup() { + createCanvas(720, 400); + background(255); + noStroke(); +} + +function draw() { + background(255); + from = color(255, 0, 0, 0.2 * 255); + to = color(0, 0, 255, 0.2 * 255); + c1 = lerpColor(from, to, 0.33); + c2 = lerpColor(from, to, 0.66); + for (let i = 0; i < 15; i++) { + fill(from); + quad( + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height), + random(-40, 220), random(height) + ); + fill(c1); + quad( + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height), + random(140, 380), random(height) + ); + fill(c2); + quad( + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height), + random(320, 580), random(height) + ); + fill(to); + quad( + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height), + random(500, 760), random(height) + ); + } + frameRate(5); +} diff --git a/dist/assets/examples/zh-Hans/08_Math/00_incrementdecrement.js b/dist/assets/examples/zh-Hans/08_Math/00_incrementdecrement.js new file mode 100644 index 0000000000..abf5b039ff --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/00_incrementdecrement.js @@ -0,0 +1,41 @@ +/* + * @name 增量/减量 + * @description "a++" 等于 "a = a + 1"。 "a--" 等于 "a = a - 1"。 + */ +let a; +let b; +let direction; + +function setup() { + createCanvas(710, 400); + colorMode(RGB, width); + a = 0; + b = width; + direction = true; + frameRate(30); +} + +function draw() { + a++; + if (a > width) { + a = 0; + direction = !direction; + } + if (direction === true) { + stroke(a); + } else { + stroke(width - a); + } + line(a, 0, a, height / 2); + + b--; + if (b < 0) { + b = width; + } + if (direction === true) { + stroke(width - b); + } else { + stroke(b); + } + line(b, height / 2 + 1, b, height); +} diff --git a/dist/assets/examples/zh-Hans/08_Math/01_operatorprecedence.js b/dist/assets/examples/zh-Hans/08_Math/01_operatorprecedence.js new file mode 100644 index 0000000000..57fd22bf21 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/01_operatorprecedence.js @@ -0,0 +1,48 @@ +/* + * @name 操作符优先级 + * @description 如果没有明确地指明表达式求值的次序,表达式将根据操作符的优先级来求值。 + * 例如,在 "4+2*8" 的语句中, 2 会先乘 8,其结果再加上 4。 + * 这是因为 "*" 的优先级比 "+" 的高。 + * 为了避免读取程序时的模凌两可,建议将该语句写成 "4+(2*8)"。 + * 在代码中加上括号可以控制求值的次序。 + * 以下是操作符优先级列表。 + */ +// 最高级(最先执行)的位于列表上方,最低级(最后执行)的位于下方。 +// 乘法: * / % +// 加法: + - +// 比较: < > <= >= +// 相等: == != +// 逻辑与 (AND): && +// 逻辑或 (OR): || +// 赋值: = += -= *= /= %= +function setup() { + createCanvas(710, 400); + background(51); + noFill(); + stroke(51); + + stroke(204); + for (let i = 0; i < width - 20; i += 4) { + // 30 和 70 先相加,其结果再和现在的 i 值比较大小 + // 更清楚的写法是:"if (i > (30 + 70)) {" + if (i > 30 + 70) { + line(i, 0, i, 50); + } + } + + stroke(255); + // 2 和 8 先相乘,其结果再加 4 + // 更清楚的写法是:"rect(5 + (2 * 8), 0, 90, 20);" + rect(4 + 2 * 8, 52, 290, 48); + rect((4 + 2) * 8, 100, 290, 49); + + stroke(153); + for (let i = 0; i < width; i += 2) { + // 先算关系表达式,再是逻辑与 (AND),最后是逻辑或 (OR) + // 更清楚的写法是: + // "if(((i > 20) && (i < 50)) || ((i > 100) && (i < width-20))) {" + if ((i > 20 && i < 50) || (i > 100 && i < width - 20)) { + line(i, 151, i, height - 1); + } + } +} diff --git a/dist/assets/examples/zh-Hans/08_Math/02_distance1d.js b/dist/assets/examples/zh-Hans/08_Math/02_distance1d.js new file mode 100644 index 0000000000..c75eabd6c5 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/02_distance1d.js @@ -0,0 +1,64 @@ +/* + * @name 一维间距 + * @description 左右移动鼠标来控制移动形状的速度和方向。 + */ +let xpos1; +let xpos2; +let xpos3; +let xpos4; +let thin = 8; +let thick = 36; + +function setup() { + createCanvas(710, 400); + noStroke(); + xpos1 = width / 2; + xpos2 = width / 2; + xpos3 = width / 2; + xpos4 = width / 2; +} + +function draw() { + background(0); + + let mx = mouseX * 0.4 - width / 5.0; + + fill(102); + rect(xpos2, 0, thick, height / 2); + fill(204); + rect(xpos1, 0, thin, height / 2); + fill(102); + rect(xpos4, height / 2, thick, height / 2); + fill(204); + rect(xpos3, height / 2, thin, height / 2); + + xpos1 += mx / 16; + xpos2 += mx / 64; + xpos3 -= mx / 16; + xpos4 -= mx / 64; + + if (xpos1 < -thin) { + xpos1 = width; + } + if (xpos1 > width) { + xpos1 = -thin; + } + if (xpos2 < -thick) { + xpos2 = width; + } + if (xpos2 > width) { + xpos2 = -thick; + } + if (xpos3 < -thin) { + xpos3 = width; + } + if (xpos3 > width) { + xpos3 = -thin; + } + if (xpos4 < -thick) { + xpos4 = width; + } + if (xpos4 > width) { + xpos4 = -thick; + } +} diff --git a/dist/assets/examples/zh-Hans/08_Math/03_distance2d.js b/dist/assets/examples/zh-Hans/08_Math/03_distance2d.js new file mode 100644 index 0000000000..c9c956d931 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/03_distance2d.js @@ -0,0 +1,24 @@ +/* + * @name 二维间距 + * @description 在图片上移动鼠标来遮盖并显示矩阵。 + * 测量鼠标到每个正方形的距离,并按比例设置大小。 + */ +let max_distance; + +function setup() { + createCanvas(710, 400); + noStroke(); + max_distance = dist(0, 0, width, height); +} + +function draw() { + background(0); + + for (let i = 0; i <= width; i += 20) { + for (let j = 0; j <= height; j += 20) { + let size = dist(mouseX, mouseY, i, j); + size = (size / max_distance) * 66; + ellipse(i, j, size, size); + } + } +} diff --git a/dist/assets/examples/zh-Hans/08_Math/04_sine.js b/dist/assets/examples/zh-Hans/08_Math/04_sine.js new file mode 100644 index 0000000000..9ddbef561c --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/04_sine.js @@ -0,0 +1,27 @@ +/* + * @name 正弦 + * @description 使用 sin() 函数平滑地缩放大小。 + */ +let diameter; +let angle = 0; + +function setup() { + createCanvas(710, 400); + diameter = height - 10; + noStroke(); + fill(255, 204, 0); +} + +function draw() { + background(0); + + let d1 = 10 + (sin(angle) * diameter) / 2 + diameter / 2; + let d2 = 10 + (sin(angle + PI / 2) * diameter) / 2 + diameter / 2; + let d3 = 10 + (sin(angle + PI) * diameter) / 2 + diameter / 2; + + ellipse(0, height / 2, d1, d1); + ellipse(width / 2, height / 2, d2, d2); + ellipse(width, height / 2, d3, d3); + + angle += 0.02; +} diff --git a/dist/assets/examples/zh-Hans/08_Math/05_sincosine.js b/dist/assets/examples/zh-Hans/08_Math/05_sincosine.js new file mode 100644 index 0000000000..900df8b666 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/05_sincosine.js @@ -0,0 +1,42 @@ +/* + * @name 正弦余弦 + * @description sin() 函数和 cos() 函数的线性运动。 + * 将 0 到 PI*2 (TWO_PI 的角度大致是 6.28) 之间的数字放进这些函数将返回 -1 到 1 之间的数字。 + * 然后这些数字将缩放以产生更大的运动。 + */ +let angle1 = 0; +let angle2 = 0; +let scalar = 70; + +function setup() { + createCanvas(710, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(0); + + let ang1 = radians(angle1); + let ang2 = radians(angle2); + + let x1 = width / 2 + scalar * cos(ang1); + let x2 = width / 2 + scalar * cos(ang2); + + let y1 = height / 2 + scalar * sin(ang1); + let y2 = height / 2 + scalar * sin(ang2); + + fill(255); + rect(width * 0.5, height * 0.5, 140, 140); + + fill(0, 102, 153); + ellipse(x1, height * 0.5 - 120, scalar, scalar); + ellipse(x2, height * 0.5 + 120, scalar, scalar); + + fill(255, 204, 0); + ellipse(width * 0.5 - 120, y1, scalar, scalar); + ellipse(width * 0.5 + 120, y2, scalar, scalar); + + angle1 += 2; + angle2 += 3; +} diff --git a/dist/assets/examples/zh-Hans/08_Math/06_sinewave.js b/dist/assets/examples/zh-Hans/08_Math/06_sinewave.js new file mode 100644 index 0000000000..a1dd4fb4de --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/06_sinewave.js @@ -0,0 +1,47 @@ +/* + * @name 正弦波 + * @description 渲染一个简单的正弦波。 + * 作者:Daniel Shiffman + */ + +let xspacing = 16; // 每个水平位置的距离 +let w; // 波的宽度 +let theta = 0.0; // 初始角度为 0 +let amplitude = 75.0; // 波的高度 +let period = 500.0; // 波在重复前的像素个数 +let dx; // x 的增量 +let yvalues; // 保存波的高度的数组 + +function setup() { + createCanvas(710, 400); + w = width + 16; + dx = (TWO_PI / period) * xspacing; + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // theta 增量(尝试赋予 ‘角速度’ 不同的数值) + theta += 0.02; + + // 对于每一个 x 值,使用正弦函数计算 y 值 + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = sin(x) * amplitude; + x += dx; + } +} + +function renderWave() { + noStroke(); + fill(255); + // 在波上的每个位置画椭圆 + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, height / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/zh-Hans/08_Math/07_additivewave.js b/dist/assets/examples/zh-Hans/08_Math/07_additivewave.js new file mode 100644 index 0000000000..bf14652432 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/07_additivewave.js @@ -0,0 +1,67 @@ +/* + * @name 加性波 + * @description 通过相加两个波来绘制一个更复杂的波。 + * 作者:Daniel Shiffman + */ +let xspacing = 8; // 每个水平位置的距离 +let w; // 波的宽度 +let maxwaves = 4; // 相加的波的总数 + +let theta = 0.0; +let amplitude = new Array(maxwaves); // 波的高度 +// x 的增量值,根据周期和水平位置距离来计算 +let dx = new Array(maxwaves); +// 用数组保存波的高度(不完全需要) +let yvalues; + +function setup() { + createCanvas(710, 400); + frameRate(30); + colorMode(RGB, 255, 255, 255, 100); + w = width + 16; + + for (let i = 0; i < maxwaves; i++) { + amplitude[i] = random(10, 30); + let period = random(100, 300); // 波在重复前的像素个数 + dx[i] = (TWO_PI / period) * xspacing; + } + + yvalues = new Array(floor(w / xspacing)); +} + +function draw() { + background(0); + calcWave(); + renderWave(); +} + +function calcWave() { + // theta 增量(尝试赋予 ‘角速度’ 不同的数值) + theta += 0.02; + + // 所有高度设为 0 + for (let i = 0; i < yvalues.length; i++) { + yvalues[i] = 0; + } + + // 累积波的高度 + for (let j = 0; j < maxwaves; j++) { + let x = theta; + for (let i = 0; i < yvalues.length; i++) { + // 正弦余弦交替 + if (j % 2 === 0) yvalues[i] += sin(x) * amplitude[j]; + else yvalues[i] += cos(x) * amplitude[j]; + x += dx[j]; + } + } +} + +function renderWave() { + // 在波上的每个位置画椭圆 + noStroke(); + fill(255, 50); + ellipseMode(CENTER); + for (let x = 0; x < yvalues.length; x++) { + ellipse(x * xspacing, width / 2 + yvalues[x], 16, 16); + } +} diff --git a/dist/assets/examples/zh-Hans/08_Math/08_polartocartesian.js b/dist/assets/examples/zh-Hans/08_Math/08_polartocartesian.js new file mode 100644 index 0000000000..c1116d3121 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/08_polartocartesian.js @@ -0,0 +1,43 @@ +/* + * @name PolarToCartesian + * @description 转换极坐标 (r,theta) 到笛卡尔坐标 (x,y): x = rcos(theta) y = rsin(theta)。 + * 作者:Daniel Shiffman + */ +let r; + +// 角度,角速度,角加速度 +let theta; +let theta_vel; +let theta_acc; + +function setup() { + createCanvas(710, 400); + + // 初始化所有值 + r = height * 0.45; + theta = 0; + theta_vel = 0; + theta_acc = 0.0001; +} + +function draw() { + background(0); + + // 将原点设为屏幕中心 + translate(width/2, height/2); + + // 转换极坐标到笛卡尔坐标 + let x = r * cos(theta); + let y = r * sin(theta); + + // 在笛卡尔坐标系上画椭圆 + ellipseMode(CENTER); + noStroke(); + fill(200); + ellipse(x, y, 32, 32); + + // 应用加速度和速度到角度上 + // (此示例中 r 保持静态) + theta_vel += theta_acc; + theta += theta_vel; +} diff --git a/dist/assets/examples/zh-Hans/08_Math/09_arctangent.js b/dist/assets/examples/zh-Hans/08_Math/09_arctangent.js new file mode 100644 index 0000000000..493f0426f9 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/09_arctangent.js @@ -0,0 +1,46 @@ +/* + * @name 反正切 + * @description 移动鼠标来改变眼球的方向。
+ * atan2() 函数计算每个眼球到鼠标的角度。 + */ +let e1, e2, e3; + +function setup() { + createCanvas(720, 400); + noStroke(); + e1 = new Eye(250, 16, 120); + e2 = new Eye(164, 185, 80); + e3 = new Eye(420, 230, 220); +} + +function draw() { + background(102); + e1.update(mouseX, mouseY); + e2.update(mouseX, mouseY); + e3.update(mouseX, mouseY); + e1.display(); + e2.display(); + e3.display(); +} + +function Eye(tx, ty, ts) { + this.x = tx; + this.y = ty; + this.size = ts; + this.angle = 0; + + this.update = function(mx, my) { + this.angle = atan2(my - this.y, mx - this.x); + }; + + this.display = function() { + push(); + translate(this.x, this.y); + fill(255); + ellipse(0, 0, this.size, this.size); + rotate(this.angle); + fill(153, 204, 0); + ellipse(this.size / 4, 0, this.size / 2, this.size / 2); + pop(); + }; +} diff --git a/dist/assets/examples/zh-Hans/08_Math/10_Interpolate.js b/dist/assets/examples/zh-Hans/08_Math/10_Interpolate.js new file mode 100644 index 0000000000..eefc644450 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/10_Interpolate.js @@ -0,0 +1,31 @@ +/* + * @name 线性插值 + * @frame 720, 400 + * @description 在屏幕上移动鼠标,圆会跟着移动。 + * 在动画绘制的每一帧之间,lerp() 函数会使圆从其当前位置向光标移动一部分距离(0.05)。 + * 这和在 Input 中的 Easing 范例一样,只是使用了 lerp() 函数。 + */ + +let x = 0; +let y = 0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(51); + + // lerp() 函数计算在特定增量下两个数值之间的数字 + // amt 参数为两个值之间的插值量 + // 0.0 为第一个值,0.1 为非常接近第一个值,0.5 为两者之间,等等 + + // 这里我们每帧移动 5% 至鼠标的距离 + x = lerp(x, mouseX, 0.05); + y = lerp(y, mouseY, 0.05); + + fill(255); + stroke(255); + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/zh-Hans/08_Math/11_doubleRandom.js b/dist/assets/examples/zh-Hans/08_Math/11_doubleRandom.js new file mode 100644 index 0000000000..2fcc2a7752 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/11_doubleRandom.js @@ -0,0 +1,23 @@ +/* + * @name 双重随机 + * @frame 720,400 (optional) + * @description 调用两个 random() 函数和一个 point() 函数来绘制一个不规则的锯齿线。 + * 作者:Ira Greenberg + */ +let totalPts = 300; +let steps = totalPts + 1; + +function setup() { + createCanvas(710, 400); + stroke(255); + frameRate(1); +} + +function draw() { + background(0); + let rand = 0; + for (let i = 1; i < steps; i++) { + point((width / steps) * i, height / 2 + random(-rand, rand)); + rand += random(-5, 5); + } +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/08_Math/12_random.js b/dist/assets/examples/zh-Hans/08_Math/12_random.js new file mode 100644 index 0000000000..a66b9bcdb6 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/12_random.js @@ -0,0 +1,20 @@ +/* + * @name 随机 + * @description 随机数创建了此图像的基础。 + * 每次加载程序将产生不同的结果。 + */ +function setup() { + createCanvas(710, 400); + background(0); + strokeWeight(20); + frameRate(2); +} + +function draw() { + for (let i = 0; i < width; i++) { + // 随机在 0-255 之间取数 + let r = random(255); + stroke(r); + line(i, 0, i, height); + } +} diff --git a/dist/assets/examples/zh-Hans/08_Math/13_noise1D.js b/dist/assets/examples/zh-Hans/08_Math/13_noise1D.js new file mode 100644 index 0000000000..d2e34e578e --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/13_noise1D.js @@ -0,0 +1,31 @@ +/* + * @name 一维噪声 (Noise1D) + * @description 调用一维柏林噪声来指定位置。 + */ +let xoff = 0.0; +let xincrement = 0.01; + +function setup() { + createCanvas(710, 400); + background(0); + noStroke(); +} + +function draw() { + // 创建一个透明度 (alpha) 混合背景 + fill(0, 10); + rect(0, 0, width, height); + + //let n = random(0,width); // 尝试用这一行代替 noise() + + // 基于 xoff 和 scale 得到一个噪声值 + // 并根据窗口宽度进行缩放 + let n = noise(xoff) * width; + + // 每一轮增加 xoff + xoff += xincrement; + + // 绘制由柏林噪声产生的数值的椭圆 + fill(200); + ellipse(n, height / 2, 64, 64); +} diff --git a/dist/assets/examples/zh-Hans/08_Math/14_noisewave.js b/dist/assets/examples/zh-Hans/08_Math/14_noisewave.js new file mode 100644 index 0000000000..ba3fbaea91 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/14_noisewave.js @@ -0,0 +1,42 @@ +/* + * @name 噪声波 + * @description 调用柏林噪声来产生波状图案。 + * 作者:Daniel Shiffman + */ +let yoff = 0.0; // 柏林噪声的第二维度 + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(51); + + fill(255); + // 我们将从波点中绘制一个多边形 + beginShape(); + + let xoff = 0; // 选项 1: 2D 噪声 + // let xoff = yoff; // 选项 2: 1D 噪声 + + // 迭代所有水平像素 + for (let x = 0; x <= width; x += 10) { + // 根据noise() 和 map() 函数计算一个 y 值 + + // 选项 1: 2D 噪声 + let y = map(noise(xoff, yoff), 0, 1, 200, 300); + + // 选项 2: 1D 噪声 + // let y = map(noise(xoff), 0, 1, 200,300); + + // 设置顶点 + vertex(x, y); + // 增加噪声的 x 维度 + xoff += 0.05; + } + // 增加噪声的 y 维度 + yoff += 0.01; + vertex(width, height); + vertex(0, height); + endShape(CLOSE); +} diff --git a/dist/assets/examples/zh-Hans/08_Math/15_Noise2D.js b/dist/assets/examples/zh-Hans/08_Math/15_Noise2D.js new file mode 100644 index 0000000000..769cc54909 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/15_Noise2D.js @@ -0,0 +1,42 @@ +/* + * @name 二维噪声 (Noise2D) + * @frame 710,400 (optional) + * @description 使用不同参数创建一个二维噪声。 + * + */ + +let noiseVal; +let noiseScale = 0.02; + +function setup() { + createCanvas(640, 360); +} + +function draw() { + background(0); + // 绘制左半边图像 + for (let y = 0; y < height - 30; y++) { + for (let x = 0; x < width / 2; x++) { + // 像素所使用的八度数和衰退因数的 noiceDetail + noiseDetail(2, 0.2); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + // 绘制右半边图像 + for (let y = 0; y < height - 30; y++) { + for (let x = width / 2; x < width; x++) { + // 像素所使用的八度数和衰退因数的 noiceDetail + noiseDetail(5, 0.5); + noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale); + stroke(noiseVal * 255); + point(x, y); + } + } + // 显示左右两分区的详细信息 + textSize(18); + fill(255, 255, 255); + text('Noice2D with 2 octaves and 0.2 falloff', 10, 350); + text('Noice2D with 1 octaves and 0.7 falloff', 330, 350); +} diff --git a/dist/assets/examples/zh-Hans/08_Math/16_Noise3D.js b/dist/assets/examples/zh-Hans/08_Math/16_Noise3D.js new file mode 100644 index 0000000000..7923d6699a --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/16_Noise3D.js @@ -0,0 +1,48 @@ +/* + * @name 三维噪声 (Noise3D) + * @frame 710,400 (optional) + * @description 使用三维噪声创建简单的动画纹理。 + */ + +let noiseVal; +// x 增加 0.01 +let x_increment = 0.01; +// 每一个 draw() 的周期,z 增加 0.02 +let z_increment = 0.02; + +// 偏移值 +let z_off, y_off, x_off; + +function setup() { + // 创建画布 + createCanvas(640, 360); + // 定义每一秒应该显示的影格数 + frameRate(20); + // 初始 z_off + z_off = 0; +} + +function draw() { + x_off = 0; + y_off = 0; + // 设置黑色背景 + background(0); + // 调整噪声细节 + noiseDetail(8, 0.65); + + // 对于每一个 x,y 计算噪声值 + for (let y = 0; y < height; y++) { + x_off += x_increment; + y_off = 0; + + for (let x = 0; x < width; x++) { + // 计算和绘制每一个像素 + noiseVal = noise(x_off, y_off, z_off); + stroke(noiseVal * 255); + y_off += x_increment; + point(x, y); + } + } + + z_off += z_increment; +} diff --git a/dist/assets/examples/zh-Hans/08_Math/17_Randomchords.js b/dist/assets/examples/zh-Hans/08_Math/17_Randomchords.js new file mode 100644 index 0000000000..84f5c693de --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/17_Randomchords.js @@ -0,0 +1,33 @@ +/* + * @name 随机弦 + * @description 累积一个圆的随机弦。每个弦都是半透明的,所以它们累积起来会造成阴影球面的错觉。 + * 贡献于 Aatish Bhatia,灵感来源于 Anders Hoff + */ +function setup() { + createCanvas(400, 400); + background(255, 255, 255); + + // 使用透明度值的半透明外形线 + stroke(0, 0, 0, 15); +} + +function draw() { + // 每一帧绘制两个随机弦 + randomChord(); + randomChord(); +} + +function randomChord() { + // 在圆上随机找一个点 + let angle1 = random(0, 2 * PI); + let xpos1 = 200 + 200 * cos(angle1); + let ypos1 = 200 + 200 * sin(angle1); + + // 在圆上随机找另一个点 + let angle2 = random(0, 2 * PI); + let xpos2 = 200 + 200 * cos(angle2); + let ypos2 = 200 + 200 * sin(angle2); + + // 在两点之间绘制一条直线 + line(xpos1, ypos1, xpos2, ypos2); +} diff --git a/dist/assets/examples/zh-Hans/08_Math/18_Map.js b/dist/assets/examples/zh-Hans/08_Math/18_Map.js new file mode 100644 index 0000000000..ec6d6802f5 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/18_Map.js @@ -0,0 +1,20 @@ +/* + * @name 映射 (Map) + * @description 调用 map() 函数将任意数值缩放至一个对于现在程序更有用的新数值。 + * 例如,使用鼠标的位置来控制形状的大小或颜色。 + * 此范例中,鼠标的 x 坐标( 0-360 之间的数字)将被缩放为新数值,用于设定圆的颜色和大小。 + */ +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(0); + // 将 mouseX 的数值从 0-720 缩放至 0-175 的范围内 + let c = map(mouseX, 0, width, 0, 175); + // 将 mouseX 的数值从 0-720 to 缩放至 40-300 的范围内 + let d = map(mouseX, 0, width, 40, 300); + fill(255, c, 0); + ellipse(width/2, height/2, d, d); +} diff --git a/dist/assets/examples/zh-Hans/08_Math/19_parametricEquation.js b/dist/assets/examples/zh-Hans/08_Math/19_parametricEquation.js new file mode 100644 index 0000000000..423400d4ae --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/19_parametricEquation.js @@ -0,0 +1,43 @@ +/* + * @name 参数方程 + * @description 参数方程是 x 和 y 坐标都用另外的字母表示。 + * 这被称为参数并且通常以字母 t 或 θ 给出。 + * 灵感来源于 Alexander Miller 油管频道。 + */ + +function setup(){ + createCanvas(720,400); +} + +// x 和 y 所依靠的参数通常被视为 t 或者 theta 的符号 +let t = 0; +function draw(){ + background('#fff'); + translate(width/2,height/2); + stroke('#0f0f0f'); + strokeWeight(1.5); + // 迭代来增加 100 条直线 + for(let i = 0;i<100;i++){ + line(x1(t+i),y1(t+i),x2(t+i)+20,y2(t+i)+20); + } + t+=0.15; +} +// 改变直线的初始 x 坐标 +function x1(t){ + return sin(t/10)*125+sin(t/20)*125+sin(t/30)*125; +} + +// 改变直线的初始 y 坐标 +function y1(t){ + return cos(t/10)*125+cos(t/20)*125+cos(t/30)*125; +} + +// 改变直线的最终 x 坐标 +function x2(t){ + return sin(t/15)*125+sin(t/25)*125+sin(t/35)*125; +} + +// 改变直线的最终 y 坐标 +function y2(t){ + return cos(t/15)*125+cos(t/25)*125+cos(t/35)*125; +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/08_Math/20_Graphing2DEquations.js b/dist/assets/examples/zh-Hans/08_Math/20_Graphing2DEquations.js new file mode 100644 index 0000000000..450f33c8ce --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/20_Graphing2DEquations.js @@ -0,0 +1,52 @@ +/** + * @name Graphing 2D Equations + * @frame 710, 400 + * @description Graphics the following equation: sin(n*cos(r) + 5*theta) where n is a function of horizontal mouse location. Original by Daniel Shiffman + */ +function setup() { + createCanvas(710, 400); + pixelDensity(1); +} + +function draw() { + loadPixels(); + let n = (mouseX * 10.0) / width; + const w = 16.0; // 2D space width + const h = 16.0; // 2D space height + const dx = w / width; // Increment x this amount per pixel + const dy = h / height; // Increment y this amount per pixel + let x = -w / 2; // Start x at -1 * width / 2 + let y; + + let r; + let theta; + let val; + + let bw; //variable to store grayscale + let i; + let j; + let cols = width; + let rows = height; + + for (i = 0; i < cols; i += 1) { + y = -h / 2; + for (j = 0; j < rows; j += 1) { + r = sqrt(x * x + y * y); // Convert cartesian to polar + theta = atan2(y, x); // Convert cartesian to polar + // Compute 2D polar coordinate function + val = sin(n * cos(r) + 5 * theta); // Results in a value between -1 and 1 + //var val = cos(r); // Another simple function + //var val = sin(theta); // Another simple function + bw = color(((val + 1) * 255) / 2); + index = 4 * (i + j * width); + pixels[index] = red(bw); + pixels[index + 1] = green(bw); + pixels[index + 2] = blue(bw); + pixels[index + 3] = alpha(bw); + + y += dy; + } + x += dx; + } + updatePixels(); +} diff --git a/dist/assets/examples/zh-Hans/08_Math/21_parametricEquation.js b/dist/assets/examples/zh-Hans/08_Math/21_parametricEquation.js new file mode 100644 index 0000000000..83c1a3c336 --- /dev/null +++ b/dist/assets/examples/zh-Hans/08_Math/21_parametricEquation.js @@ -0,0 +1,44 @@ +/* + * @name Parametric Equations + * @description A parametric equation is where x and y + * coordinates are both written in terms of another letter. This is + * called a parameter and is usually given in the letter t or θ. + * The inspiration was taken from the YouTube channel of Alexander Miller. + */ + +function setup(){ + createCanvas(720,400); +} + +// the parameter at which x and y depends is usually taken as either t or symbol of theta +let t = 0; +function draw(){ + background('#fff'); + translate(width/2,height/2); + stroke('#0f0f0f'); + strokeWeight(1.5); + //loop for adding 100 lines + for(let i = 0;i<100;i++){ + line(x1(t+i),y1(t+i),x2(t+i)+20,y2(t+i)+20); + } + t+=0.15; +} +// function to change initial x co-ordinate of the line +function x1(t){ + return sin(t/10)*125+sin(t/20)*125+sin(t/30)*125; +} + +// function to change initial y co-ordinate of the line +function y1(t){ + return cos(t/10)*125+cos(t/20)*125+cos(t/30)*125; +} + +// function to change final x co-ordinate of the line +function x2(t){ + return sin(t/15)*125+sin(t/25)*125+sin(t/35)*125; +} + +// function to change final y co-ordinate of the line +function y2(t){ + return cos(t/15)*125+cos(t/25)*125+cos(t/35)*125; +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/09_Simulate/00_Forces.js b/dist/assets/examples/zh-Hans/09_Simulate/00_Forces.js new file mode 100644 index 0000000000..6492ce8ff8 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/00_Forces.js @@ -0,0 +1,148 @@ +/* + * @name Forces + * @description Demonstration of multiple force acting on bodies + * (natureofcode.com) + */ +// Demonstration of multiple force acting on +// bodies (Mover class) +// Bodies experience gravity continuously +// Bodies experience fluid resistance when in "water" + +// Five moving bodies +let movers = []; + +// Liquid +let liquid; + +function setup() { + createCanvas(640, 360); + reset(); + // Create liquid object + liquid = new Liquid(0, height / 2, width, height / 2, 0.1); +} + +function draw() { + background(127); + + // Draw water + liquid.display(); + + for (let i = 0; i < movers.length; i++) { + + // Is the Mover in the liquid? + if (liquid.contains(movers[i])) { + // Calculate drag force + let dragForce = liquid.calculateDrag(movers[i]); + // Apply drag force to Mover + movers[i].applyForce(dragForce); + } + + // Gravity is scaled by mass here! + let gravity = createVector(0, 0.1 * movers[i].mass); + // Apply gravity + movers[i].applyForce(gravity); + + // Update and display + movers[i].update(); + movers[i].display(); + movers[i].checkEdges(); + } + +} + + +function mousePressed() { + reset(); +} + +// Restart all the Mover objects randomly +function reset() { + for (let i = 0; i < 9; i++) { + movers[i] = new Mover(random(0.5, 3), 40 + i * 70, 0); + } +} + +let Liquid = function(x, y, w, h, c) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + this.c = c; +}; + +// Is the Mover in the Liquid? +Liquid.prototype.contains = function(m) { + let l = m.position; + return l.x > this.x && l.x < this.x + this.w && + l.y > this.y && l.y < this.y + this.h; +}; + +// Calculate drag force +Liquid.prototype.calculateDrag = function(m) { + // Magnitude is coefficient * speed squared + let speed = m.velocity.mag(); + let dragMagnitude = this.c * speed * speed; + + // Direction is inverse of velocity + let dragForce = m.velocity.copy(); + dragForce.mult(-1); + + // Scale according to magnitude + // dragForce.setMag(dragMagnitude); + dragForce.normalize(); + dragForce.mult(dragMagnitude); + return dragForce; +}; + +Liquid.prototype.display = function() { + noStroke(); + fill(50); + rect(this.x, this.y, this.w, this.h); +}; + +function Mover(m,x,y) { + this.mass = m; + this.position = createVector(x, y); + this.velocity = createVector(0, 0); + this.acceleration = createVector(0, 0); +} + +// Newton's 2nd law: F = M * A +// or A = F / M +Mover.prototype.applyForce = function(force) { + let f = p5.Vector.div(force, this.mass); + this.acceleration.add(f); +}; + +Mover.prototype.update = function() { + // Velocity changes according to acceleration + this.velocity.add(this.acceleration); + // position changes by velocity + this.position.add(this.velocity); + // We must clear acceleration each frame + this.acceleration.mult(0); +}; + +Mover.prototype.display = function() { + stroke(0); + strokeWeight(2); + fill(255, 127); + ellipse(this.position.x, this.position.y, this.mass*16, this.mass*16); +}; + +// Bounce off bottom of window +Mover.prototype.checkEdges = function() { + if (this.position.y > (height - this.mass * 8)) { + // A little dampening when hitting the bottom + this.velocity.y *= -0.9; + this.position.y = (height - this.mass * 8); + } +}; + + + + + + + + diff --git a/dist/assets/examples/zh-Hans/09_Simulate/01_ParticleSystem.js b/dist/assets/examples/zh-Hans/09_Simulate/01_ParticleSystem.js new file mode 100644 index 0000000000..a026e4623c --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/01_ParticleSystem.js @@ -0,0 +1,69 @@ +/* + * @name Particle System + * @description This is a basic Particle System + * (natureofcode.com) + */ +let system; + +function setup() { + createCanvas(720, 400); + system = new ParticleSystem(createVector(width / 2, 50)); +} + +function draw() { + background(51); + system.addParticle(); + system.run(); +} + +// A simple Particle class +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// Method to update position +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// Method to display +Particle.prototype.display = function() { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// Is the particle still useful? +Particle.prototype.isDead = function(){ + return this.lifespan < 0; +}; + +let ParticleSystem = function(position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin)); +}; + +ParticleSystem.prototype.run = function() { + for (let i = this.particles.length-1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; diff --git a/dist/assets/examples/zh-Hans/09_Simulate/02_Flocking.js b/dist/assets/examples/zh-Hans/09_Simulate/02_Flocking.js new file mode 100644 index 0000000000..4f08384666 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/02_Flocking.js @@ -0,0 +1,229 @@ +/* + * @name Flocking + * @description Demonstration of Craig Reynolds' "Flocking" behavior. + * See: http://www.red3d.com/cwr/ + * Rules: Cohesion, Separation, Alignment + * (from natureofcode.com). + * Drag mouse to add boids into the system. + */ + + +let flock; + +function setup() { + createCanvas(640, 360); + createP("Drag the mouse to generate new boids."); + + flock = new Flock(); + // Add an initial set of boids into the system + for (let i = 0; i < 100; i++) { + let b = new Boid(width / 2, height / 2); + flock.addBoid(b); + } +} + +function draw() { + background(51); + flock.run(); +} + +// Add a new boid into the System +function mouseDragged() { + flock.addBoid(new Boid(mouseX,mouseY)); +} + +// The Nature of Code +// Daniel Shiffman +// http://natureofcode.com + +// Flock object +// Does very little, simply manages the array of all the boids + +function Flock() { + // An array for all the boids + this.boids = []; // Initialize the array +} + +Flock.prototype.run = function() { + for (let i = 0; i < this.boids.length; i++) { + this.boids[i].run(this.boids); // Passing the entire list of boids to each boid individually + } +} + +Flock.prototype.addBoid = function(b) { + this.boids.push(b); +} + +// The Nature of Code +// Daniel Shiffman +// http://natureofcode.com + +// Boid class +// Methods for Separation, Cohesion, Alignment added + +function Boid(x, y) { + this.acceleration = createVector(0, 0); + this.velocity = createVector(random(-1, 1),random(-1, 1)); + this.position = createVector(x,y); + this.r = 3.0; + this.maxspeed = 3; // Maximum speed + this.maxforce = 0.05; // Maximum steering force +} + +Boid.prototype.run = function(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); +} + +Boid.prototype.applyForce = function(force) { + // We could add mass here if we want A = F / M + this.acceleration.add(force); +} + +// We accumulate a new acceleration each time based on three rules +Boid.prototype.flock = function(boids) { + let sep = this.separate(boids); // Separation + let ali = this.align(boids); // Alignment + let coh = this.cohesion(boids); // Cohesion + // Arbitrarily weight these forces + sep.mult(1.5); + ali.mult(1.0); + coh.mult(1.0); + // Add the force vectors to acceleration + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); +} + +// Method to update location +Boid.prototype.update = function() { + // Update velocity + this.velocity.add(this.acceleration); + // Limit speed + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // Reset accelertion to 0 each cycle + this.acceleration.mult(0); +} + +// A method that calculates and applies a steering force towards a target +// STEER = DESIRED MINUS VELOCITY +Boid.prototype.seek = function(target) { + let desired = p5.Vector.sub(target, this.position); // A vector pointing from the location to the target + // Normalize desired and scale to maximum speed + desired.normalize(); + desired.mult(this.maxspeed); + // Steering = Desired minus Velocity + let steer = p5.Vector.sub(desired, this.velocity); + steer.limit(this.maxforce); // Limit to maximum steering force + return steer; +} + +Boid.prototype.render = function() { + // Draw a triangle rotated in the direction of velocity + let theta = this.velocity.heading() + radians(90); + fill(127); + stroke(200); + push(); + translate(this.position.x,this.position.y); + rotate(theta); + beginShape(); + vertex(0, -this.r * 2); + vertex(-this.r, this.r * 2); + vertex(this.r, this.r * 2); + endShape(CLOSE); + pop(); +} + +// Wraparound +Boid.prototype.borders = function() { + if (this.position.x < -this.r) this.position.x = width + this.r; + if (this.position.y < -this.r) this.position.y = height + this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height + this.r) this.position.y = -this.r; +} + +// Separation +// Method checks for nearby boids and steers away +Boid.prototype.separate = function(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // For every boid in the system, check if it's too close + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) + if ((d > 0) && (d < desiredseparation)) { + // Calculate vector pointing away from neighbor + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // Weight by distance + steer.add(diff); + count++; // Keep track of how many + } + } + // Average -- divide by how many + if (count > 0) { + steer.div(count); + } + + // As long as the vector is greater than 0 + if (steer.mag() > 0) { + // Implement Reynolds: Steering = Desired - Velocity + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; +} + +// Alignment +// For every nearby boid in the system, calculate the average velocity +Boid.prototype.align = function(boids) { + let neighbordist = 50; + let sum = createVector(0,0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } +} + +// Cohesion +// For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location +Boid.prototype.cohesion = function(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // Start with empty vector to accumulate all locations + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // Add location + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // Steer towards the location + } else { + return createVector(0, 0); + } +} + + diff --git a/dist/assets/examples/zh-Hans/09_Simulate/03_WolframCA.js b/dist/assets/examples/zh-Hans/09_Simulate/03_WolframCA.js new file mode 100644 index 0000000000..8e5dad9f9c --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/03_WolframCA.js @@ -0,0 +1,73 @@ +/* + * @name Wolfram CA + * @description Simple demonstration of a Wolfram 1-dimensional cellular automata + * (natureofcode.com) + */ + +let w = 10; +// An array of 0s and 1s +let cells; + + // We arbitrarily start with just the middle cell having a state of "1" +let generation = 0; + +// An array to store the ruleset, for example {0,1,1,0,1,1,0,1} +let ruleset = [0, 1, 0, 1, 1, 0, 1, 0]; + +function setup() { + createCanvas(640, 400); + cells = Array(floor(width / w)); + for (let i = 0; i < cells.length; i++) { + cells[i] = 0; + } + cells[cells.length / 2] = 1; + +} + +function draw() { + for (let i = 0; i < cells.length; i++) { + if (cells[i] === 1) { + fill(200); + } else { + fill(51); + noStroke(); + rect(i * w, generation * w, w, w); + } + } + if (generation < height / w) { + generate(); + } +} + +// The process of creating the new generation +function generate() { + // First we create an empty array for the new values + let nextgen = Array(cells.length); + // For every spot, determine new state by examing current state, and neighbor states + // Ignore edges that only have one neighor + for (let i = 1; i < cells.length-1; i++) { + let left = cells[i-1]; // Left neighbor state + let me = cells[i]; // Current state + let right = cells[i+1]; // Right neighbor state + nextgen[i] = rules(left, me, right); // Compute next generation state based on ruleset + } + // The current generation is the new generation + cells = nextgen; + generation++; +} + + +// Implementing the Wolfram rules +// Could be improved and made more concise, but here we can explicitly see what is going on for each case +function rules(a, b, c) { + if (a == 1 && b == 1 && c == 1) return ruleset[0]; + if (a == 1 && b == 1 && c == 0) return ruleset[1]; + if (a == 1 && b == 0 && c == 1) return ruleset[2]; + if (a == 1 && b == 0 && c == 0) return ruleset[3]; + if (a == 0 && b == 1 && c == 1) return ruleset[4]; + if (a == 0 && b == 1 && c == 0) return ruleset[5]; + if (a == 0 && b == 0 && c == 1) return ruleset[6]; + if (a == 0 && b == 0 && c == 0) return ruleset[7]; + return 0; +} + diff --git a/dist/assets/examples/zh-Hans/09_Simulate/04_GameOfLife.js b/dist/assets/examples/zh-Hans/09_Simulate/04_GameOfLife.js new file mode 100644 index 0000000000..8a2dbdfe62 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/04_GameOfLife.js @@ -0,0 +1,94 @@ +/* + * @name Game of Life + * @description A basic implementation of John Conway's Game of Life CA + * (natureofcode.com) + */ + +let w; +let columns; +let rows; +let board; +let next; + +function setup() { + createCanvas(720, 400); + w = 20; + // Calculate columns and rows + columns = floor(width / w); + rows = floor(height / w); + // Wacky way to make a 2D array is JS + board = new Array(columns); + for (let i = 0; i < columns; i++) { + board[i] = new Array(rows); + } + // Going to use multiple 2D arrays and swap them + next = new Array(columns); + for (i = 0; i < columns; i++) { + next[i] = new Array(rows); + } + init(); +} + +function draw() { + background(255); + generate(); + for ( let i = 0; i < columns;i++) { + for ( let j = 0; j < rows;j++) { + if ((board[i][j] == 1)) fill(0); + else fill(255); + stroke(0); + rect(i * w, j * w, w - 1, w - 1); + } + } + +} + +// reset board when mouse is pressed +function mousePressed() { + init(); +} + +// Fill board randomly +function init() { + for (let i = 0; i < columns; i++) { + for (let j = 0; j < rows; j++) { + // Lining the edges with 0s + if (i == 0 || j == 0 || i == columns - 1 || j == rows - 1) board[i][j] = 0; + // Filling the rest randomly + else board[i][j] = floor(random(2)); + next[i][j] = 0; + } + } +} + +// The process of creating the new generation +function generate() { + + // Loop through every spot in our 2D array and check spots neighbors + for (let x = 1; x < columns - 1; x++) { + for (let y = 1; y < rows - 1; y++) { + // Add up all the states in a 3x3 surrounding grid + let neighbors = 0; + for (let i = -1; i <= 1; i++) { + for (let j = -1; j <= 1; j++) { + neighbors += board[x+i][y+j]; + } + } + + // A little trick to subtract the current cell's state since + // we added it in the above loop + neighbors -= board[x][y]; + // Rules of Life + if ((board[x][y] == 1) && (neighbors < 2)) next[x][y] = 0; // Loneliness + else if ((board[x][y] == 1) && (neighbors > 3)) next[x][y] = 0; // Overpopulation + else if ((board[x][y] == 0) && (neighbors == 3)) next[x][y] = 1; // Reproduction + else next[x][y] = board[x][y]; // Stasis + } + } + + // Swap! + let temp = board; + board = next; + next = temp; +} + diff --git a/dist/assets/examples/zh-Hans/09_Simulate/05_MultipleParticleSystems.js b/dist/assets/examples/zh-Hans/09_Simulate/05_MultipleParticleSystems.js new file mode 100644 index 0000000000..99ff1439a4 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/05_MultipleParticleSystems.js @@ -0,0 +1,138 @@ +/* + * @name Multiple Particle Systems + * @description Click the mouse to generate a burst of particles at mouse location.
Each burst is one instance of a particle system with Particles and CrazyParticles (a subclass of Particle).
Note use of Inheritance and Polymorphism here.
+ * Original by Daniel Shiffman. + */ +let systems; + +function setup() { + createCanvas(710, 400); + systems = []; +} + +function draw() { + background(51); + background(0); + for (i = 0; i < systems.length; i++) { + systems[i].run(); + systems[i].addParticle(); + } + if (systems.length==0) { + fill(255); + textAlign(CENTER); + textSize(32); + text("click mouse to add particle systems", width / 2, height / 2); + } +} + +function mousePressed() { + this.p = new ParticleSystem(createVector(mouseX, mouseY)); + systems.push(p); +} + +// A simple Particle class +let Particle = function(position) { + this.acceleration = createVector(0, 0.05); + this.velocity = createVector(random(-1, 1), random(-1, 0)); + this.position = position.copy(); + this.lifespan = 255.0; +}; + +Particle.prototype.run = function() { + this.update(); + this.display(); +}; + +// Method to update position +Particle.prototype.update = function(){ + this.velocity.add(this.acceleration); + this.position.add(this.velocity); + this.lifespan -= 2; +}; + +// Method to display +Particle.prototype.display = function () { + stroke(200, this.lifespan); + strokeWeight(2); + fill(127, this.lifespan); + ellipse(this.position.x, this.position.y, 12, 12); +}; + +// Is the particle still useful? +Particle.prototype.isDead = function () { + if (this.lifespan < 0) { + return true; + } else { + return false; + } +}; + +let ParticleSystem = function (position) { + this.origin = position.copy(); + this.particles = []; +}; + +ParticleSystem.prototype.addParticle = function () { + // Add either a Particle or CrazyParticle to the system + if (int(random(0, 2)) == 0) { + p = new Particle(this.origin); + } + else { + p = new CrazyParticle(this.origin); + } + this.particles.push(p); +}; + +ParticleSystem.prototype.run = function () { + for (let i = this.particles.length - 1; i >= 0; i--) { + let p = this.particles[i]; + p.run(); + if (p.isDead()) { + this.particles.splice(i, 1); + } + } +}; + +// A subclass of Particle + +function CrazyParticle(origin) { + // Call the parent constructor, making sure (using Function#call) + // that "this" is set correctly during the call + Particle.call(this, origin); + + // Initialize our added properties + this.theta = 0.0; +}; + +// Create a Crazy.prototype object that inherits from Particle.prototype. +// Note: A common error here is to use "new Particle()" to create the +// Crazy.prototype. That's incorrect for several reasons, not least +// that we don't have anything to give Particle for the "origin" +// argument. The correct place to call Particle is above, where we call +// it from Crazy. +CrazyParticle.prototype = Object.create(Particle.prototype); // See note below + +// Set the "constructor" property to refer to CrazyParticle +CrazyParticle.prototype.constructor = CrazyParticle; + +// Notice we don't have the method run() here; it is inherited from Particle + +// This update() method overrides the parent class update() method +CrazyParticle.prototype.update = function() { + Particle.prototype.update.call(this); + // Increment rotation based on horizontal velocity + this.theta += (this.velocity.x * this.velocity.mag()) / 10.0; +} + +// This display() method overrides the parent class display() method +CrazyParticle.prototype.display = function() { + // Render the ellipse just like in a regular particle + Particle.prototype.display.call(this); + // Then add a rotating line + push(); + translate(this.position.x, this.position.y); + rotate(this.theta); + stroke(255, this.lifespan); + line(0, 0, 25, 0); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/09_Simulate/06_Spirograph.js b/dist/assets/examples/zh-Hans/09_Simulate/06_Spirograph.js new file mode 100644 index 0000000000..02cb918b09 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/06_Spirograph.js @@ -0,0 +1,73 @@ + +/* + * @name Spirograph + * @description This sketch uses simple transformations to create a + * Spirograph-like effect with interlocking circles (called sines). + * Press the spacebar to switch between tracing and showing the underlying geometry.
+ * Example created by R. Luke DuBois.
+ * http://en.wikipedia.org/wiki/Spirograph + */ +let NUMSINES = 20; // how many of these things can we do at once? +let sines = new Array(NUMSINES); // an array to hold all the current angles +let rad; // an initial radius value for the central sine +let i; // a counter variable + +// play with these to get a sense of what's going on: +let fund = 0.005; // the speed of the central sine +let ratio = 1; // what multiplier for speed is each additional sine? +let alpha = 50; // how opaque is the tracing system + +let trace = false; // are we tracing? + +function setup() { + createCanvas(710, 400); + + rad = height / 4; // compute radius for central circle + background(204); // clear the screen + + for (let i = 0; i < sines.length; i++) { + sines[i] = PI; // start EVERYBODY facing NORTH + } +} + +function draw() { + if (!trace) { + background(204); // clear screen if showing geometry + stroke(0, 255); // black pen + noFill(); // don't fill + } + + // MAIN ACTION + push(); // start a transformation matrix + translate(width / 2, height / 2); // move to middle of screen + + for (let i = 0; i < sines.length; i++) { + let erad = 0; // radius for small "point" within circle... this is the 'pen' when tracing + // setup for tracing + if (trace) { + stroke(0, 0, 255 * (float(i) / sines.length), alpha); // blue + fill(0, 0, 255, alpha / 2); // also, um, blue + erad = 5.0 * (1.0 - float(i) / sines.length); // pen width will be related to which sine + } + let radius = rad / (i+1); // radius for circle itself + rotate(sines[i]); // rotate circle + if (!trace) ellipse(0, 0, radius * 2, radius * 2); // if we're simulating, draw the sine + push(); // go up one level + translate(0, radius); // move to sine edge + if (!trace) ellipse(0, 0, 5, 5); // draw a little circle + if (trace) ellipse(0, 0, erad, erad); // draw with erad if tracing + pop(); // go down one level + translate(0, radius); // move into position for next sine + sines[i] = (sines[i] + (fund + (fund * i * ratio))) % TWO_PI; // update angle based on fundamental + } + + pop(); // pop down final transformation + +} + +function keyReleased() { + if (key==' ') { + trace = !trace; + background(255); + } +} diff --git a/dist/assets/examples/zh-Hans/09_Simulate/07_LSystems.js b/dist/assets/examples/zh-Hans/09_Simulate/07_LSystems.js new file mode 100644 index 0000000000..c5a7902950 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/07_LSystems.js @@ -0,0 +1,106 @@ +/* + * @name L-Systems + * @description This sketch creates an automated drawing based on a Lindenmayer + * or (L-) system. L-systems are often used in procedural graphics to make + * natural, geometric, or interesting "fractal-style" patterns.
+ * Example created by R. Luke DuBois.
+ * https://en.wikipedia.org/wiki/L-system + */ +// TURTLE STUFF: +let x, y; // the current position of the turtle +let currentangle = 0; // which way the turtle is pointing +let step = 20; // how much the turtle moves with each 'F' +let angle = 90; // how much the turtle turns with a '-' or '+' + +// LINDENMAYER STUFF (L-SYSTEMS) +let thestring = 'A'; // "axiom" or start of the string +let numloops = 5; // how many iterations to pre-compute +let therules = []; // array for rules +therules[0] = ['A', '-BF+AFA+FB-']; // first rule +therules[1] = ['B', '+AF-BFB-FA+']; // second rule + +let whereinstring = 0; // where in the L-system are we? + +function setup() { + createCanvas(710, 400); + background(255); + stroke(0, 0, 0, 255); + + // start the x and y position at lower-left corner + x = 0; + y = height - 1; + + // COMPUTE THE L-SYSTEM + for (let i = 0; i < numloops; i++) { + thestring = lindenmayer(thestring); + } +} + +function draw() { + + // draw the current character in the string: + drawIt(thestring[whereinstring]); + + // increment the point for where we're reading the string. + // wrap around at the end. + whereinstring++; + if (whereinstring > thestring.length - 1) whereinstring = 0; + +} + +// interpret an L-system +function lindenmayer(s) { + let outputstring = ''; // start a blank output string + + // iterate through 'therules' looking for symbol matches: + for (let i = 0; i < s.length; i++) { + let ismatch = 0; // by default, no match + for (let j = 0; j < therules.length; j++) { + if (s[i] == therules[j][0]) { + outputstring += therules[j][1]; // write substitution + ismatch = 1; // we have a match, so don't copy over symbol + break; // get outta this for() loop + } + } + // if nothing matches, just copy the symbol over. + if (ismatch == 0) outputstring+= s[i]; + } + + return outputstring; // send out the modified string +} + +// this is a custom function that draws turtle commands +function drawIt(k) { + + if (k=='F') { // draw forward + // polar to cartesian based on step and currentangle: + let x1 = x + step*cos(radians(currentangle)); + let y1 = y + step*sin(radians(currentangle)); + line(x, y, x1, y1); // connect the old and the new + + // update the turtle's position: + x = x1; + y = y1; + } else if (k == '+') { + currentangle += angle; // turn left + } else if (k == '-') { + currentangle -= angle; // turn right + } + + // give me some random color values: + let r = random(128, 255); + let g = random(0, 192); + let b = random(0, 50); + let a = random(50, 100); + + // pick a gaussian (D&D) distribution for the radius: + let radius = 0; + radius += random(0, 15); + radius += random(0, 15); + radius += random(0, 15); + radius = radius/3; + + // draw the stuff: + fill(r, g, b, a); + ellipse(x, y, radius, radius); +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/09_Simulate/08_Spring.js b/dist/assets/examples/zh-Hans/09_Simulate/08_Spring.js new file mode 100644 index 0000000000..2d0fc96a0a --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/08_Spring.js @@ -0,0 +1,92 @@ +/* + * @name Spring + * @frame 710, 400 + * @description Click, drag, and release the horizontal bar to start the spring. + */ +// Spring drawing constants for top bar +let springHeight = 32, + left, + right, + maxHeight = 200, + minHeight = 100, + over = false, + move = false; + +// Spring simulation constants +let M = 0.8, // Mass + K = 0.2, // Spring constant + D = 0.92, // Damping + R = 150; // Rest position + +// Spring simulation variables +let ps = R, // Position + vs = 0.0, // Velocity + as = 0, // Acceleration + f = 0; // Force + +function setup() { + createCanvas(710, 400); + rectMode(CORNERS); + noStroke(); + left = width / 2 - 100; + right = width / 2 + 100; +} + +function draw() { + background(102); + updateSpring(); + drawSpring(); +} + +function drawSpring() { + // Draw base + fill(0.2); + let baseWidth = 0.5 * ps + -8; + rect(width/2 - baseWidth, ps + springHeight, width / 2 + baseWidth, height); + + // Set color and draw top bar + if (over || move) { + fill(255); + } else { + fill(204); + } + + rect(left, ps, right, ps + springHeight); +} + +function updateSpring() { + // Update the spring position + if ( !move ) { + f = -K * ( ps - R ); // f=-ky + as = f / M; // Set the acceleration, f=ma == a=f/m + vs = D * (vs + as); // Set the velocity + ps = ps + vs; // Updated position + } + + if (abs(vs) < 0.1) { + vs = 0.0; + } + + // Test if mouse if over the top bar + if (mouseX > left && mouseX < right && mouseY > ps && mouseY < ps + springHeight) { + over = true; + } else { + over = false; + } + + // Set and constrain the position of top bar + if (move) { + ps = mouseY - springHeight / 2; + ps = constrain(ps, minHeight, maxHeight); + } +} + +function mousePressed() { + if (over) { + move = true; + } +} + +function mouseReleased() { + move = false; +} diff --git a/dist/assets/examples/zh-Hans/09_Simulate/09_Springs.js b/dist/assets/examples/zh-Hans/09_Simulate/09_Springs.js new file mode 100644 index 0000000000..ed0a185a65 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/09_Springs.js @@ -0,0 +1,147 @@ +/* + * @name Springs + * @frame 710,400 + * @description Move the mouse over one of the circles and click to re-position. + * When you release the mouse, it will snap back into position. + * Each circle has a slightly different behavior. + * (ported from https://processing.org/examples/springs.html) + */ +let num = 3; +let springs = []; + +function setup() { + createCanvas(710, 400); + noStroke(); + + springs[0] = new Spring(240, 260, 40, 0.98, 8.0, 0.1, springs, 0); + springs[1] = new Spring(320, 210, 120, 0.95, 9.0, 0.1, springs, 1); + springs[2] = new Spring(180, 170, 200, 0.90, 9.9, 0.1, springs, 2); +} + +function draw() { + background(51); + + for (let i = 0; i < num; i++) { + springs[i].update(); + springs[i].display(); + } +} + +function mousePressed() { + for (let i = 0; i < num; i++) { + springs[i].pressed(); + } +} + +function mouseReleased() { + for (let i = 0; i < num; i++) { + springs[i].released(); + } +} + +// Spring class +function Spring (_x, _y, _s, _d, _m, _k_in, _others, _id) { + // Screen values + // this.xpos = _x; + // this.ypos = _y; + + this.x_pos = _x; + this.y_pos= _y; + + this.size = 20; + this.size = _s; + + this.over = false; + this.move = false; + + // Spring simulation constants + this.mass = _m; // Mass + this.k = 0.2; // Spring constant + this.k = _k_in; + this.damp = _d; // Damping + this.rest_posx = _x; // Rest position X + this.rest_posy = _y; // Rest position Y + + // Spring simulation variables + //float pos = 20.0; // Position + this.velx = 0.0; // X Velocity + this.vely = 0.0; // Y Velocity + this.accel = 0; // Acceleration + this.force = 0; // Force + + this.friends = _others; + this.id = _id; + + this.update = function() { + + if (this.move) { + this.rest_posy = mouseY; + this.rest_posx = mouseX; + } + + this.force = -this.k * (this.y_pos - this.rest_posy); // f=-ky + this.accel = this.force / this.mass; // Set the acceleration, f=ma == a=f/m + this.vely = this.damp * (this.vely + this.accel); // Set the velocity + this.y_pos = this.y_pos + this.vely; // Updated position + + + this.force = -this.k * (this.x_pos - this.rest_posx); // f=-ky + this.accel = this.force / this.mass; // Set the acceleration, f=ma == a=f/m + this.velx = this.damp * (this.velx + this.accel); // Set the velocity + this.x_pos = this.x_pos + this.velx; // Updated position + + + if ((this.overEvent() || this.move) && !(this.otherOver()) ) { + this.over = true; + } else { + this.over = false; + } + } + + // Test to see if mouse is over this spring + this.overEvent = function() { + let disX = this.x_pos - mouseX; + let disY = this.y_pos - mouseY; + let dis = createVector(disX, disY); + if (dis.mag() < this.size / 2 ) { + return true; + } else { + return false; + } + } + + // Make sure no other springs are active + this.otherOver = function() { + for (let i=0; i < num; i++) { + if (i != this.id) { + if (this.friends[i].over == true) { + return true; + } + } + } + return false; + } + + this.display = function() { + if (this.over) { + fill(153); + } else { + fill(255); + } + ellipse(this.x_pos, this.y_pos, this.size, this.size); + } + + this.pressed = function() { + if (this.over) { + this.move = true; + } else { + this.move = false; + } + } + + this.released = function() { + this.move = false; + this.rest_posx = this.y_pos; + this.rest_posy = this.y_pos; + } +}; \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/09_Simulate/10_SoftBody.js b/dist/assets/examples/zh-Hans/09_Simulate/10_SoftBody.js new file mode 100644 index 0000000000..b227393300 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/10_SoftBody.js @@ -0,0 +1,110 @@ +/* + * @name Soft Body + * @description Original example by Ira Greenberg. + *

Softbody dynamics simulation using curveVertex() and curveTightness(). + */ +// center point +let centerX = 0.0, centerY = 0.0; + +let radius = 45, rotAngle = -90; +let accelX = 0.0, accelY = 0.0; +let deltaX = 0.0, deltaY = 0.0; +let springing = 0.0009, damping = 0.98; + +//corner nodes +let nodes = 5; + +//zero fill arrays +let nodeStartX = []; +let nodeStartY = []; +let nodeX = []; +let nodeY = []; +let angle = []; +let frequency = []; + +// soft-body dynamics +let organicConstant = 1.0; + +function setup() { + createCanvas(710, 400); + + //center shape in window + centerX = width / 2; + centerY = height / 2; + + //initialize arrays to 0 + for (let i = 0; i < nodes; i++){ + nodeStartX[i] = 0; + nodeStartY[i] = 0; + nodeY[i] = 0; + nodeY[i] = 0; + angle[i] = 0; + } + + // iniitalize frequencies for corner nodes + for (let i = 0; i < nodes; i++){ + frequency[i] = random(5, 12); + } + + noStroke(); + frameRate(30); +} + +function draw() { + //fade background + fill(0, 100); + rect(0, 0, width, height); + drawShape(); + moveShape(); +} + +function drawShape() { + // calculate node starting locations + for (let i = 0; i < nodes; i++){ + nodeStartX[i] = centerX + cos(radians(rotAngle)) * radius; + nodeStartY[i] = centerY + sin(radians(rotAngle)) * radius; + rotAngle += 360.0 / nodes; + } + + // draw polygon + curveTightness(organicConstant); + fill(255); + beginShape(); + for (let i = 0; i < nodes; i++){ + curveVertex(nodeX[i], nodeY[i]); + } + for (let i = 0; i < nodes-1; i++){ + curveVertex(nodeX[i], nodeY[i]); + } + endShape(CLOSE); +} + +function moveShape() { + //move center point + deltaX = mouseX - centerX; + deltaY = mouseY - centerY; + + // create springing effect + deltaX *= springing; + deltaY *= springing; + accelX += deltaX; + accelY += deltaY; + + // move predator's center + centerX += accelX; + centerY += accelY; + + // slow down springing + accelX *= damping; + accelY *= damping; + + // change curve tightness + organicConstant = 1 - ((abs(accelX) + abs(accelY)) * 0.1); + + //move nodes + for (let i = 0; i < nodes; i++){ + nodeX[i] = nodeStartX[i] + sin(radians(angle[i])) * (accelX * 2); + nodeY[i] = nodeStartY[i] + sin(radians(angle[i])) * (accelY * 2); + angle[i] += frequency[i]; + } +} diff --git a/dist/assets/examples/zh-Hans/09_Simulate/11_SmokeParticleSystem.js b/dist/assets/examples/zh-Hans/09_Simulate/11_SmokeParticleSystem.js new file mode 100644 index 0000000000..c82e6b141c --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/11_SmokeParticleSystem.js @@ -0,0 +1,180 @@ +/* + * @name SmokeParticles + * @description a port of Dan Shiffman's SmokeParticleSystem example originally + * for Processing. Creates smokey particles :p + */ + +// texture for the particle +let particle_texture = null; + +// variable holding our particle system +let ps = null; + +function preload() { + particle_texture = loadImage("assets/particle_texture.png"); +} + +function setup() { + + //set the canvas size + createCanvas(640, 360); + + //initialize our particle system + ps = new ParticleSystem(0, createVector(width / 2, height - 60), particle_texture); +} + +function draw() { + background(0); + + let dx = map(mouseX, 0, width, -0.2, 0.2); + let wind = createVector(dx, 0); + + ps.applyForce(wind); + ps.run(); + for (let i = 0; i < 2; i++) { + ps.addParticle(); + } + + // Draw an arrow representing the wind force + drawVector(wind, createVector(width / 2, 50, 0), 500); +} + +/** + * This function draws an arrow showing the direction our "wind" is blowing. + */ +function drawVector(v, loc, scale){ + push(); + let arrowsize = 4; + translate(loc.x,loc.y); + stroke(255); + rotate(v.heading()); + + let len = v.mag() * scale; + line(0, 0, len, 0); + line(len, 0, len - arrowsize, +arrowsize / 2); + line(len, 0, len - arrowsize, -arrowsize / 2); + pop(); +} +//========= PARTICLE SYSTEM =========== + +/** + * A basic particle system class + * @param num the number of particles + * @param v the origin of the particle system + * @param img_ a texture for each particle in the system + * @constructor + */ +let ParticleSystem = function(num, v, img_) { + + this.particles = []; + this.origin = v.copy(); // we make sure to copy the vector value in case we accidentally mutate the original by accident + this.img = img_ + for(let i = 0; i < num; ++i){ + this.particles.push(new Particle(this.origin, this.img)); + } +}; + +/** + * This function runs the entire particle system. + */ +ParticleSystem.prototype.run = function() { + + // cache length of the array we're going to loop into a variable + // You may see .length in a for loop, from time to time but + // we cache it here because otherwise the length is re-calculated for each iteration of a loop + let len = this.particles.length; + + //loop through and run particles + for (let i = len - 1; i >= 0; i--) { + let particle = this.particles[i]; + particle.run(); + + // if the particle is dead, we remove it. + // javascript arrays don't have a "remove" function but "splice" works just as well. + // we feed it an index to start at, then how many numbers from that point to remove. + if (particle.isDead()) { + this.particles.splice(i, 1); + } + } +} + +/** + * Method to add a force vector to all particles currently in the system + * @param dir a p5.Vector describing the direction of the force. + */ +ParticleSystem.prototype.applyForce = function(dir) { + let len = this.particles.length; + for(let i = 0; i < len; ++i){ + this.particles[i].applyForce(dir); + } +} + +/** + * Adds a new particle to the system at the origin of the system and with + * the originally set texture. + */ +ParticleSystem.prototype.addParticle = function() { + this.particles.push(new Particle(this.origin, this.img)); +} + +//========= PARTICLE =========== +/** + * A simple Particle class, renders the particle as an image + */ +let Particle = function (pos, img_) { + this.loc = pos.copy(); + + let vx = randomGaussian() * 0.3; + let vy = randomGaussian() * 0.3 - 1.0; + + this.vel = createVector(vx, vy); + this.acc = createVector(); + this.lifespan = 100.0; + this.texture = img_; +} + +/** + * Simulataneously updates and displays a particle. + */ +Particle.prototype.run = function() { + this.update(); + this.render(); +} + +/** + * A function to display a particle + */ +Particle.prototype.render = function() { + imageMode(CENTER); + tint(255, this.lifespan); + image(this.texture, this.loc.x, this.loc.y); +} + +/** + * A method to apply a force vector to a particle. + */ +Particle.prototype.applyForce = function(f) { + this.acc.add(f); +} + +/** + * This method checks to see if the particle has reached the end of it's lifespan, + * if it has, return true, otherwise return false. + */ +Particle.prototype.isDead = function () { + if (this.lifespan <= 0.0) { + return true; + } else { + return false; + } +} + +/** + * This method updates the position of the particle. + */ +Particle.prototype.update = function() { + this.vel.add(this.acc); + this.loc.add(this.vel); + this.lifespan -= 2.5; + this.acc.mult(0); +} diff --git a/dist/assets/examples/zh-Hans/09_Simulate/12_BrownianMotion.js b/dist/assets/examples/zh-Hans/09_Simulate/12_BrownianMotion.js new file mode 100644 index 0000000000..449e5ad27e --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/12_BrownianMotion.js @@ -0,0 +1,46 @@ +/* + * @name Brownian Motion + * @description Recording random movement as a continuous line. + * Port of original example from the Processing examples page. + */ + +let num = 2000; +let range = 6; + +let ax = []; +let ay = []; + + +function setup() { + createCanvas(710, 400); + for ( let i = 0; i < num; i++ ) { + ax[i] = width / 2; + ay[i] = height / 2; + } + frameRate(30); +} + +function draw() { + background(51); + + // Shift all elements 1 place to the left + for ( let i = 1; i < num; i++ ) { + ax[i - 1] = ax[i]; + ay[i - 1] = ay[i]; + } + + // Put a new value at the end of the array + ax[num - 1] += random(-range, range); + ay[num - 1] += random(-range, range); + + // Constrain all points to the screen + ax[num - 1] = constrain(ax[num - 1], 0, width); + ay[num - 1] = constrain(ay[num - 1], 0, height); + + // Draw a line connecting the points + for ( let j = 1; j < num; j++ ) { + let val = j / num * 204.0 + 51; + stroke(val); + line(ax[j - 1], ay[j - 1], ax[j], ay[j]); + } +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/09_Simulate/13_Chain.js b/dist/assets/examples/zh-Hans/09_Simulate/13_Chain.js new file mode 100644 index 0000000000..ba52c54587 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/13_Chain.js @@ -0,0 +1,55 @@ +/* + * @name Chain + * @description One mass is attached to the mouse position and the other is attached the position of the other mass. The gravity in the environment pulls down on both. + * Ported from the Processing Examples page. + */ +let s1, s2; +let gravity = 9.0; +let mass = 2.0; + +function setup() { + createCanvas(720, 400); + fill(255, 126); + // Inputs: x, y, mass, gravity + s1 = new Spring2D(0.0, width / 2, mass, gravity); + s2 = new Spring2D(0.0, width / 2, mass, gravity); +} + +function draw() { + background(0); + s1.update(mouseX, mouseY); + s1.display(mouseX, mouseY); + s2.update(s1.x, s1.y); + s2.display(s1.x, s1.y); +} + +function Spring2D(xpos, ypos, m, g) { + this.x = xpos;// The x- and y-coordinates + this.y = ypos; + this.vx = 0; // The x- and y-axis velocities + this.vy = 0; + this.mass = m; + this.gravity = g; + this.radius = 30; + this.stiffness = 0.2; + this.damping = 0.7; + + this.update = function(targetX, targetY) { + let forceX = (targetX - this.x) * this.stiffness; + let ax = forceX / this.mass; + this.vx = this.damping * (this.vx + ax); + this.x += this.vx; + let forceY = (targetY - this.y) * this.stiffness; + forceY += this.gravity; + let ay = forceY / this.mass; + this.vy = this.damping * (this.vy + ay); + this.y += this.vy; + } + + this.display = function(nx, ny) { + noStroke(); + ellipse(this.x, this.y, this.radius * 2, this.radius * 2); + stroke(255); + line(this.x, this.y, nx, ny); + } +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/09_Simulate/14_SnowflakeParticleSystem.js b/dist/assets/examples/zh-Hans/09_Simulate/14_SnowflakeParticleSystem.js new file mode 100644 index 0000000000..0956a80792 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/14_SnowflakeParticleSystem.js @@ -0,0 +1,63 @@ +/* + * @name Snowflakes + * @description Particle system simulating the motion of falling snowflakes. + * Uses an array of objects to hold the snowflake particles. + * Contributed by Aatish Bhatia. + */ + +let snowflakes = []; // array to hold snowflake objects + +function setup() { + createCanvas(400, 600); + fill(240); + noStroke(); +} + +function draw() { + background('brown'); + let t = frameCount / 60; // update time + + // create a random number of snowflakes each frame + for (let i = 0; i < random(5); i++) { + snowflakes.push(new snowflake()); // append snowflake object + } + + // loop through snowflakes with a for..of loop + for (let flake of snowflakes) { + flake.update(t); // update snowflake position + flake.display(); // draw snowflake + } +} + +// snowflake class +function snowflake() { + // initialize coordinates + this.posX = 0; + this.posY = random(-50, 0); + this.initialangle = random(0, 2 * PI); + this.size = random(2, 5); + + // radius of snowflake spiral + // chosen so the snowflakes are uniformly spread out in area + this.radius = sqrt(random(pow(width / 2, 2))); + + this.update = function(time) { + // x position follows a circle + let w = 0.6; // angular speed + let angle = w * time + this.initialangle; + this.posX = width / 2 + this.radius * sin(angle); + + // different size snowflakes fall at slightly different y speeds + this.posY += pow(this.size, 0.5); + + // delete snowflake if past end of screen + if (this.posY > height) { + let index = snowflakes.indexOf(this); + snowflakes.splice(index, 1); + } + }; + + this.display = function() { + ellipse(this.posX, this.posY, this.size); + }; +} diff --git a/dist/assets/examples/zh-Hans/09_Simulate/15_penrose_tiles.js b/dist/assets/examples/zh-Hans/09_Simulate/15_penrose_tiles.js new file mode 100644 index 0000000000..41987d4ebd --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/15_penrose_tiles.js @@ -0,0 +1,125 @@ +/* + * @name Penrose Tiles + * @frame 710,400 + * @description This is a port by David Blitz of the "Penrose Tile" example from processing.org/examples + */ + +let ds; + +function setup() { + createCanvas(710, 400); + ds = new PenroseLSystem(); + //please, play around with the following line + ds.simulate(5); +} + +function draw() { + background(0); + ds.render(); +} + +function PenroseLSystem() { + this.steps = 0; + + //these are axiom and rules for the penrose rhombus l-system + //a reference would be cool, but I couldn't find a good one + this.axiom = "[X]++[X]++[X]++[X]++[X]"; + this.ruleW = "YF++ZF----XF[-YF----WF]++"; + this.ruleX = "+YF--ZF[---WF--XF]+"; + this.ruleY = "-WF++XF[+++YF++ZF]-"; + this.ruleZ = "--YF++++WF[+ZF++++XF]--XF"; + + //please play around with the following two lines + this.startLength = 460.0; + this.theta = TWO_PI / 10.0; //36 degrees, try TWO_PI / 6.0, ... + this.reset(); +} + +PenroseLSystem.prototype.simulate = function (gen) { + while (this.getAge() < gen) { + this.iterate(this.production); + } +} + +PenroseLSystem.prototype.reset = function () { + this.production = this.axiom; + this.drawLength = this.startLength; + this.generations = 0; +} + +PenroseLSystem.prototype.getAge = function () { + return this.generations; +} + +//apply substitution rules to create new iteration of production string +PenroseLSystem.prototype.iterate = function() { + let newProduction = ""; + + for(let i = 0; i < this.production.length; ++i) { + let step = this.production.charAt(i); + //if current character is 'W', replace current character + //by corresponding rule + if (step == 'W') { + newProduction = newProduction + this.ruleW; + } + else if (step == 'X') { + newProduction = newProduction + this.ruleX; + } + else if (step == 'Y') { + newProduction = newProduction + this.ruleY; + } + else if (step == 'Z') { + newProduction = newProduction + this.ruleZ; + } + else { + //drop all 'F' characters, don't touch other + //characters (i.e. '+', '-', '[', ']' + if (step != 'F') { + newProduction = newProduction + step; + } + } + } + + this.drawLength = this.drawLength * 0.5; + this.generations++; + this.production = newProduction; +} + +//convert production string to a turtle graphic +PenroseLSystem.prototype.render = function () { + translate(width / 2, height / 2); + + this.steps += 20; + if(this.steps > this.production.length) { + this.steps = this.production.length; + } + + for(let i = 0; i < this.steps; ++i) { + let step = this.production.charAt(i); + + //'W', 'X', 'Y', 'Z' symbols don't actually correspond to a turtle action + if( step == 'F') { + stroke(255, 60); + for(let j=0; j < this.repeats; j++) { + line(0, 0, 0, -this.drawLength); + noFill(); + translate(0, -this.drawLength); + } + this.repeats = 1; + } + else if (step == '+') { + rotate(this.theta); + } + else if (step == '-') { + rotate(-this.theta); + } + else if (step == '[') { + push(); + } + else if (step == ']') { + pop(); + } + } +} + + diff --git a/dist/assets/examples/zh-Hans/09_Simulate/16_Recursive_Tree.js b/dist/assets/examples/zh-Hans/09_Simulate/16_Recursive_Tree.js new file mode 100644 index 0000000000..c86a08e6a1 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/16_Recursive_Tree.js @@ -0,0 +1,55 @@ +/* + * @name Recursive Tree + * @description Renders a simple tree-like structure via recursion. + * The branching angle is calculated as a function of the horizontal mouse + * location. Move the mouse left and right to change the angle. + * Based on Daniel Shiffman's Recursive Tree Example for Processing. + */ +let theta; + +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(0); + frameRate(30); + stroke(255); + // Let's pick an angle 0 to 90 degrees based on the mouse position + let a = (mouseX / width) * 90; + // Convert it to radians + theta = radians(a); + // Start the tree from the bottom of the screen + translate(width/2,height); + // Draw a line 120 pixels + line(0,0,0,-120); + // Move to the end of that line + translate(0,-120); + // Start the recursive branching! + branch(120); + +} + +function branch(h) { + // Each branch will be 2/3rds the size of the previous one + h *= 0.66; + + // All recursive functions must have an exit condition!!!! + // Here, ours is when the length of the branch is 2 pixels or less + if (h > 2) { + push(); // Save the current state of transformation (i.e. where are we now) + rotate(theta); // Rotate by theta + line(0, 0, 0, -h); // Draw the branch + translate(0, -h); // Move to the end of the branch + branch(h); // Ok, now call myself to draw two new branches!! + pop(); // Whenever we get back here, we "pop" in order to restore the previous matrix state + + // Repeat the same thing, only branch off to the "left" this time! + push(); + rotate(-theta); + line(0, 0, 0, -h); + translate(0, -h); + branch(h); + pop(); + } +} diff --git a/dist/assets/examples/zh-Hans/09_Simulate/17_Mandelbrot.js b/dist/assets/examples/zh-Hans/09_Simulate/17_Mandelbrot.js new file mode 100644 index 0000000000..76b0bdc4b2 --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/17_Mandelbrot.js @@ -0,0 +1,86 @@ +/* + * @name The Mandelbrot Set + * @description Simple rendering of the Mandelbrot set. + * Based on Daniel Shiffman's Mandelbrot Example for Processing. + */ + +function setup() { + createCanvas(710, 400); + pixelDensity(1); + noLoop(); +} + +function draw() { + background(0); + + // Establish a range of values on the complex plane + // A different range will allow us to "zoom" in or out on the fractal + + // It all starts with the width, try higher or lower values + const w = 4; + const h = (w * height) / width; + + // Start at negative half the width and height + const xmin = -w/2; + const ymin = -h/2; + + // Make sure we can write to the pixels[] array. + // Only need to do this once since we don't do any other drawing. + loadPixels(); + + // Maximum number of iterations for each point on the complex plane + const maxiterations = 100; + + // x goes from xmin to xmax + const xmax = xmin + w; + // y goes from ymin to ymax + const ymax = ymin + h; + + // Calculate amount we increment x,y for each pixel + const dx = (xmax - xmin) / (width); + const dy = (ymax - ymin) / (height); + + // Start y + let y = ymin; + for (let j = 0; j < height; j++) { + // Start x + let x = xmin; + for (let i = 0; i < width; i++) { + + // Now we test, as we iterate z = z^2 + cm does z tend towards infinity? + let a = x; + let b = y; + let n = 0; + while (n < maxiterations) { + const aa = a * a; + const bb = b * b; + const twoab = 2.0 * a * b; + a = aa - bb + x; + b = twoab + y; + // Infinty in our finite world is simple, let's just consider it 16 + if (dist(aa, bb, 0, 0) > 16) { + break; // Bail + } + n++; + } + + // We color each pixel based on how long it takes to get to infinity + // If we never got there, let's pick the color black + const pix = (i+j*width)*4; + const norm = map(n, 0, maxiterations, 0, 1); + let bright = map(sqrt(norm), 0, 1, 0, 255); + if (n == maxiterations) { + bright = 0; + } else { + // Gosh, we could make fancy colors here if we wanted + pixels[pix + 0] = bright; + pixels[pix + 1] = bright; + pixels[pix + 2] = bright; + pixels[pix + 3] = 255; + } + x += dx; + } + y += dy; + } + updatePixels(); +} diff --git a/dist/assets/examples/zh-Hans/09_Simulate/18_Koch.js b/dist/assets/examples/zh-Hans/09_Simulate/18_Koch.js new file mode 100644 index 0000000000..e3323141ca --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/18_Koch.js @@ -0,0 +1,140 @@ +/* + * @name Koch Curve + * @description Renders a simple fractal, the Koch snowflake. Each recursive level is drawn in sequence. + * By Daniel Shiffman + */ + +let k; + +function setup() { + createCanvas(710, 400); + frameRate(1); // Animate slowly + k = new KochFractal(); +} + +function draw() { + background(0); + // Draws the snowflake! + k.render(); + // Iterate + k.nextLevel(); + // Let's not do it more than 5 times. . . + if (k.getCount() > 5) { + k.restart(); + } +} + +// A class to describe one line segment in the fractal +// Includes methods to calculate midp5.Vectors along the line according to the Koch algorithm + +class KochLine { + constructor(a,b) { + // Two p5.Vectors, + // start is the "left" p5.Vector and + // end is the "right p5.Vector + this.start = a.copy(); + this.end = b.copy(); + } + + display() { + stroke(255); + line(this.start.x, this.start.y, this.end.x, this.end.y); + } + + kochA() { + return this.start.copy(); + } + + // This is easy, just 1/3 of the way + kochB() { + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + v.add(this.start); + return v; + } + + // More complicated, have to use a little trig to figure out where this p5.Vector is! + kochC() { + let a = this.start.copy(); // Start at the beginning + let v = p5.Vector.sub(this.end, this.start); + v.div(3); + a.add(v); // Move to point B + v.rotate(-PI/3); // Rotate 60 degrees + a.add(v); // Move to point C + return a; + } + + // Easy, just 2/3 of the way + kochD() { + let v = p5.Vector.sub(this.end, this.start); + v.mult(2/3.0); + v.add(this.start); + return v; + } + + kochE() { + return this.end.copy(); + } +} + +// A class to manage the list of line segments in the snowflake pattern + +class KochFractal { + constructor() { + this.start = createVector(0,height-20); // A p5.Vector for the start + this.end = createVector(width,height-20); // A p5.Vector for the end + this.lines = []; // An array to keep track of all the lines + this.count = 0; + this.restart(); + } + nextLevel() { + // For every line that is in the arraylist + // create 4 more lines in a new arraylist + this.lines = this.iterate(this.lines); + this.count++; + } + + restart() { + this.count = 0; // Reset count + this.lines = []; // Empty the array list + this.lines.push(new KochLine(this.start,this.end)); // Add the initial line (from one end p5.Vector to the other) + } + + getCount() { + return this.count; + } + + // This is easy, just draw all the lines + render() { + for(let i = 0; i < this.lines.length; i++) { + this.lines[i].display(); + } + } + + // This is where the **MAGIC** happens + // Step 1: Create an empty arraylist + // Step 2: For every line currently in the arraylist + // - calculate 4 line segments based on Koch algorithm + // - add all 4 line segments into the new arraylist + // Step 3: Return the new arraylist and it becomes the list of line segments for the structure + + // As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . . + iterate(before) { + let now = []; // Create emtpy list + for(let i = 0; i < this.lines.length; i++) { + let l = this.lines[i]; + // Calculate 5 koch p5.Vectors (done for us by the line object) + let a = l.kochA(); + let b = l.kochB(); + let c = l.kochC(); + let d = l.kochD(); + let e = l.kochE(); + // Make line segments between all the p5.Vectors and add them + now.push(new KochLine(a,b)); + now.push(new KochLine(b,c)); + now.push(new KochLine(c,d)); + now.push(new KochLine(d,e)); + } + return now; + } +} diff --git a/dist/assets/examples/zh-Hans/09_Simulate/19_Bubblesort.js b/dist/assets/examples/zh-Hans/09_Simulate/19_Bubblesort.js new file mode 100644 index 0000000000..85d3402dfb --- /dev/null +++ b/dist/assets/examples/zh-Hans/09_Simulate/19_Bubblesort.js @@ -0,0 +1,67 @@ +/* + * @name Bubble Sort + * @description Sorts the randomly distributed bars + * according to their height in ascending order + * while simulating the whole sorting process. + * Took references from Coding Challenge by The Coding Train. + */ + +let values = []; +let i = 0; +let j = 0; + +// The statements in the setup() function +// execute once when the program begins +// The array is filled with random values in setup() function. +function setup() { + createCanvas(720, 400); + for(let i = 0;i values[j+1]){ + values[j] = values[j+1]; + values[j+1] = temp; + } + j++; + + if(j>=values.length-i-1){ + j = 0; + i++; + } + } + else{ + noLoop(); + } + } +} + +// The simulateSorting() function helps in animating +// the whole bubble sort algorithm +// by drawing the rectangles using values +// in the array as the length of the rectangle. +function simulateSorting(){ + for(let i = 0;i= width || this.xPos <= 0){ + this.xSpeed*=-1; + } + } +} + +function setup() { + createCanvas(720, 400); + createP("Keep the mouse clicked").style('color','#ffffff'); + createP("to check whether the bricks").style('color','#ffffff'); + createP("are moving at same speed or not").style('color','#ffffff'); +} + +// creating two bricks of +// colors white and black +let brick1 = new Brick("white",100); +let brick2 = new Brick("black",250); + +// +brick1.setSpeed(); +brick2.setSpeed(); + +function draw () { + background(0); + if(mouseIsPressed){ + background(50); + } + brick1.createBrick(); + brick1.moveBrick(); + if(!mouseIsPressed){ + createBars(); + } + brick2.createBrick(); + brick2.moveBrick(); +} + +// this function creates the black and +// white bars across the screen +function createBars() { + let len = 12; + for(let i = 0;i width) + this.xSpeed*=-1; + if(this.y < 0 || this.y > height) + this.ySpeed*=-1; + this.x+=this.xSpeed; + this.y+=this.ySpeed; + } + +// this function creates the connections(lines) +// between particles which are less than a certain distance apart + joinParticles(paraticles) { + particles.forEach(element =>{ + let dis = dist(this.x,this.y,element.x,element.y); + if(dis<85) { + stroke('rgba(255,255,255,0.04)'); + line(this.x,this.y,element.x,element.y); + } + }); + } +} + +// an array to add multiple particles +let particles = []; + +function setup() { + createCanvas(720, 400); + for(let i = 0;i
+ * Quicksort is a divide-and-conquer algorithm: it + * performs sorting by dividing the original array into + * smaller subarrays and solving them independently, + * loosely speaking. It involves picking an element of + * the array as the pivot element and partitioning the + * given array around the picked pivot.
+ * Partitioning refers to arranging the given array(or + * subarray) in such a way that all elements to the left + * of the pivot element are smaller than it and all + * elements to its right are larger than it. Thus, we have + * a reference point from where we proceed to sort the + * left and right 'halves' of the array, and eventually + * arrive at an array sorted in ascending order. + * + * More
+ */ + +// width of each bar is taken as 8. +let values = []; +// The array 'states' helps in identifying the pivot index +// at every step, and also the subarray which is being sorted +// at any given time. +let states = []; + +// The setup() function is called once when the program +// starts. Here, we fill the array 'values' with random values +// and the array 'states' with a value of -1 for each position. +function setup() { + createCanvas(710, 400); + for(let i = 0; i < width/8; i++) { + values.push(random(height)); + states.push(-1); + } + quickSort(0, values.length - 1); +} + +// The statements in draw() function are executed continuously +// until the program is stopped. Each statement is executed +// sequentially and after the last line is read, the first +// line is executed again. +function draw() { + background(140); + for(let i = 0; i < values.length; i++) { + // color coding + if (states[i] == 0) { + // color for the bar at the pivot index + fill('#E0777D'); + } else if (states[i] == 1) { + // color for the bars being sorted currently + fill('#D6FFB7'); + } else { + fill(255); + } + rect(i * 8, height - values[i], 8, values[i]); + } +} + +async function quickSort(start, end) { + if (start > end) { // Nothing to sort! + return; + } + // partition() returns the index of the pivot element. + // Once partition() is executed, all elements to the + // left of the pivot element are smaller than it and + // all elements to its right are larger than it. + let index = await partition(start, end); + // restore original state + states[index] = -1; + await Promise.all( + [quickSort(start, index - 1), + quickSort(index + 1, end) + ]); +} + +// We have chosen the element at the last index as +// the pivot element, but we could've made different +// choices, e.g. take the first element as pivot. +async function partition(start, end) { + for (let i = start; i < end; i++) { + // identify the elements being considered currently + states[i] = 1; + } + // Quicksort algorithm + let pivotIndex = start; + // make pivot index distinct + states[pivotIndex] = 0; + let pivotElement = values[end]; + for (let i = start; i < end; i++) { + if (values[i] < pivotElement) { + await swap(i, pivotIndex); + states[pivotIndex] = -1; + pivotIndex++; + states[pivotIndex] = 0; + } + } + await swap(end, pivotIndex); + for (let i = start; i < end; i++) { + // restore original state + if (i != pivotIndex) { + states[i] = -1; + } + } + return pivotIndex; +} + +// swaps elements of 'values' at indices 'i' and 'j' +async function swap(i, j) { + // adjust the pace of the simulation by changing the + // value + await sleep(25); + let temp = values[i]; + values[i] = values[j]; + values[j] = temp; +} + +// custom helper function to deliberately slow down +// the sorting process and make visualization easy +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/10_Interaction/10_Tickle.js b/dist/assets/examples/zh-Hans/10_Interaction/10_Tickle.js new file mode 100644 index 0000000000..82b76bdbda --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/10_Tickle.js @@ -0,0 +1,48 @@ +/* + * @name Tickle + * @description "tickle" 这个单词会在光标移至它时抖动。 + * 有时还会抖出屏幕。 + */ +let message = 'tickle', + font, + bounds, // 存储文本框的 x, y, w, h 值 + fontsize = 60, + x, + y; // 文本的 x 和 y 坐标 + +function preload() { + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // 设置字体 + textFont(font); + textSize(fontsize); + + // 获取文本的宽度和高度,以便我们可以首先将其居中 + bounds = font.textBounds(message, 0, 0, fontsize); + x = width / 2 - bounds.w / 2; + y = height / 2 - bounds.h / 2; +} + +function draw() { + background(204, 120); + + // 写出黑色的文本并获取其文本框 + fill(0); + text(message, x, y); + bounds = font.textBounds(message, x, y, fontsize); + + // 检查鼠标是否在文本框里;如果在文本框内,抖动文本 + if ( + mouseX >= bounds.x && + mouseX <= bounds.x + bounds.w && + mouseY >= bounds.y && + mouseY <= bounds.y + bounds.h + ) { + x += random(-5, 5); + y += random(-5, 5); + } +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/11_WeightLine.js b/dist/assets/examples/zh-Hans/10_Interaction/11_WeightLine.js new file mode 100644 index 0000000000..a455dcb781 --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/11_WeightLine.js @@ -0,0 +1,55 @@ +/* + * @name Weight Line + * @frame 710,400 + * @description contributed by + Prof WM Harris, using the random function with events to color/weight a line
+ How to use the random function with events to color/ weight a line + dependent on mouse location, left mouse button clicks, character key types, and + random key releases.
+ Functions are created for both the canvas set up as well as the creation of + the line. Depending on the action taken by the user the line can + vary in width and color. Left mouse button clicks result in a color + change to blue, while the typing of any character key will change + the color to turquoise, each resulting in a variable stroke weight; + the width of the former will be between 0 – 1 while the width of + the latter will be 0 – 5. The release of any key will result in a + random hue, saturation, and brightness change to the line. + */ + + +function setup() { + createCanvas(400, 400); + background("beige"); + colorMode(HSB); + } + + function draw() { + //Line from prev pt to current pt + //of mouse position + line(mouseX, mouseY, pmouseX, pmouseY); + } + + //listen when we click the mouse + function mouseClicked() { + //weights 0 to 1 + stroke("slateBlue"); + strokeWeight(random()); + + //what if want weights 0 to .4? + //strokeWeight( random(.4) ); + } + + //listen when we release *any* key + function keyReleased() { + //color hue values between 20 and 145 + //saturation 0 to 100 + //brightness 80 to 100 + stroke(random(20, 145), random(100), random(80, 100)); + } + + //listen for only character keys + function keyTyped() { + //weights 0 to 5 + stroke("turquoise"); + strokeWeight(random(5)); + } \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/10_Interaction/20_Follow1.js b/dist/assets/examples/zh-Hans/10_Interaction/20_Follow1.js new file mode 100644 index 0000000000..290cec5a16 --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/20_Follow1.js @@ -0,0 +1,37 @@ +/* + * @name 跟随 1 + * @frame 710,400 + * @description 被光标拉扯的一条线段。 + * 基于 Keith Peters 的代码。 + */ +let x = 100, + y = 100, + angle1 = 0.0, + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + x = mouseX - cos(angle1) * segLength; + y = mouseY - sin(angle1) * segLength; + + segment(x, y, angle1); + ellipse(x, y, 20, 20); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/21_Follow2.js b/dist/assets/examples/zh-Hans/10_Interaction/21_Follow2.js new file mode 100644 index 0000000000..4d5c7e2aa5 --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/21_Follow2.js @@ -0,0 +1,39 @@ +/* + * @name 跟随 2 + * @frame 710,400 + * @description 跟随光标移动的两段式手臂。 + * 两个手臂之间的相对角度是用 atan2() 计算的,位置是用 sin() 和 cos() 计算的。 + * 基于 Keith Peters 的代码。 + */ +let x = [0, 0], + y = [0, 0], + segLength = 50; + +function setup() { + createCanvas(710, 400); + strokeWeight(20.0); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + dragSegment(1, x[0], y[0]); +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/22_Follow3.js b/dist/assets/examples/zh-Hans/10_Interaction/22_Follow3.js new file mode 100644 index 0000000000..155bf2783f --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/22_Follow3.js @@ -0,0 +1,47 @@ +/* + * @name 跟随 3 + * @frame 710,400 + * @description 随鼠标移动的一条分段式线条。 + * 每段之间的相对角度是用 atan2() 计算的,位置是用 sin() 和 cos() 计算的。 + * 基于 Keith Peters 的代码。 + */ +let x = [], + y = [], + segNum = 20, + segLength = 18; + +for (let i = 0; i < segNum; i++) { + x[i] = 0; + y[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(9); + stroke(255, 100); +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + const angle = atan2(dy, dx); + x[i] = xin - cos(angle) * segLength; + y[i] = yin - sin(angle) * segLength; + segment(x[i], y[i], angle); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/23_snake.js b/dist/assets/examples/zh-Hans/10_Interaction/23_snake.js new file mode 100644 index 0000000000..e72105780a --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/23_snake.js @@ -0,0 +1,164 @@ +/* + * @name 贪吃蛇 + * @description 著名的贪吃蛇游戏!点击 run 后,在黑色区域里任意点击, + * 使用 i j k 和 l 控制蛇。注意不要让蛇碰到自己或者墙。
+ * 由 Prashant Gupta 创作的范例 + */ + +// 蛇被分为几小段,在每次调用 draw() 时进行绘制和编辑 +let numSegments = 10; +let direction = 'right'; + +const xStart = 0; // 蛇的初始 x 坐标 +const yStart = 250; //蛇的初始 y 坐标 +const diff = 10; + +let xCor = []; +let yCor = []; + +let xFruit = 0; +let yFruit = 0; +let scoreElem; + +function setup() { + scoreElem = createDiv('Score = 0'); + scoreElem.position(20, 20); + scoreElem.id = 'score'; + scoreElem.style('color', 'white'); + + createCanvas(500, 500); + frameRate(15); + stroke(255); + strokeWeight(10); + updateFruitCoordinates(); + + for (let i = 0; i < numSegments; i++) { + xCor.push(xStart + i * diff); + yCor.push(yStart); + } +} + +function draw() { + background(0); + for (let i = 0; i < numSegments - 1; i++) { + line(xCor[i], yCor[i], xCor[i + 1], yCor[i + 1]); + } + updateSnakeCoordinates(); + checkGameStatus(); + checkForFruit(); +} + +/* + 根据蛇的方向更新每个小段。 + 从 0 至 n-1 的所有片段都被复制到 1 至 n,也就是说,段 0 获取 段 1 的值, + 段 1 获取 段 2 的值,以此类推。因此,蛇就会动起来了。 + + 最后一小段根据蛇运动的方向添加。如果蛇在左后移动,最后一小段的 x 坐标值将比倒数第二小段 + 增加预定义值 "diff";如果上下移动,则更改其 y 坐标值。 +*/ +function updateSnakeCoordinates() { + for (let i = 0; i < numSegments - 1; i++) { + xCor[i] = xCor[i + 1]; + yCor[i] = yCor[i + 1]; + } + switch (direction) { + case 'right': + xCor[numSegments - 1] = xCor[numSegments - 2] + diff; + yCor[numSegments - 1] = yCor[numSegments - 2]; + break; + case 'up': + xCor[numSegments - 1] = xCor[numSegments - 2]; + yCor[numSegments - 1] = yCor[numSegments - 2] - diff; + break; + case 'left': + xCor[numSegments - 1] = xCor[numSegments - 2] - diff; + yCor[numSegments - 1] = yCor[numSegments - 2]; + break; + case 'down': + xCor[numSegments - 1] = xCor[numSegments - 2]; + yCor[numSegments - 1] = yCor[numSegments - 2] + diff; + break; + } +} + +/* + 检查蛇头的位置 xCor[xCor.length - 1] 和 yCor[yCor.length - 1] 来看它是否 + 碰到边界或者自己。 +*/ +function checkGameStatus() { + if ( + xCor[xCor.length - 1] > width || + xCor[xCor.length - 1] < 0 || + yCor[yCor.length - 1] > height || + yCor[yCor.length - 1] < 0 || + checkSnakeCollision() + ) { + noLoop(); + const scoreVal = parseInt(scoreElem.html().substring(8)); + scoreElem.html('Game ended! Your score was : ' + scoreVal); + } +} + +/* + 如果蛇碰到自己,说明蛇头的 (x,y) 坐标和它自身的小段之一的 (x,y) 坐标相同。 +*/ +function checkSnakeCollision() { + const snakeHeadX = xCor[xCor.length - 1]; + const snakeHeadY = yCor[yCor.length - 1]; + for (let i = 0; i < xCor.length - 1; i++) { + if (xCor[i] === snakeHeadX && yCor[i] === snakeHeadY) { + return true; + } + } +} + +/* + 蛇每吃一个水果,小段的数量就会增加,然后将尾段插入数组的开头 + (将最后一个小段再次添加到尾部,从而延长了尾部) +*/ +function checkForFruit() { + point(xFruit, yFruit); + if (xCor[xCor.length - 1] === xFruit && yCor[yCor.length - 1] === yFruit) { + const prevScore = parseInt(scoreElem.html().substring(8)); + scoreElem.html('Score = ' + (prevScore + 1)); + xCor.unshift(xCor[0]); + yCor.unshift(yCor[0]); + numSegments++; + updateFruitCoordinates(); + } +} + +function updateFruitCoordinates() { + /* + 这里的数学逻辑是因为我希望这个点位于 100 和 width-100 之间,并四舍五入到 + 10 的倍数 ,因为蛇以 10 的倍数移动。 + */ + + xFruit = floor(random(10, (width - 100) / 10)) * 10; + yFruit = floor(random(10, (height - 100) / 10)) * 10; +} + +function keyPressed() { + switch (keyCode) { + case 74: + if (direction !== 'right') { + direction = 'left'; + } + break; + case 76: + if (direction !== 'left') { + direction = 'right'; + } + break; + case 73: + if (direction !== 'down') { + direction = 'up'; + } + break; + case 75: + if (direction !== 'up') { + direction = 'down'; + } + break; + } +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/24_Wavemaker.js b/dist/assets/examples/zh-Hans/10_Interaction/24_Wavemaker.js new file mode 100644 index 0000000000..18c8639868 --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/24_Wavemaker.js @@ -0,0 +1,37 @@ +/* + * @name 造波器 + * @description 此范例说明了波(如水波)是如何在粒子摆动中产生的。 + * 移动鼠标以引导波浪。 + * 由 Aatish Bhatia 贡献,灵感来自 Dave Whyte 的 Orbiters。 + */ + +let t = 0; // time variable + +function setup() { + createCanvas(600, 600); + noStroke(); + fill(40, 200, 40); +} + +function draw() { + background(10, 10); // 半透明背景(创建足迹) + + // 创建 x 和 y 网格上的椭圆 + for (let x = 0; x <= width; x = x + 30) { + for (let y = 0; y <= height; y = y + 30) { + // 每个圆的初始位置取决于鼠标位置 + const xAngle = map(mouseX, 0, width, -4 * PI, 4 * PI, true); + const yAngle = map(mouseY, 0, height, -4 * PI, 4 * PI, true); + // 也根据粒子的位置变化 + const angle = xAngle * (x / width) + yAngle * (y / height); + + // 每个粒子绕圈运动 + const myX = x + 20 * cos(2 * PI * t + angle); + const myY = y + 20 * sin(2 * PI * t + angle); + + ellipse(myX, myY, 10); // 绘制粒子 + } + } + + t = t + 0.01; // 更新时间 +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/25_reach1.js b/dist/assets/examples/zh-Hans/10_Interaction/25_reach1.js new file mode 100644 index 0000000000..d85f4f9025 --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/25_reach1.js @@ -0,0 +1,57 @@ +/* + * @name 延伸 1 + * @frame 710,400 + * @description 手臂随鼠标的位置移动,使用 atan2() 计算角度。 + * 基于 Keith Peters 的代码。 + */ +let segLength = 80, + x, + y, + x2, + y2; + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x = width / 2; + y = height / 2; + x2 = x; + y2 = y; +} + +function draw() { + background(0); + dragSegment(0, mouseX, mouseY); + for (let i = 0; i < x.length - 1; i++) { + dragSegment(i + 1, x[i], y[i]); + } +} + +function dragSegment(i, xin, yin) { + background(0); + + dx = mouseX - x; + dy = mouseY - y; + angle1 = atan2(dy, dx); + + tx = mouseX - cos(angle1) * segLength; + ty = mouseY - sin(angle1) * segLength; + dx = tx - x2; + dy = ty - y2; + angle2 = atan2(dy, dx); + x = x2 + cos(angle2) * segLength; + y = y2 + sin(angle2) * segLength; + + segment(x, y, angle1); + segment(x2, y2, angle2); +} + +function segment(x, y, a) { + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/26_reach2.js b/dist/assets/examples/zh-Hans/10_Interaction/26_reach2.js new file mode 100644 index 0000000000..a086231b62 --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/26_reach2.js @@ -0,0 +1,65 @@ +/* + * @name 延伸 2 + * @frame 710,400 + * @description 手臂随鼠标的位置移动,使用 atan2() 计算角度。 + * 基于 Keith Peters 的代码。 + */ +let numSegments = 10, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + + x[x.length - 1] = width / 2; // // 设置基础 x 坐标 + y[x.length - 1] = height; // 设置基础 y 坐标 +} + +function draw() { + background(0); + + reachSegment(0, mouseX, mouseY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/27_reach3.js b/dist/assets/examples/zh-Hans/10_Interaction/27_reach3.js new file mode 100644 index 0000000000..2d971864a0 --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/27_reach3.js @@ -0,0 +1,81 @@ +/* + * @name 延伸 3 + * @frame 710,400 + * @description 手臂随球的位置移动,使用 atan2() 计算角度。 + * 基于 Keith Peters 的代码。 + */ +let numSegments = 8, + x = [], + y = [], + angle = [], + segLength = 26, + targetX, + targetY, + ballX = 50, + ballY = 50, + ballXDirection = 1, + ballYDirection = -1; + +for (let i = 0; i < numSegments; i++) { + x[i] = 0; + y[i] = 0; + angle[i] = 0; +} + +function setup() { + createCanvas(710, 400); + strokeWeight(20); + stroke(255, 100); + noFill(); + + x[x.length - 1] = width / 2; // 设置基础 x 坐标 + y[x.length - 1] = height; // 设置基础 y 坐标 +} + +function draw() { + background(0); + + strokeWeight(20); + ballX = ballX + 1.0 * ballXDirection; + ballY = ballY + 0.8 * ballYDirection; + if (ballX > width - 25 || ballX < 25) { + ballXDirection *= -1; + } + if (ballY > height - 25 || ballY < 25) { + ballYDirection *= -1; + } + ellipse(ballX, ballY, 30, 30); + + reachSegment(0, ballX, ballY); + for (let i = 1; i < numSegments; i++) { + reachSegment(i, targetX, targetY); + } + for (let j = x.length - 1; j >= 1; j--) { + positionSegment(j, j - 1); + } + for (let k = 0; k < x.length; k++) { + segment(x[k], y[k], angle[k], (k + 1) * 2); + } +} + +function positionSegment(a, b) { + x[b] = x[a] + cos(angle[a]) * segLength; + y[b] = y[a] + sin(angle[a]) * segLength; +} + +function reachSegment(i, xin, yin) { + const dx = xin - x[i]; + const dy = yin - y[i]; + angle[i] = atan2(dy, dx); + targetX = xin - cos(angle[i]) * segLength; + targetY = yin - sin(angle[i]) * segLength; +} + +function segment(x, y, a, sw) { + strokeWeight(sw); + push(); + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/28_ArduinoSensor.js b/dist/assets/examples/zh-Hans/10_Interaction/28_ArduinoSensor.js new file mode 100644 index 0000000000..1b23ed2ed4 --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/28_ArduinoSensor.js @@ -0,0 +1,34 @@ +/* + * @name 通过 WebJack 读取 Arduino 传感器数据 + * @description WebJack 是使用音频从 Arduino(和其他来源) + * 读取数据的方式 -- 它基本上将 Arduino 变成了音频调制解调器。 + * + * https://github.com/publiclab/webjack + * + * 注: WebJack 和 p5-webjack 库必须以以下方式添加到 index.html: + *
<script src="https://webjack.io/dist/webjack.js"></script>
+ *
<script src="https://jywarren.github.io/p5-webjack/lib.js"></script>
+ * + * 实例: https://editor.p5js.org/jywarren/sketches/rkztwSt8M + * + * 测试音频: https://www.youtube.com/watch?v=GtJW1Dlt3cg + * 将此草图加载到 Arduino: + * https://create.arduino.cc/editor/jywarren/023158d8-be51-4c78-99ff-36c63126b554/preview + * 从引脚 3 + 地引脚(GND)输出音频。请使用使用麦克风或音频线。 + */ + +function setup() { + createCanvas(400, 400); + noStroke(); + fill('#ff00aa22'); + receiveSensorData(handleData); +} + +function handleData(data) { + console.log(data); // 打出数据 + // data[0] 是第一个值, data[1] 是第二个, 以此类推. + + // 绘制! 参考 http://p5js.org/reference/ + background('#ddd'); + ellipse(100, 200, data[0] + 10, data[0] + 10); +} diff --git a/dist/assets/examples/zh-Hans/10_Interaction/29_kaleidoscope.js b/dist/assets/examples/zh-Hans/10_Interaction/29_kaleidoscope.js new file mode 100644 index 0000000000..b4f445fc60 --- /dev/null +++ b/dist/assets/examples/zh-Hans/10_Interaction/29_kaleidoscope.js @@ -0,0 +1,77 @@ +/* + * @name 万花筒 + * @description 万花筒是一个光学仪器,具有两个或多个互相倾斜的反射面。 + * 此范例尝试模仿万花筒的效果。 + * 通过 symmetry 变量设定反射的数量,并开始在屏幕上绘制。 + * 通过 slider 调整画笔的大小。 + * clearScreen(),顾名思义,清空屏幕。 + * save 按钮将你绘制的艺术品以 .jpg 的文件格式下载下来。 + */ +// Symmetry 指反射的次数。更改此数值以改变反射的次数。 +let symmetry = 6; + +let angle = 360 / symmetry; +let saveButton, clearButton, mouseButton, keyboardButton; +let slider; + +function setup() { + createCanvas(710, 710); + angleMode(DEGREES); + background(127); + + // 制作保存文件的按钮 + saveButton = createButton('save'); + saveButton.mousePressed(saveFile); + + // 制作清空屏幕的按钮 + clearButton = createButton('clear'); + clearButton.mousePressed(clearScreen); + + // 制作全屏按钮 + fullscreenButton = createButton('Full Screen'); + fullscreenButton.mousePressed(screenFull); + + // 设置 slider 以改变笔刷的粗细 + brushSizeSlider = createButton('Brush Size Slider'); + sizeSlider = createSlider(1, 32, 4, 0.1); +} + +// 保存文件函数 +function saveFile() { + save('design.jpg'); +} + +// 清空屏幕函数 +function clearScreen() { + background(127); +} + +// 全屏函数 +function screenFull() { + let fs = fullscreen(); + fullscreen(!fs); +} + +function draw() { + translate(width / 2, height / 2); + + if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) { + let mx = mouseX - width / 2; + let my = mouseY - height / 2; + let pmx = pmouseX - width / 2; + let pmy = pmouseY - height / 2; + + if (mouseIsPressed) { + for (let i = 0; i < symmetry; i++) { + rotate(angle); + let sw = sizeSlider.value(); + strokeWeight(sw); + line(mx, my, pmx, pmy); + push(); + scale(1, -1); + line(mx, my, pmx, pmy); + pop(); + } + } + } +} diff --git a/dist/assets/examples/zh-Hans/11_Objects/01_Objects.js b/dist/assets/examples/zh-Hans/11_Objects/01_Objects.js new file mode 100644 index 0000000000..009c6b4dd5 --- /dev/null +++ b/dist/assets/examples/zh-Hans/11_Objects/01_Objects.js @@ -0,0 +1,38 @@ +/* + * @name 物件 (Objects) + * @description 创建一个 Jitter 类, 实例化一个物件,并且在屏幕上移动。 + * 改编自 Processing 入门,作者:Casey Reas 和 Ben Fry + */ + +let bug; // 声明物件 + +function setup() { + createCanvas(710, 400); + // 创造物件 + bug = new Jitter(); +} + +function draw() { + background(50, 89, 100); + bug.move(); + bug.display(); +} + +// Jitter 类 +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/zh-Hans/11_Objects/02_Multiple_Objects.js b/dist/assets/examples/zh-Hans/11_Objects/02_Multiple_Objects.js new file mode 100644 index 0000000000..2268530df0 --- /dev/null +++ b/dist/assets/examples/zh-Hans/11_Objects/02_Multiple_Objects.js @@ -0,0 +1,49 @@ +/* + * @name 多个物件 + * @description 创建一个 Jitter 类,实例化多个物件,并且在屏幕上移动。 + */ + +let bug1; // 声明物件 +let bug2; +let bug3; +let bug4; + +function setup() { + createCanvas(710, 400); + // 创造物件 + bug1 = new Jitter(); + bug2 = new Jitter(); + bug3 = new Jitter(); + bug4 = new Jitter(); +} + +function draw() { + background(50, 89, 100); + bug1.move(); + bug1.display(); + bug2.move(); + bug2.display(); + bug3.move(); + bug3.display(); + bug4.move(); + bug4.display(); +} + +// Jitter 类 +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/zh-Hans/11_Objects/03_Objects_Array.js b/dist/assets/examples/zh-Hans/11_Objects/03_Objects_Array.js new file mode 100644 index 0000000000..3e6c383566 --- /dev/null +++ b/dist/assets/examples/zh-Hans/11_Objects/03_Objects_Array.js @@ -0,0 +1,41 @@ +/* + * @name 物件数组 + * @description 创建一个 Jitter 类,实例化多个物件,并且在屏幕上移动。 + */ + +let bugs = []; // Jitter 物件的数组 + +function setup() { + createCanvas(710, 400); + // 创造物件 + for (let i = 0; i < 50; i++) { + bugs.push(new Jitter()); + } +} + +function draw() { + background(50, 89, 100); + for (let i = 0; i < bugs.length; i++) { + bugs[i].move(); + bugs[i].display(); + } +} + +// Jitter 类 +class Jitter { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.speed = 1; + } + + move() { + this.x += random(-this.speed, this.speed); + this.y += random(-this.speed, this.speed); + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/zh-Hans/11_Objects/03_Objects_Optional_Arguments.js b/dist/assets/examples/zh-Hans/11_Objects/03_Objects_Optional_Arguments.js new file mode 100644 index 0000000000..cc6ddc879f --- /dev/null +++ b/dist/assets/examples/zh-Hans/11_Objects/03_Objects_Optional_Arguments.js @@ -0,0 +1,64 @@ +/* + * @name 物件 2 + * @description 转自 hbarragan 的范例。在图像上移动光标以更改几何图形的速度和位置。 + * MRect 类定义了一组线。 + */ + +let r1, r2, r3, r4; + +function setup() { + createCanvas(710, 400); + fill(255, 204); + noStroke(); + r1 = new MRect(1, 134.0, 0.532, 0.1 * height, 10.0, 60.0); + r2 = new MRect(2, 44.0, 0.166, 0.3 * height, 5.0, 50.0); + r3 = new MRect(2, 58.0, 0.332, 0.4 * height, 10.0, 35.0); + r4 = new MRect(1, 120.0, 0.0498, 0.9 * height, 15.0, 60.0); +} + +function draw() { + background(0); + + r1.display(); + r2.display(); + r3.display(); + r4.display(); + + r1.move(mouseX - width / 2, mouseY + height * 0.1, 30); + r2.move((mouseX + width * 0.05) % width, mouseY + height * 0.025, 20); + r3.move(mouseX / 4, mouseY - height * 0.025, 40); + r4.move(mouseX - width / 2, height - mouseY, 50); +} + +class MRect { + constructor(iw, ixp, ih, iyp, id, it) { + this.w = iw; // 单线条宽度 + this.xpos = ixp; // rect x 值 + this.h = ih; // rect 高度 + this.ypos = iyp; // rect y 值 + this.d = id; // 单线条间距 + this.t = it; // 单线条数量 + } + + move(posX, posY, damping) { + let dif = this.ypos - posY; + if (abs(dif) > 1) { + this.ypos -= dif / damping; + } + dif = this.xpos - posX; + if (abs(dif) > 1) { + this.xpos -= dif / damping; + } + } + + display() { + for (let i = 0; i < this.t; i++) { + rect( + this.xpos + i * (this.d + this.w), + this.ypos, + this.w, + height * this.h + ); + } + } +} diff --git a/dist/assets/examples/zh-Hans/11_Objects/04_Inheritance.js b/dist/assets/examples/zh-Hans/11_Objects/04_Inheritance.js new file mode 100644 index 0000000000..2218f3c83f --- /dev/null +++ b/dist/assets/examples/zh-Hans/11_Objects/04_Inheritance.js @@ -0,0 +1,69 @@ +/* @name 继承 (Inheritance) + * @description 可以用一个类作为基础来定义另一个类。在面向对象的编程术语中, + * 一个类可以继承另一个类的字段 (fields) 和方法 (methods)。 + * 从另一个物件继承了的物件称为子类 (subclass),其继承的物件称为基类 (superclass)。 + * 子类扩展基类。 + */ +let spots, arm; + +function setup() { + createCanvas(640, 360); + arm = new SpinArm(width/2, height/2, 0.01); + spots = new SpinSpots(width/2, height/2, -0.02, 90.0); +} + +function draw() { + background(204); + arm.update(); + arm.display(); + spots.update(); + spots.display(); +} + +class Spin { + constructor(x, y, s) { + this.x = x; + this.y = y; + this.speed = s; + this.angle = 0.0; + } + + update() { + this.angle += this.speed; + } +} + +class SpinArm extends Spin { + constructor(x, y, s) { + super(x, y, s) + } + + display() { + strokeWeight(1); + stroke(0); + push(); + translate(this.x, this.y); + this.angle += this.speed; + rotate(this.angle); + line(0, 0, 165, 0); + pop(); + } +} + +class SpinSpots extends Spin { + constructor(x, y, s, d) { + super(x, y, s) + this.dim = d; + } + + display() { + noStroke(); + push(); + translate(this.x, this.y); + this.angle += this.speed; + rotate(this.angle); + ellipse(-this.dim/2, 0, this.dim, this.dim); + ellipse(this.dim/2, 0, this.dim, this.dim); + pop(); + } +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/11_Objects/05_Composite_Objects.js b/dist/assets/examples/zh-Hans/11_Objects/05_Composite_Objects.js new file mode 100644 index 0000000000..f680925995 --- /dev/null +++ b/dist/assets/examples/zh-Hans/11_Objects/05_Composite_Objects.js @@ -0,0 +1,98 @@ +/* @name 复合物件 + * @description 一个物件可以包含多个其他物件。 + * 创造复合物件是使用模块性和程序中构建更高级别的抽象的好方法。 + */ +let er1, er2; + +function setup() { + createCanvas(640, 360); + er1 = new EggRing(width*0.45, height*0.5, 0.1, 120); + er2 = new EggRing(width*0.65, height*0.8, 0.05, 180); +} + +function draw() { + background(0); + er1.transmit(); + er2.transmit(); +} + +class Egg { + constructor(xpos, ypos, t, s) { + this.x = xpos; + this.y = ypos; + this.tilt = t; + this.scalar = s / 100.0; + this.angle = 0.0; + } + + wobble() { + this.tilt = cos(this.angle) / 8; + this.angle += 0.1; + } + + display() { + noStroke(); + fill(255); + push(); + translate(this.x, this.y); + rotate(this.tilt); + scale(this.scalar); + beginShape(); + vertex(0, -100); + bezierVertex(25, -100, 40, -65, 40, -40); + bezierVertex(40, -15, 25, 0, 0, 0); + bezierVertex(-25, 0, -40, -15, -40, -40); + bezierVertex(-40, -65, -25, -100, 0, -100); + endShape(); + pop(); + } +} + +class Ring { + start(xpos, ypos) { + this.x = xpos; + this.y = ypos; + this.on = true; + this.diameter = 1; + } + + grow() { + if (this.on == true) { + this.diameter += 0.5; + if (this.diameter > width*2) { + this.diameter = 0.0; + } + } + } + + display() { + if (this.on == true) { + noFill(); + strokeWeight(4); + stroke(155, 153); + ellipse(this.x, this.y, this.diameter, this.diameter); + } + } +} + +class EggRing { + constructor(x, y, t, sp) { + this.x = x; + this.y = y; + this.t = t; + this.sp = sp; + this.circle = new Ring(); + this.ovoid = new Egg(this.x, this.y, this.t, this.sp); + this.circle.start(this.x, this.y - this.sp/2); + } + + transmit() { + this.ovoid.wobble(); + this.ovoid.display(); + this.circle.grow(); + this.circle.display(); + if (this.circle.on == false) { + this.circle.on = true; + } + } +} diff --git a/dist/assets/examples/zh-Hans/11_Objects/06_Car_Instances.js b/dist/assets/examples/zh-Hans/11_Objects/06_Car_Instances.js new file mode 100644 index 0000000000..1966f9c8e3 --- /dev/null +++ b/dist/assets/examples/zh-Hans/11_Objects/06_Car_Instances.js @@ -0,0 +1,82 @@ +/* + * @name Car Instances + * @frame 400,400 + * @description contributed by + Prof WM Harris, How to create three instances of Car Class and +invoke class methods.
+ A function is created for the canvas setup, and +3 car instances are initialized with different colors and canvas +positions. The speed of each car is set by passing value to the +instance’s start method. A second function calls class methods to +display and move the cars. +*/ +class Car { + /* Constructor expects parameters for + fill color, x and y coordinates that + will be used to initialize class properties. + */ + constructor(cColor, x, y) { + this.color = cColor; + this.doors = 4; + this.isConvertible = false; + this.x = x; + this.y = y; + this.speed = 0; + } + + start(speed) { // method expects parameter! + this.speed = speed; + } + + display() { // method! + fill(this.color); + rect(this.x, this.y, 20, 10); + } + + move() { // method! + this.x += this.speed; + // Wrap x around boundaries + if (this.x < -20) { + this.x = width; + } else if (this.x > width) { + this.x = -20; + } + } +} //end class Car + +let rav4; +let charger; +let nova; + +function setup() { + createCanvas(200, 400); + /* Construct the 3 Cars */ + //constructor expects cColor, x, y + rav4 = new Car("silver", 100, 300); + charger = new Car("gold", 0, 200); + nova = new Car("blue", 200, 100); + nova.doors = 2; //update nova's doors property + + console.log("rav4", rav4); + console.log("charger", charger); + console.log("nova", nova); + + //call start methods of Car instances + //the start method expects a number for speed + rav4.start(2.3); + charger.start(-4); + nova.start(random(-1, 1)); +} + +function draw() { + background("beige"); + + //display and move all 3 Cars + rav4.display(); + charger.display(); + nova.display(); + + rav4.move(); + charger.move(); + nova.move(); +} diff --git a/dist/assets/examples/zh-Hans/12_Lights/02_Directional.js b/dist/assets/examples/zh-Hans/12_Lights/02_Directional.js new file mode 100644 index 0000000000..71d46ea455 --- /dev/null +++ b/dist/assets/examples/zh-Hans/12_Lights/02_Directional.js @@ -0,0 +1,26 @@ +/* + * @name 定向光 + * @frame 710,400 + * @description 移动鼠标改变光线方向。 + * 定向光从一个方向打来,垂直打在一个表面上时会更强,而以平缓的角度打则会更弱。 + * 击打在表面上后,定向光会在所有方向上散射。 + */ +const radius = 200; + +function setup() { + createCanvas(710, 400, WEBGL); + noStroke(); + fill(200); +} + +function draw() { + noStroke(); + background(0); + const dirY = (mouseY / height - 0.5) * 4; + const dirX = (mouseX / width - 0.5) * 4; + directionalLight(204, 204, 204, dirX, dirY, 1); + translate(-1.5 * radius, 0, 0); + sphere(radius); + translate(3 * radius, 0, 0); + sphere(radius); +} diff --git a/dist/assets/examples/zh-Hans/12_Lights/05_Mixture.js b/dist/assets/examples/zh-Hans/12_Lights/05_Mixture.js new file mode 100644 index 0000000000..51abe75dd3 --- /dev/null +++ b/dist/assets/examples/zh-Hans/12_Lights/05_Mixture.js @@ -0,0 +1,43 @@ +/* + * @name 混合光 + * @frame 710,400 (optional) + * @description 展示一个有三种不同光的盒子。 + */ +function setup() { + createCanvas(710, 400, WEBGL); + noStroke(); +} + +function draw() { + background(0); + + // 环境光 + ambientLight(0, 255/4, 0); + + // 设置光的位置,可将坐标想成如下: + // -宽度/2,-高度/2 -------- 宽度/2,-高度/2 + // | | + // | 0,0 | + // | | + // -宽度/2,高度/2--------宽度/2,高度/2 + + // 左侧:蓝色定向光 + directionalLight(0, 0, 255, -1, 0, 0); + + // 计算由中心点至 mouseX 的距离 + let lightX = mouseX - width / 2; + let lightY = mouseY - height / 2; + + // 红色聚光 + // 光的轴位置:lightX, lightY, 500 + // 光的轴方向:0, 0, -1 + spotLight(255, 0, 0, lightX, lightY, 500, 0, 0, -1); + + // 绕 X 轴旋转 + rotateX(-PI/4); + // 绕 Y 轴旋转 + rotateY(PI/4); + + // 将方块放置在 (0, 0, 0),并设大小为 100 + box(100); +} diff --git a/dist/assets/examples/zh-Hans/13_Motion/01_non_orthogonal_reflection.js b/dist/assets/examples/zh-Hans/13_Motion/01_non_orthogonal_reflection.js new file mode 100644 index 0000000000..1d5ed269c5 --- /dev/null +++ b/dist/assets/examples/zh-Hans/13_Motion/01_non_orthogonal_reflection.js @@ -0,0 +1,110 @@ +/* + * @name Non Orthogonal Reflection + * @frame 710,400 (optional) + * @description This is a port by David Blitz of the "Reflection 1" example from processing.org/examples + */ + +//Position of left hand side of floor +let base1; + +//Position of right hand side of floor +let base2; +//Length of floor +//let baseLength; + +// Variables related to moving ball +let position; +let velocity; +let r = 6; +let speed = 3.5; + +function setup() { + createCanvas(710, 400); + + fill(128); + base1 = createVector(0, height - 150); + base2 = createVector(width, height); + //createGround(); + + //start ellipse at middle top of screen + position = createVector(width / 2, 0); + + //calculate initial random velocity + velocity = p5.Vector.random2D(); + velocity.mult(speed); +} + +function draw() { + //draw background + fill(0, 12); + noStroke(); + rect(0, 0, width, height); + + //draw base + fill(200); + quad(base1.x, base1.y, base2.x, base2.y, base2.x, height, 0, height); + + //calculate base top normal + let baseDelta = p5.Vector.sub(base2, base1); + baseDelta.normalize(); + let normal = createVector(-baseDelta.y, baseDelta.x); + let intercept = p5.Vector.dot(base1, normal); + + //draw ellipse + noStroke(); + fill(255); + ellipse(position.x, position.y, r * 2, r * 2); + + //move ellipse + position.add(velocity); + + //normalized incidence vector + incidence = p5.Vector.mult(velocity, -1); + incidence.normalize(); + + // detect and handle collision with base + if (p5.Vector.dot(normal, position) > intercept) { + //calculate dot product of incident vector and base top + let dot = incidence.dot(normal); + + //calculate reflection vector + //assign reflection vector to direction vector + velocity.set( + 2 * normal.x * dot - incidence.x, + 2 * normal.y * dot - incidence.y, + 0 + ); + velocity.mult(speed); + + // draw base top normal at collision point + stroke(255, 128, 0); + line( + position.x, + position.y, + position.x - normal.x * 100, + position.y - normal.y * 100 + ); + } + //} + + // detect boundary collision + // right + if (position.x > width - r) { + position.x = width - r; + velocity.x *= -1; + } + // left + if (position.x < r) { + position.x = r; + velocity.x *= -1; + } + // top + if (position.y < r) { + position.y = r; + velocity.y *= -1; + + //randomize base top + base1.y = random(height - 100, height); + base2.y = random(height - 100, height); + } +} diff --git a/dist/assets/examples/zh-Hans/13_Motion/02_Linear_Motion.js b/dist/assets/examples/zh-Hans/13_Motion/02_Linear_Motion.js new file mode 100644 index 0000000000..421f99c104 --- /dev/null +++ b/dist/assets/examples/zh-Hans/13_Motion/02_Linear_Motion.js @@ -0,0 +1,24 @@ +/* + * @name Linear + * @frame 720,400 + * @description Changing a variable to create a moving line. + * When the line moves off the edge of the window, + * the variable is set to 0, which places the line back at the bottom of the screen. + */ + +let a; + +function setup() { + createCanvas(720, 400); + stroke(255); + a = height / 2; +} + +function draw() { + background(51); + line(0, a, width, a); + a = a - 0.5; + if (a < 0) { + a = height; + } +} diff --git a/dist/assets/examples/zh-Hans/13_Motion/03_Bounce.js b/dist/assets/examples/zh-Hans/13_Motion/03_Bounce.js new file mode 100644 index 0000000000..a3354e015f --- /dev/null +++ b/dist/assets/examples/zh-Hans/13_Motion/03_Bounce.js @@ -0,0 +1,44 @@ +/* + * @name Bounce + * @frame 720,400 + * @description When the shape hits the edge of the window, it reverses its direction. + */ + +let rad = 60; // Width of the shape +let xpos, ypos; // Starting position of shape + +let xspeed = 2.8; // Speed of the shape +let yspeed = 2.2; // Speed of the shape + +let xdirection = 1; // Left or Right +let ydirection = 1; // Top to Bottom + +function setup() { + createCanvas(720, 400); + noStroke(); + frameRate(30); + ellipseMode(RADIUS); + // Set the starting position of the shape + xpos = width / 2; + ypos = height / 2; +} + +function draw() { + background(102); + + // Update the position of the shape + xpos = xpos + xspeed * xdirection; + ypos = ypos + yspeed * ydirection; + + // Test to see if the shape exceeds the boundaries of the screen + // If it does, reverse its direction by multiplying by -1 + if (xpos > width - rad || xpos < rad) { + xdirection *= -1; + } + if (ypos > height - rad || ypos < rad) { + ydirection *= -1; + } + + // Draw the shape + ellipse(xpos, ypos, rad, rad); +} diff --git a/dist/assets/examples/zh-Hans/13_Motion/04_Bouncy_Bubbles.js b/dist/assets/examples/zh-Hans/13_Motion/04_Bouncy_Bubbles.js new file mode 100644 index 0000000000..7347157665 --- /dev/null +++ b/dist/assets/examples/zh-Hans/13_Motion/04_Bouncy_Bubbles.js @@ -0,0 +1,95 @@ +/* + * @name Bouncy Bubbles + * @frame 720,400 + * @description based on code from Keith Peters. Multiple-object collision.. + */ + +let numBalls = 13; +let spring = 0.05; +let gravity = 0.03; +let friction = -0.9; +let balls = []; + +function setup() { + createCanvas(720, 400); + for (let i = 0; i < numBalls; i++) { + balls[i] = new Ball( + random(width), + random(height), + random(30, 70), + i, + balls + ); + } + noStroke(); + fill(255, 204); +} + +function draw() { + background(0); + balls.forEach(ball => { + ball.collide(); + ball.move(); + ball.display(); + }); +} + +class Ball { + constructor(xin, yin, din, idin, oin) { + this.x = xin; + this.y = yin; + this.vx = 0; + this.vy = 0; + this.diameter = din; + this.id = idin; + this.others = oin; + } + + collide() { + for (let i = this.id + 1; i < numBalls; i++) { + // console.log(others[i]); + let dx = this.others[i].x - this.x; + let dy = this.others[i].y - this.y; + let distance = sqrt(dx * dx + dy * dy); + let minDist = this.others[i].diameter / 2 + this.diameter / 2; + // console.log(distance); + //console.log(minDist); + if (distance < minDist) { + //console.log("2"); + let angle = atan2(dy, dx); + let targetX = this.x + cos(angle) * minDist; + let targetY = this.y + sin(angle) * minDist; + let ax = (targetX - this.others[i].x) * spring; + let ay = (targetY - this.others[i].y) * spring; + this.vx -= ax; + this.vy -= ay; + this.others[i].vx += ax; + this.others[i].vy += ay; + } + } + } + + move() { + this.vy += gravity; + this.x += this.vx; + this.y += this.vy; + if (this.x + this.diameter / 2 > width) { + this.x = width - this.diameter / 2; + this.vx *= friction; + } else if (this.x - this.diameter / 2 < 0) { + this.x = this.diameter / 2; + this.vx *= friction; + } + if (this.y + this.diameter / 2 > height) { + this.y = height - this.diameter / 2; + this.vy *= friction; + } else if (this.y - this.diameter / 2 < 0) { + this.y = this.diameter / 2; + this.vy *= friction; + } + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/zh-Hans/13_Motion/05_Morph.js b/dist/assets/examples/zh-Hans/13_Motion/05_Morph.js new file mode 100644 index 0000000000..c6479c27d6 --- /dev/null +++ b/dist/assets/examples/zh-Hans/13_Motion/05_Morph.js @@ -0,0 +1,93 @@ +/* + * @name Morph + * @frame 720,400 + * @description Changing one shape into another by interpolating vertices from one to another. + */ + +// Two ArrayLists to store the vertices for two shapes +// This example assumes that each shape will have the same +// number of vertices, i.e. the size of each ArrayList will be the same +let circle = []; +let square = []; + +// An ArrayList for a third set of vertices, the ones we will be drawing +// in the window +let morph = []; + +// This boolean variable will control if we are morphing to a circle or square +let state = false; + +function setup() { + createCanvas(720, 400); + + // Create a circle using vectors pointing from center + for (let angle = 0; angle < 360; angle += 9) { + // Note we are not starting from 0 in order to match the + // path of a circle. + let v = p5.Vector.fromAngle(radians(angle - 135)); + v.mult(100); + circle.push(v); + // Let's fill out morph ArrayList with blank PVectors while we are at it + morph.push(createVector()); + } + + // A square is a bunch of vertices along straight lines + // Top of square + for (let x = -50; x < 50; x += 10) { + square.push(createVector(x, -50)); + } + // Right side + for (let y = -50; y < 50; y += 10) { + square.push(createVector(50, y)); + } + // Bottom + for (let x = 50; x > -50; x -= 10) { + square.push(createVector(x, 50)); + } + // Left side + for (let y = 50; y > -50; y -= 10) { + square.push(createVector(-50, y)); + } +} + +function draw() { + background(51); + + // We will keep how far the vertices are from their target + let totalDistance = 0; + + // Look at each vertex + for (let i = 0; i < circle.length; i++) { + let v1; + // Are we lerping to the circle or square? + if (state) { + v1 = circle[i]; + } else { + v1 = square[i]; + } + // Get the vertex we will draw + let v2 = morph[i]; + // Lerp to the target + v2.lerp(v1, 0.1); + // Check how far we are from target + totalDistance += p5.Vector.dist(v1, v2); + } + + // If all the vertices are close, switch shape + if (totalDistance < 0.1) { + state = !state; + } + + // Draw relative to center + translate(width / 2, height / 2); + strokeWeight(4); + // Draw a polygon that makes up all the vertices + beginShape(); + noFill(); + stroke(255); + + morph.forEach(v => { + vertex(v.x, v.y); + }); + endShape(CLOSE); +} diff --git a/dist/assets/examples/zh-Hans/13_Motion/06_Moving_On_Curves.js b/dist/assets/examples/zh-Hans/13_Motion/06_Moving_On_Curves.js new file mode 100644 index 0000000000..4c347c7e00 --- /dev/null +++ b/dist/assets/examples/zh-Hans/13_Motion/06_Moving_On_Curves.js @@ -0,0 +1,47 @@ +/* + * @name Moving On Curves + * @frame 720,400 + * @description In this example, the circles moves along the curve y = x^4. + * Click the mouse to have it move to a new position. + */ + +let beginX = 20.0; // Initial x-coordinate +let beginY = 10.0; // Initial y-coordinate +let endX = 570.0; // Final x-coordinate +let endY = 320.0; // Final y-coordinate +let distX; // X-axis distance to move +let distY; // Y-axis distance to move +let exponent = 4; // Determines the curve +let x = 0.0; // Current x-coordinate +let y = 0.0; // Current y-coordinate +let step = 0.01; // Size of each step along the path +let pct = 0.0; // Percentage traveled (0.0 to 1.0) + +function setup() { + createCanvas(720, 400); + noStroke(); + distX = endX - beginX; + distY = endY - beginY; +} + +function draw() { + fill(0, 2); + rect(0, 0, width, height); + pct += step; + if (pct < 1.0) { + x = beginX + pct * distX; + y = beginY + pow(pct, exponent) * distY; + } + fill(255); + ellipse(x, y, 20, 20); +} + +function mousePressed() { + pct = 0.0; + beginX = x; + beginY = y; + endX = mouseX; + endY = mouseY; + distX = endX - beginX; + distY = endY - beginY; +} diff --git a/dist/assets/examples/zh-Hans/13_Motion/07_Circle_Collision.js b/dist/assets/examples/zh-Hans/13_Motion/07_Circle_Collision.js new file mode 100644 index 0000000000..876bc23d6e --- /dev/null +++ b/dist/assets/examples/zh-Hans/13_Motion/07_Circle_Collision.js @@ -0,0 +1,145 @@ +/* + * @name Circle Collision + * @frame 710,400 (optional) + * @description This is a port of the "Circle Collision" example from processing.org/examples
This example uses vectors for better visualization of physical Quantity + */ +class Ball { + constructor(x, y, r) { + this.position = new p5.Vector(x, y); + this.velocity = p5.Vector.random2D(); + this.velocity.mult(3); + this.r = r; + this.m = r * 0.1; + } + update() { + this.position.add(this.velocity); + } + + checkBoundaryCollision() { + if (this.position.x > width - this.r) { + this.position.x = width - this.r; + this.velocity.x *= -1; + } else if (this.position.x < this.r) { + this.position.x = this.r; + this.velocity.x *= -1; + } else if (this.position.y > height - this.r) { + this.position.y = height - this.r; + this.velocity.y *= -1; + } else if (this.position.y < this.r) { + this.position.y = this.r; + this.velocity.y *= -1; + } + } + + checkCollision(other) { + // Get distances between the balls components + let distanceVect = p5.Vector.sub(other.position, this.position); + + // Calculate magnitude of the vector separating the balls + let distanceVectMag = distanceVect.mag(); + + // Minimum distance before they are touching + let minDistance = this.r + other.r; + + if (distanceVectMag < minDistance) { + let distanceCorrection = (minDistance - distanceVectMag) / 2.0; + let d = distanceVect.copy(); + let correctionVector = d.normalize().mult(distanceCorrection); + other.position.add(correctionVector); + this.position.sub(correctionVector); + + // get angle of distanceVect + let theta = distanceVect.heading(); + // precalculate trig values + let sine = sin(theta); + let cosine = cos(theta); + + /* bTemp will hold rotated ball this.positions. You + just need to worry about bTemp[1] this.position*/ + let bTemp = [new p5.Vector(), new p5.Vector()]; + + /* this ball's this.position is relative to the other + so you can use the vector between them (bVect) as the + reference point in the rotation expressions. + bTemp[0].this.position.x and bTemp[0].this.position.y will initialize + automatically to 0.0, which is what you want + since b[1] will rotate around b[0] */ + bTemp[1].x = cosine * distanceVect.x + sine * distanceVect.y; + bTemp[1].y = cosine * distanceVect.y - sine * distanceVect.x; + + // rotate Temporary velocities + let vTemp = [new p5.Vector(), new p5.Vector()]; + + vTemp[0].x = cosine * this.velocity.x + sine * this.velocity.y; + vTemp[0].y = cosine * this.velocity.y - sine * this.velocity.x; + vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y; + vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x; + + /* Now that velocities are rotated, you can use 1D + conservation of momentum equations to calculate + the final this.velocity along the x-axis. */ + let vFinal = [new p5.Vector(), new p5.Vector()]; + + // final rotated this.velocity for b[0] + vFinal[0].x = + ((this.m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / + (this.m + other.m); + vFinal[0].y = vTemp[0].y; + + // final rotated this.velocity for b[0] + vFinal[1].x = + ((other.m - this.m) * vTemp[1].x + 2 * this.m * vTemp[0].x) / + (this.m + other.m); + vFinal[1].y = vTemp[1].y; + + // hack to avoid clumping + bTemp[0].x += vFinal[0].x; + bTemp[1].x += vFinal[1].x; + + /* Rotate ball this.positions and velocities back + Reverse signs in trig expressions to rotate + in the opposite direction */ + // rotate balls + let bFinal = [new p5.Vector(), new p5.Vector()]; + + bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y; + bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x; + bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y; + bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x; + + // update balls to screen this.position + other.position.x = this.position.x + bFinal[1].x; + other.position.y = this.position.y + bFinal[1].y; + + this.position.add(bFinal[0]); + + // update velocities + this.velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y; + this.velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x; + other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y; + other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x; + } + } + + display() { + noStroke(); + fill(204); + ellipse(this.position.x, this.position.y, this.r * 2, this.r * 2); + } +} +let balls = [new Ball(100, 400, 20), new Ball(700, 400, 80)]; +console.log(balls); +function setup() { + createCanvas(710, 400); +} + +function draw() { + background(51); + for (let i = 0; i < balls.length; i++) { + let b = balls[i]; + b.update(); + b.display(); + b.checkBoundaryCollision(); + balls[0].checkCollision(balls[1]); + } +} diff --git a/dist/assets/examples/zh-Hans/13_Motion/08_Moving_On_Curves.js b/dist/assets/examples/zh-Hans/13_Motion/08_Moving_On_Curves.js new file mode 100644 index 0000000000..4c347c7e00 --- /dev/null +++ b/dist/assets/examples/zh-Hans/13_Motion/08_Moving_On_Curves.js @@ -0,0 +1,47 @@ +/* + * @name Moving On Curves + * @frame 720,400 + * @description In this example, the circles moves along the curve y = x^4. + * Click the mouse to have it move to a new position. + */ + +let beginX = 20.0; // Initial x-coordinate +let beginY = 10.0; // Initial y-coordinate +let endX = 570.0; // Final x-coordinate +let endY = 320.0; // Final y-coordinate +let distX; // X-axis distance to move +let distY; // Y-axis distance to move +let exponent = 4; // Determines the curve +let x = 0.0; // Current x-coordinate +let y = 0.0; // Current y-coordinate +let step = 0.01; // Size of each step along the path +let pct = 0.0; // Percentage traveled (0.0 to 1.0) + +function setup() { + createCanvas(720, 400); + noStroke(); + distX = endX - beginX; + distY = endY - beginY; +} + +function draw() { + fill(0, 2); + rect(0, 0, width, height); + pct += step; + if (pct < 1.0) { + x = beginX + pct * distX; + y = beginY + pow(pct, exponent) * distY; + } + fill(255); + ellipse(x, y, 20, 20); +} + +function mousePressed() { + pct = 0.0; + beginX = x; + beginY = y; + endX = mouseX; + endY = mouseY; + distX = endX - beginX; + distY = endY - beginY; +} diff --git a/dist/assets/examples/zh-Hans/15_Instance_Mode/01_Instantiating.js b/dist/assets/examples/zh-Hans/15_Instance_Mode/01_Instantiating.js new file mode 100644 index 0000000000..592f0a3dcf --- /dev/null +++ b/dist/assets/examples/zh-Hans/15_Instance_Mode/01_Instantiating.js @@ -0,0 +1,34 @@ +/* + * @name 创建实例 + * @description 创建一个 p5 实例,以便让所有变量在全局作用域之外。 + */ +let sketch = function (p) { + let x = 100; + let y = 100; + + p.setup = function () { + p.createCanvas(700, 410); + }; + + p.draw = function () { + p.background(0); + p.fill(255); + p.rect(x, y, 50, 50); + }; +}; + +let myp5 = new p5(sketch); + +// “全局模式” 作为对照 +// let x = 100; +// let y = 100; + +// function setup() { +// createCanvas(200,200); +// } + +// function draw() { +// background(0); +// fill(255); +// ellipse(x,y,50,50); +// } diff --git a/dist/assets/examples/zh-Hans/15_Instance_Mode/02_Instance_Container.js b/dist/assets/examples/zh-Hans/15_Instance_Mode/02_Instance_Container.js new file mode 100644 index 0000000000..3b901c7348 --- /dev/null +++ b/dist/assets/examples/zh-Hans/15_Instance_Mode/02_Instance_Container.js @@ -0,0 +1,90 @@ +/* + * @norender + * @name 实例容器 + * @description 第二个参数可以是你指定作为画布的默认容器,也可以是任何 + 你想要添加此 p5 实例容器至的元素。可以是带 ID 的 html 元素, 也可以是 html 节点本身。 + * + * 以下列举了三种选择 DOM 元素作为容器的方法。 + * 所有由 p5 创建的 DOM 元素(画布,按钮,div 等)都会被添加到指定的 DOM 元素上, + * 这个指定元素就是调用 p5() 时传递的第二个参数。 + */ + + + + + + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/16_Dom/03_Input_Button.js b/dist/assets/examples/zh-Hans/16_Dom/03_Input_Button.js new file mode 100644 index 0000000000..d3aaf9cc42 --- /dev/null +++ b/dist/assets/examples/zh-Hans/16_Dom/03_Input_Button.js @@ -0,0 +1,38 @@ +/* + * @name Input and Button + * @description Input text and click the button to see it affect the the canvas. + */ +let input, button, greeting; + +function setup() { + // create canvas + createCanvas(710, 400); + + input = createInput(); + input.position(20, 65); + + button = createButton('submit'); + button.position(input.x + input.width, 65); + button.mousePressed(greet); + + greeting = createElement('h2', 'what is your name?'); + greeting.position(20, 5); + + textAlign(CENTER); + textSize(50); +} + +function greet() { + const name = input.value(); + greeting.html('hello ' + name + '!'); + input.value(''); + + for (let i = 0; i < 200; i++) { + push(); + fill(random(255), 255, 255); + translate(random(width), random(height)); + rotate(random(2 * PI)); + text(name, 0, 0); + pop(); + } +} diff --git a/dist/assets/examples/zh-Hans/16_Dom/04_Slider.js b/dist/assets/examples/zh-Hans/16_Dom/04_Slider.js new file mode 100644 index 0000000000..6cb48ced1c --- /dev/null +++ b/dist/assets/examples/zh-Hans/16_Dom/04_Slider.js @@ -0,0 +1,30 @@ +/* + * @name Slider + * @description Move the sliders to control the R, G, B values of the background. + */ +let rSlider, gSlider, bSlider; + +function setup() { + // create canvas + createCanvas(710, 400); + textSize(15); + noStroke(); + + // create sliders + rSlider = createSlider(0, 255, 100); + rSlider.position(20, 20); + gSlider = createSlider(0, 255, 0); + gSlider.position(20, 50); + bSlider = createSlider(0, 255, 255); + bSlider.position(20, 80); +} + +function draw() { + const r = rSlider.value(); + const g = gSlider.value(); + const b = bSlider.value(); + background(r, g, b); + text('red', rSlider.x * 2 + rSlider.width, 35); + text('green', gSlider.x * 2 + gSlider.width, 65); + text('blue', bSlider.x * 2 + bSlider.width, 95); +} diff --git a/dist/assets/examples/zh-Hans/16_Dom/07_Modify_DOM.js b/dist/assets/examples/zh-Hans/16_Dom/07_Modify_DOM.js new file mode 100644 index 0000000000..9ac89b7595 --- /dev/null +++ b/dist/assets/examples/zh-Hans/16_Dom/07_Modify_DOM.js @@ -0,0 +1,54 @@ +/* + * @name Modifying the DOM + * @frame 710,300 + * @description Create DOM elements and modify their properties every time + * draw() is called. + */ +let dancingWords = []; + +class DanceSpan { + constructor(element, x, y) { + element.position(x, y); + this.element = element; + this.x = x; + this.y = y; + } + + brownian() { + this.x += random(-6, 6); + this.y += random(-6, 6); + this.element.position(this.x, this.y); + } +} + +function setup() { + // This paragraph is created aside of the main block of code. + // It's to differentiate the creation of an element from its + // selection. Selected elements don't need to be created by + // p5js, they can be just plain HTML. + createP( + 'I learn in this Letter, that Don Peter of Aragon, ' + + ' comes this night to Messina' + ).addClass('text').hide(); + + // This line grabs the paragraph just created, but it would + // also grab any other elements with class 'text' in the HTML + // page. + const texts = selectAll('.text'); + + for (let i = 0; i < texts.length; i++) { + const paragraph = texts[i].html(); + const words = paragraph.split(' '); + for (let j = 0; j < words.length; j++) { + const spannedWord = createSpan(words[j]); + const dw = new DanceSpan(spannedWord, random(600), random(200)); + dancingWords.push(dw); + } + } +} + +function draw() { + for (let i = 0; i < dancingWords.length; i++) { + dancingWords[i].brownian(); + } +} diff --git a/dist/assets/examples/zh-Hans/16_Dom/08_Video.js b/dist/assets/examples/zh-Hans/16_Dom/08_Video.js new file mode 100644 index 0000000000..0078d2d793 --- /dev/null +++ b/dist/assets/examples/zh-Hans/16_Dom/08_Video.js @@ -0,0 +1,29 @@ +/* + * @name Video + * @frame 710,250 + * @description Load a video with multiple formats and toggle between playing + * and paused with a button press. + */ +let playing = false; +let fingers; +let button; + +function setup() { + noCanvas(); + // specify multiple formats for different browsers + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + button = createButton('play'); + button.mousePressed(toggleVid); // attach button listener +} + +// plays or pauses the video depending on current state +function toggleVid() { + if (playing) { + fingers.pause(); + button.html('play'); + } else { + fingers.loop(); + button.html('pause'); + } + playing = !playing; +} diff --git a/dist/assets/examples/zh-Hans/16_Dom/09_Video_Canvas.js b/dist/assets/examples/zh-Hans/16_Dom/09_Video_Canvas.js new file mode 100644 index 0000000000..2a59151e06 --- /dev/null +++ b/dist/assets/examples/zh-Hans/16_Dom/09_Video_Canvas.js @@ -0,0 +1,27 @@ +/* + * @name Video Canvas + * @description Load a video with multiple formats and draw it to the canvas. + * To run this example locally, you will need a running + * local server. + */ +let fingers; + +function setup() { + createCanvas(710, 400); + // specify multiple formats for different browsers + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.hide(); // by default video shows up in separate dom + // element. hide it and draw it to the canvas + // instead +} + +function draw() { + background(150); + image(fingers, 10, 10); // draw the video frame to canvas + filter(GRAY); + image(fingers, 150, 150); // draw a second copy to canvas +} + +function mousePressed() { + fingers.loop(); // set the video to loop and start playing +} diff --git a/dist/assets/examples/zh-Hans/16_Dom/10_Video_Pixels.js b/dist/assets/examples/zh-Hans/16_Dom/10_Video_Pixels.js new file mode 100644 index 0000000000..9169e37a3d --- /dev/null +++ b/dist/assets/examples/zh-Hans/16_Dom/10_Video_Pixels.js @@ -0,0 +1,32 @@ +/* + * @name Video Pixels + * @frame 320,240 + * @description Load a video, manipulate its pixels and draw to canvas. + * To run this example locally, you will need a running + * local server. + */ +let fingers; + +function setup() { + createCanvas(320, 240); + // specify multiple formats for different browsers + fingers = createVideo(['assets/fingers.mov', 'assets/fingers.webm']); + fingers.loop(); + fingers.hide(); + noStroke(); + fill(0); +} + +function draw() { + background(255); + fingers.loadPixels(); + const stepSize = round(constrain(mouseX / 8, 6, 32)); + for (let y = 0; y < height; y += stepSize) { + for (let x = 0; x < width; x += stepSize) { + const i = y * width + x; + const darkness = (255 - fingers.pixels[i * 4]) / 255; + const radius = stepSize * darkness; + ellipse(x, y, radius, radius); + } + } +} diff --git a/dist/assets/examples/zh-Hans/16_Dom/11_Capture.js b/dist/assets/examples/zh-Hans/16_Dom/11_Capture.js new file mode 100644 index 0000000000..4e22e6afef --- /dev/null +++ b/dist/assets/examples/zh-Hans/16_Dom/11_Capture.js @@ -0,0 +1,24 @@ +/* + * @name Video Capture + * @frame 710,240 + * @description Capture video from the webcam and display + * on the canvas as well with invert filter. Note that by + * default the capture feed shows up, too. You can hide the + * feed by uncommenting the capture.hide() line. + * To run this example locally, you will need a running + * local server. + */ +let capture; + +function setup() { + createCanvas(390, 240); + capture = createCapture(VIDEO); + capture.size(320, 240); + //capture.hide(); +} + +function draw() { + background(255); + image(capture, 0, 0, 320, 240); + filter(INVERT); +} diff --git a/dist/assets/examples/zh-Hans/16_Dom/12_Drop.js b/dist/assets/examples/zh-Hans/16_Dom/12_Drop.js new file mode 100644 index 0000000000..a36665e460 --- /dev/null +++ b/dist/assets/examples/zh-Hans/16_Dom/12_Drop.js @@ -0,0 +1,33 @@ +/* + * @name Drop + * @description Drag an image file onto the canvas to see it displayed. + */ + +function setup() { + // create canvas + const c = createCanvas(710, 400); + background(100); + // Add an event for when a file is dropped onto the canvas + c.drop(gotFile); +} + +function draw() { + fill(255); + noStroke(); + textSize(24); + textAlign(CENTER); + text('Drag an image file onto the canvas.', width / 2, height / 2); + noLoop(); +} + +function gotFile(file) { + // If it's an image file + if (file.type === 'image') { + // Create an image DOM element but don't show it + const img = createImg(file.data).hide(); + // Draw the image onto the canvas + image(img, 0, 0, width, height); + } else { + println('Not an image file!'); + } +} diff --git a/dist/assets/examples/zh-Hans/16_Dom/13_DOM_Form_Elements.js b/dist/assets/examples/zh-Hans/16_Dom/13_DOM_Form_Elements.js new file mode 100644 index 0000000000..d83dfdc13e --- /dev/null +++ b/dist/assets/examples/zh-Hans/16_Dom/13_DOM_Form_Elements.js @@ -0,0 +1,152 @@ +/* + * @name DOM Form Elements + * @frame 600,400 + * @description contributed by + Prof WM Harris, How to use p5 DOM form elements to create a slider, +button, checkbox, radio group, select menu, and entry field.
+Functions are created that include: the canvas +setup, checkbox creation with text, text box with text that projects +typed text onto canvas, slider with button, three selections which +project a rectangle in different areas on the canvas depending on +selection, and a drop down menu with font change. +*/ + +/* global variables */ +//p5 DOM form elements +let slider1; +let button1; +let checkbox1; +let radio1; +let select1; +let entry1; + +function setup() { + createCanvas(200, 200); + background("beige"); + + checkbox1 = createCheckbox("Check me"); + + createP(); //spacer with

tag + + createSpan("What's your name? "); //label for entry1 + // createInput([value], [type]) + // type: "text" (default), "number", + // "date", "password", "email", etc. + entry1 = createInput(); + //If text in the entry field changes, call + //the entryCallback function. + entry1.changed(entryCallback); + + createP(); //spacer with

tag + + //createSlider(min, max, [value], [step]) + slider1 = createSlider(10, 200); + + button1 = createButton("Press me"); //, "pressed"); + //Assign callback fcn for button1 + //when user clicks mouse on it + button1.mouseClicked(button1Clicked); + + createP(); //spacer with

tag + + radio1 = createRadio(); + + //.option([value], [contentLabel]) + //If 1 param, it's both content AND + //value. Values treated as strings. + radio1.option(1, "cranberries"); + radio1.option(2, "almonds"); + radio1.option(3, "gouda"); + + radio1.value("1"); //set init value + + createP(); //spacer with

tag + + select1 = createSelect(); + //.option([contentValue],[value]) + //If 1 param, it's both content AND + //value. Values treated as strings. + select1.option("Sans-serif"); + select1.option("Serif"); + select1.option("Fantasy"); + //If changed, call select1Changed + select1.changed(select1Changed); +} + +function draw() { + //get value from slider 1 + let gray = slider1.value(); + fill(gray); + + //If mouse in corner, turn on checkbox1 + if ((mouseX < width / 3) && + (mouseY < height / 3)) { + checkbox1.checked(true); + } + //Is checkbox1 checked? Say so. + if (checkbox1.checked()) { + text("CHECKED", 20, 40); + } + + switch (radio1.value()) { + //radio value is always a string + case "1": + rect(0, 0, width, 50); + break; + case "2": + rect(0, 70, width, 50); + break; + case "3": + rect(0, 140, width, 50); + break; + } +} + +//callback fcn for button1 +function button1Clicked() { + //reset slider value to 200 + slider1.value(200); +} + + +//callback fcn for select1 +function select1Changed() { + switch (select1.value()) { + case "Sans-serif": + textFont("sans-serif"); + break; + case "Serif": + textFont("serif"); + break; + case "Fantasy": + textFont("fantasy"); + break; + } +} + +//callback function for entry1 +function entryCallback() { + for (let i = 0; i < 25; i++) { + text(entry1.value(), random(width), + random(height)); + } + +} + +function mouseClicked() { + console.log("button1?", button1.value()); + console.log("checkbox1?", checkbox1.value()); + //Update .value of either? No visible change + //to a button or checkbox + checkbox1.value("Check again"); + button1.value("clicked?"); +} + +function keyTyped() { + switch (key) { + case "r": + //move slider1 value to 100 + slider1.value(100); + break; + } +} diff --git a/dist/assets/examples/zh-Hans/17_Drawing/00_Continuous_Lines.js b/dist/assets/examples/zh-Hans/17_Drawing/00_Continuous_Lines.js new file mode 100644 index 0000000000..f0a598656f --- /dev/null +++ b/dist/assets/examples/zh-Hans/17_Drawing/00_Continuous_Lines.js @@ -0,0 +1,15 @@ +/* + * @name Líneas continuas + * @description Haga clic y arrastre el mouse para dibujar una línea. + */ +function setup() { + createCanvas(710, 400); + background(102); +} + +function draw() { + stroke(255); + if (mouseIsPressed === true) { + line(mouseX, mouseY, pmouseX, pmouseY); + } +} diff --git a/dist/assets/examples/zh-Hans/17_Drawing/01_Pattern.js b/dist/assets/examples/zh-Hans/17_Drawing/01_Pattern.js new file mode 100644 index 0000000000..5f3401737d --- /dev/null +++ b/dist/assets/examples/zh-Hans/17_Drawing/01_Pattern.js @@ -0,0 +1,26 @@ +/* + * @name Patrones + * @description Mueva el cursor sobre la imagen para dibujar con una herramienta + * de software que responda a la velocidad del mouse. + */ +function setup() { + createCanvas(710, 400); + background(102); +} + +function draw() { + // Llame al método variableEllipse () y envíele los parámetros + // para la posición actual del mouse y la posición anterior del mouse + variableEllipse(mouseX, mouseY, pmouseX, pmouseY); +} + +// El método simple variableEllipse () fue creado específicamente +// para este programa. Calcula la velocidad del mouse +// y dibuja una pequeña elipse si el mouse se mueve lentamente +// y dibuja una elipse grande si el mouse se mueve rápidamente + +function variableEllipse(x, y, px, py) { + let speed = abs(x - px) + abs(y - py); + stroke(speed); + ellipse(x, y, speed, speed); +} diff --git a/dist/assets/examples/zh-Hans/17_Drawing/02_Pulses.js b/dist/assets/examples/zh-Hans/17_Drawing/02_Pulses.js new file mode 100644 index 0000000000..b808a4ece0 --- /dev/null +++ b/dist/assets/examples/zh-Hans/17_Drawing/02_Pulses.js @@ -0,0 +1,31 @@ +/* + * @name Pulsos + * @description Los instrumentos de dibujo de software pueden seguir un ritmo o + * cumplir las reglas independientemente de los gestos dibujados. Esta es una + * forma de dibujo colaborativo en el que el dibujante controla algunos aspectos + * de la imagen y el software controla a los demás. + */ +let angle = 0; + +function setup() { + createCanvas(710, 400); + background(102); + noStroke(); + fill(0, 102); +} + +function draw() { + // Dibujar solo cuando se presiona el mouse + if (mouseIsPressed === true) { + angle += 5; + let val = cos(radians(angle)) * 12.0; + for (let a = 0; a < 360; a += 75) { + let xoff = cos(radians(a)) * val; + let yoff = sin(radians(a)) * val; + fill(0); + ellipse(mouseX + xoff, mouseY + yoff, val, val); + } + fill(255); + ellipse(mouseX, mouseY, 2, 2); + } +} diff --git a/dist/assets/examples/zh-Hans/18_Transform/00_Translate.js b/dist/assets/examples/zh-Hans/18_Transform/00_Translate.js new file mode 100644 index 0000000000..1599f1cf4f --- /dev/null +++ b/dist/assets/examples/zh-Hans/18_Transform/00_Translate.js @@ -0,0 +1,40 @@ +/* + * @name Translate + * @description The translate() function allows objects to be + * moved to any location within the window. The first parameter + * sets the x-axis offset and the second parameter sets the + * y-axis offset. This example shows how transforms accumulate. + */ + +let x = 0; +let y = 0; +let dim = 80.0; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(102); + // Animate by increasing our x value + x = x + 0.8; + // If the shape goes off the canvas, reset the position + if (x > width + dim) { + x = -dim; + } + + // Even though our rect command draws the shape with its + // center at the origin, translate moves it to the new + // x and y position + translate(x, height / 2 - dim / 2); + fill(255); + rect(-dim / 2, -dim / 2, dim, dim); + + // Transforms accumulate. Notice how this rect moves + // twice as fast as the other, but it has the same + // parameter for the x-axis value + translate(x, dim); + fill(0); + rect(-dim / 2, -dim / 2, dim, dim); +} diff --git a/dist/assets/examples/zh-Hans/18_Transform/01_Scale.js b/dist/assets/examples/zh-Hans/18_Transform/01_Scale.js new file mode 100644 index 0000000000..d176f25680 --- /dev/null +++ b/dist/assets/examples/zh-Hans/18_Transform/01_Scale.js @@ -0,0 +1,46 @@ +/* + * @name Scale + * @description Paramenters for the scale() function are values + * specified as decimal percentages. For example, the method + * call scale(2.0) will increase the dimension of the shape by + * 200 percent. Objects always scale from the origin. This example + * shows how transforms accumulate and also how scale and translate + * interact depending on their order. + */ + +let a = 0.0; +let s = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + //Draw all rectangles from their center as opposed to + // the default upper left corner + rectMode(CENTER); +} + +function draw() { + background(102); + + //Slowly increase 'a' and then animate 's' with + //a smooth cyclical motion by finding the cosine of 'a' + a = a + 0.04; + s = cos(a) * 2; + + //Translate our rectangle from the origin to the middle of + //the canvas, then scale it with 's' + translate(width / 2, height / 2); + scale(s); + fill(51); + rect(0, 0, 50, 50); + + //Translate and scale are accumulating, so this translate + //moves the second rectangle further right than the first + //and the scale is getting doubled. Note that cosine is + //making 's' both negative and positive, thus it cycles + //from left to right. + translate(75, 0); + fill(255); + scale(s); + rect(0, 0, 50, 50); +} diff --git a/dist/assets/examples/zh-Hans/18_Transform/02_Rotate.js b/dist/assets/examples/zh-Hans/18_Transform/02_Rotate.js new file mode 100644 index 0000000000..6b91dc2186 --- /dev/null +++ b/dist/assets/examples/zh-Hans/18_Transform/02_Rotate.js @@ -0,0 +1,43 @@ +/* + * @name Rotate + * @description Rotating a square around the Z axis. + * To get the results you expect, send the rotate function angle + * parameters that are values between 0 and PI*2 (TWO_PI which is + * roughly 6.28). If you prefer to think about angles as degrees + * (0-360), you can use the radians() method to convert your values. + * For example: scale(radians(90)) is identical to the statement + * scale(PI/2). In this example, every even numbered second a jitter + * is added to the rotation. During odd seconds rotation moves CW and + * CCW at the speed determined by the last jitter value. + */ + +let angle = 0.0; +let jitter = 0.0; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255); + //Draw the rectangle from the center and it will also be the + //rotate around that center + rectMode(CENTER); +} + +function draw() { + background(51); + + // during even-numbered seconds (0, 2, 4, 6...) add jitter to + // the rotation + if (second() % 2 === 0) { + jitter = random(-0.1, 0.1); + } + //increase the angle value using the most recent jitter value + angle = angle + jitter; + //use cosine to get a smooth CW and CCW motion when not jittering + let c = cos(angle); + //move the shape to the center of the canvas + translate(width / 2, height / 2); + //apply the final rotation + rotate(c); + rect(0, 0, 180, 180); +} diff --git a/dist/assets/examples/zh-Hans/18_Transform/03_Arm.js b/dist/assets/examples/zh-Hans/18_Transform/03_Arm.js new file mode 100644 index 0000000000..733fe30909 --- /dev/null +++ b/dist/assets/examples/zh-Hans/18_Transform/03_Arm.js @@ -0,0 +1,49 @@ +/* + * @name Arm + * @description This example uses transform matrices to create + * an arm. The angle of each segment is controlled with the + * mouseX and mouseY position. The transformations applied to + * the first segment are also applied to the second segment + * because they are inside the same push() and + * pop() matrix group. + */ + +let x, y; +let angle1 = 0.0; +let angle2 = 0.0; +let segLength = 100; + +function setup() { + createCanvas(720, 400); + strokeWeight(30); + + //Stroke with a semi-transparent white + stroke(255, 160); + + //Position the "shoulder" of the arm in the center of the canvas + x = width * 0.5; + y = height * 0.5; +} + +function draw() { + background(0); + + //Change the angle of the segments according to the mouse positions + angle1 = (mouseX / float(width) - 0.5) * -TWO_PI; + angle2 = (mouseY / float(height) - 0.5) * PI; + + //use push and pop to "contain" the transforms. Note that + // even though we draw the segments using a custom function, + // the transforms still accumulate + push(); + segment(x, y, angle1); + segment(segLength, 0, angle2); + pop(); +} + +//a custom function for drawing segments +function segment(x, y, a) { + translate(x, y); + rotate(a); + line(0, 0, segLength, 0); +} diff --git a/dist/assets/examples/zh-Hans/19_Typography/00_Letters.js b/dist/assets/examples/zh-Hans/19_Typography/00_Letters.js new file mode 100644 index 0000000000..44d4f2a7ee --- /dev/null +++ b/dist/assets/examples/zh-Hans/19_Typography/00_Letters.js @@ -0,0 +1,64 @@ +/* + * @name Letters + * @description Letters can be drawn to the screen by loading a font, setting + * its characteristics and then drawing the letters. This example uses a for + * loop and unicode reference numbers to automatically fill the canvas with + * characters in a grid. Vowels are selected and given a specific fill color. + */ +let font, + fontsize = 32; + +function preload() { + // Ensure the .ttf or .otf font stored in the assets directory + // is loaded before setup() and draw() are called + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // Set text characteristics + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // Set the gap between letters and the left and top margin + let gap = 52; + let margin = 10; + translate(margin * 4, margin * 4); + + // Set the counter to start at the character you want + // in this case 35, which is the # symbol + let counter = 35; + + // Loop as long as there is space on the canvas + for (y = 0; y < height - gap; y += gap) { + for (x = 0; x < width - gap; x += gap) { + // Use the counter to retrieve individual letters by their Unicode number + let letter = char(counter); + + // Add different color to the vowels and other characters + if ( + letter === 'A' || + letter === 'E' || + letter === 'I' || + letter === 'O' || + letter === 'U' + ) { + fill('#ed225d'); + } else { + fill(255); + } + + // Draw the letter to the screen + text(letter, x, y); + + // Increment the counter + counter++; + } + } +} diff --git a/dist/assets/examples/zh-Hans/19_Typography/01_Words.js b/dist/assets/examples/zh-Hans/19_Typography/01_Words.js new file mode 100644 index 0000000000..d76271f2b8 --- /dev/null +++ b/dist/assets/examples/zh-Hans/19_Typography/01_Words.js @@ -0,0 +1,59 @@ +/* + * @name Words + * @description The text() function is used for writing words to the screen. + * The words can be aligned left, center, or right with the textAlign() + * function, and like with shapes, words can be colored with fill(). + */ +let font, + fontsize = 40; + +function preload() { + // Ensure the .ttf or .otf font stored in the assets directory + // is loaded before setup() and draw() are called + font = loadFont('assets/SourceSansPro-Regular.otf'); +} + +function setup() { + createCanvas(710, 400); + + // Set text characteristics + textFont(font); + textSize(fontsize); + textAlign(CENTER, CENTER); +} + +function draw() { + background(160); + + // Align the text to the right + // and run drawWords() in the left third of the canvas + textAlign(RIGHT); + drawWords(width * 0.25); + + // Align the text in the center + // and run drawWords() in the middle of the canvas + textAlign(CENTER); + drawWords(width * 0.5); + + // Align the text to the left + // and run drawWords() in the right third of the canvas + textAlign(LEFT); + drawWords(width * 0.75); +} + +function drawWords(x) { + // The text() function needs three parameters: + // the text to draw, the horizontal position, + // and the vertical position + fill(0); + text('ichi', x, 80); + + fill(65); + text('ni', x, 150); + + fill(190); + text('san', x, 220); + + fill(255); + text('shi', x, 290); +} diff --git a/dist/assets/examples/zh-Hans/19_Typography/02_Text_Rotation.js b/dist/assets/examples/zh-Hans/19_Typography/02_Text_Rotation.js new file mode 100644 index 0000000000..fdfd7d31a5 --- /dev/null +++ b/dist/assets/examples/zh-Hans/19_Typography/02_Text_Rotation.js @@ -0,0 +1,62 @@ +/* + * @name Text Rotation + * @description Draws letters to the screen and rotates them at different angles. + * (ported from https://processing.org/examples/textrotation.html) + */ + +let font, + fontsize = 32; + +let angleRotate = 0.0; + +function setup() { + createCanvas(710, 400); + background(0); + + // Ensure the .ttf or .otf font stored in the assets directory + // is loaded before setup() and draw() are called + font = loadFont('assets/SourceSansPro-Regular.otf'); + + // Set text characteristics + textFont(font); +} + +function draw() { + background(0); + + strokeWeight(1); + stroke(153); + + push(); + let angle1 = radians(45); + translate(100, 180); + rotate(angle1); + // Draw the letter to the screen + text("45 DEGREES", 0, 0); + line(0, 0, 150, 0); + pop(); + + push(); + let angle2 = radians(270); + translate(200, 180); + rotate(angle2); + // Draw the letter to the screen + text("270 DEGREES", 0, 0); + line(0, 0, 150, 0); + pop(); + + push(); + translate(440, 180); + rotate(radians(angleRotate)); + text(int(angleRotate) % 360 + " DEGREES ", 0, 0); + line(0, 0, 150, 0); + pop(); + + angleRotate += 0.25; + + stroke(255, 0, 0); + strokeWeight(4); + point(100, 180); + point(200, 180); + point(440, 180); +} diff --git a/dist/assets/examples/zh-Hans/20_3D/00_geometries.js b/dist/assets/examples/zh-Hans/20_3D/00_geometries.js new file mode 100644 index 0000000000..a58cce64e8 --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/00_geometries.js @@ -0,0 +1,60 @@ +/* + * @name Geometries + * @description There are six 3D primitives in p5 now. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + + translate(-240, -100, 0); + normalMaterial(); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + plane(70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + box(70, 70, 70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cylinder(70, 70); + pop(); + + translate(-240 * 2, 200, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + cone(70, 70); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + torus(70, 20); + pop(); + + translate(240, 0, 0); + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + sphere(70); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/20_3D/01_sine_cosine_in_3D.js b/dist/assets/examples/zh-Hans/20_3D/01_sine_cosine_in_3D.js new file mode 100644 index 0000000000..d9adf11963 --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/01_sine_cosine_in_3D.js @@ -0,0 +1,28 @@ +/* + * @name Sine Cosine in 3D + * @description Sine, cosine and push / pop could be applied in 3D as well. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + rotateY(frameCount * 0.01); + + for (let j = 0; j < 5; j++) { + push(); + for (let i = 0; i < 80; i++) { + translate( + sin(frameCount * 0.001 + j) * 100, + sin(frameCount * 0.001 + j) * 100, + i * 0.1 + ); + rotateZ(frameCount * 0.002); + push(); + sphere(8, 6, 4); + pop(); + } + pop(); + } +} diff --git a/dist/assets/examples/zh-Hans/20_3D/02_multiple_lights.js b/dist/assets/examples/zh-Hans/20_3D/02_multiple_lights.js new file mode 100644 index 0000000000..7bed590f63 --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/02_multiple_lights.js @@ -0,0 +1,30 @@ +/* + * @name Multiple Lights + * @description All types of lights could be used in one sketch. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(50); + directionalLight(255, 0, 0, 0.25, 0.25, 0); + pointLight(0, 0, 255, locX, locY, 250); + + push(); + translate(-width / 4, 0, 0); + rotateZ(frameCount * 0.02); + rotateX(frameCount * 0.02); + specularMaterial(250); + box(100, 100, 100); + pop(); + + translate(width / 4, 0, 0); + ambientMaterial(250); + sphere(120, 64); +} diff --git a/dist/assets/examples/zh-Hans/20_3D/03_materials.js b/dist/assets/examples/zh-Hans/20_3D/03_materials.js new file mode 100644 index 0000000000..4dd7e97e37 --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/03_materials.js @@ -0,0 +1,65 @@ +/* + * @name Materials + * @description There are five types of materials supported. + * They respond to light differently. + * Move your mouse to change the light position. + */ +let img; +function setup() { + createCanvas(710, 400, WEBGL); + img = loadImage('assets/cat.jpg'); +} + +function draw() { + background(0); + + let locX = mouseX - height / 2; + let locY = mouseY - width / 2; + + ambientLight(60, 60, 60); + pointLight(255, 255, 255, locX, locY, 100); + + push(); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + texture(img); + box(80); + pop(); + + push(); + translate(-width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + fill(250, 0, 0); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, -height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + normalMaterial(); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(-width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + ambientMaterial(250); + torus(80, 20, 64, 64); + pop(); + + push(); + translate(width / 4, height / 4, 0); + rotateZ(frameCount * 0.01); + rotateX(frameCount * 0.01); + rotateY(frameCount * 0.01); + specularMaterial(250); + torus(80, 20, 64, 64); + pop(); +} diff --git a/dist/assets/examples/zh-Hans/20_3D/04_textures.js b/dist/assets/examples/zh-Hans/20_3D/04_textures.js new file mode 100644 index 0000000000..0a4df84872 --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/04_textures.js @@ -0,0 +1,40 @@ +/* + * @name Textures + * @description Images and videos are supported for texture. + */ +// video source: https://vimeo.com/90312869 +let img; +let vid; +let theta = 0; + +function setup() { + createCanvas(710, 400, WEBGL); + + img = loadImage('assets/cat.jpg'); + vid = createVideo(['assets/360video_256crop_v2.mp4']); + vid.elt.muted = true; + vid.loop(); + vid.hide(); +} + +function draw() { + background(250); + translate(-220, 0, 0); + push(); + rotateZ(theta * mouseX * 0.001); + rotateX(theta * mouseX * 0.001); + rotateY(theta * mouseX * 0.001); + //pass image as texture + texture(vid); + sphere(150); + pop(); + translate(440, 0, 0); + push(); + rotateZ(theta * 0.1); + rotateX(theta * 0.1); + rotateY(theta * 0.1); + texture(img); + box(100, 100, 100); + pop(); + theta += 0.05; +} diff --git a/dist/assets/examples/zh-Hans/20_3D/05_ray_casting.js b/dist/assets/examples/zh-Hans/20_3D/05_ray_casting.js new file mode 100644 index 0000000000..98906dcb28 --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/05_ray_casting.js @@ -0,0 +1,100 @@ +/* + * @name Ray Casting + * @description Original example by Jonathan Watson. + *

Detecting the position of the mouse in 3D space with ray casting. + */ +const objects = []; +let eyeZ; + +function setup() { + createCanvas(710, 400, WEBGL); + + eyeZ = height / 2 / tan((30 * PI) / 180); // The default distance the camera is away from the origin. + + objects.push(new IntersectPlane(1, 0, 0, -100, 0, 0)); // Left wall + objects.push(new IntersectPlane(1, 0, 0, 100, 0, 0)); // Right wall + objects.push(new IntersectPlane(0, 1, 0, 0, -100, 0)); // Bottom wall + objects.push(new IntersectPlane(0, 1, 0, 0, 100, 0)); // Top wall + objects.push(new IntersectPlane(0, 0, 1, 0, 0, 0)); // Back wall + + noStroke(); + ambientMaterial(250); +} + +function draw() { + background(0); + + // Lights + pointLight(255, 255, 255, 0, 0, 400); + ambientLight(244, 122, 158); + + // Left wall + push(); + translate(-100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // Right wall + push(); + translate(100, 0, 200); + rotateY((90 * PI) / 180); + plane(400, 200); + pop(); + + // Bottom wall + push(); + translate(0, 100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + // Top wall + push(); + translate(0, -100, 200); + rotateX((90 * PI) / 180); + plane(200, 400); + pop(); + + plane(200, 200); // Back wall + + const x = mouseX - width / 2; + const y = mouseY - height / 2; + + const Q = createVector(0, 0, eyeZ); // A point on the ray and the default position of the camera. + const v = createVector(x, y, -eyeZ); // The direction vector of the ray. + + let intersect; // The point of intersection between the ray and a plane. + let closestLambda = eyeZ * 10; // The draw distance. + + for (let x = 0; x < objects.length; x += 1) { + let object = objects[x]; + let lambda = object.getLambda(Q, v); // The value of lambda where the ray intersects the object + + if (lambda < closestLambda && lambda > 0) { + // Find the position of the intersection of the ray and the object. + intersect = p5.Vector.add(Q, p5.Vector.mult(v, lambda)); + closestLambda = lambda; + } + } + + // Cursor + push(); + translate(intersect); + fill(237, 34, 93); + sphere(10); + pop(); +} + +// Class for a plane that extends to infinity. +class IntersectPlane { + constructor(n1, n2, n3, p1, p2, p3) { + this.normal = createVector(n1, n2, n3); // The normal vector of the plane + this.point = createVector(p1, p2, p3); // A point on the plane + this.d = this.point.dot(this.normal); + } + + getLambda(Q, v) { + return (-this.d - this.normal.dot(Q)) / this.normal.dot(v); + } +} diff --git a/dist/assets/examples/zh-Hans/20_3D/07_orbit_control.js b/dist/assets/examples/zh-Hans/20_3D/07_orbit_control.js new file mode 100644 index 0000000000..7d30f82cbd --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/07_orbit_control.js @@ -0,0 +1,36 @@ +/* + * @name Orbit Control + * @description Orbit control allows you to drag and move around the world. + */ +function setup() { + createCanvas(710, 400, WEBGL); +} + +function draw() { + background(250); + let radius = width * 1.5; + + //drag to move the world. + orbitControl(); + + normalMaterial(); + translate(0, 0, -600); + for (let i = 0; i <= 12; i++) { + for (let j = 0; j <= 12; j++) { + push(); + let a = (j / 12) * PI; + let b = (i / 12) * PI; + translate( + sin(2 * a) * radius * sin(b), + (cos(b) * radius) / 2, + cos(2 * a) * radius * sin(b) + ); + if (j % 2 === 0) { + cone(30, 30); + } else { + box(30, 30, 30); + } + pop(); + } + } +} diff --git a/dist/assets/examples/zh-Hans/20_3D/08_basic_shader.js b/dist/assets/examples/zh-Hans/20_3D/08_basic_shader.js new file mode 100644 index 0000000000..32610c79e4 --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/08_basic_shader.js @@ -0,0 +1,27 @@ +/* + * @name Basic Shader + * @description This is a basic example showing how to load shaders in p5.js. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + +// this variable will hold our shader object +let theShader; + +function preload(){ + // load the shader + theShader = loadShader('assets/basic.vert', 'assets/basic.frag'); +} + +function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); +} + +function draw() { + // shader() sets the active shader with our shader + shader(theShader); + + // rect gives us some geometry on the screen + rect(0,0,width, height); +} diff --git a/dist/assets/examples/zh-Hans/20_3D/09_shader_as_a_texture.js b/dist/assets/examples/zh-Hans/20_3D/09_shader_as_a_texture.js new file mode 100644 index 0000000000..7bffbab11b --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/09_shader_as_a_texture.js @@ -0,0 +1,68 @@ +/* + * @name Shader as a Texture + * @description Shaders can be applied to 2D/3D shapes as textures. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + + // this variable will hold our shader object + let theShader; + // this variable will hold our createGraphics layer + let shaderTexture; + + let theta = 0; + + let x; + let y; + let outsideRadius = 200; + let insideRadius = 100; + + function preload(){ + // load the shader + theShader = loadShader('assets/texture.vert','assets/texture.frag'); + } + + function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); + + // initialize the createGraphics layers + shaderTexture = createGraphics(710, 400, WEBGL); + + // turn off the createGraphics layers stroke + shaderTexture.noStroke(); + + x = -50; + y = 0; + } + + function draw() { + + // instead of just setting the active shader we are passing it to the createGraphics layer + shaderTexture.shader(theShader); + + // here we're using setUniform() to send our uniform values to the shader + theShader.setUniform("resolution", [width, height]); + theShader.setUniform("time", millis() / 1000.0); + theShader.setUniform("mouse", [mouseX, map(mouseY, 0, height, height, 0)]); + + // passing the shaderTexture layer geometry to render on + shaderTexture.rect(0,0,width,height); + + background(255); + + // pass the shader as a texture + texture(shaderTexture); + + translate(-150, 0, 0); + push(); + rotateZ(theta * mouseX * 0.0001); + rotateX(theta * mouseX * 0.0001); + rotateY(theta * mouseX * 0.0001); + theta += 0.05; + sphere(125); + pop(); + + // passing a fifth parameter to ellipse for smooth edges in 3D + ellipse(260,0,200,200,100); + } diff --git a/dist/assets/examples/zh-Hans/20_3D/10_passing_shader_uniforms.js b/dist/assets/examples/zh-Hans/20_3D/10_passing_shader_uniforms.js new file mode 100644 index 0000000000..3d6dc2ec1b --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/10_passing_shader_uniforms.js @@ -0,0 +1,33 @@ +/* + * @name Passing Shader Uniforms + * @description Uniforms are the way in which information is passed from p5 to the shader. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + + // this variable will hold our shader object + let theShader; + + function preload(){ + // load the shader + theShader = loadShader('assets/uniforms.vert', 'assets/uniforms.frag'); + } + + function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); + } + + function draw() { + // shader() sets the active shader with our shader + shader(theShader); + + // lets send the resolution, mouse, and time to our shader + // before sending mouse + time we modify the data so it's more easily usable by the shader + theShader.setUniform('resolution', [width, height]); + theShader.setUniform('mouse', map(mouseX, 0, width, 0, 7)); + theShader.setUniform('time', frameCount * 0.01); + + // rect gives us some geometry on the screen + rect(0,0,width, height); + } diff --git a/dist/assets/examples/zh-Hans/20_3D/11_shader_using_webcam.js b/dist/assets/examples/zh-Hans/20_3D/11_shader_using_webcam.js new file mode 100644 index 0000000000..9e14ebe086 --- /dev/null +++ b/dist/assets/examples/zh-Hans/20_3D/11_shader_using_webcam.js @@ -0,0 +1,38 @@ +/* + * @name Shader Using Webcam + * @description The webcam can be passed to shaders as a texture. + *
To learn more about using shaders in p5.js: p5.js Shaders + */ + +// this variable will hold our shader object +let theShader; +// this variable will hold our webcam video +let cam; + +function preload() { + // load the shader + theShader = loadShader('assets/webcam.vert', 'assets/webcam.frag'); +} + +function sizeVideo() { + cam.size(710, 400); + cam.hide(); +} +function setup() { + // shaders require WEBGL mode to work + createCanvas(710, 400, WEBGL); + noStroke(); + + cam = createCapture(VIDEO, sizeVideo); +} + +function draw() { + // shader() sets the active shader with our shader + shader(theShader); + + // passing cam as a texture + theShader.setUniform('tex0', cam); + + // rect gives us some geometry on the screen + rect(0, 0, width, height); +} diff --git a/dist/assets/examples/zh-Hans/21_Input/00_Clock.js b/dist/assets/examples/zh-Hans/21_Input/00_Clock.js new file mode 100644 index 0000000000..5603db0f3e --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/00_Clock.js @@ -0,0 +1,62 @@ +/* + * @name Clock + * @description The current time can be read with the second(), + * minute(), and hour() functions. In this example, sin() and + * cos() values are used to set the position of the hands. + */ +let cx, cy; +let secondsRadius; +let minutesRadius; +let hoursRadius; +let clockDiameter; + +function setup() { + createCanvas(720, 400); + stroke(255); + + let radius = min(width, height) / 2; + secondsRadius = radius * 0.71; + minutesRadius = radius * 0.6; + hoursRadius = radius * 0.5; + clockDiameter = radius * 1.7; + + cx = width / 2; + cy = height / 2; +} + +function draw() { + background(230); + + // Draw the clock background + noStroke(); + fill(244, 122, 158); + ellipse(cx, cy, clockDiameter + 25, clockDiameter + 25); + fill(237, 34, 93); + ellipse(cx, cy, clockDiameter, clockDiameter); + + // Angles for sin() and cos() start at 3 o'clock; + // subtract HALF_PI to make them start at the top + let s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI; + let m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI; + let h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI; + + // Draw the hands of the clock + stroke(255); + strokeWeight(1); + line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius); + strokeWeight(2); + line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius); + strokeWeight(4); + line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius); + + // Draw the minute ticks + strokeWeight(2); + beginShape(POINTS); + for (let a = 0; a < 360; a += 6) { + let angle = radians(a); + let x = cx + cos(angle) * secondsRadius; + let y = cy + sin(angle) * secondsRadius; + vertex(x, y); + } + endShape(); +} diff --git a/dist/assets/examples/zh-Hans/21_Input/01_Constrain.js b/dist/assets/examples/zh-Hans/21_Input/01_Constrain.js new file mode 100644 index 0000000000..36a08abd31 --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/01_Constrain.js @@ -0,0 +1,36 @@ +/* + * @name Constrain + * @description Move the mouse across the screen to move + * the circle. The program constrains the circle to its box. + */ +let mx = 1; +let my = 1; +let easing = 0.05; +let radius = 24; +let edge = 100; +let inner = edge + radius; + +function setup() { + createCanvas(720, 400); + noStroke(); + ellipseMode(RADIUS); + rectMode(CORNERS); +} + +function draw() { + background(230); + + if (abs(mouseX - mx) > 0.1) { + mx = mx + (mouseX - mx) * easing; + } + if (abs(mouseY - my) > 0.1) { + my = my + (mouseY - my) * easing; + } + + mx = constrain(mx, inner, width - inner); + my = constrain(my, inner, height - inner); + fill(237, 34, 93); + rect(edge, edge, width - edge, height - edge); + fill(255); + ellipse(mx, my, radius, radius); +} diff --git a/dist/assets/examples/zh-Hans/21_Input/02_Easing.js b/dist/assets/examples/zh-Hans/21_Input/02_Easing.js new file mode 100644 index 0000000000..6fe01dc1b0 --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/02_Easing.js @@ -0,0 +1,30 @@ +/* + * @name Easing + * @description Move the mouse across the screen and the symbol + * will follow. Between drawing each frame of the animation, the + * program calculates the difference between the position of the + * symbol and the cursor. If the distance is larger than 1 pixel, + * the symbol moves part of the distance (0.05) from its current + * position toward the cursor. + */ +let x = 1; +let y = 1; +let easing = 0.05; + +function setup() { + createCanvas(720, 400); + noStroke(); +} + +function draw() { + background(237, 34, 93); + let targetX = mouseX; + let dx = targetX - x; + x += dx * easing; + + let targetY = mouseY; + let dy = targetY - y; + y += dy * easing; + + ellipse(x, y, 66, 66); +} diff --git a/dist/assets/examples/zh-Hans/21_Input/03_Keyboard.js b/dist/assets/examples/zh-Hans/21_Input/03_Keyboard.js new file mode 100644 index 0000000000..c7b50f99a3 --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/03_Keyboard.js @@ -0,0 +1,38 @@ +/* + * @name Keyboard + * @description Click on the image to give it focus and + * press the letter keys to create forms in time and space. + * Each key has a unique identifying number. These numbers + * can be used to position shapes in space. + */ +let rectWidth; + +function setup() { + createCanvas(720, 400); + noStroke(); + background(230); + rectWidth = width / 4; +} + +function draw() { + // keep draw() here to continue looping while waiting for keys +} + +function keyPressed() { + let keyIndex = -1; + if (key >= 'a' && key <= 'z') { + keyIndex = key.charCodeAt(0) - 'a'.charCodeAt(0); + } + if (keyIndex === -1) { + // If it's not a letter key, clear the screen + background(230); + } else { + // It's a letter key, fill a rectangle + randFill_r = Math.floor(Math.random() * 255 + 1); + randFill_g = Math.floor(Math.random() * 255 + 1); + randFill_b = Math.floor(Math.random() * 255 + 1); + fill(randFill_r, randFill_g, randFill_b); + let x = map(keyIndex, 0, 25, 0, width - rectWidth); + rect(x, 0, rectWidth, height); + } +} diff --git a/dist/assets/examples/zh-Hans/21_Input/04_Mouse1D.js b/dist/assets/examples/zh-Hans/21_Input/04_Mouse1D.js new file mode 100644 index 0000000000..eb613fbab9 --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/04_Mouse1D.js @@ -0,0 +1,24 @@ +/* + * @name Mouse 1D + * @description Move the mouse left and right to + * shift the balance. The "mouseX" variable is used + * to control both the size and color of the rectangles. + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + + let r1 = map(mouseX, 0, width, 0, height); + let r2 = height - r1; + + fill(237, 34, 93, r1); + rect(width / 2 + r1 / 2, height / 2, r1, r1); + + fill(237, 34, 93, r2); + rect(width / 2 - r2 / 2, height / 2, r2, r2); +} diff --git a/dist/assets/examples/zh-Hans/21_Input/05_Mouse2D.js b/dist/assets/examples/zh-Hans/21_Input/05_Mouse2D.js new file mode 100644 index 0000000000..efc623adae --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/05_Mouse2D.js @@ -0,0 +1,20 @@ +/* + * @name Mouse 2D + * @description Moving the mouse changes the position and + * size of each box. + */ +function setup() { + createCanvas(720, 400); + noStroke(); + rectMode(CENTER); +} + +function draw() { + background(230); + fill(244, 122, 158); + rect(mouseX, height / 2, mouseY / 2 + 10, mouseY / 2 + 10); + fill(237, 34, 93); + let inverseX = width - mouseX; + let inverseY = height - mouseY; + rect(inverseX, height / 2, inverseY / 2 + 10, inverseY / 2 + 10); +} diff --git a/dist/assets/examples/zh-Hans/21_Input/06_MouseIsPressed.js b/dist/assets/examples/zh-Hans/21_Input/06_MouseIsPressed.js new file mode 100644 index 0000000000..27279e99b0 --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/06_MouseIsPressed.js @@ -0,0 +1,20 @@ +/* + * @name Mouse Press + * @description Move the mouse to position the shape. + * Press the mouse button to invert the color. + */ +function setup() { + createCanvas(720, 400); + background(230); + strokeWeight(2); +} + +function draw() { + if (mouseIsPressed) { + stroke(255); + } else { + stroke(237, 34, 93); + } + line(mouseX - 66, mouseY, mouseX + 66, mouseY); + line(mouseX, mouseY - 66, mouseX, mouseY + 66); +} diff --git a/dist/assets/examples/zh-Hans/21_Input/07_Mouse_Functions.js b/dist/assets/examples/zh-Hans/21_Input/07_Mouse_Functions.js new file mode 100644 index 0000000000..ad1acdc7b2 --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/07_Mouse_Functions.js @@ -0,0 +1,66 @@ +/* + * @name Mouse Functions + * @description Click on the box and drag it across the screen. + */ +let bx; +let by; +let boxSize = 75; +let overBox = false; +let locked = false; +let xOffset = 0.0; +let yOffset = 0.0; + +function setup() { + createCanvas(720, 400); + bx = width / 2.0; + by = height / 2.0; + rectMode(RADIUS); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + // Test if the cursor is over the box + if ( + mouseX > bx - boxSize && + mouseX < bx + boxSize && + mouseY > by - boxSize && + mouseY < by + boxSize + ) { + overBox = true; + if (!locked) { + stroke(255); + fill(244, 122, 158); + } + } else { + stroke(156, 39, 176); + fill(244, 122, 158); + overBox = false; + } + + // Draw the box + rect(bx, by, boxSize, boxSize); +} + +function mousePressed() { + if (overBox) { + locked = true; + fill(255, 255, 255); + } else { + locked = false; + } + xOffset = mouseX - bx; + yOffset = mouseY - by; +} + +function mouseDragged() { + if (locked) { + bx = mouseX - xOffset; + by = mouseY - yOffset; + } +} + +function mouseReleased() { + locked = false; +} diff --git a/dist/assets/examples/zh-Hans/21_Input/08_Mouse_Signals.js b/dist/assets/examples/zh-Hans/21_Input/08_Mouse_Signals.js new file mode 100644 index 0000000000..8847fe8f1c --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/08_Mouse_Signals.js @@ -0,0 +1,52 @@ +/* + * @name Mouse Signals + * @description Move and click the mouse to generate signals. + * The top row is the signal from "mouseX", the middle row is + * the signal from "mouseY", and the bottom row is the signal + * from "mouseIsPressed". + */ +let xvals = []; +let yvals = []; +let bvals = []; + +function setup() { + createCanvas(720, 400); + strokeWeight(2); +} + +function draw() { + background(237, 34, 93); + + for (let i = 1; i < width; i++) { + xvals[i - 1] = xvals[i]; + yvals[i - 1] = yvals[i]; + bvals[i - 1] = bvals[i]; + } + // Add the new values to the end of the array + xvals[width - 1] = mouseX; + yvals[width - 1] = mouseY; + + if (mouseIsPressed) { + bvals[width - 1] = 0; + } else { + bvals[width - 1] = 255; + } + + fill(255); + noStroke(); + rect(0, height / 3, width, height / 3 + 1); + + for (let i = 1; i < width; i++) { + stroke(255); + point(i, xvals[i] / 3); + stroke(0); + point(i, height / 3 + yvals[i] / 3); + stroke(255); + line( + i, + (2 * height) / 3 + bvals[i] / 3, + i, + (2 * height) / 3 + bvals[i - 1] / 3 + ); + } +} diff --git a/dist/assets/examples/zh-Hans/21_Input/09_Storing_Input.js b/dist/assets/examples/zh-Hans/21_Input/09_Storing_Input.js new file mode 100644 index 0000000000..563ff80759 --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/09_Storing_Input.js @@ -0,0 +1,38 @@ +/* + * @name Storing Input + * @description Move the mouse across the screen to + * change the position of the circles. The positions + * of the mouse are recorded into an array and played + * back every frame. Between each frame, the newest + * value are added to the end of each array and the + * oldest value is deleted. + */ +let num = 60; +let mx = []; +let my = []; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255, 153); + for (let i = 0; i < num; i++) { + mx.push(i); + my.push(i); + } +} + +function draw() { + background(237, 34, 93); + + // Cycle through the array, using a different entry on each frame. + // Using modulo (%) like this is faster than moving all the values over. + let which = frameCount % num; + mx[which] = mouseX; + my[which] = mouseY; + + for (let i = 0; i < num; i++) { + // which+1 is the smallest (the oldest in the array) + let index = (which + 1 + i) % num; + ellipse(mx[index], my[index], i, i); + } +} diff --git a/dist/assets/examples/zh-Hans/21_Input/10_Rollover.js b/dist/assets/examples/zh-Hans/21_Input/10_Rollover.js new file mode 100644 index 0000000000..09ebd6648c --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/10_Rollover.js @@ -0,0 +1,79 @@ +/* + * @name Rollover + * @description Roll over the colored squares in the center of the image to change the color of the outside rectangle. + *

This example is ported from the Rollover example + * on the Processing website + */ +let squareX, squareY; // Position of square button +let circleX, circleY; // Position of circle button +let squareSize = 90; // Width/height of square +let circleSize = 93; // Diameter of circle + +let squareColor; +let circleColor; +let baseColor; + +let squareOver = false; +let circleOver = false; + +function setup() { + createCanvas(710, 400); + squareColor = color(0); + circleColor = color(255); + baseColor = color(102); + circleX = width/2+circleSize/2+10; + circleY = height/2; + squareX = width/2-squareSize-10; + squareY = height/2-squareSize/2; +} + +function draw() { + update(mouseX, mouseY); + + noStroke(); + if (squareOver) { + background(squareColor); + } else if (circleOver) { + background(circleColor); + } else { + background(baseColor); + } + + stroke(255); + fill(squareColor); + square(squareX, squareY, squareSize); + stroke(0); + fill(circleColor); + circle(circleX, circleY, circleSize); +} + +function update(x, y) { + if( overCircle(circleX, circleY, circleSize) ) { + circleOver = true; + squareOver = false; + } else if ( overSquare(squareX, squareY, squareSize) ) { + squareOver = true; + circleOver = false; + } else { + circleOver = squareOver = false; + } +} + +function overSquare(x, y, size) { + if (mouseX >= x && mouseX <= x+size && + mouseY >= y && mouseY <= y+size) { + return true; + } else { + return false; + } +} + +function overCircle(x, y, diameter) { + const disX = x - mouseX; + const disY = y - mouseY; + if(sqrt(sq(disX) + sq(disY)) < diameter/2 ) { + return true; + } else { + return false; + } +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/21_Input/11_Storing_Input.js b/dist/assets/examples/zh-Hans/21_Input/11_Storing_Input.js new file mode 100644 index 0000000000..563ff80759 --- /dev/null +++ b/dist/assets/examples/zh-Hans/21_Input/11_Storing_Input.js @@ -0,0 +1,38 @@ +/* + * @name Storing Input + * @description Move the mouse across the screen to + * change the position of the circles. The positions + * of the mouse are recorded into an array and played + * back every frame. Between each frame, the newest + * value are added to the end of each array and the + * oldest value is deleted. + */ +let num = 60; +let mx = []; +let my = []; + +function setup() { + createCanvas(720, 400); + noStroke(); + fill(255, 153); + for (let i = 0; i < num; i++) { + mx.push(i); + my.push(i); + } +} + +function draw() { + background(237, 34, 93); + + // Cycle through the array, using a different entry on each frame. + // Using modulo (%) like this is faster than moving all the values over. + let which = frameCount % num; + mx[which] = mouseX; + my[which] = mouseY; + + for (let i = 0; i < num; i++) { + // which+1 is the smallest (the oldest in the array) + let index = (which + 1 + i) % num; + ellipse(mx[index], my[index], i, i); + } +} diff --git a/dist/assets/examples/zh-Hans/22_Advanced_Data/00_Load_Saved_JSON.js b/dist/assets/examples/zh-Hans/22_Advanced_Data/00_Load_Saved_JSON.js new file mode 100644 index 0000000000..7d3e8f4b66 --- /dev/null +++ b/dist/assets/examples/zh-Hans/22_Advanced_Data/00_Load_Saved_JSON.js @@ -0,0 +1,104 @@ +/* + * @name Load Saved JSON + * @description Create a Bubble class, instantiate multiple bubbles using data from + * a JSON file, and display results on the screen. + * Because the web browsers differ in where they save files, we do not make use of + * saveJSON, unlike the Processing example.

+ * Based on Daniel Shiffman's LoadSaveJSON Example for Processing. + */ + +// Bubble class +class Bubble { + constructor(x, y, diameter, name) { + this.x = x; + this.y = y; + this.diameter = diameter; + this.radius = diameter / 2; + this.name = name; + + this.over = false; + } + + // Check if mouse is over the bubble + rollover(px, py) { + let d = dist(px, py, this.x, this.y); + this.over = d < this.radius; + } + + // Display the Bubble + display() { + stroke(0); + strokeWeight(0.8); + noFill(); + ellipse(this.x, this.y, this.diameter, this.diameter); + if (this.over) { + fill(0); + textAlign(CENTER); + text(this.name, this.x, this.y + this.radius + 20); + } + } +} + +let data = {}; // Global object to hold results from the loadJSON call +let bubbles = []; // Global array to hold all bubble objects + +// Put any asynchronous data loading in preload to complete before "setup" is run +function preload() { + data = loadJSON('assets/bubbles.json'); +} + +// Convert saved Bubble data into Bubble Objects +function loadData() { + let bubbleData = data['bubbles']; + for (let i = 0; i < bubbleData.length; i++) { + // Get each object in the array + let bubble = bubbleData[i]; + // Get a position object + let position = bubble['position']; + // Get x,y from position + let x = position['x']; + let y = position['y']; + + // Get diameter and label + let diameter = bubble['diameter']; + let label = bubble['label']; + + // Put object in array + bubbles.push(new Bubble(x, y, diameter, label)); + } +} + +// Create a new Bubble each time the mouse is clicked. +function mousePressed() { + // Add diameter and label to bubble + let diameter = random(40, 80); + let label = 'New Label'; + + // Append the new JSON bubble object to the array + bubbles.push(new Bubble(mouseX, mouseY, diameter, label)); + + // Prune Bubble Count if there are too many + if (bubbles.length > 10) { + bubbles.shift(); // remove first item from array + } +} + +function setup() { + createCanvas(640, 360); + loadData(); +} + +function draw() { + background(255); + + // Display all bubbles + for (let i = 0; i < bubbles.length; i++) { + bubbles[i].display(); + bubbles[i].rollover(mouseX, mouseY); + } + + // Label directions at bottom + textAlign(LEFT); + fill(0); + text('Click to add bubbles.', 10, height - 10); +} diff --git a/dist/assets/examples/zh-Hans/22_Advanced_Data/01_Load_Saved_Table.js b/dist/assets/examples/zh-Hans/22_Advanced_Data/01_Load_Saved_Table.js new file mode 100644 index 0000000000..8536abcccc --- /dev/null +++ b/dist/assets/examples/zh-Hans/22_Advanced_Data/01_Load_Saved_Table.js @@ -0,0 +1,110 @@ +/* + * @name Load Saved Table + * @description Create a Bubble class, instantiate multiple bubbles using data from + * a csv file, and display results on the screen. + * Because the web browsers differ in where they save files, we do not make use of + * + * Based on Daniel Shiffman's LoadSaveTable Example for Processing. + */ + +// Bubble class +class Bubble { + constructor(x, y, diameter, name) { + this.x = x; + this.y = y; + this.diameter = diameter; + this.radius = diameter / 2; + this.name = name; + + this.over = false; + } + + // Check if mouse is over the bubble + rollover(px, py) { + let d = dist(px, py, this.x, this.y); + this.over = d < this.radius; + } + + // Display the Bubble + display() { + stroke(0); + strokeWeight(0.8); + noFill(); + ellipse(this.x, this.y, this.diameter, this.diameter); + if (this.over) { + fill(0); + textAlign(CENTER); + text(this.name, this.x, this.y + this.radius + 20); + } + } +} + +let table; // Global object to hold results from the loadTable call +let bubbles = []; // Global array to hold all bubble objects + +// Put any asynchronous data loading in preload to complete before "setup" is run +function preload() { + table = loadTable("assets/bubbles.csv", "header"); +} + +// Convert saved Bubble data into Bubble Objects +function loadData() { + const bubbleData = table.getRows(); + // The size of the array of Bubble objects is determined by the total number of rows in the CSV + const length = table.getRowCount(); + + for (let i = 0; i < length; i++) { + // Get position, diameter, name, + const x = bubbleData[i].getNum("x"); + const y = bubbleData[i].getNum("y"); + const diameter = bubbleData[i].getNum("diameter"); + const name = bubbleData[i].getString("name"); + + // Put object in array + bubbles.push(new Bubble(x, y, diameter, name)); + } +} + +// Create a new Bubble each time the mouse is clicked. +function mousePressed() { + // Create a new row + let row = table.addRow(); + + let name = "New Bubble"; + let diameter = random(40, 80); + + // Set the values of that row + row.setNum("x", mouseX); + row.setNum("y", mouseY); + row.setNum("diameter", diameter); + row.setString("name", name); + + bubbles.push(new Bubble(mouseX, mouseY, diameter, name)); + + // If the table has more than 10 rows + if (table.getRowCount() > 10) { + // Delete the oldest row + table.removeRow(0); + bubbles.shift(); + } +} + +function setup() { + createCanvas(640, 360); + loadData(); +} + +function draw() { + background(255); + + // Display all bubbles + for (let i = 0; i < bubbles.length; i++) { + bubbles[i].display(); + bubbles[i].rollover(mouseX, mouseY); + } + + // Label directions at bottom + textAlign(LEFT); + fill(0); + text("Click to add bubbles.", 10, height - 10); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/00_Load_and_Play_Sound.js b/dist/assets/examples/zh-Hans/33_Sound/00_Load_and_Play_Sound.js new file mode 100644 index 0000000000..feffaffdc7 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/00_Load_and_Play_Sound.js @@ -0,0 +1,25 @@ +/* + * @name Load and Play Sound + * @description Load sound during preload(). Play a sound when canvas is clicked. + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server. + */ +let song; + +function setup() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); + createCanvas(720, 200); + background(255, 0, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() returns a boolean + song.stop(); + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/01_Preload_Sound.js b/dist/assets/examples/zh-Hans/33_Sound/01_Preload_Sound.js new file mode 100644 index 0000000000..08c419179e --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/01_Preload_Sound.js @@ -0,0 +1,34 @@ +/* + * @name Preload SoundFile + * @description Call loadSound() during preload() to ensure that the + * sound is completely loaded before setup() is called. It's best to always + * call loadSound() in preload(), otherwise sounds won't necessarily be loaded + * by the time you want to play them in your sketch. + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server. + */ + +let song; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); // song is ready to play during setup() because it was loaded during preload + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() returns a boolean + song.pause(); // .play() will resume from .pause() position + background(255, 0, 0); + } else { + song.play(); + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/02_soundFormats.js b/dist/assets/examples/zh-Hans/33_Sound/02_soundFormats.js new file mode 100644 index 0000000000..ae7571fb01 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/02_soundFormats.js @@ -0,0 +1,54 @@ +/** + * @name soundFormats + * @description

Technically, due to patent issues, there is no single + * sound format that is supported by all web browsers. While + * mp3 is supported across the + * latest versions of major browsers on OS X and Windows, for example, + * it may not be available on some less mainstream operating systems and + * browsers.

+ * + *

To ensure full compatibility, you can include the same sound file + * in multiple formats, e.g. 'sound.mp3' and 'sound.ogg'. (Ogg is an + * open source alternative to mp3.) You can convert audio files + * into web friendly formats for free online at media.io

. + * + *

The soundFormats() method tells loadSound which formats + * we have included with our sketch. Then, loadSound will + * attempt to load the first format that is supported by the + * client's web browser.

+ * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let song; + +function preload() { + // we have included both an .ogg file and an .mp3 file + soundFormats('ogg', 'mp3'); + + // if mp3 is not supported by this browser, + // loadSound will load the ogg file + // we have included with our sketch + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + + // song loaded during preload(), ready to play in setup() + song.play(); + background(0, 255, 0); +} + +function mousePressed() { + if (song.isPlaying()) { + // .isPlaying() returns a boolean + song.pause(); + background(255, 0, 0); + } else { + song.play(); // playback will resume from the pause position + background(0, 255, 0); + } +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/03_Play_Mode.js b/dist/assets/examples/zh-Hans/33_Sound/03_Play_Mode.js new file mode 100644 index 0000000000..3b89691dee --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/03_Play_Mode.js @@ -0,0 +1,42 @@ +/* + * @name Play Mode + * @description + *

In 'sustain' mode, the sound will overlap with itself. + * In 'restart' mode it will stop and then start again. + * Click mouse to play a sound file. + * Trigger lots of sounds at once! Press any key to change playmode.

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let playMode = 'sustain'; +let sample; + +function setup() { + createCanvas(710, 50); + soundFormats('mp3', 'ogg'); + sample = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3'); +} + +function draw() { + background(255, 255, 0); + let str = 'Click here to play! Press key to toggle play mode.'; + str += ' Current Play Mode: ' + playMode + '.'; + text(str, 10, height / 2); +} + +function mouseClicked() { + sample.play(); +} +function keyPressed(k) { + togglePlayMode(); +} + +function togglePlayMode() { + if (playMode === 'sustain') { + playMode = 'restart'; + } else { + playMode = 'sustain'; + } + sample.playMode(playMode); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/04_Pan_SoundFile.js b/dist/assets/examples/zh-Hans/33_Sound/04_Pan_SoundFile.js new file mode 100644 index 0000000000..b1d881db36 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/04_Pan_SoundFile.js @@ -0,0 +1,34 @@ +/* + * @name Pan Sound + * @description

Click mouse to play the sound. + * Ball position follows mouse and correlates to panning of sound.

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ * + */ +let ball = {}; +let soundFile; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beatbox.ogg'); +} + +function setup() { + createCanvas(710, 100); +} + +function draw() { + background(0); + ball.x = constrain(mouseX, 0, width); + ellipse(ball.x, height / 2, 100, 100); +} + +function mousePressed() { + // map the ball's x location to a panning degree + // between -1.0 (left) and 1.0 (right) + let panning = map(ball.x, 0, width, -1.0, 1.0); + soundFile.pan(panning); + soundFile.play(); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/05_Sound_Effect.js b/dist/assets/examples/zh-Hans/33_Sound/05_Sound_Effect.js new file mode 100644 index 0000000000..0839b9d7fb --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/05_Sound_Effect.js @@ -0,0 +1,69 @@ +/* + * @name Sound Effect + * @description

Play a sound effect when the mouse is clicked inside the circle.

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +// Adapted from Learning Processing by Daniel Shiffman +// http://www.learningprocessing.com +// Doorbell sample by Corsica_S via freesound.org, +// Creative Commons BY 3.0 + +// A Class to describe a "doorbell" (really a button) +class Doorbell { + constructor(x_, y_, r_) { + // Location and size + this.x = x_; + this.y = y_; + this.r = r_; + } + // Is a point inside the doorbell? (used for mouse rollover, etc.) + contains(mx, my) { + return dist(mx, my, this.x, this.y) < this.r; + } + + // Show the doorbell (hardcoded colors, could be improved) + display(mx, my) { + if (this.contains(mx, my)) { + fill(100); + } else { + fill(175); + } + stroke(0); + strokeWeight(4); + ellipseMode(RADIUS); + ellipse(this.x, this.y, this.r, this.r); + } +} + +// A sound file object +let dingdong; + +// A doorbell object (that will trigger the sound) +let doorbell; + +function setup() { + createCanvas(200, 200); + + // Load the sound file. + // We have included both an MP3 and an OGG version. + soundFormats('mp3', 'ogg'); + dingdong = loadSound('assets/doorbell.mp3'); + + // Create a new doorbell + doorbell = new Doorbell(width / 2, height / 2, 32); +} + +function draw() { + background(255); + // Show the doorbell + doorbell.display(mouseX, mouseY); +} + +function mousePressed() { + // If the user clicks on the doorbell, play the sound! + if (doorbell.contains(mouseX, mouseY)) { + dingdong.play(); + } +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/06_Manipulate_Sound.js b/dist/assets/examples/zh-Hans/33_Sound/06_Manipulate_Sound.js new file mode 100644 index 0000000000..60ad548038 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/06_Manipulate_Sound.js @@ -0,0 +1,49 @@ +/* + * @name Playback Rate + * @description

Load a SoundFile and map its playback rate to + * mouseY, volume to mouseX. Playback rate is the speed with + * which the web audio context processings the sound file information. + * Slower rates not only increase the duration of the sound, but also + * decrease the pitch because it is being played back at a slower frequency.

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +// A sound file object +let song; + +function preload() { + // Load a sound file + song = loadSound('assets/Damscray_DancingTiger.mp3'); +} + +function setup() { + createCanvas(710, 400); + + // Loop the sound forever + // (well, at least until stop() is called) + song.loop(); +} + +function draw() { + background(200); + + // Set the volume to a range between 0 and 1.0 + let volume = map(mouseX, 0, width, 0, 1); + volume = constrain(volume, 0, 1); + song.amp(volume); + + // Set the rate to a range between 0.1 and 4 + // Changing the rate alters the pitch + let speed = map(mouseY, 0.1, height, 0, 2); + speed = constrain(speed, 0.01, 4); + song.rate(speed); + + // Draw some circles to show what is going on + stroke(0); + fill(51, 100); + ellipse(mouseX, 100, 48, 48); + stroke(0); + fill(51, 100); + ellipse(100, mouseY, 48, 48); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/07_Amplitude_Analysis.js b/dist/assets/examples/zh-Hans/33_Sound/07_Amplitude_Analysis.js new file mode 100644 index 0000000000..7bf3446e4f --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/07_Amplitude_Analysis.js @@ -0,0 +1,50 @@ +/** + * @name Measuring Amplitude + * @description

Analyze the amplitude of sound with + * p5.Amplitude.

+ * + *

Amplitude is the magnitude of vibration. Sound is vibration, + * so its amplitude is is closely related to volume / loudness.

+ * + *

The getLevel() method takes an array + * of amplitude values collected over a small period of time (1024 samples). + * Then it returns the Root Mean Square (RMS) of these values.

+ * + *

The original amplitude values for digital audio are between -1.0 and 1.0. + * But the RMS will always be positive, because it is squared. + * And, rather than use instantanous amplitude readings that are sampled at a rate + * of 44,100 times per second, the RMS is an average over time (1024 samples, in this case), + * which better represents how we hear amplitude. + *

+ *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let song, analyzer; + +function preload() { + song = loadSound('assets/lucky_dragons_-_power_melody.mp3'); +} + +function setup() { + createCanvas(710, 200); + song.loop(); + + // create a new Amplitude analyzer + analyzer = new p5.Amplitude(); + + // Patch the input to an volume analyzer + analyzer.setInput(song); +} + +function draw() { + background(255); + + // Get the average (root mean square) amplitude + let rms = analyzer.getLevel(); + fill(127); + stroke(0); + + // Draw an ellipse with size based on volume + ellipse(width / 2, height / 2, 10 + rms * 200, 10 + rms * 200); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/08_Noise_Envelope.js b/dist/assets/examples/zh-Hans/33_Sound/08_Noise_Envelope.js new file mode 100644 index 0000000000..b38e423c75 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/08_Noise_Envelope.js @@ -0,0 +1,54 @@ +/** + * @name Noise Drum Envelope + * @description

White Noise is a random audio signal with equal energy + * at every part of the frequency spectrum

+ * + *

An Envelope is a series of fades, defined + * as time / value pairs.

+ * + *

In this example, the p5.Env + * will be used to "play" the p5.Noise like a drum by controlling its output + * amplitude. A p5.Amplitude will get the level of all sound in the sketch, and + * we'll use this value to draw a green rectangle that shows the envelope + * in action.

+ *

To run this example locally, you will need the + * p5.sound library and a + * sound file.

+ */ +let noise, env, analyzer; + +function setup() { + createCanvas(710, 200); + noise = new p5.Noise(); // other types include 'brown' and 'pink' + noise.start(); + + // multiply noise volume by 0 + // (keep it quiet until we're ready to make noise!) + noise.amp(0); + + env = new p5.Env(); + // set attackTime, decayTime, sustainRatio, releaseTime + env.setADSR(0.001, 0.1, 0.2, 0.1); + // set attackLevel, releaseLevel + env.setRange(1, 0); + + // p5.Amplitude will analyze all sound in the sketch + // unless the setInput() method is used to specify an input. + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // get volume reading from the p5.Amplitude analyzer + let level = analyzer.getLevel(); + + // use level to draw a green rectangle + let levelHeight = map(level, 0, 0.4, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); +} + +function mousePressed() { + env.play(noise); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/09_Note_Envelope.js b/dist/assets/examples/zh-Hans/33_Sound/09_Note_Envelope.js new file mode 100644 index 0000000000..4b9122d244 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/09_Note_Envelope.js @@ -0,0 +1,61 @@ +/** + * @name Note Envelope + * @description

An Envelope is a series of fades, defined + * as time / value pairs. In this example, the envelope + * will be used to "play" a note by controlling the output + * amplitude of an oscillator.

+ * The p5.Oscillator sends its output through + * an internal Web Audio GainNode (p5.Oscillator.output). + * By default, that node has a constant value of 0.5. It can + * be reset with the osc.amp() method. Or, in this example, an + * Envelope takes control of that node, turning the amplitude + * up and down like a volume knob.

+ *

To run this example locally, you will need the + * p5.sound library and a + * sound file.

+ */ +let osc, envelope, fft; + +let scaleArray = [60, 62, 64, 65, 67, 69, 71, 72]; +let note = 0; + +function setup() { + createCanvas(710, 200); + osc = new p5.SinOsc(); + + // Instantiate the envelope + envelope = new p5.Env(); + + // set attackTime, decayTime, sustainRatio, releaseTime + envelope.setADSR(0.001, 0.5, 0.1, 0.5); + + // set attackLevel, releaseLevel + envelope.setRange(1, 0); + + osc.start(); + + fft = new p5.FFT(); + noStroke(); +} + +function draw() { + background(20); + + if (frameCount % 60 === 0 || frameCount === 1) { + let midiValue = scaleArray[note]; + let freqValue = midiToFreq(midiValue); + osc.freq(freqValue); + + envelope.play(osc, 0, 0.1); + note = (note + 1) % scaleArray.length; + } + + // plot FFT.analyze() frequency analysis on the canvas + let spectrum = fft.analyze(); + for (let i = 0; i < spectrum.length / 20; i++) { + fill(spectrum[i], spectrum[i] / 10, 0); + let x = map(i, 0, spectrum.length / 20, 0, width); + let h = map(spectrum[i], 0, 255, 0, height); + rect(x, height, spectrum.length / 20, -h); + } +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/10_Oscillator_Waveform.js b/dist/assets/examples/zh-Hans/33_Sound/10_Oscillator_Waveform.js new file mode 100644 index 0000000000..4737680b81 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/10_Oscillator_Waveform.js @@ -0,0 +1,40 @@ +/* + * @name Oscillator Frequency + * @description

Control an Oscillator and view the waveform using FFT. + * MouseX is mapped to frequency, mouseY is mapped to amplitude.

+ *

To run this example locally, you will need the + * p5.sound library and a + * sound file.

+ */ +let osc, fft; + +function setup() { + createCanvas(720, 256); + + osc = new p5.TriOsc(); // set frequency and type + osc.amp(0.5); + + fft = new p5.FFT(); + osc.start(); +} + +function draw() { + background(255); + + let waveform = fft.waveform(); // analyze the waveform + beginShape(); + strokeWeight(5); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, height, 0); + vertex(x, y); + } + endShape(); + + // change oscillator frequency based on mouseX + let freq = map(mouseX, 0, width, 40, 880); + osc.freq(freq); + + let amp = map(mouseY, 0, height, 1, 0.01); + osc.amp(amp); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/11_Live_Input.js b/dist/assets/examples/zh-Hans/33_Sound/11_Live_Input.js new file mode 100644 index 0000000000..30136d62a0 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/11_Live_Input.js @@ -0,0 +1,36 @@ +/** + * @name Mic Input + * @description

Get audio input from your computer's microphone. + * Make noise to float the ellipse.

+ *

Note: p5.AudioIn contains its own p5.Amplitude object, + * so you can call getLevel on p5.AudioIn without + * creating a p5.Amplitude.

+ *

To run this example locally, you will need the + * p5.sound library + * and a running local server.

+ */ +let mic; + +function setup() { + createCanvas(710, 200); + + // Create an Audio input + mic = new p5.AudioIn(); + + // start the Audio Input. + // By default, it does not .connect() (to the computer speakers) + mic.start(); +} + +function draw() { + background(200); + + // Get the overall volume (between 0 and 1.0) + let vol = mic.getLevel(); + fill(127); + stroke(0); + + // Draw an ellipse with height based on volume + let h = map(vol, 0, 1, height, 0); + ellipse(width / 2, h - 25, 50, 50); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/12_FFT_Spectrum.js b/dist/assets/examples/zh-Hans/33_Sound/12_FFT_Spectrum.js new file mode 100644 index 0000000000..9bc8dedfd7 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/12_FFT_Spectrum.js @@ -0,0 +1,30 @@ +/** + * @name Frequency Spectrum + * @description

Visualize the frequency spectrum of live audio input.

+ *

To run this example locally, you will need the + * p5.sound library + * and a running local server.

+ */ +let mic, fft; + +function setup() { + createCanvas(710, 400); + noFill(); + + mic = new p5.AudioIn(); + mic.start(); + fft = new p5.FFT(); + fft.setInput(mic); +} + +function draw() { + background(200); + + let spectrum = fft.analyze(); + + beginShape(); + for (i = 0; i < spectrum.length; i++) { + vertex(i, map(spectrum[i], 0, 255, height, 0)); + } + endShape(); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/13_Mic_Threshold.js b/dist/assets/examples/zh-Hans/33_Sound/13_Mic_Threshold.js new file mode 100644 index 0000000000..4c765b059d --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/13_Mic_Threshold.js @@ -0,0 +1,49 @@ +/** + * @name Mic Threshold + * @description

Trigger an event (draw a rectangle) when the Audio Input + * volume surpasses a threshold.

+ *

To run this example locally, you will need the + * p5.sound library + * and a running local server.

+ */ +// Adapted from Learning Processing, Daniel Shiffman +// learningprocessing.com +let input; +let analyzer; + +function setup() { + createCanvas(710, 200); + background(255); + + // Create an Audio input + input = new p5.AudioIn(); + + input.start(); +} + +function draw() { + // Get the overall volume (between 0 and 1.0) + let volume = input.getLevel(); + + // If the volume > 0.1, a rect is drawn at a random location. + // The louder the volume, the larger the rectangle. + let threshold = 0.1; + if (volume > threshold) { + stroke(0); + fill(0, 100); + rect(random(40, width), random(height), volume * 50, volume * 50); + } + + // Graph the overall potential volume, w/ a line at the threshold + let y = map(volume, 0, 1, height, 0); + let ythreshold = map(threshold, 0, 1, height, 0); + + noStroke(); + fill(175); + rect(0, 0, 20, height); + // Then draw a rectangle on the graph, sized according to volume + fill(0); + rect(0, y, 20, y); + stroke(0); + line(0, ythreshold, 19, ythreshold); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/14_Filter_LowPass.js b/dist/assets/examples/zh-Hans/33_Sound/14_Filter_LowPass.js new file mode 100644 index 0000000000..d1337ed63e --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/14_Filter_LowPass.js @@ -0,0 +1,62 @@ +/** + * @name Filter LowPass + * @description Apply a p5.LowPass filter to a p5.SoundFile. + * Visualize the sound with FFT. + * Map mouseX to the the filter's cutoff frequency + * and mouseY to resonance/width of the a BandPass filter + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let soundFile; +let fft; + +let filter, filterFreq, filterRes; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/beat'); +} + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + // loop the sound file + soundFile.loop(); + + filter = new p5.LowPass(); + + // Disconnect soundfile from master output. + // Then, connect it to the filter, so that we only hear the filtered sound + soundFile.disconnect(); + soundFile.connect(filter); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // Map mouseX to a the cutoff frequency from the lowest + // frequency (10Hz) to the highest (22050Hz) that humans can hear + filterFreq = map(mouseX, 0, width, 10, 22050); + + // Map mouseY to resonance (volume boost) at the cutoff frequency + filterRes = map(mouseY, 0, height, 15, 5); + + // set filter parameters + filter.set(filterFreq, filterRes); + + // Draw every value in the FFT spectrum analysis where + // x = lowest (10Hz) to highest (22050Hz) frequencies, + // h = energy (amplitude / volume) at that frequency + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/15_Filter_BandPass.js b/dist/assets/examples/zh-Hans/33_Sound/15_Filter_BandPass.js new file mode 100644 index 0000000000..5e128fcec1 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/15_Filter_BandPass.js @@ -0,0 +1,51 @@ +/** + * @name Filter BandPass + * @description Apply a p5.BandPass filter to white noise. + * Visualize the sound with FFT. + * Map mouseX to the bandpass frequency + * and mouseY to resonance/width of the a BandPass filter + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let noise; +let fft; +let filter, filterFreq, filterWidth; + +function setup() { + createCanvas(710, 256); + fill(255, 40, 255); + + filter = new p5.BandPass(); + + noise = new p5.Noise(); + + noise.disconnect(); // Disconnect soundfile from master output... + filter.process(noise); // ...and connect to filter so we'll only hear BandPass. + noise.start(); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + + // Map mouseX to a bandpass freq from the FFT spectrum range: 10Hz - 22050Hz + filterFreq = map(mouseX, 0, width, 10, 22050); + // Map mouseY to resonance/width + filterWidth = map(mouseY, 0, height, 0, 90); + // set filter parameters + filter.set(filterFreq, filterWidth); + + // Draw every value in the FFT spectrum analysis where + // x = lowest (10Hz) to highest (22050Hz) frequencies, + // h = energy / amplitude at that frequency + let spectrum = fft.analyze(); + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/16_Delay.js b/dist/assets/examples/zh-Hans/33_Sound/16_Delay.js new file mode 100644 index 0000000000..0027b42f73 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/16_Delay.js @@ -0,0 +1,56 @@ +/** + * @name Delay + * @description + * Click the mouse to hear the p5.Delay process a SoundFile. + * MouseX controls the p5.Delay Filter Frequency. + * MouseY controls both the p5.Delay Time and Resonance. + * Visualize the resulting sound's volume with an Amplitude object. + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ + +let soundFile, analyzer, delay; + +function preload() { + soundFormats('ogg', 'mp3'); + soundFile = loadSound('assets/beatbox.mp3'); +} + +function setup() { + createCanvas(710, 400); + + soundFile.disconnect(); // so we'll only hear delay + + delay = new p5.Delay(); + delay.process(soundFile, 0.12, 0.7, 2300); + delay.setType('pingPong'); // a stereo effect + + analyzer = new p5.Amplitude(); +} + +function draw() { + background(0); + + // get volume reading from the p5.Amplitude analyzer + let level = analyzer.getLevel(); + + // use level to draw a green rectangle + let levelHeight = map(level, 0, 0.1, 0, height); + fill(100, 250, 100); + rect(0, height, width, -levelHeight); + + let filterFreq = map(mouseX, 0, width, 60, 15000); + filterFreq = constrain(filterFreq, 60, 15000); + let filterRes = map(mouseY, 0, height, 3, 0.01); + filterRes = constrain(filterRes, 0.01, 3); + delay.filter(filterFreq, filterRes); + let delTime = map(mouseY, 0, width, 0.2, 0.01); + delTime = constrain(delTime, 0.01, 0.2); + delay.delayTime(delTime); +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/17_Reverb.js b/dist/assets/examples/zh-Hans/33_Sound/17_Reverb.js new file mode 100644 index 0000000000..db99aa3ed1 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/17_Reverb.js @@ -0,0 +1,36 @@ +/** + * @name Reverb + * @description Reverb gives depth and perceived space to a sound. Here, + * noise is processed with reverb. + * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let sound, reverb; + +function preload() { + soundFormats('mp3', 'ogg'); + soundFile = loadSound('assets/Damscray_DancingTiger'); + + // disconnect the default connection + // so that we only hear the sound via the reverb.process + soundFile.disconnect(); +} + +function setup() { + createCanvas(720, 100); + background(0); + + reverb = new p5.Reverb(); + + // sonnects soundFile to reverb with a + // reverbTime of 6 seconds, decayRate of 0.2% + reverb.process(soundFile, 6, 0.2); + + reverb.amp(4); // turn it up! +} + +function mousePressed() { + soundFile.play(); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/18_Convolution_Reverb.js b/dist/assets/examples/zh-Hans/33_Sound/18_Convolution_Reverb.js new file mode 100644 index 0000000000..bfcfecb57e --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/18_Convolution_Reverb.js @@ -0,0 +1,87 @@ +/** + * @name Convolution Reverb + * @description

The p5.Convolver can recreate the sound of actual + * spaces using convolution. Convolution takes an Impulse Response, + * (the sound of a room reverberating), and uses that to + * recreate the sound of that space.

Click to play a sound through + * convolution. Every time you click, the sound is convolved with + * a different Impulse Response. To hear the Impulse Response itself, + * press any key.

+ * + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server. + * These convolution samples are Creative Commons BY + * + * recordinghopkins

+ */ +let sound, env, cVerb, fft; +let currentIR = 0; +let rawImpulse; + +function preload() { + // we have included both MP3 and OGG versions of all the impulses/sounds + soundFormats('ogg', 'mp3'); + + // create a p5.Convolver + cVerb = createConvolver('assets/bx-spring'); + + // add Impulse Responses to cVerb.impulses array, in addition to bx-spring + cVerb.addImpulse('assets/small-plate'); + cVerb.addImpulse('assets/drum'); + cVerb.addImpulse('assets/beatbox'); + cVerb.addImpulse('assets/concrete-tunnel'); + + // load a sound that will be processed by the p5.ConvultionReverb + sound = loadSound('assets/Damscray_DancingTiger'); +} + +function setup() { + createCanvas(710, 400); + rawImpulse = loadSound('assets/' + cVerb.impulses[currentIR].name); + + // disconnect from master output... + sound.disconnect(); + // ... and process with cVerb + // so that we only hear the reverb + cVerb.process(sound); + + fft = new p5.FFT(); +} + +function draw() { + background(30); + fill(0, 255, 40); + + let spectrum = fft.analyze(); + + // Draw every value in the frequencySpectrum array as a rectangle + noStroke(); + for (let i = 0; i < spectrum.length; i++) { + let x = map(i, 0, spectrum.length, 0, width); + let h = -height + map(spectrum[i], 0, 255, height, 0); + rect(x, height, width / spectrum.length, h); + } +} + +function mousePressed() { + // cycle through the array of cVerb.impulses + currentIR++; + if (currentIR >= cVerb.impulses.length) { + currentIR = 0; + } + cVerb.toggleImpulse(currentIR); + + // play the sound through the impulse + sound.play(); + + // display the current Impulse Response name (the filepath) + println('Convolution Impulse Response: ' + cVerb.impulses[currentIR].name); + + rawImpulse.setPath('assets/' + cVerb.impulses[currentIR].name); +} + +// play the impulse (without convolution) +function keyPressed() { + rawImpulse.play(); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/19_Record_Save.js b/dist/assets/examples/zh-Hans/33_Sound/19_Record_Save.js new file mode 100644 index 0000000000..b44b7379a8 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/19_Record_Save.js @@ -0,0 +1,58 @@ +/** + * @name Record Save Audio + * @description Record a sound, play it back and save + * it as a .wav file to the client's computer. + * We need three objects: a p5.AudioIn (mic / sound source), + * p5.SoundRecorder (records the sound), and a + * p5.SoundFile (play back / save). + *

To run this example locally, you will need the + * p5.sound library + * a sound file, and a running local server.

+ */ +let mic, recorder, soundFile; + +let state = 0; // mousePress will increment from Record, to Stop, to Play + +function setup() { + createCanvas(400, 400); + background(200); + fill(0); + text('Enable mic and click the mouse to begin recording', 20, 20); + + // create an audio in + mic = new p5.AudioIn(); + + // users must manually enable their browser microphone for recording to work properly! + mic.start(); + + // create a sound recorder + recorder = new p5.SoundRecorder(); + + // connect the mic to the recorder + recorder.setInput(mic); + + // create an empty sound file that we will use to playback the recording + soundFile = new p5.SoundFile(); +} + +function mousePressed() { + // use the '.enabled' boolean to make sure user enabled the mic (otherwise we'd record silence) + if (state === 0 && mic.enabled) { + // Tell recorder to record to a p5.SoundFile which we will use for playback + recorder.record(soundFile); + + background(255, 0, 0); + text('Recording now! Click to stop.', 20, 20); + state++; + } else if (state === 1) { + recorder.stop(); // stop recorder, and send the result to soundFile + + background(0, 255, 0); + text('Recording stopped. Click to play & save', 20, 20); + state++; + } else if (state === 2) { + soundFile.play(); // play the result! + saveSound(soundFile, 'mySound.wav'); // save file + state++; + } +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/21_FreqModulation.js b/dist/assets/examples/zh-Hans/33_Sound/21_FreqModulation.js new file mode 100644 index 0000000000..ab51e8bc61 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/21_FreqModulation.js @@ -0,0 +1,148 @@ +/** + * @name Frequency Modulation + * @description

Frequency Modulation is a powerful form of synthesis. + * In its simplest form, FM involves two oscillators, referred + * to as the carrier and the modulator. As the modulator's waveform oscillates + * between some minimum and maximum amplitude value, that momentary value + * is added to ("modulates") the frequency of the carrier.

+ *

The carrier is typically set to oscillate at an audible frequency + * that we perceive as a pitch—in this case, it is a sine wave oscilaltor at 220Hz, + * equivalent to an "A3" note. The carrier is connected to master output by default + * (this is the case for all p5.Oscillators).

+ *

We will disconnect the modulator from master output, + * and instead connect to the frequency of the carrier: + * carrier.freq(modulator). This adds the output amplitude of the + * modulator to the frequency of the carrier.

+ *

+ * Modulation Depth describes how much the carrier frequency will modulate. + * It is based on the amplitude of the modulator. + * The modulator produces a continuous stream of amplitude values that we will add + * to the carrier frequency. An amplitude of zero means silence, so the modulation will + * have no effect. An amplitude of 1.0 scales the range of output values + * between +1.0 and -1.0. That is the standard range for sound that gets sent to + * your speakers, but in FM we are instead sending the modulator's output to the carrier frequency, + * where we'd barely notice the +1Hz / -1Hz modulation. + * So we will typically increase the amplitude ("depth") of the modulator to numbers much higher than what + * we might send to our speakers.

+ *

Modulation Frequency is the speed of modulation. When the modulation frequency is lower + * than 20Hz, we stop hearing its frequency as pitch, and start to hear it as a beating rhythm. + * For example, try 7.5Hz at a depth of 20 to mimic the "vibrato" effect of an operatic vocalist. + * The term for this is Low Frequency Oscillator, or LFO. Modulators set to higher frequencies can + * also produce interesting effects, especially when the frequency has a harmonic relationship + * to the carrier signal. For example, listen to what happens when the modulator's frequency is + * half or twice that of the carrier. This is the basis for FM Synthesis, developed by John Chowning + * in the 1960s, which came to revolutionize synthesis in the 1980s and is often used to synthesize + * brass and bell-like sounds. + * + *

In this example,

+ * - MouseX controls the modulation depth (the amplitude of the modulator) from -150 to 150. + * When the modulator's amplitude is set to 0 (in the middle), notice how the modulation + * has no effect. The greater (the absolute value of) the number, the greater the effect. + * If the modulator waveform is symetrical like a square [], sine ~ + * or triangle /\, the negative amplitude will be the same as positive amplitude. + * But in this example, the modulator is an asymetrical sawtooth wave, shaped like this /. + * When we multiply it by a negative number, it goes backwards like this \. To best + * observe the difference, try lowering the frequency. + *

+ *

- MouseY controls the frequency of the modulator from 0 to 112 Hz. + * Try comparing modulation frequencies below the audible range (which starts around 20hz), + * and above it, especially in a harmonic relationship to the carrier frequency (which is 220hz, so + * try half that, 1/3, 1/4 etc...). + * + *

You will need to include the + * p5.sound library + * for this example to work in your own project.

+ */ + +let carrier; // this is the oscillator we will hear +let modulator; // this oscillator will modulate the frequency of the carrier + +let analyzer; // we'll use this visualize the waveform + +// the carrier frequency pre-modulation +let carrierBaseFreq = 220; + +// min/max ranges for modulator +let modMaxFreq = 112; +let modMinFreq = 0; +let modMaxDepth = 150; +let modMinDepth = -150; + +function setup() { + let cnv = createCanvas(800, 400); + noFill(); + + carrier = new p5.Oscillator('sine'); + carrier.amp(0); // set amplitude + carrier.freq(carrierBaseFreq); // set frequency + carrier.start(); // start oscillating + + // try changing the type to 'square', 'sine' or 'triangle' + modulator = new p5.Oscillator('sawtooth'); + modulator.start(); + + // add the modulator's output to modulate the carrier's frequency + modulator.disconnect(); + carrier.freq(modulator); + + // create an FFT to analyze the audio + analyzer = new p5.FFT(); + + // fade carrier in/out on mouseover / touch start + toggleAudio(cnv); +} + +function draw() { + background(30); + + // map mouseY to modulator freq between a maximum and minimum frequency + let modFreq = map(mouseY, height, 0, modMinFreq, modMaxFreq); + modulator.freq(modFreq); + + // change the amplitude of the modulator + // negative amp reverses the sawtooth waveform, and sounds percussive + // + let modDepth = map(mouseX, 0, width, modMinDepth, modMaxDepth); + modulator.amp(modDepth); + + // analyze the waveform + waveform = analyzer.waveform(); + + // draw the shape of the waveform + stroke(255); + strokeWeight(10); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); + + strokeWeight(1); + // add a note about what's happening + text('Modulator Frequency: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text( + 'Modulator Amplitude (Modulation Depth): ' + modDepth.toFixed(3), + 20, + 40 + ); + text( + 'Carrier Frequency (pre-modulation): ' + carrierBaseFreq + ' Hz', + width / 2, + 20 + ); +} + +// helper function to toggle sound +function toggleAudio(cnv) { + cnv.mouseOver(function() { + carrier.amp(1.0, 0.01); + }); + cnv.touchStarted(function() { + carrier.amp(1.0, 0.01); + }); + cnv.mouseOut(function() { + carrier.amp(0.0, 1.0); + }); +} diff --git a/dist/assets/examples/zh-Hans/33_Sound/22_AmplitudeModulation.js b/dist/assets/examples/zh-Hans/33_Sound/22_AmplitudeModulation.js new file mode 100644 index 0000000000..bc77cbd091 --- /dev/null +++ b/dist/assets/examples/zh-Hans/33_Sound/22_AmplitudeModulation.js @@ -0,0 +1,95 @@ +/** + * @name Amplitude Modulation + * @description

Amplitude Modulation involves two oscillators, referred + * to as the carrier and the modulator, where the modulator controls + * the carrier's amplitude.

+ * + *

The carrier is typically set at an audible frequency (i.e. 440 Hz) + * and connected to master output by default. The carrier.amp is + * set to zero because we will have the modulator control its amplitude.

+ * + *

The modulator is disconnected from master output. Instead, it is connected + * to the amplitude of the Carrier, like this: carrier.amp(modulator).

+ * + *

In this example...

+ *

- MouseX controls the amplitude of the modulator + * from 0 to 1. When the modulator's amplitude is set to 0, the + * amplitude modulation has no effect.

+ * + *

- MouseY controls the frequency of the modulator from 0 to 20hz. + * This range is lower frequencies than humans can hear, and we perceive the + * modulation as a rhythm. This range can simulate effects such as Tremolo. + * Ring Modulation is a type of Amplitude Modulation where the original + * carrier signal is not present, and often involves modulation at a faster + * frequency.

+ * + *

You will need to include the + * p5.sound library + * for this example to work in your own project.

+ */ +let carrier; // this is the oscillator we will hear +let modulator; // this oscillator will modulate the amplitude of the carrier +let fft; // we'll visualize the waveform + +function setup() { + createCanvas(800, 400); + noFill(); + background(30); // alpha + + carrier = new p5.Oscillator(); // connects to master output by default + carrier.freq(340); + carrier.amp(0); + // carrier's amp is 0 by default, giving our modulator total control + + carrier.start(); + + modulator = new p5.Oscillator('triangle'); + modulator.disconnect(); // disconnect the modulator from master output + modulator.freq(5); + modulator.amp(1); + modulator.start(); + + // Modulate the carrier's amplitude with the modulator + // Optionally, we can scale the signal. + carrier.amp(modulator.scale(-1, 1, 1, -1)); + + // create an fft to analyze the audio + fft = new p5.FFT(); +} + +function draw() { + background(30, 30, 30, 100); // alpha + + // map mouseY to moodulator freq between 0 and 20hz + let modFreq = map(mouseY, 0, height, 20, 0); + modulator.freq(modFreq); + + let modAmp = map(mouseX, 0, width, 0, 1); + modulator.amp(modAmp, 0.01); // fade time of 0.1 for smooth fading + + // analyze the waveform + waveform = fft.waveform(); + + // draw the shape of the waveform + drawWaveform(); + + drawText(modFreq, modAmp); +} + +function drawWaveform() { + stroke(240); + strokeWeight(4); + beginShape(); + for (let i = 0; i < waveform.length; i++) { + let x = map(i, 0, waveform.length, 0, width); + let y = map(waveform[i], -1, 1, -height / 2, height / 2); + vertex(x, y + height / 2); + } + endShape(); +} + +function drawText(modFreq, modAmp) { + strokeWeight(1); + text('Modulator Frequency: ' + modFreq.toFixed(3) + ' Hz', 20, 20); + text('Modulator Amplitude: ' + modAmp.toFixed(3), 20, 40); +} diff --git a/dist/assets/examples/zh-Hans/35_Mobile/00_Acceleration_Ball_Bounce.js b/dist/assets/examples/zh-Hans/35_Mobile/00_Acceleration_Ball_Bounce.js new file mode 100644 index 0000000000..0942148573 --- /dev/null +++ b/dist/assets/examples/zh-Hans/35_Mobile/00_Acceleration_Ball_Bounce.js @@ -0,0 +1,58 @@ +/* + * @name Acceleration Ball Bounce + * @description Move an ellipse around based on accelerationX and accelerationY values, and bounces when touch the edge of the canvas. + */ + +// Position Variables +let x = 0; +let y = 0; + +// Speed - Velocity +let vx = 0; +let vy = 0; + +// Acceleration +let ax = 0; +let ay = 0; + +let vMultiplier = 0.007; +let bMultiplier = 0.6; + +function setup() { + createCanvas(displayWidth, displayHeight); + fill(0); +} + +function draw() { + background(255); + ballMove(); + ellipse(x, y, 30, 30); +} + +function ballMove() { + ax = accelerationX; + ay = accelerationY; + + vx = vx + ay; + vy = vy + ax; + y = y + vy * vMultiplier; + x = x + vx * vMultiplier; + + // Bounce when touch the edge of the canvas + if (x < 0) { + x = 0; + vx = -vx * bMultiplier; + } + if (y < 0) { + y = 0; + vy = -vy * bMultiplier; + } + if (x > width - 20) { + x = width - 20; + vx = -vx * bMultiplier; + } + if (y > height - 20) { + y = height - 20; + vy = -vy * bMultiplier; + } +} diff --git a/dist/assets/examples/zh-Hans/35_Mobile/01_Simple_Draw.js b/dist/assets/examples/zh-Hans/35_Mobile/01_Simple_Draw.js new file mode 100644 index 0000000000..80cddb8562 --- /dev/null +++ b/dist/assets/examples/zh-Hans/35_Mobile/01_Simple_Draw.js @@ -0,0 +1,15 @@ +/* + * @name Simple Draw + * @description Touch to draw on the screen using mouseX, mouseY, pmouseX, and pmouseY values. + */ + +function setup() { + createCanvas(displayWidth, displayHeight); + strokeWeight(10); + stroke(0); +} + +function touchMoved() { + line(mouseX, mouseY, pmouseX, pmouseY); + return false; +} diff --git a/dist/assets/examples/zh-Hans/35_Mobile/02_Acceleration_Color.js b/dist/assets/examples/zh-Hans/35_Mobile/02_Acceleration_Color.js new file mode 100644 index 0000000000..a7183d1def --- /dev/null +++ b/dist/assets/examples/zh-Hans/35_Mobile/02_Acceleration_Color.js @@ -0,0 +1,24 @@ +/* + * @name Acceleration Color + * @description Use deviceMoved() to detect when the device is rotated. The background RGB color values are mapped to accelerationX, accelerationY, and accelerationZ values. + */ + +let r, g, b; + +function setup() { + createCanvas(displayWidth, displayHeight); + r = random(50, 255); + g = random(0, 200); + b = random(50, 255); +} + +function draw() { + background(r, g, b); + console.log('draw'); +} + +function deviceMoved() { + r = map(accelerationX, -90, 90, 100, 175); + g = map(accelerationY, -90, 90, 100, 200); + b = map(accelerationZ, -90, 90, 100, 200); +} diff --git a/dist/assets/examples/zh-Hans/35_Mobile/03_Shake_Ball_Bounce.js b/dist/assets/examples/zh-Hans/35_Mobile/03_Shake_Ball_Bounce.js new file mode 100644 index 0000000000..5d2880dbe7 --- /dev/null +++ b/dist/assets/examples/zh-Hans/35_Mobile/03_Shake_Ball_Bounce.js @@ -0,0 +1,114 @@ +/* + * @name Shake Ball Bounce + * @description Create a Ball class, instantiate multiple objects, move it around the screen, and bounce when touch the edge of the canvas. + * Detect shake event based on total change in accelerationX and accelerationY and speed up or slow down objects based on detection. + */ + +let balls = []; + +let threshold = 30; +let accChangeX = 0; +let accChangeY = 0; +let accChangeT = 0; + +function setup() { + createCanvas(displayWidth, displayHeight); + + for (let i = 0; i < 20; i++) { + balls.push(new Ball()); + } +} + +function draw() { + background(0); + + for (let i = 0; i < balls.length; i++) { + balls[i].move(); + balls[i].display(); + } + + checkForShake(); +} + +function checkForShake() { + // Calculate total change in accelerationX and accelerationY + accChangeX = abs(accelerationX - pAccelerationX); + accChangeY = abs(accelerationY - pAccelerationY); + accChangeT = accChangeX + accChangeY; + // If shake + if (accChangeT >= threshold) { + for (let i = 0; i < balls.length; i++) { + balls[i].shake(); + balls[i].turn(); + } + } + // If not shake + else { + for (let i = 0; i < balls.length; i++) { + balls[i].stopShake(); + balls[i].turn(); + balls[i].move(); + } + } +} + +// Ball class +class Ball { + constructor() { + this.x = random(width); + this.y = random(height); + this.diameter = random(10, 30); + this.xspeed = random(-2, 2); + this.yspeed = random(-2, 2); + this.oxspeed = this.xspeed; + this.oyspeed = this.yspeed; + this.direction = 0.7; + } + + move() { + this.x += this.xspeed * this.direction; + this.y += this.yspeed * this.direction; + } + + // Bounce when touch the edge of the canvas + turn() { + if (this.x < 0) { + this.x = 0; + this.direction = -this.direction; + } else if (this.y < 0) { + this.y = 0; + this.direction = -this.direction; + } else if (this.x > width - 20) { + this.x = width - 20; + this.direction = -this.direction; + } else if (this.y > height - 20) { + this.y = height - 20; + this.direction = -this.direction; + } + } + + // Add to xspeed and yspeed based on + // the change in accelerationX value + shake() { + this.xspeed += random(5, accChangeX / 3); + this.yspeed += random(5, accChangeX / 3); + } + + // Gradually slows down + stopShake() { + if (this.xspeed > this.oxspeed) { + this.xspeed -= 0.6; + } else { + this.xspeed = this.oxspeed; + } + if (this.yspeed > this.oyspeed) { + this.yspeed -= 0.6; + } else { + this.yspeed = this.oyspeed; + } + } + + display() { + ellipse(this.x, this.y, this.diameter, this.diameter); + } +} diff --git a/dist/assets/examples/zh-Hans/35_Mobile/04_Tilted_3D_Box.js b/dist/assets/examples/zh-Hans/35_Mobile/04_Tilted_3D_Box.js new file mode 100644 index 0000000000..ea39b5414f --- /dev/null +++ b/dist/assets/examples/zh-Hans/35_Mobile/04_Tilted_3D_Box.js @@ -0,0 +1,15 @@ +/* + * @name Tilted 3D Box + * @description Use mobile to tilt a box + */ +function setup() { + createCanvas(displayWidth, displayHeight, WEBGL); +} + +function draw() { + background(250); + normalMaterial(); + rotateX(accelerationX * 0.01); + rotateY(accelerationY * 0.01); + box(100, 100, 100); +} diff --git a/dist/assets/examples/zh-Hans/90_Hello_P5/01_shapes.js b/dist/assets/examples/zh-Hans/90_Hello_P5/01_shapes.js new file mode 100644 index 0000000000..5196abef4a --- /dev/null +++ b/dist/assets/examples/zh-Hans/90_Hello_P5/01_shapes.js @@ -0,0 +1,28 @@ +/* + * @name Simple Shapes + * @description This examples includes a circle, square, triangle, and a flower. + */ +function setup() { + // Create the canvas + createCanvas(720, 400); + background(200); + + // Set colors + fill(204, 101, 192, 127); + stroke(127, 63, 120); + + // A rectangle + rect(40, 120, 120, 40); + // An ellipse + ellipse(240, 240, 80, 80); + // A triangle + triangle(300, 100, 320, 100, 310, 80); + + // A design for a simple flower + translate(580, 200); + noStroke(); + for (let i = 0; i < 10; i ++) { + ellipse(0, 30, 20, 80); + rotate(PI/5); + } +} diff --git a/dist/assets/examples/zh-Hans/90_Hello_P5/02_interactivity.js b/dist/assets/examples/zh-Hans/90_Hello_P5/02_interactivity.js new file mode 100644 index 0000000000..5bc6687440 --- /dev/null +++ b/dist/assets/examples/zh-Hans/90_Hello_P5/02_interactivity.js @@ -0,0 +1,37 @@ +/* + * @name Interactivity 1 + * @frame 720,425 + * @description The circle changes color when you click on it. + */ + +// for red, green, and blue color values +let r, g, b; + +function setup() { + createCanvas(720, 400); + // Pick colors randomly + r = random(255); + g = random(255); + b = random(255); +} + +function draw() { + background(127); + // Draw a circle + strokeWeight(2); + stroke(r, g, b); + fill(r, g, b, 127); + ellipse(360, 200, 200, 200); +} + +// When the user clicks the mouse +function mousePressed() { + // Check if mouse is inside the circle + let d = dist(mouseX, mouseY, 360, 200); + if (d < 100) { + // Pick new random color values + r = random(255); + g = random(255); + b = random(255); + } +} diff --git a/dist/assets/examples/zh-Hans/90_Hello_P5/03_interactivity.js b/dist/assets/examples/zh-Hans/90_Hello_P5/03_interactivity.js new file mode 100644 index 0000000000..6ab965cbe9 --- /dev/null +++ b/dist/assets/examples/zh-Hans/90_Hello_P5/03_interactivity.js @@ -0,0 +1,26 @@ +/* + * @name Interactivity 2 + * @frame 720,425 + * @description The circle changes color when you move the slider. + */ + +// A HTML range slider +let slider; + +function setup() { + createCanvas(720, 400); + // hue, saturation, and brightness + colorMode(HSB, 255); + // slider has a range between 0 and 255 with a starting value of 127 + slider = createSlider(0, 255, 127); +} + +function draw() { + background(127); + strokeWeight(2); + + // Set the hue according to the slider + stroke(slider.value(), 255, 255); + fill(slider.value(), 255, 255, 127); + ellipse(360, 200, 200, 200); +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/90_Hello_P5/04_animate.js b/dist/assets/examples/zh-Hans/90_Hello_P5/04_animate.js new file mode 100644 index 0000000000..7c87da3a24 --- /dev/null +++ b/dist/assets/examples/zh-Hans/90_Hello_P5/04_animate.js @@ -0,0 +1,33 @@ +/* + * @name Animation + * @description The circle moves. + */ +// Where is the circle +let x, y; + +function setup() { + createCanvas(720, 400); + // Starts in the middle + x = width / 2; + y = height; +} + +function draw() { + background(200); + + // Draw a circle + stroke(50); + fill(100); + ellipse(x, y, 24, 24); + + // Jiggling randomly on the horizontal axis + x = x + random(-1, 1); + // Moving up at a constant speed + y = y - 1; + + // Reset to the bottom + if (y < 0) { + y = height; + } +} + diff --git a/dist/assets/examples/zh-Hans/90_Hello_P5/04_flocking.js b/dist/assets/examples/zh-Hans/90_Hello_P5/04_flocking.js new file mode 100644 index 0000000000..e4d5806a97 --- /dev/null +++ b/dist/assets/examples/zh-Hans/90_Hello_P5/04_flocking.js @@ -0,0 +1,188 @@ +/* + * @name Flocking + * @description Demonstration of Craig Reynolds' "Flocking" behavior.
+ * (Rules: Cohesion, Separation, Alignment.)
+ * From natureofcode.com. + */ +let boids = []; + +function setup() { + createCanvas(720, 400); + + // Add an initial set of boids into the system + for (let i = 0; i < 100; i++) { + boids[i] = new Boid(random(width), random(height)); + } +} + +function draw() { + background(51); + // Run all the boids + for (let i = 0; i < boids.length; i++) { + boids[i].run(boids); + } +} + + +// Boid class +// Methods for Separation, Cohesion, Alignment added +class Boid { + constructor(x, y) { + this.acceleration = createVector(0, 0); + this.velocity = p5.Vector.random2D(); + this.position = createVector(x, y); + this.r = 3.0; + this.maxspeed = 3; // Maximum speed + this.maxforce = 0.05; // Maximum steering force + } + + run(boids) { + this.flock(boids); + this.update(); + this.borders(); + this.render(); + } + // Forces go into acceleration + applyForce(force) { + this.acceleration.add(force); + } + + // We accumulate a new acceleration each time based on three rules + flock(boids) { + let sep = this.separate(boids); // Separation + let ali = this.align(boids); // Alignment + let coh = this.cohesion(boids); // Cohesion + // Arbitrarily weight these forces + sep.mult(2.5); + ali.mult(1.0); + coh.mult(1.0); + // Add the force vectors to acceleration + this.applyForce(sep); + this.applyForce(ali); + this.applyForce(coh); + } + + // Method to update location + update() { + // Update velocity + this.velocity.add(this.acceleration); + // Limit speed + this.velocity.limit(this.maxspeed); + this.position.add(this.velocity); + // Reset acceleration to 0 each cycle + this.acceleration.mult(0); + } + + // A method that calculates and applies a steering force towards a target + // STEER = DESIRED MINUS VELOCITY + seek(target) { + let desired = p5.Vector.sub(target, this.position); // A vector pointing from the location to the target + // Normalize desired and scale to maximum speed + desired.normalize(); + desired.mult(this.maxspeed); + // Steering = Desired minus Velocity + let steer = p5.Vector.sub(desired, this.velocity); + steer.limit(this.maxforce); // Limit to maximum steering force + return steer; + } + + // Draw boid as a circle + render() { + fill(127, 127); + stroke(200); + ellipse(this.position.x, this.position.y, 16, 16); + } + + // Wraparound + borders() { + if (this.position.x < -this.r) this.position.x = width + this.r; + if (this.position.y < -this.r) this.position.y = height + this.r; + if (this.position.x > width + this.r) this.position.x = -this.r; + if (this.position.y > height + this.r) this.position.y = -this.r; + } + + // Separation + // Method checks for nearby boids and steers away + separate(boids) { + let desiredseparation = 25.0; + let steer = createVector(0, 0); + let count = 0; + // For every boid in the system, check if it's too close + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) + if ((d > 0) && (d < desiredseparation)) { + // Calculate vector pointing away from neighbor + let diff = p5.Vector.sub(this.position, boids[i].position); + diff.normalize(); + diff.div(d); // Weight by distance + steer.add(diff); + count++; // Keep track of how many + } + } + // Average -- divide by how many + if (count > 0) { + steer.div(count); + } + + // As long as the vector is greater than 0 + if (steer.mag() > 0) { + // Implement Reynolds: Steering = Desired - Velocity + steer.normalize(); + steer.mult(this.maxspeed); + steer.sub(this.velocity); + steer.limit(this.maxforce); + } + return steer; + } + + // Alignment + // For every nearby boid in the system, calculate the average velocity + align(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].velocity); + count++; + } + } + if (count > 0) { + sum.div(count); + sum.normalize(); + sum.mult(this.maxspeed); + let steer = p5.Vector.sub(sum, this.velocity); + steer.limit(this.maxforce); + return steer; + } else { + return createVector(0, 0); + } + } + + // Cohesion + // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location + cohesion(boids) { + let neighbordist = 50; + let sum = createVector(0, 0); // Start with empty vector to accumulate all locations + let count = 0; + for (let i = 0; i < boids.length; i++) { + let d = p5.Vector.dist(this.position, boids[i].position); + if ((d > 0) && (d < neighbordist)) { + sum.add(boids[i].position); // Add location + count++; + } + } + if (count > 0) { + sum.div(count); + return this.seek(sum); // Steer towards the location + } else { + return createVector(0, 0); + } + } +} + + + + diff --git a/dist/assets/examples/zh-Hans/90_Hello_P5/05_weather.js b/dist/assets/examples/zh-Hans/90_Hello_P5/05_weather.js new file mode 100644 index 0000000000..db3a61141c --- /dev/null +++ b/dist/assets/examples/zh-Hans/90_Hello_P5/05_weather.js @@ -0,0 +1,70 @@ +/* + * @name Weather + * @frame 720,280 + * @description This example grabs JSON weather data from www.metaweather.com. +*/ + +// A wind direction vector +let wind; +// Circle position +let position; + +function setup() { + createCanvas(720, 200); + // Request the data from metaweather.com + let url = 'https://cors-anywhere.herokuapp.com/https://www.metaweather.com/api/location/2459115/'; + loadJSON(url,gotWeather); + // Circle starts in the middle + position = createVector(width/2, height/2); + // wind starts as (0,0) + wind = createVector(); +} + +function draw() { + background(200); + + // This section draws an arrow pointing in the direction of wind + push(); + translate(32, height - 32); + // Rotate by the wind's angle + rotate(wind.heading() + PI/2); + noStroke(); + fill(255); + ellipse(0, 0, 48, 48); + + stroke(45, 123, 182); + strokeWeight(3); + line(0, -16, 0, 16); + + noStroke(); + fill(45, 123, 182); + triangle(0, -18, -6, -10, 6, -10); + pop(); + + // Move in the wind's direction + position.add(wind); + + stroke(0); + fill(51); + ellipse(position.x, position.y, 16, 16); + + if (position.x > width) position.x = 0; + if (position.x < 0) position.x = width; + if (position.y > height) position.y = 0; + if (position.y < 0) position.y = height; +} + +function gotWeather(weather) { + let weather_today = weather.consolidated_weather[0] + // Get the angle (convert to radians) + let angle = radians(Number(weather_today.wind_direction)); + // Get the wind speed + let windmag = Number(weather_today.wind_speed); + + // Display as HTML elements + let temperatureDiv = createDiv(floor(weather_today.the_temp) + '°C'); + let windDiv = createDiv("WIND " + windmag + " MPH"); + + // Make a vector + wind = p5.Vector.fromAngle(angle); +} diff --git a/dist/assets/examples/zh-Hans/90_Hello_P5/06_drawing.js b/dist/assets/examples/zh-Hans/90_Hello_P5/06_drawing.js new file mode 100644 index 0000000000..b9b884c4ad --- /dev/null +++ b/dist/assets/examples/zh-Hans/90_Hello_P5/06_drawing.js @@ -0,0 +1,132 @@ +/* +* @name Drawing +* @description Generative painting program. +*/ + +// All the paths +let paths = []; +// Are we painting? +let painting = false; +// How long until the next circle +let next = 0; +// Where are we now and where were we? +let current; +let previous; + +function setup() { + createCanvas(720, 400); + current = createVector(0,0); + previous = createVector(0,0); +}; + +function draw() { + background(200); + + // If it's time for a new point + if (millis() > next && painting) { + + // Grab mouse position + current.x = mouseX; + current.y = mouseY; + + // New particle's force is based on mouse movement + let force = p5.Vector.sub(current, previous); + force.mult(0.05); + + // Add new particle + paths[paths.length - 1].add(current, force); + + // Schedule next circle + next = millis() + random(100); + + // Store mouse values + previous.x = current.x; + previous.y = current.y; + } + + // Draw all paths + for( let i = 0; i < paths.length; i++) { + paths[i].update(); + paths[i].display(); + } +} + +// Start it up +function mousePressed() { + next = 0; + painting = true; + previous.x = mouseX; + previous.y = mouseY; + paths.push(new Path()); +} + +// Stop +function mouseReleased() { + painting = false; +} + +// A Path is a list of particles +class Path { + constructor() { + this.particles = []; + this.hue = random(100); + } + + add(position, force) { + // Add a new particle with a position, force, and hue + this.particles.push(new Particle(position, force, this.hue)); + } + + // Display plath + update() { + for (let i = 0; i < this.particles.length; i++) { + this.particles[i].update(); + } + } + + // Display plath + display() { + + // Loop through backwards + for (let i = this.particles.length - 1; i >= 0; i--) { + // If we shold remove it + if (this.particles[i].lifespan <= 0) { + this.particles.splice(i, 1); + // Otherwise, display it + } else { + this.particles[i].display(this.particles[i+1]); + } + } + } +} + +// Particles along the path +class Particle { + constructor(position, force, hue) { + this.position = createVector(position.x, position.y); + this.velocity = createVector(force.x, force.y); + this.drag = 0.95; + this.lifespan = 255; + } + + update() { + // Move it + this.position.add(this.velocity); + // Slow it down + this.velocity.mult(this.drag); + // Fade it out + this.lifespan--; + } + + // Draw particle and connect it with a line + // Draw a line to another + display(other) { + stroke(0, this.lifespan); + fill(0, this.lifespan/2); + ellipse(this.position.x,this.position.y, 8, 8); + // If we need to draw a line + if (other) { + line(this.position.x, this.position.y, other.position.x, other.position.y); + } + } +} \ No newline at end of file diff --git a/dist/assets/examples/zh-Hans/90_Hello_P5/07_song.js b/dist/assets/examples/zh-Hans/90_Hello_P5/07_song.js new file mode 100644 index 0000000000..5e4337b7c9 --- /dev/null +++ b/dist/assets/examples/zh-Hans/90_Hello_P5/07_song.js @@ -0,0 +1,119 @@ +/* + * @name Song + * @frame 720, 430 + * @description Play a song. + * You will need to include the + * p5.sound + * library for this example to work in your own project. + */ +// The midi notes of a scale +let notes = [ 60, 62, 64, 65, 67, 69, 71]; + +// For automatically playing the song +let index = 0; +let song = [ + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 200, display: "G" }, + { note: 1, duration: 200, display: "A" }, + { note: 2, duration: 200, display: "B" }, + { note: 3, duration: 200, display: "C" }, + { note: 4, duration: 400, display: "D" }, + { note: 0, duration: 400, display: "G" }, + { note: 0, duration: 400, display: "G" } +]; +let trigger = 0; +let autoplay = false; +let osc; + +function setup() { + createCanvas(720, 400); + let div = createDiv("Click to play notes or ") + div.id("instructions"); + let button = createButton("play song automatically."); + button.parent("instructions"); + // Trigger automatically playing + button.mousePressed(function() { + if (!autoplay) { + index = 0; + autoplay = true; + } + }); + + // A triangle oscillator + osc = new p5.TriOsc(); + // Start silent + osc.start(); + osc.amp(0); +} + +// A function to play a note +function playNote(note, duration) { + osc.freq(midiToFreq(note)); + // Fade it in + osc.fade(0.5,0.2); + + // If we sest a duration, fade it out + if (duration) { + setTimeout(function() { + osc.fade(0,0.2); + }, duration-50); + } +} + +function draw() { + + // If we are autoplaying and it's time for the next note + if (autoplay && millis() > trigger){ + playNote(notes[song[index].note], song[index].duration); + trigger = millis() + song[index].duration; + // Move to the next note + index ++; + // We're at the end, stop autoplaying. + } else if (index >= song.length) { + autoplay = false; + } + + + // Draw a keyboard + + // The width for each key + let w = width / notes.length; + for (let i = 0; i < notes.length; i++) { + let x = i * w; + // If the mouse is over the key + if (mouseX > x && mouseX < x + w && mouseY < height) { + // If we're clicking + if (mouseIsPressed) { + fill(100,255,200); + // Or just rolling over + } else { + fill(127); + } + } else { + fill(200); + } + + // Or if we're playing the song, let's highlight it too + if (autoplay && i === song[index-1].note) { + fill(100,255,200); + } + + // Draw the key + rect(x, 0, w-1, height-1); + } + +} + +// When we click +function mousePressed(event) { + if(event.button == 0 && event.clientX < width && event.clientY < height) { + // Map mouse to the key index + let key = floor(map(mouseX, 0, width, 0, notes.length)); + playNote(notes[key]); + } +} + +// Fade it out when we release +function mouseReleased() { + osc.fade(0,0.5); +} diff --git a/dist/assets/img/asterisk-01-01.png b/dist/assets/img/asterisk-01-01.png new file mode 100644 index 0000000000..446e558cc2 Binary files /dev/null and b/dist/assets/img/asterisk-01-01.png differ diff --git a/dist/assets/img/asterisk-01.png b/dist/assets/img/asterisk-01.png new file mode 100644 index 0000000000..22434179c5 Binary files /dev/null and b/dist/assets/img/asterisk-01.png differ diff --git a/dist/assets/img/asterisk.png b/dist/assets/img/asterisk.png new file mode 100644 index 0000000000..6821962dc7 Binary files /dev/null and b/dist/assets/img/asterisk.png differ diff --git a/dist/assets/img/books/aesthetic-programming.jpg b/dist/assets/img/books/aesthetic-programming.jpg new file mode 100644 index 0000000000..e1bfe03cad Binary files /dev/null and b/dist/assets/img/books/aesthetic-programming.jpg differ diff --git a/dist/assets/img/books/generative_design.jpg b/dist/assets/img/books/generative_design.jpg new file mode 100644 index 0000000000..2a27234a04 Binary files /dev/null and b/dist/assets/img/books/generative_design.jpg differ diff --git a/dist/assets/img/books/generative_gestaltung.jpg b/dist/assets/img/books/generative_gestaltung.jpg new file mode 100644 index 0000000000..158190cf48 Binary files /dev/null and b/dist/assets/img/books/generative_gestaltung.jpg differ diff --git a/dist/assets/img/books/gettingstarted-es.jpg b/dist/assets/img/books/gettingstarted-es.jpg new file mode 100644 index 0000000000..e27dd4f9f3 Binary files /dev/null and b/dist/assets/img/books/gettingstarted-es.jpg differ diff --git a/dist/assets/img/books/gettingstarted.jpg b/dist/assets/img/books/gettingstarted.jpg new file mode 100644 index 0000000000..05db48f71f Binary files /dev/null and b/dist/assets/img/books/gettingstarted.jpg differ diff --git a/dist/assets/img/books/learn_javascript.jpg b/dist/assets/img/books/learn_javascript.jpg new file mode 100644 index 0000000000..30e3b6830b Binary files /dev/null and b/dist/assets/img/books/learn_javascript.jpg differ diff --git a/dist/assets/img/cc_88x31.png b/dist/assets/img/cc_88x31.png new file mode 100644 index 0000000000..5f7863d5be Binary files /dev/null and b/dist/assets/img/cc_88x31.png differ diff --git a/dist/assets/img/community/2015_1.jpg b/dist/assets/img/community/2015_1.jpg new file mode 100644 index 0000000000..25ac4ca622 Binary files /dev/null and b/dist/assets/img/community/2015_1.jpg differ diff --git a/dist/assets/img/community/2015_10.jpg b/dist/assets/img/community/2015_10.jpg new file mode 100644 index 0000000000..6bce1d7805 Binary files /dev/null and b/dist/assets/img/community/2015_10.jpg differ diff --git a/dist/assets/img/community/2015_11.jpg b/dist/assets/img/community/2015_11.jpg new file mode 100644 index 0000000000..0eca240a21 Binary files /dev/null and b/dist/assets/img/community/2015_11.jpg differ diff --git a/dist/assets/img/community/2015_12.jpg b/dist/assets/img/community/2015_12.jpg new file mode 100644 index 0000000000..b6b9456230 Binary files /dev/null and b/dist/assets/img/community/2015_12.jpg differ diff --git a/dist/assets/img/community/2015_13.jpg b/dist/assets/img/community/2015_13.jpg new file mode 100644 index 0000000000..5cd8692887 Binary files /dev/null and b/dist/assets/img/community/2015_13.jpg differ diff --git a/dist/assets/img/community/2015_14.jpg b/dist/assets/img/community/2015_14.jpg new file mode 100644 index 0000000000..376626b091 Binary files /dev/null and b/dist/assets/img/community/2015_14.jpg differ diff --git a/dist/assets/img/community/2015_15.jpg b/dist/assets/img/community/2015_15.jpg new file mode 100644 index 0000000000..4ee765616e Binary files /dev/null and b/dist/assets/img/community/2015_15.jpg differ diff --git a/dist/assets/img/community/2015_2.jpg b/dist/assets/img/community/2015_2.jpg new file mode 100644 index 0000000000..187bac78d6 Binary files /dev/null and b/dist/assets/img/community/2015_2.jpg differ diff --git a/dist/assets/img/community/2015_3.jpg b/dist/assets/img/community/2015_3.jpg new file mode 100644 index 0000000000..cbb1e7e379 Binary files /dev/null and b/dist/assets/img/community/2015_3.jpg differ diff --git a/dist/assets/img/community/2015_4.jpg b/dist/assets/img/community/2015_4.jpg new file mode 100644 index 0000000000..0d9760dad9 Binary files /dev/null and b/dist/assets/img/community/2015_4.jpg differ diff --git a/dist/assets/img/community/2015_5.jpg b/dist/assets/img/community/2015_5.jpg new file mode 100644 index 0000000000..39f9b2365a Binary files /dev/null and b/dist/assets/img/community/2015_5.jpg differ diff --git a/dist/assets/img/community/2015_6.jpg b/dist/assets/img/community/2015_6.jpg new file mode 100644 index 0000000000..2f6c0f4f27 Binary files /dev/null and b/dist/assets/img/community/2015_6.jpg differ diff --git a/dist/assets/img/community/2015_7.jpg b/dist/assets/img/community/2015_7.jpg new file mode 100644 index 0000000000..235ab3cb15 Binary files /dev/null and b/dist/assets/img/community/2015_7.jpg differ diff --git a/dist/assets/img/community/2015_8.jpg b/dist/assets/img/community/2015_8.jpg new file mode 100644 index 0000000000..dbf0dd6cb7 Binary files /dev/null and b/dist/assets/img/community/2015_8.jpg differ diff --git a/dist/assets/img/community/2015_9.jpg b/dist/assets/img/community/2015_9.jpg new file mode 100644 index 0000000000..f1188e77b9 Binary files /dev/null and b/dist/assets/img/community/2015_9.jpg differ diff --git a/dist/assets/img/community/2019_1.jpg b/dist/assets/img/community/2019_1.jpg new file mode 100644 index 0000000000..820867650a Binary files /dev/null and b/dist/assets/img/community/2019_1.jpg differ diff --git a/dist/assets/img/community/2019_10.jpg b/dist/assets/img/community/2019_10.jpg new file mode 100644 index 0000000000..9b9237ab9c Binary files /dev/null and b/dist/assets/img/community/2019_10.jpg differ diff --git a/dist/assets/img/community/2019_11.jpg b/dist/assets/img/community/2019_11.jpg new file mode 100644 index 0000000000..60f92fc9aa Binary files /dev/null and b/dist/assets/img/community/2019_11.jpg differ diff --git a/dist/assets/img/community/2019_12.jpg b/dist/assets/img/community/2019_12.jpg new file mode 100644 index 0000000000..6fa1fad90c Binary files /dev/null and b/dist/assets/img/community/2019_12.jpg differ diff --git a/dist/assets/img/community/2019_13.jpg b/dist/assets/img/community/2019_13.jpg new file mode 100644 index 0000000000..9453c14cd1 Binary files /dev/null and b/dist/assets/img/community/2019_13.jpg differ diff --git a/dist/assets/img/community/2019_14.jpg b/dist/assets/img/community/2019_14.jpg new file mode 100644 index 0000000000..44809c8b9a Binary files /dev/null and b/dist/assets/img/community/2019_14.jpg differ diff --git a/dist/assets/img/community/2019_15.jpg b/dist/assets/img/community/2019_15.jpg new file mode 100644 index 0000000000..697b209dc1 Binary files /dev/null and b/dist/assets/img/community/2019_15.jpg differ diff --git a/dist/assets/img/community/2019_16.jpg b/dist/assets/img/community/2019_16.jpg new file mode 100644 index 0000000000..e57901907d Binary files /dev/null and b/dist/assets/img/community/2019_16.jpg differ diff --git a/dist/assets/img/community/2019_17.jpg b/dist/assets/img/community/2019_17.jpg new file mode 100644 index 0000000000..72d930c696 Binary files /dev/null and b/dist/assets/img/community/2019_17.jpg differ diff --git a/dist/assets/img/community/2019_18.jpg b/dist/assets/img/community/2019_18.jpg new file mode 100644 index 0000000000..40c5551679 Binary files /dev/null and b/dist/assets/img/community/2019_18.jpg differ diff --git a/dist/assets/img/community/2019_19.jpg b/dist/assets/img/community/2019_19.jpg new file mode 100644 index 0000000000..149a2997a4 Binary files /dev/null and b/dist/assets/img/community/2019_19.jpg differ diff --git a/dist/assets/img/community/2019_2.jpg b/dist/assets/img/community/2019_2.jpg new file mode 100644 index 0000000000..61a71505ed Binary files /dev/null and b/dist/assets/img/community/2019_2.jpg differ diff --git a/dist/assets/img/community/2019_20.jpg b/dist/assets/img/community/2019_20.jpg new file mode 100644 index 0000000000..0a0a4f5cbc Binary files /dev/null and b/dist/assets/img/community/2019_20.jpg differ diff --git a/dist/assets/img/community/2019_21.jpg b/dist/assets/img/community/2019_21.jpg new file mode 100644 index 0000000000..da9d037c7d Binary files /dev/null and b/dist/assets/img/community/2019_21.jpg differ diff --git a/dist/assets/img/community/2019_22.jpg b/dist/assets/img/community/2019_22.jpg new file mode 100644 index 0000000000..e52ee524bd Binary files /dev/null and b/dist/assets/img/community/2019_22.jpg differ diff --git a/dist/assets/img/community/2019_23.jpg b/dist/assets/img/community/2019_23.jpg new file mode 100644 index 0000000000..3a2cef2ef5 Binary files /dev/null and b/dist/assets/img/community/2019_23.jpg differ diff --git a/dist/assets/img/community/2019_24.jpg b/dist/assets/img/community/2019_24.jpg new file mode 100644 index 0000000000..83643badc2 Binary files /dev/null and b/dist/assets/img/community/2019_24.jpg differ diff --git a/dist/assets/img/community/2019_3.jpg b/dist/assets/img/community/2019_3.jpg new file mode 100644 index 0000000000..09151ecc7d Binary files /dev/null and b/dist/assets/img/community/2019_3.jpg differ diff --git a/dist/assets/img/community/2019_4.jpg b/dist/assets/img/community/2019_4.jpg new file mode 100644 index 0000000000..c39fe9a533 Binary files /dev/null and b/dist/assets/img/community/2019_4.jpg differ diff --git a/dist/assets/img/community/2019_5.jpg b/dist/assets/img/community/2019_5.jpg new file mode 100644 index 0000000000..4be4fc4872 Binary files /dev/null and b/dist/assets/img/community/2019_5.jpg differ diff --git a/dist/assets/img/community/2019_6.jpg b/dist/assets/img/community/2019_6.jpg new file mode 100644 index 0000000000..51d5663506 Binary files /dev/null and b/dist/assets/img/community/2019_6.jpg differ diff --git a/dist/assets/img/community/2019_7.jpg b/dist/assets/img/community/2019_7.jpg new file mode 100644 index 0000000000..935292af9e Binary files /dev/null and b/dist/assets/img/community/2019_7.jpg differ diff --git a/dist/assets/img/community/2019_8.jpg b/dist/assets/img/community/2019_8.jpg new file mode 100644 index 0000000000..85e76f8eec Binary files /dev/null and b/dist/assets/img/community/2019_8.jpg differ diff --git a/dist/assets/img/community/2019_9.jpg b/dist/assets/img/community/2019_9.jpg new file mode 100644 index 0000000000..4737541a31 Binary files /dev/null and b/dist/assets/img/community/2019_9.jpg differ diff --git a/dist/assets/img/community/COSA.png b/dist/assets/img/community/COSA.png new file mode 100644 index 0000000000..c9d94af605 Binary files /dev/null and b/dist/assets/img/community/COSA.png differ diff --git a/dist/assets/img/community/HGK.jpg b/dist/assets/img/community/HGK.jpg new file mode 100644 index 0000000000..73ed731721 Binary files /dev/null and b/dist/assets/img/community/HGK.jpg differ diff --git a/dist/assets/img/community/IDM.jpg b/dist/assets/img/community/IDM.jpg new file mode 100644 index 0000000000..194677e076 Binary files /dev/null and b/dist/assets/img/community/IDM.jpg differ diff --git a/dist/assets/img/community/NEA.png b/dist/assets/img/community/NEA.png new file mode 100644 index 0000000000..3df9374dd4 Binary files /dev/null and b/dist/assets/img/community/NEA.png differ diff --git a/dist/assets/img/community/Parsons.jpg b/dist/assets/img/community/Parsons.jpg new file mode 100644 index 0000000000..094518a0f9 Binary files /dev/null and b/dist/assets/img/community/Parsons.jpg differ diff --git a/dist/assets/img/community/bocoup.png b/dist/assets/img/community/bocoup.png new file mode 100644 index 0000000000..5f17d9f5ec Binary files /dev/null and b/dist/assets/img/community/bocoup.png differ diff --git a/dist/assets/img/community/campfire.jpg b/dist/assets/img/community/campfire.jpg new file mode 100644 index 0000000000..249347821e Binary files /dev/null and b/dist/assets/img/community/campfire.jpg differ diff --git a/dist/assets/img/community/depaul.png b/dist/assets/img/community/depaul.png new file mode 100644 index 0000000000..01c79a2917 Binary files /dev/null and b/dist/assets/img/community/depaul.png differ diff --git a/dist/assets/img/community/edp.png b/dist/assets/img/community/edp.png new file mode 100644 index 0000000000..46fb30505b Binary files /dev/null and b/dist/assets/img/community/edp.png differ diff --git a/dist/assets/img/community/itp.png b/dist/assets/img/community/itp.png new file mode 100644 index 0000000000..56dbf8d913 Binary files /dev/null and b/dist/assets/img/community/itp.png differ diff --git a/dist/assets/img/community/nea.jpg b/dist/assets/img/community/nea.jpg new file mode 100644 index 0000000000..b214d71c04 Binary files /dev/null and b/dist/assets/img/community/nea.jpg differ diff --git a/dist/assets/img/community/processing-foundation.png b/dist/assets/img/community/processing-foundation.png new file mode 100644 index 0000000000..6a18f001ba Binary files /dev/null and b/dist/assets/img/community/processing-foundation.png differ diff --git a/dist/assets/img/community/studio.png b/dist/assets/img/community/studio.png new file mode 100644 index 0000000000..3bed89e50b Binary files /dev/null and b/dist/assets/img/community/studio.png differ diff --git a/dist/assets/img/community/theartificial.png b/dist/assets/img/community/theartificial.png new file mode 100644 index 0000000000..45145985b6 Binary files /dev/null and b/dist/assets/img/community/theartificial.png differ diff --git a/dist/assets/img/community/theartificial.svg b/dist/assets/img/community/theartificial.svg new file mode 100644 index 0000000000..ef3393e862 --- /dev/null +++ b/dist/assets/img/community/theartificial.svg @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + +theartificial.nl + diff --git a/dist/assets/img/download/Cassie_CodeMiami0.png b/dist/assets/img/download/Cassie_CodeMiami0.png new file mode 100644 index 0000000000..1dd3c6d734 Binary files /dev/null and b/dist/assets/img/download/Cassie_CodeMiami0.png differ diff --git a/dist/assets/img/download/Cassie_CodeMiami5.png b/dist/assets/img/download/Cassie_CodeMiami5.png new file mode 100644 index 0000000000..6e95b60579 Binary files /dev/null and b/dist/assets/img/download/Cassie_CodeMiami5.png differ diff --git a/dist/assets/img/download/LearningToTeach45-small.jpg b/dist/assets/img/download/LearningToTeach45-small.jpg new file mode 100644 index 0000000000..a90a11c774 Binary files /dev/null and b/dist/assets/img/download/LearningToTeach45-small.jpg differ diff --git a/dist/assets/img/download/aaron.jpg b/dist/assets/img/download/aaron.jpg new file mode 100644 index 0000000000..7680c1951d Binary files /dev/null and b/dist/assets/img/download/aaron.jpg differ diff --git a/dist/assets/img/download/conf2.jpg b/dist/assets/img/download/conf2.jpg new file mode 100644 index 0000000000..e8beedc81d Binary files /dev/null and b/dist/assets/img/download/conf2.jpg differ diff --git a/dist/assets/img/download/digitalcitizens-panel3.png b/dist/assets/img/download/digitalcitizens-panel3.png new file mode 100644 index 0000000000..4412e0fc21 Binary files /dev/null and b/dist/assets/img/download/digitalcitizens-panel3.png differ diff --git a/dist/assets/img/download/digitalcitizens7.jpg b/dist/assets/img/download/digitalcitizens7.jpg new file mode 100644 index 0000000000..c71715d806 Binary files /dev/null and b/dist/assets/img/download/digitalcitizens7.jpg differ diff --git a/dist/assets/img/download/diygirls1.jpg b/dist/assets/img/download/diygirls1.jpg new file mode 100644 index 0000000000..2f927f90b7 Binary files /dev/null and b/dist/assets/img/download/diygirls1.jpg differ diff --git a/dist/assets/img/download/gsoc_kickoff.jpg b/dist/assets/img/download/gsoc_kickoff.jpg new file mode 100644 index 0000000000..330aa265f4 Binary files /dev/null and b/dist/assets/img/download/gsoc_kickoff.jpg differ diff --git a/dist/assets/img/download/p5-coast2coast.jpg b/dist/assets/img/download/p5-coast2coast.jpg new file mode 100644 index 0000000000..3ff718aa6c Binary files /dev/null and b/dist/assets/img/download/p5-coast2coast.jpg differ diff --git a/dist/assets/img/download/p5js-5939.jpg b/dist/assets/img/download/p5js-5939.jpg new file mode 100644 index 0000000000..26d8529513 Binary files /dev/null and b/dist/assets/img/download/p5js-5939.jpg differ diff --git a/dist/assets/img/download/saskia-project.jpg b/dist/assets/img/download/saskia-project.jpg new file mode 100644 index 0000000000..14bb4393c9 Binary files /dev/null and b/dist/assets/img/download/saskia-project.jpg differ diff --git a/dist/assets/img/download/signingcoders0.jpg b/dist/assets/img/download/signingcoders0.jpg new file mode 100644 index 0000000000..49fb9ac16d Binary files /dev/null and b/dist/assets/img/download/signingcoders0.jpg differ diff --git a/dist/assets/img/download/signingcoders2.jpg b/dist/assets/img/download/signingcoders2.jpg new file mode 100644 index 0000000000..ac20d8efd7 Binary files /dev/null and b/dist/assets/img/download/signingcoders2.jpg differ diff --git a/dist/assets/img/download/signingcoders3.jpg b/dist/assets/img/download/signingcoders3.jpg new file mode 100644 index 0000000000..303041c678 Binary files /dev/null and b/dist/assets/img/download/signingcoders3.jpg differ diff --git a/dist/assets/img/favicon.ico b/dist/assets/img/favicon.ico new file mode 100644 index 0000000000..32d2ac48a0 Binary files /dev/null and b/dist/assets/img/favicon.ico differ diff --git a/dist/assets/img/gallery-images/PrismPusher.jpg b/dist/assets/img/gallery-images/PrismPusher.jpg new file mode 100644 index 0000000000..3845c5680b Binary files /dev/null and b/dist/assets/img/gallery-images/PrismPusher.jpg differ diff --git a/dist/assets/img/gallery-images/cell-flight.png b/dist/assets/img/gallery-images/cell-flight.png new file mode 100644 index 0000000000..dd089694bf Binary files /dev/null and b/dist/assets/img/gallery-images/cell-flight.png differ diff --git a/dist/assets/img/gallery-images/emoji-booth.png b/dist/assets/img/gallery-images/emoji-booth.png new file mode 100644 index 0000000000..510d005b2d Binary files /dev/null and b/dist/assets/img/gallery-images/emoji-booth.png differ diff --git a/dist/assets/img/gallery-images/hardmarubox2D.png b/dist/assets/img/gallery-images/hardmarubox2D.png new file mode 100644 index 0000000000..595fac3a55 Binary files /dev/null and b/dist/assets/img/gallery-images/hardmarubox2D.png differ diff --git a/dist/assets/img/gallery-images/hardmaruplanks.png b/dist/assets/img/gallery-images/hardmaruplanks.png new file mode 100644 index 0000000000..6bb84be2ea Binary files /dev/null and b/dist/assets/img/gallery-images/hardmaruplanks.png differ diff --git a/dist/assets/img/gallery-images/keyboard.png b/dist/assets/img/gallery-images/keyboard.png new file mode 100644 index 0000000000..98b352e68f Binary files /dev/null and b/dist/assets/img/gallery-images/keyboard.png differ diff --git a/dist/assets/img/gallery-images/magic-is-real-emoji.png b/dist/assets/img/gallery-images/magic-is-real-emoji.png new file mode 100644 index 0000000000..de228db68f Binary files /dev/null and b/dist/assets/img/gallery-images/magic-is-real-emoji.png differ diff --git a/dist/assets/img/gallery-images/music-viz.png b/dist/assets/img/gallery-images/music-viz.png new file mode 100644 index 0000000000..7c529cbf97 Binary files /dev/null and b/dist/assets/img/gallery-images/music-viz.png differ diff --git a/dist/assets/img/gallery-images/neobrush.png b/dist/assets/img/gallery-images/neobrush.png new file mode 100644 index 0000000000..265977d15e Binary files /dev/null and b/dist/assets/img/gallery-images/neobrush.png differ diff --git a/dist/assets/img/gallery-images/nithi-prasanpanich.png b/dist/assets/img/gallery-images/nithi-prasanpanich.png new file mode 100644 index 0000000000..5f9aaa0513 Binary files /dev/null and b/dist/assets/img/gallery-images/nithi-prasanpanich.png differ diff --git a/dist/assets/img/gallery-images/ol-scroll.png b/dist/assets/img/gallery-images/ol-scroll.png new file mode 100644 index 0000000000..3f5ff13ec5 Binary files /dev/null and b/dist/assets/img/gallery-images/ol-scroll.png differ diff --git a/dist/assets/img/gallery-images/organic-motion-sonification.png b/dist/assets/img/gallery-images/organic-motion-sonification.png new file mode 100644 index 0000000000..bf808881c2 Binary files /dev/null and b/dist/assets/img/gallery-images/organic-motion-sonification.png differ diff --git a/dist/assets/img/gallery-images/social-tension.png b/dist/assets/img/gallery-images/social-tension.png new file mode 100644 index 0000000000..bc6fa66188 Binary files /dev/null and b/dist/assets/img/gallery-images/social-tension.png differ diff --git a/dist/assets/img/gallery-images/springs.png b/dist/assets/img/gallery-images/springs.png new file mode 100644 index 0000000000..e33398c2bb Binary files /dev/null and b/dist/assets/img/gallery-images/springs.png differ diff --git a/dist/assets/img/gallery-images/star-trails.png b/dist/assets/img/gallery-images/star-trails.png new file mode 100644 index 0000000000..c9654b61bd Binary files /dev/null and b/dist/assets/img/gallery-images/star-trails.png differ diff --git a/dist/assets/img/get-started/first-sketch.png b/dist/assets/img/get-started/first-sketch.png new file mode 100644 index 0000000000..8505f3edb1 Binary files /dev/null and b/dist/assets/img/get-started/first-sketch.png differ diff --git a/dist/assets/img/get-started/first-sketch2.png b/dist/assets/img/get-started/first-sketch2.png new file mode 100644 index 0000000000..8f6eeed629 Binary files /dev/null and b/dist/assets/img/get-started/first-sketch2.png differ diff --git a/dist/assets/img/get-started/sublime.png b/dist/assets/img/get-started/sublime.png new file mode 100644 index 0000000000..92f504a5e8 Binary files /dev/null and b/dist/assets/img/get-started/sublime.png differ diff --git a/dist/assets/img/get-started/sublime2.png b/dist/assets/img/get-started/sublime2.png new file mode 100644 index 0000000000..2c8a5888a8 Binary files /dev/null and b/dist/assets/img/get-started/sublime2.png differ diff --git a/dist/assets/img/learn/3d.jpg b/dist/assets/img/learn/3d.jpg new file mode 100644 index 0000000000..af422f5db2 Binary files /dev/null and b/dist/assets/img/learn/3d.jpg differ diff --git a/dist/assets/img/learn/dom.jpg b/dist/assets/img/learn/dom.jpg new file mode 100644 index 0000000000..eb4a48ce65 Binary files /dev/null and b/dist/assets/img/learn/dom.jpg differ diff --git a/dist/assets/img/learn/lib_placeholder.jpg b/dist/assets/img/learn/lib_placeholder.jpg new file mode 100644 index 0000000000..422b3c87a5 Binary files /dev/null and b/dist/assets/img/learn/lib_placeholder.jpg differ diff --git a/dist/assets/img/libraries/Rotating_knobs.jpg b/dist/assets/img/libraries/Rotating_knobs.jpg new file mode 100644 index 0000000000..5a56e5510b Binary files /dev/null and b/dist/assets/img/libraries/Rotating_knobs.jpg differ diff --git a/dist/assets/img/libraries/Shape5.jpg b/dist/assets/img/libraries/Shape5.jpg new file mode 100644 index 0000000000..1fad657ca0 Binary files /dev/null and b/dist/assets/img/libraries/Shape5.jpg differ diff --git a/dist/assets/img/libraries/asciiart.jpg b/dist/assets/img/libraries/asciiart.jpg new file mode 100644 index 0000000000..04dca7b2c3 Binary files /dev/null and b/dist/assets/img/libraries/asciiart.jpg differ diff --git a/dist/assets/img/libraries/dom.jpg b/dist/assets/img/libraries/dom.jpg new file mode 100644 index 0000000000..e5cf131452 Binary files /dev/null and b/dist/assets/img/libraries/dom.jpg differ diff --git a/dist/assets/img/libraries/grafica.js.jpg b/dist/assets/img/libraries/grafica.js.jpg new file mode 100644 index 0000000000..4f873efd49 Binary files /dev/null and b/dist/assets/img/libraries/grafica.js.jpg differ diff --git a/dist/assets/img/libraries/lib_placeholder.jpg b/dist/assets/img/libraries/lib_placeholder.jpg new file mode 100644 index 0000000000..422b3c87a5 Binary files /dev/null and b/dist/assets/img/libraries/lib_placeholder.jpg differ diff --git a/dist/assets/img/libraries/mappa.jpg b/dist/assets/img/libraries/mappa.jpg new file mode 100644 index 0000000000..fe07153e8a Binary files /dev/null and b/dist/assets/img/libraries/mappa.jpg differ diff --git a/dist/assets/img/libraries/marching.jpg b/dist/assets/img/libraries/marching.jpg new file mode 100644 index 0000000000..fc0afef464 Binary files /dev/null and b/dist/assets/img/libraries/marching.jpg differ diff --git a/dist/assets/img/libraries/ml5.js.jpg b/dist/assets/img/libraries/ml5.js.jpg new file mode 100644 index 0000000000..1b05c58b01 Binary files /dev/null and b/dist/assets/img/libraries/ml5.js.jpg differ diff --git a/dist/assets/img/libraries/p5.3D.jpg b/dist/assets/img/libraries/p5.3D.jpg new file mode 100644 index 0000000000..ef3c5f3067 Binary files /dev/null and b/dist/assets/img/libraries/p5.3D.jpg differ diff --git a/dist/assets/img/libraries/p5.EasyCam.jpg b/dist/assets/img/libraries/p5.EasyCam.jpg new file mode 100644 index 0000000000..de2f98fd55 Binary files /dev/null and b/dist/assets/img/libraries/p5.EasyCam.jpg differ diff --git a/dist/assets/img/libraries/p5.Riso.jpg b/dist/assets/img/libraries/p5.Riso.jpg new file mode 100644 index 0000000000..862f1fdaf0 Binary files /dev/null and b/dist/assets/img/libraries/p5.Riso.jpg differ diff --git a/dist/assets/img/libraries/p5.acc.jpg b/dist/assets/img/libraries/p5.acc.jpg new file mode 100644 index 0000000000..e397d71489 Binary files /dev/null and b/dist/assets/img/libraries/p5.acc.jpg differ diff --git a/dist/assets/img/libraries/p5.accessibility.jpg b/dist/assets/img/libraries/p5.accessibility.jpg new file mode 100644 index 0000000000..9f3ad6d2d8 Binary files /dev/null and b/dist/assets/img/libraries/p5.accessibility.jpg differ diff --git a/dist/assets/img/libraries/p5.ble.jpg b/dist/assets/img/libraries/p5.ble.jpg new file mode 100644 index 0000000000..35bebb8abe Binary files /dev/null and b/dist/assets/img/libraries/p5.ble.jpg differ diff --git a/dist/assets/img/libraries/p5.bots.jpg b/dist/assets/img/libraries/p5.bots.jpg new file mode 100644 index 0000000000..62d426d57b Binary files /dev/null and b/dist/assets/img/libraries/p5.bots.jpg differ diff --git a/dist/assets/img/libraries/p5.clickable.jpg b/dist/assets/img/libraries/p5.clickable.jpg new file mode 100644 index 0000000000..26757f367b Binary files /dev/null and b/dist/assets/img/libraries/p5.clickable.jpg differ diff --git a/dist/assets/img/libraries/p5.cmyk.js.jpg b/dist/assets/img/libraries/p5.cmyk.js.jpg new file mode 100644 index 0000000000..cdb1a4ba5f Binary files /dev/null and b/dist/assets/img/libraries/p5.cmyk.js.jpg differ diff --git a/dist/assets/img/libraries/p5.collide2D.jpg b/dist/assets/img/libraries/p5.collide2D.jpg new file mode 100644 index 0000000000..1ba7ae9869 Binary files /dev/null and b/dist/assets/img/libraries/p5.collide2D.jpg differ diff --git a/dist/assets/img/libraries/p5.createloop.jpg b/dist/assets/img/libraries/p5.createloop.jpg new file mode 100644 index 0000000000..426d0d16d7 Binary files /dev/null and b/dist/assets/img/libraries/p5.createloop.jpg differ diff --git a/dist/assets/img/libraries/p5.dimensions.jpg b/dist/assets/img/libraries/p5.dimensions.jpg new file mode 100644 index 0000000000..a9b1afbffd Binary files /dev/null and b/dist/assets/img/libraries/p5.dimensions.jpg differ diff --git a/dist/assets/img/libraries/p5.experience.jpg b/dist/assets/img/libraries/p5.experience.jpg new file mode 100644 index 0000000000..90e9b66dcd Binary files /dev/null and b/dist/assets/img/libraries/p5.experience.jpg differ diff --git a/dist/assets/img/libraries/p5.func.jpg b/dist/assets/img/libraries/p5.func.jpg new file mode 100644 index 0000000000..ff5bb258ec Binary files /dev/null and b/dist/assets/img/libraries/p5.func.jpg differ diff --git a/dist/assets/img/libraries/p5.geolocation.jpg b/dist/assets/img/libraries/p5.geolocation.jpg new file mode 100644 index 0000000000..0fe7b16f74 Binary files /dev/null and b/dist/assets/img/libraries/p5.geolocation.jpg differ diff --git a/dist/assets/img/libraries/p5.gibber.jpg b/dist/assets/img/libraries/p5.gibber.jpg new file mode 100644 index 0000000000..db9892a801 Binary files /dev/null and b/dist/assets/img/libraries/p5.gibber.jpg differ diff --git a/dist/assets/img/libraries/p5.gif.jpg b/dist/assets/img/libraries/p5.gif.jpg new file mode 100644 index 0000000000..978263369c Binary files /dev/null and b/dist/assets/img/libraries/p5.gif.jpg differ diff --git a/dist/assets/img/libraries/p5.gui.jpg b/dist/assets/img/libraries/p5.gui.jpg new file mode 100644 index 0000000000..01d56c0c14 Binary files /dev/null and b/dist/assets/img/libraries/p5.gui.jpg differ diff --git a/dist/assets/img/libraries/p5.localmessage.jpg b/dist/assets/img/libraries/p5.localmessage.jpg new file mode 100644 index 0000000000..3368efd023 Binary files /dev/null and b/dist/assets/img/libraries/p5.localmessage.jpg differ diff --git a/dist/assets/img/libraries/p5.particle.jpg b/dist/assets/img/libraries/p5.particle.jpg new file mode 100644 index 0000000000..32297160b9 Binary files /dev/null and b/dist/assets/img/libraries/p5.particle.jpg differ diff --git a/dist/assets/img/libraries/p5.play.jpg b/dist/assets/img/libraries/p5.play.jpg new file mode 100644 index 0000000000..5359c2b8b3 Binary files /dev/null and b/dist/assets/img/libraries/p5.play.jpg differ diff --git a/dist/assets/img/libraries/p5.scenemanager.jpg b/dist/assets/img/libraries/p5.scenemanager.jpg new file mode 100644 index 0000000000..0884d8cdb6 Binary files /dev/null and b/dist/assets/img/libraries/p5.scenemanager.jpg differ diff --git a/dist/assets/img/libraries/p5.screenPosition.jpg b/dist/assets/img/libraries/p5.screenPosition.jpg new file mode 100644 index 0000000000..028c260c92 Binary files /dev/null and b/dist/assets/img/libraries/p5.screenPosition.jpg differ diff --git a/dist/assets/img/libraries/p5.scribble.jpg b/dist/assets/img/libraries/p5.scribble.jpg new file mode 100644 index 0000000000..9c8b613785 Binary files /dev/null and b/dist/assets/img/libraries/p5.scribble.jpg differ diff --git a/dist/assets/img/libraries/p5.serial.jpg b/dist/assets/img/libraries/p5.serial.jpg new file mode 100644 index 0000000000..a5d443e647 Binary files /dev/null and b/dist/assets/img/libraries/p5.serial.jpg differ diff --git a/dist/assets/img/libraries/p5.shape.js.jpg b/dist/assets/img/libraries/p5.shape.js.jpg new file mode 100644 index 0000000000..a13c941dbe Binary files /dev/null and b/dist/assets/img/libraries/p5.shape.js.jpg differ diff --git a/dist/assets/img/libraries/p5.sound.jpg b/dist/assets/img/libraries/p5.sound.jpg new file mode 100644 index 0000000000..ec13fe9f39 Binary files /dev/null and b/dist/assets/img/libraries/p5.sound.jpg differ diff --git a/dist/assets/img/libraries/p5.speech.jpg b/dist/assets/img/libraries/p5.speech.jpg new file mode 100644 index 0000000000..06556c7fc2 Binary files /dev/null and b/dist/assets/img/libraries/p5.speech.jpg differ diff --git a/dist/assets/img/libraries/p5.start.js.jpg b/dist/assets/img/libraries/p5.start.js.jpg new file mode 100644 index 0000000000..bdec92b8a3 Binary files /dev/null and b/dist/assets/img/libraries/p5.start.js.jpg differ diff --git a/dist/assets/img/libraries/p5.start2d.js.jpg b/dist/assets/img/libraries/p5.start2d.js.jpg new file mode 100644 index 0000000000..591381cf35 Binary files /dev/null and b/dist/assets/img/libraries/p5.start2d.js.jpg differ diff --git a/dist/assets/img/libraries/p5.tiledmap.jpg b/dist/assets/img/libraries/p5.tiledmap.jpg new file mode 100644 index 0000000000..a3c6fcda1e Binary files /dev/null and b/dist/assets/img/libraries/p5.tiledmap.jpg differ diff --git a/dist/assets/img/libraries/p5.touchgui.jpg b/dist/assets/img/libraries/p5.touchgui.jpg new file mode 100644 index 0000000000..677f7298b5 Binary files /dev/null and b/dist/assets/img/libraries/p5.touchgui.jpg differ diff --git a/dist/assets/img/libraries/p5.voronoi.jpg b/dist/assets/img/libraries/p5.voronoi.jpg new file mode 100644 index 0000000000..2cf921b5df Binary files /dev/null and b/dist/assets/img/libraries/p5.voronoi.jpg differ diff --git a/dist/assets/img/libraries/p5.xr.jpg b/dist/assets/img/libraries/p5.xr.jpg new file mode 100644 index 0000000000..bfea38b5ae Binary files /dev/null and b/dist/assets/img/libraries/p5.xr.jpg differ diff --git a/dist/assets/img/libraries/rita.js.jpg b/dist/assets/img/libraries/rita.js.jpg new file mode 100644 index 0000000000..5ac9c6c388 Binary files /dev/null and b/dist/assets/img/libraries/rita.js.jpg differ diff --git a/dist/assets/img/libraries/tramontana.jpg b/dist/assets/img/libraries/tramontana.jpg new file mode 100644 index 0000000000..615e7609b7 Binary files /dev/null and b/dist/assets/img/libraries/tramontana.jpg differ diff --git a/dist/assets/img/libraries/vida.jpg b/dist/assets/img/libraries/vida.jpg new file mode 100644 index 0000000000..98dbf474ba Binary files /dev/null and b/dist/assets/img/libraries/vida.jpg differ diff --git a/dist/assets/img/medium.svg b/dist/assets/img/medium.svg new file mode 100644 index 0000000000..e86110339e --- /dev/null +++ b/dist/assets/img/medium.svg @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/dist/assets/img/p5js-beta.svg b/dist/assets/img/p5js-beta.svg new file mode 100644 index 0000000000..0f4c46a0ad --- /dev/null +++ b/dist/assets/img/p5js-beta.svg @@ -0,0 +1,54 @@ + + + + + + diff --git a/dist/assets/img/p5js.svg b/dist/assets/img/p5js.svg new file mode 100644 index 0000000000..1492f8bf37 --- /dev/null +++ b/dist/assets/img/p5js.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + diff --git a/dist/assets/img/search.png b/dist/assets/img/search.png new file mode 100644 index 0000000000..472493680a Binary files /dev/null and b/dist/assets/img/search.png differ diff --git a/dist/assets/img/showcase/casey-louise/casey-louise_p5js-shaders.png b/dist/assets/img/showcase/casey-louise/casey-louise_p5js-shaders.png new file mode 100644 index 0000000000..e894579508 Binary files /dev/null and b/dist/assets/img/showcase/casey-louise/casey-louise_p5js-shaders.png differ diff --git a/dist/assets/img/showcase/daein-chung/daein-chung_chillin.png b/dist/assets/img/showcase/daein-chung/daein-chung_chillin.png new file mode 100644 index 0000000000..963a47d499 Binary files /dev/null and b/dist/assets/img/showcase/daein-chung/daein-chung_chillin.png differ diff --git a/dist/assets/img/showcase/moon-xin/moon-xin_poster-carlee.png b/dist/assets/img/showcase/moon-xin/moon-xin_poster-carlee.png new file mode 100644 index 0000000000..7044ea6101 Binary files /dev/null and b/dist/assets/img/showcase/moon-xin/moon-xin_poster-carlee.png differ diff --git a/dist/assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png b/dist/assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png new file mode 100644 index 0000000000..61a0752588 Binary files /dev/null and b/dist/assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png differ diff --git a/dist/assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png b/dist/assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png new file mode 100644 index 0000000000..062cda619f Binary files /dev/null and b/dist/assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png differ diff --git a/dist/assets/img/showcase/roni-cantor/roni-cantor_plotter-turquoise.jpg b/dist/assets/img/showcase/roni-cantor/roni-cantor_plotter-turquoise.jpg new file mode 100644 index 0000000000..ca237e56de Binary files /dev/null and b/dist/assets/img/showcase/roni-cantor/roni-cantor_plotter-turquoise.jpg differ diff --git a/dist/assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg b/dist/assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg new file mode 100644 index 0000000000..d75dbdcc95 Binary files /dev/null and b/dist/assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg differ diff --git a/dist/assets/img/test-image-0.jpg b/dist/assets/img/test-image-0.jpg new file mode 100644 index 0000000000..f15abb1137 Binary files /dev/null and b/dist/assets/img/test-image-0.jpg differ diff --git a/dist/assets/img/test-image-1.jpg b/dist/assets/img/test-image-1.jpg new file mode 100644 index 0000000000..7962b03ac5 Binary files /dev/null and b/dist/assets/img/test-image-1.jpg differ diff --git a/dist/assets/img/thick-asterisk-alone-gray.svg b/dist/assets/img/thick-asterisk-alone-gray.svg new file mode 100644 index 0000000000..0313c0e024 --- /dev/null +++ b/dist/assets/img/thick-asterisk-alone-gray.svg @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/dist/assets/img/thick-asterisk-alone.svg b/dist/assets/img/thick-asterisk-alone.svg new file mode 100644 index 0000000000..3da8f9959d --- /dev/null +++ b/dist/assets/img/thick-asterisk-alone.svg @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/dist/assets/js/examples.js b/dist/assets/js/examples.js new file mode 100644 index 0000000000..a6837add4b --- /dev/null +++ b/dist/assets/js/examples.js @@ -0,0 +1,200 @@ +var examples = { + init: function(file) { + + // Editor + + examples.editor = ace.edit('exampleEditor'); + //examples.editor.setTheme('ace/theme/monokai'); + examples.editor.getSession().setMode('ace/mode/javascript'); + examples.editor.getSession().setTabSize(2); + + examples.dims = []; + + // Button + + $('#runButton').click( function() { + examples.runExample(); + }); + $('#resetButton').click( function() { + examples.resetExample(); + }); + $('#copyButton').click( function() { + // don't know why we need this twice, or the setTimeout + // guessing it's some interaction with the editor.. + document.querySelector('textarea').select(); + $('textarea')[0].select(); + document.execCommand('copy'); + setTimeout(function() { document.execCommand('copy'); }, 200); + }); + + + // Example Frame + if($('#isMobile-displayButton').length !== 0) { + //it mobile + + $('#isMobile-displayButton').click( function() { + + $('#exampleFrame').show(); + $('#exampleFrame').ready(function() { + // alert('exampleFrame load') + examples.loadExample(true); + }); + }); + } else { + $('#exampleFrame').load(function() { + examples.loadExample(false); + }); + } + + + + // Capture clicks + + $.ajax({ + url: file, + dataType: 'text' + }) + .done(function (data) { + $('#exampleSelector').hide(); + + // parse and set frame size + var frameReg = /@frame (.*),(.*)/g; + var arr = data.split(frameReg); + if (arr.length > 2) { + examples.dims[0] = arr[1]; + examples.dims[1] = arr[2]; + } + + // render? + var norender = data.indexOf('@norender') !== -1; + + // parse and set name, aria label, and description + var metaReg = new RegExp('\\* ', 'g'); + var spaceReg = new RegExp(' ', 'g'); + + var startName = data.indexOf("@name")+6; + var endName = data.indexOf("\n", startName); + + var name = startName !== 5 ? data.substring(startName, endName) : ''; + + var startAriaLabel = data.indexOf("@arialabel")+11; + var endAriaLabel = data.indexOf("\n", startAriaLabel); + + var ariaLabel = startAriaLabel !== 10 ? data.substring(startAriaLabel, endAriaLabel) : ''; + + var startDesc = data.indexOf("@description")+13; + var endDesc = data.indexOf("*/", startDesc); + + var desc = startDesc !== 12 ? data.substring(startDesc, endDesc) : ''; + desc = desc.replace(metaReg, ''); + + $('#example-name').html(name); + $('#example-desc').html(desc); + $('#exampleFrame').attr("aria-label", ariaLabel); + + // strip description and set code + var ind = data.indexOf('*/'); + data = data.substring(ind+3); + examples.resetData = data; + + examples.showExample(norender); + }) + }, + showExample: function(norender) { + examples.editor.getSession().setValue(examples.resetData); + + //resize height of editor + var rows = examples.editor.getSession().$rowLengthCache.length; + var lineH = examples.editor.renderer.lineHeight; + $('#exampleEditor').height(rows*lineH+'px'); + + if (examples.resetData.indexOf('') !== -1) { + examples.editor.getSession().setMode('ace/mode/html'); + } + + if (norender) { + $('iframe').hide(); + $('#resetButton').hide(); + $('#runButton').hide(); + $('#copyButton').hide(); + } else { + examples.runExample(); + $('#exampleDisplay').show(); + } + }, + // display iframe + runExample: function() { + $('#exampleFrame').attr('src', $('#exampleFrame').attr('src')); + }, + resetExample: function() { + examples.showExample(); + }, + // load script into iframe + loadExample: function(isMobile) { + + var exampleCode = examples.editor.getSession().getValue(); + + try { + + if (exampleCode.indexOf('new p5()') === -1) { + exampleCode += '\nnew p5();'; + } + + if(isMobile) { + + $('#exampleFrame').css('position', 'fixed'); + $('#exampleFrame').css('top', '0px'); + $('#exampleFrame').css('left', '0px'); + $('#exampleFrame').css('right', '0px'); + $('#exampleFrame').css('bottom', '0px'); + $('#exampleFrame').css('z-index', '999'); + // var re = /createCanvas\((.*),(.*)\)/g; + // var arr = exampleCode.split(re); + // var height = $(screen).height(); + // var width = $(screen).width() + // $('#exampleFrame').css('height', height+'px'); + // $('#exampleFrame').css('width', width+'px'); + // console.log(height + ' ,' + width); + //exampleCode = exampleCode.replace(/windowWidth/, winWidth).replace(/windowHeight/, winHeight); + + // var userCSS = $('#exampleFrame')[0].contentWindow.document.createElement('style'); + // userCSS.type = 'text/css'; + // userCSS.innerHTML = 'html, body, canvas { width: 100% !important; height: 100% !important;}'; + //$('#exampleFrame')[0].contentWindow.document.head.appendChild(userCSS); + + } else { + if (examples.dims.length < 2) { + var re = /createCanvas\((.*),(.*)\)/g; + var arr = exampleCode.split(re); + $('#exampleFrame').height(arr[2]+'px'); + } else { + $('#exampleFrame').height(examples.dims[1]+'px'); + } + + } + + var userScript = $('#exampleFrame')[0].contentWindow.document.createElement('script'); + userScript.type = 'text/javascript'; + userScript.text = exampleCode; + userScript.async = false; + $('#exampleFrame')[0].contentWindow.document.body.appendChild(userScript); + + } catch (e) { + console.log(e.message); + } + } + +} +if (typeof(window._p5jsExample) !== 'undefined') { + examples.init(window._p5jsExample); +} + +// if (typeof(window._p5jsLanguage) !== 'undefined') { +// $('.example-link').each(function() { +// var name = $(this).data(window._p5jsLanguage); +// console.log(window._p5jsLanguage, name) +// $(this).text(name); +// }); +// } else { +// console.log('no language') +// } diff --git a/dist/assets/js/get-started.js b/dist/assets/js/get-started.js new file mode 100644 index 0000000000..4686d623e8 --- /dev/null +++ b/dist/assets/js/get-started.js @@ -0,0 +1,31 @@ +const copyToClipboard = (element)=> { + const value = document.getElementById(element).innerText; + const el = document.createElement('textarea'); + el.value = value; + el.setAttribute('readonly', ''); + el.style.position = 'absolute'; + el.style.left = '-9999px'; + el.setAttribute('aria-hidden','true'); + document.body.appendChild(el); + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); +} +$("#copy_sketch1").click(()=>{ + copyToClipboard("first-sketch1"); +}) +$("#copy_sketch2").click(()=>{ + copyToClipboard("first-sketch2"); +}); +$("#copy_sketch3").click(()=>{ + copyToClipboard("first-sketch3"); +}); +$("#copy_p5_script").click(()=>{ + copyToClipboard("markup1"); +}); +$("#copy_p5_link").click(()=>{ + copyToClipboard("cdn-link"); +}); +$("#copy_p5_html").click(()=>{ + copyToClipboard("sample-html"); +}); diff --git a/dist/assets/js/init.js b/dist/assets/js/init.js new file mode 100644 index 0000000000..f015d97d09 --- /dev/null +++ b/dist/assets/js/init.js @@ -0,0 +1,220 @@ +// ================================================= +// Family bar: +window.onload = function() { + + var test_js = function() { + // http://stackoverflow.com/a/12410668/1293700 + document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/,'') + ' js'; + }(); + var test_pointerevents = function() { + // https://github.com/ausi/Feature-detection-technique-for-pointer-events/blob/master/modernizr-pointerevents.js + var el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; + }; + if (test_pointerevents()) { + document.documentElement.className += ' pointerevents'; + } + + var search_form = document.getElementById('search_form'), + search_field = document.getElementById('search_field'); + if (search_form) { + var open_field = function() { + search_form.className = 'form__open'; + search_field.focus(); + }; + var close_field = function(e) { + if (e.type === 'focusout') { + search_form.className = ''; + } else { + if (search_field.value === '') { + search_form.className = ''; + } + } + }; + if (search_form.addEventListener) { + search_form.addEventListener('mouseover', open_field, false); + search_form.addEventListener('mouseout', close_field, false); + search_form.addEventListener('focusout', close_field, false); + } else { // IE + search_form.attachEvent('onmouseover', open_field); + search_form.attachEvent('onmouseout', close_field); + search_form.attachEvent('onfocusout', close_field); + } + } + + // ================================================= + // set language and tagline + var path = window.location.pathname; + var parts = path.split('/'); + for (var i=0; i>16&255,a[s++]=t>>8&255,a[s++]=255&t;2===i&&(t=u[e.charCodeAt(r)]<<2|u[e.charCodeAt(r+1)]>>4,a[s++]=255&t);1===i&&(t=u[e.charCodeAt(r)]<<10|u[e.charCodeAt(r+1)]<<4|u[e.charCodeAt(r+2)]>>2,a[s++]=t>>8&255,a[s++]=255&t);return a},r.fromByteArray=function(e){for(var t,r=e.length,n=r%3,o=[],i=0,a=r-n;i>2]+s[t<<4&63]+"==")):2==n&&(t=(e[r-2]<<8)+e[r-1],o.push(s[t>>10]+s[t>>4&63]+s[t<<2&63]+"="));return o.join("")};for(var s=[],u=[],c="undefined"!=typeof Uint8Array?Uint8Array:Array,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",o=0,i=n.length;o>18&63]+s[o>>12&63]+s[o>>6&63]+s[63&o]);return i.join("")}u["-".charCodeAt(0)]=62,u["_".charCodeAt(0)]=63},{}],2:[function(e,t,r){},{}],3:[function(e,t,r){arguments[4][2][0].apply(r,arguments)},{dup:2}],4:[function(U,e,N){(function(d){"use strict";var n=U("base64-js"),i=U("ieee754"),e="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;N.Buffer=d,N.SlowBuffer=function(e){+e!=e&&(e=0);return d.alloc(+e)},N.INSPECT_MAX_BYTES=50;var r=2147483647;function a(e){if(r>>1;case"base64":return A(e).length;default:if(o)return n?-1:P(e).length;t=(""+t).toLowerCase(),o=!0}}function h(e,t,r){var n=e[t];e[t]=e[r],e[r]=n}function p(e,t,r,n,o){if(0===e.length)return-1;if("string"==typeof r?(n=r,r=0):2147483647=e.length){if(o)return-1;r=e.length-1}else if(r<0){if(!o)return-1;r=0}if("string"==typeof t&&(t=d.from(t,n)),d.isBuffer(t))return 0===t.length?-1:y(e,t,r,n,o);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,r):Uint8Array.prototype.lastIndexOf.call(e,t,r):y(e,[t],r,n,o);throw new TypeError("val must be string, number or Buffer")}function y(e,t,r,n,o){var i,a=1,s=e.length,l=t.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(e.length<2||t.length<2)return-1;s/=a=2,l/=2,r/=2}function u(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}if(o){var c=-1;for(i=r;i>8,o=r%256,i.push(o),i.push(n);return i}(t,e.length-r),e,r,n)}function b(e,t,r){return 0===t&&r===e.length?n.fromByteArray(e):n.fromByteArray(e.slice(t,r))}function _(e,t,r){r=Math.min(e.length,r);for(var n=[],o=t;o>>10&1023|55296),c=56320|1023&c),n.push(c),o+=d}return function(e){var t=e.length;if(t<=x)return String.fromCharCode.apply(String,e);var r="",n=0;for(;nthis.length)return"";if((void 0===r||r>this.length)&&(r=this.length),r<=0)return"";if((r>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":return S(this,t,r);case"utf8":case"utf-8":return _(this,t,r);case"ascii":return w(this,t,r);case"latin1":case"binary":return j(this,t,r);case"base64":return b(this,t,r);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return M(this,t,r);default:if(n)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),n=!0}}.apply(this,arguments)},d.prototype.equals=function(e){if(!d.isBuffer(e))throw new TypeError("Argument must be a Buffer");return this===e||0===d.compare(this,e)},d.prototype.inspect=function(){var e="",t=N.INSPECT_MAX_BYTES;return e=this.toString("hex",0,t).replace(/(.{2})/g,"$1 ").trim(),this.length>t&&(e+=" ... "),""},e&&(d.prototype[e]=d.prototype.inspect),d.prototype.compare=function(e,t,r,n,o){if(R(e,Uint8Array)&&(e=d.from(e,e.offset,e.byteLength)),!d.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===r&&(r=e?e.length:0),void 0===n&&(n=0),void 0===o&&(o=this.length),t<0||r>e.length||n<0||o>this.length)throw new RangeError("out of range index");if(o<=n&&r<=t)return 0;if(o<=n)return-1;if(r<=t)return 1;if(this===e)return 0;for(var i=(o>>>=0)-(n>>>=0),a=(r>>>=0)-(t>>>=0),s=Math.min(i,a),l=this.slice(n,o),u=e.slice(t,r),c=0;c>>=0,isFinite(r)?(r>>>=0,void 0===n&&(n="utf8")):(n=r,r=void 0)}var o=this.length-t;if((void 0===r||othis.length)throw new RangeError("Attempt to write outside buffer bounds");n=n||"utf8";for(var i,a,s,l,u,c,d=!1;;)switch(n){case"hex":return m(this,e,t,r);case"utf8":case"utf-8":return u=t,c=r,k(P(e,(l=this).length-u),l,u,c);case"ascii":return g(this,e,t,r);case"latin1":case"binary":return g(this,e,t,r);case"base64":return i=this,a=t,s=r,k(A(e),i,a,s);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return v(this,e,t,r);default:if(d)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),d=!0}},d.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var x=4096;function w(e,t,r){var n="";r=Math.min(e.length,r);for(var o=t;oe.length)throw new RangeError("Index out of range")}function O(e,t,r,n){if(r+n>e.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("Index out of range")}function C(e,t,r,n,o){return t=+t,r>>>=0,o||O(e,0,r,4),i.write(e,t,r,n,23,4),r+4}function L(e,t,r,n,o){return t=+t,r>>>=0,o||O(e,0,r,8),i.write(e,t,r,n,52,8),r+8}d.prototype.slice=function(e,t){var r=this.length;(e=~~e)<0?(e+=r)<0&&(e=0):r>>=0,t>>>=0,r||E(e,t,this.length);for(var n=this[e],o=1,i=0;++i>>=0,t>>>=0,r||E(e,t,this.length);for(var n=this[e+--t],o=1;0>>=0,t||E(e,1,this.length),this[e]},d.prototype.readUInt16LE=function(e,t){return e>>>=0,t||E(e,2,this.length),this[e]|this[e+1]<<8},d.prototype.readUInt16BE=function(e,t){return e>>>=0,t||E(e,2,this.length),this[e]<<8|this[e+1]},d.prototype.readUInt32LE=function(e,t){return e>>>=0,t||E(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},d.prototype.readUInt32BE=function(e,t){return e>>>=0,t||E(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},d.prototype.readIntLE=function(e,t,r){e>>>=0,t>>>=0,r||E(e,t,this.length);for(var n=this[e],o=1,i=0;++i>>=0,t>>>=0,r||E(e,t,this.length);for(var n=t,o=1,i=this[e+--n];0>>=0,t||E(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},d.prototype.readInt16LE=function(e,t){e>>>=0,t||E(e,2,this.length);var r=this[e]|this[e+1]<<8;return 32768&r?4294901760|r:r},d.prototype.readInt16BE=function(e,t){e>>>=0,t||E(e,2,this.length);var r=this[e+1]|this[e]<<8;return 32768&r?4294901760|r:r},d.prototype.readInt32LE=function(e,t){return e>>>=0,t||E(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},d.prototype.readInt32BE=function(e,t){return e>>>=0,t||E(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},d.prototype.readFloatLE=function(e,t){return e>>>=0,t||E(e,4,this.length),i.read(this,e,!0,23,4)},d.prototype.readFloatBE=function(e,t){return e>>>=0,t||E(e,4,this.length),i.read(this,e,!1,23,4)},d.prototype.readDoubleLE=function(e,t){return e>>>=0,t||E(e,8,this.length),i.read(this,e,!0,52,8)},d.prototype.readDoubleBE=function(e,t){return e>>>=0,t||E(e,8,this.length),i.read(this,e,!1,52,8)},d.prototype.writeUIntLE=function(e,t,r,n){e=+e,t>>>=0,r>>>=0,n||T(this,e,t,r,Math.pow(2,8*r)-1,0);var o=1,i=0;for(this[t]=255&e;++i>>=0,r>>>=0,n||T(this,e,t,r,Math.pow(2,8*r)-1,0);var o=r-1,i=1;for(this[t+o]=255&e;0<=--o&&(i*=256);)this[t+o]=e/i&255;return t+r},d.prototype.writeUInt8=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,1,255,0),this[t]=255&e,t+1},d.prototype.writeUInt16LE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},d.prototype.writeUInt16BE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},d.prototype.writeUInt32LE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},d.prototype.writeUInt32BE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},d.prototype.writeIntLE=function(e,t,r,n){if(e=+e,t>>>=0,!n){var o=Math.pow(2,8*r-1);T(this,e,t,r,o-1,-o)}var i=0,a=1,s=0;for(this[t]=255&e;++i>0)-s&255;return t+r},d.prototype.writeIntBE=function(e,t,r,n){if(e=+e,t>>>=0,!n){var o=Math.pow(2,8*r-1);T(this,e,t,r,o-1,-o)}var i=r-1,a=1,s=0;for(this[t+i]=255&e;0<=--i&&(a*=256);)e<0&&0===s&&0!==this[t+i+1]&&(s=1),this[t+i]=(e/a>>0)-s&255;return t+r},d.prototype.writeInt8=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},d.prototype.writeInt16LE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},d.prototype.writeInt16BE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},d.prototype.writeInt32LE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},d.prototype.writeInt32BE=function(e,t,r){return e=+e,t>>>=0,r||T(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},d.prototype.writeFloatLE=function(e,t,r){return C(this,e,t,!0,r)},d.prototype.writeFloatBE=function(e,t,r){return C(this,e,t,!1,r)},d.prototype.writeDoubleLE=function(e,t,r){return L(this,e,t,!0,r)},d.prototype.writeDoubleBE=function(e,t,r){return L(this,e,t,!1,r)},d.prototype.copy=function(e,t,r,n){if(!d.isBuffer(e))throw new TypeError("argument should be a Buffer");if(r=r||0,n||0===n||(n=this.length),t>=e.length&&(t=e.length),t=t||0,0=this.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),e.length-t>>=0,r=void 0===r?this.length:r>>>0,"number"==typeof(e=e||0))for(i=t;i>6|192,63&r|128)}else if(r<65536){if((t-=3)<0)break;i.push(r>>12|224,r>>6&63|128,63&r|128)}else{if(!(r<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;i.push(r>>18|240,r>>12&63|128,r>>6&63|128,63&r|128)}}return i}function A(e){return n.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(t,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function k(e,t,r,n){for(var o=0;o=t.length||o>=e.length);++o)t[o+r]=e[o];return o}function R(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function D(e){return e!=e}var I=function(){for(var e="0123456789abcdef",t=new Array(256),r=0;r<16;++r)for(var n=16*r,o=0;o<16;++o)t[n+o]=e[r]+e[o];return t}()}).call(this,U("buffer").Buffer)},{"base64-js":1,buffer:4,ieee754:236}],5:[function(e,t,r){t.exports=function(e){if("function"!=typeof e)throw TypeError(String(e)+" is not a function");return e}},{}],6:[function(e,t,r){var n=e("../internals/is-object");t.exports=function(e){if(!n(e)&&null!==e)throw TypeError("Can't set "+String(e)+" as a prototype");return e}},{"../internals/is-object":74}],7:[function(e,t,r){var n=e("../internals/well-known-symbol"),o=e("../internals/object-create"),i=e("../internals/object-define-property"),a=n("unscopables"),s=Array.prototype;null==s[a]&&i.f(s,a,{configurable:!0,value:o(null)}),t.exports=function(e){s[a][e]=!0}},{"../internals/object-create":90,"../internals/object-define-property":92,"../internals/well-known-symbol":146}],8:[function(e,t,r){"use strict";var n=e("../internals/string-multibyte").charAt;t.exports=function(e,t,r){return t+(r?n(e,t).length:1)}},{"../internals/string-multibyte":123}],9:[function(e,t,r){t.exports=function(e,t,r){if(!(e instanceof t))throw TypeError("Incorrect "+(r?r+" ":"")+"invocation");return e}},{}],10:[function(e,t,r){var n=e("../internals/is-object");t.exports=function(e){if(!n(e))throw TypeError(String(e)+" is not an object");return e}},{"../internals/is-object":74}],11:[function(e,t,r){t.exports="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof DataView},{}],12:[function(e,t,r){"use strict";function n(e){return l(e)&&u(L,c(e))}var o,i=e("../internals/array-buffer-native"),a=e("../internals/descriptors"),s=e("../internals/global"),l=e("../internals/is-object"),u=e("../internals/has"),c=e("../internals/classof"),d=e("../internals/create-non-enumerable-property"),f=e("../internals/redefine"),h=e("../internals/object-define-property").f,p=e("../internals/object-get-prototype-of"),y=e("../internals/object-set-prototype-of"),m=e("../internals/well-known-symbol"),g=e("../internals/uid"),v=s.Int8Array,b=v&&v.prototype,_=s.Uint8ClampedArray,x=_&&_.prototype,w=v&&p(v),j=b&&p(b),S=Object.prototype,M=S.isPrototypeOf,E=m("toStringTag"),T=g("TYPED_ARRAY_TAG"),O=i&&!!y&&"Opera"!==c(s.opera),C=!1,L={Int8Array:1,Uint8Array:1,Uint8ClampedArray:1,Int16Array:2,Uint16Array:2,Int32Array:4,Uint32Array:4,Float32Array:4,Float64Array:8};for(o in L)s[o]||(O=!1);if((!O||"function"!=typeof w||w===Function.prototype)&&(w=function(){throw TypeError("Incorrect invocation")},O))for(o in L)s[o]&&y(s[o],w);if((!O||!j||j===S)&&(j=w.prototype,O))for(o in L)s[o]&&y(s[o].prototype,j);if(O&&p(x)!==j&&y(x,j),a&&!u(j,E))for(o in C=!0,h(j,E,{get:function(){return l(this)?this[T]:void 0}}),L)s[o]&&d(s[o],T,o);t.exports={NATIVE_ARRAY_BUFFER_VIEWS:O,TYPED_ARRAY_TAG:C&&T,aTypedArray:function(e){if(n(e))return e;throw TypeError("Target is not a typed array")},aTypedArrayConstructor:function(e){if(y){if(M.call(w,e))return e}else for(var t in L)if(u(L,o)){var r=s[t];if(r&&(e===r||M.call(r,e)))return e}throw TypeError("Target is not a typed array constructor")},exportTypedArrayMethod:function(e,t,r){if(a){if(r)for(var n in L){var o=s[n];o&&u(o.prototype,e)&&delete o.prototype[e]}j[e]&&!r||f(j,e,r?t:O&&b[e]||t)}},exportTypedArrayStaticMethod:function(e,t,r){var n,o;if(a){if(y){if(r)for(n in L)(o=s[n])&&u(o,e)&&delete o[e];if(w[e]&&!r)return;try{return f(w,e,r?t:O&&v[e]||t)}catch(e){}}for(n in L)!(o=s[n])||o[e]&&!r||f(o,e,t)}},isView:function(e){var t=c(e);return"DataView"===t||u(L,t)},isTypedArray:n,TypedArray:w,TypedArrayPrototype:j}},{"../internals/array-buffer-native":11,"../internals/classof":29,"../internals/create-non-enumerable-property":37,"../internals/descriptors":42,"../internals/global":59,"../internals/has":60,"../internals/is-object":74,"../internals/object-define-property":92,"../internals/object-get-prototype-of":97,"../internals/object-set-prototype-of":101,"../internals/redefine":108,"../internals/uid":143,"../internals/well-known-symbol":146}],13:[function(e,t,r){"use strict";function n(e){return[255&e]}function o(e){return[255&e,e>>8&255]}function i(e){return[255&e,e>>8&255,e>>16&255,e>>24&255]}function a(e){return e[3]<<24|e[2]<<16|e[1]<<8|e[0]}function s(e){return V(e,23,4)}function l(e){return V(e,52,8)}function u(e,t){E(e[R],t,{get:function(){return L(this)[t]}})}function c(e,t,r,n){var o=x(r),i=L(e);if(o+t>i.byteLength)throw G(D);var a=L(i.buffer).bytes,s=o+i.byteOffset,l=a.slice(s,s+t);return n?l:l.reverse()}function d(e,t,r,n,o,i){var a=x(r),s=L(e);if(a+t>s.byteLength)throw G(D);for(var l=L(s.buffer).bytes,u=a+s.byteOffset,c=n(+o),d=0;dX;)(H=q[X++])in U||y(U,H,I[H]);W.constructor=U}S&&j(F)!==B&&S(F,B);var Y=new N(new U(2)),Z=F.setInt8;Y.setInt8(0,2147483648),Y.setInt8(1,2147483649),!Y.getInt8(0)&&Y.getInt8(1)||m(F,{setInt8:function(e,t){Z.call(this,e,t<<24>>24)},setUint8:function(e,t){Z.call(this,e,t<<24>>24)}},{unsafe:!0})}else U=function(e){v(this,U,A);var t=x(e);P(this,{bytes:T.call(new Array(t),0),byteLength:t}),h||(this.byteLength=t)},N=function(e,t,r){v(this,N,k),v(e,U,k);var n=L(e).byteLength,o=b(t);if(o<0||n>24},getUint8:function(e){return c(this,1,e)[0]},getInt16:function(e,t){var r=c(this,2,e,1>16},getUint16:function(e,t){var r=c(this,2,e,1>>0},getFloat32:function(e,t){return z(c(this,4,e,1"+o+""}},{"../internals/require-object-coercible":113}],36:[function(e,t,r){"use strict";function o(){return this}var i=e("../internals/iterators-core").IteratorPrototype,a=e("../internals/object-create"),s=e("../internals/create-property-descriptor"),l=e("../internals/set-to-string-tag"),u=e("../internals/iterators");t.exports=function(e,t,r){var n=t+" Iterator";return e.prototype=a(i,{next:s(1,r)}),l(e,n,!1,!0),u[n]=o,e}},{"../internals/create-property-descriptor":38,"../internals/iterators":79,"../internals/iterators-core":78,"../internals/object-create":90,"../internals/set-to-string-tag":117}],37:[function(e,t,r){var n=e("../internals/descriptors"),o=e("../internals/object-define-property"),i=e("../internals/create-property-descriptor");t.exports=n?function(e,t,r){return o.f(e,t,i(1,r))}:function(e,t,r){return e[t]=r,e}},{"../internals/create-property-descriptor":38,"../internals/descriptors":42,"../internals/object-define-property":92}],38:[function(e,t,r){t.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},{}],39:[function(e,t,r){"use strict";var o=e("../internals/to-primitive"),i=e("../internals/object-define-property"),a=e("../internals/create-property-descriptor");t.exports=function(e,t,r){var n=o(t);n in e?i.f(e,n,a(0,r)):e[n]=r}},{"../internals/create-property-descriptor":38,"../internals/object-define-property":92,"../internals/to-primitive":138}],40:[function(e,t,r){"use strict";function g(){return this}var v=e("../internals/export"),b=e("../internals/create-iterator-constructor"),_=e("../internals/object-get-prototype-of"),x=e("../internals/object-set-prototype-of"),w=e("../internals/set-to-string-tag"),j=e("../internals/create-non-enumerable-property"),S=e("../internals/redefine"),n=e("../internals/well-known-symbol"),M=e("../internals/is-pure"),E=e("../internals/iterators"),o=e("../internals/iterators-core"),T=o.IteratorPrototype,O=o.BUGGY_SAFARI_ITERATORS,C=n("iterator"),L="values",P="entries";t.exports=function(e,t,r,n,o,i,a){b(r,t,n);function s(e){if(e===o&&y)return y;if(!O&&e in h)return h[e];switch(e){case"keys":case L:case P:return function(){return new r(this,e)}}return function(){return new r(this)}}var l,u,c,d=t+" Iterator",f=!1,h=e.prototype,p=h[C]||h["@@iterator"]||o&&h[o],y=!O&&p||s(o),m="Array"==t&&h.entries||p;if(m&&(l=_(m.call(new e)),T!==Object.prototype&&l.next&&(M||_(l)===T||(x?x(l,T):"function"!=typeof l[C]&&j(l,C,g)),w(l,d,!0,!0),M&&(E[d]=g))),o==L&&p&&p.name!==L&&(f=!0,y=function(){return p.call(this)}),M&&!a||h[C]===y||j(h,C,y),E[t]=y,o)if(u={values:s(L),keys:i?y:s("keys"),entries:s(P)},a)for(c in u)!O&&!f&&c in h||S(h,c,u[c]);else v({target:t,proto:!0,forced:O||f},u);return u}},{"../internals/create-iterator-constructor":36,"../internals/create-non-enumerable-property":37,"../internals/export":49,"../internals/is-pure":75,"../internals/iterators":79,"../internals/iterators-core":78,"../internals/object-get-prototype-of":97,"../internals/object-set-prototype-of":101,"../internals/redefine":108,"../internals/set-to-string-tag":117,"../internals/well-known-symbol":146}],41:[function(e,t,r){var n=e("../internals/path"),o=e("../internals/has"),i=e("../internals/well-known-symbol-wrapped"),a=e("../internals/object-define-property").f;t.exports=function(e){var t=n.Symbol||(n.Symbol={});o(t,e)||a(t,e,{value:i.f(e)})}},{"../internals/has":60,"../internals/object-define-property":92,"../internals/path":104,"../internals/well-known-symbol-wrapped":145}],42:[function(e,t,r){var n=e("../internals/fails");t.exports=!n(function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})},{"../internals/fails":50}],43:[function(e,t,r){var n=e("../internals/global"),o=e("../internals/is-object"),i=n.document,a=o(i)&&o(i.createElement);t.exports=function(e){return a?i.createElement(e):{}}},{"../internals/global":59,"../internals/is-object":74}],44:[function(e,t,r){t.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},{}],45:[function(e,t,r){var n=e("../internals/engine-user-agent");t.exports=/(iphone|ipod|ipad).*applewebkit/i.test(n)},{"../internals/engine-user-agent":46}],46:[function(e,t,r){var n=e("../internals/get-built-in");t.exports=n("navigator","userAgent")||""},{"../internals/get-built-in":56}],47:[function(e,t,r){var n,o,i=e("../internals/global"),a=e("../internals/engine-user-agent"),s=i.process,l=s&&s.versions,u=l&&l.v8;u?o=(n=u.split("."))[0]+n[1]:a&&(!(n=a.match(/Edge\/(\d+)/))||74<=n[1])&&(n=a.match(/Chrome\/(\d+)/))&&(o=n[1]),t.exports=o&&+o},{"../internals/engine-user-agent":46,"../internals/global":59}],48:[function(e,t,r){t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},{}],49:[function(e,t,r){var c=e("../internals/global"),d=e("../internals/object-get-own-property-descriptor").f,f=e("../internals/create-non-enumerable-property"),h=e("../internals/redefine"),p=e("../internals/set-global"),y=e("../internals/copy-constructor-properties"),m=e("../internals/is-forced");t.exports=function(e,t){var r,n,o,i,a,s=e.target,l=e.global,u=e.stat;if(r=l?c:u?c[s]||p(s,{}):(c[s]||{}).prototype)for(n in t){if(i=t[n],o=e.noTargetGet?(a=d(r,n))&&a.value:r[n],!m(l?n:s+(u?".":"#")+n,e.forced)&&void 0!==o){if(typeof i==typeof o)continue;y(i,o)}(e.sham||o&&o.sham)&&f(i,"sham",!0),h(r,n,i,e)}}},{"../internals/copy-constructor-properties":32,"../internals/create-non-enumerable-property":37,"../internals/global":59,"../internals/is-forced":73,"../internals/object-get-own-property-descriptor":93,"../internals/redefine":108,"../internals/set-global":115}],50:[function(e,t,r){t.exports=function(e){try{return!!e()}catch(e){return!0}}},{}],51:[function(e,t,r){"use strict";e("../modules/es.regexp.exec");var d=e("../internals/redefine"),f=e("../internals/fails"),h=e("../internals/well-known-symbol"),p=e("../internals/regexp-exec"),y=e("../internals/create-non-enumerable-property"),m=h("species"),g=!f(function(){var e=/./;return e.exec=function(){var e=[];return e.groups={a:"7"},e},"7"!=="".replace(e,"$")}),v="$0"==="a".replace(/./,"$0"),n=h("replace"),b=!!/./[n]&&""===/./[n]("a","$0"),_=!f(function(){var e=/(?:)/,t=e.exec;e.exec=function(){return t.apply(this,arguments)};var r="ab".split(e);return 2!==r.length||"a"!==r[0]||"b"!==r[1]});t.exports=function(r,e,t,n){var o=h(r),i=!f(function(){var e={};return e[o]=function(){return 7},7!=""[r](e)}),a=i&&!f(function(){var e=!1,t=/a/;return"split"===r&&((t={constructor:{}}).constructor[m]=function(){return t},t.flags="",t[o]=/./[o]),t.exec=function(){return e=!0,null},t[o](""),!e});if(!i||!a||"replace"===r&&(!g||!v||b)||"split"===r&&!_){var s=/./[o],l=t(o,""[r],function(e,t,r,n,o){return t.exec===p?i&&!o?{done:!0,value:s.call(t,r,n)}:{done:!0,value:e.call(r,t,n)}:{done:!1}},{REPLACE_KEEPS_$0:v,REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE:b}),u=l[0],c=l[1];d(String.prototype,r,u),d(RegExp.prototype,o,2==e?function(e,t){return c.call(e,this,t)}:function(e){return c.call(e,this)})}n&&y(RegExp.prototype[o],"sham",!0)}},{"../internals/create-non-enumerable-property":37,"../internals/fails":50,"../internals/redefine":108,"../internals/regexp-exec":110,"../internals/well-known-symbol":146,"../modules/es.regexp.exec":181}],52:[function(e,t,r){"use strict";var f=e("../internals/is-array"),h=e("../internals/to-length"),p=e("../internals/function-bind-context"),y=function(e,t,r,n,o,i,a,s){for(var l,u=o,c=0,d=!!a&&p(a,s,3);c>1,c=23===t?p(2,-24)-p(2,-77):0,d=e<0||0===e&&1/e<0?1:0,f=0;for((e=h(e))!=e||e===1/0?(o=e!=e?1:0,n=l):(n=y(m(e)/g),e*(i=p(2,-n))<1&&(n--,i*=2),2<=(e+=1<=n+u?c/i:c*p(2,1-u))*i&&(n++,i/=2),l<=n+u?(o=0,n=l):1<=n+u?(o=(e*i-1)*p(2,t),n+=u):(o=e*p(2,u-1)*p(2,t),n=0));8<=t;a[f++]=255&o,o/=256,t-=8);for(n=n<>1,s=o-7,l=n-1,u=e[l--],c=127&u;for(u>>=7;0>=-s,s+=t;0"+e+""}var i,a=e("../internals/an-object"),s=e("../internals/object-define-properties"),l=e("../internals/enum-bug-keys"),u=e("../internals/hidden-keys"),c=e("../internals/html"),d=e("../internals/document-create-element"),f=e("../internals/shared-key"),h="prototype",p="script",y=f("IE_PROTO"),m=function(){try{i=document.domain&&new ActiveXObject("htmlfile")}catch(e){}var e,t;m=i?function(e){e.write(o("")),e.close();var t=e.parentWindow.Object;return e=null,t}(i):((t=d("iframe")).style.display="none",c.appendChild(t),t.src=String("javascript:"),(e=t.contentWindow.document).open(),e.write(o("document.F=Object")),e.close(),e.F);for(var r=l.length;r--;)delete m[h][l[r]];return m()};u[y]=!0,t.exports=Object.create||function(e,t){var r;return null!==e?(n[h]=a(e),r=new n,n[h]=null,r[y]=e):r=m(),void 0===t?r:s(r,t)}},{"../internals/an-object":10,"../internals/document-create-element":43,"../internals/enum-bug-keys":48,"../internals/hidden-keys":61,"../internals/html":63,"../internals/object-define-properties":91,"../internals/shared-key":118}],91:[function(e,t,r){var n=e("../internals/descriptors"),a=e("../internals/object-define-property"),s=e("../internals/an-object"),l=e("../internals/object-keys");t.exports=n?Object.defineProperties:function(e,t){s(e);for(var r,n=l(t),o=n.length,i=0;io;)a(n,r=t[o++])&&(~l(i,r)||i.push(r));return i}},{"../internals/array-includes":18,"../internals/has":60,"../internals/hidden-keys":61,"../internals/to-indexed-object":132}],99:[function(e,t,r){var n=e("../internals/object-keys-internal"),o=e("../internals/enum-bug-keys");t.exports=Object.keys||function(e){return n(e,o)}},{"../internals/enum-bug-keys":48,"../internals/object-keys-internal":98}],100:[function(e,t,r){"use strict";var n={}.propertyIsEnumerable,o=Object.getOwnPropertyDescriptor,i=o&&!n.call({1:2},1);r.f=i?function(e){var t=o(this,e);return!!t&&t.enumerable}:n},{}],101:[function(e,t,r){var o=e("../internals/an-object"),i=e("../internals/a-possible-prototype");t.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var r,n=!1,e={};try{(r=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set).call(e,[]),n=e instanceof Array}catch(e){}return function(e,t){return o(e),i(t),n?r.call(e,t):e.__proto__=t,e}}():void 0)},{"../internals/a-possible-prototype":6,"../internals/an-object":10}],102:[function(e,t,r){"use strict";var n=e("../internals/to-string-tag-support"),o=e("../internals/classof");t.exports=n?{}.toString:function(){return"[object "+o(this)+"]"}},{"../internals/classof":29,"../internals/to-string-tag-support":139}],103:[function(e,t,r){var n=e("../internals/get-built-in"),o=e("../internals/object-get-own-property-names"),i=e("../internals/object-get-own-property-symbols"),a=e("../internals/an-object");t.exports=n("Reflect","ownKeys")||function(e){var t=o.f(a(e)),r=i.f;return r?t.concat(r(e)):t}},{"../internals/an-object":10,"../internals/get-built-in":56,"../internals/object-get-own-property-names":95,"../internals/object-get-own-property-symbols":96}],104:[function(e,t,r){var n=e("../internals/global");t.exports=n},{"../internals/global":59}],105:[function(e,t,r){t.exports=function(e){try{return{error:!1,value:e()}}catch(e){return{error:!0,value:e}}}},{}],106:[function(e,t,r){var n=e("../internals/an-object"),o=e("../internals/is-object"),i=e("../internals/new-promise-capability");t.exports=function(e,t){if(n(e),o(t)&&t.constructor===e)return t;var r=i.f(e);return(0,r.resolve)(t),r.promise}},{"../internals/an-object":10,"../internals/is-object":74,"../internals/new-promise-capability":86}],107:[function(e,t,r){var o=e("../internals/redefine");t.exports=function(e,t,r){for(var n in t)o(e,n,t[n],r);return e}},{"../internals/redefine":108}],108:[function(e,t,r){var s=e("../internals/global"),l=e("../internals/create-non-enumerable-property"),u=e("../internals/has"),c=e("../internals/set-global"),n=e("../internals/inspect-source"),o=e("../internals/internal-state"),i=o.get,d=o.enforce,f=String(String).split("String");(t.exports=function(e,t,r,n){var o=!!n&&!!n.unsafe,i=!!n&&!!n.enumerable,a=!!n&&!!n.noTargetGet;"function"==typeof r&&("string"!=typeof t||u(r,"name")||l(r,"name",t),d(r).source=f.join("string"==typeof t?t:"")),e!==s?(o?!a&&e[t]&&(i=!0):delete e[t],i?e[t]=r:l(e,t,r)):i?e[t]=r:c(t,r)})(Function.prototype,"toString",function(){return"function"==typeof this&&i(this).source||n(this)})},{"../internals/create-non-enumerable-property":37,"../internals/global":59,"../internals/has":60,"../internals/inspect-source":68,"../internals/internal-state":70,"../internals/set-global":115}],109:[function(e,t,r){var o=e("./classof-raw"),i=e("./regexp-exec");t.exports=function(e,t){var r=e.exec;if("function"==typeof r){var n=r.call(e,t);if("object"!=typeof n)throw TypeError("RegExp exec method returned something other than an Object or null");return n}if("RegExp"!==o(e))throw TypeError("RegExp#exec called on incompatible receiver");return i.call(e,t)}},{"./classof-raw":28,"./regexp-exec":110}],110:[function(e,t,r){"use strict";var n,o,d=e("./regexp-flags"),i=e("./regexp-sticky-helpers"),f=RegExp.prototype.exec,h=String.prototype.replace,a=f,p=(n=/a/,o=/b*/g,f.call(n,"a"),f.call(o,"a"),0!==n.lastIndex||0!==o.lastIndex),y=i.UNSUPPORTED_Y||i.BROKEN_CARET,m=void 0!==/()??/.exec("")[1];(p||m||y)&&(a=function(e){var t,r,n,o,i=this,a=y&&i.sticky,s=d.call(i),l=i.source,u=0,c=e;return a&&(-1===(s=s.replace("y","")).indexOf("g")&&(s+="g"),c=String(e).slice(i.lastIndex),0>1,e+=x(e/t);455x((b-a)/d))throw RangeError(_);for(a+=(c-i)*d,i=c,t=0;tb)throw RangeError(_);if(r==i){for(var f=a,h=36;;h+=36){var p=h<=s?1:s+26<=h?26:h-s;if(f>>=1)&&(t+=t))1&n&&(r+=t);return r}},{"../internals/require-object-coercible":113,"../internals/to-integer":133}],126:[function(e,t,r){var n=e("../internals/fails"),o=e("../internals/whitespaces");t.exports=function(e){return n(function(){return!!o[e]()||"​…᠎"!="​…᠎"[e]()||o[e].name!==e})}},{"../internals/fails":50,"../internals/whitespaces":147}],127:[function(e,t,r){function n(r){return function(e){var t=String(o(e));return 1&r&&(t=t.replace(a,"")),2&r&&(t=t.replace(s,"")),t}}var o=e("../internals/require-object-coercible"),i="["+e("../internals/whitespaces")+"]",a=RegExp("^"+i+i+"*"),s=RegExp(i+i+"*$");t.exports={start:n(1),end:n(2),trim:n(3)}},{"../internals/require-object-coercible":113,"../internals/whitespaces":147}],128:[function(e,t,r){function n(e){if(S.hasOwnProperty(e)){var t=S[e];delete S[e],t()}}function o(e){return function(){n(e)}}function i(e){n(e.data)}function a(e){c.postMessage(e+"",g.protocol+"//"+g.host)}var s,l,u,c=e("../internals/global"),d=e("../internals/fails"),f=e("../internals/classof-raw"),h=e("../internals/function-bind-context"),p=e("../internals/html"),y=e("../internals/document-create-element"),m=e("../internals/engine-is-ios"),g=c.location,v=c.setImmediate,b=c.clearImmediate,_=c.process,x=c.MessageChannel,w=c.Dispatch,j=0,S={},M="onreadystatechange";v&&b||(v=function(e){for(var t=[],r=1;r=t.length?{value:e.target=void 0,done:!0}:"keys"==r?{value:n,done:!1}:"values"==r?{value:t[n],done:!1}:{value:[n,t[n]],done:!1}},"values"),i.Arguments=i.Array,o("keys"),o("values"),o("entries")},{"../internals/add-to-unscopables":7,"../internals/define-iterator":40,"../internals/internal-state":70,"../internals/iterators":79,"../internals/to-indexed-object":132}],159:[function(e,t,r){"use strict";var n=e("../internals/export"),o=e("../internals/indexed-object"),i=e("../internals/to-indexed-object"),a=e("../internals/array-method-is-strict"),s=[].join,l=o!=Object,u=a("join",",");n({target:"Array",proto:!0,forced:l||!u},{join:function(e){return s.call(i(this),void 0===e?",":e)}})},{"../internals/array-method-is-strict":22,"../internals/export":49,"../internals/indexed-object":66,"../internals/to-indexed-object":132}],160:[function(e,t,r){var n=e("../internals/export"),o=e("../internals/array-last-index-of");n({target:"Array",proto:!0,forced:o!==[].lastIndexOf},{lastIndexOf:o})},{"../internals/array-last-index-of":20,"../internals/export":49}],161:[function(e,t,r){"use strict";var n=e("../internals/export"),o=e("../internals/array-iteration").map,i=e("../internals/array-method-has-species-support"),a=e("../internals/array-method-uses-to-length"),s=i("map"),l=a("map");n({target:"Array",proto:!0,forced:!s||!l},{map:function(e,t){return o(this,e,1M;M++)l(b,w=S[M])&&!l(j,w)&&m(j,w,y(b,w));(j.prototype=_).constructor=j,s(i,v,j)}},{"../internals/classof-raw":28,"../internals/descriptors":42,"../internals/fails":50,"../internals/global":59,"../internals/has":60,"../internals/inherit-if-required":67,"../internals/is-forced":73,"../internals/object-create":90,"../internals/object-define-property":92,"../internals/object-get-own-property-descriptor":93,"../internals/object-get-own-property-names":95,"../internals/redefine":108,"../internals/string-trim":127,"../internals/to-primitive":138}],171:[function(e,t,r){e("../internals/export")({target:"Number",stat:!0},{isFinite:e("../internals/number-is-finite")})},{"../internals/export":49,"../internals/number-is-finite":88}],172:[function(e,t,r){"use strict";var n=e("../internals/export"),h=e("../internals/to-integer"),p=e("../internals/this-number-value"),y=e("../internals/string-repeat"),o=e("../internals/fails"),i=1..toFixed,m=Math.floor,g=function(e,t,r){return 0===t?r:t%2==1?g(e,t-1,r*e):g(e*e,t/2,r)};n({target:"Number",proto:!0,forced:i&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!o(function(){i.call({})})},{toFixed:function(e){function t(e,t){for(var r=-1,n=t;++r<6;)n+=e*c[r],c[r]=n%1e7,n=m(n/1e7)}function r(e){for(var t=6,r=0;0<=--t;)r+=c[t],c[t]=m(r/e),r=r%e*1e7}function n(){for(var e=6,t="";0<=--e;)if(""!==t||0===e||0!==c[e]){var r=String(c[e]);t=""===t?r:t+y.call("0",7-r.length)+r}return t}var o,i,a,s,l=p(this),u=h(e),c=[0,0,0,0,0,0],d="",f="0";if(u<0||20r;){var n,o,i,a=p[r++],s=t?a.ok:a.fail,l=a.resolve,u=a.reject,c=a.domain;try{s?(t||(2===f.rejection&&oe(d,f),f.rejection=1),!0===s?n=e:(c&&c.enter(),n=s(e),c&&(c.exit(),i=!0)),n===a.promise?u(W("Promise-chain cycle")):(o=y(n))?o.call(n,l,u):l(n)):u(e)}catch(e){c&&!i&&c.exit(),u(e)}}f.reactions=[],f.notified=!1,h&&!f.rejection&&re(d,f)})}}function o(e,t,r){var n,o;J?((n=q.createEvent("Event")).promise=t,n.reason=r,n.initEvent(e,!1,!0),h.dispatchEvent(n)):n={promise:t,reason:r},(o=h["on"+e])?o(n):e===$&&A("Unhandled promise rejection",r)}function a(t,r,n,o){return function(e){t(r,n,e,o)}}function s(e,t,r,n){t.done||(t.done=!0,n&&(t=n),t.value=r,t.state=2,i(e,t,!0))}var n,l,u,c,d=e("../internals/export"),f=e("../internals/is-pure"),h=e("../internals/global"),p=e("../internals/get-built-in"),m=e("../internals/native-promise-constructor"),g=e("../internals/redefine"),v=e("../internals/redefine-all"),b=e("../internals/set-to-string-tag"),_=e("../internals/set-species"),x=e("../internals/is-object"),w=e("../internals/a-function"),j=e("../internals/an-instance"),S=e("../internals/classof-raw"),M=e("../internals/inspect-source"),E=e("../internals/iterate"),T=e("../internals/check-correctness-of-iteration"),O=e("../internals/species-constructor"),C=e("../internals/task").set,L=e("../internals/microtask"),P=e("../internals/promise-resolve"),A=e("../internals/host-report-errors"),k=e("../internals/new-promise-capability"),R=e("../internals/perform"),D=e("../internals/internal-state"),I=e("../internals/is-forced"),U=e("../internals/well-known-symbol"),N=e("../internals/engine-v8-version"),F=U("species"),B="Promise",G=D.get,V=D.set,z=D.getterFor(B),H=m,W=h.TypeError,q=h.document,X=h.process,Y=p("fetch"),Z=k.f,Q=Z,K="process"==S(X),J=!!(q&&q.createEvent&&h.dispatchEvent),$="unhandledrejection",ee=I(B,function(){if(!(M(H)!==String(H))){if(66===N)return!0;if(!K&&"function"!=typeof PromiseRejectionEvent)return!0}if(f&&!H.prototype.finally)return!0;if(51<=N&&/native code/.test(H))return!1;function e(e){e(function(){},function(){})}var t=H.resolve(1);return(t.constructor={})[F]=e,!(t.then(function(){})instanceof e)}),te=ee||!T(function(e){H.all(e).catch(function(){})}),re=function(r,n){C.call(h,function(){var e,t=n.value;if(ne(n)&&(e=R(function(){K?X.emit("unhandledRejection",t,r):o($,r,t)}),n.rejection=K||ne(n)?2:1,e.error))throw e.value})},ne=function(e){return 1!==e.rejection&&!e.parent},oe=function(e,t){C.call(h,function(){K?X.emit("rejectionHandled",e):o("rejectionhandled",e,t.value)})},ie=function(r,n,e,t){if(!n.done){n.done=!0,t&&(n=t);try{if(r===e)throw W("Promise can't be resolved itself");var o=y(e);o?L(function(){var t={done:!1};try{o.call(e,a(ie,r,t,n),a(s,r,t,n))}catch(e){s(r,t,e,n)}}):(n.value=e,n.state=1,i(r,n,!1))}catch(e){s(r,{done:!1},e,n)}}};ee&&(H=function(e){j(this,H,B),w(e),n.call(this);var t=G(this);try{e(a(ie,this,t),a(s,this,t))}catch(e){s(this,t,e)}},(n=function(){V(this,{type:B,done:!1,notified:!1,parent:!1,reactions:[],rejection:!1,state:0,value:void 0})}).prototype=v(H.prototype,{then:function(e,t){var r=z(this),n=Z(O(this,H));return n.ok="function"!=typeof e||e,n.fail="function"==typeof t&&t,n.domain=K?X.domain:void 0,r.parent=!0,r.reactions.push(n),0!=r.state&&i(this,r,!1),n.promise},catch:function(e){return this.then(void 0,e)}}),l=function(){var e=new n,t=G(e);this.promise=e,this.resolve=a(ie,e,t),this.reject=a(s,e,t)},k.f=Z=function(e){return e===H||e===u?new l(e):Q(e)},f||"function"!=typeof m||(c=m.prototype.then,g(m.prototype,"then",function(e,t){var r=this;return new H(function(e,t){c.call(r,e,t)}).then(e,t)},{unsafe:!0}),"function"==typeof Y&&d({global:!0,enumerable:!0,forced:!0},{fetch:function(e){return P(H,Y.apply(h,arguments))}}))),d({global:!0,wrap:!0,forced:ee},{Promise:H}),b(H,B,!1,!0),_(B),u=p(B),d({target:B,stat:!0,forced:ee},{reject:function(e){var t=Z(this);return t.reject.call(void 0,e),t.promise}}),d({target:B,stat:!0,forced:f||ee},{resolve:function(e){return P(f&&this===u?H:this,e)}}),d({target:B,stat:!0,forced:te},{all:function(e){var s=this,t=Z(s),l=t.resolve,u=t.reject,r=R(function(){var n=w(s.resolve),o=[],i=0,a=1;E(e,function(e){var t=i++,r=!1;o.push(void 0),a++,n.call(s,e).then(function(e){r||(r=!0,o[t]=e,--a||l(o))},u)}),--a||l(o)});return r.error&&u(r.value),t.promise},race:function(e){var r=this,n=Z(r),o=n.reject,t=R(function(){var t=w(r.resolve);E(e,function(e){t.call(r,e).then(n.resolve,o)})});return t.error&&o(t.value),n.promise}})},{"../internals/a-function":5,"../internals/an-instance":9,"../internals/check-correctness-of-iteration":27,"../internals/classof-raw":28,"../internals/engine-v8-version":47,"../internals/export":49,"../internals/get-built-in":56,"../internals/global":59,"../internals/host-report-errors":62,"../internals/inspect-source":68,"../internals/internal-state":70,"../internals/is-forced":73,"../internals/is-object":74,"../internals/is-pure":75,"../internals/iterate":77,"../internals/microtask":81,"../internals/native-promise-constructor":82,"../internals/new-promise-capability":86,"../internals/perform":105,"../internals/promise-resolve":106,"../internals/redefine":108,"../internals/redefine-all":107,"../internals/set-species":116,"../internals/set-to-string-tag":117,"../internals/species-constructor":121,"../internals/task":128,"../internals/well-known-symbol":146}],179:[function(e,t,r){var n=e("../internals/export"),o=e("../internals/get-built-in"),l=e("../internals/a-function"),u=e("../internals/an-object"),c=e("../internals/is-object"),d=e("../internals/object-create"),f=e("../internals/function-bind"),i=e("../internals/fails"),h=o("Reflect","construct"),p=i(function(){function e(){}return!(h(function(){},[],e)instanceof e)}),y=!i(function(){h(function(){})}),a=p||y;n({target:"Reflect",stat:!0,forced:a,sham:a},{construct:function(e,t,r){l(e),u(t);var n=arguments.length<3?e:l(r);if(y&&!p)return h(e,t,n);if(e==n){switch(t.length){case 0:return new e;case 1:return new e(t[0]);case 2:return new e(t[0],t[1]);case 3:return new e(t[0],t[1],t[2]);case 4:return new e(t[0],t[1],t[2],t[3])}var o=[null];return o.push.apply(o,t),new(f.apply(e,o))}var i=n.prototype,a=d(c(i)?i:Object.prototype),s=Function.apply.call(e,a,t);return c(s)?s:a}})},{"../internals/a-function":5,"../internals/an-object":10,"../internals/export":49,"../internals/fails":50,"../internals/function-bind":55,"../internals/get-built-in":56,"../internals/is-object":74,"../internals/object-create":90}],180:[function(e,t,r){var n=e("../internals/descriptors"),o=e("../internals/global"),i=e("../internals/is-forced"),s=e("../internals/inherit-if-required"),a=e("../internals/object-define-property").f,l=e("../internals/object-get-own-property-names").f,u=e("../internals/is-regexp"),c=e("../internals/regexp-flags"),d=e("../internals/regexp-sticky-helpers"),f=e("../internals/redefine"),h=e("../internals/fails"),p=e("../internals/internal-state").set,y=e("../internals/set-species"),m=e("../internals/well-known-symbol")("match"),g=o.RegExp,v=g.prototype,b=/a/g,_=/a/g,x=new g(b)!==b,w=d.UNSUPPORTED_Y;if(n&&i("RegExp",!x||w||h(function(){return _[m]=!1,g(b)!=b||g(_)==_||"/a/i"!=g(b,"i")}))){function j(t){t in S||a(S,t,{configurable:!0,get:function(){return g[t]},set:function(e){g[t]=e}})}for(var S=function(e,t){var r,n=this instanceof S,o=u(e),i=void 0===t;if(!n&&o&&e.constructor===S&&i)return e;x?o&&!i&&(e=e.source):e instanceof S&&(i&&(t=c.call(e)),e=e.source),w&&(r=!!t&&-1E;)j(M[E++]);(v.constructor=S).prototype=v,f(o,"RegExp",S)}y("RegExp")},{"../internals/descriptors":42,"../internals/fails":50,"../internals/global":59,"../internals/inherit-if-required":67,"../internals/internal-state":70,"../internals/is-forced":73,"../internals/is-regexp":76,"../internals/object-define-property":92,"../internals/object-get-own-property-names":95,"../internals/redefine":108,"../internals/regexp-flags":111,"../internals/regexp-sticky-helpers":112,"../internals/set-species":116,"../internals/well-known-symbol":146}],181:[function(e,t,r){"use strict";var n=e("../internals/export"),o=e("../internals/regexp-exec");n({target:"RegExp",proto:!0,forced:/./.exec!==o},{exec:o})},{"../internals/export":49,"../internals/regexp-exec":110}],182:[function(e,t,r){"use strict";var n=e("../internals/redefine"),o=e("../internals/an-object"),i=e("../internals/fails"),a=e("../internals/regexp-flags"),s="toString",l=RegExp.prototype,u=l[s],c=i(function(){return"/a/b"!=u.call({source:"a",flags:"b"})}),d=u.name!=s;(c||d)&&n(RegExp.prototype,s,function(){var e=o(this),t=String(e.source),r=e.flags;return"/"+t+"/"+String(void 0===r&&e instanceof RegExp&&!("flags"in l)?a.call(e):r)},{unsafe:!0})},{"../internals/an-object":10,"../internals/fails":50,"../internals/redefine":108,"../internals/regexp-flags":111}],183:[function(e,t,r){"use strict";var n=e("../internals/collection"),o=e("../internals/collection-strong");t.exports=n("Set",function(t){return function(e){return t(this,arguments.length?e:void 0)}},o)},{"../internals/collection":31,"../internals/collection-strong":30}],184:[function(e,t,r){"use strict";var n,o=e("../internals/export"),i=e("../internals/object-get-own-property-descriptor").f,s=e("../internals/to-length"),l=e("../internals/not-a-regexp"),u=e("../internals/require-object-coercible"),a=e("../internals/correct-is-regexp-logic"),c=e("../internals/is-pure"),d="".endsWith,f=Math.min,h=a("endsWith");o({target:"String",proto:!0,forced:!!(c||h||(!(n=i(String.prototype,"endsWith"))||n.writable))&&!h},{endsWith:function(e,t){var r=String(u(this));l(e);var n=1=r.length?{value:void 0,done:!0}:(e=o(r,n),t.index+=e.length,{value:e,done:!1})})},{"../internals/define-iterator":40,"../internals/internal-state":70,"../internals/string-multibyte":123}],187:[function(e,t,r){"use strict";var n=e("../internals/fix-regexp-well-known-symbol-logic"),d=e("../internals/an-object"),f=e("../internals/to-length"),o=e("../internals/require-object-coercible"),h=e("../internals/advance-string-index"),p=e("../internals/regexp-exec-abstract");n("match",1,function(n,u,c){return[function(e){var t=o(this),r=null==e?void 0:e[n];return void 0!==r?r.call(e,t):new RegExp(e)[n](String(t))},function(e){var t=c(u,e,this);if(t.done)return t.value;var r=d(e),n=String(this);if(!r.global)return p(r,n);for(var o,i=r.unicode,a=[],s=r.lastIndex=0;null!==(o=p(r,n));){var l=String(o[0]);""===(a[s]=l)&&(r.lastIndex=h(n,f(r.lastIndex),i)),s++}return 0===s?null:a}]})},{"../internals/advance-string-index":8,"../internals/an-object":10,"../internals/fix-regexp-well-known-symbol-logic":51,"../internals/regexp-exec-abstract":109,"../internals/require-object-coercible":113,"../internals/to-length":134}],188:[function(e,t,r){e("../internals/export")({target:"String",proto:!0},{repeat:e("../internals/string-repeat")})},{"../internals/export":49,"../internals/string-repeat":125}],189:[function(e,t,r){"use strict";var n=e("../internals/fix-regexp-well-known-symbol-logic"),T=e("../internals/an-object"),f=e("../internals/to-object"),O=e("../internals/to-length"),C=e("../internals/to-integer"),i=e("../internals/require-object-coercible"),L=e("../internals/advance-string-index"),P=e("../internals/regexp-exec-abstract"),A=Math.max,k=Math.min,h=Math.floor,p=/\$([$&'`]|\d\d?|<[^>]*>)/g,y=/\$([$&'`]|\d\d?)/g;n("replace",2,function(o,x,w,e){var j=e.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE,S=e.REPLACE_KEEPS_$0,M=j?"$":"$0";return[function(e,t){var r=i(this),n=null==e?void 0:e[o];return void 0!==n?n.call(e,r,t):x.call(String(r),e,t)},function(e,t){if(!j&&S||"string"==typeof t&&-1===t.indexOf(M)){var r=w(x,e,this,t);if(r.done)return r.value}var n=T(e),o=String(this),i="function"==typeof t;i||(t=String(t));var a=n.global;if(a){var s=n.unicode;n.lastIndex=0}for(var l=[];;){var u=P(n,o);if(null===u)break;if(l.push(u),!a)break;""===String(u[0])&&(n.lastIndex=L(o,O(n.lastIndex),s))}for(var c,d="",f=0,h=0;h>>0;if(0==n)return[];if(void 0===e)return[r];if(!d(e))return m.call(r,e,n);for(var o,i,a,s=[],l=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.unicode?"u":"")+(e.sticky?"y":""),u=0,c=new RegExp(e.source,l+"g");(o=h.call(c,r))&&!(u<(i=c.lastIndex)&&(s.push(r.slice(u,o.index)),1=n));)c.lastIndex===o.index&&c.lastIndex++;return u===r.length?!a&&c.test("")||s.push(""):s.push(r.slice(u)),s.length>n?s.slice(0,n):s}:"0".split(void 0,0).length?function(e,t){return void 0===e&&0===t?[]:m.call(this,e,t)}:m,[function(e,t){var r=f(this),n=null==e?void 0:e[o];return void 0!==n?n.call(e,r,t):v.call(String(r),e,t)},function(e,t){var r=g(v,e,this,t,v!==m);if(r.done)return r.value;var n=b(e),o=String(this),i=_(n,RegExp),a=n.unicode,s=(n.ignoreCase?"i":"")+(n.multiline?"m":"")+(n.unicode?"u":"")+(E?"y":"g"),l=new i(E?n:"^(?:"+n.source+")",s),u=void 0===t?M:t>>>0;if(0==u)return[];if(0===o.length)return null===j(l,o)?[o]:[];for(var c=0,d=0,f=[];de.key){o.splice(t,0,e);break}t===r&&o.push(e)}n.updateURL()},forEach:function(e,t){for(var r,n=D(this).entries,o=_(e,1=R(256,5-t))return null}else if(255":1,"`":1}),$=p({},J,{"#":1,"?":1,"{":1,"}":1}),ee=p({},$,{"/":1,":":1,";":1,"=":1,"@":1,"[":1,"\\":1,"]":1,"^":1,"|":1}),te=function(e,t){var r=y(e,0);return 32>1,c=-7,d=r?o-1:0,f=r?-1:1,h=e[t+d];for(d+=f,i=h&(1<<-c)-1,h>>=-c,c+=s;0>=-c,c+=n;0>1,f=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=n?0:i-1,p=n?1:-1,y=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=c):(a=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-a))<1&&(a--,l*=2),2<=(t+=1<=a+d?f/l:f*Math.pow(2,1-d))*l&&(a++,l/=2),c<=a+d?(s=0,a=c):1<=a+d?(s=(t*l-1)*Math.pow(2,o),a+=d):(s=t*Math.pow(2,d-1)*Math.pow(2,o),a=0));8<=o;e[r+h]=255&s,h+=p,s/=256,o-=8);for(a=a<Math.abs(e[0])&&(t=1),Math.abs(e[2])>Math.abs(e[t])&&(t=2),t}function T(e,t){e.f+=t.f,e.b.f+=t.b.f}function u(e,t,r){return e=e.a,t=t.a,r=r.a,t.b.a===e?r.b.a===e?g(t.a,r.a)?b(r.b.a,t.a,r.a)<=0:0<=b(t.b.a,r.a,t.a):b(r.b.a,e,r.a)<=0:r.b.a===e?0<=b(t.b.a,e,t.a):(t=v(t.b.a,e,t.a),(e=v(r.b.a,e,r.a))<=t)}function O(e){e.a.i=null;var t=e.e;t.a.c=t.c,t.c.a=t.a,e.e=null}function c(e,t){d(e.a),e.c=!1,(e.a=t).i=e}function C(e){for(var t=e.a.a;(e=de(e)).a.a===t;);return e.c&&(c(e,t=f(ce(e).a.b,e.a.e)),e=de(e)),e}function L(e,t,r){var n=new ue;return n.a=r,n.e=H(e.f,t.e,n),r.i=n}function P(e,t){switch(e.s){case 100130:return 0!=(1&t);case 100131:return 0!==t;case 100132:return 0>1]],s[a[u]])?se(r,u):le(r,u)),s[i]=null,l[i]=r.b,r.b=i}else for(r.c[-(i+1)]=null;0Math.max(a.a,l.a))return!1;if(g(i,a)){if(0n.f&&(n.f*=2,n.c=oe(n.c,n.f+1)),0===n.b?r=o:(r=n.b,n.b=n.c[n.b]),n.e[r]=t,n.c[r]=o,n.d[o]=r,n.h&&le(n,o),r}return n=e.a++,e.c[n]=t,-(n+1)}function re(e){if(0===e.a)return ae(e.b);var t=e.c[e.d[e.a-1]];if(0!==e.b.a&&g(ie(e.b),t))return ae(e.b);for(;--e.a,0e.a||g(n[a],n[l])){o[r[i]=a]=i;break}o[r[i]=l]=i,i=s}}function le(e,t){for(var r=e.d,n=e.e,o=e.c,i=t,a=r[i];;){var s=i>>1,l=r[s];if(0==s||g(n[l],n[a])){o[r[i]=a]=i;break}o[r[i]=l]=i,i=s}}function ue(){this.e=this.a=null,this.f=0,this.c=this.b=this.h=this.d=!1}function ce(e){return e.e.c.b}function de(e){return e.e.a.b}(n=q.prototype).x=function(){X(this,0)},n.B=function(e,t){switch(e){case 100142:return;case 100140:switch(t){case 100130:case 100131:case 100132:case 100133:case 100134:return void(this.s=t)}break;case 100141:return void(this.m=!!t);default:return void Y(this,100900)}Y(this,100901)},n.y=function(e){switch(e){case 100142:return 0;case 100140:return this.s;case 100141:return this.m;default:Y(this,100900)}return!1},n.A=function(e,t,r){this.j[0]=e,this.j[1]=t,this.j[2]=r},n.z=function(e,t){var r=t||null;switch(e){case 100100:case 100106:this.h=r;break;case 100104:case 100110:this.l=r;break;case 100101:case 100107:this.k=r;break;case 100102:case 100108:this.i=r;break;case 100103:case 100109:this.p=r;break;case 100105:case 100111:this.o=r;break;case 100112:this.r=r;break;default:Y(this,100900)}},n.C=function(e,t){var r=!1,n=[0,0,0];X(this,2);for(var o=0;o<3;++o){var i=e[o];i<-1e150&&(i=-1e150,r=!0),1e150o[u]&&(o[u]=c,a[u]=l)}if(l=0,o[1]-i[1]>o[0]-i[0]&&(l=1),o[2]-i[2]>o[l]-i[l]&&(l=2),i[l]>=o[l])n[0]=0,n[1]=0,n[2]=1;else{for(o=0,i=s[l],a=a[l],s=[0,0,0],i=[i.g[0]-a.g[0],i.g[1]-a.g[1],i.g[2]-a.g[2]],u=[0,0,0],l=r.e;l!==r;l=l.e)u[0]=l.g[0]-a.g[0],u[1]=l.g[1]-a.g[1],u[2]=l.g[2]-a.g[2],s[0]=i[1]*u[2]-i[2]*u[1],s[1]=i[2]*u[0]-i[0]*u[2],s[2]=i[0]*u[1]-i[1]*u[0],o<(c=s[0]*s[0]+s[1]*s[1]+s[2]*s[2])&&(o=c,n[0]=s[0],n[1]=s[1],n[2]=s[2]);o<=0&&(n[0]=n[1]=n[2]=0,n[E(i)]=1)}r=!0}for(s=E(n),l=this.b.c,o=(s+1)%3,a=(s+2)%3,s=0>=l,c-=l,m!=i){if(m==a)break;for(var g=m>8,++v;var _=b;if(n>=8;null!==y&&s<4096&&(p[s++]=y<<8|_,u+1<=s&&l<12&&(++l,u=u<<1|1)),y=m}else s=1+a,u=(1<<(l=o+1))-1,y=null}return f!==n&&console.log("Warning, gif stream shorter than expected."),r}try{r.GifWriter=function(g,e,t,r){var v=0,n=void 0===(r=void 0===r?{}:r).loop?null:r.loop,b=void 0===r.palette?null:r.palette;if(e<=0||t<=0||65535>=1;)++o;if(a=1<>8&255,g[v++]=255&t,g[v++]=t>>8&255,g[v++]=(null!==b?128:0)|o,g[v++]=i,g[v++]=0,null!==b)for(var s=0,l=b.length;s>16&255,g[v++]=u>>8&255,g[v++]=255&u}if(null!==n){if(n<0||65535>8&255,g[v++]=0}var x=!1;this.addFrame=function(e,t,r,n,o,i){if(!0===x&&(--v,x=!1),i=void 0===i?{}:i,e<0||t<0||65535>=1;)++u;l=1<>8&255,g[v++]=h,g[v++]=0),g[v++]=44,g[v++]=255&e,g[v++]=e>>8&255,g[v++]=255&t,g[v++]=t>>8&255,g[v++]=255&r,g[v++]=r>>8&255,g[v++]=255&n,g[v++]=n>>8&255,g[v++]=!0===a?128|u-1:0,!0===a)for(var p=0,y=s.length;p>16&255,g[v++]=m>>8&255,g[v++]=255&m}return v=function(t,r,e,n){t[r++]=e;var o=r++,i=1<>=8,c-=8,r===o+256&&(t[o]=255,o=r++)}function h(e){d|=e<>=8,c-=8,r===o+256&&(t[o]=255,o=r++);4096===l?(h(i),l=1+s,u=e+1,y={}):(1<>7,o=1<<1+(7&r);x[e++],x[e++];var i=null,a=null;n&&(i=e,e+=3*(a=o));var s=!0,l=[],u=0,c=null,d=0,f=null;for(this.width=w,this.height=t;s&&e>2&7,e++;break;case 254:for(;;){if(!(0<=(T=x[e++])))throw Error("Invalid block size");if(0===T)break;e+=T}break;default:throw new Error("Unknown graphic control label: 0x"+x[e-1].toString(16))}break;case 44:var p=x[e++]|x[e++]<<8,y=x[e++]|x[e++]<<8,m=x[e++]|x[e++]<<8,g=x[e++]|x[e++]<<8,v=x[e++],b=v>>6&1,_=1<<1+(7&v),j=i,S=a,M=!1;if(v>>7){M=!0;j=e,e+=3*(S=_)}var E=e;for(e++;;){var T;if(!(0<=(T=x[e++])))throw Error("Invalid block size");if(0===T)break;e+=T}l.push({x:p,y:y,width:m,height:g,has_local_palette:M,palette_offset:j,palette_size:S,data_offset:E,data_length:e-E,transparent_index:c,interlaced:!!b,delay:u,disposal:d});break;case 59:s=!1;break;default:throw new Error("Unknown gif block: 0x"+x[e-1].toString(16))}this.numFrames=function(){return l.length},this.loopCount=function(){return f},this.frameInfo=function(e){if(e<0||e>=l.length)throw new Error("Frame index out of range.");return l[e]},this.decodeAndBlitFrameBGRA=function(e,t){var r=this.frameInfo(e),n=r.width*r.height,o=new Uint8Array(n);O(x,r.data_offset,o,n);var i=r.palette_offset,a=r.transparent_index;null===a&&(a=256);var s=r.width,l=w-s,u=s,c=4*(r.y*w+r.x),d=4*((r.y+r.height)*w+r.x),f=c,h=4*l;!0===r.interlaced&&(h+=4*w*7);for(var p=8,y=0,m=o.length;y>=1)),g===a)f+=4;else{var v=x[i+3*g],b=x[i+3*g+1],_=x[i+3*g+2];t[f++]=_,t[f++]=b,t[f++]=v,t[f++]=255}--u}},this.decodeAndBlitFrameRGBA=function(e,t){var r=this.frameInfo(e),n=r.width*r.height,o=new Uint8Array(n);O(x,r.data_offset,o,n);var i=r.palette_offset,a=r.transparent_index;null===a&&(a=256);var s=r.width,l=w-s,u=s,c=4*(r.y*w+r.x),d=4*((r.y+r.height)*w+r.x),f=c,h=4*l;!0===r.interlaced&&(h+=4*w*7);for(var p=8,y=0,m=o.length;y>=1)),g===a)f+=4;else{var v=x[i+3*g],b=x[i+3*g+1],_=x[i+3*g+2];t[f++]=v,t[f++]=b,t[f++]=_,t[f++]=255}--u}}}}catch(e){}},{}],239:[function(Br,r,n){(function(Fr){var e,t;e=this,t=function(M){"use strict";function e(e){if(null==this)throw TypeError();var t=String(this),r=t.length,n=e?Number(e):0;if(n!=n&&(n=0),!(n<0||r<=n)){var o,i=t.charCodeAt(n);return 55296<=i&&i<=56319&&n+1>>=1,t}function _(e,t,r){if(!t)return r;for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>16-t;return e.tag>>>=t,e.bitcount-=t,n+r}function x(e,t){for(;e.bitcount<24;)e.tag|=e.source[e.sourceIndex++]<>>=1,++o,r+=t.table[o],0<=(n-=t.table[o]););return e.tag=i,e.bitcount-=o,t.trans[r+n]}function w(e,t,r){var n,o,i,a,s,l;for(n=_(e,5,257),o=_(e,5,1),i=_(e,4,4),a=0;a<19;++a)m[a]=0;for(a=0;athis.x2&&(this.x2=e)),"number"==typeof t&&((isNaN(this.y1)||isNaN(this.y2))&&(this.y1=t,this.y2=t),tthis.y2&&(this.y2=t))},T.prototype.addX=function(e){this.addPoint(e,null)},T.prototype.addY=function(e){this.addPoint(null,e)},T.prototype.addBezier=function(e,t,r,n,o,i,a,s){var l=[e,t],u=[r,n],c=[o,i],d=[a,s];this.addPoint(e,t),this.addPoint(a,s);for(var f=0;f<=1;f++){var h=6*l[f]-12*u[f]+6*c[f],p=-3*l[f]+9*u[f]-9*c[f]+3*d[f],y=3*u[f]-3*l[f];if(0!=p){var m=Math.pow(h,2)-4*y*p;if(!(m<0)){var g=(-h+Math.sqrt(m))/(2*p);0>8&255,255&e]},k.USHORT=R(2),A.SHORT=function(e){return 32768<=e&&(e=-(65536-e)),[e>>8&255,255&e]},k.SHORT=R(2),A.UINT24=function(e){return[e>>16&255,e>>8&255,255&e]},k.UINT24=R(3),A.ULONG=function(e){return[e>>24&255,e>>16&255,e>>8&255,255&e]},k.ULONG=R(4),A.LONG=function(e){return 2147483648<=e&&(e=-(4294967296-e)),[e>>24&255,e>>16&255,e>>8&255,255&e]},k.LONG=R(4),A.FIXED=A.ULONG,k.FIXED=k.ULONG,A.FWORD=A.SHORT,k.FWORD=k.SHORT,A.UFWORD=A.USHORT,k.UFWORD=k.USHORT,A.LONGDATETIME=function(e){return[0,0,0,0,e>>24&255,e>>16&255,e>>8&255,255&e]},k.LONGDATETIME=R(8),A.TAG=function(e){return L.argument(4===e.length,"Tag should be exactly 4 ASCII characters."),[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]},k.TAG=R(4),A.Card8=A.BYTE,k.Card8=k.BYTE,A.Card16=A.USHORT,k.Card16=k.USHORT,A.OffSize=A.BYTE,k.OffSize=k.BYTE,A.SID=A.USHORT,k.SID=k.USHORT,A.NUMBER=function(e){return-107<=e&&e<=107?[e+139]:108<=e&&e<=1131?[247+((e-=108)>>8),255&e]:-1131<=e&&e<=-108?[251+((e=-e-108)>>8),255&e]:-32768<=e&&e<=32767?A.NUMBER16(e):A.NUMBER32(e)},k.NUMBER=function(e){return A.NUMBER(e).length},A.NUMBER16=function(e){return[28,e>>8&255,255&e]},k.NUMBER16=R(3),A.NUMBER32=function(e){return[29,e>>24&255,e>>16&255,e>>8&255,255&e]},k.NUMBER32=R(5),A.REAL=function(e){var t=e.toString(),r=/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(t);if(r){var n=parseFloat("1e"+((r[2]?+r[2]:0)+r[1].length));t=(Math.round(e*n)/n).toString()}for(var o="",i=0,a=t.length;i>8&255,t[t.length]=255&n}return t},k.UTF16=function(e){return 2*e.length};var I={"x-mac-croatian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈ƫȅ ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ","x-mac-cyrillic":"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю","x-mac-gaelic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæøṁṖṗɼƒſṠ«»… ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ","x-mac-greek":"Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ­","x-mac-icelandic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüݰ¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-inuit":"ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗᓘᓚᓛᓪᔨᔩᔪᔫᔭ… ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł","x-mac-ce":"ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ",macintosh:"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-romanian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-turkish":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ"};P.MACSTRING=function(e,t,r,n){var o=I[n];if(void 0!==o){for(var i="",a=0;a>8&255,l+256&255)}return i}A.MACSTRING=function(e,t){var r=function(e){if(!U)for(var t in U={},I)U[t]=new String(t);var r=U[e];if(void 0!==r){if(N){var n=N.get(r);if(void 0!==n)return n}var o=I[e];if(void 0!==o){for(var i={},a=0;a>8,t[d+1]=255&f,t=t.concat(n[c])}return t},k.TABLE=function(e){for(var t=0,r=e.fields.length,n=0;n>1,t.skip("uShort",3),e.glyphIndexMap={};for(var a=new ae.Parser(r,n+o+14),s=new ae.Parser(r,n+o+16+2*i),l=new ae.Parser(r,n+o+16+4*i),u=new ae.Parser(r,n+o+16+6*i),c=n+o+16+8*i,d=0;d>4,i=15&n;if(15==o)break;if(t+=r[o],15==i)break;t+=r[i]}return parseFloat(t)}(e);if(32<=t&&t<=246)return t-139;if(247<=t&&t<=250)return 256*(t-247)+e.parseByte()+108;if(251<=t&&t<=254)return 256*-(t-251)-e.parseByte()-108;throw new Error("Invalid b0 "+t)}function Me(e,t,r){t=void 0!==t?t:0;var n=new ae.Parser(e,t),o=[],i=[];for(r=void 0!==r?r:e.length;n.relativeOffset>1,E.length=0,O=!0}return function e(t){for(var r,n,o,i,a,s,l,u,c,d,f,h,p=0;pMath.abs(h-P)?L=f+E.shift():P=h+E.shift(),M.curveTo(v,b,_,x,l,u),M.curveTo(c,d,f,h,L,P);break;default:console.log("Glyph "+g.index+": unknown operator 1200"+y),E.length=0}break;case 14:0>3;break;case 21:2>16),p+=2;break;case 29:a=E.pop()+m.gsubrsBias,(s=m.gsubrs[a])&&e(s);break;case 30:for(;0=r.begin&&e=de.length){var a=n.parseChar();r.names.push(n.parseString(a))}break;case 2.5:r.numberOfGlyphs=n.parseUShort(),r.offset=new Array(r.numberOfGlyphs);for(var s=0;st.value.tag?1:-1}),t.fields=t.fields.concat(n),t.fields=t.fields.concat(o),t}function yt(e,t,r){for(var n=0;n 123 are reserved for internal usage");h|=1<>>1,i=e[o].tag;if(i===t)return o;i>>1,i=e[o];if(i===t)return o;i>>1,a=(r=e[i]).start;if(a===t)return r;a(r=e[n-1]).end?0:r}function _t(e,t){this.font=e,this.tableName=t}function xt(e){_t.call(this,e,"gpos")}function wt(e){_t.call(this,e,"gsub")}function jt(e,t){var r=e.length;if(r!==t.length)return!1;for(var n=0;nt.points.length-1||n.matchedPoints[1]>o.points.length-1)throw Error("Matched points out of range in "+t.name);var a=t.points[n.matchedPoints[0]],s=o.points[n.matchedPoints[1]],l={xScale:n.xScale,scale01:n.scale01,scale10:n.scale10,yScale:n.yScale,dx:0,dy:0};s=Ct([s],l)[0],l.dx=a.x-s.x,l.dy=a.y-s.y,i=Ct(o.points,l)}t.points=t.points.concat(i)}}return Lt(t.points)}(xt.prototype=_t.prototype={searchTag:gt,binSearch:vt,getTable:function(e){var t=this.font.tables[this.tableName];return!t&&e&&(t=this.font.tables[this.tableName]=this.createDefaultTable()),t},getScriptNames:function(){var e=this.getTable();return e?e.scripts.map(function(e){return e.tag}):[]},getDefaultScriptName:function(){var e=this.getTable();if(e){for(var t=!1,r=0;r=s[u-1].tag,"Features must be added in alphabetical order."),i={tag:r,feature:{params:0,lookupListIndexes:[]}},s.push(i),a.push(u),i.feature}}},getLookupTables:function(e,t,r,n,o){var i=this.getFeatureTable(e,t,r,o),a=[];if(i){for(var s,l=i.lookupListIndexes,u=this.font.tables[this.tableName].lookups,c=0;c",s),t.stack.push(Math.round(64*s))}function mr(e,t){var r=t.stack,n=r.pop(),o=t.fv,i=t.pv,a=t.ppem,s=t.deltaBase+16*(e-1),l=t.deltaShift,u=t.z0;M.DEBUG&&console.log(t.step,"DELTAP["+e+"]",n,r);for(var c=0;c>4)===a){var h=(15&f)-8;0<=h&&h++,M.DEBUG&&console.log(t.step,"DELTAPFIX",d,"by",h*l);var p=u[d];o.setRelative(p,p,h*l,i)}}}function gr(e,t){var r=t.stack,n=r.pop();M.DEBUG&&console.log(t.step,"ROUND[]"),r.push(64*t.round(n/64))}function vr(e,t){var r=t.stack,n=r.pop(),o=t.ppem,i=t.deltaBase+16*(e-1),a=t.deltaShift;M.DEBUG&&console.log(t.step,"DELTAC["+e+"]",n,r);for(var s=0;s>4)===o){var c=(15&u)-8;0<=c&&c++;var d=c*a;M.DEBUG&&console.log(t.step,"DELTACFIX",l,"by",d),t.cvt[l]+=d}}}function br(e,t){var r,n,o=t.stack,i=o.pop(),a=o.pop(),s=t.z2[i],l=t.z1[a];M.DEBUG&&console.log(t.step,"SDPVTL["+e+"]",i,a),n=e?(r=s.y-l.y,l.x-s.x):(r=l.x-s.x,l.y-s.y),t.dpv=Yt(r,n)}function _r(e,t){var r=t.stack,n=t.prog,o=t.ip;M.DEBUG&&console.log(t.step,"PUSHB["+e+"]");for(var i=0;i":"_")+(n?"R":"_")+(0===o?"Gr":1===o?"Bl":2===o?"Wh":"")+"]",e?d+"("+i.cvt[d]+","+u+")":"",f,"(d =",a,"->",l*s,")"),i.rp1=i.rp0,i.rp2=f,t&&(i.rp0=f)}Ut.prototype.exec=function(e,t){if("number"!=typeof t)throw new Error("Point size is not a number!");if(!(2",n),s.interpolate(d,i,a,l),s.touch(d)}e.loop=1},fr.bind(void 0,0),fr.bind(void 0,1),function(e){for(var t=e.stack,r=e.rp0,n=e.z0[r],o=e.loop,i=e.fv,a=e.pv,s=e.z1;o--;){var l=t.pop(),u=s[l];M.DEBUG&&console.log(e.step,(1").concat(t,"");this.dummyDOM||(this.dummyDOM=document.getElementById(n).parentNode),this.descriptions?this.descriptions.fallbackElements||(this.descriptions.fallbackElements={}):this.descriptions={fallbackElements:{}},this.descriptions.fallbackElements[e]?this.descriptions.fallbackElements[e].innerHTML!==i&&(this.descriptions.fallbackElements[e].innerHTML=i):this._describeElementHTML("fallback",e,i),r===this.LABEL&&(this.descriptions.labelElements||(this.descriptions.labelElements={}),this.descriptions.labelElements[e]?this.descriptions.labelElements[e].innerHTML!==i&&(this.descriptions.labelElements[e].innerHTML=i):this._describeElementHTML("label",e,i))}},a.default.prototype._describeHTML=function(e,t){var r=this.canvas.id;if("fallback"===e){if(this.dummyDOM.querySelector("#".concat(r+l)))this.dummyDOM.querySelector("#"+r+c).insertAdjacentHTML("beforebegin",'

'));else{var n='

');this.dummyDOM.querySelector("#".concat(r,"accessibleOutput"))?this.dummyDOM.querySelector("#".concat(r,"accessibleOutput")).insertAdjacentHTML("beforebegin",n):this.dummyDOM.querySelector("#".concat(r)).innerHTML=n}return this.descriptions.fallback=this.dummyDOM.querySelector("#".concat(r).concat(u)),void(this.descriptions.fallback.innerHTML=t)}if("label"===e){if(this.dummyDOM.querySelector("#".concat(r+d)))this.dummyDOM.querySelector("#".concat(r+h))&&this.dummyDOM.querySelector("#".concat(r+h)).insertAdjacentHTML("beforebegin",'

'));else{var o='

');this.dummyDOM.querySelector("#".concat(r,"accessibleOutputLabel"))?this.dummyDOM.querySelector("#".concat(r,"accessibleOutputLabel")).insertAdjacentHTML("beforebegin",o):this.dummyDOM.querySelector("#"+r).insertAdjacentHTML("afterend",o)}return this.descriptions.label=this.dummyDOM.querySelector("#"+r+f),void(this.descriptions.label.innerHTML=t)}},a.default.prototype._describeElementHTML=function(e,t,r){var n=this.canvas.id;if("fallback"===e){if(this.dummyDOM.querySelector("#".concat(n+l)))this.dummyDOM.querySelector("#"+n+c)||this.dummyDOM.querySelector("#"+n+u).insertAdjacentHTML("afterend",'
Canvas elements and their descriptions
'));else{var o='
Canvas elements and their descriptions
');this.dummyDOM.querySelector("#".concat(n,"accessibleOutput"))?this.dummyDOM.querySelector("#".concat(n,"accessibleOutput")).insertAdjacentHTML("beforebegin",o):this.dummyDOM.querySelector("#"+n).innerHTML=o}var i=document.createElement("tr");return i.id=n+"_fte_"+t,this.dummyDOM.querySelector("#"+n+c).appendChild(i),this.descriptions.fallbackElements[t]=this.dummyDOM.querySelector("#".concat(n).concat("_fte_").concat(t)),void(this.descriptions.fallbackElements[t].innerHTML=r)}if("label"===e){if(this.dummyDOM.querySelector("#".concat(n+d)))this.dummyDOM.querySelector("#".concat(n+h))||this.dummyDOM.querySelector("#"+n+f).insertAdjacentHTML("afterend",'
'));else{var a='
');this.dummyDOM.querySelector("#".concat(n,"accessibleOutputLabel"))?this.dummyDOM.querySelector("#".concat(n,"accessibleOutputLabel")).insertAdjacentHTML("beforebegin",a):this.dummyDOM.querySelector("#"+n).insertAdjacentHTML("afterend",a)}var s=document.createElement("tr");s.id=n+"_lte_"+t,this.dummyDOM.querySelector("#"+n+h).appendChild(s),this.descriptions.labelElements[t]=this.dummyDOM.querySelector("#".concat(n).concat("_lte_").concat(t)),this.descriptions.labelElements[t].innerHTML=r}};var o=a.default;r.default=o},{"../core/main":264,"core-js/modules/es.array.concat":149,"core-js/modules/es.regexp.exec":181,"core-js/modules/es.string.ends-with":184,"core-js/modules/es.string.replace":189}],245:[function(e,t,r){"use strict";e("core-js/modules/es.array.concat"),e("core-js/modules/es.array.map"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var n,o=(n=e("../core/main"))&&n.__esModule?n:{default:n};o.default.prototype._updateGridOutput=function(e){if(this.dummyDOM.querySelector("#".concat(e,"_summary"))){var t=this._accessibleOutputs[e],r=function(e,t){var r="",n="",o=0;for(var i in t){var a=0;for(var s in t[i]){var l='
  • ').concat(t[i][s].color," ").concat(i,",");"line"===i?l+=" location = ".concat(t[i][s].pos,", length = ").concat(t[i][s].length," pixels"):(l+=" location = ".concat(t[i][s].pos),"point"!==i&&(l+=", area = ".concat(t[i][s].area," %")),l+="
  • "),r+=l,a++,o++}n=1').concat(t[a][s].color," ").concat(a,"
    "):'').concat(t[a][s].color," ").concat(a," midpoint"),o[t[a][s].loc.locY][t[a][s].loc.locX]?o[t[a][s].loc.locY][t[a][s].loc.locX]=o[t[a][s].loc.locY][t[a][s].loc.locX]+" "+l:o[t[a][s].loc.locY][t[a][s].loc.locX]=l,r++}for(var u in o){var c="";for(var d in o[u])c+="",void 0!==o[u][d]&&(c+=o[u][d]),c+="";n=n+c+""}return n}(e,this.ingredients.shapes);n!==t.summary.innerHTML&&(t.summary.innerHTML=n),o!==t.map.innerHTML&&(t.map.innerHTML=o),r.details!==t.shapeDetails.innerHTML&&(t.shapeDetails.innerHTML=r.details),this._accessibleOutputs[e]=t}};var i=o.default;r.default=i},{"../core/main":264,"core-js/modules/es.array.concat":149,"core-js/modules/es.array.map":161}],246:[function(e,t,r){"use strict";e("core-js/modules/es.array.concat"),e("core-js/modules/es.array.fill"),e("core-js/modules/es.array.map"),e("core-js/modules/es.number.to-fixed"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var n,o=(n=e("../core/main"))&&n.__esModule?n:{default:n};function l(e,t,r){return e[0]<.4*t?e[1]<.4*r?"top left":e[1]>.6*r?"bottom left":"mid left":e[0]>.6*t?e[1]<.4*r?"top right":e[1]>.6*r?"bottom right":"mid right":e[1]<.4*r?"top middle":e[1]>.6*r?"bottom middle":"middle"}function u(e,t,r){var n=Math.floor(e[0]/t*10),o=Math.floor(e[1]/r*10);return 10===n&&--n,10===o&&--o,{locX:n,locY:o}}o.default.prototype.textOutput=function(e){o.default._validateParameters("textOutput",arguments),this._accessibleOutputs.text||(this._accessibleOutputs.text=!0,this._createOutput("textOutput","Fallback"),e===this.LABEL&&(this._accessibleOutputs.textLabel=!0,this._createOutput("textOutput","Label")))},o.default.prototype.gridOutput=function(e){o.default._validateParameters("gridOutput",arguments),this._accessibleOutputs.grid||(this._accessibleOutputs.grid=!0,this._createOutput("gridOutput","Fallback"),e===this.LABEL&&(this._accessibleOutputs.gridLabel=!0,this._createOutput("gridOutput","Label")))},o.default.prototype._addAccsOutput=function(){return this._accessibleOutputs||(this._accessibleOutputs={text:!1,grid:!1,textLabel:!1,gridLabel:!1}),this._accessibleOutputs.grid||this._accessibleOutputs.text},o.default.prototype._createOutput=function(e,t){var r,n,o,i=this.canvas.id;this.ingredients||(this.ingredients={shapes:{},colors:{background:"white",fill:"white",stroke:"black"},pShapes:""}),this.dummyDOM||(this.dummyDOM=document.getElementById(i).parentNode);var a="";"Fallback"===t?(r=i+e,n=i+"accessibleOutput",this.dummyDOM.querySelector("#".concat(n))||(this.dummyDOM.querySelector("#".concat(i,"_Description"))?this.dummyDOM.querySelector("#".concat(i,"_Description")).insertAdjacentHTML("afterend",'
    ')):this.dummyDOM.querySelector("#".concat(i)).innerHTML='
    '))):"Label"===t&&(r=i+e+(a=t),n=i+"accessibleOutput"+t,this.dummyDOM.querySelector("#".concat(n))||(this.dummyDOM.querySelector("#".concat(i,"_Label"))?this.dummyDOM.querySelector("#".concat(i,"_Label")).insertAdjacentHTML("afterend",'
    ')):this.dummyDOM.querySelector("#".concat(i)).insertAdjacentHTML("afterend",'
    ')))),this._accessibleOutputs[r]={},"textOutput"===e?(a="#".concat(i,"gridOutput").concat(a),o='
    Text Output

      '),this.dummyDOM.querySelector(a)?this.dummyDOM.querySelector(a).insertAdjacentHTML("beforebegin",o):this.dummyDOM.querySelector("#".concat(n)).innerHTML=o,this._accessibleOutputs[r].list=this.dummyDOM.querySelector("#".concat(r,"_list"))):"gridOutput"===e&&(a="#".concat(i,"textOutput").concat(a),o='
      Grid Output

        '),this.dummyDOM.querySelector(a)?this.dummyDOM.querySelector(a).insertAdjacentHTML("afterend",o):this.dummyDOM.querySelector("#".concat(n)).innerHTML=o,this._accessibleOutputs[r].map=this.dummyDOM.querySelector("#".concat(r,"_map"))),this._accessibleOutputs[r].shapeDetails=this.dummyDOM.querySelector("#".concat(r,"_shapeDetails")),this._accessibleOutputs[r].summary=this.dummyDOM.querySelector("#".concat(r,"_summary"))},o.default.prototype._updateAccsOutput=function(){var e=this.canvas.id;JSON.stringify(this.ingredients.shapes)!==this.ingredients.pShapes&&(this.ingredients.pShapes=JSON.stringify(this.ingredients.shapes),this._accessibleOutputs.text&&this._updateTextOutput(e+"textOutput"),this._accessibleOutputs.grid&&this._updateGridOutput(e+"gridOutput"),this._accessibleOutputs.textLabel&&this._updateTextOutput(e+"textOutputLabel"),this._accessibleOutputs.gridLabel&&this._updateGridOutput(e+"gridOutputLabel"))},o.default.prototype._accsBackground=function(e){this.ingredients.pShapes=JSON.stringify(this.ingredients.shapes),this.ingredients.shapes={},this.ingredients.colors.backgroundRGBA!==e&&(this.ingredients.colors.backgroundRGBA=e,this.ingredients.colors.background=this._rgbColorName(e))},o.default.prototype._accsCanvasColors=function(e,t){"fill"===e?this.ingredients.colors.fillRGBA!==t&&(this.ingredients.colors.fillRGBA=t,this.ingredients.colors.fill=this._rgbColorName(t)):"stroke"===e&&this.ingredients.colors.strokeRGBA!==t&&(this.ingredients.colors.strokeRGBA=t,this.ingredients.colors.stroke=this._rgbColorName(t))},o.default.prototype._accsOutput=function(e,t){"ellipse"===e&&t[2]===t[3]?e="circle":"rectangle"===e&&t[2]===t[3]&&(e="square");var r={},n=!0,o=function(e,t){var r,n;n="rectangle"===e||"ellipse"===e||"arc"===e||"circle"===e||"square"===e?(r=Math.round(t[0]+t[2]/2),Math.round(t[1]+t[3]/2)):"triangle"===e?(r=(t[0]+t[2]+t[4])/3,(t[1]+t[3]+t[5])/3):"quadrilateral"===e?(r=(t[0]+t[2]+t[4]+t[6])/4,(t[1]+t[3]+t[5]+t[7])/4):"line"===e?(r=(t[0]+t[2])/2,(t[1]+t[3])/2):(r=t[0],t[1]);return[r,n]}(e,t);if("line"===e){r.color=this.ingredients.colors.stroke,r.length=Math.round(this.dist(t[0],t[1],t[2],t[3]));var i=l([t[0],[1]],this.width,this.height),a=l([t[2],[3]],this.width,this.height);r.loc=u(o,this.width,this.height),r.pos=i===a?"at ".concat(i):"from ".concat(i," to ").concat(a)}else"point"===e?r.color=this.ingredients.colors.stroke:(r.color=this.ingredients.colors.fill,r.area=function(e,t,r,n){var o=0;if("arc"===e){var i=((t[5]-t[4])%(2*Math.PI)+2*Math.PI)%(2*Math.PI);if(o=i*t[2]*t[3]/8,"open"===t[6]||"chord"===t[6]){var a=t[0],s=t[1],l=t[0]+t[2]/2*Math.cos(t[4]).toFixed(2),u=t[1]+t[3]/2*Math.sin(t[4]).toFixed(2),c=t[0]+t[2]/2*Math.cos(t[5]).toFixed(2),d=t[1]+t[3]/2*Math.sin(t[5]).toFixed(2),f=Math.abs(a*(u-d)+l*(d-s)+c*(s-u))/2;i>Math.PI?o+=f:o-=f}}else"ellipse"===e||"circle"===e?o=3.14*t[2]/2*t[3]/2:"line"===e?o=0:"point"===e?o=0:"quadrilateral"===e?o=Math.abs((t[6]+t[0])*(t[7]-t[1])+(t[0]+t[2])*(t[1]-t[3])+(t[2]+t[4])*(t[3]-t[5])+(t[4]+t[6])*(t[5]-t[7]))/2:"rectangle"===e||"square"===e?o=t[2]*t[3]:"triangle"===e&&(o=Math.abs(t[0]*(t[3]-t[5])+t[2]*(t[5]-t[1])+t[4]*(t[1]-t[3]))/2);return Math.round(100*o/(r*n))}(e,t,this.width,this.height)),r.pos=l(o,this.width,this.height),r.loc=u(o,this.width,this.height);if(this.ingredients.shapes[e]){if(this.ingredients.shapes[e]!==[r]){for(var s in this.ingredients.shapes[e])JSON.stringify(this.ingredients.shapes[e][s])===JSON.stringify(r)&&(n=!1);!0===n&&this.ingredients.shapes[e].push(r)}}else this.ingredients.shapes[e]=[r]};var i=o.default;r.default=i},{"../core/main":264,"core-js/modules/es.array.concat":149,"core-js/modules/es.array.fill":151,"core-js/modules/es.array.map":161,"core-js/modules/es.number.to-fixed":172}],247:[function(e,t,r){"use strict";e("core-js/modules/es.array.concat"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var n,o=(n=e("../core/main"))&&n.__esModule?n:{default:n};o.default.prototype._updateTextOutput=function(e){if(this.dummyDOM.querySelector("#".concat(e,"_summary"))){var t=this._accessibleOutputs[e],r=function(e,t){var r="",n=0;for(var o in t)for(var i in t[o]){var a='
      • ').concat(t[o][i].color," ").concat(o,"");"line"===o?a+=", ".concat(t[o][i].pos,", ").concat(t[o][i].length," pixels long.
      • "):(a+=", at ".concat(t[o][i].pos),"point"!==o&&(a+=", covering ".concat(t[o][i].area,"% of the canvas")),a+="."),r+=a,n++}return{numShapes:n,listShapes:r}}(e,this.ingredients.shapes),n=function(e,t,r,n){var o="Your output is a, ".concat(r," by ").concat(n," pixels, ").concat(t," canvas containing the following");o=1===e?"".concat(o," shape:"):"".concat(o," ").concat(e," shapes:");return o}(r.numShapes,this.ingredients.colors.background,this.width,this.height),o=function(e,t){var r="",n=0;for(var o in t)for(var i in t[o]){var a='').concat(t[o][i].color," ").concat(o,"");"line"===o?a+="location = ".concat(t[o][i].pos,"length = ").concat(t[o][i].length," pixels"):(a+="location = ".concat(t[o][i].pos,""),"point"!==o&&(a+=" area = ".concat(t[o][i].area,"%")),a+=""),r+=a,n++}return r}(e,this.ingredients.shapes);n!==t.summary.innerHTML&&(t.summary.innerHTML=n),r.listShapes!==t.list.innerHTML&&(t.list.innerHTML=r.listShapes),o!==t.shapeDetails.innerHTML&&(t.shapeDetails.innerHTML=o),this._accessibleOutputs[e]=t}};var i=o.default;r.default=i},{"../core/main":264,"core-js/modules/es.array.concat":149}],248:[function(e,t,r){"use strict";var n,o=(n=e("./core/main"))&&n.__esModule?n:{default:n};e("./core/constants"),e("./core/environment"),e("./core/friendly_errors/stacktrace"),e("./core/friendly_errors/validate_params"),e("./core/friendly_errors/file_errors"),e("./core/friendly_errors/fes_core"),e("./core/friendly_errors/sketch_reader"),e("./core/helpers"),e("./core/legacy"),e("./core/preload"),e("./core/p5.Element"),e("./core/p5.Graphics"),e("./core/p5.Renderer"),e("./core/p5.Renderer2D"),e("./core/rendering"),e("./core/shim"),e("./core/structure"),e("./core/transform"),e("./core/shape/2d_primitives"),e("./core/shape/attributes"),e("./core/shape/curves"),e("./core/shape/vertex"),e("./accessibility/outputs"),e("./accessibility/textOutput"),e("./accessibility/gridOutput"),e("./accessibility/color_namer"),e("./color/color_conversion"),e("./color/creating_reading"),e("./color/p5.Color"),e("./color/setting"),e("./data/p5.TypedDict"),e("./data/local_storage.js"),e("./dom/dom"),e("./accessibility/describe"),e("./events/acceleration"),e("./events/keyboard"),e("./events/mouse"),e("./events/touch"),e("./image/filters"),e("./image/image"),e("./image/loading_displaying"),e("./image/p5.Image"),e("./image/pixels"),e("./io/files"),e("./io/p5.Table"),e("./io/p5.TableRow"),e("./io/p5.XML"),e("./math/calculation"),e("./math/math"),e("./math/noise"),e("./math/p5.Vector"),e("./math/random"),e("./math/trigonometry"),e("./typography/attributes"),e("./typography/loading_displaying"),e("./typography/p5.Font"),e("./utilities/array_functions"),e("./utilities/conversion"),e("./utilities/string_functions"),e("./utilities/time_date"),e("./webgl/3d_primitives"),e("./webgl/interaction"),e("./webgl/light"),e("./webgl/loading"),e("./webgl/material"),e("./webgl/p5.Camera"),e("./webgl/p5.Geometry"),e("./webgl/p5.Matrix"),e("./webgl/p5.RendererGL.Immediate"),e("./webgl/p5.RendererGL"),e("./webgl/p5.RendererGL.Retained"),e("./webgl/p5.Shader"),e("./webgl/p5.RenderBuffer"),e("./webgl/p5.Texture"),e("./webgl/text"),e("./core/init"),t.exports=o.default},{"./accessibility/color_namer":243,"./accessibility/describe":244,"./accessibility/gridOutput":245,"./accessibility/outputs":246,"./accessibility/textOutput":247,"./color/color_conversion":249,"./color/creating_reading":250,"./color/p5.Color":251,"./color/setting":252,"./core/constants":253,"./core/environment":254,"./core/friendly_errors/fes_core":255,"./core/friendly_errors/file_errors":256,"./core/friendly_errors/sketch_reader":257,"./core/friendly_errors/stacktrace":258,"./core/friendly_errors/validate_params":259,"./core/helpers":260,"./core/init":261,"./core/legacy":263,"./core/main":264,"./core/p5.Element":265,"./core/p5.Graphics":266,"./core/p5.Renderer":267,"./core/p5.Renderer2D":268,"./core/preload":269,"./core/rendering":270,"./core/shape/2d_primitives":271,"./core/shape/attributes":272,"./core/shape/curves":273,"./core/shape/vertex":274,"./core/shim":275,"./core/structure":276,"./core/transform":277,"./data/local_storage.js":278,"./data/p5.TypedDict":279,"./dom/dom":280,"./events/acceleration":281,"./events/keyboard":282,"./events/mouse":283,"./events/touch":284,"./image/filters":285,"./image/image":286,"./image/loading_displaying":287,"./image/p5.Image":288,"./image/pixels":289,"./io/files":290,"./io/p5.Table":291,"./io/p5.TableRow":292,"./io/p5.XML":293,"./math/calculation":294,"./math/math":295,"./math/noise":296,"./math/p5.Vector":297,"./math/random":298,"./math/trigonometry":299,"./typography/attributes":300,"./typography/loading_displaying":301,"./typography/p5.Font":302,"./utilities/array_functions":303,"./utilities/conversion":304,"./utilities/string_functions":305,"./utilities/time_date":306,"./webgl/3d_primitives":307,"./webgl/interaction":308,"./webgl/light":309,"./webgl/loading":310,"./webgl/material":311,"./webgl/p5.Camera":312,"./webgl/p5.Geometry":313,"./webgl/p5.Matrix":314,"./webgl/p5.RenderBuffer":315,"./webgl/p5.RendererGL":318,"./webgl/p5.RendererGL.Immediate":316,"./webgl/p5.RendererGL.Retained":317,"./webgl/p5.Shader":319,"./webgl/p5.Texture":320,"./webgl/text":321}],249:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var n,o=(n=e("../core/main"))&&n.__esModule?n:{default:n};o.default.ColorConversion={},o.default.ColorConversion._hsbaToHSLA=function(e){var t=e[0],r=e[1],n=e[2],o=(2-r)*n/2;return 0!=o&&(1==o?r=0:o<.5?r/=2-r:r=r*n/(2-2*o)),[t,r,o,e[3]]},o.default.ColorConversion._hsbaToRGBA=function(e){var t=6*e[0],r=e[1],n=e[2],o=[];if(0===r)o=[n,n,n,e[3]];else{var i,a,s,l=Math.floor(t),u=n*(1-r),c=n*(1-r*(t-l)),d=n*(1-r*(1+l-t));s=1===l?(i=c,a=n,u):2===l?(i=u,a=n,d):3===l?(i=u,a=c,n):4===l?(i=d,a=u,n):5===l?(i=n,a=u,c):(i=n,a=d,u),o=[i,a,s,e[3]]}return o},o.default.ColorConversion._hslaToHSBA=function(e){var t,r=e[0],n=e[1],o=e[2];return[r,n=2*((t=o<.5?(1+n)*o:o+n-o*n)-o)/t,t,e[3]]},o.default.ColorConversion._hslaToRGBA=function(e){var t=6*e[0],r=e[1],n=e[2],o=[];if(0===r)o=[n,n,n,e[3]];else{var i,a=2*n-(i=n<.5?(1+r)*n:n+r-n*r),s=function(e,t,r){return e<0?e+=6:6<=e&&(e-=6),e<1?t+(r-t)*e:e<3?r:e<4?t+(r-t)*(4-e):t};o=[s(2+t,a,i),s(t,a,i),s(t-2,a,i),e[3]]}return o},o.default.ColorConversion._rgbaToHSBA=function(e){var t,r,n=e[0],o=e[1],i=e[2],a=Math.max(n,o,i),s=a-Math.min(n,o,i);return 0==s?r=t=0:(r=s/a,n===a?t=(o-i)/s:o===a?t=2+(i-n)/s:i===a&&(t=4+(n-o)/s),t<0?t+=6:6<=t&&(t-=6)),[t/6,r,a,e[3]]},o.default.ColorConversion._rgbaToHSLA=function(e){var t,r,n=e[0],o=e[1],i=e[2],a=Math.max(n,o,i),s=Math.min(n,o,i),l=a+s,u=a-s;return 0==u?r=t=0:(r=l<1?u/l:u/(2-l),n===a?t=(o-i)/u:o===a?t=2+(i-n)/u:i===a&&(t=4+(n-o)/u),t<0?t+=6:6<=t&&(t-=6)),[t/6,r,l/2,e[3]]};var i=o.default.ColorConversion;r.default=i},{"../core/main":264}],250:[function(e,t,r){"use strict";function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}e("core-js/modules/es.array.map"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var n,d=(n=e("../core/main"))&&n.__esModule?n:{default:n},f=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==a(e)&&"function"!=typeof e)return{default:e};var t=s();if(t&&t.has(e))return t.get(e);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=n?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(r,o,i):r[o]=e[o]}r.default=e,t&&t.set(e,r);return r}(e("../core/constants"));function s(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return s=function(){return e},e}e("./p5.Color"),e("../core/friendly_errors/validate_params"),e("../core/friendly_errors/file_errors"),e("../core/friendly_errors/fes_core"),d.default.prototype.alpha=function(e){return d.default._validateParameters("alpha",arguments),this.color(e)._getAlpha()},d.default.prototype.blue=function(e){return d.default._validateParameters("blue",arguments),this.color(e)._getBlue()},d.default.prototype.brightness=function(e){return d.default._validateParameters("brightness",arguments),this.color(e)._getBrightness()},d.default.prototype.color=function(){if(d.default._validateParameters("color",arguments),arguments[0]instanceof d.default.Color)return arguments[0];var e=arguments[0]instanceof Array?arguments[0]:arguments;return new d.default.Color(this,e)},d.default.prototype.green=function(e){return d.default._validateParameters("green",arguments),this.color(e)._getGreen()},d.default.prototype.hue=function(e){return d.default._validateParameters("hue",arguments),this.color(e)._getHue()},d.default.prototype.lerpColor=function(e,t,r){d.default._validateParameters("lerpColor",arguments);var n,o,i,a,s,l,u=this._colorMode,c=this._colorMaxes;if(u===f.RGB)s=e.levels.map(function(e){return e/255}),l=t.levels.map(function(e){return e/255});else if(u===f.HSB)e._getBrightness(),t._getBrightness(),s=e.hsba,l=t.hsba;else{if(u!==f.HSL)throw new Error("".concat(u,"cannot be used for interpolation."));e._getLightness(),t._getLightness(),s=e.hsla,l=t.hsla}return r=Math.max(Math.min(r,1),0),void 0===this.lerp&&(this.lerp=function(e,t,r){return r*(t-e)+e}),n=this.lerp(s[0],l[0],r),o=this.lerp(s[1],l[1],r),i=this.lerp(s[2],l[2],r),a=this.lerp(s[3],l[3],r),n*=c[u][0],o*=c[u][1],i*=c[u][2],a*=c[u][3],this.color(n,o,i,a)},d.default.prototype.lightness=function(e){return d.default._validateParameters("lightness",arguments),this.color(e)._getLightness()},d.default.prototype.red=function(e){return d.default._validateParameters("red",arguments),this.color(e)._getRed()},d.default.prototype.saturation=function(e){return d.default._validateParameters("saturation",arguments),this.color(e)._getSaturation()};var o=d.default;r.default=o},{"../core/constants":253,"../core/friendly_errors/fes_core":255,"../core/friendly_errors/file_errors":256,"../core/friendly_errors/validate_params":259,"../core/main":264,"./p5.Color":251,"core-js/modules/es.array.map":161}],251:[function(e,t,r){"use strict";function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}e("core-js/modules/es.array.join"),e("core-js/modules/es.array.map"),e("core-js/modules/es.array.slice"),e("core-js/modules/es.object.to-string"),e("core-js/modules/es.regexp.constructor"),e("core-js/modules/es.regexp.exec"),e("core-js/modules/es.regexp.to-string"),e("core-js/modules/es.string.trim"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var d=n(e("../core/main")),f=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==a(e)&&"function"!=typeof e)return{default:e};var t=s();if(t&&t.has(e))return t.get(e);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=n?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(r,o,i):r[o]=e[o]}r.default=e,t&&t.set(e,r);return r}(e("../core/constants")),h=n(e("./color_conversion"));function s(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return s=function(){return e},e}function n(e){return e&&e.__esModule?e:{default:e}}d.default.Color=function(e,t){if(this._storeModeAndMaxes(e._colorMode,e._colorMaxes),this.mode!==f.RGB&&this.mode!==f.HSL&&this.mode!==f.HSB)throw new Error("".concat(this.mode," is an invalid colorMode."));return this._array=d.default.Color._parseInputs.apply(this,t),this._calculateLevels(),this},d.default.Color.prototype.toString=function(e){var t=this.levels,r=this._array,n=r[3];switch(e){case"#rrggbb":return"#".concat(t[0]<16?"0".concat(t[0].toString(16)):t[0].toString(16),t[1]<16?"0".concat(t[1].toString(16)):t[1].toString(16),t[2]<16?"0".concat(t[2].toString(16)):t[2].toString(16));case"#rrggbbaa":return"#".concat(t[0]<16?"0".concat(t[0].toString(16)):t[0].toString(16),t[1]<16?"0".concat(t[1].toString(16)):t[1].toString(16),t[2]<16?"0".concat(t[2].toString(16)):t[2].toString(16),t[3]<16?"0".concat(t[3].toString(16)):t[3].toString(16));case"#rgb":return"#".concat(Math.round(15*r[0]).toString(16),Math.round(15*r[1]).toString(16),Math.round(15*r[2]).toString(16));case"#rgba":return"#".concat(Math.round(15*r[0]).toString(16),Math.round(15*r[1]).toString(16),Math.round(15*r[2]).toString(16),Math.round(15*r[3]).toString(16));case"rgb":return"rgb(".concat(t[0],", ",t[1],", ",t[2],")");case"rgb%":return"rgb(".concat((100*r[0]).toPrecision(3),"%, ",(100*r[1]).toPrecision(3),"%, ",(100*r[2]).toPrecision(3),"%)");case"rgba%":return"rgba(".concat((100*r[0]).toPrecision(3),"%, ",(100*r[1]).toPrecision(3),"%, ",(100*r[2]).toPrecision(3),"%, ",(100*r[3]).toPrecision(3),"%)");case"hsb":case"hsv":return this.hsba||(this.hsba=h.default._rgbaToHSBA(this._array)),"hsb(".concat(this.hsba[0]*this.maxes[f.HSB][0],", ",this.hsba[1]*this.maxes[f.HSB][1],", ",this.hsba[2]*this.maxes[f.HSB][2],")");case"hsb%":case"hsv%":return this.hsba||(this.hsba=h.default._rgbaToHSBA(this._array)),"hsb(".concat((100*this.hsba[0]).toPrecision(3),"%, ",(100*this.hsba[1]).toPrecision(3),"%, ",(100*this.hsba[2]).toPrecision(3),"%)");case"hsba":case"hsva":return this.hsba||(this.hsba=h.default._rgbaToHSBA(this._array)),"hsba(".concat(this.hsba[0]*this.maxes[f.HSB][0],", ",this.hsba[1]*this.maxes[f.HSB][1],", ",this.hsba[2]*this.maxes[f.HSB][2],", ",n,")");case"hsba%":case"hsva%":return this.hsba||(this.hsba=h.default._rgbaToHSBA(this._array)),"hsba(".concat((100*this.hsba[0]).toPrecision(3),"%, ",(100*this.hsba[1]).toPrecision(3),"%, ",(100*this.hsba[2]).toPrecision(3),"%, ",(100*n).toPrecision(3),"%)");case"hsl":return this.hsla||(this.hsla=h.default._rgbaToHSLA(this._array)),"hsl(".concat(this.hsla[0]*this.maxes[f.HSL][0],", ",this.hsla[1]*this.maxes[f.HSL][1],", ",this.hsla[2]*this.maxes[f.HSL][2],")");case"hsl%":return this.hsla||(this.hsla=h.default._rgbaToHSLA(this._array)),"hsl(".concat((100*this.hsla[0]).toPrecision(3),"%, ",(100*this.hsla[1]).toPrecision(3),"%, ",(100*this.hsla[2]).toPrecision(3),"%)");case"hsla":return this.hsla||(this.hsla=h.default._rgbaToHSLA(this._array)),"hsla(".concat(this.hsla[0]*this.maxes[f.HSL][0],", ",this.hsla[1]*this.maxes[f.HSL][1],", ",this.hsla[2]*this.maxes[f.HSL][2],", ",n,")");case"hsla%":return this.hsla||(this.hsla=h.default._rgbaToHSLA(this._array)),"hsl(".concat((100*this.hsla[0]).toPrecision(3),"%, ",(100*this.hsla[1]).toPrecision(3),"%, ",(100*this.hsla[2]).toPrecision(3),"%, ",(100*n).toPrecision(3),"%)");case"rgba":default:return"rgba(".concat(t[0],",",t[1],",",t[2],",",n,")")}},d.default.Color.prototype.setRed=function(e){this._array[0]=e/this.maxes[f.RGB][0],this._calculateLevels()},d.default.Color.prototype.setGreen=function(e){this._array[1]=e/this.maxes[f.RGB][1],this._calculateLevels()},d.default.Color.prototype.setBlue=function(e){this._array[2]=e/this.maxes[f.RGB][2],this._calculateLevels()},d.default.Color.prototype.setAlpha=function(e){this._array[3]=e/this.maxes[this.mode][3],this._calculateLevels()},d.default.Color.prototype._calculateLevels=function(){for(var e=this._array,t=this.levels=new Array(e.length),r=e.length-1;0<=r;--r)t[r]=Math.round(255*e[r])},d.default.Color.prototype._getAlpha=function(){return this._array[3]*this.maxes[this.mode][3]},d.default.Color.prototype._storeModeAndMaxes=function(e,t){this.mode=e,this.maxes=t},d.default.Color.prototype._getMode=function(){return this.mode},d.default.Color.prototype._getMaxes=function(){return this.maxes},d.default.Color.prototype._getBlue=function(){return this._array[2]*this.maxes[f.RGB][2]},d.default.Color.prototype._getBrightness=function(){return this.hsba||(this.hsba=h.default._rgbaToHSBA(this._array)),this.hsba[2]*this.maxes[f.HSB][2]},d.default.Color.prototype._getGreen=function(){return this._array[1]*this.maxes[f.RGB][1]},d.default.Color.prototype._getHue=function(){return this.mode===f.HSB?(this.hsba||(this.hsba=h.default._rgbaToHSBA(this._array)),this.hsba[0]*this.maxes[f.HSB][0]):(this.hsla||(this.hsla=h.default._rgbaToHSLA(this._array)),this.hsla[0]*this.maxes[f.HSL][0])},d.default.Color.prototype._getLightness=function(){return this.hsla||(this.hsla=h.default._rgbaToHSLA(this._array)),this.hsla[2]*this.maxes[f.HSL][2]},d.default.Color.prototype._getRed=function(){return this._array[0]*this.maxes[f.RGB][0]},d.default.Color.prototype._getSaturation=function(){return this.mode===f.HSB?(this.hsba||(this.hsba=h.default._rgbaToHSBA(this._array)),this.hsba[1]*this.maxes[f.HSB][1]):(this.hsla||(this.hsla=h.default._rgbaToHSLA(this._array)),this.hsla[1]*this.maxes[f.HSL][1])};var p={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},o=/\s*/,i=/(\d{1,3})/,l=/((?:\d+(?:\.\d+)?)|(?:\.\d+))/,u=new RegExp("".concat(l.source,"%")),y={HEX3:/^#([a-f0-9])([a-f0-9])([a-f0-9])$/i,HEX4:/^#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])$/i,HEX6:/^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i,HEX8:/^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/i,RGB:new RegExp(["^rgb\\(",i.source,",",i.source,",",i.source,"\\)$"].join(o.source),"i"),RGB_PERCENT:new RegExp(["^rgb\\(",u.source,",",u.source,",",u.source,"\\)$"].join(o.source),"i"),RGBA:new RegExp(["^rgba\\(",i.source,",",i.source,",",i.source,",",l.source,"\\)$"].join(o.source),"i"),RGBA_PERCENT:new RegExp(["^rgba\\(",u.source,",",u.source,",",u.source,",",l.source,"\\)$"].join(o.source),"i"),HSL:new RegExp(["^hsl\\(",i.source,",",u.source,",",u.source,"\\)$"].join(o.source),"i"),HSLA:new RegExp(["^hsla\\(",i.source,",",u.source,",",u.source,",",l.source,"\\)$"].join(o.source),"i"),HSB:new RegExp(["^hsb\\(",i.source,",",u.source,",",u.source,"\\)$"].join(o.source),"i"),HSBA:new RegExp(["^hsba\\(",i.source,",",u.source,",",u.source,",",l.source,"\\)$"].join(o.source),"i")};d.default.Color._parseInputs=function(e,t,r,n){var o,i=arguments.length,a=this.mode,s=this.maxes[a],l=[];if(3<=i){for(l[0]=e/s[0],l[1]=t/s[1],l[2]=r/s[2],l[3]="number"==typeof n?n/s[3]:1,o=l.length-1;0<=o;--o){var u=l[o];u<0?l[o]=0:1"].indexOf(o[0])?void 0:o[0],lineNumber:o[1],columnNumber:o[2],source:e}},this)},parseFFOrSafari:function(e){return e.stack.split("\n").filter(function(e){return!e.match(n)},this).map(function(e){if(-1 eval")&&(e=e.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,":$1")),-1===e.indexOf("@")&&-1===e.indexOf(":"))return{functionName:e};var t=/((.*".+"[^@]*)?[^@]*)(?:@)/,r=e.match(t),n=r&&r[1]?r[1]:void 0,o=this.extractLocation(e.replace(t,""));return{functionName:n,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:e}},this)},parseOpera:function(e){return!e.stacktrace||-1e.stacktrace.split("\n").length?this.parseOpera9(e):e.stack?this.parseOpera11(e):this.parseOpera10(e)},parseOpera9:function(e){for(var t=/Line (\d+).*script (?:in )?(\S+)/i,r=e.message.split("\n"),n=[],o=2,i=r.length;o/,"$2").replace(/\([^)]*\)/g,"")||void 0;return o.match(/\(([^)]*)\)/)&&(t=o.replace(/^[^(]+\(([^)]*)\)$/,"$1")),{functionName:i,args:void 0===t||"[arguments not available]"===t?void 0:t.split(","),fileName:n[0],lineNumber:n[1],columnNumber:n[2],source:e}},this)}}}o.default._getErrorStackParser=function(){return new i};var a=o.default;r.default=a},{"../main":264,"core-js/modules/es.array.filter":152,"core-js/modules/es.array.index-of":157,"core-js/modules/es.array.join":159,"core-js/modules/es.array.map":161,"core-js/modules/es.array.slice":162,"core-js/modules/es.regexp.exec":181,"core-js/modules/es.string.match":187,"core-js/modules/es.string.replace":189,"core-js/modules/es.string.split":191}],259:[function(e,t,r){"use strict";e("core-js/modules/es.symbol"),e("core-js/modules/es.symbol.description"),e("core-js/modules/es.symbol.iterator"),e("core-js/modules/es.array.concat"),e("core-js/modules/es.array.for-each"),e("core-js/modules/es.array.includes"),e("core-js/modules/es.array.index-of"),e("core-js/modules/es.array.iterator"),e("core-js/modules/es.array.join"),e("core-js/modules/es.array.last-index-of"),e("core-js/modules/es.array.map"),e("core-js/modules/es.array.slice"),e("core-js/modules/es.function.name"),e("core-js/modules/es.map"),e("core-js/modules/es.number.constructor"),e("core-js/modules/es.object.get-prototype-of"),e("core-js/modules/es.object.keys"),e("core-js/modules/es.object.to-string"),e("core-js/modules/es.reflect.construct"),e("core-js/modules/es.regexp.exec"),e("core-js/modules/es.regexp.to-string"),e("core-js/modules/es.set"),e("core-js/modules/es.string.includes"),e("core-js/modules/es.string.iterator"),e("core-js/modules/es.string.split"),e("core-js/modules/web.dom-collections.for-each"),e("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var n,o=(n=e("../main"))&&n.__esModule?n:{default:n};(function(e){if(e&&e.__esModule)return;if(null===e||"object"!==s(e)&&"function"!=typeof e)return;var t=a();if(t&&t.has(e))return t.get(e);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=n?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(r,o,i):r[o]=e[o]}r.default=e,t&&t.set(e,r)})(e("../constants")),e("../internationalization");function a(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return a=function(){return e},e}function s(e){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}o.default._validateParameters=o.default._clearValidateParamsCache=function(){};var i=o.default;r.default=i},{"../../../docs/parameterData.json":void 0,"../constants":253,"../internationalization":262,"../main":264,"core-js/modules/es.array.concat":149,"core-js/modules/es.array.for-each":154,"core-js/modules/es.array.includes":156,"core-js/modules/es.array.index-of":157,"core-js/modules/es.array.iterator":158,"core-js/modules/es.array.join":159,"core-js/modules/es.array.last-index-of":160,"core-js/modules/es.array.map":161,"core-js/modules/es.array.slice":162,"core-js/modules/es.function.name":166,"core-js/modules/es.map":167,"core-js/modules/es.number.constructor":170,"core-js/modules/es.object.get-prototype-of":175,"core-js/modules/es.object.keys":176,"core-js/modules/es.object.to-string":177,"core-js/modules/es.reflect.construct":179,"core-js/modules/es.regexp.exec":181,"core-js/modules/es.regexp.to-string":182,"core-js/modules/es.set":183,"core-js/modules/es.string.includes":185,"core-js/modules/es.string.iterator":186,"core-js/modules/es.string.split":191,"core-js/modules/es.symbol":196,"core-js/modules/es.symbol.description":194,"core-js/modules/es.symbol.iterator":195,"core-js/modules/web.dom-collections.for-each":228,"core-js/modules/web.dom-collections.iterator":229}],260:[function(e,t,r){"use strict";function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var i=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==a(e)&&"function"!=typeof e)return{default:e};var t=s();if(t&&t.has(e))return t.get(e);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=n?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(r,o,i):r[o]=e[o]}r.default=e,t&&t.set(e,r);return r}(e("./constants"));function s(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return s=function(){return e},e}var n={modeAdjust:function(e,t,r,n,o){return o===i.CORNER?{x:e,y:t,w:r,h:n}:o===i.CORNERS?{x:e,y:t,w:r-e,h:n-t}:o===i.RADIUS?{x:e-r,y:t-n,w:2*r,h:2*n}:o===i.CENTER?{x:e-.5*r,y:t-.5*n,w:r,h:n}:void 0}};r.default=n},{"./constants":253}],261:[function(e,t,r){"use strict";e("core-js/modules/es.array.iterator"),e("core-js/modules/es.object.to-string"),e("core-js/modules/es.promise"),e("core-js/modules/es.string.iterator"),e("core-js/modules/web.dom-collections.iterator");var n,o=(n=e("../core/main"))&&n.__esModule?n:{default:n};e("./internationalization");var i=Promise.resolve();Promise.all([new Promise(function(e,t){"complete"===document.readyState?e():window.addEventListener("load",e,!1)}),i]).then(function(){void 0===window._setupDone?window.mocha||(window.setup&&"function"==typeof window.setup||window.draw&&"function"==typeof window.draw)&&!o.default.instance&&new o.default:console.warn("p5.js seems to have been imported multiple times. Please remove the duplicate import")})},{"../core/main":264,"./internationalization":262,"core-js/modules/es.array.iterator":158,"core-js/modules/es.object.to-string":177,"core-js/modules/es.promise":178,"core-js/modules/es.string.iterator":186,"core-js/modules/web.dom-collections.iterator":229}],262:[function(e,t,r){"use strict";e("core-js/modules/es.array.includes"),e("core-js/modules/es.array.iterator"),e("core-js/modules/es.array.join"),e("core-js/modules/es.array.slice"),e("core-js/modules/es.object.keys"),e("core-js/modules/es.object.to-string"),e("core-js/modules/es.promise"),e("core-js/modules/es.regexp.exec"),e("core-js/modules/es.string.includes"),e("core-js/modules/es.string.iterator"),e("core-js/modules/es.string.split"),e("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(r,"__esModule",{value:!0}),r.setTranslatorLanguage=r.currentTranslatorLanguage=r.availableTranslatorLanguages=r.initialize=r.translator=void 0;var i,a,n=s(e("i18next")),o=s(e("i18next-browser-languagedetector"));function s(e){return e&&e.__esModule?e:{default:e}}function l(e,t){for(var r=0;r=a.width||t>=a.height?[0,0,0,0]:this._getPixel(e,t);var s=new l.default.Image(r,n);return s.canvas.getContext("2d").drawImage(a,e,t,r*i,n*i,0,0,r,n),s},l.default.Renderer.prototype.textLeading=function(e){return"number"==typeof e?(this._setProperty("_leadingSet",!0),this._setProperty("_textLeading",e),this._pInst):this._textLeading},l.default.Renderer.prototype.textSize=function(e){return"number"==typeof e?(this._setProperty("_textSize",e),this._leadingSet||this._setProperty("_textLeading",e*k._DEFAULT_LEADMULT),this._applyTextProperties()):this._textSize},l.default.Renderer.prototype.textStyle=function(e){return e?(e!==k.NORMAL&&e!==k.ITALIC&&e!==k.BOLD&&e!==k.BOLDITALIC||this._setProperty("_textStyle",e),this._applyTextProperties()):this._textStyle},l.default.Renderer.prototype.textAscent=function(){return null===this._textAscent&&this._updateTextMetrics(),this._textAscent},l.default.Renderer.prototype.textDescent=function(){return null===this._textDescent&&this._updateTextMetrics(),this._textDescent},l.default.Renderer.prototype.textAlign=function(e,t){return void 0!==e?(this._setProperty("_textAlign",e),void 0!==t&&this._setProperty("_textBaseline",t),this._applyTextProperties()):{horizontal:this._textAlign,vertical:this._textBaseline}},l.default.Renderer.prototype.textWrap=function(e){return this._setProperty("_textWrap",e),this._textWrap},l.default.Renderer.prototype.text=function(e,t,r,n,o){var i,a,s,l,u,c,d,f=this._pInst,h=this._textWrap,p=Number.MAX_VALUE;if((this._doFill||this._doStroke)&&void 0!==e){if("string"!=typeof e&&(e=e.toString()),i=(e=e.replace(/(\t)/g," ")).split("\n"),void 0!==n){switch(this._rectMode===k.CENTER&&(t-=n/2),this._textAlign){case k.CENTER:t+=n/2;break;case k.RIGHT:t+=n}var y=!1;if(void 0!==o){switch(this._rectMode===k.CENTER&&(r-=o/2),this._textBaseline){case k.BOTTOM:d=r+o,r=Math.max(d,r);break;case k.CENTER:d=r+o/2,r=Math.max(d,r);break;case k.BASELINE:y=!0,this._textBaseline=k.TOP}p=r+o-f.textAscent()}if(h===k.WORD){for(var m=[],g=0;gs.HALF_PI&&e<=3*s.HALF_PI?Math.atan(r/n*Math.tan(e))+s.PI:Math.atan(r/n*Math.tan(e))+s.TWO_PI,t=t<=s.HALF_PI?Math.atan(r/n*Math.tan(t)):t>s.HALF_PI&&t<=3*s.HALF_PI?Math.atan(r/n*Math.tan(t))+s.PI:Math.atan(r/n*Math.tan(t))+s.TWO_PI),ty||Math.abs(this.accelerationY-this.pAccelerationY)>y||Math.abs(this.accelerationZ-this.pAccelerationZ)>y)&&r.deviceMoved(),"function"==typeof r.deviceTurned){var n=this.rotationX+180,o=this.pRotationX+180,i=u+180;0>>24],n+=x[(16711680&T)>>16],o+=x[(65280&T)>>8],i+=x[255&T],r+=L[_],s++}w[l=E+v]=a/r,j[l]=n/r,S[l]=o/r,M[l]=i/r}E+=h}for(c=(u=-O)*h,b=E=0;b>>16,e[r+1]=(65280&t[n])>>>8,e[r+2]=255&t[n],e[r+3]=(4278190080&t[n])>>>24},A._toImageData=function(e){return e instanceof ImageData?e:e.getContext("2d").getImageData(0,0,e.width,e.height)},A._createImageData=function(e,t){return A._tmpCanvas=document.createElement("canvas"),A._tmpCtx=A._tmpCanvas.getContext("2d"),this._tmpCtx.createImageData(e,t)},A.apply=function(e,t,r){var n=e.getContext("2d"),o=n.getImageData(0,0,e.width,e.height),i=t(o,r);i instanceof ImageData?n.putImageData(i,0,0,0,0,e.width,e.height):n.putImageData(o,0,0,0,0,e.width,e.height)},A.threshold=function(e,t){var r=A._toPixels(e);void 0===t&&(t=.5);for(var n=Math.floor(255*t),o=0;o>8)/n,r[o+1]=255*(a*t>>8)/n,r[o+2]=255*(s*t>>8)/n}},A.dilate=function(e){for(var t,r,n,o,i,a,s,l,u,c,d,f,h,p,y,m,g,v=A._toPixels(e),b=0,_=v.length?v.length/4:0,x=new Int32Array(_);b<_;)for(r=(t=b)+e.width;b>16&255)+151*(n>>8&255)+28*(255&n))<(y=77*(d>>16&255)+151*(d>>8&255)+28*(255&d))&&(o=d,i=y),i<(p=77*((c=A._getARGB(v,a))>>16&255)+151*(c>>8&255)+28*(255&c))&&(o=c,i=p),i<(m=77*(f>>16&255)+151*(f>>8&255)+28*(255&f))&&(o=f,i=m),i<(g=77*(h>>16&255)+151*(h>>8&255)+28*(255&h))&&(o=h,i=g),x[b++]=o;A._setPixels(v,x)},A.erode=function(e){for(var t,r,n,o,i,a,s,l,u,c,d,f,h,p,y,m,g,v=A._toPixels(e),b=0,_=v.length?v.length/4:0,x=new Int32Array(_);b<_;)for(r=(t=b)+e.width;b>16&255)+151*(d>>8&255)+28*(255&d))<(i=77*(n>>16&255)+151*(n>>8&255)+28*(255&n))&&(o=d,i=y),(p=77*((c=A._getARGB(v,a))>>16&255)+151*(c>>8&255)+28*(255&c))>16&255)+151*(f>>8&255)+28*(255&f))>16&255)+151*(h>>8&255)+28*(255&h))=n){var o=Math.floor(t.timeDisplayed/n);if(t.timeDisplayed=0,t.lastChangeTime=r,t.displayIndex+=o,t.loopCount=Math.floor(t.displayIndex/t.numFrames),null!==t.loopLimit&&t.loopCount>=t.loopLimit)t.playing=!1;else{var i=t.displayIndex%t.numFrames;this.drawingContext.putImageData(t.frames[i].image,0,0),t.displayIndex=i,this.setModified(!0)}}}},o.default.Image.prototype._setProperty=function(e,t){this[e]=t,this.setModified(!0)},o.default.Image.prototype.loadPixels=function(){o.default.Renderer2D.prototype.loadPixels.call(this),this.setModified(!0)},o.default.Image.prototype.updatePixels=function(e,t,r,n){o.default.Renderer2D.prototype.updatePixels.call(this,e,t,r,n),this.setModified(!0)},o.default.Image.prototype.get=function(e,t,r,n){return o.default._validateParameters("p5.Image.get",arguments),o.default.Renderer2D.prototype.get.apply(this,arguments)},o.default.Image.prototype._getPixel=o.default.Renderer2D.prototype._getPixel,o.default.Image.prototype.set=function(e,t,r){o.default.Renderer2D.prototype.set.call(this,e,t,r),this.setModified(!0)},o.default.Image.prototype.resize=function(e,t){0===e&&0===t?(e=this.canvas.width,t=this.canvas.height):0===e?e=this.canvas.width*t/this.canvas.height:0===t&&(t=this.canvas.height*e/this.canvas.width),e=Math.floor(e),t=Math.floor(t);var r=document.createElement("canvas");if(r.width=e,r.height=t,this.gifProperties)for(var n=this.gifProperties,o=function(e,t){for(var r=0,n=0;n/g,">").replace(/"/g,""").replace(/'/g,"'")}function l(e,t){t&&!0!==t&&"true"!==t||(t="");var r="";return(e=e||"untitled")&&e.includes(".")&&(r=e.split(".").pop()),t&&r!==t&&(r=t,e="".concat(e,".").concat(r)),[e,r]}e("../core/friendly_errors/validate_params"),e("../core/friendly_errors/file_errors"),e("../core/friendly_errors/fes_core"),g.default.prototype.loadJSON=function(){for(var e=arguments.length,t=new Array(e),r=0;r"),o.print("");if(o.print(' '),o.print(""),o.print(""),o.print(" "),"0"!==i[0]){o.print(" ");for(var c=0;c".concat(d)),o.print(" ")}o.print(" ")}for(var f=0;f");for(var h=0;h".concat(p)),o.print(" ")}o.print(" ")}o.print("
        "),o.print(""),o.print("")}o.close(),o.clear()},g.default.prototype.writeFile=function(e,t,r){var n="application/octet-stream";g.default.prototype._isSafari()&&(n="text/plain");var o=new Blob(e,{type:n});g.default.prototype.downloadFile(o,t,r)},g.default.prototype.downloadFile=function(e,t,r){var n=l(t,r),o=n[0];if(e instanceof Blob)s.default.saveAs(e,o);else{var i=document.createElement("a");if(i.href=e,i.download=o,i.onclick=function(e){var t;t=e,document.body.removeChild(t.target),e.stopPropagation()},i.style.display="none",document.body.appendChild(i),g.default.prototype._isSafari()){var a="Hello, Safari user! To download this file...\n";a+="1. Go to File --\x3e Save As.\n",a+='2. Choose "Page Source" as the Format.\n',a+='3. Name it with this extension: ."'.concat(n[1],'"'),alert(a)}i.click()}},g.default.prototype._checkFileExtension=l,g.default.prototype._isSafari=function(){return 0>>0},getSeed:function(){return t},rand:function(){return(r=(1664525*r+1013904223)%n)/n}});o.setSeed(e),_=new Array(4096);for(var i=0;i<4096;i++)_[i]=o.rand()};var i=o.default;r.default=i},{"../core/main":264}],297:[function(e,t,r){"use strict";function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}e("core-js/modules/es.array.concat"),e("core-js/modules/es.array.every"),e("core-js/modules/es.array.slice"),e("core-js/modules/es.array.some"),e("core-js/modules/es.math.sign"),e("core-js/modules/es.number.constructor"),e("core-js/modules/es.number.is-finite"),e("core-js/modules/es.object.to-string"),e("core-js/modules/es.regexp.to-string"),e("core-js/modules/es.string.sub"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var n,l=(n=e("../core/main"))&&n.__esModule?n:{default:n},i=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==a(e)&&"function"!=typeof e)return{default:e};var t=s();if(t&&t.has(e))return t.get(e);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=n?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(r,o,i):r[o]=e[o]}r.default=e,t&&t.set(e,r);return r}(e("../core/constants"));function s(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return s=function(){return e},e}l.default.Vector=function(e,t,r,n,o){var i,a,s;s="[object Function]"==={}.toString.call(e)?(this.isPInst=!0,this._fromRadians=e,this._toRadians=t,i=r||0,a=n||0,o||0):(i=e||0,a=t||0,r||0),this.x=i,this.y=a,this.z=s},l.default.Vector.prototype.toString=function(){return"p5.Vector Object : [".concat(this.x,", ").concat(this.y,", ").concat(this.z,"]")},l.default.Vector.prototype.set=function(e,t,r){return e instanceof l.default.Vector?(this.x=e.x||0,this.y=e.y||0,this.z=e.z||0):e instanceof Array?(this.x=e[0]||0,this.y=e[1]||0,this.z=e[2]||0):(this.x=e||0,this.y=t||0,this.z=r||0),this},l.default.Vector.prototype.copy=function(){return this.isPInst?new l.default.Vector(this._fromRadians,this._toRadians,this.x,this.y,this.z):new l.default.Vector(this.x,this.y,this.z)},l.default.Vector.prototype.add=function(e,t,r){return e instanceof l.default.Vector?(this.x+=e.x||0,this.y+=e.y||0,this.z+=e.z||0):e instanceof Array?(this.x+=e[0]||0,this.y+=e[1]||0,this.z+=e[2]||0):(this.x+=e||0,this.y+=t||0,this.z+=r||0),this};function u(e,t){return 0!==e&&(this.x=this.x%e),0!==t&&(this.y=this.y%t),this}function c(e,t,r){return 0!==e&&(this.x=this.x%e),0!==t&&(this.y=this.y%t),0!==r&&(this.z=this.z%r),this}l.default.Vector.prototype.rem=function(e,t,r){if(e instanceof l.default.Vector){if(Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.z)){var n=parseFloat(e.x),o=parseFloat(e.y),i=parseFloat(e.z);return c.call(this,n,o,i)}}else if(e instanceof Array){if(e.every(function(e){return Number.isFinite(e)})){if(2===e.length)return u.call(this,e[0],e[1]);if(3===e.length)return c.call(this,e[0],e[1],e[2])}}else if(1===arguments.length){if(Number.isFinite(e)&&0!==e)return this.x=this.x%e,this.y=this.y%e,this.z=this.z%e,this}else if(2===arguments.length){var a=Array.prototype.slice.call(arguments);if(a.every(function(e){return Number.isFinite(e)})&&2===a.length)return u.call(this,a[0],a[1])}else if(3===arguments.length){var s=Array.prototype.slice.call(arguments);if(s.every(function(e){return Number.isFinite(e)})&&3===s.length)return c.call(this,s[0],s[1],s[2])}},l.default.Vector.prototype.sub=function(e,t,r){return e instanceof l.default.Vector?(this.x-=e.x||0,this.y-=e.y||0,this.z-=e.z||0):e instanceof Array?(this.x-=e[0]||0,this.y-=e[1]||0,this.z-=e[2]||0):(this.x-=e||0,this.y-=t||0,this.z-=r||0),this},l.default.Vector.prototype.mult=function(e,t,r){if(e instanceof l.default.Vector)return Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.z)&&"number"==typeof e.x&&"number"==typeof e.y&&"number"==typeof e.z?(this.x*=e.x,this.y*=e.y,this.z*=e.z):console.warn("p5.Vector.prototype.mult:","x contains components that are either undefined or not finite numbers"),this;if(e instanceof Array)return e.every(function(e){return Number.isFinite(e)})&&e.every(function(e){return"number"==typeof e})?1===e.length?(this.x*=e[0],this.y*=e[0],this.z*=e[0]):2===e.length?(this.x*=e[0],this.y*=e[1]):3===e.length&&(this.x*=e[0],this.y*=e[1],this.z*=e[2]):console.warn("p5.Vector.prototype.mult:","x contains elements that are either undefined or not finite numbers"),this;var n=Array.prototype.slice.call(arguments);return n.every(function(e){return Number.isFinite(e)})&&n.every(function(e){return"number"==typeof e})?(1===arguments.length&&(this.x*=e,this.y*=e,this.z*=e),2===arguments.length&&(this.x*=e,this.y*=t),3===arguments.length&&(this.x*=e,this.y*=t,this.z*=r)):console.warn("p5.Vector.prototype.mult:","x, y, or z arguments are either undefined or not a finite number"),this},l.default.Vector.prototype.div=function(e,t,r){if(e instanceof l.default.Vector){if(Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.z)&&"number"==typeof e.x&&"number"==typeof e.y&&"number"==typeof e.z){if(0===e.x||0===e.y||0===e.z)return console.warn("p5.Vector.prototype.div:","divide by 0"),this;this.x/=e.x,this.y/=e.y,this.z/=e.z}else console.warn("p5.Vector.prototype.div:","x contains components that are either undefined or not finite numbers");return this}if(e instanceof Array){if(e.every(function(e){return Number.isFinite(e)})&&e.every(function(e){return"number"==typeof e})){if(e.some(function(e){return 0===e}))return console.warn("p5.Vector.prototype.div:","divide by 0"),this;1===e.length?(this.x/=e[0],this.y/=e[0],this.z/=e[0]):2===e.length?(this.x/=e[0],this.y/=e[1]):3===e.length&&(this.x/=e[0],this.y/=e[1],this.z/=e[2])}else console.warn("p5.Vector.prototype.div:","x contains components that are either undefined or not finite numbers");return this}var n=Array.prototype.slice.call(arguments);if(n.every(function(e){return Number.isFinite(e)})&&n.every(function(e){return"number"==typeof e})){if(n.some(function(e){return 0===e}))return console.warn("p5.Vector.prototype.div:","divide by 0"),this;1===arguments.length&&(this.x/=e,this.y/=e,this.z/=e),2===arguments.length&&(this.x/=e,this.y/=t),3===arguments.length&&(this.x/=e,this.y/=t,this.z/=r)}else console.warn("p5.Vector.prototype.div:","x, y, or z arguments are either undefined or not a finite number");return this},l.default.Vector.prototype.mag=function(){return Math.sqrt(this.magSq())},l.default.Vector.prototype.magSq=function(){var e=this.x,t=this.y,r=this.z;return e*e+t*t+r*r},l.default.Vector.prototype.dot=function(e,t,r){return e instanceof l.default.Vector?this.dot(e.x,e.y,e.z):this.x*(e||0)+this.y*(t||0)+this.z*(r||0)},l.default.Vector.prototype.cross=function(e){var t=this.y*e.z-this.z*e.y,r=this.z*e.x-this.x*e.z,n=this.x*e.y-this.y*e.x;return this.isPInst?new l.default.Vector(this._fromRadians,this._toRadians,t,r,n):new l.default.Vector(t,r,n)},l.default.Vector.prototype.dist=function(e){return e.copy().sub(this).mag()},l.default.Vector.prototype.normalize=function(){var e=this.mag();return 0!==e&&this.mult(1/e),this},l.default.Vector.prototype.limit=function(e){var t=this.magSq();return e*e>>0},o.default.prototype.randomSeed=function(e){this._lcgSetSeed(i,e),this._gaussian_previous=!1},o.default.prototype.random=function(e,t){var r;if(o.default._validateParameters("random",arguments),r=null!=this[i]?this._lcg(i):Math.random(),void 0===e)return r;if(void 0===t)return e instanceof Array?e[Math.floor(r*e.length)]:r*e;if(tf){var O=p,C=l,L=u;p=h+f*(s&&h=t&&(r=r.substring(r.length-t,r.length)),r}},o.default.prototype.unhex=function(e){return e instanceof Array?e.map(o.default.prototype.unhex):parseInt("0x".concat(e),16)};var i=o.default;r.default=i},{"../core/main":264,"core-js/modules/es.array.map":161,"core-js/modules/es.number.constructor":170,"core-js/modules/es.object.to-string":177,"core-js/modules/es.regexp.to-string":182,"core-js/modules/es.string.repeat":188}],305:[function(e,t,r){"use strict";e("core-js/modules/es.array.filter"),e("core-js/modules/es.array.index-of"),e("core-js/modules/es.array.join"),e("core-js/modules/es.array.map"),e("core-js/modules/es.array.slice"),e("core-js/modules/es.object.to-string"),e("core-js/modules/es.regexp.constructor"),e("core-js/modules/es.regexp.exec"),e("core-js/modules/es.regexp.to-string"),e("core-js/modules/es.string.match"),e("core-js/modules/es.string.replace"),e("core-js/modules/es.string.split"),e("core-js/modules/es.string.trim"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var n,a=(n=e("../core/main"))&&n.__esModule?n:{default:n};function o(e,t,r){var n=e<0,o=n?e.toString().substring(1):e.toString(),i=o.indexOf("."),a=-1!==i?o.substring(0,i):o,s=-1!==i?o.substring(i+1):"",l=n?"-":"";if(void 0!==r){var u="";(-1!==i||0r&&(s=s.substring(0,r));for(var c=0;cn.length)for(var i=t-(n+=-1===r?".":"").length+1,a=0;a=h.TWO_PI?"".concat(t="ellipse","|").concat(c,"|"):"".concat(t="arc","|").concat(s,"|").concat(l,"|").concat(u,"|").concat(c,"|"),!this.geometryInHash(r)){var d=new E.default.Geometry(c,1,function(){if(this.strokeIndices=[],s.toFixed(10)!==l.toFixed(10)){u!==h.PIE&&void 0!==u||(this.vertices.push(new E.default.Vector(.5,.5,0)),this.uvs.push([.5,.5]));for(var e=0;e<=c;e++){var t=(l-s)*(e/c)+s,r=.5+Math.cos(t)/2,n=.5+Math.sin(t)/2;this.vertices.push(new E.default.Vector(r,n,0)),this.uvs.push([r,n]),e>5&31)/31,(v>>10&31)/31):(r=a,n=s,l)}for(var b=new j.default.Vector(y,m,g),_=1;_<=3;_++){var x=p+12*_,w=new j.default.Vector(u.getFloat32(x,!0),u.getFloat32(4+x,!0),u.getFloat32(8+x,!0));e.vertices.push(w),e.vertexNormals.push(b),d&&i.push(r,n,o)}e.faces.push([3*h,3*h+1,3*h+2]),e.uvs.push([0,0],[0,0],[0,0])}}(e,t);else{var r=new DataView(t);if(!("TextDecoder"in window))return console.warn("Sorry, ASCII STL loading only works in browsers that support TextDecoder (https://caniuse.com/#feat=textencoder)");var n=new TextDecoder("utf-8").decode(r).split("\n");!function(e,t){for(var r,n,o="",i=[],a=0;aMath.PI?l=Math.PI:l<=0&&(l=.001);var u=Math.sin(l)*a*Math.sin(s),c=Math.cos(l)*a,d=Math.sin(l)*a*Math.cos(s);this.camera(u+this.centerX,c+this.centerY,d+this.centerZ,this.centerX,this.centerY,this.centerZ,0,1,0)},y.default.Camera.prototype._isActive=function(){return this===this._renderer._curCamera},y.default.prototype.setCamera=function(e){this._renderer._curCamera=e,this._renderer.uPMatrix.set(e.projMatrix.mat4[0],e.projMatrix.mat4[1],e.projMatrix.mat4[2],e.projMatrix.mat4[3],e.projMatrix.mat4[4],e.projMatrix.mat4[5],e.projMatrix.mat4[6],e.projMatrix.mat4[7],e.projMatrix.mat4[8],e.projMatrix.mat4[9],e.projMatrix.mat4[10],e.projMatrix.mat4[11],e.projMatrix.mat4[12],e.projMatrix.mat4[13],e.projMatrix.mat4[14],e.projMatrix.mat4[15])};var o=y.default.Camera;r.default=o},{"../core/main":264}],313:[function(e,t,r){"use strict";e("core-js/modules/es.string.sub"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var n,c=(n=e("../core/main"))&&n.__esModule?n:{default:n};c.default.Geometry=function(e,t,r){return this.vertices=[],this.lineVertices=[],this.lineNormals=[],this.vertexNormals=[],this.faces=[],this.uvs=[],this.edges=[],this.vertexColors=[],this.detailX=void 0!==e?e:1,this.detailY=void 0!==t?t:1,this.dirtyFlags={},r instanceof Function&&r.call(this),this},c.default.Geometry.prototype.reset=function(){this.lineVertices.length=0,this.lineNormals.length=0,this.vertices.length=0,this.edges.length=0,this.vertexColors.length=0,this.vertexNormals.length=0,this.uvs.length=0,this.dirtyFlags={}},c.default.Geometry.prototype.computeFaces=function(){this.faces.length=0;for(var e,t,r,n,o=this.detailX+1,i=0;ithis.vertices.length-1-this.detailX;n--)e.add(this.vertexNormals[n]);e=c.default.Vector.div(e,this.detailX);for(var o=this.vertices.length-1;o>this.vertices.length-1-this.detailX;o--)this.vertexNormals[o]=e;return this},c.default.Geometry.prototype._makeTriangleEdges=function(){if(this.edges.length=0,Array.isArray(this.strokeIndices))for(var e=0,t=this.strokeIndices.length;e 65535 triangles. Your web browser does not support the WebGL Extension OES_element_index_uint.");n.drawElements(n.TRIANGLES,r.vertexCount,r.indexBufferType,0)}else n.drawArrays(e||n.TRIANGLES,0,r.vertexCount)},l.default.RendererGL.prototype._drawPoints=function(e,t){var r=this.GL,n=this._getImmediatePointShader();this._setPointUniforms(n),this._bindBuffer(t,r.ARRAY_BUFFER,this._vToNArray(e),Float32Array,r.STATIC_DRAW),n.enableAttrib(n.attributes.aPosition,3),r.drawArrays(r.Points,0,e.length),n.unbindShader()};var i=l.default.RendererGL;r.default=i},{"../core/main":264,"./p5.RenderBuffer":315,"./p5.RendererGL":318,"core-js/modules/es.array.fill":151,"core-js/modules/es.array.iterator":158,"core-js/modules/es.array.some":163,"core-js/modules/es.object.keys":176,"core-js/modules/es.object.to-string":177,"core-js/modules/es.string.iterator":186,"core-js/modules/es.symbol":196,"core-js/modules/es.symbol.description":194,"core-js/modules/es.symbol.iterator":195,"core-js/modules/es.typed-array.copy-within":197,"core-js/modules/es.typed-array.every":198,"core-js/modules/es.typed-array.fill":199,"core-js/modules/es.typed-array.filter":200,"core-js/modules/es.typed-array.find":202,"core-js/modules/es.typed-array.find-index":201,"core-js/modules/es.typed-array.float32-array":203,"core-js/modules/es.typed-array.for-each":205,"core-js/modules/es.typed-array.includes":206,"core-js/modules/es.typed-array.index-of":207,"core-js/modules/es.typed-array.iterator":210,"core-js/modules/es.typed-array.join":211,"core-js/modules/es.typed-array.last-index-of":212,"core-js/modules/es.typed-array.map":213,"core-js/modules/es.typed-array.reduce":215,"core-js/modules/es.typed-array.reduce-right":214,"core-js/modules/es.typed-array.reverse":216,"core-js/modules/es.typed-array.set":217,"core-js/modules/es.typed-array.slice":218,"core-js/modules/es.typed-array.some":219,"core-js/modules/es.typed-array.sort":220,"core-js/modules/es.typed-array.subarray":221,"core-js/modules/es.typed-array.to-locale-string":222,"core-js/modules/es.typed-array.to-string":223,"core-js/modules/es.typed-array.uint16-array":224,"core-js/modules/es.typed-array.uint32-array":225,"core-js/modules/web.dom-collections.iterator":229}],318:[function(e,t,r){"use strict";function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}e("core-js/modules/es.symbol"),e("core-js/modules/es.symbol.description"),e("core-js/modules/es.symbol.iterator"),e("core-js/modules/es.array.concat"),e("core-js/modules/es.array.fill"),e("core-js/modules/es.array.filter"),e("core-js/modules/es.array.from"),e("core-js/modules/es.array.includes"),e("core-js/modules/es.array.iterator"),e("core-js/modules/es.array.slice"),e("core-js/modules/es.object.assign"),e("core-js/modules/es.object.to-string"),e("core-js/modules/es.regexp.to-string"),e("core-js/modules/es.string.includes"),e("core-js/modules/es.string.iterator"),e("core-js/modules/es.typed-array.float32-array"),e("core-js/modules/es.typed-array.float64-array"),e("core-js/modules/es.typed-array.int16-array"),e("core-js/modules/es.typed-array.uint8-array"),e("core-js/modules/es.typed-array.uint16-array"),e("core-js/modules/es.typed-array.uint32-array"),e("core-js/modules/es.typed-array.copy-within"),e("core-js/modules/es.typed-array.every"),e("core-js/modules/es.typed-array.fill"),e("core-js/modules/es.typed-array.filter"),e("core-js/modules/es.typed-array.find"),e("core-js/modules/es.typed-array.find-index"),e("core-js/modules/es.typed-array.for-each"),e("core-js/modules/es.typed-array.includes"),e("core-js/modules/es.typed-array.index-of"),e("core-js/modules/es.typed-array.iterator"),e("core-js/modules/es.typed-array.join"),e("core-js/modules/es.typed-array.last-index-of"),e("core-js/modules/es.typed-array.map"),e("core-js/modules/es.typed-array.reduce"),e("core-js/modules/es.typed-array.reduce-right"),e("core-js/modules/es.typed-array.reverse"),e("core-js/modules/es.typed-array.set"),e("core-js/modules/es.typed-array.slice"),e("core-js/modules/es.typed-array.some"),e("core-js/modules/es.typed-array.sort"),e("core-js/modules/es.typed-array.subarray"),e("core-js/modules/es.typed-array.to-locale-string"),e("core-js/modules/es.typed-array.to-string"),e("core-js/modules/web.dom-collections.iterator"),Object.defineProperty(r,"__esModule",{value:!0}),r.default=void 0;var u=o(e("../core/main")),i=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==a(e)&&"function"!=typeof e)return{default:e};var t=s();if(t&&t.has(e))return t.get(e);var r={},n=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=n?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(r,o,i):r[o]=e[o]}r.default=e,t&&t.set(e,r);return r}(e("../core/constants")),n=o(e("libtess"));e("./p5.Shader"),e("./p5.Camera"),e("../core/p5.Renderer"),e("./p5.Matrix");e("path");function s(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return s=function(){return e},e}function o(e){return e&&e.__esModule?e:{default:e}}function l(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t vTexCoord.y;\n bool y1 = p1.y > vTexCoord.y;\n bool y2 = p2.y > vTexCoord.y;\n\n // could web be under the curve (after t1)?\n if (y1 ? !y2 : y0) {\n // add the coverage for t1\n coverage.x += saturate(C1.x + 0.5);\n // calculate the anti-aliasing for t1\n weight.x = min(weight.x, abs(C1.x));\n }\n\n // are we outside the curve (after t2)?\n if (y1 ? !y0 : y2) {\n // subtract the coverage for t2\n coverage.x -= saturate(C2.x + 0.5);\n // calculate the anti-aliasing for t2\n weight.x = min(weight.x, abs(C2.x));\n }\n}\n\n// this is essentially the same as coverageX, but with the axes swapped\nvoid coverageY(vec2 p0, vec2 p1, vec2 p2) {\n\n vec2 C1, C2;\n calulateCrossings(p0, p1, p2, C1, C2);\n\n bool x0 = p0.x > vTexCoord.x;\n bool x1 = p1.x > vTexCoord.x;\n bool x2 = p2.x > vTexCoord.x;\n\n if (x1 ? !x2 : x0) {\n coverage.y -= saturate(C1.y + 0.5);\n weight.y = min(weight.y, abs(C1.y));\n }\n\n if (x1 ? !x0 : x2) {\n coverage.y += saturate(C2.y + 0.5);\n weight.y = min(weight.y, abs(C2.y));\n }\n}\n\nvoid main() {\n\n // calculate the pixel scale based on screen-coordinates\n pixelScale = hardness / fwidth(vTexCoord);\n\n // which grid cell is this pixel in?\n ivec2 gridCoord = ifloor(vTexCoord * vec2(uGridSize));\n\n // intersect curves in this row\n {\n // the index into the row info bitmap\n int rowIndex = gridCoord.y + uGridOffset.y;\n // fetch the info texel\n vec4 rowInfo = getTexel(uSamplerRows, rowIndex, uGridImageSize);\n // unpack the rowInfo\n int rowStrokeIndex = getInt16(rowInfo.xy);\n int rowStrokeCount = getInt16(rowInfo.zw);\n\n for (int iRowStroke = INT(0); iRowStroke < N; iRowStroke++) {\n if (iRowStroke >= rowStrokeCount)\n break;\n\n // each stroke is made up of 3 points: the start and control point\n // and the start of the next curve.\n // fetch the indices of this pair of strokes:\n vec4 strokeIndices = getTexel(uSamplerRowStrokes, rowStrokeIndex++, uCellsImageSize);\n\n // unpack the stroke index\n int strokePos = getInt16(strokeIndices.xy);\n\n // fetch the two strokes\n vec4 stroke0 = getTexel(uSamplerStrokes, strokePos + INT(0), uStrokeImageSize);\n vec4 stroke1 = getTexel(uSamplerStrokes, strokePos + INT(1), uStrokeImageSize);\n\n // calculate the coverage\n coverageX(stroke0.xy, stroke0.zw, stroke1.xy);\n }\n }\n\n // intersect curves in this column\n {\n int colIndex = gridCoord.x + uGridOffset.x;\n vec4 colInfo = getTexel(uSamplerCols, colIndex, uGridImageSize);\n int colStrokeIndex = getInt16(colInfo.xy);\n int colStrokeCount = getInt16(colInfo.zw);\n \n for (int iColStroke = INT(0); iColStroke < N; iColStroke++) {\n if (iColStroke >= colStrokeCount)\n break;\n\n vec4 strokeIndices = getTexel(uSamplerColStrokes, colStrokeIndex++, uCellsImageSize);\n\n int strokePos = getInt16(strokeIndices.xy);\n vec4 stroke0 = getTexel(uSamplerStrokes, strokePos + INT(0), uStrokeImageSize);\n vec4 stroke1 = getTexel(uSamplerStrokes, strokePos + INT(1), uStrokeImageSize);\n coverageY(stroke0.xy, stroke0.zw, stroke1.xy);\n }\n }\n\n weight = saturate(1.0 - weight * 2.0);\n float distance = max(weight.x + weight.y, minDistance); // manhattan approx.\n float antialias = abs(dot(coverage, weight) / distance);\n float cover = min(abs(coverage.x), abs(coverage.y));\n gl_FragColor = uMaterialColor;\n gl_FragColor.a *= saturate(max(antialias, cover));\n}",lineVert:"/*\n Part of the Processing project - http://processing.org\n Copyright (c) 2012-15 The Processing Foundation\n Copyright (c) 2004-12 Ben Fry and Casey Reas\n Copyright (c) 2001-04 Massachusetts Institute of Technology\n This library is free software; you can redistribute it and/or\n modify it under the terms of the GNU Lesser General Public\n License as published by the Free Software Foundation, version 2.1.\n This library is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n Lesser General Public License for more details.\n You should have received a copy of the GNU Lesser General\n Public License along with this library; if not, write to the\n Free Software Foundation, Inc., 59 Temple Place, Suite 330,\n Boston, MA 02111-1307 USA\n*/\n\n#define PROCESSING_LINE_SHADER\n\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;\nuniform float uStrokeWeight;\n\nuniform vec4 uViewport;\nuniform int uPerspective;\n\nattribute vec4 aPosition;\nattribute vec4 aDirection;\n \nvoid main() {\n // using a scale <1 moves the lines towards the camera\n // in order to prevent popping effects due to half of\n // the line disappearing behind the geometry faces.\n vec3 scale = vec3(0.9995);\n\n vec4 posp = uModelViewMatrix * aPosition;\n vec4 posq = uModelViewMatrix * (aPosition + vec4(aDirection.xyz, 0));\n\n // Moving vertices slightly toward the camera\n // to avoid depth-fighting with the fill triangles.\n // Discussed here:\n // http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=252848 \n posp.xyz = posp.xyz * scale;\n posq.xyz = posq.xyz * scale;\n\n vec4 p = uProjectionMatrix * posp;\n vec4 q = uProjectionMatrix * posq;\n\n // formula to convert from clip space (range -1..1) to screen space (range 0..[width or height])\n // screen_p = (p.xy/p.w + <1,1>) * 0.5 * uViewport.zw\n\n // prevent division by W by transforming the tangent formula (div by 0 causes\n // the line to disappear, see https://github.com/processing/processing/issues/5183)\n // t = screen_q - screen_p\n //\n // tangent is normalized and we don't care which aDirection it points to (+-)\n // t = +- normalize( screen_q - screen_p )\n // t = +- normalize( (q.xy/q.w+<1,1>)*0.5*uViewport.zw - (p.xy/p.w+<1,1>)*0.5*uViewport.zw )\n //\n // extract common factor, <1,1> - <1,1> cancels out\n // t = +- normalize( (q.xy/q.w - p.xy/p.w) * 0.5 * uViewport.zw )\n //\n // convert to common divisor\n // t = +- normalize( ((q.xy*p.w - p.xy*q.w) / (p.w*q.w)) * 0.5 * uViewport.zw )\n //\n // remove the common scalar divisor/factor, not needed due to normalize and +-\n // (keep uViewport - can't remove because it has different components for x and y\n // and corrects for aspect ratio, see https://github.com/processing/processing/issues/5181)\n // t = +- normalize( (q.xy*p.w - p.xy*q.w) * uViewport.zw )\n\n vec2 tangent = normalize((q.xy*p.w - p.xy*q.w) * uViewport.zw);\n\n // flip tangent to normal (it's already normalized)\n vec2 normal = vec2(-tangent.y, tangent.x);\n\n float thickness = aDirection.w * uStrokeWeight;\n vec2 offset = normal * thickness / 2.0;\n\n vec2 curPerspScale;\n\n if(uPerspective == 1) {\n // Perspective ---\n // convert from world to clip by multiplying with projection scaling factor\n // to get the right thickness (see https://github.com/processing/processing/issues/5182)\n // invert Y, projections in Processing invert Y\n curPerspScale = (uProjectionMatrix * vec4(1, -1, 0, 0)).xy;\n } else {\n // No Perspective ---\n // multiply by W (to cancel out division by W later in the pipeline) and\n // convert from screen to clip (derived from clip to screen above)\n curPerspScale = p.w / (0.5 * uViewport.zw);\n }\n\n gl_Position.xy = p.xy + offset.xy * curPerspScale;\n gl_Position.zw = p.zw;\n}\n",lineFrag:"precision mediump float;\nprecision mediump int;\n\nuniform vec4 uMaterialColor;\n\nvoid main() {\n gl_FragColor = uMaterialColor;\n}",pointVert:"attribute vec3 aPosition;\nuniform float uPointSize;\nvarying float vStrokeWeight;\nuniform mat4 uModelViewMatrix;\nuniform mat4 uProjectionMatrix;\nvoid main() {\n\tvec4 positionVec4 = vec4(aPosition, 1.0);\n\tgl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;\n\tgl_PointSize = uPointSize;\n\tvStrokeWeight = uPointSize;\n}",pointFrag:"precision mediump float;\nprecision mediump int;\nuniform vec4 uMaterialColor;\nvarying float vStrokeWeight;\n\nvoid main(){\n\tfloat mask = 0.0;\n\n\t// make a circular mask using the gl_PointCoord (goes from 0 - 1 on a point)\n // might be able to get a nicer edge on big strokeweights with smoothstep but slightly less performant\n\n\tmask = step(0.98, length(gl_PointCoord * 2.0 - 1.0));\n\n\t// if strokeWeight is 1 or less lets just draw a square\n\t// this prevents weird artifacting from carving circles when our points are really small\n\t// if strokeWeight is larger than 1, we just use it as is\n\n\tmask = mix(0.0, mask, clamp(floor(vStrokeWeight - 0.5),0.0,1.0));\n\n\t// throw away the borders of the mask\n // otherwise we get weird alpha blending issues\n\n\tif(mask > 0.98){\n discard;\n \t}\n\n \tgl_FragColor = vec4(uMaterialColor.rgb * (1.0 - mask), uMaterialColor.a) ;\n}"};u.default.RendererGL=function(e,t,r,n){return u.default.Renderer.call(this,e,t,r),this._setAttributeDefaults(t),this._initContext(),this.isP3D=!0,this.GL=this.drawingContext,this._pInst._setProperty("drawingContext",this.drawingContext),this._isErasing=!1,this._enableLighting=!1,this.ambientLightColors=[],this.specularColors=[1,1,1],this.directionalLightDirections=[],this.directionalLightDiffuseColors=[],this.directionalLightSpecularColors=[],this.pointLightPositions=[],this.pointLightDiffuseColors=[],this.pointLightSpecularColors=[],this.spotLightPositions=[],this.spotLightDirections=[],this.spotLightDiffuseColors=[],this.spotLightSpecularColors=[],this.spotLightAngle=[],this.spotLightConc=[],this.drawMode=i.FILL,this.curFillColor=this._cachedFillStyle=[1,1,1,1],this.curStrokeColor=this._cachedStrokeStyle=[0,0,0,1],this.curBlendMode=i.BLEND,this._cachedBlendMode=void 0,this.blendExt=this.GL.getExtension("EXT_blend_minmax"),this._isBlending=!1,this._useSpecularMaterial=!1,this._useEmissiveMaterial=!1,this._useNormalMaterial=!1,this._useShininess=1,this._tint=[255,255,255,255],this.constantAttenuation=1,this.linearAttenuation=0,this.quadraticAttenuation=0,this.uMVMatrix=new u.default.Matrix,this.uPMatrix=new u.default.Matrix,this.uNMatrix=new u.default.Matrix("mat3"),this._currentNormal=new u.default.Vector(0,0,1),this._curCamera=new u.default.Camera(this),this._curCamera._computeCameraDefaultSettings(),this._curCamera._setDefaultCamera(),this._defaultLightShader=void 0,this._defaultImmediateModeShader=void 0,this._defaultNormalShader=void 0,this._defaultColorShader=void 0,this._defaultPointShader=void 0,this.userFillShader=void 0,this.userStrokeShader=void 0,this.userPointShader=void 0,this.retainedMode={geometry:{},buffers:{stroke:[new u.default.RenderBuffer(3,"lineVertices","lineVertexBuffer","aPosition",this,this._flatten),new u.default.RenderBuffer(4,"lineNormals","lineNormalBuffer","aDirection",this,this._flatten)],fill:[new u.default.RenderBuffer(3,"vertices","vertexBuffer","aPosition",this,this._vToNArray),new u.default.RenderBuffer(3,"vertexNormals","normalBuffer","aNormal",this,this._vToNArray),new u.default.RenderBuffer(4,"vertexColors","colorBuffer","aVertexColor",this),new u.default.RenderBuffer(3,"vertexAmbients","ambientBuffer","aAmbientColor",this),new u.default.RenderBuffer(2,"uvs","uvBuffer","aTexCoord",this,this._flatten)],text:[new u.default.RenderBuffer(3,"vertices","vertexBuffer","aPosition",this,this._vToNArray),new u.default.RenderBuffer(2,"uvs","uvBuffer","aTexCoord",this,this._flatten)]}},this.immediateMode={geometry:new u.default.Geometry,shapeMode:i.TRIANGLE_FAN,_bezierVertex:[],_quadraticVertex:[],_curveVertex:[],buffers:{fill:[new u.default.RenderBuffer(3,"vertices","vertexBuffer","aPosition",this,this._vToNArray),new u.default.RenderBuffer(3,"vertexNormals","normalBuffer","aNormal",this,this._vToNArray),new u.default.RenderBuffer(4,"vertexColors","colorBuffer","aVertexColor",this),new u.default.RenderBuffer(3,"vertexAmbients","ambientBuffer","aAmbientColor",this),new u.default.RenderBuffer(2,"uvs","uvBuffer","aTexCoord",this,this._flatten)],stroke:[new u.default.RenderBuffer(3,"lineVertices","lineVertexBuffer","aPosition",this,this._flatten),new u.default.RenderBuffer(4,"lineNormals","lineNormalBuffer","aDirection",this,this._flatten)],point:this.GL.createBuffer()}},this.pointSize=5,this.curStrokeWeight=1,this.textures=[],this.textureMode=i.IMAGE,this.textureWrapX=i.CLAMP,this.textureWrapY=i.CLAMP,this._tex=null,this._curveTightness=6,this._lookUpTableBezier=[],this._lookUpTableQuadratic=[],this._lutBezierDetail=0,this._lutQuadraticDetail=0,this._tessy=this._initTessy(),this.fontInfos={},this._curShader=void 0,this},u.default.RendererGL.prototype=Object.create(u.default.Renderer.prototype),u.default.RendererGL.prototype._setAttributeDefaults=function(e){var t={alpha:!1,depth:!0,stencil:!0,antialias:navigator.userAgent.toLowerCase().includes("safari"),premultipliedAlpha:!1,preserveDrawingBuffer:!0,perPixelLighting:!0};null===e._glAttributes?e._glAttributes=t:e._glAttributes=Object.assign(t,e._glAttributes)},u.default.RendererGL.prototype._initContext=function(){try{if(this.drawingContext=this.canvas.getContext("webgl",this._pInst._glAttributes)||this.canvas.getContext("experimental-webgl",this._pInst._glAttributes),null===this.drawingContext)throw new Error("Error creating webgl context");var e=this.drawingContext;e.enable(e.DEPTH_TEST),e.depthFunc(e.LEQUAL),e.viewport(0,0,e.drawingBufferWidth,e.drawingBufferHeight),this._viewport=this.drawingContext.getParameter(this.drawingContext.VIEWPORT)}catch(e){throw e}},u.default.RendererGL.prototype._resetContext=function(e,t){var r=this.width,n=this.height,o=this.canvas.id,i=this._pInst instanceof u.default.Graphics;if(i){var a=this._pInst;a.canvas.parentNode.removeChild(a.canvas),a.canvas=document.createElement("canvas"),(a._pInst._userNode||document.body).appendChild(a.canvas),u.default.Element.call(a,a.canvas,a._pInst),a.width=r,a.height=n}else{var s=this.canvas;s&&s.parentNode.removeChild(s),(s=document.createElement("canvas")).id=o,this._pInst._userNode?this._pInst._userNode.appendChild(s):document.body.appendChild(s),this._pInst.canvas=s}var l=new u.default.RendererGL(this._pInst.canvas,this._pInst,!i);this._pInst._setProperty("_renderer",l),l.resize(r,n),l._applyDefaults(),i||this._pInst._elements.push(l),"function"==typeof t&&setTimeout(function(){t.apply(window._renderer,e)},0)},u.default.prototype.setAttributes=function(e,t){if(void 0!==this._glAttributes){var r=!0;if(void 0!==t?(null===this._glAttributes&&(this._glAttributes={}),this._glAttributes[e]!==t&&(this._glAttributes[e]=t,r=!1)):e instanceof Object&&this._glAttributes!==e&&(this._glAttributes=e,r=!1),this._renderer.isP3D&&!r){if(!this._setupDone)for(var n in this._renderer.retainedMode.geometry)if(this._renderer.retainedMode.geometry.hasOwnProperty(n))return void console.error("Sorry, Could not set the attributes, you need to call setAttributes() before calling the other drawing methods in setup()");this.push(),this._renderer._resetContext(),this.pop(),this._renderer._curCamera&&(this._renderer._curCamera._renderer=this._renderer)}}else console.log("You are trying to use setAttributes on a p5.Graphics object that does not use a WEBGL renderer.")},u.default.RendererGL.prototype._update=function(){this.uMVMatrix.set(this._curCamera.cameraMatrix.mat4[0],this._curCamera.cameraMatrix.mat4[1],this._curCamera.cameraMatrix.mat4[2],this._curCamera.cameraMatrix.mat4[3],this._curCamera.cameraMatrix.mat4[4],this._curCamera.cameraMatrix.mat4[5],this._curCamera.cameraMatrix.mat4[6],this._curCamera.cameraMatrix.mat4[7],this._curCamera.cameraMatrix.mat4[8],this._curCamera.cameraMatrix.mat4[9],this._curCamera.cameraMatrix.mat4[10],this._curCamera.cameraMatrix.mat4[11],this._curCamera.cameraMatrix.mat4[12],this._curCamera.cameraMatrix.mat4[13],this._curCamera.cameraMatrix.mat4[14],this._curCamera.cameraMatrix.mat4[15]),this.ambientLightColors.length=0,this.specularColors=[1,1,1],this.directionalLightDirections.length=0,this.directionalLightDiffuseColors.length=0,this.directionalLightSpecularColors.length=0,this.pointLightPositions.length=0,this.pointLightDiffuseColors.length=0,this.pointLightSpecularColors.length=0,this.spotLightPositions.length=0,this.spotLightDirections.length=0,this.spotLightDiffuseColors.length=0,this.spotLightSpecularColors.length=0,this.spotLightAngle.length=0,this.spotLightConc.length=0,this._enableLighting=!1,this._tint=[255,255,255,255],this.GL.clear(this.GL.DEPTH_BUFFER_BIT)},u.default.RendererGL.prototype.background=function(){var e,t=(e=this._pInst).color.apply(e,arguments),r=t.levels[0]/255,n=t.levels[1]/255,o=t.levels[2]/255,i=t.levels[3]/255;this.GL.clearColor(r,n,o,i),this.GL.clear(this.GL.COLOR_BUFFER_BIT)},u.default.RendererGL.prototype.fill=function(e,t,r,n){var o=u.default.prototype.color.apply(this._pInst,arguments);this.curFillColor=o._array,this.drawMode=i.FILL,this._useNormalMaterial=!1,this._tex=null},u.default.RendererGL.prototype.stroke=function(e,t,r,n){arguments[3]=255;var o=u.default.prototype.color.apply(this._pInst,arguments);this.curStrokeColor=o._array},u.default.RendererGL.prototype.strokeCap=function(e){console.error("Sorry, strokeCap() is not yet implemented in WEBGL mode")},u.default.RendererGL.prototype.strokeJoin=function(e){console.error("Sorry, strokeJoin() is not yet implemented in WEBGL mode")},u.default.RendererGL.prototype.filter=function(e){console.error("filter() does not work in WEBGL mode")},u.default.RendererGL.prototype.blendMode=function(e){e===i.DARKEST||e===i.LIGHTEST||e===i.ADD||e===i.BLEND||e===i.SUBTRACT||e===i.SCREEN||e===i.EXCLUSION||e===i.REPLACE||e===i.MULTIPLY||e===i.REMOVE?this.curBlendMode=e:e!==i.BURN&&e!==i.OVERLAY&&e!==i.HARD_LIGHT&&e!==i.SOFT_LIGHT&&e!==i.DODGE||console.warn("BURN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, and DODGE only work for blendMode in 2D mode.")},u.default.RendererGL.prototype.erase=function(e,t){this._isErasing||(this._applyBlendMode(i.REMOVE),this._isErasing=!0,this._cachedFillStyle=this.curFillColor.slice(),this.curFillColor=[1,1,1,e/255],this._cachedStrokeStyle=this.curStrokeColor.slice(),this.curStrokeColor=[1,1,1,t/255])},u.default.RendererGL.prototype.noErase=function(){this._isErasing&&(this._isErasing=!1,this.curFillColor=this._cachedFillStyle.slice(),this.curStrokeColor=this._cachedStrokeStyle.slice(),this.blendMode(this._cachedBlendMode))},u.default.RendererGL.prototype.strokeWeight=function(e){this.curStrokeWeight!==e&&(this.pointSize=e,this.curStrokeWeight=e)},u.default.RendererGL.prototype._getPixel=function(e,t){var r;return r=new Uint8Array(4),this.drawingContext.readPixels(e,t,1,1,this.drawingContext.RGBA,this.drawingContext.UNSIGNED_BYTE,r),[r[0],r[1],r[2],r[3]]},u.default.RendererGL.prototype.loadPixels=function(){var e=this._pixelsState;if(!0===this._pInst._glAttributes.preserveDrawingBuffer){var t=e.pixels,r=this.GL.drawingBufferWidth*this.GL.drawingBufferHeight*4;t instanceof Uint8Array&&t.length===r||(t=new Uint8Array(r),this._pixelsState._setProperty("pixels",t));var n=this._pInst._pixelDensity;this.GL.readPixels(0,0,this.width*n,this.height*n,this.GL.RGBA,this.GL.UNSIGNED_BYTE,t)}else console.log("loadPixels only works in WebGL when preserveDrawingBuffer is true.")},u.default.RendererGL.prototype.geometryInHash=function(e){return void 0!==this.retainedMode.geometry[e]},u.default.RendererGL.prototype.resize=function(e,t){u.default.Renderer.prototype.resize.call(this,e,t),this.GL.viewport(0,0,this.GL.drawingBufferWidth,this.GL.drawingBufferHeight),this._viewport=this.GL.getParameter(this.GL.VIEWPORT),this._curCamera._resize();var r=this._pixelsState;void 0!==r.pixels&&r._setProperty("pixels",new Uint8Array(this.GL.drawingBufferWidth*this.GL.drawingBufferHeight*4))},u.default.RendererGL.prototype.clear=function(){var e=(arguments.length<=0?void 0:arguments[0])||0,t=(arguments.length<=1?void 0:arguments[1])||0,r=(arguments.length<=2?void 0:arguments[2])||0,n=(arguments.length<=3?void 0:arguments[3])||0;this.GL.clearColor(e,t,r,n),this.GL.clearDepth(1),this.GL.clear(this.GL.COLOR_BUFFER_BIT|this.GL.DEPTH_BUFFER_BIT)},u.default.RendererGL.prototype.applyMatrix=function(e,t,r,n,o,i){16===arguments.length?u.default.Matrix.prototype.apply.apply(this.uMVMatrix,arguments):this.uMVMatrix.apply([e,t,0,0,r,n,0,0,0,0,1,0,o,i,0,1])},u.default.RendererGL.prototype.translate=function(e,t,r){return e instanceof u.default.Vector&&(r=e.z,t=e.y,e=e.x),this.uMVMatrix.translate([e,t,r]),this},u.default.RendererGL.prototype.scale=function(e,t,r){return this.uMVMatrix.scale(e,t,r),this},u.default.RendererGL.prototype.rotate=function(e,t){return void 0===t?this.rotateZ(e):(u.default.Matrix.prototype.rotate.apply(this.uMVMatrix,arguments),this)},u.default.RendererGL.prototype.rotateX=function(e){return this.rotate(e,1,0,0),this},u.default.RendererGL.prototype.rotateY=function(e){return this.rotate(e,0,1,0),this},u.default.RendererGL.prototype.rotateZ=function(e){return this.rotate(e,0,0,1),this},u.default.RendererGL.prototype.push=function(){var e=u.default.Renderer.prototype.push.apply(this),t=e.properties;return t.uMVMatrix=this.uMVMatrix.copy(),t.uPMatrix=this.uPMatrix.copy(),t._curCamera=this._curCamera,this._curCamera=this._curCamera.copy(),t.ambientLightColors=this.ambientLightColors.slice(),t.specularColors=this.specularColors.slice(),t.directionalLightDirections=this.directionalLightDirections.slice(),t.directionalLightDiffuseColors=this.directionalLightDiffuseColors.slice(),t.directionalLightSpecularColors=this.directionalLightSpecularColors.slice(),t.pointLightPositions=this.pointLightPositions.slice(),t.pointLightDiffuseColors=this.pointLightDiffuseColors.slice(),t.pointLightSpecularColors=this.pointLightSpecularColors.slice(),t.spotLightPositions=this.spotLightPositions.slice(),t.spotLightDirections=this.spotLightDirections.slice(),t.spotLightDiffuseColors=this.spotLightDiffuseColors.slice(),t.spotLightSpecularColors=this.spotLightSpecularColors.slice(),t.spotLightAngle=this.spotLightAngle.slice(),t.spotLightConc=this.spotLightConc.slice(),t.userFillShader=this.userFillShader,t.userStrokeShader=this.userStrokeShader,t.userPointShader=this.userPointShader,t.pointSize=this.pointSize,t.curStrokeWeight=this.curStrokeWeight,t.curStrokeColor=this.curStrokeColor,t.curFillColor=this.curFillColor,t._useSpecularMaterial=this._useSpecularMaterial,t._useEmissiveMaterial=this._useEmissiveMaterial,t._useShininess=this._useShininess,t.constantAttenuation=this.constantAttenuation,t.linearAttenuation=this.linearAttenuation,t.quadraticAttenuation=this.quadraticAttenuation,t._enableLighting=this._enableLighting,t._useNormalMaterial=this._useNormalMaterial,t._tex=this._tex,t.drawMode=this.drawMode,t._currentNormal=this._currentNormal,e},u.default.RendererGL.prototype.resetMatrix=function(){return this.uMVMatrix=u.default.Matrix.identity(this._pInst),this},u.default.RendererGL.prototype._getImmediateStrokeShader=function(){var e=this.userStrokeShader;return e&&e.isStrokeShader()?e:this._getLineShader()},u.default.RendererGL.prototype._getRetainedStrokeShader=u.default.RendererGL.prototype._getImmediateStrokeShader,u.default.RendererGL.prototype._getImmediateFillShader=function(){var e=this.userFillShader;if(this._useNormalMaterial&&(!e||!e.isNormalShader()))return this._getNormalShader();if(this._enableLighting){if(!e||!e.isLightShader())return this._getLightShader()}else if(this._tex){if(!e||!e.isTextureShader())return this._getLightShader()}else if(!e)return this._getImmediateModeShader();return e},u.default.RendererGL.prototype._getRetainedFillShader=function(){if(this._useNormalMaterial)return this._getNormalShader();var e=this.userFillShader;if(this._enableLighting){if(!e||!e.isLightShader())return this._getLightShader()}else if(this._tex){if(!e||!e.isTextureShader())return this._getLightShader()}else if(!e)return this._getColorShader();return e},u.default.RendererGL.prototype._getImmediatePointShader=function(){var e=this.userPointShader;return e&&e.isPointShader()?e:this._getPointShader()},u.default.RendererGL.prototype._getRetainedLineShader=u.default.RendererGL.prototype._getImmediateLineShader,u.default.RendererGL.prototype._getLightShader=function(){return this._defaultLightShader||(this._pInst._glAttributes.perPixelLighting?this._defaultLightShader=new u.default.Shader(this,d.phongVert,d.phongFrag):this._defaultLightShader=new u.default.Shader(this,d.lightVert,d.lightTextureFrag)),this._defaultLightShader},u.default.RendererGL.prototype._getImmediateModeShader=function(){return this._defaultImmediateModeShader||(this._defaultImmediateModeShader=new u.default.Shader(this,d.immediateVert,d.vertexColorFrag)),this._defaultImmediateModeShader},u.default.RendererGL.prototype._getNormalShader=function(){return this._defaultNormalShader||(this._defaultNormalShader=new u.default.Shader(this,d.normalVert,d.normalFrag)),this._defaultNormalShader},u.default.RendererGL.prototype._getColorShader=function(){return this._defaultColorShader||(this._defaultColorShader=new u.default.Shader(this,d.normalVert,d.basicFrag)),this._defaultColorShader},u.default.RendererGL.prototype._getPointShader=function(){return this._defaultPointShader||(this._defaultPointShader=new u.default.Shader(this,d.pointVert,d.pointFrag)),this._defaultPointShader},u.default.RendererGL.prototype._getLineShader=function(){return this._defaultLineShader||(this._defaultLineShader=new u.default.Shader(this,d.lineVert,d.lineFrag)),this._defaultLineShader},u.default.RendererGL.prototype._getFontShader=function(){return this._defaultFontShader||(this.GL.getExtension("OES_standard_derivatives"),this._defaultFontShader=new u.default.Shader(this,d.fontVert,d.fontFrag)),this._defaultFontShader},u.default.RendererGL.prototype._getEmptyTexture=function(){if(!this._emptyTexture){var e=new u.default.Image(1,1);e.set(0,0,255),this._emptyTexture=new u.default.Texture(this,e)}return this._emptyTexture},u.default.RendererGL.prototype.getTexture=function(e){var t=this.textures,r=!0,n=!1,o=void 0;try{for(var i,a=t[Symbol.iterator]();!(r=(i=a.next()).done);r=!0){var s=i.value;if(s.src===e)return s}}catch(e){n=!0,o=e}finally{try{r||null==a.return||a.return()}finally{if(n)throw o}}var l=new u.default.Texture(this,e);return t.push(l),l},u.default.RendererGL.prototype._setStrokeUniforms=function(e){e.bindShader(),e.setUniform("uMaterialColor",this.curStrokeColor),e.setUniform("uStrokeWeight",this.curStrokeWeight)},u.default.RendererGL.prototype._setFillUniforms=function(e){e.bindShader(),e.setUniform("uMaterialColor",this.curFillColor),e.setUniform("isTexture",!!this._tex),this._tex&&e.setUniform("uSampler",this._tex),e.setUniform("uTint",this._tint),e.setUniform("uSpecular",this._useSpecularMaterial),e.setUniform("uEmissive",this._useEmissiveMaterial),e.setUniform("uShininess",this._useShininess),e.setUniform("uUseLighting",this._enableLighting);var t=this.pointLightDiffuseColors.length/3;e.setUniform("uPointLightCount",t),e.setUniform("uPointLightLocation",this.pointLightPositions),e.setUniform("uPointLightDiffuseColors",this.pointLightDiffuseColors),e.setUniform("uPointLightSpecularColors",this.pointLightSpecularColors);var r=this.directionalLightDiffuseColors.length/3;e.setUniform("uDirectionalLightCount",r),e.setUniform("uLightingDirection",this.directionalLightDirections),e.setUniform("uDirectionalDiffuseColors",this.directionalLightDiffuseColors),e.setUniform("uDirectionalSpecularColors",this.directionalLightSpecularColors);var n=this.ambientLightColors.length/3;e.setUniform("uAmbientLightCount",n),e.setUniform("uAmbientColor",this.ambientLightColors);var o=this.spotLightDiffuseColors.length/3;e.setUniform("uSpotLightCount",o),e.setUniform("uSpotLightAngle",this.spotLightAngle),e.setUniform("uSpotLightConc",this.spotLightConc),e.setUniform("uSpotLightDiffuseColors",this.spotLightDiffuseColors),e.setUniform("uSpotLightSpecularColors",this.spotLightSpecularColors),e.setUniform("uSpotLightLocation",this.spotLightPositions),e.setUniform("uSpotLightDirection",this.spotLightDirections),e.setUniform("uConstantAttenuation",this.constantAttenuation),e.setUniform("uLinearAttenuation",this.linearAttenuation),e.setUniform("uQuadraticAttenuation",this.quadraticAttenuation),e.bindTextures()},u.default.RendererGL.prototype._setPointUniforms=function(e){e.bindShader(),e.setUniform("uMaterialColor",this.curStrokeColor),e.setUniform("uPointSize",this.pointSize*this._pInst._pixelDensity)},u.default.RendererGL.prototype._bindBuffer=function(e,t,r,n,o){if(t=t||this.GL.ARRAY_BUFFER,this.GL.bindBuffer(t,e),void 0!==r){var i=new(n||Float32Array)(r);this.GL.bufferData(t,i,o||this.GL.STATIC_DRAW)}},u.default.RendererGL.prototype._arraysEqual=function(e,t){var r=e.length;if(r!==t.length)return!1;for(var n=0;n>7,127&f,d>>7,127&d);for(var h=0;h>7,127&p,0,0)}}return{cellImageInfo:l,dimOffset:i,dimImageInfo:o}}return(t=this.glyphInfos[e.index]={glyph:e,uGlyphRect:[n.x1,-n.y1,n.x2,-n.y2],strokeImageInfo:I,strokes:h,colInfo:B(y,this.colDimImageInfos,this.colCellImageInfos),rowInfo:B(p,this.rowDimImageInfos,this.rowCellImageInfos)}).uGridOffset=[t.colInfo.dimOffset,t.rowInfo.dimOffset],t}}var z=Math.sqrt(3);G.default.RendererGL.prototype._renderText=function(e,t,r,n,o){if(this._textFont&&"string"!=typeof this._textFont){if(!(o<=n)&&this._doFill){if(!this._isOpenType())return console.log("WEBGL: only Opentype (.otf) and Truetype (.ttf) fonts are supported"),e;e.push();var i=this._doStroke,a=this.drawMode;this._doStroke=!1,this.drawMode=k.TEXTURE;var s=this._textFont.font,l=this._textFont._fontInfo;l=l||(this._textFont._fontInfo=new R(s));var u=this._textFont._handleAlignment(this,t,r,n),c=this._textSize/s.unitsPerEm;this.translate(u.x,u.y,0),this.scale(c,c,1);var d=this.GL,f=!this._defaultFontShader,h=this._getFontShader();h.init(),h.bindShader(),f&&(h.setUniform("uGridImageSize",[64,64]),h.setUniform("uCellsImageSize",[64,64]),h.setUniform("uStrokeImageSize",[64,64]),h.setUniform("uGridSize",[9,9])),this._applyColorBlend(this.curFillColor);var p=this.retainedMode.geometry.glyph;if(!p){var y=this._textGeom=new G.default.Geometry(1,1,function(){for(var e=0;e<=1;e++)for(var t=0;t<=1;t++)this.vertices.push(new G.default.Vector(t,e,0)),this.uvs.push(t,e)});y.computeFaces().computeNormals(),p=this.createBuffers("glyph",y)}var m=!0,g=!1,v=void 0;try{for(var b,_=this.retainedMode.buffers.text[Symbol.iterator]();!(m=(b=_.next()).done);m=!0){b.value._prepareBuffer(p,h)}}catch(e){g=!0,v=e}finally{try{m||null==_.return||_.return()}finally{if(g)throw v}}this._bindBuffer(p.indexBuffer,d.ELEMENT_ARRAY_BUFFER),h.setUniform("uMaterialColor",this.curFillColor);try{var x=0,w=null,j=s.stringToGlyphs(t),S=!0,M=!1,E=void 0;try{for(var T,O=j[Symbol.iterator]();!(S=(T=O.next()).done);S=!0){var C=T.value;w&&(x+=s.getKerningValue(w,C));var L=l.getGlyphInfo(C);if(L.uGlyphRect){var P=L.rowInfo,A=L.colInfo;h.setUniform("uSamplerStrokes",L.strokeImageInfo.imageData),h.setUniform("uSamplerRowStrokes",P.cellImageInfo.imageData),h.setUniform("uSamplerRows",P.dimImageInfo.imageData),h.setUniform("uSamplerColStrokes",A.cellImageInfo.imageData),h.setUniform("uSamplerCols",A.dimImageInfo.imageData),h.setUniform("uGridOffset",L.uGridOffset),h.setUniform("uGlyphRect",L.uGlyphRect),h.setUniform("uGlyphOffset",x),h.bindTextures(),d.drawElements(d.TRIANGLES,6,this.GL.UNSIGNED_SHORT,0)}x+=C.advanceWidth,w=C}}catch(e){M=!0,E=e}finally{try{S||null==O.return||O.return()}finally{if(M)throw E}}}finally{h.unbindShader(),this._doStroke=i,this.drawMode=a,e.pop()}return e}}else console.log("WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` for more details.")}},{"../core/constants":253,"../core/main":264,"./p5.RendererGL.Retained":317,"./p5.Shader":319,"core-js/modules/es.array.iterator":158,"core-js/modules/es.object.to-string":177,"core-js/modules/es.regexp.exec":181,"core-js/modules/es.string.iterator":186,"core-js/modules/es.string.split":191,"core-js/modules/es.string.sub":192,"core-js/modules/es.symbol":196,"core-js/modules/es.symbol.description":194,"core-js/modules/es.symbol.iterator":195,"core-js/modules/web.dom-collections.iterator":229}]},{},[248])(248)}); \ No newline at end of file diff --git a/dist/assets/js/p5.sound.min.js b/dist/assets/js/p5.sound.min.js new file mode 100644 index 0000000000..44f2523182 --- /dev/null +++ b/dist/assets/js/p5.sound.min.js @@ -0,0 +1,3 @@ +/** [p5.sound] Version: 1.0.1 - 2021-05-25 */ + !function(n){var i={};function r(t){if(i[t])return i[t].exports;var e=i[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}r.m=n,r.c=i,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=40)}([function(t,e,n){var i;void 0===(i=function(){"use strict";function l(t,e){this.isUndef(t)||1===t?this.input=this.context.createGain():1t)this.cancelScheduledValues(t),this.linearRampToValueAtTime(e,t);else{var i=this._searchAfter(t);i&&(this.cancelScheduledValues(t),i.type===u.TimelineSignal.Type.Linear?this.linearRampToValueAtTime(e,t):i.type===u.TimelineSignal.Type.Exponential&&this.exponentialRampToValueAtTime(e,t)),this.setValueAtTime(e,t)}return this},u.TimelineSignal.prototype.linearRampToValueBetween=function(t,e,n){return this.setRampPoint(e),this.linearRampToValueAtTime(t,n),this},u.TimelineSignal.prototype.exponentialRampToValueBetween=function(t,e,n){return this.setRampPoint(e),this.exponentialRampToValueAtTime(t,n),this},u.TimelineSignal.prototype._searchBefore=function(t){return this._events.get(t)},u.TimelineSignal.prototype._searchAfter=function(t){return this._events.getAfter(t)},u.TimelineSignal.prototype.getValueAtTime=function(t){t=this.toSeconds(t);var e=this._searchAfter(t),n=this._searchBefore(t),i=this._initial;if(null===n)i=this._initial;else if(n.type===u.TimelineSignal.Type.Target){var r,o=this._events.getBefore(n.time);r=null===o?this._initial:o.value,i=this._exponentialApproach(n.time,r,n.value,n.constant,t)}else i=n.type===u.TimelineSignal.Type.Curve?this._curveInterpolate(n.time,n.value,n.duration,t):null===e?n.value:e.type===u.TimelineSignal.Type.Linear?this._linearInterpolate(n.time,n.value,e.time,e.value,t):e.type===u.TimelineSignal.Type.Exponential?this._exponentialInterpolate(n.time,n.value,e.time,e.value,t):n.value;return i},u.TimelineSignal.prototype.connect=u.SignalBase.prototype.connect,u.TimelineSignal.prototype._exponentialApproach=function(t,e,n,i,r){return n+(e-n)*Math.exp(-(r-t)/i)},u.TimelineSignal.prototype._linearInterpolate=function(t,e,n,i,r){return e+(r-t)/(n-t)*(i-e)},u.TimelineSignal.prototype._exponentialInterpolate=function(t,e,n,i,r){return(e=Math.max(this._minOutput,e))*Math.pow(i/e,(r-t)/(n-t))},u.TimelineSignal.prototype._curveInterpolate=function(t,e,n,i){var r=e.length;if(t+n<=i)return e[r-1];if(i<=t)return e[0];var o=(i-t)/n,s=Math.floor((r-1)*o),a=Math.ceil((r-1)*o),u=e[s],c=e[a];return a===s?u:this._linearInterpolate(s,u,a,c,o*(r-1))},u.TimelineSignal.prototype.dispose=function(){u.Signal.prototype.dispose.call(this),u.Param.prototype.dispose.call(this),this._events.dispose(),this._events=null},u.TimelineSignal}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(4),n(1),n(2)],void 0===(r=function(n){"use strict";return n.Scale=function(t,e){this._outputMin=this.defaultArg(t,0),this._outputMax=this.defaultArg(e,1),this._scale=this.input=new n.Multiply(1),this._add=this.output=new n.Add(0),this._scale.connect(this._add),this._setRange()},n.extend(n.Scale,n.SignalBase),Object.defineProperty(n.Scale.prototype,"min",{get:function(){return this._outputMin},set:function(t){this._outputMin=t,this._setRange()}}),Object.defineProperty(n.Scale.prototype,"max",{get:function(){return this._outputMax},set:function(t){this._outputMax=t,this._setRange()}}),n.Scale.prototype._setRange=function(){this._add.value=this._outputMin,this._scale.value=this._outputMax-this._outputMin},n.Scale.prototype.dispose=function(){return n.prototype.dispose.call(this),this._add.dispose(),this._add=null,this._scale.dispose(),this._scale=null,this},n.Scale}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(16),n(30),n(31),n(12)],void 0===(r=function(e){return e.Type={Default:"number",Time:"time",Frequency:"frequency",TransportTime:"transportTime",Ticks:"ticks",NormalRange:"normalRange",AudioRange:"audioRange",Decibels:"db",Interval:"interval",BPM:"bpm",Positive:"positive",Cents:"cents",Degrees:"degrees",MIDI:"midi",BarsBeatsSixteenths:"barsBeatsSixteenths",Samples:"samples",Hertz:"hertz",Note:"note",Milliseconds:"milliseconds",Seconds:"seconds",Notation:"notation"},e.prototype.toSeconds=function(t){return this.isNumber(t)?t:this.isUndef(t)?this.now():this.isString(t)?new e.Time(t).toSeconds():t instanceof e.TimeBase?t.toSeconds():void 0},e.prototype.toFrequency=function(t){return this.isNumber(t)?t:this.isString(t)||this.isUndef(t)?new e.Frequency(t).valueOf():t instanceof e.TimeBase?t.toFrequency():void 0},e.prototype.toTicks=function(t){return this.isNumber(t)||this.isString(t)?new e.TransportTime(t).toTicks():this.isUndef(t)?e.Transport.ticks:t instanceof e.TimeBase?t.toTicks():void 0},e}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(18),n(9)],void 0===(r=function(n){"use strict";return window.GainNode&&!AudioContext.prototype.createGain&&(AudioContext.prototype.createGain=AudioContext.prototype.createGainNode),n.Gain=function(){var t=this.optionsObject(arguments,["gain","units"],n.Gain.defaults);this.input=this.output=this._gainNode=this.context.createGain(),this.gain=new n.Param({param:this._gainNode.gain,units:t.units,value:t.gain,convert:t.convert}),this._readOnly("gain")},n.extend(n.Gain),n.Gain.defaults={gain:1,convert:!0},n.Gain.prototype.dispose=function(){n.Param.prototype.dispose.call(this),this._gainNode.disconnect(),this._gainNode=null,this._writable("gain"),this.gain.dispose(),this.gain=null},n.prototype.createInsOuts=function(t,e){1===t?this.input=new n.Gain:1this._nextTick&&this._state;){var e=this._state.getValueAtTime(this._nextTick);if(e!==this._lastState){this._lastState=e;var n=this._state.get(this._nextTick);e===r.State.Started?(this._nextTick=n.time,this.isUndef(n.offset)||(this.ticks=n.offset),this.emit("start",n.time,this.ticks)):e===r.State.Stopped?(this.ticks=0,this.emit("stop",n.time)):e===r.State.Paused&&this.emit("pause",n.time)}var i=this._nextTick;this.frequency&&(this._nextTick+=1/this.frequency.getValueAtTime(this._nextTick),e===r.State.Started&&(this.callback(i),this.ticks++))}},r.Clock.prototype.getStateAtTime=function(t){return t=this.toSeconds(t),this._state.getValueAtTime(t)},r.Clock.prototype.dispose=function(){r.Emitter.prototype.dispose.call(this),this.context.off("tick",this._boundLoop),this._writable("frequency"),this.frequency.dispose(),this.frequency=null,this._boundLoop=null,this._nextTick=1/0,this.callback=null,this._state.dispose(),this._state=null},r.Clock}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(14)],void 0===(r=function(i){function t(t,e,n){if(t.input)Array.isArray(t.input)?(i.prototype.isUndef(n)&&(n=0),this.connect(t.input[n])):this.connect(t.input,e,n);else try{t instanceof AudioNode?r.call(this,t,e,n):r.call(this,t,e)}catch(e){throw new Error("error connecting to node: "+t+"\n"+e)}}var r,o;return!window.hasOwnProperty("AudioContext")&&window.hasOwnProperty("webkitAudioContext")&&(window.AudioContext=window.webkitAudioContext),i.Context=function(t){for(var e in i.Emitter.call(this),t=t||new window.AudioContext,this._context=t,this._context)this._defineProperty(this._context,e);this._latencyHint="interactive",this._lookAhead=.1,this._updateInterval=this._lookAhead/3,this._computedUpdateInterval=0,this._worker=this._createWorker(),this._constants={}},i.extend(i.Context,i.Emitter),i.Emitter.mixin(i.Context),i.Context.prototype._defineProperty=function(e,n){this.isUndef(this[n])&&Object.defineProperty(this,n,{get:function(){return"function"==typeof e[n]?e[n].bind(e):e[n]},set:function(t){e[n]=t}})},i.Context.prototype.now=function(){return this._context.currentTime},i.Context.prototype._createWorker=function(){window.URL=window.URL||window.webkitURL;var t=new Blob(["var timeoutTime = "+(1e3*this._updateInterval).toFixed(1)+";self.onmessage = function(msg){\ttimeoutTime = parseInt(msg.data);};function tick(){\tsetTimeout(tick, timeoutTime);\tself.postMessage('tick');}tick();"]),e=URL.createObjectURL(t),n=new Worker(e);return n.addEventListener("message",function(){this.emit("tick")}.bind(this)),n.addEventListener("message",function(){var t=this.now();if(this.isNumber(this._lastUpdate)){var e=t-this._lastUpdate;this._computedUpdateInterval=Math.max(e,.97*this._computedUpdateInterval)}this._lastUpdate=t}.bind(this)),n},i.Context.prototype.getConstant=function(t){if(this._constants[t])return this._constants[t];for(var e=this._context.createBuffer(1,128,this._context.sampleRate),n=e.getChannelData(0),i=0;ithis.memory){var n=this.length-this.memory;this._timeline.splice(0,n)}return this},e.Timeline.prototype.remove=function(t){if(this._iterating)this._toRemove.push(t);else{var e=this._timeline.indexOf(t);-1!==e&&this._timeline.splice(e,1)}return this},e.Timeline.prototype.get=function(t){var e=this._search(t);return-1!==e?this._timeline[e]:null},e.Timeline.prototype.peek=function(){return this._timeline[0]},e.Timeline.prototype.shift=function(){return this._timeline.shift()},e.Timeline.prototype.getAfter=function(t){var e=this._search(t);return e+1=t&&(this._timeline=[]);return this},e.Timeline.prototype.cancelBefore=function(t){if(this._timeline.length){var e=this._search(t);0<=e&&(this._timeline=this._timeline.slice(e+1))}return this},e.Timeline.prototype._search=function(t){var e=0,n=this._timeline.length,i=n;if(0t)return r;o.time>t?i=r:o.time=t;)n--;return this._iterate(e,n+1),this},e.Timeline.prototype.forEachAtTime=function(e,n){var t=this._search(e);return-1!==t&&this._iterate(function(t){t.time===e&&n(t)},0,t),this},e.Timeline.prototype.dispose=function(){e.prototype.dispose.call(this),this._timeline=null,this._toRemove=null},e.Timeline}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(1),n(2)],void 0===(r=function(t){"use strict";return t.Negate=function(){this._multiply=this.input=this.output=new t.Multiply(-1)},t.extend(t.Negate,t.SignalBase),t.Negate.prototype.dispose=function(){return t.prototype.dispose.call(this),this._multiply.dispose(),this._multiply=null,this},t.Negate}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r;i=[n(0),n(2),n(1),n(6)],void 0===(r=function(t){"use strict";return t.GreaterThanZero=function(){this._thresh=this.output=new t.WaveShaper(function(t){return t<=0?0:1},127),this._scale=this.input=new t.Multiply(1e4),this._scale.connect(this._thresh)},t.extend(t.GreaterThanZero,t.SignalBase),t.GreaterThanZero.prototype.dispose=function(){return t.prototype.dispose.call(this),this._scale.dispose(),this._scale=null,this._thresh.dispose(),this._thresh=null,this},t.GreaterThanZero}.apply(e,i))||(t.exports=r)},function(t,e,n){var i,r,o;r=[],void 0===(o="function"==typeof(i=function(){var s=function(t,e){this._dragged=!1,this._element=t,this._bindedMove=this._moved.bind(this),this._bindedEnd=this._ended.bind(this,e),t.addEventListener("touchstart",this._bindedEnd),t.addEventListener("touchmove",this._bindedMove),t.addEventListener("touchend",this._bindedEnd),t.addEventListener("mouseup",this._bindedEnd)};function o(t){return"running"===t.state}return s.prototype._moved=function(t){this._dragged=!0},s.prototype._ended=function(t){this._dragged||function(t){var e=t.createBuffer(1,1,t.sampleRate),n=t.createBufferSource();n.buffer=e,n.connect(t.destination),n.start(0),t.resume&&t.resume()}(t),this._dragged=!1},s.prototype.dispose=function(){this._element.removeEventListener("touchstart",this._bindedEnd),this._element.removeEventListener("touchmove",this._bindedMove),this._element.removeEventListener("touchend",this._bindedEnd),this._element.removeEventListener("mouseup",this._bindedEnd),this._bindedMove=null,this._bindedEnd=null,this._element=null},function(e,t,n){var i=new Promise(function(t){!function(e,n){o(e)?n():function t(){o(e)?n():(requestAnimationFrame(t),e.resume&&e.resume())}()}(e,t)}),r=[];return function t(e,n,i){if(Array.isArray(e)||NodeList&&e instanceof NodeList)for(var r=0;r= this._length) {\n this._writeIndex = 0;\n } // For excessive frames, the buffer will be overwritten.\n\n\n this._framesAvailable += sourceLength;\n\n if (this._framesAvailable > this._length) {\n this._framesAvailable = this._length;\n }\n }\n /**\n * Pull data out of buffer and fill a given sequence of Float32Arrays.\n *\n * @param {array} arraySequence An array of Float32Arrays.\n */\n\n }, {\n key: "pull",\n value: function pull(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // If the FIFO is completely empty, do nothing.\n if (this._framesAvailable === 0) {\n return;\n }\n\n var destinationLength = arraySequence[0].length; // Transfer data from the internal buffer to the |arraySequence| storage.\n\n for (var i = 0; i < destinationLength; ++i) {\n var readIndex = (this._readIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n arraySequence[channel][i] = this._channelData[channel][readIndex];\n }\n }\n\n this._readIndex += destinationLength;\n\n if (this._readIndex >= this._length) {\n this._readIndex = 0;\n }\n\n this._framesAvailable -= destinationLength;\n\n if (this._framesAvailable < 0) {\n this._framesAvailable = 0;\n }\n }\n }, {\n key: "framesAvailable",\n get: function get() {\n return this._framesAvailable;\n }\n }]);\n\n return RingBuffer;\n }()\n}["default"];\n\nvar RecorderProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(RecorderProcessor, _AudioWorkletProcesso);\n\n function RecorderProcessor(options) {\n var _this;\n\n _classCallCheck(this, RecorderProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(RecorderProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.numOutputChannels = options.outputChannelCount || 2;\n _this.numInputChannels = processorOptions.numInputChannels || 2;\n _this.bufferSize = processorOptions.bufferSize || 1024;\n _this.recording = false;\n\n _this.clear();\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === \'start\') {\n _this.record(data.duration);\n } else if (data.name === \'stop\') {\n _this.stop();\n }\n };\n\n return _this;\n }\n\n _createClass(RecorderProcessor, [{\n key: "process",\n value: function process(inputs) {\n if (!this.recording) {\n return true;\n } else if (this.sampleLimit && this.recordedSamples >= this.sampleLimit) {\n this.stop();\n return true;\n }\n\n var input = inputs[0];\n this.inputRingBuffer.push(input);\n\n if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {\n this.inputRingBuffer.pull(this.inputRingBufferArraySequence);\n\n for (var channel = 0; channel < this.numOutputChannels; ++channel) {\n var inputChannelCopy = this.inputRingBufferArraySequence[channel].slice();\n\n if (channel === 0) {\n this.leftBuffers.push(inputChannelCopy);\n\n if (this.numInputChannels === 1) {\n this.rightBuffers.push(inputChannelCopy);\n }\n } else if (channel === 1 && this.numInputChannels > 1) {\n this.rightBuffers.push(inputChannelCopy);\n }\n }\n\n this.recordedSamples += this.bufferSize;\n }\n\n return true;\n }\n }, {\n key: "record",\n value: function record(duration) {\n if (duration) {\n this.sampleLimit = Math.round(duration * sampleRate);\n }\n\n this.recording = true;\n }\n }, {\n key: "stop",\n value: function stop() {\n this.recording = false;\n var buffers = this.getBuffers();\n var leftBuffer = buffers[0].buffer;\n var rightBuffer = buffers[1].buffer;\n this.port.postMessage({\n name: \'buffers\',\n leftBuffer: leftBuffer,\n rightBuffer: rightBuffer\n }, [leftBuffer, rightBuffer]);\n this.clear();\n }\n }, {\n key: "getBuffers",\n value: function getBuffers() {\n var buffers = [];\n buffers.push(this.mergeBuffers(this.leftBuffers));\n buffers.push(this.mergeBuffers(this.rightBuffers));\n return buffers;\n }\n }, {\n key: "mergeBuffers",\n value: function mergeBuffers(channelBuffer) {\n var result = new Float32Array(this.recordedSamples);\n var offset = 0;\n var lng = channelBuffer.length;\n\n for (var i = 0; i < lng; i++) {\n var buffer = channelBuffer[i];\n result.set(buffer, offset);\n offset += buffer.length;\n }\n\n return result;\n }\n }, {\n key: "clear",\n value: function clear() {\n var _this2 = this;\n\n this.leftBuffers = [];\n this.rightBuffers = [];\n this.inputRingBuffer = new RingBuffer(this.bufferSize, this.numInputChannels);\n this.inputRingBufferArraySequence = new Array(this.numInputChannels).fill(null).map(function () {\n return new Float32Array(_this2.bufferSize);\n });\n this.recordedSamples = 0;\n this.sampleLimit = null;\n }\n }]);\n\n return RecorderProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.recorderProcessor, RecorderProcessor);'},function(t,e,n){"use strict";n.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// import dependencies via preval.require so that they\'re available as values at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\nvar RingBuffer = {\n "default":\n /*#__PURE__*/\n function () {\n /**\n * @constructor\n * @param {number} length Buffer length in frames.\n * @param {number} channelCount Buffer channel count.\n */\n function RingBuffer(length, channelCount) {\n _classCallCheck(this, RingBuffer);\n\n this._readIndex = 0;\n this._writeIndex = 0;\n this._framesAvailable = 0;\n this._channelCount = channelCount;\n this._length = length;\n this._channelData = [];\n\n for (var i = 0; i < this._channelCount; ++i) {\n this._channelData[i] = new Float32Array(length);\n }\n }\n /**\n * Getter for Available frames in buffer.\n *\n * @return {number} Available frames in buffer.\n */\n\n\n _createClass(RingBuffer, [{\n key: "push",\n\n /**\n * Push a sequence of Float32Arrays to buffer.\n *\n * @param {array} arraySequence A sequence of Float32Arrays.\n */\n value: function push(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // Transfer data from the |arraySequence| storage to the internal buffer.\n var sourceLength = arraySequence[0] ? arraySequence[0].length : 0;\n\n for (var i = 0; i < sourceLength; ++i) {\n var writeIndex = (this._writeIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n this._channelData[channel][writeIndex] = arraySequence[channel][i];\n }\n }\n\n this._writeIndex += sourceLength;\n\n if (this._writeIndex >= this._length) {\n this._writeIndex = 0;\n } // For excessive frames, the buffer will be overwritten.\n\n\n this._framesAvailable += sourceLength;\n\n if (this._framesAvailable > this._length) {\n this._framesAvailable = this._length;\n }\n }\n /**\n * Pull data out of buffer and fill a given sequence of Float32Arrays.\n *\n * @param {array} arraySequence An array of Float32Arrays.\n */\n\n }, {\n key: "pull",\n value: function pull(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // If the FIFO is completely empty, do nothing.\n if (this._framesAvailable === 0) {\n return;\n }\n\n var destinationLength = arraySequence[0].length; // Transfer data from the internal buffer to the |arraySequence| storage.\n\n for (var i = 0; i < destinationLength; ++i) {\n var readIndex = (this._readIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n arraySequence[channel][i] = this._channelData[channel][readIndex];\n }\n }\n\n this._readIndex += destinationLength;\n\n if (this._readIndex >= this._length) {\n this._readIndex = 0;\n }\n\n this._framesAvailable -= destinationLength;\n\n if (this._framesAvailable < 0) {\n this._framesAvailable = 0;\n }\n }\n }, {\n key: "framesAvailable",\n get: function get() {\n return this._framesAvailable;\n }\n }]);\n\n return RingBuffer;\n }()\n}["default"];\n\nvar SoundFileProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(SoundFileProcessor, _AudioWorkletProcesso);\n\n function SoundFileProcessor(options) {\n var _this;\n\n _classCallCheck(this, SoundFileProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(SoundFileProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.bufferSize = processorOptions.bufferSize || 256;\n _this.inputRingBuffer = new RingBuffer(_this.bufferSize, 1);\n _this.inputRingBufferArraySequence = [new Float32Array(_this.bufferSize)];\n return _this;\n }\n\n _createClass(SoundFileProcessor, [{\n key: "process",\n value: function process(inputs) {\n var input = inputs[0]; // we only care about the first input channel, because that contains the position data\n\n this.inputRingBuffer.push([input[0]]);\n\n if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {\n this.inputRingBuffer.pull(this.inputRingBufferArraySequence);\n var inputChannel = this.inputRingBufferArraySequence[0];\n var position = inputChannel[inputChannel.length - 1] || 0;\n this.port.postMessage({\n name: \'position\',\n position: position\n });\n }\n\n return true;\n }\n }]);\n\n return SoundFileProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.soundFileProcessor, SoundFileProcessor);'},function(t,e,n){"use strict";n.r(e),e.default='function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }\n\nfunction isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }\n\nfunction _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n// import dependencies via preval.require so that they\'re available as values at compile time\nvar processorNames = {\n "recorderProcessor": "recorder-processor",\n "soundFileProcessor": "sound-file-processor",\n "amplitudeProcessor": "amplitude-processor"\n};\nvar RingBuffer = {\n "default":\n /*#__PURE__*/\n function () {\n /**\n * @constructor\n * @param {number} length Buffer length in frames.\n * @param {number} channelCount Buffer channel count.\n */\n function RingBuffer(length, channelCount) {\n _classCallCheck(this, RingBuffer);\n\n this._readIndex = 0;\n this._writeIndex = 0;\n this._framesAvailable = 0;\n this._channelCount = channelCount;\n this._length = length;\n this._channelData = [];\n\n for (var i = 0; i < this._channelCount; ++i) {\n this._channelData[i] = new Float32Array(length);\n }\n }\n /**\n * Getter for Available frames in buffer.\n *\n * @return {number} Available frames in buffer.\n */\n\n\n _createClass(RingBuffer, [{\n key: "push",\n\n /**\n * Push a sequence of Float32Arrays to buffer.\n *\n * @param {array} arraySequence A sequence of Float32Arrays.\n */\n value: function push(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // Transfer data from the |arraySequence| storage to the internal buffer.\n var sourceLength = arraySequence[0] ? arraySequence[0].length : 0;\n\n for (var i = 0; i < sourceLength; ++i) {\n var writeIndex = (this._writeIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n this._channelData[channel][writeIndex] = arraySequence[channel][i];\n }\n }\n\n this._writeIndex += sourceLength;\n\n if (this._writeIndex >= this._length) {\n this._writeIndex = 0;\n } // For excessive frames, the buffer will be overwritten.\n\n\n this._framesAvailable += sourceLength;\n\n if (this._framesAvailable > this._length) {\n this._framesAvailable = this._length;\n }\n }\n /**\n * Pull data out of buffer and fill a given sequence of Float32Arrays.\n *\n * @param {array} arraySequence An array of Float32Arrays.\n */\n\n }, {\n key: "pull",\n value: function pull(arraySequence) {\n // The channel count of arraySequence and the length of each channel must\n // match with this buffer obejct.\n // If the FIFO is completely empty, do nothing.\n if (this._framesAvailable === 0) {\n return;\n }\n\n var destinationLength = arraySequence[0].length; // Transfer data from the internal buffer to the |arraySequence| storage.\n\n for (var i = 0; i < destinationLength; ++i) {\n var readIndex = (this._readIndex + i) % this._length;\n\n for (var channel = 0; channel < this._channelCount; ++channel) {\n arraySequence[channel][i] = this._channelData[channel][readIndex];\n }\n }\n\n this._readIndex += destinationLength;\n\n if (this._readIndex >= this._length) {\n this._readIndex = 0;\n }\n\n this._framesAvailable -= destinationLength;\n\n if (this._framesAvailable < 0) {\n this._framesAvailable = 0;\n }\n }\n }, {\n key: "framesAvailable",\n get: function get() {\n return this._framesAvailable;\n }\n }]);\n\n return RingBuffer;\n }()\n}["default"];\n\nvar AmplitudeProcessor =\n/*#__PURE__*/\nfunction (_AudioWorkletProcesso) {\n _inherits(AmplitudeProcessor, _AudioWorkletProcesso);\n\n function AmplitudeProcessor(options) {\n var _this;\n\n _classCallCheck(this, AmplitudeProcessor);\n\n _this = _possibleConstructorReturn(this, _getPrototypeOf(AmplitudeProcessor).call(this));\n var processorOptions = options.processorOptions || {};\n _this.numOutputChannels = options.outputChannelCount || 1;\n _this.numInputChannels = processorOptions.numInputChannels || 2;\n _this.normalize = processorOptions.normalize || false;\n _this.smoothing = processorOptions.smoothing || 0;\n _this.bufferSize = processorOptions.bufferSize || 2048;\n _this.inputRingBuffer = new RingBuffer(_this.bufferSize, _this.numInputChannels);\n _this.outputRingBuffer = new RingBuffer(_this.bufferSize, _this.numOutputChannels);\n _this.inputRingBufferArraySequence = new Array(_this.numInputChannels).fill(null).map(function () {\n return new Float32Array(_this.bufferSize);\n });\n _this.stereoVol = [0, 0];\n _this.stereoVolNorm = [0, 0];\n _this.volMax = 0.001;\n\n _this.port.onmessage = function (event) {\n var data = event.data;\n\n if (data.name === \'toggleNormalize\') {\n _this.normalize = data.normalize;\n } else if (data.name === \'smoothing\') {\n _this.smoothing = Math.max(0, Math.min(1, data.smoothing));\n }\n };\n\n return _this;\n } // TO DO make this stereo / dependent on # of audio channels\n\n\n _createClass(AmplitudeProcessor, [{\n key: "process",\n value: function process(inputs, outputs) {\n var input = inputs[0];\n var output = outputs[0];\n var smoothing = this.smoothing;\n this.inputRingBuffer.push(input);\n\n if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {\n this.inputRingBuffer.pull(this.inputRingBufferArraySequence);\n\n for (var channel = 0; channel < this.numInputChannels; ++channel) {\n var inputBuffer = this.inputRingBufferArraySequence[channel];\n var bufLength = inputBuffer.length;\n var sum = 0;\n\n for (var i = 0; i < bufLength; i++) {\n var x = inputBuffer[i];\n\n if (this.normalize) {\n sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1);\n } else {\n sum += x * x;\n }\n } // ... then take the square root of the sum.\n\n\n var rms = Math.sqrt(sum / bufLength);\n this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing);\n this.volMax = Math.max(this.stereoVol[channel], this.volMax);\n } // calculate stero normalized volume and add volume from all channels together\n\n\n var volSum = 0;\n\n for (var index = 0; index < this.stereoVol.length; index++) {\n this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0);\n volSum += this.stereoVol[index];\n } // volume is average of channels\n\n\n var volume = volSum / this.stereoVol.length; // normalized value\n\n var volNorm = Math.max(Math.min(volume / this.volMax, 1), 0);\n this.port.postMessage({\n name: \'amplitude\',\n volume: volume,\n volNorm: volNorm,\n stereoVol: this.stereoVol,\n stereoVolNorm: this.stereoVolNorm\n }); // pass input through to output\n\n this.outputRingBuffer.push(this.inputRingBufferArraySequence);\n } // pull 128 frames out of the ring buffer\n // if the ring buffer does not have enough frames, the output will be silent\n\n\n this.outputRingBuffer.pull(output);\n return true;\n }\n }]);\n\n return AmplitudeProcessor;\n}(_wrapNativeSuper(AudioWorkletProcessor));\n\nregisterProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor);'},function(t,e,n){var i,r;i=[n(0),n(17)],void 0===(r=function(r){r.Frequency=function(t,e){if(!(this instanceof r.Frequency))return new r.Frequency(t,e);r.TimeBase.call(this,t,e)},r.extend(r.Frequency,r.TimeBase),r.Frequency.prototype._primaryExpressions=Object.create(r.TimeBase.prototype._primaryExpressions),r.Frequency.prototype._primaryExpressions.midi={regexp:/^(\d+(?:\.\d+)?midi)/,method:function(t){return this.midiToFrequency(t)}},r.Frequency.prototype._primaryExpressions.note={regexp:/^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,method:function(t,e){var n=i[t.toLowerCase()]+12*(parseInt(e)+1);return this.midiToFrequency(n)}},r.Frequency.prototype._primaryExpressions.tr={regexp:/^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/,method:function(t,e,n){var i=1;return t&&"0"!==t&&(i*=this._beatsToUnits(this._timeSignature()*parseFloat(t))),e&&"0"!==e&&(i*=this._beatsToUnits(parseFloat(e))),n&&"0"!==n&&(i*=this._beatsToUnits(parseFloat(n)/4)),i}},r.Frequency.prototype.transpose=function(t){return this._expr=function(t,e){return t()*this.intervalToFrequencyRatio(e)}.bind(this,this._expr,t),this},r.Frequency.prototype.harmonize=function(t){return this._expr=function(t,e){for(var n=t(),i=[],r=0;rthis.buffer.duration)throw"jump time out of range";if(e>this.buffer.duration-t)throw"end time out of range";var n=t||0,i=e||void 0;this.isPlaying()&&(this.stop(0),this.play(0,this.playbackRate,this.output.gain.value,n,i))}},{key:"channels",value:function(){return this.buffer.numberOfChannels}},{key:"sampleRate",value:function(){return this.buffer.sampleRate}},{key:"frames",value:function(){return this.buffer.length}},{key:"getPeaks",value:function(t){if(!this.buffer)throw"Cannot load peaks yet, buffer is not loaded";if(t=t||5*window.width,this.buffer){for(var e=this.buffer,n=e.length/t,i=~~(n/10)||1,r=e.numberOfChannels,o=new Float32Array(Math.round(t)),s=0;so[u])&&(o[u]=h)}return o}}},{key:"reverseBuffer",value:function(){if(!this.buffer)throw"SoundFile is not done loading";var t=this._lastPos/R.sampleRate,e=this.getVolume();this.setVolume(0,.001);for(var n=this.buffer.numberOfChannels,i=0;it[o].hi&&o++,r[o]=void 0!==r[o]?(r[o]+n[s])/2:n[s]}return r}},{key:"getOctaveBands",value:function(t,e){var n=t||3,i=e||15.625,r=[],o={lo:i/Math.pow(2,1/(2*n)),ctr:i,hi:i*Math.pow(2,1/(2*n))};r.push(o);for(var s=p.audiocontext.sampleRate/2;o.hi=this._maxDelay)throw new Error("Delay Time exceeds maximum delay time of "+this._maxDelay+" second.");t.connect(this.input),this.leftDelay.delayTime.setValueAtTime(o,this.ac.currentTime),this.rightDelay.delayTime.setValueAtTime(o,this.ac.currentTime),this._leftGain.gain.value=r,this._rightGain.gain.value=r,i&&(this._leftFilter.freq(i),this._rightFilter.freq(i))}},{key:"delayTime",value:function(t){"number"!=typeof t?(t.connect(this.leftDelay.delayTime),t.connect(this.rightDelay.delayTime)):(this.leftDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.rightDelay.delayTime.cancelScheduledValues(this.ac.currentTime),this.leftDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime),this.rightDelay.delayTime.linearRampToValueAtTime(t,this.ac.currentTime))}},{key:"feedback",value:function(t){if(t&&"number"!=typeof t)t.connect(this._leftGain.gain),t.connect(this._rightGain.gain);else{if(1<=t)throw new Error("Feedback value will force a positive feedback loop.");"number"==typeof t&&(this._leftGain.gain.value=t,this._rightGain.gain.value=t)}return this._leftGain.gain.value}},{key:"filter",value:function(t,e){this._leftFilter.set(t,e),this._rightFilter.set(t,e)}},{key:"setType",value:function(t){switch(1===t&&(t="pingPong"),this._split.disconnect(),this._leftFilter.disconnect(),this._rightFilter.disconnect(),this._split.connect(this.leftDelay,0),this._split.connect(this.rightDelay,1),t){case"pingPong":this._rightFilter.setType(this._leftFilter.biquad.type),this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.rightDelay),this._rightFilter.output.connect(this.leftDelay);break;default:this._leftFilter.output.connect(this._merge,0,0),this._rightFilter.output.connect(this._merge,0,1),this._leftFilter.output.connect(this.leftDelay),this._rightFilter.output.connect(this.rightDelay)}}},{key:"dispose",value:function(){de(ye(e.prototype),"dispose",this).call(this),this._split.disconnect(),this._leftFilter.dispose(),this._rightFilter.dispose(),this._merge.disconnect(),this._leftGain.disconnect(),this._rightGain.disconnect(),this.leftDelay.disconnect(),this.rightDelay.disconnect(),this._split=void 0,this._leftFilter=void 0,this._rightFilter=void 0,this._merge=void 0,this._leftGain=void 0,this._rightGain=void 0,this.leftDelay=void 0,this.rightDelay=void 0}}]),e}();function _e(t){return(_e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function ge(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function be(t,e){for(var n=0;nthis.length&&(this.length=i.sequence.length)}},{key:"removePhrase",value:function(t){for(var e in this.phrases)this.phrases[e].name===t&&this.phrases.splice(e,1)}},{key:"getPhrase",value:function(t){for(var e in this.phrases)if(this.phrases[e].name===t)return this.phrases[e]}},{key:"replaceSequence",value:function(t,e){for(var n in this.phrases)this.phrases[n].name===t&&(this.phrases[n].sequence=e)}},{key:"incrementStep",value:function(t){this.partStep=t.parts.length?(t.scoreStep=0,t.onended()):(t.scoreStep=0,t.parts[t.currentPart-1].stop(),t.parts[t.currentPart].start())}function Ue(t,e){for(var n=0;nthis.cutoff&&e>this.threshold&&0this.treshold){this.isDetected=!0,this.callback?this.callback(this.energy):e&&e(this.energy);var n=this;setTimeout(function(){n.isDetected=!1},this.sensitivity)}this.penergy=this.energy}}]),r}();function xn(t,e){for(var n=0;n/im, + bodyRegExp = /]*>\s*([\s\S]+)\s*<\/body>/im, + hasLocation = typeof location !== 'undefined' && location.href, + defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''), + defaultHostName = hasLocation && location.hostname, + defaultPort = hasLocation && (location.port || undefined), + buildMap = {}, + masterConfig = (module.config && module.config()) || {}; + + text = { + version: '2.0.10', + + strip: function (content) { + //Strips declarations so that external SVG and XML + //documents can be added to a document without worry. Also, if the string + //is an HTML document, only the part inside the body tag is returned. + if (content) { + content = content.replace(xmlRegExp, ""); + var matches = content.match(bodyRegExp); + if (matches) { + content = matches[1]; + } + } else { + content = ""; + } + return content; + }, + + jsEscape: function (content) { + return content.replace(/(['\\])/g, '\\$1') + .replace(/[\f]/g, "\\f") + .replace(/[\b]/g, "\\b") + .replace(/[\n]/g, "\\n") + .replace(/[\t]/g, "\\t") + .replace(/[\r]/g, "\\r") + .replace(/[\u2028]/g, "\\u2028") + .replace(/[\u2029]/g, "\\u2029"); + }, + + createXhr: masterConfig.createXhr || function () { + //Would love to dump the ActiveX crap in here. Need IE 6 to die first. + var xhr, i, progId; + if (typeof XMLHttpRequest !== "undefined") { + return new XMLHttpRequest(); + } else if (typeof ActiveXObject !== "undefined") { + for (i = 0; i < 3; i += 1) { + progId = progIds[i]; + try { + xhr = new ActiveXObject(progId); + } catch (e) {} + + if (xhr) { + progIds = [progId]; // so faster next time + break; + } + } + } + + return xhr; + }, + + /** + * Parses a resource name into its component parts. Resource names + * look like: module/name.ext!strip, where the !strip part is + * optional. + * @param {String} name the resource name + * @returns {Object} with properties "moduleName", "ext" and "strip" + * where strip is a boolean. + */ + parseName: function (name) { + var modName, ext, temp, + strip = false, + index = name.indexOf("."), + isRelative = name.indexOf('./') === 0 || + name.indexOf('../') === 0; + + if (index !== -1 && (!isRelative || index > 1)) { + modName = name.substring(0, index); + ext = name.substring(index + 1, name.length); + } else { + modName = name; + } + + temp = ext || modName; + index = temp.indexOf("!"); + if (index !== -1) { + //Pull off the strip arg. + strip = temp.substring(index + 1) === "strip"; + temp = temp.substring(0, index); + if (ext) { + ext = temp; + } else { + modName = temp; + } + } + + return { + moduleName: modName, + ext: ext, + strip: strip + }; + }, + + xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/, + + /** + * Is an URL on another domain. Only works for browser use, returns + * false in non-browser environments. Only used to know if an + * optimized .js version of a text resource should be loaded + * instead. + * @param {String} url + * @returns Boolean + */ + useXhr: function (url, protocol, hostname, port) { + var uProtocol, uHostName, uPort, + match = text.xdRegExp.exec(url); + if (!match) { + return true; + } + uProtocol = match[2]; + uHostName = match[3]; + + uHostName = uHostName.split(':'); + uPort = uHostName[1]; + uHostName = uHostName[0]; + + return (!uProtocol || uProtocol === protocol) && + (!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) && + ((!uPort && !uHostName) || uPort === port); + }, + + finishLoad: function (name, strip, content, onLoad) { + content = strip ? text.strip(content) : content; + if (masterConfig.isBuild) { + buildMap[name] = content; + } + onLoad(content); + }, + + load: function (name, req, onLoad, config) { + //Name has format: some.module.filext!strip + //The strip part is optional. + //if strip is present, then that means only get the string contents + //inside a body tag in an HTML string. For XML/SVG content it means + //removing the declarations so the content can be inserted + //into the current doc without problems. + + // Do not bother with the work if a build and text will + // not be inlined. + if (config.isBuild && !config.inlineText) { + onLoad(); + return; + } + + masterConfig.isBuild = config.isBuild; + + var parsed = text.parseName(name), + nonStripName = parsed.moduleName + + (parsed.ext ? '.' + parsed.ext : ''), + url = req.toUrl(nonStripName), + useXhr = (masterConfig.useXhr) || + text.useXhr; + + // Do not load if it is an empty: url + if (url.indexOf('empty:') === 0) { + onLoad(); + return; + } + + //Load the text. Use XHR if possible and in a browser. + if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) { + text.get(url, function (content) { + text.finishLoad(name, parsed.strip, content, onLoad); + }, function (err) { + if (onLoad.error) { + onLoad.error(err); + } + }); + } else { + //Need to fetch the resource across domains. Assume + //the resource has been optimized into a JS module. Fetch + //by the module name + extension, but do not include the + //!strip part to avoid file system issues. + req([nonStripName], function (content) { + text.finishLoad(parsed.moduleName + '.' + parsed.ext, + parsed.strip, content, onLoad); + }); + } + }, + + write: function (pluginName, moduleName, write, config) { + if (buildMap.hasOwnProperty(moduleName)) { + var content = text.jsEscape(buildMap[moduleName]); + write.asModule(pluginName + "!" + moduleName, + "define(function () { return '" + + content + + "';});\n"); + } + }, + + writeFile: function (pluginName, moduleName, req, write, config) { + var parsed = text.parseName(moduleName), + extPart = parsed.ext ? '.' + parsed.ext : '', + nonStripName = parsed.moduleName + extPart, + //Use a '.js' file name so that it indicates it is a + //script that can be loaded across domains. + fileName = req.toUrl(parsed.moduleName + extPart) + '.js'; + + //Leverage own load() method to load plugin value, but only + //write out values that do not have the strip argument, + //to avoid any potential issues with ! in file names. + text.load(nonStripName, req, function (value) { + //Use own write() method to construct full module value. + //But need to create shell that translates writeFile's + //write() to the right interface. + var textWrite = function (contents) { + return write(fileName, contents); + }; + textWrite.asModule = function (moduleName, contents) { + return write.asModule(moduleName, fileName, contents); + }; + + text.write(pluginName, nonStripName, textWrite, config); + }, config); + } + }; + + if (masterConfig.env === 'node' || (!masterConfig.env && + typeof process !== "undefined" && + process.versions && + !!process.versions.node && + !process.versions['node-webkit'])) { + //Using special require.nodeRequire, something added by r.js. + fs = require.nodeRequire('fs'); + + text.get = function (url, callback, errback) { + try { + var file = fs.readFileSync(url, 'utf8'); + //Remove BOM (Byte Mark Order) from utf8 files if it is there. + if (file.indexOf('\uFEFF') === 0) { + file = file.substring(1); + } + callback(file); + } catch (e) { + errback(e); + } + }; + } else if (masterConfig.env === 'xhr' || (!masterConfig.env && + text.createXhr())) { + text.get = function (url, callback, errback, headers) { + var xhr = text.createXhr(), header; + xhr.open('GET', url, true); + + //Allow plugins direct access to xhr headers + if (headers) { + for (header in headers) { + if (headers.hasOwnProperty(header)) { + xhr.setRequestHeader(header.toLowerCase(), headers[header]); + } + } + } + + //Allow overrides specified in config + if (masterConfig.onXhr) { + masterConfig.onXhr(xhr, url); + } + + xhr.onreadystatechange = function (evt) { + var status, err; + //Do not explicitly handle errors, those should be + //visible via console output in the browser. + if (xhr.readyState === 4) { + status = xhr.status; + if (status > 399 && status < 600) { + //An http 4xx or 5xx error. Signal an error. + err = new Error(url + ' HTTP status: ' + status); + err.xhr = xhr; + errback(err); + } else { + callback(xhr.responseText); + } + + if (masterConfig.onXhrComplete) { + masterConfig.onXhrComplete(xhr, url); + } + } + }; + xhr.send(null); + }; + } else if (masterConfig.env === 'rhino' || (!masterConfig.env && + typeof Packages !== 'undefined' && typeof java !== 'undefined')) { + //Why Java, why is this so awkward? + text.get = function (url, callback) { + var stringBuffer, line, + encoding = "utf-8", + file = new java.io.File(url), + lineSeparator = java.lang.System.getProperty("line.separator"), + input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)), + content = ''; + try { + stringBuffer = new java.lang.StringBuffer(); + line = input.readLine(); + + // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324 + // http://www.unicode.org/faq/utf_bom.html + + // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK: + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 + if (line && line.length() && line.charAt(0) === 0xfeff) { + // Eat the BOM, since we've already found the encoding on this file, + // and we plan to concatenating this buffer with others; the BOM should + // only appear at the top of a file. + line = line.substring(1); + } + + if (line !== null) { + stringBuffer.append(line); + } + + while ((line = input.readLine()) !== null) { + stringBuffer.append(lineSeparator); + stringBuffer.append(line); + } + //Make sure we return a JavaScript string and not a Java string. + content = String(stringBuffer.toString()); //String + } finally { + input.close(); + } + callback(content); + }; + } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env && + typeof Components !== 'undefined' && Components.classes && + Components.interfaces)) { + //Avert your gaze! + Cc = Components.classes, + Ci = Components.interfaces; + Components.utils['import']('resource://gre/modules/FileUtils.jsm'); + xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc); + + text.get = function (url, callback) { + var inStream, convertStream, fileObj, + readData = {}; + + if (xpcIsWindows) { + url = url.replace(/\//g, '\\'); + } + + fileObj = new FileUtils.File(url); + + //XPCOM, you so crazy + try { + inStream = Cc['@mozilla.org/network/file-input-stream;1'] + .createInstance(Ci.nsIFileInputStream); + inStream.init(fileObj, 1, 0, false); + + convertStream = Cc['@mozilla.org/intl/converter-input-stream;1'] + .createInstance(Ci.nsIConverterInputStream); + convertStream.init(inStream, "utf-8", inStream.available(), + Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); + + convertStream.readString(inStream.available(), readData); + convertStream.close(); + inStream.close(); + callback(readData.value); + } catch (e) { + throw new Error((fileObj && fileObj.path || '') + ': ' + e); + } + }; + } + return text; +}); + + +define('text!tpl/search.html',[],function () { return '

        search

        \r\n
        \r\n \r\n \r\n
        \r\n\r\n';}); + + +define('text!tpl/search_suggestion.html',[],function () { return '

        \r\n\r\n <%=name%>\r\n\r\n \r\n <% if (final) { %>\r\n constant\r\n <% } else if (itemtype) { %>\r\n <%=itemtype%> \r\n <% } %>\r\n\r\n <% if (className) { %>\r\n in <%=className%>\r\n <% } %>\r\n\r\n <% if (typeof is_constructor !== \'undefined\' && is_constructor) { %>\r\n constructor\r\n <% } %>\r\n \r\n\r\n

        ';}); + +/*! + * typeahead.js 0.10.2 + * https://github.com/twitter/typeahead.js + * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT + */ +define('typeahead',[], function() { + +//(function($) { + + + var _ = { + isMsie: function() { + return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; + }, + isBlankString: function(str) { + return !str || /^\s*$/.test(str); + }, + escapeRegExChars: function(str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); + }, + isString: function(obj) { + return typeof obj === "string"; + }, + isNumber: function(obj) { + return typeof obj === "number"; + }, + isArray: $.isArray, + isFunction: $.isFunction, + isObject: $.isPlainObject, + isUndefined: function(obj) { + return typeof obj === "undefined"; + }, + bind: $.proxy, + each: function(collection, cb) { + $.each(collection, reverseArgs); + function reverseArgs(index, value) { + return cb(value, index); + } + }, + map: $.map, + filter: $.grep, + every: function(obj, test) { + var result = true; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (!(result = test.call(null, val, key, obj))) { + return false; + } + }); + return !!result; + }, + some: function(obj, test) { + var result = false; + if (!obj) { + return result; + } + $.each(obj, function(key, val) { + if (result = test.call(null, val, key, obj)) { + return false; + } + }); + return !!result; + }, + mixin: $.extend, + getUniqueId: function() { + var counter = 0; + return function() { + return counter++; + }; + }(), + templatify: function templatify(obj) { + return $.isFunction(obj) ? obj : template; + function template() { + return String(obj); + } + }, + defer: function(fn) { + setTimeout(fn, 0); + }, + debounce: function(func, wait, immediate) { + var timeout, result; + return function() { + var context = this, args = arguments, later, callNow; + later = function() { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + } + }; + callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) { + result = func.apply(context, args); + } + return result; + }; + }, + throttle: function(func, wait) { + var context, args, timeout, result, previous, later; + previous = 0; + later = function() { + previous = new Date(); + timeout = null; + result = func.apply(context, args); + }; + return function() { + var now = new Date(), remaining = wait - (now - previous); + context = this; + args = arguments; + if (remaining <= 0) { + clearTimeout(timeout); + timeout = null; + previous = now; + result = func.apply(context, args); + } else if (!timeout) { + timeout = setTimeout(later, remaining); + } + return result; + }; + }, + noop: function() {} + }; + var VERSION = "0.10.2"; + var tokenizers = function(root) { + return { + nonword: nonword, + whitespace: whitespace, + obj: { + nonword: getObjTokenizer(nonword), + whitespace: getObjTokenizer(whitespace) + } + }; + function whitespace(s) { + return s.split(/\s+/); + } + function nonword(s) { + return s.split(/\W+/); + } + function getObjTokenizer(tokenizer) { + return function setKey(key) { + return function tokenize(o) { + return tokenizer(o[key]); + }; + }; + } + }(); + var LruCache = function() { + function LruCache(maxSize) { + this.maxSize = maxSize || 100; + this.size = 0; + this.hash = {}; + this.list = new List(); + } + _.mixin(LruCache.prototype, { + set: function set(key, val) { + var tailItem = this.list.tail, node; + if (this.size >= this.maxSize) { + this.list.remove(tailItem); + delete this.hash[tailItem.key]; + } + if (node = this.hash[key]) { + node.val = val; + this.list.moveToFront(node); + } else { + node = new Node(key, val); + this.list.add(node); + this.hash[key] = node; + this.size++; + } + }, + get: function get(key) { + var node = this.hash[key]; + if (node) { + this.list.moveToFront(node); + return node.val; + } + } + }); + function List() { + this.head = this.tail = null; + } + _.mixin(List.prototype, { + add: function add(node) { + if (this.head) { + node.next = this.head; + this.head.prev = node; + } + this.head = node; + this.tail = this.tail || node; + }, + remove: function remove(node) { + node.prev ? node.prev.next = node.next : this.head = node.next; + node.next ? node.next.prev = node.prev : this.tail = node.prev; + }, + moveToFront: function(node) { + this.remove(node); + this.add(node); + } + }); + function Node(key, val) { + this.key = key; + this.val = val; + this.prev = this.next = null; + } + return LruCache; + }(); + var PersistentStorage = function() { + var ls, methods; + try { + ls = window.localStorage; + ls.setItem("~~~", "!"); + ls.removeItem("~~~"); + } catch (err) { + ls = null; + } + function PersistentStorage(namespace) { + this.prefix = [ "__", namespace, "__" ].join(""); + this.ttlKey = "__ttl__"; + this.keyMatcher = new RegExp("^" + this.prefix); + } + if (ls && window.JSON) { + methods = { + _prefix: function(key) { + return this.prefix + key; + }, + _ttlKey: function(key) { + return this._prefix(key) + this.ttlKey; + }, + get: function(key) { + if (this.isExpired(key)) { + this.remove(key); + } + return decode(ls.getItem(this._prefix(key))); + }, + set: function(key, val, ttl) { + if (_.isNumber(ttl)) { + ls.setItem(this._ttlKey(key), encode(now() + ttl)); + } else { + ls.removeItem(this._ttlKey(key)); + } + return ls.setItem(this._prefix(key), encode(val)); + }, + remove: function(key) { + ls.removeItem(this._ttlKey(key)); + ls.removeItem(this._prefix(key)); + return this; + }, + clear: function() { + var i, key, keys = [], len = ls.length; + for (i = 0; i < len; i++) { + if ((key = ls.key(i)).match(this.keyMatcher)) { + keys.push(key.replace(this.keyMatcher, "")); + } + } + for (i = keys.length; i--; ) { + this.remove(keys[i]); + } + return this; + }, + isExpired: function(key) { + var ttl = decode(ls.getItem(this._ttlKey(key))); + return _.isNumber(ttl) && now() > ttl ? true : false; + } + }; + } else { + methods = { + get: _.noop, + set: _.noop, + remove: _.noop, + clear: _.noop, + isExpired: _.noop + }; + } + _.mixin(PersistentStorage.prototype, methods); + return PersistentStorage; + function now() { + return new Date().getTime(); + } + function encode(val) { + return JSON.stringify(_.isUndefined(val) ? null : val); + } + function decode(val) { + return JSON.parse(val); + } + }(); + var Transport = function() { + var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, requestCache = new LruCache(10); + function Transport(o) { + o = o || {}; + this._send = o.transport ? callbackToDeferred(o.transport) : $.ajax; + this._get = o.rateLimiter ? o.rateLimiter(this._get) : this._get; + } + Transport.setMaxPendingRequests = function setMaxPendingRequests(num) { + maxPendingRequests = num; + }; + Transport.resetCache = function clearCache() { + requestCache = new LruCache(10); + }; + _.mixin(Transport.prototype, { + _get: function(url, o, cb) { + var that = this, jqXhr; + if (jqXhr = pendingRequests[url]) { + jqXhr.done(done).fail(fail); + } else if (pendingRequestsCount < maxPendingRequests) { + pendingRequestsCount++; + pendingRequests[url] = this._send(url, o).done(done).fail(fail).always(always); + } else { + this.onDeckRequestArgs = [].slice.call(arguments, 0); + } + function done(resp) { + cb && cb(null, resp); + requestCache.set(url, resp); + } + function fail() { + cb && cb(true); + } + function always() { + pendingRequestsCount--; + delete pendingRequests[url]; + if (that.onDeckRequestArgs) { + that._get.apply(that, that.onDeckRequestArgs); + that.onDeckRequestArgs = null; + } + } + }, + get: function(url, o, cb) { + var resp; + if (_.isFunction(o)) { + cb = o; + o = {}; + } + if (resp = requestCache.get(url)) { + _.defer(function() { + cb && cb(null, resp); + }); + } else { + this._get(url, o, cb); + } + return !!resp; + } + }); + return Transport; + function callbackToDeferred(fn) { + return function customSendWrapper(url, o) { + var deferred = $.Deferred(); + fn(url, o, onSuccess, onError); + return deferred; + function onSuccess(resp) { + _.defer(function() { + deferred.resolve(resp); + }); + } + function onError(err) { + _.defer(function() { + deferred.reject(err); + }); + } + }; + } + }(); + var SearchIndex = function() { + function SearchIndex(o) { + o = o || {}; + if (!o.datumTokenizer || !o.queryTokenizer) { + $.error("datumTokenizer and queryTokenizer are both required"); + } + this.datumTokenizer = o.datumTokenizer; + this.queryTokenizer = o.queryTokenizer; + this.reset(); + } + _.mixin(SearchIndex.prototype, { + bootstrap: function bootstrap(o) { + this.datums = o.datums; + this.trie = o.trie; + }, + add: function(data) { + var that = this; + data = _.isArray(data) ? data : [ data ]; + _.each(data, function(datum) { + var id, tokens; + id = that.datums.push(datum) - 1; + tokens = normalizeTokens(that.datumTokenizer(datum)); + _.each(tokens, function(token) { + var node, chars, ch; + node = that.trie; + chars = token.split(""); + while (ch = chars.shift()) { + node = node.children[ch] || (node.children[ch] = newNode()); + node.ids.push(id); + } + }); + }); + }, + get: function get(query) { + var that = this, tokens, matches; + tokens = normalizeTokens(this.queryTokenizer(query)); + _.each(tokens, function(token) { + var node, chars, ch, ids; + if (matches && matches.length === 0) { + return false; + } + node = that.trie; + chars = token.split(""); + while (node && (ch = chars.shift())) { + node = node.children[ch]; + } + if (node && chars.length === 0) { + ids = node.ids.slice(0); + matches = matches ? getIntersection(matches, ids) : ids; + } else { + matches = []; + return false; + } + }); + return matches ? _.map(unique(matches), function(id) { + return that.datums[id]; + }) : []; + }, + reset: function reset() { + this.datums = []; + this.trie = newNode(); + }, + serialize: function serialize() { + return { + datums: this.datums, + trie: this.trie + }; + } + }); + return SearchIndex; + function normalizeTokens(tokens) { + tokens = _.filter(tokens, function(token) { + return !!token; + }); + tokens = _.map(tokens, function(token) { + return token.toLowerCase(); + }); + return tokens; + } + function newNode() { + return { + ids: [], + children: {} + }; + } + function unique(array) { + var seen = {}, uniques = []; + for (var i = 0; i < array.length; i++) { + if (!seen[array[i]]) { + seen[array[i]] = true; + uniques.push(array[i]); + } + } + return uniques; + } + function getIntersection(arrayA, arrayB) { + var ai = 0, bi = 0, intersection = []; + arrayA = arrayA.sort(compare); + arrayB = arrayB.sort(compare); + while (ai < arrayA.length && bi < arrayB.length) { + if (arrayA[ai] < arrayB[bi]) { + ai++; + } else if (arrayA[ai] > arrayB[bi]) { + bi++; + } else { + intersection.push(arrayA[ai]); + ai++; + bi++; + } + } + return intersection; + function compare(a, b) { + return a - b; + } + } + }(); + var oParser = function() { + return { + local: getLocal, + prefetch: getPrefetch, + remote: getRemote + }; + function getLocal(o) { + return o.local || null; + } + function getPrefetch(o) { + var prefetch, defaults; + defaults = { + url: null, + thumbprint: "", + ttl: 24 * 60 * 60 * 1e3, + filter: null, + ajax: {} + }; + if (prefetch = o.prefetch || null) { + prefetch = _.isString(prefetch) ? { + url: prefetch + } : prefetch; + prefetch = _.mixin(defaults, prefetch); + prefetch.thumbprint = VERSION + prefetch.thumbprint; + prefetch.ajax.type = prefetch.ajax.type || "GET"; + prefetch.ajax.dataType = prefetch.ajax.dataType || "json"; + !prefetch.url && $.error("prefetch requires url to be set"); + } + return prefetch; + } + function getRemote(o) { + var remote, defaults; + defaults = { + url: null, + wildcard: "%QUERY", + replace: null, + rateLimitBy: "debounce", + rateLimitWait: 300, + send: null, + filter: null, + ajax: {} + }; + if (remote = o.remote || null) { + remote = _.isString(remote) ? { + url: remote + } : remote; + remote = _.mixin(defaults, remote); + remote.rateLimiter = /^throttle$/i.test(remote.rateLimitBy) ? byThrottle(remote.rateLimitWait) : byDebounce(remote.rateLimitWait); + remote.ajax.type = remote.ajax.type || "GET"; + remote.ajax.dataType = remote.ajax.dataType || "json"; + delete remote.rateLimitBy; + delete remote.rateLimitWait; + !remote.url && $.error("remote requires url to be set"); + } + return remote; + function byDebounce(wait) { + return function(fn) { + return _.debounce(fn, wait); + }; + } + function byThrottle(wait) { + return function(fn) { + return _.throttle(fn, wait); + }; + } + } + }(); + (function(root) { + var old, keys; + old = root.Bloodhound; + keys = { + data: "data", + protocol: "protocol", + thumbprint: "thumbprint" + }; + root.Bloodhound = Bloodhound; + function Bloodhound(o) { + if (!o || !o.local && !o.prefetch && !o.remote) { + $.error("one of local, prefetch, or remote is required"); + } + this.limit = o.limit || 5; + this.sorter = getSorter(o.sorter); + this.dupDetector = o.dupDetector || ignoreDuplicates; + this.local = oParser.local(o); + this.prefetch = oParser.prefetch(o); + this.remote = oParser.remote(o); + this.cacheKey = this.prefetch ? this.prefetch.cacheKey || this.prefetch.url : null; + this.index = new SearchIndex({ + datumTokenizer: o.datumTokenizer, + queryTokenizer: o.queryTokenizer + }); + this.storage = this.cacheKey ? new PersistentStorage(this.cacheKey) : null; + } + Bloodhound.noConflict = function noConflict() { + root.Bloodhound = old; + return Bloodhound; + }; + Bloodhound.tokenizers = tokenizers; + _.mixin(Bloodhound.prototype, { + _loadPrefetch: function loadPrefetch(o) { + var that = this, serialized, deferred; + if (serialized = this._readFromStorage(o.thumbprint)) { + this.index.bootstrap(serialized); + deferred = $.Deferred().resolve(); + } else { + deferred = $.ajax(o.url, o.ajax).done(handlePrefetchResponse); + } + return deferred; + function handlePrefetchResponse(resp) { + that.clear(); + that.add(o.filter ? o.filter(resp) : resp); + that._saveToStorage(that.index.serialize(), o.thumbprint, o.ttl); + } + }, + _getFromRemote: function getFromRemote(query, cb) { + var that = this, url, uriEncodedQuery; + query = query || ""; + uriEncodedQuery = encodeURIComponent(query); + url = this.remote.replace ? this.remote.replace(this.remote.url, query) : this.remote.url.replace(this.remote.wildcard, uriEncodedQuery); + return this.transport.get(url, this.remote.ajax, handleRemoteResponse); + function handleRemoteResponse(err, resp) { + err ? cb([]) : cb(that.remote.filter ? that.remote.filter(resp) : resp); + } + }, + _saveToStorage: function saveToStorage(data, thumbprint, ttl) { + if (this.storage) { + this.storage.set(keys.data, data, ttl); + this.storage.set(keys.protocol, location.protocol, ttl); + this.storage.set(keys.thumbprint, thumbprint, ttl); + } + }, + _readFromStorage: function readFromStorage(thumbprint) { + var stored = {}, isExpired; + if (this.storage) { + stored.data = this.storage.get(keys.data); + stored.protocol = this.storage.get(keys.protocol); + stored.thumbprint = this.storage.get(keys.thumbprint); + } + isExpired = stored.thumbprint !== thumbprint || stored.protocol !== location.protocol; + return stored.data && !isExpired ? stored.data : null; + }, + _initialize: function initialize() { + var that = this, local = this.local, deferred; + deferred = this.prefetch ? this._loadPrefetch(this.prefetch) : $.Deferred().resolve(); + local && deferred.done(addLocalToIndex); + this.transport = this.remote ? new Transport(this.remote) : null; + return this.initPromise = deferred.promise(); + function addLocalToIndex() { + that.add(_.isFunction(local) ? local() : local); + } + }, + initialize: function initialize(force) { + return !this.initPromise || force ? this._initialize() : this.initPromise; + }, + add: function add(data) { + this.index.add(data); + }, + get: function get(query, cb) { + var that = this, matches = [], cacheHit = false; + matches = this.index.get(query); + matches = this.sorter(matches).slice(0, this.limit); + if (matches.length < this.limit && this.transport) { + cacheHit = this._getFromRemote(query, returnRemoteMatches); + } + if (!cacheHit) { + (matches.length > 0 || !this.transport) && cb && cb(matches); + } + function returnRemoteMatches(remoteMatches) { + var matchesWithBackfill = matches.slice(0); + _.each(remoteMatches, function(remoteMatch) { + var isDuplicate; + isDuplicate = _.some(matchesWithBackfill, function(match) { + return that.dupDetector(remoteMatch, match); + }); + !isDuplicate && matchesWithBackfill.push(remoteMatch); + return matchesWithBackfill.length < that.limit; + }); + cb && cb(that.sorter(matchesWithBackfill)); + } + }, + clear: function clear() { + this.index.reset(); + }, + clearPrefetchCache: function clearPrefetchCache() { + this.storage && this.storage.clear(); + }, + clearRemoteCache: function clearRemoteCache() { + this.transport && Transport.resetCache(); + }, + ttAdapter: function ttAdapter() { + return _.bind(this.get, this); + } + }); + return Bloodhound; + function getSorter(sortFn) { + return _.isFunction(sortFn) ? sort : noSort; + function sort(array) { + return array.sort(sortFn); + } + function noSort(array) { + return array; + } + } + function ignoreDuplicates() { + return false; + } + })(this); + var html = { + wrapper: '', + dropdown: '', + dataset: '
        ', + suggestions: '', + suggestion: '
        ' + }; + var css = { + wrapper: { + position: "relative", + display: "inline-block" + }, + hint: { + position: "absolute", + top: "0", + left: "0", + borderColor: "transparent", + boxShadow: "none" + }, + input: { + position: "relative", + verticalAlign: "top", + backgroundColor: "transparent" + }, + inputWithNoHint: { + position: "relative", + verticalAlign: "top" + }, + dropdown: { + position: "absolute", + top: "100%", + left: "0", + zIndex: "100", + display: "none" + }, + suggestions: { + display: "block" + }, + suggestion: { + whiteSpace: "nowrap", + cursor: "pointer" + }, + suggestionChild: { + whiteSpace: "normal" + }, + ltr: { + left: "0", + right: "auto" + }, + rtl: { + left: "auto", + right: " 0" + } + }; + if (_.isMsie()) { + _.mixin(css.input, { + backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" + }); + } + if (_.isMsie() && _.isMsie() <= 7) { + _.mixin(css.input, { + marginTop: "-1px" + }); + } + var EventBus = function() { + var namespace = "typeahead:"; + function EventBus(o) { + if (!o || !o.el) { + $.error("EventBus initialized without el"); + } + this.$el = $(o.el); + } + _.mixin(EventBus.prototype, { + trigger: function(type) { + var args = [].slice.call(arguments, 1); + this.$el.trigger(namespace + type, args); + } + }); + return EventBus; + }(); + var EventEmitter = function() { + var splitter = /\s+/, nextTick = getNextTick(); + return { + onSync: onSync, + onAsync: onAsync, + off: off, + trigger: trigger + }; + function on(method, types, cb, context) { + var type; + if (!cb) { + return this; + } + types = types.split(splitter); + cb = context ? bindContext(cb, context) : cb; + this._callbacks = this._callbacks || {}; + while (type = types.shift()) { + this._callbacks[type] = this._callbacks[type] || { + sync: [], + async: [] + }; + this._callbacks[type][method].push(cb); + } + return this; + } + function onAsync(types, cb, context) { + return on.call(this, "async", types, cb, context); + } + function onSync(types, cb, context) { + return on.call(this, "sync", types, cb, context); + } + function off(types) { + var type; + if (!this._callbacks) { + return this; + } + types = types.split(splitter); + while (type = types.shift()) { + delete this._callbacks[type]; + } + return this; + } + function trigger(types) { + var type, callbacks, args, syncFlush, asyncFlush; + if (!this._callbacks) { + return this; + } + types = types.split(splitter); + args = [].slice.call(arguments, 1); + while ((type = types.shift()) && (callbacks = this._callbacks[type])) { + syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args)); + asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args)); + syncFlush() && nextTick(asyncFlush); + } + return this; + } + function getFlush(callbacks, context, args) { + return flush; + function flush() { + var cancelled; + for (var i = 0; !cancelled && i < callbacks.length; i += 1) { + cancelled = callbacks[i].apply(context, args) === false; + } + return !cancelled; + } + } + function getNextTick() { + var nextTickFn; + if (window.setImmediate) { + nextTickFn = function nextTickSetImmediate(fn) { + setImmediate(function() { + fn(); + }); + }; + } else { + nextTickFn = function nextTickSetTimeout(fn) { + setTimeout(function() { + fn(); + }, 0); + }; + } + return nextTickFn; + } + function bindContext(fn, context) { + return fn.bind ? fn.bind(context) : function() { + fn.apply(context, [].slice.call(arguments, 0)); + }; + } + }(); + var highlight = function(doc) { + var defaults = { + node: null, + pattern: null, + tagName: "strong", + className: null, + wordsOnly: false, + caseSensitive: false + }; + return function hightlight(o) { + var regex; + o = _.mixin({}, defaults, o); + if (!o.node || !o.pattern) { + return; + } + o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ]; + regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly); + traverse(o.node, hightlightTextNode); + function hightlightTextNode(textNode) { + var match, patternNode; + if (match = regex.exec(textNode.data)) { + wrapperNode = doc.createElement(o.tagName); + o.className && (wrapperNode.className = o.className); + patternNode = textNode.splitText(match.index); + patternNode.splitText(match[0].length); + wrapperNode.appendChild(patternNode.cloneNode(true)); + textNode.parentNode.replaceChild(wrapperNode, patternNode); + } + return !!match; + } + function traverse(el, hightlightTextNode) { + var childNode, TEXT_NODE_TYPE = 3; + for (var i = 0; i < el.childNodes.length; i++) { + childNode = el.childNodes[i]; + if (childNode.nodeType === TEXT_NODE_TYPE) { + i += hightlightTextNode(childNode) ? 1 : 0; + } else { + traverse(childNode, hightlightTextNode); + } + } + } + }; + function getRegex(patterns, caseSensitive, wordsOnly) { + var escapedPatterns = [], regexStr; + for (var i = 0; i < patterns.length; i++) { + escapedPatterns.push(_.escapeRegExChars(patterns[i])); + } + regexStr = wordsOnly ? "\\b(" + escapedPatterns.join("|") + ")\\b" : "(" + escapedPatterns.join("|") + ")"; + return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, "i"); + } + }(window.document); + var Input = function() { + var specialKeyCodeMap; + specialKeyCodeMap = { + 9: "tab", + 27: "esc", + 37: "left", + 39: "right", + 13: "enter", + 38: "up", + 40: "down" + }; + function Input(o) { + var that = this, onBlur, onFocus, onKeydown, onInput; + o = o || {}; + if (!o.input) { + $.error("input is missing"); + } + onBlur = _.bind(this._onBlur, this); + onFocus = _.bind(this._onFocus, this); + onKeydown = _.bind(this._onKeydown, this); + onInput = _.bind(this._onInput, this); + this.$hint = $(o.hint); + this.$input = $(o.input).on("blur.tt", onBlur).on("focus.tt", onFocus).on("keydown.tt", onKeydown); + if (this.$hint.length === 0) { + this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; + } + if (!_.isMsie()) { + this.$input.on("input.tt", onInput); + } else { + this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { + if (specialKeyCodeMap[$e.which || $e.keyCode]) { + return; + } + _.defer(_.bind(that._onInput, that, $e)); + }); + } + this.query = this.$input.val(); + this.$overflowHelper = buildOverflowHelper(this.$input); + } + Input.normalizeQuery = function(str) { + return (str || "").replace(/^\s*/g, "").replace(/\s{2,}/g, " "); + }; + _.mixin(Input.prototype, EventEmitter, { + _onBlur: function onBlur() { + this.resetInputValue(); + this.trigger("blurred"); + }, + _onFocus: function onFocus() { + this.trigger("focused"); + }, + _onKeydown: function onKeydown($e) { + var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; + this._managePreventDefault(keyName, $e); + if (keyName && this._shouldTrigger(keyName, $e)) { + this.trigger(keyName + "Keyed", $e); + } + }, + _onInput: function onInput() { + this._checkInputValue(); + }, + _managePreventDefault: function managePreventDefault(keyName, $e) { + var preventDefault, hintValue, inputValue; + switch (keyName) { + case "tab": + hintValue = this.getHint(); + inputValue = this.getInputValue(); + preventDefault = hintValue && hintValue !== inputValue && !withModifier($e); + break; + + case "up": + case "down": + preventDefault = !withModifier($e); + break; + + default: + preventDefault = false; + } + preventDefault && $e.preventDefault(); + }, + _shouldTrigger: function shouldTrigger(keyName, $e) { + var trigger; + switch (keyName) { + case "tab": + trigger = !withModifier($e); + break; + + default: + trigger = true; + } + return trigger; + }, + _checkInputValue: function checkInputValue() { + var inputValue, areEquivalent, hasDifferentWhitespace; + inputValue = this.getInputValue(); + areEquivalent = areQueriesEquivalent(inputValue, this.query); + hasDifferentWhitespace = areEquivalent ? this.query.length !== inputValue.length : false; + if (!areEquivalent) { + this.trigger("queryChanged", this.query = inputValue); + } else if (hasDifferentWhitespace) { + this.trigger("whitespaceChanged", this.query); + } + }, + focus: function focus() { + this.$input.focus(); + }, + blur: function blur() { + this.$input.blur(); + }, + getQuery: function getQuery() { + return this.query; + }, + setQuery: function setQuery(query) { + this.query = query; + }, + getInputValue: function getInputValue() { + return this.$input.val(); + }, + setInputValue: function setInputValue(value, silent) { + this.$input.val(value); + silent ? this.clearHint() : this._checkInputValue(); + }, + resetInputValue: function resetInputValue() { + this.setInputValue(this.query, true); + }, + getHint: function getHint() { + return this.$hint.val(); + }, + setHint: function setHint(value) { + this.$hint.val(value); + }, + clearHint: function clearHint() { + this.setHint(""); + }, + clearHintIfInvalid: function clearHintIfInvalid() { + var val, hint, valIsPrefixOfHint, isValid; + val = this.getInputValue(); + hint = this.getHint(); + valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0; + isValid = val !== "" && valIsPrefixOfHint && !this.hasOverflow(); + !isValid && this.clearHint(); + }, + getLanguageDirection: function getLanguageDirection() { + return (this.$input.css("direction") || "ltr").toLowerCase(); + }, + hasOverflow: function hasOverflow() { + var constraint = this.$input.width() - 2; + this.$overflowHelper.text(this.getInputValue()); + return this.$overflowHelper.width() >= constraint; + }, + isCursorAtEnd: function() { + var valueLength, selectionStart, range; + valueLength = this.$input.val().length; + selectionStart = this.$input[0].selectionStart; + if (_.isNumber(selectionStart)) { + return selectionStart === valueLength; + } else if (document.selection) { + range = document.selection.createRange(); + range.moveStart("character", -valueLength); + return valueLength === range.text.length; + } + return true; + }, + destroy: function destroy() { + this.$hint.off(".tt"); + this.$input.off(".tt"); + this.$hint = this.$input = this.$overflowHelper = null; + } + }); + return Input; + function buildOverflowHelper($input) { + return $('').css({ + position: "absolute", + visibility: "hidden", + whiteSpace: "pre", + fontFamily: $input.css("font-family"), + fontSize: $input.css("font-size"), + fontStyle: $input.css("font-style"), + fontVariant: $input.css("font-variant"), + fontWeight: $input.css("font-weight"), + wordSpacing: $input.css("word-spacing"), + letterSpacing: $input.css("letter-spacing"), + textIndent: $input.css("text-indent"), + textRendering: $input.css("text-rendering"), + textTransform: $input.css("text-transform") + }).insertAfter($input); + } + function areQueriesEquivalent(a, b) { + return Input.normalizeQuery(a) === Input.normalizeQuery(b); + } + function withModifier($e) { + return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey; + } + }(); + var Dataset = function() { + var datasetKey = "ttDataset", valueKey = "ttValue", datumKey = "ttDatum"; + function Dataset(o) { + o = o || {}; + o.templates = o.templates || {}; + if (!o.source) { + $.error("missing source"); + } + if (o.name && !isValidName(o.name)) { + $.error("invalid dataset name: " + o.name); + } + this.query = null; + this.highlight = !!o.highlight; + this.name = o.name || _.getUniqueId(); + this.source = o.source; + this.displayFn = getDisplayFn(o.display || o.displayKey); + this.templates = getTemplates(o.templates, this.displayFn); + this.$el = $(html.dataset.replace("%CLASS%", this.name)); + } + Dataset.extractDatasetName = function extractDatasetName(el) { + return $(el).data(datasetKey); + }; + Dataset.extractValue = function extractDatum(el) { + return $(el).data(valueKey); + }; + Dataset.extractDatum = function extractDatum(el) { + return $(el).data(datumKey); + }; + _.mixin(Dataset.prototype, EventEmitter, { + _render: function render(query, suggestions) { + if (!this.$el) { + return; + } + var that = this, hasSuggestions; + this.$el.empty(); + hasSuggestions = suggestions && suggestions.length; + if (!hasSuggestions && this.templates.empty) { + this.$el.html(getEmptyHtml()).prepend(that.templates.header ? getHeaderHtml() : null).append(that.templates.footer ? getFooterHtml() : null); + } else if (hasSuggestions) { + this.$el.html(getSuggestionsHtml()).prepend(that.templates.header ? getHeaderHtml() : null).append(that.templates.footer ? getFooterHtml() : null); + } + this.trigger("rendered"); + function getEmptyHtml() { + return that.templates.empty({ + query: query, + isEmpty: true + }); + } + function getSuggestionsHtml() { + var $suggestions, nodes; + $suggestions = $(html.suggestions).css(css.suggestions); + nodes = _.map(suggestions, getSuggestionNode); + $suggestions.append.apply($suggestions, nodes); + that.highlight && highlight({ + node: $suggestions[0], + pattern: query + }); + return $suggestions; + function getSuggestionNode(suggestion) { + var $el; + $el = $(html.suggestion).append(that.templates.suggestion(suggestion)).data(datasetKey, that.name).data(valueKey, that.displayFn(suggestion)).data(datumKey, suggestion); + $el.children().each(function() { + $(this).css(css.suggestionChild); + }); + return $el; + } + } + function getHeaderHtml() { + return that.templates.header({ + query: query, + isEmpty: !hasSuggestions + }); + } + function getFooterHtml() { + return that.templates.footer({ + query: query, + isEmpty: !hasSuggestions + }); + } + }, + getRoot: function getRoot() { + return this.$el; + }, + update: function update(query) { + var that = this; + this.query = query; + this.canceled = false; + this.source(query, render); + function render(suggestions) { + if (!that.canceled && query === that.query) { + that._render(query, suggestions); + } + } + }, + cancel: function cancel() { + this.canceled = true; + }, + clear: function clear() { + this.cancel(); + this.$el.empty(); + this.trigger("rendered"); + }, + isEmpty: function isEmpty() { + return this.$el.is(":empty"); + }, + destroy: function destroy() { + this.$el = null; + } + }); + return Dataset; + function getDisplayFn(display) { + display = display || "value"; + return _.isFunction(display) ? display : displayFn; + function displayFn(obj) { + return obj[display]; + } + } + function getTemplates(templates, displayFn) { + return { + empty: templates.empty && _.templatify(templates.empty), + header: templates.header && _.templatify(templates.header), + footer: templates.footer && _.templatify(templates.footer), + suggestion: templates.suggestion || suggestionTemplate + }; + function suggestionTemplate(context) { + return "

        " + displayFn(context) + "

        "; + } + } + function isValidName(str) { + return /^[_a-zA-Z0-9-]+$/.test(str); + } + }(); + var Dropdown = function() { + function Dropdown(o) { + var that = this, onSuggestionClick, onSuggestionMouseEnter, onSuggestionMouseLeave; + o = o || {}; + if (!o.menu) { + $.error("menu is required"); + } + this.isOpen = false; + this.isEmpty = true; + this.datasets = _.map(o.datasets, initializeDataset); + onSuggestionClick = _.bind(this._onSuggestionClick, this); + onSuggestionMouseEnter = _.bind(this._onSuggestionMouseEnter, this); + onSuggestionMouseLeave = _.bind(this._onSuggestionMouseLeave, this); + this.$menu = $(o.menu).on("click.tt", ".tt-suggestion", onSuggestionClick).on("mouseenter.tt", ".tt-suggestion", onSuggestionMouseEnter).on("mouseleave.tt", ".tt-suggestion", onSuggestionMouseLeave); + _.each(this.datasets, function(dataset) { + that.$menu.append(dataset.getRoot()); + dataset.onSync("rendered", that._onRendered, that); + }); + } + _.mixin(Dropdown.prototype, EventEmitter, { + _onSuggestionClick: function onSuggestionClick($e) { + this.trigger("suggestionClicked", $($e.currentTarget)); + }, + _onSuggestionMouseEnter: function onSuggestionMouseEnter($e) { + this._removeCursor(); + this._setCursor($($e.currentTarget), true); + }, + _onSuggestionMouseLeave: function onSuggestionMouseLeave() { + this._removeCursor(); + }, + _onRendered: function onRendered() { + this.isEmpty = _.every(this.datasets, isDatasetEmpty); + this.isEmpty ? this._hide() : this.isOpen && this._show(); + this.trigger("datasetRendered"); + function isDatasetEmpty(dataset) { + return dataset.isEmpty(); + } + }, + _hide: function() { + this.$menu.hide(); + }, + _show: function() { + this.$menu.css("display", "block"); + }, + _getSuggestions: function getSuggestions() { + return this.$menu.find(".tt-suggestion"); + }, + _getCursor: function getCursor() { + return this.$menu.find(".tt-cursor").first(); + }, + _setCursor: function setCursor($el, silent) { + $el.first().addClass("tt-cursor"); + !silent && this.trigger("cursorMoved"); + }, + _removeCursor: function removeCursor() { + this._getCursor().removeClass("tt-cursor"); + }, + _moveCursor: function moveCursor(increment) { + var $suggestions, $oldCursor, newCursorIndex, $newCursor; + if (!this.isOpen) { + return; + } + $oldCursor = this._getCursor(); + $suggestions = this._getSuggestions(); + this._removeCursor(); + newCursorIndex = $suggestions.index($oldCursor) + increment; + newCursorIndex = (newCursorIndex + 1) % ($suggestions.length + 1) - 1; + if (newCursorIndex === -1) { + this.trigger("cursorRemoved"); + return; + } else if (newCursorIndex < -1) { + newCursorIndex = $suggestions.length - 1; + } + this._setCursor($newCursor = $suggestions.eq(newCursorIndex)); + this._ensureVisible($newCursor); + }, + _ensureVisible: function ensureVisible($el) { + var elTop, elBottom, menuScrollTop, menuHeight; + elTop = $el.position().top; + elBottom = elTop + $el.outerHeight(true); + menuScrollTop = this.$menu.scrollTop(); + menuHeight = this.$menu.height() + parseInt(this.$menu.css("paddingTop"), 10) + parseInt(this.$menu.css("paddingBottom"), 10); + if (elTop < 0) { + this.$menu.scrollTop(menuScrollTop + elTop); + } else if (menuHeight < elBottom) { + this.$menu.scrollTop(menuScrollTop + (elBottom - menuHeight)); + } + }, + close: function close() { + if (this.isOpen) { + this.isOpen = false; + this._removeCursor(); + this._hide(); + this.trigger("closed"); + } + }, + open: function open() { + if (!this.isOpen) { + this.isOpen = true; + !this.isEmpty && this._show(); + this.trigger("opened"); + } + }, + setLanguageDirection: function setLanguageDirection(dir) { + this.$menu.css(dir === "ltr" ? css.ltr : css.rtl); + }, + moveCursorUp: function moveCursorUp() { + this._moveCursor(-1); + }, + moveCursorDown: function moveCursorDown() { + this._moveCursor(+1); + }, + getDatumForSuggestion: function getDatumForSuggestion($el) { + var datum = null; + if ($el.length) { + datum = { + raw: Dataset.extractDatum($el), + value: Dataset.extractValue($el), + datasetName: Dataset.extractDatasetName($el) + }; + } + return datum; + }, + getDatumForCursor: function getDatumForCursor() { + return this.getDatumForSuggestion(this._getCursor().first()); + }, + getDatumForTopSuggestion: function getDatumForTopSuggestion() { + return this.getDatumForSuggestion(this._getSuggestions().first()); + }, + update: function update(query) { + _.each(this.datasets, updateDataset); + function updateDataset(dataset) { + dataset.update(query); + } + }, + empty: function empty() { + _.each(this.datasets, clearDataset); + this.isEmpty = true; + function clearDataset(dataset) { + dataset.clear(); + } + }, + isVisible: function isVisible() { + return this.isOpen && !this.isEmpty; + }, + destroy: function destroy() { + this.$menu.off(".tt"); + this.$menu = null; + _.each(this.datasets, destroyDataset); + function destroyDataset(dataset) { + dataset.destroy(); + } + } + }); + return Dropdown; + function initializeDataset(oDataset) { + return new Dataset(oDataset); + } + }(); + var Typeahead = function() { + var attrsKey = "ttAttrs"; + function Typeahead(o) { + var $menu, $input, $hint; + o = o || {}; + if (!o.input) { + $.error("missing input"); + } + this.isActivated = false; + this.autoselect = !!o.autoselect; + this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; + this.$node = buildDomStructure(o.input, o.withHint); + $menu = this.$node.find(".tt-dropdown-menu"); + $input = this.$node.find(".tt-input"); + $hint = this.$node.find(".tt-hint"); + $input.on("blur.tt", function($e) { + var active, isActive, hasActive; + active = document.activeElement; + isActive = $menu.is(active); + hasActive = $menu.has(active).length > 0; + if (_.isMsie() && (isActive || hasActive)) { + $e.preventDefault(); + $e.stopImmediatePropagation(); + _.defer(function() { + $input.focus(); + }); + } + }); + $menu.on("mousedown.tt", function($e) { + $e.preventDefault(); + }); + this.eventBus = o.eventBus || new EventBus({ + el: $input + }); + this.dropdown = new Dropdown({ + menu: $menu, + datasets: o.datasets + }).onSync("suggestionClicked", this._onSuggestionClicked, this).onSync("cursorMoved", this._onCursorMoved, this).onSync("cursorRemoved", this._onCursorRemoved, this).onSync("opened", this._onOpened, this).onSync("closed", this._onClosed, this).onAsync("datasetRendered", this._onDatasetRendered, this); + this.input = new Input({ + input: $input, + hint: $hint + }).onSync("focused", this._onFocused, this).onSync("blurred", this._onBlurred, this).onSync("enterKeyed", this._onEnterKeyed, this).onSync("tabKeyed", this._onTabKeyed, this).onSync("escKeyed", this._onEscKeyed, this).onSync("upKeyed", this._onUpKeyed, this).onSync("downKeyed", this._onDownKeyed, this).onSync("leftKeyed", this._onLeftKeyed, this).onSync("rightKeyed", this._onRightKeyed, this).onSync("queryChanged", this._onQueryChanged, this).onSync("whitespaceChanged", this._onWhitespaceChanged, this); + this._setLanguageDirection(); + } + _.mixin(Typeahead.prototype, { + _onSuggestionClicked: function onSuggestionClicked(type, $el) { + var datum; + if (datum = this.dropdown.getDatumForSuggestion($el)) { + this._select(datum); + } + }, + _onCursorMoved: function onCursorMoved() { + var datum = this.dropdown.getDatumForCursor(); + this.input.setInputValue(datum.value, true); + this.eventBus.trigger("cursorchanged", datum.raw, datum.datasetName); + }, + _onCursorRemoved: function onCursorRemoved() { + this.input.resetInputValue(); + this._updateHint(); + }, + _onDatasetRendered: function onDatasetRendered() { + this._updateHint(); + }, + _onOpened: function onOpened() { + this._updateHint(); + this.eventBus.trigger("opened"); + }, + _onClosed: function onClosed() { + this.input.clearHint(); + this.eventBus.trigger("closed"); + }, + _onFocused: function onFocused() { + this.isActivated = true; + this.dropdown.open(); + }, + _onBlurred: function onBlurred() { + this.isActivated = false; + this.dropdown.empty(); + this.dropdown.close(); + this.setVal("", true); //LM + }, + _onEnterKeyed: function onEnterKeyed(type, $e) { + var cursorDatum, topSuggestionDatum; + cursorDatum = this.dropdown.getDatumForCursor(); + topSuggestionDatum = this.dropdown.getDatumForTopSuggestion(); + if (cursorDatum) { + this._select(cursorDatum); + $e.preventDefault(); + } else if (this.autoselect && topSuggestionDatum) { + this._select(topSuggestionDatum); + $e.preventDefault(); + } + }, + _onTabKeyed: function onTabKeyed(type, $e) { + var datum; + if (datum = this.dropdown.getDatumForCursor()) { + this._select(datum); + $e.preventDefault(); + } else { + this._autocomplete(true); + } + }, + _onEscKeyed: function onEscKeyed() { + this.dropdown.close(); + this.input.resetInputValue(); + }, + _onUpKeyed: function onUpKeyed() { + var query = this.input.getQuery(); + this.dropdown.isEmpty && query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.moveCursorUp(); + this.dropdown.open(); + }, + _onDownKeyed: function onDownKeyed() { + var query = this.input.getQuery(); + this.dropdown.isEmpty && query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.moveCursorDown(); + this.dropdown.open(); + }, + _onLeftKeyed: function onLeftKeyed() { + this.dir === "rtl" && this._autocomplete(); + }, + _onRightKeyed: function onRightKeyed() { + this.dir === "ltr" && this._autocomplete(); + }, + _onQueryChanged: function onQueryChanged(e, query) { + this.input.clearHintIfInvalid(); + query.length >= this.minLength ? this.dropdown.update(query) : this.dropdown.empty(); + this.dropdown.open(); + this._setLanguageDirection(); + }, + _onWhitespaceChanged: function onWhitespaceChanged() { + this._updateHint(); + this.dropdown.open(); + }, + _setLanguageDirection: function setLanguageDirection() { + var dir; + if (this.dir !== (dir = this.input.getLanguageDirection())) { + this.dir = dir; + this.$node.css("direction", dir); + this.dropdown.setLanguageDirection(dir); + } + }, + _updateHint: function updateHint() { + var datum, val, query, escapedQuery, frontMatchRegEx, match; + datum = this.dropdown.getDatumForTopSuggestion(); + if (datum && this.dropdown.isVisible() && !this.input.hasOverflow()) { + val = this.input.getInputValue(); + query = Input.normalizeQuery(val); + escapedQuery = _.escapeRegExChars(query); + frontMatchRegEx = new RegExp("^(?:" + escapedQuery + ")(.+$)", "i"); + match = frontMatchRegEx.exec(datum.value); + match ? this.input.setHint(val + match[1]) : this.input.clearHint(); + } else { + this.input.clearHint(); + } + }, + _autocomplete: function autocomplete(laxCursor) { + var hint, query, isCursorAtEnd, datum; + hint = this.input.getHint(); + query = this.input.getQuery(); + isCursorAtEnd = laxCursor || this.input.isCursorAtEnd(); + if (hint && query !== hint && isCursorAtEnd) { + datum = this.dropdown.getDatumForTopSuggestion(); + datum && this.input.setInputValue(datum.value); + this.eventBus.trigger("autocompleted", datum.raw, datum.datasetName); + } + }, + _select: function select(datum) { + this.input.setQuery(datum.value); + this.input.setInputValue(datum.value, true); + this._setLanguageDirection(); + this.eventBus.trigger("selected", datum.raw, datum.datasetName); + this.dropdown.close(); + _.defer(_.bind(this.dropdown.empty, this.dropdown)); + }, + open: function open() { + this.dropdown.open(); + }, + close: function close() { + this.dropdown.close(); + }, + setVal: function setVal(val) { + if (this.isActivated) { + this.input.setInputValue(val); + } else { + this.input.setQuery(val); + this.input.setInputValue(val, true); + } + this._setLanguageDirection(); + }, + getVal: function getVal() { + return this.input.getQuery(); + }, + destroy: function destroy() { + this.input.destroy(); + this.dropdown.destroy(); + destroyDomStructure(this.$node); + this.$node = null; + } + }); + return Typeahead; + function buildDomStructure(input, withHint) { + var $input, $wrapper, $dropdown, $hint; + $input = $(input); + $wrapper = $(html.wrapper).css(css.wrapper); + $dropdown = $(html.dropdown).css(css.dropdown); + $hint = $input.clone().css(css.hint).css(getBackgroundStyles($input)); + $hint.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder").prop("disabled", true).attr({ + autocomplete: "off", + spellcheck: "false" + }); + $input.data(attrsKey, { + dir: $input.attr("dir"), + autocomplete: $input.attr("autocomplete"), + spellcheck: $input.attr("spellcheck"), + style: $input.attr("style") + }); + $input.addClass("tt-input").attr({ + autocomplete: "off", + spellcheck: false + }).css(withHint ? css.input : css.inputWithNoHint); + try { + !$input.attr("dir") && $input.attr("dir", "auto"); + } catch (e) {} + return $input.wrap($wrapper).parent().prepend(withHint ? $hint : null).append($dropdown); + } + function getBackgroundStyles($el) { + return { + backgroundAttachment: $el.css("background-attachment"), + backgroundClip: $el.css("background-clip"), + backgroundColor: $el.css("background-color"), + backgroundImage: $el.css("background-image"), + backgroundOrigin: $el.css("background-origin"), + backgroundPosition: $el.css("background-position"), + backgroundRepeat: $el.css("background-repeat"), + backgroundSize: $el.css("background-size") + }; + } + function destroyDomStructure($node) { + var $input = $node.find(".tt-input"); + _.each($input.data(attrsKey), function(val, key) { + _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val); + }); + $input.detach().removeData(attrsKey).removeClass("tt-input").insertAfter($node); + $node.remove(); + } + }(); + (function() { + var old, typeaheadKey, methods; + old = $.fn.typeahead; + typeaheadKey = "ttTypeahead"; + methods = { + initialize: function initialize(o, datasets) { + datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1); + o = o || {}; + return this.each(attach); + function attach() { + var $input = $(this), eventBus, typeahead; + _.each(datasets, function(d) { + d.highlight = !!o.highlight; + }); + typeahead = new Typeahead({ + input: $input, + eventBus: eventBus = new EventBus({ + el: $input + }), + withHint: _.isUndefined(o.hint) ? true : !!o.hint, + minLength: o.minLength, + autoselect: o.autoselect, + datasets: datasets + }); + $input.data(typeaheadKey, typeahead); + } + }, + open: function open() { + return this.each(openTypeahead); + function openTypeahead() { + var $input = $(this), typeahead; + if (typeahead = $input.data(typeaheadKey)) { + typeahead.open(); + } + } + }, + close: function close() { + return this.each(closeTypeahead); + function closeTypeahead() { + var $input = $(this), typeahead; + if (typeahead = $input.data(typeaheadKey)) { + typeahead.close(); + } + } + }, + val: function val(newVal) { + return !arguments.length ? getVal(this.first()) : this.each(setVal); + function setVal() { + var $input = $(this), typeahead; + if (typeahead = $input.data(typeaheadKey)) { + typeahead.setVal(newVal); + } + } + function getVal($input) { + var typeahead, query; + if (typeahead = $input.data(typeaheadKey)) { + query = typeahead.getVal(); + } + return query; + } + }, + destroy: function destroy() { + return this.each(unattach); + function unattach() { + var $input = $(this), typeahead; + if (typeahead = $input.data(typeaheadKey)) { + typeahead.destroy(); + $input.removeData(typeaheadKey); + } + } + } + }; + $.fn.typeahead = function(method) { + if (methods[method]) { + return methods[method].apply(this, [].slice.call(arguments, 1)); + } else { + return methods.initialize.apply(this, arguments); + } + }; + $.fn.typeahead.noConflict = function noConflict() { + $.fn.typeahead = old; + return this; + }; + })(); + + + +//})(window.jQuery); + + +}); +define('searchView',[ + 'App', + // Templates + 'text!tpl/search.html', + 'text!tpl/search_suggestion.html', + // Tools + 'typeahead' +], function(App, searchTpl, suggestionTpl) { + + var searchView = Backbone.View.extend({ + el: '#search', + /** + * Init. + */ + init: function() { + var tpl = _.template(searchTpl); + var className = 'form-control input-lg'; + var placeholder = 'Search reference'; + this.searchHtml = tpl({ + 'placeholder': placeholder, + 'className': className + }); + this.items = App.classes.concat(App.allItems); + + return this; + }, + /** + * Render input field with Typehead activated. + */ + render: function() { + // Append the view to the dom + this.$el.append(this.searchHtml); + + // Render Typeahead + var $searchInput = this.$el.find('input[type=text]'); + this.typeaheadRender($searchInput); + this.typeaheadEvents($searchInput); + + return this; + }, + /** + * Apply Twitter Typeahead to the search input field. + * @param {jquery} $input + */ + typeaheadRender: function($input) { + var self = this; + $input.typeahead(null, { + 'displayKey': 'name', + 'minLength': 2, + //'highlight': true, + 'source': self.substringMatcher(this.items), + 'templates': { + 'empty': '

        Unable to find any item that match the current query

        ', + 'suggestion': _.template(suggestionTpl) + } + }); + }, + /** + * Setup typeahead custom events (item selected). + */ + typeaheadEvents: function($input) { + var self = this; + $input.on('typeahead:selected', function(e, item, datasetName) { + var selectedItem = self.items[item.idx]; + select(selectedItem); + }); + $input.on('keydown', function(e) { + if (e.which === 13) { // enter + var txt = $input.val(); + var f = _.find(self.items, function(it) { return it.name == txt; }); + if (f) { + select(f); + } + } else if (e.which === 27) { + $input.blur(); + } + }); + + function select(selectedItem) { + var hash = App.router.getHash(selectedItem);// + App.router.navigate(hash, {'trigger': true}); + $('#item').focus(); + } + }, + /** + * substringMatcher function for Typehead (search for strings in an array). + * @param {array} array + * @returns {Function} + */ + substringMatcher: function(array) { + return function findMatches(query, callback) { + var matches = [], substrRegex, arrayLength = array.length; + + // regex used to determine if a string contains the substring `query` + substrRegex = new RegExp(query, 'i'); + + // iterate through the pool of strings and for any string that + // contains the substring `query`, add it to the `matches` array + for (var i=0; i < arrayLength; i++) { + var item = array[i]; + if (substrRegex.test(item.name)) { + // typeahead expects suggestions to be a js object + matches.push({ + 'itemtype': item.itemtype, + 'name': item.name, + 'className': item.class, + 'is_constructor': !!item.is_constructor, + 'final': item.final, + 'idx': i + }); + } + } + + callback(matches); + }; + } + + }); + + return searchView; + +}); + + +define('text!tpl/list.html',[],function () { return '<% _.each(groups, function(group){ %>\r\n
        \r\n

        <%=group.name%>

        \r\n
        \r\n <% _.each(group.subgroups, function(subgroup, ind) { %>\r\n
        \r\n <% if (subgroup.name !== \'0\') { %>\r\n

        <%=subgroup.name%>

        \r\n <% } %>\r\n \r\n
        \r\n <% }); %>\r\n
        \r\n
        \r\n<% }); %>\r\n';}); + +define('listView',[ + 'App', + // Templates + 'text!tpl/list.html' +], function (App, listTpl) { + var striptags = function(html) { + var div = document.createElement('div'); + div.innerHTML = html; + return div.textContent; + }; + + var listView = Backbone.View.extend({ + el: '#list', + events: {}, + /** + * Init. + */ + init: function () { + this.listTpl = _.template(listTpl); + + return this; + }, + /** + * Render the list. + */ + render: function (items, listCollection) { + if (items && listCollection) { + var self = this; + + // Render items and group them by module + // module === group + this.groups = {}; + _.each(items, function (item, i) { + + if (!item.private && item.file.indexOf('addons') === -1) { //addons don't get displayed on main page + + var group = item.module || '_'; + var subgroup = item.submodule || '_'; + if (group === subgroup) { + subgroup = '0'; + } + var hash = App.router.getHash(item); + + // fixes broken links for #/p5/> and #/p5/>= + item.hash = item.hash.replace('>', '>'); + + // Create a group list + if (!self.groups[group]) { + self.groups[group] = { + name: group.replace('_', ' '), + subgroups: {} + }; + } + + // Create a subgroup list + if (!self.groups[group].subgroups[subgroup]) { + self.groups[group].subgroups[subgroup] = { + name: subgroup.replace('_', ' '), + items: [] + }; + } + + // hide the un-interesting constants + if (group === 'Constants' && !item.example) + return; + + if (item.class === 'p5') { + + self.groups[group].subgroups[subgroup].items.push(item); + + } else { + + var found = _.find(self.groups[group].subgroups[subgroup].items, + function(i){ return i.name == item.class; }); + + if (!found) { + + // FIX TO INVISIBLE OBJECTS: DH (see also router.js) + var ind = hash.lastIndexOf('/'); + hash = item.hash.substring(0, ind).replace('p5/','p5.'); + self.groups[group].subgroups[subgroup].items.push({ + name: item.class, + hash: hash + }); + } + + } + } + }); + + // Put the
      • items html into the list
          + var listHtml = self.listTpl({ + 'striptags': striptags, + 'title': self.capitalizeFirst(listCollection), + 'groups': self.groups, + 'listCollection': listCollection + }); + + // Render the view + this.$el.html(listHtml); + } + + var renderEvent = new Event('reference-rendered'); + window.dispatchEvent(renderEvent); + + return this; + }, + /** + * Show a list of items. + * @param {array} items Array of item objects. + * @returns {object} This view. + */ + show: function (listGroup) { + if (App[listGroup]) { + this.render(App[listGroup], listGroup); + } + App.pageView.hideContentViews(); + + this.$el.show(); + + return this; + }, + /** + * Helper method to capitalize the first letter of a string + * @param {string} str + * @returns {string} Returns the string. + */ + capitalizeFirst: function (str) { + return str.substr(0, 1).toUpperCase() + str.substr(1); + } + + + + }); + + return listView; + +}); + + +define('text!tpl/item.html',[],function () { return '

          <%=item.name%><% if (item.isMethod) { %>()<% } %>

          \r\n\r\n<% if (item.example) { %>\r\n
          \r\n

          Examples

          \r\n\r\n
          \r\n <% _.each(item.example, function(example, i){ %>\r\n <%= example %>\r\n <% }); %>\r\n
          \r\n
          \r\n<% } %>\r\n\r\n
          \r\n\r\n

          Description

          \r\n\r\n <% if (item.deprecated) { %>\r\n

          \r\n Deprecated: <%=item.name%><% if (item.isMethod) { %>()<% } %> is deprecated and will be removed in a future version of p5. <% if (item.deprecationMessage) { %><%=item.deprecationMessage%><% } %>\r\n

          \r\n <% } %>\r\n\r\n\r\n <%= item.description %>\r\n\r\n <% if (item.extends) { %>\r\n

          Extends <%=item.extends%>

          \r\n <% } %>\r\n\r\n <% if (item.module === \'p5.sound\') { %>\r\n

          This function requires you include the p5.sound library. Add the following into the head of your index.html file:\r\n

          <script src="path/to/p5.sound.js"></script>
          \r\n

          \r\n <% } %>\r\n\r\n <% if (item.constRefs) { %>\r\n

          Used by:\r\n <%\r\n var refs = item.constRefs;\r\n for (var i = 0; i < refs.length; i ++) {\r\n var ref = refs[i];\r\n var name = ref;\r\n if (name.substr(0, 3) === \'p5.\') {\r\n name = name.substr(3);\r\n }\r\n if (i !== 0) {\r\n if (i == refs.length - 1) {\r\n %> and <%\r\n } else {\r\n %>, <%\r\n }\r\n }\r\n %><%= name %>()<%\r\n }\r\n %>\r\n

          \r\n <% } %>\r\n
          \r\n\r\n<% if (isConstructor || !isClass) { %>\r\n\r\n
          \r\n

          Syntax

          \r\n

          \r\n <% syntaxes.forEach(function(syntax) { %>\r\n

          <%= syntax %>
          \r\n <% }) %>\r\n

          \r\n
          \r\n\r\n\r\n<% if (item.params) { %>\r\n
          \r\n

          Parameters

          \r\n
            \r\n <% for (var i=0; i\r\n <% var p = item.params[i] %>\r\n
          • \r\n
            <%=p.name%>
            \r\n <% if (p.type) { %>\r\n
            \r\n <% var type = p.type.replace(/(p5\\.[A-Z][A-Za-z]*)/, \'$1\'); %>\r\n <%=type%>: <%=p.description%>\r\n <% if (p.optional) { %> (Optional)<% } %>\r\n
            \r\n <% } %>\r\n
          • \r\n <% } %>\r\n
          \r\n
          \r\n<% } %>\r\n\r\n<% if (item.return && item.return.type) { %>\r\n
          \r\n

          Returns

          \r\n

          <%=item.return.type%>: <%= item.return.description %>

          \r\n
          \r\n<% } %>\r\n\r\n<% } %>\r\n';}); + + +define('text!tpl/class.html',[],function () { return '\r\n<% if (typeof constructor !== \'undefined\') { %>\r\n
          \r\n <%=constructor%>\r\n
          \r\n<% } %>\r\n\r\n<% let fields = _.filter(things, function(item) { return item.itemtype === \'property\' && item.access !== \'private\' }); %>\r\n<% if (fields.length > 0) { %>\r\n

          Fields

          \r\n \r\n<% } %>\r\n\r\n<% let methods = _.filter(things, function(item) { return item.itemtype === \'method\' && item.access !== \'private\' }); %>\r\n<% if (methods.length > 0) { %>\r\n

          Methods

          \r\n \r\n<% } %>\r\n';}); + + +define('text!tpl/itemEnd.html',[],function () { return '\r\n

          \r\n\r\n
          \r\n<% if (item.file && item.line) { %>\r\nNotice any errors or typos? Please let us know. Please feel free to edit <%= item.file %> and issue a pull request!\r\n<% } %>\r\n
          \r\n\r\ncreative commons logo\r\n

          \r\n';}); + +// Copyright (C) 2006 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * @fileoverview + * some functions for browser-side pretty printing of code contained in html. + * + *

          + * For a fairly comprehensive set of languages see the + * README + * file that came with this source. At a minimum, the lexer should work on a + * number of languages including C and friends, Java, Python, Bash, SQL, HTML, + * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk + * and a subset of Perl, but, because of commenting conventions, doesn't work on + * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. + *

          + * Usage:

            + *
          1. include this source file in an html page via + * {@code } + *
          2. define style rules. See the example page for examples. + *
          3. mark the {@code
            } and {@code } tags in your source with
            + *    {@code class=prettyprint.}
            + *    You can also use the (html deprecated) {@code } tag, but the pretty
            + *    printer needs to do more substantial DOM manipulations to support that, so
            + *    some css styles may not be preserved.
            + * </ol>
            + * That's it.  I wanted to keep the API as simple as possible, so there's no
            + * need to specify which language the code is in, but if you wish, you can add
            + * another class to the {@code <pre>} or {@code <code>} element to specify the
            + * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
            + * starts with "lang-" followed by a file extension, specifies the file type.
            + * See the "lang-*.js" files in this directory for code that implements
            + * per-language file handlers.
            + * <p>
            + * Change log:<br>
            + * cbeust, 2006/08/22
            + * <blockquote>
            + *   Java annotations (start with "@") are now captured as literals ("lit")
            + * </blockquote>
            + * @requires console
            + */
            +
            +// JSLint declarations
            +/*global console, document, navigator, setTimeout, window, define */
            +
            +/** @define {boolean} */
            +var IN_GLOBAL_SCOPE = true;
            +
            +/**
            + * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
            + * UI events.
            + * If set to {@code false}, {@code prettyPrint()} is synchronous.
            + */
            +window['PR_SHOULD_USE_CONTINUATION'] = true;
            +
            +/**
            + * Pretty print a chunk of code.
            + * @param {string} sourceCodeHtml The HTML to pretty print.
            + * @param {string} opt_langExtension The language name to use.
            + *     Typically, a filename extension like 'cpp' or 'java'.
            + * @param {number|boolean} opt_numberLines True to number lines,
            + *     or the 1-indexed number of the first line in sourceCodeHtml.
            + * @return {string} code as html, but prettier
            + */
            +var prettyPrintOne;
            +/**
            + * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
            + * {@code class=prettyprint} and prettify them.
            + *
            + * @param {Function} opt_whenDone called when prettifying is done.
            + * @param {HTMLElement|HTMLDocument} opt_root an element or document
            + *   containing all the elements to pretty print.
            + *   Defaults to {@code document.body}.
            + */
            +var prettyPrint;
            +
            +
            +(function () {
            +  var win = window;
            +  // Keyword lists for various languages.
            +  // We use things that coerce to strings to make them compact when minified
            +  // and to defeat aggressive optimizers that fold large string constants.
            +  var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
            +  var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," + 
            +      "double,enum,extern,float,goto,inline,int,long,register,short,signed," +
            +      "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
            +  var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
            +      "new,operator,private,protected,public,this,throw,true,try,typeof"];
            +  var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
            +      "concept,concept_map,const_cast,constexpr,decltype,delegate," +
            +      "dynamic_cast,explicit,export,friend,generic,late_check," +
            +      "mutable,namespace,nullptr,property,reinterpret_cast,static_assert," +
            +      "static_cast,template,typeid,typename,using,virtual,where"];
            +  var JAVA_KEYWORDS = [COMMON_KEYWORDS,
            +      "abstract,assert,boolean,byte,extends,final,finally,implements,import," +
            +      "instanceof,interface,null,native,package,strictfp,super,synchronized," +
            +      "throws,transient"];
            +  var CSHARP_KEYWORDS = [JAVA_KEYWORDS,
            +      "as,base,by,checked,decimal,delegate,descending,dynamic,event," +
            +      "fixed,foreach,from,group,implicit,in,internal,into,is,let," +
            +      "lock,object,out,override,orderby,params,partial,readonly,ref,sbyte," +
            +      "sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort," +
            +      "var,virtual,where"];
            +  var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
            +      "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
            +      "throw,true,try,unless,until,when,while,yes";
            +  var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
            +      "debugger,eval,export,function,get,null,set,undefined,var,with," +
            +      "Infinity,NaN"];
            +  var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
            +      "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
            +      "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
            +  var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
            +      "elif,except,exec,finally,from,global,import,in,is,lambda," +
            +      "nonlocal,not,or,pass,print,raise,try,with,yield," +
            +      "False,True,None"];
            +  var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
            +      "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
            +      "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
            +      "BEGIN,END"];
            +   var RUST_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "as,assert,const,copy,drop," +
            +      "enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv," +
            +      "pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"];
            +  var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
            +      "function,in,local,set,then,until"];
            +  var ALL_KEYWORDS = [
            +      CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS,
            +      PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
            +  var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
            +
            +  // token style names.  correspond to css classes
            +  /**
            +   * token style for a string literal
            +   * @const
            +   */
            +  var PR_STRING = 'str';
            +  /**
            +   * token style for a keyword
            +   * @const
            +   */
            +  var PR_KEYWORD = 'kwd';
            +  /**
            +   * token style for a comment
            +   * @const
            +   */
            +  var PR_COMMENT = 'com';
            +  /**
            +   * token style for a type
            +   * @const
            +   */
            +  var PR_TYPE = 'typ';
            +  /**
            +   * token style for a literal value.  e.g. 1, null, true.
            +   * @const
            +   */
            +  var PR_LITERAL = 'lit';
            +  /**
            +   * token style for a punctuation string.
            +   * @const
            +   */
            +  var PR_PUNCTUATION = 'pun';
            +  /**
            +   * token style for plain text.
            +   * @const
            +   */
            +  var PR_PLAIN = 'pln';
            +
            +  /**
            +   * token style for an sgml tag.
            +   * @const
            +   */
            +  var PR_TAG = 'tag';
            +  /**
            +   * token style for a markup declaration such as a DOCTYPE.
            +   * @const
            +   */
            +  var PR_DECLARATION = 'dec';
            +  /**
            +   * token style for embedded source.
            +   * @const
            +   */
            +  var PR_SOURCE = 'src';
            +  /**
            +   * token style for an sgml attribute name.
            +   * @const
            +   */
            +  var PR_ATTRIB_NAME = 'atn';
            +  /**
            +   * token style for an sgml attribute value.
            +   * @const
            +   */
            +  var PR_ATTRIB_VALUE = 'atv';
            +
            +  /**
            +   * A class that indicates a section of markup that is not code, e.g. to allow
            +   * embedding of line numbers within code listings.
            +   * @const
            +   */
            +  var PR_NOCODE = 'nocode';
            +
            +  
            +  
            +  /**
            +   * A set of tokens that can precede a regular expression literal in
            +   * javascript
            +   * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
            +   * has the full list, but I've removed ones that might be problematic when
            +   * seen in languages that don't support regular expression literals.
            +   *
            +   * <p>Specifically, I've removed any keywords that can't precede a regexp
            +   * literal in a syntactically legal javascript program, and I've removed the
            +   * "in" keyword since it's not a keyword in many languages, and might be used
            +   * as a count of inches.
            +   *
            +   * <p>The link above does not accurately describe EcmaScript rules since
            +   * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
            +   * very well in practice.
            +   *
            +   * @private
            +   * @const
            +   */
            +  var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
            +  
            +  // CAVEAT: this does not properly handle the case where a regular
            +  // expression immediately follows another since a regular expression may
            +  // have flags for case-sensitivity and the like.  Having regexp tokens
            +  // adjacent is not valid in any language I'm aware of, so I'm punting.
            +  // TODO: maybe style special characters inside a regexp as punctuation.
            +
            +  /**
            +   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
            +   * matches the union of the sets of strings matched by the input RegExp.
            +   * Since it matches globally, if the input strings have a start-of-input
            +   * anchor (/^.../), it is ignored for the purposes of unioning.
            +   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
            +   * @return {RegExp} a global regex.
            +   */
            +  function combinePrefixPatterns(regexs) {
            +    var capturedGroupIndex = 0;
            +  
            +    var needToFoldCase = false;
            +    var ignoreCase = false;
            +    for (var i = 0, n = regexs.length; i < n; ++i) {
            +      var regex = regexs[i];
            +      if (regex.ignoreCase) {
            +        ignoreCase = true;
            +      } else if (/[a-z]/i.test(regex.source.replace(
            +                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
            +        needToFoldCase = true;
            +        ignoreCase = false;
            +        break;
            +      }
            +    }
            +  
            +    var escapeCharToCodeUnit = {
            +      'b': 8,
            +      't': 9,
            +      'n': 0xa,
            +      'v': 0xb,
            +      'f': 0xc,
            +      'r': 0xd
            +    };
            +  
            +    function decodeEscape(charsetPart) {
            +      var cc0 = charsetPart.charCodeAt(0);
            +      if (cc0 !== 92 /* \\ */) {
            +        return cc0;
            +      }
            +      var c1 = charsetPart.charAt(1);
            +      cc0 = escapeCharToCodeUnit[c1];
            +      if (cc0) {
            +        return cc0;
            +      } else if ('0' <= c1 && c1 <= '7') {
            +        return parseInt(charsetPart.substring(1), 8);
            +      } else if (c1 === 'u' || c1 === 'x') {
            +        return parseInt(charsetPart.substring(2), 16);
            +      } else {
            +        return charsetPart.charCodeAt(1);
            +      }
            +    }
            +  
            +    function encodeEscape(charCode) {
            +      if (charCode < 0x20) {
            +        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
            +      }
            +      var ch = String.fromCharCode(charCode);
            +      return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
            +          ? "\\" + ch : ch;
            +    }
            +  
            +    function caseFoldCharset(charSet) {
            +      var charsetParts = charSet.substring(1, charSet.length - 1).match(
            +          new RegExp(
            +              '\\\\u[0-9A-Fa-f]{4}'
            +              + '|\\\\x[0-9A-Fa-f]{2}'
            +              + '|\\\\[0-3][0-7]{0,2}'
            +              + '|\\\\[0-7]{1,2}'
            +              + '|\\\\[\\s\\S]'
            +              + '|-'
            +              + '|[^-\\\\]',
            +              'g'));
            +      var ranges = [];
            +      var inverse = charsetParts[0] === '^';
            +  
            +      var out = ['['];
            +      if (inverse) { out.push('^'); }
            +  
            +      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
            +        var p = charsetParts[i];
            +        if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
            +          out.push(p);
            +        } else {
            +          var start = decodeEscape(p);
            +          var end;
            +          if (i + 2 < n && '-' === charsetParts[i + 1]) {
            +            end = decodeEscape(charsetParts[i + 2]);
            +            i += 2;
            +          } else {
            +            end = start;
            +          }
            +          ranges.push([start, end]);
            +          // If the range might intersect letters, then expand it.
            +          // This case handling is too simplistic.
            +          // It does not deal with non-latin case folding.
            +          // It works for latin source code identifiers though.
            +          if (!(end < 65 || start > 122)) {
            +            if (!(end < 65 || start > 90)) {
            +              ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
            +            }
            +            if (!(end < 97 || start > 122)) {
            +              ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
            +            }
            +          }
            +        }
            +      }
            +  
            +      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
            +      // -> [[1, 12], [14, 14], [16, 17]]
            +      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
            +      var consolidatedRanges = [];
            +      var lastRange = [];
            +      for (var i = 0; i < ranges.length; ++i) {
            +        var range = ranges[i];
            +        if (range[0] <= lastRange[1] + 1) {
            +          lastRange[1] = Math.max(lastRange[1], range[1]);
            +        } else {
            +          consolidatedRanges.push(lastRange = range);
            +        }
            +      }
            +  
            +      for (var i = 0; i < consolidatedRanges.length; ++i) {
            +        var range = consolidatedRanges[i];
            +        out.push(encodeEscape(range[0]));
            +        if (range[1] > range[0]) {
            +          if (range[1] + 1 > range[0]) { out.push('-'); }
            +          out.push(encodeEscape(range[1]));
            +        }
            +      }
            +      out.push(']');
            +      return out.join('');
            +    }
            +  
            +    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
            +      // Split into character sets, escape sequences, punctuation strings
            +      // like ('(', '(?:', ')', '^'), and runs of characters that do not
            +      // include any of the above.
            +      var parts = regex.source.match(
            +          new RegExp(
            +              '(?:'
            +              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
            +              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
            +              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
            +              + '|\\\\[0-9]+'  // a back-reference or octal escape
            +              + '|\\\\[^ux0-9]'  // other escape sequence
            +              + '|\\(\\?[:!=]'  // start of a non-capturing group
            +              + '|[\\(\\)\\^]'  // start/end of a group, or line start
            +              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
            +              + ')',
            +              'g'));
            +      var n = parts.length;
            +  
            +      // Maps captured group numbers to the number they will occupy in
            +      // the output or to -1 if that has not been determined, or to
            +      // undefined if they need not be capturing in the output.
            +      var capturedGroups = [];
            +  
            +      // Walk over and identify back references to build the capturedGroups
            +      // mapping.
            +      for (var i = 0, groupIndex = 0; i < n; ++i) {
            +        var p = parts[i];
            +        if (p === '(') {
            +          // groups are 1-indexed, so max group index is count of '('
            +          ++groupIndex;
            +        } else if ('\\' === p.charAt(0)) {
            +          var decimalValue = +p.substring(1);
            +          if (decimalValue) {
            +            if (decimalValue <= groupIndex) {
            +              capturedGroups[decimalValue] = -1;
            +            } else {
            +              // Replace with an unambiguous escape sequence so that
            +              // an octal escape sequence does not turn into a backreference
            +              // to a capturing group from an earlier regex.
            +              parts[i] = encodeEscape(decimalValue);
            +            }
            +          }
            +        }
            +      }
            +  
            +      // Renumber groups and reduce capturing groups to non-capturing groups
            +      // where possible.
            +      for (var i = 1; i < capturedGroups.length; ++i) {
            +        if (-1 === capturedGroups[i]) {
            +          capturedGroups[i] = ++capturedGroupIndex;
            +        }
            +      }
            +      for (var i = 0, groupIndex = 0; i < n; ++i) {
            +        var p = parts[i];
            +        if (p === '(') {
            +          ++groupIndex;
            +          if (!capturedGroups[groupIndex]) {
            +            parts[i] = '(?:';
            +          }
            +        } else if ('\\' === p.charAt(0)) {
            +          var decimalValue = +p.substring(1);
            +          if (decimalValue && decimalValue <= groupIndex) {
            +            parts[i] = '\\' + capturedGroups[decimalValue];
            +          }
            +        }
            +      }
            +  
            +      // Remove any prefix anchors so that the output will match anywhere.
            +      // ^^ really does mean an anchored match though.
            +      for (var i = 0; i < n; ++i) {
            +        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
            +      }
            +  
            +      // Expand letters to groups to handle mixing of case-sensitive and
            +      // case-insensitive patterns if necessary.
            +      if (regex.ignoreCase && needToFoldCase) {
            +        for (var i = 0; i < n; ++i) {
            +          var p = parts[i];
            +          var ch0 = p.charAt(0);
            +          if (p.length >= 2 && ch0 === '[') {
            +            parts[i] = caseFoldCharset(p);
            +          } else if (ch0 !== '\\') {
            +            // TODO: handle letters in numeric escapes.
            +            parts[i] = p.replace(
            +                /[a-zA-Z]/g,
            +                function (ch) {
            +                  var cc = ch.charCodeAt(0);
            +                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
            +                });
            +          }
            +        }
            +      }
            +  
            +      return parts.join('');
            +    }
            +  
            +    var rewritten = [];
            +    for (var i = 0, n = regexs.length; i < n; ++i) {
            +      var regex = regexs[i];
            +      if (regex.global || regex.multiline) { throw new Error('' + regex); }
            +      rewritten.push(
            +          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
            +    }
            +  
            +    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
            +  }
            +
            +  /**
            +   * Split markup into a string of source code and an array mapping ranges in
            +   * that string to the text nodes in which they appear.
            +   *
            +   * <p>
            +   * The HTML DOM structure:</p>
            +   * <pre>
            +   * (Element   "p"
            +   *   (Element "b"
            +   *     (Text  "print "))       ; #1
            +   *   (Text    "'Hello '")      ; #2
            +   *   (Element "br")            ; #3
            +   *   (Text    "  + 'World';")) ; #4
            +   * </pre>
            +   * <p>
            +   * corresponds to the HTML
            +   * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
            +   *
            +   * <p>
            +   * It will produce the output:</p>
            +   * <pre>
            +   * {
            +   *   sourceCode: "print 'Hello '\n  + 'World';",
            +   *   //                     1          2
            +   *   //           012345678901234 5678901234567
            +   *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
            +   * }
            +   * </pre>
            +   * <p>
            +   * where #1 is a reference to the {@code "print "} text node above, and so
            +   * on for the other text nodes.
            +   * </p>
            +   *
            +   * <p>
            +   * The {@code} spans array is an array of pairs.  Even elements are the start
            +   * indices of substrings, and odd elements are the text nodes (or BR elements)
            +   * that contain the text for those substrings.
            +   * Substrings continue until the next index or the end of the source.
            +   * </p>
            +   *
            +   * @param {Node} node an HTML DOM subtree containing source-code.
            +   * @param {boolean} isPreformatted true if white-space in text nodes should
            +   *    be considered significant.
            +   * @return {Object} source code and the text nodes in which they occur.
            +   */
            +  function extractSourceSpans(node, isPreformatted) {
            +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
            +  
            +    var chunks = [];
            +    var length = 0;
            +    var spans = [];
            +    var k = 0;
            +  
            +    function walk(node) {
            +      var type = node.nodeType;
            +      if (type == 1) {  // Element
            +        if (nocode.test(node.className)) { return; }
            +        for (var child = node.firstChild; child; child = child.nextSibling) {
            +          walk(child);
            +        }
            +        var nodeName = node.nodeName.toLowerCase();
            +        if ('br' === nodeName || 'li' === nodeName) {
            +          chunks[k] = '\n';
            +          spans[k << 1] = length++;
            +          spans[(k++ << 1) | 1] = node;
            +        }
            +      } else if (type == 3 || type == 4) {  // Text
            +        var text = node.nodeValue;
            +        if (text.length) {
            +          if (!isPreformatted) {
            +            text = text.replace(/[ \t\r\n]+/g, ' ');
            +          } else {
            +            text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
            +          }
            +          // TODO: handle tabs here?
            +          chunks[k] = text;
            +          spans[k << 1] = length;
            +          length += text.length;
            +          spans[(k++ << 1) | 1] = node;
            +        }
            +      }
            +    }
            +  
            +    walk(node);
            +  
            +    return {
            +      sourceCode: chunks.join('').replace(/\n$/, ''),
            +      spans: spans
            +    };
            +  }
            +
            +  /**
            +   * Apply the given language handler to sourceCode and add the resulting
            +   * decorations to out.
            +   * @param {number} basePos the index of sourceCode within the chunk of source
            +   *    whose decorations are already present on out.
            +   */
            +  function appendDecorations(basePos, sourceCode, langHandler, out) {
            +    if (!sourceCode) { return; }
            +    var job = {
            +      sourceCode: sourceCode,
            +      basePos: basePos
            +    };
            +    langHandler(job);
            +    out.push.apply(out, job.decorations);
            +  }
            +
            +  var notWs = /\S/;
            +
            +  /**
            +   * Given an element, if it contains only one child element and any text nodes
            +   * it contains contain only space characters, return the sole child element.
            +   * Otherwise returns undefined.
            +   * <p>
            +   * This is meant to return the CODE element in {@code <pre><code ...>} when
            +   * there is a single child element that contains all the non-space textual
            +   * content, but not to return anything where there are multiple child elements
            +   * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
            +   * is textual content.
            +   */
            +  function childContentWrapper(element) {
            +    var wrapper = undefined;
            +    for (var c = element.firstChild; c; c = c.nextSibling) {
            +      var type = c.nodeType;
            +      wrapper = (type === 1)  // Element Node
            +          ? (wrapper ? element : c)
            +          : (type === 3)  // Text Node
            +          ? (notWs.test(c.nodeValue) ? element : wrapper)
            +          : wrapper;
            +    }
            +    return wrapper === element ? undefined : wrapper;
            +  }
            +
            +  /** Given triples of [style, pattern, context] returns a lexing function,
            +    * The lexing function interprets the patterns to find token boundaries and
            +    * returns a decoration list of the form
            +    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
            +    * where index_n is an index into the sourceCode, and style_n is a style
            +    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
            +    * all characters in sourceCode[index_n-1:index_n].
            +    *
            +    * The stylePatterns is a list whose elements have the form
            +    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
            +    *
            +    * Style is a style constant like PR_PLAIN, or can be a string of the
            +    * form 'lang-FOO', where FOO is a language extension describing the
            +    * language of the portion of the token in $1 after pattern executes.
            +    * E.g., if style is 'lang-lisp', and group 1 contains the text
            +    * '(hello (world))', then that portion of the token will be passed to the
            +    * registered lisp handler for formatting.
            +    * The text before and after group 1 will be restyled using this decorator
            +    * so decorators should take care that this doesn't result in infinite
            +    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
            +    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
            +    * '<script>foo()<\/script>', which would cause the current decorator to
            +    * be called with '<script>' which would not match the same rule since
            +    * group 1 must not be empty, so it would be instead styled as PR_TAG by
            +    * the generic tag rule.  The handler registered for the 'js' extension would
            +    * then be called with 'foo()', and finally, the current decorator would
            +    * be called with '<\/script>' which would not match the original rule and
            +    * so the generic tag rule would identify it as a tag.
            +    *
            +    * Pattern must only match prefixes, and if it matches a prefix, then that
            +    * match is considered a token with the same style.
            +    *
            +    * Context is applied to the last non-whitespace, non-comment token
            +    * recognized.
            +    *
            +    * Shortcut is an optional string of characters, any of which, if the first
            +    * character, gurantee that this pattern and only this pattern matches.
            +    *
            +    * @param {Array} shortcutStylePatterns patterns that always start with
            +    *   a known character.  Must have a shortcut string.
            +    * @param {Array} fallthroughStylePatterns patterns that will be tried in
            +    *   order if the shortcut ones fail.  May have shortcuts.
            +    *
            +    * @return {function (Object)} a
            +    *   function that takes source code and returns a list of decorations.
            +    */
            +  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
            +    var shortcuts = {};
            +    var tokenizer;
            +    (function () {
            +      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
            +      var allRegexs = [];
            +      var regexKeys = {};
            +      for (var i = 0, n = allPatterns.length; i < n; ++i) {
            +        var patternParts = allPatterns[i];
            +        var shortcutChars = patternParts[3];
            +        if (shortcutChars) {
            +          for (var c = shortcutChars.length; --c >= 0;) {
            +            shortcuts[shortcutChars.charAt(c)] = patternParts;
            +          }
            +        }
            +        var regex = patternParts[1];
            +        var k = '' + regex;
            +        if (!regexKeys.hasOwnProperty(k)) {
            +          allRegexs.push(regex);
            +          regexKeys[k] = null;
            +        }
            +      }
            +      allRegexs.push(/[\0-\uffff]/);
            +      tokenizer = combinePrefixPatterns(allRegexs);
            +    })();
            +
            +    var nPatterns = fallthroughStylePatterns.length;
            +
            +    /**
            +     * Lexes job.sourceCode and produces an output array job.decorations of
            +     * style classes preceded by the position at which they start in
            +     * job.sourceCode in order.
            +     *
            +     * @param {Object} job an object like <pre>{
            +     *    sourceCode: {string} sourceText plain text,
            +     *    basePos: {int} position of job.sourceCode in the larger chunk of
            +     *        sourceCode.
            +     * }</pre>
            +     */
            +    var decorate = function (job) {
            +      var sourceCode = job.sourceCode, basePos = job.basePos;
            +      /** Even entries are positions in source in ascending order.  Odd enties
            +        * are style markers (e.g., PR_COMMENT) that run from that position until
            +        * the end.
            +        * @type {Array.<number|string>}
            +        */
            +      var decorations = [basePos, PR_PLAIN];
            +      var pos = 0;  // index into sourceCode
            +      var tokens = sourceCode.match(tokenizer) || [];
            +      var styleCache = {};
            +
            +      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
            +        var token = tokens[ti];
            +        var style = styleCache[token];
            +        var match = void 0;
            +
            +        var isEmbedded;
            +        if (typeof style === 'string') {
            +          isEmbedded = false;
            +        } else {
            +          var patternParts = shortcuts[token.charAt(0)];
            +          if (patternParts) {
            +            match = token.match(patternParts[1]);
            +            style = patternParts[0];
            +          } else {
            +            for (var i = 0; i < nPatterns; ++i) {
            +              patternParts = fallthroughStylePatterns[i];
            +              match = token.match(patternParts[1]);
            +              if (match) {
            +                style = patternParts[0];
            +                break;
            +              }
            +            }
            +
            +            if (!match) {  // make sure that we make progress
            +              style = PR_PLAIN;
            +            }
            +          }
            +
            +          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
            +          if (isEmbedded && !(match && typeof match[1] === 'string')) {
            +            isEmbedded = false;
            +            style = PR_SOURCE;
            +          }
            +
            +          if (!isEmbedded) { styleCache[token] = style; }
            +        }
            +
            +        var tokenStart = pos;
            +        pos += token.length;
            +
            +        if (!isEmbedded) {
            +          decorations.push(basePos + tokenStart, style);
            +        } else {  // Treat group 1 as an embedded block of source code.
            +          var embeddedSource = match[1];
            +          var embeddedSourceStart = token.indexOf(embeddedSource);
            +          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
            +          if (match[2]) {
            +            // If embeddedSource can be blank, then it would match at the
            +            // beginning which would cause us to infinitely recurse on the
            +            // entire token, so we catch the right context in match[2].
            +            embeddedSourceEnd = token.length - match[2].length;
            +            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
            +          }
            +          var lang = style.substring(5);
            +          // Decorate the left of the embedded source
            +          appendDecorations(
            +              basePos + tokenStart,
            +              token.substring(0, embeddedSourceStart),
            +              decorate, decorations);
            +          // Decorate the embedded source
            +          appendDecorations(
            +              basePos + tokenStart + embeddedSourceStart,
            +              embeddedSource,
            +              langHandlerForExtension(lang, embeddedSource),
            +              decorations);
            +          // Decorate the right of the embedded section
            +          appendDecorations(
            +              basePos + tokenStart + embeddedSourceEnd,
            +              token.substring(embeddedSourceEnd),
            +              decorate, decorations);
            +        }
            +      }
            +      job.decorations = decorations;
            +    };
            +    return decorate;
            +  }
            +
            +  /** returns a function that produces a list of decorations from source text.
            +    *
            +    * This code treats ", ', and ` as string delimiters, and \ as a string
            +    * escape.  It does not recognize perl's qq() style strings.
            +    * It has no special handling for double delimiter escapes as in basic, or
            +    * the tripled delimiters used in python, but should work on those regardless
            +    * although in those cases a single string literal may be broken up into
            +    * multiple adjacent string literals.
            +    *
            +    * It recognizes C, C++, and shell style comments.
            +    *
            +    * @param {Object} options a set of optional parameters.
            +    * @return {function (Object)} a function that examines the source code
            +    *     in the input job and builds the decoration list.
            +    */
            +  function sourceDecorator(options) {
            +    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
            +    if (options['tripleQuotedStrings']) {
            +      // '''multi-line-string''', 'single-line-string', and double-quoted
            +      shortcutStylePatterns.push(
            +          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
            +           null, '\'"']);
            +    } else if (options['multiLineStrings']) {
            +      // 'multi-line-string', "multi-line-string"
            +      shortcutStylePatterns.push(
            +          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
            +           null, '\'"`']);
            +    } else {
            +      // 'single-line-string', "single-line-string"
            +      shortcutStylePatterns.push(
            +          [PR_STRING,
            +           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
            +           null, '"\'']);
            +    }
            +    if (options['verbatimStrings']) {
            +      // verbatim-string-literal production from the C# grammar.  See issue 93.
            +      fallthroughStylePatterns.push(
            +          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
            +    }
            +    var hc = options['hashComments'];
            +    if (hc) {
            +      if (options['cStyleComments']) {
            +        if (hc > 1) {  // multiline hash comments
            +          shortcutStylePatterns.push(
            +              [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
            +        } else {
            +          // Stop C preprocessor declarations at an unclosed open comment
            +          shortcutStylePatterns.push(
            +              [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
            +               null, '#']);
            +        }
            +        // #include <stdio.h>
            +        fallthroughStylePatterns.push(
            +            [PR_STRING,
            +             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
            +             null]);
            +      } else {
            +        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
            +      }
            +    }
            +    if (options['cStyleComments']) {
            +      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
            +      fallthroughStylePatterns.push(
            +          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
            +    }
            +    var regexLiterals = options['regexLiterals'];
            +    if (regexLiterals) {
            +      /**
            +       * @const
            +       */
            +      var regexExcls = regexLiterals > 1
            +        ? ''  // Multiline regex literals
            +        : '\n\r';
            +      /**
            +       * @const
            +       */
            +      var regexAny = regexExcls ? '.' : '[\\S\\s]';
            +      /**
            +       * @const
            +       */
            +      var REGEX_LITERAL = (
            +          // A regular expression literal starts with a slash that is
            +          // not followed by * or / so that it is not confused with
            +          // comments.
            +          '/(?=[^/*' + regexExcls + '])'
            +          // and then contains any number of raw characters,
            +          + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
            +          // escape sequences (\x5C),
            +          +    '|\\x5C' + regexAny
            +          // or non-nesting character sets (\x5B\x5D);
            +          +    '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
            +          +             '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
            +          // finally closed by a /.
            +          + '/');
            +      fallthroughStylePatterns.push(
            +          ['lang-regex',
            +           RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
            +           ]);
            +    }
            +
            +    var types = options['types'];
            +    if (types) {
            +      fallthroughStylePatterns.push([PR_TYPE, types]);
            +    }
            +
            +    var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
            +    if (keywords.length) {
            +      fallthroughStylePatterns.push(
            +          [PR_KEYWORD,
            +           new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
            +           null]);
            +    }
            +
            +    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
            +
            +    var punctuation =
            +      // The Bash man page says
            +
            +      // A word is a sequence of characters considered as a single
            +      // unit by GRUB. Words are separated by metacharacters,
            +      // which are the following plus space, tab, and newline: { }
            +      // | & $ ; < >
            +      // ...
            +      
            +      // A word beginning with # causes that word and all remaining
            +      // characters on that line to be ignored.
            +
            +      // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
            +      // comment but empirically
            +      // $ echo {#}
            +      // {#}
            +      // $ echo \$#
            +      // $#
            +      // $ echo }#
            +      // }#
            +
            +      // so /(?:^|[|&;<>\s])/ is more appropriate.
            +
            +      // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
            +      // suggests that this definition is compatible with a
            +      // default mode that tries to use a single token definition
            +      // to recognize both bash/python style comments and C
            +      // preprocessor directives.
            +
            +      // This definition of punctuation does not include # in the list of
            +      // follow-on exclusions, so # will not be broken before if preceeded
            +      // by a punctuation character.  We could try to exclude # after
            +      // [|&;<>] but that doesn't seem to cause many major problems.
            +      // If that does turn out to be a problem, we should change the below
            +      // when hc is truthy to include # in the run of punctuation characters
            +      // only when not followint [|&;<>].
            +      '^.[^\\s\\w.$@\'"`/\\\\]*';
            +    if (options['regexLiterals']) {
            +      punctuation += '(?!\s*\/)';
            +    }
            +
            +    fallthroughStylePatterns.push(
            +        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
            +        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
            +        [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
            +        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
            +        [PR_LITERAL,
            +         new RegExp(
            +             '^(?:'
            +             // A hex number
            +             + '0x[a-f0-9]+'
            +             // or an octal or decimal number,
            +             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
            +             // possibly in scientific notation
            +             + '(?:e[+\\-]?\\d+)?'
            +             + ')'
            +             // with an optional modifier like UL for unsigned long
            +             + '[a-z]*', 'i'),
            +         null, '0123456789'],
            +        // Don't treat escaped quotes in bash as starting strings.
            +        // See issue 144.
            +        [PR_PLAIN,       /^\\[\s\S]?/, null],
            +        [PR_PUNCTUATION, new RegExp(punctuation), null]);
            +
            +    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
            +  }
            +
            +  var decorateSource = sourceDecorator({
            +        'keywords': ALL_KEYWORDS,
            +        'hashComments': true,
            +        'cStyleComments': true,
            +        'multiLineStrings': true,
            +        'regexLiterals': true
            +      });
            +
            +  /**
            +   * Given a DOM subtree, wraps it in a list, and puts each line into its own
            +   * list item.
            +   *
            +   * @param {Node} node modified in place.  Its content is pulled into an
            +   *     HTMLOListElement, and each line is moved into a separate list item.
            +   *     This requires cloning elements, so the input might not have unique
            +   *     IDs after numbering.
            +   * @param {boolean} isPreformatted true iff white-space in text nodes should
            +   *     be treated as significant.
            +   */
            +  function numberLines(node, opt_startLineNum, isPreformatted) {
            +    var nocode = /(?:^|\s)nocode(?:\s|$)/;
            +    var lineBreak = /\r\n?|\n/;
            +  
            +    var document = node.ownerDocument;
            +  
            +    var li = document.createElement('li');
            +    while (node.firstChild) {
            +      li.appendChild(node.firstChild);
            +    }
            +    // An array of lines.  We split below, so this is initialized to one
            +    // un-split line.
            +    var listItems = [li];
            +  
            +    function walk(node) {
            +      var type = node.nodeType;
            +      if (type == 1 && !nocode.test(node.className)) {  // Element
            +        if ('br' === node.nodeName) {
            +          breakAfter(node);
            +          // Discard the <BR> since it is now flush against a </LI>.
            +          if (node.parentNode) {
            +            node.parentNode.removeChild(node);
            +          }
            +        } else {
            +          for (var child = node.firstChild; child; child = child.nextSibling) {
            +            walk(child);
            +          }
            +        }
            +      } else if ((type == 3 || type == 4) && isPreformatted) {  // Text
            +        var text = node.nodeValue;
            +        var match = text.match(lineBreak);
            +        if (match) {
            +          var firstLine = text.substring(0, match.index);
            +          node.nodeValue = firstLine;
            +          var tail = text.substring(match.index + match[0].length);
            +          if (tail) {
            +            var parent = node.parentNode;
            +            parent.insertBefore(
            +              document.createTextNode(tail), node.nextSibling);
            +          }
            +          breakAfter(node);
            +          if (!firstLine) {
            +            // Don't leave blank text nodes in the DOM.
            +            node.parentNode.removeChild(node);
            +          }
            +        }
            +      }
            +    }
            +  
            +    // Split a line after the given node.
            +    function breakAfter(lineEndNode) {
            +      // If there's nothing to the right, then we can skip ending the line
            +      // here, and move root-wards since splitting just before an end-tag
            +      // would require us to create a bunch of empty copies.
            +      while (!lineEndNode.nextSibling) {
            +        lineEndNode = lineEndNode.parentNode;
            +        if (!lineEndNode) { return; }
            +      }
            +  
            +      function breakLeftOf(limit, copy) {
            +        // Clone shallowly if this node needs to be on both sides of the break.
            +        var rightSide = copy ? limit.cloneNode(false) : limit;
            +        var parent = limit.parentNode;
            +        if (parent) {
            +          // We clone the parent chain.
            +          // This helps us resurrect important styling elements that cross lines.
            +          // E.g. in <i>Foo<br>Bar</i>
            +          // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
            +          var parentClone = breakLeftOf(parent, 1);
            +          // Move the clone and everything to the right of the original
            +          // onto the cloned parent.
            +          var next = limit.nextSibling;
            +          parentClone.appendChild(rightSide);
            +          for (var sibling = next; sibling; sibling = next) {
            +            next = sibling.nextSibling;
            +            parentClone.appendChild(sibling);
            +          }
            +        }
            +        return rightSide;
            +      }
            +  
            +      var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
            +  
            +      // Walk the parent chain until we reach an unattached LI.
            +      for (var parent;
            +           // Check nodeType since IE invents document fragments.
            +           (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
            +        copiedListItem = parent;
            +      }
            +      // Put it on the list of lines for later processing.
            +      listItems.push(copiedListItem);
            +    }
            +  
            +    // Split lines while there are lines left to split.
            +    for (var i = 0;  // Number of lines that have been split so far.
            +         i < listItems.length;  // length updated by breakAfter calls.
            +         ++i) {
            +      walk(listItems[i]);
            +    }
            +  
            +    // Make sure numeric indices show correctly.
            +    if (opt_startLineNum === (opt_startLineNum|0)) {
            +      listItems[0].setAttribute('value', opt_startLineNum);
            +    }
            +  
            +    var ol = document.createElement('ol');
            +    ol.className = 'linenums';
            +    var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
            +    for (var i = 0, n = listItems.length; i < n; ++i) {
            +      li = listItems[i];
            +      // Stick a class on the LIs so that stylesheets can
            +      // color odd/even rows, or any other row pattern that
            +      // is co-prime with 10.
            +      li.className = 'L' + ((i + offset) % 10);
            +      if (!li.firstChild) {
            +        li.appendChild(document.createTextNode('\xA0'));
            +      }
            +      ol.appendChild(li);
            +    }
            +  
            +    node.appendChild(ol);
            +  }
            +  /**
            +   * Breaks {@code job.sourceCode} around style boundaries in
            +   * {@code job.decorations} and modifies {@code job.sourceNode} in place.
            +   * @param {Object} job like <pre>{
            +   *    sourceCode: {string} source as plain text,
            +   *    sourceNode: {HTMLElement} the element containing the source,
            +   *    spans: {Array.<number|Node>} alternating span start indices into source
            +   *       and the text node or element (e.g. {@code <BR>}) corresponding to that
            +   *       span.
            +   *    decorations: {Array.<number|string} an array of style classes preceded
            +   *       by the position at which they start in job.sourceCode in order
            +   * }</pre>
            +   * @private
            +   */
            +  function recombineTagsAndDecorations(job) {
            +    var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
            +    isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
            +    var newlineRe = /\n/g;
            +  
            +    var source = job.sourceCode;
            +    var sourceLength = source.length;
            +    // Index into source after the last code-unit recombined.
            +    var sourceIndex = 0;
            +  
            +    var spans = job.spans;
            +    var nSpans = spans.length;
            +    // Index into spans after the last span which ends at or before sourceIndex.
            +    var spanIndex = 0;
            +  
            +    var decorations = job.decorations;
            +    var nDecorations = decorations.length;
            +    // Index into decorations after the last decoration which ends at or before
            +    // sourceIndex.
            +    var decorationIndex = 0;
            +  
            +    // Remove all zero-length decorations.
            +    decorations[nDecorations] = sourceLength;
            +    var decPos, i;
            +    for (i = decPos = 0; i < nDecorations;) {
            +      if (decorations[i] !== decorations[i + 2]) {
            +        decorations[decPos++] = decorations[i++];
            +        decorations[decPos++] = decorations[i++];
            +      } else {
            +        i += 2;
            +      }
            +    }
            +    nDecorations = decPos;
            +  
            +    // Simplify decorations.
            +    for (i = decPos = 0; i < nDecorations;) {
            +      var startPos = decorations[i];
            +      // Conflate all adjacent decorations that use the same style.
            +      var startDec = decorations[i + 1];
            +      var end = i + 2;
            +      while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
            +        end += 2;
            +      }
            +      decorations[decPos++] = startPos;
            +      decorations[decPos++] = startDec;
            +      i = end;
            +    }
            +  
            +    nDecorations = decorations.length = decPos;
            +  
            +    var sourceNode = job.sourceNode;
            +    var oldDisplay;
            +    if (sourceNode) {
            +      oldDisplay = sourceNode.style.display;
            +      sourceNode.style.display = 'none';
            +    }
            +    try {
            +      var decoration = null;
            +      while (spanIndex < nSpans) {
            +        var spanStart = spans[spanIndex];
            +        var spanEnd = spans[spanIndex + 2] || sourceLength;
            +  
            +        var decEnd = decorations[decorationIndex + 2] || sourceLength;
            +  
            +        var end = Math.min(spanEnd, decEnd);
            +  
            +        var textNode = spans[spanIndex + 1];
            +        var styledText;
            +        if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
            +            // Don't introduce spans around empty text nodes.
            +            && (styledText = source.substring(sourceIndex, end))) {
            +          // This may seem bizarre, and it is.  Emitting LF on IE causes the
            +          // code to display with spaces instead of line breaks.
            +          // Emitting Windows standard issue linebreaks (CRLF) causes a blank
            +          // space to appear at the beginning of every line but the first.
            +          // Emitting an old Mac OS 9 line separator makes everything spiffy.
            +          if (isIE8OrEarlier) {
            +            styledText = styledText.replace(newlineRe, '\r');
            +          }
            +          textNode.nodeValue = styledText;
            +          var document = textNode.ownerDocument;
            +          var span = document.createElement('span');
            +          span.className = decorations[decorationIndex + 1];
            +          var parentNode = textNode.parentNode;
            +          parentNode.replaceChild(span, textNode);
            +          span.appendChild(textNode);
            +          if (sourceIndex < spanEnd) {  // Split off a text node.
            +            spans[spanIndex + 1] = textNode
            +                // TODO: Possibly optimize by using '' if there's no flicker.
            +                = document.createTextNode(source.substring(end, spanEnd));
            +            parentNode.insertBefore(textNode, span.nextSibling);
            +          }
            +        }
            +  
            +        sourceIndex = end;
            +  
            +        if (sourceIndex >= spanEnd) {
            +          spanIndex += 2;
            +        }
            +        if (sourceIndex >= decEnd) {
            +          decorationIndex += 2;
            +        }
            +      }
            +    } finally {
            +      if (sourceNode) {
            +        sourceNode.style.display = oldDisplay;
            +      }
            +    }
            +  }
            +
            +  /** Maps language-specific file extensions to handlers. */
            +  var langHandlerRegistry = {};
            +  /** Register a language handler for the given file extensions.
            +    * @param {function (Object)} handler a function from source code to a list
            +    *      of decorations.  Takes a single argument job which describes the
            +    *      state of the computation.   The single parameter has the form
            +    *      {@code {
            +    *        sourceCode: {string} as plain text.
            +    *        decorations: {Array.<number|string>} an array of style classes
            +    *                     preceded by the position at which they start in
            +    *                     job.sourceCode in order.
            +    *                     The language handler should assigned this field.
            +    *        basePos: {int} the position of source in the larger source chunk.
            +    *                 All positions in the output decorations array are relative
            +    *                 to the larger source chunk.
            +    *      } }
            +    * @param {Array.<string>} fileExtensions
            +    */
            +  function registerLangHandler(handler, fileExtensions) {
            +    for (var i = fileExtensions.length; --i >= 0;) {
            +      var ext = fileExtensions[i];
            +      if (!langHandlerRegistry.hasOwnProperty(ext)) {
            +        langHandlerRegistry[ext] = handler;
            +      } else if (win['console']) {
            +        console['warn']('cannot override language handler %s', ext);
            +      }
            +    }
            +  }
            +  function langHandlerForExtension(extension, source) {
            +    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
            +      // Treat it as markup if the first non whitespace character is a < and
            +      // the last non-whitespace character is a >.
            +      extension = /^\s*</.test(source)
            +          ? 'default-markup'
            +          : 'default-code';
            +    }
            +    return langHandlerRegistry[extension];
            +  }
            +  registerLangHandler(decorateSource, ['default-code']);
            +  registerLangHandler(
            +      createSimpleLexer(
            +          [],
            +          [
            +           [PR_PLAIN,       /^[^<?]+/],
            +           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
            +           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
            +           // Unescaped content in an unknown language
            +           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
            +           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
            +           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
            +           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
            +           // Unescaped content in javascript.  (Or possibly vbscript).
            +           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
            +           // Contains unescaped stylesheet content
            +           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
            +           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
            +          ]),
            +      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
            +  registerLangHandler(
            +      createSimpleLexer(
            +          [
            +           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
            +           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
            +           ],
            +          [
            +           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
            +           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
            +           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
            +           [PR_PUNCTUATION,  /^[=<>\/]+/],
            +           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
            +           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
            +           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
            +           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
            +           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
            +           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
            +           ]),
            +      ['in.tag']);
            +  registerLangHandler(
            +      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': CPP_KEYWORDS,
            +          'hashComments': true,
            +          'cStyleComments': true,
            +          'types': C_TYPES
            +        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': 'null,true,false'
            +        }), ['json']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': CSHARP_KEYWORDS,
            +          'hashComments': true,
            +          'cStyleComments': true,
            +          'verbatimStrings': true,
            +          'types': C_TYPES
            +        }), ['cs']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': JAVA_KEYWORDS,
            +          'cStyleComments': true
            +        }), ['java']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': SH_KEYWORDS,
            +          'hashComments': true,
            +          'multiLineStrings': true
            +        }), ['bash', 'bsh', 'csh', 'sh']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': PYTHON_KEYWORDS,
            +          'hashComments': true,
            +          'multiLineStrings': true,
            +          'tripleQuotedStrings': true
            +        }), ['cv', 'py', 'python']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': PERL_KEYWORDS,
            +          'hashComments': true,
            +          'multiLineStrings': true,
            +          'regexLiterals': 2  // multiline regex literals
            +        }), ['perl', 'pl', 'pm']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': RUBY_KEYWORDS,
            +          'hashComments': true,
            +          'multiLineStrings': true,
            +          'regexLiterals': true
            +        }), ['rb', 'ruby']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': JSCRIPT_KEYWORDS,
            +          'cStyleComments': true,
            +          'regexLiterals': true
            +        }), ['javascript', 'js']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': COFFEE_KEYWORDS,
            +          'hashComments': 3,  // ### style block comments
            +          'cStyleComments': true,
            +          'multilineStrings': true,
            +          'tripleQuotedStrings': true,
            +          'regexLiterals': true
            +        }), ['coffee']);
            +  registerLangHandler(sourceDecorator({
            +          'keywords': RUST_KEYWORDS,
            +          'cStyleComments': true,
            +          'multilineStrings': true
            +        }), ['rc', 'rs', 'rust']);
            +  registerLangHandler(
            +      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
            +
            +  function applyDecorator(job) {
            +    var opt_langExtension = job.langExtension;
            +
            +    try {
            +      // Extract tags, and convert the source code to plain text.
            +      var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
            +      /** Plain text. @type {string} */
            +      var source = sourceAndSpans.sourceCode;
            +      job.sourceCode = source;
            +      job.spans = sourceAndSpans.spans;
            +      job.basePos = 0;
            +
            +      // Apply the appropriate language handler
            +      langHandlerForExtension(opt_langExtension, source)(job);
            +
            +      // Integrate the decorations and tags back into the source code,
            +      // modifying the sourceNode in place.
            +      recombineTagsAndDecorations(job);
            +    } catch (e) {
            +      if (win['console']) {
            +        console['log'](e && e['stack'] || e);
            +      }
            +    }
            +  }
            +
            +  /**
            +   * Pretty print a chunk of code.
            +   * @param sourceCodeHtml {string} The HTML to pretty print.
            +   * @param opt_langExtension {string} The language name to use.
            +   *     Typically, a filename extension like 'cpp' or 'java'.
            +   * @param opt_numberLines {number|boolean} True to number lines,
            +   *     or the 1-indexed number of the first line in sourceCodeHtml.
            +   */
            +  function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
            +    var container = document.createElement('div');
            +    // This could cause images to load and onload listeners to fire.
            +    // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
            +    // We assume that the inner HTML is from a trusted source.
            +    // The pre-tag is required for IE8 which strips newlines from innerHTML
            +    // when it is injected into a <pre> tag.
            +    // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
            +    // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
            +    container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
            +    container = container.firstChild;
            +    if (opt_numberLines) {
            +      numberLines(container, opt_numberLines, true);
            +    }
            +
            +    var job = {
            +      langExtension: opt_langExtension,
            +      numberLines: opt_numberLines,
            +      sourceNode: container,
            +      pre: 1
            +    };
            +    applyDecorator(job);
            +    return container.innerHTML;
            +  }
            +
            +   /**
            +    * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
            +    * {@code class=prettyprint} and prettify them.
            +    *
            +    * @param {Function} opt_whenDone called when prettifying is done.
            +    * @param {HTMLElement|HTMLDocument} opt_root an element or document
            +    *   containing all the elements to pretty print.
            +    *   Defaults to {@code document.body}.
            +    */
            +  function $prettyPrint(opt_whenDone, opt_root) {
            +    var root = opt_root || document.body;
            +    var doc = root.ownerDocument || document;
            +    function byTagName(tn) { return root.getElementsByTagName(tn); }
            +    // fetch a list of nodes to rewrite
            +    var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
            +    var elements = [];
            +    for (var i = 0; i < codeSegments.length; ++i) {
            +      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
            +        elements.push(codeSegments[i][j]);
            +      }
            +    }
            +    codeSegments = null;
            +
            +    var clock = Date;
            +    if (!clock['now']) {
            +      clock = { 'now': function () { return +(new Date); } };
            +    }
            +
            +    // The loop is broken into a series of continuations to make sure that we
            +    // don't make the browser unresponsive when rewriting a large page.
            +    var k = 0;
            +    var prettyPrintingJob;
            +
            +    var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
            +    var prettyPrintRe = /\bprettyprint\b/;
            +    var prettyPrintedRe = /\bprettyprinted\b/;
            +    var preformattedTagNameRe = /pre|xmp/i;
            +    var codeRe = /^code$/i;
            +    var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
            +    var EMPTY = {};
            +
            +    function doWork() {
            +      var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
            +                     clock['now']() + 250 /* ms */ :
            +                     Infinity);
            +      for (; k < elements.length && clock['now']() < endTime; k++) {
            +        var cs = elements[k];
            +
            +        // Look for a preceding comment like
            +        // <?prettify lang="..." linenums="..."?>
            +        var attrs = EMPTY;
            +        {
            +          for (var preceder = cs; (preceder = preceder.previousSibling);) {
            +            var nt = preceder.nodeType;
            +            // <?foo?> is parsed by HTML 5 to a comment node (8)
            +            // like <!--?foo?-->, but in XML is a processing instruction
            +            var value = (nt === 7 || nt === 8) && preceder.nodeValue;
            +            if (value
            +                ? !/^\??prettify\b/.test(value)
            +                : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
            +              // Skip over white-space text nodes but not others.
            +              break;
            +            }
            +            if (value) {
            +              attrs = {};
            +              value.replace(
            +                  /\b(\w+)=([\w:.%+-]+)/g,
            +                function (_, name, value) { attrs[name] = value; });
            +              break;
            +            }
            +          }
            +        }
            +
            +        var className = cs.className;
            +        if ((attrs !== EMPTY || prettyPrintRe.test(className))
            +            // Don't redo this if we've already done it.
            +            // This allows recalling pretty print to just prettyprint elements
            +            // that have been added to the page since last call.
            +            && !prettyPrintedRe.test(className)) {
            +
            +          // make sure this is not nested in an already prettified element
            +          var nested = false;
            +          for (var p = cs.parentNode; p; p = p.parentNode) {
            +            var tn = p.tagName;
            +            if (preCodeXmpRe.test(tn)
            +                && p.className && prettyPrintRe.test(p.className)) {
            +              nested = true;
            +              break;
            +            }
            +          }
            +          if (!nested) {
            +            // Mark done.  If we fail to prettyprint for whatever reason,
            +            // we shouldn't try again.
            +            cs.className += ' prettyprinted';
            +
            +            // If the classes includes a language extensions, use it.
            +            // Language extensions can be specified like
            +            //     <pre class="prettyprint lang-cpp">
            +            // the language extension "cpp" is used to find a language handler
            +            // as passed to PR.registerLangHandler.
            +            // HTML5 recommends that a language be specified using "language-"
            +            // as the prefix instead.  Google Code Prettify supports both.
            +            // http://dev.w3.org/html5/spec-author-view/the-code-element.html
            +            var langExtension = attrs['lang'];
            +            if (!langExtension) {
            +              langExtension = className.match(langExtensionRe);
            +              // Support <pre class="prettyprint"><code class="language-c">
            +              var wrapper;
            +              if (!langExtension && (wrapper = childContentWrapper(cs))
            +                  && codeRe.test(wrapper.tagName)) {
            +                langExtension = wrapper.className.match(langExtensionRe);
            +              }
            +
            +              if (langExtension) { langExtension = langExtension[1]; }
            +            }
            +
            +            var preformatted;
            +            if (preformattedTagNameRe.test(cs.tagName)) {
            +              preformatted = 1;
            +            } else {
            +              var currentStyle = cs['currentStyle'];
            +              var defaultView = doc.defaultView;
            +              var whitespace = (
            +                  currentStyle
            +                  ? currentStyle['whiteSpace']
            +                  : (defaultView
            +                     && defaultView.getComputedStyle)
            +                  ? defaultView.getComputedStyle(cs, null)
            +                  .getPropertyValue('white-space')
            +                  : 0);
            +              preformatted = whitespace
            +                  && 'pre' === whitespace.substring(0, 3);
            +            }
            +
            +            // Look for a class like linenums or linenums:<n> where <n> is the
            +            // 1-indexed number of the first line.
            +            var lineNums = attrs['linenums'];
            +            if (!(lineNums = lineNums === 'true' || +lineNums)) {
            +              lineNums = className.match(/\blinenums\b(?::(\d+))?/);
            +              lineNums =
            +                lineNums
            +                ? lineNums[1] && lineNums[1].length
            +                  ? +lineNums[1] : true
            +                : false;
            +            }
            +            if (lineNums) { numberLines(cs, lineNums, preformatted); }
            +
            +            // do the pretty printing
            +            prettyPrintingJob = {
            +              langExtension: langExtension,
            +              sourceNode: cs,
            +              numberLines: lineNums,
            +              pre: preformatted
            +            };
            +            applyDecorator(prettyPrintingJob);
            +          }
            +        }
            +      }
            +      if (k < elements.length) {
            +        // finish up in a continuation
            +        setTimeout(doWork, 250);
            +      } else if ('function' === typeof opt_whenDone) {
            +        opt_whenDone();
            +      }
            +    }
            +
            +    doWork();
            +  }
            +
            +  /**
            +   * Contains functions for creating and registering new language handlers.
            +   * @type {Object}
            +   */
            +  var PR = win['PR'] = {
            +        'createSimpleLexer': createSimpleLexer,
            +        'registerLangHandler': registerLangHandler,
            +        'sourceDecorator': sourceDecorator,
            +        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
            +        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
            +        'PR_COMMENT': PR_COMMENT,
            +        'PR_DECLARATION': PR_DECLARATION,
            +        'PR_KEYWORD': PR_KEYWORD,
            +        'PR_LITERAL': PR_LITERAL,
            +        'PR_NOCODE': PR_NOCODE,
            +        'PR_PLAIN': PR_PLAIN,
            +        'PR_PUNCTUATION': PR_PUNCTUATION,
            +        'PR_SOURCE': PR_SOURCE,
            +        'PR_STRING': PR_STRING,
            +        'PR_TAG': PR_TAG,
            +        'PR_TYPE': PR_TYPE,
            +        'prettyPrintOne':
            +           IN_GLOBAL_SCOPE
            +             ? (win['prettyPrintOne'] = $prettyPrintOne)
            +             : (prettyPrintOne = $prettyPrintOne),
            +        'prettyPrint': prettyPrint =
            +           IN_GLOBAL_SCOPE
            +             ? (win['prettyPrint'] = $prettyPrint)
            +             : (prettyPrint = $prettyPrint)
            +      };
            +
            +  // Make PR available via the Asynchronous Module Definition (AMD) API.
            +  // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
            +  // The Asynchronous Module Definition (AMD) API specifies a
            +  // mechanism for defining modules such that the module and its
            +  // dependencies can be asynchronously loaded.
            +  // ...
            +  // To allow a clear indicator that a global define function (as
            +  // needed for script src browser loading) conforms to the AMD API,
            +  // any global define function SHOULD have a property called "amd"
            +  // whose value is an object. This helps avoid conflict with any
            +  // other existing JavaScript code that could have defined a define()
            +  // function that does not conform to the AMD API.
            +  if (typeof define === "function" && define['amd']) {
            +    define("google-code-prettify", [], function () {
            +      return PR; 
            +    });
            +  }
            +})();
            +
            +define("prettify", function(){});
            +
            +define('itemView',[
            +  'App',
            +  // Templates
            +  'text!tpl/item.html',
            +  'text!tpl/class.html',
            +  'text!tpl/itemEnd.html',
            +  // Tools
            +  'prettify'
            +], function(App, itemTpl, classTpl, endTpl) {
            +  'use strict';
            +
            +  var appVersion = App.project.version || 'master';
            +
            +  var itemView = Backbone.View.extend({
            +    el: '#item',
            +    init: function() {
            +      this.$html = $('html');
            +      this.$body = $('body');
            +      this.$scrollBody = $('html, body'); // hack for Chrome/Firefox scroll
            +
            +      this.tpl = _.template(itemTpl);
            +      this.classTpl = _.template(classTpl);
            +      this.endTpl = _.template(endTpl);
            +
            +      return this;
            +    },
            +    getSyntax: function(isMethod, cleanItem) {
            +      var isConstructor = cleanItem.is_constructor;
            +      var syntax = '';
            +      if (isConstructor) {
            +        syntax += 'new ';
            +      } else if (cleanItem.static && cleanItem.class) {
            +        syntax += cleanItem.class + '.';
            +      }
            +      syntax += cleanItem.name;
            +
            +      if (isMethod || isConstructor) {
            +        syntax += '(';
            +        if (cleanItem.params) {
            +          for (var i = 0; i < cleanItem.params.length; i++) {
            +            var p = cleanItem.params[i];
            +            if (p.optional) {
            +              syntax += '[';
            +            }
            +            syntax += p.name;
            +            if (p.optdefault) {
            +              syntax += '=' + p.optdefault;
            +            }
            +            if (p.optional) {
            +              syntax += ']';
            +            }
            +            if (i !== cleanItem.params.length - 1) {
            +              syntax += ', ';
            +            }
            +          }
            +        }
            +        syntax += ')';
            +      }
            +
            +      return syntax;
            +    },
            +    // Return a list of valid syntaxes across all overloaded versions of
            +    // this item.
            +    //
            +    // For reference, we ultimately want to replicate something like this:
            +    //
            +    // https://processing.org/reference/color_.html
            +    getSyntaxes: function(isMethod, cleanItem) {
            +      var overloads = cleanItem.overloads || [cleanItem];
            +      return overloads.map(this.getSyntax.bind(this, isMethod));
            +    },
            +    render: function(item) {
            +      if (item) {
            +        var itemHtml = '';
            +        var cleanItem = this.clean(item);
            +        var isClass = item.hasOwnProperty('itemtype') ? 0 : 1;
            +        var collectionName = isClass
            +            ? 'Constructor'
            +            : this.capitalizeFirst(cleanItem.itemtype),
            +          isConstructor = cleanItem.is_constructor;
            +        cleanItem.isMethod = collectionName === 'Method';
            +
            +        var syntaxes = this.getSyntaxes(cleanItem.isMethod, cleanItem);
            +
            +        // Set the item header (title)
            +
            +        // Set item contents
            +        if (isClass) {
            +          var constructor = this.tpl({
            +            item: cleanItem,
            +            isClass: true,
            +            isConstructor: isConstructor,
            +            syntaxes: syntaxes
            +          });
            +          cleanItem.constructor = constructor;
            +
            +          var contents = _.find(App.classes, function(c) {
            +            return c.name === cleanItem.name;
            +          });
            +          cleanItem.things = contents.items;
            +
            +          itemHtml = this.classTpl(cleanItem);
            +        } else {
            +          cleanItem.constRefs =
            +            item.module === 'Constants' && App.data.consts[item.name];
            +
            +          itemHtml = this.tpl({
            +            item: cleanItem,
            +            isClass: false,
            +            isConstructor: false,
            +            syntaxes: syntaxes
            +          });
            +        }
            +
            +        itemHtml += this.endTpl({ item: cleanItem, appVersion: appVersion });
            +
            +        // Insert the view in the dom
            +        this.$el.html(itemHtml);
            +
            +        renderCode(cleanItem.name);
            +
            +        // Set the document title based on the item name.
            +        // If it is a method, add parentheses to the name
            +        if (item.itemtype === 'method') {
            +          App.pageView.appendToDocumentTitle(item.name + '()');
            +        } else {
            +          App.pageView.appendToDocumentTitle(item.name);
            +        }
            +
            +        // Hook up alt-text for examples
            +        setTimeout(function() {
            +          var alts = $('.example-content')[0];
            +          if (alts) {
            +            alts = $(alts)
            +              .data('alt')
            +              .split('\n');
            +
            +            var canvases = $('.cnv_div');
            +            for (var j = 0; j < alts.length; j++) {
            +              if (j < canvases.length) {
            +                $(canvases[j]).append(
            +                  '<span class="sr-only">' + alts[j] + '</span>'
            +                );
            +              }
            +            }
            +          }
            +        }, 1000);
            +        Prism.highlightAll();
            +      }
            +
            +      var renderEvent = new Event('reference-rendered');
            +      window.dispatchEvent(renderEvent);
            +
            +      return this;
            +    },
            +    /**
            +     * Clean item properties: url encode properties containing paths.
            +     * @param {object} item The item object.
            +     * @returns {object} Returns the same item object with urlencoded paths.
            +     */
            +    clean: function(item) {
            +      var cleanItem = item;
            +
            +      if (cleanItem.hasOwnProperty('file')) {
            +        cleanItem.urlencodedfile = encodeURIComponent(item.file);
            +      }
            +      return cleanItem;
            +    },
            +    /**
            +     * Show a single item.
            +     * @param {object} item Item object.
            +     * @returns {object} This view.
            +     */
            +    show: function(item) {
            +      if (item) {
            +        this.render(item);
            +      }
            +
            +      App.pageView.hideContentViews();
            +
            +      this.$el.show();
            +
            +      this.scrollTop();
            +      $('#item').focus();
            +      return this;
            +    },
            +    /**
            +     * Show a message if no item is found.
            +     * @returns {object} This view.
            +     */
            +    nothingFound: function() {
            +      this.$el.html(
            +        '<p><br><br>Ouch. I am unable to find any item that match the current query.</p>'
            +      );
            +      App.pageView.hideContentViews();
            +      this.$el.show();
            +
            +      return this;
            +    },
            +    /**
            +     * Scroll to the top of the window with an animation.
            +     */
            +    scrollTop: function() {
            +      // Hack for Chrome/Firefox scroll animation
            +      // Chrome scrolls 'body', Firefox scrolls 'html'
            +      var scroll = this.$body.scrollTop() > 0 || this.$html.scrollTop() > 0;
            +      if (scroll) {
            +        this.$scrollBody.animate({ scrollTop: 0 }, 600);
            +      }
            +    },
            +    /**
            +     * Helper method to capitalize the first letter of a string
            +     * @param {string} str
            +     * @returns {string} Returns the string.
            +     */
            +    capitalizeFirst: function(str) {
            +      return str.substr(0, 1).toUpperCase() + str.substr(1);
            +    }
            +  });
            +
            +  return itemView;
            +});
            +
            +
            +define('text!tpl/menu.html',[],function () { return '<div>\r\n  <br>\r\n  <span id="reference-description1">Can\'t find what you\'re looking for? You may want to check out</span>\r\n  <a href="#/libraries/p5.sound">p5.sound</a>.<br><a href=\'https://p5js.org/offline-reference/p5-reference.zip\' target=_blank><span id="reference-description3">You can also download an offline version of the reference.</span></a>\r\n</div>\r\n\r\n<div id=\'collection-list-categories\'>\r\n<h2 class="sr-only" id="categories">Categories</h2>\r\n<% var i=0; %>\r\n<% var max=Math.floor(groups.length/4); %>\r\n<% var rem=groups.length%4; %>\r\n\r\n<% _.each(groups, function(group){ %>\r\n  <% var m = rem > 0 ? 1 : 0 %>\r\n  <% if (i === 0) { %>\r\n    <ul aria-labelledby="categories">\r\n    <% } %>\r\n    <li><a href="#group-<%=group%>"><%=group%></a></li>\r\n    <% if (i === (max+m-1)) { %>\r\n    </ul>\r\n  \t<% rem-- %>\r\n  \t<% i=0 %>\r\n  <% } else { %>\r\n  \t<% i++ %>\r\n  <% } %>\r\n<% }); %>\r\n</div>\r\n';});
            +
            +define('menuView',[
            +  'App',
            +  'text!tpl/menu.html'
            +], function(App, menuTpl) {
            +
            +  var menuView = Backbone.View.extend({
            +    el: '#collection-list-nav',
            +    /**
            +     * Init.
            +     * @returns {object} This view.
            +     */
            +    init: function() {
            +      this.menuTpl = _.template(menuTpl);
            +      return this;
            +    },
            +    /**
            +     * Render.
            +     * @returns {object} This view.
            +     */
            +    render: function() {
            +
            +      var groups = [];
            +      _.each(App.modules, function (item, i) {
            +        if (!item.is_submodule) {
            +          if (!item.file || item.file.indexOf('addons') === -1) { //addons don't get displayed on main page
            +            groups.push(item.name);
            +          }
            +        }
            +        //}
            +      });
            +
            +      // Sort groups by name A-Z
            +      groups.sort();
            +
            +      var menuHtml = this.menuTpl({
            +        'groups': groups
            +      });
            +
            +      // Render the view
            +      this.$el.html(menuHtml);
            +    },
            +
            +    hide: function() {
            +      this.$el.hide();
            +    },
            +
            +    show: function() {
            +      this.$el.show();
            +    },
            +
            +    /**
            +     * Update the menu.
            +     * @param {string} el The name of the current route.
            +     */
            +    update: function(menuItem) {
            +      //console.log(menuItem);
            +      // this.$menuItems.removeClass('active');
            +      // this.$menuItems.find('a[href=#'+menuItem+']').parent().addClass('active');
            +
            +    }
            +  });
            +
            +  return menuView;
            +
            +});
            +
            +
            +define('text!tpl/library.html',[],function () { return '<h3><%= module.name %> library</h3>\r\n\r\n<p><%= module.description %></p>\r\n\r\n<div id="library-page" class="reference-group clearfix">  \r\n\r\n<% var t = 0; col = 0; %>\r\n\r\n<% _.each(groups, function(group){ %>\r\n  <% if (t == 0) { %> \r\n    <div class="column_<%=col%>">\r\n  <% } %>\r\n  <% if (group.name !== module.name && group.name !== \'p5\') { %>\r\n    <% if (group.hash) { %> <a href="<%=group.hash%>" <% if (group.module !== module.name) { %>class="core"<% } %>><% } %>  \r\n    <h2 class="group-name <% if (t == 0) { %> first<%}%>"><%=group.name%></h2>\r\n    <% if (group.hash) { %> </a><br> <% } %>\r\n  <% } %>\r\n  <% _.each(group.items.filter(function(item) {return item.access !== \'private\'}), function(item) { %>\r\n    <a href="<%=item.hash%>" <% if (item.module !== module.name) { %>class="core"<% } %>><%=item.name%><% if (item.itemtype === \'method\') { %>()<%}%></a><br>\r\n    <% t++; %>\r\n  <% }); %>\r\n  <% if (t >= Math.floor(totalItems/4)) { col++; t = 0; %>\r\n    </div>\r\n  <% } %>\r\n<% }); %>\r\n</div>\r\n';});
            +
            +define(
            +  'libraryView',[
            +    'App',
            +    // Templates
            +    'text!tpl/library.html'
            +  ],
            +  function(App, libraryTpl) {
            +    var libraryView = Backbone.View.extend({
            +      el: '#list',
            +      events: {},
            +      /**
            +       * Init.
            +       */
            +      init: function() {
            +        this.libraryTpl = _.template(libraryTpl);
            +
            +        return this;
            +      },
            +      /**
            +       * Render the list.
            +       */
            +      render: function(m, listCollection) {
            +        if (m && listCollection) {
            +          var self = this;
            +
            +          // Render items and group them by module
            +          // module === group
            +          this.groups = {};
            +          _.each(m.items, function(item, i) {
            +            var module = item.module || '_';
            +            var group;
            +            // Override default group with a selected category
            +            // TODO: Overwriting with the first category might not be the best choice
            +            // We might also want to have links for categories
            +            if (item.category && item.category[0]) {
            +              group = item.category[0];
            +              // Populate item.hash
            +              App.router.getHash(item);
            +
            +              // Create a group list without link hash
            +              if (!self.groups[group]) {
            +                self.groups[group] = {
            +                  name: group.replace('_', '&nbsp;'),
            +                  module: module,
            +                  hash: undefined,
            +                  items: []
            +                };
            +              }
            +            } else {
            +              group = item.class || '_';
            +              var hash = App.router.getHash(item);
            +
            +              var ind = hash.lastIndexOf('/');
            +              hash = hash.substring(0, ind);
            +
            +              // Create a group list
            +              if (!self.groups[group]) {
            +                self.groups[group] = {
            +                  name: group.replace('_', '&nbsp;'),
            +                  module: module,
            +                  hash: hash,
            +                  items: []
            +                };
            +              }
            +            }
            +
            +            self.groups[group].items.push(item);
            +          });
            +
            +          // Sort groups by name A-Z
            +          self.groups = _.sortBy(self.groups, this.sortByName);
            +
            +          // Put the <li> items html into the list <ul>
            +          var libraryHtml = self.libraryTpl({
            +            title: self.capitalizeFirst(listCollection),
            +            module: m.module,
            +            totalItems: m.items.length,
            +            groups: self.groups
            +          });
            +
            +          // Render the view
            +          this.$el.html(libraryHtml);
            +        }
            +
            +        return this;
            +      },
            +      /**
            +       * Show a list of items.
            +       * @param {array} items Array of item objects.
            +       * @returns {object} This view.
            +       */
            +      show: function(listGroup) {
            +        if (App[listGroup]) {
            +          this.render(App[listGroup], listGroup);
            +        }
            +        App.pageView.hideContentViews();
            +
            +        this.$el.show();
            +
            +        return this;
            +      },
            +      /**
            +       * Helper method to capitalize the first letter of a string
            +       * @param {string} str
            +       * @returns {string} Returns the string.
            +       */
            +      capitalizeFirst: function(str) {
            +        return str.substr(0, 1).toUpperCase() + str.substr(1);
            +      },
            +      /**
            +       * Sort function (for the Array.prototype.sort() native method): from A to Z.
            +       * @param {string} a
            +       * @param {string} b
            +       * @returns {Array} Returns an array with elements sorted from A to Z.
            +       */
            +      sortAZ: function(a, b) {
            +        return a.innerHTML.toLowerCase() > b.innerHTML.toLowerCase() ? 1 : -1;
            +      },
            +
            +      sortByName: function(a, b) {
            +        if (a.name === 'p5') return -1;
            +        else return 0;
            +      }
            +    });
            +
            +    return libraryView;
            +  }
            +);
            +
            +define('pageView',[
            +  'App',
            +
            +  // Views
            +  'searchView',
            +  'listView',
            +  'itemView',
            +  'menuView',
            +  'libraryView'
            +], function(App, searchView, listView, itemView, menuView, libraryView) {
            +
            +  // Store the original title parts so we can substitue different endings.
            +  var _originalDocumentTitle = window.document.title;
            +
            +  var pageView = Backbone.View.extend({
            +    el: 'body',
            +    /**
            +     * Init.
            +     */
            +    init: function() {
            +      App.$container = $('#container');
            +      App.contentViews = [];
            +
            +      return this;
            +    },
            +    /**
            +     * Render.
            +     */
            +    render: function() {
            +
            +      // Menu view
            +      if (!App.menuView) {
            +        App.menuView = new menuView();
            +        App.menuView.init().render();
            +      }
            +
            +      // Item view
            +      if (!App.itemView) {
            +        App.itemView = new itemView();
            +        App.itemView.init().render();
            +        // Add the item view to the views array
            +        App.contentViews.push(App.itemView);
            +      }
            +
            +      // List view
            +      if (!App.listView) {
            +        App.listView = new listView();
            +        App.listView.init().render();
            +        // Add the list view to the views array
            +        App.contentViews.push(App.listView);
            +      }
            +
            +      // Library view
            +      if (!App.libraryView) {
            +        App.libraryView = new libraryView();
            +        App.libraryView.init().render();
            +        // Add the list view to the views array
            +        App.contentViews.push(App.libraryView);
            +      }
            +
            +      // Search
            +      if (!App.searchView) {
            +        App.searchView = new searchView();
            +        App.searchView.init().render();
            +      }
            +      return this;
            +    },
            +    /**
            +     * Hide item and list views.
            +     * @returns {object} This view.
            +     */
            +    hideContentViews: function() {
            +      _.each(App.contentViews, function(view, i) {
            +        view.$el.hide();
            +      });
            +
            +      return this;
            +    },
            +    /**
            +     * Append the supplied name to the first part of original document title.
            +     * If no name is supplied, the title will reset to the original one.
            +     */
            +    appendToDocumentTitle: function(name){
            +      if(name){
            +        let firstTitlePart = _originalDocumentTitle.split(" | ")[0];
            +        window.document.title = [firstTitlePart, name].join(" | ");
            +      } else {
            +        window.document.title = _originalDocumentTitle;
            +      }
            +    }    
            +  });
            +
            +  return pageView;
            +
            +});
            +
            +define('router',[
            +  'App'
            +], function(App) {
            +
            +  'use strict'; //
            +
            +  var Router = Backbone.Router.extend({
            +
            +    routes: {
            +      '': 'list',
            +      'p5': 'list',
            +      'p5/': 'list',
            +      'classes': 'list',
            +      'search': 'search',
            +      'libraries/:lib': 'library',
            +      ':searchClass(/:searchItem)': 'get'
            +    },
            +    /**
            +     * Whether the json API data was loaded.
            +     */
            +    _initialized: false,
            +    /**
            +     * Initialize the app: load json API data and create searchable arrays.
            +     */
            +    init: function(callback) {
            +      var self = this;
            +      require(['pageView'], function(pageView) {
            +
            +        // If already initialized, move away from here!
            +        if (self._initialized) {
            +          if (callback)
            +            callback();
            +          return;
            +        }
            +
            +        // Update initialization state: must be done now to avoid recursive mess
            +        self._initialized = true;
            +
            +        // Render views
            +        if (!App.pageView) {
            +          App.pageView = new pageView();
            +          App.pageView.init().render();
            +        }
            +
            +        // If a callback is set (a route has already been called), run it
            +        // otherwise, show the default list
            +        if (callback)
            +          callback();
            +        else
            +          self.list();
            +      });
            +    },
            +    /**
            +     * Start route. Simply check if initialized.
            +     */
            +    start: function() {
            +      this.init();
            +    },
            +    /**
            +     * Show item details by searching a class or a class item (method, property or event).
            +     * @param {string} searchClass The class name (mandatory).
            +     * @param {string} searchItem The class item name: can be a method, property or event name.
            +     */
            +    get: function(searchClass, searchItem) {
            +
            +      // if looking for a library page, redirect
            +      if (searchClass === 'p5.sound' && !searchItem) {
            +        window.location.hash = '/libraries/'+searchClass;
            +        return;
            +      }
            +
            +      var self = this;
            +      this.init(function() {
            +        var item = self.getItem(searchClass, searchItem);
            +
            +        App.menuView.hide();
            +
            +        if (item) {
            +          App.itemView.show(item);
            +        } else {
            +          //App.itemView.nothingFound();
            +
            +          self.list();
            +        }
            +
            +        styleCodeLinks();
            +      });
            +    },
            +    /**
            +     * Returns one item object by searching a class or a class item (method, property or event).
            +     * @param {string} searchClass The class name (mandatory).
            +     * @param {string} searchItem The class item name: can be a method, property or event name.
            +     * @returns {object} The item found or undefined if nothing was found.
            +     */
            +    getItem: function(searchClass, searchItem) {
            +      var classes = App.classes,
            +              items = App.allItems,
            +              classesCount = classes.length,
            +              itemsCount = items.length,
            +              className = searchClass ? searchClass.toLowerCase() : undefined,
            +              itemName = searchItem ? searchItem : undefined,
            +              found;
            +
            +      // Only search for a class, if itemName is undefined
            +      if (className && !itemName) {
            +        for (var i = 0; i < classesCount; i++) {
            +          if (classes[i].name.toLowerCase() === className) {
            +            found = classes[i];
            +            _.each(found.items, function(i, idx) {
            +              i.hash = App.router.getHash(i);
            +            });
            +            break;
            +          }
            +        }
            +        // Search for a class item
            +      } else if (className && itemName) {
            +        // Search case sensitively
            +        for (var i = 0; i < itemsCount; i++) {
            +          if (items[i].class.toLowerCase() === className &&
            +            items[i].name === itemName) {
            +            found = items[i];
            +            break;
            +          }
            +        }
            +
            +        // If no match was found, fallback to search case insensitively
            +        if(!found){
            +          for (var i = 0; i < itemsCount; i++) {
            +            if(items[i].class.toLowerCase() === className &&
            +              items[i].name.toLowerCase() === itemName.toLowerCase()){
            +              found = items[i];
            +              break;
            +            }
            +          }
            +        }
            +      }
            +
            +      return found;
            +    },
            +    /**
            +     * List items.
            +     * @param {string} collection The name of the collection to list.
            +     */
            +    list: function(collection) {
            +
            +      collection = 'allItems';
            +
            +      // Make sure collection is valid
            +      if (App.collections.indexOf(collection) < 0) {
            +        return;
            +      }
            +
            +      this.init(function() {
            +        App.menuView.show(collection);
            +        App.menuView.update(collection);
            +        App.listView.show(collection);
            +        styleCodeLinks();
            +      });
            +    },
            +    /**
            +     * Display information for a library.
            +     * @param {string} collection The name of the collection to list.
            +     */
            +    library: function(collection) {
            +      this.init(function() {
            +        App.menuView.hide();
            +        App.libraryView.show(collection.substring(3)); //remove p5.
            +        styleCodeLinks();
            +      });
            +    },
            +    /**
            +     * Close all content views.
            +     */
            +    search: function() {
            +      this.init(function() {
            +        App.menuView.hide();
            +        App.pageView.hideContentViews();
            +      });
            +    },
            +
            +    /**
            +     * Create an hash/url for the item.
            +     * @param {Object} item A class, method, property or event object.
            +     * @returns {String} The hash string, including the '#'.
            +     */
            +     getHash: function(item) {
            +
            +       if (!item.hash) {
            +
            +         // FIX TO INVISIBLE OBJECTS: DH (see also listView.js)
            +
            +         if (item.class) {
            +           var clsFunc = '#/' + item.class + '.' + item.name;
            +           var idx = clsFunc.lastIndexOf('.');
            +           item.hash = clsFunc.substring(0,idx) + '/' + clsFunc.substring(idx+1);
            +         } else {
            +          item.hash = '#/' + item.name;
            +         }
            +       }
            +
            +       return item.hash;
            +    }
            +  });
            +
            +  
            +  function styleCodeLinks() {
            +    var links = document.getElementsByTagName("a");
            +    for (var iLink = 0; iLink < links.length; iLink++) {
            +      var link = links[iLink];
            +      if (link.hash.startsWith('#/p5')) {
            +        link.classList.add('code');
            +      }
            +    }
            +  }
            +
            +
            +  // Get the router
            +  App.router = new Router();
            +
            +  // Start history
            +  Backbone.history.start();
            +
            +  return App.router;
            +
            +});
            +
            +/**
            + * Define global App.
            + */
            +var App = window.App || {};
            +define('App', [],function() {
            +  return App;
            +});
            +
            +/**
            + * Load json API data and start the router.
            + * @param {module} App
            + * @param {module} router
            + */
            +require([
            +  'App',
            +  './documented-method'], function(App, DocumentedMethod) {
            +
            +  // Set collections
            +  App.collections = ['allItems', 'classes', 'events', 'methods', 'properties', 'p5.sound'];
            +
            +  // Get json API data
            +  $.getJSON('data.min.json', function(data) {
            +    App.data = data;
            +    App.classes = [];
            +    App.methods = [];
            +    App.properties = [];
            +    App.events = [];
            +    App.allItems = [];
            +    App.sound = { items: [] };
            +    App.dom = { items: [] };
            +    App.modules = [];
            +    App.project = data.project;
            +
            +
            +    var modules = data.modules;
            +
            +    // Get class items (methods, properties, events)
            +    _.each(modules, function(m, idx, array) {
            +      App.modules.push(m);
            +      if (m.name == "p5.sound") {
            +        App.sound.module = m;
            +      }
            +    });
            +
            +
            +    var items = data.classitems;
            +    var classes = data.classes;
            +
            +    // Get classes
            +    _.each(classes, function(c, idx, array) {
            +      if (!c.private) {
            +        App.classes.push(c);
            +      }
            +    });
            +
            +
            +    // Get class items (methods, properties, events)
            +    _.each(items, function(el, idx, array) {
            +      if (el.itemtype) {
            +        if (el.itemtype === "method") {
            +          el = new DocumentedMethod(el);
            +          App.methods.push(el);
            +          App.allItems.push(el);
            +        } else if (el.itemtype === "property") {
            +          App.properties.push(el);
            +          App.allItems.push(el);
            +        } else if (el.itemtype === "event") {
            +          App.events.push(el);
            +          App.allItems.push(el);
            +        }
            +
            +        // libraries
            +        if (el.module === "p5.sound") {
            +          App.sound.items.push(el);
            +        }
            +      }
            +    });
            +
            +    _.each(App.classes, function(c, idx) {
            +      c.items = _.filter(App.allItems, function(it){ return it.class === c.name; });
            +    });
            +
            +    require(['router']);
            +  });
            +});
            +
            +define("main", function(){});
            +
            +}());
            \ No newline at end of file
            diff --git a/dist/assets/js/render.js b/dist/assets/js/render.js
            new file mode 100644
            index 0000000000..dee7680335
            --- /dev/null
            +++ b/dist/assets/js/render.js
            @@ -0,0 +1,280 @@
            +var renderCode = function(exampleName) {
            +  var _p5 = p5;
            +  var instances = [];
            +  var selector = 'example';
            +  var examples = document.getElementsByClassName(selector);
            +
            +  if (examples.length > 0) {
            +    var sketches = examples[0].getElementsByTagName('code');
            +    var sketches_array = Array.prototype.slice.call(sketches);
            +    var i = 0;
            +    sketches_array.forEach(function(s) {
            +      var rc = s.parentNode.className.indexOf('norender') === -1;
            +      setupCode(s, rc, i);
            +      runCode(s, rc, i);
            +      i++;
            +    });
            +  }
            +
            +  function enableTab(el) {
            +    el.onkeydown = function(e) {
            +      if (e.keyCode === 9) {
            +        // tab was pressed
            +        // get caret position/selection
            +        var val = this.value,
            +          start = this.selectionStart,
            +          end = this.selectionEnd;
            +        // set textarea value to: text before caret + tab + text after caret
            +        this.value = val.substring(0, start) + '  ' + val.substring(end);
            +        // put caret at right position again
            +        this.selectionStart = this.selectionEnd = start + 2;
            +        // prevent the focus lose
            +        return false;
            +      }
            +    };
            +  }
            +
            +  function setupCode(sketch, rc, i) {
            +    var isRef = sketch.parentNode.tagName !== 'PRE';
            +    var sketchNode = isRef ? sketch : sketch.parentNode;
            +    var sketchContainer = sketchNode.parentNode;
            +
            +    if (isRef) {
            +      $(sketchContainer).prepend('<h4 id="example'+i+'" class="sr-only">'+exampleName+' example '+i+'</h4>');
            +      var pre = document.createElement('pre');
            +      pre.classList.add('ref');
            +      pre.classList.add('example_code');
            +      pre.appendChild(sketchNode);
            +      sketchContainer.appendChild(pre);
            +      sketchContainer.className = 'example_container';
            +      sketch.className = 'language-javascript';
            +      if (!rc) {
            +        pre.className += ' norender';
            +      }
            +    }
            +
            +    // remove start and end lines
            +    var runnable = sketch.textContent.replace(/^\s+|\s+$/g, '');
            +    var rows = sketch.textContent.split('\n').length;
            +
            +    // store original sketch
            +    var orig_sketch = document.createElement('div');
            +    orig_sketch.innerHTML = sketch.innerHTML;
            +
            +    // create canvas
            +    if (rc) {
            +      var cnv = document.createElement('div');
            +      cnv.className = 'cnv_div';
            +      if (isRef) {
            +        sketchContainer.prepend(cnv);
            +      } else {
            +        sketchContainer.parentNode.insertBefore(cnv, sketchContainer);
            +      }
            +
            +      // create edit space
            +      let edit_space = document.createElement('div');
            +      edit_space.className = 'edit_space';
            +      sketchContainer.appendChild(edit_space);
            +      $(edit_space).append('<h5 class="sr-only" id="buttons"'+i+' aria-labelledby="buttons'+i+' example'+i+'">buttons</h5>');
            +
            +      var edit_area = document.createElement('textarea');
            +      edit_area.value = runnable;
            +      edit_area.rows = rows;
            +      edit_area.cols = 62;
            +      edit_area.classList.add('edit_area');
            +      edit_space.appendChild(edit_area);
            +      enableTab(edit_area);
            +
            +      //add buttons
            +      let button_space = document.createElement('ul');
            +      edit_space.appendChild(button_space);
            +
            +      let copy_button = document.createElement('button');
            +      copy_button.value = 'copy';
            +      copy_button.innerHTML = 'copy';
            +      copy_button.id = 'copy' + i;
            +      copy_button.setAttribute('aria-labelledby', copy_button.id + ' example' + i);
            +      copy_button.className = 'copy_button';
            +      copy_button.onclick = function() {
            +        setMode(sketch, 'edit');
            +        edit_area.select();
            +        document.execCommand('copy');
            +      };
            +      let copy_li = button_space.appendChild(document.createElement('li'));
            +      copy_li.appendChild(copy_button);
            +
            +      let reset_button = document.createElement('button');
            +      reset_button.value = 'reset';
            +      reset_button.innerHTML = 'reset';
            +      reset_button.id = 'reset' + i;
            +      reset_button.setAttribute('aria-labelledby', reset_button.id + ' example' + i);
            +      reset_button.className = 'reset_button';
            +      reset_button.onclick = function() {
            +        edit_area.value = orig_sketch.textContent;
            +        setMode(sketch, 'run');
            +      };
            +      let reset_li = button_space.appendChild(document.createElement('li'));
            +      reset_li.appendChild(reset_button);
            +
            +      let edit_button = document.createElement('button');
            +      edit_button.value = 'edit';
            +      edit_button.innerHTML = 'edit';
            +      edit_button.id = 'edit' + i;
            +      edit_button.setAttribute('aria-labelledby', edit_button.id + ' example' + i);
            +      edit_button.className = 'edit_button';
            +      edit_button.onclick = function(e) {
            +        if (edit_button.innerHTML === 'edit') {
            +          // edit
            +          setMode(sketch, 'edit');
            +        } else {
            +          // run
            +          setMode(sketch, 'run');
            +        }
            +      };
            +      let edit_li = button_space.appendChild(document.createElement('li'));
            +      edit_li.appendChild(edit_button);
            +
            +      function setMode(sketch, m) {
            +        if (m === 'edit') {
            +          $('.example_container').each(function(ind, con) {
            +            if (ind !== i) {
            +              $(con).css('opacity', 0.25);
            +            } else {
            +              $(con).addClass('editing');
            +            }
            +          });
            +          edit_button.innerHTML = 'run';
            +          edit_area.style.display = 'block';
            +          edit_area.focus();
            +        } else {
            +          edit_button.innerHTML = 'edit';
            +          edit_area.style.display = 'none';
            +          sketch.textContent = edit_area.value;
            +          $('.example_container').each(function(ind, con) {
            +            $(con).css('opacity', 1.0);
            +            $(con).removeClass('editing');
            +          });
            +          runCode(sketch, true, i);
            +        }
            +      }
            +    }
            +  }
            +
            +  function runCode(sketch, rc, i) {
            +    if (instances[i]) {
            +      instances[i].remove();
            +    }
            +
            +    var sketchNode = sketch.parentNode;
            +    var isRef = sketchNode.className.indexOf('ref') !== -1;
            +    var sketchContainer = sketchNode.parentNode;
            +    var parent = sketchContainer.parentNode;
            +
            +    var runnable = sketch.textContent.replace(/^\s+|\s+$/g, '');
            +    var cnv;
            +
            +    if (rc) {
            +      if (isRef) {
            +        cnv = sketchContainer.getElementsByClassName('cnv_div')[0];
            +      } else {
            +        cnv = parent.parentNode.getElementsByClassName('cnv_div')[0];
            +      }
            +      cnv.innerHTML = '';
            +
            +      var s = function(p) {
            +        var fxns = [
            +          'setup', 'draw', 'preload', 'mousePressed', 'mouseReleased',
            +          'mouseMoved', 'mouseDragged', 'mouseClicked', 'doubleClicked',
            +          'mouseWheel', 'touchStarted', 'touchMoved', 'touchEnded',
            +          'keyPressed', 'keyReleased', 'keyTyped'
            +        ];
            +        var _found = [];
            +        // p.preload is an empty function created by the p5.sound library in order to use the p5.js preload system
            +        // to load AudioWorklet modules before a sketch runs, even if that sketch doesn't have its own preload function.
            +        // However, this causes an error in the eval code below because the _found array will always contain "preload",
            +        // even if the sketch in question doesn't have a preload function. To get around this, we delete p.preload before
            +        // eval-ing the sketch and add it back afterwards if the sketch doesn't contain its own preload function.
            +        // For more info, see: https://github.com/processing/p5.js-sound/blob/master/src/audioWorklet/index.js#L22
            +        if (p.preload) {
            +          delete p.preload;
            +        }
            +        with (p) {
            +          // Builds a function to detect declared functions via
            +          // them being hoisted past the return statement. Does
            +          // not execute runnable. Two returns with different
            +          // conditions guarantee a return but suppress unreachable
            +          // code warnings.
            +          eval([
            +            '(function() {',
            +              fxns.map(function (_name) {
            +                return [
            +                  'try {',
            +                  '  eval(' + _name + ');',
            +                  '  _found.push(\'' + _name + '\');',
            +                  '} catch(e) {',
            +                  '  if(!(e instanceof ReferenceError)) {',
            +                  '    throw e;',
            +                  '  }',
            +                  '}'
            +                ].join('');
            +              }).join(''),
            +              'if(_found.length) return;',
            +              'if(!_found.length) return;',
            +              runnable,
            +            '})();'
            +          ].join('\n'));
            +        }
            +        // If we haven't found any functions we'll assume it's
            +        // just a setup body with an empty preload.
            +        if (!_found.length) {
            +          p.preload = function() {};
            +          p.setup = function() {
            +            p.createCanvas(100, 100);
            +            p.background(200);
            +            with (p) {
            +              eval(runnable);
            +            }
            +          };
            +        } else {
            +          // Actually runs the code to get functions into scope.
            +          with (p) {
            +            eval(runnable);
            +          }
            +          _found.forEach(function(name) {
            +            p[name] = eval(name);
            +          });
            +          // Ensure p.preload exists even if the sketch doesn't have a preload function.
            +          p.preload = p.preload || function() {};
            +          p.setup = p.setup || function() {
            +            p.createCanvas(100, 100);
            +            p.background(200);
            +          };
            +        }
            +      };
            +    }
            +
            +    //if (typeof prettyPrint !== 'undefined') prettyPrint();
            +    if (typeof Prism !== 'undefined') {
            +      Prism.highlightAll();
            +    }
            +
            +    // when a hash is changed, remove all the sounds,
            +    // even tho the p5 sketch has been disposed.
            +    function registerHashChange() {
            +      window.onhashchange = function(e) {
            +        for (var i = 0; i < instances.length; i++) {
            +          instances[i].remove();
            +        }
            +      };
            +    }
            +
            +    $(document).ready(function() {
            +      registerHashChange();
            +
            +      setTimeout(function() {
            +        var myp5 = new _p5(s, cnv);
            +        instances[i] = myp5;
            +      }, 100);
            +    });
            +  }
            +};
            diff --git a/dist/assets/js/slideshow.js b/dist/assets/js/slideshow.js
            new file mode 100644
            index 0000000000..52cdab9b53
            --- /dev/null
            +++ b/dist/assets/js/slideshow.js
            @@ -0,0 +1,13 @@
            +var slideIndex = 0;
            +carousel();
            +
            +function carousel() {
            +  var x = $("#slideshow").children();
            +  for (var i = 0; i < x.length; i++) {
            +    x[i].style.display = "none"; 
            +  }
            +  slideIndex++;
            +  if (slideIndex > x.length) {slideIndex = 1} 
            +  x[slideIndex-1].style.display = "block"; 
            +  setTimeout(carousel, 4000);
            +}
            \ No newline at end of file
            diff --git a/dist/assets/js/teach.js b/dist/assets/js/teach.js
            new file mode 100644
            index 0000000000..7ec3e60657
            --- /dev/null
            +++ b/dist/assets/js/teach.js
            @@ -0,0 +1,15 @@
            +	$("#filter-options :checkbox").click(function() 
            +		{
            +	       	$("#filter-list li").hide();
            +	       	$("#filter-options :checkbox:checked").each(function() 
            +	       	{
            +	           $("." + $(this).val()).fadeIn();
            +			});
            +	       
            +	        if($('#filter-options :checkbox').filter(':checked').length < 1) 
            +	        {
            +	        	$("#filter-list li").fadeIn();
            +	        	
            +	        }
            +	        
            +	    });
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ace.js b/dist/assets/js/vendor/ace-nc/ace.js
            new file mode 100644
            index 0000000000..b2ed67b299
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ace.js
            @@ -0,0 +1,11 @@
            +(function(){function s(r){var i=function(e,t){return n("",e,t)},s=e;r&&(e[r]||(e[r]={}),s=e[r]);if(!s.define||!s.define.packaged)t.original=s.define,s.define=t,s.define.packaged=!0;if(!s.require||!s.require.packaged)n.original=s.require,s.require=i,s.require.packaged=!0}var ACE_NAMESPACE = "ace",e=function(){return this}();if(!ACE_NAMESPACE&&typeof requirejs!="undefined")return;var t=function(e,n,r){if(typeof e!="string"){t.original?t.original.apply(window,arguments):(console.error("dropping module because define wasn't a string."),console.trace());return}arguments.length==2&&(r=n),t.modules||(t.modules={},t.payloads={}),t.payloads[e]=r,t.modules[e]=null},n=function(e,t,r){if(Object.prototype.toString.call(t)==="[object Array]"){var s=[];for(var o=0,u=t.length;o<u;++o){var a=i(e,t[o]);if(!a&&n.original)return n.original.apply(window,arguments);s.push(a)}r&&r.apply(null,s)}else{if(typeof t=="string"){var f=i(e,t);return!f&&n.original?n.original.apply(window,arguments):(r&&r(),f)}if(n.original)return n.original.apply(window,arguments)}},r=function(e,t){if(t.indexOf("!")!==-1){var n=t.split("!");return r(e,n[0])+"!"+r(e,n[1])}if(t.charAt(0)=="."){var i=e.split("/").slice(0,-1).join("/");t=i+"/"+t;while(t.indexOf(".")!==-1&&s!=t){var s=t;t=t.replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return t},i=function(e,i){i=r(e,i);var s=t.modules[i];if(!s){s=t.payloads[i];if(typeof s=="function"){var o={},u={id:i,uri:"",exports:o,packaged:!0},a=function(e,t){return n(i,e,t)},f=s(a,o,u);o=f||u.exports,t.modules[i]=o,delete t.payloads[i]}s=t.modules[i]=o||s}return s};s(ACE_NAMESPACE)})(),ace.define("ace/lib/regexp",["require","exports","module"],function(e,t,n){"use strict";function o(e){return(e.global?"g":"")+(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.extended?"x":"")+(e.sticky?"y":"")}function u(e,t,n){if(Array.prototype.indexOf)return e.indexOf(t,n);for(var r=n||0;r<e.length;r++)if(e[r]===t)return r;return-1}var r={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},i=r.exec.call(/()??/,"")[1]===undefined,s=function(){var e=/^/g;return r.test.call(e,""),!e.lastIndex}();if(s&&i)return;RegExp.prototype.exec=function(e){var t=r.exec.apply(this,arguments),n,a;if(typeof e=="string"&&t){!i&&t.length>1&&u(t,"")>-1&&(a=RegExp(this.source,r.replace.call(o(this),"g","")),r.replace.call(e.slice(t.index),a,function(){for(var e=1;e<arguments.length-2;e++)arguments[e]===undefined&&(t[e]=undefined)}));if(this._xregexp&&this._xregexp.captureNames)for(var f=1;f<t.length;f++)n=this._xregexp.captureNames[f-1],n&&(t[n]=t[f]);!s&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--}return t},s||(RegExp.prototype.test=function(e){var t=r.exec.call(this,e);return t&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,!!t})}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _="	\n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}}),ace.define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"],function(e,t,n){"use strict";e("./regexp"),e("./es5-shim")}),ace.define("ace/lib/dom",["require","exports","module"],function(e,t,n){"use strict";if(typeof document=="undefined")return;var r="http://www.w3.org/1999/xhtml";t.getDocumentHead=function(e){return e||(e=document),e.head||e.getElementsByTagName("head")[0]||e.documentElement},t.createElement=function(e,t){return document.createElementNS?document.createElementNS(t||r,e):document.createElement(e)},t.hasCssClass=function(e,t){var n=e.className.split(/\s+/g);return n.indexOf(t)!==-1},t.addCssClass=function(e,n){t.hasCssClass(e,n)||(e.className+=" "+n)},t.removeCssClass=function(e,t){var n=e.className.split(/\s+/g);for(;;){var r=n.indexOf(t);if(r==-1)break;n.splice(r,1)}e.className=n.join(" ")},t.toggleCssClass=function(e,t){var n=e.className.split(/\s+/g),r=!0;for(;;){var i=n.indexOf(t);if(i==-1)break;r=!1,n.splice(i,1)}return r&&n.push(t),e.className=n.join(" "),r},t.setCssClass=function(e,n,r){r?t.addCssClass(e,n):t.removeCssClass(e,n)},t.hasCssString=function(e,t){var n=0,r;t=t||document;if(t.createStyleSheet&&(r=t.styleSheets)){while(n<r.length)if(r[n++].owningElement.id===e)return!0}else if(r=t.getElementsByTagName("style"))while(n<r.length)if(r[n++].id===e)return!0;return!1},t.importCssString=function(n,i,s){s=s||document;if(i&&t.hasCssString(i,s))return null;var o;s.createStyleSheet?(o=s.createStyleSheet(),o.cssText=n,i&&(o.owningElement.id=i)):(o=s.createElementNS?s.createElementNS(r,"style"):s.createElement("style"),o.appendChild(s.createTextNode(n)),i&&(o.id=i),t.getDocumentHead(s).appendChild(o))},t.importCssStylsheet=function(e,n){if(n.createStyleSheet)n.createStyleSheet(e);else{var r=t.createElement("link");r.rel="stylesheet",r.href=e,t.getDocumentHead(n).appendChild(r)}},t.getInnerWidth=function(e){return parseInt(t.computedStyle(e,"paddingLeft"),10)+parseInt(t.computedStyle(e,"paddingRight"),10)+e.clientWidth},t.getInnerHeight=function(e){return parseInt(t.computedStyle(e,"paddingTop"),10)+parseInt(t.computedStyle(e,"paddingBottom"),10)+e.clientHeight},window.pageYOffset!==undefined?(t.getPageScrollTop=function(){return window.pageYOffset},t.getPageScrollLeft=function(){return window.pageXOffset}):(t.getPageScrollTop=function(){return document.body.scrollTop},t.getPageScrollLeft=function(){return document.body.scrollLeft}),window.getComputedStyle?t.computedStyle=function(e,t){return t?(window.getComputedStyle(e,"")||{})[t]||"":window.getComputedStyle(e,"")||{}}:t.computedStyle=function(e,t){return t?e.currentStyle[t]:e.currentStyle},t.scrollbarWidth=function(e){var n=t.createElement("ace_inner");n.style.width="100%",n.style.minWidth="0px",n.style.height="200px",n.style.display="block";var r=t.createElement("ace_outer"),i=r.style;i.position="absolute",i.left="-10000px",i.overflow="hidden",i.width="200px",i.minWidth="0px",i.height="150px",i.display="block",r.appendChild(n);var s=e.documentElement;s.appendChild(r);var o=n.offsetWidth;i.overflow="scroll";var u=n.offsetWidth;return o==u&&(u=r.clientWidth),s.removeChild(r),o-u},t.setInnerHtml=function(e,t){var n=e.cloneNode(!1);return n.innerHTML=t,e.parentNode.replaceChild(n,e),n},"textContent"in document.documentElement?(t.setInnerText=function(e,t){e.textContent=t},t.getInnerText=function(e){return e.textContent}):(t.setInnerText=function(e,t){e.innerText=t},t.getInnerText=function(e){return e.innerText}),t.getParentWindow=function(e){return e.defaultView||e.parentWindow}}),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/keys",["require","exports","module","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./oop"),i=function(){var e={MODIFIER_KEYS:{16:"Shift",17:"Ctrl",18:"Alt",224:"Meta"},KEY_MODS:{ctrl:1,alt:2,option:2,shift:4,"super":8,meta:8,command:8,cmd:8},FUNCTION_KEYS:{8:"Backspace",9:"Tab",13:"Return",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9","-13":"NumpadEnter",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock"},PRINTABLE_KEYS:{32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"}},t,n;for(n in e.FUNCTION_KEYS)t=e.FUNCTION_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);for(n in e.PRINTABLE_KEYS)t=e.PRINTABLE_KEYS[n].toLowerCase(),e[t]=parseInt(n,10);return r.mixin(e,e.MODIFIER_KEYS),r.mixin(e,e.PRINTABLE_KEYS),r.mixin(e,e.FUNCTION_KEYS),e.enter=e["return"],e.escape=e.esc,e.del=e["delete"],e[173]="-",function(){var t=["cmd","ctrl","alt","shift"];for(var n=Math.pow(2,t.length);n--;)e.KEY_MODS[n]=t.filter(function(t){return n&e.KEY_MODS[t]}).join("-")+"-"}(),e}();r.mixin(t,i),t.keyCodeToString=function(e){var t=i[e];return typeof t!="string"&&(t=String.fromCharCode(e)),t.toLowerCase()}}),ace.define("ace/lib/useragent",["require","exports","module"],function(e,t,n){"use strict";t.OS={LINUX:"LINUX",MAC:"MAC",WINDOWS:"WINDOWS"},t.getOS=function(){return t.isMac?t.OS.MAC:t.isLinux?t.OS.LINUX:t.OS.WINDOWS};if(typeof navigator!="object")return;var r=(navigator.platform.match(/mac|win|linux/i)||["other"])[0].toLowerCase(),i=navigator.userAgent;t.isWin=r=="win",t.isMac=r=="mac",t.isLinux=r=="linux",t.isIE=navigator.appName=="Microsoft Internet Explorer"||navigator.appName.indexOf("MSAppHost")>=0?parseFloat((i.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]):parseFloat((i.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]),t.isOldIE=t.isIE&&t.isIE<9,t.isGecko=t.isMozilla=(window.Controllers||window.controllers)&&window.navigator.product==="Gecko",t.isOldGecko=t.isGecko&&parseInt((i.match(/rv\:(\d+)/)||[])[1],10)<4,t.isOpera=window.opera&&Object.prototype.toString.call(window.opera)=="[object Opera]",t.isWebKit=parseFloat(i.split("WebKit/")[1])||undefined,t.isChrome=parseFloat(i.split(" Chrome/")[1])||undefined,t.isAIR=i.indexOf("AdobeAIR")>=0,t.isIPad=i.indexOf("iPad")>=0,t.isTouchPad=i.indexOf("TouchPad")>=0,t.isChromeOS=i.indexOf(" CrOS ")>=0}),ace.define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function o(e,t,n){var o=s(t);if(!i.isMac&&u){if(u[91]||u[92])o|=8;if(u.altGr){if((3&o)==3)return;u.altGr=0}if(n===18||n===17){var f=t.location||t.keyLocation;if(n===17&&f===1)a=t.timeStamp;else if(n===18&&o===3&&f===2){var l=-a;a=t.timeStamp,l+=a,l<3&&(u.altGr=!0)}}}if(n in r.MODIFIER_KEYS){switch(r.MODIFIER_KEYS[n]){case"Alt":o=2;break;case"Shift":o=4;break;case"Ctrl":o=1;break;default:o=8}n=-1}o&8&&(n===91||n===93)&&(n=-1);if(!o&&n===13)if(t.location||t.keyLocation===3){e(t,o,-n);if(t.defaultPrevented)return}if(i.isChromeOS&&o&8){e(t,o,n);if(t.defaultPrevented)return;o&=-9}return!!o||n in r.FUNCTION_KEYS||n in r.PRINTABLE_KEYS?e(t,o,n):!1}var r=e("./keys"),i=e("./useragent");t.addListener=function(e,t,n){if(e.addEventListener)return e.addEventListener(t,n,!1);if(e.attachEvent){var r=function(){n.call(e,window.event)};n._wrapper=r,e.attachEvent("on"+t,r)}},t.removeListener=function(e,t,n){if(e.removeEventListener)return e.removeEventListener(t,n,!1);e.detachEvent&&e.detachEvent("on"+t,n._wrapper||n)},t.stopEvent=function(e){return t.stopPropagation(e),t.preventDefault(e),!1},t.stopPropagation=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0},t.preventDefault=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1},t.getButton=function(e){return e.type=="dblclick"?0:e.type=="contextmenu"||i.isMac&&e.ctrlKey&&!e.altKey&&!e.shiftKey?2:e.preventDefault?e.button:{1:0,2:2,4:1}[e.button]},t.capture=function(e,n,r){function i(e){n&&n(e),r&&r(e),t.removeListener(document,"mousemove",n,!0),t.removeListener(document,"mouseup",i,!0),t.removeListener(document,"dragstart",i,!0)}return t.addListener(document,"mousemove",n,!0),t.addListener(document,"mouseup",i,!0),t.addListener(document,"dragstart",i,!0),i},t.addMouseWheelListener=function(e,n){"onmousewheel"in e?t.addListener(e,"mousewheel",function(e){var t=8;e.wheelDeltaX!==undefined?(e.wheelX=-e.wheelDeltaX/t,e.wheelY=-e.wheelDeltaY/t):(e.wheelX=0,e.wheelY=-e.wheelDelta/t),n(e)}):"onwheel"in e?t.addListener(e,"wheel",function(e){var t=.35;switch(e.deltaMode){case e.DOM_DELTA_PIXEL:e.wheelX=e.deltaX*t||0,e.wheelY=e.deltaY*t||0;break;case e.DOM_DELTA_LINE:case e.DOM_DELTA_PAGE:e.wheelX=(e.deltaX||0)*5,e.wheelY=(e.deltaY||0)*5}n(e)}):t.addListener(e,"DOMMouseScroll",function(e){e.axis&&e.axis==e.HORIZONTAL_AXIS?(e.wheelX=(e.detail||0)*5,e.wheelY=0):(e.wheelX=0,e.wheelY=(e.detail||0)*5),n(e)})},t.addMultiMouseDownListener=function(e,n,r,s){var o=0,u,a,f,l={2:"dblclick",3:"tripleclick",4:"quadclick"};t.addListener(e,"mousedown",function(e){t.getButton(e)!==0?o=0:e.detail>1?(o++,o>4&&(o=1)):o=1;if(i.isIE){var c=Math.abs(e.clientX-u)>5||Math.abs(e.clientY-a)>5;if(!f||c)o=1;f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),o==1&&(u=e.clientX,a=e.clientY)}r[s]("mousedown",e);if(o>4)o=0;else if(o>1)return r[s](l[o],e)}),i.isOldIE&&t.addListener(e,"dblclick",function(e){o=2,f&&clearTimeout(f),f=setTimeout(function(){f=null},n[o-1]||600),r[s]("mousedown",e),r[s](l[o],e)})};var s=!i.isMac||!i.isOpera||"KeyboardEvent"in window?function(e){return 0|(e.ctrlKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.metaKey?8:0)}:function(e){return 0|(e.metaKey?1:0)|(e.altKey?2:0)|(e.shiftKey?4:0)|(e.ctrlKey?8:0)};t.getModifierString=function(e){return r.KEY_MODS[s(e)]};var u=null,a=0;t.addCommandKeyListener=function(e,n){var r=t.addListener;if(i.isOldGecko||i.isOpera&&!("KeyboardEvent"in window)){var s=null;r(e,"keydown",function(e){s=e.keyCode}),r(e,"keypress",function(e){return o(n,e,s)})}else{var a=null;r(e,"keydown",function(e){u[e.keyCode]=!0;var t=o(n,e,e.keyCode);return a=e.defaultPrevented,t}),r(e,"keypress",function(e){a&&(e.ctrlKey||e.altKey||e.shiftKey||e.metaKey)&&(t.stopEvent(e),a=null)}),r(e,"keyup",function(e){u[e.keyCode]=null}),u||(u=Object.create(null),r(window,"focus",function(e){u=Object.create(null)}))}};if(window.postMessage&&!i.isOldIE){var f=1;t.nextTick=function(e,n){n=n||window;var r="zero-timeout-message-"+f;t.addListener(n,"message",function i(s){s.data==r&&(t.stopPropagation(s),t.removeListener(n,"message",i),e())}),n.postMessage(r,"*")}}t.nextFrame=window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame||window.oRequestAnimationFrame,t.nextFrame?t.nextFrame=t.nextFrame.bind(window):t.nextFrame=function(e){setTimeout(e,17)}}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]=="object"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("../lib/dom"),o=e("../lib/lang"),u=i.isChrome<18,a=i.isIE,f=function(e,t){function b(e){if(h)return;if(k)t=0,r=e?0:n.value.length-1;else var t=e?2:1,r=2;try{n.setSelectionRange(t,r)}catch(i){}}function w(){if(h)return;n.value=f,i.isWebKit&&y.schedule()}function q(){setTimeout(function(){p&&(n.style.cssText=p,p=""),t.renderer.$keepTextAreaAtCursor==null&&(t.renderer.$keepTextAreaAtCursor=!0,t.renderer.$moveTextAreaToCursor())},0)}var n=s.createElement("textarea");n.className="ace_text-input",i.isTouchPad&&n.setAttribute("x-palm-disable-auto-cap",!0),n.wrap="off",n.autocorrect="off",n.autocapitalize="off",n.spellcheck=!1,n.style.opacity="0",e.insertBefore(n,e.firstChild);var f="",l=!1,c=!1,h=!1,p="",d=!0;try{var v=document.activeElement===n}catch(m){}r.addListener(n,"blur",function(){t.onBlur(),v=!1}),r.addListener(n,"focus",function(){v=!0,t.onFocus(),b()}),this.focus=function(){n.focus()},this.blur=function(){n.blur()},this.isFocused=function(){return v};var g=o.delayedCall(function(){v&&b(d)}),y=o.delayedCall(function(){h||(n.value=f,v&&b())});i.isWebKit||t.addEventListener("changeSelection",function(){t.selection.isEmpty()!=d&&(d=!d,g.schedule())}),w(),v&&t.onFocus();var E=function(e){return e.selectionStart===0&&e.selectionEnd===e.value.length};!n.setSelectionRange&&n.createTextRange&&(n.setSelectionRange=function(e,t){var n=this.createTextRange();n.collapse(!0),n.moveStart("character",e),n.moveEnd("character",t),n.select()},E=function(e){try{var t=e.ownerDocument.selection.createRange()}catch(n){}return!t||t.parentElement()!=e?!1:t.text==e.value});if(i.isOldIE){var S=!1,x=function(e){if(S)return;var t=n.value;if(h||!t||t==f)return;if(e&&t==f[0])return T.schedule();A(t),S=!0,w(),S=!1},T=o.delayedCall(x);r.addListener(n,"propertychange",x);var N={13:1,27:1};r.addListener(n,"keyup",function(e){h&&(!n.value||N[e.keyCode])&&setTimeout(F,0);if((n.value.charCodeAt(0)||0)<129)return T.call();h?j():B()}),r.addListener(n,"keydown",function(e){T.schedule(50)})}var C=function(e){l?l=!1:E(n)?(t.selectAll(),b()):k&&b(t.selection.isEmpty())},k=null;this.setInputHandler=function(e){k=e},this.getInputHandler=function(){return k};var L=!1,A=function(e){k&&(e=k(e),k=null),c?(b(),e&&t.onPaste(e),c=!1):e==f.charAt(0)?L?t.execCommand("del",{source:"ace"}):t.execCommand("backspace",{source:"ace"}):(e.substring(0,2)==f?e=e.substr(2):e.charAt(0)==f.charAt(0)?e=e.substr(1):e.charAt(e.length-1)==f.charAt(0)&&(e=e.slice(0,-1)),e.charAt(e.length-1)==f.charAt(0)&&(e=e.slice(0,-1)),e&&t.onTextInput(e)),L&&(L=!1)},O=function(e){if(h)return;var t=n.value;A(t),w()},M=function(e,t){var n=e.clipboardData||window.clipboardData;if(!n||u)return;var r=a?"Text":"text/plain";return t?n.setData(r,t)!==!1:n.getData(r)},_=function(e,i){var s=t.getCopyText();if(!s)return r.preventDefault(e);M(e,s)?(i?t.onCut():t.onCopy(),r.preventDefault(e)):(l=!0,n.value=s,n.select(),setTimeout(function(){l=!1,w(),b(),i?t.onCut():t.onCopy()}))},D=function(e){_(e,!0)},P=function(e){_(e,!1)},H=function(e){var s=M(e);typeof s=="string"?(s&&t.onPaste(s),i.isIE&&setTimeout(b),r.preventDefault(e)):(n.value="",c=!0)};r.addCommandKeyListener(n,t.onCommandKey.bind(t)),r.addListener(n,"select",C),r.addListener(n,"input",O),r.addListener(n,"cut",D),r.addListener(n,"copy",P),r.addListener(n,"paste",H),(!("oncut"in n)||!("oncopy"in n)||!("onpaste"in n))&&r.addListener(e,"keydown",function(e){if(i.isMac&&!e.metaKey||!e.ctrlKey)return;switch(e.keyCode){case 67:P(e);break;case 86:H(e);break;case 88:D(e)}});var B=function(e){if(h||!t.onCompositionStart)return;h={},t.onCompositionStart(),setTimeout(j,0),t.on("mousedown",F),t.selection.isEmpty()||(t.insert(""),t.session.markUndoGroup(),t.selection.clearSelection()),t.session.markUndoGroup()},j=function(){if(!h||!t.onCompositionUpdate)return;var e=n.value.replace(/\x01/g,"");if(h.lastValue===e)return;t.onCompositionUpdate(e),h.lastValue&&t.undo(),h.lastValue=e;if(h.lastValue){var r=t.selection.getRange();t.insert(h.lastValue),t.session.markUndoGroup(),h.range=t.selection.getRange(),t.selection.setRange(r),t.selection.clearSelection()}},F=function(e){if(!t.onCompositionEnd)return;var r=h;h=!1;var i=setTimeout(function(){i=null;var e=n.value.replace(/\x01/g,"");if(h)return;e==r.lastValue?w():!r.lastValue&&e&&(w(),A(e))});k=function(n){return i&&clearTimeout(i),n=n.replace(/\x01/g,""),n==r.lastValue?"":(r.lastValue&&i&&t.undo(),n)},t.onCompositionEnd(),t.removeListener("mousedown",F),e.type=="compositionend"&&r.range&&t.selection.setRange(r.range)},I=o.delayedCall(j,50);r.addListener(n,"compositionstart",B),i.isGecko?r.addListener(n,"text",function(){I.schedule()}):(r.addListener(n,"keyup",function(){I.schedule()}),r.addListener(n,"keydown",function(){I.schedule()})),r.addListener(n,"compositionend",F),this.getElement=function(){return n},this.setReadOnly=function(e){n.readOnly=e},this.onContextMenu=function(e){L=!0,b(t.selection.isEmpty()),t._emit("nativecontextmenu",{target:t,domEvent:e}),this.moveToMouse(e,!0)},this.moveToMouse=function(e,o){p||(p=n.style.cssText),n.style.cssText=(o?"z-index:100000;":"")+(i.isIE?"opacity:0.1;":"");var u=t.container.getBoundingClientRect(),a=s.computedStyle(t.container),f=u.top+(parseInt(a.borderTopWidth)||0),l=u.left+(parseInt(u.borderLeftWidth)||0),c=u.bottom-f-n.clientHeight,h=function(e){n.style.left=e.clientX-l-2+"px",n.style.top=Math.min(e.clientY-f-2,c)+"px"};h(e);if(e.type!="mousedown")return;t.renderer.$keepTextAreaAtCursor&&(t.renderer.$keepTextAreaAtCursor=null),i.isWin&&r.capture(t.container,h,q)},this.onContextMenuClose=q;if(!i.isGecko||i.isMac){var R=function(e){t.textInput.onContextMenu(e),q()};r.addListener(t.renderer.scroller,"contextmenu",R),r.addListener(n,"contextmenu",R)}};t.TextInput=f}),ace.define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function u(e){e.$clickSelection=null;var t=e.editor;t.setDefaultHandler("mousedown",this.onMouseDown.bind(e)),t.setDefaultHandler("dblclick",this.onDoubleClick.bind(e)),t.setDefaultHandler("tripleclick",this.onTripleClick.bind(e)),t.setDefaultHandler("quadclick",this.onQuadClick.bind(e)),t.setDefaultHandler("mousewheel",this.onMouseWheel.bind(e));var n=["select","startSelect","selectEnd","selectAllEnd","selectByWordsEnd","selectByLinesEnd","dragWait","dragWaitEnd","focusWait"];n.forEach(function(t){e[t]=this[t]},this),e.selectByLines=this.extendSelectionBy.bind(e,"getLineRange"),e.selectByWords=this.extendSelectionBy.bind(e,"getWordRange")}function a(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}function f(e,t){if(e.start.row==e.end.row)var n=2*t.column-e.start.column-e.end.column;else if(e.start.row==e.end.row-1&&!e.start.column&&!e.end.column)var n=t.column-4;else var n=2*t.row-e.start.row-e.end.row;return n<0?{cursor:e.start,anchor:e.end}:{cursor:e.end,anchor:e.start}}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=0;(function(){this.onMouseDown=function(e){var t=e.inSelection(),n=e.getDocumentPosition();this.mousedownEvent=e;var r=this.editor,i=e.getButton();if(i!==0){var s=r.getSelectionRange(),o=s.isEmpty();o&&r.selection.moveToPosition(n),r.textInput.onContextMenu(e.domEvent);return}if(t&&!r.isFocused()){r.focus();if(this.$focusTimout&&!this.$clickSelection&&!r.inMultiSelectMode){this.mousedownEvent.time=Date.now(),this.setState("focusWait"),this.captureMouse(e);return}}return this.captureMouse(e),!t||this.$clickSelection||e.getShiftKey()||r.inMultiSelectMode?this.startSelect(n):t&&(this.mousedownEvent.time=Date.now(),this.startSelect(n)),e.preventDefault()},this.startSelect=function(e){e=e||this.editor.renderer.screenToTextCoordinates(this.x,this.y);var t=this.editor,n=this.mousedownEvent.getShiftKey();setTimeout(function(){n?t.selection.selectToPosition(e):this.$clickSelection||t.selection.moveToPosition(e),this.select()}.bind(this),0),t.renderer.scroller.setCapture&&t.renderer.scroller.setCapture(),t.setStyle("ace_selecting"),this.setState("select")},this.select=function(){var e,t=this.editor,n=t.renderer.screenToTextCoordinates(this.x,this.y);if(this.$clickSelection){var r=this.$clickSelection.comparePoint(n);if(r==-1)e=this.$clickSelection.end;else if(r==1)e=this.$clickSelection.start;else{var i=f(this.$clickSelection,n);n=i.cursor,e=i.anchor}t.selection.setSelectionAnchor(e.row,e.column)}t.selection.selectToPosition(n),t.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(e){var t,n=this.editor,r=n.renderer.screenToTextCoordinates(this.x,this.y),i=n.selection[e](r.row,r.column);if(this.$clickSelection){var s=this.$clickSelection.comparePoint(i.start),o=this.$clickSelection.comparePoint(i.end);if(s==-1&&o<=0){t=this.$clickSelection.end;if(i.end.row!=r.row||i.end.column!=r.column)r=i.start}else if(o==1&&s>=0){t=this.$clickSelection.start;if(i.start.row!=r.row||i.start.column!=r.column)r=i.end}else if(s==-1&&o==1)r=i.end,t=i.start;else{var u=f(this.$clickSelection,r);r=u.cursor,t=u.anchor}n.selection.setSelectionAnchor(t.row,t.column)}n.selection.selectToPosition(r),n.renderer.scrollCursorIntoView()},this.selectEnd=this.selectAllEnd=this.selectByWordsEnd=this.selectByLinesEnd=function(){this.$clickSelection=null,this.editor.unsetStyle("ace_selecting"),this.editor.renderer.scroller.releaseCapture&&this.editor.renderer.scroller.releaseCapture()},this.focusWait=function(){var e=a(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),t=Date.now();(e>o||t-this.mousedownEvent.time>this.$focusTimout)&&this.startSelect(this.mousedownEvent.getDocumentPosition())},this.onDoubleClick=function(e){var t=e.getDocumentPosition(),n=this.editor,r=n.session,i=r.getBracketRange(t);i?(i.isEmpty()&&(i.start.column--,i.end.column++),this.setState("select")):(i=n.selection.getWordRange(t.row,t.column),this.setState("selectByWords")),this.$clickSelection=i},this.onTripleClick=function(e){var t=e.getDocumentPosition(),n=this.editor;this.setState("selectByLines");var r=n.getSelectionRange();r.isMultiLine()&&r.contains(t.row,t.column)?(this.$clickSelection=n.selection.getLineRange(r.start.row),this.$clickSelection.end=n.selection.getLineRange(r.end.row).end):this.$clickSelection=n.selection.getLineRange(t.row)},this.onQuadClick=function(e){var t=this.editor;t.selectAll(),this.$clickSelection=t.getSelectionRange(),this.setState("selectAll")},this.onMouseWheel=function(e){if(e.getAccelKey())return;e.getShiftKey()&&e.wheelY&&!e.wheelX&&(e.wheelX=e.wheelY,e.wheelY=0);var t=e.domEvent.timeStamp,n=t-(this.$lastScrollTime||0),r=this.editor,i=r.renderer.isScrollableBy(e.wheelX*e.speed,e.wheelY*e.speed);if(i||n<200)return this.$lastScrollTime=t,r.renderer.scrollBy(e.wheelX*e.speed,e.wheelY*e.speed),e.stop()}}).call(u.prototype),t.DefaultHandlers=u}),ace.define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"],function(e,t,n){"use strict";function s(e){this.isOpen=!1,this.$element=null,this.$parentNode=e}var r=e("./lib/oop"),i=e("./lib/dom");(function(){this.$init=function(){return this.$element=i.createElement("div"),this.$element.className="ace_tooltip",this.$element.style.display="none",this.$parentNode.appendChild(this.$element),this.$element},this.getElement=function(){return this.$element||this.$init()},this.setText=function(e){i.setInnerText(this.getElement(),e)},this.setHtml=function(e){this.getElement().innerHTML=e},this.setPosition=function(e,t){this.getElement().style.left=e+"px",this.getElement().style.top=t+"px"},this.setClassName=function(e){i.addCssClass(this.getElement(),e)},this.show=function(e,t,n){e!=null&&this.setText(e),t!=null&&n!=null&&this.setPosition(t,n),this.isOpen||(this.getElement().style.display="block",this.isOpen=!0)},this.hide=function(){this.isOpen&&(this.getElement().style.display="none",this.isOpen=!1)},this.getHeight=function(){return this.getElement().offsetHeight},this.getWidth=function(){return this.getElement().offsetWidth}}).call(s.prototype),t.Tooltip=s}),ace.define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"],function(e,t,n){"use strict";function u(e){function l(){var r=u.getDocumentPosition().row,s=n.$annotations[r];if(!s)return c();var o=t.session.getLength();if(r==o){var a=t.renderer.pixelToScreenCoordinates(0,u.y).row,l=u.$pos;if(a>t.session.documentToScreenRow(l.row,l.column))return c()}if(f==s)return;f=s.text.join("<br/>"),i.setHtml(f),i.show(),t.on("mousewheel",c);if(e.$tooltipFollowsMouse)h(u);else{var p=n.$cells[t.session.documentToScreenRow(r,0)].element,d=p.getBoundingClientRect(),v=i.getElement().style;v.left=d.right+"px",v.top=d.bottom+"px"}}function c(){o&&(o=clearTimeout(o)),f&&(i.hide(),f=null,t.removeEventListener("mousewheel",c))}function h(e){i.setPosition(e.x,e.y)}var t=e.editor,n=t.renderer.$gutterLayer,i=new a(t.container);e.editor.setDefaultHandler("guttermousedown",function(r){if(!t.isFocused()||r.getButton()!=0)return;var i=n.getRegion(r);if(i=="foldWidgets")return;var s=r.getDocumentPosition().row,o=t.session.selection;if(r.getShiftKey())o.selectTo(s,0);else{if(r.domEvent.detail==2)return t.selectAll(),r.preventDefault();e.$clickSelection=t.selection.getLineRange(s)}return e.setState("selectByLines"),e.captureMouse(r),r.preventDefault()});var o,u,f;e.editor.setDefaultHandler("guttermousemove",function(t){var n=t.domEvent.target||t.domEvent.srcElement;if(r.hasCssClass(n,"ace_fold-widget"))return c();f&&e.$tooltipFollowsMouse&&h(t),u=t;if(o)return;o=setTimeout(function(){o=null,u&&!e.isMousePressed?l():c()},50)}),s.addListener(t.renderer.$gutter,"mouseout",function(e){u=null;if(!f||o)return;o=setTimeout(function(){o=null,c()},50)}),t.on("changeSession",c)}function a(e){o.call(this,e)}var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/event"),o=e("../tooltip").Tooltip;i.inherits(a,o),function(){this.setPosition=function(e,t){var n=window.innerWidth||document.documentElement.clientWidth,r=window.innerHeight||document.documentElement.clientHeight,i=this.getWidth(),s=this.getHeight();e+=15,t+=15,e+i>n&&(e-=e+i-n),t+s>r&&(t-=20+s),o.prototype.setPosition.call(this,e,t)}}.call(a.prototype),t.GutterHandler=u}),ace.define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=t.MouseEvent=function(e,t){this.domEvent=e,this.editor=t,this.x=this.clientX=e.clientX,this.y=this.clientY=e.clientY,this.$pos=null,this.$inSelection=null,this.propagationStopped=!1,this.defaultPrevented=!1};(function(){this.stopPropagation=function(){r.stopPropagation(this.domEvent),this.propagationStopped=!0},this.preventDefault=function(){r.preventDefault(this.domEvent),this.defaultPrevented=!0},this.stop=function(){this.stopPropagation(),this.preventDefault()},this.getDocumentPosition=function(){return this.$pos?this.$pos:(this.$pos=this.editor.renderer.screenToTextCoordinates(this.clientX,this.clientY),this.$pos)},this.inSelection=function(){if(this.$inSelection!==null)return this.$inSelection;var e=this.editor,t=e.getSelectionRange();if(t.isEmpty())this.$inSelection=!1;else{var n=this.getDocumentPosition();this.$inSelection=t.contains(n.row,n.column)}return this.$inSelection},this.getButton=function(){return r.getButton(this.domEvent)},this.getShiftKey=function(){return this.domEvent.shiftKey},this.getAccelKey=i.isMac?function(){return this.domEvent.metaKey}:function(){return this.domEvent.ctrlKey}}).call(s.prototype)}),ace.define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"],function(e,t,n){"use strict";function f(e){function T(e,n){var r=Date.now(),i=!n||e.row!=n.row,s=!n||e.column!=n.column;if(!S||i||s)t.$blockScrolling+=1,t.moveCursorToPosition(e),t.$blockScrolling-=1,S=r,x={x:p,y:d};else{var o=l(x.x,x.y,p,d);o>a?S=null:r-S>=u&&(t.renderer.scrollCursorIntoView(),S=null)}}function N(e,n){var r=Date.now(),i=t.renderer.layerConfig.lineHeight,s=t.renderer.layerConfig.characterWidth,u=t.renderer.scroller.getBoundingClientRect(),a={x:{left:p-u.left,right:u.right-p},y:{top:d-u.top,bottom:u.bottom-d}},f=Math.min(a.x.left,a.x.right),l=Math.min(a.y.top,a.y.bottom),c={row:e.row,column:e.column};f/s<=2&&(c.column+=a.x.left<a.x.right?-3:2),l/i<=1&&(c.row+=a.y.top<a.y.bottom?-1:1);var h=e.row!=c.row,v=e.column!=c.column,m=!n||e.row!=n.row;h||v&&!m?E?r-E>=o&&t.renderer.scrollCursorIntoView(c):E=r:E=null}function C(){var e=g;g=t.renderer.screenToTextCoordinates(p,d),T(g,e),N(g,e)}function k(){m=t.selection.toOrientedRange(),h=t.session.addMarker(m,"ace_selection",t.getSelectionStyle()),t.clearSelection(),t.isFocused()&&t.renderer.$cursorLayer.setBlinking(!1),clearInterval(v),v=setInterval(C,20),y=0,i.addListener(document,"mousemove",O)}function L(){clearInterval(v),t.session.removeMarker(h),h=null,t.$blockScrolling+=1,t.selection.fromOrientedRange(m),t.$blockScrolling-=1,t.isFocused()&&!w&&t.renderer.$cursorLayer.setBlinking(!t.getReadOnly()),m=null,y=0,E=null,S=null,i.removeListener(document,"mousemove",O)}function O(){A==null&&(A=setTimeout(function(){A!=null&&h&&L()},20))}function M(e){var t=e.types;return!t||Array.prototype.some.call(t,function(e){return e=="text/plain"||e=="Text"})}function _(e){var t=["copy","copymove","all","uninitialized"],n=["move","copymove","linkmove","all","uninitialized"],r=s.isMac?e.altKey:e.ctrlKey,i="uninitialized";try{i=e.dataTransfer.effectAllowed.toLowerCase()}catch(e){}var o="none";return r&&t.indexOf(i)>=0?o="copy":n.indexOf(i)>=0?o="move":t.indexOf(i)>=0&&(o="copy"),o}var t=e.editor,n=r.createElement("img");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",s.isOpera&&(n.style.cssText="width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;");var f=["dragWait","dragWaitEnd","startDrag","dragReadyEnd","onMouseDrag"];f.forEach(function(t){e[t]=this[t]},this),t.addEventListener("mousedown",this.onMouseDown.bind(e));var c=t.container,h,p,d,v,m,g,y=0,b,w,E,S,x;this.onDragStart=function(e){if(this.cancelDrag||!c.draggable){var r=this;return setTimeout(function(){r.startSelect(),r.captureMouse(e)},0),e.preventDefault()}m=t.getSelectionRange();var i=e.dataTransfer;i.effectAllowed=t.getReadOnly()?"copy":"copyMove",s.isOpera&&(t.container.appendChild(n),n._top=n.offsetTop),i.setDragImage&&i.setDragImage(n,0,0),s.isOpera&&t.container.removeChild(n),i.clearData(),i.setData("Text",t.session.getTextRange()),w=!0,this.setState("drag")},this.onDragEnd=function(e){c.draggable=!1,w=!1,this.setState(null);if(!t.getReadOnly()){var n=e.dataTransfer.dropEffect;!b&&n=="move"&&t.session.remove(t.getSelectionRange()),t.renderer.$cursorLayer.setBlinking(!0)}this.editor.unsetStyle("ace_dragging")},this.onDragEnter=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return h||k(),y++,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragOver=function(e){if(t.getReadOnly()||!M(e.dataTransfer))return;return h||(k(),y++),A!==null&&(A=null),p=e.clientX,d=e.clientY,e.dataTransfer.dropEffect=b=_(e),i.preventDefault(e)},this.onDragLeave=function(e){y--;if(y<=0&&h)return L(),b=null,i.preventDefault(e)},this.onDrop=function(e){if(!h)return;var n=e.dataTransfer;if(w)switch(b){case"move":m.contains(g.row,g.column)?m={start:g,end:g}:m=t.moveText(m,g);break;case"copy":m=t.moveText(m,g,!0)}else{var r=n.getData("Text");m={start:g,end:t.session.insert(g,r)},t.focus(),b=null}return L(),i.preventDefault(e)},i.addListener(c,"dragstart",this.onDragStart.bind(e)),i.addListener(c,"dragend",this.onDragEnd.bind(e)),i.addListener(c,"dragenter",this.onDragEnter.bind(e)),i.addListener(c,"dragover",this.onDragOver.bind(e)),i.addListener(c,"dragleave",this.onDragLeave.bind(e)),i.addListener(c,"drop",this.onDrop.bind(e));var A=null}function l(e,t,n,r){return Math.sqrt(Math.pow(n-e,2)+Math.pow(r-t,2))}var r=e("../lib/dom"),i=e("../lib/event"),s=e("../lib/useragent"),o=200,u=200,a=5;(function(){this.dragWait=function(){var e=Date.now()-this.mousedownEvent.time;e>this.editor.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(){var e=this.editor.container;e.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()),this.selectEnd()},this.dragReadyEnd=function(e){this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly()),this.editor.unsetStyle("ace_dragging"),this.dragWaitEnd()},this.startDrag=function(){this.cancelDrag=!1;var e=this.editor.container;e.draggable=!0,this.editor.renderer.$cursorLayer.setBlinking(!1),this.editor.setStyle("ace_dragging"),this.setState("dragReady")},this.onMouseDrag=function(e){var t=this.editor.container;if(s.isIE&&this.state=="dragReady"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>3&&t.dragDrop()}if(this.state==="dragWait"){var n=l(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y);n>0&&(t.draggable=!1,this.startSelect(this.mousedownEvent.getDocumentPosition()))}},this.onMouseDown=function(e){if(!this.$dragEnabled)return;this.mousedownEvent=e;var t=this.editor,n=e.inSelection(),r=e.getButton(),i=e.domEvent.detail||1;if(i===1&&r===0&&n){if(e.editor.inMultiSelectMode&&(e.getAccelKey()||e.getShiftKey()))return;this.mousedownEvent.time=Date.now();var o=e.domEvent.target||e.domEvent.srcElement;"unselectable"in o&&(o.unselectable="on");if(t.getDragDelay()){if(s.isWebKit){this.cancelDrag=!0;var u=t.container;u.draggable=!0}this.setState("dragWait")}else this.startDrag();this.captureMouse(e,this.onMouseDrag.bind(this)),e.defaultPrevented=!0}}}).call(f.prototype),t.DragdropHandler=f}),ace.define("ace/lib/net",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("./dom");t.get=function(e,t){var n=new XMLHttpRequest;n.open("GET",e,!0),n.onreadystatechange=function(){n.readyState===4&&t(n.responseText)},n.send(null)},t.loadScript=function(e,t){var n=r.getDocumentHead(),i=document.createElement("script");i.src=e,n.appendChild(i),i.onload=i.onreadystatechange=function(e,n){if(n||!i.readyState||i.readyState=="loaded"||i.readyState=="complete")i=i.onload=i.onreadystatechange=null,n||t()}},t.qualifyURL=function(e){var t=document.createElement("a");return t.href=e,t.href}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/config",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/lib/net","ace/lib/event_emitter"],function(e,t,n){"no use strict";function f(r){a.packaged=r||e.packaged||n.packaged||u.define&&define.packaged;if(!u.document)return"";var i={},s="",o=document.currentScript||document._currentScript,f=o&&o.ownerDocument||document,c=f.getElementsByTagName("script");for(var h=0;h<c.length;h++){var p=c[h],d=p.src||p.getAttribute("src");if(!d)continue;var v=p.attributes;for(var m=0,g=v.length;m<g;m++){var y=v[m];y.name.indexOf("data-ace-")===0&&(i[l(y.name.replace(/^data-ace-/,""))]=y.value)}var b=d.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/);b&&(s=b[1])}s&&(i.base=i.base||s,i.packaged=!0),i.basePath=i.base,i.workerPath=i.workerPath||i.base,i.modePath=i.modePath||i.base,i.themePath=i.themePath||i.base,delete i.base;for(var w in i)typeof i[w]!="undefined"&&t.set(w,i[w])}function l(e){return e.replace(/-(.)/g,function(e,t){return t.toUpperCase()})}var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./lib/net"),o=e("./lib/event_emitter").EventEmitter,u=function(){return this}(),a={packaged:!1,workerPath:null,modePath:null,themePath:null,basePath:"",suffix:".js",$moduleUrls:{}};t.get=function(e){if(!a.hasOwnProperty(e))throw new Error("Unknown config key: "+e);return a[e]},t.set=function(e,t){if(!a.hasOwnProperty(e))throw new Error("Unknown config key: "+e);a[e]=t},t.all=function(){return r.copyObject(a)},i.implement(t,o),t.moduleUrl=function(e,t){if(a.$moduleUrls[e])return a.$moduleUrls[e];var n=e.split("/");t=t||n[n.length-2]||"";var r=t=="snippets"?"/":"-",i=n[n.length-1];if(r=="-"){var s=new RegExp("^"+t+"[\\-_]|[\\-_]"+t+"$","g");i=i.replace(s,"")}(!i||i==t)&&n.length>1&&(i=n[n.length-2]);var o=a[t+"Path"];return o==null?o=a.basePath:r=="/"&&(t=r=""),o&&o.slice(-1)!="/"&&(o+="/"),o+t+r+i+this.get("suffix")},t.setModuleUrl=function(e,t){return a.$moduleUrls[e]=t},t.$loading={},t.loadModule=function(n,r){var i,o;Array.isArray(n)&&(o=n[0],n=n[1]);try{i=e(n)}catch(u){}if(i&&!t.$loading[n])return r&&r(i);t.$loading[n]||(t.$loading[n]=[]),t.$loading[n].push(r);if(t.$loading[n].length>1)return;var a=function(){e([n],function(e){t._emit("load.module",{name:n,module:e});var r=t.$loading[n];t.$loading[n]=null,r.forEach(function(t){t&&t(e)})})};if(!t.get("packaged"))return a();s.loadScript(t.moduleUrl(n,o),a)},t.init=f;var c={setOptions:function(e){Object.keys(e).forEach(function(t){this.setOption(t,e[t])},this)},getOptions:function(e){var t={};return e?Array.isArray(e)||(t=e,e=Object.keys(t)):e=Object.keys(this.$options),e.forEach(function(e){t[e]=this.getOption(e)},this),t},setOption:function(e,t){if(this["$"+e]===t)return;var n=this.$options[e];if(!n)return typeof console!="undefined"&&console.warn&&console.warn('misspelled option "'+e+'"'),undefined;if(n.forwardTo)return this[n.forwardTo]&&this[n.forwardTo].setOption(e,t);n.handlesSet||(this["$"+e]=t),n&&n.set&&n.set.call(this,t)},getOption:function(e){var t=this.$options[e];return t?t.forwardTo?this[t.forwardTo]&&this[t.forwardTo].getOption(e):t&&t.get?t.get.call(this):this["$"+e]:(typeof console!="undefined"&&console.warn&&console.warn('misspelled option "'+e+'"'),undefined)}},h={};t.defineOptions=function(e,t,n){return e.$options||(h[t]=e.$options={}),Object.keys(n).forEach(function(t){var r=n[t];typeof r=="string"&&(r={forwardTo:r}),r.name||(r.name=t),e.$options[r.name]=r,"initialValue"in r&&(e["$"+r.name]=r.initialValue)}),i.implement(e,c),this},t.resetOptions=function(e){Object.keys(e.$options).forEach(function(t){var n=e.$options[t];"value"in n&&e.setOption(t,n.value)})},t.setDefaultValue=function(e,n,r){var i=h[e]||(h[e]={});i[n]&&(i.forwardTo?t.setDefaultValue(i.forwardTo,n,r):i[n].value=r)},t.setDefaultValues=function(e,n){Object.keys(n).forEach(function(r){t.setDefaultValue(e,r,n[r])})}}),ace.define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event","ace/mouse/dragdrop_handler","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event"),i=e("../lib/useragent"),s=e("./default_handlers").DefaultHandlers,o=e("./default_gutter_handler").GutterHandler,u=e("./mouse_event").MouseEvent,a=e("./dragdrop_handler").DragdropHandler,f=e("../config"),l=function(e){var t=this;this.editor=e,new s(this),new o(this),new a(this);var n=function(t){!e.isFocused()&&e.textInput&&e.textInput.moveToMouse(t),e.focus()},u=e.renderer.getMouseEventTarget();r.addListener(u,"click",this.onMouseEvent.bind(this,"click")),r.addListener(u,"mousemove",this.onMouseMove.bind(this,"mousemove")),r.addMultiMouseDownListener(u,[400,300,250],this,"onMouseEvent"),e.renderer.scrollBarV&&(r.addMultiMouseDownListener(e.renderer.scrollBarV.inner,[400,300,250],this,"onMouseEvent"),r.addMultiMouseDownListener(e.renderer.scrollBarH.inner,[400,300,250],this,"onMouseEvent"),i.isIE&&(r.addListener(e.renderer.scrollBarV.element,"mousedown",n),r.addListener(e.renderer.scrollBarH.element,"mousemove",n))),r.addMouseWheelListener(e.container,this.onMouseWheel.bind(this,"mousewheel"));var f=e.renderer.$gutter;r.addListener(f,"mousedown",this.onMouseEvent.bind(this,"guttermousedown")),r.addListener(f,"click",this.onMouseEvent.bind(this,"gutterclick")),r.addListener(f,"dblclick",this.onMouseEvent.bind(this,"gutterdblclick")),r.addListener(f,"mousemove",this.onMouseEvent.bind(this,"guttermousemove")),r.addListener(u,"mousedown",n),r.addListener(f,"mousedown",function(t){return e.focus(),r.preventDefault(t)}),e.on("mousemove",function(n){if(t.state||t.$dragDelay||!t.$dragEnabled)return;var r=e.renderer.screenToTextCoordinates(n.x,n.y),i=e.session.selection.getRange(),s=e.renderer;!i.isEmpty()&&i.insideStart(r.row,r.column)?s.setCursorStyle("default"):s.setCursorStyle("")})};(function(){this.onMouseEvent=function(e,t){this.editor._emit(e,new u(t,this.editor))},this.onMouseMove=function(e,t){var n=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!n||!n.length)return;this.editor._emit(e,new u(t,this.editor))},this.onMouseWheel=function(e,t){var n=new u(t,this.editor);n.speed=this.$scrollSpeed*2,n.wheelX=t.wheelX,n.wheelY=t.wheelY,this.editor._emit(e,n)},this.setState=function(e){this.state=e},this.captureMouse=function(e,t){this.x=e.x,this.y=e.y,this.isMousePressed=!0;var n=this.editor.renderer;n.$keepTextAreaAtCursor&&(n.$keepTextAreaAtCursor=null);var s=this,o=function(e){if(!e)return;if(i.isWebKit&&!e.which&&s.releaseMouse)return s.releaseMouse();s.x=e.clientX,s.y=e.clientY,t&&t(e),s.mouseEvent=new u(e,s.editor),s.$mouseMoved=!0},a=function(e){clearInterval(l),f(),s[s.state+"End"]&&s[s.state+"End"](e),s.state="",n.$keepTextAreaAtCursor==null&&(n.$keepTextAreaAtCursor=!0,n.$moveTextAreaToCursor()),s.isMousePressed=!1,s.$onCaptureMouseMove=s.releaseMouse=null,e&&s.onMouseEvent("mouseup",e)},f=function(){s[s.state]&&s[s.state](),s.$mouseMoved=!1};if(i.isOldIE&&e.domEvent.type=="dblclick")return setTimeout(function(){a(e)});s.$onCaptureMouseMove=o,s.releaseMouse=r.capture(this.editor.container,o,a);var l=setInterval(f,20)},this.releaseMouse=null,this.cancelContextMenu=function(){var e=function(t){if(t&&t.domEvent&&t.domEvent.type!="contextmenu")return;this.editor.off("nativecontextmenu",e),t&&t.domEvent&&r.stopEvent(t.domEvent)}.bind(this);setTimeout(e,10),this.editor.on("nativecontextmenu",e)}}).call(l.prototype),f.defineOptions(l.prototype,"mouseHandler",{scrollSpeed:{initialValue:2},dragDelay:{initialValue:i.isMac?150:0},dragEnabled:{initialValue:!0},focusTimout:{initialValue:0},tooltipFollowsMouse:{initialValue:!0}}),t.MouseHandler=l}),ace.define("ace/mouse/fold_handler",["require","exports","module"],function(e,t,n){"use strict";function r(e){e.on("click",function(t){var n=t.getDocumentPosition(),r=e.session,i=r.getFoldAt(n.row,n.column,1);i&&(t.getAccelKey()?r.removeFold(i):r.expandFold(i),t.stop())}),e.on("gutterclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session;i.foldWidgets&&i.foldWidgets[r]&&e.session.onFoldWidgetClick(r,t),e.isFocused()||e.focus(),t.stop()}}),e.on("gutterdblclick",function(t){var n=e.renderer.$gutterLayer.getRegion(t);if(n=="foldWidgets"){var r=t.getDocumentPosition().row,i=e.session,s=i.getParentFoldRangeData(r,!0),o=s.range||s.firstRange;if(o){r=o.start.row;var u=i.getFoldAt(r,i.getLine(r).length,1);u?i.removeFold(u):(i.addFold("...",o),e.renderer.scrollCursorIntoView({row:o.start.row,column:0}))}t.stop()}})}t.FoldHandler=r}),ace.define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"],function(e,t,n){"use strict";var r=e("../lib/keys"),i=e("../lib/event"),s=function(e){this.$editor=e,this.$data={editor:e},this.$handlers=[],this.setDefaultHandler(e.commands)};(function(){this.setDefaultHandler=function(e){this.removeKeyboardHandler(this.$defaultHandler),this.$defaultHandler=e,this.addKeyboardHandler(e,0)},this.setKeyboardHandler=function(e){var t=this.$handlers;if(t[t.length-1]==e)return;while(t[t.length-1]&&t[t.length-1]!=this.$defaultHandler)this.removeKeyboardHandler(t[t.length-1]);this.addKeyboardHandler(e,1)},this.addKeyboardHandler=function(e,t){if(!e)return;typeof e=="function"&&!e.handleKeyboard&&(e.handleKeyboard=e);var n=this.$handlers.indexOf(e);n!=-1&&this.$handlers.splice(n,1),t==undefined?this.$handlers.push(e):this.$handlers.splice(t,0,e),n==-1&&e.attach&&e.attach(this.$editor)},this.removeKeyboardHandler=function(e){var t=this.$handlers.indexOf(e);return t==-1?!1:(this.$handlers.splice(t,1),e.detach&&e.detach(this.$editor),!0)},this.getKeyboardHandler=function(){return this.$handlers[this.$handlers.length-1]},this.$callKeyboardHandlers=function(e,t,n,r){var s,o=!1,u=this.$editor.commands;for(var a=this.$handlers.length;a--;){s=this.$handlers[a].handleKeyboard(this.$data,e,t,n,r);if(!s||!s.command)continue;s.command=="null"?o=!0:o=u.exec(s.command,this.$editor,s.args,r),o&&r&&e!=-1&&s.passEvent!=1&&s.command.passEvent!=1&&i.stopEvent(r);if(o)break}return o},this.onCommandKey=function(e,t,n){var i=r.keyCodeToString(n);this.$callKeyboardHandlers(t,i,n,e)},this.onTextInput=function(e){var t=this.$callKeyboardHandlers(-1,e);t||this.$editor.commands.exec("insertstring",this.$editor,e)}}).call(s.prototype),t.KeyBinding=s}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/lang"),s=e("./lib/event_emitter").EventEmitter,o=e("./range").Range,u=function(e){this.session=e,this.doc=e.getDocument(),this.clearSelection(),this.lead=this.selectionLead=this.doc.createAnchor(0,0),this.anchor=this.selectionAnchor=this.doc.createAnchor(0,0);var t=this;this.lead.on("change",function(e){t._emit("changeCursor"),t.$isEmpty||t._emit("changeSelection"),!t.$keepDesiredColumnOnChange&&e.old.column!=e.value.column&&(t.$desiredColumn=null)}),this.selectionAnchor.on("change",function(){t.$isEmpty||t._emit("changeSelection")})};(function(){r.implement(this,s),this.isEmpty=function(){return this.$isEmpty||this.anchor.row==this.lead.row&&this.anchor.column==this.lead.column},this.isMultiLine=function(){return this.isEmpty()?!1:this.getRange().isMultiLine()},this.getCursor=function(){return this.lead.getPosition()},this.setSelectionAnchor=function(e,t){this.anchor.setPosition(e,t),this.$isEmpty&&(this.$isEmpty=!1,this._emit("changeSelection"))},this.getSelectionAnchor=function(){return this.$isEmpty?this.getSelectionLead():this.anchor.getPosition()},this.getSelectionLead=function(){return this.lead.getPosition()},this.shiftSelection=function(e){if(this.$isEmpty){this.moveCursorTo(this.lead.row,this.lead.column+e);return}var t=this.getSelectionAnchor(),n=this.getSelectionLead(),r=this.isBackwards();(!r||t.column!==0)&&this.setSelectionAnchor(t.row,t.column+e),(r||n.column!==0)&&this.$moveSelection(function(){this.moveCursorTo(n.row,n.column+e)})},this.isBackwards=function(){var e=this.anchor,t=this.lead;return e.row>t.row||e.row==t.row&&e.column>t.column},this.getRange=function(){var e=this.anchor,t=this.lead;return this.isEmpty()?o.fromPoints(t,t):this.isBackwards()?o.fromPoints(t,e):o.fromPoints(e,t)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit("changeSelection"))},this.selectAll=function(){var e=this.doc.getLength()-1;this.setSelectionAnchor(0,0),this.moveCursorTo(e,this.doc.getLine(e).length)},this.setRange=this.setSelectionRange=function(e,t){t?(this.setSelectionAnchor(e.end.row,e.end.column),this.selectTo(e.start.row,e.start.column)):(this.setSelectionAnchor(e.start.row,e.start.column),this.selectTo(e.end.row,e.end.column)),this.getRange().isEmpty()&&(this.$isEmpty=!0),this.$desiredColumn=null},this.$moveSelection=function(e){var t=this.lead;this.$isEmpty&&this.setSelectionAnchor(t.row,t.column),e.call(this)},this.selectTo=function(e,t){this.$moveSelection(function(){this.moveCursorTo(e,t)})},this.selectToPosition=function(e){this.$moveSelection(function(){this.moveCursorToPosition(e)})},this.moveTo=function(e,t){this.clearSelection(),this.moveCursorTo(e,t)},this.moveToPosition=function(e){this.clearSelection(),this.moveCursorToPosition(e)},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.getWordRange=function(e,t){if(typeof t=="undefined"){var n=e||this.lead;e=n.row,t=n.column}return this.session.getWordRange(e,t)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var e=this.getCursor(),t=this.session.getAWordRange(e.row,e.column);this.setSelectionRange(t)},this.getLineRange=function(e,t){var n=typeof e=="number"?e:this.lead.row,r,i=this.session.getFoldLine(n);return i?(n=i.start.row,r=i.end.row):r=n,t===!0?new o(n,0,r,this.session.getLine(r).length):new o(n,0,r+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,-1))this.moveCursorTo(t.start.row,t.start.column);else if(e.column==0)e.row>0&&this.moveCursorTo(e.row-1,this.doc.getLine(e.row-1).length);else{var n=this.session.getTabSize();this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(e.column-n,e.column).split(" ").length-1==n?this.moveCursorBy(0,-n):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var e=this.lead.getPosition(),t;if(t=this.session.getFoldAt(e.row,e.column,1))this.moveCursorTo(t.end.row,t.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.row<this.doc.getLength()-1&&this.moveCursorTo(this.lead.row+1,0);else{var n=this.session.getTabSize(),e=this.lead;this.session.isTabStop(e)&&this.doc.getLine(e.row).slice(e.column,e.column+n).split(" ").length-1==n?this.moveCursorBy(0,n):this.moveCursorBy(0,1)}},this.moveCursorLineStart=function(){var e=this.lead.row,t=this.lead.column,n=this.session.documentToScreenRow(e,t),r=this.session.screenToDocumentPosition(n,0),i=this.session.getDisplayLine(e,null,r.row,r.column),s=i.match(/^\s*/);s[0].length!=t&&!this.session.$useEmacsStyleLineStart&&(r.column+=s[0].length),this.moveCursorToPosition(r)},this.moveCursorLineEnd=function(){var e=this.lead,t=this.session.getDocumentLastRowColumnPosition(e.row,e.column);if(this.lead.column==t.column){var n=this.session.getLine(t.row);if(t.column==n.length){var r=n.search(/\s+$/);r>0&&(t.column=r)}}this.moveCursorTo(t.row,t.column)},this.moveCursorFileEnd=function(){var e=this.doc.getLength()-1,t=this.doc.getLine(e).length;this.moveCursorTo(e,t)},this.moveCursorFileStart=function(){this.moveCursorTo(0,0)},this.moveCursorLongWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i;this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;var s=this.session.getFoldAt(e,t,1);if(s){this.moveCursorTo(s.end.row,s.end.column);return}if(i=this.session.nonTokenRe.exec(r))t+=this.session.nonTokenRe.lastIndex,this.session.nonTokenRe.lastIndex=0,r=n.substring(t);if(t>=n.length){this.moveCursorTo(e,n.length),this.moveCursorRight(),e<this.doc.getLength()-1&&this.moveCursorWordRight();return}if(i=this.session.tokenRe.exec(r))t+=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(e,t)},this.moveCursorLongWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1)){this.moveCursorTo(n.start.row,n.start.column);return}var r=this.session.getFoldStringAt(e,t,-1);r==null&&(r=this.doc.getLine(e).substring(0,t));var s=i.stringReverse(r),o;this.session.nonTokenRe.lastIndex=0,this.session.tokenRe.lastIndex=0;if(o=this.session.nonTokenRe.exec(s))t-=this.session.nonTokenRe.lastIndex,s=s.slice(this.session.nonTokenRe.lastIndex),this.session.nonTokenRe.lastIndex=0;if(t<=0){this.moveCursorTo(e,0),this.moveCursorLeft(),e>0&&this.moveCursorWordLeft();return}if(o=this.session.tokenRe.exec(s))t-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(e,t)},this.$shortWordEndIndex=function(e){var t,n=0,r,i=/\s/,s=this.session.tokenRe;s.lastIndex=0;if(t=this.session.tokenRe.exec(e))n=this.session.tokenRe.lastIndex;else{while((r=e[n])&&i.test(r))n++;if(n<1){s.lastIndex=0;while((r=e[n])&&!s.test(r)){s.lastIndex=0,n++;if(i.test(r)){if(n>2){n--;break}while((r=e[n])&&i.test(r))n++;if(n>2)break}}}}return s.lastIndex=0,n},this.moveCursorShortWordRight=function(){var e=this.lead.row,t=this.lead.column,n=this.doc.getLine(e),r=n.substring(t),i=this.session.getFoldAt(e,t,1);if(i)return this.moveCursorTo(i.end.row,i.end.column);if(t==n.length){var s=this.doc.getLength();do e++,r=this.doc.getLine(e);while(e<s&&/^\s*$/.test(r));/^\s+/.test(r)||(r=""),t=0}var o=this.$shortWordEndIndex(r);this.moveCursorTo(e,t+o)},this.moveCursorShortWordLeft=function(){var e=this.lead.row,t=this.lead.column,n;if(n=this.session.getFoldAt(e,t,-1))return this.moveCursorTo(n.start.row,n.start.column);var r=this.session.getLine(e).substring(0,t);if(t==0){do e--,r=this.doc.getLine(e);while(e>0&&/^\s*$/.test(r));t=r.length,/\s+$/.test(r)||(r="")}var s=i.stringReverse(r),o=this.$shortWordEndIndex(s);return this.moveCursorTo(e,t-o)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(e,t){var n=this.session.documentToScreenPosition(this.lead.row,this.lead.column);t===0&&(this.$desiredColumn?n.column=this.$desiredColumn:this.$desiredColumn=n.column);var r=this.session.screenToDocumentPosition(n.row+e,n.column);e!==0&&t===0&&r.row===this.lead.row&&r.column===this.lead.column&&this.session.lineWidgets&&this.session.lineWidgets[r.row]&&r.row++,this.moveCursorTo(r.row,r.column+t,t===0)},this.moveCursorToPosition=function(e){this.moveCursorTo(e.row,e.column)},this.moveCursorTo=function(e,t,n){var r=this.session.getFoldAt(e,t,1);r&&(e=r.start.row,t=r.start.column),this.$keepDesiredColumnOnChange=!0,this.lead.setPosition(e,t),this.$keepDesiredColumnOnChange=!1,n||(this.$desiredColumn=null)},this.moveCursorToScreen=function(e,t,n){var r=this.session.screenToDocumentPosition(e,t);this.moveCursorTo(r.row,r.column,n)},this.detach=function(){this.lead.detach(),this.anchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(e){this.setSelectionRange(e,e.cursor==e.start),this.$desiredColumn=e.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(e){var t=this.getRange();return e?(e.start.column=t.start.column,e.start.row=t.start.row,e.end.column=t.end.column,e.end.row=t.end.row):e=t,e.cursor=this.isBackwards()?e.start:e.end,e.desiredColumn=this.$desiredColumn,e},this.getRangeOfMovements=function(e){var t=this.getCursor();try{e.call(null,this);var n=this.getCursor();return o.fromPoints(t,n)}catch(r){return o.fromPoints(t,t)}finally{this.moveCursorToPosition(t)}},this.toJSON=function(){if(this.rangeCount)var e=this.ranges.map(function(e){var t=e.clone();return t.isBackwards=e.cursor==e.start,t});else{var e=this.getRange();e.isBackwards=this.isBackwards()}return e},this.fromJSON=function(e){if(e.start==undefined){if(this.rangeList){this.toSingleRange(e[0]);for(var t=e.length;t--;){var n=o.fromPoints(e[t].start,e[t].end);e.isBackwards&&(n.cursor=n.start),this.addRange(n,!0)}return}e=e[0]}this.rangeList&&this.toSingleRange(e),this.setSelectionRange(e,e.isBackwards)},this.isEqual=function(e){if((e.length||this.rangeCount)&&e.length!=this.rangeCount)return!1;if(!e.length||!this.ranges)return this.getRange().isEqual(e);for(var t=this.ranges.length;t--;)if(!this.ranges[t].isEqual(e[t]))return!1;return!0}}).call(u.prototype),t.Selection=u}),ace.define("ace/tokenizer",["require","exports","module"],function(e,t,n){"use strict";var r=1e3,i=function(e){this.states=e,this.regExps={},this.matchMappings={};for(var t in this.states){var n=this.states[t],r=[],i=0,s=this.matchMappings[t]={defaultToken:"text"},o="g",u=[];for(var a=0;a<n.length;a++){var f=n[a];f.defaultToken&&(s.defaultToken=f.defaultToken),f.caseInsensitive&&(o="gi");if(f.regex==null)continue;f.regex instanceof RegExp&&(f.regex=f.regex.toString().slice(1,-1));var l=f.regex,c=(new RegExp("(?:("+l+")|(.))")).exec("a").length-2;if(Array.isArray(f.token))if(f.token.length==1||c==1)f.token=f.token[0];else{if(c-1!=f.token.length)throw new Error("number of classes and regexp groups in '"+f.token+"'\n'"+f.regex+"' doesn't match\n"+(c-1)+"!="+f.token.length);f.tokenArray=f.token,f.token=null,f.onMatch=this.$arrayTokens}else typeof f.token=="function"&&!f.onMatch&&(c>1?f.onMatch=this.$applyToken:f.onMatch=f.token);c>1&&(/\\\d/.test(f.regex)?l=f.regex.replace(/\\([0-9]+)/g,function(e,t){return"\\"+(parseInt(t,10)+i+1)}):(c=1,l=this.removeCapturingGroups(f.regex)),!f.splitRegex&&typeof f.token!="string"&&u.push(f)),s[i]=a,i+=c,r.push(l),f.onMatch||(f.onMatch=null)}r.length||(s[0]=0,r.push("$")),u.forEach(function(e){e.splitRegex=this.createSplitterRegexp(e.regex,o)},this),this.regExps[t]=new RegExp("("+r.join(")|(")+")|($)",o)}};(function(){this.$setMaxTokenCount=function(e){r=e|0},this.$applyToken=function(e){var t=this.splitRegex.exec(e).slice(1),n=this.token.apply(this,t);if(typeof n=="string")return[{type:n,value:e}];var r=[];for(var i=0,s=n.length;i<s;i++)t[i]&&(r[r.length]={type:n[i],value:t[i]});return r},this.$arrayTokens=function(e){if(!e)return[];var t=this.splitRegex.exec(e);if(!t)return"text";var n=[],r=this.tokenArray;for(var i=0,s=r.length;i<s;i++)t[i+1]&&(n[n.length]={type:r[i],value:t[i+1]});return n},this.removeCapturingGroups=function(e){var t=e.replace(/\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g,function(e,t){return t?"(?:":e});return t},this.createSplitterRegexp=function(e,t){if(e.indexOf("(?=")!=-1){var n=0,r=!1,i={};e.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g,function(e,t,s,o,u,a){return r?r=u!="]":u?r=!0:o?(n==i.stack&&(i.end=a+1,i.stack=-1),n--):s&&(n++,s.length!=1&&(i.stack=n,i.start=a)),e}),i.end!=null&&/^\)*$/.test(e.substr(i.end))&&(e=e.substring(0,i.start)+e.substr(i.end))}return new RegExp(e,(t||"").replace("g",""))},this.getLineTokens=function(e,t){if(t&&typeof t!="string"){var n=t.slice(0);t=n[0]}else var n=[];var i=t||"start",s=this.states[i];s||(i="start",s=this.states[i]);var o=this.matchMappings[i],u=this.regExps[i];u.lastIndex=0;var a,f=[],l=0,c={type:null,value:""};while(a=u.exec(e)){var h=o.defaultToken,p=null,d=a[0],v=u.lastIndex;if(v-d.length>l){var m=e.substring(l,v-d.length);c.type==h?c.value+=m:(c.type&&f.push(c),c={type:h,value:m})}for(var g=0;g<a.length-2;g++){if(a[g+1]===undefined)continue;p=s[o[g]],p.onMatch?h=p.onMatch(d,i,n):h=p.token,p.next&&(typeof p.next=="string"?i=p.next:i=p.next(i,n),s=this.states[i],s||(window.console&&console.error&&console.error(i,"doesn't exist"),i="start",s=this.states[i]),o=this.matchMappings[i],l=v,u=this.regExps[i],u.lastIndex=v);break}if(d)if(typeof h=="string")!!p&&p.merge===!1||c.type!==h?(c.type&&f.push(c),c={type:h,value:d}):c.value+=d;else if(h){c.type&&f.push(c),c={type:null,value:""};for(var g=0;g<h.length;g++)f.push(h[g])}if(l==e.length)break;l=v;if(f.length>r){while(l<e.length)c.type&&f.push(c),c={value:e.substring(l,l+=2e3),type:"overflow"};i="start",n=[];break}}return c.type&&f.push(c),n.length>1&&n[0]!==i&&n.unshift(i),{tokens:f,state:n.length?n:i}}}).call(i.prototype),t.Tokenizer=i}),ace.define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../lib/lang"),i=function(){this.$rules={start:[{token:"empty_line",regex:"^$"},{defaultToken:"text"}]}};(function(){this.addRules=function(e,t){if(!t){for(var n in e)this.$rules[n]=e[n];return}for(var n in e){var r=e[n];for(var i=0;i<r.length;i++){var s=r[i];s.next&&(typeof s.next!="string"?s.nextState&&s.nextState.indexOf(t)!==0&&(s.nextState=t+s.nextState):s.next.indexOf(t)!==0&&(s.next=t+s.next))}this.$rules[t+n]=r}},this.getRules=function(){return this.$rules},this.embedRules=function(e,t,n,i,s){var o=typeof e=="function"?(new e).getRules():e;if(i)for(var u=0;u<i.length;u++)i[u]=t+i[u];else{i=[];for(var a in o)i.push(t+a)}this.addRules(o,t);if(n){var f=Array.prototype[s?"push":"unshift"];for(var u=0;u<i.length;u++)f.apply(this.$rules[i[u]],r.deepCopy(n))}this.$embeds||(this.$embeds=[]),this.$embeds.push(t)},this.getEmbeds=function(){return this.$embeds};var e=function(e,t){return(e!="start"||t.length)&&t.unshift(this.nextState,e),this.nextState},t=function(e,t){return t.shift(),t.shift()||"start"};this.normalizeRules=function(){function i(s){var o=r[s];o.processed=!0;for(var u=0;u<o.length;u++){var a=o[u];!a.regex&&a.start&&(a.regex=a.start,a.next||(a.next=[]),a.next.push({defaultToken:a.token},{token:a.token+".end",regex:a.end||a.start,next:"pop"}),a.token=a.token+".start",a.push=!0);var f=a.next||a.push;if(f&&Array.isArray(f)){var l=a.stateName;l||(l=a.token,typeof l!="string"&&(l=l[0]||""),r[l]&&(l+=n++)),r[l]=f,a.next=l,i(l)}else f=="pop"&&(a.next=t);a.push&&(a.nextState=a.next||a.push,a.next=e,delete a.push);if(a.rules)for(var c in a.rules)r[c]?r[c].push&&r[c].push.apply(r[c],a.rules[c]):r[c]=a.rules[c];if(a.include||typeof a=="string")var h=a.include||a,p=r[h];else Array.isArray(a)&&(p=a);if(p){var d=[u,1].concat(p);a.noEscape&&(d=d.filter(function(e){return!e.next})),o.splice.apply(o,d),u--,p=null}a.keywordMap&&(a.token=this.createKeywordMapper(a.keywordMap,a.defaultToken||"text",a.caseInsensitive),delete a.defaultToken)}}var n=0,r=this.$rules;Object.keys(r).forEach(i,this)},this.createKeywordMapper=function(e,t,n,r){var i=Object.create(null);return Object.keys(e).forEach(function(t){var s=e[t];n&&(s=s.toLowerCase());var o=s.split(r||"|");for(var u=o.length;u--;)i[o[u]]=t}),Object.getPrototypeOf(i)&&(i.__proto__=null),this.$keywordList=Object.keys(i),e=null,n?function(e){return i[e.toLowerCase()]||t}:function(e){return i[e]||t}},this.getKeywords=function(){return this.$keywords}}).call(i.prototype),t.TextHighlightRules=i}),ace.define("ace/mode/behaviour",["require","exports","module"],function(e,t,n){"use strict";var r=function(){this.$behaviours={}};(function(){this.add=function(e,t,n){switch(undefined){case this.$behaviours:this.$behaviours={};case this.$behaviours[e]:this.$behaviours[e]={}}this.$behaviours[e][t]=n},this.addBehaviours=function(e){for(var t in e)for(var n in e[t])this.add(t,n,e[t][n])},this.remove=function(e){this.$behaviours&&this.$behaviours[e]&&delete this.$behaviours[e]},this.inherit=function(e,t){if(typeof e=="function")var n=(new e).getBehaviours(t);else var n=e.getBehaviours(t);this.addBehaviours(n)},this.getBehaviours=function(e){if(!e)return this.$behaviours;var t={};for(var n=0;n<e.length;n++)this.$behaviours[e[n]]&&(t[e[n]]=this.$behaviours[e[n]]);return t}}).call(r.prototype),t.Behaviour=r}),ace.define("ace/unicode",["require","exports","module"],function(e,t,n){"use strict";function r(e){var n=/\w{4}/g;for(var r in e)t.packages[r]=e[r].replace(n,"\\u$&")}t.packages={},r({L:"0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",Ll:"0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A",Lu:"0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A",Lt:"01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",Lm:"02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",Lo:"01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",M:"0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26",Mn:"0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26",Mc:"0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC",Me:"0488048906DE20DD-20E020E2-20E4A670-A672",N:"0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",Nd:"0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",Nl:"16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",No:"00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",P:"0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65",Pd:"002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",Ps:"0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",Pe:"0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",Pi:"00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",Pf:"00BB2019201D203A2E032E052E0A2E0D2E1D2E21",Pc:"005F203F20402054FE33FE34FE4D-FE4FFF3F",Po:"0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65",S:"0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD",Sm:"002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC",Sc:"002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",Sk:"005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",So:"00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD",Z:"002000A01680180E2000-200A20282029202F205F3000",Zs:"002000A01680180E2000-200A202F205F3000",Zl:"2028",Zp:"2029",C:"0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF",Cc:"0000-001F007F-009F",Cf:"00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",Co:"E000-F8FF",Cs:"D800-DFFF",Cn:"03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF"})}),ace.define("ace/token_iterator",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t,n){this.$session=e,this.$row=t,this.$rowTokens=e.getTokens(t);var r=e.getTokenAt(t,n);this.$tokenIndex=r?r.index:-1};(function(){this.stepBackward=function(){this.$tokenIndex-=1;while(this.$tokenIndex<0){this.$row-=1;if(this.$row<0)return this.$row=0,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=this.$rowTokens.length-1}return this.$rowTokens[this.$tokenIndex]},this.stepForward=function(){this.$tokenIndex+=1;var e;while(this.$tokenIndex>=this.$rowTokens.length){this.$row+=1,e||(e=this.$session.getLength());if(this.$row>=e)return this.$row=e-1,null;this.$rowTokens=this.$session.getTokens(this.$row),this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var e=this.$rowTokens,t=this.$tokenIndex,n=e[t].start;if(n!==undefined)return n;n=0;while(t>0)t-=1,n+=e[t].value.length;return n}}).call(r.prototype),t.TokenIterator=r}),ace.define("ace/mode/text",["require","exports","module","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour","ace/unicode","ace/lib/lang","ace/token_iterator","ace/range"],function(e,t,n){"use strict";var r=e("../tokenizer").Tokenizer,i=e("./text_highlight_rules").TextHighlightRules,s=e("./behaviour").Behaviour,o=e("../unicode"),u=e("../lib/lang"),a=e("../token_iterator").TokenIterator,f=e("../range").Range,l=function(){this.HighlightRules=i,this.$behaviour=new s};(function(){this.tokenRe=new RegExp("^["+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+"\\$_]+","g"),this.nonTokenRe=new RegExp("^(?:[^"+o.packages.L+o.packages.Mn+o.packages.Mc+o.packages.Nd+o.packages.Pc+"\\$_]|\\s])+","g"),this.getTokenizer=function(){return this.$tokenizer||(this.$highlightRules=this.$highlightRules||new this.HighlightRules,this.$tokenizer=new r(this.$highlightRules.getRules())),this.$tokenizer},this.lineCommentStart="",this.blockComment="",this.toggleCommentLines=function(e,t,n,r){function w(e){for(var t=n;t<=r;t++)e(i.getLine(t),t)}var i=t.doc,s=!0,o=!0,a=Infinity,f=t.getTabSize(),l=!1;if(!this.lineCommentStart){if(!this.blockComment)return!1;var c=this.blockComment.start,h=this.blockComment.end,p=new RegExp("^(\\s*)(?:"+u.escapeRegExp(c)+")"),d=new RegExp("(?:"+u.escapeRegExp(h)+")\\s*$"),v=function(e,t){if(g(e,t))return;if(!s||/\S/.test(e))i.insertInLine({row:t,column:e.length},h),i.insertInLine({row:t,column:a},c)},m=function(e,t){var n;(n=e.match(d))&&i.removeInLine(t,e.length-n[0].length,e.length),(n=e.match(p))&&i.removeInLine(t,n[1].length,n[0].length)},g=function(e,n){if(p.test(e))return!0;var r=t.getTokens(n);for(var i=0;i<r.length;i++)if(r[i].type==="comment")return!0}}else{if(Array.isArray(this.lineCommentStart))var p=this.lineCommentStart.map(u.escapeRegExp).join("|"),c=this.lineCommentStart[0];else var p=u.escapeRegExp(this.lineCommentStart),c=this.lineCommentStart;p=new RegExp("^(\\s*)(?:"+p+") ?"),l=t.getUseSoftTabs();var m=function(e,t){var n=e.match(p);if(!n)return;var r=n[1].length,s=n[0].length;!b(e,r,s)&&n[0][s-1]==" "&&s--,i.removeInLine(t,r,s)},y=c+" ",v=function(e,t){if(!s||/\S/.test(e))b(e,a,a)?i.insertInLine({row:t,column:a},y):i.insertInLine({row:t,column:a},c)},g=function(e,t){return p.test(e)},b=function(e,t,n){var r=0;while(t--&&e.charAt(t)==" ")r++;if(r%f!=0)return!1;var r=0;while(e.charAt(n++)==" ")r++;return f>2?r%f!=f-1:r%f==0}}var E=Infinity;w(function(e,t){var n=e.search(/\S/);n!==-1?(n<a&&(a=n),o&&!g(e,t)&&(o=!1)):E>e.length&&(E=e.length)}),a==Infinity&&(a=E,s=!1,o=!1),l&&a%f!=0&&(a=Math.floor(a/f)*f),w(o?m:v)},this.toggleBlockComment=function(e,t,n,r){var i=this.blockComment;if(!i)return;!i.start&&i[0]&&(i=i[0]);var s=new a(t,r.row,r.column),o=s.getCurrentToken(),u=t.selection,l=t.selection.toOrientedRange(),c,h;if(o&&/comment/.test(o.type)){var p,d;while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.start);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;p=new f(m,g,m,g+i.start.length);break}o=s.stepBackward()}var s=new a(t,r.row,r.column),o=s.getCurrentToken();while(o&&/comment/.test(o.type)){var v=o.value.indexOf(i.end);if(v!=-1){var m=s.getCurrentTokenRow(),g=s.getCurrentTokenColumn()+v;d=new f(m,g,m,g+i.end.length);break}o=s.stepForward()}d&&t.remove(d),p&&(t.remove(p),c=p.start.row,h=-i.start.length)}else h=i.start.length,c=n.start.row,t.insert(n.end,i.end),t.insert(n.start,i.start);l.start.row==c&&(l.start.column+=h),l.end.row==c&&(l.end.column+=h),t.selection.fromOrientedRange(l)},this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.autoOutdent=function(e,t,n){},this.$getIndent=function(e){return e.match(/^\s*/)[0]},this.createWorker=function(e){return null},this.createModeDelegates=function(e){this.$embeds=[],this.$modes={};for(var t in e)e[t]&&(this.$embeds.push(t),this.$modes[t]=new e[t]);var n=["toggleBlockComment","toggleCommentLines","getNextLineIndent","checkOutdent","autoOutdent","transformAction","getCompletions"];for(var t=0;t<n.length;t++)(function(e){var r=n[t],i=e[r];e[n[t]]=function(){return this.$delegator(r,arguments,i)}})(this)},this.$delegator=function(e,t,n){var r=t[0];typeof r!="string"&&(r=r[0]);for(var i=0;i<this.$embeds.length;i++){if(!this.$modes[this.$embeds[i]])continue;var s=r.split(this.$embeds[i]);if(!s[0]&&s[1]){t[0]=s[1];var o=this.$modes[this.$embeds[i]];return o[e].apply(o,t)}}var u=n.apply(this,t);return n?u:undefined},this.transformAction=function(e,t,n,r,i){if(this.$behaviour){var s=this.$behaviour.getBehaviours();for(var o in s)if(s[o][t]){var u=s[o][t].apply(this,arguments);if(u)return u}}},this.getKeywords=function(e){if(!this.completionKeywords){var t=this.$tokenizer.rules,n=[];for(var r in t){var i=t[r];for(var s=0,o=i.length;s<o;s++)if(typeof i[s].token=="string")/keyword|support|storage/.test(i[s].token)&&n.push(i[s].regex);else if(typeof i[s].token=="object")for(var u=0,a=i[s].token.length;u<a;u++)if(/keyword|support|storage/.test(i[s].token[u])){var r=i[s].regex.match(/\(.+?\)/g)[u];n.push(r.substr(1,r.length-2))}}this.completionKeywords=n}return e?n.concat(this.$keywordList||[]):this.$keywordList},this.$createKeywordList=function(){return this.$highlightRules||this.getTokenizer(),this.$keywordList=this.$highlightRules.$keywordList||[]},this.getCompletions=function(e,t,n,r){var i=this.$keywordList||this.$createKeywordList();return i.map(function(e){return{name:e,value:e,score:0,meta:"keyword"}})},this.$id="ace/mode/text"}).call(l.prototype),t.Mode=l}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action==="insertText")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action==="insertLines"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action==="removeText"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action=="removeLines"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[""]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},"\n"+t.join("\n")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._signal("change",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._signal("change",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._signal("change",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._signal("change",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this._insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define("ace/background_tokenizer",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=function(e,t){this.running=!1,this.lines=[],this.states=[],this.currentLine=0,this.tokenizer=e;var n=this;this.$worker=function(){if(!n.running)return;var e=new Date,t=n.currentLine,r=-1,i=n.doc;while(n.lines[t])t++;var s=t,o=i.getLength(),u=0;n.running=!1;while(t<o){n.$tokenizeRow(t),r=t;do t++;while(n.lines[t]);u++;if(u%5==0&&new Date-e>20){n.running=setTimeout(n.$worker,20),n.currentLine=t;return}}n.currentLine=t,s<=r&&n.fireUpdateEvent(s,r)}};(function(){r.implement(this,i),this.setTokenizer=function(e){this.tokenizer=e,this.lines=[],this.states=[],this.start(0)},this.setDocument=function(e){this.doc=e,this.lines=[],this.states=[],this.stop()},this.fireUpdateEvent=function(e,t){var n={first:e,last:t};this._signal("update",{data:n})},this.start=function(e){this.currentLine=Math.min(e||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.states.splice(this.currentLine,this.states.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.scheduleStart=function(){this.running||(this.running=setTimeout(this.$worker,700))},this.$updateOnChange=function(e){var t=e.range,n=t.start.row,r=t.end.row-n;if(r===0)this.lines[n]=null;else if(e.action=="removeText"||e.action=="removeLines")this.lines.splice(n,r+1,null),this.states.splice(n,r+1,null);else{var i=Array(r+1);i.unshift(n,1),this.lines.splice.apply(this.lines,i),this.states.splice.apply(this.states,i)}this.currentLine=Math.min(n,this.currentLine,this.doc.getLength()),this.stop()},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(e){return this.lines[e]||this.$tokenizeRow(e)},this.getState=function(e){return this.currentLine==e&&this.$tokenizeRow(e),this.states[e]||"start"},this.$tokenizeRow=function(e){var t=this.doc.getLine(e),n=this.states[e-1],r=this.tokenizer.getLineTokens(t,n,e);return this.states[e]+""!=r.state+""?(this.states[e]=r.state,this.lines[e+1]=null,this.currentLine>e+1&&(this.currentLine=e+1)):this.currentLine==e&&(this.currentLine=e+1),this.lines[e]=r.tokens}}).call(s.prototype),t.BackgroundTokenizer=s}),ace.define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(e,t,n){this.setRegexp(e),this.clazz=t,this.type=n||"text"};(function(){this.MAX_RANGES=500,this.setRegexp=function(e){if(this.regExp+""==e+"")return;this.regExp=e,this.cache=[]},this.update=function(e,t,n,i){if(!this.regExp)return;var o=i.firstRow,u=i.lastRow;for(var a=o;a<=u;a++){var f=this.cache[a];f==null&&(f=r.getMatchOffsets(n.getLine(a),this.regExp),f.length>this.MAX_RANGES&&(f=f.slice(0,this.MAX_RANGES)),f=f.map(function(e){return new s(a,e.offset,a,e.offset+e.length)}),this.cache[a]=f.length?f:"");for(var l=f.length;l--;)t.drawSingleLineMarker(e,f[l].toScreenRange(n),this.clazz,i)}}}).call(o.prototype),t.SearchHighlight=o}),ace.define("ace/edit_session/fold_line",["require","exports","module","ace/range"],function(e,t,n){"use strict";function i(e,t){this.foldData=e,Array.isArray(t)?this.folds=t:t=this.folds=[t];var n=t[t.length-1];this.range=new r(t[0].start.row,t[0].start.column,n.end.row,n.end.column),this.start=this.range.start,this.end=this.range.end,this.folds.forEach(function(e){e.setFoldLine(this)},this)}var r=e("../range").Range;(function(){this.shiftRow=function(e){this.start.row+=e,this.end.row+=e,this.folds.forEach(function(t){t.start.row+=e,t.end.row+=e})},this.addFold=function(e){if(e.sameRow){if(e.start.row<this.startRow||e.endRow>this.endRow)throw new Error("Can't add a fold to this FoldLine as it has no connection");this.folds.push(e),this.folds.sort(function(e,t){return-e.range.compareEnd(t.start.row,t.start.column)}),this.range.compareEnd(e.start.row,e.start.column)>0?(this.end.row=e.end.row,this.end.column=e.end.column):this.range.compareStart(e.end.row,e.end.column)<0&&(this.start.row=e.start.row,this.start.column=e.start.column)}else if(e.start.row==this.end.row)this.folds.push(e),this.end.row=e.end.row,this.end.column=e.end.column;else{if(e.end.row!=this.start.row)throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");this.folds.unshift(e),this.start.row=e.start.row,this.start.column=e.start.column}e.foldLine=this},this.containsRow=function(e){return e>=this.start.row&&e<=this.end.row},this.walk=function(e,t,n){var r=0,i=this.folds,s,o,u,a=!0;t==null&&(t=this.end.row,n=this.end.column);for(var f=0;f<i.length;f++){s=i[f],o=s.range.compareStart(t,n);if(o==-1){e(null,t,n,r,a);return}u=e(null,s.start.row,s.start.column,r,a),u=!u&&e(s.placeholder,s.start.row,s.start.column,r);if(u||o==0)return;a=!s.sameRow,r=s.end.column}e(null,t,n,r,a)},this.getNextFoldTo=function(e,t){var n,r;for(var i=0;i<this.folds.length;i++){n=this.folds[i],r=n.range.compareEnd(e,t);if(r==-1)return{fold:n,kind:"after"};if(r==0)return{fold:n,kind:"inside"}}return null},this.addRemoveChars=function(e,t,n){var r=this.getNextFoldTo(e,t),i,s;if(r){i=r.fold;if(r.kind=="inside"&&i.start.column!=t&&i.start.row!=e)window.console&&window.console.log(e,t,i);else if(i.start.row==e){s=this.folds;var o=s.indexOf(i);o==0&&(this.start.column+=n);for(o;o<s.length;o++){i=s[o],i.start.column+=n;if(!i.sameRow)return;i.end.column+=n}this.end.column+=n}}},this.split=function(e,t){var n=this.getNextFoldTo(e,t).fold,r=this.folds,s=this.foldData;if(!n)return null;var o=r.indexOf(n),u=r[o-1];this.end.row=u.end.row,this.end.column=u.end.column,r=r.splice(o,r.length-o);var a=new i(s,r);return s.splice(s.indexOf(this)+1,0,a),a},this.merge=function(e){var t=e.folds;for(var n=0;n<t.length;n++)this.addFold(t[n]);var r=this.foldData;r.splice(r.indexOf(e),1)},this.toString=function(){var e=[this.range.toString()+": ["];return this.folds.forEach(function(t){e.push("  "+t.toString())}),e.push("]"),e.join("\n")},this.idxToPosition=function(e){var t=0,n;for(var r=0;r<this.folds.length;r++){var n=this.folds[r];e-=n.start.column-t;if(e<0)return{row:n.start.row,column:n.start.column+e};e-=n.placeholder.length;if(e<0)return n.start;t=n.end.column}return{row:this.end.row,column:this.end.column+e}}}).call(i.prototype),t.FoldLine=i}),ace.define("ace/range_list",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("./range").Range,i=r.comparePoints,s=function(){this.ranges=[]};(function(){this.comparePoints=i,this.pointIndex=function(e,t,n){var r=this.ranges;for(var s=n||0;s<r.length;s++){var o=r[s],u=i(e,o.end);if(u>0)continue;var a=i(e,o.start);return u===0?t&&a!==0?-s-2:s:a>0||a===0&&!t?s:-s-1}return-s-1},this.add=function(e){var t=!e.isEmpty(),n=this.pointIndex(e.start,t);n<0&&(n=-n-1);var r=this.pointIndex(e.end,t,n);return r<0?r=-r-1:r++,this.ranges.splice(n,r-n,e)},this.addList=function(e){var t=[];for(var n=e.length;n--;)t.push.call(t,this.add(e[n]));return t},this.substractPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges.splice(t,1)},this.merge=function(){var e=[],t=this.ranges;t=t.sort(function(e,t){return i(e.start,t.start)});var n=t[0],r;for(var s=1;s<t.length;s++){r=n,n=t[s];var o=i(r.end,n.start);if(o<0)continue;if(o==0&&!r.isEmpty()&&!n.isEmpty())continue;i(r.end,n.end)<0&&(r.end.row=n.end.row,r.end.column=n.end.column),t.splice(s,1),e.push(n),n=r,s--}return this.ranges=t,e},this.contains=function(e,t){return this.pointIndex({row:e,column:t})>=0},this.containsPoint=function(e){return this.pointIndex(e)>=0},this.rangeAtPoint=function(e){var t=this.pointIndex(e);if(t>=0)return this.ranges[t]},this.clipRows=function(e,t){var n=this.ranges;if(n[0].start.row>t||n[n.length-1].start.row<e)return[];var r=this.pointIndex({row:e,column:0});r<0&&(r=-r-1);var i=this.pointIndex({row:t,column:0},r);i<0&&(i=-i-1);var s=[];for(var o=r;o<i;o++)s.push(n[o]);return s},this.removeAll=function(){return this.ranges.splice(0,this.ranges.length)},this.attach=function(e){this.session&&this.detach(),this.session=e,this.onChange=this.$onChange.bind(this),this.session.on("change",this.onChange)},this.detach=function(){if(!this.session)return;this.session.removeListener("change",this.onChange),this.session=null},this.$onChange=function(e){var t=e.data.range;if(e.data.action[0]=="i")var n=t.start,r=t.end;else var r=t.start,n=t.end;var i=n.row,s=r.row,o=s-i,u=-n.column+r.column,a=this.ranges;for(var f=0,l=a.length;f<l;f++){var c=a[f];if(c.end.row<i)continue;if(c.start.row>i)break;c.start.row==i&&c.start.column>=n.column&&(c.start.column!=n.column||!this.$insertRight)&&(c.start.column+=u,c.start.row+=o);if(c.end.row==i&&c.end.column>=n.column){if(c.end.column==n.column&&this.$insertRight)continue;c.end.column==n.column&&u>0&&f<l-1&&c.end.column>c.start.column&&c.end.column==a[f+1].start.column&&(c.end.column-=u),c.end.column+=u,c.end.row+=o}}if(o!=0&&f<l)for(;f<l;f++){var c=a[f];c.start.row+=o,c.end.row+=o}}}).call(s.prototype),t.RangeList=s}),ace.define("ace/edit_session/fold",["require","exports","module","ace/range","ace/range_list","ace/lib/oop"],function(e,t,n){"use strict";function u(e,t){e.row-=t.row,e.row==0&&(e.column-=t.column)}function a(e,t){u(e.start,t),u(e.end,t)}function f(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row}function l(e,t){f(e.start,t),f(e.end,t)}var r=e("../range").Range,i=e("../range_list").RangeList,s=e("../lib/oop"),o=t.Fold=function(e,t){this.foldLine=null,this.placeholder=t,this.range=e,this.start=e.start,this.end=e.end,this.sameRow=e.start.row==e.end.row,this.subFolds=this.ranges=[]};s.inherits(o,i),function(){this.toString=function(){return'"'+this.placeholder+'" '+this.range.toString()},this.setFoldLine=function(e){this.foldLine=e,this.subFolds.forEach(function(t){t.setFoldLine(e)})},this.clone=function(){var e=this.range.clone(),t=new o(e,this.placeholder);return this.subFolds.forEach(function(e){t.subFolds.push(e.clone())}),t.collapseChildren=this.collapseChildren,t},this.addSubFold=function(e){if(this.range.isEqual(e))return;if(!this.range.containsRange(e))throw new Error("A fold can't intersect already existing fold"+e.range+this.range);a(e,this.start);var t=e.start.row,n=e.start.column;for(var r=0,i=-1;r<this.subFolds.length;r++){i=this.subFolds[r].range.compare(t,n);if(i!=1)break}var s=this.subFolds[r];if(i==0)return s.addSubFold(e);var t=e.range.end.row,n=e.range.end.column;for(var o=r,i=-1;o<this.subFolds.length;o++){i=this.subFolds[o].range.compare(t,n);if(i!=1)break}var u=this.subFolds[o];if(i==0)throw new Error("A fold can't intersect already existing fold"+e.range+this.range);var f=this.subFolds.splice(r,o-r,e);return e.setFoldLine(this.foldLine),e},this.restoreRange=function(e){return l(e,this.start)}}.call(o.prototype)}),ace.define("ace/edit_session/folding",["require","exports","module","ace/range","ace/edit_session/fold_line","ace/edit_session/fold","ace/token_iterator"],function(e,t,n){"use strict";function u(){this.getFoldAt=function(e,t,n){var r=this.getFoldLine(e);if(!r)return null;var i=r.folds;for(var s=0;s<i.length;s++){var o=i[s];if(o.range.contains(e,t)){if(n==1&&o.range.isEnd(e,t))continue;if(n==-1&&o.range.isStart(e,t))continue;return o}}},this.getFoldsInRange=function(e){var t=e.start,n=e.end,r=this.$foldData,i=[];t.column+=1,n.column-=1;for(var s=0;s<r.length;s++){var o=r[s].range.compareRange(e);if(o==2)continue;if(o==-2)break;var u=r[s].folds;for(var a=0;a<u.length;a++){var f=u[a];o=f.range.compareRange(e);if(o==-2)break;if(o==2)continue;if(o==42)break;i.push(f)}}return t.column-=1,n.column+=1,i},this.getFoldsInRangeList=function(e){if(Array.isArray(e)){var t=[];e.forEach(function(e){t=t.concat(this.getFoldsInRange(e))},this)}else var t=this.getFoldsInRange(e);return t},this.getAllFolds=function(){var e=[],t=this.$foldData;for(var n=0;n<t.length;n++)for(var r=0;r<t[n].folds.length;r++)e.push(t[n].folds[r]);return e},this.getFoldStringAt=function(e,t,n,r){r=r||this.getFoldLine(e);if(!r)return null;var i={end:{column:0}},s,o;for(var u=0;u<r.folds.length;u++){o=r.folds[u];var a=o.range.compareEnd(e,t);if(a==-1){s=this.getLine(o.start.row).substring(i.end.column,o.start.column);break}if(a===0)return null;i=o}return s||(s=this.getLine(o.start.row).substring(i.end.column)),n==-1?s.substring(0,t-i.end.column):n==1?s.substring(t-i.end.column):s},this.getFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.start.row<=e&&i.end.row>=e)return i;if(i.end.row>e)return null}return null},this.getNextFoldLine=function(e,t){var n=this.$foldData,r=0;t&&(r=n.indexOf(t)),r==-1&&(r=0);for(r;r<n.length;r++){var i=n[r];if(i.end.row>=e)return i}return null},this.getFoldedRowCount=function(e,t){var n=this.$foldData,r=t-e+1;for(var i=0;i<n.length;i++){var s=n[i],o=s.end.row,u=s.start.row;if(o>=t){u<t&&(u>=e?r-=t-u:r=0);break}o>=e&&(u>=e?r-=o-u:r-=o-e+1)}return r},this.$addFoldLine=function(e){return this.$foldData.push(e),this.$foldData.sort(function(e,t){return e.start.row-t.start.row}),e},this.addFold=function(e,t){var n=this.$foldData,r=!1,o;e instanceof s?o=e:(o=new s(t,e),o.collapseChildren=t.collapseChildren),this.$clipRangeToDocument(o.range);var u=o.start.row,a=o.start.column,f=o.end.row,l=o.end.column;if(u<f||u==f&&a<=l-2){var c=this.getFoldAt(u,a,1),h=this.getFoldAt(f,l,-1);if(c&&h==c)return c.addSubFold(o);if(c&&!c.range.isStart(u,a)||h&&!h.range.isEnd(f,l))throw new Error("A fold can't intersect already existing fold"+o.range+c.range);var p=this.getFoldsInRange(o.range);p.length>0&&(this.removeFolds(p),p.forEach(function(e){o.addSubFold(e)}));for(var d=0;d<n.length;d++){var v=n[d];if(f==v.start.row){v.addFold(o),r=!0;break}if(u==v.end.row){v.addFold(o),r=!0;if(!o.sameRow){var m=n[d+1];if(m&&m.start.row==f){v.merge(m);break}}break}if(f<=v.start.row)break}return r||(v=this.$addFoldLine(new i(this.$foldData,o))),this.$useWrapMode?this.$updateWrapData(v.start.row,v.start.row):this.$updateRowLengthCache(v.start.row,v.start.row),this.$modified=!0,this._emit("changeFold",{data:o,action:"add"}),o}throw new Error("The range has to be at least 2 characters width")},this.addFolds=function(e){e.forEach(function(e){this.addFold(e)},this)},this.removeFold=function(e){var t=e.foldLine,n=t.start.row,r=t.end.row,i=this.$foldData,s=t.folds;if(s.length==1)i.splice(i.indexOf(t),1);else if(t.range.isEnd(e.end.row,e.end.column))s.pop(),t.end.row=s[s.length-1].end.row,t.end.column=s[s.length-1].end.column;else if(t.range.isStart(e.start.row,e.start.column))s.shift(),t.start.row=s[0].start.row,t.start.column=s[0].start.column;else if(e.sameRow)s.splice(s.indexOf(e),1);else{var o=t.split(e.start.row,e.start.column);s=o.folds,s.shift(),o.start.row=s[0].start.row,o.start.column=s[0].start.column}this.$updating||(this.$useWrapMode?this.$updateWrapData(n,r):this.$updateRowLengthCache(n,r)),this.$modified=!0,this._emit("changeFold",{data:e,action:"remove"})},this.removeFolds=function(e){var t=[];for(var n=0;n<e.length;n++)t.push(e[n]);t.forEach(function(e){this.removeFold(e)},this),this.$modified=!0},this.expandFold=function(e){this.removeFold(e),e.subFolds.forEach(function(t){e.restoreRange(t),this.addFold(t)},this),e.collapseChildren>0&&this.foldAll(e.start.row+1,e.end.row,e.collapseChildren-1),e.subFolds=[]},this.expandFolds=function(e){e.forEach(function(e){this.expandFold(e)},this)},this.unfold=function(e,t){var n,i;e==null?(n=new r(0,0,this.getLength(),0),t=!0):typeof e=="number"?n=new r(e,0,e,this.getLine(e).length):"row"in e?n=r.fromPoints(e,e):n=e,i=this.getFoldsInRangeList(n);if(t)this.removeFolds(i);else{var s=i;while(s.length)this.expandFolds(s),s=this.getFoldsInRangeList(n)}if(i.length)return i},this.isRowFolded=function(e,t){return!!this.getFoldLine(e,t)},this.getRowFoldEnd=function(e,t){var n=this.getFoldLine(e,t);return n?n.end.row:e},this.getRowFoldStart=function(e,t){var n=this.getFoldLine(e,t);return n?n.start.row:e},this.getFoldDisplayLine=function(e,t,n,r,i){r==null&&(r=e.start.row),i==null&&(i=0),t==null&&(t=e.end.row),n==null&&(n=this.getLine(t).length);var s=this.doc,o="";return e.walk(function(e,t,n,u){if(t<r)return;if(t==r){if(n<i)return;u=Math.max(i,u)}e!=null?o+=e:o+=s.getLine(t).substring(u,n)},t,n),o},this.getDisplayLine=function(e,t,n,r){var i=this.getFoldLine(e);if(!i){var s;return s=this.doc.getLine(e),s.substring(r||0,t||s.length)}return this.getFoldDisplayLine(i,e,t,n,r)},this.$cloneFoldData=function(){var e=[];return e=this.$foldData.map(function(t){var n=t.folds.map(function(e){return e.clone()});return new i(e,n)}),e},this.toggleFold=function(e){var t=this.selection,n=t.getRange(),r,i;if(n.isEmpty()){var s=n.start;r=this.getFoldAt(s.row,s.column);if(r){this.expandFold(r);return}(i=this.findMatchingBracket(s))?n.comparePoint(i)==1?n.end=i:(n.start=i,n.start.column++,n.end.column--):(i=this.findMatchingBracket({row:s.row,column:s.column+1}))?(n.comparePoint(i)==1?n.end=i:n.start=i,n.start.column++):n=this.getCommentFoldRange(s.row,s.column)||n}else{var o=this.getFoldsInRange(n);if(e&&o.length){this.expandFolds(o);return}o.length==1&&(r=o[0])}r||(r=this.getFoldAt(n.start.row,n.start.column));if(r&&r.range.toString()==n.toString()){this.expandFold(r);return}var u="...";if(!n.isMultiLine()){u=this.getTextRange(n);if(u.length<4)return;u=u.trim().substring(0,2)+".."}this.addFold(u,n)},this.getCommentFoldRange=function(e,t,n){var i=new o(this,e,t),s=i.getCurrentToken();if(s&&/^comment|string/.test(s.type)){var u=new r,a=new RegExp(s.type.replace(/\..*/,"\\."));if(n!=1){do s=i.stepBackward();while(s&&a.test(s.type));i.stepForward()}u.start.row=i.getCurrentTokenRow(),u.start.column=i.getCurrentTokenColumn()+2,i=new o(this,e,t);if(n!=-1){do s=i.stepForward();while(s&&a.test(s.type));s=i.stepBackward()}else s=i.getCurrentToken();return u.end.row=i.getCurrentTokenRow(),u.end.column=i.getCurrentTokenColumn()+s.value.length-2,u}},this.foldAll=function(e,t,n){n==undefined&&(n=1e5);var r=this.foldWidgets;if(!r)return;t=t||this.getLength(),e=e||0;for(var i=e;i<t;i++){r[i]==null&&(r[i]=this.getFoldWidget(i));if(r[i]!="start")continue;var s=this.getFoldWidgetRange(i);if(s&&s.isMultiLine()&&s.end.row<=t&&s.start.row>=e){i=s.end.row;try{var o=this.addFold("...",s);o&&(o.collapseChildren=n)}catch(u){}}}},this.$foldStyles={manual:1,markbegin:1,markbeginend:1},this.$foldStyle="markbegin",this.setFoldStyle=function(e){if(!this.$foldStyles[e])throw new Error("invalid fold style: "+e+"["+Object.keys(this.$foldStyles).join(", ")+"]");if(this.$foldStyle==e)return;this.$foldStyle=e,e=="manual"&&this.unfold();var t=this.$foldMode;this.$setFolding(null),this.$setFolding(t)},this.$setFolding=function(e){if(this.$foldMode==e)return;this.$foldMode=e,this.removeListener("change",this.$updateFoldWidgets),this._emit("changeAnnotation");if(!e||this.$foldStyle=="manual"){this.foldWidgets=null;return}this.foldWidgets=[],this.getFoldWidget=e.getFoldWidget.bind(e,this,this.$foldStyle),this.getFoldWidgetRange=e.getFoldWidgetRange.bind(e,this,this.$foldStyle),this.$updateFoldWidgets=this.updateFoldWidgets.bind(this),this.on("change",this.$updateFoldWidgets)},this.getParentFoldRangeData=function(e,t){var n=this.foldWidgets;if(!n||t&&n[e])return{};var r=e-1,i;while(r>=0){var s=n[r];s==null&&(s=n[r]=this.getFoldWidget(r));if(s=="start"){var o=this.getFoldWidgetRange(r);i||(i=o);if(o&&o.end.row>=e)break}r--}return{range:r!==-1&&o,firstRange:i}},this.onFoldWidgetClick=function(e,t){t=t.domEvent;var n={children:t.shiftKey,all:t.ctrlKey||t.metaKey,siblings:t.altKey},r=this.$toggleFoldWidget(e,n);if(!r){var i=t.target||t.srcElement;i&&/ace_fold-widget/.test(i.className)&&(i.className+=" ace_invalid")}},this.$toggleFoldWidget=function(e,t){if(!this.getFoldWidget)return;var n=this.getFoldWidget(e),r=this.getLine(e),i=n==="end"?-1:1,s=this.getFoldAt(e,i===-1?0:r.length,i);if(s){t.children||t.all?this.removeFold(s):this.expandFold(s);return}var o=this.getFoldWidgetRange(e,!0);if(o&&!o.isMultiLine()){s=this.getFoldAt(o.start.row,o.start.column,1);if(s&&o.isEqual(s.range)){this.removeFold(s);return}}if(t.siblings){var u=this.getParentFoldRangeData(e);if(u.range)var a=u.range.start.row+1,f=u.range.end.row;this.foldAll(a,f,t.all?1e4:0)}else t.children?(f=o?o.end.row:this.getLength(),this.foldAll(e+1,o.end.row,t.all?1e4:0)):o&&(t.all&&(o.collapseChildren=1e4),this.addFold("...",o));return o},this.toggleFoldWidget=function(e){var t=this.selection.getCursor().row;t=this.getRowFoldStart(t);var n=this.$toggleFoldWidget(t,{});if(n)return;var r=this.getParentFoldRangeData(t,!0);n=r.range||r.firstRange;if(n){t=n.start.row;var i=this.getFoldAt(t,this.getLine(t).length,1);i?this.removeFold(i):this.addFold("...",n)}},this.updateFoldWidgets=function(e){var t=e.data,n=t.range,r=n.start.row,i=n.end.row-r;if(i===0)this.foldWidgets[r]=null;else if(t.action=="removeText"||t.action=="removeLines")this.foldWidgets.splice(r,i+1,null);else{var s=Array(i+1);s.unshift(r,1),this.foldWidgets.splice.apply(this.foldWidgets,s)}}}var r=e("../range").Range,i=e("./fold_line").FoldLine,s=e("./fold").Fold,o=e("../token_iterator").TokenIterator;t.Folding=u}),ace.define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"],function(e,t,n){"use strict";function s(){this.findMatchingBracket=function(e,t){if(e.column==0)return null;var n=t||this.getLine(e.row).charAt(e.column-1);if(n=="")return null;var r=n.match(/([\(\[\{])|([\)\]\}])/);return r?r[1]?this.$findClosingBracket(r[1],e):this.$findOpeningBracket(r[2],e):null},this.getBracketRange=function(e){var t=this.getLine(e.row),n=!0,r,s=t.charAt(e.column-1),o=s&&s.match(/([\(\[\{])|([\)\]\}])/);o||(s=t.charAt(e.column),e={row:e.row,column:e.column+1},o=s&&s.match(/([\(\[\{])|([\)\]\}])/),n=!1);if(!o)return null;if(o[1]){var u=this.$findClosingBracket(o[1],e);if(!u)return null;r=i.fromPoints(e,u),n||(r.end.column++,r.start.column--),r.cursor=r.end}else{var u=this.$findOpeningBracket(o[2],e);if(!u)return null;r=i.fromPoints(u,e),n||(r.start.column++,r.end.column--),r.cursor=r.start}return r},this.$brackets={")":"(","(":")","]":"[","[":"]","{":"}","}":"{"},this.$findOpeningBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("rparen",".paren")+")+"));var a=t.column-o.getCurrentTokenColumn()-2,f=u.value;for(;;){while(a>=0){var l=f.charAt(a);if(l==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else l==e&&(s+=1);a-=1}do u=o.stepBackward();while(u&&!n.test(u.type));if(u==null)break;f=u.value,a=f.length-1}return null},this.$findClosingBracket=function(e,t,n){var i=this.$brackets[e],s=1,o=new r(this,t.row,t.column),u=o.getCurrentToken();u||(u=o.stepForward());if(!u)return;n||(n=new RegExp("(\\.?"+u.type.replace(".","\\.").replace("lparen",".paren")+")+"));var a=t.column-o.getCurrentTokenColumn();for(;;){var f=u.value,l=f.length;while(a<l){var c=f.charAt(a);if(c==i){s-=1;if(s==0)return{row:o.getCurrentTokenRow(),column:a+o.getCurrentTokenColumn()}}else c==e&&(s+=1);a+=1}do u=o.stepForward();while(u&&!n.test(u.type));if(u==null)break;a=0}return null}}var r=e("../token_iterator").TokenIterator,i=e("../range").Range;t.BracketMatch=s}),ace.define("ace/edit_session",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/config","ace/lib/event_emitter","ace/selection","ace/mode/text","ace/range","ace/document","ace/background_tokenizer","ace/search_highlight","ace/edit_session/folding","ace/edit_session/bracket_match"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/lang"),s=e("./config"),o=e("./lib/event_emitter").EventEmitter,u=e("./selection").Selection,a=e("./mode/text").Mode,f=e("./range").Range,l=e("./document").Document,c=e("./background_tokenizer").BackgroundTokenizer,h=e("./search_highlight").SearchHighlight,p=function(e,t){this.$breakpoints=[],this.$decorations=[],this.$frontMarkers={},this.$backMarkers={},this.$markerId=1,this.$undoSelect=!0,this.$foldData=[],this.$foldData.toString=function(){return this.join("\n")},this.on("changeFold",this.onChangeFold.bind(this)),this.$onChange=this.onChange.bind(this);if(typeof e!="object"||!e.getLine)e=new l(e);this.setDocument(e),this.selection=new u(this),s.resetOptions(this),this.setMode(t),s._signal("session",this)};(function(){function g(e){return e<4352?!1:e>=4352&&e<=4447||e>=4515&&e<=4519||e>=4602&&e<=4607||e>=9001&&e<=9002||e>=11904&&e<=11929||e>=11931&&e<=12019||e>=12032&&e<=12245||e>=12272&&e<=12283||e>=12288&&e<=12350||e>=12353&&e<=12438||e>=12441&&e<=12543||e>=12549&&e<=12589||e>=12593&&e<=12686||e>=12688&&e<=12730||e>=12736&&e<=12771||e>=12784&&e<=12830||e>=12832&&e<=12871||e>=12880&&e<=13054||e>=13056&&e<=19903||e>=19968&&e<=42124||e>=42128&&e<=42182||e>=43360&&e<=43388||e>=44032&&e<=55203||e>=55216&&e<=55238||e>=55243&&e<=55291||e>=63744&&e<=64255||e>=65040&&e<=65049||e>=65072&&e<=65106||e>=65108&&e<=65126||e>=65128&&e<=65131||e>=65281&&e<=65376||e>=65504&&e<=65510}r.implement(this,o),this.setDocument=function(e){this.doc&&this.doc.removeListener("change",this.$onChange),this.doc=e,e.on("change",this.$onChange),this.bgTokenizer&&this.bgTokenizer.setDocument(this.getDocument()),this.resetCaches()},this.getDocument=function(){return this.doc},this.$resetRowCache=function(e){if(!e){this.$docRowCache=[],this.$screenRowCache=[];return}var t=this.$docRowCache.length,n=this.$getRowCacheIndex(this.$docRowCache,e)+1;t>n&&(this.$docRowCache.splice(n,t),this.$screenRowCache.splice(n,t))},this.$getRowCacheIndex=function(e,t){var n=0,r=e.length-1;while(n<=r){var i=n+r>>1,s=e[i];if(t>s)n=i+1;else{if(!(t<s))return i;r=i-1}}return n-1},this.resetCaches=function(){this.$modified=!0,this.$wrapData=[],this.$rowLengthCache=[],this.$resetRowCache(0),this.bgTokenizer&&this.bgTokenizer.start(0)},this.onChangeFold=function(e){var t=e.data;this.$resetRowCache(t.start.row)},this.onChange=function(e){var t=e.data;this.$modified=!0,this.$resetRowCache(t.range.start.row);var n=this.$updateInternalDataOnChange(e);!this.$fromUndo&&this.$undoManager&&!t.ignore&&(this.$deltasDoc.push(t),n&&n.length!=0&&this.$deltasFold.push({action:"removeFolds",folds:n}),this.$informUndoManager.schedule()),this.bgTokenizer.$updateOnChange(t),this._signal("change",e)},this.setValue=function(e){this.doc.setValue(e),this.selection.moveTo(0,0),this.$resetRowCache(0),this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.setUndoManager(this.$undoManager),this.getUndoManager().reset()},this.getValue=this.toString=function(){return this.doc.getValue()},this.getSelection=function(){return this.selection},this.getState=function(e){return this.bgTokenizer.getState(e)},this.getTokens=function(e){return this.bgTokenizer.getTokens(e)},this.getTokenAt=function(e,t){var n=this.bgTokenizer.getTokens(e),r,i=0;if(t==null)s=n.length-1,i=this.getLine(e).length;else for(var s=0;s<n.length;s++){i+=n[s].value.length;if(i>=t)break}return r=n[s],r?(r.index=s,r.start=i-r.value.length,r):null},this.setUndoManager=function(e){this.$undoManager=e,this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.$informUndoManager&&this.$informUndoManager.cancel();if(e){var t=this;this.$syncInformUndoManager=function(){t.$informUndoManager.cancel(),t.$deltasFold.length&&(t.$deltas.push({group:"fold",deltas:t.$deltasFold}),t.$deltasFold=[]),t.$deltasDoc.length&&(t.$deltas.push({group:"doc",deltas:t.$deltasDoc}),t.$deltasDoc=[]),t.$deltas.length>0&&e.execute({action:"aceupdate",args:[t.$deltas,t],merge:t.mergeUndoDeltas}),t.mergeUndoDeltas=!1,t.$deltas=[]},this.$informUndoManager=i.delayedCall(this.$syncInformUndoManager)}},this.markUndoGroup=function(){this.$syncInformUndoManager&&this.$syncInformUndoManager()},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?i.stringRepeat(" ",this.getTabSize()):"	"},this.setUseSoftTabs=function(e){this.setOption("useSoftTabs",e)},this.getUseSoftTabs=function(){return this.$useSoftTabs&&!this.$mode.$indentWithTabs},this.setTabSize=function(e){this.setOption("tabSize",e)},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(e){return this.$useSoftTabs&&e.column%this.$tabSize===0},this.$overwrite=!1,this.setOverwrite=function(e){this.setOption("overwrite",e)},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.addGutterDecoration=function(e,t){this.$decorations[e]||(this.$decorations[e]=""),this.$decorations[e]+=" "+t,this._signal("changeBreakpoint",{})},this.removeGutterDecoration=function(e,t){this.$decorations[e]=(this.$decorations[e]||"").replace(" "+t,""),this._signal("changeBreakpoint",{})},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(e){this.$breakpoints=[];for(var t=0;t<e.length;t++)this.$breakpoints[e[t]]="ace_breakpoint";this._signal("changeBreakpoint",{})},this.clearBreakpoints=function(){this.$breakpoints=[],this._signal("changeBreakpoint",{})},this.setBreakpoint=function(e,t){t===undefined&&(t="ace_breakpoint"),t?this.$breakpoints[e]=t:delete this.$breakpoints[e],this._signal("changeBreakpoint",{})},this.clearBreakpoint=function(e){delete this.$breakpoints[e],this._signal("changeBreakpoint",{})},this.addMarker=function(e,t,n,r){var i=this.$markerId++,s={range:e,type:n||"line",renderer:typeof n=="function"?n:null,clazz:t,inFront:!!r,id:i};return r?(this.$frontMarkers[i]=s,this._signal("changeFrontMarker")):(this.$backMarkers[i]=s,this._signal("changeBackMarker")),i},this.addDynamicMarker=function(e,t){if(!e.update)return;var n=this.$markerId++;return e.id=n,e.inFront=!!t,t?(this.$frontMarkers[n]=e,this._signal("changeFrontMarker")):(this.$backMarkers[n]=e,this._signal("changeBackMarker")),e},this.removeMarker=function(e){var t=this.$frontMarkers[e]||this.$backMarkers[e];if(!t)return;var n=t.inFront?this.$frontMarkers:this.$backMarkers;t&&(delete n[e],this._signal(t.inFront?"changeFrontMarker":"changeBackMarker"))},this.getMarkers=function(e){return e?this.$frontMarkers:this.$backMarkers},this.highlight=function(e){if(!this.$searchHighlight){var t=new h(null,"ace_selected-word","text");this.$searchHighlight=this.addDynamicMarker(t)}this.$searchHighlight.setRegexp(e)},this.highlightLines=function(e,t,n,r){typeof t!="number"&&(n=t,t=e),n||(n="ace_step");var i=new f(e,0,t,Infinity);return i.id=this.addMarker(i,n,"fullLine",r),i},this.setAnnotations=function(e){this.$annotations=e,this._signal("changeAnnotation",{})},this.getAnnotations=function(){return this.$annotations||[]},this.clearAnnotations=function(){this.setAnnotations([])},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r?\n)/m);t?this.$autoNewLine=t[1]:this.$autoNewLine="\n"},this.getWordRange=function(e,t){var n=this.getLine(e),r=!1;t>0&&(r=!!n.charAt(t-1).match(this.tokenRe)),r||(r=!!n.charAt(t).match(this.tokenRe));if(r)var i=this.tokenRe;else if(/^\s+$/.test(n.slice(t-1,t+1)))var i=/\s/;else var i=this.nonTokenRe;var s=t;if(s>0){do s--;while(s>=0&&n.charAt(s).match(i));s++}var o=t;while(o<n.length&&n.charAt(o).match(i))o++;return new f(e,s,e,o)},this.getAWordRange=function(e,t){var n=this.getWordRange(e,t),r=this.getLine(n.end.row);while(r.charAt(n.end.column).match(/[ \t]/))n.end.column+=1;return n},this.setNewLineMode=function(e){this.doc.setNewLineMode(e)},this.getNewLineMode=function(){return this.doc.getNewLineMode()},this.setUseWorker=function(e){this.setOption("useWorker",e)},this.getUseWorker=function(){return this.$useWorker},this.onReloadTokenizer=function(e){var t=e.data;this.bgTokenizer.start(t.first),this._signal("tokenizerUpdate",e)},this.$modes={},this.$mode=null,this.$modeId=null,this.setMode=function(e,t){if(e&&typeof e=="object"){if(e.getTokenizer)return this.$onChangeMode(e);var n=e,r=n.path}else r=e||"ace/mode/text";this.$modes["ace/mode/text"]||(this.$modes["ace/mode/text"]=new a);if(this.$modes[r]&&!n){this.$onChangeMode(this.$modes[r]),t&&t();return}this.$modeId=r,s.loadModule(["mode",r],function(e){if(this.$modeId!==r)return t&&t();if(this.$modes[r]&&!n)return this.$onChangeMode(this.$modes[r]);e&&e.Mode&&(e=new e.Mode(n),n||(this.$modes[r]=e,e.$id=r),this.$onChangeMode(e),t&&t())}.bind(this)),this.$mode||this.$onChangeMode(this.$modes["ace/mode/text"],!0)},this.$onChangeMode=function(e,t){t||(this.$modeId=e.$id);if(this.$mode===e)return;this.$mode=e,this.$stopWorker(),this.$useWorker&&this.$startWorker();var n=e.getTokenizer();if(n.addEventListener!==undefined){var r=this.onReloadTokenizer.bind(this);n.addEventListener("update",r)}if(!this.bgTokenizer){this.bgTokenizer=new c(n);var i=this;this.bgTokenizer.addEventListener("update",function(e){i._signal("tokenizerUpdate",e)})}else this.bgTokenizer.setTokenizer(n);this.bgTokenizer.setDocument(this.getDocument()),this.tokenRe=e.tokenRe,this.nonTokenRe=e.nonTokenRe,t||(this.$options.wrapMethod.set.call(this,this.$wrapMethod),this.$setFolding(e.foldingRules),this.bgTokenizer.start(0),this._emit("changeMode"))},this.$stopWorker=function(){this.$worker&&this.$worker.terminate(),this.$worker=null},this.$startWorker=function(){if(typeof Worker!="undefined"&&!e.noWorker)try{this.$worker=this.$mode.createWorker(this)}catch(t){console.log("Could not load worker"),console.log(t),this.$worker=null}else this.$worker=null},this.getMode=function(){return this.$mode},this.$scrollTop=0,this.setScrollTop=function(e){if(this.$scrollTop===e||isNaN(e))return;this.$scrollTop=e,this._signal("changeScrollTop",e)},this.getScrollTop=function(){return this.$scrollTop},this.$scrollLeft=0,this.setScrollLeft=function(e){if(this.$scrollLeft===e||isNaN(e))return;this.$scrollLeft=e,this._signal("changeScrollLeft",e)},this.getScrollLeft=function(){return this.$scrollLeft},this.getScreenWidth=function(){return this.$computeWidth(),this.lineWidgets?Math.max(this.getLineWidgetMaxWidth(),this.screenWidth):this.screenWidth},this.getLineWidgetMaxWidth=function(){if(this.lineWidgetsWidth!=null)return this.lineWidgetsWidth;var e=0;return this.lineWidgets.forEach(function(t){t&&t.screenWidth>e&&(e=t.screenWidth)}),this.lineWidgetWidth=e},this.$computeWidth=function(e){if(this.$modified||e){this.$modified=!1;if(this.$useWrapMode)return this.screenWidth=this.$wrapLimit;var t=this.doc.getAllLines(),n=this.$rowLengthCache,r=0,i=0,s=this.$foldData[i],o=s?s.start.row:Infinity,u=t.length;for(var a=0;a<u;a++){if(a>o){a=s.end.row+1;if(a>=u)break;s=this.$foldData[i++],o=s?s.start.row:Infinity}n[a]==null&&(n[a]=this.$getStringScreenWidth(t[a])[0]),n[a]>r&&(r=n[a])}this.screenWidth=r}},this.getLine=function(e){return this.doc.getLine(e)},this.getLines=function(e,t){return this.doc.getLines(e,t)},this.getLength=function(){return this.doc.getLength()},this.getTextRange=function(e){return this.doc.getTextRange(e||this.selection.getRange())},this.insert=function(e,t){return this.doc.insert(e,t)},this.remove=function(e){return this.doc.remove(e)},this.undoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=e.length-1;r!=-1;r--){var i=e[r];i.group=="doc"?(this.doc.revertDeltas(i.deltas),n=this.$getUndoSelection(i.deltas,!0,n)):i.deltas.forEach(function(e){this.addFolds(e.folds)},this)}return this.$fromUndo=!1,n&&this.$undoSelect&&!t&&this.selection.setSelectionRange(n),n},this.redoChanges=function(e,t){if(!e.length)return;this.$fromUndo=!0;var n=null;for(var r=0;r<e.length;r++){var i=e[r];i.group=="doc"&&(this.doc.applyDeltas(i.deltas),n=this.$getUndoSelection(i.deltas,!1,n))}return this.$fromUndo=!1,n&&this.$undoSelect&&!t&&this.selection.setSelectionRange(n),n},this.setUndoSelect=function(e){this.$undoSelect=e},this.$getUndoSelection=function(e,t,n){function r(e){var n=e.action==="insertText"||e.action==="insertLines";return t?!n:n}var i=e[0],s,o,u=!1;r(i)?(s=f.fromPoints(i.range.start,i.range.end),u=!0):(s=f.fromPoints(i.range.start,i.range.start),u=!1);for(var a=1;a<e.length;a++)i=e[a],r(i)?(o=i.range.start,s.compare(o.row,o.column)==-1&&s.setStart(i.range.start),o=i.range.end,s.compare(o.row,o.column)==1&&s.setEnd(i.range.end),u=!0):(o=i.range.start,s.compare(o.row,o.column)==-1&&(s=f.fromPoints(i.range.start,i.range.start)),u=!1);if(n!=null){f.comparePoints(n.start,s.start)===0&&(n.start.column+=s.end.column-s.start.column,n.end.column+=s.end.column-s.start.column);var l=n.compareRange(s);l==1?s.setStart(n.start):l==-1&&s.setEnd(n.end)}return s},this.replace=function(e,t){return this.doc.replace(e,t)},this.moveText=function(e,t,n){var r=this.getTextRange(e),i=this.getFoldsInRange(e),s=f.fromPoints(t,t);if(!n){this.remove(e);var o=e.start.row-e.end.row,u=o?-e.end.column:e.start.column-e.end.column;u&&(s.start.row==e.end.row&&s.start.column>e.end.column&&(s.start.column+=u),s.end.row==e.end.row&&s.end.column>e.end.column&&(s.end.column+=u)),o&&s.start.row>=e.end.row&&(s.start.row+=o,s.end.row+=o)}s.end=this.insert(s.start,r);if(i.length){var a=e.start,l=s.start,o=l.row-a.row,u=l.column-a.column;this.addFolds(i.map(function(e){return e=e.clone(),e.start.row==a.row&&(e.start.column+=u),e.end.row==a.row&&(e.end.column+=u),e.start.row+=o,e.end.row+=o,e}))}return s},this.indentRows=function(e,t,n){n=n.replace(/\t/g,this.getTabString());for(var r=e;r<=t;r++)this.insert({row:r,column:0},n)},this.outdentRows=function(e){var t=e.collapseRows(),n=new f(0,0,0,0),r=this.getTabSize();for(var i=t.start.row;i<=t.end.row;++i){var s=this.getLine(i);n.start.row=i,n.end.row=i;for(var o=0;o<r;++o)if(s.charAt(o)!=" ")break;o<r&&s.charAt(o)=="	"?(n.start.column=o,n.end.column=o+1):(n.start.column=0,n.end.column=o),this.remove(n)}},this.$moveLines=function(e,t,n){e=this.getRowFoldStart(e),t=this.getRowFoldEnd(t);if(n<0){var r=this.getRowFoldStart(e+n);if(r<0)return 0;var i=r-e}else if(n>0){var r=this.getRowFoldEnd(t+n);if(r>this.doc.getLength()-1)return 0;var i=r-t}else{e=this.$clipRowToDocument(e),t=this.$clipRowToDocument(t);var i=t-e+1}var s=new f(e,0,t,Number.MAX_VALUE),o=this.getFoldsInRange(s).map(function(e){return e=e.clone(),e.start.row+=i,e.end.row+=i,e}),u=n==0?this.doc.getLines(e,t):this.doc.removeLines(e,t);return this.doc.insertLines(e+i,u),o.length&&this.addFolds(o),i},this.moveLinesUp=function(e,t){return this.$moveLines(e,t,-1)},this.moveLinesDown=function(e,t){return this.$moveLines(e,t,1)},this.duplicateLines=function(e,t){return this.$moveLines(e,t,0)},this.$clipRowToDocument=function(e){return Math.max(0,Math.min(e,this.doc.getLength()-1))},this.$clipColumnToRow=function(e,t){return t<0?0:Math.min(this.doc.getLine(e).length,t)},this.$clipPositionToDocument=function(e,t){t=Math.max(0,t);if(e<0)e=0,t=0;else{var n=this.doc.getLength();e>=n?(e=n-1,t=this.doc.getLine(n-1).length):t=Math.min(this.doc.getLine(e).length,t)}return{row:e,column:t}},this.$clipRangeToDocument=function(e){e.start.row<0?(e.start.row=0,e.start.column=0):e.start.column=this.$clipColumnToRow(e.start.row,e.start.column);var t=this.doc.getLength()-1;return e.end.row>t?(e.end.row=t,e.end.column=this.doc.getLine(t).length):e.end.column=this.$clipColumnToRow(e.end.row,e.end.column),e},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(e){if(e!=this.$useWrapMode){this.$useWrapMode=e,this.$modified=!0,this.$resetRowCache(0);if(e){var t=this.getLength();this.$wrapData=Array(t),this.$updateWrapData(0,t-1)}this._signal("changeWrapMode")}},this.getUseWrapMode=function(){return this.$useWrapMode},this.setWrapLimitRange=function(e,t){if(this.$wrapLimitRange.min!==e||this.$wrapLimitRange.max!==t)this.$wrapLimitRange={min:e,max:t},this.$modified=!0,this._signal("changeWrapMode")},this.adjustWrapLimit=function(e,t){var n=this.$wrapLimitRange;n.max<0&&(n={min:t,max:t});var r=this.$constrainWrapLimit(e,n.min,n.max);return r!=this.$wrapLimit&&r>1?(this.$wrapLimit=r,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._signal("changeWrapLimit")),!0):!1},this.$constrainWrapLimit=function(e,t,n){return t&&(e=Math.max(t,e)),n&&(e=Math.min(n,e)),e},this.getWrapLimit=function(){return this.$wrapLimit},this.setWrapLimit=function(e){this.setWrapLimitRange(e,e)},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(e){var t=this.$useWrapMode,n,r=e.data.action,i=e.data.range.start.row,s=e.data.range.end.row,o=e.data.range.start,u=e.data.range.end,a=null;r.indexOf("Lines")!=-1?(r=="insertLines"?s=i+e.data.lines.length:s=i,n=e.data.lines?e.data.lines.length:s-i):n=s-i,this.$updating=!0;if(n!=0)if(r.indexOf("remove")!=-1){this[t?"$wrapData":"$rowLengthCache"].splice(i,n);var f=this.$foldData;a=this.getFoldsInRange(e.data.range),this.removeFolds(a);var l=this.getFoldLine(u.row),c=0;if(l){l.addRemoveChars(u.row,u.column,o.column-u.column),l.shiftRow(-n);var h=this.getFoldLine(i);h&&h!==l&&(h.merge(l),l=h),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=u.row&&l.shiftRow(-n)}s=i}else{var p=Array(n);p.unshift(i,0);var d=t?this.$wrapData:this.$rowLengthCache;d.splice.apply(d,p);var f=this.$foldData,l=this.getFoldLine(i),c=0;if(l){var v=l.range.compareInside(o.row,o.column);v==0?(l=l.split(o.row,o.column),l.shiftRow(n),l.addRemoveChars(s,0,u.column-o.column)):v==-1&&(l.addRemoveChars(i,0,u.column-o.column),l.shiftRow(n)),c=f.indexOf(l)+1}for(c;c<f.length;c++){var l=f[c];l.start.row>=i&&l.shiftRow(n)}}else{n=Math.abs(e.data.range.start.column-e.data.range.end.column),r.indexOf("remove")!=-1&&(a=this.getFoldsInRange(e.data.range),this.removeFolds(a),n=-n);var l=this.getFoldLine(i);l&&l.addRemoveChars(i,o.column,n)}return t&&this.$wrapData.length!=this.doc.getLength()&&console.error("doc.getLength() and $wrapData.length have to be the same!"),this.$updating=!1,t?this.$updateWrapData(i,s):this.$updateRowLengthCache(i,s),a},this.$updateRowLengthCache=function(e,t,n){this.$rowLengthCache[e]=null,this.$rowLengthCache[t]=null},this.$updateWrapData=function(e,t){var n=this.doc.getAllLines(),r=this.getTabSize(),i=this.$wrapData,s=this.$wrapLimit,o,a,f=e;t=Math.min(t,n.length-1);while(f<=t)a=this.getFoldLine(f,a),a?(o=[],a.walk(function(e,t,r,i){var s;if(e!=null){s=this.$getDisplayTokens(e,o.length),s[0]=u;for(var a=1;a<s.length;a++)s[a]=l}else s=this.$getDisplayTokens(n[t].substring(i,r),o.length);o=o.concat(s)}.bind(this),a.end.row,n[a.end.row].length+1),i[a.start.row]=this.$computeWrapSplits(o,s,r),f=a.end.row+1):(o=this.$getDisplayTokens(n[f]),i[f]=this.$computeWrapSplits(o,s,r),f++)};var t=1,n=2,u=3,l=4,p=9,d=10,v=11,m=12;this.$computeWrapSplits=function(e,t){function a(t){var r=e.slice(i,t),o=r.length;r.join("").replace(/12/g,function(){o-=1}).replace(/2/g,function(){o-=1}),s+=o,n.push(s),i=t}if(e.length==0)return[];var n=[],r=e.length,i=0,s=0,o=this.$wrapAsCode;while(r-i>t){var f=i+t;if(e[f-1]>=d&&e[f]>=d){a(f);continue}if(e[f]==u||e[f]==l){for(f;f!=i-1;f--)if(e[f]==u)break;if(f>i){a(f);continue}f=i+t;for(f;f<e.length;f++)if(e[f]!=l)break;if(f==e.length)break;a(f);continue}var c=Math.max(f-(o?10:t-(t>>2)),i-1);while(f>c&&e[f]<u)f--;if(o){while(f>c&&e[f]<u)f--;while(f>c&&e[f]==p)f--}else while(f>c&&e[f]<d)f--;if(f>c){a(++f);continue}f=i+t,a(f)}return n},this.$getDisplayTokens=function(e,r){var i=[],s;r=r||0;for(var o=0;o<e.length;o++){var u=e.charCodeAt(o);if(u==9){s=this.getScreenTabSize(i.length+r),i.push(v);for(var a=1;a<s;a++)i.push(m)}else u==32?i.push(d):u>39&&u<48||u>57&&u<64?i.push(p):u>=4352&&g(u)?i.push(t,n):i.push(t)}return i},this.$getStringScreenWidth=function(e,t,n){if(t==0)return[0,0];t==null&&(t=Infinity),n=n||0;var r,i;for(i=0;i<e.length;i++){r=e.charCodeAt(i),r==9?n+=this.getScreenTabSize(n):r>=4352&&g(r)?n+=2:n+=1;if(n>t)break}return[n,i]},this.lineWidgets=null,this.getRowLength=function(e){if(this.lineWidgets)var t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0;else t=0;return!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.getRowLineCount=function(e){return!this.$useWrapMode||!this.$wrapData[e]?1:this.$wrapData[e].length+1},this.getScreenLastRowColumn=function(e){var t=this.screenToDocumentPosition(e,Number.MAX_VALUE);return this.documentToScreenColumn(t.row,t.column)},this.getDocumentLastRowColumn=function(e,t){var n=this.documentToScreenRow(e,t);return this.getScreenLastRowColumn(n)},this.getDocumentLastRowColumnPosition=function(e,t){var n=this.documentToScreenRow(e,t);return this.screenToDocumentPosition(n,Number.MAX_VALUE/10)},this.getRowSplitData=function(e){return this.$useWrapMode?this.$wrapData[e]:undefined},this.getScreenTabSize=function(e){return this.$tabSize-e%this.$tabSize},this.screenToDocumentRow=function(e,t){return this.screenToDocumentPosition(e,t).row},this.screenToDocumentColumn=function(e,t){return this.screenToDocumentPosition(e,t).column},this.screenToDocumentPosition=function(e,t){if(e<0)return{row:0,column:0};var n,r=0,i=0,s,o=0,u=0,a=this.$screenRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var o=a[f],r=this.$docRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getLength()-1,p=this.getNextFoldLine(r),d=p?p.start.row:Infinity;while(o<=e){u=this.getRowLength(r);if(o+u>e||r>=h)break;o+=u,r++,r>d&&(r=p.end.row+1,p=this.getNextFoldLine(r,p),d=p?p.start.row:Infinity),c&&(this.$docRowCache.push(r),this.$screenRowCache.push(o))}if(p&&p.start.row<=r)n=this.getFoldDisplayLine(p),r=p.start.row;else{if(o+u<=e||r>h)return{row:h,column:this.getLine(h).length};n=this.getLine(r),p=null}if(this.$useWrapMode){var v=this.$wrapData[r];if(v){var m=Math.floor(e-o);s=v[m],m>0&&v.length&&(i=v[m-1]||v[v.length-1],n=n.substring(i))}}return i+=this.$getStringScreenWidth(n,t)[1],this.$useWrapMode&&i>=s&&(i=s-1),p?p.idxToPosition(i):{row:r,column:i}},this.documentToScreenPosition=function(e,t){if(typeof t=="undefined")var n=this.$clipPositionToDocument(e.row,e.column);else n=this.$clipPositionToDocument(e,t);e=n.row,t=n.column;var r=0,i=null,s=null;s=this.getFoldAt(e,t,1),s&&(e=s.start.row,t=s.start.column);var o,u=0,a=this.$docRowCache,f=this.$getRowCacheIndex(a,e),l=a.length;if(l&&f>=0)var u=a[f],r=this.$screenRowCache[f],c=e>a[l-1];else var c=!l;var h=this.getNextFoldLine(u),p=h?h.start.row:Infinity;while(u<e){if(u>=p){o=h.end.row+1;if(o>e)break;h=this.getNextFoldLine(o,h),p=h?h.start.row:Infinity}else o=u+1;r+=this.getRowLength(u),u=o,c&&(this.$docRowCache.push(u),this.$screenRowCache.push(r))}var d="";h&&u>=p?(d=this.getFoldDisplayLine(h,e,t),i=h.start.row):(d=this.getLine(e).substring(0,t),i=e);if(this.$useWrapMode){var v=this.$wrapData[i];if(v){var m=0;while(d.length>=v[m])r++,m++;d=d.substring(v[m-1]||0,d.length)}}return{row:r,column:this.$getStringScreenWidth(d)[0]}},this.documentToScreenColumn=function(e,t){return this.documentToScreenPosition(e,t).column},this.documentToScreenRow=function(e,t){return this.documentToScreenPosition(e,t).row},this.getScreenLength=function(){var e=0,t=null;if(!this.$useWrapMode){e=this.getLength();var n=this.$foldData;for(var r=0;r<n.length;r++)t=n[r],e-=t.end.row-t.start.row}else{var i=this.$wrapData.length,s=0,r=0,t=this.$foldData[r++],o=t?t.start.row:Infinity;while(s<i){var u=this.$wrapData[s];e+=u?u.length+1:1,s++,s>o&&(s=t.end.row+1,t=this.$foldData[r++],o=t?t.start.row:Infinity)}}return this.lineWidgets&&(e+=this.$getWidgetScreenLength()),e},this.$setFontMetrics=function(e){}}).call(p.prototype),e("./edit_session/folding").Folding.call(p.prototype),e("./edit_session/bracket_match").BracketMatch.call(p.prototype),s.defineOptions(p.prototype,"session",{wrap:{set:function(e){!e||e=="off"?e=!1:e=="free"?e=!0:e=="printMargin"?e=-1:typeof e=="string"&&(e=parseInt(e,10)||!1);if(this.$wrap==e)return;if(!e)this.setUseWrapMode(!1);else{var t=typeof e=="number"?e:null;this.setWrapLimitRange(t,t),this.setUseWrapMode(!0)}this.$wrap=e},get:function(){return this.getUseWrapMode()?this.$wrap==-1?"printMargin":this.getWrapLimitRange().min?this.$wrap:"free":"off"},handlesSet:!0},wrapMethod:{set:function(e){e=e=="auto"?this.$mode.type!="text":e!="text",e!=this.$wrapAsCode&&(this.$wrapAsCode=e,this.$useWrapMode&&(this.$modified=!0,this.$resetRowCache(0),this.$updateWrapData(0,this.getLength()-1)))},initialValue:"auto"},firstLineNumber:{set:function(){this._signal("changeBreakpoint")},initialValue:1},useWorker:{set:function(e){this.$useWorker=e,this.$stopWorker(),e&&this.$startWorker()},initialValue:!0},useSoftTabs:{initialValue:!0},tabSize:{set:function(e){if(isNaN(e)||this.$tabSize===e)return;this.$modified=!0,this.$rowLengthCache=[],this.$tabSize=e,this._signal("changeTabSize")},initialValue:4,handlesSet:!0},overwrite:{set:function(e){this._signal("changeOverwrite")},initialValue:!1},newLineMode:{set:function(e){this.doc.setNewLineMode(e)},get:function(){return this.doc.getNewLineMode()},handlesSet:!0},mode:{set:function(e){this.setMode(e)},get:function(){return this.$modeId}}}),t.EditSession=p}),ace.define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"],function(e,t,n){"use strict";var r=e("./lib/lang"),i=e("./lib/oop"),s=e("./range").Range,o=function(){this.$options={}};(function(){this.set=function(e){return i.mixin(this.$options,e),this},this.getOptions=function(){return r.copyObject(this.$options)},this.setOptions=function(e){this.$options=e},this.find=function(e){var t=this.$matchIterator(e,this.$options);if(!t)return!1;var n=null;return t.forEach(function(e,t,r){if(!e.start){var i=e.offset+(r||0);n=new s(t,i,t,i+e.length)}else n=e;return!0}),n},this.findAll=function(e){var t=this.$options;if(!t.needle)return[];this.$assembleRegExp(t);var n=t.range,i=n?e.getLines(n.start.row,n.end.row):e.doc.getAllLines(),o=[],u=t.re;if(t.$isMultiLine){var a=u.length,f=i.length-a,l;e:for(var c=u.offset||0;c<=f;c++){for(var h=0;h<a;h++)if(i[c+h].search(u[h])==-1)continue e;var p=i[c],d=i[c+a-1],v=p.length-p.match(u[0])[0].length,m=d.match(u[a-1])[0].length;if(l&&l.end.row===c&&l.end.column>v)continue;o.push(l=new s(c,v,c+a-1,m)),a>2&&(c=c+a-2)}}else for(var g=0;g<i.length;g++){var y=r.getMatchOffsets(i[g],u);for(var h=0;h<y.length;h++){var b=y[h];o.push(new s(g,b.offset,g,b.offset+b.length))}}if(n){var w=n.start.column,E=n.start.column,g=0,h=o.length-1;while(g<h&&o[g].start.column<w&&o[g].start.row==n.start.row)g++;while(g<h&&o[h].end.column>E&&o[h].end.row==n.end.row)h--;o=o.slice(g,h+1);for(g=0,h=o.length;g<h;g++)o[g].start.row+=n.start.row,o[g].end.row+=n.start.row}return o},this.replace=function(e,t){var n=this.$options,r=this.$assembleRegExp(n);if(n.$isMultiLine)return t;if(!r)return;var i=r.exec(e);if(!i||i[0].length!=e.length)return null;t=e.replace(r,t);if(n.preserveCase){t=t.split("");for(var s=Math.min(e.length,e.length);s--;){var o=e[s];o&&o.toLowerCase()!=o?t[s]=t[s].toUpperCase():t[s]=t[s].toLowerCase()}t=t.join("")}return t},this.$matchIterator=function(e,t){var n=this.$assembleRegExp(t);if(!n)return!1;var i=this,o,u=t.backwards;if(t.$isMultiLine)var a=n.length,f=function(t,r,i){var u=t.search(n[0]);if(u==-1)return;for(var f=1;f<a;f++){t=e.getLine(r+f);if(t.search(n[f])==-1)return}var l=t.match(n[a-1])[0].length,c=new s(r,u,r+a-1,l);n.offset==1?(c.start.row--,c.start.column=Number.MAX_VALUE):i&&(c.start.column+=i);if(o(c))return!0};else if(u)var f=function(e,t,i){var s=r.getMatchOffsets(e,n);for(var u=s.length-1;u>=0;u--)if(o(s[u],t,i))return!0};else var f=function(e,t,i){var s=r.getMatchOffsets(e,n);for(var u=0;u<s.length;u++)if(o(s[u],t,i))return!0};return{forEach:function(n){o=n,i.$lineIterator(e,t).forEach(f)}}},this.$assembleRegExp=function(e,t){if(e.needle instanceof RegExp)return e.re=e.needle;var n=e.needle;if(!e.needle)return e.re=!1;e.regExp||(n=r.escapeRegExp(n)),e.wholeWord&&(n="\\b"+n+"\\b");var i=e.caseSensitive?"g":"gi";e.$isMultiLine=!t&&/[\n\r]/.test(n);if(e.$isMultiLine)return e.re=this.$assembleMultilineRegExp(n,i);try{var s=new RegExp(n,i)}catch(o){s=!1}return e.re=s},this.$assembleMultilineRegExp=function(e,t){var n=e.replace(/\r\n|\r|\n/g,"$\n^").split("\n"),r=[];for(var i=0;i<n.length;i++)try{r.push(new RegExp(n[i],t))}catch(s){return!1}return n[0]==""?(r.shift(),r.offset=1):r.offset=0,r},this.$lineIterator=function(e,t){var n=t.backwards==1,r=t.skipCurrent!=0,i=t.range,s=t.start;s||(s=i?i[n?"end":"start"]:e.selection.getRange()),s.start&&(s=s[r!=n?"end":"start"]);var o=i?i.start.row:0,u=i?i.end.row:e.getLength()-1,a=n?function(n){var r=s.row,i=e.getLine(r).substring(0,s.column);if(n(i,r))return;for(r--;r>=o;r--)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=u,o=s.row;r>=o;r--)if(n(e.getLine(r),r))return}:function(n){var r=s.row,i=e.getLine(r).substr(s.column);if(n(i,r,s.column))return;for(r+=1;r<=u;r++)if(n(e.getLine(r),r))return;if(t.wrap==0)return;for(r=o,u=s.row;r<=u;r++)if(n(e.getLine(r),r))return};return{forEach:a}}}).call(o.prototype),t.Search=o}),ace.define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"],function(e,t,n){"use strict";function s(e,t){this.platform=t||(i.isMac?"mac":"win"),this.commands={},this.commandKeyBinding={};if(this.__defineGetter__&&this.__defineSetter__&&typeof console!="undefined"&&console.error){var n=!1,r=function(){n||(n=!0,console.error("commmandKeyBinding has too many m's. use commandKeyBinding"))};this.__defineGetter__("commmandKeyBinding",function(){return r(),this.commandKeyBinding}),this.__defineSetter__("commmandKeyBinding",function(e){return r(),this.commandKeyBinding=e})}else this.commmandKeyBinding=this.commandKeyBinding;this.addCommands(e)}var r=e("../lib/keys"),i=e("../lib/useragent");(function(){this.addCommand=function(e){this.commands[e.name]&&this.removeCommand(e),this.commands[e.name]=e,e.bindKey&&this._buildKeyHash(e)},this.removeCommand=function(e){var t=typeof e=="string"?e:e.name;e=this.commands[t],delete this.commands[t];var n=this.commandKeyBinding;for(var r in n)for(var i in n[r])n[r][i]==e&&delete n[r][i]},this.bindKey=function(e,t){if(!e)return;if(typeof t=="function"){this.addCommand({exec:t,bindKey:e,name:t.name||e});return}var n=this.commandKeyBinding;e.split("|").forEach(function(e){var r=this.parseKeys(e,t),i=r.hashId;(n[i]||(n[i]={}))[r.key]=t},this)},this.addCommands=function(e){e&&Object.keys(e).forEach(function(t){var n=e[t];if(!n)return;if(typeof n=="string")return this.bindKey(n,t);typeof n=="function"&&(n={exec:n});if(typeof n!="object")return;n.name||(n.name=t),this.addCommand(n)},this)},this.removeCommands=function(e){Object.keys(e).forEach(function(t){this.removeCommand(e[t])},this)},this.bindKeys=function(e){Object.keys(e).forEach(function(t){this.bindKey(t,e[t])},this)},this._buildKeyHash=function(e){var t=e.bindKey;if(!t)return;var n=typeof t=="string"?t:t[this.platform];this.bindKey(n,e)},this.parseKeys=function(e){e.indexOf(" ")!=-1&&(e=e.split(/\s+/).pop());var t=e.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(e){return e}),n=t.pop(),i=r[n];if(r.FUNCTION_KEYS[i])n=r.FUNCTION_KEYS[i].toLowerCase();else{if(!t.length)return{key:n,hashId:-1};if(t.length==1&&t[0]=="shift")return{key:n.toUpperCase(),hashId:-1}}var s=0;for(var o=t.length;o--;){var u=r.KEY_MODS[t[o]];if(u==null)return typeof console!="undefined"&&console.error("invalid modifier "+t[o]+" in "+e),!1;s|=u}return{key:n,hashId:s}},this.findKeyCommand=function(t,n){var r=this.commandKeyBinding;return r[t]&&r[t][n]},this.handleKeyboard=function(e,t,n,r){return{command:this.findKeyCommand(t,n)}}}).call(s.prototype),t.HashHandler=s}),ace.define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../keyboard/hash_handler").HashHandler,s=e("../lib/event_emitter").EventEmitter,o=function(e,t){i.call(this,t,e),this.byName=this.commands,this.setDefaultHandler("exec",function(e){return e.command.exec(e.editor,e.args||{})})};r.inherits(o,i),function(){r.implement(this,s),this.exec=function(e,t,n){typeof e=="string"&&(e=this.commands[e]);if(!e)return!1;if(t&&t.$readOnly&&!e.readOnly)return!1;var r={editor:t,command:e,args:n},i=this._emit("exec",r);return this._signal("afterExec",r),i===!1?!1:!0},this.toggleRecording=function(e){if(this.$inReplay)return;return e&&e._emit("changeStatus"),this.recording?(this.macro.pop(),this.removeEventListener("exec",this.$addCommandToMacro),this.macro.length||(this.macro=this.oldMacro),this.recording=!1):(this.$addCommandToMacro||(this.$addCommandToMacro=function(e){this.macro.push([e.command,e.args])}.bind(this)),this.oldMacro=this.macro,this.macro=[],this.on("exec",this.$addCommandToMacro),this.recording=!0)},this.replay=function(e){if(this.$inReplay||!this.macro)return;if(this.recording)return this.toggleRecording(e);try{this.$inReplay=!0,this.macro.forEach(function(t){typeof t=="string"?this.exec(t,e):this.exec(t[0],e,t[1])},this)}finally{this.$inReplay=!1}},this.trimMacro=function(e){return e.map(function(e){return typeof e[0]!="string"&&(e[0]=e[0].name),e[1]||(e=e[0]),e})}}.call(o.prototype),t.CommandManager=o}),ace.define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"],function(e,t,n){"use strict";function o(e,t){return{win:e,mac:t}}var r=e("../lib/lang"),i=e("../config"),s=e("../range").Range;t.commands=[{name:"showSettingsMenu",bindKey:o("Ctrl-,","Command-,"),exec:function(e){i.loadModule("ace/ext/settings_menu",function(t){t.init(e),e.showSettingsMenu()})},readOnly:!0},{name:"goToNextError",bindKey:o("Alt-E","Ctrl-E"),exec:function(e){i.loadModule("ace/ext/error_marker",function(t){t.showErrorMarker(e,1)})},scrollIntoView:"animate",readOnly:!0},{name:"goToPreviousError",bindKey:o("Alt-Shift-E","Ctrl-Shift-E"),exec:function(e){i.loadModule("ace/ext/error_marker",function(t){t.showErrorMarker(e,-1)})},scrollIntoView:"animate",readOnly:!0},{name:"selectall",bindKey:o("Ctrl-A","Command-A"),exec:function(e){e.selectAll()},readOnly:!0},{name:"centerselection",bindKey:o(null,"Ctrl-L"),exec:function(e){e.centerSelection()},readOnly:!0},{name:"gotoline",bindKey:o("Ctrl-L","Command-L"),exec:function(e){var t=parseInt(prompt("Enter line number:"),10);isNaN(t)||e.gotoLine(t)},readOnly:!0},{name:"fold",bindKey:o("Alt-L|Ctrl-F1","Command-Alt-L|Command-F1"),exec:function(e){e.session.toggleFold(!1)},scrollIntoView:"center",readOnly:!0},{name:"unfold",bindKey:o("Alt-Shift-L|Ctrl-Shift-F1","Command-Alt-Shift-L|Command-Shift-F1"),exec:function(e){e.session.toggleFold(!0)},scrollIntoView:"center",readOnly:!0},{name:"toggleFoldWidget",bindKey:o("F2","F2"),exec:function(e){e.session.toggleFoldWidget()},scrollIntoView:"center",readOnly:!0},{name:"toggleParentFoldWidget",bindKey:o("Alt-F2","Alt-F2"),exec:function(e){e.session.toggleFoldWidget(!0)},scrollIntoView:"center",readOnly:!0},{name:"foldall",bindKey:o("Ctrl-Alt-0","Ctrl-Command-Option-0"),exec:function(e){e.session.foldAll()},scrollIntoView:"center",readOnly:!0},{name:"foldOther",bindKey:o("Alt-0","Command-Option-0"),exec:function(e){e.session.foldAll(),e.session.unfold(e.selection.getAllRanges())},scrollIntoView:"center",readOnly:!0},{name:"unfoldall",bindKey:o("Alt-Shift-0","Command-Option-Shift-0"),exec:function(e){e.session.unfold()},scrollIntoView:"center",readOnly:!0},{name:"findnext",bindKey:o("Ctrl-K","Command-G"),exec:function(e){e.findNext()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"findprevious",bindKey:o("Ctrl-Shift-K","Command-Shift-G"),exec:function(e){e.findPrevious()},multiSelectAction:"forEach",scrollIntoView:"center",readOnly:!0},{name:"selectOrFindNext",bindKey:o("Alt-K","Ctrl-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findNext()},readOnly:!0},{name:"selectOrFindPrevious",bindKey:o("Alt-Shift-K","Ctrl-Shift-G"),exec:function(e){e.selection.isEmpty()?e.selection.selectWord():e.findPrevious()},readOnly:!0},{name:"find",bindKey:o("Ctrl-F","Command-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e)})},readOnly:!0},{name:"overwrite",bindKey:"Insert",exec:function(e){e.toggleOverwrite()},readOnly:!0},{name:"selecttostart",bindKey:o("Ctrl-Shift-Home","Command-Shift-Up"),exec:function(e){e.getSelection().selectFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotostart",bindKey:o("Ctrl-Home","Command-Home|Command-Up"),exec:function(e){e.navigateFileStart()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectup",bindKey:o("Shift-Up","Shift-Up"),exec:function(e){e.getSelection().selectUp()},multiSelectAction:"forEach",readOnly:!0},{name:"golineup",bindKey:o("Up","Up|Ctrl-P"),exec:function(e,t){e.navigateUp(t.times)},multiSelectAction:"forEach",readOnly:!0},{name:"selecttoend",bindKey:o("Ctrl-Shift-End","Command-Shift-Down"),exec:function(e){e.getSelection().selectFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"gotoend",bindKey:o("Ctrl-End","Command-End|Command-Down"),exec:function(e){e.navigateFileEnd()},multiSelectAction:"forEach",readOnly:!0,scrollIntoView:"animate",aceCommandGroup:"fileJump"},{name:"selectdown",bindKey:o("Shift-Down","Shift-Down"),exec:function(e){e.getSelection().selectDown()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"golinedown",bindKey:o("Down","Down|Ctrl-N"),exec:function(e,t){e.navigateDown(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordleft",bindKey:o("Ctrl-Shift-Left","Option-Shift-Left"),exec:function(e){e.getSelection().selectWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordleft",bindKey:o("Ctrl-Left","Option-Left"),exec:function(e){e.navigateWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolinestart",bindKey:o("Alt-Shift-Left","Command-Shift-Left"),exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolinestart",bindKey:o("Alt-Left|Home","Command-Left|Home|Ctrl-A"),exec:function(e){e.navigateLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectleft",bindKey:o("Shift-Left","Shift-Left"),exec:function(e){e.getSelection().selectLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoleft",bindKey:o("Left","Left|Ctrl-B"),exec:function(e,t){e.navigateLeft(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectwordright",bindKey:o("Ctrl-Shift-Right","Option-Shift-Right"),exec:function(e){e.getSelection().selectWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotowordright",bindKey:o("Ctrl-Right","Option-Right"),exec:function(e){e.navigateWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selecttolineend",bindKey:o("Alt-Shift-Right","Command-Shift-Right"),exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotolineend",bindKey:o("Alt-Right|End","Command-Right|End|Ctrl-E"),exec:function(e){e.navigateLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectright",bindKey:o("Shift-Right","Shift-Right"),exec:function(e){e.getSelection().selectRight()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"gotoright",bindKey:o("Right","Right|Ctrl-F"),exec:function(e,t){e.navigateRight(t.times)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectpagedown",bindKey:"Shift-PageDown",exec:function(e){e.selectPageDown()},readOnly:!0},{name:"pagedown",bindKey:o(null,"Option-PageDown"),exec:function(e){e.scrollPageDown()},readOnly:!0},{name:"gotopagedown",bindKey:o("PageDown","PageDown|Ctrl-V"),exec:function(e){e.gotoPageDown()},readOnly:!0},{name:"selectpageup",bindKey:"Shift-PageUp",exec:function(e){e.selectPageUp()},readOnly:!0},{name:"pageup",bindKey:o(null,"Option-PageUp"),exec:function(e){e.scrollPageUp()},readOnly:!0},{name:"gotopageup",bindKey:"PageUp",exec:function(e){e.gotoPageUp()},readOnly:!0},{name:"scrollup",bindKey:o("Ctrl-Up",null),exec:function(e){e.renderer.scrollBy(0,-2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"scrolldown",bindKey:o("Ctrl-Down",null),exec:function(e){e.renderer.scrollBy(0,2*e.renderer.layerConfig.lineHeight)},readOnly:!0},{name:"selectlinestart",bindKey:"Shift-Home",exec:function(e){e.getSelection().selectLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"selectlineend",bindKey:"Shift-End",exec:function(e){e.getSelection().selectLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"togglerecording",bindKey:o("Ctrl-Alt-E","Command-Option-E"),exec:function(e){e.commands.toggleRecording(e)},readOnly:!0},{name:"replaymacro",bindKey:o("Ctrl-Shift-E","Command-Shift-E"),exec:function(e){e.commands.replay(e)},readOnly:!0},{name:"jumptomatching",bindKey:o("Ctrl-P","Ctrl-P"),exec:function(e){e.jumpToMatching()},multiSelectAction:"forEach",readOnly:!0},{name:"selecttomatching",bindKey:o("Ctrl-Shift-P","Ctrl-Shift-P"),exec:function(e){e.jumpToMatching(!0)},multiSelectAction:"forEach",readOnly:!0},{name:"passKeysToBrowser",bindKey:o("null","null"),exec:function(){},passEvent:!0,readOnly:!0},{name:"cut",exec:function(e){var t=e.getSelectionRange();e._emit("cut",t),e.selection.isEmpty()||(e.session.remove(t),e.clearSelection())},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"removeline",bindKey:o("Ctrl-D","Command-D"),exec:function(e){e.removeLines()},scrollIntoView:"cursor",multiSelectAction:"forEachLine"},{name:"duplicateSelection",bindKey:o("Ctrl-Shift-D","Command-Shift-D"),exec:function(e){e.duplicateSelection()},scrollIntoView:"cursor",multiSelectAction:"forEach"},{name:"sortlines",bindKey:o("Ctrl-Alt-S","Command-Alt-S"),exec:function(e){e.sortLines()},scrollIntoView:"selection",multiSelectAction:"forEachLine"},{name:"togglecomment",bindKey:o("Ctrl-/","Command-/"),exec:function(e){e.toggleCommentLines()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"toggleBlockComment",bindKey:o("Ctrl-Shift-/","Command-Shift-/"),exec:function(e){e.toggleBlockComment()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"modifyNumberUp",bindKey:o("Ctrl-Shift-Up","Alt-Shift-Up"),exec:function(e){e.modifyNumber(1)},multiSelectAction:"forEach"},{name:"modifyNumberDown",bindKey:o("Ctrl-Shift-Down","Alt-Shift-Down"),exec:function(e){e.modifyNumber(-1)},multiSelectAction:"forEach"},{name:"replace",bindKey:o("Ctrl-H","Command-Option-F"),exec:function(e){i.loadModule("ace/ext/searchbox",function(t){t.Search(e,!0)})}},{name:"undo",bindKey:o("Ctrl-Z","Command-Z"),exec:function(e){e.undo()}},{name:"redo",bindKey:o("Ctrl-Shift-Z|Ctrl-Y","Command-Shift-Z|Command-Y"),exec:function(e){e.redo()}},{name:"copylinesup",bindKey:o("Alt-Shift-Up","Command-Option-Up"),exec:function(e){e.copyLinesUp()},scrollIntoView:"cursor"},{name:"movelinesup",bindKey:o("Alt-Up","Option-Up"),exec:function(e){e.moveLinesUp()},scrollIntoView:"cursor"},{name:"copylinesdown",bindKey:o("Alt-Shift-Down","Command-Option-Down"),exec:function(e){e.copyLinesDown()},scrollIntoView:"cursor"},{name:"movelinesdown",bindKey:o("Alt-Down","Option-Down"),exec:function(e){e.moveLinesDown()},scrollIntoView:"cursor"},{name:"del",bindKey:o("Delete","Delete|Ctrl-D|Shift-Delete"),exec:function(e){e.remove("right")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"backspace",bindKey:o("Shift-Backspace|Backspace","Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"),exec:function(e){e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"cut_or_delete",bindKey:o("Shift-Delete",null),exec:function(e){if(!e.selection.isEmpty())return!1;e.remove("left")},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolinestart",bindKey:o("Alt-Backspace","Command-Backspace"),exec:function(e){e.removeToLineStart()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removetolineend",bindKey:o("Alt-Delete","Ctrl-K"),exec:function(e){e.removeToLineEnd()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordleft",bindKey:o("Ctrl-Backspace","Alt-Backspace|Ctrl-Alt-Backspace"),exec:function(e){e.removeWordLeft()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"removewordright",bindKey:o("Ctrl-Delete","Alt-Delete"),exec:function(e){e.removeWordRight()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"outdent",bindKey:o("Shift-Tab","Shift-Tab"),exec:function(e){e.blockOutdent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"indent",bindKey:o("Tab","Tab"),exec:function(e){e.indent()},multiSelectAction:"forEach",scrollIntoView:"selectionPart"},{name:"blockoutdent",bindKey:o("Ctrl-[","Ctrl-["),exec:function(e){e.blockOutdent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"blockindent",bindKey:o("Ctrl-]","Ctrl-]"),exec:function(e){e.blockIndent()},multiSelectAction:"forEachLine",scrollIntoView:"selectionPart"},{name:"insertstring",exec:function(e,t){e.insert(t)},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"inserttext",exec:function(e,t){e.insert(r.stringRepeat(t.text||"",t.times||1))},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"splitline",bindKey:o(null,"Ctrl-O"),exec:function(e){e.splitLine()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"transposeletters",bindKey:o("Ctrl-T","Ctrl-T"),exec:function(e){e.transposeLetters()},multiSelectAction:function(e){e.transposeSelections(1)},scrollIntoView:"cursor"},{name:"touppercase",bindKey:o("Ctrl-U","Ctrl-U"),exec:function(e){e.toUpperCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"tolowercase",bindKey:o("Ctrl-Shift-U","Ctrl-Shift-U"),exec:function(e){e.toLowerCase()},multiSelectAction:"forEach",scrollIntoView:"cursor"},{name:"expandtoline",bindKey:o("Ctrl-Shift-L","Command-Shift-L"),exec:function(e){var t=e.selection.getRange();t.start.column=t.end.column=0,t.end.row++,e.selection.setRange(t,!1)},multiSelectAction:"forEach",scrollIntoView:"cursor",readOnly:!0},{name:"joinlines",bindKey:o(null,null),exec:function(e){var t=e.selection.isBackwards(),n=t?e.selection.getSelectionLead():e.selection.getSelectionAnchor(),i=t?e.selection.getSelectionAnchor():e.selection.getSelectionLead(),o=e.session.doc.getLine(n.row).length,u=e.session.doc.getTextRange(e.selection.getRange()),a=u.replace(/\n\s*/," ").length,f=e.session.doc.getLine(n.row);for(var l=n.row+1;l<=i.row+1;l++){var c=r.stringTrimLeft(r.stringTrimRight(e.session.doc.getLine(l)));c.length!==0&&(c=" "+c),f+=c}i.row+1<e.session.doc.getLength()-1&&(f+=e.session.doc.getNewLineCharacter()),e.clearSelection(),e.session.doc.replace(new s(n.row,0,i.row+2,0),f),a>0?(e.selection.moveCursorTo(n.row,n.column),e.selection.selectTo(n.row,n.column+a)):(o=e.session.doc.getLine(n.row).length>o?o+1:o,e.selection.moveCursorTo(n.row,o))},multiSelectAction:"forEach",readOnly:!0},{name:"invertSelection",bindKey:o(null,null),exec:function(e){var t=e.session.doc.getLength()-1,n=e.session.doc.getLine(t).length,r=e.selection.rangeList.ranges,i=[];r.length<1&&(r=[e.selection.getRange()]);for(var o=0;o<r.length;o++)o==r.length-1&&(r[o].end.row!==t||r[o].end.column!==n)&&i.push(new s(r[o].end.row,r[o].end.column,t,n)),o===0?(r[o].start.row!==0||r[o].start.column!==0)&&i.push(new s(0,0,r[o].start.row,r[o].start.column)):i.push(new s(r[o-1].end.row,r[o-1].end.column,r[o].start.row,r[o].start.column));e.exitMultiSelectMode(),e.clearSelection();for(var o=0;o<i.length;o++)e.selection.addRange(i[o],!1)},readOnly:!0,scrollIntoView:"none"}]}),ace.define("ace/editor",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/keyboard/textinput","ace/mouse/mouse_handler","ace/mouse/fold_handler","ace/keyboard/keybinding","ace/edit_session","ace/search","ace/range","ace/lib/event_emitter","ace/commands/command_manager","ace/commands/default_commands","ace/config","ace/token_iterator"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./lib/lang"),o=e("./lib/useragent"),u=e("./keyboard/textinput").TextInput,a=e("./mouse/mouse_handler").MouseHandler,f=e("./mouse/fold_handler").FoldHandler,l=e("./keyboard/keybinding").KeyBinding,c=e("./edit_session").EditSession,h=e("./search").Search,p=e("./range").Range,d=e("./lib/event_emitter").EventEmitter,v=e("./commands/command_manager").CommandManager,m=e("./commands/default_commands").commands,g=e("./config"),y=e("./token_iterator").TokenIterator,b=function(e,t){var n=e.getContainerElement();this.container=n,this.renderer=e,this.commands=new v(o.isMac?"mac":"win",m),this.textInput=new u(e.getTextAreaContainer(),this),this.renderer.textarea=this.textInput.getElement(),this.keyBinding=new l(this),this.$mouseHandler=new a(this),new f(this),this.$blockScrolling=0,this.$search=(new h).set({wrap:!0}),this.$historyTracker=this.$historyTracker.bind(this),this.commands.on("exec",this.$historyTracker),this.$initOperationListeners(),this._$emitInputEvent=s.delayedCall(function(){this._signal("input",{}),this.session.bgTokenizer&&this.session.bgTokenizer.scheduleStart()}.bind(this)),this.on("change",function(e,t){t._$emitInputEvent.schedule(31)}),this.setSession(t||new c("")),g.resetOptions(this),g._signal("editor",this)};(function(){r.implement(this,d),this.$initOperationListeners=function(){function e(e){return e[e.length-1]}this.selections=[],this.commands.on("exec",function(t){this.startOperation(t);var n=t.command;if(n.aceCommandGroup=="fileJump"){var r=this.prevOp;if(!r||r.command.aceCommandGroup!="fileJump")this.lastFileJumpPos=e(this.selections)}else this.lastFileJumpPos=null}.bind(this),!0),this.commands.on("afterExec",function(e){var t=e.command;t.aceCommandGroup=="fileJump"&&this.lastFileJumpPos&&!this.curOp.selectionChanged&&this.selection.fromJSON(this.lastFileJumpPos),this.endOperation(e)}.bind(this),!0),this.$opResetTimer=s.delayedCall(this.endOperation.bind(this)),this.on("change",function(){this.curOp||this.startOperation(),this.curOp.docChanged=!0}.bind(this),!0),this.on("changeSelection",function(){this.curOp||this.startOperation(),this.curOp.selectionChanged=!0}.bind(this),!0)},this.curOp=null,this.prevOp={},this.startOperation=function(e){if(this.curOp){if(!e||this.curOp.command)return;this.prevOp=this.curOp}e||(this.previousCommand=null,e={}),this.$opResetTimer.schedule(),this.curOp={command:e.command||{},args:e.args,scrollTop:this.renderer.scrollTop};var t=this.curOp.command;t&&t.scrollIntoView&&this.$blockScrolling++,this.selections.push(this.selection.toJSON())},this.endOperation=function(){if(this.curOp){var e=this.curOp.command;if(e&&e.scrollIntoView){this.$blockScrolling--;switch(e.scrollIntoView){case"center":this.renderer.scrollCursorIntoView(null,.5);break;case"animate":case"cursor":this.renderer.scrollCursorIntoView();break;case"selectionPart":var t=this.selection.getRange(),n=this.renderer.layerConfig;(t.start.row>=n.lastRow||t.end.row<=n.firstRow)&&this.renderer.scrollSelectionIntoView(this.selection.anchor,this.selection.lead);break;default:}e.scrollIntoView=="animate"&&this.renderer.animateScrolling(this.curOp.scrollTop)}this.prevOp=this.curOp,this.curOp=null}},this.$mergeableCommands=["backspace","del","insertstring"],this.$historyTracker=function(e){if(!this.$mergeUndoDeltas)return;var t=this.prevOp,n=this.$mergeableCommands,r=t.command&&e.command.name==t.command.name;if(e.command.name=="insertstring"){var i=e.args;this.mergeNextCommand===undefined&&(this.mergeNextCommand=!0),r=r&&this.mergeNextCommand&&(!/\s/.test(i)||/\s/.test(t.args)),this.mergeNextCommand=!0}else r=r&&n.indexOf(e.command.name)!==-1;this.$mergeUndoDeltas!="always"&&Date.now()-this.sequenceStartTime>2e3&&(r=!1),r?this.session.mergeUndoDeltas=!0:n.indexOf(e.command.name)!==-1&&(this.sequenceStartTime=Date.now())},this.setKeyboardHandler=function(e){if(!e)this.keyBinding.setKeyboardHandler(null);else if(typeof e=="string"){this.$keybindingId=e;var t=this;g.loadModule(["keybinding",e],function(n){t.$keybindingId==e&&t.keyBinding.setKeyboardHandler(n&&n.handler)})}else this.$keybindingId=null,this.keyBinding.setKeyboardHandler(e)},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(e){if(this.session==e)return;var t=this.session;if(t){this.session.removeEventListener("change",this.$onDocumentChange),this.session.removeEventListener("changeMode",this.$onChangeMode),this.session.removeEventListener("tokenizerUpdate",this.$onTokenizerUpdate),this.session.removeEventListener("changeTabSize",this.$onChangeTabSize),this.session.removeEventListener("changeWrapLimit",this.$onChangeWrapLimit),this.session.removeEventListener("changeWrapMode",this.$onChangeWrapMode),this.session.removeEventListener("onChangeFold",this.$onChangeFold),this.session.removeEventListener("changeFrontMarker",this.$onChangeFrontMarker),this.session.removeEventListener("changeBackMarker",this.$onChangeBackMarker),this.session.removeEventListener("changeBreakpoint",this.$onChangeBreakpoint),this.session.removeEventListener("changeAnnotation",this.$onChangeAnnotation),this.session.removeEventListener("changeOverwrite",this.$onCursorChange),this.session.removeEventListener("changeScrollTop",this.$onScrollTopChange),this.session.removeEventListener("changeScrollLeft",this.$onScrollLeftChange);var n=this.session.getSelection();n.removeEventListener("changeCursor",this.$onCursorChange),n.removeEventListener("changeSelection",this.$onSelectionChange)}this.session=e,e&&(this.$onDocumentChange=this.onDocumentChange.bind(this),e.addEventListener("change",this.$onDocumentChange),this.renderer.setSession(e),this.$onChangeMode=this.onChangeMode.bind(this),e.addEventListener("changeMode",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),e.addEventListener("tokenizerUpdate",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.onChangeTabSize.bind(this.renderer),e.addEventListener("changeTabSize",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),e.addEventListener("changeWrapLimit",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),e.addEventListener("changeWrapMode",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),e.addEventListener("changeFold",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.addEventListener("changeFrontMarker",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.addEventListener("changeBackMarker",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.addEventListener("changeBreakpoint",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.addEventListener("changeAnnotation",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.addEventListener("changeOverwrite",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.addEventListener("changeScrollTop",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.addEventListener("changeScrollLeft",this.$onScrollLeftChange),this.selection=e.getSelection(),this.selection.addEventListener("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.addEventListener("changeSelection",this.$onSelectionChange),this.onChangeMode(),this.$blockScrolling+=1,this.onCursorChange(),this.$blockScrolling-=1,this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull()),this._signal("changeSession",{session:e,oldSession:t}),t&&t._signal("changeEditor",{oldEditor:this}),e&&e._signal("changeEditor",{editor:this})},this.getSession=function(){return this.session},this.setValue=function(e,t){return this.session.doc.setValue(e),t?t==1?this.navigateFileEnd():t==-1&&this.navigateFileStart():this.selectAll(),e},this.getValue=function(){return this.session.getValue()},this.getSelection=function(){return this.selection},this.resize=function(e){this.renderer.onResize(e)},this.setTheme=function(e,t){this.renderer.setTheme(e,t)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(e){this.renderer.setStyle(e)},this.unsetStyle=function(e){this.renderer.unsetStyle(e)},this.getFontSize=function(){return this.getOption("fontSize")||i.computedStyle(this.container,"fontSize")},this.setFontSize=function(e){this.setOption("fontSize",e)},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var e=this;this.$highlightPending=!0,setTimeout(function(){e.$highlightPending=!1;var t=e.session.findMatchingBracket(e.getCursorPosition());if(t)var n=new p(t.row,t.column,t.row,t.column+1);else if(e.session.$mode.getMatching)var n=e.session.$mode.getMatching(e.session);n&&(e.session.$bracketHighlight=e.session.addMarker(n,"ace_bracket","text"))},50)},this.$highlightTags=function(){var e=this.session;if(this.$highlightTagPending)return;var t=this;this.$highlightTagPending=!0,setTimeout(function(){t.$highlightTagPending=!1;var n=t.getCursorPosition(),r=new y(t.session,n.row,n.column),i=r.getCurrentToken();if(!i||i.type.indexOf("tag-name")===-1){e.removeMarker(e.$tagHighlight),e.$tagHighlight=null;return}var s=i.value,o=0,u=r.stepBackward();if(u.value=="<"){do u=i,i=r.stepForward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="</"&&o--);while(i&&o>=0)}else{do i=u,u=r.stepBackward(),i&&i.value===s&&i.type.indexOf("tag-name")!==-1&&(u.value==="<"?o++:u.value==="</"&&o--);while(u&&o<=0);r.stepForward()}if(!i){e.removeMarker(e.$tagHighlight),e.$tagHighlight=null;return}var a=r.getCurrentTokenRow(),f=r.getCurrentTokenColumn(),l=new p(a,f,a,f+i.value.length);e.$tagHighlight&&l.compareRange(e.$backMarkers[e.$tagHighlight].range)!==0&&(e.removeMarker(e.$tagHighlight),e.$tagHighlight=null),l&&!e.$tagHighlight&&(e.$tagHighlight=e.addMarker(l,"ace_bracket","text"))},50)},this.focus=function(){var e=this;setTimeout(function(){e.textInput.focus()}),this.textInput.focus()},this.isFocused=function(){return this.textInput.isFocused()},this.blur=function(){this.textInput.blur()},this.onFocus=function(){if(this.$isFocused)return;this.$isFocused=!0,this.renderer.showCursor(),this.renderer.visualizeFocus(),this._emit("focus")},this.onBlur=function(){if(!this.$isFocused)return;this.$isFocused=!1,this.renderer.hideCursor(),this.renderer.visualizeBlur(),this._emit("blur")},this.$cursorChange=function(){this.renderer.updateCursor()},this.onDocumentChange=function(e){var t=e.data,n=t.range,r;n.start.row==n.end.row&&t.action!="insertLines"&&t.action!="removeLines"?r=n.end.row:r=Infinity,this.renderer.updateLines(n.start.row,r),this._signal("change",e),this.$cursorChange()},this.onTokenizerUpdate=function(e){var t=e.data;this.renderer.updateLines(t.first,t.last)},this.onScrollTopChange=function(){this.renderer.scrollToY(this.session.getScrollTop())},this.onScrollLeftChange=function(){this.renderer.scrollToX(this.session.getScrollLeft())},this.onCursorChange=function(){this.$cursorChange(),this.$blockScrolling||this.renderer.scrollCursorIntoView(),this.$highlightBrackets(),this.$highlightTags(),this.$updateHighlightActiveLine(),this._signal("changeSelection")},this.$updateHighlightActiveLine=function(){var e=this.getSession(),t;if(this.$highlightActiveLine){if(this.$selectionStyle!="line"||!this.selection.isMultiLine())t=this.getCursorPosition();this.renderer.$maxLines&&this.session.getLength()===1&&!(this.renderer.$minLines>1)&&(t=!1)}if(e.$highlightLineMarker&&!t)e.removeMarker(e.$highlightLineMarker.id),e.$highlightLineMarker=null;else if(!e.$highlightLineMarker&&t){var n=new p(t.row,t.column,t.row,Infinity);n.id=e.addMarker(n,"ace_active-line","screenLine"),e.$highlightLineMarker=n}else t&&(e.$highlightLineMarker.start.row=t.row,e.$highlightLineMarker.end.row=t.row,e.$highlightLineMarker.start.column=t.column,e._signal("changeBackMarker"))},this.onSelectionChange=function(e){var t=this.session;t.$selectionMarker&&t.removeMarker(t.$selectionMarker),t.$selectionMarker=null;if(!this.selection.isEmpty()){var n=this.selection.getRange(),r=this.getSelectionStyle();t.$selectionMarker=t.addMarker(n,"ace_selection",r)}else this.$updateHighlightActiveLine();var i=this.$highlightSelectedWord&&this.$getSelectionHighLightRegexp();this.session.highlight(i),this._signal("changeSelection")},this.$getSelectionHighLightRegexp=function(){var e=this.session,t=this.getSelectionRange();if(t.isEmpty()||t.isMultiLine())return;var n=t.start.column-1,r=t.end.column+1,i=e.getLine(t.start.row),s=i.length,o=i.substring(Math.max(n,0),Math.min(r,s));if(n>=0&&/^[\w\d]/.test(o)||r<=s&&/[\w\d]$/.test(o))return;o=i.substring(t.start.column,t.end.column);if(!/^[\w\d]+$/.test(o))return;var u=this.$search.$assembleRegExp({wholeWord:!0,caseSensitive:!0,needle:o});return u},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.updateBreakpoints()},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(e){this.renderer.updateText(),this._emit("changeMode",e)},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getSelectedText=function(){return this.session.getTextRange(this.getSelectionRange())},this.getCopyText=function(){var e=this.getSelectedText();return this._signal("copy",e),e},this.onCopy=function(){this.commands.exec("copy",this)},this.onCut=function(){this.commands.exec("cut",this)},this.onPaste=function(e){if(this.$readOnly)return;var t={text:e};this._signal("paste",t),this.insert(t.text,!0)},this.execCommand=function(e,t){this.commands.exec(e,this,t)},this.insert=function(e,t){var n=this.session,r=n.getMode(),i=this.getCursorPosition();if(this.getBehavioursEnabled()&&!t){var s=r.transformAction(n.getState(i.row),"insertion",this,n,e);s&&(e!==s.text&&(this.session.mergeUndoDeltas=!1,this.$mergeNextCommand=!1),e=s.text)}e=="	"&&(e=this.session.getTabString());if(!this.selection.isEmpty()){var o=this.getSelectionRange();i=this.session.remove(o),this.clearSelection()}else if(this.session.getOverwrite()){var o=new p.fromPoints(i,i);o.end.column+=e.length,this.session.remove(o)}if(e=="\n"||e=="\r\n"){var u=n.getLine(i.row);if(i.column>u.search(/\S|$/)){var a=u.substr(i.column).search(/\S|$/);n.doc.removeInLine(i.row,i.column,i.column+a)}}this.clearSelection();var f=i.column,l=n.getState(i.row),u=n.getLine(i.row),c=r.checkOutdent(l,u,e),h=n.insert(i,e);s&&s.selection&&(s.selection.length==2?this.selection.setSelectionRange(new p(i.row,f+s.selection[0],i.row,f+s.selection[1])):this.selection.setSelectionRange(new p(i.row+s.selection[0],s.selection[1],i.row+s.selection[2],s.selection[3])));if(n.getDocument().isNewLine(e)){var d=r.getNextLineIndent(l,u.slice(0,i.column),n.getTabString());n.insert({row:i.row+1,column:0},d)}c&&r.autoOutdent(l,n,i.row)},this.onTextInput=function(e){this.keyBinding.onTextInput(e)},this.onCommandKey=function(e,t,n){this.keyBinding.onCommandKey(e,t,n)},this.setOverwrite=function(e){this.session.setOverwrite(e)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(e){this.setOption("scrollSpeed",e)},this.getScrollSpeed=function(){return this.getOption("scrollSpeed")},this.setDragDelay=function(e){this.setOption("dragDelay",e)},this.getDragDelay=function(){return this.getOption("dragDelay")},this.setSelectionStyle=function(e){this.setOption("selectionStyle",e)},this.getSelectionStyle=function(){return this.getOption("selectionStyle")},this.setHighlightActiveLine=function(e){this.setOption("highlightActiveLine",e)},this.getHighlightActiveLine=function(){return this.getOption("highlightActiveLine")},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.setHighlightSelectedWord=function(e){this.setOption("highlightSelectedWord",e)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(e){this.renderer.setAnimatedScroll(e)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(e){this.renderer.setShowInvisibles(e)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setDisplayIndentGuides=function(e){this.renderer.setDisplayIndentGuides(e)},this.getDisplayIndentGuides=function(){return this.renderer.getDisplayIndentGuides()},this.setShowPrintMargin=function(e){this.renderer.setShowPrintMargin(e)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(e){this.renderer.setPrintMarginColumn(e)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.setReadOnly=function(e){this.setOption("readOnly",e)},this.getReadOnly=function(){return this.getOption("readOnly")},this.setBehavioursEnabled=function(e){this.setOption("behavioursEnabled",e)},this.getBehavioursEnabled=function(){return this.getOption("behavioursEnabled")},this.setWrapBehavioursEnabled=function(e){this.setOption("wrapBehavioursEnabled",e)},this.getWrapBehavioursEnabled=function(){return this.getOption("wrapBehavioursEnabled")},this.setShowFoldWidgets=function(e){this.setOption("showFoldWidgets",e)},this.getShowFoldWidgets=function(){return this.getOption("showFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.remove=function(e){this.selection.isEmpty()&&(e=="left"?this.selection.selectLeft():this.selection.selectRight());var t=this.getSelectionRange();if(this.getBehavioursEnabled()){var n=this.session,r=n.getState(t.start.row),i=n.getMode().transformAction(r,"deletion",this,n,t);if(t.end.column===0){var s=n.getTextRange(t);if(s[s.length-1]=="\n"){var o=n.getLine(t.end.row);/^\s+$/.test(o)&&(t.end.column=o.length)}}i&&(t=i)}this.session.remove(t),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var e=this.getSelectionRange();e.start.column==e.end.column&&e.start.row==e.end.row&&(e.end.column=0,e.end.row++),this.session.remove(e),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var e=this.getCursorPosition();this.insert("\n"),this.moveCursorToPosition(e)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var e=this.getCursorPosition(),t=e.column;if(t===0)return;var n=this.session.getLine(e.row),r,i;t<n.length?(r=n.charAt(t)+n.charAt(t-1),i=new p(e.row,t-1,e.row,t+1)):(r=n.charAt(t-1)+n.charAt(t-2),i=new p(e.row,t-2,e.row,t)),this.session.replace(i,r)},this.toLowerCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toLowerCase()),this.selection.setSelectionRange(e)},this.toUpperCase=function(){var e=this.getSelectionRange();this.selection.isEmpty()&&this.selection.selectWord();var t=this.getSelectionRange(),n=this.session.getTextRange(t);this.session.replace(t,n.toUpperCase()),this.selection.setSelectionRange(e)},this.indent=function(){var e=this.session,t=this.getSelectionRange();if(t.start.row<t.end.row){var n=this.$getSelectedRows();e.indentRows(n.first,n.last,"	");return}if(t.start.column<t.end.column){var r=e.getTextRange(t);if(!/^\s+$/.test(r)){var n=this.$getSelectedRows();e.indentRows(n.first,n.last,"	");return}}var i=e.getLine(t.start.row),o=t.start,u=e.getTabSize(),a=e.documentToScreenColumn(o.row,o.column);if(this.session.getUseSoftTabs())var f=u-a%u,l=s.stringRepeat(" ",f);else{var f=a%u;while(i[t.start.column]==" "&&f)t.start.column--,f--;this.selection.setSelectionRange(t),l="	"}return this.insert(l)},this.blockIndent=function(){var e=this.$getSelectedRows();this.session.indentRows(e.first,e.last,"	")},this.blockOutdent=function(){var e=this.session.getSelection();this.session.outdentRows(e.getRange())},this.sortLines=function(){var e=this.$getSelectedRows(),t=this.session,n=[];for(i=e.first;i<=e.last;i++)n.push(t.getLine(i));n.sort(function(e,t){return e.toLowerCase()<t.toLowerCase()?-1:e.toLowerCase()>t.toLowerCase()?1:0});var r=new p(0,0,0,0);for(var i=e.first;i<=e.last;i++){var s=t.getLine(i);r.start.row=i,r.end.row=i,r.end.column=s.length,t.replace(r,n[i-e.first])}},this.toggleCommentLines=function(){var e=this.session.getState(this.getCursorPosition().row),t=this.$getSelectedRows();this.session.getMode().toggleCommentLines(e,this.session,t.first,t.last)},this.toggleBlockComment=function(){var e=this.getCursorPosition(),t=this.session.getState(e.row),n=this.getSelectionRange();this.session.getMode().toggleBlockComment(t,this.session,n,e)},this.getNumberAt=function(e,t){var n=/[\-]?[0-9]+(?:\.[0-9]+)?/g;n.lastIndex=0;var r=this.session.getLine(e);while(n.lastIndex<t){var i=n.exec(r);if(i.index<=t&&i.index+i[0].length>=t){var s={value:i[0],start:i.index,end:i.index+i[0].length};return s}}return null},this.modifyNumber=function(e){var t=this.selection.getCursor().row,n=this.selection.getCursor().column,r=new p(t,n-1,t,n),i=this.session.getTextRange(r);if(!isNaN(parseFloat(i))&&isFinite(i)){var s=this.getNumberAt(t,n);if(s){var o=s.value.indexOf(".")>=0?s.start+s.value.indexOf(".")+1:s.end,u=s.start+s.value.length-o,a=parseFloat(s.value);a*=Math.pow(10,u),o!==s.end&&n<o?e*=Math.pow(10,s.end-n-1):e*=Math.pow(10,s.end-n),a+=e,a/=Math.pow(10,u);var f=a.toFixed(u),l=new p(t,s.start,t,s.end);this.session.replace(l,f),this.moveCursorTo(t,Math.max(s.start+1,n+f.length-s.value.length))}}},this.removeLines=function(){var e=this.$getSelectedRows(),t;e.first===0||e.last+1<this.session.getLength()?t=new p(e.first,0,e.last+1,0):t=new p(e.first-1,this.session.getLine(e.first-1).length,e.last,this.session.getLine(e.last).length),this.session.remove(t),this.clearSelection()},this.duplicateSelection=function(){var e=this.selection,t=this.session,n=e.getRange(),r=e.isBackwards();if(n.isEmpty()){var i=n.start.row;t.duplicateLines(i,i)}else{var s=r?n.start:n.end,o=t.insert(s,t.getTextRange(n),!1);n.start=s,n.end=o,e.setSelectionRange(n,r)}},this.moveLinesDown=function(){this.$moveLines(function(e,t){return this.session.moveLinesDown(e,t)})},this.moveLinesUp=function(){this.$moveLines(function(e,t){return this.session.moveLinesUp(e,t)})},this.moveText=function(e,t,n){return this.session.moveText(e,t,n)},this.copyLinesUp=function(){this.$moveLines(function(e,t){return this.session.duplicateLines(e,t),0})},this.copyLinesDown=function(){this.$moveLines(function(e,t){return this.session.duplicateLines(e,t)})},this.$moveLines=function(e){var t=this.selection;if(!t.inMultiSelectMode||this.inVirtualSelectionMode){var n=t.toOrientedRange(),r=this.$getSelectedRows(n),i=e.call(this,r.first,r.last);n.moveBy(i,0),t.fromOrientedRange(n)}else{var s=t.rangeList.ranges;t.rangeList.detach(this.session);for(var o=s.length;o--;){var u=o,r=s[o].collapseRows(),a=r.end.row,f=r.start.row;while(o--){r=s[o].collapseRows();if(!(f-r.end.row<=1))break;f=r.end.row}o++;var i=e.call(this,f,a);while(u>=o)s[u].moveBy(i,0),u--}t.fromOrientedRange(t.ranges[0]),t.rangeList.attach(this.session)}},this.$getSelectedRows=function(){var e=this.getSelectionRange().collapseRows();return{first:this.session.getRowFoldStart(e.start.row),last:this.session.getRowFoldEnd(e.end.row)}},this.onCompositionStart=function(e){this.renderer.showComposition(this.getCursorPosition())},this.onCompositionUpdate=function(e){this.renderer.setCompositionText(e)},this.onCompositionEnd=function(){this.renderer.hideComposition()},this.getFirstVisibleRow=function(){return this.renderer.getFirstVisibleRow()},this.getLastVisibleRow=function(){return this.renderer.getLastVisibleRow()},this.isRowVisible=function(e){return e>=this.getFirstVisibleRow()&&e<=this.getLastVisibleRow()},this.isRowFullyVisible=function(e){return e>=this.renderer.getFirstFullyVisibleRow()&&e<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$moveByPage=function(e,t){var n=this.renderer,r=this.renderer.layerConfig,i=e*Math.floor(r.height/r.lineHeight);this.$blockScrolling++,t===!0?this.selection.$moveSelection(function(){this.moveCursorBy(i,0)}):t===!1&&(this.selection.moveCursorBy(i,0),this.selection.clearSelection()),this.$blockScrolling--;var s=n.scrollTop;n.scrollBy(0,i*r.lineHeight),t!=null&&n.scrollCursorIntoView(null,.5),n.animateScrolling(s)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(e){this.renderer.scrollToRow(e)},this.scrollToLine=function(e,t,n,r){this.renderer.scrollToLine(e,t,n,r)},this.centerSelection=function(){var e=this.getSelectionRange(),t={row:Math.floor(e.start.row+(e.end.row-e.start.row)/2),column:Math.floor(e.start.column+(e.end.column-e.start.column)/2)};this.renderer.alignCursor(t,.5)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.$blockScrolling+=1,this.selection.selectAll(),this.$blockScrolling-=1},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(e,t){this.selection.moveCursorTo(e,t)},this.moveCursorToPosition=function(e){this.selection.moveCursorToPosition(e)},this.jumpToMatching=function(e){var t=this.getCursorPosition(),n=new y(this.session,t.row,t.column),r=n.getCurrentToken(),i=r;i||(i=n.stepForward());if(!i)return;var s,o=!1,u={},a=t.column-i.start,f,l={")":"(","(":"(","]":"[","[":"[","{":"{","}":"{"};do{if(i.value.match(/[{}()\[\]]/g))for(;a<i.value.length&&!o;a++){if(!l[i.value[a]])continue;f=l[i.value[a]]+"."+i.type.replace("rparen","lparen"),isNaN(u[f])&&(u[f]=0);switch(i.value[a]){case"(":case"[":case"{":u[f]++;break;case")":case"]":case"}":u[f]--,u[f]===-1&&(s="bracket",o=!0)}}else i&&i.type.indexOf("tag-name")!==-1&&(isNaN(u[i.value])&&(u[i.value]=0),r.value==="<"?u[i.value]++:r.value==="</"&&u[i.value]--,u[i.value]===-1&&(s="tag",o=!0));o||(r=i,i=n.stepForward(),a=0)}while(i&&!o);if(!s)return;var c;if(s==="bracket"){c=this.session.getBracketRange(t);if(!c){c=new p(n.getCurrentTokenRow(),n.getCurrentTokenColumn()+a-1,n.getCurrentTokenRow(),n.getCurrentTokenColumn()+a-1);if(!c)return;var h=c.start;h.row===t.row&&Math.abs(h.column-t.column)<2&&(c=this.session.getBracketRange(h))}}else if(s==="tag"){if(!i||i.type.indexOf("tag-name")===-1)return;var d=i.value,c=new p(n.getCurrentTokenRow(),n.getCurrentTokenColumn()-2,n.getCurrentTokenRow(),n.getCurrentTokenColumn()-2);if(c.compare(t.row,t.column)===0){o=!1;do i=r,r=n.stepBackward(),r&&(r.type.indexOf("tag-close")!==-1&&c.setEnd(n.getCurrentTokenRow(),n.getCurrentTokenColumn()+1),i.value===d&&i.type.indexOf("tag-name")!==-1&&(r.value==="<"?u[d]++:r.value==="</"&&u[d]--,u[d]===0&&(o=!0)));while(r&&!o)}if(i&&i.type.indexOf("tag-name")){var h=c.start;h.row==t.row&&Math.abs(h.column-t.column)<2&&(h=c.end)}}h=c&&c.cursor||h,h&&(e?c&&c.isEqual(this.getSelectionRange())?this.clearSelection():this.selection.selectTo(h.row,h.column):this.selection.moveTo(h.row,h.column))},this.gotoLine=function(e,t,n){this.selection.clearSelection(),this.session.unfold({row:e-1,column:t||0}),this.$blockScrolling+=1,this.exitMultiSelectMode&&this.exitMultiSelectMode(),this.moveCursorTo(e-1,t||0),this.$blockScrolling-=1,this.isRowFullyVisible(e-1)||this.scrollToLine(e-1,!0,n)},this.navigateTo=function(e,t){this.selection.moveTo(e,t)},this.navigateUp=function(e){if(this.selection.isMultiLine()&&!this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(-e||-1,0)},this.navigateDown=function(e){if(this.selection.isMultiLine()&&this.selection.isBackwards()){var t=this.selection.anchor.getPosition();return this.moveCursorToPosition(t)}this.selection.clearSelection(),this.selection.moveCursorBy(e||1,0)},this.navigateLeft=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().start;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorLeft()}this.clearSelection()},this.navigateRight=function(e){if(!this.selection.isEmpty()){var t=this.getSelectionRange().end;this.moveCursorToPosition(t)}else{e=e||1;while(e--)this.selection.moveCursorRight()}this.clearSelection()},this.navigateLineStart=function(){this.selection.moveCursorLineStart(),this.clearSelection()},this.navigateLineEnd=function(){this.selection.moveCursorLineEnd(),this.clearSelection()},this.navigateFileEnd=function(){this.selection.moveCursorFileEnd(),this.clearSelection()},this.navigateFileStart=function(){this.selection.moveCursorFileStart(),this.clearSelection()},this.navigateWordRight=function(){this.selection.moveCursorWordRight(),this.clearSelection()},this.navigateWordLeft=function(){this.selection.moveCursorWordLeft(),this.clearSelection()},this.replace=function(e,t){t&&this.$search.set(t);var n=this.$search.find(this.session),r=0;return n?(this.$tryReplace(n,e)&&(r=1),n!==null&&(this.selection.setSelectionRange(n),this.renderer.scrollSelectionIntoView(n.start,n.end)),r):r},this.replaceAll=function(e,t){t&&this.$search.set(t);var n=this.$search.findAll(this.session),r=0;if(!n.length)return r;this.$blockScrolling+=1;var i=this.getSelectionRange();this.selection.moveTo(0,0);for(var s=n.length-1;s>=0;--s)this.$tryReplace(n[s],e)&&r++;return this.selection.setSelectionRange(i),this.$blockScrolling-=1,r},this.$tryReplace=function(e,t){var n=this.session.getTextRange(e);return t=this.$search.replace(n,t),t!==null?(e.end=this.session.replace(e,t),e):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(e,t,n){t||(t={}),typeof e=="string"||e instanceof RegExp?t.needle=e:typeof e=="object"&&r.mixin(t,e);var i=this.selection.getRange();t.needle==null&&(e=this.session.getTextRange(i)||this.$search.$options.needle,e||(i=this.session.getWordRange(i.start.row,i.start.column),e=this.session.getTextRange(i)),this.$search.set({needle:e})),this.$search.set(t),t.start||this.$search.set({start:i});var s=this.$search.find(this.session);if(t.preventScroll)return s;if(s)return this.revealRange(s,n),s;t.backwards?i.start=i.end:i.end=i.start,this.selection.setRange(i)},this.findNext=function(e,t){this.find({skipCurrent:!0,backwards:!1},e,t)},this.findPrevious=function(e,t){this.find(e,{skipCurrent:!0,backwards:!0},t)},this.revealRange=function(e,t){this.$blockScrolling+=1,this.session.unfold(e),this.selection.setSelectionRange(e),this.$blockScrolling-=1;var n=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(e.start,e.end,.5),t!==!1&&this.renderer.animateScrolling(n)},this.undo=function(){this.$blockScrolling++,this.session.getUndoManager().undo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.$blockScrolling++,this.session.getUndoManager().redo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy(),this._signal("destroy",this)},this.setAutoScrollEditorIntoView=function(e){if(!e)return;var t,n=this,r=!1;this.$scrollAnchor||(this.$scrollAnchor=document.createElement("div"));var i=this.$scrollAnchor;i.style.cssText="position:absolute",this.container.insertBefore(i,this.container.firstChild);var s=this.on("changeSelection",function(){r=!0}),o=this.renderer.on("beforeRender",function(){r&&(t=n.renderer.container.getBoundingClientRect())}),u=this.renderer.on("afterRender",function(){if(r&&t&&n.isFocused()){var e=n.renderer,s=e.$cursorLayer.$pixelPos,o=e.layerConfig,u=s.top-o.offset;s.top>=0&&u+t.top<0?r=!0:s.top<o.height&&s.top+t.top+o.lineHeight>window.innerHeight?r=!1:r=null,r!=null&&(i.style.top=u+"px",i.style.left=s.left+"px",i.style.height=o.lineHeight+"px",i.scrollIntoView(r)),r=t=null}});this.setAutoScrollEditorIntoView=function(e){if(e)return;delete this.setAutoScrollEditorIntoView,this.removeEventListener("changeSelection",s),this.renderer.removeEventListener("afterRender",u),this.renderer.removeEventListener("beforeRender",o)}},this.$resetCursorStyle=function(){var e=this.$cursorStyle||"ace",t=this.renderer.$cursorLayer;if(!t)return;t.setSmoothBlinking(/smooth/.test(e)),t.isBlinking=!this.$readOnly&&e!="wide",i.setCssClass(t.element,"ace_slim-cursors",/slim/.test(e))}}).call(b.prototype),g.defineOptions(b.prototype,"editor",{selectionStyle:{set:function(e){this.onSelectionChange(),this._signal("changeSelectionStyle",{data:e})},initialValue:"line"},highlightActiveLine:{set:function(){this.$updateHighlightActiveLine()},initialValue:!0},highlightSelectedWord:{set:function(e){this.$onSelectionChange()},initialValue:!0},readOnly:{set:function(e){this.$resetCursorStyle()},initialValue:!1},cursorStyle:{set:function(e){this.$resetCursorStyle()},values:["ace","slim","smooth","wide"],initialValue:"ace"},mergeUndoDeltas:{values:[!1,!0,"always"],initialValue:!0},behavioursEnabled:{initialValue:!0},wrapBehavioursEnabled:{initialValue:!0},autoScrollEditorIntoView:{set:function(e){this.setAutoScrollEditorIntoView(e)}},hScrollBarAlwaysVisible:"renderer",vScrollBarAlwaysVisible:"renderer",highlightGutterLine:"renderer",animatedScroll:"renderer",showInvisibles:"renderer",showPrintMargin:"renderer",printMarginColumn:"renderer",printMargin:"renderer",fadeFoldWidgets:"renderer",showFoldWidgets:"renderer",showLineNumbers:"renderer",showGutter:"renderer",displayIndentGuides:"renderer",fontSize:"renderer",fontFamily:"renderer",maxLines:"renderer",minLines:"renderer",scrollPastEnd:"renderer",fixedWidthGutter:"renderer",theme:"renderer",scrollSpeed:"$mouseHandler",dragDelay:"$mouseHandler",dragEnabled:"$mouseHandler",focusTimout:"$mouseHandler",tooltipFollowsMouse:"$mouseHandler",firstLineNumber:"session",overwrite:"session",newLineMode:"session",useWorker:"session",useSoftTabs:"session",tabSize:"session",wrap:"session",foldStyle:"session",mode:"session"}),t.Editor=b}),ace.define("ace/undomanager",["require","exports","module"],function(e,t,n){"use strict";var r=function(){this.reset()};(function(){this.execute=function(e){var t=e.args[0];this.$doc=e.args[1],e.merge&&this.hasUndo()&&(this.dirtyCounter--,t=this.$undoStack.pop().concat(t)),this.$undoStack.push(t),this.$redoStack=[],this.dirtyCounter<0&&(this.dirtyCounter=NaN),this.dirtyCounter++},this.undo=function(e){var t=this.$undoStack.pop(),n=null;return t&&(n=this.$doc.undoChanges(t,e),this.$redoStack.push(t),this.dirtyCounter--),n},this.redo=function(e){var t=this.$redoStack.pop(),n=null;return t&&(n=this.$doc.redoChanges(t,e),this.$undoStack.push(t),this.dirtyCounter++),n},this.reset=function(){this.$undoStack=[],this.$redoStack=[],this.dirtyCounter=0},this.hasUndo=function(){return this.$undoStack.length>0},this.hasRedo=function(){return this.$redoStack.length>0},this.markClean=function(){this.dirtyCounter=0},this.isClean=function(){return this.dirtyCounter===0}}).call(r.prototype),t.UndoManager=r}),ace.define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=e("../lib/oop"),s=e("../lib/lang"),o=e("../lib/event_emitter").EventEmitter,u=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_gutter-layer",e.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$annotations=[],this.$updateAnnotations=this.$updateAnnotations.bind(this),this.$cells=[]};(function(){i.implement(this,o),this.setSession=function(e){this.session&&this.session.removeEventListener("change",this.$updateAnnotations),this.session=e,e.on("change",this.$updateAnnotations)},this.addGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.addGutterDecoration"),this.session.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){window.console&&console.warn&&console.warn("deprecated use session.removeGutterDecoration"),this.session.removeGutterDecoration(e,t)},this.setAnnotations=function(e){this.$annotations=[];for(var t=0;t<e.length;t++){var n=e[t],r=n.row,i=this.$annotations[r];i||(i=this.$annotations[r]={text:[]});var o=n.text;o=o?s.escapeHTML(o):n.html||"",i.text.indexOf(o)===-1&&i.text.push(o);var u=n.type;u=="error"?i.className=" ace_error":u=="warning"&&i.className!=" ace_error"?i.className=" ace_warning":u=="info"&&!i.className&&(i.className=" ace_info")}},this.$updateAnnotations=function(e){if(!this.$annotations.length)return;var t=e.data,n=t.range,r=n.start.row,i=n.end.row-r;if(i!==0)if(t.action=="removeText"||t.action=="removeLines")this.$annotations.splice(r,i+1,null);else{var s=new Array(i+1);s.unshift(r,1),this.$annotations.splice.apply(this.$annotations,s)}},this.update=function(e){var t=this.session,n=e.firstRow,i=Math.min(e.lastRow+e.gutterOffset,t.getLength()-1),s=t.getNextFoldLine(n),o=s?s.start.row:Infinity,u=this.$showFoldWidgets&&t.foldWidgets,a=t.$breakpoints,f=t.$decorations,l=t.$firstLineNumber,c=0,h=t.gutterRenderer||this.$renderer,p=null,d=-1,v=n;for(;;){v>o&&(v=s.end.row+1,s=t.getNextFoldLine(v,s),o=s?s.start.row:Infinity);if(v>i){while(this.$cells.length>d+1)p=this.$cells.pop(),this.element.removeChild(p.element);break}p=this.$cells[++d],p||(p={element:null,textNode:null,foldWidget:null},p.element=r.createElement("div"),p.textNode=document.createTextNode(""),p.element.appendChild(p.textNode),this.element.appendChild(p.element),this.$cells[d]=p);var m="ace_gutter-cell ";a[v]&&(m+=a[v]),f[v]&&(m+=f[v]),this.$annotations[v]&&(m+=this.$annotations[v].className),p.element.className!=m&&(p.element.className=m);var g=t.getRowLength(v)*e.lineHeight+"px";g!=p.element.style.height&&(p.element.style.height=g);if(u){var y=u[v];y==null&&(y=u[v]=t.getFoldWidget(v))}if(y){p.foldWidget||(p.foldWidget=r.createElement("span"),p.element.appendChild(p.foldWidget));var m="ace_fold-widget ace_"+y;y=="start"&&v==o&&v<s.end.row?m+=" ace_closed":m+=" ace_open",p.foldWidget.className!=m&&(p.foldWidget.className=m);var g=e.lineHeight+"px";p.foldWidget.style.height!=g&&(p.foldWidget.style.height=g)}else p.foldWidget&&(p.element.removeChild(p.foldWidget),p.foldWidget=null);var b=c=h?h.getText(t,v):v+l;b!=p.textNode.data&&(p.textNode.data=b),v++}this.element.style.height=e.minHeight+"px";if(this.$fixedWidth||t.$useWrapMode)c=t.getLength()+l;var w=h?h.getWidth(t,c,e):c.toString().length*e.characterWidth,E=this.$padding||this.$computePadding();w+=E.left+E.right,w!==this.gutterWidth&&!isNaN(w)&&(this.gutterWidth=w,this.element.style.width=Math.ceil(this.gutterWidth)+"px",this._emit("changeGutterWidth",w))},this.$fixedWidth=!1,this.$showLineNumbers=!0,this.$renderer="",this.setShowLineNumbers=function(e){this.$renderer=!e&&{getWidth:function(){return""},getText:function(){return""}}},this.getShowLineNumbers=function(){return this.$showLineNumbers},this.$showFoldWidgets=!0,this.setShowFoldWidgets=function(e){e?r.addCssClass(this.element,"ace_folding-enabled"):r.removeCssClass(this.element,"ace_folding-enabled"),this.$showFoldWidgets=e,this.$padding=null},this.getShowFoldWidgets=function(){return this.$showFoldWidgets},this.$computePadding=function(){if(!this.element.firstChild)return{left:0,right:0};var e=r.computedStyle(this.element.firstChild);return this.$padding={},this.$padding.left=parseInt(e.paddingLeft)+1||0,this.$padding.right=parseInt(e.paddingRight)||0,this.$padding},this.getRegion=function(e){var t=this.$padding||this.$computePadding(),n=this.element.getBoundingClientRect();if(e.x<t.left+n.left)return"markers";if(this.$showFoldWidgets&&e.x>n.right-t.right)return"foldWidgets"}}).call(u.prototype),t.Gutter=u}),ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../lib/dom"),s=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_marker-layer",e.appendChild(this.element)};(function(){this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setMarkers=function(e){this.markers=e},this.update=function(e){var e=e||this.config;if(!e)return;this.config=e;var t=[];for(var n in this.markers){var r=this.markers[n];if(!r.range){r.update(t,this,this.session,e);continue}var i=r.range.clipRows(e.firstRow,e.lastRow);if(i.isEmpty())continue;i=i.toScreenRange(this.session);if(r.renderer){var s=this.$getTop(i.start.row,e),o=this.$padding+i.start.column*e.characterWidth;r.renderer(t,i,o,s,e)}else r.type=="fullLine"?this.drawFullLineMarker(t,i,r.clazz,e):r.type=="screenLine"?this.drawScreenLineMarker(t,i,r.clazz,e):i.isMultiLine()?r.type=="text"?this.drawTextMarker(t,i,r.clazz,e):this.drawMultiLineMarker(t,i,r.clazz,e):this.drawSingleLineMarker(t,i,r.clazz+" ace_start",e)}this.element.innerHTML=t.join("")},this.$getTop=function(e,t){return(e-t.firstRowScreen)*t.lineHeight},this.drawTextMarker=function(e,t,n,i,s){var o=t.start.row,u=new r(o,t.start.column,o,this.session.getScreenLastRowColumn(o));this.drawSingleLineMarker(e,u,n+" ace_start",i,1,s),o=t.end.row,u=new r(o,0,o,t.end.column),this.drawSingleLineMarker(e,u,n,i,0,s);for(o=t.start.row+1;o<t.end.row;o++)u.start.row=o,u.end.row=o,u.end.column=this.session.getScreenLastRowColumn(o),this.drawSingleLineMarker(e,u,n,i,1,s)},this.drawMultiLineMarker=function(e,t,n,r,i){var s=this.$padding,o=r.lineHeight,u=this.$getTop(t.start.row,r),a=s+t.start.column*r.characterWidth;i=i||"",e.push("<div class='",n," ace_start' style='","height:",o,"px;","right:0;","top:",u,"px;","left:",a,"px;",i,"'></div>"),u=this.$getTop(t.end.row,r);var f=t.end.column*r.characterWidth;e.push("<div class='",n,"' style='","height:",o,"px;","width:",f,"px;","top:",u,"px;","left:",s,"px;",i,"'></div>"),o=(t.end.row-t.start.row-1)*r.lineHeight;if(o<0)return;u=this.$getTop(t.start.row+1,r),e.push("<div class='",n,"' style='","height:",o,"px;","right:0;","top:",u,"px;","left:",s,"px;",i,"'></div>")},this.drawSingleLineMarker=function(e,t,n,r,i,s){var o=r.lineHeight,u=(t.end.column+(i||0)-t.start.column)*r.characterWidth,a=this.$getTop(t.start.row,r),f=this.$padding+t.start.column*r.characterWidth;e.push("<div class='",n,"' style='","height:",o,"px;","width:",u,"px;","top:",a,"px;","left:",f,"px;",s||"","'></div>")},this.drawFullLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;t.start.row!=t.end.row&&(o+=this.$getTop(t.end.row,r)-s),e.push("<div class='",n,"' style='","height:",o,"px;","top:",s,"px;","left:0;right:0;",i||"","'></div>")},this.drawScreenLineMarker=function(e,t,n,r,i){var s=this.$getTop(t.start.row,r),o=r.lineHeight;e.push("<div class='",n,"' style='","height:",o,"px;","top:",s,"px;","left:0;right:0;",i||"","'></div>")}}).call(s.prototype),t.Marker=s}),ace.define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/useragent"),u=e("../lib/event_emitter").EventEmitter,a=function(e){this.element=i.createElement("div"),this.element.className="ace_layer ace_text-layer",e.appendChild(this.element),this.$updateEolChar=this.$updateEolChar.bind(this)};(function(){r.implement(this,u),this.EOF_CHAR="\u00b6",this.EOL_CHAR_LF="\u00ac",this.EOL_CHAR_CRLF="\u00a4",this.EOL_CHAR=this.EOL_CHAR_LF,this.TAB_CHAR="\u2192",this.SPACE_CHAR="\u00b7",this.$padding=0,this.$updateEolChar=function(){var e=this.session.doc.getNewLineCharacter()=="\n"?this.EOL_CHAR_LF:this.EOL_CHAR_CRLF;if(this.EOL_CHAR!=e)return this.EOL_CHAR=e,!0},this.setPadding=function(e){this.$padding=e,this.element.style.padding="0 "+e+"px"},this.getLineHeight=function(){return this.$fontMetrics.$characterSize.height||0},this.getCharacterWidth=function(){return this.$fontMetrics.$characterSize.width||0},this.$setFontMetrics=function(e){this.$fontMetrics=e,this.$fontMetrics.on("changeCharacterSize",function(e){this._signal("changeCharacterSize",e)}.bind(this)),this.$pollSizeChanges()},this.checkForSizeChanges=function(){this.$fontMetrics.checkForSizeChanges()},this.$pollSizeChanges=function(){return this.$pollSizeChangesTimer=this.$fontMetrics.$pollSizeChanges()},this.setSession=function(e){this.session=e,this.$computeTabString()},this.showInvisibles=!1,this.setShowInvisibles=function(e){return this.showInvisibles==e?!1:(this.showInvisibles=e,this.$computeTabString(),!0)},this.displayIndentGuides=!0,this.setDisplayIndentGuides=function(e){return this.displayIndentGuides==e?!1:(this.displayIndentGuides=e,this.$computeTabString(),!0)},this.$tabStrings=[],this.onChangeTabSize=this.$computeTabString=function(){var e=this.session.getTabSize();this.tabSize=e;var t=this.$tabStrings=[0];for(var n=1;n<e+1;n++)this.showInvisibles?t.push("<span class='ace_invisible ace_invisible_tab'>"+this.TAB_CHAR+s.stringRepeat("\u00a0",n-1)+"</span>"):t.push(s.stringRepeat("\u00a0",n));if(this.displayIndentGuides){this.$indentGuideRe=/\s\S| \t|\t |\s$/;var r="ace_indent-guide",i="",o="";if(this.showInvisibles){r+=" ace_invisible",i=" ace_invisible_space",o=" ace_invisible_tab";var u=s.stringRepeat(this.SPACE_CHAR,this.tabSize),a=this.TAB_CHAR+s.stringRepeat("\u00a0",this.tabSize-1)}else var u=s.stringRepeat("\u00a0",this.tabSize),a=u;this.$tabStrings[" "]="<span class='"+r+i+"'>"+u+"</span>",this.$tabStrings["	"]="<span class='"+r+o+"'>"+a+"</span>"}},this.updateLines=function(e,t,n){(this.config.lastRow!=e.lastRow||this.config.firstRow!=e.firstRow)&&this.scrollLines(e),this.config=e;var r=Math.max(t,e.firstRow),i=Math.min(n,e.lastRow),s=this.element.childNodes,o=0;for(var u=e.firstRow;u<r;u++){var a=this.session.getFoldLine(u);if(a){if(a.containsRow(r)){r=a.start.row;break}u=a.end.row}o++}var u=r,a=this.session.getNextFoldLine(u),f=a?a.start.row:Infinity;for(;;){u>f&&(u=a.end.row+1,a=this.session.getNextFoldLine(u,a),f=a?a.start.row:Infinity);if(u>i)break;var l=s[o++];if(l){var c=[];this.$renderLine(c,u,!this.$useLineGroups(),u==f?a:!1),l.style.height=e.lineHeight*this.session.getRowLength(u)+"px",l.innerHTML=c.join("")}u++}},this.scrollLines=function(e){var t=this.config;this.config=e;if(!t||t.lastRow<e.firstRow)return this.update(e);if(e.lastRow<t.firstRow)return this.update(e);var n=this.element;if(t.firstRow<e.firstRow)for(var r=this.session.getFoldedRowCount(t.firstRow,e.firstRow-1);r>0;r--)n.removeChild(n.firstChild);if(t.lastRow>e.lastRow)for(var r=this.session.getFoldedRowCount(e.lastRow+1,t.lastRow);r>0;r--)n.removeChild(n.lastChild);if(e.firstRow<t.firstRow){var i=this.$renderLinesFragment(e,e.firstRow,t.firstRow-1);n.firstChild?n.insertBefore(i,n.firstChild):n.appendChild(i)}if(e.lastRow>t.lastRow){var i=this.$renderLinesFragment(e,t.lastRow+1,e.lastRow);n.appendChild(i)}},this.$renderLinesFragment=function(e,t,n){var r=this.element.ownerDocument.createDocumentFragment(),s=t,o=this.session.getNextFoldLine(s),u=o?o.start.row:Infinity;for(;;){s>u&&(s=o.end.row+1,o=this.session.getNextFoldLine(s,o),u=o?o.start.row:Infinity);if(s>n)break;var a=i.createElement("div"),f=[];this.$renderLine(f,s,!1,s==u?o:!1),a.innerHTML=f.join("");if(this.$useLineGroups())a.className="ace_line_group",r.appendChild(a),a.style.height=e.lineHeight*this.session.getRowLength(s)+"px";else while(a.firstChild)r.appendChild(a.firstChild);s++}return r},this.update=function(e){this.config=e;var t=[],n=e.firstRow,r=e.lastRow,i=n,s=this.session.getNextFoldLine(i),o=s?s.start.row:Infinity;for(;;){i>o&&(i=s.end.row+1,s=this.session.getNextFoldLine(i,s),o=s?s.start.row:Infinity);if(i>r)break;this.$useLineGroups()&&t.push("<div class='ace_line_group' style='height:",e.lineHeight*this.session.getRowLength(i),"px'>"),this.$renderLine(t,i,!1,i==o?s:!1),this.$useLineGroups()&&t.push("</div>"),i++}this.element.innerHTML=t.join("")},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(e,t,n,r){var i=this,o=/\t|&|<|( +)|([\x00-\x1f\x80-\xa0\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g,u=function(e,n,r,o,u){if(n)return i.showInvisibles?"<span class='ace_invisible ace_invisible_space'>"+s.stringRepeat(i.SPACE_CHAR,e.length)+"</span>":s.stringRepeat("\u00a0",e.length);if(e=="&")return"&#38;";if(e=="<")return"&#60;";if(e=="	"){var a=i.session.getScreenTabSize(t+o);return t+=a-1,i.$tabStrings[a]}if(e=="\u3000"){var f=i.showInvisibles?"ace_cjk ace_invisible ace_invisible_space":"ace_cjk",l=i.showInvisibles?i.SPACE_CHAR:"";return t+=1,"<span class='"+f+"' style='width:"+i.config.characterWidth*2+"px'>"+l+"</span>"}return r?"<span class='ace_invisible ace_invisible_space ace_invalid'>"+i.SPACE_CHAR+"</span>":(t+=1,"<span class='ace_cjk' style='width:"+i.config.characterWidth*2+"px'>"+e+"</span>")},a=r.replace(o,u);if(!this.$textToken[n.type]){var f="ace_"+n.type.replace(/\./g," ace_"),l="";n.type=="fold"&&(l=" style='width:"+n.value.length*this.config.characterWidth+"px;' "),e.push("<span class='",f,"'",l,">",a,"</span>")}else e.push(a);return t+r.length},this.renderIndentGuide=function(e,t,n){var r=t.search(this.$indentGuideRe);return r<=0||r>=n?t:t[0]==" "?(r-=r%this.tabSize,e.push(s.stringRepeat(this.$tabStrings[" "],r/this.tabSize)),t.substr(r)):t[0]=="	"?(e.push(s.stringRepeat(this.$tabStrings["	"],r)),t.substr(r)):t},this.$renderWrappedLine=function(e,t,n,r){var i=0,s=0,o=n[0],u=0;for(var a=0;a<t.length;a++){var f=t[a],l=f.value;if(a==0&&this.displayIndentGuides){i=l.length,l=this.renderIndentGuide(e,l,o);if(!l)continue;i-=l.length}if(i+l.length<o)u=this.$renderToken(e,u,f,l),i+=l.length;else{while(i+l.length>=o)u=this.$renderToken(e,u,f,l.substring(0,o-i)),l=l.substring(o-i),i=o,r||e.push("</div>","<div class='ace_line' style='height:",this.config.lineHeight,"px'>"),s++,u=0,o=n[s]||Number.MAX_VALUE;l.length!=0&&(i+=l.length,u=this.$renderToken(e,u,f,l))}}},this.$renderSimpleLine=function(e,t){var n=0,r=t[0],i=r.value;this.displayIndentGuides&&(i=this.renderIndentGuide(e,i)),i&&(n=this.$renderToken(e,n,r,i));for(var s=1;s<t.length;s++)r=t[s],i=r.value,n=this.$renderToken(e,n,r,i)},this.$renderLine=function(e,t,n,r){!r&&r!=0&&(r=this.session.getFoldLine(t));if(r)var i=this.$getFoldLineTokens(t,r);else var i=this.session.getTokens(t);n||e.push("<div class='ace_line' style='height:",this.config.lineHeight*(this.$useLineGroups()?1:this.session.getRowLength(t)),"px'>");if(i.length){var s=this.session.getRowSplitData(t);s&&s.length?this.$renderWrappedLine(e,i,s,n):this.$renderSimpleLine(e,i)}this.showInvisibles&&(r&&(t=r.end.row),e.push("<span class='ace_invisible ace_invisible_eol'>",t==this.session.getLength()-1?this.EOF_CHAR:this.EOL_CHAR,"</span>")),n||e.push("</div>")},this.$getFoldLineTokens=function(e,t){function i(e,t,n){var i=0,s=0;while(s+e[i].value.length<t){s+=e[i].value.length,i++;if(i==e.length)return}if(s!=t){var o=e[i].value.substring(t-s);o.length>n-t&&(o=o.substring(0,n-t)),r.push({type:e[i].type,value:o}),s=t+o.length,i+=1}while(s<n&&i<e.length){var o=e[i].value;o.length+s>n?r.push({type:e[i].type,value:o.substring(0,n-s)}):r.push(e[i]),s+=o.length,i+=1}}var n=this.session,r=[],s=n.getTokens(e);return t.walk(function(e,t,o,u,a){e!=null?r.push({type:"fold",value:e}):(a&&(s=n.getTokens(t)),s.length&&i(s,u,o))},t.end.row,this.session.getLine(t.end.row).length),r},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(a.prototype),t.Text=a}),ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../lib/dom"),i,s=function(e){this.element=r.createElement("div"),this.element.className="ace_layer ace_cursor-layer",e.appendChild(this.element),i===undefined&&(i="opacity"in this.element),this.isVisible=!1,this.isBlinking=!0,this.blinkInterval=1e3,this.smoothBlinking=!1,this.cursors=[],this.cursor=this.addCursor(),r.addCssClass(this.element,"ace_hidden-cursors"),this.$updateCursors=this.$updateVisibility.bind(this)};(function(){this.$updateVisibility=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.visibility=e?"":"hidden"},this.$updateOpacity=function(e){var t=this.cursors;for(var n=t.length;n--;)t[n].style.opacity=e?"":"0"},this.$padding=0,this.setPadding=function(e){this.$padding=e},this.setSession=function(e){this.session=e},this.setBlinking=function(e){e!=this.isBlinking&&(this.isBlinking=e,this.restartTimer())},this.setBlinkInterval=function(e){e!=this.blinkInterval&&(this.blinkInterval=e,this.restartTimer())},this.setSmoothBlinking=function(e){e!=this.smoothBlinking&&!i&&(this.smoothBlinking=e,r.setCssClass(this.element,"ace_smooth-blinking",e),this.$updateCursors(!0),this.$updateCursors=(e?this.$updateOpacity:this.$updateVisibility).bind(this),this.restartTimer())},this.addCursor=function(){var e=r.createElement("div");return e.className="ace_cursor",this.element.appendChild(e),this.cursors.push(e),e},this.removeCursor=function(){if(this.cursors.length>1){var e=this.cursors.pop();return e.parentNode.removeChild(e),e}},this.hideCursor=function(){this.isVisible=!1,r.addCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.showCursor=function(){this.isVisible=!0,r.removeCssClass(this.element,"ace_hidden-cursors"),this.restartTimer()},this.restartTimer=function(){var e=this.$updateCursors;clearInterval(this.intervalId),clearTimeout(this.timeoutId),this.smoothBlinking&&r.removeCssClass(this.element,"ace_smooth-blinking"),e(!0);if(!this.isBlinking||!this.blinkInterval||!this.isVisible)return;this.smoothBlinking&&setTimeout(function(){r.addCssClass(this.element,"ace_smooth-blinking")}.bind(this));var t=function(){this.timeoutId=setTimeout(function(){e(!1)},.6*this.blinkInterval)}.bind(this);this.intervalId=setInterval(function(){e(!0),t()},this.blinkInterval),t()},this.getPixelPosition=function(e,t){if(!this.config||!this.session)return{left:0,top:0};e||(e=this.session.selection.getCursor());var n=this.session.documentToScreenPosition(e),r=this.$padding+n.column*this.config.characterWidth,i=(n.row-(t?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:r,top:i}},this.update=function(e){this.config=e;var t=this.session.$selectionMarkers,n=0,r=0;if(t===undefined||t.length===0)t=[{cursor:null}];for(var n=0,i=t.length;n<i;n++){var s=this.getPixelPosition(t[n].cursor,!0);if((s.top>e.height+e.offset||s.top<0)&&n>1)continue;var o=(this.cursors[r++]||this.addCursor()).style;o.left=s.left+"px",o.top=s.top+"px",o.width=e.characterWidth+"px",o.height=e.lineHeight+"px"}while(this.cursors.length>r)this.removeCursor();var u=this.session.getOverwrite();this.$setOverwrite(u),this.$pixelPos=s,this.restartTimer()},this.$setOverwrite=function(e){e!=this.overwrite&&(this.overwrite=e,e?r.addCssClass(this.element,"ace_overwrite-cursors"):r.removeCssClass(this.element,"ace_overwrite-cursors"))},this.destroy=function(){clearInterval(this.intervalId),clearTimeout(this.timeoutId)}}).call(s.prototype),t.Cursor=s}),ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./lib/event"),o=e("./lib/event_emitter").EventEmitter,u=function(e){this.element=i.createElement("div"),this.element.className="ace_scrollbar ace_scrollbar"+this.classSuffix,this.inner=i.createElement("div"),this.inner.className="ace_scrollbar-inner",this.element.appendChild(this.inner),e.appendChild(this.element),this.setVisible(!1),this.skipEvent=!1,s.addListener(this.element,"scroll",this.onScroll.bind(this)),s.addListener(this.element,"mousedown",s.preventDefault)};(function(){r.implement(this,o),this.setVisible=function(e){this.element.style.display=e?"":"none",this.isVisible=e}}).call(u.prototype);var a=function(e,t){u.call(this,e),this.scrollTop=0,t.$scrollbarWidth=this.width=i.scrollbarWidth(e.ownerDocument),this.inner.style.width=this.element.style.width=(this.width||15)+5+"px"};r.inherits(a,u),function(){this.classSuffix="-v",this.onScroll=function(){this.skipEvent||(this.scrollTop=this.element.scrollTop,this._emit("scroll",{data:this.scrollTop})),this.skipEvent=!1},this.getWidth=function(){return this.isVisible?this.width:0},this.setHeight=function(e){this.element.style.height=e+"px"},this.setInnerHeight=function(e){this.inner.style.height=e+"px"},this.setScrollHeight=function(e){this.inner.style.height=e+"px"},this.setScrollTop=function(e){this.scrollTop!=e&&(this.skipEvent=!0,this.scrollTop=this.element.scrollTop=e)}}.call(a.prototype);var f=function(e,t){u.call(this,e),this.scrollLeft=0,this.height=t.$scrollbarWidth,this.inner.style.height=this.element.style.height=(this.height||15)+5+"px"};r.inherits(f,u),function(){this.classSuffix="-h",this.onScroll=function(){this.skipEvent||(this.scrollLeft=this.element.scrollLeft,this._emit("scroll",{data:this.scrollLeft})),this.skipEvent=!1},this.getHeight=function(){return this.isVisible?this.height:0},this.setWidth=function(e){this.element.style.width=e+"px"},this.setInnerWidth=function(e){this.inner.style.width=e+"px"},this.setScrollWidth=function(e){this.inner.style.width=e+"px"},this.setScrollLeft=function(e){this.scrollLeft!=e&&(this.skipEvent=!0,this.scrollLeft=this.element.scrollLeft=e)}}.call(f.prototype),t.ScrollBar=a,t.ScrollBarV=a,t.ScrollBarH=f,t.VScrollBar=a,t.HScrollBar=f}),ace.define("ace/renderloop",["require","exports","module","ace/lib/event"],function(e,t,n){"use strict";var r=e("./lib/event"),i=function(e,t){this.onRender=e,this.pending=!1,this.changes=0,this.window=t||window};(function(){this.schedule=function(e){this.changes=this.changes|e;if(!this.pending&&this.changes){this.pending=!0;var t=this;r.nextFrame(function(){t.pending=!1;var e;while(e=t.changes)t.changes=0,t.onRender(e)},this.window)}}}).call(i.prototype),t.RenderLoop=i}),ace.define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/dom"),s=e("../lib/lang"),o=e("../lib/useragent"),u=e("../lib/event_emitter").EventEmitter,a=0,f=t.FontMetrics=function(e,t){this.el=i.createElement("div"),this.$setMeasureNodeStyles(this.el.style,!0),this.$main=i.createElement("div"),this.$setMeasureNodeStyles(this.$main.style),this.$measureNode=i.createElement("div"),this.$setMeasureNodeStyles(this.$measureNode.style),this.el.appendChild(this.$main),this.el.appendChild(this.$measureNode),e.appendChild(this.el),a||this.$testFractionalRect(),this.$measureNode.innerHTML=s.stringRepeat("X",a),this.$characterSize={width:0,height:0},this.checkForSizeChanges()};(function(){r.implement(this,u),this.$characterSize={width:0,height:0},this.$testFractionalRect=function(){var e=i.createElement("div");this.$setMeasureNodeStyles(e.style),e.style.width="0.2px",document.documentElement.appendChild(e);var t=e.getBoundingClientRect().width;t>0&&t<1?a=1:a=100,e.parentNode.removeChild(e)},this.$setMeasureNodeStyles=function(e,t){e.width=e.height="auto",e.left=e.top="-100px",e.visibility="hidden",e.position="fixed",e.whiteSpace="pre",o.isIE<8?e["font-family"]="inherit":e.font="inherit",e.overflow=t?"hidden":"visible"},this.checkForSizeChanges=function(){var e=this.$measureSizes();if(e&&(this.$characterSize.width!==e.width||this.$characterSize.height!==e.height)){this.$measureNode.style.fontWeight="bold";var t=this.$measureSizes();this.$measureNode.style.fontWeight="",this.$characterSize=e,this.charSizes=Object.create(null),this.allowBoldFonts=t&&t.width===e.width&&t.height===e.height,this._emit("changeCharacterSize",{data:e})}},this.$pollSizeChanges=function(){if(this.$pollSizeChangesTimer)return this.$pollSizeChangesTimer;var e=this;return this.$pollSizeChangesTimer=setInterval(function(){e.checkForSizeChanges()},500)},this.setPolling=function(e){e?this.$pollSizeChanges():this.$pollSizeChangesTimer&&this.$pollSizeChangesTimer},this.$measureSizes=function(){if(a===1)var e=this.$measureNode.getBoundingClientRect(),t={height:e.height,width:e.width};else var t={height:this.$measureNode.clientHeight,width:this.$measureNode.clientWidth/a};return t.width===0||t.height===0?null:t},this.$measureCharWidth=function(e){this.$main.innerHTML=s.stringRepeat(e,a);var t=this.$main.getBoundingClientRect();return t.width/a},this.getCharacterWidth=function(e){var t=this.charSizes[e];return t===undefined&&(this.charSizes[e]=this.$measureCharWidth(e)/this.$characterSize.width),t},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.el&&this.el.parentNode&&this.el.parentNode.removeChild(this.el)}}).call(f.prototype)}),ace.define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/lib/useragent","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./config"),o=e("./lib/useragent"),u=e("./layer/gutter").Gutter,a=e("./layer/marker").Marker,f=e("./layer/text").Text,l=e("./layer/cursor").Cursor,c=e("./scrollbar").HScrollBar,h=e("./scrollbar").VScrollBar,p=e("./renderloop").RenderLoop,d=e("./layer/font_metrics").FontMetrics,v=e("./lib/event_emitter").EventEmitter,m='.ace_editor {position: relative;overflow: hidden;font-family: \'Monaco\', \'Menlo\', \'Ubuntu Mono\', \'Consolas\', \'source-code-pro\', monospace;font-size: 12px;line-height: normal;direction: ltr;}.ace_scroller {position: absolute;overflow: hidden;top: 0;bottom: 0;background-color: inherit;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;}.ace_content {position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;cursor: text;min-width: 100%;}.ace_dragging, .ace_dragging * {cursor: move !important;}.ace_dragging .ace_scroller:before{position: absolute;top: 0;left: 0;right: 0;bottom: 0;content: \'\';background: rgba(250, 250, 250, 0.01);z-index: 1000;}.ace_dragging.ace_dark .ace_scroller:before{background: rgba(0, 0, 0, 0.01);}.ace_selecting, .ace_selecting * {cursor: text !important;}.ace_gutter {position: absolute;overflow : hidden;width: auto;top: 0;bottom: 0;left: 0;cursor: default;z-index: 4;-ms-user-select: none;-moz-user-select: none;-webkit-user-select: none;user-select: none;}.ace_gutter-active-line {position: absolute;left: 0;right: 0;}.ace_scroller.ace_scroll-left {box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;}.ace_gutter-cell {padding-left: 19px;padding-right: 6px;background-repeat: no-repeat;}.ace_gutter-cell.ace_error {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: 2px center;}.ace_gutter-cell.ace_warning {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==");background-position: 2px center;}.ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=");background-position: 2px center;}.ace_dark .ace_gutter-cell.ace_info {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC");}.ace_scrollbar {position: absolute;right: 0;bottom: 0;z-index: 6;}.ace_scrollbar-inner {position: absolute;cursor: text;left: 0;top: 0;}.ace_scrollbar-v{overflow-x: hidden;overflow-y: scroll;top: 0;}.ace_scrollbar-h {overflow-x: scroll;overflow-y: hidden;left: 0;}.ace_print-margin {position: absolute;height: 100%;}.ace_text-input {position: absolute;z-index: 0;width: 0.5em;height: 1em;opacity: 0;background: transparent;-moz-appearance: none;appearance: none;border: none;resize: none;outline: none;overflow: hidden;font: inherit;padding: 0 1px;margin: 0 -1px;text-indent: -1em;-ms-user-select: text;-moz-user-select: text;-webkit-user-select: text;user-select: text;}.ace_text-input.ace_composition {background: #f8f8f8;color: #111;z-index: 1000;opacity: 1;text-indent: 0;}.ace_layer {z-index: 1;position: absolute;overflow: hidden;white-space: pre;height: 100%;width: 100%;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;pointer-events: none;}.ace_gutter-layer {position: relative;width: auto;text-align: right;pointer-events: auto;}.ace_text-layer {font: inherit !important;}.ace_cjk {display: inline-block;text-align: center;}.ace_cursor-layer {z-index: 4;}.ace_cursor {z-index: 4;position: absolute;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;border-left: 2px solid}.ace_slim-cursors .ace_cursor {border-left-width: 1px;}.ace_overwrite-cursors .ace_cursor {border-left-width: 0px;border-bottom: 1px solid;}.ace_hidden-cursors .ace_cursor {opacity: 0.2;}.ace_smooth-blinking .ace_cursor {-moz-transition: opacity 0.18s;-webkit-transition: opacity 0.18s;-o-transition: opacity 0.18s;-ms-transition: opacity 0.18s;transition: opacity 0.18s;}.ace_editor.ace_multiselect .ace_cursor {border-left-width: 1px;}.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {position: absolute;z-index: 3;}.ace_marker-layer .ace_selection {position: absolute;z-index: 5;}.ace_marker-layer .ace_bracket {position: absolute;z-index: 6;}.ace_marker-layer .ace_active-line {position: absolute;z-index: 2;}.ace_marker-layer .ace_selected-word {position: absolute;z-index: 4;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;}.ace_line .ace_fold {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;display: inline-block;height: 11px;margin-top: -2px;vertical-align: middle;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=");background-repeat: no-repeat, repeat-x;background-position: center center, top left;color: transparent;border: 1px solid black;-moz-border-radius: 2px;-webkit-border-radius: 2px;border-radius: 2px;cursor: pointer;pointer-events: auto;}.ace_dark .ace_fold {}.ace_fold:hover{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII="),url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC");}.ace_tooltip {background-color: #FFF;background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));border: 1px solid gray;border-radius: 1px;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);color: black;display: block;max-width: 100%;padding: 3px 4px;position: fixed;z-index: 999999;-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;cursor: default;white-space: pre;word-wrap: break-word;line-height: normal;font-style: normal;font-weight: normal;letter-spacing: normal;pointer-events: none;}.ace_folding-enabled > .ace_gutter-cell {padding-right: 13px;}.ace_fold-widget {-moz-box-sizing: border-box;-webkit-box-sizing: border-box;box-sizing: border-box;margin: 0 -12px 0 1px;display: none;width: 11px;vertical-align: top;background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==");background-repeat: no-repeat;background-position: center;border-radius: 3px;border: 1px solid transparent;cursor: pointer;}.ace_folding-enabled .ace_fold-widget {display: inline-block;   }.ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==");}.ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==");}.ace_fold-widget:hover {border: 1px solid rgba(0, 0, 0, 0.3);background-color: rgba(255, 255, 255, 0.2);-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);}.ace_fold-widget:active {border: 1px solid rgba(0, 0, 0, 0.4);background-color: rgba(0, 0, 0, 0.05);-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);}.ace_dark .ace_fold-widget {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC");}.ace_dark .ace_fold-widget.ace_end {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget.ace_closed {background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==");}.ace_dark .ace_fold-widget:hover {box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);background-color: rgba(255, 255, 255, 0.1);}.ace_dark .ace_fold-widget:active {-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);}.ace_fold-widget.ace_invalid {background-color: #FFB4B4;border-color: #DE5555;}.ace_fade-fold-widgets .ace_fold-widget {-moz-transition: opacity 0.4s ease 0.05s;-webkit-transition: opacity 0.4s ease 0.05s;-o-transition: opacity 0.4s ease 0.05s;-ms-transition: opacity 0.4s ease 0.05s;transition: opacity 0.4s ease 0.05s;opacity: 0;}.ace_fade-fold-widgets:hover .ace_fold-widget {-moz-transition: opacity 0.05s ease 0.05s;-webkit-transition: opacity 0.05s ease 0.05s;-o-transition: opacity 0.05s ease 0.05s;-ms-transition: opacity 0.05s ease 0.05s;transition: opacity 0.05s ease 0.05s;opacity:1;}.ace_underline {text-decoration: underline;}.ace_bold {font-weight: bold;}.ace_nobold .ace_bold {font-weight: normal;}.ace_italic {font-style: italic;}.ace_error-marker {background-color: rgba(255, 0, 0,0.2);position: absolute;z-index: 9;}.ace_highlight-marker {background-color: rgba(255, 255, 0,0.2);position: absolute;z-index: 8;}';i.importCssString(m,"ace_editor");var g=function(e,t){var n=this;this.container=e||i.createElement("div"),this.$keepTextAreaAtCursor=!o.isOldIE,i.addCssClass(this.container,"ace_editor"),this.setTheme(t),this.$gutter=i.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.scroller=i.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=i.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new u(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onGutterResize.bind(this)),this.$markerBack=new a(this.content);var r=this.$textLayer=new f(this.content);this.canvas=r.element,this.$markerFront=new a(this.content),this.$cursorLayer=new l(this.content),this.$horizScroll=!1,this.$vScroll=!1,this.scrollBar=this.scrollBarV=new h(this.container,this),this.scrollBarH=new c(this.container,this),this.scrollBarV.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollTop(e.data-n.scrollMargin.top)}),this.scrollBarH.addEventListener("scroll",function(e){n.$scrollAnimation||n.session.setScrollLeft(e.data-n.scrollMargin.left)}),this.scrollTop=0,this.scrollLeft=0,this.cursorPos={row:0,column:0},this.$fontMetrics=new d(this.container,500),this.$textLayer.$setFontMetrics(this.$fontMetrics),this.$textLayer.addEventListener("changeCharacterSize",function(e){n.updateCharacterSize(),n.onResize(!0,n.gutterWidth,n.$size.width,n.$size.height),n._signal("changeCharacterSize",e)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0,$dirty:!0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:0,characterWidth:0,minHeight:1,maxHeight:1,offset:0,height:1,gutterOffset:1},this.scrollMargin={left:0,right:0,top:0,bottom:0,v:0,h:0},this.$loop=new p(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.updateCharacterSize(),this.setPadding(4),s.resetOptions(this),s._emit("renderer",this)};(function(){this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,r.implement(this,v),this.updateCharacterSize=function(){this.$textLayer.allowBoldFonts!=this.$allowBoldFonts&&(this.$allowBoldFonts=this.$textLayer.allowBoldFonts,this.setStyle("ace_nobold",!this.$allowBoldFonts)),this.layerConfig.characterWidth=this.characterWidth=this.$textLayer.getCharacterWidth(),this.layerConfig.lineHeight=this.lineHeight=this.$textLayer.getLineHeight(),this.$updatePrintMargin()},this.setSession=function(e){this.session&&this.session.doc.off("changeNewLineMode",this.onChangeNewLineMode),this.session=e;if(!e)return;this.scrollMargin.top&&e.getScrollTop()<=0&&e.setScrollTop(-this.scrollMargin.top),this.$cursorLayer.setSession(e),this.$markerBack.setSession(e),this.$markerFront.setSession(e),this.$gutterLayer.setSession(e),this.$textLayer.setSession(e),this.$loop.schedule(this.CHANGE_FULL),this.session.$setFontMetrics(this.$fontMetrics),this.onChangeNewLineMode=this.onChangeNewLineMode.bind(this),this.onChangeNewLineMode(),this.session.doc.on("changeNewLineMode",this.onChangeNewLineMode)},this.updateLines=function(e,t){t===undefined&&(t=Infinity),this.$changedLines?(this.$changedLines.firstRow>e&&(this.$changedLines.firstRow=e),this.$changedLines.lastRow<t&&(this.$changedLines.lastRow=t)):this.$changedLines={firstRow:e,lastRow:t};if(this.$changedLines.firstRow>this.layerConfig.lastRow||this.$changedLines.lastRow<this.layerConfig.firstRow)return;this.$loop.schedule(this.CHANGE_LINES)},this.onChangeNewLineMode=function(){this.$loop.schedule(this.CHANGE_TEXT),this.$textLayer.$updateEolChar()},this.onChangeTabSize=function(){this.$loop.schedule(this.CHANGE_TEXT|this.CHANGE_MARKER),this.$textLayer.onChangeTabSize()},this.updateText=function(){this.$loop.schedule(this.CHANGE_TEXT)},this.updateFull=function(e){e?this.$renderChanges(this.CHANGE_FULL,!0):this.$loop.schedule(this.CHANGE_FULL)},this.updateFontSize=function(){this.$textLayer.checkForSizeChanges()},this.$changes=0,this.$updateSizeAsync=function(){this.$loop.pending?this.$size.$dirty=!0:this.onResize()},this.onResize=function(e,t,n,r){if(this.resizing>2)return;this.resizing>0?this.resizing++:this.resizing=e?1:0;var i=this.container;r||(r=i.clientHeight||i.scrollHeight),n||(n=i.clientWidth||i.scrollWidth);var s=this.$updateCachedSize(e,t,n,r);if(!this.$size.scrollerHeight||!n&&!r)return this.resizing=0;e&&(this.$gutterLayer.$padding=null),e?this.$renderChanges(s|this.$changes,!0):this.$loop.schedule(s|this.$changes),this.resizing&&(this.resizing=0)},this.$updateCachedSize=function(e,t,n,r){r-=this.$extraHeight||0;var i=0,s=this.$size,o={width:s.width,height:s.height,scrollerHeight:s.scrollerHeight,scrollerWidth:s.scrollerWidth};r&&(e||s.height!=r)&&(s.height=r,i|=this.CHANGE_SIZE,s.scrollerHeight=s.height,this.$horizScroll&&(s.scrollerHeight-=this.scrollBarH.getHeight()),this.scrollBarV.element.style.bottom=this.scrollBarH.getHeight()+"px",i|=this.CHANGE_SCROLL);if(n&&(e||s.width!=n)){i|=this.CHANGE_SIZE,s.width=n,t==null&&(t=this.$showGutter?this.$gutter.offsetWidth:0),this.gutterWidth=t,this.scrollBarH.element.style.left=this.scroller.style.left=t+"px",s.scrollerWidth=Math.max(0,n-t-this.scrollBarV.getWidth()),this.scrollBarH.element.style.right=this.scroller.style.right=this.scrollBarV.getWidth()+"px",this.scroller.style.bottom=this.scrollBarH.getHeight()+"px";if(this.session&&this.session.getUseWrapMode()&&this.adjustWrapLimit()||e)i|=this.CHANGE_FULL}return s.$dirty=!n||!r,i&&this._signal("resize",o),i},this.onGutterResize=function(){var e=this.$showGutter?this.$gutter.offsetWidth:0;e!=this.gutterWidth&&(this.$changes|=this.$updateCachedSize(!0,e,this.$size.width,this.$size.height)),this.session.getUseWrapMode()&&this.adjustWrapLimit()?this.$loop.schedule(this.CHANGE_FULL):this.$size.$dirty?this.$loop.schedule(this.CHANGE_FULL):(this.$computeLayerConfig(),this.$loop.schedule(this.CHANGE_MARKER))},this.adjustWrapLimit=function(){var e=this.$size.scrollerWidth-this.$padding*2,t=Math.floor(e/this.characterWidth);return this.session.adjustWrapLimit(t,this.$showPrintMargin&&this.$printMarginColumn)},this.setAnimatedScroll=function(e){this.setOption("animatedScroll",e)},this.getAnimatedScroll=function(){return this.$animatedScroll},this.setShowInvisibles=function(e){this.setOption("showInvisibles",e)},this.getShowInvisibles=function(){return this.getOption("showInvisibles")},this.getDisplayIndentGuides=function(){return this.getOption("displayIndentGuides")},this.setDisplayIndentGuides=function(e){this.setOption("displayIndentGuides",e)},this.setShowPrintMargin=function(e){this.setOption("showPrintMargin",e)},this.getShowPrintMargin=function(){return this.getOption("showPrintMargin")},this.setPrintMarginColumn=function(e){this.setOption("printMarginColumn",e)},this.getPrintMarginColumn=function(){return this.getOption("printMarginColumn")},this.getShowGutter=function(){return this.getOption("showGutter")},this.setShowGutter=function(e){return this.setOption("showGutter",e)},this.getFadeFoldWidgets=function(){return this.getOption("fadeFoldWidgets")},this.setFadeFoldWidgets=function(e){this.setOption("fadeFoldWidgets",e)},this.setHighlightGutterLine=function(e){this.setOption("highlightGutterLine",e)},this.getHighlightGutterLine=function(){return this.getOption("highlightGutterLine")},this.$updateGutterLineHighlight=function(){var e=this.$cursorLayer.$pixelPos,t=this.layerConfig.lineHeight;if(this.session.getUseWrapMode()){var n=this.session.selection.getCursor();n.column=0,e=this.$cursorLayer.getPixelPosition(n,!0),t*=this.session.getRowLength(n.row)}this.$gutterLineHighlight.style.top=e.top-this.layerConfig.offset+"px",this.$gutterLineHighlight.style.height=t+"px"},this.$updatePrintMargin=function(){if(!this.$showPrintMargin&&!this.$printMarginEl)return;if(!this.$printMarginEl){var e=i.createElement("div");e.className="ace_layer ace_print-margin-layer",this.$printMarginEl=i.createElement("div"),this.$printMarginEl.className="ace_print-margin",e.appendChild(this.$printMarginEl),this.content.insertBefore(e,this.content.firstChild)}var t=this.$printMarginEl.style;t.left=this.characterWidth*this.$printMarginColumn+this.$padding+"px",t.visibility=this.$showPrintMargin?"visible":"hidden",this.session&&this.session.$wrap==-1&&this.adjustWrapLimit()},this.getContainerElement=function(){return this.container},this.getMouseEventTarget=function(){return this.content},this.getTextAreaContainer=function(){return this.container},this.$moveTextAreaToCursor=function(){if(!this.$keepTextAreaAtCursor)return;var e=this.layerConfig,t=this.$cursorLayer.$pixelPos.top,n=this.$cursorLayer.$pixelPos.left;t-=e.offset;var r=this.lineHeight;if(t<0||t>e.height-r)return;var i=this.characterWidth;if(this.$composition){var s=this.textarea.value.replace(/^\x01+/,"");i*=this.session.$getStringScreenWidth(s)[0]+2,r+=2,t-=1}n-=this.scrollLeft,n>this.$size.scrollerWidth-i&&(n=this.$size.scrollerWidth-i),n-=this.scrollBar.width,this.textarea.style.height=r+"px",this.textarea.style.width=i+"px",this.textarea.style.right=Math.max(0,this.$size.scrollerWidth-n-i)+"px",this.textarea.style.bottom=Math.max(0,this.$size.height-t-r)+"px"},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var e=Math.floor((this.layerConfig.height+this.layerConfig.offset)/this.layerConfig.lineHeight);return this.layerConfig.firstRow-1+e},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(e){this.$padding=e,this.$textLayer.setPadding(e),this.$cursorLayer.setPadding(e),this.$markerFront.setPadding(e),this.$markerBack.setPadding(e),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.setScrollMargin=function(e,t,n,r){var i=this.scrollMargin;i.top=e|0,i.bottom=t|0,i.right=r|0,i.left=n|0,i.v=i.top+i.bottom,i.h=i.left+i.right,i.top&&this.scrollTop<=0&&this.session&&this.session.setScrollTop(-i.top),this.updateFull()},this.getHScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setHScrollBarAlwaysVisible=function(e){this.setOption("hScrollBarAlwaysVisible",e)},this.getVScrollBarAlwaysVisible=function(){return this.$hScrollBarAlwaysVisible},this.setVScrollBarAlwaysVisible=function(e){this.setOption("vScrollBarAlwaysVisible",e)},this.$updateScrollBarV=function(){var e=this.layerConfig.maxHeight,t=this.$size.scrollerHeight;!this.$maxLines&&this.$scrollPastEnd&&(e-=(t-this.lineHeight)*this.$scrollPastEnd,this.scrollTop>e-t&&(e=this.scrollTop+t,this.scrollBarV.scrollTop=null)),this.scrollBarV.setScrollHeight(e+this.scrollMargin.v),this.scrollBarV.setScrollTop(this.scrollTop+this.scrollMargin.top)},this.$updateScrollBarH=function(){this.scrollBarH.setScrollWidth(this.layerConfig.width+2*this.$padding+this.scrollMargin.h),this.scrollBarH.setScrollLeft(this.scrollLeft+this.scrollMargin.left)},this.$frozen=!1,this.freeze=function(){this.$frozen=!0},this.unfreeze=function(){this.$frozen=!1},this.$renderChanges=function(e,t){this.$changes&&(e|=this.$changes,this.$changes=0);if(!this.session||!this.container.offsetWidth||this.$frozen||!e&&!t){this.$changes|=e;return}if(this.$size.$dirty)return this.$changes|=e,this.onResize(!0);this.lineHeight||this.$textLayer.checkForSizeChanges(),this._signal("beforeRender");var n=this.layerConfig;if(e&this.CHANGE_FULL||e&this.CHANGE_SIZE||e&this.CHANGE_TEXT||e&this.CHANGE_LINES||e&this.CHANGE_SCROLL||e&this.CHANGE_H_SCROLL)e|=this.$computeLayerConfig(),n=this.layerConfig,this.$updateScrollBarV(),e&this.CHANGE_H_SCROLL&&this.$updateScrollBarH(),this.$gutterLayer.element.style.marginTop=-n.offset+"px",this.content.style.marginTop=-n.offset+"px",this.content.style.width=n.width+2*this.$padding+"px",this.content.style.height=n.minHeight+"px";e&this.CHANGE_H_SCROLL&&(this.content.style.marginLeft=-this.scrollLeft+"px",this.scroller.className=this.scrollLeft<=0?"ace_scroller":"ace_scroller ace_scroll-left");if(e&this.CHANGE_FULL){this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this._signal("afterRender");return}if(e&this.CHANGE_SCROLL){e&this.CHANGE_TEXT||e&this.CHANGE_LINES?this.$textLayer.update(n):this.$textLayer.scrollLines(n),this.$showGutter&&this.$gutterLayer.update(n),this.$markerBack.update(n),this.$markerFront.update(n),this.$cursorLayer.update(n),this.$highlightGutterLine&&this.$updateGutterLineHighlight(),this.$moveTextAreaToCursor(),this._signal("afterRender");return}e&this.CHANGE_TEXT?(this.$textLayer.update(n),this.$showGutter&&this.$gutterLayer.update(n)):e&this.CHANGE_LINES?(this.$updateLines()||e&this.CHANGE_GUTTER&&this.$showGutter)&&this.$gutterLayer.update(n):(e&this.CHANGE_TEXT||e&this.CHANGE_GUTTER)&&this.$showGutter&&this.$gutterLayer.update(n),e&this.CHANGE_CURSOR&&(this.$cursorLayer.update(n),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight()),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(n),e&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(n),this._signal("afterRender")},this.$autosize=function(){var e=this.session.getScreenLength()*this.lineHeight,t=this.$maxLines*this.lineHeight,n=Math.max((this.$minLines||1)*this.lineHeight,Math.min(t,e))+this.scrollMargin.v+(this.$extraHeight||0),r=e>t;if(n!=this.desiredHeight||this.$size.height!=this.desiredHeight||r!=this.$vScroll){r!=this.$vScroll&&(this.$vScroll=r,this.scrollBarV.setVisible(r));var i=this.container.clientWidth;this.container.style.height=n+"px",this.$updateCachedSize(!0,this.$gutterWidth,i,n),this.desiredHeight=n}},this.$computeLayerConfig=function(){this.$maxLines&&this.lineHeight>1&&this.$autosize();var e=this.session,t=this.$size,n=t.height<=2*this.lineHeight,r=this.session.getScreenLength(),i=r*this.lineHeight,s=this.scrollTop%this.lineHeight,o=t.scrollerHeight+this.lineHeight,u=this.$getLongestLine(),a=!n&&(this.$hScrollBarAlwaysVisible||t.scrollerWidth-u-2*this.$padding<0),f=this.$horizScroll!==a;f&&(this.$horizScroll=a,this.scrollBarH.setVisible(a)),!this.$maxLines&&this.$scrollPastEnd&&(i+=(t.scrollerHeight-this.lineHeight)*this.$scrollPastEnd);var l=!n&&(this.$vScrollBarAlwaysVisible||t.scrollerHeight-i<0),c=this.$vScroll!==l;c&&(this.$vScroll=l,this.scrollBarV.setVisible(l)),this.session.setScrollTop(Math.max(-this.scrollMargin.top,Math.min(this.scrollTop,i-t.scrollerHeight+this.scrollMargin.bottom))),this.session.setScrollLeft(Math.max(-this.scrollMargin.left,Math.min(this.scrollLeft,u+2*this.$padding-t.scrollerWidth+this.scrollMargin.right)));var h=Math.ceil(o/this.lineHeight)-1,p=Math.max(0,Math.round((this.scrollTop-s)/this.lineHeight)),d=p+h,v,m,g=this.lineHeight;p=e.screenToDocumentRow(p,0);var y=e.getFoldLine(p);y&&(p=y.start.row),v=e.documentToScreenRow(p,0),m=e.getRowLength(p)*g,d=Math.min(e.screenToDocumentRow(d,0),e.getLength()-1),o=t.scrollerHeight+e.getRowLength(d)*g+m,s=this.scrollTop-v*g;var b=0;this.layerConfig.width!=u&&(b=this.CHANGE_H_SCROLL);if(f||c)b=this.$updateCachedSize(!0,this.gutterWidth,t.width,t.height),this._signal("scrollbarVisibilityChanged"),c&&(u=this.$getLongestLine());return this.layerConfig={width:u,padding:this.$padding,firstRow:p,firstRowScreen:v,lastRow:d,lineHeight:g,characterWidth:this.characterWidth,minHeight:o,maxHeight:i,offset:s,gutterOffset:Math.max(0,Math.ceil((s+t.height-t.scrollerHeight)/g)),height:this.$size.scrollerHeight},b},this.$updateLines=function(){var e=this.$changedLines.firstRow,t=this.$changedLines.lastRow;this.$changedLines=null;var n=this.layerConfig;if(e>n.lastRow+1)return;if(t<n.firstRow)return;if(t===Infinity){this.$showGutter&&this.$gutterLayer.update(n),this.$textLayer.update(n);return}return this.$textLayer.updateLines(n,e,t),!0},this.$getLongestLine=function(){var e=this.session.getScreenWidth();return this.showInvisibles&&!this.session.$useWrapMode&&(e+=1),Math.max(this.$size.scrollerWidth-2*this.$padding,Math.round(e*this.characterWidth))},this.updateFrontMarkers=function(){this.$markerFront.setMarkers(this.session.getMarkers(!0)),this.$loop.schedule(this.CHANGE_MARKER_FRONT)},this.updateBackMarkers=function(){this.$markerBack.setMarkers(this.session.getMarkers()),this.$loop.schedule(this.CHANGE_MARKER_BACK)},this.addGutterDecoration=function(e,t){this.$gutterLayer.addGutterDecoration(e,t)},this.removeGutterDecoration=function(e,t){this.$gutterLayer.removeGutterDecoration(e,t)},this.updateBreakpoints=function(e){this.$loop.schedule(this.CHANGE_GUTTER)},this.setAnnotations=function(e){this.$gutterLayer.setAnnotations(e),this.$loop.schedule(this.CHANGE_GUTTER)},this.updateCursor=function(){this.$loop.schedule(this.CHANGE_CURSOR)},this.hideCursor=function(){this.$cursorLayer.hideCursor()},this.showCursor=function(){this.$cursorLayer.showCursor()},this.scrollSelectionIntoView=function(e,t,n){this.scrollCursorIntoView(e,n),this.scrollCursorIntoView(t,n)},this.scrollCursorIntoView=function(e,t,n){if(this.$size.scrollerHeight===0)return;var r=this.$cursorLayer.getPixelPosition(e),i=r.left,s=r.top,o=n&&n.top||0,u=n&&n.bottom||0,a=this.$scrollAnimation?this.session.getScrollTop():this.scrollTop;a+o>s?(t&&(s-=t*this.$size.scrollerHeight),s===0&&(s=-this.scrollMargin.top),this.session.setScrollTop(s)):a+this.$size.scrollerHeight-u<s+this.lineHeight&&(t&&(s+=t*this.$size.scrollerHeight),this.session.setScrollTop(s+this.lineHeight-this.$size.scrollerHeight));var f=this.scrollLeft;f>i?(i<this.$padding+2*this.layerConfig.characterWidth&&(i=-this.scrollMargin.left),this.session.setScrollLeft(i)):f+this.$size.scrollerWidth<i+this.characterWidth?this.session.setScrollLeft(Math.round(i+this.characterWidth-this.$size.scrollerWidth)):f<=this.$padding&&i-f<this.characterWidth&&this.session.setScrollLeft(0)},this.getScrollTop=function(){return this.session.getScrollTop()},this.getScrollLeft=function(){return this.session.getScrollLeft()},this.getScrollTopRow=function(){return this.scrollTop/this.lineHeight},this.getScrollBottomRow=function(){return Math.max(0,Math.floor((this.scrollTop+this.$size.scrollerHeight)/this.lineHeight)-1)},this.scrollToRow=function(e){this.session.setScrollTop(e*this.lineHeight)},this.alignCursor=function(e,t){typeof e=="number"&&(e={row:e,column:0});var n=this.$cursorLayer.getPixelPosition(e),r=this.$size.scrollerHeight-this.lineHeight,i=n.top-r*(t||0);return this.session.setScrollTop(i),i},this.STEPS=8,this.$calcSteps=function(e,t){var n=0,r=this.STEPS,i=[],s=function(e,t,n){return n*(Math.pow(e-1,3)+1)+t};for(n=0;n<r;++n)i.push(s(n/this.STEPS,e,t-e));return i},this.scrollToLine=function(e,t,n,r){var i=this.$cursorLayer.getPixelPosition({row:e,column:0}),s=i.top;t&&(s-=this.$size.scrollerHeight/2);var o=this.scrollTop;this.session.setScrollTop(s),n!==!1&&this.animateScrolling(o,r)},this.animateScrolling=function(e,t){var n=this.scrollTop;if(!this.$animatedScroll)return;var r=this;if(e==n)return;if(this.$scrollAnimation){var i=this.$scrollAnimation.steps;if(i.length){e=i[0];if(e==n)return}}var s=r.$calcSteps(e,n);this.$scrollAnimation={from:e,to:n,steps:s},clearInterval(this.$timer),r.session.setScrollTop(s.shift()),r.session.$scrollTop=n,this.$timer=setInterval(function(){s.length?(r.session.setScrollTop(s.shift()),r.session.$scrollTop=n):n!=null?(r.session.$scrollTop=-1,r.session.setScrollTop(n),n=null):(r.$timer=clearInterval(r.$timer),r.$scrollAnimation=null,t&&t())},10)},this.scrollToY=function(e){this.scrollTop!==e&&(this.$loop.schedule(this.CHANGE_SCROLL),this.scrollTop=e)},this.scrollToX=function(e){this.scrollLeft!==e&&(this.scrollLeft=e),this.$loop.schedule(this.CHANGE_H_SCROLL)},this.scrollTo=function(e,t){this.session.setScrollTop(t),this.session.setScrollLeft(t)},this.scrollBy=function(e,t){t&&this.session.setScrollTop(this.session.getScrollTop()+t),e&&this.session.setScrollLeft(this.session.getScrollLeft()+e)},this.isScrollableBy=function(e,t){if(t<0&&this.session.getScrollTop()>=1-this.scrollMargin.top)return!0;if(t>0&&this.session.getScrollTop()+this.$size.scrollerHeight-this.layerConfig.maxHeight<-1+this.scrollMargin.bottom)return!0;if(e<0&&this.session.getScrollLeft()>=1-this.scrollMargin.left)return!0;if(e>0&&this.session.getScrollLeft()+this.$size.scrollerWidth-this.layerConfig.width<-1+this.scrollMargin.right)return!0},this.pixelToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=(e+this.scrollLeft-n.left-this.$padding)/this.characterWidth,i=Math.floor((t+this.scrollTop-n.top)/this.lineHeight),s=Math.round(r);return{row:i,column:s,side:r-s>0?1:-1}},this.screenToTextCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=Math.round((e+this.scrollLeft-n.left-this.$padding)/this.characterWidth),i=(t+this.scrollTop-n.top)/this.lineHeight;return this.session.screenToDocumentPosition(i,Math.max(r,0))},this.textToScreenCoordinates=function(e,t){var n=this.scroller.getBoundingClientRect(),r=this.session.documentToScreenPosition(e,t),i=this.$padding+Math.round(r.column*this.characterWidth),s=r.row*this.lineHeight;return{pageX:n.left+i-this.scrollLeft,pageY:n.top+s-this.scrollTop}},this.visualizeFocus=function(){i.addCssClass(this.container,"ace_focus")},this.visualizeBlur=function(){i.removeCssClass(this.container,"ace_focus")},this.showComposition=function(e){this.$composition||(this.$composition={keepTextAreaAtCursor:this.$keepTextAreaAtCursor,cssText:this.textarea.style.cssText}),this.$keepTextAreaAtCursor=!0,i.addCssClass(this.textarea,"ace_composition"),this.textarea.style.cssText="",this.$moveTextAreaToCursor()},this.setCompositionText=function(e){this.$moveTextAreaToCursor()},this.hideComposition=function(){if(!this.$composition)return;i.removeCssClass(this.textarea,"ace_composition"),this.$keepTextAreaAtCursor=this.$composition.keepTextAreaAtCursor,this.textarea.style.cssText=this.$composition.cssText,this.$composition=null},this.setTheme=function(e,t){function o(r){if(n.$themeId!=e)return t&&t();if(!r.cssClass)return;i.importCssString(r.cssText,r.cssClass,n.container.ownerDocument),n.theme&&i.removeCssClass(n.container,n.theme.cssClass);var s="padding"in r?r.padding:"padding"in(n.theme||{})?4:n.$padding;n.$padding&&s!=n.$padding&&n.setPadding(s),n.$theme=r.cssClass,n.theme=r,i.addCssClass(n.container,r.cssClass),i.setCssClass(n.container,"ace_dark",r.isDark),n.$size&&(n.$size.width=0,n.$updateSizeAsync()),n._dispatchEvent("themeLoaded",{theme:r}),t&&t()}var n=this;this.$themeId=e,n._dispatchEvent("themeChange",{theme:e});if(!e||typeof e=="string"){var r=e||this.$options.theme.initialValue;s.loadModule(["theme",r],o)}else o(e)},this.getTheme=function(){return this.$themeId},this.setStyle=function(e,t){i.setCssClass(this.container,e,t!==!1)},this.unsetStyle=function(e){i.removeCssClass(this.container,e)},this.setCursorStyle=function(e){this.content.style.cursor!=e&&(this.content.style.cursor=e)},this.setMouseCursor=function(e){this.content.style.cursor=e},this.destroy=function(){this.$textLayer.destroy(),this.$cursorLayer.destroy()}}).call(g.prototype),s.defineOptions(g.prototype,"renderer",{animatedScroll:{initialValue:!1},showInvisibles:{set:function(e){this.$textLayer.setShowInvisibles(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!1},showPrintMargin:{set:function(){this.$updatePrintMargin()},initialValue:!0},printMarginColumn:{set:function(){this.$updatePrintMargin()},initialValue:80},printMargin:{set:function(e){typeof e=="number"&&(this.$printMarginColumn=e),this.$showPrintMargin=!!e,this.$updatePrintMargin()},get:function(){return this.$showPrintMargin&&this.$printMarginColumn}},showGutter:{set:function(e){this.$gutter.style.display=e?"block":"none",this.$loop.schedule(this.CHANGE_FULL),this.onGutterResize()},initialValue:!0},fadeFoldWidgets:{set:function(e){i.setCssClass(this.$gutter,"ace_fade-fold-widgets",e)},initialValue:!1},showFoldWidgets:{set:function(e){this.$gutterLayer.setShowFoldWidgets(e)},initialValue:!0},showLineNumbers:{set:function(e){this.$gutterLayer.setShowLineNumbers(e),this.$loop.schedule(this.CHANGE_GUTTER)},initialValue:!0},displayIndentGuides:{set:function(e){this.$textLayer.setDisplayIndentGuides(e)&&this.$loop.schedule(this.CHANGE_TEXT)},initialValue:!0},highlightGutterLine:{set:function(e){if(!this.$gutterLineHighlight){this.$gutterLineHighlight=i.createElement("div"),this.$gutterLineHighlight.className="ace_gutter-active-line",this.$gutter.appendChild(this.$gutterLineHighlight);return}this.$gutterLineHighlight.style.display=e?"":"none",this.$cursorLayer.$pixelPos&&this.$updateGutterLineHighlight()},initialValue:!1,value:!0},hScrollBarAlwaysVisible:{set:function(e){(!this.$hScrollBarAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},vScrollBarAlwaysVisible:{set:function(e){(!this.$vScrollBarAlwaysVisible||!this.$vScroll)&&this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:!1},fontSize:{set:function(e){typeof e=="number"&&(e+="px"),this.container.style.fontSize=e,this.updateFontSize()},initialValue:12},fontFamily:{set:function(e){this.container.style.fontFamily=e,this.updateFontSize()}},maxLines:{set:function(e){this.updateFull()}},minLines:{set:function(e){this.updateFull()}},scrollPastEnd:{set:function(e){e=+e||0;if(this.$scrollPastEnd==e)return;this.$scrollPastEnd=e,this.$loop.schedule(this.CHANGE_SCROLL)},initialValue:0,handlesSet:!0},fixedWidthGutter:{set:function(e){this.$gutterLayer.$fixedWidth=!!e,this.$loop.schedule(this.CHANGE_GUTTER)}},theme:{set:function(e){this.setTheme(e)},get:function(){return this.$themeId||this.theme},initialValue:"./theme/textmate",handlesSet:!0}}),t.VirtualRenderer=g}),ace.define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/net"),s=e("../lib/event_emitter").EventEmitter,o=e("../config"),u=function(t,n,r,i){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.onMessage=this.onMessage.bind(this),e.nameToUrl&&!e.toUrl&&(e.toUrl=e.nameToUrl);if(o.get("packaged")||!e.toUrl)i=i||o.moduleUrl(n,"worker");else{var s=this.$normalizePath;i=i||s(e.toUrl("ace/worker/worker.js",null,"_"));var u={};t.forEach(function(t){u[t]=s(e.toUrl(t,null,"_").replace(/(\.js)?(\?.*)?$/,""))})}try{this.$worker=new Worker(i)}catch(a){if(!(a instanceof window.DOMException))throw a;var f=this.$workerBlob(i),l=window.URL||window.webkitURL,c=l.createObjectURL(f);this.$worker=new Worker(c),l.revokeObjectURL(c)}this.$worker.postMessage({init:!0,tlns:u,module:n,classname:r}),this.callbackId=1,this.callbacks={},this.$worker.onmessage=this.onMessage};(function(){r.implement(this,s),this.onMessage=function(e){var t=e.data;switch(t.type){case"log":window.console&&console.log&&console.log.apply(console,t.data);break;case"event":this._signal(t.name,{data:t.data});break;case"call":var n=this.callbacks[t.id];n&&(n(t.data),delete this.callbacks[t.id])}},this.$normalizePath=function(e){return i.qualifyURL(e)},this.terminate=function(){this._signal("terminate",{}),this.deltaQueue=null,this.$worker.terminate(),this.$worker=null,this.$doc.removeEventListener("change",this.changeListener),this.$doc=null},this.send=function(e,t){this.$worker.postMessage({command:e,args:t})},this.call=function(e,t,n){if(n){var r=this.callbackId++;this.callbacks[r]=n,t.push(r)}this.send(e,t)},this.emit=function(e,t){try{this.$worker.postMessage({event:e,data:{data:t.data}})}catch(n){console.error(n.stack)}},this.attachToDocument=function(e){this.$doc&&this.terminate(),this.$doc=e,this.call("setValue",[e.getValue()]),e.on("change",this.changeListener)},this.changeListener=function(e){this.deltaQueue?this.deltaQueue.push(e.data):(this.deltaQueue=[e.data],setTimeout(this.$sendDeltaQueue,0))},this.$sendDeltaQueue=function(){var e=this.deltaQueue;if(!e)return;this.deltaQueue=null,e.length>20&&e.length>this.$doc.getLength()>>1?this.call("setValue",[this.$doc.getValue()]):this.emit("change",{data:e})},this.$workerBlob=function(e){var t="importScripts('"+i.qualifyURL(e)+"');";try{return new Blob([t],{type:"application/javascript"})}catch(n){var r=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder,s=new r;return s.append(t),s.getBlob("application/javascript")}}}).call(u.prototype);var a=function(e,t,n){this.$sendDeltaQueue=this.$sendDeltaQueue.bind(this),this.changeListener=this.changeListener.bind(this),this.callbackId=1,this.callbacks={},this.messageBuffer=[];var r=null,i=!1,u=Object.create(s),a=this;this.$worker={},this.$worker.terminate=function(){},this.$worker.postMessage=function(e){a.messageBuffer.push(e),r&&(i?setTimeout(f):f())},this.setEmitSync=function(e){i=e};var f=function(){var e=a.messageBuffer.shift();e.command?r[e.command].apply(r,e.args):e.event&&u._signal(e.event,e.data)};u.postMessage=function(e){a.onMessage({data:e})},u.callback=function(e,t){this.postMessage({type:"call",id:t,data:e})},u.emit=function(e,t){this.postMessage({type:"event",name:e,data:t})},o.loadModule(["worker",t],function(e){r=new e[n](u);while(a.messageBuffer.length)f()})};a.prototype=u.prototype,t.UIWorkerClient=a,t.WorkerClient=u}),ace.define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./range").Range,i=e("./lib/event_emitter").EventEmitter,s=e("./lib/oop"),o=function(e,t,n,r,i,s){var o=this;this.length=t,this.session=e,this.doc=e.getDocument(),this.mainClass=i,this.othersClass=s,this.$onUpdate=this.onUpdate.bind(this),this.doc.on("change",this.$onUpdate),this.$others=r,this.$onCursorChange=function(){setTimeout(function(){o.onCursorChange()})},this.$pos=n;var u=e.getUndoManager().$undoStack||e.getUndoManager().$undostack||{length:-1};this.$undoStackDepth=u.length,this.setup(),e.selection.on("changeCursor",this.$onCursorChange)};(function(){s.implement(this,i),this.setup=function(){var e=this,t=this.doc,n=this.session,i=this.$pos;this.pos=t.createAnchor(i.row,i.column),this.markerId=n.addMarker(new r(i.row,i.column,i.row,i.column+this.length),this.mainClass,null,!1),this.pos.on("change",function(t){n.removeMarker(e.markerId),e.markerId=n.addMarker(new r(t.value.row,t.value.column,t.value.row,t.value.column+e.length),e.mainClass,null,!1)}),this.others=[],this.$others.forEach(function(n){var r=t.createAnchor(n.row,n.column);e.others.push(r)}),n.setUndoSelect(!1)},this.showOtherMarkers=function(){if(this.othersActive)return;var e=this.session,t=this;this.othersActive=!0,this.others.forEach(function(n){n.markerId=e.addMarker(new r(n.row,n.column,n.row,n.column+t.length),t.othersClass,null,!1),n.on("change",function(i){e.removeMarker(n.markerId),n.markerId=e.addMarker(new r(i.value.row,i.value.column,i.value.row,i.value.column+t.length),t.othersClass,null,!1)})})},this.hideOtherMarkers=function(){if(!this.othersActive)return;this.othersActive=!1;for(var e=0;e<this.others.length;e++)this.session.removeMarker(this.others[e].markerId)},this.onUpdate=function(e){var t=e.data,n=t.range;if(n.start.row!==n.end.row)return;if(n.start.row!==this.pos.row)return;if(this.$updating)return;this.$updating=!0;var i=t.action==="insertText"?n.end.column-n.start.column:n.start.column-n.end.column;if(n.start.column>=this.pos.column&&n.start.column<=this.pos.column+this.length+1){var s=n.start.column-this.pos.column;this.length+=i;if(!this.session.$fromUndo){if(t.action==="insertText")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};u.row===n.start.row&&n.start.column<u.column&&(a.column+=i),this.doc.insert(a,t.text)}else if(t.action==="removeText")for(var o=this.others.length-1;o>=0;o--){var u=this.others[o],a={row:u.row,column:u.column+s};u.row===n.start.row&&n.start.column<u.column&&(a.column+=i),this.doc.remove(new r(a.row,a.column,a.row,a.column-i))}n.start.column===this.pos.column&&t.action==="insertText"?setTimeout(function(){this.pos.setPosition(this.pos.row,this.pos.column-i);for(var e=0;e<this.others.length;e++){var t=this.others[e],r={row:t.row,column:t.column-i};t.row===n.start.row&&n.start.column<t.column&&(r.column+=i),t.setPosition(r.row,r.column)}}.bind(this),0):n.start.column===this.pos.column&&t.action==="removeText"&&setTimeout(function(){for(var e=0;e<this.others.length;e++){var t=this.others[e];t.row===n.start.row&&n.start.column<t.column&&t.setPosition(t.row,t.column-i)}}.bind(this),0)}this.pos._emit("change",{value:this.pos});for(var o=0;o<this.others.length;o++)this.others[o]._emit("change",{value:this.others[o]})}this.$updating=!1},this.onCursorChange=function(e){if(this.$updating)return;var t=this.session.selection.getCursor();t.row===this.pos.row&&t.column>=this.pos.column&&t.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",e)):(this.hideOtherMarkers(),this._emit("cursorLeave",e))},this.detach=function(){this.session.removeMarker(this.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.pos.detach();for(var e=0;e<this.others.length;e++)this.others[e].detach();this.session.setUndoSelect(!0)},this.cancel=function(){if(this.$undoStackDepth===-1)throw Error("Canceling placeholders only supported with undo manager attached to session.");var e=this.session.getUndoManager(),t=(e.$undoStack||e.$undostack).length-this.$undoStackDepth;for(var n=0;n<t;n++)e.undo(!0)}}).call(o.prototype),t.PlaceHolder=o}),ace.define("ace/mouse/multi_select_handler",["require","exports","module","ace/lib/event","ace/lib/useragent"],function(e,t,n){function s(e,t){return e.row==t.row&&e.column==t.column}function o(e){var t=e.domEvent,n=t.altKey,o=t.shiftKey,u=t.ctrlKey,a=e.getAccelKey(),f=e.getButton();u&&i.isMac&&(f=t.button);if(e.editor.inMultiSelectMode&&f==2){e.editor.textInput.onContextMenu(e.domEvent);return}if(!u&&!n&&!a){f===0&&e.editor.inMultiSelectMode&&e.editor.exitMultiSelectMode();return}if(f!==0)return;var l=e.editor,c=l.selection,h=l.inMultiSelectMode,p=e.getDocumentPosition(),d=c.getCursor(),v=e.inSelection()||c.isEmpty()&&s(p,d),m=e.x,g=e.y,y=function(e){m=e.clientX,g=e.clientY},b=l.session,w=l.renderer.pixelToScreenCoordinates(m,g),E=w,S;if(l.$mouseHandler.$enableJumpToDef)u&&n||a&&n?S="add":n&&(S="block");else if(a&&!n){S="add";if(!h&&o)return}else n&&(S="block");S&&i.isMac&&t.ctrlKey&&l.$mouseHandler.cancelContextMenu();if(S=="add"){if(!h&&v)return;if(!h){var x=c.toOrientedRange();l.addSelectionMarker(x)}var T=c.rangeList.rangeAtPoint(p);l.$blockScrolling++,l.inVirtualSelectionMode=!0,o&&(T=null,x=c.ranges[0],l.removeSelectionMarker(x)),l.once("mouseup",function(){var e=c.toOrientedRange();T&&e.isEmpty()&&s(T.cursor,e.cursor)?c.substractPoint(e.cursor):(o?c.substractPoint(x.cursor):x&&(l.removeSelectionMarker(x),c.addRange(x)),c.addRange(e)),l.$blockScrolling--,l.inVirtualSelectionMode=!1})}else if(S=="block"){e.stop(),l.inVirtualSelectionMode=!0;var N,C=[],k=function(){var e=l.renderer.pixelToScreenCoordinates(m,g),t=b.screenToDocumentPosition(e.row,e.column);if(s(E,e)&&s(t,c.lead))return;E=e,l.selection.moveToPosition(t),l.renderer.scrollCursorIntoView(),l.removeSelectionMarkers(C),C=c.rectangularRangeBlock(E,w),l.$mouseHandler.$clickSelection&&C.length==1&&C[0].isEmpty()&&(C[0]=l.$mouseHandler.$clickSelection.clone()),C.forEach(l.addSelectionMarker,l),l.updateSelectionMarkers()};h&&!a?c.toSingleRange():!h&&a&&(N=c.toOrientedRange(),l.addSelectionMarker(N)),o?w=b.documentToScreenPosition(c.lead):c.moveToPosition(p),E={row:-1,column:-1};var L=function(e){clearInterval(O),l.removeSelectionMarkers(C),C.length||(C=[c.toOrientedRange()]),l.$blockScrolling++,N&&(l.removeSelectionMarker(N),c.toSingleRange(N));for(var t=0;t<C.length;t++)c.addRange(C[t]);l.inVirtualSelectionMode=!1,l.$mouseHandler.$clickSelection=null,l.$blockScrolling--},A=k;r.capture(l.container,y,L);var O=setInterval(function(){A()},20);return e.preventDefault()}}var r=e("../lib/event"),i=e("../lib/useragent");t.onMouseDown=o}),ace.define("ace/commands/multi_select_commands",["require","exports","module","ace/keyboard/hash_handler"],function(e,t,n){t.defaultCommands=[{name:"addCursorAbove",exec:function(e){e.selectMoreLines(-1)},bindKey:{win:"Ctrl-Alt-Up",mac:"Ctrl-Alt-Up"},readonly:!0},{name:"addCursorBelow",exec:function(e){e.selectMoreLines(1)},bindKey:{win:"Ctrl-Alt-Down",mac:"Ctrl-Alt-Down"},readonly:!0},{name:"addCursorAboveSkipCurrent",exec:function(e){e.selectMoreLines(-1,!0)},bindKey:{win:"Ctrl-Alt-Shift-Up",mac:"Ctrl-Alt-Shift-Up"},readonly:!0},{name:"addCursorBelowSkipCurrent",exec:function(e){e.selectMoreLines(1,!0)},bindKey:{win:"Ctrl-Alt-Shift-Down",mac:"Ctrl-Alt-Shift-Down"},readonly:!0},{name:"selectMoreBefore",exec:function(e){e.selectMore(-1)},bindKey:{win:"Ctrl-Alt-Left",mac:"Ctrl-Alt-Left"},readonly:!0},{name:"selectMoreAfter",exec:function(e){e.selectMore(1)},bindKey:{win:"Ctrl-Alt-Right",mac:"Ctrl-Alt-Right"},readonly:!0},{name:"selectNextBefore",exec:function(e){e.selectMore(-1,!0)},bindKey:{win:"Ctrl-Alt-Shift-Left",mac:"Ctrl-Alt-Shift-Left"},readonly:!0},{name:"selectNextAfter",exec:function(e){e.selectMore(1,!0)},bindKey:{win:"Ctrl-Alt-Shift-Right",mac:"Ctrl-Alt-Shift-Right"},readonly:!0},{name:"splitIntoLines",exec:function(e){e.multiSelect.splitIntoLines()},bindKey:{win:"Ctrl-Alt-L",mac:"Ctrl-Alt-L"},readonly:!0},{name:"alignCursors",exec:function(e){e.alignCursors()},bindKey:{win:"Ctrl-Alt-A",mac:"Ctrl-Alt-A"}},{name:"findAll",exec:function(e){e.findAll()},bindKey:{win:"Ctrl-Alt-K",mac:"Ctrl-Alt-G"},readonly:!0}],t.multiSelectCommands=[{name:"singleSelection",bindKey:"esc",exec:function(e){e.exitMultiSelectMode()},readonly:!0,isAvailable:function(e){return e&&e.inMultiSelectMode}}];var r=e("../keyboard/hash_handler").HashHandler;t.keyboardHandler=new r(t.multiSelectCommands)}),ace.define("ace/multi_select",["require","exports","module","ace/range_list","ace/range","ace/selection","ace/mouse/multi_select_handler","ace/lib/event","ace/lib/lang","ace/commands/multi_select_commands","ace/search","ace/edit_session","ace/editor","ace/config"],function(e,t,n){function h(e,t,n){return c.$options.wrap=!0,c.$options.needle=t,c.$options.backwards=n==-1,c.find(e)}function v(e,t){return e.row==t.row&&e.column==t.column}function m(e){if(e.$multiselectOnSessionChange)return;e.$onAddRange=e.$onAddRange.bind(e),e.$onRemoveRange=e.$onRemoveRange.bind(e),e.$onMultiSelect=e.$onMultiSelect.bind(e),e.$onSingleSelect=e.$onSingleSelect.bind(e),e.$multiselectOnSessionChange=t.onSessionChange.bind(e),e.$checkMultiselectChange=e.$checkMultiselectChange.bind(e),e.$multiselectOnSessionChange(e),e.on("changeSession",e.$multiselectOnSessionChange),e.on("mousedown",o),e.commands.addCommands(f.defaultCommands),g(e)}function g(e){function r(t){n&&(e.renderer.setMouseCursor(""),n=!1)}var t=e.textInput.getElement(),n=!1;u.addListener(t,"keydown",function(t){t.keyCode==18&&!(t.ctrlKey||t.shiftKey||t.metaKey)?n||(e.renderer.setMouseCursor("crosshair"),n=!0):n&&r()}),u.addListener(t,"keyup",r),u.addListener(t,"blur",r)}var r=e("./range_list").RangeList,i=e("./range").Range,s=e("./selection").Selection,o=e("./mouse/multi_select_handler").onMouseDown,u=e("./lib/event"),a=e("./lib/lang"),f=e("./commands/multi_select_commands");t.commands=f.defaultCommands.concat(f.multiSelectCommands);var l=e("./search").Search,c=new l,p=e("./edit_session").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(p.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(e,t){if(!e)return;if(!this.inMultiSelectMode&&this.rangeCount===0){var n=this.toOrientedRange();this.rangeList.add(n),this.rangeList.add(e);if(this.rangeList.ranges.length!=2)return this.rangeList.removeAll(),t||this.fromOrientedRange(e);this.rangeList.removeAll(),this.rangeList.add(n),this.$onAddRange(n)}e.cursor||(e.cursor=e.end);var r=this.rangeList.add(e);return this.$onAddRange(e),r.length&&this.$onRemoveRange(r),this.rangeCount>1&&!this.inMultiSelectMode&&(this._signal("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),t||this.fromOrientedRange(e)},this.toSingleRange=function(e){e=e||this.ranges[0];var t=this.rangeList.removeAll();t.length&&this.$onRemoveRange(t),e&&this.fromOrientedRange(e)},this.substractPoint=function(e){var t=this.rangeList.substractPoint(e);if(t)return this.$onRemoveRange(t),t[0]},this.mergeOverlappingRanges=function(){var e=this.rangeList.merge();e.length?this.$onRemoveRange(e):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(e){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(e),this._signal("addRange",{range:e})},this.$onRemoveRange=function(e){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var t=this.rangeList.ranges.pop();e.push(t),this.rangeCount=0}for(var n=e.length;n--;){var r=this.ranges.indexOf(e[n]);this.ranges.splice(r,1)}this._signal("removeRange",{ranges:e}),this.rangeCount===0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._signal("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),t=t||this.ranges[0],t&&!t.isEqual(this.getRange())&&this.fromOrientedRange(t)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new r,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeCount?this.rangeList.ranges.concat():[this.getRange()]},this.splitIntoLines=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var n=this.getRange(),r=this.isBackwards(),s=n.start.row,o=n.end.row;if(s==o){if(r)var u=n.end,a=n.start;else var u=n.start,a=n.end;this.addRange(i.fromPoints(a,a)),this.addRange(i.fromPoints(u,u));return}var f=[],l=this.getLineRange(s,!0);l.start.column=n.start.column,f.push(l);for(var c=s+1;c<o;c++)f.push(this.getLineRange(c,!0));l=this.getLineRange(o,!0),l.end.column=n.end.column,f.push(l),f.forEach(this.addRange,this)}},this.toggleBlockSelection=function(){if(this.rangeCount>1){var e=this.rangeList.ranges,t=e[e.length-1],n=i.fromPoints(e[0].start,t.end);this.toSingleRange(),this.setSelectionRange(n,t.cursor==t.start)}else{var r=this.session.documentToScreenPosition(this.selectionLead),s=this.session.documentToScreenPosition(this.selectionAnchor),o=this.rectangularRangeBlock(r,s);o.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(e,t,n){var r=[],s=e.column<t.column;if(s)var o=e.column,u=t.column;else var o=t.column,u=e.column;var a=e.row<t.row;if(a)var f=e.row,l=t.row;else var f=t.row,l=e.row;o<0&&(o=0),f<0&&(f=0),f==l&&(n=!0);for(var c=f;c<=l;c++){var h=i.fromPoints(this.session.screenToDocumentPosition(c,o),this.session.screenToDocumentPosition(c,u));if(h.isEmpty()){if(p&&v(h.end,p))break;var p=h.end}h.cursor=s?h.start:h.end,r.push(h)}a&&r.reverse();if(!n){var d=r.length-1;while(r[d].isEmpty()&&d>0)d--;if(d>0){var m=0;while(r[m].isEmpty())m++}for(var g=d;g>=m;g--)r[g].isEmpty()&&r.splice(g,1)}return r}}.call(s.prototype);var d=e("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(e){e.cursor||(e.cursor=e.end);var t=this.getSelectionStyle();return e.marker=this.session.addMarker(e,"ace_selection",t),this.session.$selectionMarkers.push(e),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,e},this.removeSelectionMarker=function(e){if(!e.marker)return;this.session.removeMarker(e.marker);var t=this.session.$selectionMarkers.indexOf(e);t!=-1&&this.session.$selectionMarkers.splice(t,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(e){var t=this.session.$selectionMarkers;for(var n=e.length;n--;){var r=e[n];if(!r.marker)continue;this.session.removeMarker(r.marker);var i=t.indexOf(r);i!=-1&&t.splice(i,1)}this.session.selectionMarkerCount=t.length},this.$onAddRange=function(e){this.addSelectionMarker(e.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(e){this.removeSelectionMarkers(e.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(e){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("ace_multiselect"),this.keyBinding.addKeyboardHandler(f.keyboardHandler),this.commands.setDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(e){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("ace_multiselect"),this.keyBinding.removeKeyboardHandler(f.keyboardHandler),this.commands.removeDefaultHandler("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers(),this._emit("changeSelection")},this.$onMultiSelectExec=function(e){var t=e.command,n=e.editor;if(!n.multiSelect)return;if(!t.multiSelectAction){var r=t.exec(n,e.args||{});n.multiSelect.addRange(n.multiSelect.toOrientedRange()),n.multiSelect.mergeOverlappingRanges()}else t.multiSelectAction=="forEach"?r=n.forEachSelection(t,e.args):t.multiSelectAction=="forEachLine"?r=n.forEachSelection(t,e.args,!0):t.multiSelectAction=="single"?(n.exitMultiSelectMode(),r=t.exec(n,e.args||{})):r=t.multiSelectAction(n,e.args||{});return r},this.forEachSelection=function(e,t,n){if(this.inVirtualSelectionMode)return;var r=n&&n.keepOrder,i=n==1||n&&n.$byLines,o=this.session,u=this.selection,a=u.rangeList,f=(r?u:a).ranges,l;if(!f.length)return e.exec?e.exec(this,t||{}):e(this,t||{});var c=u._eventRegistry;u._eventRegistry={};var h=new s(o);this.inVirtualSelectionMode=!0;for(var p=f.length;p--;){if(i)while(p>0&&f[p].start.row==f[p-1].end.row)p--;h.fromOrientedRange(f[p]),h.index=p,this.selection=o.selection=h;var d=e.exec?e.exec(this,t||{}):e(this,t||{});!l&&d!==undefined&&(l=d),h.toOrientedRange(f[p])}h.detach(),this.selection=o.selection=u,this.inVirtualSelectionMode=!1,u._eventRegistry=c,u.mergeOverlappingRanges();var v=this.renderer.$scrollAnimation;return this.onCursorChange(),this.onSelectionChange(),v&&v.from==v.to&&this.renderer.animateScrolling(v.from),l},this.exitMultiSelectMode=function(){if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getSelectedText=function(){var e="";if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var t=this.multiSelect.rangeList.ranges,n=[];for(var r=0;r<t.length;r++)n.push(this.session.getTextRange(t[r]));var i=this.session.getDocument().getNewLineCharacter();e=n.join(i),e.length==(n.length-1)*i.length&&(e="")}else this.selection.isEmpty()||(e=this.session.getTextRange(this.getSelectionRange()));return e},this.$checkMultiselectChange=function(e,t){if(this.inMultiSelectMode&&!this.inVirtualSelectionMode){var n=this.multiSelect.ranges[0];if(this.multiSelect.isEmpty()&&t==this.multiSelect.anchor)return;var r=t==this.multiSelect.anchor?n.cursor==n.start?n.end:n.start:n.cursor;v(r,t)||this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange())}},this.onPaste=function(e){if(this.$readOnly)return;var t={text:e};this._signal("paste",t),e=t.text;if(!this.inMultiSelectMode||this.inVirtualSelectionMode)return this.insert(e);var n=e.split(/\r\n|\r|\n/),r=this.selection.rangeList.ranges;if(n.length>r.length||n.length<2||!n[1])return this.commands.exec("insertstring",this,e);for(var i=r.length;i--;){var s=r[i];s.isEmpty()||this.session.remove(s),this.session.insert(s.start,n[i])}},this.findAll=function(e,t,n){t=t||{},t.needle=e||t.needle;if(t.needle==undefined){var r=this.selection.isEmpty()?this.selection.getWordRange():this.selection.getRange();t.needle=this.session.getTextRange(r)}this.$search.set(t);var i=this.$search.findAll(this.session);if(!i.length)return 0;this.$blockScrolling+=1;var s=this.multiSelect;n||s.toSingleRange(i[0]);for(var o=i.length;o--;)s.addRange(i[o],!0);return r&&s.rangeList.rangeAtPoint(r.start)&&s.addRange(r,!0),this.$blockScrolling-=1,i.length},this.selectMoreLines=function(e,t){var n=this.selection.toOrientedRange(),r=n.cursor==n.end,s=this.session.documentToScreenPosition(n.cursor);this.selection.$desiredColumn&&(s.column=this.selection.$desiredColumn);var o=this.session.screenToDocumentPosition(s.row+e,s.column);if(!n.isEmpty())var u=this.session.documentToScreenPosition(r?n.end:n.start),a=this.session.screenToDocumentPosition(u.row+e,u.column);else var a=o;if(r){var f=i.fromPoints(o,a);f.cursor=f.start}else{var f=i.fromPoints(a,o);f.cursor=f.end}f.desiredColumn=s.column;if(!this.selection.inMultiSelectMode)this.selection.addRange(n);else if(t)var l=n.cursor;this.selection.addRange(f),l&&this.selection.substractPoint(l)},this.transposeSelections=function(e){var t=this.session,n=t.multiSelect,r=n.ranges;for(var i=r.length;i--;){var s=r[i];if(s.isEmpty()){var o=t.getWordRange(s.start.row,s.start.column);s.start.row=o.start.row,s.start.column=o.start.column,s.end.row=o.end.row,s.end.column=o.end.column}}n.mergeOverlappingRanges();var u=[];for(var i=r.length;i--;){var s=r[i];u.unshift(t.getTextRange(s))}e<0?u.unshift(u.pop()):u.push(u.shift());for(var i=r.length;i--;){var s=r[i],o=s.clone();t.replace(s,u[i]),s.start.row=o.start.row,s.start.column=o.start.column}},this.selectMore=function(e,t){var n=this.session,r=n.multiSelect,i=r.toOrientedRange();i.isEmpty()&&(i=n.getWordRange(i.start.row,i.start.column),i.cursor=e==-1?i.start:i.end,this.multiSelect.addRange(i));var s=n.getTextRange(i),o=h(n,s,e);o&&(o.cursor=e==-1?o.start:o.end,this.$blockScrolling+=1,this.session.unfold(o),this.multiSelect.addRange(o),this.$blockScrolling-=1,this.renderer.scrollCursorIntoView(null,.5)),t&&this.multiSelect.substractPoint(i.cursor)},this.alignCursors=function(){var e=this.session,t=e.multiSelect,n=t.ranges,r=-1,s=n.filter(function(e){if(e.cursor.row==r)return!0;r=e.cursor.row});if(!n.length||s.length==n.length-1){var o=this.selection.getRange(),u=o.start.row,f=o.end.row,l=u==f;if(l){var c=this.session.getLength(),h;do h=this.session.getLine(f);while(/[=:]/.test(h)&&++f<c);do h=this.session.getLine(u);while(/[=:]/.test(h)&&--u>0);u<0&&(u=0),f>=c&&(f=c-1)}var p=this.session.doc.removeLines(u,f);p=this.$reAlignText(p,l),this.session.doc.insert({row:u,column:0},p.join("\n")+"\n"),l||(o.start.column=0,o.end.column=p[p.length-1].length),this.selection.setRange(o)}else{s.forEach(function(e){t.substractPoint(e.cursor)});var d=0,v=Infinity,m=n.map(function(t){var n=t.cursor,r=e.getLine(n.row),i=r.substr(n.column).search(/\S/g);return i==-1&&(i=0),n.column>d&&(d=n.column),i<v&&(v=i),i});n.forEach(function(t,n){var r=t.cursor,s=d-r.column,o=m[n]-v;s>o?e.insert(r,a.stringRepeat(" ",s-o)):e.remove(new i(r.row,r.column,r.row,r.column-s+o)),t.start.column=t.end.column=d,t.start.row=t.end.row=r.row,t.cursor=t.end}),t.fromOrientedRange(n[0]),this.renderer.updateCursor(),this.renderer.updateBackMarkers()}},this.$reAlignText=function(e,t){function u(e){return a.stringRepeat(" ",e)}function f(e){return e[2]?u(i)+e[2]+u(s-e[2].length+o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function l(e){return e[2]?u(i+s-e[2].length)+e[2]+u(o," ")+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}function c(e){return e[2]?u(i)+e[2]+u(o)+e[4].replace(/^([=:])\s+/,"$1 "):e[0]}var n=!0,r=!0,i,s,o;return e.map(function(e){var t=e.match(/(\s*)(.*?)(\s*)([=:].*)/);return t?i==null?(i=t[1].length,s=t[2].length,o=t[3].length,t):(i+s+o!=t[1].length+t[2].length+t[3].length&&(r=!1),i!=t[1].length&&(n=!1),i>t[1].length&&(i=t[1].length),s<t[2].length&&(s=t[2].length),o>t[3].length&&(o=t[3].length),t):[e]}).map(t?f:n?r?l:f:c)}}).call(d.prototype),t.onSessionChange=function(e){var t=e.session;t.multiSelect||(t.$selectionMarkers=[],t.selection.$initRangeList(),t.multiSelect=t.selection),this.multiSelect=t.multiSelect;var n=e.oldSession;n&&(n.multiSelect.off("addRange",this.$onAddRange),n.multiSelect.off("removeRange",this.$onRemoveRange),n.multiSelect.off("multiSelect",this.$onMultiSelect),n.multiSelect.off("singleSelect",this.$onSingleSelect),n.multiSelect.lead.off("change",this.$checkMultiselectChange),n.multiSelect.anchor.off("change",this.$checkMultiselectChange)),t.multiSelect.on("addRange",this.$onAddRange),t.multiSelect.on("removeRange",this.$onRemoveRange),t.multiSelect.on("multiSelect",this.$onMultiSelect),t.multiSelect.on("singleSelect",this.$onSingleSelect),t.multiSelect.lead.on("change",this.$checkMultiselectChange),t.multiSelect.anchor.on("change",this.$checkMultiselectChange),this.inMultiSelectMode!=t.selection.inMultiSelectMode&&(t.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},t.MultiSelect=m,e("./config").defineOptions(d.prototype,"editor",{enableMultiselect:{set:function(e){m(this),e?(this.on("changeSession",this.$multiselectOnSessionChange),this.on("mousedown",o)):(this.off("changeSession",this.$multiselectOnSessionChange),this.off("mousedown",o))},value:!0}})}),ace.define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../../range").Range,i=t.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?"start":t=="markbeginend"&&this.foldingStopMarker&&this.foldingStopMarker.test(r)?"end":""},this.getFoldWidgetRange=function(e,t,n){return null},this.indentationBlock=function(e,t,n){var i=/\S/,s=e.getLine(t),o=s.search(i);if(o==-1)return;var u=n||s.length,a=e.getLength(),f=t,l=t;while(++t<a){var c=e.getLine(t).search(i);if(c==-1)continue;if(c<=o)break;l=t}if(l>f){var h=e.getLine(l).length;return new r(f,u,l,h)}},this.openingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i+1},u=e.$findClosingBracket(t,o,s);if(!u)return;var a=e.foldWidgets[u.row];return a==null&&(a=e.getFoldWidget(u.row)),a=="start"&&u.row>o.row&&(u.row--,u.column=e.getLine(u.row).length),r.fromPoints(o,u)},this.closingBracketBlock=function(e,t,n,i,s){var o={row:n,column:i},u=e.$findOpeningBracket(t,o);if(!u)return;return u.column++,o.column--,r.fromPoints(u,o)}}).call(i.prototype)}),ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;border-radius: 2px;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}),ace.define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e){this.session=e,this.session.widgetManager=this,this.session.getRowLength=this.getRowLength,this.session.$getWidgetScreenLength=this.$getWidgetScreenLength,this.updateOnChange=this.updateOnChange.bind(this),this.renderWidgets=this.renderWidgets.bind(this),this.measureWidgets=this.measureWidgets.bind(this),this.session._changedWidgets=[],this.detach=this.detach.bind(this),this.session.on("change",this.updateOnChange)}var r=e("./lib/oop"),i=e("./lib/dom"),s=e("./range").Range;(function(){this.getRowLength=function(e){var t;return this.lineWidgets?t=this.lineWidgets[e]&&this.lineWidgets[e].rowCount||0:t=0,!this.$useWrapMode||!this.$wrapData[e]?1+t:this.$wrapData[e].length+1+t},this.$getWidgetScreenLength=function(){var e=0;return this.lineWidgets.forEach(function(t){t&&t.rowCount&&(e+=t.rowCount)}),e},this.attach=function(e){e.widgetManager&&e.widgetManager!=this&&e.widgetManager.detach();if(this.editor==e)return;this.detach(),this.editor=e,this.editor.on("changeSession",this.detach),e.widgetManager=this,e.renderer.on("beforeRender",this.measureWidgets),e.renderer.on("afterRender",this.renderWidgets)},this.detach=function(e){if(e&&e.session==this.session)return;var t=this.editor;if(!t)return;t.off("changeSession",this.detach),this.editor=null,t.widgetManager=null,t.renderer.off("beforeRender",this.measureWidgets),t.renderer.off("afterRender",this.renderWidgets);var n=this.session.lineWidgets;n&&n.forEach(function(e){e&&e.el&&e.el.parentNode&&(e._inDocument=!1,e.el.parentNode.removeChild(e.el))})},this.updateOnChange=function(e){var t=this.session.lineWidgets;if(!t)return;var n=e.data,r=n.range,i=r.start.row,s=r.end.row-i;if(s!==0)if(n.action=="removeText"||n.action=="removeLines"){var o=t.splice(i+1,s);o.forEach(function(e){e&&this.removeLineWidget(e)},this),this.$updateRows()}else{var u=new Array(s);u.unshift(i,0),t.splice.apply(t,u),this.$updateRows()}},this.$updateRows=function(){var e=this.session.lineWidgets;if(!e)return;var t=!0;e.forEach(function(e,n){e&&(t=!1,e.row=n)}),t&&(this.session.lineWidgets=null)},this.addLineWidget=function(e){this.session.lineWidgets||(this.session.lineWidgets=new Array(this.session.getLength())),this.session.lineWidgets[e.row]=e;var t=this.editor.renderer;return e.html&&!e.el&&(e.el=i.createElement("div"),e.el.innerHTML=e.html),e.el&&(i.addCssClass(e.el,"ace_lineWidgetContainer"),e.el.style.position="absolute",e.el.style.zIndex=5,t.container.appendChild(e.el),e._inDocument=!0),e.coverGutter||(e.el.style.zIndex=3),e.pixelHeight||(e.pixelHeight=e.el.offsetHeight),e.rowCount==null&&(e.rowCount=e.pixelHeight/t.layerConfig.lineHeight),this.session._emit("changeFold",{data:{start:{row:e.row}}}),this.$updateRows(),this.renderWidgets(null,t),e},this.removeLineWidget=function(e){e._inDocument=!1,e.el&&e.el.parentNode&&e.el.parentNode.removeChild(e.el);if(e.editor&&e.editor.destroy)try{e.editor.destroy()}catch(t){}this.session.lineWidgets&&(this.session.lineWidgets[e.row]=undefined),this.session._emit("changeFold",{data:{start:{row:e.row}}}),this.$updateRows()},this.onWidgetChanged=function(e){this.session._changedWidgets.push(e),this.editor&&this.editor.renderer.updateFull()},this.measureWidgets=function(e,t){var n=this.session._changedWidgets,r=t.layerConfig;if(!n||!n.length)return;var i=Infinity;for(var s=0;s<n.length;s++){var o=n[s];o._inDocument||(o._inDocument=!0,t.container.appendChild(o.el)),o.h=o.el.offsetHeight,o.fixedWidth||(o.w=o.el.offsetWidth,o.screenWidth=Math.ceil(o.w/r.characterWidth));var u=o.h/r.lineHeight;o.coverLine&&(u-=this.session.getRowLineCount(o.row),u<0&&(u=0)),o.rowCount!=u&&(o.rowCount=u,o.row<i&&(i=o.row))}i!=Infinity&&(this.session._emit("changeFold",{data:{start:{row:i}}}),this.session.lineWidgetWidth=null),this.session._changedWidgets=[]},this.renderWidgets=function(e,t){var n=t.layerConfig,r=this.session.lineWidgets;if(!r)return;var i=Math.min(this.firstRow,n.firstRow),s=Math.max(this.lastRow,n.lastRow,r.length);while(i>0&&!r[i])i--;this.firstRow=n.firstRow,this.lastRow=n.lastRow,t.$cursorLayer.config=n;for(var o=i;o<=s;o++){var u=r[o];if(!u||!u.el)continue;u._inDocument||(u._inDocument=!0,t.container.appendChild(u.el));var a=t.$cursorLayer.getPixelPosition({row:o,column:0},!0).top;u.coverLine||(a+=n.lineHeight*this.session.getRowLineCount(u.row)),u.el.style.top=a-n.offset+"px";var f=u.coverGutter?0:t.gutterWidth;u.fixedWidth||(f-=t.scrollLeft),u.el.style.left=f+"px",u.fixedWidth?u.el.style.right=t.scrollBar.getWidth()+"px":u.el.style.right=""}}}).call(o.prototype),t.LineWidgets=o}),ace.define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"],function(e,t,n){"use strict";function o(e,t,n){var r=0,i=e.length-1;while(r<=i){var s=r+i>>1,o=n(t,e[s]);if(o>0)r=s+1;else{if(!(o<0))return s;i=s-1}}return-(r+1)}function u(e,t,n){var r=e.getAnnotations().sort(s.comparePoints);if(!r.length)return;var i=o(r,{row:t,column:-1},s.comparePoints);i<0&&(i=-i-1),i>=r.length-1?i=n>0?0:r.length-1:i===0&&n<0&&(i=r.length-1);var u=r[i];if(!u||!n)return;if(u.row===t){do u=r[i+=n];while(u&&u.row===t);if(!u)return r.slice()}var a=[];t=u.row;do a[n<0?"unshift":"push"](u),u=r[i+=n];while(u&&u.row==t);return a.length&&a}var r=e("ace/line_widgets").LineWidgets,i=e("ace/lib/dom"),s=e("ace/range").Range;t.showErrorMarker=function(e,t){var n=e.session;n.widgetManager||(n.widgetManager=new r(n),n.widgetManager.attach(e));var s=e.getCursorPosition(),o=s.row,a=n.lineWidgets&&n.lineWidgets[o];a?a.destroy():o-=t;var f=u(n,o,t),l;if(f){var c=f[0];s.column=(c.pos&&typeof c.column!="number"?c.pos.sc:c.column)||0,s.row=c.row,l=e.renderer.$gutterLayer.$annotations[s.row]}else{if(a)return;l={text:["Looks good!"],className:"ace_ok"}}e.session.unfold(s.row),e.selection.moveToPosition(s);var h={row:s.row,fixedWidth:!0,coverGutter:!0,el:i.createElement("div")},p=h.el.appendChild(i.createElement("div")),d=h.el.appendChild(i.createElement("div"));d.className="error_widget_arrow "+l.className;var v=e.renderer.$cursorLayer.getPixelPosition(s).left;d.style.left=v+e.renderer.gutterWidth-5+"px",h.el.className="error_widget_wrapper",p.className="error_widget "+l.className,p.innerHTML=l.text.join("<br>"),p.appendChild(i.createElement("div"));var m=function(e,t,n){if(t===0&&(n==="esc"||n==="return"))return h.destroy(),{command:"null"}};h.destroy=function(){if(e.$mouseHandler.isMousePressed)return;e.keyBinding.removeKeyboardHandler(m),n.widgetManager.removeLineWidget(h),e.off("changeSelection",h.destroy),e.off("changeSession",h.destroy),e.off("mouseup",h.destroy),e.off("change",h.destroy)},e.keyBinding.addKeyboardHandler(m),e.on("changeSelection",h.destroy),e.on("changeSession",h.destroy),e.on("mouseup",h.destroy),e.on("change",h.destroy),e.session.widgetManager.addLineWidget(h),h.el.onmousedown=e.focus.bind(e),e.renderer.scrollCursorIntoView(null,.5,{bottom:h.el.offsetHeight})},i.importCssString("    .error_widget_wrapper {        background: inherit;        color: inherit;        border:none    }    .error_widget {        border-top: solid 2px;        border-bottom: solid 2px;        margin: 5px 0;        padding: 10px 40px;        white-space: pre-wrap;    }    .error_widget.ace_error, .error_widget_arrow.ace_error{        border-color: #ff5a5a    }    .error_widget.ace_warning, .error_widget_arrow.ace_warning{        border-color: #F1D817    }    .error_widget.ace_info, .error_widget_arrow.ace_info{        border-color: #5a5a5a    }    .error_widget.ace_ok, .error_widget_arrow.ace_ok{        border-color: #5aaa5a    }    .error_widget_arrow {        position: absolute;        border: solid 5px;        border-top-color: transparent!important;        border-right-color: transparent!important;        border-left-color: transparent!important;        top: -5px;    }","")}),ace.define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/dom"),i=e("./lib/event"),s=e("./editor").Editor,o=e("./edit_session").EditSession,u=e("./undomanager").UndoManager,a=e("./virtual_renderer").VirtualRenderer;e("./worker/worker_client"),e("./keyboard/hash_handler"),e("./placeholder"),e("./multi_select"),e("./mode/folding/fold_mode"),e("./theme/textmate"),e("./ext/error_marker"),t.config=e("./config"),t.require=e,t.edit=function(e){if(typeof e=="string"){var n=e;e=document.getElementById(n);if(!e)throw new Error("ace.edit can't find div #"+n)}if(e.env&&e.env.editor instanceof s)return e.env.editor;var o=t.createEditSession(r.getInnerText(e));e.innerHTML="";var u=new s(new a(e));u.setSession(o);var f={document:o,editor:u,onResize:u.resize.bind(u,null)};return i.addListener(window,"resize",f.onResize),u.on("destroy",function(){i.removeListener(window,"resize",f.onResize)}),e.env=u.env=f,u},t.createEditSession=function(e,t){var n=new o(e,t);return n.setUndoManager(new u),n},t.EditSession=o,t.UndoManager=u});
            +            (function() {
            +                ace.require(["ace/ace"], function(a) {
            +                    a && a.config.init(true);
            +                    if (!window.ace)
            +                        window.ace = a;
            +                    for (var key in a) if (a.hasOwnProperty(key))
            +                        window.ace[key] = a[key];
            +                });
            +            })();
            +        
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-beautify.js b/dist/assets/js/vendor/ace-nc/ext-beautify.js
            new file mode 100644
            index 0000000000..659262c8c3
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-beautify.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/beautify/php_rules",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";var r=e("ace/token_iterator").TokenIterator;t.newLines=[{type:"support.php_tag",value:"<?php"},{type:"support.php_tag",value:"<?"},{type:"support.php_tag",value:"?>"},{type:"paren.lparen",value:"{",indent:!0},{type:"paren.rparen",breakBefore:!0,value:"}",indent:!1},{type:"paren.rparen",breakBefore:!0,value:"})",indent:!1,dontBreak:!0},{type:"comment"},{type:"text",value:";"},{type:"text",value:":",context:"php"},{type:"keyword",value:"case",indent:!0,dontBreak:!0},{type:"keyword",value:"default",indent:!0,dontBreak:!0},{type:"keyword",value:"break",indent:!1,dontBreak:!0},{type:"punctuation.doctype.end",value:">"},{type:"meta.tag.punctuation.end",value:">"},{type:"meta.tag.punctuation.begin",value:"<",blockTag:!0,indent:!0,dontBreak:!0},{type:"meta.tag.punctuation.begin",value:"</",indent:!1,breakBefore:!0,dontBreak:!0},{type:"punctuation.operator",value:";"}],t.spaces=[{type:"xml-pe",prepend:!0},{type:"entity.other.attribute-name",prepend:!0},{type:"storage.type",value:"var",append:!0},{type:"storage.type",value:"function",append:!0},{type:"keyword.operator",value:"="},{type:"keyword",value:"as",prepend:!0,append:!0},{type:"keyword",value:"function",append:!0},{type:"support.function",next:/[^\(]/,append:!0},{type:"keyword",value:"or",append:!0,prepend:!0},{type:"keyword",value:"and",append:!0,prepend:!0},{type:"keyword",value:"case",append:!0},{type:"keyword.operator",value:"||",append:!0,prepend:!0},{type:"keyword.operator",value:"&&",append:!0,prepend:!0}],t.singleTags=["!doctype","area","base","br","hr","input","img","link","meta"],t.transform=function(e,n,r){var i=e.getCurrentToken(),s=t.newLines,o=t.spaces,u=t.singleTags,a="",f=0,l=!1,c,h,p={},d,v={},m=!1,g="";while(i!==null){console.log(i);if(!i){i=e.stepForward();continue}i.type=="support.php_tag"&&i.value!="?>"?r="php":i.type=="support.php_tag"&&i.value=="?>"?r="html":i.type=="meta.tag.name.style"&&r!="css"?r="css":i.type=="meta.tag.name.style"&&r=="css"?r="html":i.type=="meta.tag.name.script"&&r!="js"?r="js":i.type=="meta.tag.name.script"&&r=="js"&&(r="html"),v=e.stepForward(),v&&v.type.indexOf("meta.tag.name")==0&&(d=v.value),p.type=="support.php_tag"&&p.value=="<?="&&(l=!0),i.type=="meta.tag.name"&&(i.value=i.value.toLowerCase()),i.type=="text"&&(i.value=i.value.trim());if(!i.value){i=v;continue}g=i.value;for(var y in o)i.type==o[y].type&&(!o[y].value||i.value==o[y].value)&&v&&(!o[y].next||o[y].next.test(v.value))&&(o[y].prepend&&(g=" "+i.value),o[y].append&&(g+=" "));i.type.indexOf("meta.tag.name")==0&&(c=i.value),m=!1;for(y in s)if(i.type==s[y].type&&(!s[y].value||i.value==s[y].value)&&(!s[y].blockTag||u.indexOf(d)===-1)&&(!s[y].context||s[y].context===r)){s[y].indent===!1&&f--;if(s[y].breakBefore&&(!s[y].prev||s[y].prev.test(p.value))){a+="\n",m=!0;for(y=0;y<f;y++)a+="	"}break}if(l===!1)for(y in s)if(p.type==s[y].type&&(!s[y].value||p.value==s[y].value)&&(!s[y].blockTag||u.indexOf(c)===-1)&&(!s[y].context||s[y].context===r)){s[y].indent===!0&&f++;if(!s[y].dontBreak&&!m){a+="\n";for(y=0;y<f;y++)a+="	"}break}a+=g,p.type=="support.php_tag"&&p.value=="?>"&&(l=!1),h=c,p=i,i=v;if(i===null)break}return a}}),ace.define("ace/ext/beautify",["require","exports","module","ace/token_iterator","ace/ext/beautify/php_rules"],function(e,t,n){"use strict";var r=e("ace/token_iterator").TokenIterator,i=e("./beautify/php_rules").transform;t.beautify=function(e){var t=new r(e,0,0),n=t.getCurrentToken(),s=e.$modeId.split("/").pop(),o=i(t,s);e.doc.setValue(o)},t.commands=[{name:"beautify",exec:function(e){t.beautify(e.session)},bindKey:"Ctrl-Shift-B"}]});
            +                (function() {
            +                    ace.require(["ace/ext/beautify"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-chromevox.js b/dist/assets/js/vendor/ace-nc/ext-chromevox.js
            new file mode 100644
            index 0000000000..21014840f7
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-chromevox.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/chromevox",["require","exports","module","ace/editor","ace/config"],function(e,t,n){function gt(){return typeof cvox!="undefined"&&cvox&&cvox.Api}function wt(e){if(gt())mt(e);else{yt++;if(yt>=bt)return;window.setTimeout(wt,500,e)}}var r={};r.SpeechProperty,r.Cursor,r.Token,r.Annotation;var i={rate:.8,pitch:.4,volume:.9},s={rate:1,pitch:.5,volume:.9},o={rate:.8,pitch:.8,volume:.9},u={rate:.8,pitch:.3,volume:.9},a={rate:.8,pitch:.7,volume:.9},f={rate:.8,pitch:.8,volume:.9},l={punctuationEcho:"none",relativePitch:-0.6},c="ALERT_NONMODAL",h="ALERT_MODAL",p="INVALID_KEYPRESS",d="insertMode",v="start",m=[{substr:";",newSubstr:" semicolon "},{substr:":",newSubstr:" colon "}],g={SPEAK_ANNOT:"annots",SPEAK_ALL_ANNOTS:"all_annots",TOGGLE_LOCATION:"toggle_location",SPEAK_MODE:"mode",SPEAK_ROW_COL:"row_col",TOGGLE_DISPLACEMENT:"toggle_displacement",FOCUS_TEXT:"focus_text"},y="CONTROL + SHIFT ";r.editor=null;var b=null,w={},E=!1,S=!1,x=!1,T=null,N={},C={},k=function(e){return y+String.fromCharCode(e)},L=function(){var e=r.editor.keyBinding.getKeyboardHandler();return e.$id==="ace/keyboard/vim"},A=function(e){return r.editor.getSession().getTokenAt(e.row,e.column+1)},O=function(e){return r.editor.getSession().getLine(e.row)},M=function(e){w[e.row]&&cvox.Api.playEarcon(c),E?(cvox.Api.stop(),W(e),R(A(e)),I(e.row,1)):I(e.row,0)},_=function(e){var t=O(e),n=t.substr(e.column-1);e.column===0&&(n=" "+t);var r=/^\W(\w+)/,i=r.exec(n);return i!==null},D={constant:{prop:i},entity:{prop:o},keyword:{prop:u},storage:{prop:a},variable:{prop:f},meta:{prop:s,replace:[{substr:"</",newSubstr:" closing tag "},{substr:"/>",newSubstr:" close tag "},{substr:"<",newSubstr:" tag start "},{substr:">",newSubstr:" tag end "}]}},P={prop:P},H=function(e,t){var n=e;for(var r=0;r<t.length;r++){var i=t[r],s=new RegExp(i.substr,"g");n=n.replace(s,i.newSubstr)}return n},B=function(e,t,n){var r={};r.value="",r.type=e[t].type;for(var i=t;i<n;i++)r.value+=e[i].value;return r},j=function(e){if(e.length<=1)return e;var t=[],n=0;for(var r=1;r<e.length;r++){var i=e[n],s=e[r];U(i)!==U(s)&&(t.push(B(e,n,r)),n=r)}return t.push(B(e,n,e.length)),t},F=function(e){var t=r.editor.getSession().getLine(e),n=/^\s*$/;return n.exec(t)!==null},I=function(e,t){var n=r.editor.getSession().getTokens(e);if(n.length===0||F(e)){cvox.Api.playEarcon("EDITABLE_TEXT");return}n=j(n);var i=n[0];n=n.filter(function(e){return e!==i}),z(i,t),n.forEach(R)},q=function(e){z(e,0)},R=function(e){z(e,1)},U=function(e){if(!e||!e.type)return;var t=e.type.split(".");if(t.length===0)return;var n=t[0],r=D[n];return r?r:P},z=function(e,t){var n=U(e),r=H(e.value,m);n.replace&&(r=H(r,n.replace)),cvox.Api.speak(r,t,n.prop)},W=function(e){var t=O(e);cvox.Api.speak(t[e.column],1)},X=function(e,t){var n=O(t),r=n.substring(e.column,t.column);r=r.replace(/ /g," space "),cvox.Api.speak(r)},V=function(e,t){if(Math.abs(e.column-t.column)!==1){var n=O(t).length;if(t.column===0||t.column===n){I(t.row,0);return}if(_(t)){cvox.Api.stop(),R(A(t));return}}W(t)},$=function(e,t){r.editor.selection.isEmpty()?S?X(e,t):V(e,t):(X(e,t),cvox.Api.speak("selected",1))},J=function(e){if(x){x=!1;return}var t=r.editor.selection.getCursor();t.row!==b.row?M(t):$(b,t),b=t},K=function(e){r.editor.selection.isEmpty()&&cvox.Api.speak("unselected")},Q=function(e){var t=e.data;switch(t.action){case"removeText":cvox.Api.speak(t.text,0,l),x=!0;break;case"insertText":cvox.Api.speak(t.text,0),x=!0}},G=function(e){var t=e.row,n=e.column;return!w[t]||!w[t][n]},Y=function(e){w={};for(var t=0;t<e.length;t++){var n=e[t],r=n.row,i=n.column;w[r]||(w[r]={}),w[r][i]=n}},Z=function(e){var t=r.editor.getSession().getAnnotations(),n=t.filter(G);n.length>0&&cvox.Api.playEarcon(c),Y(t)},et=function(e){var t=e.type+" "+e.text+" on "+nt(e.row,e.column);t=t.replace(";","semicolon"),cvox.Api.speak(t,1)},tt=function(e){var t=w[e];for(var n in t)et(t[n])},nt=function(e,t){return"row "+(e+1)+" column "+(t+1)},rt=function(){cvox.Api.speak(nt(b.row,b.column))},it=function(){for(var e in w)tt(e)},st=function(){if(!L())return;switch(r.editor.keyBinding.$data.state){case d:cvox.Api.speak("Insert mode");break;case v:cvox.Api.speak("Command mode")}},ot=function(){E=!E,E?cvox.Api.speak("Speak location on row change enabled."):cvox.Api.speak("Speak location on row change disabled.")},ut=function(){S=!S,S?cvox.Api.speak("Speak displacement on column changes."):cvox.Api.speak("Speak current character or word on column changes.")},at=function(e){if(e.ctrlKey&&e.shiftKey){var t=N[e.keyCode];t&&t.func()}},ft=function(e,t){if(!L())return;var n=t.keyBinding.$data.state;if(n===T)return;switch(n){case d:cvox.Api.playEarcon(h),cvox.Api.setKeyEcho(!0);break;case v:cvox.Api.playEarcon(h),cvox.Api.setKeyEcho(!1)}T=n},lt=function(e){var t=e.detail.customCommand,n=C[t];n&&(n.func(),r.editor.focus())},ct=function(){var e=dt.map(function(e){return{desc:e.desc+k(e.keyCode),cmd:e.cmd}}),t=document.querySelector("body");t.setAttribute("contextMenuActions",JSON.stringify(e)),t.addEventListener("ATCustomEvent",lt,!0)},ht=function(e){e.match?I(b.row,0):cvox.Api.playEarcon(p)},pt=function(){r.editor.focus()},dt=[{keyCode:49,func:function(){tt(b.row)},cmd:g.SPEAK_ANNOT,desc:"Speak annotations on line"},{keyCode:50,func:it,cmd:g.SPEAK_ALL_ANNOTS,desc:"Speak all annotations"},{keyCode:51,func:st,cmd:g.SPEAK_MODE,desc:"Speak Vim mode"},{keyCode:52,func:ot,cmd:g.TOGGLE_LOCATION,desc:"Toggle speak row location"},{keyCode:53,func:rt,cmd:g.SPEAK_ROW_COL,desc:"Speak row and column"},{keyCode:54,func:ut,cmd:g.TOGGLE_DISPLACEMENT,desc:"Toggle speak displacement"},{keyCode:55,func:pt,cmd:g.FOCUS_TEXT,desc:"Focus text"}],vt=function(){r.editor=editor,editor.getSession().selection.on("changeCursor",J),editor.getSession().selection.on("changeSelection",K),editor.getSession().on("change",Q),editor.getSession().on("changeAnnotation",Z),editor.on("changeStatus",ft),editor.on("findSearchBox",ht),editor.container.addEventListener("keydown",at),b=editor.selection.getCursor()},mt=function(e){vt(),dt.forEach(function(e){N[e.keyCode]=e,C[e.cmd]=e}),e.on("focus",vt),L()&&cvox.Api.setKeyEcho(!1),ct()},yt=0,bt=15,Et=e("../editor").Editor;e("../config").defineOptions(Et.prototype,"editor",{enableChromevoxEnhancements:{set:function(e){e&&wt(this)},value:!0}})});
            +                (function() {
            +                    ace.require(["ace/ext/chromevox"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-elastic_tabstops_lite.js b/dist/assets/js/vendor/ace-nc/ext-elastic_tabstops_lite.js
            new file mode 100644
            index 0000000000..2d475d2430
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-elastic_tabstops_lite.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/elastic_tabstops_lite",["require","exports","module","ace/editor","ace/config"],function(e,t,n){"use strict";var r=function(e){this.$editor=e;var t=this,n=[],r=!1;this.onAfterExec=function(){r=!1,t.processRows(n),n=[]},this.onExec=function(){r=!0},this.onChange=function(e){var t=e.data.range;r&&(n.indexOf(t.start.row)==-1&&n.push(t.start.row),t.end.row!=t.start.row&&n.push(t.end.row))}};(function(){this.processRows=function(e){this.$inChange=!0;var t=[];for(var n=0,r=e.length;n<r;n++){var i=e[n];if(t.indexOf(i)>-1)continue;var s=this.$findCellWidthsForBlock(i),o=this.$setBlockCellWidthsToMax(s.cellWidths),u=s.firstRow;for(var a=0,f=o.length;a<f;a++){var l=o[a];t.push(u),this.$adjustRow(u,l),u++}}this.$inChange=!1},this.$findCellWidthsForBlock=function(e){var t=[],n,r=e;while(r>=0){n=this.$cellWidthsForRow(r);if(n.length==0)break;t.unshift(n),r--}var i=r+1;r=e;var s=this.$editor.session.getLength();while(r<s-1){r++,n=this.$cellWidthsForRow(r);if(n.length==0)break;t.push(n)}return{cellWidths:t,firstRow:i}},this.$cellWidthsForRow=function(e){var t=this.$selectionColumnsForRow(e),n=[-1].concat(this.$tabsForRow(e)),r=n.map(function(e){return 0}).slice(1),i=this.$editor.session.getLine(e);for(var s=0,o=n.length-1;s<o;s++){var u=n[s]+1,a=n[s+1],f=this.$rightmostSelectionInCell(t,a),l=i.substring(u,a);r[s]=Math.max(l.replace(/\s+$/g,"").length,f-u)}return r},this.$selectionColumnsForRow=function(e){var t=[],n=this.$editor.getCursorPosition();return this.$editor.session.getSelection().isEmpty()&&e==n.row&&t.push(n.column),t},this.$setBlockCellWidthsToMax=function(e){var t=!0,n,r,i,s=this.$izip_longest(e);for(var o=0,u=s.length;o<u;o++){var a=s[o];if(!a.push){console.error(a);continue}a.push(NaN);for(var f=0,l=a.length;f<l;f++){var c=a[f];t&&(n=f,i=0,t=!1);if(isNaN(c)){r=f;for(var h=n;h<r;h++)e[h][o]=i;t=!0}i=Math.max(i,c)}}return e},this.$rightmostSelectionInCell=function(e,t){var n=0;if(e.length){var r=[];for(var i=0,s=e.length;i<s;i++)e[i]<=t?r.push(i):r.push(0);n=Math.max.apply(Math,r)}return n},this.$tabsForRow=function(e){var t=[],n=this.$editor.session.getLine(e),r=/\t/g,i;while((i=r.exec(n))!=null)t.push(i.index);return t},this.$adjustRow=function(e,t){var n=this.$tabsForRow(e);if(n.length==0)return;var r=0,i=-1,s=this.$izip(t,n);for(var o=0,u=s.length;o<u;o++){var a=s[o][0],f=s[o][1];i+=1+a,f+=r;var l=i-f;if(l==0)continue;var c=this.$editor.session.getLine(e).substr(0,f),h=c.replace(/\s*$/g,""),p=c.length-h.length;l>0&&(this.$editor.session.getDocument().insertInLine({row:e,column:f+1},Array(l+1).join(" ")+"	"),this.$editor.session.getDocument().removeInLine(e,f,f+1),r+=l),l<0&&p>=-l&&(this.$editor.session.getDocument().removeInLine(e,f+l,f),r+=l)}},this.$izip_longest=function(e){if(!e[0])return[];var t=e[0].length,n=e.length;for(var r=1;r<n;r++){var i=e[r].length;i>t&&(t=i)}var s=[];for(var o=0;o<t;o++){var u=[];for(var r=0;r<n;r++)e[r][o]===""?u.push(NaN):u.push(e[r][o]);s.push(u)}return s},this.$izip=function(e,t){var n=e.length>=t.length?t.length:e.length,r=[];for(var i=0;i<n;i++){var s=[e[i],t[i]];r.push(s)}return r}}).call(r.prototype),t.ElasticTabstopsLite=r;var i=e("../editor").Editor;e("../config").defineOptions(i.prototype,"editor",{useElasticTabstops:{set:function(e){e?(this.elasticTabstops||(this.elasticTabstops=new r(this)),this.commands.on("afterExec",this.elasticTabstops.onAfterExec),this.commands.on("exec",this.elasticTabstops.onExec),this.on("change",this.elasticTabstops.onChange)):this.elasticTabstops&&(this.commands.removeListener("afterExec",this.elasticTabstops.onAfterExec),this.commands.removeListener("exec",this.elasticTabstops.onExec),this.removeListener("change",this.elasticTabstops.onChange))}}})});
            +                (function() {
            +                    ace.require(["ace/ext/elastic_tabstops_lite"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-emmet.js b/dist/assets/js/vendor/ace-nc/ext-emmet.js
            new file mode 100644
            index 0000000000..00f8815823
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-emmet.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/anchor","ace/keyboard/hash_handler","ace/tokenizer","ace/lib/dom","ace/editor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./lib/lang"),o=e("./range").Range,u=e("./anchor").Anchor,a=e("./keyboard/hash_handler").HashHandler,f=e("./tokenizer").Tokenizer,l=o.comparePoints,c=function(){this.snippetMap={},this.snippetNameMap={}};(function(){r.implement(this,i),this.getTokenizer=function(){function e(e,t,n){return e=e.substr(1),/^\d+$/.test(e)&&!n.inFormatString?[{tabstopId:parseInt(e,10)}]:[{text:e}]}function t(e){return"(?:[^\\\\"+e+"]|\\\\.)"}return c.$tokenizer=new f({start:[{regex:/:/,onMatch:function(e,t,n){return n.length&&n[0].expectIf?(n[0].expectIf=!1,n[0].elseBranch=n[0],[n[0]]):":"}},{regex:/\\./,onMatch:function(e,t,n){var r=e[1];return r=="}"&&n.length?e=r:"`$\\".indexOf(r)!=-1?e=r:n.inFormatString&&(r=="n"?e="\n":r=="t"?e="\n":"ulULE".indexOf(r)!=-1&&(e={changeCase:r,local:r>"a"})),[e]}},{regex:/}/,onMatch:function(e,t,n){return[n.length?n.shift():e]}},{regex:/\$(?:\d+|\w+)/,onMatch:e},{regex:/\$\{[\dA-Z_a-z]+/,onMatch:function(t,n,r){var i=e(t.substr(1),n,r);return r.unshift(i[0]),i},next:"snippetVar"},{regex:/\n/,token:"newline",merge:!1}],snippetVar:[{regex:"\\|"+t("\\|")+"*\\|",onMatch:function(e,t,n){n[0].choices=e.slice(1,-1).split(",")},next:"start"},{regex:"/("+t("/")+"+)/(?:("+t("/")+"*)/)(\\w*):?",onMatch:function(e,t,n){var r=n[0];return r.fmtString=e,e=this.splitRegex.exec(e),r.guard=e[1],r.fmt=e[2],r.flag=e[3],""},next:"start"},{regex:"`"+t("`")+"*`",onMatch:function(e,t,n){return n[0].code=e.splice(1,-1),""},next:"start"},{regex:"\\?",onMatch:function(e,t,n){n[0]&&(n[0].expectIf=!0)},next:"start"},{regex:"([^:}\\\\]|\\\\.)*:?",token:"",next:"start"}],formatString:[{regex:"/("+t("/")+"+)/",token:"regex"},{regex:"",onMatch:function(e,t,n){n.inFormatString=!0},next:"start"}]}),c.prototype.getTokenizer=function(){return c.$tokenizer},c.$tokenizer},this.tokenizeTmSnippet=function(e,t){return this.getTokenizer().getLineTokens(e,t).tokens.map(function(e){return e.value||e})},this.$getDefaultValue=function(e,t){if(/^[A-Z]\d+$/.test(t)){var n=t.substr(1);return(this.variables[t[0]+"__"]||{})[n]}if(/^\d+$/.test(t))return(this.variables.__||{})[t];t=t.replace(/^TM_/,"");if(!e)return;var r=e.session;switch(t){case"CURRENT_WORD":var i=r.getWordRange();case"SELECTION":case"SELECTED_TEXT":return r.getTextRange(i);case"CURRENT_LINE":return r.getLine(e.getCursorPosition().row);case"PREV_LINE":return r.getLine(e.getCursorPosition().row-1);case"LINE_INDEX":return e.getCursorPosition().column;case"LINE_NUMBER":return e.getCursorPosition().row+1;case"SOFT_TABS":return r.getUseSoftTabs()?"YES":"NO";case"TAB_SIZE":return r.getTabSize();case"FILENAME":case"FILEPATH":return"";case"FULLNAME":return"Ace"}},this.variables={},this.getVariableValue=function(e,t){return this.variables.hasOwnProperty(t)?this.variables[t](e,t)||"":this.$getDefaultValue(e,t)||""},this.tmStrFormat=function(e,t,n){var r=t.flag||"",i=t.guard;i=new RegExp(i,r.replace(/[^gi]/,""));var s=this.tokenizeTmSnippet(t.fmt,"formatString"),o=this,u=e.replace(i,function(){o.variables.__=arguments;var e=o.resolveVariables(s,n),t="E";for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="object"){e[r]="";if(i.changeCase&&i.local){var u=e[r+1];u&&typeof u=="string"&&(i.changeCase=="u"?e[r]=u[0].toUpperCase():e[r]=u[0].toLowerCase(),e[r+1]=u.substr(1))}else i.changeCase&&(t=i.changeCase)}else t=="U"?e[r]=i.toUpperCase():t=="L"&&(e[r]=i.toLowerCase())}return e.join("")});return this.variables.__=null,u},this.resolveVariables=function(e,t){function o(t){var n=e.indexOf(t,r+1);n!=-1&&(r=n)}var n=[];for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="string")n.push(i);else{if(typeof i!="object")continue;if(i.skip)o(i);else{if(i.processed<r)continue;if(i.text){var s=this.getVariableValue(t,i.text);s&&i.fmtString&&(s=this.tmStrFormat(s,i)),i.processed=r,i.expectIf==null?s&&(n.push(s),o(i)):s?i.skip=i.elseBranch:o(i)}else i.tabstopId!=null?n.push(i):i.changeCase!=null&&n.push(i)}}}return n},this.insertSnippetForSelection=function(e,t){function f(e){var t=[];for(var n=0;n<e.length;n++){var r=e[n];if(typeof r=="object"){if(a[r.tabstopId])continue;var i=e.lastIndexOf(r,n-1);r=t[i]||{tabstopId:r.tabstopId}}t[n]=r}return t}var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=e.session.getTabString(),s=r.match(/^\s*/)[0];n.column<s.length&&(s=s.slice(0,n.column));var o=this.tokenizeTmSnippet(t);o=this.resolveVariables(o,e),o=o.map(function(e){return e=="\n"?e+s:typeof e=="string"?e.replace(/\t/g,i):e});var u=[];o.forEach(function(e,t){if(typeof e!="object")return;var n=e.tabstopId,r=u[n];r||(r=u[n]=[],r.index=n,r.value="");if(r.indexOf(e)!==-1)return;r.push(e);var i=o.indexOf(e,t+1);if(i===-1)return;var s=o.slice(t+1,i),a=s.some(function(e){return typeof e=="object"});a&&!r.value?r.value=s:s.length&&(!r.value||typeof r.value!="string")&&(r.value=s.join(""))}),u.forEach(function(e){e.length=0});var a={};for(var l=0;l<o.length;l++){var c=o[l];if(typeof c!="object")continue;var p=c.tabstopId,d=o.indexOf(c,l+1);if(a[p]){a[p]===c&&(a[p]=null);continue}var v=u[p],m=typeof v.value=="string"?[v.value]:f(v.value);m.unshift(l+1,Math.max(0,d-l)),m.push(c),a[p]=c,o.splice.apply(o,m),v.indexOf(c)===-1&&v.push(c)}var g=0,y=0,b="";o.forEach(function(e){typeof e=="string"?(e[0]==="\n"?(y=e.length-1,g++):y+=e.length,b+=e):e.start?e.end={row:g,column:y}:e.start={row:g,column:y}});var w=e.getSelectionRange(),E=e.session.replace(w,b),S=new h(e),x=e.inVirtualSelectionMode&&e.selection.index;S.addTabstops(u,w.start,E,x)},this.insertSnippet=function(e,t){var n=this;if(e.inVirtualSelectionMode)return n.insertSnippetForSelection(e,t);e.forEachSelection(function(){n.insertSnippetForSelection(e,t)},null,{keepOrder:!0}),e.tabstopManager&&e.tabstopManager.tabNext()},this.$getScope=function(e){var t=e.session.$mode.$id||"";t=t.split("/").pop();if(t==="html"||t==="php"){t==="php"&&!e.session.$mode.inlinePhp&&(t="html");var n=e.getCursorPosition(),r=e.session.getState(n.row);typeof r=="object"&&(r=r[0]),r.substring&&(r.substring(0,3)=="js-"?t="javascript":r.substring(0,4)=="css-"?t="css":r.substring(0,4)=="php-"&&(t="php"))}return t},this.getActiveScopes=function(e){var t=this.$getScope(e),n=[t],r=this.snippetMap;return r[t]&&r[t].includeScopes&&n.push.apply(n,r[t].includeScopes),n.push("_"),n},this.expandWithTab=function(e,t){var n=this,r=e.forEachSelection(function(){return n.expandSnippetForSelection(e,t)},null,{keepOrder:!0});return r&&e.tabstopManager&&e.tabstopManager.tabNext(),r},this.expandSnippetForSelection=function(e,t){var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=r.substring(0,n.column),s=r.substr(n.column),o=this.snippetMap,u;return this.getActiveScopes(e).some(function(e){var t=o[e];return t&&(u=this.findMatchingSnippet(t,i,s)),!!u},this),u?t&&t.dryRun?!0:(e.session.doc.removeInLine(n.row,n.column-u.replaceBefore.length,n.column+u.replaceAfter.length),this.variables.M__=u.matchBefore,this.variables.T__=u.matchAfter,this.insertSnippetForSelection(e,u.content),this.variables.M__=this.variables.T__=null,!0):!1},this.findMatchingSnippet=function(e,t,n){for(var r=e.length;r--;){var i=e[r];if(i.startRe&&!i.startRe.test(t))continue;if(i.endRe&&!i.endRe.test(n))continue;if(!i.startRe&&!i.endRe)continue;return i.matchBefore=i.startRe?i.startRe.exec(t):[""],i.matchAfter=i.endRe?i.endRe.exec(n):[""],i.replaceBefore=i.triggerRe?i.triggerRe.exec(t)[0]:"",i.replaceAfter=i.endTriggerRe?i.endTriggerRe.exec(n)[0]:"",i}},this.snippetMap={},this.snippetNameMap={},this.register=function(e,t){function o(e){return e&&!/^\^?\(.*\)\$?$|^\\b$/.test(e)&&(e="(?:"+e+")"),e||""}function u(e,t,n){return e=o(e),t=o(t),n?(e=t+e,e&&e[e.length-1]!="$"&&(e+="$")):(e+=t,e&&e[0]!="^"&&(e="^"+e)),new RegExp(e)}function a(e){e.scope||(e.scope=t||"_"),t=e.scope,n[t]||(n[t]=[],r[t]={});var o=r[t];if(e.name){var a=o[e.name];a&&i.unregister(a),o[e.name]=e}n[t].push(e),e.tabTrigger&&!e.trigger&&(!e.guard&&/^\w/.test(e.tabTrigger)&&(e.guard="\\b"),e.trigger=s.escapeRegExp(e.tabTrigger)),e.startRe=u(e.trigger,e.guard,!0),e.triggerRe=new RegExp(e.trigger,"",!0),e.endRe=u(e.endTrigger,e.endGuard,!0),e.endTriggerRe=new RegExp(e.endTrigger,"",!0)}var n=this.snippetMap,r=this.snippetNameMap,i=this;e.content?a(e):Array.isArray(e)&&e.forEach(a),this._signal("registerSnippets",{scope:t})},this.unregister=function(e,t){function i(e){var i=r[e.scope||t];if(i&&i[e.name]){delete i[e.name];var s=n[e.scope||t],o=s&&s.indexOf(e);o>=0&&s.splice(o,1)}}var n=this.snippetMap,r=this.snippetNameMap;e.content?i(e):Array.isArray(e)&&e.forEach(i)},this.parseSnippetFile=function(e){e=e.replace(/\r/g,"");var t=[],n={},r=/^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm,i;while(i=r.exec(e)){if(i[1])try{n=JSON.parse(i[1]),t.push(n)}catch(s){}if(i[4])n.content=i[4].replace(/^\t/gm,""),t.push(n),n={};else{var o=i[2],u=i[3];if(o=="regex"){var a=/\/((?:[^\/\\]|\\.)*)|$/g;n.guard=a.exec(u)[1],n.trigger=a.exec(u)[1],n.endTrigger=a.exec(u)[1],n.endGuard=a.exec(u)[1]}else o=="snippet"?(n.tabTrigger=u.match(/^\S*/)[0],n.name||(n.name=u)):n[o]=u}}return t},this.getSnippetByName=function(e,t){var n=this.snippetNameMap,r;return this.getActiveScopes(t).some(function(t){var i=n[t];return i&&(r=i[e]),!!r},this),r}}).call(c.prototype);var h=function(e){if(e.tabstopManager)return e.tabstopManager;e.tabstopManager=this,this.$onChange=this.onChange.bind(this),this.$onChangeSelection=s.delayedCall(this.onChangeSelection.bind(this)).schedule,this.$onChangeSession=this.onChangeSession.bind(this),this.$onAfterExec=this.onAfterExec.bind(this),this.attach(e)};(function(){this.attach=function(e){this.index=0,this.ranges=[],this.tabstops=[],this.$openTabstops=null,this.selectedTabstop=null,this.editor=e,this.editor.on("change",this.$onChange),this.editor.on("changeSelection",this.$onChangeSelection),this.editor.on("changeSession",this.$onChangeSession),this.editor.commands.on("afterExec",this.$onAfterExec),this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.detach=function(){this.tabstops.forEach(this.removeTabstopMarkers,this),this.ranges=null,this.tabstops=null,this.selectedTabstop=null,this.editor.removeListener("change",this.$onChange),this.editor.removeListener("changeSelection",this.$onChangeSelection),this.editor.removeListener("changeSession",this.$onChangeSession),this.editor.commands.removeListener("afterExec",this.$onAfterExec),this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.tabstopManager=null,this.editor=null},this.onChange=function(e){var t=e.data.range,n=e.data.action[0]=="r",r=t.start,i=t.end,s=r.row,o=i.row,u=o-s,a=i.column-r.column;n&&(u=-u,a=-a);if(!this.$inChange&&n){var f=this.selectedTabstop,c=f&&!f.some(function(e){return l(e.start,r)<=0&&l(e.end,i)>=0});if(c)return this.detach()}var h=this.ranges;for(var p=0;p<h.length;p++){var d=h[p];if(d.end.row<r.row)continue;if(n&&l(r,d.start)<0&&l(i,d.end)>0){this.removeRange(d),p--;continue}d.start.row==s&&d.start.column>r.column&&(d.start.column+=a),d.end.row==s&&d.end.column>=r.column&&(d.end.column+=a),d.start.row>=s&&(d.start.row+=u),d.end.row>=s&&(d.end.row+=u),l(d.start,d.end)>0&&this.removeRange(d)}h.length||this.detach()},this.updateLinkedFields=function(){var e=this.selectedTabstop;if(!e||!e.hasLinkedRanges)return;this.$inChange=!0;var n=this.editor.session,r=n.getTextRange(e.firstNonLinked);for(var i=e.length;i--;){var s=e[i];if(!s.linked)continue;var o=t.snippetManager.tmStrFormat(r,s.original);n.replace(s,o)}this.$inChange=!1},this.onAfterExec=function(e){e.command&&!e.command.readOnly&&this.updateLinkedFields()},this.onChangeSelection=function(){if(!this.editor)return;var e=this.editor.selection.lead,t=this.editor.selection.anchor,n=this.editor.selection.isEmpty();for(var r=this.ranges.length;r--;){if(this.ranges[r].linked)continue;var i=this.ranges[r].contains(e.row,e.column),s=n||this.ranges[r].contains(t.row,t.column);if(i&&s)return}this.detach()},this.onChangeSession=function(){this.detach()},this.tabNext=function(e){var t=this.tabstops.length,n=this.index+(e||1);n=Math.min(Math.max(n,1),t),n==t&&(n=0),this.selectTabstop(n),n===0&&this.detach()},this.selectTabstop=function(e){this.$openTabstops=null;var t=this.tabstops[this.index];t&&this.addTabstopMarkers(t),this.index=e,t=this.tabstops[this.index];if(!t||!t.length)return;this.selectedTabstop=t;if(!this.editor.inVirtualSelectionMode){var n=this.editor.multiSelect;n.toSingleRange(t.firstNonLinked.clone());for(var r=t.length;r--;){if(t.hasLinkedRanges&&t[r].linked)continue;n.addRange(t[r].clone(),!0)}n.ranges[0]&&n.addRange(n.ranges[0].clone())}else this.editor.selection.setRange(t.firstNonLinked);this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.addTabstops=function(e,t,n){this.$openTabstops||(this.$openTabstops=[]);if(!e[0]){var r=o.fromPoints(n,n);v(r.start,t),v(r.end,t),e[0]=[r],e[0].index=0}var i=this.index,s=[i+1,0],u=this.ranges;e.forEach(function(e,n){var r=this.$openTabstops[n]||e;for(var i=e.length;i--;){var a=e[i],f=o.fromPoints(a.start,a.end||a.start);d(f.start,t),d(f.end,t),f.original=a,f.tabstop=r,u.push(f),r!=e?r.unshift(f):r[i]=f,a.fmtString?(f.linked=!0,r.hasLinkedRanges=!0):r.firstNonLinked||(r.firstNonLinked=f)}r.firstNonLinked||(r.hasLinkedRanges=!1),r===e&&(s.push(r),this.$openTabstops[n]=r),this.addTabstopMarkers(r)},this),s.length>2&&(this.tabstops.length&&s.push(s.splice(2,1)[0]),this.tabstops.splice.apply(this.tabstops,s))},this.addTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){e.markerId||(e.markerId=t.addMarker(e,"ace_snippet-marker","text"))})},this.removeTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){t.removeMarker(e.markerId),e.markerId=null})},this.removeRange=function(e){var t=e.tabstop.indexOf(e);e.tabstop.splice(t,1),t=this.ranges.indexOf(e),this.ranges.splice(t,1),this.editor.session.removeMarker(e.markerId),e.tabstop.length||(t=this.tabstops.indexOf(e.tabstop),t!=-1&&this.tabstops.splice(t,1),this.tabstops.length||this.detach())},this.keyboardHandler=new a,this.keyboardHandler.bindKeys({Tab:function(e){if(t.snippetManager&&t.snippetManager.expandWithTab(e))return;e.tabstopManager.tabNext(1)},"Shift-Tab":function(e){e.tabstopManager.tabNext(-1)},Esc:function(e){e.tabstopManager.detach()},Return:function(e){return!1}})}).call(h.prototype);var p={};p.onChange=u.prototype.onChange,p.setPosition=function(e,t){this.pos.row=e,this.pos.column=t},p.update=function(e,t,n){this.$insertRight=n,this.pos=e,this.onChange(t)};var d=function(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row},v=function(e,t){e.row==t.row&&(e.column-=t.column),e.row-=t.row};e("./lib/dom").importCssString(".ace_snippet-marker {    -moz-box-sizing: border-box;    box-sizing: border-box;    background: rgba(194, 193, 208, 0.09);    border: 1px dotted rgba(211, 208, 235, 0.62);    position: absolute;}"),t.snippetManager=new c;var m=e("./editor").Editor;(function(){this.insertSnippet=function(e,n){return t.snippetManager.insertSnippet(this,e,n)},this.expandSnippet=function(e){return t.snippetManager.expandWithTab(this,e)}}).call(m.prototype)}),ace.define("ace/ext/emmet",["require","exports","module","ace/keyboard/hash_handler","ace/editor","ace/snippets","ace/range","resources","resources","range","tabStops","resources","utils","actions","ace/config"],function(e,t,n){"use strict";function a(){}var r=e("ace/keyboard/hash_handler").HashHandler,i=e("ace/editor").Editor,s=e("ace/snippets").snippetManager,o=e("ace/range").Range,u;i.prototype.indexToPosition=function(e){return this.session.doc.indexToPosition(e)},i.prototype.positionToIndex=function(e){return this.session.doc.positionToIndex(e)},a.prototype={setupContext:function(e){this.ace=e,this.indentation=e.session.getTabString(),u||(u=window.emmet),u.require("resources").setVariable("indentation",this.indentation),this.$syntax=null,this.$syntax=this.getSyntax()},getSelectionRange:function(){var e=this.ace.getSelectionRange();return{start:this.ace.positionToIndex(e.start),end:this.ace.positionToIndex(e.end)}},createSelection:function(e,t){this.ace.selection.setRange({start:this.ace.indexToPosition(e),end:this.ace.indexToPosition(t)})},getCurrentLineRange:function(){var e=this.ace.getCursorPosition().row,t=this.ace.session.getLine(e).length,n=this.ace.positionToIndex({row:e,column:0});return{start:n,end:n+t}},getCaretPos:function(){var e=this.ace.getCursorPosition();return this.ace.positionToIndex(e)},setCaretPos:function(e){var t=this.ace.indexToPosition(e);this.ace.selection.moveToPosition(t)},getCurrentLine:function(){var e=this.ace.getCursorPosition().row;return this.ace.session.getLine(e)},replaceContent:function(e,t,n,r){n==null&&(n=t==null?this.getContent().length:t),t==null&&(t=0);var i=this.ace,u=o.fromPoints(i.indexToPosition(t),i.indexToPosition(n));i.session.remove(u),u.end=u.start,e=this.$updateTabstops(e),s.insertSnippet(i,e)},getContent:function(){return this.ace.getValue()},getSyntax:function(){if(this.$syntax)return this.$syntax;var e=this.ace.session.$modeId.split("/").pop();if(e=="html"||e=="php"){var t=this.ace.getCursorPosition(),n=this.ace.session.getState(t.row);typeof n!="string"&&(n=n[0]),n&&(n=n.split("-"),n.length>1?e=n[0]:e=="php"&&(e="html"))}return e},getProfileName:function(){switch(this.getSyntax()){case"css":return"css";case"xml":case"xsl":return"xml";case"html":var e=u.require("resources").getVariable("profile");return e||(e=this.ace.session.getLines(0,2).join("").search(/<!DOCTYPE[^>]+XHTML/i)!=-1?"xhtml":"html"),e}return"xhtml"},prompt:function(e){return prompt(e)},getSelection:function(){return this.ace.session.getTextRange()},getFilePath:function(){return""},$updateTabstops:function(e){var t=1e3,n=0,r=null,i=u.require("range"),s=u.require("tabStops"),o=u.require("resources").getVocabulary("user"),a={tabstop:function(e){var o=parseInt(e.group,10),u=o===0;u?o=++n:o+=t;var f=e.placeholder;f&&(f=s.processText(f,a));var l="${"+o+(f?":"+f:"")+"}";return u&&(r=i.create(e.start,l)),l},escape:function(e){return e=="$"?"\\$":e=="\\"?"\\\\":e}};return e=s.processText(e,a),o.variables.insert_final_tabstop&&!/\$\{0\}$/.test(e)?e+="${0}":r&&(e=u.require("utils").replaceSubstring(e,"${0}",r)),e}};var f={expand_abbreviation:{mac:"ctrl+alt+e",win:"alt+e"},match_pair_outward:{mac:"ctrl+d",win:"ctrl+,"},match_pair_inward:{mac:"ctrl+j",win:"ctrl+shift+0"},matching_pair:{mac:"ctrl+alt+j",win:"alt+j"},next_edit_point:"alt+right",prev_edit_point:"alt+left",toggle_comment:{mac:"command+/",win:"ctrl+/"},split_join_tag:{mac:"shift+command+'",win:"shift+ctrl+`"},remove_tag:{mac:"command+'",win:"shift+ctrl+;"},evaluate_math_expression:{mac:"shift+command+y",win:"shift+ctrl+y"},increment_number_by_1:"ctrl+up",decrement_number_by_1:"ctrl+down",increment_number_by_01:"alt+up",decrement_number_by_01:"alt+down",increment_number_by_10:{mac:"alt+command+up",win:"shift+alt+up"},decrement_number_by_10:{mac:"alt+command+down",win:"shift+alt+down"},select_next_item:{mac:"shift+command+.",win:"shift+ctrl+."},select_previous_item:{mac:"shift+command+,",win:"shift+ctrl+,"},reflect_css_value:{mac:"shift+command+r",win:"shift+ctrl+r"},encode_decode_data_url:{mac:"shift+ctrl+d",win:"ctrl+'"},expand_abbreviation_with_tab:"Tab",wrap_with_abbreviation:{mac:"shift+ctrl+a",win:"shift+ctrl+a"}},l=new a;t.commands=new r,t.runEmmetCommand=function(e){l.setupContext(e);if(l.getSyntax()=="php")return!1;var t=u.require("actions");if(this.action=="expand_abbreviation_with_tab"&&!e.selection.isEmpty())return!1;if(this.action=="wrap_with_abbreviation")return setTimeout(function(){t.run("wrap_with_abbreviation",l)},0);try{var n=t.run(this.action,l)}catch(r){e._signal("changeStatus",typeof r=="string"?r:r.message),console.log(r),n=!1}return n};for(var c in f)t.commands.addCommand({name:"emmet:"+c,action:c,bindKey:f[c],exec:t.runEmmetCommand,multiSelectAction:"forEach"});var h=function(e,n){var r=n;if(!r)return;var i=r.session.$modeId,s=i&&/css|less|scss|sass|stylus|html|php/.test(i);e.enableEmmet===!1&&(s=!1),s?r.keyBinding.addKeyboardHandler(t.commands):r.keyBinding.removeKeyboardHandler(t.commands)};t.AceEmmetEditor=a,e("ace/config").defineOptions(i.prototype,"editor",{enableEmmet:{set:function(e){this[e?"on":"removeListener"]("changeMode",h),h({enableEmmet:!!e},this)},value:!0}}),t.setCore=function(e){u=e}});
            +                (function() {
            +                    ace.require(["ace/ext/emmet"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-error_marker.js b/dist/assets/js/vendor/ace-nc/ext-error_marker.js
            new file mode 100644
            index 0000000000..dfefa20ab8
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-error_marker.js
            @@ -0,0 +1,5 @@
            +;
            +                (function() {
            +                    ace.require(["ace/ext/error_marker"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-keybinding_menu.js b/dist/assets/js/vendor/ace-nc/ext-keybinding_menu.js
            new file mode 100644
            index 0000000000..8d4a6dc187
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-keybinding_menu.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/menu_tools/overlay_page",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../../lib/dom"),i="#ace_settingsmenu, #kbshortcutmenu {background-color: #F7F7F7;color: black;box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55);padding: 1em 0.5em 2em 1em;overflow: auto;position: absolute;margin: 0;bottom: 0;right: 0;top: 0;z-index: 9991;cursor: default;}.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu {box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25);background-color: rgba(255, 255, 255, 0.6);color: black;}.ace_optionsMenuEntry:hover {background-color: rgba(100, 100, 100, 0.1);-webkit-transition: all 0.5s;transition: all 0.3s}.ace_closeButton {background: rgba(245, 146, 146, 0.5);border: 1px solid #F48A8A;border-radius: 50%;padding: 7px;position: absolute;right: -8px;top: -8px;z-index: 1000;}.ace_closeButton{background: rgba(245, 146, 146, 0.9);}.ace_optionsMenuKey {color: darkslateblue;font-weight: bold;}.ace_optionsMenuCommand {color: darkcyan;font-weight: normal;}";r.importCssString(i),n.exports.overlayPage=function(t,n,i,s,o,u){function l(e){e.keyCode===27&&a.click()}i=i?"top: "+i+";":"",o=o?"bottom: "+o+";":"",s=s?"right: "+s+";":"",u=u?"left: "+u+";":"";var a=document.createElement("div"),f=document.createElement("div");a.style.cssText="margin: 0; padding: 0; position: fixed; top:0; bottom:0; left:0; right:0;z-index: 9990; background-color: rgba(0, 0, 0, 0.3);",a.addEventListener("click",function(){document.removeEventListener("keydown",l),a.parentNode.removeChild(a),t.focus(),a=null}),document.addEventListener("keydown",l),f.style.cssText=i+s+o+u,f.addEventListener("click",function(e){e.stopPropagation()});var c=r.createElement("div");c.style.position="relative";var h=r.createElement("div");h.className="ace_closeButton",h.addEventListener("click",function(){a.click()}),c.appendChild(h),f.appendChild(c),f.appendChild(n),a.appendChild(f),document.body.appendChild(a),t.blur()}}),ace.define("ace/ext/menu_tools/get_editor_keyboard_shortcuts",["require","exports","module","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../../lib/keys");n.exports.getEditorKeybordShortcuts=function(e){var t=r.KEY_MODS,n=[],i={};return e.keyBinding.$handlers.forEach(function(e){var r=e.commandKeyBinding;for(var s in r){var o=parseInt(s);o==-1?o="":isNaN(o)?o=s:o=""+(o&t.command?"Cmd-":"")+(o&t.ctrl?"Ctrl-":"")+(o&t.alt?"Alt-":"")+(o&t.shift?"Shift-":"");for(var u in r[s]){var a=r[s][u];typeof a!="string"&&(a=a.name),i[a]?i[a].key+="|"+o+u:(i[a]={key:o+u,command:a},n.push(i[a]))}}}),n}}),ace.define("ace/ext/keybinding_menu",["require","exports","module","ace/editor","ace/ext/menu_tools/overlay_page","ace/ext/menu_tools/get_editor_keyboard_shortcuts"],function(e,t,n){"use strict";function i(t){if(!document.getElementById("kbshortcutmenu")){var n=e("./menu_tools/overlay_page").overlayPage,r=e("./menu_tools/get_editor_keyboard_shortcuts").getEditorKeybordShortcuts,i=r(t),s=document.createElement("div"),o=i.reduce(function(e,t){return e+'<div class="ace_optionsMenuEntry"><span class="ace_optionsMenuCommand">'+t.command+"</span> : "+'<span class="ace_optionsMenuKey">'+t.key+"</span></div>"},"");s.id="kbshortcutmenu",s.innerHTML="<h1>Keyboard Shortcuts</h1>"+o+"</div>",n(t,s,"0","0","0",null)}}var r=e("ace/editor").Editor;n.exports.init=function(e){r.prototype.showKeyboardShortcuts=function(){i(this)},e.commands.addCommands([{name:"showKeyboardShortcuts",bindKey:{win:"Ctrl-Alt-h",mac:"Command-Alt-h"},exec:function(e,t){e.showKeyboardShortcuts()}}])}});
            +                (function() {
            +                    ace.require(["ace/ext/keybinding_menu"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-language_tools.js b/dist/assets/js/vendor/ace-nc/ext-language_tools.js
            new file mode 100644
            index 0000000000..2a672e88e0
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-language_tools.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/anchor","ace/keyboard/hash_handler","ace/tokenizer","ace/lib/dom","ace/editor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./lib/lang"),o=e("./range").Range,u=e("./anchor").Anchor,a=e("./keyboard/hash_handler").HashHandler,f=e("./tokenizer").Tokenizer,l=o.comparePoints,c=function(){this.snippetMap={},this.snippetNameMap={}};(function(){r.implement(this,i),this.getTokenizer=function(){function e(e,t,n){return e=e.substr(1),/^\d+$/.test(e)&&!n.inFormatString?[{tabstopId:parseInt(e,10)}]:[{text:e}]}function t(e){return"(?:[^\\\\"+e+"]|\\\\.)"}return c.$tokenizer=new f({start:[{regex:/:/,onMatch:function(e,t,n){return n.length&&n[0].expectIf?(n[0].expectIf=!1,n[0].elseBranch=n[0],[n[0]]):":"}},{regex:/\\./,onMatch:function(e,t,n){var r=e[1];return r=="}"&&n.length?e=r:"`$\\".indexOf(r)!=-1?e=r:n.inFormatString&&(r=="n"?e="\n":r=="t"?e="\n":"ulULE".indexOf(r)!=-1&&(e={changeCase:r,local:r>"a"})),[e]}},{regex:/}/,onMatch:function(e,t,n){return[n.length?n.shift():e]}},{regex:/\$(?:\d+|\w+)/,onMatch:e},{regex:/\$\{[\dA-Z_a-z]+/,onMatch:function(t,n,r){var i=e(t.substr(1),n,r);return r.unshift(i[0]),i},next:"snippetVar"},{regex:/\n/,token:"newline",merge:!1}],snippetVar:[{regex:"\\|"+t("\\|")+"*\\|",onMatch:function(e,t,n){n[0].choices=e.slice(1,-1).split(",")},next:"start"},{regex:"/("+t("/")+"+)/(?:("+t("/")+"*)/)(\\w*):?",onMatch:function(e,t,n){var r=n[0];return r.fmtString=e,e=this.splitRegex.exec(e),r.guard=e[1],r.fmt=e[2],r.flag=e[3],""},next:"start"},{regex:"`"+t("`")+"*`",onMatch:function(e,t,n){return n[0].code=e.splice(1,-1),""},next:"start"},{regex:"\\?",onMatch:function(e,t,n){n[0]&&(n[0].expectIf=!0)},next:"start"},{regex:"([^:}\\\\]|\\\\.)*:?",token:"",next:"start"}],formatString:[{regex:"/("+t("/")+"+)/",token:"regex"},{regex:"",onMatch:function(e,t,n){n.inFormatString=!0},next:"start"}]}),c.prototype.getTokenizer=function(){return c.$tokenizer},c.$tokenizer},this.tokenizeTmSnippet=function(e,t){return this.getTokenizer().getLineTokens(e,t).tokens.map(function(e){return e.value||e})},this.$getDefaultValue=function(e,t){if(/^[A-Z]\d+$/.test(t)){var n=t.substr(1);return(this.variables[t[0]+"__"]||{})[n]}if(/^\d+$/.test(t))return(this.variables.__||{})[t];t=t.replace(/^TM_/,"");if(!e)return;var r=e.session;switch(t){case"CURRENT_WORD":var i=r.getWordRange();case"SELECTION":case"SELECTED_TEXT":return r.getTextRange(i);case"CURRENT_LINE":return r.getLine(e.getCursorPosition().row);case"PREV_LINE":return r.getLine(e.getCursorPosition().row-1);case"LINE_INDEX":return e.getCursorPosition().column;case"LINE_NUMBER":return e.getCursorPosition().row+1;case"SOFT_TABS":return r.getUseSoftTabs()?"YES":"NO";case"TAB_SIZE":return r.getTabSize();case"FILENAME":case"FILEPATH":return"";case"FULLNAME":return"Ace"}},this.variables={},this.getVariableValue=function(e,t){return this.variables.hasOwnProperty(t)?this.variables[t](e,t)||"":this.$getDefaultValue(e,t)||""},this.tmStrFormat=function(e,t,n){var r=t.flag||"",i=t.guard;i=new RegExp(i,r.replace(/[^gi]/,""));var s=this.tokenizeTmSnippet(t.fmt,"formatString"),o=this,u=e.replace(i,function(){o.variables.__=arguments;var e=o.resolveVariables(s,n),t="E";for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="object"){e[r]="";if(i.changeCase&&i.local){var u=e[r+1];u&&typeof u=="string"&&(i.changeCase=="u"?e[r]=u[0].toUpperCase():e[r]=u[0].toLowerCase(),e[r+1]=u.substr(1))}else i.changeCase&&(t=i.changeCase)}else t=="U"?e[r]=i.toUpperCase():t=="L"&&(e[r]=i.toLowerCase())}return e.join("")});return this.variables.__=null,u},this.resolveVariables=function(e,t){function o(t){var n=e.indexOf(t,r+1);n!=-1&&(r=n)}var n=[];for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="string")n.push(i);else{if(typeof i!="object")continue;if(i.skip)o(i);else{if(i.processed<r)continue;if(i.text){var s=this.getVariableValue(t,i.text);s&&i.fmtString&&(s=this.tmStrFormat(s,i)),i.processed=r,i.expectIf==null?s&&(n.push(s),o(i)):s?i.skip=i.elseBranch:o(i)}else i.tabstopId!=null?n.push(i):i.changeCase!=null&&n.push(i)}}}return n},this.insertSnippetForSelection=function(e,t){function f(e){var t=[];for(var n=0;n<e.length;n++){var r=e[n];if(typeof r=="object"){if(a[r.tabstopId])continue;var i=e.lastIndexOf(r,n-1);r=t[i]||{tabstopId:r.tabstopId}}t[n]=r}return t}var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=e.session.getTabString(),s=r.match(/^\s*/)[0];n.column<s.length&&(s=s.slice(0,n.column));var o=this.tokenizeTmSnippet(t);o=this.resolveVariables(o,e),o=o.map(function(e){return e=="\n"?e+s:typeof e=="string"?e.replace(/\t/g,i):e});var u=[];o.forEach(function(e,t){if(typeof e!="object")return;var n=e.tabstopId,r=u[n];r||(r=u[n]=[],r.index=n,r.value="");if(r.indexOf(e)!==-1)return;r.push(e);var i=o.indexOf(e,t+1);if(i===-1)return;var s=o.slice(t+1,i),a=s.some(function(e){return typeof e=="object"});a&&!r.value?r.value=s:s.length&&(!r.value||typeof r.value!="string")&&(r.value=s.join(""))}),u.forEach(function(e){e.length=0});var a={};for(var l=0;l<o.length;l++){var c=o[l];if(typeof c!="object")continue;var p=c.tabstopId,d=o.indexOf(c,l+1);if(a[p]){a[p]===c&&(a[p]=null);continue}var v=u[p],m=typeof v.value=="string"?[v.value]:f(v.value);m.unshift(l+1,Math.max(0,d-l)),m.push(c),a[p]=c,o.splice.apply(o,m),v.indexOf(c)===-1&&v.push(c)}var g=0,y=0,b="";o.forEach(function(e){typeof e=="string"?(e[0]==="\n"?(y=e.length-1,g++):y+=e.length,b+=e):e.start?e.end={row:g,column:y}:e.start={row:g,column:y}});var w=e.getSelectionRange(),E=e.session.replace(w,b),S=new h(e),x=e.inVirtualSelectionMode&&e.selection.index;S.addTabstops(u,w.start,E,x)},this.insertSnippet=function(e,t){var n=this;if(e.inVirtualSelectionMode)return n.insertSnippetForSelection(e,t);e.forEachSelection(function(){n.insertSnippetForSelection(e,t)},null,{keepOrder:!0}),e.tabstopManager&&e.tabstopManager.tabNext()},this.$getScope=function(e){var t=e.session.$mode.$id||"";t=t.split("/").pop();if(t==="html"||t==="php"){t==="php"&&!e.session.$mode.inlinePhp&&(t="html");var n=e.getCursorPosition(),r=e.session.getState(n.row);typeof r=="object"&&(r=r[0]),r.substring&&(r.substring(0,3)=="js-"?t="javascript":r.substring(0,4)=="css-"?t="css":r.substring(0,4)=="php-"&&(t="php"))}return t},this.getActiveScopes=function(e){var t=this.$getScope(e),n=[t],r=this.snippetMap;return r[t]&&r[t].includeScopes&&n.push.apply(n,r[t].includeScopes),n.push("_"),n},this.expandWithTab=function(e,t){var n=this,r=e.forEachSelection(function(){return n.expandSnippetForSelection(e,t)},null,{keepOrder:!0});return r&&e.tabstopManager&&e.tabstopManager.tabNext(),r},this.expandSnippetForSelection=function(e,t){var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=r.substring(0,n.column),s=r.substr(n.column),o=this.snippetMap,u;return this.getActiveScopes(e).some(function(e){var t=o[e];return t&&(u=this.findMatchingSnippet(t,i,s)),!!u},this),u?t&&t.dryRun?!0:(e.session.doc.removeInLine(n.row,n.column-u.replaceBefore.length,n.column+u.replaceAfter.length),this.variables.M__=u.matchBefore,this.variables.T__=u.matchAfter,this.insertSnippetForSelection(e,u.content),this.variables.M__=this.variables.T__=null,!0):!1},this.findMatchingSnippet=function(e,t,n){for(var r=e.length;r--;){var i=e[r];if(i.startRe&&!i.startRe.test(t))continue;if(i.endRe&&!i.endRe.test(n))continue;if(!i.startRe&&!i.endRe)continue;return i.matchBefore=i.startRe?i.startRe.exec(t):[""],i.matchAfter=i.endRe?i.endRe.exec(n):[""],i.replaceBefore=i.triggerRe?i.triggerRe.exec(t)[0]:"",i.replaceAfter=i.endTriggerRe?i.endTriggerRe.exec(n)[0]:"",i}},this.snippetMap={},this.snippetNameMap={},this.register=function(e,t){function o(e){return e&&!/^\^?\(.*\)\$?$|^\\b$/.test(e)&&(e="(?:"+e+")"),e||""}function u(e,t,n){return e=o(e),t=o(t),n?(e=t+e,e&&e[e.length-1]!="$"&&(e+="$")):(e+=t,e&&e[0]!="^"&&(e="^"+e)),new RegExp(e)}function a(e){e.scope||(e.scope=t||"_"),t=e.scope,n[t]||(n[t]=[],r[t]={});var o=r[t];if(e.name){var a=o[e.name];a&&i.unregister(a),o[e.name]=e}n[t].push(e),e.tabTrigger&&!e.trigger&&(!e.guard&&/^\w/.test(e.tabTrigger)&&(e.guard="\\b"),e.trigger=s.escapeRegExp(e.tabTrigger)),e.startRe=u(e.trigger,e.guard,!0),e.triggerRe=new RegExp(e.trigger,"",!0),e.endRe=u(e.endTrigger,e.endGuard,!0),e.endTriggerRe=new RegExp(e.endTrigger,"",!0)}var n=this.snippetMap,r=this.snippetNameMap,i=this;e.content?a(e):Array.isArray(e)&&e.forEach(a),this._signal("registerSnippets",{scope:t})},this.unregister=function(e,t){function i(e){var i=r[e.scope||t];if(i&&i[e.name]){delete i[e.name];var s=n[e.scope||t],o=s&&s.indexOf(e);o>=0&&s.splice(o,1)}}var n=this.snippetMap,r=this.snippetNameMap;e.content?i(e):Array.isArray(e)&&e.forEach(i)},this.parseSnippetFile=function(e){e=e.replace(/\r/g,"");var t=[],n={},r=/^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm,i;while(i=r.exec(e)){if(i[1])try{n=JSON.parse(i[1]),t.push(n)}catch(s){}if(i[4])n.content=i[4].replace(/^\t/gm,""),t.push(n),n={};else{var o=i[2],u=i[3];if(o=="regex"){var a=/\/((?:[^\/\\]|\\.)*)|$/g;n.guard=a.exec(u)[1],n.trigger=a.exec(u)[1],n.endTrigger=a.exec(u)[1],n.endGuard=a.exec(u)[1]}else o=="snippet"?(n.tabTrigger=u.match(/^\S*/)[0],n.name||(n.name=u)):n[o]=u}}return t},this.getSnippetByName=function(e,t){var n=this.snippetNameMap,r;return this.getActiveScopes(t).some(function(t){var i=n[t];return i&&(r=i[e]),!!r},this),r}}).call(c.prototype);var h=function(e){if(e.tabstopManager)return e.tabstopManager;e.tabstopManager=this,this.$onChange=this.onChange.bind(this),this.$onChangeSelection=s.delayedCall(this.onChangeSelection.bind(this)).schedule,this.$onChangeSession=this.onChangeSession.bind(this),this.$onAfterExec=this.onAfterExec.bind(this),this.attach(e)};(function(){this.attach=function(e){this.index=0,this.ranges=[],this.tabstops=[],this.$openTabstops=null,this.selectedTabstop=null,this.editor=e,this.editor.on("change",this.$onChange),this.editor.on("changeSelection",this.$onChangeSelection),this.editor.on("changeSession",this.$onChangeSession),this.editor.commands.on("afterExec",this.$onAfterExec),this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.detach=function(){this.tabstops.forEach(this.removeTabstopMarkers,this),this.ranges=null,this.tabstops=null,this.selectedTabstop=null,this.editor.removeListener("change",this.$onChange),this.editor.removeListener("changeSelection",this.$onChangeSelection),this.editor.removeListener("changeSession",this.$onChangeSession),this.editor.commands.removeListener("afterExec",this.$onAfterExec),this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.tabstopManager=null,this.editor=null},this.onChange=function(e){var t=e.data.range,n=e.data.action[0]=="r",r=t.start,i=t.end,s=r.row,o=i.row,u=o-s,a=i.column-r.column;n&&(u=-u,a=-a);if(!this.$inChange&&n){var f=this.selectedTabstop,c=f&&!f.some(function(e){return l(e.start,r)<=0&&l(e.end,i)>=0});if(c)return this.detach()}var h=this.ranges;for(var p=0;p<h.length;p++){var d=h[p];if(d.end.row<r.row)continue;if(n&&l(r,d.start)<0&&l(i,d.end)>0){this.removeRange(d),p--;continue}d.start.row==s&&d.start.column>r.column&&(d.start.column+=a),d.end.row==s&&d.end.column>=r.column&&(d.end.column+=a),d.start.row>=s&&(d.start.row+=u),d.end.row>=s&&(d.end.row+=u),l(d.start,d.end)>0&&this.removeRange(d)}h.length||this.detach()},this.updateLinkedFields=function(){var e=this.selectedTabstop;if(!e||!e.hasLinkedRanges)return;this.$inChange=!0;var n=this.editor.session,r=n.getTextRange(e.firstNonLinked);for(var i=e.length;i--;){var s=e[i];if(!s.linked)continue;var o=t.snippetManager.tmStrFormat(r,s.original);n.replace(s,o)}this.$inChange=!1},this.onAfterExec=function(e){e.command&&!e.command.readOnly&&this.updateLinkedFields()},this.onChangeSelection=function(){if(!this.editor)return;var e=this.editor.selection.lead,t=this.editor.selection.anchor,n=this.editor.selection.isEmpty();for(var r=this.ranges.length;r--;){if(this.ranges[r].linked)continue;var i=this.ranges[r].contains(e.row,e.column),s=n||this.ranges[r].contains(t.row,t.column);if(i&&s)return}this.detach()},this.onChangeSession=function(){this.detach()},this.tabNext=function(e){var t=this.tabstops.length,n=this.index+(e||1);n=Math.min(Math.max(n,1),t),n==t&&(n=0),this.selectTabstop(n),n===0&&this.detach()},this.selectTabstop=function(e){this.$openTabstops=null;var t=this.tabstops[this.index];t&&this.addTabstopMarkers(t),this.index=e,t=this.tabstops[this.index];if(!t||!t.length)return;this.selectedTabstop=t;if(!this.editor.inVirtualSelectionMode){var n=this.editor.multiSelect;n.toSingleRange(t.firstNonLinked.clone());for(var r=t.length;r--;){if(t.hasLinkedRanges&&t[r].linked)continue;n.addRange(t[r].clone(),!0)}n.ranges[0]&&n.addRange(n.ranges[0].clone())}else this.editor.selection.setRange(t.firstNonLinked);this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.addTabstops=function(e,t,n){this.$openTabstops||(this.$openTabstops=[]);if(!e[0]){var r=o.fromPoints(n,n);v(r.start,t),v(r.end,t),e[0]=[r],e[0].index=0}var i=this.index,s=[i+1,0],u=this.ranges;e.forEach(function(e,n){var r=this.$openTabstops[n]||e;for(var i=e.length;i--;){var a=e[i],f=o.fromPoints(a.start,a.end||a.start);d(f.start,t),d(f.end,t),f.original=a,f.tabstop=r,u.push(f),r!=e?r.unshift(f):r[i]=f,a.fmtString?(f.linked=!0,r.hasLinkedRanges=!0):r.firstNonLinked||(r.firstNonLinked=f)}r.firstNonLinked||(r.hasLinkedRanges=!1),r===e&&(s.push(r),this.$openTabstops[n]=r),this.addTabstopMarkers(r)},this),s.length>2&&(this.tabstops.length&&s.push(s.splice(2,1)[0]),this.tabstops.splice.apply(this.tabstops,s))},this.addTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){e.markerId||(e.markerId=t.addMarker(e,"ace_snippet-marker","text"))})},this.removeTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){t.removeMarker(e.markerId),e.markerId=null})},this.removeRange=function(e){var t=e.tabstop.indexOf(e);e.tabstop.splice(t,1),t=this.ranges.indexOf(e),this.ranges.splice(t,1),this.editor.session.removeMarker(e.markerId),e.tabstop.length||(t=this.tabstops.indexOf(e.tabstop),t!=-1&&this.tabstops.splice(t,1),this.tabstops.length||this.detach())},this.keyboardHandler=new a,this.keyboardHandler.bindKeys({Tab:function(e){if(t.snippetManager&&t.snippetManager.expandWithTab(e))return;e.tabstopManager.tabNext(1)},"Shift-Tab":function(e){e.tabstopManager.tabNext(-1)},Esc:function(e){e.tabstopManager.detach()},Return:function(e){return!1}})}).call(h.prototype);var p={};p.onChange=u.prototype.onChange,p.setPosition=function(e,t){this.pos.row=e,this.pos.column=t},p.update=function(e,t,n){this.$insertRight=n,this.pos=e,this.onChange(t)};var d=function(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row},v=function(e,t){e.row==t.row&&(e.column-=t.column),e.row-=t.row};e("./lib/dom").importCssString(".ace_snippet-marker {    -moz-box-sizing: border-box;    box-sizing: border-box;    background: rgba(194, 193, 208, 0.09);    border: 1px dotted rgba(211, 208, 235, 0.62);    position: absolute;}"),t.snippetManager=new c;var m=e("./editor").Editor;(function(){this.insertSnippet=function(e,n){return t.snippetManager.insertSnippet(this,e,n)},this.expandSnippet=function(e){return t.snippetManager.expandWithTab(this,e)}}).call(m.prototype)}),ace.define("ace/autocomplete/popup",["require","exports","module","ace/edit_session","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../edit_session").EditSession,i=e("../virtual_renderer").VirtualRenderer,s=e("../editor").Editor,o=e("../range").Range,u=e("../lib/event"),a=e("../lib/lang"),f=e("../lib/dom"),l=function(e){var t=new i(e);t.$maxLines=4;var n=new s(t);return n.setHighlightActiveLine(!1),n.setShowPrintMargin(!1),n.renderer.setShowGutter(!1),n.renderer.setHighlightGutterLine(!1),n.$mouseHandler.$focusWaitTimout=0,n},c=function(e){var t=f.createElement("div"),n=new l(t);e&&e.appendChild(t),t.style.display="none",n.renderer.content.style.cursor="default",n.renderer.setStyle("ace_autocomplete"),n.setOption("displayIndentGuides",!1),n.setOption("dragDelay",150);var r=function(){};n.focus=r,n.$isFocused=!0,n.renderer.$cursorLayer.restartTimer=r,n.renderer.$cursorLayer.element.style.opacity=0,n.renderer.$maxLines=8,n.renderer.$keepTextAreaAtCursor=!1,n.setHighlightActiveLine(!1),n.session.highlight(""),n.session.$searchHighlight.clazz="ace_highlight-marker",n.on("mousedown",function(e){var t=e.getDocumentPosition();n.selection.moveToPosition(t),c.start.row=c.end.row=t.row,e.stop()});var i,s=new o(-1,0,-1,Infinity),c=new o(-1,0,-1,Infinity);c.id=n.session.addMarker(c,"ace_active-line","fullLine"),n.setSelectOnHover=function(e){e?s.id&&(n.session.removeMarker(s.id),s.id=null):s.id=n.session.addMarker(s,"ace_line-hover","fullLine")},n.setSelectOnHover(!1),n.on("mousemove",function(e){if(!i){i=e;return}if(i.x==e.x&&i.y==e.y)return;i=e,i.scrollTop=n.renderer.scrollTop;var t=i.getDocumentPosition().row;s.start.row!=t&&(s.id||n.setRow(t),p(t))}),n.renderer.on("beforeRender",function(){if(i&&s.start.row!=-1){i.$pos=null;var e=i.getDocumentPosition().row;s.id||n.setRow(e),p(e,!0)}}),n.renderer.on("afterRender",function(){var e=n.getRow(),t=n.renderer.$textLayer,r=t.element.childNodes[e-t.config.firstRow];if(r==t.selectedNode)return;t.selectedNode&&f.removeCssClass(t.selectedNode,"ace_selected"),t.selectedNode=r,r&&f.addCssClass(r,"ace_selected")});var h=function(){p(-1)},p=function(e,t){e!==s.start.row&&(s.start.row=s.end.row=e,t||n.session._emit("changeBackMarker"),n._emit("changeHoverMarker"))};n.getHoveredRow=function(){return s.start.row},u.addListener(n.container,"mouseout",h),n.on("hide",h),n.on("changeSelection",h),n.session.doc.getLength=function(){return n.data.length},n.session.doc.getLine=function(e){var t=n.data[e];return typeof t=="string"?t:t&&t.value||""};var d=n.session.bgTokenizer;return d.$tokenizeRow=function(e){var t=n.data[e],r=[];if(!t)return r;typeof t=="string"&&(t={value:t}),t.caption||(t.caption=t.value||t.name);var i=-1,s,o;for(var e=0;e<t.caption.length;e++)o=t.caption[e],s=t.matchMask&1<<e?1:0,i!==s?(r.push({type:t.className||""+(s?"completion-highlight":""),value:o}),i=s):r[r.length-1].value+=o;if(t.meta){var u=n.renderer.$size.scrollerWidth/n.renderer.layerConfig.characterWidth;t.meta.length+t.caption.length<u-2&&r.push({type:"rightAlignedText",value:t.meta})}return r},d.$updateOnChange=r,d.start=r,n.session.$computeWidth=function(){return this.screenWidth=0},n.isOpen=!1,n.isTopdown=!1,n.data=[],n.setData=function(e){n.data=e||[],n.setValue(a.stringRepeat("\n",e.length),-1),n.setRow(0)},n.getData=function(e){return n.data[e]},n.getRow=function(){return c.start.row},n.setRow=function(e){e=Math.max(-1,Math.min(this.data.length,e)),c.start.row!=e&&(n.selection.clearSelection(),c.start.row=c.end.row=e||0,n.session._emit("changeBackMarker"),n.moveCursorTo(e||0,0),n.isOpen&&n._signal("select"))},n.on("changeSelection",function(){n.isOpen&&n.setRow(n.selection.lead.row)}),n.hide=function(){this.container.style.display="none",this._signal("hide"),n.isOpen=!1},n.show=function(e,t,r){var s=this.container,o=window.innerHeight,u=window.innerWidth,a=this.renderer,f=a.$maxLines*t*1.4,l=e.top+this.$borderSize;l+f>o-t&&!r?(s.style.top="",s.style.bottom=o-l+"px",n.isTopdown=!1):(l+=t,s.style.top=l+"px",s.style.bottom="",n.isTopdown=!0),s.style.display="",this.renderer.$textLayer.checkForSizeChanges();var c=e.left;c+s.offsetWidth>u&&(c=u-s.offsetWidth),s.style.left=c+"px",this._signal("show"),i=null,n.isOpen=!0},n.getTextLeftOffset=function(){return this.$borderSize+this.renderer.$padding+this.$imageSize},n.$imageSize=0,n.$borderSize=1,n};f.importCssString(".ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {    background-color: #CAD6FA;    z-index: 1;}.ace_editor.ace_autocomplete .ace_line-hover {    border: 1px solid #abbffe;    margin-top: -1px;    background: rgba(233,233,253,0.4);}.ace_editor.ace_autocomplete .ace_line-hover {    position: absolute;    z-index: 2;}.ace_editor.ace_autocomplete .ace_scroller {   background: none;   border: none;   box-shadow: none;}.ace_rightAlignedText {    color: gray;    display: inline-block;    position: absolute;    right: 4px;    text-align: right;    z-index: -1;}.ace_editor.ace_autocomplete .ace_completion-highlight{    color: #000;    text-shadow: 0 0 0.01em;}.ace_editor.ace_autocomplete {    width: 280px;    z-index: 200000;    background: #fbfbfb;    color: #444;    border: 1px lightgray solid;    position: fixed;    box-shadow: 2px 3px 5px rgba(0,0,0,.2);    line-height: 1.4;}"),t.AcePopup=c}),ace.define("ace/autocomplete/util",["require","exports","module"],function(e,t,n){"use strict";t.parForEach=function(e,t,n){var r=0,i=e.length;i===0&&n();for(var s=0;s<i;s++)t(e[s],function(e,t){r++,r===i&&n(e,t)})};var r=/[a-zA-Z_0-9\$\-\u00A2-\uFFFF]/;t.retrievePrecedingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t-1;s>=0;s--){if(!n.test(e[s]))break;i.push(e[s])}return i.reverse().join("")},t.retrieveFollowingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t;s<e.length;s++){if(!n.test(e[s]))break;i.push(e[s])}return i}}),ace.define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/event","ace/lib/lang","ace/snippets"],function(e,t,n){"use strict";var r=e("./keyboard/hash_handler").HashHandler,i=e("./autocomplete/popup").AcePopup,s=e("./autocomplete/util"),o=e("./lib/event"),u=e("./lib/lang"),a=e("./snippets").snippetManager,f=function(){this.autoInsert=!0,this.autoSelect=!0,this.keyboardHandler=new r,this.keyboardHandler.bindKeys(this.commands),this.blurListener=this.blurListener.bind(this),this.changeListener=this.changeListener.bind(this),this.mousedownListener=this.mousedownListener.bind(this),this.mousewheelListener=this.mousewheelListener.bind(this),this.changeTimer=u.delayedCall(function(){this.updateCompletions(!0)}.bind(this))};(function(){this.gatherCompletionsId=0,this.$init=function(){this.popup=new i(document.body||document.documentElement),this.popup.on("click",function(e){this.insertMatch(),e.stop()}.bind(this)),this.popup.focus=this.editor.focus.bind(this.editor)},this.openPopup=function(e,t,n){this.popup||this.$init(),this.popup.setData(this.completions.filtered);var r=e.renderer;this.popup.setRow(this.autoSelect?0:-1);if(!n){this.popup.setTheme(e.getTheme()),this.popup.setFontSize(e.getFontSize());var i=r.layerConfig.lineHeight,s=r.$cursorLayer.getPixelPosition(this.base,!0);s.left-=this.popup.getTextLeftOffset();var o=e.container.getBoundingClientRect();s.top+=o.top-r.layerConfig.offset,s.left+=o.left-e.renderer.scrollLeft,s.left+=r.$gutterLayer.gutterWidth,this.popup.show(s,i)}},this.detach=function(){this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.off("changeSelection",this.changeListener),this.editor.off("blur",this.blurListener),this.editor.off("mousedown",this.mousedownListener),this.editor.off("mousewheel",this.mousewheelListener),this.changeTimer.cancel(),this.popup&&this.popup.isOpen&&(this.gatherCompletionsId+=1,this.popup.hide()),this.base&&this.base.detach(),this.activated=!1,this.completions=this.base=null},this.changeListener=function(e){var t=this.editor.selection.lead;(t.row!=this.base.row||t.column<this.base.column)&&this.detach(),this.activated?this.changeTimer.schedule():this.detach()},this.blurListener=function(){var e=document.activeElement;e!=this.editor.textInput.getElement()&&e.parentNode!=this.popup.container&&this.detach()},this.mousedownListener=function(e){this.detach()},this.mousewheelListener=function(e){this.detach()},this.goTo=function(e){var t=this.popup.getRow(),n=this.popup.session.getLength()-1;switch(e){case"up":t=t<=0?n:t-1;break;case"down":t=t>=n?-1:t+1;break;case"start":t=0;break;case"end":t=n}this.popup.setRow(t)},this.insertMatch=function(e){e||(e=this.popup.getData(this.popup.getRow()));if(!e)return!1;if(e.completer&&e.completer.insertMatch)e.completer.insertMatch(this.editor);else{if(this.completions.filterText){var t=this.editor.selection.getAllRanges();for(var n=0,r;r=t[n];n++)r.start.column-=this.completions.filterText.length,this.editor.session.remove(r)}e.snippet?a.insertSnippet(this.editor,e.snippet):this.editor.execCommand("insertstring",e.value||e)}this.detach()},this.commands={Up:function(e){e.completer.goTo("up")},Down:function(e){e.completer.goTo("down")},"Ctrl-Up|Ctrl-Home":function(e){e.completer.goTo("start")},"Ctrl-Down|Ctrl-End":function(e){e.completer.goTo("end")},Esc:function(e){e.completer.detach()},Space:function(e){e.completer.detach(),e.insert(" ")},Return:function(e){return e.completer.insertMatch()},"Shift-Return":function(e){e.completer.insertMatch(!0)},Tab:function(e){var t=e.completer.insertMatch();if(!!t||!!e.tabstopManager)return t;e.completer.goTo("down")},PageUp:function(e){e.completer.popup.gotoPageUp()},PageDown:function(e){e.completer.popup.gotoPageDown()}},this.gatherCompletions=function(e,t){var n=e.getSession(),r=e.getCursorPosition(),i=n.getLine(r.row),o=s.retrievePrecedingIdentifier(i,r.column);this.base=n.doc.createAnchor(r.row,r.column-o.length);var u=[],a=e.completers.length;return e.completers.forEach(function(i,f){i.getCompletions(e,n,r,o,function(r,i){r||(u=u.concat(i));var o=e.getCursorPosition(),f=n.getLine(o.row);t(null,{prefix:s.retrievePrecedingIdentifier(f,o.column,i[0]&&i[0].identifierRegex),matches:u,finished:--a===0})})}),!0},this.showPopup=function(e){this.editor&&this.detach(),this.activated=!0,this.editor=e,e.completer!=this&&(e.completer&&e.completer.detach(),e.completer=this),e.keyBinding.addKeyboardHandler(this.keyboardHandler),e.on("changeSelection",this.changeListener),e.on("blur",this.blurListener),e.on("mousedown",this.mousedownListener),e.on("mousewheel",this.mousewheelListener),this.updateCompletions()},this.updateCompletions=function(e){if(e&&this.base&&this.completions){var t=this.editor.getCursorPosition(),n=this.editor.session.getTextRange({start:this.base,end:t});if(n==this.completions.filterText)return;this.completions.setFilter(n);if(!this.completions.filtered.length)return this.detach();if(this.completions.filtered.length==1&&this.completions.filtered[0].value==n&&!this.completions.filtered[0].snippet)return this.detach();this.openPopup(this.editor,n,e);return}var r=this.gatherCompletionsId;this.gatherCompletions(this.editor,function(t,n){var i=function(){if(!n.finished)return;return this.detach()}.bind(this),s=n.prefix,o=n&&n.matches;if(!o||!o.length)return i();if(s.indexOf(n.prefix)!==0||r!=this.gatherCompletionsId)return;this.completions=new l(o),this.completions.setFilter(s);var u=this.completions.filtered;if(!u.length)return i();if(u.length==1&&u[0].value==s&&!u[0].snippet)return i();if(this.autoInsert&&u.length==1)return this.insertMatch(u[0]);this.openPopup(this.editor,s,e)}.bind(this))},this.cancelContextMenu=function(){this.editor.$mouseHandler.cancelContextMenu()}}).call(f.prototype),f.startCommand={name:"startAutocomplete",exec:function(e){e.completer||(e.completer=new f),e.completer.autoInsert=e.completer.autoSelect=!0,e.completer.showPopup(e),e.completer.cancelContextMenu()},bindKey:"Ctrl-Space|Ctrl-Shift-Space|Alt-Space"};var l=function(e,t,n){this.all=e,this.filtered=e,this.filterText=t||""};(function(){this.setFilter=function(e){if(e.length>this.filterText&&e.lastIndexOf(this.filterText,0)===0)var t=this.filtered;else var t=this.all;this.filterText=e,t=this.filterCompletions(t,this.filterText),t=t.sort(function(e,t){return t.exactMatch-e.exactMatch||t.score-e.score});var n=null;t=t.filter(function(e){var t=e.value||e.caption||e.snippet;return t===n?!1:(n=t,!0)}),this.filtered=t},this.filterCompletions=function(e,t){var n=[],r=t.toUpperCase(),i=t.toLowerCase();e:for(var s=0,o;o=e[s];s++){var u=o.value||o.caption||o.snippet;if(!u)continue;var a=-1,f=0,l=0,c,h;for(var p=0;p<t.length;p++){var d=u.indexOf(i[p],a+1),v=u.indexOf(r[p],a+1);c=d>=0?v<0||d<v?d:v:v;if(c<0)continue e;h=c-a-1,h>0&&(a===-1&&(l+=10),l+=h),f|=1<<c,a=c}o.matchMask=f,o.exactMatch=l?0:1,o.score=(o.score||0)-l,n.push(o)}return n}}).call(l.prototype),t.Autocomplete=f,t.FilteredList=l}),ace.define("ace/autocomplete/text_completer",["require","exports","module","ace/range"],function(e,t,n){function s(e,t){var n=e.getTextRange(r.fromPoints({row:0,column:0},t));return n.split(i).length-1}function o(e,t){var n=s(e,t),r=e.getValue().split(i),o=Object.create(null),u=r[n];return r.forEach(function(e,t){if(!e||e===u)return;var i=Math.abs(n-t),s=r.length-i;o[e]?o[e]=Math.max(s,o[e]):o[e]=s}),o}var r=e("../range").Range,i=/[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;t.getCompletions=function(e,t,n,r,i){var s=o(t,n,r),u=Object.keys(s);i(null,u.map(function(e){return{caption:e,value:e,score:s[e],meta:"local"}}))}}),ace.define("ace/ext/language_tools",["require","exports","module","ace/snippets","ace/autocomplete","ace/config","ace/autocomplete/util","ace/autocomplete/text_completer","ace/editor","ace/config"],function(e,t,n){"use strict";function v(e){var t=e.getCursorPosition(),n=e.session.getLine(t.row),r=o.retrievePrecedingIdentifier(n,t.column);return e.completers.forEach(function(e){e.identifierRegexps&&e.identifierRegexps.forEach(function(e){!r&&e&&(r=o.retrievePrecedingIdentifier(n,t.column,e))})}),r}var r=e("../snippets").snippetManager,i=e("../autocomplete").Autocomplete,s=e("../config"),o=e("../autocomplete/util"),u=e("../autocomplete/text_completer"),a={getCompletions:function(e,t,n,r,i){var s=e.session.getState(n.row),o=t.$mode.getCompletions(s,t,n,r);i(null,o)}},f={getCompletions:function(e,t,n,i,s){var o=r.snippetMap,u=[];r.getActiveScopes(e).forEach(function(e){var t=o[e]||[];for(var n=t.length;n--;){var r=t[n],i=r.name||r.tabTrigger;if(!i)continue;u.push({caption:i,snippet:r.content,meta:r.tabTrigger&&!r.name?r.tabTrigger+"\u21e5 ":"snippet"})}},this),s(null,u)}},l=[f,u,a];t.addCompleter=function(e){l.push(e)},t.textCompleter=u,t.keyWordCompleter=a,t.snippetCompleter=f;var c={name:"expandSnippet",exec:function(e){var t=r.expandWithTab(e);t||e.execCommand("indent")},bindKey:"Tab"},h=function(e,t){p(t.session.$mode)},p=function(e){var t=e.$id;r.files||(r.files={}),d(t),e.modes&&e.modes.forEach(p)},d=function(e){if(!e||r.files[e])return;var t=e.replace("mode","snippets");r.files[e]={},s.loadModule(t,function(t){t&&(r.files[e]=t,!t.snippets&&t.snippetText&&(t.snippets=r.parseSnippetFile(t.snippetText)),r.register(t.snippets||[],t.scope),t.includeScopes&&(r.snippetMap[t.scope].includeScopes=t.includeScopes,t.includeScopes.forEach(function(e){d("ace/mode/"+e)})))})},m=function(e){var t=e.editor,n=e.args||"",r=t.completer&&t.completer.activated;if(e.command.name==="backspace")r&&!v(t)&&t.completer.detach();else if(e.command.name==="insertstring"){var s=v(t);s&&!r&&(t.completer||(t.completer=new i),t.completer.autoSelect=!1,t.completer.autoInsert=!1,t.completer.showPopup(t))}},g=e("../editor").Editor;e("../config").defineOptions(g.prototype,"editor",{enableBasicAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:l),this.commands.addCommand(i.startCommand)):this.commands.removeCommand(i.startCommand)},value:!1},enableLiveAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:l),this.commands.on("afterExec",m)):this.commands.removeListener("afterExec",m)},value:!1},enableSnippets:{set:function(e){e?(this.commands.addCommand(c),this.on("changeMode",h),h(null,this)):(this.commands.removeCommand(c),this.off("changeMode",h))},value:!1}})});
            +                (function() {
            +                    ace.require(["ace/ext/language_tools"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-linking.js b/dist/assets/js/vendor/ace-nc/ext-linking.js
            new file mode 100644
            index 0000000000..69f87918ff
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-linking.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/linking",["require","exports","module","ace/editor","ace/config"],function(e,t,n){function i(e){var t=e.editor,n=e.getAccelKey();if(n){var t=e.editor,r=e.getDocumentPosition(),i=t.session,s=i.getTokenAt(r.row,r.column);t._emit("linkHover",{position:r,token:s})}}function s(e){var t=e.getAccelKey(),n=e.getButton();if(n==0&&t){var r=e.editor,i=e.getDocumentPosition(),s=r.session,o=s.getTokenAt(i.row,i.column);r._emit("linkClick",{position:i,token:o})}}var r=e("ace/editor").Editor;e("../config").defineOptions(r.prototype,"editor",{enableLinking:{set:function(e){e?(this.on("click",s),this.on("mousemove",i)):(this.off("click",s),this.off("mousemove",i))},value:!1}})});
            +                (function() {
            +                    ace.require(["ace/ext/linking"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-modelist.js b/dist/assets/js/vendor/ace-nc/ext-modelist.js
            new file mode 100644
            index 0000000000..968afa0493
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-modelist.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/modelist",["require","exports","module"],function(e,t,n){"use strict";function i(e){var t=a.text,n=e.split(/[\/\\]/).pop();for(var i=0;i<r.length;i++)if(r[i].supportsFile(n)){t=r[i];break}return t}var r=[],s=function(e,t,n){this.name=e,this.caption=t,this.mode="ace/mode/"+e,this.extensions=n;if(/\^/.test(n))var r=n.replace(/\|(\^)?/g,function(e,t){return"$|"+(t?"^":"^.*\\.")})+"$";else var r="^.*\\.("+n+")$";this.extRe=new RegExp(r,"gi")};s.prototype.supportsFile=function(e){return e.match(this.extRe)};var o={ABAP:["abap"],ActionScript:["as"],ADA:["ada|adb"],Apache_Conf:["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"],AsciiDoc:["asciidoc"],Assembly_x86:["asm"],AutoHotKey:["ahk"],BatchFile:["bat|cmd"],C9Search:["c9search_results"],C_Cpp:["cpp|c|cc|cxx|h|hh|hpp"],Cirru:["cirru|cr"],Clojure:["clj|cljs"],Cobol:["CBL|COB"],coffee:["coffee|cf|cson|^Cakefile"],ColdFusion:["cfm"],CSharp:["cs"],CSS:["css"],Curly:["curly"],D:["d|di"],Dart:["dart"],Diff:["diff|patch"],Dockerfile:["^Dockerfile"],Dot:["dot"],Erlang:["erl|hrl"],EJS:["ejs"],Forth:["frt|fs|ldr"],FTL:["ftl"],Gherkin:["feature"],Gitignore:["^.gitignore"],Glsl:["glsl|frag|vert"],golang:["go"],Groovy:["groovy"],HAML:["haml"],Handlebars:["hbs|handlebars|tpl|mustache"],Haskell:["hs"],haXe:["hx"],HTML:["html|htm|xhtml"],HTML_Ruby:["erb|rhtml|html.erb"],INI:["ini|conf|cfg|prefs"],Jack:["jack"],Jade:["jade"],Java:["java"],JavaScript:["js|jsm"],JSON:["json"],JSONiq:["jq"],JSP:["jsp"],JSX:["jsx"],Julia:["jl"],LaTeX:["tex|latex|ltx|bib"],LESS:["less"],Liquid:["liquid"],Lisp:["lisp"],LiveScript:["ls"],LogiQL:["logic|lql"],LSL:["lsl"],Lua:["lua"],LuaPage:["lp"],Lucene:["lucene"],Makefile:["^Makefile|^GNUmakefile|^makefile|^OCamlMakefile|make"],MATLAB:["matlab"],Markdown:["md|markdown"],MEL:["mel"],MySQL:["mysql"],MUSHCode:["mc|mush"],Nix:["nix"],ObjectiveC:["m|mm"],OCaml:["ml|mli"],Pascal:["pas|p"],Perl:["pl|pm"],pgSQL:["pgsql"],PHP:["php|phtml"],Powershell:["ps1"],Prolog:["plg|prolog"],Properties:["properties"],Protobuf:["proto"],Python:["py"],R:["r"],RDoc:["Rd"],RHTML:["Rhtml"],Ruby:["rb|ru|gemspec|rake|^Guardfile|^Rakefile|^Gemfile"],Rust:["rs"],SASS:["sass"],SCAD:["scad"],Scala:["scala"],Smarty:["smarty|tpl"],Scheme:["scm|rkt"],SCSS:["scss"],SH:["sh|bash|^.bashrc"],SJS:["sjs"],Space:["space"],snippets:["snippets"],Soy_Template:["soy"],SQL:["sql"],Stylus:["styl|stylus"],SVG:["svg"],Tcl:["tcl"],Tex:["tex"],Text:["txt"],Textile:["textile"],Toml:["toml"],Twig:["twig"],Typescript:["ts|typescript|str"],Vala:["vala"],VBScript:["vbs"],Velocity:["vm"],Verilog:["v|vh|sv|svh"],XML:["xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl"],XQuery:["xq"],YAML:["yaml|yml"]},u={ObjectiveC:"Objective-C",CSharp:"C#",golang:"Go",C_Cpp:"C/C++",coffee:"CoffeeScript",HTML_Ruby:"HTML (Ruby)",FTL:"FreeMarker"},a={};for(var f in o){var l=o[f],c=(u[f]||f).replace(/_/g," "),h=f.toLowerCase(),p=new s(h,c,l[0]);a[h]=p,r.push(p)}n.exports={getModeForPath:i,modes:r,modesByName:a}});
            +                (function() {
            +                    ace.require(["ace/ext/modelist"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-old_ie.js b/dist/assets/js/vendor/ace-nc/ext-old_ie.js
            new file mode 100644
            index 0000000000..b285cd7a73
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-old_ie.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/searchbox",["require","exports","module","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/keyboard/hash_handler","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=e("../lib/lang"),s=e("../lib/event"),o=".ace_search {background-color: #ddd;border: 1px solid #cbcbcb;border-top: 0 none;max-width: 297px;overflow: hidden;margin: 0;padding: 4px;padding-right: 6px;padding-bottom: 0;position: absolute;top: 0px;z-index: 99;white-space: normal;}.ace_search.left {border-left: 0 none;border-radius: 0px 0px 5px 0px;left: 0;}.ace_search.right {border-radius: 0px 0px 0px 5px;border-right: 0 none;right: 0;}.ace_search_form, .ace_replace_form {border-radius: 3px;border: 1px solid #cbcbcb;float: left;margin-bottom: 4px;overflow: hidden;}.ace_search_form.ace_nomatch {outline: 1px solid red;}.ace_search_field {background-color: white;border-right: 1px solid #cbcbcb;border: 0 none;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;display: block;float: left;height: 22px;outline: 0;padding: 0 7px;width: 214px;margin: 0;}.ace_searchbtn,.ace_replacebtn {background: #fff;border: 0 none;border-left: 1px solid #dcdcdc;cursor: pointer;display: block;float: left;height: 22px;margin: 0;padding: 0;position: relative;}.ace_searchbtn:last-child,.ace_replacebtn:last-child {border-top-right-radius: 3px;border-bottom-right-radius: 3px;}.ace_searchbtn:disabled {background: none;cursor: default;}.ace_searchbtn {background-position: 50% 50%;background-repeat: no-repeat;width: 27px;}.ace_searchbtn.prev {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiSU1NZUAC/6E0I0yACYskCpsJiySKIiY0SUZk40FyTEgCjGgKwTRAgAEAQJUIPCE+qfkAAAAASUVORK5CYII=);    }.ace_searchbtn.next {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNpiTE1NZQCC/0DMyIAKwGJMUAYDEo3M/s+EpvM/mkKwCQxYjIeLMaELoLMBAgwAU7UJObTKsvAAAAAASUVORK5CYII=);    }.ace_searchbtn_close {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;border-radius: 50%;border: 0 none;color: #656565;cursor: pointer;display: block;float: right;font-family: Arial;font-size: 16px;height: 14px;line-height: 16px;margin: 5px 1px 9px 5px;padding: 0;text-align: center;width: 14px;}.ace_searchbtn_close:hover {background-color: #656565;background-position: 50% 100%;color: white;}.ace_replacebtn.prev {width: 54px}.ace_replacebtn.next {width: 27px}.ace_button {margin-left: 2px;cursor: pointer;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;overflow: hidden;opacity: 0.7;border: 1px solid rgba(100,100,100,0.23);padding: 1px;-moz-box-sizing: border-box;box-sizing:    border-box;color: black;}.ace_button:hover {background-color: #eee;opacity:1;}.ace_button:active {background-color: #ddd;}.ace_button.checked {border-color: #3399ff;opacity:1;}.ace_search_options{margin-bottom: 3px;text-align: right;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;}",u=e("../keyboard/hash_handler").HashHandler,a=e("../lib/keys");r.importCssString(o,"ace_searchbox");var f='<div class="ace_search right">    <button type="button" action="hide" class="ace_searchbtn_close"></button>    <div class="ace_search_form">        <input class="ace_search_field" placeholder="Search for" spellcheck="false"></input>        <button type="button" action="findNext" class="ace_searchbtn next"></button>        <button type="button" action="findPrev" class="ace_searchbtn prev"></button>    </div>    <div class="ace_replace_form">        <input class="ace_search_field" placeholder="Replace with" spellcheck="false"></input>        <button type="button" action="replaceAndFindNext" class="ace_replacebtn">Replace</button>        <button type="button" action="replaceAll" class="ace_replacebtn">All</button>    </div>    <div class="ace_search_options">        <span action="toggleRegexpMode" class="ace_button" title="RegExp Search">.*</span>        <span action="toggleCaseSensitive" class="ace_button" title="CaseSensitive Search">Aa</span>        <span action="toggleWholeWords" class="ace_button" title="Whole Word Search">\\b</span>    </div></div>'.replace(/>\s+/g,">"),l=function(e,t,n){var i=r.createElement("div");i.innerHTML=f,this.element=i.firstChild,this.$init(),this.setEditor(e)};(function(){this.setEditor=function(e){e.searchBox=this,e.container.appendChild(this.element),this.editor=e},this.$initElements=function(e){this.searchBox=e.querySelector(".ace_search_form"),this.replaceBox=e.querySelector(".ace_replace_form"),this.searchOptions=e.querySelector(".ace_search_options"),this.regExpOption=e.querySelector("[action=toggleRegexpMode]"),this.caseSensitiveOption=e.querySelector("[action=toggleCaseSensitive]"),this.wholeWordOption=e.querySelector("[action=toggleWholeWords]"),this.searchInput=this.searchBox.querySelector(".ace_search_field"),this.replaceInput=this.replaceBox.querySelector(".ace_search_field")},this.$init=function(){var e=this.element;this.$initElements(e);var t=this;s.addListener(e,"mousedown",function(e){setTimeout(function(){t.activeInput.focus()},0),s.stopPropagation(e)}),s.addListener(e,"click",function(e){var n=e.target||e.srcElement,r=n.getAttribute("action");r&&t[r]?t[r]():t.$searchBarKb.commands[r]&&t.$searchBarKb.commands[r].exec(t),s.stopPropagation(e)}),s.addCommandKeyListener(e,function(e,n,r){var i=a.keyCodeToString(r),o=t.$searchBarKb.findKeyCommand(n,i);o&&o.exec&&(o.exec(t),s.stopEvent(e))}),this.$onChange=i.delayedCall(function(){t.find(!1,!1)}),s.addListener(this.searchInput,"input",function(){t.$onChange.schedule(20)}),s.addListener(this.searchInput,"focus",function(){t.activeInput=t.searchInput,t.searchInput.value&&t.highlight()}),s.addListener(this.replaceInput,"focus",function(){t.activeInput=t.replaceInput,t.searchInput.value&&t.highlight()})},this.$closeSearchBarKb=new u([{bindKey:"Esc",name:"closeSearchBar",exec:function(e){e.searchBox.hide()}}]),this.$searchBarKb=new u,this.$searchBarKb.bindKeys({"Ctrl-f|Command-f|Ctrl-H|Command-Option-F":function(e){var t=e.isReplace=!e.isReplace;e.replaceBox.style.display=t?"":"none",e[t?"replaceInput":"searchInput"].focus()},"Ctrl-G|Command-G":function(e){e.findNext()},"Ctrl-Shift-G|Command-Shift-G":function(e){e.findPrev()},esc:function(e){setTimeout(function(){e.hide()})},Return:function(e){e.activeInput==e.replaceInput&&e.replace(),e.findNext()},"Shift-Return":function(e){e.activeInput==e.replaceInput&&e.replace(),e.findPrev()},Tab:function(e){(e.activeInput==e.replaceInput?e.searchInput:e.replaceInput).focus()}}),this.$searchBarKb.addCommands([{name:"toggleRegexpMode",bindKey:{win:"Alt-R|Alt-/",mac:"Ctrl-Alt-R|Ctrl-Alt-/"},exec:function(e){e.regExpOption.checked=!e.regExpOption.checked,e.$syncOptions()}},{name:"toggleCaseSensitive",bindKey:{win:"Alt-C|Alt-I",mac:"Ctrl-Alt-R|Ctrl-Alt-I"},exec:function(e){e.caseSensitiveOption.checked=!e.caseSensitiveOption.checked,e.$syncOptions()}},{name:"toggleWholeWords",bindKey:{win:"Alt-B|Alt-W",mac:"Ctrl-Alt-B|Ctrl-Alt-W"},exec:function(e){e.wholeWordOption.checked=!e.wholeWordOption.checked,e.$syncOptions()}}]),this.$syncOptions=function(){r.setCssClass(this.regExpOption,"checked",this.regExpOption.checked),r.setCssClass(this.wholeWordOption,"checked",this.wholeWordOption.checked),r.setCssClass(this.caseSensitiveOption,"checked",this.caseSensitiveOption.checked),this.find(!1,!1)},this.highlight=function(e){this.editor.session.highlight(e||this.editor.$search.$options.re),this.editor.renderer.updateBackMarkers()},this.find=function(e,t){var n=this.editor.find(this.searchInput.value,{skipCurrent:e,backwards:t,wrap:!0,regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked}),i=!n&&this.searchInput.value;r.setCssClass(this.searchBox,"ace_nomatch",i),this.editor._emit("findSearchBox",{match:!i}),this.highlight()},this.findNext=function(){this.find(!0,!1)},this.findPrev=function(){this.find(!0,!0)},this.replace=function(){this.editor.getReadOnly()||this.editor.replace(this.replaceInput.value)},this.replaceAndFindNext=function(){this.editor.getReadOnly()||(this.editor.replace(this.replaceInput.value),this.findNext())},this.replaceAll=function(){this.editor.getReadOnly()||this.editor.replaceAll(this.replaceInput.value)},this.hide=function(){this.element.style.display="none",this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb),this.editor.focus()},this.show=function(e,t){this.element.style.display="",this.replaceBox.style.display=t?"":"none",this.isReplace=t,e&&(this.searchInput.value=e),this.searchInput.focus(),this.searchInput.select(),this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb)}}).call(l.prototype),t.SearchBox=l,t.Search=function(e,t){var n=e.searchBox||new l(e);n.show(e.session.getTextRange(),t)}}),ace.define("ace/ext/old_ie",["require","exports","module","ace/lib/useragent","ace/tokenizer","ace/ext/searchbox","ace/mode/text"],function(require,exports,module){"use strict";function patch(obj,name,regexp,replacement){eval("obj['"+name+"']="+obj[name].toString().replace(regexp,replacement))}var MAX_TOKEN_COUNT=1e3,useragent=require("../lib/useragent"),TokenizerModule=require("../tokenizer");useragent.isIE&&useragent.isIE<10&&window.top.document.compatMode==="BackCompat"&&(useragent.isOldIE=!0);if(typeof document!="undefined"&&!document.documentElement.querySelector){useragent.isOldIE=!0;var qs=function(e,t){if(t.charAt(0)==".")var n=t.slice(1);else var r=t.match(/(\w+)=(\w+)/),i=r&&r[1],s=r&&r[2];for(var o=0;o<e.all.length;o++){var u=e.all[o];if(n){if(u.className.indexOf(n)!=-1)return u}else if(i&&u.getAttribute(i)==s)return u}},sb=require("./searchbox").SearchBox.prototype;patch(sb,"$initElements",/([^\s=]*).querySelector\((".*?")\)/g,"qs($1, $2)")}var compliantExecNpcg=/()??/.exec("")[1]===undefined;if(compliantExecNpcg)return;var proto=TokenizerModule.Tokenizer.prototype;TokenizerModule.Tokenizer_orig=TokenizerModule.Tokenizer,proto.getLineTokens_orig=proto.getLineTokens,patch(TokenizerModule,"Tokenizer","ruleRegExps.push(adjustedregex);\n",function(e){return e+'        if (state[i].next && RegExp(adjustedregex).test(""))\n            rule._qre = RegExp(adjustedregex, "g");\n        '}),TokenizerModule.Tokenizer.prototype=proto,patch(proto,"getLineTokens",/if \(match\[i \+ 1\] === undefined\)\s*continue;/,"if (!match[i + 1]) {\n        if (value)continue;\n        var qre = state[mapping[i]]._qre;\n        if (!qre) continue;\n        qre.lastIndex = lastIndex;\n        if (!qre.exec(line) || qre.lastIndex != lastIndex)\n            continue;\n    }"),patch(require("../mode/text").Mode.prototype,"getTokenizer",/Tokenizer/,"TokenizerModule.Tokenizer"),useragent.isOldIE=!0});
            +                (function() {
            +                    ace.require(["ace/ext/old_ie"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-searchbox.js b/dist/assets/js/vendor/ace-nc/ext-searchbox.js
            new file mode 100644
            index 0000000000..08d7ac1134
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-searchbox.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/searchbox",["require","exports","module","ace/lib/dom","ace/lib/lang","ace/lib/event","ace/keyboard/hash_handler","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../lib/dom"),i=e("../lib/lang"),s=e("../lib/event"),o=".ace_search {background-color: #ddd;border: 1px solid #cbcbcb;border-top: 0 none;max-width: 297px;overflow: hidden;margin: 0;padding: 4px;padding-right: 6px;padding-bottom: 0;position: absolute;top: 0px;z-index: 99;white-space: normal;}.ace_search.left {border-left: 0 none;border-radius: 0px 0px 5px 0px;left: 0;}.ace_search.right {border-radius: 0px 0px 0px 5px;border-right: 0 none;right: 0;}.ace_search_form, .ace_replace_form {border-radius: 3px;border: 1px solid #cbcbcb;float: left;margin-bottom: 4px;overflow: hidden;}.ace_search_form.ace_nomatch {outline: 1px solid red;}.ace_search_field {background-color: white;border-right: 1px solid #cbcbcb;border: 0 none;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;display: block;float: left;height: 22px;outline: 0;padding: 0 7px;width: 214px;margin: 0;}.ace_searchbtn,.ace_replacebtn {background: #fff;border: 0 none;border-left: 1px solid #dcdcdc;cursor: pointer;display: block;float: left;height: 22px;margin: 0;padding: 0;position: relative;}.ace_searchbtn:last-child,.ace_replacebtn:last-child {border-top-right-radius: 3px;border-bottom-right-radius: 3px;}.ace_searchbtn:disabled {background: none;cursor: default;}.ace_searchbtn {background-position: 50% 50%;background-repeat: no-repeat;width: 27px;}.ace_searchbtn.prev {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiSU1NZUAC/6E0I0yACYskCpsJiySKIiY0SUZk40FyTEgCjGgKwTRAgAEAQJUIPCE+qfkAAAAASUVORK5CYII=);    }.ace_searchbtn.next {background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNpiTE1NZQCC/0DMyIAKwGJMUAYDEo3M/s+EpvM/mkKwCQxYjIeLMaELoLMBAgwAU7UJObTKsvAAAAAASUVORK5CYII=);    }.ace_searchbtn_close {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;border-radius: 50%;border: 0 none;color: #656565;cursor: pointer;display: block;float: right;font-family: Arial;font-size: 16px;height: 14px;line-height: 16px;margin: 5px 1px 9px 5px;padding: 0;text-align: center;width: 14px;}.ace_searchbtn_close:hover {background-color: #656565;background-position: 50% 100%;color: white;}.ace_replacebtn.prev {width: 54px}.ace_replacebtn.next {width: 27px}.ace_button {margin-left: 2px;cursor: pointer;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;overflow: hidden;opacity: 0.7;border: 1px solid rgba(100,100,100,0.23);padding: 1px;-moz-box-sizing: border-box;box-sizing:    border-box;color: black;}.ace_button:hover {background-color: #eee;opacity:1;}.ace_button:active {background-color: #ddd;}.ace_button.checked {border-color: #3399ff;opacity:1;}.ace_search_options{margin-bottom: 3px;text-align: right;-webkit-user-select: none;-moz-user-select: none;-o-user-select: none;-ms-user-select: none;user-select: none;}",u=e("../keyboard/hash_handler").HashHandler,a=e("../lib/keys");r.importCssString(o,"ace_searchbox");var f='<div class="ace_search right">    <button type="button" action="hide" class="ace_searchbtn_close"></button>    <div class="ace_search_form">        <input class="ace_search_field" placeholder="Search for" spellcheck="false"></input>        <button type="button" action="findNext" class="ace_searchbtn next"></button>        <button type="button" action="findPrev" class="ace_searchbtn prev"></button>    </div>    <div class="ace_replace_form">        <input class="ace_search_field" placeholder="Replace with" spellcheck="false"></input>        <button type="button" action="replaceAndFindNext" class="ace_replacebtn">Replace</button>        <button type="button" action="replaceAll" class="ace_replacebtn">All</button>    </div>    <div class="ace_search_options">        <span action="toggleRegexpMode" class="ace_button" title="RegExp Search">.*</span>        <span action="toggleCaseSensitive" class="ace_button" title="CaseSensitive Search">Aa</span>        <span action="toggleWholeWords" class="ace_button" title="Whole Word Search">\\b</span>    </div></div>'.replace(/>\s+/g,">"),l=function(e,t,n){var i=r.createElement("div");i.innerHTML=f,this.element=i.firstChild,this.$init(),this.setEditor(e)};(function(){this.setEditor=function(e){e.searchBox=this,e.container.appendChild(this.element),this.editor=e},this.$initElements=function(e){this.searchBox=e.querySelector(".ace_search_form"),this.replaceBox=e.querySelector(".ace_replace_form"),this.searchOptions=e.querySelector(".ace_search_options"),this.regExpOption=e.querySelector("[action=toggleRegexpMode]"),this.caseSensitiveOption=e.querySelector("[action=toggleCaseSensitive]"),this.wholeWordOption=e.querySelector("[action=toggleWholeWords]"),this.searchInput=this.searchBox.querySelector(".ace_search_field"),this.replaceInput=this.replaceBox.querySelector(".ace_search_field")},this.$init=function(){var e=this.element;this.$initElements(e);var t=this;s.addListener(e,"mousedown",function(e){setTimeout(function(){t.activeInput.focus()},0),s.stopPropagation(e)}),s.addListener(e,"click",function(e){var n=e.target||e.srcElement,r=n.getAttribute("action");r&&t[r]?t[r]():t.$searchBarKb.commands[r]&&t.$searchBarKb.commands[r].exec(t),s.stopPropagation(e)}),s.addCommandKeyListener(e,function(e,n,r){var i=a.keyCodeToString(r),o=t.$searchBarKb.findKeyCommand(n,i);o&&o.exec&&(o.exec(t),s.stopEvent(e))}),this.$onChange=i.delayedCall(function(){t.find(!1,!1)}),s.addListener(this.searchInput,"input",function(){t.$onChange.schedule(20)}),s.addListener(this.searchInput,"focus",function(){t.activeInput=t.searchInput,t.searchInput.value&&t.highlight()}),s.addListener(this.replaceInput,"focus",function(){t.activeInput=t.replaceInput,t.searchInput.value&&t.highlight()})},this.$closeSearchBarKb=new u([{bindKey:"Esc",name:"closeSearchBar",exec:function(e){e.searchBox.hide()}}]),this.$searchBarKb=new u,this.$searchBarKb.bindKeys({"Ctrl-f|Command-f|Ctrl-H|Command-Option-F":function(e){var t=e.isReplace=!e.isReplace;e.replaceBox.style.display=t?"":"none",e[t?"replaceInput":"searchInput"].focus()},"Ctrl-G|Command-G":function(e){e.findNext()},"Ctrl-Shift-G|Command-Shift-G":function(e){e.findPrev()},esc:function(e){setTimeout(function(){e.hide()})},Return:function(e){e.activeInput==e.replaceInput&&e.replace(),e.findNext()},"Shift-Return":function(e){e.activeInput==e.replaceInput&&e.replace(),e.findPrev()},Tab:function(e){(e.activeInput==e.replaceInput?e.searchInput:e.replaceInput).focus()}}),this.$searchBarKb.addCommands([{name:"toggleRegexpMode",bindKey:{win:"Alt-R|Alt-/",mac:"Ctrl-Alt-R|Ctrl-Alt-/"},exec:function(e){e.regExpOption.checked=!e.regExpOption.checked,e.$syncOptions()}},{name:"toggleCaseSensitive",bindKey:{win:"Alt-C|Alt-I",mac:"Ctrl-Alt-R|Ctrl-Alt-I"},exec:function(e){e.caseSensitiveOption.checked=!e.caseSensitiveOption.checked,e.$syncOptions()}},{name:"toggleWholeWords",bindKey:{win:"Alt-B|Alt-W",mac:"Ctrl-Alt-B|Ctrl-Alt-W"},exec:function(e){e.wholeWordOption.checked=!e.wholeWordOption.checked,e.$syncOptions()}}]),this.$syncOptions=function(){r.setCssClass(this.regExpOption,"checked",this.regExpOption.checked),r.setCssClass(this.wholeWordOption,"checked",this.wholeWordOption.checked),r.setCssClass(this.caseSensitiveOption,"checked",this.caseSensitiveOption.checked),this.find(!1,!1)},this.highlight=function(e){this.editor.session.highlight(e||this.editor.$search.$options.re),this.editor.renderer.updateBackMarkers()},this.find=function(e,t){var n=this.editor.find(this.searchInput.value,{skipCurrent:e,backwards:t,wrap:!0,regExp:this.regExpOption.checked,caseSensitive:this.caseSensitiveOption.checked,wholeWord:this.wholeWordOption.checked}),i=!n&&this.searchInput.value;r.setCssClass(this.searchBox,"ace_nomatch",i),this.editor._emit("findSearchBox",{match:!i}),this.highlight()},this.findNext=function(){this.find(!0,!1)},this.findPrev=function(){this.find(!0,!0)},this.replace=function(){this.editor.getReadOnly()||this.editor.replace(this.replaceInput.value)},this.replaceAndFindNext=function(){this.editor.getReadOnly()||(this.editor.replace(this.replaceInput.value),this.findNext())},this.replaceAll=function(){this.editor.getReadOnly()||this.editor.replaceAll(this.replaceInput.value)},this.hide=function(){this.element.style.display="none",this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb),this.editor.focus()},this.show=function(e,t){this.element.style.display="",this.replaceBox.style.display=t?"":"none",this.isReplace=t,e&&(this.searchInput.value=e),this.searchInput.focus(),this.searchInput.select(),this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb)}}).call(l.prototype),t.SearchBox=l,t.Search=function(e,t){var n=e.searchBox||new l(e);n.show(e.session.getTextRange(),t)}});
            +                (function() {
            +                    ace.require(["ace/ext/searchbox"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-settings_menu.js b/dist/assets/js/vendor/ace-nc/ext-settings_menu.js
            new file mode 100644
            index 0000000000..742e570a70
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-settings_menu.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/menu_tools/element_generator",["require","exports","module"],function(e,t,n){"use strict";n.exports.createOption=function(t){var n,r=document.createElement("option");for(n in t)t.hasOwnProperty(n)&&(n==="selected"?r.setAttribute(n,t[n]):r[n]=t[n]);return r},n.exports.createCheckbox=function(t,n,r){var i=document.createElement("input");return i.setAttribute("type","checkbox"),i.setAttribute("id",t),i.setAttribute("name",t),i.setAttribute("value",n),i.setAttribute("class",r),n&&i.setAttribute("checked","checked"),i},n.exports.createInput=function(t,n,r){var i=document.createElement("input");return i.setAttribute("type","text"),i.setAttribute("id",t),i.setAttribute("name",t),i.setAttribute("value",n),i.setAttribute("class",r),i},n.exports.createLabel=function(t,n){var r=document.createElement("label");return r.setAttribute("for",n),r.textContent=t,r},n.exports.createSelection=function(t,r,i){var s=document.createElement("select");return s.setAttribute("id",t),s.setAttribute("name",t),s.setAttribute("class",i),r.forEach(function(e){s.appendChild(n.exports.createOption(e))}),s}}),ace.define("ace/ext/modelist",["require","exports","module"],function(e,t,n){"use strict";function i(e){var t=a.text,n=e.split(/[\/\\]/).pop();for(var i=0;i<r.length;i++)if(r[i].supportsFile(n)){t=r[i];break}return t}var r=[],s=function(e,t,n){this.name=e,this.caption=t,this.mode="ace/mode/"+e,this.extensions=n;if(/\^/.test(n))var r=n.replace(/\|(\^)?/g,function(e,t){return"$|"+(t?"^":"^.*\\.")})+"$";else var r="^.*\\.("+n+")$";this.extRe=new RegExp(r,"gi")};s.prototype.supportsFile=function(e){return e.match(this.extRe)};var o={ABAP:["abap"],ActionScript:["as"],ADA:["ada|adb"],Apache_Conf:["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"],AsciiDoc:["asciidoc"],Assembly_x86:["asm"],AutoHotKey:["ahk"],BatchFile:["bat|cmd"],C9Search:["c9search_results"],C_Cpp:["cpp|c|cc|cxx|h|hh|hpp"],Cirru:["cirru|cr"],Clojure:["clj|cljs"],Cobol:["CBL|COB"],coffee:["coffee|cf|cson|^Cakefile"],ColdFusion:["cfm"],CSharp:["cs"],CSS:["css"],Curly:["curly"],D:["d|di"],Dart:["dart"],Diff:["diff|patch"],Dockerfile:["^Dockerfile"],Dot:["dot"],Erlang:["erl|hrl"],EJS:["ejs"],Forth:["frt|fs|ldr"],FTL:["ftl"],Gherkin:["feature"],Gitignore:["^.gitignore"],Glsl:["glsl|frag|vert"],golang:["go"],Groovy:["groovy"],HAML:["haml"],Handlebars:["hbs|handlebars|tpl|mustache"],Haskell:["hs"],haXe:["hx"],HTML:["html|htm|xhtml"],HTML_Ruby:["erb|rhtml|html.erb"],INI:["ini|conf|cfg|prefs"],Jack:["jack"],Jade:["jade"],Java:["java"],JavaScript:["js|jsm"],JSON:["json"],JSONiq:["jq"],JSP:["jsp"],JSX:["jsx"],Julia:["jl"],LaTeX:["tex|latex|ltx|bib"],LESS:["less"],Liquid:["liquid"],Lisp:["lisp"],LiveScript:["ls"],LogiQL:["logic|lql"],LSL:["lsl"],Lua:["lua"],LuaPage:["lp"],Lucene:["lucene"],Makefile:["^Makefile|^GNUmakefile|^makefile|^OCamlMakefile|make"],MATLAB:["matlab"],Markdown:["md|markdown"],MEL:["mel"],MySQL:["mysql"],MUSHCode:["mc|mush"],Nix:["nix"],ObjectiveC:["m|mm"],OCaml:["ml|mli"],Pascal:["pas|p"],Perl:["pl|pm"],pgSQL:["pgsql"],PHP:["php|phtml"],Powershell:["ps1"],Prolog:["plg|prolog"],Properties:["properties"],Protobuf:["proto"],Python:["py"],R:["r"],RDoc:["Rd"],RHTML:["Rhtml"],Ruby:["rb|ru|gemspec|rake|^Guardfile|^Rakefile|^Gemfile"],Rust:["rs"],SASS:["sass"],SCAD:["scad"],Scala:["scala"],Smarty:["smarty|tpl"],Scheme:["scm|rkt"],SCSS:["scss"],SH:["sh|bash|^.bashrc"],SJS:["sjs"],Space:["space"],snippets:["snippets"],Soy_Template:["soy"],SQL:["sql"],Stylus:["styl|stylus"],SVG:["svg"],Tcl:["tcl"],Tex:["tex"],Text:["txt"],Textile:["textile"],Toml:["toml"],Twig:["twig"],Typescript:["ts|typescript|str"],Vala:["vala"],VBScript:["vbs"],Velocity:["vm"],Verilog:["v|vh|sv|svh"],XML:["xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl"],XQuery:["xq"],YAML:["yaml|yml"]},u={ObjectiveC:"Objective-C",CSharp:"C#",golang:"Go",C_Cpp:"C/C++",coffee:"CoffeeScript",HTML_Ruby:"HTML (Ruby)",FTL:"FreeMarker"},a={};for(var f in o){var l=o[f],c=(u[f]||f).replace(/_/g," "),h=f.toLowerCase(),p=new s(h,c,l[0]);a[h]=p,r.push(p)}n.exports={getModeForPath:i,modes:r,modesByName:a}}),ace.define("ace/ext/themelist",["require","exports","module","ace/lib/fixoldbrowsers"],function(e,t,n){"use strict";e("ace/lib/fixoldbrowsers");var r=[["Chrome"],["Clouds"],["Crimson Editor"],["Dawn"],["Dreamweaver"],["Eclipse"],["GitHub"],["Solarized Light"],["TextMate"],["Tomorrow"],["XCode"],["Kuroir"],["KatzenMilch"],["Ambiance","ambiance","dark"],["Chaos","chaos","dark"],["Clouds Midnight","clouds_midnight","dark"],["Cobalt","cobalt","dark"],["idle Fingers","idle_fingers","dark"],["krTheme","kr_theme","dark"],["Merbivore","merbivore","dark"],["Merbivore Soft","merbivore_soft","dark"],["Mono Industrial","mono_industrial","dark"],["Monokai","monokai","dark"],["Pastel on dark","pastel_on_dark","dark"],["Solarized Dark","solarized_dark","dark"],["Terminal","terminal","dark"],["Tomorrow Night","tomorrow_night","dark"],["Tomorrow Night Blue","tomorrow_night_blue","dark"],["Tomorrow Night Bright","tomorrow_night_bright","dark"],["Tomorrow Night 80s","tomorrow_night_eighties","dark"],["Twilight","twilight","dark"],["Vibrant Ink","vibrant_ink","dark"]];t.themesByName={},t.themes=r.map(function(e){var n=e[1]||e[0].replace(/ /g,"_").toLowerCase(),r={caption:e[0],theme:"ace/theme/"+n,isDark:e[2]=="dark",name:n};return t.themesByName[n]=r,r})}),ace.define("ace/ext/menu_tools/add_editor_menu_options",["require","exports","module","ace/ext/modelist","ace/ext/themelist"],function(e,t,n){"use strict";n.exports.addEditorMenuOptions=function(n){var r=e("../modelist"),i=e("../themelist");n.menuOptions={setNewLineMode:[{textContent:"unix",value:"unix"},{textContent:"windows",value:"windows"},{textContent:"auto",value:"auto"}],setTheme:[],setMode:[],setKeyboardHandler:[{textContent:"ace",value:""},{textContent:"vim",value:"ace/keyboard/vim"},{textContent:"emacs",value:"ace/keyboard/emacs"},{textContent:"textarea",value:"ace/keyboard/textarea"},{textContent:"sublime",value:"ace/keyboard/sublime"}]},n.menuOptions.setTheme=i.themes.map(function(e){return{textContent:e.caption,value:e.theme}}),n.menuOptions.setMode=r.modes.map(function(e){return{textContent:e.name,value:e.mode}})}}),ace.define("ace/ext/menu_tools/get_set_functions",["require","exports","module"],function(e,t,n){"use strict";n.exports.getSetFunctions=function(t){var n=[],r={editor:t,session:t.session,renderer:t.renderer},i=[],s=["setOption","setUndoManager","setDocument","setValue","setBreakpoints","setScrollTop","setScrollLeft","setSelectionStyle","setWrapLimitRange"];return["renderer","session","editor"].forEach(function(e){var t=r[e],o=e;for(var u in t)s.indexOf(u)===-1&&/^set/.test(u)&&i.indexOf(u)===-1&&(i.push(u),n.push({functionName:u,parentObj:t,parentName:o}))}),n}}),ace.define("ace/ext/menu_tools/generate_settings_menu",["require","exports","module","ace/ext/menu_tools/element_generator","ace/ext/menu_tools/add_editor_menu_options","ace/ext/menu_tools/get_set_functions"],function(e,t,n){"use strict";var r=e("./element_generator"),i=e("./add_editor_menu_options").addEditorMenuOptions,s=e("./get_set_functions").getSetFunctions;n.exports.generateSettingsMenu=function(t){function o(){n.sort(function(e,t){var n=e.getAttribute("contains"),r=t.getAttribute("contains");return n.localeCompare(r)})}function u(){var e=document.createElement("div");return e.setAttribute("id","ace_settingsmenu"),n.forEach(function(t){e.appendChild(t)}),e}function a(e,n,i,s){var o,u=document.createElement("div");return u.setAttribute("contains",i),u.setAttribute("class","ace_optionsMenuEntry"),u.setAttribute("style","clear: both;"),u.appendChild(r.createLabel(i.replace(/^set/,"").replace(/([A-Z])/g," $1").trim(),i)),Array.isArray(s)?(o=r.createSelection(i,s,n),o.addEventListener("change",function(n){try{t.menuOptions[n.target.id].forEach(function(e){e.textContent!==n.target.textContent&&delete e.selected}),e[n.target.id](n.target.value)}catch(r){throw new Error(r)}})):typeof s=="boolean"?(o=r.createCheckbox(i,s,n),o.addEventListener("change",function(t){try{e[t.target.id](!!t.target.checked)}catch(n){throw new Error(n)}})):(o=r.createInput(i,s,n),o.addEventListener("change",function(t){try{t.target.value==="true"?e[t.target.id](!0):t.target.value==="false"?e[t.target.id](!1):e[t.target.id](t.target.value)}catch(n){throw new Error(n)}})),o.style.cssText="float:right;",u.appendChild(o),u}function f(e,n,r,i){var s=t.menuOptions[e],o=n[i]();return typeof o=="object"&&(o=o.$id),s.forEach(function(e){e.value===o&&(e.selected="selected")}),a(n,r,e,s)}function l(e){var r=e.functionName,i=e.parentObj,s=e.parentName,o,u=r.replace(/^set/,"get");if(t.menuOptions[r]!==undefined)n.push(f(r,i,s,u));else if(typeof i[u]=="function")try{o=i[u](),typeof o=="object"&&(o=o.$id),n.push(a(i,s,r,o))}catch(l){}}var n=[];return i(t),s(t).forEach(function(e){l(e)}),o(),u()}}),ace.define("ace/ext/menu_tools/overlay_page",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../../lib/dom"),i="#ace_settingsmenu, #kbshortcutmenu {background-color: #F7F7F7;color: black;box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55);padding: 1em 0.5em 2em 1em;overflow: auto;position: absolute;margin: 0;bottom: 0;right: 0;top: 0;z-index: 9991;cursor: default;}.ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu {box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25);background-color: rgba(255, 255, 255, 0.6);color: black;}.ace_optionsMenuEntry:hover {background-color: rgba(100, 100, 100, 0.1);-webkit-transition: all 0.5s;transition: all 0.3s}.ace_closeButton {background: rgba(245, 146, 146, 0.5);border: 1px solid #F48A8A;border-radius: 50%;padding: 7px;position: absolute;right: -8px;top: -8px;z-index: 1000;}.ace_closeButton{background: rgba(245, 146, 146, 0.9);}.ace_optionsMenuKey {color: darkslateblue;font-weight: bold;}.ace_optionsMenuCommand {color: darkcyan;font-weight: normal;}";r.importCssString(i),n.exports.overlayPage=function(t,n,i,s,o,u){function l(e){e.keyCode===27&&a.click()}i=i?"top: "+i+";":"",o=o?"bottom: "+o+";":"",s=s?"right: "+s+";":"",u=u?"left: "+u+";":"";var a=document.createElement("div"),f=document.createElement("div");a.style.cssText="margin: 0; padding: 0; position: fixed; top:0; bottom:0; left:0; right:0;z-index: 9990; background-color: rgba(0, 0, 0, 0.3);",a.addEventListener("click",function(){document.removeEventListener("keydown",l),a.parentNode.removeChild(a),t.focus(),a=null}),document.addEventListener("keydown",l),f.style.cssText=i+s+o+u,f.addEventListener("click",function(e){e.stopPropagation()});var c=r.createElement("div");c.style.position="relative";var h=r.createElement("div");h.className="ace_closeButton",h.addEventListener("click",function(){a.click()}),c.appendChild(h),f.appendChild(c),f.appendChild(n),a.appendChild(f),document.body.appendChild(a),t.blur()}}),ace.define("ace/ext/settings_menu",["require","exports","module","ace/ext/menu_tools/generate_settings_menu","ace/ext/menu_tools/overlay_page","ace/editor"],function(e,t,n){"use strict";function s(e){var t=document.getElementById("ace_settingsmenu");t||i(e,r(e),"0","0","0")}var r=e("./menu_tools/generate_settings_menu").generateSettingsMenu,i=e("./menu_tools/overlay_page").overlayPage;n.exports.init=function(t){var n=e("ace/editor").Editor;n.prototype.showSettingsMenu=function(){s(this)}}});
            +                (function() {
            +                    ace.require(["ace/ext/settings_menu"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-spellcheck.js b/dist/assets/js/vendor/ace-nc/ext-spellcheck.js
            new file mode 100644
            index 0000000000..15c0f86f1b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-spellcheck.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/spellcheck",["require","exports","module","ace/lib/event","ace/editor","ace/config"],function(e,t,n){"use strict";var r=e("../lib/event");t.contextMenuHandler=function(e){var t=e.target,n=t.textInput.getElement();if(!t.selection.isEmpty())return;var i=t.getCursorPosition(),s=t.session.getWordRange(i.row,i.column),o=t.session.getTextRange(s);t.session.tokenRe.lastIndex=0;if(!t.session.tokenRe.test(o))return;var u="",a=o+" "+u;n.value=a,n.setSelectionRange(o.length,o.length+1),n.setSelectionRange(0,0),n.setSelectionRange(0,o.length);var f=!1;r.addListener(n,"keydown",function l(){r.removeListener(n,"keydown",l),f=!0}),t.textInput.setInputHandler(function(e){console.log(e,a,n.selectionStart,n.selectionEnd);if(e==a)return"";if(e.lastIndexOf(a,0)===0)return e.slice(a.length);if(e.substr(n.selectionEnd)==a)return e.slice(0,-a.length);if(e.slice(-2)==u){var r=e.slice(0,-2);if(r.slice(-1)==" ")return f?r.substring(0,n.selectionEnd):(r=r.slice(0,-1),t.session.replace(s,r),"")}return e})};var i=e("../editor").Editor;e("../config").defineOptions(i.prototype,"editor",{spellcheck:{set:function(e){var n=this.textInput.getElement();n.spellcheck=!!e,e?this.on("nativecontextmenu",t.contextMenuHandler):this.removeListener("nativecontextmenu",t.contextMenuHandler)},value:!0}})});
            +                (function() {
            +                    ace.require(["ace/ext/spellcheck"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-split.js b/dist/assets/js/vendor/ace-nc/ext-split.js
            new file mode 100644
            index 0000000000..31b3ee7cd7
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-split.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/split",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/editor","ace/virtual_renderer","ace/edit_session"],function(e,t,n){"use strict";function l(e,t){this.$u=e,this.$doc=t}var r=e("./lib/oop"),i=e("./lib/lang"),s=e("./lib/event_emitter").EventEmitter,o=e("./editor").Editor,u=e("./virtual_renderer").VirtualRenderer,a=e("./edit_session").EditSession,f=function(e,t,n){this.BELOW=1,this.BESIDE=0,this.$container=e,this.$theme=t,this.$splits=0,this.$editorCSS="",this.$editors=[],this.$orientation=this.BESIDE,this.setSplits(n||1),this.$cEditor=this.$editors[0],this.on("focus",function(e){this.$cEditor=e}.bind(this))};(function(){r.implement(this,s),this.$createEditor=function(){var e=document.createElement("div");e.className=this.$editorCSS,e.style.cssText="position: absolute; top:0px; bottom:0px",this.$container.appendChild(e);var t=new o(new u(e,this.$theme));return t.on("focus",function(){this._emit("focus",t)}.bind(this)),this.$editors.push(t),t.setFontSize(this.$fontSize),t},this.setSplits=function(e){var t;if(e<1)throw"The number of splits have to be > 0!";if(e==this.$splits)return;if(e>this.$splits){while(this.$splits<this.$editors.length&&this.$splits<e)t=this.$editors[this.$splits],this.$container.appendChild(t.container),t.setFontSize(this.$fontSize),this.$splits++;while(this.$splits<e)this.$createEditor(),this.$splits++}else while(this.$splits>e)t=this.$editors[this.$splits-1],this.$container.removeChild(t.container),this.$splits--;this.resize()},this.getSplits=function(){return this.$splits},this.getEditor=function(e){return this.$editors[e]},this.getCurrentEditor=function(){return this.$cEditor},this.focus=function(){this.$cEditor.focus()},this.blur=function(){this.$cEditor.blur()},this.setTheme=function(e){this.$editors.forEach(function(t){t.setTheme(e)})},this.setKeyboardHandler=function(e){this.$editors.forEach(function(t){t.setKeyboardHandler(e)})},this.forEach=function(e,t){this.$editors.forEach(e,t)},this.$fontSize="",this.setFontSize=function(e){this.$fontSize=e,this.forEach(function(t){t.setFontSize(e)})},this.$cloneSession=function(e){var t=new a(e.getDocument(),e.getMode()),n=e.getUndoManager();if(n){var r=new l(n,t);t.setUndoManager(r)}return t.$informUndoManager=i.delayedCall(function(){t.$deltas=[]}),t.setTabSize(e.getTabSize()),t.setUseSoftTabs(e.getUseSoftTabs()),t.setOverwrite(e.getOverwrite()),t.setBreakpoints(e.getBreakpoints()),t.setUseWrapMode(e.getUseWrapMode()),t.setUseWorker(e.getUseWorker()),t.setWrapLimitRange(e.$wrapLimitRange.min,e.$wrapLimitRange.max),t.$foldData=e.$cloneFoldData(),t},this.setSession=function(e,t){var n;t==null?n=this.$cEditor:n=this.$editors[t];var r=this.$editors.some(function(t){return t.session===e});return r&&(e=this.$cloneSession(e)),n.setSession(e),e},this.getOrientation=function(){return this.$orientation},this.setOrientation=function(e){if(this.$orientation==e)return;this.$orientation=e,this.resize()},this.resize=function(){var e=this.$container.clientWidth,t=this.$container.clientHeight,n;if(this.$orientation==this.BESIDE){var r=e/this.$splits;for(var i=0;i<this.$splits;i++)n=this.$editors[i],n.container.style.width=r+"px",n.container.style.top="0px",n.container.style.left=i*r+"px",n.container.style.height=t+"px",n.resize()}else{var s=t/this.$splits;for(var i=0;i<this.$splits;i++)n=this.$editors[i],n.container.style.width=e+"px",n.container.style.top=i*s+"px",n.container.style.left="0px",n.container.style.height=s+"px",n.resize()}}}).call(f.prototype),function(){this.execute=function(e){this.$u.execute(e)},this.undo=function(){var e=this.$u.undo(!0);e&&this.$doc.selection.setSelectionRange(e)},this.redo=function(){var e=this.$u.redo(!0);e&&this.$doc.selection.setSelectionRange(e)},this.reset=function(){this.$u.reset()},this.hasUndo=function(){return this.$u.hasUndo()},this.hasRedo=function(){return this.$u.hasRedo()}}.call(l.prototype),t.Split=f}),ace.define("ace/ext/split",["require","exports","module","ace/split"],function(e,t,n){"use strict";n.exports=e("../split")});
            +                (function() {
            +                    ace.require(["ace/ext/split"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-static_highlight.js b/dist/assets/js/vendor/ace-nc/ext-static_highlight.js
            new file mode 100644
            index 0000000000..308412758f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-static_highlight.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/static_highlight",["require","exports","module","ace/edit_session","ace/layer/text","ace/config","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../edit_session").EditSession,i=e("../layer/text").Text,s=".ace_static_highlight {font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'Droid Sans Mono', monospace;font-size: 12px;}.ace_static_highlight .ace_gutter {width: 25px !important;display: block;float: left;text-align: right;padding: 0 3px 0 0;margin-right: 3px;position: static !important;}.ace_static_highlight .ace_line { clear: both; }.ace_static_highlight .ace_gutter-cell {-moz-user-select: -moz-none;-khtml-user-select: none;-webkit-user-select: none;user-select: none;}.ace_static_highlight .ace_gutter-cell:before {content: counter(ace_line, decimal);counter-increment: ace_line;}.ace_static_highlight {counter-reset: ace_line;}",o=e("../config"),u=e("../lib/dom"),a=function(e,t,n){var r=e.className.match(/lang-(\w+)/),i=t.mode||r&&"ace/mode/"+r[1];if(!i)return!1;var s=t.theme||"ace/theme/textmate",o="",f=[];if(e.firstElementChild){var l=0;for(var c=0;c<e.childNodes.length;c++){var h=e.childNodes[c];h.nodeType==3?(l+=h.data.length,o+=h.data):f.push(l,h)}}else o=u.getInnerText(e),t.trim&&(o=o.trim());a.render(o,i,s,t.firstLineNumber,!t.showGutter,function(t){u.importCssString(t.css,"ace_highlight"),e.innerHTML=t.html;var r=e.firstChild.firstChild;for(var i=0;i<f.length;i+=2){var s=t.session.doc.indexToPosition(f[i]),o=f[i+1],a=r.children[s.row];a&&a.appendChild(o)}n&&n()})};a.render=function(e,t,n,i,s,u){function c(){var r=a.renderSync(e,t,n,i,s);return u?u(r):r}var f=1,l=r.prototype.$modes;return typeof n=="string"&&(f++,o.loadModule(["theme",n],function(e){n=e,--f||c()})),typeof t=="string"&&(f++,o.loadModule(["mode",t],function(e){l[t]||(l[t]=new e.Mode),t=l[t],--f||c()})),--f||c()},a.renderSync=function(e,t,n,o,u){o=parseInt(o||1,10);var a=new r("");a.setUseWorker(!1),a.setMode(t);var f=new i(document.createElement("div"));f.setSession(a),f.config={characterWidth:10,lineHeight:20},a.setValue(e);var l=[],c=a.getLength();for(var h=0;h<c;h++)l.push("<div class='ace_line'>"),u||l.push("<span class='ace_gutter ace_gutter-cell' unselectable='on'></span>"),f.$renderLine(l,h,!0,!1),l.push("\n</div>");var p="<div class='"+n.cssClass+"'>"+"<div class='ace_static_highlight' style='counter-reset:ace_line "+(o-1)+"'>"+l.join("")+"</div>"+"</div>";return f.destroy(),{css:s+n.cssText,html:p,session:a}},n.exports=a,n.exports.highlight=a});
            +                (function() {
            +                    ace.require(["ace/ext/static_highlight"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-statusbar.js b/dist/assets/js/vendor/ace-nc/ext-statusbar.js
            new file mode 100644
            index 0000000000..f1cd0bad44
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-statusbar.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/statusbar",["require","exports","module","ace/lib/dom","ace/lib/lang"],function(e,t,n){"use strict";var r=e("ace/lib/dom"),i=e("ace/lib/lang"),s=function(e,t){this.element=r.createElement("div"),this.element.className="ace_status-indicator",this.element.style.cssText="display: inline-block;",t.appendChild(this.element);var n=i.delayedCall(function(){this.updateStatus(e)}.bind(this));e.on("changeStatus",function(){n.schedule(100)}),e.on("changeSelection",function(){n.schedule(100)})};(function(){this.updateStatus=function(e){function n(e,n){e&&t.push(e,n||"|")}var t=[];e.$vimModeHandler?n(e.$vimModeHandler.getStatusText()):e.commands.recording&&n("REC");var r=e.selection.lead;n(r.row+":"+r.column," ");if(!e.selection.isEmpty()){var i=e.getSelectionRange();n("("+(i.end.row-i.start.row)+":"+(i.end.column-i.start.column)+")")}t.pop(),this.element.textContent=t.join("")}}).call(s.prototype),t.StatusBar=s});
            +                (function() {
            +                    ace.require(["ace/ext/statusbar"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-textarea.js b/dist/assets/js/vendor/ace-nc/ext-textarea.js
            new file mode 100644
            index 0000000000..3e95a30296
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-textarea.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;border-radius: 2px;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)}),ace.define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"],function(e,t,n){"use strict";e("./lib/fixoldbrowsers");var r=e("./lib/dom"),i=e("./lib/event"),s=e("./editor").Editor,o=e("./edit_session").EditSession,u=e("./undomanager").UndoManager,a=e("./virtual_renderer").VirtualRenderer;e("./worker/worker_client"),e("./keyboard/hash_handler"),e("./placeholder"),e("./multi_select"),e("./mode/folding/fold_mode"),e("./theme/textmate"),e("./ext/error_marker"),t.config=e("./config"),t.require=e,t.edit=function(e){if(typeof e=="string"){var n=e;e=document.getElementById(n);if(!e)throw new Error("ace.edit can't find div #"+n)}if(e.env&&e.env.editor instanceof s)return e.env.editor;var o=t.createEditSession(r.getInnerText(e));e.innerHTML="";var u=new s(new a(e));u.setSession(o);var f={document:o,editor:u,onResize:u.resize.bind(u,null)};return i.addListener(window,"resize",f.onResize),u.on("destroy",function(){i.removeListener(window,"resize",f.onResize)}),e.env=u.env=f,u},t.createEditSession=function(e,t){var n=new o(e,t);return n.setUndoManager(new u),n},t.EditSession=o,t.UndoManager=u}),ace.define("ace/ext/textarea",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/net","ace/ace","ace/theme/textmate"],function(e,t,n){"use strict";function a(e,t){for(var n in t)e.style[n]=t[n]}function f(e,t){if(e.type!="textarea")throw new Error("Textarea required!");var n=e.parentNode,i=document.createElement("div"),s=function(){var t="position:relative;";["margin-top","margin-left","margin-right","margin-bottom"].forEach(function(n){t+=n+":"+u(e,i,n)+";"});var n=u(e,i,"width")||e.clientWidth+"px",r=u(e,i,"height")||e.clientHeight+"px";t+="height:"+r+";width:"+n+";",t+="display:inline-block;",i.setAttribute("style",t)};r.addListener(window,"resize",s),s(),n.insertBefore(i,e.nextSibling);while(n!==document){if(n.tagName.toUpperCase()==="FORM"){var o=n.onsubmit;n.onsubmit=function(n){e.value=t(),o&&o.call(this,n)};break}n=n.parentNode}return i}function l(t,n,r){s.loadScript(t,function(){e([n],r)})}function c(e,t,n,r,i,s){function a(e){return e==="true"||e==1}var o=e.getSession(),u=e.renderer;return s=s||l,e.setDisplaySettings=function(t){t==null&&(t=n.style.display=="none"),t?(n.style.display="block",n.hideButton.focus(),e.on("focus",function r(){e.removeListener("focus",r),n.style.display="none"})):e.focus()},e.$setOption=e.setOption,e.$getOption=e.getOption,e.setOption=function(t,n){switch(t){case"mode":e.$setOption("mode","ace/mode/"+n);break;case"theme":e.$setOption("theme","ace/theme/"+n);break;case"keybindings":switch(n){case"vim":e.setKeyboardHandler("ace/keyboard/vim");break;case"emacs":e.setKeyboardHandler("ace/keyboard/emacs");break;default:e.setKeyboardHandler(null)}break;case"softWrap":case"fontSize":e.$setOption(t,n);break;default:e.$setOption(t,a(n))}},e.getOption=function(t){switch(t){case"mode":return e.$getOption("mode").substr("ace/mode/".length);case"theme":return e.$getOption("theme").substr("ace/theme/".length);case"keybindings":var n=e.getKeyboardHandler();switch(n&&n.$id){case"ace/keyboard/vim":return"vim";case"ace/keyboard/emacs":return"emacs";default:return"ace"}break;default:return e.$getOption(t)}},e.setOptions(i),e}function h(e,n,i){function f(e,t,n,r){if(!n){e.push("<input type='checkbox' title='",t,"' ",r+""=="true"?"checked='true'":"","'></input>");return}e.push("<select title='"+t+"'>");for(var i in n)e.push("<option value='"+i+"' "),r==i&&e.push(" selected "),e.push(">",n[i],"</option>");e.push("</select>")}var s=null,o={mode:"Mode:",wrap:"Soft Wrap:",theme:"Theme:",fontSize:"Font Size:",showGutter:"Display Gutter:",keybindings:"Keyboard",showPrintMargin:"Show Print Margin:",useSoftTabs:"Use Soft Tabs:",showInvisibles:"Show Invisibles"},u={mode:{text:"Plain",javascript:"JavaScript",xml:"XML",html:"HTML",css:"CSS",scss:"SCSS",python:"Python",php:"PHP",java:"Java",ruby:"Ruby",c_cpp:"C/C++",coffee:"CoffeeScript",json:"json",perl:"Perl",clojure:"Clojure",ocaml:"OCaml",csharp:"C#",haxe:"haXe",svg:"SVG",textile:"Textile",groovy:"Groovy",liquid:"Liquid",Scala:"Scala"},theme:{clouds:"Clouds",clouds_midnight:"Clouds Midnight",cobalt:"Cobalt",crimson_editor:"Crimson Editor",dawn:"Dawn",eclipse:"Eclipse",idle_fingers:"Idle Fingers",kr_theme:"Kr Theme",merbivore:"Merbivore",merbivore_soft:"Merbivore Soft",mono_industrial:"Mono Industrial",monokai:"Monokai",pastel_on_dark:"Pastel On Dark",solarized_dark:"Solarized Dark",solarized_light:"Solarized Light",textmate:"Textmate",twilight:"Twilight",vibrant_ink:"Vibrant Ink"},showGutter:s,fontSize:{"10px":"10px","11px":"11px","12px":"12px","14px":"14px","16px":"16px"},wrap:{off:"Off",40:"40",80:"80",free:"Free"},keybindings:{ace:"ace",vim:"vim",emacs:"emacs"},showPrintMargin:s,useSoftTabs:s,showInvisibles:s},a=[];a.push("<table><tr><th>Setting</th><th>Value</th></tr>");for(var l in t.defaultOptions)a.push("<tr><td>",o[l],"</td>"),a.push("<td>"),f(a,l,u[l],i.getOption(l)),a.push("</td></tr>");a.push("</table>"),e.innerHTML=a.join("");var c=function(e){var t=e.currentTarget;i.setOption(t.title,t.value)},h=function(e){var t=e.currentTarget;i.setOption(t.title,t.checked)},p=e.getElementsByTagName("select");for(var d=0;d<p.length;d++)p[d].onchange=c;var v=e.getElementsByTagName("input");for(var d=0;d<v.length;d++)v[d].onclick=h;var m=document.createElement("input");m.type="button",m.value="Hide",r.addListener(m,"click",function(){i.setDisplaySettings(!1)}),e.appendChild(m),e.hideButton=m}var r=e("../lib/event"),i=e("../lib/useragent"),s=e("../lib/net"),o=e("../ace");e("../theme/textmate"),n.exports=t=o;var u=function(e,t,n){var r=e.style[n];r||(window.getComputedStyle?r=window.getComputedStyle(e,"").getPropertyValue(n):r=e.currentStyle[n]);if(!r||r=="auto"||r=="intrinsic")r=t.style[n];return r};t.transformTextarea=function(e,n){var s,u=f(e,function(){return s.getValue()});e.style.display="none",u.style.background="white";var p=document.createElement("div");a(p,{top:"0px",left:"0px",right:"0px",bottom:"0px",border:"1px solid gray",position:"absolute"}),u.appendChild(p);var d=document.createElement("div");a(d,{position:"absolute",right:"0px",bottom:"0px",background:"red",cursor:"nw-resize",borderStyle:"solid",borderWidth:"9px 8px 10px 9px",width:"2px",borderColor:"lightblue gray gray lightblue",zIndex:101});var v=document.createElement("div"),m={top:"0px",left:"20%",right:"0px",bottom:"0px",position:"absolute",padding:"5px",zIndex:100,color:"white",display:"none",overflow:"auto",fontSize:"14px",boxShadow:"-5px 2px 3px gray"};i.isOldIE?m.backgroundColor="#333":m.backgroundColor="rgba(0, 0, 0, 0.6)",a(v,m),u.appendChild(v),n=n||t.defaultOptions;var g=o.edit(p);s=g.getSession(),s.setValue(e.value||e.innerHTML),g.focus(),u.appendChild(d),c(g,p,v,o,n,l),h(v,d,g);var y="";return r.addListener(d,"mousemove",function(e){var t=this.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top;n+r<(t.width+t.height)/2?(this.style.cursor="pointer",y="toggle"):(y="resize",this.style.cursor="nw-resize")}),r.addListener(d,"mousedown",function(e){if(y=="toggle"){g.setDisplaySettings();return}u.style.zIndex=1e5;var t=u.getBoundingClientRect(),n=t.width+t.left-e.clientX,i=t.height+t.top-e.clientY;r.capture(d,function(e){u.style.width=e.clientX-t.left+n+"px",u.style.height=e.clientY-t.top+i+"px",g.resize()},function(){})}),g},t.defaultOptions={mode:"javascript",theme:"textmate",wrap:"off",fontSize:"12px",showGutter:"false",keybindings:"ace",showPrintMargin:"false",useSoftTabs:"true",showInvisibles:"false"}});
            +                (function() {
            +                    ace.require(["ace/ext/textarea"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-themelist.js b/dist/assets/js/vendor/ace-nc/ext-themelist.js
            new file mode 100644
            index 0000000000..18b731d944
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-themelist.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/themelist",["require","exports","module","ace/lib/fixoldbrowsers"],function(e,t,n){"use strict";e("ace/lib/fixoldbrowsers");var r=[["Chrome"],["Clouds"],["Crimson Editor"],["Dawn"],["Dreamweaver"],["Eclipse"],["GitHub"],["Solarized Light"],["TextMate"],["Tomorrow"],["XCode"],["Kuroir"],["KatzenMilch"],["Ambiance","ambiance","dark"],["Chaos","chaos","dark"],["Clouds Midnight","clouds_midnight","dark"],["Cobalt","cobalt","dark"],["idle Fingers","idle_fingers","dark"],["krTheme","kr_theme","dark"],["Merbivore","merbivore","dark"],["Merbivore Soft","merbivore_soft","dark"],["Mono Industrial","mono_industrial","dark"],["Monokai","monokai","dark"],["Pastel on dark","pastel_on_dark","dark"],["Solarized Dark","solarized_dark","dark"],["Terminal","terminal","dark"],["Tomorrow Night","tomorrow_night","dark"],["Tomorrow Night Blue","tomorrow_night_blue","dark"],["Tomorrow Night Bright","tomorrow_night_bright","dark"],["Tomorrow Night 80s","tomorrow_night_eighties","dark"],["Twilight","twilight","dark"],["Vibrant Ink","vibrant_ink","dark"]];t.themesByName={},t.themes=r.map(function(e){var n=e[1]||e[0].replace(/ /g,"_").toLowerCase(),r={caption:e[0],theme:"ace/theme/"+n,isDark:e[2]=="dark",name:n};return t.themesByName[n]=r,r})});
            +                (function() {
            +                    ace.require(["ace/ext/themelist"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/ext-whitespace.js b/dist/assets/js/vendor/ace-nc/ext-whitespace.js
            new file mode 100644
            index 0000000000..ef013d808f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/ext-whitespace.js
            @@ -0,0 +1,5 @@
            +ace.define("ace/ext/whitespace",["require","exports","module","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../lib/lang");t.$detectIndentation=function(e,t){function c(e){var t=0;for(var r=e;r<n.length;r+=e)t+=n[r]||0;return t}var n=[],r=[],i=0,s=0,o=Math.min(e.length,1e3);for(var u=0;u<o;u++){var a=e[u];if(!/^\s*[^*+\-\s]/.test(a))continue;a[0]=="	"&&i++;var f=a.match(/^ */)[0].length;if(f&&a[f]!="	"){var l=f-s;l>0&&!(s%l)&&!(f%l)&&(r[l]=(r[l]||0)+1),n[f]=(n[f]||0)+1}s=f;while(u<o&&a[a.length-1]=="\\")a=e[u++]}var h=r.reduce(function(e,t){return e+t},0),p={score:0,length:0},d=0;for(var u=1;u<12;u++){if(u==1){d=c(u);var v=n.length&&1}else var v=c(u)/d;r[u]&&(v+=r[u]/h),v>p.score&&(p={score:v,length:u})}if(p.score&&p.score>1.4)var m=p.length;if(i>d+1)return{ch:"	",length:m};if(d>i+1)return{ch:" ",length:m}},t.detectIndentation=function(e){var n=e.getLines(0,1e3),r=t.$detectIndentation(n)||{};return r.ch&&e.setUseSoftTabs(r.ch==" "),r.length&&e.setTabSize(r.length),r},t.trimTrailingSpace=function(e,t){var n=e.getDocument(),r=n.getAllLines(),i=t?-1:0;for(var s=0,o=r.length;s<o;s++){var u=r[s],a=u.search(/\s+$/);a>i&&n.removeInLine(s,a,u.length)}},t.convertIndentation=function(e,t,n){var i=e.getTabString()[0],s=e.getTabSize();n||(n=s),t||(t=i);var o=t=="	"?t:r.stringRepeat(t,n),u=e.doc,a=u.getAllLines(),f={},l={};for(var c=0,h=a.length;c<h;c++){var p=a[c],d=p.match(/^\s*/)[0];if(d){var v=e.$getStringScreenWidth(d)[0],m=Math.floor(v/s),g=v%s,y=f[m]||(f[m]=r.stringRepeat(o,m));y+=l[g]||(l[g]=r.stringRepeat(" ",g)),y!=d&&(u.removeInLine(c,0,d.length),u.insertInLine({row:c,column:0},y))}}e.setTabSize(n),e.setUseSoftTabs(t==" ")},t.$parseStringArg=function(e){var t={};/t/.test(e)?t.ch="	":/s/.test(e)&&(t.ch=" ");var n=e.match(/\d+/);return n&&(t.length=parseInt(n[0],10)),t},t.$parseArg=function(e){return e?typeof e=="string"?t.$parseStringArg(e):typeof e.text=="string"?t.$parseStringArg(e.text):e:{}},t.commands=[{name:"detectIndentation",exec:function(e){t.detectIndentation(e.session)}},{name:"trimTrailingSpace",exec:function(e){t.trimTrailingSpace(e.session)}},{name:"convertIndentation",exec:function(e,n){var r=t.$parseArg(n);t.convertIndentation(e.session,r.ch,r.length)}},{name:"setIndentation",exec:function(e,n){var r=t.$parseArg(n);r.length&&e.session.setTabSize(r.length),r.ch&&e.session.setUseSoftTabs(r.ch==" ")}}]});
            +                (function() {
            +                    ace.require(["ace/ext/whitespace"], function() {});
            +                })();
            +            
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/keybinding-emacs.js b/dist/assets/js/vendor/ace-nc/keybinding-emacs.js
            new file mode 100644
            index 0000000000..82eabd63da
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/keybinding-emacs.js
            @@ -0,0 +1 @@
            +ace.define("ace/occur",["require","exports","module","ace/lib/oop","ace/range","ace/search","ace/edit_session","ace/search_highlight","ace/lib/dom"],function(e,t,n){"use strict";function a(){}var r=e("./lib/oop"),i=e("./range").Range,s=e("./search").Search,o=e("./edit_session").EditSession,u=e("./search_highlight").SearchHighlight;r.inherits(a,s),function(){this.enter=function(e,t){if(!t.needle)return!1;var n=e.getCursorPosition();this.displayOccurContent(e,t);var r=this.originalToOccurPosition(e.session,n);return e.moveCursorToPosition(r),!0},this.exit=function(e,t){var n=t.translatePosition&&e.getCursorPosition(),r=n&&this.occurToOriginalPosition(e.session,n);return this.displayOriginalContent(e),r&&e.moveCursorToPosition(r),!0},this.highlight=function(e,t){var n=e.$occurHighlight=e.$occurHighlight||e.addDynamicMarker(new u(null,"ace_occur-highlight","text"));n.setRegexp(t),e._emit("changeBackMarker")},this.displayOccurContent=function(e,t){this.$originalSession=e.session;var n=this.matchingLines(e.session,t),r=n.map(function(e){return e.content}),i=new o(r.join("\n"));i.$occur=this,i.$occurMatchingLines=n,e.setSession(i),this.$useEmacsStyleLineStart=this.$originalSession.$useEmacsStyleLineStart,i.$useEmacsStyleLineStart=this.$useEmacsStyleLineStart,this.highlight(i,t.re),i._emit("changeBackMarker")},this.displayOriginalContent=function(e){e.setSession(this.$originalSession),this.$originalSession.$useEmacsStyleLineStart=this.$useEmacsStyleLineStart},this.originalToOccurPosition=function(e,t){var n=e.$occurMatchingLines,r={row:0,column:0};if(!n)return r;for(var i=0;i<n.length;i++)if(n[i].row===t.row)return{row:i,column:t.column};return r},this.occurToOriginalPosition=function(e,t){var n=e.$occurMatchingLines;return!n||!n[t.row]?t:{row:n[t.row].row,column:t.column}},this.matchingLines=function(e,t){t=r.mixin({},t);if(!e||!t.needle)return[];var n=new s;return n.set(t),n.findAll(e).reduce(function(t,n){var r=n.start.row,i=t[t.length-1];return i&&i.row===r?t:t.concat({row:r,content:e.getLine(r)})},[])}}.call(a.prototype);var f=e("./lib/dom");f.importCssString(".ace_occur-highlight {\n    border-radius: 4px;\n    background-color: rgba(87, 255, 8, 0.25);\n    position: absolute;\n    z-index: 4;\n    -moz-box-sizing: border-box;\n    -webkit-box-sizing: border-box;\n    box-sizing: border-box;\n    box-shadow: 0 0 4px rgb(91, 255, 50);\n}\n.ace_dark .ace_occur-highlight {\n    background-color: rgb(80, 140, 85);\n    box-shadow: 0 0 4px rgb(60, 120, 70);\n}\n","incremental-occur-highlighting"),t.Occur=a}),ace.define("ace/commands/occur_commands",["require","exports","module","ace/config","ace/occur","ace/keyboard/hash_handler","ace/lib/oop"],function(e,t,n){function f(){}var r=e("../config"),i=e("../occur").Occur,s={name:"occur",exec:function(e,t){var n=!!e.session.$occur,r=(new i).enter(e,t);r&&!n&&f.installIn(e)},readOnly:!0},o=[{name:"occurexit",bindKey:"esc|Ctrl-G",exec:function(e){var t=e.session.$occur;if(!t)return;t.exit(e,{}),e.session.$occur||f.uninstallFrom(e)},readOnly:!0},{name:"occuraccept",bindKey:"enter",exec:function(e){var t=e.session.$occur;if(!t)return;t.exit(e,{translatePosition:!0}),e.session.$occur||f.uninstallFrom(e)},readOnly:!0}],u=e("../keyboard/hash_handler").HashHandler,a=e("../lib/oop");a.inherits(f,u),function(){this.isOccurHandler=!0,this.attach=function(e){u.call(this,o,e.commands.platform),this.$editor=e};var e=this.handleKeyboard;this.handleKeyboard=function(t,n,r,i){var s=e.call(this,t,n,r,i);return s&&s.command?s:undefined}}.call(f.prototype),f.installIn=function(e){var t=new this;e.keyBinding.addKeyboardHandler(t),e.commands.addCommands(o)},f.uninstallFrom=function(e){e.commands.removeCommands(o);var t=e.getKeyboardHandler();t.isOccurHandler&&e.keyBinding.removeKeyboardHandler(t)},t.occurStartCommand=s}),ace.define("ace/commands/incremental_search_commands",["require","exports","module","ace/config","ace/lib/oop","ace/keyboard/hash_handler","ace/commands/occur_commands"],function(e,t,n){function u(e){this.$iSearch=e}var r=e("../config"),i=e("../lib/oop"),s=e("../keyboard/hash_handler").HashHandler,o=e("./occur_commands").occurStartCommand;t.iSearchStartCommands=[{name:"iSearch",bindKey:{win:"Ctrl-F",mac:"Command-F"},exec:function(e,t){r.loadModule(["core","ace/incremental_search"],function(n){var r=n.iSearch=n.iSearch||new n.IncrementalSearch;r.activate(e,t.backwards),t.jumpToFirstMatch&&r.next(t)})},readOnly:!0},{name:"iSearchBackwards",exec:function(e,t){e.execCommand("iSearch",{backwards:!0})},readOnly:!0},{name:"iSearchAndGo",bindKey:{win:"Ctrl-K",mac:"Command-G"},exec:function(e,t){e.execCommand("iSearch",{jumpToFirstMatch:!0,useCurrentOrPrevSearch:!0})},readOnly:!0},{name:"iSearchBackwardsAndGo",bindKey:{win:"Ctrl-Shift-K",mac:"Command-Shift-G"},exec:function(e){e.execCommand("iSearch",{jumpToFirstMatch:!0,backwards:!0,useCurrentOrPrevSearch:!0})},readOnly:!0}],t.iSearchCommands=[{name:"restartSearch",bindKey:{win:"Ctrl-F",mac:"Command-F"},exec:function(e){e.cancelSearch(!0)},readOnly:!0,isIncrementalSearchCommand:!0},{name:"searchForward",bindKey:{win:"Ctrl-S|Ctrl-K",mac:"Ctrl-S|Command-G"},exec:function(e,t){t.useCurrentOrPrevSearch=!0,e.next(t)},readOnly:!0,isIncrementalSearchCommand:!0},{name:"searchBackward",bindKey:{win:"Ctrl-R|Ctrl-Shift-K",mac:"Ctrl-R|Command-Shift-G"},exec:function(e,t){t.useCurrentOrPrevSearch=!0,t.backwards=!0,e.next(t)},readOnly:!0,isIncrementalSearchCommand:!0},{name:"extendSearchTerm",exec:function(e,t){e.addString(t)},readOnly:!0,isIncrementalSearchCommand:!0},{name:"extendSearchTermSpace",bindKey:"space",exec:function(e){e.addString(" ")},readOnly:!0,isIncrementalSearchCommand:!0},{name:"shrinkSearchTerm",bindKey:"backspace",exec:function(e){e.removeChar()},readOnly:!0,isIncrementalSearchCommand:!0},{name:"confirmSearch",bindKey:"return",exec:function(e){e.deactivate()},readOnly:!0,isIncrementalSearchCommand:!0},{name:"cancelSearch",bindKey:"esc|Ctrl-G",exec:function(e){e.deactivate(!0)},readOnly:!0,isIncrementalSearchCommand:!0},{name:"occurisearch",bindKey:"Ctrl-O",exec:function(e){var t=i.mixin({},e.$options);e.deactivate(),o.exec(e.$editor,t)},readOnly:!0,isIncrementalSearchCommand:!0},{name:"yankNextWord",bindKey:"Ctrl-w",exec:function(e){var t=e.$editor,n=t.selection.getRangeOfMovements(function(e){e.moveCursorWordRight()}),r=t.session.getTextRange(n);e.addString(r)},readOnly:!0,isIncrementalSearchCommand:!0},{name:"yankNextChar",bindKey:"Ctrl-Alt-y",exec:function(e){var t=e.$editor,n=t.selection.getRangeOfMovements(function(e){e.moveCursorRight()}),r=t.session.getTextRange(n);e.addString(r)},readOnly:!0,isIncrementalSearchCommand:!0},{name:"recenterTopBottom",bindKey:"Ctrl-l",exec:function(e){e.$editor.execCommand("recenterTopBottom")},readOnly:!0,isIncrementalSearchCommand:!0}],i.inherits(u,s),function(){this.attach=function(e){var n=this.$iSearch;s.call(this,t.iSearchCommands,e.commands.platform),this.$commandExecHandler=e.commands.addEventListener("exec",function(e){return e.command.isIncrementalSearchCommand?(e.stopPropagation(),e.preventDefault(),e.command.exec(n,e.args||{})):undefined})},this.detach=function(e){if(!this.$commandExecHandler)return;e.commands.removeEventListener("exec",this.$commandExecHandler),delete this.$commandExecHandler};var e=this.handleKeyboard;this.handleKeyboard=function(t,n,r,i){if((n===1||n===8)&&r==="v"||n===1&&r==="y")return null;var s=e.call(this,t,n,r,i);if(s.command)return s;if(n==-1){var o=this.commands.extendSearchTerm;if(o)return{command:o,args:r}}return{command:"null",passEvent:n==0||n==4}}}.call(u.prototype),t.IncrementalSearchKeyboardHandler=u}),ace.define("ace/incremental_search",["require","exports","module","ace/lib/oop","ace/range","ace/search","ace/search_highlight","ace/commands/incremental_search_commands","ace/lib/dom","ace/commands/command_manager","ace/editor","ace/config"],function(e,t,n){"use strict";function f(){this.$options={wrap:!1,skipCurrent:!1},this.$keyboardHandler=new a(this)}var r=e("./lib/oop"),i=e("./range").Range,s=e("./search").Search,o=e("./search_highlight").SearchHighlight,u=e("./commands/incremental_search_commands"),a=u.IncrementalSearchKeyboardHandler;r.inherits(f,s),function(){this.activate=function(e,t){this.$editor=e,this.$startPos=this.$currentPos=e.getCursorPosition(),this.$options.needle="",this.$options.backwards=t,e.keyBinding.addKeyboardHandler(this.$keyboardHandler),this.$originalEditorOnPaste=e.onPaste,e.onPaste=this.onPaste.bind(this),this.$mousedownHandler=e.addEventListener("mousedown",this.onMouseDown.bind(this)),this.selectionFix(e),this.statusMessage(!0)},this.deactivate=function(e){this.cancelSearch(e);var t=this.$editor;t.keyBinding.removeKeyboardHandler(this.$keyboardHandler),this.$mousedownHandler&&(t.removeEventListener("mousedown",this.$mousedownHandler),delete this.$mousedownHandler),t.onPaste=this.$originalEditorOnPaste,this.message("")},this.selectionFix=function(e){e.selection.isEmpty()&&!e.session.$emacsMark&&e.clearSelection()},this.highlight=function(e){var t=this.$editor.session,n=t.$isearchHighlight=t.$isearchHighlight||t.addDynamicMarker(new o(null,"ace_isearch-result","text"));n.setRegexp(e),t._emit("changeBackMarker")},this.cancelSearch=function(e){var t=this.$editor;return this.$prevNeedle=this.$options.needle,this.$options.needle="",e?(t.moveCursorToPosition(this.$startPos),this.$currentPos=this.$startPos):t.pushEmacsMark&&t.pushEmacsMark(this.$startPos,!1),this.highlight(null),i.fromPoints(this.$currentPos,this.$currentPos)},this.highlightAndFindWithNeedle=function(e,t){if(!this.$editor)return null;var n=this.$options;t&&(n.needle=t.call(this,n.needle||"")||"");if(n.needle.length===0)return this.statusMessage(!0),this.cancelSearch(!0);n.start=this.$currentPos;var r=this.$editor.session,s=this.find(r);return s&&(n.backwards&&(s=i.fromPoints(s.end,s.start)),this.$editor.moveCursorToPosition(s.end),e&&(this.$currentPos=s.end),this.highlight(n.re)),this.statusMessage(s),s},this.addString=function(e){return this.highlightAndFindWithNeedle(!1,function(t){return t+e})},this.removeChar=function(e){return this.highlightAndFindWithNeedle(!1,function(e){return e.length>0?e.substring(0,e.length-1):e})},this.next=function(e){return e=e||{},this.$options.backwards=!!e.backwards,this.$currentPos=this.$editor.getCursorPosition(),this.highlightAndFindWithNeedle(!0,function(t){return e.useCurrentOrPrevSearch&&t.length===0?this.$prevNeedle||"":t})},this.onMouseDown=function(e){return this.deactivate(),!0},this.onPaste=function(e){this.addString(e)},this.statusMessage=function(e){var t=this.$options,n="";n+=t.backwards?"reverse-":"",n+="isearch: "+t.needle,n+=e?"":" (not found)",this.message(n)},this.message=function(e){this.$editor.showCommandLine?(this.$editor.showCommandLine(e),this.$editor.focus()):console.log(e)}}.call(f.prototype),t.IncrementalSearch=f;var l=e("./lib/dom");l.importCssString&&l.importCssString(".ace_marker-layer .ace_isearch-result {  position: absolute;  z-index: 6;  -moz-box-sizing: border-box;  -webkit-box-sizing: border-box;  box-sizing: border-box;}div.ace_isearch-result {  border-radius: 4px;  background-color: rgba(255, 200, 0, 0.5);  box-shadow: 0 0 4px rgb(255, 200, 0);}.ace_dark div.ace_isearch-result {  background-color: rgb(100, 110, 160);  box-shadow: 0 0 4px rgb(80, 90, 140);}","incremental-search-highlighting");var c=e("./commands/command_manager");(function(){this.setupIncrementalSearch=function(e,t){if(this.usesIncrementalSearch==t)return;this.usesIncrementalSearch=t;var n=u.iSearchStartCommands,r=t?"addCommands":"removeCommands";this[r](n)}}).call(c.CommandManager.prototype);var h=e("./editor").Editor;e("./config").defineOptions(h.prototype,"editor",{useIncrementalSearch:{set:function(e){this.keyBinding.$handlers.forEach(function(t){t.setupIncrementalSearch&&t.setupIncrementalSearch(this,e)}),this._emit("incrementalSearchSettingChanged",{isEnabled:e})}}})}),ace.define("ace/keyboard/emacs",["require","exports","module","ace/lib/dom","ace/incremental_search","ace/commands/incremental_search_commands","ace/keyboard/hash_handler","ace/lib/keys"],function(e,t,n){"use strict";var r=e("../lib/dom");e("../incremental_search");var i=e("../commands/incremental_search_commands"),s=function(e,t){var n=this.scroller.getBoundingClientRect(),r=Math.floor((e+this.scrollLeft-n.left-this.$padding)/this.characterWidth),i=Math.floor((t+this.scrollTop-n.top)/this.lineHeight);return this.session.screenToDocumentPosition(i,r)},o=e("./hash_handler").HashHandler;t.handler=new o,t.handler.isEmacs=!0,t.handler.$id="ace/keyboard/emacs";var u=!1,a,f;t.handler.attach=function(e){u||(u=!0,r.importCssString("            .emacs-mode .ace_cursor{                border: 2px rgba(50,250,50,0.8) solid!important;                -moz-box-sizing: border-box!important;                -webkit-box-sizing: border-box!important;                box-sizing: border-box!important;                background-color: rgba(0,250,0,0.9);                opacity: 0.5;            }            .emacs-mode .ace_hidden-cursors .ace_cursor{                opacity: 1;                background-color: transparent;            }            .emacs-mode .ace_overwrite-cursors .ace_cursor {                opacity: 1;                background-color: transparent;                border-width: 0 0 2px 2px !important;            }            .emacs-mode .ace_text-layer {                z-index: 4            }            .emacs-mode .ace_cursor-layer {                z-index: 2            }","emacsMode")),a=e.session.$selectLongWords,e.session.$selectLongWords=!0,f=e.session.$useEmacsStyleLineStart,e.session.$useEmacsStyleLineStart=!0,e.session.$emacsMark=null,e.session.$emacsMarkRing=e.session.$emacsMarkRing||[],e.emacsMark=function(){return this.session.$emacsMark},e.setEmacsMark=function(e){this.session.$emacsMark=e},e.pushEmacsMark=function(e,t){var n=this.session.$emacsMark;n&&this.session.$emacsMarkRing.push(n),!e||t?this.setEmacsMark(e):this.session.$emacsMarkRing.push(e)},e.popEmacsMark=function(){var e=this.emacsMark();return e?(this.setEmacsMark(null),e):this.session.$emacsMarkRing.pop()},e.getLastEmacsMark=function(e){return this.session.$emacsMark||this.session.$emacsMarkRing.slice(-1)[0]},e.on("click",c),e.on("changeSession",l),e.renderer.screenToTextCoordinates=s,e.setStyle("emacs-mode"),e.commands.addCommands(v),t.handler.platform=e.commands.platform,e.$emacsModeHandler=this,e.addEventListener("copy",this.onCopy),e.addEventListener("paste",this.onPaste)},t.handler.detach=function(e){delete e.renderer.screenToTextCoordinates,e.session.$selectLongWords=a,e.session.$useEmacsStyleLineStart=f,e.removeEventListener("click",c),e.removeEventListener("changeSession",l),e.unsetStyle("emacs-mode"),e.commands.removeCommands(v),e.removeEventListener("copy",this.onCopy),e.removeEventListener("paste",this.onPaste)};var l=function(e){e.oldSession&&(e.oldSession.$selectLongWords=a,e.oldSession.$useEmacsStyleLineStart=f),a=e.session.$selectLongWords,e.session.$selectLongWords=!0,f=e.session.$useEmacsStyleLineStart,e.session.$useEmacsStyleLineStart=!0,e.session.hasOwnProperty("$emacsMark")||(e.session.$emacsMark=null),e.session.hasOwnProperty("$emacsMarkRing")||(e.session.$emacsMarkRing=[])},c=function(e){e.editor.session.$emacsMark=null},h=e("../lib/keys").KEY_MODS,p={C:"ctrl",S:"shift",M:"alt",CMD:"command"},d=["C-S-M-CMD","S-M-CMD","C-M-CMD","C-S-CMD","C-S-M","M-CMD","S-CMD","S-M","C-CMD","C-M","C-S","CMD","M","S","C"];d.forEach(function(e){var t=0;e.split("-").forEach(function(e){t|=h[p[e]]}),p[t]=e.toLowerCase()+"-"}),t.handler.onCopy=function(e,n){if(n.$handlesEmacsOnCopy)return;n.$handlesEmacsOnCopy=!0,t.handler.commands.killRingSave.exec(n),delete n.$handlesEmacsOnCopy},t.handler.onPaste=function(e,t){t.pushEmacsMark(t.getCursorPosition())},t.handler.bindKey=function(e,t){if(!e)return;var n=this.commandKeyBinding;e.split("|").forEach(function(e){e=e.toLowerCase(),n[e]=t;var r=e.split(" ").slice(0,-1);r.reduce(function(e,t,n){var r=e[n-1]?e[n-1]+" ":"";return e.concat([r+t])},[]).forEach(function(e){n[e]||(n[e]="null")})},this)},t.handler.handleKeyboard=function(e,t,n,r){if(r===-1)return undefined;var i=e.editor;if(t==-1){i.pushEmacsMark();if(e.count){var s=(new Array(e.count+1)).join(n);return e.count=null,{command:"insertstring",args:s}}}if(n=="\0")return undefined;var o=p[t];if(o=="c-"||e.universalArgument){var u=String(e.count||0),a=parseInt(n[n.length-1]);if(typeof a=="number"&&!isNaN(a))return e.count=parseInt(u+a),{command:"null"};e.universalArgument&&(e.count=4)}e.universalArgument=!1,o&&(n=o+n),e.keyChain&&(n=e.keyChain+=" "+n);var f=this.commandKeyBinding[n];e.keyChain=f=="null"?n:"";if(!f)return undefined;if(f==="null")return{command:"null"};if(f==="universalArgument")return e.universalArgument=!0,{command:"null"};var l;typeof f!="string"&&(l=f.args,f.command&&(f=f.command),f==="goorselect"&&(f=i.emacsMark()?l[1]:l[0],l=null));if(typeof f=="string"){(f==="insertstring"||f==="splitline"||f==="togglecomment")&&i.pushEmacsMark(),f=this.commands[f]||i.commands.commands[f];if(!f)return undefined}!f.readonly&&!f.isYank&&(e.lastCommand=null);if(e.count){var a=e.count;e.count=0;if(!f||!f.handlesCount)return{args:l,command:{exec:function(e,t){for(var n=0;n<a;n++)f.exec(e,t)}}};l||(l={}),typeof l=="object"&&(l.count=a)}return{command:f,args:l}},t.emacsKeys={"Up|C-p":{command:"goorselect",args:["golineup","selectup"]},"Down|C-n":{command:"goorselect",args:["golinedown","selectdown"]},"Left|C-b":{command:"goorselect",args:["gotoleft","selectleft"]},"Right|C-f":{command:"goorselect",args:["gotoright","selectright"]},"C-Left|M-b":{command:"goorselect",args:["gotowordleft","selectwordleft"]},"C-Right|M-f":{command:"goorselect",args:["gotowordright","selectwordright"]},"Home|C-a":{command:"goorselect",args:["gotolinestart","selecttolinestart"]},"End|C-e":{command:"goorselect",args:["gotolineend","selecttolineend"]},"C-Home|S-M-,":{command:"goorselect",args:["gotostart","selecttostart"]},"C-End|S-M-.":{command:"goorselect",args:["gotoend","selecttoend"]},"S-Up|S-C-p":"selectup","S-Down|S-C-n":"selectdown","S-Left|S-C-b":"selectleft","S-Right|S-C-f":"selectright","S-C-Left|S-M-b":"selectwordleft","S-C-Right|S-M-f":"selectwordright","S-Home|S-C-a":"selecttolinestart","S-End|S-C-e":"selecttolineend","S-C-Home":"selecttostart","S-C-End":"selecttoend","C-l":"recenterTopBottom","M-s":"centerselection","M-g":"gotoline","C-x C-p":"selectall","C-Down":{command:"goorselect",args:["gotopagedown","selectpagedown"]},"C-Up":{command:"goorselect",args:["gotopageup","selectpageup"]},"PageDown|C-v":{command:"goorselect",args:["gotopagedown","selectpagedown"]},"PageUp|M-v":{command:"goorselect",args:["gotopageup","selectpageup"]},"S-C-Down":"selectpagedown","S-C-Up":"selectpageup","C-s":"iSearch","C-r":"iSearchBackwards","M-C-s":"findnext","M-C-r":"findprevious","S-M-5":"replace",Backspace:"backspace","Delete|C-d":"del","Return|C-m":{command:"insertstring",args:"\n"},"C-o":"splitline","M-d|C-Delete":{command:"killWord",args:"right"},"C-Backspace|M-Backspace|M-Delete":{command:"killWord",args:"left"},"C-k":"killLine","C-y|S-Delete":"yank","M-y":"yankRotate","C-g":"keyboardQuit","C-w":"killRegion","M-w":"killRingSave","C-Space":"setMark","C-x C-x":"exchangePointAndMark","C-t":"transposeletters","M-u":"touppercase","M-l":"tolowercase","M-/":"autocomplete","C-u":"universalArgument","M-;":"togglecomment","C-/|C-x u|S-C--|C-z":"undo","S-C-/|S-C-x u|C--|S-C-z":"redo","C-x r":"selectRectangularRegion","M-x":{command:"focusCommandLine",args:"M-x "}},t.handler.bindKeys(t.emacsKeys),t.handler.addCommands({recenterTopBottom:function(e){var t=e.renderer,n=t.$cursorLayer.getPixelPosition(),r=t.$size.scrollerHeight-t.lineHeight,i=t.scrollTop;Math.abs(n.top-i)<2?i=n.top-r:Math.abs(n.top-i-r*.5)<2?i=n.top:i=n.top-r*.5,e.session.setScrollTop(i)},selectRectangularRegion:function(e){e.multiSelect.toggleBlockSelection()},setMark:{exec:function(e,t){if(t&&t.count){var n=e.popEmacsMark();n&&e.selection.moveCursorToPosition(n);return}var n=e.emacsMark(),r=!0;if(r&&(n||!e.selection.isEmpty())){e.pushEmacsMark(),e.clearSelection();return}if(n){var i=e.getCursorPosition();if(e.selection.isEmpty()&&n.row==i.row&&n.column==i.column){e.pushEmacsMark();return}}n=e.getCursorPosition(),e.setEmacsMark(n),e.selection.setSelectionAnchor(n.row,n.column)},readonly:!0,handlesCount:!0,multiSelectAction:"forEach"},exchangePointAndMark:{exec:function(e,t){var n=e.selection;if(t.count){var r=e.getCursorPosition();n.clearSelection(),n.moveCursorToPosition(e.popEmacsMark()),e.pushEmacsMark(r);return}var i=e.getLastEmacsMark(),s=n.getRange();if(s.isEmpty()){n.selectToPosition(i);return}n.setSelectionRange(s,!n.isBackwards())},readonly:!0,handlesCount:!0,multiSelectAction:"forEach"},killWord:{exec:function(e,n){e.clearSelection(),n=="left"?e.selection.selectWordLeft():e.selection.selectWordRight();var r=e.getSelectionRange(),i=e.session.getTextRange(r);t.killRing.add(i),e.session.remove(r),e.clearSelection()},multiSelectAction:"forEach"},killLine:function(e){e.pushEmacsMark(null);var n=e.getCursorPosition();n.column===0&&e.session.doc.getLine(n.row).length===0?e.selection.selectLine():(e.clearSelection(),e.selection.selectLineEnd());var r=e.getSelectionRange(),i=e.session.getTextRange(r);t.killRing.add(i),e.session.remove(r),e.clearSelection()},yank:function(e){e.onPaste(t.killRing.get()||""),e.keyBinding.$data.lastCommand="yank"},yankRotate:function(e){if(e.keyBinding.$data.lastCommand!="yank")return;e.undo(),e.onPaste(t.killRing.rotate()),e.keyBinding.$data.lastCommand="yank"},killRegion:{exec:function(e){t.killRing.add(e.getCopyText()),e.commands.byName.cut.exec(e)},readonly:!0,multiSelectAction:"forEach"},killRingSave:{exec:function(e){t.killRing.add(e.getCopyText()),setTimeout(function(){var t=e.selection,n=t.getRange();e.pushEmacsMark(t.isBackwards()?n.end:n.start),t.clearSelection()},0)},readonly:!0},keyboardQuit:function(e){e.selection.clearSelection(),e.setEmacsMark(null)},focusCommandLine:function(e,t){e.showCommandLine&&e.showCommandLine(t)}}),t.handler.addCommands(i.iSearchStartCommands);var v=t.handler.commands;v.yank.isYank=!0,v.yankRotate.isYank=!0,t.killRing={$data:[],add:function(e){e&&this.$data.push(e),this.$data.length>30&&this.$data.shift()},get:function(e){return e=e||1,this.$data.slice(this.$data.length-e,this.$data.length).reverse().join("\n")},pop:function(){return this.$data.length>1&&this.$data.pop(),this.get()},rotate:function(){return this.$data.unshift(this.$data.pop()),this.get()}}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/keybinding-vim.js b/dist/assets/js/vendor/ace-nc/keybinding-vim.js
            new file mode 100644
            index 0000000000..01ab7ed3ae
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/keybinding-vim.js
            @@ -0,0 +1 @@
            +ace.define("ace/keyboard/vim/registers",["require","exports","module"],function(e,t,n){"never use strict";n.exports={_default:{text:"",isLine:!1}}}),ace.define("ace/keyboard/vim/maps/util",["require","exports","module","ace/keyboard/vim/registers","ace/lib/dom"],function(e,t,n){var r=e("../registers"),i=e("../../../lib/dom");i.importCssString(".insert-mode .ace_cursor{    border-left: 2px solid #333333;}.ace_dark.insert-mode .ace_cursor{    border-left: 2px solid #eeeeee;}.normal-mode .ace_cursor{    border: 0!important;    background-color: red;    opacity: 0.5;}","vimMode"),n.exports={onVisualMode:!1,onVisualLineMode:!1,currentMode:"normal",noMode:function(e){e.unsetStyle("insert-mode"),e.unsetStyle("normal-mode"),e.commands.recording&&e.commands.toggleRecording(e),e.setOverwrite(!1)},insertMode:function(e){this.currentMode="insert",e.setStyle("insert-mode"),e.unsetStyle("normal-mode"),e.setOverwrite(!1),e.keyBinding.$data.buffer="",e.keyBinding.$data.vimState="insertMode",this.onVisualMode=!1,this.onVisualLineMode=!1,this.onInsertReplaySequence?(e.commands.macro=this.onInsertReplaySequence,e.commands.replay(e),this.onInsertReplaySequence=null,this.normalMode(e)):(e._emit("changeStatus"),e.commands.recording||e.commands.toggleRecording(e))},normalMode:function(e){this.currentMode="normal",e.unsetStyle("insert-mode"),e.setStyle("normal-mode"),e.clearSelection();var t;return e.getOverwrite()||(t=e.getCursorPosition(),t.column>0&&e.navigateLeft()),e.setOverwrite(!0),e.keyBinding.$data.buffer="",e.keyBinding.$data.vimState="start",this.onVisualMode=!1,this.onVisualLineMode=!1,e._emit("changeStatus"),e.commands.recording?(e.commands.toggleRecording(e),e.commands.macro):[]},visualMode:function(e,t){if(this.onVisualLineMode&&t||this.onVisualMode&&!t){this.normalMode(e);return}e.setStyle("insert-mode"),e.unsetStyle("normal-mode"),e._emit("changeStatus"),t?this.onVisualLineMode=!0:(this.onVisualMode=!0,this.onVisualLineMode=!1)},getRightNthChar:function(e,t,n,r){var i=e.getSession().getLine(t.row),s=i.substr(t.column+1).split(n);return r<s.length?s.slice(0,r).join(n).length:null},getLeftNthChar:function(e,t,n,r){var i=e.getSession().getLine(t.row),s=i.substr(0,t.column).split(n);return r<s.length?s.slice(-1*r).join(n).length:null},toRealChar:function(e){return e.length===1?e:/^shift-./.test(e)?e[e.length-1].toUpperCase():""},copyLine:function(e){var t=e.getCursorPosition();e.selection.moveTo(t.row,t.column),e.selection.selectLine(),r._default.isLine=!0,r._default.text=e.getCopyText().replace(/\n$/,""),e.selection.moveTo(t.row,t.column)}}}),ace.define("ace/keyboard/vim/maps/motions",["require","exports","module","ace/keyboard/vim/maps/util","ace/search","ace/range"],function(e,t,n){"use strict";function s(e){if(typeof e=="function"){var t=e;e=this}else var t=e.getPos;return e.nav=function(e,n,r,i){var s=t(e,n,r,i,!1);if(!s)return;e.selection.moveTo(s.row,s.column)},e.sel=function(e,n,r,i){var s=t(e,n,r,i,!0);if(!s)return;e.selection.selectTo(s.row,s.column)},e}function h(e,t,n){return c.$options.needle=t,c.$options.backwards=n==-1,c.find(e.session)}var r=e("./util"),i=function(e,t){var n=e.renderer.getScrollTopRow(),r=e.getCursorPosition().row,i=r-n;t&&t.call(e),e.renderer.scrollToRow(e.getCursorPosition().row-i)},o=/[\s.\/\\()\"'-:,.;<>~!@#$%^&*|+=\[\]{}`~?]/,u=/[.\/\\()\"'-:,.;<>~!@#$%^&*|+=\[\]{}`~?]/,a=/\s/,f=function(e,t){var n=e.selection;this.range=n.getRange(),t=t||n.selectionLead,this.row=t.row,this.col=t.column;var r=e.session.getLine(this.row),i=e.session.getLength();this.ch=r[this.col]||"\n",this.skippedLines=0,this.next=function(){return this.ch=r[++this.col]||this.handleNewLine(1),this.ch},this.prev=function(){return this.ch=r[--this.col]||this.handleNewLine(-1),this.ch},this.peek=function(t){var n=r[this.col+t];return n?n:t==-1?"\n":this.col==r.length-1?"\n":e.session.getLine(this.row+1)[0]||"\n"},this.handleNewLine=function(t){if(t==1)return this.col==r.length?"\n":this.row==i-1?"":(this.col=0,this.row++,r=e.session.getLine(this.row),this.skippedLines++,r[0]||"\n");if(t==-1)return this.row===0?"":(this.row--,r=e.session.getLine(this.row),this.col=r.length,this.skippedLines--,"\n")},this.debug=function(){console.log(r.substring(0,this.col)+"|"+this.ch+"'"+this.col+"'"+r.substr(this.col+1))}},l=e("../../../search").Search,c=new l,p=e("../../../range").Range,d={};n.exports={w:new s(function(e){var t=new f(e);if(t.ch&&u.test(t.ch))while(t.ch&&u.test(t.ch))t.next();else while(t.ch&&!o.test(t.ch))t.next();while(t.ch&&a.test(t.ch)&&t.skippedLines<2)t.next();return t.skippedLines==2&&t.prev(),{column:t.col,row:t.row}}),W:new s(function(e){var t=new f(e);while(t.ch&&(!a.test(t.ch)||!!a.test(t.peek(1)))&&t.skippedLines<2)t.next();return t.skippedLines==2?t.prev():t.next(),{column:t.col,row:t.row}}),b:new s(function(e){var t=new f(e);t.prev();while(t.ch&&a.test(t.ch)&&t.skippedLines>-2)t.prev();if(t.ch&&u.test(t.ch))while(t.ch&&u.test(t.ch))t.prev();else while(t.ch&&!o.test(t.ch))t.prev();return t.ch&&t.next(),{column:t.col,row:t.row}}),B:new s(function(e){var t=new f(e);t.prev();while(t.ch&&(!!a.test(t.ch)||!a.test(t.peek(-1)))&&t.skippedLines>-2)t.prev();return t.skippedLines==-2&&t.next(),{column:t.col,row:t.row}}),e:new s(function(e){var t=new f(e);t.next();while(t.ch&&a.test(t.ch))t.next();if(t.ch&&u.test(t.ch))while(t.ch&&u.test(t.ch))t.next();else while(t.ch&&!o.test(t.ch))t.next();return t.ch&&t.prev(),{column:t.col,row:t.row}}),E:new s(function(e){var t=new f(e);t.next();while(t.ch&&(!!a.test(t.ch)||!a.test(t.peek(1))))t.next();return{column:t.col,row:t.row}}),l:{nav:function(e){var t=e.getCursorPosition(),n=t.column,r=e.session.getLine(t.row).length;r&&n!==r&&e.navigateRight()},sel:function(e){var t=e.getCursorPosition(),n=t.column,r=e.session.getLine(t.row).length;r&&n!==r&&e.selection.selectRight()}},h:{nav:function(e){var t=e.getCursorPosition();t.column>0&&e.navigateLeft()},sel:function(e){var t=e.getCursorPosition();t.column>0&&e.selection.selectLeft()}},H:{nav:function(e){var t=e.renderer.getScrollTopRow();e.moveCursorTo(t)},sel:function(e){var t=e.renderer.getScrollTopRow();e.selection.selectTo(t)}},M:{nav:function(e){var t=e.renderer.getScrollTopRow(),n=e.renderer.getScrollBottomRow(),r=t+(n-t)/2;e.moveCursorTo(r)},sel:function(e){var t=e.renderer.getScrollTopRow(),n=e.renderer.getScrollBottomRow(),r=t+(n-t)/2;e.selection.selectTo(r)}},L:{nav:function(e){var t=e.renderer.getScrollBottomRow();e.moveCursorTo(t)},sel:function(e){var t=e.renderer.getScrollBottomRow();e.selection.selectTo(t)}},k:{nav:function(e){e.navigateUp()},sel:function(e){e.selection.selectUp()}},j:{nav:function(e){e.navigateDown()},sel:function(e){e.selection.selectDown()}},i:{param:!0,sel:function(e,t,n,r){switch(r){case"w":e.selection.selectWord();break;case"W":e.selection.selectAWord();break;case"(":case"{":case"[":var i=e.getCursorPosition(),s=e.session.$findClosingBracket(r,i,/paren/);if(!s)return;var o=e.session.$findOpeningBracket(e.session.$brackets[r],i,/paren/);if(!o)return;o.column++,e.selection.setSelectionRange(p.fromPoints(o,s));break;case"'":case'"':case"/":var s=h(e,r,1);if(!s)return;var o=h(e,r,-1);if(!o)return;e.selection.setSelectionRange(p.fromPoints(o.end,s.start))}}},a:{param:!0,sel:function(e,t,n,r){switch(r){case"w":e.selection.selectAWord();break;case"W":e.selection.selectAWord();break;case")":case"}":case"]":r=e.session.$brackets[r];case"(":case"{":case"[":var i=e.getCursorPosition(),s=e.session.$findClosingBracket(r,i,/paren/);if(!s)return;var o=e.session.$findOpeningBracket(e.session.$brackets[r],i,/paren/);if(!o)return;s.column++,e.selection.setSelectionRange(p.fromPoints(o,s));break;case"'":case'"':case"/":var s=h(e,r,1);if(!s)return;var o=h(e,r,-1);if(!o)return;s.column++,e.selection.setSelectionRange(p.fromPoints(o.start,s.end))}}},f:new s({param:!0,handlesCount:!0,getPos:function(e,t,n,i,s,o){i=="space"&&(i=" "),o||(d={ch:"f",param:i});var u=e.getCursorPosition(),a=r.getRightNthChar(e,u,i,n||1);if(typeof a=="number")return u.column+=a+(s?2:1),u}}),F:new s({param:!0,handlesCount:!0,getPos:function(e,t,n,i,s,o){i=="space"&&(i=" "),o||(d={ch:"F",param:i});var u=e.getCursorPosition(),a=r.getLeftNthChar(e,u,i,n||1);if(typeof a=="number")return u.column-=a+1,u}}),t:new s({param:!0,handlesCount:!0,getPos:function(e,t,n,i,s,o){i=="space"&&(i=" "),o||(d={ch:"t",param:i});var u=e.getCursorPosition(),a=r.getRightNthChar(e,u,i,n||1);if(o&&a==0&&!(n>1))var a=r.getRightNthChar(e,u,i,2);if(typeof a=="number")return u.column+=a+(s?1:0),u}}),T:new s({param:!0,handlesCount:!0,getPos:function(e,t,n,i,s,o){i=="space"&&(i=" "),o||(d={ch:"T",param:i});var u=e.getCursorPosition(),a=r.getLeftNthChar(e,u,i,n||1);if(o&&a==0&&!(n>1))var a=r.getLeftNthChar(e,u,i,2);if(typeof a=="number")return u.column-=a,u}}),";":new s({handlesCount:!0,getPos:function(e,t,r,i,s){var o=d.ch;if(!o)return;return n.exports[o].getPos(e,t,r,d.param,s,!0)}}),",":new s({handlesCount:!0,getPos:function(e,t,r,i,s){var o=d.ch;if(!o)return;var u=o.toUpperCase();return o=o===u?o.toLowerCase():u,n.exports[o].getPos(e,t,r,d.param,s,!0)}}),"^":{nav:function(e){e.navigateLineStart()},sel:function(e){e.selection.selectLineStart()}},$:{handlesCount:!0,nav:function(e,t,n,r){n>1&&e.navigateDown(n-1),e.navigateLineEnd()},sel:function(e,t,n,r){n>1&&e.selection.moveCursorBy(n-1,0),e.selection.selectLineEnd()}},0:new s(function(e){return{row:e.selection.lead.row,column:0}}),G:{nav:function(e,t,n,r){!n&&n!==0&&(n=e.session.getLength()),e.gotoLine(n)},sel:function(e,t,n,r){!n&&n!==0&&(n=e.session.getLength()),e.selection.selectTo(n,0)}},g:{param:!0,nav:function(e,t,n,r){switch(r){case"m":console.log("Middle line");break;case"e":console.log("End of prev word");break;case"g":e.gotoLine(n||0);case"u":e.gotoLine(n||0);case"U":e.gotoLine(n||0)}},sel:function(e,t,n,r){switch(r){case"m":console.log("Middle line");break;case"e":console.log("End of prev word");break;case"g":e.selection.selectTo(n||0,0)}}},o:{nav:function(e,t,n,i){n=n||1;var s="";while(0<n--)s+="\n";s.length&&(e.navigateLineEnd(),e.insert(s),r.insertMode(e))}},O:{nav:function(e,t,n,i){var s=e.getCursorPosition().row;n=n||1;var o="";while(0<n--)o+="\n";o.length&&(s>0?(e.navigateUp(),e.navigateLineEnd(),e.insert(o)):(e.session.insert({row:0,column:0},o),e.navigateUp()),r.insertMode(e))}},"%":new s(function(e){var t=/[\[\]{}()]/g,n=e.getCursorPosition(),r=e.session.getLine(n.row)[n.column];if(!t.test(r)){var i=h(e,t);if(!i)return;n=i.start}var s=e.session.findMatchingBracket({row:n.row,column:n.column+1});return s}),"{":new s(function(e){var t=e.session,n=t.selection.lead.row;while(n>0&&!/\S/.test(t.getLine(n)))n--;while(/\S/.test(t.getLine(n)))n--;return{column:0,row:n}}),"}":new s(function(e){var t=e.session,n=t.getLength(),r=t.selection.lead.row;while(r<n&&!/\S/.test(t.getLine(r)))r++;while(/\S/.test(t.getLine(r)))r++;return{column:0,row:r}}),"ctrl-d":{nav:function(e,t,n,r){e.selection.clearSelection(),i(e,e.gotoPageDown)},sel:function(e,t,n,r){i(e,e.selectPageDown)}},"ctrl-u":{nav:function(e,t,n,r){e.selection.clearSelection(),i(e,e.gotoPageUp)},sel:function(e,t,n,r){i(e,e.selectPageUp)}},"`":new s({param:!0,handlesCount:!0,getPos:function(e,t,n,r,i){var s=e.session,o=s.vimMarkers&&s.vimMarkers[r];if(o)return o.getPosition()}}),"'":new s({param:!0,handlesCount:!0,getPos:function(e,t,n,r,i){var s=e.session,o=s.vimMarkers&&s.vimMarkers[r];if(o){var u=o.getPosition(),a=e.session.getLine(u.row);return u.column=a.search(/\S/),u.column==-1&&(u.column=a.length),u}},isLine:!0})},n.exports.backspace=n.exports.left=n.exports.h,n.exports.space=n.exports["return"]=n.exports.right=n.exports.l,n.exports.up=n.exports.k,n.exports.down=n.exports.j,n.exports.pagedown=n.exports["ctrl-d"],n.exports.pageup=n.exports["ctrl-u"],n.exports.home=n.exports[0],n.exports.end=n.exports.$}),ace.define("ace/keyboard/vim/maps/operators",["require","exports","module","ace/keyboard/vim/maps/util","ace/keyboard/vim/registers","ace/range"],function(e,t,n){"use strict";var r=e("./util"),i=e("../registers"),s=e("../../../range").Range;n.exports={d:{selFn:function(e,t,n,s){i._default.text=e.getCopyText(),i._default.isLine=r.onVisualLineMode,r.onVisualLineMode?e.removeLines():e.session.remove(t),r.normalMode(e)},fn:function(e,t,n,r){n=n||1;switch(r){case"d":i._default.text="",i._default.isLine=!0;for(var s=0;s<n;s++){e.selection.selectLine(),i._default.text+=e.getCopyText();var o=e.getSelectionRange();if(!o.isMultiLine()){var u=o.start.row-1,a=e.session.getLine(u).length;o.setStart(u,a),e.session.remove(o),e.selection.clearSelection();break}e.session.remove(o),e.selection.clearSelection()}i._default.text=i._default.text.replace(/\n$/,"");break;default:t&&(e.selection.setSelectionRange(t),i._default.text=e.getCopyText(),i._default.isLine=!1,e.session.remove(t),e.selection.clearSelection())}}},c:{selFn:function(e,t,n,i){e.session.remove(t),r.insertMode(e)},fn:function(e,t,n,i){n=n||1;switch(i){case"c":e.$blockScrolling++,e.selection.$moveSelection(function(){e.selection.moveCursorBy(n-1,0)});var o=e.$getSelectedRows();t=new s(o.first,0,o.last,Infinity),e.session.remove(t),e.$blockScrolling--,r.insertMode(e);break;default:t&&(e.session.remove(t),r.insertMode(e))}}},y:{selFn:function(e,t,n,s){i._default.text=e.getCopyText(),i._default.isLine=r.onVisualLineMode,e.selection.clearSelection(),r.normalMode(e)},fn:function(e,t,n,r){n=n||1,r&&r.isLine&&(r="y");switch(r){case"y":var s=e.getCursorPosition();e.selection.selectLine();for(var o=0;o<n-1;o++)e.selection.moveCursorDown();i._default.text=e.getCopyText().replace(/\n$/,""),e.selection.clearSelection(),i._default.isLine=!0,e.moveCursorToPosition(s);break;default:if(t){var s=e.getCursorPosition();e.selection.setSelectionRange(t),i._default.text=e.getCopyText(),i._default.isLine=!1,e.selection.clearSelection(),e.moveCursorTo(s.row,s.column)}}}},">":{selFn:function(e,t,n,i){n=n||1;for(var s=0;s<n;s++)e.indent();r.normalMode(e)},fn:function(e,t,n,r){n=parseInt(n||1,10);switch(r){case">":var i=e.getCursorPosition();e.selection.selectLine();for(var s=0;s<n-1;s++)e.selection.moveCursorDown();e.indent(),e.selection.clearSelection(),e.moveCursorToPosition(i),e.navigateLineEnd(),e.navigateLineStart()}}},"<":{selFn:function(e,t,n,i){n=n||1;for(var s=0;s<n;s++)e.blockOutdent();r.normalMode(e)},fn:function(e,t,n,r){n=n||1;switch(r){case"<":var i=e.getCursorPosition();e.selection.selectLine();for(var s=0;s<n-1;s++)e.selection.moveCursorDown();e.blockOutdent(),e.selection.clearSelection(),e.moveCursorToPosition(i),e.navigateLineEnd(),e.navigateLineStart()}}}}}),"use strict",ace.define("ace/keyboard/vim/maps/aliases",["require","exports","module"],function(e,t,n){n.exports={x:{operator:{ch:"d",count:1},motion:{ch:"l",count:1}},X:{operator:{ch:"d",count:1},motion:{ch:"h",count:1}},D:{operator:{ch:"d",count:1},motion:{ch:"$",count:1}},C:{operator:{ch:"c",count:1},motion:{ch:"$",count:1}},s:{operator:{ch:"c",count:1},motion:{ch:"l",count:1}},S:{operator:{ch:"c",count:1},param:"c"}}}),ace.define("ace/keyboard/vim/commands",["require","exports","module","ace/lib/lang","ace/keyboard/vim/maps/util","ace/keyboard/vim/maps/motions","ace/keyboard/vim/maps/operators","ace/keyboard/vim/maps/aliases","ace/keyboard/vim/registers"],function(e,t,n){"never use strict";function y(e){g.previous={action:{action:{fn:e}}}}var r=e("../../lib/lang"),i=e("./maps/util"),s=e("./maps/motions"),o=e("./maps/operators"),u=e("./maps/aliases"),a=e("./registers"),f=1,l=2,c=3,h=4,p=8,d=function(t,n,r){while(0<n--)t.apply(this,r)},v=function(e){var t=e.renderer,n=t.$cursorLayer.getPixelPosition(),r=n.top,i=p*t.layerConfig.lineHeight;2*i>t.$size.scrollerHeight&&(i=t.$size.scrollerHeight/2),t.scrollTop>r-i&&t.session.setScrollTop(r-i),t.scrollTop+t.$size.scrollerHeight<r+i+t.lineHeight&&t.session.setScrollTop(r+i+t.lineHeight-t.$size.scrollerHeight)},m=t.actions={z:{param:!0,fn:function(e,t,n,r){switch(r){case"z":e.renderer.alignCursor(null,.5);break;case"t":e.renderer.alignCursor(null,0);break;case"b":e.renderer.alignCursor(null,1);break;case"c":e.session.onFoldWidgetClick(t.start.row,{domEvent:{target:{}}});break;case"o":e.session.onFoldWidgetClick(t.start.row,{domEvent:{target:{}}});break;case"C":e.session.foldAll();break;case"O":e.session.unfold()}}},r:{param:!0,fn:function(e,t,n,r){r&&r.length&&(r.length>1&&(r=r=="return"?"\n":r=="tab"?"	":r),d(function(){e.insert(r)},n||1),e.navigateLeft())}},R:{fn:function(e,t,n,r){i.insertMode(e),e.setOverwrite(!0)}},"~":{fn:function(e,t,n){d(function(){var t=e.selection.getRange();t.isEmpty()&&t.end.column++;var n=e.session.getTextRange(t),r=n.toUpperCase();r!=n?e.session.replace(t,r):n.toLowerCase()!=n?e.session.replace(t,n.toLowerCase()):e.navigateRight()},n||1)}},"*":{fn:function(e,t,n,r){e.selection.selectWord(),e.findNext(),v(e);var i=e.selection.getRange();e.selection.setSelectionRange(i,!0)}},"#":{fn:function(e,t,n,r){e.selection.selectWord(),e.findPrevious(),v(e);var i=e.selection.getRange();e.selection.setSelectionRange(i,!0)}},m:{param:!0,fn:function(e,t,n,r){var i=e.session,s=i.vimMarkers||(i.vimMarkers={}),o=e.getCursorPosition();s[r]||(s[r]=e.session.doc.createAnchor(o)),s[r].setPosition(o.row,o.column,!0)}},n:{fn:function(e,t,n,r){var i=e.getLastSearchOptions();i.backwards=!1,i.start=null,e.selection.moveCursorRight(),e.selection.clearSelection(),e.findNext(i),v(e);var s=e.selection.getRange();s.end.row=s.start.row,s.end.column=s.start.column,e.selection.setSelectionRange(s,!0)}},N:{fn:function(e,t,n,r){var i=e.getLastSearchOptions();i.backwards=!0,i.start=null,e.findPrevious(i),v(e);var s=e.selection.getRange();s.end.row=s.start.row,s.end.column=s.start.column,e.selection.setSelectionRange(s,!0)}},v:{fn:function(e,t,n,r){e.selection.selectRight(),i.visualMode(e,!1)},acceptsMotion:!0},V:{fn:function(e,t,n,r){var s=e.getCursorPosition().row;e.selection.moveTo(s,0),e.selection.selectLineEnd(),e.selection.visualLineStart=s,i.visualMode(e,!0)},acceptsMotion:!0},Y:{fn:function(e,t,n,r){i.copyLine(e)}},p:{fn:function(e,t,n,i){var s=a._default;e.setOverwrite(!1);if(s.isLine){var o=e.getCursorPosition();o.column=e.session.getLine(o.row).length;var u=r.stringRepeat("\n"+s.text,n||1);e.session.insert(o,u),e.moveCursorTo(o.row+1,0)}else e.navigateRight(),e.insert(r.stringRepeat(s.text,n||1)),e.navigateLeft();e.setOverwrite(!0),e.selection.clearSelection()}},P:{fn:function(e,t,n,i){var s=a._default;e.setOverwrite(!1);if(s.isLine){var o=e.getCursorPosition();o.column=0;var u=r.stringRepeat(s.text+"\n",n||1);e.session.insert(o,u),e.moveCursorToPosition(o)}else e.insert(r.stringRepeat(s.text,n||1));e.setOverwrite(!0),e.selection.clearSelection()}},J:{fn:function(e,t,n,r){var i=e.session;t=e.getSelectionRange();var s={row:t.start.row,column:t.start.column};n=n||t.end.row-t.start.row;var o=Math.min(s.row+(n||1),i.getLength()-1);t.start.column=i.getLine(s.row).length,t.end.column=i.getLine(o).length,t.end.row=o;var u="";for(var a=s.row;a<o;a++){var f=i.getLine(a+1);u+=" "+/^\s*(.*)$/.exec(f)[1]||""}i.replace(t,u),e.moveCursorTo(s.row,s.column)}},u:{fn:function(e,t,n,r){n=parseInt(n||1,10);for(var i=0;i<n;i++)e.undo();e.selection.clearSelection()}},"ctrl-r":{fn:function(e,t,n,r){n=parseInt(n||1,10);for(var i=0;i<n;i++)e.redo();e.selection.clearSelection()}},":":{fn:function(e,t,n,r){var i=":";n>1&&(i=".,.+"+n+i),e.showCommandLine&&e.showCommandLine(i)}},"/":{fn:function(e,t,n,r){e.showCommandLine&&e.showCommandLine("/")}},"?":{fn:function(e,t,n,r){e.showCommandLine&&e.showCommandLine("?")}},".":{fn:function(e,t,n,r){i.onInsertReplaySequence=g.lastInsertCommands;var s=g.previous;s&&g.exec(e,s.action,s.param)}},"ctrl-x":{fn:function(e,t,n,r){e.modifyNumber(-(n||1))}},"ctrl-a":{fn:function(e,t,n,r){e.modifyNumber(n||1)}}},g=t.inputBuffer={accepting:[f,l,c,h],currentCmd:null,currentCount:"",pendingCount:"",status:"",operator:null,motion:null,lastInsertCommands:[],push:function(e,t,n){var r=this.status,i=!0;this.idle=!1;var a=this.waitingForParam;/^numpad\d+$/i.test(t)&&(t=t.substr(6));if(a)this.exec(e,a,t);else if(t==="0"&&!this.currentCount.length||!/^\d+$/.test(t)||!this.isAccepting(f))if(!this.operator&&this.isAccepting(l)&&o[t])this.operator={ch:t,count:this.getCount()},this.currentCmd=l,this.accepting=[f,c,h],this.exec(e,{operator:this.operator});else if(s[t]&&this.isAccepting(c)){this.currentCmd=c;var p={operator:this.operator,motion:{ch:t,count:this.getCount()}};s[t].param?this.waitForParam(p):this.exec(e,p)}else if(u[t]&&this.isAccepting(c))u[t].operator.count=this.getCount(),this.exec(e,u[t]);else if(m[t]&&this.isAccepting(h)){var d={action:{fn:m[t].fn,count:this.getCount()}};m[t].param?this.waitForParam(d):this.exec(e,d),m[t].acceptsMotion&&(this.idle=!1)}else this.operator?(this.operator.count=this.getCount(),this.exec(e,{operator:this.operator},t)):(i=t.length==1,this.reset());else this.currentCount+=t,this.currentCmd=f,this.accepting=[f,l,c,h];return this.waitingForParam||this.motion||this.operator?this.status+=t:this.currentCount?this.status=this.currentCount:this.status&&(this.status=""),this.status!=r&&e._emit("changeStatus"),i},waitForParam:function(e){this.waitingForParam=e},getCount:function(){var e=this.currentCount||this.pendingCount;return this.currentCount="",this.pendingCount=e,e&&parseInt(e,10)},exec:function(e,t,n){var r=t.motion,u=t.operator,a=t.action;n||(n=t.param),u&&(this.previous={action:t,param:n});if(u&&!e.selection.isEmpty()){o[u.ch].selFn&&(o[u.ch].selFn(e,e.getSelectionRange(),u.count,n),this.reset());return}if(!r&&!a&&u&&n)o[u.ch].fn(e,null,u.count,n),this.reset();else if(r){var f=function(t){t&&typeof t=="function"&&(r.count&&!l.handlesCount?d(t,r.count,[e,null,r.count,n]):t(e,null,r.count,n))},l=s[r.ch],c=l.sel;u?c&&d(function(){f(l.sel),o[u.ch].fn(e,e.getSelectionRange(),u.count,l.param?l:n)},u.count||1):(i.onVisualMode||i.onVisualLineMode)&&c?f(l.sel):f(l.nav),this.reset()}else a&&(a.fn(e,e.getSelectionRange(),a.count,n),this.reset());b(e)},isAccepting:function(e){return this.accepting.indexOf(e)!==-1},reset:function(){this.operator=null,this.motion=null,this.currentCount="",this.pendingCount="",this.status="",this.accepting=[f,l,c,h],this.idle=!0,this.waitingForParam=null}};t.coreCommands={start:{exec:function w(e){i.insertMode(e),y(w)}},startBeginning:{exec:function E(e){e.navigateLineStart(),i.insertMode(e),y(E)}},stop:{exec:function(t){g.reset(),i.onVisualMode=!1,i.onVisualLineMode=!1,g.lastInsertCommands=i.normalMode(t)}},append:{exec:function S(e){var t=e.getCursorPosition(),n=e.session.getLine(t.row).length;n&&e.navigateRight(),i.insertMode(e),y(S)}},appendEnd:{exec:function x(e){e.navigateLineEnd(),i.insertMode(e),y(x)}}};var b=t.onCursorMove=function(e,t){if(i.currentMode==="insert"||b.running)return;if(!e.selection.isEmpty()){b.running=!0;if(i.onVisualLineMode){var n=e.selection.visualLineStart,r=e.getCursorPosition().row;if(n<=r){var s=e.session.getLine(r);e.selection.moveTo(n,0),e.selection.selectTo(r,s.length)}else{var s=e.session.getLine(n);e.selection.moveTo(n,s.length),e.selection.selectTo(r,0)}}b.running=!1;return}t&&(i.onVisualLineMode||i.onVisualMode)&&(e.selection.clearSelection(),i.normalMode(e)),b.running=!0;var o=e.getCursorPosition(),u=e.session.getLine(o.row).length;u&&o.column===u&&e.navigateLeft(),b.running=!1}}),ace.define("ace/keyboard/vim",["require","exports","module","ace/keyboard/vim/commands","ace/keyboard/vim/maps/util","ace/lib/useragent"],function(e,t,n){"use strict";var r=e("./vim/commands"),i=r.coreCommands,s=e("./vim/maps/util"),o=e("../lib/useragent"),u={i:{command:i.start},I:{command:i.startBeginning},a:{command:i.append},A:{command:i.appendEnd},"ctrl-f":{command:"gotopagedown"},"ctrl-b":{command:"gotopageup"}};t.handler={$id:"ace/keyboard/vim",handleMacRepeat:function(e,t,n){if(t==-1)e.inputChar=n,e.lastEvent="input";else if(e.inputChar&&e.$lastHash==t&&e.$lastKey==n){if(e.lastEvent=="input")e.lastEvent="input1";else if(e.lastEvent=="input1")return!0}else e.$lastHash=t,e.$lastKey=n,e.lastEvent="keypress"},updateMacCompositionHandlers:function(e,t){var n=function(e){if(s.currentMode!=="insert"){var t=this.textInput.getElement();t.blur(),t.focus(),t.value=e}else this.onCompositionUpdateOrig(e)},r=function(e){s.currentMode==="insert"&&this.onCompositionStartOrig(e)};t?e.onCompositionUpdateOrig||(e.onCompositionUpdateOrig=e.onCompositionUpdate,e.onCompositionUpdate=n,e.onCompositionStartOrig=e.onCompositionStart,e.onCompositionStart=r):e.onCompositionUpdateOrig&&(e.onCompositionUpdate=e.onCompositionUpdateOrig,e.onCompositionUpdateOrig=null,e.onCompositionStart=e.onCompositionStartOrig,e.onCompositionStartOrig=null)},handleKeyboard:function(e,t,n,s,a){if(t!==0&&(!n||s==-1))return null;var f=e.editor,l=e.vimState||"start";t==1&&(n="ctrl-"+n);if(n=="ctrl-c")return!o.isMac&&f.getCopyText()?(f.once("copy",function(){l=="start"?i.stop.exec(f):f.selection.clearSelection()}),{command:"null",passEvent:!0}):{command:i.stop};if(n=="esc"&&t===0||n=="ctrl-[")return{command:i.stop};if(l=="start"){o.isMac&&this.handleMacRepeat(e,t,n)&&(t=-1,n=e.inputChar);if(t==-1||t==1||t===0&&n.length>1){if(r.inputBuffer.idle&&u[n])return u[n];var c=r.inputBuffer.push(f,n);if(!c&&t!==-1)return;return{command:"null",passEvent:!c}}if(n=="esc"&&t===0)return{command:i.stop};if(t===0||t==4)return{command:"null",passEvent:!0}}else if(n=="ctrl-w")return{command:"removewordleft"}},attach:function(e){e.on("click",t.onCursorMove),s.currentMode!=="insert"&&r.coreCommands.stop.exec(e),e.$vimModeHandler=this,this.updateMacCompositionHandlers(e,!0)},detach:function(e){e.removeListener("click",t.onCursorMove),s.noMode(e),s.currentMode="normal",this.updateMacCompositionHandlers(e,!1)},actions:r.actions,getStatusText:function(){return s.currentMode=="insert"?"INSERT":s.onVisualMode?(s.onVisualLineMode?"VISUAL LINE ":"VISUAL ")+r.inputBuffer.status:r.inputBuffer.status}},t.onCursorMove=function(e){r.onCursorMove(e.editor,e),t.onCursorMove.scheduled=!1}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-abap.js b/dist/assets/js/vendor/ace-nc/mode-abap.js
            new file mode 100644
            index 0000000000..3d46996c33
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-abap.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/abap_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e=this.createKeywordMapper({"variable.language":"this",keyword:"ADD ALIAS ALIASES ASSERT ASSIGN ASSIGNING AT BACK CALL CASE CATCH CHECK CLASS CLEAR CLOSE CNT COLLECT COMMIT COMMUNICATION COMPUTE CONCATENATE CONDENSE CONSTANTS CONTINUE CONTROLS CONVERT CREATE CURRENCY DATA DEFINE DEFINITION DEFERRED DELETE DESCRIBE DETAIL DIVIDE DO ELSE ELSEIF ENDAT ENDCASE ENDCLASS ENDDO ENDEXEC ENDFORM ENDFUNCTION ENDIF ENDIFEND ENDINTERFACE ENDLOOP ENDMETHOD ENDMODULE ENDON ENDPROVIDE ENDSELECT ENDTRY ENDWHILE EVENT EVENTS EXEC EXIT EXPORT EXPORTING EXTRACT FETCH FIELDS FORM FORMAT FREE FROM FUNCTION GENERATE GET HIDE IF IMPORT IMPORTING INDEX INFOTYPES INITIALIZATION INTERFACE INTERFACES INPUT INSERT IMPLEMENTATION LEAVE LIKE LINE LOAD LOCAL LOOP MESSAGE METHOD METHODS MODIFY MODULE MOVE MULTIPLY ON OVERLAY OPTIONAL OTHERS PACK PARAMETERS PERFORM POSITION PROGRAM PROVIDE PUT RAISE RANGES READ RECEIVE RECEIVING REDEFINITION REFERENCE REFRESH REJECT REPLACE REPORT RESERVE RESTORE RETURNING ROLLBACK SCAN SCROLL SEARCH SELECT SET SHIFT SKIP SORT SORTED SPLIT STANDARD STATICS STEP STOP SUBMIT SUBTRACT SUM SUMMARY SUPPRESS TABLES TIMES TRANSFER TRANSLATE TRY TYPE TYPES UNASSIGN ULINE UNPACK UPDATE WHEN WHILE WINDOW WRITE OCCURS STRUCTURE OBJECT PROPERTY CASTING APPEND RAISING VALUE COLOR CHANGING EXCEPTION EXCEPTIONS DEFAULT CHECKBOX COMMENT ID NUMBER FOR TITLE OUTPUT WITH EXIT USING INTO WHERE GROUP BY HAVING ORDER BY SINGLE APPENDING CORRESPONDING FIELDS OF TABLE LEFT RIGHT OUTER INNER JOIN AS CLIENT SPECIFIED BYPASSING BUFFER UP TO ROWS CONNECTING EQ NE LT LE GT GE NOT AND OR XOR IN LIKE BETWEEN","constant.language":"TRUE FALSE NULL SPACE","support.type":"c n i p f d t x string xstring decfloat16 decfloat34","keyword.operator":"abs sign ceil floor trunc frac acos asin atan cos sin tan abapOperator cosh sinh tanh exp log log10 sqrt strlen xstrlen charlen numofchar dbmaxlen lines"},"text",!0," "),t="WITH\\W+(?:HEADER\\W+LINE|FRAME|KEY)|NO\\W+STANDARD\\W+PAGE\\W+HEADING|EXIT\\W+FROM\\W+STEP\\W+LOOP|BEGIN\\W+OF\\W+(?:BLOCK|LINE)|BEGIN\\W+OF|END\\W+OF\\W+(?:BLOCK|LINE)|END\\W+OF|NO\\W+INTERVALS|RESPECTING\\W+BLANKS|SEPARATED\\W+BY|USING\\W+(?:EDIT\\W+MASK)|WHERE\\W+(?:LINE)|RADIOBUTTON\\W+GROUP|REF\\W+TO|(?:PUBLIC|PRIVATE|PROTECTED)(?:\\W+SECTION)?|DELETING\\W+(?:TRAILING|LEADING)(?:ALL\\W+OCCURRENCES)|(?:FIRST|LAST)\\W+OCCURRENCE|INHERITING\\W+FROM|LINE-COUNT|ADD-CORRESPONDING|AUTHORITY-CHECK|BREAK-POINT|CLASS-DATA|CLASS-METHODS|CLASS-METHOD|DIVIDE-CORRESPONDING|EDITOR-CALL|END-OF-DEFINITION|END-OF-PAGE|END-OF-SELECTION|FIELD-GROUPS|FIELD-SYMBOLS|FUNCTION-POOL|MOVE-CORRESPONDING|MULTIPLY-CORRESPONDING|NEW-LINE|NEW-PAGE|NEW-SECTION|PRINT-CONTROL|RP-PROVIDE-FROM-LAST|SELECT-OPTIONS|SELECTION-SCREEN|START-OF-SELECTION|SUBTRACT-CORRESPONDING|SYNTAX-CHECK|SYNTAX-TRACE|TOP-OF-PAGE|TYPE-POOL|TYPE-POOLS|LINE-SIZE|LINE-COUNT|MESSAGE-ID|DISPLAY-MODE|READ(?:-ONLY)?|IS\\W+(?:NOT\\W+)?(?:ASSIGNED|BOUND|INITIAL|SUPPLIED)";this.$rules={start:[{token:"string",regex:"`",next:"string"},{token:"string",regex:"'",next:"qstring"},{token:"doc.comment",regex:/^\*.+/},{token:"comment",regex:/".+$/},{token:"invalid",regex:"\\.{2,}"},{token:"keyword.operator",regex:/\W[\-+\%=<>*]\W|\*\*|[~:,\.&$]|->*?|=>/},{token:"paren.lparen",regex:"[\\[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"constant.numeric",regex:"[+-]?\\d+\\b"},{token:"variable.parameter",regex:/sy|pa?\d\d\d\d\|t\d\d\d\.|innnn/},{token:"keyword",regex:t},{token:"variable.parameter",regex:/\w+-\w+(?:-\w+)*/},{token:e,regex:"\\b\\w+\\b"},{caseInsensitive:!0}],qstring:[{token:"constant.language.escape",regex:"''"},{token:"string",regex:"'",next:"start"},{defaultToken:"string"}],string:[{token:"constant.language.escape",regex:"``"},{token:"string",regex:"`",next:"start"},{defaultToken:"string"}]}};r.inherits(s,i),t.AbapHighlightRules=s}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/abap",["require","exports","module","ace/mode/abap_highlight_rules","ace/mode/folding/coffee","ace/range","ace/mode/text","ace/lib/oop"],function(e,t,n){"use strict";function a(){this.HighlightRules=r,this.foldingRules=new i}var r=e("./abap_highlight_rules").AbapHighlightRules,i=e("./folding/coffee").FoldMode,s=e("../range").Range,o=e("./text").Mode,u=e("../lib/oop");u.inherits(a,o),function(){this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);return r},this.toggleCommentLines=function(e,t,n,r){var i=new s(0,0,0,0);for(var o=n;o<=r;++o){var u=t.getLine(o);if(hereComment.test(u))continue;commentLine.test(u)?u=u.replace(commentLine,"$1"):u=u.replace(indentation,"$&#"),i.end.row=i.start.row=o,i.end.column=u.length+1,t.replace(i,u)}},this.$id="ace/mode/abap"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-actionscript.js b/dist/assets/js/vendor/ace-nc/mode-actionscript.js
            new file mode 100644
            index 0000000000..703dba2823
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-actionscript.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/actionscript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"support.class.actionscript.2",regex:"\\b(?:R(?:ecordset|DBMSResolver|adioButton(?:Group)?)|X(?:ML(?:Socket|Node|Connector)?|UpdateResolverDataHolder)|M(?:M(?:Save|Execute)|icrophoneMicrophone|o(?:use|vieClip(?:Loader)?)|e(?:nu(?:Bar)?|dia(?:Controller|Display|Playback))|ath)|B(?:yName|inding|utton)|S(?:haredObject|ystem|crollPane|t(?:yleSheet|age|ream)|ound|e(?:ndEvent|rviceObject)|OAPCall|lide)|N(?:umericStepper|et(?:stream|S(?:tream|ervices)|Connection|Debug(?:Config)?))|C(?:heckBox|o(?:ntextMenu(?:Item)?|okie|lor|m(?:ponentMixins|boBox))|ustomActions|lient|amera)|T(?:ypedValue|ext(?:Snapshot|Input|F(?:ield|ormat)|Area)|ree|AB)|Object|D(?:ownload|elta(?:Item|Packet)?|at(?:e(?:Chooser|Field)?|a(?:G(?:lue|rid)|Set|Type)))|U(?:RL|TC|IScrollBar)|P(?:opUpManager|endingCall|r(?:intJob|o(?:duct|gressBar)))|E(?:ndPoint|rror)|Video|Key|F(?:RadioButton|GridColumn|MessageBox|BarChart|S(?:croll(?:Bar|Pane)|tyleFormat|plitView)|orm|C(?:heckbox|omboBox|alendar)|unction|T(?:icker|ooltip(?:Lite)?|ree(?:Node)?)|IconButton|D(?:ataGrid|raggablePane)|P(?:ieChart|ushButton|ro(?:gressBar|mptBox))|L(?:i(?:stBox|neChart)|oadingBox)|AdvancedMessageBox)|W(?:indow|SDLURL|ebService(?:Connector)?)|L(?:ist|o(?:calConnection|ad(?:er|Vars)|g)|a(?:unch|bel))|A(?:sBroadcaster|cc(?:ordion|essibility)|S(?:Set(?:Native|PropFlags)|N(?:ew|ative)|C(?:onstructor|lamp(?:2)?)|InstanceOf)|pplication|lert|rray))\\b"},{token:"support.function.actionscript.2",regex:"\\b(?:s(?:h(?:ift|ow(?:GridLines|Menu|Border|Settings|Headers|ColumnHeaders|Today|Preferences)?|ad(?:ow|ePane))|c(?:hema|ale(?:X|Mode|Y|Content)|r(?:oll(?:Track|Drag)?|een(?:Resolution|Color|DPI)))|t(?:yleSheet|op(?:Drag|A(?:nimation|llSounds|gent))?|epSize|a(?:tus|rt(?:Drag|A(?:nimation|gent))?))|i(?:n|ze|lence(?:TimeOut|Level))|o(?:ngname|urce|rt(?:Items(?:By)?|On(?:HeaderRelease)?|able(?:Columns)?)?)|u(?:ppressInvalidCalls|bstr(?:ing)?)|p(?:li(?:ce|t)|aceCol(?:umnsEqually|lumnsEqually))|e(?:nd(?:DefaultPushButtonEvent|AndLoad)?|curity|t(?:R(?:GB|o(?:otNode|w(?:Height|Count))|esizable(?:Columns)?|a(?:nge|te))|G(?:ain|roupName)|X(?:AxisTitle)?|M(?:i(?:n(?:imum|utes)|lliseconds)|o(?:nth(?:Names)?|tionLevel|de)|ultilineMode|e(?:ssage|nu(?:ItemEnabled(?:At)?|EnabledAt)|dia)|a(?:sk|ximum))|B(?:u(?:tton(?:s|Width)|fferTime)|a(?:seTabIndex|ndwidthLimit|ckground))|S(?:howAsDisabled|croll(?:ing|Speed|Content|Target|P(?:osition|roperties)|barState|Location)|t(?:yle(?:Property)?|opOnFocus|at(?:us|e))|i(?:ze|lenceLevel)|ort(?:able(?:Columns)?|Function)|p(?:litterBarPosition|acing)|e(?:conds|lect(?:Multiple|ion(?:Required|Type)?|Style|Color|ed(?:Node(?:s)?|Cell|I(?:nd(?:ices|ex)|tem(?:s)?))?|able))|kin|m(?:oothness|allScroll))|H(?:ighlight(?:s|Color)|Scroll|o(?:urs|rizontal)|eader(?:Symbol|Height|Text|Property|Format|Width|Location)?|as(?:Shader|CloseBox))|Y(?:ear|AxisTitle)?|N(?:ode(?:Properties|ExpansionHandler)|ewTextFormat)|C(?:h(?:ildNodes|a(?:ngeHandler|rt(?:Title|EventHandler)))|o(?:ntent(?:Size)?|okie|lumns)|ell(?:Symbol|Data)|l(?:i(?:ckHandler|pboard)|oseHandler)|redentials)|T(?:ype(?:dVaule)?|i(?:tle(?:barHeight)?|p(?:Target|Offset)?|me(?:out(?:Handler)?)?)|oggle|extFormat|ransform)|I(?:s(?:Branch|Open)|n(?:terval|putProperty)|con(?:SymbolName)?|te(?:rator|m(?:ByKey|Symbol)))|Orientation|D(?:i(?:splay(?:Range|Graphics|Mode|Clip|Text|edMonth)|rection)|uration|e(?:pth(?:Below|To|Above)|fault(?:GatewayURL|Mappings|NodeIconSymbolName)|l(?:iveryMode|ay)|bug(?:ID)?)|a(?:yOfWeekNames|t(?:e(?:Filter)?|a(?:Mapping(?:s)?|Item(?:Text|Property|Format)|Provider|All(?:Height|Property|Format|Width))?))|ra(?:wConnectors|gContent))|U(?:se(?:Shadow|HandCursor|EchoSuppression|rInput|Fade)|TC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear))|P(?:osition|ercentComplete|an(?:e(?:M(?:inimumSize|aximumSize)|Size|Title))?|ro(?:pert(?:y(?:Data)?|iesAt)|gress))|E(?:nabled|dit(?:Handler|able)|xpand(?:NodeTrigger|erSymbolName))|V(?:Scroll|olume|alue(?:Source)?)|KeyFrameInterval|Quality|F(?:i(?:eld|rst(?:DayOfWeek|VisibleNode))|ocus|ullYear|ps|ade(?:InLength|OutLength)|rame(?:Color|Width))|Width|L(?:ine(?:Color|Weight)|o(?:opback|adTarget)|a(?:rgeScroll|bel(?:Source|Placement)?))|A(?:s(?:Boolean|String|Number)|n(?:yTypedValue|imation)|ctiv(?:e(?:State(?:Handler)?|Handler)|ateHandler)|utoH(?:ideScrollBar|eight)))?|paratorBefore|ek|lect(?:ion(?:Disabled|Unfocused)?|ed(?:Node(?:s)?|Child|I(?:nd(?:ices|ex)|tem(?:s)?)|Dat(?:e|a))?|able(?:Ranges)?)|rver(?:String)?)|kip|qrt|wapDepths|lice|aveToSharedObj|moothing)|h(?:scroll(?:Policy)?|tml(?:Text)?|i(?:t(?:Test(?:TextNearPos)?|Area)|de(?:BuiltInItems|Child)?|ghlight(?:2D|3D)?)|orizontal|e(?:ight|ader(?:Re(?:nderer|lease)|Height|Text))|P(?:osition|ageScrollSize)|a(?:s(?:childNodes|MP3|S(?:creen(?:Broadcast|Playback)|treaming(?:Video|Audio)|ort)|Next|OwnProperty|Pr(?:inting|evious)|EmbeddedVideo|VideoEncoder|A(?:ccesibility|udio(?:Encoder)?))|ndlerName)|LineScrollSize)|ye(?:sLabel|ar)|n(?:o(?:t|de(?:Name|Close|Type|Open|Value)|Label)|u(?:llValue|mChild(?:S(?:creens|lides)|ren|Forms))|e(?:w(?:Item|line|Value|LocationDialog)|xt(?:S(?:cene|ibling|lide)|TabIndex|Value|Frame)?)?|ame(?:s)?)|c(?:h(?:ildNodes|eck|a(?:nge(?:sPending)?|r(?:CodeAt|At))|r)|o(?:s|n(?:st(?:ant|ructor)|nect|c(?:urrency|at)|t(?:ent(?:Type|Path)?|ains|rol(?:Placement|lerPolicy))|denseWhite|version)|py|l(?:or|umn(?:Stretch|Name(?:s)?|Count))|m(?:p(?:onent|lete)|ment))|u(?:stomItems|ePoint(?:s)?|r(?:veTo|Value|rent(?:Slide|ChildSlide|Item|F(?:ocused(?:S(?:creen|lide)|Form)|ps))))|e(?:il|ll(?:Renderer|Press|Edit|Focus(?:In|Out)))|l(?:i(?:ck|ents)|o(?:se(?:Button|Pane)?|ne(?:Node)?)|ear(?:S(?:haredObjects|treams)|Timeout|Interval)?)|a(?:ncelLabel|tch|p(?:tion|abilities)|l(?:cFields|l(?:e(?:e|r))?))|reate(?:GatewayConnection|Menu|Se(?:rver|gment)|C(?:hild(?:AtDepth)?|l(?:ient|ass(?:ChildAtDepth|Object(?:AtDepth)?))|all)|Text(?:Node|Field)|Item|Object(?:AtDepth)?|PopUp|E(?:lement|mptyMovieClip)))|t(?:h(?:is|row)|ype(?:of|Name)?|i(?:tle(?:StyleDeclaration)?|me(?:out)?)|o(?:talTime|String|olTipText|p|UpperCase|ggle(?:HighQuality)?|Lo(?:caleString|werCase))|e(?:st|llTarget|xt(?:RightMargin|Bold|S(?:ize|elected)|Height|Color|I(?:ndent|talic)|Disabled|Underline|F(?:ield|ont)|Width|LeftMargin|Align)?)|a(?:n|rget(?:Path)?|b(?:Stops|Children|Index|Enabled|leName))|r(?:y|igger|ac(?:e|k(?:AsMenu)?)))|i(?:s(?:Running|Branch|NaN|Con(?:soleOpen|nected)|Toggled|Installed|Open|D(?:own|ebugger)|P(?:urchased|ro(?:totypeOf|pertyEnumerable))|Empty|F(?:inite|ullyPopulated)|Local|Active)|n(?:s(?:tall|ertBefore)|cludeDeltaPacketInfo|t|it(?:ialize|Component|Pod|A(?:pplication|gent))?|de(?:nt|terminate|x(?:InParent(?:Slide|Form)?|Of)?)|put|validate|finity|LocalInternetCache)?|con(?:F(?:ield|unction))?|t(?:e(?:ratorScrolled|m(?:s|RollO(?:ut|ver)|ClassName))|alic)|d3|p|fFrameLoaded|gnore(?:Case|White))|o(?:s|n(?:R(?:ollO(?:ut|ver)|e(?:s(?:ize|ult)|l(?:ease(?:Outside)?|aseOutside)))|XML|Mouse(?:Move|Down|Up|Wheel)|S(?:ync|croller|tatus|oundComplete|e(?:tFocus|lect(?:edItem)?))|N(?:oticeEvent|etworkChange)|C(?:hanged|onnect|l(?:ipEvent|ose))|ID3|D(?:isconnect|eactivate|ata|ragO(?:ut|ver))|Un(?:install|load)|P(?:aymentResult|ress)|EnterFrame|K(?:illFocus|ey(?:Down|Up))|Fault|Lo(?:ad|g)|A(?:ctiv(?:ity|ate)|ppSt(?:op|art)))?|pe(?:n|ration)|verLayChildren|kLabel|ldValue|r(?:d)?)|d(?:i(?:s(?:connect|play(?:Normal|ed(?:Month|Year)|Full)|able(?:Shader|d(?:Ranges|Days)|CloseBox|Events))|rection)|o(?:cTypeDecl|tall|Decoding|main|LazyDecoding)|u(?:plicateMovieClip|ration)|e(?:stroy(?:ChildAt|Object)|code|fault(?:PushButton(?:Enabled)?|KeydownHandler)?|l(?:ta(?:Packet(?:Changed)?)?|ete(?:PopUp|All)?)|blocking)|a(?:shBoardSave|yNames|ta(?:Provider)?|rkshadow)|r(?:opdown(?:Width)?|a(?:w|gO(?:ut|ver))))|u(?:se(?:Sort|HandCursor|Codepage|EchoSuppression)|n(?:shift|install|derline|escape|format|watch|lo(?:ck|ad(?:Movie(?:Num)?)?))|pdate(?:Results|Mode|I(?:nputProperties|tem(?:ByIndex)?)|P(?:acket|roperties)|View|AfterEvent)|rl)|join|p(?:ixelAspectRatio|o(?:sition|p|w)|u(?:sh|rge|blish)|ercen(?:tComplete|Loaded)|lay(?:head(?:Change|Time)|ing|Hidden|erType)?|a(?:ssword|use|r(?:se(?:XML|CSS|Int|Float)|ent(?:Node|Is(?:S(?:creen|lide)|Form))|ams))|r(?:int(?:Num|AsBitmap(?:Num)?)?|o(?:to(?:type)?|pert(?:y|ies)|gress)|e(?:ss|v(?:ious(?:S(?:ibling|lide)|Value)?|Scene|Frame)|ferred(?:Height|Width))))|e(?:scape|n(?:code(?:r)?|ter(?:Frame)?|dFill|able(?:Shader|d|CloseBox|Events))|dit(?:able|Field|LocationDialog)|v(?:ent|al(?:uate)?)|q|x(?:tended|p|ec(?:ute)?|actSettings)|m(?:phasized(?:StyleDeclaration)?|bedFonts))|v(?:i(?:sible|ewPod)|ScrollPolicy|o(?:id|lume)|ersion|P(?:osition|ageScrollSize)|a(?:l(?:idat(?:ionError|e(?:Property|ActivationKey)?)|ue(?:Of)?)|riable)|LineScrollSize)|k(?:ind|ey(?:Down|Up|Press|FrameInterval))|q(?:sort|uality)|f(?:scommand|i(?:n(?:d(?:Text|First|Last)?|ally)|eldInfo|lter(?:ed|Func)?|rst(?:Slide|Child|DayOfWeek|VisibleNode)?)|o(?:nt|cus(?:In|edCell|Out|Enabled)|r(?:egroundDisabled|mat(?:ter)?))|unctionName|ps|l(?:oor|ush)|ace|romCharCode)|w(?:i(?:th|dth)|ordWrap|atch|riteAccess)|l(?:t|i(?:st(?:Owner)?|ne(?:Style|To))|o(?:c(?:k|a(?:t(?:ion|eByld)|l(?:ToGlobal|FileReadDisable)))|opback|ad(?:Movie(?:Num)?|S(?:crollContent|ound)|ed|Variables(?:Num)?|Application)?|g(?:Changes)?)|e(?:ngth|ft(?:Margin)?|ading)?|a(?:st(?:Slide|Child|Index(?:Of)?)?|nguage|b(?:el(?:Placement|F(?:ield|unction))?|leField)))|a(?:s(?:scociate(?:Controller|Display)|in|pectRatio|function)|nd|c(?:ceptConnection|tiv(?:ityLevel|ePlayControl)|os)|t(?:t(?:ach(?:Movie|Sound|Video|Audio)|ributes)|an(?:2)?)|dd(?:header|RequestHeader|Menu(?:Item(?:At)?|At)?|Sort|Header|No(?:tice|de(?:At)?)|C(?:olumn(?:At)?|uePoint)|T(?:oLocalInternetCache|reeNode(?:At)?)|I(?:con|tem(?:s(?:At)?|At)?)|DeltaItem|P(?:od|age|roperty)|EventListener|View|FieldInfo|Listener|Animation)?|uto(?:Size|Play|KeyNav|Load)|pp(?:endChild|ly(?:Changes|Updates)?)|vHardwareDisable|fterLoaded|l(?:ternateRowColors|ign|l(?:ow(?:InsecureDomain|Domain)|Transitions(?:InDone|OutDone))|bum)|r(?:tist|row|g(?:uments|List))|gent|bs)|r(?:ight(?:Margin)?|o(?:ot(?:S(?:creen|lide)|Form)|und|w(?:Height|Count)|llO(?:ut|ver))|e(?:s(?:yncDepth|t(?:orePane|artAnimation|rict)|iz(?:e|able(?:Columns)?)|olveDelta|ult(?:s)?|ponse)|c(?:o(?:ncile(?:Results|Updates)|rd)|eive(?:Video|Audio))|draw|jectConnection|place(?:Sel|ItemAt|AllItems)?|ve(?:al(?:Child)?|rse)|quest(?:SizeChange|Payment)?|f(?:errer|resh(?:ScrollContent|Destinations|Pane|FromSources)?)|lease(?:Outside)?|ad(?:Only|Access)|gister(?:SkinElement|C(?:olor(?:Style|Name)|lass)|InheritingStyle|Proxy)|move(?:Range|M(?:ovieClip|enu(?:Item(?:At)?|At))|Background|Sort|No(?:tice|de(?:sAt|At)?)|C(?:olum(?:nAt|At)|uePoints)|T(?:extField|reeNode(?:At)?)|Item(?:At)?|Pod|EventListener|FromLocalInternetCache|Listener|All(?:C(?:olumns|uePoints)|Items)?))|a(?:ndom|te|dioDot))|g(?:t|oto(?:Slide|NextSlide|PreviousSlide|FirstSlide|LastSlide|And(?:Stop|Play))|e(?:nre|t(?:R(?:GB|o(?:otNode|wCount)|e(?:sizable|mote))|X(?:AxisTitle)?|M(?:i(?:n(?:imum(?:Size)?|utes)|lliseconds)|onth(?:Names)?|ultilineMode|e(?:ssage|nu(?:ItemAt|EnabledAt|At))|aximum(?:Size)?)|B(?:ytes(?:Total|Loaded)|ounds|utton(?:s|Width)|eginIndex|a(?:ndwidthLimit|ckground))|S(?:howAsDisabled|croll(?:ing|Speed|Content|Position|barState|Location)|t(?:yle(?:Names)?|opOnFocus|ate)|ize|o(?:urce|rtState)|p(?:litterBarPosition|acing)|e(?:conds|lect(?:Multiple|ion(?:Required|Type)|Style|ed(?:Node(?:s)?|Cell|Text|I(?:nd(?:ices|ex)|tem(?:s)?))?)|rvice)|moothness|WFVersion)|H(?:ighlight(?:s|Color)|ours|e(?:ight|ader(?:Height|Text|Property|Format|Width|Location)?)|as(?:Shader|CloseBox))|Y(?:ear|AxisTitle)?|N(?:o(?:tices|de(?:DisplayedAt|At))|um(?:Children|berAvailable)|e(?:wTextFormat|xtHighestDepth))|C(?:h(?:ild(?:S(?:creen|lide)|Nodes|Form|At)|artTitle)|o(?:n(?:tent|figInfo)|okie|de|unt|lumn(?:Names|Count|Index|At))|uePoint|ellIndex|loseHandler|a(?:ll|retIndex))|T(?:ypedValue|i(?:tle(?:barHeight)?|p(?:Target|Offset)?|me(?:stamp|zoneOffset|out(?:State|Handler)|r)?)|oggle|ext(?:Extent|Format)?|r(?:ee(?:NodeAt|Length)|ans(?:form|actionId)))|I(?:s(?:Branch|Open)|n(?:stanceAtDepth|d(?:icesByKey|exByKey))|con(?:SymbolName)?|te(?:rator|m(?:sByKey|By(?:Name|Key)|id|ID|At))|d)|O(?:utput(?:Parameter(?:s|ByName)?|Value(?:s)?)|peration|ri(?:entation|ginalCellData))|D(?:i(?:s(?:play(?:Range|Mode|Clip|Index|edMonth)|kUsage)|rection)|uration|e(?:pth|faultNodeIconSymbolName|l(?:taPacket|ay)|bug(?:Config|ID)?)|a(?:y(?:OfWeekNames)?|t(?:e|a(?:Mapping(?:s)?|Item(?:Text|Property|Format)|Label|All(?:Height|Property|Format|Width))?))|rawConnectors)|U(?:se(?:Shadow|HandCursor|rInput|Fade)|RL|TC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear))|P(?:o(?:sition|ds)|ercentComplete|a(?:n(?:e(?:M(?:inimums|aximums)|Height|Title|Width))?|rentNode)|r(?:operty(?:Name|Data)?|efer(?:ences|red(?:Height|Width))))|E(?:n(?:dIndex|abled)|ditingData|x(?:panderSymbolName|andNodeTrigger))|V(?:iewed(?:Pods|Applications)|olume|ersion|alue(?:Source)?)|F(?:i(?:eld|rst(?:DayOfWeek|VisibleNode))|o(?:ntList|cus)|ullYear|ade(?:InLength|OutLength)|rame(?:Color|Width))|Width|L(?:ine(?:Color|Weight)|o(?:cal|adTarget)|ength|a(?:stTabIndex|bel(?:Source)?))|A(?:s(?:cii|Boolean|String|Number)|n(?:yTypedValue|imation)|ctiv(?:eState(?:Handler)?|ateHandler)|utoH(?:ideScrollBar|eight)|llItems|gent))?)?|lobal(?:StyleFormat|ToLocal)?|ain|roupName)|x(?:updatePackety|mlDecl)?|m(?:y(?:MethodName|Call)|in(?:imum)?|o(?:nthNames|tion(?:TimeOut|Level)|de(?:lChanged)?|use(?:Move|O(?:ut|ver)|Down(?:Somewhere|Outside)?|Up(?:Somewhere)?|WheelEnabled)|ve(?:To)?)|u(?:ted|lti(?:pleS(?:imultaneousAllowed|elections)|line))|e(?:ssage|nu(?:Show|Hide)?|th(?:od)?|diaType)|a(?:nufacturer|tch|x(?:scroll|hscroll|imum|HPosition|Chars|VPosition)?)|b(?:substring|chr|ord|length))|b(?:ytes(?:Total|Loaded)|indFormat(?:Strings|Function)|o(?:ttom(?:Scroll)?|ld|rder(?:Color)?)|u(?:tton(?:Height|Width)|iltInItems|ffer(?:Time|Length)|llet)|e(?:foreApplyUpdates|gin(?:GradientFill|Fill))|lockIndent|a(?:ndwidth|ckground(?:Style|Color|Disabled)?)|roadcastMessage)|onHTTPStatus)\\b"},{token:"support.constant.actionscript.2",regex:"\\b(?:__proto__|__resolve|_accProps|_alpha|_changed|_currentframe|_droptarget|_flash|_focusrect|_framesloaded|_global|_height|_highquality|_level|_listeners|_lockroot|_name|_parent|_quality|_root|_rotation|_soundbuftime|_target|_totalframes|_url|_visible|_width|_x|_xmouse|_xscale|_y|_ymouse|_yscale)\\b"},{token:"keyword.control.actionscript.2",regex:"\\b(?:dynamic|extends|import|implements|interface|public|private|new|static|super|var|for|in|break|continue|while|do|return|if|else|case|switch)\\b"},{token:"storage.type.actionscript.2",regex:"\\b(?:Boolean|Number|String|Void)\\b"},{token:"constant.language.actionscript.2",regex:"\\b(?:null|undefined|true|false)\\b"},{token:"constant.numeric.actionscript.2",regex:"\\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\\.?[0-9]*|\\.[0-9]+)(?:(?:e|E)(?:\\+|-)?[0-9]+)?)(?:L|l|UL|ul|u|U|F|f)?\\b"},{token:"punctuation.definition.string.begin.actionscript.2",regex:'"',push:[{token:"punctuation.definition.string.end.actionscript.2",regex:'"',next:"pop"},{token:"constant.character.escape.actionscript.2",regex:"\\\\."},{defaultToken:"string.quoted.double.actionscript.2"}]},{token:"punctuation.definition.string.begin.actionscript.2",regex:"'",push:[{token:"punctuation.definition.string.end.actionscript.2",regex:"'",next:"pop"},{token:"constant.character.escape.actionscript.2",regex:"\\\\."},{defaultToken:"string.quoted.single.actionscript.2"}]},{token:"support.constant.actionscript.2",regex:"\\b(?:BACKSPACE|CAPSLOCK|CONTROL|DELETEKEY|DOWN|END|ENTER|HOME|INSERT|LEFT|LN10|LN2|LOG10E|LOG2E|MAX_VALUE|MIN_VALUE|NEGATIVE_INFINITY|NaN|PGDN|PGUP|PI|POSITIVE_INFINITY|RIGHT|SPACE|SQRT1_2|SQRT2|UP)\\b"},{token:"punctuation.definition.comment.actionscript.2",regex:"/\\*",push:[{token:"punctuation.definition.comment.actionscript.2",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.actionscript.2"}]},{token:"punctuation.definition.comment.actionscript.2",regex:"//.*$",push_:[{token:"comment.line.double-slash.actionscript.2",regex:"$",next:"pop"},{defaultToken:"comment.line.double-slash.actionscript.2"}]},{token:"keyword.operator.actionscript.2",regex:"\\binstanceof\\b"},{token:"keyword.operator.symbolic.actionscript.2",regex:"[-!%&*+=/?:]"},{token:["meta.preprocessor.actionscript.2","punctuation.definition.preprocessor.actionscript.2","meta.preprocessor.actionscript.2"],regex:"^([ \\t]*)(#)([a-zA-Z]+)"},{token:["storage.type.function.actionscript.2","meta.function.actionscript.2","entity.name.function.actionscript.2","meta.function.actionscript.2","punctuation.definition.parameters.begin.actionscript.2"],regex:"\\b(function)(\\s+)([a-zA-Z_]\\w*)(\\s*)(\\()",push:[{token:"punctuation.definition.parameters.end.actionscript.2",regex:"\\)",next:"pop"},{token:"variable.parameter.function.actionscript.2",regex:"[^,)$]+"},{defaultToken:"meta.function.actionscript.2"}]},{token:["storage.type.class.actionscript.2","meta.class.actionscript.2","entity.name.type.class.actionscript.2","meta.class.actionscript.2","storage.modifier.extends.actionscript.2","meta.class.actionscript.2","entity.other.inherited-class.actionscript.2"],regex:"\\b(class)(\\s+)([a-zA-Z_](?:\\w|\\.)*)(?:(\\s+)(extends)(\\s+)([a-zA-Z_](?:\\w|\\.)*))?"}]},this.normalizeRules()};s.metaData={fileTypes:["as"],keyEquivalent:"^~A",name:"ActionScript",scopeName:"source.actionscript.2"},r.inherits(s,i),t.ActionScriptHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/actionscript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/actionscript_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./actionscript_highlight_rules").ActionScriptHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/actionscript"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-ada.js b/dist/assets/js/vendor/ace-nc/mode-ada.js
            new file mode 100644
            index 0000000000..81cdc59e62
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-ada.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/ada_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="abort|else|new|return|abs|elsif|not|reverse|abstract|end|null|accept|entry|select|access|exception|of|separate|aliased|exit|or|some|all|others|subtype|and|for|out|synchronized|array|function|overriding|at|tagged|generic|package|task|begin|goto|pragma|terminate|body|private|then|if|procedure|type|case|in|protected|constant|interface|until||is|raise|use|declare|range|delay|limited|record|when|delta|loop|rem|while|digits|renames|with|do|mod|requeue|xor",t="true|false|null",n="count|min|max|avg|sum|rank|now|coalesce|main",r=this.createKeywordMapper({"support.function":n,keyword:e,"constant.language":t},"identifier",!0);this.$rules={start:[{token:"comment",regex:"--.*$"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]}};r.inherits(s,i),t.AdaHighlightRules=s}),ace.define("ace/mode/ada",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ada_highlight_rules","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./ada_highlight_rules").AdaHighlightRules,o=e("../range").Range,u=function(){this.HighlightRules=s};r.inherits(u,i),function(){this.lineCommentStart="--",this.$id="ace/mode/ada"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-apache_conf.js b/dist/assets/js/vendor/ace-nc/mode-apache_conf.js
            new file mode 100644
            index 0000000000..ccde5f26b0
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-apache_conf.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/apache_conf_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:["punctuation.definition.comment.apacheconf","comment.line.hash.ini","comment.line.hash.ini"],regex:"^((?:\\s)*)(#)(.*$)"},{token:["punctuation.definition.tag.apacheconf","entity.tag.apacheconf","text","string.value.apacheconf","punctuation.definition.tag.apacheconf"],regex:"(<)(Proxy|ProxyMatch|IfVersion|Directory|DirectoryMatch|Files|FilesMatch|IfDefine|IfModule|Limit|LimitExcept|Location|LocationMatch|VirtualHost)(?:(\\s)(.+?))?(>)"},{token:["punctuation.definition.tag.apacheconf","entity.tag.apacheconf","punctuation.definition.tag.apacheconf"],regex:"(</)(Proxy|ProxyMatch|IfVersion|Directory|DirectoryMatch|Files|FilesMatch|IfDefine|IfModule|Limit|LimitExcept|Location|LocationMatch|VirtualHost)(>)"},{token:["keyword.alias.apacheconf","text","string.regexp.apacheconf","text","string.replacement.apacheconf","text"],regex:"(Rewrite(?:Rule|Cond))(\\s+)(.+?)(\\s+)(.+?)($|\\s)"},{token:["keyword.alias.apacheconf","text","entity.status.apacheconf","text","string.regexp.apacheconf","text","string.path.apacheconf","text"],regex:"(RedirectMatch)(?:(\\s+)(\\d\\d\\d|permanent|temp|seeother|gone))?(\\s+)(.+?)(\\s+)(?:(.+?)($|\\s))?"},{token:["keyword.alias.apacheconf","text","entity.status.apacheconf","text","string.path.apacheconf","text","string.path.apacheconf","text"],regex:"(Redirect)(?:(\\s+)(\\d\\d\\d|permanent|temp|seeother|gone))?(\\s+)(.+?)(\\s+)(?:(.+?)($|\\s))?"},{token:["keyword.alias.apacheconf","text","string.regexp.apacheconf","text","string.path.apacheconf","text"],regex:"(ScriptAliasMatch|AliasMatch)(\\s+)(.+?)(\\s+)(?:(.+?)(\\s))?"},{token:["keyword.alias.apacheconf","text","string.path.apacheconf","text","string.path.apacheconf","text"],regex:"(RedirectPermanent|RedirectTemp|ScriptAlias|Alias)(\\s+)(.+?)(\\s+)(?:(.+?)($|\\s))?"},{token:"keyword.core.apacheconf",regex:"\\b(?:AcceptPathInfo|AccessFileName|AddDefaultCharset|AddOutputFilterByType|AllowEncodedSlashes|AllowOverride|AuthName|AuthType|CGIMapExtension|ContentDigest|DefaultType|DocumentRoot|EnableMMAP|EnableSendfile|ErrorDocument|ErrorLog|FileETag|ForceType|HostnameLookups|IdentityCheck|Include|KeepAlive|KeepAliveTimeout|LimitInternalRecursion|LimitRequestBody|LimitRequestFields|LimitRequestFieldSize|LimitRequestLine|LimitXMLRequestBody|LogLevel|MaxKeepAliveRequests|NameVirtualHost|Options|Require|RLimitCPU|RLimitMEM|RLimitNPROC|Satisfy|ScriptInterpreterSource|ServerAdmin|ServerAlias|ServerName|ServerPath|ServerRoot|ServerSignature|ServerTokens|SetHandler|SetInputFilter|SetOutputFilter|TimeOut|TraceEnable|UseCanonicalName)\\b"},{token:"keyword.mpm.apacheconf",regex:"\\b(?:AcceptMutex|AssignUserID|BS2000Account|ChildPerUserID|CoreDumpDirectory|EnableExceptionHook|Group|Listen|ListenBacklog|LockFile|MaxClients|MaxMemFree|MaxRequestsPerChild|MaxRequestsPerThread|MaxSpareServers|MaxSpareThreads|MaxThreads|MaxThreadsPerChild|MinSpareServers|MinSpareThreads|NumServers|PidFile|ReceiveBufferSize|ScoreBoardFile|SendBufferSize|ServerLimit|StartServers|StartThreads|ThreadLimit|ThreadsPerChild|ThreadStackSize|User|Win32DisableAcceptEx)\\b"},{token:"keyword.access.apacheconf",regex:"\\b(?:Allow|Deny|Order)\\b"},{token:"keyword.actions.apacheconf",regex:"\\b(?:Action|Script)\\b"},{token:"keyword.alias.apacheconf",regex:"\\b(?:Alias|AliasMatch|Redirect|RedirectMatch|RedirectPermanent|RedirectTemp|ScriptAlias|ScriptAliasMatch)\\b"},{token:"keyword.auth.apacheconf",regex:"\\b(?:AuthAuthoritative|AuthGroupFile|AuthUserFile)\\b"},{token:"keyword.auth_anon.apacheconf",regex:"\\b(?:Anonymous|Anonymous_Authoritative|Anonymous_LogEmail|Anonymous_MustGiveEmail|Anonymous_NoUserID|Anonymous_VerifyEmail)\\b"},{token:"keyword.auth_dbm.apacheconf",regex:"\\b(?:AuthDBMAuthoritative|AuthDBMGroupFile|AuthDBMType|AuthDBMUserFile)\\b"},{token:"keyword.auth_digest.apacheconf",regex:"\\b(?:AuthDigestAlgorithm|AuthDigestDomain|AuthDigestFile|AuthDigestGroupFile|AuthDigestNcCheck|AuthDigestNonceFormat|AuthDigestNonceLifetime|AuthDigestQop|AuthDigestShmemSize)\\b"},{token:"keyword.auth_ldap.apacheconf",regex:"\\b(?:AuthLDAPAuthoritative|AuthLDAPBindDN|AuthLDAPBindPassword|AuthLDAPCharsetConfig|AuthLDAPCompareDNOnServer|AuthLDAPDereferenceAliases|AuthLDAPEnabled|AuthLDAPFrontPageHack|AuthLDAPGroupAttribute|AuthLDAPGroupAttributeIsDN|AuthLDAPRemoteUserIsDN|AuthLDAPUrl)\\b"},{token:"keyword.autoindex.apacheconf",regex:"\\b(?:AddAlt|AddAltByEncoding|AddAltByType|AddDescription|AddIcon|AddIconByEncoding|AddIconByType|DefaultIcon|HeaderName|IndexIgnore|IndexOptions|IndexOrderDefault|ReadmeName)\\b"},{token:"keyword.cache.apacheconf",regex:"\\b(?:CacheDefaultExpire|CacheDisable|CacheEnable|CacheForceCompletion|CacheIgnoreCacheControl|CacheIgnoreHeaders|CacheIgnoreNoLastMod|CacheLastModifiedFactor|CacheMaxExpire)\\b"},{token:"keyword.cern_meta.apacheconf",regex:"\\b(?:MetaDir|MetaFiles|MetaSuffix)\\b"},{token:"keyword.cgi.apacheconf",regex:"\\b(?:ScriptLog|ScriptLogBuffer|ScriptLogLength)\\b"},{token:"keyword.cgid.apacheconf",regex:"\\b(?:ScriptLog|ScriptLogBuffer|ScriptLogLength|ScriptSock)\\b"},{token:"keyword.charset_lite.apacheconf",regex:"\\b(?:CharsetDefault|CharsetOptions|CharsetSourceEnc)\\b"},{token:"keyword.dav.apacheconf",regex:"\\b(?:Dav|DavDepthInfinity|DavMinTimeout|DavLockDB)\\b"},{token:"keyword.deflate.apacheconf",regex:"\\b(?:DeflateBufferSize|DeflateCompressionLevel|DeflateFilterNote|DeflateMemLevel|DeflateWindowSize)\\b"},{token:"keyword.dir.apacheconf",regex:"\\b(?:DirectoryIndex|DirectorySlash)\\b"},{token:"keyword.disk_cache.apacheconf",regex:"\\b(?:CacheDirLength|CacheDirLevels|CacheExpiryCheck|CacheGcClean|CacheGcDaily|CacheGcInterval|CacheGcMemUsage|CacheGcUnused|CacheMaxFileSize|CacheMinFileSize|CacheRoot|CacheSize|CacheTimeMargin)\\b"},{token:"keyword.dumpio.apacheconf",regex:"\\b(?:DumpIOInput|DumpIOOutput)\\b"},{token:"keyword.env.apacheconf",regex:"\\b(?:PassEnv|SetEnv|UnsetEnv)\\b"},{token:"keyword.expires.apacheconf",regex:"\\b(?:ExpiresActive|ExpiresByType|ExpiresDefault)\\b"},{token:"keyword.ext_filter.apacheconf",regex:"\\b(?:ExtFilterDefine|ExtFilterOptions)\\b"},{token:"keyword.file_cache.apacheconf",regex:"\\b(?:CacheFile|MMapFile)\\b"},{token:"keyword.headers.apacheconf",regex:"\\b(?:Header|RequestHeader)\\b"},{token:"keyword.imap.apacheconf",regex:"\\b(?:ImapBase|ImapDefault|ImapMenu)\\b"},{token:"keyword.include.apacheconf",regex:"\\b(?:SSIEndTag|SSIErrorMsg|SSIStartTag|SSITimeFormat|SSIUndefinedEcho|XBitHack)\\b"},{token:"keyword.isapi.apacheconf",regex:"\\b(?:ISAPIAppendLogToErrors|ISAPIAppendLogToQuery|ISAPICacheFile|ISAPIFakeAsync|ISAPILogNotSupported|ISAPIReadAheadBuffer)\\b"},{token:"keyword.ldap.apacheconf",regex:"\\b(?:LDAPCacheEntries|LDAPCacheTTL|LDAPConnectionTimeout|LDAPOpCacheEntries|LDAPOpCacheTTL|LDAPSharedCacheFile|LDAPSharedCacheSize|LDAPTrustedCA|LDAPTrustedCAType)\\b"},{token:"keyword.log.apacheconf",regex:"\\b(?:BufferedLogs|CookieLog|CustomLog|LogFormat|TransferLog|ForensicLog)\\b"},{token:"keyword.mem_cache.apacheconf",regex:"\\b(?:MCacheMaxObjectCount|MCacheMaxObjectSize|MCacheMaxStreamingBuffer|MCacheMinObjectSize|MCacheRemovalAlgorithm|MCacheSize)\\b"},{token:"keyword.mime.apacheconf",regex:"\\b(?:AddCharset|AddEncoding|AddHandler|AddInputFilter|AddLanguage|AddOutputFilter|AddType|DefaultLanguage|ModMimeUsePathInfo|MultiviewsMatch|RemoveCharset|RemoveEncoding|RemoveHandler|RemoveInputFilter|RemoveLanguage|RemoveOutputFilter|RemoveType|TypesConfig)\\b"},{token:"keyword.misc.apacheconf",regex:"\\b(?:ProtocolEcho|Example|AddModuleInfo|MimeMagicFile|CheckSpelling|ExtendedStatus|SuexecUserGroup|UserDir)\\b"},{token:"keyword.negotiation.apacheconf",regex:"\\b(?:CacheNegotiatedDocs|ForceLanguagePriority|LanguagePriority)\\b"},{token:"keyword.nw_ssl.apacheconf",regex:"\\b(?:NWSSLTrustedCerts|NWSSLUpgradeable|SecureListen)\\b"},{token:"keyword.proxy.apacheconf",regex:"\\b(?:AllowCONNECT|NoProxy|ProxyBadHeader|ProxyBlock|ProxyDomain|ProxyErrorOverride|ProxyFtpDirCharset|ProxyIOBufferSize|ProxyMaxForwards|ProxyPass|ProxyPassReverse|ProxyPreserveHost|ProxyReceiveBufferSize|ProxyRemote|ProxyRemoteMatch|ProxyRequests|ProxyTimeout|ProxyVia)\\b"},{token:"keyword.rewrite.apacheconf",regex:"\\b(?:RewriteBase|RewriteCond|RewriteEngine|RewriteLock|RewriteLog|RewriteLogLevel|RewriteMap|RewriteOptions|RewriteRule)\\b"},{token:"keyword.setenvif.apacheconf",regex:"\\b(?:BrowserMatch|BrowserMatchNoCase|SetEnvIf|SetEnvIfNoCase)\\b"},{token:"keyword.so.apacheconf",regex:"\\b(?:LoadFile|LoadModule)\\b"},{token:"keyword.ssl.apacheconf",regex:"\\b(?:SSLCACertificateFile|SSLCACertificatePath|SSLCARevocationFile|SSLCARevocationPath|SSLCertificateChainFile|SSLCertificateFile|SSLCertificateKeyFile|SSLCipherSuite|SSLEngine|SSLMutex|SSLOptions|SSLPassPhraseDialog|SSLProtocol|SSLProxyCACertificateFile|SSLProxyCACertificatePath|SSLProxyCARevocationFile|SSLProxyCARevocationPath|SSLProxyCipherSuite|SSLProxyEngine|SSLProxyMachineCertificateFile|SSLProxyMachineCertificatePath|SSLProxyProtocol|SSLProxyVerify|SSLProxyVerifyDepth|SSLRandomSeed|SSLRequire|SSLRequireSSL|SSLSessionCache|SSLSessionCacheTimeout|SSLUserName|SSLVerifyClient|SSLVerifyDepth)\\b"},{token:"keyword.usertrack.apacheconf",regex:"\\b(?:CookieDomain|CookieExpires|CookieName|CookieStyle|CookieTracking)\\b"},{token:"keyword.vhost_alias.apacheconf",regex:"\\b(?:VirtualDocumentRoot|VirtualDocumentRootIP|VirtualScriptAlias|VirtualScriptAliasIP)\\b"},{token:["keyword.php.apacheconf","text","entity.property.apacheconf","text","string.value.apacheconf","text"],regex:"\\b(php_value|php_flag)\\b(?:(\\s+)(.+?)(?:(\\s+)(.+?))?)?(\\s)"},{token:["punctuation.variable.apacheconf","variable.env.apacheconf","variable.misc.apacheconf","punctuation.variable.apacheconf"],regex:"(%\\{)(?:(HTTP_USER_AGENT|HTTP_REFERER|HTTP_COOKIE|HTTP_FORWARDED|HTTP_HOST|HTTP_PROXY_CONNECTION|HTTP_ACCEPT|REMOTE_ADDR|REMOTE_HOST|REMOTE_PORT|REMOTE_USER|REMOTE_IDENT|REQUEST_METHOD|SCRIPT_FILENAME|PATH_INFO|QUERY_STRING|AUTH_TYPE|DOCUMENT_ROOT|SERVER_ADMIN|SERVER_NAME|SERVER_ADDR|SERVER_PORT|SERVER_PROTOCOL|SERVER_SOFTWARE|TIME_YEAR|TIME_MON|TIME_DAY|TIME_HOUR|TIME_MIN|TIME_SEC|TIME_WDAY|TIME|API_VERSION|THE_REQUEST|REQUEST_URI|REQUEST_FILENAME|IS_SUBREQ|HTTPS)|(.*?))(\\})"},{token:["entity.mime-type.apacheconf","text"],regex:"\\b((?:text|image|application|video|audio)/.+?)(\\s)"},{token:"entity.helper.apacheconf",regex:"\\b(?:from|unset|set|on|off)\\b",caseInsensitive:!0},{token:"constant.integer.apacheconf",regex:"\\b\\d+\\b"},{token:["text","punctuation.definition.flag.apacheconf","string.flag.apacheconf","punctuation.definition.flag.apacheconf","text"],regex:"(\\s)(\\[)(.*?)(\\])(\\s)"}]},this.normalizeRules()};s.metaData={fileTypes:["conf","CONF","htaccess","HTACCESS","htgroups","HTGROUPS","htpasswd","HTPASSWD",".htaccess",".HTACCESS",".htgroups",".HTGROUPS",".htpasswd",".HTPASSWD"],name:"Apache Conf",scopeName:"source.apacheconf"},r.inherits(s,i),t.ApacheConfHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/apache_conf",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/apache_conf_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./apache_conf_highlight_rules").ApacheConfHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="#",this.$id="ace/mode/apache_conf"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-applescript.js b/dist/assets/js/vendor/ace-nc/mode-applescript.js
            new file mode 100644
            index 0000000000..ff9a8e7da6
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-applescript.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/applescript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="about|above|after|against|and|around|as|at|back|before|beginning|behind|below|beneath|beside|between|but|by|considering|contain|contains|continue|copy|div|does|eighth|else|end|equal|equals|error|every|exit|fifth|first|for|fourth|from|front|get|given|global|if|ignoring|in|into|is|it|its|last|local|me|middle|mod|my|ninth|not|of|on|onto|or|over|prop|property|put|ref|reference|repeat|returning|script|second|set|seventh|since|sixth|some|tell|tenth|that|the|then|third|through|thru|timeout|times|to|transaction|try|until|where|while|whose|with|without",t="AppleScript|false|linefeed|return|pi|quote|result|space|tab|true",n="activate|beep|count|delay|launch|log|offset|read|round|run|say|summarize|write",r="alias|application|boolean|class|constant|date|file|integer|list|number|real|record|string|text|character|characters|contents|day|frontmost|id|item|length|month|name|paragraph|paragraphs|rest|reverse|running|time|version|weekday|word|words|year",i=this.createKeywordMapper({"support.function":n,"constant.language":t,"support.type":r,keyword:e},"identifier");this.$rules={start:[{token:"comment",regex:"--.*$"},{token:"comment",regex:"\\(\\*",next:"comment"},{token:"string",regex:'".*?"'},{token:"support.type",regex:"\\b(POSIX file|POSIX path|(date|time) string|quoted form)\\b"},{token:"support.function",regex:"\\b(clipboard info|the clipboard|info for|list (disks|folder)|mount volume|path to|(close|open for) access|(get|set) eof|current date|do shell script|get volume settings|random number|set volume|system attribute|system info|time to GMT|(load|run|store) script|scripting components|ASCII (character|number)|localized string|choose (application|color|file|file name|folder|from list|remote application|URL)|display (alert|dialog))\\b|^\\s*return\\b"},{token:"constant.language",regex:"\\b(text item delimiters|current application|missing value)\\b"},{token:"keyword",regex:"\\b(apart from|aside from|instead of|out of|greater than|isn't|(doesn't|does not) (equal|come before|come after|contain)|(greater|less) than( or equal)?|(starts?|ends|begins?) with|contained by|comes (before|after)|a (ref|reference))\\b"},{token:i,regex:"[a-zA-Z][a-zA-Z0-9_]*\\b"}],comment:[{token:"comment",regex:"\\*\\)",next:"start"},{defaultToken:"comment"}]},this.normalizeRules()};r.inherits(s,i),t.AppleScriptHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/applescript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/applescript_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./applescript_highlight_rules").AppleScriptHighlightRules,u=e("./folding/cstyle").FoldMode,a=function(){this.HighlightRules=o,this.foldingRules=new u};r.inherits(a,i),function(){this.lineCommentStart="--",this.blockComment={start:"(*",end:"*)"},this.$id="ace/mode/applescript"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-asciidoc.js b/dist/assets/js/vendor/ace-nc/mode-asciidoc.js
            new file mode 100644
            index 0000000000..de55f241b5
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-asciidoc.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/asciidoc_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){function t(e){var t=/\w/.test(e)?"\\b":"(?:\\B|^)";return t+e+"[^"+e+"].*?"+e+"(?![\\w*])"}var e="[a-zA-Z\u00a1-\uffff]+\\b";this.$rules={start:[{token:"empty",regex:/$/},{token:"literal",regex:/^\.{4,}\s*$/,next:"listingBlock"},{token:"literal",regex:/^-{4,}\s*$/,next:"literalBlock"},{token:"string",regex:/^\+{4,}\s*$/,next:"passthroughBlock"},{token:"keyword",regex:/^={4,}\s*$/},{token:"text",regex:/^\s*$/},{token:"empty",regex:"",next:"dissallowDelimitedBlock"}],dissallowDelimitedBlock:[{include:"paragraphEnd"},{token:"comment",regex:"^//.+$"},{token:"keyword",regex:"^(?:NOTE|TIP|IMPORTANT|WARNING|CAUTION):"},{include:"listStart"},{token:"literal",regex:/^\s+.+$/,next:"indentedBlock"},{token:"empty",regex:"",next:"text"}],paragraphEnd:[{token:"doc.comment",regex:/^\/{4,}\s*$/,next:"commentBlock"},{token:"tableBlock",regex:/^\s*[|!]=+\s*$/,next:"tableBlock"},{token:"keyword",regex:/^(?:--|''')\s*$/,next:"start"},{token:"option",regex:/^\[.*\]\s*$/,next:"start"},{token:"pageBreak",regex:/^>{3,}$/,next:"start"},{token:"literal",regex:/^\.{4,}\s*$/,next:"listingBlock"},{token:"titleUnderline",regex:/^(?:={2,}|-{2,}|~{2,}|\^{2,}|\+{2,})\s*$/,next:"start"},{token:"singleLineTitle",regex:/^={1,5}\s+\S.*$/,next:"start"},{token:"otherBlock",regex:/^(?:\*{2,}|_{2,})\s*$/,next:"start"},{token:"optionalTitle",regex:/^\.[^.\s].+$/,next:"start"}],listStart:[{token:"keyword",regex:/^\s*(?:\d+\.|[a-zA-Z]\.|[ixvmIXVM]+\)|\*{1,5}|-|\.{1,5})\s/,next:"listText"},{token:"meta.tag",regex:/^.+(?::{2,4}|;;)(?: |$)/,next:"listText"},{token:"support.function.list.callout",regex:/^(?:<\d+>|\d+>|>) /,next:"text"},{token:"keyword",regex:/^\+\s*$/,next:"start"}],text:[{token:["link","variable.language"],regex:/((?:https?:\/\/|ftp:\/\/|file:\/\/|mailto:|callto:)[^\s\[]+)(\[.*?\])/},{token:"link",regex:/(?:https?:\/\/|ftp:\/\/|file:\/\/|mailto:|callto:)[^\s\[]+/},{token:"link",regex:/\b[\w\.\/\-]+@[\w\.\/\-]+\b/},{include:"macros"},{include:"paragraphEnd"},{token:"literal",regex:/\+{3,}/,next:"smallPassthrough"},{token:"escape",regex:/\((?:C|TM|R)\)|\.{3}|->|<-|=>|<=|&#(?:\d+|x[a-fA-F\d]+);|(?: |^)--(?=\s+\S)/},{token:"escape",regex:/\\[_*'`+#]|\\{2}[_*'`+#]{2}/},{token:"keyword",regex:/\s\+$/},{token:"text",regex:e},{token:["keyword","string","keyword"],regex:/(<<[\w\d\-$]+,)(.*?)(>>|$)/},{token:"keyword",regex:/<<[\w\d\-$]+,?|>>/},{token:"constant.character",regex:/\({2,3}.*?\){2,3}/},{token:"keyword",regex:/\[\[.+?\]\]/},{token:"support",regex:/^\[{3}[\w\d =\-]+\]{3}/},{include:"quotes"},{token:"empty",regex:/^\s*$/,next:"start"}],listText:[{include:"listStart"},{include:"text"}],indentedBlock:[{token:"literal",regex:/^[\s\w].+$/,next:"indentedBlock"},{token:"literal",regex:"",next:"start"}],listingBlock:[{token:"literal",regex:/^\.{4,}\s*$/,next:"dissallowDelimitedBlock"},{token:"constant.numeric",regex:"<\\d+>"},{token:"literal",regex:"[^<]+"},{token:"literal",regex:"<"}],literalBlock:[{token:"literal",regex:/^-{4,}\s*$/,next:"dissallowDelimitedBlock"},{token:"constant.numeric",regex:"<\\d+>"},{token:"literal",regex:"[^<]+"},{token:"literal",regex:"<"}],passthroughBlock:[{token:"literal",regex:/^\+{4,}\s*$/,next:"dissallowDelimitedBlock"},{token:"literal",regex:e+"|\\d+"},{include:"macros"},{token:"literal",regex:"."}],smallPassthrough:[{token:"literal",regex:/[+]{3,}/,next:"dissallowDelimitedBlock"},{token:"literal",regex:/^\s*$/,next:"dissallowDelimitedBlock"},{token:"literal",regex:e+"|\\d+"},{include:"macros"}],commentBlock:[{token:"doc.comment",regex:/^\/{4,}\s*$/,next:"dissallowDelimitedBlock"},{token:"doc.comment",regex:"^.*$"}],tableBlock:[{token:"tableBlock",regex:/^\s*\|={3,}\s*$/,next:"dissallowDelimitedBlock"},{token:"tableBlock",regex:/^\s*!={3,}\s*$/,next:"innerTableBlock"},{token:"tableBlock",regex:/\|/},{include:"text",noEscape:!0}],innerTableBlock:[{token:"tableBlock",regex:/^\s*!={3,}\s*$/,next:"tableBlock"},{token:"tableBlock",regex:/^\s*|={3,}\s*$/,next:"dissallowDelimitedBlock"},{token:"tableBlock",regex:/\!/}],macros:[{token:"macro",regex:/{[\w\-$]+}/},{token:["text","string","text","constant.character","text"],regex:/({)([\w\-$]+)(:)?(.+)?(})/},{token:["text","markup.list.macro","keyword","string"],regex:/(\w+)(footnote(?:ref)?::?)([^\s\[]+)?(\[.*?\])?/},{token:["markup.list.macro","keyword","string"],regex:/([a-zA-Z\-][\w\.\/\-]*::?)([^\s\[]+)(\[.*?\])?/},{token:["markup.list.macro","keyword"],regex:/([a-zA-Z\-][\w\.\/\-]+::?)(\[.*?\])/},{token:"keyword",regex:/^:.+?:(?= |$)/}],quotes:[{token:"string.italic",regex:/__[^_\s].*?__/},{token:"string.italic",regex:t("_")},{token:"keyword.bold",regex:/\*\*[^*\s].*?\*\*/},{token:"keyword.bold",regex:t("\\*")},{token:"literal",regex:t("\\+")},{token:"literal",regex:/\+\+[^+\s].*?\+\+/},{token:"literal",regex:/\$\$.+?\$\$/},{token:"literal",regex:t("`")},{token:"keyword",regex:t("^")},{token:"keyword",regex:t("~")},{token:"keyword",regex:/##?/},{token:"keyword",regex:/(?:\B|^)``|\b''/}]};var n={macro:"constant.character",tableBlock:"doc.comment",titleUnderline:"markup.heading",singleLineTitle:"markup.heading",pageBreak:"string",option:"string.regexp",otherBlock:"markup.list",literal:"support.function",optionalTitle:"constant.numeric",escape:"constant.language.escape",link:"markup.underline.list"};for(var r in this.$rules){var i=this.$rules[r];for(var s=i.length;s--;){var o=i[s];if(o.include||typeof o=="string"){var u=[s,1].concat(this.$rules[o.include||o]);o.noEscape&&(u=u.filter(function(e){return!e.next})),i.splice.apply(i,u)}else o.token in n&&(o.token=n[o.token])}}};r.inherits(s,i),t.AsciidocHighlightRules=s}),ace.define("ace/mode/folding/asciidoc",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.foldingStartMarker=/^(?:\|={10,}|[\.\/=\-~^+]{4,}\s*$|={1,5} )/,this.singleLineHeadingRe=/^={1,5}(?=\s+\S)/,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?r[0]=="="?this.singleLineHeadingRe.test(r)?"start":e.getLine(n-1).length!=e.getLine(n).length?"":"start":e.bgTokenizer.getState(n)=="dissallowDelimitedBlock"?"end":"start":""},this.getFoldWidgetRange=function(e,t,n){function l(t){return f=e.getTokens(t)[0],f&&f.type}function d(){var t=f.value.match(p);if(t)return t[0].length;var r=c.indexOf(f.value[0])+1;return r==1&&e.getLine(n-1).length!=e.getLine(n).length?Infinity:r}var r=e.getLine(n),i=r.length,o=e.getLength(),u=n,a=n;if(!r.match(this.foldingStartMarker))return;var f,c=["=","-","~","^","+"],h="markup.heading",p=this.singleLineHeadingRe;if(l(n)==h){var v=d();while(++n<o){if(l(n)!=h)continue;var m=d();if(m<=v)break}var g=f&&f.value.match(this.singleLineHeadingRe);a=g?n-1:n-2;if(a>u)while(a>u&&(!l(a)||f.value[0]=="["))a--;if(a>u){var y=e.getLine(a).length;return new s(u,i,a,y)}}else{var b=e.bgTokenizer.getState(n);if(b=="dissallowDelimitedBlock"){while(n-->0)if(e.bgTokenizer.getState(n).lastIndexOf("Block")==-1)break;a=n+1;if(a<u){var y=e.getLine(n).length;return new s(a,5,u,i-5)}}else{while(++n<o)if(e.bgTokenizer.getState(n)=="dissallowDelimitedBlock")break;a=n;if(a>u){var y=e.getLine(n).length;return new s(u,5,a,y-5)}}}}}.call(o.prototype)}),ace.define("ace/mode/asciidoc",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/asciidoc_highlight_rules","ace/mode/folding/asciidoc"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./asciidoc_highlight_rules").AsciidocHighlightRules,o=e("./folding/asciidoc").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.type="text",this.getNextLineIndent=function(e,t,n){if(e=="listblock"){var r=/^((?:.+)?)([-+*][ ]+)/.exec(t);return r?(new Array(r[1].length+1)).join(" ")+r[2]:""}return this.$getIndent(t)},this.$id="ace/mode/asciidoc"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-assembly_x86.js b/dist/assets/js/vendor/ace-nc/mode-assembly_x86.js
            new file mode 100644
            index 0000000000..06378b61de
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-assembly_x86.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/assembly_x86_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"keyword.control.assembly",regex:"\\b(?:aaa|aad|aam|aas|adc|add|addpd|addps|addsd|addss|addsubpd|addsubps|aesdec|aesdeclast|aesenc|aesenclast|aesimc|aeskeygenassist|and|andpd|andps|andnpd|andnps|arpl|blendpd|blendps|blendvpd|blendvps|bound|bsf|bsr|bswap|bt|btc|btr|bts|cbw|cwde|cdqe|clc|cld|cflush|clts|cmc|cmov(?:n?e|ge?|ae?|le?|be?|n?o|n?z)|cmp|cmppd|cmpps|cmps|cnpsb|cmpsw|cmpsd|cmpsq|cmpss|cmpxchg|cmpxchg8b|cmpxchg16b|comisd|comiss|cpuid|crc32|cvtdq2pd|cvtdq2ps|cvtpd2dq|cvtpd2pi|cvtpd2ps|cvtpi2pd|cvtpi2ps|cvtps2dq|cvtps2pd|cvtps2pi|cvtsd2si|cvtsd2ss|cvts2sd|cvtsi2ss|cvtss2sd|cvtss2si|cvttpd2dq|cvtpd2pi|cvttps2dq|cvttps2pi|cvttps2dq|cvttps2pi|cvttsd2si|cvttss2si|cwd|cdq|cqo|daa|das|dec|div|divpd|divps|divsd|divss|dppd|dpps|emms|enter|extractps|f2xm1|fabs|fadd|faddp|fiadd|fbld|fbstp|fchs|fclex|fnclex|fcmov(?:n?e|ge?|ae?|le?|be?|n?o|n?z)|fcom|fcmop|fcompp|fcomi|fcomip|fucomi|fucomip|fcos|fdecstp|fdiv|fdivp|fidiv|fdivr|fdivrp|fidivr|ffree|ficom|ficomp|fild|fincstp|finit|fnint|fist|fistp|fisttp|fld|fld1|fldl2t|fldl2e|fldpi|fldlg2|fldln2|fldz|fldcw|fldenv|fmul|fmulp|fimul|fnop|fpatan|fprem|fprem1|fptan|frndint|frstor|fsave|fnsave|fscale|fsin|fsincos|fsqrt|fst|fstp|fstcw|fnstcw|fstenv|fnstenv|fsts|fnstsw|fsub|fsubp|fisub|fsubr|fsubrp|fisubr|ftst|fucom|fucomp|fucompp|fxam|fxch|fxrstor|fxsave|fxtract|fyl2x|fyl2xp1|haddpd|haddps|husbpd|hsubps|idiv|imul|in|inc|ins|insb|insw|insd|insertps|int|into|invd|invplg|invpcid|iret|iretd|iretq|lahf|lar|lddqu|ldmxcsr|lds|les|lfs|lgs|lss|lea|leave|lfence|lgdt|lidt|llgdt|lmsw|lock|lods|lodsb|lodsw|lodsd|lodsq|lsl|ltr|maskmovdqu|maskmovq|maxpd|maxps|maxsd|maxss|mfence|minpd|minps|minsd|minss|monitor|mov|movapd|movaps|movbe|movd|movq|movddup|movdqa|movdqu|movq2q|movhlps|movhpd|movhps|movlhps|movlpd|movlps|movmskpd|movmskps|movntdqa|movntdq|movnti|movntpd|movntps|movntq|movq|movq2dq|movs|movsb|movsw|movsd|movsq|movsd|movshdup|movsldup|movss|movsx|movsxd|movupd|movups|movzx|mpsadbw|mul|mulpd|mulps|mulsd|mulss|mwait|neg|not|or|orpd|orps|out|outs|outsb|outsw|outsd|pabsb|pabsw|pabsd|packsswb|packssdw|packusdw|packuswbpaddb|paddw|paddd|paddq|paddsb|paddsw|paddusb|paddusw|palignr|pand|pandn|pause|pavgb|pavgw|pblendvb|pblendw|pclmulqdq|pcmpeqb|pcmpeqw|pcmpeqd|pcmpeqq|pcmpestri|pcmpestrm|pcmptb|pcmptgw|pcmpgtd|pcmpgtq|pcmpistri|pcmpisrm|pextrb|pextrd|pextrq|pextrw|phaddw|phaddd|phaddsw|phinposuw|phsubw|phsubd|phsubsw|pinsrb|pinsrd|pinsrq|pinsrw|pmaddubsw|pmadddwd|pmaxsb|pmaxsd|pmaxsw|pmaxsw|pmaxub|pmaxud|pmaxuw|pminsb|pminsd|pminsw|pminub|pminud|pminuw|pmovmskb|pmovsx|pmovzx|pmuldq|pmulhrsw|pmulhuw|pmulhw|pmulld|pmullw|pmuludw|pop|popa|popad|popcnt|popf|popfd|popfq|por|prefetch|psadbw|pshufb|pshufd|pshufhw|pshuflw|pshufw|psignb|psignw|psignd|pslldq|psllw|pslld|psllq|psraw|psrad|psrldq|psrlw|psrld|psrlq|psubb|psubw|psubd|psubq|psubsb|psubsw|psubusb|psubusw|test|ptest|punpckhbw|punpckhwd|punpckhdq|punpckhddq|punpcklbw|punpcklwd|punpckldq|punpckldqd|push|pusha|pushad|pushf|pushfd|pxor|prcl|rcr|rol|ror|rcpps|rcpss|rdfsbase|rdgsbase|rdmsr|rdpmc|rdrand|rdtsc|rdtscp|rep|repe|repz|repne|repnz|roundpd|roundps|roundsd|roundss|rsm|rsqrps|rsqrtss|sahf|sal|sar|shl|shr|sbb|scas|scasb|scasw|scasd|set(?:n?e|ge?|ae?|le?|be?|n?o|n?z)|sfence|sgdt|shld|shrd|shufpd|shufps|sidt|sldt|smsw|sqrtpd|sqrtps|sqrtsd|sqrtss|stc|std|stmxcsr|stos|stosb|stosw|stosd|stosq|str|sub|subpd|subps|subsd|subss|swapgs|syscall|sysenter|sysexit|sysret|teset|ucomisd|ucomiss|ud2|unpckhpd|unpckhps|unpcklpd|unpcklps|vbroadcast|vcvtph2ps|vcvtp2sph|verr|verw|vextractf128|vinsertf128|vmaskmov|vpermilpd|vpermilps|vperm2f128|vtestpd|vtestps|vzeroall|vzeroupper|wait|fwait|wbinvd|wrfsbase|wrgsbase|wrmsr|xadd|xchg|xgetbv|xlat|xlatb|xor|xorpd|xorps|xrstor|xsave|xsaveopt|xsetbv|lzcnt|extrq|insertq|movntsd|movntss|vfmaddpd|vfmaddps|vfmaddsd|vfmaddss|vfmaddsubbpd|vfmaddsubps|vfmsubaddpd|vfmsubaddps|vfmsubpd|vfmsubps|vfmsubsd|vfnmaddpd|vfnmaddps|vfnmaddsd|vfnmaddss|vfnmsubpd|vfnmusbps|vfnmusbsd|vfnmusbss|cvt|xor|cli|sti|hlt|nop|lock|wait|enter|leave|ret|loop(?:n?e|n?z)?|call|j(?:mp|n?e|ge?|ae?|le?|be?|n?o|n?z))\\b",caseInsensitive:!0},{token:"variable.parameter.register.assembly",regex:"\\b(?:CS|DS|ES|FS|GS|SS|RAX|EAX|RBX|EBX|RCX|ECX|RDX|EDX|RCX|RIP|EIP|IP|RSP|ESP|SP|RSI|ESI|SI|RDI|EDI|DI|RFLAGS|EFLAGS|FLAGS|R8-15|(?:Y|X)MM(?:[0-9]|10|11|12|13|14|15)|(?:A|B|C|D)(?:X|H|L)|CR(?:[0-4]|DR(?:[0-7]|TR6|TR7|EFER)))\\b",caseInsensitive:!0},{token:"constant.character.decimal.assembly",regex:"\\b[0-9]+\\b"},{token:"constant.character.hexadecimal.assembly",regex:"\\b0x[A-F0-9]+\\b",caseInsensitive:!0},{token:"constant.character.hexadecimal.assembly",regex:"\\b[A-F0-9]+h\\b",caseInsensitive:!0},{token:"string.assembly",regex:/'([^\\']|\\.)*'/},{token:"string.assembly",regex:/"([^\\"]|\\.)*"/},{token:"support.function.directive.assembly",regex:"^\\[",push:[{token:"support.function.directive.assembly",regex:"\\]$",next:"pop"},{defaultToken:"support.function.directive.assembly"}]},{token:["support.function.directive.assembly","support.function.directive.assembly","entity.name.function.assembly"],regex:"(^struc)( )([_a-zA-Z][_a-zA-Z0-9]*)"},{token:"support.function.directive.assembly",regex:"^endstruc\\b"},{token:["support.function.directive.assembly","entity.name.function.assembly","support.function.directive.assembly","constant.character.assembly"],regex:"^(%macro )([_a-zA-Z][_a-zA-Z0-9]*)( )([0-9]+)"},{token:"support.function.directive.assembly",regex:"^%endmacro"},{token:["text","support.function.directive.assembly","text","entity.name.function.assembly"],regex:"(\\s*)(%define|%xdefine|%idefine|%undef|%assign|%defstr|%strcat|%strlen|%substr|%00|%0|%rotate|%rep|%endrep|%include|\\$\\$|\\$|%unmacro|%if|%elif|%else|%endif|%(?:el)?ifdef|%(?:el)?ifmacro|%(?:el)?ifctx|%(?:el)?ifidn|%(?:el)?ifidni|%(?:el)?ifid|%(?:el)?ifnum|%(?:el)?ifstr|%(?:el)?iftoken|%(?:el)?ifempty|%(?:el)?ifenv|%pathsearch|%depend|%use|%push|%pop|%repl|%arg|%stacksize|%local|%error|%warning|%fatal|%line|%!|%comment|%endcomment|__NASM_VERSION_ID__|__NASM_VER__|__FILE__|__LINE__|__BITS__|__OUTPUT_FORMAT__|__DATE__|__TIME__|__DATE_NUM__|_TIME__NUM__|__UTC_DATE__|__UTC_TIME__|__UTC_DATE_NUM__|__UTC_TIME_NUM__|__POSIX_TIME__|__PASS__|ISTRUC|AT|IEND|BITS 16|BITS 32|BITS 64|USE16|USE32|__SECT__|ABSOLUTE|EXTERN|GLOBAL|COMMON|CPU|FLOAT)\\b( ?)((?:[_a-zA-Z][_a-zA-Z0-9]*)?)",caseInsensitive:!0},{token:"support.function.directive.assembly",regex:"\\b(?:d[bwdqtoy]|res[bwdqto]|equ|times|align|alignb|sectalign|section|ptr|byte|word|dword|qword|incbin)\\b",caseInsensitive:!0},{token:"entity.name.function.assembly",regex:"^\\s*%%[\\w.]+?:$"},{token:"entity.name.function.assembly",regex:"^\\s*%\\$[\\w.]+?:$"},{token:"entity.name.function.assembly",regex:"^[\\w.]+?:"},{token:"entity.name.function.assembly",regex:"^[\\w.]+?\\b"},{token:"comment.assembly",regex:";.*$"}]},this.normalizeRules()};s.metaData={fileTypes:["asm"],name:"Assembly x86",scopeName:"source.assembly"},r.inherits(s,i),t.AssemblyX86HighlightRules=s}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/assembly_x86",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/assembly_x86_highlight_rules","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./assembly_x86_highlight_rules").AssemblyX86HighlightRules,o=e("./folding/coffee").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart=";",this.$id="ace/mode/assembly_x86"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-autohotkey.js b/dist/assets/js/vendor/ace-nc/mode-autohotkey.js
            new file mode 100644
            index 0000000000..c6a07d9bab
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-autohotkey.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/autohotkey_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="And|ByRef|Case|Const|ContinueCase|ContinueLoop|Default|Dim|Do|Else|ElseIf|EndFunc|EndIf|EndSelect|EndSwitch|EndWith|Enum|Exit|ExitLoop|False|For|Func|Global|If|In|Local|Next|Not|Or|ReDim|Return|Select|Step|Switch|Then|To|True|Until|WEnd|While|With|Abs|ACos|AdlibDisable|AdlibEnable|Asc|AscW|ASin|Assign|ATan|AutoItSetOption|AutoItWinGetTitle|AutoItWinSetTitle|Beep|Binary|BinaryLen|BinaryMid|BinaryToString|BitAND|BitNOT|BitOR|BitRotate|BitShift|BitXOR|BlockInput|Break|Call|CDTray|Ceiling|Chr|ChrW|ClipGet|ClipPut|ConsoleRead|ConsoleWrite|ConsoleWriteError|ControlClick|ControlCommand|ControlDisable|ControlEnable|ControlFocus|ControlGetFocus|ControlGetHandle|ControlGetPos|ControlGetText|ControlHide|ControlListView|ControlMove|ControlSend|ControlSetText|ControlShow|ControlTreeView|Cos|Dec|DirCopy|DirCreate|DirGetSize|DirMove|DirRemove|DllCall|DllCallbackFree|DllCallbackGetPtr|DllCallbackRegister|DllClose|DllOpen|DllStructCreate|DllStructGetData|DllStructGetPtr|DllStructGetSize|DllStructSetData|DriveGetDrive|DriveGetFileSystem|DriveGetLabel|DriveGetSerial|DriveGetType|DriveMapAdd|DriveMapDel|DriveMapGet|DriveSetLabel|DriveSpaceFree|DriveSpaceTotal|DriveStatus|EnvGet|EnvSet|EnvUpdate|Eval|Execute|Exp|FileChangeDir|FileClose|FileCopy|FileCreateNTFSLink|FileCreateShortcut|FileDelete|FileExists|FileFindFirstFile|FileFindNextFile|FileGetAttrib|FileGetLongName|FileGetShortcut|FileGetShortName|FileGetSize|FileGetTime|FileGetVersion|FileInstall|FileMove|FileOpen|FileOpenDialog|FileRead|FileReadLine|FileRecycle|FileRecycleEmpty|FileSaveDialog|FileSelectFolder|FileSetAttrib|FileSetTime|FileWrite|FileWriteLine|Floor|FtpSetProxy|GUICreate|GUICtrlCreateAvi|GUICtrlCreateButton|GUICtrlCreateCheckbox|GUICtrlCreateCombo|GUICtrlCreateContextMenu|GUICtrlCreateDate|GUICtrlCreateDummy|GUICtrlCreateEdit|GUICtrlCreateGraphic|GUICtrlCreateGroup|GUICtrlCreateIcon|GUICtrlCreateInput|GUICtrlCreateLabel|GUICtrlCreateList|GUICtrlCreateListView|GUICtrlCreateListViewItem|GUICtrlCreateMenu|GUICtrlCreateMenuItem|GUICtrlCreateMonthCal|GUICtrlCreateObj|GUICtrlCreatePic|GUICtrlCreateProgress|GUICtrlCreateRadio|GUICtrlCreateSlider|GUICtrlCreateTab|GUICtrlCreateTabItem|GUICtrlCreateTreeView|GUICtrlCreateTreeViewItem|GUICtrlCreateUpdown|GUICtrlDelete|GUICtrlGetHandle|GUICtrlGetState|GUICtrlRead|GUICtrlRecvMsg|GUICtrlRegisterListViewSort|GUICtrlSendMsg|GUICtrlSendToDummy|GUICtrlSetBkColor|GUICtrlSetColor|GUICtrlSetCursor|GUICtrlSetData|GUICtrlSetFont|GUICtrlSetDefColor|GUICtrlSetDefBkColor|GUICtrlSetGraphic|GUICtrlSetImage|GUICtrlSetLimit|GUICtrlSetOnEvent|GUICtrlSetPos|GUICtrlSetResizing|GUICtrlSetState|GUICtrlSetStyle|GUICtrlSetTip|GUIDelete|GUIGetCursorInfo|GUIGetMsg|GUIGetStyle|GUIRegisterMsg|GUISetAccelerators()|GUISetBkColor|GUISetCoord|GUISetCursor|GUISetFont|GUISetHelp|GUISetIcon|GUISetOnEvent|GUISetState|GUISetStyle|GUIStartGroup|GUISwitch|Hex|HotKeySet|HttpSetProxy|HWnd|InetGet|InetGetSize|IniDelete|IniRead|IniReadSection|IniReadSectionNames|IniRenameSection|IniWrite|IniWriteSection|InputBox|Int|IsAdmin|IsArray|IsBinary|IsBool|IsDeclared|IsDllStruct|IsFloat|IsHWnd|IsInt|IsKeyword|IsNumber|IsObj|IsPtr|IsString|Log|MemGetStats|Mod|MouseClick|MouseClickDrag|MouseDown|MouseGetCursor|MouseGetPos|MouseMove|MouseUp|MouseWheel|MsgBox|Number|ObjCreate|ObjEvent|ObjGet|ObjName|Opt|Ping|PixelChecksum|PixelGetColor|PixelSearch|PluginClose|PluginOpen|ProcessClose|ProcessExists|ProcessGetStats|ProcessList|ProcessSetPriority|ProcessWait|ProcessWaitClose|ProgressOff|ProgressOn|ProgressSet|Ptr|Random|RegDelete|RegEnumKey|RegEnumVal|RegRead|RegWrite|Round|Run|RunAs|RunAsWait|RunWait|Send|SendKeepActive|SetError|SetExtended|ShellExecute|ShellExecuteWait|Shutdown|Sin|Sleep|SoundPlay|SoundSetWaveVolume|SplashImageOn|SplashOff|SplashTextOn|Sqrt|SRandom|StatusbarGetText|StderrRead|StdinWrite|StdioClose|StdoutRead|String|StringAddCR|StringCompare|StringFormat|StringInStr|StringIsAlNum|StringIsAlpha|StringIsASCII|StringIsDigit|StringIsFloat|StringIsInt|StringIsLower|StringIsSpace|StringIsUpper|StringIsXDigit|StringLeft|StringLen|StringLower|StringMid|StringRegExp|StringRegExpReplace|StringReplace|StringRight|StringSplit|StringStripCR|StringStripWS|StringToBinary|StringTrimLeft|StringTrimRight|StringUpper|Tan|TCPAccept|TCPCloseSocket|TCPConnect|TCPListen|TCPNameToIP|TCPRecv|TCPSend|TCPShutdown|TCPStartup|TimerDiff|TimerInit|ToolTip|TrayCreateItem|TrayCreateMenu|TrayGetMsg|TrayItemDelete|TrayItemGetHandle|TrayItemGetState|TrayItemGetText|TrayItemSetOnEvent|TrayItemSetState|TrayItemSetText|TraySetClick|TraySetIcon|TraySetOnEvent|TraySetPauseIcon|TraySetState|TraySetToolTip|TrayTip|UBound|UDPBind|UDPCloseSocket|UDPOpen|UDPRecv|UDPSend|UDPShutdown|UDPStartup|VarGetType|WinActivate|WinActive|WinClose|WinExists|WinFlash|WinGetCaretPos|WinGetClassList|WinGetClientSize|WinGetHandle|WinGetPos|WinGetProcess|WinGetState|WinGetText|WinGetTitle|WinKill|WinList|WinMenuSelectItem|WinMinimizeAll|WinMinimizeAllUndo|WinMove|WinSetOnTop|WinSetState|WinSetTitle|WinSetTrans|WinWait|WinWaitActive|WinWaitClose|WinWaitNotActive|ArrayAdd|ArrayBinarySearch|ArrayConcatenate|ArrayDelete|ArrayDisplay|ArrayFindAll|ArrayInsert|ArrayMax|ArrayMaxIndex|ArrayMin|ArrayMinIndex|ArrayPop|ArrayPush|ArrayReverse|ArraySearch|ArraySort|ArraySwap|ArrayToClip|ArrayToString|ArrayTrim|ChooseColor|ChooseFont|ClipBoard_ChangeChain|ClipBoard_Close|ClipBoard_CountFormats|ClipBoard_Empty|ClipBoard_EnumFormats|ClipBoard_FormatStr|ClipBoard_GetData|ClipBoard_GetDataEx|ClipBoard_GetFormatName|ClipBoard_GetOpenWindow|ClipBoard_GetOwner|ClipBoard_GetPriorityFormat|ClipBoard_GetSequenceNumber|ClipBoard_GetViewer|ClipBoard_IsFormatAvailable|ClipBoard_Open|ClipBoard_RegisterFormat|ClipBoard_SetData|ClipBoard_SetDataEx|ClipBoard_SetViewer|ClipPutFile|ColorConvertHSLtoRGB|ColorConvertRGBtoHSL|ColorGetBlue|ColorGetGreen|ColorGetRed|Date_Time_CompareFileTime|Date_Time_DOSDateTimeToArray|Date_Time_DOSDateTimeToFileTime|Date_Time_DOSDateTimeToStr|Date_Time_DOSDateToArray|Date_Time_DOSDateToStr|Date_Time_DOSTimeToArray|Date_Time_DOSTimeToStr|Date_Time_EncodeFileTime|Date_Time_EncodeSystemTime|Date_Time_FileTimeToArray|Date_Time_FileTimeToDOSDateTime|Date_Time_FileTimeToLocalFileTime|Date_Time_FileTimeToStr|Date_Time_FileTimeToSystemTime|Date_Time_GetFileTime|Date_Time_GetLocalTime|Date_Time_GetSystemTime|Date_Time_GetSystemTimeAdjustment|Date_Time_GetSystemTimeAsFileTime|Date_Time_GetSystemTimes|Date_Time_GetTickCount|Date_Time_GetTimeZoneInformation|Date_Time_LocalFileTimeToFileTime|Date_Time_SetFileTime|Date_Time_SetLocalTime|Date_Time_SetSystemTime|Date_Time_SetSystemTimeAdjustment|Date_Time_SetTimeZoneInformation|Date_Time_SystemTimeToArray|Date_Time_SystemTimeToDateStr|Date_Time_SystemTimeToDateTimeStr|Date_Time_SystemTimeToFileTime|Date_Time_SystemTimeToTimeStr|Date_Time_SystemTimeToTzSpecificLocalTime|Date_Time_TzSpecificLocalTimeToSystemTime|DateAdd|DateDayOfWeek|DateDaysInMonth|DateDiff|DateIsLeapYear|DateIsValid|DateTimeFormat|DateTimeSplit|DateToDayOfWeek|DateToDayOfWeekISO|DateToDayValue|DateToMonth|DayValueToDate|DebugBugReportEnv|DebugOut|DebugSetup|Degree|EventLog__Backup|EventLog__Clear|EventLog__Close|EventLog__Count|EventLog__DeregisterSource|EventLog__Full|EventLog__Notify|EventLog__Oldest|EventLog__Open|EventLog__OpenBackup|EventLog__Read|EventLog__RegisterSource|EventLog__Report|FileCountLines|FileCreate|FileListToArray|FilePrint|FileReadToArray|FileWriteFromArray|FileWriteLog|FileWriteToLine|GDIPlus_ArrowCapCreate|GDIPlus_ArrowCapDispose|GDIPlus_ArrowCapGetFillState|GDIPlus_ArrowCapGetHeight|GDIPlus_ArrowCapGetMiddleInset|GDIPlus_ArrowCapGetWidth|GDIPlus_ArrowCapSetFillState|GDIPlus_ArrowCapSetHeight|GDIPlus_ArrowCapSetMiddleInset|GDIPlus_ArrowCapSetWidth|GDIPlus_BitmapCloneArea|GDIPlus_BitmapCreateFromFile|GDIPlus_BitmapCreateFromGraphics|GDIPlus_BitmapCreateFromHBITMAP|GDIPlus_BitmapCreateHBITMAPFromBitmap|GDIPlus_BitmapDispose|GDIPlus_BitmapLockBits|GDIPlus_BitmapUnlockBits|GDIPlus_BrushClone|GDIPlus_BrushCreateSolid|GDIPlus_BrushDispose|GDIPlus_BrushGetType|GDIPlus_CustomLineCapDispose|GDIPlus_Decoders|GDIPlus_DecodersGetCount|GDIPlus_DecodersGetSize|GDIPlus_Encoders|GDIPlus_EncodersGetCLSID|GDIPlus_EncodersGetCount|GDIPlus_EncodersGetParamList|GDIPlus_EncodersGetParamListSize|GDIPlus_EncodersGetSize|GDIPlus_FontCreate|GDIPlus_FontDispose|GDIPlus_FontFamilyCreate|GDIPlus_FontFamilyDispose|GDIPlus_GraphicsClear|GDIPlus_GraphicsCreateFromHDC|GDIPlus_GraphicsCreateFromHWND|GDIPlus_GraphicsDispose|GDIPlus_GraphicsDrawArc|GDIPlus_GraphicsDrawBezier|GDIPlus_GraphicsDrawClosedCurve|GDIPlus_GraphicsDrawCurve|GDIPlus_GraphicsDrawEllipse|GDIPlus_GraphicsDrawImage|GDIPlus_GraphicsDrawImageRect|GDIPlus_GraphicsDrawImageRectRect|GDIPlus_GraphicsDrawLine|GDIPlus_GraphicsDrawPie|GDIPlus_GraphicsDrawPolygon|GDIPlus_GraphicsDrawRect|GDIPlus_GraphicsDrawString|GDIPlus_GraphicsDrawStringEx|GDIPlus_GraphicsFillClosedCurve|GDIPlus_GraphicsFillEllipse|GDIPlus_GraphicsFillPie|GDIPlus_GraphicsFillRect|GDIPlus_GraphicsGetDC|GDIPlus_GraphicsGetSmoothingMode|GDIPlus_GraphicsMeasureString|GDIPlus_GraphicsReleaseDC|GDIPlus_GraphicsSetSmoothingMode|GDIPlus_GraphicsSetTransform|GDIPlus_ImageDispose|GDIPlus_ImageGetGraphicsContext|GDIPlus_ImageGetHeight|GDIPlus_ImageGetWidth|GDIPlus_ImageLoadFromFile|GDIPlus_ImageSaveToFile|GDIPlus_ImageSaveToFileEx|GDIPlus_MatrixCreate|GDIPlus_MatrixDispose|GDIPlus_MatrixRotate|GDIPlus_ParamAdd|GDIPlus_ParamInit|GDIPlus_PenCreate|GDIPlus_PenDispose|GDIPlus_PenGetAlignment|GDIPlus_PenGetColor|GDIPlus_PenGetCustomEndCap|GDIPlus_PenGetDashCap|GDIPlus_PenGetDashStyle|GDIPlus_PenGetEndCap|GDIPlus_PenGetWidth|GDIPlus_PenSetAlignment|GDIPlus_PenSetColor|GDIPlus_PenSetCustomEndCap|GDIPlus_PenSetDashCap|GDIPlus_PenSetDashStyle|GDIPlus_PenSetEndCap|GDIPlus_PenSetWidth|GDIPlus_RectFCreate|GDIPlus_Shutdown|GDIPlus_Startup|GDIPlus_StringFormatCreate|GDIPlus_StringFormatDispose|GetIP|GUICtrlAVI_Close|GUICtrlAVI_Create|GUICtrlAVI_Destroy|GUICtrlAVI_Open|GUICtrlAVI_OpenEx|GUICtrlAVI_Play|GUICtrlAVI_Seek|GUICtrlAVI_Show|GUICtrlAVI_Stop|GUICtrlButton_Click|GUICtrlButton_Create|GUICtrlButton_Destroy|GUICtrlButton_Enable|GUICtrlButton_GetCheck|GUICtrlButton_GetFocus|GUICtrlButton_GetIdealSize|GUICtrlButton_GetImage|GUICtrlButton_GetImageList|GUICtrlButton_GetState|GUICtrlButton_GetText|GUICtrlButton_GetTextMargin|GUICtrlButton_SetCheck|GUICtrlButton_SetFocus|GUICtrlButton_SetImage|GUICtrlButton_SetImageList|GUICtrlButton_SetSize|GUICtrlButton_SetState|GUICtrlButton_SetStyle|GUICtrlButton_SetText|GUICtrlButton_SetTextMargin|GUICtrlButton_Show|GUICtrlComboBox_AddDir|GUICtrlComboBox_AddString|GUICtrlComboBox_AutoComplete|GUICtrlComboBox_BeginUpdate|GUICtrlComboBox_Create|GUICtrlComboBox_DeleteString|GUICtrlComboBox_Destroy|GUICtrlComboBox_EndUpdate|GUICtrlComboBox_FindString|GUICtrlComboBox_FindStringExact|GUICtrlComboBox_GetComboBoxInfo|GUICtrlComboBox_GetCount|GUICtrlComboBox_GetCurSel|GUICtrlComboBox_GetDroppedControlRect|GUICtrlComboBox_GetDroppedControlRectEx|GUICtrlComboBox_GetDroppedState|GUICtrlComboBox_GetDroppedWidth|GUICtrlComboBox_GetEditSel|GUICtrlComboBox_GetEditText|GUICtrlComboBox_GetExtendedUI|GUICtrlComboBox_GetHorizontalExtent|GUICtrlComboBox_GetItemHeight|GUICtrlComboBox_GetLBText|GUICtrlComboBox_GetLBTextLen|GUICtrlComboBox_GetList|GUICtrlComboBox_GetListArray|GUICtrlComboBox_GetLocale|GUICtrlComboBox_GetLocaleCountry|GUICtrlComboBox_GetLocaleLang|GUICtrlComboBox_GetLocalePrimLang|GUICtrlComboBox_GetLocaleSubLang|GUICtrlComboBox_GetMinVisible|GUICtrlComboBox_GetTopIndex|GUICtrlComboBox_InitStorage|GUICtrlComboBox_InsertString|GUICtrlComboBox_LimitText|GUICtrlComboBox_ReplaceEditSel|GUICtrlComboBox_ResetContent|GUICtrlComboBox_SelectString|GUICtrlComboBox_SetCurSel|GUICtrlComboBox_SetDroppedWidth|GUICtrlComboBox_SetEditSel|GUICtrlComboBox_SetEditText|GUICtrlComboBox_SetExtendedUI|GUICtrlComboBox_SetHorizontalExtent|GUICtrlComboBox_SetItemHeight|GUICtrlComboBox_SetMinVisible|GUICtrlComboBox_SetTopIndex|GUICtrlComboBox_ShowDropDown|GUICtrlComboBoxEx_AddDir|GUICtrlComboBoxEx_AddString|GUICtrlComboBoxEx_BeginUpdate|GUICtrlComboBoxEx_Create|GUICtrlComboBoxEx_CreateSolidBitMap|GUICtrlComboBoxEx_DeleteString|GUICtrlComboBoxEx_Destroy|GUICtrlComboBoxEx_EndUpdate|GUICtrlComboBoxEx_FindStringExact|GUICtrlComboBoxEx_GetComboBoxInfo|GUICtrlComboBoxEx_GetComboControl|GUICtrlComboBoxEx_GetCount|GUICtrlComboBoxEx_GetCurSel|GUICtrlComboBoxEx_GetDroppedControlRect|GUICtrlComboBoxEx_GetDroppedControlRectEx|GUICtrlComboBoxEx_GetDroppedState|GUICtrlComboBoxEx_GetDroppedWidth|GUICtrlComboBoxEx_GetEditControl|GUICtrlComboBoxEx_GetEditSel|GUICtrlComboBoxEx_GetEditText|GUICtrlComboBoxEx_GetExtendedStyle|GUICtrlComboBoxEx_GetExtendedUI|GUICtrlComboBoxEx_GetImageList|GUICtrlComboBoxEx_GetItem|GUICtrlComboBoxEx_GetItemEx|GUICtrlComboBoxEx_GetItemHeight|GUICtrlComboBoxEx_GetItemImage|GUICtrlComboBoxEx_GetItemIndent|GUICtrlComboBoxEx_GetItemOverlayImage|GUICtrlComboBoxEx_GetItemParam|GUICtrlComboBoxEx_GetItemSelectedImage|GUICtrlComboBoxEx_GetItemText|GUICtrlComboBoxEx_GetItemTextLen|GUICtrlComboBoxEx_GetList|GUICtrlComboBoxEx_GetListArray|GUICtrlComboBoxEx_GetLocale|GUICtrlComboBoxEx_GetLocaleCountry|GUICtrlComboBoxEx_GetLocaleLang|GUICtrlComboBoxEx_GetLocalePrimLang|GUICtrlComboBoxEx_GetLocaleSubLang|GUICtrlComboBoxEx_GetMinVisible|GUICtrlComboBoxEx_GetTopIndex|GUICtrlComboBoxEx_InitStorage|GUICtrlComboBoxEx_InsertString|GUICtrlComboBoxEx_LimitText|GUICtrlComboBoxEx_ReplaceEditSel|GUICtrlComboBoxEx_ResetContent|GUICtrlComboBoxEx_SetCurSel|GUICtrlComboBoxEx_SetDroppedWidth|GUICtrlComboBoxEx_SetEditSel|GUICtrlComboBoxEx_SetEditText|GUICtrlComboBoxEx_SetExtendedStyle|GUICtrlComboBoxEx_SetExtendedUI|GUICtrlComboBoxEx_SetImageList|GUICtrlComboBoxEx_SetItem|GUICtrlComboBoxEx_SetItemEx|GUICtrlComboBoxEx_SetItemHeight|GUICtrlComboBoxEx_SetItemImage|GUICtrlComboBoxEx_SetItemIndent|GUICtrlComboBoxEx_SetItemOverlayImage|GUICtrlComboBoxEx_SetItemParam|GUICtrlComboBoxEx_SetItemSelectedImage|GUICtrlComboBoxEx_SetMinVisible|GUICtrlComboBoxEx_SetTopIndex|GUICtrlComboBoxEx_ShowDropDown|GUICtrlDTP_Create|GUICtrlDTP_Destroy|GUICtrlDTP_GetMCColor|GUICtrlDTP_GetMCFont|GUICtrlDTP_GetMonthCal|GUICtrlDTP_GetRange|GUICtrlDTP_GetRangeEx|GUICtrlDTP_GetSystemTime|GUICtrlDTP_GetSystemTimeEx|GUICtrlDTP_SetFormat|GUICtrlDTP_SetMCColor|GUICtrlDTP_SetMCFont|GUICtrlDTP_SetRange|GUICtrlDTP_SetRangeEx|GUICtrlDTP_SetSystemTime|GUICtrlDTP_SetSystemTimeEx|GUICtrlEdit_AppendText|GUICtrlEdit_BeginUpdate|GUICtrlEdit_CanUndo|GUICtrlEdit_CharFromPos|GUICtrlEdit_Create|GUICtrlEdit_Destroy|GUICtrlEdit_EmptyUndoBuffer|GUICtrlEdit_EndUpdate|GUICtrlEdit_Find|GUICtrlEdit_FmtLines|GUICtrlEdit_GetFirstVisibleLine|GUICtrlEdit_GetLimitText|GUICtrlEdit_GetLine|GUICtrlEdit_GetLineCount|GUICtrlEdit_GetMargins|GUICtrlEdit_GetModify|GUICtrlEdit_GetPasswordChar|GUICtrlEdit_GetRECT|GUICtrlEdit_GetRECTEx|GUICtrlEdit_GetSel|GUICtrlEdit_GetText|GUICtrlEdit_GetTextLen|GUICtrlEdit_HideBalloonTip|GUICtrlEdit_InsertText|GUICtrlEdit_LineFromChar|GUICtrlEdit_LineIndex|GUICtrlEdit_LineLength|GUICtrlEdit_LineScroll|GUICtrlEdit_PosFromChar|GUICtrlEdit_ReplaceSel|GUICtrlEdit_Scroll|GUICtrlEdit_SetLimitText|GUICtrlEdit_SetMargins|GUICtrlEdit_SetModify|GUICtrlEdit_SetPasswordChar|GUICtrlEdit_SetReadOnly|GUICtrlEdit_SetRECT|GUICtrlEdit_SetRECTEx|GUICtrlEdit_SetRECTNP|GUICtrlEdit_SetRectNPEx|GUICtrlEdit_SetSel|GUICtrlEdit_SetTabStops|GUICtrlEdit_SetText|GUICtrlEdit_ShowBalloonTip|GUICtrlEdit_Undo|GUICtrlHeader_AddItem|GUICtrlHeader_ClearFilter|GUICtrlHeader_ClearFilterAll|GUICtrlHeader_Create|GUICtrlHeader_CreateDragImage|GUICtrlHeader_DeleteItem|GUICtrlHeader_Destroy|GUICtrlHeader_EditFilter|GUICtrlHeader_GetBitmapMargin|GUICtrlHeader_GetImageList|GUICtrlHeader_GetItem|GUICtrlHeader_GetItemAlign|GUICtrlHeader_GetItemBitmap|GUICtrlHeader_GetItemCount|GUICtrlHeader_GetItemDisplay|GUICtrlHeader_GetItemFlags|GUICtrlHeader_GetItemFormat|GUICtrlHeader_GetItemImage|GUICtrlHeader_GetItemOrder|GUICtrlHeader_GetItemParam|GUICtrlHeader_GetItemRect|GUICtrlHeader_GetItemRectEx|GUICtrlHeader_GetItemText|GUICtrlHeader_GetItemWidth|GUICtrlHeader_GetOrderArray|GUICtrlHeader_GetUnicodeFormat|GUICtrlHeader_HitTest|GUICtrlHeader_InsertItem|GUICtrlHeader_Layout|GUICtrlHeader_OrderToIndex|GUICtrlHeader_SetBitmapMargin|GUICtrlHeader_SetFilterChangeTimeout|GUICtrlHeader_SetHotDivider|GUICtrlHeader_SetImageList|GUICtrlHeader_SetItem|GUICtrlHeader_SetItemAlign|GUICtrlHeader_SetItemBitmap|GUICtrlHeader_SetItemDisplay|GUICtrlHeader_SetItemFlags|GUICtrlHeader_SetItemFormat|GUICtrlHeader_SetItemImage|GUICtrlHeader_SetItemOrder|GUICtrlHeader_SetItemParam|GUICtrlHeader_SetItemText|GUICtrlHeader_SetItemWidth|GUICtrlHeader_SetOrderArray|GUICtrlHeader_SetUnicodeFormat|GUICtrlIpAddress_ClearAddress|GUICtrlIpAddress_Create|GUICtrlIpAddress_Destroy|GUICtrlIpAddress_Get|GUICtrlIpAddress_GetArray|GUICtrlIpAddress_GetEx|GUICtrlIpAddress_IsBlank|GUICtrlIpAddress_Set|GUICtrlIpAddress_SetArray|GUICtrlIpAddress_SetEx|GUICtrlIpAddress_SetFocus|GUICtrlIpAddress_SetFont|GUICtrlIpAddress_SetRange|GUICtrlIpAddress_ShowHide|GUICtrlListBox_AddFile|GUICtrlListBox_AddString|GUICtrlListBox_BeginUpdate|GUICtrlListBox_Create|GUICtrlListBox_DeleteString|GUICtrlListBox_Destroy|GUICtrlListBox_Dir|GUICtrlListBox_EndUpdate|GUICtrlListBox_FindInText|GUICtrlListBox_FindString|GUICtrlListBox_GetAnchorIndex|GUICtrlListBox_GetCaretIndex|GUICtrlListBox_GetCount|GUICtrlListBox_GetCurSel|GUICtrlListBox_GetHorizontalExtent|GUICtrlListBox_GetItemData|GUICtrlListBox_GetItemHeight|GUICtrlListBox_GetItemRect|GUICtrlListBox_GetItemRectEx|GUICtrlListBox_GetListBoxInfo|GUICtrlListBox_GetLocale|GUICtrlListBox_GetLocaleCountry|GUICtrlListBox_GetLocaleLang|GUICtrlListBox_GetLocalePrimLang|GUICtrlListBox_GetLocaleSubLang|GUICtrlListBox_GetSel|GUICtrlListBox_GetSelCount|GUICtrlListBox_GetSelItems|GUICtrlListBox_GetSelItemsText|GUICtrlListBox_GetText|GUICtrlListBox_GetTextLen|GUICtrlListBox_GetTopIndex|GUICtrlListBox_InitStorage|GUICtrlListBox_InsertString|GUICtrlListBox_ItemFromPoint|GUICtrlListBox_ReplaceString|GUICtrlListBox_ResetContent|GUICtrlListBox_SelectString|GUICtrlListBox_SelItemRange|GUICtrlListBox_SelItemRangeEx|GUICtrlListBox_SetAnchorIndex|GUICtrlListBox_SetCaretIndex|GUICtrlListBox_SetColumnWidth|GUICtrlListBox_SetCurSel|GUICtrlListBox_SetHorizontalExtent|GUICtrlListBox_SetItemData|GUICtrlListBox_SetItemHeight|GUICtrlListBox_SetLocale|GUICtrlListBox_SetSel|GUICtrlListBox_SetTabStops|GUICtrlListBox_SetTopIndex|GUICtrlListBox_Sort|GUICtrlListBox_SwapString|GUICtrlListBox_UpdateHScroll|GUICtrlListView_AddArray|GUICtrlListView_AddColumn|GUICtrlListView_AddItem|GUICtrlListView_AddSubItem|GUICtrlListView_ApproximateViewHeight|GUICtrlListView_ApproximateViewRect|GUICtrlListView_ApproximateViewWidth|GUICtrlListView_Arrange|GUICtrlListView_BeginUpdate|GUICtrlListView_CancelEditLabel|GUICtrlListView_ClickItem|GUICtrlListView_CopyItems|GUICtrlListView_Create|GUICtrlListView_CreateDragImage|GUICtrlListView_CreateSolidBitMap|GUICtrlListView_DeleteAllItems|GUICtrlListView_DeleteColumn|GUICtrlListView_DeleteItem|GUICtrlListView_DeleteItemsSelected|GUICtrlListView_Destroy|GUICtrlListView_DrawDragImage|GUICtrlListView_EditLabel|GUICtrlListView_EnableGroupView|GUICtrlListView_EndUpdate|GUICtrlListView_EnsureVisible|GUICtrlListView_FindInText|GUICtrlListView_FindItem|GUICtrlListView_FindNearest|GUICtrlListView_FindParam|GUICtrlListView_FindText|GUICtrlListView_GetBkColor|GUICtrlListView_GetBkImage|GUICtrlListView_GetCallbackMask|GUICtrlListView_GetColumn|GUICtrlListView_GetColumnCount|GUICtrlListView_GetColumnOrder|GUICtrlListView_GetColumnOrderArray|GUICtrlListView_GetColumnWidth|GUICtrlListView_GetCounterPage|GUICtrlListView_GetEditControl|GUICtrlListView_GetExtendedListViewStyle|GUICtrlListView_GetGroupInfo|GUICtrlListView_GetGroupViewEnabled|GUICtrlListView_GetHeader|GUICtrlListView_GetHotCursor|GUICtrlListView_GetHotItem|GUICtrlListView_GetHoverTime|GUICtrlListView_GetImageList|GUICtrlListView_GetISearchString|GUICtrlListView_GetItem|GUICtrlListView_GetItemChecked|GUICtrlListView_GetItemCount|GUICtrlListView_GetItemCut|GUICtrlListView_GetItemDropHilited|GUICtrlListView_GetItemEx|GUICtrlListView_GetItemFocused|GUICtrlListView_GetItemGroupID|GUICtrlListView_GetItemImage|GUICtrlListView_GetItemIndent|GUICtrlListView_GetItemParam|GUICtrlListView_GetItemPosition|GUICtrlListView_GetItemPositionX|GUICtrlListView_GetItemPositionY|GUICtrlListView_GetItemRect|GUICtrlListView_GetItemRectEx|GUICtrlListView_GetItemSelected|GUICtrlListView_GetItemSpacing|GUICtrlListView_GetItemSpacingX|GUICtrlListView_GetItemSpacingY|GUICtrlListView_GetItemState|GUICtrlListView_GetItemStateImage|GUICtrlListView_GetItemText|GUICtrlListView_GetItemTextArray|GUICtrlListView_GetItemTextString|GUICtrlListView_GetNextItem|GUICtrlListView_GetNumberOfWorkAreas|GUICtrlListView_GetOrigin|GUICtrlListView_GetOriginX|GUICtrlListView_GetOriginY|GUICtrlListView_GetOutlineColor|GUICtrlListView_GetSelectedColumn|GUICtrlListView_GetSelectedCount|GUICtrlListView_GetSelectedIndices|GUICtrlListView_GetSelectionMark|GUICtrlListView_GetStringWidth|GUICtrlListView_GetSubItemRect|GUICtrlListView_GetTextBkColor|GUICtrlListView_GetTextColor|GUICtrlListView_GetToolTips|GUICtrlListView_GetTopIndex|GUICtrlListView_GetUnicodeFormat|GUICtrlListView_GetView|GUICtrlListView_GetViewDetails|GUICtrlListView_GetViewLarge|GUICtrlListView_GetViewList|GUICtrlListView_GetViewRect|GUICtrlListView_GetViewSmall|GUICtrlListView_GetViewTile|GUICtrlListView_HideColumn|GUICtrlListView_HitTest|GUICtrlListView_InsertColumn|GUICtrlListView_InsertGroup|GUICtrlListView_InsertItem|GUICtrlListView_JustifyColumn|GUICtrlListView_MapIDToIndex|GUICtrlListView_MapIndexToID|GUICtrlListView_RedrawItems|GUICtrlListView_RegisterSortCallBack|GUICtrlListView_RemoveAllGroups|GUICtrlListView_RemoveGroup|GUICtrlListView_Scroll|GUICtrlListView_SetBkColor|GUICtrlListView_SetBkImage|GUICtrlListView_SetCallBackMask|GUICtrlListView_SetColumn|GUICtrlListView_SetColumnOrder|GUICtrlListView_SetColumnOrderArray|GUICtrlListView_SetColumnWidth|GUICtrlListView_SetExtendedListViewStyle|GUICtrlListView_SetGroupInfo|GUICtrlListView_SetHotItem|GUICtrlListView_SetHoverTime|GUICtrlListView_SetIconSpacing|GUICtrlListView_SetImageList|GUICtrlListView_SetItem|GUICtrlListView_SetItemChecked|GUICtrlListView_SetItemCount|GUICtrlListView_SetItemCut|GUICtrlListView_SetItemDropHilited|GUICtrlListView_SetItemEx|GUICtrlListView_SetItemFocused|GUICtrlListView_SetItemGroupID|GUICtrlListView_SetItemImage|GUICtrlListView_SetItemIndent|GUICtrlListView_SetItemParam|GUICtrlListView_SetItemPosition|GUICtrlListView_SetItemPosition32|GUICtrlListView_SetItemSelected|GUICtrlListView_SetItemState|GUICtrlListView_SetItemStateImage|GUICtrlListView_SetItemText|GUICtrlListView_SetOutlineColor|GUICtrlListView_SetSelectedColumn|GUICtrlListView_SetSelectionMark|GUICtrlListView_SetTextBkColor|GUICtrlListView_SetTextColor|GUICtrlListView_SetToolTips|GUICtrlListView_SetUnicodeFormat|GUICtrlListView_SetView|GUICtrlListView_SetWorkAreas|GUICtrlListView_SimpleSort|GUICtrlListView_SortItems|GUICtrlListView_SubItemHitTest|GUICtrlListView_UnRegisterSortCallBack|GUICtrlMenu_AddMenuItem|GUICtrlMenu_AppendMenu|GUICtrlMenu_CheckMenuItem|GUICtrlMenu_CheckRadioItem|GUICtrlMenu_CreateMenu|GUICtrlMenu_CreatePopup|GUICtrlMenu_DeleteMenu|GUICtrlMenu_DestroyMenu|GUICtrlMenu_DrawMenuBar|GUICtrlMenu_EnableMenuItem|GUICtrlMenu_FindItem|GUICtrlMenu_FindParent|GUICtrlMenu_GetItemBmp|GUICtrlMenu_GetItemBmpChecked|GUICtrlMenu_GetItemBmpUnchecked|GUICtrlMenu_GetItemChecked|GUICtrlMenu_GetItemCount|GUICtrlMenu_GetItemData|GUICtrlMenu_GetItemDefault|GUICtrlMenu_GetItemDisabled|GUICtrlMenu_GetItemEnabled|GUICtrlMenu_GetItemGrayed|GUICtrlMenu_GetItemHighlighted|GUICtrlMenu_GetItemID|GUICtrlMenu_GetItemInfo|GUICtrlMenu_GetItemRect|GUICtrlMenu_GetItemRectEx|GUICtrlMenu_GetItemState|GUICtrlMenu_GetItemStateEx|GUICtrlMenu_GetItemSubMenu|GUICtrlMenu_GetItemText|GUICtrlMenu_GetItemType|GUICtrlMenu_GetMenu|GUICtrlMenu_GetMenuBackground|GUICtrlMenu_GetMenuBarInfo|GUICtrlMenu_GetMenuContextHelpID|GUICtrlMenu_GetMenuData|GUICtrlMenu_GetMenuDefaultItem|GUICtrlMenu_GetMenuHeight|GUICtrlMenu_GetMenuInfo|GUICtrlMenu_GetMenuStyle|GUICtrlMenu_GetSystemMenu|GUICtrlMenu_InsertMenuItem|GUICtrlMenu_InsertMenuItemEx|GUICtrlMenu_IsMenu|GUICtrlMenu_LoadMenu|GUICtrlMenu_MapAccelerator|GUICtrlMenu_MenuItemFromPoint|GUICtrlMenu_RemoveMenu|GUICtrlMenu_SetItemBitmaps|GUICtrlMenu_SetItemBmp|GUICtrlMenu_SetItemBmpChecked|GUICtrlMenu_SetItemBmpUnchecked|GUICtrlMenu_SetItemChecked|GUICtrlMenu_SetItemData|GUICtrlMenu_SetItemDefault|GUICtrlMenu_SetItemDisabled|GUICtrlMenu_SetItemEnabled|GUICtrlMenu_SetItemGrayed|GUICtrlMenu_SetItemHighlighted|GUICtrlMenu_SetItemID|GUICtrlMenu_SetItemInfo|GUICtrlMenu_SetItemState|GUICtrlMenu_SetItemSubMenu|GUICtrlMenu_SetItemText|GUICtrlMenu_SetItemType|GUICtrlMenu_SetMenu|GUICtrlMenu_SetMenuBackground|GUICtrlMenu_SetMenuContextHelpID|GUICtrlMenu_SetMenuData|GUICtrlMenu_SetMenuDefaultItem|GUICtrlMenu_SetMenuHeight|GUICtrlMenu_SetMenuInfo|GUICtrlMenu_SetMenuStyle|GUICtrlMenu_TrackPopupMenu|GUICtrlMonthCal_Create|GUICtrlMonthCal_Destroy|GUICtrlMonthCal_GetColor|GUICtrlMonthCal_GetColorArray|GUICtrlMonthCal_GetCurSel|GUICtrlMonthCal_GetCurSelStr|GUICtrlMonthCal_GetFirstDOW|GUICtrlMonthCal_GetFirstDOWStr|GUICtrlMonthCal_GetMaxSelCount|GUICtrlMonthCal_GetMaxTodayWidth|GUICtrlMonthCal_GetMinReqHeight|GUICtrlMonthCal_GetMinReqRect|GUICtrlMonthCal_GetMinReqRectArray|GUICtrlMonthCal_GetMinReqWidth|GUICtrlMonthCal_GetMonthDelta|GUICtrlMonthCal_GetMonthRange|GUICtrlMonthCal_GetMonthRangeMax|GUICtrlMonthCal_GetMonthRangeMaxStr|GUICtrlMonthCal_GetMonthRangeMin|GUICtrlMonthCal_GetMonthRangeMinStr|GUICtrlMonthCal_GetMonthRangeSpan|GUICtrlMonthCal_GetRange|GUICtrlMonthCal_GetRangeMax|GUICtrlMonthCal_GetRangeMaxStr|GUICtrlMonthCal_GetRangeMin|GUICtrlMonthCal_GetRangeMinStr|GUICtrlMonthCal_GetSelRange|GUICtrlMonthCal_GetSelRangeMax|GUICtrlMonthCal_GetSelRangeMaxStr|GUICtrlMonthCal_GetSelRangeMin|GUICtrlMonthCal_GetSelRangeMinStr|GUICtrlMonthCal_GetToday|GUICtrlMonthCal_GetTodayStr|GUICtrlMonthCal_GetUnicodeFormat|GUICtrlMonthCal_HitTest|GUICtrlMonthCal_SetColor|GUICtrlMonthCal_SetCurSel|GUICtrlMonthCal_SetDayState|GUICtrlMonthCal_SetFirstDOW|GUICtrlMonthCal_SetMaxSelCount|GUICtrlMonthCal_SetMonthDelta|GUICtrlMonthCal_SetRange|GUICtrlMonthCal_SetSelRange|GUICtrlMonthCal_SetToday|GUICtrlMonthCal_SetUnicodeFormat|GUICtrlRebar_AddBand|GUICtrlRebar_AddToolBarBand|GUICtrlRebar_BeginDrag|GUICtrlRebar_Create|GUICtrlRebar_DeleteBand|GUICtrlRebar_Destroy|GUICtrlRebar_DragMove|GUICtrlRebar_EndDrag|GUICtrlRebar_GetBandBackColor|GUICtrlRebar_GetBandBorders|GUICtrlRebar_GetBandBordersEx|GUICtrlRebar_GetBandChildHandle|GUICtrlRebar_GetBandChildSize|GUICtrlRebar_GetBandCount|GUICtrlRebar_GetBandForeColor|GUICtrlRebar_GetBandHeaderSize|GUICtrlRebar_GetBandID|GUICtrlRebar_GetBandIdealSize|GUICtrlRebar_GetBandLength|GUICtrlRebar_GetBandLParam|GUICtrlRebar_GetBandMargins|GUICtrlRebar_GetBandMarginsEx|GUICtrlRebar_GetBandRect|GUICtrlRebar_GetBandRectEx|GUICtrlRebar_GetBandStyle|GUICtrlRebar_GetBandStyleBreak|GUICtrlRebar_GetBandStyleChildEdge|GUICtrlRebar_GetBandStyleFixedBMP|GUICtrlRebar_GetBandStyleFixedSize|GUICtrlRebar_GetBandStyleGripperAlways|GUICtrlRebar_GetBandStyleHidden|GUICtrlRebar_GetBandStyleHideTitle|GUICtrlRebar_GetBandStyleNoGripper|GUICtrlRebar_GetBandStyleTopAlign|GUICtrlRebar_GetBandStyleUseChevron|GUICtrlRebar_GetBandStyleVariableHeight|GUICtrlRebar_GetBandText|GUICtrlRebar_GetBarHeight|GUICtrlRebar_GetBKColor|GUICtrlRebar_GetColorScheme|GUICtrlRebar_GetRowCount|GUICtrlRebar_GetRowHeight|GUICtrlRebar_GetTextColor|GUICtrlRebar_GetToolTips|GUICtrlRebar_GetUnicodeFormat|GUICtrlRebar_HitTest|GUICtrlRebar_IDToIndex|GUICtrlRebar_MaximizeBand|GUICtrlRebar_MinimizeBand|GUICtrlRebar_MoveBand|GUICtrlRebar_SetBandBackColor|GUICtrlRebar_SetBandForeColor|GUICtrlRebar_SetBandHeaderSize|GUICtrlRebar_SetBandID|GUICtrlRebar_SetBandIdealSize|GUICtrlRebar_SetBandLength|GUICtrlRebar_SetBandLParam|GUICtrlRebar_SetBandStyle|GUICtrlRebar_SetBandStyleBreak|GUICtrlRebar_SetBandStyleChildEdge|GUICtrlRebar_SetBandStyleFixedBMP|GUICtrlRebar_SetBandStyleFixedSize|GUICtrlRebar_SetBandStyleGripperAlways|GUICtrlRebar_SetBandStyleHidden|GUICtrlRebar_SetBandStyleHideTitle|GUICtrlRebar_SetBandStyleNoGripper|GUICtrlRebar_SetBandStyleTopAlign|GUICtrlRebar_SetBandStyleUseChevron|GUICtrlRebar_SetBandStyleVariableHeight|GUICtrlRebar_SetBandText|GUICtrlRebar_SetBKColor|GUICtrlRebar_SetColorScheme|GUICtrlRebar_SetTextColor|GUICtrlRebar_SetToolTips|GUICtrlRebar_SetUnicodeFormat|GUICtrlRebar_ShowBand|GUICtrlSlider_ClearSel|GUICtrlSlider_ClearTics|GUICtrlSlider_Create|GUICtrlSlider_Destroy|GUICtrlSlider_GetBuddy|GUICtrlSlider_GetChannelRect|GUICtrlSlider_GetLineSize|GUICtrlSlider_GetNumTics|GUICtrlSlider_GetPageSize|GUICtrlSlider_GetPos|GUICtrlSlider_GetPTics|GUICtrlSlider_GetRange|GUICtrlSlider_GetRangeMax|GUICtrlSlider_GetRangeMin|GUICtrlSlider_GetSel|GUICtrlSlider_GetSelEnd|GUICtrlSlider_GetSelStart|GUICtrlSlider_GetThumbLength|GUICtrlSlider_GetThumbRect|GUICtrlSlider_GetThumbRectEx|GUICtrlSlider_GetTic|GUICtrlSlider_GetTicPos|GUICtrlSlider_GetToolTips|GUICtrlSlider_GetUnicodeFormat|GUICtrlSlider_SetBuddy|GUICtrlSlider_SetLineSize|GUICtrlSlider_SetPageSize|GUICtrlSlider_SetPos|GUICtrlSlider_SetRange|GUICtrlSlider_SetRangeMax|GUICtrlSlider_SetRangeMin|GUICtrlSlider_SetSel|GUICtrlSlider_SetSelEnd|GUICtrlSlider_SetSelStart|GUICtrlSlider_SetThumbLength|GUICtrlSlider_SetTic|GUICtrlSlider_SetTicFreq|GUICtrlSlider_SetTipSide|GUICtrlSlider_SetToolTips|GUICtrlSlider_SetUnicodeFormat|GUICtrlStatusBar_Create|GUICtrlStatusBar_Destroy|GUICtrlStatusBar_EmbedControl|GUICtrlStatusBar_GetBorders|GUICtrlStatusBar_GetBordersHorz|GUICtrlStatusBar_GetBordersRect|GUICtrlStatusBar_GetBordersVert|GUICtrlStatusBar_GetCount|GUICtrlStatusBar_GetHeight|GUICtrlStatusBar_GetIcon|GUICtrlStatusBar_GetParts|GUICtrlStatusBar_GetRect|GUICtrlStatusBar_GetRectEx|GUICtrlStatusBar_GetText|GUICtrlStatusBar_GetTextFlags|GUICtrlStatusBar_GetTextLength|GUICtrlStatusBar_GetTextLengthEx|GUICtrlStatusBar_GetTipText|GUICtrlStatusBar_GetUnicodeFormat|GUICtrlStatusBar_GetWidth|GUICtrlStatusBar_IsSimple|GUICtrlStatusBar_Resize|GUICtrlStatusBar_SetBkColor|GUICtrlStatusBar_SetIcon|GUICtrlStatusBar_SetMinHeight|GUICtrlStatusBar_SetParts|GUICtrlStatusBar_SetSimple|GUICtrlStatusBar_SetText|GUICtrlStatusBar_SetTipText|GUICtrlStatusBar_SetUnicodeFormat|GUICtrlStatusBar_ShowHide|GUICtrlTab_Create|GUICtrlTab_DeleteAllItems|GUICtrlTab_DeleteItem|GUICtrlTab_DeselectAll|GUICtrlTab_Destroy|GUICtrlTab_FindTab|GUICtrlTab_GetCurFocus|GUICtrlTab_GetCurSel|GUICtrlTab_GetDisplayRect|GUICtrlTab_GetDisplayRectEx|GUICtrlTab_GetExtendedStyle|GUICtrlTab_GetImageList|GUICtrlTab_GetItem|GUICtrlTab_GetItemCount|GUICtrlTab_GetItemImage|GUICtrlTab_GetItemParam|GUICtrlTab_GetItemRect|GUICtrlTab_GetItemRectEx|GUICtrlTab_GetItemState|GUICtrlTab_GetItemText|GUICtrlTab_GetRowCount|GUICtrlTab_GetToolTips|GUICtrlTab_GetUnicodeFormat|GUICtrlTab_HighlightItem|GUICtrlTab_HitTest|GUICtrlTab_InsertItem|GUICtrlTab_RemoveImage|GUICtrlTab_SetCurFocus|GUICtrlTab_SetCurSel|GUICtrlTab_SetExtendedStyle|GUICtrlTab_SetImageList|GUICtrlTab_SetItem|GUICtrlTab_SetItemImage|GUICtrlTab_SetItemParam|GUICtrlTab_SetItemSize|GUICtrlTab_SetItemState|GUICtrlTab_SetItemText|GUICtrlTab_SetMinTabWidth|GUICtrlTab_SetPadding|GUICtrlTab_SetToolTips|GUICtrlTab_SetUnicodeFormat|GUICtrlToolbar_AddBitmap|GUICtrlToolbar_AddButton|GUICtrlToolbar_AddButtonSep|GUICtrlToolbar_AddString|GUICtrlToolbar_ButtonCount|GUICtrlToolbar_CheckButton|GUICtrlToolbar_ClickAccel|GUICtrlToolbar_ClickButton|GUICtrlToolbar_ClickIndex|GUICtrlToolbar_CommandToIndex|GUICtrlToolbar_Create|GUICtrlToolbar_Customize|GUICtrlToolbar_DeleteButton|GUICtrlToolbar_Destroy|GUICtrlToolbar_EnableButton|GUICtrlToolbar_FindToolbar|GUICtrlToolbar_GetAnchorHighlight|GUICtrlToolbar_GetBitmapFlags|GUICtrlToolbar_GetButtonBitmap|GUICtrlToolbar_GetButtonInfo|GUICtrlToolbar_GetButtonInfoEx|GUICtrlToolbar_GetButtonParam|GUICtrlToolbar_GetButtonRect|GUICtrlToolbar_GetButtonRectEx|GUICtrlToolbar_GetButtonSize|GUICtrlToolbar_GetButtonState|GUICtrlToolbar_GetButtonStyle|GUICtrlToolbar_GetButtonText|GUICtrlToolbar_GetColorScheme|GUICtrlToolbar_GetDisabledImageList|GUICtrlToolbar_GetExtendedStyle|GUICtrlToolbar_GetHotImageList|GUICtrlToolbar_GetHotItem|GUICtrlToolbar_GetImageList|GUICtrlToolbar_GetInsertMark|GUICtrlToolbar_GetInsertMarkColor|GUICtrlToolbar_GetMaxSize|GUICtrlToolbar_GetMetrics|GUICtrlToolbar_GetPadding|GUICtrlToolbar_GetRows|GUICtrlToolbar_GetString|GUICtrlToolbar_GetStyle|GUICtrlToolbar_GetStyleAltDrag|GUICtrlToolbar_GetStyleCustomErase|GUICtrlToolbar_GetStyleFlat|GUICtrlToolbar_GetStyleList|GUICtrlToolbar_GetStyleRegisterDrop|GUICtrlToolbar_GetStyleToolTips|GUICtrlToolbar_GetStyleTransparent|GUICtrlToolbar_GetStyleWrapable|GUICtrlToolbar_GetTextRows|GUICtrlToolbar_GetToolTips|GUICtrlToolbar_GetUnicodeFormat|GUICtrlToolbar_HideButton|GUICtrlToolbar_HighlightButton|GUICtrlToolbar_HitTest|GUICtrlToolbar_IndexToCommand|GUICtrlToolbar_InsertButton|GUICtrlToolbar_InsertMarkHitTest|GUICtrlToolbar_IsButtonChecked|GUICtrlToolbar_IsButtonEnabled|GUICtrlToolbar_IsButtonHidden|GUICtrlToolbar_IsButtonHighlighted|GUICtrlToolbar_IsButtonIndeterminate|GUICtrlToolbar_IsButtonPressed|GUICtrlToolbar_LoadBitmap|GUICtrlToolbar_LoadImages|GUICtrlToolbar_MapAccelerator|GUICtrlToolbar_MoveButton|GUICtrlToolbar_PressButton|GUICtrlToolbar_SetAnchorHighlight|GUICtrlToolbar_SetBitmapSize|GUICtrlToolbar_SetButtonBitMap|GUICtrlToolbar_SetButtonInfo|GUICtrlToolbar_SetButtonInfoEx|GUICtrlToolbar_SetButtonParam|GUICtrlToolbar_SetButtonSize|GUICtrlToolbar_SetButtonState|GUICtrlToolbar_SetButtonStyle|GUICtrlToolbar_SetButtonText|GUICtrlToolbar_SetButtonWidth|GUICtrlToolbar_SetCmdID|GUICtrlToolbar_SetColorScheme|GUICtrlToolbar_SetDisabledImageList|GUICtrlToolbar_SetDrawTextFlags|GUICtrlToolbar_SetExtendedStyle|GUICtrlToolbar_SetHotImageList|GUICtrlToolbar_SetHotItem|GUICtrlToolbar_SetImageList|GUICtrlToolbar_SetIndent|GUICtrlToolbar_SetIndeterminate|GUICtrlToolbar_SetInsertMark|GUICtrlToolbar_SetInsertMarkColor|GUICtrlToolbar_SetMaxTextRows|GUICtrlToolbar_SetMetrics|GUICtrlToolbar_SetPadding|GUICtrlToolbar_SetParent|GUICtrlToolbar_SetRows|GUICtrlToolbar_SetStyle|GUICtrlToolbar_SetStyleAltDrag|GUICtrlToolbar_SetStyleCustomErase|GUICtrlToolbar_SetStyleFlat|GUICtrlToolbar_SetStyleList|GUICtrlToolbar_SetStyleRegisterDrop|GUICtrlToolbar_SetStyleToolTips|GUICtrlToolbar_SetStyleTransparent|GUICtrlToolbar_SetStyleWrapable|GUICtrlToolbar_SetToolTips|GUICtrlToolbar_SetUnicodeFormat|GUICtrlToolbar_SetWindowTheme|GUICtrlTreeView_Add|GUICtrlTreeView_AddChild|GUICtrlTreeView_AddChildFirst|GUICtrlTreeView_AddFirst|GUICtrlTreeView_BeginUpdate|GUICtrlTreeView_ClickItem|GUICtrlTreeView_Create|GUICtrlTreeView_CreateDragImage|GUICtrlTreeView_CreateSolidBitMap|GUICtrlTreeView_Delete|GUICtrlTreeView_DeleteAll|GUICtrlTreeView_DeleteChildren|GUICtrlTreeView_Destroy|GUICtrlTreeView_DisplayRect|GUICtrlTreeView_DisplayRectEx|GUICtrlTreeView_EditText|GUICtrlTreeView_EndEdit|GUICtrlTreeView_EndUpdate|GUICtrlTreeView_EnsureVisible|GUICtrlTreeView_Expand|GUICtrlTreeView_ExpandedOnce|GUICtrlTreeView_FindItem|GUICtrlTreeView_FindItemEx|GUICtrlTreeView_GetBkColor|GUICtrlTreeView_GetBold|GUICtrlTreeView_GetChecked|GUICtrlTreeView_GetChildCount|GUICtrlTreeView_GetChildren|GUICtrlTreeView_GetCount|GUICtrlTreeView_GetCut|GUICtrlTreeView_GetDropTarget|GUICtrlTreeView_GetEditControl|GUICtrlTreeView_GetExpanded|GUICtrlTreeView_GetFirstChild|GUICtrlTreeView_GetFirstItem|GUICtrlTreeView_GetFirstVisible|GUICtrlTreeView_GetFocused|GUICtrlTreeView_GetHeight|GUICtrlTreeView_GetImageIndex|GUICtrlTreeView_GetImageListIconHandle|GUICtrlTreeView_GetIndent|GUICtrlTreeView_GetInsertMarkColor|GUICtrlTreeView_GetISearchString|GUICtrlTreeView_GetItemByIndex|GUICtrlTreeView_GetItemHandle|GUICtrlTreeView_GetItemParam|GUICtrlTreeView_GetLastChild|GUICtrlTreeView_GetLineColor|GUICtrlTreeView_GetNext|GUICtrlTreeView_GetNextChild|GUICtrlTreeView_GetNextSibling|GUICtrlTreeView_GetNextVisible|GUICtrlTreeView_GetNormalImageList|GUICtrlTreeView_GetParentHandle|GUICtrlTreeView_GetParentParam|GUICtrlTreeView_GetPrev|GUICtrlTreeView_GetPrevChild|GUICtrlTreeView_GetPrevSibling|GUICtrlTreeView_GetPrevVisible|GUICtrlTreeView_GetScrollTime|GUICtrlTreeView_GetSelected|GUICtrlTreeView_GetSelectedImageIndex|GUICtrlTreeView_GetSelection|GUICtrlTreeView_GetSiblingCount|GUICtrlTreeView_GetState|GUICtrlTreeView_GetStateImageIndex|GUICtrlTreeView_GetStateImageList|GUICtrlTreeView_GetText|GUICtrlTreeView_GetTextColor|GUICtrlTreeView_GetToolTips|GUICtrlTreeView_GetTree|GUICtrlTreeView_GetUnicodeFormat|GUICtrlTreeView_GetVisible|GUICtrlTreeView_GetVisibleCount|GUICtrlTreeView_HitTest|GUICtrlTreeView_HitTestEx|GUICtrlTreeView_HitTestItem|GUICtrlTreeView_Index|GUICtrlTreeView_InsertItem|GUICtrlTreeView_IsFirstItem|GUICtrlTreeView_IsParent|GUICtrlTreeView_Level|GUICtrlTreeView_SelectItem|GUICtrlTreeView_SelectItemByIndex|GUICtrlTreeView_SetBkColor|GUICtrlTreeView_SetBold|GUICtrlTreeView_SetChecked|GUICtrlTreeView_SetCheckedByIndex|GUICtrlTreeView_SetChildren|GUICtrlTreeView_SetCut|GUICtrlTreeView_SetDropTarget|GUICtrlTreeView_SetFocused|GUICtrlTreeView_SetHeight|GUICtrlTreeView_SetIcon|GUICtrlTreeView_SetImageIndex|GUICtrlTreeView_SetIndent|GUICtrlTreeView_SetInsertMark|GUICtrlTreeView_SetInsertMarkColor|GUICtrlTreeView_SetItemHeight|GUICtrlTreeView_SetItemParam|GUICtrlTreeView_SetLineColor|GUICtrlTreeView_SetNormalImageList|GUICtrlTreeView_SetScrollTime|GUICtrlTreeView_SetSelected|GUICtrlTreeView_SetSelectedImageIndex|GUICtrlTreeView_SetState|GUICtrlTreeView_SetStateImageIndex|GUICtrlTreeView_SetStateImageList|GUICtrlTreeView_SetText|GUICtrlTreeView_SetTextColor|GUICtrlTreeView_SetToolTips|GUICtrlTreeView_SetUnicodeFormat|GUICtrlTreeView_Sort|GUIImageList_Add|GUIImageList_AddBitmap|GUIImageList_AddIcon|GUIImageList_AddMasked|GUIImageList_BeginDrag|GUIImageList_Copy|GUIImageList_Create|GUIImageList_Destroy|GUIImageList_DestroyIcon|GUIImageList_DragEnter|GUIImageList_DragLeave|GUIImageList_DragMove|GUIImageList_Draw|GUIImageList_DrawEx|GUIImageList_Duplicate|GUIImageList_EndDrag|GUIImageList_GetBkColor|GUIImageList_GetIcon|GUIImageList_GetIconHeight|GUIImageList_GetIconSize|GUIImageList_GetIconSizeEx|GUIImageList_GetIconWidth|GUIImageList_GetImageCount|GUIImageList_GetImageInfoEx|GUIImageList_Remove|GUIImageList_ReplaceIcon|GUIImageList_SetBkColor|GUIImageList_SetIconSize|GUIImageList_SetImageCount|GUIImageList_Swap|GUIScrollBars_EnableScrollBar|GUIScrollBars_GetScrollBarInfoEx|GUIScrollBars_GetScrollBarRect|GUIScrollBars_GetScrollBarRGState|GUIScrollBars_GetScrollBarXYLineButton|GUIScrollBars_GetScrollBarXYThumbBottom|GUIScrollBars_GetScrollBarXYThumbTop|GUIScrollBars_GetScrollInfo|GUIScrollBars_GetScrollInfoEx|GUIScrollBars_GetScrollInfoMax|GUIScrollBars_GetScrollInfoMin|GUIScrollBars_GetScrollInfoPage|GUIScrollBars_GetScrollInfoPos|GUIScrollBars_GetScrollInfoTrackPos|GUIScrollBars_GetScrollPos|GUIScrollBars_GetScrollRange|GUIScrollBars_Init|GUIScrollBars_ScrollWindow|GUIScrollBars_SetScrollInfo|GUIScrollBars_SetScrollInfoMax|GUIScrollBars_SetScrollInfoMin|GUIScrollBars_SetScrollInfoPage|GUIScrollBars_SetScrollInfoPos|GUIScrollBars_SetScrollRange|GUIScrollBars_ShowScrollBar|GUIToolTip_Activate|GUIToolTip_AddTool|GUIToolTip_AdjustRect|GUIToolTip_BitsToTTF|GUIToolTip_Create|GUIToolTip_DelTool|GUIToolTip_Destroy|GUIToolTip_EnumTools|GUIToolTip_GetBubbleHeight|GUIToolTip_GetBubbleSize|GUIToolTip_GetBubbleWidth|GUIToolTip_GetCurrentTool|GUIToolTip_GetDelayTime|GUIToolTip_GetMargin|GUIToolTip_GetMarginEx|GUIToolTip_GetMaxTipWidth|GUIToolTip_GetText|GUIToolTip_GetTipBkColor|GUIToolTip_GetTipTextColor|GUIToolTip_GetTitleBitMap|GUIToolTip_GetTitleText|GUIToolTip_GetToolCount|GUIToolTip_GetToolInfo|GUIToolTip_HitTest|GUIToolTip_NewToolRect|GUIToolTip_Pop|GUIToolTip_PopUp|GUIToolTip_SetDelayTime|GUIToolTip_SetMargin|GUIToolTip_SetMaxTipWidth|GUIToolTip_SetTipBkColor|GUIToolTip_SetTipTextColor|GUIToolTip_SetTitle|GUIToolTip_SetToolInfo|GUIToolTip_SetWindowTheme|GUIToolTip_ToolExists|GUIToolTip_ToolToArray|GUIToolTip_TrackActivate|GUIToolTip_TrackPosition|GUIToolTip_TTFToBits|GUIToolTip_Update|GUIToolTip_UpdateTipText|HexToString|IE_Example|IE_Introduction|IE_VersionInfo|IEAction|IEAttach|IEBodyReadHTML|IEBodyReadText|IEBodyWriteHTML|IECreate|IECreateEmbedded|IEDocGetObj|IEDocInsertHTML|IEDocInsertText|IEDocReadHTML|IEDocWriteHTML|IEErrorHandlerDeRegister|IEErrorHandlerRegister|IEErrorNotify|IEFormElementCheckBoxSelect|IEFormElementGetCollection|IEFormElementGetObjByName|IEFormElementGetValue|IEFormElementOptionSelect|IEFormElementRadioSelect|IEFormElementSetValue|IEFormGetCollection|IEFormGetObjByName|IEFormImageClick|IEFormReset|IEFormSubmit|IEFrameGetCollection|IEFrameGetObjByName|IEGetObjById|IEGetObjByName|IEHeadInsertEventScript|IEImgClick|IEImgGetCollection|IEIsFrameSet|IELinkClickByIndex|IELinkClickByText|IELinkGetCollection|IELoadWait|IELoadWaitTimeout|IENavigate|IEPropertyGet|IEPropertySet|IEQuit|IETableGetCollection|IETableWriteToArray|IETagNameAllGetCollection|IETagNameGetCollection|Iif|INetExplorerCapable|INetGetSource|INetMail|INetSmtpMail|IsPressed|MathCheckDiv|Max|MemGlobalAlloc|MemGlobalFree|MemGlobalLock|MemGlobalSize|MemGlobalUnlock|MemMoveMemory|MemMsgBox|MemShowError|MemVirtualAlloc|MemVirtualAllocEx|MemVirtualFree|MemVirtualFreeEx|Min|MouseTrap|NamedPipes_CallNamedPipe|NamedPipes_ConnectNamedPipe|NamedPipes_CreateNamedPipe|NamedPipes_CreatePipe|NamedPipes_DisconnectNamedPipe|NamedPipes_GetNamedPipeHandleState|NamedPipes_GetNamedPipeInfo|NamedPipes_PeekNamedPipe|NamedPipes_SetNamedPipeHandleState|NamedPipes_TransactNamedPipe|NamedPipes_WaitNamedPipe|Net_Share_ConnectionEnum|Net_Share_FileClose|Net_Share_FileEnum|Net_Share_FileGetInfo|Net_Share_PermStr|Net_Share_ResourceStr|Net_Share_SessionDel|Net_Share_SessionEnum|Net_Share_SessionGetInfo|Net_Share_ShareAdd|Net_Share_ShareCheck|Net_Share_ShareDel|Net_Share_ShareEnum|Net_Share_ShareGetInfo|Net_Share_ShareSetInfo|Net_Share_StatisticsGetSvr|Net_Share_StatisticsGetWrk|Now|NowCalc|NowCalcDate|NowDate|NowTime|PathFull|PathMake|PathSplit|ProcessGetName|ProcessGetPriority|Radian|ReplaceStringInFile|RunDOS|ScreenCapture_Capture|ScreenCapture_CaptureWnd|ScreenCapture_SaveImage|ScreenCapture_SetBMPFormat|ScreenCapture_SetJPGQuality|ScreenCapture_SetTIFColorDepth|ScreenCapture_SetTIFCompression|Security__AdjustTokenPrivileges|Security__GetAccountSid|Security__GetLengthSid|Security__GetTokenInformation|Security__ImpersonateSelf|Security__IsValidSid|Security__LookupAccountName|Security__LookupAccountSid|Security__LookupPrivilegeValue|Security__OpenProcessToken|Security__OpenThreadToken|Security__OpenThreadTokenEx|Security__SetPrivilege|Security__SidToStringSid|Security__SidTypeStr|Security__StringSidToSid|SendMessage|SendMessageA|SetDate|SetTime|Singleton|SoundClose|SoundLength|SoundOpen|SoundPause|SoundPlay|SoundPos|SoundResume|SoundSeek|SoundStatus|SoundStop|SQLite_Changes|SQLite_Close|SQLite_Display2DResult|SQLite_Encode|SQLite_ErrCode|SQLite_ErrMsg|SQLite_Escape|SQLite_Exec|SQLite_FetchData|SQLite_FetchNames|SQLite_GetTable|SQLite_GetTable2d|SQLite_LastInsertRowID|SQLite_LibVersion|SQLite_Open|SQLite_Query|SQLite_QueryFinalize|SQLite_QueryReset|SQLite_QuerySingleRow|SQLite_SaveMode|SQLite_SetTimeout|SQLite_Shutdown|SQLite_SQLiteExe|SQLite_Startup|SQLite_TotalChanges|StringAddComma|StringBetween|StringEncrypt|StringInsert|StringProper|StringRepeat|StringReverse|StringSplit|StringToHex|TCPIpToName|TempFile|TicksToTime|Timer_Diff|Timer_GetTimerID|Timer_Init|Timer_KillAllTimers|Timer_KillTimer|Timer_SetTimer|TimeToTicks|VersionCompare|viClose|viExecCommand|viFindGpib|viGpibBusReset|viGTL|viOpen|viSetAttribute|viSetTimeout|WeekNumberISO|WinAPI_AttachConsole|WinAPI_AttachThreadInput|WinAPI_Beep|WinAPI_BitBlt|WinAPI_CallNextHookEx|WinAPI_Check|WinAPI_ClientToScreen|WinAPI_CloseHandle|WinAPI_CommDlgExtendedError|WinAPI_CopyIcon|WinAPI_CreateBitmap|WinAPI_CreateCompatibleBitmap|WinAPI_CreateCompatibleDC|WinAPI_CreateEvent|WinAPI_CreateFile|WinAPI_CreateFont|WinAPI_CreateFontIndirect|WinAPI_CreateProcess|WinAPI_CreateSolidBitmap|WinAPI_CreateSolidBrush|WinAPI_CreateWindowEx|WinAPI_DefWindowProc|WinAPI_DeleteDC|WinAPI_DeleteObject|WinAPI_DestroyIcon|WinAPI_DestroyWindow|WinAPI_DrawEdge|WinAPI_DrawFrameControl|WinAPI_DrawIcon|WinAPI_DrawIconEx|WinAPI_DrawText|WinAPI_EnableWindow|WinAPI_EnumDisplayDevices|WinAPI_EnumWindows|WinAPI_EnumWindowsPopup|WinAPI_EnumWindowsTop|WinAPI_ExpandEnvironmentStrings|WinAPI_ExtractIconEx|WinAPI_FatalAppExit|WinAPI_FillRect|WinAPI_FindExecutable|WinAPI_FindWindow|WinAPI_FlashWindow|WinAPI_FlashWindowEx|WinAPI_FloatToInt|WinAPI_FlushFileBuffers|WinAPI_FormatMessage|WinAPI_FrameRect|WinAPI_FreeLibrary|WinAPI_GetAncestor|WinAPI_GetAsyncKeyState|WinAPI_GetClassName|WinAPI_GetClientHeight|WinAPI_GetClientRect|WinAPI_GetClientWidth|WinAPI_GetCurrentProcess|WinAPI_GetCurrentProcessID|WinAPI_GetCurrentThread|WinAPI_GetCurrentThreadId|WinAPI_GetCursorInfo|WinAPI_GetDC|WinAPI_GetDesktopWindow|WinAPI_GetDeviceCaps|WinAPI_GetDIBits|WinAPI_GetDlgCtrlID|WinAPI_GetDlgItem|WinAPI_GetFileSizeEx|WinAPI_GetFocus|WinAPI_GetForegroundWindow|WinAPI_GetIconInfo|WinAPI_GetLastError|WinAPI_GetLastErrorMessage|WinAPI_GetModuleHandle|WinAPI_GetMousePos|WinAPI_GetMousePosX|WinAPI_GetMousePosY|WinAPI_GetObject|WinAPI_GetOpenFileName|WinAPI_GetOverlappedResult|WinAPI_GetParent|WinAPI_GetProcessAffinityMask|WinAPI_GetSaveFileName|WinAPI_GetStdHandle|WinAPI_GetStockObject|WinAPI_GetSysColor|WinAPI_GetSysColorBrush|WinAPI_GetSystemMetrics|WinAPI_GetTextExtentPoint32|WinAPI_GetWindow|WinAPI_GetWindowDC|WinAPI_GetWindowHeight|WinAPI_GetWindowLong|WinAPI_GetWindowRect|WinAPI_GetWindowText|WinAPI_GetWindowThreadProcessId|WinAPI_GetWindowWidth|WinAPI_GetXYFromPoint|WinAPI_GlobalMemStatus|WinAPI_GUIDFromString|WinAPI_GUIDFromStringEx|WinAPI_HiWord|WinAPI_InProcess|WinAPI_IntToFloat|WinAPI_InvalidateRect|WinAPI_IsClassName|WinAPI_IsWindow|WinAPI_IsWindowVisible|WinAPI_LoadBitmap|WinAPI_LoadImage|WinAPI_LoadLibrary|WinAPI_LoadLibraryEx|WinAPI_LoadShell32Icon|WinAPI_LoadString|WinAPI_LocalFree|WinAPI_LoWord|WinAPI_MakeDWord|WinAPI_MAKELANGID|WinAPI_MAKELCID|WinAPI_MakeLong|WinAPI_MessageBeep|WinAPI_Mouse_Event|WinAPI_MoveWindow|WinAPI_MsgBox|WinAPI_MulDiv|WinAPI_MultiByteToWideChar|WinAPI_MultiByteToWideCharEx|WinAPI_OpenProcess|WinAPI_PointFromRect|WinAPI_PostMessage|WinAPI_PrimaryLangId|WinAPI_PtInRect|WinAPI_ReadFile|WinAPI_ReadProcessMemory|WinAPI_RectIsEmpty|WinAPI_RedrawWindow|WinAPI_RegisterWindowMessage|WinAPI_ReleaseCapture|WinAPI_ReleaseDC|WinAPI_ScreenToClient|WinAPI_SelectObject|WinAPI_SetBkColor|WinAPI_SetCapture|WinAPI_SetCursor|WinAPI_SetDefaultPrinter|WinAPI_SetDIBits|WinAPI_SetEvent|WinAPI_SetFocus|WinAPI_SetFont|WinAPI_SetHandleInformation|WinAPI_SetLastError|WinAPI_SetParent|WinAPI_SetProcessAffinityMask|WinAPI_SetSysColors|WinAPI_SetTextColor|WinAPI_SetWindowLong|WinAPI_SetWindowPos|WinAPI_SetWindowsHookEx|WinAPI_SetWindowText|WinAPI_ShowCursor|WinAPI_ShowError|WinAPI_ShowMsg|WinAPI_ShowWindow|WinAPI_StringFromGUID|WinAPI_SubLangId|WinAPI_SystemParametersInfo|WinAPI_TwipsPerPixelX|WinAPI_TwipsPerPixelY|WinAPI_UnhookWindowsHookEx|WinAPI_UpdateLayeredWindow|WinAPI_UpdateWindow|WinAPI_ValidateClassName|WinAPI_WaitForInputIdle|WinAPI_WaitForMultipleObjects|WinAPI_WaitForSingleObject|WinAPI_WideCharToMultiByte|WinAPI_WindowFromPoint|WinAPI_WriteConsole|WinAPI_WriteFile|WinAPI_WriteProcessMemory|WinNet_AddConnection|WinNet_AddConnection2|WinNet_AddConnection3|WinNet_CancelConnection|WinNet_CancelConnection2|WinNet_CloseEnum|WinNet_ConnectionDialog|WinNet_ConnectionDialog1|WinNet_DisconnectDialog|WinNet_DisconnectDialog1|WinNet_EnumResource|WinNet_GetConnection|WinNet_GetConnectionPerformance|WinNet_GetLastError|WinNet_GetNetworkInformation|WinNet_GetProviderName|WinNet_GetResourceInformation|WinNet_GetResourceParent|WinNet_GetUniversalName|WinNet_GetUser|WinNet_OpenEnum|WinNet_RestoreConnection|WinNet_UseConnection|Word_VersionInfo|WordAttach|WordCreate|WordDocAdd|WordDocAddLink|WordDocAddPicture|WordDocClose|WordDocFindReplace|WordDocGetCollection|WordDocLinkGetCollection|WordDocOpen|WordDocPrint|WordDocPropertyGet|WordDocPropertySet|WordDocSave|WordDocSaveAs|WordErrorHandlerDeRegister|WordErrorHandlerRegister|WordErrorNotify|WordMacroRun|WordPropertyGet|WordPropertySet|WordQuit|ce|comments-end|comments-start|cs|include|include-once|NoTrayIcon|RequireAdmin|AutoIt3Wrapper_Au3Check_Parameters|AutoIt3Wrapper_Au3Check_Stop_OnWarning|AutoIt3Wrapper_Change2CUI|AutoIt3Wrapper_Compression|AutoIt3Wrapper_cvsWrapper_Parameters|AutoIt3Wrapper_Icon|AutoIt3Wrapper_Outfile|AutoIt3Wrapper_Outfile_Type|AutoIt3Wrapper_Plugin_Funcs|AutoIt3Wrapper_Res_Comment|AutoIt3Wrapper_Res_Description|AutoIt3Wrapper_Res_Field|AutoIt3Wrapper_Res_File_Add|AutoIt3Wrapper_Res_Fileversion|AutoIt3Wrapper_Res_FileVersion_AutoIncrement|AutoIt3Wrapper_Res_Icon_Add|AutoIt3Wrapper_Res_Language|AutoIt3Wrapper_Res_LegalCopyright|AutoIt3Wrapper_res_requestedExecutionLevel|AutoIt3Wrapper_Res_SaveSource|AutoIt3Wrapper_Run_After|AutoIt3Wrapper_Run_Au3check|AutoIt3Wrapper_Run_Before|AutoIt3Wrapper_Run_cvsWrapper|AutoIt3Wrapper_Run_Debug_Mode|AutoIt3Wrapper_Run_Obfuscator|AutoIt3Wrapper_Run_Tidy|AutoIt3Wrapper_Tidy_Stop_OnError|AutoIt3Wrapper_UseAnsi|AutoIt3Wrapper_UseUpx|AutoIt3Wrapper_UseX64|AutoIt3Wrapper_Version|EndRegion|forceref|Obfuscator_Ignore_Funcs|Obfuscator_Ignore_Variables|Obfuscator_Parameters|Region|Tidy_Parameters",t="AppDataCommonDir|AppDataDir|AutoItExe|AutoItPID|AutoItUnicode|AutoItVersion|AutoItX64|COM_EventObj|CommonFilesDir|Compiled|ComputerName|ComSpec|CR|CRLF|DesktopCommonDir|DesktopDepth|DesktopDir|DesktopHeight|DesktopRefresh|DesktopWidth|DocumentsCommonDir|error|exitCode|exitMethod|extended|FavoritesCommonDir|FavoritesDir|GUI_CtrlHandle|GUI_CtrlId|GUI_DragFile|GUI_DragId|GUI_DropId|GUI_WinHandle|HomeDrive|HomePath|HomeShare|HotKeyPressed|HOUR|InetGetActive|InetGetBytesRead|IPAddress1|IPAddress2|IPAddress3|IPAddress4|KBLayout|LF|LogonDNSDomain|LogonDomain|LogonServer|MDAY|MIN|MON|MyDocumentsDir|NumParams|OSBuild|OSLang|OSServicePack|OSTYPE|OSVersion|ProcessorArch|ProgramFilesDir|ProgramsCommonDir|ProgramsDir|ScriptDir|ScriptFullPath|ScriptLineNumber|ScriptName|SEC|StartMenuCommonDir|StartMenuDir|StartupCommonDir|StartupDir|SW_DISABLE|SW_ENABLE|SW_HIDE|SW_LOCK|SW_MAXIMIZE|SW_MINIMIZE|SW_RESTORE|SW_SHOW|SW_SHOWDEFAULT|SW_SHOWMAXIMIZED|SW_SHOWMINIMIZED|SW_SHOWMINNOACTIVE|SW_SHOWNA|SW_SHOWNOACTIVATE|SW_SHOWNORMAL|SW_UNLOCK|SystemDir|TAB|TempDir|TRAY_ID|TrayIconFlashing|TrayIconVisible|UserName|UserProfileDir|WDAY|WindowsDir|WorkingDir|YDAY|YEAR";this.$rules={start:[{token:"comment.line.ahk",regex:"(?:^| );.*$"},{token:"comment.block.ahk",regex:"/\\*",push:[{token:"comment.block.ahk",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.ahk"}]},{token:"doc.comment.ahk",regex:"#cs",push:[{token:"doc.comment.ahk",regex:"#ce",next:"pop"},{defaultToken:"doc.comment.ahk"}]},{token:"keyword.command.ahk",regex:"(?:\\b|^)(?:allowsamelinecomments|clipboardtimeout|commentflag|errorstdout|escapechar|hotkeyinterval|hotkeymodifiertimeout|hotstring|include|includeagain|installkeybdhook|installmousehook|keyhistory|ltrim|maxhotkeysperinterval|maxmem|maxthreads|maxthreadsbuffer|maxthreadsperhotkey|noenv|notrayicon|persistent|singleinstance|usehook|winactivateforce|autotrim|blockinput|click|clipwait|continue|control|controlclick|controlfocus|controlget|controlgetfocus|controlgetpos|controlgettext|controlmove|controlsend|controlsendraw|controlsettext|coordmode|critical|detecthiddentext|detecthiddenwindows|drive|driveget|drivespacefree|edit|endrepeat|envadd|envdiv|envget|envmult|envset|envsub|envupdate|exit|exitapp|fileappend|filecopy|filecopydir|filecreatedir|filecreateshortcut|filedelete|filegetattrib|filegetshortcut|filegetsize|filegettime|filegetversion|fileinstall|filemove|filemovedir|fileread|filereadline|filerecycle|filerecycleempty|fileremovedir|fileselectfile|fileselectfolder|filesetattrib|filesettime|formattime|getkeystate|gosub|goto|groupactivate|groupadd|groupclose|groupdeactivate|gui|guicontrol|guicontrolget|hideautoitwin|hotkey|ifequal|ifexist|ifgreater|ifgreaterorequal|ifinstring|ifless|iflessorequal|ifmsgbox|ifnotequal|ifnotexist|ifnotinstring|ifwinactive|ifwinexist|ifwinnotactive|ifwinnotexist|imagesearch|inidelete|iniread|iniwrite|input|inputbox|keyhistory|keywait|listhotkeys|listlines|listvars|menu|mouseclick|mouseclickdrag|mousegetpos|mousemove|msgbox|onexit|outputdebug|pause|pixelgetcolor|pixelsearch|postmessage|process|progress|random|regdelete|regread|regwrite|reload|repeat|run|runas|runwait|send|sendevent|sendinput|sendmode|sendplay|sendmessage|sendraw|setbatchlines|setcapslockstate|setcontroldelay|setdefaultmousespeed|setenv|setformat|setkeydelay|setmousedelay|setnumlockstate|setscrolllockstate|setstorecapslockmode|settimer|settitlematchmode|setwindelay|setworkingdir|shutdown|sleep|sort|soundbeep|soundget|soundgetwavevolume|soundplay|soundset|soundsetwavevolume|splashimage|splashtextoff|splashtexton|splitpath|statusbargettext|statusbarwait|stringcasesense|stringgetpos|stringleft|stringlen|stringlower|stringmid|stringreplace|stringright|stringsplit|stringtrimleft|stringtrimright|stringupper|suspend|sysget|thread|tooltip|transform|traytip|urldownloadtofile|while|winactivate|winactivatebottom|winclose|winget|wingetactivestats|wingetactivetitle|wingetclass|wingetpos|wingettext|wingettitle|winhide|winkill|winmaximize|winmenuselectitem|winminimize|winminimizeall|winminimizeallundo|winmove|winrestore|winset|winsettitle|winshow|winwait|winwaitactive|winwaitclose|winwaitnotactive)\\b",caseInsensitive:!0},{token:"keyword.control.ahk",regex:"(?:\\b|^)(?:if|else|return|loop|break|for|while|global|local|byref)\\b",caseInsensitive:!0},{token:"support.function.ahk",regex:"(?:\\b|^)(?:abs|acos|asc|asin|atan|ceil|chr|cos|dllcall|exp|fileexist|floor|getkeystate|il_add|il_create|il_destroy|instr|substr|isfunc|islabel|ln|log|lv_add|lv_delete|lv_deletecol|lv_getcount|lv_getnext|lv_gettext|lv_insert|lv_insertcol|lv_modify|lv_modifycol|lv_setimagelist|mod|onmessage|numget|numput|registercallback|regexmatch|regexreplace|round|sin|tan|sqrt|strlen|sb_seticon|sb_setparts|sb_settext|tv_add|tv_delete|tv_getchild|tv_getcount|tv_getnext|tv_get|tv_getparent|tv_getprev|tv_getselection|tv_gettext|tv_modify|varsetcapacity|winactive|winexist)\\b",caseInsensitive:!0},{token:"variable.predefined.ahk",regex:"(?:\\b|^)(?:a_ahkpath|a_ahkversion|a_appdata|a_appdatacommon|a_autotrim|a_batchlines|a_caretx|a_carety|a_computername|a_controldelay|a_cursor|a_dd|a_ddd|a_dddd|a_defaultmousespeed|a_desktop|a_desktopcommon|a_detecthiddentext|a_detecthiddenwindows|a_endchar|a_eventinfo|a_exitreason|a_formatfloat|a_formatinteger|a_gui|a_guievent|a_guicontrol|a_guicontrolevent|a_guiheight|a_guiwidth|a_guix|a_guiy|a_hour|a_iconfile|a_iconhidden|a_iconnumber|a_icontip|a_index|a_ipaddress1|a_ipaddress2|a_ipaddress3|a_ipaddress4|a_isadmin|a_iscompiled|a_iscritical|a_ispaused|a_issuspended|a_keydelay|a_language|a_lasterror|a_linefile|a_linenumber|a_loopfield|a_loopfileattrib|a_loopfiledir|a_loopfileext|a_loopfilefullpath|a_loopfilelongpath|a_loopfilename|a_loopfileshortname|a_loopfileshortpath|a_loopfilesize|a_loopfilesizekb|a_loopfilesizemb|a_loopfiletimeaccessed|a_loopfiletimecreated|a_loopfiletimemodified|a_loopreadline|a_loopregkey|a_loopregname|a_loopregsubkey|a_loopregtimemodified|a_loopregtype|a_mday|a_min|a_mm|a_mmm|a_mmmm|a_mon|a_mousedelay|a_msec|a_mydocuments|a_now|a_nowutc|a_numbatchlines|a_ostype|a_osversion|a_priorhotkey|programfiles|a_programfiles|a_programs|a_programscommon|a_screenheight|a_screenwidth|a_scriptdir|a_scriptfullpath|a_scriptname|a_sec|a_space|a_startmenu|a_startmenucommon|a_startup|a_startupcommon|a_stringcasesense|a_tab|a_temp|a_thisfunc|a_thishotkey|a_thislabel|a_thismenu|a_thismenuitem|a_thismenuitempos|a_tickcount|a_timeidle|a_timeidlephysical|a_timesincepriorhotkey|a_timesincethishotkey|a_titlematchmode|a_titlematchmodespeed|a_username|a_wday|a_windelay|a_windir|a_workingdir|a_yday|a_year|a_yweek|a_yyyy|clipboard|clipboardall|comspec|errorlevel)\\b",caseInsensitive:!0},{token:"support.constant.ahk",regex:"(?:\\b|^)(?:shift|lshift|rshift|alt|lalt|ralt|control|lcontrol|rcontrol|ctrl|lctrl|rctrl|lwin|rwin|appskey|altdown|altup|shiftdown|shiftup|ctrldown|ctrlup|lwindown|lwinup|rwindown|rwinup|lbutton|rbutton|mbutton|wheelup|wheelleft|wheelright|wheeldown|xbutton1|xbutton2|joy1|joy2|joy3|joy4|joy5|joy6|joy7|joy8|joy9|joy10|joy11|joy12|joy13|joy14|joy15|joy16|joy17|joy18|joy19|joy20|joy21|joy22|joy23|joy24|joy25|joy26|joy27|joy28|joy29|joy30|joy31|joy32|joyx|joyy|joyz|joyr|joyu|joyv|joypov|joyname|joybuttons|joyaxes|joyinfo|space|tab|enter|escape|esc|backspace|bs|delete|del|insert|ins|pgup|pgdn|home|end|up|down|left|right|printscreen|ctrlbreak|pause|scrolllock|capslock|numlock|numpad0|numpad1|numpad2|numpad3|numpad4|numpad5|numpad6|numpad7|numpad8|numpad9|numpadmult|numpadadd|numpadsub|numpaddiv|numpaddot|numpaddel|numpadins|numpadclear|numpadup|numpaddown|numpadleft|numpadright|numpadhome|numpadend|numpadpgup|numpadpgdn|numpadenter|f1|f2|f3|f4|f5|f6|f7|f8|f9|f10|f11|f12|f13|f14|f15|f16|f17|f18|f19|f20|f21|f22|f23|f24|browser_back|browser_forward|browser_refresh|browser_stop|browser_search|browser_favorites|browser_home|volume_mute|volume_down|volume_up|media_next|media_prev|media_stop|media_play_pause|launch_mail|launch_media|launch_app1|launch_app2)\\b",caseInsensitive:!0},{token:"variable.parameter",regex:"(?:\\b|^)(?:pixel|mouse|screen|relative|rgb|ltrim|rtrim|join|low|belownormal|normal|abovenormal|high|realtime|ahk_id|ahk_pid|ahk_class|ahk_group|between|contains|in|is|integer|float|integerfast|floatfast|number|digit|xdigit|alpha|upper|lower|alnum|time|date|not|or|and|alwaysontop|topmost|top|bottom|transparent|transcolor|redraw|region|id|idlast|processname|minmax|controllist|count|list|capacity|statuscd|eject|lock|unlock|label|filesystem|label|setlabel|serial|type|status|static|seconds|minutes|hours|days|read|parse|logoff|close|error|single|tray|add|rename|check|uncheck|togglecheck|enable|disable|toggleenable|default|nodefault|standard|nostandard|color|delete|deleteall|icon|noicon|tip|click|show|mainwindow|nomainwindow|useerrorlevel|text|picture|pic|groupbox|button|checkbox|radio|dropdownlist|ddl|combobox|listbox|listview|datetime|monthcal|updown|slider|tab|tab2|statusbar|treeview|iconsmall|tile|report|sortdesc|nosort|nosorthdr|grid|hdr|autosize|range|xm|ym|ys|xs|xp|yp|font|resize|owner|submit|nohide|minimize|maximize|restore|noactivate|na|cancel|destroy|center|margin|maxsize|minsize|owndialogs|guiescape|guiclose|guisize|guicontextmenu|guidropfiles|tabstop|section|altsubmit|wrap|hscroll|vscroll|border|top|bottom|buttons|expand|first|imagelist|lines|wantctrla|wantf2|vis|visfirst|number|uppercase|lowercase|limit|password|multi|wantreturn|group|background|bold|italic|strike|underline|norm|backgroundtrans|theme|caption|delimiter|minimizebox|maximizebox|sysmenu|toolwindow|flash|style|exstyle|check3|checked|checkedgray|readonly|password|hidden|left|right|center|notab|section|move|focus|hide|choose|choosestring|text|pos|enabled|disabled|visible|lastfound|lastfoundexist|alttab|shiftalttab|alttabmenu|alttabandmenu|alttabmenudismiss|notimers|interrupt|priority|waitclose|blind|raw|unicode|deref|pow|bitnot|bitand|bitor|bitxor|bitshiftleft|bitshiftright|yes|no|ok|cancel|abort|retry|ignore|tryagain|on|off|all|hkey_local_machine|hkey_users|hkey_current_user|hkey_classes_root|hkey_current_config|hklm|hku|hkcu|hkcr|hkcc|reg_sz|reg_expand_sz|reg_multi_sz|reg_dword|reg_qword|reg_binary|reg_link|reg_resource_list|reg_full_resource_descriptor|reg_resource_requirements_list|reg_dword_big_endian)\\b",caseInsensitive:!0},{keywordMap:{"constant.language":e},regex:"\\w+\\b"},{keywordMap:{"variable.function":t},regex:"@\\w+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"keyword.operator.ahk",regex:"=|==|<>|:=|<|>|\\*|\\/|\\+|:|\\?|\\-"},{token:"punctuation.ahk",regex:"#|`|::|,|\\{|\\}|\\(|\\)|\\%"},{token:["punctuation.quote.double","string.quoted.ahk","punctuation.quote.double"],regex:'(")((?:[^"]|"")*)(")'},{token:["label.ahk","punctuation.definition.label.ahk"],regex:"^([^: ]+)(:)(?!:)"}]},this.normalizeRules()};s.metaData={name:"AutoHotKey",scopeName:"source.ahk",fileTypes:["ahk"],foldingStartMarker:"^\\s*/\\*|^(?![^{]*?;|[^{]*?/\\*(?!.*?\\*/.*?\\{)).*?\\{\\s*($|;|/\\*(?!.*?\\*/.*\\S))",foldingStopMarker:"^\\s*\\*/|^\\s*\\}"},r.inherits(s,i),t.AutoHotKeyHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/autohotkey",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/autohotkey_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./autohotkey_highlight_rules").AutoHotKeyHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="/\\*",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/autohotkey"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-batchfile.js b/dist/assets/js/vendor/ace-nc/mode-batchfile.js
            new file mode 100644
            index 0000000000..f954ba2767
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-batchfile.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/batchfile_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"keyword.command.dosbatch",regex:"\\b(?:append|assoc|at|attrib|break|cacls|cd|chcp|chdir|chkdsk|chkntfs|cls|cmd|color|comp|compact|convert|copy|date|del|dir|diskcomp|diskcopy|doskey|echo|endlocal|erase|fc|find|findstr|format|ftype|graftabl|help|keyb|label|md|mkdir|mode|more|move|path|pause|popd|print|prompt|pushd|rd|recover|ren|rename|replace|restore|rmdir|set|setlocal|shift|sort|start|subst|time|title|tree|type|ver|verify|vol|xcopy)\\b",caseInsensitive:!0},{token:"keyword.control.statement.dosbatch",regex:"\\b(?:goto|call|exit)\\b",caseInsensitive:!0},{token:"keyword.control.conditional.if.dosbatch",regex:"\\bif\\s+not\\s+(?:exist|defined|errorlevel|cmdextversion)\\b",caseInsensitive:!0},{token:"keyword.control.conditional.dosbatch",regex:"\\b(?:if|else)\\b",caseInsensitive:!0},{token:"keyword.control.repeat.dosbatch",regex:"\\bfor\\b",caseInsensitive:!0},{token:"keyword.operator.dosbatch",regex:"\\b(?:EQU|NEQ|LSS|LEQ|GTR|GEQ)\\b"},{token:["doc.comment","comment"],regex:"(?:^|\\b)(rem)($|\\s.*$)",caseInsensitive:!0},{token:"comment.line.colons.dosbatch",regex:"::.*$"},{include:"variable"},{token:"punctuation.definition.string.begin.shell",regex:'"',push:[{token:"punctuation.definition.string.end.shell",regex:'"',next:"pop"},{include:"variable"},{defaultToken:"string.quoted.double.dosbatch"}]},{token:"keyword.operator.pipe.dosbatch",regex:"[|]"},{token:"keyword.operator.redirect.shell",regex:"&>|\\d*>&\\d*|\\d*(?:>>|>|<)|\\d*<&|\\d*<>"}],variable:[{token:"constant.numeric",regex:"%%\\w+|%[*\\d]|%\\w+%"},{token:"constant.numeric",regex:"%~\\d+"},{token:["markup.list","constant.other","markup.list"],regex:"(%)(\\w+)(%?)"}]},this.normalizeRules()};s.metaData={name:"Batch File",scopeName:"source.dosbatch",fileTypes:["bat"]},r.inherits(s,i),t.BatchFileHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/batchfile",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/batchfile_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./batchfile_highlight_rules").BatchFileHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="::",this.blockComment="",this.$id="ace/mode/batchfile"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-c9search.js b/dist/assets/js/vendor/ace-nc/mode-c9search.js
            new file mode 100644
            index 0000000000..508198cbbd
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-c9search.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/c9search_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function o(e,t){try{return new RegExp(e,t)}catch(n){}}var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,u=function(){this.$rules={start:[{tokenNames:["c9searchresults.constant.numeric","c9searchresults.text","c9searchresults.text","c9searchresults.keyword"],regex:"(^\\s+[0-9]+)(:\\s)(.+)",onMatch:function(e,t,n){var r=this.splitRegex.exec(e),i=this.tokenNames,s=[{type:i[0],value:r[1]},{type:i[1],value:r[2]}],o=n[1],u=r[3],a,f=0;if(o&&o.exec){o.lastIndex=0;while(a=o.exec(u)){var l=u.substring(f,a.index);f=o.lastIndex,l&&s.push({type:i[2],value:l});if(a[0])s.push({type:i[3],value:a[0]});else if(!l)break}}return f<u.length&&s.push({type:i[2],value:u.substr(f)}),s}},{token:["string","text"],regex:"(\\S.*)(:$)"},{regex:"Searching for .*$",onMatch:function(e,t,n){var r=e.split("");if(r.length<3)return"text";var s,u,a,f=0,l=[{value:r[f++]+"'",type:"text"},{value:u=r[f++],type:"text"},{value:"'"+r[f++],type:"text"}];r[2]!==" in"&&(a=r[f],l.push({value:"'"+r[f++]+"'",type:"text"},{value:r[f++],type:"text"})),l.push({value:" "+r[f++]+" ",type:"text"}),r[f+1]?(s=r[f+1],l.push({value:"("+r[f+1]+")",type:"text"}),f+=1):f-=1;while(f++<r.length)r[f]&&l.push({value:r[f],type:"text"});a&&(u=a,s=""),u&&(/regex/.test(s)||(u=i.escapeRegExp(u)),/whole/.test(s)&&(u="\\b"+u+"\\b"));var c=u&&o("("+u+")",/ sensitive/.test(s)?"g":"ig");return c&&(n[0]=t,n[1]=c),l}},{regex:"\\d+",token:"constant.numeric"}]}};r.inherits(u,s),t.C9SearchHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/c9search",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(){};r.inherits(o,s),function(){this.foldingStartMarker=/^(\S.*\:|Searching for.*)$/,this.foldingStopMarker=/^(\s+|Found.*)$/,this.getFoldWidgetRange=function(e,t,n){var r=e.doc.getAllLines(n),s=r[n],o=/^(Found.*|Searching for.*)$/,u=/^(\S.*\:|\s*)$/,a=o.test(s)?o:u,f=n,l=n;if(this.foldingStartMarker.test(s)){for(var c=n+1,h=e.getLength();c<h;c++)if(a.test(r[c]))break;l=c}else if(this.foldingStopMarker.test(s)){for(var c=n-1;c>=0;c--){s=r[c];if(a.test(s))break}f=c}if(f!=l){var p=s.length;return a===o&&(p=s.search(/\(Found[^)]+\)$|$/)),new i(f,p,l,0)}}}.call(o.prototype)}),ace.define("ace/mode/c9search",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/c9search_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/c9search"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./c9search_highlight_rules").C9SearchHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./folding/c9search").FoldMode,a=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new u};r.inherits(a,i),function(){this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/c9search"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-c_cpp.js b/dist/assets/js/vendor/ace-nc/mode-c_cpp.js
            new file mode 100644
            index 0000000000..6b856994d8
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-c_cpp.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/c_cpp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=t.cFunctions="\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\b",u=function(){var e="break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while|catch|operator|try|throw|using",t="asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|class|wchar_t|template",n="const|extern|register|restrict|static|volatile|inline|private:|protected:|public:|friend|explicit|virtual|export|mutable|typename",r="and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eqconst_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace",s="NULL|true|false|TRUE|FALSE",u=this.$keywords=this.createKeywordMapper({"keyword.control":e,"storage.type":t,"storage.modifier":n,"keyword.operator":r,"variable.language":"this","constant.language":s},"identifier"),a="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Zd\\$_\u00a1-\uffff]*\\b";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"keyword",regex:"#\\s*(?:include|import|pragma|line|define|undef|if|ifdef|else|elif|ifndef)\\b",next:"directive"},{token:"keyword",regex:"(?:#\\s*endif)\\b"},{token:"support.function.C99.c",regex:o},{token:u,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}],directive:[{token:"constant.other.multiline",regex:/\\/},{token:"constant.other.multiline",regex:/.*\\/},{token:"constant.other",regex:"\\s*<.+?>",next:"start"},{token:"constant.other",regex:'\\s*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]',next:"start"},{token:"constant.other",regex:"\\s*['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']",next:"start"},{token:"constant.other",regex:/[^\\\/]+/,next:"start"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(u,s),t.c_cppHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/c_cpp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/c_cpp_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./c_cpp_highlight_rules").c_cppHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/c_cpp"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-cirru.js b/dist/assets/js/vendor/ace-nc/mode-cirru.js
            new file mode 100644
            index 0000000000..73fd5da8d3
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-cirru.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/cirru_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"constant.numeric",regex:/[\d\.]+/},{token:"comment.line.double-dash",regex:/--/,next:"comment"},{token:"storage.modifier",regex:/\(/},{token:"storage.modifier",regex:/\,/,next:"line"},{token:"support.function",regex:/[^\(\)\"\s]+/,next:"line"},{token:"string.quoted.double",regex:/"/,next:"string"},{token:"storage.modifier",regex:/\)/}],comment:[{token:"comment.line.double-dash",regex:/\ +[^\n]+/,next:"start"}],string:[{token:"string.quoted.double",regex:/"/,next:"line"},{token:"constant.character.escape",regex:/\\/,next:"escape"},{token:"string.quoted.double",regex:/[^\\\"]+/}],escape:[{token:"constant.character.escape",regex:/./,next:"string"}],line:[{token:"constant.numeric",regex:/[\d\.]+/},{token:"markup.raw",regex:/^\s*/,next:"start"},{token:"storage.modifier",regex:/\$/,next:"start"},{token:"variable.parameter",regex:/[^\(\)\"\s]+/},{token:"storage.modifier",regex:/\(/,next:"start"},{token:"storage.modifier",regex:/\)/},{token:"markup.raw",regex:/^\ */,next:"start"},{token:"string.quoted.double",regex:/"/,next:"string"}]}};r.inherits(s,i),t.CirruHighlightRules=s}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/cirru",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/cirru_highlight_rules","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./cirru_highlight_rules").CirruHighlightRules,o=e("./folding/coffee").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="--",this.$id="ace/mode/cirru"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-clojure.js b/dist/assets/js/vendor/ace-nc/mode-clojure.js
            new file mode 100644
            index 0000000000..c1bc4f186b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-clojure.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/clojure_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="* *1 *2 *3 *agent* *allow-unresolved-vars* *assert* *clojure-version* *command-line-args* *compile-files* *compile-path* *e *err* *file* *flush-on-newline* *in* *macro-meta* *math-context* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* *print-readably* *read-eval* *source-path* *use-context-classloader* *warn-on-reflection* + - -> ->> .. / < <= = == > &gt; >= &gt;= accessor aclone add-classpath add-watch agent agent-errors aget alength alias all-ns alter alter-meta! alter-var-root amap ancestors and apply areduce array-map aset aset-boolean aset-byte aset-char aset-double aset-float aset-int aset-long aset-short assert assoc assoc! assoc-in associative? atom await await-for await1 bases bean bigdec bigint binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array booleans bound-fn bound-fn* butlast byte byte-array bytes cast char char-array char-escape-string char-name-string char? chars chunk chunk-append chunk-buffer chunk-cons chunk-first chunk-next chunk-rest chunked-seq? class class? clear-agent-errors clojure-version coll? comment commute comp comparator compare compare-and-set! compile complement concat cond condp conj conj! cons constantly construct-proxy contains? count counted? create-ns create-struct cycle dec decimal? declare definline defmacro defmethod defmulti defn defn- defonce defstruct delay delay? deliver deref derive descendants destructure disj disj! dissoc dissoc! distinct distinct? doall doc dorun doseq dosync dotimes doto double double-array doubles drop drop-last drop-while empty empty? ensure enumeration-seq eval even? every? false? ffirst file-seq filter find find-doc find-ns find-var first float float-array float? floats flush fn fn? fnext for force format future future-call future-cancel future-cancelled? future-done? future? gen-class gen-interface gensym get get-in get-method get-proxy-class get-thread-bindings get-validator hash hash-map hash-set identical? identity if-let if-not ifn? import in-ns inc init-proxy instance? int int-array integer? interleave intern interpose into into-array ints io! isa? iterate iterator-seq juxt key keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* list? load load-file load-reader load-string loaded-libs locking long long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy map map? mapcat max max-key memfn memoize merge merge-with meta method-sig methods min min-key mod name namespace neg? newline next nfirst nil? nnext not not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth nthnext num number? odd? or parents partial partition pcalls peek persistent! pmap pop pop! pop-thread-bindings pos? pr pr-str prefer-method prefers primitives-classnames print print-ctor print-doc print-dup print-method print-namespace-doc print-simple print-special-doc print-str printf println println-str prn prn-str promise proxy proxy-call-with-super proxy-mappings proxy-name proxy-super push-thread-bindings pvalues quot rand rand-int range ratio? rational? rationalize re-find re-groups re-matcher re-matches re-pattern re-seq read read-line read-string reduce ref ref-history-count ref-max-history ref-min-history ref-set refer refer-clojure release-pending-sends rem remove remove-method remove-ns remove-watch repeat repeatedly replace replicate require reset! reset-meta! resolve rest resultset-seq reverse reversible? rseq rsubseq second select-keys send send-off seq seq? seque sequence sequential? set set-validator! set? short short-array shorts shutdown-agents slurp some sort sort-by sorted-map sorted-map-by sorted-set sorted-set-by sorted? special-form-anchor special-symbol? split-at split-with str stream? string? struct struct-map subs subseq subvec supers swap! symbol symbol? sync syntax-symbol-anchor take take-last take-nth take-while test the-ns time to-array to-array-2d trampoline transient tree-seq true? type unchecked-add unchecked-dec unchecked-divide unchecked-inc unchecked-multiply unchecked-negate unchecked-remainder unchecked-subtract underive unquote unquote-splicing update-in update-proxy use val vals var-get var-set var? vary-meta vec vector vector? when when-first when-let when-not while with-bindings with-bindings* with-in-str with-loading-context with-local-vars with-meta with-open with-out-str with-precision xml-seq zero? zipmap",t="throw try var def do fn if let loop monitor-enter monitor-exit new quote recur set!",n="true false nil",r=this.createKeywordMapper({keyword:t,"constant.language":n,"support.function":e},"identifier",!1," ");this.$rules={start:[{token:"comment",regex:";.*$"},{token:"keyword",regex:"[\\(|\\)]"},{token:"keyword",regex:"[\\'\\(]"},{token:"keyword",regex:"[\\[|\\]]"},{token:"keyword",regex:"[\\{|\\}|\\#\\{|\\#\\}]"},{token:"keyword",regex:"[\\&]"},{token:"keyword",regex:"[\\#\\^\\{]"},{token:"keyword",regex:"[\\%]"},{token:"keyword",regex:"[@]"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language",regex:"[!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+||=|!=|<=|>=|<>|<|>|!|&&]"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$\\-]*\\b"},{token:"string",regex:'"',next:"string"},{token:"constant",regex:/:[^()\[\]{}'"\^%`,;\s]+/},{token:"string.regexp",regex:'/#"(?:\\.|(?:\\")|[^""\n])*"/g'}],string:[{token:"constant.language.escape",regex:"\\\\.|\\\\$"},{token:"string",regex:'[^"\\\\]+'},{token:"string",regex:'"',next:"start"}]}};r.inherits(s,i),t.ClojureHighlightRules=s}),ace.define("ace/mode/matching_parens_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\)/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\))/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){var t=e.match(/^(\s+)/);return t?t[1]:""}}).call(i.prototype),t.MatchingParensOutdent=i}),ace.define("ace/mode/clojure",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/clojure_highlight_rules","ace/mode/matching_parens_outdent"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./clojure_highlight_rules").ClojureHighlightRules,o=e("./matching_parens_outdent").MatchingParensOutdent,u=function(){this.HighlightRules=s,this.$outdent=new o};r.inherits(u,i),function(){this.lineCommentStart=";",this.minorIndentFunctions=["defn","defn-","defmacro","def","deftest","testing"],this.$toIndent=function(e){return e.split("").map(function(e){return/\s/.exec(e)?e:" "}).join("")},this.$calculateIndent=function(e,t){var n=this.$getIndent(e),r=0,i,s;for(var o=e.length-1;o>=0;o--){s=e[o],s==="("?(r--,i=!0):s==="("||s==="["||s==="{"?(r--,i=!1):(s===")"||s==="]"||s==="}")&&r++;if(r<0)break}if(!(r<0&&i))return r<0&&!i?this.$toIndent(e.substring(0,o+1)):r>0?(n=n.substring(0,n.length-t.length),n):n;o+=1;var u=o,a="";for(;;){s=e[o];if(s===" "||s==="	")return this.minorIndentFunctions.indexOf(a)!==-1?this.$toIndent(e.substring(0,u-1)+t):this.$toIndent(e.substring(0,o+1));if(s===undefined)return this.$toIndent(e.substring(0,u-1)+t);a+=e[o],o++}},this.getNextLineIndent=function(e,t,n){return this.$calculateIndent(t,n)},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/clojure"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-cobol.js b/dist/assets/js/vendor/ace-nc/mode-cobol.js
            new file mode 100644
            index 0000000000..2f766c1a74
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-cobol.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/cobol_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="ACCEPT|MERGE|SUM|ADD||MESSAGE|TABLE|ADVANCING|MODE|TAPE|AFTER|MULTIPLY|TEST|ALL|NEGATIVE|TEXT|ALPHABET|NEXT|THAN|ALSO|NO|THEN|ALTERNATE|NOT|THROUGH|AND|NUMBER|THRU|ANY|OCCURS|TIME|ARE|OF|TO|AREA|OFF|TOP||ASCENDING|OMITTED|TRUE|ASSIGN|ON|TYPE|AT|OPEN|UNIT|AUTHOR|OR|UNTIL|BEFORE|OTHER|UP|BLANK|OUTPUT|USE|BLOCK|PAGE|USING|BOTTOM|PERFORM|VALUE|BY|PIC|VALUES|CALL|PICTURE|WHEN|CANCEL|PLUS|WITH|CD|POINTER|WRITE|CHARACTER|POSITION||ZERO|CLOSE|POSITIVE|ZEROS|COLUMN|PROCEDURE|ZEROES|COMMA|PROGRAM|COMMON|PROGRAM-ID|COMMUNICATION|QUOTE|COMP|RANDOM|COMPUTE|READ|CONTAINS|RECEIVE|CONFIGURATION|RECORD|CONTINUE|REDEFINES|CONTROL|REFERENCE|COPY|REMAINDER|COUNT|REPLACE|DATA|REPORT|DATE|RESERVE|DAY|RESET|DELETE|RETURN|DESTINATION|REWIND|DISABLE|REWRITE|DISPLAY|RIGHT|DIVIDE|RUN|DOWN|SAME|ELSE|SEARCH|ENABLE|SECTION|END|SELECT|ENVIRONMENT|SENTENCE|EQUAL|SET|ERROR|SIGN|EXIT|SEQUENTIAL|EXTERNAL|SIZE|FLASE|SORT|FILE|SOURCE|LENGTH|SPACE|LESS|STANDARD|LIMIT|START|LINE|STOP|LOCK|STRING|LOW-VALUE|SUBTRACT",t="true|false|null",n="count|min|max|avg|sum|rank|now|coalesce|main",r=this.createKeywordMapper({"support.function":n,keyword:e,"constant.language":t},"identifier",!0);this.$rules={start:[{token:"comment",regex:"\\*.*$"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]}};r.inherits(s,i),t.CobolHighlightRules=s}),ace.define("ace/mode/cobol",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/cobol_highlight_rules","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./cobol_highlight_rules").CobolHighlightRules,o=e("../range").Range,u=function(){this.HighlightRules=s};r.inherits(u,i),function(){this.lineCommentStart="*",this.$id="ace/mode/cobol"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-coffee.js b/dist/assets/js/vendor/ace-nc/mode-coffee.js
            new file mode 100644
            index 0000000000..cc70f0fe76
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-coffee.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/coffee_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function s(){var e="[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*",t="this|throw|then|try|typeof|super|switch|return|break|by|continue|catch|class|in|instanceof|is|isnt|if|else|extends|for|own|finally|function|while|when|new|no|not|delete|debugger|do|loop|of|off|or|on|unless|until|and|yes",n="true|false|null|undefined|NaN|Infinity",r="case|const|default|function|var|void|with|enum|export|implements|interface|let|package|private|protected|public|static|yield|__hasProp|slice|bind|indexOf",i="Array|Boolean|Date|Function|Number|Object|RegExp|ReferenceError|String|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray",s="Math|JSON|isNaN|isFinite|parseInt|parseFloat|encodeURI|encodeURIComponent|decodeURI|decodeURIComponent|String|",o="window|arguments|prototype|document",u=this.createKeywordMapper({keyword:t,"constant.language":n,"invalid.illegal":r,"language.support.class":i,"language.support.function":s,"variable.language":o},"identifier"),a={token:["paren.lparen","variable.parameter","paren.rparen","text","storage.type"],regex:/(?:(\()((?:"[^")]*?"|'[^')]*?'|\/[^\/)]*?\/|[^()\"'\/])*?)(\))(\s*))?([\-=]>)/.source},f=/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)/;this.$rules={start:[{token:"constant.numeric",regex:"(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)"},{stateName:"qdoc",token:"string",regex:"'''",next:[{token:"string",regex:"'''",next:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{stateName:"qqdoc",token:"string",regex:'"""',next:[{token:"string",regex:'"""',next:"start"},{token:"paren.string",regex:"#{",push:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{stateName:"qstring",token:"string",regex:"'",next:[{token:"string",regex:"'",next:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{stateName:"qqstring",token:"string.start",regex:'"',next:[{token:"string.end",regex:'"',next:"start"},{token:"paren.string",regex:"#{",push:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{stateName:"js",token:"string",regex:"`",next:[{token:"string",regex:"`",next:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{regex:"[{}]",onMatch:function(e,t,n){this.next="";if(e=="{"&&n.length)return n.unshift("start",t),"paren";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.string"}return"paren"}},{token:"string.regex",regex:"///",next:"heregex"},{token:"string.regex",regex:/(?:\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)(?:[imgy]{0,4})(?!\w)/},{token:"comment",regex:"###(?!#)",next:"comment"},{token:"comment",regex:"#.*"},{token:["punctuation.operator","text","identifier"],regex:"(\\.)(\\s*)("+r+")"},{token:"punctuation.operator",regex:"\\."},{token:["keyword","text","language.support.class","text","keyword","text","language.support.class"],regex:"(class)(\\s+)("+e+")(?:(\\s+)(extends)(\\s+)("+e+"))?"},{token:["entity.name.function","text","keyword.operator","text"].concat(a.token),regex:"("+e+")(\\s*)([=:])(\\s*)"+a.regex},a,{token:"variable",regex:"@(?:"+e+")?"},{token:u,regex:e},{token:"punctuation.operator",regex:"\\,|\\."},{token:"storage.type",regex:"[\\-=]>"},{token:"keyword.operator",regex:"(?:[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|[!*+-=><])"},{token:"paren.lparen",regex:"[({[]"},{token:"paren.rparen",regex:"[\\]})]"},{token:"text",regex:"\\s+"}],heregex:[{token:"string.regex",regex:".*?///[imgy]{0,4}",next:"start"},{token:"comment.regex",regex:"\\s+(?:#.*)?"},{token:"string.regex",regex:"\\S+"}],comment:[{token:"comment",regex:"###",next:"start"},{defaultToken:"comment"}]},this.normalizeRules()}var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules;r.inherits(s,i),t.CoffeeHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/coffee",["require","exports","module","ace/mode/coffee_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/coffee","ace/range","ace/mode/text","ace/worker/worker_client","ace/lib/oop"],function(e,t,n){"use strict";function l(){this.HighlightRules=r,this.$outdent=new i,this.foldingRules=new s}var r=e("./coffee_highlight_rules").CoffeeHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("./folding/coffee").FoldMode,o=e("../range").Range,u=e("./text").Mode,a=e("../worker/worker_client").WorkerClient,f=e("../lib/oop");f.inherits(l,u),function(){var e=/(?:[({[=:]|[-=]>|\b(?:else|try|(?:swi|ca)tch(?:\s+[$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)?|finally))\s*$|^\s*(else\b\s*)?(?:if|for|while|loop)\b(?!.*\bthen\b)/,t=/^(\s*)#/,n=/^\s*###(?!#)/,r=/^\s*/;this.getNextLineIndent=function(t,n,r){var i=this.$getIndent(n),s=this.getTokenizer().getLineTokens(n,t).tokens;return(!s.length||s[s.length-1].type!=="comment")&&t==="start"&&e.test(n)&&(i+=r),i},this.toggleCommentLines=function(e,i,s,u){console.log("toggle");var a=new o(0,0,0,0);for(var f=s;f<=u;++f){var l=i.getLine(f);if(n.test(l))continue;t.test(l)?l=l.replace(t,"$1"):l=l.replace(r,"$&#"),a.end.row=a.start.row=f,a.end.column=l.length+1,i.replace(a,l)}},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/coffee_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("error",function(t){e.setAnnotations([t.data])}),t.on("ok",function(t){e.clearAnnotations()}),t},this.$id="ace/mode/coffee"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-coldfusion.js b/dist/assets/js/vendor/ace-nc/mode-coldfusion.js
            new file mode 100644
            index 0000000000..b3060e7f69
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-coldfusion.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/coldfusion_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/javascript_highlight_rules","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./html_highlight_rules").HtmlHighlightRules,o=function(){s.call(this),this.embedTagRules(i,"cfjs-","cfscript"),this.normalizeRules()};r.inherits(o,s),t.ColdfusionHighlightRules=o}),ace.define("ace/mode/coldfusion",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/html","ace/mode/coldfusion_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./html").Mode,o=e("./coldfusion_highlight_rules").ColdfusionHighlightRules,u="cfabort|cfapplication|cfargument|cfassociate|cfbreak|cfcache|cfcollection|cfcookie|cfdbinfo|cfdirectory|cfdump|cfelse|cfelseif|cferror|cfexchangecalendar|cfexchangeconnection|cfexchangecontact|cfexchangefilter|cfexchangetask|cfexit|cffeed|cffile|cfflush|cfftp|cfheader|cfhtmlhead|cfhttpparam|cfimage|cfimport|cfinclude|cfindex|cfinsert|cfinvokeargument|cflocation|cflog|cfmailparam|cfNTauthenticate|cfobject|cfobjectcache|cfparam|cfpdfformparam|cfprint|cfprocparam|cfprocresult|cfproperty|cfqueryparam|cfregistry|cfreportparam|cfrethrow|cfreturn|cfschedule|cfsearch|cfset|cfsetting|cfthrow|cfzipparam)".split("|"),a=function(){s.call(this),this.HighlightRules=o};r.inherits(a,s),function(){this.voidElements=r.mixin(i.arrayToMap(u),this.voidElements),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.$id="ace/mode/coldfusion"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-csharp.js b/dist/assets/js/vendor/ace-nc/mode-csharp.js
            new file mode 100644
            index 0000000000..06ba6f7637
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-csharp.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/csharp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"this",keyword:"abstract|event|new|struct|as|explicit|null|switch|base|extern|object|this|bool|false|operator|throw|break|finally|out|true|byte|fixed|override|try|case|float|params|typeof|catch|for|private|uint|char|foreach|protected|ulong|checked|goto|public|unchecked|class|if|readonly|unsafe|const|implicit|ref|ushort|continue|in|return|using|decimal|int|sbyte|virtual|default|interface|sealed|volatile|delegate|internal|short|void|do|is|sizeof|while|double|lock|stackalloc|else|long|static|enum|namespace|string|var|dynamic","constant.language":"null|true|false"},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:/'(?:.|\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n]))'/},{token:"string",start:'"',end:'"|$',next:[{token:"constant.language.escape",regex:/\\(:?u[\da-fA-F]+|x[\da-fA-F]+|[tbrf'"n])/},{token:"invalid",regex:/\\./}]},{token:"string",start:'@"',end:'"',next:[{token:"constant.language.escape",regex:'""'}]},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"keyword",regex:"^\\s*#(if|else|elif|endif|define|undef|warning|error|line|region|endregion|pragma)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}]},this.embedRules(i,"doc-",[i.getEndRule("start")]),this.normalizeRules()};r.inherits(o,s),t.CSharpHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/folding/csharp",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./cstyle").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.usingRe=/^\s*using \S/,this.getFoldWidgetRangeBase=this.getFoldWidgetRange,this.getFoldWidgetBase=this.getFoldWidget,this.getFoldWidget=function(e,t,n){var r=this.getFoldWidgetBase(e,t,n);if(!r){var i=e.getLine(n);if(/^\s*#region\b/.test(i))return"start";var s=this.usingRe;if(s.test(i)){var o=e.getLine(n-1),u=e.getLine(n+1);if(!s.test(o)&&s.test(u))return"start"}}return r},this.getFoldWidgetRange=function(e,t,n){var r=this.getFoldWidgetRangeBase(e,t,n);if(r)return r;var i=e.getLine(n);if(this.usingRe.test(i))return this.getUsingStatementBlock(e,i,n);if(/^\s*#region\b/.test(i))return this.getRegionBlock(e,i,n)},this.getUsingStatementBlock=function(e,t,n){var r=t.match(this.usingRe)[0].length-1,s=e.getLength(),o=n,u=n;while(++n<s){t=e.getLine(n);if(/^\s*$/.test(t))continue;if(!this.usingRe.test(t))break;u=n}if(u>o){var a=e.getLine(u).length;return new i(o,r,u,a)}},this.getRegionBlock=function(e,t,n){var r=t.search(/\s*$/),s=e.getLength(),o=n,u=/^\s*#(end)?region\b/,a=1;while(++n<s){t=e.getLine(n);var f=u.exec(t);if(!f)continue;f[1]?a--:a++;if(!a)break}var l=n;if(l>o){var c=t.search(/\S/);return new i(o,r,l,c)}}}.call(o.prototype)}),ace.define("ace/mode/csharp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/csharp_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/csharp"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./csharp_highlight_rules").CSharpHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/csharp").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[]\s*$/);o&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){return null},this.$id="ace/mode/csharp"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-css.js b/dist/assets/js/vendor/ace-nc/mode-css.js
            new file mode 100644
            index 0000000000..7004bf601e
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-css.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-curly.js b/dist/assets/js/vendor/ace-nc/mode-curly.js
            new file mode 100644
            index 0000000000..ae2ba47385
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-curly.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/curly_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=function(){i.call(this),this.$rules.start.unshift({token:"variable",regex:"{{",push:"curly-start"}),this.$rules["curly-start"]=[{token:"variable",regex:"}}",next:"pop"}],this.normalizeRules()};r.inherits(s,i),t.CurlyHighlightRules=s}),ace.define("ace/mode/curly",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/matching_brace_outdent","ace/mode/html_highlight_rules","ace/mode/folding/html","ace/mode/curly_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html").Mode,s=e("./matching_brace_outdent").MatchingBraceOutdent,o=e("./html_highlight_rules").HtmlHighlightRules,u=e("./folding/html").FoldMode,a=e("./curly_highlight_rules").CurlyHighlightRules,f=function(){i.call(this),this.HighlightRules=a,this.$outdent=new s,this.foldingRules=new u};r.inherits(f,i),function(){this.$id="ace/mode/curly"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-d.js b/dist/assets/js/vendor/ace-nc/mode-d.js
            new file mode 100644
            index 0000000000..d8bf889fbf
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-d.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/d_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="this|super|import|module|body|mixin|__traits|invariant|alias|asm|delete|typeof|typeid|sizeof|cast|new|in|is|typedef|__vector|__parameters",t="break|case|continue|default|do|else|for|foreach|foreach_reverse|goto|if|return|switch|while|catch|try|throw|finally|version|assert|unittest|with",n="auto|bool|char|dchar|wchar|byte|ubyte|float|double|real|cfloat|creal|cdouble|cent|ifloat|ireal|idouble|int|long|short|void|uint|ulong|ushort|ucent|function|delegate|string|wstring|dstring|size_t|ptrdiff_t|hash_t|Object",r="abstract|align|debug|deprecated|export|extern|const|final|in|inout|out|ref|immutable|lazy|nothrow|override|package|pragma|private|protected|public|pure|scope|shared|__gshared|synchronized|static|volatile",s="class|struct|union|template|interface|enum|macro",o={token:"constant.language.escape",regex:"\\\\(?:(?:x[0-9A-F]{2})|(?:[0-7]{1,3})|(?:['\"\\?0abfnrtv\\\\])|(?:u[0-9a-fA-F]{4})|(?:U[0-9a-fA-F]{8}))"},u="null|true|false|__DATE__|__EOF__|__TIME__|__TIMESTAMP__|__VENDOR__|__VERSION__|__FILE__|__MODULE__|__LINE__|__FUNCTION__|__PRETTY_FUNCTION__",a="/|/\\=|&|&\\=|&&|\\|\\|\\=|\\|\\||\\-|\\-\\=|\\-\\-|\\+|\\+\\=|\\+\\+|\\<|\\<\\=|\\<\\<|\\<\\<\\=|\\<\\>|\\<\\>\\=|\\>|\\>\\=|\\>\\>\\=|\\>\\>\\>\\=|\\>\\>|\\>\\>\\>|\\!|\\!\\=|\\!\\<\\>|\\!\\<\\>\\=|\\!\\<|\\!\\<\\=|\\!\\>|\\!\\>\\=|\\?|\\$|\\=|\\=\\=|\\*|\\*\\=|%|%\\=|\\^|\\^\\=|\\^\\^|\\^\\^\\=|~|~\\=|\\=\\>|#",f=this.$keywords=this.createKeywordMapper({"keyword.modifier":r,"keyword.control":t,"keyword.type":n,keyword:e,"keyword.storage":s,punctation:"\\.|\\,|;|\\.\\.|\\.\\.\\.","keyword.operator":a,"constant.language":u},"identifier"),l="[a-zA-Z_\u00a1-\uffff][a-zA-Z\\d_\u00a1-\uffff]*\\b";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"star-comment"},{token:"comment.shebang",regex:"^s*#!.*"},{token:"comment",regex:"\\/\\+",next:"plus-comment"},{onMatch:function(e,t,n){return n.unshift(this.next,e.substr(2)),"string"},regex:'q"(?:[\\[\\(\\{\\<]+)',next:"operator-heredoc-string"},{onMatch:function(e,t,n){return n.unshift(this.next,e.substr(2)),"string"},regex:'q"(?:[a-zA-Z_]+)$',next:"identifier-heredoc-string"},{token:"string",regex:'[xr]?"',next:"quote-string"},{token:"string",regex:"[xr]?`",next:"backtick-string"},{token:"string",regex:"[xr]?['](?:(?:\\\\.)|(?:[^'\\\\]))*?['][cdw]?"},{token:["keyword","text","paren.lparen"],regex:/(asm)(\s*)({)/,next:"d-asm"},{token:["keyword","text","paren.lparen","constant.language"],regex:"(__traits)(\\s*)(\\()("+l+")"},{token:["keyword","text","variable.module"],regex:"(import|module)(\\s+)((?:"+l+"\\.?)*)"},{token:["keyword.storage","text","entity.name.type"],regex:"("+s+")(\\s*)("+l+")"},{token:["keyword","text","variable.storage","text"],regex:"(alias|typedef)(\\s*)("+l+")(\\s*)"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F_]+(l|ul|u|f|F|L|U|UL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d[\\d_]*(?:(?:\\.[\\d_]*)?(?:[eE][+-]?[\\d_]+)?)?(l|ul|u|f|F|L|U|UL)?\\b"},{token:"entity.other.attribute-name",regex:"@"+l},{token:f,regex:"[a-zA-Z_][a-zA-Z0-9_]*\\b"},{token:"keyword.operator",regex:a},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\.|\\:"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],"star-comment":[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],"plus-comment":[{token:"comment",regex:"\\+\\/",next:"start"},{defaultToken:"comment"}],"quote-string":[o,{token:"string",regex:'"[cdw]?',next:"start"},{defaultToken:"string"}],"backtick-string":[o,{token:"string",regex:"`[cdw]?",next:"start"},{defaultToken:"string"}],"operator-heredoc-string":[{onMatch:function(e,t,n){e=e.substring(e.length-2,e.length-1);var r={">":"<","]":"[",")":"(","}":"{"};return Object.keys(r).indexOf(e)!=-1&&(e=r[e]),e!=n[1]?"string":(n.shift(),n.shift(),"string")},regex:'(?:[\\]\\)}>]+)"',next:"start"},{token:"string",regex:"[^\\]\\)}>]+"}],"identifier-heredoc-string":[{onMatch:function(e,t,n){return e=e.substring(0,e.length-1),e!=n[1]?"string":(n.shift(),n.shift(),"string")},regex:'^(?:[A-Za-z_][a-zA-Z0-9]+)"',next:"start"},{token:"string",regex:"[^\\]\\)}>]+"}],"d-asm":[{token:"paren.rparen",regex:"\\}",next:"start"},{token:"keyword.instruction",regex:"[a-zA-Z]+",next:"d-asm-instruction"},{token:"text",regex:"\\s+"}],"d-asm-instruction":[{token:"constant.language",regex:/AL|AH|AX|EAX|BL|BH|BX|EBX|CL|CH|CX|ECX|DL|DH|DX|EDX|BP|EBP|SP|ESP|DI|EDI|SI|ESI/i},{token:"identifier",regex:"[a-zA-Z]+"},{token:"string",regex:'".*"'},{token:"comment",regex:"//.*$"},{token:"constant.numeric",regex:"[0-9.xA-F]+"},{token:"punctuation.operator",regex:"\\,"},{token:"punctuation.operator",regex:";",next:"d-asm"},{token:"text",regex:"\\s+"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};o.metaData={comment:"D language",fileTypes:["d","di"],firstLineMatch:"^#!.*\\b[glr]?dmd\\b.",foldingStartMarker:"(?x)/\\*\\*(?!\\*)|^(?![^{]*?//|[^{]*?/\\*(?!.*?\\*/.*?\\{)).*?\\{\\s*($|//|/\\*(?!.*?\\*/.*\\S))",foldingStopMarker:"(?<!\\*)\\*\\*/|^\\s*\\}",keyEquivalent:"^~D",name:"D",scopeName:"source.d"},r.inherits(o,s),t.DHighlightRules=o}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/d",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/d_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./d_highlight_rules").DHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="/\\+",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/d"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-dart.js b/dist/assets/js/vendor/ace-nc/mode-dart.js
            new file mode 100644
            index 0000000000..7330550244
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-dart.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/c_cpp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=t.cFunctions="\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\b",u=function(){var e="break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while|catch|operator|try|throw|using",t="asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|class|wchar_t|template",n="const|extern|register|restrict|static|volatile|inline|private:|protected:|public:|friend|explicit|virtual|export|mutable|typename",r="and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eqconst_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace",s="NULL|true|false|TRUE|FALSE",u=this.$keywords=this.createKeywordMapper({"keyword.control":e,"storage.type":t,"storage.modifier":n,"keyword.operator":r,"variable.language":"this","constant.language":s},"identifier"),a="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Zd\\$_\u00a1-\uffff]*\\b";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"keyword",regex:"#\\s*(?:include|import|pragma|line|define|undef|if|ifdef|else|elif|ifndef)\\b",next:"directive"},{token:"keyword",regex:"(?:#\\s*endif)\\b"},{token:"support.function.C99.c",regex:o},{token:u,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}],directive:[{token:"constant.other.multiline",regex:/\\/},{token:"constant.other.multiline",regex:/.*\\/},{token:"constant.other",regex:"\\s*<.+?>",next:"start"},{token:"constant.other",regex:'\\s*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]',next:"start"},{token:"constant.other",regex:"\\s*['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']",next:"start"},{token:"constant.other",regex:/[^\\\/]+/,next:"start"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(u,s),t.c_cppHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/c_cpp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/c_cpp_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./c_cpp_highlight_rules").c_cppHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/c_cpp"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/dart_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="true|false|null",t="this|super",n="try|catch|finally|throw|rethrow|assert|break|case|continue|default|do|else|for|if|in|return|switch|while|new",r="abstract|class|extends|external|factory|implements|get|native|operator|set|typedef|with",s="static|final|const",o="void|bool|num|int|double|dynamic|var|String",u=this.createKeywordMapper({"constant.language.dart":e,"variable.language.dart":t,"keyword.control.dart":n,"keyword.declaration.dart":r,"storage.modifier.dart":s,"storage.type.primitive.dart":o},"identifier"),a={token:"string",regex:".+"};this.$rules={start:[{token:"comment",regex:/\/\/.*$/},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:["meta.preprocessor.script.dart"],regex:"^(#!.*)$"},{token:"keyword.other.import.dart",regex:"(?:\\b)(?:library|import|export|part|of)(?:\\b)"},{token:["keyword.other.import.dart","text"],regex:"(?:\\b)(prefix)(\\s*:)"},{regex:"\\bas\\b",token:"keyword.cast.dart"},{regex:"\\?|:",token:"keyword.control.ternary.dart"},{regex:"(?:\\b)(is\\!?)(?:\\b)",token:["keyword.operator.dart"]},{regex:"(<<|>>>?|~|\\^|\\||&)",token:["keyword.operator.bitwise.dart"]},{regex:"((?:&|\\^|\\||<<|>>>?)=)",token:["keyword.operator.assignment.bitwise.dart"]},{regex:"(===?|!==?|<=?|>=?)",token:["keyword.operator.comparison.dart"]},{regex:"((?:[+*/%-]|\\~)=)",token:["keyword.operator.assignment.arithmetic.dart"]},{regex:"=",token:"keyword.operator.assignment.dart"},{token:"string",regex:"'''",next:"qdoc"},{token:"string",regex:'"""',next:"qqdoc"},{token:"string",regex:"'",next:"qstring"},{token:"string",regex:'"',next:"qqstring"},{regex:"(\\-\\-|\\+\\+)",token:["keyword.operator.increment-decrement.dart"]},{regex:"(\\-|\\+|\\*|\\/|\\~\\/|%)",token:["keyword.operator.arithmetic.dart"]},{regex:"(!|&&|\\|\\|)",token:["keyword.operator.logical.dart"]},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:u,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qdoc:[{token:"string",regex:".*?'''",next:"start"},a],qqdoc:[{token:"string",regex:'.*?"""',next:"start"},a],qstring:[{token:"string",regex:"[^\\\\']*(?:\\\\.[^\\\\']*)*'",next:"start"},a],qqstring:[{token:"string",regex:'[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',next:"start"},a]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(o,s),t.DartHighlightRules=o}),ace.define("ace/mode/dart",["require","exports","module","ace/lib/oop","ace/mode/c_cpp","ace/mode/dart_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./c_cpp").Mode,s=e("./dart_highlight_rules").DartHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){i.call(this),this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/dart"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-diff.js b/dist/assets/js/vendor/ace-nc/mode-diff.js
            new file mode 100644
            index 0000000000..7760fe7943
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-diff.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/diff_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{regex:"^(?:\\*{15}|={67}|-{3}|\\+{3})$",token:"punctuation.definition.separator.diff",name:"keyword"},{regex:"^(@@)(\\s*.+?\\s*)(@@)(.*)$",token:["constant","constant.numeric","constant","comment.doc.tag"]},{regex:"^(\\d+)([,\\d]+)(a|d|c)(\\d+)([,\\d]+)(.*)$",token:["constant.numeric","punctuation.definition.range.diff","constant.function","constant.numeric","punctuation.definition.range.diff","invalid"],name:"meta."},{regex:"^(\\-{3}|\\+{3}|\\*{3})( .+)$",token:["constant.numeric","meta.tag"]},{regex:"^([!+>])(.*?)(\\s*)$",token:["support.constant","text","invalid"]},{regex:"^([<\\-])(.*?)(\\s*)$",token:["support.function","string","invalid"]},{regex:"^(diff)(\\s+--\\w+)?(.+?)( .+)?$",token:["variable","variable","keyword","variable"]},{regex:"^Index.+$",token:"variable"},{regex:"^\\s+$",token:"text"},{regex:"\\s*$",token:"invalid"},{defaultToken:"invisible",caseInsensitive:!0}]}};r.inherits(s,i),t.DiffHighlightRules=s}),ace.define("ace/mode/folding/diff",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(e,t){this.regExpList=e,this.flag=t,this.foldingStartMarker=RegExp("^("+e.join("|")+")",this.flag)};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i={row:n,column:r.length},o=this.regExpList;for(var u=1;u<=o.length;u++){var a=RegExp("^("+o.slice(0,u).join("|")+")",this.flag);if(a.test(r))break}for(var f=e.getLength();++n<f;){r=e.getLine(n);if(a.test(r))break}if(n==i.row+1)return;return s.fromPoints(i,{row:n-1,column:r.length})}}.call(o.prototype)}),ace.define("ace/mode/diff",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/diff_highlight_rules","ace/mode/folding/diff"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./diff_highlight_rules").DiffHighlightRules,o=e("./folding/diff").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o(["diff","index","\\+{3}","@@|\\*{5}"],"i")};r.inherits(u,i),function(){this.$id="ace/mode/diff"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-django.js b/dist/assets/js/vendor/ace-nc/mode-django.js
            new file mode 100644
            index 0000000000..e65d11c7a0
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-django.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/django",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/html_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./html").Mode,s=e("./html_highlight_rules").HtmlHighlightRules,o=e("./text_highlight_rules").TextHighlightRules,u=function(){this.$rules={start:[{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant",regex:"[0-9]+"},{token:"variable",regex:"[-_a-zA-Z0-9:]+"}],comment:[{token:"comment.block",merge:!0,regex:".+?"}],tag:[{token:"entity.name.function",regex:"[a-zA-Z][_a-zA-Z0-9]*",next:"start"}]}};r.inherits(u,o);var a=function(){this.$rules=(new s).getRules();for(var e in this.$rules)this.$rules[e].unshift({token:"comment.line",regex:"\\{#.*?#\\}"},{token:"comment.block",regex:"\\{\\%\\s*comment\\s*\\%\\}",merge:!0,next:"django-comment"},{token:"constant.language",regex:"\\{\\{",next:"django-start"},{token:"constant.language",regex:"\\{\\%",next:"django-tag"}),this.embedRules(u,"django-",[{token:"comment.block",regex:"\\{\\%\\s*endcomment\\s*\\%\\}",merge:!0,next:"start"},{token:"constant.language",regex:"\\%\\}",next:"start"},{token:"constant.language",regex:"\\}\\}",next:"start"}])};r.inherits(a,s);var f=function(){i.call(this),this.HighlightRules=a};r.inherits(f,i),function(){this.$id="ace/mode/django"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-dockerfile.js b/dist/assets/js/vendor/ace-nc/mode-dockerfile.js
            new file mode 100644
            index 0000000000..00bcd9b868
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-dockerfile.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/sh_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.reservedKeywords="!|{|}|case|do|done|elif|else|esac|fi|for|if|in|then|until|while|&|;|export|local|read|typeset|unset|elif|select|set",o=t.languageConstructs="[|]|alias|bg|bind|break|builtin|cd|command|compgen|complete|continue|dirs|disown|echo|enable|eval|exec|exit|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|return|set|shift|shopt|source|suspend|test|times|trap|type|ulimit|umask|unalias|wait",u=function(){var e=this.createKeywordMapper({keyword:s,"support.function.builtin":o,"invalid.deprecated":"debugger"},"identifier"),t="(?:(?:[1-9]\\d*)|(?:0))",n="(?:\\.\\d+)",r="(?:\\d+)",i="(?:(?:"+r+"?"+n+")|(?:"+r+"\\.))",u="(?:(?:"+i+"|"+r+")"+")",a="(?:"+u+"|"+i+")",f="(?:&"+r+")",l="[a-zA-Z_][a-zA-Z0-9_]*",c="(?:(?:\\$"+l+")|(?:"+l+"=))",h="(?:\\$(?:SHLVL|\\$|\\!|\\?))",p="(?:"+l+"\\s*\\(\\))";this.$rules={start:[{token:"constant",regex:/\\./},{token:["text","comment"],regex:/(^|\s)(#.*)$/},{token:"string",regex:'"',push:[{token:"constant.language.escape",regex:/\\(?:[$abeEfnrtv\\'"]|x[a-fA-F\d]{1,2}|u[a-fA-F\d]{4}([a-fA-F\d]{4})?|c.|\d{1,3})/},{token:"constant",regex:/\$\w+/},{token:"string",regex:'"',next:"pop"},{defaultToken:"string"}]},{token:"variable.language",regex:h},{token:"variable",regex:c},{token:"support.function",regex:p},{token:"support.function",regex:f},{token:"string",start:"'",end:"'"},{token:"constant.numeric",regex:a},{token:"constant.numeric",regex:t+"\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|~|<|>|<=|=>|=|!="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"}]},this.normalizeRules()};r.inherits(u,i),t.ShHighlightRules=u}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/sh",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sh_highlight_rules","ace/range","ace/mode/folding/cstyle","ace/mode/behaviour/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./sh_highlight_rules").ShHighlightRules,o=e("../range").Range,u=e("./folding/cstyle").FoldMode,a=e("./behaviour/cstyle").CstyleBehaviour,f=function(){this.HighlightRules=s,this.foldingRules=new u,this.$behaviour=new a};r.inherits(f,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[\:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new o(n,r.length-i.length,n,r.length))},this.$id="ace/mode/sh"}.call(f.prototype),t.Mode=f}),ace.define("ace/mode/dockerfile_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/sh_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./sh_highlight_rules").ShHighlightRules,s=function(){i.call(this);var e=this.$rules.start;for(var t=0;t<e.length;t++)if(e[t].token=="variable.language"){e.splice(t,0,{token:"variable.language",regex:"(?:^(?:FROM|MAINTAINER|RUN|CMD|EXPOSE|ENV|ADD|ENTRYPOINT|VOLUME|USER|WORKDIR|ONBUILD)\\b)",caseInsensitive:!0});break}};r.inherits(s,i),t.DockerfileHighlightRules=s}),ace.define("ace/mode/dockerfile",["require","exports","module","ace/lib/oop","ace/mode/sh","ace/mode/dockerfile_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./sh").Mode,s=e("./dockerfile_highlight_rules").DockerfileHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){i.call(this),this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.$id="ace/mode/dockerfile"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-dot.js b/dist/assets/js/vendor/ace-nc/mode-dot.js
            new file mode 100644
            index 0000000000..e1073b01ec
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-dot.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/dot_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/doc_comment_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=e("./doc_comment_highlight_rules").DocCommentHighlightRules,u=function(){var e=i.arrayToMap("strict|node|edge|graph|digraph|subgraph".split("|")),t=i.arrayToMap("damping|k|url|area|arrowhead|arrowsize|arrowtail|aspect|bb|bgcolor|center|charset|clusterrank|color|colorscheme|comment|compound|concentrate|constraint|decorate|defaultdist|dim|dimen|dir|diredgeconstraints|distortion|dpi|edgeurl|edgehref|edgetarget|edgetooltip|epsilon|esep|fillcolor|fixedsize|fontcolor|fontname|fontnames|fontpath|fontsize|forcelabels|gradientangle|group|headurl|head_lp|headclip|headhref|headlabel|headport|headtarget|headtooltip|height|href|id|image|imagepath|imagescale|label|labelurl|label_scheme|labelangle|labeldistance|labelfloat|labelfontcolor|labelfontname|labelfontsize|labelhref|labeljust|labelloc|labeltarget|labeltooltip|landscape|layer|layerlistsep|layers|layerselect|layersep|layout|len|levels|levelsgap|lhead|lheight|lp|ltail|lwidth|margin|maxiter|mclimit|mindist|minlen|mode|model|mosek|nodesep|nojustify|normalize|nslimit|nslimit1|ordering|orientation|outputorder|overlap|overlap_scaling|pack|packmode|pad|page|pagedir|pencolor|penwidth|peripheries|pin|pos|quadtree|quantum|rank|rankdir|ranksep|ratio|rects|regular|remincross|repulsiveforce|resolution|root|rotate|rotation|samehead|sametail|samplepoints|scale|searchsize|sep|shape|shapefile|showboxes|sides|size|skew|smoothing|sortv|splines|start|style|stylesheet|tailurl|tail_lp|tailclip|tailhref|taillabel|tailport|tailtarget|tailtooltip|target|tooltip|truecolor|vertices|viewport|voro_margin|weight|width|xlabel|xlp|z".split("|"));this.$rules={start:[{token:"comment",regex:/\/\/.*$/},{token:"comment",regex:/#.*$/},{token:"comment",merge:!0,regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/[+\-]?\d+(?:(?:\.\d*)?(?:[eE][+\-]?\d+)?)?\b/},{token:"keyword.operator",regex:/\+|=|\->/},{token:"punctuation.operator",regex:/,|;/},{token:"paren.lparen",regex:/[\[{]/},{token:"paren.rparen",regex:/[\]}]/},{token:"comment",regex:/^#!.*$/},{token:function(n){return e.hasOwnProperty(n.toLowerCase())?"keyword":t.hasOwnProperty(n.toLowerCase())?"variable":"text"},regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"}],comment:[{token:"comment",regex:".*?\\*\\/",merge:!0,next:"start"},{token:"comment",merge:!0,regex:".+"}],qqstring:[{token:"string",regex:'[^"\\\\]+',merge:!0},{token:"string",regex:"\\\\$",next:"qqstring",merge:!0},{token:"string",regex:'"|$',next:"start",merge:!0}],qstring:[{token:"string",regex:"[^'\\\\]+",merge:!0},{token:"string",regex:"\\\\$",next:"qstring",merge:!0},{token:"string",regex:"'|$",next:"start",merge:!0}]}};r.inherits(u,s),t.DotHighlightRules=u}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/dot",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/matching_brace_outdent","ace/mode/dot_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./matching_brace_outdent").MatchingBraceOutdent,o=e("./dot_highlight_rules").DotHighlightRules,u=e("./folding/cstyle").FoldMode,a=function(){this.HighlightRules=o,this.$outdent=new s,this.foldingRules=new u};r.inherits(a,i),function(){this.lineCommentStart=["//","#"],this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/dot"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-ejs.js b/dist/assets/js/vendor/ace-nc/mode-ejs.js
            new file mode 100644
            index 0000000000..5a541e2c2d
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-ejs.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},o=t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},u=t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},a=t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},f=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},l=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},c=function(){var e="abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many",t="alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield",n="true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING",r="$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self",i=this.$keywords=this.createKeywordMapper({keyword:t,"constant.language":n,"variable.language":r,"support.function":e,"invalid.deprecated":"debugger"},"identifier");this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin(?:$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},o,u,a,{token:"text",regex:"::"},{token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},s,f,l,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./ruby_highlight_rules").RubyHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./folding/coffee").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new a};r.inherits(f,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[]\s*$/),u=t.match(/^\s*(class|def|module)\s.*$/),a=t.match(/.*do(\s*|\s+\|.*\|\s*)$/),f=t.match(/^\s*(if|else)\s*/);if(o||u||a||f)r+=n}return r},this.checkOutdent=function(e,t,n){return/^\s+(end|else)$/.test(t+n)||this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){var r=t.getLine(n);if(/}/.test(r))return this.$outdent.autoOutdent(t,n);var i=this.$getIndent(r),s=t.getLine(n-1),o=this.$getIndent(s),a=t.getTabString();o.length<=i.length&&i.slice(-a.length)==a&&t.remove(new u(n,i.length-a.length,n,i.length))},this.$id="ace/mode/ruby"}.call(f.prototype),t.Mode=f}),ace.define("ace/mode/ejs",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/javascript_highlight_rules","ace/lib/oop","ace/mode/html","ace/mode/javascript","ace/mode/css","ace/mode/ruby"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=function(e,t){i.call(this),e||(e="(?:<%|<\\?|{{)"),t||(t="(?:%>|\\?>|}})");for(var n in this.$rules)this.$rules[n].unshift({token:"markup.list.meta.tag",regex:e+"(?![>}])[-=]?",push:"ejs-start"});this.embedRules(s,"ejs-"),this.$rules["ejs-start"].unshift({token:"markup.list.meta.tag",regex:"-?"+t,next:"pop"},{token:"comment",regex:"//.*?"+t,next:"pop"}),this.$rules["ejs-no_regex"].unshift({token:"markup.list.meta.tag",regex:"-?"+t,next:"pop"},{token:"comment",regex:"//.*?"+t,next:"pop"}),this.normalizeRules()};r.inherits(o,i),t.EjsHighlightRules=o;var r=e("../lib/oop"),u=e("./html").Mode,a=e("./javascript").Mode,f=e("./css").Mode,l=e("./ruby").Mode,c=function(){u.call(this),this.HighlightRules=o,this.createModeDelegates({"js-":a,"css-":f,"ejs-":a})};r.inherits(c,u),function(){this.$id="ace/mode/ejs"}.call(c.prototype),t.Mode=c})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-erlang.js b/dist/assets/js/vendor/ace-nc/mode-erlang.js
            new file mode 100644
            index 0000000000..44485fc51c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-erlang.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/erlang_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{include:"#module-directive"},{include:"#import-export-directive"},{include:"#behaviour-directive"},{include:"#record-directive"},{include:"#define-directive"},{include:"#macro-directive"},{include:"#directive"},{include:"#function"},{include:"#everything-else"}],"#atom":[{token:"punctuation.definition.symbol.begin.erlang",regex:"'",push:[{token:"punctuation.definition.symbol.end.erlang",regex:"'",next:"pop"},{token:["punctuation.definition.escape.erlang","constant.other.symbol.escape.erlang","punctuation.definition.escape.erlang","constant.other.symbol.escape.erlang","constant.other.symbol.escape.erlang"],regex:"(\\\\)(?:([bdefnrstv\\\\'\"])|(\\^)([@-_])|([0-7]{1,3}))"},{token:"invalid.illegal.atom.erlang",regex:"\\\\\\^?.?"},{defaultToken:"constant.other.symbol.quoted.single.erlang"}]},{token:"constant.other.symbol.unquoted.erlang",regex:"[a-z][a-zA-Z\\d@_]*"}],"#behaviour-directive":[{token:["meta.directive.behaviour.erlang","punctuation.section.directive.begin.erlang","meta.directive.behaviour.erlang","keyword.control.directive.behaviour.erlang","meta.directive.behaviour.erlang","punctuation.definition.parameters.begin.erlang","meta.directive.behaviour.erlang","entity.name.type.class.behaviour.definition.erlang","meta.directive.behaviour.erlang","punctuation.definition.parameters.end.erlang","meta.directive.behaviour.erlang","punctuation.section.directive.end.erlang"],regex:"^(\\s*)(-)(\\s*)(behaviour)(\\s*)(\\()(\\s*)([a-z][a-zA-Z\\d@_]*)(\\s*)(\\))(\\s*)(\\.)"}],"#binary":[{token:"punctuation.definition.binary.begin.erlang",regex:"<<",push:[{token:"punctuation.definition.binary.end.erlang",regex:">>",next:"pop"},{token:["punctuation.separator.binary.erlang","punctuation.separator.value-size.erlang"],regex:"(,)|(:)"},{include:"#internal-type-specifiers"},{include:"#everything-else"},{defaultToken:"meta.structure.binary.erlang"}]}],"#character":[{token:["punctuation.definition.character.erlang","punctuation.definition.escape.erlang","constant.character.escape.erlang","punctuation.definition.escape.erlang","constant.character.escape.erlang","constant.character.escape.erlang"],regex:"(\\$)(\\\\)(?:([bdefnrstv\\\\'\"])|(\\^)([@-_])|([0-7]{1,3}))"},{token:"invalid.illegal.character.erlang",regex:"\\$\\\\\\^?.?"},{token:["punctuation.definition.character.erlang","constant.character.erlang"],regex:"(\\$)(\\S)"},{token:"invalid.illegal.character.erlang",regex:"\\$.?"}],"#comment":[{token:"punctuation.definition.comment.erlang",regex:"%.*$",push_:[{token:"comment.line.percentage.erlang",regex:"$",next:"pop"},{defaultToken:"comment.line.percentage.erlang"}]}],"#define-directive":[{token:["meta.directive.define.erlang","punctuation.section.directive.begin.erlang","meta.directive.define.erlang","keyword.control.directive.define.erlang","meta.directive.define.erlang","punctuation.definition.parameters.begin.erlang","meta.directive.define.erlang","entity.name.function.macro.definition.erlang","meta.directive.define.erlang","punctuation.separator.parameters.erlang"],regex:"^(\\s*)(-)(\\s*)(define)(\\s*)(\\()(\\s*)([a-zA-Z\\d@_]+)(\\s*)(,)",push:[{token:["punctuation.definition.parameters.end.erlang","meta.directive.define.erlang","punctuation.section.directive.end.erlang"],regex:"(\\))(\\s*)(\\.)",next:"pop"},{include:"#everything-else"},{defaultToken:"meta.directive.define.erlang"}]},{token:"meta.directive.define.erlang",regex:"(?=^\\s*-\\s*define\\s*\\(\\s*[a-zA-Z\\d@_]+\\s*\\()",push:[{token:["punctuation.definition.parameters.end.erlang","meta.directive.define.erlang","punctuation.section.directive.end.erlang"],regex:"(\\))(\\s*)(\\.)",next:"pop"},{token:["text","punctuation.section.directive.begin.erlang","text","keyword.control.directive.define.erlang","text","punctuation.definition.parameters.begin.erlang","text","entity.name.function.macro.definition.erlang","text","punctuation.definition.parameters.begin.erlang"],regex:"^(\\s*)(-)(\\s*)(define)(\\s*)(\\()(\\s*)([a-zA-Z\\d@_]+)(\\s*)(\\()",push:[{token:["punctuation.definition.parameters.end.erlang","text","punctuation.separator.parameters.erlang"],regex:"(\\))(\\s*)(,)",next:"pop"},{token:"punctuation.separator.parameters.erlang",regex:","},{include:"#everything-else"}]},{token:"punctuation.separator.define.erlang",regex:"\\|\\||\\||:|;|,|\\.|->"},{include:"#everything-else"},{defaultToken:"meta.directive.define.erlang"}]}],"#directive":[{token:["meta.directive.erlang","punctuation.section.directive.begin.erlang","meta.directive.erlang","keyword.control.directive.erlang","meta.directive.erlang","punctuation.definition.parameters.begin.erlang"],regex:"^(\\s*)(-)(\\s*)([a-z][a-zA-Z\\d@_]*)(\\s*)(\\(?)",push:[{token:["punctuation.definition.parameters.end.erlang","meta.directive.erlang","punctuation.section.directive.end.erlang"],regex:"(\\)?)(\\s*)(\\.)",next:"pop"},{include:"#everything-else"},{defaultToken:"meta.directive.erlang"}]},{token:["meta.directive.erlang","punctuation.section.directive.begin.erlang","meta.directive.erlang","keyword.control.directive.erlang","meta.directive.erlang","punctuation.section.directive.end.erlang"],regex:"^(\\s*)(-)(\\s*)([a-z][a-zA-Z\\d@_]*)(\\s*)(\\.)"}],"#everything-else":[{include:"#comment"},{include:"#record-usage"},{include:"#macro-usage"},{include:"#expression"},{include:"#keyword"},{include:"#textual-operator"},{include:"#function-call"},{include:"#tuple"},{include:"#list"},{include:"#binary"},{include:"#parenthesized-expression"},{include:"#character"},{include:"#number"},{include:"#atom"},{include:"#string"},{include:"#symbolic-operator"},{include:"#variable"}],"#expression":[{token:"keyword.control.if.erlang",regex:"\\bif\\b",push:[{token:"keyword.control.end.erlang",regex:"\\bend\\b",next:"pop"},{include:"#internal-expression-punctuation"},{include:"#everything-else"},{defaultToken:"meta.expression.if.erlang"}]},{token:"keyword.control.case.erlang",regex:"\\bcase\\b",push:[{token:"keyword.control.end.erlang",regex:"\\bend\\b",next:"pop"},{include:"#internal-expression-punctuation"},{include:"#everything-else"},{defaultToken:"meta.expression.case.erlang"}]},{token:"keyword.control.receive.erlang",regex:"\\breceive\\b",push:[{token:"keyword.control.end.erlang",regex:"\\bend\\b",next:"pop"},{include:"#internal-expression-punctuation"},{include:"#everything-else"},{defaultToken:"meta.expression.receive.erlang"}]},{token:["keyword.control.fun.erlang","text","entity.name.type.class.module.erlang","text","punctuation.separator.module-function.erlang","text","entity.name.function.erlang","text","punctuation.separator.function-arity.erlang"],regex:"\\b(fun)(\\s*)(?:([a-z][a-zA-Z\\d@_]*)(\\s*)(:)(\\s*))?([a-z][a-zA-Z\\d@_]*)(\\s*)(/)"},{token:"keyword.control.fun.erlang",regex:"\\bfun\\b",push:[{token:"keyword.control.end.erlang",regex:"\\bend\\b",next:"pop"},{token:"text",regex:"(?=\\()",push:[{token:"punctuation.separator.clauses.erlang",regex:";|(?=\\bend\\b)",next:"pop"},{include:"#internal-function-parts"}]},{include:"#everything-else"},{defaultToken:"meta.expression.fun.erlang"}]},{token:"keyword.control.try.erlang",regex:"\\btry\\b",push:[{token:"keyword.control.end.erlang",regex:"\\bend\\b",next:"pop"},{include:"#internal-expression-punctuation"},{include:"#everything-else"},{defaultToken:"meta.expression.try.erlang"}]},{token:"keyword.control.begin.erlang",regex:"\\bbegin\\b",push:[{token:"keyword.control.end.erlang",regex:"\\bend\\b",next:"pop"},{include:"#internal-expression-punctuation"},{include:"#everything-else"},{defaultToken:"meta.expression.begin.erlang"}]},{token:"keyword.control.query.erlang",regex:"\\bquery\\b",push:[{token:"keyword.control.end.erlang",regex:"\\bend\\b",next:"pop"},{include:"#everything-else"},{defaultToken:"meta.expression.query.erlang"}]}],"#function":[{token:["meta.function.erlang","entity.name.function.definition.erlang","meta.function.erlang"],regex:"^(\\s*)([a-z][a-zA-Z\\d@_]*|'[^']*')(\\s*)(?=\\()",push:[{token:"punctuation.terminator.function.erlang",regex:"\\.",next:"pop"},{token:["text","entity.name.function.erlang","text"],regex:"^(\\s*)([a-z][a-zA-Z\\d@_]*|'[^']*')(\\s*)(?=\\()"},{token:"text",regex:"(?=\\()",push:[{token:"punctuation.separator.clauses.erlang",regex:";|(?=\\.)",next:"pop"},{include:"#parenthesized-expression"},{include:"#internal-function-parts"}]},{include:"#everything-else"},{defaultToken:"meta.function.erlang"}]}],"#function-call":[{token:"meta.function-call.erlang",regex:"(?=(?:[a-z][a-zA-Z\\d@_]*|'[^']*')\\s*(?:\\(|:\\s*(?:[a-z][a-zA-Z\\d@_]*|'[^']*')\\s*\\())",push:[{token:"punctuation.definition.parameters.end.erlang",regex:"\\)",next:"pop"},{token:["entity.name.type.class.module.erlang","text","punctuation.separator.module-function.erlang","text","entity.name.function.guard.erlang","text","punctuation.definition.parameters.begin.erlang"],regex:"(?:(erlang)(\\s*)(:)(\\s*))?(is_atom|is_binary|is_constant|is_float|is_function|is_integer|is_list|is_number|is_pid|is_port|is_reference|is_tuple|is_record|abs|element|hd|length|node|round|self|size|tl|trunc)(\\s*)(\\()",push:[{token:"text",regex:"(?=\\))",next:"pop"},{token:"punctuation.separator.parameters.erlang",regex:","},{include:"#everything-else"}]},{token:["entity.name.type.class.module.erlang","text","punctuation.separator.module-function.erlang","text","entity.name.function.erlang","text","punctuation.definition.parameters.begin.erlang"],regex:"(?:([a-z][a-zA-Z\\d@_]*|'[^']*')(\\s*)(:)(\\s*))?([a-z][a-zA-Z\\d@_]*|'[^']*')(\\s*)(\\()",push:[{token:"text",regex:"(?=\\))",next:"pop"},{token:"punctuation.separator.parameters.erlang",regex:","},{include:"#everything-else"}]},{defaultToken:"meta.function-call.erlang"}]}],"#import-export-directive":[{token:["meta.directive.import.erlang","punctuation.section.directive.begin.erlang","meta.directive.import.erlang","keyword.control.directive.import.erlang","meta.directive.import.erlang","punctuation.definition.parameters.begin.erlang","meta.directive.import.erlang","entity.name.type.class.module.erlang","meta.directive.import.erlang","punctuation.separator.parameters.erlang"],regex:"^(\\s*)(-)(\\s*)(import)(\\s*)(\\()(\\s*)([a-z][a-zA-Z\\d@_]*|'[^']*')(\\s*)(,)",push:[{token:["punctuation.definition.parameters.end.erlang","meta.directive.import.erlang","punctuation.section.directive.end.erlang"],regex:"(\\))(\\s*)(\\.)",next:"pop"},{include:"#internal-function-list"},{defaultToken:"meta.directive.import.erlang"}]},{token:["meta.directive.export.erlang","punctuation.section.directive.begin.erlang","meta.directive.export.erlang","keyword.control.directive.export.erlang","meta.directive.export.erlang","punctuation.definition.parameters.begin.erlang"],regex:"^(\\s*)(-)(\\s*)(export)(\\s*)(\\()",push:[{token:["punctuation.definition.parameters.end.erlang","meta.directive.export.erlang","punctuation.section.directive.end.erlang"],regex:"(\\))(\\s*)(\\.)",next:"pop"},{include:"#internal-function-list"},{defaultToken:"meta.directive.export.erlang"}]}],"#internal-expression-punctuation":[{token:["punctuation.separator.clause-head-body.erlang","punctuation.separator.clauses.erlang","punctuation.separator.expressions.erlang"],regex:"(->)|(;)|(,)"}],"#internal-function-list":[{token:"punctuation.definition.list.begin.erlang",regex:"\\[",push:[{token:"punctuation.definition.list.end.erlang",regex:"\\]",next:"pop"},{token:["entity.name.function.erlang","text","punctuation.separator.function-arity.erlang"],regex:"([a-z][a-zA-Z\\d@_]*|'[^']*')(\\s*)(/)",push:[{token:"punctuation.separator.list.erlang",regex:",|(?=\\])",next:"pop"},{include:"#everything-else"}]},{include:"#everything-else"},{defaultToken:"meta.structure.list.function.erlang"}]}],"#internal-function-parts":[{token:"text",regex:"(?=\\()",push:[{token:"punctuation.separator.clause-head-body.erlang",regex:"->",next:"pop"},{token:"punctuation.definition.parameters.begin.erlang",regex:"\\(",push:[{token:"punctuation.definition.parameters.end.erlang",regex:"\\)",next:"pop"},{token:"punctuation.separator.parameters.erlang",regex:","},{include:"#everything-else"}]},{token:"punctuation.separator.guards.erlang",regex:",|;"},{include:"#everything-else"}]},{token:"punctuation.separator.expressions.erlang",regex:","},{include:"#everything-else"}],"#internal-record-body":[{token:"punctuation.definition.class.record.begin.erlang",regex:"\\{",push:[{token:"meta.structure.record.erlang",regex:"(?=\\})",next:"pop"},{token:["variable.other.field.erlang","variable.language.omitted.field.erlang","text","keyword.operator.assignment.erlang"],regex:"(?:([a-z][a-zA-Z\\d@_]*|'[^']*')|(_))(\\s*)(=|::)",push:[{token:"punctuation.separator.class.record.erlang",regex:",|(?=\\})",next:"pop"},{include:"#everything-else"}]},{token:["variable.other.field.erlang","text","punctuation.separator.class.record.erlang"],regex:"([a-z][a-zA-Z\\d@_]*|'[^']*')(\\s*)((?:,)?)"},{include:"#everything-else"},{defaultToken:"meta.structure.record.erlang"}]}],"#internal-type-specifiers":[{token:"punctuation.separator.value-type.erlang",regex:"/",push:[{token:"text",regex:"(?=,|:|>>)",next:"pop"},{token:["storage.type.erlang","storage.modifier.signedness.erlang","storage.modifier.endianness.erlang","storage.modifier.unit.erlang","punctuation.separator.type-specifiers.erlang"],regex:"(integer|float|binary|bytes|bitstring|bits)|(signed|unsigned)|(big|little|native)|(unit)|(-)"}]}],"#keyword":[{token:"keyword.control.erlang",regex:"\\b(?:after|begin|case|catch|cond|end|fun|if|let|of|query|try|receive|when)\\b"}],"#list":[{token:"punctuation.definition.list.begin.erlang",regex:"\\[",push:[{token:"punctuation.definition.list.end.erlang",regex:"\\]",next:"pop"},{token:"punctuation.separator.list.erlang",regex:"\\||\\|\\||,"},{include:"#everything-else"},{defaultToken:"meta.structure.list.erlang"}]}],"#macro-directive":[{token:["meta.directive.ifdef.erlang","punctuation.section.directive.begin.erlang","meta.directive.ifdef.erlang","keyword.control.directive.ifdef.erlang","meta.directive.ifdef.erlang","punctuation.definition.parameters.begin.erlang","meta.directive.ifdef.erlang","entity.name.function.macro.erlang","meta.directive.ifdef.erlang","punctuation.definition.parameters.end.erlang","meta.directive.ifdef.erlang","punctuation.section.directive.end.erlang"],regex:"^(\\s*)(-)(\\s*)(ifdef)(\\s*)(\\()(\\s*)([a-zA-z\\d@_]+)(\\s*)(\\))(\\s*)(\\.)"},{token:["meta.directive.ifndef.erlang","punctuation.section.directive.begin.erlang","meta.directive.ifndef.erlang","keyword.control.directive.ifndef.erlang","meta.directive.ifndef.erlang","punctuation.definition.parameters.begin.erlang","meta.directive.ifndef.erlang","entity.name.function.macro.erlang","meta.directive.ifndef.erlang","punctuation.definition.parameters.end.erlang","meta.directive.ifndef.erlang","punctuation.section.directive.end.erlang"],regex:"^(\\s*)(-)(\\s*)(ifndef)(\\s*)(\\()(\\s*)([a-zA-z\\d@_]+)(\\s*)(\\))(\\s*)(\\.)"},{token:["meta.directive.undef.erlang","punctuation.section.directive.begin.erlang","meta.directive.undef.erlang","keyword.control.directive.undef.erlang","meta.directive.undef.erlang","punctuation.definition.parameters.begin.erlang","meta.directive.undef.erlang","entity.name.function.macro.erlang","meta.directive.undef.erlang","punctuation.definition.parameters.end.erlang","meta.directive.undef.erlang","punctuation.section.directive.end.erlang"],regex:"^(\\s*)(-)(\\s*)(undef)(\\s*)(\\()(\\s*)([a-zA-z\\d@_]+)(\\s*)(\\))(\\s*)(\\.)"}],"#macro-usage":[{token:["keyword.operator.macro.erlang","meta.macro-usage.erlang","entity.name.function.macro.erlang"],regex:"(\\?\\??)(\\s*)([a-zA-Z\\d@_]+)"}],"#module-directive":[{token:["meta.directive.module.erlang","punctuation.section.directive.begin.erlang","meta.directive.module.erlang","keyword.control.directive.module.erlang","meta.directive.module.erlang","punctuation.definition.parameters.begin.erlang","meta.directive.module.erlang","entity.name.type.class.module.definition.erlang","meta.directive.module.erlang","punctuation.definition.parameters.end.erlang","meta.directive.module.erlang","punctuation.section.directive.end.erlang"],regex:"^(\\s*)(-)(\\s*)(module)(\\s*)(\\()(\\s*)([a-z][a-zA-Z\\d@_]*)(\\s*)(\\))(\\s*)(\\.)"}],"#number":[{token:"text",regex:"(?=\\d)",push:[{token:"text",regex:"(?!\\d)",next:"pop"},{token:["constant.numeric.float.erlang","punctuation.separator.integer-float.erlang","constant.numeric.float.erlang","punctuation.separator.float-exponent.erlang"],regex:"(\\d+)(\\.)(\\d+)((?:[eE][\\+\\-]?\\d+)?)"},{token:["constant.numeric.integer.binary.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.binary.erlang"],regex:"(2)(#)([0-1]+)"},{token:["constant.numeric.integer.base-3.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-3.erlang"],regex:"(3)(#)([0-2]+)"},{token:["constant.numeric.integer.base-4.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-4.erlang"],regex:"(4)(#)([0-3]+)"},{token:["constant.numeric.integer.base-5.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-5.erlang"],regex:"(5)(#)([0-4]+)"},{token:["constant.numeric.integer.base-6.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-6.erlang"],regex:"(6)(#)([0-5]+)"},{token:["constant.numeric.integer.base-7.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-7.erlang"],regex:"(7)(#)([0-6]+)"},{token:["constant.numeric.integer.octal.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.octal.erlang"],regex:"(8)(#)([0-7]+)"},{token:["constant.numeric.integer.base-9.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-9.erlang"],regex:"(9)(#)([0-8]+)"},{token:["constant.numeric.integer.decimal.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.decimal.erlang"],regex:"(10)(#)(\\d+)"},{token:["constant.numeric.integer.base-11.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-11.erlang"],regex:"(11)(#)([\\daA]+)"},{token:["constant.numeric.integer.base-12.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-12.erlang"],regex:"(12)(#)([\\da-bA-B]+)"},{token:["constant.numeric.integer.base-13.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-13.erlang"],regex:"(13)(#)([\\da-cA-C]+)"},{token:["constant.numeric.integer.base-14.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-14.erlang"],regex:"(14)(#)([\\da-dA-D]+)"},{token:["constant.numeric.integer.base-15.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-15.erlang"],regex:"(15)(#)([\\da-eA-E]+)"},{token:["constant.numeric.integer.hexadecimal.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.hexadecimal.erlang"],regex:"(16)(#)([\\da-fA-F]+)"},{token:["constant.numeric.integer.base-17.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-17.erlang"],regex:"(17)(#)([\\da-gA-G]+)"},{token:["constant.numeric.integer.base-18.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-18.erlang"],regex:"(18)(#)([\\da-hA-H]+)"},{token:["constant.numeric.integer.base-19.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-19.erlang"],regex:"(19)(#)([\\da-iA-I]+)"},{token:["constant.numeric.integer.base-20.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-20.erlang"],regex:"(20)(#)([\\da-jA-J]+)"},{token:["constant.numeric.integer.base-21.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-21.erlang"],regex:"(21)(#)([\\da-kA-K]+)"},{token:["constant.numeric.integer.base-22.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-22.erlang"],regex:"(22)(#)([\\da-lA-L]+)"},{token:["constant.numeric.integer.base-23.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-23.erlang"],regex:"(23)(#)([\\da-mA-M]+)"},{token:["constant.numeric.integer.base-24.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-24.erlang"],regex:"(24)(#)([\\da-nA-N]+)"},{token:["constant.numeric.integer.base-25.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-25.erlang"],regex:"(25)(#)([\\da-oA-O]+)"},{token:["constant.numeric.integer.base-26.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-26.erlang"],regex:"(26)(#)([\\da-pA-P]+)"},{token:["constant.numeric.integer.base-27.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-27.erlang"],regex:"(27)(#)([\\da-qA-Q]+)"},{token:["constant.numeric.integer.base-28.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-28.erlang"],regex:"(28)(#)([\\da-rA-R]+)"},{token:["constant.numeric.integer.base-29.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-29.erlang"],regex:"(29)(#)([\\da-sA-S]+)"},{token:["constant.numeric.integer.base-30.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-30.erlang"],regex:"(30)(#)([\\da-tA-T]+)"},{token:["constant.numeric.integer.base-31.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-31.erlang"],regex:"(31)(#)([\\da-uA-U]+)"},{token:["constant.numeric.integer.base-32.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-32.erlang"],regex:"(32)(#)([\\da-vA-V]+)"},{token:["constant.numeric.integer.base-33.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-33.erlang"],regex:"(33)(#)([\\da-wA-W]+)"},{token:["constant.numeric.integer.base-34.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-34.erlang"],regex:"(34)(#)([\\da-xA-X]+)"},{token:["constant.numeric.integer.base-35.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-35.erlang"],regex:"(35)(#)([\\da-yA-Y]+)"},{token:["constant.numeric.integer.base-36.erlang","punctuation.separator.base-integer.erlang","constant.numeric.integer.base-36.erlang"],regex:"(36)(#)([\\da-zA-Z]+)"},{token:"invalid.illegal.integer.erlang",regex:"\\d+#[\\da-zA-Z]+"},{token:"constant.numeric.integer.decimal.erlang",regex:"\\d+"}]}],"#parenthesized-expression":[{token:"punctuation.section.expression.begin.erlang",regex:"\\(",push:[{token:"punctuation.section.expression.end.erlang",regex:"\\)",next:"pop"},{include:"#everything-else"},{defaultToken:"meta.expression.parenthesized"}]}],"#record-directive":[{token:["meta.directive.record.erlang","punctuation.section.directive.begin.erlang","meta.directive.record.erlang","keyword.control.directive.import.erlang","meta.directive.record.erlang","punctuation.definition.parameters.begin.erlang","meta.directive.record.erlang","entity.name.type.class.record.definition.erlang","meta.directive.record.erlang","punctuation.separator.parameters.erlang"],regex:"^(\\s*)(-)(\\s*)(record)(\\s*)(\\()(\\s*)([a-z][a-zA-Z\\d@_]*|'[^']*')(\\s*)(,)",push:[{token:["punctuation.definition.class.record.end.erlang","meta.directive.record.erlang","punctuation.definition.parameters.end.erlang","meta.directive.record.erlang","punctuation.section.directive.end.erlang"],regex:"(\\})(\\s*)(\\))(\\s*)(\\.)",next:"pop"},{include:"#internal-record-body"},{defaultToken:"meta.directive.record.erlang"}]}],"#record-usage":[{token:["keyword.operator.record.erlang","meta.record-usage.erlang","entity.name.type.class.record.erlang","meta.record-usage.erlang","punctuation.separator.record-field.erlang","meta.record-usage.erlang","variable.other.field.erlang"],regex:"(#)(\\s*)([a-z][a-zA-Z\\d@_]*|'[^']*')(\\s*)(\\.)(\\s*)([a-z][a-zA-Z\\d@_]*|'[^']*')"},{token:["keyword.operator.record.erlang","meta.record-usage.erlang","entity.name.type.class.record.erlang"],regex:"(#)(\\s*)([a-z][a-zA-Z\\d@_]*|'[^']*')",push:[{token:"punctuation.definition.class.record.end.erlang",regex:"\\}",next:"pop"},{include:"#internal-record-body"},{defaultToken:"meta.record-usage.erlang"}]}],"#string":[{token:"punctuation.definition.string.begin.erlang",regex:'"',push:[{token:"punctuation.definition.string.end.erlang",regex:'"',next:"pop"},{token:["punctuation.definition.escape.erlang","constant.character.escape.erlang","punctuation.definition.escape.erlang","constant.character.escape.erlang","constant.character.escape.erlang"],regex:"(\\\\)(?:([bdefnrstv\\\\'\"])|(\\^)([@-_])|([0-7]{1,3}))"},{token:"invalid.illegal.string.erlang",regex:"\\\\\\^?.?"},{token:["punctuation.definition.placeholder.erlang","punctuation.separator.placeholder-parts.erlang","constant.other.placeholder.erlang","punctuation.separator.placeholder-parts.erlang","punctuation.separator.placeholder-parts.erlang","constant.other.placeholder.erlang","punctuation.separator.placeholder-parts.erlang","punctuation.separator.placeholder-parts.erlang","punctuation.separator.placeholder-parts.erlang","constant.other.placeholder.erlang","constant.other.placeholder.erlang"],regex:"(~)(?:((?:\\-)?)(\\d+)|(\\*))?(?:(\\.)(?:(\\d+)|(\\*)))?(?:(\\.)(?:(\\*)|(.)))?([~cfegswpWPBX#bx\\+ni])"},{token:["punctuation.definition.placeholder.erlang","punctuation.separator.placeholder-parts.erlang","constant.other.placeholder.erlang","constant.other.placeholder.erlang"],regex:"(~)((?:\\*)?)((?:\\d+)?)([~du\\-#fsacl])"},{token:"invalid.illegal.string.erlang",regex:"~.?"},{defaultToken:"string.quoted.double.erlang"}]}],"#symbolic-operator":[{token:"keyword.operator.symbolic.erlang",regex:"\\+\\+|\\+|--|-|\\*|/=|/|=/=|=:=|==|=<|=|<-|<|>=|>|!|::"}],"#textual-operator":[{token:"keyword.operator.textual.erlang",regex:"\\b(?:andalso|band|and|bxor|xor|bor|orelse|or|bnot|not|bsl|bsr|div|rem)\\b"}],"#tuple":[{token:"punctuation.definition.tuple.begin.erlang",regex:"\\{",push:[{token:"punctuation.definition.tuple.end.erlang",regex:"\\}",next:"pop"},{token:"punctuation.separator.tuple.erlang",regex:","},{include:"#everything-else"},{defaultToken:"meta.structure.tuple.erlang"}]}],"#variable":[{token:["variable.other.erlang","variable.language.omitted.erlang"],regex:"(_[a-zA-Z\\d@_]+|[A-Z][a-zA-Z\\d@_]*)|(_)"}]},this.normalizeRules()};s.metaData={comment:"The recognition of function definitions and compiler directives (such as module, record and macro definitions) requires that each of the aforementioned constructs must be the first string inside a line (except for whitespace).  Also, the function/module/record/macro names must be given unquoted.  -- desp",fileTypes:["erl","hrl"],keyEquivalent:"^~E",name:"Erlang",scopeName:"source.erlang"},r.inherits(s,i),t.ErlangHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/erlang",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/erlang_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./erlang_highlight_rules").ErlangHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="%",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/erlang"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-forth.js b/dist/assets/js/vendor/ace-nc/mode-forth.js
            new file mode 100644
            index 0000000000..0ee11918e7
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-forth.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/forth_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{include:"#forth"}],"#comment":[{token:"comment.line.double-dash.forth",regex:"(?:^|\\s)--\\s.*$",comment:"line comments for iForth"},{token:"comment.line.backslash.forth",regex:"(?:^|\\s)\\\\[\\s\\S]*$",comment:"ANSI line comment"},{token:"comment.line.backslash-g.forth",regex:"(?:^|\\s)\\\\[Gg] .*$",comment:"gForth line comment"},{token:"comment.block.forth",regex:"(?:^|\\s)\\(\\*(?=\\s|$)",push:[{token:"comment.block.forth",regex:"(?:^|\\s)\\*\\)(?=\\s|$)",next:"pop"},{defaultToken:"comment.block.forth"}],comment:"multiline comments for iForth"},{token:"comment.block.documentation.forth",regex:"\\bDOC\\b",caseInsensitive:!0,push:[{token:"comment.block.documentation.forth",regex:"\\bENDDOC\\b",caseInsensitive:!0,next:"pop"},{defaultToken:"comment.block.documentation.forth"}],comment:"documentation comments for iForth"},{token:"comment.line.parentheses.forth",regex:"(?:^|\\s)\\.?\\( [^)]*\\)",comment:"ANSI line comment"}],"#constant":[{token:"constant.language.forth",regex:"(?:^|\\s)(?:TRUE|FALSE|BL|PI|CELL|C/L|R/O|W/O|R/W)(?=\\s|$)",caseInsensitive:!0},{token:"constant.numeric.forth",regex:"(?:^|\\s)[$#%]?[-+]?[0-9]+(?:\\.[0-9]*e-?[0-9]+|\\.?[0-9a-fA-F]*)(?=\\s|$)"},{token:"constant.character.forth",regex:"(?:^|\\s)(?:[&^]\\S|(?:\"|')\\S(?:\"|'))(?=\\s|$)"}],"#forth":[{include:"#constant"},{include:"#comment"},{include:"#string"},{include:"#word"},{include:"#variable"},{include:"#storage"},{include:"#word-def"}],"#storage":[{token:"storage.type.forth",regex:"(?:^|\\s)(?:2CONSTANT|2VARIABLE|ALIAS|CONSTANT|CREATE-INTERPRET/COMPILE[:]?|CREATE|DEFER|FCONSTANT|FIELD|FVARIABLE|USER|VALUE|VARIABLE|VOCABULARY)(?=\\s|$)",caseInsensitive:!0}],"#string":[{token:"string.quoted.double.forth",regex:'(ABORT" |BREAK" |\\." |C" |0"|S\\\\?" )([^"]+")',caseInsensitive:!0},{token:"string.unquoted.forth",regex:"(?:INCLUDE|NEEDS|REQUIRE|USE)[ ]\\S+(?=\\s|$)",caseInsensitive:!0}],"#variable":[{token:"variable.language.forth",regex:"\\b(?:I|J)\\b",caseInsensitive:!0}],"#word":[{token:"keyword.control.immediate.forth",regex:"(?:^|\\s)\\[(?:\\?DO|\\+LOOP|AGAIN|BEGIN|DEFINED|DO|ELSE|ENDIF|FOR|IF|IFDEF|IFUNDEF|LOOP|NEXT|REPEAT|THEN|UNTIL|WHILE)\\](?=\\s|$)",caseInsensitive:!0},{token:"keyword.other.immediate.forth",regex:"(?:^|\\s)(?:COMPILE-ONLY|IMMEDIATE|IS|RESTRICT|TO|WHAT'S|])(?=\\s|$)",caseInsensitive:!0},{token:"keyword.control.compile-only.forth",regex:'(?:^|\\s)(?:-DO|\\-LOOP|\\?DO|\\?LEAVE|\\+DO|\\+LOOP|ABORT\\"|AGAIN|AHEAD|BEGIN|CASE|DO|ELSE|ENDCASE|ENDIF|ENDOF|ENDTRY\\-IFERROR|ENDTRY|FOR|IF|IFERROR|LEAVE|LOOP|NEXT|RECOVER|REPEAT|RESTORE|THEN|TRY|U\\-DO|U\\+DO|UNTIL|WHILE)(?=\\s|$)',caseInsensitive:!0},{token:"keyword.other.compile-only.forth",regex:"(?:^|\\s)(?:\\?DUP-0=-IF|\\?DUP-IF|\\)|\\[|\\['\\]|\\[CHAR\\]|\\[COMPILE\\]|\\[IS\\]|\\[TO\\]|<COMPILATION|<INTERPRETATION|ASSERT\\(|ASSERT0\\(|ASSERT1\\(|ASSERT2\\(|ASSERT3\\(|COMPILATION>|DEFERS|DOES>|INTERPRETATION>|OF|POSTPONE)(?=\\s|$)",caseInsensitive:!0},{token:"keyword.other.non-immediate.forth",regex:"(?:^|\\s)(?:'|<IS>|<TO>|CHAR|END-STRUCT|INCLUDE[D]?|LOAD|NEEDS|REQUIRE[D]?|REVISION|SEE|STRUCT|THRU|USE)(?=\\s|$)",caseInsensitive:!0},{token:"keyword.other.warning.forth",regex:'(?:^|\\s)(?:~~|BREAK:|BREAK"|DBG)(?=\\s|$)',caseInsensitive:!0}],"#word-def":[{token:["keyword.other.compile-only.forth","keyword.other.compile-only.forth","meta.block.forth","entity.name.function.forth"],regex:"(:NONAME)|(^:|\\s:)(\\s)(\\S+)(?=\\s|$)",caseInsensitive:!0,push:[{token:"keyword.other.compile-only.forth",regex:";(?:CODE)?",caseInsensitive:!0,next:"pop"},{include:"#constant"},{include:"#comment"},{include:"#string"},{include:"#word"},{include:"#variable"},{include:"#storage"},{defaultToken:"meta.block.forth"}]}]},this.normalizeRules()};s.metaData={fileTypes:["frt","fs","ldr"],foldingStartMarker:"/\\*\\*|\\{\\s*$",foldingStopMarker:"\\*\\*/|^\\s*\\}",keyEquivalent:"^~F",name:"Forth",scopeName:"source.forth"},r.inherits(s,i),t.ForthHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/forth",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/forth_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./forth_highlight_rules").ForthHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="(?<=^|\\s)\\.?\\( [^)]*\\)",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/forth"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-ftl.js b/dist/assets/js/vendor/ace-nc/mode-ftl.js
            new file mode 100644
            index 0000000000..e932f4af4d
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-ftl.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/ftl_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="\\?|substring|cap_first|uncap_first|capitalize|chop_linebreak|date|time|datetime|ends_with|html|groups|index_of|j_string|js_string|json_string|last_index_of|length|lower_case|left_pad|right_pad|contains|matches|number|replace|rtf|url|split|starts_with|string|trim|upper_case|word_list|xhtml|xml",t="c|round|floor|ceiling",n="iso_[a-z_]+",r="first|last|seq_contains|seq_index_of|seq_last_index_of|reverse|size|sort|sort_by|chunk",i="keys|values",s="children|parent|root|ancestors|node_name|node_type|node_namespace",o="byte|double|float|int|long|short|number_to_date|number_to_time|number_to_datetime|eval|has_content|interpret|is_[a-z_]+|namespacenew",u=e+t+n+r+i+s+o,a="default|exists|if_exists|web_safe",f="data_model|error|globals|lang|locale|locals|main|namespace|node|current_node|now|output_encoding|template_name|url_escaping_charset|vars|version",l="gt|gte|lt|lte|as|in|using",c="true|false",h="encoding|parse|locale|number_format|date_format|time_format|datetime_format|time_zone|url_escaping_charset|classic_compatible|strip_whitespace|strip_text|strict_syntax|ns_prefixes|attributes";this.$rules={start:[{token:"constant.character.entity",regex:/&[^;]+;/},{token:"support.function",regex:"\\?("+u+")"},{token:"support.function.deprecated",regex:"\\?("+a+")"},{token:"language.variable",regex:"\\.(?:"+f+")"},{token:"constant.language",regex:"\\b("+c+")\\b"},{token:"keyword.operator",regex:"\\b(?:"+l+")\\b"},{token:"entity.other.attribute-name",regex:h},{token:"string",regex:/['"]/,next:"qstring"},{token:function(e){return e.match("^[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?$")?"constant.numeric":"variable"},regex:/[\w.+\-]+/},{token:"keyword.operator",regex:"!|\\.|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^="},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],qstring:[{token:"constant.character.escape",regex:'\\\\[nrtvef\\\\"$]'},{token:"string",regex:/['"]/,next:"start"},{defaultToken:"string"}]}};r.inherits(o,s);var u=function(){i.call(this);var e="assign|attempt|break|case|compress|default|elseif|else|escape|fallback|function|flush|ftl|global|if|import|include|list|local|lt|macro|nested|noescape|noparse|nt|recover|recurse|return|rt|setting|stop|switch|t|visit",t=[{token:"comment",regex:"<#--",next:"ftl-dcomment"},{token:"string.interpolated",regex:"\\${",push:"ftl-start"},{token:"keyword.function",regex:"</?#("+e+")",push:"ftl-start"},{token:"keyword.other",regex:"</?@[a-zA-Z\\.]+",push:"ftl-start"}],n=[{token:"keyword",regex:"/?>",next:"pop"},{token:"string.interpolated",regex:"}",next:"pop"}];for(var r in this.$rules)this.$rules[r].unshift.apply(this.$rules[r],t);this.embedRules(o,"ftl-",n,["start"]),this.addRules({"ftl-dcomment":[{token:"comment",regex:".*?-->",next:"pop"},{token:"comment",regex:".+"}]}),this.normalizeRules()};r.inherits(u,i),t.FtlHighlightRules=u}),ace.define("ace/mode/ftl",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ftl_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./ftl_highlight_rules").FtlHighlightRules,o=function(){this.HighlightRules=s};r.inherits(o,i),function(){this.$id="ace/mode/ftl"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-gherkin.js b/dist/assets/js/vendor/ace-nc/mode-gherkin.js
            new file mode 100644
            index 0000000000..90a56f56ba
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-gherkin.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/gherkin_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s="\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})",o=function(){this.$rules={start:[{token:"constant.numeric",regex:"(?:(?:[1-9]\\d*)|(?:0))"},{token:"comment",regex:"#.*$"},{token:"keyword",regex:"Feature:|Background:|Scenario:|Scenario Outline:|Examples:|Given|When|Then|And|But|\\*"},{token:"string",regex:'"{3}',next:"qqstring3"},{token:"string",regex:'"',next:"qqstring"},{token:"comment",regex:"@[A-Za-z0-9]+",next:"start"},{token:"comment",regex:"<.+>"},{token:"comment",regex:"\\| ",next:"table-item"},{token:"comment",regex:"\\|$",next:"start"}],qqstring3:[{token:"constant.language.escape",regex:s},{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:s},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],"table-item":[{token:"string",regex:"[A-Za-z0-9 ]*",next:"start"}]}};r.inherits(o,i),t.GherkinHighlightRules=o}),ace.define("ace/mode/gherkin",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/gherkin_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("./gherkin_highlight_rules").GherkinHighlightRules,o=function(){this.HighlightRules=s};r.inherits(o,i),function(){this.lineCommentStart="#",this.$id="ace/mode/gherkin",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i="  ",s=this.getTokenizer().getLineTokens(t,e),o=s.tokens;return console.log(e),t.match("[ ]*\\|")&&(r+="| "),o.length&&o[o.length-1].type=="comment"?r:(e=="start"&&(t.match("Scenario:|Feature:|Scenario Outline:|Background:")?r+=i:t.match("(Given|Then).+(:)$|Examples:")?r+=i:t.match("\\*.+")&&(r+="* ")),r)}}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-gitignore.js b/dist/assets/js/vendor/ace-nc/mode-gitignore.js
            new file mode 100644
            index 0000000000..25327ac0aa
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-gitignore.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/gitignore_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment",regex:/^\s*#.*$/},{token:"keyword",regex:/^\s*!.*$/}]},this.normalizeRules()};s.metaData={fileTypes:["gitignore"],name:"Gitignore"},r.inherits(s,i),t.GitignoreHighlightRules=s}),ace.define("ace/mode/gitignore",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/gitignore_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./gitignore_highlight_rules").GitignoreHighlightRules,o=function(){this.HighlightRules=s};r.inherits(o,i),function(){this.$id="ace/mode/gitignore"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-glsl.js b/dist/assets/js/vendor/ace-nc/mode-glsl.js
            new file mode 100644
            index 0000000000..087c59d73e
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-glsl.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/c_cpp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=t.cFunctions="\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\b",u=function(){var e="break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while|catch|operator|try|throw|using",t="asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|class|wchar_t|template",n="const|extern|register|restrict|static|volatile|inline|private:|protected:|public:|friend|explicit|virtual|export|mutable|typename",r="and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eqconst_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace",s="NULL|true|false|TRUE|FALSE",u=this.$keywords=this.createKeywordMapper({"keyword.control":e,"storage.type":t,"storage.modifier":n,"keyword.operator":r,"variable.language":"this","constant.language":s},"identifier"),a="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Zd\\$_\u00a1-\uffff]*\\b";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"keyword",regex:"#\\s*(?:include|import|pragma|line|define|undef|if|ifdef|else|elif|ifndef)\\b",next:"directive"},{token:"keyword",regex:"(?:#\\s*endif)\\b"},{token:"support.function.C99.c",regex:o},{token:u,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}],directive:[{token:"constant.other.multiline",regex:/\\/},{token:"constant.other.multiline",regex:/.*\\/},{token:"constant.other",regex:"\\s*<.+?>",next:"start"},{token:"constant.other",regex:'\\s*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]',next:"start"},{token:"constant.other",regex:"\\s*['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']",next:"start"},{token:"constant.other",regex:/[^\\\/]+/,next:"start"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(u,s),t.c_cppHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/c_cpp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/c_cpp_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./c_cpp_highlight_rules").c_cppHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/c_cpp"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/glsl_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/c_cpp_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./c_cpp_highlight_rules").c_cppHighlightRules,s=function(){var e="attribute|const|uniform|varying|break|continue|do|for|while|if|else|in|out|inout|float|int|void|bool|true|false|lowp|mediump|highp|precision|invariant|discard|return|mat2|mat3|mat4|vec2|vec3|vec4|ivec2|ivec3|ivec4|bvec2|bvec3|bvec4|sampler2D|samplerCube|struct",t="radians|degrees|sin|cos|tan|asin|acos|atan|pow|exp|log|exp2|log2|sqrt|inversesqrt|abs|sign|floor|ceil|fract|mod|min|max|clamp|mix|step|smoothstep|length|distance|dot|cross|normalize|faceforward|reflect|refract|matrixCompMult|lessThan|lessThanEqual|greaterThan|greaterThanEqual|equal|notEqual|any|all|not|dFdx|dFdy|fwidth|texture2D|texture2DProj|texture2DLod|texture2DProjLod|textureCube|textureCubeLod|gl_MaxVertexAttribs|gl_MaxVertexUniformVectors|gl_MaxVaryingVectors|gl_MaxVertexTextureImageUnits|gl_MaxCombinedTextureImageUnits|gl_MaxTextureImageUnits|gl_MaxFragmentUniformVectors|gl_MaxDrawBuffers|gl_DepthRangeParameters|gl_DepthRange|gl_Position|gl_PointSize|gl_FragCoord|gl_FrontFacing|gl_PointCoord|gl_FragColor|gl_FragData",n=this.createKeywordMapper({"variable.language":"this",keyword:e,"constant.language":t},"identifier");this.$rules=(new i).$rules,this.$rules.start.forEach(function(e){typeof e.token=="function"&&(e.token=n)})};r.inherits(s,i),t.glslHighlightRules=s}),ace.define("ace/mode/glsl",["require","exports","module","ace/lib/oop","ace/mode/c_cpp","ace/mode/glsl_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./c_cpp").Mode,s=e("./glsl_highlight_rules").glslHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.$id="ace/mode/glsl"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-golang.js b/dist/assets/js/vendor/ace-nc/mode-golang.js
            new file mode 100644
            index 0000000000..c4e4364afe
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-golang.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/golang_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="else|break|case|return|goto|if|const|select|continue|struct|default|switch|for|range|func|import|package|chan|defer|fallthrough|go|interface|map|range|select|type|var",t="string|uint8|uint16|uint32|uint64|int8|int16|int32|int64|float32|float64|complex64|complex128|byte|rune|uint|int|uintptr|bool|error",n="make|close|new|panic|recover",r="nil|true|false|iota",s=this.createKeywordMapper({keyword:e,"constant.language":r,"support.function":n,"support.type":t},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"[`](?:[^`]*)[`]"},{token:"string",merge:!0,regex:"[`](?:[^`]*)$",next:"bqstring"},{token:"constant.numeric",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:s,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^="},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],bqstring:[{token:"string",regex:"(?:[^`]*)`",next:"start"},{token:"string",regex:".+"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(o,s),t.GolangHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/golang",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/golang_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("./golang_highlight_rules").GolangHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new a};r.inherits(f,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/golang"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-groovy.js b/dist/assets/js/vendor/ace-nc/mode-groovy.js
            new file mode 100644
            index 0000000000..e380ac1e3d
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-groovy.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/groovy_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="assert|with|abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|def|float|native|super|while",t="null|Infinity|NaN|undefined",n="AbstractMethodError|AssertionError|ClassCircularityError|ClassFormatError|Deprecated|EnumConstantNotPresentException|ExceptionInInitializerError|IllegalAccessError|IllegalThreadStateException|InstantiationError|InternalError|NegativeArraySizeException|NoSuchFieldError|Override|Process|ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|SuppressWarnings|TypeNotPresentException|UnknownError|UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|InstantiationException|IndexOutOfBoundsException|ArrayIndexOutOfBoundsException|CloneNotSupportedException|NoSuchFieldException|IllegalArgumentException|NumberFormatException|SecurityException|Void|InheritableThreadLocal|IllegalStateException|InterruptedException|NoSuchMethodException|IllegalAccessException|UnsupportedOperationException|Enum|StrictMath|Package|Compiler|Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|Character|Boolean|StackTraceElement|Appendable|StringBuffer|Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|StackOverflowError|OutOfMemoryError|VirtualMachineError|ArrayStoreException|ClassCastException|LinkageError|NoClassDefFoundError|ClassNotFoundException|RuntimeException|Exception|ThreadDeath|Error|Throwable|System|ClassLoader|Cloneable|Class|CharSequence|Comparable|String|Object",r=this.createKeywordMapper({"variable.language":"this",keyword:e,"support.function":n,"constant.language":t},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'"""',next:"qqstring"},{token:"string",regex:"'''",next:"qstring"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\?:|\\?\\.|\\*\\.|<=>|=~|==~|\\.@|\\*\\.@|\\.&|as|in|is|!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"constant.language.escape",regex:/\\(?:u[0-9A-Fa-f]{4}|.|$)/},{token:"constant.language.escape",regex:/\$[\w\d]+/},{token:"constant.language.escape",regex:/\$\{[^"\}]+\}?/},{token:"string",regex:'"{3,5}',next:"start"},{token:"string",regex:".+?"}],qstring:[{token:"constant.language.escape",regex:/\\(?:u[0-9A-Fa-f]{4}|.|$)/},{token:"string",regex:"'{3,5}",next:"start"},{token:"string",regex:".+?"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(o,s),t.GroovyHighlightRules=o}),ace.define("ace/mode/groovy",["require","exports","module","ace/lib/oop","ace/mode/javascript","ace/mode/groovy_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript").Mode,s=e("./groovy_highlight_rules").GroovyHighlightRules,o=function(){i.call(this),this.HighlightRules=s};r.inherits(o,i),function(){this.createWorker=function(e){return null},this.$id="ace/mode/groovy"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-haml.js b/dist/assets/js/vendor/ace-nc/mode-haml.js
            new file mode 100644
            index 0000000000..2f44f56474
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-haml.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},o=t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},u=t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},a=t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},f=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},l=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},c=function(){var e="abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many",t="alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield",n="true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING",r="$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self",i=this.$keywords=this.createKeywordMapper({keyword:t,"constant.language":n,"variable.language":r,"support.function":e,"invalid.deprecated":"debugger"},"identifier");this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin(?:$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},o,u,a,{token:"text",regex:"::"},{token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},s,f,l,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/haml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/ruby_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=e("./ruby_highlight_rules"),o=s.RubyHighlightRules,u=function(){this.$rules={start:[{token:"punctuation.section.comment",regex:/^\s*\/.*/},{token:"punctuation.section.comment",regex:/^\s*#.*/},{token:"string.quoted.double",regex:"==.+?=="},{token:"keyword.other.doctype",regex:"^!!!\\s*(?:[a-zA-Z0-9-_]+)?"},s.qString,s.qqString,s.tString,{token:["entity.name.tag.haml"],regex:/^\s*%[\w:]+/,next:"tag_single"},{token:["meta.escape.haml"],regex:"^\\s*\\\\."},s.constantNumericHex,s.constantNumericFloat,s.constantOtherSymbol,{token:"text",regex:"=|-|~",next:"embedded_ruby"}],tag_single:[{token:"entity.other.attribute-name.class.haml",regex:"\\.[\\w-]+"},{token:"entity.other.attribute-name.id.haml",regex:"#[\\w-]+"},{token:"punctuation.section",regex:"\\{",next:"section"},s.constantOtherSymbol,{token:"text",regex:/\s/,next:"start"},{token:"empty",regex:"$|(?!\\.|#|\\{|\\[|=|-|~|\\/)",next:"start"}],section:[s.constantOtherSymbol,s.qString,s.qqString,s.tString,s.constantNumericHex,s.constantNumericFloat,{token:"punctuation.section",regex:"\\}",next:"start"}],embedded_ruby:[s.constantNumericHex,s.constantNumericFloat,{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},{token:(new o).getKeywords(),regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:["keyword","text","text"],regex:"(?:do|\\{)(?: \\|[^|]+\\|)?$",next:"start"},{token:["text"],regex:"^$",next:"start"},{token:["text"],regex:"^(?!.*\\|\\s*$)",next:"start"}]}};r.inherits(u,i),t.HamlHighlightRules=u}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/haml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/haml_highlight_rules","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./haml_highlight_rules").HamlHighlightRules,o=e("./folding/coffee").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart=["//","#"],this.$id="ace/mode/haml"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-handlebars.js b/dist/assets/js/vendor/ace-nc/mode-handlebars.js
            new file mode 100644
            index 0000000000..a5904695f5
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-handlebars.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/handlebars_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";function s(e,t){return t.splice(0,3),t.shift()||"start"}var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,o=function(){i.call(this);var e={regex:"(?={{)",push:"handlebars"};for(var t in this.$rules)this.$rules[t].unshift(e);this.$rules.handlebars=[{token:"comment.start",regex:"{{!--",push:[{token:"comment.end",regex:"--}}",next:s},{defaultToken:"comment"}]},{token:"comment.start",regex:"{{!",push:[{token:"comment.end",regex:"}}",next:s},{defaultToken:"comment"}]},{token:"storage.type.start",regex:"{{[#\\^/&]?",push:[{token:"storage.type.end",regex:"}}",next:s},{token:"variable.parameter",regex:"[a-zA-Z_$][a-zA-Z0-9_$]*"}]},{token:"support.function",regex:"{{{",push:[{token:"support.function",regex:"}}}",next:s},{token:"variable.parameter",regex:"[a-zA-Z_$][a-zA-Z0-9_$]*"}]}],this.normalizeRules()};r.inherits(o,i),t.HandlebarsHighlightRules=o}),ace.define("ace/mode/behaviour/html",["require","exports","module","ace/lib/oop","ace/mode/behaviour/xml"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour/xml").XmlBehaviour,s=function(){i.call(this)};r.inherits(s,i),t.HtmlBehaviour=s}),ace.define("ace/mode/handlebars",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/handlebars_highlight_rules","ace/mode/behaviour/html","ace/mode/folding/html"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html").Mode,s=e("./handlebars_highlight_rules").HandlebarsHighlightRules,o=e("./behaviour/html").HtmlBehaviour,u=e("./folding/html").FoldMode,a=function(){i.call(this),this.HighlightRules=s,this.$behaviour=new o,this.foldingRules=new u};r.inherits(a,i),function(){this.$id="ace/mode/handlebars"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-haskell.js b/dist/assets/js/vendor/ace-nc/mode-haskell.js
            new file mode 100644
            index 0000000000..052d46ac05
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-haskell.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/haskell_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:["punctuation.definition.entity.haskell","keyword.operator.function.infix.haskell","punctuation.definition.entity.haskell"],regex:"(`)([a-zA-Z_']*?)(`)",comment:"In case this regex seems unusual for an infix operator, note that Haskell allows any ordinary function application (elem 4 [1..10]) to be rewritten as an infix expression (4 `elem` [1..10])."},{token:"constant.language.unit.haskell",regex:"\\(\\)"},{token:"constant.language.empty-list.haskell",regex:"\\[\\]"},{token:"keyword.other.haskell",regex:"module",push:[{token:"keyword.other.haskell",regex:"where",next:"pop"},{include:"#module_name"},{include:"#module_exports"},{token:"invalid",regex:"[a-z]+"},{defaultToken:"meta.declaration.module.haskell"}]},{token:"keyword.other.haskell",regex:"\\bclass\\b",push:[{token:"keyword.other.haskell",regex:"\\bwhere\\b",next:"pop"},{token:"support.class.prelude.haskell",regex:"\\b(?:Monad|Functor|Eq|Ord|Read|Show|Num|(?:Frac|Ra)tional|Enum|Bounded|Real(?:Frac|Float)?|Integral|Floating)\\b"},{token:"entity.other.inherited-class.haskell",regex:"[A-Z][A-Za-z_']*"},{token:"variable.other.generic-type.haskell",regex:"\\b[a-z][a-zA-Z0-9_']*\\b"},{defaultToken:"meta.declaration.class.haskell"}]},{token:"keyword.other.haskell",regex:"\\binstance\\b",push:[{token:"keyword.other.haskell",regex:"\\bwhere\\b|$",next:"pop"},{include:"#type_signature"},{defaultToken:"meta.declaration.instance.haskell"}]},{token:"keyword.other.haskell",regex:"import",push:[{token:"meta.import.haskell",regex:"$|;",next:"pop"},{token:"keyword.other.haskell",regex:"qualified|as|hiding"},{include:"#module_name"},{include:"#module_exports"},{defaultToken:"meta.import.haskell"}]},{token:["keyword.other.haskell","meta.deriving.haskell"],regex:"(deriving)(\\s*\\()",push:[{token:"meta.deriving.haskell",regex:"\\)",next:"pop"},{token:"entity.other.inherited-class.haskell",regex:"\\b[A-Z][a-zA-Z_']*"},{defaultToken:"meta.deriving.haskell"}]},{token:"keyword.other.haskell",regex:"\\b(?:deriving|where|data|type|case|of|let|in|newtype|default)\\b"},{token:"keyword.operator.haskell",regex:"\\binfix[lr]?\\b"},{token:"keyword.control.haskell",regex:"\\b(?:do|if|then|else)\\b"},{token:"constant.numeric.float.haskell",regex:"\\b(?:[0-9]+\\.[0-9]+(?:[eE][+-]?[0-9]+)?|[0-9]+[eE][+-]?[0-9]+)\\b",comment:"Floats are always decimal"},{token:"constant.numeric.haskell",regex:"\\b(?:[0-9]+|0(?:[xX][0-9a-fA-F]+|[oO][0-7]+))\\b"},{token:["meta.preprocessor.c","punctuation.definition.preprocessor.c","meta.preprocessor.c"],regex:"^(\\s*)(#)(\\s*\\w+)",comment:'In addition to Haskell\'s "native" syntax, GHC permits the C preprocessor to be run on a source file.'},{include:"#pragma"},{token:"punctuation.definition.string.begin.haskell",regex:'"',push:[{token:"punctuation.definition.string.end.haskell",regex:'"',next:"pop"},{token:"constant.character.escape.haskell",regex:"\\\\(?:NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|[abfnrtv\\\\\\\"'\\&])"},{token:"constant.character.escape.octal.haskell",regex:"\\\\o[0-7]+|\\\\x[0-9A-Fa-f]+|\\\\[0-9]+"},{token:"constant.character.escape.control.haskell",regex:"\\^[A-Z@\\[\\]\\\\\\^_]"},{defaultToken:"string.quoted.double.haskell"}]},{token:["punctuation.definition.string.begin.haskell","string.quoted.single.haskell","constant.character.escape.haskell","constant.character.escape.octal.haskell","constant.character.escape.hexadecimal.haskell","constant.character.escape.control.haskell","punctuation.definition.string.end.haskell"],regex:"(')(?:([\\ -\\[\\]-~])|(\\\\(?:NUL|SOH|STX|ETX|EOT|ENQ|ACK|BEL|BS|HT|LF|VT|FF|CR|SO|SI|DLE|DC1|DC2|DC3|DC4|NAK|SYN|ETB|CAN|EM|SUB|ESC|FS|GS|RS|US|SP|DEL|[abfnrtv\\\\\\\"'\\&]))|(\\\\o[0-7]+)|(\\\\x[0-9A-Fa-f]+)|(\\^[A-Z@\\[\\]\\\\\\^_]))(')"},{token:["meta.function.type-declaration.haskell","entity.name.function.haskell","meta.function.type-declaration.haskell","keyword.other.double-colon.haskell"],regex:"^(\\s*)([a-z_][a-zA-Z0-9_']*|\\([|!%$+\\-.,=</>]+\\))(\\s*)(::)",push:[{token:"meta.function.type-declaration.haskell",regex:"$",next:"pop"},{include:"#type_signature"},{defaultToken:"meta.function.type-declaration.haskell"}]},{token:"support.constant.haskell",regex:"\\b(?:Just|Nothing|Left|Right|True|False|LT|EQ|GT|\\(\\)|\\[\\])\\b"},{token:"constant.other.haskell",regex:"\\b[A-Z]\\w*\\b"},{include:"#comments"},{token:"support.function.prelude.haskell",regex:"\\b(?:abs|acos|acosh|all|and|any|appendFile|applyM|asTypeOf|asin|asinh|atan|atan2|atanh|break|catch|ceiling|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|div|divMod|drop|dropWhile|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromEnum|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|head|id|init|interact|ioError|isDenormalized|isIEEE|isInfinite|isNaN|isNegativeZero|iterate|last|lcm|length|lex|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|odd|or|otherwise|pi|pred|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|read|readFile|readIO|readList|readLn|readParen|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showList|showParen|showString|shows|showsPrec|significand|signum|sin|sinh|snd|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|toEnum|toInteger|toRational|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\\b"},{include:"#infix_op"},{token:"keyword.operator.haskell",regex:"[|!%$?~+:\\-.=</>\\\\]+",comment:"In case this regex seems overly general, note that Haskell permits the definition of new operators which can be nearly any string of punctuation characters, such as $%^&*."},{token:"punctuation.separator.comma.haskell",regex:","}],"#block_comment":[{token:"punctuation.definition.comment.haskell",regex:"\\{-(?!#)",push:[{include:"#block_comment"},{token:"punctuation.definition.comment.haskell",regex:"-\\}",next:"pop"},{defaultToken:"comment.block.haskell"}]}],"#comments":[{token:"punctuation.definition.comment.haskell",regex:"--.*",push_:[{token:"comment.line.double-dash.haskell",regex:"$",next:"pop"},{defaultToken:"comment.line.double-dash.haskell"}]},{include:"#block_comment"}],"#infix_op":[{token:"entity.name.function.infix.haskell",regex:"\\([|!%$+:\\-.=</>]+\\)|\\(,+\\)"}],"#module_exports":[{token:"meta.declaration.exports.haskell",regex:"\\(",push:[{token:"meta.declaration.exports.haskell",regex:"\\)",next:"pop"},{token:"entity.name.function.haskell",regex:"\\b[a-z][a-zA-Z_']*"},{token:"storage.type.haskell",regex:"\\b[A-Z][A-Za-z_']*"},{token:"punctuation.separator.comma.haskell",regex:","},{include:"#infix_op"},{token:"meta.other.unknown.haskell",regex:"\\(.*?\\)",comment:"So named because I don't know what to call this."},{defaultToken:"meta.declaration.exports.haskell"}]}],"#module_name":[{token:"support.other.module.haskell",regex:"[A-Z][A-Za-z._']*"}],"#pragma":[{token:"meta.preprocessor.haskell",regex:"\\{-#",push:[{token:"meta.preprocessor.haskell",regex:"#-\\}",next:"pop"},{token:"keyword.other.preprocessor.haskell",regex:"\\b(?:LANGUAGE|UNPACK|INLINE)\\b"},{defaultToken:"meta.preprocessor.haskell"}]}],"#type_signature":[{token:["meta.class-constraint.haskell","entity.other.inherited-class.haskell","meta.class-constraint.haskell","variable.other.generic-type.haskell","meta.class-constraint.haskell","keyword.other.big-arrow.haskell"],regex:"(\\(\\s*)([A-Z][A-Za-z]*)(\\s+)([a-z][A-Za-z_']*)(\\)\\s*)(=>)"},{include:"#pragma"},{token:"keyword.other.arrow.haskell",regex:"->"},{token:"keyword.other.big-arrow.haskell",regex:"=>"},{token:"support.type.prelude.haskell",regex:"\\b(?:Int(?:eger)?|Maybe|Either|Bool|Float|Double|Char|String|Ordering|ShowS|ReadS|FilePath|IO(?:Error)?)\\b"},{token:"variable.other.generic-type.haskell",regex:"\\b[a-z][a-zA-Z0-9_']*\\b"},{token:"storage.type.haskell",regex:"\\b[A-Z][a-zA-Z0-9_']*\\b"},{token:"support.constant.unit.haskell",regex:"\\(\\)"},{include:"#comments"}]},this.normalizeRules()};s.metaData={fileTypes:["hs"],keyEquivalent:"^~H",name:"Haskell",scopeName:"source.haskell"},r.inherits(s,i),t.HaskellHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/haskell",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/haskell_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./haskell_highlight_rules").HaskellHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="--",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/haskell"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-haxe.js b/dist/assets/js/vendor/ace-nc/mode-haxe.js
            new file mode 100644
            index 0000000000..36ddb143ec
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-haxe.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/haxe_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="break|case|cast|catch|class|continue|default|else|enum|extends|for|function|if|implements|import|in|inline|interface|new|override|package|private|public|return|static|super|switch|this|throw|trace|try|typedef|untyped|var|while|Array|Void|Bool|Int|UInt|Float|Dynamic|String|List|Hash|IntHash|Error|Unknown|Type|Std",t="null|true|false",n=this.createKeywordMapper({"variable.language":"this",keyword:e,"constant.language":t},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:n,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({<]"},{token:"paren.rparen",regex:"[\\])}>]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(o,s),t.HaxeHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/haxe",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/haxe_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./haxe_highlight_rules").HaxeHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[]\s*$/);o&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/haxe"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-html.js b/dist/assets/js/vendor/ace-nc/mode-html.js
            new file mode 100644
            index 0000000000..9c15f36ee1
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-html.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-html_ruby.js b/dist/assets/js/vendor/ace-nc/mode-html_ruby.js
            new file mode 100644
            index 0000000000..675aa7f211
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-html_ruby.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},o=t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},u=t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},a=t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},f=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},l=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},c=function(){var e="abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many",t="alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield",n="true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING",r="$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self",i=this.$keywords=this.createKeywordMapper({keyword:t,"constant.language":n,"variable.language":r,"support.function":e,"invalid.deprecated":"debugger"},"identifier");this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin(?:$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},o,u,a,{token:"text",regex:"::"},{token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},s,f,l,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/html_ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/ruby_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=e("./ruby_highlight_rules").RubyHighlightRules,o=function(){i.call(this);var e=[{regex:"<%%|%%>",token:"constant.language.escape"},{token:"comment.start.erb",regex:"<%#",push:[{token:"comment.end.erb",regex:"%>",next:"pop",defaultToken:"comment"}]},{token:"support.ruby_tag",regex:"<%+(?!>)[-=]?",push:"ruby-start"}],t=[{token:"support.ruby_tag",regex:"%>",next:"pop"},{token:"comment",regex:"#(?:[^%]|%[^>])*"}];for(var n in this.$rules)this.$rules[n].unshift.apply(this.$rules[n],e);this.embedRules(s,"ruby-",t,["start"]),this.normalizeRules()};r.inherits(o,i),t.HtmlRubyHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./ruby_highlight_rules").RubyHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./folding/coffee").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new a};r.inherits(f,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[]\s*$/),u=t.match(/^\s*(class|def|module)\s.*$/),a=t.match(/.*do(\s*|\s+\|.*\|\s*)$/),f=t.match(/^\s*(if|else)\s*/);if(o||u||a||f)r+=n}return r},this.checkOutdent=function(e,t,n){return/^\s+(end|else)$/.test(t+n)||this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){var r=t.getLine(n);if(/}/.test(r))return this.$outdent.autoOutdent(t,n);var i=this.$getIndent(r),s=t.getLine(n-1),o=this.$getIndent(s),a=t.getTabString();o.length<=i.length&&i.slice(-a.length)==a&&t.remove(new u(n,i.length-a.length,n,i.length))},this.$id="ace/mode/ruby"}.call(f.prototype),t.Mode=f}),ace.define("ace/mode/html_ruby",["require","exports","module","ace/lib/oop","ace/mode/html_ruby_highlight_rules","ace/mode/html","ace/mode/javascript","ace/mode/css","ace/mode/ruby"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_ruby_highlight_rules").HtmlRubyHighlightRules,s=e("./html").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./ruby").Mode,f=function(){s.call(this),this.HighlightRules=i,this.createModeDelegates({"js-":o,"css-":u,"ruby-":a})};r.inherits(f,s),function(){this.$id="ace/mode/html_ruby"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-ini.js b/dist/assets/js/vendor/ace-nc/mode-ini.js
            new file mode 100644
            index 0000000000..54c2e9233b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-ini.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/ini_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s="\\\\(?:[\\\\0abtrn;#=:]|x[a-fA-F\\d]{4})",o=function(){this.$rules={start:[{token:"punctuation.definition.comment.ini",regex:"#.*",push_:[{token:"comment.line.number-sign.ini",regex:"$|^",next:"pop"},{defaultToken:"comment.line.number-sign.ini"}]},{token:"punctuation.definition.comment.ini",regex:";.*",push_:[{token:"comment.line.semicolon.ini",regex:"$|^",next:"pop"},{defaultToken:"comment.line.semicolon.ini"}]},{token:["keyword.other.definition.ini","text","punctuation.separator.key-value.ini"],regex:"\\b([a-zA-Z0-9_.-]+)\\b(\\s*)(=)"},{token:["punctuation.definition.entity.ini","constant.section.group-title.ini","punctuation.definition.entity.ini"],regex:"^(\\[)(.*?)(\\])"},{token:"punctuation.definition.string.begin.ini",regex:"'",push:[{token:"punctuation.definition.string.end.ini",regex:"'",next:"pop"},{token:"constant.language.escape",regex:s},{defaultToken:"string.quoted.single.ini"}]},{token:"punctuation.definition.string.begin.ini",regex:'"',push:[{token:"constant.language.escape",regex:s},{token:"punctuation.definition.string.end.ini",regex:'"',next:"pop"},{defaultToken:"string.quoted.double.ini"}]}]},this.normalizeRules()};o.metaData={fileTypes:["ini","conf"],keyEquivalent:"^~I",name:"Ini",scopeName:"source.ini"},r.inherits(o,i),t.IniHighlightRules=o}),ace.define("ace/mode/folding/ini",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(){};r.inherits(o,s),function(){this.foldingStartMarker=/^\s*\[([^\])]*)]\s*(?:$|[;#])/,this.getFoldWidgetRange=function(e,t,n){var r=this.foldingStartMarker,s=e.getLine(n),o=s.match(r);if(!o)return;var u=o[1]+".",a=s.length,f=e.getLength(),l=n,c=n;while(++n<f){s=e.getLine(n);if(/^\s*$/.test(s))continue;o=s.match(r);if(o&&o[1].lastIndexOf(u,0)!==0)break;c=n}if(c>l){var h=e.getLine(c).length;return new i(l,a,c,h)}}}.call(o.prototype)}),ace.define("ace/mode/ini",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ini_highlight_rules","ace/mode/folding/ini"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./ini_highlight_rules").IniHighlightRules,o=e("./folding/ini").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart=";",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/ini"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-jack.js b/dist/assets/js/vendor/ace-nc/mode-jack.js
            new file mode 100644
            index 0000000000..1994d9e09c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-jack.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/jack_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"string",regex:'"',next:"string2"},{token:"string",regex:"'",next:"string1"},{token:"constant.numeric",regex:"-?0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"(?:0|[-+]?[1-9][0-9]*)\\b"},{token:"constant.binary",regex:"<[0-9A-Fa-f][0-9A-Fa-f](\\s+[0-9A-Fa-f][0-9A-Fa-f])*>"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:"constant.language.null",regex:"null\\b"},{token:"storage.type",regex:"(?:Integer|Boolean|Null|String|Buffer|Tuple|List|Object|Function|Coroutine|Form)\\b"},{token:"keyword",regex:"(?:return|abort|vars|for|delete|in|is|escape|exec|split|and|if|elif|else|while)\\b"},{token:"language.builtin",regex:"(?:lines|source|parse|read-stream|interval|substr|parseint|write|print|range|rand|inspect|bind|i-values|i-pairs|i-map|i-filter|i-chunk|i-all\\?|i-any\\?|i-collect|i-zip|i-merge|i-each)\\b"},{token:"comment",regex:"--.*$"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"storage.form",regex:"@[a-z]+"},{token:"constant.other.symbol",regex:":+[a-zA-Z_]([-]?[a-zA-Z0-9_])*[?!]?"},{token:"variable",regex:"[a-zA-Z_]([-]?[a-zA-Z0-9_])*[?!]?"},{token:"keyword.operator",regex:"\\|\\||\\^\\^|&&|!=|==|<=|<|>=|>|\\+|-|\\*|\\/|\\^|\\%|\\#|\\!"},{token:"text",regex:"\\s+"}],string1:[{token:"constant.language.escape",regex:/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|['"\\\/bfnrt])/},{token:"string",regex:"[^'\\\\]+"},{token:"string",regex:"'",next:"start"},{token:"string",regex:"",next:"start"}],string2:[{token:"constant.language.escape",regex:/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|['"\\\/bfnrt])/},{token:"string",regex:'[^"\\\\]+'},{token:"string",regex:'"',next:"start"},{token:"string",regex:"",next:"start"}]}};r.inherits(s,i),t.JackHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/jack",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/jack_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./jack_highlight_rules").JackHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,i),function(){this.lineCommentStart="--",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);if(e=="start"){var i=t.match(/^.*[\{\(\[]\s*$/);i&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/jack"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-jade.js b/dist/assets/js/vendor/ace-nc/mode-jade.js
            new file mode 100644
            index 0000000000..da62aece62
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-jade.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/markdown_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules","ace/mode/html_highlight_rules","ace/mode/css_highlight_rules"],function(e,t,n){"use strict";function c(e,t){return{token:"support.function",regex:"^\\s*```"+e+"\\s*$",push:t+"start"}}var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./css_highlight_rules").CssHighlightRules,l=function(e){return"(?:[^"+i.escapeRegExp(e)+"\\\\]|\\\\.)*"},h=function(){a.call(this),this.$rules.start.unshift({token:"empty_line",regex:"^$",next:"allowBlock"},{token:"markup.heading.1",regex:"^=+(?=\\s*$)"},{token:"markup.heading.2",regex:"^\\-+(?=\\s*$)"},{token:function(e){return"markup.heading."+e.length},regex:/^#{1,6}(?=\s*[^ #]|\s+#.)/,next:"header"},c("(?:javascript|js)","jscode-"),c("xml","xmlcode-"),c("html","htmlcode-"),c("css","csscode-"),{token:"support.function",regex:"^\\s*```\\s*\\S*(?:{.*?\\})?\\s*$",next:"githubblock"},{token:"string.blockquote",regex:"^\\s*>\\s*(?:[*+-]|\\d+\\.)?\\s+",next:"blockquote"},{token:"constant",regex:"^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$",next:"allowBlock"},{token:"markup.list",regex:"^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",next:"listblock-start"},{include:"basic"}),this.addRules({basic:[{token:"constant.language.escape",regex:/\\[\\`*_{}\[\]()#+\-.!]/},{token:"support.function",regex:"(`+)(.*?[^`])(\\1)"},{token:["text","constant","text","url","string","text"],regex:'^([ ]{0,3}\\[)([^\\]]+)(\\]:\\s*)([^ ]+)(\\s*(?:["][^"]+["])?(\\s*))$'},{token:["text","string","text","constant","text"],regex:"(\\[)("+l("]")+")(\\]s*\\[)("+l("]")+")(\\])"},{token:["text","string","text","markup.underline","string","text"],regex:"(\\[)("+l("]")+")(\\]\\()"+'((?:[^\\)\\s\\\\]|\\\\.|\\s(?=[^"]))*)'+'(\\s*"'+l('"')+'"\\s*)?'+"(\\))"},{token:"string.strong",regex:"([*]{2}|[_]{2}(?=\\S))(.*?\\S[*_]*)(\\1)"},{token:"string.emphasis",regex:"([*]|[_](?=\\S))(.*?\\S[*_]*)(\\1)"},{token:["text","url","text"],regex:"(<)((?:https?|ftp|dict):[^'\">\\s]+|(?:mailto:)?[-.\\w]+\\@[-a-z0-9]+(?:\\.[-a-z0-9]+)*\\.[a-z]+)(>)"}],allowBlock:[{token:"support.function",regex:"^ {4}.+",next:"allowBlock"},{token:"empty",regex:"",next:"start"}],header:[{regex:"$",next:"start"},{include:"basic"},{defaultToken:"heading"}],"listblock-start":[{token:"support.variable",regex:/(?:\[[ x]\])?/,next:"listblock"}],listblock:[{token:"empty_line",regex:"^$",next:"start"},{token:"markup.list",regex:"^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",next:"listblock-start"},{include:"basic",noEscape:!0},{token:"support.function",regex:"^\\s*```\\s*[a-zA-Z]*(?:{.*?\\})?\\s*$",next:"githubblock"},{defaultToken:"list"}],blockquote:[{token:"empty_line",regex:"^\\s*$",next:"start"},{token:"string.blockquote",regex:"^\\s*>\\s*(?:[*+-]|\\d+\\.)?\\s+",next:"blockquote"},{include:"basic",noEscape:!0},{defaultToken:"string.blockquote"}],githubblock:[{token:"support.function",regex:"^\\s*```",next:"start"},{token:"support.function",regex:".+"}]}),this.embedRules(o,"jscode-",[{token:"support.function",regex:"^\\s*```",next:"pop"}]),this.embedRules(a,"htmlcode-",[{token:"support.function",regex:"^\\s*```",next:"pop"}]),this.embedRules(f,"csscode-",[{token:"support.function",regex:"^\\s*```",next:"pop"}]),this.embedRules(u,"xmlcode-",[{token:"support.function",regex:"^\\s*```",next:"pop"}]),this.normalizeRules()};r.inherits(h,s),t.MarkdownHighlightRules=h}),ace.define("ace/mode/scss_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=i.arrayToMap(function(){var e="-webkit-|-moz-|-o-|-ms-|-svg-|-pie-|-khtml-".split("|"),t="appearance|background-clip|background-inline-policy|background-origin|background-size|binding|border-bottom-colors|border-left-colors|border-right-colors|border-top-colors|border-end|border-end-color|border-end-style|border-end-width|border-image|border-start|border-start-color|border-start-style|border-start-width|box-align|box-direction|box-flex|box-flexgroup|box-ordinal-group|box-orient|box-pack|box-sizing|column-count|column-gap|column-width|column-rule|column-rule-width|column-rule-style|column-rule-color|float-edge|font-feature-settings|font-language-override|force-broken-image-icon|image-region|margin-end|margin-start|opacity|outline|outline-color|outline-offset|outline-radius|outline-radius-bottomleft|outline-radius-bottomright|outline-radius-topleft|outline-radius-topright|outline-style|outline-width|padding-end|padding-start|stack-sizing|tab-size|text-blink|text-decoration-color|text-decoration-line|text-decoration-style|transform|transform-origin|transition|transition-delay|transition-duration|transition-property|transition-timing-function|user-focus|user-input|user-modify|user-select|window-shadow|border-radius".split("|"),n="azimuth|background-attachment|background-color|background-image|background-position|background-repeat|background|border-bottom-color|border-bottom-style|border-bottom-width|border-bottom|border-collapse|border-color|border-left-color|border-left-style|border-left-width|border-left|border-right-color|border-right-style|border-right-width|border-right|border-spacing|border-style|border-top-color|border-top-style|border-top-width|border-top|border-width|border|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|content|counter-increment|counter-reset|cue-after|cue-before|cue|cursor|direction|display|elevation|empty-cells|float|font-family|font-size-adjust|font-size|font-stretch|font-style|font-variant|font-weight|font|height|left|letter-spacing|line-height|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|marker-offset|margin|marks|max-height|max-width|min-height|min-width|opacity|orphans|outline-color|outline-style|outline-width|outline|overflow|overflow-x|overflow-y|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page|pause-after|pause-before|pause|pitch-range|pitch|play-during|position|quotes|richness|right|size|speak-header|speak-numeral|speak-punctuation|speech-rate|speak|stress|table-layout|text-align|text-decoration|text-indent|text-shadow|text-transform|top|unicode-bidi|vertical-align|visibility|voice-family|volume|white-space|widows|width|word-spacing|z-index".split("|"),r=[];for(var i=0,s=e.length;i<s;i++)Array.prototype.push.apply(r,(e[i]+t.join("|"+e[i])).split("|"));return Array.prototype.push.apply(r,t),Array.prototype.push.apply(r,n),r}()),t=i.arrayToMap("hsl|hsla|rgb|rgba|url|attr|counter|counters|abs|adjust_color|adjust_hue|alpha|join|blue|ceil|change_color|comparable|complement|darken|desaturate|floor|grayscale|green|hue|if|invert|join|length|lighten|lightness|mix|nth|opacify|opacity|percentage|quote|red|round|saturate|saturation|scale_color|transparentize|type_of|unit|unitless|unqoute".split("|")),n=i.arrayToMap("absolute|all-scroll|always|armenian|auto|baseline|below|bidi-override|block|bold|bolder|border-box|both|bottom|break-all|break-word|capitalize|center|char|circle|cjk-ideographic|col-resize|collapse|content-box|crosshair|dashed|decimal-leading-zero|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fixed|georgian|groove|hand|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|katakana-iroha|katakana|keep-all|left|lighter|line-edge|line-through|line|list-item|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|outset|outside|overline|pointer|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|super|sw-resize|table-footer-group|table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|zero".split("|")),r=i.arrayToMap("aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow".split("|")),s=i.arrayToMap("@mixin|@extend|@include|@import|@media|@debug|@warn|@if|@for|@each|@while|@else|@font-face|@-webkit-keyframes|if|and|!default|module|def|end|declare".split("|")),o=i.arrayToMap("a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdo|big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|keygen|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|source|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|u|ul|var|video|wbr|xmp".split("|")),u="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:u+"(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)"},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:"constant.numeric",regex:u},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:function(i){return e.hasOwnProperty(i.toLowerCase())?"support.type":s.hasOwnProperty(i)?"keyword":n.hasOwnProperty(i)?"constant.language":t.hasOwnProperty(i)?"support.function":r.hasOwnProperty(i.toLowerCase())?"support.constant.color":o.hasOwnProperty(i.toLowerCase())?"variable.language":"text"},regex:"\\-?[@a-z_][@a-z0-9_\\-]*"},{token:"variable",regex:"[a-z_\\-$][a-z0-9_\\-$]*\\b"},{token:"variable.language",regex:"#[a-z0-9-_]+"},{token:"variable.language",regex:"\\.[a-z0-9-_]+"},{token:"variable.language",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{token:"keyword.operator",regex:"<|>|<=|>=|==|!=|-|%|#|\\+|\\$|\\+|\\*"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]}};r.inherits(o,s),t.ScssHighlightRules=o}),ace.define("ace/mode/less_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=i.arrayToMap(function(){var e="-webkit-|-moz-|-o-|-ms-|-svg-|-pie-|-khtml-".split("|"),t="appearance|background-clip|background-inline-policy|background-origin|background-size|binding|border-bottom-colors|border-left-colors|border-right-colors|border-top-colors|border-end|border-end-color|border-end-style|border-end-width|border-image|border-start|border-start-color|border-start-style|border-start-width|box-align|box-direction|box-flex|box-flexgroup|box-ordinal-group|box-orient|box-pack|box-sizing|column-count|column-gap|column-width|column-rule|column-rule-width|column-rule-style|column-rule-color|float-edge|font-feature-settings|font-language-override|force-broken-image-icon|image-region|margin-end|margin-start|opacity|outline|outline-color|outline-offset|outline-radius|outline-radius-bottomleft|outline-radius-bottomright|outline-radius-topleft|outline-radius-topright|outline-style|outline-width|padding-end|padding-start|stack-sizing|tab-size|text-blink|text-decoration-color|text-decoration-line|text-decoration-style|transform|transform-origin|transition|transition-delay|transition-duration|transition-property|transition-timing-function|user-focus|user-input|user-modify|user-select|window-shadow|border-radius".split("|"),n="azimuth|background-attachment|background-color|background-image|background-position|background-repeat|background|border-bottom-color|border-bottom-style|border-bottom-width|border-bottom|border-collapse|border-color|border-left-color|border-left-style|border-left-width|border-left|border-right-color|border-right-style|border-right-width|border-right|border-spacing|border-style|border-top-color|border-top-style|border-top-width|border-top|border-width|border|bottom|box-sizing|caption-side|clear|clip|color|content|counter-increment|counter-reset|cue-after|cue-before|cue|cursor|direction|display|elevation|empty-cells|float|font-family|font-size-adjust|font-size|font-stretch|font-style|font-variant|font-weight|font|height|left|letter-spacing|line-height|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|marker-offset|margin|marks|max-height|max-width|min-height|min-width|opacity|orphans|outline-color|outline-style|outline-width|outline|overflow|overflow-x|overflow-y|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page|pause-after|pause-before|pause|pitch-range|pitch|play-during|position|quotes|richness|right|size|speak-header|speak-numeral|speak-punctuation|speech-rate|speak|stress|table-layout|text-align|text-decoration|text-indent|text-shadow|text-transform|top|unicode-bidi|vertical-align|visibility|voice-family|volume|white-space|widows|width|word-spacing|z-index".split("|"),r=[];for(var i=0,s=e.length;i<s;i++)Array.prototype.push.apply(r,(e[i]+t.join("|"+e[i])).split("|"));return Array.prototype.push.apply(r,t),Array.prototype.push.apply(r,n),r}()),t=i.arrayToMap("hsl|hsla|rgb|rgba|url|attr|counter|counters|lighten|darken|saturate|desaturate|fadein|fadeout|fade|spin|mix|hue|saturation|lightness|alpha|round|ceil|floor|percentage|color|iscolor|isnumber|isstring|iskeyword|isurl|ispixel|ispercentage|isem".split("|")),n=i.arrayToMap("absolute|all-scroll|always|armenian|auto|baseline|below|bidi-override|block|bold|bolder|border-box|both|bottom|break-all|break-word|capitalize|center|char|circle|cjk-ideographic|col-resize|collapse|content-box|crosshair|dashed|decimal-leading-zero|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fixed|georgian|groove|hand|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|katakana-iroha|katakana|keep-all|left|lighter|line-edge|line-through|line|list-item|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|outset|outside|overline|pointer|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|super|sw-resize|table-footer-group|table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|zero".split("|")),r=i.arrayToMap("aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow".split("|")),s=i.arrayToMap("@mixin|@extend|@include|@import|@media|@debug|@warn|@if|@for|@each|@while|@else|@font-face|@-webkit-keyframes|if|and|!default|module|def|end|declare|when|not|and".split("|")),o=i.arrayToMap("a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdo|big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|keygen|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|source|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|u|ul|var|video|wbr|xmp".split("|")),u="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:u+"(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)"},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:"constant.numeric",regex:u},{token:function(e){return s.hasOwnProperty(e)?"keyword":"variable"},regex:"@[a-z0-9_\\-@]*\\b"},{token:function(i){return e.hasOwnProperty(i.toLowerCase())?"support.type":s.hasOwnProperty(i)?"keyword":n.hasOwnProperty(i)?"constant.language":t.hasOwnProperty(i)?"support.function":r.hasOwnProperty(i.toLowerCase())?"support.constant.color":o.hasOwnProperty(i.toLowerCase())?"variable.language":"text"},regex:"\\-?[@a-z_][@a-z0-9_\\-]*"},{token:"variable.language",regex:"#[a-z0-9-_]+"},{token:"variable.language",regex:"\\.[a-z0-9-_]+"},{token:"variable.language",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{token:"keyword.operator",regex:"<|>|<=|>=|==|!=|-|%|#|\\+|\\$|\\+|\\*"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}]}};r.inherits(o,s),t.LessHighlightRules=o}),ace.define("ace/mode/coffee_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function s(){var e="[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*",t="this|throw|then|try|typeof|super|switch|return|break|by|continue|catch|class|in|instanceof|is|isnt|if|else|extends|for|own|finally|function|while|when|new|no|not|delete|debugger|do|loop|of|off|or|on|unless|until|and|yes",n="true|false|null|undefined|NaN|Infinity",r="case|const|default|function|var|void|with|enum|export|implements|interface|let|package|private|protected|public|static|yield|__hasProp|slice|bind|indexOf",i="Array|Boolean|Date|Function|Number|Object|RegExp|ReferenceError|String|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray",s="Math|JSON|isNaN|isFinite|parseInt|parseFloat|encodeURI|encodeURIComponent|decodeURI|decodeURIComponent|String|",o="window|arguments|prototype|document",u=this.createKeywordMapper({keyword:t,"constant.language":n,"invalid.illegal":r,"language.support.class":i,"language.support.function":s,"variable.language":o},"identifier"),a={token:["paren.lparen","variable.parameter","paren.rparen","text","storage.type"],regex:/(?:(\()((?:"[^")]*?"|'[^')]*?'|\/[^\/)]*?\/|[^()\"'\/])*?)(\))(\s*))?([\-=]>)/.source},f=/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)/;this.$rules={start:[{token:"constant.numeric",regex:"(?:0x[\\da-fA-F]+|(?:\\d+(?:\\.\\d+)?|\\.\\d+)(?:[eE][+-]?\\d+)?)"},{stateName:"qdoc",token:"string",regex:"'''",next:[{token:"string",regex:"'''",next:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{stateName:"qqdoc",token:"string",regex:'"""',next:[{token:"string",regex:'"""',next:"start"},{token:"paren.string",regex:"#{",push:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{stateName:"qstring",token:"string",regex:"'",next:[{token:"string",regex:"'",next:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{stateName:"qqstring",token:"string.start",regex:'"',next:[{token:"string.end",regex:'"',next:"start"},{token:"paren.string",regex:"#{",push:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{stateName:"js",token:"string",regex:"`",next:[{token:"string",regex:"`",next:"start"},{token:"constant.language.escape",regex:f},{defaultToken:"string"}]},{regex:"[{}]",onMatch:function(e,t,n){this.next="";if(e=="{"&&n.length)return n.unshift("start",t),"paren";if(e=="}"&&n.length){n.shift(),this.next=n.shift();if(this.next.indexOf("string")!=-1)return"paren.string"}return"paren"}},{token:"string.regex",regex:"///",next:"heregex"},{token:"string.regex",regex:/(?:\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)(?:[imgy]{0,4})(?!\w)/},{token:"comment",regex:"###(?!#)",next:"comment"},{token:"comment",regex:"#.*"},{token:["punctuation.operator","text","identifier"],regex:"(\\.)(\\s*)("+r+")"},{token:"punctuation.operator",regex:"\\."},{token:["keyword","text","language.support.class","text","keyword","text","language.support.class"],regex:"(class)(\\s+)("+e+")(?:(\\s+)(extends)(\\s+)("+e+"))?"},{token:["entity.name.function","text","keyword.operator","text"].concat(a.token),regex:"("+e+")(\\s*)([=:])(\\s*)"+a.regex},a,{token:"variable",regex:"@(?:"+e+")?"},{token:u,regex:e},{token:"punctuation.operator",regex:"\\,|\\."},{token:"storage.type",regex:"[\\-=]>"},{token:"keyword.operator",regex:"(?:[-+*/%<>&|^!?=]=|>>>=?|\\-\\-|\\+\\+|::|&&=|\\|\\|=|<<=|>>=|\\?\\.|\\.{2,3}|[!*+-=><])"},{token:"paren.lparen",regex:"[({[]"},{token:"paren.rparen",regex:"[\\]})]"},{token:"text",regex:"\\s+"}],heregex:[{token:"string.regex",regex:".*?///[imgy]{0,4}",next:"start"},{token:"comment.regex",regex:"\\s+(?:#.*)?"},{token:"string.regex",regex:"\\S+"}],comment:[{token:"comment",regex:"###",next:"start"},{defaultToken:"comment"}]},this.normalizeRules()}var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules;r.inherits(s,i),t.CoffeeHighlightRules=s}),ace.define("ace/mode/jade_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/markdown_highlight_rules","ace/mode/scss_highlight_rules","ace/mode/less_highlight_rules","ace/mode/coffee_highlight_rules","ace/mode/javascript_highlight_rules"],function(e,t,n){"use strict";function l(e,t){return{token:"entity.name.function.jade",regex:"^\\s*\\:"+e,next:t+"start"}}var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=e("./markdown_highlight_rules").MarkdownHighlightRules,o=e("./scss_highlight_rules").ScssHighlightRules,u=e("./less_highlight_rules").LessHighlightRules,a=e("./coffee_highlight_rules").CoffeeHighlightRules,f=e("./javascript_highlight_rules").JavaScriptHighlightRules,c=function(){var e="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={start:[{token:"keyword.control.import.include.jade",regex:"\\s*\\binclude\\b"},{token:"keyword.other.doctype.jade",regex:"^!!!\\s*(?:[a-zA-Z0-9-_]+)?"},{token:"punctuation.section.comment",regex:"^\\s*//(?:\\s*[^-\\s]|\\s+\\S)(?:.*$)"},{onMatch:function(e,t,n){return n.unshift(this.next,e.length-2,t),"comment"},regex:/^\s*\/\//,next:"comment_block"},l("markdown","markdown-"),l("sass","sass-"),l("less","less-"),l("coffee","coffee-"),{token:["storage.type.function.jade","entity.name.function.jade","punctuation.definition.parameters.begin.jade","variable.parameter.function.jade","punctuation.definition.parameters.end.jade"],regex:"^(\\s*mixin)( [\\w\\-]+)(\\s*\\()(.*?)(\\))"},{token:["storage.type.function.jade","entity.name.function.jade"],regex:"^(\\s*mixin)( [\\w\\-]+)"},{token:"source.js.embedded.jade",regex:"^\\s*(?:-|=|!=)",next:"js-start"},{token:"string.interpolated.jade",regex:"[#!]\\{[^\\}]+\\}"},{token:"meta.tag.any.jade",regex:/^\s*(?!\w+\:)(?:[\w]+|(?=\.|#)])/,next:"tag_single"},{token:"suport.type.attribute.id.jade",regex:"#\\w+"},{token:"suport.type.attribute.class.jade",regex:"\\.\\w+"},{token:"punctuation",regex:"\\s*(?:\\()",next:"tag_attributes"}],comment_block:[{regex:/^\s*/,onMatch:function(e,t,n){return e.length<=n[1]?(n.shift(),n.shift(),this.next=n.shift(),"text"):(this.next="","comment")},next:"start"},{defaultToken:"comment"}],tag_single:[{token:"entity.other.attribute-name.class.jade",regex:"\\.[\\w-]+"},{token:"entity.other.attribute-name.id.jade",regex:"#[\\w-]+"},{token:["text","punctuation"],regex:"($)|((?!\\.|#|=|-))",next:"start"}],tag_attributes:[{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"entity.other.attribute-name.jade",regex:"\\b[a-zA-Z\\-:]+"},{token:["entity.other.attribute-name.jade","punctuation"],regex:"\\b([a-zA-Z:\\.-]+)(=)",next:"attribute_strings"},{token:"punctuation",regex:"\\)",next:"start"}],attribute_strings:[{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"}],qqstring:[{token:"constant.language.escape",regex:e},{token:"string",regex:'[^"\\\\]+'},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"tag_attributes"}],qstring:[{token:"constant.language.escape",regex:e},{token:"string",regex:"[^'\\\\]+"},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"tag_attributes"}]},this.embedRules(f,"js-",[{token:"text",regex:".$",next:"start"}])};r.inherits(c,i),t.JadeHighlightRules=c}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/jade",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/jade_highlight_rules","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./jade_highlight_rules").JadeHighlightRules,o=e("./folding/coffee").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="//",this.$id="ace/mode/jade"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-java.js b/dist/assets/js/vendor/ace-nc/mode-java.js
            new file mode 100644
            index 0000000000..1df2ad32b2
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-java.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/java_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while",t="null|Infinity|NaN|undefined",n="AbstractMethodError|AssertionError|ClassCircularityError|ClassFormatError|Deprecated|EnumConstantNotPresentException|ExceptionInInitializerError|IllegalAccessError|IllegalThreadStateException|InstantiationError|InternalError|NegativeArraySizeException|NoSuchFieldError|Override|Process|ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|SuppressWarnings|TypeNotPresentException|UnknownError|UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|InstantiationException|IndexOutOfBoundsException|ArrayIndexOutOfBoundsException|CloneNotSupportedException|NoSuchFieldException|IllegalArgumentException|NumberFormatException|SecurityException|Void|InheritableThreadLocal|IllegalStateException|InterruptedException|NoSuchMethodException|IllegalAccessException|UnsupportedOperationException|Enum|StrictMath|Package|Compiler|Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|Character|Boolean|StackTraceElement|Appendable|StringBuffer|Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|StackOverflowError|OutOfMemoryError|VirtualMachineError|ArrayStoreException|ClassCastException|LinkageError|NoClassDefFoundError|ClassNotFoundException|RuntimeException|Exception|ThreadDeath|Error|Throwable|System|ClassLoader|Cloneable|Class|CharSequence|Comparable|String|Object",r=this.createKeywordMapper({"variable.language":"this",keyword:e,"constant.language":t,"support.function":n},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(o,s),t.JavaHighlightRules=o}),ace.define("ace/mode/java",["require","exports","module","ace/lib/oop","ace/mode/javascript","ace/mode/java_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript").Mode,s=e("./java_highlight_rules").JavaHighlightRules,o=function(){i.call(this),this.HighlightRules=s};r.inherits(o,i),function(){this.createWorker=function(e){return null},this.$id="ace/mode/java"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-javascript.js b/dist/assets/js/vendor/ace-nc/mode-javascript.js
            new file mode 100644
            index 0000000000..30dcda85df
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-javascript.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-json.js b/dist/assets/js/vendor/ace-nc/mode-json.js
            new file mode 100644
            index 0000000000..84eda38c01
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-json.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/json_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"variable",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)'},{token:"string",regex:'"',next:"string"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:"invalid.illegal",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"invalid.illegal",regex:"\\/\\/.*$"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],string:[{token:"constant.language.escape",regex:/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/},{token:"string",regex:'[^"\\\\]+'},{token:"string",regex:'"',next:"start"},{token:"string",regex:"",next:"start"}]}};r.inherits(s,i),t.JsonHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/json",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/json_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./json_highlight_rules").JsonHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode,f=e("../worker/worker_client").WorkerClient,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(l,i),function(){this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);if(e=="start"){var i=t.match(/^.*[\{\(\[]\s*$/);i&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new f(["ace"],"ace/mode/json_worker","JsonWorker");return t.attachToDocument(e.getDocument()),t.on("error",function(t){e.setAnnotations([t.data])}),t.on("ok",function(){e.clearAnnotations()}),t},this.$id="ace/mode/json"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-jsoniq.js b/dist/assets/js/vendor/ace-nc/mode-jsoniq.js
            new file mode 100644
            index 0000000000..11ddf245c9
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-jsoniq.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/xquery/jsoniq_lexer",["require","exports","module"],function(e,t,n){n.exports=function r(t,n,i){function s(u,a){if(!n[u]){if(!t[u]){var f=typeof e=="function"&&e;if(!a&&f)return f(u,!0);if(o)return o(u,!0);throw new Error("Cannot find module '"+u+"'")}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return s(n?n:e)},l,l.exports,r,t,n,i)}return n[u].exports}var o=typeof e=="function"&&e;for(var u=0;u<i.length;u++)s(i[u]);return s}({1:[function(e,t,n){var r=n.JSONiqTokenizer=function i(e,t){function r(e,t){E=t,S=e,x=e.length,s(0,0,0)}function s(e,t,n){m=t,g=t,y=e,b=t,w=n,N=n,E.reset(S)}function o(){E.startNonterminal("EQName",g);switch(y){case 80:f(80);break;case 94:f(94);break;case 118:f(118);break;case 119:f(119);break;case 122:f(122);break;case 143:f(143);break;case 150:f(150);break;case 163:f(163);break;case 183:f(183);break;case 189:f(189);break;case 214:f(214);break;case 224:f(224);break;case 225:f(225);break;case 241:f(241);break;case 242:f(242);break;case 251:f(251);break;default:u()}E.endNonterminal("EQName",g)}function u(){E.startNonterminal("FunctionName",g);switch(y){case 17:f(17);break;case 68:f(68);break;case 71:f(71);break;case 72:f(72);break;case 73:f(73);break;case 77:f(77);break;case 78:f(78);break;case 82:f(82);break;case 86:f(86);break;case 87:f(87);break;case 88:f(88);break;case 91:f(91);break;case 92:f(92);break;case 101:f(101);break;case 103:f(103);break;case 106:f(106);break;case 107:f(107);break;case 108:f(108);break;case 109:f(109);break;case 110:f(110);break;case 111:f(111);break;case 116:f(116);break;case 117:f(117);break;case 120:f(120);break;case 121:f(121);break;case 124:f(124);break;case 126:f(126);break;case 127:f(127);break;case 129:f(129);break;case 132:f(132);break;case 133:f(133);break;case 134:f(134);break;case 135:f(135);break;case 144:f(144);break;case 146:f(146);break;case 148:f(148);break;case 149:f(149);break;case 151:f(151);break;case 157:f(157);break;case 158:f(158);break;case 160:f(160);break;case 161:f(161);break;case 162:f(162);break;case 168:f(168);break;case 170:f(170);break;case 172:f(172);break;case 176:f(176);break;case 178:f(178);break;case 179:f(179);break;case 180:f(180);break;case 182:f(182);break;case 184:f(184);break;case 196:f(196);break;case 198:f(198);break;case 199:f(199);break;case 200:f(200);break;case 204:f(204);break;case 210:f(210);break;case 211:f(211);break;case 216:f(216);break;case 217:f(217);break;case 218:f(218);break;case 222:f(222);break;case 227:f(227);break;case 233:f(233);break;case 234:f(234);break;case 235:f(235);break;case 246:f(246);break;case 247:f(247);break;case 248:f(248);break;case 252:f(252);break;case 254:f(254);break;case 258:f(258);break;case 264:f(264);break;case 268:f(268);break;case 272:f(272);break;case 70:f(70);break;case 79:f(79);break;case 81:f(81);break;case 83:f(83);break;case 84:f(84);break;case 89:f(89);break;case 96:f(96);break;case 99:f(99);break;case 100:f(100);break;case 102:f(102);break;case 104:f(104);break;case 123:f(123);break;case 130:f(130);break;case 131:f(131);break;case 139:f(139);break;case 152:f(152);break;case 153:f(153);break;case 159:f(159);break;case 169:f(169);break;case 190:f(190);break;case 197:f(197);break;case 201:f(201);break;case 220:f(220);break;case 223:f(223);break;case 226:f(226);break;case 232:f(232);break;case 238:f(238);break;case 249:f(249);break;case 250:f(250);break;case 255:f(255);break;case 259:f(259);break;case 260:f(260);break;case 261:f(261);break;case 265:f(265);break;case 95:f(95);break;case 174:f(174);break;default:f(219)}E.endNonterminal("FunctionName",g)}function a(){E.startNonterminal("NCName",g);switch(y){case 28:f(28);break;case 68:f(68);break;case 73:f(73);break;case 77:f(77);break;case 78:f(78);break;case 82:f(82);break;case 86:f(86);break;case 87:f(87);break;case 88:f(88);break;case 92:f(92);break;case 103:f(103);break;case 107:f(107);break;case 111:f(111);break;case 116:f(116);break;case 120:f(120);break;case 121:f(121);break;case 124:f(124);break;case 126:f(126);break;case 129:f(129);break;case 135:f(135);break;case 144:f(144);break;case 146:f(146);break;case 148:f(148);break;case 149:f(149);break;case 158:f(158);break;case 160:f(160);break;case 161:f(161);break;case 162:f(162);break;case 170:f(170);break;case 172:f(172);break;case 176:f(176);break;case 178:f(178);break;case 179:f(179);break;case 184:f(184);break;case 196:f(196);break;case 198:f(198);break;case 199:f(199);break;case 218:f(218);break;case 222:f(222);break;case 234:f(234);break;case 235:f(235);break;case 246:f(246);break;case 247:f(247);break;case 252:f(252);break;case 264:f(264);break;case 268:f(268);break;case 71:f(71);break;case 72:f(72);break;case 80:f(80);break;case 91:f(91);break;case 94:f(94);break;case 101:f(101);break;case 106:f(106);break;case 108:f(108);break;case 109:f(109);break;case 110:f(110);break;case 117:f(117);break;case 118:f(118);break;case 119:f(119);break;case 122:f(122);break;case 127:f(127);break;case 132:f(132);break;case 133:f(133);break;case 134:f(134);break;case 143:f(143);break;case 150:f(150);break;case 151:f(151);break;case 157:f(157);break;case 163:f(163);break;case 168:f(168);break;case 180:f(180);break;case 182:f(182);break;case 183:f(183);break;case 189:f(189);break;case 200:f(200);break;case 204:f(204);break;case 210:f(210);break;case 211:f(211);break;case 214:f(214);break;case 216:f(216);break;case 217:f(217);break;case 224:f(224);break;case 225:f(225);break;case 227:f(227);break;case 233:f(233);break;case 241:f(241);break;case 242:f(242);break;case 248:f(248);break;case 251:f(251);break;case 254:f(254);break;case 258:f(258);break;case 260:f(260);break;case 272:f(272);break;case 70:f(70);break;case 79:f(79);break;case 81:f(81);break;case 83:f(83);break;case 84:f(84);break;case 89:f(89);break;case 96:f(96);break;case 99:f(99);break;case 100:f(100);break;case 102:f(102);break;case 104:f(104);break;case 123:f(123);break;case 130:f(130);break;case 131:f(131);break;case 139:f(139);break;case 152:f(152);break;case 153:f(153);break;case 159:f(159);break;case 169:f(169);break;case 190:f(190);break;case 197:f(197);break;case 201:f(201);break;case 220:f(220);break;case 223:f(223);break;case 226:f(226);break;case 232:f(232);break;case 238:f(238);break;case 249:f(249);break;case 250:f(250);break;case 255:f(255);break;case 259:f(259);break;case 261:f(261);break;case 265:f(265);break;case 95:f(95);break;case 174:f(174);break;default:f(219)}E.endNonterminal("NCName",g)}function f(e){y==e?(l(),E.terminal(i.TOKEN[y],b,w>x?x:w),m=b,g=w,y=0):d(b,w,0,y,e)}function l(){g!=b&&(m=g,g=b,E.whitespace(m,g))}function c(e){var t;for(;;){t=C(e);if(t!=30)break}return t}function h(e){y==0&&(y=c(e),b=T,w=N)}function p(e){y==0&&(y=C(e),b=T,w=N)}function d(e,t,r,i,s){throw new n.ParseException(e,t,r,i,s)}function C(e){var t=!1;T=N;var n=N,r=i.INITIAL[e],s=0;for(var o=r&4095;o!=0;){var u,a=n<x?S.charCodeAt(n):0;++n;if(a<128)u=i.MAP0[a];else if(a<55296){var f=a>>4;u=i.MAP1[(a&15)+i.MAP1[(f&31)+i.MAP1[f>>5]]]}else{if(a<56320){var f=n<x?S.charCodeAt(n):0;f>=56320&&f<57344&&(++n,a=((a&1023)<<10)+(f&1023)+65536,t=!0)}var l=0,c=5;for(var h=3;;h=c+l>>1){if(i.MAP2[h]>a)c=h-1;else{if(!(i.MAP2[6+h]<a)){u=i.MAP2[12+h];break}l=h+1}if(l>c){u=0;break}}}s=o;var p=(u<<12)+o-1;o=i.TRANSITION[(p&15)+i.TRANSITION[p>>4]],o>4095&&(r=o,o&=4095,N=n)}r>>=12;if(r==0){N=n-1;var f=N<x?S.charCodeAt(N):0;return f>=56320&&f<57344&&--N,d(T,N,s,-1,-1)}if(t)for(var v=r>>9;v>0;--v){--N;var f=N<x?S.charCodeAt(N):0;f>=56320&&f<57344&&--N}else N-=r>>9;return(r&511)-1}r(e,t);var n=this;this.ParseException=function(e,t,n,r,i){var s=e,o=t,u=n,a=r,f=i;this.getBegin=function(){return s},this.getEnd=function(){return o},this.getState=function(){return u},this.getExpected=function(){return f},this.getOffending=function(){return a},this.getMessage=function(){return a<0?"lexical analysis failed":"syntax error"}},this.getInput=function(){return S},this.getOffendingToken=function(e){var t=e.getOffending();return t>=0?i.TOKEN[t]:null},this.getExpectedTokenSet=function(e){var t;return e.getExpected()<0?t=i.getTokenSet(-e.getState()):t=[i.TOKEN[e.getExpected()]],t},this.getErrorMessage=function(e){var t=this.getExpectedTokenSet(e),n=this.getOffendingToken(e),r=S.substring(0,e.getBegin()),i=r.split("\n"),s=i.length,o=i[s-1].length+1,u=e.getEnd()-e.getBegin();return e.getMessage()+(n==null?"":", found "+n)+"\nwhile expecting "+(t.length==1?t[0]:"["+t.join(", ")+"]")+"\n"+(u==0||n!=null?"":"after successfully scanning "+u+" characters beginning ")+"at line "+s+", column "+o+":\n..."+S.substring(e.getBegin(),Math.min(S.length,e.getBegin()+64))+"..."},this.parse_start=function(){E.startNonterminal("start",g),h(14);switch(y){case 58:f(58);break;case 57:f(57);break;case 59:f(59);break;case 43:f(43);break;case 45:f(45);break;case 44:f(44);break;case 37:f(37);break;case 41:f(41);break;case 277:f(277);break;case 274:f(274);break;case 42:f(42);break;case 46:f(46);break;case 52:f(52);break;case 65:f(65);break;case 66:f(66);break;case 49:f(49);break;case 51:f(51);break;case 56:f(56);break;case 54:f(54);break;case 36:f(36);break;case 276:f(276);break;case 40:f(40);break;case 5:f(5);break;case 4:f(4);break;case 6:f(6);break;case 15:f(15);break;case 16:f(16);break;case 18:f(18);break;case 19:f(19);break;case 20:f(20);break;case 8:f(8);break;case 9:f(9);break;case 7:f(7);break;case 35:f(35);break;default:o()}E.endNonterminal("start",g)},this.parse_StartTag=function(){E.startNonterminal("StartTag",g),h(8);switch(y){case 61:f(61);break;case 53:f(53);break;case 29:f(29);break;case 60:f(60);break;case 37:f(37);break;case 41:f(41);break;default:f(35)}E.endNonterminal("StartTag",g)},this.parse_TagContent=function(){E.startNonterminal("TagContent",g),p(11);switch(y){case 25:f(25);break;case 9:f(9);break;case 10:f(10);break;case 58:f(58);break;case 57:f(57);break;case 21:f(21);break;case 31:f(31);break;case 275:f(275);break;case 278:f(278);break;case 274:f(274);break;default:f(35)}E.endNonterminal("TagContent",g)},this.parse_AposAttr=function(){E.startNonterminal("AposAttr",g),p(10);switch(y){case 23:f(23);break;case 27:f(27);break;case 21:f(21);break;case 31:f(31);break;case 275:f(275);break;case 278:f(278);break;case 274:f(274);break;case 41:f(41);break;default:f(35)}E.endNonterminal("AposAttr",g)},this.parse_QuotAttr=function(){E.startNonterminal("QuotAttr",g),p(9);switch(y){case 22:f(22);break;case 26:f(26);break;case 21:f(21);break;case 31:f(31);break;case 275:f(275);break;case 278:f(278);break;case 274:f(274);break;case 37:f(37);break;default:f(35)}E.endNonterminal("QuotAttr",g)},this.parse_CData=function(){E.startNonterminal("CData",g),p(1);switch(y){case 14:f(14);break;case 67:f(67);break;default:f(35)}E.endNonterminal("CData",g)},this.parse_XMLComment=function(){E.startNonterminal("XMLComment",g),p(0);switch(y){case 12:f(12);break;case 50:f(50);break;default:f(35)}E.endNonterminal("XMLComment",g)},this.parse_PI=function(){E.startNonterminal("PI",g),p(3);switch(y){case 13:f(13);break;case 62:f(62);break;case 63:f(63);break;default:f(35)}E.endNonterminal("PI",g)},this.parse_Pragma=function(){E.startNonterminal("Pragma",g),p(2);switch(y){case 11:f(11);break;case 38:f(38);break;case 39:f(39);break;default:f(35)}E.endNonterminal("Pragma",g)},this.parse_Comment=function(){E.startNonterminal("Comment",g),p(4);switch(y){case 55:f(55);break;case 44:f(44);break;case 32:f(32);break;default:f(35)}E.endNonterminal("Comment",g)},this.parse_CommentDoc=function(){E.startNonterminal("CommentDoc",g),p(6);switch(y){case 33:f(33);break;case 34:f(34);break;case 55:f(55);break;case 44:f(44);break;default:f(35)}E.endNonterminal("CommentDoc",g)},this.parse_QuotString=function(){E.startNonterminal("QuotString",g),p(5);switch(y){case 3:f(3);break;case 2:f(2);break;case 1:f(1);break;case 37:f(37);break;default:f(35)}E.endNonterminal("QuotString",g)},this.parse_AposString=function(){E.startNonterminal("AposString",g),p(7);switch(y){case 21:f(21);break;case 31:f(31);break;case 23:f(23);break;case 24:f(24);break;case 41:f(41);break;default:f(35)}E.endNonterminal("AposString",g)},this.parse_Prefix=function(){E.startNonterminal("Prefix",g),h(13),l(),a(),E.endNonterminal("Prefix",g)},this.parse__EQName=function(){E.startNonterminal("_EQName",g),h(12),l(),o(),E.endNonterminal("_EQName",g)};var v,m,g,y,b,w,E,S,x,T,N};r.getTokenSet=function(e){var t=[],n=e<0?-e:INITIAL[e]&4095;for(var i=0;i<279;i+=32){var s=i,o=(i>>5)*2066+n-1,u=o>>2,a=u>>2,f=r.EXPECTED[(o&3)+r.EXPECTED[(u&3)+r.EXPECTED[(a&3)+r.EXPECTED[a>>2]]]];for(;f!=0;f>>>=1,++s)(f&1)!=0&&t.push(r.TOKEN[s])}return t},r.MAP0=[67,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,18,18,18,18,18,18,18,18,19,20,21,22,23,24,25,26,27,28,29,30,27,31,31,31,31,31,31,31,31,31,31,32,31,31,33,31,31,31,31,31,31,34,35,36,37,31,37,38,39,40,41,42,43,44,45,46,31,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,31,62,63,64,65,37],r.MAP1=[108,124,214,214,214,214,214,214,214,214,214,214,214,214,214,214,156,181,181,181,181,181,214,215,213,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,247,261,277,293,309,347,363,379,416,416,416,408,331,323,331,323,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,433,433,433,433,433,433,433,316,331,331,331,331,331,331,331,331,394,416,416,417,415,416,416,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,330,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,416,67,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,18,18,18,18,18,18,18,18,19,20,21,22,23,24,25,26,27,28,29,30,27,31,31,31,31,31,31,31,31,31,31,31,31,31,31,37,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,32,31,31,33,31,31,31,31,31,31,34,35,36,37,31,37,38,39,40,41,42,43,44,45,46,31,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,31,62,63,64,65,37,37,37,37,37,37,37,37,37,37,37,37,31,31,37,37,37,37,37,37,37,66,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66],r.MAP2=[57344,63744,64976,65008,65536,983040,63743,64975,65007,65533,983039,1114111,37,31,37,31,31,37],r.INITIAL=[1,2,49155,57348,5,6,7,8,9,10,11,12,13,14,15],r.TRANSITION=[19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,17408,19288,17439,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,22126,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17672,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,19469,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,36919,18234,18262,18278,18294,18320,18336,18361,18397,18419,18432,18304,18448,18485,18523,18553,18583,18599,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,18825,18841,18871,18906,18944,18960,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19074,36169,17439,36866,17466,36890,36866,22314,19105,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,22126,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17672,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,19469,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,36919,18234,18262,18278,18294,18320,18336,18361,18397,18419,18432,18304,18448,18485,18523,18553,18583,18599,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,18825,18841,18871,18906,18944,18960,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22182,19288,19121,36866,17466,18345,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19273,19552,19304,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19332,17423,19363,36866,17466,17537,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,18614,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,19391,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,19427,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36154,19288,19457,36866,17466,17740,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22780,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22375,22197,18469,36866,17466,36890,36866,21991,24018,22987,17556,17575,22288,17486,17509,17525,18373,21331,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,19485,19501,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19537,22390,19568,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19596,19611,19457,36866,17466,36890,36866,18246,19627,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22242,20553,19457,36866,17466,36890,36866,18648,30477,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36472,19288,19457,36866,17466,17809,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,21770,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,19643,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,19672,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,20538,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,17975,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22345,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19726,19742,21529,24035,23112,26225,23511,27749,27397,24035,34360,24035,24036,23114,35166,23114,23114,19758,23511,35247,23511,23511,28447,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,24254,19821,23511,23511,23511,23511,23512,19441,36539,24035,24035,24035,24035,19846,19869,23114,23114,23114,28618,32187,19892,23511,23511,23511,34585,20402,36647,24035,24035,24036,23114,33757,23114,23114,23029,20271,23511,27070,23511,23511,30562,24035,24035,29274,26576,23114,23114,31118,23036,29695,23511,23511,32431,23634,30821,24035,23110,19913,23114,23467,31261,23261,34299,19932,24035,32609,19965,35389,19984,27689,19830,29391,29337,20041,22643,35619,33728,20062,20121,20166,35100,26145,20211,23008,19876,20208,20227,25670,20132,26578,27685,20141,20243,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36094,19288,19457,36866,17466,21724,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22735,19552,20287,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22750,19288,21529,24035,23112,28056,23511,29483,28756,24035,24035,24035,24036,23114,23114,23114,23114,20327,23511,23511,23511,23511,31156,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,24254,20371,23511,23511,23511,23511,27443,20395,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,29457,29700,23511,23511,23511,23511,33444,20402,24035,24035,24035,24036,23114,23114,23114,23114,28350,20421,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,20447,20475,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,20523,22257,20569,20783,21715,17603,20699,20837,20614,20630,21149,20670,21405,17486,17509,17525,18373,19179,20695,20716,20732,20755,19194,18042,21641,20592,20779,20598,21412,17470,17591,20896,17468,17619,20799,20700,21031,20744,20699,20828,18075,21259,20581,20853,18048,20868,20884,17756,17784,17800,17825,17854,21171,21200,20931,20947,21378,20955,20971,18086,20645,21002,20986,18178,17960,18012,18381,18064,29176,21044,21438,21018,21122,21393,21060,21844,21094,20654,17493,18150,18166,18214,25967,20763,21799,21110,21830,21138,21246,21301,18336,18361,21165,21187,20812,21216,21232,21287,21317,18553,21347,21363,21428,21454,21271,21483,21499,21515,21575,21467,18712,21591,21633,21078,18189,18198,20679,21657,21701,21074,21687,21740,21756,21786,21815,21860,21876,21892,21946,21962,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36457,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,36813,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,21981,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,22151,22007,18884,17900,17922,17944,18178,17960,18012,18381,18064,27898,17884,18890,17906,17928,22042,25022,18130,36931,36963,17493,18150,18166,22070,22112,25026,18134,36935,18262,18278,18294,18320,18336,18361,22142,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36109,19288,18469,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22167,19288,19457,36866,17466,17768,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22227,36487,22273,36866,17466,36890,36866,19316,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18749,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,22304,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,19580,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22330,19089,19457,36866,17466,18721,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22765,19347,19457,36866,17466,36890,36866,18114,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29116,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34541,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,22540,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29116,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29908,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29116,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22561,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,23837,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22584,23511,23511,23511,23511,29116,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,27443,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,22839,23511,23511,23511,23511,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36442,19288,21605,24035,23112,28137,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,31568,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22690,19288,19457,36866,17466,36890,36866,21991,27584,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,22659,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22360,19552,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22675,22811,19457,36866,17466,36890,36866,19133,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,22827,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36139,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36064,19288,22865,22881,32031,22897,22913,22956,29939,24035,24035,24035,23003,23114,23114,23114,23024,22420,23511,23511,23511,23052,29116,23073,29268,24035,25563,26915,23106,23131,23114,23114,23159,23181,23197,23248,23511,23511,23282,23305,22493,32364,24035,33472,30138,26325,31770,33508,27345,33667,23114,23321,23473,23351,35793,36576,23511,23375,22500,24145,24035,29197,20192,24533,23440,23114,19017,23459,22839,23489,23510,23511,33563,23528,32076,25389,24035,26576,23561,23583,23114,32683,22516,23622,23655,23511,23634,35456,37144,23110,23683,34153,20499,32513,25824,23705,24035,24035,23111,23114,19874,27078,33263,19830,24035,23112,19872,27741,23266,24036,23114,30243,20507,32241,20150,31862,27464,35108,23727,23007,35895,34953,26578,27685,20141,24569,31691,19787,33967,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36427,19552,21605,24035,23112,32618,23511,29483,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,29116,19803,24035,24035,24035,27027,26576,23114,23114,23114,31471,23756,22468,23511,23511,23511,34687,23772,22493,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34564,23788,24035,24035,24035,21559,23828,23114,23114,23114,25086,22839,23853,23511,23511,23511,23876,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,31761,23909,23953,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36049,19288,21605,30825,23112,23987,23511,24003,31001,27617,24034,24035,24036,24052,24089,23114,23114,22420,24109,24168,23511,23511,29116,24188,27609,20017,29516,24035,26576,24222,19968,23114,24252,33811,22468,24270,33587,23511,24320,27443,22493,24035,24035,24035,24035,24339,23113,23114,23114,23114,28128,28618,29700,23511,23511,23511,28276,34564,20402,24035,24035,32929,24036,23114,23114,23114,24357,23029,22839,23511,23511,23511,24377,25645,24035,34112,24035,26576,23114,26643,23114,32683,22516,23511,25638,23511,23711,24035,24395,27809,23114,24414,20499,24432,30917,23628,24035,30680,23111,23114,30233,27078,25748,24452,24035,23112,19872,27741,23266,24036,23114,24475,19829,26577,26597,26154,24519,24556,24596,23007,20046,20132,26578,24634,20141,24569,31691,24679,24727,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36412,19288,21605,19943,34861,32618,26027,29483,32016,32050,36233,24776,35574,24801,24819,32671,31289,22420,24868,24886,20087,26849,29116,19803,24035,24035,24035,36228,26576,23114,23114,23114,24981,33811,22468,23511,23511,23511,29028,27443,22493,24923,27965,24035,24035,32797,24946,23443,23114,23114,29636,24997,22849,28252,23511,23511,23511,25042,25110,24035,24035,34085,24036,25133,23114,23114,25152,23029,22839,25169,23511,36764,23511,25645,30403,24035,25186,26576,31806,24093,25212,32683,22516,32713,26245,34293,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,24035,32406,23111,23114,28676,30944,27689,25234,24035,23112,19872,37063,23266,24036,23114,30243,20379,26100,29218,20211,30105,25257,25284,23007,20046,20132,26578,27685,20141,24569,24834,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36034,19288,21671,25314,25072,25330,25346,25362,29939,29951,35288,29984,23812,27216,25405,25424,30456,22584,26292,25461,25480,31592,29116,25516,34963,25545,27007,25579,33937,25614,25661,25686,34872,25702,25718,25734,25769,25795,25811,25840,22493,26533,25856,24035,25876,30763,27481,25909,23114,28987,25936,25954,29700,25983,23511,31412,26043,26063,22568,29241,29592,26116,31216,35383,26170,34783,26194,26221,22839,26241,26261,22477,26283,26308,27306,31035,24655,26576,29854,33386,26341,32683,22516,32153,30926,26361,19996,26381,35463,26397,26424,34646,26478,35605,31386,26494,35567,31964,22940,23689,25218,30309,32289,19830,33605,23112,32109,27733,27084,24496,35886,35221,26525,36602,26549,26558,26574,26594,26613,26629,26666,26700,26578,27685,23740,24285,31691,26733,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36397,19552,18991,25887,28117,32618,26776,29483,29939,26802,24035,24035,24036,28664,23114,23114,23114,22420,30297,23511,23511,23511,29116,19803,24035,24035,24035,25559,26576,23114,23114,23114,30525,33811,22468,23511,23511,23511,28725,27443,22493,24035,24035,27249,24035,24035,23113,23114,23114,26827,23114,28618,29700,23511,23511,26845,23511,34564,20402,24035,24035,26979,24036,23114,23114,23114,24974,23029,22839,23511,23511,23511,26865,25645,24035,24035,24035,26576,23114,23114,23114,32683,22516,23511,23511,23511,23634,24035,24035,23110,23114,23114,20499,23511,23261,23628,33305,24035,25598,23114,19874,34253,27689,19830,24035,23112,19872,27741,23266,24036,23114,26886,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,26931,24569,26439,26947,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36019,19288,26995,24035,23112,32618,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,27043,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,27061,23511,23511,23511,23511,23512,24694,24035,24035,29978,24035,24035,23113,23114,33114,23114,23114,30010,29700,23511,35913,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,27155,26576,23114,23114,30447,23036,29695,23511,23511,30935,20099,24152,25529,27100,34461,27121,22625,29156,26009,27137,30422,31903,31655,28870,27171,32439,31731,19830,27232,22612,27265,26786,25494,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,20342,27288,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,27322,27339,28020,27361,27382,29939,24035,24035,32581,24036,23114,23114,23114,27425,22420,23511,23511,23511,27442,28306,19803,24035,24035,24035,24035,26710,23114,23114,23114,23114,32261,22468,23511,23511,23511,23511,35719,24694,29510,24035,24035,24035,24035,26717,23114,23114,23114,23114,28618,32217,23511,23511,23511,23511,34585,20402,24035,24035,24035,27459,23114,23114,23114,36252,23029,20271,23511,23511,23511,28840,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,27480,34483,28401,29761,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36382,19288,21605,27497,27517,28504,28898,27569,29939,29401,27600,27323,27633,19025,27662,23114,27705,22420,20483,27721,23511,27765,28306,19803,23540,24035,24610,27781,27805,26650,23114,28573,32990,25920,22468,26870,23511,26684,34262,34737,25057,34622,24035,24035,23971,24206,27825,27847,23114,23114,27865,27885,35766,27914,23511,23511,32766,32844,27934,28795,26909,27955,26092,27988,25445,28005,28036,28052,21965,23511,32196,19897,28072,28102,36534,21541,23801,28153,28180,28197,28221,23036,32695,28251,28268,28292,23667,34825,23930,24580,28322,28344,31627,28366,25996,23628,24035,24035,23111,23114,19874,27078,27689,35625,33477,33359,27674,28393,33992,24036,23114,30243,19829,28417,28433,28463,23008,19876,20208,23007,20046,20132,28489,28520,20141,24569,31691,19787,28550,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,24035,23112,32618,23511,31507,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,24694,28589,24035,24035,24035,24035,28608,23114,23114,23114,23114,28618,20431,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36004,19288,28634,31951,28565,28702,28718,28741,32544,20175,28792,32086,20105,28811,29059,29862,28856,22420,28886,30354,23359,28922,28306,28952,23888,26320,36506,24035,29331,28968,36609,23114,29003,31661,27061,30649,27366,23511,29023,27918,24694,24035,24035,23893,33094,30867,23113,23114,23114,29044,34184,30010,29700,23511,23511,29081,29102,34585,20402,27789,24035,24035,24036,23114,29132,23114,23114,23029,20271,23511,29153,23511,23511,30562,30174,24035,24035,27409,25438,23114,23114,29172,36668,31332,23511,23511,29192,30144,24035,23110,30203,23114,23467,31544,23261,23628,24035,22545,23111,23114,29213,27078,27689,29234,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,29257,23008,19876,20208,28768,29290,29320,34776,29353,20141,22435,29378,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36367,19288,21605,34616,19006,32618,31497,31507,36216,20184,24035,34393,29424,34668,23114,34900,29447,22420,30360,23511,37089,29473,28306,19803,29499,24398,24035,24035,26576,31799,29532,29550,23114,33811,22468,32298,29571,31184,23511,23512,37127,36628,29589,24035,24135,24035,23113,29608,23114,27831,29634,28618,29652,30037,23511,24172,29671,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,29555,29690,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,29719,24035,23110,29738,23114,23467,34035,29756,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,29777,34364,28181,30243,29799,31920,27272,27185,23008,31126,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29828,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35989,19552,19687,35139,28649,29878,29894,29924,29939,23224,23085,31969,24036,35173,24752,24803,23114,22420,31190,30318,24870,23511,28306,29967,23967,24035,24035,24035,26576,3e4,23114,23114,23114,33811,22468,30026,23511,23511,23511,23512,26078,24035,24035,24035,30053,37137,30071,23114,23114,33368,25136,28618,30723,23511,23511,37096,31356,34585,20402,30092,30127,30160,24036,35740,30219,24960,30259,23029,20271,34042,30285,30342,30376,23289,30055,30400,30419,30438,32640,33532,33514,30472,18792,26267,24323,23057,30493,23639,20008,30196,33188,30517,20075,23511,30541,23628,30578,33928,28776,30594,19874,30610,30637,19830,30677,27646,19872,25779,23266,23232,35016,30243,30696,29812,30712,30746,27206,30779,30807,23007,33395,20132,26578,27685,31703,22928,31691,19787,31079,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36352,19288,23335,30841,26131,30888,30904,30986,29939,24035,24704,31017,20025,23114,26178,31051,31095,22420,23511,22524,31142,31172,28534,31206,35497,25196,24035,28592,24503,23114,31239,31285,23114,31305,31321,31355,31372,31407,23511,30556,24694,24035,27501,19805,24035,24035,23113,23114,31428,24066,23114,28618,29700,23511,31837,18809,23511,34585,31448,24035,24035,24035,23090,23114,23114,23114,23114,31619,35038,23511,23511,23511,23511,33714,24035,33085,24035,29431,23114,31467,23114,23143,31487,23511,31523,23511,35195,36783,24035,30111,23567,23114,23467,31543,31560,23628,24035,24035,23111,23114,19874,30953,31584,34508,24035,31608,26345,37055,23266,31643,31677,31719,31747,31786,31822,26898,23008,19876,31859,23007,20046,20132,26578,27685,20141,24569,31691,31878,31936,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35974,19288,21605,27972,35663,31985,29655,32001,36715,24785,25893,23545,31912,19853,19916,25938,24540,22420,31843,29674,29573,32735,28936,19803,24035,24035,32047,24035,26576,23114,23114,27544,23114,33811,22468,23511,23511,32161,23511,23512,32066,24035,33313,24035,24035,24035,23113,27426,32102,23114,23114,28618,32125,23511,32144,23511,23511,33569,20402,24035,27045,24035,24036,23114,23114,28328,23114,30076,32177,23511,23511,30384,23511,30562,24035,24035,24035,26576,23114,23114,23114,23595,32212,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,22635,25753,32233,32257,32277,19829,26577,26597,20211,23008,19876,32322,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,32352,35285,32380,34196,33016,30661,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,32404,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,32422,23511,23511,23511,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,30269,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,19949,24035,23111,32455,19874,31269,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36337,19552,19209,21617,26509,32475,32491,32529,29939,24035,32578,25241,32597,23114,32634,29007,32656,22420,23511,32729,26365,32751,28306,32788,32882,24035,24035,32813,36727,23114,33182,23114,27553,33235,32829,23511,32706,23511,28906,28377,26962,32881,32904,32898,32920,24035,32953,23114,32977,26408,23114,28164,33006,23511,33039,35774,23511,32306,20402,33076,30872,24035,24036,25408,33110,28979,23114,23029,20271,35835,33130,33054,23511,30562,33148,24035,24035,33167,23114,23114,33775,23036,20459,23511,23511,25464,24646,24035,24035,22446,23114,23114,25627,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,31391,33204,33220,33251,33287,26577,26597,20211,33329,19876,33345,23007,20046,20132,26578,27685,28473,22599,31691,33411,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35959,19288,21907,27243,29843,32618,33427,31507,29939,33460,34090,24035,24036,33493,24416,33530,23114,22420,33548,24379,33585,23511,28306,19803,33603,24202,24035,24035,25593,33749,28205,23114,23114,32388,22468,33853,33060,23511,23511,31339,33621,24035,24035,34397,24618,30757,33663,23114,23114,33683,35684,28618,26678,23511,23511,32506,33699,34585,20402,24035,32562,26973,24036,23114,23114,33377,33773,23029,20271,23511,23511,30621,23511,23860,24035,33791,21553,26576,36558,23114,33809,23036,32857,26047,23511,33827,23634,24035,24035,23110,23114,23114,31252,23511,33845,23628,24035,24459,23111,23114,33869,27078,30791,29783,24035,24742,19872,33895,23266,26462,19710,33879,33919,26577,26597,24123,24930,21930,20208,30501,33953,25268,20252,33983,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36322,19552,23390,33634,35154,34008,34024,34058,35544,34106,34128,26811,33151,34144,34169,34212,23114,34228,34244,34278,34315,23511,34331,34347,34380,34413,24035,24663,26576,34429,34453,34477,29534,33811,22468,34499,34524,34557,25170,34580,35436,23937,34601,24035,24341,26453,23113,34638,34662,23114,24236,28618,34684,34703,34729,23511,35352,34753,34799,24035,34815,32558,34848,34888,35814,34923,23165,29137,23606,30326,30730,34939,33023,30562,36848,34979,24035,24847,34996,23114,23114,35032,29695,35054,23511,23511,35091,33296,35124,24296,28235,24361,36276,32772,35067,35189,27301,30855,24852,22452,35211,35237,35316,25500,35270,23405,24304,35304,29362,24036,23114,35332,19829,26577,26597,20211,23008,19876,20208,35368,28823,23920,32336,35405,20141,24569,31691,35421,35479,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35944,22795,21605,33647,35877,35513,30962,35529,34073,35557,24035,24035,20405,31107,23114,23114,23114,35590,34713,23511,23511,23511,35641,19803,29408,32937,25298,24035,35657,23115,27849,24760,35679,26205,22468,23511,35700,24907,24901,35075,31893,34980,24035,24035,24035,24035,23113,35009,23114,23114,23114,28618,35716,30970,23511,23511,23511,34585,23215,24035,24035,24035,24036,35735,23114,23114,23114,27105,35756,35790,23511,23511,23511,35254,35446,24035,24035,31223,35809,23114,23114,23036,36825,35830,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,31031,20355,19872,33903,23266,24036,23114,28686,19829,26577,26597,20211,23008,23424,20208,24711,31065,24486,26578,27685,20141,19773,35851,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36307,19288,21605,35494,19702,32618,33437,31507,29939,25117,24035,27939,24036,27869,23114,26829,23114,22420,23494,23511,33132,23511,28306,19803,24035,34832,24035,24035,26576,23114,25153,23114,23114,33811,22468,23511,23511,35911,23511,23512,24694,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,35929,19288,21605,25860,23112,36185,23511,36201,29939,24035,24035,24035,24036,23114,23114,23114,23114,22420,23511,23511,23511,23511,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,26748,24035,24035,24035,24035,24035,36249,23114,23114,23114,23114,28618,28835,23511,23511,23511,23511,34585,20402,24035,27151,24035,26760,23114,27989,23114,23114,36268,20271,23511,24436,23511,29703,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36292,19288,21605,36503,21922,32618,34534,31507,36522,24035,33793,24035,35864,23114,23114,36555,23417,22420,23511,23511,36574,26020,28306,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,33811,22468,23511,23511,23511,23511,23512,36592,24035,24035,36625,24035,24035,23113,23114,32961,23114,23114,29618,29700,23511,29086,23511,23511,34585,20402,36644,24035,24035,24036,29740,23114,23114,23114,29065,36663,31527,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36079,19288,21605,31451,23112,36684,23511,36700,29939,24035,24035,24035,30185,23114,23114,23114,27526,22420,23511,23511,23511,32865,28306,19803,36743,24035,27017,24035,26576,27535,23114,31432,23114,33811,22468,33271,23511,32128,23511,23512,24694,24035,27196,24035,24035,24035,23113,32459,23114,23114,23114,28618,29700,33829,36762,23511,23511,34585,20402,24035,36746,24035,29722,23114,23114,34437,23114,34907,20271,23511,23511,18801,23511,23206,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,36837,24035,24035,33739,23114,23114,25094,23511,23261,23628,24035,36780,23111,24073,19874,27078,35344,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22720,19288,36799,36866,17466,36890,36864,21991,22211,22987,17556,17575,22288,17486,17509,17525,18373,17631,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,36883,36906,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,22705,19288,19457,36866,17466,36890,36866,19375,22971,22987,17556,17575,22288,17486,17509,17525,18373,18855,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36124,19288,36951,36866,17466,36890,36866,21991,22404,22987,17556,17575,22288,17486,17509,17525,18373,18567,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,36979,36995,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36139,19288,19457,36866,17466,36890,36866,21991,22971,22987,17556,17575,22288,17486,17509,17525,18373,18027,22984,17553,17572,22285,18462,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,17619,22083,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,36139,19288,21529,24035,23112,23033,23511,31507,25377,24035,24035,24035,24036,23114,23114,23114,23114,37040,23511,23511,23511,23511,28086,19803,24035,24035,24035,24035,26576,23114,23114,23114,23114,24254,37079,23511,23511,23511,23511,23512,34766,24035,24035,24035,24035,24035,23113,23114,23114,23114,23114,28618,29700,23511,23511,23511,23511,34585,20402,24035,24035,24035,24036,23114,23114,23114,23114,23029,20271,23511,23511,23511,23511,30562,24035,24035,24035,26576,23114,23114,23114,23036,29695,23511,23511,23511,23634,24035,24035,23110,23114,23114,23467,23511,23261,23628,24035,24035,23111,23114,19874,27078,27689,19830,24035,23112,19872,27741,23266,24036,23114,30243,19829,26577,26597,20211,23008,19876,20208,23007,20046,20132,26578,27685,20141,24569,31691,19787,29304,20268,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,37112,37160,18469,36866,17466,36890,36866,17656,37174,22987,17556,17575,22288,17486,17509,17525,18373,18537,22984,17553,17572,22285,18780,17990,18622,19411,20306,17996,17689,17470,17591,20896,17468,36883,36906,36867,19404,20299,36866,17647,17862,18921,19514,17705,20311,37017,17728,17756,17784,17800,17825,17854,18403,18928,19521,17712,37008,37024,17878,18884,17900,17922,17944,18178,17960,18012,18381,18064,18218,17884,18890,17906,17928,18102,25022,18130,36931,36963,17493,18150,18166,18214,25010,25026,18134,36935,18262,18278,18294,18320,18336,18361,18397,18274,22096,18304,18448,18485,18523,18553,18583,19149,18638,18497,19656,18664,18680,18507,18696,19164,18712,18737,17681,22026,20906,20915,22054,17838,17450,22022,18765,19225,18841,18871,18906,19241,19257,18976,19041,19056,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,19058,53264,18,49172,57366,24,8192,28,102432,127011,110630,114730,106539,127011,127011,127011,53264,18,18,0,0,57366,0,24,24,24,0,28,28,28,28,102432,0,0,127011,0,2220032,110630,0,0,0,114730,106539,0,2170880,2170880,2170880,2170880,0,0,0,2170880,2170880,2170880,3002368,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2576384,2215936,2215936,2215936,2416640,2424832,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2543616,2215936,2215936,2215936,2215936,2215936,2629632,2215936,2617344,2215936,2215936,2215936,2215936,2215936,2215936,2691072,2215936,2707456,2215936,2715648,2215936,2723840,2764800,2215936,2215936,2797568,2215936,2822144,2215936,2215936,2854912,2215936,2215936,2215936,2912256,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,180224,0,0,2174976,0,0,2170880,2617344,2170880,2170880,2170880,2170880,2170880,2170880,2691072,2170880,2707456,2170880,2715648,2170880,2723840,2764800,2170880,2170880,2797568,2170880,2170880,2797568,2170880,2822144,2170880,2170880,2854912,2170880,2170880,2170880,2912256,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2609152,2215936,2215936,2215936,2215936,2215936,2215936,2654208,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,184599,280,0,2174976,0,0,2215936,3117056,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,544,0,546,0,0,2179072,0,0,0,552,0,0,2170880,2170880,2170880,3117056,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,0,0,0,2158592,2158592,2232320,2232320,0,2240512,2240512,0,0,0,644,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,3129344,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2400256,2215936,2215936,2215936,2215936,2711552,2170880,2170880,2170880,2170880,2170880,2760704,2768896,2789376,2813952,2170880,2170880,2170880,2875392,2904064,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2453504,2457600,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,167936,0,0,0,0,2174976,0,0,2215936,2215936,2514944,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2592768,2215936,2215936,2215936,2215936,2215936,2215936,2215936,32768,0,0,0,0,0,2174976,32768,0,2633728,2215936,2215936,2215936,2215936,2215936,2215936,2711552,2215936,2215936,2215936,2215936,2215936,2760704,2768896,2789376,2813952,2215936,2215936,2215936,2875392,2904064,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2174976,0,65819,2215936,2215936,3031040,2215936,3055616,2215936,2215936,2215936,2215936,3092480,2215936,2215936,3125248,2215936,2215936,2215936,2215936,2215936,2215936,3002368,2215936,2215936,2170880,2170880,2494464,2170880,2170880,0,0,2215936,2215936,2215936,2215936,2215936,2215936,3198976,2215936,0,0,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,0,0,0,2379776,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2445312,2170880,2465792,2473984,2170880,2170880,2170880,2170880,2170880,2170880,2523136,2170880,2170880,2641920,2170880,2170880,2170880,2699264,2170880,2727936,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2879488,2170880,2916352,2170880,2170880,2170880,2879488,2170880,2916352,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3026944,2170880,2170880,3063808,2170880,2170880,3112960,2170880,2170880,3133440,2170880,2170880,3112960,2170880,2170880,3133440,2170880,2170880,2170880,3162112,2170880,2170880,3182592,3186688,2170880,2379776,2215936,2523136,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2596864,2215936,2621440,2215936,2215936,2641920,2215936,2215936,0,0,0,0,0,0,2179072,548,0,0,0,0,287,2170880,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3117056,2170880,2170880,2170880,2170880,2215936,2215936,2699264,2215936,2727936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2879488,2215936,2916352,2215936,2215936,0,0,0,0,188416,0,2179072,0,0,0,0,0,287,2170880,0,2171019,2171019,2171019,2400395,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3031179,2171019,3055755,2171019,2171019,2215936,3133440,2215936,2215936,2215936,3162112,2215936,2215936,3182592,3186688,2215936,0,0,0,0,0,0,0,0,0,0,2171019,2171019,2171019,2171019,2171019,2171019,2523275,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2597003,2171019,2621579,2170880,2170880,2170880,3162112,2170880,2170880,3182592,3186688,2170880,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,24,24,0,4337664,28,2170880,2170880,2170880,2629632,2170880,2170880,2170880,2170880,2719744,2744320,2170880,2170880,2170880,2834432,2838528,2170880,2908160,2170880,2170880,2936832,2215936,2215936,2215936,2215936,2719744,2744320,2215936,2215936,2215936,2834432,2838528,2215936,2908160,2215936,2215936,2936832,2215936,2215936,2985984,2215936,2994176,2215936,2215936,3014656,2215936,3059712,3076096,3088384,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2445312,2215936,2465792,2473984,2215936,2215936,2215936,2215936,2215936,2215936,2171166,2171166,2171166,2171166,2171166,0,0,0,2171166,2171166,2171166,2171166,2171166,2171166,2171019,2171019,2494603,2171019,2171019,2215936,2215936,2215936,3215360,0,0,0,0,0,0,0,0,0,0,0,0,0,2379776,2170880,2170880,2170880,2170880,2985984,2170880,2994176,2170880,2170880,3016168,2170880,3059712,3076096,3088384,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,124,124,0,128,128,2170880,2170880,2170880,3215360,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2486272,2170880,2170880,2506752,2170880,2170880,2170880,2535424,2539520,2170880,2170880,2588672,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2920448,2170880,2170880,2170880,2990080,2170880,2170880,2170880,2170880,3051520,2170880,2170880,2170880,2170880,2170880,2170880,3170304,0,2387968,2392064,2170880,2170880,2433024,2170880,2170880,2170880,3170304,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2486272,2215936,2215936,2506752,2215936,2215936,2215936,2535424,2539520,2215936,2215936,2588672,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2174976,136,0,2215936,2215936,2920448,2215936,2215936,2215936,2990080,2215936,2215936,2215936,2215936,3051520,2215936,2215936,2215936,2215936,2215936,2215936,2215936,3108864,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,3026944,2215936,2215936,3063808,2215936,2215936,3112960,2215936,2215936,2215936,3170304,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2453504,2457600,2170880,2170880,2170880,2486272,2170880,2170880,2506752,2170880,2170880,2170880,2537049,2539520,2170880,2170880,2588672,2170880,2170880,2170880,1508,2170880,2170880,2170880,1512,2170880,2920448,2170880,2170880,2170880,2990080,2170880,2170880,2170880,2461696,2170880,2170880,2170880,2510848,2170880,2170880,2170880,2170880,2580480,2170880,2605056,2637824,2170880,2170880,18,0,0,0,0,0,0,0,0,2220032,0,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2686976,2748416,2170880,2170880,2170880,2924544,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3121152,2170880,2170880,3145728,3158016,3166208,2170880,2420736,2428928,2170880,2478080,2170880,2170880,2170880,2170880,0,0,2170880,2170880,2170880,2170880,2646016,2670592,0,0,3145728,3158016,3166208,2387968,2392064,2215936,2215936,2433024,2215936,2461696,2215936,2215936,2215936,2510848,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,0,0,2170880,2215936,2215936,2580480,2215936,2605056,2637824,2215936,2215936,2686976,2748416,2215936,2215936,2215936,2924544,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,0,286,2170880,2215936,2215936,2215936,2215936,2215936,3121152,2215936,2215936,3145728,3158016,3166208,2387968,2392064,2170880,2170880,2433024,2170880,2461696,2170880,2170880,2170880,2510848,2170880,2170880,1625,2170880,2170880,2580480,2170880,2605056,2637824,2170880,647,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2576384,2170880,2170880,2170880,2170880,2170880,2609152,2170880,2170880,2686976,0,0,2748416,2170880,2170880,0,2170880,2924544,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,24,0,0,28,28,2170880,3141632,2215936,2420736,2428928,2215936,2478080,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2646016,2670592,2752512,2756608,2846720,2961408,2215936,2998272,2215936,3010560,2215936,2215936,2215936,3141632,2170880,2420736,2428928,2752512,2756608,0,2846720,2961408,2170880,2998272,2170880,3010560,2170880,2170880,2170880,3141632,2170880,2170880,2490368,2215936,2490368,2215936,2215936,2215936,2547712,2555904,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2174976,245760,0,3129344,2170880,2170880,2490368,2170880,2170880,2170880,0,0,2547712,2555904,2170880,2170880,2170880,0,0,0,0,0,0,0,0,0,2220032,0,0,45056,0,2584576,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2170880,2170880,2170880,2170880,0,0,0,2170880,2170880,2158592,0,0,0,0,0,0,0,0,2220032,0,0,0,0,0,0,0,0,1482,97,97,97,97,97,97,97,1354,97,97,97,97,97,97,97,97,1148,97,97,97,97,97,97,97,2584576,2170880,2170880,1512,0,2170880,2170880,2170880,2170880,2170880,2170880,2441216,2170880,2527232,2170880,2600960,2170880,2850816,2170880,2170880,2170880,3022848,2215936,2441216,2215936,2527232,2215936,2600960,2215936,2850816,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,0,287,2170880,2215936,3022848,2170880,2441216,2170880,2527232,0,0,2170880,2600960,2170880,0,2850816,2170880,2170880,2170880,2170880,2170880,2523136,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2596864,2170880,2621440,2170880,2170880,2641920,2170880,2170880,2170880,3022848,2170880,2519040,2170880,2170880,2170880,2170880,2170880,2215936,2519040,2215936,2215936,2215936,2215936,2215936,2170880,2170880,2170880,2453504,2457600,2170880,2170880,2170880,2170880,2170880,2170880,2514944,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2592768,2170880,2170880,2519040,0,2024,2170880,2170880,0,2170880,2170880,2170880,2396160,2170880,2170880,2170880,2170880,3018752,2396160,2215936,2215936,2215936,2215936,3018752,2396160,0,2024,2170880,2170880,2170880,2170880,3018752,2170880,2650112,2965504,2170880,2215936,2650112,2965504,2215936,0,0,2170880,2650112,2965504,2170880,2551808,2170880,2551808,2215936,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,141,45,45,67,67,67,67,67,224,67,67,238,67,67,67,67,67,67,67,1288,67,67,67,67,67,67,67,67,67,469,67,67,67,67,67,67,0,2551808,2170880,2170880,2215936,0,2170880,2170880,2215936,0,2170880,2170880,2215936,0,2170880,2977792,2977792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53264,18,49172,57366,24,8192,29,102432,127011,110630,114730,106539,127011,127011,127011,53264,18,18,49172,0,0,0,24,24,24,0,28,28,28,28,102432,127,0,0,0,0,0,0,0,0,0,0,140,2170880,2170880,2170880,2416640,0,0,0,0,2220032,110630,0,0,0,114730,106539,136,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,4256099,4256099,24,24,0,28,28,2170880,2461696,2170880,2170880,2170880,2510848,2170880,2170880,0,2170880,2170880,2580480,2170880,2605056,2637824,2170880,2170880,2170880,2547712,2555904,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3129344,2215936,2215936,543,543,545,545,0,0,2179072,0,550,551,551,0,287,2171166,2171166,18,0,0,0,0,0,0,0,0,2220032,0,0,645,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,149,2584576,2170880,2170880,0,0,2170880,2170880,2170880,2170880,2170880,2170880,2441216,2170880,2527232,2170880,2600960,2519040,0,0,2170880,2170880,0,2170880,2170880,2170880,2396160,2170880,2170880,2170880,2170880,3018752,2396160,2215936,2215936,2215936,2215936,3018752,2396160,0,0,2170880,2170880,2170880,2170880,3018752,2170880,2650112,2965504,53264,18,49172,57366,24,155648,28,102432,155648,155687,114730,106539,0,0,155648,53264,18,18,49172,0,57366,0,24,24,24,0,28,28,28,28,102432,0,0,0,0,2220032,0,94208,0,0,114730,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,208896,18,278528,24,24,0,28,28,53264,18,159765,57366,24,8192,28,102432,0,110630,114730,106539,0,0,0,53264,18,18,49172,0,57366,0,24,24,24,0,28,139394,28,28,102432,131,0,0,0,2220032,110630,0,0,0,114730,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,32768,53264,0,18,18,24,24,0,28,28,0,546,0,0,2183168,0,0,552,832,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2170880,2609152,2170880,2170880,2170880,2170880,2170880,2170880,2654208,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,3198976,2215936,0,1084,0,1088,0,1092,0,0,0,0,0,41606,0,0,0,0,45,45,45,45,45,937,0,0,0,0,2220032,110630,0,0,0,114730,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3198976,2170880,0,0,644,0,0,0,2215936,3117056,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,826,0,828,0,0,2183168,0,0,830,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2592768,2170880,2170880,2170880,2170880,2633728,2170880,2170880,2170880,2170880,2170880,2170880,2711552,2170880,2170880,2170880,2170880,2170880,2760704,53264,18,49172,57366,24,8192,28,172066,172032,110630,172066,106539,0,0,172032,53264,18,18,49172,0,57366,0,24,24,24,16384,28,28,28,28,102432,0,98304,0,0,2220032,110630,0,0,0,0,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3198976,2170880,0,0,45056,0,0,0,53264,18,49172,57366,25,8192,30,102432,0,110630,114730,106539,0,0,176219,53264,18,18,49172,0,57366,0,124,124,124,0,128,128,128,128,102432,128,0,0,0,0,0,0,0,0,0,0,140,2170880,2170880,2170880,2416640,0,546,0,0,2183168,0,65536,552,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2646016,2670592,2752512,2756608,2846720,2961408,2170880,2998272,2170880,3010560,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,3198976,2215936,0,0,0,0,0,0,65536,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,143,45,45,67,67,67,67,67,227,67,67,67,67,67,67,67,67,67,1824,67,1826,67,67,67,67,17,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,32768,120,121,18,18,49172,0,57366,0,24,24,24,0,28,28,28,28,102432,67,67,37139,37139,24853,24853,0,0,2179072,548,0,65820,65820,0,287,97,0,0,97,97,0,97,97,97,45,45,45,45,2033,45,67,67,67,67,0,0,97,97,97,97,45,45,67,67,0,369,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,978,0,546,70179,0,2183168,0,0,552,0,97,97,97,97,97,97,97,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,1013,67,67,67,67,67,67,67,67,67,67,473,67,67,67,67,483,67,67,1025,67,67,67,67,67,67,67,67,67,67,67,67,67,97,97,97,97,97,0,0,97,97,97,97,1119,97,97,97,97,97,97,97,97,97,97,97,97,1359,97,97,97,67,67,1584,67,67,67,67,67,67,67,67,67,67,67,67,67,497,67,67,1659,45,45,45,45,45,45,45,45,45,1667,45,45,45,45,45,169,45,45,45,45,45,45,45,45,45,45,45,1668,45,45,45,45,67,67,1694,67,67,67,67,67,67,67,67,67,67,67,67,67,774,67,67,1713,97,97,97,97,97,97,97,0,97,97,1723,97,97,97,97,0,45,45,45,45,45,45,1538,45,45,45,45,45,1559,45,45,1561,45,45,45,45,45,45,45,687,45,45,45,45,45,45,45,45,448,45,45,45,45,45,45,67,67,67,67,1771,1772,67,67,67,67,67,67,67,67,97,97,97,97,0,0,0,97,67,67,67,67,67,1821,67,67,67,67,67,67,1827,67,67,67,0,0,0,0,0,0,97,97,1614,97,97,97,97,97,603,97,97,605,97,97,608,97,97,97,97,0,1532,45,45,45,45,45,45,45,45,45,45,450,45,45,45,45,67,67,97,97,97,97,97,97,0,0,1839,97,97,97,97,0,0,97,97,97,97,97,45,45,45,45,45,45,45,67,67,67,67,67,67,67,97,1883,97,1885,97,0,1888,0,97,97,0,97,97,1848,97,97,97,97,1852,45,45,45,45,45,45,45,384,391,45,45,45,45,45,45,45,385,45,45,45,45,45,45,45,45,1237,45,45,45,45,45,45,67,0,97,97,97,97,0,0,0,97,97,97,97,97,97,45,45,45,45,45,45,45,1951,45,45,45,45,45,45,45,45,67,67,67,67,1963,97,2023,0,97,97,0,97,97,97,45,45,45,45,45,45,67,67,1994,67,1995,67,67,67,67,67,67,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,97,97,0,0,0,0,2220032,110630,0,0,0,114730,106539,137,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2793472,2805760,2170880,2830336,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3031040,2170880,3055616,2170880,2170880,67,67,37139,37139,24853,24853,0,0,281,549,0,65820,65820,0,287,97,0,0,97,97,0,97,97,97,45,45,2031,2032,45,45,67,67,67,67,67,67,67,67,67,67,67,67,1769,67,0,546,70179,549,549,0,0,552,0,97,97,97,97,97,97,97,45,45,45,45,45,45,1858,45,641,0,0,0,0,41606,926,0,0,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,456,67,0,0,0,1313,0,0,0,1096,1319,0,0,0,0,97,97,97,97,97,97,97,97,1110,97,97,97,97,67,67,67,67,1301,1476,0,0,0,0,1307,1478,0,0,0,0,0,0,0,0,97,97,97,97,1486,97,1487,97,1313,1480,0,0,0,0,1319,0,97,97,97,97,97,97,97,97,97,566,97,97,97,97,97,97,67,67,67,1476,0,1478,0,1480,0,97,97,97,97,97,97,97,45,1853,45,1855,45,45,45,45,53264,18,49172,57366,26,8192,31,102432,0,110630,114730,106539,0,0,225368,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,32768,53264,18,18,49172,163840,57366,0,24,24,229376,0,28,28,28,229376,102432,0,0,0,0,2220167,110630,0,0,0,114730,106539,0,2171019,2171019,2171019,2171019,2592907,2171019,2171019,2171019,2171019,2633867,2171019,2171019,2171019,2171019,2171019,2171019,2654347,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3117195,2171019,2171019,2171019,2171019,2240641,0,0,0,0,0,0,0,0,368,0,140,2171019,2171019,2171019,2416779,2424971,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2617483,2171019,2171019,2642059,2171019,2171019,2171019,2699403,2171019,2728075,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3215499,2215936,2215936,2215936,2215936,2215936,2437120,2215936,2215936,2171019,2822283,2171019,2171019,2855051,2171019,2171019,2171019,2912395,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3002507,2171019,2171019,2215936,2215936,2494464,2215936,2215936,2215936,2171166,2171166,2416926,2425118,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2576670,2171166,2617630,2171166,2171166,2171166,2171166,2171166,2171166,2691358,2171166,2707742,2171166,2715934,2171166,2724126,2765086,2171166,2171166,2797854,2171166,2822430,2171166,2171166,2855198,2171166,2171166,2171166,2912542,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2793758,2806046,2171166,2830622,2171166,2171166,2171166,2171166,2171166,2171166,2171166,3109150,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2543902,2171166,2171166,2171166,2171166,2171166,2629918,2793611,2805899,2171019,2830475,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,0,546,0,0,2183168,0,0,552,0,2171166,2171166,2171166,2400542,2171166,2171166,2171166,0,2171166,2171166,2171166,0,2171166,2920734,2171166,2171166,2171166,2990366,2171166,2171166,2171166,2171166,3117342,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,0,53264,0,18,18,4329472,2232445,0,2240641,4337664,2711691,2171019,2171019,2171019,2171019,2171019,2760843,2769035,2789515,2814091,2171019,2171019,2171019,2875531,2904203,2171019,2171019,3092619,2171019,2171019,3125387,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3199115,2171019,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2453504,2457600,2215936,2215936,2215936,2215936,2215936,2215936,2793472,2805760,2215936,2830336,2215936,2215936,2215936,2215936,2215936,2215936,2170880,2170880,2170880,2170880,2170880,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2494464,2170880,2170880,2171166,2171166,2634014,2171166,2171166,2171166,2171166,2171166,2171166,2711838,2171166,2171166,2171166,2171166,2171166,2760990,2769182,2789662,2814238,2171166,2171166,2171166,2875678,2904350,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,3199262,2171166,0,0,0,0,0,0,0,0,0,2379915,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2445451,2171019,2465931,2474123,2171019,2171019,3113099,2171019,2171019,3133579,2171019,2171019,2171019,3162251,2171019,2171019,3182731,3186827,2171019,2379776,2879627,2171019,2916491,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3027083,2171019,2171019,3063947,2699550,2171166,2728222,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2879774,2171166,2916638,2171166,2171166,2171166,2171166,2171166,2609438,2171166,2171166,2171166,2171166,2171166,2171166,2654494,2171166,2171166,2171166,2171166,2171166,2445598,2171166,2466078,2474270,2171166,2171166,2171166,2171166,2171166,2171166,2523422,2171019,2437259,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2543755,2171019,2171019,2171019,2584715,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2908299,2171019,2171019,2936971,2171019,2171019,2986123,2171019,2994315,2171019,2171019,3014795,2171019,3059851,3076235,3088523,2171166,2171166,2986270,2171166,2994462,2171166,2171166,3014942,2171166,3059998,3076382,3088670,2171166,2171166,2171166,2171166,2171166,2171166,3027230,2171166,2171166,3064094,2171166,2171166,3113246,2171166,2171166,3133726,2506891,2171019,2171019,2171019,2535563,2539659,2171019,2171019,2588811,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2691211,2171019,2707595,2171019,2715787,2171019,2723979,2764939,2171019,2171019,2797707,2215936,2215936,3170304,0,0,0,0,0,0,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2453790,2457886,2171166,2171166,2171166,2486558,2171166,2171166,2507038,2171166,2171166,2171166,2535710,2539806,2171166,2171166,2588958,2171166,2171166,2171166,2171166,2515230,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2593054,2171166,2171166,2171166,2171166,3051806,2171166,2171166,2171166,2171166,2171166,2171166,3170590,0,2388107,2392203,2171019,2171019,2433163,2171019,2461835,2171019,2171019,2171019,2510987,2171019,2171019,2171019,2171019,2580619,2171019,2605195,2637963,2171019,2171019,2171019,2920587,2171019,2171019,2171019,2990219,2171019,2171019,2171019,2171019,3051659,2171019,2171019,2171019,2453643,2457739,2171019,2171019,2171019,2171019,2171019,2171019,2515083,2171019,2171019,2171019,2171019,2646155,2670731,2752651,2756747,2846859,2961547,2171019,2998411,2171019,3010699,2171019,2171019,2687115,2748555,2171019,2171019,2171019,2924683,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3121291,2171019,2171019,2171019,3170443,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2486272,2215936,2215936,2506752,3145867,3158155,3166347,2387968,2392064,2215936,2215936,2433024,2215936,2461696,2215936,2215936,2215936,2510848,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,0,553,2170880,2215936,2215936,2215936,2215936,2215936,3121152,2215936,2215936,3145728,3158016,3166208,2388254,2392350,2171166,2171166,2433310,2171166,2461982,2171166,2171166,2171166,2511134,2171166,2171166,0,2171166,2171166,2580766,2171166,2605342,2638110,2171166,2171166,2171166,2171166,3031326,2171166,3055902,2171166,2171166,2171166,2171166,3092766,2171166,2171166,3125534,2171166,2171166,2171166,3162398,2171166,2171166,3182878,3186974,2171166,0,0,0,2171019,2171019,2171019,2171019,3109003,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2215936,2215936,2215936,2400256,2215936,2215936,2215936,2215936,2171166,2687262,0,0,2748702,2171166,2171166,0,2171166,2924830,2171166,2171166,2171166,2171166,2171166,2171166,2171166,2597150,2171166,2621726,2171166,2171166,2642206,2171166,2171166,2171166,2171166,3121438,2171166,2171166,3146014,3158302,3166494,2171019,2420875,2429067,2171019,2478219,2171019,2171019,2171019,2171019,2547851,2556043,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,3129483,2215936,2171019,3141771,2215936,2420736,2428928,2215936,2478080,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2646016,2670592,2752512,2756608,2846720,2961408,2215936,2998272,2215936,3010560,2215936,2215936,2215936,3141632,2171166,2421022,2429214,2171166,2478366,2171166,2171166,2171166,2171166,0,0,2171166,2171166,2171166,2171166,2646302,2670878,0,0,0,0,37,110630,0,0,0,114730,106539,0,45,45,45,45,45,1405,1406,45,45,45,45,1409,45,45,45,45,45,1415,45,45,45,45,45,45,45,45,45,45,1238,45,45,45,45,67,2752798,2756894,0,2847006,2961694,2171166,2998558,2171166,3010846,2171166,2171166,2171166,3141918,2171019,2171019,2490507,3129344,2171166,2171166,2490654,2171166,2171166,2171166,0,0,2547998,2556190,2171166,2171166,2171166,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,45,167,45,45,45,45,185,187,45,45,198,45,45,0,2171166,2171166,2171166,2171166,2171166,2171166,3129630,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2576523,2171019,2171019,2171019,2171019,2171019,2609291,2171019,2215936,2215936,2215936,2215936,2215936,2215936,3002368,2215936,2215936,2171166,2171166,2494750,2171166,2171166,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,147,2584576,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2171166,2171166,2171166,2171166,0,0,0,2171166,2171166,2171166,2171166,0,0,0,2171166,2171166,2171166,3002654,2171166,2171166,2171019,2171019,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2175257,0,0,2584862,2171166,2171166,0,0,2171166,2171166,2171166,2171166,2171166,2171019,2441355,2171019,2527371,2171019,2601099,2171019,2850955,2171019,2171019,2171019,3022987,2215936,2441216,2215936,2527232,2215936,2600960,2215936,2850816,2215936,2215936,0,0,0,0,0,0,2179072,0,0,0,0,69632,287,2170880,2215936,3022848,2171166,2441502,2171166,2527518,0,0,2171166,2601246,2171166,0,2851102,2171166,2171166,2171166,2171166,2720030,2744606,2171166,2171166,2171166,2834718,2838814,2171166,2908446,2171166,2171166,2937118,3023134,2171019,2519179,2171019,2171019,2171019,2171019,2171019,2215936,2519040,2215936,2215936,2215936,2215936,2215936,2171166,2171166,2171166,3215646,0,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2171019,2486411,2171019,2171019,2171019,2629771,2171019,2171019,2171019,2171019,2719883,2744459,2171019,2171019,2171019,2834571,2838667,2171019,2519326,0,0,2171166,2171166,0,2171166,2171166,2171166,2396299,2171019,2171019,2171019,2171019,3018891,2396160,2215936,2215936,2215936,2215936,3018752,2396446,0,0,2171166,2171166,2171166,2171166,3019038,2171019,2650251,2965643,2171019,2215936,2650112,2965504,2215936,0,0,2171166,2650398,2965790,2171166,2551947,2171019,2551808,2215936,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,144,45,45,67,67,67,67,67,228,67,67,67,67,67,67,67,67,67,1929,97,97,97,97,0,0,0,2552094,2171166,2171019,2215936,0,2171166,2171019,2215936,0,2171166,2171019,2215936,0,2171166,2977931,2977792,2978078,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,1321,97,131072,0,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,24,24,0,28,28,0,140,0,2379776,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2445312,2170880,2465792,2473984,2170880,2170880,2170880,2584576,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2170880,2170880,2170880,3162112,2170880,2170880,3182592,3186688,2170880,0,140,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3002368,2170880,2170880,2215936,2215936,2494464,2215936,2215936,2215936,2215936,2215936,2215936,3215360,544,0,0,0,544,0,546,0,0,0,546,0,0,2183168,0,0,552,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,0,2170880,2170880,2170880,0,2170880,2920448,2170880,2170880,2170880,2990080,2170880,2170880,552,0,0,0,552,0,287,0,2170880,2170880,2170880,2170880,2170880,2437120,2170880,2170880,18,0,0,0,0,0,0,0,0,2220032,0,0,644,0,2215936,2215936,3170304,544,0,546,0,552,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3198976,2170880,0,0,0,140,0,0,53264,18,49172,57366,24,8192,28,102432,249856,110630,114730,106539,0,0,32768,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,151640,53264,18,18,49172,0,57366,0,24,24,24,0,28,28,28,28,0,0,0,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2416640,53264,18,49172,57366,24,8192,28,102432,253952,110630,114730,106539,0,0,32856,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,192512,53264,18,18,49172,0,57366,0,2232445,184320,2232445,0,2240641,2240641,184320,2240641,102432,0,0,0,221184,2220032,110630,0,0,0,114730,106539,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3108864,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2215936,0,0,0,45056,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,0,53264,0,18,18,24,24,0,127,127,53264,18,49172,258071,24,8192,28,102432,0,110630,114730,106539,0,0,32768,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,204800,53264,18,49172,57366,24,27,28,102432,0,110630,114730,106539,0,0,0,53264,18,49172,57366,24,8192,28,33,0,33,33,33,0,0,0,53264,18,18,49172,0,57366,0,24,24,24,16384,28,28,28,28,0,0,0,0,0,0,0,0,0,0,139,2170880,2170880,2170880,2416640,67,67,37139,37139,24853,24853,0,70179,0,0,0,65820,65820,369,287,97,0,0,97,97,0,97,97,97,45,2030,45,45,45,45,67,1573,67,67,67,67,67,67,67,67,67,67,67,1699,67,67,67,67,25403,546,70179,0,0,66365,66365,552,0,97,97,97,97,97,97,97,97,1355,97,97,97,1358,97,97,97,641,0,0,0,925,41606,0,0,0,0,45,45,45,45,45,45,45,1187,45,45,45,45,45,0,1480,0,0,0,0,1319,0,97,97,97,97,97,97,97,97,97,592,97,97,97,97,97,97,97,97,97,97,1531,45,45,45,45,45,45,45,45,45,45,45,45,1680,45,45,45,641,0,924,0,925,41606,0,0,0,0,45,45,45,45,45,45,1186,45,45,45,45,45,45,67,67,37139,37139,24853,24853,0,70179,282,0,0,65820,65820,369,287,97,0,0,97,97,0,97,2028,97,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,1767,67,67,67,0,0,0,0,0,0,1612,97,97,97,97,97,97,0,1785,97,97,97,97,97,97,0,0,97,97,97,97,1790,97,0,0,2170880,2170880,3051520,2170880,2170880,2170880,2170880,2170880,2170880,3170304,241664,2387968,2392064,2170880,2170880,2433024,53264,19,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,274432,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,270336,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,1134711,53264,18,49172,57366,24,8192,28,102432,0,1126440,1126440,1126440,0,0,1126400,53264,18,49172,57366,24,8192,28,102432,36,110630,114730,106539,0,0,217088,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,94,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,96,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,24666,53264,18,18,49172,0,57366,0,24,24,24,126,28,28,28,28,102432,53264,122,123,49172,0,57366,0,24,24,24,0,28,28,28,28,102432,2170880,2170880,4256099,0,0,0,0,0,0,0,0,2220032,0,0,0,0,0,0,0,0,1319,0,0,0,0,97,97,97,97,97,97,97,1109,97,97,97,97,1113,132,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,146,150,45,45,45,45,45,175,45,180,45,186,45,189,45,45,203,67,256,67,67,270,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,97,293,297,97,97,97,97,97,322,97,327,97,333,97,0,0,97,2026,0,2027,97,97,45,45,45,45,45,45,67,67,67,1685,67,67,67,67,67,67,67,1690,67,336,97,97,350,97,97,0,53264,0,18,18,24,24,356,28,28,0,0,0,0,0,0,0,0,0,0,140,2170880,2170880,2170880,2416640,2424832,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2617344,2170880,45,439,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,525,67,67,67,67,67,67,67,67,67,67,67,0,0,0,0,0,0,0,0,0,0,0,0,97,97,97,97,622,97,97,97,97,97,97,97,97,97,97,97,97,1524,97,97,1527,369,648,45,45,45,45,45,45,45,45,45,659,45,45,45,45,408,45,45,45,45,45,45,45,45,45,45,45,1239,45,45,45,67,729,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,762,67,746,67,67,67,67,67,67,67,67,67,759,67,67,67,67,0,0,0,1477,0,1086,0,0,0,1479,0,1090,67,67,796,67,67,799,67,67,67,67,67,67,67,67,67,67,67,67,1291,67,67,67,811,67,67,67,67,67,816,67,67,67,67,67,67,67,37689,544,25403,546,70179,0,0,66365,66365,552,833,97,97,97,97,97,97,97,97,1380,0,0,0,45,45,45,45,45,1185,45,45,45,45,45,45,45,386,45,45,45,45,45,45,45,45,1810,45,45,45,45,45,45,67,97,97,844,97,97,97,97,97,97,97,97,97,857,97,97,97,0,97,97,97,0,97,97,97,97,97,97,97,97,97,97,45,45,45,97,97,97,894,97,97,897,97,97,97,97,97,97,97,97,97,0,0,0,1382,45,45,45,97,909,97,97,97,97,97,914,97,97,97,97,97,97,97,923,67,67,1079,67,67,67,67,67,37689,1085,25403,1089,66365,1093,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,148,1114,97,97,97,97,97,97,1122,97,97,97,97,97,97,97,97,97,606,97,97,97,97,97,97,97,97,97,97,1173,97,97,97,97,97,12288,0,925,0,1179,0,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,145,45,45,67,67,67,67,67,1762,67,67,67,1766,67,67,67,67,67,67,528,67,67,67,67,67,67,67,67,67,97,97,97,97,97,0,1934,67,67,1255,67,67,67,67,67,67,67,67,67,67,67,67,67,1035,67,67,67,67,67,67,1297,67,67,67,67,67,67,0,0,0,0,0,0,97,97,97,97,97,97,97,97,97,97,1111,97,97,97,97,97,97,1327,97,97,97,97,97,97,97,97,97,97,97,97,33344,97,97,97,1335,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,0,97,97,1377,97,97,97,97,97,97,0,1179,0,45,45,45,45,670,45,45,45,45,45,45,45,45,45,45,45,430,45,45,45,45,67,67,1438,67,67,1442,67,67,67,67,67,67,67,67,67,67,67,67,1592,67,67,67,1451,67,67,67,67,67,67,67,67,67,67,1458,67,67,67,67,0,0,1305,0,0,0,0,0,1311,0,0,0,1317,0,0,0,0,0,0,0,97,97,1322,97,97,1491,97,97,1495,97,97,97,97,97,97,97,97,97,97,0,45,45,45,45,45,45,45,45,45,45,45,45,1551,45,1553,45,1504,97,97,97,97,97,97,97,97,97,97,1513,97,97,97,97,0,45,45,45,45,1536,45,45,45,45,1540,45,67,67,67,67,67,1585,67,67,67,67,67,67,67,67,67,67,67,67,1700,67,67,67,97,1648,97,97,97,97,97,97,97,97,0,45,45,45,45,45,45,45,45,45,45,1541,0,97,97,97,97,0,1940,0,97,97,97,97,97,97,45,45,2011,45,45,45,2015,67,67,2017,67,67,67,2021,97,67,67,812,67,67,67,67,67,67,67,67,67,67,67,37689,544,97,97,97,910,97,97,97,97,97,97,97,97,97,97,97,923,0,0,0,45,45,45,45,1184,45,45,45,45,1188,45,45,45,45,1414,45,45,45,1417,45,1419,45,45,45,45,45,443,45,45,45,45,45,45,453,45,45,67,67,67,67,1244,67,67,67,67,1248,67,67,67,67,67,67,67,0,37139,24853,0,0,0,282,41098,65820,97,1324,97,97,97,97,1328,97,97,97,97,97,97,97,97,97,0,0,930,45,45,45,45,97,97,97,97,1378,97,97,97,97,0,1179,0,45,45,45,45,671,45,45,45,45,45,45,45,45,45,45,45,975,45,45,45,45,67,67,1923,67,1925,67,67,1927,67,97,97,97,97,97,0,0,97,97,97,97,1985,45,45,45,45,45,45,1560,45,45,45,45,45,45,45,45,45,946,45,45,950,45,45,45,0,97,97,97,1939,0,0,0,97,1943,97,97,1945,97,45,45,45,669,45,45,45,45,45,45,45,45,45,45,45,45,990,45,45,45,67,257,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,337,97,97,97,97,97,0,53264,0,18,18,24,24,356,28,28,0,0,0,0,0,0,0,0,0,0,370,2170880,2170880,2170880,2416640,401,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,459,461,67,67,67,67,67,67,67,67,475,67,480,67,67,67,67,67,67,1054,67,67,67,67,67,67,67,67,67,67,1698,67,67,67,67,67,484,67,67,487,67,67,67,67,67,67,67,67,67,67,67,67,67,1459,67,67,97,556,558,97,97,97,97,97,97,97,97,572,97,577,97,97,0,0,1896,97,97,97,97,97,97,1903,45,45,45,45,983,45,45,45,45,988,45,45,45,45,45,45,1195,45,45,45,45,45,45,45,45,45,45,1549,45,45,45,45,45,581,97,97,584,97,97,97,97,97,97,97,97,97,97,97,97,97,1153,97,97,369,0,45,45,45,45,45,45,45,45,45,45,45,662,45,45,45,684,45,45,45,45,45,45,45,45,45,45,45,45,1004,45,45,45,67,67,67,749,67,67,67,67,67,67,67,67,67,761,67,67,67,67,67,67,1068,67,67,67,1071,67,67,67,67,1076,794,795,67,67,67,67,67,67,67,67,67,67,67,67,67,67,0,544,97,97,97,97,847,97,97,97,97,97,97,97,97,97,859,97,0,0,2025,97,20480,97,97,2029,45,45,45,45,45,45,67,67,67,1575,67,67,67,67,67,67,67,67,67,1775,67,67,67,97,97,97,97,892,893,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1515,97,993,994,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,992,67,67,67,1284,67,67,67,67,67,67,67,67,67,67,67,67,67,1607,67,67,97,1364,97,97,97,97,97,97,97,97,97,97,97,97,97,97,596,97,45,1556,1557,45,45,45,45,45,45,45,45,45,45,45,45,45,45,696,45,1596,1597,67,67,67,67,67,67,67,67,67,67,67,67,67,67,499,67,97,97,97,1621,97,97,97,97,97,97,97,97,97,97,97,97,97,1346,97,97,97,97,1740,97,97,97,97,45,45,45,45,45,45,45,45,45,45,1678,45,45,45,45,45,67,97,97,97,97,97,97,1836,0,97,97,97,97,97,0,0,97,97,97,1984,97,45,45,45,45,45,45,1808,45,45,45,45,45,45,45,45,67,739,67,67,67,67,67,744,45,45,1909,45,45,45,45,45,45,45,67,1917,67,1918,67,67,67,67,67,67,1247,67,67,67,67,67,67,67,67,67,67,532,67,67,67,67,67,67,1922,67,67,67,67,67,67,67,97,1930,97,1931,97,0,0,97,97,0,97,97,97,45,45,45,45,45,45,67,67,67,67,1576,67,67,67,67,1580,67,67,0,97,97,1938,97,0,0,0,97,97,97,97,97,97,45,45,45,699,45,45,45,704,45,45,45,45,45,45,45,45,987,45,45,45,45,45,45,45,67,67,97,97,97,97,0,0,97,97,97,2006,97,97,97,97,0,45,1533,45,45,45,45,45,45,45,45,45,1416,45,45,45,45,45,45,45,45,722,723,45,45,45,45,45,45,2045,67,67,67,2047,0,0,97,97,97,2051,45,45,67,67,0,0,0,0,925,41606,0,0,0,0,45,45,45,45,45,45,409,45,45,45,45,45,45,45,45,45,1957,45,67,67,67,67,67,1836,97,97,45,67,0,97,45,67,0,97,45,67,0,97,45,45,67,67,67,1761,67,67,67,1764,67,67,67,67,67,67,67,494,67,67,67,67,67,67,67,67,67,787,67,67,67,67,67,67,45,45,420,45,45,422,45,45,425,45,45,45,45,45,45,45,387,45,45,45,45,397,45,45,45,67,460,67,67,67,67,67,67,67,67,67,67,67,67,67,67,515,67,485,67,67,67,67,67,67,67,67,67,67,67,67,67,498,67,67,67,67,67,97,0,2039,97,97,97,97,97,45,45,45,45,1426,45,45,45,67,67,67,67,67,67,67,67,67,1689,67,67,67,97,557,97,97,97,97,97,97,97,97,97,97,97,97,97,97,612,97,582,97,97,97,97,97,97,97,97,97,97,97,97,97,595,97,97,97,97,97,896,97,97,97,97,97,97,97,97,97,97,885,97,97,97,97,97,45,939,45,45,45,45,943,45,45,45,45,45,45,45,45,45,45,1916,67,67,67,67,67,45,67,67,67,67,67,67,67,1015,67,67,67,67,1019,67,67,67,67,67,67,1271,67,67,67,67,67,67,1277,67,67,67,67,67,67,1287,67,67,67,67,67,67,67,67,67,67,804,67,67,67,67,67,1077,67,67,67,67,67,67,67,37689,0,25403,0,66365,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2170880,2170880,2437120,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2543616,2170880,2170880,2170880,2170880,2170880,2629632,1169,97,1171,97,97,97,97,97,97,97,12288,0,925,0,1179,0,0,0,0,925,41606,0,0,0,0,45,45,45,45,936,45,45,67,67,214,67,220,67,67,233,67,243,67,248,67,67,67,67,67,67,1298,67,67,67,67,0,0,0,0,0,0,97,97,97,97,97,1617,97,0,0,0,45,45,45,1183,45,45,45,45,45,45,45,45,45,393,45,45,45,45,45,45,67,67,1243,67,67,67,67,67,67,67,67,67,67,67,67,67,1074,67,67,1281,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,776,1323,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,907,45,1412,45,45,45,45,45,45,45,1418,45,45,45,45,45,45,686,45,45,45,690,45,45,695,45,45,67,67,67,67,67,1465,67,67,67,67,67,67,67,67,67,67,67,97,97,97,1712,97,97,97,97,1741,97,97,97,45,45,45,45,45,45,45,45,45,426,45,45,45,45,45,45,67,67,67,1924,67,67,67,67,67,97,97,97,97,97,0,0,97,97,1983,97,97,45,45,1987,45,1988,45,0,97,97,97,97,0,0,0,1942,97,97,97,97,97,45,45,45,700,45,45,45,45,45,45,45,45,45,45,711,45,45,153,45,45,166,45,176,45,181,45,45,188,191,196,45,204,255,258,263,67,271,67,67,0,37139,24853,0,0,0,282,41098,65820,97,97,97,294,97,300,97,97,313,97,323,97,328,97,97,335,338,343,97,351,97,97,0,53264,0,18,18,24,24,356,28,28,0,0,0,0,0,0,0,0,41098,0,140,45,45,45,45,1404,45,45,45,45,45,45,45,45,45,45,1411,67,67,486,67,67,67,67,67,67,67,67,67,67,67,67,67,1251,67,67,501,67,67,67,67,67,67,67,67,67,67,67,67,513,67,67,67,67,67,67,1443,67,67,67,67,67,67,67,67,67,67,1263,67,67,67,67,67,97,97,583,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1526,97,598,97,97,97,97,97,97,97,97,97,97,97,97,610,97,97,0,97,97,1796,97,97,97,97,97,97,97,45,45,45,45,45,1744,45,45,45,369,0,651,45,653,45,654,45,656,45,45,45,660,45,45,45,45,1558,45,45,45,45,45,45,45,45,1566,45,45,681,45,683,45,45,45,45,45,45,45,45,691,692,694,45,45,45,716,45,45,45,45,45,45,45,45,45,45,45,45,709,45,45,712,45,714,45,45,45,718,45,45,45,45,45,45,45,726,45,45,45,733,45,45,45,45,67,67,67,67,67,67,67,67,67,67,67,67,1691,67,67,747,67,67,67,67,67,67,67,67,67,760,67,67,67,0,0,0,0,0,0,97,1613,97,97,97,97,97,97,1509,97,97,97,97,97,97,97,97,97,0,1179,0,45,45,45,45,67,764,67,67,67,67,768,67,770,67,67,67,67,67,67,67,67,97,97,97,97,0,0,0,1977,67,778,779,781,67,67,67,67,67,67,788,789,67,67,792,793,67,67,67,813,67,67,67,67,67,67,67,67,67,824,37689,544,25403,546,70179,0,0,66365,66365,552,0,836,97,838,97,839,97,841,97,97,97,845,97,97,97,97,97,97,97,97,97,858,97,97,0,1728,97,97,97,0,97,97,97,97,97,97,97,97,97,97,45,1802,45,97,97,862,97,97,97,97,866,97,868,97,97,97,97,97,97,0,0,97,97,1788,97,97,97,0,0,97,97,876,877,879,97,97,97,97,97,97,886,887,97,97,890,891,97,97,97,97,97,97,97,899,97,97,97,903,97,97,97,0,97,97,97,0,97,97,97,97,97,97,97,1646,97,97,97,97,911,97,97,97,97,97,97,97,97,97,922,923,45,955,45,957,45,45,45,45,45,45,45,45,45,45,45,45,195,45,45,45,45,45,981,982,45,45,45,45,45,45,989,45,45,45,45,45,170,45,45,45,45,45,45,45,45,45,45,411,45,45,45,45,45,67,1023,67,67,67,67,67,67,1031,67,1033,67,67,67,67,67,67,67,817,819,67,67,67,67,67,37689,544,67,1065,67,67,67,67,67,67,67,67,67,67,67,67,67,67,516,67,67,1078,67,67,1081,1082,67,67,37689,0,25403,0,66365,0,0,0,0,0,0,0,0,2171166,2171166,2171166,2171166,2171166,2437406,2171166,2171166,97,1115,97,1117,97,97,97,97,97,97,1125,97,1127,97,97,97,0,97,97,97,0,97,97,97,97,1644,97,97,97,0,97,97,97,0,97,97,1642,97,97,97,97,97,97,625,97,97,97,97,97,97,97,97,97,316,97,97,97,97,97,97,97,97,97,1159,97,97,97,97,97,97,97,97,97,97,97,97,97,1502,97,97,97,97,97,1172,97,97,1175,1176,97,97,12288,0,925,0,1179,0,0,0,0,925,41606,0,0,0,0,45,45,45,935,45,45,45,1233,45,45,45,1236,45,45,45,45,45,45,45,67,67,67,67,67,67,1873,67,67,45,45,1218,45,45,45,1223,45,45,45,45,45,45,45,1230,45,45,67,67,215,219,222,67,230,67,67,244,246,249,67,67,67,67,67,67,1882,97,97,97,97,0,0,0,97,97,97,97,97,97,45,1904,45,1905,45,67,67,67,67,67,1258,67,1260,67,67,67,67,67,67,67,67,67,495,67,67,67,67,67,67,67,67,1283,67,67,67,67,67,67,67,1290,67,67,67,67,67,67,67,818,67,67,67,67,67,67,37689,544,67,67,1295,67,67,67,67,67,67,67,67,0,0,0,0,0,0,2174976,0,0,97,97,97,1326,97,97,97,97,97,97,97,97,97,97,97,97,97,1514,97,97,97,97,97,1338,97,1340,97,97,97,97,97,97,97,97,97,97,97,1500,97,97,1503,97,1363,97,97,97,97,97,97,97,1370,97,97,97,97,97,97,97,563,97,97,97,97,97,97,578,97,1375,97,97,97,97,97,97,97,97,0,1179,0,45,45,45,45,685,45,45,45,45,45,45,45,45,45,45,45,1003,45,45,45,45,67,67,67,1463,67,67,67,67,67,67,67,67,67,67,67,67,67,1778,97,97,97,97,97,1518,97,97,97,97,97,97,97,97,97,97,97,97,609,97,97,97,45,1542,45,45,45,45,45,45,45,1548,45,45,45,45,45,1554,45,1570,1571,45,67,67,67,67,67,67,1578,67,67,67,67,67,67,67,1055,67,67,67,67,67,1061,67,67,1582,67,67,67,67,67,67,67,1588,67,67,67,67,67,1594,67,67,67,67,67,97,2038,0,97,97,97,97,97,2044,45,45,45,995,45,45,45,45,1e3,45,45,45,45,45,45,45,1809,45,1811,45,45,45,45,45,67,1610,1611,67,1476,0,1478,0,1480,0,97,97,97,97,97,97,1618,1647,1649,97,97,97,1652,97,1654,1655,97,0,45,45,45,1658,45,45,67,67,216,67,67,67,67,234,67,67,67,67,252,254,1845,97,97,97,97,97,97,97,45,45,45,45,45,45,45,45,945,45,947,45,45,45,45,45,67,67,67,67,67,1881,97,97,97,97,97,0,0,0,97,97,97,97,97,1902,45,45,45,45,45,45,1908,45,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,1921,67,67,67,67,67,67,67,67,97,97,97,97,97,0,0,0,97,97,0,97,1937,97,97,1940,0,0,97,97,97,97,97,97,1947,1948,1949,45,45,45,1952,45,1954,45,45,45,45,1959,1960,1961,67,67,67,67,67,67,1455,67,67,67,67,67,67,67,67,67,67,757,67,67,67,67,67,67,1964,67,1966,67,67,67,67,1971,1972,1973,97,0,0,0,97,97,1104,97,97,97,97,97,97,97,97,97,97,884,97,97,97,889,97,97,1978,97,0,0,1981,97,97,97,97,45,45,45,45,45,45,736,45,67,67,67,67,67,67,67,67,67,67,67,1018,67,67,67,45,67,67,67,67,0,2049,97,97,97,97,45,45,67,67,0,0,0,0,925,41606,0,0,0,0,45,933,45,45,45,45,1234,45,45,45,45,45,45,45,45,45,45,67,97,97,288,97,97,97,97,97,97,317,97,97,97,97,97,97,0,0,97,1787,97,97,97,97,0,0,45,45,378,45,45,45,45,45,390,45,45,45,45,45,45,45,424,45,45,45,431,433,45,45,45,67,1050,67,67,67,67,67,67,67,67,67,67,67,67,67,67,518,67,97,97,97,1144,97,97,97,97,97,97,97,97,97,97,97,97,632,97,97,97,97,97,97,97,1367,97,97,97,97,97,97,97,97,97,97,97,855,97,97,97,97,67,97,97,97,97,97,97,1837,0,97,97,97,97,97,0,0,0,1897,97,97,97,97,97,45,45,45,45,45,1208,45,45,45,45,45,45,45,45,45,45,724,45,45,45,45,45,97,2010,45,45,45,45,45,45,2016,67,67,67,67,67,67,2022,45,2046,67,67,67,0,0,2050,97,97,97,45,45,67,67,0,0,0,0,925,41606,0,0,0,0,932,45,45,45,45,45,1222,45,45,45,45,45,45,45,45,45,45,1227,45,45,45,45,45,133,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,45,701,702,45,45,705,706,45,45,45,45,45,45,703,45,45,45,45,45,45,45,45,45,719,45,45,45,45,45,725,45,45,45,369,649,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1216,25403,546,70179,0,0,66365,66365,552,834,97,97,97,97,97,97,97,1342,97,97,97,97,97,97,97,97,0,97,97,97,97,97,97,97,1799,97,97,45,45,45,1569,45,45,45,1572,67,67,67,67,67,67,67,67,67,67,67,0,0,0,1306,0,67,67,67,1598,67,67,67,67,67,67,67,67,1606,67,67,1609,97,97,97,1650,97,97,1653,97,97,97,0,45,45,1657,45,45,45,1206,45,45,45,45,45,45,45,45,45,45,45,45,1421,45,45,45,1703,67,67,67,67,67,67,67,67,67,67,97,97,1711,97,97,0,1895,0,97,97,97,97,97,97,45,45,45,45,45,958,45,960,45,45,45,45,45,45,45,45,1913,45,45,1915,67,67,67,67,67,67,67,466,67,67,67,67,67,67,481,67,45,1749,45,45,45,45,45,45,45,45,1755,45,45,45,45,45,173,45,45,45,45,45,45,45,45,45,45,974,45,45,45,45,45,67,67,67,67,67,1773,67,67,67,67,67,67,67,97,97,97,97,1886,0,0,0,97,97,67,2035,2036,67,67,97,0,0,97,2041,2042,97,97,45,45,45,45,1662,45,45,45,45,45,45,45,45,45,45,45,1397,45,45,45,45,151,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,437,205,45,67,67,67,218,67,67,67,67,67,67,67,67,67,67,67,1047,67,67,67,67,97,97,97,97,298,97,97,97,97,97,97,97,97,97,97,97,870,97,97,97,97,97,97,97,97,352,97,0,53264,0,18,18,24,24,0,28,28,0,0,0,0,0,0,365,0,41098,0,140,45,45,45,45,45,1427,45,45,67,67,67,67,67,67,67,1435,520,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1037,617,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,923,45,1232,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,67,67,1919,67,1759,45,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1021,45,154,45,162,45,45,45,45,45,45,45,45,45,45,45,45,964,45,45,45,206,45,67,67,67,67,221,67,229,67,67,67,67,67,67,67,67,530,67,67,67,67,67,67,67,67,755,67,67,67,67,67,67,67,67,785,67,67,67,67,67,67,67,67,802,67,67,67,807,67,67,67,97,97,97,97,353,97,0,53264,0,18,18,24,24,0,28,28,0,0,0,0,0,0,366,0,0,0,140,2170880,2170880,2170880,2416640,402,45,45,45,45,45,45,45,410,45,45,45,45,45,45,45,674,45,45,45,45,45,45,45,45,389,45,394,45,45,398,45,45,45,45,441,45,45,45,45,45,447,45,45,45,454,45,45,67,67,67,67,67,67,67,67,67,67,67,1768,67,67,67,67,67,488,67,67,67,67,67,67,67,496,67,67,67,67,67,67,67,1774,67,67,67,67,67,97,97,97,97,0,0,97,97,97,0,97,97,97,97,97,97,97,97,67,67,523,67,67,527,67,67,67,67,67,533,67,67,67,540,97,97,97,585,97,97,97,97,97,97,97,593,97,97,97,97,97,97,1784,0,97,97,97,97,97,97,0,0,97,97,97,97,97,97,0,0,0,18,18,24,24,0,28,28,97,97,620,97,97,624,97,97,97,97,97,630,97,97,97,637,713,45,45,45,45,45,45,721,45,45,45,45,45,45,45,45,1197,45,45,45,45,45,45,45,45,730,732,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,1581,67,45,67,67,67,67,1012,67,67,67,67,67,67,67,67,67,67,67,1059,67,67,67,67,67,1024,67,67,67,67,67,67,67,67,67,67,67,67,67,67,775,67,67,67,67,1066,67,67,67,67,67,67,67,67,67,67,67,67,479,67,67,67,67,67,67,1080,67,67,67,67,37689,0,25403,0,66365,0,0,0,0,0,0,0,287,0,0,0,287,0,2379776,2170880,2170880,97,97,97,1118,97,97,97,97,97,97,97,97,97,97,97,97,920,97,97,0,0,0,0,45,1181,45,45,45,45,45,45,45,45,45,45,45,432,45,45,45,45,45,45,1219,45,45,45,45,45,45,1226,45,45,45,45,45,45,959,45,45,45,45,45,45,45,45,45,184,45,45,45,45,202,45,1241,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1266,67,1268,67,67,67,67,67,67,67,67,67,67,67,67,1279,67,67,67,67,67,272,67,0,37139,24853,0,0,0,0,41098,65820,67,67,67,67,67,1286,67,67,67,67,67,67,67,67,67,1293,67,67,67,1296,67,67,67,67,67,67,67,0,0,0,0,0,281,94,0,0,97,97,97,1366,97,97,97,97,97,97,97,97,97,1373,97,97,18,0,139621,0,0,0,0,0,0,364,0,0,367,0,97,1376,97,97,97,97,97,97,97,0,0,0,45,45,1384,45,45,67,208,67,67,67,67,67,67,237,67,67,67,67,67,67,67,1069,1070,67,67,67,67,67,67,67,0,37140,24854,0,0,0,0,41098,65821,45,1423,45,45,45,45,45,45,67,67,1431,67,67,67,67,67,67,67,1083,37689,0,25403,0,66365,0,0,0,1436,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1830,67,1452,1453,67,67,67,67,1456,67,67,67,67,67,67,67,67,67,771,67,67,67,67,67,67,1461,67,67,67,1464,67,1466,67,67,67,67,67,67,1470,67,67,67,67,67,67,1587,67,67,67,67,67,67,67,67,1595,1489,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1129,97,1505,1506,97,97,97,97,1510,97,97,97,97,97,97,97,97,97,1163,1164,97,97,97,97,97,1516,97,97,97,1519,97,1521,97,97,97,97,97,97,1525,97,97,18,0,139621,0,0,0,0,0,0,364,0,0,367,41606,67,67,67,67,67,1586,67,67,67,67,67,67,67,67,67,67,67,1276,67,67,67,67,67,67,67,67,67,1600,67,67,67,67,67,67,67,67,67,67,67,1301,0,0,0,1307,97,97,1620,97,97,97,97,97,97,97,1627,97,97,97,97,97,97,913,97,97,97,97,919,97,97,97,0,97,97,97,1781,97,97,0,0,97,97,97,97,97,97,0,0,97,97,97,97,97,97,0,1792,1860,45,1862,1863,45,1865,45,67,67,67,67,67,67,67,67,1875,67,1877,1878,67,1880,67,97,97,97,97,97,1887,0,1889,97,97,18,0,139621,0,0,0,0,0,0,364,237568,0,367,0,97,1893,0,0,0,97,1898,1899,97,1901,97,45,45,45,45,45,2014,45,67,67,67,67,67,2020,67,97,1989,45,1990,45,45,45,67,67,67,67,67,67,1996,67,1997,67,67,67,67,67,273,67,0,37139,24853,0,0,0,0,41098,65820,67,67,97,97,97,97,0,0,97,97,2005,0,97,2007,97,97,18,0,139621,0,0,0,642,0,133,364,0,0,367,41606,0,97,97,2056,2057,0,2059,45,67,0,97,45,67,0,97,45,45,67,209,67,67,67,223,67,67,67,67,67,67,67,67,67,786,67,67,67,791,67,67,45,45,940,45,45,45,45,45,45,45,45,45,45,45,45,45,45,727,45,45,67,67,67,67,67,67,67,67,1016,67,67,67,67,67,67,67,67,37689,0,25403,0,66365,0,0,0,133,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,142,45,45,67,210,67,67,67,225,67,67,239,67,67,67,250,67,67,67,67,67,464,67,67,67,67,67,476,67,67,67,67,67,67,67,1709,67,67,67,97,97,97,97,97,97,0,0,97,97,97,97,97,1843,0,67,259,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,289,97,97,97,303,97,97,97,97,97,97,97,97,97,97,901,97,97,97,97,97,339,97,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,0,358,0,0,0,0,0,0,41098,0,140,45,45,45,45,45,1953,45,1955,45,45,45,67,67,67,67,67,67,67,1687,1688,67,67,67,67,45,45,405,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1203,45,458,67,67,67,67,67,67,67,67,67,470,477,67,67,67,67,67,67,67,1970,97,97,97,1974,0,0,0,97,1103,97,97,97,97,97,97,97,97,97,97,97,1372,97,97,97,97,67,522,67,67,67,67,67,67,67,67,67,67,67,536,67,67,67,67,67,67,1696,67,67,67,67,67,67,67,1701,67,555,97,97,97,97,97,97,97,97,97,567,574,97,97,97,97,97,301,97,309,97,97,97,97,97,97,97,97,97,900,97,97,97,905,97,97,97,619,97,97,97,97,97,97,97,97,97,97,97,633,97,97,18,0,139621,0,0,362,0,0,0,364,0,0,367,41606,369,649,45,45,45,45,45,45,45,45,45,45,45,45,663,664,67,67,67,67,750,751,67,67,67,67,758,67,67,67,67,67,67,67,1272,67,67,67,67,67,67,67,67,67,1057,1058,67,67,67,67,67,67,67,67,797,67,67,67,67,67,67,67,67,67,67,67,67,512,67,67,67,97,97,97,97,895,97,97,97,97,97,97,97,97,97,97,97,902,97,97,97,97,67,67,1051,67,67,67,67,67,67,67,67,67,67,67,1062,67,67,67,67,67,491,67,67,67,67,67,67,67,67,67,67,67,1302,0,0,0,1308,97,97,97,97,1145,97,97,97,97,97,97,97,97,97,97,97,1139,97,97,97,97,1156,97,97,97,97,97,97,1161,97,97,97,97,97,1166,97,97,18,640,139621,0,641,0,0,0,0,364,0,0,367,41606,67,67,67,67,1257,67,67,67,67,67,67,67,67,67,67,67,0,0,1305,0,0,97,97,1337,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1630,97,67,1474,67,67,0,0,0,0,0,0,0,0,0,0,0,0,0,2380062,2171166,2171166,97,1529,97,97,0,45,45,45,45,45,45,45,45,45,45,45,1228,45,45,45,45,67,67,67,67,1707,67,67,67,67,67,67,97,97,97,97,97,0,0,0,97,1891,1739,97,97,97,97,97,97,45,45,45,45,45,45,45,45,45,1198,45,1200,45,45,45,45,97,97,1894,0,0,97,97,97,97,97,97,45,45,45,45,45,672,45,45,45,45,45,45,45,45,45,45,45,1420,45,45,45,45,67,67,1965,67,1967,67,67,67,97,97,97,97,0,1976,0,97,97,45,67,0,97,45,67,0,97,45,67,0,97,45,97,97,1979,0,0,97,1982,97,97,97,1986,45,45,45,45,45,735,45,45,67,67,67,67,67,67,67,67,67,67,67,67,67,1770,67,67,2e3,97,97,97,2002,0,97,97,97,0,97,97,97,97,97,97,1798,97,97,97,45,45,45,2034,67,67,67,67,97,0,0,2040,97,97,97,97,45,45,45,45,1752,45,45,45,1753,1754,45,45,45,45,45,45,383,45,45,45,45,45,45,45,45,45,675,45,45,45,45,45,45,438,45,45,45,45,45,445,45,45,45,45,45,45,45,45,67,1430,67,67,67,67,67,67,67,67,67,524,67,67,67,67,67,531,67,67,67,67,67,67,67,67,37689,0,25403,0,66365,0,0,1096,97,97,97,621,97,97,97,97,97,628,97,97,97,97,97,97,0,53264,0,18,18,24,24,356,28,28,665,45,45,45,45,45,45,45,45,45,676,45,45,45,45,45,942,45,45,45,45,45,45,45,45,45,45,707,708,45,45,45,45,763,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,809,810,67,67,67,67,783,67,67,67,67,67,67,67,67,67,67,67,0,1303,0,0,0,97,861,97,97,97,97,97,97,97,97,97,97,97,97,97,97,613,97,45,45,956,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1215,45,67,67,67,67,1027,67,67,67,67,1032,67,67,67,67,67,67,67,67,37689,0,25403,0,66365,0,0,1097,1064,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1075,67,1098,0,0,97,97,97,97,97,97,97,97,97,97,97,97,97,331,97,97,97,97,1158,97,97,97,97,97,97,97,97,97,97,97,97,97,594,97,97,1309,0,0,0,1315,0,0,0,0,0,0,0,0,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1374,97,45,45,1543,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1240,67,67,1583,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1252,67,97,97,97,1635,97,97,97,0,97,97,97,97,97,97,97,97,1800,97,45,45,45,97,97,1793,97,97,97,97,97,97,97,97,97,97,45,45,45,1743,45,45,45,1746,45,0,97,97,97,97,97,1851,97,45,45,45,45,1856,45,45,45,45,1864,45,45,67,67,1869,67,67,67,67,1874,67,0,97,97,45,67,2058,97,45,67,0,97,45,67,0,97,45,45,67,211,67,67,67,67,67,67,240,67,67,67,67,67,67,67,1444,67,67,67,67,67,67,67,67,67,509,67,67,67,67,67,67,67,67,67,268,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,290,97,97,97,305,97,97,319,97,97,97,330,97,97,18,640,139621,0,641,0,0,0,0,364,0,643,367,41606,97,97,348,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,0,364,0,367,41098,369,140,45,45,45,45,380,45,45,45,45,45,45,395,45,45,45,400,369,0,45,45,45,45,45,45,45,45,658,45,45,45,45,45,972,45,45,45,45,45,45,45,45,45,45,427,45,45,45,45,45,745,67,67,67,67,67,67,67,67,756,67,67,67,67,67,67,67,67,37689,1086,25403,1090,66365,1094,0,0,97,843,97,97,97,97,97,97,97,97,854,97,97,97,97,97,97,1121,97,97,97,97,1126,97,97,97,97,45,980,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1400,45,67,67,67,1011,67,67,67,67,67,67,67,67,67,67,67,0,1304,0,0,0,1190,45,45,1193,1194,45,45,45,45,45,1199,45,1201,45,45,45,45,1911,45,45,45,45,45,67,67,67,67,67,67,67,1579,67,67,67,67,45,1205,45,45,45,45,45,45,45,45,1211,45,45,45,45,45,984,45,45,45,45,45,45,45,45,45,45,45,1550,45,45,45,45,45,1217,45,45,45,45,45,45,1225,45,45,45,45,1229,45,45,45,1388,45,45,45,45,45,45,1396,45,45,45,45,45,444,45,45,45,45,45,45,45,45,45,67,67,1574,67,67,67,67,67,67,67,67,67,67,1590,67,67,67,67,67,1254,67,67,67,67,67,1259,67,1261,67,67,67,67,1265,67,67,67,67,67,67,1708,67,67,67,67,97,97,97,97,97,97,0,0,97,97,97,97,97,0,0,67,67,67,67,1285,67,67,67,67,1289,67,67,67,67,67,67,67,67,37689,1087,25403,1091,66365,1095,0,0,97,97,97,97,1339,97,1341,97,97,97,97,1345,97,97,97,97,97,561,97,97,97,97,97,573,97,97,97,97,97,97,1717,97,0,97,97,97,97,97,97,97,591,97,97,97,97,97,97,97,97,97,1329,97,97,97,97,97,97,97,97,97,97,1351,97,97,97,97,97,97,1357,97,97,97,97,97,588,97,97,97,97,97,97,97,97,97,97,568,97,97,97,97,97,97,97,1365,97,97,97,97,1369,97,97,97,97,97,97,97,97,97,1356,97,97,97,97,97,97,45,45,1403,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1399,45,45,45,1413,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1669,45,1422,45,45,1425,45,45,1428,45,1429,67,67,67,67,67,67,67,67,1468,67,67,67,67,67,67,67,67,529,67,67,67,67,67,67,539,67,67,1475,67,0,0,0,0,0,0,0,0,0,0,0,0,140,2170880,2170880,2170880,2416640,97,97,1530,97,0,45,45,1534,45,45,45,45,45,45,45,45,1956,45,45,67,67,67,67,67,67,67,67,67,1599,67,67,1601,67,67,67,67,67,67,67,67,67,803,67,67,67,67,67,67,1632,97,1634,0,97,97,97,1640,97,97,97,1643,97,97,1645,97,97,97,97,97,912,97,97,97,97,97,97,97,97,97,0,0,0,45,45,45,45,45,45,1660,1661,45,45,45,45,1665,1666,45,45,45,45,45,1670,1692,1693,67,67,67,67,67,1697,67,67,67,67,67,67,67,1702,97,97,1714,1715,97,97,97,97,0,1721,1722,97,97,97,97,97,97,1353,97,97,97,97,97,97,97,97,1362,1726,97,0,0,97,97,97,0,97,97,97,1734,97,97,97,97,97,848,849,97,97,97,97,856,97,97,97,97,97,354,0,53264,0,18,18,24,24,0,28,28,45,45,1750,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1681,45,0,1846,97,97,97,97,97,97,45,45,1854,45,45,45,45,1859,67,67,67,1879,67,67,97,97,1884,97,97,0,0,0,97,97,97,1105,97,97,97,97,97,97,97,97,97,97,1344,97,97,97,1347,97,1892,97,0,0,0,97,97,97,1900,97,97,45,45,45,45,45,997,45,45,45,45,45,45,45,45,45,45,1002,45,45,1005,1006,45,67,67,67,67,67,1926,67,67,1928,97,97,97,97,97,0,0,97,97,97,0,97,97,97,97,97,97,1737,97,0,97,97,97,97,0,0,0,97,97,1944,97,97,1946,45,45,45,1544,45,45,45,45,45,45,45,45,45,45,45,45,190,45,45,45,152,155,45,163,45,45,177,179,182,45,45,45,193,197,45,45,45,1672,45,45,45,45,45,1677,45,1679,45,45,45,45,996,45,45,45,45,45,45,45,45,45,45,45,1212,45,45,45,45,67,260,264,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,97,295,299,302,97,310,97,97,324,326,329,97,97,97,0,97,97,1639,0,1641,97,97,97,97,97,97,97,97,1511,97,97,97,97,97,97,97,97,1523,97,97,97,97,97,97,97,97,1719,97,97,97,97,97,97,97,97,1720,97,97,97,97,97,97,97,312,97,97,97,97,97,97,97,97,1123,97,97,97,97,97,97,97,340,344,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,0,364,0,367,41098,369,140,45,45,373,375,419,45,45,45,45,45,45,45,45,45,428,45,45,435,45,45,45,1751,45,45,45,45,45,45,45,45,45,45,45,45,1410,45,45,45,67,67,67,505,67,67,67,67,67,67,67,67,67,514,67,67,67,67,67,67,1969,67,97,97,97,97,0,0,0,97,97,45,67,0,97,45,67,0,97,2064,2065,0,2066,45,521,67,67,67,67,67,67,67,67,67,67,534,67,67,67,67,67,67,465,67,67,67,474,67,67,67,67,67,67,67,1467,67,67,67,67,67,67,67,67,67,97,97,97,97,97,1933,0,97,97,97,602,97,97,97,97,97,97,97,97,97,611,97,97,18,640,139621,358,641,0,0,0,0,364,0,0,367,0,618,97,97,97,97,97,97,97,97,97,97,631,97,97,97,97,97,881,97,97,97,97,97,97,97,97,97,97,569,97,97,97,97,97,369,0,45,652,45,45,45,45,45,657,45,45,45,45,45,45,1235,45,45,45,45,45,45,45,45,67,67,67,1432,67,67,67,67,67,67,67,766,67,67,67,67,67,67,67,67,773,67,67,67,0,1305,0,1311,0,1317,97,97,97,97,97,97,97,1624,97,97,97,97,97,97,97,97,0,97,97,97,1724,97,97,97,777,67,67,782,67,67,67,67,67,67,67,67,67,67,67,67,535,67,67,67,67,67,67,67,814,67,67,67,67,67,67,67,67,67,37689,544,25403,546,70179,0,0,66365,66365,552,0,97,837,97,97,97,97,97,97,1496,97,97,97,97,97,97,97,97,97,97,918,97,97,97,97,0,842,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1168,97,97,97,97,864,97,97,97,97,97,97,97,97,871,97,97,97,0,1637,97,97,0,97,97,97,97,97,97,97,97,97,97,1801,45,45,97,875,97,97,880,97,97,97,97,97,97,97,97,97,97,97,1151,1152,97,97,97,67,67,67,1040,67,67,67,67,67,67,67,67,67,67,67,67,790,67,67,67,1180,0,649,45,45,45,45,45,45,45,45,45,45,45,45,45,200,45,45,67,67,67,1454,67,67,67,67,67,67,67,67,67,67,67,67,806,67,67,67,0,0,0,1481,0,1094,0,0,97,1483,97,97,97,97,97,97,304,97,97,318,97,97,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,97,97,97,1507,97,97,97,97,97,97,97,97,97,97,97,97,1332,97,97,97,1619,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1631,97,1633,97,0,97,97,97,0,97,97,97,97,97,97,97,97,97,1381,0,0,45,45,45,45,97,97,1727,0,97,97,97,0,97,97,97,97,97,97,97,97,626,97,97,97,97,97,97,636,45,45,1760,67,67,67,67,67,67,67,1765,67,67,67,67,67,67,67,1299,67,67,67,0,0,0,0,0,0,97,97,97,97,1616,97,97,1803,45,45,45,45,1807,45,45,45,45,45,1813,45,45,45,67,67,1684,67,67,67,67,67,67,67,67,67,67,67,822,67,67,37689,544,67,67,1818,67,67,67,67,1822,67,67,67,67,67,1828,67,67,67,67,67,97,0,0,97,97,97,97,97,45,45,45,2012,2013,45,45,67,67,67,2018,2019,67,67,97,67,97,97,97,1833,97,97,0,0,97,97,1840,97,97,0,0,97,97,97,0,97,97,1733,97,1735,97,97,97,0,97,97,97,1849,97,97,97,45,45,45,45,45,1857,45,45,45,1910,45,1912,45,45,1914,45,67,67,67,67,67,67,67,67,67,67,1017,67,67,1020,67,45,1861,45,45,45,45,45,67,67,67,67,67,1872,67,67,67,67,67,67,752,67,67,67,67,67,67,67,67,67,67,1446,67,67,67,67,67,1876,67,67,67,67,67,97,97,97,97,97,0,0,0,1890,97,97,97,97,97,1134,97,97,97,97,97,97,97,97,97,97,570,97,97,97,97,580,1935,97,97,97,97,0,0,0,97,97,97,97,97,97,45,45,45,45,1906,45,67,67,67,67,2048,0,97,97,97,97,45,45,67,67,0,0,0,0,925,41606,0,0,0,931,45,45,45,45,45,45,1674,45,1676,45,45,45,45,45,45,45,446,45,45,45,45,45,45,45,67,67,67,67,1871,67,67,67,67,0,97,97,45,67,0,97,2060,2061,0,2063,45,67,0,97,45,45,156,45,45,45,45,45,45,45,45,45,192,45,45,45,45,1673,45,45,45,45,45,45,45,45,45,45,45,429,45,45,45,45,67,67,67,269,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,349,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,0,364,0,367,41098,369,140,45,45,374,45,45,67,67,213,217,67,67,67,67,67,242,67,247,67,253,45,45,698,45,45,45,45,45,45,45,45,45,45,45,45,45,399,45,45,0,0,0,0,925,41606,0,929,0,0,45,45,45,45,45,45,1391,45,45,1395,45,45,45,45,45,45,423,45,45,45,45,45,45,45,436,45,67,67,67,67,1041,67,1043,67,67,67,67,67,67,67,67,67,67,1776,67,67,97,97,97,1099,0,0,97,97,97,97,97,97,97,97,97,97,97,97,97,888,97,97,97,1131,97,97,97,97,1135,97,1137,97,97,97,97,97,97,97,1497,97,97,97,97,97,97,97,97,97,883,97,97,97,97,97,97,1310,0,0,0,1316,0,0,0,0,1100,0,0,0,97,97,97,97,97,1107,97,97,97,97,97,97,97,97,1343,97,97,97,97,97,97,1348,0,0,1317,0,0,0,0,0,97,97,97,97,97,97,97,97,97,97,97,1112,97,45,1804,45,45,45,45,45,45,45,45,45,45,45,45,45,67,1868,67,1870,67,67,67,67,67,1817,67,67,1819,67,67,67,67,67,67,67,67,67,67,67,67,823,67,37689,544,67,97,1832,97,97,1834,97,0,0,97,97,97,97,97,0,0,97,97,97,0,1732,97,97,97,97,97,97,97,850,97,97,97,97,97,97,97,97,97,1177,0,0,925,0,0,0,0,97,97,97,97,0,0,1941,97,97,97,97,97,97,45,45,45,1991,1992,45,67,67,67,67,67,67,67,67,67,1998,134,0,0,0,37,110630,0,0,0,114730,106539,41098,45,45,45,45,941,45,45,944,45,45,45,45,45,45,952,45,45,207,67,67,67,67,67,226,67,67,67,67,67,67,67,67,67,820,67,67,67,67,37689,544,369,650,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1682,25403,546,70179,0,0,66365,66365,552,835,97,97,97,97,97,97,97,1522,97,97,97,97,97,97,97,97,0,97,97,97,97,97,97,1725,67,67,67,1695,67,67,67,67,67,67,67,67,67,67,67,67,1034,67,1036,67,67,67,265,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,97,296,97,97,97,97,314,97,97,97,97,332,334,97,97,97,97,97,1146,1147,97,97,97,97,97,97,97,97,97,97,1626,97,97,97,97,97,97,345,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,0,364,0,367,41098,369,140,45,372,45,45,45,1220,45,45,45,45,45,45,45,45,45,45,45,45,1213,45,45,45,45,404,406,45,45,45,45,45,45,45,45,45,45,45,45,45,434,45,45,45,440,45,45,45,45,45,45,45,45,451,452,45,45,45,67,1683,67,67,67,1686,67,67,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,67,67,67,67,490,492,67,67,67,67,67,67,67,67,67,67,67,1447,67,67,1450,67,67,67,67,67,526,67,67,67,67,67,67,67,67,537,538,67,67,67,67,67,506,67,67,508,67,67,511,67,67,67,67,0,1476,0,0,0,0,0,1478,0,0,0,0,0,0,0,0,97,97,1484,97,97,97,97,97,97,865,97,97,97,97,97,97,97,97,97,97,1499,97,97,97,97,97,97,97,97,97,587,589,97,97,97,97,97,97,97,97,97,97,629,97,97,97,97,97,97,97,97,97,623,97,97,97,97,97,97,97,97,634,635,97,97,97,97,97,1160,97,97,97,97,97,97,97,97,97,97,97,1628,97,97,97,97,369,0,45,45,45,45,45,655,45,45,45,45,45,45,45,45,999,45,1001,45,45,45,45,45,45,45,45,715,45,45,45,720,45,45,45,45,45,45,45,45,728,25403,546,70179,0,0,66365,66365,552,0,97,97,97,97,97,840,97,97,97,97,97,1174,97,97,97,97,0,0,925,0,0,0,0,0,0,0,1100,97,97,97,97,97,97,97,97,627,97,97,97,97,97,97,97,938,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,680,45,968,45,970,45,973,45,45,45,45,45,45,45,45,45,45,962,45,45,45,45,45,979,45,45,45,45,45,985,45,45,45,45,45,45,45,45,45,1224,45,45,45,45,45,45,45,45,688,45,45,45,45,45,45,45,1007,1008,67,67,67,67,67,1014,67,67,67,67,67,67,67,67,67,1045,67,67,67,67,67,67,67,1038,67,67,67,67,67,67,1044,67,1046,67,1049,67,67,67,67,67,67,800,67,67,67,67,67,67,808,67,67,0,0,0,1102,97,97,97,97,97,1108,97,97,97,97,97,97,306,97,97,97,97,97,97,97,97,97,97,1371,97,97,97,97,97,97,97,97,1132,97,97,97,97,97,97,1138,97,1140,97,1143,97,97,97,97,97,1352,97,97,97,97,97,97,97,97,97,97,869,97,97,97,97,97,45,1191,45,45,45,45,45,1196,45,45,45,45,45,45,45,45,1407,45,45,45,45,45,45,45,45,986,45,45,45,45,45,45,991,45,67,67,67,1256,67,67,67,67,67,67,67,67,67,67,67,67,1048,67,67,67,97,1336,97,97,97,97,97,97,97,97,97,97,97,97,97,97,615,97,1386,45,1387,45,45,45,45,45,45,45,45,45,45,45,45,45,455,45,457,45,45,1424,45,45,45,45,45,67,67,67,67,1433,67,1434,67,67,67,67,67,767,67,67,67,67,67,67,67,67,67,67,67,1591,67,1593,67,67,45,45,1805,45,45,45,45,45,45,45,45,45,1814,45,45,1816,67,67,67,67,1820,67,67,67,67,67,67,67,67,67,1829,67,67,67,67,67,815,67,67,67,67,821,67,67,67,37689,544,67,1831,97,97,97,97,1835,0,0,97,97,97,97,97,0,0,97,97,97,1731,97,97,97,97,97,97,97,97,97,853,97,97,97,97,97,97,0,97,97,97,97,1850,97,97,45,45,45,45,45,45,45,45,1547,45,45,45,45,45,45,45,45,1664,45,45,45,45,45,45,45,45,961,45,45,45,45,965,45,967,1907,45,45,45,45,45,45,45,45,45,67,67,67,67,67,1920,0,1936,97,97,97,0,0,0,97,97,97,97,97,97,45,45,67,67,67,67,67,67,1763,67,67,67,67,67,67,67,67,1056,67,67,67,67,67,67,67,67,1273,67,67,67,67,67,67,67,67,1457,67,67,67,67,67,67,67,67,97,97,97,97,0,0,28672,97,45,67,67,67,67,0,0,97,97,97,97,45,45,67,67,2054,97,97,291,97,97,97,97,97,97,320,97,97,97,97,97,97,307,97,97,97,97,97,97,97,97,97,97,12288,0,925,926,1179,0,45,377,45,45,45,381,45,45,392,45,45,396,45,45,45,45,971,45,45,45,45,45,45,45,45,45,45,45,45,1756,45,45,45,67,67,67,67,463,67,67,67,467,67,67,478,67,67,482,67,67,67,67,67,1028,67,67,67,67,67,67,67,67,67,67,67,67,1469,67,67,1472,67,502,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1460,67,97,97,97,97,560,97,97,97,564,97,97,575,97,97,579,97,97,97,97,97,1368,97,97,97,97,97,97,97,97,97,97,0,0,925,0,0,930,97,599,97,97,97,97,97,97,97,97,97,97,97,97,97,97,872,97,45,666,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1758,0,362,0,0,925,41606,0,0,0,0,45,45,934,45,45,45,164,168,174,178,45,45,45,45,45,194,45,45,45,165,45,45,45,45,45,45,45,45,45,199,45,45,45,67,67,1010,67,67,67,67,67,67,67,67,67,67,67,67,1060,67,67,67,67,67,67,1052,1053,67,67,67,67,67,67,67,67,67,67,1063,97,1157,97,97,97,97,97,97,97,97,97,97,97,97,1167,97,97,97,97,97,1379,97,97,97,0,0,0,45,1383,45,45,45,1806,45,45,45,45,45,45,1812,45,45,45,45,67,67,67,67,67,1577,67,67,67,67,67,67,67,753,67,67,67,67,67,67,67,67,67,1262,67,67,67,67,67,67,67,1282,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1471,67,45,1402,45,45,45,45,45,45,45,45,45,45,45,45,45,45,417,45,67,1462,67,67,67,67,67,67,67,67,67,67,67,67,67,67,37689,544,97,1517,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1128,97,97,97,97,1636,97,97,97,0,97,97,97,97,97,97,97,97,851,97,97,97,97,97,97,97,67,67,1705,67,67,67,67,67,67,67,67,97,97,97,97,97,97,0,0,97,97,97,97,1842,0,0,1779,97,97,97,1782,97,0,0,97,97,97,97,97,97,0,0,97,97,97,1789,97,97,0,0,0,97,1847,97,97,97,97,97,45,45,45,45,45,45,45,45,1675,45,45,45,45,45,45,45,45,737,738,67,740,67,741,67,743,67,67,67,67,67,67,1968,67,67,97,97,97,97,0,0,0,97,97,45,67,0,97,45,67,2062,97,45,67,0,97,45,67,67,97,97,2001,97,0,0,2004,97,97,0,97,97,97,97,1797,97,97,97,97,97,45,45,45,67,261,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,97,292,97,97,97,97,311,315,321,325,97,97,97,97,97,97,1623,97,97,97,97,97,97,97,97,97,97,1330,97,97,1333,1334,97,341,97,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,0,363,364,0,367,41098,369,140,45,45,45,45,1221,45,45,45,45,45,45,45,45,45,45,45,413,45,45,416,45,376,45,45,45,45,382,45,45,45,45,45,45,45,45,45,45,1408,45,45,45,45,45,403,45,45,45,45,45,45,45,45,45,45,414,45,45,45,418,67,67,67,462,67,67,67,67,468,67,67,67,67,67,67,67,67,1602,67,1604,67,67,67,67,67,67,67,67,489,67,67,67,67,67,67,67,67,67,67,500,67,67,67,67,67,1067,67,67,67,67,67,1072,67,67,67,67,67,67,274,0,37139,24853,0,0,0,0,41098,65820,67,67,504,67,67,67,67,67,67,67,510,67,67,67,517,519,541,67,37139,37139,24853,24853,0,70179,0,0,0,65820,65820,369,287,554,97,97,97,559,97,97,97,97,565,97,97,97,97,97,97,97,1718,0,97,97,97,97,97,97,97,898,97,97,97,97,97,97,906,97,97,97,97,586,97,97,97,97,97,97,97,97,97,97,597,97,97,97,97,97,1520,97,97,97,97,97,97,97,97,97,97,0,45,1656,45,45,45,97,97,601,97,97,97,97,97,97,97,607,97,97,97,614,616,638,97,18,0,139621,0,0,0,0,0,0,364,0,0,367,41606,369,0,45,45,45,45,45,45,45,45,45,45,661,45,45,45,407,45,45,45,45,45,45,45,45,45,45,45,45,45,1815,45,67,45,667,45,45,45,45,45,45,45,45,45,45,678,45,45,45,421,45,45,45,45,45,45,45,45,45,45,45,45,976,977,45,45,45,682,45,45,45,45,45,45,45,45,45,45,693,45,45,697,67,67,748,67,67,67,67,754,67,67,67,67,67,67,67,67,67,1274,67,67,67,67,67,67,67,67,765,67,67,67,67,769,67,67,67,67,67,67,67,67,67,1589,67,67,67,67,67,67,67,67,780,67,67,784,67,67,67,67,67,67,67,67,67,67,67,1777,67,97,97,97,97,97,97,846,97,97,97,97,852,97,97,97,97,97,97,97,1742,45,45,45,45,45,45,45,1747,97,97,97,863,97,97,97,97,867,97,97,97,97,97,97,97,308,97,97,97,97,97,97,97,97,97,97,12288,1178,925,0,1179,0,97,97,97,878,97,97,882,97,97,97,97,97,97,97,97,97,97,12288,0,925,0,1179,0,908,97,97,97,97,97,97,97,97,97,97,97,97,97,97,0,0,925,0,0,0,954,45,45,45,45,45,45,45,45,45,45,963,45,45,966,45,45,157,45,45,171,45,45,45,45,45,45,45,45,45,45,948,45,45,45,45,45,1022,67,67,1026,67,67,67,1030,67,67,67,67,67,67,67,67,67,1603,1605,67,67,67,1608,67,67,67,1039,67,67,1042,67,67,67,67,67,67,67,67,67,67,471,67,67,67,67,67,0,1100,0,97,97,97,97,97,97,97,97,97,97,97,97,97,904,97,97,97,97,1116,97,97,1120,97,97,97,1124,97,97,97,97,97,97,562,97,97,97,571,97,97,97,97,97,97,97,97,97,1133,97,97,1136,97,97,97,97,97,97,97,97,915,917,97,97,97,97,97,0,97,1170,97,97,97,97,97,97,97,97,0,0,925,0,0,0,0,0,41606,0,0,0,0,45,45,45,45,45,45,1993,67,67,67,67,67,67,67,67,67,67,1275,67,67,67,1278,67,0,0,0,45,45,1182,45,45,45,45,45,45,45,45,45,1189,1204,45,45,45,1207,45,45,1209,45,1210,45,45,45,45,45,45,1546,45,45,45,45,45,45,45,45,45,689,45,45,45,45,45,45,1231,45,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,236,67,67,67,67,67,67,67,801,67,67,67,805,67,67,67,67,67,1242,67,67,67,67,67,67,67,67,67,1249,67,67,67,67,67,67,507,67,67,67,67,67,67,67,67,67,67,1300,0,0,0,0,0,1267,67,67,1269,67,1270,67,67,67,67,67,67,67,67,67,1280,97,1349,97,1350,97,97,97,97,97,97,97,97,97,1360,97,97,97,0,1980,97,97,97,97,97,45,45,45,45,45,45,673,45,45,45,45,677,45,45,45,45,1401,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,953,67,1437,67,1440,67,67,67,67,1445,67,67,67,1448,67,67,67,67,67,67,1029,67,67,67,67,67,67,67,67,67,67,1825,67,67,67,67,67,1473,67,67,67,0,0,0,0,0,0,0,0,0,0,0,0,1320,0,834,97,97,97,97,1490,97,1493,97,97,97,97,1498,97,97,97,1501,97,97,97,0,97,1638,97,0,97,97,97,97,97,97,97,97,916,97,97,97,97,97,97,0,1528,97,97,97,0,45,45,45,1535,45,45,45,45,45,45,45,1867,67,67,67,67,67,67,67,67,67,97,97,97,97,1932,0,0,1555,45,45,45,45,45,45,45,45,45,45,45,45,45,1567,45,45,158,45,45,172,45,45,45,183,45,45,45,45,201,45,45,67,212,67,67,67,67,231,235,241,245,67,67,67,67,67,67,493,67,67,67,67,67,67,67,67,67,67,472,67,67,67,67,67,97,97,97,97,1651,97,97,97,97,97,0,45,45,45,45,45,45,45,1539,45,45,45,67,1704,67,1706,67,67,67,67,67,67,67,97,97,97,97,97,97,0,0,97,97,97,1841,97,0,1844,97,97,97,97,1716,97,97,97,0,97,97,97,97,97,97,97,590,97,97,97,97,97,97,97,97,97,0,0,0,45,45,45,1385,1748,45,45,45,45,45,45,45,45,45,45,45,45,45,1757,45,45,159,45,45,45,45,45,45,45,45,45,45,45,45,45,415,45,45,97,97,1780,97,97,97,0,0,1786,97,97,97,97,97,0,0,97,97,1730,0,97,97,97,97,97,1736,97,1738,67,97,97,97,97,97,97,0,1838,97,97,97,97,97,0,0,97,1729,97,0,97,97,97,97,97,97,97,97,1162,97,97,97,1165,97,97,97,45,1950,45,45,45,45,45,45,45,45,1958,67,67,67,1962,67,67,67,67,67,1246,67,67,67,67,67,67,67,67,67,67,67,97,1710,97,97,97,1999,67,97,97,97,97,0,2003,97,97,97,0,97,97,2008,2009,45,67,67,67,67,0,0,97,97,97,97,45,2052,67,2053,0,0,0,0,925,41606,0,0,930,0,45,45,45,45,45,45,1392,45,1394,45,45,45,45,45,45,45,1545,45,45,45,45,45,45,45,45,45,45,1563,1565,45,45,45,1568,0,97,2055,45,67,0,97,45,67,0,97,45,67,28672,97,45,45,160,45,45,45,45,45,45,45,45,45,45,45,45,45,679,45,45,67,67,266,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,346,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,0,362,0,364,0,367,41098,369,140,371,45,45,45,379,45,45,45,388,45,45,45,45,45,45,45,45,1663,45,45,45,45,45,45,45,45,45,449,45,45,45,45,45,67,67,542,37139,37139,24853,24853,0,70179,0,0,0,65820,65820,369,287,97,97,97,97,97,1622,97,97,97,97,97,97,97,1629,97,97,0,1794,1795,97,97,97,97,97,97,97,97,45,45,45,45,45,45,1745,45,45,97,639,18,0,139621,0,0,0,0,0,0,364,0,0,367,41606,45,731,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,67,67,251,67,67,67,67,67,798,67,67,67,67,67,67,67,67,67,67,67,67,1073,67,67,67,860,97,97,97,97,97,97,97,97,97,97,97,97,97,97,873,0,0,1101,97,97,97,97,97,97,97,97,97,97,97,97,97,921,97,0,67,67,67,67,1245,67,67,67,67,67,67,67,67,67,67,67,67,1250,67,67,1253,0,0,1312,0,0,0,1318,0,0,0,0,0,0,97,97,97,97,1106,97,97,97,97,97,97,97,97,97,1149,97,97,97,97,97,1155,97,97,1325,97,97,97,97,97,97,97,97,97,97,97,97,97,1141,97,97,67,67,1439,67,1441,67,67,67,67,67,67,67,67,67,67,67,67,1264,67,67,67,97,97,1492,97,1494,97,97,97,97,97,97,97,97,97,97,97,1331,97,97,97,97,67,67,67,2037,67,97,0,0,97,97,97,2043,97,45,45,45,442,45,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,67,232,67,67,67,67,67,67,67,67,1823,67,67,67,67,67,67,67,67,97,97,97,97,1975,0,0,97,874,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1142,97,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,65,86,117,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,63,84,115,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,61,82,113,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,59,80,111,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,57,78,109,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,55,76,107,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,53,74,105,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,51,72,103,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,49,70,101,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,47,68,99,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,45,67,97,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,213085,53264,18,49172,57366,24,8192,28,102432,0,0,0,44,0,0,32863,53264,18,49172,57366,24,8192,28,102432,0,41,41,41,0,0,1138688,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,0,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,89,53264,18,18,49172,0,57366,0,24,24,24,0,127,127,127,127,102432,67,262,67,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,342,97,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,360,0,0,364,0,367,41098,369,140,45,45,45,45,717,45,45,45,45,45,45,45,45,45,45,45,412,45,45,45,45,45,67,1009,67,67,67,67,67,67,67,67,67,67,67,67,67,1292,67,67,1294,67,67,67,67,67,67,67,67,67,67,0,0,0,0,0,0,97,97,97,1615,97,97,97,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,66,87,118,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,64,85,116,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,62,83,114,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,60,81,112,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,58,79,110,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,56,77,108,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,54,75,106,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,52,73,104,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,50,71,102,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,48,69,100,53264,18,49172,57366,24,8192,28,102432,37,110630,114730,106539,46,67,98,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,233472,53264,18,49172,57366,24,8192,28,102432,0,110630,114730,106539,0,0,69724,53264,18,18,49172,0,57366,262144,24,24,24,0,28,28,28,28,102432,45,45,161,45,45,45,45,45,45,45,45,45,45,45,45,45,710,45,45,28,139621,359,0,0,0,364,0,367,41098,369,140,45,45,45,45,1389,45,45,45,45,45,45,45,45,45,45,45,949,45,45,45,45,67,503,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1449,67,67,97,600,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1154,97,0,0,0,0,925,41606,927,0,0,0,45,45,45,45,45,45,1866,67,67,67,67,67,67,67,67,67,67,772,67,67,67,67,67,45,45,969,45,45,45,45,45,45,45,45,45,45,45,45,45,951,45,45,45,45,1192,45,45,45,45,45,45,45,45,45,45,45,45,45,1202,45,45,0,0,0,1314,0,0,0,0,0,0,0,0,0,97,97,97,97,97,97,97,1488,67,67,267,67,67,67,67,0,37139,24853,0,0,0,0,41098,65820,97,347,97,97,97,97,0,53264,0,18,18,24,24,0,28,28,139621,0,361,0,0,364,0,367,41098,369,140,45,45,45,45,734,45,45,45,67,67,67,67,67,742,67,67,45,45,668,45,45,45,45,45,45,45,45,45,45,45,45,45,1214,45,45,1130,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1361,97,45,45,1671,45,45,45,45,45,45,45,45,45,45,45,45,45,1552,45,45,0,0,0,0,2220032,0,0,1130496,0,0,0,0,2170880,2171020,2170880,2170880,18,0,0,131072,0,0,0,90112,0,2220032,0,0,0,0,0,0,0,0,97,97,97,1485,97,97,97,97,0,45,45,45,45,45,1537,45,45,45,45,45,1390,45,1393,45,45,45,45,1398,45,45,45,2170880,2171167,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2576384,2215936,3117056,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,0,0,0,0,0,2174976,0,0,0,0,0,0,2183168,0,0,0,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,2721252,2744320,2170880,2170880,2170880,2834432,2840040,2170880,2908160,2170880,2170880,2936832,2170880,2170880,2985984,2170880,2994176,2170880,2170880,3014656,2170880,3059712,3076096,3088384,2170880,2170880,2170880,2170880,0,0,0,0,2220032,0,0,0,1142784,0,0,0,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3215360,2215936,2215936,2215936,2215936,2215936,2437120,2215936,2215936,2215936,3117056,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,2215936,0,543,0,545,0,0,2183168,0,0,831,0,2170880,2170880,2170880,2400256,2170880,2170880,2170880,2170880,3031040,2170880,3055616,2170880,2170880,2170880,2170880,3092480,2170880,2170880,3125248,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,2170880,3198976,2170880,0,0,0,0,0,0,67,67,37139,37139,24853,24853,0,0,0,0,0,65820,65820,0,287,97,97,97,97,97,1783,0,0,97,97,97,97,97,97,0,0,97,97,97,97,97,97,1791,0,0,546,70179,0,0,0,0,552,0,97,97,97,97,97,97,97,604,97,97,97,97,97,97,97,97,97,97,1150,97,97,97,97,97,147456,147456,147456,147456,147456,147456,147456,147456,147456,147456,147456,147456,0,0,147456,0,0,0,0,925,41606,0,928,0,0,45,45,45,45,45,45,998,45,45,45,45,45,45,45,45,45,1562,45,1564,45,45,45,45,0,2158592,2158592,0,0,0,0,2232320,2232320,2232320,0,2240512,2240512,2240512,2240512,0,0,0,0,0,0,0,0,0,0,0,2170880,2170880,2170880,2416640],r.EXPECTED=[291,300,304,341,315,309,305,295,319,323,327,329,296,333,337,339,342,346,350,294,356,360,312,367,352,371,363,375,379,383,387,391,395,726,399,405,518,684,405,405,405,405,808,405,405,405,512,405,405,405,431,405,405,406,405,405,404,405,405,405,405,405,405,405,908,631,410,415,405,414,419,608,405,429,602,405,435,443,405,441,641,478,405,447,451,450,456,643,461,460,762,679,465,469,741,473,477,482,486,492,932,931,523,498,504,720,405,510,596,405,516,941,580,522,929,527,590,589,897,939,534,538,547,551,555,559,563,567,571,969,575,708,690,689,579,584,634,405,594,731,405,600,882,405,606,895,786,452,612,405,615,620,876,624,628,638,647,651,655,659,663,667,676,683,688,695,694,791,405,699,437,405,706,714,405,712,825,870,405,718,724,769,768,823,730,735,745,751,422,755,759,425,766,902,810,587,775,888,887,405,773,992,405,779,962,405,785,781,986,790,795,797,506,500,499,801,805,814,820,829,833,837,841,845,849,853,857,861,616,865,869,868,488,405,874,816,405,880,738,405,886,892,543,405,901,906,913,912,918,494,541,922,926,936,945,949,953,957,530,966,973,960,702,701,405,979,981,405,985,747,405,990,998,914,405,996,1004,672,975,974,1014,1002,1008,670,1012,405,405,405,405,405,401,1018,1022,1026,1106,1071,1111,1111,1111,1082,1145,1030,1101,1034,1038,1106,1106,1106,1106,1046,1206,1052,1106,1072,1111,1111,1042,1134,1065,1111,1112,1056,1160,1207,1062,1204,1208,1069,1106,1106,1106,1076,1111,1207,1161,1122,1205,1064,1094,1106,1106,1107,1111,1111,1111,1078,1086,1207,1092,1098,1046,1058,1106,1106,1110,1111,1111,1116,1120,1161,1126,1202,1104,1106,1145,1146,1129,1138,1088,1151,1048,1157,1153,1132,1141,1165,1107,1111,1172,1179,1109,1183,1175,1143,1147,1187,1108,1191,1195,1144,1199,1168,1212,1216,1220,1224,1228,1232,1236,1557,1247,1241,1241,1038,1434,1241,1241,1241,1241,1254,1275,1617,1241,1280,1287,1241,1241,1241,1287,1241,2114,1291,1241,1243,1241,2049,1824,2094,2095,1520,1309,1241,1241,1302,1241,1321,1311,1241,1241,1313,1778,1325,1336,1241,1241,1325,1330,1353,1241,1241,1695,1354,1241,1241,1241,1294,1686,1331,1241,1696,1368,1241,1338,1370,1241,1392,1399,1364,2017,1406,2016,1405,1716,1406,1407,1422,1417,1421,1241,1241,1241,1349,1426,1241,1774,1756,1241,1773,1241,1241,1345,1964,1812,1432,1241,1241,1345,1993,1459,1241,1241,1241,1395,1848,1767,1465,1241,1241,1394,1847,1242,1477,1241,1241,1428,1241,1445,1492,1241,1241,1438,1241,1499,1241,1241,1241,1455,1241,1818,1448,1241,1250,1241,2026,1623,1449,1241,1612,1616,1241,1614,1241,1257,1241,1241,1985,1292,1586,1512,1241,1517,2050,1526,1674,1519,1524,1647,2051,1532,1537,1551,1544,1550,1555,1561,1571,1578,1584,1590,1591,1653,1595,1602,1606,1610,1634,1628,1640,1633,1645,1241,1241,1241,1469,1241,1970,1651,1241,1270,1241,1241,1819,1449,1241,1293,1664,1241,1241,1481,1485,1574,1672,1241,1241,1513,1317,1487,1684,1241,1241,1533,1299,1694,1241,1241,1295,1241,1241,1241,1546,1700,1241,1241,1707,1241,1713,1241,1849,1715,1241,1720,1241,1276,1267,1241,1241,2107,1657,1864,1241,1881,1241,1326,1292,1241,1685,1358,1724,1338,1241,1363,1362,1342,1340,1361,1339,1833,1372,1360,1833,1833,1342,1343,1835,1341,1731,1738,1344,1241,1745,1241,1379,1241,1241,2092,1241,1388,1761,1754,1241,1386,1241,1400,1760,1241,1241,1241,1598,1734,1241,1241,1241,1635,1645,1241,1780,1766,1241,1241,1332,1771,1241,1241,1629,2079,1241,1242,1784,1241,1241,1680,1639,2063,1790,1241,1241,1741,1241,1241,1800,1241,1241,1762,1473,1241,1806,1241,1241,1786,1240,1709,1241,1241,1241,1668,1811,1241,1940,1241,1401,1974,1241,1408,1413,1382,1241,1816,1241,1241,1802,2086,1811,1241,1817,1945,1823,2095,2095,2047,2094,2046,2080,1241,1409,1312,1376,2096,2048,1241,1241,1807,1241,1241,1241,2035,1241,1241,1828,1241,2057,2061,1241,1241,1843,1241,2059,1241,1241,1241,1690,1847,1241,1241,1241,1703,2102,1848,1241,1241,1853,1292,1848,1241,2016,1857,1241,2002,1868,1241,1436,1241,1241,1271,1305,1241,1874,1241,1241,1884,2037,1892,1241,1890,1241,1461,1241,1241,1795,1241,1241,1891,1241,1878,1241,1888,1241,1888,1905,1896,2087,1912,1903,1241,1911,1906,1916,1905,2027,1863,1925,2088,1859,1861,1922,1927,1931,1935,1494,1241,1241,1918,1907,1939,1917,1944,1949,1241,1241,1451,1955,1241,1241,1241,1796,1727,2061,1241,1241,1899,1241,1660,1968,1241,1241,1951,1678,1978,1241,1241,1241,1839,1241,1241,1984,1982,1241,1488,1241,1241,1624,1450,1989,1241,1241,1241,1870,1995,1292,1241,1241,1958,1261,1241,1996,1241,1241,1241,2039,2008,1241,1241,1750,2e3,1241,1256,2001,1960,1241,1564,1241,1504,1241,1241,1442,1241,1241,1564,1528,1263,1241,1508,1241,1241,1468,1498,2006,1540,2015,1539,2014,1748,2013,1539,1831,2014,2012,1500,1567,2022,2021,1241,1580,1241,1241,2033,2037,1791,2045,2031,1241,1621,1241,1641,2044,1241,1241,1241,2093,1241,1241,2055,1241,1241,2067,1241,1283,1241,1241,1241,2101,2071,1241,1241,1241,2073,1848,2040,1241,1241,1241,2077,1241,1241,2106,1241,1241,2084,1241,2111,1241,1241,1381,1380,1241,1241,1241,2100,1241,2129,2118,2122,2126,2197,2133,3010,2825,2145,2698,2156,2226,2160,2161,2165,2174,2293,2194,2630,2201,2203,2152,3019,2226,2263,2209,2213,2218,2269,2292,2269,2269,2184,2226,2238,2148,2151,3017,2245,2214,2269,2269,2185,2226,2292,2269,2291,2269,2269,2269,2292,2205,3019,2226,2226,2160,2160,2160,2261,2160,2160,2160,2262,2276,2160,2160,2277,2216,2283,2216,2269,2269,2268,2269,2267,2269,2269,2269,2271,2568,2292,2269,2293,2269,2182,2190,2269,2186,2226,2226,2226,2226,2227,2160,2160,2160,2160,2263,2160,2275,2277,2282,2215,2217,2269,2269,2291,2269,2269,2293,2291,2269,2220,2269,2295,2294,2269,2269,2305,2233,2262,2278,2218,2269,2234,2226,2226,2228,2160,2160,2160,2289,2220,2294,2294,2269,2269,2304,2269,2160,2160,2287,2269,2269,2305,2269,2269,2312,2269,2269,2225,2226,2160,2287,2289,2219,2304,2295,2314,2234,2226,2314,2269,2226,2226,2160,2288,2219,2222,2304,2296,2269,2224,2160,2160,2269,2302,2294,2314,2224,2226,2288,2220,2294,2269,2290,2269,2269,2293,2269,2269,2269,2269,2270,2221,2313,2225,2227,2160,2300,2269,2225,2261,2309,2234,2229,2223,2318,2318,2318,2328,2336,2340,2344,2350,2637,2712,2358,2362,2372,2135,2378,2398,2135,2135,2135,2135,2136,2417,2241,2135,2378,2135,2135,2980,2984,2135,3006,2135,2135,2135,2945,2931,2425,2400,2135,2135,2135,2954,2135,2481,2433,2135,2135,2988,2824,2135,2135,2482,2434,2135,2135,2440,2445,2452,2135,2135,2998,3002,2961,2441,2446,2453,2463,2974,2135,2135,2135,2140,2642,2709,2459,2470,2465,2135,2135,3005,2135,2135,2987,2823,2458,2469,2464,2975,2135,2135,2135,2353,2488,2447,2324,2974,2135,2409,2459,2448,2135,2961,2487,2446,2476,2323,2973,2135,2135,2135,2354,2476,2974,2135,2135,2135,2957,2135,2135,2960,2135,2135,2135,2363,2409,2459,2474,2465,2487,2571,2973,2135,2135,2168,2973,2135,2135,2135,2959,2135,2135,2135,2506,2135,2957,2488,2170,2135,2135,2135,2960,2135,2818,2493,2135,2135,3033,2135,2135,2135,2934,2819,2494,2135,2135,2135,2976,2780,2499,2135,2135,2135,3e3,2968,2135,2935,2135,2135,2135,2364,2507,2135,2135,2934,2135,2135,2780,2492,2507,2135,2135,2506,2780,2135,2135,2782,2780,2135,2782,2135,2783,2374,2514,2135,2135,2135,3007,2530,2974,2135,2135,2135,3008,2135,2135,2134,2135,2526,2531,2975,2135,2135,3042,2581,2575,2956,2135,2135,2135,2394,2135,2508,2535,2840,2844,2495,2135,2135,2136,2684,2537,2842,2846,2135,2136,2561,2581,2551,2536,2841,2845,2975,3043,2582,2843,2555,2135,3040,3044,2538,2844,2975,2135,2135,2253,2644,2672,2542,2554,2135,2135,2346,2873,2551,2555,2135,2135,2135,2381,2559,2565,2538,2553,2135,2560,2914,2576,2590,2135,2135,2135,2408,2136,2596,2624,2135,2135,2135,2409,2135,2618,2597,3008,2135,2135,2380,2956,2601,2135,2135,2135,2410,2620,2624,2135,2136,2383,2135,2135,2783,2623,2135,2135,2393,2888,2136,2621,3008,2135,2618,2618,2622,2135,2135,2405,2414,2619,2384,2624,2135,2136,2950,2135,2138,2135,2139,2135,2604,2623,2135,2140,2878,2665,2957,2622,2135,2135,2428,2762,2606,2612,2135,2135,2501,2586,2604,3038,2135,2604,3036,2387,2958,2386,2135,2141,2135,2421,2387,2385,2135,2385,2384,2384,2135,2386,2628,2384,2135,2135,2501,2596,2591,2135,2135,2135,2400,2135,2634,2135,2135,2559,2580,2575,2648,2135,2135,2135,2429,2649,2135,2135,2135,2435,2654,2658,2135,2135,2135,2436,2649,2178,2659,2135,2135,2595,2601,2669,2677,2135,2135,2616,2957,2879,2665,2691,2135,2363,2367,2900,2878,2664,2690,2975,2877,2643,2670,2974,2671,2975,2135,2135,2619,2608,2669,2673,2135,2135,2653,2177,2672,2135,2135,2135,2486,2168,2251,2255,2695,2974,2709,2135,2135,2135,2487,2169,2399,2716,2975,2135,2363,2770,2776,2640,2717,2135,2135,2729,2135,2135,2641,2718,2135,2135,2135,2505,2135,2640,2257,2974,2135,2727,2975,2135,2365,2332,2895,2957,2135,2959,2135,2365,2749,2754,2959,2958,2958,2135,2380,2793,2799,2135,2735,2738,2135,2381,2135,2135,2940,2974,2135,2744,2135,2135,2739,2519,2976,2745,2135,2135,2135,2509,2755,2135,2135,2135,2510,2772,2778,2135,2135,2740,2520,2135,2771,2777,2135,2135,2759,2750,2792,2798,2135,2135,2781,2392,2779,2135,2135,2135,2521,2135,2679,2248,2135,2135,2681,2480,2135,2135,2786,3e3,2135,2679,2683,2135,2135,2416,2135,2135,2135,2525,2135,2730,2135,2135,2135,2560,2581,2135,2805,2135,2135,2804,2962,2832,2974,2135,2382,2135,2135,2958,2135,2135,2960,2135,2829,2833,2975,2961,2965,2969,2973,2968,2972,2135,2135,2135,2641,2135,2515,2966,2970,2851,2478,2135,2135,2808,2135,2809,2135,2135,2135,2722,2852,2479,2135,2135,2815,2135,2135,2766,2853,2480,2135,2857,2479,2135,2388,2723,2135,2364,2331,2894,2858,2480,2135,2135,2850,2478,2135,2135,2135,2806,2864,2135,2399,2256,2974,2865,2135,2135,2862,2135,2135,2135,2685,2807,2865,2135,2135,2807,2863,2135,2135,2135,2686,2884,2807,2135,2809,2807,2135,2135,2807,2806,2705,2810,2808,2700,2869,2702,2702,2702,2704,2883,2135,2135,2135,2730,2884,2135,2135,2135,2731,2321,2546,2135,2135,2876,2255,2889,2322,2547,2135,2401,2135,2135,2135,2949,2367,2893,2544,2973,2906,2973,2135,2135,2877,2663,2368,2901,2907,2974,2366,2899,2905,2972,2920,2974,2135,2135,2911,2900,2920,2363,2913,2918,2465,2941,2975,2135,2135,2924,2928,2974,2945,2931,2135,2135,2135,2765,2136,2955,2135,2135,2939,2931,2380,2135,2135,2380,2135,2135,2135,2780,2507,2137,2135,2137,2135,2139,2135,2806,2810,2135,2135,2135,2992,2135,2135,2962,2966,2970,2974,2135,2135,2787,3014,2135,2521,2993,2135,2135,2135,2803,2135,2135,2135,2618,2607,2997,3001,2135,2135,2963,2967,2971,2975,2135,2135,2791,2797,2135,3009,2999,3003,2787,3001,2135,2135,2964,2968,2785,2999,3003,2135,2135,2135,2804,2785,2999,3004,2135,2135,2135,2807,2135,2135,3023,2135,2135,2135,2811,2135,2135,3027,2135,2135,2135,2837,2968,3028,2135,2135,2135,2875,2135,2784,3029,2135,2408,2457,2446,0,14,0,-2120220672,1610612736,-2074083328,-2002780160,-2111830528,1073872896,1342177280,1075807216,4096,16384,2048,8192,0,8192,0,0,0,0,1,0,0,0,2,0,-2145386496,8388608,1073741824,0,2147483648,2147483648,2097152,2097152,2097152,536870912,0,0,134217728,33554432,1536,268435456,268435456,268435456,268435456,128,256,32,0,65536,131072,524288,16777216,268435456,2147483648,1572864,1835008,640,32768,65536,262144,1048576,2097152,196608,196800,196608,196608,0,131072,131072,131072,196608,196624,196608,196624,196608,196608,128,4096,16384,16384,2048,0,4,0,0,2147483648,2097152,0,1024,32,32,0,65536,1572864,1048576,32768,32768,32768,32768,196608,196608,196608,64,64,196608,196608,131072,131072,131072,131072,268435456,268435456,64,196736,196608,196608,196608,131072,196608,196608,16384,4,4,4,2,32,32,65536,1048576,12582912,1073741824,0,0,2,8,16,96,2048,32768,0,0,131072,268435456,268435456,268435456,256,256,196608,196672,196608,196608,196608,196608,4,0,256,256,256,256,32,32,32768,32,32,32,32,32768,268435456,268435456,268435456,196608,196608,196608,196624,196608,196608,196608,16,16,16,268435456,196608,64,64,64,196608,196608,196608,196672,268435456,64,64,196608,196608,16,196608,196608,196608,268435456,64,196608,131072,262144,4194304,25165824,33554432,134217728,268435456,268435456,196608,262152,8,256,512,3072,16384,200,-1073741816,8392713,40,8392718,520,807404072,40,520,100663304,0,0,-540651761,-540651761,257589048,0,262144,0,0,3,8,256,0,4,6,4100,8388612,0,0,0,3,4,8,256,512,1024,0,2097152,0,0,-537854471,-537854471,0,100663296,0,0,1,2,0,0,0,16384,0,0,0,96,14336,0,0,0,7,8,234881024,0,0,0,8,0,0,0,0,262144,0,0,16,64,384,512,0,1,1,0,12582912,0,0,0,0,33554432,67108864,-606084144,-606084144,-606084138,0,0,28,32,768,1966080,-608174080,0,0,0,14,35056,16,64,896,24576,98304,98304,131072,262144,524288,1048576,4194304,25165824,1048576,62914560,134217728,-805306368,0,384,512,16384,65536,131072,262144,29360128,33554432,134217728,268435456,1073741824,2147483648,262144,524288,1048576,29360128,33554432,524288,1048576,16777216,33554432,134217728,268435456,1073741824,0,0,0,123856,1966080,0,64,384,16384,65536,131072,16384,65536,524288,268435456,2147483648,0,0,524288,2147483648,0,0,1,16,0,256,524288,0,0,0,25,96,128,-537854471,0,0,0,32,7404800,-545259520,0,0,0,60,0,249,64768,1048576,6291456,6291456,25165824,100663296,402653184,1073741824,96,128,1280,2048,4096,57344,6291456,57344,6291456,8388608,16777216,33554432,201326592,1342177280,2147483648,0,57344,6291456,8388608,100663296,134217728,2147483648,0,0,0,1,8,16,64,128,64,128,256,1024,131072,131072,131072,262144,524288,16777216,57344,6291456,8388608,67108864,134217728,64,256,1024,2048,4096,57344,64,256,0,24576,32768,6291456,67108864,134217728,0,1,64,256,24576,32768,4194304,32768,4194304,67108864,0,0,64,256,0,0,24576,32768,0,16384,4194304,67108864,64,16384,0,0,1,64,256,16384,4194304,67108864,0,0,0,16384,0,16384,16384,0,-470447874,-470447874,-470447874,0,0,128,0,0,8,96,2048,32768,262144,8388608,35056,1376256,-471859200,0,0,14,16,224,2048,32768,2097152,4194304,8388608,-486539264,0,96,128,2048,32768,262144,2097152,262144,2097152,8388608,33554432,536870912,1073741824,2147483648,0,1610612736,2147483648,0,0,1,524288,1048576,12582912,0,0,0,151311,264503296,2097152,8388608,33554432,1610612736,2147483648,262144,8388608,33554432,536870912,67108864,4194304,0,4194304,0,4194304,4194304,0,0,524288,8388608,536870912,1073741824,2147483648,1,4097,8388609,96,2048,32768,1073741824,2147483648,0,96,2048,2147483648,0,0,96,2048,0,0,1,12582912,0,0,0,0,1641895695,1641895695,0,0,0,249,7404800,15,87808,1835008,1639972864,0,768,5120,16384,65536,1835008,1835008,12582912,16777216,1610612736,0,3,4,8,768,4096,65536,0,0,256,512,786432,8,256,512,4096,16384,1835008,16384,1835008,12582912,1610612736,0,0,0,256,0,0,0,4,8,16,32,1,2,8,256,16384,524288,16384,524288,1048576,12582912,1610612736,0,0,0,8388608,0,0,0,524288,4194304,0,0,0,8388608,-548662288,-548662288,-548662288,0,0,256,16384,65536,520093696,-1073741824,0,0,0,16777216,0,16,32,960,4096,4980736,520093696,1073741824,0,32,896,4096,57344,1048576,6291456,8388608,16777216,100663296,134217728,268435456,2147483648,0,512,786432,4194304,33554432,134217728,268435456,0,786432,4194304,134217728,268435456,0,524288,4194304,268435456,0,0,0,0,0,4194304,4194304,-540651761,0,0,0,2,4,8,16,96,128,264503296,-805306368,0,0,0,8,256,512,19456,131072,3072,16384,131072,262144,8388608,16777216,512,1024,2048,16384,131072,262144,131072,262144,8388608,33554432,201326592,268435456,0,3,4,256,1024,2048,57344,16384,131072,8388608,33554432,134217728,268435456,0,3,256,1024,16384,131072,33554432,134217728,1073741824,2147483648,0,0,256,524288,2147483648,0,3,256,33554432,134217728,1073741824,0,1,2,33554432,1,2,134217728,1073741824,0,1,2,134217728,0,0,0,64,0,0,0,16,32,896,4096,786432,4194304,16777216,33554432,201326592,268435456,1073741824,2147483648,0,0,0,15,0,4980736,4980736,4980736,70460,70460,3478332,0,0,1008,4984832,520093696,60,4864,65536,0,0,0,12,16,32,256,512,4096,65536,0,0,0,67108864,0,0,0,12,0,256,512,65536,0,0,1024,512,131072,131072,4,16,32,65536,0,4,16,32,0,0,0,4,16,0,0,16384,67108864,0,0,1,24,96,128,256,1024],r.TOKEN=["(0)","JSONChar","JSONCharRef","JSONPredefinedCharRef","ModuleDecl","Annotation","OptionDecl","Operator","Variable","Tag","EndTag","PragmaContents","DirCommentContents","DirPIContents","CDataSectionContents","AttrTest","Wildcard","EQName","IntegerLiteral","DecimalLiteral","DoubleLiteral","PredefinedEntityRef","'\"\"'","EscapeApos","AposChar","ElementContentChar","QuotAttrContentChar","AposAttrContentChar","NCName","QName","S","CharRef","CommentContents","DocTag","DocCommentContents","EOF","'!'","'\"'","'#'","'#)'","'$$'","''''","'('","'(#'","'(:'","'(:~'","')'","'*'","'*'","','","'-->'","'.'","'/'","'/>'","':'","':)'","';'","'<!--'","'<![CDATA['","'<?'","'='","'>'","'?'","'?>'","'NaN'","'['","']'","']]>'","'after'","'all'","'allowing'","'ancestor'","'ancestor-or-self'","'and'","'any'","'append'","'array'","'as'","'ascending'","'at'","'attribute'","'base-uri'","'before'","'boundary-space'","'break'","'by'","'case'","'cast'","'castable'","'catch'","'check'","'child'","'collation'","'collection'","'comment'","'constraint'","'construction'","'contains'","'content'","'context'","'continue'","'copy'","'copy-namespaces'","'count'","'decimal-format'","'decimal-separator'","'declare'","'default'","'delete'","'descendant'","'descendant-or-self'","'descending'","'diacritics'","'different'","'digit'","'distance'","'div'","'document'","'document-node'","'element'","'else'","'empty'","'empty-sequence'","'encoding'","'end'","'entire'","'eq'","'every'","'exactly'","'except'","'exit'","'external'","'first'","'following'","'following-sibling'","'for'","'foreach'","'foreign'","'from'","'ft-option'","'ftand'","'ftnot'","'ftor'","'function'","'ge'","'greatest'","'group'","'grouping-separator'","'gt'","'idiv'","'if'","'import'","'in'","'index'","'infinity'","'inherit'","'insensitive'","'insert'","'instance'","'integrity'","'intersect'","'into'","'is'","'item'","'json'","'json-item'","'key'","'language'","'last'","'lax'","'le'","'least'","'let'","'levels'","'loop'","'lowercase'","'lt'","'minus-sign'","'mod'","'modify'","'module'","'most'","'namespace'","'namespace-node'","'ne'","'next'","'no'","'no-inherit'","'no-preserve'","'node'","'nodes'","'not'","'object'","'occurs'","'of'","'on'","'only'","'option'","'or'","'order'","'ordered'","'ordering'","'paragraph'","'paragraphs'","'parent'","'pattern-separator'","'per-mille'","'percent'","'phrase'","'position'","'preceding'","'preceding-sibling'","'preserve'","'previous'","'processing-instruction'","'relationship'","'rename'","'replace'","'return'","'returning'","'revalidation'","'same'","'satisfies'","'schema'","'schema-attribute'","'schema-element'","'score'","'self'","'sensitive'","'sentence'","'sentences'","'skip'","'sliding'","'some'","'stable'","'start'","'stemming'","'stop'","'strict'","'strip'","'structured-item'","'switch'","'text'","'then'","'thesaurus'","'times'","'to'","'treat'","'try'","'tumbling'","'type'","'typeswitch'","'union'","'unique'","'unordered'","'updating'","'uppercase'","'using'","'validate'","'value'","'variable'","'version'","'weight'","'when'","'where'","'while'","'wildcards'","'window'","'with'","'without'","'word'","'words'","'xquery'","'zero-digit'","'{'","'{{'","'|'","'}'","'}}'"]},{}],2:[function(e,t,n){"use strict";var r=e("./JSONiqTokenizer").JSONiqTokenizer,i=function(e){var t=e;this.tokens=[],this.reset=function(){t=t,this.tokens=[]},this.startNonterminal=function(){},this.endNonterminal=function(){},this.terminal=function(e,n,r){this.tokens.push({name:e,value:t.substring(n,r)})},this.whitespace=function(e,n){this.tokens.push({name:"WS",value:t.substring(e,n)})}},s="NaN|after|allowing|ancestor|ancestor-or-self|and|append|array|as|ascending|at|attribute|base-uri|before|boundary-space|break|by|case|cast|castable|catch|child|collation|comment|constraint|construction|contains|context|continue|copy|copy-namespaces|count|decimal-format|decimal-separator|declare|default|delete|descendant|descendant-or-self|descending|digit|div|document|document-node|element|else|empty|empty-sequence|encoding|end|eq|every|except|exit|external|false|first|following|following-sibling|for|from|ft-option|function|ge|greatest|group|grouping-separator|gt|idiv|if|import|in|index|infinity|insert|instance|integrity|intersect|into|is|item|json|json-item|jsoniq|last|lax|le|least|let|loop|lt|minus-sign|mod|modify|module|namespace|namespace-node|ne|next|node|nodes|not|null|object|of|only|option|or|order|ordered|ordering|paragraphs|parent|pattern-separator|per-mille|percent|preceding|preceding-sibling|previous|processing-instruction|rename|replace|return|returning|revalidation|satisfies|schema|schema-attribute|schema-element|score|select|self|sentences|sliding|some|stable|start|strict|switch|text|then|times|to|treat|true|try|tumbling|type|typeswitch|union|unordered|updating|validate|value|variable|version|when|where|while|window|with|words|xquery|zero-digit".split("|"),o=s.map(function(e){return{name:"'"+e+"'",token:"keyword"}}),u=s.map(function(e){return{name:"'"+e+"'",token:"text",next:function(e){e.pop()}}}),a="constant.language",f="constant",l="comment",c="xml-pe",h="constant.buildin",p=function(e){return"'"+e+"'"},d={start:[{name:p("(#"),token:h,next:function(e){e.push("Pragma")}},{name:p("(:"),token:"comment",next:function(e){e.push("Comment")}},{name:p("(:~"),token:"comment.doc",next:function(e){e.push("CommentDoc")}},{name:p("<!--"),token:l,next:function(e){e.push("XMLComment")}},{name:p("<?"),token:c,next:function(e){e.push("PI")}},{name:p("''"),token:"string",next:function(e){e.push("AposString")}},{name:p('"'),token:"string",next:function(e){e.push("QuotString")}},{name:"Annotation",token:"support.function"},{name:"ModuleDecl",token:"keyword",next:function(e){e.push("Prefix")}},{name:"OptionDecl",token:"keyword",next:function(e){e.push("_EQName")}},{name:"AttrTest",token:"support.type"},{name:"Variable",token:"variable"},{name:p("<![CDATA["),token:a,next:function(e){e.push("CData")}},{name:"IntegerLiteral",token:f},{name:"DecimalLiteral",token:f},{name:"DoubleLiteral",token:f},{name:"Operator",token:"keyword.operator"},{name:"EQName",token:function(e){return s.indexOf(e)!==-1?"keyword":"support.function"}},{name:p("("),token:"lparen"},{name:p(")"),token:"rparen"},{name:"Tag",token:"meta.tag",next:function(e){e.push("StartTag")}},{name:p("}"),token:"text",next:function(e){e.length>1&&e.pop()}},{name:p("{"),token:"text",next:function(e){e.push("start")}}].concat(o),_EQName:[{name:"EQName",token:"text",next:function(e){e.pop()}}].concat(u),Prefix:[{name:"NCName",token:"text",next:function(e){e.pop()}}].concat(u),StartTag:[{name:p(">"),token:"meta.tag",next:function(e){e.push("TagContent")}},{name:"QName",token:"entity.other.attribute-name"},{name:p("="),token:"text"},{name:p("''"),token:"string",next:function(e){e.push("AposAttr")}},{name:p('"'),token:"string",next:function(e){e.push("QuotAttr")}},{name:p("/>"),token:"meta.tag.r",next:function(e){e.pop()}}],TagContent:[{name:"ElementContentChar",token:"text"},{name:p("<![CDATA["),token:a,next:function(e){e.push("CData")}},{name:p("<!--"),token:l,next:function(e){e.push("XMLComment")}},{name:"Tag",token:"meta.tag",next:function(e){e.push("StartTag")}},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:p("{{"),token:"text"},{name:p("}}"),token:"text"},{name:p("{"),token:"text",next:function(e){e.push("start")}},{name:"EndTag",token:"meta.tag",next:function(e){e.pop(),e.pop()}}],AposAttr:[{name:p("''"),token:"string",next:function(e){e.pop()}},{name:"EscapeApos",token:"constant.language.escape"},{name:"AposAttrContentChar",token:"string"},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:p("{{"),token:"string"},{name:p("}}"),token:"string"},{name:p("{"),token:"text",next:function(e){e.push("start")}}],QuotAttr:[{name:p('"'),token:"string",next:function(e){e.pop()}},{name:"EscapeQuot",token:"constant.language.escape"},{name:"QuotAttrContentChar",token:"string"},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:p("{{"),token:"string"},{name:p("}}"),token:"string"},{name:p("{"),token:"text",next:function(e){e.push("start")}}],Pragma:[{name:"PragmaContents",token:h},{name:p("#"),token:h},{name:p("#)"),token:h,next:function(e){e.pop()}}],Comment:[{name:"CommentContents",token:"comment"},{name:p("(:"),token:"comment",next:function(e){e.push("Comment")}},{name:p(":)"),token:"comment",next:function(e){e.pop()}}],CommentDoc:[{name:"DocCommentContents",token:"comment.doc"},{name:"DocTag",token:"comment.doc.tag"},{name:p("(:"),token:"comment.doc",next:function(e){e.push("CommentDoc")}},{name:p(":)"),token:"comment.doc",next:function(e){e.pop()}}],XMLComment:[{name:"DirCommentContents",token:l},{name:p("-->"),token:l,next:function(e){e.pop()}}],CData:[{name:"CDataSectionContents",token:a},{name:p("]]>"),token:a,next:function(e){e.pop()}}],PI:[{name:"DirPIContents",token:c},{name:p("?"),token:c},{name:p("?>"),token:c,next:function(e){e.pop()}}],AposString:[{name:p("''"),token:"string",next:function(e){e.pop()}},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:"EscapeApos",token:"constant.language.escape"},{name:"AposChar",token:"string"}],QuotString:[{name:p('"'),token:"string",next:function(e){e.pop()}},{name:"JSONPredefinedCharRef",token:"constant.language.escape"},{name:"JSONCharRef",token:"constant.language.escape"},{name:"JSONChar",token:"string"}]};n.JSONiqLexer=function(){this.tokens=[],this.getLineTokens=function(e,t){t=t==="start"||!t?'["start"]':t;var n=JSON.parse(t),s=new i(e),o=new r(e,s),u=[];for(;;){var a=n[n.length-1];try{s.tokens=[],o["parse_"+a]();var f=null;s.tokens.length>1&&s.tokens[0].name==="WS"&&(u.push({type:"text",value:s.tokens[0].value}),s.tokens.splice(0,1));var l=s.tokens[0],c=d[a];for(var h=0;h<c.length;h++){var p=d[a][h];if(typeof p.name=="function"&&p.name(l)||p.name===l.name){f=p;break}}if(l.name==="EOF")break;if(l.value==="")throw"Encountered empty string lexical rule.";u.push({type:f===null?"text":typeof f.token=="function"?f.token(l.value):f.token,value:l.value}),f&&f.next&&f.next(n)}catch(v){if(v instanceof o.ParseException){var m=0;for(var g=0;g<u.length;g++)m+=u[g].value.length;return u.push({type:"text",value:e.substring(m)}),{tokens:u,state:JSON.stringify(["start"])}}throw v}}return{tokens:u,state:JSON.stringify(n)}}}},{"./JSONiqTokenizer":1}]},{},[2])(2)}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/behaviour/xquery",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/mode/behaviour/xml","ace/token_iterator"],function(e,t,n){"use strict";function a(e,t){var n=!0,r=e.type.split("."),i=t.split(".");return i.forEach(function(e){if(r.indexOf(e)==-1)return n=!1,!1}),n}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../behaviour/xml").XmlBehaviour,u=e("../../token_iterator").TokenIterator,f=function(){this.inherit(s,["braces","parens","string_dquotes"]),this.inherit(o),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var s=n.getCursorPosition(),o=new u(r,s.row,s.column),f=o.getCurrentToken(),l=!1,e=JSON.parse(e).pop();if(f&&f.value===">"||e!=="StartTag")return;if(!f||!a(f,"meta.tag")&&(!a(f,"text")||!f.value.match("/"))){do f=o.stepBackward();while(f&&(a(f,"string")||a(f,"keyword.operator")||a(f,"entity.attribute-name")||a(f,"text")))}else l=!0;var c=o.stepBackward();if(!f||!a(f,"meta.tag")||c!==null&&c.value.match("/"))return;var h=f.value.substring(1);if(l)var h=h.substring(0,s.column-f.start);return{text:"></"+h+">",selection:[1,1]}}})};r.inherits(f,i),t.XQueryBehaviour=f}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/anchor","ace/keyboard/hash_handler","ace/tokenizer","ace/lib/dom","ace/editor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./lib/lang"),o=e("./range").Range,u=e("./anchor").Anchor,a=e("./keyboard/hash_handler").HashHandler,f=e("./tokenizer").Tokenizer,l=o.comparePoints,c=function(){this.snippetMap={},this.snippetNameMap={}};(function(){r.implement(this,i),this.getTokenizer=function(){function e(e,t,n){return e=e.substr(1),/^\d+$/.test(e)&&!n.inFormatString?[{tabstopId:parseInt(e,10)}]:[{text:e}]}function t(e){return"(?:[^\\\\"+e+"]|\\\\.)"}return c.$tokenizer=new f({start:[{regex:/:/,onMatch:function(e,t,n){return n.length&&n[0].expectIf?(n[0].expectIf=!1,n[0].elseBranch=n[0],[n[0]]):":"}},{regex:/\\./,onMatch:function(e,t,n){var r=e[1];return r=="}"&&n.length?e=r:"`$\\".indexOf(r)!=-1?e=r:n.inFormatString&&(r=="n"?e="\n":r=="t"?e="\n":"ulULE".indexOf(r)!=-1&&(e={changeCase:r,local:r>"a"})),[e]}},{regex:/}/,onMatch:function(e,t,n){return[n.length?n.shift():e]}},{regex:/\$(?:\d+|\w+)/,onMatch:e},{regex:/\$\{[\dA-Z_a-z]+/,onMatch:function(t,n,r){var i=e(t.substr(1),n,r);return r.unshift(i[0]),i},next:"snippetVar"},{regex:/\n/,token:"newline",merge:!1}],snippetVar:[{regex:"\\|"+t("\\|")+"*\\|",onMatch:function(e,t,n){n[0].choices=e.slice(1,-1).split(",")},next:"start"},{regex:"/("+t("/")+"+)/(?:("+t("/")+"*)/)(\\w*):?",onMatch:function(e,t,n){var r=n[0];return r.fmtString=e,e=this.splitRegex.exec(e),r.guard=e[1],r.fmt=e[2],r.flag=e[3],""},next:"start"},{regex:"`"+t("`")+"*`",onMatch:function(e,t,n){return n[0].code=e.splice(1,-1),""},next:"start"},{regex:"\\?",onMatch:function(e,t,n){n[0]&&(n[0].expectIf=!0)},next:"start"},{regex:"([^:}\\\\]|\\\\.)*:?",token:"",next:"start"}],formatString:[{regex:"/("+t("/")+"+)/",token:"regex"},{regex:"",onMatch:function(e,t,n){n.inFormatString=!0},next:"start"}]}),c.prototype.getTokenizer=function(){return c.$tokenizer},c.$tokenizer},this.tokenizeTmSnippet=function(e,t){return this.getTokenizer().getLineTokens(e,t).tokens.map(function(e){return e.value||e})},this.$getDefaultValue=function(e,t){if(/^[A-Z]\d+$/.test(t)){var n=t.substr(1);return(this.variables[t[0]+"__"]||{})[n]}if(/^\d+$/.test(t))return(this.variables.__||{})[t];t=t.replace(/^TM_/,"");if(!e)return;var r=e.session;switch(t){case"CURRENT_WORD":var i=r.getWordRange();case"SELECTION":case"SELECTED_TEXT":return r.getTextRange(i);case"CURRENT_LINE":return r.getLine(e.getCursorPosition().row);case"PREV_LINE":return r.getLine(e.getCursorPosition().row-1);case"LINE_INDEX":return e.getCursorPosition().column;case"LINE_NUMBER":return e.getCursorPosition().row+1;case"SOFT_TABS":return r.getUseSoftTabs()?"YES":"NO";case"TAB_SIZE":return r.getTabSize();case"FILENAME":case"FILEPATH":return"";case"FULLNAME":return"Ace"}},this.variables={},this.getVariableValue=function(e,t){return this.variables.hasOwnProperty(t)?this.variables[t](e,t)||"":this.$getDefaultValue(e,t)||""},this.tmStrFormat=function(e,t,n){var r=t.flag||"",i=t.guard;i=new RegExp(i,r.replace(/[^gi]/,""));var s=this.tokenizeTmSnippet(t.fmt,"formatString"),o=this,u=e.replace(i,function(){o.variables.__=arguments;var e=o.resolveVariables(s,n),t="E";for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="object"){e[r]="";if(i.changeCase&&i.local){var u=e[r+1];u&&typeof u=="string"&&(i.changeCase=="u"?e[r]=u[0].toUpperCase():e[r]=u[0].toLowerCase(),e[r+1]=u.substr(1))}else i.changeCase&&(t=i.changeCase)}else t=="U"?e[r]=i.toUpperCase():t=="L"&&(e[r]=i.toLowerCase())}return e.join("")});return this.variables.__=null,u},this.resolveVariables=function(e,t){function o(t){var n=e.indexOf(t,r+1);n!=-1&&(r=n)}var n=[];for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="string")n.push(i);else{if(typeof i!="object")continue;if(i.skip)o(i);else{if(i.processed<r)continue;if(i.text){var s=this.getVariableValue(t,i.text);s&&i.fmtString&&(s=this.tmStrFormat(s,i)),i.processed=r,i.expectIf==null?s&&(n.push(s),o(i)):s?i.skip=i.elseBranch:o(i)}else i.tabstopId!=null?n.push(i):i.changeCase!=null&&n.push(i)}}}return n},this.insertSnippetForSelection=function(e,t){function f(e){var t=[];for(var n=0;n<e.length;n++){var r=e[n];if(typeof r=="object"){if(a[r.tabstopId])continue;var i=e.lastIndexOf(r,n-1);r=t[i]||{tabstopId:r.tabstopId}}t[n]=r}return t}var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=e.session.getTabString(),s=r.match(/^\s*/)[0];n.column<s.length&&(s=s.slice(0,n.column));var o=this.tokenizeTmSnippet(t);o=this.resolveVariables(o,e),o=o.map(function(e){return e=="\n"?e+s:typeof e=="string"?e.replace(/\t/g,i):e});var u=[];o.forEach(function(e,t){if(typeof e!="object")return;var n=e.tabstopId,r=u[n];r||(r=u[n]=[],r.index=n,r.value="");if(r.indexOf(e)!==-1)return;r.push(e);var i=o.indexOf(e,t+1);if(i===-1)return;var s=o.slice(t+1,i),a=s.some(function(e){return typeof e=="object"});a&&!r.value?r.value=s:s.length&&(!r.value||typeof r.value!="string")&&(r.value=s.join(""))}),u.forEach(function(e){e.length=0});var a={};for(var l=0;l<o.length;l++){var c=o[l];if(typeof c!="object")continue;var p=c.tabstopId,d=o.indexOf(c,l+1);if(a[p]){a[p]===c&&(a[p]=null);continue}var v=u[p],m=typeof v.value=="string"?[v.value]:f(v.value);m.unshift(l+1,Math.max(0,d-l)),m.push(c),a[p]=c,o.splice.apply(o,m),v.indexOf(c)===-1&&v.push(c)}var g=0,y=0,b="";o.forEach(function(e){typeof e=="string"?(e[0]==="\n"?(y=e.length-1,g++):y+=e.length,b+=e):e.start?e.end={row:g,column:y}:e.start={row:g,column:y}});var w=e.getSelectionRange(),E=e.session.replace(w,b),S=new h(e),x=e.inVirtualSelectionMode&&e.selection.index;S.addTabstops(u,w.start,E,x)},this.insertSnippet=function(e,t){var n=this;if(e.inVirtualSelectionMode)return n.insertSnippetForSelection(e,t);e.forEachSelection(function(){n.insertSnippetForSelection(e,t)},null,{keepOrder:!0}),e.tabstopManager&&e.tabstopManager.tabNext()},this.$getScope=function(e){var t=e.session.$mode.$id||"";t=t.split("/").pop();if(t==="html"||t==="php"){t==="php"&&!e.session.$mode.inlinePhp&&(t="html");var n=e.getCursorPosition(),r=e.session.getState(n.row);typeof r=="object"&&(r=r[0]),r.substring&&(r.substring(0,3)=="js-"?t="javascript":r.substring(0,4)=="css-"?t="css":r.substring(0,4)=="php-"&&(t="php"))}return t},this.getActiveScopes=function(e){var t=this.$getScope(e),n=[t],r=this.snippetMap;return r[t]&&r[t].includeScopes&&n.push.apply(n,r[t].includeScopes),n.push("_"),n},this.expandWithTab=function(e,t){var n=this,r=e.forEachSelection(function(){return n.expandSnippetForSelection(e,t)},null,{keepOrder:!0});return r&&e.tabstopManager&&e.tabstopManager.tabNext(),r},this.expandSnippetForSelection=function(e,t){var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=r.substring(0,n.column),s=r.substr(n.column),o=this.snippetMap,u;return this.getActiveScopes(e).some(function(e){var t=o[e];return t&&(u=this.findMatchingSnippet(t,i,s)),!!u},this),u?t&&t.dryRun?!0:(e.session.doc.removeInLine(n.row,n.column-u.replaceBefore.length,n.column+u.replaceAfter.length),this.variables.M__=u.matchBefore,this.variables.T__=u.matchAfter,this.insertSnippetForSelection(e,u.content),this.variables.M__=this.variables.T__=null,!0):!1},this.findMatchingSnippet=function(e,t,n){for(var r=e.length;r--;){var i=e[r];if(i.startRe&&!i.startRe.test(t))continue;if(i.endRe&&!i.endRe.test(n))continue;if(!i.startRe&&!i.endRe)continue;return i.matchBefore=i.startRe?i.startRe.exec(t):[""],i.matchAfter=i.endRe?i.endRe.exec(n):[""],i.replaceBefore=i.triggerRe?i.triggerRe.exec(t)[0]:"",i.replaceAfter=i.endTriggerRe?i.endTriggerRe.exec(n)[0]:"",i}},this.snippetMap={},this.snippetNameMap={},this.register=function(e,t){function o(e){return e&&!/^\^?\(.*\)\$?$|^\\b$/.test(e)&&(e="(?:"+e+")"),e||""}function u(e,t,n){return e=o(e),t=o(t),n?(e=t+e,e&&e[e.length-1]!="$"&&(e+="$")):(e+=t,e&&e[0]!="^"&&(e="^"+e)),new RegExp(e)}function a(e){e.scope||(e.scope=t||"_"),t=e.scope,n[t]||(n[t]=[],r[t]={});var o=r[t];if(e.name){var a=o[e.name];a&&i.unregister(a),o[e.name]=e}n[t].push(e),e.tabTrigger&&!e.trigger&&(!e.guard&&/^\w/.test(e.tabTrigger)&&(e.guard="\\b"),e.trigger=s.escapeRegExp(e.tabTrigger)),e.startRe=u(e.trigger,e.guard,!0),e.triggerRe=new RegExp(e.trigger,"",!0),e.endRe=u(e.endTrigger,e.endGuard,!0),e.endTriggerRe=new RegExp(e.endTrigger,"",!0)}var n=this.snippetMap,r=this.snippetNameMap,i=this;e.content?a(e):Array.isArray(e)&&e.forEach(a),this._signal("registerSnippets",{scope:t})},this.unregister=function(e,t){function i(e){var i=r[e.scope||t];if(i&&i[e.name]){delete i[e.name];var s=n[e.scope||t],o=s&&s.indexOf(e);o>=0&&s.splice(o,1)}}var n=this.snippetMap,r=this.snippetNameMap;e.content?i(e):Array.isArray(e)&&e.forEach(i)},this.parseSnippetFile=function(e){e=e.replace(/\r/g,"");var t=[],n={},r=/^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm,i;while(i=r.exec(e)){if(i[1])try{n=JSON.parse(i[1]),t.push(n)}catch(s){}if(i[4])n.content=i[4].replace(/^\t/gm,""),t.push(n),n={};else{var o=i[2],u=i[3];if(o=="regex"){var a=/\/((?:[^\/\\]|\\.)*)|$/g;n.guard=a.exec(u)[1],n.trigger=a.exec(u)[1],n.endTrigger=a.exec(u)[1],n.endGuard=a.exec(u)[1]}else o=="snippet"?(n.tabTrigger=u.match(/^\S*/)[0],n.name||(n.name=u)):n[o]=u}}return t},this.getSnippetByName=function(e,t){var n=this.snippetNameMap,r;return this.getActiveScopes(t).some(function(t){var i=n[t];return i&&(r=i[e]),!!r},this),r}}).call(c.prototype);var h=function(e){if(e.tabstopManager)return e.tabstopManager;e.tabstopManager=this,this.$onChange=this.onChange.bind(this),this.$onChangeSelection=s.delayedCall(this.onChangeSelection.bind(this)).schedule,this.$onChangeSession=this.onChangeSession.bind(this),this.$onAfterExec=this.onAfterExec.bind(this),this.attach(e)};(function(){this.attach=function(e){this.index=0,this.ranges=[],this.tabstops=[],this.$openTabstops=null,this.selectedTabstop=null,this.editor=e,this.editor.on("change",this.$onChange),this.editor.on("changeSelection",this.$onChangeSelection),this.editor.on("changeSession",this.$onChangeSession),this.editor.commands.on("afterExec",this.$onAfterExec),this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.detach=function(){this.tabstops.forEach(this.removeTabstopMarkers,this),this.ranges=null,this.tabstops=null,this.selectedTabstop=null,this.editor.removeListener("change",this.$onChange),this.editor.removeListener("changeSelection",this.$onChangeSelection),this.editor.removeListener("changeSession",this.$onChangeSession),this.editor.commands.removeListener("afterExec",this.$onAfterExec),this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.tabstopManager=null,this.editor=null},this.onChange=function(e){var t=e.data.range,n=e.data.action[0]=="r",r=t.start,i=t.end,s=r.row,o=i.row,u=o-s,a=i.column-r.column;n&&(u=-u,a=-a);if(!this.$inChange&&n){var f=this.selectedTabstop,c=f&&!f.some(function(e){return l(e.start,r)<=0&&l(e.end,i)>=0});if(c)return this.detach()}var h=this.ranges;for(var p=0;p<h.length;p++){var d=h[p];if(d.end.row<r.row)continue;if(n&&l(r,d.start)<0&&l(i,d.end)>0){this.removeRange(d),p--;continue}d.start.row==s&&d.start.column>r.column&&(d.start.column+=a),d.end.row==s&&d.end.column>=r.column&&(d.end.column+=a),d.start.row>=s&&(d.start.row+=u),d.end.row>=s&&(d.end.row+=u),l(d.start,d.end)>0&&this.removeRange(d)}h.length||this.detach()},this.updateLinkedFields=function(){var e=this.selectedTabstop;if(!e||!e.hasLinkedRanges)return;this.$inChange=!0;var n=this.editor.session,r=n.getTextRange(e.firstNonLinked);for(var i=e.length;i--;){var s=e[i];if(!s.linked)continue;var o=t.snippetManager.tmStrFormat(r,s.original);n.replace(s,o)}this.$inChange=!1},this.onAfterExec=function(e){e.command&&!e.command.readOnly&&this.updateLinkedFields()},this.onChangeSelection=function(){if(!this.editor)return;var e=this.editor.selection.lead,t=this.editor.selection.anchor,n=this.editor.selection.isEmpty();for(var r=this.ranges.length;r--;){if(this.ranges[r].linked)continue;var i=this.ranges[r].contains(e.row,e.column),s=n||this.ranges[r].contains(t.row,t.column);if(i&&s)return}this.detach()},this.onChangeSession=function(){this.detach()},this.tabNext=function(e){var t=this.tabstops.length,n=this.index+(e||1);n=Math.min(Math.max(n,1),t),n==t&&(n=0),this.selectTabstop(n),n===0&&this.detach()},this.selectTabstop=function(e){this.$openTabstops=null;var t=this.tabstops[this.index];t&&this.addTabstopMarkers(t),this.index=e,t=this.tabstops[this.index];if(!t||!t.length)return;this.selectedTabstop=t;if(!this.editor.inVirtualSelectionMode){var n=this.editor.multiSelect;n.toSingleRange(t.firstNonLinked.clone());for(var r=t.length;r--;){if(t.hasLinkedRanges&&t[r].linked)continue;n.addRange(t[r].clone(),!0)}n.ranges[0]&&n.addRange(n.ranges[0].clone())}else this.editor.selection.setRange(t.firstNonLinked);this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.addTabstops=function(e,t,n){this.$openTabstops||(this.$openTabstops=[]);if(!e[0]){var r=o.fromPoints(n,n);v(r.start,t),v(r.end,t),e[0]=[r],e[0].index=0}var i=this.index,s=[i+1,0],u=this.ranges;e.forEach(function(e,n){var r=this.$openTabstops[n]||e;for(var i=e.length;i--;){var a=e[i],f=o.fromPoints(a.start,a.end||a.start);d(f.start,t),d(f.end,t),f.original=a,f.tabstop=r,u.push(f),r!=e?r.unshift(f):r[i]=f,a.fmtString?(f.linked=!0,r.hasLinkedRanges=!0):r.firstNonLinked||(r.firstNonLinked=f)}r.firstNonLinked||(r.hasLinkedRanges=!1),r===e&&(s.push(r),this.$openTabstops[n]=r),this.addTabstopMarkers(r)},this),s.length>2&&(this.tabstops.length&&s.push(s.splice(2,1)[0]),this.tabstops.splice.apply(this.tabstops,s))},this.addTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){e.markerId||(e.markerId=t.addMarker(e,"ace_snippet-marker","text"))})},this.removeTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){t.removeMarker(e.markerId),e.markerId=null})},this.removeRange=function(e){var t=e.tabstop.indexOf(e);e.tabstop.splice(t,1),t=this.ranges.indexOf(e),this.ranges.splice(t,1),this.editor.session.removeMarker(e.markerId),e.tabstop.length||(t=this.tabstops.indexOf(e.tabstop),t!=-1&&this.tabstops.splice(t,1),this.tabstops.length||this.detach())},this.keyboardHandler=new a,this.keyboardHandler.bindKeys({Tab:function(e){if(t.snippetManager&&t.snippetManager.expandWithTab(e))return;e.tabstopManager.tabNext(1)},"Shift-Tab":function(e){e.tabstopManager.tabNext(-1)},Esc:function(e){e.tabstopManager.detach()},Return:function(e){return!1}})}).call(h.prototype);var p={};p.onChange=u.prototype.onChange,p.setPosition=function(e,t){this.pos.row=e,this.pos.column=t},p.update=function(e,t,n){this.$insertRight=n,this.pos=e,this.onChange(t)};var d=function(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row},v=function(e,t){e.row==t.row&&(e.column-=t.column),e.row-=t.row};e("./lib/dom").importCssString(".ace_snippet-marker {    -moz-box-sizing: border-box;    box-sizing: border-box;    background: rgba(194, 193, 208, 0.09);    border: 1px dotted rgba(211, 208, 235, 0.62);    position: absolute;}"),t.snippetManager=new c;var m=e("./editor").Editor;(function(){this.insertSnippet=function(e,n){return t.snippetManager.insertSnippet(this,e,n)},this.expandSnippet=function(e){return t.snippetManager.expandWithTab(this,e)}}).call(m.prototype)}),ace.define("ace/autocomplete/popup",["require","exports","module","ace/edit_session","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../edit_session").EditSession,i=e("../virtual_renderer").VirtualRenderer,s=e("../editor").Editor,o=e("../range").Range,u=e("../lib/event"),a=e("../lib/lang"),f=e("../lib/dom"),l=function(e){var t=new i(e);t.$maxLines=4;var n=new s(t);return n.setHighlightActiveLine(!1),n.setShowPrintMargin(!1),n.renderer.setShowGutter(!1),n.renderer.setHighlightGutterLine(!1),n.$mouseHandler.$focusWaitTimout=0,n},c=function(e){var t=f.createElement("div"),n=new l(t);e&&e.appendChild(t),t.style.display="none",n.renderer.content.style.cursor="default",n.renderer.setStyle("ace_autocomplete"),n.setOption("displayIndentGuides",!1),n.setOption("dragDelay",150);var r=function(){};n.focus=r,n.$isFocused=!0,n.renderer.$cursorLayer.restartTimer=r,n.renderer.$cursorLayer.element.style.opacity=0,n.renderer.$maxLines=8,n.renderer.$keepTextAreaAtCursor=!1,n.setHighlightActiveLine(!1),n.session.highlight(""),n.session.$searchHighlight.clazz="ace_highlight-marker",n.on("mousedown",function(e){var t=e.getDocumentPosition();n.selection.moveToPosition(t),c.start.row=c.end.row=t.row,e.stop()});var i,s=new o(-1,0,-1,Infinity),c=new o(-1,0,-1,Infinity);c.id=n.session.addMarker(c,"ace_active-line","fullLine"),n.setSelectOnHover=function(e){e?s.id&&(n.session.removeMarker(s.id),s.id=null):s.id=n.session.addMarker(s,"ace_line-hover","fullLine")},n.setSelectOnHover(!1),n.on("mousemove",function(e){if(!i){i=e;return}if(i.x==e.x&&i.y==e.y)return;i=e,i.scrollTop=n.renderer.scrollTop;var t=i.getDocumentPosition().row;s.start.row!=t&&(s.id||n.setRow(t),p(t))}),n.renderer.on("beforeRender",function(){if(i&&s.start.row!=-1){i.$pos=null;var e=i.getDocumentPosition().row;s.id||n.setRow(e),p(e,!0)}}),n.renderer.on("afterRender",function(){var e=n.getRow(),t=n.renderer.$textLayer,r=t.element.childNodes[e-t.config.firstRow];if(r==t.selectedNode)return;t.selectedNode&&f.removeCssClass(t.selectedNode,"ace_selected"),t.selectedNode=r,r&&f.addCssClass(r,"ace_selected")});var h=function(){p(-1)},p=function(e,t){e!==s.start.row&&(s.start.row=s.end.row=e,t||n.session._emit("changeBackMarker"),n._emit("changeHoverMarker"))};n.getHoveredRow=function(){return s.start.row},u.addListener(n.container,"mouseout",h),n.on("hide",h),n.on("changeSelection",h),n.session.doc.getLength=function(){return n.data.length},n.session.doc.getLine=function(e){var t=n.data[e];return typeof t=="string"?t:t&&t.value||""};var d=n.session.bgTokenizer;return d.$tokenizeRow=function(e){var t=n.data[e],r=[];if(!t)return r;typeof t=="string"&&(t={value:t}),t.caption||(t.caption=t.value||t.name);var i=-1,s,o;for(var e=0;e<t.caption.length;e++)o=t.caption[e],s=t.matchMask&1<<e?1:0,i!==s?(r.push({type:t.className||""+(s?"completion-highlight":""),value:o}),i=s):r[r.length-1].value+=o;if(t.meta){var u=n.renderer.$size.scrollerWidth/n.renderer.layerConfig.characterWidth;t.meta.length+t.caption.length<u-2&&r.push({type:"rightAlignedText",value:t.meta})}return r},d.$updateOnChange=r,d.start=r,n.session.$computeWidth=function(){return this.screenWidth=0},n.isOpen=!1,n.isTopdown=!1,n.data=[],n.setData=function(e){n.data=e||[],n.setValue(a.stringRepeat("\n",e.length),-1),n.setRow(0)},n.getData=function(e){return n.data[e]},n.getRow=function(){return c.start.row},n.setRow=function(e){e=Math.max(-1,Math.min(this.data.length,e)),c.start.row!=e&&(n.selection.clearSelection(),c.start.row=c.end.row=e||0,n.session._emit("changeBackMarker"),n.moveCursorTo(e||0,0),n.isOpen&&n._signal("select"))},n.on("changeSelection",function(){n.isOpen&&n.setRow(n.selection.lead.row)}),n.hide=function(){this.container.style.display="none",this._signal("hide"),n.isOpen=!1},n.show=function(e,t,r){var s=this.container,o=window.innerHeight,u=window.innerWidth,a=this.renderer,f=a.$maxLines*t*1.4,l=e.top+this.$borderSize;l+f>o-t&&!r?(s.style.top="",s.style.bottom=o-l+"px",n.isTopdown=!1):(l+=t,s.style.top=l+"px",s.style.bottom="",n.isTopdown=!0),s.style.display="",this.renderer.$textLayer.checkForSizeChanges();var c=e.left;c+s.offsetWidth>u&&(c=u-s.offsetWidth),s.style.left=c+"px",this._signal("show"),i=null,n.isOpen=!0},n.getTextLeftOffset=function(){return this.$borderSize+this.renderer.$padding+this.$imageSize},n.$imageSize=0,n.$borderSize=1,n};f.importCssString(".ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {    background-color: #CAD6FA;    z-index: 1;}.ace_editor.ace_autocomplete .ace_line-hover {    border: 1px solid #abbffe;    margin-top: -1px;    background: rgba(233,233,253,0.4);}.ace_editor.ace_autocomplete .ace_line-hover {    position: absolute;    z-index: 2;}.ace_editor.ace_autocomplete .ace_scroller {   background: none;   border: none;   box-shadow: none;}.ace_rightAlignedText {    color: gray;    display: inline-block;    position: absolute;    right: 4px;    text-align: right;    z-index: -1;}.ace_editor.ace_autocomplete .ace_completion-highlight{    color: #000;    text-shadow: 0 0 0.01em;}.ace_editor.ace_autocomplete {    width: 280px;    z-index: 200000;    background: #fbfbfb;    color: #444;    border: 1px lightgray solid;    position: fixed;    box-shadow: 2px 3px 5px rgba(0,0,0,.2);    line-height: 1.4;}"),t.AcePopup=c}),ace.define("ace/autocomplete/util",["require","exports","module"],function(e,t,n){"use strict";t.parForEach=function(e,t,n){var r=0,i=e.length;i===0&&n();for(var s=0;s<i;s++)t(e[s],function(e,t){r++,r===i&&n(e,t)})};var r=/[a-zA-Z_0-9\$\-\u00A2-\uFFFF]/;t.retrievePrecedingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t-1;s>=0;s--){if(!n.test(e[s]))break;i.push(e[s])}return i.reverse().join("")},t.retrieveFollowingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t;s<e.length;s++){if(!n.test(e[s]))break;i.push(e[s])}return i}}),ace.define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/event","ace/lib/lang","ace/snippets"],function(e,t,n){"use strict";var r=e("./keyboard/hash_handler").HashHandler,i=e("./autocomplete/popup").AcePopup,s=e("./autocomplete/util"),o=e("./lib/event"),u=e("./lib/lang"),a=e("./snippets").snippetManager,f=function(){this.autoInsert=!0,this.autoSelect=!0,this.keyboardHandler=new r,this.keyboardHandler.bindKeys(this.commands),this.blurListener=this.blurListener.bind(this),this.changeListener=this.changeListener.bind(this),this.mousedownListener=this.mousedownListener.bind(this),this.mousewheelListener=this.mousewheelListener.bind(this),this.changeTimer=u.delayedCall(function(){this.updateCompletions(!0)}.bind(this))};(function(){this.gatherCompletionsId=0,this.$init=function(){this.popup=new i(document.body||document.documentElement),this.popup.on("click",function(e){this.insertMatch(),e.stop()}.bind(this)),this.popup.focus=this.editor.focus.bind(this.editor)},this.openPopup=function(e,t,n){this.popup||this.$init(),this.popup.setData(this.completions.filtered);var r=e.renderer;this.popup.setRow(this.autoSelect?0:-1);if(!n){this.popup.setTheme(e.getTheme()),this.popup.setFontSize(e.getFontSize());var i=r.layerConfig.lineHeight,s=r.$cursorLayer.getPixelPosition(this.base,!0);s.left-=this.popup.getTextLeftOffset();var o=e.container.getBoundingClientRect();s.top+=o.top-r.layerConfig.offset,s.left+=o.left-e.renderer.scrollLeft,s.left+=r.$gutterLayer.gutterWidth,this.popup.show(s,i)}},this.detach=function(){this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.off("changeSelection",this.changeListener),this.editor.off("blur",this.blurListener),this.editor.off("mousedown",this.mousedownListener),this.editor.off("mousewheel",this.mousewheelListener),this.changeTimer.cancel(),this.popup&&this.popup.isOpen&&(this.gatherCompletionsId+=1,this.popup.hide()),this.base&&this.base.detach(),this.activated=!1,this.completions=this.base=null},this.changeListener=function(e){var t=this.editor.selection.lead;(t.row!=this.base.row||t.column<this.base.column)&&this.detach(),this.activated?this.changeTimer.schedule():this.detach()},this.blurListener=function(){var e=document.activeElement;e!=this.editor.textInput.getElement()&&e.parentNode!=this.popup.container&&this.detach()},this.mousedownListener=function(e){this.detach()},this.mousewheelListener=function(e){this.detach()},this.goTo=function(e){var t=this.popup.getRow(),n=this.popup.session.getLength()-1;switch(e){case"up":t=t<=0?n:t-1;break;case"down":t=t>=n?-1:t+1;break;case"start":t=0;break;case"end":t=n}this.popup.setRow(t)},this.insertMatch=function(e){e||(e=this.popup.getData(this.popup.getRow()));if(!e)return!1;if(e.completer&&e.completer.insertMatch)e.completer.insertMatch(this.editor);else{if(this.completions.filterText){var t=this.editor.selection.getAllRanges();for(var n=0,r;r=t[n];n++)r.start.column-=this.completions.filterText.length,this.editor.session.remove(r)}e.snippet?a.insertSnippet(this.editor,e.snippet):this.editor.execCommand("insertstring",e.value||e)}this.detach()},this.commands={Up:function(e){e.completer.goTo("up")},Down:function(e){e.completer.goTo("down")},"Ctrl-Up|Ctrl-Home":function(e){e.completer.goTo("start")},"Ctrl-Down|Ctrl-End":function(e){e.completer.goTo("end")},Esc:function(e){e.completer.detach()},Space:function(e){e.completer.detach(),e.insert(" ")},Return:function(e){return e.completer.insertMatch()},"Shift-Return":function(e){e.completer.insertMatch(!0)},Tab:function(e){var t=e.completer.insertMatch();if(!!t||!!e.tabstopManager)return t;e.completer.goTo("down")},PageUp:function(e){e.completer.popup.gotoPageUp()},PageDown:function(e){e.completer.popup.gotoPageDown()}},this.gatherCompletions=function(e,t){var n=e.getSession(),r=e.getCursorPosition(),i=n.getLine(r.row),o=s.retrievePrecedingIdentifier(i,r.column);this.base=n.doc.createAnchor(r.row,r.column-o.length);var u=[],a=e.completers.length;return e.completers.forEach(function(i,f){i.getCompletions(e,n,r,o,function(r,i){r||(u=u.concat(i));var o=e.getCursorPosition(),f=n.getLine(o.row);t(null,{prefix:s.retrievePrecedingIdentifier(f,o.column,i[0]&&i[0].identifierRegex),matches:u,finished:--a===0})})}),!0},this.showPopup=function(e){this.editor&&this.detach(),this.activated=!0,this.editor=e,e.completer!=this&&(e.completer&&e.completer.detach(),e.completer=this),e.keyBinding.addKeyboardHandler(this.keyboardHandler),e.on("changeSelection",this.changeListener),e.on("blur",this.blurListener),e.on("mousedown",this.mousedownListener),e.on("mousewheel",this.mousewheelListener),this.updateCompletions()},this.updateCompletions=function(e){if(e&&this.base&&this.completions){var t=this.editor.getCursorPosition(),n=this.editor.session.getTextRange({start:this.base,end:t});if(n==this.completions.filterText)return;this.completions.setFilter(n);if(!this.completions.filtered.length)return this.detach();if(this.completions.filtered.length==1&&this.completions.filtered[0].value==n&&!this.completions.filtered[0].snippet)return this.detach();this.openPopup(this.editor,n,e);return}var r=this.gatherCompletionsId;this.gatherCompletions(this.editor,function(t,n){var i=function(){if(!n.finished)return;return this.detach()}.bind(this),s=n.prefix,o=n&&n.matches;if(!o||!o.length)return i();if(s.indexOf(n.prefix)!==0||r!=this.gatherCompletionsId)return;this.completions=new l(o),this.completions.setFilter(s);var u=this.completions.filtered;if(!u.length)return i();if(u.length==1&&u[0].value==s&&!u[0].snippet)return i();if(this.autoInsert&&u.length==1)return this.insertMatch(u[0]);this.openPopup(this.editor,s,e)}.bind(this))},this.cancelContextMenu=function(){this.editor.$mouseHandler.cancelContextMenu()}}).call(f.prototype),f.startCommand={name:"startAutocomplete",exec:function(e){e.completer||(e.completer=new f),e.completer.autoInsert=e.completer.autoSelect=!0,e.completer.showPopup(e),e.completer.cancelContextMenu()},bindKey:"Ctrl-Space|Ctrl-Shift-Space|Alt-Space"};var l=function(e,t,n){this.all=e,this.filtered=e,this.filterText=t||""};(function(){this.setFilter=function(e){if(e.length>this.filterText&&e.lastIndexOf(this.filterText,0)===0)var t=this.filtered;else var t=this.all;this.filterText=e,t=this.filterCompletions(t,this.filterText),t=t.sort(function(e,t){return t.exactMatch-e.exactMatch||t.score-e.score});var n=null;t=t.filter(function(e){var t=e.value||e.caption||e.snippet;return t===n?!1:(n=t,!0)}),this.filtered=t},this.filterCompletions=function(e,t){var n=[],r=t.toUpperCase(),i=t.toLowerCase();e:for(var s=0,o;o=e[s];s++){var u=o.value||o.caption||o.snippet;if(!u)continue;var a=-1,f=0,l=0,c,h;for(var p=0;p<t.length;p++){var d=u.indexOf(i[p],a+1),v=u.indexOf(r[p],a+1);c=d>=0?v<0||d<v?d:v:v;if(c<0)continue e;h=c-a-1,h>0&&(a===-1&&(l+=10),l+=h),f|=1<<c,a=c}o.matchMask=f,o.exactMatch=l?0:1,o.score=(o.score||0)-l,n.push(o)}return n}}).call(l.prototype),t.Autocomplete=f,t.FilteredList=l}),ace.define("ace/autocomplete/text_completer",["require","exports","module","ace/range"],function(e,t,n){function s(e,t){var n=e.getTextRange(r.fromPoints({row:0,column:0},t));return n.split(i).length-1}function o(e,t){var n=s(e,t),r=e.getValue().split(i),o=Object.create(null),u=r[n];return r.forEach(function(e,t){if(!e||e===u)return;var i=Math.abs(n-t),s=r.length-i;o[e]?o[e]=Math.max(s,o[e]):o[e]=s}),o}var r=e("../range").Range,i=/[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;t.getCompletions=function(e,t,n,r,i){var s=o(t,n,r),u=Object.keys(s);i(null,u.map(function(e){return{caption:e,value:e,score:s[e],meta:"local"}}))}}),ace.define("ace/ext/language_tools",["require","exports","module","ace/snippets","ace/autocomplete","ace/config","ace/autocomplete/util","ace/autocomplete/text_completer","ace/editor","ace/config"],function(e,t,n){"use strict";function v(e){var t=e.getCursorPosition(),n=e.session.getLine(t.row),r=o.retrievePrecedingIdentifier(n,t.column);return e.completers.forEach(function(e){e.identifierRegexps&&e.identifierRegexps.forEach(function(e){!r&&e&&(r=o.retrievePrecedingIdentifier(n,t.column,e))})}),r}var r=e("../snippets").snippetManager,i=e("../autocomplete").Autocomplete,s=e("../config"),o=e("../autocomplete/util"),u=e("../autocomplete/text_completer"),a={getCompletions:function(e,t,n,r,i){var s=e.session.getState(n.row),o=t.$mode.getCompletions(s,t,n,r);i(null,o)}},f={getCompletions:function(e,t,n,i,s){var o=r.snippetMap,u=[];r.getActiveScopes(e).forEach(function(e){var t=o[e]||[];for(var n=t.length;n--;){var r=t[n],i=r.name||r.tabTrigger;if(!i)continue;u.push({caption:i,snippet:r.content,meta:r.tabTrigger&&!r.name?r.tabTrigger+"\u21e5 ":"snippet"})}},this),s(null,u)}},l=[f,u,a];t.addCompleter=function(e){l.push(e)},t.textCompleter=u,t.keyWordCompleter=a,t.snippetCompleter=f;var c={name:"expandSnippet",exec:function(e){var t=r.expandWithTab(e);t||e.execCommand("indent")},bindKey:"Tab"},h=function(e,t){p(t.session.$mode)},p=function(e){var t=e.$id;r.files||(r.files={}),d(t),e.modes&&e.modes.forEach(p)},d=function(e){if(!e||r.files[e])return;var t=e.replace("mode","snippets");r.files[e]={},s.loadModule(t,function(t){t&&(r.files[e]=t,!t.snippets&&t.snippetText&&(t.snippets=r.parseSnippetFile(t.snippetText)),r.register(t.snippets||[],t.scope),t.includeScopes&&(r.snippetMap[t.scope].includeScopes=t.includeScopes,t.includeScopes.forEach(function(e){d("ace/mode/"+e)})))})},m=function(e){var t=e.editor,n=e.args||"",r=t.completer&&t.completer.activated;if(e.command.name==="backspace")r&&!v(t)&&t.completer.detach();else if(e.command.name==="insertstring"){var s=v(t);s&&!r&&(t.completer||(t.completer=new i),t.completer.autoSelect=!1,t.completer.autoInsert=!1,t.completer.showPopup(t))}},g=e("../editor").Editor;e("../config").defineOptions(g.prototype,"editor",{enableBasicAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:l),this.commands.addCommand(i.startCommand)):this.commands.removeCommand(i.startCommand)},value:!1},enableLiveAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:l),this.commands.on("afterExec",m)):this.commands.removeListener("afterExec",m)},value:!1},enableSnippets:{set:function(e){e?(this.commands.addCommand(c),this.on("changeMode",h),h(null,this)):(this.commands.removeCommand(c),this.off("changeMode",h))},value:!1}})}),ace.define("ace/mode/jsoniq",["require","exports","module","ace/worker/worker_client","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/xquery/jsoniq_lexer","ace/range","ace/mode/behaviour/xquery","ace/mode/folding/cstyle","ace/anchor","ace/ext/language_tools"],function(e,t,n){"use strict";var r=e("../worker/worker_client").WorkerClient,i=e("../lib/oop"),s=e("./text").Mode,o=e("./text_highlight_rules").TextHighlightRules,u=e("./xquery/jsoniq_lexer").JSONiqLexer,a=e("../range").Range,f=e("./behaviour/xquery").XQueryBehaviour,l=e("./folding/cstyle").FoldMode,c=e("../anchor").Anchor,h=e("../ext/language_tools"),p=function(){this.$tokenizer=new u,this.$behaviour=new f,this.foldingRules=new l,this.$highlightRules=new o};i.inherits(p,s),function(){h.addCompleter({getCompletions:function(e,t,n,r,i){t.$worker.emit("complete",{data:{pos:n,prefix:r}}),t.$worker.on("complete",function(e){i(null,e.data)})}}),this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=t.match(/\s*(?:then|else|return|[{\(]|<\w+>)\s*$/);return i&&(r+=n),r},this.checkOutdent=function(e,t,n){return/^\s+$/.test(t)?/^\s*[\}\)]/.test(n):!1},this.autoOutdent=function(e,t,n){var r=t.getLine(n),i=r.match(/^(\s*[\}\)])/);if(!i)return 0;var s=i[1].length,o=t.findMatchingBracket({row:n,column:s});if(!o||o.row==n)return 0;var u=this.$getIndent(t.getLine(o.row));t.replace(new a(n,0,n,s-1),u)},this.toggleCommentLines=function(e,t,n,r){var i,s,o=!0,u=/^\s*\(:(.*):\)/;for(i=n;i<=r;i++)if(!u.test(t.getLine(i))){o=!1;break}var f=new a(0,0,0,0);for(i=n;i<=r;i++)s=t.getLine(i),f.start.row=i,f.end.row=i,f.end.column=s.length,t.replace(f,o?s.match(u)[1]:"(:"+s+":)")},this.createWorker=function(e){var t=new r(["ace"],"ace/mode/xquery_worker","XQueryWorker"),n=this;return t.attachToDocument(e.getDocument()),t.on("ok",function(t){e.clearAnnotations()}),t.on("markers",function(t){e.clearAnnotations(),n.addMarkers(t.data,e)}),t},this.removeMarkers=function(e){var t=e.getMarkers(!1);for(var n in t)t[n].clazz.indexOf("language_highlight_")===0&&e.removeMarker(n);for(var r=0;r<e.markerAnchors.length;r++)e.markerAnchors[r].detach();e.markerAnchors=[]},this.addMarkers=function(e,t){var n=this;t.markerAnchors||(t.markerAnchors=[]),this.removeMarkers(t),t.languageAnnos=[],e.forEach(function(e){function u(i){r&&t.removeMarker(r),o.row=n.row;if(e.pos.sc!==undefined&&e.pos.ec!==undefined){var s=new a(e.pos.sl,e.pos.sc,e.pos.el,e.pos.ec);r=t.addMarker(s,"language_highlight_"+(e.type?e.type:"default"))}i&&t.setAnnotations(t.languageAnnos)}var n=new c(t.getDocument(),e.pos.sl,e.pos.sc||0);t.markerAnchors.push(n);var r,i=e.pos.ec-e.pos.sc,s=e.pos.el-e.pos.sl,o={guttertext:e.message,type:e.level||"warning",text:e.message};u(),n.on("change",function(){u(!0)}),e.message&&t.languageAnnos.push(o)}),t.setAnnotations(t.languageAnnos)},this.$id="ace/mode/jsoniq"}.call(p.prototype),t.Mode=p})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-jsp.js b/dist/assets/js/vendor/ace-nc/mode-jsp.js
            new file mode 100644
            index 0000000000..767800affa
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-jsp.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/java_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while",t="null|Infinity|NaN|undefined",n="AbstractMethodError|AssertionError|ClassCircularityError|ClassFormatError|Deprecated|EnumConstantNotPresentException|ExceptionInInitializerError|IllegalAccessError|IllegalThreadStateException|InstantiationError|InternalError|NegativeArraySizeException|NoSuchFieldError|Override|Process|ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|SuppressWarnings|TypeNotPresentException|UnknownError|UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|InstantiationException|IndexOutOfBoundsException|ArrayIndexOutOfBoundsException|CloneNotSupportedException|NoSuchFieldException|IllegalArgumentException|NumberFormatException|SecurityException|Void|InheritableThreadLocal|IllegalStateException|InterruptedException|NoSuchMethodException|IllegalAccessException|UnsupportedOperationException|Enum|StrictMath|Package|Compiler|Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|Character|Boolean|StackTraceElement|Appendable|StringBuffer|Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|StackOverflowError|OutOfMemoryError|VirtualMachineError|ArrayStoreException|ClassCastException|LinkageError|NoClassDefFoundError|ClassNotFoundException|RuntimeException|Exception|ThreadDeath|Error|Throwable|System|ClassLoader|Cloneable|Class|CharSequence|Comparable|String|Object",r=this.createKeywordMapper({"variable.language":"this",keyword:e,"constant.language":t,"support.function":n},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(o,s),t.JavaHighlightRules=o}),ace.define("ace/mode/jsp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/java_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=e("./java_highlight_rules").JavaHighlightRules,o=function(){i.call(this);var e="request|response|out|session|application|config|pageContext|page|Exception",t="page|include|taglib",n=[{token:"comment",regex:"<%--",push:"jsp-dcomment"},{token:"meta.tag",regex:"<%@?|<%=?|<jsp:[^>]+>",push:"jsp-start"}],r=[{token:"meta.tag",regex:"%>|<\\/jsp:[^>]+>",next:"pop"},{token:"variable.language",regex:e},{token:"keyword",regex:t}];for(var o in this.$rules)this.$rules[o].unshift.apply(this.$rules[o],n);this.embedRules(s,"jsp-",r,["start"]),this.addRules({"jsp-dcomment":[{token:"comment",regex:".*?--%>",next:"pop"}]}),this.normalizeRules()};r.inherits(o,i),t.JspHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/jsp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/jsp_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./jsp_highlight_rules").JspHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,i),function(){this.$id="ace/mode/jsp"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-jsx.js b/dist/assets/js/vendor/ace-nc/mode-jsx.js
            new file mode 100644
            index 0000000000..119a44e90e
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-jsx.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/jsx_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./doc_comment_highlight_rules").DocCommentHighlightRules,o=e("./text_highlight_rules").TextHighlightRules,u=function(){var e=i.arrayToMap("break|do|instanceof|typeof|case|else|new|var|catch|finally|return|void|continue|for|switch|default|while|function|this|if|throw|delete|in|try|class|extends|super|import|from|into|implements|interface|static|mixin|override|abstract|final|number|int|string|boolean|variant|log|assert".split("|")),t=i.arrayToMap("null|true|false|NaN|Infinity|__FILE__|__LINE__|undefined".split("|")),n=i.arrayToMap("debugger|with|const|export|let|private|public|yield|protected|extern|native|as|operator|__fake__|__readonly__".split("|")),r="[a-zA-Z_][a-zA-Z0-9_]*\\b";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},s.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:["storage.type","text","entity.name.function"],regex:"(function)(\\s+)("+r+")"},{token:function(r){return r=="this"?"variable.language":r=="function"?"storage.type":e.hasOwnProperty(r)||n.hasOwnProperty(r)?"keyword":t.hasOwnProperty(r)?"constant.language":/^_?[A-Z][a-zA-Z0-9_]*$/.test(r)?"language.support.class":"identifier"},regex:r},{token:"keyword.operator",regex:"!|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({<]"},{token:"paren.rparen",regex:"[\\])}>]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}]},this.embedRules(s,"doc-",[s.getEndRule("start")])};r.inherits(u,o),t.JsxHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/jsx",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/jsx_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";function f(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a}var r=e("../lib/oop"),i=e("./text").Mode,s=e("./jsx_highlight_rules").JsxHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode;r.inherits(f,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[]\s*$/);o&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/jsx"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-julia.js b/dist/assets/js/vendor/ace-nc/mode-julia.js
            new file mode 100644
            index 0000000000..685d9d58ff
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-julia.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/julia_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{include:"#function_decl"},{include:"#function_call"},{include:"#type_decl"},{include:"#keyword"},{include:"#operator"},{include:"#number"},{include:"#string"},{include:"#comment"}],"#bracket":[{token:"keyword.bracket.julia",regex:"\\(|\\)|\\[|\\]|\\{|\\}|,"}],"#comment":[{token:["punctuation.definition.comment.julia","comment.line.number-sign.julia"],regex:"(#)(?!\\{)(.*$)"}],"#function_call":[{token:["support.function.julia","text"],regex:"([a-zA-Z0-9_]+!?)([\\w\\xff-\\u218e\\u2455-\\uffff]*\\()"}],"#function_decl":[{token:["keyword.other.julia","meta.function.julia","entity.name.function.julia","meta.function.julia","text"],regex:"(function|macro)(\\s*)([a-zA-Z0-9_\\{]+!?)([\\w\\xff-\\u218e\\u2455-\\uffff]*)([(\\\\{])"}],"#keyword":[{token:"keyword.other.julia",regex:"\\b(?:function|type|immutable|macro|quote|abstract|bitstype|typealias|module|baremodule|new)\\b"},{token:"keyword.control.julia",regex:"\\b(?:if|else|elseif|while|for|in|begin|let|end|do|try|catch|finally|return|break|continue)\\b"},{token:"storage.modifier.variable.julia",regex:"\\b(?:global|local|const|export|import|importall|using)\\b"},{token:"variable.macro.julia",regex:"@[\\w\\xff-\\u218e\\u2455-\\uffff]+\\b"}],"#number":[{token:"constant.numeric.julia",regex:"\\b0(?:x|X)[0-9a-fA-F]*|(?:\\b[0-9]+\\.?[0-9]*|\\.[0-9]+)(?:(?:e|E)(?:\\+|-)?[0-9]*)?(?:im)?|\\bInf(?:32)?\\b|\\bNaN(?:32)?\\b|\\btrue\\b|\\bfalse\\b"}],"#operator":[{token:"keyword.operator.update.julia",regex:"=|:=|\\+=|-=|\\*=|/=|//=|\\.//=|\\.\\*=|\\\\=|\\.\\\\=|^=|\\.^=|%=|\\|=|&=|\\$=|<<=|>>="},{token:"keyword.operator.ternary.julia",regex:"\\?|:"},{token:"keyword.operator.boolean.julia",regex:"\\|\\||&&|!"},{token:"keyword.operator.arrow.julia",regex:"->|<-|-->"},{token:"keyword.operator.relation.julia",regex:">|<|>=|<=|==|!=|\\.>|\\.<|\\.>=|\\.>=|\\.==|\\.!=|\\.=|\\.!|<:|:>"},{token:"keyword.operator.range.julia",regex:":"},{token:"keyword.operator.shift.julia",regex:"<<|>>"},{token:"keyword.operator.bitwise.julia",regex:"\\||\\&|~"},{token:"keyword.operator.arithmetic.julia",regex:"\\+|-|\\*|\\.\\*|/|\\./|//|\\.//|%|\\.%|\\\\|\\.\\\\|\\^|\\.\\^"},{token:"keyword.operator.isa.julia",regex:"::"},{token:"keyword.operator.dots.julia",regex:"\\.(?=[a-zA-Z])|\\.\\.+"},{token:"keyword.operator.interpolation.julia",regex:"\\$#?(?=.)"},{token:["variable","keyword.operator.transposed-variable.julia"],regex:"([\\w\\xff-\\u218e\\u2455-\\uffff]+)((?:'|\\.')*\\.?')"},{token:"text",regex:"\\[|\\("},{token:["text","keyword.operator.transposed-matrix.julia"],regex:"([\\]\\)])((?:'|\\.')*\\.?')"}],"#string":[{token:"punctuation.definition.string.begin.julia",regex:"'",push:[{token:"punctuation.definition.string.end.julia",regex:"'",next:"pop"},{include:"#string_escaped_char"},{defaultToken:"string.quoted.single.julia"}]},{token:"punctuation.definition.string.begin.julia",regex:'"',push:[{token:"punctuation.definition.string.end.julia",regex:'"',next:"pop"},{include:"#string_escaped_char"},{defaultToken:"string.quoted.double.julia"}]},{token:"punctuation.definition.string.begin.julia",regex:'\\b[\\w\\xff-\\u218e\\u2455-\\uffff]+"',push:[{token:"punctuation.definition.string.end.julia",regex:'"[\\w\\xff-\\u218e\\u2455-\\uffff]*',next:"pop"},{include:"#string_custom_escaped_char"},{defaultToken:"string.quoted.custom-double.julia"}]},{token:"punctuation.definition.string.begin.julia",regex:"`",push:[{token:"punctuation.definition.string.end.julia",regex:"`",next:"pop"},{include:"#string_escaped_char"},{defaultToken:"string.quoted.backtick.julia"}]}],"#string_custom_escaped_char":[{token:"constant.character.escape.julia",regex:'\\\\"'}],"#string_escaped_char":[{token:"constant.character.escape.julia",regex:"\\\\(?:\\\\|[0-3]\\d{,2}|[4-7]\\d?|x[a-fA-F0-9]{,2}|u[a-fA-F0-9]{,4}|U[a-fA-F0-9]{,8}|.)"}],"#type_decl":[{token:["keyword.control.type.julia","meta.type.julia","entity.name.type.julia","entity.other.inherited-class.julia","punctuation.separator.inheritance.julia","entity.other.inherited-class.julia"],regex:"(type|immutable)(\\s+)([a-zA-Z0-9_]+)(?:(\\s*)(<:)(\\s*[.a-zA-Z0-9_:]+))?"},{token:["other.typed-variable.julia","support.type.julia"],regex:"([a-zA-Z0-9_]+)(::[a-zA-Z0-9_{}]+)"}]},this.normalizeRules()};s.metaData={fileTypes:["jl"],firstLineMatch:"^#!.*\\bjulia\\s*$",foldingStartMarker:"^\\s*(?:if|while|for|begin|function|macro|module|baremodule|type|immutable|let)\\b(?!.*\\bend\\b).*$",foldingStopMarker:"^\\s*(?:end)\\b.*$",name:"Julia",scopeName:"source.julia"},r.inherits(s,i),t.JuliaHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/julia",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/julia_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./julia_highlight_rules").JuliaHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="#",this.blockComment="",this.$id="ace/mode/julia"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-latex.js b/dist/assets/js/vendor/ace-nc/mode-latex.js
            new file mode 100644
            index 0000000000..42be382697
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-latex.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/latex_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"keyword",regex:"\\\\(?:[^a-zA-Z]|[a-zA-Z]+)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"string",regex:"\\$(?:(?:\\\\.)|(?:[^\\$\\\\]))*?\\$"},{token:"comment",regex:"%.*$"}]}};r.inherits(s,i),t.LatexHighlightRules=s}),ace.define("ace/mode/folding/latex",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=e("../../token_iterator").TokenIterator,u=t.FoldMode=function(){};r.inherits(u,i),function(){this.foldingStartMarker=/^\s*\\(begin)|(section|subsection)\b|{\s*$/,this.foldingStopMarker=/^\s*\\(end)\b|^\s*}/,this.getFoldWidgetRange=function(e,t,n){var r=e.doc.getLine(n),i=this.foldingStartMarker.exec(r);if(i)return i[1]?this.latexBlock(e,n,i[0].length-1):i[2]?this.latexSection(e,n,i[0].length-1):this.openingBracketBlock(e,"{",n,i.index);var i=this.foldingStopMarker.exec(r);if(i)return i[1]?this.latexBlock(e,n,i[0].length-1):this.closingBracketBlock(e,"}",n,i.index+i[0].length)},this.latexBlock=function(e,t,n){var r={"\\begin":1,"\\end":-1},i=new o(e,t,n),u=i.getCurrentToken();if(!u||u.type!=="keyword")return;var a=u.value,f=r[a],l=function(){var e=i.stepForward(),t=e.type=="lparen"?i.stepForward().value:"";return f===-1&&(i.stepBackward(),t&&i.stepBackward()),t},c=[l()],h=f===-1?i.getCurrentTokenColumn():e.getLine(t).length,p=t;i.step=f===-1?i.stepBackward:i.stepForward;while(u=i.step()){if(u.type!=="keyword")continue;var d=r[u.value];if(!d)continue;var v=l();if(d===f)c.unshift(v);else if(c.shift()!==v||!c.length)break}if(c.length)return;var t=i.getCurrentTokenRow();return f===-1?new s(t,e.getLine(t).length,p,h):(i.stepBackward(),new s(p,h,t,i.getCurrentTokenColumn()))},this.latexSection=function(e,t,n){var r=["\\subsection","\\section","\\begin","\\end"],i=new o(e,t,n),u=i.getCurrentToken();if(!u||u.type!="keyword")return;var a=r.indexOf(u.value),f=0,l=t;while(u=i.stepForward()){if(u.type!=="keyword")continue;var c=r.indexOf(u.value);if(c>=2){f||(l=i.getCurrentTokenRow()-1),f+=c==2?1:-1;if(f<0)break}else if(c>=a)break}f||(l=i.getCurrentTokenRow()-1);while(l>t&&!/\S/.test(e.getLine(l)))l--;return new s(t,e.getLine(t).length,l,e.getLine(l).length)}}.call(u.prototype)}),ace.define("ace/mode/latex",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/latex_highlight_rules","ace/mode/folding/latex","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./latex_highlight_rules").LatexHighlightRules,o=e("./folding/latex").FoldMode,u=e("../range").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(a,i),function(){this.lineCommentStart="%",this.$id="ace/mode/latex"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-less.js b/dist/assets/js/vendor/ace-nc/mode-less.js
            new file mode 100644
            index 0000000000..620294884c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-less.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/less_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=i.arrayToMap(function(){var e="-webkit-|-moz-|-o-|-ms-|-svg-|-pie-|-khtml-".split("|"),t="appearance|background-clip|background-inline-policy|background-origin|background-size|binding|border-bottom-colors|border-left-colors|border-right-colors|border-top-colors|border-end|border-end-color|border-end-style|border-end-width|border-image|border-start|border-start-color|border-start-style|border-start-width|box-align|box-direction|box-flex|box-flexgroup|box-ordinal-group|box-orient|box-pack|box-sizing|column-count|column-gap|column-width|column-rule|column-rule-width|column-rule-style|column-rule-color|float-edge|font-feature-settings|font-language-override|force-broken-image-icon|image-region|margin-end|margin-start|opacity|outline|outline-color|outline-offset|outline-radius|outline-radius-bottomleft|outline-radius-bottomright|outline-radius-topleft|outline-radius-topright|outline-style|outline-width|padding-end|padding-start|stack-sizing|tab-size|text-blink|text-decoration-color|text-decoration-line|text-decoration-style|transform|transform-origin|transition|transition-delay|transition-duration|transition-property|transition-timing-function|user-focus|user-input|user-modify|user-select|window-shadow|border-radius".split("|"),n="azimuth|background-attachment|background-color|background-image|background-position|background-repeat|background|border-bottom-color|border-bottom-style|border-bottom-width|border-bottom|border-collapse|border-color|border-left-color|border-left-style|border-left-width|border-left|border-right-color|border-right-style|border-right-width|border-right|border-spacing|border-style|border-top-color|border-top-style|border-top-width|border-top|border-width|border|bottom|box-sizing|caption-side|clear|clip|color|content|counter-increment|counter-reset|cue-after|cue-before|cue|cursor|direction|display|elevation|empty-cells|float|font-family|font-size-adjust|font-size|font-stretch|font-style|font-variant|font-weight|font|height|left|letter-spacing|line-height|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|marker-offset|margin|marks|max-height|max-width|min-height|min-width|opacity|orphans|outline-color|outline-style|outline-width|outline|overflow|overflow-x|overflow-y|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page|pause-after|pause-before|pause|pitch-range|pitch|play-during|position|quotes|richness|right|size|speak-header|speak-numeral|speak-punctuation|speech-rate|speak|stress|table-layout|text-align|text-decoration|text-indent|text-shadow|text-transform|top|unicode-bidi|vertical-align|visibility|voice-family|volume|white-space|widows|width|word-spacing|z-index".split("|"),r=[];for(var i=0,s=e.length;i<s;i++)Array.prototype.push.apply(r,(e[i]+t.join("|"+e[i])).split("|"));return Array.prototype.push.apply(r,t),Array.prototype.push.apply(r,n),r}()),t=i.arrayToMap("hsl|hsla|rgb|rgba|url|attr|counter|counters|lighten|darken|saturate|desaturate|fadein|fadeout|fade|spin|mix|hue|saturation|lightness|alpha|round|ceil|floor|percentage|color|iscolor|isnumber|isstring|iskeyword|isurl|ispixel|ispercentage|isem".split("|")),n=i.arrayToMap("absolute|all-scroll|always|armenian|auto|baseline|below|bidi-override|block|bold|bolder|border-box|both|bottom|break-all|break-word|capitalize|center|char|circle|cjk-ideographic|col-resize|collapse|content-box|crosshair|dashed|decimal-leading-zero|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fixed|georgian|groove|hand|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|katakana-iroha|katakana|keep-all|left|lighter|line-edge|line-through|line|list-item|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|outset|outside|overline|pointer|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|super|sw-resize|table-footer-group|table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|zero".split("|")),r=i.arrayToMap("aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow".split("|")),s=i.arrayToMap("@mixin|@extend|@include|@import|@media|@debug|@warn|@if|@for|@each|@while|@else|@font-face|@-webkit-keyframes|if|and|!default|module|def|end|declare|when|not|and".split("|")),o=i.arrayToMap("a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdo|big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|keygen|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|source|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|u|ul|var|video|wbr|xmp".split("|")),u="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:u+"(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)"},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:"constant.numeric",regex:u},{token:function(e){return s.hasOwnProperty(e)?"keyword":"variable"},regex:"@[a-z0-9_\\-@]*\\b"},{token:function(i){return e.hasOwnProperty(i.toLowerCase())?"support.type":s.hasOwnProperty(i)?"keyword":n.hasOwnProperty(i)?"constant.language":t.hasOwnProperty(i)?"support.function":r.hasOwnProperty(i.toLowerCase())?"support.constant.color":o.hasOwnProperty(i.toLowerCase())?"variable.language":"text"},regex:"\\-?[@a-z_][@a-z0-9_\\-]*"},{token:"variable.language",regex:"#[a-z0-9-_]+"},{token:"variable.language",regex:"\\.[a-z0-9-_]+"},{token:"variable.language",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{token:"keyword.operator",regex:"<|>|<=|>=|==|!=|-|%|#|\\+|\\$|\\+|\\*"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}]}};r.inherits(o,s),t.LessHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/less",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/less_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./less_highlight_rules").LessHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/css").CssBehaviour,a=e("./folding/cstyle").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/less"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-liquid.js b/dist/assets/js/vendor/ace-nc/mode-liquid.js
            new file mode 100644
            index 0000000000..7056499b00
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-liquid.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/liquid_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=e("./html_highlight_rules").HtmlHighlightRules,o=function(){s.call(this);var e="date|capitalize|downcase|upcase|first|last|join|sort|map|size|escape|escape_once|strip_html|strip_newlines|newline_to_br|replace|replace_first|truncate|truncatewords|prepend|append|minus|plus|times|divided_by|split",t="capture|endcapture|case|endcase|when|comment|endcomment|cycle|for|endfor|in|reversed|if|endif|else|elsif|include|endinclude|unless|endunless|style|text|image|widget|plugin|marker|endmarker|tablerow|endtablerow",n="forloop|tablerowloop",r="assign",i=this.createKeywordMapper({"variable.language":n,keyword:t,"support.function":e,"keyword.definition":r},"identifier");for(var o in this.$rules)this.$rules[o].unshift({token:"variable",regex:"{%",push:"liquid-start"},{token:"variable",regex:"{{",push:"liquid-start"});this.addRules({"liquid-start":[{token:"variable",regex:"}}",next:"pop"},{token:"variable",regex:"%}",next:"pop"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"/|\\*|\\-|\\+|=|!=|\\?\\:"},{token:"paren.lparen",regex:/[\[\({]/},{token:"paren.rparen",regex:/[\])}]/},{token:"text",regex:"\\s+"}]}),this.normalizeRules()};r.inherits(o,i),t.LiquidHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/liquid",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/liquid_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("./liquid_highlight_rules").LiquidHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=function(){this.HighlightRules=s,this.$outdent=new o};r.inherits(a,i),function(){this.blockComment={start:"<!--",end:"-->"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/liquid"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-lisp.js b/dist/assets/js/vendor/ace-nc/mode-lisp.js
            new file mode 100644
            index 0000000000..830ec74cc1
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-lisp.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/lisp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="case|do|let|loop|if|else|when",t="eq|neq|and|or",n="null|nil",r="cons|car|cdr|cond|lambda|format|setq|setf|quote|eval|append|list|listp|memberp|t|load|progn",i=this.createKeywordMapper({"keyword.control":e,"keyword.operator":t,"constant.language":n,"support.function":r},"identifier",!0);this.$rules={start:[{token:"comment",regex:";.*$"},{token:["storage.type.function-type.lisp","text","entity.name.function.lisp"],regex:"(?:\\b(?:(defun|defmethod|defmacro))\\b)(\\s+)((?:\\w|\\-|\\!|\\?)*)"},{token:["punctuation.definition.constant.character.lisp","constant.character.lisp"],regex:"(#)((?:\\w|[\\\\+-=<>'\"&#])+)"},{token:["punctuation.definition.variable.lisp","variable.other.global.lisp","punctuation.definition.variable.lisp"],regex:"(\\*)(\\S*)(\\*)"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(?:L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"string",regex:'"(?=.)',next:"qqstring"}],qqstring:[{token:"constant.character.escape.lisp",regex:"\\\\."},{token:"string",regex:'[^"\\\\]+'},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"}]}};r.inherits(s,i),t.LispHighlightRules=s}),ace.define("ace/mode/lisp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/lisp_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./lisp_highlight_rules").LispHighlightRules,o=function(){this.HighlightRules=s};r.inherits(o,i),function(){this.lineCommentStart=";",this.$id="ace/mode/lisp"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-livescript.js b/dist/assets/js/vendor/ace-nc/mode-livescript.js
            new file mode 100644
            index 0000000000..51f610b45c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-livescript.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/livescript",["require","exports","module","ace/tokenizer","ace/mode/matching_brace_outdent","ace/range","ace/mode/text"],function(e,t,n){function u(e,t){function n(){}return n.prototype=(e.superclass=t).prototype,(e.prototype=new n).constructor=e,typeof t.extended=="function"&&t.extended(e),e}function a(e,t){var n={}.hasOwnProperty;for(var r in t)n.call(t,r)&&(e[r]=t[r]);return e}var r,i,s,o;r="(?![\\d\\s])[$\\w\\xAA-\\uFFDC](?:(?!\\s)[$\\w\\xAA-\\uFFDC]|-[A-Za-z])*",t.Mode=i=function(t){function o(){var t;this.$tokenizer=new(e("../tokenizer").Tokenizer)(o.Rules);if(t=e("../mode/matching_brace_outdent"))this.$outdent=new t.MatchingBraceOutdent;this.$id="ace/mode/livescript"}var n,i=u((a(o,t).displayName="LiveScriptMode",o),t).prototype,s=o;return n=RegExp("(?:[({[=:]|[-~]>|\\b(?:e(?:lse|xport)|d(?:o|efault)|t(?:ry|hen)|finally|import(?:\\s*all)?|const|var|let|new|catch(?:\\s*"+r+")?))\\s*$"),i.getNextLineIndent=function(e,t,r){var i,s;return i=this.$getIndent(t),s=this.$tokenizer.getLineTokens(t,e).tokens,(!s.length||s[s.length-1].type!=="comment")&&e==="start"&&n.test(t)&&(i+=r),i},i.toggleCommentLines=function(t,n,r,i){var s,o,u,a,f,l;s=/^(\s*)#/,o=new(e("../range").Range)(0,0,0,0);for(u=r;u<=i;++u)a=u,(f=s.test(l=n.getLine(a)))?l=l.replace(s,"$1"):l=l.replace(/^\s*/,"$&#"),o.end.row=o.start.row=a,o.end.column=l.length+1,n.replace(o,l);return 1-f*2},i.checkOutdent=function(e,t,n){var r;return(r=this.$outdent)!=null?r.checkOutdent(t,n):void 8},i.autoOutdent=function(e,t,n){var r;return(r=this.$outdent)!=null?r.autoOutdent(t,n):void 8},o}(e("../mode/text").Mode),s="(?![$\\w]|-[A-Za-z]|\\s*:(?![:=]))",o={token:"string",regex:".+"},i.Rules={start:[{token:"keyword",regex:"(?:t(?:h(?:is|row|en)|ry|ypeof!?)|c(?:on(?:tinue|st)|a(?:se|tch)|lass)|i(?:n(?:stanceof)?|mp(?:ort(?:\\s+all)?|lements)|[fs])|d(?:e(?:fault|lete|bugger)|o)|f(?:or(?:\\s+own)?|inally|unction)|s(?:uper|witch)|e(?:lse|x(?:tends|port)|val)|a(?:nd|rguments)|n(?:ew|ot)|un(?:less|til)|w(?:hile|ith)|o[fr]|return|break|let|var|loop)"+s},{token:"constant.language",regex:"(?:true|false|yes|no|on|off|null|void|undefined)"+s},{token:"invalid.illegal",regex:"(?:p(?:ackage|r(?:ivate|otected)|ublic)|i(?:mplements|nterface)|enum|static|yield)"+s},{token:"language.support.class",regex:"(?:R(?:e(?:gExp|ferenceError)|angeError)|S(?:tring|yntaxError)|E(?:rror|valError)|Array|Boolean|Date|Function|Number|Object|TypeError|URIError)"+s},{token:"language.support.function",regex:"(?:is(?:NaN|Finite)|parse(?:Int|Float)|Math|JSON|(?:en|de)codeURI(?:Component)?)"+s},{token:"variable.language",regex:"(?:t(?:hat|il|o)|f(?:rom|allthrough)|it|by|e)"+s},{token:"identifier",regex:r+"\\s*:(?![:=])"},{token:"variable",regex:r},{token:"keyword.operator",regex:"(?:\\.{3}|\\s+\\?)"},{token:"keyword.variable",regex:"(?:@+|::|\\.\\.)",next:"key"},{token:"keyword.operator",regex:"\\.\\s*",next:"key"},{token:"string",regex:"\\\\\\S[^\\s,;)}\\]]*"},{token:"string.doc",regex:"'''",next:"qdoc"},{token:"string.doc",regex:'"""',next:"qqdoc"},{token:"string",regex:"'",next:"qstring"},{token:"string",regex:'"',next:"qqstring"},{token:"string",regex:"`",next:"js"},{token:"string",regex:"<\\[",next:"words"},{token:"string.regex",regex:"//",next:"heregex"},{token:"comment.doc",regex:"/\\*",next:"comment"},{token:"comment",regex:"#.*"},{token:"string.regex",regex:"\\/(?:[^[\\/\\n\\\\]*(?:(?:\\\\.|\\[[^\\]\\n\\\\]*(?:\\\\.[^\\]\\n\\\\]*)*\\])[^[\\/\\n\\\\]*)*)\\/[gimy$]{0,4}",next:"key"},{token:"constant.numeric",regex:"(?:0x[\\da-fA-F][\\da-fA-F_]*|(?:[2-9]|[12]\\d|3[0-6])r[\\da-zA-Z][\\da-zA-Z_]*|(?:\\d[\\d_]*(?:\\.\\d[\\d_]*)?|\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[\\w$]*)"},{token:"lparen",regex:"[({[]"},{token:"rparen",regex:"[)}\\]]",next:"key"},{token:"keyword.operator",regex:"\\S+"},{token:"text",regex:"\\s+"}],heregex:[{token:"string.regex",regex:".*?//[gimy$?]{0,4}",next:"start"},{token:"string.regex",regex:"\\s*#{"},{token:"comment.regex",regex:"\\s+(?:#.*)?"},{token:"string.regex",regex:"\\S+"}],key:[{token:"keyword.operator",regex:"[.?@!]+"},{token:"identifier",regex:r,next:"start"},{token:"text",regex:".",next:"start"}],comment:[{token:"comment.doc",regex:".*?\\*/",next:"start"},{token:"comment.doc",regex:".+"}],qdoc:[{token:"string",regex:".*?'''",next:"key"},o],qqdoc:[{token:"string",regex:'.*?"""',next:"key"},o],qstring:[{token:"string",regex:"[^\\\\']*(?:\\\\.[^\\\\']*)*'",next:"key"},o],qqstring:[{token:"string",regex:'[^\\\\"]*(?:\\\\.[^\\\\"]*)*"',next:"key"},o],js:[{token:"string",regex:"[^\\\\`]*(?:\\\\.[^\\\\`]*)*`",next:"key"},o],words:[{token:"string",regex:".*?\\]>",next:"key"},o]}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-logiql.js b/dist/assets/js/vendor/ace-nc/mode-logiql.js
            new file mode 100644
            index 0000000000..9e04504e94
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-logiql.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/logiql_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.block",regex:"/\\*",push:[{token:"comment.block",regex:"\\*/",next:"pop"},{defaultToken:"comment.block"}]},{token:"comment.single",regex:"//.*"},{token:"constant.numeric",regex:"\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?[fd]?"},{token:"string",regex:'"',push:[{token:"string",regex:'"',next:"pop"},{defaultToken:"string"}]},{token:"constant.language",regex:"\\b(true|false)\\b"},{token:"entity.name.type.logicblox",regex:"`[a-zA-Z_:]+(\\d|\\a)*\\b"},{token:"keyword.start",regex:"->",comment:"Constraint"},{token:"keyword.start",regex:"-->",comment:"Level 1 Constraint"},{token:"keyword.start",regex:"<-",comment:"Rule"},{token:"keyword.start",regex:"<--",comment:"Level 1 Rule"},{token:"keyword.end",regex:"\\.",comment:"Terminator"},{token:"keyword.other",regex:"!",comment:"Negation"},{token:"keyword.other",regex:",",comment:"Conjunction"},{token:"keyword.other",regex:";",comment:"Disjunction"},{token:"keyword.operator",regex:"<=|>=|!=|<|>",comment:"Equality"},{token:"keyword.other",regex:"@",comment:"Equality"},{token:"keyword.operator",regex:"\\+|-|\\*|/",comment:"Arithmetic operations"},{token:"keyword",regex:"::",comment:"Colon colon"},{token:"support.function",regex:"\\b(agg\\s*<<)",push:[{include:"$self"},{token:"support.function",regex:">>",next:"pop"}]},{token:"storage.modifier",regex:"\\b(lang:[\\w:]*)"},{token:["storage.type","text"],regex:"(export|sealed|clauses|block|alias|alias_all)(\\s*\\()(?=`)"},{token:"entity.name",regex:"[a-zA-Z_][a-zA-Z_0-9:]*(@prev|@init|@final)?(?=(\\(|\\[))"},{token:"variable.parameter",regex:"([a-zA-Z][a-zA-Z_0-9]*|_)\\s*(?=(,|\\.|<-|->|\\)|\\]|=))"}]},this.normalizeRules()};r.inherits(s,i),t.LogiQLHighlightRules=s}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/logiql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/logiql_highlight_rules","ace/mode/folding/coffee","ace/token_iterator","ace/range","ace/mode/behaviour/cstyle","ace/mode/matching_brace_outdent"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./logiql_highlight_rules").LogiQLHighlightRules,o=e("./folding/coffee").FoldMode,u=e("../token_iterator").TokenIterator,a=e("../range").Range,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./matching_brace_outdent").MatchingBraceOutdent,c=function(){this.HighlightRules=s,this.foldingRules=new o,this.$outdent=new l,this.$behaviour=new f};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(/comment|string/.test(o))return r;if(s.length&&s[s.length-1].type=="comment.single")return r;var u=t.match();return/(-->|<--|<-|->|{)\s*$/.test(t)&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)?!0:n!=="\n"&&n!=="\r\n"?!1:/^\s+/.test(t)?!0:!1},this.autoOutdent=function(e,t,n){if(this.$outdent.autoOutdent(t,n))return;var r=t.getLine(n),i=r.match(/^\s+/),s=r.lastIndexOf(".")+1;if(!i||!n||!s)return 0;var o=t.getLine(n+1),u=this.getMatching(t,{row:n,column:s});if(!u||u.start.row==n)return 0;s=i[0].length;var f=this.$getIndent(t.getLine(u.start.row));t.replace(new a(n+1,0,n+1,s),f)},this.getMatching=function(e,t,n){t==undefined&&(t=e.selection.lead),typeof t=="object"&&(n=t.column,t=t.row);var r=e.getTokenAt(t,n),i="keyword.start",s="keyword.end",o;if(!r)return;if(r.type==i){var f=new u(e,t,n);f.step=f.stepForward}else{if(r.type!=s)return;var f=new u(e,t,n);f.step=f.stepBackward}while(o=f.step())if(o.type==i||o.type==s)break;if(!o||o.type==r.type)return;var l=f.getCurrentTokenColumn(),t=f.getCurrentTokenRow();return new a(t,l,t,l+o.value.length)},this.$id="ace/mode/logiql"}.call(c.prototype),t.Mode=c})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-lsl.js b/dist/assets/js/vendor/ace-nc/mode-lsl.js
            new file mode 100644
            index 0000000000..a16163f481
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-lsl.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/lsl_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";function s(){var e=this.createKeywordMapper({"constant.language.float.lsl":"DEG_TO_RAD|PI|PI_BY_TWO|RAD_TO_DEG|SQRT2|TWO_PI","constant.language.integer.lsl":"ACTIVE|AGENT|AGENT_ALWAYS_RUN|AGENT_ATTACHMENTS|AGENT_AUTOPILOT|AGENT_AWAY|AGENT_BUSY|AGENT_BY_LEGACY_NAME|AGENT_BY_USERNAME|AGENT_CROUCHING|AGENT_FLYING|AGENT_IN_AIR|AGENT_LIST_PARCEL|AGENT_LIST_PARCEL_OWNER|AGENT_LIST_REGION|AGENT_MOUSELOOK|AGENT_ON_OBJECT|AGENT_SCRIPTED|AGENT_SITTING|AGENT_TYPING|AGENT_WALKING|ALL_SIDES|ANIM_ON|ATTACH_AVATAR_CENTER|ATTACH_BACK|ATTACH_BELLY|ATTACH_CHEST|ATTACH_CHIN|ATTACH_HEAD|ATTACH_HUD_BOTTOM|ATTACH_HUD_BOTTOM_LEFT|ATTACH_HUD_BOTTOM_RIGHT|ATTACH_HUD_CENTER_1|ATTACH_HUD_CENTER_2|ATTACH_HUD_TOP_CENTER|ATTACH_HUD_TOP_LEFT|ATTACH_HUD_TOP_RIGHT|ATTACH_LEAR|ATTACH_LEFT_PEC|ATTACH_LEYE|ATTACH_LFOOT|ATTACH_LHAND|ATTACH_LHIP|ATTACH_LLARM|ATTACH_LLLEG|ATTACH_LSHOULDER|ATTACH_LUARM|ATTACH_LULEG|ATTACH_MOUTH|ATTACH_NECK|ATTACH_NOSE|ATTACH_PELVIS|ATTACH_REAR|ATTACH_REYE|ATTACH_RFOOT|ATTACH_RHAND|ATTACH_RHIP|ATTACH_RIGHT_PEC|ATTACH_RLARM|ATTACH_RLLEG|ATTACH_RSHOULDER|ATTACH_RUARM|ATTACH_RULEG|AVOID_CHARACTERS|AVOID_DYNAMIC_OBSTACLES|AVOID_NONE|CAMERA_ACTIVE|CAMERA_BEHINDNESS_ANGLE|CAMERA_BEHINDNESS_LAG|CAMERA_DISTANCE|CAMERA_FOCUS|CAMERA_FOCUS_LAG|CAMERA_FOCUS_LOCKED|CAMERA_FOCUS_OFFSET|CAMERA_FOCUS_THRESHOLD|CAMERA_PITCH|CAMERA_POSITION|CAMERA_POSITION_LAG|CAMERA_POSITION_LOCKED|CAMERA_POSITION_THRESHOLD|CHANGED_ALLOWED_DROP|CHANGED_COLOR|CHANGED_INVENTORY|CHANGED_LINK|CHANGED_MEDIA|CHANGED_OWNER|CHANGED_REGION|CHANGED_REGION_START|CHANGED_SCALE|CHANGED_SHAPE|CHANGED_TELEPORT|CHANGED_TEXTURE|CHARACTER_ACCOUNT_FOR_SKIPPED_FRAMES|CHARACTER_AVOIDANCE_MODE|CHARACTER_CMD_JUMP|CHARACTER_CMD_SMOOTH_STOP|CHARACTER_CMD_STOP|CHARACTER_DESIRED_SPEED|CHARACTER_DESIRED_TURN_SPEED|CHARACTER_LENGTH|CHARACTER_MAX_ACCEL|CHARACTER_MAX_DECEL|CHARACTER_MAX_SPEED|CHARACTER_MAX_TURN_RADIUS|CHARACTER_ORIENTATION|CHARACTER_RADIUS|CHARACTER_STAY_WITHIN_PARCEL|CHARACTER_TYPE|CHARACTER_TYPE_A|CHARACTER_TYPE_B|CHARACTER_TYPE_C|CHARACTER_TYPE_D|CHARACTER_TYPE_NONE|CLICK_ACTION_BUY|CLICK_ACTION_NONE|CLICK_ACTION_OPEN|CLICK_ACTION_OPEN_MEDIA|CLICK_ACTION_PAY|CLICK_ACTION_PLAY|CLICK_ACTION_SIT|CLICK_ACTION_TOUCH|CONTENT_TYPE_ATOM|CONTENT_TYPE_FORM|CONTENT_TYPE_HTML|CONTENT_TYPE_JSON|CONTENT_TYPE_LLSD|CONTENT_TYPE_RSS|CONTENT_TYPE_TEXT|CONTENT_TYPE_XHTML|CONTENT_TYPE_XML|CONTROL_BACK|CONTROL_DOWN|CONTROL_FWD|CONTROL_LBUTTON|CONTROL_LEFT|CONTROL_ML_LBUTTON|CONTROL_RIGHT|CONTROL_ROT_LEFT|CONTROL_ROT_RIGHT|CONTROL_UP|DATA_BORN|DATA_NAME|DATA_ONLINE|DATA_PAYINFO|DATA_SIM_POS|DATA_SIM_RATING|DATA_SIM_STATUS|DEBUG_CHANNEL|DENSITY|ERR_GENERIC|ERR_MALFORMED_PARAMS|ERR_PARCEL_PERMISSIONS|ERR_RUNTIME_PERMISSIONS|ERR_THROTTLED|ESTATE_ACCESS_ALLOWED_AGENT_ADD|ESTATE_ACCESS_ALLOWED_AGENT_REMOVE|ESTATE_ACCESS_ALLOWED_GROUP_ADD|ESTATE_ACCESS_ALLOWED_GROUP_REMOVE|ESTATE_ACCESS_BANNED_AGENT_ADD|ESTATE_ACCESS_BANNED_AGENT_REMOVE|FALSE|FORCE_DIRECT_PATH|FRICTION|GCNP_RADIUS|GCNP_STATIC|GRAVITY_MULTIPLIER|HORIZONTAL|HTTP_BODY_MAXLENGTH|HTTP_BODY_TRUNCATED|HTTP_CUSTOM_HEADER|HTTP_METHOD|HTTP_MIMETYPE|HTTP_PRAGMA_NO_CACHE|HTTP_VERBOSE_THROTTLE|HTTP_VERIFY_CERT|INVENTORY_ALL|INVENTORY_ANIMATION|INVENTORY_BODYPART|INVENTORY_CLOTHING|INVENTORY_GESTURE|INVENTORY_LANDMARK|INVENTORY_NONE|INVENTORY_NOTECARD|INVENTORY_OBJECT|INVENTORY_SCRIPT|INVENTORY_SOUND|INVENTORY_TEXTURE|JSON_APPEND|KFM_CMD_PAUSE|KFM_CMD_PLAY|KFM_CMD_SET_MODE|KFM_CMD_STOP|KFM_COMMAND|KFM_DATA|KFM_FORWARD|KFM_LOOP|KFM_MODE|KFM_PING_PONG|KFM_REVERSE|KFM_ROTATION|KFM_TRANSLATION|LAND_LEVEL|LAND_LOWER|LAND_NOISE|LAND_RAISE|LAND_REVERT|LAND_SMOOTH|LINK_ALL_CHILDREN|LINK_ALL_OTHERS|LINK_ROOT|LINK_SET|LINK_THIS|LIST_STAT_GEOMETRIC_MEAN|LIST_STAT_MAX|LIST_STAT_MEAN|LIST_STAT_MEDIAN|LIST_STAT_MIN|LIST_STAT_NUM_COUNT|LIST_STAT_RANGE|LIST_STAT_STD_DEV|LIST_STAT_SUM|LIST_STAT_SUM_SQUARES|LOOP|MASK_BASE|MASK_EVERYONE|MASK_GROUP|MASK_NEXT|MASK_OWNER|OBJECT_ATTACHED_POINT|OBJECT_CHARACTER_TIME|OBJECT_CREATOR|OBJECT_DESC|OBJECT_GROUP|OBJECT_NAME|OBJECT_OWNER|OBJECT_PATHFINDING_TYPE|OBJECT_PHANTOM|OBJECT_PHYSICS|OBJECT_PHYSICS_COST|OBJECT_POS|OBJECT_PRIM_EQUIVALENCE|OBJECT_RENDER_WEIGHT|OBJECT_RETURN_PARCEL|OBJECT_RETURN_PARCEL_OWNER|OBJECT_RETURN_REGION|OBJECT_ROOT|OBJECT_ROT|OBJECT_RUNNING_SCRIPT_COUNT|OBJECT_SCRIPT_MEMORY|OBJECT_SCRIPT_TIME|OBJECT_SERVER_COST|OBJECT_STREAMING_COST|OBJECT_TEMP_ON_REZ|OBJECT_TOTAL_SCRIPT_COUNT|OBJECT_UNKNOWN_DETAIL|OBJECT_VELOCITY|OPT_AVATAR|OPT_CHARACTER|OPT_EXCLUSION_VOLUME|OPT_LEGACY_LINKSET|OPT_MATERIAL_VOLUME|OPT_OTHER|OPT_STATIC_OBSTACLE|OPT_WALKABLE|PARCEL_COUNT_GROUP|PARCEL_COUNT_OTHER|PARCEL_COUNT_OWNER|PARCEL_COUNT_SELECTED|PARCEL_COUNT_TEMP|PARCEL_COUNT_TOTAL|PARCEL_DETAILS_AREA|PARCEL_DETAILS_DESC|PARCEL_DETAILS_GROUP|PARCEL_DETAILS_ID|PARCEL_DETAILS_NAME|PARCEL_DETAILS_OWNER|PARCEL_DETAILS_SEE_AVATARS|PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY|PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS|PARCEL_FLAG_ALLOW_CREATE_OBJECTS|PARCEL_FLAG_ALLOW_DAMAGE|PARCEL_FLAG_ALLOW_FLY|PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY|PARCEL_FLAG_ALLOW_GROUP_SCRIPTS|PARCEL_FLAG_ALLOW_LANDMARK|PARCEL_FLAG_ALLOW_SCRIPTS|PARCEL_FLAG_ALLOW_TERRAFORM|PARCEL_FLAG_LOCAL_SOUND_ONLY|PARCEL_FLAG_RESTRICT_PUSHOBJECT|PARCEL_FLAG_USE_ACCESS_GROUP|PARCEL_FLAG_USE_ACCESS_LIST|PARCEL_FLAG_USE_BAN_LIST|PARCEL_FLAG_USE_LAND_PASS_LIST|PARCEL_MEDIA_COMMAND_AGENT|PARCEL_MEDIA_COMMAND_AUTO_ALIGN|PARCEL_MEDIA_COMMAND_DESC|PARCEL_MEDIA_COMMAND_LOOP|PARCEL_MEDIA_COMMAND_LOOP_SET|PARCEL_MEDIA_COMMAND_PAUSE|PARCEL_MEDIA_COMMAND_PLAY|PARCEL_MEDIA_COMMAND_SIZE|PARCEL_MEDIA_COMMAND_STOP|PARCEL_MEDIA_COMMAND_TEXTURE|PARCEL_MEDIA_COMMAND_TIME|PARCEL_MEDIA_COMMAND_TYPE|PARCEL_MEDIA_COMMAND_UNLOAD|PARCEL_MEDIA_COMMAND_URL|PASSIVE|PATROL_PAUSE_AT_WAYPOINTS|PAYMENT_INFO_ON_FILE|PAYMENT_INFO_USED|PAY_DEFAULT|PAY_HIDE|PERMISSION_ATTACH|PERMISSION_CHANGE_LINKS|PERMISSION_CONTROL_CAMERA|PERMISSION_DEBIT|PERMISSION_OVERRIDE_ANIMATIONS|PERMISSION_RETURN_OBJECTS|PERMISSION_SILENT_ESTATE_MANAGEMENT|PERMISSION_TAKE_CONTROLS|PERMISSION_TELEPORT|PERMISSION_TRACK_CAMERA|PERMISSION_TRIGGER_ANIMATION|PERM_ALL|PERM_COPY|PERM_MODIFY|PERM_MOVE|PERM_TRANSFER|PING_PONG|PRIM_BUMP_BARK|PRIM_BUMP_BLOBS|PRIM_BUMP_BRICKS|PRIM_BUMP_BRIGHT|PRIM_BUMP_CHECKER|PRIM_BUMP_CONCRETE|PRIM_BUMP_DARK|PRIM_BUMP_DISKS|PRIM_BUMP_GRAVEL|PRIM_BUMP_LARGETILE|PRIM_BUMP_NONE|PRIM_BUMP_SHINY|PRIM_BUMP_SIDING|PRIM_BUMP_STONE|PRIM_BUMP_STUCCO|PRIM_BUMP_SUCTION|PRIM_BUMP_TILE|PRIM_BUMP_WEAVE|PRIM_BUMP_WOOD|PRIM_COLOR|PRIM_DESC|PRIM_FLEXIBLE|PRIM_FULLBRIGHT|PRIM_GLOW|PRIM_HOLE_CIRCLE|PRIM_HOLE_DEFAULT|PRIM_HOLE_SQUARE|PRIM_HOLE_TRIANGLE|PRIM_LINK_TARGET|PRIM_MATERIAL|PRIM_MATERIAL_FLESH|PRIM_MATERIAL_GLASS|PRIM_MATERIAL_METAL|PRIM_MATERIAL_PLASTIC|PRIM_MATERIAL_RUBBER|PRIM_MATERIAL_STONE|PRIM_MATERIAL_WOOD|PRIM_MEDIA_ALT_IMAGE_ENABLE|PRIM_MEDIA_AUTO_LOOP|PRIM_MEDIA_AUTO_PLAY|PRIM_MEDIA_AUTO_SCALE|PRIM_MEDIA_AUTO_ZOOM|PRIM_MEDIA_CONTROLS|PRIM_MEDIA_CONTROLS_MINI|PRIM_MEDIA_CONTROLS_STANDARD|PRIM_MEDIA_CURRENT_URL|PRIM_MEDIA_FIRST_CLICK_INTERACT|PRIM_MEDIA_HEIGHT_PIXELS|PRIM_MEDIA_HOME_URL|PRIM_MEDIA_MAX_HEIGHT_PIXELS|PRIM_MEDIA_MAX_URL_LENGTH|PRIM_MEDIA_MAX_WHITELIST_COUNT|PRIM_MEDIA_MAX_WHITELIST_SIZE|PRIM_MEDIA_MAX_WIDTH_PIXELS|PRIM_MEDIA_PARAM_MAX|PRIM_MEDIA_PERMS_CONTROL|PRIM_MEDIA_PERMS_INTERACT|PRIM_MEDIA_PERM_ANYONE|PRIM_MEDIA_PERM_GROUP|PRIM_MEDIA_PERM_NONE|PRIM_MEDIA_PERM_OWNER|PRIM_MEDIA_WHITELIST|PRIM_MEDIA_WHITELIST_ENABLE|PRIM_MEDIA_WIDTH_PIXELS|PRIM_NAME|PRIM_OMEGA|PRIM_PHANTOM|PRIM_PHYSICS|PRIM_PHYSICS_SHAPE_CONVEX|PRIM_PHYSICS_SHAPE_NONE|PRIM_PHYSICS_SHAPE_PRIM|PRIM_PHYSICS_SHAPE_TYPE|PRIM_POINT_LIGHT|PRIM_POSITION|PRIM_POS_LOCAL|PRIM_ROTATION|PRIM_ROT_LOCAL|PRIM_SCULPT_FLAG_INVERT|PRIM_SCULPT_FLAG_MIRROR|PRIM_SCULPT_TYPE_CYLINDER|PRIM_SCULPT_TYPE_MASK|PRIM_SCULPT_TYPE_PLANE|PRIM_SCULPT_TYPE_SPHERE|PRIM_SCULPT_TYPE_TORUS|PRIM_SHINY_HIGH|PRIM_SHINY_LOW|PRIM_SHINY_MEDIUM|PRIM_SHINY_NONE|PRIM_SIZE|PRIM_SLICE|PRIM_TEMP_ON_REZ|PRIM_TEXGEN|PRIM_TEXGEN_DEFAULT|PRIM_TEXGEN_PLANAR|PRIM_TEXT|PRIM_TEXTURE|PRIM_TYPE|PRIM_TYPE_BOX|PRIM_TYPE_CYLINDER|PRIM_TYPE_PRISM|PRIM_TYPE_RING|PRIM_TYPE_SCULPT|PRIM_TYPE_SPHERE|PRIM_TYPE_TORUS|PRIM_TYPE_TUBE|PROFILE_NONE|PROFILE_SCRIPT_MEMORY|PSYS_PART_BF_DEST_COLOR|PSYS_PART_BF_ONE|PSYS_PART_BF_ONE_MINUS_DEST_COLOR|PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA|PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR|PSYS_PART_BF_SOURCE_ALPHA|PSYS_PART_BF_SOURCE_COLOR|PSYS_PART_BF_ZERO|PSYS_PART_BLEND_FUNC_DEST|PSYS_PART_BLEND_FUNC_SOURCE|PSYS_PART_BOUNCE_MASK|PSYS_PART_EMISSIVE_MASK|PSYS_PART_END_ALPHA|PSYS_PART_END_COLOR|PSYS_PART_END_GLOW|PSYS_PART_END_SCALE|PSYS_PART_FLAGS|PSYS_PART_FOLLOW_SRC_MASK|PSYS_PART_FOLLOW_VELOCITY_MASK|PSYS_PART_INTERP_COLOR_MASK|PSYS_PART_INTERP_SCALE_MASK|PSYS_PART_MAX_AGE|PSYS_PART_RIBBON_MASK|PSYS_PART_START_ALPHA|PSYS_PART_START_COLOR|PSYS_PART_START_GLOW|PSYS_PART_START_SCALE|PSYS_PART_TARGET_LINEAR_MASK|PSYS_PART_TARGET_POS_MASK|PSYS_PART_WIND_MASK|PSYS_SRC_ACCEL|PSYS_SRC_ANGLE_BEGIN|PSYS_SRC_ANGLE_END|PSYS_SRC_BURST_PART_COUNT|PSYS_SRC_BURST_RADIUS|PSYS_SRC_BURST_RATE|PSYS_SRC_BURST_SPEED_MAX|PSYS_SRC_BURST_SPEED_MIN|PSYS_SRC_MAX_AGE|PSYS_SRC_OMEGA|PSYS_SRC_PATTERN|PSYS_SRC_PATTERN_ANGLE|PSYS_SRC_PATTERN_ANGLE_CONE|PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY|PSYS_SRC_PATTERN_DROP|PSYS_SRC_PATTERN_EXPLODE|PSYS_SRC_TARGET_KEY|PSYS_SRC_TEXTURE|PUBLIC_CHANNEL|PURSUIT_FUZZ_FACTOR|PURSUIT_GOAL_TOLERANCE|PURSUIT_INTERCEPT|PURSUIT_OFFSET|PU_EVADE_HIDDEN|PU_EVADE_SPOTTED|PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED|PU_FAILURE_INVALID_GOAL|PU_FAILURE_INVALID_START|PU_FAILURE_NO_NAVMESH|PU_FAILURE_NO_VALID_DESTINATION|PU_FAILURE_OTHER|PU_FAILURE_PARCEL_UNREACHABLE|PU_FAILURE_TARGET_GONE|PU_FAILURE_UNREACHABLE|PU_GOAL_REACHED|PU_SLOWDOWN_DISTANCE_REACHED|RCERR_CAST_TIME_EXCEEDED|RCERR_SIM_PERF_LOW|RCERR_UNKNOWN|RC_DATA_FLAGS|RC_DETECT_PHANTOM|RC_GET_LINK_NUM|RC_GET_NORMAL|RC_GET_ROOT_KEY|RC_MAX_HITS|RC_REJECT_AGENTS|RC_REJECT_LAND|RC_REJECT_NONPHYSICAL|RC_REJECT_PHYSICAL|RC_REJECT_TYPES|REGION_FLAG_ALLOW_DAMAGE|REGION_FLAG_ALLOW_DIRECT_TELEPORT|REGION_FLAG_BLOCK_FLY|REGION_FLAG_BLOCK_TERRAFORM|REGION_FLAG_DISABLE_COLLISIONS|REGION_FLAG_DISABLE_PHYSICS|REGION_FLAG_FIXED_SUN|REGION_FLAG_RESTRICT_PUSHOBJECT|REGION_FLAG_SANDBOX|REMOTE_DATA_CHANNEL|REMOTE_DATA_REPLY|REMOTE_DATA_REQUEST|REQUIRE_LINE_OF_SIGHT|RESTITUTION|REVERSE|ROTATE|SCALE|SCRIPTED|SIM_STAT_PCT_CHARS_STEPPED|SMOOTH|STATUS_BLOCK_GRAB|STATUS_BLOCK_GRAB_OBJECT|STATUS_BOUNDS_ERROR|STATUS_CAST_SHADOWS|STATUS_DIE_AT_EDGE|STATUS_INTERNAL_ERROR|STATUS_MALFORMED_PARAMS|STATUS_NOT_FOUND|STATUS_NOT_SUPPORTED|STATUS_OK|STATUS_PHANTOM|STATUS_PHYSICS|STATUS_RETURN_AT_EDGE|STATUS_ROTATE_X|STATUS_ROTATE_Y|STATUS_ROTATE_Z|STATUS_SANDBOX|STATUS_TYPE_MISMATCH|STATUS_WHITELIST_FAILED|STRING_TRIM|STRING_TRIM_HEAD|STRING_TRIM_TAIL|TOUCH_INVALID_FACE|TRAVERSAL_TYPE|TRAVERSAL_TYPE_FAST|TRAVERSAL_TYPE_NONE|TRAVERSAL_TYPE_SLOW|TRUE|TYPE_FLOAT|TYPE_INTEGER|TYPE_INVALID|TYPE_KEY|TYPE_ROTATION|TYPE_STRING|TYPE_VECTOR|VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY|VEHICLE_ANGULAR_DEFLECTION_TIMESCALE|VEHICLE_ANGULAR_FRICTION_TIMESCALE|VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE|VEHICLE_ANGULAR_MOTOR_DIRECTION|VEHICLE_ANGULAR_MOTOR_TIMESCALE|VEHICLE_BANKING_EFFICIENCY|VEHICLE_BANKING_MIX|VEHICLE_BANKING_TIMESCALE|VEHICLE_BUOYANCY|VEHICLE_FLAG_CAMERA_DECOUPLED|VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT|VEHICLE_FLAG_HOVER_TERRAIN_ONLY|VEHICLE_FLAG_HOVER_UP_ONLY|VEHICLE_FLAG_HOVER_WATER_ONLY|VEHICLE_FLAG_LIMIT_MOTOR_UP|VEHICLE_FLAG_LIMIT_ROLL_ONLY|VEHICLE_FLAG_MOUSELOOK_BANK|VEHICLE_FLAG_MOUSELOOK_STEER|VEHICLE_FLAG_NO_DEFLECTION_UP|VEHICLE_HOVER_EFFICIENCY|VEHICLE_HOVER_HEIGHT|VEHICLE_HOVER_TIMESCALE|VEHICLE_LINEAR_DEFLECTION_EFFICIENCY|VEHICLE_LINEAR_DEFLECTION_TIMESCALE|VEHICLE_LINEAR_FRICTION_TIMESCALE|VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE|VEHICLE_LINEAR_MOTOR_DIRECTION|VEHICLE_LINEAR_MOTOR_OFFSET|VEHICLE_LINEAR_MOTOR_TIMESCALE|VEHICLE_REFERENCE_FRAME|VEHICLE_TYPE_AIRPLANE|VEHICLE_TYPE_BALLOON|VEHICLE_TYPE_BOAT|VEHICLE_TYPE_CAR|VEHICLE_TYPE_NONE|VEHICLE_TYPE_SLED|VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY|VEHICLE_VERTICAL_ATTRACTION_TIMESCALE|VERTICAL|WANDER_PAUSE_AT_WAYPOINTS","constant.language.integer.boolean.lsl":"FALSE|TRUE","constant.language.quaternion.lsl":"ZERO_ROTATION","constant.language.string.lsl":"EOF|JSON_ARRAY|JSON_DELETE|JSON_FALSE|JSON_INVALID|JSON_NULL|JSON_NUMBER|JSON_OBJECT|JSON_STRING|JSON_TRUE|NULL_KEY|TEXTURE_BLANK|TEXTURE_DEFAULT|TEXTURE_MEDIA|TEXTURE_PLYWOOD|TEXTURE_TRANSPARENT|URL_REQUEST_DENIED|URL_REQUEST_GRANTED","constant.language.vector.lsl":"TOUCH_INVALID_TEXCOORD|TOUCH_INVALID_VECTOR|ZERO_VECTOR","invalid.broken.lsl":"LAND_LARGE_BRUSH|LAND_MEDIUM_BRUSH|LAND_SMALL_BRUSH","invalid.deprecated.lsl":"ATTACH_LPEC|ATTACH_RPEC|DATA_RATING|OBJECT_ATTACHMENT_GEOMETRY_BYTES|OBJECT_ATTACHMENT_SURFACE_AREA|PRIM_CAST_SHADOWS|PRIM_MATERIAL_LIGHT|PRIM_TYPE_LEGACY|PSYS_SRC_INNERANGLE|PSYS_SRC_OUTERANGLE|VEHICLE_FLAG_NO_FLY_UP|llCloud|llMakeExplosion|llMakeFire|llMakeFountain|llMakeSmoke|llRemoteDataSetRegion|llSound|llSoundPreload|llXorBase64Strings|llXorBase64StringsCorrect","invalid.illegal.lsl":"event","invalid.unimplemented.lsl":"CHARACTER_MAX_ANGULAR_ACCEL|CHARACTER_MAX_ANGULAR_SPEED|CHARACTER_TURN_SPEED_MULTIPLIER|PERMISSION_CHANGE_JOINTS|PERMISSION_CHANGE_PERMISSIONS|PERMISSION_RELEASE_OWNERSHIP|PERMISSION_REMAP_CONTROLS|PRIM_PHYSICS_MATERIAL|PSYS_SRC_OBJ_REL_MASK|llCollisionSprite|llPointAt|llRefreshPrimURL|llReleaseCamera|llRemoteLoadScript|llSetPrimURL|llStopPointAt|llTakeCamera","reserved.godmode.lsl":"llGodLikeRezObject|llSetInventoryPermMask|llSetObjectPermMask","reserved.log.lsl":"print","keyword.control.lsl":"do|else|for|if|jump|return|while","storage.type.lsl":"float|integer|key|list|quaternion|rotation|string|vector","support.function.lsl":"llAbs|llAcos|llAddToLandBanList|llAddToLandPassList|llAdjustSoundVolume|llAllowInventoryDrop|llAngleBetween|llApplyImpulse|llApplyRotationalImpulse|llAsin|llAtan2|llAttachToAvatar|llAttachToAvatarTemp|llAvatarOnLinkSitTarget|llAvatarOnSitTarget|llAxes2Rot|llAxisAngle2Rot|llBase64ToInteger|llBase64ToString|llBreakAllLinks|llBreakLink|llCSV2List|llCastRay|llCeil|llClearCameraParams|llClearLinkMedia|llClearPrimMedia|llCloseRemoteDataChannel|llCollisionFilter|llCollisionSound|llCos|llCreateCharacter|llCreateLink|llDeleteCharacter|llDeleteSubList|llDeleteSubString|llDetachFromAvatar|llDetectedGrab|llDetectedGroup|llDetectedKey|llDetectedLinkNumber|llDetectedName|llDetectedOwner|llDetectedPos|llDetectedRot|llDetectedTouchBinormal|llDetectedTouchFace|llDetectedTouchNormal|llDetectedTouchPos|llDetectedTouchST|llDetectedTouchUV|llDetectedType|llDetectedVel|llDialog|llDie|llDumpList2String|llEdgeOfWorld|llEjectFromLand|llEmail|llEscapeURL|llEuler2Rot|llEvade|llExecCharacterCmd|llFabs|llFleeFrom|llFloor|llForceMouselook|llFrand|llGenerateKey|llGetAccel|llGetAgentInfo|llGetAgentLanguage|llGetAgentList|llGetAgentSize|llGetAlpha|llGetAndResetTime|llGetAnimation|llGetAnimationList|llGetAnimationOverride|llGetAttached|llGetBoundingBox|llGetCameraPos|llGetCameraRot|llGetCenterOfMass|llGetClosestNavPoint|llGetColor|llGetCreator|llGetDate|llGetDisplayName|llGetEnergy|llGetEnv|llGetForce|llGetFreeMemory|llGetFreeURLs|llGetGMTclock|llGetGeometricCenter|llGetHTTPHeader|llGetInventoryCreator|llGetInventoryKey|llGetInventoryName|llGetInventoryNumber|llGetInventoryPermMask|llGetInventoryType|llGetKey|llGetLandOwnerAt|llGetLinkKey|llGetLinkMedia|llGetLinkName|llGetLinkNumber|llGetLinkNumberOfSides|llGetLinkPrimitiveParams|llGetListEntryType|llGetListLength|llGetLocalPos|llGetLocalRot|llGetMass|llGetMassMKS|llGetMaxScaleFactor|llGetMemoryLimit|llGetMinScaleFactor|llGetNextEmail|llGetNotecardLine|llGetNumberOfNotecardLines|llGetNumberOfPrims|llGetNumberOfSides|llGetObjectDesc|llGetObjectDetails|llGetObjectMass|llGetObjectName|llGetObjectPermMask|llGetObjectPrimCount|llGetOmega|llGetOwner|llGetOwnerKey|llGetParcelDetails|llGetParcelFlags|llGetParcelMaxPrims|llGetParcelMusicURL|llGetParcelPrimCount|llGetParcelPrimOwners|llGetPermissions|llGetPermissionsKey|llGetPhysicsMaterial|llGetPos|llGetPrimMediaParams|llGetPrimitiveParams|llGetRegionAgentCount|llGetRegionCorner|llGetRegionFPS|llGetRegionFlags|llGetRegionName|llGetRegionTimeDilation|llGetRootPosition|llGetRootRotation|llGetRot|llGetSPMaxMemory|llGetScale|llGetScriptName|llGetScriptState|llGetSimStats|llGetSimulatorHostname|llGetStartParameter|llGetStaticPath|llGetStatus|llGetSubString|llGetSunDirection|llGetTexture|llGetTextureOffset|llGetTextureRot|llGetTextureScale|llGetTime|llGetTimeOfDay|llGetTimestamp|llGetTorque|llGetUnixTime|llGetUsedMemory|llGetUsername|llGetVel|llGetWallclock|llGiveInventory|llGiveInventoryList|llGiveMoney|llGround|llGroundContour|llGroundNormal|llGroundRepel|llGroundSlope|llHTTPRequest|llHTTPResponse|llInsertString|llInstantMessage|llIntegerToBase64|llJson2List|llJsonGetValue|llJsonSetValue|llJsonValueType|llKey2Name|llLinkParticleSystem|llLinkSitTarget|llList2CSV|llList2Float|llList2Integer|llList2Json|llList2Key|llList2List|llList2ListStrided|llList2Rot|llList2String|llList2Vector|llListFindList|llListInsertList|llListRandomize|llListReplaceList|llListSort|llListStatistics|llListen|llListenControl|llListenRemove|llLoadURL|llLog|llLog10|llLookAt|llLoopSound|llLoopSoundMaster|llLoopSoundSlave|llMD5String|llManageEstateAccess|llMapDestination|llMessageLinked|llMinEventDelay|llModPow|llModifyLand|llMoveToTarget|llNavigateTo|llOffsetTexture|llOpenRemoteDataChannel|llOverMyLand|llOwnerSay|llParcelMediaCommandList|llParcelMediaQuery|llParseString2List|llParseStringKeepNulls|llParticleSystem|llPassCollisions|llPassTouches|llPatrolPoints|llPlaySound|llPlaySoundSlave|llPow|llPreloadSound|llPursue|llPushObject|llRegionSay|llRegionSayTo|llReleaseControls|llReleaseURL|llRemoteDataReply|llRemoteLoadScriptPin|llRemoveFromLandBanList|llRemoveFromLandPassList|llRemoveInventory|llRemoveVehicleFlags|llRequestAgentData|llRequestDisplayName|llRequestInventoryData|llRequestPermissions|llRequestSecureURL|llRequestSimulatorData|llRequestURL|llRequestUsername|llResetAnimationOverride|llResetLandBanList|llResetLandPassList|llResetOtherScript|llResetScript|llResetTime|llReturnObjectsByID|llReturnObjectsByOwner|llRezAtRoot|llRezObject|llRot2Angle|llRot2Axis|llRot2Euler|llRot2Fwd|llRot2Left|llRot2Up|llRotBetween|llRotLookAt|llRotTarget|llRotTargetRemove|llRotateTexture|llRound|llSHA1String|llSameGroup|llSay|llScaleByFactor|llScaleTexture|llScriptDanger|llScriptProfiler|llSendRemoteData|llSensor|llSensorRemove|llSensorRepeat|llSetAlpha|llSetAngularVelocity|llSetAnimationOverride|llSetBuoyancy|llSetCameraAtOffset|llSetCameraEyeOffset|llSetCameraParams|llSetClickAction|llSetColor|llSetContentType|llSetDamage|llSetForce|llSetForceAndTorque|llSetHoverHeight|llSetKeyframedMotion|llSetLinkAlpha|llSetLinkCamera|llSetLinkColor|llSetLinkMedia|llSetLinkPrimitiveParams|llSetLinkPrimitiveParamsFast|llSetLinkTexture|llSetLinkTextureAnim|llSetLocalRot|llSetMemoryLimit|llSetObjectDesc|llSetObjectName|llSetParcelMusicURL|llSetPayPrice|llSetPhysicsMaterial|llSetPos|llSetPrimMediaParams|llSetPrimitiveParams|llSetRegionPos|llSetRemoteScriptAccessPin|llSetRot|llSetScale|llSetScriptState|llSetSitText|llSetSoundQueueing|llSetSoundRadius|llSetStatus|llSetText|llSetTexture|llSetTextureAnim|llSetTimerEvent|llSetTorque|llSetTouchText|llSetVehicleFlags|llSetVehicleFloatParam|llSetVehicleRotationParam|llSetVehicleType|llSetVehicleVectorParam|llSetVelocity|llShout|llSin|llSitTarget|llSleep|llSqrt|llStartAnimation|llStopAnimation|llStopHover|llStopLookAt|llStopMoveToTarget|llStopSound|llStringLength|llStringToBase64|llStringTrim|llSubStringIndex|llTakeControls|llTan|llTarget|llTargetOmega|llTargetRemove|llTeleportAgent|llTeleportAgentGlobalCoords|llTeleportAgentHome|llTextBox|llToLower|llToUpper|llTransferLindenDollars|llTriggerSound|llTriggerSoundLimited|llUnSit|llUnescapeURL|llUpdateCharacter|llVecDist|llVecMag|llVecNorm|llVolumeDetect|llWanderWithin|llWater|llWhisper|llWind|llXorBase64","support.function.event.lsl":"at_rot_target|at_target|attach|changed|collision|collision_end|collision_start|control|dataserver|email|http_request|http_response|land_collision|land_collision_end|land_collision_start|link_message|listen|money|moving_end|moving_start|no_sensor|not_at_rot_target|not_at_target|object_rez|on_rez|path_update|remote_data|run_time_permissions|sensor|state_entry|state_exit|timer|touch|touch_end|touch_start|transaction_result"},"identifier");this.$rules={start:[{token:"comment.line.double-slash.lsl",regex:"\\/\\/.*$"},{token:"comment.block.begin.lsl",regex:"\\/\\*",next:"comment"},{token:"string.quoted.double.lsl",start:'"',end:'"',next:[{token:"constant.character.escape.lsl",regex:/\\[tn"\\]/}]},{token:"constant.numeric.lsl",regex:"(0[xX][0-9a-fA-F]+|[+-]?[0-9]+(?:(?:\\.[0-9]*)?(?:[eE][+-]?[0-9]+)?)?)\\b"},{token:"entity.name.state.lsl",regex:"\\b((state)\\s+\\w+|default)\\b"},{token:e,regex:"\\b[a-zA-Z_][a-zA-Z0-9_]*\\b"},{token:"support.function.user-defined.lsl",regex:/\b([a-zA-Z_]\w*)(?=\(.*?\))/},{token:"keyword.operator.lsl",regex:"\\+\\+|\\-\\-|<<|>>|&&?|\\|\\|?|\\^|~|[!%<>=*+\\-\\/]=?"},{token:"invalid.illegal.keyword.operator.lsl",regex:":=?"},{token:"punctuation.operator.lsl",regex:"\\,|\\;"},{token:"paren.lparen.lsl",regex:"[\\[\\(\\{]"},{token:"paren.rparen.lsl",regex:"[\\]\\)\\}]"},{token:"text.lsl",regex:"\\s+"}],comment:[{token:"comment.block.end.lsl",regex:"\\*\\/",next:"start"},{token:"comment.block.lsl",regex:".+"}]},this.normalizeRules()}var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules;r.inherits(s,i),t.LSLHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/lsl",["require","exports","module","ace/mode/lsl_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/text","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle","ace/lib/oop"],function(e,t,n){"use strict";var r=e("./lsl_highlight_rules").LSLHighlightRules,i=e("./matching_brace_outdent").MatchingBraceOutdent,s=e("../range").Range,o=e("./text").Mode,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode,f=e("../lib/oop"),l=function(){this.HighlightRules=r,this.$outdent=new i,this.$behaviour=new u,this.foldingRules=new a};f.inherits(l,o),function(){this.lineCommentStart=["//"],this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type==="comment.block.lsl")return r;if(e==="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/lsl"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-lua.js b/dist/assets/js/vendor/ace-nc/mode-lua.js
            new file mode 100644
            index 0000000000..19bd3d5dc7
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-lua.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/lua_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="break|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while|or|and|not",t="true|false|nil|_G|_VERSION",n="string|xpcall|package|tostring|print|os|unpack|require|getfenv|setmetatable|next|assert|tonumber|io|rawequal|collectgarbage|getmetatable|module|rawset|math|debug|pcall|table|newproxy|type|coroutine|_G|select|gcinfo|pairs|rawget|loadstring|ipairs|_VERSION|dofile|setfenv|load|error|loadfile|sub|upper|len|gfind|rep|find|match|char|dump|gmatch|reverse|byte|format|gsub|lower|preload|loadlib|loaded|loaders|cpath|config|path|seeall|exit|setlocale|date|getenv|difftime|remove|time|clock|tmpname|rename|execute|lines|write|close|flush|open|output|type|read|stderr|stdin|input|stdout|popen|tmpfile|log|max|acos|huge|ldexp|pi|cos|tanh|pow|deg|tan|cosh|sinh|random|randomseed|frexp|ceil|floor|rad|abs|sqrt|modf|asin|min|mod|fmod|log10|atan2|exp|sin|atan|getupvalue|debug|sethook|getmetatable|gethook|setmetatable|setlocal|traceback|setfenv|getinfo|setupvalue|getlocal|getregistry|getfenv|setn|insert|getn|foreachi|maxn|foreach|concat|sort|remove|resume|yield|status|wrap|create|running|__add|__sub|__mod|__unm|__concat|__lt|__index|__call|__gc|__metatable|__mul|__div|__pow|__len|__eq|__le|__newindex|__tostring|__mode|__tonumber",r="string|package|os|io|math|debug|table|coroutine",i="",s="setn|foreach|foreachi|gcinfo|log10|maxn",o=this.createKeywordMapper({keyword:e,"support.function":n,"invalid.deprecated":s,"constant.library":r,"constant.language":t,"invalid.illegal":i,"variable.language":"self"},"identifier"),u="(?:(?:[1-9]\\d*)|(?:0))",a="(?:0[xX][\\dA-Fa-f]+)",f="(?:"+u+"|"+a+")",l="(?:\\.\\d+)",c="(?:\\d+)",h="(?:(?:"+c+"?"+l+")|(?:"+c+"\\.))",p="(?:"+h+")";this.$rules={start:[{stateName:"bracketedComment",onMatch:function(e,t,n){return n.unshift(this.next,e.length-2,t),"comment"},regex:/\-\-\[=*\[/,next:[{onMatch:function(e,t,n){return e.length==n[1]?(n.shift(),n.shift(),this.next=n.shift()):this.next="","comment"},regex:/\]=*\]/,next:"start"},{defaultToken:"comment"}]},{token:"comment",regex:"\\-\\-.*$"},{stateName:"bracketedString",onMatch:function(e,t,n){return n.unshift(this.next,e.length,t),"comment"},regex:/\[=*\[/,next:[{onMatch:function(e,t,n){return e.length==n[1]?(n.shift(),n.shift(),this.next=n.shift()):this.next="","comment"},regex:/\]=*\]/,next:"start"},{defaultToken:"comment"}]},{token:"string",regex:'"(?:[^\\\\]|\\\\.)*?"'},{token:"string",regex:"'(?:[^\\\\]|\\\\.)*?'"},{token:"constant.numeric",regex:p},{token:"constant.numeric",regex:f+"\\b"},{token:o,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\/|%|\\#|\\^|~|<|>|<=|=>|==|~=|=|\\:|\\.\\.\\.|\\.\\."},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+|\\w+"}]},this.normalizeRules()};r.inherits(s,i),t.LuaHighlightRules=s}),ace.define("ace/mode/folding/lua",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=e("../../token_iterator").TokenIterator,u=t.FoldMode=function(){};r.inherits(u,i),function(){this.foldingStartMarker=/\b(function|then|do|repeat)\b|{\s*$|(\[=*\[)/,this.foldingStopMarker=/\bend\b|^\s*}|\]=*\]/,this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=this.foldingStartMarker.test(r),s=this.foldingStopMarker.test(r);if(i&&!s){var o=r.match(this.foldingStartMarker);if(o[1]=="then"&&/\belseif\b/.test(r))return;if(o[1]){if(e.getTokenAt(n,o.index+1).type==="keyword")return"start"}else{if(!o[2])return"start";var u=e.bgTokenizer.getState(n)||"";if(u[0]=="bracketedComment"||u[0]=="bracketedString")return"start"}}if(t!="markbeginend"||!s||i&&s)return"";var o=r.match(this.foldingStopMarker);if(o[0]==="end"){if(e.getTokenAt(n,o.index+1).type==="keyword")return"end"}else{if(o[0][0]!=="]")return"end";var u=e.bgTokenizer.getState(n-1)||"";if(u[0]=="bracketedComment"||u[0]=="bracketedString")return"end"}},this.getFoldWidgetRange=function(e,t,n){var r=e.doc.getLine(n),i=this.foldingStartMarker.exec(r);if(i)return i[1]?this.luaBlock(e,n,i.index+1):i[2]?e.getCommentFoldRange(n,i.index+1):this.openingBracketBlock(e,"{",n,i.index);var i=this.foldingStopMarker.exec(r);if(i)return i[0]==="end"&&e.getTokenAt(n,i.index+1).type==="keyword"?this.luaBlock(e,n,i.index+1):i[0][0]==="]"?e.getCommentFoldRange(n,i.index+1):this.closingBracketBlock(e,"}",n,i.index+i[0].length)},this.luaBlock=function(e,t,n){var r=new o(e,t,n),i={"function":1,"do":1,then:1,elseif:-1,end:-1,repeat:1,until:-1},u=r.getCurrentToken();if(!u||u.type!="keyword")return;var a=u.value,f=[a],l=i[a];if(!l)return;var c=l===-1?r.getCurrentTokenColumn():e.getLine(t).length,h=t;r.step=l===-1?r.stepBackward:r.stepForward;while(u=r.step()){if(u.type!=="keyword")continue;var p=l*i[u.value];if(p>0)f.unshift(u.value);else if(p<=0){f.shift();if(!f.length&&u.value!="elseif")break;p===0&&f.unshift(u.value)}}var t=r.getCurrentTokenRow();return l===-1?new s(t,e.getLine(t).length,h,c):new s(h,c,t,r.getCurrentTokenColumn())}}.call(u.prototype)}),ace.define("ace/mode/lua",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/lua_highlight_rules","ace/mode/folding/lua","ace/range","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./lua_highlight_rules").LuaHighlightRules,o=e("./folding/lua").FoldMode,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(f,i),function(){function n(t){var n=0;for(var r=0;r<t.length;r++){var i=t[r];i.type=="keyword"?i.value in e&&(n+=e[i.value]):i.type=="paren.lparen"?n++:i.type=="paren.rparen"&&n--}return n<0?-1:n>0?1:0}this.lineCommentStart="--",this.blockComment={start:"--[",end:"]--"};var e={"function":1,then:1,"do":1,"else":1,elseif:1,repeat:1,end:-1,until:-1},t=["else","elseif","end","until"];this.getNextLineIndent=function(e,t,r){var i=this.$getIndent(t),s=0,o=this.getTokenizer().getLineTokens(t,e),u=o.tokens;return e=="start"&&(s=n(u)),s>0?i+r:s<0&&i.substr(i.length-r.length)==r&&!this.checkOutdent(e,t,"\n")?i.substr(0,i.length-r.length):i},this.checkOutdent=function(e,n,r){if(r!="\n"&&r!="\r"&&r!="\r\n")return!1;if(n.match(/^\s*[\)\}\]]$/))return!0;var i=this.getTokenizer().getLineTokens(n.trim(),e).tokens;return!i||!i.length?!1:i[0].type=="keyword"&&t.indexOf(i[0].value)!=-1},this.autoOutdent=function(e,t,r){var i=t.getLine(r-1),s=this.$getIndent(i).length,o=this.getTokenizer().getLineTokens(i,"start").tokens,a=t.getTabString().length,f=s+a*n(o),l=this.$getIndent(t.getLine(r)).length;if(l<f)return;t.outdentRows(new u(r,0,r+2,0))},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/lua_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("error",function(t){e.setAnnotations([t.data])}),t.on("ok",function(t){e.clearAnnotations()}),t},this.$id="ace/mode/lua"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-luapage.js b/dist/assets/js/vendor/ace-nc/mode-luapage.js
            new file mode 100644
            index 0000000000..9b87486ba4
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-luapage.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/lua_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="break|do|else|elseif|end|for|function|if|in|local|repeat|return|then|until|while|or|and|not",t="true|false|nil|_G|_VERSION",n="string|xpcall|package|tostring|print|os|unpack|require|getfenv|setmetatable|next|assert|tonumber|io|rawequal|collectgarbage|getmetatable|module|rawset|math|debug|pcall|table|newproxy|type|coroutine|_G|select|gcinfo|pairs|rawget|loadstring|ipairs|_VERSION|dofile|setfenv|load|error|loadfile|sub|upper|len|gfind|rep|find|match|char|dump|gmatch|reverse|byte|format|gsub|lower|preload|loadlib|loaded|loaders|cpath|config|path|seeall|exit|setlocale|date|getenv|difftime|remove|time|clock|tmpname|rename|execute|lines|write|close|flush|open|output|type|read|stderr|stdin|input|stdout|popen|tmpfile|log|max|acos|huge|ldexp|pi|cos|tanh|pow|deg|tan|cosh|sinh|random|randomseed|frexp|ceil|floor|rad|abs|sqrt|modf|asin|min|mod|fmod|log10|atan2|exp|sin|atan|getupvalue|debug|sethook|getmetatable|gethook|setmetatable|setlocal|traceback|setfenv|getinfo|setupvalue|getlocal|getregistry|getfenv|setn|insert|getn|foreachi|maxn|foreach|concat|sort|remove|resume|yield|status|wrap|create|running|__add|__sub|__mod|__unm|__concat|__lt|__index|__call|__gc|__metatable|__mul|__div|__pow|__len|__eq|__le|__newindex|__tostring|__mode|__tonumber",r="string|package|os|io|math|debug|table|coroutine",i="",s="setn|foreach|foreachi|gcinfo|log10|maxn",o=this.createKeywordMapper({keyword:e,"support.function":n,"invalid.deprecated":s,"constant.library":r,"constant.language":t,"invalid.illegal":i,"variable.language":"self"},"identifier"),u="(?:(?:[1-9]\\d*)|(?:0))",a="(?:0[xX][\\dA-Fa-f]+)",f="(?:"+u+"|"+a+")",l="(?:\\.\\d+)",c="(?:\\d+)",h="(?:(?:"+c+"?"+l+")|(?:"+c+"\\.))",p="(?:"+h+")";this.$rules={start:[{stateName:"bracketedComment",onMatch:function(e,t,n){return n.unshift(this.next,e.length-2,t),"comment"},regex:/\-\-\[=*\[/,next:[{onMatch:function(e,t,n){return e.length==n[1]?(n.shift(),n.shift(),this.next=n.shift()):this.next="","comment"},regex:/\]=*\]/,next:"start"},{defaultToken:"comment"}]},{token:"comment",regex:"\\-\\-.*$"},{stateName:"bracketedString",onMatch:function(e,t,n){return n.unshift(this.next,e.length,t),"comment"},regex:/\[=*\[/,next:[{onMatch:function(e,t,n){return e.length==n[1]?(n.shift(),n.shift(),this.next=n.shift()):this.next="","comment"},regex:/\]=*\]/,next:"start"},{defaultToken:"comment"}]},{token:"string",regex:'"(?:[^\\\\]|\\\\.)*?"'},{token:"string",regex:"'(?:[^\\\\]|\\\\.)*?'"},{token:"constant.numeric",regex:p},{token:"constant.numeric",regex:f+"\\b"},{token:o,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\/|%|\\#|\\^|~|<|>|<=|=>|==|~=|=|\\:|\\.\\.\\.|\\.\\."},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+|\\w+"}]},this.normalizeRules()};r.inherits(s,i),t.LuaHighlightRules=s}),ace.define("ace/mode/folding/lua",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=e("../../token_iterator").TokenIterator,u=t.FoldMode=function(){};r.inherits(u,i),function(){this.foldingStartMarker=/\b(function|then|do|repeat)\b|{\s*$|(\[=*\[)/,this.foldingStopMarker=/\bend\b|^\s*}|\]=*\]/,this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=this.foldingStartMarker.test(r),s=this.foldingStopMarker.test(r);if(i&&!s){var o=r.match(this.foldingStartMarker);if(o[1]=="then"&&/\belseif\b/.test(r))return;if(o[1]){if(e.getTokenAt(n,o.index+1).type==="keyword")return"start"}else{if(!o[2])return"start";var u=e.bgTokenizer.getState(n)||"";if(u[0]=="bracketedComment"||u[0]=="bracketedString")return"start"}}if(t!="markbeginend"||!s||i&&s)return"";var o=r.match(this.foldingStopMarker);if(o[0]==="end"){if(e.getTokenAt(n,o.index+1).type==="keyword")return"end"}else{if(o[0][0]!=="]")return"end";var u=e.bgTokenizer.getState(n-1)||"";if(u[0]=="bracketedComment"||u[0]=="bracketedString")return"end"}},this.getFoldWidgetRange=function(e,t,n){var r=e.doc.getLine(n),i=this.foldingStartMarker.exec(r);if(i)return i[1]?this.luaBlock(e,n,i.index+1):i[2]?e.getCommentFoldRange(n,i.index+1):this.openingBracketBlock(e,"{",n,i.index);var i=this.foldingStopMarker.exec(r);if(i)return i[0]==="end"&&e.getTokenAt(n,i.index+1).type==="keyword"?this.luaBlock(e,n,i.index+1):i[0][0]==="]"?e.getCommentFoldRange(n,i.index+1):this.closingBracketBlock(e,"}",n,i.index+i[0].length)},this.luaBlock=function(e,t,n){var r=new o(e,t,n),i={"function":1,"do":1,then:1,elseif:-1,end:-1,repeat:1,until:-1},u=r.getCurrentToken();if(!u||u.type!="keyword")return;var a=u.value,f=[a],l=i[a];if(!l)return;var c=l===-1?r.getCurrentTokenColumn():e.getLine(t).length,h=t;r.step=l===-1?r.stepBackward:r.stepForward;while(u=r.step()){if(u.type!=="keyword")continue;var p=l*i[u.value];if(p>0)f.unshift(u.value);else if(p<=0){f.shift();if(!f.length&&u.value!="elseif")break;p===0&&f.unshift(u.value)}}var t=r.getCurrentTokenRow();return l===-1?new s(t,e.getLine(t).length,h,c):new s(h,c,t,r.getCurrentTokenColumn())}}.call(u.prototype)}),ace.define("ace/mode/lua",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/lua_highlight_rules","ace/mode/folding/lua","ace/range","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./lua_highlight_rules").LuaHighlightRules,o=e("./folding/lua").FoldMode,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(f,i),function(){function n(t){var n=0;for(var r=0;r<t.length;r++){var i=t[r];i.type=="keyword"?i.value in e&&(n+=e[i.value]):i.type=="paren.lparen"?n++:i.type=="paren.rparen"&&n--}return n<0?-1:n>0?1:0}this.lineCommentStart="--",this.blockComment={start:"--[",end:"]--"};var e={"function":1,then:1,"do":1,"else":1,elseif:1,repeat:1,end:-1,until:-1},t=["else","elseif","end","until"];this.getNextLineIndent=function(e,t,r){var i=this.$getIndent(t),s=0,o=this.getTokenizer().getLineTokens(t,e),u=o.tokens;return e=="start"&&(s=n(u)),s>0?i+r:s<0&&i.substr(i.length-r.length)==r&&!this.checkOutdent(e,t,"\n")?i.substr(0,i.length-r.length):i},this.checkOutdent=function(e,n,r){if(r!="\n"&&r!="\r"&&r!="\r\n")return!1;if(n.match(/^\s*[\)\}\]]$/))return!0;var i=this.getTokenizer().getLineTokens(n.trim(),e).tokens;return!i||!i.length?!1:i[0].type=="keyword"&&t.indexOf(i[0].value)!=-1},this.autoOutdent=function(e,t,r){var i=t.getLine(r-1),s=this.$getIndent(i).length,o=this.getTokenizer().getLineTokens(i,"start").tokens,a=t.getTabString().length,f=s+a*n(o),l=this.$getIndent(t.getLine(r)).length;if(l<f)return;t.outdentRows(new u(r,0,r+2,0))},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/lua_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("error",function(t){e.setAnnotations([t.data])}),t.on("ok",function(t){e.clearAnnotations()}),t},this.$id="ace/mode/lua"}.call(f.prototype),t.Mode=f}),ace.define("ace/mode/luapage_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules","ace/mode/lua_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=e("./lua_highlight_rules").LuaHighlightRules,o=function(){i.call(this);var e=[{token:"keyword",regex:"<\\%\\=?",push:"lua-start"},{token:"keyword",regex:"<\\?lua\\=?",push:"lua-start"}],t=[{token:"keyword",regex:"\\%>",next:"pop"},{token:"keyword",regex:"\\?>",next:"pop"}];this.embedRules(s,"lua-",t,["start"]);for(var n in this.$rules)this.$rules[n].unshift.apply(this.$rules[n],e);this.normalizeRules()};r.inherits(o,i),t.LuaPageHighlightRules=o}),ace.define("ace/mode/luapage",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/lua","ace/mode/luapage_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html").Mode,s=e("./lua").Mode,o=e("./luapage_highlight_rules").LuaPageHighlightRules,u=function(){i.call(this),this.HighlightRules=o,this.createModeDelegates({"lua-":s})};r.inherits(u,i),function(){this.$id="ace/mode/luapage"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-lucene.js b/dist/assets/js/vendor/ace-nc/mode-lucene.js
            new file mode 100644
            index 0000000000..6b482d3c51
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-lucene.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/lucene_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(){this.$rules={start:[{token:"constant.character.negation",regex:"[\\-]"},{token:"constant.character.interro",regex:"[\\?]"},{token:"constant.character.asterisk",regex:"[\\*]"},{token:"constant.character.proximity",regex:"~[0-9]+\\b"},{token:"keyword.operator",regex:"(?:AND|OR|NOT)\\b"},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"keyword",regex:"[\\S]+:"},{token:"string",regex:'".*?"'},{token:"text",regex:"\\s+"}]}};r.inherits(o,s),t.LuceneHighlightRules=o}),ace.define("ace/mode/lucene",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/lucene_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./lucene_highlight_rules").LuceneHighlightRules,o=function(){this.HighlightRules=s};r.inherits(o,i),function(){this.$id="ace/mode/lucene"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-makefile.js b/dist/assets/js/vendor/ace-nc/mode-makefile.js
            new file mode 100644
            index 0000000000..af99489922
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-makefile.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/sh_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.reservedKeywords="!|{|}|case|do|done|elif|else|esac|fi|for|if|in|then|until|while|&|;|export|local|read|typeset|unset|elif|select|set",o=t.languageConstructs="[|]|alias|bg|bind|break|builtin|cd|command|compgen|complete|continue|dirs|disown|echo|enable|eval|exec|exit|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|return|set|shift|shopt|source|suspend|test|times|trap|type|ulimit|umask|unalias|wait",u=function(){var e=this.createKeywordMapper({keyword:s,"support.function.builtin":o,"invalid.deprecated":"debugger"},"identifier"),t="(?:(?:[1-9]\\d*)|(?:0))",n="(?:\\.\\d+)",r="(?:\\d+)",i="(?:(?:"+r+"?"+n+")|(?:"+r+"\\.))",u="(?:(?:"+i+"|"+r+")"+")",a="(?:"+u+"|"+i+")",f="(?:&"+r+")",l="[a-zA-Z_][a-zA-Z0-9_]*",c="(?:(?:\\$"+l+")|(?:"+l+"=))",h="(?:\\$(?:SHLVL|\\$|\\!|\\?))",p="(?:"+l+"\\s*\\(\\))";this.$rules={start:[{token:"constant",regex:/\\./},{token:["text","comment"],regex:/(^|\s)(#.*)$/},{token:"string",regex:'"',push:[{token:"constant.language.escape",regex:/\\(?:[$abeEfnrtv\\'"]|x[a-fA-F\d]{1,2}|u[a-fA-F\d]{4}([a-fA-F\d]{4})?|c.|\d{1,3})/},{token:"constant",regex:/\$\w+/},{token:"string",regex:'"',next:"pop"},{defaultToken:"string"}]},{token:"variable.language",regex:h},{token:"variable",regex:c},{token:"support.function",regex:p},{token:"support.function",regex:f},{token:"string",start:"'",end:"'"},{token:"constant.numeric",regex:a},{token:"constant.numeric",regex:t+"\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|~|<|>|<=|=>|=|!="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"}]},this.normalizeRules()};r.inherits(u,i),t.ShHighlightRules=u}),ace.define("ace/mode/makefile_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/sh_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=e("./sh_highlight_rules"),o=function(){var e=this.createKeywordMapper({keyword:s.reservedKeywords,"support.function.builtin":s.languageConstructs,"invalid.deprecated":"debugger"},"string");this.$rules={start:[{token:"string.interpolated.backtick.makefile",regex:"`",next:"shell-start"},{token:"punctuation.definition.comment.makefile",regex:/#(?=.)/,next:"comment"},{token:["keyword.control.makefile"],regex:"^(?:\\s*\\b)(\\-??include|ifeq|ifneq|ifdef|ifndef|else|endif|vpath|export|unexport|define|endef|override)(?:\\b)"},{token:["entity.name.function.makefile","text"],regex:"^([^\\t ]+(?:\\s[^\\t ]+)*:)(\\s*.*)"}],comment:[{token:"punctuation.definition.comment.makefile",regex:/.+\\/},{token:"punctuation.definition.comment.makefile",regex:".+",next:"start"}],"shell-start":[{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"string",regex:"\\w+"},{token:"string.interpolated.backtick.makefile",regex:"`",next:"start"}]}};r.inherits(o,i),t.MakefileHighlightRules=o}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/makefile",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/makefile_highlight_rules","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./makefile_highlight_rules").MakefileHighlightRules,o=e("./folding/coffee").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="#",this.$indentWithTabs=!0,this.$id="ace/mode/makefile"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-markdown.js b/dist/assets/js/vendor/ace-nc/mode-markdown.js
            new file mode 100644
            index 0000000000..b314dc2ed6
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-markdown.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/xml_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/xml"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./xml_highlight_rules").XmlHighlightRules,u=e("./behaviour/xml").XmlBehaviour,a=e("./folding/xml").FoldMode,f=function(){this.HighlightRules=o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,s),function(){this.voidElements=i.arrayToMap([]),this.blockComment={start:"<!--",end:"-->"},this.$id="ace/mode/xml"}.call(f.prototype),t.Mode=f}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/markdown_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules","ace/mode/html_highlight_rules","ace/mode/css_highlight_rules"],function(e,t,n){"use strict";function c(e,t){return{token:"support.function",regex:"^\\s*```"+e+"\\s*$",push:t+"start"}}var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./css_highlight_rules").CssHighlightRules,l=function(e){return"(?:[^"+i.escapeRegExp(e)+"\\\\]|\\\\.)*"},h=function(){a.call(this),this.$rules.start.unshift({token:"empty_line",regex:"^$",next:"allowBlock"},{token:"markup.heading.1",regex:"^=+(?=\\s*$)"},{token:"markup.heading.2",regex:"^\\-+(?=\\s*$)"},{token:function(e){return"markup.heading."+e.length},regex:/^#{1,6}(?=\s*[^ #]|\s+#.)/,next:"header"},c("(?:javascript|js)","jscode-"),c("xml","xmlcode-"),c("html","htmlcode-"),c("css","csscode-"),{token:"support.function",regex:"^\\s*```\\s*\\S*(?:{.*?\\})?\\s*$",next:"githubblock"},{token:"string.blockquote",regex:"^\\s*>\\s*(?:[*+-]|\\d+\\.)?\\s+",next:"blockquote"},{token:"constant",regex:"^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$",next:"allowBlock"},{token:"markup.list",regex:"^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",next:"listblock-start"},{include:"basic"}),this.addRules({basic:[{token:"constant.language.escape",regex:/\\[\\`*_{}\[\]()#+\-.!]/},{token:"support.function",regex:"(`+)(.*?[^`])(\\1)"},{token:["text","constant","text","url","string","text"],regex:'^([ ]{0,3}\\[)([^\\]]+)(\\]:\\s*)([^ ]+)(\\s*(?:["][^"]+["])?(\\s*))$'},{token:["text","string","text","constant","text"],regex:"(\\[)("+l("]")+")(\\]s*\\[)("+l("]")+")(\\])"},{token:["text","string","text","markup.underline","string","text"],regex:"(\\[)("+l("]")+")(\\]\\()"+'((?:[^\\)\\s\\\\]|\\\\.|\\s(?=[^"]))*)'+'(\\s*"'+l('"')+'"\\s*)?'+"(\\))"},{token:"string.strong",regex:"([*]{2}|[_]{2}(?=\\S))(.*?\\S[*_]*)(\\1)"},{token:"string.emphasis",regex:"([*]|[_](?=\\S))(.*?\\S[*_]*)(\\1)"},{token:["text","url","text"],regex:"(<)((?:https?|ftp|dict):[^'\">\\s]+|(?:mailto:)?[-.\\w]+\\@[-a-z0-9]+(?:\\.[-a-z0-9]+)*\\.[a-z]+)(>)"}],allowBlock:[{token:"support.function",regex:"^ {4}.+",next:"allowBlock"},{token:"empty",regex:"",next:"start"}],header:[{regex:"$",next:"start"},{include:"basic"},{defaultToken:"heading"}],"listblock-start":[{token:"support.variable",regex:/(?:\[[ x]\])?/,next:"listblock"}],listblock:[{token:"empty_line",regex:"^$",next:"start"},{token:"markup.list",regex:"^\\s{0,3}(?:[*+-]|\\d+\\.)\\s+",next:"listblock-start"},{include:"basic",noEscape:!0},{token:"support.function",regex:"^\\s*```\\s*[a-zA-Z]*(?:{.*?\\})?\\s*$",next:"githubblock"},{defaultToken:"list"}],blockquote:[{token:"empty_line",regex:"^\\s*$",next:"start"},{token:"string.blockquote",regex:"^\\s*>\\s*(?:[*+-]|\\d+\\.)?\\s+",next:"blockquote"},{include:"basic",noEscape:!0},{defaultToken:"string.blockquote"}],githubblock:[{token:"support.function",regex:"^\\s*```",next:"start"},{token:"support.function",regex:".+"}]}),this.embedRules(o,"jscode-",[{token:"support.function",regex:"^\\s*```",next:"pop"}]),this.embedRules(a,"htmlcode-",[{token:"support.function",regex:"^\\s*```",next:"pop"}]),this.embedRules(f,"csscode-",[{token:"support.function",regex:"^\\s*```",next:"pop"}]),this.embedRules(u,"xmlcode-",[{token:"support.function",regex:"^\\s*```",next:"pop"}]),this.normalizeRules()};r.inherits(h,s),t.MarkdownHighlightRules=h}),ace.define("ace/mode/folding/markdown",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.foldingStartMarker=/^(?:[=-]+\s*$|#{1,6} |`{3})/,this.getFoldWidget=function(e,t,n){var r=e.getLine(n);return this.foldingStartMarker.test(r)?r[0]=="`"?e.bgTokenizer.getState(n)=="start"?"end":"start":"start":""},this.getFoldWidgetRange=function(e,t,n){function l(t){return f=e.getTokens(t)[0],f&&f.type.lastIndexOf(c,0)===0}function h(){var e=f.value[0];return e=="="?6:e=="-"?5:7-f.value.search(/[^#]/)}var r=e.getLine(n),i=r.length,o=e.getLength(),u=n,a=n;if(!r.match(this.foldingStartMarker))return;if(r[0]=="`"){if(e.bgTokenizer.getState(n)!=="start"){while(++n<o){r=e.getLine(n);if(r[0]=="`"&r.substring(0,3)=="```")break}return new s(u,i,n,0)}while(n-->0){r=e.getLine(n);if(r[0]=="`"&r.substring(0,3)=="```")break}return new s(n,r.length,u,0)}var f,c="markup.heading";if(l(n)){var p=h();while(++n<o){if(!l(n))continue;var d=h();if(d>=p)break}a=n-(!f||["=","-"].indexOf(f.value[0])==-1?1:2);if(a>u)while(a>u&&/^\s*$/.test(e.getLine(a)))a--;if(a>u){var v=e.getLine(a).length;return new s(u,i,a,v)}}}}.call(o.prototype)}),ace.define("ace/mode/markdown",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript","ace/mode/xml","ace/mode/html","ace/mode/markdown_highlight_rules","ace/mode/folding/markdown"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript").Mode,o=e("./xml").Mode,u=e("./html").Mode,a=e("./markdown_highlight_rules").MarkdownHighlightRules,f=e("./folding/markdown").FoldMode,l=function(){this.HighlightRules=a,this.createModeDelegates({"js-":s,"xml-":o,"html-":u}),this.foldingRules=new f};r.inherits(l,i),function(){this.type="text",this.blockComment={start:"<!--",end:"-->"},this.getNextLineIndent=function(e,t,n){if(e=="listblock"){var r=/^(\s*)(?:([-+*])|(\d+)\.)(\s+)/.exec(t);if(!r)return"";var i=r[2];return i||(i=parseInt(r[3],10)+1+"."),r[1]+i+r[4]}return this.$getIndent(t)},this.$id="ace/mode/markdown"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-matlab.js b/dist/assets/js/vendor/ace-nc/mode-matlab.js
            new file mode 100644
            index 0000000000..85ead52819
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-matlab.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/matlab_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="break|case|catch|classdef|continue|else|elseif|end|for|function|global|if|otherwise|parfor|persistent|return|spmd|switch|try|while",t="true|false|inf|Inf|nan|NaN|eps|pi|ans|nargin|nargout|varargin|varargout",n="abs|accumarray|acos(?:d|h)?|acot(?:d|h)?|acsc(?:d|h)?|actxcontrol(?:list|select)?|actxGetRunningServer|actxserver|addlistener|addpath|addpref|addtodate|airy|align|alim|all|allchild|alpha|alphamap|amd|ancestor|and|angle|annotation|any|area|arrayfun|asec(?:d|h)?|asin(?:d|h)?|assert|assignin|atan(?:2|d|h)?|audiodevinfo|audioplayer|audiorecorder|aufinfo|auread|autumn|auwrite|avifile|aviinfo|aviread|axes|axis|balance|bar(?:3|3h|h)?|base2dec|beep|BeginInvoke|bench|bessel(?:h|i|j|k|y)|beta|betainc|betaincinv|betaln|bicg|bicgstab|bicgstabl|bin2dec|bitand|bitcmp|bitget|bitmax|bitnot|bitor|bitset|bitshift|bitxor|blanks|blkdiag|bone|box|brighten|brush|bsxfun|builddocsearchdb|builtin|bvp4c|bvp5c|bvpget|bvpinit|bvpset|bvpxtend|calendar|calllib|callSoapService|camdolly|cameratoolbar|camlight|camlookat|camorbit|campan|campos|camproj|camroll|camtarget|camup|camva|camzoom|cart2pol|cart2sph|cast|cat|caxis|cd|cdf2rdf|cdfepoch|cdfinfo|cdflib(?:.(?:close|closeVar|computeEpoch|computeEpoch16|create|createAttr|createVar|delete|deleteAttr|deleteAttrEntry|deleteAttrgEntry|deleteVar|deleteVarRecords|epoch16Breakdown|epochBreakdown|getAttrEntry|getAttrgEntry|getAttrMaxEntry|getAttrMaxgEntry|getAttrName|getAttrNum|getAttrScope|getCacheSize|getChecksum|getCompression|getCompressionCacheSize|getConstantNames|getConstantValue|getCopyright|getFileBackward|getFormat|getLibraryCopyright|getLibraryVersion|getMajority|getName|getNumAttrEntries|getNumAttrgEntries|getNumAttributes|getNumgAttributes|getReadOnlyMode|getStageCacheSize|getValidate|getVarAllocRecords|getVarBlockingFactor|getVarCacheSize|getVarCompression|getVarData|getVarMaxAllocRecNum|getVarMaxWrittenRecNum|getVarName|getVarNum|getVarNumRecsWritten|getVarPadValue|getVarRecordData|getVarReservePercent|getVarsMaxWrittenRecNum|getVarSparseRecords|getVersion|hyperGetVarData|hyperPutVarData|inquire|inquireAttr|inquireAttrEntry|inquireAttrgEntry|inquireVar|open|putAttrEntry|putAttrgEntry|putVarData|putVarRecordData|renameAttr|renameVar|setCacheSize|setChecksum|setCompression|setCompressionCacheSize|setFileBackward|setFormat|setMajority|setReadOnlyMode|setStageCacheSize|setValidate|setVarAllocBlockRecords|setVarBlockingFactor|setVarCacheSize|setVarCompression|setVarInitialRecs|setVarPadValue|SetVarReservePercent|setVarsCacheSize|setVarSparseRecords))?|cdfread|cdfwrite|ceil|cell2mat|cell2struct|celldisp|cellfun|cellplot|cellstr|cgs|checkcode|checkin|checkout|chol|cholinc|cholupdate|circshift|cla|clabel|class|clc|clear|clearvars|clf|clipboard|clock|close|closereq|cmopts|cmpermute|cmunique|colamd|colon|colorbar|colordef|colormap|colormapeditor|colperm|Combine|comet|comet3|commandhistory|commandwindow|compan|compass|complex|computer|cond|condeig|condest|coneplot|conj|containers.Map|contour(?:3|c|f|slice)?|contrast|conv|conv2|convhull|convhulln|convn|cool|copper|copyfile|copyobj|corrcoef|cos(?:d|h)?|cot(?:d|h)?|cov|cplxpair|cputime|createClassFromWsdl|createSoapMessage|cross|csc(?:d|h)?|csvread|csvwrite|ctranspose|cumprod|cumsum|cumtrapz|curl|customverctrl|cylinder|daqread|daspect|datacursormode|datatipinfo|date|datenum|datestr|datetick|datevec|dbclear|dbcont|dbdown|dblquad|dbmex|dbquit|dbstack|dbstatus|dbstep|dbstop|dbtype|dbup|dde23|ddeget|ddesd|ddeset|deal|deblank|dec2base|dec2bin|dec2hex|decic|deconv|del2|delaunay|delaunay3|delaunayn|DelaunayTri|delete|demo|depdir|depfun|det|detrend|deval|diag|dialog|diary|diff|diffuse|dir|disp|display|dither|divergence|dlmread|dlmwrite|dmperm|doc|docsearch|dos|dot|dragrect|drawnow|dsearch|dsearchn|dynamicprops|echo|echodemo|edit|eig|eigs|ellipj|ellipke|ellipsoid|empty|enableNETfromNetworkDrive|enableservice|EndInvoke|enumeration|eomday|eq|erf|erfc|erfcinv|erfcx|erfinv|error|errorbar|errordlg|etime|etree|etreeplot|eval|evalc|evalin|event.(?:EventData|listener|PropertyEvent|proplistener)|exifread|exist|exit|exp|expint|expm|expm1|export2wsdlg|eye|ezcontour|ezcontourf|ezmesh|ezmeshc|ezplot|ezplot3|ezpolar|ezsurf|ezsurfc|factor|factorial|fclose|feather|feature|feof|ferror|feval|fft|fft2|fftn|fftshift|fftw|fgetl|fgets|fieldnames|figure|figurepalette|fileattrib|filebrowser|filemarker|fileparts|fileread|filesep|fill|fill3|filter|filter2|find|findall|findfigs|findobj|findstr|finish|fitsdisp|fitsinfo|fitsread|fitswrite|fix|flag|flipdim|fliplr|flipud|floor|flow|fminbnd|fminsearch|fopen|format|fplot|fprintf|frame2im|fread|freqspace|frewind|fscanf|fseek|ftell|FTP|full|fullfile|func2str|functions|funm|fwrite|fzero|gallery|gamma|gammainc|gammaincinv|gammaln|gca|gcbf|gcbo|gcd|gcf|gco|ge|genpath|genvarname|get|getappdata|getenv|getfield|getframe|getpixelposition|getpref|ginput|gmres|gplot|grabcode|gradient|gray|graymon|grid|griddata(?:3|n)?|griddedInterpolant|gsvd|gt|gtext|guidata|guide|guihandles|gunzip|gzip|h5create|h5disp|h5info|h5read|h5readatt|h5write|h5writeatt|hadamard|handle|hankel|hdf|hdf5|hdf5info|hdf5read|hdf5write|hdfinfo|hdfread|hdftool|help|helpbrowser|helpdesk|helpdlg|helpwin|hess|hex2dec|hex2num|hgexport|hggroup|hgload|hgsave|hgsetget|hgtransform|hidden|hilb|hist|histc|hold|home|horzcat|hostid|hot|hsv|hsv2rgb|hypot|ichol|idivide|ifft|ifft2|ifftn|ifftshift|ilu|im2frame|im2java|imag|image|imagesc|imapprox|imfinfo|imformats|import|importdata|imread|imwrite|ind2rgb|ind2sub|inferiorto|info|inline|inmem|inpolygon|input|inputdlg|inputname|inputParser|inspect|instrcallback|instrfind|instrfindall|int2str|integral(?:2|3)?|interp(?:1|1q|2|3|ft|n)|interpstreamspeed|intersect|intmax|intmin|inv|invhilb|ipermute|isa|isappdata|iscell|iscellstr|ischar|iscolumn|isdir|isempty|isequal|isequaln|isequalwithequalnans|isfield|isfinite|isfloat|isglobal|ishandle|ishghandle|ishold|isinf|isinteger|isjava|iskeyword|isletter|islogical|ismac|ismatrix|ismember|ismethod|isnan|isnumeric|isobject|isocaps|isocolors|isonormals|isosurface|ispc|ispref|isprime|isprop|isreal|isrow|isscalar|issorted|isspace|issparse|isstr|isstrprop|isstruct|isstudent|isunix|isvarname|isvector|javaaddpath|javaArray|javachk|javaclasspath|javacomponent|javaMethod|javaMethodEDT|javaObject|javaObjectEDT|javarmpath|jet|keyboard|kron|lasterr|lasterror|lastwarn|lcm|ldivide|ldl|le|legend|legendre|length|libfunctions|libfunctionsview|libisloaded|libpointer|libstruct|license|light|lightangle|lighting|lin2mu|line|lines|linkaxes|linkdata|linkprop|linsolve|linspace|listdlg|listfonts|load|loadlibrary|loadobj|log|log10|log1p|log2|loglog|logm|logspace|lookfor|lower|ls|lscov|lsqnonneg|lsqr|lt|lu|luinc|magic|makehgtform|mat2cell|mat2str|material|matfile|matlab.io.MatFile|matlab.mixin.(?:Copyable|Heterogeneous(?:.getDefaultScalarElement)?)|matlabrc|matlabroot|max|maxNumCompThreads|mean|median|membrane|memmapfile|memory|menu|mesh|meshc|meshgrid|meshz|meta.(?:class(?:.fromName)?|DynamicProperty|EnumeratedValue|event|MetaData|method|package(?:.(?:fromName|getAllPackages))?|property)|metaclass|methods|methodsview|mex(?:.getCompilerConfigurations)?|MException|mexext|mfilename|min|minres|minus|mislocked|mkdir|mkpp|mldivide|mlint|mlintrpt|mlock|mmfileinfo|mmreader|mod|mode|more|move|movefile|movegui|movie|movie2avi|mpower|mrdivide|msgbox|mtimes|mu2lin|multibandread|multibandwrite|munlock|namelengthmax|nargchk|narginchk|nargoutchk|native2unicode|nccreate|ncdisp|nchoosek|ncinfo|ncread|ncreadatt|ncwrite|ncwriteatt|ncwriteschema|ndgrid|ndims|ne|NET(?:.(?:addAssembly|Assembly|convertArray|createArray|createGeneric|disableAutoRelease|enableAutoRelease|GenericClass|invokeGenericMethod|NetException|setStaticProperty))?|netcdf.(?:abort|close|copyAtt|create|defDim|defGrp|defVar|defVarChunking|defVarDeflate|defVarFill|defVarFletcher32|delAtt|endDef|getAtt|getChunkCache|getConstant|getConstantNames|getVar|inq|inqAtt|inqAttID|inqAttName|inqDim|inqDimID|inqDimIDs|inqFormat|inqGrpName|inqGrpNameFull|inqGrpParent|inqGrps|inqLibVers|inqNcid|inqUnlimDims|inqVar|inqVarChunking|inqVarDeflate|inqVarFill|inqVarFletcher32|inqVarID|inqVarIDs|open|putAtt|putVar|reDef|renameAtt|renameDim|renameVar|setChunkCache|setDefaultFormat|setFill|sync)|newplot|nextpow2|nnz|noanimate|nonzeros|norm|normest|not|notebook|now|nthroot|null|num2cell|num2hex|num2str|numel|nzmax|ode(?:113|15i|15s|23|23s|23t|23tb|45)|odeget|odeset|odextend|onCleanup|ones|open|openfig|opengl|openvar|optimget|optimset|or|ordeig|orderfields|ordqz|ordschur|orient|orth|pack|padecoef|pagesetupdlg|pan|pareto|parseSoapResponse|pascal|patch|path|path2rc|pathsep|pathtool|pause|pbaspect|pcg|pchip|pcode|pcolor|pdepe|pdeval|peaks|perl|perms|permute|pie|pink|pinv|planerot|playshow|plot|plot3|plotbrowser|plotedit|plotmatrix|plottools|plotyy|plus|pol2cart|polar|poly|polyarea|polyder|polyeig|polyfit|polyint|polyval|polyvalm|pow2|power|ppval|prefdir|preferences|primes|print|printdlg|printopt|printpreview|prod|profile|profsave|propedit|propertyeditor|psi|publish|PutCharArray|PutFullMatrix|PutWorkspaceData|pwd|qhull|qmr|qr|qrdelete|qrinsert|qrupdate|quad|quad2d|quadgk|quadl|quadv|questdlg|quit|quiver|quiver3|qz|rand|randi|randn|randperm|RandStream(?:.(?:create|getDefaultStream|getGlobalStream|list|setDefaultStream|setGlobalStream))?|rank|rat|rats|rbbox|rcond|rdivide|readasync|real|reallog|realmax|realmin|realpow|realsqrt|record|rectangle|rectint|recycle|reducepatch|reducevolume|refresh|refreshdata|regexp|regexpi|regexprep|regexptranslate|rehash|rem|Remove|RemoveAll|repmat|reset|reshape|residue|restoredefaultpath|rethrow|rgb2hsv|rgb2ind|rgbplot|ribbon|rmappdata|rmdir|rmfield|rmpath|rmpref|rng|roots|rose|rosser|rot90|rotate|rotate3d|round|rref|rsf2csf|run|save|saveas|saveobj|savepath|scatter|scatter3|schur|sec|secd|sech|selectmoveresize|semilogx|semilogy|sendmail|serial|set|setappdata|setdiff|setenv|setfield|setpixelposition|setpref|setstr|setxor|shading|shg|shiftdim|showplottool|shrinkfaces|sign|sin(?:d|h)?|size|slice|smooth3|snapnow|sort|sortrows|sound|soundsc|spalloc|spaugment|spconvert|spdiags|specular|speye|spfun|sph2cart|sphere|spinmap|spline|spones|spparms|sprand|sprandn|sprandsym|sprank|spring|sprintf|spy|sqrt|sqrtm|squeeze|ss2tf|sscanf|stairs|startup|std|stem|stem3|stopasync|str2double|str2func|str2mat|str2num|strcat|strcmp|strcmpi|stream2|stream3|streamline|streamparticles|streamribbon|streamslice|streamtube|strfind|strjust|strmatch|strncmp|strncmpi|strread|strrep|strtok|strtrim|struct2cell|structfun|strvcat|sub2ind|subplot|subsasgn|subsindex|subspace|subsref|substruct|subvolume|sum|summer|superclasses|superiorto|support|surf|surf2patch|surface|surfc|surfl|surfnorm|svd|svds|swapbytes|symamd|symbfact|symmlq|symrcm|symvar|system|tan(?:d|h)?|tar|tempdir|tempname|tetramesh|texlabel|text|textread|textscan|textwrap|tfqmr|throw|tic|Tiff(?:.(?:getTagNames|getVersion))?|timer|timerfind|timerfindall|times|timeseries|title|toc|todatenum|toeplitz|toolboxdir|trace|transpose|trapz|treelayout|treeplot|tril|trimesh|triplequad|triplot|TriRep|TriScatteredInterp|trisurf|triu|tscollection|tsearch|tsearchn|tstool|type|typecast|uibuttongroup|uicontextmenu|uicontrol|uigetdir|uigetfile|uigetpref|uiimport|uimenu|uiopen|uipanel|uipushtool|uiputfile|uiresume|uisave|uisetcolor|uisetfont|uisetpref|uistack|uitable|uitoggletool|uitoolbar|uiwait|uminus|undocheckout|unicode2native|union|unique|unix|unloadlibrary|unmesh|unmkpp|untar|unwrap|unzip|uplus|upper|urlread|urlwrite|usejava|userpath|validateattributes|validatestring|vander|var|vectorize|ver|verctrl|verLessThan|version|vertcat|VideoReader(?:.isPlatformSupported)?|VideoWriter(?:.getProfiles)?|view|viewmtx|visdiff|volumebounds|voronoi|voronoin|wait|waitbar|waitfor|waitforbuttonpress|warndlg|warning|waterfall|wavfinfo|wavplay|wavread|wavrecord|wavwrite|web|weekday|what|whatsnew|which|whitebg|who|whos|wilkinson|winopen|winqueryreg|winter|wk1finfo|wk1read|wk1write|workspace|xlabel|xlim|xlsfinfo|xlsread|xlswrite|xmlread|xmlwrite|xor|xslt|ylabel|ylim|zeros|zip|zlabel|zlim|zoom|addedvarplot|andrewsplot|anova(?:1|2|n)|ansaribradley|aoctool|barttest|bbdesign|beta(?:cdf|fit|inv|like|pdf|rnd|stat)|bino(?:cdf|fit|inv|pdf|rnd|stat)|biplot|bootci|bootstrp|boxplot|candexch|candgen|canoncorr|capability|capaplot|caseread|casewrite|categorical|ccdesign|cdfplot|chi2(?:cdf|gof|inv|pdf|rnd|stat)|cholcov|Classification(?:BaggedEnsemble|Discriminant(?:.(?:fit|make|template))?|Ensemble|KNN(?:.(?:fit|template))?|PartitionedEnsemble|PartitionedModel|Tree(?:.(?:fit|template))?)|classify|classregtree|cluster|clusterdata|cmdscale|combnk|Compact(?:Classification(?:Discriminant|Ensemble|Tree)|Regression(?:Ensemble|Tree)|TreeBagger)|confusionmat|controlchart|controlrules|cophenet|copula(?:cdf|fit|param|pdf|rnd|stat)|cordexch|corr|corrcov|coxphfit|createns|crosstab|crossval|cvpartition|datasample|dataset|daugment|dcovary|dendrogram|dfittool|disttool|dummyvar|dwtest|ecdf|ecdfhist|ev(?:cdf|fit|inv|like|pdf|rnd|stat)|ExhaustiveSearcher|exp(?:cdf|fit|inv|like|pdf|rnd|stat)|factoran|fcdf|ff2n|finv|fitdist|fitensemble|fpdf|fracfact|fracfactgen|friedman|frnd|fstat|fsurfht|fullfact|gagerr|gam(?:cdf|fit|inv|like|pdf|rnd|stat)|GeneralizedLinearModel(?:.fit)?|geo(?:cdf|inv|mean|pdf|rnd|stat)|gev(?:cdf|fit|inv|like|pdf|rnd|stat)|gline|glmfit|glmval|glyphplot|gmdistribution(?:.fit)?|gname|gp(?:cdf|fit|inv|like|pdf|rnd|stat)|gplotmatrix|grp2idx|grpstats|gscatter|haltonset|harmmean|hist3|histfit|hmm(?:decode|estimate|generate|train|viterbi)|hougen|hyge(?:cdf|inv|pdf|rnd|stat)|icdf|inconsistent|interactionplot|invpred|iqr|iwishrnd|jackknife|jbtest|johnsrnd|KDTreeSearcher|kmeans|knnsearch|kruskalwallis|ksdensity|kstest|kstest2|kurtosis|lasso|lassoglm|lassoPlot|leverage|lhsdesign|lhsnorm|lillietest|LinearModel(?:.fit)?|linhyptest|linkage|logn(?:cdf|fit|inv|like|pdf|rnd|stat)|lsline|mad|mahal|maineffectsplot|manova1|manovacluster|mdscale|mhsample|mle|mlecov|mnpdf|mnrfit|mnrnd|mnrval|moment|multcompare|multivarichart|mvn(?:cdf|pdf|rnd)|mvregress|mvregresslike|mvt(?:cdf|pdf|rnd)|NaiveBayes(?:.fit)?|nan(?:cov|max|mean|median|min|std|sum|var)|nbin(?:cdf|fit|inv|pdf|rnd|stat)|ncf(?:cdf|inv|pdf|rnd|stat)|nct(?:cdf|inv|pdf|rnd|stat)|ncx2(?:cdf|inv|pdf|rnd|stat)|NeighborSearcher|nlinfit|nlintool|nlmefit|nlmefitsa|nlparci|nlpredci|nnmf|nominal|NonLinearModel(?:.fit)?|norm(?:cdf|fit|inv|like|pdf|rnd|stat)|normplot|normspec|ordinal|outlierMeasure|parallelcoords|paretotails|partialcorr|pcacov|pcares|pdf|pdist|pdist2|pearsrnd|perfcurve|perms|piecewisedistribution|plsregress|poiss(?:cdf|fit|inv|pdf|rnd|tat)|polyconf|polytool|prctile|princomp|ProbDist(?:Kernel|Parametric|UnivKernel|UnivParam)?|probplot|procrustes|qqplot|qrandset|qrandstream|quantile|randg|random|randsample|randtool|range|rangesearch|ranksum|rayl(?:cdf|fit|inv|pdf|rnd|stat)|rcoplot|refcurve|refline|regress|Regression(?:BaggedEnsemble|Ensemble|PartitionedEnsemble|PartitionedModel|Tree(?:.(?:fit|template))?)|regstats|relieff|ridge|robustdemo|robustfit|rotatefactors|rowexch|rsmdemo|rstool|runstest|sampsizepwr|scatterhist|sequentialfs|signrank|signtest|silhouette|skewness|slicesample|sobolset|squareform|statget|statset|stepwise|stepwisefit|surfht|tabulate|tblread|tblwrite|tcdf|tdfread|tiedrank|tinv|tpdf|TreeBagger|treedisp|treefit|treeprune|treetest|treeval|trimmean|trnd|tstat|ttest|ttest2|unid(?:cdf|inv|pdf|rnd|stat)|unif(?:cdf|inv|it|pdf|rnd|stat)|vartest(?:2|n)?|wbl(?:cdf|fit|inv|like|pdf|rnd|stat)|wblplot|wishrnd|x2fx|xptread|zscore|ztestadapthisteq|analyze75info|analyze75read|applycform|applylut|axes2pix|bestblk|blockproc|bwarea|bwareaopen|bwboundaries|bwconncomp|bwconvhull|bwdist|bwdistgeodesic|bweuler|bwhitmiss|bwlabel|bwlabeln|bwmorph|bwpack|bwperim|bwselect|bwtraceboundary|bwulterode|bwunpack|checkerboard|col2im|colfilt|conndef|convmtx2|corner|cornermetric|corr2|cp2tform|cpcorr|cpselect|cpstruct2pairs|dct2|dctmtx|deconvblind|deconvlucy|deconvreg|deconvwnr|decorrstretch|demosaic|dicom(?:anon|dict|info|lookup|read|uid|write)|edge|edgetaper|entropy|entropyfilt|fan2para|fanbeam|findbounds|fliptform|freqz2|fsamp2|fspecial|ftrans2|fwind1|fwind2|getheight|getimage|getimagemodel|getline|getneighbors|getnhood|getpts|getrangefromclass|getrect|getsequence|gray2ind|graycomatrix|graycoprops|graydist|grayslice|graythresh|hdrread|hdrwrite|histeq|hough|houghlines|houghpeaks|iccfind|iccread|iccroot|iccwrite|idct2|ifanbeam|im2bw|im2col|im2double|im2int16|im2java2d|im2single|im2uint16|im2uint8|imabsdiff|imadd|imadjust|ImageAdapter|imageinfo|imagemodel|imapplymatrix|imattributes|imbothat|imclearborder|imclose|imcolormaptool|imcomplement|imcontour|imcontrast|imcrop|imdilate|imdisplayrange|imdistline|imdivide|imellipse|imerode|imextendedmax|imextendedmin|imfill|imfilter|imfindcircles|imfreehand|imfuse|imgca|imgcf|imgetfile|imhandles|imhist|imhmax|imhmin|imimposemin|imlincomb|imline|immagbox|immovie|immultiply|imnoise|imopen|imoverview|imoverviewpanel|impixel|impixelinfo|impixelinfoval|impixelregion|impixelregionpanel|implay|impoint|impoly|impositionrect|improfile|imputfile|impyramid|imreconstruct|imrect|imregconfig|imregionalmax|imregionalmin|imregister|imresize|imroi|imrotate|imsave|imscrollpanel|imshow|imshowpair|imsubtract|imtool|imtophat|imtransform|imview|ind2gray|ind2rgb|interfileinfo|interfileread|intlut|ippl|iptaddcallback|iptcheckconn|iptcheckhandle|iptcheckinput|iptcheckmap|iptchecknargin|iptcheckstrs|iptdemos|iptgetapi|iptGetPointerBehavior|iptgetpref|ipticondir|iptnum2ordinal|iptPointerManager|iptprefs|iptremovecallback|iptSetPointerBehavior|iptsetpref|iptwindowalign|iradon|isbw|isflat|isgray|isicc|isind|isnitf|isrgb|isrset|lab2double|lab2uint16|lab2uint8|label2rgb|labelmatrix|makecform|makeConstrainToRectFcn|makehdr|makelut|makeresampler|maketform|mat2gray|mean2|medfilt2|montage|nitfinfo|nitfread|nlfilter|normxcorr2|ntsc2rgb|openrset|ordfilt2|otf2psf|padarray|para2fan|phantom|poly2mask|psf2otf|qtdecomp|qtgetblk|qtsetblk|radon|rangefilt|reflect|regionprops|registration.metric.(?:MattesMutualInformation|MeanSquares)|registration.optimizer.(?:OnePlusOneEvolutionary|RegularStepGradientDescent)|rgb2gray|rgb2ntsc|rgb2ycbcr|roicolor|roifill|roifilt2|roipoly|rsetwrite|std2|stdfilt|strel|stretchlim|subimage|tformarray|tformfwd|tforminv|tonemap|translate|truesize|uintlut|viscircles|warp|watershed|whitepoint|wiener2|xyz2double|xyz2uint16|ycbcr2rgb|bintprog|color|fgoalattain|fminbnd|fmincon|fminimax|fminsearch|fminunc|fseminf|fsolve|fzero|fzmult|gangstr|ktrlink|linprog|lsqcurvefit|lsqlin|lsqnonlin|lsqnonneg|optimget|optimset|optimtool|quadprog",r="cell|struct|char|double|single|logical|u?int(?:8|16|32|64)|sparse",i=this.createKeywordMapper({"storage.type":r,"support.function":n,keyword:e,"constant.language":t},"identifier",!0);this.$rules={start:[{token:"comment",regex:"%[^\r\n]*"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]}};r.inherits(s,i),t.MatlabHighlightRules=s}),ace.define("ace/mode/matlab",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/matlab_highlight_rules","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./matlab_highlight_rules").MatlabHighlightRules,o=e("../range").Range,u=function(){this.HighlightRules=s};r.inherits(u,i),function(){this.lineCommentStart="%",this.blockComment={start:"%{",end:"%}"},this.$id="ace/mode/matlab"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-mel.js b/dist/assets/js/vendor/ace-nc/mode-mel.js
            new file mode 100644
            index 0000000000..34b707ac47
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-mel.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/mel_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{caseInsensitive:!0,token:"storage.type.mel",regex:"\\b(matrix|string|vector|float|int|void)\\b"},{caseInsensitive:!0,token:"support.function.mel",regex:"\\b((s(h(ow(ManipCtx|S(hadingGroupAttrEditor|electionInTitle)|H(idden|elp)|Window)|el(f(Button|TabLayout|Layout)|lField)|ading(GeometryRelCtx|Node|Connection|LightRelCtx))|y(s(tem|File)|mbol(Button|CheckBox))|nap(shot|Mode|2to2 |TogetherCtx|Key)|c(ulpt|ene(UIReplacement|Editor)|ale(BrushBrightness |Constraint|Key(Ctx)?)?|r(ipt(Node|Ctx|Table|edPanel(Type)?|Job|EditorInfo)|oll(Field|Layout))|mh)|t(itch(Surface(Points)?|AndExplodeShell )|a(ckTrace|rt(sWith |String ))|r(cmp|i(ng(ToStringArray |Array(Remove(Duplicates | )|C(ount |atenate )|ToString |Intersector))|p )|oke))|i(n(gleProfileBirailSurface)?|ze|gn|mplify)|o(u(nd(Control)?|rce)|ft(Mod(Ctx)?)?|rt)|u(perCtx|rface(S(haderList|ampler))?|b(st(itute(Geometry|AllString )?|ring)|d(M(irror|a(tchTopology|p(SewMove|Cut)))|iv(Crease|DisplaySmoothness)?|C(ollapse|leanTopology)|T(o(Blind|Poly)|ransferUVsToCache)|DuplicateAndConnect|EditUV|ListComponentConversion|AutoProjection)))|p(h(ere|rand)|otLight(PreviewPort)?|aceLocator|r(ing|eadSheetEditor))|e(t(s|MenuMode|Sta(te |rtupMessage|mpDensity )|NodeTypeFlag|ConstraintRestPosition |ToolTo|In(putDeviceMapping|finity)|D(ynamic|efaultShadingGroup|rivenKeyframe)|UITemplate|P(ar(ticleAttr|ent)|roject )|E(scapeCtx|dit(or|Ctx))|Key(Ctx|frame|Path)|F(ocus|luidAttr)|Attr(Mapping)?)|parator|ed|l(ect(Mode|ionConnection|Context|Type|edNodes|Pr(iority|ef)|Key(Ctx)?)?|LoadSettings)|archPathArray )|kin(Cluster|Percent)|q(uareSurface|rt)|w(itchTable|atchDisplayPort)|a(ve(Menu|Shelf|ToolSettings|I(nitialState|mage)|Pref(s|Objects)|Fluid|A(ttrPreset |llShelves))|mpleImage)|rtContext|mooth(step|Curve|TangentSurface))|h(sv_to_rgb|yp(ot|er(Graph|Shade|Panel))|i(tTest|de|lite)|ot(Box|key(Check)?)|ud(Button|Slider(Button)?)|e(lp(Line)?|adsUpDisplay|rmite)|wRe(nder(Load)?|flectionMap)|ard(enPointCurve|ware(RenderPanel)?))|n(o(nLinear|ise|de(Type|IconButton|Outliner|Preset)|rmal(ize |Constraint))|urbs(Boolean|S(elect|quare)|C(opyUVSet|ube)|To(Subdiv|Poly(gonsPref)?)|Plane|ViewDirectionVector )|ew(ton|PanelItems)|ame(space(Info)?|Command|Field))|c(h(oice|dir|eck(Box(Grp)?|DefaultRenderGlobals)|a(n(nelBox|geSubdiv(Region|ComponentDisplayLevel))|racter(Map|OutlineEditor)?))|y(cleCheck|linder)|tx(Completion|Traverse|EditMode|Abort)|irc(ularFillet|le)|o(s|n(str(uctionHistory|ain(Value)?)|nect(ionInfo|Control|Dynamic|Joint|Attr)|t(extInfo|rol)|dition|e|vert(SolidTx|Tessellation|Unit|FromOldLayers |Lightmap)|firmDialog)|py(SkinWeights|Key|Flexor|Array )|l(or(Slider(Grp|ButtonGrp)|Index(SliderGrp)?|Editor|AtPoint)?|umnLayout|lision)|arsenSubdivSelectionList|m(p(onentEditor|utePolysetVolume |actHairSystem )|mand(Port|Echo|Line)))|u(tKey|r(ve(MoveEPCtx|SketchCtx|CVCtx|Intersect|OnSurface|E(ditorCtx|PCtx)|AddPtCtx)?|rent(Ctx|Time(Ctx)?|Unit)))|p(GetSolverAttr|Button|S(olver(Types)?|e(t(SolverAttr|Edit)|am))|C(o(nstraint|llision)|ache)|Tool|P(anel|roperty))|eil|l(ip(Schedule(rOutliner)?|TrimBefore |Editor(CurrentTimeCtx)?)?|ose(Surface|Curve)|uster|ear(Cache)?|amp)|a(n(CreateManip|vas)|tch(Quiet)?|pitalizeString |mera(View)?)|r(oss(Product )?|eate(RenderLayer|MotionField |SubdivRegion|N(ode|ewShelf )|D(isplayLayer|rawCtx)|Editor))|md(Shell|FileOutput))|M(R(ender(ShadowData|Callback|Data|Util|View|Line(Array)?)|ampAttribute)|G(eometryData|lobal)|M(odelMessage|essage|a(nipData|t(erial|rix)))|BoundingBox|S(yntax|ceneMessage|t(atus|ring(Array)?)|imple|pace|elect(ion(Mask|List)|Info)|watchRender(Register|Base))|H(ardwareRenderer|WShaderSwatchGenerator)|NodeMessage|C(o(nditionMessage|lor(Array)?|m(putation|mand(Result|Message)))|ursor|loth(Material|S(ystem|olverRegister)|Con(straint|trol)|Triangle|Particle|Edge|Force)|allbackIdArray)|T(ypeId|ime(r(Message)?|Array)?|oolsInfo|esselationParams|r(imBoundaryArray|ansformationMatrix))|I(ntArray|t(Geometry|Mesh(Polygon|Edge|Vertex|FaceVertex)|S(urfaceCV|electionList)|CurveCV|Instancer|eratorType|D(ependency(Graph|Nodes)|ag)|Keyframe)|k(System|HandleGroup)|mage)|3dView|Object(SetMessage|Handle|Array)?|D(G(M(odifier|essage)|Context)|ynSwept(Triangle|Line)|istance|oubleArray|evice(State|Channel)|a(ta(Block|Handle)|g(M(odifier|essage)|Path(Array)?))|raw(Request(Queue)?|Info|Data|ProcedureBase))|U(serEventMessage|i(nt(Array|64Array)|Message))|P(o(int(Array)?|lyMessage)|lug(Array)?|rogressWindow|x(G(eometry(Iterator|Data)|lBuffer)|M(idiInputDevice|odelEditorCommand|anipContainer)|S(urfaceShape(UI)?|pringNode|electionContext)|HwShaderNode|Node|Co(ntext(Command)?|m(ponentShape|mand))|T(oolCommand|ransform(ationMatrix)?)|IkSolver(Node)?|3dModelView|ObjectSet|D(eformerNode|ata|ragAndDropBehavior)|PolyT(weakUVCommand|rg)|EmitterNode|F(i(eldNode|leTranslator)|luidEmitterNode)|LocatorNode))|E(ulerRotation|vent(Message)?)|ayatomr|Vector(Array)?|Quaternion|F(n(R(otateManip|eflectShader|adialField)|G(e(nericAttribute|ometry(Data|Filter))|ravityField)|M(otionPath|es(sageAttribute|h(Data)?)|a(nip3D|trix(Data|Attribute)))|B(l(innShader|endShapeDeformer)|ase)|S(caleManip|t(ateManip|ring(Data|ArrayData))|ingleIndexedComponent|ubd(Names|Data)?|p(hereData|otLight)|et|kinCluster)|HikEffector|N(on(ExtendedLight|AmbientLight)|u(rbs(Surface(Data)?|Curve(Data)?)|meric(Data|Attribute))|ewtonField)|C(haracter|ircleSweepManip|ompo(nent(ListData)?|undAttribute)|urveSegmentManip|lip|amera)|T(ypedAttribute|oggleManip|urbulenceField|r(ipleIndexedComponent|ansform))|I(ntArrayData|k(Solver|Handle|Joint|Effector))|D(ynSweptGeometryData|i(s(cManip|tanceManip)|rection(Manip|alLight))|ouble(IndexedComponent|ArrayData)|ependencyNode|a(ta|gNode)|ragField)|U(ni(tAttribute|formField)|Int64ArrayData)|P(hong(Shader|EShader)|oint(On(SurfaceManip|CurveManip)|Light|ArrayData)|fxGeometry|lugin(Data)?|arti(cleSystem|tion))|E(numAttribute|xpression)|V(o(lume(Light|AxisField)|rtexField)|ectorArrayData)|KeyframeDelta(Move|B(lockAddRemove|reakdown)|Scale|Tangent|InfType|Weighted|AddRemove)?|F(ield|luid|reePointTriadManip)|W(ireDeformer|eightGeometryFilter)|L(ight(DataAttribute)?|a(yeredShader|ttice(D(eformer|ata))?|mbertShader))|A(ni(sotropyShader|mCurve)|ttribute|irField|r(eaLight|rayAttrsData)|mbientLight))?|ile(IO|Object)|eedbackLine|loat(Matrix|Point(Array)?|Vector(Array)?|Array))|L(i(ghtLinks|brary)|ockMessage)|A(n(im(Message|C(ontrol|urveC(hange|lipboard(Item(Array)?)?))|Util)|gle)|ttribute(Spec(Array)?|Index)|r(rayData(Builder|Handle)|g(Database|Parser|List))))|t(hreePointArcCtx|ime(Control|Port|rX)|o(ol(Button|HasOptions|Collection|Dropped|PropertyWindow)|NativePath |upper|kenize(List )?|l(ower|erance)|rus|ggle(WindowVisibility|Axis)?)|u(rbulence|mble(Ctx)?)|ex(RotateContext|M(oveContext|anipContext)|t(ScrollList|Curves|ure(HairColor |DisplacePlane |PlacementContext|Window)|ToShelf |Field(Grp|ButtonGrp)?)?|S(caleContext|electContext|mudgeUVContext)|WinToolCtx)|woPointArcCtx|a(n(gentConstraint)?|bLayout)|r(im|unc(ate(HairCache|FluidCache))?|a(ns(formLimits|lator)|c(e|k(Ctx)?))))|i(s(olateSelect|Connected|True|Dirty|ParentOf |Valid(String |ObjectName |UiName )|AnimCurve )|n(s(tance(r)?|ert(Joint(Ctx)?|K(not(Surface|Curve)|eyCtx)))|heritTransform|t(S(crollBar|lider(Grp)?)|er(sect|nalVar|ToUI )|Field(Grp)?))|conText(Radio(Button|Collection)|Button|StaticLabel|CheckBox)|temFilter(Render|Type|Attr)?|prEngine|k(S(ystem(Info)?|olver|plineHandleCtx)|Handle(Ctx|DisplayScale)?|fkDisplayMethod)|m(portComposerCurves |fPlugins|age))|o(ceanNurbsPreviewPlane |utliner(Panel|Editor)|p(tion(Menu(Grp)?|Var)|en(GLExtension|MayaPref))|verrideModifier|ffset(Surface|Curve(OnSurface)?)|r(ientConstraint|bit(Ctx)?)|b(soleteProc |j(ect(Center|Type(UI)?|Layer )|Exists)))|d(yn(RelEd(itor|Panel)|Globals|C(ontrol|ache)|P(a(intEditor|rticleCtx)|ref)|Exp(ort|ression)|amicLoad)|i(s(connect(Joint|Attr)|tanceDim(Context|ension)|pla(y(RGBColor|S(tats|urface|moothness)|C(olor|ull)|Pref|LevelOfDetail|Affected)|cementToPoly)|kCache|able)|r(name |ect(ionalLight|KeyCtx)|map)|mWhen)|o(cServer|Blur|t(Product )?|ubleProfileBirailSurface|peSheetEditor|lly(Ctx)?)|uplicate(Surface|Curve)?|e(tach(Surface|Curve|DeviceAttr)|vice(Panel|Editor)|f(ine(DataServer|VirtualDevice)|ormer|ault(Navigation|LightListCheckBox))|l(ete(Sh(elfTab |adingGroupsAndMaterials )|U(nusedBrushes |I)|Attr)?|randstr)|g_to_rad)|agPose|r(opoffLocator|ag(gerContext)?)|g(timer|dirty|Info|eval))|CBG |u(serCtx|n(t(angleUV|rim)|i(t|form)|do(Info)?|loadPlugin|assignInputDevice|group)|iTemplate|p(dateAE |Axis)|v(Snapshot|Link))|joint(C(tx|luster)|DisplayScale|Lattice)?|p(sd(ChannelOutliner|TextureFile|E(ditTextureFile|xport))|close|i(c(ture|kWalk)|xelMove)|o(se|int(MatrixMult |C(onstraint|urveConstraint)|On(Surface|Curve)|Position|Light)|p(upMenu|en)|w|l(y(Reduce|GeoSampler|M(irrorFace|ove(UV|Edge|Vertex|Facet(UV)?)|erge(UV|Edge(Ctx)?|Vertex|Facet(Ctx)?)|ap(Sew(Move)?|Cut|Del))|B(oolOp|evel|l(indData|endColor))|S(traightenUVBorder|oftEdge|u(perCtx|bdivide(Edge|Facet))|p(her(icalProjection|e)|lit(Ring|Ctx|Edge|Vertex)?)|e(tToFaceNormal|parate|wEdge|lect(Constraint(Monitor)?|EditCtx))|mooth)|Normal(izeUV|PerVertex)?|C(hipOff|ylind(er|ricalProjection)|o(ne|pyUV|l(or(BlindData|Set|PerVertex)|lapse(Edge|Facet)))|u(t(Ctx)?|be)|l(ipboard|oseBorder)|acheMonitor|rea(seEdge|teFacet(Ctx)?))|T(o(Subdiv|rus)|r(iangulate|ansfer))|In(stallAction|fo)|Options|D(uplicate(Edge|AndConnect)|el(Edge|Vertex|Facet))|U(nite|VSet)|P(yramid|oke|lan(e|arProjection)|r(ism|ojection))|E(ditUV|valuate|xtrude(Edge|Facet))|Qu(eryBlindData|ad)|F(orceUV|lip(UV|Edge))|WedgeFace|L(istComponentConversion|ayoutUV)|A(utoProjection|ppend(Vertex|FacetCtx)?|verage(Normal|Vertex)))|eVectorConstraint))|utenv|er(cent|formanceOptions)|fxstrokes|wd|l(uginInfo|a(y(b(last|ackOptions))?|n(e|arSrf)))|a(steKey|ne(l(History|Configuration)?|Layout)|thAnimation|irBlend|use|lettePort|r(ti(cle(RenderInfo|Instancer|Exists)?|tion)|ent(Constraint)?|am(Dim(Context|ension)|Locator)))|r(int|o(j(ect(ion(Manip|Context)|Curve|Tangent)|FileViewer)|pMo(dCtx|ve)|gress(Bar|Window)|mptDialog)|eloadRefEd))|e(n(codeString|d(sWith |String )|v|ableDevice)|dit(RenderLayer(Globals|Members)|or(Template)?|DisplayLayer(Globals|Members)|AttrLimits )|v(ent|al(Deferred|Echo)?)|quivalent(Tol | )|ffector|r(f|ror)|x(clusiveLightCheckBox|t(end(Surface|Curve)|rude)|ists|p(ortComposerCurves |ression(EditorListen)?)?|ec(uteForEachObject )?|actWorldBoundingBox)|mit(ter)?)|v(i(sor|ew(Set|HeadOn|2dToolCtx|C(lipPlane|amera)|Place|Fit|LookAt))|o(lumeAxis|rtex)|e(ctorize|rifyCmd )|alidateShelfName )|key(Tangent|frame(Region(MoveKeyCtx|S(caleKeyCtx|e(tKeyCtx|lectKeyCtx))|CurrentTimeCtx|TrackCtx|InsertKeyCtx|D(irectKeyCtx|ollyCtx))|Stats|Outliner)?)|qu(it|erySubdiv)|f(c(heck|lose)|i(nd(RelatedSkinCluster |MenuItem |er|Keyframe|AllIntersections )|tBspline|l(ter(StudioImport|Curve|Expand)?|e(BrowserDialog|test|Info|Dialog|Extension )?|letCurve)|rstParentOf )|o(ntDialog|pen|rmLayout)|print|eof|flush|write|l(o(or|w|at(S(crollBar|lider(Grp|ButtonGrp|2)?)|Eq |Field(Grp)?))|u(shUndo|id(CacheInfo|Emitter|VoxelInfo))|exor)|r(omNativePath |e(eFormFillet|wind|ad)|ameLayout)|get(word|line)|mod)|w(hatIs|i(ndow(Pref)?|re(Context)?)|orkspace|ebBrowser(Prefs)?|a(itCursor|rning)|ri(nkle(Context)?|teTake))|l(s(T(hroughFilter|ype )|UI)?|i(st(Relatives|MenuAnnotation |Sets|History|NodeTypes|C(onnections|ameras)|Transforms |InputDevice(s|Buttons|Axes)|erEditor|DeviceAttachments|Unselected |A(nimatable|ttr))|n(step|eIntersection )|ght(link|List(Panel|Editor)?))|o(ckNode|okThru|ft|ad(NewShelf |P(lugin|refObjects)|Fluid)|g)|a(ssoContext|y(out|er(Button|ed(ShaderPort|TexturePort)))|ttice(DeformKeyCtx)?|unch(ImageEditor)?))|a(ssign(Command|InputDevice)|n(notate|im(C(one|urveEditor)|Display|View)|gle(Between)?)|tt(ach(Surface|Curve|DeviceAttr)|r(ibute(Menu|Info|Exists|Query)|NavigationControlGrp|Co(ntrolGrp|lorSliderGrp|mpatibility)|PresetEditWin|EnumOptionMenu(Grp)?|Field(Grp|SliderGrp)))|i(r|mConstraint)|d(d(NewShelfTab|Dynamic|PP|Attr(ibuteEditorNodeHelp)?)|vanceToNextDrivenKey)|uto(Place|Keyframe)|pp(endStringArray|l(y(Take|AttrPreset)|icationName))|ffect(s|edNet)|l(i(as(Attr)?|gn(Surface|C(tx|urve))?)|lViewFit)|r(c(len|Len(DimContext|gthDimension))|t(BuildPaintMenu|Se(tPaintCtx|lectCtx)|3dPaintCtx|UserPaintCtx|PuttyCtx|FluidAttrCtx|Attr(SkinPaintCtx|Ctx|PaintVertexCtx))|rayMapper)|mbientLight|b(s|out))|r(igid(Body|Solver)|o(t(at(ionInterpolation|e))?|otOf |undConstantRadius|w(ColumnLayout|Layout)|ll(Ctx)?)|un(up|TimeCommand)|e(s(olutionNode|et(Tool|AE )|ampleFluid)|hash|n(der(GlobalsNode|Manip|ThumbnailUpdate|Info|er|Partition|QualityNode|Window(SelectContext|Editor)|LayerButton)?|ame(SelectionList |UI|Attr)?)|cord(Device|Attr)|target|order(Deformers)?|do|v(olve|erse(Surface|Curve))|quires|f(ineSubdivSelectionList|erence(Edit|Query)?|resh(AE )?)|loadImage|adTake|root|move(MultiInstance|Joint)|build(Surface|Curve))|a(n(d(state|omizeFollicles )?|geControl)|d(i(o(MenuItemCollection|Button(Grp)?|Collection)|al)|_to_deg)|mpColorPort)|gb_to_hsv)|g(o(toBindPose |al)|e(t(M(odifiers|ayaPanelTypes )|Classification|InputDeviceRange|pid|env|DefaultBrush|Pa(nel|rticleAttr)|F(ileList|luidAttr)|A(ttr|pplicationVersionAsFloat ))|ometryConstraint)|l(Render(Editor)?|obalStitch)|a(uss|mma)|r(id(Layout)?|oup(ObjectsByName )?|a(dientControl(NoAttr)?|ph(SelectContext|TrackCtx|DollyCtx)|vity|bColor))|match)|x(pmPicker|form|bmLangPathList )|m(i(n(imizeApp)?|rrorJoint)|o(del(CurrentTimeCtx|Panel|Editor)|use|v(In|e(IKtoFK |VertexAlongDirection|KeyCtx)?|Out))|u(te|ltiProfileBirailSurface)|e(ssageLine|nu(BarLayout|Item(ToShelf )?|Editor)?|mory)|a(nip(Rotate(Context|LimitsCtx)|Move(Context|LimitsCtx)|Scale(Context|LimitsCtx)|Options)|tch|ke(Roll |SingleSurface|TubeOn |Identity|Paintable|bot|Live)|rker|g|x))|b(in(Membership|d(Skin|Pose))|o(neLattice|undary|x(ZoomCtx|DollyCtx))|u(tton(Manip)?|ild(BookmarkMenu|KeyframeMenu)|fferCurve)|e(ssel|vel(Plus)?)|l(indDataType|end(Shape(Panel|Editor)?|2|TwoAttr))|a(sename(Ex | )|tchRender|ke(Results|Simulation|Clip|PartialHistory|FluidShading )))))\\b"},{caseInsensitive:!0,token:"support.constant.mel",regex:"\\b(s(h(ellTessellate|a(d(ing(Map|Engine)|erGlow)|pe))|n(ow|apshot(Shape)?)|c(ulpt|aleConstraint|ript)|t(yleCurve|itch(Srf|AsNurbsShell)|u(cco|dioClearCoat)|encil|roke(Globals)?)|i(ngleShadingSwitch|mpleVolumeShader)|o(ftMod(Manip|Handle)?|lidFractal)|u(rface(Sha(der|pe)|Info|EdManip|VarGroup|Luminance)|b(Surface|d(M(odifier(UV|World)?|ap(SewMove|Cut|pingManip))|B(lindData|ase)|iv(ReverseFaces|SurfaceVarGroup|Co(llapse|mponentId)|To(Nurbs|Poly))?|HierBlind|CleanTopology|Tweak(UV)?|P(lanarProj|rojManip)|LayoutUV|A(ddTopology|utoProj))|Curve))|p(BirailSrf|otLight|ring)|e(tRange|lectionListOperator)|k(inCluster|etchPlane)|quareSrf|ampler(Info)?|m(ooth(Curve|TangentSrf)|ear))|h(svToRgb|yper(GraphInfo|View|Layout)|ik(Solver|Handle|Effector)|oldMatrix|eightField|w(Re(nderGlobals|flectionMap)|Shader)|a(ir(System|Constraint|TubeShader)|rd(enPoint|wareRenderGlobals)))|n(o(n(ExtendedLightShapeNode|Linear|AmbientLightShapeNode)|ise|rmalConstraint)|urbs(Surface|Curve|T(oSubdiv(Proc)?|essellate)|DimShape)|e(twork|wtonField))|c(h(o(ice|oser)|ecker|aracter(Map|Offset)?)|o(n(straint|tr(olPoint|ast)|dition)|py(ColorSet|UVSet))|urve(Range|Shape|Normalizer(Linear|Angle)?|In(tersect|fo)|VarGroup|From(Mesh(CoM|Edge)?|Su(rface(Bnd|CoS|Iso)?|bdiv(Edge|Face)?)))|l(ip(Scheduler|Library)|o(se(stPointOnSurface|Surface|Curve)|th|ud)|uster(Handle)?|amp)|amera(View)?|r(eate(BPManip|ColorSet|UVSet)|ater))|t(ime(ToUnitConversion|Function)?|oo(nLineAttributes|lDrawManip)|urbulenceField|ex(BaseDeformManip|ture(BakeSet|2d|ToGeom|3d|Env)|SmudgeUVManip|LatticeDeformManip)|weak|angentConstraint|r(i(pleShadingSwitch|m(WithBoundaries)?)|ansform(Geometry)?))|i(n(s(tancer|ertKnot(Surface|Curve))|tersectSurface)|k(RPsolver|MCsolver|S(ystem|olver|Csolver|plineSolver)|Handle|PASolver|Effector)|m(plicit(Box|Sphere|Cone)|agePlane))|o(cean(Shader)?|pticalFX|ffset(Surface|C(os|urve))|ldBlindDataBase|rient(Constraint|ationMarker)|bject(RenderFilter|MultiFilter|BinFilter|S(criptFilter|et)|NameFilter|TypeFilter|Filter|AttrFilter))|d(yn(Globals|Base)|i(s(tance(Between|DimShape)|pla(yLayer(Manager)?|cementShader)|kCache)|rect(ionalLight|edDisc)|mensionShape)|o(ubleShadingSwitch|f)|pBirailSrf|e(tach(Surface|Curve)|pendNode|f(orm(Bend|S(ine|quash)|Twist|ableShape|F(unc|lare)|Wave)|ault(RenderUtilityList|ShaderList|TextureList|LightList))|lete(Co(lorSet|mponent)|UVSet))|ag(Node|Pose)|r(opoffLocator|agField))|u(seBackground|n(trim|i(t(Conversion|ToTimeConversion)|formField)|known(Transform|Dag)?)|vChooser)|j(iggle|oint(Cluster|Ffd|Lattice)?)|p(sdFileTex|hong(E)?|o(s(tProcessList|itionMarker)|int(MatrixMult|Constraint|On(SurfaceInfo|CurveInfo)|Emitter|Light)|l(y(Reduce|M(irror|o(difier(UV|World)?|ve(UV|Edge|Vertex|Face(tUV)?))|erge(UV|Edge|Vert|Face)|ap(Sew(Move)?|Cut|Del))|B(oolOp|evel|lindData|ase)|S(traightenUVBorder|oftEdge|ubd(Edge|Face)|p(h(ere|Proj)|lit(Ring|Edge|Vert)?)|e(parate|wEdge)|mooth(Proxy|Face)?)|Normal(izeUV|PerVertex)?|C(hipOff|yl(inder|Proj)|o(ne|pyUV|l(orPerVertex|lapse(Edge|F)))|u(t(Manip(Container)?)?|be)|loseBorder|rea(seEdge|t(or|eFace)))|T(o(Subdiv|rus)|weak(UV)?|r(iangulate|ansfer))|OptUvs|D(uplicateEdge|el(Edge|Vertex|Facet))|Unite|P(yramid|oke(Manip)?|lan(e|arProj)|r(i(sm|mitive)|oj))|Extrude(Edge|Vertex|Face)|VertexNormalManip|Quad|Flip(UV|Edge)|WedgeFace|LayoutUV|A(utoProj|ppend(Vertex)?|verageVertex))|eVectorConstraint))|fx(Geometry|Hair|Toon)|l(usMinusAverage|a(n(e|arTrimSurface)|ce(2dTexture|3dTexture)))|a(ssMatrix|irBlend|r(ti(cle(SamplerInfo|C(olorMapper|loud)|TranspMapper|IncandMapper|AgeMapper)?|tion)|ent(Constraint|Tessellate)|amDimension))|r(imitive|o(ject(ion|Curve|Tangent)|xyManager)))|e(n(tity|v(Ball|ironmentFog|S(phere|ky)|C(hrome|ube)|Fog))|x(t(end(Surface|Curve)|rude)|p(lodeNurbsShell|ression)))|v(iewManip|o(lume(Shader|Noise|Fog|Light|AxisField)|rtexField)|e(ctor(RenderGlobals|Product)|rtexBakeSet))|quadShadingSwitch|f(i(tBspline|eld|l(ter(Resample|Simplify|ClosestSample|Euler)?|e|letCurve))|o(urByFourMatrix|llicle)|urPointOn(MeshInfo|Subd)|f(BlendSrf(Obsolete)?|d|FilletSrf)|l(ow|uid(S(hape|liceManip)|Texture(2D|3D)|Emitter)|exorShape)|ra(ctal|meCache))|w(tAddMatrix|ire|ood|eightGeometryFilter|ater|rap)|l(ight(Info|Fog|Li(st|nker))?|o(cator|okAt|d(Group|Thresholds)|ft)|uminance|ea(stSquaresModifier|ther)|a(yered(Shader|Texture)|ttice|mbert))|a(n(notationShape|i(sotropic|m(Blend(InOut)?|C(urve(T(T|U|L|A)|U(T|U|L|A))?|lip)))|gleBetween)|tt(ach(Surface|Curve)|rHierarchyTest)|i(rField|mConstraint)|dd(Matrix|DoubleLinear)|udio|vg(SurfacePoints|NurbsSurfacePoints|Curves)|lign(Manip|Surface|Curve)|r(cLengthDimension|tAttrPaintTest|eaLight|rayMapper)|mbientLight|bstractBase(NurbsConversion|Create))|r(igid(Body|Solver|Constraint)|o(ck|undConstantRadius)|e(s(olution|ultCurve(TimeTo(Time|Unitless|Linear|Angular))?)|nder(Rect|Globals(List)?|Box|Sphere|Cone|Quality|L(ight|ayer(Manager)?))|cord|v(olve(dPrimitive)?|erse(Surface|Curve)?)|f(erence|lect)|map(Hsv|Color|Value)|build(Surface|Curve))|a(dialField|mp(Shader)?)|gbToHsv|bfSrf)|g(uide|eo(Connect(or|able)|metry(Shape|Constraint|VarGroup|Filter))|lobal(Stitch|CacheControl)|ammaCorrect|r(id|oup(Id|Parts)|a(nite|vityField)))|Fur(Globals|Description|Feedback|Attractors)|xformManip|m(o(tionPath|untain|vie)|u(te|lt(Matrix|i(plyDivide|listerLight)|DoubleLinear))|pBirailSrf|e(sh(VarGroup)?|ntalray(Texture|IblShape))|a(terialInfo|ke(Group|Nurb(sSquare|Sphere|C(ylinder|ircle|one|ube)|Torus|Plane)|CircularArc|T(hreePointCircularArc|extCurves|woPointCircularArc))|rble))|b(irailSrf|o(neLattice|olean|undary(Base)?)|u(lge|mp(2d|3d))|evel(Plus)?|l(in(n|dDataTemplate)|end(Shape|Color(s|Sets)|TwoAttr|Device|Weighted)?)|a(se(GeometryVarGroup|ShadingSwitch|Lattice)|keSet)|r(ownian|ush)))\\b"},{caseInsensitive:!0,token:"keyword.control.mel",regex:"\\b(if|in|else|for|while|break|continue|case|default|do|switch|return|switch|case|source|catch|alias)\\b"},{token:"keyword.other.mel",regex:"\\b(global)\\b"},{caseInsensitive:!0,token:"constant.language.mel",regex:"\\b(null|undefined)\\b"},{token:"constant.numeric.mel",regex:"\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f)?\\b"},{token:"punctuation.definition.string.begin.mel",regex:'"',push:[{token:"constant.character.escape.mel",regex:"\\\\."},{token:"punctuation.definition.string.end.mel",regex:'"',next:"pop"},{defaultToken:"string.quoted.double.mel"}]},{token:["variable.other.mel","punctuation.definition.variable.mel"],regex:"(\\$)([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*?\\b)"},{token:"punctuation.definition.string.begin.mel",regex:"'",push:[{token:"constant.character.escape.mel",regex:"\\\\."},{token:"punctuation.definition.string.end.mel",regex:"'",next:"pop"},{defaultToken:"string.quoted.single.mel"}]},{token:"constant.language.mel",regex:"\\b(false|true|yes|no|on|off)\\b"},{token:"punctuation.definition.comment.mel",regex:"/\\*",push:[{token:"punctuation.definition.comment.mel",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.mel"}]},{token:["comment.line.double-slash.mel","punctuation.definition.comment.mel"],regex:"(//)(.*$\\n?)"},{caseInsensitive:!0,token:"keyword.operator.mel",regex:"\\b(instanceof)\\b"},{token:"keyword.operator.symbolic.mel",regex:"[-\\!\\%\\&\\*\\+\\=\\/\\?\\:]"},{token:["meta.preprocessor.mel","punctuation.definition.preprocessor.mel"],regex:"(^[ \\t]*)((?:#)[a-zA-Z]+)"},{token:["meta.function.mel","keyword.other.mel","storage.type.mel","entity.name.function.mel","punctuation.section.function.mel"],regex:"((?:global\\s*)?proc)\\s*(\\w+\\s*\\[?\\]?\\s+|\\s+)([A-Za-z_][A-Za-z0-9_\\.]*)(\\s*(\\())",push:[{include:"$self"},{token:"punctuation.section.function.mel",regex:"\\)",next:"pop"},{defaultToken:"meta.function.mel"}]}]},this.normalizeRules()};r.inherits(s,i),t.MELHighlightRules=s}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/mel",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/mel_highlight_rules","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./mel_highlight_rules").MELHighlightRules,o=e("./behaviour/cstyle").CstyleBehaviour,u=e("./folding/cstyle").FoldMode,a=function(){this.HighlightRules=s,this.$behaviour=new o,this.foldingRules=new u};r.inherits(a,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/mel"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-mushcode.js b/dist/assets/js/vendor/ace-nc/mode-mushcode.js
            new file mode 100644
            index 0000000000..1830f09916
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-mushcode.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/mushcode_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="@if|@ifelse|@switch|@halt|@dolist|@create|@scent|@sound|@touch|@ataste|@osound|@ahear|@aahear|@amhear|@otouch|@otaste|@drop|@odrop|@adrop|@dropfail|@odropfail|@smell|@oemit|@emit|@pemit|@parent|@clone|@taste|whisper|page|say|pose|semipose|teach|touch|taste|smell|listen|look|move|go|home|follow|unfollow|desert|dismiss|@tel",t="=#0",n="default|edefault|eval|get_eval|get|grep|grepi|hasattr|hasattrp|hasattrval|hasattrpval|lattr|nattr|poss|udefault|ufun|u|v|uldefault|xget|zfun|band|bnand|bnot|bor|bxor|shl|shr|and|cand|cor|eq|gt|gte|lt|lte|nand|neq|nor|not|or|t|xor|con|entrances|exit|followers|home|lcon|lexits|loc|locate|lparent|lsearch|next|num|owner|parent|pmatch|rloc|rnum|room|where|zone|worn|held|carried|acos|asin|atan|ceil|cos|e|exp|fdiv|fmod|floor|log|ln|pi|power|round|sin|sqrt|tan|aposs|andflags|conn|commandssent|controls|doing|elock|findable|flags|fullname|hasflag|haspower|hastype|hidden|idle|isbaker|lock|lstats|money|who|name|nearby|obj|objflags|photo|poll|powers|pendingtext|receivedtext|restarts|restarttime|subj|shortestpath|tmoney|type|visible|cat|element|elements|extract|filter|filterbool|first|foreach|fold|grab|graball|index|insert|itemize|items|iter|last|ldelete|map|match|matchall|member|mix|munge|pick|remove|replace|rest|revwords|setdiff|setinter|setunion|shuffle|sort|sortby|splice|step|wordpos|words|add|lmath|max|mean|median|min|mul|percent|sign|stddev|sub|val|bound|abs|inc|dec|dist2d|dist3d|div|floordiv|mod|modulo|remainder|vadd|vdim|vdot|vmag|vmax|vmin|vmul|vsub|vunit|regedit|regeditall|regeditalli|regediti|regmatch|regmatchi|regrab|regraball|regraballi|regrabi|regrep|regrepi|after|alphamin|alphamax|art|before|brackets|capstr|case|caseall|center|containsfansi|comp|decompose|decrypt|delete|edit|encrypt|escape|if|ifelse|lcstr|left|lit|ljust|merge|mid|ostrlen|pos|repeat|reverse|right|rjust|scramble|secure|space|spellnum|squish|strcat|strmatch|strinsert|stripansi|stripfansi|strlen|switch|switchall|table|tr|trim|ucstr|unsafe|wrap|ctitle|cwho|channels|clock|cflags|ilev|itext|inum|convsecs|convutcsecs|convtime|ctime|etimefmt|isdaylight|mtime|secs|msecs|starttime|time|timefmt|timestring|utctime|atrlock|clone|create|cook|dig|emit|lemit|link|oemit|open|pemit|remit|set|tel|wipe|zemit|fbcreate|fbdestroy|fbwrite|fbclear|fbcopy|fbcopyto|fbclip|fbdump|fbflush|fbhset|fblist|fbstats|qentries|qentry|play|ansi|break|c|asc|die|isdbref|isint|isnum|isletters|linecoords|localize|lnum|nameshort|null|objeval|r|rand|s|setq|setr|soundex|soundslike|valid|vchart|vchart2|vlabel|@@|bakerdays|bodybuild|box|capall|catalog|children|ctrailer|darttime|debt|detailbar|exploredroom|fansitoansi|fansitoxansi|fullbar|halfbar|isdarted|isnewbie|isword|lambda|lobjects|lplayers|lthings|lvexits|lvobjects|lvplayers|lvthings|newswrap|numsuffix|playerson|playersthisweek|randomad|randword|realrandword|replacechr|second|splitamount|strlenall|text|third|tofansi|totalac|unique|getaddressroom|listpropertycomm|listpropertyres|lotowner|lotrating|lotratingcount|lotvalue|boughtproduct|companyabb|companyicon|companylist|companyname|companyowners|companyvalue|employees|invested|productlist|productname|productowners|productrating|productratingcount|productsoldat|producttype|ratedproduct|soldproduct|topproducts|totalspentonproduct|totalstock|transfermoney|uniquebuyercount|uniqueproductsbought|validcompany|deletepicture|fbsave|getpicturesecurity|haspicture|listpictures|picturesize|replacecolor|rgbtocolor|savepicture|setpicturesecurity|showpicture|piechart|piechartlabel|createmaze|drawmaze|drawwireframe",r=this.createKeywordMapper({"invalid.deprecated":"debugger","support.function":n,"constant.language":t,keyword:e},"identifier"),i="(?:r|u|ur|R|U|UR|Ur|uR)?",s="(?:(?:[1-9]\\d*)|(?:0))",o="(?:0[oO]?[0-7]+)",u="(?:0[xX][\\dA-Fa-f]+)",a="(?:0[bB][01]+)",f="(?:"+s+"|"+o+"|"+u+"|"+a+")",l="(?:[eE][+-]?\\d+)",c="(?:\\.\\d+)",h="(?:\\d+)",p="(?:(?:"+h+"?"+c+")|(?:"+h+"\\.))",d="(?:(?:"+p+"|"+h+")"+l+")",v="(?:"+d+"|"+p+")";this.$rules={start:[{token:"variable",regex:"%[0-9]{1}"},{token:"variable",regex:"%q[0-9A-Za-z]{1}"},{token:"variable",regex:"%[a-zA-Z]{1}"},{token:"variable.language",regex:"%[a-z0-9-_]+"},{token:"constant.numeric",regex:"(?:"+v+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:v},{token:"constant.numeric",regex:f+"[lL]\\b"},{token:"constant.numeric",regex:f+"\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|#|%|<<|>>|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}]}};r.inherits(s,i),t.MushCodeRules=s}),ace.define("ace/mode/folding/pythonic",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e){this.foldingStartMarker=new RegExp("([\\[{])(?:\\s*)$|("+e+")(?:\\s*)(?:#.*)?$")};r.inherits(s,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i=r.match(this.foldingStartMarker);if(i)return i[1]?this.openingBracketBlock(e,i[1],n,i.index):i[2]?this.indentationBlock(e,n,i.index+i[2].length):this.indentationBlock(e,n)}}.call(s.prototype)}),ace.define("ace/mode/mushcode",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/mushcode_highlight_rules","ace/mode/folding/pythonic","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./mushcode_highlight_rules").MushCodeRules,o=e("./folding/pythonic").FoldMode,u=e("../range").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o("\\:")};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[\:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new u(n,r.length-i.length,n,r.length))},this.$id="ace/mode/mushcode"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-mysql.js b/dist/assets/js/vendor/ace-nc/mode-mysql.js
            new file mode 100644
            index 0000000000..01da5d0633
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-mysql.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/mysql_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./doc_comment_highlight_rules").DocCommentHighlightRules,o=e("./text_highlight_rules").TextHighlightRules,u=function(){function i(e){var t=e.start,n=e.escape;return{token:"string.start",regex:t,next:[{token:"constant.language.escape",regex:n},{token:"string.end",next:"start",regex:t},{defaultToken:"string"}]}}var e="alter|and|as|asc|between|count|create|delete|desc|distinct|drop|from|having|in|insert|into|is|join|like|not|on|or|order|select|set|table|union|update|values|where|accessible|action|add|after|algorithm|all|analyze|asensitive|at|authors|auto_increment|autocommit|avg|avg_row_length|before|binary|binlog|both|btree|cache|call|cascade|cascaded|case|catalog_name|chain|change|changed|character|check|checkpoint|checksum|class_origin|client_statistics|close|coalesce|code|collate|collation|collations|column|columns|comment|commit|committed|completion|concurrent|condition|connection|consistent|constraint|contains|continue|contributors|convert|cross|current_date|current_time|current_timestamp|current_user|cursor|data|database|databases|day_hour|day_microsecond|day_minute|day_second|deallocate|dec|declare|default|delay_key_write|delayed|delimiter|des_key_file|describe|deterministic|dev_pop|dev_samp|deviance|directory|disable|discard|distinctrow|div|dual|dumpfile|each|elseif|enable|enclosed|end|ends|engine|engines|enum|errors|escape|escaped|even|event|events|every|execute|exists|exit|explain|extended|fast|fetch|field|fields|first|flush|for|force|foreign|found_rows|full|fulltext|function|general|global|grant|grants|group|groupby_concat|handler|hash|help|high_priority|hosts|hour_microsecond|hour_minute|hour_second|if|ignore|ignore_server_ids|import|index|index_statistics|infile|inner|innodb|inout|insensitive|insert_method|install|interval|invoker|isolation|iterate|key|keys|kill|language|last|leading|leave|left|level|limit|linear|lines|list|load|local|localtime|localtimestamp|lock|logs|low_priority|master|master_heartbeat_period|master_ssl_verify_server_cert|masters|match|max|max_rows|maxvalue|message_text|middleint|migrate|min|min_rows|minute_microsecond|minute_second|mod|mode|modifies|modify|mutex|mysql_errno|natural|next|no|no_write_to_binlog|offline|offset|one|online|open|optimize|option|optionally|out|outer|outfile|pack_keys|parser|partition|partitions|password|phase|plugin|plugins|prepare|preserve|prev|primary|privileges|procedure|processlist|profile|profiles|purge|query|quick|range|read|read_write|reads|real|rebuild|recover|references|regexp|relaylog|release|remove|rename|reorganize|repair|repeatable|replace|require|resignal|restrict|resume|return|returns|revoke|right|rlike|rollback|rollup|row|row_format|rtree|savepoint|schedule|schema|schema_name|schemas|second_microsecond|security|sensitive|separator|serializable|server|session|share|show|signal|slave|slow|smallint|snapshot|soname|spatial|specific|sql|sql_big_result|sql_buffer_result|sql_cache|sql_calc_found_rows|sql_no_cache|sql_small_result|sqlexception|sqlstate|sqlwarning|ssl|start|starting|starts|status|std|stddev|stddev_pop|stddev_samp|storage|straight_join|subclass_origin|sum|suspend|table_name|table_statistics|tables|tablespace|temporary|terminated|to|trailing|transaction|trigger|triggers|truncate|uncommitted|undo|uninstall|unique|unlock|upgrade|usage|use|use_frm|user|user_resources|user_statistics|using|utc_date|utc_time|utc_timestamp|value|variables|varying|view|views|warnings|when|while|with|work|write|xa|xor|year_month|zerofill|begin|do|then|else|loop|repeat",t="by|bool|boolean|bit|blob|decimal|double|enum|float|long|longblob|longtext|medium|mediumblob|mediumint|mediumtext|time|timestamp|tinyblob|tinyint|tinytext|text|bigint|int|int1|int2|int3|int4|int8|integer|float|float4|float8|double|char|varbinary|varchar|varcharacter|precision|date|datetime|year|unsigned|signed|numeric",n="charset|clear|connect|edit|ego|exit|go|help|nopager|notee|nowarning|pager|print|prompt|quit|rehash|source|status|system|tee",r=this.createKeywordMapper({"support.function":t,keyword:e,constant:"false|true|null|unknown|date|time|timestamp|ODBCdotTable|zerolessFloat","variable.language":n},"identifier",!0);this.$rules={start:[{token:"comment",regex:"(?:-- |#).*$"},i({start:'"',escape:/\\[0'"bnrtZ\\%_]?/}),i({start:"'",escape:/\\[0'"bnrtZ\\%_]?/}),s.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+|[xX]'[0-9a-fA-F]+'|0[bB][01]+|[bB]'[01]+'/},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"constant.class",regex:"@@?[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"constant.buildin",regex:"`[^`]*`"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}]},this.embedRules(s,"doc-",[s.getEndRule("start")]),this.normalizeRules()};r.inherits(u,o),t.MysqlHighlightRules=u}),ace.define("ace/mode/mysql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/mysql_highlight_rules","ace/range"],function(e,t,n){var r=e("../lib/oop"),i=e("../mode/text").Mode,s=e("./mysql_highlight_rules").MysqlHighlightRules,o=e("../range").Range,u=function(){this.HighlightRules=s};r.inherits(u,i),function(){this.lineCommentStart=["--","#"],this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/mysql"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-nix.js b/dist/assets/js/vendor/ace-nc/mode-nix.js
            new file mode 100644
            index 0000000000..80f1c99e0b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-nix.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/c_cpp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=t.cFunctions="\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\b",u=function(){var e="break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while|catch|operator|try|throw|using",t="asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|class|wchar_t|template",n="const|extern|register|restrict|static|volatile|inline|private:|protected:|public:|friend|explicit|virtual|export|mutable|typename",r="and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eqconst_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace",s="NULL|true|false|TRUE|FALSE",u=this.$keywords=this.createKeywordMapper({"keyword.control":e,"storage.type":t,"storage.modifier":n,"keyword.operator":r,"variable.language":"this","constant.language":s},"identifier"),a="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Zd\\$_\u00a1-\uffff]*\\b";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"keyword",regex:"#\\s*(?:include|import|pragma|line|define|undef|if|ifdef|else|elif|ifndef)\\b",next:"directive"},{token:"keyword",regex:"(?:#\\s*endif)\\b"},{token:"support.function.C99.c",regex:o},{token:u,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}],directive:[{token:"constant.other.multiline",regex:/\\/},{token:"constant.other.multiline",regex:/.*\\/},{token:"constant.other",regex:"\\s*<.+?>",next:"start"},{token:"constant.other",regex:'\\s*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]',next:"start"},{token:"constant.other",regex:"\\s*['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']",next:"start"},{token:"constant.other",regex:/[^\\\/]+/,next:"start"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(u,s),t.c_cppHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/c_cpp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/c_cpp_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./c_cpp_highlight_rules").c_cppHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/c_cpp"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/nix_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="true|false",t="with|import|if|else|then|inherit",n="let|in|rec",r=this.createKeywordMapper({"constant.language.nix":e,"keyword.control.nix":t,"keyword.declaration.nix":n},"identifier");this.$rules={start:[{token:"comment",regex:/#.*$/},{token:"comment",regex:/\/\*/,next:"comment"},{token:"constant",regex:"<[^>]+>"},{regex:"(==|!=|<=?|>=?)",token:["keyword.operator.comparison.nix"]},{regex:"((?:[+*/%-]|\\~)=)",token:["keyword.operator.assignment.arithmetic.nix"]},{regex:"=",token:"keyword.operator.assignment.nix"},{token:"string",regex:"''",next:"qqdoc"},{token:"string",regex:"'",next:"qstring"},{token:"string",regex:'"',push:"qqstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{regex:"}",token:function(e,t,n){return n[1]&&n[1].charAt(0)=="q"?"constant.language.escape":"text"},next:"pop"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqdoc:[{token:"constant.language.escape",regex:/\$\{/,push:"start"},{token:"string",regex:"''",next:"pop"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:/\$\{/,push:"start"},{token:"string",regex:'"',next:"pop"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:/\$\{/,push:"start"},{token:"string",regex:"'",next:"pop"},{defaultToken:"string"}]},this.normalizeRules()};r.inherits(s,i),t.NixHighlightRules=s}),ace.define("ace/mode/nix",["require","exports","module","ace/lib/oop","ace/mode/c_cpp","ace/mode/nix_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./c_cpp").Mode,s=e("./nix_highlight_rules").NixHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){i.call(this),this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="#",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/nix"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-objectivec.js b/dist/assets/js/vendor/ace-nc/mode-objectivec.js
            new file mode 100644
            index 0000000000..4239ed6ff3
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-objectivec.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/c_cpp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=t.cFunctions="\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\b",u=function(){var e="break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while|catch|operator|try|throw|using",t="asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|class|wchar_t|template",n="const|extern|register|restrict|static|volatile|inline|private:|protected:|public:|friend|explicit|virtual|export|mutable|typename",r="and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eqconst_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace",s="NULL|true|false|TRUE|FALSE",u=this.$keywords=this.createKeywordMapper({"keyword.control":e,"storage.type":t,"storage.modifier":n,"keyword.operator":r,"variable.language":"this","constant.language":s},"identifier"),a="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Zd\\$_\u00a1-\uffff]*\\b";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"keyword",regex:"#\\s*(?:include|import|pragma|line|define|undef|if|ifdef|else|elif|ifndef)\\b",next:"directive"},{token:"keyword",regex:"(?:#\\s*endif)\\b"},{token:"support.function.C99.c",regex:o},{token:u,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}],directive:[{token:"constant.other.multiline",regex:/\\/},{token:"constant.other.multiline",regex:/.*\\/},{token:"constant.other",regex:"\\s*<.+?>",next:"start"},{token:"constant.other",regex:'\\s*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]',next:"start"},{token:"constant.other",regex:"\\s*['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']",next:"start"},{token:"constant.other",regex:/[^\\\/]+/,next:"start"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(u,s),t.c_cppHighlightRules=u}),ace.define("ace/mode/objectivec_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/c_cpp_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./c_cpp_highlight_rules"),o=s.c_cppHighlightRules,u=function(){var e="\\\\(?:[abefnrtv'\"?\\\\]|[0-3]\\d{1,2}|[4-7]\\d?|222|x[a-zA-Z0-9]+)",t=[{regex:"\\b_cmd\\b",token:"variable.other.selector.objc"},{regex:"\\b(?:self|super)\\b",token:"variable.language.objc"}],n=new o,r=n.getRules();this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:["storage.type.objc","punctuation.definition.storage.type.objc","entity.name.type.objc","text","entity.other.inherited-class.objc"],regex:"(@)(interface|protocol)(?!.+;)(\\s+[A-Za-z_][A-Za-z0-9_]*)(\\s*:\\s*)([A-Za-z]+)"},{token:["storage.type.objc"],regex:"(@end)"},{token:["storage.type.objc","entity.name.type.objc","entity.other.inherited-class.objc"],regex:"(@implementation)(\\s+[A-Za-z_][A-Za-z0-9_]*)(\\s*?::\\s*(?:[A-Za-z][A-Za-z0-9]*))?"},{token:"string.begin.objc",regex:'@"',next:"constant_NSString"},{token:"storage.type.objc",regex:"\\bid\\s*<",next:"protocol_list"},{token:"keyword.control.macro.objc",regex:"\\bNS_DURING|NS_HANDLER|NS_ENDHANDLER\\b"},{token:["punctuation.definition.keyword.objc","keyword.control.exception.objc"],regex:"(@)(try|catch|finally|throw)\\b"},{token:["punctuation.definition.keyword.objc","keyword.other.objc"],regex:"(@)(defs|encode)\\b"},{token:["storage.type.id.objc","text"],regex:"(\\bid\\b)(\\s|\\n)?"},{token:"storage.type.objc",regex:"\\bIBOutlet|IBAction|BOOL|SEL|id|unichar|IMP|Class\\b"},{token:["punctuation.definition.storage.type.objc","storage.type.objc"],regex:"(@)(class|protocol)\\b"},{token:["punctuation.definition.storage.type.objc","punctuation"],regex:"(@selector)(\\s*\\()",next:"selectors"},{token:["punctuation.definition.storage.modifier.objc","storage.modifier.objc"],regex:"(@)(synchronized|public|private|protected|package)\\b"},{token:"constant.language.objc",regex:"\\bYES|NO|Nil|nil\\b"},{token:"support.variable.foundation",regex:"\\bNSApp\\b"},{token:["support.function.cocoa.leopard"],regex:"(?:\\b)(NS(?:Rect(?:ToCGRect|FromCGRect)|MakeCollectable|S(?:tringFromProtocol|ize(?:ToCGSize|FromCGSize))|Draw(?:NinePartImage|ThreePartImage)|P(?:oint(?:ToCGPoint|FromCGPoint)|rotocolFromString)|EventMaskFromType|Value))(?:\\b)"},{token:["support.function.cocoa"],regex:"(?:\\b)(NS(?:R(?:ound(?:DownToMultipleOfPageSize|UpToMultipleOfPageSize)|un(?:CriticalAlertPanel(?:RelativeToWindow)?|InformationalAlertPanel(?:RelativeToWindow)?|AlertPanel(?:RelativeToWindow)?)|e(?:set(?:MapTable|HashTable)|c(?:ycleZone|t(?:Clip(?:List)?|F(?:ill(?:UsingOperation|List(?:UsingOperation|With(?:Grays|Colors(?:UsingOperation)?))?)?|romString))|ordAllocationEvent)|turnAddress|leaseAlertPanel|a(?:dPixel|l(?:MemoryAvailable|locateCollectable))|gisterServicesProvider)|angeFromString)|Get(?:SizeAndAlignment|CriticalAlertPanel|InformationalAlertPanel|UncaughtExceptionHandler|FileType(?:s)?|WindowServerMemory|AlertPanel)|M(?:i(?:n(?:X|Y)|d(?:X|Y))|ouseInRect|a(?:p(?:Remove|Get|Member|Insert(?:IfAbsent|KnownAbsent)?)|ke(?:R(?:ect|ange)|Size|Point)|x(?:Range|X|Y)))|B(?:itsPer(?:SampleFromDepth|PixelFromDepth)|e(?:stDepth|ep|gin(?:CriticalAlertSheet|InformationalAlertSheet|AlertSheet)))|S(?:ho(?:uldRetainWithZone|w(?:sServicesMenuItem|AnimationEffect))|tringFrom(?:R(?:ect|ange)|MapTable|S(?:ize|elector)|HashTable|Class|Point)|izeFromString|e(?:t(?:ShowsServicesMenuItem|ZoneName|UncaughtExceptionHandler|FocusRingStyle)|lectorFromString|archPathForDirectoriesInDomains)|wap(?:Big(?:ShortToHost|IntToHost|DoubleToHost|FloatToHost|Long(?:ToHost|LongToHost))|Short|Host(?:ShortTo(?:Big|Little)|IntTo(?:Big|Little)|DoubleTo(?:Big|Little)|FloatTo(?:Big|Little)|Long(?:To(?:Big|Little)|LongTo(?:Big|Little)))|Int|Double|Float|L(?:ittle(?:ShortToHost|IntToHost|DoubleToHost|FloatToHost|Long(?:ToHost|LongToHost))|ong(?:Long)?)))|H(?:ighlightRect|o(?:stByteOrder|meDirectory(?:ForUser)?)|eight|ash(?:Remove|Get|Insert(?:IfAbsent|KnownAbsent)?)|FSType(?:CodeFromFileType|OfFile))|N(?:umberOfColorComponents|ext(?:MapEnumeratorPair|HashEnumeratorItem))|C(?:o(?:n(?:tainsRect|vert(?:GlyphsToPackedGlyphs|Swapped(?:DoubleToHost|FloatToHost)|Host(?:DoubleToSwapped|FloatToSwapped)))|unt(?:MapTable|HashTable|Frames|Windows(?:ForContext)?)|py(?:M(?:emoryPages|apTableWithZone)|Bits|HashTableWithZone|Object)|lorSpaceFromDepth|mpare(?:MapTables|HashTables))|lassFromString|reate(?:MapTable(?:WithZone)?|HashTable(?:WithZone)?|Zone|File(?:namePboardType|ContentsPboardType)))|TemporaryDirectory|I(?:s(?:ControllerMarker|EmptyRect|FreedObject)|n(?:setRect|crementExtraRefCount|te(?:r(?:sect(?:sRect|ionR(?:ect|ange))|faceStyleForKey)|gralRect)))|Zone(?:Realloc|Malloc|Name|Calloc|Fr(?:omPointer|ee))|O(?:penStepRootDirectory|ffsetRect)|D(?:i(?:sableScreenUpdates|videRect)|ottedFrameRect|e(?:c(?:imal(?:Round|Multiply|S(?:tring|ubtract)|Normalize|Co(?:py|mpa(?:ct|re))|IsNotANumber|Divide|Power|Add)|rementExtraRefCountWasZero)|faultMallocZone|allocate(?:MemoryPages|Object))|raw(?:Gr(?:oove|ayBezel)|B(?:itmap|utton)|ColorTiledRects|TiledRects|DarkBezel|W(?:hiteBezel|indowBackground)|LightBezel))|U(?:serName|n(?:ionR(?:ect|ange)|registerServicesProvider)|pdateDynamicServices)|Java(?:Bundle(?:Setup|Cleanup)|Setup(?:VirtualMachine)?|Needs(?:ToLoadClasses|VirtualMachine)|ClassesF(?:orBundle|romPath)|ObjectNamedInPath|ProvidesClasses)|P(?:oint(?:InRect|FromString)|erformService|lanarFromDepth|ageSize)|E(?:n(?:d(?:MapTableEnumeration|HashTableEnumeration)|umerate(?:MapTable|HashTable)|ableScreenUpdates)|qual(?:R(?:ects|anges)|Sizes|Points)|raseRect|xtraRefCount)|F(?:ileTypeForHFSTypeCode|ullUserName|r(?:ee(?:MapTable|HashTable)|ame(?:Rect(?:WithWidth(?:UsingOperation)?)?|Address)))|Wi(?:ndowList(?:ForContext)?|dth)|Lo(?:cationInRange|g(?:v|PageSize)?)|A(?:ccessibility(?:R(?:oleDescription(?:ForUIElement)?|aiseBadArgumentException)|Unignored(?:Children(?:ForOnlyChild)?|Descendant|Ancestor)|PostNotification|ActionDescription)|pplication(?:Main|Load)|vailableWindowDepths|ll(?:MapTable(?:Values|Keys)|HashTableObjects|ocate(?:MemoryPages|Collectable|Object)))))(?:\\b)"},{token:["support.class.cocoa.leopard"],regex:"(?:\\b)(NS(?:RuleEditor|G(?:arbageCollector|radient)|MapTable|HashTable|Co(?:ndition|llectionView(?:Item)?)|T(?:oolbarItemGroup|extInputClient|r(?:eeNode|ackingArea))|InvocationOperation|Operation(?:Queue)?|D(?:ictionaryController|ockTile)|P(?:ointer(?:Functions|Array)|athC(?:o(?:ntrol(?:Delegate)?|mponentCell)|ell(?:Delegate)?)|r(?:intPanelAccessorizing|edicateEditor(?:RowTemplate)?))|ViewController|FastEnumeration|Animat(?:ionContext|ablePropertyContainer)))(?:\\b)"},{token:["support.class.cocoa"],regex:"(?:\\b)(NS(?:R(?:u(?:nLoop|ler(?:Marker|View))|e(?:sponder|cursiveLock|lativeSpecifier)|an(?:domSpecifier|geSpecifier))|G(?:etCommand|lyph(?:Generator|Storage|Info)|raphicsContext)|XML(?:Node|D(?:ocument|TD(?:Node)?)|Parser|Element)|M(?:iddleSpecifier|ov(?:ie(?:View)?|eCommand)|utable(?:S(?:tring|et)|C(?:haracterSet|opying)|IndexSet|D(?:ictionary|ata)|URLRequest|ParagraphStyle|A(?:ttributedString|rray))|e(?:ssagePort(?:NameServer)?|nu(?:Item(?:Cell)?|View)?|t(?:hodSignature|adata(?:Item|Query(?:ResultGroup|AttributeValueTuple)?)))|a(?:ch(?:BootstrapServer|Port)|trix))|B(?:itmapImageRep|ox|u(?:ndle|tton(?:Cell)?)|ezierPath|rowser(?:Cell)?)|S(?:hadow|c(?:anner|r(?:ipt(?:SuiteRegistry|C(?:o(?:ercionHandler|mmand(?:Description)?)|lassDescription)|ObjectSpecifier|ExecutionContext|WhoseTest)|oll(?:er|View)|een))|t(?:epper(?:Cell)?|atus(?:Bar|Item)|r(?:ing|eam))|imple(?:HorizontalTypesetter|CString)|o(?:cketPort(?:NameServer)?|und|rtDescriptor)|p(?:e(?:cifierTest|ech(?:Recognizer|Synthesizer)|ll(?:Server|Checker))|litView)|e(?:cureTextField(?:Cell)?|t(?:Command)?|archField(?:Cell)?|rializer|gmentedC(?:ontrol|ell))|lider(?:Cell)?|avePanel)|H(?:ost|TTP(?:Cookie(?:Storage)?|URLResponse)|elpManager)|N(?:ib(?:Con(?:nector|trolConnector)|OutletConnector)?|otification(?:Center|Queue)?|u(?:ll|mber(?:Formatter)?)|etService(?:Browser)?|ameSpecifier)|C(?:ha(?:ngeSpelling|racterSet)|o(?:n(?:stantString|nection|trol(?:ler)?|ditionLock)|d(?:ing|er)|unt(?:Command|edSet)|pying|lor(?:Space|P(?:ick(?:ing(?:Custom|Default)|er)|anel)|Well|List)?|m(?:p(?:oundPredicate|arisonPredicate)|boBox(?:Cell)?))|u(?:stomImageRep|rsor)|IImageRep|ell|l(?:ipView|o(?:seCommand|neCommand)|assDescription)|a(?:ched(?:ImageRep|URLResponse)|lendar(?:Date)?)|reateCommand)|T(?:hread|ypesetter|ime(?:Zone|r)|o(?:olbar(?:Item(?:Validations)?)?|kenField(?:Cell)?)|ext(?:Block|Storage|Container|Tab(?:le(?:Block)?)?|Input|View|Field(?:Cell)?|List|Attachment(?:Cell)?)?|a(?:sk|b(?:le(?:Header(?:Cell|View)|Column|View)|View(?:Item)?))|reeController)|I(?:n(?:dex(?:S(?:pecifier|et)|Path)|put(?:Manager|S(?:tream|erv(?:iceProvider|er(?:MouseTracker)?)))|vocation)|gnoreMisspelledWords|mage(?:Rep|Cell|View)?)|O(?:ut(?:putStream|lineView)|pen(?:GL(?:Context|Pixel(?:Buffer|Format)|View)|Panel)|bj(?:CTypeSerializationCallBack|ect(?:Controller)?))|D(?:i(?:st(?:antObject(?:Request)?|ributed(?:NotificationCenter|Lock))|ctionary|rectoryEnumerator)|ocument(?:Controller)?|e(?:serializer|cimalNumber(?:Behaviors|Handler)?|leteCommand)|at(?:e(?:Components|Picker(?:Cell)?|Formatter)?|a)|ra(?:wer|ggingInfo))|U(?:ser(?:InterfaceValidations|Defaults(?:Controller)?)|RL(?:Re(?:sponse|quest)|Handle(?:Client)?|C(?:onnection|ache|redential(?:Storage)?)|Download(?:Delegate)?|Prot(?:ocol(?:Client)?|ectionSpace)|AuthenticationChallenge(?:Sender)?)?|n(?:iqueIDSpecifier|doManager|archiver))|P(?:ipe|o(?:sitionalSpecifier|pUpButton(?:Cell)?|rt(?:Message|NameServer|Coder)?)|ICTImageRep|ersistentDocument|DFImageRep|a(?:steboard|nel|ragraphStyle|geLayout)|r(?:int(?:Info|er|Operation|Panel)|o(?:cessInfo|tocolChecker|perty(?:Specifier|ListSerialization)|gressIndicator|xy)|edicate))|E(?:numerator|vent|PSImageRep|rror|x(?:ception|istsCommand|pression))|V(?:iew(?:Animation)?|al(?:idated(?:ToobarItem|UserInterfaceItem)|ue(?:Transformer)?))|Keyed(?:Unarchiver|Archiver)|Qui(?:ckDrawView|tCommand)|F(?:ile(?:Manager|Handle|Wrapper)|o(?:nt(?:Manager|Descriptor|Panel)?|rm(?:Cell|atter)))|W(?:hoseSpecifier|indow(?:Controller)?|orkspace)|L(?:o(?:c(?:k(?:ing)?|ale)|gicalTest)|evelIndicator(?:Cell)?|ayoutManager)|A(?:ssertionHandler|nimation|ctionCell|ttributedString|utoreleasePool|TSTypesetter|ppl(?:ication|e(?:Script|Event(?:Manager|Descriptor)))|ffineTransform|lert|r(?:chiver|ray(?:Controller)?))))(?:\\b)"},{token:["support.type.cocoa.leopard"],regex:"(?:\\b)(NS(?:R(?:u(?:nLoop|ler(?:Marker|View))|e(?:sponder|cursiveLock|lativeSpecifier)|an(?:domSpecifier|geSpecifier))|G(?:etCommand|lyph(?:Generator|Storage|Info)|raphicsContext)|XML(?:Node|D(?:ocument|TD(?:Node)?)|Parser|Element)|M(?:iddleSpecifier|ov(?:ie(?:View)?|eCommand)|utable(?:S(?:tring|et)|C(?:haracterSet|opying)|IndexSet|D(?:ictionary|ata)|URLRequest|ParagraphStyle|A(?:ttributedString|rray))|e(?:ssagePort(?:NameServer)?|nu(?:Item(?:Cell)?|View)?|t(?:hodSignature|adata(?:Item|Query(?:ResultGroup|AttributeValueTuple)?)))|a(?:ch(?:BootstrapServer|Port)|trix))|B(?:itmapImageRep|ox|u(?:ndle|tton(?:Cell)?)|ezierPath|rowser(?:Cell)?)|S(?:hadow|c(?:anner|r(?:ipt(?:SuiteRegistry|C(?:o(?:ercionHandler|mmand(?:Description)?)|lassDescription)|ObjectSpecifier|ExecutionContext|WhoseTest)|oll(?:er|View)|een))|t(?:epper(?:Cell)?|atus(?:Bar|Item)|r(?:ing|eam))|imple(?:HorizontalTypesetter|CString)|o(?:cketPort(?:NameServer)?|und|rtDescriptor)|p(?:e(?:cifierTest|ech(?:Recognizer|Synthesizer)|ll(?:Server|Checker))|litView)|e(?:cureTextField(?:Cell)?|t(?:Command)?|archField(?:Cell)?|rializer|gmentedC(?:ontrol|ell))|lider(?:Cell)?|avePanel)|H(?:ost|TTP(?:Cookie(?:Storage)?|URLResponse)|elpManager)|N(?:ib(?:Con(?:nector|trolConnector)|OutletConnector)?|otification(?:Center|Queue)?|u(?:ll|mber(?:Formatter)?)|etService(?:Browser)?|ameSpecifier)|C(?:ha(?:ngeSpelling|racterSet)|o(?:n(?:stantString|nection|trol(?:ler)?|ditionLock)|d(?:ing|er)|unt(?:Command|edSet)|pying|lor(?:Space|P(?:ick(?:ing(?:Custom|Default)|er)|anel)|Well|List)?|m(?:p(?:oundPredicate|arisonPredicate)|boBox(?:Cell)?))|u(?:stomImageRep|rsor)|IImageRep|ell|l(?:ipView|o(?:seCommand|neCommand)|assDescription)|a(?:ched(?:ImageRep|URLResponse)|lendar(?:Date)?)|reateCommand)|T(?:hread|ypesetter|ime(?:Zone|r)|o(?:olbar(?:Item(?:Validations)?)?|kenField(?:Cell)?)|ext(?:Block|Storage|Container|Tab(?:le(?:Block)?)?|Input|View|Field(?:Cell)?|List|Attachment(?:Cell)?)?|a(?:sk|b(?:le(?:Header(?:Cell|View)|Column|View)|View(?:Item)?))|reeController)|I(?:n(?:dex(?:S(?:pecifier|et)|Path)|put(?:Manager|S(?:tream|erv(?:iceProvider|er(?:MouseTracker)?)))|vocation)|gnoreMisspelledWords|mage(?:Rep|Cell|View)?)|O(?:ut(?:putStream|lineView)|pen(?:GL(?:Context|Pixel(?:Buffer|Format)|View)|Panel)|bj(?:CTypeSerializationCallBack|ect(?:Controller)?))|D(?:i(?:st(?:antObject(?:Request)?|ributed(?:NotificationCenter|Lock))|ctionary|rectoryEnumerator)|ocument(?:Controller)?|e(?:serializer|cimalNumber(?:Behaviors|Handler)?|leteCommand)|at(?:e(?:Components|Picker(?:Cell)?|Formatter)?|a)|ra(?:wer|ggingInfo))|U(?:ser(?:InterfaceValidations|Defaults(?:Controller)?)|RL(?:Re(?:sponse|quest)|Handle(?:Client)?|C(?:onnection|ache|redential(?:Storage)?)|Download(?:Delegate)?|Prot(?:ocol(?:Client)?|ectionSpace)|AuthenticationChallenge(?:Sender)?)?|n(?:iqueIDSpecifier|doManager|archiver))|P(?:ipe|o(?:sitionalSpecifier|pUpButton(?:Cell)?|rt(?:Message|NameServer|Coder)?)|ICTImageRep|ersistentDocument|DFImageRep|a(?:steboard|nel|ragraphStyle|geLayout)|r(?:int(?:Info|er|Operation|Panel)|o(?:cessInfo|tocolChecker|perty(?:Specifier|ListSerialization)|gressIndicator|xy)|edicate))|E(?:numerator|vent|PSImageRep|rror|x(?:ception|istsCommand|pression))|V(?:iew(?:Animation)?|al(?:idated(?:ToobarItem|UserInterfaceItem)|ue(?:Transformer)?))|Keyed(?:Unarchiver|Archiver)|Qui(?:ckDrawView|tCommand)|F(?:ile(?:Manager|Handle|Wrapper)|o(?:nt(?:Manager|Descriptor|Panel)?|rm(?:Cell|atter)))|W(?:hoseSpecifier|indow(?:Controller)?|orkspace)|L(?:o(?:c(?:k(?:ing)?|ale)|gicalTest)|evelIndicator(?:Cell)?|ayoutManager)|A(?:ssertionHandler|nimation|ctionCell|ttributedString|utoreleasePool|TSTypesetter|ppl(?:ication|e(?:Script|Event(?:Manager|Descriptor)))|ffineTransform|lert|r(?:chiver|ray(?:Controller)?))))(?:\\b)"},{token:["support.class.quartz"],regex:"(?:\\b)(C(?:I(?:Sampler|Co(?:ntext|lor)|Image(?:Accumulator)?|PlugIn(?:Registration)?|Vector|Kernel|Filter(?:Generator|Shape)?)|A(?:Renderer|MediaTiming(?:Function)?|BasicAnimation|ScrollLayer|Constraint(?:LayoutManager)?|T(?:iledLayer|extLayer|rans(?:ition|action))|OpenGLLayer|PropertyAnimation|KeyframeAnimation|Layer|A(?:nimation(?:Group)?|ction))))(?:\\b)"},{token:["support.type.quartz"],regex:"(?:\\b)(C(?:G(?:Float|Point|Size|Rect)|IFormat|AConstraintAttribute))(?:\\b)"},{token:["support.type.cocoa"],regex:"(?:\\b)(NS(?:R(?:ect(?:Edge)?|ange)|G(?:lyph(?:Relation|LayoutMode)?|radientType)|M(?:odalSession|a(?:trixMode|p(?:Table|Enumerator)))|B(?:itmapImageFileType|orderType|uttonType|ezelStyle|ackingStoreType|rowserColumnResizingType)|S(?:cr(?:oll(?:er(?:Part|Arrow)|ArrowPosition)|eenAuxiliaryOpaque)|tringEncoding|ize|ocketNativeHandle|election(?:Granularity|Direction|Affinity)|wapped(?:Double|Float)|aveOperationType)|Ha(?:sh(?:Table|Enumerator)|ndler(?:2)?)|C(?:o(?:ntrol(?:Size|Tint)|mp(?:ositingOperation|arisonResult))|ell(?:State|Type|ImagePosition|Attribute))|T(?:hreadPrivate|ypesetterGlyphInfo|i(?:ckMarkPosition|tlePosition|meInterval)|o(?:ol(?:TipTag|bar(?:SizeMode|DisplayMode))|kenStyle)|IFFCompression|ext(?:TabType|Alignment)|ab(?:State|leViewDropOperation|ViewType)|rackingRectTag)|ImageInterpolation|Zone|OpenGL(?:ContextAuxiliary|PixelFormatAuxiliary)|D(?:ocumentChangeType|atePickerElementFlags|ra(?:werState|gOperation))|UsableScrollerParts|P(?:oint|r(?:intingPageOrder|ogressIndicator(?:Style|Th(?:ickness|readInfo))))|EventType|KeyValueObservingOptions|Fo(?:nt(?:SymbolicTraits|TraitMask|Action)|cusRingType)|W(?:indow(?:OrderingMode|Depth)|orkspace(?:IconCreationOptions|LaunchOptions)|ritingDirection)|L(?:ineBreakMode|ayout(?:Status|Direction))|A(?:nimation(?:Progress|Effect)|ppl(?:ication(?:TerminateReply|DelegateReply|PrintReply)|eEventManagerSuspensionID)|ffineTransformStruct|lertStyle)))(?:\\b)"},{token:["support.constant.cocoa"],regex:"(?:\\b)(NS(?:NotFound|Ordered(?:Ascending|Descending|Same)))(?:\\b)"},{token:["support.constant.notification.cocoa.leopard"],regex:"(?:\\b)(NS(?:MenuDidBeginTracking|ViewDidUpdateTrackingAreas)?Notification)(?:\\b)"},{token:["support.constant.notification.cocoa"],regex:"(?:\\b)(NS(?:Menu(?:Did(?:RemoveItem|SendAction|ChangeItem|EndTracking|AddItem)|WillSendAction)|S(?:ystemColorsDidChange|plitView(?:DidResizeSubviews|WillResizeSubviews))|C(?:o(?:nt(?:extHelpModeDid(?:Deactivate|Activate)|rolT(?:intDidChange|extDid(?:BeginEditing|Change|EndEditing)))|lor(?:PanelColorDidChange|ListDidChange)|mboBox(?:Selection(?:IsChanging|DidChange)|Will(?:Dismiss|PopUp)))|lassDescriptionNeededForClass)|T(?:oolbar(?:DidRemoveItem|WillAddItem)|ext(?:Storage(?:DidProcessEditing|WillProcessEditing)|Did(?:BeginEditing|Change|EndEditing)|View(?:DidChange(?:Selection|TypingAttributes)|WillChangeNotifyingTextView))|ableView(?:Selection(?:IsChanging|DidChange)|ColumnDid(?:Resize|Move)))|ImageRepRegistryDidChange|OutlineView(?:Selection(?:IsChanging|DidChange)|ColumnDid(?:Resize|Move)|Item(?:Did(?:Collapse|Expand)|Will(?:Collapse|Expand)))|Drawer(?:Did(?:Close|Open)|Will(?:Close|Open))|PopUpButton(?:CellWillPopUp|WillPopUp)|View(?:GlobalFrameDidChange|BoundsDidChange|F(?:ocusDidChange|rameDidChange))|FontSetChanged|W(?:indow(?:Did(?:Resi(?:ze|gn(?:Main|Key))|M(?:iniaturize|ove)|Become(?:Main|Key)|ChangeScreen(?:|Profile)|Deminiaturize|Update|E(?:ndSheet|xpose))|Will(?:M(?:iniaturize|ove)|BeginSheet|Close))|orkspace(?:SessionDid(?:ResignActive|BecomeActive)|Did(?:Mount|TerminateApplication|Unmount|PerformFileOperation|Wake|LaunchApplication)|Will(?:Sleep|Unmount|PowerOff|LaunchApplication)))|A(?:ntialiasThresholdChanged|ppl(?:ication(?:Did(?:ResignActive|BecomeActive|Hide|ChangeScreenParameters|U(?:nhide|pdate)|FinishLaunching)|Will(?:ResignActive|BecomeActive|Hide|Terminate|U(?:nhide|pdate)|FinishLaunching))|eEventManagerWillProcessFirstEvent)))Notification)(?:\\b)"},{token:["support.constant.cocoa.leopard"],regex:"(?:\\b)(NS(?:RuleEditor(?:RowType(?:Simple|Compound)|NestingMode(?:Si(?:ngle|mple)|Compound|List))|GradientDraws(?:BeforeStartingLocation|AfterEndingLocation)|M(?:inusSetExpressionType|a(?:chPortDeallocate(?:ReceiveRight|SendRight|None)|pTable(?:StrongMemory|CopyIn|ZeroingWeakMemory|ObjectPointerPersonality)))|B(?:oxCustom|undleExecutableArchitecture(?:X86|I386|PPC(?:64)?)|etweenPredicateOperatorType|ackgroundStyle(?:Raised|Dark|L(?:ight|owered)))|S(?:tring(?:DrawingTruncatesLastVisibleLine|EncodingConversion(?:ExternalRepresentation|AllowLossy))|ubqueryExpressionType|p(?:e(?:ech(?:SentenceBoundary|ImmediateBoundary|WordBoundary)|llingState(?:GrammarFlag|SpellingFlag))|litViewDividerStyleThi(?:n|ck))|e(?:rvice(?:RequestTimedOutError|M(?:iscellaneousError|alformedServiceDictionaryError)|InvalidPasteboardDataError|ErrorM(?:inimum|aximum)|Application(?:NotFoundError|LaunchFailedError))|gmentStyle(?:Round(?:Rect|ed)|SmallSquare|Capsule|Textured(?:Rounded|Square)|Automatic)))|H(?:UDWindowMask|ashTable(?:StrongMemory|CopyIn|ZeroingWeakMemory|ObjectPointerPersonality))|N(?:oModeColorPanel|etServiceNoAutoRename)|C(?:hangeRedone|o(?:ntainsPredicateOperatorType|l(?:orRenderingIntent(?:RelativeColorimetric|Saturation|Default|Perceptual|AbsoluteColorimetric)|lectorDisabledOption))|ellHit(?:None|ContentArea|TrackableArea|EditableTextArea))|T(?:imeZoneNameStyle(?:S(?:hort(?:Standard|DaylightSaving)|tandard)|DaylightSaving)|extFieldDatePickerStyle|ableViewSelectionHighlightStyle(?:Regular|SourceList)|racking(?:Mouse(?:Moved|EnteredAndExited)|CursorUpdate|InVisibleRect|EnabledDuringMouseDrag|A(?:ssumeInside|ctive(?:In(?:KeyWindow|ActiveApp)|WhenFirstResponder|Always))))|I(?:n(?:tersectSetExpressionType|dexedColorSpaceModel)|mageScale(?:None|Proportionally(?:Down|UpOrDown)|AxesIndependently))|Ope(?:nGLPFAAllowOfflineRenderers|rationQueue(?:DefaultMaxConcurrentOperationCount|Priority(?:High|Normal|Very(?:High|Low)|Low)))|D(?:iacriticInsensitiveSearch|ownloadsDirectory)|U(?:nionSetExpressionType|TF(?:16(?:BigEndianStringEncoding|StringEncoding|LittleEndianStringEncoding)|32(?:BigEndianStringEncoding|StringEncoding|LittleEndianStringEncoding)))|P(?:ointerFunctions(?:Ma(?:chVirtualMemory|llocMemory)|Str(?:ongMemory|uctPersonality)|C(?:StringPersonality|opyIn)|IntegerPersonality|ZeroingWeakMemory|O(?:paque(?:Memory|Personality)|bjectP(?:ointerPersonality|ersonality)))|at(?:hStyle(?:Standard|NavigationBar|PopUp)|ternColorSpaceModel)|rintPanelShows(?:Scaling|Copies|Orientation|P(?:a(?:perSize|ge(?:Range|SetupAccessory))|review)))|Executable(?:RuntimeMismatchError|NotLoadableError|ErrorM(?:inimum|aximum)|L(?:inkError|oadError)|ArchitectureMismatchError)|KeyValueObservingOption(?:Initial|Prior)|F(?:i(?:ndPanelSubstringMatchType(?:StartsWith|Contains|EndsWith|FullWord)|leRead(?:TooLargeError|UnknownStringEncodingError))|orcedOrderingSearch)|Wi(?:ndow(?:BackingLocation(?:MainMemory|Default|VideoMemory)|Sharing(?:Read(?:Only|Write)|None)|CollectionBehavior(?:MoveToActiveSpace|CanJoinAllSpaces|Default))|dthInsensitiveSearch)|AggregateExpressionType))(?:\\b)"},{token:["support.constant.cocoa"],regex:"(?:\\b)(NS(?:R(?:GB(?:ModeColorPanel|ColorSpaceModel)|ight(?:Mouse(?:D(?:own(?:Mask)?|ragged(?:Mask)?)|Up(?:Mask)?)|T(?:ext(?:Movement|Alignment)|ab(?:sBezelBorder|StopType))|ArrowFunctionKey)|ound(?:RectBezelStyle|Bankers|ed(?:BezelStyle|TokenStyle|DisclosureBezelStyle)|Down|Up|Plain|Line(?:CapStyle|JoinStyle))|un(?:StoppedResponse|ContinuesResponse|AbortedResponse)|e(?:s(?:izableWindowMask|et(?:CursorRectsRunLoopOrdering|FunctionKey))|ce(?:ssedBezelStyle|iver(?:sCantHandleCommandScriptError|EvaluationScriptError))|turnTextMovement|doFunctionKey|quiredArgumentsMissingScriptError|l(?:evancyLevelIndicatorStyle|ative(?:Before|After))|gular(?:SquareBezelStyle|ControlSize)|moveTraitFontAction)|a(?:n(?:domSubelement|geDateMode)|tingLevelIndicatorStyle|dio(?:ModeMatrix|Button)))|G(?:IFFileType|lyph(?:Below|Inscribe(?:B(?:elow|ase)|Over(?:strike|Below)|Above)|Layout(?:WithPrevious|A(?:tAPoint|gainstAPoint))|A(?:ttribute(?:BidiLevel|Soft|Inscribe|Elastic)|bove))|r(?:ooveBorder|eaterThan(?:Comparison|OrEqualTo(?:Comparison|PredicateOperatorType)|PredicateOperatorType)|a(?:y(?:ModeColorPanel|ColorSpaceModel)|dient(?:None|Con(?:cave(?:Strong|Weak)|vex(?:Strong|Weak)))|phiteControlTint)))|XML(?:N(?:o(?:tationDeclarationKind|de(?:CompactEmptyElement|IsCDATA|OptionsNone|Use(?:SingleQuotes|DoubleQuotes)|Pre(?:serve(?:NamespaceOrder|C(?:haracterReferences|DATA)|DTD|Prefixes|E(?:ntities|mptyElements)|Quotes|Whitespace|A(?:ttributeOrder|ll))|ttyPrint)|ExpandEmptyElement))|amespaceKind)|CommentKind|TextKind|InvalidKind|D(?:ocument(?:X(?:MLKind|HTMLKind|Include)|HTMLKind|T(?:idy(?:XML|HTML)|extKind)|IncludeContentTypeDeclaration|Validate|Kind)|TDKind)|P(?:arser(?:GTRequiredError|XMLDeclNot(?:StartedError|FinishedError)|Mi(?:splaced(?:XMLDeclarationError|CDATAEndStringError)|xedContentDeclNot(?:StartedError|FinishedError))|S(?:t(?:andaloneValueError|ringNot(?:StartedError|ClosedError))|paceRequiredError|eparatorRequiredError)|N(?:MTOKENRequiredError|o(?:t(?:ationNot(?:StartedError|FinishedError)|WellBalancedError)|DTDError)|amespaceDeclarationError|AMERequiredError)|C(?:haracterRef(?:In(?:DTDError|PrologError|EpilogError)|AtEOFError)|o(?:nditionalSectionNot(?:StartedError|FinishedError)|mment(?:NotFinishedError|ContainsDoubleHyphenError))|DATANotFinishedError)|TagNameMismatchError|In(?:ternalError|valid(?:HexCharacterRefError|C(?:haracter(?:RefError|InEntityError|Error)|onditionalSectionError)|DecimalCharacterRefError|URIError|Encoding(?:NameError|Error)))|OutOfMemoryError|D(?:ocumentStartError|elegateAbortedParseError|OCTYPEDeclNotFinishedError)|U(?:RI(?:RequiredError|FragmentError)|n(?:declaredEntityError|parsedEntityError|knownEncodingError|finishedTagError))|P(?:CDATARequiredError|ublicIdentifierRequiredError|arsedEntityRef(?:MissingSemiError|NoNameError|In(?:Internal(?:SubsetError|Error)|PrologError|EpilogError)|AtEOFError)|r(?:ocessingInstructionNot(?:StartedError|FinishedError)|ematureDocumentEndError))|E(?:n(?:codingNotSupportedError|tity(?:Ref(?:In(?:DTDError|PrologError|EpilogError)|erence(?:MissingSemiError|WithoutNameError)|LoopError|AtEOFError)|BoundaryError|Not(?:StartedError|FinishedError)|Is(?:ParameterError|ExternalError)|ValueRequiredError))|qualExpectedError|lementContentDeclNot(?:StartedError|FinishedError)|xt(?:ernalS(?:tandaloneEntityError|ubsetNotFinishedError)|raContentError)|mptyDocumentError)|L(?:iteralNot(?:StartedError|FinishedError)|T(?:RequiredError|SlashRequiredError)|essThanSymbolInAttributeError)|Attribute(?:RedefinedError|HasNoValueError|Not(?:StartedError|FinishedError)|ListNot(?:StartedError|FinishedError)))|rocessingInstructionKind)|E(?:ntity(?:GeneralKind|DeclarationKind|UnparsedKind|P(?:ar(?:sedKind|ameterKind)|redefined))|lement(?:Declaration(?:MixedKind|UndefinedKind|E(?:lementKind|mptyKind)|Kind|AnyKind)|Kind))|Attribute(?:N(?:MToken(?:sKind|Kind)|otationKind)|CDATAKind|ID(?:Ref(?:sKind|Kind)|Kind)|DeclarationKind|En(?:tit(?:yKind|iesKind)|umerationKind)|Kind))|M(?:i(?:n(?:XEdge|iaturizableWindowMask|YEdge|uteCalendarUnit)|terLineJoinStyle|ddleSubelement|xedState)|o(?:nthCalendarUnit|deSwitchFunctionKey|use(?:Moved(?:Mask)?|E(?:ntered(?:Mask)?|ventSubtype|xited(?:Mask)?))|veToBezierPathElement|mentary(?:ChangeButton|Push(?:Button|InButton)|Light(?:Button)?))|enuFunctionKey|a(?:c(?:intoshInterfaceStyle|OSRomanStringEncoding)|tchesPredicateOperatorType|ppedRead|x(?:XEdge|YEdge))|ACHOperatingSystem)|B(?:MPFileType|o(?:ttomTabsBezelBorder|ldFontMask|rderlessWindowMask|x(?:Se(?:condary|parator)|OldStyle|Primary))|uttLineCapStyle|e(?:zelBorder|velLineJoinStyle|low(?:Bottom|Top)|gin(?:sWith(?:Comparison|PredicateOperatorType)|FunctionKey))|lueControlTint|ack(?:spaceCharacter|tabTextMovement|ingStore(?:Retained|Buffered|Nonretained)|TabCharacter|wardsSearch|groundTab)|r(?:owser(?:NoColumnResizing|UserColumnResizing|AutoColumnResizing)|eakFunctionKey))|S(?:h(?:ift(?:JISStringEncoding|KeyMask)|ow(?:ControlGlyphs|InvisibleGlyphs)|adowlessSquareBezelStyle)|y(?:s(?:ReqFunctionKey|tem(?:D(?:omainMask|efined(?:Mask)?)|FunctionKey))|mbolStringEncoding)|c(?:a(?:nnedOption|le(?:None|ToFit|Proportionally))|r(?:oll(?:er(?:NoPart|Increment(?:Page|Line|Arrow)|Decrement(?:Page|Line|Arrow)|Knob(?:Slot)?|Arrows(?:M(?:inEnd|axEnd)|None|DefaultSetting))|Wheel(?:Mask)?|LockFunctionKey)|eenChangedEventType))|t(?:opFunctionKey|r(?:ingDrawing(?:OneShot|DisableScreenFontSubstitution|Uses(?:DeviceMetrics|FontLeading|LineFragmentOrigin))|eam(?:Status(?:Reading|NotOpen|Closed|Open(?:ing)?|Error|Writing|AtEnd)|Event(?:Has(?:BytesAvailable|SpaceAvailable)|None|OpenCompleted|E(?:ndEncountered|rrorOccurred)))))|i(?:ngle(?:DateMode|UnderlineStyle)|ze(?:DownFontAction|UpFontAction))|olarisOperatingSystem|unOSOperatingSystem|pecialPageOrder|e(?:condCalendarUnit|lect(?:By(?:Character|Paragraph|Word)|i(?:ng(?:Next|Previous)|onAffinity(?:Downstream|Upstream))|edTab|FunctionKey)|gmentSwitchTracking(?:Momentary|Select(?:One|Any)))|quareLineCapStyle|witchButton|ave(?:ToOperation|Op(?:tions(?:Yes|No|Ask)|eration)|AsOperation)|mall(?:SquareBezelStyle|C(?:ontrolSize|apsFontMask)|IconButtonBezelStyle))|H(?:ighlightModeMatrix|SBModeColorPanel|o(?:ur(?:Minute(?:SecondDatePickerElementFlag|DatePickerElementFlag)|CalendarUnit)|rizontalRuler|meFunctionKey)|TTPCookieAcceptPolicy(?:Never|OnlyFromMainDocumentDomain|Always)|e(?:lp(?:ButtonBezelStyle|KeyMask|FunctionKey)|avierFontAction)|PUXOperatingSystem)|Year(?:MonthDa(?:yDatePickerElementFlag|tePickerElementFlag)|CalendarUnit)|N(?:o(?:n(?:StandardCharacterSetFontMask|ZeroWindingRule|activatingPanelMask|LossyASCIIStringEncoding)|Border|t(?:ification(?:SuspensionBehavior(?:Hold|Coalesce|D(?:eliverImmediately|rop))|NoCoalescing|CoalescingOn(?:Sender|Name)|DeliverImmediately|PostToAllSessions)|PredicateType|EqualToPredicateOperatorType)|S(?:cr(?:iptError|ollerParts)|ubelement|pecifierError)|CellMask|T(?:itle|opLevelContainersSpecifierError|abs(?:BezelBorder|NoBorder|LineBorder))|I(?:nterfaceStyle|mage)|UnderlineStyle|FontChangeAction)|u(?:ll(?:Glyph|CellType)|m(?:eric(?:Search|PadKeyMask)|berFormatter(?:Round(?:Half(?:Down|Up|Even)|Ceiling|Down|Up|Floor)|Behavior(?:10|Default)|S(?:cientificStyle|pellOutStyle)|NoStyle|CurrencyStyle|DecimalStyle|P(?:ercentStyle|ad(?:Before(?:Suffix|Prefix)|After(?:Suffix|Prefix))))))|e(?:t(?:Services(?:BadArgumentError|NotFoundError|C(?:ollisionError|ancelledError)|TimeoutError|InvalidError|UnknownError|ActivityInProgress)|workDomainMask)|wlineCharacter|xt(?:StepInterfaceStyle|FunctionKey))|EXTSTEPStringEncoding|a(?:t(?:iveShortGlyphPacking|uralTextAlignment)|rrowFontMask))|C(?:hange(?:ReadOtherContents|GrayCell(?:Mask)?|BackgroundCell(?:Mask)?|Cleared|Done|Undone|Autosaved)|MYK(?:ModeColorPanel|ColorSpaceModel)|ircular(?:BezelStyle|Slider)|o(?:n(?:stantValueExpressionType|t(?:inuousCapacityLevelIndicatorStyle|entsCellMask|ain(?:sComparison|erSpecifierError)|rol(?:Glyph|KeyMask))|densedFontMask)|lor(?:Panel(?:RGBModeMask|GrayModeMask|HSBModeMask|C(?:MYKModeMask|olorListModeMask|ustomPaletteModeMask|rayonModeMask)|WheelModeMask|AllModesMask)|ListModeColorPanel)|reServiceDirectory|m(?:p(?:osite(?:XOR|Source(?:In|O(?:ut|ver)|Atop)|Highlight|C(?:opy|lear)|Destination(?:In|O(?:ut|ver)|Atop)|Plus(?:Darker|Lighter))|ressedFontMask)|mandKeyMask))|u(?:stom(?:SelectorPredicateOperatorType|PaletteModeColorPanel)|r(?:sor(?:Update(?:Mask)?|PointingDevice)|veToBezierPathElement))|e(?:nterT(?:extAlignment|abStopType)|ll(?:State|H(?:ighlighted|as(?:Image(?:Horizontal|OnLeftOrBottom)|OverlappingImage))|ChangesContents|Is(?:Bordered|InsetButton)|Disabled|Editable|LightsBy(?:Gray|Background|Contents)|AllowsMixedState))|l(?:ipPagination|o(?:s(?:ePathBezierPathElement|ableWindowMask)|ckAndCalendarDatePickerStyle)|ear(?:ControlTint|DisplayFunctionKey|LineFunctionKey))|a(?:seInsensitive(?:Search|PredicateOption)|n(?:notCreateScriptCommandError|cel(?:Button|TextMovement))|chesDirectory|lculation(?:NoError|Overflow|DivideByZero|Underflow|LossOfPrecision)|rriageReturnCharacter)|r(?:itical(?:Request|AlertStyle)|ayonModeColorPanel))|T(?:hick(?:SquareBezelStyle|erSquareBezelStyle)|ypesetter(?:Behavior|HorizontalTabAction|ContainerBreakAction|ZeroAdvancementAction|OriginalBehavior|ParagraphBreakAction|WhitespaceAction|L(?:ineBreakAction|atestBehavior))|i(?:ckMark(?:Right|Below|Left|Above)|tledWindowMask|meZoneDatePickerElementFlag)|o(?:olbarItemVisibilityPriority(?:Standard|High|User|Low)|pTabsBezelBorder|ggleButton)|IFF(?:Compression(?:N(?:one|EXT)|CCITTFAX(?:3|4)|OldJPEG|JPEG|PackBits|LZW)|FileType)|e(?:rminate(?:Now|Cancel|Later)|xt(?:Read(?:InapplicableDocumentTypeError|WriteErrorM(?:inimum|aximum))|Block(?:M(?:i(?:nimum(?:Height|Width)|ddleAlignment)|a(?:rgin|ximum(?:Height|Width)))|B(?:o(?:ttomAlignment|rder)|aselineAlignment)|Height|TopAlignment|P(?:ercentageValueType|adding)|Width|AbsoluteValueType)|StorageEdited(?:Characters|Attributes)|CellType|ured(?:RoundedBezelStyle|BackgroundWindowMask|SquareBezelStyle)|Table(?:FixedLayoutAlgorithm|AutomaticLayoutAlgorithm)|Field(?:RoundedBezel|SquareBezel|AndStepperDatePickerStyle)|WriteInapplicableDocumentTypeError|ListPrependEnclosingMarker))|woByteGlyphPacking|ab(?:Character|TextMovement|le(?:tP(?:oint(?:Mask|EventSubtype)?|roximity(?:Mask|EventSubtype)?)|Column(?:NoResizing|UserResizingMask|AutoresizingMask)|View(?:ReverseSequentialColumnAutoresizingStyle|GridNone|S(?:olid(?:HorizontalGridLineMask|VerticalGridLineMask)|equentialColumnAutoresizingStyle)|NoColumnAutoresizing|UniformColumnAutoresizingStyle|FirstColumnOnlyAutoresizingStyle|LastColumnOnlyAutoresizingStyle)))|rackModeMatrix)|I(?:n(?:sert(?:CharFunctionKey|FunctionKey|LineFunctionKey)|t(?:Type|ernalS(?:criptError|pecifierError))|dexSubelement|validIndexSpecifierError|formational(?:Request|AlertStyle)|PredicateOperatorType)|talicFontMask|SO(?:2022JPStringEncoding|Latin(?:1StringEncoding|2StringEncoding))|dentityMappingCharacterCollection|llegalTextMovement|mage(?:R(?:ight|ep(?:MatchesDevice|LoadStatus(?:ReadingHeader|Completed|InvalidData|Un(?:expectedEOF|knownType)|WillNeedAllData)))|Below|C(?:ellType|ache(?:BySize|Never|Default|Always))|Interpolation(?:High|None|Default|Low)|O(?:nly|verlaps)|Frame(?:Gr(?:oove|ayBezel)|Button|None|Photo)|L(?:oadStatus(?:ReadError|C(?:ompleted|ancelled)|InvalidData|UnexpectedEOF)|eft)|A(?:lign(?:Right|Bottom(?:Right|Left)?|Center|Top(?:Right|Left)?|Left)|bove)))|O(?:n(?:State|eByteGlyphPacking|OffButton|lyScrollerArrows)|ther(?:Mouse(?:D(?:own(?:Mask)?|ragged(?:Mask)?)|Up(?:Mask)?)|TextMovement)|SF1OperatingSystem|pe(?:n(?:GL(?:GO(?:Re(?:setLibrary|tainRenderers)|ClearFormatCache|FormatCacheSize)|PFA(?:R(?:obust|endererID)|M(?:inimumPolicy|ulti(?:sample|Screen)|PSafe|aximumPolicy)|BackingStore|S(?:creenMask|te(?:ncilSize|reo)|ingleRenderer|upersample|ample(?:s|Buffers|Alpha))|NoRecovery|C(?:o(?:lor(?:Size|Float)|mpliant)|losestPolicy)|OffScreen|D(?:oubleBuffer|epthSize)|PixelBuffer|VirtualScreenCount|FullScreen|Window|A(?:cc(?:umSize|elerated)|ux(?:Buffers|DepthStencil)|l(?:phaSize|lRenderers))))|StepUnicodeReservedBase)|rationNotSupportedForKeyS(?:criptError|pecifierError))|ffState|KButton|rPredicateType|bjC(?:B(?:itfield|oolType)|S(?:hortType|tr(?:ingType|uctType)|electorType)|NoType|CharType|ObjectType|DoubleType|UnionType|PointerType|VoidType|FloatType|Long(?:Type|longType)|ArrayType))|D(?:i(?:s(?:c(?:losureBezelStyle|reteCapacityLevelIndicatorStyle)|playWindowRunLoopOrdering)|acriticInsensitivePredicateOption|rect(?:Selection|PredicateModifier))|o(?:c(?:ModalWindowMask|ument(?:Directory|ationDirectory))|ubleType|wn(?:TextMovement|ArrowFunctionKey))|e(?:s(?:cendingPageOrder|ktopDirectory)|cimalTabStopType|v(?:ice(?:NColorSpaceModel|IndependentModifierFlagsMask)|eloper(?:Directory|ApplicationDirectory))|fault(?:ControlTint|TokenStyle)|lete(?:Char(?:acter|FunctionKey)|FunctionKey|LineFunctionKey)|moApplicationDirectory)|a(?:yCalendarUnit|teFormatter(?:MediumStyle|Behavior(?:10|Default)|ShortStyle|NoStyle|FullStyle|LongStyle))|ra(?:wer(?:Clos(?:ingState|edState)|Open(?:ingState|State))|gOperation(?:Generic|Move|None|Copy|Delete|Private|Every|Link|All)))|U(?:ser(?:CancelledError|D(?:irectory|omainMask)|FunctionKey)|RL(?:Handle(?:NotLoaded|Load(?:Succeeded|InProgress|Failed))|CredentialPersistence(?:None|Permanent|ForSession))|n(?:scaledWindowMask|cachedRead|i(?:codeStringEncoding|talicFontMask|fiedTitleAndToolbarWindowMask)|d(?:o(?:CloseGroupingRunLoopOrdering|FunctionKey)|e(?:finedDateComponent|rline(?:Style(?:Single|None|Thick|Double)|Pattern(?:Solid|D(?:ot|ash(?:Dot(?:Dot)?)?)))))|known(?:ColorSpaceModel|P(?:ointingDevice|ageOrder)|KeyS(?:criptError|pecifierError))|boldFontMask)|tilityWindowMask|TF8StringEncoding|p(?:dateWindowsRunLoopOrdering|TextMovement|ArrowFunctionKey))|J(?:ustifiedTextAlignment|PEG(?:2000FileType|FileType)|apaneseEUC(?:GlyphPacking|StringEncoding))|P(?:o(?:s(?:t(?:Now|erFontMask|WhenIdle|ASAP)|iti(?:on(?:Replace|Be(?:fore|ginning)|End|After)|ve(?:IntType|DoubleType|FloatType)))|pUp(?:NoArrow|ArrowAt(?:Bottom|Center))|werOffEventType|rtraitOrientation)|NGFileType|ush(?:InCell(?:Mask)?|OnPushOffButton)|e(?:n(?:TipMask|UpperSideMask|PointingDevice|LowerSideMask)|riodic(?:Mask)?)|P(?:S(?:caleField|tatus(?:Title|Field)|aveButton)|N(?:ote(?:Title|Field)|ame(?:Title|Field))|CopiesField|TitleField|ImageButton|OptionsButton|P(?:a(?:perFeedButton|ge(?:Range(?:To|From)|ChoiceMatrix))|reviewButton)|LayoutButton)|lainTextTokenStyle|a(?:useFunctionKey|ragraphSeparatorCharacter|ge(?:DownFunctionKey|UpFunctionKey))|r(?:int(?:ing(?:ReplyLater|Success|Cancelled|Failure)|ScreenFunctionKey|erTable(?:NotFound|OK|Error)|FunctionKey)|o(?:p(?:ertyList(?:XMLFormat|MutableContainers(?:AndLeaves)?|BinaryFormat|Immutable|OpenStepFormat)|rietaryStringEncoding)|gressIndicator(?:BarStyle|SpinningStyle|Preferred(?:SmallThickness|Thickness|LargeThickness|AquaThickness)))|e(?:ssedTab|vFunctionKey))|L(?:HeightForm|CancelButton|TitleField|ImageButton|O(?:KButton|rientationMatrix)|UnitsButton|PaperNameButton|WidthForm))|E(?:n(?:terCharacter|d(?:sWith(?:Comparison|PredicateOperatorType)|FunctionKey))|v(?:e(?:nOddWindingRule|rySubelement)|aluatedObjectExpressionType)|qualTo(?:Comparison|PredicateOperatorType)|ra(?:serPointingDevice|CalendarUnit|DatePickerElementFlag)|x(?:clude(?:10|QuickDrawElementsIconCreationOption)|pandedFontMask|ecuteFunctionKey))|V(?:i(?:ew(?:M(?:in(?:XMargin|YMargin)|ax(?:XMargin|YMargin))|HeightSizable|NotSizable|WidthSizable)|aPanelFontAction)|erticalRuler|a(?:lidationErrorM(?:inimum|aximum)|riableExpressionType))|Key(?:SpecifierEvaluationScriptError|Down(?:Mask)?|Up(?:Mask)?|PathExpressionType|Value(?:MinusSetMutation|SetSetMutation|Change(?:Re(?:placement|moval)|Setting|Insertion)|IntersectSetMutation|ObservingOption(?:New|Old)|UnionSetMutation|ValidationError))|QTMovie(?:NormalPlayback|Looping(?:BackAndForthPlayback|Playback))|F(?:1(?:1FunctionKey|7FunctionKey|2FunctionKey|8FunctionKey|3FunctionKey|9FunctionKey|4FunctionKey|5FunctionKey|FunctionKey|0FunctionKey|6FunctionKey)|7FunctionKey|i(?:nd(?:PanelAction(?:Replace(?:A(?:ndFind|ll(?:InSelection)?))?|S(?:howFindPanel|e(?:tFindString|lectAll(?:InSelection)?))|Next|Previous)|FunctionKey)|tPagination|le(?:Read(?:No(?:SuchFileError|PermissionError)|CorruptFileError|In(?:validFileNameError|applicableStringEncodingError)|Un(?:supportedSchemeError|knownError))|HandlingPanel(?:CancelButton|OKButton)|NoSuchFileError|ErrorM(?:inimum|aximum)|Write(?:NoPermissionError|In(?:validFileNameError|applicableStringEncodingError)|OutOfSpaceError|Un(?:supportedSchemeError|knownError))|LockingError)|xedPitchFontMask)|2(?:1FunctionKey|7FunctionKey|2FunctionKey|8FunctionKey|3FunctionKey|9FunctionKey|4FunctionKey|5FunctionKey|FunctionKey|0FunctionKey|6FunctionKey)|o(?:nt(?:Mo(?:noSpaceTrait|dernSerifsClass)|BoldTrait|S(?:ymbolicClass|criptsClass|labSerifsClass|ansSerifClass)|C(?:o(?:ndensedTrait|llectionApplicationOnlyMask)|larendonSerifsClass)|TransitionalSerifsClass|I(?:ntegerAdvancementsRenderingMode|talicTrait)|O(?:ldStyleSerifsClass|rnamentalsClass)|DefaultRenderingMode|U(?:nknownClass|IOptimizedTrait)|Panel(?:S(?:hadowEffectModeMask|t(?:andardModesMask|rikethroughEffectModeMask)|izeModeMask)|CollectionModeMask|TextColorEffectModeMask|DocumentColorEffectModeMask|UnderlineEffectModeMask|FaceModeMask|All(?:ModesMask|EffectsModeMask))|ExpandedTrait|VerticalTrait|F(?:amilyClassMask|reeformSerifsClass)|Antialiased(?:RenderingMode|IntegerAdvancementsRenderingMode))|cusRing(?:Below|Type(?:None|Default|Exterior)|Only|Above)|urByteGlyphPacking|rm(?:attingError(?:M(?:inimum|aximum))?|FeedCharacter))|8FunctionKey|unction(?:ExpressionType|KeyMask)|3(?:1FunctionKey|2FunctionKey|3FunctionKey|4FunctionKey|5FunctionKey|FunctionKey|0FunctionKey)|9FunctionKey|4FunctionKey|P(?:RevertButton|S(?:ize(?:Title|Field)|etButton)|CurrentField|Preview(?:Button|Field))|l(?:oat(?:ingPointSamplesBitmapFormat|Type)|agsChanged(?:Mask)?)|axButton|5FunctionKey|6FunctionKey)|W(?:heelModeColorPanel|indow(?:s(?:NTOperatingSystem|CP125(?:1StringEncoding|2StringEncoding|3StringEncoding|4StringEncoding|0StringEncoding)|95(?:InterfaceStyle|OperatingSystem))|M(?:iniaturizeButton|ovedEventType)|Below|CloseButton|ToolbarButton|ZoomButton|Out|DocumentIconButton|ExposedEventType|Above)|orkspaceLaunch(?:NewInstance|InhibitingBackgroundOnly|Default|PreferringClassic|WithoutA(?:ctivation|ddingToRecents)|A(?:sync|nd(?:Hide(?:Others)?|Print)|llowingClassicStartup))|eek(?:day(?:CalendarUnit|OrdinalCalendarUnit)|CalendarUnit)|a(?:ntsBidiLevels|rningAlertStyle)|r(?:itingDirection(?:RightToLeft|Natural|LeftToRight)|apCalendarComponents))|L(?:i(?:stModeMatrix|ne(?:Moves(?:Right|Down|Up|Left)|B(?:order|reakBy(?:C(?:harWrapping|lipping)|Truncating(?:Middle|Head|Tail)|WordWrapping))|S(?:eparatorCharacter|weep(?:Right|Down|Up|Left))|ToBezierPathElement|DoesntMove|arSlider)|teralSearch|kePredicateOperatorType|ghterFontAction|braryDirectory)|ocalDomainMask|e(?:ssThan(?:Comparison|OrEqualTo(?:Comparison|PredicateOperatorType)|PredicateOperatorType)|ft(?:Mouse(?:D(?:own(?:Mask)?|ragged(?:Mask)?)|Up(?:Mask)?)|T(?:ext(?:Movement|Alignment)|ab(?:sBezelBorder|StopType))|ArrowFunctionKey))|a(?:yout(?:RightToLeft|NotDone|CantFit|OutOfGlyphs|Done|LeftToRight)|ndscapeOrientation)|ABColorSpaceModel)|A(?:sc(?:iiWithDoubleByteEUCGlyphPacking|endingPageOrder)|n(?:y(?:Type|PredicateModifier|EventMask)|choredSearch|imation(?:Blocking|Nonblocking(?:Threaded)?|E(?:ffect(?:DisappearingItemDefault|Poof)|ase(?:In(?:Out)?|Out))|Linear)|dPredicateType)|t(?:Bottom|tachmentCharacter|omicWrite|Top)|SCIIStringEncoding|d(?:obe(?:GB1CharacterCollection|CNS1CharacterCollection|Japan(?:1CharacterCollection|2CharacterCollection)|Korea1CharacterCollection)|dTraitFontAction|minApplicationDirectory)|uto(?:saveOperation|Pagination)|pp(?:lication(?:SupportDirectory|D(?:irectory|e(?:fined(?:Mask)?|legateReply(?:Success|Cancel|Failure)|activatedEventType))|ActivatedEventType)|KitDefined(?:Mask)?)|l(?:ternateKeyMask|pha(?:ShiftKeyMask|NonpremultipliedBitmapFormat|FirstBitmapFormat)|ert(?:SecondButtonReturn|ThirdButtonReturn|OtherReturn|DefaultReturn|ErrorReturn|FirstButtonReturn|AlternateReturn)|l(?:ScrollerParts|DomainsMask|PredicateModifier|LibrariesDirectory|ApplicationsDirectory))|rgument(?:sWrongScriptError|EvaluationScriptError)|bove(?:Bottom|Top)|WTEventType)))(?:\\b)"},{token:"support.function.C99.c",regex:s.cFunctions},{token:n.getKeywords(),regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.section.scope.begin.objc",regex:"\\[",next:"bracketed_content"},{token:"meta.function.objc",regex:"^(?:-|\\+)\\s*"}],constant_NSString:[{token:"constant.character.escape.objc",regex:e},{token:"invalid.illegal.unknown-escape.objc",regex:"\\\\."},{token:"string",regex:'[^"\\\\]+'},{token:"punctuation.definition.string.end",regex:'"',next:"start"}],protocol_list:[{token:"punctuation.section.scope.end.objc",regex:">",next:"start"},{token:"support.other.protocol.objc",regex:"\bNS(?:GlyphStorage|M(?:utableCopying|enuItem)|C(?:hangeSpelling|o(?:ding|pying|lorPicking(?:Custom|Default)))|T(?:oolbarItemValidations|ext(?:Input|AttachmentCell))|I(?:nputServ(?:iceProvider|erMouseTracker)|gnoreMisspelledWords)|Obj(?:CTypeSerializationCallBack|ect)|D(?:ecimalNumberBehaviors|raggingInfo)|U(?:serInterfaceValidations|RL(?:HandleClient|DownloadDelegate|ProtocolClient|AuthenticationChallengeSender))|Validated(?:ToobarItem|UserInterfaceItem)|Locking)\b"}],selectors:[{token:"support.function.any-method.name-of-parameter.objc",regex:"\\b(?:[a-zA-Z_:][\\w]*)+"},{token:"punctuation",regex:"\\)",next:"start"}],bracketed_content:[{token:"punctuation.section.scope.end.objc",regex:"]",next:"start"},{token:["support.function.any-method.objc"],regex:"(?:predicateWithFormat:| NSPredicate predicateWithFormat:)",next:"start"},{token:"support.function.any-method.objc",regex:"\\w+(?::|(?=]))",next:"start"}],bracketed_strings:[{token:"punctuation.section.scope.end.objc",regex:"]",next:"start"},{token:"keyword.operator.logical.predicate.cocoa",regex:"\\b(?:AND|OR|NOT|IN)\\b"},{token:["invalid.illegal.unknown-method.objc","punctuation.separator.arguments.objc"],regex:"\\b(w+)(:)"},{regex:"\\b(?:ALL|ANY|SOME|NONE)\\b",token:"constant.language.predicate.cocoa"},{regex:"\\b(?:NULL|NIL|SELF|TRUE|YES|FALSE|NO|FIRST|LAST|SIZE)\\b",token:"constant.language.predicate.cocoa"},{regex:"\\b(?:MATCHES|CONTAINS|BEGINSWITH|ENDSWITH|BETWEEN)\\b",token:"keyword.operator.comparison.predicate.cocoa"},{regex:"\\bC(?:ASEINSENSITIVE|I)\\b",token:"keyword.other.modifier.predicate.cocoa"},{regex:"\\b(?:ANYKEY|SUBQUERY|CAST|TRUEPREDICATE|FALSEPREDICATE)\\b",token:"keyword.other.predicate.cocoa"},{regex:e,token:"constant.character.escape.objc"},{regex:"\\\\.",token:"invalid.illegal.unknown-escape.objc"},{token:"string",regex:'[^"\\\\]'},{token:"punctuation.definition.string.end.objc",regex:'"',next:"predicates"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],methods:[{token:"meta.function.objc",regex:"(?=\\{|#)|;",next:"start"}]};for(var u in r)this.$rules[u]?this.$rules[u].push&&this.$rules[u].push.apply(this.$rules[u],r[u]):this.$rules[u]=r[u];this.$rules.bracketed_content=this.$rules.bracketed_content.concat(this.$rules.start,t),this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(u,o),t.ObjectiveCHighlightRules=u}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/objectivec",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/objectivec_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./objectivec_highlight_rules").ObjectiveCHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/objectivec"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-ocaml.js b/dist/assets/js/vendor/ace-nc/mode-ocaml.js
            new file mode 100644
            index 0000000000..9c5a92db66
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-ocaml.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/ocaml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|object|of|open|or|private|rec|sig|struct|then|to|try|type|val|virtual|when|while|with",t="true|false",n="abs|abs_big_int|abs_float|abs_num|abstract_tag|accept|access|acos|add|add_available_units|add_big_int|add_buffer|add_channel|add_char|add_initializer|add_int_big_int|add_interfaces|add_num|add_string|add_substitute|add_substring|alarm|allocated_bytes|allow_only|allow_unsafe_modules|always|append|appname_get|appname_set|approx_num_exp|approx_num_fix|arg|argv|arith_status|array|array1_of_genarray|array2_of_genarray|array3_of_genarray|asin|asr|assoc|assq|at_exit|atan|atan2|auto_synchronize|background|basename|beginning_of_input|big_int_of_int|big_int_of_num|big_int_of_string|bind|bind_class|bind_tag|bits|bits_of_float|black|blit|blit_image|blue|bool|bool_of_string|bounded_full_split|bounded_split|bounded_split_delim|bprintf|break|broadcast|bscanf|button_down|c_layout|capitalize|cardinal|cardinal|catch|catch_break|ceil|ceiling_num|channel|char|char_of_int|chdir|check|check_suffix|chmod|choose|chop_extension|chop_suffix|chown|chown|chr|chroot|classify_float|clear|clear_available_units|clear_close_on_exec|clear_graph|clear_nonblock|clear_parser|close|close|closeTk|close_box|close_graph|close_in|close_in_noerr|close_out|close_out_noerr|close_process|close_process|close_process_full|close_process_in|close_process_out|close_subwindow|close_tag|close_tbox|closedir|closedir|closure_tag|code|combine|combine|combine|command|compact|compare|compare_big_int|compare_num|complex32|complex64|concat|conj|connect|contains|contains_from|contents|copy|cos|cosh|count|count|counters|create|create_alarm|create_image|create_matrix|create_matrix|create_matrix|create_object|create_object_and_run_initializers|create_object_opt|create_process|create_process|create_process_env|create_process_env|create_table|current|current_dir_name|current_point|current_x|current_y|curveto|custom_tag|cyan|data_size|decr|decr_num|default_available_units|delay|delete_alarm|descr_of_in_channel|descr_of_out_channel|destroy|diff|dim|dim1|dim2|dim3|dims|dirname|display_mode|div|div_big_int|div_num|double_array_tag|double_tag|draw_arc|draw_char|draw_circle|draw_ellipse|draw_image|draw_poly|draw_poly_line|draw_rect|draw_segments|draw_string|dummy_pos|dummy_table|dump_image|dup|dup2|elements|empty|end_of_input|environment|eprintf|epsilon_float|eq_big_int|eq_num|equal|err_formatter|error_message|escaped|establish_server|executable_name|execv|execve|execvp|execvpe|exists|exists2|exit|exp|failwith|fast_sort|fchmod|fchown|field|file|file_exists|fill|fill_arc|fill_circle|fill_ellipse|fill_poly|fill_rect|filter|final_tag|finalise|find|find_all|first_chars|firstkey|flatten|float|float32|float64|float_of_big_int|float_of_bits|float_of_int|float_of_num|float_of_string|floor|floor_num|flush|flush_all|flush_input|flush_str_formatter|fold|fold_left|fold_left2|fold_right|fold_right2|for_all|for_all2|force|force_newline|force_val|foreground|fork|format_of_string|formatter_of_buffer|formatter_of_out_channel|fortran_layout|forward_tag|fprintf|frexp|from|from_channel|from_file|from_file_bin|from_function|from_string|fscanf|fst|fstat|ftruncate|full_init|full_major|full_split|gcd_big_int|ge_big_int|ge_num|genarray_of_array1|genarray_of_array2|genarray_of_array3|get|get_all_formatter_output_functions|get_approx_printing|get_copy|get_ellipsis_text|get_error_when_null_denominator|get_floating_precision|get_formatter_output_functions|get_formatter_tag_functions|get_image|get_margin|get_mark_tags|get_max_boxes|get_max_indent|get_method|get_method_label|get_normalize_ratio|get_normalize_ratio_when_printing|get_print_tags|get_state|get_variable|getcwd|getegid|getegid|getenv|getenv|getenv|geteuid|geteuid|getgid|getgid|getgrgid|getgrgid|getgrnam|getgrnam|getgroups|gethostbyaddr|gethostbyname|gethostname|getitimer|getlogin|getpeername|getpid|getppid|getprotobyname|getprotobynumber|getpwnam|getpwuid|getservbyname|getservbyport|getsockname|getsockopt|getsockopt_float|getsockopt_int|getsockopt_optint|gettimeofday|getuid|global_replace|global_substitute|gmtime|green|grid|group_beginning|group_end|gt_big_int|gt_num|guard|handle_unix_error|hash|hash_param|hd|header_size|i|id|ignore|in_channel_length|in_channel_of_descr|incr|incr_num|index|index_from|inet_addr_any|inet_addr_of_string|infinity|infix_tag|init|init_class|input|input_binary_int|input_byte|input_char|input_line|input_value|int|int16_signed|int16_unsigned|int32|int64|int8_signed|int8_unsigned|int_of_big_int|int_of_char|int_of_float|int_of_num|int_of_string|integer_num|inter|interactive|inv|invalid_arg|is_block|is_empty|is_implicit|is_int|is_int_big_int|is_integer_num|is_relative|iter|iter2|iteri|join|junk|key_pressed|kill|kind|kprintf|kscanf|land|last_chars|layout|lazy_from_fun|lazy_from_val|lazy_is_val|lazy_tag|ldexp|le_big_int|le_num|length|lexeme|lexeme_char|lexeme_end|lexeme_end_p|lexeme_start|lexeme_start_p|lineto|link|list|listen|lnot|loadfile|loadfile_private|localtime|lock|lockf|log|log10|logand|lognot|logor|logxor|lor|lower_window|lowercase|lseek|lsl|lsr|lstat|lt_big_int|lt_num|lxor|magenta|magic|mainLoop|major|major_slice|make|make_formatter|make_image|make_lexer|make_matrix|make_self_init|map|map2|map_file|mapi|marshal|match_beginning|match_end|matched_group|matched_string|max|max_array_length|max_big_int|max_elt|max_float|max_int|max_num|max_string_length|mem|mem_assoc|mem_assq|memq|merge|min|min_big_int|min_elt|min_float|min_int|min_num|minor|minus_big_int|minus_num|minus_one|mkdir|mkfifo|mktime|mod|mod_big_int|mod_float|mod_num|modf|mouse_pos|moveto|mul|mult_big_int|mult_int_big_int|mult_num|nan|narrow|nat_of_num|nativeint|neg|neg_infinity|new_block|new_channel|new_method|new_variable|next|nextkey|nice|nice|no_scan_tag|norm|norm2|not|npeek|nth|nth_dim|num_digits_big_int|num_dims|num_of_big_int|num_of_int|num_of_nat|num_of_ratio|num_of_string|O|obj|object_tag|ocaml_version|of_array|of_channel|of_float|of_int|of_int32|of_list|of_nativeint|of_string|one|openTk|open_box|open_connection|open_graph|open_hbox|open_hovbox|open_hvbox|open_in|open_in_bin|open_in_gen|open_out|open_out_bin|open_out_gen|open_process|open_process_full|open_process_in|open_process_out|open_subwindow|open_tag|open_tbox|open_temp_file|open_vbox|opendbm|opendir|openfile|or|os_type|out_channel_length|out_channel_of_descr|output|output_binary_int|output_buffer|output_byte|output_char|output_string|output_value|over_max_boxes|pack|params|parent_dir_name|parse|parse_argv|partition|pause|peek|pipe|pixels|place|plot|plots|point_color|polar|poll|pop|pos_in|pos_out|pow|power_big_int_positive_big_int|power_big_int_positive_int|power_int_positive_big_int|power_int_positive_int|power_num|pp_close_box|pp_close_tag|pp_close_tbox|pp_force_newline|pp_get_all_formatter_output_functions|pp_get_ellipsis_text|pp_get_formatter_output_functions|pp_get_formatter_tag_functions|pp_get_margin|pp_get_mark_tags|pp_get_max_boxes|pp_get_max_indent|pp_get_print_tags|pp_open_box|pp_open_hbox|pp_open_hovbox|pp_open_hvbox|pp_open_tag|pp_open_tbox|pp_open_vbox|pp_over_max_boxes|pp_print_as|pp_print_bool|pp_print_break|pp_print_char|pp_print_cut|pp_print_float|pp_print_flush|pp_print_if_newline|pp_print_int|pp_print_newline|pp_print_space|pp_print_string|pp_print_tab|pp_print_tbreak|pp_set_all_formatter_output_functions|pp_set_ellipsis_text|pp_set_formatter_out_channel|pp_set_formatter_output_functions|pp_set_formatter_tag_functions|pp_set_margin|pp_set_mark_tags|pp_set_max_boxes|pp_set_max_indent|pp_set_print_tags|pp_set_tab|pp_set_tags|pred|pred_big_int|pred_num|prerr_char|prerr_endline|prerr_float|prerr_int|prerr_newline|prerr_string|print|print_as|print_bool|print_break|print_char|print_cut|print_endline|print_float|print_flush|print_if_newline|print_int|print_newline|print_space|print_stat|print_string|print_tab|print_tbreak|printf|prohibit|public_method_label|push|putenv|quo_num|quomod_big_int|quote|raise|raise_window|ratio_of_num|rcontains_from|read|read_float|read_int|read_key|read_line|readdir|readdir|readlink|really_input|receive|recv|recvfrom|red|ref|regexp|regexp_case_fold|regexp_string|regexp_string_case_fold|register|register_exception|rem|remember_mode|remove|remove_assoc|remove_assq|rename|replace|replace_first|replace_matched|repr|reset|reshape|reshape_1|reshape_2|reshape_3|rev|rev_append|rev_map|rev_map2|rewinddir|rgb|rhs_end|rhs_end_pos|rhs_start|rhs_start_pos|rindex|rindex_from|rlineto|rmdir|rmoveto|round_num|run_initializers|run_initializers_opt|scanf|search_backward|search_forward|seek_in|seek_out|select|self|self_init|send|sendto|set|set_all_formatter_output_functions|set_approx_printing|set_binary_mode_in|set_binary_mode_out|set_close_on_exec|set_close_on_exec|set_color|set_ellipsis_text|set_error_when_null_denominator|set_field|set_floating_precision|set_font|set_formatter_out_channel|set_formatter_output_functions|set_formatter_tag_functions|set_line_width|set_margin|set_mark_tags|set_max_boxes|set_max_indent|set_method|set_nonblock|set_nonblock|set_normalize_ratio|set_normalize_ratio_when_printing|set_print_tags|set_signal|set_state|set_tab|set_tag|set_tags|set_text_size|set_window_title|setgid|setgid|setitimer|setitimer|setsid|setsid|setsockopt|setsockopt|setsockopt_float|setsockopt_float|setsockopt_int|setsockopt_int|setsockopt_optint|setsockopt_optint|setuid|setuid|shift_left|shift_left|shift_left|shift_right|shift_right|shift_right|shift_right_logical|shift_right_logical|shift_right_logical|show_buckets|shutdown|shutdown|shutdown_connection|shutdown_connection|sigabrt|sigalrm|sigchld|sigcont|sigfpe|sighup|sigill|sigint|sigkill|sign_big_int|sign_num|signal|signal|sigpending|sigpending|sigpipe|sigprocmask|sigprocmask|sigprof|sigquit|sigsegv|sigstop|sigsuspend|sigsuspend|sigterm|sigtstp|sigttin|sigttou|sigusr1|sigusr2|sigvtalrm|sin|singleton|sinh|size|size|size_x|size_y|sleep|sleep|sleep|slice_left|slice_left|slice_left_1|slice_left_2|slice_right|slice_right|slice_right_1|slice_right_2|snd|socket|socket|socket|socketpair|socketpair|sort|sound|split|split_delim|sprintf|sprintf|sqrt|sqrt|sqrt_big_int|square_big_int|square_num|sscanf|stable_sort|stable_sort|stable_sort|stable_sort|stable_sort|stable_sort|stat|stat|stat|stat|stat|stats|stats|std_formatter|stdbuf|stderr|stderr|stderr|stdib|stdin|stdin|stdin|stdout|stdout|stdout|str_formatter|string|string_after|string_before|string_match|string_of_big_int|string_of_bool|string_of_float|string_of_format|string_of_inet_addr|string_of_inet_addr|string_of_int|string_of_num|string_partial_match|string_tag|sub|sub|sub_big_int|sub_left|sub_num|sub_right|subset|subset|substitute_first|substring|succ|succ|succ|succ|succ_big_int|succ_num|symbol_end|symbol_end_pos|symbol_start|symbol_start_pos|symlink|symlink|sync|synchronize|system|system|system|tag|take|tan|tanh|tcdrain|tcdrain|tcflow|tcflow|tcflush|tcflush|tcgetattr|tcgetattr|tcsendbreak|tcsendbreak|tcsetattr|tcsetattr|temp_file|text_size|time|time|time|timed_read|timed_write|times|times|tl|tl|tl|to_buffer|to_channel|to_float|to_hex|to_int|to_int32|to_list|to_list|to_list|to_nativeint|to_string|to_string|to_string|to_string|to_string|top|top|total_size|transfer|transp|truncate|truncate|truncate|truncate|truncate|truncate|try_lock|umask|umask|uncapitalize|uncapitalize|uncapitalize|union|union|unit_big_int|unlink|unlink|unlock|unmarshal|unsafe_blit|unsafe_fill|unsafe_get|unsafe_get|unsafe_set|unsafe_set|update|uppercase|uppercase|uppercase|uppercase|usage|utimes|utimes|wait|wait|wait|wait|wait_next_event|wait_pid|wait_read|wait_signal|wait_timed_read|wait_timed_write|wait_write|waitpid|white|widen|window_id|word_size|wrap|wrap_abort|write|yellow|yield|zero|zero_big_int|Arg|Arith_status|Array|Array1|Array2|Array3|ArrayLabels|Big_int|Bigarray|Buffer|Callback|CamlinternalOO|Char|Complex|Condition|Dbm|Digest|Dynlink|Event|Filename|Format|Gc|Genarray|Genlex|Graphics|GraphicsX11|Hashtbl|Int32|Int64|LargeFile|Lazy|Lexing|List|ListLabels|Make|Map|Marshal|MoreLabels|Mutex|Nativeint|Num|Obj|Oo|Parsing|Pervasives|Printexc|Printf|Queue|Random|Scanf|Scanning|Set|Sort|Stack|State|StdLabels|Str|Stream|String|StringLabels|Sys|Thread|ThreadUnix|Tk|Unix|UnixLabels|Weak",r=this.createKeywordMapper({"variable.language":"this",keyword:e,"constant.language":t,"support.function":n},"identifier"),i="(?:(?:[1-9]\\d*)|(?:0))",s="(?:0[oO]?[0-7]+)",o="(?:0[xX][\\dA-Fa-f]+)",u="(?:0[bB][01]+)",a="(?:"+i+"|"+s+"|"+o+"|"+u+")",f="(?:[eE][+-]?\\d+)",l="(?:\\.\\d+)",c="(?:\\d+)",h="(?:(?:"+c+"?"+l+")|(?:"+c+"\\.))",p="(?:(?:"+h+"|"+c+")"+f+")",d="(?:"+p+"|"+h+")";this.$rules={start:[{token:"comment",regex:"\\(\\*.*?\\*\\)\\s*?$"},{token:"comment",regex:"\\(\\*.*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"'.'"},{token:"string",regex:'"',next:"qstring"},{token:"constant.numeric",regex:"(?:"+d+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:d},{token:"constant.numeric",regex:a+"\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+\\.|\\-\\.|\\*\\.|\\/\\.|#|;;|\\+|\\-|\\*|\\*\\*\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|<-|="},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\)",next:"start"},{token:"comment",regex:".+"}],qstring:[{token:"string",regex:'"',next:"start"},{token:"string",regex:".+"}]}};r.inherits(s,i),t.OcamlHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/ocaml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ocaml_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./ocaml_highlight_rules").OcamlHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=function(){this.HighlightRules=s,this.$outdent=new o};r.inherits(a,i);var f=/(?:[({[=:]|[-=]>|\b(?:else|try|with))\s*$/;(function(){this.toggleCommentLines=function(e,t,n,r){var i,s,o=!0,a=/^\s*\(\*(.*)\*\)/;for(i=n;i<=r;i++)if(!a.test(t.getLine(i))){o=!1;break}var f=new u(0,0,0,0);for(i=n;i<=r;i++)s=t.getLine(i),f.start.row=i,f.end.row=i,f.end.column=s.length,t.replace(f,o?s.match(a)[1]:"(*"+s+"*)")},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;return(!i.length||i[i.length-1].type!=="comment")&&e==="start"&&f.test(t)&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/ocaml"}).call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-pascal.js b/dist/assets/js/vendor/ace-nc/mode-pascal.js
            new file mode 100644
            index 0000000000..b5534398da
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-pascal.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/pascal_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{caseInsensitive:!0,token:"keyword.control.pascal",regex:"\\b(?:(absolute|abstract|all|and|and_then|array|as|asm|attribute|begin|bindable|case|class|const|constructor|destructor|div|do|do|else|end|except|export|exports|external|far|file|finalization|finally|for|forward|goto|if|implementation|import|in|inherited|initialization|interface|interrupt|is|label|library|mod|module|name|near|nil|not|object|of|only|operator|or|or_else|otherwise|packed|pow|private|program|property|protected|public|published|qualified|record|repeat|resident|restricted|segment|set|shl|shr|then|to|try|type|unit|until|uses|value|var|view|virtual|while|with|xor))\\b"},{caseInsensitive:!0,token:["variable.pascal","text","storage.type.prototype.pascal","entity.name.function.prototype.pascal"],regex:"\\b(function|procedure)(\\s+)(\\w+)(\\.\\w+)?(?=(?:\\(.*?\\))?;\\s*(?:attribute|forward|external))"},{caseInsensitive:!0,token:["variable.pascal","text","storage.type.function.pascal","entity.name.function.pascal"],regex:"\\b(function|procedure)(\\s+)(\\w+)(\\.\\w+)?"},{token:"constant.numeric.pascal",regex:"\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"punctuation.definition.comment.pascal",regex:"--.*$",push_:[{token:"comment.line.double-dash.pascal.one",regex:"$",next:"pop"},{defaultToken:"comment.line.double-dash.pascal.one"}]},{token:"punctuation.definition.comment.pascal",regex:"//.*$",push_:[{token:"comment.line.double-slash.pascal.two",regex:"$",next:"pop"},{defaultToken:"comment.line.double-slash.pascal.two"}]},{token:"punctuation.definition.comment.pascal",regex:"\\(\\*",push:[{token:"punctuation.definition.comment.pascal",regex:"\\*\\)",next:"pop"},{defaultToken:"comment.block.pascal.one"}]},{token:"punctuation.definition.comment.pascal",regex:"\\{",push:[{token:"punctuation.definition.comment.pascal",regex:"\\}",next:"pop"},{defaultToken:"comment.block.pascal.two"}]},{token:"punctuation.definition.string.begin.pascal",regex:'"',push:[{token:"constant.character.escape.pascal",regex:"\\\\."},{token:"punctuation.definition.string.end.pascal",regex:'"',next:"pop"},{defaultToken:"string.quoted.double.pascal"}]},{token:"punctuation.definition.string.begin.pascal",regex:"'",push:[{token:"constant.character.escape.apostrophe.pascal",regex:"''"},{token:"punctuation.definition.string.end.pascal",regex:"'",next:"pop"},{defaultToken:"string.quoted.single.pascal"}]},{token:"keyword.operator",regex:"[+\\-;,/*%]|:=|="}]},this.normalizeRules()};r.inherits(s,i),t.PascalHighlightRules=s}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/pascal",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/pascal_highlight_rules","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./pascal_highlight_rules").PascalHighlightRules,o=e("./folding/coffee").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart=["--","//"],this.blockComment=[{start:"(*",end:"*)"},{start:"{",end:"}"}],this.$id="ace/mode/pascal"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-perl.js b/dist/assets/js/vendor/ace-nc/mode-perl.js
            new file mode 100644
            index 0000000000..59b1a77d31
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-perl.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/perl_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="base|constant|continue|else|elsif|for|foreach|format|goto|if|last|local|my|next|no|package|parent|redo|require|scalar|sub|unless|until|while|use|vars",t="ARGV|ENV|INC|SIG",n="getprotobynumber|getprotobyname|getservbyname|gethostbyaddr|gethostbyname|getservbyport|getnetbyaddr|getnetbyname|getsockname|getpeername|setpriority|getprotoent|setprotoent|getpriority|endprotoent|getservent|setservent|endservent|sethostent|socketpair|getsockopt|gethostent|endhostent|setsockopt|setnetent|quotemeta|localtime|prototype|getnetent|endnetent|rewinddir|wantarray|getpwuid|closedir|getlogin|readlink|endgrent|getgrgid|getgrnam|shmwrite|shutdown|readline|endpwent|setgrent|readpipe|formline|truncate|dbmclose|syswrite|setpwent|getpwnam|getgrent|getpwent|ucfirst|sysread|setpgrp|shmread|sysseek|sysopen|telldir|defined|opendir|connect|lcfirst|getppid|binmode|syscall|sprintf|getpgrp|readdir|seekdir|waitpid|reverse|unshift|symlink|dbmopen|semget|msgrcv|rename|listen|chroot|msgsnd|shmctl|accept|unpack|exists|fileno|shmget|system|unlink|printf|gmtime|msgctl|semctl|values|rindex|substr|splice|length|msgget|select|socket|return|caller|delete|alarm|ioctl|index|undef|lstat|times|srand|chown|fcntl|close|write|umask|rmdir|study|sleep|chomp|untie|print|utime|mkdir|atan2|split|crypt|flock|chmod|BEGIN|bless|chdir|semop|shift|reset|link|stat|chop|grep|fork|dump|join|open|tell|pipe|exit|glob|warn|each|bind|sort|pack|eval|push|keys|getc|kill|seek|sqrt|send|wait|rand|tied|read|time|exec|recv|eof|chr|int|ord|exp|pos|pop|sin|log|abs|oct|hex|tie|cos|vec|END|ref|map|die|uc|lc|do",r=this.createKeywordMapper({keyword:e,"constant.language":t,"support.function":n},"identifier");this.$rules={start:[{token:"comment.doc",regex:"^=(?:begin|item)\\b",next:"block_comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0x[0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"%#|\\$#|\\.\\.\\.|\\|\\|=|>>=|<<=|<=>|&&=|=>|!~|\\^=|&=|\\|=|\\.=|x=|%=|\\/=|\\*=|\\-=|\\+=|=~|\\*\\*|\\-\\-|\\.\\.|\\|\\||&&|\\+\\+|\\->|!=|==|>=|<=|>>|<<|,|=|\\?\\:|\\^|\\||x|%|\\/|\\*|<|&|\\\\|~|!|>|\\.|\\-|\\+|\\-C|\\-b|\\-S|\\-u|\\-t|\\-p|\\-l|\\-d|\\-f|\\-g|\\-s|\\-z|\\-k|\\-e|\\-O|\\-T|\\-B|\\-M|\\-A|\\-X|\\-W|\\-c|\\-R|\\-o|\\-x|\\-w|\\-r|\\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)"},{token:"comment",regex:"#.*$"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}],block_comment:[{token:"comment.doc",regex:"^=cut\\b",next:"start"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),t.PerlHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/perl",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/perl_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./perl_highlight_rules").PerlHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./folding/cstyle").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new a({start:"^=(begin|item)\\b",end:"^=(cut)\\b"})};r.inherits(f,i),function(){this.lineCommentStart="#",this.blockComment=[{start:"=begin",end:"=cut"},{start:"=item",end:"=cut"}],this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[\:]\s*$/);o&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/perl"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-pgsql.js b/dist/assets/js/vendor/ace-nc/mode-pgsql.js
            new file mode 100644
            index 0000000000..b7ce6cc5f2
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-pgsql.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/perl_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="base|constant|continue|else|elsif|for|foreach|format|goto|if|last|local|my|next|no|package|parent|redo|require|scalar|sub|unless|until|while|use|vars",t="ARGV|ENV|INC|SIG",n="getprotobynumber|getprotobyname|getservbyname|gethostbyaddr|gethostbyname|getservbyport|getnetbyaddr|getnetbyname|getsockname|getpeername|setpriority|getprotoent|setprotoent|getpriority|endprotoent|getservent|setservent|endservent|sethostent|socketpair|getsockopt|gethostent|endhostent|setsockopt|setnetent|quotemeta|localtime|prototype|getnetent|endnetent|rewinddir|wantarray|getpwuid|closedir|getlogin|readlink|endgrent|getgrgid|getgrnam|shmwrite|shutdown|readline|endpwent|setgrent|readpipe|formline|truncate|dbmclose|syswrite|setpwent|getpwnam|getgrent|getpwent|ucfirst|sysread|setpgrp|shmread|sysseek|sysopen|telldir|defined|opendir|connect|lcfirst|getppid|binmode|syscall|sprintf|getpgrp|readdir|seekdir|waitpid|reverse|unshift|symlink|dbmopen|semget|msgrcv|rename|listen|chroot|msgsnd|shmctl|accept|unpack|exists|fileno|shmget|system|unlink|printf|gmtime|msgctl|semctl|values|rindex|substr|splice|length|msgget|select|socket|return|caller|delete|alarm|ioctl|index|undef|lstat|times|srand|chown|fcntl|close|write|umask|rmdir|study|sleep|chomp|untie|print|utime|mkdir|atan2|split|crypt|flock|chmod|BEGIN|bless|chdir|semop|shift|reset|link|stat|chop|grep|fork|dump|join|open|tell|pipe|exit|glob|warn|each|bind|sort|pack|eval|push|keys|getc|kill|seek|sqrt|send|wait|rand|tied|read|time|exec|recv|eof|chr|int|ord|exp|pos|pop|sin|log|abs|oct|hex|tie|cos|vec|END|ref|map|die|uc|lc|do",r=this.createKeywordMapper({keyword:e,"constant.language":t,"support.function":n},"identifier");this.$rules={start:[{token:"comment.doc",regex:"^=(?:begin|item)\\b",next:"block_comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0x[0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"%#|\\$#|\\.\\.\\.|\\|\\|=|>>=|<<=|<=>|&&=|=>|!~|\\^=|&=|\\|=|\\.=|x=|%=|\\/=|\\*=|\\-=|\\+=|=~|\\*\\*|\\-\\-|\\.\\.|\\|\\||&&|\\+\\+|\\->|!=|==|>=|<=|>>|<<|,|=|\\?\\:|\\^|\\||x|%|\\/|\\*|<|&|\\\\|~|!|>|\\.|\\-|\\+|\\-C|\\-b|\\-S|\\-u|\\-t|\\-p|\\-l|\\-d|\\-f|\\-g|\\-s|\\-z|\\-k|\\-e|\\-O|\\-T|\\-B|\\-M|\\-A|\\-X|\\-W|\\-c|\\-R|\\-o|\\-x|\\-w|\\-r|\\b(?:and|cmp|eq|ge|gt|le|lt|ne|not|or|xor)"},{token:"comment",regex:"#.*$"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}],block_comment:[{token:"comment.doc",regex:"^=cut\\b",next:"start"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),t.PerlHighlightRules=s}),ace.define("ace/mode/python_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield",t="True|False|None|NotImplemented|Ellipsis|__debug__",n="abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern",r=this.createKeywordMapper({"invalid.deprecated":"debugger","support.function":n,"constant.language":t,keyword:e},"identifier"),i="(?:r|u|ur|R|U|UR|Ur|uR)?",s="(?:(?:[1-9]\\d*)|(?:0))",o="(?:0[oO]?[0-7]+)",u="(?:0[xX][\\dA-Fa-f]+)",a="(?:0[bB][01]+)",f="(?:"+s+"|"+o+"|"+u+"|"+a+")",l="(?:[eE][+-]?\\d+)",c="(?:\\.\\d+)",h="(?:\\d+)",p="(?:(?:"+h+"?"+c+")|(?:"+h+"\\.))",d="(?:(?:"+p+"|"+h+")"+l+")",v="(?:"+d+"|"+p+")",m="\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:i+'"{3}',next:"qqstring3"},{token:"string",regex:i+'"(?=.)',next:"qqstring"},{token:"string",regex:i+"'{3}",next:"qstring3"},{token:"string",regex:i+"'(?=.)",next:"qstring"},{token:"constant.numeric",regex:"(?:"+v+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:v},{token:"constant.numeric",regex:f+"[lL]\\b"},{token:"constant.numeric",regex:f+"\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qqstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],qstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}]}};r.inherits(s,i),t.PythonHighlightRules=s}),ace.define("ace/mode/json_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"variable",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)'},{token:"string",regex:'"',next:"string"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:"invalid.illegal",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"invalid.illegal",regex:"\\/\\/.*$"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],string:[{token:"constant.language.escape",regex:/\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/},{token:"string",regex:'[^"\\\\]+'},{token:"string",regex:'"',next:"start"},{token:"string",regex:"",next:"start"}]}};r.inherits(s,i),t.JsonHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/pgsql_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules","ace/mode/perl_highlight_rules","ace/mode/python_highlight_rules","ace/mode/json_highlight_rules","ace/mode/javascript_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./doc_comment_highlight_rules").DocCommentHighlightRules,o=e("./text_highlight_rules").TextHighlightRules,u=e("./perl_highlight_rules").PerlHighlightRules,a=e("./python_highlight_rules").PythonHighlightRules,f=e("./json_highlight_rules").JsonHighlightRules,l=e("./javascript_highlight_rules").JavaScriptHighlightRules,c=function(){var e="abort|absolute|abstime|access|aclitem|action|add|admin|after|aggregate|all|also|alter|always|analyse|analyze|and|any|anyarray|anyelement|anyenum|anynonarray|anyrange|array|as|asc|assertion|assignment|asymmetric|at|attribute|authorization|backward|before|begin|between|bigint|binary|bit|bool|boolean|both|box|bpchar|by|bytea|cache|called|cascade|cascaded|case|cast|catalog|chain|char|character|characteristics|check|checkpoint|cid|cidr|circle|class|close|cluster|coalesce|collate|collation|column|comment|comments|commit|committed|concurrently|configuration|connection|constraint|constraints|content|continue|conversion|copy|cost|create|cross|cstring|csv|current|current_catalog|current_date|current_role|current_schema|current_time|current_timestamp|current_user|cursor|cycle|data|database|date|daterange|day|deallocate|dec|decimal|declare|default|defaults|deferrable|deferred|definer|delete|delimiter|delimiters|desc|dictionary|disable|discard|distinct|do|document|domain|double|drop|each|else|enable|encoding|encrypted|end|enum|escape|event|event_trigger|except|exclude|excluding|exclusive|execute|exists|explain|extension|external|extract|false|family|fdw_handler|fetch|first|float|float4|float8|following|for|force|foreign|forward|freeze|from|full|function|functions|global|grant|granted|greatest|group|gtsvector|handler|having|header|hold|hour|identity|if|ilike|immediate|immutable|implicit|in|including|increment|index|indexes|inet|inherit|inherits|initially|inline|inner|inout|input|insensitive|insert|instead|int|int2|int2vector|int4|int4range|int8|int8range|integer|internal|intersect|interval|into|invoker|is|isnull|isolation|join|json|key|label|language|language_handler|large|last|lateral|lc_collate|lc_ctype|leading|leakproof|least|left|level|like|limit|line|listen|load|local|localtime|localtimestamp|location|lock|lseg|macaddr|mapping|match|materialized|maxvalue|minute|minvalue|mode|money|month|move|name|names|national|natural|nchar|next|no|none|not|nothing|notify|notnull|nowait|null|nullif|nulls|numeric|numrange|object|of|off|offset|oid|oids|oidvector|on|only|opaque|operator|option|options|or|order|out|outer|over|overlaps|overlay|owned|owner|parser|partial|partition|passing|password|path|pg_attribute|pg_auth_members|pg_authid|pg_class|pg_database|pg_node_tree|pg_proc|pg_type|placing|plans|point|polygon|position|preceding|precision|prepare|prepared|preserve|primary|prior|privileges|procedural|procedure|program|quote|range|read|real|reassign|recheck|record|recursive|ref|refcursor|references|refresh|regclass|regconfig|regdictionary|regoper|regoperator|regproc|regprocedure|regtype|reindex|relative|release|reltime|rename|repeatable|replace|replica|reset|restart|restrict|returning|returns|revoke|right|role|rollback|row|rows|rule|savepoint|schema|scroll|search|second|security|select|sequence|sequences|serializable|server|session|session_user|set|setof|share|show|similar|simple|smallint|smgr|snapshot|some|stable|standalone|start|statement|statistics|stdin|stdout|storage|strict|strip|substring|symmetric|sysid|system|table|tables|tablespace|temp|template|temporary|text|then|tid|time|timestamp|timestamptz|timetz|tinterval|to|trailing|transaction|treat|trigger|trim|true|truncate|trusted|tsquery|tsrange|tstzrange|tsvector|txid_snapshot|type|types|unbounded|uncommitted|unencrypted|union|unique|unknown|unlisten|unlogged|until|update|user|using|uuid|vacuum|valid|validate|validator|value|values|varbit|varchar|variadic|varying|verbose|version|view|void|volatile|when|where|whitespace|window|with|without|work|wrapper|write|xid|xml|xmlattributes|xmlconcat|xmlelement|xmlexists|xmlforest|xmlparse|xmlpi|xmlroot|xmlserialize|year|yes|zone",t="RI_FKey_cascade_del|RI_FKey_cascade_upd|RI_FKey_check_ins|RI_FKey_check_upd|RI_FKey_noaction_del|RI_FKey_noaction_upd|RI_FKey_restrict_del|RI_FKey_restrict_upd|RI_FKey_setdefault_del|RI_FKey_setdefault_upd|RI_FKey_setnull_del|RI_FKey_setnull_upd|abbrev|abs|abstime|abstimeeq|abstimege|abstimegt|abstimein|abstimele|abstimelt|abstimene|abstimeout|abstimerecv|abstimesend|aclcontains|acldefault|aclexplode|aclinsert|aclitemeq|aclitemin|aclitemout|aclremove|acos|age|any_in|any_out|anyarray_in|anyarray_out|anyarray_recv|anyarray_send|anyelement_in|anyelement_out|anyenum_in|anyenum_out|anynonarray_in|anynonarray_out|anyrange_in|anyrange_out|anytextcat|area|areajoinsel|areasel|array_agg|array_agg_finalfn|array_agg_transfn|array_append|array_cat|array_dims|array_eq|array_fill|array_ge|array_gt|array_in|array_larger|array_le|array_length|array_lower|array_lt|array_ndims|array_ne|array_out|array_prepend|array_recv|array_remove|array_replace|array_send|array_smaller|array_to_json|array_to_string|array_typanalyze|array_upper|arraycontained|arraycontains|arraycontjoinsel|arraycontsel|arrayoverlap|ascii|ascii_to_mic|ascii_to_utf8|asin|atan|atan2|avg|big5_to_euc_tw|big5_to_mic|big5_to_utf8|bit_and|bit_in|bit_length|bit_or|bit_out|bit_recv|bit_send|bitand|bitcat|bitcmp|biteq|bitge|bitgt|bitle|bitlt|bitne|bitnot|bitor|bitshiftleft|bitshiftright|bittypmodin|bittypmodout|bitxor|bool|bool_and|bool_or|booland_statefunc|booleq|boolge|boolgt|boolin|boolle|boollt|boolne|boolor_statefunc|boolout|boolrecv|boolsend|box|box_above|box_above_eq|box_add|box_below|box_below_eq|box_center|box_contain|box_contain_pt|box_contained|box_distance|box_div|box_eq|box_ge|box_gt|box_in|box_intersect|box_le|box_left|box_lt|box_mul|box_out|box_overabove|box_overbelow|box_overlap|box_overleft|box_overright|box_recv|box_right|box_same|box_send|box_sub|bpchar_larger|bpchar_pattern_ge|bpchar_pattern_gt|bpchar_pattern_le|bpchar_pattern_lt|bpchar_smaller|bpcharcmp|bpchareq|bpcharge|bpchargt|bpchariclike|bpcharicnlike|bpcharicregexeq|bpcharicregexne|bpcharin|bpcharle|bpcharlike|bpcharlt|bpcharne|bpcharnlike|bpcharout|bpcharrecv|bpcharregexeq|bpcharregexne|bpcharsend|bpchartypmodin|bpchartypmodout|broadcast|btabstimecmp|btarraycmp|btbeginscan|btboolcmp|btbpchar_pattern_cmp|btbuild|btbuildempty|btbulkdelete|btcanreturn|btcharcmp|btcostestimate|btendscan|btfloat48cmp|btfloat4cmp|btfloat4sortsupport|btfloat84cmp|btfloat8cmp|btfloat8sortsupport|btgetbitmap|btgettuple|btinsert|btint24cmp|btint28cmp|btint2cmp|btint2sortsupport|btint42cmp|btint48cmp|btint4cmp|btint4sortsupport|btint82cmp|btint84cmp|btint8cmp|btint8sortsupport|btmarkpos|btnamecmp|btnamesortsupport|btoidcmp|btoidsortsupport|btoidvectorcmp|btoptions|btrecordcmp|btreltimecmp|btrescan|btrestrpos|btrim|bttext_pattern_cmp|bttextcmp|bttidcmp|bttintervalcmp|btvacuumcleanup|bytea_string_agg_finalfn|bytea_string_agg_transfn|byteacat|byteacmp|byteaeq|byteage|byteagt|byteain|byteale|bytealike|bytealt|byteane|byteanlike|byteaout|bytearecv|byteasend|cash_cmp|cash_div_cash|cash_div_flt4|cash_div_flt8|cash_div_int2|cash_div_int4|cash_eq|cash_ge|cash_gt|cash_in|cash_le|cash_lt|cash_mi|cash_mul_flt4|cash_mul_flt8|cash_mul_int2|cash_mul_int4|cash_ne|cash_out|cash_pl|cash_recv|cash_send|cash_words|cashlarger|cashsmaller|cbrt|ceil|ceiling|center|char|char_length|character_length|chareq|charge|chargt|charin|charle|charlt|charne|charout|charrecv|charsend|chr|cideq|cidin|cidout|cidr|cidr_in|cidr_out|cidr_recv|cidr_send|cidrecv|cidsend|circle|circle_above|circle_add_pt|circle_below|circle_center|circle_contain|circle_contain_pt|circle_contained|circle_distance|circle_div_pt|circle_eq|circle_ge|circle_gt|circle_in|circle_le|circle_left|circle_lt|circle_mul_pt|circle_ne|circle_out|circle_overabove|circle_overbelow|circle_overlap|circle_overleft|circle_overright|circle_recv|circle_right|circle_same|circle_send|circle_sub_pt|clock_timestamp|close_lb|close_ls|close_lseg|close_pb|close_pl|close_ps|close_sb|close_sl|col_description|concat|concat_ws|contjoinsel|contsel|convert|convert_from|convert_to|corr|cos|cot|count|covar_pop|covar_samp|cstring_in|cstring_out|cstring_recv|cstring_send|cume_dist|current_database|current_query|current_schema|current_schemas|current_setting|current_user|currtid|currtid2|currval|cursor_to_xml|cursor_to_xmlschema|database_to_xml|database_to_xml_and_xmlschema|database_to_xmlschema|date|date_cmp|date_cmp_timestamp|date_cmp_timestamptz|date_eq|date_eq_timestamp|date_eq_timestamptz|date_ge|date_ge_timestamp|date_ge_timestamptz|date_gt|date_gt_timestamp|date_gt_timestamptz|date_in|date_larger|date_le|date_le_timestamp|date_le_timestamptz|date_lt|date_lt_timestamp|date_lt_timestamptz|date_mi|date_mi_interval|date_mii|date_ne|date_ne_timestamp|date_ne_timestamptz|date_out|date_part|date_pl_interval|date_pli|date_recv|date_send|date_smaller|date_sortsupport|date_trunc|daterange|daterange_canonical|daterange_subdiff|datetime_pl|datetimetz_pl|dcbrt|decode|degrees|dense_rank|dexp|diagonal|diameter|dispell_init|dispell_lexize|dist_cpoly|dist_lb|dist_pb|dist_pc|dist_pl|dist_ppath|dist_ps|dist_sb|dist_sl|div|dlog1|dlog10|domain_in|domain_recv|dpow|dround|dsimple_init|dsimple_lexize|dsnowball_init|dsnowball_lexize|dsqrt|dsynonym_init|dsynonym_lexize|dtrunc|elem_contained_by_range|encode|enum_cmp|enum_eq|enum_first|enum_ge|enum_gt|enum_in|enum_larger|enum_last|enum_le|enum_lt|enum_ne|enum_out|enum_range|enum_recv|enum_send|enum_smaller|eqjoinsel|eqsel|euc_cn_to_mic|euc_cn_to_utf8|euc_jis_2004_to_shift_jis_2004|euc_jis_2004_to_utf8|euc_jp_to_mic|euc_jp_to_sjis|euc_jp_to_utf8|euc_kr_to_mic|euc_kr_to_utf8|euc_tw_to_big5|euc_tw_to_mic|euc_tw_to_utf8|event_trigger_in|event_trigger_out|every|exp|factorial|family|fdw_handler_in|fdw_handler_out|first_value|float4|float48div|float48eq|float48ge|float48gt|float48le|float48lt|float48mi|float48mul|float48ne|float48pl|float4_accum|float4abs|float4div|float4eq|float4ge|float4gt|float4in|float4larger|float4le|float4lt|float4mi|float4mul|float4ne|float4out|float4pl|float4recv|float4send|float4smaller|float4um|float4up|float8|float84div|float84eq|float84ge|float84gt|float84le|float84lt|float84mi|float84mul|float84ne|float84pl|float8_accum|float8_avg|float8_corr|float8_covar_pop|float8_covar_samp|float8_regr_accum|float8_regr_avgx|float8_regr_avgy|float8_regr_intercept|float8_regr_r2|float8_regr_slope|float8_regr_sxx|float8_regr_sxy|float8_regr_syy|float8_stddev_pop|float8_stddev_samp|float8_var_pop|float8_var_samp|float8abs|float8div|float8eq|float8ge|float8gt|float8in|float8larger|float8le|float8lt|float8mi|float8mul|float8ne|float8out|float8pl|float8recv|float8send|float8smaller|float8um|float8up|floor|flt4_mul_cash|flt8_mul_cash|fmgr_c_validator|fmgr_internal_validator|fmgr_sql_validator|format|format_type|gb18030_to_utf8|gbk_to_utf8|generate_series|generate_subscripts|get_bit|get_byte|get_current_ts_config|getdatabaseencoding|getpgusername|gin_cmp_prefix|gin_cmp_tslexeme|gin_extract_tsquery|gin_extract_tsvector|gin_tsquery_consistent|ginarrayconsistent|ginarrayextract|ginbeginscan|ginbuild|ginbuildempty|ginbulkdelete|gincostestimate|ginendscan|gingetbitmap|gininsert|ginmarkpos|ginoptions|ginqueryarrayextract|ginrescan|ginrestrpos|ginvacuumcleanup|gist_box_compress|gist_box_consistent|gist_box_decompress|gist_box_penalty|gist_box_picksplit|gist_box_same|gist_box_union|gist_circle_compress|gist_circle_consistent|gist_point_compress|gist_point_consistent|gist_point_distance|gist_poly_compress|gist_poly_consistent|gistbeginscan|gistbuild|gistbuildempty|gistbulkdelete|gistcostestimate|gistendscan|gistgetbitmap|gistgettuple|gistinsert|gistmarkpos|gistoptions|gistrescan|gistrestrpos|gistvacuumcleanup|gtsquery_compress|gtsquery_consistent|gtsquery_decompress|gtsquery_penalty|gtsquery_picksplit|gtsquery_same|gtsquery_union|gtsvector_compress|gtsvector_consistent|gtsvector_decompress|gtsvector_penalty|gtsvector_picksplit|gtsvector_same|gtsvector_union|gtsvectorin|gtsvectorout|has_any_column_privilege|has_column_privilege|has_database_privilege|has_foreign_data_wrapper_privilege|has_function_privilege|has_language_privilege|has_schema_privilege|has_sequence_privilege|has_server_privilege|has_table_privilege|has_tablespace_privilege|has_type_privilege|hash_aclitem|hash_array|hash_numeric|hash_range|hashbeginscan|hashbpchar|hashbuild|hashbuildempty|hashbulkdelete|hashchar|hashcostestimate|hashendscan|hashenum|hashfloat4|hashfloat8|hashgetbitmap|hashgettuple|hashinet|hashinsert|hashint2|hashint2vector|hashint4|hashint8|hashmacaddr|hashmarkpos|hashname|hashoid|hashoidvector|hashoptions|hashrescan|hashrestrpos|hashtext|hashvacuumcleanup|hashvarlena|height|host|hostmask|iclikejoinsel|iclikesel|icnlikejoinsel|icnlikesel|icregexeqjoinsel|icregexeqsel|icregexnejoinsel|icregexnesel|inet_client_addr|inet_client_port|inet_in|inet_out|inet_recv|inet_send|inet_server_addr|inet_server_port|inetand|inetmi|inetmi_int8|inetnot|inetor|inetpl|initcap|int2|int24div|int24eq|int24ge|int24gt|int24le|int24lt|int24mi|int24mul|int24ne|int24pl|int28div|int28eq|int28ge|int28gt|int28le|int28lt|int28mi|int28mul|int28ne|int28pl|int2_accum|int2_avg_accum|int2_mul_cash|int2_sum|int2abs|int2and|int2div|int2eq|int2ge|int2gt|int2in|int2larger|int2le|int2lt|int2mi|int2mod|int2mul|int2ne|int2not|int2or|int2out|int2pl|int2recv|int2send|int2shl|int2shr|int2smaller|int2um|int2up|int2vectoreq|int2vectorin|int2vectorout|int2vectorrecv|int2vectorsend|int2xor|int4|int42div|int42eq|int42ge|int42gt|int42le|int42lt|int42mi|int42mul|int42ne|int42pl|int48div|int48eq|int48ge|int48gt|int48le|int48lt|int48mi|int48mul|int48ne|int48pl|int4_accum|int4_avg_accum|int4_mul_cash|int4_sum|int4abs|int4and|int4div|int4eq|int4ge|int4gt|int4in|int4inc|int4larger|int4le|int4lt|int4mi|int4mod|int4mul|int4ne|int4not|int4or|int4out|int4pl|int4range|int4range_canonical|int4range_subdiff|int4recv|int4send|int4shl|int4shr|int4smaller|int4um|int4up|int4xor|int8|int82div|int82eq|int82ge|int82gt|int82le|int82lt|int82mi|int82mul|int82ne|int82pl|int84div|int84eq|int84ge|int84gt|int84le|int84lt|int84mi|int84mul|int84ne|int84pl|int8_accum|int8_avg|int8_avg_accum|int8_sum|int8abs|int8and|int8div|int8eq|int8ge|int8gt|int8in|int8inc|int8inc_any|int8inc_float8_float8|int8larger|int8le|int8lt|int8mi|int8mod|int8mul|int8ne|int8not|int8or|int8out|int8pl|int8pl_inet|int8range|int8range_canonical|int8range_subdiff|int8recv|int8send|int8shl|int8shr|int8smaller|int8um|int8up|int8xor|integer_pl_date|inter_lb|inter_sb|inter_sl|internal_in|internal_out|interval_accum|interval_avg|interval_cmp|interval_div|interval_eq|interval_ge|interval_gt|interval_hash|interval_in|interval_larger|interval_le|interval_lt|interval_mi|interval_mul|interval_ne|interval_out|interval_pl|interval_pl_date|interval_pl_time|interval_pl_timestamp|interval_pl_timestamptz|interval_pl_timetz|interval_recv|interval_send|interval_smaller|interval_transform|interval_um|intervaltypmodin|intervaltypmodout|intinterval|isclosed|isempty|isfinite|ishorizontal|iso8859_1_to_utf8|iso8859_to_utf8|iso_to_koi8r|iso_to_mic|iso_to_win1251|iso_to_win866|isopen|isparallel|isperp|isvertical|johab_to_utf8|json_agg|json_agg_finalfn|json_agg_transfn|json_array_element|json_array_element_text|json_array_elements|json_array_length|json_each|json_each_text|json_extract_path|json_extract_path_op|json_extract_path_text|json_extract_path_text_op|json_in|json_object_field|json_object_field_text|json_object_keys|json_out|json_populate_record|json_populate_recordset|json_recv|json_send|justify_days|justify_hours|justify_interval|koi8r_to_iso|koi8r_to_mic|koi8r_to_utf8|koi8r_to_win1251|koi8r_to_win866|koi8u_to_utf8|lag|language_handler_in|language_handler_out|last_value|lastval|latin1_to_mic|latin2_to_mic|latin2_to_win1250|latin3_to_mic|latin4_to_mic|lead|left|length|like|like_escape|likejoinsel|likesel|line|line_distance|line_eq|line_horizontal|line_in|line_interpt|line_intersect|line_out|line_parallel|line_perp|line_recv|line_send|line_vertical|ln|lo_close|lo_creat|lo_create|lo_export|lo_import|lo_lseek|lo_lseek64|lo_open|lo_tell|lo_tell64|lo_truncate|lo_truncate64|lo_unlink|log|loread|lower|lower_inc|lower_inf|lowrite|lpad|lseg|lseg_center|lseg_distance|lseg_eq|lseg_ge|lseg_gt|lseg_horizontal|lseg_in|lseg_interpt|lseg_intersect|lseg_le|lseg_length|lseg_lt|lseg_ne|lseg_out|lseg_parallel|lseg_perp|lseg_recv|lseg_send|lseg_vertical|ltrim|macaddr_and|macaddr_cmp|macaddr_eq|macaddr_ge|macaddr_gt|macaddr_in|macaddr_le|macaddr_lt|macaddr_ne|macaddr_not|macaddr_or|macaddr_out|macaddr_recv|macaddr_send|makeaclitem|masklen|max|md5|mic_to_ascii|mic_to_big5|mic_to_euc_cn|mic_to_euc_jp|mic_to_euc_kr|mic_to_euc_tw|mic_to_iso|mic_to_koi8r|mic_to_latin1|mic_to_latin2|mic_to_latin3|mic_to_latin4|mic_to_sjis|mic_to_win1250|mic_to_win1251|mic_to_win866|min|mktinterval|mod|money|mul_d_interval|name|nameeq|namege|namegt|nameiclike|nameicnlike|nameicregexeq|nameicregexne|namein|namele|namelike|namelt|namene|namenlike|nameout|namerecv|nameregexeq|nameregexne|namesend|neqjoinsel|neqsel|netmask|network|network_cmp|network_eq|network_ge|network_gt|network_le|network_lt|network_ne|network_sub|network_subeq|network_sup|network_supeq|nextval|nlikejoinsel|nlikesel|notlike|now|npoints|nth_value|ntile|numeric_abs|numeric_accum|numeric_add|numeric_avg|numeric_avg_accum|numeric_cmp|numeric_div|numeric_div_trunc|numeric_eq|numeric_exp|numeric_fac|numeric_ge|numeric_gt|numeric_in|numeric_inc|numeric_larger|numeric_le|numeric_ln|numeric_log|numeric_lt|numeric_mod|numeric_mul|numeric_ne|numeric_out|numeric_power|numeric_recv|numeric_send|numeric_smaller|numeric_sqrt|numeric_stddev_pop|numeric_stddev_samp|numeric_sub|numeric_transform|numeric_uminus|numeric_uplus|numeric_var_pop|numeric_var_samp|numerictypmodin|numerictypmodout|numnode|numrange|numrange_subdiff|obj_description|octet_length|oid|oideq|oidge|oidgt|oidin|oidlarger|oidle|oidlt|oidne|oidout|oidrecv|oidsend|oidsmaller|oidvectoreq|oidvectorge|oidvectorgt|oidvectorin|oidvectorle|oidvectorlt|oidvectorne|oidvectorout|oidvectorrecv|oidvectorsend|oidvectortypes|on_pb|on_pl|on_ppath|on_ps|on_sb|on_sl|opaque_in|opaque_out|overlaps|overlay|path|path_add|path_add_pt|path_center|path_contain_pt|path_distance|path_div_pt|path_in|path_inter|path_length|path_mul_pt|path_n_eq|path_n_ge|path_n_gt|path_n_le|path_n_lt|path_npoints|path_out|path_recv|path_send|path_sub_pt|pclose|percent_rank|pg_advisory_lock|pg_advisory_lock_shared|pg_advisory_unlock|pg_advisory_unlock_all|pg_advisory_unlock_shared|pg_advisory_xact_lock|pg_advisory_xact_lock_shared|pg_available_extension_versions|pg_available_extensions|pg_backend_pid|pg_backup_start_time|pg_cancel_backend|pg_char_to_encoding|pg_client_encoding|pg_collation_for|pg_collation_is_visible|pg_column_is_updatable|pg_column_size|pg_conf_load_time|pg_conversion_is_visible|pg_create_restore_point|pg_current_xlog_insert_location|pg_current_xlog_location|pg_cursor|pg_database_size|pg_describe_object|pg_encoding_max_length|pg_encoding_to_char|pg_event_trigger_dropped_objects|pg_export_snapshot|pg_extension_config_dump|pg_extension_update_paths|pg_function_is_visible|pg_get_constraintdef|pg_get_expr|pg_get_function_arguments|pg_get_function_identity_arguments|pg_get_function_result|pg_get_functiondef|pg_get_indexdef|pg_get_keywords|pg_get_multixact_members|pg_get_ruledef|pg_get_serial_sequence|pg_get_triggerdef|pg_get_userbyid|pg_get_viewdef|pg_has_role|pg_identify_object|pg_indexes_size|pg_is_in_backup|pg_is_in_recovery|pg_is_other_temp_schema|pg_is_xlog_replay_paused|pg_last_xact_replay_timestamp|pg_last_xlog_receive_location|pg_last_xlog_replay_location|pg_listening_channels|pg_lock_status|pg_ls_dir|pg_my_temp_schema|pg_node_tree_in|pg_node_tree_out|pg_node_tree_recv|pg_node_tree_send|pg_notify|pg_opclass_is_visible|pg_operator_is_visible|pg_opfamily_is_visible|pg_options_to_table|pg_postmaster_start_time|pg_prepared_statement|pg_prepared_xact|pg_read_binary_file|pg_read_file|pg_relation_filenode|pg_relation_filepath|pg_relation_is_updatable|pg_relation_size|pg_reload_conf|pg_rotate_logfile|pg_sequence_parameters|pg_show_all_settings|pg_size_pretty|pg_sleep|pg_start_backup|pg_stat_clear_snapshot|pg_stat_file|pg_stat_get_activity|pg_stat_get_analyze_count|pg_stat_get_autoanalyze_count|pg_stat_get_autovacuum_count|pg_stat_get_backend_activity|pg_stat_get_backend_activity_start|pg_stat_get_backend_client_addr|pg_stat_get_backend_client_port|pg_stat_get_backend_dbid|pg_stat_get_backend_idset|pg_stat_get_backend_pid|pg_stat_get_backend_start|pg_stat_get_backend_userid|pg_stat_get_backend_waiting|pg_stat_get_backend_xact_start|pg_stat_get_bgwriter_buf_written_checkpoints|pg_stat_get_bgwriter_buf_written_clean|pg_stat_get_bgwriter_maxwritten_clean|pg_stat_get_bgwriter_requested_checkpoints|pg_stat_get_bgwriter_stat_reset_time|pg_stat_get_bgwriter_timed_checkpoints|pg_stat_get_blocks_fetched|pg_stat_get_blocks_hit|pg_stat_get_buf_alloc|pg_stat_get_buf_fsync_backend|pg_stat_get_buf_written_backend|pg_stat_get_checkpoint_sync_time|pg_stat_get_checkpoint_write_time|pg_stat_get_db_blk_read_time|pg_stat_get_db_blk_write_time|pg_stat_get_db_blocks_fetched|pg_stat_get_db_blocks_hit|pg_stat_get_db_conflict_all|pg_stat_get_db_conflict_bufferpin|pg_stat_get_db_conflict_lock|pg_stat_get_db_conflict_snapshot|pg_stat_get_db_conflict_startup_deadlock|pg_stat_get_db_conflict_tablespace|pg_stat_get_db_deadlocks|pg_stat_get_db_numbackends|pg_stat_get_db_stat_reset_time|pg_stat_get_db_temp_bytes|pg_stat_get_db_temp_files|pg_stat_get_db_tuples_deleted|pg_stat_get_db_tuples_fetched|pg_stat_get_db_tuples_inserted|pg_stat_get_db_tuples_returned|pg_stat_get_db_tuples_updated|pg_stat_get_db_xact_commit|pg_stat_get_db_xact_rollback|pg_stat_get_dead_tuples|pg_stat_get_function_calls|pg_stat_get_function_self_time|pg_stat_get_function_total_time|pg_stat_get_last_analyze_time|pg_stat_get_last_autoanalyze_time|pg_stat_get_last_autovacuum_time|pg_stat_get_last_vacuum_time|pg_stat_get_live_tuples|pg_stat_get_numscans|pg_stat_get_tuples_deleted|pg_stat_get_tuples_fetched|pg_stat_get_tuples_hot_updated|pg_stat_get_tuples_inserted|pg_stat_get_tuples_returned|pg_stat_get_tuples_updated|pg_stat_get_vacuum_count|pg_stat_get_wal_senders|pg_stat_get_xact_blocks_fetched|pg_stat_get_xact_blocks_hit|pg_stat_get_xact_function_calls|pg_stat_get_xact_function_self_time|pg_stat_get_xact_function_total_time|pg_stat_get_xact_numscans|pg_stat_get_xact_tuples_deleted|pg_stat_get_xact_tuples_fetched|pg_stat_get_xact_tuples_hot_updated|pg_stat_get_xact_tuples_inserted|pg_stat_get_xact_tuples_returned|pg_stat_get_xact_tuples_updated|pg_stat_reset|pg_stat_reset_shared|pg_stat_reset_single_function_counters|pg_stat_reset_single_table_counters|pg_stop_backup|pg_switch_xlog|pg_table_is_visible|pg_table_size|pg_tablespace_databases|pg_tablespace_location|pg_tablespace_size|pg_terminate_backend|pg_timezone_abbrevs|pg_timezone_names|pg_total_relation_size|pg_trigger_depth|pg_try_advisory_lock|pg_try_advisory_lock_shared|pg_try_advisory_xact_lock|pg_try_advisory_xact_lock_shared|pg_ts_config_is_visible|pg_ts_dict_is_visible|pg_ts_parser_is_visible|pg_ts_template_is_visible|pg_type_is_visible|pg_typeof|pg_xlog_location_diff|pg_xlog_replay_pause|pg_xlog_replay_resume|pg_xlogfile_name|pg_xlogfile_name_offset|pi|plainto_tsquery|plpgsql_call_handler|plpgsql_inline_handler|plpgsql_validator|point|point_above|point_add|point_below|point_distance|point_div|point_eq|point_horiz|point_in|point_left|point_mul|point_ne|point_out|point_recv|point_right|point_send|point_sub|point_vert|poly_above|poly_below|poly_center|poly_contain|poly_contain_pt|poly_contained|poly_distance|poly_in|poly_left|poly_npoints|poly_out|poly_overabove|poly_overbelow|poly_overlap|poly_overleft|poly_overright|poly_recv|poly_right|poly_same|poly_send|polygon|popen|position|positionjoinsel|positionsel|postgresql_fdw_validator|pow|power|prsd_end|prsd_headline|prsd_lextype|prsd_nexttoken|prsd_start|pt_contained_circle|pt_contained_poly|query_to_xml|query_to_xml_and_xmlschema|query_to_xmlschema|querytree|quote_ident|quote_literal|quote_nullable|radians|radius|random|range_adjacent|range_after|range_before|range_cmp|range_contained_by|range_contains|range_contains_elem|range_eq|range_ge|range_gist_compress|range_gist_consistent|range_gist_decompress|range_gist_penalty|range_gist_picksplit|range_gist_same|range_gist_union|range_gt|range_in|range_intersect|range_le|range_lt|range_minus|range_ne|range_out|range_overlaps|range_overleft|range_overright|range_recv|range_send|range_typanalyze|range_union|rangesel|rank|record_eq|record_ge|record_gt|record_in|record_le|record_lt|record_ne|record_out|record_recv|record_send|regclass|regclassin|regclassout|regclassrecv|regclasssend|regconfigin|regconfigout|regconfigrecv|regconfigsend|regdictionaryin|regdictionaryout|regdictionaryrecv|regdictionarysend|regexeqjoinsel|regexeqsel|regexnejoinsel|regexnesel|regexp_matches|regexp_replace|regexp_split_to_array|regexp_split_to_table|regoperatorin|regoperatorout|regoperatorrecv|regoperatorsend|regoperin|regoperout|regoperrecv|regopersend|regprocedurein|regprocedureout|regprocedurerecv|regproceduresend|regprocin|regprocout|regprocrecv|regprocsend|regr_avgx|regr_avgy|regr_count|regr_intercept|regr_r2|regr_slope|regr_sxx|regr_sxy|regr_syy|regtypein|regtypeout|regtyperecv|regtypesend|reltime|reltimeeq|reltimege|reltimegt|reltimein|reltimele|reltimelt|reltimene|reltimeout|reltimerecv|reltimesend|repeat|replace|reverse|right|round|row_number|row_to_json|rpad|rtrim|scalargtjoinsel|scalargtsel|scalarltjoinsel|scalarltsel|schema_to_xml|schema_to_xml_and_xmlschema|schema_to_xmlschema|session_user|set_bit|set_byte|set_config|set_masklen|setseed|setval|setweight|shell_in|shell_out|shift_jis_2004_to_euc_jis_2004|shift_jis_2004_to_utf8|shobj_description|sign|similar_escape|sin|sjis_to_euc_jp|sjis_to_mic|sjis_to_utf8|slope|smgreq|smgrin|smgrne|smgrout|spg_kd_choose|spg_kd_config|spg_kd_inner_consistent|spg_kd_picksplit|spg_quad_choose|spg_quad_config|spg_quad_inner_consistent|spg_quad_leaf_consistent|spg_quad_picksplit|spg_range_quad_choose|spg_range_quad_config|spg_range_quad_inner_consistent|spg_range_quad_leaf_consistent|spg_range_quad_picksplit|spg_text_choose|spg_text_config|spg_text_inner_consistent|spg_text_leaf_consistent|spg_text_picksplit|spgbeginscan|spgbuild|spgbuildempty|spgbulkdelete|spgcanreturn|spgcostestimate|spgendscan|spggetbitmap|spggettuple|spginsert|spgmarkpos|spgoptions|spgrescan|spgrestrpos|spgvacuumcleanup|split_part|sqrt|statement_timestamp|stddev|stddev_pop|stddev_samp|string_agg|string_agg_finalfn|string_agg_transfn|string_to_array|strip|strpos|substr|substring|sum|suppress_redundant_updates_trigger|table_to_xml|table_to_xml_and_xmlschema|table_to_xmlschema|tan|text|text_ge|text_gt|text_larger|text_le|text_lt|text_pattern_ge|text_pattern_gt|text_pattern_le|text_pattern_lt|text_smaller|textanycat|textcat|texteq|texticlike|texticnlike|texticregexeq|texticregexne|textin|textlen|textlike|textne|textnlike|textout|textrecv|textregexeq|textregexne|textsend|thesaurus_init|thesaurus_lexize|tideq|tidge|tidgt|tidin|tidlarger|tidle|tidlt|tidne|tidout|tidrecv|tidsend|tidsmaller|time_cmp|time_eq|time_ge|time_gt|time_hash|time_in|time_larger|time_le|time_lt|time_mi_interval|time_mi_time|time_ne|time_out|time_pl_interval|time_recv|time_send|time_smaller|time_transform|timedate_pl|timemi|timenow|timeofday|timepl|timestamp_cmp|timestamp_cmp_date|timestamp_cmp_timestamptz|timestamp_eq|timestamp_eq_date|timestamp_eq_timestamptz|timestamp_ge|timestamp_ge_date|timestamp_ge_timestamptz|timestamp_gt|timestamp_gt_date|timestamp_gt_timestamptz|timestamp_hash|timestamp_in|timestamp_larger|timestamp_le|timestamp_le_date|timestamp_le_timestamptz|timestamp_lt|timestamp_lt_date|timestamp_lt_timestamptz|timestamp_mi|timestamp_mi_interval|timestamp_ne|timestamp_ne_date|timestamp_ne_timestamptz|timestamp_out|timestamp_pl_interval|timestamp_recv|timestamp_send|timestamp_smaller|timestamp_sortsupport|timestamp_transform|timestamptypmodin|timestamptypmodout|timestamptz_cmp|timestamptz_cmp_date|timestamptz_cmp_timestamp|timestamptz_eq|timestamptz_eq_date|timestamptz_eq_timestamp|timestamptz_ge|timestamptz_ge_date|timestamptz_ge_timestamp|timestamptz_gt|timestamptz_gt_date|timestamptz_gt_timestamp|timestamptz_in|timestamptz_larger|timestamptz_le|timestamptz_le_date|timestamptz_le_timestamp|timestamptz_lt|timestamptz_lt_date|timestamptz_lt_timestamp|timestamptz_mi|timestamptz_mi_interval|timestamptz_ne|timestamptz_ne_date|timestamptz_ne_timestamp|timestamptz_out|timestamptz_pl_interval|timestamptz_recv|timestamptz_send|timestamptz_smaller|timestamptztypmodin|timestamptztypmodout|timetypmodin|timetypmodout|timetz_cmp|timetz_eq|timetz_ge|timetz_gt|timetz_hash|timetz_in|timetz_larger|timetz_le|timetz_lt|timetz_mi_interval|timetz_ne|timetz_out|timetz_pl_interval|timetz_recv|timetz_send|timetz_smaller|timetzdate_pl|timetztypmodin|timetztypmodout|timezone|tinterval|tintervalct|tintervalend|tintervaleq|tintervalge|tintervalgt|tintervalin|tintervalle|tintervalleneq|tintervallenge|tintervallengt|tintervallenle|tintervallenlt|tintervallenne|tintervallt|tintervalne|tintervalout|tintervalov|tintervalrecv|tintervalrel|tintervalsame|tintervalsend|tintervalstart|to_ascii|to_char|to_date|to_hex|to_json|to_number|to_timestamp|to_tsquery|to_tsvector|transaction_timestamp|translate|trigger_in|trigger_out|trunc|ts_debug|ts_headline|ts_lexize|ts_match_qv|ts_match_tq|ts_match_tt|ts_match_vq|ts_parse|ts_rank|ts_rank_cd|ts_rewrite|ts_stat|ts_token_type|ts_typanalyze|tsmatchjoinsel|tsmatchsel|tsq_mcontained|tsq_mcontains|tsquery_and|tsquery_cmp|tsquery_eq|tsquery_ge|tsquery_gt|tsquery_le|tsquery_lt|tsquery_ne|tsquery_not|tsquery_or|tsqueryin|tsqueryout|tsqueryrecv|tsquerysend|tsrange|tsrange_subdiff|tstzrange|tstzrange_subdiff|tsvector_cmp|tsvector_concat|tsvector_eq|tsvector_ge|tsvector_gt|tsvector_le|tsvector_lt|tsvector_ne|tsvector_update_trigger|tsvector_update_trigger_column|tsvectorin|tsvectorout|tsvectorrecv|tsvectorsend|txid_current|txid_current_snapshot|txid_snapshot_in|txid_snapshot_out|txid_snapshot_recv|txid_snapshot_send|txid_snapshot_xip|txid_snapshot_xmax|txid_snapshot_xmin|txid_visible_in_snapshot|uhc_to_utf8|unique_key_recheck|unknownin|unknownout|unknownrecv|unknownsend|unnest|upper|upper_inc|upper_inf|utf8_to_ascii|utf8_to_big5|utf8_to_euc_cn|utf8_to_euc_jis_2004|utf8_to_euc_jp|utf8_to_euc_kr|utf8_to_euc_tw|utf8_to_gb18030|utf8_to_gbk|utf8_to_iso8859|utf8_to_iso8859_1|utf8_to_johab|utf8_to_koi8r|utf8_to_koi8u|utf8_to_shift_jis_2004|utf8_to_sjis|utf8_to_uhc|utf8_to_win|uuid_cmp|uuid_eq|uuid_ge|uuid_gt|uuid_hash|uuid_in|uuid_le|uuid_lt|uuid_ne|uuid_out|uuid_recv|uuid_send|var_pop|var_samp|varbit_in|varbit_out|varbit_recv|varbit_send|varbit_transform|varbitcmp|varbiteq|varbitge|varbitgt|varbitle|varbitlt|varbitne|varbittypmodin|varbittypmodout|varchar_transform|varcharin|varcharout|varcharrecv|varcharsend|varchartypmodin|varchartypmodout|variance|version|void_in|void_out|void_recv|void_send|width|width_bucket|win1250_to_latin2|win1250_to_mic|win1251_to_iso|win1251_to_koi8r|win1251_to_mic|win1251_to_win866|win866_to_iso|win866_to_koi8r|win866_to_mic|win866_to_win1251|win_to_utf8|xideq|xideqint4|xidin|xidout|xidrecv|xidsend|xml|xml_in|xml_is_well_formed|xml_is_well_formed_content|xml_is_well_formed_document|xml_out|xml_recv|xml_send|xmlagg|xmlcomment|xmlconcat2|xmlexists|xmlvalidate|xpath|xpath_exists",n=this.createKeywordMapper({"support.function":t,keyword:e},"identifier",!0),r=[{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"variable.language",regex:'".*?"'},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:n,regex:"[a-zA-Z_][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|!!|!~|!~\\*|!~~|!~~\\*|#|##|#<|#<=|#<>|#=|#>|#>=|%|\\&|\\&\\&|\\&<|\\&<\\||\\&>|\\*|\\+|\\-|/|<|<#>|<\\->|<<|<<=|<<\\||<=|<>|<\\?>|<@|<\\^|=|>|>=|>>|>>=|>\\^|\\?#|\\?\\-|\\?\\-\\||\\?\\||\\?\\|\\||@|@\\-@|@>|@@|@@@|\\^|\\||\\|\\&>|\\|/|\\|>>|\\|\\||\\|\\|/|~|~\\*|~<=~|~<~|~=|~>=~|~>~|~~|~~\\*"},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}];this.$rules={start:[{token:"comment",regex:"--.*$"},s.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"keyword.statementBegin",regex:"^[a-zA-Z]+",next:"statement"},{token:"support.buildin",regex:"^\\\\[\\S]+.*$"}],statement:[{token:"comment",regex:"--.*$"},{token:"comment",regex:"\\/\\*",next:"commentStatement"},{token:"statementEnd",regex:";",next:"start"},{token:"string",regex:"\\$perl\\$",next:"perl-start"},{token:"string",regex:"\\$python\\$",next:"python-start"},{token:"string",regex:"\\$json\\$",next:"json-start"},{token:"string",regex:"\\$(js|javascript)\\$",next:"javascript-start"},{token:"string",regex:"\\$[\\w_0-9]*\\$$",next:"dollarSql"},{token:"string",regex:"\\$[\\w_0-9]*\\$",next:"dollarStatementString"}].concat(r),dollarSql:[{token:"comment",regex:"--.*$"},{token:"comment",regex:"\\/\\*",next:"commentDollarSql"},{token:"string",regex:"^\\$[\\w_0-9]*\\$",next:"statement"},{token:"string",regex:"\\$[\\w_0-9]*\\$",next:"dollarSqlString"}].concat(r),comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],commentStatement:[{token:"comment",regex:".*?\\*\\/",next:"statement"},{token:"comment",regex:".+"}],commentDollarSql:[{token:"comment",regex:".*?\\*\\/",next:"dollarSql"},{token:"comment",regex:".+"}],dollarStatementString:[{token:"string",regex:".*?\\$[\\w_0-9]*\\$",next:"statement"},{token:"string",regex:".+"}],dollarSqlString:[{token:"string",regex:".*?\\$[\\w_0-9]*\\$",next:"dollarSql"},{token:"string",regex:".+"}]},this.embedRules(s,"doc-",[s.getEndRule("start")]),this.embedRules(u,"perl-",[{token:"string",regex:"\\$perl\\$",next:"statement"}]),this.embedRules(a,"python-",[{token:"string",regex:"\\$python\\$",next:"statement"}]),this.embedRules(f,"json-",[{token:"string",regex:"\\$json\\$",next:"statement"}]),this.embedRules(l,"javascript-",[{token:"string",regex:"\\$(js|javascript)\\$",next:"statement"}])};r.inherits(c,o),t.PgsqlHighlightRules=c}),ace.define("ace/mode/pgsql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/pgsql_highlight_rules","ace/range"],function(e,t,n){var r=e("../lib/oop"),i=e("../mode/text").Mode,s=e("./pgsql_highlight_rules").PgsqlHighlightRules,o=e("../range").Range,u=function(){this.HighlightRules=s};r.inherits(u,i),function(){this.lineCommentStart="--",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){return e=="start"||e=="keyword.statementEnd"?"":this.$getIndent(t)},this.$id="ace/mode/pgsql"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-php.js b/dist/assets/js/vendor/ace-nc/mode-php.js
            new file mode 100644
            index 0000000000..eb0bac741b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-php.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/php_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./doc_comment_highlight_rules").DocCommentHighlightRules,o=e("./text_highlight_rules").TextHighlightRules,u=e("./html_highlight_rules").HtmlHighlightRules,a=function(){var e=s,t=i.arrayToMap("abs|acos|acosh|addcslashes|addslashes|aggregate|aggregate_info|aggregate_methods|aggregate_methods_by_list|aggregate_methods_by_regexp|aggregate_properties|aggregate_properties_by_list|aggregate_properties_by_regexp|aggregation_info|amqpconnection|amqpexchange|amqpqueue|apache_child_terminate|apache_get_modules|apache_get_version|apache_getenv|apache_lookup_uri|apache_note|apache_request_headers|apache_reset_timeout|apache_response_headers|apache_setenv|apc_add|apc_bin_dump|apc_bin_dumpfile|apc_bin_load|apc_bin_loadfile|apc_cache_info|apc_cas|apc_clear_cache|apc_compile_file|apc_dec|apc_define_constants|apc_delete|apc_delete_file|apc_exists|apc_fetch|apc_inc|apc_load_constants|apc_sma_info|apc_store|apciterator|apd_breakpoint|apd_callstack|apd_clunk|apd_continue|apd_croak|apd_dump_function_table|apd_dump_persistent_resources|apd_dump_regular_resources|apd_echo|apd_get_active_symbols|apd_set_pprof_trace|apd_set_session|apd_set_session_trace|apd_set_session_trace_socket|appenditerator|array|array_change_key_case|array_chunk|array_combine|array_count_values|array_diff|array_diff_assoc|array_diff_key|array_diff_uassoc|array_diff_ukey|array_fill|array_fill_keys|array_filter|array_flip|array_intersect|array_intersect_assoc|array_intersect_key|array_intersect_uassoc|array_intersect_ukey|array_key_exists|array_keys|array_map|array_merge|array_merge_recursive|array_multisort|array_pad|array_pop|array_product|array_push|array_rand|array_reduce|array_replace|array_replace_recursive|array_reverse|array_search|array_shift|array_slice|array_splice|array_sum|array_udiff|array_udiff_assoc|array_udiff_uassoc|array_uintersect|array_uintersect_assoc|array_uintersect_uassoc|array_unique|array_unshift|array_values|array_walk|array_walk_recursive|arrayaccess|arrayiterator|arrayobject|arsort|asin|asinh|asort|assert|assert_options|atan|atan2|atanh|audioproperties|badfunctioncallexception|badmethodcallexception|base64_decode|base64_encode|base_convert|basename|bbcode_add_element|bbcode_add_smiley|bbcode_create|bbcode_destroy|bbcode_parse|bbcode_set_arg_parser|bbcode_set_flags|bcadd|bccomp|bcdiv|bcmod|bcmul|bcompiler_load|bcompiler_load_exe|bcompiler_parse_class|bcompiler_read|bcompiler_write_class|bcompiler_write_constant|bcompiler_write_exe_footer|bcompiler_write_file|bcompiler_write_footer|bcompiler_write_function|bcompiler_write_functions_from_file|bcompiler_write_header|bcompiler_write_included_filename|bcpow|bcpowmod|bcscale|bcsqrt|bcsub|bin2hex|bind_textdomain_codeset|bindec|bindtextdomain|bson_decode|bson_encode|bumpValue|bzclose|bzcompress|bzdecompress|bzerrno|bzerror|bzerrstr|bzflush|bzopen|bzread|bzwrite|cachingiterator|cairo|cairo_create|cairo_font_face_get_type|cairo_font_face_status|cairo_font_options_create|cairo_font_options_equal|cairo_font_options_get_antialias|cairo_font_options_get_hint_metrics|cairo_font_options_get_hint_style|cairo_font_options_get_subpixel_order|cairo_font_options_hash|cairo_font_options_merge|cairo_font_options_set_antialias|cairo_font_options_set_hint_metrics|cairo_font_options_set_hint_style|cairo_font_options_set_subpixel_order|cairo_font_options_status|cairo_format_stride_for_width|cairo_image_surface_create|cairo_image_surface_create_for_data|cairo_image_surface_create_from_png|cairo_image_surface_get_data|cairo_image_surface_get_format|cairo_image_surface_get_height|cairo_image_surface_get_stride|cairo_image_surface_get_width|cairo_matrix_create_scale|cairo_matrix_create_translate|cairo_matrix_invert|cairo_matrix_multiply|cairo_matrix_rotate|cairo_matrix_transform_distance|cairo_matrix_transform_point|cairo_matrix_translate|cairo_pattern_add_color_stop_rgb|cairo_pattern_add_color_stop_rgba|cairo_pattern_create_for_surface|cairo_pattern_create_linear|cairo_pattern_create_radial|cairo_pattern_create_rgb|cairo_pattern_create_rgba|cairo_pattern_get_color_stop_count|cairo_pattern_get_color_stop_rgba|cairo_pattern_get_extend|cairo_pattern_get_filter|cairo_pattern_get_linear_points|cairo_pattern_get_matrix|cairo_pattern_get_radial_circles|cairo_pattern_get_rgba|cairo_pattern_get_surface|cairo_pattern_get_type|cairo_pattern_set_extend|cairo_pattern_set_filter|cairo_pattern_set_matrix|cairo_pattern_status|cairo_pdf_surface_create|cairo_pdf_surface_set_size|cairo_ps_get_levels|cairo_ps_level_to_string|cairo_ps_surface_create|cairo_ps_surface_dsc_begin_page_setup|cairo_ps_surface_dsc_begin_setup|cairo_ps_surface_dsc_comment|cairo_ps_surface_get_eps|cairo_ps_surface_restrict_to_level|cairo_ps_surface_set_eps|cairo_ps_surface_set_size|cairo_scaled_font_create|cairo_scaled_font_extents|cairo_scaled_font_get_ctm|cairo_scaled_font_get_font_face|cairo_scaled_font_get_font_matrix|cairo_scaled_font_get_font_options|cairo_scaled_font_get_scale_matrix|cairo_scaled_font_get_type|cairo_scaled_font_glyph_extents|cairo_scaled_font_status|cairo_scaled_font_text_extents|cairo_surface_copy_page|cairo_surface_create_similar|cairo_surface_finish|cairo_surface_flush|cairo_surface_get_content|cairo_surface_get_device_offset|cairo_surface_get_font_options|cairo_surface_get_type|cairo_surface_mark_dirty|cairo_surface_mark_dirty_rectangle|cairo_surface_set_device_offset|cairo_surface_set_fallback_resolution|cairo_surface_show_page|cairo_surface_status|cairo_surface_write_to_png|cairo_svg_surface_create|cairo_svg_surface_restrict_to_version|cairo_svg_version_to_string|cairoantialias|cairocontent|cairocontext|cairoexception|cairoextend|cairofillrule|cairofilter|cairofontface|cairofontoptions|cairofontslant|cairofonttype|cairofontweight|cairoformat|cairogradientpattern|cairohintmetrics|cairohintstyle|cairoimagesurface|cairolineargradient|cairolinecap|cairolinejoin|cairomatrix|cairooperator|cairopath|cairopattern|cairopatterntype|cairopdfsurface|cairopslevel|cairopssurface|cairoradialgradient|cairoscaledfont|cairosolidpattern|cairostatus|cairosubpixelorder|cairosurface|cairosurfacepattern|cairosurfacetype|cairosvgsurface|cairosvgversion|cairotoyfontface|cal_days_in_month|cal_from_jd|cal_info|cal_to_jd|calcul_hmac|calculhmac|call_user_func|call_user_func_array|call_user_method|call_user_method_array|callbackfilteriterator|ceil|chdb|chdb_create|chdir|checkdate|checkdnsrr|chgrp|chmod|chop|chown|chr|chroot|chunk_split|class_alias|class_exists|class_implements|class_parents|classkit_import|classkit_method_add|classkit_method_copy|classkit_method_redefine|classkit_method_remove|classkit_method_rename|clearstatcache|clone|closedir|closelog|collator|com|com_addref|com_create_guid|com_event_sink|com_get|com_get_active_object|com_invoke|com_isenum|com_load|com_load_typelib|com_message_pump|com_print_typeinfo|com_propget|com_propput|com_propset|com_release|com_set|compact|connection_aborted|connection_status|connection_timeout|constant|construct|construct|construct|convert_cyr_string|convert_uudecode|convert_uuencode|copy|cos|cosh|count|count_chars|countable|counter_bump|counter_bump_value|counter_create|counter_get|counter_get_meta|counter_get_named|counter_get_value|counter_reset|counter_reset_value|crack_check|crack_closedict|crack_getlastmessage|crack_opendict|crc32|create_function|crypt|ctype_alnum|ctype_alpha|ctype_cntrl|ctype_digit|ctype_graph|ctype_lower|ctype_print|ctype_punct|ctype_space|ctype_upper|ctype_xdigit|cubrid_affected_rows|cubrid_bind|cubrid_client_encoding|cubrid_close|cubrid_close_prepare|cubrid_close_request|cubrid_col_get|cubrid_col_size|cubrid_column_names|cubrid_column_types|cubrid_commit|cubrid_connect|cubrid_connect_with_url|cubrid_current_oid|cubrid_data_seek|cubrid_db_name|cubrid_disconnect|cubrid_drop|cubrid_errno|cubrid_error|cubrid_error_code|cubrid_error_code_facility|cubrid_error_msg|cubrid_execute|cubrid_fetch|cubrid_fetch_array|cubrid_fetch_assoc|cubrid_fetch_field|cubrid_fetch_lengths|cubrid_fetch_object|cubrid_fetch_row|cubrid_field_flags|cubrid_field_len|cubrid_field_name|cubrid_field_seek|cubrid_field_table|cubrid_field_type|cubrid_free_result|cubrid_get|cubrid_get_autocommit|cubrid_get_charset|cubrid_get_class_name|cubrid_get_client_info|cubrid_get_db_parameter|cubrid_get_server_info|cubrid_insert_id|cubrid_is_instance|cubrid_list_dbs|cubrid_load_from_glo|cubrid_lob_close|cubrid_lob_export|cubrid_lob_get|cubrid_lob_send|cubrid_lob_size|cubrid_lock_read|cubrid_lock_write|cubrid_move_cursor|cubrid_new_glo|cubrid_next_result|cubrid_num_cols|cubrid_num_fields|cubrid_num_rows|cubrid_ping|cubrid_prepare|cubrid_put|cubrid_query|cubrid_real_escape_string|cubrid_result|cubrid_rollback|cubrid_save_to_glo|cubrid_schema|cubrid_send_glo|cubrid_seq_drop|cubrid_seq_insert|cubrid_seq_put|cubrid_set_add|cubrid_set_autocommit|cubrid_set_db_parameter|cubrid_set_drop|cubrid_unbuffered_query|cubrid_version|curl_close|curl_copy_handle|curl_errno|curl_error|curl_exec|curl_getinfo|curl_init|curl_multi_add_handle|curl_multi_close|curl_multi_exec|curl_multi_getcontent|curl_multi_info_read|curl_multi_init|curl_multi_remove_handle|curl_multi_select|curl_setopt|curl_setopt_array|curl_version|current|cyrus_authenticate|cyrus_bind|cyrus_close|cyrus_connect|cyrus_query|cyrus_unbind|date|date_add|date_create|date_create_from_format|date_date_set|date_default_timezone_get|date_default_timezone_set|date_diff|date_format|date_get_last_errors|date_interval_create_from_date_string|date_interval_format|date_isodate_set|date_modify|date_offset_get|date_parse|date_parse_from_format|date_sub|date_sun_info|date_sunrise|date_sunset|date_time_set|date_timestamp_get|date_timestamp_set|date_timezone_get|date_timezone_set|dateinterval|dateperiod|datetime|datetimezone|db2_autocommit|db2_bind_param|db2_client_info|db2_close|db2_column_privileges|db2_columns|db2_commit|db2_conn_error|db2_conn_errormsg|db2_connect|db2_cursor_type|db2_escape_string|db2_exec|db2_execute|db2_fetch_array|db2_fetch_assoc|db2_fetch_both|db2_fetch_object|db2_fetch_row|db2_field_display_size|db2_field_name|db2_field_num|db2_field_precision|db2_field_scale|db2_field_type|db2_field_width|db2_foreign_keys|db2_free_result|db2_free_stmt|db2_get_option|db2_last_insert_id|db2_lob_read|db2_next_result|db2_num_fields|db2_num_rows|db2_pclose|db2_pconnect|db2_prepare|db2_primary_keys|db2_procedure_columns|db2_procedures|db2_result|db2_rollback|db2_server_info|db2_set_option|db2_special_columns|db2_statistics|db2_stmt_error|db2_stmt_errormsg|db2_table_privileges|db2_tables|dba_close|dba_delete|dba_exists|dba_fetch|dba_firstkey|dba_handlers|dba_insert|dba_key_split|dba_list|dba_nextkey|dba_open|dba_optimize|dba_popen|dba_replace|dba_sync|dbase_add_record|dbase_close|dbase_create|dbase_delete_record|dbase_get_header_info|dbase_get_record|dbase_get_record_with_names|dbase_numfields|dbase_numrecords|dbase_open|dbase_pack|dbase_replace_record|dbplus_add|dbplus_aql|dbplus_chdir|dbplus_close|dbplus_curr|dbplus_errcode|dbplus_errno|dbplus_find|dbplus_first|dbplus_flush|dbplus_freealllocks|dbplus_freelock|dbplus_freerlocks|dbplus_getlock|dbplus_getunique|dbplus_info|dbplus_last|dbplus_lockrel|dbplus_next|dbplus_open|dbplus_prev|dbplus_rchperm|dbplus_rcreate|dbplus_rcrtexact|dbplus_rcrtlike|dbplus_resolve|dbplus_restorepos|dbplus_rkeys|dbplus_ropen|dbplus_rquery|dbplus_rrename|dbplus_rsecindex|dbplus_runlink|dbplus_rzap|dbplus_savepos|dbplus_setindex|dbplus_setindexbynumber|dbplus_sql|dbplus_tcl|dbplus_tremove|dbplus_undo|dbplus_undoprepare|dbplus_unlockrel|dbplus_unselect|dbplus_update|dbplus_xlockrel|dbplus_xunlockrel|dbx_close|dbx_compare|dbx_connect|dbx_error|dbx_escape_string|dbx_fetch_row|dbx_query|dbx_sort|dcgettext|dcngettext|deaggregate|debug_backtrace|debug_print_backtrace|debug_zval_dump|decbin|dechex|decoct|define|define_syslog_variables|defined|deg2rad|delete|dgettext|die|dio_close|dio_fcntl|dio_open|dio_read|dio_seek|dio_stat|dio_tcsetattr|dio_truncate|dio_write|dir|directoryiterator|dirname|disk_free_space|disk_total_space|diskfreespace|dl|dngettext|dns_check_record|dns_get_mx|dns_get_record|dom_import_simplexml|domainexception|domattr|domattribute_name|domattribute_set_value|domattribute_specified|domattribute_value|domcharacterdata|domcomment|domdocument|domdocument_add_root|domdocument_create_attribute|domdocument_create_cdata_section|domdocument_create_comment|domdocument_create_element|domdocument_create_element_ns|domdocument_create_entity_reference|domdocument_create_processing_instruction|domdocument_create_text_node|domdocument_doctype|domdocument_document_element|domdocument_dump_file|domdocument_dump_mem|domdocument_get_element_by_id|domdocument_get_elements_by_tagname|domdocument_html_dump_mem|domdocument_xinclude|domdocumentfragment|domdocumenttype|domdocumenttype_entities|domdocumenttype_internal_subset|domdocumenttype_name|domdocumenttype_notations|domdocumenttype_public_id|domdocumenttype_system_id|domelement|domelement_get_attribute|domelement_get_attribute_node|domelement_get_elements_by_tagname|domelement_has_attribute|domelement_remove_attribute|domelement_set_attribute|domelement_set_attribute_node|domelement_tagname|domentity|domentityreference|domexception|domimplementation|domnamednodemap|domnode|domnode_add_namespace|domnode_append_child|domnode_append_sibling|domnode_attributes|domnode_child_nodes|domnode_clone_node|domnode_dump_node|domnode_first_child|domnode_get_content|domnode_has_attributes|domnode_has_child_nodes|domnode_insert_before|domnode_is_blank_node|domnode_last_child|domnode_next_sibling|domnode_node_name|domnode_node_type|domnode_node_value|domnode_owner_document|domnode_parent_node|domnode_prefix|domnode_previous_sibling|domnode_remove_child|domnode_replace_child|domnode_replace_node|domnode_set_content|domnode_set_name|domnode_set_namespace|domnode_unlink_node|domnodelist|domnotation|domprocessinginstruction|domprocessinginstruction_data|domprocessinginstruction_target|domtext|domxml_new_doc|domxml_open_file|domxml_open_mem|domxml_version|domxml_xmltree|domxml_xslt_stylesheet|domxml_xslt_stylesheet_doc|domxml_xslt_stylesheet_file|domxml_xslt_version|domxpath|domxsltstylesheet_process|domxsltstylesheet_result_dump_file|domxsltstylesheet_result_dump_mem|dotnet|dotnet_load|doubleval|each|easter_date|easter_days|echo|empty|emptyiterator|enchant_broker_describe|enchant_broker_dict_exists|enchant_broker_free|enchant_broker_free_dict|enchant_broker_get_error|enchant_broker_init|enchant_broker_list_dicts|enchant_broker_request_dict|enchant_broker_request_pwl_dict|enchant_broker_set_ordering|enchant_dict_add_to_personal|enchant_dict_add_to_session|enchant_dict_check|enchant_dict_describe|enchant_dict_get_error|enchant_dict_is_in_session|enchant_dict_quick_check|enchant_dict_store_replacement|enchant_dict_suggest|end|ereg|ereg_replace|eregi|eregi_replace|error_get_last|error_log|error_reporting|errorexception|escapeshellarg|escapeshellcmd|eval|event_add|event_base_free|event_base_loop|event_base_loopbreak|event_base_loopexit|event_base_new|event_base_priority_init|event_base_set|event_buffer_base_set|event_buffer_disable|event_buffer_enable|event_buffer_fd_set|event_buffer_free|event_buffer_new|event_buffer_priority_set|event_buffer_read|event_buffer_set_callback|event_buffer_timeout_set|event_buffer_watermark_set|event_buffer_write|event_del|event_free|event_new|event_set|exception|exec|exif_imagetype|exif_read_data|exif_tagname|exif_thumbnail|exit|exp|expect_expectl|expect_popen|explode|expm1|export|export|extension_loaded|extract|ezmlm_hash|fam_cancel_monitor|fam_close|fam_monitor_collection|fam_monitor_directory|fam_monitor_file|fam_next_event|fam_open|fam_pending|fam_resume_monitor|fam_suspend_monitor|fbsql_affected_rows|fbsql_autocommit|fbsql_blob_size|fbsql_change_user|fbsql_clob_size|fbsql_close|fbsql_commit|fbsql_connect|fbsql_create_blob|fbsql_create_clob|fbsql_create_db|fbsql_data_seek|fbsql_database|fbsql_database_password|fbsql_db_query|fbsql_db_status|fbsql_drop_db|fbsql_errno|fbsql_error|fbsql_fetch_array|fbsql_fetch_assoc|fbsql_fetch_field|fbsql_fetch_lengths|fbsql_fetch_object|fbsql_fetch_row|fbsql_field_flags|fbsql_field_len|fbsql_field_name|fbsql_field_seek|fbsql_field_table|fbsql_field_type|fbsql_free_result|fbsql_get_autostart_info|fbsql_hostname|fbsql_insert_id|fbsql_list_dbs|fbsql_list_fields|fbsql_list_tables|fbsql_next_result|fbsql_num_fields|fbsql_num_rows|fbsql_password|fbsql_pconnect|fbsql_query|fbsql_read_blob|fbsql_read_clob|fbsql_result|fbsql_rollback|fbsql_rows_fetched|fbsql_select_db|fbsql_set_characterset|fbsql_set_lob_mode|fbsql_set_password|fbsql_set_transaction|fbsql_start_db|fbsql_stop_db|fbsql_table_name|fbsql_tablename|fbsql_username|fbsql_warnings|fclose|fdf_add_doc_javascript|fdf_add_template|fdf_close|fdf_create|fdf_enum_values|fdf_errno|fdf_error|fdf_get_ap|fdf_get_attachment|fdf_get_encoding|fdf_get_file|fdf_get_flags|fdf_get_opt|fdf_get_status|fdf_get_value|fdf_get_version|fdf_header|fdf_next_field_name|fdf_open|fdf_open_string|fdf_remove_item|fdf_save|fdf_save_string|fdf_set_ap|fdf_set_encoding|fdf_set_file|fdf_set_flags|fdf_set_javascript_action|fdf_set_on_import_javascript|fdf_set_opt|fdf_set_status|fdf_set_submit_form_action|fdf_set_target_frame|fdf_set_value|fdf_set_version|feof|fflush|fgetc|fgetcsv|fgets|fgetss|file|file_exists|file_get_contents|file_put_contents|fileatime|filectime|filegroup|fileinode|filemtime|fileowner|fileperms|filepro|filepro_fieldcount|filepro_fieldname|filepro_fieldtype|filepro_fieldwidth|filepro_retrieve|filepro_rowcount|filesize|filesystemiterator|filetype|filter_has_var|filter_id|filter_input|filter_input_array|filter_list|filter_var|filter_var_array|filteriterator|finfo_buffer|finfo_close|finfo_file|finfo_open|finfo_set_flags|floatval|flock|floor|flush|fmod|fnmatch|fopen|forward_static_call|forward_static_call_array|fpassthru|fprintf|fputcsv|fputs|fread|frenchtojd|fribidi_log2vis|fscanf|fseek|fsockopen|fstat|ftell|ftok|ftp_alloc|ftp_cdup|ftp_chdir|ftp_chmod|ftp_close|ftp_connect|ftp_delete|ftp_exec|ftp_fget|ftp_fput|ftp_get|ftp_get_option|ftp_login|ftp_mdtm|ftp_mkdir|ftp_nb_continue|ftp_nb_fget|ftp_nb_fput|ftp_nb_get|ftp_nb_put|ftp_nlist|ftp_pasv|ftp_put|ftp_pwd|ftp_quit|ftp_raw|ftp_rawlist|ftp_rename|ftp_rmdir|ftp_set_option|ftp_site|ftp_size|ftp_ssl_connect|ftp_systype|ftruncate|func_get_arg|func_get_args|func_num_args|function_exists|fwrite|gc_collect_cycles|gc_disable|gc_enable|gc_enabled|gd_info|gearmanclient|gearmanjob|gearmantask|gearmanworker|geoip_continent_code_by_name|geoip_country_code3_by_name|geoip_country_code_by_name|geoip_country_name_by_name|geoip_database_info|geoip_db_avail|geoip_db_filename|geoip_db_get_all_info|geoip_id_by_name|geoip_isp_by_name|geoip_org_by_name|geoip_record_by_name|geoip_region_by_name|geoip_region_name_by_code|geoip_time_zone_by_country_and_region|getMeta|getNamed|getValue|get_browser|get_called_class|get_cfg_var|get_class|get_class_methods|get_class_vars|get_current_user|get_declared_classes|get_declared_interfaces|get_defined_constants|get_defined_functions|get_defined_vars|get_extension_funcs|get_headers|get_html_translation_table|get_include_path|get_included_files|get_loaded_extensions|get_magic_quotes_gpc|get_magic_quotes_runtime|get_meta_tags|get_object_vars|get_parent_class|get_required_files|get_resource_type|getallheaders|getconstant|getconstants|getconstructor|getcwd|getdate|getdefaultproperties|getdoccomment|getendline|getenv|getextension|getextensionname|getfilename|gethostbyaddr|gethostbyname|gethostbynamel|gethostname|getimagesize|getinterfacenames|getinterfaces|getlastmod|getmethod|getmethods|getmodifiers|getmxrr|getmygid|getmyinode|getmypid|getmyuid|getname|getnamespacename|getopt|getparentclass|getproperties|getproperty|getprotobyname|getprotobynumber|getrandmax|getrusage|getservbyname|getservbyport|getshortname|getstartline|getstaticproperties|getstaticpropertyvalue|gettext|gettimeofday|gettype|glob|globiterator|gmagick|gmagickdraw|gmagickpixel|gmdate|gmmktime|gmp_abs|gmp_add|gmp_and|gmp_clrbit|gmp_cmp|gmp_com|gmp_div|gmp_div_q|gmp_div_qr|gmp_div_r|gmp_divexact|gmp_fact|gmp_gcd|gmp_gcdext|gmp_hamdist|gmp_init|gmp_intval|gmp_invert|gmp_jacobi|gmp_legendre|gmp_mod|gmp_mul|gmp_neg|gmp_nextprime|gmp_or|gmp_perfect_square|gmp_popcount|gmp_pow|gmp_powm|gmp_prob_prime|gmp_random|gmp_scan0|gmp_scan1|gmp_setbit|gmp_sign|gmp_sqrt|gmp_sqrtrem|gmp_strval|gmp_sub|gmp_testbit|gmp_xor|gmstrftime|gnupg_adddecryptkey|gnupg_addencryptkey|gnupg_addsignkey|gnupg_cleardecryptkeys|gnupg_clearencryptkeys|gnupg_clearsignkeys|gnupg_decrypt|gnupg_decryptverify|gnupg_encrypt|gnupg_encryptsign|gnupg_export|gnupg_geterror|gnupg_getprotocol|gnupg_import|gnupg_init|gnupg_keyinfo|gnupg_setarmor|gnupg_seterrormode|gnupg_setsignmode|gnupg_sign|gnupg_verify|gopher_parsedir|grapheme_extract|grapheme_stripos|grapheme_stristr|grapheme_strlen|grapheme_strpos|grapheme_strripos|grapheme_strrpos|grapheme_strstr|grapheme_substr|gregoriantojd|gupnp_context_get_host_ip|gupnp_context_get_port|gupnp_context_get_subscription_timeout|gupnp_context_host_path|gupnp_context_new|gupnp_context_set_subscription_timeout|gupnp_context_timeout_add|gupnp_context_unhost_path|gupnp_control_point_browse_start|gupnp_control_point_browse_stop|gupnp_control_point_callback_set|gupnp_control_point_new|gupnp_device_action_callback_set|gupnp_device_info_get|gupnp_device_info_get_service|gupnp_root_device_get_available|gupnp_root_device_get_relative_location|gupnp_root_device_new|gupnp_root_device_set_available|gupnp_root_device_start|gupnp_root_device_stop|gupnp_service_action_get|gupnp_service_action_return|gupnp_service_action_return_error|gupnp_service_action_set|gupnp_service_freeze_notify|gupnp_service_info_get|gupnp_service_info_get_introspection|gupnp_service_introspection_get_state_variable|gupnp_service_notify|gupnp_service_proxy_action_get|gupnp_service_proxy_action_set|gupnp_service_proxy_add_notify|gupnp_service_proxy_callback_set|gupnp_service_proxy_get_subscribed|gupnp_service_proxy_remove_notify|gupnp_service_proxy_set_subscribed|gupnp_service_thaw_notify|gzclose|gzcompress|gzdecode|gzdeflate|gzencode|gzeof|gzfile|gzgetc|gzgets|gzgetss|gzinflate|gzopen|gzpassthru|gzputs|gzread|gzrewind|gzseek|gztell|gzuncompress|gzwrite|halt_compiler|haruannotation|haruannotation_setborderstyle|haruannotation_sethighlightmode|haruannotation_seticon|haruannotation_setopened|harudestination|harudestination_setfit|harudestination_setfitb|harudestination_setfitbh|harudestination_setfitbv|harudestination_setfith|harudestination_setfitr|harudestination_setfitv|harudestination_setxyz|harudoc|harudoc_addpage|harudoc_addpagelabel|harudoc_construct|harudoc_createoutline|harudoc_getcurrentencoder|harudoc_getcurrentpage|harudoc_getencoder|harudoc_getfont|harudoc_getinfoattr|harudoc_getpagelayout|harudoc_getpagemode|harudoc_getstreamsize|harudoc_insertpage|harudoc_loadjpeg|harudoc_loadpng|harudoc_loadraw|harudoc_loadttc|harudoc_loadttf|harudoc_loadtype1|harudoc_output|harudoc_readfromstream|harudoc_reseterror|harudoc_resetstream|harudoc_save|harudoc_savetostream|harudoc_setcompressionmode|harudoc_setcurrentencoder|harudoc_setencryptionmode|harudoc_setinfoattr|harudoc_setinfodateattr|harudoc_setopenaction|harudoc_setpagelayout|harudoc_setpagemode|harudoc_setpagesconfiguration|harudoc_setpassword|harudoc_setpermission|harudoc_usecnsencodings|harudoc_usecnsfonts|harudoc_usecntencodings|harudoc_usecntfonts|harudoc_usejpencodings|harudoc_usejpfonts|harudoc_usekrencodings|harudoc_usekrfonts|haruencoder|haruencoder_getbytetype|haruencoder_gettype|haruencoder_getunicode|haruencoder_getwritingmode|haruexception|harufont|harufont_getascent|harufont_getcapheight|harufont_getdescent|harufont_getencodingname|harufont_getfontname|harufont_gettextwidth|harufont_getunicodewidth|harufont_getxheight|harufont_measuretext|haruimage|haruimage_getbitspercomponent|haruimage_getcolorspace|haruimage_getheight|haruimage_getsize|haruimage_getwidth|haruimage_setcolormask|haruimage_setmaskimage|haruoutline|haruoutline_setdestination|haruoutline_setopened|harupage|harupage_arc|harupage_begintext|harupage_circle|harupage_closepath|harupage_concat|harupage_createdestination|harupage_createlinkannotation|harupage_createtextannotation|harupage_createurlannotation|harupage_curveto|harupage_curveto2|harupage_curveto3|harupage_drawimage|harupage_ellipse|harupage_endpath|harupage_endtext|harupage_eofill|harupage_eofillstroke|harupage_fill|harupage_fillstroke|harupage_getcharspace|harupage_getcmykfill|harupage_getcmykstroke|harupage_getcurrentfont|harupage_getcurrentfontsize|harupage_getcurrentpos|harupage_getcurrenttextpos|harupage_getdash|harupage_getfillingcolorspace|harupage_getflatness|harupage_getgmode|harupage_getgrayfill|harupage_getgraystroke|harupage_getheight|harupage_gethorizontalscaling|harupage_getlinecap|harupage_getlinejoin|harupage_getlinewidth|harupage_getmiterlimit|harupage_getrgbfill|harupage_getrgbstroke|harupage_getstrokingcolorspace|harupage_gettextleading|harupage_gettextmatrix|harupage_gettextrenderingmode|harupage_gettextrise|harupage_gettextwidth|harupage_gettransmatrix|harupage_getwidth|harupage_getwordspace|harupage_lineto|harupage_measuretext|harupage_movetextpos|harupage_moveto|harupage_movetonextline|harupage_rectangle|harupage_setcharspace|harupage_setcmykfill|harupage_setcmykstroke|harupage_setdash|harupage_setflatness|harupage_setfontandsize|harupage_setgrayfill|harupage_setgraystroke|harupage_setheight|harupage_sethorizontalscaling|harupage_setlinecap|harupage_setlinejoin|harupage_setlinewidth|harupage_setmiterlimit|harupage_setrgbfill|harupage_setrgbstroke|harupage_setrotate|harupage_setsize|harupage_setslideshow|harupage_settextleading|harupage_settextmatrix|harupage_settextrenderingmode|harupage_settextrise|harupage_setwidth|harupage_setwordspace|harupage_showtext|harupage_showtextnextline|harupage_stroke|harupage_textout|harupage_textrect|hasconstant|hash|hash_algos|hash_copy|hash_file|hash_final|hash_hmac|hash_hmac_file|hash_init|hash_update|hash_update_file|hash_update_stream|hasmethod|hasproperty|header|header_register_callback|header_remove|headers_list|headers_sent|hebrev|hebrevc|hex2bin|hexdec|highlight_file|highlight_string|html_entity_decode|htmlentities|htmlspecialchars|htmlspecialchars_decode|http_build_cookie|http_build_query|http_build_str|http_build_url|http_cache_etag|http_cache_last_modified|http_chunked_decode|http_date|http_deflate|http_get|http_get_request_body|http_get_request_body_stream|http_get_request_headers|http_head|http_inflate|http_match_etag|http_match_modified|http_match_request_header|http_negotiate_charset|http_negotiate_content_type|http_negotiate_language|http_parse_cookie|http_parse_headers|http_parse_message|http_parse_params|http_persistent_handles_clean|http_persistent_handles_count|http_persistent_handles_ident|http_post_data|http_post_fields|http_put_data|http_put_file|http_put_stream|http_redirect|http_request|http_request_body_encode|http_request_method_exists|http_request_method_name|http_request_method_register|http_request_method_unregister|http_response_code|http_send_content_disposition|http_send_content_type|http_send_data|http_send_file|http_send_last_modified|http_send_status|http_send_stream|http_support|http_throttle|httpdeflatestream|httpdeflatestream_construct|httpdeflatestream_factory|httpdeflatestream_finish|httpdeflatestream_flush|httpdeflatestream_update|httpinflatestream|httpinflatestream_construct|httpinflatestream_factory|httpinflatestream_finish|httpinflatestream_flush|httpinflatestream_update|httpmessage|httpmessage_addheaders|httpmessage_construct|httpmessage_detach|httpmessage_factory|httpmessage_fromenv|httpmessage_fromstring|httpmessage_getbody|httpmessage_getheader|httpmessage_getheaders|httpmessage_gethttpversion|httpmessage_getparentmessage|httpmessage_getrequestmethod|httpmessage_getrequesturl|httpmessage_getresponsecode|httpmessage_getresponsestatus|httpmessage_gettype|httpmessage_guesscontenttype|httpmessage_prepend|httpmessage_reverse|httpmessage_send|httpmessage_setbody|httpmessage_setheaders|httpmessage_sethttpversion|httpmessage_setrequestmethod|httpmessage_setrequesturl|httpmessage_setresponsecode|httpmessage_setresponsestatus|httpmessage_settype|httpmessage_tomessagetypeobject|httpmessage_tostring|httpquerystring|httpquerystring_construct|httpquerystring_get|httpquerystring_mod|httpquerystring_set|httpquerystring_singleton|httpquerystring_toarray|httpquerystring_tostring|httpquerystring_xlate|httprequest|httprequest_addcookies|httprequest_addheaders|httprequest_addpostfields|httprequest_addpostfile|httprequest_addputdata|httprequest_addquerydata|httprequest_addrawpostdata|httprequest_addssloptions|httprequest_clearhistory|httprequest_construct|httprequest_enablecookies|httprequest_getcontenttype|httprequest_getcookies|httprequest_getheaders|httprequest_gethistory|httprequest_getmethod|httprequest_getoptions|httprequest_getpostfields|httprequest_getpostfiles|httprequest_getputdata|httprequest_getputfile|httprequest_getquerydata|httprequest_getrawpostdata|httprequest_getrawrequestmessage|httprequest_getrawresponsemessage|httprequest_getrequestmessage|httprequest_getresponsebody|httprequest_getresponsecode|httprequest_getresponsecookies|httprequest_getresponsedata|httprequest_getresponseheader|httprequest_getresponseinfo|httprequest_getresponsemessage|httprequest_getresponsestatus|httprequest_getssloptions|httprequest_geturl|httprequest_resetcookies|httprequest_send|httprequest_setcontenttype|httprequest_setcookies|httprequest_setheaders|httprequest_setmethod|httprequest_setoptions|httprequest_setpostfields|httprequest_setpostfiles|httprequest_setputdata|httprequest_setputfile|httprequest_setquerydata|httprequest_setrawpostdata|httprequest_setssloptions|httprequest_seturl|httprequestpool|httprequestpool_attach|httprequestpool_construct|httprequestpool_destruct|httprequestpool_detach|httprequestpool_getattachedrequests|httprequestpool_getfinishedrequests|httprequestpool_reset|httprequestpool_send|httprequestpool_socketperform|httprequestpool_socketselect|httpresponse|httpresponse_capture|httpresponse_getbuffersize|httpresponse_getcache|httpresponse_getcachecontrol|httpresponse_getcontentdisposition|httpresponse_getcontenttype|httpresponse_getdata|httpresponse_getetag|httpresponse_getfile|httpresponse_getgzip|httpresponse_getheader|httpresponse_getlastmodified|httpresponse_getrequestbody|httpresponse_getrequestbodystream|httpresponse_getrequestheaders|httpresponse_getstream|httpresponse_getthrottledelay|httpresponse_guesscontenttype|httpresponse_redirect|httpresponse_send|httpresponse_setbuffersize|httpresponse_setcache|httpresponse_setcachecontrol|httpresponse_setcontentdisposition|httpresponse_setcontenttype|httpresponse_setdata|httpresponse_setetag|httpresponse_setfile|httpresponse_setgzip|httpresponse_setheader|httpresponse_setlastmodified|httpresponse_setstream|httpresponse_setthrottledelay|httpresponse_status|hw_array2objrec|hw_changeobject|hw_children|hw_childrenobj|hw_close|hw_connect|hw_connection_info|hw_cp|hw_deleteobject|hw_docbyanchor|hw_docbyanchorobj|hw_document_attributes|hw_document_bodytag|hw_document_content|hw_document_setcontent|hw_document_size|hw_dummy|hw_edittext|hw_error|hw_errormsg|hw_free_document|hw_getanchors|hw_getanchorsobj|hw_getandlock|hw_getchildcoll|hw_getchildcollobj|hw_getchilddoccoll|hw_getchilddoccollobj|hw_getobject|hw_getobjectbyquery|hw_getobjectbyquerycoll|hw_getobjectbyquerycollobj|hw_getobjectbyqueryobj|hw_getparents|hw_getparentsobj|hw_getrellink|hw_getremote|hw_getremotechildren|hw_getsrcbydestobj|hw_gettext|hw_getusername|hw_identify|hw_incollections|hw_info|hw_inscoll|hw_insdoc|hw_insertanchors|hw_insertdocument|hw_insertobject|hw_mapid|hw_modifyobject|hw_mv|hw_new_document|hw_objrec2array|hw_output_document|hw_pconnect|hw_pipedocument|hw_root|hw_setlinkroot|hw_stat|hw_unlock|hw_who|hwapi_attribute|hwapi_attribute_key|hwapi_attribute_langdepvalue|hwapi_attribute_value|hwapi_attribute_values|hwapi_checkin|hwapi_checkout|hwapi_children|hwapi_content|hwapi_content_mimetype|hwapi_content_read|hwapi_copy|hwapi_dbstat|hwapi_dcstat|hwapi_dstanchors|hwapi_dstofsrcanchor|hwapi_error_count|hwapi_error_reason|hwapi_find|hwapi_ftstat|hwapi_hgcsp|hwapi_hwstat|hwapi_identify|hwapi_info|hwapi_insert|hwapi_insertanchor|hwapi_insertcollection|hwapi_insertdocument|hwapi_link|hwapi_lock|hwapi_move|hwapi_new_content|hwapi_object|hwapi_object_assign|hwapi_object_attreditable|hwapi_object_count|hwapi_object_insert|hwapi_object_new|hwapi_object_remove|hwapi_object_title|hwapi_object_value|hwapi_objectbyanchor|hwapi_parents|hwapi_reason_description|hwapi_reason_type|hwapi_remove|hwapi_replace|hwapi_setcommittedversion|hwapi_srcanchors|hwapi_srcsofdst|hwapi_unlock|hwapi_user|hwapi_userlist|hypot|ibase_add_user|ibase_affected_rows|ibase_backup|ibase_blob_add|ibase_blob_cancel|ibase_blob_close|ibase_blob_create|ibase_blob_echo|ibase_blob_get|ibase_blob_import|ibase_blob_info|ibase_blob_open|ibase_close|ibase_commit|ibase_commit_ret|ibase_connect|ibase_db_info|ibase_delete_user|ibase_drop_db|ibase_errcode|ibase_errmsg|ibase_execute|ibase_fetch_assoc|ibase_fetch_object|ibase_fetch_row|ibase_field_info|ibase_free_event_handler|ibase_free_query|ibase_free_result|ibase_gen_id|ibase_maintain_db|ibase_modify_user|ibase_name_result|ibase_num_fields|ibase_num_params|ibase_param_info|ibase_pconnect|ibase_prepare|ibase_query|ibase_restore|ibase_rollback|ibase_rollback_ret|ibase_server_info|ibase_service_attach|ibase_service_detach|ibase_set_event_handler|ibase_timefmt|ibase_trans|ibase_wait_event|iconv|iconv_get_encoding|iconv_mime_decode|iconv_mime_decode_headers|iconv_mime_encode|iconv_set_encoding|iconv_strlen|iconv_strpos|iconv_strrpos|iconv_substr|id3_get_frame_long_name|id3_get_frame_short_name|id3_get_genre_id|id3_get_genre_list|id3_get_genre_name|id3_get_tag|id3_get_version|id3_remove_tag|id3_set_tag|id3v2attachedpictureframe|id3v2frame|id3v2tag|idate|idn_to_ascii|idn_to_unicode|idn_to_utf8|ifx_affected_rows|ifx_blobinfile_mode|ifx_byteasvarchar|ifx_close|ifx_connect|ifx_copy_blob|ifx_create_blob|ifx_create_char|ifx_do|ifx_error|ifx_errormsg|ifx_fetch_row|ifx_fieldproperties|ifx_fieldtypes|ifx_free_blob|ifx_free_char|ifx_free_result|ifx_get_blob|ifx_get_char|ifx_getsqlca|ifx_htmltbl_result|ifx_nullformat|ifx_num_fields|ifx_num_rows|ifx_pconnect|ifx_prepare|ifx_query|ifx_textasvarchar|ifx_update_blob|ifx_update_char|ifxus_close_slob|ifxus_create_slob|ifxus_free_slob|ifxus_open_slob|ifxus_read_slob|ifxus_seek_slob|ifxus_tell_slob|ifxus_write_slob|ignore_user_abort|iis_add_server|iis_get_dir_security|iis_get_script_map|iis_get_server_by_comment|iis_get_server_by_path|iis_get_server_rights|iis_get_service_state|iis_remove_server|iis_set_app_settings|iis_set_dir_security|iis_set_script_map|iis_set_server_rights|iis_start_server|iis_start_service|iis_stop_server|iis_stop_service|image2wbmp|image_type_to_extension|image_type_to_mime_type|imagealphablending|imageantialias|imagearc|imagechar|imagecharup|imagecolorallocate|imagecolorallocatealpha|imagecolorat|imagecolorclosest|imagecolorclosestalpha|imagecolorclosesthwb|imagecolordeallocate|imagecolorexact|imagecolorexactalpha|imagecolormatch|imagecolorresolve|imagecolorresolvealpha|imagecolorset|imagecolorsforindex|imagecolorstotal|imagecolortransparent|imageconvolution|imagecopy|imagecopymerge|imagecopymergegray|imagecopyresampled|imagecopyresized|imagecreate|imagecreatefromgd|imagecreatefromgd2|imagecreatefromgd2part|imagecreatefromgif|imagecreatefromjpeg|imagecreatefrompng|imagecreatefromstring|imagecreatefromwbmp|imagecreatefromxbm|imagecreatefromxpm|imagecreatetruecolor|imagedashedline|imagedestroy|imageellipse|imagefill|imagefilledarc|imagefilledellipse|imagefilledpolygon|imagefilledrectangle|imagefilltoborder|imagefilter|imagefontheight|imagefontwidth|imageftbbox|imagefttext|imagegammacorrect|imagegd|imagegd2|imagegif|imagegrabscreen|imagegrabwindow|imageinterlace|imageistruecolor|imagejpeg|imagelayereffect|imageline|imageloadfont|imagepalettecopy|imagepng|imagepolygon|imagepsbbox|imagepsencodefont|imagepsextendfont|imagepsfreefont|imagepsloadfont|imagepsslantfont|imagepstext|imagerectangle|imagerotate|imagesavealpha|imagesetbrush|imagesetpixel|imagesetstyle|imagesetthickness|imagesettile|imagestring|imagestringup|imagesx|imagesy|imagetruecolortopalette|imagettfbbox|imagettftext|imagetypes|imagewbmp|imagexbm|imagick|imagick_adaptiveblurimage|imagick_adaptiveresizeimage|imagick_adaptivesharpenimage|imagick_adaptivethresholdimage|imagick_addimage|imagick_addnoiseimage|imagick_affinetransformimage|imagick_animateimages|imagick_annotateimage|imagick_appendimages|imagick_averageimages|imagick_blackthresholdimage|imagick_blurimage|imagick_borderimage|imagick_charcoalimage|imagick_chopimage|imagick_clear|imagick_clipimage|imagick_clippathimage|imagick_clone|imagick_clutimage|imagick_coalesceimages|imagick_colorfloodfillimage|imagick_colorizeimage|imagick_combineimages|imagick_commentimage|imagick_compareimagechannels|imagick_compareimagelayers|imagick_compareimages|imagick_compositeimage|imagick_construct|imagick_contrastimage|imagick_contraststretchimage|imagick_convolveimage|imagick_cropimage|imagick_cropthumbnailimage|imagick_current|imagick_cyclecolormapimage|imagick_decipherimage|imagick_deconstructimages|imagick_deleteimageartifact|imagick_despeckleimage|imagick_destroy|imagick_displayimage|imagick_displayimages|imagick_distortimage|imagick_drawimage|imagick_edgeimage|imagick_embossimage|imagick_encipherimage|imagick_enhanceimage|imagick_equalizeimage|imagick_evaluateimage|imagick_extentimage|imagick_flattenimages|imagick_flipimage|imagick_floodfillpaintimage|imagick_flopimage|imagick_frameimage|imagick_fximage|imagick_gammaimage|imagick_gaussianblurimage|imagick_getcolorspace|imagick_getcompression|imagick_getcompressionquality|imagick_getcopyright|imagick_getfilename|imagick_getfont|imagick_getformat|imagick_getgravity|imagick_gethomeurl|imagick_getimage|imagick_getimagealphachannel|imagick_getimageartifact|imagick_getimagebackgroundcolor|imagick_getimageblob|imagick_getimageblueprimary|imagick_getimagebordercolor|imagick_getimagechanneldepth|imagick_getimagechanneldistortion|imagick_getimagechanneldistortions|imagick_getimagechannelextrema|imagick_getimagechannelmean|imagick_getimagechannelrange|imagick_getimagechannelstatistics|imagick_getimageclipmask|imagick_getimagecolormapcolor|imagick_getimagecolors|imagick_getimagecolorspace|imagick_getimagecompose|imagick_getimagecompression|imagick_getimagecompressionquality|imagick_getimagedelay|imagick_getimagedepth|imagick_getimagedispose|imagick_getimagedistortion|imagick_getimageextrema|imagick_getimagefilename|imagick_getimageformat|imagick_getimagegamma|imagick_getimagegeometry|imagick_getimagegravity|imagick_getimagegreenprimary|imagick_getimageheight|imagick_getimagehistogram|imagick_getimageindex|imagick_getimageinterlacescheme|imagick_getimageinterpolatemethod|imagick_getimageiterations|imagick_getimagelength|imagick_getimagemagicklicense|imagick_getimagematte|imagick_getimagemattecolor|imagick_getimageorientation|imagick_getimagepage|imagick_getimagepixelcolor|imagick_getimageprofile|imagick_getimageprofiles|imagick_getimageproperties|imagick_getimageproperty|imagick_getimageredprimary|imagick_getimageregion|imagick_getimagerenderingintent|imagick_getimageresolution|imagick_getimagesblob|imagick_getimagescene|imagick_getimagesignature|imagick_getimagesize|imagick_getimagetickspersecond|imagick_getimagetotalinkdensity|imagick_getimagetype|imagick_getimageunits|imagick_getimagevirtualpixelmethod|imagick_getimagewhitepoint|imagick_getimagewidth|imagick_getinterlacescheme|imagick_getiteratorindex|imagick_getnumberimages|imagick_getoption|imagick_getpackagename|imagick_getpage|imagick_getpixeliterator|imagick_getpixelregioniterator|imagick_getpointsize|imagick_getquantumdepth|imagick_getquantumrange|imagick_getreleasedate|imagick_getresource|imagick_getresourcelimit|imagick_getsamplingfactors|imagick_getsize|imagick_getsizeoffset|imagick_getversion|imagick_hasnextimage|imagick_haspreviousimage|imagick_identifyimage|imagick_implodeimage|imagick_labelimage|imagick_levelimage|imagick_linearstretchimage|imagick_liquidrescaleimage|imagick_magnifyimage|imagick_mapimage|imagick_mattefloodfillimage|imagick_medianfilterimage|imagick_mergeimagelayers|imagick_minifyimage|imagick_modulateimage|imagick_montageimage|imagick_morphimages|imagick_mosaicimages|imagick_motionblurimage|imagick_negateimage|imagick_newimage|imagick_newpseudoimage|imagick_nextimage|imagick_normalizeimage|imagick_oilpaintimage|imagick_opaquepaintimage|imagick_optimizeimagelayers|imagick_orderedposterizeimage|imagick_paintfloodfillimage|imagick_paintopaqueimage|imagick_painttransparentimage|imagick_pingimage|imagick_pingimageblob|imagick_pingimagefile|imagick_polaroidimage|imagick_posterizeimage|imagick_previewimages|imagick_previousimage|imagick_profileimage|imagick_quantizeimage|imagick_quantizeimages|imagick_queryfontmetrics|imagick_queryfonts|imagick_queryformats|imagick_radialblurimage|imagick_raiseimage|imagick_randomthresholdimage|imagick_readimage|imagick_readimageblob|imagick_readimagefile|imagick_recolorimage|imagick_reducenoiseimage|imagick_removeimage|imagick_removeimageprofile|imagick_render|imagick_resampleimage|imagick_resetimagepage|imagick_resizeimage|imagick_rollimage|imagick_rotateimage|imagick_roundcorners|imagick_sampleimage|imagick_scaleimage|imagick_separateimagechannel|imagick_sepiatoneimage|imagick_setbackgroundcolor|imagick_setcolorspace|imagick_setcompression|imagick_setcompressionquality|imagick_setfilename|imagick_setfirstiterator|imagick_setfont|imagick_setformat|imagick_setgravity|imagick_setimage|imagick_setimagealphachannel|imagick_setimageartifact|imagick_setimagebackgroundcolor|imagick_setimagebias|imagick_setimageblueprimary|imagick_setimagebordercolor|imagick_setimagechanneldepth|imagick_setimageclipmask|imagick_setimagecolormapcolor|imagick_setimagecolorspace|imagick_setimagecompose|imagick_setimagecompression|imagick_setimagecompressionquality|imagick_setimagedelay|imagick_setimagedepth|imagick_setimagedispose|imagick_setimageextent|imagick_setimagefilename|imagick_setimageformat|imagick_setimagegamma|imagick_setimagegravity|imagick_setimagegreenprimary|imagick_setimageindex|imagick_setimageinterlacescheme|imagick_setimageinterpolatemethod|imagick_setimageiterations|imagick_setimagematte|imagick_setimagemattecolor|imagick_setimageopacity|imagick_setimageorientation|imagick_setimagepage|imagick_setimageprofile|imagick_setimageproperty|imagick_setimageredprimary|imagick_setimagerenderingintent|imagick_setimageresolution|imagick_setimagescene|imagick_setimagetickspersecond|imagick_setimagetype|imagick_setimageunits|imagick_setimagevirtualpixelmethod|imagick_setimagewhitepoint|imagick_setinterlacescheme|imagick_setiteratorindex|imagick_setlastiterator|imagick_setoption|imagick_setpage|imagick_setpointsize|imagick_setresolution|imagick_setresourcelimit|imagick_setsamplingfactors|imagick_setsize|imagick_setsizeoffset|imagick_settype|imagick_shadeimage|imagick_shadowimage|imagick_sharpenimage|imagick_shaveimage|imagick_shearimage|imagick_sigmoidalcontrastimage|imagick_sketchimage|imagick_solarizeimage|imagick_spliceimage|imagick_spreadimage|imagick_steganoimage|imagick_stereoimage|imagick_stripimage|imagick_swirlimage|imagick_textureimage|imagick_thresholdimage|imagick_thumbnailimage|imagick_tintimage|imagick_transformimage|imagick_transparentpaintimage|imagick_transposeimage|imagick_transverseimage|imagick_trimimage|imagick_uniqueimagecolors|imagick_unsharpmaskimage|imagick_valid|imagick_vignetteimage|imagick_waveimage|imagick_whitethresholdimage|imagick_writeimage|imagick_writeimagefile|imagick_writeimages|imagick_writeimagesfile|imagickdraw|imagickdraw_affine|imagickdraw_annotation|imagickdraw_arc|imagickdraw_bezier|imagickdraw_circle|imagickdraw_clear|imagickdraw_clone|imagickdraw_color|imagickdraw_comment|imagickdraw_composite|imagickdraw_construct|imagickdraw_destroy|imagickdraw_ellipse|imagickdraw_getclippath|imagickdraw_getcliprule|imagickdraw_getclipunits|imagickdraw_getfillcolor|imagickdraw_getfillopacity|imagickdraw_getfillrule|imagickdraw_getfont|imagickdraw_getfontfamily|imagickdraw_getfontsize|imagickdraw_getfontstyle|imagickdraw_getfontweight|imagickdraw_getgravity|imagickdraw_getstrokeantialias|imagickdraw_getstrokecolor|imagickdraw_getstrokedasharray|imagickdraw_getstrokedashoffset|imagickdraw_getstrokelinecap|imagickdraw_getstrokelinejoin|imagickdraw_getstrokemiterlimit|imagickdraw_getstrokeopacity|imagickdraw_getstrokewidth|imagickdraw_gettextalignment|imagickdraw_gettextantialias|imagickdraw_gettextdecoration|imagickdraw_gettextencoding|imagickdraw_gettextundercolor|imagickdraw_getvectorgraphics|imagickdraw_line|imagickdraw_matte|imagickdraw_pathclose|imagickdraw_pathcurvetoabsolute|imagickdraw_pathcurvetoquadraticbezierabsolute|imagickdraw_pathcurvetoquadraticbezierrelative|imagickdraw_pathcurvetoquadraticbeziersmoothabsolute|imagickdraw_pathcurvetoquadraticbeziersmoothrelative|imagickdraw_pathcurvetorelative|imagickdraw_pathcurvetosmoothabsolute|imagickdraw_pathcurvetosmoothrelative|imagickdraw_pathellipticarcabsolute|imagickdraw_pathellipticarcrelative|imagickdraw_pathfinish|imagickdraw_pathlinetoabsolute|imagickdraw_pathlinetohorizontalabsolute|imagickdraw_pathlinetohorizontalrelative|imagickdraw_pathlinetorelative|imagickdraw_pathlinetoverticalabsolute|imagickdraw_pathlinetoverticalrelative|imagickdraw_pathmovetoabsolute|imagickdraw_pathmovetorelative|imagickdraw_pathstart|imagickdraw_point|imagickdraw_polygon|imagickdraw_polyline|imagickdraw_pop|imagickdraw_popclippath|imagickdraw_popdefs|imagickdraw_poppattern|imagickdraw_push|imagickdraw_pushclippath|imagickdraw_pushdefs|imagickdraw_pushpattern|imagickdraw_rectangle|imagickdraw_render|imagickdraw_rotate|imagickdraw_roundrectangle|imagickdraw_scale|imagickdraw_setclippath|imagickdraw_setcliprule|imagickdraw_setclipunits|imagickdraw_setfillalpha|imagickdraw_setfillcolor|imagickdraw_setfillopacity|imagickdraw_setfillpatternurl|imagickdraw_setfillrule|imagickdraw_setfont|imagickdraw_setfontfamily|imagickdraw_setfontsize|imagickdraw_setfontstretch|imagickdraw_setfontstyle|imagickdraw_setfontweight|imagickdraw_setgravity|imagickdraw_setstrokealpha|imagickdraw_setstrokeantialias|imagickdraw_setstrokecolor|imagickdraw_setstrokedasharray|imagickdraw_setstrokedashoffset|imagickdraw_setstrokelinecap|imagickdraw_setstrokelinejoin|imagickdraw_setstrokemiterlimit|imagickdraw_setstrokeopacity|imagickdraw_setstrokepatternurl|imagickdraw_setstrokewidth|imagickdraw_settextalignment|imagickdraw_settextantialias|imagickdraw_settextdecoration|imagickdraw_settextencoding|imagickdraw_settextundercolor|imagickdraw_setvectorgraphics|imagickdraw_setviewbox|imagickdraw_skewx|imagickdraw_skewy|imagickdraw_translate|imagickpixel|imagickpixel_clear|imagickpixel_construct|imagickpixel_destroy|imagickpixel_getcolor|imagickpixel_getcolorasstring|imagickpixel_getcolorcount|imagickpixel_getcolorvalue|imagickpixel_gethsl|imagickpixel_issimilar|imagickpixel_setcolor|imagickpixel_setcolorvalue|imagickpixel_sethsl|imagickpixeliterator|imagickpixeliterator_clear|imagickpixeliterator_construct|imagickpixeliterator_destroy|imagickpixeliterator_getcurrentiteratorrow|imagickpixeliterator_getiteratorrow|imagickpixeliterator_getnextiteratorrow|imagickpixeliterator_getpreviousiteratorrow|imagickpixeliterator_newpixeliterator|imagickpixeliterator_newpixelregioniterator|imagickpixeliterator_resetiterator|imagickpixeliterator_setiteratorfirstrow|imagickpixeliterator_setiteratorlastrow|imagickpixeliterator_setiteratorrow|imagickpixeliterator_synciterator|imap_8bit|imap_alerts|imap_append|imap_base64|imap_binary|imap_body|imap_bodystruct|imap_check|imap_clearflag_full|imap_close|imap_create|imap_createmailbox|imap_delete|imap_deletemailbox|imap_errors|imap_expunge|imap_fetch_overview|imap_fetchbody|imap_fetchheader|imap_fetchmime|imap_fetchstructure|imap_fetchtext|imap_gc|imap_get_quota|imap_get_quotaroot|imap_getacl|imap_getmailboxes|imap_getsubscribed|imap_header|imap_headerinfo|imap_headers|imap_last_error|imap_list|imap_listmailbox|imap_listscan|imap_listsubscribed|imap_lsub|imap_mail|imap_mail_compose|imap_mail_copy|imap_mail_move|imap_mailboxmsginfo|imap_mime_header_decode|imap_msgno|imap_num_msg|imap_num_recent|imap_open|imap_ping|imap_qprint|imap_rename|imap_renamemailbox|imap_reopen|imap_rfc822_parse_adrlist|imap_rfc822_parse_headers|imap_rfc822_write_address|imap_savebody|imap_scan|imap_scanmailbox|imap_search|imap_set_quota|imap_setacl|imap_setflag_full|imap_sort|imap_status|imap_subscribe|imap_thread|imap_timeout|imap_uid|imap_undelete|imap_unsubscribe|imap_utf7_decode|imap_utf7_encode|imap_utf8|implementsinterface|implode|import_request_variables|in_array|include|include_once|inclued_get_data|inet_ntop|inet_pton|infiniteiterator|ingres_autocommit|ingres_autocommit_state|ingres_charset|ingres_close|ingres_commit|ingres_connect|ingres_cursor|ingres_errno|ingres_error|ingres_errsqlstate|ingres_escape_string|ingres_execute|ingres_fetch_array|ingres_fetch_assoc|ingres_fetch_object|ingres_fetch_proc_return|ingres_fetch_row|ingres_field_length|ingres_field_name|ingres_field_nullable|ingres_field_precision|ingres_field_scale|ingres_field_type|ingres_free_result|ingres_next_error|ingres_num_fields|ingres_num_rows|ingres_pconnect|ingres_prepare|ingres_query|ingres_result_seek|ingres_rollback|ingres_set_environment|ingres_unbuffered_query|ini_alter|ini_get|ini_get_all|ini_restore|ini_set|innamespace|inotify_add_watch|inotify_init|inotify_queue_len|inotify_read|inotify_rm_watch|interface_exists|intl_error_name|intl_get_error_code|intl_get_error_message|intl_is_failure|intldateformatter|intval|invalidargumentexception|invoke|invokeargs|ip2long|iptcembed|iptcparse|is_a|is_array|is_bool|is_callable|is_dir|is_double|is_executable|is_file|is_finite|is_float|is_infinite|is_int|is_integer|is_link|is_long|is_nan|is_null|is_numeric|is_object|is_readable|is_real|is_resource|is_scalar|is_soap_fault|is_string|is_subclass_of|is_uploaded_file|is_writable|is_writeable|isabstract|iscloneable|isdisabled|isfinal|isinstance|isinstantiable|isinterface|isinternal|isiterateable|isset|issubclassof|isuserdefined|iterator|iterator_apply|iterator_count|iterator_to_array|iteratoraggregate|iteratoriterator|java_last_exception_clear|java_last_exception_get|jddayofweek|jdmonthname|jdtofrench|jdtogregorian|jdtojewish|jdtojulian|jdtounix|jewishtojd|join|jpeg2wbmp|json_decode|json_encode|json_last_error|jsonserializable|judy|judy_type|judy_version|juliantojd|kadm5_chpass_principal|kadm5_create_principal|kadm5_delete_principal|kadm5_destroy|kadm5_flush|kadm5_get_policies|kadm5_get_principal|kadm5_get_principals|kadm5_init_with_password|kadm5_modify_principal|key|krsort|ksort|lcfirst|lcg_value|lchgrp|lchown|ldap_8859_to_t61|ldap_add|ldap_bind|ldap_close|ldap_compare|ldap_connect|ldap_count_entries|ldap_delete|ldap_dn2ufn|ldap_err2str|ldap_errno|ldap_error|ldap_explode_dn|ldap_first_attribute|ldap_first_entry|ldap_first_reference|ldap_free_result|ldap_get_attributes|ldap_get_dn|ldap_get_entries|ldap_get_option|ldap_get_values|ldap_get_values_len|ldap_list|ldap_mod_add|ldap_mod_del|ldap_mod_replace|ldap_modify|ldap_next_attribute|ldap_next_entry|ldap_next_reference|ldap_parse_reference|ldap_parse_result|ldap_read|ldap_rename|ldap_sasl_bind|ldap_search|ldap_set_option|ldap_set_rebind_proc|ldap_sort|ldap_start_tls|ldap_t61_to_8859|ldap_unbind|lengthexception|levenshtein|libxml_clear_errors|libxml_disable_entity_loader|libxml_get_errors|libxml_get_last_error|libxml_set_streams_context|libxml_use_internal_errors|libxmlerror|limititerator|link|linkinfo|list|locale|localeconv|localtime|log|log10|log1p|logicexception|long2ip|lstat|ltrim|lzf_compress|lzf_decompress|lzf_optimized_for|m_checkstatus|m_completeauthorizations|m_connect|m_connectionerror|m_deletetrans|m_destroyconn|m_destroyengine|m_getcell|m_getcellbynum|m_getcommadelimited|m_getheader|m_initconn|m_initengine|m_iscommadelimited|m_maxconntimeout|m_monitor|m_numcolumns|m_numrows|m_parsecommadelimited|m_responsekeys|m_responseparam|m_returnstatus|m_setblocking|m_setdropfile|m_setip|m_setssl|m_setssl_cafile|m_setssl_files|m_settimeout|m_sslcert_gen_hash|m_transactionssent|m_transinqueue|m_transkeyval|m_transnew|m_transsend|m_uwait|m_validateidentifier|m_verifyconnection|m_verifysslcert|magic_quotes_runtime|mail|mailparse_determine_best_xfer_encoding|mailparse_msg_create|mailparse_msg_extract_part|mailparse_msg_extract_part_file|mailparse_msg_extract_whole_part_file|mailparse_msg_free|mailparse_msg_get_part|mailparse_msg_get_part_data|mailparse_msg_get_structure|mailparse_msg_parse|mailparse_msg_parse_file|mailparse_rfc822_parse_addresses|mailparse_stream_encode|mailparse_uudecode_all|main|max|maxdb_affected_rows|maxdb_autocommit|maxdb_bind_param|maxdb_bind_result|maxdb_change_user|maxdb_character_set_name|maxdb_client_encoding|maxdb_close|maxdb_close_long_data|maxdb_commit|maxdb_connect|maxdb_connect_errno|maxdb_connect_error|maxdb_data_seek|maxdb_debug|maxdb_disable_reads_from_master|maxdb_disable_rpl_parse|maxdb_dump_debug_info|maxdb_embedded_connect|maxdb_enable_reads_from_master|maxdb_enable_rpl_parse|maxdb_errno|maxdb_error|maxdb_escape_string|maxdb_execute|maxdb_fetch|maxdb_fetch_array|maxdb_fetch_assoc|maxdb_fetch_field|maxdb_fetch_field_direct|maxdb_fetch_fields|maxdb_fetch_lengths|maxdb_fetch_object|maxdb_fetch_row|maxdb_field_count|maxdb_field_seek|maxdb_field_tell|maxdb_free_result|maxdb_get_client_info|maxdb_get_client_version|maxdb_get_host_info|maxdb_get_metadata|maxdb_get_proto_info|maxdb_get_server_info|maxdb_get_server_version|maxdb_info|maxdb_init|maxdb_insert_id|maxdb_kill|maxdb_master_query|maxdb_more_results|maxdb_multi_query|maxdb_next_result|maxdb_num_fields|maxdb_num_rows|maxdb_options|maxdb_param_count|maxdb_ping|maxdb_prepare|maxdb_query|maxdb_real_connect|maxdb_real_escape_string|maxdb_real_query|maxdb_report|maxdb_rollback|maxdb_rpl_parse_enabled|maxdb_rpl_probe|maxdb_rpl_query_type|maxdb_select_db|maxdb_send_long_data|maxdb_send_query|maxdb_server_end|maxdb_server_init|maxdb_set_opt|maxdb_sqlstate|maxdb_ssl_set|maxdb_stat|maxdb_stmt_affected_rows|maxdb_stmt_bind_param|maxdb_stmt_bind_result|maxdb_stmt_close|maxdb_stmt_close_long_data|maxdb_stmt_data_seek|maxdb_stmt_errno|maxdb_stmt_error|maxdb_stmt_execute|maxdb_stmt_fetch|maxdb_stmt_free_result|maxdb_stmt_init|maxdb_stmt_num_rows|maxdb_stmt_param_count|maxdb_stmt_prepare|maxdb_stmt_reset|maxdb_stmt_result_metadata|maxdb_stmt_send_long_data|maxdb_stmt_sqlstate|maxdb_stmt_store_result|maxdb_store_result|maxdb_thread_id|maxdb_thread_safe|maxdb_use_result|maxdb_warning_count|mb_check_encoding|mb_convert_case|mb_convert_encoding|mb_convert_kana|mb_convert_variables|mb_decode_mimeheader|mb_decode_numericentity|mb_detect_encoding|mb_detect_order|mb_encode_mimeheader|mb_encode_numericentity|mb_encoding_aliases|mb_ereg|mb_ereg_match|mb_ereg_replace|mb_ereg_search|mb_ereg_search_getpos|mb_ereg_search_getregs|mb_ereg_search_init|mb_ereg_search_pos|mb_ereg_search_regs|mb_ereg_search_setpos|mb_eregi|mb_eregi_replace|mb_get_info|mb_http_input|mb_http_output|mb_internal_encoding|mb_language|mb_list_encodings|mb_output_handler|mb_parse_str|mb_preferred_mime_name|mb_regex_encoding|mb_regex_set_options|mb_send_mail|mb_split|mb_strcut|mb_strimwidth|mb_stripos|mb_stristr|mb_strlen|mb_strpos|mb_strrchr|mb_strrichr|mb_strripos|mb_strrpos|mb_strstr|mb_strtolower|mb_strtoupper|mb_strwidth|mb_substitute_character|mb_substr|mb_substr_count|mcrypt_cbc|mcrypt_cfb|mcrypt_create_iv|mcrypt_decrypt|mcrypt_ecb|mcrypt_enc_get_algorithms_name|mcrypt_enc_get_block_size|mcrypt_enc_get_iv_size|mcrypt_enc_get_key_size|mcrypt_enc_get_modes_name|mcrypt_enc_get_supported_key_sizes|mcrypt_enc_is_block_algorithm|mcrypt_enc_is_block_algorithm_mode|mcrypt_enc_is_block_mode|mcrypt_enc_self_test|mcrypt_encrypt|mcrypt_generic|mcrypt_generic_deinit|mcrypt_generic_end|mcrypt_generic_init|mcrypt_get_block_size|mcrypt_get_cipher_name|mcrypt_get_iv_size|mcrypt_get_key_size|mcrypt_list_algorithms|mcrypt_list_modes|mcrypt_module_close|mcrypt_module_get_algo_block_size|mcrypt_module_get_algo_key_size|mcrypt_module_get_supported_key_sizes|mcrypt_module_is_block_algorithm|mcrypt_module_is_block_algorithm_mode|mcrypt_module_is_block_mode|mcrypt_module_open|mcrypt_module_self_test|mcrypt_ofb|md5|md5_file|mdecrypt_generic|memcache|memcache_debug|memcached|memory_get_peak_usage|memory_get_usage|messageformatter|metaphone|method_exists|mhash|mhash_count|mhash_get_block_size|mhash_get_hash_name|mhash_keygen_s2k|microtime|mime_content_type|min|ming_keypress|ming_setcubicthreshold|ming_setscale|ming_setswfcompression|ming_useconstants|ming_useswfversion|mkdir|mktime|money_format|mongo|mongobindata|mongocode|mongocollection|mongoconnectionexception|mongocursor|mongocursorexception|mongocursortimeoutexception|mongodate|mongodb|mongodbref|mongoexception|mongogridfs|mongogridfscursor|mongogridfsexception|mongogridfsfile|mongoid|mongoint32|mongoint64|mongomaxkey|mongominkey|mongoregex|mongotimestamp|move_uploaded_file|mpegfile|mqseries_back|mqseries_begin|mqseries_close|mqseries_cmit|mqseries_conn|mqseries_connx|mqseries_disc|mqseries_get|mqseries_inq|mqseries_open|mqseries_put|mqseries_put1|mqseries_set|mqseries_strerror|msession_connect|msession_count|msession_create|msession_destroy|msession_disconnect|msession_find|msession_get|msession_get_array|msession_get_data|msession_inc|msession_list|msession_listvar|msession_lock|msession_plugin|msession_randstr|msession_set|msession_set_array|msession_set_data|msession_timeout|msession_uniq|msession_unlock|msg_get_queue|msg_queue_exists|msg_receive|msg_remove_queue|msg_send|msg_set_queue|msg_stat_queue|msql|msql_affected_rows|msql_close|msql_connect|msql_create_db|msql_createdb|msql_data_seek|msql_db_query|msql_dbname|msql_drop_db|msql_error|msql_fetch_array|msql_fetch_field|msql_fetch_object|msql_fetch_row|msql_field_flags|msql_field_len|msql_field_name|msql_field_seek|msql_field_table|msql_field_type|msql_fieldflags|msql_fieldlen|msql_fieldname|msql_fieldtable|msql_fieldtype|msql_free_result|msql_list_dbs|msql_list_fields|msql_list_tables|msql_num_fields|msql_num_rows|msql_numfields|msql_numrows|msql_pconnect|msql_query|msql_regcase|msql_result|msql_select_db|msql_tablename|mssql_bind|mssql_close|mssql_connect|mssql_data_seek|mssql_execute|mssql_fetch_array|mssql_fetch_assoc|mssql_fetch_batch|mssql_fetch_field|mssql_fetch_object|mssql_fetch_row|mssql_field_length|mssql_field_name|mssql_field_seek|mssql_field_type|mssql_free_result|mssql_free_statement|mssql_get_last_message|mssql_guid_string|mssql_init|mssql_min_error_severity|mssql_min_message_severity|mssql_next_result|mssql_num_fields|mssql_num_rows|mssql_pconnect|mssql_query|mssql_result|mssql_rows_affected|mssql_select_db|mt_getrandmax|mt_rand|mt_srand|multipleiterator|mysql_affected_rows|mysql_client_encoding|mysql_close|mysql_connect|mysql_create_db|mysql_data_seek|mysql_db_name|mysql_db_query|mysql_drop_db|mysql_errno|mysql_error|mysql_escape_string|mysql_fetch_array|mysql_fetch_assoc|mysql_fetch_field|mysql_fetch_lengths|mysql_fetch_object|mysql_fetch_row|mysql_field_flags|mysql_field_len|mysql_field_name|mysql_field_seek|mysql_field_table|mysql_field_type|mysql_free_result|mysql_get_client_info|mysql_get_host_info|mysql_get_proto_info|mysql_get_server_info|mysql_info|mysql_insert_id|mysql_list_dbs|mysql_list_fields|mysql_list_processes|mysql_list_tables|mysql_num_fields|mysql_num_rows|mysql_pconnect|mysql_ping|mysql_query|mysql_real_escape_string|mysql_result|mysql_select_db|mysql_set_charset|mysql_stat|mysql_tablename|mysql_thread_id|mysql_unbuffered_query|mysqli|mysqli_bind_param|mysqli_bind_result|mysqli_client_encoding|mysqli_connect|mysqli_disable_reads_from_master|mysqli_disable_rpl_parse|mysqli_driver|mysqli_enable_reads_from_master|mysqli_enable_rpl_parse|mysqli_escape_string|mysqli_execute|mysqli_fetch|mysqli_get_metadata|mysqli_master_query|mysqli_param_count|mysqli_report|mysqli_result|mysqli_rpl_parse_enabled|mysqli_rpl_probe|mysqli_rpl_query_type|mysqli_send_long_data|mysqli_send_query|mysqli_set_opt|mysqli_slave_query|mysqli_stmt|mysqli_warning|mysqlnd_ms_get_stats|mysqlnd_ms_query_is_select|mysqlnd_ms_set_user_pick_server|mysqlnd_qc_change_handler|mysqlnd_qc_clear_cache|mysqlnd_qc_get_cache_info|mysqlnd_qc_get_core_stats|mysqlnd_qc_get_handler|mysqlnd_qc_get_query_trace_log|mysqlnd_qc_set_user_handlers|natcasesort|natsort|ncurses_addch|ncurses_addchnstr|ncurses_addchstr|ncurses_addnstr|ncurses_addstr|ncurses_assume_default_colors|ncurses_attroff|ncurses_attron|ncurses_attrset|ncurses_baudrate|ncurses_beep|ncurses_bkgd|ncurses_bkgdset|ncurses_border|ncurses_bottom_panel|ncurses_can_change_color|ncurses_cbreak|ncurses_clear|ncurses_clrtobot|ncurses_clrtoeol|ncurses_color_content|ncurses_color_set|ncurses_curs_set|ncurses_def_prog_mode|ncurses_def_shell_mode|ncurses_define_key|ncurses_del_panel|ncurses_delay_output|ncurses_delch|ncurses_deleteln|ncurses_delwin|ncurses_doupdate|ncurses_echo|ncurses_echochar|ncurses_end|ncurses_erase|ncurses_erasechar|ncurses_filter|ncurses_flash|ncurses_flushinp|ncurses_getch|ncurses_getmaxyx|ncurses_getmouse|ncurses_getyx|ncurses_halfdelay|ncurses_has_colors|ncurses_has_ic|ncurses_has_il|ncurses_has_key|ncurses_hide_panel|ncurses_hline|ncurses_inch|ncurses_init|ncurses_init_color|ncurses_init_pair|ncurses_insch|ncurses_insdelln|ncurses_insertln|ncurses_insstr|ncurses_instr|ncurses_isendwin|ncurses_keyok|ncurses_keypad|ncurses_killchar|ncurses_longname|ncurses_meta|ncurses_mouse_trafo|ncurses_mouseinterval|ncurses_mousemask|ncurses_move|ncurses_move_panel|ncurses_mvaddch|ncurses_mvaddchnstr|ncurses_mvaddchstr|ncurses_mvaddnstr|ncurses_mvaddstr|ncurses_mvcur|ncurses_mvdelch|ncurses_mvgetch|ncurses_mvhline|ncurses_mvinch|ncurses_mvvline|ncurses_mvwaddstr|ncurses_napms|ncurses_new_panel|ncurses_newpad|ncurses_newwin|ncurses_nl|ncurses_nocbreak|ncurses_noecho|ncurses_nonl|ncurses_noqiflush|ncurses_noraw|ncurses_pair_content|ncurses_panel_above|ncurses_panel_below|ncurses_panel_window|ncurses_pnoutrefresh|ncurses_prefresh|ncurses_putp|ncurses_qiflush|ncurses_raw|ncurses_refresh|ncurses_replace_panel|ncurses_reset_prog_mode|ncurses_reset_shell_mode|ncurses_resetty|ncurses_savetty|ncurses_scr_dump|ncurses_scr_init|ncurses_scr_restore|ncurses_scr_set|ncurses_scrl|ncurses_show_panel|ncurses_slk_attr|ncurses_slk_attroff|ncurses_slk_attron|ncurses_slk_attrset|ncurses_slk_clear|ncurses_slk_color|ncurses_slk_init|ncurses_slk_noutrefresh|ncurses_slk_refresh|ncurses_slk_restore|ncurses_slk_set|ncurses_slk_touch|ncurses_standend|ncurses_standout|ncurses_start_color|ncurses_termattrs|ncurses_termname|ncurses_timeout|ncurses_top_panel|ncurses_typeahead|ncurses_ungetch|ncurses_ungetmouse|ncurses_update_panels|ncurses_use_default_colors|ncurses_use_env|ncurses_use_extended_names|ncurses_vidattr|ncurses_vline|ncurses_waddch|ncurses_waddstr|ncurses_wattroff|ncurses_wattron|ncurses_wattrset|ncurses_wborder|ncurses_wclear|ncurses_wcolor_set|ncurses_werase|ncurses_wgetch|ncurses_whline|ncurses_wmouse_trafo|ncurses_wmove|ncurses_wnoutrefresh|ncurses_wrefresh|ncurses_wstandend|ncurses_wstandout|ncurses_wvline|newinstance|newinstanceargs|newt_bell|newt_button|newt_button_bar|newt_centered_window|newt_checkbox|newt_checkbox_get_value|newt_checkbox_set_flags|newt_checkbox_set_value|newt_checkbox_tree|newt_checkbox_tree_add_item|newt_checkbox_tree_find_item|newt_checkbox_tree_get_current|newt_checkbox_tree_get_entry_value|newt_checkbox_tree_get_multi_selection|newt_checkbox_tree_get_selection|newt_checkbox_tree_multi|newt_checkbox_tree_set_current|newt_checkbox_tree_set_entry|newt_checkbox_tree_set_entry_value|newt_checkbox_tree_set_width|newt_clear_key_buffer|newt_cls|newt_compact_button|newt_component_add_callback|newt_component_takes_focus|newt_create_grid|newt_cursor_off|newt_cursor_on|newt_delay|newt_draw_form|newt_draw_root_text|newt_entry|newt_entry_get_value|newt_entry_set|newt_entry_set_filter|newt_entry_set_flags|newt_finished|newt_form|newt_form_add_component|newt_form_add_components|newt_form_add_hot_key|newt_form_destroy|newt_form_get_current|newt_form_run|newt_form_set_background|newt_form_set_height|newt_form_set_size|newt_form_set_timer|newt_form_set_width|newt_form_watch_fd|newt_get_screen_size|newt_grid_add_components_to_form|newt_grid_basic_window|newt_grid_free|newt_grid_get_size|newt_grid_h_close_stacked|newt_grid_h_stacked|newt_grid_place|newt_grid_set_field|newt_grid_simple_window|newt_grid_v_close_stacked|newt_grid_v_stacked|newt_grid_wrapped_window|newt_grid_wrapped_window_at|newt_init|newt_label|newt_label_set_text|newt_listbox|newt_listbox_append_entry|newt_listbox_clear|newt_listbox_clear_selection|newt_listbox_delete_entry|newt_listbox_get_current|newt_listbox_get_selection|newt_listbox_insert_entry|newt_listbox_item_count|newt_listbox_select_item|newt_listbox_set_current|newt_listbox_set_current_by_key|newt_listbox_set_data|newt_listbox_set_entry|newt_listbox_set_width|newt_listitem|newt_listitem_get_data|newt_listitem_set|newt_open_window|newt_pop_help_line|newt_pop_window|newt_push_help_line|newt_radio_get_current|newt_radiobutton|newt_redraw_help_line|newt_reflow_text|newt_refresh|newt_resize_screen|newt_resume|newt_run_form|newt_scale|newt_scale_set|newt_scrollbar_set|newt_set_help_callback|newt_set_suspend_callback|newt_suspend|newt_textbox|newt_textbox_get_num_lines|newt_textbox_reflowed|newt_textbox_set_height|newt_textbox_set_text|newt_vertical_scrollbar|newt_wait_for_key|newt_win_choice|newt_win_entries|newt_win_menu|newt_win_message|newt_win_messagev|newt_win_ternary|next|ngettext|nl2br|nl_langinfo|norewinditerator|normalizer|notes_body|notes_copy_db|notes_create_db|notes_create_note|notes_drop_db|notes_find_note|notes_header_info|notes_list_msgs|notes_mark_read|notes_mark_unread|notes_nav_create|notes_search|notes_unread|notes_version|nsapi_request_headers|nsapi_response_headers|nsapi_virtual|nthmac|number_format|numberformatter|oauth|oauth_get_sbs|oauth_urlencode|oauthexception|oauthprovider|ob_clean|ob_deflatehandler|ob_end_clean|ob_end_flush|ob_etaghandler|ob_flush|ob_get_clean|ob_get_contents|ob_get_flush|ob_get_length|ob_get_level|ob_get_status|ob_gzhandler|ob_iconv_handler|ob_implicit_flush|ob_inflatehandler|ob_list_handlers|ob_start|ob_tidyhandler|oci_bind_array_by_name|oci_bind_by_name|oci_cancel|oci_client_version|oci_close|oci_collection_append|oci_collection_assign|oci_collection_element_assign|oci_collection_element_get|oci_collection_free|oci_collection_max|oci_collection_size|oci_collection_trim|oci_commit|oci_connect|oci_define_by_name|oci_error|oci_execute|oci_fetch|oci_fetch_all|oci_fetch_array|oci_fetch_assoc|oci_fetch_object|oci_fetch_row|oci_field_is_null|oci_field_name|oci_field_precision|oci_field_scale|oci_field_size|oci_field_type|oci_field_type_raw|oci_free_statement|oci_internal_debug|oci_lob_append|oci_lob_close|oci_lob_copy|oci_lob_eof|oci_lob_erase|oci_lob_export|oci_lob_flush|oci_lob_free|oci_lob_getbuffering|oci_lob_import|oci_lob_is_equal|oci_lob_load|oci_lob_read|oci_lob_rewind|oci_lob_save|oci_lob_savefile|oci_lob_seek|oci_lob_setbuffering|oci_lob_size|oci_lob_tell|oci_lob_truncate|oci_lob_write|oci_lob_writetemporary|oci_lob_writetofile|oci_new_collection|oci_new_connect|oci_new_cursor|oci_new_descriptor|oci_num_fields|oci_num_rows|oci_parse|oci_password_change|oci_pconnect|oci_result|oci_rollback|oci_server_version|oci_set_action|oci_set_client_identifier|oci_set_client_info|oci_set_edition|oci_set_module_name|oci_set_prefetch|oci_statement_type|ocibindbyname|ocicancel|ocicloselob|ocicollappend|ocicollassign|ocicollassignelem|ocicollgetelem|ocicollmax|ocicollsize|ocicolltrim|ocicolumnisnull|ocicolumnname|ocicolumnprecision|ocicolumnscale|ocicolumnsize|ocicolumntype|ocicolumntyperaw|ocicommit|ocidefinebyname|ocierror|ociexecute|ocifetch|ocifetchinto|ocifetchstatement|ocifreecollection|ocifreecursor|ocifreedesc|ocifreestatement|ociinternaldebug|ociloadlob|ocilogoff|ocilogon|ocinewcollection|ocinewcursor|ocinewdescriptor|ocinlogon|ocinumcols|ociparse|ociplogon|ociresult|ocirollback|ocirowcount|ocisavelob|ocisavelobfile|ociserverversion|ocisetprefetch|ocistatementtype|ociwritelobtofile|ociwritetemporarylob|octdec|odbc_autocommit|odbc_binmode|odbc_close|odbc_close_all|odbc_columnprivileges|odbc_columns|odbc_commit|odbc_connect|odbc_cursor|odbc_data_source|odbc_do|odbc_error|odbc_errormsg|odbc_exec|odbc_execute|odbc_fetch_array|odbc_fetch_into|odbc_fetch_object|odbc_fetch_row|odbc_field_len|odbc_field_name|odbc_field_num|odbc_field_precision|odbc_field_scale|odbc_field_type|odbc_foreignkeys|odbc_free_result|odbc_gettypeinfo|odbc_longreadlen|odbc_next_result|odbc_num_fields|odbc_num_rows|odbc_pconnect|odbc_prepare|odbc_primarykeys|odbc_procedurecolumns|odbc_procedures|odbc_result|odbc_result_all|odbc_rollback|odbc_setoption|odbc_specialcolumns|odbc_statistics|odbc_tableprivileges|odbc_tables|openal_buffer_create|openal_buffer_data|openal_buffer_destroy|openal_buffer_get|openal_buffer_loadwav|openal_context_create|openal_context_current|openal_context_destroy|openal_context_process|openal_context_suspend|openal_device_close|openal_device_open|openal_listener_get|openal_listener_set|openal_source_create|openal_source_destroy|openal_source_get|openal_source_pause|openal_source_play|openal_source_rewind|openal_source_set|openal_source_stop|openal_stream|opendir|openlog|openssl_cipher_iv_length|openssl_csr_export|openssl_csr_export_to_file|openssl_csr_get_public_key|openssl_csr_get_subject|openssl_csr_new|openssl_csr_sign|openssl_decrypt|openssl_dh_compute_key|openssl_digest|openssl_encrypt|openssl_error_string|openssl_free_key|openssl_get_cipher_methods|openssl_get_md_methods|openssl_get_privatekey|openssl_get_publickey|openssl_open|openssl_pkcs12_export|openssl_pkcs12_export_to_file|openssl_pkcs12_read|openssl_pkcs7_decrypt|openssl_pkcs7_encrypt|openssl_pkcs7_sign|openssl_pkcs7_verify|openssl_pkey_export|openssl_pkey_export_to_file|openssl_pkey_free|openssl_pkey_get_details|openssl_pkey_get_private|openssl_pkey_get_public|openssl_pkey_new|openssl_private_decrypt|openssl_private_encrypt|openssl_public_decrypt|openssl_public_encrypt|openssl_random_pseudo_bytes|openssl_seal|openssl_sign|openssl_verify|openssl_x509_check_private_key|openssl_x509_checkpurpose|openssl_x509_export|openssl_x509_export_to_file|openssl_x509_free|openssl_x509_parse|openssl_x509_read|ord|outeriterator|outofboundsexception|outofrangeexception|output_add_rewrite_var|output_reset_rewrite_vars|overflowexception|overload|override_function|ovrimos_close|ovrimos_commit|ovrimos_connect|ovrimos_cursor|ovrimos_exec|ovrimos_execute|ovrimos_fetch_into|ovrimos_fetch_row|ovrimos_field_len|ovrimos_field_name|ovrimos_field_num|ovrimos_field_type|ovrimos_free_result|ovrimos_longreadlen|ovrimos_num_fields|ovrimos_num_rows|ovrimos_prepare|ovrimos_result|ovrimos_result_all|ovrimos_rollback|pack|parentiterator|parse_ini_file|parse_ini_string|parse_str|parse_url|parsekit_compile_file|parsekit_compile_string|parsekit_func_arginfo|passthru|pathinfo|pclose|pcntl_alarm|pcntl_exec|pcntl_fork|pcntl_getpriority|pcntl_setpriority|pcntl_signal|pcntl_signal_dispatch|pcntl_sigprocmask|pcntl_sigtimedwait|pcntl_sigwaitinfo|pcntl_wait|pcntl_waitpid|pcntl_wexitstatus|pcntl_wifexited|pcntl_wifsignaled|pcntl_wifstopped|pcntl_wstopsig|pcntl_wtermsig|pdf_activate_item|pdf_add_annotation|pdf_add_bookmark|pdf_add_launchlink|pdf_add_locallink|pdf_add_nameddest|pdf_add_note|pdf_add_outline|pdf_add_pdflink|pdf_add_table_cell|pdf_add_textflow|pdf_add_thumbnail|pdf_add_weblink|pdf_arc|pdf_arcn|pdf_attach_file|pdf_begin_document|pdf_begin_font|pdf_begin_glyph|pdf_begin_item|pdf_begin_layer|pdf_begin_page|pdf_begin_page_ext|pdf_begin_pattern|pdf_begin_template|pdf_begin_template_ext|pdf_circle|pdf_clip|pdf_close|pdf_close_image|pdf_close_pdi|pdf_close_pdi_page|pdf_closepath|pdf_closepath_fill_stroke|pdf_closepath_stroke|pdf_concat|pdf_continue_text|pdf_create_3dview|pdf_create_action|pdf_create_annotation|pdf_create_bookmark|pdf_create_field|pdf_create_fieldgroup|pdf_create_gstate|pdf_create_pvf|pdf_create_textflow|pdf_curveto|pdf_define_layer|pdf_delete|pdf_delete_pvf|pdf_delete_table|pdf_delete_textflow|pdf_encoding_set_char|pdf_end_document|pdf_end_font|pdf_end_glyph|pdf_end_item|pdf_end_layer|pdf_end_page|pdf_end_page_ext|pdf_end_pattern|pdf_end_template|pdf_endpath|pdf_fill|pdf_fill_imageblock|pdf_fill_pdfblock|pdf_fill_stroke|pdf_fill_textblock|pdf_findfont|pdf_fit_image|pdf_fit_pdi_page|pdf_fit_table|pdf_fit_textflow|pdf_fit_textline|pdf_get_apiname|pdf_get_buffer|pdf_get_errmsg|pdf_get_errnum|pdf_get_font|pdf_get_fontname|pdf_get_fontsize|pdf_get_image_height|pdf_get_image_width|pdf_get_majorversion|pdf_get_minorversion|pdf_get_parameter|pdf_get_pdi_parameter|pdf_get_pdi_value|pdf_get_value|pdf_info_font|pdf_info_matchbox|pdf_info_table|pdf_info_textflow|pdf_info_textline|pdf_initgraphics|pdf_lineto|pdf_load_3ddata|pdf_load_font|pdf_load_iccprofile|pdf_load_image|pdf_makespotcolor|pdf_moveto|pdf_new|pdf_open_ccitt|pdf_open_file|pdf_open_gif|pdf_open_image|pdf_open_image_file|pdf_open_jpeg|pdf_open_memory_image|pdf_open_pdi|pdf_open_pdi_document|pdf_open_pdi_page|pdf_open_tiff|pdf_pcos_get_number|pdf_pcos_get_stream|pdf_pcos_get_string|pdf_place_image|pdf_place_pdi_page|pdf_process_pdi|pdf_rect|pdf_restore|pdf_resume_page|pdf_rotate|pdf_save|pdf_scale|pdf_set_border_color|pdf_set_border_dash|pdf_set_border_style|pdf_set_char_spacing|pdf_set_duration|pdf_set_gstate|pdf_set_horiz_scaling|pdf_set_info|pdf_set_info_author|pdf_set_info_creator|pdf_set_info_keywords|pdf_set_info_subject|pdf_set_info_title|pdf_set_layer_dependency|pdf_set_leading|pdf_set_parameter|pdf_set_text_matrix|pdf_set_text_pos|pdf_set_text_rendering|pdf_set_text_rise|pdf_set_value|pdf_set_word_spacing|pdf_setcolor|pdf_setdash|pdf_setdashpattern|pdf_setflat|pdf_setfont|pdf_setgray|pdf_setgray_fill|pdf_setgray_stroke|pdf_setlinecap|pdf_setlinejoin|pdf_setlinewidth|pdf_setmatrix|pdf_setmiterlimit|pdf_setpolydash|pdf_setrgbcolor|pdf_setrgbcolor_fill|pdf_setrgbcolor_stroke|pdf_shading|pdf_shading_pattern|pdf_shfill|pdf_show|pdf_show_boxed|pdf_show_xy|pdf_skew|pdf_stringwidth|pdf_stroke|pdf_suspend_page|pdf_translate|pdf_utf16_to_utf8|pdf_utf32_to_utf16|pdf_utf8_to_utf16|pdo|pdo_cubrid_schema|pdo_pgsqllobcreate|pdo_pgsqllobopen|pdo_pgsqllobunlink|pdo_sqlitecreateaggregate|pdo_sqlitecreatefunction|pdoexception|pdostatement|pfsockopen|pg_affected_rows|pg_cancel_query|pg_client_encoding|pg_close|pg_connect|pg_connection_busy|pg_connection_reset|pg_connection_status|pg_convert|pg_copy_from|pg_copy_to|pg_dbname|pg_delete|pg_end_copy|pg_escape_bytea|pg_escape_string|pg_execute|pg_fetch_all|pg_fetch_all_columns|pg_fetch_array|pg_fetch_assoc|pg_fetch_object|pg_fetch_result|pg_fetch_row|pg_field_is_null|pg_field_name|pg_field_num|pg_field_prtlen|pg_field_size|pg_field_table|pg_field_type|pg_field_type_oid|pg_free_result|pg_get_notify|pg_get_pid|pg_get_result|pg_host|pg_insert|pg_last_error|pg_last_notice|pg_last_oid|pg_lo_close|pg_lo_create|pg_lo_export|pg_lo_import|pg_lo_open|pg_lo_read|pg_lo_read_all|pg_lo_seek|pg_lo_tell|pg_lo_unlink|pg_lo_write|pg_meta_data|pg_num_fields|pg_num_rows|pg_options|pg_parameter_status|pg_pconnect|pg_ping|pg_port|pg_prepare|pg_put_line|pg_query|pg_query_params|pg_result_error|pg_result_error_field|pg_result_seek|pg_result_status|pg_select|pg_send_execute|pg_send_prepare|pg_send_query|pg_send_query_params|pg_set_client_encoding|pg_set_error_verbosity|pg_trace|pg_transaction_status|pg_tty|pg_unescape_bytea|pg_untrace|pg_update|pg_version|php_check_syntax|php_ini_loaded_file|php_ini_scanned_files|php_logo_guid|php_sapi_name|php_strip_whitespace|php_uname|phpcredits|phpinfo|phpversion|pi|png2wbmp|popen|pos|posix_access|posix_ctermid|posix_errno|posix_get_last_error|posix_getcwd|posix_getegid|posix_geteuid|posix_getgid|posix_getgrgid|posix_getgrnam|posix_getgroups|posix_getlogin|posix_getpgid|posix_getpgrp|posix_getpid|posix_getppid|posix_getpwnam|posix_getpwuid|posix_getrlimit|posix_getsid|posix_getuid|posix_initgroups|posix_isatty|posix_kill|posix_mkfifo|posix_mknod|posix_setegid|posix_seteuid|posix_setgid|posix_setpgid|posix_setsid|posix_setuid|posix_strerror|posix_times|posix_ttyname|posix_uname|pow|preg_filter|preg_grep|preg_last_error|preg_match|preg_match_all|preg_quote|preg_replace|preg_replace_callback|preg_split|prev|print|print_r|printer_abort|printer_close|printer_create_brush|printer_create_dc|printer_create_font|printer_create_pen|printer_delete_brush|printer_delete_dc|printer_delete_font|printer_delete_pen|printer_draw_bmp|printer_draw_chord|printer_draw_elipse|printer_draw_line|printer_draw_pie|printer_draw_rectangle|printer_draw_roundrect|printer_draw_text|printer_end_doc|printer_end_page|printer_get_option|printer_list|printer_logical_fontheight|printer_open|printer_select_brush|printer_select_font|printer_select_pen|printer_set_option|printer_start_doc|printer_start_page|printer_write|printf|proc_close|proc_get_status|proc_nice|proc_open|proc_terminate|property_exists|ps_add_bookmark|ps_add_launchlink|ps_add_locallink|ps_add_note|ps_add_pdflink|ps_add_weblink|ps_arc|ps_arcn|ps_begin_page|ps_begin_pattern|ps_begin_template|ps_circle|ps_clip|ps_close|ps_close_image|ps_closepath|ps_closepath_stroke|ps_continue_text|ps_curveto|ps_delete|ps_end_page|ps_end_pattern|ps_end_template|ps_fill|ps_fill_stroke|ps_findfont|ps_get_buffer|ps_get_parameter|ps_get_value|ps_hyphenate|ps_include_file|ps_lineto|ps_makespotcolor|ps_moveto|ps_new|ps_open_file|ps_open_image|ps_open_image_file|ps_open_memory_image|ps_place_image|ps_rect|ps_restore|ps_rotate|ps_save|ps_scale|ps_set_border_color|ps_set_border_dash|ps_set_border_style|ps_set_info|ps_set_parameter|ps_set_text_pos|ps_set_value|ps_setcolor|ps_setdash|ps_setflat|ps_setfont|ps_setgray|ps_setlinecap|ps_setlinejoin|ps_setlinewidth|ps_setmiterlimit|ps_setoverprintmode|ps_setpolydash|ps_shading|ps_shading_pattern|ps_shfill|ps_show|ps_show2|ps_show_boxed|ps_show_xy|ps_show_xy2|ps_string_geometry|ps_stringwidth|ps_stroke|ps_symbol|ps_symbol_name|ps_symbol_width|ps_translate|pspell_add_to_personal|pspell_add_to_session|pspell_check|pspell_clear_session|pspell_config_create|pspell_config_data_dir|pspell_config_dict_dir|pspell_config_ignore|pspell_config_mode|pspell_config_personal|pspell_config_repl|pspell_config_runtogether|pspell_config_save_repl|pspell_new|pspell_new_config|pspell_new_personal|pspell_save_wordlist|pspell_store_replacement|pspell_suggest|putenv|px_close|px_create_fp|px_date2string|px_delete|px_delete_record|px_get_field|px_get_info|px_get_parameter|px_get_record|px_get_schema|px_get_value|px_insert_record|px_new|px_numfields|px_numrecords|px_open_fp|px_put_record|px_retrieve_record|px_set_blob_file|px_set_parameter|px_set_tablename|px_set_targetencoding|px_set_value|px_timestamp2string|px_update_record|qdom_error|qdom_tree|quoted_printable_decode|quoted_printable_encode|quotemeta|rad2deg|radius_acct_open|radius_add_server|radius_auth_open|radius_close|radius_config|radius_create_request|radius_cvt_addr|radius_cvt_int|radius_cvt_string|radius_demangle|radius_demangle_mppe_key|radius_get_attr|radius_get_vendor_attr|radius_put_addr|radius_put_attr|radius_put_int|radius_put_string|radius_put_vendor_addr|radius_put_vendor_attr|radius_put_vendor_int|radius_put_vendor_string|radius_request_authenticator|radius_send_request|radius_server_secret|radius_strerror|rand|range|rangeexception|rar_wrapper_cache_stats|rararchive|rarentry|rarexception|rawurldecode|rawurlencode|read_exif_data|readdir|readfile|readgzfile|readline|readline_add_history|readline_callback_handler_install|readline_callback_handler_remove|readline_callback_read_char|readline_clear_history|readline_completion_function|readline_info|readline_list_history|readline_on_new_line|readline_read_history|readline_redisplay|readline_write_history|readlink|realpath|realpath_cache_get|realpath_cache_size|recode|recode_file|recode_string|recursivearrayiterator|recursivecachingiterator|recursivecallbackfilteriterator|recursivedirectoryiterator|recursivefilteriterator|recursiveiterator|recursiveiteratoriterator|recursiveregexiterator|recursivetreeiterator|reflection|reflectionclass|reflectionexception|reflectionextension|reflectionfunction|reflectionfunctionabstract|reflectionmethod|reflectionobject|reflectionparameter|reflectionproperty|reflector|regexiterator|register_shutdown_function|register_tick_function|rename|rename_function|require|require_once|reset|resetValue|resourcebundle|restore_error_handler|restore_exception_handler|restore_include_path|return|rewind|rewinddir|rmdir|round|rpm_close|rpm_get_tag|rpm_is_valid|rpm_open|rpm_version|rrd_create|rrd_error|rrd_fetch|rrd_first|rrd_graph|rrd_info|rrd_last|rrd_lastupdate|rrd_restore|rrd_tune|rrd_update|rrd_xport|rrdcreator|rrdgraph|rrdupdater|rsort|rtrim|runkit_class_adopt|runkit_class_emancipate|runkit_constant_add|runkit_constant_redefine|runkit_constant_remove|runkit_function_add|runkit_function_copy|runkit_function_redefine|runkit_function_remove|runkit_function_rename|runkit_import|runkit_lint|runkit_lint_file|runkit_method_add|runkit_method_copy|runkit_method_redefine|runkit_method_remove|runkit_method_rename|runkit_return_value_used|runkit_sandbox_output_handler|runkit_superglobals|runtimeexception|samconnection_commit|samconnection_connect|samconnection_constructor|samconnection_disconnect|samconnection_errno|samconnection_error|samconnection_isconnected|samconnection_peek|samconnection_peekall|samconnection_receive|samconnection_remove|samconnection_rollback|samconnection_send|samconnection_setDebug|samconnection_subscribe|samconnection_unsubscribe|sammessage_body|sammessage_constructor|sammessage_header|sca_createdataobject|sca_getservice|sca_localproxy_createdataobject|sca_soapproxy_createdataobject|scandir|sdo_das_changesummary_beginlogging|sdo_das_changesummary_endlogging|sdo_das_changesummary_getchangeddataobjects|sdo_das_changesummary_getchangetype|sdo_das_changesummary_getoldcontainer|sdo_das_changesummary_getoldvalues|sdo_das_changesummary_islogging|sdo_das_datafactory_addpropertytotype|sdo_das_datafactory_addtype|sdo_das_datafactory_getdatafactory|sdo_das_dataobject_getchangesummary|sdo_das_relational_applychanges|sdo_das_relational_construct|sdo_das_relational_createrootdataobject|sdo_das_relational_executepreparedquery|sdo_das_relational_executequery|sdo_das_setting_getlistindex|sdo_das_setting_getpropertyindex|sdo_das_setting_getpropertyname|sdo_das_setting_getvalue|sdo_das_setting_isset|sdo_das_xml_addtypes|sdo_das_xml_create|sdo_das_xml_createdataobject|sdo_das_xml_createdocument|sdo_das_xml_document_getrootdataobject|sdo_das_xml_document_getrootelementname|sdo_das_xml_document_getrootelementuri|sdo_das_xml_document_setencoding|sdo_das_xml_document_setxmldeclaration|sdo_das_xml_document_setxmlversion|sdo_das_xml_loadfile|sdo_das_xml_loadstring|sdo_das_xml_savefile|sdo_das_xml_savestring|sdo_datafactory_create|sdo_dataobject_clear|sdo_dataobject_createdataobject|sdo_dataobject_getcontainer|sdo_dataobject_getsequence|sdo_dataobject_gettypename|sdo_dataobject_gettypenamespaceuri|sdo_exception_getcause|sdo_list_insert|sdo_model_property_getcontainingtype|sdo_model_property_getdefault|sdo_model_property_getname|sdo_model_property_gettype|sdo_model_property_iscontainment|sdo_model_property_ismany|sdo_model_reflectiondataobject_construct|sdo_model_reflectiondataobject_export|sdo_model_reflectiondataobject_getcontainmentproperty|sdo_model_reflectiondataobject_getinstanceproperties|sdo_model_reflectiondataobject_gettype|sdo_model_type_getbasetype|sdo_model_type_getname|sdo_model_type_getnamespaceuri|sdo_model_type_getproperties|sdo_model_type_getproperty|sdo_model_type_isabstracttype|sdo_model_type_isdatatype|sdo_model_type_isinstance|sdo_model_type_isopentype|sdo_model_type_issequencedtype|sdo_sequence_getproperty|sdo_sequence_insert|sdo_sequence_move|seekableiterator|sem_acquire|sem_get|sem_release|sem_remove|serializable|serialize|session_cache_expire|session_cache_limiter|session_commit|session_decode|session_destroy|session_encode|session_get_cookie_params|session_id|session_is_registered|session_module_name|session_name|session_pgsql_add_error|session_pgsql_get_error|session_pgsql_get_field|session_pgsql_reset|session_pgsql_set_field|session_pgsql_status|session_regenerate_id|session_register|session_save_path|session_set_cookie_params|session_set_save_handler|session_start|session_unregister|session_unset|session_write_close|setCounterClass|set_error_handler|set_exception_handler|set_file_buffer|set_include_path|set_magic_quotes_runtime|set_socket_blocking|set_time_limit|setcookie|setlocale|setproctitle|setrawcookie|setstaticpropertyvalue|setthreadtitle|settype|sha1|sha1_file|shell_exec|shm_attach|shm_detach|shm_get_var|shm_has_var|shm_put_var|shm_remove|shm_remove_var|shmop_close|shmop_delete|shmop_open|shmop_read|shmop_size|shmop_write|show_source|shuffle|signeurlpaiement|similar_text|simplexml_import_dom|simplexml_load_file|simplexml_load_string|simplexmlelement|simplexmliterator|sin|sinh|sizeof|sleep|snmp|snmp2_get|snmp2_getnext|snmp2_real_walk|snmp2_set|snmp2_walk|snmp3_get|snmp3_getnext|snmp3_real_walk|snmp3_set|snmp3_walk|snmp_get_quick_print|snmp_get_valueretrieval|snmp_read_mib|snmp_set_enum_print|snmp_set_oid_numeric_print|snmp_set_oid_output_format|snmp_set_quick_print|snmp_set_valueretrieval|snmpget|snmpgetnext|snmprealwalk|snmpset|snmpwalk|snmpwalkoid|soapclient|soapfault|soapheader|soapparam|soapserver|soapvar|socket_accept|socket_bind|socket_clear_error|socket_close|socket_connect|socket_create|socket_create_listen|socket_create_pair|socket_get_option|socket_get_status|socket_getpeername|socket_getsockname|socket_last_error|socket_listen|socket_read|socket_recv|socket_recvfrom|socket_select|socket_send|socket_sendto|socket_set_block|socket_set_blocking|socket_set_nonblock|socket_set_option|socket_set_timeout|socket_shutdown|socket_strerror|socket_write|solr_get_version|solrclient|solrclientexception|solrdocument|solrdocumentfield|solrexception|solrgenericresponse|solrillegalargumentexception|solrillegaloperationexception|solrinputdocument|solrmodifiableparams|solrobject|solrparams|solrpingresponse|solrquery|solrqueryresponse|solrresponse|solrupdateresponse|solrutils|sort|soundex|sphinxclient|spl_autoload|spl_autoload_call|spl_autoload_extensions|spl_autoload_functions|spl_autoload_register|spl_autoload_unregister|spl_classes|spl_object_hash|splbool|spldoublylinkedlist|splenum|splfileinfo|splfileobject|splfixedarray|splfloat|splheap|splint|split|spliti|splmaxheap|splminheap|splobjectstorage|splobserver|splpriorityqueue|splqueue|splstack|splstring|splsubject|spltempfileobject|spoofchecker|sprintf|sql_regcase|sqlite3|sqlite3result|sqlite3stmt|sqlite_array_query|sqlite_busy_timeout|sqlite_changes|sqlite_close|sqlite_column|sqlite_create_aggregate|sqlite_create_function|sqlite_current|sqlite_error_string|sqlite_escape_string|sqlite_exec|sqlite_factory|sqlite_fetch_all|sqlite_fetch_array|sqlite_fetch_column_types|sqlite_fetch_object|sqlite_fetch_single|sqlite_fetch_string|sqlite_field_name|sqlite_has_more|sqlite_has_prev|sqlite_key|sqlite_last_error|sqlite_last_insert_rowid|sqlite_libencoding|sqlite_libversion|sqlite_next|sqlite_num_fields|sqlite_num_rows|sqlite_open|sqlite_popen|sqlite_prev|sqlite_query|sqlite_rewind|sqlite_seek|sqlite_single_query|sqlite_udf_decode_binary|sqlite_udf_encode_binary|sqlite_unbuffered_query|sqlite_valid|sqrt|srand|sscanf|ssdeep_fuzzy_compare|ssdeep_fuzzy_hash|ssdeep_fuzzy_hash_filename|ssh2_auth_hostbased_file|ssh2_auth_none|ssh2_auth_password|ssh2_auth_pubkey_file|ssh2_connect|ssh2_exec|ssh2_fetch_stream|ssh2_fingerprint|ssh2_methods_negotiated|ssh2_publickey_add|ssh2_publickey_init|ssh2_publickey_list|ssh2_publickey_remove|ssh2_scp_recv|ssh2_scp_send|ssh2_sftp|ssh2_sftp_lstat|ssh2_sftp_mkdir|ssh2_sftp_readlink|ssh2_sftp_realpath|ssh2_sftp_rename|ssh2_sftp_rmdir|ssh2_sftp_stat|ssh2_sftp_symlink|ssh2_sftp_unlink|ssh2_shell|ssh2_tunnel|stat|stats_absolute_deviation|stats_cdf_beta|stats_cdf_binomial|stats_cdf_cauchy|stats_cdf_chisquare|stats_cdf_exponential|stats_cdf_f|stats_cdf_gamma|stats_cdf_laplace|stats_cdf_logistic|stats_cdf_negative_binomial|stats_cdf_noncentral_chisquare|stats_cdf_noncentral_f|stats_cdf_poisson|stats_cdf_t|stats_cdf_uniform|stats_cdf_weibull|stats_covariance|stats_den_uniform|stats_dens_beta|stats_dens_cauchy|stats_dens_chisquare|stats_dens_exponential|stats_dens_f|stats_dens_gamma|stats_dens_laplace|stats_dens_logistic|stats_dens_negative_binomial|stats_dens_normal|stats_dens_pmf_binomial|stats_dens_pmf_hypergeometric|stats_dens_pmf_poisson|stats_dens_t|stats_dens_weibull|stats_harmonic_mean|stats_kurtosis|stats_rand_gen_beta|stats_rand_gen_chisquare|stats_rand_gen_exponential|stats_rand_gen_f|stats_rand_gen_funiform|stats_rand_gen_gamma|stats_rand_gen_ibinomial|stats_rand_gen_ibinomial_negative|stats_rand_gen_int|stats_rand_gen_ipoisson|stats_rand_gen_iuniform|stats_rand_gen_noncenral_chisquare|stats_rand_gen_noncentral_f|stats_rand_gen_noncentral_t|stats_rand_gen_normal|stats_rand_gen_t|stats_rand_get_seeds|stats_rand_phrase_to_seeds|stats_rand_ranf|stats_rand_setall|stats_skew|stats_standard_deviation|stats_stat_binomial_coef|stats_stat_correlation|stats_stat_gennch|stats_stat_independent_t|stats_stat_innerproduct|stats_stat_noncentral_t|stats_stat_paired_t|stats_stat_percentile|stats_stat_powersum|stats_variance|stomp|stomp_connect_error|stomp_version|stompexception|stompframe|str_getcsv|str_ireplace|str_pad|str_repeat|str_replace|str_rot13|str_shuffle|str_split|str_word_count|strcasecmp|strchr|strcmp|strcoll|strcspn|stream_bucket_append|stream_bucket_make_writeable|stream_bucket_new|stream_bucket_prepend|stream_context_create|stream_context_get_default|stream_context_get_options|stream_context_get_params|stream_context_set_default|stream_context_set_option|stream_context_set_params|stream_copy_to_stream|stream_encoding|stream_filter_append|stream_filter_prepend|stream_filter_register|stream_filter_remove|stream_get_contents|stream_get_filters|stream_get_line|stream_get_meta_data|stream_get_transports|stream_get_wrappers|stream_is_local|stream_notification_callback|stream_register_wrapper|stream_resolve_include_path|stream_select|stream_set_blocking|stream_set_read_buffer|stream_set_timeout|stream_set_write_buffer|stream_socket_accept|stream_socket_client|stream_socket_enable_crypto|stream_socket_get_name|stream_socket_pair|stream_socket_recvfrom|stream_socket_sendto|stream_socket_server|stream_socket_shutdown|stream_supports_lock|stream_wrapper_register|stream_wrapper_restore|stream_wrapper_unregister|streamwrapper|strftime|strip_tags|stripcslashes|stripos|stripslashes|stristr|strlen|strnatcasecmp|strnatcmp|strncasecmp|strncmp|strpbrk|strpos|strptime|strrchr|strrev|strripos|strrpos|strspn|strstr|strtok|strtolower|strtotime|strtoupper|strtr|strval|substr|substr_compare|substr_count|substr_replace|svm|svmmodel|svn_add|svn_auth_get_parameter|svn_auth_set_parameter|svn_blame|svn_cat|svn_checkout|svn_cleanup|svn_client_version|svn_commit|svn_delete|svn_diff|svn_export|svn_fs_abort_txn|svn_fs_apply_text|svn_fs_begin_txn2|svn_fs_change_node_prop|svn_fs_check_path|svn_fs_contents_changed|svn_fs_copy|svn_fs_delete|svn_fs_dir_entries|svn_fs_file_contents|svn_fs_file_length|svn_fs_is_dir|svn_fs_is_file|svn_fs_make_dir|svn_fs_make_file|svn_fs_node_created_rev|svn_fs_node_prop|svn_fs_props_changed|svn_fs_revision_prop|svn_fs_revision_root|svn_fs_txn_root|svn_fs_youngest_rev|svn_import|svn_log|svn_ls|svn_mkdir|svn_repos_create|svn_repos_fs|svn_repos_fs_begin_txn_for_commit|svn_repos_fs_commit_txn|svn_repos_hotcopy|svn_repos_open|svn_repos_recover|svn_revert|svn_status|svn_update|swf_actiongeturl|swf_actiongotoframe|swf_actiongotolabel|swf_actionnextframe|swf_actionplay|swf_actionprevframe|swf_actionsettarget|swf_actionstop|swf_actiontogglequality|swf_actionwaitforframe|swf_addbuttonrecord|swf_addcolor|swf_closefile|swf_definebitmap|swf_definefont|swf_defineline|swf_definepoly|swf_definerect|swf_definetext|swf_endbutton|swf_enddoaction|swf_endshape|swf_endsymbol|swf_fontsize|swf_fontslant|swf_fonttracking|swf_getbitmapinfo|swf_getfontinfo|swf_getframe|swf_labelframe|swf_lookat|swf_modifyobject|swf_mulcolor|swf_nextid|swf_oncondition|swf_openfile|swf_ortho|swf_ortho2|swf_perspective|swf_placeobject|swf_polarview|swf_popmatrix|swf_posround|swf_pushmatrix|swf_removeobject|swf_rotate|swf_scale|swf_setfont|swf_setframe|swf_shapearc|swf_shapecurveto|swf_shapecurveto3|swf_shapefillbitmapclip|swf_shapefillbitmaptile|swf_shapefilloff|swf_shapefillsolid|swf_shapelinesolid|swf_shapelineto|swf_shapemoveto|swf_showframe|swf_startbutton|swf_startdoaction|swf_startshape|swf_startsymbol|swf_textwidth|swf_translate|swf_viewport|swfaction|swfbitmap|swfbutton|swfdisplayitem|swffill|swffont|swffontchar|swfgradient|swfmorph|swfmovie|swfprebuiltclip|swfshape|swfsound|swfsoundinstance|swfsprite|swftext|swftextfield|swfvideostream|swish_construct|swish_getmetalist|swish_getpropertylist|swish_prepare|swish_query|swishresult_getmetalist|swishresult_stem|swishresults_getparsedwords|swishresults_getremovedstopwords|swishresults_nextresult|swishresults_seekresult|swishsearch_execute|swishsearch_resetlimit|swishsearch_setlimit|swishsearch_setphrasedelimiter|swishsearch_setsort|swishsearch_setstructure|sybase_affected_rows|sybase_close|sybase_connect|sybase_data_seek|sybase_deadlock_retry_count|sybase_fetch_array|sybase_fetch_assoc|sybase_fetch_field|sybase_fetch_object|sybase_fetch_row|sybase_field_seek|sybase_free_result|sybase_get_last_message|sybase_min_client_severity|sybase_min_error_severity|sybase_min_message_severity|sybase_min_server_severity|sybase_num_fields|sybase_num_rows|sybase_pconnect|sybase_query|sybase_result|sybase_select_db|sybase_set_message_handler|sybase_unbuffered_query|symlink|sys_get_temp_dir|sys_getloadavg|syslog|system|tag|tan|tanh|tcpwrap_check|tempnam|textdomain|tidy|tidy_access_count|tidy_config_count|tidy_diagnose|tidy_error_count|tidy_get_error_buffer|tidy_get_output|tidy_load_config|tidy_reset_config|tidy_save_config|tidy_set_encoding|tidy_setopt|tidy_warning_count|tidynode|time|time_nanosleep|time_sleep_until|timezone_abbreviations_list|timezone_identifiers_list|timezone_location_get|timezone_name_from_abbr|timezone_name_get|timezone_offset_get|timezone_open|timezone_transitions_get|timezone_version_get|tmpfile|token_get_all|token_name|tokyotyrant|tokyotyrantquery|tokyotyranttable|tostring|tostring|touch|transliterator|traversable|trigger_error|trim|uasort|ucfirst|ucwords|udm_add_search_limit|udm_alloc_agent|udm_alloc_agent_array|udm_api_version|udm_cat_list|udm_cat_path|udm_check_charset|udm_check_stored|udm_clear_search_limits|udm_close_stored|udm_crc32|udm_errno|udm_error|udm_find|udm_free_agent|udm_free_ispell_data|udm_free_res|udm_get_doc_count|udm_get_res_field|udm_get_res_param|udm_hash32|udm_load_ispell_data|udm_open_stored|udm_set_agent_param|uksort|umask|underflowexception|unexpectedvalueexception|uniqid|unixtojd|unlink|unpack|unregister_tick_function|unserialize|unset|urldecode|urlencode|use_soap_error_handler|user_error|usleep|usort|utf8_decode|utf8_encode|v8js|v8jsexception|var_dump|var_export|variant|variant_abs|variant_add|variant_and|variant_cast|variant_cat|variant_cmp|variant_date_from_timestamp|variant_date_to_timestamp|variant_div|variant_eqv|variant_fix|variant_get_type|variant_idiv|variant_imp|variant_int|variant_mod|variant_mul|variant_neg|variant_not|variant_or|variant_pow|variant_round|variant_set|variant_set_type|variant_sub|variant_xor|version_compare|vfprintf|virtual|vpopmail_add_alias_domain|vpopmail_add_alias_domain_ex|vpopmail_add_domain|vpopmail_add_domain_ex|vpopmail_add_user|vpopmail_alias_add|vpopmail_alias_del|vpopmail_alias_del_domain|vpopmail_alias_get|vpopmail_alias_get_all|vpopmail_auth_user|vpopmail_del_domain|vpopmail_del_domain_ex|vpopmail_del_user|vpopmail_error|vpopmail_passwd|vpopmail_set_user_quota|vprintf|vsprintf|w32api_deftype|w32api_init_dtype|w32api_invoke_function|w32api_register_function|w32api_set_call_method|wddx_add_vars|wddx_deserialize|wddx_packet_end|wddx_packet_start|wddx_serialize_value|wddx_serialize_vars|win32_continue_service|win32_create_service|win32_delete_service|win32_get_last_control_message|win32_pause_service|win32_ps_list_procs|win32_ps_stat_mem|win32_ps_stat_proc|win32_query_service_status|win32_set_service_status|win32_start_service|win32_start_service_ctrl_dispatcher|win32_stop_service|wincache_fcache_fileinfo|wincache_fcache_meminfo|wincache_lock|wincache_ocache_fileinfo|wincache_ocache_meminfo|wincache_refresh_if_changed|wincache_rplist_fileinfo|wincache_rplist_meminfo|wincache_scache_info|wincache_scache_meminfo|wincache_ucache_add|wincache_ucache_cas|wincache_ucache_clear|wincache_ucache_dec|wincache_ucache_delete|wincache_ucache_exists|wincache_ucache_get|wincache_ucache_inc|wincache_ucache_info|wincache_ucache_meminfo|wincache_ucache_set|wincache_unlock|wordwrap|xattr_get|xattr_list|xattr_remove|xattr_set|xattr_supported|xdiff_file_bdiff|xdiff_file_bdiff_size|xdiff_file_bpatch|xdiff_file_diff|xdiff_file_diff_binary|xdiff_file_merge3|xdiff_file_patch|xdiff_file_patch_binary|xdiff_file_rabdiff|xdiff_string_bdiff|xdiff_string_bdiff_size|xdiff_string_bpatch|xdiff_string_diff|xdiff_string_diff_binary|xdiff_string_merge3|xdiff_string_patch|xdiff_string_patch_binary|xdiff_string_rabdiff|xhprof_disable|xhprof_enable|xhprof_sample_disable|xhprof_sample_enable|xml_error_string|xml_get_current_byte_index|xml_get_current_column_number|xml_get_current_line_number|xml_get_error_code|xml_parse|xml_parse_into_struct|xml_parser_create|xml_parser_create_ns|xml_parser_free|xml_parser_get_option|xml_parser_set_option|xml_set_character_data_handler|xml_set_default_handler|xml_set_element_handler|xml_set_end_namespace_decl_handler|xml_set_external_entity_ref_handler|xml_set_notation_decl_handler|xml_set_object|xml_set_processing_instruction_handler|xml_set_start_namespace_decl_handler|xml_set_unparsed_entity_decl_handler|xmlreader|xmlrpc_decode|xmlrpc_decode_request|xmlrpc_encode|xmlrpc_encode_request|xmlrpc_get_type|xmlrpc_is_fault|xmlrpc_parse_method_descriptions|xmlrpc_server_add_introspection_data|xmlrpc_server_call_method|xmlrpc_server_create|xmlrpc_server_destroy|xmlrpc_server_register_introspection_callback|xmlrpc_server_register_method|xmlrpc_set_type|xmlwriter_end_attribute|xmlwriter_end_cdata|xmlwriter_end_comment|xmlwriter_end_document|xmlwriter_end_dtd|xmlwriter_end_dtd_attlist|xmlwriter_end_dtd_element|xmlwriter_end_dtd_entity|xmlwriter_end_element|xmlwriter_end_pi|xmlwriter_flush|xmlwriter_full_end_element|xmlwriter_open_memory|xmlwriter_open_uri|xmlwriter_output_memory|xmlwriter_set_indent|xmlwriter_set_indent_string|xmlwriter_start_attribute|xmlwriter_start_attribute_ns|xmlwriter_start_cdata|xmlwriter_start_comment|xmlwriter_start_document|xmlwriter_start_dtd|xmlwriter_start_dtd_attlist|xmlwriter_start_dtd_element|xmlwriter_start_dtd_entity|xmlwriter_start_element|xmlwriter_start_element_ns|xmlwriter_start_pi|xmlwriter_text|xmlwriter_write_attribute|xmlwriter_write_attribute_ns|xmlwriter_write_cdata|xmlwriter_write_comment|xmlwriter_write_dtd|xmlwriter_write_dtd_attlist|xmlwriter_write_dtd_element|xmlwriter_write_dtd_entity|xmlwriter_write_element|xmlwriter_write_element_ns|xmlwriter_write_pi|xmlwriter_write_raw|xpath_eval|xpath_eval_expression|xpath_new_context|xpath_register_ns|xpath_register_ns_auto|xptr_eval|xptr_new_context|xslt_backend_info|xslt_backend_name|xslt_backend_version|xslt_create|xslt_errno|xslt_error|xslt_free|xslt_getopt|xslt_process|xslt_set_base|xslt_set_encoding|xslt_set_error_handler|xslt_set_log|xslt_set_object|xslt_set_sax_handler|xslt_set_sax_handlers|xslt_set_scheme_handler|xslt_set_scheme_handlers|xslt_setopt|xsltprocessor|yaml_emit|yaml_emit_file|yaml_parse|yaml_parse_file|yaml_parse_url|yaz_addinfo|yaz_ccl_conf|yaz_ccl_parse|yaz_close|yaz_connect|yaz_database|yaz_element|yaz_errno|yaz_error|yaz_es|yaz_es_result|yaz_get_option|yaz_hits|yaz_itemorder|yaz_present|yaz_range|yaz_record|yaz_scan|yaz_scan_result|yaz_schema|yaz_search|yaz_set_option|yaz_sort|yaz_syntax|yaz_wait|yp_all|yp_cat|yp_err_string|yp_errno|yp_first|yp_get_default_domain|yp_master|yp_match|yp_next|yp_order|zend_logo_guid|zend_thread_id|zend_version|zip_close|zip_entry_close|zip_entry_compressedsize|zip_entry_compressionmethod|zip_entry_filesize|zip_entry_name|zip_entry_open|zip_entry_read|zip_open|zip_read|ziparchive|ziparchive_addemptydir|ziparchive_addfile|ziparchive_addfromstring|ziparchive_close|ziparchive_deleteindex|ziparchive_deletename|ziparchive_extractto|ziparchive_getarchivecomment|ziparchive_getcommentindex|ziparchive_getcommentname|ziparchive_getfromindex|ziparchive_getfromname|ziparchive_getnameindex|ziparchive_getstatusstring|ziparchive_getstream|ziparchive_locatename|ziparchive_open|ziparchive_renameindex|ziparchive_renamename|ziparchive_setCommentName|ziparchive_setarchivecomment|ziparchive_setcommentindex|ziparchive_statindex|ziparchive_statname|ziparchive_unchangeall|ziparchive_unchangearchive|ziparchive_unchangeindex|ziparchive_unchangename|zlib_get_coding_type".split("|")),n=i.arrayToMap("abstract|and|array|as|break|case|catch|class|clone|const|continue|declare|default|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|final|for|foreach|function|global|goto|if|implements|interface|instanceof|namespace|new|or|private|protected|public|static|switch|throw|try|use|var|while|xor".split("|")),r=i.arrayToMap("die|echo|empty|exit|eval|include|include_once|isset|list|require|require_once|return|print|unset".split("|")),o=i.arrayToMap("true|false|null|__CLASS__|__DIR__|__FILE__|__LINE__|__METHOD__|__FUNCTION__|__NAMESPACE__".split("|")),u=i.arrayToMap("$GLOBALS|$_SERVER|$_GET|$_POST|$_FILES|$_REQUEST|$_SESSION|$_ENV|$_COOKIE|$php_errormsg|$HTTP_RAW_POST_DATA|$http_response_header|$argc|$argv".split("|")),a=i.arrayToMap("key_exists|cairo_matrix_create_scale|cairo_matrix_create_translate|call_user_method|call_user_method_array|com_addref|com_get|com_invoke|com_isenum|com_load|com_release|com_set|connection_timeout|cubrid_load_from_glo|cubrid_new_glo|cubrid_save_to_glo|cubrid_send_glo|define_syslog_variables|dl|ereg|ereg_replace|eregi|eregi_replace|hw_documentattributes|hw_documentbodytag|hw_documentsize|hw_outputdocument|imagedashedline|maxdb_bind_param|maxdb_bind_result|maxdb_client_encoding|maxdb_close_long_data|maxdb_execute|maxdb_fetch|maxdb_get_metadata|maxdb_param_count|maxdb_send_long_data|mcrypt_ecb|mcrypt_generic_end|mime_content_type|mysql_createdb|mysql_dbname|mysql_db_query|mysql_drop_db|mysql_dropdb|mysql_escape_string|mysql_fieldflags|mysql_fieldflags|mysql_fieldname|mysql_fieldtable|mysql_fieldtype|mysql_freeresult|mysql_listdbs|mysql_list_fields|mysql_listfields|mysql_list_tables|mysql_listtables|mysql_numfields|mysql_numrows|mysql_selectdb|mysql_tablename|mysqli_bind_param|mysqli_bind_result|mysqli_disable_reads_from_master|mysqli_disable_rpl_parse|mysqli_enable_reads_from_master|mysqli_enable_rpl_parse|mysqli_execute|mysqli_fetch|mysqli_get_metadata|mysqli_master_query|mysqli_param_count|mysqli_rpl_parse_enabled|mysqli_rpl_probe|mysqli_rpl_query_type|mysqli_send_long_data|mysqli_send_query|mysqli_slave_query|ocibindbyname|ocicancel|ocicloselob|ocicollappend|ocicollassign|ocicollassignelem|ocicollgetelem|ocicollmax|ocicollsize|ocicolltrim|ocicolumnisnull|ocicolumnname|ocicolumnprecision|ocicolumnscale|ocicolumnsize|ocicolumntype|ocicolumntyperaw|ocicommit|ocidefinebyname|ocierror|ociexecute|ocifetch|ocifetchinto|ocifetchstatement|ocifreecollection|ocifreecursor|ocifreedesc|ocifreestatement|ociinternaldebug|ociloadlob|ocilogoff|ocilogon|ocinewcollection|ocinewcursor|ocinewdescriptor|ocinlogon|ocinumcols|ociparse|ociplogon|ociresult|ocirollback|ocirowcount|ocisavelob|ocisavelobfile|ociserverversion|ocisetprefetch|ocistatementtype|ociwritelobtofile|ociwritetemporarylob|PDF_add_annotation|PDF_add_bookmark|PDF_add_launchlink|PDF_add_locallink|PDF_add_note|PDF_add_outline|PDF_add_pdflink|PDF_add_weblink|PDF_attach_file|PDF_begin_page|PDF_begin_template|PDF_close_pdi|PDF_close|PDF_findfont|PDF_get_font|PDF_get_fontname|PDF_get_fontsize|PDF_get_image_height|PDF_get_image_width|PDF_get_majorversion|PDF_get_minorversion|PDF_get_pdi_parameter|PDF_get_pdi_value|PDF_open_ccitt|PDF_open_file|PDF_open_gif|PDF_open_image_file|PDF_open_image|PDF_open_jpeg|PDF_open_pdi|PDF_open_tiff|PDF_place_image|PDF_place_pdi_page|PDF_set_border_color|PDF_set_border_dash|PDF_set_border_style|PDF_set_char_spacing|PDF_set_duration|PDF_set_horiz_scaling|PDF_set_info_author|PDF_set_info_creator|PDF_set_info_keywords|PDF_set_info_subject|PDF_set_info_title|PDF_set_leading|PDF_set_text_matrix|PDF_set_text_rendering|PDF_set_text_rise|PDF_set_word_spacing|PDF_setgray_fill|PDF_setgray_stroke|PDF_setgray|PDF_setpolydash|PDF_setrgbcolor_fill|PDF_setrgbcolor_stroke|PDF_setrgbcolor|PDF_show_boxed|php_check_syntax|px_set_tablename|px_set_targetencoding|runkit_sandbox_output_handler|session_is_registered|session_register|session_unregisterset_magic_quotes_runtime|magic_quotes_runtime|set_socket_blocking|socket_set_blocking|set_socket_timeout|socket_set_timeout|split|spliti|sql_regcase".split("|")),f=i.arrayToMap("cfunction|old_function".split("|")),l=i.arrayToMap([]);this.$rules={start:[{token:"comment",regex:/(?:#|\/\/)(?:[^?]|\?[^>])*/},e.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/][gimy]*\\s*(?=[).,;]|$)"},{token:"string",regex:'"',next:"qqstring"},{token:"string",regex:"'",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language",regex:"\\b(?:DEFAULT_INCLUDE_PATH|E_(?:ALL|CO(?:MPILE_(?:ERROR|WARNING)|RE_(?:ERROR|WARNING))|ERROR|NOTICE|PARSE|STRICT|USER_(?:ERROR|NOTICE|WARNING)|WARNING)|P(?:EAR_(?:EXTENSION_DIR|INSTALL_DIR)|HP_(?:BINDIR|CONFIG_FILE_(?:PATH|SCAN_DIR)|DATADIR|E(?:OL|XTENSION_DIR)|INT_(?:MAX|SIZE)|L(?:IBDIR|OCALSTATEDIR)|O(?:S|UTPUT_HANDLER_(?:CONT|END|START))|PREFIX|S(?:API|HLIB_SUFFIX|YSCONFDIR)|VERSION))|__COMPILER_HALT_OFFSET__)\\b"},{token:["keyword","text","support.class"],regex:"\\b(new)(\\s+)(\\w+)"},{token:["support.class","keyword.operator"],regex:"\\b(\\w+)(::)"},{token:"constant.language",regex:"\\b(?:A(?:B(?:DAY_(?:1|2|3|4|5|6|7)|MON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9))|LT_DIGITS|M_STR|SSERT_(?:ACTIVE|BAIL|CALLBACK|QUIET_EVAL|WARNING))|C(?:ASE_(?:LOWER|UPPER)|HAR_MAX|O(?:DESET|NNECTION_(?:ABORTED|NORMAL|TIMEOUT)|UNT_(?:NORMAL|RECURSIVE))|R(?:EDITS_(?:ALL|DOCS|FULLPAGE|G(?:ENERAL|ROUP)|MODULES|QA|SAPI)|NCYSTR|YPT_(?:BLOWFISH|EXT_DES|MD5|S(?:ALT_LENGTH|TD_DES)))|URRENCY_SYMBOL)|D(?:AY_(?:1|2|3|4|5|6|7)|ECIMAL_POINT|IRECTORY_SEPARATOR|_(?:FMT|T_FMT))|E(?:NT_(?:COMPAT|NOQUOTES|QUOTES)|RA(?:_(?:D_(?:FMT|T_FMT)|T_FMT|YEAR)|)|XTR_(?:IF_EXISTS|OVERWRITE|PREFIX_(?:ALL|I(?:F_EXISTS|NVALID)|SAME)|SKIP))|FRAC_DIGITS|GROUPING|HTML_(?:ENTITIES|SPECIALCHARS)|IN(?:FO_(?:ALL|C(?:ONFIGURATION|REDITS)|ENVIRONMENT|GENERAL|LICENSE|MODULES|VARIABLES)|I_(?:ALL|PERDIR|SYSTEM|USER)|T_(?:CURR_SYMBOL|FRAC_DIGITS))|L(?:C_(?:ALL|C(?:OLLATE|TYPE)|M(?:ESSAGES|ONETARY)|NUMERIC|TIME)|O(?:CK_(?:EX|NB|SH|UN)|G_(?:A(?:LERT|UTH(?:PRIV|))|C(?:ONS|R(?:IT|ON))|D(?:AEMON|EBUG)|E(?:MERG|RR)|INFO|KERN|L(?:OCAL(?:0|1|2|3|4|5|6|7)|PR)|MAIL|N(?:DELAY|EWS|O(?:TICE|WAIT))|ODELAY|P(?:ERROR|ID)|SYSLOG|U(?:SER|UCP)|WARNING)))|M(?:ON_(?:1(?:0|1|2|)|2|3|4|5|6|7|8|9|DECIMAL_POINT|GROUPING|THOUSANDS_SEP)|_(?:1_PI|2_(?:PI|SQRTPI)|E|L(?:N(?:10|2)|OG(?:10E|2E))|PI(?:_(?:2|4)|)|SQRT(?:1_2|2)))|N(?:EGATIVE_SIGN|O(?:EXPR|STR)|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|P(?:ATH(?:INFO_(?:BASENAME|DIRNAME|EXTENSION)|_SEPARATOR)|M_STR|OSITIVE_SIGN|_(?:CS_PRECEDES|S(?:EP_BY_SPACE|IGN_POSN)))|RADIXCHAR|S(?:EEK_(?:CUR|END|SET)|ORT_(?:ASC|DESC|NUMERIC|REGULAR|STRING)|TR_PAD_(?:BOTH|LEFT|RIGHT))|T(?:HOUS(?:ANDS_SEP|EP)|_FMT(?:_AMPM|))|YES(?:EXPR|STR)|STD(?:IN|OUT|ERR))\\b"},{token:function(e){return n.hasOwnProperty(e)?"keyword":o.hasOwnProperty(e)?"constant.language":u.hasOwnProperty(e)?"variable.language":l.hasOwnProperty(e)?"invalid.illegal":t.hasOwnProperty(e)?"support.function":e=="debugger"?"invalid.deprecated":e.match(/^(\$[a-zA-Z_\x7f-\uffff][a-zA-Z0-9_\x7f-\uffff]*|self|parent)$/)?"variable":"identifier"},regex:/[a-zA-Z_$\x7f-\uffff][a-zA-Z0-9_\x7f-\uffff]*/},{onMatch:function(e,t,n){e=e.substr(3);if(e[0]=="'"||e[0]=='"')e=e.slice(1,-1);return n.unshift(this.next,e),"markup.list"},regex:/<<<(?:\w+|'\w+'|"\w+")$/,next:"heredoc"},{token:"keyword.operator",regex:"::|!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|!=|!==|<=|>=|=>|<<=|>>=|>>>=|<>|<|>|=|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],heredoc:[{onMatch:function(e,t,n){return n[1]!=e?"string":(n.shift(),n.shift(),"markup.list")},regex:"^\\w+(?=;?$)",next:"start"},{token:"string",regex:".*"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"constant.language.escape",regex:'\\\\(?:[nrtvef\\\\"$]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2})'},{token:"constant.language.escape",regex:/\$[\w]+(?:\[[\w\]+]|=>\w+)?/},{token:"constant.language.escape",regex:/\$\{[^"\}]+\}?/},{token:"string",regex:'"',next:"start"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:/\\['\\]/},{token:"string",regex:"'",next:"start"},{defaultToken:"string"}]},this.embedRules(s,"doc-",[s.getEndRule("start")])};r.inherits(a,o);var f=function(){u.call(this);var e=[{token:"support.php_tag",regex:"<\\?(?:php|=)?",push:"php-start"}],t=[{token:"support.php_tag",regex:"\\?>",next:"pop"}];for(var n in this.$rules)this.$rules[n].unshift.apply(this.$rules[n],e);this.embedRules(a,"php-",t,["start"]),this.normalizeRules()};r.inherits(f,u),t.PhpHighlightRules=f,t.PhpLangHighlightRules=a}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/php",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/php_highlight_rules","ace/mode/php_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle","ace/unicode"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./php_highlight_rules").PhpHighlightRules,o=e("./php_highlight_rules").PhpLangHighlightRules,u=e("./matching_brace_outdent").MatchingBraceOutdent,a=e("../range").Range,f=e("../worker/worker_client").WorkerClient,l=e("./behaviour/cstyle").CstyleBehaviour,c=e("./folding/cstyle").FoldMode,h=e("../unicode"),p=function(e){this.inlinePhp=e&&e.inline;var t=this.inlinePhp?o:s;this.HighlightRules=t,this.$outdent=new u,this.$behaviour=new l,this.foldingRules=new c};r.inherits(p,i),function(){this.tokenRe=new RegExp("^["+h.packages.L+h.packages.Mn+h.packages.Mc+h.packages.Nd+h.packages.Pc+"_]+","g"),this.nonTokenRe=new RegExp("^(?:[^"+h.packages.L+h.packages.Mn+h.packages.Mc+h.packages.Nd+h.packages.Pc+"_]|s])+","g"),this.lineCommentStart=["//","#"],this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="php-start"){var u=t.match(/^.*[\{\(\[\:]\s*$/);u&&(r+=n)}else if(e=="php-doc-start"){if(o!="php-doc-start")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new f(["ace"],"ace/mode/php_worker","PhpWorker");return t.attachToDocument(e.getDocument()),this.inlinePhp&&t.call("setOptions",[{inline:!0}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("ok",function(){e.clearAnnotations()}),t},this.$id="ace/mode/php"}.call(p.prototype),t.Mode=p})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-plain_text.js b/dist/assets/js/vendor/ace-nc/mode-plain_text.js
            new file mode 100644
            index 0000000000..be72ab9982
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-plain_text.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/plain_text",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/behaviour"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./text_highlight_rules").TextHighlightRules,o=e("./behaviour").Behaviour,u=function(){this.HighlightRules=s,this.$behaviour=new o};r.inherits(u,i),function(){this.type="text",this.getNextLineIndent=function(e,t,n){return""},this.$id="ace/mode/plain_text"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-powershell.js b/dist/assets/js/vendor/ace-nc/mode-powershell.js
            new file mode 100644
            index 0000000000..514449cf85
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-powershell.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/powershell_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="function|if|else|elseif|switch|while|default|for|do|until|break|continue|foreach|return|filter|in|trap|throw|param|begin|process|end",t="Get-Alias|Import-Alias|New-Alias|Set-Alias|Get-AuthenticodeSignature|Set-AuthenticodeSignature|Set-Location|Get-ChildItem|Clear-Item|Get-Command|Measure-Command|Trace-Command|Add-Computer|Checkpoint-Computer|Remove-Computer|Restart-Computer|Restore-Computer|Stop-Computer|Reset-ComputerMachinePassword|Test-ComputerSecureChannel|Add-Content|Get-Content|Set-Content|Clear-Content|Get-Command|Invoke-Command|Enable-ComputerRestore|Disable-ComputerRestore|Get-ComputerRestorePoint|Test-Connection|ConvertFrom-CSV|ConvertTo-CSV|ConvertTo-Html|ConvertTo-Xml|ConvertFrom-SecureString|ConvertTo-SecureString|Copy-Item|Export-Counter|Get-Counter|Import-Counter|Get-Credential|Get-Culture|Get-ChildItem|Get-Date|Set-Date|Remove-Item|Compare-Object|Get-Event|Get-WinEvent|New-Event|Remove-Event|Unregister-Event|Wait-Event|Clear-EventLog|Get-Eventlog|Limit-EventLog|New-Eventlog|Remove-EventLog|Show-EventLog|Write-EventLog|Get-EventSubscriber|Register-EngineEvent|Register-ObjectEvent|Register-WmiEvent|Get-ExecutionPolicy|Set-ExecutionPolicy|Export-Alias|Export-Clixml|Export-Console|Export-Csv|ForEach-Object|Format-Custom|Format-List|Format-Table|Format-Wide|Export-FormatData|Get-FormatData|Get-Item|Get-ChildItem|Get-Help|Add-History|Clear-History|Get-History|Invoke-History|Get-Host|Read-Host|Write-Host|Get-HotFix|Import-Clixml|Import-Csv|Invoke-Command|Invoke-Expression|Get-Item|Invoke-Item|New-Item|Remove-Item|Set-Item|Clear-ItemProperty|Copy-ItemProperty|Get-ItemProperty|Move-ItemProperty|New-ItemProperty|Remove-ItemProperty|Rename-ItemProperty|Set-ItemProperty|Get-Job|Receive-Job|Remove-Job|Start-Job|Stop-Job|Wait-Job|Stop-Process|Update-List|Get-Location|Pop-Location|Push-Location|Set-Location|Send-MailMessage|Add-Member|Get-Member|Move-Item|Compare-Object|Group-Object|Measure-Object|New-Object|Select-Object|Sort-Object|Where-Object|Out-Default|Out-File|Out-GridView|Out-Host|Out-Null|Out-Printer|Out-String|Convert-Path|Join-Path|Resolve-Path|Split-Path|Test-Path|Get-Pfxcertificate|Pop-Location|Push-Location|Get-Process|Start-Process|Stop-Process|Wait-Process|Enable-PSBreakpoint|Disable-PSBreakpoint|Get-PSBreakpoint|Set-PSBreakpoint|Remove-PSBreakpoint|Get-PSDrive|New-PSDrive|Remove-PSDrive|Get-PSProvider|Set-PSdebug|Enter-PSSession|Exit-PSSession|Export-PSSession|Get-PSSession|Import-PSSession|New-PSSession|Remove-PSSession|Disable-PSSessionConfiguration|Enable-PSSessionConfiguration|Get-PSSessionConfiguration|Register-PSSessionConfiguration|Set-PSSessionConfiguration|Unregister-PSSessionConfiguration|New-PSSessionOption|Add-PsSnapIn|Get-PsSnapin|Remove-PSSnapin|Get-Random|Read-Host|Remove-Item|Rename-Item|Rename-ItemProperty|Select-Object|Select-XML|Send-MailMessage|Get-Service|New-Service|Restart-Service|Resume-Service|Set-Service|Start-Service|Stop-Service|Suspend-Service|Sort-Object|Start-Sleep|ConvertFrom-StringData|Select-String|Tee-Object|New-Timespan|Trace-Command|Get-Tracesource|Set-Tracesource|Start-Transaction|Complete-Transaction|Get-Transaction|Use-Transaction|Undo-Transaction|Start-Transcript|Stop-Transcript|Add-Type|Update-TypeData|Get-Uiculture|Get-Unique|Update-Formatdata|Update-Typedata|Clear-Variable|Get-Variable|New-Variable|Remove-Variable|Set-Variable|New-WebServiceProxy|Where-Object|Write-Debug|Write-Error|Write-Host|Write-Output|Write-Progress|Write-Verbose|Write-Warning|Set-WmiInstance|Invoke-WmiMethod|Get-WmiObject|Remove-WmiObject|Connect-WSMan|Disconnect-WSMan|Test-WSMan|Invoke-WSManAction|Disable-WSManCredSSP|Enable-WSManCredSSP|Get-WSManCredSSP|New-WSManInstance|Get-WSManInstance|Set-WSManInstance|Remove-WSManInstance|Set-WSManQuickConfig|New-WSManSessionOption",n=this.createKeywordMapper({"support.function":t,keyword:e},"identifier"),r="eq|ne|ge|gt|lt|le|like|notlike|match|notmatch|replace|contains|notcontains|ieq|ine|ige|igt|ile|ilt|ilike|inotlike|imatch|inotmatch|ireplace|icontains|inotcontains|is|isnot|as|and|or|band|bor|not";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment.start",regex:"<#",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"[$](?:[Tt]rue|[Ff]alse)\\b"},{token:"constant.language",regex:"[$][Nn]ull\\b"},{token:"variable.instance",regex:"[$][a-zA-Z][a-zA-Z0-9_]*\\b"},{token:n,regex:"[a-zA-Z_$][a-zA-Z0-9_$\\-]*\\b"},{token:"keyword.operator",regex:"\\-(?:"+r+")"},{token:"keyword.operator",regex:"&|\\*|\\+|\\-|\\=|\\+=|\\-="},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment.end",regex:"#>",next:"start"},{token:"doc.comment.tag",regex:"^\\.\\w+"},{token:"comment",regex:"\\w+"},{token:"comment",regex:"."}]}};r.inherits(s,i),t.PowershellHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/powershell",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/powershell_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./powershell_highlight_rules").PowershellHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a({start:"^\\s*(<#)",end:"^[#\\s]>\\s*$"})};r.inherits(f,i),function(){this.lineCommentStart="#",this.blockComment={start:"<#",end:"#>"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[]\s*$/);o&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){return null},this.$id="ace/mode/powershell"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-prolog.js b/dist/assets/js/vendor/ace-nc/mode-prolog.js
            new file mode 100644
            index 0000000000..66c8eae9b3
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-prolog.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/prolog_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{include:"#comment"},{include:"#basic_fact"},{include:"#rule"},{include:"#directive"},{include:"#fact"}],"#atom":[{token:"constant.other.atom.prolog",regex:"\\b[a-z][a-zA-Z0-9_]*\\b"},{token:"constant.numeric.prolog",regex:"-?\\d+(?:\\.\\d+)?"},{include:"#string"}],"#basic_elem":[{include:"#comment"},{include:"#statement"},{include:"#constants"},{include:"#operators"},{include:"#builtins"},{include:"#list"},{include:"#atom"},{include:"#variable"}],"#basic_fact":[{token:["entity.name.function.fact.basic.prolog","punctuation.end.fact.basic.prolog"],regex:"([a-z]\\w*)(\\.)"}],"#builtins":[{token:"support.function.builtin.prolog",regex:"\\b(?:abolish|abort|ancestors|arg|ascii|assert[az]|atom(?:ic)?|body|char|close|conc|concat|consult|define|definition|dynamic|dump|fail|file|free|free_proc|functor|getc|goal|halt|head|head|integer|length|listing|match_args|member|next_clause|nl|nonvar|nth|number|cvars|nvars|offset|op|print?|prompt|putc|quoted|ratom|read|redefine|rename|retract(?:all)?|see|seeing|seen|skip|spy|statistics|system|tab|tell|telling|term|time|told|univ|unlink_clause|unspy_predicate|var|write)\\b"}],"#comment":[{token:["punctuation.definition.comment.prolog","comment.line.percentage.prolog"],regex:"(%)(.*$)"},{token:"punctuation.definition.comment.prolog",regex:"/\\*",push:[{token:"punctuation.definition.comment.prolog",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.prolog"}]}],"#constants":[{token:"constant.language.prolog",regex:"\\b(?:true|false|yes|no)\\b"}],"#directive":[{token:"keyword.operator.directive.prolog",regex:":-",push:[{token:"meta.directive.prolog",regex:"\\.",next:"pop"},{include:"#comment"},{include:"#statement"},{defaultToken:"meta.directive.prolog"}]}],"#expr":[{include:"#comments"},{token:"meta.expression.prolog",regex:"\\(",push:[{token:"meta.expression.prolog",regex:"\\)",next:"pop"},{include:"#expr"},{defaultToken:"meta.expression.prolog"}]},{token:"keyword.control.cutoff.prolog",regex:"!"},{token:"punctuation.control.and.prolog",regex:","},{token:"punctuation.control.or.prolog",regex:";"},{include:"#basic_elem"}],"#fact":[{token:["entity.name.function.fact.prolog","punctuation.begin.fact.parameters.prolog"],regex:"([a-z]\\w*)(\\()(?!.*:-)",push:[{token:["punctuation.end.fact.parameters.prolog","punctuation.end.fact.prolog"],regex:"(\\))(\\.?)",next:"pop"},{include:"#parameter"},{defaultToken:"meta.fact.prolog"}]}],"#list":[{token:"punctuation.begin.list.prolog",regex:"\\[(?=.*\\])",push:[{token:"punctuation.end.list.prolog",regex:"\\]",next:"pop"},{include:"#comment"},{token:"punctuation.separator.list.prolog",regex:","},{token:"punctuation.concat.list.prolog",regex:"\\|",push:[{token:"meta.list.concat.prolog",regex:"(?=\\s*\\])",next:"pop"},{include:"#basic_elem"},{defaultToken:"meta.list.concat.prolog"}]},{include:"#basic_elem"},{defaultToken:"meta.list.prolog"}]}],"#operators":[{token:"keyword.operator.prolog",regex:"\\\\\\+|\\bnot\\b|\\bis\\b|->|[><]|[><\\\\:=]?=|(?:=\\\\|\\\\=)="}],"#parameter":[{token:"variable.language.anonymous.prolog",regex:"\\b_\\b"},{token:"variable.parameter.prolog",regex:"\\b[A-Z_]\\w*\\b"},{token:"punctuation.separator.parameters.prolog",regex:","},{include:"#basic_elem"},{token:"text",regex:"[^\\s]"}],"#rule":[{token:"meta.rule.prolog",regex:"(?=[a-z]\\w*.*:-)",push:[{token:"punctuation.rule.end.prolog",regex:"\\.",next:"pop"},{token:"meta.rule.signature.prolog",regex:"(?=[a-z]\\w*.*:-)",push:[{token:"meta.rule.signature.prolog",regex:"(?=:-)",next:"pop"},{token:"entity.name.function.rule.prolog",regex:"[a-z]\\w*(?=\\(|\\s*:-)"},{token:"punctuation.rule.parameters.begin.prolog",regex:"\\(",push:[{token:"punctuation.rule.parameters.end.prolog",regex:"\\)",next:"pop"},{include:"#parameter"},{defaultToken:"meta.rule.parameters.prolog"}]},{defaultToken:"meta.rule.signature.prolog"}]},{token:"keyword.operator.definition.prolog",regex:":-",push:[{token:"meta.rule.definition.prolog",regex:"(?=\\.)",next:"pop"},{include:"#comment"},{include:"#expr"},{defaultToken:"meta.rule.definition.prolog"}]},{defaultToken:"meta.rule.prolog"}]}],"#statement":[{token:"meta.statement.prolog",regex:"(?=[a-z]\\w*\\()",push:[{token:"punctuation.end.statement.parameters.prolog",regex:"\\)",next:"pop"},{include:"#builtins"},{include:"#atom"},{token:"punctuation.begin.statement.parameters.prolog",regex:"\\(",push:[{token:"meta.statement.parameters.prolog",regex:"(?=\\))",next:"pop"},{token:"punctuation.separator.statement.prolog",regex:","},{include:"#basic_elem"},{defaultToken:"meta.statement.parameters.prolog"}]},{defaultToken:"meta.statement.prolog"}]}],"#string":[{token:"punctuation.definition.string.begin.prolog",regex:"'",push:[{token:"punctuation.definition.string.end.prolog",regex:"'",next:"pop"},{token:"constant.character.escape.prolog",regex:"\\\\."},{token:"constant.character.escape.quote.prolog",regex:"''"},{defaultToken:"string.quoted.single.prolog"}]}],"#variable":[{token:"variable.language.anonymous.prolog",regex:"\\b_\\b"},{token:"variable.other.prolog",regex:"\\b[A-Z_][a-zA-Z0-9_]*\\b"}]},this.normalizeRules()};s.metaData={fileTypes:["plg","prolog"],foldingStartMarker:"(%\\s*region \\w*)|([a-z]\\w*.*:- ?)",foldingStopMarker:"(%\\s*end(\\s*region)?)|(?=\\.)",keyEquivalent:"^~P",name:"Prolog",scopeName:"source.prolog"},r.inherits(s,i),t.PrologHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/prolog",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/prolog_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./prolog_highlight_rules").PrologHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="%",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/prolog"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-properties.js b/dist/assets/js/vendor/ace-nc/mode-properties.js
            new file mode 100644
            index 0000000000..bccfa478e8
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-properties.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/properties_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e=/\\u[0-9a-fA-F]{4}|\\/;this.$rules={start:[{token:"comment",regex:/[!#].*$/},{token:"keyword",regex:/[=:]$/},{token:"keyword",regex:/[=:]/,next:"value"},{token:"constant.language.escape",regex:e},{defaultToken:"variable"}],value:[{regex:/\\$/,token:"string",next:"value"},{regex:/$/,token:"string",next:"start"},{token:"constant.language.escape",regex:e},{defaultToken:"string"}]}};r.inherits(s,i),t.PropertiesHighlightRules=s}),ace.define("ace/mode/properties",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/properties_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./properties_highlight_rules").PropertiesHighlightRules,o=function(){this.HighlightRules=s};r.inherits(o,i),function(){this.$id="ace/mode/properties"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-protobuf.js b/dist/assets/js/vendor/ace-nc/mode-protobuf.js
            new file mode 100644
            index 0000000000..a9731e3daf
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-protobuf.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/c_cpp_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=t.cFunctions="\\b(?:hypot(?:f|l)?|s(?:scanf|ystem|nprintf|ca(?:nf|lb(?:n(?:f|l)?|ln(?:f|l)?))|i(?:n(?:h(?:f|l)?|f|l)?|gn(?:al|bit))|tr(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?)|error|pbrk|ftime|len|rchr|xfrm)|printf|et(?:jmp|vbuf|locale|buf)|qrt(?:f|l)?|w(?:scanf|printf)|rand)|n(?:e(?:arbyint(?:f|l)?|xt(?:toward(?:f|l)?|after(?:f|l)?))|an(?:f|l)?)|c(?:s(?:in(?:h(?:f|l)?|f|l)?|qrt(?:f|l)?)|cos(?:h(?:f)?|f|l)?|imag(?:f|l)?|t(?:ime|an(?:h(?:f|l)?|f|l)?)|o(?:s(?:h(?:f|l)?|f|l)?|nj(?:f|l)?|pysign(?:f|l)?)|p(?:ow(?:f|l)?|roj(?:f|l)?)|e(?:il(?:f|l)?|xp(?:f|l)?)|l(?:o(?:ck|g(?:f|l)?)|earerr)|a(?:sin(?:h(?:f|l)?|f|l)?|cos(?:h(?:f|l)?|f|l)?|tan(?:h(?:f|l)?|f|l)?|lloc|rg(?:f|l)?|bs(?:f|l)?)|real(?:f|l)?|brt(?:f|l)?)|t(?:ime|o(?:upper|lower)|an(?:h(?:f|l)?|f|l)?|runc(?:f|l)?|gamma(?:f|l)?|mp(?:nam|file))|i(?:s(?:space|n(?:ormal|an)|cntrl|inf|digit|u(?:nordered|pper)|p(?:unct|rint)|finite|w(?:space|c(?:ntrl|type)|digit|upper|p(?:unct|rint)|lower|al(?:num|pha)|graph|xdigit|blank)|l(?:ower|ess(?:equal|greater)?)|al(?:num|pha)|gr(?:eater(?:equal)?|aph)|xdigit|blank)|logb(?:f|l)?|max(?:div|abs))|di(?:v|fftime)|_Exit|unget(?:c|wc)|p(?:ow(?:f|l)?|ut(?:s|c(?:har)?|wc(?:har)?)|error|rintf)|e(?:rf(?:c(?:f|l)?|f|l)?|x(?:it|p(?:2(?:f|l)?|f|l|m1(?:f|l)?)?))|v(?:s(?:scanf|nprintf|canf|printf|w(?:scanf|printf))|printf|f(?:scanf|printf|w(?:scanf|printf))|w(?:scanf|printf)|a_(?:start|copy|end|arg))|qsort|f(?:s(?:canf|e(?:tpos|ek))|close|tell|open|dim(?:f|l)?|p(?:classify|ut(?:s|c|w(?:s|c))|rintf)|e(?:holdexcept|set(?:e(?:nv|xceptflag)|round)|clearexcept|testexcept|of|updateenv|r(?:aiseexcept|ror)|get(?:e(?:nv|xceptflag)|round))|flush|w(?:scanf|ide|printf|rite)|loor(?:f|l)?|abs(?:f|l)?|get(?:s|c|pos|w(?:s|c))|re(?:open|e|ad|xp(?:f|l)?)|m(?:in(?:f|l)?|od(?:f|l)?|a(?:f|l|x(?:f|l)?)?))|l(?:d(?:iv|exp(?:f|l)?)|o(?:ngjmp|cal(?:time|econv)|g(?:1(?:p(?:f|l)?|0(?:f|l)?)|2(?:f|l)?|f|l|b(?:f|l)?)?)|abs|l(?:div|abs|r(?:int(?:f|l)?|ound(?:f|l)?))|r(?:int(?:f|l)?|ound(?:f|l)?)|gamma(?:f|l)?)|w(?:scanf|c(?:s(?:s(?:tr|pn)|nc(?:py|at|mp)|c(?:spn|hr|oll|py|at|mp)|to(?:imax|d|u(?:l(?:l)?|max)|k|f|l(?:d|l)?|mbs)|pbrk|ftime|len|r(?:chr|tombs)|xfrm)|to(?:b|mb)|rtomb)|printf|mem(?:set|c(?:hr|py|mp)|move))|a(?:s(?:sert|ctime|in(?:h(?:f|l)?|f|l)?)|cos(?:h(?:f|l)?|f|l)?|t(?:o(?:i|f|l(?:l)?)|exit|an(?:h(?:f|l)?|2(?:f|l)?|f|l)?)|b(?:s|ort))|g(?:et(?:s|c(?:har)?|env|wc(?:har)?)|mtime)|r(?:int(?:f|l)?|ound(?:f|l)?|e(?:name|alloc|wind|m(?:ove|quo(?:f|l)?|ainder(?:f|l)?))|a(?:nd|ise))|b(?:search|towc)|m(?:odf(?:f|l)?|em(?:set|c(?:hr|py|mp)|move)|ktime|alloc|b(?:s(?:init|towcs|rtowcs)|towc|len|r(?:towc|len))))\\b",u=function(){var e="break|case|continue|default|do|else|for|goto|if|_Pragma|return|switch|while|catch|operator|try|throw|using",t="asm|__asm__|auto|bool|_Bool|char|_Complex|double|enum|float|_Imaginary|int|long|short|signed|struct|typedef|union|unsigned|void|class|wchar_t|template",n="const|extern|register|restrict|static|volatile|inline|private:|protected:|public:|friend|explicit|virtual|export|mutable|typename",r="and|and_eq|bitand|bitor|compl|not|not_eq|or|or_eq|typeid|xor|xor_eqconst_cast|dynamic_cast|reinterpret_cast|static_cast|sizeof|namespace",s="NULL|true|false|TRUE|FALSE",u=this.$keywords=this.createKeywordMapper({"keyword.control":e,"storage.type":t,"storage.modifier":n,"keyword.operator":r,"variable.language":"this","constant.language":s},"identifier"),a="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Zd\\$_\u00a1-\uffff]*\\b";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"},{token:"keyword",regex:"#\\s*(?:include|import|pragma|line|define|undef|if|ifdef|else|elif|ifndef)\\b",next:"directive"},{token:"keyword",regex:"(?:#\\s*endif)\\b"},{token:"support.function.C99.c",regex:o},{token:u,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"punctuation.operator",regex:"\\?|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}],directive:[{token:"constant.other.multiline",regex:/\\/},{token:"constant.other.multiline",regex:/.*\\/},{token:"constant.other",regex:"\\s*<.+?>",next:"start"},{token:"constant.other",regex:'\\s*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]',next:"start"},{token:"constant.other",regex:"\\s*['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']",next:"start"},{token:"constant.other",regex:/[^\\\/]+/,next:"start"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(u,s),t.c_cppHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/c_cpp",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/c_cpp_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./c_cpp_highlight_rules").c_cppHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/c_cpp"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/protobuf_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="double|float|int32|int64|uint32|uint64|sint32|sint64|fixed32|fixed64|sfixed32|sfixed64|bool|string|bytes",t="message|required|optional|repeated|package|import|option|enum",n=this.createKeywordMapper({"keyword.declaration.protobuf":t,"support.type":e},"identifier");this.$rules={start:[{token:"comment",regex:/\/\/.*$/},{token:"comment",regex:/\/\*/,next:"comment"},{token:"constant",regex:"<[^>]+>"},{regex:"=",token:"keyword.operator.assignment.protobuf"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:n,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(s,i),t.ProtobufHighlightRules=s}),ace.define("ace/mode/protobuf",["require","exports","module","ace/lib/oop","ace/mode/c_cpp","ace/mode/protobuf_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./c_cpp").Mode,s=e("./protobuf_highlight_rules").ProtobufHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){i.call(this),this.foldingRules=new o,this.HighlightRules=s};r.inherits(u,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/protobuf"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-python.js b/dist/assets/js/vendor/ace-nc/mode-python.js
            new file mode 100644
            index 0000000000..f80eb0e8af
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-python.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/python_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|not|or|pass|print|raise|return|try|while|with|yield",t="True|False|None|NotImplemented|Ellipsis|__debug__",n="abs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|binfile|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern",r=this.createKeywordMapper({"invalid.deprecated":"debugger","support.function":n,"constant.language":t,keyword:e},"identifier"),i="(?:r|u|ur|R|U|UR|Ur|uR)?",s="(?:(?:[1-9]\\d*)|(?:0))",o="(?:0[oO]?[0-7]+)",u="(?:0[xX][\\dA-Fa-f]+)",a="(?:0[bB][01]+)",f="(?:"+s+"|"+o+"|"+u+"|"+a+")",l="(?:[eE][+-]?\\d+)",c="(?:\\.\\d+)",h="(?:\\d+)",p="(?:(?:"+h+"?"+c+")|(?:"+h+"\\.))",d="(?:(?:"+p+"|"+h+")"+l+")",v="(?:"+d+"|"+p+")",m="\\\\(x[0-9A-Fa-f]{2}|[0-7]{3}|[\\\\abfnrtv'\"]|U[0-9A-Fa-f]{8}|u[0-9A-Fa-f]{4})";this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"string",regex:i+'"{3}',next:"qqstring3"},{token:"string",regex:i+'"(?=.)',next:"qqstring"},{token:"string",regex:i+"'{3}",next:"qstring3"},{token:"string",regex:i+"'(?=.)",next:"qstring"},{token:"constant.numeric",regex:"(?:"+v+"|\\d+)[jJ]\\b"},{token:"constant.numeric",regex:v},{token:"constant.numeric",regex:f+"[lL]\\b"},{token:"constant.numeric",regex:f+"\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|%|<<|>>|&|\\||\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"},{token:"text",regex:"\\s+"}],qqstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:'"{3}',next:"start"},{defaultToken:"string"}],qstring3:[{token:"constant.language.escape",regex:m},{token:"string",regex:"'{3}",next:"start"},{defaultToken:"string"}],qqstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:m},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"start"},{defaultToken:"string"}]}};r.inherits(s,i),t.PythonHighlightRules=s}),ace.define("ace/mode/folding/pythonic",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e){this.foldingStartMarker=new RegExp("([\\[{])(?:\\s*)$|("+e+")(?:\\s*)(?:#.*)?$")};r.inherits(s,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=e.getLine(n),i=r.match(this.foldingStartMarker);if(i)return i[1]?this.openingBracketBlock(e,i[1],n,i.index):i[2]?this.indentationBlock(e,n,i.index+i[2].length):this.indentationBlock(e,n)}}.call(s.prototype)}),ace.define("ace/mode/python",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/python_highlight_rules","ace/mode/folding/pythonic","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./python_highlight_rules").PythonHighlightRules,o=e("./folding/pythonic").FoldMode,u=e("../range").Range,a=function(){this.HighlightRules=s,this.foldingRules=new o("\\:")};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[\:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new u(n,r.length-i.length,n,r.length))},this.$id="ace/mode/python"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-r.js b/dist/assets/js/vendor/ace-nc/mode-r.js
            new file mode 100644
            index 0000000000..89e73b3067
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-r.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/tex_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(e){e||(e="text"),this.$rules={start:[{token:"comment",regex:"%.*$"},{token:e,regex:"\\\\[$&%#\\{\\}]"},{token:"keyword",regex:"\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b",next:"nospell"},{token:"keyword",regex:"\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])}]"},{token:e,regex:"\\s+"}],nospell:[{token:"comment",regex:"%.*$",next:"start"},{token:"nospell."+e,regex:"\\\\[$&%#\\{\\}]"},{token:"keyword",regex:"\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b"},{token:"keyword",regex:"\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])",next:"start"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])]"},{token:"paren.keyword.operator",regex:"}",next:"start"},{token:"nospell."+e,regex:"\\s+"},{token:"nospell."+e,regex:"\\w+"}]}};r.inherits(o,s),t.TexHighlightRules=o}),ace.define("ace/mode/r_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/tex_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=e("./tex_highlight_rules").TexHighlightRules,u=function(){var e=i.arrayToMap("function|if|in|break|next|repeat|else|for|return|switch|while|try|tryCatch|stop|warning|require|library|attach|detach|source|setMethod|setGeneric|setGroupGeneric|setClass".split("|")),t=i.arrayToMap("NULL|NA|TRUE|FALSE|T|F|Inf|NaN|NA_integer_|NA_real_|NA_character_|NA_complex_".split("|"));this.$rules={start:[{token:"comment.sectionhead",regex:"#+(?!').*(?:----|====|####)\\s*$"},{token:"comment",regex:"#+'",next:"rd-start"},{token:"comment",regex:"#.*$"},{token:"string",regex:'["]',next:"qqstring"},{token:"string",regex:"[']",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+[Li]?\\b"},{token:"constant.numeric",regex:"\\d+L\\b"},{token:"constant.numeric",regex:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b"},{token:"constant.numeric",regex:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b"},{token:"constant.language.boolean",regex:"(?:TRUE|FALSE|T|F)\\b"},{token:"identifier",regex:"`.*?`"},{onMatch:function(n){return e[n]?"keyword":t[n]?"constant.language":n=="..."||n.match(/^\.\.\d+$/)?"variable.language":"identifier"},regex:"[a-zA-Z.][a-zA-Z0-9._]*\\b"},{token:"keyword.operator",regex:"%%|>=|<=|==|!=|\\->|<\\-|\\|\\||&&|=|\\+|\\-|\\*|/|\\^|>|<|!|&|\\||~|\\$|:"},{token:"keyword.operator",regex:"%.*?%"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]};var n=(new o("comment")).getRules();for(var r=0;r<n.start.length;r++)n.start[r].token+=".virtual-comment";this.addRules(n,"rd-"),this.$rules["rd-start"].unshift({token:"text",regex:"^",next:"start"}),this.$rules["rd-start"].unshift({token:"keyword",regex:"@(?!@)[^ ]*"}),this.$rules["rd-start"].unshift({token:"comment",regex:"@@"}),this.$rules["rd-start"].push({token:"comment",regex:"[^%\\\\[({\\])}]+"})};r.inherits(u,s),t.RHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/r",["require","exports","module","ace/range","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/r_highlight_rules","ace/mode/matching_brace_outdent","ace/unicode"],function(e,t,n){"use strict";var r=e("../range").Range,i=e("../lib/oop"),s=e("./text").Mode,o=e("./text_highlight_rules").TextHighlightRules,u=e("./r_highlight_rules").RHighlightRules,a=e("./matching_brace_outdent").MatchingBraceOutdent,f=e("../unicode"),l=function(){this.HighlightRules=u,this.$outdent=new a};i.inherits(l,s),function(){this.lineCommentStart="#",this.$id="ace/mode/r"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-rdoc.js b/dist/assets/js/vendor/ace-nc/mode-rdoc.js
            new file mode 100644
            index 0000000000..8b0c5ce8fe
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-rdoc.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/latex_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"keyword",regex:"\\\\(?:[^a-zA-Z]|[a-zA-Z]+)"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"string",regex:"\\$(?:(?:\\\\.)|(?:[^\\$\\\\]))*?\\$"},{token:"comment",regex:"%.*$"}]}};r.inherits(s,i),t.LatexHighlightRules=s}),ace.define("ace/mode/rdoc_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/latex_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=e("./latex_highlight_rules"),u=function(){this.$rules={start:[{token:"comment",regex:"%.*$"},{token:"text",regex:"\\\\[$&%#\\{\\}]"},{token:"keyword",regex:"\\\\(?:name|alias|method|S3method|S4method|item|code|preformatted|kbd|pkg|var|env|option|command|author|email|url|source|cite|acronym|href|code|preformatted|link|eqn|deqn|keyword|usage|examples|dontrun|dontshow|figure|if|ifelse|Sexpr|RdOpts|inputencoding|usepackage)\\b",next:"nospell"},{token:"keyword",regex:"\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],nospell:[{token:"comment",regex:"%.*$",next:"start"},{token:"nospell.text",regex:"\\\\[$&%#\\{\\}]"},{token:"keyword",regex:"\\\\(?:name|alias|method|S3method|S4method|item|code|preformatted|kbd|pkg|var|env|option|command|author|email|url|source|cite|acronym|href|code|preformatted|link|eqn|deqn|keyword|usage|examples|dontrun|dontshow|figure|if|ifelse|Sexpr|RdOpts|inputencoding|usepackage)\\b"},{token:"keyword",regex:"\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])",next:"start"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])]"},{token:"paren.keyword.operator",regex:"}",next:"start"},{token:"nospell.text",regex:"\\s+"},{token:"nospell.text",regex:"\\w+"}]}};r.inherits(u,s),t.RDocHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/rdoc",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/rdoc_highlight_rules","ace/mode/matching_brace_outdent"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./text_highlight_rules").TextHighlightRules,o=e("./rdoc_highlight_rules").RDocHighlightRules,u=e("./matching_brace_outdent").MatchingBraceOutdent,a=function(e){this.HighlightRules=o,this.$outdent=new u};r.inherits(a,i),function(){this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.$id="ace/mode/rdoc"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-rhtml.js b/dist/assets/js/vendor/ace-nc/mode-rhtml.js
            new file mode 100644
            index 0000000000..b75d29fff8
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-rhtml.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/tex_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(e){e||(e="text"),this.$rules={start:[{token:"comment",regex:"%.*$"},{token:e,regex:"\\\\[$&%#\\{\\}]"},{token:"keyword",regex:"\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b",next:"nospell"},{token:"keyword",regex:"\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])}]"},{token:e,regex:"\\s+"}],nospell:[{token:"comment",regex:"%.*$",next:"start"},{token:"nospell."+e,regex:"\\\\[$&%#\\{\\}]"},{token:"keyword",regex:"\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b"},{token:"keyword",regex:"\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])",next:"start"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])]"},{token:"paren.keyword.operator",regex:"}",next:"start"},{token:"nospell."+e,regex:"\\s+"},{token:"nospell."+e,regex:"\\w+"}]}};r.inherits(o,s),t.TexHighlightRules=o}),ace.define("ace/mode/r_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/tex_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=e("./tex_highlight_rules").TexHighlightRules,u=function(){var e=i.arrayToMap("function|if|in|break|next|repeat|else|for|return|switch|while|try|tryCatch|stop|warning|require|library|attach|detach|source|setMethod|setGeneric|setGroupGeneric|setClass".split("|")),t=i.arrayToMap("NULL|NA|TRUE|FALSE|T|F|Inf|NaN|NA_integer_|NA_real_|NA_character_|NA_complex_".split("|"));this.$rules={start:[{token:"comment.sectionhead",regex:"#+(?!').*(?:----|====|####)\\s*$"},{token:"comment",regex:"#+'",next:"rd-start"},{token:"comment",regex:"#.*$"},{token:"string",regex:'["]',next:"qqstring"},{token:"string",regex:"[']",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+[Li]?\\b"},{token:"constant.numeric",regex:"\\d+L\\b"},{token:"constant.numeric",regex:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b"},{token:"constant.numeric",regex:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b"},{token:"constant.language.boolean",regex:"(?:TRUE|FALSE|T|F)\\b"},{token:"identifier",regex:"`.*?`"},{onMatch:function(n){return e[n]?"keyword":t[n]?"constant.language":n=="..."||n.match(/^\.\.\d+$/)?"variable.language":"identifier"},regex:"[a-zA-Z.][a-zA-Z0-9._]*\\b"},{token:"keyword.operator",regex:"%%|>=|<=|==|!=|\\->|<\\-|\\|\\||&&|=|\\+|\\-|\\*|/|\\^|>|<|!|&|\\||~|\\$|:"},{token:"keyword.operator",regex:"%.*?%"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]};var n=(new o("comment")).getRules();for(var r=0;r<n.start.length;r++)n.start[r].token+=".virtual-comment";this.addRules(n,"rd-"),this.$rules["rd-start"].unshift({token:"text",regex:"^",next:"start"}),this.$rules["rd-start"].unshift({token:"keyword",regex:"@(?!@)[^ ]*"}),this.$rules["rd-start"].unshift({token:"comment",regex:"@@"}),this.$rules["rd-start"].push({token:"comment",regex:"[^%\\\\[({\\])}]+"})};r.inherits(u,s),t.RHighlightRules=u}),ace.define("ace/mode/rhtml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/r_highlight_rules","ace/mode/html_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./r_highlight_rules").RHighlightRules,s=e("./html_highlight_rules").HtmlHighlightRules,o=e("./text_highlight_rules").TextHighlightRules,u=function(){s.call(this),this.$rules.start.unshift({token:"support.function.codebegin",regex:"^<!--\\s*begin.rcode\\s*(?:.*)",next:"r-start"}),this.embedRules(i,"r-",[{token:"support.function.codeend",regex:"^\\s*end.rcode\\s*-->",next:"start"}],["start"]),this.normalizeRules()};r.inherits(u,o),t.RHtmlHighlightRules=u}),ace.define("ace/mode/rhtml",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/rhtml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html").Mode,s=e("./rhtml_highlight_rules").RHtmlHighlightRules,o=function(e,t){i.call(this),this.$session=t,this.HighlightRules=s};r.inherits(o,i),function(){this.insertChunkInfo={value:"<!--begin.rcode\n\nend.rcode-->\n",position:{row:0,column:15}},this.getLanguageMode=function(e){return this.$session.getState(e.row).match(/^r-/)?"R":"HTML"},this.$id="ace/mode/rhtml"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-ruby.js b/dist/assets/js/vendor/ace-nc/mode-ruby.js
            new file mode 100644
            index 0000000000..e5975316d9
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-ruby.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/ruby_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.constantOtherSymbol={token:"constant.other.symbol.ruby",regex:"[:](?:[A-Za-z_]|[@$](?=[a-zA-Z0-9_]))[a-zA-Z0-9_]*[!=?]?"},o=t.qString={token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},u=t.qqString={token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},a=t.tString={token:"string",regex:"[`](?:(?:\\\\.)|(?:[^'\\\\]))*?[`]"},f=t.constantNumericHex={token:"constant.numeric",regex:"0[xX][0-9a-fA-F](?:[0-9a-fA-F]|_(?=[0-9a-fA-F]))*\\b"},l=t.constantNumericFloat={token:"constant.numeric",regex:"[+-]?\\d(?:\\d|_(?=\\d))*(?:(?:\\.\\d(?:\\d|_(?=\\d))*)?(?:[eE][+-]?\\d+)?)?\\b"},c=function(){var e="abort|Array|assert|assert_equal|assert_not_equal|assert_same|assert_not_same|assert_nil|assert_not_nil|assert_match|assert_no_match|assert_in_delta|assert_throws|assert_raise|assert_nothing_raised|assert_instance_of|assert_kind_of|assert_respond_to|assert_operator|assert_send|assert_difference|assert_no_difference|assert_recognizes|assert_generates|assert_response|assert_redirected_to|assert_template|assert_select|assert_select_email|assert_select_rjs|assert_select_encoded|css_select|at_exit|attr|attr_writer|attr_reader|attr_accessor|attr_accessible|autoload|binding|block_given?|callcc|caller|catch|chomp|chomp!|chop|chop!|defined?|delete_via_redirect|eval|exec|exit|exit!|fail|Float|flunk|follow_redirect!|fork|form_for|form_tag|format|gets|global_variables|gsub|gsub!|get_via_redirect|host!|https?|https!|include|Integer|lambda|link_to|link_to_unless_current|link_to_function|link_to_remote|load|local_variables|loop|open|open_session|p|print|printf|proc|putc|puts|post_via_redirect|put_via_redirect|raise|rand|raw|readline|readlines|redirect?|request_via_redirect|require|scan|select|set_trace_func|sleep|split|sprintf|srand|String|stylesheet_link_tag|syscall|system|sub|sub!|test|throw|trace_var|trap|untrace_var|atan2|cos|exp|frexp|ldexp|log|log10|sin|sqrt|tan|render|javascript_include_tag|csrf_meta_tag|label_tag|text_field_tag|submit_tag|check_box_tag|content_tag|radio_button_tag|text_area_tag|password_field_tag|hidden_field_tag|fields_for|select_tag|options_for_select|options_from_collection_for_select|collection_select|time_zone_select|select_date|select_time|select_datetime|date_select|time_select|datetime_select|select_year|select_month|select_day|select_hour|select_minute|select_second|file_field_tag|file_field|respond_to|skip_before_filter|around_filter|after_filter|verify|protect_from_forgery|rescue_from|helper_method|redirect_to|before_filter|send_data|send_file|validates_presence_of|validates_uniqueness_of|validates_length_of|validates_format_of|validates_acceptance_of|validates_associated|validates_exclusion_of|validates_inclusion_of|validates_numericality_of|validates_with|validates_each|authenticate_or_request_with_http_basic|authenticate_or_request_with_http_digest|filter_parameter_logging|match|get|post|resources|redirect|scope|assert_routing|translate|localize|extract_locale_from_tld|caches_page|expire_page|caches_action|expire_action|cache|expire_fragment|expire_cache_for|observe|cache_sweeper|has_many|has_one|belongs_to|has_and_belongs_to_many",t="alias|and|BEGIN|begin|break|case|class|def|defined|do|else|elsif|END|end|ensure|__FILE__|finally|for|gem|if|in|__LINE__|module|next|not|or|private|protected|public|redo|rescue|retry|return|super|then|undef|unless|until|when|while|yield",n="true|TRUE|false|FALSE|nil|NIL|ARGF|ARGV|DATA|ENV|RUBY_PLATFORM|RUBY_RELEASE_DATE|RUBY_VERSION|STDERR|STDIN|STDOUT|TOPLEVEL_BINDING",r="$DEBUG|$defout|$FILENAME|$LOAD_PATH|$SAFE|$stdin|$stdout|$stderr|$VERBOSE|$!|root_url|flash|session|cookies|params|request|response|logger|self",i=this.$keywords=this.createKeywordMapper({keyword:t,"constant.language":n,"variable.language":r,"support.function":e,"invalid.deprecated":"debugger"},"identifier");this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"comment",regex:"^=begin(?:$|\\s.*$)",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},o,u,a,{token:"text",regex:"::"},{token:"variable.instance",regex:"@{1,2}[a-zA-Z_\\d]+"},{token:"support.class",regex:"[A-Z][a-zA-Z_\\d]+"},s,f,l,{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:i,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"punctuation.separator.key-value",regex:"=>"},{stateName:"heredoc",onMatch:function(e,t,n){var r=e[2]=="-"?"indentedHeredoc":"heredoc",i=e.split(this.splitRegex);return n.push(r,i[3]),[{type:"constant",value:i[1]},{type:"string",value:i[2]},{type:"support.class",value:i[3]},{type:"string",value:i[4]}]},regex:"(<<-?)(['\"`]?)([\\w]+)(['\"`]?)",rules:{heredoc:[{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}],indentedHeredoc:[{token:"string",regex:"^ +"},{onMatch:function(e,t,n){return e===n[1]?(n.shift(),n.shift(),this.next=n[0]||"start","support.class"):(this.next="","string")},regex:".*$",next:"start"}]}},{regex:"$",token:"empty",next:function(e,t){return t[0]==="heredoc"||t[0]==="indentedHeredoc"?t[0]:e}},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:"^=end(?:$|\\s.*$)",next:"start"},{token:"comment",regex:".+"}]},this.normalizeRules()};r.inherits(c,i),t.RubyHighlightRules=c}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/ruby",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/ruby_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./ruby_highlight_rules").RubyHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./folding/coffee").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new a};r.inherits(f,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[]\s*$/),u=t.match(/^\s*(class|def|module)\s.*$/),a=t.match(/.*do(\s*|\s+\|.*\|\s*)$/),f=t.match(/^\s*(if|else)\s*/);if(o||u||a||f)r+=n}return r},this.checkOutdent=function(e,t,n){return/^\s+(end|else)$/.test(t+n)||this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){var r=t.getLine(n);if(/}/.test(r))return this.$outdent.autoOutdent(t,n);var i=this.$getIndent(r),s=t.getLine(n-1),o=this.$getIndent(s),a=t.getTabString();o.length<=i.length&&i.slice(-a.length)==a&&t.remove(new u(n,i.length-a.length,n,i.length))},this.$id="ace/mode/ruby"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-rust.js b/dist/assets/js/vendor/ace-nc/mode-rust.js
            new file mode 100644
            index 0000000000..98a14addaf
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-rust.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/rust_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"variable.other.source.rust",regex:"'[a-zA-Z_][a-zA-Z0-9_]*[^\\']"},{token:"string.quoted.single.source.rust",regex:"'",push:[{token:"string.quoted.single.source.rust",regex:"'",next:"pop"},{include:"#rust_escaped_character"},{defaultToken:"string.quoted.single.source.rust"}]},{token:"string.quoted.double.source.rust",regex:'"',push:[{token:"string.quoted.double.source.rust",regex:'"',next:"pop"},{include:"#rust_escaped_character"},{defaultToken:"string.quoted.double.source.rust"}]},{token:["keyword.source.rust","meta.function.source.rust","entity.name.function.source.rust","meta.function.source.rust"],regex:"\\b(fn)(\\s+)([a-zA-Z_][a-zA-Z0-9_][\\w\\:,+ \\'<>]*)(\\s*\\()"},{token:"support.constant",regex:"\\b[a-zA-Z_][\\w\\d]*::"},{token:"keyword.source.rust",regex:"\\b(?:as|assert|break|claim|const|copy|Copy|do|drop|else|extern|fail|for|if|impl|in|let|log|loop|match|mod|module|move|mut|Owned|priv|pub|pure|ref|return|unchecked|unsafe|use|while|mod|Send|static|trait|class|struct|enum|type)\\b"},{token:"storage.type.source.rust",regex:"\\b(?:Self|m32|m64|m128|f80|f16|f128|int|uint|float|char|bool|u8|u16|u32|u64|f32|f64|i8|i16|i32|i64|str|option|either|c_float|c_double|c_void|FILE|fpos_t|DIR|dirent|c_char|c_schar|c_uchar|c_short|c_ushort|c_int|c_uint|c_long|c_ulong|size_t|ptrdiff_t|clock_t|time_t|c_longlong|c_ulonglong|intptr_t|uintptr_t|off_t|dev_t|ino_t|pid_t|mode_t|ssize_t)\\b"},{token:"variable.language.source.rust",regex:"\\bself\\b"},{token:"keyword.operator",regex:"!|\\$|\\*|\\-\\-|\\-|\\+\\+|\\+|-->|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|/=|%=|\\+=|\\-=|&=|\\^=|,|;"},{token:"constant.language.source.rust",regex:"\\b(?:true|false|Some|None|Left|Right|Ok|Err)\\b"},{token:"support.constant.source.rust",regex:"\\b(?:EXIT_FAILURE|EXIT_SUCCESS|RAND_MAX|EOF|SEEK_SET|SEEK_CUR|SEEK_END|_IOFBF|_IONBF|_IOLBF|BUFSIZ|FOPEN_MAX|FILENAME_MAX|L_tmpnam|TMP_MAX|O_RDONLY|O_WRONLY|O_RDWR|O_APPEND|O_CREAT|O_EXCL|O_TRUNC|S_IFIFO|S_IFCHR|S_IFBLK|S_IFDIR|S_IFREG|S_IFMT|S_IEXEC|S_IWRITE|S_IREAD|S_IRWXU|S_IXUSR|S_IWUSR|S_IRUSR|F_OK|R_OK|W_OK|X_OK|STDIN_FILENO|STDOUT_FILENO|STDERR_FILENO)\\b"},{token:"meta.preprocessor.source.rust",regex:"\\b\\w\\(\\w\\)*!|#\\[[\\w=\\(\\)_]+\\]\\b"},{token:"constant.numeric.integer.source.rust",regex:"\\b(?:[0-9][0-9_]*|[0-9][0-9_]*(?:u|u8|u16|u32|u64)|[0-9][0-9_]*(?:i|i8|i16|i32|i64))\\b"},{token:"constant.numeric.hex.source.rust",regex:"\\b(?:0x[a-fA-F0-9_]+|0x[a-fA-F0-9_]+(?:u|u8|u16|u32|u64)|0x[a-fA-F0-9_]+(?:i|i8|i16|i32|i64))\\b"},{token:"constant.numeric.binary.source.rust",regex:"\\b(?:0b[01_]+|0b[01_]+(?:u|u8|u16|u32|u64)|0b[01_]+(?:i|i8|i16|i32|i64))\\b"},{token:"constant.numeric.float.source.rust",regex:"[0-9][0-9_]*(?:f32|f64|f)|[0-9][0-9_]*[eE][+-]=[0-9_]+|[0-9][0-9_]*[eE][+-]=[0-9_]+(?:f32|f64|f)|[0-9][0-9_]*\\.[0-9_]+|[0-9][0-9_]*\\.[0-9_]+(?:f32|f64|f)|[0-9][0-9_]*\\.[0-9_]+%[eE][+-]=[0-9_]+|[0-9][0-9_]*\\.[0-9_]+%[eE][+-]=[0-9_]+(?:f32|f64|f)"},{token:"comment.line.documentation.source.rust",regex:"//!.*$",push_:[{token:"comment.line.documentation.source.rust",regex:"$",next:"pop"},{defaultToken:"comment.line.documentation.source.rust"}]},{token:"comment.line.double-dash.source.rust",regex:"//.*$",push_:[{token:"comment.line.double-dash.source.rust",regex:"$",next:"pop"},{defaultToken:"comment.line.double-dash.source.rust"}]},{token:"comment.block.source.rust",regex:"/\\*",push:[{token:"comment.block.source.rust",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.source.rust"}]}],"#rust_escaped_character":[{token:"constant.character.escape.source.rust",regex:"\\\\(?:x[\\da-fA-F]{2}|[0-2][0-7]{,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)"}]},this.normalizeRules()};s.metaData={fileTypes:["rs","rc"],foldingStartMarker:"^.*\\bfn\\s*(\\w+\\s*)?\\([^\\)]*\\)(\\s*\\{[^\\}]*)?\\s*$",foldingStopMarker:"^\\s*\\}",name:"Rust",scopeName:"source.rust"},r.inherits(s,i),t.RustHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/rust",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/rust_highlight_rules","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./rust_highlight_rules").RustHighlightRules,o=e("./folding/cstyle").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="/\\*",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/rust"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-sass.js b/dist/assets/js/vendor/ace-nc/mode-sass.js
            new file mode 100644
            index 0000000000..91a991d6d5
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-sass.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/scss_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=i.arrayToMap(function(){var e="-webkit-|-moz-|-o-|-ms-|-svg-|-pie-|-khtml-".split("|"),t="appearance|background-clip|background-inline-policy|background-origin|background-size|binding|border-bottom-colors|border-left-colors|border-right-colors|border-top-colors|border-end|border-end-color|border-end-style|border-end-width|border-image|border-start|border-start-color|border-start-style|border-start-width|box-align|box-direction|box-flex|box-flexgroup|box-ordinal-group|box-orient|box-pack|box-sizing|column-count|column-gap|column-width|column-rule|column-rule-width|column-rule-style|column-rule-color|float-edge|font-feature-settings|font-language-override|force-broken-image-icon|image-region|margin-end|margin-start|opacity|outline|outline-color|outline-offset|outline-radius|outline-radius-bottomleft|outline-radius-bottomright|outline-radius-topleft|outline-radius-topright|outline-style|outline-width|padding-end|padding-start|stack-sizing|tab-size|text-blink|text-decoration-color|text-decoration-line|text-decoration-style|transform|transform-origin|transition|transition-delay|transition-duration|transition-property|transition-timing-function|user-focus|user-input|user-modify|user-select|window-shadow|border-radius".split("|"),n="azimuth|background-attachment|background-color|background-image|background-position|background-repeat|background|border-bottom-color|border-bottom-style|border-bottom-width|border-bottom|border-collapse|border-color|border-left-color|border-left-style|border-left-width|border-left|border-right-color|border-right-style|border-right-width|border-right|border-spacing|border-style|border-top-color|border-top-style|border-top-width|border-top|border-width|border|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|content|counter-increment|counter-reset|cue-after|cue-before|cue|cursor|direction|display|elevation|empty-cells|float|font-family|font-size-adjust|font-size|font-stretch|font-style|font-variant|font-weight|font|height|left|letter-spacing|line-height|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|marker-offset|margin|marks|max-height|max-width|min-height|min-width|opacity|orphans|outline-color|outline-style|outline-width|outline|overflow|overflow-x|overflow-y|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page|pause-after|pause-before|pause|pitch-range|pitch|play-during|position|quotes|richness|right|size|speak-header|speak-numeral|speak-punctuation|speech-rate|speak|stress|table-layout|text-align|text-decoration|text-indent|text-shadow|text-transform|top|unicode-bidi|vertical-align|visibility|voice-family|volume|white-space|widows|width|word-spacing|z-index".split("|"),r=[];for(var i=0,s=e.length;i<s;i++)Array.prototype.push.apply(r,(e[i]+t.join("|"+e[i])).split("|"));return Array.prototype.push.apply(r,t),Array.prototype.push.apply(r,n),r}()),t=i.arrayToMap("hsl|hsla|rgb|rgba|url|attr|counter|counters|abs|adjust_color|adjust_hue|alpha|join|blue|ceil|change_color|comparable|complement|darken|desaturate|floor|grayscale|green|hue|if|invert|join|length|lighten|lightness|mix|nth|opacify|opacity|percentage|quote|red|round|saturate|saturation|scale_color|transparentize|type_of|unit|unitless|unqoute".split("|")),n=i.arrayToMap("absolute|all-scroll|always|armenian|auto|baseline|below|bidi-override|block|bold|bolder|border-box|both|bottom|break-all|break-word|capitalize|center|char|circle|cjk-ideographic|col-resize|collapse|content-box|crosshair|dashed|decimal-leading-zero|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fixed|georgian|groove|hand|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|katakana-iroha|katakana|keep-all|left|lighter|line-edge|line-through|line|list-item|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|outset|outside|overline|pointer|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|super|sw-resize|table-footer-group|table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|zero".split("|")),r=i.arrayToMap("aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow".split("|")),s=i.arrayToMap("@mixin|@extend|@include|@import|@media|@debug|@warn|@if|@for|@each|@while|@else|@font-face|@-webkit-keyframes|if|and|!default|module|def|end|declare".split("|")),o=i.arrayToMap("a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdo|big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|keygen|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|source|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|u|ul|var|video|wbr|xmp".split("|")),u="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:u+"(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)"},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:"constant.numeric",regex:u},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:function(i){return e.hasOwnProperty(i.toLowerCase())?"support.type":s.hasOwnProperty(i)?"keyword":n.hasOwnProperty(i)?"constant.language":t.hasOwnProperty(i)?"support.function":r.hasOwnProperty(i.toLowerCase())?"support.constant.color":o.hasOwnProperty(i.toLowerCase())?"variable.language":"text"},regex:"\\-?[@a-z_][@a-z0-9_\\-]*"},{token:"variable",regex:"[a-z_\\-$][a-z0-9_\\-$]*\\b"},{token:"variable.language",regex:"#[a-z0-9-_]+"},{token:"variable.language",regex:"\\.[a-z0-9-_]+"},{token:"variable.language",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{token:"keyword.operator",regex:"<|>|<=|>=|==|!=|-|%|#|\\+|\\$|\\+|\\*"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]}};r.inherits(o,s),t.ScssHighlightRules=o}),ace.define("ace/mode/sass_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/scss_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./scss_highlight_rules").ScssHighlightRules,o=function(){s.call(this);var e=this.$rules.start;e[1].token=="comment"&&(e.splice(1,1,{onMatch:function(e,t,n){return n.unshift(this.next,-1,e.length-2,t),"comment"},regex:/^\s*\/\*/,next:"comment"},{token:"error.invalid",regex:"/\\*|[{;}]"},{token:"support.type",regex:/^\s*:[\w\-]+\s/}),this.$rules.comment=[{regex:/^\s*/,onMatch:function(e,t,n){return n[1]===-1&&(n[1]=Math.max(n[2],e.length-1)),e.length<=n[1]?(n.shift(),n.shift(),n.shift(),this.next=n.shift(),"text"):(this.next="","comment")},next:"start"},{defaultToken:"comment"}])};r.inherits(o,s),t.SassHighlightRules=o}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/sass",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sass_highlight_rules","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./sass_highlight_rules").SassHighlightRules,o=e("./folding/coffee").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="//",this.$id="ace/mode/sass"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-scad.js b/dist/assets/js/vendor/ace-nc/mode-scad.js
            new file mode 100644
            index 0000000000..6aa418a6d3
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-scad.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/scad_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./doc_comment_highlight_rules").DocCommentHighlightRules,o=e("./text_highlight_rules").TextHighlightRules,u=function(){var e=this.createKeywordMapper({"variable.language":"this",keyword:"module|if|else|for","constant.language":"NULL"},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},s.getStartRule("start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant",regex:"<[a-zA-Z0-9.]+>"},{token:"keyword",regex:"(?:use|include)"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|==|=|!=|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]},this.embedRules(s,"doc-",[s.getEndRule("start")])};r.inherits(u,o),t.scadHighlightRules=u}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/scad",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/scad_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./scad_highlight_rules").scadHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/scad"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-scala.js b/dist/assets/js/vendor/ace-nc/mode-scala.js
            new file mode 100644
            index 0000000000..572e606635
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-scala.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/scala_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="case|default|do|else|for|if|match|while|throw|return|try|catch|finally|yield|abstract|class|def|extends|final|forSome|implicit|implicits|import|lazy|new|object|override|package|private|protected|sealed|super|this|trait|type|val|var|with",t="true|false",n="AbstractMethodError|AssertionError|ClassCircularityError|ClassFormatError|Deprecated|EnumConstantNotPresentException|ExceptionInInitializerError|IllegalAccessError|IllegalThreadStateException|InstantiationError|InternalError|NegativeArraySizeException|NoSuchFieldError|Override|Process|ProcessBuilder|SecurityManager|StringIndexOutOfBoundsException|SuppressWarnings|TypeNotPresentException|UnknownError|UnsatisfiedLinkError|UnsupportedClassVersionError|VerifyError|InstantiationException|IndexOutOfBoundsException|ArrayIndexOutOfBoundsException|CloneNotSupportedException|NoSuchFieldException|IllegalArgumentException|NumberFormatException|SecurityException|Void|InheritableThreadLocal|IllegalStateException|InterruptedException|NoSuchMethodException|IllegalAccessException|UnsupportedOperationException|Enum|StrictMath|Package|Compiler|Readable|Runtime|StringBuilder|Math|IncompatibleClassChangeError|NoSuchMethodError|ThreadLocal|RuntimePermission|ArithmeticException|NullPointerException|Long|Integer|Short|Byte|Double|Number|Float|Character|Boolean|StackTraceElement|Appendable|StringBuffer|Iterable|ThreadGroup|Runnable|Thread|IllegalMonitorStateException|StackOverflowError|OutOfMemoryError|VirtualMachineError|ArrayStoreException|ClassCastException|LinkageError|NoClassDefFoundError|ClassNotFoundException|RuntimeException|Exception|ThreadDeath|Error|Throwable|System|ClassLoader|Cloneable|Class|CharSequence|Comparable|String|Object|Unit|Any|AnyVal|AnyRef|Null|ScalaObject|Singleton|Seq|Iterable|List|Option|Array|Char|Byte|Short|Int|Long|Nothing",r=this.createKeywordMapper({"variable.language":"this",keyword:e,"support.function":n,"constant.language":t},"identifier");this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'"""',next:"tstring"},{token:"string",regex:'"(?=.)',next:"string"},{token:"symbol.constant",regex:"'[\\w\\d_]+"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(?:in|instanceof|new|delete|typeof|void)"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],string:[{token:"escape",regex:'\\\\"'},{token:"string",regex:'"',next:"start"},{token:"string.invalid",regex:'[^"\\\\]*$',next:"start"},{token:"string",regex:'[^"\\\\]+'}],tstring:[{token:"string",regex:'"{3,5}',next:"start"},{token:"string",regex:".+?"}]},this.embedRules(i,"doc-",[i.getEndRule("start")])};r.inherits(o,s),t.ScalaHighlightRules=o}),ace.define("ace/mode/scala",["require","exports","module","ace/lib/oop","ace/mode/javascript","ace/mode/scala_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript").Mode,s=e("./scala_highlight_rules").ScalaHighlightRules,o=function(){i.call(this),this.HighlightRules=s};r.inherits(o,i),function(){this.createWorker=function(e){return null},this.$id="ace/mode/scala"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-scheme.js b/dist/assets/js/vendor/ace-nc/mode-scheme.js
            new file mode 100644
            index 0000000000..be482560de
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-scheme.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/scheme_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="case|do|let|loop|if|else|when",t="eq?|eqv?|equal?|and|or|not|null?",n="#t|#f",r="cons|car|cdr|cond|lambda|lambda*|syntax-rules|format|set!|quote|eval|append|list|list?|member?|load",i=this.createKeywordMapper({"keyword.control":e,"keyword.operator":t,"constant.language":n,"support.function":r},"identifier",!0);this.$rules={start:[{token:"comment",regex:";.*$"},{token:["storage.type.function-type.scheme","text","entity.name.function.scheme"],regex:"(?:\\b(?:(define|define-syntax|define-macro))\\b)(\\s+)((?:\\w|\\-|\\!|\\?)*)"},{token:"punctuation.definition.constant.character.scheme",regex:"#:\\S+"},{token:["punctuation.definition.variable.scheme","variable.other.global.scheme","punctuation.definition.variable.scheme"],regex:"(\\*)(\\S*)(\\*)"},{token:"constant.numeric",regex:"#[xXoObB][0-9a-fA-F]+"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?"},{token:i,regex:"[a-zA-Z_#][a-zA-Z0-9_\\-\\?\\!\\*]*"},{token:"string",regex:'"(?=.)',next:"qqstring"}],qqstring:[{token:"constant.character.escape.scheme",regex:"\\\\."},{token:"string",regex:'[^"\\\\]+',merge:!0},{token:"string",regex:"\\\\$",next:"qqstring",merge:!0},{token:"string",regex:'"|$',next:"start",merge:!0}]}};r.inherits(s,i),t.SchemeHighlightRules=s}),ace.define("ace/mode/scheme",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/scheme_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./scheme_highlight_rules").SchemeHighlightRules,o=function(){this.HighlightRules=s};r.inherits(o,i),function(){this.lineCommentStart=";",this.$id="ace/mode/scheme"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-scss.js b/dist/assets/js/vendor/ace-nc/mode-scss.js
            new file mode 100644
            index 0000000000..6f9bab866f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-scss.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/scss_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=i.arrayToMap(function(){var e="-webkit-|-moz-|-o-|-ms-|-svg-|-pie-|-khtml-".split("|"),t="appearance|background-clip|background-inline-policy|background-origin|background-size|binding|border-bottom-colors|border-left-colors|border-right-colors|border-top-colors|border-end|border-end-color|border-end-style|border-end-width|border-image|border-start|border-start-color|border-start-style|border-start-width|box-align|box-direction|box-flex|box-flexgroup|box-ordinal-group|box-orient|box-pack|box-sizing|column-count|column-gap|column-width|column-rule|column-rule-width|column-rule-style|column-rule-color|float-edge|font-feature-settings|font-language-override|force-broken-image-icon|image-region|margin-end|margin-start|opacity|outline|outline-color|outline-offset|outline-radius|outline-radius-bottomleft|outline-radius-bottomright|outline-radius-topleft|outline-radius-topright|outline-style|outline-width|padding-end|padding-start|stack-sizing|tab-size|text-blink|text-decoration-color|text-decoration-line|text-decoration-style|transform|transform-origin|transition|transition-delay|transition-duration|transition-property|transition-timing-function|user-focus|user-input|user-modify|user-select|window-shadow|border-radius".split("|"),n="azimuth|background-attachment|background-color|background-image|background-position|background-repeat|background|border-bottom-color|border-bottom-style|border-bottom-width|border-bottom|border-collapse|border-color|border-left-color|border-left-style|border-left-width|border-left|border-right-color|border-right-style|border-right-width|border-right|border-spacing|border-style|border-top-color|border-top-style|border-top-width|border-top|border-width|border|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|content|counter-increment|counter-reset|cue-after|cue-before|cue|cursor|direction|display|elevation|empty-cells|float|font-family|font-size-adjust|font-size|font-stretch|font-style|font-variant|font-weight|font|height|left|letter-spacing|line-height|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|marker-offset|margin|marks|max-height|max-width|min-height|min-width|opacity|orphans|outline-color|outline-style|outline-width|outline|overflow|overflow-x|overflow-y|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page|pause-after|pause-before|pause|pitch-range|pitch|play-during|position|quotes|richness|right|size|speak-header|speak-numeral|speak-punctuation|speech-rate|speak|stress|table-layout|text-align|text-decoration|text-indent|text-shadow|text-transform|top|unicode-bidi|vertical-align|visibility|voice-family|volume|white-space|widows|width|word-spacing|z-index".split("|"),r=[];for(var i=0,s=e.length;i<s;i++)Array.prototype.push.apply(r,(e[i]+t.join("|"+e[i])).split("|"));return Array.prototype.push.apply(r,t),Array.prototype.push.apply(r,n),r}()),t=i.arrayToMap("hsl|hsla|rgb|rgba|url|attr|counter|counters|abs|adjust_color|adjust_hue|alpha|join|blue|ceil|change_color|comparable|complement|darken|desaturate|floor|grayscale|green|hue|if|invert|join|length|lighten|lightness|mix|nth|opacify|opacity|percentage|quote|red|round|saturate|saturation|scale_color|transparentize|type_of|unit|unitless|unqoute".split("|")),n=i.arrayToMap("absolute|all-scroll|always|armenian|auto|baseline|below|bidi-override|block|bold|bolder|border-box|both|bottom|break-all|break-word|capitalize|center|char|circle|cjk-ideographic|col-resize|collapse|content-box|crosshair|dashed|decimal-leading-zero|decimal|default|disabled|disc|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ellipsis|fixed|georgian|groove|hand|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|inactive|inherit|inline-block|inline|inset|inside|inter-ideograph|inter-word|italic|justify|katakana-iroha|katakana|keep-all|left|lighter|line-edge|line-through|line|list-item|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|nw-resize|none|normal|not-allowed|nowrap|oblique|outset|outside|overline|pointer|progress|relative|repeat-x|repeat-y|repeat|right|ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|solid|square|static|strict|super|sw-resize|table-footer-group|table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|zero".split("|")),r=i.arrayToMap("aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow".split("|")),s=i.arrayToMap("@mixin|@extend|@include|@import|@media|@debug|@warn|@if|@for|@each|@while|@else|@font-face|@-webkit-keyframes|if|and|!default|module|def|end|declare".split("|")),o=i.arrayToMap("a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdo|big|blockquote|body|br|button|canvas|caption|center|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|dir|div|dl|dt|em|embed|fieldset|figcaption|figure|font|footer|form|frame|frameset|h1|h2|h3|h4|h5|h6|head|header|hgroup|hr|html|i|iframe|img|input|ins|keygen|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|s|samp|script|section|select|small|source|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|u|ul|var|video|wbr|xmp".split("|")),u="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))";this.$rules={start:[{token:"comment",regex:"\\/\\/.*$"},{token:"comment",regex:"\\/\\*",next:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'["].*\\\\$',next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"string",regex:"['].*\\\\$",next:"qstring"},{token:"constant.numeric",regex:u+"(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)"},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:"constant.numeric",regex:u},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:function(i){return e.hasOwnProperty(i.toLowerCase())?"support.type":s.hasOwnProperty(i)?"keyword":n.hasOwnProperty(i)?"constant.language":t.hasOwnProperty(i)?"support.function":r.hasOwnProperty(i.toLowerCase())?"support.constant.color":o.hasOwnProperty(i.toLowerCase())?"variable.language":"text"},regex:"\\-?[@a-z_][@a-z0-9_\\-]*"},{token:"variable",regex:"[a-z_\\-$][a-z0-9_\\-$]*\\b"},{token:"variable.language",regex:"#[a-z0-9-_]+"},{token:"variable.language",regex:"\\.[a-z0-9-_]+"},{token:"variable.language",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{token:"keyword.operator",regex:"<|>|<=|>=|==|!=|-|%|#|\\+|\\$|\\+|\\*"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"',next:"start"},{token:"string",regex:".+"}],qstring:[{token:"string",regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'",next:"start"},{token:"string",regex:".+"}]}};r.inherits(o,s),t.ScssHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/scss",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/scss_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./scss_highlight_rules").ScssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/css").CssBehaviour,a=e("./folding/cstyle").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/scss"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-sh.js b/dist/assets/js/vendor/ace-nc/mode-sh.js
            new file mode 100644
            index 0000000000..1e17e4e04e
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-sh.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/sh_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=t.reservedKeywords="!|{|}|case|do|done|elif|else|esac|fi|for|if|in|then|until|while|&|;|export|local|read|typeset|unset|elif|select|set",o=t.languageConstructs="[|]|alias|bg|bind|break|builtin|cd|command|compgen|complete|continue|dirs|disown|echo|enable|eval|exec|exit|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|popd|printf|pushd|pwd|return|set|shift|shopt|source|suspend|test|times|trap|type|ulimit|umask|unalias|wait",u=function(){var e=this.createKeywordMapper({keyword:s,"support.function.builtin":o,"invalid.deprecated":"debugger"},"identifier"),t="(?:(?:[1-9]\\d*)|(?:0))",n="(?:\\.\\d+)",r="(?:\\d+)",i="(?:(?:"+r+"?"+n+")|(?:"+r+"\\.))",u="(?:(?:"+i+"|"+r+")"+")",a="(?:"+u+"|"+i+")",f="(?:&"+r+")",l="[a-zA-Z_][a-zA-Z0-9_]*",c="(?:(?:\\$"+l+")|(?:"+l+"=))",h="(?:\\$(?:SHLVL|\\$|\\!|\\?))",p="(?:"+l+"\\s*\\(\\))";this.$rules={start:[{token:"constant",regex:/\\./},{token:["text","comment"],regex:/(^|\s)(#.*)$/},{token:"string",regex:'"',push:[{token:"constant.language.escape",regex:/\\(?:[$abeEfnrtv\\'"]|x[a-fA-F\d]{1,2}|u[a-fA-F\d]{4}([a-fA-F\d]{4})?|c.|\d{1,3})/},{token:"constant",regex:/\$\w+/},{token:"string",regex:'"',next:"pop"},{defaultToken:"string"}]},{token:"variable.language",regex:h},{token:"variable",regex:c},{token:"support.function",regex:p},{token:"support.function",regex:f},{token:"string",start:"'",end:"'"},{token:"constant.numeric",regex:a},{token:"constant.numeric",regex:t+"\\b"},{token:e,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\*|\\*\\*|\\/|\\/\\/|~|<|>|<=|=>|=|!="},{token:"paren.lparen",regex:"[\\[\\(\\{]"},{token:"paren.rparen",regex:"[\\]\\)\\}]"}]},this.normalizeRules()};r.inherits(u,i),t.ShHighlightRules=u}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/sh",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sh_highlight_rules","ace/range","ace/mode/folding/cstyle","ace/mode/behaviour/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./sh_highlight_rules").ShHighlightRules,o=e("../range").Range,u=e("./folding/cstyle").FoldMode,a=e("./behaviour/cstyle").CstyleBehaviour,f=function(){this.HighlightRules=s,this.foldingRules=new u,this.$behaviour=new a};r.inherits(f,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[\:]\s*$/);o&&(r+=n)}return r};var e={pass:1,"return":1,raise:1,"break":1,"continue":1};this.checkOutdent=function(t,n,r){if(r!=="\r\n"&&r!=="\r"&&r!=="\n")return!1;var i=this.getTokenizer().getLineTokens(n.trim(),t).tokens;if(!i)return!1;do var s=i.pop();while(s&&(s.type=="comment"||s.type=="text"&&s.value.match(/^\s+$/)));return s?s.type=="keyword"&&e[s.value]:!1},this.autoOutdent=function(e,t,n){n+=1;var r=this.$getIndent(t.getLine(n)),i=t.getTabString();r.slice(-i.length)==i&&t.remove(new o(n,r.length-i.length,n,r.length))},this.$id="ace/mode/sh"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-sjs.js b/dist/assets/js/vendor/ace-nc/mode-sjs.js
            new file mode 100644
            index 0000000000..1a7d275670
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-sjs.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/sjs_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/javascript_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=new i,t="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)",n=function(e){return e.isContextAware=!0,e},r=function(e){return{token:e.token,regex:e.regex,next:n(function(t,n){return n.length===0&&n.unshift(t),n.unshift(e.next),e.next})}},s=function(e){return{token:e.token,regex:e.regex,next:n(function(e,t){return t.shift(),t[0]||"start"})}};this.$rules=e.$rules,this.$rules.no_regex=[{token:"keyword",regex:"(waitfor|or|and|collapse|spawn|retract)\\b"},{token:"keyword.operator",regex:"(->|=>|\\.\\.)"},{token:"variable.language",regex:"(hold|default)\\b"},r({token:"string",regex:"`",next:"bstring"}),r({token:"string",regex:'"',next:"qqstring"}),r({token:"string",regex:'"',next:"qqstring"}),{token:["paren.lparen","text","paren.rparen"],regex:"(\\{)(\\s*)(\\|)",next:"block_arguments"}].concat(this.$rules.no_regex),this.$rules.block_arguments=[{token:"paren.rparen",regex:"\\|",next:"no_regex"}].concat(this.$rules.function_arguments),this.$rules.bstring=[{token:"constant.language.escape",regex:t},{token:"string",regex:"\\\\$",next:"bstring"},r({token:"paren.lparen",regex:"\\$\\{",next:"string_interp"}),r({token:"paren.lparen",regex:"\\$",next:"bstring_interp_single"}),s({token:"string",regex:"`"}),{defaultToken:"string"}],this.$rules.qqstring=[{token:"constant.language.escape",regex:t},{token:"string",regex:"\\\\$",next:"qqstring"},r({token:"paren.lparen",regex:"#\\{",next:"string_interp"}),s({token:"string",regex:'"'}),{defaultToken:"string"}];var o=[];for(var u=0;u<this.$rules.no_regex.length;u++){var a=this.$rules.no_regex[u],f=String(a.token);f.indexOf("paren")==-1&&(!a.next||a.next.isContextAware)&&o.push(a)}this.$rules.string_interp=[s({token:"paren.rparen",regex:"\\}"}),r({token:"paren.lparen",regex:"{",next:"string_interp"})].concat(o),this.$rules.bstring_interp_single=[{token:["identifier","paren.lparen"],regex:"(\\w+)(\\()",next:"bstring_interp_single_call"},s({token:"identifier",regex:"\\w*"})],this.$rules.bstring_interp_single_call=[r({token:"paren.lparen",regex:"\\(",next:"bstring_interp_single_call"}),s({token:"paren.rparen",regex:"\\)"})].concat(o)};r.inherits(o,s),t.SJSHighlightRules=o}),ace.define("ace/mode/sjs",["require","exports","module","ace/lib/oop","ace/mode/javascript","ace/mode/sjs_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript").Mode,s=e("./sjs_highlight_rules").SJSHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./behaviour/cstyle").CstyleBehaviour,a=e("./folding/cstyle").FoldMode,f=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,i),function(){this.createWorker=function(e){return null},this.$id="ace/mode/sjs"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-smarty.js b/dist/assets/js/vendor/ace-nc/mode-smarty.js
            new file mode 100644
            index 0000000000..16ca6ea012
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-smarty.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/smarty_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=function(){i.call(this);var e={start:[{include:"#comments"},{include:"#blocks"}],"#blocks":[{token:"punctuation.section.embedded.begin.smarty",regex:"\\{%?",push:[{token:"punctuation.section.embedded.end.smarty",regex:"%?\\}",next:"pop"},{include:"#strings"},{include:"#variables"},{include:"#lang"},{defaultToken:"source.smarty"}]}],"#comments":[{token:["punctuation.definition.comment.smarty","comment.block.smarty"],regex:"(\\{%?)(\\*)",push:[{token:"comment.block.smarty",regex:"\\*%?\\}",next:"pop"},{defaultToken:"comment.block.smarty"}]}],"#lang":[{token:"keyword.operator.smarty",regex:"(?:!=|!|<=|>=|<|>|===|==|%|&&|\\|\\|)|\\b(?:and|or|eq|neq|ne|gte|gt|ge|lte|lt|le|not|mod)\\b"},{token:"constant.language.smarty",regex:"\\b(?:TRUE|FALSE|true|false)\\b"},{token:"keyword.control.smarty",regex:"\\b(?:if|else|elseif|foreach|foreachelse|section|switch|case|break|default)\\b"},{token:"variable.parameter.smarty",regex:"\\b[a-zA-Z]+="},{token:"support.function.built-in.smarty",regex:"\\b(?:capture|config_load|counter|cycle|debug|eval|fetch|include_php|include|insert|literal|math|strip|rdelim|ldelim|assign|constant|block|html_[a-z_]*)\\b"},{token:"support.function.variable-modifier.smarty",regex:"\\|(?:capitalize|cat|count_characters|count_paragraphs|count_sentences|count_words|date_format|default|escape|indent|lower|nl2br|regex_replace|replace|spacify|string_format|strip_tags|strip|truncate|upper|wordwrap)"}],"#strings":[{token:"punctuation.definition.string.begin.smarty",regex:"'",push:[{token:"punctuation.definition.string.end.smarty",regex:"'",next:"pop"},{token:"constant.character.escape.smarty",regex:"\\\\."},{defaultToken:"string.quoted.single.smarty"}]},{token:"punctuation.definition.string.begin.smarty",regex:'"',push:[{token:"punctuation.definition.string.end.smarty",regex:'"',next:"pop"},{token:"constant.character.escape.smarty",regex:"\\\\."},{defaultToken:"string.quoted.double.smarty"}]}],"#variables":[{token:["punctuation.definition.variable.smarty","variable.other.global.smarty"],regex:"\\b(\\$)(Smarty\\.)"},{token:["punctuation.definition.variable.smarty","variable.other.smarty"],regex:"(\\$)([a-zA-Z_][a-zA-Z0-9_]*)\\b"},{token:["keyword.operator.smarty","variable.other.property.smarty"],regex:"(->)([a-zA-Z_][a-zA-Z0-9_]*)\\b"},{token:["keyword.operator.smarty","meta.function-call.object.smarty","punctuation.definition.variable.smarty","variable.other.smarty","punctuation.definition.variable.smarty"],regex:"(->)([a-zA-Z_][a-zA-Z0-9_]*)(\\()(.*?)(\\))"}]},t=e.start;for(var n in this.$rules)this.$rules[n].unshift.apply(this.$rules[n],t);Object.keys(e).forEach(function(t){this.$rules[t]||(this.$rules[t]=e[t])},this),this.normalizeRules()};s.metaData={fileTypes:["tpl"],foldingStartMarker:"\\{%?",foldingStopMarker:"%?\\}",name:"Smarty",scopeName:"text.html.smarty"},r.inherits(s,i),t.SmartyHighlightRules=s}),ace.define("ace/mode/smarty",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/smarty_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html").Mode,s=e("./smarty_highlight_rules").SmartyHighlightRules,o=function(){i.call(this),this.HighlightRules=s};r.inherits(o,i),function(){this.$id="ace/mode/smarty"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-snippets.js b/dist/assets/js/vendor/ace-nc/mode-snippets.js
            new file mode 100644
            index 0000000000..f066672e9c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-snippets.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/snippets",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e="SELECTION|CURRENT_WORD|SELECTED_TEXT|CURRENT_LINE|LINE_INDEX|LINE_NUMBER|SOFT_TABS|TAB_SIZE|FILENAME|FILEPATH|FULLNAME";this.$rules={start:[{token:"constant.language.escape",regex:/\\[\$}`\\]/},{token:"keyword",regex:"\\$(?:TM_)?(?:"+e+")\\b"},{token:"variable",regex:"\\$\\w+"},{onMatch:function(e,t,n){return n[1]?n[1]++:n.unshift(t,1),this.tokenName},tokenName:"markup.list",regex:"\\${",next:"varDecl"},{onMatch:function(e,t,n){return n[1]?(n[1]--,n[1]||n.splice(0,2),this.tokenName):"text"},tokenName:"markup.list",regex:"}"},{token:"doc.comment",regex:/^\${2}-{5,}$/}],varDecl:[{regex:/\d+\b/,token:"constant.numeric"},{token:"keyword",regex:"(?:TM_)?(?:"+e+")\\b"},{token:"variable",regex:"\\w+"},{regex:/:/,token:"punctuation.operator",next:"start"},{regex:/\//,token:"string.regex",next:"regexp"},{regex:"",next:"start"}],regexp:[{regex:/\\./,token:"escape"},{regex:/\[/,token:"regex.start",next:"charClass"},{regex:"/",token:"string.regex",next:"format"},{token:"string.regex",regex:"."}],charClass:[{regex:"\\.",token:"escape"},{regex:"\\]",token:"regex.end",next:"regexp"},{token:"string.regex",regex:"."}],format:[{regex:/\\[ulULE]/,token:"keyword"},{regex:/\$\d+/,token:"variable"},{regex:"/[gim]*:?",token:"string.regex",next:"start"},{token:"string",regex:"."}]}};r.inherits(o,s),t.SnippetHighlightRules=o;var u=function(){this.$rules={start:[{token:"text",regex:"^\\t",next:"sn-start"},{token:"invalid",regex:/^ \s*/},{token:"comment",regex:/^#.*/},{token:"constant.language.escape",regex:"^regex ",next:"regex"},{token:"constant.language.escape",regex:"^(trigger|endTrigger|name|snippet|guard|endGuard|tabTrigger|key)\\b"}],regex:[{token:"text",regex:"\\."},{token:"keyword",regex:"/"},{token:"empty",regex:"$",next:"start"}]},this.embedRules(o,"sn-",[{token:"text",regex:"^\\t",next:"sn-start"},{onMatch:function(e,t,n){return n.splice(n.length),this.tokenName},tokenName:"text",regex:"^(?!	)",next:"start"}])};r.inherits(u,s),t.SnippetGroupHighlightRules=u;var a=e("./folding/coffee").FoldMode,f=function(){this.HighlightRules=u,this.foldingRules=new a};r.inherits(f,i),function(){this.$indentWithTabs=!0,this.$id="ace/mode/snippets"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-soy_template.js b/dist/assets/js/vendor/ace-nc/mode-soy_template.js
            new file mode 100644
            index 0000000000..5b1f734805
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-soy_template.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/soy_template_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html_highlight_rules").HtmlHighlightRules,s=function(){i.call(this);var e={start:[{include:"#template"},{include:"#if"},{include:"#comment-line"},{include:"#comment-block"},{include:"#comment-doc"},{include:"#call"},{include:"#css"},{include:"#param"},{include:"#print"},{include:"#msg"},{include:"#for"},{include:"#foreach"},{include:"#switch"},{include:"#tag"},{include:"text.html.basic"}],"#call":[{token:["punctuation.definition.tag.begin.soy","meta.tag.call.soy"],regex:"(\\{/?)(\\s*)(?=call|delcall)",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{include:"#string-quoted-single"},{include:"#string-quoted-double"},{token:["entity.name.tag.soy","variable.parameter.soy"],regex:"(call|delcall)(\\s+[\\.\\w]+)"},{token:["entity.other.attribute-name.soy","text","keyword.operator.soy"],regex:"\\b(data)(\\s*)(=)"},{defaultToken:"meta.tag.call.soy"}]}],"#comment-line":[{token:["comment.line.double-slash.soy","punctuation.definition.comment.soy","comment.line.double-slash.soy"],regex:"(\\s+)(//)(.*$)"}],"#comment-block":[{token:"punctuation.definition.comment.begin.soy",regex:"/\\*(?!\\*)",push:[{token:"punctuation.definition.comment.end.soy",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.soy"}]}],"#comment-doc":[{token:"punctuation.definition.comment.begin.soy",regex:"/\\*\\*(?!/)",push:[{token:"punctuation.definition.comment.end.soy",regex:"\\*/",next:"pop"},{token:["support.type.soy","text","variable.parameter.soy"],regex:"(@param|@param\\?)(\\s+)(\\w+)"},{defaultToken:"comment.block.documentation.soy"}]}],"#css":[{token:["punctuation.definition.tag.begin.soy","meta.tag.css.soy","entity.name.tag.soy"],regex:"(\\{/?)(\\s*)(css)\\b",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{token:"support.constant.soy",regex:"\\b(?:LITERAL|REFERENCE|BACKEND_SPECIFIC|GOOG)\\b"},{defaultToken:"meta.tag.css.soy"}]}],"#for":[{token:["punctuation.definition.tag.begin.soy","meta.tag.for.soy","entity.name.tag.soy"],regex:"(\\{/?)(\\s*)(for)\\b",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{token:"keyword.operator.soy",regex:"\\bin\\b"},{token:"support.function.soy",regex:"\\brange\\b"},{include:"#variable"},{include:"#number"},{include:"#primitive"},{defaultToken:"meta.tag.for.soy"}]}],"#foreach":[{token:["punctuation.definition.tag.begin.soy","meta.tag.foreach.soy","entity.name.tag.soy"],regex:"(\\{/?)(\\s*)(foreach)\\b",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{token:"keyword.operator.soy",regex:"\\bin\\b"},{include:"#variable"},{defaultToken:"meta.tag.foreach.soy"}]}],"#function":[{token:"support.function.soy",regex:"\\b(?:isFirst|isLast|index|hasData|length|keys|round|floor|ceiling|min|max|randomInt)\\b"}],"#if":[{token:["punctuation.definition.tag.begin.soy","meta.tag.if.soy","entity.name.tag.soy"],regex:"(\\{/?)(\\s*)(if|elseif)\\b",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{include:"#variable"},{include:"#operator"},{include:"#function"},{include:"#string-quoted-single"},{include:"#string-quoted-double"},{defaultToken:"meta.tag.if.soy"}]}],"#namespace":[{token:["entity.name.tag.soy","text","variable.parameter.soy"],regex:"(namespace|delpackage)(\\s+)([\\w\\.]+)"}],"#number":[{token:"constant.numeric",regex:"[\\d]+"}],"#operator":[{token:"keyword.operator.soy",regex:"==|!=|\\band\\b|\\bor\\b|\\bnot\\b|-|\\+|/|\\?:"}],"#param":[{token:["punctuation.definition.tag.begin.soy","meta.tag.param.soy","entity.name.tag.soy"],regex:"(\\{/?)(\\s*)(param)",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{include:"#variable"},{token:["entity.other.attribute-name.soy","text","keyword.operator.soy"],regex:"\\b([\\w]*)(\\s*)((?::)?)"},{defaultToken:"meta.tag.param.soy"}]}],"#primitive":[{token:"constant.language.soy",regex:"\\b(?:null|false|true)\\b"}],"#msg":[{token:["punctuation.definition.tag.begin.soy","meta.tag.msg.soy","entity.name.tag.soy"],regex:"(\\{/?)(\\s*)(msg)\\b",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{include:"#string-quoted-single"},{include:"#string-quoted-double"},{token:["entity.other.attribute-name.soy","text","keyword.operator.soy"],regex:"\\b(meaning|desc)(\\s*)(=)"},{defaultToken:"meta.tag.msg.soy"}]}],"#print":[{token:["punctuation.definition.tag.begin.soy","meta.tag.print.soy","entity.name.tag.soy"],regex:"(\\{/?)(\\s*)(print)\\b",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{include:"#variable"},{include:"#print-parameter"},{include:"#number"},{include:"#primitive"},{include:"#attribute-lookup"},{defaultToken:"meta.tag.print.soy"}]}],"#print-parameter":[{token:"keyword.operator.soy",regex:"\\|"},{token:"variable.parameter.soy",regex:"noAutoescape|id|escapeHtml|escapeJs|insertWorkBreaks|truncate"}],"#special-character":[{token:"support.constant.soy",regex:"\\bsp\\b|\\bnil\\b|\\\\r|\\\\n|\\\\t|\\blb\\b|\\brb\\b"}],"#string-quoted-double":[{token:"string.quoted.double",regex:'"[^"]*"'}],"#string-quoted-single":[{token:"string.quoted.single",regex:"'[^']*'"}],"#switch":[{token:["punctuation.definition.tag.begin.soy","meta.tag.switch.soy","entity.name.tag.soy"],regex:"(\\{/?)(\\s*)(switch|case)\\b",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{include:"#variable"},{include:"#function"},{include:"#number"},{include:"#string-quoted-single"},{include:"#string-quoted-double"},{defaultToken:"meta.tag.switch.soy"}]}],"#attribute-lookup":[{token:"punctuation.definition.attribute-lookup.begin.soy",regex:"\\[",push:[{token:"punctuation.definition.attribute-lookup.end.soy",regex:"\\]",next:"pop"},{include:"#variable"},{include:"#function"},{include:"#operator"},{include:"#number"},{include:"#primitive"},{include:"#string-quoted-single"},{include:"#string-quoted-double"}]}],"#tag":[{token:"punctuation.definition.tag.begin.soy",regex:"\\{",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{include:"#namespace"},{include:"#variable"},{include:"#special-character"},{include:"#tag-simple"},{include:"#function"},{include:"#operator"},{include:"#attribute-lookup"},{include:"#number"},{include:"#primitive"},{include:"#print-parameter"}]}],"#tag-simple":[{token:"entity.name.tag.soy",regex:"{{\\s*(?:literal|else|ifempty|default)\\s*(?=\\})"}],"#template":[{token:["punctuation.definition.tag.begin.soy","meta.tag.template.soy"],regex:"(\\{/?)(\\s*)(?=template|deltemplate)",push:[{token:"punctuation.definition.tag.end.soy",regex:"\\}",next:"pop"},{token:["entity.name.tag.soy","text","entity.name.function.soy"],regex:"(template|deltemplate)(\\s+)([\\.\\w]+)",originalRegex:"(?<=template|deltemplate)\\s+([\\.\\w]+)"},{token:["entity.other.attribute-name.soy","text","keyword.operator.soy","text","string.quoted.double.soy"],regex:'\\b(private)(\\s*)(=)(\\s*)("true"|"false")'},{token:["entity.other.attribute-name.soy","text","keyword.operator.soy","text","string.quoted.single.soy"],regex:"\\b(private)(\\s*)(=)(\\s*)('true'|'false')"},{token:["entity.other.attribute-name.soy","text","keyword.operator.soy","text","string.quoted.double.soy"],regex:'\\b(autoescape)(\\s*)(=)(\\s*)("true"|"false"|"contextual")'},{token:["entity.other.attribute-name.soy","text","keyword.operator.soy","text","string.quoted.single.soy"],regex:"\\b(autoescape)(\\s*)(=)(\\s*)('true'|'false'|'contextual')"},{defaultToken:"meta.tag.template.soy"}]}],"#variable":[{token:"variable.other.soy",regex:"\\$[\\w\\.]+"}]};for(var t in e)this.$rules[t]?this.$rules[t].unshift.call(this.$rules[t],e[t]):this.$rules[t]=e[t];this.normalizeRules()};s.metaData={comment:"SoyTemplate",fileTypes:["soy"],firstLineMatch:"\\{\\s*namespace\\b",foldingStartMarker:"\\{\\s*template\\s+[^\\}]*\\}",foldingStopMarker:"\\{\\s*/\\s*template\\s*\\}",name:"SoyTemplate",scopeName:"source.soy"},r.inherits(s,i),t.SoyTemplateHighlightRules=s}),ace.define("ace/mode/soy_template",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/soy_template_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html").Mode,s=e("./soy_template_highlight_rules").SoyTemplateHighlightRules,o=function(){i.call(this),this.HighlightRules=s};r.inherits(o,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/soy_template"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-space.js b/dist/assets/js/vendor/ace-nc/mode-space.js
            new file mode 100644
            index 0000000000..f13e8effe5
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-space.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/space_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"empty_line",regex:/ */,next:"key"},{token:"empty_line",regex:/$/,next:"key"}],key:[{token:"variable",regex:/\S+/},{token:"empty_line",regex:/$/,next:"start"},{token:"keyword.operator",regex:/ /,next:"value"}],value:[{token:"keyword.operator",regex:/$/,next:"start"},{token:"string",regex:/[^$]/}]}};r.inherits(s,i),t.SpaceHighlightRules=s}),ace.define("ace/mode/space",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/folding/coffee","ace/mode/space_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./folding/coffee").FoldMode,o=e("./space_highlight_rules").SpaceHighlightRules,u=function(){this.HighlightRules=o,this.foldingRules=new s};r.inherits(u,i),function(){this.$id="ace/mode/space"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-sql.js b/dist/assets/js/vendor/ace-nc/mode-sql.js
            new file mode 100644
            index 0000000000..c5e02e5a80
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-sql.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/sql_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="select|insert|update|delete|from|where|and|or|group|by|order|limit|offset|having|as|case|when|else|end|type|left|right|join|on|outer|desc|asc",t="true|false|null",n="count|min|max|avg|sum|rank|now|coalesce",r=this.createKeywordMapper({"support.function":n,keyword:e,"constant.language":t},"identifier",!0);this.$rules={start:[{token:"comment",regex:"--.*$"},{token:"comment",start:"/\\*",end:"\\*/"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]},this.normalizeRules()};r.inherits(s,i),t.SqlHighlightRules=s}),ace.define("ace/mode/sql",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/sql_highlight_rules","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./sql_highlight_rules").SqlHighlightRules,o=e("../range").Range,u=function(){this.HighlightRules=s};r.inherits(u,i),function(){this.lineCommentStart="--",this.$id="ace/mode/sql"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-stylus.js b/dist/assets/js/vendor/ace-nc/mode-stylus.js
            new file mode 100644
            index 0000000000..70a849bf00
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-stylus.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/stylus_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/css_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=e("./css_highlight_rules"),o=function(){var e=this.createKeywordMapper({"support.type":s.supportType,"support.function":s.supportFunction,"support.constant":s.supportConstant,"support.constant.color":s.supportConstantColor,"support.constant.fonts":s.supportConstantFonts},"text",!0);this.$rules={start:[{token:"comment",regex:/\/\/.*$/},{token:"comment",regex:/\/\*/,next:"comment"},{token:["entity.name.function.stylus","text"],regex:"^([-a-zA-Z_][-\\w]*)?(\\()"},{token:["entity.other.attribute-name.class.stylus"],regex:"\\.-?[_a-zA-Z]+[_a-zA-Z0-9-]*"},{token:["entity.language.stylus"],regex:"^ *&"},{token:["variable.language.stylus"],regex:"(arguments)"},{token:["keyword.stylus"],regex:"@[-\\w]+"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:s.pseudoElements},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:s.pseudoClasses},{token:["entity.name.tag.stylus"],regex:"(?:\\b)(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|datalist|dd|del|details|dfn|dialog|div|dl|dt|em|eventsource|fieldset|figure|figcaption|footer|form|frame|frameset|(?:h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|label|legend|li|link|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|samp|script|section|select|small|span|strike|strong|style|sub|summary|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)(?:\\b)"},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation.definition.entity.stylus","entity.other.attribute-name.id.stylus"],regex:"(#)([a-zA-Z][a-zA-Z0-9_-]*)"},{token:"meta.vendor-prefix.stylus",regex:"-webkit-|-moz\\-|-ms-|-o-"},{token:"keyword.control.stylus",regex:"(?:!important|for|in|return|true|false|null|if|else|unless|return)\\b"},{token:"keyword.operator.stylus",regex:"!|~|\\+|-|(?:\\*)?\\*|\\/|%|(?:\\.)\\.\\.|<|>|(?:=|:|\\?|\\+|-|\\*|\\/|%|<|>)?=|!="},{token:"keyword.operator.stylus",regex:"(?:in|is(?:nt)?|not)\\b"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:s.numRe},{token:"keyword",regex:"(?:ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)\\b"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"}],comment:[{token:"comment",regex:".*?\\*\\/",next:"start"},{token:"comment",regex:".+"}],qqstring:[{token:"string",regex:'[^"\\\\]+'},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"start"}],qstring:[{token:"string",regex:"[^'\\\\]+"},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"start"}]}};r.inherits(o,i),t.StylusHighlightRules=o}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/stylus",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/stylus_highlight_rules","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./stylus_highlight_rules").StylusHighlightRules,o=e("./folding/coffee").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.$id="ace/mode/stylus"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-svg.js b/dist/assets/js/vendor/ace-nc/mode-svg.js
            new file mode 100644
            index 0000000000..a51528e0e4
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-svg.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/xml_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/xml"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./xml_highlight_rules").XmlHighlightRules,u=e("./behaviour/xml").XmlBehaviour,a=e("./folding/xml").FoldMode,f=function(){this.HighlightRules=o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,s),function(){this.voidElements=i.arrayToMap([]),this.blockComment={start:"<!--",end:"-->"},this.$id="ace/mode/xml"}.call(f.prototype),t.Mode=f}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/svg_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=e("./xml_highlight_rules").XmlHighlightRules,o=function(){s.call(this),this.embedTagRules(i,"js-","script"),this.normalizeRules()};r.inherits(o,s),t.SvgHighlightRules=o}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/svg",["require","exports","module","ace/lib/oop","ace/mode/xml","ace/mode/javascript","ace/mode/svg_highlight_rules","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./xml").Mode,s=e("./javascript").Mode,o=e("./svg_highlight_rules").SvgHighlightRules,u=e("./folding/mixed").FoldMode,a=e("./folding/xml").FoldMode,f=e("./folding/cstyle").FoldMode,l=function(){i.call(this),this.HighlightRules=o,this.createModeDelegates({"js-":s}),this.foldingRules=new u(new a,{"js-":new f})};r.inherits(l,i),function(){this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.$id="ace/mode/svg"}.call(l.prototype),t.Mode=l})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-tcl.js b/dist/assets/js/vendor/ace-nc/mode-tcl.js
            new file mode 100644
            index 0000000000..d54aef2756
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-tcl.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/tcl_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment",regex:"#.*\\\\$",next:"commentfollow"},{token:"comment",regex:"#.*$"},{token:"support.function",regex:"[\\\\]$",next:"splitlineStart"},{token:"text",regex:'[\\\\](?:["]|[{]|[}]|[[]|[]]|[$]|[])'},{token:"text",regex:"^|[^{][;][^}]|[/\r/]",next:"commandItem"},{token:"string",regex:'[ ]*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:'[ ]*["]',next:"qqstring"},{token:"variable.instance",regex:"[$]",next:"variable"},{token:"support.function",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|{\\*}|;|::"},{token:"identifier",regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"paren.lparen",regex:"[[{]",next:"commandItem"},{token:"paren.lparen",regex:"[(]"},{token:"paren.rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}],commandItem:[{token:"comment",regex:"#.*\\\\$",next:"commentfollow"},{token:"comment",regex:"#.*$",next:"start"},{token:"string",regex:'[ ]*["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"variable.instance",regex:"[$]",next:"variable"},{token:"support.function",regex:"(?:[:][:])[a-zA-Z0-9_/]+(?:[:][:])",next:"commandItem"},{token:"support.function",regex:"[a-zA-Z0-9_/]+(?:[:][:])",next:"commandItem"},{token:"support.function",regex:"(?:[:][:])",next:"commandItem"},{token:"paren.rparen",regex:"[\\])}]"},{token:"support.function",regex:"!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|{\\*}|;|::"},{token:"keyword",regex:"[a-zA-Z0-9_/]+",next:"start"}],commentfollow:[{token:"comment",regex:".*\\\\$",next:"commentfollow"},{token:"comment",regex:".+",next:"start"}],splitlineStart:[{token:"text",regex:"^.",next:"start"}],variable:[{token:"variable.instance",regex:"[a-zA-Z_\\d]+(?:[(][a-zA-Z_\\d]+[)])?",next:"start"},{token:"variable.instance",regex:"{?[a-zA-Z_\\d]+}?",next:"start"}],qqstring:[{token:"string",regex:'(?:[^\\\\]|\\\\.)*?["]',next:"start"},{token:"string",regex:".+"}]}};r.inherits(s,i),t.TclHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/tcl",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/folding/cstyle","ace/mode/tcl_highlight_rules","ace/mode/matching_brace_outdent","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./folding/cstyle").FoldMode,o=e("./tcl_highlight_rules").TclHighlightRules,u=e("./matching_brace_outdent").MatchingBraceOutdent,a=e("../range").Range,f=function(){this.HighlightRules=o,this.$outdent=new u,this.foldingRules=new s};r.inherits(f,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var o=t.match(/^.*[\{\(\[]\s*$/);o&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/tcl"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-tex.js b/dist/assets/js/vendor/ace-nc/mode-tex.js
            new file mode 100644
            index 0000000000..37d98d4efd
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-tex.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/tex_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=function(e){e||(e="text"),this.$rules={start:[{token:"comment",regex:"%.*$"},{token:e,regex:"\\\\[$&%#\\{\\}]"},{token:"keyword",regex:"\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b",next:"nospell"},{token:"keyword",regex:"\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])}]"},{token:e,regex:"\\s+"}],nospell:[{token:"comment",regex:"%.*$",next:"start"},{token:"nospell."+e,regex:"\\\\[$&%#\\{\\}]"},{token:"keyword",regex:"\\\\(?:documentclass|usepackage|newcounter|setcounter|addtocounter|value|arabic|stepcounter|newenvironment|renewenvironment|ref|vref|eqref|pageref|label|cite[a-zA-Z]*|tag|begin|end|bibitem)\\b"},{token:"keyword",regex:"\\\\(?:[a-zA-z0-9]+|[^a-zA-z0-9])",next:"start"},{token:"paren.keyword.operator",regex:"[[({]"},{token:"paren.keyword.operator",regex:"[\\])]"},{token:"paren.keyword.operator",regex:"}",next:"start"},{token:"nospell."+e,regex:"\\s+"},{token:"nospell."+e,regex:"\\w+"}]}};r.inherits(o,s),t.TexHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/tex",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/tex_highlight_rules","ace/mode/matching_brace_outdent"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./text_highlight_rules").TextHighlightRules,o=e("./tex_highlight_rules").TexHighlightRules,u=e("./matching_brace_outdent").MatchingBraceOutdent,a=function(e){e?this.HighlightRules=s:this.HighlightRules=o,this.$outdent=new u};r.inherits(a,i),function(){this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.allowAutoInsert=function(){return!1},this.$id="ace/mode/tex"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-text.js b/dist/assets/js/vendor/ace-nc/mode-text.js
            new file mode 100644
            index 0000000000..e69de29bb2
            diff --git a/dist/assets/js/vendor/ace-nc/mode-textile.js b/dist/assets/js/vendor/ace-nc/mode-textile.js
            new file mode 100644
            index 0000000000..fc208f3800
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-textile.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/textile_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:function(e){return e.charAt(0)=="h"?"markup.heading."+e.charAt(1):"markup.heading"},regex:"h1|h2|h3|h4|h5|h6|bq|p|bc|pre",next:"blocktag"},{token:"keyword",regex:"[\\*]+|[#]+"},{token:"text",regex:".+"}],blocktag:[{token:"keyword",regex:"\\. ",next:"start"},{token:"keyword",regex:"\\(",next:"blocktagproperties"}],blocktagproperties:[{token:"keyword",regex:"\\)",next:"blocktag"},{token:"string",regex:"[a-zA-Z0-9\\-_]+"},{token:"keyword",regex:"#"}]}};r.inherits(s,i),t.TextileHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/textile",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/textile_highlight_rules","ace/mode/matching_brace_outdent"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./textile_highlight_rules").TextileHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=function(){this.HighlightRules=s,this.$outdent=new o};r.inherits(u,i),function(){this.getNextLineIndent=function(e,t,n){return e=="intag"?n:""},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/textile"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-toml.js b/dist/assets/js/vendor/ace-nc/mode-toml.js
            new file mode 100644
            index 0000000000..1028aa574e
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-toml.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/toml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e=this.createKeywordMapper({"constant.language.boolean":"true|false"},"identifier"),t="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b";this.$rules={start:[{token:"comment.toml",regex:/#.*$/},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:["variable.keygroup.toml"],regex:"(?:^\\s*)(\\[([^\\]]+)\\])"},{token:e,regex:t},{token:"support.date.toml",regex:"\\d{4}-\\d{2}-\\d{2}(T)\\d{2}:\\d{2}:\\d{2}(Z)"},{token:"constant.numeric.toml",regex:"-?\\d+(\\.?\\d+)?"}],qqstring:[{token:"string",regex:"\\\\$",next:"qqstring"},{token:"constant.language.escape",regex:'\\\\[0tnr"\\\\]'},{token:"string",regex:'"|$',next:"start"},{defaultToken:"string"}]}};r.inherits(s,i),t.TomlHighlightRules=s}),ace.define("ace/mode/folding/ini",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(){};r.inherits(o,s),function(){this.foldingStartMarker=/^\s*\[([^\])]*)]\s*(?:$|[;#])/,this.getFoldWidgetRange=function(e,t,n){var r=this.foldingStartMarker,s=e.getLine(n),o=s.match(r);if(!o)return;var u=o[1]+".",a=s.length,f=e.getLength(),l=n,c=n;while(++n<f){s=e.getLine(n);if(/^\s*$/.test(s))continue;o=s.match(r);if(o&&o[1].lastIndexOf(u,0)!==0)break;c=n}if(c>l){var h=e.getLine(c).length;return new i(l,a,c,h)}}}.call(o.prototype)}),ace.define("ace/mode/toml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/toml_highlight_rules","ace/mode/folding/ini"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./toml_highlight_rules").TomlHighlightRules,o=e("./folding/ini").FoldMode,u=function(){this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="#",this.$id="ace/mode/toml"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-twig.js b/dist/assets/js/vendor/ace-nc/mode-twig.js
            new file mode 100644
            index 0000000000..3f3687520d
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-twig.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/twig_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/html_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./html_highlight_rules").HtmlHighlightRules,o=e("./text_highlight_rules").TextHighlightRules,u=function(){s.call(this);var e="autoescape|block|do|embed|extends|filter|flush|for|from|if|import|include|macro|sandbox|set|spaceless|use|verbatim";e=e+"|end"+e.replace(/\|/g,"|end");var t="abs|batch|capitalize|convert_encoding|date|date_modify|default|e|escape|first|format|join|json_encode|keys|last|length|lower|merge|nl2br|number_format|raw|replace|reverse|slice|sort|split|striptags|title|trim|upper|url_encode",n="attribute|constant|cycle|date|dump|parent|random|range|template_from_string",r="constant|divisibleby|sameas|defined|empty|even|iterable|odd",i="null|none|true|false",o="b-and|b-xor|b-or|in|is|and|or|not",u=this.createKeywordMapper({"keyword.control.twig":e,"support.function.twig":[t,n,r].join("|"),"keyword.operator.twig":o,"constant.language.twig":i},"identifier");for(var a in this.$rules)this.$rules[a].unshift({token:"variable.other.readwrite.local.twig",regex:"\\{\\{-?",push:"twig-start"},{token:"meta.tag.twig",regex:"\\{%-?",push:"twig-start"},{token:"comment.block.twig",regex:"\\{#-?",push:"twig-comment"});this.$rules["twig-comment"]=[{token:"comment.block.twig",regex:".*-?#\\}",next:"pop"}],this.$rules["twig-start"]=[{token:"variable.other.readwrite.local.twig",regex:"-?\\}\\}",next:"pop"},{token:"meta.tag.twig",regex:"-?%\\}",next:"pop"},{token:"string",regex:"'",next:"twig-qstring"},{token:"string",regex:'"',next:"twig-qqstring"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:u,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator.assignment",regex:"=|~"},{token:"keyword.operator.comparison",regex:"==|!=|<|>|>=|<=|==="},{token:"keyword.operator.arithmetic",regex:"\\+|-|/|%|//|\\*|\\*\\*"},{token:"keyword.operator.other",regex:"\\.\\.|\\|"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./},{token:"paren.lparen",regex:/[\[\({]/},{token:"paren.rparen",regex:/[\])}]/},{token:"text",regex:"\\s+"}],this.$rules["twig-qqstring"]=[{token:"constant.language.escape",regex:/\\[\\"$#ntr]|#{[^"}]*}/},{token:"string",regex:'"',next:"twig-start"},{defaultToken:"string"}],this.$rules["twig-qstring"]=[{token:"constant.language.escape",regex:/\\[\\'ntr]}/},{token:"string",regex:"'",next:"twig-start"},{defaultToken:"string"}],this.normalizeRules()};r.inherits(u,o),t.TwigHighlightRules=u}),ace.define("ace/mode/twig",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/twig_highlight_rules","ace/mode/matching_brace_outdent"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html").Mode,s=e("./twig_highlight_rules").TwigHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=function(){i.call(this),this.HighlightRules=s,this.$outdent=new o};r.inherits(u,i),function(){this.blockComment={start:"{#",end:"#}"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"){var u=t.match(/^.*[\{\(\[]\s*$/);u&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/twig"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-typescript.js b/dist/assets/js/vendor/ace-nc/mode-typescript.js
            new file mode 100644
            index 0000000000..bec91a59bb
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-typescript.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/typescript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/javascript_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript_highlight_rules").JavaScriptHighlightRules,s=function(){var e=[{token:["keyword.operator.ts","text","variable.parameter.function.ts","text"],regex:"\\b(module)(\\s*)([a-zA-Z0-9_?.$][\\w?.$]*)(\\s*\\{)"},{token:["storage.type.variable.ts","text","keyword.other.ts","text"],regex:"(super)(\\s*\\()([a-zA-Z0-9,_?.$\\s]+\\s*)(\\))"},{token:["entity.name.function.ts","paren.lparen","paren.rparen"],regex:"([a-zA-Z_?.$][\\w?.$]*)(\\()(\\))"},{token:["variable.parameter.function.ts","text","variable.parameter.function.ts"],regex:"([a-zA-Z0-9_?.$][\\w?.$]*)(\\s*:\\s*)([a-zA-Z0-9_?.$][\\w?.$]*)"},{token:["keyword.operator.ts"],regex:"(?:\\b(constructor|declare|interface|as|AS|public|private|class|extends|export|super)\\b)"},{token:["storage.type.variable.ts"],regex:"(?:\\b(this\\.|string\\b|bool\\b|number)\\b)"},{token:["keyword.operator.ts","storage.type.variable.ts","keyword.operator.ts","storage.type.variable.ts"],regex:"(class)(\\s+[a-zA-Z0-9_?.$][\\w?.$]*\\s+)(extends)(\\s+[a-zA-Z0-9_?.$][\\w?.$]*\\s+)?"},{token:"keyword",regex:"(?:super|export|class|extends|import)\\b"}],t=(new i).getRules();t.start=e.concat(t.start),this.$rules=t};r.inherits(s,i),t.TypeScriptHighlightRules=s}),ace.define("ace/mode/typescript",["require","exports","module","ace/lib/oop","ace/mode/javascript","ace/mode/typescript_highlight_rules","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle","ace/mode/matching_brace_outdent"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./javascript").Mode,s=e("./typescript_highlight_rules").TypeScriptHighlightRules,o=e("./behaviour/cstyle").CstyleBehaviour,u=e("./folding/cstyle").FoldMode,a=e("./matching_brace_outdent").MatchingBraceOutdent,f=function(){this.HighlightRules=s,this.$outdent=new a,this.$behaviour=new o,this.foldingRules=new u};r.inherits(f,i),function(){this.createWorker=function(e){return null},this.$id="ace/mode/typescript"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-vala.js b/dist/assets/js/vendor/ace-nc/mode-vala.js
            new file mode 100644
            index 0000000000..4b9169d77a
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-vala.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/vala_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:["meta.using.vala","keyword.other.using.vala","meta.using.vala","storage.modifier.using.vala","meta.using.vala","punctuation.terminator.vala"],regex:"^(\\s*)(using)\\b(?:(\\s*)([^ ;$]+)(\\s*)((?:;)?))?"},{include:"#code"}],"#all-types":[{include:"#primitive-arrays"},{include:"#primitive-types"},{include:"#object-types"}],"#annotations":[{token:["storage.type.annotation.vala","punctuation.definition.annotation-arguments.begin.vala"],regex:"(@[^ (]+)(\\()",push:[{token:"punctuation.definition.annotation-arguments.end.vala",regex:"\\)",next:"pop"},{token:["constant.other.key.vala","text","keyword.operator.assignment.vala"],regex:"(\\w*)(\\s*)(=)"},{include:"#code"},{token:"punctuation.seperator.property.vala",regex:","},{defaultToken:"meta.declaration.annotation.vala"}]},{token:"storage.type.annotation.vala",regex:"@\\w*"}],"#anonymous-classes-and-new":[{token:"keyword.control.new.vala",regex:"\\bnew\\b",push_disabled:[{token:"text",regex:"(?<=\\)|\\])(?!\\s*{)|(?<=})|(?=;)",TODO:"FIXME: regexp doesn't have js equivalent",originalRegex:"(?<=\\)|\\])(?!\\s*{)|(?<=})|(?=;)",next:"pop"},{token:["storage.type.vala","text"],regex:"(\\w+)(\\s*)(?=\\[)",push:[{token:"text",regex:"}|(?=;|\\))",next:"pop"},{token:"text",regex:"\\[",push:[{token:"text",regex:"\\]",next:"pop"},{include:"#code"}]},{token:"text",regex:"{",push:[{token:"text",regex:"(?=})",next:"pop"},{include:"#code"}]}]},{token:"text",regex:"(?=\\w.*\\()",push:[{token:"text",regex:"(?<=\\))",TODO:"FIXME: regexp doesn't have js equivalent",originalRegex:"(?<=\\))",next:"pop"},{include:"#object-types"},{token:"text",regex:"\\(",push:[{token:"text",regex:"\\)",next:"pop"},{include:"#code"}]}]},{token:"meta.inner-class.vala",regex:"{",push:[{token:"meta.inner-class.vala",regex:"}",next:"pop"},{include:"#class-body"},{defaultToken:"meta.inner-class.vala"}]}]}],"#assertions":[{token:["keyword.control.assert.vala","meta.declaration.assertion.vala"],regex:"\\b(assert|requires|ensures)(\\s)",push:[{token:"meta.declaration.assertion.vala",regex:"$",next:"pop"},{token:"keyword.operator.assert.expression-seperator.vala",regex:":"},{include:"#code"},{defaultToken:"meta.declaration.assertion.vala"}]}],"#class":[{token:"meta.class.vala",regex:"(?=\\w?[\\w\\s]*(?:class|(?:@)?interface|enum|struct|namespace)\\s+\\w+)",push:[{token:"punctuation.section.class.end.vala",regex:"}",next:"pop"},{include:"#storage-modifiers"},{include:"#comments"},{token:["storage.modifier.vala","meta.class.identifier.vala","entity.name.type.class.vala"],regex:"(class|(?:@)?interface|enum|struct|namespace)(\\s+)([\\w\\.]+)"},{token:"storage.modifier.extends.vala",regex:":",push:[{token:"meta.definition.class.inherited.classes.vala",regex:"(?={|,)",next:"pop"},{include:"#object-types-inherited"},{include:"#comments"},{defaultToken:"meta.definition.class.inherited.classes.vala"}]},{token:["storage.modifier.implements.vala","meta.definition.class.implemented.interfaces.vala"],regex:"(,)(\\s)",push:[{token:"meta.definition.class.implemented.interfaces.vala",regex:"(?=\\{)",next:"pop"},{include:"#object-types-inherited"},{include:"#comments"},{defaultToken:"meta.definition.class.implemented.interfaces.vala"}]},{token:"meta.class.body.vala",regex:"{",push:[{token:"meta.class.body.vala",regex:"(?=})",next:"pop"},{include:"#class-body"},{defaultToken:"meta.class.body.vala"}]},{defaultToken:"meta.class.vala"}],comment:"attempting to put namespace in here."}],"#class-body":[{include:"#comments"},{include:"#class"},{include:"#enums"},{include:"#methods"},{include:"#annotations"},{include:"#storage-modifiers"},{include:"#code"}],"#code":[{include:"#comments"},{include:"#class"},{token:"text",regex:"{",push:[{token:"text",regex:"}",next:"pop"},{include:"#code"}]},{include:"#assertions"},{include:"#parens"},{include:"#constants-and-special-vars"},{include:"#anonymous-classes-and-new"},{include:"#keywords"},{include:"#storage-modifiers"},{include:"#strings"},{include:"#all-types"}],"#comments":[{token:"punctuation.definition.comment.vala",regex:"/\\*\\*/"},{include:"text.html.javadoc"},{include:"#comments-inline"}],"#comments-inline":[{token:"punctuation.definition.comment.vala",regex:"/\\*",push:[{token:"punctuation.definition.comment.vala",regex:"\\*/",next:"pop"},{defaultToken:"comment.block.vala"}]},{token:["text","punctuation.definition.comment.vala","comment.line.double-slash.vala"],regex:"(\\s*)(//)(.*$)"}],"#constants-and-special-vars":[{token:"constant.language.vala",regex:"\\b(?:true|false|null)\\b"},{token:"variable.language.vala",regex:"\\b(?:this|base)\\b"},{token:"constant.numeric.vala",regex:"\\b(?:0(?:x|X)[0-9a-fA-F]*|(?:[0-9]+\\.?[0-9]*|\\.[0-9]+)(?:(?:e|E)(?:\\+|-)?[0-9]+)?)(?:[LlFfUuDd]|UL|ul)?\\b"},{token:["keyword.operator.dereference.vala","constant.other.vala"],regex:"((?:\\.)?)\\b([A-Z][A-Z0-9_]+)(?!<|\\.class|\\s*\\w+\\s*=)\\b"}],"#enums":[{token:"text",regex:"^(?=\\s*[A-Z0-9_]+\\s*(?:{|\\(|,))",push:[{token:"text",regex:"(?=;|})",next:"pop"},{token:"constant.other.enum.vala",regex:"\\w+",push:[{token:"meta.enum.vala",regex:"(?=,|;|})",next:"pop"},{include:"#parens"},{token:"text",regex:"{",push:[{token:"text",regex:"}",next:"pop"},{include:"#class-body"}]},{defaultToken:"meta.enum.vala"}]}]}],"#keywords":[{token:"keyword.control.catch-exception.vala",regex:"\\b(?:try|catch|finally|throw)\\b"},{token:"keyword.control.vala",regex:"\\?|:|\\?\\?"},{token:"keyword.control.vala",regex:"\\b(?:return|break|case|continue|default|do|while|for|foreach|switch|if|else|in|yield|get|set|value)\\b"},{token:"keyword.operator.vala",regex:"\\b(?:typeof|is|as)\\b"},{token:"keyword.operator.comparison.vala",regex:"==|!=|<=|>=|<>|<|>"},{token:"keyword.operator.assignment.vala",regex:"="},{token:"keyword.operator.increment-decrement.vala",regex:"\\-\\-|\\+\\+"},{token:"keyword.operator.arithmetic.vala",regex:"\\-|\\+|\\*|\\/|%"},{token:"keyword.operator.logical.vala",regex:"!|&&|\\|\\|"},{token:"keyword.operator.dereference.vala",regex:"\\.(?=\\S)",originalRegex:"(?<=\\S)\\.(?=\\S)"},{token:"punctuation.terminator.vala",regex:";"},{token:"keyword.operator.ownership",regex:"owned|unowned"}],"#methods":[{token:"meta.method.vala",regex:"(?!new)(?=\\w.*\\s+)(?=[^=]+\\()",push:[{token:"meta.method.vala",regex:"}|(?=;)",next:"pop"},{include:"#storage-modifiers"},{token:["entity.name.function.vala","meta.method.identifier.vala"],regex:"([\\~\\w\\.]+)(\\s*\\()",push:[{token:"meta.method.identifier.vala",regex:"\\)",next:"pop"},{include:"#parameters"},{defaultToken:"meta.method.identifier.vala"}]},{token:"meta.method.return-type.vala",regex:"(?=\\w.*\\s+\\w+\\s*\\()",push:[{token:"meta.method.return-type.vala",regex:"(?=\\w+\\s*\\()",next:"pop"},{include:"#all-types"},{defaultToken:"meta.method.return-type.vala"}]},{include:"#throws"},{token:"meta.method.body.vala",regex:"{",push:[{token:"meta.method.body.vala",regex:"(?=})",next:"pop"},{include:"#code"},{defaultToken:"meta.method.body.vala"}]},{defaultToken:"meta.method.vala"}]}],"#namespace":[{token:"text",regex:"^(?=\\s*[A-Z0-9_]+\\s*(?:{|\\(|,))",push:[{token:"text",regex:"(?=;|})",next:"pop"},{token:"constant.other.namespace.vala",regex:"\\w+",push:[{token:"meta.namespace.vala",regex:"(?=,|;|})",next:"pop"},{include:"#parens"},{token:"text",regex:"{",push:[{token:"text",regex:"}",next:"pop"},{include:"#code"}]},{defaultToken:"meta.namespace.vala"}]}],comment:"This is not quite right. See the class grammar right now"}],"#object-types":[{token:"storage.type.generic.vala",regex:"\\b(?:[a-z]\\w*\\.)*[A-Z]+\\w*<",push:[{token:"storage.type.generic.vala",regex:">|[^\\w\\s,\\?<\\[()\\]]",TODO:"FIXME: regexp doesn't have js equivalent",originalRegex:">|[^\\w\\s,\\?<\\[(?:[,]+)\\]]",next:"pop"},{include:"#object-types"},{token:"storage.type.generic.vala",regex:"<",push:[{token:"storage.type.generic.vala",regex:">|[^\\w\\s,\\[\\]<]",next:"pop"},{defaultToken:"storage.type.generic.vala"}],comment:"This is just to support <>'s with no actual type prefix"},{defaultToken:"storage.type.generic.vala"}]},{token:"storage.type.object.array.vala",regex:"\\b(?:[a-z]\\w*\\.)*[A-Z]+\\w*(?=\\[)",push:[{token:"storage.type.object.array.vala",regex:"(?=[^\\]\\s])",next:"pop"},{token:"text",regex:"\\[",push:[{token:"text",regex:"\\]",next:"pop"},{include:"#code"}]},{defaultToken:"storage.type.object.array.vala"}]},{token:["storage.type.vala","keyword.operator.dereference.vala","storage.type.vala"],regex:"\\b(?:([a-z]\\w*)(\\.))*([A-Z]+\\w*\\b)"}],"#object-types-inherited":[{token:"entity.other.inherited-class.vala",regex:"\\b(?:[a-z]\\w*\\.)*[A-Z]+\\w*<",push:[{token:"entity.other.inherited-class.vala",regex:">|[^\\w\\s,<]",next:"pop"},{include:"#object-types"},{token:"storage.type.generic.vala",regex:"<",push:[{token:"storage.type.generic.vala",regex:">|[^\\w\\s,<]",next:"pop"},{defaultToken:"storage.type.generic.vala"}],comment:"This is just to support <>'s with no actual type prefix"},{defaultToken:"entity.other.inherited-class.vala"}]},{token:["entity.other.inherited-class.vala","keyword.operator.dereference.vala","entity.other.inherited-class.vala"],regex:"\\b(?:([a-z]\\w*)(\\.))*([A-Z]+\\w*)"}],"#parameters":[{token:"storage.modifier.vala",regex:"final"},{include:"#primitive-arrays"},{include:"#primitive-types"},{include:"#object-types"},{token:"variable.parameter.vala",regex:"\\w+"}],"#parens":[{token:"text",regex:"\\(",push:[{token:"text",regex:"\\)",next:"pop"},{include:"#code"}]}],"#primitive-arrays":[{token:"storage.type.primitive.array.vala",regex:"\\b(?:bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|int8|int16|int32|int64|uint8|uint16|uint32|uint64)(?:\\[\\])*\\b"}],"#primitive-types":[{token:"storage.type.primitive.vala",regex:"\\b(?:var|bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|signal|int8|int16|int32|int64|uint8|uint16|uint32|uint64)\\b",comment:"var is not really a primitive, but acts like one in most cases"}],"#storage-modifiers":[{token:"storage.modifier.vala",regex:"\\b(?:public|private|protected|internal|static|final|sealed|virtual|override|abstract|readonly|volatile|dynamic|async|unsafe|out|ref|weak|owned|unowned|const)\\b",comment:"Not sure about unsafe and readonly"}],"#strings":[{token:"punctuation.definition.string.begin.vala",regex:'@"',push:[{token:"punctuation.definition.string.end.vala",regex:'"',next:"pop"},{token:"constant.character.escape.vala",regex:"\\\\.|%[\\w\\.\\-]+|\\$(?:\\w+|\\([\\w\\s\\+\\-\\*\\/]+\\))"},{defaultToken:"string.quoted.interpolated.vala"}]},{token:"punctuation.definition.string.begin.vala",regex:'"',push:[{token:"punctuation.definition.string.end.vala",regex:'"',next:"pop"},{token:"constant.character.escape.vala",regex:"\\\\."},{token:"constant.character.escape.vala",regex:"%[\\w\\.\\-]+"},{defaultToken:"string.quoted.double.vala"}]},{token:"punctuation.definition.string.begin.vala",regex:"'",push:[{token:"punctuation.definition.string.end.vala",regex:"'",next:"pop"},{token:"constant.character.escape.vala",regex:"\\\\."},{defaultToken:"string.quoted.single.vala"}]},{token:"punctuation.definition.string.begin.vala",regex:'"""',push:[{token:"punctuation.definition.string.end.vala",regex:'"""',next:"pop"},{token:"constant.character.escape.vala",regex:"%[\\w\\.\\-]+"},{defaultToken:"string.quoted.triple.vala"}]}],"#throws":[{token:"storage.modifier.vala",regex:"throws",push:[{token:"meta.throwables.vala",regex:"(?={|;)",next:"pop"},{include:"#object-types"},{defaultToken:"meta.throwables.vala"}]}],"#values":[{include:"#strings"},{include:"#object-types"},{include:"#constants-and-special-vars"}]},this.normalizeRules()};s.metaData={comment:"Based heavily on the Java bundle's language syntax. TODO:\n* Closures\n* Delegates\n* Properties: Better support for properties.\n* Annotations\n* Error domains\n* Named arguments\n* Array slicing, negative indexes, multidimensional\n* construct blocks\n* lock blocks?\n* regex literals\n* DocBlock syntax highlighting. (Currently importing javadoc)\n* Folding rule for comments.\n",fileTypes:["vala"],foldingStartMarker:"(\\{\\s*(//.*)?$|^\\s*// \\{\\{\\{)",foldingStopMarker:"^\\s*(\\}|// \\}\\}\\}$)",name:"Vala",scopeName:"source.vala"},r.inherits(s,i),t.ValaHighlightRules=s}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/vala",["require","exports","module","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/vala_highlight_rules","ace/mode/folding/cstyle","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle","ace/mode/matching_brace_outdent"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("../tokenizer").Tokenizer,o=e("./vala_highlight_rules").ValaHighlightRules,u=e("./folding/cstyle").FoldMode,a=e("./behaviour/cstyle").CstyleBehaviour,f=e("./folding/cstyle").FoldMode,l=e("./matching_brace_outdent").MatchingBraceOutdent,c=function(){this.HighlightRules=o,this.$outdent=new l,this.$behaviour=new a,this.foldingRules=new f};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/vala"}.call(c.prototype),t.Mode=c})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-vbscript.js b/dist/assets/js/vendor/ace-nc/mode-vbscript.js
            new file mode 100644
            index 0000000000..331221e5ec
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-vbscript.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/vbscript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:["meta.ending-space"],regex:"$"},{token:[null],regex:"^(?=\\t)",next:"state_3"},{token:[null],regex:"^(?= )",next:"state_4"},{token:["text","storage.type.function.asp","text","entity.name.function.asp","text","punctuation.definition.parameters.asp","variable.parameter.function.asp","punctuation.definition.parameters.asp"],regex:"^(\\s*)(Function|Sub)(\\s*)([a-zA-Z_]\\w*)(\\s*)(\\()([^)]*)(\\))"},{token:"punctuation.definition.comment.asp",regex:"'|REM",next:"comment"},{token:["keyword.control.asp"],regex:"\\b(?:If|Then|Else|ElseIf|Else If|End If|While|Wend|For|To|Each|Case|Select|End Select|Return|Continue|Do|Until|Loop|Next|With|Exit Do|Exit For|Exit Function|Exit Property|Exit Sub|IIf)\\b"},{token:"keyword.operator.asp",regex:"\\b(?:Mod|And|Not|Or|Xor|as)\\b"},{token:"storage.type.asp",regex:"Dim|Call|Class|Const|Dim|Redim|Function|Sub|Private Sub|Public Sub|End sub|End Function|Set|Let|Get|New|Randomize|Option Explicit|On Error Resume Next|On Error GoTo"},{token:"storage.modifier.asp",regex:"\\b(?:Private|Public|Default)\\b"},{token:"constant.language.asp",regex:"\\b(?:Empty|False|Nothing|Null|True)\\b"},{token:"punctuation.definition.string.begin.asp",regex:'"',next:"string"},{token:["punctuation.definition.variable.asp"],regex:"(\\$)[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*?\\b\\s*"},{token:"support.class.asp",regex:"\\b(?:Application|ObjectContext|Request|Response|Server|Session)\\b"},{token:"support.class.collection.asp",regex:"\\b(?:Contents|StaticObjects|ClientCertificate|Cookies|Form|QueryString|ServerVariables)\\b"},{token:"support.constant.asp",regex:"\\b(?:TotalBytes|Buffer|CacheControl|Charset|ContentType|Expires|ExpiresAbsolute|IsClientConnected|PICS|Status|ScriptTimeout|CodePage|LCID|SessionID|Timeout)\\b"},{token:"support.function.asp",regex:"\\b(?:Lock|Unlock|SetAbort|SetComplete|BinaryRead|AddHeader|AppendToLog|BinaryWrite|Clear|End|Flush|Redirect|Write|CreateObject|HTMLEncode|MapPath|URLEncode|Abandon|Convert|Regex)\\b"},{token:"support.function.event.asp",regex:"\\b(?:Application_OnEnd|Application_OnStart|OnTransactionAbort|OnTransactionCommit|Session_OnEnd|Session_OnStart)\\b"},{token:"support.function.vb.asp",regex:"\\b(?:Array|Add|Asc|Atn|CBool|CByte|CCur|CDate|CDbl|Chr|CInt|CLng|Conversions|Cos|CreateObject|CSng|CStr|Date|DateAdd|DateDiff|DatePart|DateSerial|DateValue|Day|Derived|Math|Escape|Eval|Exists|Exp|Filter|FormatCurrency|FormatDateTime|FormatNumber|FormatPercent|GetLocale|GetObject|GetRef|Hex|Hour|InputBox|InStr|InStrRev|Int|Fix|IsArray|IsDate|IsEmpty|IsNull|IsNumeric|IsObject|Item|Items|Join|Keys|LBound|LCase|Left|Len|LoadPicture|Log|LTrim|RTrim|Trim|Maths|Mid|Minute|Month|MonthName|MsgBox|Now|Oct|Remove|RemoveAll|Replace|RGB|Right|Rnd|Round|ScriptEngine|ScriptEngineBuildVersion|ScriptEngineMajorVersion|ScriptEngineMinorVersion|Second|SetLocale|Sgn|Sin|Space|Split|Sqr|StrComp|String|StrReverse|Tan|Time|Timer|TimeSerial|TimeValue|TypeName|UBound|UCase|Unescape|VarType|Weekday|WeekdayName|Year)\\b"},{token:["constant.numeric.asp"],regex:"-?\\b(?:(?:0(?:x|X)[0-9a-fA-F]*)|(?:(?:[0-9]+\\.?[0-9]*)|(?:\\.[0-9]+))(?:(?:e|E)(?:\\+|-)?[0-9]+)?)(?:L|l|UL|ul|u|U|F|f)?\\b"},{token:"support.type.vb.asp",regex:"\\b(?:vbtrue|vbfalse|vbcr|vbcrlf|vbformfeed|vblf|vbnewline|vbnullchar|vbnullstring|int32|vbtab|vbverticaltab|vbbinarycompare|vbtextcomparevbsunday|vbmonday|vbtuesday|vbwednesday|vbthursday|vbfriday|vbsaturday|vbusesystemdayofweek|vbfirstjan1|vbfirstfourdays|vbfirstfullweek|vbgeneraldate|vblongdate|vbshortdate|vblongtime|vbshorttime|vbobjecterror|vbEmpty|vbNull|vbInteger|vbLong|vbSingle|vbDouble|vbCurrency|vbDate|vbString|vbObject|vbError|vbBoolean|vbVariant|vbDataObject|vbDecimal|vbByte|vbArray)\\b"},{token:["entity.name.function.asp"],regex:"(?:(\\b[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*?\\b)(?=\\(\\)?))"},{token:["keyword.operator.asp"],regex:"\\-|\\+|\\*\\/|\\>|\\<|\\=|\\&"}],state_3:[{token:["meta.odd-tab.tabs","meta.even-tab.tabs"],regex:"(\\t)(\\t)?"},{token:"meta.leading-space",regex:"(?=[^\\t])",next:"start"},{token:"meta.leading-space",regex:".",next:"state_3"}],state_4:[{token:["meta.odd-tab.spaces","meta.even-tab.spaces"],regex:"(  )(  )?"},{token:"meta.leading-space",regex:"(?=[^ ])",next:"start"},{defaultToken:"meta.leading-space"}],comment:[{token:"comment.line.apostrophe.asp",regex:"$|(?=(?:%>))",next:"start"},{defaultToken:"comment.line.apostrophe.asp"}],string:[{token:"constant.character.escape.apostrophe.asp",regex:'""'},{token:"string.quoted.double.asp",regex:'"',next:"start"},{defaultToken:"string.quoted.double.asp"}]}};r.inherits(s,i),t.VBScriptHighlightRules=s}),ace.define("ace/mode/vbscript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/vbscript_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./vbscript_highlight_rules").VBScriptHighlightRules,o=function(){this.HighlightRules=s};r.inherits(o,i),function(){this.lineCommentStart=["'","REM"],this.$id="ace/mode/vbscript"}.call(o.prototype),t.Mode=o})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-velocity.js b/dist/assets/js/vendor/ace-nc/mode-velocity.js
            new file mode 100644
            index 0000000000..e31b37fa2f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-velocity.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),ace.define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["support.constant"],regex:/that\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),ace.define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=t.supportType="animation-fill-mode|alignment-adjust|alignment-baseline|animation-delay|animation-direction|animation-duration|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|animation|appearance|azimuth|backface-visibility|background-attachment|background-break|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|background|baseline-shift|binding|bleed|bookmark-label|bookmark-level|bookmark-state|bookmark-target|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|border|bottom|box-align|box-decoration-break|box-direction|box-flex-group|box-flex|box-lines|box-ordinal-group|box-orient|box-pack|box-shadow|box-sizing|break-after|break-before|break-inside|caption-side|clear|clip|color-profile|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|crop|cue-after|cue-before|cue|cursor|direction|display|dominant-baseline|drop-initial-after-adjust|drop-initial-after-align|drop-initial-before-adjust|drop-initial-before-align|drop-initial-size|drop-initial-value|elevation|empty-cells|fit|fit-position|float-offset|float|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|font|grid-columns|grid-rows|hanging-punctuation|height|hyphenate-after|hyphenate-before|hyphenate-character|hyphenate-lines|hyphenate-resource|hyphens|icon|image-orientation|image-rendering|image-resolution|inline-box-align|left|letter-spacing|line-height|line-stacking-ruby|line-stacking-shift|line-stacking-strategy|line-stacking|list-style-image|list-style-position|list-style-type|list-style|margin-bottom|margin-left|margin-right|margin-top|margin|mark-after|mark-before|mark|marks|marquee-direction|marquee-play-count|marquee-speed|marquee-style|max-height|max-width|min-height|min-width|move-to|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|orphans|outline-color|outline-offset|outline-style|outline-width|outline|overflow-style|overflow-x|overflow-y|overflow|padding-bottom|padding-left|padding-right|padding-top|padding|page-break-after|page-break-before|page-break-inside|page-policy|page|pause-after|pause-before|pause|perspective-origin|perspective|phonemes|pitch-range|pitch|play-during|pointer-events|position|presentation-level|punctuation-trim|quotes|rendering-intent|resize|rest-after|rest-before|rest|richness|right|rotation-point|rotation|ruby-align|ruby-overhang|ruby-position|ruby-span|size|speak-header|speak-numeral|speak-punctuation|speak|speech-rate|stress|string-set|table-layout|target-name|target-new|target-position|target|text-align-last|text-align|text-decoration|text-emphasis|text-height|text-indent|text-justify|text-outline|text-shadow|text-transform|text-wrap|top|transform-origin|transform-style|transform|transition-delay|transition-duration|transition-property|transition-timing-function|transition|unicode-bidi|vertical-align|visibility|voice-balance|voice-duration|voice-family|voice-pitch-range|voice-pitch|voice-rate|voice-stress|voice-volume|volume|white-space-collapse|white-space|widows|width|word-break|word-spacing|word-wrap|z-index",u=t.supportFunction="rgb|rgba|url|attr|counter|counters",a=t.supportConstant="absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero",f=t.supportConstantColor="aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow",l=t.supportConstantFonts="arial|century|comic|courier|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace",c=t.numRe="\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))",h=t.pseudoElements="(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b",p=t.pseudoClasses="(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b",d=function(){var e=this.createKeywordMapper({"support.function":u,"support.constant":a,"support.type":o,"support.constant.color":f,"support.constant.fonts":l},"text",!0);this.$rules={start:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"@.*?{",push:"media"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],media:[{token:"comment",regex:"\\/\\*",push:"comment"},{token:"paren.lparen",regex:"\\{",push:"ruleset"},{token:"string",regex:"\\}",next:"pop"},{token:"keyword",regex:"#[a-z0-9-_]+"},{token:"variable",regex:"\\.[a-z0-9-_]+"},{token:"string",regex:":[a-z0-9-_]+"},{token:"constant",regex:"[a-z0-9-_]+"},{caseInsensitive:!0}],comment:[{token:"comment",regex:"\\*\\/",next:"pop"},{defaultToken:"comment"}],ruleset:[{token:"paren.rparen",regex:"\\}",next:"pop"},{token:"comment",regex:"\\/\\*",push:"comment"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:["constant.numeric","keyword"],regex:"("+c+")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vm|vw|%)"},{token:"constant.numeric",regex:c},{token:"constant.numeric",regex:"#[a-f0-9]{6}"},{token:"constant.numeric",regex:"#[a-f0-9]{3}"},{token:["punctuation","entity.other.attribute-name.pseudo-element.css"],regex:h},{token:["punctuation","entity.other.attribute-name.pseudo-class.css"],regex:p},{token:["support.function","string","support.function"],regex:"(url\\()(.*)(\\))"},{token:e,regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"},{caseInsensitive:!0}]},this.normalizeRules()};r.inherits(d,s),t.CssHighlightRules=d}),ace.define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../../token_iterator").TokenIterator,u=function(){this.inherit(s),this.add("colon","insertion",function(e,t,n,r,i){if(i===":"){var s=n.getCursorPosition(),u=new o(r,s.row,s.column),a=u.getCurrentToken();a&&a.value.match(/\s+/)&&(a=u.stepBackward());if(a&&a.type==="support.type"){var f=r.doc.getLine(s.row),l=f.substring(s.column,s.column+1);if(l===":")return{text:"",selection:[1,1]};if(!f.substring(s.column).match(/^\s*;/))return{text:":;",selection:[1,1]}}}}),this.add("colon","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s===":"){var u=n.getCursorPosition(),a=new o(r,u.row,u.column),f=a.getCurrentToken();f&&f.value.match(/\s+/)&&(f=a.stepBackward());if(f&&f.type==="support.type"){var l=r.doc.getLine(i.start.row),c=l.substring(i.end.column,i.end.column+1);if(c===";")return i.end.column++,i}}}),this.add("semicolon","insertion",function(e,t,n,r,i){if(i===";"){var s=n.getCursorPosition(),o=r.doc.getLine(s.row),u=o.substring(s.column,s.column+1);if(u===";")return{text:"",selection:[1,1]}}})};r.inherits(u,s),t.CssBehaviour=u}),ace.define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/css","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./css_highlight_rules").CssHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../worker/worker_client").WorkerClient,a=e("./behaviour/css").CssBehaviour,f=e("./folding/cstyle").FoldMode,l=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new a,this.foldingRules=new f};r.inherits(l,i),function(){this.foldingRules="cStyle",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e).tokens;if(i.length&&i[i.length-1].type=="comment")return r;var s=t.match(/^.*\{\s*$/);return s&&(r+=n),r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new u(["ace"],"ace/mode/css_worker","Worker");return t.attachToDocument(e.getDocument()),t.on("csslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/css"}.call(l.prototype),t.Mode=l}),ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./css_highlight_rules").CssHighlightRules,o=e("./javascript_highlight_rules").JavaScriptHighlightRules,u=e("./xml_highlight_rules").XmlHighlightRules,a=i.createMap({a:"anchor",button:"form",form:"form",img:"image",input:"form",label:"form",option:"form",script:"script",select:"form",textarea:"form",style:"style",table:"table",tbody:"table",td:"table",tfoot:"table",th:"table",tr:"table"}),f=function(){u.call(this),this.addRules({attributes:[{include:"tag_whitespace"},{token:"entity.other.attribute-name.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"keyword.operator.attribute-equals.xml",regex:"=",push:[{include:"tag_whitespace"},{token:"string.unquoted.attribute-value.html",regex:"[^<>='\"`\\s]+",next:"pop"},{token:"empty",regex:"",next:"pop"}]},{include:"attribute_value"}],tag:[{token:function(e,t){var n=a[t];return["meta.tag.punctuation."+(e=="<"?"":"end-")+"tag-open.xml","meta.tag"+(n?"."+n:"")+".tag-name.xml"]},regex:"(</?)([-_a-zA-Z0-9:]+)",next:"tag_stuff"}],tag_stuff:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}),this.embedTagRules(s,"css-","style"),this.embedTagRules(o,"js-","script"),this.constructor===f&&this.normalizeRules()};r.inherits(f,u),t.HtmlHighlightRules=f}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/mixed",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=t.FoldMode=function(e,t){this.defaultMode=e,this.subModes=t};r.inherits(s,i),function(){this.$getMode=function(e){typeof e!="string"&&(e=e[0]);for(var t in this.subModes)if(e.indexOf(t)===0)return this.subModes[t];return null},this.$tryMode=function(e,t,n,r){var i=this.$getMode(e);return i?i.getFoldWidget(t,n,r):""},this.getFoldWidget=function(e,t,n){return this.$tryMode(e.getState(n-1),e,t,n)||this.$tryMode(e.getState(n),e,t,n)||this.defaultMode.getFoldWidget(e,t,n)},this.getFoldWidgetRange=function(e,t,n){var r=this.$getMode(e.getState(n-1));if(!r||!r.getFoldWidget(e,t,n))r=this.$getMode(e.getState(n));if(!r||!r.getFoldWidget(e,t,n))r=this.defaultMode;return r.getFoldWidgetRange(e,t,n)}}.call(s.prototype)}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./mixed").FoldMode,s=e("./xml").FoldMode,o=e("./cstyle").FoldMode,u=t.FoldMode=function(e,t){i.call(this,new s(e,t),{"js-":new o,"css-":new o})};r.inherits(u,i)}),ace.define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"],function(e,t,n){"use strict";function f(e,t){return e.type.lastIndexOf(t+".xml")>-1}function l(e,t){var n=new r(e,t.row,t.column),i=n.getCurrentToken();while(i&&!f(i,"tag-name"))i=n.stepBackward();if(i)return i.value}var r=e("../token_iterator").TokenIterator,i=["accesskey","class","contenteditable","contextmenu","dir","draggable","dropzone","hidden","id","inert","itemid","itemprop","itemref","itemscope","itemtype","lang","spellcheck","style","tabindex","title","translate"],s=["onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onscroll","onseeked","onseeking","onselect","onshow","onstalled","onsubmit","onsuspend","ontimeupdate","onvolumechange","onwaiting"],o=i.concat(s),u={html:["manifest"],head:[],title:[],base:["href","target"],link:["href","hreflang","rel","media","type","sizes"],meta:["http-equiv","name","content","charset"],style:["type","media","scoped"],script:["charset","type","src","defer","async"],noscript:["href"],body:["onafterprint","onbeforeprint","onbeforeunload","onhashchange","onmessage","onoffline","onpopstate","onredo","onresize","onstorage","onundo","onunload"],section:[],nav:[],article:["pubdate"],aside:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],header:[],footer:[],address:[],main:[],p:[],hr:[],pre:[],blockquote:["cite"],ol:["start","reversed"],ul:[],li:["value"],dl:[],dt:[],dd:[],figure:[],figcaption:[],div:[],a:["href","target","ping","rel","media","hreflang","type"],em:[],strong:[],small:[],s:[],cite:[],q:["cite"],dfn:[],abbr:[],data:[],time:["datetime"],code:[],"var":[],samp:[],kbd:[],sub:[],sup:[],i:[],b:[],u:[],mark:[],ruby:[],rt:[],rp:[],bdi:[],bdo:[],span:[],br:[],wbr:[],ins:["cite","datetime"],del:["cite","datetime"],img:["alt","src","height","width","usemap","ismap"],iframe:["name","src","height","width","sandbox","seamless"],embed:["src","height","width","type"],object:["param","data","type","height","width","usemap","name","form","classid"],param:["name","value"],video:["src","autobuffer","autoplay","loop","controls","width","height","poster"],audio:["src","autobuffer","autoplay","loop","controls"],source:["src","type","media"],track:["kind","src","srclang","label","default"],canvas:["width","height"],map:["name"],area:["shape","coords","href","hreflang","alt","target","media","rel","ping","type"],svg:[],math:[],table:["summary"],caption:[],colgroup:["span"],col:["span"],tbody:[],thead:[],tfoot:[],tr:[],td:["headers","rowspan","colspan"],th:["headers","rowspan","colspan","scope"],form:["accept-charset","action","autocomplete","enctype","method","name","novalidate","target"],fieldset:["disabled","form","name"],legend:[],label:["form","for"],input:["type","accept","alt","autocomplete","checked","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","height","list","max","maxlength","min","multiple","pattern","placeholder","readonly","required","size","src","step","width","files","value"],button:["autofocus","disabled","form","formaction","formenctype","formmethod","formnovalidate","formtarget","name","value","type"],select:["autofocus","disabled","form","multiple","name","size"],datalist:[],optgroup:["disabled","label"],option:["disabled","selected","label","value"],textarea:["autofocus","disabled","form","maxlength","name","placeholder","readonly","required","rows","cols","wrap"],keygen:["autofocus","challenge","disabled","form","keytype","name"],output:["for","form","name"],progress:["value","max"],meter:["value","min","max","low","high","optimum"],details:["open"],summary:[],command:["type","label","icon","disabled","checked","radiogroup","command"],menu:["type","label"],dialog:["open"]},a=Object.keys(u),c=function(){};(function(){this.getCompletions=function(e,t,n,r){var i=t.getTokenAt(n.row,n.column);return i?f(i,"tag-name")||f(i,"tag-open")||f(i,"end-tag-open")?this.getTagCompletions(e,t,n,r):f(i,"tag-whitespace")||f(i,"attribute-name")?this.getAttributeCompetions(e,t,n,r):[]:[]},this.getTagCompletions=function(e,t,n,r){return a.map(function(e){return{value:e,meta:"tag",score:Number.MAX_VALUE}})},this.getAttributeCompetions=function(e,t,n,r){var i=l(t,n);if(!i)return[];var s=o;return i in u&&(s=s.concat(u[i])),s.map(function(e){return{caption:e,snippet:e+'="$0"',meta:"attribute",score:Number.MAX_VALUE}})}}).call(c.prototype),t.HtmlCompletions=c}),ace.define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./javascript").Mode,u=e("./css").Mode,a=e("./html_highlight_rules").HtmlHighlightRules,f=e("./behaviour/xml").XmlBehaviour,l=e("./folding/html").FoldMode,c=e("./html_completions").HtmlCompletions,h=e("../worker/worker_client").WorkerClient,p=["area","base","br","col","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"],d=["li","dt","dd","p","rt","rp","optgroup","option","colgroup","td","th"],v=function(e){this.fragmentContext=e&&e.fragmentContext,this.HighlightRules=a,this.$behaviour=new f,this.$completer=new c,this.createModeDelegates({"js-":o,"css-":u}),this.foldingRules=new l(this.voidElements,i.arrayToMap(d))};r.inherits(v,s),function(){this.blockComment={start:"<!--",end:"-->"},this.voidElements=i.arrayToMap(p),this.getNextLineIndent=function(e,t,n){return this.$getIndent(t)},this.checkOutdent=function(e,t,n){return!1},this.getCompletions=function(e,t,n,r){return this.$completer.getCompletions(e,t,n,r)},this.createWorker=function(e){if(this.constructor!=v)return;var t=new h(["ace"],"ace/mode/html_worker","Worker");return t.attachToDocument(e.getDocument()),this.fragmentContext&&t.call("setOptions",[{context:this.fragmentContext}]),t.on("error",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/html"}.call(v.prototype),t.Mode=v}),ace.define("ace/mode/velocity_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules","ace/mode/html_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text_highlight_rules").TextHighlightRules,o=e("./html_highlight_rules").HtmlHighlightRules,u=function(){o.call(this);var e=i.arrayToMap("true|false|null".split("|")),t=i.arrayToMap("_DateTool|_DisplayTool|_EscapeTool|_FieldTool|_MathTool|_NumberTool|_SerializerTool|_SortTool|_StringTool|_XPathTool".split("|")),n=i.arrayToMap("$contentRoot|$foreach".split("|")),r=i.arrayToMap("#set|#macro|#include|#parse|#if|#elseif|#else|#foreach|#break|#end|#stop".split("|"));this.$rules.start.push({token:"comment",regex:"##.*$"},{token:"comment.block",regex:"#\\*",next:"vm_comment"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:function(i){return r.hasOwnProperty(i)?"keyword":e.hasOwnProperty(i)?"constant.language":n.hasOwnProperty(i)?"variable.language":t.hasOwnProperty(i)||t.hasOwnProperty(i.substring(1))?"support.function":i=="debugger"?"invalid.deprecated":i.match(/^(\$[a-zA-Z_][a-zA-Z0-9_]*)$/)?"variable":"identifier"},regex:"[a-zA-Z$#][a-zA-Z0-9_]*\\b"},{token:"keyword.operator",regex:"!|&|\\*|\\-|\\+|=|!=|<=|>=|<|>|&&|\\|\\|"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}),this.$rules.vm_comment=[{token:"comment",regex:"\\*#|-->",next:"start"},{defaultToken:"comment"}],this.$rules.vm_start=[{token:"variable",regex:"}",next:"pop"},{token:"string.regexp",regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/]\\w*\\s*(?=[).,;]|$)"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:"0[xX][0-9a-fA-F]+\\b"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"constant.language.boolean",regex:"(?:true|false)\\b"},{token:function(i){return r.hasOwnProperty(i)?"keyword":e.hasOwnProperty(i)?"constant.language":n.hasOwnProperty(i)?"variable.language":t.hasOwnProperty(i)||t.hasOwnProperty(i.substring(1))?"support.function":i=="debugger"?"invalid.deprecated":i.match(/^(\$[a-zA-Z_$][a-zA-Z0-9_]*)$/)?"variable":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"!|&|\\*|\\-|\\+|=|!=|<=|>=|<|>|&&|\\|\\|"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"},{token:"text",regex:"\\s+"}];for(var s in this.$rules)this.$rules[s].unshift({token:"variable",regex:"\\${",push:"vm_start"});this.normalizeRules()};r.inherits(u,s),t.VelocityHighlightRules=u}),ace.define("ace/mode/folding/velocity",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="##")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="##")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="##"&&s[i]=="##")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="##"&&o[i]=="##"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/velocity",["require","exports","module","ace/lib/oop","ace/mode/html","ace/mode/velocity_highlight_rules","ace/mode/folding/velocity"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./html").Mode,s=e("./velocity_highlight_rules").VelocityHighlightRules,o=e("./folding/velocity").FoldMode,u=function(){i.call(this),this.HighlightRules=s,this.foldingRules=new o};r.inherits(u,i),function(){this.lineCommentStart="##",this.blockComment={start:"#*",end:"*#"},this.$id="ace/mode/velocity"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-verilog.js b/dist/assets/js/vendor/ace-nc/mode-verilog.js
            new file mode 100644
            index 0000000000..9883bd3c2f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-verilog.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/verilog_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="always|and|assign|automatic|begin|buf|bufif0|bufif1|case|casex|casez|cell|cmos|config|deassign|default|defparam|design|disable|edge|else|end|endcase|endconfig|endfunction|endgenerate|endmodule|endprimitive|endspecify|endtable|endtask|event|for|force|forever|fork|function|generate|genvar|highz0|highz1|if|ifnone|incdir|include|initial|inout|input|instance|integer|join|large|liblist|library|localparam|macromodule|medium|module|nand|negedge|nmos|nor|noshowcancelled|not|notif0|notif1|or|output|parameter|pmos|posedge|primitive|pull0|pull1|pulldown|pullup|pulsestyle_onevent|pulsestyle_ondetect|rcmos|real|realtime|reg|release|repeat|rnmos|rpmos|rtran|rtranif0|rtranif1|scalared|showcancelled|signed|small|specify|specparam|strong0|strong1|supply0|supply1|table|task|time|tran|tranif0|tranif1|tri|tri0|tri1|triand|trior|trireg|unsigned|use|vectored|wait|wand|weak0|weak1|while|wire|wor|xnor|xorbegin|bufif0|bufif1|case|casex|casez|config|else|end|endcase|endconfig|endfunction|endgenerate|endmodule|endprimitive|endspecify|endtable|endtask|for|forever|function|generate|if|ifnone|macromodule|module|primitive|repeat|specify|table|task|while",t="true|false|null",n="count|min|max|avg|sum|rank|now|coalesce|main",r=this.createKeywordMapper({"support.function":n,keyword:e,"constant.language":t},"identifier",!0);this.$rules={start:[{token:"comment",regex:"//.*$"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:r,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\+|\\-|\\/|\\/\\/|%|<@>|@>|<@|&|\\^|~|<|>|<=|=>|==|!=|<>|="},{token:"paren.lparen",regex:"[\\(]"},{token:"paren.rparen",regex:"[\\)]"},{token:"text",regex:"\\s+"}]}};r.inherits(s,i),t.VerilogHighlightRules=s}),ace.define("ace/mode/verilog",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/verilog_highlight_rules","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./verilog_highlight_rules").VerilogHighlightRules,o=e("../range").Range,u=function(){this.HighlightRules=s};r.inherits(u,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.$id="ace/mode/verilog"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-vhdl.js b/dist/assets/js/vendor/ace-nc/mode-vhdl.js
            new file mode 100644
            index 0000000000..94a061c69f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-vhdl.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/vhdl_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){var e="access|after|ailas|all|architecture|assert|attribute|begin|block|buffer|bus|case|component|configuration|disconnect|downto|else|elsif|end|entity|file|for|function|generate|generic|guarded|if|impure|in|inertial|inout|is|label|linkage|literal|loop|mapnew|next|of|on|open|others|out|port|process|pure|range|record|reject|report|return|select|shared|subtype|then|to|transport|type|unaffected|united|until|wait|when|while|with",t="bit|bit_vector|boolean|character|integer|line|natural|positive|real|register|severity|signal|signed|std_logic|std_logic_vector|string||text|time|unsigned|variable",n="array|constant",r="abs|and|mod|nand|nor|not|rem|rol|ror|sla|sll|srasrl|xnor|xor",i="true|false|null",s=this.createKeywordMapper({"keyword.operator":r,keyword:e,"constant.language":i,"storage.modifier":n,"storage.type":t},"identifier",!0);this.$rules={start:[{token:"comment",regex:"--.*$"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"constant.numeric",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"keyword",regex:"\\s*(?:library|package|use)\\b"},{token:s,regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"&|\\*|\\+|\\-|\\/|<|=|>|\\||=>|\\*\\*|:=|\\/=|>=|<=|<>"},{token:"punctuation.operator",regex:"\\'|\\:|\\,|\\;|\\."},{token:"paren.lparen",regex:"[[(]"},{token:"paren.rparen",regex:"[\\])]"},{token:"text",regex:"\\s+"}]}};r.inherits(s,i),t.VHDLHighlightRules=s}),ace.define("ace/mode/vhdl",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/vhdl_highlight_rules","ace/range"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./vhdl_highlight_rules").VHDLHighlightRules,o=e("../range").Range,u=function(){this.HighlightRules=s};r.inherits(u,i),function(){this.lineCommentStart="--",this.$id="ace/mode/vhdl"}.call(u.prototype),t.Mode=u})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-xml.js b/dist/assets/js/vendor/ace-nc/mode-xml.js
            new file mode 100644
            index 0000000000..f03e532ca0
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-xml.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(e){this.$rules={start:[{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\[",next:"cdata"},{token:["punctuation.xml-decl.xml","keyword.xml-decl.xml"],regex:"(<\\?)(xml)(?=[\\s])",next:"xml_decl",caseInsensitive:!0},{token:["punctuation.instruction.xml","keyword.instruction.xml"],regex:"(<\\?)([-_a-zA-Z0-9]+)",next:"processing_instruction"},{token:"comment.xml",regex:"<\\!--",next:"comment"},{token:["xml-pe.doctype.xml","xml-pe.doctype.xml"],regex:"(<\\!)(DOCTYPE)(?=[\\s])",next:"doctype",caseInsensitive:!0},{include:"tag"},{token:"text.end-tag-open.xml",regex:"</"},{token:"text.tag-open.xml",regex:"<"},{include:"reference"},{defaultToken:"text.xml"}],xml_decl:[{token:"entity.other.attribute-name.decl-attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.decl-attribute-equals.xml",regex:"="},{include:"whitespace"},{include:"string"},{token:"punctuation.xml-decl.xml",regex:"\\?>",next:"start"}],processing_instruction:[{token:"punctuation.instruction.xml",regex:"\\?>",next:"start"},{defaultToken:"instruction.xml"}],doctype:[{include:"whitespace"},{include:"string"},{token:"xml-pe.doctype.xml",regex:">",next:"start"},{token:"xml-pe.xml",regex:"[-_a-zA-Z0-9:]+"},{token:"punctuation.int-subset",regex:"\\[",push:"int_subset"}],int_subset:[{token:"text.xml",regex:"\\s+"},{token:"punctuation.int-subset.xml",regex:"]",next:"pop"},{token:["punctuation.markup-decl.xml","keyword.markup-decl.xml"],regex:"(<\\!)([-_a-zA-Z0-9]+)",push:[{token:"text",regex:"\\s+"},{token:"punctuation.markup-decl.xml",regex:">",next:"pop"},{include:"string"}]}],cdata:[{token:"string.cdata.xml",regex:"\\]\\]>",next:"start"},{token:"text.xml",regex:"\\s+"},{token:"text.xml",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment.xml",regex:"-->",next:"start"},{defaultToken:"comment.xml"}],reference:[{token:"constant.language.escape.reference.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],attr_reference:[{token:"constant.language.escape.reference.attribute-value.xml",regex:"(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)"}],tag:[{token:["meta.tag.punctuation.tag-open.xml","meta.tag.punctuation.end-tag-open.xml","meta.tag.tag-name.xml"],regex:"(?:(<)|(</))((?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+)",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start"}]}],tag_whitespace:[{token:"text.tag-whitespace.xml",regex:"\\s+"}],whitespace:[{token:"text.whitespace.xml",regex:"\\s+"}],string:[{token:"string.xml",regex:"'",push:[{token:"string.xml",regex:"'",next:"pop"},{defaultToken:"string.xml"}]},{token:"string.xml",regex:'"',push:[{token:"string.xml",regex:'"',next:"pop"},{defaultToken:"string.xml"}]}],attributes:[{token:"entity.other.attribute-name.xml",regex:"(?:[-_a-zA-Z0-9]+:)?[-_a-zA-Z0-9]+"},{token:"keyword.operator.attribute-equals.xml",regex:"="},{include:"tag_whitespace"},{include:"attribute_value"}],attribute_value:[{token:"string.attribute-value.xml",regex:"'",push:[{token:"string.attribute-value.xml",regex:"'",next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]},{token:"string.attribute-value.xml",regex:'"',push:[{token:"string.attribute-value.xml",regex:'"',next:"pop"},{include:"attr_reference"},{defaultToken:"string.attribute-value.xml"}]}]},this.constructor===s&&this.normalizeRules()};(function(){this.embedTagRules=function(e,t,n){this.$rules.tag.unshift({token:["meta.tag.punctuation.tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(<)("+n+"(?=\\s|>|$))",next:[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:t+"start"}]}),this.$rules[n+"-end"]=[{include:"attributes"},{token:"meta.tag.punctuation.tag-close.xml",regex:"/?>",next:"start",onMatch:function(e,t,n){return n.splice(0),this.token}}],this.embedRules(e,t,[{token:["meta.tag.punctuation.end-tag-open.xml","meta.tag."+n+".tag-name.xml"],regex:"(</)("+n+"(?=\\s|>|$))",next:n+"-end"},{token:"string.cdata.xml",regex:"<\\!\\[CDATA\\["},{token:"string.cdata.xml",regex:"\\]\\]>"}])}}).call(i.prototype),r.inherits(s,i),t.XmlHighlightRules=s}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/folding/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/range","ace/mode/folding/fold_mode","ace/token_iterator"],function(e,t,n){"use strict";function l(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../../lib/lang"),s=e("../../range").Range,o=e("./fold_mode").FoldMode,u=e("../../token_iterator").TokenIterator,a=t.FoldMode=function(e,t){o.call(this),this.voidElements=r.mixin(e||{},t||{})};r.inherits(a,o);var f=function(){this.tagName="",this.closing=!1,this.selfClosing=!1,this.start={row:0,column:0},this.end={row:0,column:0}};(function(){this.getFoldWidget=function(e,t,n){var r=this._getFirstTagInLine(e,n);return r?r.closing||!r.tagName&&r.selfClosing?t=="markbeginend"?"end":"":!r.tagName||r.selfClosing||this.voidElements.hasOwnProperty(r.tagName.toLowerCase())?"":this._findEndTagInLine(e,n,r.tagName,r.end.column)?"":"start":""},this._getFirstTagInLine=function(e,t){var n=e.getTokens(t),r=new f;for(var i=0;i<n.length;i++){var s=n[i];if(l(s,"tag-open")){r.end.column=r.start.column+s.value.length,r.closing=l(s,"end-tag-open"),s=n[++i];if(!s)return null;r.tagName=s.value,r.end.column+=s.value.length;for(i++;i<n.length;i++){s=n[i],r.end.column+=s.value.length;if(l(s,"tag-close")){r.selfClosing=s.value=="/>";break}}return r}if(l(s,"tag-close"))return r.selfClosing=s.value=="/>",r;r.start.column+=s.value.length}return null},this._findEndTagInLine=function(e,t,n,r){var i=e.getTokens(t),s=0;for(var o=0;o<i.length;o++){var u=i[o];s+=u.value.length;if(s<r)continue;if(l(u,"end-tag-open")){u=i[o+1];if(u&&u.value==n)return!0}}return!1},this._readTagForward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do if(l(t,"tag-open"))n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn();else if(l(t,"tag-name"))n.tagName=t.value;else if(l(t,"tag-close"))return n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length,e.stepForward(),n;while(t=e.stepForward());return null},this._readTagBackward=function(e){var t=e.getCurrentToken();if(!t)return null;var n=new f;do{if(l(t,"tag-open"))return n.closing=l(t,"end-tag-open"),n.start.row=e.getCurrentTokenRow(),n.start.column=e.getCurrentTokenColumn(),e.stepBackward(),n;l(t,"tag-name")?n.tagName=t.value:l(t,"tag-close")&&(n.selfClosing=t.value=="/>",n.end.row=e.getCurrentTokenRow(),n.end.column=e.getCurrentTokenColumn()+t.value.length)}while(t=e.stepBackward());return null},this._pop=function(e,t){while(e.length){var n=e[e.length-1];if(!t||n.tagName==t.tagName)return e.pop();if(this.voidElements.hasOwnProperty(t.tagName))return;if(this.voidElements.hasOwnProperty(n.tagName)){e.pop();continue}return null}},this.getFoldWidgetRange=function(e,t,n){var r=this._getFirstTagInLine(e,n);if(!r)return null;var i=r.closing||r.selfClosing,o=[],a;if(!i){var f=new u(e,n,r.start.column),l={row:n,column:r.start.column+r.tagName.length+2};while(a=this._readTagForward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(a.closing){this._pop(o,a);if(o.length==0)return s.fromPoints(l,a.start)}else o.push(a)}}else{var f=new u(e,n,r.end.column),c={row:n,column:r.start.column};while(a=this._readTagBackward(f)){if(a.selfClosing){if(!o.length)return a.start.column+=a.tagName.length+2,a.end.column-=2,s.fromPoints(a.start,a.end);continue}if(!a.closing){this._pop(o,a);if(o.length==0)return a.start.column+=a.tagName.length+2,s.fromPoints(a.start,c)}else o.push(a)}}}}).call(a.prototype)}),ace.define("ace/mode/xml",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/xml_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/xml"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("./text").Mode,o=e("./xml_highlight_rules").XmlHighlightRules,u=e("./behaviour/xml").XmlBehaviour,a=e("./folding/xml").FoldMode,f=function(){this.HighlightRules=o,this.$behaviour=new u,this.foldingRules=new a};r.inherits(f,s),function(){this.voidElements=i.arrayToMap([]),this.blockComment={start:"<!--",end:"-->"},this.$id="ace/mode/xml"}.call(f.prototype),t.Mode=f})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-xquery.js b/dist/assets/js/vendor/ace-nc/mode-xquery.js
            new file mode 100644
            index 0000000000..4203caa7f2
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-xquery.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/xquery/xquery_lexer",["require","exports","module"],function(e,t,n){n.exports=function r(t,n,i){function s(u,a){if(!n[u]){if(!t[u]){var f=typeof e=="function"&&e;if(!a&&f)return f(u,!0);if(o)return o(u,!0);throw new Error("Cannot find module '"+u+"'")}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return s(n?n:e)},l,l.exports,r,t,n,i)}return n[u].exports}var o=typeof e=="function"&&e;for(var u=0;u<i.length;u++)s(i[u]);return s}({1:[function(e,t,n){var r=n.XQueryTokenizer=function i(e,t){function r(e,t){E=t,S=e,x=e.length,s(0,0,0)}function s(e,t,n){m=t,g=t,y=e,b=t,w=n,N=n,E.reset(S)}function o(){E.startNonterminal("EQName",g);switch(y){case 77:f(77);break;case 91:f(91);break;case 115:f(115);break;case 116:f(116);break;case 119:f(119);break;case 140:f(140);break;case 147:f(147);break;case 160:f(160);break;case 180:f(180);break;case 186:f(186);break;case 211:f(211);break;case 221:f(221);break;case 222:f(222);break;case 238:f(238);break;case 239:f(239);break;case 248:f(248);break;default:u()}E.endNonterminal("EQName",g)}function u(){E.startNonterminal("FunctionName",g);switch(y){case 14:f(14);break;case 65:f(65);break;case 68:f(68);break;case 69:f(69);break;case 70:f(70);break;case 74:f(74);break;case 75:f(75);break;case 79:f(79);break;case 83:f(83);break;case 84:f(84);break;case 85:f(85);break;case 88:f(88);break;case 89:f(89);break;case 98:f(98);break;case 100:f(100);break;case 103:f(103);break;case 104:f(104);break;case 105:f(105);break;case 106:f(106);break;case 107:f(107);break;case 108:f(108);break;case 113:f(113);break;case 114:f(114);break;case 117:f(117);break;case 118:f(118);break;case 121:f(121);break;case 123:f(123);break;case 124:f(124);break;case 126:f(126);break;case 129:f(129);break;case 130:f(130);break;case 131:f(131);break;case 132:f(132);break;case 141:f(141);break;case 143:f(143);break;case 145:f(145);break;case 146:f(146);break;case 148:f(148);break;case 154:f(154);break;case 155:f(155);break;case 157:f(157);break;case 158:f(158);break;case 159:f(159);break;case 165:f(165);break;case 167:f(167);break;case 169:f(169);break;case 173:f(173);break;case 175:f(175);break;case 176:f(176);break;case 177:f(177);break;case 179:f(179);break;case 181:f(181);break;case 193:f(193);break;case 195:f(195);break;case 196:f(196);break;case 197:f(197);break;case 201:f(201);break;case 207:f(207);break;case 208:f(208);break;case 213:f(213);break;case 214:f(214);break;case 215:f(215);break;case 219:f(219);break;case 224:f(224);break;case 230:f(230);break;case 231:f(231);break;case 232:f(232);break;case 243:f(243);break;case 244:f(244);break;case 245:f(245);break;case 249:f(249);break;case 251:f(251);break;case 255:f(255);break;case 261:f(261);break;case 265:f(265);break;case 269:f(269);break;case 67:f(67);break;case 76:f(76);break;case 78:f(78);break;case 80:f(80);break;case 81:f(81);break;case 86:f(86);break;case 93:f(93);break;case 96:f(96);break;case 97:f(97);break;case 99:f(99);break;case 101:f(101);break;case 120:f(120);break;case 127:f(127);break;case 128:f(128);break;case 136:f(136);break;case 149:f(149);break;case 150:f(150);break;case 156:f(156);break;case 166:f(166);break;case 187:f(187);break;case 194:f(194);break;case 198:f(198);break;case 217:f(217);break;case 220:f(220);break;case 223:f(223);break;case 229:f(229);break;case 235:f(235);break;case 246:f(246);break;case 247:f(247);break;case 252:f(252);break;case 256:f(256);break;case 257:f(257);break;case 258:f(258);break;case 262:f(262);break;case 92:f(92);break;case 171:f(171);break;default:f(216)}E.endNonterminal("FunctionName",g)}function a(){E.startNonterminal("NCName",g);switch(y){case 26:f(26);break;case 65:f(65);break;case 70:f(70);break;case 74:f(74);break;case 75:f(75);break;case 79:f(79);break;case 83:f(83);break;case 84:f(84);break;case 85:f(85);break;case 89:f(89);break;case 100:f(100);break;case 104:f(104);break;case 108:f(108);break;case 113:f(113);break;case 117:f(117);break;case 118:f(118);break;case 121:f(121);break;case 123:f(123);break;case 126:f(126);break;case 132:f(132);break;case 141:f(141);break;case 143:f(143);break;case 145:f(145);break;case 146:f(146);break;case 155:f(155);break;case 157:f(157);break;case 158:f(158);break;case 159:f(159);break;case 167:f(167);break;case 169:f(169);break;case 173:f(173);break;case 175:f(175);break;case 176:f(176);break;case 181:f(181);break;case 193:f(193);break;case 195:f(195);break;case 196:f(196);break;case 215:f(215);break;case 219:f(219);break;case 231:f(231);break;case 232:f(232);break;case 243:f(243);break;case 244:f(244);break;case 249:f(249);break;case 261:f(261);break;case 265:f(265);break;case 68:f(68);break;case 69:f(69);break;case 77:f(77);break;case 88:f(88);break;case 91:f(91);break;case 98:f(98);break;case 103:f(103);break;case 105:f(105);break;case 106:f(106);break;case 107:f(107);break;case 114:f(114);break;case 115:f(115);break;case 116:f(116);break;case 119:f(119);break;case 124:f(124);break;case 129:f(129);break;case 130:f(130);break;case 131:f(131);break;case 140:f(140);break;case 147:f(147);break;case 148:f(148);break;case 154:f(154);break;case 160:f(160);break;case 165:f(165);break;case 177:f(177);break;case 179:f(179);break;case 180:f(180);break;case 186:f(186);break;case 197:f(197);break;case 201:f(201);break;case 207:f(207);break;case 208:f(208);break;case 211:f(211);break;case 213:f(213);break;case 214:f(214);break;case 221:f(221);break;case 222:f(222);break;case 224:f(224);break;case 230:f(230);break;case 238:f(238);break;case 239:f(239);break;case 245:f(245);break;case 248:f(248);break;case 251:f(251);break;case 255:f(255);break;case 257:f(257);break;case 269:f(269);break;case 67:f(67);break;case 76:f(76);break;case 78:f(78);break;case 80:f(80);break;case 81:f(81);break;case 86:f(86);break;case 93:f(93);break;case 96:f(96);break;case 97:f(97);break;case 99:f(99);break;case 101:f(101);break;case 120:f(120);break;case 127:f(127);break;case 128:f(128);break;case 136:f(136);break;case 149:f(149);break;case 150:f(150);break;case 156:f(156);break;case 166:f(166);break;case 187:f(187);break;case 194:f(194);break;case 198:f(198);break;case 217:f(217);break;case 220:f(220);break;case 223:f(223);break;case 229:f(229);break;case 235:f(235);break;case 246:f(246);break;case 247:f(247);break;case 252:f(252);break;case 256:f(256);break;case 258:f(258);break;case 262:f(262);break;case 92:f(92);break;case 171:f(171);break;default:f(216)}E.endNonterminal("NCName",g)}function f(e){y==e?(l(),E.terminal(i.TOKEN[y],b,w>x?x:w),m=b,g=w,y=0):d(b,w,0,y,e)}function l(){g!=b&&(m=g,g=b,E.whitespace(m,g))}function c(e){var t;for(;;){t=C(e);if(t!=28)break}return t}function h(e){y==0&&(y=c(e),b=T,w=N)}function p(e){y==0&&(y=C(e),b=T,w=N)}function d(e,t,r,i,s){throw new n.ParseException(e,t,r,i,s)}function C(e){var t=!1;T=N;var n=N,r=i.INITIAL[e],s=0;for(var o=r&4095;o!=0;){var u,a=n<x?S.charCodeAt(n):0;++n;if(a<128)u=i.MAP0[a];else if(a<55296){var f=a>>4;u=i.MAP1[(a&15)+i.MAP1[(f&31)+i.MAP1[f>>5]]]}else{if(a<56320){var f=n<x?S.charCodeAt(n):0;f>=56320&&f<57344&&(++n,a=((a&1023)<<10)+(f&1023)+65536,t=!0)}var l=0,c=5;for(var h=3;;h=c+l>>1){if(i.MAP2[h]>a)c=h-1;else{if(!(i.MAP2[6+h]<a)){u=i.MAP2[12+h];break}l=h+1}if(l>c){u=0;break}}}s=o;var p=(u<<12)+o-1;o=i.TRANSITION[(p&15)+i.TRANSITION[p>>4]],o>4095&&(r=o,o&=4095,N=n)}r>>=12;if(r==0){N=n-1;var f=N<x?S.charCodeAt(N):0;return f>=56320&&f<57344&&--N,d(T,N,s,-1,-1)}if(t)for(var v=r>>9;v>0;--v){--N;var f=N<x?S.charCodeAt(N):0;f>=56320&&f<57344&&--N}else N-=r>>9;return(r&511)-1}r(e,t);var n=this;this.ParseException=function(e,t,n,r,i){var s=e,o=t,u=n,a=r,f=i;this.getBegin=function(){return s},this.getEnd=function(){return o},this.getState=function(){return u},this.getExpected=function(){return f},this.getOffending=function(){return a},this.getMessage=function(){return a<0?"lexical analysis failed":"syntax error"}},this.getInput=function(){return S},this.getOffendingToken=function(e){var t=e.getOffending();return t>=0?i.TOKEN[t]:null},this.getExpectedTokenSet=function(e){var t;return e.getExpected()<0?t=i.getTokenSet(-e.getState()):t=[i.TOKEN[e.getExpected()]],t},this.getErrorMessage=function(e){var t=this.getExpectedTokenSet(e),n=this.getOffendingToken(e),r=S.substring(0,e.getBegin()),i=r.split("\n"),s=i.length,o=i[s-1].length+1,u=e.getEnd()-e.getBegin();return e.getMessage()+(n==null?"":", found "+n)+"\nwhile expecting "+(t.length==1?t[0]:"["+t.join(", ")+"]")+"\n"+(u==0||n!=null?"":"after successfully scanning "+u+" characters beginning ")+"at line "+s+", column "+o+":\n..."+S.substring(e.getBegin(),Math.min(S.length,e.getBegin()+64))+"..."},this.parse_start=function(){E.startNonterminal("start",g),h(14);switch(y){case 55:f(55);break;case 54:f(54);break;case 56:f(56);break;case 40:f(40);break;case 42:f(42);break;case 41:f(41);break;case 35:f(35);break;case 38:f(38);break;case 274:f(274);break;case 271:f(271);break;case 39:f(39);break;case 43:f(43);break;case 49:f(49);break;case 62:f(62);break;case 63:f(63);break;case 46:f(46);break;case 48:f(48);break;case 53:f(53);break;case 51:f(51);break;case 34:f(34);break;case 273:f(273);break;case 2:f(2);break;case 1:f(1);break;case 3:f(3);break;case 12:f(12);break;case 13:f(13);break;case 15:f(15);break;case 16:f(16);break;case 17:f(17);break;case 5:f(5);break;case 6:f(6);break;case 4:f(4);break;case 33:f(33);break;default:o()}E.endNonterminal("start",g)},this.parse_StartTag=function(){E.startNonterminal("StartTag",g),h(8);switch(y){case 58:f(58);break;case 50:f(50);break;case 27:f(27);break;case 57:f(57);break;case 35:f(35);break;case 38:f(38);break;default:f(33)}E.endNonterminal("StartTag",g)},this.parse_TagContent=function(){E.startNonterminal("TagContent",g),p(11);switch(y){case 23:f(23);break;case 6:f(6);break;case 7:f(7);break;case 55:f(55);break;case 54:f(54);break;case 18:f(18);break;case 29:f(29);break;case 272:f(272);break;case 275:f(275);break;case 271:f(271);break;default:f(33)}E.endNonterminal("TagContent",g)},this.parse_AposAttr=function(){E.startNonterminal("AposAttr",g),p(10);switch(y){case 20:f(20);break;case 25:f(25);break;case 18:f(18);break;case 29:f(29);break;case 272:f(272);break;case 275:f(275);break;case 271:f(271);break;case 38:f(38);break;default:f(33)}E.endNonterminal("AposAttr",g)},this.parse_QuotAttr=function(){E.startNonterminal("QuotAttr",g),p(9);switch(y){case 19:f(19);break;case 24:f(24);break;case 18:f(18);break;case 29:f(29);break;case 272:f(272);break;case 275:f(275);break;case 271:f(271);break;case 35:f(35);break;default:f(33)}E.endNonterminal("QuotAttr",g)},this.parse_CData=function(){E.startNonterminal("CData",g),p(1);switch(y){case 11:f(11);break;case 64:f(64);break;default:f(33)}E.endNonterminal("CData",g)},this.parse_XMLComment=function(){E.startNonterminal("XMLComment",g),p(0);switch(y){case 9:f(9);break;case 47:f(47);break;default:f(33)}E.endNonterminal("XMLComment",g)},this.parse_PI=function(){E.startNonterminal("PI",g),p(3);switch(y){case 10:f(10);break;case 59:f(59);break;case 60:f(60);break;default:f(33)}E.endNonterminal("PI",g)},this.parse_Pragma=function(){E.startNonterminal("Pragma",g),p(2);switch(y){case 8:f(8);break;case 36:f(36);break;case 37:f(37);break;default:f(33)}E.endNonterminal("Pragma",g)},this.parse_Comment=function(){E.startNonterminal("Comment",g),p(4);switch(y){case 52:f(52);break;case 41:f(41);break;case 30:f(30);break;default:f(33)}E.endNonterminal("Comment",g)},this.parse_CommentDoc=function(){E.startNonterminal("CommentDoc",g),p(5);switch(y){case 31:f(31);break;case 32:f(32);break;case 52:f(52);break;case 41:f(41);break;default:f(33)}E.endNonterminal("CommentDoc",g)},this.parse_QuotString=function(){E.startNonterminal("QuotString",g),p(6);switch(y){case 18:f(18);break;case 29:f(29);break;case 19:f(19);break;case 21:f(21);break;case 35:f(35);break;default:f(33)}E.endNonterminal("QuotString",g)},this.parse_AposString=function(){E.startNonterminal("AposString",g),p(7);switch(y){case 18:f(18);break;case 29:f(29);break;case 20:f(20);break;case 22:f(22);break;case 38:f(38);break;default:f(33)}E.endNonterminal("AposString",g)},this.parse_Prefix=function(){E.startNonterminal("Prefix",g),h(13),l(),a(),E.endNonterminal("Prefix",g)},this.parse__EQName=function(){E.startNonterminal("_EQName",g),h(12),l(),o(),E.endNonterminal("_EQName",g)};var v,m,g,y,b,w,E,S,x,T,N};r.getTokenSet=function(e){var t=[],n=e<0?-e:INITIAL[e]&4095;for(var i=0;i<276;i+=32){var s=i,o=(i>>5)*2062+n-1,u=o>>2,a=u>>2,f=r.EXPECTED[(o&3)+r.EXPECTED[(u&3)+r.EXPECTED[(a&3)+r.EXPECTED[a>>2]]]];for(;f!=0;f>>>=1,++s)(f&1)!=0&&t.push(r.TOKEN[s])}return t},r.MAP0=[66,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,18,18,18,18,18,18,18,18,19,20,21,22,23,24,25,26,27,28,29,30,27,31,31,31,31,31,31,31,31,31,31,32,31,31,33,31,31,31,31,31,31,34,35,36,35,31,35,37,38,39,40,41,42,43,44,45,31,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,31,61,62,63,64,35],r.MAP1=[108,124,214,214,214,214,214,214,214,214,214,214,214,214,214,214,156,181,181,181,181,181,214,215,213,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,247,261,277,293,309,347,363,379,416,416,416,408,331,323,331,323,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,433,433,433,433,433,433,433,316,331,331,331,331,331,331,331,331,394,416,416,417,415,416,416,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,330,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,416,66,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,18,18,18,18,18,18,18,18,19,20,21,22,23,24,25,26,27,28,29,30,27,31,31,31,31,31,31,31,31,31,31,31,31,31,31,35,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,32,31,31,33,31,31,31,31,31,31,34,35,36,35,31,35,37,38,39,40,41,42,43,44,45,31,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,31,61,62,63,64,35,35,35,35,35,35,35,35,35,35,35,35,31,31,35,35,35,35,35,35,35,65,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65],r.MAP2=[57344,63744,64976,65008,65536,983040,63743,64975,65007,65533,983039,1114111,35,31,35,31,31,35],r.INITIAL=[1,2,36867,45060,5,6,7,8,9,10,11,12,13,14,15],r.TRANSITION=[17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22908,18836,17152,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,17365,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,17470,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,18157,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,17848,17880,18731,17918,36551,17292,17934,17979,18727,18023,36545,18621,18039,18056,18072,18117,18143,18173,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17687,18805,18421,18437,18101,17393,18489,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,18579,21711,17152,19008,19233,20367,19008,28684,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,17365,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,17470,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,18157,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,17848,17880,18731,17918,36551,17292,17934,17979,18727,18023,36545,18621,18039,18056,18072,18117,18143,18173,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17687,18805,18421,18437,18101,17393,18489,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,20116,18836,18637,19008,19233,21267,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,18763,18778,18794,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,18821,22923,18906,19008,19233,17431,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18937,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,19054,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,18953,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21843,18836,18987,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21696,18836,18987,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22429,20131,18720,19008,19233,20367,19008,17173,23559,36437,17330,17349,18921,17189,17208,17281,20355,18087,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,21242,19111,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,19024,18836,18609,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,19081,22444,18987,19008,19233,20367,19008,19065,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21992,22007,18987,19008,19233,20367,19008,18690,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22414,18836,18987,19008,19233,30651,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,19138,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,19280,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,19172,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21783,18836,18987,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,19218,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21651,18836,18987,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,19249,19265,19307,18888,27857,30536,24401,31444,23357,18888,19351,18888,18890,27211,19370,27211,27211,19392,24401,31911,24401,24401,25467,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,28537,19440,24401,24401,24401,24401,24036,17994,24060,18888,18888,18888,18890,19468,27211,27211,27211,27211,19484,35367,19520,24401,24401,24401,19628,18888,29855,18888,18888,23086,27211,19538,27211,27211,30756,24012,24401,19560,24401,24401,26750,18888,18888,19327,27855,27211,27211,19580,17590,24017,24401,24401,19600,25665,18888,18888,28518,27211,27212,24016,19620,19868,28435,25722,18889,19644,27211,32888,35852,19868,31018,19694,19376,19717,22215,19735,22098,19751,35203,19776,19797,19817,19840,25783,31738,24135,19701,19856,31015,23516,31008,28311,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21768,18836,19307,18888,27857,27904,24401,29183,28015,18888,18888,18888,18890,27211,27211,27211,27211,19888,24401,24401,24401,24401,22953,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,28537,19440,24401,24401,24401,24401,24036,18881,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,24012,24401,24401,24401,24401,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22399,18836,19918,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21666,18836,19307,18888,27857,27525,24401,29183,21467,18888,18888,18888,18890,27211,27211,27211,27211,19946,24401,24401,24401,24401,32382,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,28537,19998,24401,24401,24401,24401,31500,18467,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,20021,24401,24401,24401,24401,24401,34271,18888,18888,18888,18888,23086,27211,27211,27211,27211,32926,29908,24401,24401,24401,24401,26095,18888,18888,18888,27855,27211,27211,27211,20050,22968,24401,24401,24401,18887,18888,18888,27211,27211,35779,20080,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,20101,19039,20191,20412,20903,17569,20309,20872,25633,20623,20505,20218,20242,17189,17208,17281,20355,20265,20306,20328,20383,22490,20796,20619,21354,20654,20410,20956,21232,20765,17421,20535,17192,18127,22459,20312,25531,22470,20309,20428,18964,20466,20491,21342,21070,20521,20682,17714,18326,17543,17559,17585,22497,20559,19504,20279,20575,20290,20475,20604,20639,20226,20670,17661,21190,17703,21176,17730,19494,20698,20711,22480,21046,21116,18971,21130,20727,20755,17675,17753,17832,17590,25518,20394,20781,20831,20202,20847,21401,17292,17934,17979,18549,20863,20588,25542,20888,20919,18072,18117,20935,20972,21032,21062,21086,18239,21102,18563,21146,21162,21206,18351,20949,20902,18340,21222,21258,21283,18360,20249,17405,21295,21311,21327,20739,20343,21370,21386,21417,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21977,18836,18987,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,21452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,21504,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,36501,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,28674,21946,17617,36473,18223,17237,17477,19152,17860,17892,17675,17753,17832,21575,21534,17481,19156,17864,18731,17918,36551,17292,17934,21560,30628,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21798,18836,21612,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21636,18836,18987,19008,19233,17902,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21753,19096,21903,19008,19233,20367,19008,19291,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,17379,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,21931,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,18280,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21962,18594,18987,19008,19233,22043,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21681,21858,18987,19008,19233,20367,19008,21544,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,18888,27857,34097,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,30613,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,31500,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,32319,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,21431,24401,24401,24401,24401,26095,18888,18888,18888,27855,27211,27211,27211,22187,22968,24401,24401,24401,22231,18888,18888,27211,27211,35779,20080,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,18888,27857,34097,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,30613,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,31500,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,31181,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,21431,24401,24401,24401,24401,26095,18888,18888,18888,27855,27211,27211,27211,22187,22968,24401,24401,24401,18887,18888,18888,27211,27211,35779,20080,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,18888,27857,34097,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,31678,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,31500,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,31181,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,21431,24401,24401,24401,24401,26095,18888,18888,18888,27855,27211,27211,27211,22187,22968,24401,24401,24401,18887,18888,18888,27211,27211,35779,20080,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,18888,27857,34097,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,30613,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,33588,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,31181,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,21431,24401,24401,24401,24401,26095,18888,18888,18888,27855,27211,27211,27211,22187,22968,24401,24401,24401,18887,18888,18888,27211,27211,35779,20080,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,18888,27857,35019,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22248,24401,24401,24401,24401,30613,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,31500,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,31181,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,21431,24401,24401,24401,24401,26095,18888,18888,18888,27855,27211,27211,27211,22187,22968,24401,24401,24401,18887,18888,18888,27211,27211,35779,20080,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,18888,27857,34097,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,18866,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,24036,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,24012,24401,24401,24401,24401,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22324,18836,22059,18888,27857,30501,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,18866,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,24036,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,24012,24401,24401,24401,24401,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,18888,27857,34097,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,18866,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,24036,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,24012,24401,24401,24401,24401,34365,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22354,18836,18987,19008,19233,20367,19008,17173,27086,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,19930,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21828,18836,18987,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22309,22513,18987,19008,19233,20367,19008,19122,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,22544,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22608,18836,22988,23004,27585,23020,23036,23067,22087,18888,18888,18888,23083,27211,27211,27211,23102,22121,24401,24401,24401,23122,31386,26154,19674,18888,28119,28232,19424,23705,27211,27211,23142,23173,23189,23212,24401,24401,23246,34427,31693,23262,18888,23290,23308,27783,27620,23327,35263,35107,33383,23346,18193,23393,32748,23968,24401,23414,35153,23463,18888,33913,23442,23482,27211,27211,23532,23552,21431,23575,24401,24401,23604,26095,23635,23657,18888,33482,23685,33251,27211,22187,18851,23721,35536,24401,18887,23750,32641,27211,23769,23787,20080,33012,24384,25659,18888,18889,27211,27211,19719,23889,23803,31018,18890,27211,31833,19406,19447,23086,23330,19828,28224,31826,23823,26917,34978,23850,26493,25782,23878,23914,23516,31008,22105,19419,27963,19659,29781,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22623,18836,22059,18888,27857,34097,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,30613,18888,18888,18888,18888,28909,25783,27211,27211,27211,34048,23933,22164,24401,24401,24401,28409,23949,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,31181,26583,18888,18888,18888,35585,23984,27211,27211,27211,24005,22201,24033,24401,24401,24401,24052,18888,18888,18888,27855,27211,27211,27211,22187,22968,24401,24401,24401,18887,18888,18888,27211,27211,35779,20080,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,26496,24076,24126,24151,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22638,18836,22059,19678,27857,24185,24401,24201,24217,26592,18888,18888,18890,24252,24268,27211,27211,22121,24287,24303,24401,24401,30613,19781,35432,36007,32649,18888,25783,24322,28966,23771,27211,35072,22164,24358,32106,26829,24400,31500,31693,18888,18888,18888,24801,18890,27211,27211,27211,27211,24418,19484,24401,24401,24401,24401,20167,31181,18888,18888,18888,27833,23086,27211,27211,33540,27211,30756,21431,24401,24401,22972,24401,26095,18888,36131,18888,27855,27211,24440,27211,22187,22968,24401,24459,24401,31699,28454,18888,34528,34570,35779,24478,24402,24494,25659,18888,36228,27211,27211,24515,30981,23734,31018,18890,27211,31833,19406,19447,23086,23330,24538,31017,27856,31741,30059,23377,24563,19837,25782,19760,31015,23516,25374,22105,19419,29793,24579,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22653,18836,22059,25756,19982,34097,23196,29183,24614,24110,23641,24673,26103,24697,24443,24713,28558,22121,24748,24462,24764,23398,30613,18888,18888,18888,18888,24798,25783,27211,27211,27211,34232,35072,22164,24401,24401,24401,33302,31500,22559,24106,24232,18888,18888,34970,24817,30411,27211,27211,32484,19484,29750,35127,24401,24401,19872,31181,24852,18888,18888,24871,29221,27211,27211,32072,27211,30756,34441,24401,24401,31571,24401,26095,33141,27802,27011,27855,25295,25607,24888,22187,22968,19195,34593,24906,18887,18888,18888,27211,27211,35779,20080,24402,19868,25659,18888,33663,27211,27211,24924,24947,23588,31018,18890,27211,31833,22135,19447,23086,23330,19828,30904,31042,24972,19840,25e3,31738,30898,25782,19760,31015,23516,31008,22105,19419,25016,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22668,18836,25041,25057,31320,25073,25089,25105,22087,34796,24236,36138,34870,34125,25121,23106,35497,22248,36613,25137,30671,27365,30613,25153,26447,25199,25233,22574,23274,25249,25265,25281,25318,25344,25360,25400,25428,25452,26731,25504,31693,23669,25558,27407,25575,28599,25934,25599,27211,28180,27304,25623,25839,25649,24401,34820,25681,25698,22586,27775,30190,25745,25778,25799,25817,28995,33569,30756,21518,33443,25837,25855,25893,26095,31254,26677,30136,27855,25930,25950,27211,22187,22968,25966,25986,24401,23428,27763,36330,26959,26002,26029,26045,26085,26119,26170,26203,26222,26239,30527,26372,26274,28404,31018,33757,27211,34262,26316,36729,26345,26366,35337,31017,26388,26407,30954,26350,33861,26434,26463,26479,26512,23516,33189,26531,26547,27963,31293,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22683,18836,26568,26181,26608,34097,26643,29183,22087,26669,18888,18888,18890,26693,27211,27211,27211,22121,26720,24401,24401,24401,30613,18888,18888,18888,18888,26774,25783,27211,27211,27211,26619,35072,22164,24401,24401,24401,21596,31500,31693,18888,18888,33978,18888,18890,27211,27211,25801,27211,27211,19484,24401,24401,24401,26792,24401,31181,18888,18888,18888,35464,23086,27211,27211,27211,26809,30756,21431,24401,24401,24401,26828,26095,18888,18888,18888,27855,27211,27211,27211,22187,22968,24401,24401,24401,18887,18888,18888,27211,27211,35779,20080,24402,19868,25659,31948,18889,35707,27211,19719,26845,19868,31018,18890,27211,31833,19406,19447,23086,23330,26905,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,24984,31088,19419,26945,27651,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22698,18836,26999,18888,27857,34097,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,23051,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,27033,24401,24401,24401,24401,24036,31693,18888,18888,27056,18888,18890,27211,27211,30320,27211,27211,27075,24401,24401,29032,24401,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,24012,24401,24401,24401,24401,26750,18888,18888,33986,27855,27211,27211,27102,17590,24017,24401,24401,27123,27144,36254,27162,27210,27228,28500,18187,34842,33426,27244,35980,27277,27302,27320,36048,34013,20999,31882,21478,27895,27356,30287,27381,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,26329,30087,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,27406,27423,27445,35294,27461,22087,18888,18888,30140,18890,27211,27211,27989,27211,22121,24401,24401,25682,24401,18866,18888,18888,18888,18888,18888,34042,27211,27211,27211,27211,29700,22164,24401,24401,24401,24401,27128,31693,27477,18888,18888,18888,18890,27194,27211,27211,27211,27211,19484,35299,24401,24401,24401,24401,19628,18888,18888,18888,27059,23086,27211,27211,27211,33366,30756,24012,24401,24401,24401,35044,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,20815,27211,30818,19960,33969,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22713,18836,22059,27496,27516,27541,35231,27557,22087,29662,26292,23292,27573,24836,27601,27211,27636,22121,35544,27686,24401,27721,18866,18888,27799,18888,27818,22071,27853,32260,27211,26013,27873,27920,22164,29419,24401,29946,33413,26742,27751,26881,18888,18888,27261,36776,27936,27211,27211,27211,27988,28005,28031,28052,24401,24401,28069,28088,28135,25488,28152,26069,28167,27211,28340,24657,28196,30756,31523,24401,28212,34176,36174,24956,28248,28266,28290,21488,33077,28327,28356,17590,20986,23126,28391,28425,28102,28451,28470,28490,28516,28534,20034,33728,25868,25659,18888,18889,27211,27211,19719,23889,19868,30241,28274,28553,28574,19406,28590,23086,23330,19828,19452,28615,28660,26147,25783,31738,19837,25782,19760,29613,35958,29276,22105,19419,27963,23157,28700,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,18888,27857,34097,24401,29183,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,18866,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,24036,22528,18888,18888,18888,18888,18890,27333,27211,27211,27211,27211,19484,30853,24401,24401,24401,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,24012,24401,24401,24401,24401,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22728,18836,28747,28782,28817,28841,28857,28880,28896,24161,28943,32011,36261,27340,28961,29492,28982,29011,24522,29027,25436,29048,23051,27500,29090,29110,30713,18888,23512,29130,25183,27211,29155,28927,27033,29173,23230,24401,29199,35373,31693,18888,18888,25583,32629,29218,27211,27211,31461,30692,29237,27075,24401,24401,24401,29262,29302,19628,18888,34329,18888,18888,23086,27211,29329,27211,27211,30756,24012,35933,24401,24401,24401,27705,31612,18888,18888,29346,29374,27211,35650,17590,21436,29393,24401,25970,18887,33895,18888,27211,32528,27212,24016,32769,19868,25659,18888,26889,27211,27211,29412,23889,24371,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31768,19840,25783,31738,19837,29435,29508,31102,29550,29606,22105,30300,29462,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22743,18836,22059,29629,29473,34097,33285,29183,29651,27254,18888,29678,33329,32535,27211,29694,29716,22121,19202,24401,32742,29741,18866,26776,33921,28474,18888,18888,25783,29766,27211,29809,27211,35072,22164,35825,24401,29828,24401,24036,36769,25217,18888,18888,29848,18890,27211,29871,27211,26258,27211,29894,24401,29929,24401,36587,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,29725,29962,24401,24401,24401,24401,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18473,18888,18888,19584,27211,27212,24016,29982,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19902,19447,32052,19544,19828,29998,30097,30031,19840,25783,30047,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,30075,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22758,18836,30121,30156,30206,30257,30273,30336,22087,35624,32837,25762,18890,29878,34934,26812,27211,22121,24931,23223,29202,24401,18866,34373,30352,18888,18888,18888,23447,24828,27211,27211,27211,35072,30370,35052,24401,24401,24401,24036,29523,18888,18888,27146,18888,31308,30386,27211,27211,30405,30558,19484,30427,24401,24401,29938,35686,19628,28766,30447,34506,35614,23086,28731,30482,30517,30552,30756,24012,20156,30574,30598,30667,26283,33464,28945,27670,30687,32915,33504,25328,17590,23963,20450,33837,21016,32397,26300,30708,30729,27885,30748,21588,36373,30779,26653,24628,33220,32514,30806,31835,25412,25906,26515,18890,28825,31833,26133,19447,28304,31730,23834,26057,30869,30885,32181,30920,30942,32797,25782,30970,31015,23516,31008,30997,31034,27963,19659,29450,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22773,18836,31058,31074,32463,31125,31141,31197,22087,18888,29534,35471,36738,27211,24342,31213,24424,22121,24401,20175,31229,31917,27736,31245,34334,27175,18888,29094,27286,27211,31278,31336,27211,31355,31371,24401,31402,31418,24401,31437,31693,18888,31619,32841,18888,18890,27211,27211,31460,31477,27211,19484,24401,24401,31497,36581,24401,33020,18888,18888,18888,18888,30007,27211,27211,27211,27211,31516,32310,24401,24401,24401,24401,31539,18888,28762,18888,24651,35740,27211,27211,28644,31565,35796,24401,24401,19318,32188,18888,24334,28366,27212,29966,29832,19868,25659,18888,18889,27211,27211,19719,31587,19868,31635,32435,33693,30105,31663,20005,31715,31757,31784,31812,30015,31851,31878,25783,31898,19837,25782,19760,31015,23516,31008,22105,19419,27963,31933,30221,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22788,18836,22059,25729,30466,31968,24306,31984,32e3,32807,35160,27017,29590,34941,19801,29377,33700,22121,27040,30431,29396,28864,29565,18888,18888,18888,32027,18888,25783,27211,27211,23698,27211,35072,22164,24401,24401,30845,24401,24036,32045,18888,26929,18888,18888,18890,27211,31481,32068,27211,27211,32088,24401,33058,32122,24401,24401,33736,18888,18888,33162,18888,23086,27211,27211,29484,27211,28375,32144,24401,24401,33831,24401,26750,18888,18888,18888,27855,27211,27211,27211,36704,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,33107,22171,33224,24271,32169,31017,27856,31741,19840,25783,31738,30234,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,32204,32232,32252,32677,33295,29074,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,23619,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,32276,24401,24401,24401,24401,24036,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,32299,24401,24401,24401,24401,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,24012,24401,24401,24401,24401,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,33886,18889,36065,27211,19719,35326,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22803,18836,32335,31647,34666,32351,32367,32417,22087,18888,32433,19335,32451,27211,32479,27107,32500,22121,24401,32551,20085,32572,18866,22287,23753,18888,18888,32602,32665,27211,32693,27211,26972,32713,32729,24401,32764,24401,25877,32785,34768,18888,27390,32823,24594,24855,32857,24890,32878,32904,27211,32942,32977,24401,33e3,29313,24401,30790,26206,27666,33904,18888,23086,36353,27211,33036,27211,30756,24012,32153,24401,33056,24401,35861,18888,18888,30354,27972,27211,27211,33800,17590,20145,24401,24401,34638,20811,18888,18888,33074,27211,27212,36167,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,34616,24169,33093,33123,33157,27856,31741,23862,26552,34302,19837,25782,19760,31015,23516,31008,33178,19973,27963,23497,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22818,18836,33205,28113,33240,34097,33275,29183,22087,33318,35438,18888,18890,33345,26391,33382,27211,22121,33399,28072,33442,24401,18866,22232,18888,33459,18888,18888,33480,33498,25175,27211,27211,26704,22164,24775,35239,24401,24401,25914,29580,18888,18888,31109,25211,33520,33539,27211,27211,33556,36284,19484,33585,24401,24401,33604,32556,19628,18888,18888,31262,33658,23086,27211,27211,33679,27211,30756,24012,24401,24401,33716,24401,26854,27480,18888,33752,27855,33259,34701,27211,17590,32102,24782,23807,24401,18887,18888,18888,27211,27211,27212,33773,36105,19868,25659,18888,23368,27211,29157,19719,23889,34454,29286,18890,33794,25302,33816,19447,34079,33853,31862,31017,27856,31741,33877,28920,33937,19837,30461,34002,22276,36041,34029,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22833,18836,34064,32616,34113,34141,34157,34192,34208,32216,36013,31549,31952,34224,34248,34287,29330,34350,34389,34413,34481,26793,18866,26187,29635,22293,18888,36654,25783,34522,34544,34566,25821,35072,22164,34586,34609,34632,19604,24036,36644,36674,24681,18888,32401,34654,31339,34682,34698,27211,34717,34753,28053,34812,34836,24401,33619,19628,34858,32236,34906,24598,33523,27612,34890,34922,24732,29246,36717,33634,34465,32984,34168,26750,34957,18888,18888,34994,35010,27211,33040,17590,29913,35035,24401,36304,25482,30171,35883,35068,35088,26627,20441,31173,35123,35143,35176,24640,30492,29358,19719,35192,35219,25384,28801,35255,35279,32586,34496,23086,23330,29061,31017,27856,31741,19840,25783,31738,24547,25164,35315,31796,35353,34316,22105,19419,27963,24091,28630,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22848,18836,22059,34782,34088,35389,21008,35405,35421,35454,18888,18888,23466,35487,27211,27211,27211,35513,31154,24401,24401,24401,35560,18888,26863,36664,35601,24872,25783,30389,23536,26250,35647,35666,22164,19522,19564,30582,35682,27697,35575,29114,18888,18888,18888,18890,27211,35702,27211,27211,27211,35723,24401,35527,24401,24401,24401,19628,30184,18888,18888,18888,23086,35739,27211,27211,27211,29139,22938,24401,24401,24401,24401,23898,35756,18888,18888,25025,35778,27211,27211,17590,20064,35795,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,23917,18890,34550,31833,22262,19447,23086,23330,26418,31017,27856,31741,19840,25783,35812,19837,27187,35841,33135,23516,31008,22105,22148,28712,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22863,18836,22059,35877,28723,34097,31164,29183,22087,26758,18888,22592,18890,23989,27211,29812,27211,22121,33778,24401,31421,24401,18866,18888,18888,26872,18888,18888,25783,27211,30732,27211,27211,35072,22164,24401,24908,24401,24401,24036,31693,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,24012,24401,24401,24401,24401,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22878,18836,22059,27837,27857,35899,24401,35915,22087,18888,18888,18888,18890,27211,27211,27211,27211,22121,24401,24401,24401,24401,18866,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,24036,31602,18888,18888,18888,18888,26223,27211,27211,27211,27211,27211,19484,35931,24401,24401,24401,24401,19628,18888,28136,18888,18888,35949,27211,32862,27211,32697,30756,24012,24401,32283,24401,32128,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22893,18836,22059,35974,34882,34097,33960,29183,35996,18888,23311,18888,36029,27211,27211,36064,36081,22121,24401,24401,36104,33950,18866,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,35072,22164,24401,24401,24401,24401,24036,36121,18888,25559,18888,18888,18890,27211,27211,30313,27211,27211,36154,24401,24401,34397,24401,24401,19628,28250,18888,18888,18888,23086,30926,27211,27211,27211,26983,24012,33642,24401,24401,24401,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22339,18836,22059,19354,27857,36190,24401,36206,22087,18888,18888,18888,18007,27211,27211,27211,24724,22121,24401,24401,24401,30827,18866,18888,36222,18888,28795,18888,25783,35100,27211,27429,27211,35072,22164,30836,24401,24499,24401,24036,31693,18888,36244,18888,18888,18890,27211,36088,27211,27211,27211,19484,24401,28036,24401,24401,24401,19628,18888,18888,35631,18888,35762,27211,27211,36277,27211,34730,24012,24401,24401,36300,24401,36320,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,25712,18888,18888,36346,27211,27212,19184,24402,19868,25659,32029,18889,27211,33359,19719,23889,36369,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22384,18836,36389,19008,19233,20367,36434,17173,17595,36437,17330,17349,18921,17189,17208,17281,20355,36453,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,20362,21726,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,22369,18836,18987,19008,19233,20367,19008,21737,30763,36437,17330,17349,18921,17189,17208,17281,20355,17949,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21813,18836,36489,19008,19233,20367,19008,17173,17737,36437,17330,17349,18921,17189,17208,17281,20355,17768,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,20543,22022,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21828,18836,18987,19008,19233,20367,19008,17173,30763,36437,17330,17349,18921,17189,17208,17281,20355,36517,17308,17327,17346,18918,18452,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,18127,21873,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,21828,18836,19307,18888,27857,30756,24401,29183,28015,18888,18888,18888,18890,27211,27211,27211,27211,36567,24401,24401,24401,24401,22953,18888,18888,18888,18888,18888,25783,27211,27211,27211,27211,28537,36603,24401,24401,24401,24401,24036,18881,18888,18888,18888,18888,18890,27211,27211,27211,27211,27211,19484,24401,24401,24401,24401,24401,19628,18888,18888,18888,18888,23086,27211,27211,27211,27211,30756,24012,24401,24401,24401,24401,26750,18888,18888,18888,27855,27211,27211,27211,17590,24017,24401,24401,24401,18887,18888,18888,27211,27211,27212,24016,24402,19868,25659,18888,18889,27211,27211,19719,23889,19868,31018,18890,27211,31833,19406,19447,23086,23330,19828,31017,27856,31741,19840,25783,31738,19837,25782,19760,31015,23516,31008,22105,19419,27963,19659,27951,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,36629,36690,18720,19008,19233,20367,19008,17454,17595,36437,17330,17349,18921,17189,17208,17281,20355,17223,17308,17327,17346,18918,36754,21880,18649,18665,19006,17265,22033,20765,17421,20535,17192,20362,21726,17311,18658,18999,19008,17447,32952,17497,17520,17251,36411,17782,20682,17714,18326,17543,17559,17585,21887,17504,17527,17258,36418,21915,21940,17611,36467,18217,17633,17661,21190,17703,21176,17730,34737,21946,17617,36473,18223,36531,17477,19152,17860,17892,17675,17753,17832,17590,21620,17481,19156,17864,18731,17918,36551,17292,17934,17979,18727,18681,18405,18621,18039,18056,18072,18117,18143,18706,18052,18209,18250,18239,18266,17963,18296,18312,18376,17807,36403,19232,17796,17163,30642,18392,17816,32961,17645,18805,18421,18437,18519,17393,18747,18505,18535,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,17590,0,94242,0,118820,0,2211840,102439,0,0,106538,98347,0,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2482176,2158592,2158592,2158592,2158592,2158592,2158592,0,40976,0,18,18,24,24,27,27,27,2207744,2404352,2412544,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,3104768,2605056,2207744,2207744,2207744,2207744,2207744,2207744,2678784,2207744,2695168,2207744,2703360,2207744,2711552,2752512,2207744,0,0,0,0,0,0,2166784,0,0,0,0,0,0,2158592,2158592,3170304,3174400,2158592,0,139,0,2158592,2158592,2158592,2158592,2158592,2424832,2158592,2158592,2158592,2748416,2756608,2777088,2801664,2158592,2158592,2158592,2863104,2891776,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,3104768,2158592,2158592,2158592,2158592,2158592,2158592,2207744,2785280,2207744,2809856,2207744,2207744,2842624,2207744,2207744,2207744,2899968,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2473984,2207744,2207744,2494464,2207744,2207744,2207744,2523136,2158592,2404352,2412544,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2564096,2158592,2158592,2605056,2158592,2158592,2158592,2158592,2158592,2158592,2678784,2158592,2695168,2158592,2703360,2158592,2711552,2752512,2158592,2158592,2785280,2158592,2158592,2785280,2158592,2809856,2158592,2158592,2842624,2158592,2158592,2158592,2899968,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,18,0,0,0,0,0,0,0,2211840,0,0,641,0,2158592,0,0,0,0,0,0,0,0,2211840,0,0,32768,0,2158592,0,2158592,2158592,2158592,2383872,2158592,2158592,2158592,2158592,3006464,2383872,2207744,2207744,2207744,2207744,2158877,2158877,2158877,2158877,0,0,0,2158877,2572573,2158877,2158877,0,2207744,2207744,2596864,2207744,2207744,2207744,2207744,2207744,2207744,2641920,2207744,2207744,2207744,2207744,2207744,2207744,2207744,0,0,0,167936,0,0,2162688,0,0,3104768,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,0,0,0,2146304,2146304,2224128,2224128,2232320,2232320,2232320,641,0,0,0,0,0,0,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2531328,2158592,2158592,2158592,2158592,2158592,2617344,2158592,2158592,2158592,2158592,2441216,2445312,2158592,2158592,2158592,2158592,2158592,2158592,2502656,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2580480,2158592,2158592,2158592,2158592,2621440,2158592,2580480,2158592,2158592,2158592,2158592,2621440,2158592,2158592,2158592,2158592,2158592,2158592,2699264,2158592,2158592,2158592,2158592,2158592,2748416,2756608,2777088,2801664,2207744,2863104,2891776,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,3018752,2207744,3043328,2207744,2207744,2207744,2207744,3080192,2207744,2207744,3112960,2207744,2207744,2207744,2207744,2207744,2207744,2207744,0,0,0,172310,279,0,2162688,0,0,2207744,2207744,2207744,3186688,2207744,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2158592,2158592,2158592,2404352,2412544,2158592,2510848,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2584576,2158592,2609152,2158592,2158592,2629632,2158592,2158592,2158592,2686976,2158592,2715648,2158592,2158592,3121152,2158592,2158592,2158592,3149824,2158592,2158592,3170304,3174400,2158592,2367488,2207744,2207744,2207744,2207744,2158592,2158592,2158592,2158592,0,0,0,2158592,2572288,2158592,2158592,0,2207744,2207744,2207744,2433024,2207744,2453504,2461696,2207744,2207744,2207744,2207744,2207744,2207744,2510848,2207744,2207744,2207744,2207744,2207744,2531328,2207744,2207744,2207744,2207744,2207744,2617344,2207744,2207744,2207744,2207744,2158592,2158592,2158592,2158592,0,0,0,2158592,2572288,2158592,2158592,1508,2715648,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2867200,2207744,2904064,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2580480,2207744,2207744,2207744,2207744,2621440,2207744,2207744,2207744,3149824,2207744,2207744,3170304,3174400,2207744,0,0,0,0,0,0,0,0,0,0,138,2158592,2158592,2158592,2404352,2412544,2707456,2732032,2207744,2207744,2207744,2822144,2826240,2207744,2895872,2207744,2207744,2924544,2207744,2207744,2973696,2207744,0,0,0,0,0,0,2166784,0,0,0,0,0,285,2158592,2158592,3112960,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,3186688,2158592,2207744,2207744,2158592,2158592,2158592,2158592,2158592,0,0,0,2158592,2158592,2158592,2158592,0,0,2535424,2543616,2158592,2158592,2158592,0,0,0,2158592,2158592,2158592,2990080,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2572288,2981888,2207744,2207744,3002368,2207744,3047424,3063808,3076096,2207744,2207744,2207744,2207744,2207744,2207744,2207744,3203072,2708960,2732032,2158592,2158592,2158592,2822144,2827748,2158592,2895872,2158592,2158592,2924544,2158592,2158592,2973696,2158592,2981888,2158592,2158592,3002368,2158592,3047424,3063808,3076096,2158592,2158592,2158592,2158592,2158592,2158592,2158592,3203072,2981888,2158592,2158592,3003876,2158592,3047424,3063808,3076096,2158592,2158592,2158592,2158592,2158592,2158592,2158592,3203072,2207744,2207744,2207744,2207744,2207744,2424832,2207744,2207744,2207744,2207744,2207744,2207744,2207744,20480,0,0,0,0,0,2162688,20480,0,2523136,2527232,2158592,2158592,2576384,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2908160,2527232,2207744,2207744,2576384,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2908160,2207744,0,0,0,0,0,0,2166784,0,0,0,0,0,286,2158592,2158592,0,0,2158592,2158592,2158592,2158592,2633728,2658304,0,0,2740224,2744320,0,2834432,2207744,2207744,2977792,2207744,2207744,2207744,2207744,3039232,2207744,2207744,2207744,2207744,2207744,2207744,3158016,0,0,29315,0,0,0,0,45,45,45,45,45,933,45,45,45,45,442,45,45,45,45,45,45,45,45,45,67,67,2494464,2158592,2158592,2158592,2524757,2527232,2158592,2158592,2576384,2158592,2158592,2158592,2158592,2158592,2158592,1504,2158592,2498560,2158592,2158592,2158592,2158592,2568192,2158592,2592768,2625536,2158592,2158592,2674688,2736128,2158592,2158592,0,2158592,2912256,2158592,2158592,2158592,2158592,2158592,2158592,2158592,3108864,2158592,2158592,3133440,3145728,3153920,2375680,2379776,2207744,2207744,2420736,2207744,2449408,2207744,2207744,2207744,2498560,2207744,2207744,2207744,2207744,2568192,2207744,0,0,0,0,0,0,2166784,0,0,0,0,0,551,2158592,2158592,2158592,2158592,2207744,2506752,2207744,2207744,2207744,2207744,2207744,2158592,2506752,0,2020,2158592,2592768,2625536,2207744,2207744,2674688,2736128,2207744,2207744,2207744,2912256,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,0,542,0,544,2207744,3108864,2207744,2207744,3133440,3145728,3153920,2375680,2379776,2158592,2158592,2420736,2158592,2449408,2158592,2158592,2158592,2158592,2158592,3186688,2158592,0,641,0,0,0,0,0,0,2367488,2158592,2498560,2158592,2158592,1621,2158592,2158592,2568192,2158592,2592768,2625536,2158592,2158592,2674688,0,0,0,0,0,1608,97,97,97,97,97,97,97,97,97,97,1107,97,97,1110,97,97,3133440,3145728,3153920,2158592,2408448,2416640,2158592,2465792,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,3014656,2158592,2158592,3051520,2158592,2158592,3100672,2158592,2158592,3121152,2158592,2158592,2158592,3149824,2416640,2207744,2465792,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2633728,2658304,2740224,2744320,2834432,2949120,2158592,2985984,2158592,2998272,2158592,2158592,2158592,3129344,2207744,2408448,2949120,2207744,2985984,2207744,2998272,2207744,2207744,2207744,3129344,2158592,2408448,2416640,2158592,2465792,2158592,2158592,2158592,2158592,2158592,3186688,2158592,0,32768,0,0,0,0,0,0,2367488,2949120,2158592,2985984,2158592,2998272,2158592,2158592,2158592,3129344,2158592,2158592,2478080,2158592,2158592,2158592,2535424,2543616,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,3117056,2207744,2207744,2478080,2207744,2207744,2207744,2207744,2699264,2207744,2207744,2207744,2207744,2207744,2748416,2756608,2777088,2801664,2207744,2207744,2158877,2158877,2158877,2158877,2158877,0,0,0,2158877,2158877,2158877,2158877,0,0,2535709,2543901,2158877,2158877,2158877,0,0,0,2158877,2158877,2158877,2990365,2158877,2158877,2158730,2158730,2158730,2158730,2158730,2572426,2207744,2535424,2543616,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,3117056,2158592,2158592,2478080,2207744,2207744,2990080,2207744,2207744,2158592,2158592,2482176,2158592,2158592,0,0,0,2158592,2158592,2158592,0,2158592,2908160,2158592,2158592,2158592,2977792,2158592,2158592,2158592,2158592,3039232,2158592,2158592,3010560,2207744,2428928,2207744,2514944,2207744,2588672,2207744,2838528,2207744,2207744,2207744,3010560,2158592,2428928,2158592,2514944,0,0,2158592,2588672,2158592,0,2838528,2158592,2158592,2158592,3010560,2158592,2506752,2158592,18,0,0,0,0,0,0,0,2211840,0,0,0,0,2158592,0,0,29315,922,0,0,0,45,45,45,45,45,45,45,45,45,45,45,45,45,1539,45,3006464,2383872,0,2020,2158592,2158592,2158592,2158592,3006464,2158592,2637824,2953216,2158592,2207744,2637824,2953216,2207744,0,0,2158592,2637824,2953216,2158592,2539520,2158592,2539520,2207744,0,0,2539520,2158592,2158592,2158592,2158592,2207744,2506752,2207744,2207744,2207744,2207744,2207744,2158592,2506752,0,0,2158592,2207744,0,2158592,2158592,2207744,0,2158592,2158592,2207744,0,2158592,2965504,2965504,2965504,0,0,0,0,0,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2474269,2158877,2158877,0,0,2158877,2158877,2158877,2158877,2634013,2658589,0,0,2740509,2744605,0,2834717,40976,18,36884,45078,24,28,90143,94242,118820,102439,106538,98347,118820,118820,118820,40976,18,18,36884,0,0,0,24,24,24,27,27,27,27,90143,0,0,86016,0,0,2211840,102439,0,0,0,98347,0,2158592,2158592,2158592,2158592,2158592,3158016,0,2375680,2379776,2158592,2158592,2420736,2158592,2449408,2158592,2158592,0,94242,0,0,0,2211840,102439,0,0,106538,98347,135,2158592,2158592,2158592,2158592,2158592,2158592,2564096,2158592,2158592,2158592,2158592,2158592,2596864,2158592,2158592,2158592,2158592,2158592,2158592,2641920,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2781184,2793472,2494464,2158592,2158592,2158592,2523136,2527232,2158592,2158592,2576384,2158592,2158592,2158592,2158592,2158592,2158592,0,40976,0,18,18,24,0,27,27,0,2158592,2498560,2158592,2158592,0,2158592,2158592,2568192,2158592,2592768,2625536,2158592,2158592,2674688,0,0,0,0,0,2211840,0,0,0,0,0,0,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2473984,2158592,2158592,2494464,2158592,2158592,2158592,3006464,2383872,0,0,2158592,2158592,2158592,2158592,3006464,2158592,2637824,2953216,2158592,2207744,2637824,2953216,40976,18,36884,45078,24,27,147488,94242,147456,147488,106538,98347,0,0,147456,40976,18,18,36884,0,45078,0,24,24,24,27,27,27,27,0,81920,0,94242,0,0,0,2211840,0,0,0,106538,98347,0,2158592,2158592,2158592,2158592,2158592,2158592,2428928,2158592,2514944,2158592,2588672,2158592,2838528,2158592,2158592,40976,18,151573,45078,24,27,90143,94242,0,102439,106538,98347,0,0,0,40976,18,18,36884,0,45078,0,24,24,24,27,27,27,27,90143,0,0,1315,0,97,97,97,97,97,97,97,97,97,97,1487,97,18,131427,0,0,0,0,0,0,362,0,0,365,29315,367,0,0,29315,0,0,0,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,130,94242,0,0,0,2211840,102439,0,0,106538,98347,0,2158592,2158592,2158592,2158592,2158592,2158592,3096576,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2207744,2207744,2158592,18,0,0,0,0,0,0,0,2211840,0,0,0,0,2158592,644,2207744,2207744,2207744,3186688,2207744,0,1080,0,1084,0,1088,0,0,0,0,0,0,0,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2531466,2158730,2158730,2158730,2158730,2158730,2617482,0,94242,0,0,0,2211840,102439,0,0,106538,98347,0,2158592,2158592,2158592,2158592,2158592,2781184,2793472,2158592,2818048,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,40976,18,36884,45078,24,27,90143,159779,159744,102439,159779,98347,0,0,159744,40976,18,18,36884,0,45078,0,2224253,172032,2224253,2232448,2232448,172032,2232448,90143,0,0,2170880,0,0,550,829,2158592,2158592,2158592,2387968,2158592,2158592,2158592,2158592,2158592,2158592,0,40976,0,18,18,124,124,127,127,127,40976,18,36884,45078,25,29,90143,94242,0,102439,106538,98347,0,0,163931,40976,18,18,36884,0,45078,249856,24,24,24,27,27,27,27,90143,0,0,2170880,0,0,827,0,2158592,2158592,2158592,2387968,2158592,2158592,2158592,2158592,2158592,2158592,0,40976,0,4243810,4243810,24,24,27,27,27,2207744,0,0,0,0,0,0,2166784,0,0,0,0,57344,286,2158592,2158592,2158592,2158592,2707456,2732032,2158592,2158592,2158592,2822144,2826240,2158592,2895872,2158592,2158592,2924544,2158592,2158592,2973696,2158592,2207744,2207744,2207744,3186688,2207744,0,0,0,0,0,0,53248,0,0,0,0,0,97,97,97,97,97,1613,97,97,97,97,97,97,1495,97,97,97,97,97,97,97,97,97,566,97,97,97,97,97,97,2207744,0,0,0,0,0,0,2166784,546,0,0,0,0,286,2158592,2158592,2158592,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,17,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,20480,120,121,18,18,36884,0,45078,0,24,24,24,27,27,27,27,90143,0,0,2170880,0,53248,550,0,2158592,2158592,2158592,2387968,2158592,2158592,2158592,2158592,2158592,2158592,0,40976,196608,18,266240,24,24,27,27,27,0,94242,0,0,0,38,102439,0,0,106538,98347,0,45,45,45,45,45,45,45,1535,45,45,45,45,45,45,45,1416,45,45,45,45,45,45,45,45,424,45,45,45,45,45,45,45,45,45,405,45,45,45,45,45,45,45,45,45,45,45,45,45,199,45,45,67,67,67,67,67,491,67,67,67,67,67,67,67,67,67,67,67,1766,67,67,67,1767,67,24850,24850,12564,12564,0,0,2166784,546,0,53531,53531,0,286,97,97,0,0,97,97,97,97,97,97,0,0,97,97,0,97,97,97,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,743,57889,0,2170880,0,0,550,0,97,97,97,97,97,97,97,97,97,45,45,45,45,45,45,45,45,1856,45,1858,1859,67,67,67,1009,67,67,67,67,67,67,67,67,67,67,67,1021,67,67,67,67,67,25398,0,13112,0,54074,0,0,0,0,0,0,0,0,0,2367773,2158877,2158877,2158877,2158877,2158877,2158877,2699549,2158877,2158877,2158877,2158877,2158877,2748701,2756893,2777373,2801949,97,1115,97,97,97,97,97,97,97,97,97,97,97,97,97,97,857,97,67,67,67,67,67,1258,67,67,67,67,67,67,67,67,67,67,67,1826,67,97,97,97,97,97,97,1338,97,97,97,97,97,97,97,97,97,97,97,97,97,870,97,97,67,67,67,1463,67,67,67,67,67,67,67,67,67,67,67,67,67,1579,67,67,97,97,97,1518,97,97,97,97,97,97,97,97,97,97,97,97,97,904,905,97,97,97,97,1620,97,97,97,97,97,97,97,97,97,97,97,0,921,0,0,0,0,0,0,45,1679,67,67,67,1682,67,67,67,67,67,67,67,67,67,1690,67,0,0,97,97,97,97,45,45,67,67,0,0,97,97,45,45,45,669,45,45,45,45,45,45,45,45,45,45,45,45,189,45,45,45,1748,45,45,45,1749,1750,45,45,45,45,45,45,45,45,67,67,67,67,1959,67,67,67,67,1768,67,67,67,67,67,67,67,67,97,97,97,97,97,97,97,97,97,1791,97,97,97,97,97,97,97,97,45,45,45,45,45,45,1802,67,1817,67,67,67,67,67,67,1823,67,67,67,67,97,97,97,97,0,0,0,97,97,97,97,0,97,97,97,97,1848,45,45,45,45,45,45,45,45,45,45,45,659,45,45,45,45,45,45,45,1863,67,67,67,67,67,67,67,67,67,67,67,67,495,67,67,67,67,67,1878,97,97,97,97,0,0,0,97,97,97,97,0,0,97,97,97,97,97,0,0,0,97,97,97,97,97,97,45,45,45,45,45,45,45,45,45,67,67,67,67,97,97,97,97,0,0,0,1973,97,97,97,0,97,97,97,97,97,97,97,97,97,97,97,97,97,1165,97,1167,67,24850,24850,12564,12564,0,0,2166784,0,0,53531,53531,0,286,97,97,0,0,97,97,97,97,97,97,0,0,97,97,1789,97,0,94242,0,0,0,2211840,102439,0,0,106538,98347,136,2158592,2158592,2158592,2158592,2158592,3158016,229376,2375680,2379776,2158592,2158592,2420736,2158592,2449408,2158592,2158592,67,24850,24850,12564,12564,0,0,280,547,0,53531,53531,0,286,97,97,0,0,97,97,97,97,97,97,0,1788,97,97,0,97,2024,97,45,45,45,45,45,45,67,67,67,67,67,67,67,67,235,67,67,67,67,67,57889,547,547,0,0,550,0,97,97,97,97,97,97,97,97,97,45,45,45,1799,45,45,45,67,67,67,67,67,25398,0,13112,0,54074,0,0,1092,0,0,0,0,0,97,97,97,97,1612,97,97,97,97,1616,97,1297,1472,0,0,0,0,1303,1474,0,0,0,0,1309,1476,0,0,0,0,97,97,97,1481,97,97,97,97,97,97,1488,97,0,1474,0,1476,0,97,97,97,97,97,97,97,97,97,97,97,607,97,97,97,97,40976,18,36884,45078,26,30,90143,94242,0,102439,106538,98347,0,0,213080,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,143448,40976,18,18,36884,0,45078,0,24,24,24,27,27,27,27,0,0,0,0,97,97,97,97,1482,97,1483,97,97,97,97,97,97,1326,97,97,1329,1330,97,97,97,97,97,97,1159,1160,97,97,97,97,97,97,97,97,590,97,97,97,97,97,97,97,0,94242,0,0,0,2211974,102439,0,0,106538,98347,0,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2474122,2158730,2158730,2494602,2158730,2158730,2158730,2809994,2158730,2158730,2842762,2158730,2158730,2158730,2900106,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,3014794,2158730,2158730,3051658,2158730,2158730,3100810,2158730,2158730,2158730,2158730,3096714,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2207744,2207744,2207744,2207744,2207744,2572288,2207744,2207744,2207744,2207744,541,541,543,543,0,0,2166784,0,548,549,549,0,286,2158877,2158877,2158877,2863389,2892061,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,3186973,2158877,0,0,0,0,0,0,0,0,2367626,2158877,2404637,2412829,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2564381,2158877,2158877,2605341,2158877,2158877,2158877,2158877,2158877,2158877,2679069,2158877,2695453,2158877,2703645,2158877,2711837,2752797,2158877,0,2158877,2158877,2158877,2384010,2158730,2158730,2158730,2158730,3006602,2383872,2207744,2207744,2207744,2207744,2207744,2207744,3096576,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,0,0,0,0,0,0,2162688,0,0,2158877,2785565,2158877,2810141,2158877,2158877,2842909,2158877,2158877,2158877,2900253,2158877,2158877,2158877,2158877,2158877,2531613,2158877,2158877,2158877,2158877,2158877,2617629,2158877,2158877,2158877,2158877,2158730,2818186,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,3105053,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,0,0,0,0,0,97,97,97,1611,97,97,97,97,97,97,97,1496,97,97,1499,97,97,97,97,97,2441354,2445450,2158730,2158730,2158730,2158730,2158730,2158730,2502794,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2433162,2158730,2453642,2461834,2158730,2158730,2158730,2158730,2158730,2158730,2580618,2158730,2158730,2158730,2158730,2621578,2158730,2158730,2158730,2158730,2158730,2158730,2699402,2158730,2158730,2158730,2158730,2678922,2158730,2695306,2158730,2703498,2158730,2711690,2752650,2158730,2158730,2785418,2158730,2158730,2158730,3113098,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,3186826,2158730,2207744,2207744,2207744,2207744,2781184,2793472,2207744,2818048,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,0,541,0,543,2158877,2502941,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2580765,2158877,2158877,2158877,2158877,2621725,2158877,3019037,2158877,3043613,2158877,2158877,2158877,2158877,3080477,2158877,2158877,3113245,2158877,2158877,2158877,2158877,0,2158877,2908445,2158877,2158877,2158877,2978077,2158877,2158877,2158877,2158877,3039517,2158877,2158730,2510986,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2584714,2158730,2609290,2158730,2158730,2629770,2158730,2158730,2158730,2388106,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2605194,2158730,2158730,2158730,2158730,2687114,2158730,2715786,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2867338,2158730,2904202,2158730,2158730,2158730,2642058,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2781322,2793610,2158730,3121290,2158730,2158730,2158730,3149962,2158730,2158730,3170442,3174538,2158730,2367488,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2441216,2445312,2207744,2207744,2207744,2207744,2207744,2207744,2502656,2158877,2433309,2158877,2453789,2461981,2158877,2158877,2158877,2158877,2158877,2158877,2511133,2158877,2158877,2158877,2158877,2584861,2158877,2609437,2158877,2158877,2629917,2158877,2158877,2158877,2687261,2158877,2715933,2158877,2158730,2158730,2973834,2158730,2982026,2158730,2158730,3002506,2158730,3047562,3063946,3076234,2158730,2158730,2158730,2158730,2207744,2506752,2207744,2207744,2207744,2207744,2207744,2158877,2507037,0,0,2158877,2158730,2158730,2158730,3203210,2207744,2207744,2207744,2207744,2207744,2424832,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2564096,2207744,2207744,2207744,2707741,2732317,2158877,2158877,2158877,2822429,2826525,2158877,2896157,2158877,2158877,2924829,2158877,2158877,2973981,2158877,18,0,0,0,0,0,0,0,2211840,0,0,642,0,2158592,0,45,1529,45,45,45,45,45,45,45,45,45,45,45,45,45,1755,45,67,67,2982173,2158877,2158877,3002653,2158877,3047709,3064093,3076381,2158877,2158877,2158877,2158877,2158877,2158877,2158877,3203357,2523274,2527370,2158730,2158730,2576522,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2908298,2494749,2158877,2158877,2158877,2523421,2527517,2158877,2158877,2576669,2158877,2158877,2158877,2158877,2158877,2158877,0,40976,0,18,18,4321280,2224253,2232448,4329472,2232448,2158730,2498698,2158730,2158730,2158730,2158730,2568330,2158730,2592906,2625674,2158730,2158730,2674826,2736266,2158730,2158730,2158730,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2158730,2912394,2158730,2158730,2158730,2158730,2158730,2158730,2158730,3109002,2158730,2158730,3133578,3145866,3154058,2375680,2207744,3108864,2207744,2207744,3133440,3145728,3153920,2375965,2380061,2158877,2158877,2421021,2158877,2449693,2158877,2158877,2158877,3117341,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,3104906,2158730,2158730,2158730,2158730,2158730,2158730,2158877,2498845,2158877,2158877,0,2158877,2158877,2568477,2158877,2593053,2625821,2158877,2158877,2674973,0,0,0,0,97,97,1480,97,97,97,97,97,1485,97,97,97,0,97,97,1729,97,1731,97,97,97,97,97,97,97,311,97,97,97,97,97,97,97,97,1520,97,97,1523,97,97,1526,97,2736413,2158877,2158877,0,2158877,2912541,2158877,2158877,2158877,2158877,2158877,2158877,2158877,3109149,2158877,2158877,3014941,2158877,2158877,3051805,2158877,2158877,3100957,2158877,2158877,3121437,2158877,2158877,2158877,3150109,3133725,3146013,3154205,2158730,2408586,2416778,2158730,2465930,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,3018890,2158730,3043466,2158730,2158730,2158730,2158730,3080330,2633866,2658442,2740362,2744458,2834570,2949258,2158730,2986122,2158730,2998410,2158730,2158730,2158730,3129482,2207744,2408448,2949120,2207744,2985984,2207744,2998272,2207744,2207744,2207744,3129344,2158877,2408733,2416925,2158877,2466077,2158877,2158877,3170589,3174685,2158877,0,0,0,2158730,2158730,2158730,2158730,2158730,2424970,2158730,2158730,2158730,2158730,2707594,2732170,2158730,2158730,2158730,2822282,2826378,2158730,2896010,2158730,2158730,2924682,2949405,2158877,2986269,2158877,2998557,2158877,2158877,2158877,3129629,2158730,2158730,2478218,2158730,2158730,2158730,2535562,2543754,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,2158730,3117194,2207744,2207744,2478080,2207744,2207744,2207744,2207744,3014656,2207744,2207744,3051520,2207744,2207744,3100672,2207744,2207744,3121152,2207744,2207744,2207744,2207744,2207744,2584576,2207744,2609152,2207744,2207744,2629632,2207744,2207744,2207744,2686976,2207744,2207744,2535424,2543616,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,3117056,2158877,2158877,2478365,0,2158877,2158877,2158877,2158877,2158877,2158877,2158730,2158730,2482314,2158730,2158730,2158730,2158730,2158730,2158730,2207744,2207744,2207744,2387968,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,2207744,0,823,0,825,2158730,2158730,2158730,2990218,2158730,2158730,2207744,2207744,2482176,2207744,2207744,2207744,2207744,2207744,2207744,2207744,0,0,0,0,0,0,2162688,135,0,2207744,2207744,2990080,2207744,2207744,2158877,2158877,2482461,2158877,2158877,0,0,0,2158877,2158877,2158877,2158877,2158877,2158730,2429066,2158730,2515082,2158730,2588810,2158730,2838666,2158730,2158730,2158730,3010698,2207744,2428928,2207744,2514944,2207744,2588672,2207744,2838528,2207744,2207744,2207744,3010560,2158877,2429213,2158877,2515229,0,0,2158877,2588957,2158877,0,2838813,2158877,2158877,2158877,3010845,2158730,2506890,2158730,2158730,2158730,2748554,2756746,2777226,2801802,2158730,2158730,2158730,2863242,2891914,2158730,2158730,2158730,2158730,2158730,2158730,2564234,2158730,2158730,2158730,2158730,2158730,2597002,2158730,2158730,2158730,3006464,2384157,0,0,2158877,2158877,2158877,2158877,3006749,2158730,2637962,2953354,2158730,2207744,2637824,2953216,2207744,0,0,2158877,2638109,2953501,2158877,2539658,2158730,2539520,2207744,0,0,2539805,2158877,2158730,2158730,2158730,2977930,2158730,2158730,2158730,2158730,3039370,2158730,2158730,2158730,2158730,2158730,2158730,3158154,2207744,0,2158877,2158730,2207744,0,2158877,2158730,2207744,0,2158877,2965642,2965504,2965789,0,0,0,0,1315,0,0,0,0,97,97,97,97,97,97,97,1484,97,97,97,97,2158592,18,0,122880,0,0,0,77824,0,2211840,0,0,0,0,2158592,0,356,0,0,0,0,0,0,28809,0,139,45,45,45,45,45,45,1751,45,45,45,45,45,45,45,67,67,1427,67,67,67,67,67,1432,67,67,67,3104768,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,122880,0,0,0,0,1315,0,0,0,0,97,97,97,97,97,97,1322,550,0,286,0,2158592,2158592,2158592,2158592,2158592,2424832,2158592,2158592,2158592,2158592,2158592,2158592,0,40976,0,18,18,24,24,4329472,27,27,2207744,2207744,2977792,2207744,2207744,2207744,2207744,3039232,2207744,2207744,2207744,2207744,2207744,2207744,3158016,542,0,0,0,542,0,544,0,0,0,544,0,550,0,0,0,0,0,97,97,1610,97,97,97,97,97,97,97,97,898,97,97,97,97,97,97,97,0,94242,0,0,0,2211840,0,0,0,0,0,0,2158592,2158592,2158592,2158592,2158592,2424832,2158592,2158592,2158592,2158592,2158592,2158592,40976,18,36884,45078,24,27,90143,94242,237568,102439,106538,98347,0,0,20480,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,192512,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,94,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,96,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,12378,40976,18,18,36884,0,45078,0,24,24,24,126,126,126,126,90143,0,0,2170880,0,0,0,0,2158592,2158592,2158592,2387968,2158592,2158592,2158592,2158592,2158592,2158592,20480,40976,0,18,18,24,24,27,27,27,40976,18,36884,45078,24,27,90143,94242,241664,102439,106538,98347,0,0,20568,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,200797,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,20480,40976,18,36884,45078,24,27,90143,94242,0,0,0,44,0,0,20575,40976,18,36884,45078,24,27,90143,94242,0,41,41,41,0,0,1126400,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,0,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,89,40976,18,18,36884,0,45078,0,24,24,24,27,131201,27,27,90143,0,0,2170880,0,0,550,0,2158592,2158592,2158592,2387968,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2441216,2445312,2158592,2158592,2158592,2158592,2158592,0,94242,0,0,208896,2211840,102439,0,0,106538,98347,0,2158592,2158592,2158592,2158592,2158592,3186688,2158592,0,0,0,0,0,0,0,0,2367488,32768,0,0,0,0,0,0,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2433024,2158592,2453504,2461696,2158592,2158592,2158592,2158592,2158592,2158592,2510848,2158592,2158592,2158592,2158592,40976,18,36884,245783,24,27,90143,94242,0,102439,106538,98347,0,0,20480,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,221184,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,180224,40976,18,18,36884,155648,45078,0,24,24,217088,27,27,27,217088,90143,0,0,2170880,0,0,828,0,2158592,2158592,2158592,2387968,2158592,2158592,2158592,2158592,2158592,2158592,2207744,2207744,2207744,2387968,2207744,2207744,2207744,2207744,2207744,2207744,2207744,0,0,0,0,0,0,2162688,233472,0,0,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,45,45,45,718,45,45,45,45,45,45,45,45,45,727,131427,0,0,0,0,362,0,365,28809,367,139,45,45,45,45,45,45,1808,45,45,45,45,67,67,67,67,67,67,67,97,97,0,0,97,67,24850,24850,12564,12564,0,57889,0,0,0,53531,53531,367,286,97,97,0,0,97,97,97,97,97,97,1787,0,97,97,0,97,97,97,45,45,45,45,2029,45,67,67,67,67,2033,57889,0,0,54074,54074,550,0,97,97,97,97,97,97,97,97,97,45,1798,45,45,1800,45,45,0,1472,0,0,0,0,0,1474,0,0,0,0,0,1476,0,0,0,0,1315,0,0,0,0,97,97,97,97,1320,97,97,0,0,97,97,97,97,1786,97,0,0,97,97,0,1790,1527,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,663,67,24850,24850,12564,12564,0,57889,281,0,0,53531,53531,367,286,97,97,0,0,97,97,97,1785,97,97,0,0,97,97,0,97,97,1979,97,97,45,45,1983,45,1984,45,45,45,45,45,652,45,45,45,45,45,45,45,45,45,45,690,45,45,694,45,45,40976,19,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,262144,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,46,67,98,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,45,67,97,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,258048,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,1122423,40976,18,36884,45078,24,27,90143,94242,0,1114152,1114152,1114152,0,0,1114112,40976,18,36884,45078,24,27,90143,94242,37,102439,106538,98347,0,0,204800,40976,18,36884,45078,24,27,90143,94242,0,102439,106538,98347,0,0,57436,40976,18,36884,45078,24,27,33,33,0,33,33,33,0,0,0,40976,18,18,36884,0,45078,0,124,124,124,127,127,127,127,90143,0,0,2170880,0,0,550,0,2158877,2158877,2158877,2388253,2158877,2158877,2158877,2158877,2158877,2781469,2793757,2158877,2818333,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2867485,2158877,2904349,2158877,2158877,2158877,2158877,2158877,2158877,2158877,3096861,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2158877,2441501,2445597,2158877,2158877,2158877,2158877,2158877,40976,122,123,36884,0,45078,0,24,24,24,27,27,27,27,90143,0,921,29315,0,0,0,0,45,45,45,45,45,45,45,45,936,2158592,4243810,0,0,0,0,0,0,0,2211840,0,0,0,0,2158592,0,921,29315,0,0,0,0,45,45,45,45,45,45,45,935,45,45,45,715,45,45,45,45,45,45,45,723,45,45,45,45,45,1182,45,45,45,45,45,45,45,45,45,45,430,45,45,45,45,45,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,47,68,99,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,48,69,100,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,49,70,101,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,50,71,102,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,51,72,103,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,52,73,104,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,53,74,105,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,54,75,106,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,55,76,107,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,56,77,108,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,57,78,109,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,58,79,110,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,59,80,111,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,60,81,112,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,61,82,113,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,62,83,114,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,63,84,115,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,64,85,116,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,65,86,117,40976,18,36884,45078,24,27,90143,94242,38,102439,106538,98347,66,87,118,40976,18,36884,45078,24,27,90143,94242,118820,102439,106538,98347,118820,118820,118820,40976,18,18,0,0,45078,0,24,24,24,27,27,27,27,90143,0,0,1314,0,0,0,0,0,0,97,97,97,97,97,1321,97,18,131427,0,0,0,0,0,0,362,0,0,365,0,367,0,0,1315,0,97,97,97,97,97,97,97,97,97,97,97,97,97,1360,97,97,131,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,45,145,149,45,45,45,45,45,174,45,179,45,185,45,188,45,45,202,67,255,67,67,269,67,67,0,24850,12564,0,0,0,0,28809,53531,97,97,97,292,296,97,97,97,97,97,321,97,326,97,332,97,18,131427,0,0,0,0,0,0,362,0,0,365,29315,367,646,335,97,97,349,97,97,0,40976,0,18,18,24,24,27,27,27,437,45,45,45,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,523,67,67,67,67,67,67,67,67,67,67,67,67,511,67,67,67,97,97,97,620,97,97,97,97,97,97,97,97,97,97,97,97,97,1501,1502,97,793,67,67,796,67,67,67,67,67,67,67,67,67,67,808,67,0,0,97,97,97,97,45,45,67,67,0,0,97,97,2052,67,67,67,67,813,67,67,67,67,67,67,67,25398,542,13112,544,57889,0,0,54074,54074,550,830,97,97,97,97,97,97,97,97,97,315,97,97,97,97,97,97,841,97,97,97,97,97,97,97,97,97,854,97,97,97,97,97,97,589,97,97,97,97,97,97,97,97,97,867,97,97,97,97,97,97,97,891,97,97,894,97,97,97,97,97,97,97,97,97,97,906,45,937,45,45,940,45,45,45,45,45,45,948,45,45,45,45,45,734,735,67,737,67,738,67,740,67,67,67,45,967,45,45,45,45,45,45,45,45,45,45,45,45,45,45,435,45,45,45,980,45,45,45,45,45,45,45,45,45,45,45,45,45,415,45,45,67,67,1024,67,67,67,67,67,67,67,67,67,67,67,67,67,97,97,97,67,67,67,67,67,25398,1081,13112,1085,54074,1089,0,0,0,0,0,0,363,0,28809,0,139,45,45,45,45,45,45,1674,45,45,45,45,45,45,45,45,67,1913,67,1914,67,67,67,1918,67,67,97,97,97,97,1118,97,97,97,97,97,97,97,97,97,97,97,630,97,97,97,97,97,1169,97,97,97,97,97,0,921,0,1175,0,0,0,0,45,45,45,45,45,45,1534,45,45,45,45,45,1538,45,45,45,45,1233,45,45,45,45,45,45,67,67,67,67,67,67,67,67,742,67,45,45,1191,45,45,45,45,45,45,45,45,45,45,45,45,45,454,67,67,67,67,1243,67,67,67,67,67,67,67,67,67,67,67,1251,67,0,0,97,97,97,97,45,45,67,67,2050,0,97,97,45,45,45,732,45,45,67,67,67,67,67,67,67,67,67,67,67,67,97,97,67,67,67,1284,67,67,67,67,67,67,67,67,67,67,67,67,772,67,67,67,1293,67,67,67,67,67,67,0,0,0,0,0,0,0,0,0,0,368,2158592,2158592,2158592,2404352,2412544,1323,97,97,97,97,97,97,97,97,97,97,97,1331,97,97,97,0,97,97,97,97,97,97,97,97,97,97,97,1737,97,1364,97,97,97,97,97,97,97,97,97,97,97,97,1373,97,18,131427,0,0,0,0,0,0,362,0,0,365,29315,367,647,45,45,1387,45,45,1391,45,45,45,45,45,45,45,45,45,45,410,45,45,45,45,45,1400,45,45,45,45,45,45,45,45,45,45,1407,45,45,45,45,45,941,45,943,45,45,45,45,45,45,951,45,67,1438,67,67,67,67,67,67,67,67,67,67,1447,67,67,67,67,67,67,782,67,67,67,67,67,67,67,67,67,756,67,67,67,67,67,67,97,1491,97,97,97,97,97,97,97,97,97,97,1500,97,97,97,0,97,97,97,97,97,97,97,97,97,97,1736,97,45,45,1541,45,45,45,45,45,45,45,45,45,45,45,45,45,677,45,45,67,1581,67,67,67,67,67,67,67,67,67,67,67,67,67,67,791,792,67,67,67,67,1598,67,1600,67,67,67,67,67,67,67,67,1472,97,97,97,1727,97,97,97,97,97,97,97,97,97,97,97,97,97,1513,97,97,67,67,97,1879,97,1881,97,0,1884,0,97,97,97,97,0,0,97,97,97,97,97,0,0,0,1842,97,97,67,67,67,67,67,97,97,97,97,1928,0,0,0,97,97,97,97,97,97,45,45,45,45,45,1903,45,45,45,67,67,67,67,97,97,97,97,1971,0,0,97,97,97,97,0,97,97,97,97,97,97,97,97,97,0,0,0,45,45,45,1381,45,45,45,45,1976,97,97,97,97,97,45,45,45,45,45,45,45,45,45,45,45,45,1747,809,67,67,67,67,67,67,67,67,67,67,67,25398,542,13112,544,97,907,97,97,97,97,97,97,97,97,97,97,97,638,0,0,0,0,1478,97,97,97,97,97,97,97,97,97,97,97,1150,97,97,97,97,67,67,67,67,1244,67,67,67,67,67,67,67,67,67,67,67,477,67,67,67,67,67,67,1294,67,67,67,67,0,0,0,0,0,0,0,0,0,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1324,97,97,97,97,97,97,97,97,97,97,97,97,97,0,0,0,1374,97,97,97,97,0,1175,0,45,45,45,45,45,45,45,45,945,45,45,45,45,45,45,45,45,1908,45,45,1910,45,67,67,67,67,67,67,67,67,1919,67,0,0,97,97,97,97,45,2048,67,2049,0,0,97,2051,45,45,45,939,45,45,45,45,45,45,45,45,45,45,45,45,397,45,45,45,1921,67,67,1923,67,97,97,97,97,97,0,0,0,97,97,97,97,97,97,45,45,45,45,1947,45,1935,0,0,0,97,1939,97,97,1941,97,45,45,45,45,45,45,382,389,45,45,45,45,45,45,45,45,1810,45,45,1812,67,67,67,67,67,256,67,67,67,67,67,0,24850,12564,0,0,0,0,28809,53531,336,97,97,97,97,97,0,40976,0,18,18,24,24,27,27,27,131427,0,0,0,0,362,0,365,28809,367,139,45,45,371,373,45,45,45,955,45,45,45,45,45,45,45,45,45,45,45,45,413,45,45,45,457,459,67,67,67,67,67,67,67,67,473,67,478,67,67,482,67,67,485,67,67,67,67,67,67,67,67,67,67,67,67,67,97,1828,97,554,556,97,97,97,97,97,97,97,97,570,97,575,97,97,579,97,97,582,97,97,97,97,97,97,97,97,97,97,97,97,97,330,97,97,67,746,67,67,67,67,67,67,67,67,67,758,67,67,67,67,67,67,67,1575,67,67,67,67,67,67,67,67,493,67,67,67,67,67,67,67,97,97,844,97,97,97,97,97,97,97,97,97,856,97,97,97,0,97,97,97,97,97,97,97,97,1735,97,97,97,0,97,97,97,97,97,97,97,1642,97,1644,97,97,890,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,0,67,67,67,67,1065,1066,67,67,67,67,67,67,67,67,67,67,532,67,67,67,67,67,67,67,1451,67,67,67,67,67,67,67,67,67,67,67,67,67,496,67,67,97,97,1505,97,97,97,97,97,97,97,97,97,97,97,97,97,593,97,97,0,1474,0,1476,0,97,97,97,97,97,97,97,97,97,97,1617,97,97,1635,0,1637,97,97,97,97,97,97,97,97,97,97,97,885,97,97,97,97,67,67,1704,67,67,67,67,97,97,97,97,97,97,97,97,97,565,572,97,97,97,97,97,97,97,97,1832,0,97,97,97,97,97,0,0,0,97,97,97,97,97,97,45,45,45,1946,45,45,67,67,67,67,67,97,1926,97,1927,97,0,0,0,97,97,1934,2043,0,0,97,97,97,2047,45,45,67,67,0,1832,97,97,45,45,45,981,45,45,45,45,45,45,45,45,45,45,45,45,1227,45,45,45,131427,0,0,0,0,362,0,365,28809,367,139,45,45,372,45,45,45,45,1661,1662,45,45,45,45,45,1666,45,45,45,45,45,1673,45,1675,45,45,45,45,45,45,45,67,1426,67,67,67,67,67,67,67,67,67,67,1275,67,67,67,67,67,45,418,45,45,420,45,45,423,45,45,45,45,45,45,45,45,959,45,45,962,45,45,45,45,458,67,67,67,67,67,67,67,67,67,67,67,67,67,67,483,67,67,67,67,504,67,67,506,67,67,509,67,67,67,67,67,67,67,528,67,67,67,67,67,67,67,67,1287,67,67,67,67,67,67,67,555,97,97,97,97,97,97,97,97,97,97,97,97,97,97,580,97,97,97,97,601,97,97,603,97,97,606,97,97,97,97,97,97,848,97,97,97,97,97,97,97,97,97,1498,97,97,97,97,97,97,45,45,714,45,45,45,45,45,45,45,45,45,45,45,45,45,989,990,45,67,67,67,67,67,1011,67,67,67,67,1015,67,67,67,67,67,67,67,753,67,67,67,67,67,67,67,67,467,67,67,67,67,67,67,67,45,45,1179,45,45,45,45,45,45,45,45,45,45,45,45,45,1003,1004,67,1217,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,728,67,1461,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1034,67,97,1516,97,97,97,97,97,97,97,97,97,97,97,97,97,97,871,97,67,67,67,1705,67,67,67,97,97,97,97,97,97,97,97,97,567,97,97,97,97,97,97,97,97,97,97,1715,97,97,97,97,97,97,97,97,97,0,0,0,45,45,1380,45,45,45,45,45,67,67,97,97,97,97,97,0,0,0,97,1887,97,97,0,0,97,97,97,0,97,97,97,97,97,2006,45,45,1907,45,45,45,45,45,67,67,67,67,67,67,67,67,67,1920,67,97,0,2035,97,97,97,97,97,45,45,45,45,67,67,67,1428,67,67,67,67,67,67,1435,67,0,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,45,146,45,152,45,45,165,45,175,45,180,45,45,187,190,195,45,203,254,257,262,67,270,67,67,0,24850,12564,0,0,0,281,28809,53531,97,97,97,293,97,299,97,97,312,97,322,97,327,97,97,334,337,342,97,350,97,97,0,40976,0,18,18,24,24,27,27,27,67,484,67,67,67,67,67,67,67,67,67,67,67,67,67,499,97,581,97,97,97,97,97,97,97,97,97,97,97,97,97,596,648,45,650,45,651,45,653,45,45,45,657,45,45,45,45,45,45,1954,67,67,67,1958,67,67,67,67,67,67,67,768,67,67,67,67,67,67,67,67,769,67,67,67,67,67,67,67,680,45,45,45,45,45,45,45,45,688,689,691,45,45,45,45,45,983,45,45,45,45,45,45,45,45,45,45,947,45,45,45,45,952,45,45,698,699,45,45,702,703,45,45,45,45,45,45,45,711,744,67,67,67,67,67,67,67,67,67,757,67,67,67,67,761,67,67,67,67,765,67,767,67,67,67,67,67,67,67,67,775,776,778,67,67,67,67,67,67,785,786,67,67,789,790,67,67,67,67,67,67,1442,67,67,67,67,67,67,67,67,67,97,97,97,1775,97,97,97,67,67,67,67,67,798,67,67,67,802,67,67,67,67,67,67,67,67,1465,67,67,1468,67,67,1471,67,67,810,67,67,67,67,67,67,67,67,67,821,25398,542,13112,544,57889,0,0,54074,54074,550,0,833,97,835,97,836,97,838,97,97,0,0,97,97,97,2002,97,97,97,97,97,45,45,45,45,45,1740,45,45,45,1744,45,45,45,97,842,97,97,97,97,97,97,97,97,97,855,97,97,97,97,0,1717,1718,97,97,97,97,97,1722,97,0,0,859,97,97,97,97,863,97,865,97,97,97,97,97,97,97,97,604,97,97,97,97,97,97,97,873,874,876,97,97,97,97,97,97,883,884,97,97,887,888,97,18,131427,0,0,0,0,0,0,362,225280,0,365,0,367,0,45,45,45,1531,45,45,45,45,45,45,45,45,45,45,45,1199,45,45,45,45,45,97,97,908,97,97,97,97,97,97,97,97,97,919,638,0,0,0,0,2158877,2158877,2158877,2158877,2158877,2425117,2158877,2158877,2158877,2158877,2158877,2158877,2597149,2158877,2158877,2158877,2158877,2158877,2158877,2642205,2158877,2158877,2158877,2158877,2158877,3158301,0,2375818,2379914,2158730,2158730,2420874,2158730,2449546,2158730,2158730,953,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,965,978,45,45,45,45,45,45,985,45,45,45,45,45,45,45,45,971,45,45,45,45,45,45,45,67,67,67,67,67,1027,67,1029,67,67,67,67,67,67,67,67,67,1455,67,67,67,67,67,67,67,1077,1078,67,67,25398,0,13112,0,54074,0,0,0,0,0,0,0,0,366,0,139,2158730,2158730,2158730,2404490,2412682,1113,97,97,97,97,97,97,1121,97,1123,97,97,97,97,97,97,0,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1540,1155,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,615,1168,97,97,1171,1172,97,97,0,921,0,1175,0,0,0,0,45,45,45,45,45,1533,45,45,45,45,45,45,45,45,45,1663,45,45,45,45,45,45,45,45,45,183,45,45,45,45,201,45,45,45,1219,45,45,45,45,45,45,45,1226,45,45,45,45,45,168,45,45,45,45,45,45,45,45,45,45,427,45,45,45,45,45,45,45,1231,45,45,45,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,67,1242,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1046,67,67,1254,67,1256,67,67,67,67,67,67,67,67,67,67,67,67,806,807,67,67,97,1336,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1111,97,97,97,97,97,1351,97,97,97,1354,97,97,97,1359,97,97,97,0,97,97,97,97,1640,97,97,97,97,97,97,97,897,97,97,97,902,97,97,97,97,97,97,97,97,1366,97,97,97,97,97,97,97,1371,97,97,97,0,97,97,97,1730,97,97,97,97,97,97,97,97,915,97,97,97,97,0,360,0,67,67,67,1440,67,67,67,67,67,67,67,67,67,67,67,67,1017,67,1019,67,67,67,67,67,1453,67,67,67,67,67,67,67,67,67,67,1459,97,97,97,1493,97,97,97,97,97,97,97,97,97,97,97,97,97,1525,97,97,97,97,97,97,1507,97,97,97,97,97,97,97,97,97,97,1514,67,67,67,67,1584,67,67,67,67,67,1590,67,67,67,67,67,67,67,783,67,67,67,788,67,67,67,67,67,67,67,67,67,1599,1601,67,67,67,1604,67,1606,1607,67,1472,0,1474,0,1476,0,97,97,97,97,97,97,1614,97,97,97,97,45,45,1850,45,45,45,45,1855,45,45,45,45,45,1222,45,45,45,45,45,45,45,45,45,1229,97,1618,97,97,97,97,97,97,97,1625,97,97,97,97,97,0,1175,0,45,45,45,45,45,45,45,45,447,45,45,45,45,45,67,67,1633,97,97,0,97,97,97,97,97,97,97,97,1643,1645,97,97,0,0,97,97,1784,97,97,97,0,0,97,97,0,97,1894,1895,97,1897,97,45,45,45,45,45,45,45,45,45,656,45,45,45,45,45,45,97,1648,97,1650,1651,97,0,45,45,45,1654,45,45,45,45,45,169,45,45,45,45,45,45,45,45,45,45,658,45,45,45,45,664,45,45,1659,45,45,45,45,45,45,45,45,45,45,45,45,45,1187,45,45,1669,45,45,45,45,45,45,45,45,45,45,45,45,45,45,67,1005,67,67,1681,67,67,67,67,67,67,67,1686,67,67,67,67,67,67,67,784,67,67,67,67,67,67,67,67,1055,67,67,67,67,1060,67,67,97,97,1713,97,0,97,97,97,97,97,97,97,97,97,0,0,0,1378,45,45,45,45,45,45,45,408,45,45,45,45,45,45,45,45,1547,45,1549,45,45,45,45,45,97,97,1780,0,97,97,97,97,97,97,0,0,97,97,0,97,97,97,45,45,2027,2028,45,45,67,67,2031,2032,67,45,45,1804,45,45,45,45,45,45,45,45,67,67,67,67,67,67,1917,67,67,67,67,67,67,67,1819,67,67,67,67,67,67,67,67,97,97,97,1708,97,97,97,97,97,45,45,1862,67,67,67,67,67,67,67,67,67,67,67,67,67,497,67,67,67,1877,97,97,97,97,97,0,0,0,97,97,97,97,0,0,97,97,97,97,97,1839,0,0,97,97,97,97,1936,0,0,97,97,97,97,97,97,1943,1944,1945,45,45,45,45,670,45,45,45,45,674,45,45,45,45,678,45,1948,45,1950,45,45,45,45,1955,1956,1957,67,67,67,1960,67,1962,67,67,67,67,1967,1968,1969,97,0,0,0,97,97,1974,97,0,1936,0,97,97,97,97,97,97,45,45,45,45,45,45,45,45,1906,0,1977,97,97,97,97,45,45,45,45,45,45,45,45,45,45,45,1746,45,45,45,45,2011,67,67,2013,67,67,67,2017,97,97,0,0,2021,97,8192,97,97,2025,45,45,45,45,45,45,67,67,67,67,67,1916,67,67,67,67,0,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,140,45,45,45,1180,45,45,45,45,1184,45,45,45,45,45,45,45,387,45,392,45,45,396,45,45,399,45,45,67,207,67,67,67,67,67,67,236,67,67,67,67,67,67,67,800,67,67,67,67,67,67,67,67,67,1603,67,67,67,67,67,0,97,97,287,97,97,97,97,97,97,316,97,97,97,97,97,97,0,45,45,45,45,45,45,45,1656,1657,45,376,45,45,45,45,45,388,45,45,45,45,45,45,45,45,1406,45,45,45,45,45,45,45,67,67,67,67,462,67,67,67,67,67,474,67,67,67,67,67,67,67,817,67,67,67,67,25398,542,13112,544,97,97,97,97,559,97,97,97,97,97,571,97,97,97,97,97,97,896,97,97,97,900,97,97,97,97,97,97,912,914,97,97,97,97,97,0,0,0,45,45,45,45,45,45,45,45,391,45,45,45,45,45,45,45,45,713,45,45,45,45,45,45,45,45,45,45,45,45,45,45,662,45,1140,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,636,67,67,1283,67,67,67,67,67,67,67,67,67,67,67,67,67,513,67,67,1363,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,889,97,97,97,1714,0,97,97,97,97,97,97,97,97,97,0,0,926,45,45,45,45,45,45,45,45,672,45,45,45,45,45,45,45,45,686,45,45,45,45,45,45,45,45,944,45,45,45,45,45,45,45,45,1676,45,45,45,45,45,45,67,97,97,97,1833,0,97,97,97,97,97,0,0,0,97,97,97,97,97,97,45,45,45,45,1902,45,45,45,45,45,957,45,45,45,45,961,45,963,45,45,45,67,97,2034,0,97,97,97,97,97,2040,45,45,45,2042,67,67,67,67,67,67,1574,67,67,67,67,67,1578,67,67,67,67,67,67,799,67,67,67,804,67,67,67,67,67,67,67,1298,0,0,0,1304,0,0,0,1310,132,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,45,45,45,1414,45,45,45,45,45,45,45,45,45,45,428,45,45,45,45,45,57889,0,0,54074,54074,550,831,97,97,97,97,97,97,97,97,97,568,97,97,97,97,578,97,45,45,968,45,45,45,45,45,45,45,45,45,45,45,45,45,1228,45,45,67,67,67,67,67,25398,1082,13112,1086,54074,1090,0,0,0,0,0,0,364,0,0,0,139,2158592,2158592,2158592,2404352,2412544,67,67,67,67,1464,67,67,67,67,67,67,67,67,67,67,67,510,67,67,67,67,97,97,97,97,1519,97,97,97,97,97,97,97,97,97,97,97,918,97,0,0,0,0,1528,45,45,45,45,45,45,45,45,45,45,45,45,45,45,976,45,1554,45,45,45,45,45,45,45,45,1562,45,45,1565,45,45,45,45,683,45,45,45,687,45,45,692,45,45,45,45,45,1953,45,67,67,67,67,67,67,67,67,67,1014,67,67,67,67,67,67,1568,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,0,67,67,67,67,67,1585,67,67,67,67,67,67,67,67,67,1594,97,97,1649,97,97,97,0,45,45,1653,45,45,45,45,45,45,383,45,45,45,45,45,45,45,45,45,986,45,45,45,45,45,45,45,45,1670,45,1672,45,45,45,45,45,45,45,45,45,45,67,736,67,67,67,67,67,741,67,67,67,1680,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1074,67,67,67,1692,67,67,67,67,67,67,67,1697,67,1699,67,67,67,67,67,67,1012,67,67,67,67,67,67,67,67,67,468,475,67,67,67,67,67,67,1769,67,67,67,67,67,67,67,97,97,97,97,97,97,97,624,97,97,97,97,97,97,634,97,97,1792,97,97,97,97,97,97,97,45,45,45,45,45,45,45,958,45,45,45,45,45,45,964,45,150,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,977,204,45,67,67,67,217,67,67,67,67,67,67,67,67,67,67,787,67,67,67,67,67,67,67,67,67,67,271,67,0,24850,12564,0,0,0,0,28809,53531,97,97,97,97,351,97,0,40976,0,18,18,24,24,27,27,27,45,45,938,45,45,45,45,45,45,45,45,45,45,45,45,45,1398,45,45,45,153,45,161,45,45,45,45,45,45,45,45,45,45,45,45,660,661,45,45,205,45,67,67,67,67,220,67,228,67,67,67,67,67,67,67,0,0,0,0,0,280,94,0,0,67,67,67,67,67,272,67,0,24850,12564,0,0,0,0,28809,53531,97,97,97,97,352,97,0,40976,0,18,18,24,24,27,27,27,45,439,45,45,45,45,45,445,45,45,45,452,45,45,67,67,212,216,67,67,67,67,67,241,67,246,67,252,67,67,486,67,67,67,67,67,67,67,494,67,67,67,67,67,67,67,1245,67,67,67,67,67,67,67,67,1013,67,67,1016,67,67,67,67,67,521,67,67,525,67,67,67,67,67,531,67,67,67,538,67,0,0,2046,97,97,97,45,45,67,67,0,0,97,97,45,45,45,1192,45,45,45,45,45,45,45,45,45,45,45,45,1418,45,45,1421,97,97,583,97,97,97,97,97,97,97,591,97,97,97,97,97,97,913,97,97,97,97,97,97,0,0,0,45,45,45,45,45,45,45,1384,97,618,97,97,622,97,97,97,97,97,628,97,97,97,635,97,18,131427,0,0,0,639,0,132,362,0,0,365,29315,367,0,921,29315,0,0,0,0,45,45,45,45,932,45,45,45,45,45,1544,45,45,45,45,45,1550,45,45,45,45,45,1194,45,1196,45,45,45,45,45,45,45,45,999,45,45,45,45,45,67,67,45,45,667,45,45,45,45,45,45,45,45,45,45,45,45,45,1408,45,45,45,696,45,45,45,701,45,45,45,45,45,45,45,45,710,45,45,45,1220,45,45,45,45,45,45,45,45,45,45,45,45,194,45,45,45,729,45,45,45,45,45,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,797,67,67,67,67,67,67,805,67,67,67,67,67,67,67,1587,67,1589,67,67,67,67,67,67,67,67,1763,67,67,67,67,67,67,67,0,0,0,0,0,0,2162968,0,0,67,67,67,67,67,814,816,67,67,67,67,67,25398,542,13112,544,67,67,1008,67,67,67,67,67,67,67,67,67,67,67,1020,67,0,97,45,67,0,97,45,67,0,97,45,67,97,0,0,97,97,97,97,97,45,45,45,45,67,67,67,67,1429,67,1430,67,67,67,67,67,1062,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,518,1076,67,67,67,67,25398,0,13112,0,54074,0,0,0,0,0,0,0,0,28809,0,139,45,45,45,45,45,97,97,97,97,1102,97,97,97,97,97,97,97,97,97,97,97,1124,97,1126,97,97,1114,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1112,97,97,1156,97,97,97,97,97,97,97,97,97,97,97,97,97,594,97,97,97,97,1170,97,97,97,97,0,921,0,0,0,0,0,0,45,45,45,45,1532,45,45,45,45,1536,45,45,45,45,45,172,45,45,45,45,45,45,45,45,45,45,706,45,45,709,45,45,1177,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1202,45,1204,45,45,45,45,45,45,45,45,45,45,45,45,1215,45,45,45,1232,45,45,45,45,45,45,45,67,1237,67,67,67,67,67,67,1053,1054,67,67,67,67,67,67,1061,67,67,1282,67,67,67,67,67,67,67,67,67,1289,67,67,67,1292,97,97,97,97,1339,97,97,97,97,97,97,1344,97,97,97,97,45,1849,45,1851,45,45,45,45,45,45,45,45,721,45,45,45,45,45,726,45,1385,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1188,45,45,1401,1402,45,45,45,45,1405,45,45,45,45,45,45,45,45,1752,45,45,45,45,45,67,67,1410,45,45,45,1413,45,1415,45,45,45,45,45,45,1419,45,45,45,45,1806,45,45,45,45,45,45,67,67,67,67,67,67,67,97,97,2019,0,97,67,67,67,1452,67,67,67,67,67,67,67,67,1457,67,67,67,67,67,67,1259,67,67,67,67,67,67,1264,67,67,1460,67,1462,67,67,67,67,67,67,1466,67,67,67,67,67,67,67,67,1588,67,67,67,67,67,67,67,0,1300,0,0,0,1306,0,0,0,97,97,97,1506,97,97,97,97,97,97,97,97,1512,97,97,97,0,1728,97,97,97,97,97,97,97,97,97,97,97,901,97,97,97,97,1515,97,1517,97,97,97,97,97,97,1521,97,97,97,97,97,97,0,45,1652,45,45,45,1655,45,45,45,45,45,1542,45,45,45,45,45,45,45,45,45,45,45,45,45,1552,1553,45,45,45,1556,45,45,45,45,45,45,45,45,45,45,45,45,45,693,45,45,45,67,67,67,67,1572,67,67,67,67,1576,67,67,67,67,67,67,67,67,1602,67,67,1605,67,67,67,0,67,1582,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1580,67,67,1596,67,67,67,67,67,67,67,67,67,67,67,67,67,0,542,0,544,67,67,67,67,1759,67,67,67,67,67,67,67,67,67,67,67,533,67,67,67,67,67,67,67,1770,67,67,67,67,67,97,97,97,97,97,97,1777,97,97,97,1793,97,97,97,97,97,45,45,45,45,45,45,45,998,45,45,1001,1002,45,45,67,67,45,1861,45,67,67,67,67,67,67,67,67,1871,67,1873,1874,67,0,97,45,67,0,97,45,67,16384,97,45,67,97,0,0,0,1473,0,1082,0,0,0,1475,0,1086,0,0,0,1477,1876,67,97,97,97,97,97,1883,0,1885,97,97,97,1889,0,0,0,286,0,0,0,286,0,2367488,2158592,2158592,2158592,2158592,2158592,2158592,0,40976,0,18,18,24,24,126,126,126,2053,0,2055,45,67,0,97,45,67,0,97,45,67,97,0,0,97,97,97,2039,97,45,45,45,45,67,67,67,67,67,226,67,67,67,67,67,67,67,67,1246,67,67,1249,1250,67,67,67,132,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,141,45,45,45,1403,45,45,45,45,45,45,45,45,45,45,45,45,1186,45,45,1189,45,45,155,45,45,45,45,45,45,45,45,45,191,45,45,45,45,700,45,45,45,45,45,45,45,45,45,45,45,1753,45,45,45,67,67,45,45,67,208,67,67,67,222,67,67,67,67,67,67,67,67,67,1764,67,67,67,67,67,67,67,258,67,67,67,67,67,0,24850,12564,0,0,0,0,28809,53531,97,97,288,97,97,97,302,97,97,97,97,97,97,97,97,97,627,97,97,97,97,97,97,338,97,97,97,97,97,0,40976,0,18,18,24,24,27,27,27,131427,0,0,0,0,362,0,365,28809,367,139,45,370,45,45,45,45,716,45,45,45,45,45,722,45,45,45,45,45,45,1912,67,67,67,67,67,67,67,67,67,819,67,67,25398,542,13112,544,45,403,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1409,45,67,67,67,67,489,67,67,67,67,67,67,67,67,67,67,67,771,67,67,67,67,520,67,67,67,67,67,67,67,67,67,67,67,534,67,67,67,67,67,67,1271,67,67,67,1274,67,67,67,1279,67,67,24850,24850,12564,12564,0,57889,0,0,0,53531,53531,367,286,97,553,97,97,97,97,586,97,97,97,97,97,97,97,97,97,97,97,1138,97,97,97,97,617,97,97,97,97,97,97,97,97,97,97,97,631,97,97,97,0,1834,97,97,97,97,97,0,0,0,97,97,97,97,97,353,0,40976,0,18,18,24,24,27,27,27,45,45,668,45,45,45,45,45,45,45,45,45,45,45,45,45,724,45,45,45,45,45,682,45,45,45,45,45,45,45,45,45,45,45,45,45,949,45,45,45,67,67,747,748,67,67,67,67,755,67,67,67,67,67,67,67,0,0,0,1302,0,0,0,1308,0,67,794,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1701,67,97,97,97,845,846,97,97,97,97,853,97,97,97,97,97,97,0,40976,0,18,18,24,24,27,27,27,97,97,892,97,97,97,97,97,97,97,97,97,97,97,97,97,610,97,97,45,992,45,45,45,45,45,45,45,45,45,45,45,45,67,67,67,1239,67,67,67,1063,67,67,67,67,67,1068,67,67,67,67,67,67,67,0,0,1301,0,0,0,1307,0,0,97,1141,97,97,97,97,97,97,97,97,97,97,97,1152,97,97,0,0,97,97,2001,0,97,2003,97,97,97,45,45,45,1739,45,45,45,1742,45,45,45,45,45,97,97,97,97,1157,97,97,97,97,97,1162,97,97,97,97,97,97,1145,97,97,97,97,97,1151,97,97,97,1253,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,539,45,1423,45,45,67,67,67,67,67,67,67,1431,67,67,67,67,67,67,67,1695,67,67,67,67,67,1700,67,1702,67,67,1439,67,67,67,67,67,67,67,67,67,67,67,67,67,514,67,67,97,97,1492,97,97,97,97,97,97,97,97,97,97,97,97,97,611,97,97,1703,67,67,67,67,67,67,97,97,97,97,97,97,97,97,97,852,97,97,97,97,97,97,45,1949,45,1951,45,45,45,67,67,67,67,67,67,67,1961,67,0,97,45,67,0,97,2060,2061,0,2062,45,67,97,0,0,2036,97,97,97,97,45,45,45,45,67,67,67,67,67,223,67,67,237,67,67,67,67,67,67,67,1272,67,67,67,67,67,67,67,67,507,67,67,67,67,67,67,67,1963,67,67,67,97,97,97,97,0,1972,0,97,97,97,1975,0,921,29315,0,0,0,0,45,45,45,931,45,45,45,45,45,407,45,45,45,45,45,45,45,45,45,417,45,45,1989,67,67,67,67,67,67,67,67,67,67,67,1996,97,18,131427,0,0,360,0,0,0,362,0,0,365,29315,367,0,921,29315,0,0,0,0,45,45,930,45,45,45,45,45,45,444,45,45,45,45,45,45,45,67,67,97,97,1998,0,97,97,97,0,97,97,97,97,97,45,45,45,45,45,45,1985,45,1986,45,45,45,156,45,45,170,45,45,45,45,45,45,45,45,45,45,675,45,45,45,45,679,131427,0,358,0,0,362,0,365,28809,367,139,45,45,45,45,45,381,45,45,45,45,45,45,45,45,45,400,45,45,419,45,45,45,45,45,45,45,45,45,45,45,45,436,67,67,67,67,67,505,67,67,67,67,67,67,67,67,67,67,820,67,25398,542,13112,544,67,67,522,67,67,67,67,67,529,67,67,67,67,67,67,67,0,1299,0,0,0,1305,0,0,0,97,97,619,97,97,97,97,97,626,97,97,97,97,97,97,97,1105,97,97,97,97,1109,97,97,97,67,67,67,67,749,67,67,67,67,67,67,67,67,67,760,67,0,97,45,67,2058,97,45,67,0,97,45,67,97,0,0,97,97,97,97,97,45,45,45,2041,67,67,67,67,67,780,67,67,67,67,67,67,67,67,67,67,67,67,67,516,67,67,97,97,97,878,97,97,97,97,97,97,97,97,97,97,97,97,97,1629,97,0,45,979,45,45,45,45,984,45,45,45,45,45,45,45,45,45,1198,45,45,45,45,45,45,67,1023,67,67,67,67,1028,67,67,67,67,67,67,67,67,67,470,67,67,67,67,67,67,67,67,67,67,67,25398,0,13112,0,54074,0,0,0,1094,0,0,0,1092,1315,0,0,0,0,97,97,97,97,97,97,97,97,97,1486,97,1489,97,97,97,1117,97,97,97,97,1122,97,97,97,97,97,97,97,1146,97,97,97,97,97,97,97,97,881,97,97,97,886,97,97,97,1311,0,0,0,0,0,0,0,0,97,97,97,97,97,97,97,1615,97,97,97,97,97,1619,97,97,97,97,97,97,97,97,97,97,97,97,1631,97,97,1847,97,45,45,45,45,1852,45,45,45,45,45,45,45,1235,45,45,45,67,67,67,67,67,1868,67,67,67,1872,67,67,67,67,67,97,97,97,97,1882,0,0,0,97,97,97,97,0,1891,67,67,67,67,67,97,97,97,97,97,1929,0,0,97,97,97,97,97,97,45,1900,45,1901,45,45,45,1905,45,67,2054,97,45,67,0,97,45,67,0,97,45,67,97,0,0,97,2037,2038,97,97,45,45,45,45,67,67,67,67,1867,67,67,67,67,67,67,67,67,67,1774,97,97,97,97,97,97,0,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,142,45,45,45,1412,45,45,45,45,45,45,45,45,45,45,45,45,432,45,45,45,45,45,157,45,45,171,45,45,45,182,45,45,45,45,200,45,45,45,1543,45,45,45,45,45,45,45,45,1551,45,45,45,45,1181,45,45,45,45,45,45,45,45,45,45,45,1211,45,45,45,1214,45,45,45,67,209,67,67,67,224,67,67,238,67,67,67,249,67,0,97,2056,2057,0,2059,45,67,0,97,45,67,97,0,0,1937,97,97,97,97,97,97,45,45,45,45,45,45,1741,45,45,45,45,45,45,67,67,67,267,67,67,67,0,24850,12564,0,0,0,0,28809,53531,97,97,289,97,97,97,304,97,97,318,97,97,97,329,97,97,0,0,97,1783,97,97,97,97,0,0,97,97,0,97,97,97,45,2026,45,45,45,45,67,2030,67,67,67,67,67,67,1041,67,67,67,67,67,67,67,67,67,1044,67,67,67,67,67,67,97,97,347,97,97,97,0,40976,0,18,18,24,24,27,27,27,45,666,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1420,45,57889,0,0,54074,54074,550,0,97,97,97,97,97,97,97,97,840,67,1007,67,67,67,67,67,67,67,67,67,67,67,67,67,67,759,67,67,67,67,67,67,67,1052,67,67,67,67,67,67,67,67,67,67,1031,67,67,67,67,67,97,97,97,1101,97,97,97,97,97,97,97,97,97,97,97,97,592,97,97,97,1190,45,45,45,45,45,1195,45,1197,45,45,45,45,1201,45,45,45,45,1952,45,45,67,67,67,67,67,67,67,67,67,67,67,67,250,67,67,67,1255,67,1257,67,67,67,67,1261,67,67,67,67,67,67,67,67,1685,67,67,67,67,67,67,67,0,24851,12565,0,0,0,0,28809,53532,67,67,1267,67,67,67,67,67,67,1273,67,67,67,67,67,67,67,67,1696,67,67,67,67,67,67,67,0,0,0,0,0,0,2162688,0,0,1281,67,67,67,67,1285,67,67,67,67,67,67,67,67,67,67,1070,67,67,67,67,67,1335,97,1337,97,97,97,97,1341,97,97,97,97,97,97,97,97,882,97,97,97,97,97,97,97,1347,97,97,97,97,97,97,1353,97,97,97,97,97,97,1361,97,18,131427,0,638,0,0,0,0,362,0,0,365,29315,367,0,544,0,550,0,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2473984,2158592,2158592,2158592,2990080,2158592,2158592,2207744,2207744,2482176,2207744,2207744,2207744,2207744,2207744,2207744,2207744,0,0,0,0,0,0,2162688,0,53530,97,97,97,1365,97,97,97,97,97,97,97,97,97,97,97,97,608,97,97,97,45,45,1424,45,1425,67,67,67,67,67,67,67,67,67,67,67,1058,67,67,67,67,45,1555,45,45,1557,45,45,45,45,45,45,45,45,45,45,45,707,45,45,45,45,67,67,1570,67,67,67,67,67,67,67,67,67,67,67,67,67,773,67,67,1595,67,67,1597,67,67,67,67,67,67,67,67,67,67,67,0,0,0,0,0,0,0,0,0,0,139,2158592,2158592,2158592,2404352,2412544,97,97,97,1636,97,97,97,1639,97,97,1641,97,97,97,97,97,97,1173,0,921,0,0,0,0,0,0,45,67,67,67,1693,67,67,67,67,67,67,67,1698,67,67,67,67,67,67,67,1773,67,97,97,97,97,97,97,97,625,97,97,97,97,97,97,97,97,850,97,97,97,97,97,97,97,97,880,97,97,97,97,97,97,97,97,1106,97,97,97,97,97,97,97,1860,45,45,67,67,1865,67,67,67,67,1870,67,67,67,67,1875,67,67,97,97,1880,97,97,0,0,0,97,97,1888,97,0,0,0,1938,97,97,97,97,97,45,45,45,45,45,45,1854,45,45,45,45,45,45,45,1909,45,45,1911,67,67,67,67,67,67,67,67,67,67,1248,67,67,67,67,67,67,1922,67,67,1924,97,97,97,97,97,0,0,0,97,97,97,97,97,1898,45,45,45,45,45,45,1904,45,45,67,67,67,67,97,97,97,97,0,0,16384,97,97,97,97,0,97,97,97,97,97,97,97,97,97,0,1724,2008,2009,45,45,67,67,67,2014,2015,67,67,97,97,0,0,97,97,97,0,97,97,97,97,97,45,45,45,45,45,45,45,45,45,45,45,45,45,2022,0,2023,97,97,45,45,45,45,45,45,67,67,67,67,67,67,1869,67,67,67,67,67,67,0,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,45,147,151,154,45,162,45,45,176,178,181,45,45,45,192,196,45,45,45,45,2012,67,67,67,67,67,67,2018,97,0,0,97,1978,97,97,97,1982,45,45,45,45,45,45,45,45,45,972,973,45,45,45,45,45,67,259,263,67,67,67,67,0,24850,12564,0,0,0,0,28809,53531,97,97,97,294,298,301,97,309,97,97,323,325,328,97,97,97,97,97,560,97,97,97,569,97,97,97,97,97,97,306,97,97,97,97,97,97,97,97,97,1624,97,97,97,97,97,97,97,0,921,0,1175,0,0,0,0,45,339,343,97,97,97,97,0,40976,0,18,18,24,24,27,27,27,67,67,503,67,67,67,67,67,67,67,67,67,512,67,67,519,97,97,600,97,97,97,97,97,97,97,97,97,609,97,97,616,45,649,45,45,45,45,45,654,45,45,45,45,45,45,45,45,1393,45,45,45,45,45,45,45,45,1209,45,45,45,45,45,45,45,67,763,67,67,67,67,67,67,67,67,770,67,67,67,774,67,0,2045,97,97,97,97,45,45,67,67,0,0,97,97,45,45,45,994,45,45,45,45,45,45,45,45,45,45,67,67,213,67,219,67,67,232,67,242,67,247,67,67,67,779,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1018,67,67,67,67,811,67,67,67,67,67,67,67,67,67,25398,542,13112,544,57889,0,0,54074,54074,550,0,97,834,97,97,97,97,97,839,97,18,131427,0,638,0,0,0,0,362,0,0,365,29315,367,645,97,97,861,97,97,97,97,97,97,97,97,868,97,97,97,872,97,97,877,97,97,97,97,97,97,97,97,97,97,97,97,97,613,97,97,97,97,97,909,97,97,97,97,97,97,97,97,97,0,0,0,18,18,24,24,27,27,27,1036,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1047,67,67,67,1050,67,67,67,67,67,67,67,67,67,67,67,67,1033,67,67,67,97,97,1130,97,97,97,97,97,97,97,97,97,97,97,97,97,638,0,0,67,67,67,1295,67,67,67,0,0,0,0,0,0,0,0,0,97,1317,97,97,97,97,97,97,1375,97,97,97,0,0,0,45,1379,45,45,45,45,45,45,422,45,45,45,429,431,45,45,45,45,0,1090,0,0,97,1479,97,97,97,97,97,97,97,97,97,97,1357,97,97,97,97,97,97,97,97,97,1716,97,97,97,97,97,97,97,97,97,1723,0,921,29315,0,0,0,0,45,929,45,45,45,45,45,45,45,1392,45,45,45,45,45,45,45,45,45,960,45,45,45,45,45,45,97,97,97,1738,45,45,45,45,45,45,45,1743,45,45,45,45,166,45,45,45,45,184,186,45,45,197,45,45,97,1779,0,0,97,97,97,97,97,97,0,0,97,97,0,97,18,131427,0,638,0,0,0,0,362,0,640,365,29315,367,0,921,29315,0,0,0,0,45,45,45,45,45,45,45,45,45,45,1537,45,45,45,45,45,1803,45,45,45,45,45,1809,45,45,45,67,67,67,1814,67,67,67,67,67,67,1821,67,67,67,67,67,67,97,97,97,97,97,0,0,0,97,97,97,97,0,0,67,67,67,1818,67,67,67,67,67,1824,67,67,67,97,97,97,97,97,0,0,0,97,97,97,97,1890,0,1829,97,97,0,0,97,97,1836,97,97,0,0,0,97,97,97,97,1981,45,45,45,45,45,45,45,45,45,1987,1845,97,97,97,45,45,45,45,45,1853,45,45,45,1857,45,45,45,67,1864,67,1866,67,67,67,67,67,67,67,67,67,97,97,97,97,97,97,97,1710,1711,67,67,97,97,97,97,97,0,0,0,1886,97,97,97,0,0,97,97,97,97,1838,0,0,0,97,1843,97,0,1893,97,97,97,97,97,45,45,45,45,45,45,45,45,45,45,1745,45,45,67,67,67,67,67,97,97,97,97,97,0,0,1931,97,97,97,97,97,588,97,97,97,97,97,97,97,97,97,97,629,97,97,97,97,97,67,2044,0,97,97,97,97,45,45,67,67,0,0,97,97,45,45,45,1660,45,45,45,45,45,45,45,45,45,45,45,45,453,45,455,67,67,67,67,268,67,67,67,0,24850,12564,0,0,0,0,28809,53531,97,97,348,97,97,97,0,40976,0,18,18,24,24,27,27,27,131427,0,359,0,0,362,0,365,28809,367,139,45,45,45,45,45,421,45,45,45,45,45,45,45,434,45,45,695,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1667,45,0,921,29315,0,925,0,0,45,45,45,45,45,45,45,45,45,1811,45,67,67,67,67,67,67,1037,67,1039,67,67,67,67,67,67,67,67,67,67,67,67,1277,67,67,67,67,67,67,67,67,25398,0,13112,0,54074,0,0,0,1095,0,0,0,1096,97,97,97,97,97,97,97,97,97,97,97,97,869,97,97,97,97,97,97,1131,97,1133,97,97,97,97,97,97,97,97,97,97,1370,97,97,97,97,97,1312,0,0,0,0,1096,0,0,0,97,97,97,97,97,97,97,1327,97,97,97,97,97,1332,97,97,97,1830,97,0,0,97,97,97,97,97,0,0,0,97,97,97,1896,97,97,45,45,45,45,45,45,45,45,45,1548,45,45,45,45,45,45,133,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,45,45,380,45,45,45,45,45,45,45,45,45,45,401,45,45,158,45,45,45,45,45,45,45,45,45,45,45,45,45,1200,45,45,45,45,206,67,67,67,67,67,225,67,67,67,67,67,67,67,67,754,67,67,67,67,67,67,67,57889,0,0,54074,54074,550,832,97,97,97,97,97,97,97,97,97,1342,97,97,97,97,97,97,67,67,67,67,67,25398,1083,13112,1087,54074,1091,0,0,0,0,0,0,1316,0,831,97,97,97,97,97,97,97,1174,921,0,1175,0,0,0,0,45,0,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,45,148,67,67,264,67,67,67,67,0,24850,12564,0,0,0,0,28809,53531,97,97,97,295,97,97,97,97,313,97,97,97,97,331,333,97,18,131427,356,638,0,0,0,0,362,0,0,365,0,367,0,45,45,1530,45,45,45,45,45,45,45,45,45,45,45,45,988,45,45,45,97,344,97,97,97,97,0,40976,0,18,18,24,24,27,27,27,402,404,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1756,67,438,45,45,45,45,45,45,45,45,449,450,45,45,45,67,67,214,218,221,67,229,67,67,243,245,248,67,67,67,67,67,488,490,67,67,67,67,67,67,67,67,67,67,67,1071,67,1073,67,67,67,67,67,524,67,67,67,67,67,67,67,67,535,536,67,67,67,67,67,67,1683,1684,67,67,67,67,1688,1689,67,67,67,67,67,67,1586,67,67,67,67,67,67,67,67,67,469,67,67,67,67,67,67,97,97,97,585,587,97,97,97,97,97,97,97,97,97,97,97,1163,97,97,97,97,97,97,97,621,97,97,97,97,97,97,97,97,632,633,97,97,0,0,1782,97,97,97,97,97,0,0,97,97,0,97,712,45,45,45,717,45,45,45,45,45,45,45,45,725,45,45,45,163,167,173,177,45,45,45,45,45,193,45,45,45,45,982,45,45,45,45,45,45,987,45,45,45,45,45,1558,45,1560,45,45,45,45,45,45,45,45,704,705,45,45,45,45,45,45,45,45,731,45,45,45,67,67,67,67,67,739,67,67,67,67,67,67,273,0,24850,12564,0,0,0,0,28809,53531,67,67,67,764,67,67,67,67,67,67,67,67,67,67,67,67,1290,67,67,67,67,67,67,812,67,67,67,67,818,67,67,67,25398,542,13112,544,57889,0,0,54074,54074,550,0,97,97,97,97,97,837,97,97,97,97,97,602,97,97,97,97,97,97,97,97,97,97,1137,97,97,97,97,97,97,97,97,97,862,97,97,97,97,97,97,97,97,97,97,97,1627,97,97,97,0,97,97,97,97,910,97,97,97,97,916,97,97,97,0,0,0,97,97,1940,97,97,1942,45,45,45,45,45,45,385,45,45,45,45,395,45,45,45,45,966,45,969,45,45,45,45,45,45,45,45,45,45,975,45,45,45,406,45,45,45,45,45,45,45,45,45,45,45,45,974,45,45,45,67,67,67,67,1010,67,67,67,67,67,67,67,67,67,67,67,1262,67,67,67,67,67,67,67,67,67,1040,67,1042,67,1045,67,67,67,67,67,67,67,97,1706,97,97,97,1709,97,97,97,67,67,67,67,1051,67,67,67,67,67,1057,67,67,67,67,67,67,67,1443,67,67,1446,67,67,67,67,67,67,67,1297,0,0,0,1303,0,0,0,1309,67,67,67,67,1079,25398,0,13112,0,54074,0,0,0,0,0,0,0,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2207744,2207744,2207744,2207744,2207744,2572288,2207744,2207744,2207744,1098,97,97,97,97,97,1104,97,97,97,97,97,97,97,97,97,1356,97,97,97,97,97,97,1128,97,97,97,97,97,97,1134,97,1136,97,1139,97,97,97,97,97,97,1622,97,97,97,97,97,97,97,97,0,921,0,0,0,1176,0,646,45,67,67,67,1268,67,67,67,67,67,67,67,67,67,67,67,67,1469,67,67,67,97,1348,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1127,97,67,1569,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1448,1449,67,1816,67,67,67,67,67,67,67,67,67,1825,67,67,1827,97,97,0,1781,97,97,97,97,97,97,0,0,97,97,0,97,97,97,1831,0,0,97,97,97,97,97,0,0,0,97,97,97,1980,97,45,45,45,45,45,45,45,45,45,45,1395,45,45,45,45,45,97,1846,97,97,45,45,45,45,45,45,45,45,45,45,45,45,1212,45,45,45,45,45,45,2010,45,67,67,67,67,67,2016,67,97,97,0,0,97,97,97,0,97,97,97,97,97,45,45,2007,0,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,143,45,45,45,1671,45,45,45,45,45,45,45,45,45,45,45,67,1813,67,67,1815,45,45,67,210,67,67,67,67,67,67,239,67,67,67,67,67,67,67,1454,67,67,67,67,67,67,67,67,67,1445,67,67,67,67,67,67,97,97,290,97,97,97,97,97,97,319,97,97,97,97,97,97,303,97,97,317,97,97,97,97,97,97,305,97,97,97,97,97,97,97,97,97,899,97,97,97,97,97,97,375,45,45,45,379,45,45,390,45,45,394,45,45,45,45,45,443,45,45,45,45,45,45,45,45,67,67,67,67,67,461,67,67,67,465,67,67,476,67,67,480,67,67,67,67,67,67,1694,67,67,67,67,67,67,67,67,67,1288,67,67,67,67,67,67,500,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1075,97,97,97,558,97,97,97,562,97,97,573,97,97,577,97,97,97,97,97,895,97,97,97,97,97,97,903,97,97,97,0,97,97,1638,97,97,97,97,97,97,97,97,1646,597,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1334,45,681,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1396,45,45,1399,45,45,730,45,45,45,45,67,67,67,67,67,67,67,67,67,67,1434,67,67,67,67,67,67,750,67,67,67,67,67,67,67,67,67,67,1456,67,67,67,67,67,45,45,993,45,45,45,45,45,45,45,45,45,45,45,67,67,1238,67,67,1006,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1280,1048,1049,67,67,67,67,67,67,67,67,67,67,1059,67,67,67,67,67,67,1286,67,67,67,67,67,67,67,1291,67,97,97,1100,97,97,97,97,97,97,97,97,97,97,97,97,97,638,0,920,97,97,1142,1143,97,97,97,97,97,97,97,97,97,97,1153,97,97,97,97,97,1158,97,97,97,1161,97,97,97,97,1166,97,97,97,97,97,1325,97,97,97,97,97,97,97,97,97,97,1328,97,97,97,97,97,97,97,45,1218,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1678,45,45,45,67,67,67,67,67,1269,67,67,67,67,67,67,67,67,1278,67,67,67,67,67,67,1761,67,67,67,67,67,67,67,67,67,530,67,67,67,67,67,67,97,97,1349,97,97,97,97,97,97,97,97,1358,97,97,97,97,97,97,1623,97,97,97,97,97,97,97,97,0,921,0,0,926,0,0,0,45,45,1411,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1754,45,45,67,67,1301,0,1307,0,1313,97,97,97,97,97,97,97,97,97,97,97,21054,97,97,97,97,67,1757,67,67,67,1760,67,67,67,67,67,67,67,67,67,67,1467,67,67,67,67,67,1778,97,0,0,97,97,97,97,97,97,0,0,97,97,0,97,97,97,97,97,1352,97,97,97,97,97,97,97,97,97,97,1511,97,97,97,97,97,67,67,67,67,67,1820,67,1822,67,67,67,67,67,97,97,97,97,97,0,0,0,97,1933,97,1892,97,97,97,97,97,97,1899,45,45,45,45,45,45,45,45,1664,45,45,45,45,45,45,45,45,1546,45,45,45,45,45,45,45,45,1208,45,45,45,45,45,45,45,45,1224,45,45,45,45,45,45,45,45,673,45,45,45,45,45,45,45,67,67,67,67,67,1925,97,97,97,97,0,0,0,97,97,97,97,97,623,97,97,97,97,97,97,97,97,97,97,307,97,97,97,97,97,97,97,97,97,1796,97,45,45,45,45,45,45,45,970,45,45,45,45,45,45,45,45,1417,45,45,45,45,45,45,45,67,1964,67,67,97,97,97,97,0,0,0,97,97,97,97,0,97,97,97,97,97,97,1721,97,97,0,0,1997,97,0,0,2e3,97,97,0,97,97,97,97,97,45,45,45,45,733,45,67,67,67,67,67,67,67,67,67,67,803,67,67,67,67,67,0,94242,0,0,0,38,102439,0,0,106538,98347,28809,45,45,144,45,45,45,1805,45,1807,45,45,45,45,45,67,67,67,67,67,67,231,67,67,67,67,67,67,67,0,24850,12564,0,0,0,0,28809,53531,45,45,67,211,67,67,67,67,230,234,240,244,67,67,67,67,67,67,464,67,67,67,67,67,67,479,67,67,67,260,67,67,67,67,67,0,24850,12564,0,0,0,0,28809,53531,97,97,291,97,97,97,97,310,314,320,324,97,97,97,97,97,97,1367,97,97,97,97,97,97,97,97,97,1355,97,97,97,97,97,97,1362,340,97,97,97,97,97,0,40976,0,18,18,24,24,27,27,27,131427,0,0,360,0,362,0,365,28809,367,139,369,45,45,45,374,67,67,460,67,67,67,67,466,67,67,67,67,67,67,67,67,801,67,67,67,67,67,67,67,67,67,487,67,67,67,67,67,67,67,67,67,67,498,67,67,67,67,67,67,1772,67,67,97,97,97,97,97,97,97,0,921,922,1175,0,0,0,0,45,67,502,67,67,67,67,67,67,67,508,67,67,67,515,517,67,67,67,67,67,97,97,97,97,97,0,0,0,1932,97,97,0,1999,97,97,97,0,97,97,2004,2005,97,45,45,45,45,1193,45,45,45,45,45,45,45,45,45,45,45,676,45,45,45,45,67,24850,24850,12564,12564,0,57889,0,0,0,53531,53531,367,286,552,97,97,97,97,97,1377,0,0,45,45,45,45,45,45,45,45,655,45,45,45,45,45,45,45,97,97,557,97,97,97,97,563,97,97,97,97,97,97,97,97,1135,97,97,97,97,97,97,97,97,97,584,97,97,97,97,97,97,97,97,97,97,595,97,97,97,97,97,911,97,97,97,97,97,97,97,638,0,0,0,0,1315,0,0,0,0,97,97,97,1319,97,97,97,0,97,97,97,97,97,97,1733,97,97,97,97,97,97,1340,97,97,97,1343,97,97,1345,97,1346,97,599,97,97,97,97,97,97,97,605,97,97,97,612,614,97,97,97,97,97,1794,97,97,97,45,45,45,45,45,45,45,1207,45,45,45,45,45,45,1213,45,45,745,67,67,67,67,751,67,67,67,67,67,67,67,67,67,67,1577,67,67,67,67,67,762,67,67,67,67,766,67,67,67,67,67,67,67,67,67,67,1765,67,67,67,67,67,777,67,67,781,67,67,67,67,67,67,67,67,67,67,67,67,1592,1593,67,67,97,843,97,97,97,97,849,97,97,97,97,97,97,97,97,97,1510,97,97,97,97,97,97,97,860,97,97,97,97,864,97,97,97,97,97,97,97,97,97,1797,45,45,45,45,1801,45,97,875,97,97,879,97,97,97,97,97,97,97,97,97,97,97,1522,97,97,97,97,97,991,45,45,45,45,996,45,45,45,45,45,45,45,45,67,67,215,67,67,67,67,233,67,67,67,67,251,253,1022,67,67,67,1026,67,67,67,67,67,67,67,67,67,67,1035,67,67,1038,67,67,67,67,67,67,67,67,67,67,67,67,67,1458,67,67,67,67,67,1064,67,67,67,1067,67,67,67,67,1072,67,67,67,67,67,67,1296,0,0,0,0,0,0,0,0,0,2367488,2158592,2158592,2158592,2158592,2158592,2158592,67,67,67,67,67,25398,0,13112,0,54074,0,0,0,0,1096,0,921,29315,0,0,0,0,928,45,45,45,45,45,934,45,45,45,164,45,45,45,45,45,45,45,45,45,198,45,45,45,378,45,45,45,45,45,45,393,45,45,45,398,45,97,97,1116,97,97,97,1120,97,97,97,97,97,97,97,97,97,1147,1148,97,97,97,97,97,97,97,1129,97,97,1132,97,97,97,97,97,97,97,97,97,97,97,1626,97,97,97,97,0,45,1178,45,45,45,45,45,45,45,45,45,1185,45,45,45,45,441,45,45,45,45,45,45,451,45,45,67,67,67,67,67,227,67,67,67,67,67,67,67,67,1260,67,67,67,1263,67,67,1265,1203,45,45,1205,45,1206,45,45,45,45,45,45,45,45,45,1216,67,1266,67,67,67,67,67,67,67,67,67,1276,67,67,67,67,67,67,492,67,67,67,67,67,67,67,67,67,471,67,67,67,67,481,67,45,1386,45,1389,45,45,45,45,1394,45,45,45,1397,45,45,45,45,995,45,997,45,45,45,45,45,45,45,67,67,67,67,1915,67,67,67,67,67,1422,45,45,45,67,67,67,67,67,67,67,67,67,1433,67,1436,67,67,67,67,1441,67,67,67,1444,67,67,67,67,67,67,67,0,24850,12564,0,0,0,281,28809,53531,97,97,97,97,1494,97,97,97,1497,97,97,97,97,97,97,97,1368,97,97,97,97,97,97,97,97,851,97,97,97,97,97,97,97,67,67,67,1571,67,67,67,67,67,67,67,67,67,67,67,67,25398,542,13112,544,67,67,1583,67,67,67,67,67,67,67,67,1591,67,67,67,67,67,67,752,67,67,67,67,67,67,67,67,67,1056,67,67,67,67,67,67,97,1634,97,0,97,97,97,97,97,97,97,97,97,97,97,97,1125,97,97,97,1647,97,97,97,97,97,0,45,45,45,45,45,45,45,45,45,1183,45,45,45,45,45,45,45,45,45,409,45,45,45,45,45,45,1658,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1668,1712,97,97,97,0,97,97,97,97,97,97,97,97,97,0,0,1835,97,97,97,97,0,0,0,97,97,1844,97,97,1726,0,97,97,97,97,97,1732,97,1734,97,97,97,97,97,300,97,308,97,97,97,97,97,97,97,97,866,97,97,97,97,97,97,97,67,67,67,1758,67,67,67,1762,67,67,67,67,67,67,67,67,1043,67,67,67,67,67,67,67,67,67,67,67,67,1771,67,67,67,97,97,97,97,97,1776,97,97,97,97,297,97,97,97,97,97,97,97,97,97,97,97,1108,97,97,97,97,67,67,67,1966,97,97,97,1970,0,0,0,97,97,97,97,0,97,97,97,1720,97,97,97,97,97,0,0,97,97,97,1837,97,0,1840,1841,97,97,97,1988,45,67,67,67,67,67,67,67,67,67,1994,1995,67,97,97,97,97,97,1103,97,97,97,97,97,97,97,97,97,97,917,97,97,0,0,0,67,67,265,67,67,67,67,0,24850,12564,0,0,0,0,28809,53531,97,345,97,97,97,97,0,40976,0,18,18,24,24,27,27,27,131427,0,0,0,361,362,0,365,28809,367,139,45,45,45,45,45,671,45,45,45,45,45,45,45,45,45,45,411,45,45,414,45,45,45,45,377,45,45,45,386,45,45,45,45,45,45,45,45,45,1223,45,45,45,45,45,45,45,45,45,426,45,45,433,45,45,45,67,67,67,67,67,463,67,67,67,472,67,67,67,67,67,67,67,527,67,67,67,67,67,67,537,67,540,24850,24850,12564,12564,0,57889,0,0,0,53531,53531,367,286,97,97,97,97,97,1119,97,97,97,97,97,97,97,97,97,97,1509,97,97,97,97,97,97,97,97,564,97,97,97,97,97,97,97,637,18,131427,0,0,0,0,0,0,362,0,0,365,29315,367,0,921,29315,0,0,0,927,45,45,45,45,45,45,45,45,45,1234,45,45,45,45,67,67,67,67,1240,45,697,45,45,45,45,45,45,45,45,45,45,708,45,45,45,45,1221,45,45,45,45,1225,45,45,45,45,45,45,384,45,45,45,45,45,45,45,45,45,1210,45,45,45,45,45,45,67,67,795,67,67,67,67,67,67,67,67,67,67,67,67,67,1470,67,67,67,67,67,67,67,815,67,67,67,67,67,67,25398,542,13112,544,97,97,97,893,97,97,97,97,97,97,97,97,97,97,97,97,1164,97,97,97,67,67,67,1025,67,67,67,67,67,67,67,67,67,67,67,67,1687,67,67,67,67,67,67,67,67,67,25398,0,13112,0,54074,0,0,0,0,0,1097,1241,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1450,45,45,1388,45,1390,45,45,45,45,45,45,45,45,45,45,45,1236,67,67,67,67,67,1437,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1472,1490,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1503,67,67,67,67,67,97,97,97,97,97,0,1930,0,97,97,97,97,97,847,97,97,97,97,97,97,97,97,97,858,67,67,1965,67,97,97,97,97,0,0,0,97,97,97,97,0,97,97,1719,97,97,97,97,97,97,0,0,0,45,45,45,45,1382,45,1383,45,45,45,159,45,45,45,45,45,45,45,45,45,45,45,45,45,1563,45,45,45,45,45,67,261,67,67,67,67,67,0,24850,12564,0,0,0,0,28809,53531,341,97,97,97,97,97,0,40976,0,18,18,24,24,27,27,27,97,1099,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1333,97,1230,45,45,45,45,45,45,45,45,45,45,67,67,67,67,67,67,1992,67,1993,67,67,67,97,97,45,45,160,45,45,45,45,45,45,45,45,45,45,45,45,45,1665,45,45,45,45,45,131427,357,0,0,0,362,0,365,28809,367,139,45,45,45,45,45,684,45,45,45,45,45,45,45,45,45,45,412,45,45,45,416,45,45,45,440,45,45,45,45,45,45,45,45,45,45,45,67,67,1990,67,1991,67,67,67,67,67,67,67,97,97,1707,97,97,97,97,97,97,501,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,1691,67,67,67,67,67,526,67,67,67,67,67,67,67,67,67,67,1030,67,1032,67,67,67,67,598,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,1632,0,921,29315,923,0,0,0,45,45,45,45,45,45,45,45,45,1404,45,45,45,45,45,45,45,45,45,425,45,45,45,45,45,45,67,67,67,67,67,25398,0,13112,0,54074,0,0,1093,0,0,0,0,0,97,1609,97,97,97,97,97,97,97,97,97,1369,97,97,97,1372,97,97,67,67,266,67,67,67,67,0,24850,12564,0,0,0,0,28809,53531,97,346,97,97,97,97,0,40976,0,18,18,24,24,27,27,27,665,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,1677,45,45,45,45,67,45,45,954,45,956,45,45,45,45,45,45,45,45,45,45,45,1545,45,45,45,45,45,45,45,45,45,448,45,45,45,45,67,456,67,67,67,67,67,1270,67,67,67,67,67,67,67,67,67,67,1069,67,67,67,67,67,67,97,97,97,1350,97,97,97,97,97,97,97,97,97,97,97,97,1524,97,97,97,97,97,97,97,1376,0,0,0,45,45,45,45,45,45,45,45,1559,1561,45,45,45,1564,45,1566,1567,45,67,67,67,67,67,1573,67,67,67,67,67,67,67,67,67,67,1247,67,67,67,67,67,1252,97,1725,97,0,97,97,97,97,97,97,97,97,97,97,97,97,1628,97,1630,0,0,94242,0,0,0,2211840,0,1118208,0,0,0,0,2158592,2158731,2158592,2158592,2158592,3117056,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,3018752,2158592,3043328,2158592,2158592,2158592,2158592,3080192,2158592,2158592,3112960,2158592,2158592,2158592,2158592,2158592,2158878,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2605056,2158592,2158592,2207744,0,542,0,544,0,0,2166784,0,0,0,550,0,0,2158592,2158592,2686976,2158592,2715648,2158592,2158592,2158592,2158592,2158592,2158592,2158592,2867200,2158592,2904064,2158592,2158592,2158592,2158592,2158592,2158592,2158592,0,94242,0,0,0,2211840,0,0,1130496,0,0,0,2158592,2158592,2158592,2158592,2158592,3186688,2158592,0,0,139,0,0,0,139,0,2367488,2207744,0,0,0,0,176128,0,2166784,0,0,0,0,0,286,2158592,2158592,3170304,3174400,2158592,0,0,0,2158592,2158592,2158592,2158592,2158592,2424832,2158592,2158592,2158592,1508,2158592,2908160,2158592,2158592,2158592,2977792,2158592,2158592,2158592,2158592,3039232,2158592,2158592,2158592,2158592,2158592,2158592,3158016,67,24850,24850,12564,12564,0,0,0,0,0,53531,53531,0,286,97,97,97,97,97,1144,97,97,97,97,97,97,97,97,97,97,1149,97,97,97,97,1154,57889,0,0,0,0,550,0,97,97,97,97,97,97,97,97,97,561,97,97,97,97,97,97,576,97,97,139264,139264,139264,139264,139264,139264,139264,139264,139264,139264,139264,139264,0,0,139264,0,921,29315,0,0,926,0,45,45,45,45,45,45,45,45,45,719,720,45,45,45,45,45,45,45,45,685,45,45,45,45,45,45,45,45,45,942,45,45,946,45,45,45,950,45,45,0,2146304,2146304,0,0,0,0,2224128,2224128,2224128,2232320,2232320,2232320,2232320,0,0,1301,0,0,0,0,0,1307,0,0,0,0,0,1313,0,0,0,0,0,0,0,97,97,1318,97,97,97,97,97,97,1795,97,97,45,45,45,45,45,45,45,446,45,45,45,45,45,45,67,67,2158592,2146304,0,0,0,0,0,0,0,2211840,0,0,0,0,2158592,0,921,29315,0,924,0,0,45,45,45,45,45,45,45,45,45,1e3,45,45,45,45,67,67],r.EXPECTED=[290,300,304,353,296,309,305,319,315,324,328,352,354,334,338,330,320,345,349,293,358,362,341,366,312,370,374,378,382,386,390,394,398,737,402,634,439,604,634,634,634,634,408,634,634,634,404,634,634,634,457,634,634,963,634,634,413,634,634,634,634,634,634,634,663,418,422,903,902,426,431,548,634,437,521,919,443,615,409,449,455,624,731,751,634,461,465,672,470,469,474,481,485,477,489,493,629,542,497,505,603,602,991,648,510,804,634,515,958,526,525,530,768,634,546,552,711,710,593,558,562,618,566,570,574,578,582,586,590,608,612,660,822,821,634,622,596,444,628,533,724,633,640,653,647,652,536,1008,451,450,445,657,670,676,685,689,693,697,701,704,707,715,719,798,815,634,723,762,996,634,728,969,730,735,908,634,741,679,889,511,747,634,750,755,499,666,499,501,759,772,776,780,634,787,784,797,802,809,808,427,814,1006,517,634,519,853,634,813,850,793,634,819,826,833,832,837,843,847,857,861,863,867,871,875,879,883,643,887,539,980,979,634,893,944,634,900,896,634,907,933,506,912,917,828,433,636,635,554,961,923,930,927,937,941,634,634,634,974,948,952,985,913,968,967,743,634,973,839,634,978,599,634,984,989,765,444,995,1e3,634,1003,790,955,1012,681,634,634,634,634,634,414,1016,1020,1024,1085,1027,1090,1090,1046,1080,1137,1108,1215,1049,1032,1039,1085,1085,1085,1085,1058,1062,1068,1085,1086,1090,1090,1091,1072,1064,1107,1090,1090,1090,1118,1123,1138,1078,1074,1084,1085,1085,1085,1087,1090,1062,1052,1060,1114,1062,1104,1085,1085,1090,1090,1028,1122,1063,1128,1139,1127,1158,1085,1085,1151,1090,1090,1090,1095,1090,1132,1073,1136,1143,1061,1150,1085,1155,1098,1101,1146,1162,1169,1101,1185,1151,1090,1110,1173,1054,1087,1109,1177,1165,1089,1204,1184,1107,1189,1193,1088,1197,1180,1201,1208,1042,1212,1219,1223,1227,1231,1235,1245,1777,1527,1686,1686,1238,1686,1254,1686,1686,1686,1294,1669,1686,1686,1686,1322,1625,1534,1268,1624,1275,1281,1443,1292,1300,1686,1686,1686,1350,1826,1306,1686,1686,1240,2032,1317,1321,1686,1686,1253,1686,1326,1686,1686,1686,1418,1709,1446,1686,1686,1686,1492,1686,1295,1447,1686,1686,1258,1686,1736,1686,1686,1520,1355,1686,1288,1348,1361,1686,1359,1686,1364,1498,1368,1302,1362,1381,1389,1395,1486,1686,1371,1377,1370,1686,1375,1382,1384,1402,1408,1385,1383,1619,1413,1423,1428,1433,1686,1686,1270,1686,1338,1686,1440,1686,1686,1686,1499,1465,1686,1686,1686,1639,1473,1884,1686,1686,1293,1864,1686,1686,1296,1321,1483,1686,1686,1686,1646,1686,1748,1496,1686,1418,1675,1686,1418,1702,1686,1418,1981,1686,1429,1409,1427,1504,1692,1686,1686,1313,1448,1651,1508,1686,1686,1340,1686,1903,1686,1686,1435,1513,1686,1283,1287,1519,1686,1524,1363,1568,1938,1539,1566,1579,1479,1533,1538,1553,1544,1552,1557,1563,1574,1557,1583,1589,1590,1759,1594,1603,1607,1611,1686,1436,1514,1686,1434,1656,1686,1434,1680,1686,1453,1686,1686,1686,1559,1617,1686,1770,1418,1623,1769,1629,1686,1515,1335,1686,1285,1686,1671,1921,1650,1686,1686,1344,1308,1666,1686,1686,1686,1659,1685,1686,1686,1686,1686,1241,1686,1686,1844,1691,1686,1630,1977,1970,1362,1686,1686,1686,1693,1698,1686,1686,1686,1697,1686,1764,1715,1686,1634,1638,1686,1599,1585,1686,1271,1686,1269,1686,1721,1686,1686,1354,1686,1801,1686,1799,1686,1640,1686,1686,1461,1686,1686,1732,1686,1944,1686,1740,1686,1746,1415,1396,1686,1598,1547,1417,1597,1416,1577,1546,1397,1577,1547,1548,1570,1398,1753,1686,1652,1509,1686,1686,1686,1757,1686,1419,1686,1763,1418,1768,1781,1686,1686,1686,1705,1686,2048,1792,1686,1686,1686,1735,1686,1797,1686,1686,1404,1686,1639,1815,1686,1686,1418,2017,1820,1686,1686,1803,1686,1686,1686,1736,1489,1686,1686,1825,1338,1260,1263,1686,1686,1785,1686,1686,1728,1686,1686,1749,1497,1830,1830,1262,1248,1261,1329,1260,1264,1329,1248,1249,1259,1540,1849,1842,1686,1686,1835,1686,1686,1816,1686,1686,1831,1882,1848,1686,1686,1686,1774,2071,1854,1686,1686,1469,1884,1686,1821,1859,1686,1686,1350,1883,1686,1686,1686,1781,1391,1875,1686,1686,1613,1644,1686,1686,1889,1686,1686,1662,1884,1686,1885,1890,1686,1686,1686,1894,1686,1686,1678,1686,1907,1686,1686,1529,1914,1686,1838,1686,1686,1881,1686,1686,1872,1876,1836,1919,1686,1837,1692,1910,1686,1925,1928,1742,1686,1811,1811,1930,1810,1929,1935,1928,1900,1942,1867,1868,1931,1035,1788,1948,1952,1956,1960,1964,1686,1976,1686,1686,1686,2065,1686,1992,2037,1686,1686,1998,2009,1972,2002,1686,1686,1686,2077,1300,2023,1686,1686,1686,1807,2031,1686,1686,1686,1860,1500,2032,1686,1686,1686,2083,1686,2036,1686,1277,1276,2042,1877,1686,1686,2041,1686,1686,2027,2037,2012,1686,2012,1855,1850,1686,2046,1686,1686,2054,1996,1686,1897,1309,2059,2052,1686,2058,1686,1686,2081,1686,1717,1477,1686,1331,1686,1686,1687,1686,1860,1681,1686,1686,1686,1966,1724,1686,1686,1686,1984,2015,1686,1686,1686,1988,1686,2063,1686,1686,1686,2005,1686,1727,1686,1686,1711,1457,2069,1686,1686,1686,2019,2075,1686,1686,1915,1686,1686,1793,1874,1686,1686,1491,1362,1449,1686,1686,1460,2098,2087,2091,2095,2184,2102,2113,2780,2117,2134,2142,2281,2146,2146,2146,2304,2296,2181,2639,2591,2872,2592,2873,2313,2195,2200,2281,2146,2273,2226,2204,2152,2219,2276,2167,2177,2276,2235,2276,2276,2230,2281,2276,2296,2276,2293,2276,2276,2276,2276,2234,2276,2311,2314,2210,2199,2217,2222,2276,2276,2276,2240,2276,2294,2276,2276,2173,2276,2198,2281,2281,2281,2281,2282,2146,2146,2146,2146,2205,2146,2204,2248,2276,2235,2276,2297,2276,2276,2276,2277,2256,2281,2283,2146,2146,2146,2275,2276,2295,2276,2276,2293,2146,2304,2264,2269,2221,2276,2276,2276,2293,2295,2276,2276,2276,2295,2263,2205,2268,2220,2172,2276,2276,2276,2296,2276,2276,2296,2294,2276,2276,2278,2281,2281,2280,2281,2281,2281,2283,2206,2223,2276,2276,2279,2281,2281,2146,2273,2276,2276,2281,2281,2281,2276,2292,2276,2298,2225,2276,2298,2169,2224,2292,2298,2171,2229,2281,2281,2171,2236,2281,2281,2281,2146,2275,2225,2292,2299,2276,2229,2281,2146,2276,2290,2297,2283,2146,2146,2274,2224,2227,2298,2225,2297,2276,2230,2170,2230,2282,2146,2147,2151,2156,2288,2276,2230,2303,2308,2236,2284,2228,2318,2318,2318,2326,2335,2339,2343,2349,2416,2693,2357,2592,2109,2592,2592,2162,2943,2823,2646,2592,2361,2592,2122,2592,2592,2122,2470,2592,2592,2592,2109,2107,2592,2592,2592,2123,2592,2592,2592,2125,2592,2413,2592,2592,2592,2127,2592,2592,2414,2592,2592,2592,2130,2952,2592,2594,2592,2592,2212,2609,2252,2592,2592,2592,2446,2434,2592,2592,2592,2212,2446,2450,2456,2431,2435,2592,2592,2243,2478,2448,2439,2946,2592,2592,2592,2368,2809,2813,2450,2441,2212,2812,2449,2440,2947,2592,2592,2592,2345,2451,2457,2948,2592,2124,2592,2592,2650,2823,2449,2455,2946,2592,2128,2592,2592,2649,2952,2592,2810,2448,2461,2991,2467,2592,2592,2329,2817,2474,2990,2466,2592,2592,2373,2447,2992,2469,2592,2592,2592,2373,2447,2477,2468,2592,2592,2353,2469,2592,2495,2592,2592,2415,2483,2592,2415,2496,2592,2592,2352,2592,2592,2352,2352,2469,2592,2592,2363,2331,2494,2592,2592,2592,2375,2592,2375,2415,2504,2592,2592,2367,2372,2503,2592,2592,2592,2389,2418,2415,2592,2592,2373,2592,2592,2592,2593,2732,2417,2415,2592,2417,2520,2592,2592,2592,2390,2521,2521,2592,2592,2592,2401,2599,2585,2526,2531,2120,2592,2212,2426,2450,2463,2948,2592,2592,2592,2213,2389,2527,2532,2121,2542,2551,2105,2592,2213,2592,2592,2592,2558,2538,2544,2553,2557,2537,2543,2552,2421,2572,2576,2546,2543,2547,2592,2592,2373,2615,2575,2545,2105,2592,2244,2479,2592,2129,2592,2592,2628,2690,2469,2562,2566,2592,2592,2592,2415,2928,2934,2401,2570,2574,2564,2572,2585,2590,2592,2592,2585,2965,2592,2592,2592,2445,2251,2592,2592,2592,2474,2592,2609,2892,2592,2362,2592,2592,2138,2851,2159,2592,2592,2592,2509,2888,2892,2592,2592,2592,2490,2418,2891,2592,2592,2376,2592,2592,2374,2592,2889,2388,2592,2373,2373,2890,2592,2592,2387,2592,2887,2505,2892,2592,2373,2610,2388,2592,2592,2376,2373,2592,2887,2891,2592,2374,2592,2592,2608,2159,2614,2620,2592,2592,2394,2594,2887,2399,2592,2887,2397,2508,2374,2507,2592,2375,2592,2592,2592,2595,2508,2506,2592,2506,2505,2505,2592,2507,2637,2505,2592,2592,2401,2661,2592,2643,2592,2592,2417,2592,2655,2592,2592,2592,2510,2414,2656,2592,2592,2592,2516,2592,2593,2660,2665,2880,2592,2592,2592,2522,2767,2666,2881,2592,2592,2420,2571,2696,2592,2592,2592,2580,2572,2686,2632,2698,2592,2383,2514,2592,2163,2932,2465,2685,2631,2697,2592,2388,2592,2592,2212,2604,2671,2632,2678,2592,2401,2405,2409,2592,2592,2592,2679,2592,2592,2592,2592,2108,2677,2591,2592,2592,2592,2419,2592,2683,2187,2191,2469,2671,2189,2467,2592,2401,2629,2633,2702,2468,2592,2592,2421,2536,2703,2469,2592,2592,2422,2573,2593,2672,2467,2592,2402,2406,2592,2402,2979,2592,2592,2626,2673,2467,2592,2446,2259,2947,2592,2377,2709,2592,2592,2522,2862,2713,2468,2592,2592,2581,2572,2562,2374,2374,2592,2376,2721,2724,2592,2592,2624,2373,2731,2592,2592,2592,2626,2732,2592,2592,2592,2755,2656,2726,2736,2741,2592,2486,2593,2381,2592,2727,2737,2742,2715,2747,2753,2592,2498,2469,2873,2743,2592,2592,2592,2791,2759,2763,2592,2592,2627,2704,2592,2592,2522,2789,2593,2761,2753,2592,2498,2863,2592,2592,2767,2592,2592,2592,2792,2789,2592,2592,2592,2803,2126,2592,2592,2592,2811,2122,2592,2592,2592,2834,2777,2592,2592,2592,2848,2936,2591,2489,2797,2592,2592,2670,2631,2490,2798,2592,2592,2592,2963,2807,2592,2592,2592,2965,2838,2592,2592,2592,2975,2330,2818,2829,2592,2498,2939,2592,2498,2592,2791,2331,2819,2830,2592,2592,2592,2982,2834,2817,2828,2106,2592,2592,2592,2405,2405,2817,2828,2592,2592,2415,2849,2842,2592,2522,2773,2592,2522,2868,2592,2580,2600,2586,2137,2850,2843,2592,2592,2855,2937,2844,2592,2592,2592,2987,2936,2591,2592,2592,2684,2630,2592,2856,2938,2592,2592,2860,2939,2592,2592,2872,2592,2861,2591,2592,2592,2887,2616,2592,2867,2592,2592,2708,2592,2498,2469,2498,2497,2785,2773,2499,2783,2770,2877,2877,2877,2772,2592,2592,2345,2885,2592,2592,2592,2715,2762,2515,2896,2592,2592,2715,2917,2516,2897,2592,2592,2592,2901,2906,2911,2592,2592,2956,2960,2715,2902,2907,2912,2593,2916,2920,2820,2922,2822,2592,2592,2715,2927,2921,2821,2106,2592,2592,2974,2408,2321,2821,2106,2592,2592,2983,2592,2593,2404,2408,2592,2592,2717,2749,2716,2928,2322,2822,2593,2926,2919,2820,2934,2823,2592,2592,2592,2651,2824,2592,2592,2592,2130,2952,2592,2592,2592,2592,2964,2592,2592,2716,2748,2592,2969,2592,2592,2716,2918,2368,2970,2592,2592,2592,2403,2407,2592,2592,2787,2211,2404,2409,2592,2592,2802,2837,2987,2592,2592,2592,2809,2427,2592,2793,2592,2592,2809,2447,1073741824,2147483648,539754496,542375936,402653184,554434560,571736064,545521856,268451840,335544320,268693630,512,2048,256,1024,0,1024,0,1073741824,2147483648,0,0,0,8388608,0,0,1073741824,1073741824,0,2147483648,537133056,4194304,1048576,268435456,-1073741824,0,0,0,1048576,0,0,0,1572864,0,0,0,4194304,0,134217728,16777216,0,0,32,64,98304,0,33554432,8388608,192,67108864,67108864,67108864,67108864,16,32,4,0,8192,196608,196608,229376,80,4096,524288,8388608,0,0,32,128,256,24576,24600,24576,24576,2,24576,24576,24576,24584,24592,24576,24578,24576,24578,24576,24576,16,512,2048,2048,256,4096,32768,1048576,4194304,67108864,134217728,268435456,262144,134217728,0,128,128,64,16384,16384,16384,67108864,32,32,4,4,4096,262144,134217728,0,0,0,2,0,8192,131072,131072,4096,4096,4096,4096,24576,24576,24576,8,8,24576,24576,16384,16384,16384,24576,24584,24576,24576,24576,16384,24576,536870912,262144,0,0,32,2048,8192,4,4096,4096,4096,786432,8388608,16777216,0,128,16384,16384,16384,32768,65536,2097152,32,32,32,32,4,4,4,4,4,4096,67108864,67108864,67108864,24576,24576,24576,24576,0,16384,16384,16384,16384,67108864,67108864,8,67108864,24576,8,8,8,24576,24576,24576,24578,24576,24576,24576,2,2,2,16384,67108864,67108864,67108864,32,67108864,8,8,24576,2048,2147483648,536870912,262144,262144,262144,67108864,8,24576,16384,32768,1048576,4194304,25165824,67108864,24576,32770,2,4,112,512,98304,524288,50,402653186,1049090,1049091,10,66,100925514,10,66,12582914,0,0,-1678194207,-1678194207,-1041543218,0,32768,0,0,32,65536,268435456,1,1,513,1048577,0,12582912,0,0,0,4,1792,0,0,0,7,29360128,0,0,0,8,0,0,0,12,1,1,0,0,-604102721,-604102721,4194304,8388608,0,0,0,31,925600,997981306,997981306,997981306,0,0,2048,8388608,0,0,1,2,4,32,64,512,8192,0,0,0,245760,997720064,0,0,0,32,0,0,0,3,12,16,32,8,112,3072,12288,16384,32768,65536,131072,7864320,16777216,973078528,0,0,65536,131072,3670016,4194304,16777216,33554432,2,8,48,2048,8192,16384,32768,65536,131072,524288,131072,524288,3145728,4194304,16777216,33554432,65536,131072,2097152,4194304,16777216,33554432,134217728,268435456,536870912,0,0,0,1024,0,8,48,2048,8192,65536,33554432,268435456,536870912,65536,268435456,536870912,0,0,32768,0,0,126,623104,65011712,0,32,65536,536870912,0,0,65536,524288,0,32,65536,0,0,0,2048,0,0,0,15482,245760,-604102721,0,0,0,18913,33062912,925600,-605028352,0,0,0,65536,31,8096,131072,786432,3145728,3145728,12582912,50331648,134217728,268435456,160,256,512,7168,131072,786432,131072,786432,1048576,2097152,12582912,16777216,268435456,1073741824,2147483648,12582912,16777216,33554432,268435456,1073741824,2147483648,3,12,16,160,256,7168,786432,1048576,12582912,16777216,268435456,1073741824,0,8,16,32,128,256,512,7168,786432,1048576,2097152,0,1,2,8,16,7168,786432,1048576,8388608,16777216,16777216,1073741824,0,0,0,0,1,0,0,8,32,128,256,7168,8,32,0,3072,0,8,32,3072,4096,524288,8,32,0,0,3072,4096,0,2048,524288,8388608,8,2048,0,0,1,12,256,4096,32768,262144,1048576,4194304,67108864,0,2048,0,2048,2048,1073741824,-58805985,-58805985,-58805985,0,0,262144,0,0,32,4194304,16777216,134217728,4382,172032,-58982400,0,0,2,28,256,4096,8192,8192,32768,131072,262144,524288,1,2,12,256,4096,0,0,4194304,67108864,134217728,805306368,1073741824,0,0,1,2,12,16,256,4096,1048576,67108864,134217728,268435456,0,512,1048576,4194304,201326592,1879048192,0,0,12,256,4096,134217728,268435456,536870912,12,256,268435456,536870912,0,12,256,0,0,1,32,64,512,0,0,205236961,205236961,0,0,0,1,96,640,1,10976,229376,204996608,0,640,2048,8192,229376,1572864,1572864,2097152,201326592,0,0,0,64,512,2048,229376,1572864,201326592,1572864,201326592,0,0,1,4382,0,1,32,2048,65536,131072,1572864,201326592,131072,1572864,134217728,0,0,524288,524288,0,0,0,-68582786,-68582786,-68582786,0,0,2097152,524288,0,524288,0,0,65536,131072,1572864,0,0,2,4,0,0,65011712,-134217728,0,0,0,0,2,4,120,512,-268435456,0,0,0,2,8,48,64,2048,8192,98304,524288,2097152,4194304,25165824,33554432,134217728,268435456,2147483648,0,0,25165824,33554432,134217728,1879048192,2147483648,0,0,4,112,512,622592,65011712,134217728,-268435456,16777216,33554432,134217728,1610612736,0,0,0,64,98304,524288,4194304,16777216,33554432,0,98304,524288,16777216,33554432,0,65536,524288,33554432,536870912,1073741824,0,65536,524288,536870912,1073741824,0,0,65536,524288,536870912,0,524288,0,524288,524288,1048576,2086666240,2147483648,0,-1678194207,0,0,0,8,32,2048,524288,8388608,0,0,33062912,436207616,2147483648,0,0,32,64,2432,16384,32768,32768,524288,3145728,4194304,25165824,25165824,167772160,268435456,2147483648,0,32,64,384,2048,16384,32768,1048576,2097152,4194304,25165824,32,64,128,256,2048,16384,2048,16384,1048576,4194304,16777216,33554432,134217728,536870912,1073741824,0,0,2048,16384,4194304,16777216,33554432,134217728,805306368,0,0,16777216,134217728,268435456,2147483648,0,622592,622592,622592,8807,8807,434791,0,0,16777216,0,0,0,7,608,8192,0,0,0,3,4,96,512,32,64,8192,0,0,16777216,134217728,0,0,2,4,8192,16384,65536,2097152,33554432,268435456],r.TOKEN=["(0)","ModuleDecl","Annotation","OptionDecl","Operator","Variable","Tag","EndTag","PragmaContents","DirCommentContents","DirPIContents","CDataSectionContents","AttrTest","Wildcard","EQName","IntegerLiteral","DecimalLiteral","DoubleLiteral","PredefinedEntityRef","'\"\"'","EscapeApos","QuotChar","AposChar","ElementContentChar","QuotAttrContentChar","AposAttrContentChar","NCName","QName","S","CharRef","CommentContents","DocTag","DocCommentContents","EOF","'!'","'\"'","'#'","'#)'","''''","'('","'(#'","'(:'","'(:~'","')'","'*'","'*'","','","'-->'","'.'","'/'","'/>'","':'","':)'","';'","'<!--'","'<![CDATA['","'<?'","'='","'>'","'?'","'?>'","'NaN'","'['","']'","']]>'","'after'","'all'","'allowing'","'ancestor'","'ancestor-or-self'","'and'","'any'","'append'","'array'","'as'","'ascending'","'at'","'attribute'","'base-uri'","'before'","'boundary-space'","'break'","'by'","'case'","'cast'","'castable'","'catch'","'check'","'child'","'collation'","'collection'","'comment'","'constraint'","'construction'","'contains'","'content'","'context'","'continue'","'copy'","'copy-namespaces'","'count'","'decimal-format'","'decimal-separator'","'declare'","'default'","'delete'","'descendant'","'descendant-or-self'","'descending'","'diacritics'","'different'","'digit'","'distance'","'div'","'document'","'document-node'","'element'","'else'","'empty'","'empty-sequence'","'encoding'","'end'","'entire'","'eq'","'every'","'exactly'","'except'","'exit'","'external'","'first'","'following'","'following-sibling'","'for'","'foreach'","'foreign'","'from'","'ft-option'","'ftand'","'ftnot'","'ftor'","'function'","'ge'","'greatest'","'group'","'grouping-separator'","'gt'","'idiv'","'if'","'import'","'in'","'index'","'infinity'","'inherit'","'insensitive'","'insert'","'instance'","'integrity'","'intersect'","'into'","'is'","'item'","'json'","'json-item'","'key'","'language'","'last'","'lax'","'le'","'least'","'let'","'levels'","'loop'","'lowercase'","'lt'","'minus-sign'","'mod'","'modify'","'module'","'most'","'namespace'","'namespace-node'","'ne'","'next'","'no'","'no-inherit'","'no-preserve'","'node'","'nodes'","'not'","'object'","'occurs'","'of'","'on'","'only'","'option'","'or'","'order'","'ordered'","'ordering'","'paragraph'","'paragraphs'","'parent'","'pattern-separator'","'per-mille'","'percent'","'phrase'","'position'","'preceding'","'preceding-sibling'","'preserve'","'previous'","'processing-instruction'","'relationship'","'rename'","'replace'","'return'","'returning'","'revalidation'","'same'","'satisfies'","'schema'","'schema-attribute'","'schema-element'","'score'","'self'","'sensitive'","'sentence'","'sentences'","'skip'","'sliding'","'some'","'stable'","'start'","'stemming'","'stop'","'strict'","'strip'","'structured-item'","'switch'","'text'","'then'","'thesaurus'","'times'","'to'","'treat'","'try'","'tumbling'","'type'","'typeswitch'","'union'","'unique'","'unordered'","'updating'","'uppercase'","'using'","'validate'","'value'","'variable'","'version'","'weight'","'when'","'where'","'while'","'wildcards'","'window'","'with'","'without'","'word'","'words'","'xquery'","'zero-digit'","'{'","'{{'","'|'","'}'","'}}'"]},{}],2:[function(e,t,n){"use strict";var r=e("./XQueryTokenizer").XQueryTokenizer,i=function(e){var t=e;this.tokens=[],this.reset=function(){t=t,this.tokens=[]},this.startNonterminal=function(){},this.endNonterminal=function(){},this.terminal=function(e,n,r){this.tokens.push({name:e,value:t.substring(n,r)})},this.whitespace=function(e,n){this.tokens.push({name:"WS",value:t.substring(e,n)})}},s="after|ancestor|ancestor-or-self|and|as|ascending|attribute|before|case|cast|castable|child|collation|comment|copy|count|declare|default|delete|descendant|descendant-or-self|descending|div|document|document-node|element|else|empty|empty-sequence|end|eq|every|except|first|following|following-sibling|for|function|ge|group|gt|idiv|if|import|insert|instance|intersect|into|is|item|last|le|let|lt|mod|modify|module|namespace|namespace-node|ne|node|only|or|order|ordered|parent|preceding|preceding-sibling|processing-instruction|rename|replace|return|satisfies|schema-attribute|schema-element|self|some|stable|start|switch|text|to|treat|try|typeswitch|union|unordered|validate|where|with|xquery|contains|paragraphs|sentences|times|words|by|collectionreturn|variable|version|option|when|encoding|toswitch|catch|tumbling|sliding|window|at|using|stemming|collection|schema|while|on|nodes|index|external|then|in|updating|value|of|containsbreak|loop|continue|exit|returning|append|json|position|strict".split("|"),o=s.map(function(e){return{name:"'"+e+"'",token:"keyword"}}),u=s.map(function(e){return{name:"'"+e+"'",token:"text",next:function(e){e.pop()}}}),a="constant.language",f="constant",l="comment",c="xml-pe",h="constant.buildin",p=function(e){return"'"+e+"'"},d={start:[{name:p("(#"),token:h,next:function(e){e.push("Pragma")}},{name:p("(:"),token:"comment",next:function(e){e.push("Comment")}},{name:p("(:~"),token:"comment.doc",next:function(e){e.push("CommentDoc")}},{name:p("<!--"),token:l,next:function(e){e.push("XMLComment")}},{name:p("<?"),token:c,next:function(e){e.push("PI")}},{name:p("''"),token:"string",next:function(e){e.push("AposString")}},{name:p('"'),token:"string",next:function(e){e.push("QuotString")}},{name:"Annotation",token:"support.function"},{name:"ModuleDecl",token:"keyword",next:function(e){e.push("Prefix")}},{name:"OptionDecl",token:"keyword",next:function(e){e.push("_EQName")}},{name:"AttrTest",token:"support.type"},{name:"Variable",token:"variable"},{name:p("<![CDATA["),token:a,next:function(e){e.push("CData")}},{name:"IntegerLiteral",token:f},{name:"DecimalLiteral",token:f},{name:"DoubleLiteral",token:f},{name:"Operator",token:"keyword.operator"},{name:"EQName",token:function(e){return s.indexOf(e)!==-1?"keyword":"support.function"}},{name:p("("),token:"lparen"},{name:p(")"),token:"rparen"},{name:"Tag",token:"meta.tag",next:function(e){e.push("StartTag")}},{name:p("}"),token:"text",next:function(e){e.length>1&&e.pop()}},{name:p("{"),token:"text",next:function(e){e.push("start")}}].concat(o),_EQName:[{name:"EQName",token:"text",next:function(e){e.pop()}}].concat(u),Prefix:[{name:"NCName",token:"text",next:function(e){e.pop()}}].concat(u),StartTag:[{name:p(">"),token:"meta.tag",next:function(e){e.push("TagContent")}},{name:"QName",token:"entity.other.attribute-name"},{name:p("="),token:"text"},{name:p("''"),token:"string",next:function(e){e.push("AposAttr")}},{name:p('"'),token:"string",next:function(e){e.push("QuotAttr")}},{name:p("/>"),token:"meta.tag.r",next:function(e){e.pop()}}],TagContent:[{name:"ElementContentChar",token:"text"},{name:p("<![CDATA["),token:a,next:function(e){e.push("CData")}},{name:p("<!--"),token:l,next:function(e){e.push("XMLComment")}},{name:"Tag",token:"meta.tag",next:function(e){e.push("StartTag")}},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:p("{{"),token:"text"},{name:p("}}"),token:"text"},{name:p("{"),token:"text",next:function(e){e.push("start")}},{name:"EndTag",token:"meta.tag",next:function(e){e.pop(),e.pop()}}],AposAttr:[{name:p("''"),token:"string",next:function(e){e.pop()}},{name:"EscapeApos",token:"constant.language.escape"},{name:"AposAttrContentChar",token:"string"},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:p("{{"),token:"string"},{name:p("}}"),token:"string"},{name:p("{"),token:"text",next:function(e){e.push("start")}}],QuotAttr:[{name:p('"'),token:"string",next:function(e){e.pop()}},{name:"EscapeQuot",token:"constant.language.escape"},{name:"QuotAttrContentChar",token:"string"},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:p("{{"),token:"string"},{name:p("}}"),token:"string"},{name:p("{"),token:"text",next:function(e){e.push("start")}}],Pragma:[{name:"PragmaContents",token:h},{name:p("#"),token:h},{name:p("#)"),token:h,next:function(e){e.pop()}}],Comment:[{name:"CommentContents",token:"comment"},{name:p("(:"),token:"comment",next:function(e){e.push("Comment")}},{name:p(":)"),token:"comment",next:function(e){e.pop()}}],CommentDoc:[{name:"DocCommentContents",token:"comment.doc"},{name:"DocTag",token:"comment.doc.tag"},{name:p("(:"),token:"comment.doc",next:function(e){e.push("CommentDoc")}},{name:p(":)"),token:"comment.doc",next:function(e){e.pop()}}],XMLComment:[{name:"DirCommentContents",token:l},{name:p("-->"),token:l,next:function(e){e.pop()}}],CData:[{name:"CDataSectionContents",token:a},{name:p("]]>"),token:a,next:function(e){e.pop()}}],PI:[{name:"DirPIContents",token:c},{name:p("?"),token:c},{name:p("?>"),token:c,next:function(e){e.pop()}}],AposString:[{name:p("''"),token:"string",next:function(e){e.pop()}},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:"EscapeApos",token:"constant.language.escape"},{name:"AposChar",token:"string"}],QuotString:[{name:p('"'),token:"string",next:function(e){e.pop()}},{name:"PredefinedEntityRef",token:"constant.language.escape"},{name:"CharRef",token:"constant.language.escape"},{name:"EscapeQuot",token:"constant.language.escape"},{name:"QuotChar",token:"string"}]};n.XQueryLexer=function(){function e(e){e=e.slice(0).sort();var t,n,r;t=e[0],r=t.length,n=e.pop();while(r&&n.indexOf(t)===-1)t=t.substring(0,--r);return t}this.tokens=[],this.getLineTokens=function(t,n,s){n=n==="start"||!n?'["start"]':n;var o=JSON.parse(n),u=new i(t),a=new r(t,u),f=[];for(;;){var l=o[o.length-1];try{u.tokens=[],a["parse_"+l]();var c=null;u.tokens.length>1&&u.tokens[0].name==="WS"&&(f.push({type:"text",value:u.tokens[0].value}),u.tokens.splice(0,1));var h=u.tokens[0],p=d[l];for(var v=0;v<p.length;v++){var m=d[l][v];if(typeof m.name=="function"&&m.name(h)||m.name===h.name){c=m;break}}if(h.name==="EOF")break;if(h.value==="")throw"Encountered empty string lexical rule.";f.push({type:c===null?"text":typeof c.token=="function"?c.token(h.value):c.token,value:h.value}),c&&c.next&&c.next(o)}catch(g){if(g instanceof a.ParseException){var y=0;for(var b=0;b<f.length;b++)y+=f[b].value.length;return f.push({type:"text",value:t.substring(y)}),{tokens:f,state:JSON.stringify(["start"])}}throw g}}if(this.tokens[s]!==undefined){var w=this.lines[s],E=e([t,w]),S=w.length-t.length,x=0,T=0;for(var b=0;b<f.length;b++){var N=f[b];for(var C=0;C<this.tokens[s].length;C++){var k=this.tokens[s][C];if(T+N.value.length<=E.length&&k.sc===T&&k.ec===T+N.value.length||k.sc===T+S&&k.ec===T+N.value.length+S)x=b,N.type=k.type}T+=N.value.length}}return{tokens:f,state:JSON.stringify(o)}}}},{"./XQueryTokenizer":1}]},{},[2])(2)}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),ace.define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator"],function(e,t,n){"use strict";function o(e,t){return e.type.lastIndexOf(t+".xml")>-1}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,u=function(){this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){var u=i,a=r.doc.getTextRange(n.getSelectionRange());if(a!==""&&a!=="'"&&a!='"'&&n.getWrapBehavioursEnabled())return{text:u+a+u,selection:!1};var f=n.getCursorPosition(),l=r.doc.getLine(f.row),c=l.substring(f.column,f.column+1),h=new s(r,f.row,f.column),p=h.getCurrentToken();if(c==u&&(o(p,"attribute-value")||o(p,"string")))return{text:"",selection:[1,1]};p||(p=h.stepBackward());if(!p)return;while(o(p,"tag-whitespace")||o(p,"whitespace"))p=h.stepBackward();var d=!c||c.match(/\s/);if(o(p,"attribute-equals")&&(d||c==">")||o(p,"decl-attribute-equals")&&(d||c=="?"))return{text:u+u,selection:[1,1]}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}}),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var u=n.getCursorPosition(),a=new s(r,u.row,u.column),f=a.getCurrentToken()||a.stepBackward();if(!f||!(o(f,"tag-name")||o(f,"tag-whitespace")||o(f,"attribute-name")||o(f,"attribute-equals")||o(f,"attribute-value")))return;if(o(f,"reference.attribute-value"))return;if(o(f,"attribute-value")){var l=f.value.charAt(0);if(l=='"'||l=="'"){var c=f.value.charAt(f.value.length-1),h=a.getCurrentTokenColumn()+f.value.length;if(h>u.column||h==u.column&&l!=c)return}}while(!o(f,"tag-name"))f=a.stepBackward();var p=a.getCurrentTokenRow(),d=a.getCurrentTokenColumn();if(o(a.stepBackward(),"end-tag-open"))return;var v=f.value;p==u.row&&(v=v.substring(0,u.column-d));if(this.voidElements.hasOwnProperty(v.toLowerCase()))return;return{text:"></"+v+">",selection:[1,1]}}}),this.add("autoindent","insertion",function(e,t,n,r,i){if(i=="\n"){var s=n.getCursorPosition(),o=r.getLine(s.row),u=o.substring(s.column,s.column+2);if(u=="</"){var a=this.$getIndent(o),f=a+r.getTabString();return{text:"\n"+f+"\n"+a,selection:[1,f.length,1,f.length]}}}})};r.inherits(u,i),t.XmlBehaviour=u}),ace.define("ace/mode/behaviour/xquery",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/mode/behaviour/xml","ace/token_iterator"],function(e,t,n){"use strict";function a(e,t){var n=!0,r=e.type.split("."),i=t.split(".");return i.forEach(function(e){if(r.indexOf(e)==-1)return n=!1,!1}),n}var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("./cstyle").CstyleBehaviour,o=e("../behaviour/xml").XmlBehaviour,u=e("../../token_iterator").TokenIterator,f=function(){this.inherit(s,["braces","parens","string_dquotes"]),this.inherit(o),this.add("autoclosing","insertion",function(e,t,n,r,i){if(i==">"){var s=n.getCursorPosition(),o=new u(r,s.row,s.column),f=o.getCurrentToken(),l=!1,e=JSON.parse(e).pop();if(f&&f.value===">"||e!=="StartTag")return;if(!f||!a(f,"meta.tag")&&(!a(f,"text")||!f.value.match("/"))){do f=o.stepBackward();while(f&&(a(f,"string")||a(f,"keyword.operator")||a(f,"entity.attribute-name")||a(f,"text")))}else l=!0;var c=o.stepBackward();if(!f||!a(f,"meta.tag")||c!==null&&c.value.match("/"))return;var h=f.value.substring(1);if(l)var h=h.substring(0,s.column-f.start);return{text:"></"+h+">",selection:[1,1]}}})};r.inherits(f,i),t.XQueryBehaviour=f}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)}),ace.define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/anchor","ace/keyboard/hash_handler","ace/tokenizer","ace/lib/dom","ace/editor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./lib/lang"),o=e("./range").Range,u=e("./anchor").Anchor,a=e("./keyboard/hash_handler").HashHandler,f=e("./tokenizer").Tokenizer,l=o.comparePoints,c=function(){this.snippetMap={},this.snippetNameMap={}};(function(){r.implement(this,i),this.getTokenizer=function(){function e(e,t,n){return e=e.substr(1),/^\d+$/.test(e)&&!n.inFormatString?[{tabstopId:parseInt(e,10)}]:[{text:e}]}function t(e){return"(?:[^\\\\"+e+"]|\\\\.)"}return c.$tokenizer=new f({start:[{regex:/:/,onMatch:function(e,t,n){return n.length&&n[0].expectIf?(n[0].expectIf=!1,n[0].elseBranch=n[0],[n[0]]):":"}},{regex:/\\./,onMatch:function(e,t,n){var r=e[1];return r=="}"&&n.length?e=r:"`$\\".indexOf(r)!=-1?e=r:n.inFormatString&&(r=="n"?e="\n":r=="t"?e="\n":"ulULE".indexOf(r)!=-1&&(e={changeCase:r,local:r>"a"})),[e]}},{regex:/}/,onMatch:function(e,t,n){return[n.length?n.shift():e]}},{regex:/\$(?:\d+|\w+)/,onMatch:e},{regex:/\$\{[\dA-Z_a-z]+/,onMatch:function(t,n,r){var i=e(t.substr(1),n,r);return r.unshift(i[0]),i},next:"snippetVar"},{regex:/\n/,token:"newline",merge:!1}],snippetVar:[{regex:"\\|"+t("\\|")+"*\\|",onMatch:function(e,t,n){n[0].choices=e.slice(1,-1).split(",")},next:"start"},{regex:"/("+t("/")+"+)/(?:("+t("/")+"*)/)(\\w*):?",onMatch:function(e,t,n){var r=n[0];return r.fmtString=e,e=this.splitRegex.exec(e),r.guard=e[1],r.fmt=e[2],r.flag=e[3],""},next:"start"},{regex:"`"+t("`")+"*`",onMatch:function(e,t,n){return n[0].code=e.splice(1,-1),""},next:"start"},{regex:"\\?",onMatch:function(e,t,n){n[0]&&(n[0].expectIf=!0)},next:"start"},{regex:"([^:}\\\\]|\\\\.)*:?",token:"",next:"start"}],formatString:[{regex:"/("+t("/")+"+)/",token:"regex"},{regex:"",onMatch:function(e,t,n){n.inFormatString=!0},next:"start"}]}),c.prototype.getTokenizer=function(){return c.$tokenizer},c.$tokenizer},this.tokenizeTmSnippet=function(e,t){return this.getTokenizer().getLineTokens(e,t).tokens.map(function(e){return e.value||e})},this.$getDefaultValue=function(e,t){if(/^[A-Z]\d+$/.test(t)){var n=t.substr(1);return(this.variables[t[0]+"__"]||{})[n]}if(/^\d+$/.test(t))return(this.variables.__||{})[t];t=t.replace(/^TM_/,"");if(!e)return;var r=e.session;switch(t){case"CURRENT_WORD":var i=r.getWordRange();case"SELECTION":case"SELECTED_TEXT":return r.getTextRange(i);case"CURRENT_LINE":return r.getLine(e.getCursorPosition().row);case"PREV_LINE":return r.getLine(e.getCursorPosition().row-1);case"LINE_INDEX":return e.getCursorPosition().column;case"LINE_NUMBER":return e.getCursorPosition().row+1;case"SOFT_TABS":return r.getUseSoftTabs()?"YES":"NO";case"TAB_SIZE":return r.getTabSize();case"FILENAME":case"FILEPATH":return"";case"FULLNAME":return"Ace"}},this.variables={},this.getVariableValue=function(e,t){return this.variables.hasOwnProperty(t)?this.variables[t](e,t)||"":this.$getDefaultValue(e,t)||""},this.tmStrFormat=function(e,t,n){var r=t.flag||"",i=t.guard;i=new RegExp(i,r.replace(/[^gi]/,""));var s=this.tokenizeTmSnippet(t.fmt,"formatString"),o=this,u=e.replace(i,function(){o.variables.__=arguments;var e=o.resolveVariables(s,n),t="E";for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="object"){e[r]="";if(i.changeCase&&i.local){var u=e[r+1];u&&typeof u=="string"&&(i.changeCase=="u"?e[r]=u[0].toUpperCase():e[r]=u[0].toLowerCase(),e[r+1]=u.substr(1))}else i.changeCase&&(t=i.changeCase)}else t=="U"?e[r]=i.toUpperCase():t=="L"&&(e[r]=i.toLowerCase())}return e.join("")});return this.variables.__=null,u},this.resolveVariables=function(e,t){function o(t){var n=e.indexOf(t,r+1);n!=-1&&(r=n)}var n=[];for(var r=0;r<e.length;r++){var i=e[r];if(typeof i=="string")n.push(i);else{if(typeof i!="object")continue;if(i.skip)o(i);else{if(i.processed<r)continue;if(i.text){var s=this.getVariableValue(t,i.text);s&&i.fmtString&&(s=this.tmStrFormat(s,i)),i.processed=r,i.expectIf==null?s&&(n.push(s),o(i)):s?i.skip=i.elseBranch:o(i)}else i.tabstopId!=null?n.push(i):i.changeCase!=null&&n.push(i)}}}return n},this.insertSnippetForSelection=function(e,t){function f(e){var t=[];for(var n=0;n<e.length;n++){var r=e[n];if(typeof r=="object"){if(a[r.tabstopId])continue;var i=e.lastIndexOf(r,n-1);r=t[i]||{tabstopId:r.tabstopId}}t[n]=r}return t}var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=e.session.getTabString(),s=r.match(/^\s*/)[0];n.column<s.length&&(s=s.slice(0,n.column));var o=this.tokenizeTmSnippet(t);o=this.resolveVariables(o,e),o=o.map(function(e){return e=="\n"?e+s:typeof e=="string"?e.replace(/\t/g,i):e});var u=[];o.forEach(function(e,t){if(typeof e!="object")return;var n=e.tabstopId,r=u[n];r||(r=u[n]=[],r.index=n,r.value="");if(r.indexOf(e)!==-1)return;r.push(e);var i=o.indexOf(e,t+1);if(i===-1)return;var s=o.slice(t+1,i),a=s.some(function(e){return typeof e=="object"});a&&!r.value?r.value=s:s.length&&(!r.value||typeof r.value!="string")&&(r.value=s.join(""))}),u.forEach(function(e){e.length=0});var a={};for(var l=0;l<o.length;l++){var c=o[l];if(typeof c!="object")continue;var p=c.tabstopId,d=o.indexOf(c,l+1);if(a[p]){a[p]===c&&(a[p]=null);continue}var v=u[p],m=typeof v.value=="string"?[v.value]:f(v.value);m.unshift(l+1,Math.max(0,d-l)),m.push(c),a[p]=c,o.splice.apply(o,m),v.indexOf(c)===-1&&v.push(c)}var g=0,y=0,b="";o.forEach(function(e){typeof e=="string"?(e[0]==="\n"?(y=e.length-1,g++):y+=e.length,b+=e):e.start?e.end={row:g,column:y}:e.start={row:g,column:y}});var w=e.getSelectionRange(),E=e.session.replace(w,b),S=new h(e),x=e.inVirtualSelectionMode&&e.selection.index;S.addTabstops(u,w.start,E,x)},this.insertSnippet=function(e,t){var n=this;if(e.inVirtualSelectionMode)return n.insertSnippetForSelection(e,t);e.forEachSelection(function(){n.insertSnippetForSelection(e,t)},null,{keepOrder:!0}),e.tabstopManager&&e.tabstopManager.tabNext()},this.$getScope=function(e){var t=e.session.$mode.$id||"";t=t.split("/").pop();if(t==="html"||t==="php"){t==="php"&&!e.session.$mode.inlinePhp&&(t="html");var n=e.getCursorPosition(),r=e.session.getState(n.row);typeof r=="object"&&(r=r[0]),r.substring&&(r.substring(0,3)=="js-"?t="javascript":r.substring(0,4)=="css-"?t="css":r.substring(0,4)=="php-"&&(t="php"))}return t},this.getActiveScopes=function(e){var t=this.$getScope(e),n=[t],r=this.snippetMap;return r[t]&&r[t].includeScopes&&n.push.apply(n,r[t].includeScopes),n.push("_"),n},this.expandWithTab=function(e,t){var n=this,r=e.forEachSelection(function(){return n.expandSnippetForSelection(e,t)},null,{keepOrder:!0});return r&&e.tabstopManager&&e.tabstopManager.tabNext(),r},this.expandSnippetForSelection=function(e,t){var n=e.getCursorPosition(),r=e.session.getLine(n.row),i=r.substring(0,n.column),s=r.substr(n.column),o=this.snippetMap,u;return this.getActiveScopes(e).some(function(e){var t=o[e];return t&&(u=this.findMatchingSnippet(t,i,s)),!!u},this),u?t&&t.dryRun?!0:(e.session.doc.removeInLine(n.row,n.column-u.replaceBefore.length,n.column+u.replaceAfter.length),this.variables.M__=u.matchBefore,this.variables.T__=u.matchAfter,this.insertSnippetForSelection(e,u.content),this.variables.M__=this.variables.T__=null,!0):!1},this.findMatchingSnippet=function(e,t,n){for(var r=e.length;r--;){var i=e[r];if(i.startRe&&!i.startRe.test(t))continue;if(i.endRe&&!i.endRe.test(n))continue;if(!i.startRe&&!i.endRe)continue;return i.matchBefore=i.startRe?i.startRe.exec(t):[""],i.matchAfter=i.endRe?i.endRe.exec(n):[""],i.replaceBefore=i.triggerRe?i.triggerRe.exec(t)[0]:"",i.replaceAfter=i.endTriggerRe?i.endTriggerRe.exec(n)[0]:"",i}},this.snippetMap={},this.snippetNameMap={},this.register=function(e,t){function o(e){return e&&!/^\^?\(.*\)\$?$|^\\b$/.test(e)&&(e="(?:"+e+")"),e||""}function u(e,t,n){return e=o(e),t=o(t),n?(e=t+e,e&&e[e.length-1]!="$"&&(e+="$")):(e+=t,e&&e[0]!="^"&&(e="^"+e)),new RegExp(e)}function a(e){e.scope||(e.scope=t||"_"),t=e.scope,n[t]||(n[t]=[],r[t]={});var o=r[t];if(e.name){var a=o[e.name];a&&i.unregister(a),o[e.name]=e}n[t].push(e),e.tabTrigger&&!e.trigger&&(!e.guard&&/^\w/.test(e.tabTrigger)&&(e.guard="\\b"),e.trigger=s.escapeRegExp(e.tabTrigger)),e.startRe=u(e.trigger,e.guard,!0),e.triggerRe=new RegExp(e.trigger,"",!0),e.endRe=u(e.endTrigger,e.endGuard,!0),e.endTriggerRe=new RegExp(e.endTrigger,"",!0)}var n=this.snippetMap,r=this.snippetNameMap,i=this;e.content?a(e):Array.isArray(e)&&e.forEach(a),this._signal("registerSnippets",{scope:t})},this.unregister=function(e,t){function i(e){var i=r[e.scope||t];if(i&&i[e.name]){delete i[e.name];var s=n[e.scope||t],o=s&&s.indexOf(e);o>=0&&s.splice(o,1)}}var n=this.snippetMap,r=this.snippetNameMap;e.content?i(e):Array.isArray(e)&&e.forEach(i)},this.parseSnippetFile=function(e){e=e.replace(/\r/g,"");var t=[],n={},r=/^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm,i;while(i=r.exec(e)){if(i[1])try{n=JSON.parse(i[1]),t.push(n)}catch(s){}if(i[4])n.content=i[4].replace(/^\t/gm,""),t.push(n),n={};else{var o=i[2],u=i[3];if(o=="regex"){var a=/\/((?:[^\/\\]|\\.)*)|$/g;n.guard=a.exec(u)[1],n.trigger=a.exec(u)[1],n.endTrigger=a.exec(u)[1],n.endGuard=a.exec(u)[1]}else o=="snippet"?(n.tabTrigger=u.match(/^\S*/)[0],n.name||(n.name=u)):n[o]=u}}return t},this.getSnippetByName=function(e,t){var n=this.snippetNameMap,r;return this.getActiveScopes(t).some(function(t){var i=n[t];return i&&(r=i[e]),!!r},this),r}}).call(c.prototype);var h=function(e){if(e.tabstopManager)return e.tabstopManager;e.tabstopManager=this,this.$onChange=this.onChange.bind(this),this.$onChangeSelection=s.delayedCall(this.onChangeSelection.bind(this)).schedule,this.$onChangeSession=this.onChangeSession.bind(this),this.$onAfterExec=this.onAfterExec.bind(this),this.attach(e)};(function(){this.attach=function(e){this.index=0,this.ranges=[],this.tabstops=[],this.$openTabstops=null,this.selectedTabstop=null,this.editor=e,this.editor.on("change",this.$onChange),this.editor.on("changeSelection",this.$onChangeSelection),this.editor.on("changeSession",this.$onChangeSession),this.editor.commands.on("afterExec",this.$onAfterExec),this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.detach=function(){this.tabstops.forEach(this.removeTabstopMarkers,this),this.ranges=null,this.tabstops=null,this.selectedTabstop=null,this.editor.removeListener("change",this.$onChange),this.editor.removeListener("changeSelection",this.$onChangeSelection),this.editor.removeListener("changeSession",this.$onChangeSession),this.editor.commands.removeListener("afterExec",this.$onAfterExec),this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.tabstopManager=null,this.editor=null},this.onChange=function(e){var t=e.data.range,n=e.data.action[0]=="r",r=t.start,i=t.end,s=r.row,o=i.row,u=o-s,a=i.column-r.column;n&&(u=-u,a=-a);if(!this.$inChange&&n){var f=this.selectedTabstop,c=f&&!f.some(function(e){return l(e.start,r)<=0&&l(e.end,i)>=0});if(c)return this.detach()}var h=this.ranges;for(var p=0;p<h.length;p++){var d=h[p];if(d.end.row<r.row)continue;if(n&&l(r,d.start)<0&&l(i,d.end)>0){this.removeRange(d),p--;continue}d.start.row==s&&d.start.column>r.column&&(d.start.column+=a),d.end.row==s&&d.end.column>=r.column&&(d.end.column+=a),d.start.row>=s&&(d.start.row+=u),d.end.row>=s&&(d.end.row+=u),l(d.start,d.end)>0&&this.removeRange(d)}h.length||this.detach()},this.updateLinkedFields=function(){var e=this.selectedTabstop;if(!e||!e.hasLinkedRanges)return;this.$inChange=!0;var n=this.editor.session,r=n.getTextRange(e.firstNonLinked);for(var i=e.length;i--;){var s=e[i];if(!s.linked)continue;var o=t.snippetManager.tmStrFormat(r,s.original);n.replace(s,o)}this.$inChange=!1},this.onAfterExec=function(e){e.command&&!e.command.readOnly&&this.updateLinkedFields()},this.onChangeSelection=function(){if(!this.editor)return;var e=this.editor.selection.lead,t=this.editor.selection.anchor,n=this.editor.selection.isEmpty();for(var r=this.ranges.length;r--;){if(this.ranges[r].linked)continue;var i=this.ranges[r].contains(e.row,e.column),s=n||this.ranges[r].contains(t.row,t.column);if(i&&s)return}this.detach()},this.onChangeSession=function(){this.detach()},this.tabNext=function(e){var t=this.tabstops.length,n=this.index+(e||1);n=Math.min(Math.max(n,1),t),n==t&&(n=0),this.selectTabstop(n),n===0&&this.detach()},this.selectTabstop=function(e){this.$openTabstops=null;var t=this.tabstops[this.index];t&&this.addTabstopMarkers(t),this.index=e,t=this.tabstops[this.index];if(!t||!t.length)return;this.selectedTabstop=t;if(!this.editor.inVirtualSelectionMode){var n=this.editor.multiSelect;n.toSingleRange(t.firstNonLinked.clone());for(var r=t.length;r--;){if(t.hasLinkedRanges&&t[r].linked)continue;n.addRange(t[r].clone(),!0)}n.ranges[0]&&n.addRange(n.ranges[0].clone())}else this.editor.selection.setRange(t.firstNonLinked);this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)},this.addTabstops=function(e,t,n){this.$openTabstops||(this.$openTabstops=[]);if(!e[0]){var r=o.fromPoints(n,n);v(r.start,t),v(r.end,t),e[0]=[r],e[0].index=0}var i=this.index,s=[i+1,0],u=this.ranges;e.forEach(function(e,n){var r=this.$openTabstops[n]||e;for(var i=e.length;i--;){var a=e[i],f=o.fromPoints(a.start,a.end||a.start);d(f.start,t),d(f.end,t),f.original=a,f.tabstop=r,u.push(f),r!=e?r.unshift(f):r[i]=f,a.fmtString?(f.linked=!0,r.hasLinkedRanges=!0):r.firstNonLinked||(r.firstNonLinked=f)}r.firstNonLinked||(r.hasLinkedRanges=!1),r===e&&(s.push(r),this.$openTabstops[n]=r),this.addTabstopMarkers(r)},this),s.length>2&&(this.tabstops.length&&s.push(s.splice(2,1)[0]),this.tabstops.splice.apply(this.tabstops,s))},this.addTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){e.markerId||(e.markerId=t.addMarker(e,"ace_snippet-marker","text"))})},this.removeTabstopMarkers=function(e){var t=this.editor.session;e.forEach(function(e){t.removeMarker(e.markerId),e.markerId=null})},this.removeRange=function(e){var t=e.tabstop.indexOf(e);e.tabstop.splice(t,1),t=this.ranges.indexOf(e),this.ranges.splice(t,1),this.editor.session.removeMarker(e.markerId),e.tabstop.length||(t=this.tabstops.indexOf(e.tabstop),t!=-1&&this.tabstops.splice(t,1),this.tabstops.length||this.detach())},this.keyboardHandler=new a,this.keyboardHandler.bindKeys({Tab:function(e){if(t.snippetManager&&t.snippetManager.expandWithTab(e))return;e.tabstopManager.tabNext(1)},"Shift-Tab":function(e){e.tabstopManager.tabNext(-1)},Esc:function(e){e.tabstopManager.detach()},Return:function(e){return!1}})}).call(h.prototype);var p={};p.onChange=u.prototype.onChange,p.setPosition=function(e,t){this.pos.row=e,this.pos.column=t},p.update=function(e,t,n){this.$insertRight=n,this.pos=e,this.onChange(t)};var d=function(e,t){e.row==0&&(e.column+=t.column),e.row+=t.row},v=function(e,t){e.row==t.row&&(e.column-=t.column),e.row-=t.row};e("./lib/dom").importCssString(".ace_snippet-marker {    -moz-box-sizing: border-box;    box-sizing: border-box;    background: rgba(194, 193, 208, 0.09);    border: 1px dotted rgba(211, 208, 235, 0.62);    position: absolute;}"),t.snippetManager=new c;var m=e("./editor").Editor;(function(){this.insertSnippet=function(e,n){return t.snippetManager.insertSnippet(this,e,n)},this.expandSnippet=function(e){return t.snippetManager.expandWithTab(this,e)}}).call(m.prototype)}),ace.define("ace/autocomplete/popup",["require","exports","module","ace/edit_session","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom"],function(e,t,n){"use strict";var r=e("../edit_session").EditSession,i=e("../virtual_renderer").VirtualRenderer,s=e("../editor").Editor,o=e("../range").Range,u=e("../lib/event"),a=e("../lib/lang"),f=e("../lib/dom"),l=function(e){var t=new i(e);t.$maxLines=4;var n=new s(t);return n.setHighlightActiveLine(!1),n.setShowPrintMargin(!1),n.renderer.setShowGutter(!1),n.renderer.setHighlightGutterLine(!1),n.$mouseHandler.$focusWaitTimout=0,n},c=function(e){var t=f.createElement("div"),n=new l(t);e&&e.appendChild(t),t.style.display="none",n.renderer.content.style.cursor="default",n.renderer.setStyle("ace_autocomplete"),n.setOption("displayIndentGuides",!1),n.setOption("dragDelay",150);var r=function(){};n.focus=r,n.$isFocused=!0,n.renderer.$cursorLayer.restartTimer=r,n.renderer.$cursorLayer.element.style.opacity=0,n.renderer.$maxLines=8,n.renderer.$keepTextAreaAtCursor=!1,n.setHighlightActiveLine(!1),n.session.highlight(""),n.session.$searchHighlight.clazz="ace_highlight-marker",n.on("mousedown",function(e){var t=e.getDocumentPosition();n.selection.moveToPosition(t),c.start.row=c.end.row=t.row,e.stop()});var i,s=new o(-1,0,-1,Infinity),c=new o(-1,0,-1,Infinity);c.id=n.session.addMarker(c,"ace_active-line","fullLine"),n.setSelectOnHover=function(e){e?s.id&&(n.session.removeMarker(s.id),s.id=null):s.id=n.session.addMarker(s,"ace_line-hover","fullLine")},n.setSelectOnHover(!1),n.on("mousemove",function(e){if(!i){i=e;return}if(i.x==e.x&&i.y==e.y)return;i=e,i.scrollTop=n.renderer.scrollTop;var t=i.getDocumentPosition().row;s.start.row!=t&&(s.id||n.setRow(t),p(t))}),n.renderer.on("beforeRender",function(){if(i&&s.start.row!=-1){i.$pos=null;var e=i.getDocumentPosition().row;s.id||n.setRow(e),p(e,!0)}}),n.renderer.on("afterRender",function(){var e=n.getRow(),t=n.renderer.$textLayer,r=t.element.childNodes[e-t.config.firstRow];if(r==t.selectedNode)return;t.selectedNode&&f.removeCssClass(t.selectedNode,"ace_selected"),t.selectedNode=r,r&&f.addCssClass(r,"ace_selected")});var h=function(){p(-1)},p=function(e,t){e!==s.start.row&&(s.start.row=s.end.row=e,t||n.session._emit("changeBackMarker"),n._emit("changeHoverMarker"))};n.getHoveredRow=function(){return s.start.row},u.addListener(n.container,"mouseout",h),n.on("hide",h),n.on("changeSelection",h),n.session.doc.getLength=function(){return n.data.length},n.session.doc.getLine=function(e){var t=n.data[e];return typeof t=="string"?t:t&&t.value||""};var d=n.session.bgTokenizer;return d.$tokenizeRow=function(e){var t=n.data[e],r=[];if(!t)return r;typeof t=="string"&&(t={value:t}),t.caption||(t.caption=t.value||t.name);var i=-1,s,o;for(var e=0;e<t.caption.length;e++)o=t.caption[e],s=t.matchMask&1<<e?1:0,i!==s?(r.push({type:t.className||""+(s?"completion-highlight":""),value:o}),i=s):r[r.length-1].value+=o;if(t.meta){var u=n.renderer.$size.scrollerWidth/n.renderer.layerConfig.characterWidth;t.meta.length+t.caption.length<u-2&&r.push({type:"rightAlignedText",value:t.meta})}return r},d.$updateOnChange=r,d.start=r,n.session.$computeWidth=function(){return this.screenWidth=0},n.isOpen=!1,n.isTopdown=!1,n.data=[],n.setData=function(e){n.data=e||[],n.setValue(a.stringRepeat("\n",e.length),-1),n.setRow(0)},n.getData=function(e){return n.data[e]},n.getRow=function(){return c.start.row},n.setRow=function(e){e=Math.max(-1,Math.min(this.data.length,e)),c.start.row!=e&&(n.selection.clearSelection(),c.start.row=c.end.row=e||0,n.session._emit("changeBackMarker"),n.moveCursorTo(e||0,0),n.isOpen&&n._signal("select"))},n.on("changeSelection",function(){n.isOpen&&n.setRow(n.selection.lead.row)}),n.hide=function(){this.container.style.display="none",this._signal("hide"),n.isOpen=!1},n.show=function(e,t,r){var s=this.container,o=window.innerHeight,u=window.innerWidth,a=this.renderer,f=a.$maxLines*t*1.4,l=e.top+this.$borderSize;l+f>o-t&&!r?(s.style.top="",s.style.bottom=o-l+"px",n.isTopdown=!1):(l+=t,s.style.top=l+"px",s.style.bottom="",n.isTopdown=!0),s.style.display="",this.renderer.$textLayer.checkForSizeChanges();var c=e.left;c+s.offsetWidth>u&&(c=u-s.offsetWidth),s.style.left=c+"px",this._signal("show"),i=null,n.isOpen=!0},n.getTextLeftOffset=function(){return this.$borderSize+this.renderer.$padding+this.$imageSize},n.$imageSize=0,n.$borderSize=1,n};f.importCssString(".ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {    background-color: #CAD6FA;    z-index: 1;}.ace_editor.ace_autocomplete .ace_line-hover {    border: 1px solid #abbffe;    margin-top: -1px;    background: rgba(233,233,253,0.4);}.ace_editor.ace_autocomplete .ace_line-hover {    position: absolute;    z-index: 2;}.ace_editor.ace_autocomplete .ace_scroller {   background: none;   border: none;   box-shadow: none;}.ace_rightAlignedText {    color: gray;    display: inline-block;    position: absolute;    right: 4px;    text-align: right;    z-index: -1;}.ace_editor.ace_autocomplete .ace_completion-highlight{    color: #000;    text-shadow: 0 0 0.01em;}.ace_editor.ace_autocomplete {    width: 280px;    z-index: 200000;    background: #fbfbfb;    color: #444;    border: 1px lightgray solid;    position: fixed;    box-shadow: 2px 3px 5px rgba(0,0,0,.2);    line-height: 1.4;}"),t.AcePopup=c}),ace.define("ace/autocomplete/util",["require","exports","module"],function(e,t,n){"use strict";t.parForEach=function(e,t,n){var r=0,i=e.length;i===0&&n();for(var s=0;s<i;s++)t(e[s],function(e,t){r++,r===i&&n(e,t)})};var r=/[a-zA-Z_0-9\$\-\u00A2-\uFFFF]/;t.retrievePrecedingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t-1;s>=0;s--){if(!n.test(e[s]))break;i.push(e[s])}return i.reverse().join("")},t.retrieveFollowingIdentifier=function(e,t,n){n=n||r;var i=[];for(var s=t;s<e.length;s++){if(!n.test(e[s]))break;i.push(e[s])}return i}}),ace.define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/event","ace/lib/lang","ace/snippets"],function(e,t,n){"use strict";var r=e("./keyboard/hash_handler").HashHandler,i=e("./autocomplete/popup").AcePopup,s=e("./autocomplete/util"),o=e("./lib/event"),u=e("./lib/lang"),a=e("./snippets").snippetManager,f=function(){this.autoInsert=!0,this.autoSelect=!0,this.keyboardHandler=new r,this.keyboardHandler.bindKeys(this.commands),this.blurListener=this.blurListener.bind(this),this.changeListener=this.changeListener.bind(this),this.mousedownListener=this.mousedownListener.bind(this),this.mousewheelListener=this.mousewheelListener.bind(this),this.changeTimer=u.delayedCall(function(){this.updateCompletions(!0)}.bind(this))};(function(){this.gatherCompletionsId=0,this.$init=function(){this.popup=new i(document.body||document.documentElement),this.popup.on("click",function(e){this.insertMatch(),e.stop()}.bind(this)),this.popup.focus=this.editor.focus.bind(this.editor)},this.openPopup=function(e,t,n){this.popup||this.$init(),this.popup.setData(this.completions.filtered);var r=e.renderer;this.popup.setRow(this.autoSelect?0:-1);if(!n){this.popup.setTheme(e.getTheme()),this.popup.setFontSize(e.getFontSize());var i=r.layerConfig.lineHeight,s=r.$cursorLayer.getPixelPosition(this.base,!0);s.left-=this.popup.getTextLeftOffset();var o=e.container.getBoundingClientRect();s.top+=o.top-r.layerConfig.offset,s.left+=o.left-e.renderer.scrollLeft,s.left+=r.$gutterLayer.gutterWidth,this.popup.show(s,i)}},this.detach=function(){this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler),this.editor.off("changeSelection",this.changeListener),this.editor.off("blur",this.blurListener),this.editor.off("mousedown",this.mousedownListener),this.editor.off("mousewheel",this.mousewheelListener),this.changeTimer.cancel(),this.popup&&this.popup.isOpen&&(this.gatherCompletionsId+=1,this.popup.hide()),this.base&&this.base.detach(),this.activated=!1,this.completions=this.base=null},this.changeListener=function(e){var t=this.editor.selection.lead;(t.row!=this.base.row||t.column<this.base.column)&&this.detach(),this.activated?this.changeTimer.schedule():this.detach()},this.blurListener=function(){var e=document.activeElement;e!=this.editor.textInput.getElement()&&e.parentNode!=this.popup.container&&this.detach()},this.mousedownListener=function(e){this.detach()},this.mousewheelListener=function(e){this.detach()},this.goTo=function(e){var t=this.popup.getRow(),n=this.popup.session.getLength()-1;switch(e){case"up":t=t<=0?n:t-1;break;case"down":t=t>=n?-1:t+1;break;case"start":t=0;break;case"end":t=n}this.popup.setRow(t)},this.insertMatch=function(e){e||(e=this.popup.getData(this.popup.getRow()));if(!e)return!1;if(e.completer&&e.completer.insertMatch)e.completer.insertMatch(this.editor);else{if(this.completions.filterText){var t=this.editor.selection.getAllRanges();for(var n=0,r;r=t[n];n++)r.start.column-=this.completions.filterText.length,this.editor.session.remove(r)}e.snippet?a.insertSnippet(this.editor,e.snippet):this.editor.execCommand("insertstring",e.value||e)}this.detach()},this.commands={Up:function(e){e.completer.goTo("up")},Down:function(e){e.completer.goTo("down")},"Ctrl-Up|Ctrl-Home":function(e){e.completer.goTo("start")},"Ctrl-Down|Ctrl-End":function(e){e.completer.goTo("end")},Esc:function(e){e.completer.detach()},Space:function(e){e.completer.detach(),e.insert(" ")},Return:function(e){return e.completer.insertMatch()},"Shift-Return":function(e){e.completer.insertMatch(!0)},Tab:function(e){var t=e.completer.insertMatch();if(!!t||!!e.tabstopManager)return t;e.completer.goTo("down")},PageUp:function(e){e.completer.popup.gotoPageUp()},PageDown:function(e){e.completer.popup.gotoPageDown()}},this.gatherCompletions=function(e,t){var n=e.getSession(),r=e.getCursorPosition(),i=n.getLine(r.row),o=s.retrievePrecedingIdentifier(i,r.column);this.base=n.doc.createAnchor(r.row,r.column-o.length);var u=[],a=e.completers.length;return e.completers.forEach(function(i,f){i.getCompletions(e,n,r,o,function(r,i){r||(u=u.concat(i));var o=e.getCursorPosition(),f=n.getLine(o.row);t(null,{prefix:s.retrievePrecedingIdentifier(f,o.column,i[0]&&i[0].identifierRegex),matches:u,finished:--a===0})})}),!0},this.showPopup=function(e){this.editor&&this.detach(),this.activated=!0,this.editor=e,e.completer!=this&&(e.completer&&e.completer.detach(),e.completer=this),e.keyBinding.addKeyboardHandler(this.keyboardHandler),e.on("changeSelection",this.changeListener),e.on("blur",this.blurListener),e.on("mousedown",this.mousedownListener),e.on("mousewheel",this.mousewheelListener),this.updateCompletions()},this.updateCompletions=function(e){if(e&&this.base&&this.completions){var t=this.editor.getCursorPosition(),n=this.editor.session.getTextRange({start:this.base,end:t});if(n==this.completions.filterText)return;this.completions.setFilter(n);if(!this.completions.filtered.length)return this.detach();if(this.completions.filtered.length==1&&this.completions.filtered[0].value==n&&!this.completions.filtered[0].snippet)return this.detach();this.openPopup(this.editor,n,e);return}var r=this.gatherCompletionsId;this.gatherCompletions(this.editor,function(t,n){var i=function(){if(!n.finished)return;return this.detach()}.bind(this),s=n.prefix,o=n&&n.matches;if(!o||!o.length)return i();if(s.indexOf(n.prefix)!==0||r!=this.gatherCompletionsId)return;this.completions=new l(o),this.completions.setFilter(s);var u=this.completions.filtered;if(!u.length)return i();if(u.length==1&&u[0].value==s&&!u[0].snippet)return i();if(this.autoInsert&&u.length==1)return this.insertMatch(u[0]);this.openPopup(this.editor,s,e)}.bind(this))},this.cancelContextMenu=function(){this.editor.$mouseHandler.cancelContextMenu()}}).call(f.prototype),f.startCommand={name:"startAutocomplete",exec:function(e){e.completer||(e.completer=new f),e.completer.autoInsert=e.completer.autoSelect=!0,e.completer.showPopup(e),e.completer.cancelContextMenu()},bindKey:"Ctrl-Space|Ctrl-Shift-Space|Alt-Space"};var l=function(e,t,n){this.all=e,this.filtered=e,this.filterText=t||""};(function(){this.setFilter=function(e){if(e.length>this.filterText&&e.lastIndexOf(this.filterText,0)===0)var t=this.filtered;else var t=this.all;this.filterText=e,t=this.filterCompletions(t,this.filterText),t=t.sort(function(e,t){return t.exactMatch-e.exactMatch||t.score-e.score});var n=null;t=t.filter(function(e){var t=e.value||e.caption||e.snippet;return t===n?!1:(n=t,!0)}),this.filtered=t},this.filterCompletions=function(e,t){var n=[],r=t.toUpperCase(),i=t.toLowerCase();e:for(var s=0,o;o=e[s];s++){var u=o.value||o.caption||o.snippet;if(!u)continue;var a=-1,f=0,l=0,c,h;for(var p=0;p<t.length;p++){var d=u.indexOf(i[p],a+1),v=u.indexOf(r[p],a+1);c=d>=0?v<0||d<v?d:v:v;if(c<0)continue e;h=c-a-1,h>0&&(a===-1&&(l+=10),l+=h),f|=1<<c,a=c}o.matchMask=f,o.exactMatch=l?0:1,o.score=(o.score||0)-l,n.push(o)}return n}}).call(l.prototype),t.Autocomplete=f,t.FilteredList=l}),ace.define("ace/autocomplete/text_completer",["require","exports","module","ace/range"],function(e,t,n){function s(e,t){var n=e.getTextRange(r.fromPoints({row:0,column:0},t));return n.split(i).length-1}function o(e,t){var n=s(e,t),r=e.getValue().split(i),o=Object.create(null),u=r[n];return r.forEach(function(e,t){if(!e||e===u)return;var i=Math.abs(n-t),s=r.length-i;o[e]?o[e]=Math.max(s,o[e]):o[e]=s}),o}var r=e("../range").Range,i=/[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;t.getCompletions=function(e,t,n,r,i){var s=o(t,n,r),u=Object.keys(s);i(null,u.map(function(e){return{caption:e,value:e,score:s[e],meta:"local"}}))}}),ace.define("ace/ext/language_tools",["require","exports","module","ace/snippets","ace/autocomplete","ace/config","ace/autocomplete/util","ace/autocomplete/text_completer","ace/editor","ace/config"],function(e,t,n){"use strict";function v(e){var t=e.getCursorPosition(),n=e.session.getLine(t.row),r=o.retrievePrecedingIdentifier(n,t.column);return e.completers.forEach(function(e){e.identifierRegexps&&e.identifierRegexps.forEach(function(e){!r&&e&&(r=o.retrievePrecedingIdentifier(n,t.column,e))})}),r}var r=e("../snippets").snippetManager,i=e("../autocomplete").Autocomplete,s=e("../config"),o=e("../autocomplete/util"),u=e("../autocomplete/text_completer"),a={getCompletions:function(e,t,n,r,i){var s=e.session.getState(n.row),o=t.$mode.getCompletions(s,t,n,r);i(null,o)}},f={getCompletions:function(e,t,n,i,s){var o=r.snippetMap,u=[];r.getActiveScopes(e).forEach(function(e){var t=o[e]||[];for(var n=t.length;n--;){var r=t[n],i=r.name||r.tabTrigger;if(!i)continue;u.push({caption:i,snippet:r.content,meta:r.tabTrigger&&!r.name?r.tabTrigger+"\u21e5 ":"snippet"})}},this),s(null,u)}},l=[f,u,a];t.addCompleter=function(e){l.push(e)},t.textCompleter=u,t.keyWordCompleter=a,t.snippetCompleter=f;var c={name:"expandSnippet",exec:function(e){var t=r.expandWithTab(e);t||e.execCommand("indent")},bindKey:"Tab"},h=function(e,t){p(t.session.$mode)},p=function(e){var t=e.$id;r.files||(r.files={}),d(t),e.modes&&e.modes.forEach(p)},d=function(e){if(!e||r.files[e])return;var t=e.replace("mode","snippets");r.files[e]={},s.loadModule(t,function(t){t&&(r.files[e]=t,!t.snippets&&t.snippetText&&(t.snippets=r.parseSnippetFile(t.snippetText)),r.register(t.snippets||[],t.scope),t.includeScopes&&(r.snippetMap[t.scope].includeScopes=t.includeScopes,t.includeScopes.forEach(function(e){d("ace/mode/"+e)})))})},m=function(e){var t=e.editor,n=e.args||"",r=t.completer&&t.completer.activated;if(e.command.name==="backspace")r&&!v(t)&&t.completer.detach();else if(e.command.name==="insertstring"){var s=v(t);s&&!r&&(t.completer||(t.completer=new i),t.completer.autoSelect=!1,t.completer.autoInsert=!1,t.completer.showPopup(t))}},g=e("../editor").Editor;e("../config").defineOptions(g.prototype,"editor",{enableBasicAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:l),this.commands.addCommand(i.startCommand)):this.commands.removeCommand(i.startCommand)},value:!1},enableLiveAutocompletion:{set:function(e){e?(this.completers||(this.completers=Array.isArray(e)?e:l),this.commands.on("afterExec",m)):this.commands.removeListener("afterExec",m)},value:!1},enableSnippets:{set:function(e){e?(this.commands.addCommand(c),this.on("changeMode",h),h(null,this)):(this.commands.removeCommand(c),this.off("changeMode",h))},value:!1}})}),ace.define("ace/mode/xquery",["require","exports","module","ace/worker/worker_client","ace/lib/oop","ace/mode/text","ace/mode/text_highlight_rules","ace/mode/xquery/xquery_lexer","ace/range","ace/mode/behaviour/xquery","ace/mode/folding/cstyle","ace/anchor","ace/ext/language_tools"],function(e,t,n){"use strict";var r=e("../worker/worker_client").WorkerClient,i=e("../lib/oop"),s=e("./text").Mode,o=e("./text_highlight_rules").TextHighlightRules,u=e("./xquery/xquery_lexer").XQueryLexer,a=e("../range").Range,f=e("./behaviour/xquery").XQueryBehaviour,l=e("./folding/cstyle").FoldMode,c=e("../anchor").Anchor,h=e("../ext/language_tools"),p=function(){this.$tokenizer=new u,this.$behaviour=new f,this.foldingRules=new l,this.$highlightRules=new o};i.inherits(p,s),function(){h.addCompleter({getCompletions:function(e,t,n,r,i){t.$worker.emit("complete",{data:{pos:n,prefix:r}}),t.$worker.on("complete",function(e){i(null,e.data)})}}),this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=t.match(/\s*(?:then|else|return|[{\(]|<\w+>)\s*$/);return i&&(r+=n),r},this.checkOutdent=function(e,t,n){return/^\s+$/.test(t)?/^\s*[\}\)]/.test(n):!1},this.autoOutdent=function(e,t,n){var r=t.getLine(n),i=r.match(/^(\s*[\}\)])/);if(!i)return 0;var s=i[1].length,o=t.findMatchingBracket({row:n,column:s});if(!o||o.row==n)return 0;var u=this.$getIndent(t.getLine(o.row));t.replace(new a(n,0,n,s-1),u)},this.toggleCommentLines=function(e,t,n,r){var i,s,o=!0,u=/^\s*\(:(.*):\)/;for(i=n;i<=r;i++)if(!u.test(t.getLine(i))){o=!1;break}var f=new a(0,0,0,0);for(i=n;i<=r;i++)s=t.getLine(i),f.start.row=i,f.end.row=i,f.end.column=s.length,t.replace(f,o?s.match(u)[1]:"(:"+s+":)")},this.createWorker=function(e){var t=new r(["ace"],"ace/mode/xquery_worker","XQueryWorker"),n=this;return t.attachToDocument(e.getDocument()),t.on("ok",function(t){e.clearAnnotations()}),t.on("markers",function(t){e.clearAnnotations(),n.addMarkers(t.data,e)}),t.on("highlight",function(t){n.$tokenizer.tokens=t.data.tokens,n.$tokenizer.lines=e.getDocument().getAllLines();var r=Object.keys(n.$tokenizer.tokens);for(var i=0;i<r.length;i++){var s=parseInt(r[i]);delete e.bgTokenizer.lines[s],delete e.bgTokenizer.states[s],e.bgTokenizer.fireUpdateEvent(s,s)}}),t},this.removeMarkers=function(e){var t=e.getMarkers(!1);for(var n in t)t[n].clazz.indexOf("language_highlight_")===0&&e.removeMarker(n);for(var r=0;r<e.markerAnchors.length;r++)e.markerAnchors[r].detach();e.markerAnchors=[]},this.addMarkers=function(e,t){var n=this;t.markerAnchors||(t.markerAnchors=[]),this.removeMarkers(t),t.languageAnnos=[],e.forEach(function(e){function u(i){r&&t.removeMarker(r),o.row=n.row;if(e.pos.sc!==undefined&&e.pos.ec!==undefined){var s=new a(e.pos.sl,e.pos.sc,e.pos.el,e.pos.ec);r=t.addMarker(s,"language_highlight_"+(e.type?e.type:"default"))}i&&t.setAnnotations(t.languageAnnos)}var n=new c(t.getDocument(),e.pos.sl,e.pos.sc||0);t.markerAnchors.push(n);var r,i=e.pos.ec-e.pos.sc,s=e.pos.el-e.pos.sl,o={guttertext:e.message,type:e.level||"warning",text:e.message};u(),n.on("change",function(){u(!0)}),e.message&&t.languageAnnos.push(o)}),t.setAnnotations(t.languageAnnos)},this.$id="ace/mode/xquery"}.call(p.prototype),t.Mode=p})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/mode-yaml.js b/dist/assets/js/vendor/ace-nc/mode-yaml.js
            new file mode 100644
            index 0000000000..df458d7a9e
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/mode-yaml.js
            @@ -0,0 +1 @@
            +ace.define("ace/mode/yaml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment",regex:"#.*$"},{token:"list.markup",regex:/^(?:-{3}|\.{3})\s*(?=#|$)/},{token:"list.markup",regex:/^\s*[\-?](?:$|\s)/},{token:"constant",regex:"!![\\w//]+"},{token:"constant.language",regex:"[&\\*][a-zA-Z0-9-_]+"},{token:["meta.tag","keyword"],regex:/^(\s*\w.*?)(\:(?:\s+|$))/},{token:["meta.tag","keyword"],regex:/(\w+?)(\s*\:(?:\s+|$))/},{token:"keyword.operator",regex:"<<\\w*:\\w*"},{token:"keyword.operator",regex:"-\\s*(?=[{])"},{token:"string",regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'},{token:"string",regex:"[|>][-+\\d\\s]*$",next:"qqstring"},{token:"string",regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"},{token:"constant.numeric",regex:/(\b|[+\-\.])[\d_]+(?:(?:\.[\d_]*)?(?:[eE][+\-]?[\d_]+)?)/},{token:"constant.numeric",regex:/[+\-]?\.inf\b|NaN\b|0x[\dA-Fa-f_]+|0b[10_]+/},{token:"constant.language.boolean",regex:"(?:true|false|TRUE|FALSE|True|False|yes|no)\\b"},{token:"paren.lparen",regex:"[[({]"},{token:"paren.rparen",regex:"[\\])}]"}],qqstring:[{token:"string",regex:"(?=(?:(?:\\\\.)|(?:[^:]))*?:)",next:"start"},{token:"string",regex:".+"}]}};r.inherits(s,i),t.YamlHighlightRules=s}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){"use strict";var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),ace.define("ace/mode/folding/coffee",["require","exports","module","ace/lib/oop","ace/mode/folding/fold_mode","ace/range"],function(e,t,n){"use strict";var r=e("../../lib/oop"),i=e("./fold_mode").FoldMode,s=e("../../range").Range,o=t.FoldMode=function(){};r.inherits(o,i),function(){this.getFoldWidgetRange=function(e,t,n){var r=this.indentationBlock(e,n);if(r)return r;var i=/\S/,o=e.getLine(n),u=o.search(i);if(u==-1||o[u]!="#")return;var a=o.length,f=e.getLength(),l=n,c=n;while(++n<f){o=e.getLine(n);var h=o.search(i);if(h==-1)continue;if(o[h]!="#")break;c=n}if(c>l){var p=e.getLine(c).length;return new s(l,a,c,p)}},this.getFoldWidget=function(e,t,n){var r=e.getLine(n),i=r.search(/\S/),s=e.getLine(n+1),o=e.getLine(n-1),u=o.search(/\S/),a=s.search(/\S/);if(i==-1)return e.foldWidgets[n-1]=u!=-1&&u<a?"start":"","";if(u==-1){if(i==a&&r[i]=="#"&&s[i]=="#")return e.foldWidgets[n-1]="",e.foldWidgets[n+1]="","start"}else if(u==i&&r[i]=="#"&&o[i]=="#"&&e.getLine(n-2).search(/\S/)==-1)return e.foldWidgets[n-1]="start",e.foldWidgets[n+1]="","";return u!=-1&&u<i?e.foldWidgets[n-1]="start":e.foldWidgets[n-1]="",i<a?"start":""}}.call(o.prototype)}),ace.define("ace/mode/yaml",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/yaml_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/folding/coffee"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("./text").Mode,s=e("./yaml_highlight_rules").YamlHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("./folding/coffee").FoldMode,a=function(){this.HighlightRules=s,this.$outdent=new o,this.foldingRules=new u};r.inherits(a,i),function(){this.lineCommentStart="#",this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t);if(e=="start"){var i=t.match(/^.*[\{\(\[]\s*$/);i&&(r+=n)}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.$id="ace/mode/yaml"}.call(a.prototype),t.Mode=a})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/abap.js b/dist/assets/js/vendor/ace-nc/snippets/abap.js
            new file mode 100644
            index 0000000000..5e1c4c2de2
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/abap.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/abap",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="abap"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/actionscript.js b/dist/assets/js/vendor/ace-nc/snippets/actionscript.js
            new file mode 100644
            index 0000000000..8ff37868bb
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/actionscript.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/actionscript",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet main\n	package {\n		import flash.display.*;\n		import flash.Events.*;\n	\n		public class Main extends Sprite {\n			public function Main (	) {\n				trace("start");\n				stage.scaleMode = StageScaleMode.NO_SCALE;\n				stage.addEventListener(Event.RESIZE, resizeListener);\n			}\n	\n			private function resizeListener (e:Event):void {\n				trace("The application window changed size!");\n				trace("New width:  " + stage.stageWidth);\n				trace("New height: " + stage.stageHeight);\n			}\n	\n		}\n	\n	}\nsnippet class\n	${1:public|internal} class ${2:name} ${3:extends } {\n		public function $2 (	) {\n			("start");\n		}\n	}\nsnippet all\n	package name {\n\n		${1:public|internal|final} class ${2:name} ${3:extends } {\n			private|public| static const FOO = "abc";\n			private|public| static var BAR = "abc";\n			if Cababilities.os == "Linux|MacOS" {\n				FOO = "other";\n			}\n			public function $2 (	){\n				super2();\n				trace("start");\n			}\n			public function name (a, b...){\n				super.name(..);\n				lable:break\n			}\n		}\n	}\n\n	function A(){\n	}\nsnippet switch\n	switch(${1}){\n		case ${2}:\n			${3}\n		break;\n		default:\n	}\nsnippet case\n		case ${1}:\n			${2}\n		break;\nsnippet package\n	package ${1:package}{\n		${2}\n	}\nsnippet wh\n	while ${1:cond}{\n		${2}\n	}\nsnippet do\n	do {\n		${2}\n	} while (${1:cond})\nsnippet while\n	while ${1:cond}{\n		${2}\n	}\nsnippet for enumerate names\n	for (${1:var} in ${2:object}){\n		${3}\n	}\nsnippet for enumerate values\n	for each (${1:var} in ${2:object}){\n		${3}\n	}\nsnippet get_set\n	function get ${1:name} {\n		return ${2}\n	}\n	function set $1 (newValue) {\n		${3}\n	}\nsnippet interface\n	interface name {\n		function method(${1}):${2:returntype};\n	}\nsnippet try\n	try {\n		${1}\n	} catch (error:ErrorType) {\n		${2}\n	} finally {\n		${3}\n	}\n# For Loop (same as c.snippet)\nsnippet for for (..) {..}\n	for (${2:i} = 0; $2 < ${1:count}; $2${3:++}) {\n		${4:/* code */}\n	}\n# Custom For Loop\nsnippet forr\n	for (${1:i} = ${2:0}; ${3:$1 < 10}; $1${4:++}) {\n		${5:/* code */}\n	}\n# If Condition\nsnippet if\n	if (${1:/* condition */}) {\n		${2:/* code */}\n	}\nsnippet el\n	else {\n		${1}\n	}\n# Ternary conditional\nsnippet t\n	${1:/* condition */} ? ${2:a} : ${3:b}\nsnippet fun\n	function ${1:function_name}(${2})${3}\n	{\n		${4:/* code */}\n	}\n# FlxSprite (usefull when using the flixel library)\nsnippet FlxSprite\n	package\n	{\n		import org.flixel.*\n\n		public class ${1:ClassName} extends ${2:FlxSprite}\n		{\n			public function $1(${3: X:Number, Y:Number}):void\n			{\n				super(X,Y);\n				${4: //code...}\n			}\n\n			override public function update():void\n			{\n				super.update();\n				${5: //code...}\n			}\n		}\n	}\n\n',t.scope="actionscript"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/ada.js b/dist/assets/js/vendor/ace-nc/snippets/ada.js
            new file mode 100644
            index 0000000000..65a1adc4c8
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/ada.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/ada",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="ada"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/apache_conf.js b/dist/assets/js/vendor/ace-nc/snippets/apache_conf.js
            new file mode 100644
            index 0000000000..a4364ecdf3
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/apache_conf.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/apache_conf",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="apache_conf"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/applescript.js b/dist/assets/js/vendor/ace-nc/snippets/applescript.js
            new file mode 100644
            index 0000000000..d3a7cd5987
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/applescript.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/applescript",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="applescript"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/asciidoc.js b/dist/assets/js/vendor/ace-nc/snippets/asciidoc.js
            new file mode 100644
            index 0000000000..ec76c4f397
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/asciidoc.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/asciidoc",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="asciidoc"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/assembly_x86.js b/dist/assets/js/vendor/ace-nc/snippets/assembly_x86.js
            new file mode 100644
            index 0000000000..7c6e63224b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/assembly_x86.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/assembly_x86",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="assembly_x86"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/autohotkey.js b/dist/assets/js/vendor/ace-nc/snippets/autohotkey.js
            new file mode 100644
            index 0000000000..0507ad9224
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/autohotkey.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/autohotkey",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="autohotkey"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/batchfile.js b/dist/assets/js/vendor/ace-nc/snippets/batchfile.js
            new file mode 100644
            index 0000000000..bffe14eb42
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/batchfile.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/batchfile",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="batchfile"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/c9search.js b/dist/assets/js/vendor/ace-nc/snippets/c9search.js
            new file mode 100644
            index 0000000000..0f455c179e
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/c9search.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/c9search",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="c9search"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/c_cpp.js b/dist/assets/js/vendor/ace-nc/snippets/c_cpp.js
            new file mode 100644
            index 0000000000..9fc5a58240
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/c_cpp.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/c_cpp",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="## STL Collections\n# std::array\nsnippet array\n	std::array<${1:T}, ${2:N}> ${3};${4}\n# std::vector\nsnippet vector\n	std::vector<${1:T}> ${2};${3}\n# std::deque\nsnippet deque\n	std::deque<${1:T}> ${2};${3}\n# std::forward_list\nsnippet flist\n	std::forward_list<${1:T}> ${2};${3}\n# std::list\nsnippet list\n	std::list<${1:T}> ${2};${3}\n# std::set\nsnippet set\n	std::set<${1:T}> ${2};${3}\n# std::map\nsnippet map\n	std::map<${1:Key}, ${2:T}> ${3};${4}\n# std::multiset\nsnippet mset\n	std::multiset<${1:T}> ${2};${3}\n# std::multimap\nsnippet mmap\n	std::multimap<${1:Key}, ${2:T}> ${3};${4}\n# std::unordered_set\nsnippet uset\n	std::unordered_set<${1:T}> ${2};${3}\n# std::unordered_map\nsnippet umap\n	std::unordered_map<${1:Key}, ${2:T}> ${3};${4}\n# std::unordered_multiset\nsnippet umset\n	std::unordered_multiset<${1:T}> ${2};${3}\n# std::unordered_multimap\nsnippet ummap\n	std::unordered_multimap<${1:Key}, ${2:T}> ${3};${4}\n# std::stack\nsnippet stack\n	std::stack<${1:T}> ${2};${3}\n# std::queue\nsnippet queue\n	std::queue<${1:T}> ${2};${3}\n# std::priority_queue\nsnippet pqueue\n	std::priority_queue<${1:T}> ${2};${3}\n##\n## Access Modifiers\n# private\nsnippet pri\n	private\n# protected\nsnippet pro\n	protected\n# public\nsnippet pub\n	public\n# friend\nsnippet fr\n	friend\n# mutable\nsnippet mu\n	mutable\n## \n## Class\n# class\nsnippet cl\n	class ${1:`Filename('$1', 'name')`} \n	{\n	public:\n		$1(${2});\n		~$1();\n\n	private:\n		${3:/* data */}\n	};\n# member function implementation\nsnippet mfun\n	${4:void} ${1:`Filename('$1', 'ClassName')`}::${2:memberFunction}(${3}) {\n		${5:/* code */}\n	}\n# namespace\nsnippet ns\n	namespace ${1:`Filename('', 'my')`} {\n		${2}\n	} /* namespace $1 */\n##\n## Input/Output\n# std::cout\nsnippet cout\n	std::cout << ${1} << std::endl;${2}\n# std::cin\nsnippet cin\n	std::cin >> ${1};${2}\n##\n## Iteration\n# for i \nsnippet fori\n	for (int ${2:i} = 0; $2 < ${1:count}; $2${3:++}) {\n		${4:/* code */}\n	}${5}\n\n# foreach\nsnippet fore\n	for (${1:auto} ${2:i} : ${3:container}) {\n		${4:/* code */}\n	}${5}\n# iterator\nsnippet iter\n	for (${1:std::vector}<${2:type}>::${3:const_iterator} ${4:i} = ${5:container}.begin(); $4 != $5.end(); ++$4) {\n		${6}\n	}${7}\n\n# auto iterator\nsnippet itera\n	for (auto ${1:i} = $1.begin(); $1 != $1.end(); ++$1) {\n		${2:std::cout << *$1 << std::endl;}\n	}${3}\n##\n## Lambdas\n# lamda (one line)\nsnippet ld\n	[${1}](${2}){${3:/* code */}}${4}\n# lambda (multi-line)\nsnippet lld\n	[${1}](${2}){\n		${3:/* code */}\n	}${4}\n",t.scope="c_cpp"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/cirru.js b/dist/assets/js/vendor/ace-nc/snippets/cirru.js
            new file mode 100644
            index 0000000000..8ecce1b5e0
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/cirru.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/cirru",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="cirru"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/clojure.js b/dist/assets/js/vendor/ace-nc/snippets/clojure.js
            new file mode 100644
            index 0000000000..3aebfa568c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/clojure.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/clojure",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet comm\n	(comment\n	  ${1}\n	  )\nsnippet condp\n	(condp ${1:pred} ${2:expr}\n	  ${3})\nsnippet def\n	(def ${1})\nsnippet defm\n	(defmethod ${1:multifn} "${2:doc-string}" ${3:dispatch-val} [${4:args}]\n	  ${5})\nsnippet defmm\n	(defmulti ${1:name} "${2:doc-string}" ${3:dispatch-fn})\nsnippet defma\n	(defmacro ${1:name} "${2:doc-string}" ${3:dispatch-fn})\nsnippet defn\n	(defn ${1:name} "${2:doc-string}" [${3:arg-list}]\n	  ${4})\nsnippet defp\n	(defprotocol ${1:name}\n	  ${2})\nsnippet defr\n	(defrecord ${1:name} [${2:fields}]\n	  ${3:protocol}\n	  ${4})\nsnippet deft\n	(deftest ${1:name}\n	    (is (= ${2:assertion})))\n	  ${3})\nsnippet is\n	(is (= ${1} ${2}))\nsnippet defty\n	(deftype ${1:Name} [${2:fields}]\n	  ${3:Protocol}\n	  ${4})\nsnippet doseq\n	(doseq [${1:elem} ${2:coll}]\n	  ${3})\nsnippet fn\n	(fn [${1:arg-list}] ${2})\nsnippet if\n	(if ${1:test-expr}\n	  ${2:then-expr}\n	  ${3:else-expr})\nsnippet if-let \n	(if-let [${1:result} ${2:test-expr}]\n		(${3:then-expr} $1)\n		(${4:else-expr}))\nsnippet imp\n	(:import [${1:package}])\n	& {:keys [${1:keys}] :or {${2:defaults}}}\nsnippet let\n	(let [${1:name} ${2:expr}]\n		${3})\nsnippet letfn\n	(letfn [(${1:name) [${2:args}]\n	          ${3})])\nsnippet map\n	(map ${1:func} ${2:coll})\nsnippet mapl\n	(map #(${1:lambda}) ${2:coll})\nsnippet met\n	(${1:name} [${2:this} ${3:args}]\n	  ${4})\nsnippet ns\n	(ns ${1:name}\n	  ${2})\nsnippet dotimes\n	(dotimes [_ 10]\n	  (time\n	    (dotimes [_ ${1:times}]\n	      ${2})))\nsnippet pmethod\n	(${1:name} [${2:this} ${3:args}])\nsnippet refer\n	(:refer-clojure :exclude [${1}])\nsnippet require\n	(:require [${1:namespace} :as [${2}]])\nsnippet use\n	(:use [${1:namespace} :only [${2}]])\nsnippet print\n	(println ${1})\nsnippet reduce\n	(reduce ${1:(fn [p n] ${3})} ${2})\nsnippet when\n	(when ${1:test} ${2:body})\nsnippet when-let\n	(when-let [${1:result} ${2:test}]\n		${3:body})\n',t.scope="clojure"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/cobol.js b/dist/assets/js/vendor/ace-nc/snippets/cobol.js
            new file mode 100644
            index 0000000000..f957427344
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/cobol.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/cobol",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="cobol"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/coffee.js b/dist/assets/js/vendor/ace-nc/snippets/coffee.js
            new file mode 100644
            index 0000000000..ac1b7304d4
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/coffee.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/coffee",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="# Closure loop\nsnippet forindo\n	for ${1:name} in ${2:array}\n		do ($1) ->\n			${3:// body}\n# Array comprehension\nsnippet fora\n	for ${1:name} in ${2:array}\n		${3:// body...}\n# Object comprehension\nsnippet foro\n	for ${1:key}, ${2:value} of ${3:object}\n		${4:// body...}\n# Range comprehension (inclusive)\nsnippet forr\n	for ${1:name} in [${2:start}..${3:finish}]\n		${4:// body...}\nsnippet forrb\n	for ${1:name} in [${2:start}..${3:finish}] by ${4:step}\n		${5:// body...}\n# Range comprehension (exclusive)\nsnippet forrex\n	for ${1:name} in [${2:start}...${3:finish}]\n		${4:// body...}\nsnippet forrexb\n	for ${1:name} in [${2:start}...${3:finish}] by ${4:step}\n		${5:// body...}\n# Function\nsnippet fun\n	(${1:args}) ->\n		${2:// body...}\n# Function (bound)\nsnippet bfun\n	(${1:args}) =>\n		${2:// body...}\n# Class\nsnippet cla class ..\n	class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`}\n		${2}\nsnippet cla class .. constructor: ..\n	class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`}\n		constructor: (${2:args}) ->\n			${3}\n\n		${4}\nsnippet cla class .. extends ..\n	class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`} extends ${2:ParentClass}\n		${3}\nsnippet cla class .. extends .. constructor: ..\n	class ${1:`substitute(Filename(), '\\(_\\|^\\)\\(.\\)', '\\u\\2', 'g')`} extends ${2:ParentClass}\n		constructor: (${3:args}) ->\n			${4}\n\n		${5}\n# If\nsnippet if\n	if ${1:condition}\n		${2:// body...}\n# If __ Else\nsnippet ife\n	if ${1:condition}\n		${2:// body...}\n	else\n		${3:// body...}\n# Else if\nsnippet elif\n	else if ${1:condition}\n		${2:// body...}\n# Ternary If\nsnippet ifte\n	if ${1:condition} then ${2:value} else ${3:other}\n# Unless\nsnippet unl\n	${1:action} unless ${2:condition}\n# Switch\nsnippet swi\n	switch ${1:object}\n		when ${2:value}\n			${3:// body...}\n\n# Log\nsnippet log\n	console.log ${1}\n# Try __ Catch\nsnippet try\n	try\n		${1}\n	catch ${2:error}\n		${3}\n# Require\nsnippet req\n	${2:$1} = require '${1:sys}'${3}\n# Export\nsnippet exp\n	${1:root} = exports ? this\n",t.scope="coffee"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/coldfusion.js b/dist/assets/js/vendor/ace-nc/snippets/coldfusion.js
            new file mode 100644
            index 0000000000..5342f2f96a
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/coldfusion.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/coldfusion",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="coldfusion"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/csharp.js b/dist/assets/js/vendor/ace-nc/snippets/csharp.js
            new file mode 100644
            index 0000000000..9805077aeb
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/csharp.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/csharp",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="csharp"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/css.js b/dist/assets/js/vendor/ace-nc/snippets/css.js
            new file mode 100644
            index 0000000000..9659ba49b1
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/css.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/css",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet .\n	${1} {\n		${2}\n	}\nsnippet !\n	 !important\nsnippet bdi:m+\n	-moz-border-image: url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${7:stretch};\nsnippet bdi:m\n	-moz-border-image: ${1};\nsnippet bdrz:m\n	-moz-border-radius: ${1};\nsnippet bxsh:m+\n	-moz-box-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet bxsh:m\n	-moz-box-shadow: ${1};\nsnippet bdi:w+\n	-webkit-border-image: url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${7:stretch};\nsnippet bdi:w\n	-webkit-border-image: ${1};\nsnippet bdrz:w\n	-webkit-border-radius: ${1};\nsnippet bxsh:w+\n	-webkit-box-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet bxsh:w\n	-webkit-box-shadow: ${1};\nsnippet @f\n	@font-face {\n		font-family: ${1};\n		src: url(${2});\n	}\nsnippet @i\n	@import url(${1});\nsnippet @m\n	@media ${1:print} {\n		${2}\n	}\nsnippet bg+\n	background: #${1:FFF} url(${2}) ${3:0} ${4:0} ${5:no-repeat};\nsnippet bga\n	background-attachment: ${1};\nsnippet bga:f\n	background-attachment: fixed;\nsnippet bga:s\n	background-attachment: scroll;\nsnippet bgbk\n	background-break: ${1};\nsnippet bgbk:bb\n	background-break: bounding-box;\nsnippet bgbk:c\n	background-break: continuous;\nsnippet bgbk:eb\n	background-break: each-box;\nsnippet bgcp\n	background-clip: ${1};\nsnippet bgcp:bb\n	background-clip: border-box;\nsnippet bgcp:cb\n	background-clip: content-box;\nsnippet bgcp:nc\n	background-clip: no-clip;\nsnippet bgcp:pb\n	background-clip: padding-box;\nsnippet bgc\n	background-color: #${1:FFF};\nsnippet bgc:t\n	background-color: transparent;\nsnippet bgi\n	background-image: url(${1});\nsnippet bgi:n\n	background-image: none;\nsnippet bgo\n	background-origin: ${1};\nsnippet bgo:bb\n	background-origin: border-box;\nsnippet bgo:cb\n	background-origin: content-box;\nsnippet bgo:pb\n	background-origin: padding-box;\nsnippet bgpx\n	background-position-x: ${1};\nsnippet bgpy\n	background-position-y: ${1};\nsnippet bgp\n	background-position: ${1:0} ${2:0};\nsnippet bgr\n	background-repeat: ${1};\nsnippet bgr:n\n	background-repeat: no-repeat;\nsnippet bgr:x\n	background-repeat: repeat-x;\nsnippet bgr:y\n	background-repeat: repeat-y;\nsnippet bgr:r\n	background-repeat: repeat;\nsnippet bgz\n	background-size: ${1};\nsnippet bgz:a\n	background-size: auto;\nsnippet bgz:ct\n	background-size: contain;\nsnippet bgz:cv\n	background-size: cover;\nsnippet bg\n	background: ${1};\nsnippet bg:ie\n	filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='${1}',sizingMethod='${2:crop}');\nsnippet bg:n\n	background: none;\nsnippet bd+\n	border: ${1:1px} ${2:solid} #${3:000};\nsnippet bdb+\n	border-bottom: ${1:1px} ${2:solid} #${3:000};\nsnippet bdbc\n	border-bottom-color: #${1:000};\nsnippet bdbi\n	border-bottom-image: url(${1});\nsnippet bdbi:n\n	border-bottom-image: none;\nsnippet bdbli\n	border-bottom-left-image: url(${1});\nsnippet bdbli:c\n	border-bottom-left-image: continue;\nsnippet bdbli:n\n	border-bottom-left-image: none;\nsnippet bdblrz\n	border-bottom-left-radius: ${1};\nsnippet bdbri\n	border-bottom-right-image: url(${1});\nsnippet bdbri:c\n	border-bottom-right-image: continue;\nsnippet bdbri:n\n	border-bottom-right-image: none;\nsnippet bdbrrz\n	border-bottom-right-radius: ${1};\nsnippet bdbs\n	border-bottom-style: ${1};\nsnippet bdbs:n\n	border-bottom-style: none;\nsnippet bdbw\n	border-bottom-width: ${1};\nsnippet bdb\n	border-bottom: ${1};\nsnippet bdb:n\n	border-bottom: none;\nsnippet bdbk\n	border-break: ${1};\nsnippet bdbk:c\n	border-break: close;\nsnippet bdcl\n	border-collapse: ${1};\nsnippet bdcl:c\n	border-collapse: collapse;\nsnippet bdcl:s\n	border-collapse: separate;\nsnippet bdc\n	border-color: #${1:000};\nsnippet bdci\n	border-corner-image: url(${1});\nsnippet bdci:c\n	border-corner-image: continue;\nsnippet bdci:n\n	border-corner-image: none;\nsnippet bdf\n	border-fit: ${1};\nsnippet bdf:c\n	border-fit: clip;\nsnippet bdf:of\n	border-fit: overwrite;\nsnippet bdf:ow\n	border-fit: overwrite;\nsnippet bdf:r\n	border-fit: repeat;\nsnippet bdf:sc\n	border-fit: scale;\nsnippet bdf:sp\n	border-fit: space;\nsnippet bdf:st\n	border-fit: stretch;\nsnippet bdi\n	border-image: url(${1}) ${2:0} ${3:0} ${4:0} ${5:0} ${6:stretch} ${7:stretch};\nsnippet bdi:n\n	border-image: none;\nsnippet bdl+\n	border-left: ${1:1px} ${2:solid} #${3:000};\nsnippet bdlc\n	border-left-color: #${1:000};\nsnippet bdli\n	border-left-image: url(${1});\nsnippet bdli:n\n	border-left-image: none;\nsnippet bdls\n	border-left-style: ${1};\nsnippet bdls:n\n	border-left-style: none;\nsnippet bdlw\n	border-left-width: ${1};\nsnippet bdl\n	border-left: ${1};\nsnippet bdl:n\n	border-left: none;\nsnippet bdlt\n	border-length: ${1};\nsnippet bdlt:a\n	border-length: auto;\nsnippet bdrz\n	border-radius: ${1};\nsnippet bdr+\n	border-right: ${1:1px} ${2:solid} #${3:000};\nsnippet bdrc\n	border-right-color: #${1:000};\nsnippet bdri\n	border-right-image: url(${1});\nsnippet bdri:n\n	border-right-image: none;\nsnippet bdrs\n	border-right-style: ${1};\nsnippet bdrs:n\n	border-right-style: none;\nsnippet bdrw\n	border-right-width: ${1};\nsnippet bdr\n	border-right: ${1};\nsnippet bdr:n\n	border-right: none;\nsnippet bdsp\n	border-spacing: ${1};\nsnippet bds\n	border-style: ${1};\nsnippet bds:ds\n	border-style: dashed;\nsnippet bds:dtds\n	border-style: dot-dash;\nsnippet bds:dtdtds\n	border-style: dot-dot-dash;\nsnippet bds:dt\n	border-style: dotted;\nsnippet bds:db\n	border-style: double;\nsnippet bds:g\n	border-style: groove;\nsnippet bds:h\n	border-style: hidden;\nsnippet bds:i\n	border-style: inset;\nsnippet bds:n\n	border-style: none;\nsnippet bds:o\n	border-style: outset;\nsnippet bds:r\n	border-style: ridge;\nsnippet bds:s\n	border-style: solid;\nsnippet bds:w\n	border-style: wave;\nsnippet bdt+\n	border-top: ${1:1px} ${2:solid} #${3:000};\nsnippet bdtc\n	border-top-color: #${1:000};\nsnippet bdti\n	border-top-image: url(${1});\nsnippet bdti:n\n	border-top-image: none;\nsnippet bdtli\n	border-top-left-image: url(${1});\nsnippet bdtli:c\n	border-corner-image: continue;\nsnippet bdtli:n\n	border-corner-image: none;\nsnippet bdtlrz\n	border-top-left-radius: ${1};\nsnippet bdtri\n	border-top-right-image: url(${1});\nsnippet bdtri:c\n	border-top-right-image: continue;\nsnippet bdtri:n\n	border-top-right-image: none;\nsnippet bdtrrz\n	border-top-right-radius: ${1};\nsnippet bdts\n	border-top-style: ${1};\nsnippet bdts:n\n	border-top-style: none;\nsnippet bdtw\n	border-top-width: ${1};\nsnippet bdt\n	border-top: ${1};\nsnippet bdt:n\n	border-top: none;\nsnippet bdw\n	border-width: ${1};\nsnippet bd\n	border: ${1};\nsnippet bd:n\n	border: none;\nsnippet b\n	bottom: ${1};\nsnippet b:a\n	bottom: auto;\nsnippet bxsh+\n	box-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet bxsh\n	box-shadow: ${1};\nsnippet bxsh:n\n	box-shadow: none;\nsnippet bxz\n	box-sizing: ${1};\nsnippet bxz:bb\n	box-sizing: border-box;\nsnippet bxz:cb\n	box-sizing: content-box;\nsnippet cps\n	caption-side: ${1};\nsnippet cps:b\n	caption-side: bottom;\nsnippet cps:t\n	caption-side: top;\nsnippet cl\n	clear: ${1};\nsnippet cl:b\n	clear: both;\nsnippet cl:l\n	clear: left;\nsnippet cl:n\n	clear: none;\nsnippet cl:r\n	clear: right;\nsnippet cp\n	clip: ${1};\nsnippet cp:a\n	clip: auto;\nsnippet cp:r\n	clip: rect(${1:0} ${2:0} ${3:0} ${4:0});\nsnippet c\n	color: #${1:000};\nsnippet ct\n	content: ${1};\nsnippet ct:a\n	content: attr(${1});\nsnippet ct:cq\n	content: close-quote;\nsnippet ct:c\n	content: counter(${1});\nsnippet ct:cs\n	content: counters(${1});\nsnippet ct:ncq\n	content: no-close-quote;\nsnippet ct:noq\n	content: no-open-quote;\nsnippet ct:n\n	content: normal;\nsnippet ct:oq\n	content: open-quote;\nsnippet coi\n	counter-increment: ${1};\nsnippet cor\n	counter-reset: ${1};\nsnippet cur\n	cursor: ${1};\nsnippet cur:a\n	cursor: auto;\nsnippet cur:c\n	cursor: crosshair;\nsnippet cur:d\n	cursor: default;\nsnippet cur:ha\n	cursor: hand;\nsnippet cur:he\n	cursor: help;\nsnippet cur:m\n	cursor: move;\nsnippet cur:p\n	cursor: pointer;\nsnippet cur:t\n	cursor: text;\nsnippet d\n	display: ${1};\nsnippet d:mib\n	display: -moz-inline-box;\nsnippet d:mis\n	display: -moz-inline-stack;\nsnippet d:b\n	display: block;\nsnippet d:cp\n	display: compact;\nsnippet d:ib\n	display: inline-block;\nsnippet d:itb\n	display: inline-table;\nsnippet d:i\n	display: inline;\nsnippet d:li\n	display: list-item;\nsnippet d:n\n	display: none;\nsnippet d:ri\n	display: run-in;\nsnippet d:tbcp\n	display: table-caption;\nsnippet d:tbc\n	display: table-cell;\nsnippet d:tbclg\n	display: table-column-group;\nsnippet d:tbcl\n	display: table-column;\nsnippet d:tbfg\n	display: table-footer-group;\nsnippet d:tbhg\n	display: table-header-group;\nsnippet d:tbrg\n	display: table-row-group;\nsnippet d:tbr\n	display: table-row;\nsnippet d:tb\n	display: table;\nsnippet ec\n	empty-cells: ${1};\nsnippet ec:h\n	empty-cells: hide;\nsnippet ec:s\n	empty-cells: show;\nsnippet exp\n	expression()\nsnippet fl\n	float: ${1};\nsnippet fl:l\n	float: left;\nsnippet fl:n\n	float: none;\nsnippet fl:r\n	float: right;\nsnippet f+\n	font: ${1:1em} ${2:Arial},${3:sans-serif};\nsnippet fef\n	font-effect: ${1};\nsnippet fef:eb\n	font-effect: emboss;\nsnippet fef:eg\n	font-effect: engrave;\nsnippet fef:n\n	font-effect: none;\nsnippet fef:o\n	font-effect: outline;\nsnippet femp\n	font-emphasize-position: ${1};\nsnippet femp:a\n	font-emphasize-position: after;\nsnippet femp:b\n	font-emphasize-position: before;\nsnippet fems\n	font-emphasize-style: ${1};\nsnippet fems:ac\n	font-emphasize-style: accent;\nsnippet fems:c\n	font-emphasize-style: circle;\nsnippet fems:ds\n	font-emphasize-style: disc;\nsnippet fems:dt\n	font-emphasize-style: dot;\nsnippet fems:n\n	font-emphasize-style: none;\nsnippet fem\n	font-emphasize: ${1};\nsnippet ff\n	font-family: ${1};\nsnippet ff:c\n	font-family: ${1:'Monotype Corsiva','Comic Sans MS'},cursive;\nsnippet ff:f\n	font-family: ${1:Capitals,Impact},fantasy;\nsnippet ff:m\n	font-family: ${1:Monaco,'Courier New'},monospace;\nsnippet ff:ss\n	font-family: ${1:Helvetica,Arial},sans-serif;\nsnippet ff:s\n	font-family: ${1:Georgia,'Times New Roman'},serif;\nsnippet fza\n	font-size-adjust: ${1};\nsnippet fza:n\n	font-size-adjust: none;\nsnippet fz\n	font-size: ${1};\nsnippet fsm\n	font-smooth: ${1};\nsnippet fsm:aw\n	font-smooth: always;\nsnippet fsm:a\n	font-smooth: auto;\nsnippet fsm:n\n	font-smooth: never;\nsnippet fst\n	font-stretch: ${1};\nsnippet fst:c\n	font-stretch: condensed;\nsnippet fst:e\n	font-stretch: expanded;\nsnippet fst:ec\n	font-stretch: extra-condensed;\nsnippet fst:ee\n	font-stretch: extra-expanded;\nsnippet fst:n\n	font-stretch: normal;\nsnippet fst:sc\n	font-stretch: semi-condensed;\nsnippet fst:se\n	font-stretch: semi-expanded;\nsnippet fst:uc\n	font-stretch: ultra-condensed;\nsnippet fst:ue\n	font-stretch: ultra-expanded;\nsnippet fs\n	font-style: ${1};\nsnippet fs:i\n	font-style: italic;\nsnippet fs:n\n	font-style: normal;\nsnippet fs:o\n	font-style: oblique;\nsnippet fv\n	font-variant: ${1};\nsnippet fv:n\n	font-variant: normal;\nsnippet fv:sc\n	font-variant: small-caps;\nsnippet fw\n	font-weight: ${1};\nsnippet fw:b\n	font-weight: bold;\nsnippet fw:br\n	font-weight: bolder;\nsnippet fw:lr\n	font-weight: lighter;\nsnippet fw:n\n	font-weight: normal;\nsnippet f\n	font: ${1};\nsnippet h\n	height: ${1};\nsnippet h:a\n	height: auto;\nsnippet l\n	left: ${1};\nsnippet l:a\n	left: auto;\nsnippet lts\n	letter-spacing: ${1};\nsnippet lh\n	line-height: ${1};\nsnippet lisi\n	list-style-image: url(${1});\nsnippet lisi:n\n	list-style-image: none;\nsnippet lisp\n	list-style-position: ${1};\nsnippet lisp:i\n	list-style-position: inside;\nsnippet lisp:o\n	list-style-position: outside;\nsnippet list\n	list-style-type: ${1};\nsnippet list:c\n	list-style-type: circle;\nsnippet list:dclz\n	list-style-type: decimal-leading-zero;\nsnippet list:dc\n	list-style-type: decimal;\nsnippet list:d\n	list-style-type: disc;\nsnippet list:lr\n	list-style-type: lower-roman;\nsnippet list:n\n	list-style-type: none;\nsnippet list:s\n	list-style-type: square;\nsnippet list:ur\n	list-style-type: upper-roman;\nsnippet lis\n	list-style: ${1};\nsnippet lis:n\n	list-style: none;\nsnippet mb\n	margin-bottom: ${1};\nsnippet mb:a\n	margin-bottom: auto;\nsnippet ml\n	margin-left: ${1};\nsnippet ml:a\n	margin-left: auto;\nsnippet mr\n	margin-right: ${1};\nsnippet mr:a\n	margin-right: auto;\nsnippet mt\n	margin-top: ${1};\nsnippet mt:a\n	margin-top: auto;\nsnippet m\n	margin: ${1};\nsnippet m:4\n	margin: ${1:0} ${2:0} ${3:0} ${4:0};\nsnippet m:3\n	margin: ${1:0} ${2:0} ${3:0};\nsnippet m:2\n	margin: ${1:0} ${2:0};\nsnippet m:0\n	margin: 0;\nsnippet m:a\n	margin: auto;\nsnippet mah\n	max-height: ${1};\nsnippet mah:n\n	max-height: none;\nsnippet maw\n	max-width: ${1};\nsnippet maw:n\n	max-width: none;\nsnippet mih\n	min-height: ${1};\nsnippet miw\n	min-width: ${1};\nsnippet op\n	opacity: ${1};\nsnippet op:ie\n	filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=${1:100});\nsnippet op:ms\n	-ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=${1:100})';\nsnippet orp\n	orphans: ${1};\nsnippet o+\n	outline: ${1:1px} ${2:solid} #${3:000};\nsnippet oc\n	outline-color: ${1:#000};\nsnippet oc:i\n	outline-color: invert;\nsnippet oo\n	outline-offset: ${1};\nsnippet os\n	outline-style: ${1};\nsnippet ow\n	outline-width: ${1};\nsnippet o\n	outline: ${1};\nsnippet o:n\n	outline: none;\nsnippet ovs\n	overflow-style: ${1};\nsnippet ovs:a\n	overflow-style: auto;\nsnippet ovs:mq\n	overflow-style: marquee;\nsnippet ovs:mv\n	overflow-style: move;\nsnippet ovs:p\n	overflow-style: panner;\nsnippet ovs:s\n	overflow-style: scrollbar;\nsnippet ovx\n	overflow-x: ${1};\nsnippet ovx:a\n	overflow-x: auto;\nsnippet ovx:h\n	overflow-x: hidden;\nsnippet ovx:s\n	overflow-x: scroll;\nsnippet ovx:v\n	overflow-x: visible;\nsnippet ovy\n	overflow-y: ${1};\nsnippet ovy:a\n	overflow-y: auto;\nsnippet ovy:h\n	overflow-y: hidden;\nsnippet ovy:s\n	overflow-y: scroll;\nsnippet ovy:v\n	overflow-y: visible;\nsnippet ov\n	overflow: ${1};\nsnippet ov:a\n	overflow: auto;\nsnippet ov:h\n	overflow: hidden;\nsnippet ov:s\n	overflow: scroll;\nsnippet ov:v\n	overflow: visible;\nsnippet pb\n	padding-bottom: ${1};\nsnippet pl\n	padding-left: ${1};\nsnippet pr\n	padding-right: ${1};\nsnippet pt\n	padding-top: ${1};\nsnippet p\n	padding: ${1};\nsnippet p:4\n	padding: ${1:0} ${2:0} ${3:0} ${4:0};\nsnippet p:3\n	padding: ${1:0} ${2:0} ${3:0};\nsnippet p:2\n	padding: ${1:0} ${2:0};\nsnippet p:0\n	padding: 0;\nsnippet pgba\n	page-break-after: ${1};\nsnippet pgba:aw\n	page-break-after: always;\nsnippet pgba:a\n	page-break-after: auto;\nsnippet pgba:l\n	page-break-after: left;\nsnippet pgba:r\n	page-break-after: right;\nsnippet pgbb\n	page-break-before: ${1};\nsnippet pgbb:aw\n	page-break-before: always;\nsnippet pgbb:a\n	page-break-before: auto;\nsnippet pgbb:l\n	page-break-before: left;\nsnippet pgbb:r\n	page-break-before: right;\nsnippet pgbi\n	page-break-inside: ${1};\nsnippet pgbi:a\n	page-break-inside: auto;\nsnippet pgbi:av\n	page-break-inside: avoid;\nsnippet pos\n	position: ${1};\nsnippet pos:a\n	position: absolute;\nsnippet pos:f\n	position: fixed;\nsnippet pos:r\n	position: relative;\nsnippet pos:s\n	position: static;\nsnippet q\n	quotes: ${1};\nsnippet q:en\n	quotes: '\\201C' '\\201D' '\\2018' '\\2019';\nsnippet q:n\n	quotes: none;\nsnippet q:ru\n	quotes: '\\00AB' '\\00BB' '\\201E' '\\201C';\nsnippet rz\n	resize: ${1};\nsnippet rz:b\n	resize: both;\nsnippet rz:h\n	resize: horizontal;\nsnippet rz:n\n	resize: none;\nsnippet rz:v\n	resize: vertical;\nsnippet r\n	right: ${1};\nsnippet r:a\n	right: auto;\nsnippet tbl\n	table-layout: ${1};\nsnippet tbl:a\n	table-layout: auto;\nsnippet tbl:f\n	table-layout: fixed;\nsnippet tal\n	text-align-last: ${1};\nsnippet tal:a\n	text-align-last: auto;\nsnippet tal:c\n	text-align-last: center;\nsnippet tal:l\n	text-align-last: left;\nsnippet tal:r\n	text-align-last: right;\nsnippet ta\n	text-align: ${1};\nsnippet ta:c\n	text-align: center;\nsnippet ta:l\n	text-align: left;\nsnippet ta:r\n	text-align: right;\nsnippet td\n	text-decoration: ${1};\nsnippet td:l\n	text-decoration: line-through;\nsnippet td:n\n	text-decoration: none;\nsnippet td:o\n	text-decoration: overline;\nsnippet td:u\n	text-decoration: underline;\nsnippet te\n	text-emphasis: ${1};\nsnippet te:ac\n	text-emphasis: accent;\nsnippet te:a\n	text-emphasis: after;\nsnippet te:b\n	text-emphasis: before;\nsnippet te:c\n	text-emphasis: circle;\nsnippet te:ds\n	text-emphasis: disc;\nsnippet te:dt\n	text-emphasis: dot;\nsnippet te:n\n	text-emphasis: none;\nsnippet th\n	text-height: ${1};\nsnippet th:a\n	text-height: auto;\nsnippet th:f\n	text-height: font-size;\nsnippet th:m\n	text-height: max-size;\nsnippet th:t\n	text-height: text-size;\nsnippet ti\n	text-indent: ${1};\nsnippet ti:-\n	text-indent: -9999px;\nsnippet tj\n	text-justify: ${1};\nsnippet tj:a\n	text-justify: auto;\nsnippet tj:d\n	text-justify: distribute;\nsnippet tj:ic\n	text-justify: inter-cluster;\nsnippet tj:ii\n	text-justify: inter-ideograph;\nsnippet tj:iw\n	text-justify: inter-word;\nsnippet tj:k\n	text-justify: kashida;\nsnippet tj:t\n	text-justify: tibetan;\nsnippet to+\n	text-outline: ${1:0} ${2:0} #${3:000};\nsnippet to\n	text-outline: ${1};\nsnippet to:n\n	text-outline: none;\nsnippet tr\n	text-replace: ${1};\nsnippet tr:n\n	text-replace: none;\nsnippet tsh+\n	text-shadow: ${1:0} ${2:0} ${3:0} #${4:000};\nsnippet tsh\n	text-shadow: ${1};\nsnippet tsh:n\n	text-shadow: none;\nsnippet tt\n	text-transform: ${1};\nsnippet tt:c\n	text-transform: capitalize;\nsnippet tt:l\n	text-transform: lowercase;\nsnippet tt:n\n	text-transform: none;\nsnippet tt:u\n	text-transform: uppercase;\nsnippet tw\n	text-wrap: ${1};\nsnippet tw:no\n	text-wrap: none;\nsnippet tw:n\n	text-wrap: normal;\nsnippet tw:s\n	text-wrap: suppress;\nsnippet tw:u\n	text-wrap: unrestricted;\nsnippet t\n	top: ${1};\nsnippet t:a\n	top: auto;\nsnippet va\n	vertical-align: ${1};\nsnippet va:bl\n	vertical-align: baseline;\nsnippet va:b\n	vertical-align: bottom;\nsnippet va:m\n	vertical-align: middle;\nsnippet va:sub\n	vertical-align: sub;\nsnippet va:sup\n	vertical-align: super;\nsnippet va:tb\n	vertical-align: text-bottom;\nsnippet va:tt\n	vertical-align: text-top;\nsnippet va:t\n	vertical-align: top;\nsnippet v\n	visibility: ${1};\nsnippet v:c\n	visibility: collapse;\nsnippet v:h\n	visibility: hidden;\nsnippet v:v\n	visibility: visible;\nsnippet whsc\n	white-space-collapse: ${1};\nsnippet whsc:ba\n	white-space-collapse: break-all;\nsnippet whsc:bs\n	white-space-collapse: break-strict;\nsnippet whsc:k\n	white-space-collapse: keep-all;\nsnippet whsc:l\n	white-space-collapse: loose;\nsnippet whsc:n\n	white-space-collapse: normal;\nsnippet whs\n	white-space: ${1};\nsnippet whs:n\n	white-space: normal;\nsnippet whs:nw\n	white-space: nowrap;\nsnippet whs:pl\n	white-space: pre-line;\nsnippet whs:pw\n	white-space: pre-wrap;\nsnippet whs:p\n	white-space: pre;\nsnippet wid\n	widows: ${1};\nsnippet w\n	width: ${1};\nsnippet w:a\n	width: auto;\nsnippet wob\n	word-break: ${1};\nsnippet wob:ba\n	word-break: break-all;\nsnippet wob:bs\n	word-break: break-strict;\nsnippet wob:k\n	word-break: keep-all;\nsnippet wob:l\n	word-break: loose;\nsnippet wob:n\n	word-break: normal;\nsnippet wos\n	word-spacing: ${1};\nsnippet wow\n	word-wrap: ${1};\nsnippet wow:no\n	word-wrap: none;\nsnippet wow:n\n	word-wrap: normal;\nsnippet wow:s\n	word-wrap: suppress;\nsnippet wow:u\n	word-wrap: unrestricted;\nsnippet z\n	z-index: ${1};\nsnippet z:a\n	z-index: auto;\nsnippet zoo\n	zoom: 1;\n",t.scope="css"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/curly.js b/dist/assets/js/vendor/ace-nc/snippets/curly.js
            new file mode 100644
            index 0000000000..6bb5604e06
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/curly.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/curly",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="curly"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/d.js b/dist/assets/js/vendor/ace-nc/snippets/d.js
            new file mode 100644
            index 0000000000..1057608dac
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/d.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/d",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="d"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/dart.js b/dist/assets/js/vendor/ace-nc/snippets/dart.js
            new file mode 100644
            index 0000000000..63c63c9fc4
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/dart.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/dart",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet lib\n	library ${1};\n	${2}\nsnippet im\n	import '${1}';\n	${2}\nsnippet pa\n	part '${1}';\n	${2}\nsnippet pao\n	part of ${1};\n	${2}\nsnippet main\n	void main() {\n	  ${1:/* code */}\n	}\nsnippet st\n	static ${1}\nsnippet fi\n	final ${1}\nsnippet re\n	return ${1}\nsnippet br\n	break;\nsnippet th\n	throw ${1}\nsnippet cl\n	class ${1:`Filename(\"\", \"untitled\")`} ${2}\nsnippet imp\n	implements ${1}\nsnippet ext\n	extends ${1}\nsnippet if\n	if (${1:true}) {\n	  ${2}\n	}\nsnippet ife\n	if (${1:true}) {\n	  ${2}\n	} else {\n	  ${3}\n	}\nsnippet el\n	else\nsnippet sw\n	switch (${1}) {\n	  ${2}\n	}\nsnippet cs\n	case ${1}:\n	  ${2}\nsnippet de\n	default:\n	  ${1}\nsnippet for\n	for (var ${2:i} = 0, len = ${1:things}.length; $2 < len; ${3:++}$2) {\n	  ${4:$1[$2]}\n	}\nsnippet fore\n	for (final ${2:item} in ${1:itemList}) {\n	  ${3:/* code */}\n	}\nsnippet wh\n	while (${1:/* condition */}) {\n	  ${2:/* code */}\n	}\nsnippet dowh\n	do {\n	  ${2:/* code */}\n	} while (${1:/* condition */});\nsnippet as\n	assert(${1:/* condition */});\nsnippet try\n	try {\n	  ${2}\n	} catch (${1:Exception e}) {\n	}\nsnippet tryf\n	try {\n	  ${2}\n	} catch (${1:Exception e}) {\n	} finally {\n	}\n",t.scope="dart"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/diff.js b/dist/assets/js/vendor/ace-nc/snippets/diff.js
            new file mode 100644
            index 0000000000..493c0e9a38
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/diff.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/diff",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# DEP-3 (http://dep.debian.net/deps/dep3/) style patch header\nsnippet header DEP-3 style header\n	Description: ${1}\n	Origin: ${2:vendor|upstream|other}, ${3:url of the original patch}\n	Bug: ${4:url in upstream bugtracker}\n	Forwarded: ${5:no|not-needed|url}\n	Author: ${6:`g:snips_author`}\n	Reviewed-by: ${7:name and email}\n	Last-Update: ${8:`strftime("%Y-%m-%d")`}\n	Applied-Upstream: ${9:upstream version|url|commit}\n\n',t.scope="diff"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/django.js b/dist/assets/js/vendor/ace-nc/snippets/django.js
            new file mode 100644
            index 0000000000..d0f67a6c67
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/django.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/django",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="# Model Fields\n\n# Note: Optional arguments are using defaults that match what Django will use\n# as a default, e.g. with max_length fields.  Doing this as a form of self\n# documentation and to make it easy to know whether you should override the\n# default or not.\n\n# Note: Optional arguments that are booleans will use the opposite since you\n# can either not specify them, or override them, e.g. auto_now_add=False.\n\nsnippet auto\n	${1:FIELDNAME} = models.AutoField(${2})\nsnippet bool\n	${1:FIELDNAME} = models.BooleanField(${2:default=True})\nsnippet char\n	${1:FIELDNAME} = models.CharField(max_length=${2}${3:, blank=True})\nsnippet comma\n	${1:FIELDNAME} = models.CommaSeparatedIntegerField(max_length=${2}${3:, blank=True})\nsnippet date\n	${1:FIELDNAME} = models.DateField(${2:auto_now_add=True, auto_now=True}${3:, blank=True, null=True})\nsnippet datetime\n	${1:FIELDNAME} = models.DateTimeField(${2:auto_now_add=True, auto_now=True}${3:, blank=True, null=True})\nsnippet decimal\n	${1:FIELDNAME} = models.DecimalField(max_digits=${2}, decimal_places=${3})\nsnippet email\n	${1:FIELDNAME} = models.EmailField(max_length=${2:75}${3:, blank=True})\nsnippet file\n	${1:FIELDNAME} = models.FileField(upload_to=${2:path/for/upload}${3:, max_length=100})\nsnippet filepath\n	${1:FIELDNAME} = models.FilePathField(path=${2:\"/abs/path/to/dir\"}${3:, max_length=100}${4:, match=\"*.ext\"}${5:, recursive=True}${6:, blank=True, })\nsnippet float\n	${1:FIELDNAME} = models.FloatField(${2})\nsnippet image\n	${1:FIELDNAME} = models.ImageField(upload_to=${2:path/for/upload}${3:, height_field=height, width_field=width}${4:, max_length=100})\nsnippet int\n	${1:FIELDNAME} = models.IntegerField(${2})\nsnippet ip\n	${1:FIELDNAME} = models.IPAddressField(${2})\nsnippet nullbool\n	${1:FIELDNAME} = models.NullBooleanField(${2})\nsnippet posint\n	${1:FIELDNAME} = models.PositiveIntegerField(${2})\nsnippet possmallint\n	${1:FIELDNAME} = models.PositiveSmallIntegerField(${2})\nsnippet slug\n	${1:FIELDNAME} = models.SlugField(max_length=${2:50}${3:, blank=True})\nsnippet smallint\n	${1:FIELDNAME} = models.SmallIntegerField(${2})\nsnippet text\n	${1:FIELDNAME} = models.TextField(${2:blank=True})\nsnippet time\n	${1:FIELDNAME} = models.TimeField(${2:auto_now_add=True, auto_now=True}${3:, blank=True, null=True})\nsnippet url\n	${1:FIELDNAME} = models.URLField(${2:verify_exists=False}${3:, max_length=200}${4:, blank=True})\nsnippet xml\n	${1:FIELDNAME} = models.XMLField(schema_path=${2:None}${3:, blank=True})\n# Relational Fields\nsnippet fk\n	${1:FIELDNAME} = models.ForeignKey(${2:OtherModel}${3:, related_name=''}${4:, limit_choices_to=}${5:, to_field=''})\nsnippet m2m\n	${1:FIELDNAME} = models.ManyToManyField(${2:OtherModel}${3:, related_name=''}${4:, limit_choices_to=}${5:, symmetrical=False}${6:, through=''}${7:, db_table=''})\nsnippet o2o\n	${1:FIELDNAME} = models.OneToOneField(${2:OtherModel}${3:, parent_link=True}${4:, related_name=''}${5:, limit_choices_to=}${6:, to_field=''})\n\n# Code Skeletons\n\nsnippet form\n	class ${1:FormName}(forms.Form):\n		\"\"\"${2:docstring}\"\"\"\n		${3}\n\nsnippet model\n	class ${1:ModelName}(models.Model):\n		\"\"\"${2:docstring}\"\"\"\n		${3}\n		\n		class Meta:\n			${4}\n		\n		def __unicode__(self):\n			${5}\n		\n		def save(self, force_insert=False, force_update=False):\n			${6}\n		\n		@models.permalink\n		def get_absolute_url(self):\n			return ('${7:view_or_url_name}' ${8})\n\nsnippet modeladmin\n	class ${1:ModelName}Admin(admin.ModelAdmin):\n		${2}\n	\n	admin.site.register($1, $1Admin)\n	\nsnippet tabularinline\n	class ${1:ModelName}Inline(admin.TabularInline):\n		model = $1\n\nsnippet stackedinline\n	class ${1:ModelName}Inline(admin.StackedInline):\n		model = $1\n\nsnippet r2r\n	return render_to_response('${1:template.html}', {\n			${2}\n		}${3:, context_instance=RequestContext(request)}\n	)\n",t.scope="django"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/dockerfile.js b/dist/assets/js/vendor/ace-nc/snippets/dockerfile.js
            new file mode 100644
            index 0000000000..0c27420207
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/dockerfile.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/dockerfile",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="dockerfile"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/dot.js b/dist/assets/js/vendor/ace-nc/snippets/dot.js
            new file mode 100644
            index 0000000000..d4a9e9b7a1
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/dot.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/dot",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="dot"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/ejs.js b/dist/assets/js/vendor/ace-nc/snippets/ejs.js
            new file mode 100644
            index 0000000000..2e8cbcac6f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/ejs.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/ejs",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="ejs"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/erlang.js b/dist/assets/js/vendor/ace-nc/snippets/erlang.js
            new file mode 100644
            index 0000000000..58de696d2c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/erlang.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/erlang",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="# module and export all\nsnippet mod\n	-module(${1:`Filename('', 'my')`}).\n	\n	-compile([export_all]).\n	\n	start() ->\n	    ${2}\n	\n	stop() ->\n	    ok.\n# define directive\nsnippet def\n	-ace.define(${1:macro}, ${2:body}).${3}\n# export directive\nsnippet exp\n	-export([${1:function}/${2:arity}]).\n# include directive\nsnippet inc\n	-include(\"${1:file}\").${2}\n# behavior directive\nsnippet beh\n	-behaviour(${1:behaviour}).${2}\n# if expression\nsnippet if\n	if\n	    ${1:guard} ->\n	        ${2:body}\n	end\n# case expression\nsnippet case\n	case ${1:expression} of\n	    ${2:pattern} ->\n	        ${3:body};\n	end\n# anonymous function\nsnippet fun\n	fun (${1:Parameters}) -> ${2:body} end${3}\n# try...catch\nsnippet try\n	try\n	    ${1}\n	catch\n	    ${2:_:_} -> ${3:got_some_exception}\n	end\n# record directive\nsnippet rec\n	-record(${1:record}, {\n	    ${2:field}=${3:value}}).${4}\n# todo comment\nsnippet todo\n	%% TODO: ${1}\n## Snippets below (starting with '%') are in EDoc format.\n## See http://www.erlang.org/doc/apps/edoc/chapter.html#id56887 for more details\n# doc comment\nsnippet %d\n	%% @doc ${1}\n# end of doc comment\nsnippet %e\n	%% @end\n# specification comment\nsnippet %s\n	%% @spec ${1}\n# private function marker\nsnippet %p\n	%% @private\n# OTP application\nsnippet application\n	-module(${1:`Filename('', 'my')`}).\n\n	-behaviour(application).\n\n	-export([start/2, stop/1]).\n\n	start(_Type, _StartArgs) ->\n	    case ${2:root_supervisor}:start_link() of\n	        {ok, Pid} ->\n	            {ok, Pid};\n	        Other ->\n		          {error, Other}\n	    end.\n\n	stop(_State) ->\n	    ok.	\n# OTP supervisor\nsnippet supervisor\n	-module(${1:`Filename('', 'my')`}).\n\n	-behaviour(supervisor).\n\n	%% API\n	-export([start_link/0]).\n\n	%% Supervisor callbacks\n	-export([init/1]).\n\n	-ace.define(SERVER, ?MODULE).\n\n	start_link() ->\n	    supervisor:start_link({local, ?SERVER}, ?MODULE, []).\n\n	init([]) ->\n	    Server = {${2:my_server}, {$2, start_link, []},\n	      permanent, 2000, worker, [$2]},\n	    Children = [Server],\n	    RestartStrategy = {one_for_one, 0, 1},\n	    {ok, {RestartStrategy, Children}}.\n# OTP gen_server\nsnippet gen_server\n	-module(${1:`Filename('', 'my')`}).\n\n	-behaviour(gen_server).\n\n	%% API\n	-export([\n	         start_link/0\n	        ]).\n\n	%% gen_server callbacks\n	-export([init/1, handle_call/3, handle_cast/2, handle_info/2,\n	         terminate/2, code_change/3]).\n\n	-ace.define(SERVER, ?MODULE).\n\n	-record(state, {}).\n\n	%%%===================================================================\n	%%% API\n	%%%===================================================================\n\n	start_link() ->\n	    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).\n\n	%%%===================================================================\n	%%% gen_server callbacks\n	%%%===================================================================\n\n	init([]) ->\n	    {ok, #state{}}.\n\n	handle_call(_Request, _From, State) ->\n	    Reply = ok,\n	    {reply, Reply, State}.\n\n	handle_cast(_Msg, State) ->\n	    {noreply, State}.\n\n	handle_info(_Info, State) ->\n	    {noreply, State}.\n\n	terminate(_Reason, _State) ->\n	    ok.\n\n	code_change(_OldVsn, State, _Extra) ->\n	    {ok, State}.\n\n	%%%===================================================================\n	%%% Internal functions\n	%%%===================================================================\n\n",t.scope="erlang"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/forth.js b/dist/assets/js/vendor/ace-nc/snippets/forth.js
            new file mode 100644
            index 0000000000..3aa9db09d3
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/forth.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/forth",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="forth"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/ftl.js b/dist/assets/js/vendor/ace-nc/snippets/ftl.js
            new file mode 100644
            index 0000000000..3e57d17239
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/ftl.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/ftl",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="ftl"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/gherkin.js b/dist/assets/js/vendor/ace-nc/snippets/gherkin.js
            new file mode 100644
            index 0000000000..44a88695f4
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/gherkin.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/gherkin",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="gherkin"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/gitignore.js b/dist/assets/js/vendor/ace-nc/snippets/gitignore.js
            new file mode 100644
            index 0000000000..87713df048
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/gitignore.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/gitignore",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="gitignore"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/glsl.js b/dist/assets/js/vendor/ace-nc/snippets/glsl.js
            new file mode 100644
            index 0000000000..042ed75b7a
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/glsl.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/glsl",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="glsl"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/golang.js b/dist/assets/js/vendor/ace-nc/snippets/golang.js
            new file mode 100644
            index 0000000000..f1f0309c06
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/golang.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/golang",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="golang"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/groovy.js b/dist/assets/js/vendor/ace-nc/snippets/groovy.js
            new file mode 100644
            index 0000000000..a293cc4891
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/groovy.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/groovy",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="groovy"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/haml.js b/dist/assets/js/vendor/ace-nc/snippets/haml.js
            new file mode 100644
            index 0000000000..95d637aad1
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/haml.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/haml",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet t\n	%table\n		%tr\n			%th\n				${1:headers}\n		%tr\n			%td\n				${2:headers}\nsnippet ul\n	%ul\n		%li\n			${1:item}\n		%li\nsnippet =rp\n	= render :partial => '${1:partial}'\nsnippet =rpl\n	= render :partial => '${1:partial}', :locals => {}\nsnippet =rpc\n	= render :partial => '${1:partial}', :collection => @$1\n\n",t.scope="haml"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/handlebars.js b/dist/assets/js/vendor/ace-nc/snippets/handlebars.js
            new file mode 100644
            index 0000000000..70dc88efa9
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/handlebars.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/handlebars",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="handlebars"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/haskell.js b/dist/assets/js/vendor/ace-nc/snippets/haskell.js
            new file mode 100644
            index 0000000000..69c2ef80b1
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/haskell.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/haskell",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet lang\n	{-# LANGUAGE ${1:OverloadedStrings} #-}\nsnippet info\n	-- |\n	-- Module      :  ${1:Module.Namespace}\n	-- Copyright   :  ${2:Author} ${3:2011-2012}\n	-- License     :  ${4:BSD3}\n	--\n	-- Maintainer  :  ${5:email@something.com}\n	-- Stability   :  ${6:experimental}\n	-- Portability :  ${7:unknown}\n	--\n	-- ${8:Description}\n	--\nsnippet import\n	import           ${1:Data.Text}\nsnippet import2\n	import           ${1:Data.Text} (${2:head})\nsnippet importq\n	import qualified ${1:Data.Text} as ${2:T}\nsnippet inst\n	instance ${1:Monoid} ${2:Type} where\n		${3}\nsnippet type\n	type ${1:Type} = ${2:Type}\nsnippet data\n	data ${1:Type} = ${2:$1} ${3:Int}\nsnippet newtype\n	newtype ${1:Type} = ${2:$1} ${3:Int}\nsnippet class\n	class ${1:Class} a where\n		${2}\nsnippet module\n	module `substitute(substitute(expand('%:r'), '[/\\\\]','.','g'),'^\\%(\\l*\\.\\)\\?','','')` (\n	)	where\n	`expand('%') =~ 'Main' ? \"\\n\\nmain = do\\n  print \\\"hello world\\\"\" : \"\"`\n\nsnippet const\n	${1:name} :: ${2:a}\n	$1 = ${3:undefined}\nsnippet fn\n	${1:fn} :: ${2:a} -> ${3:a}\n	$1 ${4} = ${5:undefined}\nsnippet fn2\n	${1:fn} :: ${2:a} -> ${3:a} -> ${4:a}\n	$1 ${5} = ${6:undefined}\nsnippet ap\n	${1:map} ${2:fn} ${3:list}\nsnippet do\n	do\n		\nsnippet \u03bb\n	\\${1:x} -> ${2}\nsnippet \\\n	\\${1:x} -> ${2}\nsnippet <-\n	${1:a} <- ${2:m a}\nsnippet \u2190\n	${1:a} <- ${2:m a}\nsnippet ->\n	${1:m a} -> ${2:a}\nsnippet \u2192\n	${1:m a} -> ${2:a}\nsnippet tup\n	(${1:a}, ${2:b})\nsnippet tup2\n	(${1:a}, ${2:b}, ${3:c})\nsnippet tup3\n	(${1:a}, ${2:b}, ${3:c}, ${4:d})\nsnippet rec\n	${1:Record} { ${2:recFieldA} = ${3:undefined}\n				, ${4:recFieldB} = ${5:undefined}\n				}\nsnippet case\n	case ${1:something} of\n		${2} -> ${3}\nsnippet let\n	let ${1} = ${2}\n	in ${3}\nsnippet where\n	where\n		${1:fn} = ${2:undefined}\n",t.scope="haskell"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/haxe.js b/dist/assets/js/vendor/ace-nc/snippets/haxe.js
            new file mode 100644
            index 0000000000..d24a9828e6
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/haxe.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/haxe",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="haxe"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/html.js b/dist/assets/js/vendor/ace-nc/snippets/html.js
            new file mode 100644
            index 0000000000..23177a3e0c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/html.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/html",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# Some useful Unicode entities\n# Non-Breaking Space\nsnippet nbs\n	&nbsp;\n# \u2190\nsnippet left\n	&#x2190;\n# \u2192\nsnippet right\n	&#x2192;\n# \u2191\nsnippet up\n	&#x2191;\n# \u2193\nsnippet down\n	&#x2193;\n# \u21a9\nsnippet return\n	&#x21A9;\n# \u21e4\nsnippet backtab\n	&#x21E4;\n# \u21e5\nsnippet tab\n	&#x21E5;\n# \u21e7\nsnippet shift\n	&#x21E7;\n# \u2303\nsnippet ctrl\n	&#x2303;\n# \u2305\nsnippet enter\n	&#x2305;\n# \u2318\nsnippet cmd\n	&#x2318;\n# \u2325\nsnippet option\n	&#x2325;\n# \u2326\nsnippet delete\n	&#x2326;\n# \u232b\nsnippet backspace\n	&#x232B;\n# \u238b\nsnippet esc\n	&#x238B;\n# Generic Doctype\nsnippet doctype HTML 4.01 Strict\n	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"\n	"http://www.w3.org/TR/html4/strict.dtd">\nsnippet doctype HTML 4.01 Transitional\n	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"\n	"http://www.w3.org/TR/html4/loose.dtd">\nsnippet doctype HTML 5\n	<!DOCTYPE HTML>\nsnippet doctype XHTML 1.0 Frameset\n	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\nsnippet doctype XHTML 1.0 Strict\n	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\nsnippet doctype XHTML 1.0 Transitional\n	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\nsnippet doctype XHTML 1.1\n	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\n	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n# HTML Doctype 4.01 Strict\nsnippet docts\n	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"\n	"http://www.w3.org/TR/html4/strict.dtd">\n# HTML Doctype 4.01 Transitional\nsnippet doct\n	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"\n	"http://www.w3.org/TR/html4/loose.dtd">\n# HTML Doctype 5\nsnippet doct5\n	<!DOCTYPE HTML>\n# XHTML Doctype 1.0 Frameset\nsnippet docxf\n	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"\n	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">\n# XHTML Doctype 1.0 Strict\nsnippet docxs\n	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n# XHTML Doctype 1.0 Transitional\nsnippet docxt\n	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"\n	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n# XHTML Doctype 1.1\nsnippet docx\n	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\n	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n# Attributes\nsnippet attr\n	${1:attribute}="${2:property}"\nsnippet attr+\n	${1:attribute}="${2:property}" attr+${3}\nsnippet .\n	class="${1}"${2}\nsnippet #\n	id="${1}"${2}\nsnippet alt\n	alt="${1}"${2}\nsnippet charset\n	charset="${1:utf-8}"${2}\nsnippet data\n	data-${1}="${2:$1}"${3}\nsnippet for\n	for="${1}"${2}\nsnippet height\n	height="${1}"${2}\nsnippet href\n	href="${1:#}"${2}\nsnippet lang\n	lang="${1:en}"${2}\nsnippet media\n	media="${1}"${2}\nsnippet name\n	name="${1}"${2}\nsnippet rel\n	rel="${1}"${2}\nsnippet scope\n	scope="${1:row}"${2}\nsnippet src\n	src="${1}"${2}\nsnippet title=\n	title="${1}"${2}\nsnippet type\n	type="${1}"${2}\nsnippet value\n	value="${1}"${2}\nsnippet width\n	width="${1}"${2}\n# Elements\nsnippet a\n	<a href="${1:#}">${2:$1}</a>\nsnippet a.\n	<a class="${1}" href="${2:#}">${3:$1}</a>\nsnippet a#\n	<a id="${1}" href="${2:#}">${3:$1}</a>\nsnippet a:ext\n	<a href="http://${1:example.com}">${2:$1}</a>\nsnippet a:mail\n	<a href="mailto:${1:joe@example.com}?subject=${2:feedback}">${3:email me}</a>\nsnippet abbr\n	<abbr title="${1}">${2}</abbr>\nsnippet address\n	<address>\n		${1}\n	</address>\nsnippet area\n	<area shape="${1:rect}" coords="${2}" href="${3}" alt="${4}" />\nsnippet area+\n	<area shape="${1:rect}" coords="${2}" href="${3}" alt="${4}" />\n	area+${5}\nsnippet area:c\n	<area shape="circle" coords="${1}" href="${2}" alt="${3}" />\nsnippet area:d\n	<area shape="default" coords="${1}" href="${2}" alt="${3}" />\nsnippet area:p\n	<area shape="poly" coords="${1}" href="${2}" alt="${3}" />\nsnippet area:r\n	<area shape="rect" coords="${1}" href="${2}" alt="${3}" />\nsnippet article\n	<article>\n		${1}\n	</article>\nsnippet article.\n	<article class="${1}">\n		${2}\n	</article>\nsnippet article#\n	<article id="${1}">\n		${2}\n	</article>\nsnippet aside\n	<aside>\n		${1}\n	</aside>\nsnippet aside.\n	<aside class="${1}">\n		${2}\n	</aside>\nsnippet aside#\n	<aside id="${1}">\n		${2}\n	</aside>\nsnippet audio\n	<audio src="${1}>${2}</audio>\nsnippet b\n	<b>${1}</b>\nsnippet base\n	<base href="${1}" target="${2}" />\nsnippet bdi\n	<bdi>${1}</bdo>\nsnippet bdo\n	<bdo dir="${1}">${2}</bdo>\nsnippet bdo:l\n	<bdo dir="ltr">${1}</bdo>\nsnippet bdo:r\n	<bdo dir="rtl">${1}</bdo>\nsnippet blockquote\n	<blockquote>\n		${1}\n	</blockquote>\nsnippet body\n	<body>\n		${1}\n	</body>\nsnippet br\n	<br />${1}\nsnippet button\n	<button type="${1:submit}">${2}</button>\nsnippet button.\n	<button class="${1:button}" type="${2:submit}">${3}</button>\nsnippet button#\n	<button id="${1}" type="${2:submit}">${3}</button>\nsnippet button:s\n	<button type="submit">${1}</button>\nsnippet button:r\n	<button type="reset">${1}</button>\nsnippet canvas\n	<canvas>\n		${1}\n	</canvas>\nsnippet caption\n	<caption>${1}</caption>\nsnippet cite\n	<cite>${1}</cite>\nsnippet code\n	<code>${1}</code>\nsnippet col\n	<col />${1}\nsnippet col+\n	<col />\n	col+${1}\nsnippet colgroup\n	<colgroup>\n		${1}\n	</colgroup>\nsnippet colgroup+\n	<colgroup>\n		<col />\n		col+${1}\n	</colgroup>\nsnippet command\n	<command type="command" label="${1}" icon="${2}" />\nsnippet command:c\n	<command type="checkbox" label="${1}" icon="${2}" />\nsnippet command:r\n	<command type="radio" radiogroup="${1}" label="${2}" icon="${3}" />\nsnippet datagrid\n	<datagrid>\n		${1}\n	</datagrid>\nsnippet datalist\n	<datalist>\n		${1}\n	</datalist>\nsnippet datatemplate\n	<datatemplate>\n		${1}\n	</datatemplate>\nsnippet dd\n	<dd>${1}</dd>\nsnippet dd.\n	<dd class="${1}">${2}</dd>\nsnippet dd#\n	<dd id="${1}">${2}</dd>\nsnippet del\n	<del>${1}</del>\nsnippet details\n	<details>${1}</details>\nsnippet dfn\n	<dfn>${1}</dfn>\nsnippet dialog\n	<dialog>\n		${1}\n	</dialog>\nsnippet div\n	<div>\n		${1}\n	</div>\nsnippet div.\n	<div class="${1}">\n		${2}\n	</div>\nsnippet div#\n	<div id="${1}">\n		${2}\n	</div>\nsnippet dl\n	<dl>\n		${1}\n	</dl>\nsnippet dl.\n	<dl class="${1}">\n		${2}\n	</dl>\nsnippet dl#\n	<dl id="${1}">\n		${2}\n	</dl>\nsnippet dl+\n	<dl>\n		<dt>${1}</dt>\n		<dd>${2}</dd>\n		dt+${3}\n	</dl>\nsnippet dt\n	<dt>${1}</dt>\nsnippet dt.\n	<dt class="${1}">${2}</dt>\nsnippet dt#\n	<dt id="${1}">${2}</dt>\nsnippet dt+\n	<dt>${1}</dt>\n	<dd>${2}</dd>\n	dt+${3}\nsnippet em\n	<em>${1}</em>\nsnippet embed\n	<embed src=${1} type="${2} />\nsnippet fieldset\n	<fieldset>\n		${1}\n	</fieldset>\nsnippet fieldset.\n	<fieldset class="${1}">\n		${2}\n	</fieldset>\nsnippet fieldset#\n	<fieldset id="${1}">\n		${2}\n	</fieldset>\nsnippet fieldset+\n	<fieldset>\n		<legend><span>${1}</span></legend>\n		${2}\n	</fieldset>\n	fieldset+${3}\nsnippet figcaption\n	<figcaption>${1}</figcaption>\nsnippet figure\n	<figure>${1}</figure>\nsnippet footer\n	<footer>\n		${1}\n	</footer>\nsnippet footer.\n	<footer class="${1}">\n		${2}\n	</footer>\nsnippet footer#\n	<footer id="${1}">\n		${2}\n	</footer>\nsnippet form\n	<form action="${1}" method="${2:get}" accept-charset="utf-8">\n		${3}\n	</form>\nsnippet form.\n	<form class="${1}" action="${2}" method="${3:get}" accept-charset="utf-8">\n		${4}\n	</form>\nsnippet form#\n	<form id="${1}" action="${2}" method="${3:get}" accept-charset="utf-8">\n		${4}\n	</form>\nsnippet h1\n	<h1>${1}</h1>\nsnippet h1.\n	<h1 class="${1}">${2}</h1>\nsnippet h1#\n	<h1 id="${1}">${2}</h1>\nsnippet h2\n	<h2>${1}</h2>\nsnippet h2.\n	<h2 class="${1}">${2}</h2>\nsnippet h2#\n	<h2 id="${1}">${2}</h2>\nsnippet h3\n	<h3>${1}</h3>\nsnippet h3.\n	<h3 class="${1}">${2}</h3>\nsnippet h3#\n	<h3 id="${1}">${2}</h3>\nsnippet h4\n	<h4>${1}</h4>\nsnippet h4.\n	<h4 class="${1}">${2}</h4>\nsnippet h4#\n	<h4 id="${1}">${2}</h4>\nsnippet h5\n	<h5>${1}</h5>\nsnippet h5.\n	<h5 class="${1}">${2}</h5>\nsnippet h5#\n	<h5 id="${1}">${2}</h5>\nsnippet h6\n	<h6>${1}</h6>\nsnippet h6.\n	<h6 class="${1}">${2}</h6>\nsnippet h6#\n	<h6 id="${1}">${2}</h6>\nsnippet head\n	<head>\n		<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n\n		<title>${1:`substitute(Filename(\'\', \'Page Title\'), \'^.\', \'\\u&\', \'\')`}</title>\n		${2}\n	</head>\nsnippet header\n	<header>\n		${1}\n	</header>\nsnippet header.\n	<header class="${1}">\n		${2}\n	</header>\nsnippet header#\n	<header id="${1}">\n		${2}\n	</header>\nsnippet hgroup\n	<hgroup>\n		${1}\n	</hgroup>\nsnippet hgroup.\n	<hgroup class="${1}>\n		${2}\n	</hgroup>\nsnippet hr\n	<hr />${1}\nsnippet html\n	<!DOCTYPE html>\n	${1}\n	</html>\nsnippet xhtml\n	<html xmlns="http://www.w3.org/1999/xhtml">\n	${1}\n	</html>\nsnippet html5\n	<!DOCTYPE html>\n	<!DOCTYPE html>\n		<head>\n			<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n			<title>${1:`substitute(Filename(\'\', \'Page Title\'), \'^.\', \'\\u&\', \'\')`}</title>\n			${2:meta}\n		</head>\n		<body>\n			${3:body}\n		</body>\n	</html>\nsnippet i\n	<i>${1}</i>\nsnippet iframe\n	<iframe src="${1}" frameborder="0"></iframe>${2}\nsnippet iframe.\n	<iframe class="${1}" src="${2}" frameborder="0"></iframe>${3}\nsnippet iframe#\n	<iframe id="${1}" src="${2}" frameborder="0"></iframe>${3}\nsnippet img\n	<img src="${1}" alt="${2}" />${3}\nsnippet img.\n	<img class="${1}" src="${2}" alt="${3}" />${4}\nsnippet img#\n	<img id="${1}" src="${2}" alt="${3}" />${4}\nsnippet input\n	<input type="${1:text/submit/hidden/button/image}" name="${2}" id="${3:$2}" value="${4}" />${5}\nsnippet input.\n	<input class="${1}" type="${2:text/submit/hidden/button/image}" name="${3}" id="${4:$3}" value="${5}" />${6}\nsnippet input:text\n	<input type="text" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:submit\n	<input type="submit" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:hidden\n	<input type="hidden" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:button\n	<input type="button" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:image\n	<input type="image" name="${1}" id="${2:$1}" src="${3}" alt="${4}" />${5}\nsnippet input:checkbox\n	<input type="checkbox" name="${1}" id="${2:$1}" />${3}\nsnippet input:radio\n	<input type="radio" name="${1}" id="${2:$1}" />${3}\nsnippet input:color\n	<input type="color" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:date\n	<input type="date" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:datetime\n	<input type="datetime" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:datetime-local\n	<input type="datetime-local" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:email\n	<input type="email" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:file\n	<input type="file" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:month\n	<input type="month" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:number\n	<input type="number" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:password\n	<input type="password" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:range\n	<input type="range" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:reset\n	<input type="reset" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:search\n	<input type="search" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:time\n	<input type="time" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:url\n	<input type="url" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet input:week\n	<input type="week" name="${1}" id="${2:$1}" value="${3}" />${4}\nsnippet ins\n	<ins>${1}</ins>\nsnippet kbd\n	<kbd>${1}</kbd>\nsnippet keygen\n	<keygen>${1}</keygen>\nsnippet label\n	<label for="${2:$1}">${1}</label>\nsnippet label:i\n	<label for="${2:$1}">${1}</label>\n	<input type="${3:text/submit/hidden/button}" name="${4:$2}" id="${5:$2}" value="${6}" />${7}\nsnippet label:s\n	<label for="${2:$1}">${1}</label>\n	<select name="${3:$2}" id="${4:$2}">\n		<option value="${5}">${6:$5}</option>\n	</select>\nsnippet legend\n	<legend>${1}</legend>\nsnippet legend+\n	<legend><span>${1}</span></legend>\nsnippet li\n	<li>${1}</li>\nsnippet li.\n	<li class="${1}">${2}</li>\nsnippet li+\n	<li>${1}</li>\n	li+${2}\nsnippet lia\n	<li><a href="${2:#}">${1}</a></li>\nsnippet lia+\n	<li><a href="${2:#}">${1}</a></li>\n	lia+${3}\nsnippet link\n	<link rel="${1}" href="${2}" title="${3}" type="${4}" />${5}\nsnippet link:atom\n	<link rel="alternate" href="${1:atom.xml}" title="Atom" type="application/atom+xml" />${2}\nsnippet link:css\n	<link rel="stylesheet" href="${2:style.css}" type="text/css" media="${3:all}" />${4}\nsnippet link:favicon\n	<link rel="shortcut icon" href="${1:favicon.ico}" type="image/x-icon" />${2}\nsnippet link:rss\n	<link rel="alternate" href="${1:rss.xml}" title="RSS" type="application/atom+xml" />${2}\nsnippet link:touch\n	<link rel="apple-touch-icon" href="${1:favicon.png}" />${2}\nsnippet map\n	<map name="${1}">\n		${2}\n	</map>\nsnippet map.\n	<map class="${1}" name="${2}">\n		${3}\n	</map>\nsnippet map#\n	<map name="${1}" id="${2:$1}>\n		${3}\n	</map>\nsnippet map+\n	<map name="${1}">\n		<area shape="${2}" coords="${3}" href="${4}" alt="${5}" />${6}\n	</map>${7}\nsnippet mark\n	<mark>${1}</mark>\nsnippet menu\n	<menu>\n		${1}\n	</menu>\nsnippet menu:c\n	<menu type="context">\n		${1}\n	</menu>\nsnippet menu:t\n	<menu type="toolbar">\n		${1}\n	</menu>\nsnippet meta\n	<meta http-equiv="${1}" content="${2}" />${3}\nsnippet meta:compat\n	<meta http-equiv="X-UA-Compatible" content="IE=${1:7,8,edge}" />${3}\nsnippet meta:refresh\n	<meta http-equiv="refresh" content="text/html;charset=UTF-8" />${3}\nsnippet meta:utf\n	<meta http-equiv="content-type" content="text/html;charset=UTF-8" />${3}\nsnippet meter\n	<meter>${1}</meter>\nsnippet nav\n	<nav>\n		${1}\n	</nav>\nsnippet nav.\n	<nav class="${1}">\n		${2}\n	</nav>\nsnippet nav#\n	<nav id="${1}">\n		${2}\n	</nav>\nsnippet noscript\n	<noscript>\n		${1}\n	</noscript>\nsnippet object\n	<object data="${1}" type="${2}">\n		${3}\n	</object>${4}\n# Embed QT Movie\nsnippet movie\n	<object width="$2" height="$3" classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"\n	 codebase="http://www.apple.com/qtactivex/qtplugin.cab">\n		<param name="src" value="$1" />\n		<param name="controller" value="$4" />\n		<param name="autoplay" value="$5" />\n		<embed src="${1:movie.mov}"\n			width="${2:320}" height="${3:240}"\n			controller="${4:true}" autoplay="${5:true}"\n			scale="tofit" cache="true"\n			pluginspage="http://www.apple.com/quicktime/download/" />\n	</object>${6}\nsnippet ol\n	<ol>\n		${1}\n	</ol>\nsnippet ol.\n	<ol class="${1}>\n		${2}\n	</ol>\nsnippet ol#\n	<ol id="${1}>\n		${2}\n	</ol>\nsnippet ol+\n	<ol>\n		<li>${1}</li>\n		li+${2}\n	</ol>\nsnippet opt\n	<option value="${1}">${2:$1}</option>\nsnippet opt+\n	<option value="${1}">${2:$1}</option>\n	opt+${3}\nsnippet optt\n	<option>${1}</option>\nsnippet optgroup\n	<optgroup>\n		<option value="${1}">${2:$1}</option>\n		opt+${3}\n	</optgroup>\nsnippet output\n	<output>${1}</output>\nsnippet p\n	<p>${1}</p>\nsnippet param\n	<param name="${1}" value="${2}" />${3}\nsnippet pre\n	<pre>\n		${1}\n	</pre>\nsnippet progress\n	<progress>${1}</progress>\nsnippet q\n	<q>${1}</q>\nsnippet rp\n	<rp>${1}</rp>\nsnippet rt\n	<rt>${1}</rt>\nsnippet ruby\n	<ruby>\n		<rp><rt>${1}</rt></rp>\n	</ruby>\nsnippet s\n	<s>${1}</s>\nsnippet samp\n	<samp>\n		${1}\n	</samp>\nsnippet script\n	<script type="text/javascript" charset="utf-8">\n		${1}\n	<\/script>\nsnippet scriptsrc\n	<script src="${1}.js" type="text/javascript" charset="utf-8"><\/script>\nsnippet section\n	<section>\n		${1}\n	</main>\nsnippet section.\n	<main class="${1}">\n		${2}\n	</main>\nsnippet section#\n	<main id="${1}">\n		${2}\n	</main>\nsnippet select\n	<select name="${1}" id="${2:$1}">\n		${3}\n	</select>\nsnippet select.\n	<select name="${1}" id="${2:$1}" class="${3}>\n		${4}\n	</select>\nsnippet select+\n	<select name="${1}" id="${2:$1}">\n		<option value="${3}">${4:$3}</option>\n		opt+${5}\n	</select>\nsnippet small\n	<small>${1}</small>\nsnippet source\n	<source src="${1}" type="${2}" media="${3}" />\nsnippet span\n	<span>${1}</span>\nsnippet strong\n	<strong>${1}</strong>\nsnippet style\n	<style type="text/css" media="${1:all}">\n		${2}\n	</style>\nsnippet sub\n	<sub>${1}</sub>\nsnippet summary\n	<summary>\n		${1}\n	</summary>\nsnippet sup\n	<sup>${1}</sup>\nsnippet table\n	<table border="${1:0}">\n		${2}\n	</table>\nsnippet table.\n	<table class="${1}" border="${2:0}">\n		${3}\n	</table>\nsnippet table#\n	<table id="${1}" border="${2:0}">\n		${3}\n	</table>\nsnippet tbody\n	<tbody>\n		${1}\n	</tbody>\nsnippet td\n	<td>${1}</td>\nsnippet td.\n	<td class="${1}">${2}</td>\nsnippet td#\n	<td id="${1}">${2}</td>\nsnippet td+\n	<td>${1}</td>\n	td+${2}\nsnippet textarea\n	<textarea name="${1}" id=${2:$1} rows="${3:8}" cols="${4:40}">${5}</textarea>${6}\nsnippet tfoot\n	<tfoot>\n		${1}\n	</tfoot>\nsnippet th\n	<th>${1}</th>\nsnippet th.\n	<th class="${1}">${2}</th>\nsnippet th#\n	<th id="${1}">${2}</th>\nsnippet th+\n	<th>${1}</th>\n	th+${2}\nsnippet thead\n	<thead>\n		${1}\n	</thead>\nsnippet time\n	<time datetime="${1}" pubdate="${2:$1}>${3:$1}</time>\nsnippet title\n	<title>${1:`substitute(Filename(\'\', \'Page Title\'), \'^.\', \'\\u&\', \'\')`}</title>\nsnippet tr\n	<tr>\n		${1}\n	</tr>\nsnippet tr+\n	<tr>\n		<td>${1}</td>\n		td+${2}\n	</tr>\nsnippet track\n	<track src="${1}" srclang="${2}" label="${3}" default="${4:default}>${5}</track>${6}\nsnippet ul\n	<ul>\n		${1}\n	</ul>\nsnippet ul.\n	<ul class="${1}">\n		${2}\n	</ul>\nsnippet ul#\n	<ul id="${1}">\n		${2}\n	</ul>\nsnippet ul+\n	<ul>\n		<li>${1}</li>\n		li+${2}\n	</ul>\nsnippet var\n	<var>${1}</var>\nsnippet video\n	<video src="${1} height="${2}" width="${3}" preload="${5:none}" autoplay="${6:autoplay}>${7}</video>${8}\nsnippet wbr\n	<wbr />${1}\n',t.scope="html"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/html_ruby.js b/dist/assets/js/vendor/ace-nc/snippets/html_ruby.js
            new file mode 100644
            index 0000000000..4ed2cd912b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/html_ruby.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/html_ruby",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="html_ruby"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/ini.js b/dist/assets/js/vendor/ace-nc/snippets/ini.js
            new file mode 100644
            index 0000000000..f520b9bed7
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/ini.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/ini",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="ini"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/jack.js b/dist/assets/js/vendor/ace-nc/snippets/jack.js
            new file mode 100644
            index 0000000000..99b0ebd5b5
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/jack.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/jack",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="jack"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/jade.js b/dist/assets/js/vendor/ace-nc/snippets/jade.js
            new file mode 100644
            index 0000000000..bbd1087fb7
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/jade.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/jade",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="jade"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/java.js b/dist/assets/js/vendor/ace-nc/snippets/java.js
            new file mode 100644
            index 0000000000..e00063ee24
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/java.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/java",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='## Access Modifiers\nsnippet po\n	protected\nsnippet pu\n	public\nsnippet pr\n	private\n##\n## Annotations\nsnippet before\n	@Before\n	static void ${1:intercept}(${2:args}) { ${3} }\nsnippet mm\n	@ManyToMany\n	${1}\nsnippet mo\n	@ManyToOne\n	${1}\nsnippet om\n	@OneToMany${1:(cascade=CascadeType.ALL)}\n	${2}\nsnippet oo\n	@OneToOne\n	${1}\n##\n## Basic Java packages and import\nsnippet im\n	import\nsnippet j.b\n	java.beans.\nsnippet j.i\n	java.io.\nsnippet j.m\n	java.math.\nsnippet j.n\n	java.net.\nsnippet j.u\n	java.util.\n##\n## Class\nsnippet cl\n	class ${1:`Filename("", "untitled")`} ${2}\nsnippet in\n	interface ${1:`Filename("", "untitled")`} ${2:extends Parent}${3}\nsnippet tc\n	public class ${1:`Filename()`} extends ${2:TestCase}\n##\n## Class Enhancements\nsnippet ext\n	extends \nsnippet imp\n	implements\n##\n## Comments\nsnippet /*\n##\n## Constants\nsnippet co\n	static public final ${1:String} ${2:var} = ${3};${4}\nsnippet cos\n	static public final String ${1:var} = "${2}";${3}\n##\n## Control Statements\nsnippet case\n	case ${1}:\n		${2}\nsnippet def\n	default:\n		${2}\nsnippet el\n	else\nsnippet elif\n	else if (${1}) ${2}\nsnippet if\n	if (${1}) ${2}\nsnippet sw\n	switch (${1}) {\n		${2}\n	}\n##\n## Create a Method\nsnippet m\n	${1:void} ${2:method}(${3}) ${4:throws }${5}\n##\n## Create a Variable\nsnippet v\n	${1:String} ${2:var}${3: = null}${4};${5}\n##\n## Enhancements to Methods, variables, classes, etc.\nsnippet ab\n	abstract\nsnippet fi\n	final\nsnippet st\n	static\nsnippet sy\n	synchronized\n##\n## Error Methods\nsnippet err\n	System.err.print("${1:Message}");\nsnippet errf\n	System.err.printf("${1:Message}", ${2:exception});\nsnippet errln\n	System.err.println("${1:Message}");\n##\n## Exception Handling\nsnippet as\n	assert ${1:test} : "${2:Failure message}";${3}\nsnippet ca\n	catch(${1:Exception} ${2:e}) ${3}\nsnippet thr\n	throw\nsnippet ths\n	throws\nsnippet try\n	try {\n		${3}\n	} catch(${1:Exception} ${2:e}) {\n	}\nsnippet tryf\n	try {\n		${3}\n	} catch(${1:Exception} ${2:e}) {\n	} finally {\n	}\n##\n## Find Methods\nsnippet findall\n	List<${1:listName}> ${2:items} = ${1}.findAll();${3}\nsnippet findbyid\n	${1:var} ${2:item} = ${1}.findById(${3});${4}\n##\n## Javadocs\nsnippet /**\nsnippet @au\n	@author `system("grep \\`id -un\\` /etc/passwd | cut -d \\":\\" -f5 | cut -d \\",\\" -f1")`\nsnippet @br\n	@brief ${1:Description}\nsnippet @fi\n	@file ${1:`Filename()`}.java\nsnippet @pa\n	@param ${1:param}\nsnippet @re\n	@return ${1:param}\n##\n## Logger Methods\nsnippet debug\n	Logger.debug(${1:param});${2}\nsnippet error\n	Logger.error(${1:param});${2}\nsnippet info\n	Logger.info(${1:param});${2}\nsnippet warn\n	Logger.warn(${1:param});${2}\n##\n## Loops\nsnippet enfor\n	for (${1} : ${2}) ${3}\nsnippet for\n	for (${1}; ${2}; ${3}) ${4}\nsnippet wh\n	while (${1}) ${2}\n##\n## Main method\nsnippet main\n	public static void main (String[] args) {\n		${1:/* code */}\n	}\n##\n## Print Methods\nsnippet print\n	System.out.print("${1:Message}");\nsnippet printf\n	System.out.printf("${1:Message}", ${2:args});\nsnippet println\n	System.out.println(${1});\n##\n## Render Methods\nsnippet ren\n	render(${1:param});${2}\nsnippet rena\n	renderArgs.put("${1}", ${2});${3}\nsnippet renb\n	renderBinary(${1:param});${2}\nsnippet renj\n	renderJSON(${1:param});${2}\nsnippet renx\n	renderXml(${1:param});${2}\n##\n## Setter and Getter Methods\nsnippet set\n	${1:public} void set${3:}(${2:String} ${4:}){\n		this.$4 = $4;\n	}\nsnippet get\n	${1:public} ${2:String} get${3:}(){\n		return this.${4:};\n	}\n##\n## Terminate Methods or Loops\nsnippet re\n	return\nsnippet br\n	break;\n##\n## Test Methods\nsnippet t\n	public void test${1:Name}() throws Exception {\n		${2}\n	}\nsnippet test\n	@Test\n	public void test${1:Name}() throws Exception {\n		${2}\n	}\n##\n## Utils\nsnippet Sc\n	Scanner\n##\n## Miscellaneous\nsnippet action\n	public static void ${1:index}(${2:args}) { ${3} }\nsnippet rnf\n	notFound(${1:param});${2}\nsnippet rnfin\n	notFoundIfNull(${1:param});${2}\nsnippet rr\n	redirect(${1:param});${2}\nsnippet ru\n	unauthorized(${1:param});${2}\nsnippet unless\n	(unless=${1:param});${2}\n',t.scope="java"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/javascript.js b/dist/assets/js/vendor/ace-nc/snippets/javascript.js
            new file mode 100644
            index 0000000000..6e1fc6af0c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/javascript.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/javascript",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# Prototype\nsnippet proto\n	${1:class_name}.prototype.${2:method_name} = function(${3:first_argument}) {\n		${4:// body...}\n	};\n# Function\nsnippet fun\n	function ${1?:function_name}(${2:argument}) {\n		${3:// body...}\n	}\n# Anonymous Function\nregex /((=)\\s*|(:)\\s*|(\\()|\\b)/f/(\\))?/\nsnippet f\n	function${M1?: ${1:functionName}}($2) {\n		${0:$TM_SELECTED_TEXT}\n	}${M2?;}${M3?,}${M4?)}\n# Immediate function\ntrigger \\(?f\\(\nendTrigger \\)?\nsnippet f(\n	(function(${1}) {\n		${0:${TM_SELECTED_TEXT:/* code */}}\n	}(${1}));\n# if\nsnippet if\n	if (${1:true}) {\n		${0}\n	}\n# if ... else\nsnippet ife\n	if (${1:true}) {\n		${2}\n	} else {\n		${0}\n	}\n# tertiary conditional\nsnippet ter\n	${1:/* condition */} ? ${2:a} : ${3:b}\n# switch\nsnippet switch\n	switch (${1:expression}) {\n		case \'${3:case}\':\n			${4:// code}\n			break;\n		${5}\n		default:\n			${2:// code}\n	}\n# case\nsnippet case\n	case \'${1:case}\':\n		${2:// code}\n		break;\n	${3}\n\n# while (...) {...}\nsnippet wh\n	while (${1:/* condition */}) {\n		${0:/* code */}\n	}\n# try\nsnippet try\n	try {\n		${0:/* code */}\n	} catch (e) {}\n# do...while\nsnippet do\n	do {\n		${2:/* code */}\n	} while (${1:/* condition */});\n# Object Method\nsnippet :f\nregex /([,{[])|^\\s*/:f/\n	${1:method_name}: function(${2:attribute}) {\n		${0}\n	}${3:,}\n# setTimeout function\nsnippet setTimeout\nregex /\\b/st|timeout|setTimeo?u?t?/\n	setTimeout(function() {${3:$TM_SELECTED_TEXT}}, ${1:10});\n# Get Elements\nsnippet gett\n	getElementsBy${1:TagName}(\'${2}\')${3}\n# Get Element\nsnippet get\n	getElementBy${1:Id}(\'${2}\')${3}\n# console.log (Firebug)\nsnippet cl\n	console.log(${1});\n# return\nsnippet ret\n	return ${1:result}\n# for (property in object ) { ... }\nsnippet fori\n	for (var ${1:prop} in ${2:Things}) {\n		${0:$2[$1]}\n	}\n# hasOwnProperty\nsnippet has\n	hasOwnProperty(${1})\n# docstring\nsnippet /**\nsnippet @par\nregex /^\\s*\\*\\s*/@(para?m?)?/\n	@param {${1:type}} ${2:name} ${3:description}\nsnippet @ret\n	@return {${1:type}} ${2:description}\n# JSON.parse\nsnippet jsonp\n	JSON.parse(${1:jstr});\n# JSON.stringify\nsnippet jsons\n	JSON.stringify(${1:object});\n# self-defining function\nsnippet sdf\n	var ${1:function_name} = function(${2:argument}) {\n		${3:// initial code ...}\n\n		$1 = function($2) {\n			${4:// main code}\n		};\n	}\n# singleton\nsnippet sing\n	function ${1:Singleton} (${2:argument}) {\n		var instance;\n		$1 = function $1($2) {\n			return instance;\n		};\n		$1.prototype = this;\n		instance = new $1();\n		instance.constructor = $1;\n\n		${3:// code ...}\n\n		return instance;\n	}\n# class\nsnippet class\nregex /^\\s*/clas{0,2}/\n	var ${1:class} = function(${20}) {\n		$40$0\n	};\n	\n	(function() {\n		${60:this.prop = ""}\n	}).call(${1:class}.prototype);\n	\n	exports.${1:class} = ${1:class};\n# \nsnippet for-\n	for (var ${1:i} = ${2:Things}.length; ${1:i}--; ) {\n		${0:${2:Things}[${1:i}];}\n	}\n# for (...) {...}\nsnippet for\n	for (var ${1:i} = 0; $1 < ${2:Things}.length; $1++) {\n		${3:$2[$1]}$0\n	}\n# for (...) {...} (Improved Native For-Loop)\nsnippet forr\n	for (var ${1:i} = ${2:Things}.length - 1; $1 >= 0; $1--) {\n		${3:$2[$1]}$0\n	}\n\n\n#modules\nsnippet def\n	ace.define(function(require, exports, module) {\n	"use strict";\n	var ${1/.*\\///} = require("${1}");\n	\n	$TM_SELECTED_TEXT\n	});\nsnippet req\nguard ^\\s*\n	var ${1/.*\\///} = require("${1}");\n	$0\nsnippet requ\nguard ^\\s*\n	var ${1/.*\\/(.)/\\u$1/} = require("${1}").${1/.*\\/(.)/\\u$1/};\n	$0\n',t.scope="javascript"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/json.js b/dist/assets/js/vendor/ace-nc/snippets/json.js
            new file mode 100644
            index 0000000000..5e0e0ea2eb
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/json.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/json",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="json"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/jsoniq.js b/dist/assets/js/vendor/ace-nc/snippets/jsoniq.js
            new file mode 100644
            index 0000000000..7ca20f9d4a
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/jsoniq.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/jsoniq",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet for\n	for $${1:item} in ${2:expr}\nsnippet return\n	return ${1:expr}\nsnippet import\n	import module namespace ${1:ns} = "${2:http://www.example.com/}";\nsnippet some\n	some $${1:varname} in ${2:expr} satisfies ${3:expr}\nsnippet every\n	every $${1:varname} in ${2:expr} satisfies ${3:expr}\nsnippet if\n	if(${1:true}) then ${2:expr} else ${3:true}\nsnippet switch\n	switch(${1:"foo"})\n	case ${2:"foo"}\n	return ${3:true}\n	default return ${4:false}\nsnippet try\n	try { ${1:expr} } catch ${2:*} { ${3:expr} }\nsnippet tumbling\n	for tumbling window $${1:varname} in ${2:expr}\n	start at $${3:start} when ${4:expr}\n	end at $${5:end} when ${6:expr}\n	return ${7:expr}\nsnippet sliding\n	for sliding window $${1:varname} in ${2:expr}\n	start at $${3:start} when ${4:expr}\n	end at $${5:end} when ${6:expr}\n	return ${7:expr}\nsnippet let\n	let $${1:varname} := ${2:expr}\nsnippet group\n	group by $${1:varname} := ${2:expr}\nsnippet order\n	order by ${1:expr} ${2:descending}\nsnippet stable\n	stable order by ${1:expr}\nsnippet count\n	count $${1:varname}\nsnippet ordered\n	ordered { ${1:expr} }\nsnippet unordered\n	unordered { ${1:expr} }\nsnippet treat \n	treat as ${1:expr}\nsnippet castable\n	castable as ${1:atomicType}\nsnippet cast\n	cast as ${1:atomicType}\nsnippet typeswitch\n	typeswitch(${1:expr})\n	case ${2:type}  return ${3:expr}\n	default return ${4:expr}\nsnippet var\n	declare variable $${1:varname} := ${2:expr};\nsnippet fn\n	declare function ${1:ns}:${2:name}(){\n	${3:expr}\n	};\nsnippet module\n	module namespace ${1:ns} = "${2:http://www.example.com}";\n',t.scope="jsoniq"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/jsp.js b/dist/assets/js/vendor/ace-nc/snippets/jsp.js
            new file mode 100644
            index 0000000000..fcbace719a
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/jsp.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/jsp",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet @page\n	<%@page contentType="text/html" pageEncoding="UTF-8"%>\nsnippet jstl\n	<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>\n	<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>\nsnippet jstl:c\n	<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>\nsnippet jstl:fn\n	<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>\nsnippet cpath\n	${pageContext.request.contextPath}\nsnippet cout\n	<c:out value="${1}" default="${2}" />\nsnippet cset\n	<c:set var="${1}" value="${2}" />\nsnippet cremove\n	<c:remove var="${1}" scope="${2:page}" />\nsnippet ccatch\n	<c:catch var="${1}" />\nsnippet cif\n	<c:if test="${${1}}">\n		${2}\n	</c:if>\nsnippet cchoose\n	<c:choose>\n		${1}\n	</c:choose>\nsnippet cwhen\n	<c:when test="${${1}}">\n		${2}\n	</c:when>\nsnippet cother\n	<c:otherwise>\n		${1}\n	</c:otherwise>\nsnippet cfore\n	<c:forEach items="${${1}}" var="${2}" varStatus="${3}">\n		${4:<c:out value="$2" />}\n	</c:forEach>\nsnippet cfort\n	<c:set var="${1}">${2:item1,item2,item3}</c:set>\n	<c:forTokens var="${3}" items="${$1}" delims="${4:,}">\n		${5:<c:out value="$3" />}\n	</c:forTokens>\nsnippet cparam\n	<c:param name="${1}" value="${2}" />\nsnippet cparam+\n	<c:param name="${1}" value="${2}" />\n	cparam+${3}\nsnippet cimport\n	<c:import url="${1}" />\nsnippet cimport+\n	<c:import url="${1}">\n		<c:param name="${2}" value="${3}" />\n		cparam+${4}\n	</c:import>\nsnippet curl\n	<c:url value="${1}" var="${2}" />\n	<a href="${$2}">${3}</a>\nsnippet curl+\n	<c:url value="${1}" var="${2}">\n		<c:param name="${4}" value="${5}" />\n		cparam+${6}\n	</c:url>\n	<a href="${$2}">${3}</a>\nsnippet credirect\n	<c:redirect url="${1}" />\nsnippet contains\n	${fn:contains(${1:string}, ${2:substr})}\nsnippet contains:i\n	${fn:containsIgnoreCase(${1:string}, ${2:substr})}\nsnippet endswith\n	${fn:endsWith(${1:string}, ${2:suffix})}\nsnippet escape\n	${fn:escapeXml(${1:string})}\nsnippet indexof\n	${fn:indexOf(${1:string}, ${2:substr})}\nsnippet join\n	${fn:join(${1:collection}, ${2:delims})}\nsnippet length\n	${fn:length(${1:collection_or_string})}\nsnippet replace\n	${fn:replace(${1:string}, ${2:substr}, ${3:replace})}\nsnippet split\n	${fn:split(${1:string}, ${2:delims})}\nsnippet startswith\n	${fn:startsWith(${1:string}, ${2:prefix})}\nsnippet substr\n	${fn:substring(${1:string}, ${2:begin}, ${3:end})}\nsnippet substr:a\n	${fn:substringAfter(${1:string}, ${2:substr})}\nsnippet substr:b\n	${fn:substringBefore(${1:string}, ${2:substr})}\nsnippet lc\n	${fn:toLowerCase(${1:string})}\nsnippet uc\n	${fn:toUpperCase(${1:string})}\nsnippet trim\n	${fn:trim(${1:string})}\n',t.scope="jsp"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/jsx.js b/dist/assets/js/vendor/ace-nc/snippets/jsx.js
            new file mode 100644
            index 0000000000..9ae1382f47
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/jsx.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/jsx",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="jsx"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/julia.js b/dist/assets/js/vendor/ace-nc/snippets/julia.js
            new file mode 100644
            index 0000000000..131783f292
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/julia.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/julia",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="julia"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/latex.js b/dist/assets/js/vendor/ace-nc/snippets/latex.js
            new file mode 100644
            index 0000000000..43f3fdbf7b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/latex.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/latex",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="latex"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/less.js b/dist/assets/js/vendor/ace-nc/snippets/less.js
            new file mode 100644
            index 0000000000..4e2cafcd33
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/less.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/less",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="less"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/liquid.js b/dist/assets/js/vendor/ace-nc/snippets/liquid.js
            new file mode 100644
            index 0000000000..a57996395c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/liquid.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/liquid",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="liquid"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/lisp.js b/dist/assets/js/vendor/ace-nc/snippets/lisp.js
            new file mode 100644
            index 0000000000..7c3fd308ef
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/lisp.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/lisp",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="lisp"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/livescript.js b/dist/assets/js/vendor/ace-nc/snippets/livescript.js
            new file mode 100644
            index 0000000000..7ca405642e
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/livescript.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/livescript",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="livescript"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/logiql.js b/dist/assets/js/vendor/ace-nc/snippets/logiql.js
            new file mode 100644
            index 0000000000..c4f097549b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/logiql.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/logiql",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="logiql"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/lsl.js b/dist/assets/js/vendor/ace-nc/snippets/lsl.js
            new file mode 100644
            index 0000000000..859727a17c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/lsl.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/lsl",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet @\n	@${1:label};\nsnippet CAMERA_ACTIVE\n	CAMERA_ACTIVE, ${1:integer isActive}, $0\nsnippet CAMERA_BEHINDNESS_ANGLE\n	CAMERA_BEHINDNESS_ANGLE, ${1:float degrees}, $0\nsnippet CAMERA_BEHINDNESS_LAG\n	CAMERA_BEHINDNESS_LAG, ${1:float seconds}, $0\nsnippet CAMERA_DISTANCE\n	CAMERA_DISTANCE, ${1:float meters}, $0\nsnippet CAMERA_FOCUS\n	CAMERA_FOCUS, ${1:vector position}, $0\nsnippet CAMERA_FOCUS_LAG\n	CAMERA_FOCUS_LAG, ${1:float seconds}, $0\nsnippet CAMERA_FOCUS_LOCKED\n	CAMERA_FOCUS_LOCKED, ${1:integer isLocked}, $0\nsnippet CAMERA_FOCUS_OFFSET\n	CAMERA_FOCUS_OFFSET, ${1:vector meters}, $0\nsnippet CAMERA_FOCUS_THRESHOLD\n	CAMERA_FOCUS_THRESHOLD, ${1:float meters}, $0\nsnippet CAMERA_PITCH\n	CAMERA_PITCH, ${1:float degrees}, $0\nsnippet CAMERA_POSITION\n	CAMERA_POSITION, ${1:vector position}, $0\nsnippet CAMERA_POSITION_LAG\n	CAMERA_POSITION_LAG, ${1:float seconds}, $0\nsnippet CAMERA_POSITION_LOCKED\n	CAMERA_POSITION_LOCKED, ${1:integer isLocked}, $0\nsnippet CAMERA_POSITION_THRESHOLD\n	CAMERA_POSITION_THRESHOLD, ${1:float meters}, $0\nsnippet CHARACTER_AVOIDANCE_MODE\n	CHARACTER_AVOIDANCE_MODE, ${1:integer flags}, $0\nsnippet CHARACTER_DESIRED_SPEED\n	CHARACTER_DESIRED_SPEED, ${1:float speed}, $0\nsnippet CHARACTER_DESIRED_TURN_SPEED\n	CHARACTER_DESIRED_TURN_SPEED, ${1:float speed}, $0\nsnippet CHARACTER_LENGTH\n	CHARACTER_LENGTH, ${1:float length}, $0\nsnippet CHARACTER_MAX_TURN_RADIUS\n	CHARACTER_MAX_TURN_RADIUS, ${1:float radius}, $0\nsnippet CHARACTER_ORIENTATION\n	CHARACTER_ORIENTATION, ${1:integer orientation}, $0\nsnippet CHARACTER_RADIUS\n	CHARACTER_RADIUS, ${1:float radius}, $0\nsnippet CHARACTER_STAY_WITHIN_PARCEL\n	CHARACTER_STAY_WITHIN_PARCEL, ${1:boolean stay}, $0\nsnippet CHARACTER_TYPE\n	CHARACTER_TYPE, ${1:integer type}, $0\nsnippet HTTP_BODY_MAXLENGTH\n	HTTP_BODY_MAXLENGTH, ${1:integer length}, $0\nsnippet HTTP_CUSTOM_HEADER\n	HTTP_CUSTOM_HEADER, ${1:string name}, ${2:string value}, $0\nsnippet HTTP_METHOD\n	HTTP_METHOD, ${1:string method}, $0\nsnippet HTTP_MIMETYPE\n	HTTP_MIMETYPE, ${1:string mimeType}, $0\nsnippet HTTP_PRAGMA_NO_CACHE\n	HTTP_PRAGMA_NO_CACHE, ${1:integer send_header}, $0\nsnippet HTTP_VERBOSE_THROTTLE\n	HTTP_VERBOSE_THROTTLE, ${1:integer noisy}, $0\nsnippet HTTP_VERIFY_CERT\n	HTTP_VERIFY_CERT, ${1:integer verify}, $0\nsnippet RC_DATA_FLAGS\n	RC_DATA_FLAGS, ${1:integer flags}, $0\nsnippet RC_DETECT_PHANTOM\n	RC_DETECT_PHANTOM, ${1:integer dectedPhantom}, $0\nsnippet RC_MAX_HITS\n	RC_MAX_HITS, ${1:integer maxHits}, $0\nsnippet RC_REJECT_TYPES\n	RC_REJECT_TYPES, ${1:integer filterMask}, $0\nsnippet at_rot_target\n	at_rot_target(${1:integer handle}, ${2:rotation targetrot}, ${3:rotation ourrot})\n	{\n		$0\n	}\nsnippet at_target\n	at_target(${1:integer tnum}, ${2:vector targetpos}, ${3:vector ourpos})\n	{\n		$0\n	}\nsnippet attach\n	attach(${1:key id})\n	{\n		$0\n	}\nsnippet changed\n	changed(${1:integer change})\n	{\n		$0\n	}\nsnippet collision\n	collision(${1:integer index})\n	{\n		$0\n	}\nsnippet collision_end\n	collision_end(${1:integer index})\n	{\n		$0\n	}\nsnippet collision_start\n	collision_start(${1:integer index})\n	{\n		$0\n	}\nsnippet control\n	control(${1:key id}, ${2:integer level}, ${3:integer edge})\n	{\n		$0\n	}\nsnippet dataserver\n	dataserver(${1:key query_id}, ${2:string data})\n	{\n		$0\n	}\nsnippet do\n	do\n	{\n		$0\n	}\n	while (${1:condition});\nsnippet else\n	else\n	{\n		$0\n	}\nsnippet email\n	email(${1:string time}, ${2:string address}, ${3:string subject}, ${4:string message}, ${5:integer num_left})\n	{\n		$0\n	}\nsnippet for\n	for (${1:start}; ${3:condition}; ${3:step})\n	{\n		$0\n	}\nsnippet http_request\n	http_request(${1:key request_id}, ${2:string method}, ${3:string body})\n	{\n		$0\n	}\nsnippet http_response\n	http_response(${1:key request_id}, ${2:integer status}, ${3:list metadata}, ${4:string body})\n	{\n		$0\n	}\nsnippet if\n	if (${1:condition})\n	{\n		$0\n	}\nsnippet jump\n	jump ${1:label};\nsnippet land_collision\n	land_collision(${1:vector pos})\n	{\n		$0\n	}\nsnippet land_collision_end\n	land_collision_end(${1:vector pos})\n	{\n		$0\n	}\nsnippet land_collision_start\n	land_collision_start(${1:vector pos})\n	{\n		$0\n	}\nsnippet link_message\n	link_message(${1:integer sender_num}, ${2:integer num}, ${3:string str}, ${4:key id})\n	{\n		$0\n	}\nsnippet listen\n	listen(${1:integer channel}, ${2:string name}, ${3:key id}, ${4:string message})\n	{\n		$0\n	}\nsnippet llAbs\n	llAbs(${1:integer val})\nsnippet llAcos\n	llAcos(${1:float val})\nsnippet llAddToLandBanList\n	llAddToLandBanList(${1:key agent}, ${2:float hours});\nsnippet llAddToLandPassList\n	llAddToLandPassList(${1:key agent}, ${2:float hours});\nsnippet llAdjustSoundVolume\n	llAdjustSoundVolume(${1:float volume});\nsnippet llAllowInventoryDrop\n	llAllowInventoryDrop(${1:integer add});\nsnippet llAngleBetween\n	llAngleBetween(${1:rotation a}, ${2:rotation b})\nsnippet llApplyImpulse\n	llApplyImpulse(${1:vector force}, ${2:integer local});\nsnippet llApplyRotationalImpulse\n	llApplyRotationalImpulse(${1:vector force}, ${2:integer local});\nsnippet llAsin\n	llAsin(${1:float val})\nsnippet llAtan2\n	llAtan2(${1:float y}, ${2:float x})\nsnippet llAttachToAvatar\n	llAttachToAvatar(${1:integer attach_point});\nsnippet llAttachToAvatarTemp\n	llAttachToAvatarTemp(${1:integer attach_point});\nsnippet llAvatarOnLinkSitTarget\n	llAvatarOnLinkSitTarget(${1:integer link})\nsnippet llAvatarOnSitTarget\n	llAvatarOnSitTarget()\nsnippet llAxes2Rot\n	llAxes2Rot(${1:vector fwd}, ${2:vector left}, ${3:vector up})\nsnippet llAxisAngle2Rot\n	llAxisAngle2Rot(${1:vector axis}, ${2:float angle})\nsnippet llBase64ToInteger\n	llBase64ToInteger(${1:string str})\nsnippet llBase64ToString\n	llBase64ToString(${1:string str})\nsnippet llBreakAllLinks\n	llBreakAllLinks();\nsnippet llBreakLink\n	llBreakLink(${1:integer link});\nsnippet llCastRay\n	llCastRay(${1:vector start}, ${2:vector end}, ${3:list options});\nsnippet llCeil\n	llCeil(${1:float val})\nsnippet llClearCameraParams\n	llClearCameraParams();\nsnippet llClearLinkMedia\n	llClearLinkMedia(${1:integer link}, ${2:integer face});\nsnippet llClearPrimMedia\n	llClearPrimMedia(${1:integer face});\nsnippet llCloseRemoteDataChannel\n	llCloseRemoteDataChannel(${1:key channel});\nsnippet llCollisionFilter\n	llCollisionFilter(${1:string name}, ${2:key id}, ${3:integer accept});\nsnippet llCollisionSound\n	llCollisionSound(${1:string impact_sound}, ${2:float impact_volume});\nsnippet llCos\n	llCos(${1:float theta})\nsnippet llCreateCharacter\n	llCreateCharacter(${1:list options});\nsnippet llCreateLink\n	llCreateLink(${1:key target}, ${2:integer parent});\nsnippet llCSV2List\n	llCSV2List(${1:string src})\nsnippet llDeleteCharacter\n	llDeleteCharacter();\nsnippet llDeleteSubList\n	llDeleteSubList(${1:list src}, ${2:integer start}, ${3:integer end})\nsnippet llDeleteSubString\n	llDeleteSubString(${1:string src}, ${2:integer start}, ${3:integer end})\nsnippet llDetachFromAvatar\n	llDetachFromAvatar();\nsnippet llDetectedGrab\n	llDetectedGrab(${1:integer number})\nsnippet llDetectedGroup\n	llDetectedGroup(${1:integer number})\nsnippet llDetectedKey\n	llDetectedKey(${1:integer number})\nsnippet llDetectedLinkNumber\n	llDetectedLinkNumber(${1:integer number})\nsnippet llDetectedName\n	llDetectedName(${1:integer number})\nsnippet llDetectedOwner\n	llDetectedOwner(${1:integer number})\nsnippet llDetectedPos\n	llDetectedPosl(${1:integer number})\nsnippet llDetectedRot\n	llDetectedRot(${1:integer number})\nsnippet llDetectedTouchBinormal\n	llDetectedTouchBinormal(${1:integer number})\nsnippet llDetectedTouchFace\n	llDetectedTouchFace(${1:integer number})\nsnippet llDetectedTouchNormal\n	llDetectedTouchNormal(${1:integer number})\nsnippet llDetectedTouchPos\n	llDetectedTouchPos(${1:integer number})\nsnippet llDetectedTouchST\n	llDetectedTouchST(${1:integer number})\nsnippet llDetectedTouchUV\n	llDetectedTouchUV(${1:integer number})\nsnippet llDetectedType\n	llDetectedType(${1:integer number})\nsnippet llDetectedVel\n	llDetectedVel(${1:integer number})\nsnippet llDialog\n	llDialog(${1:key agent}, ${2:string message}, ${3:list buttons}, ${4:integer channel});\nsnippet llDie\n	llDie();\nsnippet llDumpList2String\n	llDumpList2String(${1:list src}, ${2:string separator})\nsnippet llEdgeOfWorld\n	llEdgeOfWorld(${1:vector pos}, ${2:vector dir})\nsnippet llEjectFromLand\n	llEjectFromLand(${1:key agent});\nsnippet llEmail\n	llEmail(${1:string address}, ${2:string subject}, ${3:string message});\nsnippet llEscapeURL\n	llEscapeURL(${1:string url})\nsnippet llEuler2Rot\n	llEuler2Rot(${1:vector v})\nsnippet llExecCharacterCmd\n	llExecCharacterCmd(${1:integer command}, ${2:list options});\nsnippet llEvade\n	llEvade(${1:key target}, ${2:list options});\nsnippet llFabs\n	llFabs(${1:float val})\nsnippet llFleeFrom\n	llFleeFrom(${1:vector position}, ${2:float distance}, ${3:list options});\nsnippet llFloor\n	llFloor(${1:float val})\nsnippet llForceMouselook\n	llForceMouselook(${1:integer mouselook});\nsnippet llFrand\n	llFrand(${1:float mag})\nsnippet llGenerateKey\n	llGenerateKey()\nsnippet llGetAccel\n	llGetAccel()\nsnippet llGetAgentInfo\n	llGetAgentInfo(${1:key id})\nsnippet llGetAgentLanguage\n	llGetAgentLanguage(${1:key agent})\nsnippet llGetAgentList\n	llGetAgentList(${1:integer scope}, ${2:list options})\nsnippet llGetAgentSize\n	llGetAgentSize(${1:key agent})\nsnippet llGetAlpha\n	llGetAlpha(${1:integer face})\nsnippet llGetAndResetTime\n	llGetAndResetTime()\nsnippet llGetAnimation\n	llGetAnimation(${1:key id})\nsnippet llGetAnimationList\n	llGetAnimationList(${1:key agent})\nsnippet llGetAnimationOverride\n	llGetAnimationOverride(${1:string anim_state})\nsnippet llGetAttached\n	llGetAttached()\nsnippet llGetBoundingBox\n	llGetBoundingBox(${1:key object})\nsnippet llGetCameraPos\n	llGetCameraPos()\nsnippet llGetCameraRot\n	llGetCameraRot()\nsnippet llGetCenterOfMass\n	llGetCenterOfMass()\nsnippet llGetClosestNavPoint\n	llGetClosestNavPoint(${1:vector point}, ${2:list options})\nsnippet llGetColor\n	llGetColor(${1:integer face})\nsnippet llGetCreator\n	llGetCreator()\nsnippet llGetDate\n	llGetDate()\nsnippet llGetDisplayName\n	llGetDisplayName(${1:key id})\nsnippet llGetEnergy\n	llGetEnergy()\nsnippet llGetEnv\n	llGetEnv(${1:string name})\nsnippet llGetForce\n	llGetForce()\nsnippet llGetFreeMemory\n	llGetFreeMemory()\nsnippet llGetFreeURLs\n	llGetFreeURLs()\nsnippet llGetGeometricCenter\n	llGetGeometricCenter()\nsnippet llGetGMTclock\n	llGetGMTclock()\nsnippet llGetHTTPHeader\n	llGetHTTPHeader(${1:key request_id}, ${2:string header})\nsnippet llGetInventoryCreator\n	llGetInventoryCreator(${1:string item})\nsnippet llGetInventoryKey\n	llGetInventoryKey(${1:string name})\nsnippet llGetInventoryName\n	llGetInventoryName(${1:integer type}, ${2:integer number})\nsnippet llGetInventoryNumber\n	llGetInventoryNumber(${1:integer type})\nsnippet llGetInventoryPermMask\n	llGetInventoryPermMask(${1:string item}, ${2:integer mask})\nsnippet llGetInventoryType\n	llGetInventoryType(${1:string name})\nsnippet llGetKey\n	llGetKey()\nsnippet llGetLandOwnerAt\n	llGetLandOwnerAt(${1:vector pos})\nsnippet llGetLinkKey\n	llGetLinkKey(${1:integer link})\nsnippet llGetLinkMedia\n	llGetLinkMedia(${1:integer link}, ${2:integer face}, ${3:list params})\nsnippet llGetLinkName\n	llGetLinkName(${1:integer link})\nsnippet llGetLinkNumber\n	llGetLinkNumber()\nsnippet llGetLinkNumberOfSides\n	llGetLinkNumberOfSides(${1:integer link})\nsnippet llGetLinkPrimitiveParams\n	llGetLinkPrimitiveParams(${1:integer link}, ${2:list params})\nsnippet llGetListEntryType\n	llGetListEntryType(${1:list src}, ${2:integer index})\nsnippet llGetListLength\n	llGetListLength(${1:list src})\nsnippet llGetLocalPos\n	llGetLocalPos()\nsnippet llGetLocalRot\n	llGetLocalRot()\nsnippet llGetMass\n	llGetMass()\nsnippet llGetMassMKS\n	llGetMassMKS()\nsnippet llGetMaxScaleFactor\n	llGetMaxScaleFactor()\nsnippet llGetMemoryLimit\n	llGetMemoryLimit()\nsnippet llGetMinScaleFactor\n	llGetMinScaleFactor()\nsnippet llGetNextEmail\n	llGetNextEmail(${1:string address}, ${2:string subject});\nsnippet llGetNotecardLine\n	llGetNotecardLine(${1:string name}, ${2:integer line})\nsnippet llGetNumberOfNotecardLines\n	llGetNumberOfNotecardLines(${1:string name})\nsnippet llGetNumberOfPrims\n	llGetNumberOfPrims()\nsnippet llGetNumberOfSides\n	llGetNumberOfSides()\nsnippet llGetObjectDesc\n	llGetObjectDesc()\nsnippet llGetObjectDetails\n	llGetObjectDetails(${1:key id}, ${2:list params})\nsnippet llGetObjectMass\n	llGetObjectMass(${1:key id})\nsnippet llGetObjectName\n	llGetObjectName()\nsnippet llGetObjectPermMask\n	llGetObjectPermMask(${1:integer mask})\nsnippet llGetObjectPrimCount\n	llGetObjectPrimCount(${1:key prim})\nsnippet llGetOmega\n	llGetOmega()\nsnippet llGetOwner\n	llGetOwner()\nsnippet llGetOwnerKey\n	llGetOwnerKey(${1:key id})\nsnippet llGetParcelDetails\n	llGetParcelDetails(${1:vector pos}, ${2:list params})\nsnippet llGetParcelFlags\n	llGetParcelFlags(${1:vector pos})\nsnippet llGetParcelMaxPrims\n	llGetParcelMaxPrims(${1:vector pos}, ${2:integer sim_wide})\nsnippet llGetParcelMusicURL\n	llGetParcelMusicURL()\nsnippet llGetParcelPrimCount\n	llGetParcelPrimCount(${1:vector pos}, ${2:integer category}, ${3:integer sim_wide})\nsnippet llGetParcelPrimOwners\n	llGetParcelPrimOwners(${1:vector pos})\nsnippet llGetPermissions\n	llGetPermissions()\nsnippet llGetPermissionsKey\n	llGetPermissionsKey()\nsnippet llGetPhysicsMaterial\n	llGetPhysicsMaterial()\nsnippet llGetPos\n	llGetPos()\nsnippet llGetPrimitiveParams\n	llGetPrimitiveParams(${1:list params})\nsnippet llGetPrimMediaParams\n	llGetPrimMediaParams(${1:integer face}, ${2:list params})\nsnippet llGetRegionAgentCount\n	llGetRegionAgentCount()\nsnippet llGetRegionCorner\n	llGetRegionCorner()\nsnippet llGetRegionFlags\n	llGetRegionFlags()\nsnippet llGetRegionFPS\n	llGetRegionFPS()\nsnippet llGetRegionName\n	llGetRegionName()\nsnippet llGetRegionTimeDilation\n	llGetRegionTimeDilation()\nsnippet llGetRootPosition\n	llGetRootPosition()\nsnippet llGetRootRotation\n	llGetRootRotation()\nsnippet llGetRot\n	llGetRot()\nsnippet llGetScale\n	llGetScale()\nsnippet llGetScriptName\n	llGetScriptName()\nsnippet llGetScriptState\n	llGetScriptState(${1:string script})\nsnippet llGetSimStats\n	llGetSimStats(${1:integer stat_type})\nsnippet llGetSimulatorHostname\n	llGetSimulatorHostname()\nsnippet llGetSPMaxMemory\n	llGetSPMaxMemory()\nsnippet llGetStartParameter\n	llGetStartParameter()\nsnippet llGetStaticPath\n	llGetStaticPath(${1:vector start}, ${2:vector end}, ${3:float radius}, ${4:list params})\nsnippet llGetStatus\n	llGetStatus(${1:integer status})\nsnippet llGetSubString\n	llGetSubString(${1:string src}, ${2:integer start}, ${3:integer end})\nsnippet llGetSunDirection\n	llGetSunDirection()\nsnippet llGetTexture\n	llGetTexture(${1:integer face})\nsnippet llGetTextureOffset\n	llGetTextureOffset(${1:integer face})\nsnippet llGetTextureRot\n	llGetTextureRot(${1:integer face})\nsnippet llGetTextureScale\n	llGetTextureScale(${1:integer face})\nsnippet llGetTime\n	llGetTime()\nsnippet llGetTimeOfDay\n	llGetTimeOfDay()\nsnippet llGetTimestamp\n	llGetTimestamp()\nsnippet llGetTorque\n	llGetTorque()\nsnippet llGetUnixTime\n	llGetUnixTime()\nsnippet llGetUsedMemory\n	llGetUsedMemory()\nsnippet llGetUsername\n	llGetUsername(${1:key id})\nsnippet llGetVel\n	llGetVel()\nsnippet llGetWallclock\n	llGetWallclock()\nsnippet llGiveInventory\n	llGiveInventory(${1:key destination}, ${2:string inventory});\nsnippet llGiveInventoryList\n	llGiveInventoryList(${1:key target}, ${2:string folder}, ${3:list inventory});\nsnippet llGiveMoney\n	llGiveMoney(${1:key destination}, ${2:integer amount})\nsnippet llGround\n	llGround(${1:vector offset})\nsnippet llGroundContour\n	llGroundContour(${1:vector offset})\nsnippet llGroundNormal\n	llGroundNormal(${1:vector offset})\nsnippet llGroundRepel\n	llGroundRepel(${1:float height}, ${2:integer water}, ${3:float tau});\nsnippet llGroundSlope\n	llGroundSlope(${1:vector offset})\nsnippet llHTTPRequest\n	llHTTPRequest(${1:string url}, ${2:list parameters}, ${3:string body})\nsnippet llHTTPResponse\n	llHTTPResponse(${1:key request_id}, ${2:integer status}, ${3:string body});\nsnippet llInsertString\n	llInsertString(${1:string dst}, ${2:integer pos}, ${3:string src})\nsnippet llInstantMessage\n	llInstantMessage(${1:key user}, ${2:string message});\nsnippet llIntegerToBase64\n	llIntegerToBase64(${1:integer number})\nsnippet llJson2List\n	llJson2List(${1:string json})\nsnippet llJsonGetValue\n	llJsonGetValue(${1:string json}, ${2:list specifiers})\nsnippet llJsonSetValue\n	llJsonSetValue(${1:string json}, ${2:list specifiers}, ${3:string newValue})\nsnippet llJsonValueType\n	llJsonValueType(${1:string json}, ${2:list specifiers})\nsnippet llKey2Name\n	llKey2Name(${1:key id})\nsnippet llLinkParticleSystem\n	llLinkParticleSystem(${1:integer link}, ${2:list rules});\nsnippet llLinkSitTarget\n	llLinkSitTarget(${1:integer link}, ${2:vector offset}, ${3:rotation rot});\nsnippet llList2CSV\n	llList2CSV(${1:list src})\nsnippet llList2Float\n	llList2Float(${1:list src}, ${2:integer index})\nsnippet llList2Integer\n	llList2Integer(${1:list src}, ${2:integer index})\nsnippet llList2Json\n	llList2Json(${1:string type}, ${2:list values})\nsnippet llList2Key\n	llList2Key(${1:list src}, ${2:integer index})\nsnippet llList2List\n	llList2List(${1:list src}, ${2:integer start}, ${3:integer end})\nsnippet llList2ListStrided\n	llList2ListStrided(${1:list src}, ${2:integer start}, ${3:integer end}, ${4:integer stride})\nsnippet llList2Rot\n	llList2Rot(${1:list src}, ${2:integer index})\nsnippet llList2String\n	llList2String(${1:list src}, ${2:integer index})\nsnippet llList2Vector\n	llList2Vector(${1:list src}, ${2:integer index})\nsnippet llListen\n	llListen(${1:integer channel}, ${2:string name}, ${3:key id}, ${4:string msg})\nsnippet llListenControl\n	llListenControl(${1:integer handle}, ${2:integer active});\nsnippet llListenRemove\n	llListenRemove(${1:integer handle});\nsnippet llListFindList\n	llListFindList(${1:list src}, ${2:list test})\nsnippet llListInsertList\n	llListInsertList(${1:list dest}, ${2:list src}, ${3:integer start})\nsnippet llListRandomize\n	llListRandomize(${1:list src}, ${2:integer stride})\nsnippet llListReplaceList\n	llListReplaceList(${1:list dest}, ${2:list src}, ${3:integer start}, ${4:integer end})\nsnippet llListSort\n	llListSort(${1:list src}, ${2:integer stride}, ${3:integer ascending})\nsnippet llListStatistics\n	llListStatistics(${1:integer operation}, ${2:list src})\nsnippet llLoadURL\n	llLoadURL(${1:key agent}, ${2:string message}, ${3:string url});\nsnippet llLog\n	llLog(${1:float val})\nsnippet llLog10\n	llLog10(${1:float val})\nsnippet llLookAt\n	llLookAt(${1:vector target}, ${2:float strength}, ${3:float damping});\nsnippet llLoopSound\n	llLoopSound(${1:string sound}, ${2:float volume});\nsnippet llLoopSoundMaster\n	llLoopSoundMaster(${1:string sound}, ${2:float volume});\nsnippet llLoopSoundSlave\n	llLoopSoundSlave(${1:string sound}, ${2:float volume});\nsnippet llManageEstateAccess\n	llManageEstateAccess(${1:integer action}, ${2:key agent})\nsnippet llMapDestination\n	llMapDestination(${1:string simname}, ${2:vector pos}, ${3:vector look_at});\nsnippet llMD5String\n	llMD5String(${1:string src}, ${2:integer nonce})\nsnippet llMessageLinked\n	llMessageLinked(${1:integer link}, ${2:integer num}, ${3:string str}, ${4:key id});\nsnippet llMinEventDelay\n	llMinEventDelay(${1:float delay});\nsnippet llModifyLand\n	llModifyLand(${1:integer action}, ${2:integer brush});\nsnippet llModPow\n	llModPow(${1:integer a}, ${2:integer b}, ${3:integer c})\nsnippet llMoveToTarget\n	llMoveToTarget(${1:vector target}, ${2:float tau});\nsnippet llNavigateTo\n	llNavigateTo(${1:vector pos}, ${2:list options});\nsnippet llOffsetTexture\n	llOffsetTexture(${1:float u}, ${2:float v}, ${3:integer face});\nsnippet llOpenRemoteDataChannel\n	llOpenRemoteDataChannel();\nsnippet llOverMyLand\n	llOverMyLand(${1:key id})\nsnippet llOwnerSay\n	llOwnerSay(${1:string msg});\nsnippet llParcelMediaCommandList\n	llParcelMediaCommandList(${1:list commandList});\nsnippet llParcelMediaQuery\n	llParcelMediaQuery(${1:list query})\nsnippet llParseString2List\n	llParseString2List(${1:string src}, ${2:list separators}, ${3:list spacers})\nsnippet llParseStringKeepNulls\n	llParseStringKeepNulls(${1:string src}, ${2:list separators}, ${3:list spacers})\nsnippet llParticleSystem\n	llParticleSystem(${1:list rules});\nsnippet llPassCollisions\n	llPassCollisions(${1:integer pass});\nsnippet llPassTouches\n	llPassTouches(${1:integer pass});\nsnippet llPatrolPoints\n	llPatrolPoints(${1:list patrolPoints}, ${2:list options});\nsnippet llPlaySound\n	llPlaySound(${1:string sound}, ${2:float volume});\nsnippet llPlaySoundSlave\n	llPlaySoundSlave(${1:string sound}, ${2:float volume});\nsnippet llPow\n	llPow(${1:float base}, ${2:float exponent})\nsnippet llPreloadSound\n	llPreloadSound(${1:string sound});\nsnippet llPursue\n	llPursue(${1:key target}, ${2:list options});\nsnippet llPushObject\n	llPushObject(${1:key target}, ${2:vector impulse}, ${3:vector ang_impulse}, ${4:integer local});\nsnippet llRegionSay\n	llRegionSay(${1:integer channel}, ${2:string msg});\nsnippet llRegionSayTo\n	llRegionSayTo(${1:key target}, ${2:integer channel}, ${3:string msg});\nsnippet llReleaseControls\n	llReleaseControls();\nsnippet llReleaseURL\n	llReleaseURL(${1:string url});\nsnippet llRemoteDataReply\n	llRemoteDataReply(${1:key channel}, ${2:key message_id}, ${3:string sdata}, ${4:integer idata});\nsnippet llRemoteLoadScriptPin\n	llRemoteLoadScriptPin(${1:key target}, ${2:string name}, ${3:integer pin}, ${4:integer running}, ${5:integer start_param});\nsnippet llRemoveFromLandBanList\n	llRemoveFromLandBanList(${1:key agent});\nsnippet llRemoveFromLandPassList\n	llRemoveFromLandPassList(${1:key agent});\nsnippet llRemoveInventory\n	llRemoveInventory(${1:string item});\nsnippet llRemoveVehicleFlags\n	llRemoveVehicleFlags(${1:integer flags});\nsnippet llRequestAgentData\n	llRequestAgentData(${1:key id}, ${2:integer data})\nsnippet llRequestDisplayName\n	llRequestDisplayName(${1:key id})\nsnippet llRequestInventoryData\n	llRequestInventoryData(${1:string name})\nsnippet llRequestPermissions\n	llRequestPermissions(${1:key agent}, ${2:integer permissions})\nsnippet llRequestSecureURL\n	llRequestSecureURL()\nsnippet llRequestSimulatorData\n	llRequestSimulatorData(${1:string region}, ${2:integer data})\nsnippet llRequestURL\n	llRequestURL()\nsnippet llRequestUsername\n	llRequestUsername(${1:key id})\nsnippet llResetAnimationOverride\n	llResetAnimationOverride(${1:string anim_state});\nsnippet llResetLandBanList\n	llResetLandBanList();\nsnippet llResetLandPassList\n	llResetLandPassList();\nsnippet llResetOtherScript\n	llResetOtherScript(${1:string name});\nsnippet llResetScript\n	llResetScript();\nsnippet llResetTime\n	llResetTime();\nsnippet llReturnObjectsByID\n	llReturnObjectsByID(${1:list objects})\nsnippet llReturnObjectsByOwner\n	llReturnObjectsByOwner(${1:key owner}, ${2:integer scope})\nsnippet llRezAtRoot\n	llRezAtRoot(${1:string inventory}, ${2:vector position}, ${3:vector velocity}, ${4:rotation rot}, ${5:integer param});\nsnippet llRezObject\n	llRezObject(${1:string inventory}, ${2:vector pos}, ${3:vector vel}, ${4:rotation rot}, ${5:integer param});\nsnippet llRot2Angle\n	llRot2Angle(${1:rotation rot})\nsnippet llRot2Axis\n	llRot2Axis(${1:rotation rot})\nsnippet llRot2Euler\n	llRot2Euler(${1:rotation quat})\nsnippet llRot2Fwd\n	llRot2Fwd(${1:rotation q})\nsnippet llRot2Left\n	llRot2Left(${1:rotation q})\nsnippet llRot2Up\n	llRot2Up(${1:rotation q})\nsnippet llRotateTexture\n	llRotateTexture(${1:float angle}, ${2:integer face});\nsnippet llRotBetween\n	llRotBetween(${1:vector start}, ${2:vector end})\nsnippet llRotLookAt\n	llRotLookAt(${1:rotation target_direction}, ${2:float strength}, ${3:float damping});\nsnippet llRotTarget\n	llRotTarget(${1:rotation rot}, ${2:float error})\nsnippet llRotTargetRemove\n	llRotTargetRemove(${1:integer handle});\nsnippet llRound\n	llRound(${1:float val})\nsnippet llSameGroup\n	llSameGroup(${1:key group})\nsnippet llSay\n	llSay(${1:integer channel}, ${2:string msg});\nsnippet llScaleByFactor\n	llScaleByFactor(${1:float scaling_factor})\nsnippet llScaleTexture\n	llScaleTexture(${1:float u}, ${2:float v}, ${3:integer face});\nsnippet llScriptDanger\n	llScriptDanger(${1:vector pos})\nsnippet llScriptProfiler\n	llScriptProfiler(${1:integer flags});\nsnippet llSendRemoteData\n	llSendRemoteData(${1:key channel}, ${2:string dest}, ${3:integer idata}, ${4:string sdata})\nsnippet llSensor\n	llSensor(${1:string name}, ${2:key id}, ${3:integer type}, ${4:float range}, ${5:float arc});\nsnippet llSensorRepeat\n	llSensorRepeat(${1:string name}, ${2:key id}, ${3:integer type}, ${4:float range}, ${5:float arc}, ${6:float rate});\nsnippet llSetAlpha\n	llSetAlpha(${1:float alpha}, ${2:integer face});\nsnippet llSetAngularVelocity\n	llSetAngularVelocity(${1:vector force}, ${2:integer local});\nsnippet llSetAnimationOverride\n	llSetAnimationOverride(${1:string anim_state}, ${2:string anim})\nsnippet llSetBuoyancy\n	llSetBuoyancy(${1:float buoyancy});\nsnippet llSetCameraAtOffset\n	llSetCameraAtOffset(${1:vector offset});\nsnippet llSetCameraEyeOffset\n	llSetCameraEyeOffset(${1:vector offset});\nsnippet llSetCameraParams\n	llSetCameraParams(${1:list rules});\nsnippet llSetClickAction\n	llSetClickAction(${1:integer action});\nsnippet llSetColor\n	llSetColor(${1:vector color}, ${2:integer face});\nsnippet llSetContentType\n	llSetContentType(${1:key request_id}, ${2:integer content_type});\nsnippet llSetDamage\n	llSetDamage(${1:float damage});\nsnippet llSetForce\n	llSetForce(${1:vector force}, ${2:integer local});\nsnippet llSetForceAndTorque\n	llSetForceAndTorque(${1:vector force}, ${2:vector torque}, ${3:integer local});\nsnippet llSetHoverHeight\n	llSetHoverHeight(${1:float height}, ${2:integer water}, ${3:float tau});\nsnippet llSetKeyframedMotion\n	llSetKeyframedMotion(${1:list keyframes}, ${2:list options});\nsnippet llSetLinkAlpha\n	llSetLinkAlpha(${1:integer link}, ${2:float alpha}, ${3:integer face});\nsnippet llSetLinkCamera\n	llSetLinkCamera(${1:integer link}, ${2:vector eye}, ${3:vector at});\nsnippet llSetLinkColor\n	llSetLinkColor(${1:integer link}, ${2:vector color}, ${3:integer face});\nsnippet llSetLinkMedia\n	llSetLinkMedia(${1:integer link}, ${2:integer face}, ${3:list params});\nsnippet llSetLinkPrimitiveParams\n	llSetLinkPrimitiveParams(${1:integer link}, ${2:list rules});\nsnippet llSetLinkPrimitiveParamsFast\n	llSetLinkPrimitiveParamsFast(${1:integer link}, ${2:list rules});\nsnippet llSetLinkTexture\n	llSetLinkTexture(${1:integer link}, ${2:string texture}, ${3:integer face});\nsnippet llSetLinkTextureAnim\n	llSetLinkTextureAnim(${1:integer link}, ${2:integer mode}, ${3:integer face}, ${4:integer sizex}, ${5:integer sizey}, ${6:float start}, ${7:float length}, ${8:float rate});\nsnippet llSetLocalRot\n	llSetLocalRot(${1:rotation rot});\nsnippet llSetMemoryLimit\n	llSetMemoryLimit(${1:integer limit})\nsnippet llSetObjectDesc\n	llSetObjectDesc(${1:string description});\nsnippet llSetObjectName\n	llSetObjectName(${1:string name});\nsnippet llSetParcelMusicURL\n	llSetParcelMusicURL(${1:string url});\nsnippet llSetPayPrice\n	llSetPayPrice(${1:integer price}, [${2:integer price_button_a}, ${3:integer price_button_b}, ${4:integer price_button_c}, ${5:integer price_button_d}]);\nsnippet llSetPhysicsMaterial\n	llSetPhysicsMaterial(${1:integer mask}, ${2:float gravity_multiplier}, ${3:float restitution}, ${4:float friction}, ${5:float density});\nsnippet llSetPos\n	llSetPos(${1:vector pos});\nsnippet llSetPrimitiveParams\n	llSetPrimitiveParams(${1:list rules});\nsnippet llSetPrimMediaParams\n	llSetPrimMediaParams(${1:integer face}, ${2:list params});\nsnippet llSetRegionPos\n	llSetRegionPos(${1:vector position})\nsnippet llSetRemoteScriptAccessPin\n	llSetRemoteScriptAccessPin(${1:integer pin});\nsnippet llSetRot\n	llSetRot(${1:rotation rot});\nsnippet llSetScale\n	llSetScale(${1:vector size});\nsnippet llSetScriptState\n	llSetScriptState(${1:string name}, ${2:integer run});\nsnippet llSetSitText\n	llSetSitText(${1:string text});\nsnippet llSetSoundQueueing\n	llSetSoundQueueing(${1:integer queue});\nsnippet llSetSoundRadius\n	llSetSoundRadius(${1:float radius});\nsnippet llSetStatus\n	llSetStatus(${1:integer status}, ${2:integer value});\nsnippet llSetText\n	llSetText(${1:string text}, ${2:vector color}, ${3:float alpha});\nsnippet llSetTexture\n	llSetTexture(${1:string texture}, ${2:integer face});\nsnippet llSetTextureAnim\n	llSetTextureAnim(${1:integer mode}, ${2:integer face}, ${3:integer sizex}, ${4:integer sizey}, ${5:float start}, ${6:float length}, ${7:float rate});\nsnippet llSetTimerEvent\n	llSetTimerEvent(${1:float sec});\nsnippet llSetTorque\n	llSetTorque(${1:vector torque}, ${2:integer local});\nsnippet llSetTouchText\n	llSetTouchText(${1:string text});\nsnippet llSetVehicleFlags\n	llSetVehicleFlags(${1:integer flags});\nsnippet llSetVehicleFloatParam\n	llSetVehicleFloatParam(${1:integer param}, ${2:float value});\nsnippet llSetVehicleRotationParam\n	llSetVehicleRotationParam(${1:integer param}, ${2:rotation rot});\nsnippet llSetVehicleType\n	llSetVehicleType(${1:integer type});\nsnippet llSetVehicleVectorParam\n	llSetVehicleVectorParam(${1:integer param}, ${2:vector vec});\nsnippet llSetVelocity\n	llSetVelocity(${1:vector force}, ${2:integer local});\nsnippet llSHA1String\n	llSHA1String(${1:string src})\nsnippet llShout\n	llShout(${1:integer channel}, ${2:string msg});\nsnippet llSin\n	llSin(${1:float theta})\nsnippet llSitTarget\n	llSitTarget(${1:vector offset}, ${2:rotation rot});\nsnippet llSleep\n	llSleep(${1:float sec});\nsnippet llSqrt\n	llSqrt(${1:float val})\nsnippet llStartAnimation\n	llStartAnimation(${1:string anim});\nsnippet llStopAnimation\n	llStopAnimation(${1:string anim});\nsnippet llStopHover\n	llStopHover();\nsnippet llStopLookAt\n	llStopLookAt();\nsnippet llStopMoveToTarget\n	llStopMoveToTarget();\nsnippet llStopSound\n	llStopSound();\nsnippet llStringLength\n	llStringLength(${1:string str})\nsnippet llStringToBase64\n	llStringToBase64(${1:string str})\nsnippet llStringTrim\n	llStringTrim(${1:string src}, ${2:integer type})\nsnippet llSubStringIndex\n	llSubStringIndex(${1:string source}, ${2:string pattern})\nsnippet llTakeControls\n	llTakeControls(${1:integer controls}, ${2:integer accept}, ${3:integer pass_on});\nsnippet llTan\n	llTan(${1:float theta})\nsnippet llTarget\n	llTarget(${1:vector position}, ${2:float range})\nsnippet llTargetOmega\n	llTargetOmega(${1:vector axis}, ${2:float spinrate}, ${3:float gain});\nsnippet llTargetRemove\n	llTargetRemove(${1:integer handle});\nsnippet llTeleportAgent\n	llTeleportAgent(${1:key agent}, ${2:string landmark}, ${3:vector position}, ${4:vector look_at});\nsnippet llTeleportAgentGlobalCoords\n	llTeleportAgentGlobalCoords(${1:key agent}, ${2:vector global_coordinates}, ${3:vector region_coordinates}, ${4:vector look_at});\nsnippet llTeleportAgentHome\n	llTeleportAgentHome(${1:key agent});\nsnippet llTextBox\n	llTextBox(${1:key agent}, ${2:string message}, ${3:integer channel});\nsnippet llToLower\n	llToLower(${1:string src})\nsnippet llToUpper\n	llToUpper(${1:string src})\nsnippet llTransferLindenDollars\n	llTransferLindenDollars(${1:key destination}, ${2:integer amount})\nsnippet llTriggerSound\n	llTriggerSound(${1:string sound}, ${2:float volume});\nsnippet llTriggerSoundLimited\n	llTriggerSoundLimited(${1:string sound}, ${2:float volume}, ${3:vector top_north_east}, ${4:vector bottom_south_west});\nsnippet llUnescapeURL\n	llUnescapeURL(${1:string url})\nsnippet llUnSit\n	llUnSit(${1:key id});\nsnippet llUpdateCharacter\n	llUpdateCharacter(${1:list options})\nsnippet llVecDist\n	llVecDist(${1:vector vec_a}, ${2:vector vec_b})\nsnippet llVecMag\n	llVecMag(${1:vector vec})\nsnippet llVecNorm\n	llVecNorm(${1:vector vec})\nsnippet llVolumeDetect\n	llVolumeDetect(${1:integer detect});\nsnippet llWanderWithin\n	llWanderWithin(${1:vector origin}, ${2:vector dist}, ${3:list options});\nsnippet llWater\n	llWater(${1:vector offset});\nsnippet llWhisper\n	llWhisper(${1:integer channel}, ${2:string msg});\nsnippet llWind\n	llWind(${1:vector offset});\nsnippet llXorBase64\n	llXorBase64(${1:string str1}, ${2:string str2})\nsnippet money\n	money(${1:key id}, ${2:integer amount})\n	{\n		$0\n	}\nsnippet object_rez\n	object_rez(${1:key id})\n	{\n		$0\n	}\nsnippet on_rez\n	on_rez(${1:integer start_param})\n	{\n		$0\n	}\nsnippet path_update\n	path_update(${1:integer type}, ${2:list reserved})\n	{\n		$0\n	}\nsnippet remote_data\n	remote_data(${1:integer event_type}, ${2:key channel}, ${3:key message_id}, ${4:string sender}, ${5:integer idata}, ${6:string sdata})\n	{\n		$0\n	}\nsnippet run_time_permissions\n	run_time_permissions(${1:integer perm})\n	{\n		$0\n	}\nsnippet sensor\n	sensor(${1:integer index})\n	{\n		$0\n	}\nsnippet state\n	state ${1:name}\nsnippet touch\n	touch(${1:integer index})\n	{\n		$0\n	}\nsnippet touch_end\n	touch_end(${1:integer index})\n	{\n		$0\n	}\nsnippet touch_start\n	touch_start(${1:integer index})\n	{\n		$0\n	}\nsnippet transaction_result\n	transaction_result(${1:key id}, ${2:integer success}, ${3:string data})\n	{\n		$0\n	}\nsnippet while\n	while (${1:condition})\n	{\n		$0\n	}\n",t.scope="lsl"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/lua.js b/dist/assets/js/vendor/ace-nc/snippets/lua.js
            new file mode 100644
            index 0000000000..091d96a489
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/lua.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/lua",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet #!\n	#!/usr/bin/env lua\n	$1\nsnippet local\n	local ${1:x} = ${2:1}\nsnippet fun\n	function ${1:fname}(${2:...})\n		${3:-- body}\n	end\nsnippet for\n	for ${1:i}=${2:1},${3:10} do\n		${4:print(i)}\n	end\nsnippet forp\n	for ${1:i},${2:v} in pairs(${3:table_name}) do\n	   ${4:-- body}\n	end\nsnippet fori\n	for ${1:i},${2:v} in ipairs(${3:table_name}) do\n	   ${4:-- body}\n	end\n",t.scope="lua"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/luapage.js b/dist/assets/js/vendor/ace-nc/snippets/luapage.js
            new file mode 100644
            index 0000000000..b78dcf9421
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/luapage.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/luapage",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="luapage"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/lucene.js b/dist/assets/js/vendor/ace-nc/snippets/lucene.js
            new file mode 100644
            index 0000000000..232999adb3
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/lucene.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/lucene",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="lucene"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/makefile.js b/dist/assets/js/vendor/ace-nc/snippets/makefile.js
            new file mode 100644
            index 0000000000..c9870856c2
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/makefile.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/makefile",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet ifeq\n	ifeq (${1:cond0},${2:cond1})\n		${3:code}\n	endif\n",t.scope="makefile"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/markdown.js b/dist/assets/js/vendor/ace-nc/snippets/markdown.js
            new file mode 100644
            index 0000000000..0a4a8f8bd8
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/markdown.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/markdown",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# Markdown\n\n# Includes octopress (http://octopress.org/) snippets\n\nsnippet [\n	[${1:text}](http://${2:address} "${3:title}")\nsnippet [*\n	[${1:link}](${2:`@*`} "${3:title}")${4}\n\nsnippet [:\n	[${1:id}]: http://${2:url} "${3:title}"\nsnippet [:*\n	[${1:id}]: ${2:`@*`} "${3:title}"\n\nsnippet ![\n	![${1:alttext}](${2:/images/image.jpg} "${3:title}")\nsnippet ![*\n	![${1:alt}](${2:`@*`} "${3:title}")${4}\n\nsnippet ![:\n	![${1:id}]: ${2:url} "${3:title}"\nsnippet ![:*\n	![${1:id}]: ${2:`@*`} "${3:title}"\n\nsnippet ===\nregex /^/=+/=*//\n	${PREV_LINE/./=/g}\n	\n	${0}\nsnippet ---\nregex /^/-+/-*//\n	${PREV_LINE/./-/g}\n	\n	${0}\nsnippet blockquote\n	{% blockquote %}\n	${1:quote}\n	{% endblockquote %}\n\nsnippet blockquote-author\n	{% blockquote ${1:author}, ${2:title} %}\n	${3:quote}\n	{% endblockquote %}\n\nsnippet blockquote-link\n	{% blockquote ${1:author} ${2:URL} ${3:link_text} %}\n	${4:quote}\n	{% endblockquote %}\n\nsnippet bt-codeblock-short\n	```\n	${1:code_snippet}\n	```\n\nsnippet bt-codeblock-full\n	``` ${1:language} ${2:title} ${3:URL} ${4:link_text}\n	${5:code_snippet}\n	```\n\nsnippet codeblock-short\n	{% codeblock %}\n	${1:code_snippet}\n	{% endcodeblock %}\n\nsnippet codeblock-full\n	{% codeblock ${1:title} lang:${2:language} ${3:URL} ${4:link_text} %}\n	${5:code_snippet}\n	{% endcodeblock %}\n\nsnippet gist-full\n	{% gist ${1:gist_id} ${2:filename} %}\n\nsnippet gist-short\n	{% gist ${1:gist_id} %}\n\nsnippet img\n	{% img ${1:class} ${2:URL} ${3:width} ${4:height} ${5:title_text} ${6:alt_text} %}\n\nsnippet youtube\n	{% youtube ${1:video_id} %}\n\n# The quote should appear only once in the text. It is inherently part of it.\n# See http://octopress.org/docs/plugins/pullquote/ for more info.\n\nsnippet pullquote\n	{% pullquote %}\n	${1:text} {" ${2:quote} "} ${3:text}\n	{% endpullquote %}\n',t.scope="markdown"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/matlab.js b/dist/assets/js/vendor/ace-nc/snippets/matlab.js
            new file mode 100644
            index 0000000000..e2ee0a7671
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/matlab.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/matlab",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="matlab"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/mel.js b/dist/assets/js/vendor/ace-nc/snippets/mel.js
            new file mode 100644
            index 0000000000..1e1c4743b2
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/mel.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/mel",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="mel"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/mushcode.js b/dist/assets/js/vendor/ace-nc/snippets/mushcode.js
            new file mode 100644
            index 0000000000..25b7e76a10
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/mushcode.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/mushcode",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="mushcode"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/mysql.js b/dist/assets/js/vendor/ace-nc/snippets/mysql.js
            new file mode 100644
            index 0000000000..71b06d9cb6
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/mysql.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/mysql",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="mysql"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/nix.js b/dist/assets/js/vendor/ace-nc/snippets/nix.js
            new file mode 100644
            index 0000000000..c44b967350
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/nix.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/nix",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="nix"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/objectivec.js b/dist/assets/js/vendor/ace-nc/snippets/objectivec.js
            new file mode 100644
            index 0000000000..aa49339f05
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/objectivec.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/objectivec",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="objectivec"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/ocaml.js b/dist/assets/js/vendor/ace-nc/snippets/ocaml.js
            new file mode 100644
            index 0000000000..c9a46aa905
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/ocaml.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/ocaml",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="ocaml"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/pascal.js b/dist/assets/js/vendor/ace-nc/snippets/pascal.js
            new file mode 100644
            index 0000000000..176f7d95e5
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/pascal.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/pascal",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="pascal"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/perl.js b/dist/assets/js/vendor/ace-nc/snippets/perl.js
            new file mode 100644
            index 0000000000..0668b47c1b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/perl.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/perl",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="# #!/usr/bin/perl\nsnippet #!\n	#!/usr/bin/env perl\n\n# Hash Pointer\nsnippet .\n	 =>\n# Function\nsnippet sub\n	sub ${1:function_name} {\n		${2:#body ...}\n	}\n# Conditional\nsnippet if\n	if (${1}) {\n		${2:# body...}\n	}\n# Conditional if..else\nsnippet ife\n	if (${1}) {\n		${2:# body...}\n	}\n	else {\n		${3:# else...}\n	}\n# Conditional if..elsif..else\nsnippet ifee\n	if (${1}) {\n		${2:# body...}\n	}\n	elsif (${3}) {\n		${4:# elsif...}\n	}\n	else {\n		${5:# else...}\n	}\n# Conditional One-line\nsnippet xif\n	${1:expression} if ${2:condition};${3}\n# Unless conditional\nsnippet unless\n	unless (${1}) {\n		${2:# body...}\n	}\n# Unless conditional One-line\nsnippet xunless\n	${1:expression} unless ${2:condition};${3}\n# Try/Except\nsnippet eval\n	local $@;\n	eval {\n		${1:# do something risky...}\n	};\n	if (my $e = $@) {\n		${2:# handle failure...}\n	}\n# While Loop\nsnippet wh\n	while (${1}) {\n		${2:# body...}\n	}\n# While Loop One-line\nsnippet xwh\n	${1:expression} while ${2:condition};${3}\n# C-style For Loop\nsnippet cfor\n	for (my $${2:var} = 0; $$2 < ${1:count}; $$2${3:++}) {\n		${4:# body...}\n	}\n# For loop one-line\nsnippet xfor\n	${1:expression} for @${2:array};${3}\n# Foreach Loop\nsnippet for\n	foreach my $${1:x} (@${2:array}) {\n		${3:# body...}\n	}\n# Foreach Loop One-line\nsnippet fore\n	${1:expression} foreach @${2:array};${3}\n# Package\nsnippet package\n	package ${1:`substitute(Filename('', 'Page Title'), '^.', '\\u&', '')`};\n\n	${2}\n\n	1;\n\n	__END__\n# Package syntax perl >= 5.14\nsnippet packagev514\n	package ${1:`substitute(Filename('', 'Page Title'), '^.', '\\u&', '')`} ${2:0.99};\n\n	${3}\n\n	1;\n\n	__END__\n#moose\nsnippet moose\n	use Moose;\n	use namespace::autoclean;\n	${1:#}BEGIN {extends '${2:ParentClass}'};\n\n	${3}\n# parent\nsnippet parent\n	use parent qw(${1:Parent Class});\n# Read File\nsnippet slurp\n	my $${1:var} = do { local $/; open my $file, '<', \"${2:file}\"; <$file> };\n	${3}\n# strict warnings\nsnippet strwar\n	use strict;\n	use warnings;\n# older versioning with perlcritic bypass\nsnippet vers\n	## no critic\n	our $VERSION = '${1:version}';\n	eval $VERSION;\n	## use critic\n# new 'switch' like feature\nsnippet switch\n	use feature 'switch';\n\n# Anonymous subroutine\nsnippet asub\n	sub {\n	 	${1:# body }\n	}\n\n\n\n# Begin block\nsnippet begin\n	BEGIN {\n		${1:# begin body}\n	}\n\n# call package function with some parameter\nsnippet pkgmv\n	__PACKAGE__->${1:package_method}(${2:var})\n\n# call package function without a parameter\nsnippet pkgm\n	__PACKAGE__->${1:package_method}()\n\n# call package \"get_\" function without a parameter\nsnippet pkget\n	__PACKAGE__->get_${1:package_method}()\n\n# call package function with a parameter\nsnippet pkgetv\n	__PACKAGE__->get_${1:package_method}(${2:var})\n\n# complex regex\nsnippet qrx\n	qr/\n	     ${1:regex}\n	/xms\n\n#simpler regex\nsnippet qr/\n	qr/${1:regex}/x\n\n#given\nsnippet given\n	given ($${1:var}) {\n		${2:# cases}\n		${3:# default}\n	}\n\n# switch-like case\nsnippet when\n	when (${1:case}) {\n		${2:# body}\n	}\n\n# hash slice\nsnippet hslice\n	@{ ${1:hash}  }{ ${2:array} }\n\n\n# map\nsnippet map\n	map {  ${2: body }    }  ${1: @array } ;\n\n\n\n# Pod stub\nsnippet ppod\n	=head1 NAME\n\n	${1:ClassName} - ${2:ShortDesc}\n\n	=head1 SYNOPSIS\n\n	  use $1;\n\n	  ${3:# synopsis...}\n\n	=head1 DESCRIPTION\n\n	${4:# longer description...}\n\n\n	=head1 INTERFACE\n\n\n	=head1 DEPENDENCIES\n\n\n	=head1 SEE ALSO\n\n\n# Heading for a subroutine stub\nsnippet psub\n	=head2 ${1:MethodName}\n\n	${2:Summary....}\n\n# Heading for inline subroutine pod\nsnippet psubi\n	=head2 ${1:MethodName}\n\n	${2:Summary...}\n\n\n	=cut\n# inline documented subroutine\nsnippet subpod\n	=head2 $1\n\n	Summary of $1\n\n	=cut\n\n	sub ${1:subroutine_name} {\n		${2:# body...}\n	}\n# Subroutine signature\nsnippet parg\n	=over 2\n\n	=item\n	Arguments\n\n\n	=over 3\n\n	=item\n	C<${1:DataStructure}>\n\n	  ${2:Sample}\n\n\n	=back\n\n\n	=item\n	Return\n\n	=over 3\n\n\n	=item\n	C<${3:...return data}>\n\n\n	=back\n\n\n	=back\n\n\n\n# Moose has\nsnippet has\n	has ${1:attribute} => (\n		is	    => '${2:ro|rw}',\n		isa 	=> '${3:Str|Int|HashRef|ArrayRef|etc}',\n		default => sub {\n			${4:defaultvalue}\n		},\n		${5:# other attributes}\n	);\n\n\n# override\nsnippet override\n	override ${1:attribute} => sub {\n		${2:# my $self = shift;};\n		${3:# my ($self, $args) = @_;};\n	};\n\n\n# use test classes\nsnippet tuse\n	use Test::More;\n	use Test::Deep; # (); # uncomment to stop prototype errors\n	use Test::Exception;\n\n# local test lib\nsnippet tlib\n	use lib qw{ ./t/lib };\n\n#test methods\nsnippet tmeths\n	$ENV{TEST_METHOD} = '${1:regex}';\n\n# runtestclass\nsnippet trunner\n	use ${1:test_class};\n	$1->runtests();\n\n# Test::Class-style test\nsnippet tsub\n	sub t${1:number}_${2:test_case} :Test(${3:num_of_tests}) {\n		my $self = shift;\n		${4:#  body}\n\n	}\n\n# Test::Routine-style test\nsnippet trsub\n	test ${1:test_name} => { description => '${2:Description of test.}'} => sub {\n		my ($self) = @_;\n		${3:# test code}\n	};\n\n#prep test method\nsnippet tprep\n	sub prep${1:number}_${2:test_case} :Test(startup) {\n		my $self = shift;\n		${4:#  body}\n	}\n\n# cause failures to print stack trace\nsnippet debug_trace\n	use Carp; # 'verbose';\n	# cloak \"die\"\n	# warn \"warning\"\n	$SIG{'__DIE__'} = sub {\n		require Carp; Carp::confess\n	};\n\n",t.scope="perl"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/pgsql.js b/dist/assets/js/vendor/ace-nc/snippets/pgsql.js
            new file mode 100644
            index 0000000000..260ff292de
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/pgsql.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/pgsql",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="pgsql"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/php.js b/dist/assets/js/vendor/ace-nc/snippets/php.js
            new file mode 100644
            index 0000000000..39f9ed33c3
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/php.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/php",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet <?\n	<?php\n\n	${1}\nsnippet ec\n	echo ${1};\nsnippet <?e\n	<?php echo ${1} ?>\n# this one is for php5.4\nsnippet <?=\n	<?=${1}?>\nsnippet ns\n	namespace ${1:Foo\\Bar\\Baz};\n	${2}\nsnippet use\n	use ${1:Foo\\Bar\\Baz};\n	${2}\nsnippet c\n	${1:abstract }class ${2:$FILENAME}\n	{\n		${3}\n	}\nsnippet i\n	interface ${1:$FILENAME}\n	{\n		${2}\n	}\nsnippet t.\n	$this->${1}\nsnippet f\n	function ${1:foo}(${2:array }${3:$bar})\n	{\n		${4}\n	}\n# method\nsnippet m\n	${1:abstract }${2:protected}${3: static} function ${4:foo}(${5:array }${6:$bar})\n	{\n		${7}\n	}\n# setter method\nsnippet sm \n	${5:public} function set${6:$2}(${7:$2 }$$1)\n	{\n		$this->${8:$1} = $$1;\n		return $this;\n	}${9}\n# getter method\nsnippet gm\n	${3:public} function get${4:$2}()\n	{\n		return $this->${5:$1};\n	}${6}\n#setter\nsnippet $s\n	${1:$foo}->set${2:Bar}(${3});\n#getter\nsnippet $g\n	${1:$foo}->get${2:Bar}();\n\n# Tertiary conditional\nsnippet =?:\n	$${1:foo} = ${2:true} ? ${3:a} : ${4};\nsnippet ?:\n	${1:true} ? ${2:a} : ${3}\n\nsnippet C\n	$_COOKIE['${1:variable}']${2}\nsnippet E\n	$_ENV['${1:variable}']${2}\nsnippet F\n	$_FILES['${1:variable}']${2}\nsnippet G\n	$_GET['${1:variable}']${2}\nsnippet P\n	$_POST['${1:variable}']${2}\nsnippet R\n	$_REQUEST['${1:variable}']${2}\nsnippet S\n	$_SERVER['${1:variable}']${2}\nsnippet SS\n	$_SESSION['${1:variable}']${2}\n	\n# the following are old ones\nsnippet inc\n	include '${1:file}';${2}\nsnippet inc1\n	include_once '${1:file}';${2}\nsnippet req\n	require '${1:file}';${2}\nsnippet req1\n	require_once '${1:file}';${2}\n# Start Docblock\nsnippet /*\n# Class - post doc\nsnippet doc_cp${5}\n# Class Variable - post doc\nsnippet doc_vp${3}\n# Class Variable\nsnippet doc_v\n	${1:var} $${2};${5}\n# Class\nsnippet doc_c\n	${1:}class ${2:}\n	{\n		${7}\n	} // END $1class $2\n# Constant Definition - post doc\nsnippet doc_dp${2}\n# Constant Definition\nsnippet doc_d\n	ace.define(${1}, ${2});${4}\n# Function - post doc\nsnippet doc_fp${4}\n# Function signature\nsnippet doc_s\n	${1}function ${2}(${3});${7}\n# Function\nsnippet doc_f\n	${1}function ${2}(${3})\n	{${7}\n	}\n# Header\nsnippet doc_h\n	\n# Interface\nsnippet interface\n	interface ${1:$FILENAME}\n	{\n		${5}\n	}\n# class ...\nsnippet class\n	class ${2:$FILENAME}\n	{\n		${3}\n		${5:public} function ${6:__construct}(${7:argument})\n		{\n			${8:// code...}\n		}\n	}\n# ace.define(...)\nsnippet def\n	ace.define('${1}'${2});${3}\n# defined(...)\nsnippet def?\n	${1}defined('${2}')${3}\nsnippet wh\n	while (${1:/* condition */}) {\n		${2:// code...}\n	}\n# do ... while\nsnippet do\n	do {\n		${2:// code... }\n	} while (${1:/* condition */});\nsnippet if\n	if (${1:/* condition */}) {\n		${2:// code...}\n	}\nsnippet ifil\n	<?php if (${1:/* condition */}): ?>\n		${2:<!-- code... -->}\n	<?php endif; ?>\nsnippet ife\n	if (${1:/* condition */}) {\n		${2:// code...}\n	} else {\n		${3:// code...}\n	}\n	${4}\nsnippet ifeil\n	<?php if (${1:/* condition */}): ?>\n		${2:<!-- html... -->}\n	<?php else: ?>\n		${3:<!-- html... -->}\n	<?php endif; ?>\n	${4}\nsnippet else\n	else {\n		${1:// code...}\n	}\nsnippet elseif\n	elseif (${1:/* condition */}) {\n		${2:// code...}\n	}\nsnippet switch\n	switch ($${1:variable}) {\n		case '${2:value}':\n			${3:// code...}\n			break;\n		${5}\n		default:\n			${4:// code...}\n			break;\n	}\nsnippet case\n	case '${1:value}':\n		${2:// code...}\n		break;${3}\nsnippet for\n	for ($${2:i} = 0; $$2 < ${1:count}; $$2${3:++}) {\n		${4: // code...}\n	}\nsnippet foreach\n	foreach ($${1:variable} as $${2:value}) {\n		${3:// code...}\n	}\nsnippet foreachil\n	<?php foreach ($${1:variable} as $${2:value}): ?>\n		${3:<!-- html... -->}\n	<?php endforeach; ?>\nsnippet foreachk\n	foreach ($${1:variable} as $${2:key} => $${3:value}) {\n		${4:// code...}\n	}\nsnippet foreachkil\n	<?php foreach ($${1:variable} as $${2:key} => $${3:value}): ?>\n		${4:<!-- html... -->}\n	<?php endforeach; ?>\n# $... = array (...)\nsnippet array\n	$${1:arrayName} = array('${2}' => ${3});${4}\nsnippet try\n	try {\n		${2}\n	} catch (${1:Exception} $e) {\n	}\n# lambda with closure\nsnippet lambda\n	${1:static }function (${2:args}) use (${3:&$x, $y /*put vars in scope (closure) */}) {\n		${4}\n	};\n# pre_dump();\nsnippet pd\n	echo '<pre>'; var_dump(${1}); echo '</pre>';\n# pre_dump(); die();\nsnippet pdd\n	echo '<pre>'; var_dump(${1}); echo '</pre>'; die(${2:});\nsnippet vd\n	var_dump(${1});\nsnippet vdd\n	var_dump(${1}); die(${2:});\nsnippet http_redirect\n	header (\"HTTP/1.1 301 Moved Permanently\"); \n	header (\"Location: \".URL); \n	exit();\n# Getters & Setters\nsnippet gs\n	public function get${3:$2}()\n	{\n		return $this->${4:$1};\n	}\n	public function set$3(${7:$2 }$$1)\n	{\n		$this->$4 = $$1;\n		return $this;\n	}${8}\n# anotation, get, and set, useful for doctrine\nsnippet ags\n	${2:protected} $${3:foo};\n\n	public function get${4:$3}()\n	{\n		return $this->$3;\n	}\n\n	public function set$4(${5:$4 }$${6:$3})\n	{\n		$this->$3 = $$6;\n		return $this;\n	}\nsnippet rett\n	return true;\nsnippet retf\n	return false;\n",t.scope="php"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/plain_text.js b/dist/assets/js/vendor/ace-nc/snippets/plain_text.js
            new file mode 100644
            index 0000000000..25ec4afaea
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/plain_text.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/plain_text",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="plain_text"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/powershell.js b/dist/assets/js/vendor/ace-nc/snippets/powershell.js
            new file mode 100644
            index 0000000000..1672035d78
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/powershell.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/powershell",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="powershell"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/prolog.js b/dist/assets/js/vendor/ace-nc/snippets/prolog.js
            new file mode 100644
            index 0000000000..7f0071104b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/prolog.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/prolog",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="prolog"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/properties.js b/dist/assets/js/vendor/ace-nc/snippets/properties.js
            new file mode 100644
            index 0000000000..6c0b236a74
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/properties.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/properties",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="properties"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/protobuf.js b/dist/assets/js/vendor/ace-nc/snippets/protobuf.js
            new file mode 100644
            index 0000000000..20b10fbb2c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/protobuf.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/protobuf",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="",t.scope="protobuf"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/python.js b/dist/assets/js/vendor/ace-nc/snippets/python.js
            new file mode 100644
            index 0000000000..ee023b2b4a
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/python.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/python",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet #!\n	#!/usr/bin/env python\nsnippet imp\n	import ${1:module}\nsnippet from\n	from ${1:package} import ${2:module}\n# Module Docstring\nsnippet docs\n	\'\'\'\n	File: ${1:FILENAME:file_name}\n	Author: ${2:author}\n	Description: ${3}\n	\'\'\'\nsnippet wh\n	while ${1:condition}:\n		${2:# TODO: write code...}\n# dowh - does the same as do...while in other languages\nsnippet dowh\n	while True:\n		${1:# TODO: write code...}\n		if ${2:condition}:\n			break\nsnippet with\n	with ${1:expr} as ${2:var}:\n		${3:# TODO: write code...}\n# New Class\nsnippet cl\n	class ${1:ClassName}(${2:object}):\n		"""${3:docstring for $1}"""\n		def __init__(self, ${4:arg}):\n			${5:super($1, self).__init__()}\n			self.$4 = $4\n			${6}\n# New Function\nsnippet def\n	def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n		"""${3:docstring for $1}"""\n		${4:# TODO: write code...}\nsnippet deff\n	def ${1:fname}(${2:`indent(\'.\') ? \'self\' : \'\'`}):\n		${3:# TODO: write code...}\n# New Method\nsnippet defs\n	def ${1:mname}(self, ${2:arg}):\n		${3:# TODO: write code...}\n# New Property\nsnippet property\n	def ${1:foo}():\n		doc = "${2:The $1 property.}"\n		def fget(self):\n			${3:return self._$1}\n		def fset(self, value):\n			${4:self._$1 = value}\n# Ifs\nsnippet if\n	if ${1:condition}:\n		${2:# TODO: write code...}\nsnippet el\n	else:\n		${1:# TODO: write code...}\nsnippet ei\n	elif ${1:condition}:\n		${2:# TODO: write code...}\n# For\nsnippet for\n	for ${1:item} in ${2:items}:\n		${3:# TODO: write code...}\n# Encodes\nsnippet cutf8\n	# -*- coding: utf-8 -*-\nsnippet clatin1\n	# -*- coding: latin-1 -*-\nsnippet cascii\n	# -*- coding: ascii -*-\n# Lambda\nsnippet ld\n	${1:var} = lambda ${2:vars} : ${3:action}\nsnippet .\n	self.\nsnippet try Try/Except\n	try:\n		${1:# TODO: write code...}\n	except ${2:Exception}, ${3:e}:\n		${4:raise $3}\nsnippet try Try/Except/Else\n	try:\n		${1:# TODO: write code...}\n	except ${2:Exception}, ${3:e}:\n		${4:raise $3}\n	else:\n		${5:# TODO: write code...}\nsnippet try Try/Except/Finally\n	try:\n		${1:# TODO: write code...}\n	except ${2:Exception}, ${3:e}:\n		${4:raise $3}\n	finally:\n		${5:# TODO: write code...}\nsnippet try Try/Except/Else/Finally\n	try:\n		${1:# TODO: write code...}\n	except ${2:Exception}, ${3:e}:\n		${4:raise $3}\n	else:\n		${5:# TODO: write code...}\n	finally:\n		${6:# TODO: write code...}\n# if __name__ == \'__main__\':\nsnippet ifmain\n	if __name__ == \'__main__\':\n		${1:main()}\n# __magic__\nsnippet _\n	__${1:init}__${2}\n# python debugger (pdb)\nsnippet pdb\n	import pdb; pdb.set_trace()\n# ipython debugger (ipdb)\nsnippet ipdb\n	import ipdb; ipdb.set_trace()\n# ipython debugger (pdbbb)\nsnippet pdbbb\n	import pdbpp; pdbpp.set_trace()\nsnippet pprint\n	import pprint; pprint.pprint(${1})${2}\nsnippet "\n	"""\n	${1:doc}\n	"""\n# test function/method\nsnippet test\n	def test_${1:description}(${2:self}):\n		${3:# TODO: write code...}\n# test case\nsnippet testcase\n	class ${1:ExampleCase}(unittest.TestCase):\n		\n		def test_${2:description}(self):\n			${3:# TODO: write code...}\nsnippet fut\n	from __future__ import ${1}\n#getopt\nsnippet getopt\n	try:\n		# Short option syntax: "hv:"\n		# Long option syntax: "help" or "verbose="\n		opts, args = getopt.getopt(sys.argv[1:], "${1:short_options}", [${2:long_options}])\n	\n	except getopt.GetoptError, err:\n		# Print debug info\n		print str(err)\n		${3:error_action}\n\n	for option, argument in opts:\n		if option in ("-h", "--help"):\n			${4}\n		elif option in ("-v", "--verbose"):\n			verbose = argument\n',t.scope="python"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/r.js b/dist/assets/js/vendor/ace-nc/snippets/r.js
            new file mode 100644
            index 0000000000..85076d5955
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/r.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/r",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet #!\n	#!/usr/bin/env Rscript\n\n# includes\nsnippet lib\n	library(${1:package})\nsnippet req\n	require(${1:package})\nsnippet source\n	source(\'${1:file}\')\n\n# conditionals\nsnippet if\n	if (${1:condition}) {\n		${2:code}\n	}\nsnippet el\n	else {\n		${1:code}\n	}\nsnippet ei\n	else if (${1:condition}) {\n		${2:code}\n	}\n\n# functions\nsnippet fun\n	${1:name} = function (${2:variables}) {\n		${3:code}\n	}\nsnippet ret\n	return(${1:code})\n\n# dataframes, lists, etc\nsnippet df\n	${1:name}[${2:rows}, ${3:cols}]\nsnippet c\n	c(${1:items})\nsnippet li\n	list(${1:items})\nsnippet mat\n	matrix(${1:data}, nrow=${2:rows}, ncol=${3:cols})\n\n# apply functions\nsnippet apply\n	apply(${1:array}, ${2:margin}, ${3:function})\nsnippet lapply\n	lapply(${1:list}, ${2:function})\nsnippet sapply\n	lapply(${1:list}, ${2:function})\nsnippet vapply\n	vapply(${1:list}, ${2:function}, ${3:type})\nsnippet mapply\n	mapply(${1:function}, ${2:...})\nsnippet tapply\n	tapply(${1:vector}, ${2:index}, ${3:function})\nsnippet rapply\n	rapply(${1:list}, ${2:function})\n\n# plyr functions\nsnippet dd\n	ddply(${1:frame}, ${2:variables}, ${3:function})\nsnippet dl\n	dlply(${1:frame}, ${2:variables}, ${3:function})\nsnippet da\n	daply(${1:frame}, ${2:variables}, ${3:function})\nsnippet d_\n	d_ply(${1:frame}, ${2:variables}, ${3:function})\n\nsnippet ad\n	adply(${1:array}, ${2:margin}, ${3:function})\nsnippet al\n	alply(${1:array}, ${2:margin}, ${3:function})\nsnippet aa\n	aaply(${1:array}, ${2:margin}, ${3:function})\nsnippet a_\n	a_ply(${1:array}, ${2:margin}, ${3:function})\n\nsnippet ld\n	ldply(${1:list}, ${2:function})\nsnippet ll\n	llply(${1:list}, ${2:function})\nsnippet la\n	laply(${1:list}, ${2:function})\nsnippet l_\n	l_ply(${1:list}, ${2:function})\n\nsnippet md\n	mdply(${1:matrix}, ${2:function})\nsnippet ml\n	mlply(${1:matrix}, ${2:function})\nsnippet ma\n	maply(${1:matrix}, ${2:function})\nsnippet m_\n	m_ply(${1:matrix}, ${2:function})\n\n# plot functions\nsnippet pl\n	plot(${1:x}, ${2:y})\nsnippet ggp\n	ggplot(${1:data}, aes(${2:aesthetics}))\nsnippet img\n	${1:(jpeg,bmp,png,tiff)}(filename="${2:filename}", width=${3}, height=${4}, unit="${5}")\n	${6:plot}\n	dev.off()\n\n# statistical test functions\nsnippet fis\n	fisher.test(${1:x}, ${2:y})\nsnippet chi\n	chisq.test(${1:x}, ${2:y})\nsnippet tt\n	t.test(${1:x}, ${2:y})\nsnippet wil\n	wilcox.test(${1:x}, ${2:y})\nsnippet cor\n	cor.test(${1:x}, ${2:y})\nsnippet fte\n	var.test(${1:x}, ${2:y})\nsnippet kvt \n	kv.test(${1:x}, ${2:y})\n',t.scope="r"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/rdoc.js b/dist/assets/js/vendor/ace-nc/snippets/rdoc.js
            new file mode 100644
            index 0000000000..c7c3b1e06f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/rdoc.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/rdoc",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="rdoc"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/rhtml.js b/dist/assets/js/vendor/ace-nc/snippets/rhtml.js
            new file mode 100644
            index 0000000000..f2b53b5a34
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/rhtml.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/rhtml",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="rhtml"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/ruby.js b/dist/assets/js/vendor/ace-nc/snippets/ruby.js
            new file mode 100644
            index 0000000000..0c3068010f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/ruby.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/ruby",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='########################################\n# Ruby snippets - for Rails, see below #\n########################################\n\n# encoding for Ruby 1.9\nsnippet enc\n	# encoding: utf-8\n\n# #!/usr/bin/env ruby\nsnippet #!\n	#!/usr/bin/env ruby\n	# encoding: utf-8\n\n# New Block\nsnippet =b\n	=begin rdoc\n		${1}\n	=end\nsnippet y\n	:yields: ${1:arguments}\nsnippet rb\n	#!/usr/bin/env ruby -wKU\nsnippet beg\n	begin\n		${3}\n	rescue ${1:Exception} => ${2:e}\n	end\n\nsnippet req require\n	require "${1}"${2}\nsnippet #\n	# =>\nsnippet end\n	__END__\nsnippet case\n	case ${1:object}\n	when ${2:condition}\n		${3}\n	end\nsnippet when\n	when ${1:condition}\n		${2}\nsnippet def\n	def ${1:method_name}\n		${2}\n	end\nsnippet deft\n	def test_${1:case_name}\n		${2}\n	end\nsnippet if\n	if ${1:condition}\n		${2}\n	end\nsnippet ife\n	if ${1:condition}\n		${2}\n	else\n		${3}\n	end\nsnippet elsif\n	elsif ${1:condition}\n		${2}\nsnippet unless\n	unless ${1:condition}\n		${2}\n	end\nsnippet while\n	while ${1:condition}\n		${2}\n	end\nsnippet for\n	for ${1:e} in ${2:c}\n		${3}\n	end\nsnippet until\n	until ${1:condition}\n		${2}\n	end\nsnippet cla class .. end\n	class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n		${2}\n	end\nsnippet cla class .. initialize .. end\n	class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n		def initialize(${2:args})\n			${3}\n		end\n	end\nsnippet cla class .. < ParentClass .. initialize .. end\n	class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} < ${2:ParentClass}\n		def initialize(${3:args})\n			${4}\n		end\n	end\nsnippet cla ClassName = Struct .. do .. end\n	${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} = Struct.new(:${2:attr_names}) do\n		def ${3:method_name}\n			${4}\n		end\n	end\nsnippet cla class BlankSlate .. initialize .. end\n	class ${1:BlankSlate}\n		instance_methods.each { |meth| undef_method(meth) unless meth =~ /\\A__/ }\n	end\nsnippet cla class << self .. end\n	class << ${1:self}\n		${2}\n	end\n# class .. < DelegateClass .. initialize .. end\nsnippet cla-\n	class ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`} < DelegateClass(${2:ParentClass})\n		def initialize(${3:args})\n			super(${4:del_obj})\n\n			${5}\n		end\n	end\nsnippet mod module .. end\n	module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n		${2}\n	end\nsnippet mod module .. module_function .. end\n	module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n		module_function\n\n		${2}\n	end\nsnippet mod module .. ClassMethods .. end\n	module ${1:`substitute(Filename(), \'\\(_\\|^\\)\\(.\\)\', \'\\u\\2\', \'g\')`}\n		module ClassMethods\n			${2}\n		end\n\n		module InstanceMethods\n\n		end\n\n		def self.included(receiver)\n			receiver.extend         ClassMethods\n			receiver.send :include, InstanceMethods\n		end\n	end\n# attr_reader\nsnippet r\n	attr_reader :${1:attr_names}\n# attr_writer\nsnippet w\n	attr_writer :${1:attr_names}\n# attr_accessor\nsnippet rw\n	attr_accessor :${1:attr_names}\nsnippet atp\n	attr_protected :${1:attr_names}\nsnippet ata\n	attr_accessible :${1:attr_names}\n# include Enumerable\nsnippet Enum\n	include Enumerable\n\n	def each(&block)\n		${1}\n	end\n# include Comparable\nsnippet Comp\n	include Comparable\n\n	def <=>(other)\n		${1}\n	end\n# extend Forwardable\nsnippet Forw-\n	extend Forwardable\n# def self\nsnippet defs\n	def self.${1:class_method_name}\n		${2}\n	end\n# def method_missing\nsnippet defmm\n	def method_missing(meth, *args, &blk)\n		${1}\n	end\nsnippet defd\n	def_delegator :${1:@del_obj}, :${2:del_meth}, :${3:new_name}\nsnippet defds\n	def_delegators :${1:@del_obj}, :${2:del_methods}\nsnippet am\n	alias_method :${1:new_name}, :${2:old_name}\nsnippet app\n	if __FILE__ == $PROGRAM_NAME\n		${1}\n	end\n# usage_if()\nsnippet usai\n	if ARGV.${1}\n		abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n	end\n# usage_unless()\nsnippet usau\n	unless ARGV.${1}\n		abort "Usage: #{$PROGRAM_NAME} ${2:ARGS_GO_HERE}"${3}\n	end\nsnippet array\n	Array.new(${1:10}) { |${2:i}| ${3} }\nsnippet hash\n	Hash.new { |${1:hash}, ${2:key}| $1[$2] = ${3} }\nsnippet file File.foreach() { |line| .. }\n	File.foreach(${1:"path/to/file"}) { |${2:line}| ${3} }\nsnippet file File.read()\n	File.read(${1:"path/to/file"})${2}\nsnippet Dir Dir.global() { |file| .. }\n	Dir.glob(${1:"dir/glob/*"}) { |${2:file}| ${3} }\nsnippet Dir Dir[".."]\n	Dir[${1:"glob/**/*.rb"}]${2}\nsnippet dir\n	Filename.dirname(__FILE__)\nsnippet deli\n	delete_if { |${1:e}| ${2} }\nsnippet fil\n	fill(${1:range}) { |${2:i}| ${3} }\n# flatten_once()\nsnippet flao\n	inject(Array.new) { |${1:arr}, ${2:a}| $1.push(*$2)}${3}\nsnippet zip\n	zip(${1:enums}) { |${2:row}| ${3} }\n# downto(0) { |n| .. }\nsnippet dow\n	downto(${1:0}) { |${2:n}| ${3} }\nsnippet ste\n	step(${1:2}) { |${2:n}| ${3} }\nsnippet tim\n	times { |${1:n}| ${2} }\nsnippet upt\n	upto(${1:1.0/0.0}) { |${2:n}| ${3} }\nsnippet loo\n	loop { ${1} }\nsnippet ea\n	each { |${1:e}| ${2} }\nsnippet ead\n	each do |${1:e}|\n		${2}\n	end\nsnippet eab\n	each_byte { |${1:byte}| ${2} }\nsnippet eac- each_char { |chr| .. }\n	each_char { |${1:chr}| ${2} }\nsnippet eac- each_cons(..) { |group| .. }\n	each_cons(${1:2}) { |${2:group}| ${3} }\nsnippet eai\n	each_index { |${1:i}| ${2} }\nsnippet eaid\n	each_index do |${1:i}|\n		${2}\n	end\nsnippet eak\n	each_key { |${1:key}| ${2} }\nsnippet eakd\n	each_key do |${1:key}|\n		${2}\n	end\nsnippet eal\n	each_line { |${1:line}| ${2} }\nsnippet eald\n	each_line do |${1:line}|\n		${2}\n	end\nsnippet eap\n	each_pair { |${1:name}, ${2:val}| ${3} }\nsnippet eapd\n	each_pair do |${1:name}, ${2:val}|\n		${3}\n	end\nsnippet eas-\n	each_slice(${1:2}) { |${2:group}| ${3} }\nsnippet easd-\n	each_slice(${1:2}) do |${2:group}|\n		${3}\n	end\nsnippet eav\n	each_value { |${1:val}| ${2} }\nsnippet eavd\n	each_value do |${1:val}|\n		${2}\n	end\nsnippet eawi\n	each_with_index { |${1:e}, ${2:i}| ${3} }\nsnippet eawid\n	each_with_index do |${1:e},${2:i}|\n		${3}\n	end\nsnippet reve\n	reverse_each { |${1:e}| ${2} }\nsnippet reved\n	reverse_each do |${1:e}|\n		${2}\n	end\nsnippet inj\n	inject(${1:init}) { |${2:mem}, ${3:var}| ${4} }\nsnippet injd\n	inject(${1:init}) do |${2:mem}, ${3:var}|\n		${4}\n	end\nsnippet map\n	map { |${1:e}| ${2} }\nsnippet mapd\n	map do |${1:e}|\n		${2}\n	end\nsnippet mapwi-\n	enum_with_index.map { |${1:e}, ${2:i}| ${3} }\nsnippet sor\n	sort { |a, b| ${1} }\nsnippet sorb\n	sort_by { |${1:e}| ${2} }\nsnippet ran\n	sort_by { rand }\nsnippet all\n	all? { |${1:e}| ${2} }\nsnippet any\n	any? { |${1:e}| ${2} }\nsnippet cl\n	classify { |${1:e}| ${2} }\nsnippet col\n	collect { |${1:e}| ${2} }\nsnippet cold\n	collect do |${1:e}|\n		${2}\n	end\nsnippet det\n	detect { |${1:e}| ${2} }\nsnippet detd\n	detect do |${1:e}|\n		${2}\n	end\nsnippet fet\n	fetch(${1:name}) { |${2:key}| ${3} }\nsnippet fin\n	find { |${1:e}| ${2} }\nsnippet find\n	find do |${1:e}|\n		${2}\n	end\nsnippet fina\n	find_all { |${1:e}| ${2} }\nsnippet finad\n	find_all do |${1:e}|\n		${2}\n	end\nsnippet gre\n	grep(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet sub\n	${1:g}sub(${2:/pattern/}) { |${3:match}| ${4} }\nsnippet sca\n	scan(${1:/pattern/}) { |${2:match}| ${3} }\nsnippet scad\n	scan(${1:/pattern/}) do |${2:match}|\n		${3}\n	end\nsnippet max\n	max { |a, b| ${1} }\nsnippet min\n	min { |a, b| ${1} }\nsnippet par\n	partition { |${1:e}| ${2} }\nsnippet pard\n	partition do |${1:e}|\n		${2}\n	end\nsnippet rej\n	reject { |${1:e}| ${2} }\nsnippet rejd\n	reject do |${1:e}|\n		${2}\n	end\nsnippet sel\n	select { |${1:e}| ${2} }\nsnippet seld\n	select do |${1:e}|\n		${2}\n	end\nsnippet lam\n	lambda { |${1:args}| ${2} }\nsnippet doo\n	do\n		${1}\n	end\nsnippet dov\n	do |${1:variable}|\n		${2}\n	end\nsnippet :\n	:${1:key} => ${2:"value"}${3}\nsnippet ope\n	open(${1:"path/or/url/or/pipe"}, "${2:w}") { |${3:io}| ${4} }\n# path_from_here()\nsnippet fpath\n	File.join(File.dirname(__FILE__), *%2[${1:rel path here}])${2}\n# unix_filter {}\nsnippet unif\n	ARGF.each_line${1} do |${2:line}|\n		${3}\n	end\n# option_parse {}\nsnippet optp\n	require "optparse"\n\n	options = {${1:default => "args"}}\n\n	ARGV.options do |opts|\n		opts.banner = "Usage: #{File.basename($PROGRAM_NAME)}\nsnippet opt\n	opts.on( "-${1:o}", "--${2:long-option-name}", ${3:String},\n	         "${4:Option description.}") do |${5:opt}|\n		${6}\n	end\nsnippet tc\n	require "test/unit"\n\n	require "${1:library_file_name}"\n\n	class Test${2:$1} < Test::Unit::TestCase\n		def test_${3:case_name}\n			${4}\n		end\n	end\nsnippet ts\n	require "test/unit"\n\n	require "tc_${1:test_case_file}"\n	require "tc_${2:test_case_file}"${3}\nsnippet as\n	assert ${1:test}, "${2:Failure message.}"${3}\nsnippet ase\n	assert_equal ${1:expected}, ${2:actual}${3}\nsnippet asne\n	assert_not_equal ${1:unexpected}, ${2:actual}${3}\nsnippet asid\n	assert_in_delta ${1:expected_float}, ${2:actual_float}, ${3:2 ** -20}${4}\nsnippet asio\n	assert_instance_of ${1:ExpectedClass}, ${2:actual_instance}${3}\nsnippet asko\n	assert_kind_of ${1:ExpectedKind}, ${2:actual_instance}${3}\nsnippet asn\n	assert_nil ${1:instance}${2}\nsnippet asnn\n	assert_not_nil ${1:instance}${2}\nsnippet asm\n	assert_match /${1:expected_pattern}/, ${2:actual_string}${3}\nsnippet asnm\n	assert_no_match /${1:unexpected_pattern}/, ${2:actual_string}${3}\nsnippet aso\n	assert_operator ${1:left}, :${2:operator}, ${3:right}${4}\nsnippet asr\n	assert_raise ${1:Exception} { ${2} }\nsnippet asrd\n	assert_raise ${1:Exception} do\n		${2}\n	end\nsnippet asnr\n	assert_nothing_raised ${1:Exception} { ${2} }\nsnippet asnrd\n	assert_nothing_raised ${1:Exception} do\n		${2}\n	end\nsnippet asrt\n	assert_respond_to ${1:object}, :${2:method}${3}\nsnippet ass assert_same(..)\n	assert_same ${1:expected}, ${2:actual}${3}\nsnippet ass assert_send(..)\n	assert_send [${1:object}, :${2:message}, ${3:args}]${4}\nsnippet asns\n	assert_not_same ${1:unexpected}, ${2:actual}${3}\nsnippet ast\n	assert_throws :${1:expected} { ${2} }\nsnippet astd\n	assert_throws :${1:expected} do\n		${2}\n	end\nsnippet asnt\n	assert_nothing_thrown { ${1} }\nsnippet asntd\n	assert_nothing_thrown do\n		${1}\n	end\nsnippet fl\n	flunk "${1:Failure message.}"${2}\n# Benchmark.bmbm do .. end\nsnippet bm-\n	TESTS = ${1:10_000}\n	Benchmark.bmbm do |results|\n		${2}\n	end\nsnippet rep\n	results.report("${1:name}:") { TESTS.times { ${2} }}\n# Marshal.dump(.., file)\nsnippet Md\n	File.open(${1:"path/to/file.dump"}, "wb") { |${2:file}| Marshal.dump(${3:obj}, $2) }${4}\n# Mashal.load(obj)\nsnippet Ml\n	File.open(${1:"path/to/file.dump"}, "rb") { |${2:file}| Marshal.load($2) }${3}\n# deep_copy(..)\nsnippet deec\n	Marshal.load(Marshal.dump(${1:obj_to_copy}))${2}\nsnippet Pn-\n	PStore.new(${1:"file_name.pstore"})${2}\nsnippet tra\n	transaction(${1:true}) { ${2} }\n# xmlread(..)\nsnippet xml-\n	REXML::Document.new(File.read(${1:"path/to/file"}))${2}\n# xpath(..) { .. }\nsnippet xpa\n	elements.each(${1:"//Xpath"}) do |${2:node}|\n		${3}\n	end\n# class_from_name()\nsnippet clafn\n	split("::").inject(Object) { |par, const| par.const_get(const) }\n# singleton_class()\nsnippet sinc\n	class << self; self end\nsnippet nam\n	namespace :${1:`Filename()`} do\n		${2}\n	end\nsnippet tas\n	desc "${1:Task description}"\n	task :${2:task_name => [:dependent, :tasks]} do\n		${3}\n	end\n# block\nsnippet b\n	{ |${1:var}| ${2} }\nsnippet begin\n	begin\n		raise \'A test exception.\'\n	rescue Exception => e\n		puts e.message\n		puts e.backtrace.inspect\n	else\n		# other exception\n	ensure\n		# always executed\n	end\n\n#debugging\nsnippet debug\n	require \'ruby-debug\'; debugger; true;\nsnippet pry\n	require \'pry\'; binding.pry\n\n#############################################\n# Rails snippets - for pure Ruby, see above #\n#############################################\nsnippet art\n	assert_redirected_to ${1::action => "${2:index}"}\nsnippet artnp\n	assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1}, ${4:@$2})\nsnippet artnpp\n	assert_redirected_to ${1:parent}_${2:child}_path(${3:@$1})\nsnippet artp\n	assert_redirected_to ${1:model}_path(${2:@$1})\nsnippet artpp\n	assert_redirected_to ${1:model}s_path\nsnippet asd\n	assert_difference "${1:Model}.${2:count}", $1 do\n		${3}\n	end\nsnippet asnd\n	assert_no_difference "${1:Model}.${2:count}" do\n		${3}\n	end\nsnippet asre\n	assert_response :${1:success}, @response.body${2}\nsnippet asrj\n	assert_rjs :${1:replace}, "${2:dom id}"\nsnippet ass assert_select(..)\n	assert_select \'${1:path}\', :${2:text} => \'${3:inner_html\' ${4:do}\nsnippet bf\n	before_filter :${1:method}\nsnippet bt\n	belongs_to :${1:association}\nsnippet crw\n	cattr_accessor :${1:attr_names}\nsnippet defcreate\n	def create\n		@${1:model_class_name} = ${2:ModelClassName}.new(params[:$1])\n\n		respond_to do |wants|\n			if @$1.save\n				flash[:notice] = \'$2 was successfully created.\'\n				wants.html { redirect_to(@$1) }\n				wants.xml  { render :xml => @$1, :status => :created, :location => @$1 }\n			else\n				wants.html { render :action => "new" }\n				wants.xml  { render :xml => @$1.errors, :status => :unprocessable_entity }\n			end\n		end\n	end${3}\nsnippet defdestroy\n	def destroy\n		@${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n		@$1.destroy\n\n		respond_to do |wants|\n			wants.html { redirect_to($1s_url) }\n			wants.xml  { head :ok }\n		end\n	end${3}\nsnippet defedit\n	def edit\n		@${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n	end\nsnippet defindex\n	def index\n		@${1:model_class_name} = ${2:ModelClassName}.all\n\n		respond_to do |wants|\n			wants.html # index.html.erb\n			wants.xml  { render :xml => @$1s }\n		end\n	end${3}\nsnippet defnew\n	def new\n		@${1:model_class_name} = ${2:ModelClassName}.new\n\n		respond_to do |wants|\n			wants.html # new.html.erb\n			wants.xml  { render :xml => @$1 }\n		end\n	end${3}\nsnippet defshow\n	def show\n		@${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n		respond_to do |wants|\n			wants.html # show.html.erb\n			wants.xml  { render :xml => @$1 }\n		end\n	end${3}\nsnippet defupdate\n	def update\n		@${1:model_class_name} = ${2:ModelClassName}.find(params[:id])\n\n		respond_to do |wants|\n			if @$1.update_attributes(params[:$1])\n				flash[:notice] = \'$2 was successfully updated.\'\n				wants.html { redirect_to(@$1) }\n				wants.xml  { head :ok }\n			else\n				wants.html { render :action => "edit" }\n				wants.xml  { render :xml => @$1.errors, :status => :unprocessable_entity }\n			end\n		end\n	end${3}\nsnippet flash\n	flash[:${1:notice}] = "${2}"\nsnippet habtm\n	has_and_belongs_to_many :${1:object}, :join_table => "${2:table_name}", :foreign_key => "${3}_id"${4}\nsnippet hm\n	has_many :${1:object}\nsnippet hmd\n	has_many :${1:other}s, :class_name => "${2:$1}", :foreign_key => "${3:$1}_id", :dependent => :destroy${4}\nsnippet hmt\n	has_many :${1:object}, :through => :${2:object}\nsnippet ho\n	has_one :${1:object}\nsnippet i18\n	I18n.t(\'${1:type.key}\')${2}\nsnippet ist\n	<%= image_submit_tag("${1:agree.png}", :id => "${2:id}"${3} %>\nsnippet log\n	Rails.logger.${1:debug} ${2}\nsnippet log2\n	RAILS_DEFAULT_LOGGER.${1:debug} ${2}\nsnippet logd\n	logger.debug { "${1:message}" }${2}\nsnippet loge\n	logger.error { "${1:message}" }${2}\nsnippet logf\n	logger.fatal { "${1:message}" }${2}\nsnippet logi\n	logger.info { "${1:message}" }${2}\nsnippet logw\n	logger.warn { "${1:message}" }${2}\nsnippet mapc\n	${1:map}.${2:connect} \'${3:controller/:action/:id}\'\nsnippet mapca\n	${1:map}.catch_all "*${2:anything}", :controller => "${3:default}", :action => "${4:error}"${5}\nsnippet mapr\n	${1:map}.resource :${2:resource}\nsnippet maprs\n	${1:map}.resources :${2:resource}\nsnippet mapwo\n	${1:map}.with_options :${2:controller} => \'${3:thing}\' do |$3|\n		${4}\n	end\nsnippet mbs\n	before_save :${1:method}\nsnippet mcht\n	change_table :${1:table_name} do |t|\n		${2}\n	end\nsnippet mp\n	map(&:${1:id})\nsnippet mrw\n	mattr_accessor :${1:attr_names}\nsnippet oa\n	order("${1:field}")\nsnippet od\n	order("${1:field} DESC")\nsnippet pa\n	params[:${1:id}]${2}\nsnippet ra\n	render :action => "${1:action}"\nsnippet ral\n	render :action => "${1:action}", :layout => "${2:layoutname}"\nsnippet rest\n	respond_to do |wants|\n		wants.${1:html} { ${2} }\n	end\nsnippet rf\n	render :file => "${1:filepath}"\nsnippet rfu\n	render :file => "${1:filepath}", :use_full_path => ${2:false}\nsnippet ri\n	render :inline => "${1:<%= \'hello\' %>}"\nsnippet ril\n	render :inline => "${1:<%= \'hello\' %>}", :locals => { ${2::name} => "${3:value}"${4} }\nsnippet rit\n	render :inline => "${1:<%= \'hello\' %>}", :type => ${2::rxml}\nsnippet rjson\n	render :json => ${1:text to render}\nsnippet rl\n	render :layout => "${1:layoutname}"\nsnippet rn\n	render :nothing => ${1:true}\nsnippet rns\n	render :nothing => ${1:true}, :status => ${2:401}\nsnippet rp\n	render :partial => "${1:item}"\nsnippet rpc\n	render :partial => "${1:item}", :collection => ${2:@$1s}\nsnippet rpl\n	render :partial => "${1:item}", :locals => { :${2:$1} => ${3:@$1}\nsnippet rpo\n	render :partial => "${1:item}", :object => ${2:@$1}\nsnippet rps\n	render :partial => "${1:item}", :status => ${2:500}\nsnippet rt\n	render :text => "${1:text to render}"\nsnippet rtl\n	render :text => "${1:text to render}", :layout => "${2:layoutname}"\nsnippet rtlt\n	render :text => "${1:text to render}", :layout => ${2:true}\nsnippet rts\n	render :text => "${1:text to render}", :status => ${2:401}\nsnippet ru\n	render :update do |${1:page}|\n		$1.${2}\n	end\nsnippet rxml\n	render :xml => ${1:text to render}\nsnippet sc\n	scope :${1:name}, :where(:@${2:field} => ${3:value})\nsnippet sl\n	scope :${1:name}, lambda do |${2:value}|\n		where("${3:field = ?}", ${4:bind var})\n	end\nsnippet sha1\n	Digest::SHA1.hexdigest(${1:string})\nsnippet sweeper\n	class ${1:ModelClassName}Sweeper < ActionController::Caching::Sweeper\n		observe $1\n\n		def after_save(${2:model_class_name})\n			expire_cache($2)\n		end\n\n		def after_destroy($2)\n			expire_cache($2)\n		end\n\n		def expire_cache($2)\n			expire_page\n		end\n	end\nsnippet tcb\n	t.boolean :${1:title}\n	${2}\nsnippet tcbi\n	t.binary :${1:title}, :limit => ${2:2}.megabytes\n	${3}\nsnippet tcd\n	t.decimal :${1:title}, :precision => ${2:10}, :scale => ${3:2}\n	${4}\nsnippet tcda\n	t.date :${1:title}\n	${2}\nsnippet tcdt\n	t.datetime :${1:title}\n	${2}\nsnippet tcf\n	t.float :${1:title}\n	${2}\nsnippet tch\n	t.change :${1:name}, :${2:string}, :${3:limit} => ${4:80}\n	${5}\nsnippet tci\n	t.integer :${1:title}\n	${2}\nsnippet tcl\n	t.integer :lock_version, :null => false, :default => 0\n	${1}\nsnippet tcr\n	t.references :${1:taggable}, :polymorphic => { :default => \'${2:Photo}\' }\n	${3}\nsnippet tcs\n	t.string :${1:title}\n	${2}\nsnippet tct\n	t.text :${1:title}\n	${2}\nsnippet tcti\n	t.time :${1:title}\n	${2}\nsnippet tcts\n	t.timestamp :${1:title}\n	${2}\nsnippet tctss\n	t.timestamps\n	${1}\nsnippet va\n	validates_associated :${1:attribute}\nsnippet vao\n	validates_acceptance_of :${1:terms}\nsnippet vc\n	validates_confirmation_of :${1:attribute}\nsnippet ve\n	validates_exclusion_of :${1:attribute}, :in => ${2:%w( mov avi )}\nsnippet vf\n	validates_format_of :${1:attribute}, :with => /${2:regex}/\nsnippet vi\n	validates_inclusion_of :${1:attribute}, :in => %w(${2: mov avi })\nsnippet vl\n	validates_length_of :${1:attribute}, :within => ${2:3}..${3:20}\nsnippet vn\n	validates_numericality_of :${1:attribute}\nsnippet vpo\n	validates_presence_of :${1:attribute}\nsnippet vu\n	validates_uniqueness_of :${1:attribute}\nsnippet wants\n	wants.${1:js|xml|html} { ${2} }\nsnippet wc\n	where(${1:"conditions"}${2:, bind_var})\nsnippet wh\n	where(${1:field} => ${2:value})\nsnippet xdelete\n	xhr :delete, :${1:destroy}, :id => ${2:1}${3}\nsnippet xget\n	xhr :get, :${1:show}, :id => ${2:1}${3}\nsnippet xpost\n	xhr :post, :${1:create}, :${2:object} => { ${3} }\nsnippet xput\n	xhr :put, :${1:update}, :id => ${2:1}, :${3:object} => { ${4} }${5}\nsnippet test\n	test "should ${1:do something}" do\n		${2}\n	end\n#migrations\nsnippet mac\n	add_column :${1:table_name}, :${2:column_name}, :${3:data_type}\nsnippet mrc\n	remove_column :${1:table_name}, :${2:column_name}\nsnippet mrnc\n	rename_column :${1:table_name}, :${2:old_column_name}, :${3:new_column_name}\nsnippet mcc\n	change_column :${1:table}, :${2:column}, :${3:type}\nsnippet mccc\n	t.column :${1:title}, :${2:string}\nsnippet mct\n	create_table :${1:table_name} do |t|\n		t.column :${2:name}, :${3:type}\n	end\nsnippet migration\n	class ${1:class_name} < ActiveRecord::Migration\n		def self.up\n			${2}\n		end\n\n		def self.down\n		end\n	end\n\nsnippet trc\n	t.remove :${1:column}\nsnippet tre\n	t.rename :${1:old_column_name}, :${2:new_column_name}\n	${3}\nsnippet tref\n	t.references :${1:model}\n\n#rspec\nsnippet it\n	it "${1:spec_name}" do\n		${2}\n	end\nsnippet itp\n	it "${1:spec_name}"\n	${2}\nsnippet desc\n	describe ${1:class_name} do\n		${2}\n	end\nsnippet cont\n	context "${1:message}" do\n		${2}\n	end\nsnippet bef\n	before :${1:each} do\n		${2}\n	end\nsnippet aft\n	after :${1:each} do\n		${2}\n	end\n',t.scope="ruby"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/rust.js b/dist/assets/js/vendor/ace-nc/snippets/rust.js
            new file mode 100644
            index 0000000000..d30d87eb83
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/rust.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/rust",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="rust"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/sass.js b/dist/assets/js/vendor/ace-nc/snippets/sass.js
            new file mode 100644
            index 0000000000..ccfde2c940
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/sass.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/sass",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="sass"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/scad.js b/dist/assets/js/vendor/ace-nc/snippets/scad.js
            new file mode 100644
            index 0000000000..9a4fcb0052
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/scad.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/scad",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="scad"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/scala.js b/dist/assets/js/vendor/ace-nc/snippets/scala.js
            new file mode 100644
            index 0000000000..dbbc7f4817
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/scala.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/scala",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="scala"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/scheme.js b/dist/assets/js/vendor/ace-nc/snippets/scheme.js
            new file mode 100644
            index 0000000000..d8770f2d40
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/scheme.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/scheme",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="scheme"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/scss.js b/dist/assets/js/vendor/ace-nc/snippets/scss.js
            new file mode 100644
            index 0000000000..0526c69cc1
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/scss.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/scss",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="scss"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/sh.js b/dist/assets/js/vendor/ace-nc/snippets/sh.js
            new file mode 100644
            index 0000000000..3871076853
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/sh.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/sh",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# Shebang. Executing bash via /usr/bin/env makes scripts more portable.\nsnippet #!\n	#!/usr/bin/env bash\n	\nsnippet if\n	if [[ ${1:condition} ]]; then\n		${2:#statements}\n	fi\nsnippet elif\n	elif [[ ${1:condition} ]]; then\n		${2:#statements}\nsnippet for\n	for (( ${2:i} = 0; $2 < ${1:count}; $2++ )); do\n		${3:#statements}\n	done\nsnippet fori\n	for ${1:needle} in ${2:haystack} ; do\n		${3:#statements}\n	done\nsnippet wh\n	while [[ ${1:condition} ]]; do\n		${2:#statements}\n	done\nsnippet until\n	until [[ ${1:condition} ]]; do\n		${2:#statements}\n	done\nsnippet case\n	case ${1:word} in\n		${2:pattern})\n			${3};;\n	esac\nsnippet go \n	while getopts \'${1:o}\' ${2:opts} \n	do \n		case $$2 in\n		${3:o0})\n			${4:#staments};;\n		esac\n	done\n# Set SCRIPT_DIR variable to directory script is located.\nsnippet sdir\n	SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"\n# getopt\nsnippet getopt\n	__ScriptVersion="${1:version}"\n\n	#===  FUNCTION  ================================================================\n	#         NAME:  usage\n	#  DESCRIPTION:  Display usage information.\n	#===============================================================================\n	function usage ()\n	{\n			cat <<- EOT\n\n	  Usage :  $${0:0} [options] [--] \n\n	  Options: \n	  -h|help       Display this message\n	  -v|version    Display script version\n\n			EOT\n	}    # ----------  end of function usage  ----------\n\n	#-----------------------------------------------------------------------\n	#  Handle command line arguments\n	#-----------------------------------------------------------------------\n\n	while getopts ":hv" opt\n	do\n	  case $opt in\n\n		h|help     )  usage; exit 0   ;;\n\n		v|version  )  echo "$${0:0} -- Version $__ScriptVersion"; exit 0   ;;\n\n		\\? )  echo -e "\\n  Option does not exist : $OPTARG\\n"\n			  usage; exit 1   ;;\n\n	  esac    # --- end of case ---\n	done\n	shift $(($OPTIND-1))\n\n',t.scope="sh"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/sjs.js b/dist/assets/js/vendor/ace-nc/snippets/sjs.js
            new file mode 100644
            index 0000000000..8023e0dbff
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/sjs.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/sjs",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="sjs"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/smarty.js b/dist/assets/js/vendor/ace-nc/snippets/smarty.js
            new file mode 100644
            index 0000000000..5dc13d731b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/smarty.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/smarty",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="smarty"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/snippets.js b/dist/assets/js/vendor/ace-nc/snippets/snippets.js
            new file mode 100644
            index 0000000000..8f2d037da6
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/snippets.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/snippets",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="# snippets for making snippets :)\nsnippet snip\n	snippet ${1:trigger}\n		${2}\nsnippet msnip\n	snippet ${1:trigger} ${2:description}\n		${3}\nsnippet v\n	{VISUAL}\n",t.scope="snippets"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/soy_template.js b/dist/assets/js/vendor/ace-nc/snippets/soy_template.js
            new file mode 100644
            index 0000000000..710cee62d5
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/soy_template.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/soy_template",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="soy_template"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/space.js b/dist/assets/js/vendor/ace-nc/snippets/space.js
            new file mode 100644
            index 0000000000..8bc916be45
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/space.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/space",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="space"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/sql.js b/dist/assets/js/vendor/ace-nc/snippets/sql.js
            new file mode 100644
            index 0000000000..1bacce06d4
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/sql.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/sql",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="snippet tbl\n	create table ${1:table} (\n		${2:columns}\n	);\nsnippet col\n	${1:name}	${2:type}	${3:default ''}	${4:not null}\nsnippet ccol\n	${1:name}	varchar2(${2:size})	${3:default ''}	${4:not null}\nsnippet ncol\n	${1:name}	number	${3:default 0}	${4:not null}\nsnippet dcol\n	${1:name}	date	${3:default sysdate}	${4:not null}\nsnippet ind\n	create index ${3:$1_$2} on ${1:table}(${2:column});\nsnippet uind\n	create unique index ${1:name} on ${2:table}(${3:column});\nsnippet tblcom\n	comment on table ${1:table} is '${2:comment}';\nsnippet colcom\n	comment on column ${1:table}.${2:column} is '${3:comment}';\nsnippet addcol\n	alter table ${1:table} add (${2:column} ${3:type});\nsnippet seq\n	create sequence ${1:name} start with ${2:1} increment by ${3:1} minvalue ${4:1};\nsnippet s*\n	select * from ${1:table}\n",t.scope="sql"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/stylus.js b/dist/assets/js/vendor/ace-nc/snippets/stylus.js
            new file mode 100644
            index 0000000000..1da9d776aa
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/stylus.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/stylus",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="stylus"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/svg.js b/dist/assets/js/vendor/ace-nc/snippets/svg.js
            new file mode 100644
            index 0000000000..26d9b1a48d
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/svg.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/svg",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="svg"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/tcl.js b/dist/assets/js/vendor/ace-nc/snippets/tcl.js
            new file mode 100644
            index 0000000000..69ccc25944
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/tcl.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/tcl",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="# #!/usr/bin/env tclsh\nsnippet #!\n	#!/usr/bin/env tclsh\n	\n# Process\nsnippet pro\n	proc ${1:function_name} {${2:args}} {\n		${3:#body ...}\n	}\n#xif\nsnippet xif\n	${1:expr}? ${2:true} : ${3:false}\n# Conditional\nsnippet if\n	if {${1}} {\n		${2:# body...}\n	}\n# Conditional if..else\nsnippet ife\n	if {${1}} {\n		${2:# body...}\n	} else {\n		${3:# else...}\n	}\n# Conditional if..elsif..else\nsnippet ifee\n	if {${1}} {\n		${2:# body...}\n	} elseif {${3}} {\n		${4:# elsif...}\n	} else {\n		${5:# else...}\n	}\n# If catch then\nsnippet ifc\n	if { [catch {${1:#do something...}} ${2:err}] } {\n		${3:# handle failure...}\n	}\n# Catch\nsnippet catch\n	catch {${1}} ${2:err} ${3:options}\n# While Loop\nsnippet wh\n	while {${1}} {\n		${2:# body...}\n	}\n# For Loop\nsnippet for\n	for {set ${2:var} 0} {$$2 < ${1:count}} {${3:incr} $2} {\n		${4:# body...}\n	}\n# Foreach Loop\nsnippet fore\n	foreach ${1:x} {${2:#list}} {\n		${3:# body...}\n	}\n# after ms script...\nsnippet af\n	after ${1:ms} ${2:#do something}\n# after cancel id\nsnippet afc\n	after cancel ${1:id or script}\n# after idle\nsnippet afi\n	after idle ${1:script}\n# after info id\nsnippet afin\n	after info ${1:id}\n# Expr\nsnippet exp\n	expr {${1:#expression here}}\n# Switch\nsnippet sw\n	switch ${1:var} {\n		${3:pattern 1} {\n			${4:#do something}\n		}\n		default {\n			${2:#do something}\n		}\n	}\n# Case\nsnippet ca\n	${1:pattern} {\n		${2:#do something}\n	}${3}\n# Namespace eval\nsnippet ns\n	namespace eval ${1:path} {${2:#script...}}\n# Namespace current\nsnippet nsc\n	namespace current\n",t.scope="tcl"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/tex.js b/dist/assets/js/vendor/ace-nc/snippets/tex.js
            new file mode 100644
            index 0000000000..99d058ea71
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/tex.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/tex",["require","exports","module"],function(e,t,n){"use strict";t.snippetText="#PREAMBLE\n#newcommand\nsnippet nc\n	\\newcommand{\\${1:cmd}}[${2:opt}]{${3:realcmd}}${4}\n#usepackage\nsnippet up\n	\\usepackage[${1:[options}]{${2:package}}\n#newunicodechar\nsnippet nuc\n	\\newunicodechar{${1}}{${2:\\ensuremath}${3:tex-substitute}}}\n#DeclareMathOperator\nsnippet dmo\n	\\DeclareMathOperator{${1}}{${2}}\n\n#DOCUMENT\n# \\begin{}...\\end{}\nsnippet begin\n	\\begin{${1:env}}\n		${2}\n	\\end{$1}\n# Tabular\nsnippet tab\n	\\begin{${1:tabular}}{${2:c}}\n	${3}\n	\\end{$1}\nsnippet thm\n	\\begin[${1:author}]{${2:thm}}\n	${3}\n	\\end{$1}\nsnippet center\n	\\begin{center}\n		${1}\n	\\end{center}\n# Align(ed)\nsnippet ali\n	\\begin{align${1:ed}}\n		${2}\n	\\end{align$1}\n# Gather(ed)\nsnippet gat\n	\\begin{gather${1:ed}}\n		${2}\n	\\end{gather$1}\n# Equation\nsnippet eq\n	\\begin{equation}\n		${1}\n	\\end{equation}\n# Equation\nsnippet eq*\n	\\begin{equation*}\n		${1}\n	\\end{equation*}\n# Unnumbered Equation\nsnippet \\\n	\\[\n		${1}\n	\\]\n# Enumerate\nsnippet enum\n	\\begin{enumerate}\n		\\item ${1}\n	\\end{enumerate}\n# Itemize\nsnippet itemize\n	\\begin{itemize}\n		\\item ${1}\n	\\end{itemize}\n# Description\nsnippet desc\n	\\begin{description}\n		\\item[${1}] ${2}\n	\\end{description}\n# Matrix\nsnippet mat\n	\\begin{${1:p/b/v/V/B/small}matrix}\n		${2}\n	\\end{$1matrix}\n# Cases\nsnippet cas\n	\\begin{cases}\n		${1:equation}, &\\text{ if }${2:case}\\\\\n		${3}\n	\\end{cases}\n# Split\nsnippet spl\n	\\begin{split}\n		${1}\n	\\end{split}\n# Part\nsnippet part\n	\\part{${1:part name}} % (fold)\n	\\label{prt:${2:$1}}\n	${3}\n	% part $2 (end)\n# Chapter\nsnippet cha\n	\\chapter{${1:chapter name}}\n	\\label{cha:${2:$1}}\n	${3}\n# Section\nsnippet sec\n	\\section{${1:section name}}\n	\\label{sec:${2:$1}}\n	${3}\n# Sub Section\nsnippet sub\n	\\subsection{${1:subsection name}}\n	\\label{sub:${2:$1}}\n	${3}\n# Sub Sub Section\nsnippet subs\n	\\subsubsection{${1:subsubsection name}}\n	\\label{ssub:${2:$1}}\n	${3}\n# Paragraph\nsnippet par\n	\\paragraph{${1:paragraph name}}\n	\\label{par:${2:$1}}\n	${3}\n# Sub Paragraph\nsnippet subp\n	\\subparagraph{${1:subparagraph name}}\n	\\label{subp:${2:$1}}\n	${3}\n#References\nsnippet itd\n	\\item[${1:description}] ${2:item}\nsnippet figure\n	${1:Figure}~\\ref{${2:fig:}}${3}\nsnippet table\n	${1:Table}~\\ref{${2:tab:}}${3}\nsnippet listing\n	${1:Listing}~\\ref{${2:list}}${3}\nsnippet section\n	${1:Section}~\\ref{${2:sec:}}${3}\nsnippet page\n	${1:page}~\\pageref{${2}}${3}\nsnippet index\n	\\index{${1:index}}${2}\n#Citations\nsnippet cite\n	\\cite[${1}]{${2}}${3}\nsnippet fcite\n	\\footcite[${1}]{${2}}${3}\n#Formating text: italic, bold, underline, small capital, emphase ..\nsnippet it\n	\\textit{${1:text}}\nsnippet bf\n	\\textbf{${1:text}}\nsnippet under\n	\\underline{${1:text}}\nsnippet emp\n	\\emph{${1:text}}\nsnippet sc\n	\\textsc{${1:text}}\n#Choosing font\nsnippet sf\n	\\textsf{${1:text}}\nsnippet rm\n	\\textrm{${1:text}}\nsnippet tt\n	\\texttt{${1:text}}\n#misc\nsnippet ft\n	\\footnote{${1:text}}\nsnippet fig\n	\\begin{figure}\n	\\begin{center}\n	    \\includegraphics[scale=${1}]{Figures/${2}}\n	\\end{center}\n	\\caption{${3}}\n	\\label{fig:${4}}\n	\\end{figure}\nsnippet tikz\n	\\begin{figure}\n	\\begin{center}\n	\\begin{tikzpicture}[scale=${1:1}]\n		${2}\n	\\end{tikzpicture}\n	\\end{center}\n	\\caption{${3}}\n	\\label{fig:${4}}\n	\\end{figure}\n#math\nsnippet stackrel\n	\\stackrel{${1:above}}{${2:below}} ${3}\nsnippet frac\n	\\frac{${1:num}}{${2:denom}}\nsnippet sum\n	\\sum^{${1:n}}_{${2:i=1}}{${3}}",t.scope="tex"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/text.js b/dist/assets/js/vendor/ace-nc/snippets/text.js
            new file mode 100644
            index 0000000000..233803daeb
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/text.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/text",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="text"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/textile.js b/dist/assets/js/vendor/ace-nc/snippets/textile.js
            new file mode 100644
            index 0000000000..cf4d5d566b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/textile.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/textile",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# Jekyll post header\nsnippet header\n	---\n	title: ${1:title}\n	layout: post\n	date: ${2:date} ${3:hour:minute:second} -05:00\n	---\n\n# Image\nsnippet img\n	!${1:url}(${2:title}):${3:link}!\n\n# Table\nsnippet |\n	|${1}|${2}\n\n# Link\nsnippet link\n	"${1:link text}":${2:url}\n\n# Acronym\nsnippet (\n	(${1:Expand acronym})${2}\n\n# Footnote\nsnippet fn\n	[${1:ref number}] ${3}\n\n	fn$1. ${2:footnote}\n	\n',t.scope="textile"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/toml.js b/dist/assets/js/vendor/ace-nc/snippets/toml.js
            new file mode 100644
            index 0000000000..8c3dbefdf5
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/toml.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/toml",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="toml"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/twig.js b/dist/assets/js/vendor/ace-nc/snippets/twig.js
            new file mode 100644
            index 0000000000..9c21046820
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/twig.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/twig",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="twig"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/typescript.js b/dist/assets/js/vendor/ace-nc/snippets/typescript.js
            new file mode 100644
            index 0000000000..5e6425ecbf
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/typescript.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/typescript",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="typescript"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/vala.js b/dist/assets/js/vendor/ace-nc/snippets/vala.js
            new file mode 100644
            index 0000000000..89927bcfbd
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/vala.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/vala",["require","exports","module"],function(e,t,n){"use strict";t.snippets=[{content:"case ${1:condition}:\n	$0\n	break;\n",name:"case",scope:"vala",tabTrigger:"case"},{content:"/**\n * ${6}\n */\n${1:public} class ${2:MethodName}${3: : GLib.Object} {\n\n	/**\n	 * ${7}\n	 */\n	public ${2}(${4}) {\n		${5}\n	}\n\n	$0\n}",name:"class",scope:"vala",tabTrigger:"class"},{content:"(${1}) => {\n	${0}\n}\n",name:"closure",scope:"vala",tabTrigger:"=>"},{content:"/*\n * $0\n */",name:"Comment (multiline)",scope:"vala",tabTrigger:"/*"},{content:"Console.WriteLine($1);\n$0",name:"Console.WriteLine (writeline)",scope:"vala",tabTrigger:"writeline"},{content:'[DBus(name = "$0")]',name:"DBus annotation",scope:"vala",tabTrigger:"[DBus"},{content:"delegate ${1:void} ${2:DelegateName}($0);",name:"delegate",scope:"vala",tabTrigger:"delegate"},{content:"do {\n	$0\n} while ($1);\n",name:"do while",scope:"vala",tabTrigger:"dowhile"},{content:"/**\n * $0\n */",name:"DocBlock",scope:"vala",tabTrigger:"/**"},{content:"else if ($1) {\n	$0\n}\n",name:"else if (elseif)",scope:"vala",tabTrigger:"elseif"},{content:"else {\n	$0\n}",name:"else",scope:"vala",tabTrigger:"else"},{content:"enum {$1:EnumName} {\n	$0\n}",name:"enum",scope:"vala",tabTrigger:"enum"},{content:"public errordomain ${1:Error} {\n	$0\n}",name:"error domain",scope:"vala",tabTrigger:"errordomain"},{content:"for ($1;$2;$3) {\n	$0\n}",name:"for",scope:"vala",tabTrigger:"for"},{content:"foreach ($1 in $2) {\n	$0\n}",name:"foreach",scope:"vala",tabTrigger:"foreach"},{content:"Gee.ArrayList<${1:G}>($0);",name:"Gee.ArrayList",scope:"vala",tabTrigger:"ArrayList"},{content:"Gee.HashMap<${1:K},${2:V}>($0);",name:"Gee.HashMap",scope:"vala",tabTrigger:"HashMap"},{content:"Gee.HashSet<${1:G}>($0);",name:"Gee.HashSet",scope:"vala",tabTrigger:"HashSet"},{content:"if ($1) {\n	$0\n}",name:"if",scope:"vala",tabTrigger:"if"},{content:"interface ${1:InterfaceName}{$2: : SuperInterface} {\n	$0\n}",name:"interface",scope:"vala",tabTrigger:"interface"},{content:"public static int main(string [] argv) {\n	${0}\n	return 0;\n}",name:"Main function",scope:"vala",tabTrigger:"main"},{content:"namespace $1 {\n	$0\n}\n",name:"namespace (ns)",scope:"vala",tabTrigger:"ns"},{content:"stdout.printf($0);",name:"printf",scope:"vala",tabTrigger:"printf"},{content:"${1:public} ${2:Type} ${3:Name} {\n	set {\n		$0\n	}\n	get {\n\n	}\n}",name:"property (prop)",scope:"vala",tabTrigger:"prop"},{content:"${1:public} ${2:Type} ${3:Name} {\n	get {\n		$0\n	}\n}",name:"read-only property (roprop)",scope:"vala",tabTrigger:"roprop"},{content:'@"${1:\\$var}"',name:"String template (@)",scope:"vala",tabTrigger:"@"},{content:"struct ${1:StructName} {\n	$0\n}",name:"struct",scope:"vala",tabTrigger:"struct"},{content:"switch ($1) {\n	$0\n}",name:"switch",scope:"vala",tabTrigger:"switch"},{content:"try {\n	$2\n} catch (${1:Error} e) {\n	$0\n}",name:"try/catch",scope:"vala",tabTrigger:"try"},{content:'"""$0""";',name:'Verbatim string (""")',scope:"vala",tabTrigger:"verbatim"},{content:"while ($1) {\n	$0\n}",name:"while",scope:"vala",tabTrigger:"while"}],t.scope=""})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/vbscript.js b/dist/assets/js/vendor/ace-nc/snippets/vbscript.js
            new file mode 100644
            index 0000000000..1cf30b9420
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/vbscript.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/vbscript",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="vbscript"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/velocity.js b/dist/assets/js/vendor/ace-nc/snippets/velocity.js
            new file mode 100644
            index 0000000000..9ab7789cbd
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/velocity.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/velocity",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='# macro\nsnippet #macro\n	#macro ( ${1:macroName} ${2:\\$var1, [\\$var2, ...]} )\n		${3:## macro code}\n	#end\n# foreach\nsnippet #foreach\n	#foreach ( ${1:\\$item} in ${2:\\$collection} )\n		${3:## foreach code}\n	#end\n# if\nsnippet #if\n	#if ( ${1:true} )\n		${0}\n	#end\n# if ... else\nsnippet #ife\n	#if ( ${1:true} )\n		${2}\n	#else\n		${0}\n	#end\n#import\nsnippet #import\n	#import ( "${1:path/to/velocity/format}" )\n# set\nsnippet #set\n	#set ( $${1:var} = ${0} )\n',t.scope="velocity",t.includeScopes=["html","javascript","css"]})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/verilog.js b/dist/assets/js/vendor/ace-nc/snippets/verilog.js
            new file mode 100644
            index 0000000000..2c6f906cf4
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/verilog.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/verilog",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="verilog"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/vhdl.js b/dist/assets/js/vendor/ace-nc/snippets/vhdl.js
            new file mode 100644
            index 0000000000..c8d6fb904b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/vhdl.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/vhdl",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="vhdl"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/xml.js b/dist/assets/js/vendor/ace-nc/snippets/xml.js
            new file mode 100644
            index 0000000000..e1c1b3941b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/xml.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/xml",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="xml"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/xquery.js b/dist/assets/js/vendor/ace-nc/snippets/xquery.js
            new file mode 100644
            index 0000000000..ea0f7edeca
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/xquery.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/xquery",["require","exports","module"],function(e,t,n){"use strict";t.snippetText='snippet for\n	for $${1:item} in ${2:expr}\nsnippet return\n	return ${1:expr}\nsnippet import\n	import module namespace ${1:ns} = "${2:http://www.example.com/}";\nsnippet some\n	some $${1:varname} in ${2:expr} satisfies ${3:expr}\nsnippet every\n	every $${1:varname} in ${2:expr} satisfies ${3:expr}\nsnippet if\n	if(${1:true}) then ${2:expr} else ${3:true}\nsnippet switch\n	switch(${1:"foo"})\n	case ${2:"foo"}\n	return ${3:true}\n	default return ${4:false}\nsnippet try\n	try { ${1:expr} } catch ${2:*} { ${3:expr} }\nsnippet tumbling\n	for tumbling window $${1:varname} in ${2:expr}\n	start at $${3:start} when ${4:expr}\n	end at $${5:end} when ${6:expr}\n	return ${7:expr}\nsnippet sliding\n	for sliding window $${1:varname} in ${2:expr}\n	start at $${3:start} when ${4:expr}\n	end at $${5:end} when ${6:expr}\n	return ${7:expr}\nsnippet let\n	let $${1:varname} := ${2:expr}\nsnippet group\n	group by $${1:varname} := ${2:expr}\nsnippet order\n	order by ${1:expr} ${2:descending}\nsnippet stable\n	stable order by ${1:expr}\nsnippet count\n	count $${1:varname}\nsnippet ordered\n	ordered { ${1:expr} }\nsnippet unordered\n	unordered { ${1:expr} }\nsnippet treat \n	treat as ${1:expr}\nsnippet castable\n	castable as ${1:atomicType}\nsnippet cast\n	cast as ${1:atomicType}\nsnippet typeswitch\n	typeswitch(${1:expr})\n	case ${2:type}  return ${3:expr}\n	default return ${4:expr}\nsnippet var\n	declare variable $${1:varname} := ${2:expr};\nsnippet fn\n	declare function ${1:ns}:${2:name}(){\n	${3:expr}\n	};\nsnippet module\n	module namespace ${1:ns} = "${2:http://www.example.com}";\n',t.scope="xquery"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/snippets/yaml.js b/dist/assets/js/vendor/ace-nc/snippets/yaml.js
            new file mode 100644
            index 0000000000..80b5d3b36f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/snippets/yaml.js
            @@ -0,0 +1 @@
            +ace.define("ace/snippets/yaml",["require","exports","module"],function(e,t,n){"use strict";t.snippetText=undefined,t.scope="yaml"})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-ambiance.js b/dist/assets/js/vendor/ace-nc/theme-ambiance.js
            new file mode 100644
            index 0000000000..e7c0b6b049
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-ambiance.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/ambiance",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-ambiance",t.cssText=".ace-ambiance .ace_gutter {background-color: #3d3d3d;background-image: -moz-linear-gradient(left, #3D3D3D, #333);background-image: -ms-linear-gradient(left, #3D3D3D, #333);background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#3D3D3D), to(#333));background-image: -webkit-linear-gradient(left, #3D3D3D, #333);background-image: -o-linear-gradient(left, #3D3D3D, #333);background-image: linear-gradient(left, #3D3D3D, #333);background-repeat: repeat-x;border-right: 1px solid #4d4d4d;text-shadow: 0px 1px 1px #4d4d4d;color: #222;}.ace-ambiance .ace_gutter-layer {background: repeat left top;}.ace-ambiance .ace_gutter-active-line {background-color: #3F3F3F;}.ace-ambiance .ace_fold-widget {text-align: center;}.ace-ambiance .ace_fold-widget:hover {color: #777;}.ace-ambiance .ace_fold-widget.ace_start,.ace-ambiance .ace_fold-widget.ace_end,.ace-ambiance .ace_fold-widget.ace_closed{background: none;border: none;box-shadow: none;}.ace-ambiance .ace_fold-widget.ace_start:after {content: '\u25be'}.ace-ambiance .ace_fold-widget.ace_end:after {content: '\u25b4'}.ace-ambiance .ace_fold-widget.ace_closed:after {content: '\u2023'}.ace-ambiance .ace_print-margin {border-left: 1px dotted #2D2D2D;right: 0;background: #262626;}.ace-ambiance .ace_scroller {-webkit-box-shadow: inset 0 0 10px black;-moz-box-shadow: inset 0 0 10px black;-o-box-shadow: inset 0 0 10px black;box-shadow: inset 0 0 10px black;}.ace-ambiance {color: #E6E1DC;background-color: #202020;}.ace-ambiance .ace_cursor {border-left: 1px solid #7991E8;}.ace-ambiance .ace_overwrite-cursors .ace_cursor {border: 1px solid #FFE300;background: #766B13;}.ace-ambiance.normal-mode .ace_cursor-layer {z-index: 0;}.ace-ambiance .ace_marker-layer .ace_selection {background: rgba(221, 240, 255, 0.20);}.ace-ambiance .ace_marker-layer .ace_selected-word {border-radius: 4px;border: 8px solid #3f475d;box-shadow: 0 0 4px black;}.ace-ambiance .ace_marker-layer .ace_step {background: rgb(198, 219, 174);}.ace-ambiance .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(255, 255, 255, 0.25);}.ace-ambiance .ace_marker-layer .ace_active-line {background: rgba(255, 255, 255, 0.031);}.ace-ambiance .ace_invisible {color: #333;}.ace-ambiance .ace_paren {color: #24C2C7;}.ace-ambiance .ace_keyword {color: #cda869;}.ace-ambiance .ace_keyword.ace_operator {color: #fa8d6a;}.ace-ambiance .ace_punctuation.ace_operator {color: #fa8d6a;}.ace-ambiance .ace_identifier {}.ace-ambiance .ace-statement {color: #cda869;}.ace-ambiance .ace_constant {color: #CF7EA9;}.ace-ambiance .ace_constant.ace_language {color: #CF7EA9;}.ace-ambiance .ace_constant.ace_library {}.ace-ambiance .ace_constant.ace_numeric {color: #78CF8A;}.ace-ambiance .ace_invalid {text-decoration: underline;}.ace-ambiance .ace_invalid.ace_illegal {color:#F8F8F8;background-color: rgba(86, 45, 86, 0.75);}.ace-ambiance .ace_invalid,.ace-ambiance .ace_deprecated {text-decoration: underline;font-style: italic;color: #D2A8A1;}.ace-ambiance .ace_support {color: #9B859D;}.ace-ambiance .ace_support.ace_function {color: #DAD085;}.ace-ambiance .ace_function.ace_buildin {color: #9b859d;}.ace-ambiance .ace_string {color: #8f9d6a;}.ace-ambiance .ace_string.ace_regexp {color: #DAD085;}.ace-ambiance .ace_comment {font-style: italic;color: #555;}.ace-ambiance .ace_comment.ace_doc {}.ace-ambiance .ace_comment.ace_doc.ace_tag {color: #666;font-style: normal;}.ace-ambiance .ace_definition,.ace-ambiance .ace_type {color: #aac6e3;}.ace-ambiance .ace_variable {color: #9999cc;}.ace-ambiance .ace_variable.ace_language {color: #9b859d;}.ace-ambiance .ace_xml-pe {color: #494949;}.ace-ambiance .ace_gutter-layer,.ace-ambiance .ace_text-layer {background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAQAAAAHUWYVAABFFUlEQVQYGbzBCeDVU/74/6fj9HIcx/FRHx9JCFmzMyGRURhLZIkUsoeRfUjS2FNDtr6WkMhO9sm+S8maJfu+Jcsg+/o/c+Z4z/t97/vezy3z+z8ekGlnYICG/o7gdk+wmSHZ1z4pJItqapjoKXWahm8NmV6eOTbWUOp6/6a/XIg6GQqmenJ2lDHyvCFZ2cBDbmtHA043VFhHwXxClWmeYAdLhV00Bd85go8VmaFCkbVkzlQENzfBDZ5gtN7HwF0KDrTwJ0dypSOzpaKCMwQHKTIreYIxlmhXTzTWkVm+LTynZhiSBT3RZQ7aGfjGEd3qyXQ1FDymqbKxpspERQN2MiRjNZlFFQXfCNFm9nM1zpAsoYjmtRTc5ajwuaXc5xrWskT97RaKzAGe5ARHhVUsDbjKklziiX5WROcJwSNCNI+9w1Jwv4Zb2r7lCMZ4oq5C0EdTx+2GzNuKpJ+iFf38JEWkHJn9DNF7mmBDITrWEg0VWL3pHU20tSZnuqWu+R3BtYa8XxV1HO7GyD32UkOpL/yDloINFTmvtId+nmAjxRw40VMwVKiwrKLE4bK5UOVntYwhOcSSXKrJHKPJedocpGjVz/ZMIbnYUPB10/eKCrs5apqpgVmWzBYWpmtKHecJPjaUuEgRDDaU0oZghCJ6zNMQ5ZhDYx05r5v2muQdM0EILtXUsaKiQX9WMEUotagQzFbUNN6NUPC2nm5pxEWGCjMc3GdJHjSU2kORLK/JGSrkfGEIjncU/CYUnOipoYemwj8tST9NsJmB7TUVXtbUtXATJVZXBMvYeTXJfobgJUPmGMP/yFaWonaa6BcFO3nqcIqCozSZoZoSr1g4zJOzuyGnxTEX3lUEJ7WcZgme8ddaWvWJo2AJR9DZU3CUIbhCSG6ybSwN6qtJVnCU2svDTP2ZInOw2cBTrqtQahtNZn9NcJ4l2NaSmSkkP1noZWnVwkLmdUPOwLZEwy2Z3S3R+4rIG9hcbpPXHFVWcQdZkn2FOta3cKWQnNRC5g1LsJah4GCzSVsKnCOY5OAFRTBekyyryeyilhFKva75r4Mc0aWanGEaThcy31s439KKxTzJYY5WTHPU1FtIHjQU3Oip4xlNzj/lBw23dYZVliQa7WAXf4shetcQfatI+jWRDBPmyNeW6A1P5kdDgyYJlba0BIM8BZu1JfrFwItyjcAMR3K0BWOIrtMEXyhyrlVEx3ui5dUBjmB/Q3CXW85R4mBD0s7B+4q5tKUjOlb9qqmhi5AZ6GFIC5HXtOobdYGlVdMVbNJ8toNTFcHxnoL+muBagcctjWnbNMuR00uI7nQESwg5q2qqrKWIfrNUmeQocY6HuyxJV02wj36w00yhpmUFenv4p6fUkZYqLyuinx2RGOjhCXYyJF84oiU00YMOOhhquNdfbOB7gU88pY4xJO8LVdp6/q2voeB4R04vIdhSE40xZObx1HGGJ/ja0LBthFInKaLPPFzuCaYaoj8JjPME8yoyxo6zlBqkiUZYgq00OYMswbWO5NGmq+xhipxHLRW29ARjNKXO0wRnear8XSg4XFPLKEPUS1GqvyLwiuBUoa7zpZ0l5xxFwWmWZC1H5h5FwU8eQ7K+g8UcVY6TMQreVQT/8uQ8Z+ALIXnSEa2pYZQneE9RZbSBNYXfWYJzW/h/4j4Dp1tYVcFIC5019Vyi4ThPqSFCzjGWaHQTBU8q6vrVwgxP9Lkm840imWKpcLCjYTtrKuwvsKSnrvHCXGkSMk9p6lhckfRpIeis+N2PiszT+mFLspyGleUhDwcLrZqmyeylxwjBcKHEapqkmyangyLZRVOijwOtCY5SsG5zL0OwlCJ4y5KznF3EUNDDrinwiyLZRzOXtlBbK5ITHFGLp8Q0R6ab6mS7enI2cFrxOyHvOCFaT1HThS1krjCwqWeurCkk+willhCC+RSZnRXBiZaC5RXRIZYKp2lyfrHwiKPKR0JDzrdU2EFgpidawlFDR6FgXUMNa+g1FY3bUQh2cLCwosRdnuQTS/S+JVrGLeWIvtQUvONJxlqSQYYKpwoN2kaocLjdVsis4Mk80ESF2YpSkzwldjHkjFCUutI/r+EHDU8oCs6yzL3PhWiEooZdFMkymlas4AcI3KmoMMNSQ3tHzjGWCrcJJdYyZC7QFGwjRL9p+MrRkAGWzIaWCn9W0F3TsK01c2ZvQw0byvxuQU0r1lM0qJO7wW0kRIMdDTtXEdzi4VIh+EoIHm0mWtAtpCixlabgn83fKTI7anJe9ST7WIK1DMGpQmYeA58ImV6ezOGOzK2Kgq01pd60cKWiUi9Lievb/0vIDPHQ05Kzt4ddPckQBQtoaurjyHnek/nKzpQLrVgKPjIkh2v4uyezpv+Xoo7fPFXaGFp1vaLKxQ4uUpQQS5VuQs7BCq4xRJv7fwpVvvFEB3j+620haOuocqMhWd6TTPAEx+mdFNGHdranFe95WrWmIvlY4F1Dle2ECgc6cto7SryuqGGGha0tFQ5V53migUKmg6XKAo4qS3mik+0OZpAhOLeZKicacgaYcyx5hypYQE02ZA4xi/pNhOQxR4klNKyqacj+mpxnLTnnGSo85++3ZCZq6lrZkXlGEX3o+C9FieccJbZWVFjC0Yo1FZnJhoYMFoI1hEZ9r6hwg75HwzBNhbZCdJEfJwTPGzJvaKImw1yYX1HDAmpXR+ZJQ/SmgqMNVQb5vgamGwLtt7VwvP7Qk1xpiM5x5Cyv93E06MZmgs0Nya2azIKOYKCGBQQW97RmhKNKF02JZqHEJ4o58qp7X5EcZmc56trXEqzjCBZ1MFGR87Ql2tSTs6CGxS05PTzRQorkbw7aKoKXFDXsYW42VJih/q+FP2BdTzDTwVqOYB13liM50vG7wy28qagyuIXMeQI/Oqq8bcn5wJI50xH00CRntyfpL1T4hydYpoXgNiFzoIUTDZnLNRzh4TBHwbYGDvZkxmlyJloyr6tRihpeUG94GnKtIznREF0tzJG/OOr73JBcrSh1k6WuTprgLU+mnSGnv6Zge0NNz+kTDdH8nuAuTdJDCNb21LCiIuqlYbqGzT3RAoZofQfjFazkqeNWdYaGvYTM001EW2oKPvVk1ldUGSgUtHFwjKM1h9jnFcmy5lChoLNaQMGGDsYbKixlaMBmmsx1QjCfflwTfO/gckW0ruZ3jugKR3R5W9hGUWqCgxuFgsuaCHorotGKzGaeZB9DMsaTnKCpMtwTvOzhYk0rdrArKCqcaWmVk1+F372ur1YkKxgatI8Qfe1gIX9wE9FgS8ESmuABIXnRUbCapcKe+nO7slClSZFzpV/LkLncEb1qiO42fS3R855Su2mCLh62t1SYZZYVmKwIHjREF2uihTzB20JOkz7dkxzYQnK0UOU494wh+VWRc6Un2kpTaVgLDFEkJ/uhzRcI0YKGgpGWOlocBU/a4fKoJ/pEaNV6jip3+Es9VXY078rGnmAdf7t9ylPXS34RBSuYPs1UecZTU78WanhBCHpZ5sAoTz0LGZKjPf9TRypqWEiTvOFglL1fCEY3wY/++rbk7C8bWebA6p6om6PgOL2kp44TFJlVNBXae2rqqdZztOJpT87GQsE9jqCPIe9VReZuQ/CIgacsyZdCpIScSYqcZk8r+nsyCzhyfhOqHGOIvrLknC8wTpFcaYiGC/RU1NRbUeUpocQOnkRpGOrIOcNRx+1uA0UrzhSSt+VyS3SJpnFWkzNDqOFGIWcfR86DnmARTQ1HKIL33ExPiemeOhYSSjzlSUZZuE4TveoJLnBUOFof6KiysCbnAEcZgcUNTDOwkqWu3RWtmGpZwlHhJENdZ3miGz0lJlsKnjbwqSHQjpxnFDlTLLwqJPMZMjd7KrzkSG7VsxXBZE+F8YZkb01Oe00yyRK9psh5SYh29ySPKBo2ylNht7ZkZnsKenjKNJu9PNEyZpaCHv4Kt6RQsLvAVp7M9kIimmCUwGeWqLMmGuIotYMmWNpSahkhZw9FqZsVnKJhsjAHvtHMsTM9fCI06Dx/u3vfUXCqfsKRc4oFY2jMsoo/7DJDwZ1CsIKnJu+J9ldkpmiCxQx1rWjI+T9FwcWWzOuaYH0Hj7klNRVWEQpmaqosakiGNTFHdjS/qnUdmf0NJW5xsL0HhimCCZZSRzmSPTXJQ4aaztAwtZnoabebJ+htCaZ7Cm535ByoqXKbX1WRc4Eh2MkRXWzImVc96Cj4VdOKVxR84VdQsIUM8Psoou2byVHyZFuq7O8otbSQ2UAoeEWTudATLGSpZzVLlXVkPU2Jc+27lsw2jmg5T5VhbeE3BT083K9WsTTkFU/Osi0rC5lRlpwRHUiesNS0sOvmqGML1aRbPAxTJD9ZKtxuob+hhl8cwYGWpJ8nub7t5p6coYbMovZ1BTdaKn1jYD6h4GFDNFyT/Kqe1XCXphXHOKLZmuRSRdBPEfVUXQzJm5YGPGGJdvAEr7hHNdGZnuBvrpciGmopOLf5N0uVMy0FfYToJk90uUCbJupaVpO53UJXR2bVpoU00V2KOo4zMFrBd0Jtz2pa0clT5Q5L8IpQ177mWQejPMEJhuQjS10ref6HHjdEhy1P1EYR7GtO0uSsKJQYLiTnG1rVScj5lyazpqWGl5uBbRWl7m6ixGOOnEsMJR7z8J0n6KMnCdxhiNYQCoZ6CmYLnO8omC3MkW3bktlPmEt/VQQHejL3+dOE5FlPdK/Mq8hZxxJtLyRrepLThYKbLZxkSb5W52vYxNOaOxUF0yxMUPwBTYqCzy01XayYK0sJyWBLqX0MwU5CzoymRzV0EjjeUeLgDpTo6ij42ZAzvD01dHUUTPLU96MdLbBME8nFBn7zJCMtJcZokn8YoqU0FS5WFKyniHobguMcmW8N0XkWZjkyN3hqOMtS08r+/xTBwpZSZ3qiVRX8SzMHHjfUNFjgHEPmY9PL3ykEzxkSre/1ZD6z/NuznuB0RcE1TWTm9zRgfUWVJiG6yrzgmWPXC8EAR4Wxhlad0ZbgQyEz3pG5RVEwwDJH2mgKpjcTiCOzn1lfUWANFbZ2BA8balnEweJC9J0iuaeZoI+ippFCztEKVvckR2iice1JvhVytrQwUAZpgsubCPaU7xUe9vWnaOpaSBEspalykhC9bUlOMpT42ZHca6hyrqKmw/wMR8H5ZmdFoBVJb03O4UL0tSNnvIeRmkrLWqrs78gcrEn2tpcboh0UPOW3UUR9PMk4T4nnNKWmCjlrefhCwxRNztfmIQVdDElvS4m1/WuOujoZCs5XVOjtKPGokJzsYCtFYoWonSPT21DheU/wWhM19FcElwqNGOsp9Q8N/cwXaiND1MmeL1Q5XROtYYgGeFq1aTMsoMmcrKjQrOFQTQ1fmBYhmW6o8Jkjc7iDJRTBIo5kgJD5yMEYA3srCg7VFKwiVJkmRCc5ohGOKhsYMn/XBLdo5taZjlb9YAlGWRimqbCsoY7HFAXLa5I1HPRxMMsQDHFkWtRNniqT9UEeNjcE7RUlrCJ4R2CSJuqlKHWvJXjAUNcITYkenuBRB84TbeepcqTj3zZyFJzgYQdHnqfgI0ddUwS6GqWpsKWhjq9cV0vBAEMN2znq+EBfIWT+pClYw5xsTlJU6GeIBsjGmmANTzJZiIYpgrM0Oa8ZMjd7NP87jxhqGOhJlnQtjuQpB+8aEE00wZFznSJPyHxgH3HkPOsJFvYk8zqCHzTs1BYOa4J3PFU+UVRZxlHDM4YavlNUuMoRveiZA2d7grMNc2g+RbSCEKzmgYsUmWmazFJyoiOZ4KnyhKOGRzWJa0+moyV4TVHDzn51Awtqaphfk/lRQ08FX1iiqxTB/kLwd0VynKfEvI6cd4XMV5bMhZ7gZUWVzYQ6Nm2BYzxJbw3bGthEUUMfgbGeorae6DxHtJoZ6alhZ0+ytiVoK1R4z5PTrOECT/SugseEOlb1MMNR4VRNcJy+V1Hg9ONClSZFZjdHlc6W6FBLdJja2MC5hhpu0DBYEY1TFGwiFAxRRCsYkiM9JRb0JNMVkW6CZYT/2EiTGWmo8k+h4FhDNE7BvppoTSFnmCV5xZKzvcCdDo7VVPnIU+I+Rc68juApC90MwcFCsJ5hDqxgScYKreruyQwTqrzoqDCmhWi4IbhB0Yrt3RGa6GfDv52rKXWhh28dyZaWUvcZeMTBaZoSGyiCtRU5J8iviioHaErs7Jkj61syVzTTgOcUOQ8buFBTYWdL5g3T4qlpe0+wvD63heAXRfCCIed9RbCsp2CiI7raUOYOTU13N8PNHvpaGvayo4a3LLT1lDrVEPT2zLUlheB1R+ZTRfKWJ+dcocLJfi11vyJ51lLqJ0WD7tRwryezjiV5W28uJO9qykzX8JDe2lHl/9oyBwa2UMfOngpXCixvKdXTk3wrsKmiVYdZIqsoWEERjbcUNDuiaQomGoIbFdEHmsyWnuR+IeriKDVLnlawlyNHKwKlSU631PKep8J4Q+ayjkSLKYLhalNHlYvttb6fHm0p6OApsZ4l2VfdqZkjuysy6ysKLlckf1KUutCTs39bmCgEyyoasIWlVaMF7mgmWtBT8Kol5xpH9IGllo8cJdopcvZ2sImlDmMIbtDk3KIpeNiS08lQw11NFPTwVFlPP6pJ2gvRfI7gQUfmNAtf6Gs0wQxDsKGlVBdF8rCa3jzdwMaGHOsItrZk7hAyOzpK9VS06j5F49b0VNGOOfKs3lDToMsMBe9ZWtHFEgxTJLs7qrygKZjUnmCYoeAqeU6jqWuLJup4WghOdvCYJnrSkSzoyRkm5M2StQwVltPkfCAk58tET/CSg+8MUecmotMEnhBKfWBIZsg2ihruMJQaoIm+tkTLKEqspMh00w95gvFCQRtDwTT1gVDDSEVdlwqZfxoQRbK0g+tbiBZxzKlpnpypejdDwTaeOvorMk/IJE10h9CqRe28hhLbe0pMsdSwv4ZbhKivo2BjDWfL8UKJgeavwlwb5KlwhyE4u4XkGE2ytZCznKLCDZZq42VzT8HLCrpruFbIfOIINmh/qCdZ1ZBc65kLHR1Bkyf5zn6pN3SvGKIlFNGplhrO9QSXanLOMQTLCa0YJCRrCZm/CZmrLTm7WzCK4GJDiWUdFeYx1LCFg3NMd0XmCuF3Y5rITLDUsYS9zoHVzwnJoYpSTQoObyEzr4cFBNqYTopoaU/wkyLZ2lPhX/5Y95ulxGTV7KjhWrOZgl8MyUUafjYraNjNU1N3IWcjT5WzWqjwtoarHSUObGYO3GCJZpsBlnJGPd6ZYLyl1GdCA2625IwwJDP8GUKymbzuyPlZlvTUsaUh5zFDhRWFzPKKZLAlWdcQbObgF9tOqOsmB1dqcqYJmWstFbZRRI9poolmqiLnU0POvxScpah2iSL5UJNzgScY5+AuIbpO0YD3NCW+dLMszFSdFCWGqG6eVq2uYVNDdICGD6W7EPRWZEY5gpsE9rUkS3mijzzJnm6UpUFXG1hCUeVoS5WfNcFpblELL2qqrCvMvRfd45oalvKU2tiQ6ePJOVMRXase9iTtLJztPxJKLWpo2CRDcJwn2sWSLKIO1WQWNTCvpVUvOZhgSC40JD0dOctaSqzkCRbXsKlb11Oip6PCJ0IwSJM31j3akRxlP7Rwn6aGaUL0qiLnJkvB3xWZ2+Q1TfCwpQH3G0o92UzmX4o/oJNQMMSQc547wVHhdk+VCw01DFYEnTxzZKAm74QmeNNR1w6WzEhNK15VJzuCdxQ53dRUDws5KvwgBMOEgpcVNe0hZI6RXT1Jd0cyj5nsaEAHgVmGaJIlWdsc5Ui2ElrRR6jrRAttNMEAIWrTDFubkZaok7/AkzfIwfuWVq0jHzuCK4QabtLUMVPB3kJ0oyHTSVFlqMALilJf2Rf8k5aaHtMfayocLBS8L89oKoxpJvnAkDPa0qp5DAUTHKWmCcnthlou8iCKaFFLHWcINd1nyIwXqrSxMNmSs6KmoL2QrKuWtlQ5V0120xQ5vRyZS1rgFkWwhiOwiuQbR0OOVhQM9iS3tiXp4RawRPMp5tDletOOBL95MpM01dZTBM9pkn5qF010rIeHFcFZhmSGpYpTsI6nwhqe5C9ynhlpp5ophuRb6WcJFldkVnVEwwxVfrVkvnWUuNLCg5bgboFHPDlDPDmnK7hUrWiIbjadDclujlZcaokOFup4Ri1kacV6jmrrK1hN9bGwpKEBQ4Q6DvIUXOmo6U5LqQM6EPyiKNjVkPnJkDPNEaxhiFay5ExW1NXVUGqcpYYdPcGiCq7z/TSlbhL4pplWXKd7NZO5QQFrefhRQW/NHOsqcIglc4UhWklR8K0QzbAw08CBDnpbgqXdeD/QUsM4RZXDFBW6WJKe/mFPdH0LtBgiq57wFLzlyQzz82qYx5D5WJP5yVJDW01BfyHnS6HKO/reZqId1WGa4Hkh2kWodJ8i6KoIPlAj2hPt76CzXsVR6koPRzWTfKqIentatYpQw2me4AA3y1Kind3SwoOKZDcFXTwl9tWU6mfgRk9d71sKtlNwrjnYw5tC5n5LdKiGry3JKNlHEd3oaMCFHrazBPMp/uNJ+V7IudcSbeOIdjUEdwl0VHCOZo5t6YluEuaC9mQeMgSfOyKnYGFHcIeQ84yQWbuJYJpZw5CzglDH7gKnWqqM9ZTaXcN0TeYhR84eQtJT76JJ1lREe7WnnvsMmRc9FQ7SBBM9mV3lCUdmHk/S2RAMt0QjFNFqQpWjDPQ01DXWUdDBkXziKPjGEP3VP+zIWU2t7im41FOloyWzn/L6dkUy3VLDaZ6appgDLHPjJEsyvJngWEPUyVBiAaHCTEXwrLvSEbV1e1gKJniicWorC1MUrVjB3uDhJE/wgSOzk1DXpk0k73qCM8xw2UvD5kJmDUfOomqMpWCkJRlvKXGmoeBm18USjVIk04SClxTB6YrgLAPLWYK9HLUt5cmc0vYES8GnTeRc6skZbQkWdxRsIcyBRzx1DbTk9FbU0caTPOgJHhJKnOGIVhQqvKmo0llRw9sabrZkDtdg3PqaKi9oatjY8B+G371paMg6+mZFNNtQ04mWBq3rYLOmtWWQp8KJnpy9DdFensyjdqZ+yY40VJlH8wcdLzC8PZnvHMFUTZUrDTkLyQaGus5X5LzpYAf3i+e/ZlhqGqWhh6Ou6xTR9Z6oi5AZZtp7Mj2EEm8oSpxiYZCHU/1fbGdNNNRRoZMhmilEb2gqHOEJDtXkHK/JnG6IrvbPCwV3NhONVdS1thBMs1T4QOBcTWa2IzhMk2nW5Kyn9tXUtpv9RsG2msxk+ZsQzRQacJncpgke0+T8y5Fzj8BiGo7XlJjaTIlpQs7KFjpqGnKuoyEPeIKnFMkZHvopgh81ySxNFWvJWcKRs70j2FOT012IllEEO1n4pD1513Yg2ssQPOThOkvyrqHUdEXOSEsihmBbTbKX1kLBPWqWkLOqJbjB3GBIZmoa8qWl4CG/iZ7oiA72ZL7TJNeZUY7kFQftDcHHluBzRbCegzMtrRjVQpX2lgoPKKLJAkcbMl01XK2p7yhL8pCBbQ3BN2avJgKvttcrWDK3CiUOVxQ8ZP+pqXKyIxnmBymCg5vJjNfkPK4+c8cIfK8ocVt7kmfd/I5SR1hKvCzUtb+lhgc00ZaO6CyhIQP1Uv4yIZjload72PXX0OIJvnFU+0Zf6MhsJwTfW0r0UwQfW4LNLZl5HK261JCZ4qnBaAreVAS3WrjV0LBnNDUNNDToCEeFfwgcb4gOEqLRhirWkexrCEYKVV711DLYEE1XBEsp5tpTGjorkomKYF9FDXv7fR3BGwbettSxnyL53MBPjsxDZjMh+VUW9NRxq1DhVk+FSxQcaGjV9Pawv6eGByw5qzoy7xk4RsOShqjJwWKe/1pEEfzkobeD/dQJmpqedcyBTy2sr4nGNRH0c0SPWTLrqAc0OQcb/gemKgqucQT7ySWKCn2EUotoCvpZct7RO2sy/QW0IWcXd7pQRQyZVwT2USRO87uhjioTLKV2brpMUcMQRbKH/N2T+UlTpaMls6cmc6CCNy3JdYYSUzzJQ4oSD3oKLncULOiJvjBEC2oqnCJkJluCYy2ZQ5so9YYlZ1VLlQU1mXEW1jZERwj/MUSRc24TdexlqLKfQBtDTScJUV8FszXBEY5ktpD5Ur9hYB4Nb1iikw3JoYpkKX+RodRKFt53MMuRnKSpY31PwYaGaILh3wxJGz9TkTPEETxoCWZrgvOlmyMzxFEwVJE5xZKzvyJ4WxEc16Gd4Xe3Weq4XH2jKRikqOkGQ87hQnC7wBmGYLAnesX3M+S87eFATauuN+Qcrh7xIxXJbUIdMw3JGE3ylCWzrieaqCn4zhGM19TQ3z1oH1AX+pWEqIc7wNGAkULBo/ZxRaV9NNyh4Br3rCHZzbzmSfawBL0dNRwpW1kK9mxPXR9povcdrGSZK9c2k0xwFGzjuniCtRSZCZ6ccZ7gaktmgAOtKbG/JnOkJrjcQTdFMsxRQ2cLY3WTIrlCw1eWKn8R6pvt4GFDso3QoL4a3nLk3G6JrtME3dSenpx7PNFTmga0EaJTLQ061sEeQoWXhSo9LTXsaSjoJQRXeZLtDclbCrYzfzHHeaKjHCVOUkQHO3JeEepr56mhiyaYYKjjNU+Fed1wS5VlhWSqI/hYUdDOkaxiKehoyOnrCV5yBHtbWFqTHCCwtpDcYolesVR5yUzTZBb3RNMd0d6WP+SvhuBmRcGxnuQzT95IC285cr41cLGQ6aJJhmi4TMGempxeimBRQw1tFKV+8jd6KuzoSTqqDxzRtpZkurvKEHxlqXKRIjjfUNNXQsNOsRScoWFLT+YeRZVD3GRN0MdQcKqQjHDMrdGGVu3iYJpQx3WGUvfbmxwFfR20WBq0oYY7LMFhhgYtr8jpaEnaOzjawWWaTP8mMr0t/EPDPoqcnxTBI5o58L7uoWnMrpoqPwgVrlAUWE+V+TQl9rawoyP6QGAlQw2TPRX+YSkxyBC8Z6jhHkXBgQL7WII3DVFnRfCrBfxewv9D6xsyjys4VkhWb9pUU627JllV0YDNHMku/ldNMMXDEo4aFnAkk4U6frNEU4XgZUPmEKHUl44KrzmYamjAbh0JFvGnaTLPu1s9jPCwjFpYiN7z1DTOk/nc07CfDFzmCf7i+bfNHXhDtLeBXzTBT5rkMvWOIxpl4EMh2LGJBu2syDnAEx2naEhHDWMMzPZEhygyS1mS5RTJr5ZkoKbEUoYqr2kqdDUE8ztK7OaIntJkFrIECwv8LJTaVx5XJE86go8dFeZ3FN3rjabCAYpoYEeC9zzJVULBbmZhDyd7ko09ydpNZ3nm2Kee4FPPXHnYEF1nqOFEC08LUVcDvYXkJHW8gTaKCk9YGOeIJhqiE4ToPEepdp7IWFjdwnWaufGMwJJCMtUTTBBK9BGCOy2tGGrJTHIwyEOzp6aPzNMOtlZkDvcEWpP5SVNhfkvDxhmSazTJXYrM9U1E0xwFVwqZQwzJxw6+kGGGUj2FglGGmnb1/G51udRSMNlTw6GGnCcUwVcOpmsqTHa06o72sw1RL02p9z0VbnMLOaIX3QKaYKSCFQzBKEUNHTSc48k53RH9wxGMtpQa5KjjW0W0n6XCCCG4yxNNdhQ4R4l1Ff+2sSd6UFHiIEOyqqFgT01mEUMD+joy75jPhOA+oVVLm309FR4yVOlp4RhLiScNmSmaYF5Pw0STrOIoWMSR2UkRXOMp+M4SHW8o8Zoi6OZgjKOaFar8zZDzkWzvKOjkKBjmCXby8JahhjXULY4KlzgKLvAwxVGhvyd4zxB1d9T0piazmKLCVZY5sKiD0y2ZSYrkUEPUbIk+dlQ4SJHTR50k1DPaUWIdTZW9NJwnJMOECgd7ou/MnppMJ02O1VT4Wsh85MnZzcFTngpXGKo84qmwgKbCL/orR/SzJ2crA+t6Mp94KvxJUeIbT3CQu1uIdlQEOzlKfS3UMcrTiFmOuroocrZrT2AcmamOKg8YomeEKm/rlT2sociMaybaUlFhuqHCM2qIJ+rg4EcDFymiDSxzaHdPcpE62pD5kyM5SBMoA1PaUtfIthS85ig1VPiPPYXgYEMNk4Qq7TXBgo7oT57gPUdwgCHzhIVFPFU6OYJzHAX9m5oNrVjeE61miDrqQ4VSa1oiURTsKHC0IfjNwU2WzK6eqK8jWln4g15TVBnqmDteCJ501PGAocJhhqjZdtBEB6lnhLreFJKxmlKbeGrqLiSThVIbCdGzloasa6lpMQXHCME2boLpJgT7yWaemu6wBONbqGNVRS0PKIL7LckbjmQtR7K8I5qtqel+T/ChJTNIKLjdUMNIRyvOEko9YYl2cwQveBikCNawJKcLBbc7+JM92mysNvd/Fqp8a0k6CNEe7cnZrxlW0wQXaXjaktnRwNOGZKYiONwS7a1JVheq3WgJHlQUGKHKmp4KAxXR/ULURcNgoa4zhKSLpZR3kxRRb0NmD0OFn+UCS7CzI1nbP6+o4x47QZE5xRCt3ZagnYcvmpYQktXdk5YKXTzBC57kKEe0VVuiSYqapssMS3C9p2CKkHOg8B8Pa8p5atrIw3qezIWanMGa5HRDNF6RM9wcacl0N+Q8Z8hsIkSnaIIdHRUOEebAPy1zbCkhM062FCJtif7PU+UtoVXzWKqM1PxXO8cfdruhFQ/a6x3JKYagvVDhQEtNiyiiSQ7OsuRsZUku0CRNDs4Sog6KKjsZgk2bYJqijgsEenoKeniinRXBn/U3lgpPdyDZynQx8IiioMnCep5Ky8mjGs6Wty0l1hUQTcNWswS3WRp2kCNZwJG8omG8JphPUaFbC8lEfabwP7VtM9yoaNCAjpR41VNhrD9LkbN722v0CoZMByFzhaW+MyzRYEWFDQwN2M4/JiT76PuljT3VU/A36eaIThb+R9oZGOAJ9tewkgGvqOMNRWYjT/Cwu99Q8LqDE4TgbLWxJ1jaDDAERsFOFrobgjUsBScaguXU8kKm2RL19tRypSHnHNlHiIZqgufs4opgQdVdwxBNNFBR6kVFqb8ogimOzB6a6HTzrlDHEpYaxjiiA4TMQobkDg2vejjfwJGWmnbVFAw3H3hq2NyQfG7hz4aC+w3BbwbesG0swYayvpAs6++Ri1Vfzx93mFChvyN5xVHTS+0p9aqCAxyZ6ZacZyw5+7uuQkFPR9DDk9NOiE7X1PCYJVjVUqq7JlrHwWALF5nfHNGjApdpqgzx5OwilDhCiDYTgnc9waGW4BdLNNUQvOtpzDOWHDH8D7TR/A/85KljEQu3NREc4Pl/6B1Hhc8Umb5CsKMmGC9EPcxoT2amwHNCmeOEnOPbklnMkbOgIvO5UMOpQrS9UGVdt6iH/fURjhI/WOpaW9OKLYRod6HCUEdOX000wpDZQ6hwg6LgZfOqo1RfT/CrJzjekXOGhpc1VW71ZLbXyyp+93ILbC1kPtIEYx0FIx1VDrLoVzXRKRYWk809yYlC9ImcrinxtabKnzRJk3lAU1OLEN1j2zrYzr2myHRXJFf4h4QKT1qSTzTB5+ZNTzTRkAxX8FcLV2uS8eoQQ2aAkFzvCM72sJIcJET3WPjRk5wi32uSS9rfZajpWEvj9hW42F4o5NytSXYy8IKHay10VYdrcl4SkqscrXpMwyGOgtkajheSxdQqmpxP1L3t4R5PqasFnrQEjytq6qgp9Y09Qx9o4S1FzhUCn1kyHSzBWLemoSGvOqLNhZyBjmCaAUYpMgt4Ck7wBBMMwWKWgjsUwTaGVsxWC1mYoKiyqqeGKYqonSIRQ3KIkHO0pmAxTdBHkbOvfllfr+AA+7gnc50huVKYK393FOyg7rbPO/izI7hE4CnHHHnJ0ogNPRUGeUpsrZZTBJcrovUcJe51BPsr6GkJdhCCsZ6aTtMEb2pqWkqeVtDXE/QVggsU/Nl86d9RMF3DxvZTA58agu810RWawCiSzzXBeU3MMW9oyJUedvNEvQyNu1f10BSMddR1vaLCYpYa/mGocLSiYDcLbQz8aMn5iyF4xBNMs1P0QEOV7o5gaWGuzSeLue4tt3ro7y4Tgm4G/mopdZgl6q0o6KzJWE3mMksNr3r+a6CbT8g5wZNzT9O7fi/zpaOmnz3BRoqos+tv9zMbdpxsqDBOEewtJLt7cg5wtKKbvldpSzRRCD43VFheCI7yZLppggMVBS/KMAdHODJvOwq2NQSbKKKPLdFWQs7Fqo+mpl01JXYRgq8dnGLhTiFzqmWsUMdpllZdbKlyvSdYxhI9YghOtxR8LgSLWHK62mGGVoxzBE8LNWzqH9CUesQzFy5RQzTc56mhi6fgXEWwpKfE5Z7M05ZgZUPmo6auiv8YKzDYwWBLMErIbKHJvOwIrvEdhOBcQ9JdU1NHQ7CXn2XIDFBKU2WAgcX9UAUzDXWd5alwuyJ41Z9rjKLCL4aCp4WarhPm2rH+SaHUYE001JDZ2ZAzXPjdMpZWvC9wmqIB2lLhQ01D5jO06hghWMndbM7yRJMsoCj1vYbnFQVrW9jak3OlEJ3s/96+p33dEPRV5GxiqaGjIthUU6FFEZyqCa5qJrpBdzSw95IUnOPIrCUUjRZQFrbw5PR0R1qiYx3cb6nrWUMrBmmiBQxVHtTew5ICP/ip6g4hed/Akob/32wvBHsIOX83cI8hGeNeNPCIkPmXe8fPKx84OMSRM1MTdXSwjCZ4S30jVGhvqTRak/OVhgGazHuOCud5onEO1lJr6ecVyaOK6H7zqlBlIaHE0oroCgfvGJIdPcmfLNGLjpz7hZwZQpUbFME0A1cIJa7VNORkgfsMBatbKgwwJM9bSvQXeNOvbIjelg6WWvo5kvbKaJJNHexkKNHL9xRyFlH8Ti2riB5wVPhUk7nGkJnoCe428LR/wRGdYIlmWebCyxou1rCk4g/ShugBDX0V0ZQWkh0dOVsagkM0yV6OoLd5ye+pRlsCr0n+KiQrGuq5yJDzrTAXHtLUMduTDBVKrSm3eHL+6ijxhFDX9Z5gVU/wliHYTMiMFpKLNMEywu80wd3meoFmt6VbRMPenhrOc6DVe4pgXU8DnnHakLOIIrlF4FZPIw6R+zxBP0dyq6OOZ4Q5sLKCcz084ok+VsMMyQhNZmmBgX5xIXOEJTmi7VsGTvMTNdHHhpzdbE8Du2oKxgvBqQKdDDnTFOylCFaxR1syz2iqrOI/FEpNc3C6f11/7+ASS6l2inq2ciTrCCzgyemrCL5SVPjQkdPZUmGy2c9Sw9FtR1sS30RmsKPCS4rkIC/2U0MduwucYolGaPjKEyhzmiPYXagyWbYz8LWBDdzRimAXzxx4z8K9hpzlhLq+NiQ97HuKorMUfK/OVvC2JfiHUPCQI/q7J2gjK+tTDNxkCc4TMssqCs4TGtLVwQihyoAWgj9bosU80XGW6Ac9TJGziaUh5+hnFcHOnlaM1iRn29NaqGENTTTSUHCH2tWTeV0osUhH6psuVLjRUmGWhm6OZEshGeNowABHcJ2Bpy2ZszRcKkRXd2QuKVEeXnbfaEq825FguqfgfE2whlChSRMdron+LATTPQ2Z369t4B9C5gs/ylzv+CMmepIDPclFQl13W0rspPd1JOcbghGOEutqCv5qacURQl3dDKyvyJlqKXGPgcM9FfawJAMVmdcspcYKOZc4GjDYkFlK05olNMHyHn4zFNykyOxt99RkHlfwmiHo60l2EKI+mhreEKp080Tbug08BVPcgoqC5zWt+NLDTZ7oNSF51N1qie7Va3uCCwyZbkINf/NED6jzOsBdZjFN8oqG3wxVunqCSYYKf3EdhJyf9YWGf7tRU2oH3VHgPr1fe5J9hOgHd7xQ0y7qBwXr23aGErP0cm64JVjZwsOGqL+mhNgZmhJLW2oY4UhedsyBgzrCKrq7BmcpNVhR6jBPq64Vgi+kn6XE68pp8J5/+0wRHGOpsKenQn9DZntPzjRLZpDAdD2fnSgkG9tmIXnUwQ6WVighs7Yi2MxQ0N3CqYaCXkJ0oyOztMDJjmSSpcpvlrk0RMMOjmArQ04PRV1DO1FwhCVaUVPpKUM03JK5SxPsIWRu8/CGHi8UHChiqGFDTbSRJWeYUDDcH6vJWUxR4k1FXbMUwV6e4AJFXS8oMqsZKqzvYQ9DDQdZckY4aGsIhtlubbd2r3j4QBMoTamdPZk7O/Bf62lacZwneNjQoGcdVU7zJOd7ghsUHOkosagic6cnWc8+4gg285R6zZP5s1/LUbCKIznTwK36PkdwlOrl4U1LwfdCCa+IrvFkmgw1PCAUXKWo0sURXWcI2muKJlgyFzhynCY4RBOsqCjoI1R5zREco0n2Vt09BQtYSizgKNHfUmUrQ5UOCh51BFcLmY7umhYqXKQomOop8bUnWNNQcIiBcYaC6xzMNOS8JQQfeqKBmmglB+97ok/lfk3ygaHSyZaCRTzRxQo6GzLfa2jWBPepw+UmT7SQEJyiyRkhBLMVOfcoMjcK0eZChfUNzFAUzCsEN5vP/X1uP/n/aoMX+K+nw/Hjr/9xOo7j7Pju61tLcgvJpTWXNbfN5jLpi6VfCOviTktKlFusQixdEKWmEBUKNaIpjZRSSOXSgzaaKLdabrm1/9nZ+/f+vd/vz/v9+Xy+zZ7PRorYoZqyLrCwQdEAixxVOEXNNnjX2nUSRlkqGmWowk8lxR50JPy9Bo6qJXaXwNvREBvnThPEPrewryLhcAnj5WE15Fqi8W7R1sAuEu86S4ENikItFN4xkv9Af4nXSnUVcLiA9xzesFpivRRVeFKtsMRaKBhuSbjOELnAUtlSQUpXgdfB4Z1oSbnFEetbQ0IrAe+Y+pqnDcEJFj6S8LDZzZHwY4e3XONNlARraomNEt2bkvGsosA3ioyHm+6jCMbI59wqt4eeara28IzEmyPgoRaUOEDhTVdEJhmCoTWfC0p8aNkCp0oYqih2iqGi4yXeMkOsn4LdLLnmKfh/YogjNsPebeFGR4m9BJHLzB61XQ3BtpISfS2FugsK9FAtLWX1dCRcrCnUp44CNzuCowUZmxSRgYaE6Za0W2u/E7CVXCiI/UOR8aAm1+OSyE3mOUcwyc1zBBeoX1kiKy0Zfxck1Gsyulti11i83QTBF5Kg3pDQThFMVHiPSlK+0cSedng/VaS8bOZbtsBcTcZAR8JP5KeqQ1OYKAi20njdNNRpgnsU//K+JnaXJaGTomr7aYIphoRn9aeShJWKEq9LcozSF7QleEfDI5LYm5bgVkFkRwVDBCVu0DDIkGupo8TZBq+/pMQURYErJQmPKGKjNDkWOLx7Jd5QizdUweIaKrlP7SwJDhZvONjLkOsBBX9UpGxnydhXkfBLQ8IxgojQbLFnJf81JytSljclYYyEFyx0kVBvKWOFJmONpshGAcsduQY5giVNCV51eOdJYo/pLhbvM0uDHSevNKRcrKZIqnCtJeEsO95RoqcgGK4ocZcho1tTYtcZvH41pNQ7vA0WrhIfOSraIIntIAi+NXWCErdbkvrWwjRLrt0NKUdL6KSOscTOdMSOUtBHwL6OLA0vNSdynaWQEnCpIvKaIrJJEbvHkmuNhn6OjM8VkSGSqn1uYJCGHnq9I3aLhNME3t6GjIkO7xrNFumpyTNX/NrwX7CrIRiqqWijI9JO4d1iieykyfiposQIQ8YjjsjlBh6oHWbwRjgYJQn2NgSnNycmJAk3NiXhx44Sxykihxm8ybUwT1OVKySc7vi3OXVkdBJ4AyXBeksDXG0IhgtYY0lY5ahCD0ehborIk5aUWRJviMA7Xt5kyRjonrXENkm8yYqgs8VzgrJmClK20uMM3jRJ0FiQICQF9hdETlLQWRIb5ki6WDfWRPobvO6a4GP5mcOrNzDFELtTkONLh9dXE8xypEg7z8A9jkhrQ6Fhjlg/QVktJXxt4WXzT/03Q8IaQWSqIuEvloQ2mqC9Jfi7wRul4RX3pSPlzpoVlmCtI2jvKHCFhjcM3sN6lqF6HxnKelLjXWbwrpR4xzuCrTUZx2qq9oAh8p6ixCUGr78g8oyjRAtB5CZFwi80VerVpI0h+IeBxa6Zg6kWvpDHaioYYuEsRbDC3eOmC2JvGYLeioxGknL2UATNJN6hmtj1DlpLvDVmocYbrGCVJKOrg4X6DgddLA203BKMFngdJJFtFd7vJLm6KEpc5yjQrkk7M80SGe34X24nSex1Ra5Omgb71JKyg8SrU3i/kARKwWpH0kOGhKkObyfd0ZGjvyXlAkVZ4xRbYJ2irFMkFY1SwyWxr2oo4zlNiV+7zmaweFpT4kR3kaDAFW6xpSqzJay05FtYR4HmZhc9UxKbbfF2V8RG1MBmSaE+kmC6JnaRXK9gsiXhJHl/U0qM0WTcbyhwkYIvFGwjSbjfwhiJt8ZSQU+Bd5+marPMOkVkD0muxYLIfEuhh60x/J92itguihJSEMySVPQnTewnEm+620rTQEMsOfo4/kP/0ARvWjitlpSX7GxBgcMEsd3EEeYWvdytd+Saawi6aCIj1CkGb6Aj9rwhx16Cf3vAwFy5pyLhVonXzy51FDpdEblbkdJbUcEPDEFzQ8qNmhzzLTmmKWKbFCXeEuRabp6rxbvAtLF442QjQ+wEA9eL1xSR7Q0JXzlSHjJ4exq89yR0laScJ/FW6z4a73pFMEfDiRZvuvijIt86RaSFOl01riV2mD1UEvxGk/Geg5aWwGki1zgKPG9J2U8PEg8qYvMsZeytiTRXBMslCU8JSlxi8EabjwUldlDNLfzTUmCgxWsjqWCOHavYAqsknKFIO0yQ61VL5AVFxk6WhEaCAkdJgt9aSkzXlKNX2jEa79waYuc7gq0N3GDJGCBhoiTXUEPsdknCUE1CK0fwsiaylSF2uiDyO4XX3pFhNd7R4itFGc0k/ElBZwWvq+GC6szVeEoS/MZ+qylwpKNKv9Z469UOjqCjwlusicyTxG6VpNxcQ8IncoR4RhLbR+NdpGGmJWOcIzJGUuKPGpQg8rrG21dOMqQssJQ4RxH5jaUqnZuQ0F4Q+cjxLwPtpZbIAk3QTJHQWBE5S1BokoVtDd6lhqr9UpHSUxMcIYl9pojsb8h4SBOsMQcqvOWC2E8EVehqiJ1hrrAEbQxeK0NGZ0Gkq+guSRgniM23bIHVkqwx4hiHd7smaOyglyIyQuM978j4VS08J/A2G1KeMBRo4fBaSNhKUEZfQewVQ/C1I+MgfbEleEzCUw7mKXI0M3hd1EESVji8x5uQ41nxs1q4RMJCCXs7Iq9acpxn22oSDnQ/sJTxsCbHIYZiLyhY05TY0ZLIOQrGaSJDDN4t8pVaIrsqqFdEegtizc1iTew5Q4ayBDMUsQMkXocaYkc0hZua412siZ1rSXlR460zRJ5SlHGe5j801RLMlJTxtaOM3Q1pvxJ45zUlWFD7rsAbpfEm1JHxG0eh8w2R7QQVzBUw28FhFp5QZzq8t2rx2joqulYTWSuJdTYfWwqMFMcovFmSyJPNyLhE4E10pHzYjOC3huArRa571ZsGajQpQx38SBP5pyZB6lMU3khDnp0MBV51BE9o2E+TY5Ml2E8S7C0o6w1xvCZjf0HkVEHCzFoyNmqC+9wdcqN+Tp7jSDheE9ws8Y5V0NJCn2bk2tqSY4okdrEhx1iDN8cSudwepWmAGXKcJXK65H9to8jYQRH7SBF01ESUJdd0TayVInaWhLkOjlXE5irKGOnI6GSWGCJa482zBI9rCr0jyTVcEuzriC1vcr6mwFGSiqy5zMwxBH/TJHwjSPhL8+01kaaSUuMFKTcLEvaUePcrSmwn8DZrgikWb7CGPxkSjhQwrRk57tctmxLsb9sZvL9LSlyuSLlWkqOjwduo8b6Uv1DkmudIeFF2dHCgxVtk8dpIvHpBxhEOdhKk7OLIUSdJ+cSRY57B+0DgGUUlNfpthTfGkauzxrvTsUUaCVhlKeteTXCoJDCa2NOKhOmC4G1H8JBd4OBZReSRGkqcb/CO1PyLJTLB4j1q8JYaIutEjSLX8YKM+a6phdMsdLFUoV5RTm9JSkuDN8WcIon0NZMNZWh1q8C7SJEwV5HxrmnnTrf3KoJBlmCYI2ilSLlfEvlE4011NNgjgthzEua0oKK7JLE7HZHlEl60BLMVFewg4EWNt0ThrVNEVkkiTwpKXSWJzdRENgvKGq4IhjsiezgSFtsfCUq8qki5S1LRQeYQQ4nemmCkImWMw3tFUoUBZk4NOeZYEp4XRKTGa6wJjrWNHBVJR4m3FCnbuD6aak2WsMTh3SZImGCIPKNgsDpVwnsa70K31lCFJZYcwwSMFcQulGTsZuEaSdBXkPGZhu0FsdUO73RHjq8MPGGIfaGIbVTk6iuI3GFgucHrIQkmWSJdBd7BBu+uOryWAhY7+Lki9rK5wtEQzWwvtbqGhIMFwWRJsElsY4m9IIg9L6lCX0VklaPAYkfkZEGDnOWowlBJjtMUkcGK4Lg6EtoZInMUBVYLgn0UsdmCyCz7gIGHFfk+k1QwTh5We7A9x+IdJ6CvIkEagms0hR50eH9UnTQJ+2oiKyVlLFUE+8gBGu8MQ3CppUHesnjTHN4QB/UGPhCTHLFPHMFrCqa73gqObUJGa03wgbhHkrCfpEpzNLE7JDS25FMKhlhKKWKfCgqstLCPu1zBXy0J2ztwjtixBu8UTRn9LVtkmCN2iyFhtME70JHRQ1KVZXqKI/KNIKYMCYs1GUMEKbM1bKOI9LDXC7zbHS+bt+1MTWS9odA9DtrYtpbImQJ2VHh/lisEwaHqUk1kjKTAKknkBEXkbkdMGwq0dnhzLJF3NJH3JVwrqOB4Sca2hti75nmJN0WzxS6UxDYoEpxpa4htVlRjkYE7DZGzJVU72uC9IyhQL4i8YfGWSYLLNcHXloyz7QhNifmKSE9JgfGmuyLhc403Xm9vqcp6gXe3xuuv8F6VJNxkyTHEkHG2g0aKXL0MsXc1bGfgas2//dCONXiNLCX+5mB7eZIl1kHh7ajwpikyzlUUWOVOsjSQlsS+M0R+pPje/dzBXRZGO0rMtgQrLLG9VSu9n6CMXS3BhwYmSoIBhsjNBmZbgusE9BCPCP5triU4VhNbJfE+swSP27aayE8tuTpYYjtrYjMVGZdp2NpS1s6aBnKSHDsbKuplKbHM4a0wMFd/5/DmGyKrJSUaW4IBrqUhx0vyfzTBBLPIUcnZdrAkNsKR0sWRspumSns6Ch0v/qqIbBYUWKvPU/CFoyrDJGwSNFhbA/MlzKqjrO80hRbpKx0Jewsi/STftwGSlKc1JZyAzx05dhLEdnfQvhZOqiHWWEAHC7+30FuRcZUgaO5gpaIK+xsiHRUsqaPElTV40xQZQ107Q9BZE1nryDVGU9ZSQ47bmhBpLcYpUt7S+xuK/FiT8qKjwXYw5ypS2iuCv7q1gtgjhuBuB8LCFY5cUuCNtsQOFcT+4Ih9JX+k8Ea6v0iCIRZOtCT0Et00JW5UeC85Cg0ScK0k411HcG1zKtre3SeITBRk7WfwDhEvaYLTHP9le0m8By0JDwn4TlLW/aJOvGHxdjYUes+ScZigCkYQdNdEOhkiezgShqkx8ueKjI8lDfK2oNiOFvrZH1hS+tk7NV7nOmLHicGWEgubkXKdwdtZknCLJXaCpkrjZBtLZFsDP9CdxWsSr05Sxl6CMmoFbCOgryX40uDtamB7SVmXW4Ihlgpmq+00tBKUUa83WbjLUNkzDmY7cow1JDygyPGlhgGKYKz4vcV7QBNbJIgM11TUqZaMdwTeSguH6rOaw1JRKzaaGyxVm2EJ/uCIrVWUcZUkcp2grMsEjK+DMwS59jQk3Kd6SEq1d0S6uVmO4Bc1lDXTUcHjluCXEq+1OlBDj1pi9zgiXxnKuE0SqTXwhqbETW6RggMEnGl/q49UT2iCzgJvRwVXS2K/d6+ZkyUl7jawSVLit46EwxVljDZwoSQ20sDBihztHfk2yA8NVZghiXwrYHQdfKAOtzsayjhY9bY0yE2CWEeJ9xfzO423xhL5syS2TFJofO2pboHob0nY4GiAgRrvGQEDa/FWSsoaaYl0syRsEt3kWoH3B01shCXhTUWe9w3Bt44SC9QCh3eShQctwbaK2ApLroGCMlZrYqvlY3qYhM0aXpFkPOuoqJ3Dm6fxXrGwVF9gCWZagjPqznfkuMKQ8DPTQRO8ZqG1hPGKEm9IgpGW4DZDgTNriTxvFiq+Lz+0cKfp4wj6OCK9JSnzNSn9LFU7UhKZZMnYwcJ8s8yRsECScK4j5UOB95HFO0CzhY4xJxuCix0lDlEUeMdS6EZBkTsUkZ4K74dugyTXS7aNgL8aqjDfkCE0ZbwkCXpaWCKhl8P7VD5jxykivSyxyZrYERbe168LYu9ZYh86IkscgVLE7tWPKmJv11CgoyJltMEbrohtVAQfO4ImltiHEroYEs7RxAarVpY8AwXMcMReFOTYWe5iiLRQxJ5Q8DtJ8LQhWOhIeFESPGsILhbNDRljNbHzNRlTFbk2S3L0NOS6V1KFJYKUbSTcIIhM0wQ/s2TM0SRMNcQmSap3jCH4yhJZKSkwyRHpYYgsFeQ4U7xoCB7VVOExhXepo9ABBsYbvGWKXPME3lyH95YioZ0gssQRWWbI+FaSMkXijZXwgiTlYdPdkNLaETxlyDVIwqeaEus0aTcYcg0RVOkpR3CSJqIddK+90JCxzsDVloyrFd5ZAr4TBKfaWa6boEA7C7s6EpYaeFPjveooY72mjIccLHJ9HUwVlDhKkmutJDJBwnp1rvulJZggKDRfbXAkvC/4l3ozQOG9a8lxjx0i7nV4jSXc7vhe3OwIxjgSHjdEhhsif9YkPGlus3iLFDnWOFhtCZbJg0UbQcIaR67JjthoCyMEZRwhiXWyxO5QxI6w5NhT4U1WsJvDO60J34fW9hwzwlKij6ZAW9ne4L0s8C6XeBMEkd/LQy1VucBRot6QMlbivaBhoBgjqGiCJNhsqVp/S2SsG6DIONCR0dXhvWbJ+MRRZJkkuEjgDXJjFQW6SSL7GXK8Z2CZg7cVsbWGoKmEpzQ5elpiy8Ryg7dMkLLUEauzeO86CuwlSOlgYLojZWeJ9xM3S1PWfEfKl5ISLQ0MEKR8YOB2QfCxJBjrKPCN4f9MkaSsqoVXJBmP7EpFZ9UQfOoOFwSzBN4MQ8LsGrymlipcJQhmy0GaQjPqCHaXRwuCZwRbqK2Fg9wlClZqYicrIgMdZfxTQ0c7TBIbrChxmuzoKG8XRaSrIhhiyNFJkrC7oIAWMEOQa5aBekPCRknCo4IKPrYkvCDI8aYmY7WFtprgekcJZ3oLIqssCSMtFbQTJKwXYy3BY5oCh2iKPCpJOE+zRdpYgi6O2KmOAgvVCYaU4ySRek1sgyFhJ403QFHiVEmJHwtybO1gs8Hr5+BETQX3War0qZngYGgtVZtoqd6vFSk/UwdZElYqyjrF4HXUeFspIi9IGKf4j92pKGAdCYMVsbcV3kRF0N+R8LUd5PCsIGWoxDtBkCI0nKofdJQxT+LtZflvuc8Q3CjwWkq8KwUpHzkK/NmSsclCL0nseQdj5FRH5CNHSgtLiW80Of5HU9Hhlsga9bnBq3fEVltKfO5IaSTmGjjc4J0otcP7QsJUSQM8pEj5/wCuUuC2DWz8AAAAAElFTkSuQmCC\");}.ace-ambiance .ace_indent-guide {background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQUFD4z6Crq/sfAAuYAuYl+7lfAAAAAElFTkSuQmCC\") right repeat-y;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-chaos.js b/dist/assets/js/vendor/ace-nc/theme-chaos.js
            new file mode 100644
            index 0000000000..fa5b75aab6
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-chaos.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/chaos",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-chaos",t.cssText=".ace-chaos .ace_gutter {background: #141414;color: #595959;border-right: 1px solid #282828;}.ace-chaos .ace_gutter-cell.ace_warning {background-image: none;background: #FC0;border-left: none;padding-left: 0;color: #000;}.ace-chaos .ace_gutter-cell.ace_error {background-position: -6px center;background-image: none;background: #F10;border-left: none;padding-left: 0;color: #000;}.ace-chaos .ace_print-margin {border-left: 1px solid #555;right: 0;background: #1D1D1D;}.ace-chaos {background-color: #161616;color: #E6E1DC;}.ace-chaos .ace_cursor {border-left: 2px solid #FFFFFF;}.ace-chaos .ace_cursor.ace_overwrite {border-left: 0px;border-bottom: 1px solid #FFFFFF;}.ace-chaos .ace_marker-layer .ace_selection {background: #494836;}.ace-chaos .ace_marker-layer .ace_step {background: rgb(198, 219, 174);}.ace-chaos .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #FCE94F;}.ace-chaos .ace_marker-layer .ace_active-line {background: #333;}.ace-chaos .ace_gutter-active-line {background-color: #222;}.ace-chaos .ace_invisible {color: #404040;}.ace-chaos .ace_keyword {color:#00698F;}.ace-chaos .ace_keyword.ace_operator {color:#FF308F;}.ace-chaos .ace_constant {color:#1EDAFB;}.ace-chaos .ace_constant.ace_language {color:#FDC251;}.ace-chaos .ace_constant.ace_library {color:#8DFF0A;}.ace-chaos .ace_constant.ace_numeric {color:#58C554;}.ace-chaos .ace_invalid {color:#FFFFFF;background-color:#990000;}.ace-chaos .ace_invalid.ace_deprecated {color:#FFFFFF;background-color:#990000;}.ace-chaos .ace_support {color: #999;}.ace-chaos .ace_support.ace_function {color:#00AEEF;}.ace-chaos .ace_function {color:#00AEEF;}.ace-chaos .ace_string {color:#58C554;}.ace-chaos .ace_comment {color:#555;font-style:italic;padding-bottom: 0px;}.ace-chaos .ace_variable {color:#997744;}.ace-chaos .ace_meta.ace_tag {color:#BE53E6;}.ace-chaos .ace_entity.ace_other.ace_attribute-name {color:#FFFF89;}.ace-chaos .ace_markup.ace_underline {text-decoration: underline;}.ace-chaos .ace_fold-widget {text-align: center;}.ace-chaos .ace_fold-widget:hover {color: #777;}.ace-chaos .ace_fold-widget.ace_start,.ace-chaos .ace_fold-widget.ace_end,.ace-chaos .ace_fold-widget.ace_closed{background: none;border: none;box-shadow: none;}.ace-chaos .ace_fold-widget.ace_start:after {content: '\u25be'}.ace-chaos .ace_fold-widget.ace_end:after {content: '\u25b4'}.ace-chaos .ace_fold-widget.ace_closed:after {content: '\u2023'}.ace-chaos .ace_indent-guide {border-right:1px dotted #333;margin-right:-1px;}.ace-chaos .ace_fold { background: #222; border-radius: 3px; color: #7AF; border: none; }.ace-chaos .ace_fold:hover {background: #CCC; color: #000;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-chrome.js b/dist/assets/js/vendor/ace-nc/theme-chrome.js
            new file mode 100644
            index 0000000000..29b01c7ab5
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-chrome.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/chrome",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-chrome",t.cssText='.ace-chrome .ace_gutter {background: #ebebeb;color: #333;overflow : hidden;}.ace-chrome .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-chrome {background-color: #FFFFFF;color: black;}.ace-chrome .ace_cursor {color: black;}.ace-chrome .ace_invisible {color: rgb(191, 191, 191);}.ace-chrome .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-chrome .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-chrome .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-chrome .ace_invalid {background-color: rgb(153, 0, 0);color: white;}.ace-chrome .ace_fold {}.ace-chrome .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-chrome .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-chrome .ace_support.ace_type,.ace-chrome .ace_support.ace_class.ace-chrome .ace_support.ace_other {color: rgb(109, 121, 222);}.ace-chrome .ace_variable.ace_parameter {font-style:italic;color:#FD971F;}.ace-chrome .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-chrome .ace_comment {color: #236e24;}.ace-chrome .ace_comment.ace_doc {color: #236e24;}.ace-chrome .ace_comment.ace_doc.ace_tag {color: #236e24;}.ace-chrome .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-chrome .ace_variable {color: rgb(49, 132, 149);}.ace-chrome .ace_xml-pe {color: rgb(104, 104, 91);}.ace-chrome .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-chrome .ace_heading {color: rgb(12, 7, 255);}.ace-chrome .ace_list {color:rgb(185, 6, 144);}.ace-chrome .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-chrome .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-chrome .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-chrome .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-chrome .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-chrome .ace_gutter-active-line {background-color : #dcdcdc;}.ace-chrome .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-chrome .ace_storage,.ace-chrome .ace_keyword,.ace-chrome .ace_meta.ace_tag {color: rgb(147, 15, 128);}.ace-chrome .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-chrome .ace_string {color: #1A1AA6;}.ace-chrome .ace_entity.ace_other.ace_attribute-name {color: #994409;}.ace-chrome .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-clouds.js b/dist/assets/js/vendor/ace-nc/theme-clouds.js
            new file mode 100644
            index 0000000000..c04b8d1854
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-clouds.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/clouds",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-clouds",t.cssText='.ace-clouds .ace_gutter {background: #ebebeb;color: #333}.ace-clouds .ace_print-margin {width: 1px;background: #e8e8e8}.ace-clouds {background-color: #FFFFFF;color: #000000}.ace-clouds .ace_cursor {color: #000000}.ace-clouds .ace_marker-layer .ace_selection {background: #BDD5FC}.ace-clouds.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FFFFFF;border-radius: 2px}.ace-clouds .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-clouds .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #BFBFBF}.ace-clouds .ace_marker-layer .ace_active-line {background: #FFFBD1}.ace-clouds .ace_gutter-active-line {background-color : #dcdcdc}.ace-clouds .ace_marker-layer .ace_selected-word {border: 1px solid #BDD5FC}.ace-clouds .ace_invisible {color: #BFBFBF}.ace-clouds .ace_keyword,.ace-clouds .ace_meta,.ace-clouds .ace_support.ace_constant.ace_property-value {color: #AF956F}.ace-clouds .ace_keyword.ace_operator {color: #484848}.ace-clouds .ace_keyword.ace_other.ace_unit {color: #96DC5F}.ace-clouds .ace_constant.ace_language {color: #39946A}.ace-clouds .ace_constant.ace_numeric {color: #46A609}.ace-clouds .ace_constant.ace_character.ace_entity {color: #BF78CC}.ace-clouds .ace_invalid {background-color: #FF002A}.ace-clouds .ace_fold {background-color: #AF956F;border-color: #000000}.ace-clouds .ace_storage,.ace-clouds .ace_support.ace_class,.ace-clouds .ace_support.ace_function,.ace-clouds .ace_support.ace_other,.ace-clouds .ace_support.ace_type {color: #C52727}.ace-clouds .ace_string {color: #5D90CD}.ace-clouds .ace_comment {color: #BCC8BA}.ace-clouds .ace_entity.ace_name.ace_tag,.ace-clouds .ace_entity.ace_other.ace_attribute-name {color: #606060}.ace-clouds .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-clouds_midnight.js b/dist/assets/js/vendor/ace-nc/theme-clouds_midnight.js
            new file mode 100644
            index 0000000000..74278071ef
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-clouds_midnight.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/clouds_midnight",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-clouds-midnight",t.cssText=".ace-clouds-midnight .ace_gutter {background: #232323;color: #929292}.ace-clouds-midnight .ace_print-margin {width: 1px;background: #232323}.ace-clouds-midnight {background-color: #191919;color: #929292}.ace-clouds-midnight .ace_cursor {color: #7DA5DC}.ace-clouds-midnight .ace_marker-layer .ace_selection {background: #000000}.ace-clouds-midnight.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #191919;border-radius: 2px}.ace-clouds-midnight .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-clouds-midnight .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #BFBFBF}.ace-clouds-midnight .ace_marker-layer .ace_active-line {background: rgba(215, 215, 215, 0.031)}.ace-clouds-midnight .ace_gutter-active-line {background-color: rgba(215, 215, 215, 0.031)}.ace-clouds-midnight .ace_marker-layer .ace_selected-word {border: 1px solid #000000}.ace-clouds-midnight .ace_invisible {color: #BFBFBF}.ace-clouds-midnight .ace_keyword,.ace-clouds-midnight .ace_meta,.ace-clouds-midnight .ace_support.ace_constant.ace_property-value {color: #927C5D}.ace-clouds-midnight .ace_keyword.ace_operator {color: #4B4B4B}.ace-clouds-midnight .ace_keyword.ace_other.ace_unit {color: #366F1A}.ace-clouds-midnight .ace_constant.ace_language {color: #39946A}.ace-clouds-midnight .ace_constant.ace_numeric {color: #46A609}.ace-clouds-midnight .ace_constant.ace_character.ace_entity {color: #A165AC}.ace-clouds-midnight .ace_invalid {color: #FFFFFF;background-color: #E92E2E}.ace-clouds-midnight .ace_fold {background-color: #927C5D;border-color: #929292}.ace-clouds-midnight .ace_storage,.ace-clouds-midnight .ace_support.ace_class,.ace-clouds-midnight .ace_support.ace_function,.ace-clouds-midnight .ace_support.ace_other,.ace-clouds-midnight .ace_support.ace_type {color: #E92E2E}.ace-clouds-midnight .ace_string {color: #5D90CD}.ace-clouds-midnight .ace_comment {color: #3C403B}.ace-clouds-midnight .ace_entity.ace_name.ace_tag,.ace-clouds-midnight .ace_entity.ace_other.ace_attribute-name {color: #606060}.ace-clouds-midnight .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-cobalt.js b/dist/assets/js/vendor/ace-nc/theme-cobalt.js
            new file mode 100644
            index 0000000000..0473c2d80e
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-cobalt.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/cobalt",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-cobalt",t.cssText=".ace-cobalt .ace_gutter {background: #011e3a;color: #fff}.ace-cobalt .ace_print-margin {width: 1px;background: #011e3a}.ace-cobalt {background-color: #002240;color: #FFFFFF}.ace-cobalt .ace_cursor {color: #FFFFFF}.ace-cobalt .ace_marker-layer .ace_selection {background: rgba(179, 101, 57, 0.75)}.ace-cobalt.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #002240;border-radius: 2px}.ace-cobalt .ace_marker-layer .ace_step {background: rgb(127, 111, 19)}.ace-cobalt .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(255, 255, 255, 0.15)}.ace-cobalt .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.35)}.ace-cobalt .ace_gutter-active-line {background-color: rgba(0, 0, 0, 0.35)}.ace-cobalt .ace_marker-layer .ace_selected-word {border: 1px solid rgba(179, 101, 57, 0.75)}.ace-cobalt .ace_invisible {color: rgba(255, 255, 255, 0.15)}.ace-cobalt .ace_keyword,.ace-cobalt .ace_meta {color: #FF9D00}.ace-cobalt .ace_constant,.ace-cobalt .ace_constant.ace_character,.ace-cobalt .ace_constant.ace_character.ace_escape,.ace-cobalt .ace_constant.ace_other {color: #FF628C}.ace-cobalt .ace_invalid {color: #F8F8F8;background-color: #800F00}.ace-cobalt .ace_support {color: #80FFBB}.ace-cobalt .ace_support.ace_constant {color: #EB939A}.ace-cobalt .ace_fold {background-color: #FF9D00;border-color: #FFFFFF}.ace-cobalt .ace_support.ace_function {color: #FFB054}.ace-cobalt .ace_storage {color: #FFEE80}.ace-cobalt .ace_entity {color: #FFDD00}.ace-cobalt .ace_string {color: #3AD900}.ace-cobalt .ace_string.ace_regexp {color: #80FFC2}.ace-cobalt .ace_comment {font-style: italic;color: #0088FF}.ace-cobalt .ace_heading,.ace-cobalt .ace_markup.ace_heading {color: #C8E4FD;background-color: #001221}.ace-cobalt .ace_list,.ace-cobalt .ace_markup.ace_list {background-color: #130D26}.ace-cobalt .ace_variable {color: #CCCCCC}.ace-cobalt .ace_variable.ace_language {color: #FF80E1}.ace-cobalt .ace_meta.ace_tag {color: #9EFFFF}.ace-cobalt .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHCLSvkPAAP3AgSDTRd4AAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-crimson_editor.js b/dist/assets/js/vendor/ace-nc/theme-crimson_editor.js
            new file mode 100644
            index 0000000000..9e3653e0d8
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-crimson_editor.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/crimson_editor",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssText='.ace-crimson-editor .ace_gutter {background: #ebebeb;color: #333;overflow : hidden;}.ace-crimson-editor .ace_gutter-layer {width: 100%;text-align: right;}.ace-crimson-editor .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-crimson-editor {background-color: #FFFFFF;color: rgb(64, 64, 64);}.ace-crimson-editor .ace_cursor {color: black;}.ace-crimson-editor .ace_invisible {color: rgb(191, 191, 191);}.ace-crimson-editor .ace_identifier {color: black;}.ace-crimson-editor .ace_keyword {color: blue;}.ace-crimson-editor .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-crimson-editor .ace_constant.ace_language {color: rgb(255, 156, 0);}.ace-crimson-editor .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-crimson-editor .ace_invalid {text-decoration: line-through;color: rgb(224, 0, 0);}.ace-crimson-editor .ace_fold {}.ace-crimson-editor .ace_support.ace_function {color: rgb(192, 0, 0);}.ace-crimson-editor .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-crimson-editor .ace_support.ace_type,.ace-crimson-editor .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-crimson-editor .ace_keyword.ace_operator {color: rgb(49, 132, 149);}.ace-crimson-editor .ace_string {color: rgb(128, 0, 128);}.ace-crimson-editor .ace_comment {color: rgb(76, 136, 107);}.ace-crimson-editor .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-crimson-editor .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-crimson-editor .ace_constant.ace_numeric {color: rgb(0, 0, 64);}.ace-crimson-editor .ace_variable {color: rgb(0, 64, 128);}.ace-crimson-editor .ace_xml-pe {color: rgb(104, 104, 91);}.ace-crimson-editor .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-crimson-editor .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-crimson-editor .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-crimson-editor .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-crimson-editor .ace_marker-layer .ace_active-line {background: rgb(232, 242, 254);}.ace-crimson-editor .ace_gutter-active-line {background-color : #dcdcdc;}.ace-crimson-editor .ace_meta.ace_tag {color:rgb(28, 2, 255);}.ace-crimson-editor .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-crimson-editor .ace_string.ace_regex {color: rgb(192, 0, 192);}.ace-crimson-editor .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}',t.cssClass="ace-crimson-editor";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-dawn.js b/dist/assets/js/vendor/ace-nc/theme-dawn.js
            new file mode 100644
            index 0000000000..79ca2f12dd
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-dawn.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/dawn",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-dawn",t.cssText=".ace-dawn .ace_gutter {background: #ebebeb;color: #333}.ace-dawn .ace_print-margin {width: 1px;background: #e8e8e8}.ace-dawn {background-color: #F9F9F9;color: #080808}.ace-dawn .ace_cursor {color: #000000}.ace-dawn .ace_marker-layer .ace_selection {background: rgba(39, 95, 255, 0.30)}.ace-dawn.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #F9F9F9;border-radius: 2px}.ace-dawn .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-dawn .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(75, 75, 126, 0.50)}.ace-dawn .ace_marker-layer .ace_active-line {background: rgba(36, 99, 180, 0.12)}.ace-dawn .ace_gutter-active-line {background-color : #dcdcdc}.ace-dawn .ace_marker-layer .ace_selected-word {border: 1px solid rgba(39, 95, 255, 0.30)}.ace-dawn .ace_invisible {color: rgba(75, 75, 126, 0.50)}.ace-dawn .ace_keyword,.ace-dawn .ace_meta {color: #794938}.ace-dawn .ace_constant,.ace-dawn .ace_constant.ace_character,.ace-dawn .ace_constant.ace_character.ace_escape,.ace-dawn .ace_constant.ace_other {color: #811F24}.ace-dawn .ace_invalid.ace_illegal {text-decoration: underline;font-style: italic;color: #F8F8F8;background-color: #B52A1D}.ace-dawn .ace_invalid.ace_deprecated {text-decoration: underline;font-style: italic;color: #B52A1D}.ace-dawn .ace_support {color: #691C97}.ace-dawn .ace_support.ace_constant {color: #B4371F}.ace-dawn .ace_fold {background-color: #794938;border-color: #080808}.ace-dawn .ace_list,.ace-dawn .ace_markup.ace_list,.ace-dawn .ace_support.ace_function {color: #693A17}.ace-dawn .ace_storage {font-style: italic;color: #A71D5D}.ace-dawn .ace_string {color: #0B6125}.ace-dawn .ace_string.ace_regexp {color: #CF5628}.ace-dawn .ace_comment {font-style: italic;color: #5A525F}.ace-dawn .ace_heading,.ace-dawn .ace_markup.ace_heading {color: #19356D}.ace-dawn .ace_variable {color: #234A97}.ace-dawn .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLh/5+x/AAizA4hxNNsZAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-dreamweaver.js b/dist/assets/js/vendor/ace-nc/theme-dreamweaver.js
            new file mode 100644
            index 0000000000..618cbaeff2
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-dreamweaver.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/dreamweaver",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-dreamweaver",t.cssText='.ace-dreamweaver .ace_gutter {background: #e8e8e8;color: #333;}.ace-dreamweaver .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-dreamweaver {background-color: #FFFFFF;color: black;}.ace-dreamweaver .ace_fold {background-color: #757AD8;}.ace-dreamweaver .ace_cursor {color: black;}.ace-dreamweaver .ace_invisible {color: rgb(191, 191, 191);}.ace-dreamweaver .ace_storage,.ace-dreamweaver .ace_keyword {color: blue;}.ace-dreamweaver .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-dreamweaver .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-dreamweaver .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-dreamweaver .ace_invalid {background-color: rgb(153, 0, 0);color: white;}.ace-dreamweaver .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-dreamweaver .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-dreamweaver .ace_support.ace_type,.ace-dreamweaver .ace_support.ace_class {color: #009;}.ace-dreamweaver .ace_support.ace_php_tag {color: #f00;}.ace-dreamweaver .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-dreamweaver .ace_string {color: #00F;}.ace-dreamweaver .ace_comment {color: rgb(76, 136, 107);}.ace-dreamweaver .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-dreamweaver .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-dreamweaver .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-dreamweaver .ace_variable {color: #06F}.ace-dreamweaver .ace_xml-pe {color: rgb(104, 104, 91);}.ace-dreamweaver .ace_entity.ace_name.ace_function {color: #00F;}.ace-dreamweaver .ace_heading {color: rgb(12, 7, 255);}.ace-dreamweaver .ace_list {color:rgb(185, 6, 144);}.ace-dreamweaver .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-dreamweaver .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-dreamweaver .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-dreamweaver .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-dreamweaver .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-dreamweaver .ace_gutter-active-line {background-color : #DCDCDC;}.ace-dreamweaver .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-dreamweaver .ace_meta.ace_tag {color:#009;}.ace-dreamweaver .ace_meta.ace_tag.ace_anchor {color:#060;}.ace-dreamweaver .ace_meta.ace_tag.ace_form {color:#F90;}.ace-dreamweaver .ace_meta.ace_tag.ace_image {color:#909;}.ace-dreamweaver .ace_meta.ace_tag.ace_script {color:#900;}.ace-dreamweaver .ace_meta.ace_tag.ace_style {color:#909;}.ace-dreamweaver .ace_meta.ace_tag.ace_table {color:#099;}.ace-dreamweaver .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-dreamweaver .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-eclipse.js b/dist/assets/js/vendor/ace-nc/theme-eclipse.js
            new file mode 100644
            index 0000000000..b15aeec106
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-eclipse.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/eclipse",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssText='.ace-eclipse .ace_gutter {background: #ebebeb;border-right: 1px solid rgb(159, 159, 159);color: rgb(136, 136, 136);}.ace-eclipse .ace_print-margin {width: 1px;background: #ebebeb;}.ace-eclipse {background-color: #FFFFFF;color: black;}.ace-eclipse .ace_fold {background-color: rgb(60, 76, 114);}.ace-eclipse .ace_cursor {color: black;}.ace-eclipse .ace_storage,.ace-eclipse .ace_keyword,.ace-eclipse .ace_variable {color: rgb(127, 0, 85);}.ace-eclipse .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-eclipse .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-eclipse .ace_function {color: rgb(60, 76, 114);}.ace-eclipse .ace_string {color: rgb(42, 0, 255);}.ace-eclipse .ace_comment {color: rgb(113, 150, 130);}.ace-eclipse .ace_comment.ace_doc {color: rgb(63, 95, 191);}.ace-eclipse .ace_comment.ace_doc.ace_tag {color: rgb(127, 159, 191);}.ace-eclipse .ace_constant.ace_numeric {color: darkblue;}.ace-eclipse .ace_tag {color: rgb(25, 118, 116);}.ace-eclipse .ace_type {color: rgb(127, 0, 127);}.ace-eclipse .ace_xml-pe {color: rgb(104, 104, 91);}.ace-eclipse .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-eclipse .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-eclipse .ace_meta.ace_tag {color:rgb(25, 118, 116);}.ace-eclipse .ace_invisible {color: #ddd;}.ace-eclipse .ace_entity.ace_other.ace_attribute-name {color:rgb(127, 0, 127);}.ace-eclipse .ace_marker-layer .ace_step {background: rgb(255, 255, 0);}.ace-eclipse .ace_active-line {background: rgb(232, 242, 254);}.ace-eclipse .ace_gutter-active-line {background-color : #DADADA;}.ace-eclipse .ace_marker-layer .ace_selected-word {border: 1px solid rgb(181, 213, 255);}.ace-eclipse .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}',t.cssClass="ace-eclipse";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-github.js b/dist/assets/js/vendor/ace-nc/theme-github.js
            new file mode 100644
            index 0000000000..56ee219b0c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-github.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/github",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-github",t.cssText='.ace-github .ace_gutter {background: #e8e8e8;color: #AAA;}.ace-github  {background: #fff;color: #000;}.ace-github .ace_keyword {font-weight: bold;}.ace-github .ace_string {color: #D14;}.ace-github .ace_variable.ace_class {color: teal;}.ace-github .ace_constant.ace_numeric {color: #099;}.ace-github .ace_constant.ace_buildin {color: #0086B3;}.ace-github .ace_support.ace_function {color: #0086B3;}.ace-github .ace_comment {color: #998;font-style: italic;}.ace-github .ace_variable.ace_language  {color: #0086B3;}.ace-github .ace_paren {font-weight: bold;}.ace-github .ace_boolean {font-weight: bold;}.ace-github .ace_string.ace_regexp {color: #009926;font-weight: normal;}.ace-github .ace_variable.ace_instance {color: teal;}.ace-github .ace_constant.ace_language {font-weight: bold;}.ace-github .ace_cursor {color: black;}.ace-github .ace_marker-layer .ace_active-line {background: rgb(255, 255, 204);}.ace-github .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-github.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;border-radius: 2px;}.ace-github.ace_nobold .ace_line > span {font-weight: normal !important;}.ace-github .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-github .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-github .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-github .ace_gutter-active-line {background-color : rgba(0, 0, 0, 0.07);}.ace-github .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-github .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-github .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-idle_fingers.js b/dist/assets/js/vendor/ace-nc/theme-idle_fingers.js
            new file mode 100644
            index 0000000000..cf2c41e1be
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-idle_fingers.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/idle_fingers",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-idle-fingers",t.cssText=".ace-idle-fingers .ace_gutter {background: #3b3b3b;color: #fff}.ace-idle-fingers .ace_print-margin {width: 1px;background: #3b3b3b}.ace-idle-fingers {background-color: #323232;color: #FFFFFF}.ace-idle-fingers .ace_cursor {color: #91FF00}.ace-idle-fingers .ace_marker-layer .ace_selection {background: rgba(90, 100, 126, 0.88)}.ace-idle-fingers.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #323232;border-radius: 2px}.ace-idle-fingers .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-idle-fingers .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #404040}.ace-idle-fingers .ace_marker-layer .ace_active-line {background: #353637}.ace-idle-fingers .ace_gutter-active-line {background-color: #353637}.ace-idle-fingers .ace_marker-layer .ace_selected-word {border: 1px solid rgba(90, 100, 126, 0.88)}.ace-idle-fingers .ace_invisible {color: #404040}.ace-idle-fingers .ace_keyword,.ace-idle-fingers .ace_meta {color: #CC7833}.ace-idle-fingers .ace_constant,.ace-idle-fingers .ace_constant.ace_character,.ace-idle-fingers .ace_constant.ace_character.ace_escape,.ace-idle-fingers .ace_constant.ace_other,.ace-idle-fingers .ace_support.ace_constant {color: #6C99BB}.ace-idle-fingers .ace_invalid {color: #FFFFFF;background-color: #FF0000}.ace-idle-fingers .ace_fold {background-color: #CC7833;border-color: #FFFFFF}.ace-idle-fingers .ace_support.ace_function {color: #B83426}.ace-idle-fingers .ace_variable.ace_parameter {font-style: italic}.ace-idle-fingers .ace_string {color: #A5C261}.ace-idle-fingers .ace_string.ace_regexp {color: #CCCC33}.ace-idle-fingers .ace_comment {font-style: italic;color: #BC9458}.ace-idle-fingers .ace_meta.ace_tag {color: #FFE5BB}.ace-idle-fingers .ace_entity.ace_name {color: #FFC66D}.ace-idle-fingers .ace_collab.ace_user1 {color: #323232;background-color: #FFF980}.ace-idle-fingers .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMwMjLyZYiPj/8PAAreAwAI1+g0AAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-katzenmilch.js b/dist/assets/js/vendor/ace-nc/theme-katzenmilch.js
            new file mode 100644
            index 0000000000..7d729382de
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-katzenmilch.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/katzenmilch",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-katzenmilch",t.cssText=".ace-katzenmilch .ace_gutter,.ace-katzenmilch .ace_gutter {background: #e8e8e8;color: #333}.ace-katzenmilch .ace_print-margin {width: 1px;background: #e8e8e8}.ace-katzenmilch {background-color: #f3f2f3;color: rgba(15, 0, 9, 1.0)}.ace-katzenmilch .ace_cursor {border-left: 2px solid #100011}.ace-katzenmilch .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid #100011}.ace-katzenmilch .ace_marker-layer .ace_selection {background: rgba(100, 5, 208, 0.27)}.ace-katzenmilch.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #f3f2f3;border-radius: 2px}.ace-katzenmilch .ace_marker-layer .ace_step {background: rgb(198, 219, 174)}.ace-katzenmilch .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #000000}.ace-katzenmilch .ace_marker-layer .ace_active-line {background: rgb(232, 242, 254)}.ace-katzenmilch .ace_gutter-active-line {background-color: rgb(232, 242, 254)}.ace-katzenmilch .ace_marker-layer .ace_selected-word {border: 1px solid rgba(100, 5, 208, 0.27)}.ace-katzenmilch .ace_fold {background-color: rgba(2, 95, 73, 0.97);border-color: rgba(15, 0, 9, 1.0)}.ace-katzenmilch .ace_keyword {color: #674Aa8;rbackground-color: rgba(163, 170, 216, 0.055)}.ace-katzenmilch .ace_constant.ace_language {color: #7D7e52;rbackground-color: rgba(189, 190, 130, 0.059)}.ace-katzenmilch .ace_constant.ace_numeric {color: rgba(79, 130, 123, 0.93);rbackground-color: rgba(119, 194, 187, 0.059)}.ace-katzenmilch .ace_constant.ace_character,.ace-katzenmilch .ace_constant.ace_other {color: rgba(2, 95, 105, 1.0);rbackground-color: rgba(127, 34, 153, 0.063)}.ace-katzenmilch .ace_support.ace_function {color: #9D7e62;rbackground-color: rgba(189, 190, 130, 0.039)}.ace-katzenmilch .ace_support.ace_class {color: rgba(239, 106, 167, 1.0);rbackground-color: rgba(239, 106, 167, 0.063)}.ace-katzenmilch .ace_storage {color: rgba(123, 92, 191, 1.0);rbackground-color: rgba(139, 93, 223, 0.051)}.ace-katzenmilch .ace_invalid {color: #DFDFD5;rbackground-color: #CC1B27}.ace-katzenmilch .ace_string {color: #5a5f9b;rbackground-color: rgba(170, 175, 219, 0.035)}.ace-katzenmilch .ace_comment {font-style: italic;color: rgba(64, 79, 80, 0.67);rbackground-color: rgba(95, 15, 255, 0.0078)}.ace-katzenmilch .ace_entity.ace_name.ace_function,.ace-katzenmilch .ace_variable {color: rgba(2, 95, 73, 0.97);rbackground-color: rgba(34, 255, 73, 0.12)}.ace-katzenmilch .ace_variable.ace_language {color: #316fcf;rbackground-color: rgba(58, 175, 255, 0.039)}.ace-katzenmilch .ace_variable.ace_parameter {font-style: italic;color: rgba(51, 150, 159, 0.87);rbackground-color: rgba(5, 214, 249, 0.043)}.ace-katzenmilch .ace_entity.ace_other.ace_attribute-name {color: rgba(73, 70, 194, 0.93);rbackground-color: rgba(73, 134, 194, 0.035)}.ace-katzenmilch .ace_entity.ace_name.ace_tag {color: #3976a2;rbackground-color: rgba(73, 166, 210, 0.039)}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-kr.js b/dist/assets/js/vendor/ace-nc/theme-kr.js
            new file mode 100644
            index 0000000000..5f5a402a2b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-kr.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/kr_theme",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-kr-theme",t.cssText=".ace-kr-theme .ace_gutter {background: #1c1917;color: #FCFFE0}.ace-kr-theme .ace_print-margin {width: 1px;background: #1c1917}.ace-kr-theme {background-color: #0B0A09;color: #FCFFE0}.ace-kr-theme .ace_cursor {color: #FF9900}.ace-kr-theme .ace_marker-layer .ace_selection {background: rgba(170, 0, 255, 0.45)}.ace-kr-theme.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #0B0A09;border-radius: 2px}.ace-kr-theme .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-kr-theme .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(255, 177, 111, 0.32)}.ace-kr-theme .ace_marker-layer .ace_active-line {background: #38403D}.ace-kr-theme .ace_gutter-active-line {background-color : #38403D}.ace-kr-theme .ace_marker-layer .ace_selected-word {border: 1px solid rgba(170, 0, 255, 0.45)}.ace-kr-theme .ace_invisible {color: rgba(255, 177, 111, 0.32)}.ace-kr-theme .ace_keyword,.ace-kr-theme .ace_meta {color: #949C8B}.ace-kr-theme .ace_constant,.ace-kr-theme .ace_constant.ace_character,.ace-kr-theme .ace_constant.ace_character.ace_escape,.ace-kr-theme .ace_constant.ace_other {color: rgba(210, 117, 24, 0.76)}.ace-kr-theme .ace_invalid {color: #F8F8F8;background-color: #A41300}.ace-kr-theme .ace_support {color: #9FC28A}.ace-kr-theme .ace_support.ace_constant {color: #C27E66}.ace-kr-theme .ace_fold {background-color: #949C8B;border-color: #FCFFE0}.ace-kr-theme .ace_support.ace_function {color: #85873A}.ace-kr-theme .ace_storage {color: #FFEE80}.ace-kr-theme .ace_string {color: rgba(164, 161, 181, 0.8)}.ace-kr-theme .ace_string.ace_regexp {color: rgba(125, 255, 192, 0.65)}.ace-kr-theme .ace_comment {font-style: italic;color: #706D5B}.ace-kr-theme .ace_variable {color: #D1A796}.ace-kr-theme .ace_list,.ace-kr-theme .ace_markup.ace_list {background-color: #0F0040}.ace-kr-theme .ace_variable.ace_language {color: #FF80E1}.ace-kr-theme .ace_meta.ace_tag {color: #BABD9C}.ace-kr-theme .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-kuroir.js b/dist/assets/js/vendor/ace-nc/theme-kuroir.js
            new file mode 100644
            index 0000000000..9cc8c07d14
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-kuroir.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/kuroir",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-kuroir",t.cssText=".ace-kuroir .ace_gutter {background: #e8e8e8;color: #333;}.ace-kuroir .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-kuroir {background-color: #E8E9E8;color: #363636;}.ace-kuroir .ace_cursor {color: #202020;}.ace-kuroir .ace_marker-layer .ace_selection {background: rgba(245, 170, 0, 0.57);}.ace-kuroir.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #E8E9E8;border-radius: 2px;}.ace-kuroir .ace_marker-layer .ace_step {background: rgb(198, 219, 174);}.ace-kuroir .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(0, 0, 0, 0.29);}.ace-kuroir .ace_marker-layer .ace_active-line {background: rgba(203, 220, 47, 0.22);}.ace-kuroir .ace_gutter-active-line {background-color: rgba(203, 220, 47, 0.22);}.ace-kuroir .ace_marker-layer .ace_selected-word {border: 1px solid rgba(245, 170, 0, 0.57);}.ace-kuroir .ace_fold {border-color: #363636;}.ace-kuroir .ace_constant{color:#CD6839;}.ace-kuroir .ace_constant.ace_numeric{color:#9A5925;}.ace-kuroir .ace_support{color:#104E8B;}.ace-kuroir .ace_support.ace_function{color:#005273;}.ace-kuroir .ace_support.ace_constant{color:#CF6A4C;}.ace-kuroir .ace_storage{color:#A52A2A;}.ace-kuroir .ace_invalid.ace_illegal{color:#FD1224;background-color:rgba(255, 6, 0, 0.15);}.ace-kuroir .ace_invalid.ace_deprecated{text-decoration:underline;font-style:italic;color:#FD1732;background-color:#E8E9E8;}.ace-kuroir .ace_string{color:#639300;}.ace-kuroir .ace_string.ace_regexp{color:#417E00;background-color:#C9D4BE;}.ace-kuroir .ace_comment{color:rgba(148, 148, 148, 0.91);background-color:rgba(220, 220, 220, 0.56);}.ace-kuroir .ace_variable{color:#009ACD;}.ace-kuroir .ace_meta.ace_tag{color:#005273;}.ace-kuroir .ace_markup.ace_heading{color:#B8012D;background-color:rgba(191, 97, 51, 0.051);}.ace-kuroir .ace_markup.ace_list{color:#8F5B26;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-merbivore.js b/dist/assets/js/vendor/ace-nc/theme-merbivore.js
            new file mode 100644
            index 0000000000..bd1844e63a
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-merbivore.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/merbivore",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-merbivore",t.cssText=".ace-merbivore .ace_gutter {background: #202020;color: #E6E1DC}.ace-merbivore .ace_print-margin {width: 1px;background: #555651}.ace-merbivore {background-color: #161616;color: #E6E1DC}.ace-merbivore .ace_cursor {color: #FFFFFF}.ace-merbivore .ace_marker-layer .ace_selection {background: #454545}.ace-merbivore.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #161616;border-radius: 2px}.ace-merbivore .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-merbivore .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #404040}.ace-merbivore .ace_marker-layer .ace_active-line {background: #333435}.ace-merbivore .ace_gutter-active-line {background-color: #333435}.ace-merbivore .ace_marker-layer .ace_selected-word {border: 1px solid #454545}.ace-merbivore .ace_invisible {color: #404040}.ace-merbivore .ace_entity.ace_name.ace_tag,.ace-merbivore .ace_keyword,.ace-merbivore .ace_meta,.ace-merbivore .ace_meta.ace_tag,.ace-merbivore .ace_storage,.ace-merbivore .ace_support.ace_function {color: #FC6F09}.ace-merbivore .ace_constant,.ace-merbivore .ace_constant.ace_character,.ace-merbivore .ace_constant.ace_character.ace_escape,.ace-merbivore .ace_constant.ace_other,.ace-merbivore .ace_support.ace_type {color: #1EDAFB}.ace-merbivore .ace_constant.ace_character.ace_escape {color: #519F50}.ace-merbivore .ace_constant.ace_language {color: #FDC251}.ace-merbivore .ace_constant.ace_library,.ace-merbivore .ace_string,.ace-merbivore .ace_support.ace_constant {color: #8DFF0A}.ace-merbivore .ace_constant.ace_numeric {color: #58C554}.ace-merbivore .ace_invalid {color: #FFFFFF;background-color: #990000}.ace-merbivore .ace_fold {background-color: #FC6F09;border-color: #E6E1DC}.ace-merbivore .ace_comment {font-style: italic;color: #AD2EA4}.ace-merbivore .ace_entity.ace_other.ace_attribute-name {color: #FFFF89}.ace-merbivore .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQFxf3ZXB1df0PAAdsAmERTkEHAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-merbivore_soft.js b/dist/assets/js/vendor/ace-nc/theme-merbivore_soft.js
            new file mode 100644
            index 0000000000..6e21e7b214
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-merbivore_soft.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/merbivore_soft",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-merbivore-soft",t.cssText=".ace-merbivore-soft .ace_gutter {background: #262424;color: #E6E1DC}.ace-merbivore-soft .ace_print-margin {width: 1px;background: #262424}.ace-merbivore-soft {background-color: #1C1C1C;color: #E6E1DC}.ace-merbivore-soft .ace_cursor {color: #FFFFFF}.ace-merbivore-soft .ace_marker-layer .ace_selection {background: #494949}.ace-merbivore-soft.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #1C1C1C;border-radius: 2px}.ace-merbivore-soft .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-merbivore-soft .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #404040}.ace-merbivore-soft .ace_marker-layer .ace_active-line {background: #333435}.ace-merbivore-soft .ace_gutter-active-line {background-color: #333435}.ace-merbivore-soft .ace_marker-layer .ace_selected-word {border: 1px solid #494949}.ace-merbivore-soft .ace_invisible {color: #404040}.ace-merbivore-soft .ace_entity.ace_name.ace_tag,.ace-merbivore-soft .ace_keyword,.ace-merbivore-soft .ace_meta,.ace-merbivore-soft .ace_meta.ace_tag,.ace-merbivore-soft .ace_storage {color: #FC803A}.ace-merbivore-soft .ace_constant,.ace-merbivore-soft .ace_constant.ace_character,.ace-merbivore-soft .ace_constant.ace_character.ace_escape,.ace-merbivore-soft .ace_constant.ace_other,.ace-merbivore-soft .ace_support.ace_type {color: #68C1D8}.ace-merbivore-soft .ace_constant.ace_character.ace_escape {color: #B3E5B4}.ace-merbivore-soft .ace_constant.ace_language {color: #E1C582}.ace-merbivore-soft .ace_constant.ace_library,.ace-merbivore-soft .ace_string,.ace-merbivore-soft .ace_support.ace_constant {color: #8EC65F}.ace-merbivore-soft .ace_constant.ace_numeric {color: #7FC578}.ace-merbivore-soft .ace_invalid,.ace-merbivore-soft .ace_invalid.ace_deprecated {color: #FFFFFF;background-color: #FE3838}.ace-merbivore-soft .ace_fold {background-color: #FC803A;border-color: #E6E1DC}.ace-merbivore-soft .ace_comment,.ace-merbivore-soft .ace_meta {font-style: italic;color: #AC4BB8}.ace-merbivore-soft .ace_entity.ace_other.ace_attribute-name {color: #EAF1A3}.ace-merbivore-soft .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWOQkpLyZfD09PwPAAfYAnaStpHRAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-mono_industrial.js b/dist/assets/js/vendor/ace-nc/theme-mono_industrial.js
            new file mode 100644
            index 0000000000..4d6b93c4de
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-mono_industrial.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/mono_industrial",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-mono-industrial",t.cssText=".ace-mono-industrial .ace_gutter {background: #1d2521;color: #C5C9C9}.ace-mono-industrial .ace_print-margin {width: 1px;background: #555651}.ace-mono-industrial {background-color: #222C28;color: #FFFFFF}.ace-mono-industrial .ace_cursor {color: #FFFFFF}.ace-mono-industrial .ace_marker-layer .ace_selection {background: rgba(145, 153, 148, 0.40)}.ace-mono-industrial.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #222C28;border-radius: 2px}.ace-mono-industrial .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-mono-industrial .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(102, 108, 104, 0.50)}.ace-mono-industrial .ace_marker-layer .ace_active-line {background: rgba(12, 13, 12, 0.25)}.ace-mono-industrial .ace_gutter-active-line {background-color: rgba(12, 13, 12, 0.25)}.ace-mono-industrial .ace_marker-layer .ace_selected-word {border: 1px solid rgba(145, 153, 148, 0.40)}.ace-mono-industrial .ace_invisible {color: rgba(102, 108, 104, 0.50)}.ace-mono-industrial .ace_string {background-color: #151C19;color: #FFFFFF}.ace-mono-industrial .ace_keyword,.ace-mono-industrial .ace_meta {color: #A39E64}.ace-mono-industrial .ace_constant,.ace-mono-industrial .ace_constant.ace_character,.ace-mono-industrial .ace_constant.ace_character.ace_escape,.ace-mono-industrial .ace_constant.ace_numeric,.ace-mono-industrial .ace_constant.ace_other {color: #E98800}.ace-mono-industrial .ace_entity.ace_name.ace_function,.ace-mono-industrial .ace_keyword.ace_operator,.ace-mono-industrial .ace_variable {color: #A8B3AB}.ace-mono-industrial .ace_invalid {color: #FFFFFF;background-color: rgba(153, 0, 0, 0.68)}.ace-mono-industrial .ace_support.ace_constant {color: #C87500}.ace-mono-industrial .ace_fold {background-color: #A8B3AB;border-color: #FFFFFF}.ace-mono-industrial .ace_support.ace_function {color: #588E60}.ace-mono-industrial .ace_entity.ace_name,.ace-mono-industrial .ace_support.ace_class,.ace-mono-industrial .ace_support.ace_type {color: #5778B6}.ace-mono-industrial .ace_storage {color: #C23B00}.ace-mono-industrial .ace_variable.ace_language,.ace-mono-industrial .ace_variable.ace_parameter {color: #648BD2}.ace-mono-industrial .ace_comment {color: #666C68;background-color: #151C19}.ace-mono-industrial .ace_entity.ace_other.ace_attribute-name {color: #909993}.ace-mono-industrial .ace_entity.ace_name.ace_tag {color: #A65EFF}.ace-mono-industrial .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNQ1NbwZfALD/4PAAlTArlEC4r/AAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-monokai.js b/dist/assets/js/vendor/ace-nc/theme-monokai.js
            new file mode 100644
            index 0000000000..3a4361c8f7
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-monokai.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-monokai",t.cssText=".ace-monokai .ace_gutter {background: #2F3129;color: #8F908A}.ace-monokai .ace_print-margin {width: 1px;background: #555651}.ace-monokai {background-color: #272822;color: #F8F8F2}.ace-monokai .ace_cursor {color: #F8F8F0}.ace-monokai .ace_marker-layer .ace_selection {background: #49483E}.ace-monokai.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #272822;border-radius: 2px}.ace-monokai .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-monokai .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #49483E}.ace-monokai .ace_marker-layer .ace_active-line {background: #202020}.ace-monokai .ace_gutter-active-line {background-color: #272727}.ace-monokai .ace_marker-layer .ace_selected-word {border: 1px solid #49483E}.ace-monokai .ace_invisible {color: #52524d}.ace-monokai .ace_entity.ace_name.ace_tag,.ace-monokai .ace_keyword,.ace-monokai .ace_meta.ace_tag,.ace-monokai .ace_storage {color: #F92672}.ace-monokai .ace_punctuation,.ace-monokai .ace_punctuation.ace_tag {color: #fff}.ace-monokai .ace_constant.ace_character,.ace-monokai .ace_constant.ace_language,.ace-monokai .ace_constant.ace_numeric,.ace-monokai .ace_constant.ace_other {color: #AE81FF}.ace-monokai .ace_invalid {color: #F8F8F0;background-color: #F92672}.ace-monokai .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #AE81FF}.ace-monokai .ace_support.ace_constant,.ace-monokai .ace_support.ace_function {color: #66D9EF}.ace-monokai .ace_fold {background-color: #A6E22E;border-color: #F8F8F2}.ace-monokai .ace_storage.ace_type,.ace-monokai .ace_support.ace_class,.ace-monokai .ace_support.ace_type {font-style: italic;color: #66D9EF}.ace-monokai .ace_entity.ace_name.ace_function,.ace-monokai .ace_entity.ace_other,.ace-monokai .ace_entity.ace_other.ace_attribute-name,.ace-monokai .ace_variable {color: #A6E22E}.ace-monokai .ace_variable.ace_parameter {font-style: italic;color: #FD971F}.ace-monokai .ace_string {color: #E6DB74}.ace-monokai .ace_comment {color: #75715E}.ace-monokai .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-pastel_on_dark.js b/dist/assets/js/vendor/ace-nc/theme-pastel_on_dark.js
            new file mode 100644
            index 0000000000..e3dee73603
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-pastel_on_dark.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/pastel_on_dark",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-pastel-on-dark",t.cssText=".ace-pastel-on-dark .ace_gutter {background: #353030;color: #8F938F}.ace-pastel-on-dark .ace_print-margin {width: 1px;background: #353030}.ace-pastel-on-dark {background-color: #2C2828;color: #8F938F}.ace-pastel-on-dark .ace_cursor {color: #A7A7A7}.ace-pastel-on-dark .ace_marker-layer .ace_selection {background: rgba(221, 240, 255, 0.20)}.ace-pastel-on-dark.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #2C2828;border-radius: 2px}.ace-pastel-on-dark .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-pastel-on-dark .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(255, 255, 255, 0.25)}.ace-pastel-on-dark .ace_marker-layer .ace_active-line {background: rgba(255, 255, 255, 0.031)}.ace-pastel-on-dark .ace_gutter-active-line {background-color: rgba(255, 255, 255, 0.031)}.ace-pastel-on-dark .ace_marker-layer .ace_selected-word {border: 1px solid rgba(221, 240, 255, 0.20)}.ace-pastel-on-dark .ace_invisible {color: rgba(255, 255, 255, 0.25)}.ace-pastel-on-dark .ace_keyword,.ace-pastel-on-dark .ace_meta {color: #757aD8}.ace-pastel-on-dark .ace_constant,.ace-pastel-on-dark .ace_constant.ace_character,.ace-pastel-on-dark .ace_constant.ace_character.ace_escape,.ace-pastel-on-dark .ace_constant.ace_other {color: #4FB7C5}.ace-pastel-on-dark .ace_keyword.ace_operator {color: #797878}.ace-pastel-on-dark .ace_constant.ace_character {color: #AFA472}.ace-pastel-on-dark .ace_constant.ace_language {color: #DE8E30}.ace-pastel-on-dark .ace_constant.ace_numeric {color: #CCCCCC}.ace-pastel-on-dark .ace_invalid,.ace-pastel-on-dark .ace_invalid.ace_illegal {color: #F8F8F8;background-color: rgba(86, 45, 86, 0.75)}.ace-pastel-on-dark .ace_invalid.ace_deprecated {text-decoration: underline;font-style: italic;color: #D2A8A1}.ace-pastel-on-dark .ace_fold {background-color: #757aD8;border-color: #8F938F}.ace-pastel-on-dark .ace_support.ace_function {color: #AEB2F8}.ace-pastel-on-dark .ace_string {color: #66A968}.ace-pastel-on-dark .ace_string.ace_regexp {color: #E9C062}.ace-pastel-on-dark .ace_comment {color: #A6C6FF}.ace-pastel-on-dark .ace_variable {color: #BEBF55}.ace-pastel-on-dark .ace_variable.ace_language {color: #C1C144}.ace-pastel-on-dark .ace_xml-pe {color: #494949}.ace-pastel-on-dark .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYIiPj/8PAARgAh2NTMh8AAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-solarized_dark.js b/dist/assets/js/vendor/ace-nc/theme-solarized_dark.js
            new file mode 100644
            index 0000000000..34af0338e2
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-solarized_dark.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/solarized_dark",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-solarized-dark",t.cssText=".ace-solarized-dark .ace_gutter {background: #01313f;color: #d0edf7}.ace-solarized-dark .ace_print-margin {width: 1px;background: #33555E}.ace-solarized-dark {background-color: #002B36;color: #93A1A1}.ace-solarized-dark .ace_entity.ace_other.ace_attribute-name,.ace-solarized-dark .ace_storage {color: #93A1A1}.ace-solarized-dark .ace_cursor,.ace-solarized-dark .ace_string.ace_regexp {color: #D30102}.ace-solarized-dark .ace_marker-layer .ace_active-line,.ace-solarized-dark .ace_marker-layer .ace_selection {background: rgba(255, 255, 255, 0.1)}.ace-solarized-dark.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #002B36;border-radius: 2px}.ace-solarized-dark .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-solarized-dark .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(147, 161, 161, 0.50)}.ace-solarized-dark .ace_gutter-active-line {background-color: #0d3440}.ace-solarized-dark .ace_marker-layer .ace_selected-word {border: 1px solid #073642}.ace-solarized-dark .ace_invisible {color: rgba(147, 161, 161, 0.50)}.ace-solarized-dark .ace_keyword,.ace-solarized-dark .ace_meta,.ace-solarized-dark .ace_support.ace_class,.ace-solarized-dark .ace_support.ace_type {color: #859900}.ace-solarized-dark .ace_constant.ace_character,.ace-solarized-dark .ace_constant.ace_other {color: #CB4B16}.ace-solarized-dark .ace_constant.ace_language {color: #B58900}.ace-solarized-dark .ace_constant.ace_numeric {color: #D33682}.ace-solarized-dark .ace_fold {background-color: #268BD2;border-color: #93A1A1}.ace-solarized-dark .ace_entity.ace_name.ace_function,.ace-solarized-dark .ace_entity.ace_name.ace_tag,.ace-solarized-dark .ace_support.ace_function,.ace-solarized-dark .ace_variable,.ace-solarized-dark .ace_variable.ace_language {color: #268BD2}.ace-solarized-dark .ace_string {color: #2AA198}.ace-solarized-dark .ace_comment {font-style: italic;color: #657B83}.ace-solarized-dark .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNg0Db1ZVCxc/sPAAd4AlUHlLenAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-solarized_light.js b/dist/assets/js/vendor/ace-nc/theme-solarized_light.js
            new file mode 100644
            index 0000000000..d785f2baa1
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-solarized_light.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/solarized_light",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-solarized-light",t.cssText=".ace-solarized-light .ace_gutter {background: #fbf1d3;color: #333}.ace-solarized-light .ace_print-margin {width: 1px;background: #e8e8e8}.ace-solarized-light {background-color: #FDF6E3;color: #586E75}.ace-solarized-light .ace_cursor {color: #000000}.ace-solarized-light .ace_marker-layer .ace_selection {background: rgba(7, 54, 67, 0.09)}.ace-solarized-light.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FDF6E3;border-radius: 2px}.ace-solarized-light .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-solarized-light .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(147, 161, 161, 0.50)}.ace-solarized-light .ace_marker-layer .ace_active-line {background: #EEE8D5}.ace-solarized-light .ace_gutter-active-line {background-color : #EDE5C1}.ace-solarized-light .ace_marker-layer .ace_selected-word {border: 1px solid #073642}.ace-solarized-light .ace_invisible {color: rgba(147, 161, 161, 0.50)}.ace-solarized-light .ace_keyword,.ace-solarized-light .ace_meta,.ace-solarized-light .ace_support.ace_class,.ace-solarized-light .ace_support.ace_type {color: #859900}.ace-solarized-light .ace_constant.ace_character,.ace-solarized-light .ace_constant.ace_other {color: #CB4B16}.ace-solarized-light .ace_constant.ace_language {color: #B58900}.ace-solarized-light .ace_constant.ace_numeric {color: #D33682}.ace-solarized-light .ace_fold {background-color: #268BD2;border-color: #586E75}.ace-solarized-light .ace_entity.ace_name.ace_function,.ace-solarized-light .ace_entity.ace_name.ace_tag,.ace-solarized-light .ace_support.ace_function,.ace-solarized-light .ace_variable,.ace-solarized-light .ace_variable.ace_language {color: #268BD2}.ace-solarized-light .ace_storage {color: #073642}.ace-solarized-light .ace_string {color: #2AA198}.ace-solarized-light .ace_string.ace_regexp {color: #D30102}.ace-solarized-light .ace_comment,.ace-solarized-light .ace_entity.ace_other.ace_attribute-name {color: #93A1A1}.ace-solarized-light .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHjy8NJ/AAjgA5fzQUmBAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-terminal.js b/dist/assets/js/vendor/ace-nc/theme-terminal.js
            new file mode 100644
            index 0000000000..494922823c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-terminal.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/terminal",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-terminal-theme",t.cssText=".ace-terminal-theme .ace_gutter {background: #1a0005;color: steelblue}.ace-terminal-theme .ace_print-margin {width: 1px;background: #1a1a1a}.ace-terminal-theme {background-color: black;color: #DEDEDE}.ace-terminal-theme .ace_cursor {color: #9F9F9F}.ace-terminal-theme .ace_marker-layer .ace_selection {background: #424242}.ace-terminal-theme.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px black;border-radius: 2px}.ace-terminal-theme .ace_marker-layer .ace_step {background: rgb(0, 0, 0)}.ace-terminal-theme .ace_marker-layer .ace_bracket {background: #090;}.ace-terminal-theme .ace_marker-layer .ace_bracket-start {background: #090;}.ace-terminal-theme .ace_marker-layer .ace_bracket-unmatched {margin: -1px 0 0 -1px;border: 1px solid #900}.ace-terminal-theme .ace_marker-layer .ace_active-line {background: #2A2A2A}.ace-terminal-theme .ace_gutter-active-line {background-color: #2A112A}.ace-terminal-theme .ace_marker-layer .ace_selected-word {border: 1px solid #424242}.ace-terminal-theme .ace_invisible {color: #343434}.ace-terminal-theme .ace_keyword,.ace-terminal-theme .ace_meta,.ace-terminal-theme .ace_storage,.ace-terminal-theme .ace_storage.ace_type,.ace-terminal-theme .ace_support.ace_type {color: tomato}.ace-terminal-theme .ace_keyword.ace_operator {color: deeppink}.ace-terminal-theme .ace_constant.ace_character,.ace-terminal-theme .ace_constant.ace_language,.ace-terminal-theme .ace_constant.ace_numeric,.ace-terminal-theme .ace_keyword.ace_other.ace_unit,.ace-terminal-theme .ace_support.ace_constant,.ace-terminal-theme .ace_variable.ace_parameter {color: #E78C45}.ace-terminal-theme .ace_constant.ace_other {color: gold}.ace-terminal-theme .ace_invalid {color: yellow;background-color: red}.ace-terminal-theme .ace_invalid.ace_deprecated {color: #CED2CF;background-color: #B798BF}.ace-terminal-theme .ace_fold {background-color: #7AA6DA;border-color: #DEDEDE}.ace-terminal-theme .ace_entity.ace_name.ace_function,.ace-terminal-theme .ace_support.ace_function,.ace-terminal-theme .ace_variable {color: #7AA6DA}.ace-terminal-theme .ace_support.ace_class,.ace-terminal-theme .ace_support.ace_type {color: #E7C547}.ace-terminal-theme .ace_heading,.ace-terminal-theme .ace_string {color: #B9CA4A}.ace-terminal-theme .ace_entity.ace_name.ace_tag,.ace-terminal-theme .ace_entity.ace_other.ace_attribute-name,.ace-terminal-theme .ace_meta.ace_tag,.ace-terminal-theme .ace_string.ace_regexp,.ace-terminal-theme .ace_variable {color: #D54E53}.ace-terminal-theme .ace_comment {color: orangered}.ace-terminal-theme .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYLBWV/8PAAK4AYnhiq+xAAAAAElFTkSuQmCC) right repeat-y;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-textmate.js b/dist/assets/js/vendor/ace-nc/theme-textmate.js
            new file mode 100644
            index 0000000000..24c5e161cd
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-textmate.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/textmate",["require","exports","module","ace/lib/dom"],function(e,t,n){"use strict";t.isDark=!1,t.cssClass="ace-tm",t.cssText='.ace-tm .ace_gutter {background: #f0f0f0;color: #333;}.ace-tm .ace_print-margin {width: 1px;background: #e8e8e8;}.ace-tm .ace_fold {background-color: #6B72E6;}.ace-tm {background-color: #FFFFFF;color: black;}.ace-tm .ace_cursor {color: black;}.ace-tm .ace_invisible {color: rgb(191, 191, 191);}.ace-tm .ace_storage,.ace-tm .ace_keyword {color: blue;}.ace-tm .ace_constant {color: rgb(197, 6, 11);}.ace-tm .ace_constant.ace_buildin {color: rgb(88, 72, 246);}.ace-tm .ace_constant.ace_language {color: rgb(88, 92, 246);}.ace-tm .ace_constant.ace_library {color: rgb(6, 150, 14);}.ace-tm .ace_invalid {background-color: rgba(255, 0, 0, 0.1);color: red;}.ace-tm .ace_support.ace_function {color: rgb(60, 76, 114);}.ace-tm .ace_support.ace_constant {color: rgb(6, 150, 14);}.ace-tm .ace_support.ace_type,.ace-tm .ace_support.ace_class {color: rgb(109, 121, 222);}.ace-tm .ace_keyword.ace_operator {color: rgb(104, 118, 135);}.ace-tm .ace_string {color: rgb(3, 106, 7);}.ace-tm .ace_comment {color: rgb(76, 136, 107);}.ace-tm .ace_comment.ace_doc {color: rgb(0, 102, 255);}.ace-tm .ace_comment.ace_doc.ace_tag {color: rgb(128, 159, 191);}.ace-tm .ace_constant.ace_numeric {color: rgb(0, 0, 205);}.ace-tm .ace_variable {color: rgb(49, 132, 149);}.ace-tm .ace_xml-pe {color: rgb(104, 104, 91);}.ace-tm .ace_entity.ace_name.ace_function {color: #0000A2;}.ace-tm .ace_heading {color: rgb(12, 7, 255);}.ace-tm .ace_list {color:rgb(185, 6, 144);}.ace-tm .ace_meta.ace_tag {color:rgb(0, 22, 142);}.ace-tm .ace_string.ace_regex {color: rgb(255, 0, 0)}.ace-tm .ace_marker-layer .ace_selection {background: rgb(181, 213, 255);}.ace-tm.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px white;border-radius: 2px;}.ace-tm .ace_marker-layer .ace_step {background: rgb(252, 255, 0);}.ace-tm .ace_marker-layer .ace_stack {background: rgb(164, 229, 101);}.ace-tm .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgb(192, 192, 192);}.ace-tm .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.07);}.ace-tm .ace_gutter-active-line {background-color : #dcdcdc;}.ace-tm .ace_marker-layer .ace_selected-word {background: rgb(250, 250, 255);border: 1px solid rgb(200, 200, 250);}.ace-tm .ace_indent-guide {background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==") right repeat-y;}';var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-tomorrow.js b/dist/assets/js/vendor/ace-nc/theme-tomorrow.js
            new file mode 100644
            index 0000000000..0c43059089
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-tomorrow.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/tomorrow",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-tomorrow",t.cssText=".ace-tomorrow .ace_gutter {background: #f6f6f6;color: #4D4D4C}.ace-tomorrow .ace_print-margin {width: 1px;background: #f6f6f6}.ace-tomorrow {background-color: #FFFFFF;color: #4D4D4C}.ace-tomorrow .ace_cursor {color: #AEAFAD}.ace-tomorrow .ace_marker-layer .ace_selection {background: #D6D6D6}.ace-tomorrow.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FFFFFF;border-radius: 2px}.ace-tomorrow .ace_marker-layer .ace_step {background: rgb(255, 255, 0)}.ace-tomorrow .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #D1D1D1}.ace-tomorrow .ace_marker-layer .ace_active-line {background: #EFEFEF}.ace-tomorrow .ace_gutter-active-line {background-color : #dcdcdc}.ace-tomorrow .ace_marker-layer .ace_selected-word {border: 1px solid #D6D6D6}.ace-tomorrow .ace_invisible {color: #D1D1D1}.ace-tomorrow .ace_keyword,.ace-tomorrow .ace_meta,.ace-tomorrow .ace_storage,.ace-tomorrow .ace_storage.ace_type,.ace-tomorrow .ace_support.ace_type {color: #8959A8}.ace-tomorrow .ace_keyword.ace_operator {color: #3E999F}.ace-tomorrow .ace_constant.ace_character,.ace-tomorrow .ace_constant.ace_language,.ace-tomorrow .ace_constant.ace_numeric,.ace-tomorrow .ace_keyword.ace_other.ace_unit,.ace-tomorrow .ace_support.ace_constant,.ace-tomorrow .ace_variable.ace_parameter {color: #F5871F}.ace-tomorrow .ace_constant.ace_other {color: #666969}.ace-tomorrow .ace_invalid {color: #FFFFFF;background-color: #C82829}.ace-tomorrow .ace_invalid.ace_deprecated {color: #FFFFFF;background-color: #8959A8}.ace-tomorrow .ace_fold {background-color: #4271AE;border-color: #4D4D4C}.ace-tomorrow .ace_entity.ace_name.ace_function,.ace-tomorrow .ace_support.ace_function,.ace-tomorrow .ace_variable {color: #4271AE}.ace-tomorrow .ace_support.ace_class,.ace-tomorrow .ace_support.ace_type {color: #C99E00}.ace-tomorrow .ace_heading,.ace-tomorrow .ace_markup.ace_heading,.ace-tomorrow .ace_string {color: #718C00}.ace-tomorrow .ace_entity.ace_name.ace_tag,.ace-tomorrow .ace_entity.ace_other.ace_attribute-name,.ace-tomorrow .ace_meta.ace_tag,.ace-tomorrow .ace_string.ace_regexp,.ace-tomorrow .ace_variable {color: #C82829}.ace-tomorrow .ace_comment {color: #8E908C}.ace-tomorrow .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bdu3f/BwAlfgctduB85QAAAABJRU5ErkJggg==) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-tomorrow_night.js b/dist/assets/js/vendor/ace-nc/theme-tomorrow_night.js
            new file mode 100644
            index 0000000000..d144fa8278
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-tomorrow_night.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/tomorrow_night",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-tomorrow-night",t.cssText=".ace-tomorrow-night .ace_gutter {background: #25282c;color: #C5C8C6}.ace-tomorrow-night .ace_print-margin {width: 1px;background: #25282c}.ace-tomorrow-night {background-color: #1D1F21;color: #C5C8C6}.ace-tomorrow-night .ace_cursor {color: #AEAFAD}.ace-tomorrow-night .ace_marker-layer .ace_selection {background: #373B41}.ace-tomorrow-night.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #1D1F21;border-radius: 2px}.ace-tomorrow-night .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-tomorrow-night .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #4B4E55}.ace-tomorrow-night .ace_marker-layer .ace_active-line {background: #282A2E}.ace-tomorrow-night .ace_gutter-active-line {background-color: #282A2E}.ace-tomorrow-night .ace_marker-layer .ace_selected-word {border: 1px solid #373B41}.ace-tomorrow-night .ace_invisible {color: #4B4E55}.ace-tomorrow-night .ace_keyword,.ace-tomorrow-night .ace_meta,.ace-tomorrow-night .ace_storage,.ace-tomorrow-night .ace_storage.ace_type,.ace-tomorrow-night .ace_support.ace_type {color: #B294BB}.ace-tomorrow-night .ace_keyword.ace_operator {color: #8ABEB7}.ace-tomorrow-night .ace_constant.ace_character,.ace-tomorrow-night .ace_constant.ace_language,.ace-tomorrow-night .ace_constant.ace_numeric,.ace-tomorrow-night .ace_keyword.ace_other.ace_unit,.ace-tomorrow-night .ace_support.ace_constant,.ace-tomorrow-night .ace_variable.ace_parameter {color: #DE935F}.ace-tomorrow-night .ace_constant.ace_other {color: #CED1CF}.ace-tomorrow-night .ace_invalid {color: #CED2CF;background-color: #DF5F5F}.ace-tomorrow-night .ace_invalid.ace_deprecated {color: #CED2CF;background-color: #B798BF}.ace-tomorrow-night .ace_fold {background-color: #81A2BE;border-color: #C5C8C6}.ace-tomorrow-night .ace_entity.ace_name.ace_function,.ace-tomorrow-night .ace_support.ace_function,.ace-tomorrow-night .ace_variable {color: #81A2BE}.ace-tomorrow-night .ace_support.ace_class,.ace-tomorrow-night .ace_support.ace_type {color: #F0C674}.ace-tomorrow-night .ace_heading,.ace-tomorrow-night .ace_markup.ace_heading,.ace-tomorrow-night .ace_string {color: #B5BD68}.ace-tomorrow-night .ace_entity.ace_name.ace_tag,.ace-tomorrow-night .ace_entity.ace_other.ace_attribute-name,.ace-tomorrow-night .ace_meta.ace_tag,.ace-tomorrow-night .ace_string.ace_regexp,.ace-tomorrow-night .ace_variable {color: #CC6666}.ace-tomorrow-night .ace_comment {color: #969896}.ace-tomorrow-night .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYHB3d/8PAAOIAdULw8qMAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-tomorrow_night_blue.js b/dist/assets/js/vendor/ace-nc/theme-tomorrow_night_blue.js
            new file mode 100644
            index 0000000000..8cbe316460
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-tomorrow_night_blue.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/tomorrow_night_blue",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-tomorrow-night-blue",t.cssText=".ace-tomorrow-night-blue .ace_gutter {background: #00204b;color: #7388b5}.ace-tomorrow-night-blue .ace_print-margin {width: 1px;background: #00204b}.ace-tomorrow-night-blue {background-color: #002451;color: #FFFFFF}.ace-tomorrow-night-blue .ace_constant.ace_other,.ace-tomorrow-night-blue .ace_cursor {color: #FFFFFF}.ace-tomorrow-night-blue .ace_marker-layer .ace_selection {background: #003F8E}.ace-tomorrow-night-blue.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #002451;border-radius: 2px}.ace-tomorrow-night-blue .ace_marker-layer .ace_step {background: rgb(127, 111, 19)}.ace-tomorrow-night-blue .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #404F7D}.ace-tomorrow-night-blue .ace_marker-layer .ace_active-line {background: #00346E}.ace-tomorrow-night-blue .ace_gutter-active-line {background-color: #022040}.ace-tomorrow-night-blue .ace_marker-layer .ace_selected-word {border: 1px solid #003F8E}.ace-tomorrow-night-blue .ace_invisible {color: #404F7D}.ace-tomorrow-night-blue .ace_keyword,.ace-tomorrow-night-blue .ace_meta,.ace-tomorrow-night-blue .ace_storage,.ace-tomorrow-night-blue .ace_storage.ace_type,.ace-tomorrow-night-blue .ace_support.ace_type {color: #EBBBFF}.ace-tomorrow-night-blue .ace_keyword.ace_operator {color: #99FFFF}.ace-tomorrow-night-blue .ace_constant.ace_character,.ace-tomorrow-night-blue .ace_constant.ace_language,.ace-tomorrow-night-blue .ace_constant.ace_numeric,.ace-tomorrow-night-blue .ace_keyword.ace_other.ace_unit,.ace-tomorrow-night-blue .ace_support.ace_constant,.ace-tomorrow-night-blue .ace_variable.ace_parameter {color: #FFC58F}.ace-tomorrow-night-blue .ace_invalid {color: #FFFFFF;background-color: #F99DA5}.ace-tomorrow-night-blue .ace_invalid.ace_deprecated {color: #FFFFFF;background-color: #EBBBFF}.ace-tomorrow-night-blue .ace_fold {background-color: #BBDAFF;border-color: #FFFFFF}.ace-tomorrow-night-blue .ace_entity.ace_name.ace_function,.ace-tomorrow-night-blue .ace_support.ace_function,.ace-tomorrow-night-blue .ace_variable {color: #BBDAFF}.ace-tomorrow-night-blue .ace_support.ace_class,.ace-tomorrow-night-blue .ace_support.ace_type {color: #FFEEAD}.ace-tomorrow-night-blue .ace_heading,.ace-tomorrow-night-blue .ace_markup.ace_heading,.ace-tomorrow-night-blue .ace_string {color: #D1F1A9}.ace-tomorrow-night-blue .ace_entity.ace_name.ace_tag,.ace-tomorrow-night-blue .ace_entity.ace_other.ace_attribute-name,.ace-tomorrow-night-blue .ace_meta.ace_tag,.ace-tomorrow-night-blue .ace_string.ace_regexp,.ace-tomorrow-night-blue .ace_variable {color: #FF9DA4}.ace-tomorrow-night-blue .ace_comment {color: #7285B7}.ace-tomorrow-night-blue .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYJDzqfwPAANXAeNsiA+ZAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-tomorrow_night_bright.js b/dist/assets/js/vendor/ace-nc/theme-tomorrow_night_bright.js
            new file mode 100644
            index 0000000000..de5c78e17b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-tomorrow_night_bright.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/tomorrow_night_bright",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-tomorrow-night-bright",t.cssText=".ace-tomorrow-night-bright .ace_gutter {background: #1a1a1a;color: #DEDEDE}.ace-tomorrow-night-bright .ace_print-margin {width: 1px;background: #1a1a1a}.ace-tomorrow-night-bright {background-color: #000000;color: #DEDEDE}.ace-tomorrow-night-bright .ace_cursor {color: #9F9F9F}.ace-tomorrow-night-bright .ace_marker-layer .ace_selection {background: #424242}.ace-tomorrow-night-bright.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #000000;border-radius: 2px}.ace-tomorrow-night-bright .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-tomorrow-night-bright .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #888888}.ace-tomorrow-night-bright .ace_marker-layer .ace_highlight {border: 1px solid rgb(110, 119, 0);border-bottom: 0;box-shadow: inset 0 -1px rgb(110, 119, 0);margin: -1px 0 0 -1px;background: rgba(255, 235, 0, 0.1);}.ace-tomorrow-night-bright .ace_marker-layer .ace_active-line {background: #2A2A2A}.ace-tomorrow-night-bright .ace_gutter-active-line {background-color: #2A2A2A}.ace-tomorrow-night-bright .ace_stack {background-color: rgb(66, 90, 44)}.ace-tomorrow-night-bright .ace_marker-layer .ace_selected-word {border: 1px solid #888888}.ace-tomorrow-night-bright .ace_invisible {color: #343434}.ace-tomorrow-night-bright .ace_keyword,.ace-tomorrow-night-bright .ace_meta,.ace-tomorrow-night-bright .ace_storage,.ace-tomorrow-night-bright .ace_storage.ace_type,.ace-tomorrow-night-bright .ace_support.ace_type {color: #C397D8}.ace-tomorrow-night-bright .ace_keyword.ace_operator {color: #70C0B1}.ace-tomorrow-night-bright .ace_constant.ace_character,.ace-tomorrow-night-bright .ace_constant.ace_language,.ace-tomorrow-night-bright .ace_constant.ace_numeric,.ace-tomorrow-night-bright .ace_keyword.ace_other.ace_unit,.ace-tomorrow-night-bright .ace_support.ace_constant,.ace-tomorrow-night-bright .ace_variable.ace_parameter {color: #E78C45}.ace-tomorrow-night-bright .ace_constant.ace_other {color: #EEEEEE}.ace-tomorrow-night-bright .ace_invalid {color: #CED2CF;background-color: #DF5F5F}.ace-tomorrow-night-bright .ace_invalid.ace_deprecated {color: #CED2CF;background-color: #B798BF}.ace-tomorrow-night-bright .ace_fold {background-color: #7AA6DA;border-color: #DEDEDE}.ace-tomorrow-night-bright .ace_entity.ace_name.ace_function,.ace-tomorrow-night-bright .ace_support.ace_function,.ace-tomorrow-night-bright .ace_variable {color: #7AA6DA}.ace-tomorrow-night-bright .ace_support.ace_class,.ace-tomorrow-night-bright .ace_support.ace_type {color: #E7C547}.ace-tomorrow-night-bright .ace_heading,.ace-tomorrow-night-bright .ace_markup.ace_heading,.ace-tomorrow-night-bright .ace_string {color: #B9CA4A}.ace-tomorrow-night-bright .ace_entity.ace_name.ace_tag,.ace-tomorrow-night-bright .ace_entity.ace_other.ace_attribute-name,.ace-tomorrow-night-bright .ace_meta.ace_tag,.ace-tomorrow-night-bright .ace_string.ace_regexp,.ace-tomorrow-night-bright .ace_variable {color: #D54E53}.ace-tomorrow-night-bright .ace_comment {color: #969896}.ace-tomorrow-night-bright .ace_c9searchresults.ace_keyword {color: #C2C280;}.ace-tomorrow-night-bright .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYFBXV/8PAAJoAXX4kT2EAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-tomorrow_night_eighties.js b/dist/assets/js/vendor/ace-nc/theme-tomorrow_night_eighties.js
            new file mode 100644
            index 0000000000..6dea2cc6f1
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-tomorrow_night_eighties.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/tomorrow_night_eighties",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-tomorrow-night-eighties",t.cssText=".ace-tomorrow-night-eighties .ace_gutter {background: #272727;color: #CCC}.ace-tomorrow-night-eighties .ace_print-margin {width: 1px;background: #272727}.ace-tomorrow-night-eighties {background-color: #2D2D2D;color: #CCCCCC}.ace-tomorrow-night-eighties .ace_constant.ace_other,.ace-tomorrow-night-eighties .ace_cursor {color: #CCCCCC}.ace-tomorrow-night-eighties .ace_marker-layer .ace_selection {background: #515151}.ace-tomorrow-night-eighties.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #2D2D2D;border-radius: 2px}.ace-tomorrow-night-eighties .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-tomorrow-night-eighties .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #6A6A6A}.ace-tomorrow-night-bright .ace_stack {background: rgb(66, 90, 44)}.ace-tomorrow-night-eighties .ace_marker-layer .ace_active-line {background: #393939}.ace-tomorrow-night-eighties .ace_gutter-active-line {background-color: #393939}.ace-tomorrow-night-eighties .ace_marker-layer .ace_selected-word {border: 1px solid #515151}.ace-tomorrow-night-eighties .ace_invisible {color: #6A6A6A}.ace-tomorrow-night-eighties .ace_keyword,.ace-tomorrow-night-eighties .ace_meta,.ace-tomorrow-night-eighties .ace_storage,.ace-tomorrow-night-eighties .ace_storage.ace_type,.ace-tomorrow-night-eighties .ace_support.ace_type {color: #CC99CC}.ace-tomorrow-night-eighties .ace_keyword.ace_operator {color: #66CCCC}.ace-tomorrow-night-eighties .ace_constant.ace_character,.ace-tomorrow-night-eighties .ace_constant.ace_language,.ace-tomorrow-night-eighties .ace_constant.ace_numeric,.ace-tomorrow-night-eighties .ace_keyword.ace_other.ace_unit,.ace-tomorrow-night-eighties .ace_support.ace_constant,.ace-tomorrow-night-eighties .ace_variable.ace_parameter {color: #F99157}.ace-tomorrow-night-eighties .ace_invalid {color: #CDCDCD;background-color: #F2777A}.ace-tomorrow-night-eighties .ace_invalid.ace_deprecated {color: #CDCDCD;background-color: #CC99CC}.ace-tomorrow-night-eighties .ace_fold {background-color: #6699CC;border-color: #CCCCCC}.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_function,.ace-tomorrow-night-eighties .ace_support.ace_function,.ace-tomorrow-night-eighties .ace_variable {color: #6699CC}.ace-tomorrow-night-eighties .ace_support.ace_class,.ace-tomorrow-night-eighties .ace_support.ace_type {color: #FFCC66}.ace-tomorrow-night-eighties .ace_heading,.ace-tomorrow-night-eighties .ace_markup.ace_heading,.ace-tomorrow-night-eighties .ace_string {color: #99CC99}.ace-tomorrow-night-eighties .ace_comment {color: #999999}.ace-tomorrow-night-eighties .ace_entity.ace_name.ace_tag,.ace-tomorrow-night-eighties .ace_entity.ace_other.ace_attribute-name,.ace-tomorrow-night-eighties .ace_meta.ace_tag,.ace-tomorrow-night-eighties .ace_variable {color: #F2777A}.ace-tomorrow-night-eighties .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ09NrYAgMjP4PAAtGAwchHMyAAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-twilight.js b/dist/assets/js/vendor/ace-nc/theme-twilight.js
            new file mode 100644
            index 0000000000..1c5dfda765
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-twilight.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/twilight",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-twilight",t.cssText=".ace-twilight .ace_gutter {background: #232323;color: #E2E2E2}.ace-twilight .ace_print-margin {width: 1px;background: #232323}.ace-twilight {background-color: #141414;color: #F8F8F8}.ace-twilight .ace_cursor {color: #A7A7A7}.ace-twilight .ace_marker-layer .ace_selection {background: rgba(221, 240, 255, 0.20)}.ace-twilight.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #141414;border-radius: 2px}.ace-twilight .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-twilight .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid rgba(255, 255, 255, 0.25)}.ace-twilight .ace_marker-layer .ace_active-line {background: rgba(255, 255, 255, 0.031)}.ace-twilight .ace_gutter-active-line {background-color: rgba(255, 255, 255, 0.031)}.ace-twilight .ace_marker-layer .ace_selected-word {border: 1px solid rgba(221, 240, 255, 0.20)}.ace-twilight .ace_invisible {color: rgba(255, 255, 255, 0.25)}.ace-twilight .ace_keyword,.ace-twilight .ace_meta {color: #CDA869}.ace-twilight .ace_constant,.ace-twilight .ace_constant.ace_character,.ace-twilight .ace_constant.ace_character.ace_escape,.ace-twilight .ace_constant.ace_other,.ace-twilight .ace_heading,.ace-twilight .ace_markup.ace_heading,.ace-twilight .ace_support.ace_constant {color: #CF6A4C}.ace-twilight .ace_invalid.ace_illegal {color: #F8F8F8;background-color: rgba(86, 45, 86, 0.75)}.ace-twilight .ace_invalid.ace_deprecated {text-decoration: underline;font-style: italic;color: #D2A8A1}.ace-twilight .ace_support {color: #9B859D}.ace-twilight .ace_fold {background-color: #AC885B;border-color: #F8F8F8}.ace-twilight .ace_support.ace_function {color: #DAD085}.ace-twilight .ace_list,.ace-twilight .ace_markup.ace_list,.ace-twilight .ace_storage {color: #F9EE98}.ace-twilight .ace_entity.ace_name.ace_function,.ace-twilight .ace_meta.ace_tag,.ace-twilight .ace_variable {color: #AC885B}.ace-twilight .ace_string {color: #8F9D6A}.ace-twilight .ace_string.ace_regexp {color: #E9C062}.ace-twilight .ace_comment {font-style: italic;color: #5F5A60}.ace-twilight .ace_variable {color: #7587A6}.ace-twilight .ace_xml-pe {color: #494949}.ace-twilight .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-vibrant_ink.js b/dist/assets/js/vendor/ace-nc/theme-vibrant_ink.js
            new file mode 100644
            index 0000000000..a0aebbf19f
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-vibrant_ink.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/vibrant_ink",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-vibrant-ink",t.cssText=".ace-vibrant-ink .ace_gutter {background: #1a1a1a;color: #BEBEBE}.ace-vibrant-ink .ace_print-margin {width: 1px;background: #1a1a1a}.ace-vibrant-ink {background-color: #0F0F0F;color: #FFFFFF}.ace-vibrant-ink .ace_cursor {color: #FFFFFF}.ace-vibrant-ink .ace_marker-layer .ace_selection {background: #6699CC}.ace-vibrant-ink.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #0F0F0F;border-radius: 2px}.ace-vibrant-ink .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-vibrant-ink .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #404040}.ace-vibrant-ink .ace_marker-layer .ace_active-line {background: #333333}.ace-vibrant-ink .ace_gutter-active-line {background-color: #333333}.ace-vibrant-ink .ace_marker-layer .ace_selected-word {border: 1px solid #6699CC}.ace-vibrant-ink .ace_invisible {color: #404040}.ace-vibrant-ink .ace_keyword,.ace-vibrant-ink .ace_meta {color: #FF6600}.ace-vibrant-ink .ace_constant,.ace-vibrant-ink .ace_constant.ace_character,.ace-vibrant-ink .ace_constant.ace_character.ace_escape,.ace-vibrant-ink .ace_constant.ace_other {color: #339999}.ace-vibrant-ink .ace_constant.ace_numeric {color: #99CC99}.ace-vibrant-ink .ace_invalid,.ace-vibrant-ink .ace_invalid.ace_deprecated {color: #CCFF33;background-color: #000000}.ace-vibrant-ink .ace_fold {background-color: #FFCC00;border-color: #FFFFFF}.ace-vibrant-ink .ace_entity.ace_name.ace_function,.ace-vibrant-ink .ace_support.ace_function,.ace-vibrant-ink .ace_variable {color: #FFCC00}.ace-vibrant-ink .ace_variable.ace_parameter {font-style: italic}.ace-vibrant-ink .ace_string {color: #66FF00}.ace-vibrant-ink .ace_string.ace_regexp {color: #44B4CC}.ace-vibrant-ink .ace_comment {color: #9933CC}.ace-vibrant-ink .ace_entity.ace_other.ace_attribute-name {font-style: italic;color: #99CC99}.ace-vibrant-ink .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWNgYGBgYNDTc/oPAALPAZ7hxlbYAAAAAElFTkSuQmCC) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/theme-xcode.js b/dist/assets/js/vendor/ace-nc/theme-xcode.js
            new file mode 100644
            index 0000000000..873bd3572d
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/theme-xcode.js
            @@ -0,0 +1 @@
            +ace.define("ace/theme/xcode",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!1,t.cssClass="ace-xcode",t.cssText=".ace-xcode .ace_gutter {background: #e8e8e8;color: #333}.ace-xcode .ace_print-margin {width: 1px;background: #e8e8e8}.ace-xcode {background-color: #FFFFFF;color: #000000}.ace-xcode .ace_cursor {color: #000000}.ace-xcode .ace_marker-layer .ace_selection {background: #B5D5FF}.ace-xcode.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #FFFFFF;border-radius: 2px}.ace-xcode .ace_marker-layer .ace_step {background: rgb(198, 219, 174)}.ace-xcode .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #BFBFBF}.ace-xcode .ace_marker-layer .ace_active-line {background: rgba(0, 0, 0, 0.071)}.ace-xcode .ace_gutter-active-line {background-color: rgba(0, 0, 0, 0.071)}.ace-xcode .ace_marker-layer .ace_selected-word {border: 1px solid #B5D5FF}.ace-xcode .ace_constant.ace_language,.ace-xcode .ace_keyword,.ace-xcode .ace_meta,.ace-xcode .ace_variable.ace_language {color: #C800A4}.ace-xcode .ace_invisible {color: #BFBFBF}.ace-xcode .ace_constant.ace_character,.ace-xcode .ace_constant.ace_other {color: #275A5E}.ace-xcode .ace_constant.ace_numeric {color: #3A00DC}.ace-xcode .ace_entity.ace_other.ace_attribute-name,.ace-xcode .ace_support.ace_constant,.ace-xcode .ace_support.ace_function {color: #450084}.ace-xcode .ace_fold {background-color: #C800A4;border-color: #000000}.ace-xcode .ace_entity.ace_name.ace_tag,.ace-xcode .ace_support.ace_class,.ace-xcode .ace_support.ace_type {color: #790EAD}.ace-xcode .ace_storage {color: #C900A4}.ace-xcode .ace_string {color: #DF0002}.ace-xcode .ace_comment {color: #008E00}.ace-xcode .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==) right repeat-y}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/worker-coffee.js b/dist/assets/js/vendor/ace-nc/worker-coffee.js
            new file mode 100644
            index 0000000000..37508a059c
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/worker-coffee.js
            @@ -0,0 +1 @@
            +"no use strict";(function(e){if(typeof e.window!="undefined"&&e.document)return;e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console,e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){console.error("Worker "+(i?i.stack:e))},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(t,n){n||(n=t,t=null);if(!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;var i=n.split("/");if(!e.require.tlns)return console.log("unable to load "+n);i[0]=e.require.tlns[i[0]]||i[0];var s=i.join("/")+".js";return e.require.id=n,importScripts(s),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id),n.length||(n=["require","exports","module"]);if(t.indexOf("text!")===0)return;var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},e.initBaseUrls=function(t){require.tlns=t},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var i=r.data;if(i.command){if(!t[i.command])throw new Error("Unknown command:"+i.command);t[i.command].apply(t,i.args)}else if(i.init){initBaseUrls(i.tlns),require("ace/lib/es5-shim"),n=e.sender=initSender();var s=require(i.module)[i.classname];t=e.main=new s(n)}else i.event&&n&&n._signal(i.event,i.data)}})(this),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action==="insertText")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action==="insertLines"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action==="removeText"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action=="removeLines"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[""]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},"\n"+t.join("\n")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._signal("change",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._signal("change",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._signal("change",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._signal("change",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this._insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]=="object"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/worker/mirror",["require","exports","module","ace/document","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../document").Document,i=e("../lib/lang"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=i.delayedCall(this.onUpdate.bind(this)),s=this;e.on("change",function(e){t.applyDeltas(e.data);if(s.$timeout)return n.schedule(s.$timeout);s.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(s.prototype)}),ace.define("ace/mode/coffee/rewriter",["require","exports","module"],function(e,t,n){var r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E,S=[].indexOf||function(e){for(var t=0,n=this.length;t<n;t++)if(t in this&&this[t]===e)return t;return-1},x=[].slice;m=function(e,t){var n;return n=[e,t],n.generated=!0,n},t.Rewriter=function(){function e(){}return e.prototype.rewrite=function(e){return this.tokens=e,this.removeLeadingNewlines(),this.closeOpenCalls(),this.closeOpenIndexes(),this.normalizeLines(),this.tagPostfixConditionals(),this.addImplicitBracesAndParens(),this.addLocationDataToGeneratedTokens(),this.tokens},e.prototype.scanTokens=function(e){var t,n,r;r=this.tokens,t=0;while(n=r[t])t+=e.call(this,n,t,r);return!0},e.prototype.detectEnd=function(e,t,n){var r,i,s,a,f;s=this.tokens,r=0;while(i=s[e]){if(r===0&&t.call(this,i,e))return n.call(this,i,e);if(!i||r<0)return n.call(this,i,e-1);if(a=i[0],S.call(u,a)>=0)r+=1;else if(f=i[0],S.call(o,f)>=0)r-=1;e+=1}return e-1},e.prototype.removeLeadingNewlines=function(){var e,t,n,r,i;i=this.tokens;for(e=n=0,r=i.length;n<r;e=++n){t=i[e][0];if(t!=="TERMINATOR")break}if(e)return this.tokens.splice(0,e)},e.prototype.closeOpenCalls=function(){var e,t;return t=function(e,t){var n;return(n=e[0])===")"||n==="CALL_END"||e[0]==="OUTDENT"&&this.tag(t-1)===")"},e=function(e,t){return this.tokens[e[0]==="OUTDENT"?t-1:t][0]="CALL_END"},this.scanTokens(function(n,r){return n[0]==="CALL_START"&&this.detectEnd(r+1,t,e),1})},e.prototype.closeOpenIndexes=function(){var e,t;return t=function(e,t){var n;return(n=e[0])==="]"||n==="INDEX_END"},e=function(e,t){return e[0]="INDEX_END"},this.scanTokens(function(n,r){return n[0]==="INDEX_START"&&this.detectEnd(r+1,t,e),1})},e.prototype.matchTags=function(){var e,t,n,r,i,s,o;t=arguments[0],r=2<=arguments.length?x.call(arguments,1):[],e=0;for(n=i=0,s=r.length;0<=s?i<s:i>s;n=0<=s?++i:--i){while(this.tag(t+n+e)==="HERECOMMENT")e+=2;if(r[n]==null)continue;typeof r[n]=="string"&&(r[n]=[r[n]]);if(o=this.tag(t+n+e),S.call(r[n],o)<0)return!1}return!0},e.prototype.looksObjectish=function(e){return this.matchTags(e,"@",null,":")||this.matchTags(e,null,":")},e.prototype.findTagsBackwards=function(e,t){var n,r,i,s,a,f,l;n=[];while(e>=0&&(n.length||(s=this.tag(e),S.call(t,s)<0)&&((a=this.tag(e),S.call(u,a)<0)||this.tokens[e].generated)&&(f=this.tag(e),S.call(p,f)<0)))(r=this.tag(e),S.call(o,r)>=0)&&n.push(this.tag(e)),(i=this.tag(e),S.call(u,i)>=0)&&n.length&&n.pop(),e-=1;return l=this.tag(e),S.call(t,l)>=0},e.prototype.addImplicitBracesAndParens=function(){var e;return e=[],this.scanTokens(function(t,n,r){var s,h,d,v,g,y,b,w,E,x,T,N,C,k,L,A,O,M,_,D,P,H,B,j,F,I,q,R;H=t[0],T=(N=n>0?r[n-1]:[])[0],E=(n<r.length-1?r[n+1]:[])[0],O=function(){return e[e.length-1]},M=n,v=function(e){return n-M+e},g=function(){var e,t;return(e=O())!=null?(t=e[2])!=null?t.ours:void 0:void 0},y=function(){var e;return g()&&((e=O())!=null?e[0]:void 0)==="("},w=function(){var e;return g()&&((e=O())!=null?e[0]:void 0)==="{"},b=function(){var e;return g&&((e=O())!=null?e[0]:void 0)==="CONTROL"},_=function(t){var i;i=t!=null?t:n,e.push(["(",i,{ours:!0}]),r.splice(i,0,m("CALL_START","("));if(t==null)return n+=1},h=function(){return e.pop(),r.splice(n,0,m("CALL_END",")")),n+=1},s=function(){while(y())h()},D=function(t,i){var s;i==null&&(i=!0),s=t!=null?t:n,e.push(["{",s,{sameLine:!0,startsLine:i,ours:!0}]),r.splice(s,0,m("{",m(new String("{"))));if(t==null)return n+=1},d=function(t){return t=t!=null?t:n,e.pop(),r.splice(t,0,m("}","}")),n+=1};if(!y()||H!=="IF"&&H!=="TRY"&&H!=="FINALLY"&&H!=="CATCH"&&H!=="CLASS"&&H!=="SWITCH"){if(H==="INDENT"&&g()){if(T!=="=>"&&T!=="->"&&T!=="["&&T!=="("&&T!==","&&T!=="{"&&T!=="TRY"&&T!=="ELSE"&&T!=="=")while(y())h();return b()&&e.pop(),e.push([H,n]),v(1)}if(S.call(u,H)>=0)return e.push([H,n]),v(1);if(S.call(o,H)>=0){while(g())y()?h():w()?d():e.pop();e.pop()}if((S.call(l,H)>=0&&t.spaced&&!t.stringEnd||H==="?"&&n>0&&!r[n-1].spaced)&&(S.call(a,E)>=0||S.call(c,E)>=0&&((B=r[n+1])!=null?!B.spaced:!void 0)&&((j=r[n+1])!=null?!j.newLine:!void 0)))return H==="?"&&(H=t[0]="FUNC_EXIST"),_(n+1),v(2);if(S.call(l,H)>=0&&this.matchTags(n+1,"INDENT",null,":")&&!this.findTagsBackwards(n,["CLASS","EXTENDS","IF","CATCH","SWITCH","LEADING_WHEN","FOR","WHILE","UNTIL"]))return _(n+1),e.push(["INDENT",n+2]),v(3);if(H===":"){this.tag(n-2)==="@"?C=n-2:C=n-1;while(this.tag(C-2)==="HERECOMMENT")C-=2;P=C===0||(F=this.tag(C-1),S.call(p,F)>=0)||r[C-1].newLine;if(O()){I=O(),A=I[0],L=I[1];if((A==="{"||A==="INDENT"&&this.tag(L-1)==="{")&&(P||this.tag(C-1)===","||this.tag(C-1)==="{"))return v(1)}return D(C,!!P),v(2)}if(y()&&S.call(i,H)>=0){if(T==="OUTDENT")return h(),v(1);if(N.newLine)return s(),v(1)}w()&&S.call(p,H)>=0&&(O()[2].sameLine=!1);if(S.call(f,H)>=0)while(g()){q=O(),A=q[0],L=q[1],R=q[2],k=R.sameLine,P=R.startsLine;if(y()&&T!==",")h();else if(w()&&k&&!P)d();else{if(!w()||H!=="TERMINATOR"||T===","||!!P&&!!this.looksObjectish(n+1))break;d()}}if(H===","&&!this.looksObjectish(n+1)&&w()&&(E!=="TERMINATOR"||!this.looksObjectish(n+2))){x=E==="OUTDENT"?1:0;while(w())d(n+x)}return v(1)}return e.push(["CONTROL",n,{ours:!0}]),v(1)})},e.prototype.addLocationDataToGeneratedTokens=function(){return this.scanTokens(function(e,t,n){var r,i,s,o,u,a;return e[2]?1:!e.generated&&!e.explicit?1:(e[0]==="{"&&(s=(u=n[t+1])!=null?u[2]:void 0)?(i=s.first_line,r=s.first_column):(o=(a=n[t-1])!=null?a[2]:void 0)?(i=o.last_line,r=o.last_column):i=r=0,e[2]={first_line:i,first_column:r,last_line:i,last_column:r},1)})},e.prototype.normalizeLines=function(){var e,t,n,r,o;return o=n=r=null,t=function(e,t){var n,r,u,a;return e[1]!==";"&&(n=e[0],S.call(d,n)>=0)&&!(e[0]==="TERMINATOR"&&(r=this.tag(t+1),S.call(s,r)>=0))&&(e[0]!=="ELSE"||o==="THEN")&&((u=e[0])!=="CATCH"&&u!=="FINALLY"||o!=="->"&&o!=="=>")||(a=e[0],S.call(i,a)>=0)&&this.tokens[t-1].newLine},e=function(e,t){return this.tokens.splice(this.tag(t-1)===","?t-1:t,0,r)},this.scanTokens(function(i,u,a){var f,l,c,h,p,d;l=i[0];if(l==="TERMINATOR"){if(this.tag(u+1)==="ELSE"&&this.tag(u-1)!=="OUTDENT")return a.splice.apply(a,[u,1].concat(x.call(this.indentation()))),1;if(h=this.tag(u+1),S.call(s,h)>=0)return a.splice(u,1),0}if(l==="CATCH")for(f=c=1;c<=2;f=++c){if((p=this.tag(u+f))!=="OUTDENT"&&p!=="TERMINATOR"&&p!=="FINALLY")continue;return a.splice.apply(a,[u+f,0].concat(x.call(this.indentation()))),2+f}return S.call(v,l)>=0&&this.tag(u+1)!=="INDENT"&&(l!=="ELSE"||this.tag(u+1)!=="IF")?(o=l,d=this.indentation(!0),n=d[0],r=d[1],o==="THEN"&&(n.fromThen=!0),a.splice(u+1,0,n),this.detectEnd(u+2,t,e),l==="THEN"&&a.splice(u,1),1):1})},e.prototype.tagPostfixConditionals=function(){var e,t,n;return n=null,t=function(e,t){var n,r;return r=e[0],n=this.tokens[t-1][0],r==="TERMINATOR"||r==="INDENT"&&S.call(v,n)<0},e=function(e,t){if(e[0]!=="INDENT"||e.generated&&!e.fromThen)return n[0]="POST_"+n[0]},this.scanTokens(function(r,i){return r[0]!=="IF"?1:(n=r,this.detectEnd(i+1,t,e),1)})},e.prototype.indentation=function(e){var t,n;return e==null&&(e=!1),t=["INDENT",2],n=["OUTDENT",2],e&&(t.generated=n.generated=!0),e||(t.explicit=n.explicit=!0),[t,n]},e.prototype.generate=m,e.prototype.tag=function(e){var t;return(t=this.tokens[e])!=null?t[0]:void 0},e}(),r=[["(",")"],["[","]"],["{","}"],["INDENT","OUTDENT"],["CALL_START","CALL_END"],["PARAM_START","PARAM_END"],["INDEX_START","INDEX_END"]],t.INVERSES=h={},u=[],o=[];for(b=0,w=r.length;b<w;b++)E=r[b],g=E[0],y=E[1],u.push(h[y]=g),o.push(h[g]=y);s=["CATCH","THEN","ELSE","FINALLY"].concat(o),l=["IDENTIFIER","SUPER",")","CALL_END","]","INDEX_END","@","THIS"],a=["IDENTIFIER","NUMBER","STRING","JS","REGEX","NEW","PARAM_START","CLASS","IF","TRY","SWITCH","THIS","BOOL","NULL","UNDEFINED","UNARY","SUPER","THROW","@","->","=>","[","(","{","--","++"],c=["+","-"],f=["POST_IF","FOR","WHILE","UNTIL","WHEN","BY","LOOP","TERMINATOR"],v=["ELSE","->","=>","TRY","FINALLY","THEN"],d=["TERMINATOR","CATCH","FINALLY","ELSE","OUTDENT","LEADING_WHEN"],p=["TERMINATOR","INDENT","OUTDENT"],i=[".","?.","::","?::"]}),ace.define("ace/mode/coffee/helpers",["require","exports","module"],function(e,t,n){var r,i,s,o,u,a,f;t.starts=function(e,t,n){return t===e.substr(n,t.length)},t.ends=function(e,t,n){var r;return r=t.length,t===e.substr(e.length-r-(n||0),r)},t.repeat=u=function(e,t){var n;n="";while(t>0)t&1&&(n+=e),t>>>=1,e+=e;return n},t.compact=function(e){var t,n,r,i;i=[];for(n=0,r=e.length;n<r;n++)t=e[n],t&&i.push(t);return i},t.count=function(e,t){var n,r;n=r=0;if(!t.length)return 1/0;while(r=1+e.indexOf(t,r))n++;return n},t.merge=function(e,t){return i(i({},e),t)},i=t.extend=function(e,t){var n,r;for(n in t)r=t[n],e[n]=r;return e},t.flatten=s=function(e){var t,n,r,i;n=[];for(r=0,i=e.length;r<i;r++)t=e[r],t instanceof Array?n=n.concat(s(t)):n.push(t);return n},t.del=function(e,t){var n;return n=e[t],delete e[t],n},t.last=o=function(e,t){return e[e.length-(t||0)-1]},t.some=(f=Array.prototype.some)!=null?f:function(e){var t,n,r;for(n=0,r=this.length;n<r;n++){t=this[n];if(e(t))return!0}return!1},t.invertLiterate=function(e){var t,n,r;return r=!0,n=function(){var n,i,s,o;s=e.split("\n"),o=[];for(n=0,i=s.length;n<i;n++)t=s[n],r&&/^([ ]{4}|[ ]{0,3}\t)/.test(t)?o.push(t):(r=/^\s*$/.test(t))?o.push(t):o.push("# "+t);return o}(),n.join("\n")},r=function(e,t){return t?{first_line:e.first_line,first_column:e.first_column,last_line:t.last_line,last_column:t.last_column}:e},t.addLocationDataFn=function(e,t){return function(n){return typeof n=="object"&&!!n.updateLocationDataIfMissing&&n.updateLocationDataIfMissing(r(e,t)),n}},t.locationDataToString=function(e){var t;return"2"in e&&"first_line"in e[2]?t=e[2]:"first_line"in e&&(t=e),t?""+(t.first_line+1)+":"+(t.first_column+1)+"-"+(""+(t.last_line+1)+":"+(t.last_column+1)):"No location data"},t.baseFileName=function(e,t,n){var r,i;return t==null&&(t=!1),n==null&&(n=!1),i=n?/\\|\//:/\//,r=e.split(i),e=r[r.length-1],t&&e.indexOf(".")>=0?(r=e.split("."),r.pop(),r[r.length-1]==="coffee"&&r.length>1&&r.pop(),r.join(".")):e},t.isCoffee=function(e){return/\.((lit)?coffee|coffee\.md)$/.test(e)},t.isLiterate=function(e){return/\.(litcoffee|coffee\.md)$/.test(e)},t.throwSyntaxError=function(e,t){var n;throw t.last_line==null&&(t.last_line=t.first_line),t.last_column==null&&(t.last_column=t.first_column),n=new SyntaxError(e),n.location=t,n.toString=a,n.stack=n.toString(),n},t.updateSyntaxError=function(e,t,n){return e.toString===a&&(e.code||(e.code=t),e.filename||(e.filename=n),e.stack=e.toString()),e},a=function(){var e,t,n,r,i,s,o,a,f,l,c,h,p;if(!this.code||!this.location)return Error.prototype.toString.call(this);h=this.location,o=h.first_line,s=h.first_column,f=h.last_line,a=h.last_column,f==null&&(f=o),a==null&&(a=s),i=this.filename||"[stdin]",e=this.code.split("\n")[o],c=s,r=o===f?a+1:e.length,l=u(" ",c)+u("^",r-c),typeof process!="undefined"&&process!==null&&(n=process.stdout.isTTY&&!process.env.NODE_DISABLE_COLORS);if((p=this.colorful)!=null?p:n)t=function(e){return""+e+""},e=e.slice(0,c)+t(e.slice(c,r))+e.slice(r),l=t(l);return""+i+":"+(o+1)+":"+(s+1)+": error: "+this.message+"\n"+e+"\n"+l}}),ace.define("ace/mode/coffee/lexer",["require","exports","module","ace/mode/coffee/rewriter","ace/mode/coffee/helpers"],function(e,t,n){var r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E,S,x,T,N,C,k,L,A,O,M,_,D,P,H,B,j,F,I,q,R,U,z,W,X,V,$,J,K,Q,G,Y,Z,et,tt,nt=[].indexOf||function(e){for(var t=0,n=this.length;t<n;t++)if(t in this&&this[t]===e)return t;return-1};et=e("./rewriter"),F=et.Rewriter,w=et.INVERSES,tt=e("./helpers"),V=tt.count,Y=tt.starts,X=tt.compact,K=tt.last,G=tt.repeat,$=tt.invertLiterate,Q=tt.locationDataToString,Z=tt.throwSyntaxError,t.Lexer=k=function(){function e(){}return e.prototype.tokenize=function(e,t){var n,r,i,s;t==null&&(t={}),this.literate=t.literate,this.indent=0,this.baseIndent=0,this.indebt=0,this.outdebt=0,this.indents=[],this.ends=[],this.tokens=[],this.chunkLine=t.line||0,this.chunkColumn=t.column||0,e=this.clean(e),r=0;while(this.chunk=e.slice(r))n=this.identifierToken()||this.commentToken()||this.whitespaceToken()||this.lineToken()||this.heredocToken()||this.stringToken()||this.numberToken()||this.regexToken()||this.jsToken()||this.literalToken(),s=this.getLineAndColumnFromChunk(n),this.chunkLine=s[0],this.chunkColumn=s[1],r+=n;return this.closeIndentation(),(i=this.ends.pop())&&this.error("missing "+i),t.rewrite===!1?this.tokens:(new F).rewrite(this.tokens)},e.prototype.clean=function(e){return e.charCodeAt(0)===r&&(e=e.slice(1)),e=e.replace(/\r/g,"").replace(U,""),W.test(e)&&(e="\n"+e,this.chunkLine--),this.literate&&(e=$(e)),e},e.prototype.identifierToken=function(){var e,t,n,r,i,s,o,l,c,h,p,d,v,m;return(o=y.exec(this.chunk))?(s=o[0],r=o[1],e=o[2],i=r.length,l=void 0,r==="own"&&this.tag()==="FOR"?(this.token("OWN",r),r.length):(n=e||(c=K(this.tokens))&&((d=c[0])==="."||d==="?."||d==="::"||d==="?::"||!c.spaced&&c[0]==="@"),h="IDENTIFIER",!n&&(nt.call(x,r)>=0||nt.call(f,r)>=0)&&(h=r.toUpperCase(),h==="WHEN"&&(v=this.tag(),nt.call(T,v)>=0)?h="LEADING_WHEN":h==="FOR"?this.seenFor=!0:h==="UNLESS"?h="IF":nt.call(z,h)>=0?h="UNARY":nt.call(B,h)>=0&&(h!=="INSTANCEOF"&&this.seenFor?(h="FOR"+h,this.seenFor=!1):(h="RELATION",this.value()==="!"&&(l=this.tokens.pop(),r="!"+r)))),nt.call(S,r)>=0&&(n?(h="IDENTIFIER",r=new String(r),r.reserved=!0):nt.call(j,r)>=0&&this.error('reserved word "'+r+'"')),n||(nt.call(u,r)>=0&&(r=a[r]),h=function(){switch(r){case"!":return"UNARY";case"==":case"!=":return"COMPARE";case"&&":case"||":return"LOGIC";case"true":case"false":return"BOOL";case"break":case"continue":return"STATEMENT";default:return h}}()),p=this.token(h,r,0,i),l&&(m=[l[2].first_line,l[2].first_column],p[2].first_line=m[0],p[2].first_column=m[1]),e&&(t=s.lastIndexOf(":"),this.token(":",":",t,e.length)),s.length)):0},e.prototype.numberToken=function(){var e,t,n,r,i;if(!(n=D.exec(this.chunk)))return 0;r=n[0],/^0[BOX]/.test(r)?this.error("radix prefix '"+r+"' must be lowercase"):/E/.test(r)&&!/^0x/.test(r)?this.error("exponential notation '"+r+"' must be indicated with a lowercase 'e'"):/^0\d*[89]/.test(r)?this.error("decimal literal '"+r+"' must not be prefixed with '0'"):/^0\d+/.test(r)&&this.error("octal literal '"+r+"' must be prefixed with '0o'"),t=r.length;if(i=/^0o([0-7]+)/.exec(r))r="0x"+parseInt(i[1],8).toString(16);if(e=/^0b([01]+)/.exec(r))r="0x"+parseInt(e[1],2).toString(16);return this.token("NUMBER",r,0,t),t},e.prototype.stringToken=function(){var e,t,n,r;switch(t=this.chunk.charAt(0)){case"'":n=q.exec(this.chunk)[0];break;case'"':n=this.balancedString(this.chunk,'"')}return n?(r=this.removeNewlines(n.slice(1,-1)),t==='"'&&0<n.indexOf("#{",1)?this.interpolateString(r,{strOffset:1,lexedLength:n.length}):this.token("STRING",t+this.escapeLines(r)+t,0,n.length),(e=/^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(n))&&this.error("octal escape sequences "+n+" are not allowed"),n.length):0},e.prototype.heredocToken=function(){var e,t,n,r;return(n=p.exec(this.chunk))?(t=n[0],r=t.charAt(0),e=this.sanitizeHeredoc(n[2],{quote:r,indent:null}),r==='"'&&0<=e.indexOf("#{")?this.interpolateString(e,{heredoc:!0,strOffset:3,lexedLength:t.length}):this.token("STRING",this.makeString(e,r,!0),0,t.length),t.length):0},e.prototype.commentToken=function(){var e,t,n;return(n=this.chunk.match(l))?(e=n[0],t=n[1],t&&this.token("HERECOMMENT",this.sanitizeHeredoc(t,{herecomment:!0,indent:G(" ",this.indent)}),0,e.length),e.length):0},e.prototype.jsToken=function(){var e,t;return this.chunk.charAt(0)!=="`"||!(e=E.exec(this.chunk))?0:(this.token("JS",(t=e[0]).slice(1,-1),0,t.length),t.length)},e.prototype.regexToken=function(){var e,t,n,r,i,s,o;return this.chunk.charAt(0)!=="/"?0:(n=m.exec(this.chunk))?(t=this.heregexToken(n),t):(r=K(this.tokens),r&&(s=r[0],nt.call(r.spaced?M:_,s)>=0)?0:(n=H.exec(this.chunk))?(o=n,n=o[0],i=o[1],e=o[2],i.slice(0,2)==="/*"&&this.error("regular expressions cannot begin with `*`"),i==="//"&&(i="/(?:)/"),this.token("REGEX",""+i+e,0,n.length),n.length):0)},e.prototype.heregexToken=function(e){var t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m;i=e[0],t=e[1],n=e[2];if(0>t.indexOf("#{"))return u=this.escapeLines(t.replace(g,"$1$2").replace(/\//g,"\\/"),!0),u.match(/^\*/)&&this.error("regular expressions cannot begin with `*`"),this.token("REGEX","/"+(u||"(?:)")+"/"+n,0,i.length),i.length;this.token("IDENTIFIER","RegExp",0,0),this.token("CALL_START","(",0,0),l=[],d=this.interpolateString(t,{regex:!0});for(h=0,p=d.length;h<p;h++){f=d[h],a=f[0],c=f[1];if(a==="TOKENS")l.push.apply(l,c);else if(a==="NEOSTRING"){if(!(c=c.replace(g,"$1$2")))continue;c=c.replace(/\\/g,"\\\\"),f[0]="STRING",f[1]=this.makeString(c,'"',!0),l.push(f)}else this.error("Unexpected "+a);o=K(this.tokens),s=["+","+"],s[2]=o[2],l.push(s)}return l.pop(),((v=l[0])!=null?v[0]:void 0)!=="STRING"&&(this.token("STRING",'""',0,0),this.token("+","+",0,0)),(m=this.tokens).push.apply(m,l),n&&(r=i.lastIndexOf(n),this.token(",",",",r,0),this.token("STRING",'"'+n+'"',r,n.length)),this.token(")",")",i.length-1,0),i.length},e.prototype.lineToken=function(){var e,t,n,r,i;if(!(n=O.exec(this.chunk)))return 0;t=n[0],this.seenFor=!1,i=t.length-1-t.lastIndexOf("\n"),r=this.unfinished();if(i-this.indebt===this.indent)return r?this.suppressNewlines():this.newlineToken(0),t.length;if(i>this.indent){if(r)return this.indebt=i-this.indent,this.suppressNewlines(),t.length;if(!this.tokens.length)return this.baseIndent=this.indent=i,t.length;e=i-this.indent+this.outdebt,this.token("INDENT",e,t.length-i,i),this.indents.push(e),this.ends.push("OUTDENT"),this.outdebt=this.indebt=0}else i<this.baseIndent?this.error("missing indentation",t.length):(this.indebt=0,this.outdentToken(this.indent-i,r,t.length));return this.indent=i,t.length},e.prototype.outdentToken=function(e,t,n){var r,i;while(e>0)i=this.indents.length-1,this.indents[i]===void 0?e=0:this.indents[i]===this.outdebt?(e-=this.outdebt,this.outdebt=0):this.indents[i]<this.outdebt?(this.outdebt-=this.indents[i],e-=this.indents[i]):(r=this.indents.pop()+this.outdebt,e-=r,this.outdebt=0,this.pair("OUTDENT"),this.token("OUTDENT",r,0,n));r&&(this.outdebt-=e);while(this.value()===";")this.tokens.pop();return this.tag()!=="TERMINATOR"&&!t&&this.token("TERMINATOR","\n",n,0),this},e.prototype.whitespaceToken=function(){var e,t,n;return!(e=W.exec(this.chunk))&&!(t=this.chunk.charAt(0)==="\n")?0:(n=K(this.tokens),n&&(n[e?"spaced":"newLine"]=!0),e?e[0].length:0)},e.prototype.newlineToken=function(e){while(this.value()===";")this.tokens.pop();return this.tag()!=="TERMINATOR"&&this.token("TERMINATOR","\n",e,0),this},e.prototype.suppressNewlines=function(){return this.value()==="\\"&&this.tokens.pop(),this},e.prototype.literalToken=function(){var e,t,n,r,i,u,a,f;(e=P.exec(this.chunk))?(r=e[0],o.test(r)&&this.tagParameters()):r=this.chunk.charAt(0),n=r,t=K(this.tokens);if(r==="="&&t){!t[1].reserved&&(i=t[1],nt.call(S,i)>=0)&&this.error('reserved word "'+this.value()+"\" can't be assigned");if((u=t[1])==="||"||u==="&&")return t[0]="COMPOUND_ASSIGN",t[1]+="=",r.length}if(r===";")this.seenFor=!1,n="TERMINATOR";else if(nt.call(L,r)>=0)n="MATH";else if(nt.call(c,r)>=0)n="COMPARE";else if(nt.call(h,r)>=0)n="COMPOUND_ASSIGN";else if(nt.call(z,r)>=0)n="UNARY";else if(nt.call(I,r)>=0)n="SHIFT";else if(nt.call(C,r)>=0||r==="?"&&(t!=null?t.spaced:void 0))n="LOGIC";else if(t&&!t.spaced)if(r==="("&&(a=t[0],nt.call(s,a)>=0))t[0]==="?"&&(t[0]="FUNC_EXIST"),n="CALL_START";else if(r==="["&&(f=t[0],nt.call(b,f)>=0)){n="INDEX_START";switch(t[0]){case"?":t[0]="INDEX_SOAK"}}switch(r){case"(":case"{":case"[":this.ends.push(w[r]);break;case")":case"}":case"]":this.pair(r)}return this.token(n,r),r.length},e.prototype.sanitizeHeredoc=function(e,t){var n,r,i,s,o;i=t.indent,r=t.herecomment;if(r){d.test(e)&&this.error('block comment cannot contain "*/", starting');if(e.indexOf("\n")<0)return e}else while(s=v.exec(e)){n=s[1];if(i===null||0<(o=n.length)&&o<i.length)i=n}return i&&(e=e.replace(RegExp("\\n"+i,"g"),"\n")),r||(e=e.replace(/^\n/,"")),e},e.prototype.tagParameters=function(){var e,t,n,r;if(this.tag()!==")")return this;t=[],r=this.tokens,e=r.length,r[--e][0]="PARAM_END";while(n=r[--e])switch(n[0]){case")":t.push(n);break;case"(":case"CALL_START":if(!t.length)return n[0]==="("?(n[0]="PARAM_START",this):this;t.pop()}return this},e.prototype.closeIndentation=function(){return this.outdentToken(this.indent)},e.prototype.balancedString=function(e,t){var n,r,i,s,o,u,a,f;n=0,u=[t];for(r=a=1,f=e.length;1<=f?a<f:a>f;r=1<=f?++a:--a){if(n){--n;continue}switch(i=e.charAt(r)){case"\\":++n;continue;case t:u.pop();if(!u.length)return e.slice(0,+r+1||9e9);t=u[u.length-1];continue}t!=="}"||i!=='"'&&i!=="'"?t==="}"&&i==="/"&&(s=m.exec(e.slice(r))||H.exec(e.slice(r)))?n+=s[0].length-1:t==="}"&&i==="{"?u.push(t="}"):t==='"'&&o==="#"&&i==="{"&&u.push(t="}"):u.push(t=i),o=i}return this.error("missing "+u.pop()+", starting")},e.prototype.interpolateString=function(t,n){var r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E,S,x,T,N,C,k,L,A,O;n==null&&(n={}),s=n.heredoc,b=n.regex,v=n.offsetInChunk,E=n.strOffset,c=n.lexedLength,v=v||0,E=E||0,c=c||t.length,T=[],m=0,o=-1;while(l=t.charAt(o+=1)){if(l==="\\"){o+=1;continue}if(l!=="#"||t.charAt(o+1)!=="{"||!(i=this.balancedString(t.slice(o+1),"}")))continue;m<o&&T.push(this.makeToken("NEOSTRING",t.slice(m,o),E+m)),u=i.slice(1,-1);if(u.length){L=this.getLineAndColumnFromChunk(E+o+1),h=L[0],r=L[1],d=(new e).tokenize(u,{line:h,column:r,rewrite:!1}),y=d.pop(),((A=d[0])!=null?A[0]:void 0)==="TERMINATOR"&&(y=d.shift());if(f=d.length)f>1&&(d.unshift(this.makeToken("(","(",E+o+1,0)),d.push(this.makeToken(")",")",E+o+1+u.length,0))),T.push(["TOKENS",d])}o+=i.length,m=o+1}o>m&&m<t.length&&T.push(this.makeToken("NEOSTRING",t.slice(m),E+m));if(b)return T;if(!T.length)return this.token("STRING",'""',v,c);T[0][0]!=="NEOSTRING"&&T.unshift(this.makeToken("NEOSTRING","",v)),(a=T.length>1)&&this.token("(","(",v,0);for(o=C=0,k=T.length;C<k;o=++C)x=T[o],S=x[0],N=x[1],o&&(o&&(g=this.token("+","+")),p=S==="TOKENS"?N[0]:x,g[2]={first_line:p[2].first_line,first_column:p[2].first_column,last_line:p[2].first_line,last_column:p[2].first_column}),S==="TOKENS"?(O=this.tokens).push.apply(O,N):S==="NEOSTRING"?(x[0]="STRING",x[1]=this.makeString(N,'"',s),this.tokens.push(x)):this.error("Unexpected "+S);return a&&(w=this.makeToken(")",")",v+c,0),w.stringEnd=!0,this.tokens.push(w)),T},e.prototype.pair=function(e){var t,n;return e!==(n=K(this.ends))?("OUTDENT"!==n&&this.error("unmatched "+e),this.indent-=t=K(this.indents),this.outdentToken(t,!0),this.pair(e)):this.ends.pop()},e.prototype.getLineAndColumnFromChunk=function(e){var t,n,r,i;return e===0?[this.chunkLine,this.chunkColumn]:(e>=this.chunk.length?i=this.chunk:i=this.chunk.slice(0,+(e-1)+1||9e9),n=V(i,"\n"),t=this.chunkColumn,n>0?(r=i.split("\n"),t=K(r).length):t+=i.length,[this.chunkLine+n,t])},e.prototype.makeToken=function(e,t,n,r){var i,s,o,u,a;return n==null&&(n=0),r==null&&(r=t.length),s={},u=this.getLineAndColumnFromChunk(n),s.first_line=u[0],s.first_column=u[1],i=Math.max(0,r-1),a=this.getLineAndColumnFromChunk(n+i),s.last_line=a[0],s.last_column=a[1],o=[e,t,s],o},e.prototype.token=function(e,t,n,r){var i;return i=this.makeToken(e,t,n,r),this.tokens.push(i),i},e.prototype.tag=function(e,t){var n;return(n=K(this.tokens,e))&&(t?n[0]=t:n[0])},e.prototype.value=function(e,t){var n;return(n=K(this.tokens,e))&&(t?n[1]=t:n[1])},e.prototype.unfinished=function(){var e;return N.test(this.chunk)||(e=this.tag())==="\\"||e==="."||e==="?."||e==="?::"||e==="UNARY"||e==="MATH"||e==="+"||e==="-"||e==="SHIFT"||e==="RELATION"||e==="COMPARE"||e==="LOGIC"||e==="THROW"||e==="EXTENDS"},e.prototype.removeNewlines=function(e){return e.replace(/^\s*\n\s*/,"").replace(/([^\\]|\\\\)\s*\n\s*$/,"$1")},e.prototype.escapeLines=function(e,t){return e=e.replace(/\\[^\S\n]*(\n|\\)\s*/g,function(e,t){return t==="\n"?"":e}),t?e.replace(A,"\\n"):e.replace(/\s*\n\s*/g," ")},e.prototype.makeString=function(e,t,n){return e?(e=e.replace(RegExp("\\\\("+t+"|\\\\)","g"),function(e,n){return n===t?n:e}),e=e.replace(RegExp(""+t,"g"),"\\$&"),t+this.escapeLines(e,n)+t):t+t},e.prototype.error=function(e,t){var n,r,i;return t==null&&(t=0),i=this.getLineAndColumnFromChunk(t),r=i[0],n=i[1],Z(e,{first_line:r,first_column:n})},e}(),x=["true","false","null","this","new","delete","typeof","in","instanceof","return","throw","break","continue","debugger","if","else","switch","for","while","do","try","catch","finally","class","extends","super"],f=["undefined","then","unless","until","loop","of","by","when"],a={and:"&&",or:"||",is:"==",isnt:"!=",not:"!",yes:"true",no:"false",on:"true",off:"false"},u=function(){var e;e=[];for(J in a)e.push(J);return e}(),f=f.concat(u),j=["case","default","function","var","void","with","const","let","enum","export","import","native","__hasProp","__extends","__slice","__bind","__indexOf","implements","interface","package","private","protected","public","static","yield"],R=["arguments","eval"],S=x.concat(j).concat(R),t.RESERVED=j.concat(x).concat(f).concat(R),t.STRICT_PROSCRIBED=R,r=65279,y=/^([$A-Za-z_\x7f-\uffff][$\w\x7f-\uffff]*)([^\n\S]*:(?!:))?/,D=/^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i,p=/^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/,P=/^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?(\.|::)|\.{2,3})/,W=/^[^\n\S]+/,l=/^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/,o=/^[-=]>/,O=/^(?:\n[^\n\S]*)+/,q=/^'[^\\']*(?:\\[\s\S][^\\']*)*'/,E=/^`[^\\`]*(?:\\.[^\\`]*)*`/,H=/^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/,m=/^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/,g=/((?:\\\\)+)|\\(\s|\/)|\s+(?:#.*)?/g,A=/\n/g,v=/\n+([^\n\S]*)/g,d=/\*\//,N=/^\s*(?:,|\??\.(?![.\d])|::)/,U=/\s+$/,h=["-=","+=","/=","*=","%=","||=","&&=","?=","<<=",">>=",">>>=","&=","^=","|="],z=["!","~","NEW","TYPEOF","DELETE","DO"],C=["&&","||","&","|","^"],I=["<<",">>",">>>"],c=["==","!=","<",">","<=",">="],L=["*","/","%"],B=["IN","OF","INSTANCEOF"],i=["TRUE","FALSE"],M=["NUMBER","REGEX","BOOL","NULL","UNDEFINED","++","--"],_=M.concat(")","}","THIS","IDENTIFIER","STRING","]"),s=["IDENTIFIER","STRING","REGEX",")","]","}","?","::","@","THIS","SUPER"],b=s.concat("NUMBER","BOOL","NULL","UNDEFINED"),T=["INDENT","OUTDENT","TERMINATOR"]}),ace.define("ace/mode/coffee/parser",["require","exports","module"],function(e,t,n){function i(){this.yy={}}var r={trace:function(){},yy:{},symbols_:{error:2,Root:3,Body:4,Line:5,TERMINATOR:6,Expression:7,Statement:8,Return:9,Comment:10,STATEMENT:11,Value:12,Invocation:13,Code:14,Operation:15,Assign:16,If:17,Try:18,While:19,For:20,Switch:21,Class:22,Throw:23,Block:24,INDENT:25,OUTDENT:26,Identifier:27,IDENTIFIER:28,AlphaNumeric:29,NUMBER:30,STRING:31,Literal:32,JS:33,REGEX:34,DEBUGGER:35,UNDEFINED:36,NULL:37,BOOL:38,Assignable:39,"=":40,AssignObj:41,ObjAssignable:42,":":43,ThisProperty:44,RETURN:45,HERECOMMENT:46,PARAM_START:47,ParamList:48,PARAM_END:49,FuncGlyph:50,"->":51,"=>":52,OptComma:53,",":54,Param:55,ParamVar:56,"...":57,Array:58,Object:59,Splat:60,SimpleAssignable:61,Accessor:62,Parenthetical:63,Range:64,This:65,".":66,"?.":67,"::":68,"?::":69,Index:70,INDEX_START:71,IndexValue:72,INDEX_END:73,INDEX_SOAK:74,Slice:75,"{":76,AssignList:77,"}":78,CLASS:79,EXTENDS:80,OptFuncExist:81,Arguments:82,SUPER:83,FUNC_EXIST:84,CALL_START:85,CALL_END:86,ArgList:87,THIS:88,"@":89,"[":90,"]":91,RangeDots:92,"..":93,Arg:94,SimpleArgs:95,TRY:96,Catch:97,FINALLY:98,CATCH:99,THROW:100,"(":101,")":102,WhileSource:103,WHILE:104,WHEN:105,UNTIL:106,Loop:107,LOOP:108,ForBody:109,FOR:110,ForStart:111,ForSource:112,ForVariables:113,OWN:114,ForValue:115,FORIN:116,FOROF:117,BY:118,SWITCH:119,Whens:120,ELSE:121,When:122,LEADING_WHEN:123,IfBlock:124,IF:125,POST_IF:126,UNARY:127,"-":128,"+":129,"--":130,"++":131,"?":132,MATH:133,SHIFT:134,COMPARE:135,LOGIC:136,RELATION:137,COMPOUND_ASSIGN:138,$accept:0,$end:1},terminals_:{2:"error",6:"TERMINATOR",11:"STATEMENT",25:"INDENT",26:"OUTDENT",28:"IDENTIFIER",30:"NUMBER",31:"STRING",33:"JS",34:"REGEX",35:"DEBUGGER",36:"UNDEFINED",37:"NULL",38:"BOOL",40:"=",43:":",45:"RETURN",46:"HERECOMMENT",47:"PARAM_START",49:"PARAM_END",51:"->",52:"=>",54:",",57:"...",66:".",67:"?.",68:"::",69:"?::",71:"INDEX_START",73:"INDEX_END",74:"INDEX_SOAK",76:"{",78:"}",79:"CLASS",80:"EXTENDS",83:"SUPER",84:"FUNC_EXIST",85:"CALL_START",86:"CALL_END",88:"THIS",89:"@",90:"[",91:"]",93:"..",96:"TRY",98:"FINALLY",99:"CATCH",100:"THROW",101:"(",102:")",104:"WHILE",105:"WHEN",106:"UNTIL",108:"LOOP",110:"FOR",114:"OWN",116:"FORIN",117:"FOROF",118:"BY",119:"SWITCH",121:"ELSE",123:"LEADING_WHEN",125:"IF",126:"POST_IF",127:"UNARY",128:"-",129:"+",130:"--",131:"++",132:"?",133:"MATH",134:"SHIFT",135:"COMPARE",136:"LOGIC",137:"RELATION",138:"COMPOUND_ASSIGN"},productions_:[0,[3,0],[3,1],[4,1],[4,3],[4,2],[5,1],[5,1],[8,1],[8,1],[8,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[24,2],[24,3],[27,1],[29,1],[29,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[32,1],[16,3],[16,4],[16,5],[41,1],[41,3],[41,5],[41,1],[42,1],[42,1],[42,1],[9,2],[9,1],[10,1],[14,5],[14,2],[50,1],[50,1],[53,0],[53,1],[48,0],[48,1],[48,3],[48,4],[48,6],[55,1],[55,2],[55,3],[56,1],[56,1],[56,1],[56,1],[60,2],[61,1],[61,2],[61,2],[61,1],[39,1],[39,1],[39,1],[12,1],[12,1],[12,1],[12,1],[12,1],[62,2],[62,2],[62,2],[62,2],[62,1],[62,1],[70,3],[70,2],[72,1],[72,1],[59,4],[77,0],[77,1],[77,3],[77,4],[77,6],[22,1],[22,2],[22,3],[22,4],[22,2],[22,3],[22,4],[22,5],[13,3],[13,3],[13,1],[13,2],[81,0],[81,1],[82,2],[82,4],[65,1],[65,1],[44,2],[58,2],[58,4],[92,1],[92,1],[64,5],[75,3],[75,2],[75,2],[75,1],[87,1],[87,3],[87,4],[87,4],[87,6],[94,1],[94,1],[95,1],[95,3],[18,2],[18,3],[18,4],[18,5],[97,3],[97,3],[97,2],[23,2],[63,3],[63,5],[103,2],[103,4],[103,2],[103,4],[19,2],[19,2],[19,2],[19,1],[107,2],[107,2],[20,2],[20,2],[20,2],[109,2],[109,2],[111,2],[111,3],[115,1],[115,1],[115,1],[115,1],[113,1],[113,3],[112,2],[112,2],[112,4],[112,4],[112,4],[112,6],[112,6],[21,5],[21,7],[21,4],[21,6],[120,1],[120,2],[122,3],[122,4],[124,3],[124,5],[17,1],[17,3],[17,3],[17,3],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,2],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,3],[15,5],[15,4],[15,3]],performAction:function(t,n,r,i,s,o,u){var a=o.length-1;switch(s){case 1:return this.$=i.addLocationDataFn(u[a],u[a])(new i.Block);case 2:return this.$=o[a];case 3:this.$=i.addLocationDataFn(u[a],u[a])(i.Block.wrap([o[a]]));break;case 4:this.$=i.addLocationDataFn(u[a-2],u[a])(o[a-2].push(o[a]));break;case 5:this.$=o[a-1];break;case 6:this.$=o[a];break;case 7:this.$=o[a];break;case 8:this.$=o[a];break;case 9:this.$=o[a];break;case 10:this.$=i.addLocationDataFn(u[a],u[a])(new i.Literal(o[a]));break;case 11:this.$=o[a];break;case 12:this.$=o[a];break;case 13:this.$=o[a];break;case 14:this.$=o[a];break;case 15:this.$=o[a];break;case 16:this.$=o[a];break;case 17:this.$=o[a];break;case 18:this.$=o[a];break;case 19:this.$=o[a];break;case 20:this.$=o[a];break;case 21:this.$=o[a];break;case 22:this.$=o[a];break;case 23:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Block);break;case 24:this.$=i.addLocationDataFn(u[a-2],u[a])(o[a-1]);break;case 25:this.$=i.addLocationDataFn(u[a],u[a])(new i.Literal(o[a]));break;case 26:this.$=i.addLocationDataFn(u[a],u[a])(new i.Literal(o[a]));break;case 27:this.$=i.addLocationDataFn(u[a],u[a])(new i.Literal(o[a]));break;case 28:this.$=o[a];break;case 29:this.$=i.addLocationDataFn(u[a],u[a])(new i.Literal(o[a]));break;case 30:this.$=i.addLocationDataFn(u[a],u[a])(new i.Literal(o[a]));break;case 31:this.$=i.addLocationDataFn(u[a],u[a])(new i.Literal(o[a]));break;case 32:this.$=i.addLocationDataFn(u[a],u[a])(new i.Undefined);break;case 33:this.$=i.addLocationDataFn(u[a],u[a])(new i.Null);break;case 34:this.$=i.addLocationDataFn(u[a],u[a])(new i.Bool(o[a]));break;case 35:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Assign(o[a-2],o[a]));break;case 36:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.Assign(o[a-3],o[a]));break;case 37:this.$=i.addLocationDataFn(u[a-4],u[a])(new i.Assign(o[a-4],o[a-1]));break;case 38:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(o[a]));break;case 39:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Assign(i.addLocationDataFn(u[a-2])(new i.Value(o[a-2])),o[a],"object"));break;case 40:this.$=i.addLocationDataFn(u[a-4],u[a])(new i.Assign(i.addLocationDataFn(u[a-4])(new i.Value(o[a-4])),o[a-1],"object"));break;case 41:this.$=o[a];break;case 42:this.$=o[a];break;case 43:this.$=o[a];break;case 44:this.$=o[a];break;case 45:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Return(o[a]));break;case 46:this.$=i.addLocationDataFn(u[a],u[a])(new i.Return);break;case 47:this.$=i.addLocationDataFn(u[a],u[a])(new i.Comment(o[a]));break;case 48:this.$=i.addLocationDataFn(u[a-4],u[a])(new i.Code(o[a-3],o[a],o[a-1]));break;case 49:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Code([],o[a],o[a-1]));break;case 50:this.$=i.addLocationDataFn(u[a],u[a])("func");break;case 51:this.$=i.addLocationDataFn(u[a],u[a])("boundfunc");break;case 52:this.$=o[a];break;case 53:this.$=o[a];break;case 54:this.$=i.addLocationDataFn(u[a],u[a])([]);break;case 55:this.$=i.addLocationDataFn(u[a],u[a])([o[a]]);break;case 56:this.$=i.addLocationDataFn(u[a-2],u[a])(o[a-2].concat(o[a]));break;case 57:this.$=i.addLocationDataFn(u[a-3],u[a])(o[a-3].concat(o[a]));break;case 58:this.$=i.addLocationDataFn(u[a-5],u[a])(o[a-5].concat(o[a-2]));break;case 59:this.$=i.addLocationDataFn(u[a],u[a])(new i.Param(o[a]));break;case 60:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Param(o[a-1],null,!0));break;case 61:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Param(o[a-2],o[a]));break;case 62:this.$=o[a];break;case 63:this.$=o[a];break;case 64:this.$=o[a];break;case 65:this.$=o[a];break;case 66:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Splat(o[a-1]));break;case 67:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(o[a]));break;case 68:this.$=i.addLocationDataFn(u[a-1],u[a])(o[a-1].add(o[a]));break;case 69:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Value(o[a-1],[].concat(o[a])));break;case 70:this.$=o[a];break;case 71:this.$=o[a];break;case 72:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(o[a]));break;case 73:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(o[a]));break;case 74:this.$=o[a];break;case 75:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(o[a]));break;case 76:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(o[a]));break;case 77:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(o[a]));break;case 78:this.$=o[a];break;case 79:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Access(o[a]));break;case 80:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Access(o[a],"soak"));break;case 81:this.$=i.addLocationDataFn(u[a-1],u[a])([i.addLocationDataFn(u[a-1])(new i.Access(new i.Literal("prototype"))),i.addLocationDataFn(u[a])(new i.Access(o[a]))]);break;case 82:this.$=i.addLocationDataFn(u[a-1],u[a])([i.addLocationDataFn(u[a-1])(new i.Access(new i.Literal("prototype"),"soak")),i.addLocationDataFn(u[a])(new i.Access(o[a]))]);break;case 83:this.$=i.addLocationDataFn(u[a],u[a])(new i.Access(new i.Literal("prototype")));break;case 84:this.$=o[a];break;case 85:this.$=i.addLocationDataFn(u[a-2],u[a])(o[a-1]);break;case 86:this.$=i.addLocationDataFn(u[a-1],u[a])(i.extend(o[a],{soak:!0}));break;case 87:this.$=i.addLocationDataFn(u[a],u[a])(new i.Index(o[a]));break;case 88:this.$=i.addLocationDataFn(u[a],u[a])(new i.Slice(o[a]));break;case 89:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.Obj(o[a-2],o[a-3].generated));break;case 90:this.$=i.addLocationDataFn(u[a],u[a])([]);break;case 91:this.$=i.addLocationDataFn(u[a],u[a])([o[a]]);break;case 92:this.$=i.addLocationDataFn(u[a-2],u[a])(o[a-2].concat(o[a]));break;case 93:this.$=i.addLocationDataFn(u[a-3],u[a])(o[a-3].concat(o[a]));break;case 94:this.$=i.addLocationDataFn(u[a-5],u[a])(o[a-5].concat(o[a-2]));break;case 95:this.$=i.addLocationDataFn(u[a],u[a])(new i.Class);break;case 96:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Class(null,null,o[a]));break;case 97:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Class(null,o[a]));break;case 98:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.Class(null,o[a-1],o[a]));break;case 99:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Class(o[a]));break;case 100:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Class(o[a-1],null,o[a]));break;case 101:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.Class(o[a-2],o[a]));break;case 102:this.$=i.addLocationDataFn(u[a-4],u[a])(new i.Class(o[a-3],o[a-1],o[a]));break;case 103:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Call(o[a-2],o[a],o[a-1]));break;case 104:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Call(o[a-2],o[a],o[a-1]));break;case 105:this.$=i.addLocationDataFn(u[a],u[a])(new i.Call("super",[new i.Splat(new i.Literal("arguments"))]));break;case 106:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Call("super",o[a]));break;case 107:this.$=i.addLocationDataFn(u[a],u[a])(!1);break;case 108:this.$=i.addLocationDataFn(u[a],u[a])(!0);break;case 109:this.$=i.addLocationDataFn(u[a-1],u[a])([]);break;case 110:this.$=i.addLocationDataFn(u[a-3],u[a])(o[a-2]);break;case 111:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(new i.Literal("this")));break;case 112:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(new i.Literal("this")));break;case 113:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Value(i.addLocationDataFn(u[a-1])(new i.Literal("this")),[i.addLocationDataFn(u[a])(new i.Access(o[a]))],"this"));break;case 114:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Arr([]));break;case 115:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.Arr(o[a-2]));break;case 116:this.$=i.addLocationDataFn(u[a],u[a])("inclusive");break;case 117:this.$=i.addLocationDataFn(u[a],u[a])("exclusive");break;case 118:this.$=i.addLocationDataFn(u[a-4],u[a])(new i.Range(o[a-3],o[a-1],o[a-2]));break;case 119:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Range(o[a-2],o[a],o[a-1]));break;case 120:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Range(o[a-1],null,o[a]));break;case 121:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Range(null,o[a],o[a-1]));break;case 122:this.$=i.addLocationDataFn(u[a],u[a])(new i.Range(null,null,o[a]));break;case 123:this.$=i.addLocationDataFn(u[a],u[a])([o[a]]);break;case 124:this.$=i.addLocationDataFn(u[a-2],u[a])(o[a-2].concat(o[a]));break;case 125:this.$=i.addLocationDataFn(u[a-3],u[a])(o[a-3].concat(o[a]));break;case 126:this.$=i.addLocationDataFn(u[a-3],u[a])(o[a-2]);break;case 127:this.$=i.addLocationDataFn(u[a-5],u[a])(o[a-5].concat(o[a-2]));break;case 128:this.$=o[a];break;case 129:this.$=o[a];break;case 130:this.$=o[a];break;case 131:this.$=i.addLocationDataFn(u[a-2],u[a])([].concat(o[a-2],o[a]));break;case 132:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Try(o[a]));break;case 133:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Try(o[a-1],o[a][0],o[a][1]));break;case 134:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.Try(o[a-2],null,null,o[a]));break;case 135:this.$=i.addLocationDataFn(u[a-4],u[a])(new i.Try(o[a-3],o[a-2][0],o[a-2][1],o[a]));break;case 136:this.$=i.addLocationDataFn(u[a-2],u[a])([o[a-1],o[a]]);break;case 137:this.$=i.addLocationDataFn(u[a-2],u[a])([i.addLocationDataFn(u[a-1])(new i.Value(o[a-1])),o[a]]);break;case 138:this.$=i.addLocationDataFn(u[a-1],u[a])([null,o[a]]);break;case 139:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Throw(o[a]));break;case 140:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Parens(o[a-1]));break;case 141:this.$=i.addLocationDataFn(u[a-4],u[a])(new i.Parens(o[a-2]));break;case 142:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.While(o[a]));break;case 143:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.While(o[a-2],{guard:o[a]}));break;case 144:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.While(o[a],{invert:!0}));break;case 145:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.While(o[a-2],{invert:!0,guard:o[a]}));break;case 146:this.$=i.addLocationDataFn(u[a-1],u[a])(o[a-1].addBody(o[a]));break;case 147:this.$=i.addLocationDataFn(u[a-1],u[a])(o[a].addBody(i.addLocationDataFn(u[a-1])(i.Block.wrap([o[a-1]]))));break;case 148:this.$=i.addLocationDataFn(u[a-1],u[a])(o[a].addBody(i.addLocationDataFn(u[a-1])(i.Block.wrap([o[a-1]]))));break;case 149:this.$=i.addLocationDataFn(u[a],u[a])(o[a]);break;case 150:this.$=i.addLocationDataFn(u[a-1],u[a])((new i.While(i.addLocationDataFn(u[a-1])(new i.Literal("true")))).addBody(o[a]));break;case 151:this.$=i.addLocationDataFn(u[a-1],u[a])((new i.While(i.addLocationDataFn(u[a-1])(new i.Literal("true")))).addBody(i.addLocationDataFn(u[a])(i.Block.wrap([o[a]]))));break;case 152:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.For(o[a-1],o[a]));break;case 153:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.For(o[a-1],o[a]));break;case 154:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.For(o[a],o[a-1]));break;case 155:this.$=i.addLocationDataFn(u[a-1],u[a])({source:i.addLocationDataFn(u[a])(new i.Value(o[a]))});break;case 156:this.$=i.addLocationDataFn(u[a-1],u[a])(function(){return o[a].own=o[a-1].own,o[a].name=o[a-1][0],o[a].index=o[a-1][1],o[a]}());break;case 157:this.$=i.addLocationDataFn(u[a-1],u[a])(o[a]);break;case 158:this.$=i.addLocationDataFn(u[a-2],u[a])(function(){return o[a].own=!0,o[a]}());break;case 159:this.$=o[a];break;case 160:this.$=o[a];break;case 161:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(o[a]));break;case 162:this.$=i.addLocationDataFn(u[a],u[a])(new i.Value(o[a]));break;case 163:this.$=i.addLocationDataFn(u[a],u[a])([o[a]]);break;case 164:this.$=i.addLocationDataFn(u[a-2],u[a])([o[a-2],o[a]]);break;case 165:this.$=i.addLocationDataFn(u[a-1],u[a])({source:o[a]});break;case 166:this.$=i.addLocationDataFn(u[a-1],u[a])({source:o[a],object:!0});break;case 167:this.$=i.addLocationDataFn(u[a-3],u[a])({source:o[a-2],guard:o[a]});break;case 168:this.$=i.addLocationDataFn(u[a-3],u[a])({source:o[a-2],guard:o[a],object:!0});break;case 169:this.$=i.addLocationDataFn(u[a-3],u[a])({source:o[a-2],step:o[a]});break;case 170:this.$=i.addLocationDataFn(u[a-5],u[a])({source:o[a-4],guard:o[a-2],step:o[a]});break;case 171:this.$=i.addLocationDataFn(u[a-5],u[a])({source:o[a-4],step:o[a-2],guard:o[a]});break;case 172:this.$=i.addLocationDataFn(u[a-4],u[a])(new i.Switch(o[a-3],o[a-1]));break;case 173:this.$=i.addLocationDataFn(u[a-6],u[a])(new i.Switch(o[a-5],o[a-3],o[a-1]));break;case 174:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.Switch(null,o[a-1]));break;case 175:this.$=i.addLocationDataFn(u[a-5],u[a])(new i.Switch(null,o[a-3],o[a-1]));break;case 176:this.$=o[a];break;case 177:this.$=i.addLocationDataFn(u[a-1],u[a])(o[a-1].concat(o[a]));break;case 178:this.$=i.addLocationDataFn(u[a-2],u[a])([[o[a-1],o[a]]]);break;case 179:this.$=i.addLocationDataFn(u[a-3],u[a])([[o[a-2],o[a-1]]]);break;case 180:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.If(o[a-1],o[a],{type:o[a-2]}));break;case 181:this.$=i.addLocationDataFn(u[a-4],u[a])(o[a-4].addElse(i.addLocationDataFn(u[a-2],u[a])(new i.If(o[a-1],o[a],{type:o[a-2]}))));break;case 182:this.$=o[a];break;case 183:this.$=i.addLocationDataFn(u[a-2],u[a])(o[a-2].addElse(o[a]));break;case 184:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.If(o[a],i.addLocationDataFn(u[a-2])(i.Block.wrap([o[a-2]])),{type:o[a-1],statement:!0}));break;case 185:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.If(o[a],i.addLocationDataFn(u[a-2])(i.Block.wrap([o[a-2]])),{type:o[a-1],statement:!0}));break;case 186:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Op(o[a-1],o[a]));break;case 187:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Op("-",o[a]));break;case 188:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Op("+",o[a]));break;case 189:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Op("--",o[a]));break;case 190:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Op("++",o[a]));break;case 191:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Op("--",o[a-1],null,!0));break;case 192:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Op("++",o[a-1],null,!0));break;case 193:this.$=i.addLocationDataFn(u[a-1],u[a])(new i.Existence(o[a-1]));break;case 194:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Op("+",o[a-2],o[a]));break;case 195:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Op("-",o[a-2],o[a]));break;case 196:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Op(o[a-1],o[a-2],o[a]));break;case 197:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Op(o[a-1],o[a-2],o[a]));break;case 198:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Op(o[a-1],o[a-2],o[a]));break;case 199:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Op(o[a-1],o[a-2],o[a]));break;case 200:this.$=i.addLocationDataFn(u[a-2],u[a])(function(){return o[a-1].charAt(0)==="!"?(new i.Op(o[a-1].slice(1),o[a-2],o[a])).invert():new i.Op(o[a-1],o[a-2],o[a])}());break;case 201:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Assign(o[a-2],o[a],o[a-1]));break;case 202:this.$=i.addLocationDataFn(u[a-4],u[a])(new i.Assign(o[a-4],o[a-1],o[a-3]));break;case 203:this.$=i.addLocationDataFn(u[a-3],u[a])(new i.Assign(o[a-3],o[a],o[a-2]));break;case 204:this.$=i.addLocationDataFn(u[a-2],u[a])(new i.Extends(o[a-2],o[a]))}},table:[{1:[2,1],3:1,4:2,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[3]},{1:[2,2],6:[1,72]},{1:[2,3],6:[2,3],26:[2,3],102:[2,3]},{1:[2,6],6:[2,6],26:[2,6],102:[2,6],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,7],6:[2,7],26:[2,7],102:[2,7],103:85,104:[1,63],106:[1,64],109:86,110:[1,66],111:67,126:[1,84]},{1:[2,11],6:[2,11],25:[2,11],26:[2,11],49:[2,11],54:[2,11],57:[2,11],62:88,66:[1,90],67:[1,91],68:[1,92],69:[1,93],70:94,71:[1,95],73:[2,11],74:[1,96],78:[2,11],81:87,84:[1,89],85:[2,107],86:[2,11],91:[2,11],93:[2,11],102:[2,11],104:[2,11],105:[2,11],106:[2,11],110:[2,11],118:[2,11],126:[2,11],128:[2,11],129:[2,11],132:[2,11],133:[2,11],134:[2,11],135:[2,11],136:[2,11],137:[2,11]},{1:[2,12],6:[2,12],25:[2,12],26:[2,12],49:[2,12],54:[2,12],57:[2,12],62:98,66:[1,90],67:[1,91],68:[1,92],69:[1,93],70:94,71:[1,95],73:[2,12],74:[1,96],78:[2,12],81:97,84:[1,89],85:[2,107],86:[2,12],91:[2,12],93:[2,12],102:[2,12],104:[2,12],105:[2,12],106:[2,12],110:[2,12],118:[2,12],126:[2,12],128:[2,12],129:[2,12],132:[2,12],133:[2,12],134:[2,12],135:[2,12],136:[2,12],137:[2,12]},{1:[2,13],6:[2,13],25:[2,13],26:[2,13],49:[2,13],54:[2,13],57:[2,13],73:[2,13],78:[2,13],86:[2,13],91:[2,13],93:[2,13],102:[2,13],104:[2,13],105:[2,13],106:[2,13],110:[2,13],118:[2,13],126:[2,13],128:[2,13],129:[2,13],132:[2,13],133:[2,13],134:[2,13],135:[2,13],136:[2,13],137:[2,13]},{1:[2,14],6:[2,14],25:[2,14],26:[2,14],49:[2,14],54:[2,14],57:[2,14],73:[2,14],78:[2,14],86:[2,14],91:[2,14],93:[2,14],102:[2,14],104:[2,14],105:[2,14],106:[2,14],110:[2,14],118:[2,14],126:[2,14],128:[2,14],129:[2,14],132:[2,14],133:[2,14],134:[2,14],135:[2,14],136:[2,14],137:[2,14]},{1:[2,15],6:[2,15],25:[2,15],26:[2,15],49:[2,15],54:[2,15],57:[2,15],73:[2,15],78:[2,15],86:[2,15],91:[2,15],93:[2,15],102:[2,15],104:[2,15],105:[2,15],106:[2,15],110:[2,15],118:[2,15],126:[2,15],128:[2,15],129:[2,15],132:[2,15],133:[2,15],134:[2,15],135:[2,15],136:[2,15],137:[2,15]},{1:[2,16],6:[2,16],25:[2,16],26:[2,16],49:[2,16],54:[2,16],57:[2,16],73:[2,16],78:[2,16],86:[2,16],91:[2,16],93:[2,16],102:[2,16],104:[2,16],105:[2,16],106:[2,16],110:[2,16],118:[2,16],126:[2,16],128:[2,16],129:[2,16],132:[2,16],133:[2,16],134:[2,16],135:[2,16],136:[2,16],137:[2,16]},{1:[2,17],6:[2,17],25:[2,17],26:[2,17],49:[2,17],54:[2,17],57:[2,17],73:[2,17],78:[2,17],86:[2,17],91:[2,17],93:[2,17],102:[2,17],104:[2,17],105:[2,17],106:[2,17],110:[2,17],118:[2,17],126:[2,17],128:[2,17],129:[2,17],132:[2,17],133:[2,17],134:[2,17],135:[2,17],136:[2,17],137:[2,17]},{1:[2,18],6:[2,18],25:[2,18],26:[2,18],49:[2,18],54:[2,18],57:[2,18],73:[2,18],78:[2,18],86:[2,18],91:[2,18],93:[2,18],102:[2,18],104:[2,18],105:[2,18],106:[2,18],110:[2,18],118:[2,18],126:[2,18],128:[2,18],129:[2,18],132:[2,18],133:[2,18],134:[2,18],135:[2,18],136:[2,18],137:[2,18]},{1:[2,19],6:[2,19],25:[2,19],26:[2,19],49:[2,19],54:[2,19],57:[2,19],73:[2,19],78:[2,19],86:[2,19],91:[2,19],93:[2,19],102:[2,19],104:[2,19],105:[2,19],106:[2,19],110:[2,19],118:[2,19],126:[2,19],128:[2,19],129:[2,19],132:[2,19],133:[2,19],134:[2,19],135:[2,19],136:[2,19],137:[2,19]},{1:[2,20],6:[2,20],25:[2,20],26:[2,20],49:[2,20],54:[2,20],57:[2,20],73:[2,20],78:[2,20],86:[2,20],91:[2,20],93:[2,20],102:[2,20],104:[2,20],105:[2,20],106:[2,20],110:[2,20],118:[2,20],126:[2,20],128:[2,20],129:[2,20],132:[2,20],133:[2,20],134:[2,20],135:[2,20],136:[2,20],137:[2,20]},{1:[2,21],6:[2,21],25:[2,21],26:[2,21],49:[2,21],54:[2,21],57:[2,21],73:[2,21],78:[2,21],86:[2,21],91:[2,21],93:[2,21],102:[2,21],104:[2,21],105:[2,21],106:[2,21],110:[2,21],118:[2,21],126:[2,21],128:[2,21],129:[2,21],132:[2,21],133:[2,21],134:[2,21],135:[2,21],136:[2,21],137:[2,21]},{1:[2,22],6:[2,22],25:[2,22],26:[2,22],49:[2,22],54:[2,22],57:[2,22],73:[2,22],78:[2,22],86:[2,22],91:[2,22],93:[2,22],102:[2,22],104:[2,22],105:[2,22],106:[2,22],110:[2,22],118:[2,22],126:[2,22],128:[2,22],129:[2,22],132:[2,22],133:[2,22],134:[2,22],135:[2,22],136:[2,22],137:[2,22]},{1:[2,8],6:[2,8],26:[2,8],102:[2,8],104:[2,8],106:[2,8],110:[2,8],126:[2,8]},{1:[2,9],6:[2,9],26:[2,9],102:[2,9],104:[2,9],106:[2,9],110:[2,9],126:[2,9]},{1:[2,10],6:[2,10],26:[2,10],102:[2,10],104:[2,10],106:[2,10],110:[2,10],126:[2,10]},{1:[2,74],6:[2,74],25:[2,74],26:[2,74],40:[1,99],49:[2,74],54:[2,74],57:[2,74],66:[2,74],67:[2,74],68:[2,74],69:[2,74],71:[2,74],73:[2,74],74:[2,74],78:[2,74],84:[2,74],85:[2,74],86:[2,74],91:[2,74],93:[2,74],102:[2,74],104:[2,74],105:[2,74],106:[2,74],110:[2,74],118:[2,74],126:[2,74],128:[2,74],129:[2,74],132:[2,74],133:[2,74],134:[2,74],135:[2,74],136:[2,74],137:[2,74]},{1:[2,75],6:[2,75],25:[2,75],26:[2,75],49:[2,75],54:[2,75],57:[2,75],66:[2,75],67:[2,75],68:[2,75],69:[2,75],71:[2,75],73:[2,75],74:[2,75],78:[2,75],84:[2,75],85:[2,75],86:[2,75],91:[2,75],93:[2,75],102:[2,75],104:[2,75],105:[2,75],106:[2,75],110:[2,75],118:[2,75],126:[2,75],128:[2,75],129:[2,75],132:[2,75],133:[2,75],134:[2,75],135:[2,75],136:[2,75],137:[2,75]},{1:[2,76],6:[2,76],25:[2,76],26:[2,76],49:[2,76],54:[2,76],57:[2,76],66:[2,76],67:[2,76],68:[2,76],69:[2,76],71:[2,76],73:[2,76],74:[2,76],78:[2,76],84:[2,76],85:[2,76],86:[2,76],91:[2,76],93:[2,76],102:[2,76],104:[2,76],105:[2,76],106:[2,76],110:[2,76],118:[2,76],126:[2,76],128:[2,76],129:[2,76],132:[2,76],133:[2,76],134:[2,76],135:[2,76],136:[2,76],137:[2,76]},{1:[2,77],6:[2,77],25:[2,77],26:[2,77],49:[2,77],54:[2,77],57:[2,77],66:[2,77],67:[2,77],68:[2,77],69:[2,77],71:[2,77],73:[2,77],74:[2,77],78:[2,77],84:[2,77],85:[2,77],86:[2,77],91:[2,77],93:[2,77],102:[2,77],104:[2,77],105:[2,77],106:[2,77],110:[2,77],118:[2,77],126:[2,77],128:[2,77],129:[2,77],132:[2,77],133:[2,77],134:[2,77],135:[2,77],136:[2,77],137:[2,77]},{1:[2,78],6:[2,78],25:[2,78],26:[2,78],49:[2,78],54:[2,78],57:[2,78],66:[2,78],67:[2,78],68:[2,78],69:[2,78],71:[2,78],73:[2,78],74:[2,78],78:[2,78],84:[2,78],85:[2,78],86:[2,78],91:[2,78],93:[2,78],102:[2,78],104:[2,78],105:[2,78],106:[2,78],110:[2,78],118:[2,78],126:[2,78],128:[2,78],129:[2,78],132:[2,78],133:[2,78],134:[2,78],135:[2,78],136:[2,78],137:[2,78]},{1:[2,105],6:[2,105],25:[2,105],26:[2,105],49:[2,105],54:[2,105],57:[2,105],66:[2,105],67:[2,105],68:[2,105],69:[2,105],71:[2,105],73:[2,105],74:[2,105],78:[2,105],82:100,84:[2,105],85:[1,101],86:[2,105],91:[2,105],93:[2,105],102:[2,105],104:[2,105],105:[2,105],106:[2,105],110:[2,105],118:[2,105],126:[2,105],128:[2,105],129:[2,105],132:[2,105],133:[2,105],134:[2,105],135:[2,105],136:[2,105],137:[2,105]},{6:[2,54],25:[2,54],27:105,28:[1,71],44:106,48:102,49:[2,54],54:[2,54],55:103,56:104,58:107,59:108,76:[1,68],89:[1,109],90:[1,110]},{24:111,25:[1,112]},{7:113,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:115,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:116,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{12:118,13:119,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:120,44:61,58:45,59:46,61:117,63:23,64:24,65:25,76:[1,68],83:[1,26],88:[1,56],89:[1,57],90:[1,55],101:[1,54]},{12:118,13:119,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:120,44:61,58:45,59:46,61:121,63:23,64:24,65:25,76:[1,68],83:[1,26],88:[1,56],89:[1,57],90:[1,55],101:[1,54]},{1:[2,71],6:[2,71],25:[2,71],26:[2,71],40:[2,71],49:[2,71],54:[2,71],57:[2,71],66:[2,71],67:[2,71],68:[2,71],69:[2,71],71:[2,71],73:[2,71],74:[2,71],78:[2,71],80:[1,125],84:[2,71],85:[2,71],86:[2,71],91:[2,71],93:[2,71],102:[2,71],104:[2,71],105:[2,71],106:[2,71],110:[2,71],118:[2,71],126:[2,71],128:[2,71],129:[2,71],130:[1,122],131:[1,123],132:[2,71],133:[2,71],134:[2,71],135:[2,71],136:[2,71],137:[2,71],138:[1,124]},{1:[2,182],6:[2,182],25:[2,182],26:[2,182],49:[2,182],54:[2,182],57:[2,182],73:[2,182],78:[2,182],86:[2,182],91:[2,182],93:[2,182],102:[2,182],104:[2,182],105:[2,182],106:[2,182],110:[2,182],118:[2,182],121:[1,126],126:[2,182],128:[2,182],129:[2,182],132:[2,182],133:[2,182],134:[2,182],135:[2,182],136:[2,182],137:[2,182]},{24:127,25:[1,112]},{24:128,25:[1,112]},{1:[2,149],6:[2,149],25:[2,149],26:[2,149],49:[2,149],54:[2,149],57:[2,149],73:[2,149],78:[2,149],86:[2,149],91:[2,149],93:[2,149],102:[2,149],104:[2,149],105:[2,149],106:[2,149],110:[2,149],118:[2,149],126:[2,149],128:[2,149],129:[2,149],132:[2,149],133:[2,149],134:[2,149],135:[2,149],136:[2,149],137:[2,149]},{24:129,25:[1,112]},{7:130,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,131],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,95],6:[2,95],12:118,13:119,24:132,25:[1,112],26:[2,95],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:120,44:61,49:[2,95],54:[2,95],57:[2,95],58:45,59:46,61:134,63:23,64:24,65:25,73:[2,95],76:[1,68],78:[2,95],80:[1,133],83:[1,26],86:[2,95],88:[1,56],89:[1,57],90:[1,55],91:[2,95],93:[2,95],101:[1,54],102:[2,95],104:[2,95],105:[2,95],106:[2,95],110:[2,95],118:[2,95],126:[2,95],128:[2,95],129:[2,95],132:[2,95],133:[2,95],134:[2,95],135:[2,95],136:[2,95],137:[2,95]},{7:135,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,46],6:[2,46],7:136,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[2,46],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],102:[2,46],103:37,104:[2,46],106:[2,46],107:38,108:[1,65],109:39,110:[2,46],111:67,119:[1,40],124:35,125:[1,62],126:[2,46],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,47],6:[2,47],25:[2,47],26:[2,47],54:[2,47],78:[2,47],102:[2,47],104:[2,47],106:[2,47],110:[2,47],126:[2,47]},{1:[2,72],6:[2,72],25:[2,72],26:[2,72],40:[2,72],49:[2,72],54:[2,72],57:[2,72],66:[2,72],67:[2,72],68:[2,72],69:[2,72],71:[2,72],73:[2,72],74:[2,72],78:[2,72],84:[2,72],85:[2,72],86:[2,72],91:[2,72],93:[2,72],102:[2,72],104:[2,72],105:[2,72],106:[2,72],110:[2,72],118:[2,72],126:[2,72],128:[2,72],129:[2,72],132:[2,72],133:[2,72],134:[2,72],135:[2,72],136:[2,72],137:[2,72]},{1:[2,73],6:[2,73],25:[2,73],26:[2,73],40:[2,73],49:[2,73],54:[2,73],57:[2,73],66:[2,73],67:[2,73],68:[2,73],69:[2,73],71:[2,73],73:[2,73],74:[2,73],78:[2,73],84:[2,73],85:[2,73],86:[2,73],91:[2,73],93:[2,73],102:[2,73],104:[2,73],105:[2,73],106:[2,73],110:[2,73],118:[2,73],126:[2,73],128:[2,73],129:[2,73],132:[2,73],133:[2,73],134:[2,73],135:[2,73],136:[2,73],137:[2,73]},{1:[2,28],6:[2,28],25:[2,28],26:[2,28],49:[2,28],54:[2,28],57:[2,28],66:[2,28],67:[2,28],68:[2,28],69:[2,28],71:[2,28],73:[2,28],74:[2,28],78:[2,28],84:[2,28],85:[2,28],86:[2,28],91:[2,28],93:[2,28],102:[2,28],104:[2,28],105:[2,28],106:[2,28],110:[2,28],118:[2,28],126:[2,28],128:[2,28],129:[2,28],132:[2,28],133:[2,28],134:[2,28],135:[2,28],136:[2,28],137:[2,28]},{1:[2,29],6:[2,29],25:[2,29],26:[2,29],49:[2,29],54:[2,29],57:[2,29],66:[2,29],67:[2,29],68:[2,29],69:[2,29],71:[2,29],73:[2,29],74:[2,29],78:[2,29],84:[2,29],85:[2,29],86:[2,29],91:[2,29],93:[2,29],102:[2,29],104:[2,29],105:[2,29],106:[2,29],110:[2,29],118:[2,29],126:[2,29],128:[2,29],129:[2,29],132:[2,29],133:[2,29],134:[2,29],135:[2,29],136:[2,29],137:[2,29]},{1:[2,30],6:[2,30],25:[2,30],26:[2,30],49:[2,30],54:[2,30],57:[2,30],66:[2,30],67:[2,30],68:[2,30],69:[2,30],71:[2,30],73:[2,30],74:[2,30],78:[2,30],84:[2,30],85:[2,30],86:[2,30],91:[2,30],93:[2,30],102:[2,30],104:[2,30],105:[2,30],106:[2,30],110:[2,30],118:[2,30],126:[2,30],128:[2,30],129:[2,30],132:[2,30],133:[2,30],134:[2,30],135:[2,30],136:[2,30],137:[2,30]},{1:[2,31],6:[2,31],25:[2,31],26:[2,31],49:[2,31],54:[2,31],57:[2,31],66:[2,31],67:[2,31],68:[2,31],69:[2,31],71:[2,31],73:[2,31],74:[2,31],78:[2,31],84:[2,31],85:[2,31],86:[2,31],91:[2,31],93:[2,31],102:[2,31],104:[2,31],105:[2,31],106:[2,31],110:[2,31],118:[2,31],126:[2,31],128:[2,31],129:[2,31],132:[2,31],133:[2,31],134:[2,31],135:[2,31],136:[2,31],137:[2,31]},{1:[2,32],6:[2,32],25:[2,32],26:[2,32],49:[2,32],54:[2,32],57:[2,32],66:[2,32],67:[2,32],68:[2,32],69:[2,32],71:[2,32],73:[2,32],74:[2,32],78:[2,32],84:[2,32],85:[2,32],86:[2,32],91:[2,32],93:[2,32],102:[2,32],104:[2,32],105:[2,32],106:[2,32],110:[2,32],118:[2,32],126:[2,32],128:[2,32],129:[2,32],132:[2,32],133:[2,32],134:[2,32],135:[2,32],136:[2,32],137:[2,32]},{1:[2,33],6:[2,33],25:[2,33],26:[2,33],49:[2,33],54:[2,33],57:[2,33],66:[2,33],67:[2,33],68:[2,33],69:[2,33],71:[2,33],73:[2,33],74:[2,33],78:[2,33],84:[2,33],85:[2,33],86:[2,33],91:[2,33],93:[2,33],102:[2,33],104:[2,33],105:[2,33],106:[2,33],110:[2,33],118:[2,33],126:[2,33],128:[2,33],129:[2,33],132:[2,33],133:[2,33],134:[2,33],135:[2,33],136:[2,33],137:[2,33]},{1:[2,34],6:[2,34],25:[2,34],26:[2,34],49:[2,34],54:[2,34],57:[2,34],66:[2,34],67:[2,34],68:[2,34],69:[2,34],71:[2,34],73:[2,34],74:[2,34],78:[2,34],84:[2,34],85:[2,34],86:[2,34],91:[2,34],93:[2,34],102:[2,34],104:[2,34],105:[2,34],106:[2,34],110:[2,34],118:[2,34],126:[2,34],128:[2,34],129:[2,34],132:[2,34],133:[2,34],134:[2,34],135:[2,34],136:[2,34],137:[2,34]},{4:137,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,138],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:139,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],87:141,88:[1,56],89:[1,57],90:[1,55],91:[1,140],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,111],6:[2,111],25:[2,111],26:[2,111],49:[2,111],54:[2,111],57:[2,111],66:[2,111],67:[2,111],68:[2,111],69:[2,111],71:[2,111],73:[2,111],74:[2,111],78:[2,111],84:[2,111],85:[2,111],86:[2,111],91:[2,111],93:[2,111],102:[2,111],104:[2,111],105:[2,111],106:[2,111],110:[2,111],118:[2,111],126:[2,111],128:[2,111],129:[2,111],132:[2,111],133:[2,111],134:[2,111],135:[2,111],136:[2,111],137:[2,111]},{1:[2,112],6:[2,112],25:[2,112],26:[2,112],27:145,28:[1,71],49:[2,112],54:[2,112],57:[2,112],66:[2,112],67:[2,112],68:[2,112],69:[2,112],71:[2,112],73:[2,112],74:[2,112],78:[2,112],84:[2,112],85:[2,112],86:[2,112],91:[2,112],93:[2,112],102:[2,112],104:[2,112],105:[2,112],106:[2,112],110:[2,112],118:[2,112],126:[2,112],128:[2,112],129:[2,112],132:[2,112],133:[2,112],134:[2,112],135:[2,112],136:[2,112],137:[2,112]},{25:[2,50]},{25:[2,51]},{1:[2,67],6:[2,67],25:[2,67],26:[2,67],40:[2,67],49:[2,67],54:[2,67],57:[2,67],66:[2,67],67:[2,67],68:[2,67],69:[2,67],71:[2,67],73:[2,67],74:[2,67],78:[2,67],80:[2,67],84:[2,67],85:[2,67],86:[2,67],91:[2,67],93:[2,67],102:[2,67],104:[2,67],105:[2,67],106:[2,67],110:[2,67],118:[2,67],126:[2,67],128:[2,67],129:[2,67],130:[2,67],131:[2,67],132:[2,67],133:[2,67],134:[2,67],135:[2,67],136:[2,67],137:[2,67],138:[2,67]},{1:[2,70],6:[2,70],25:[2,70],26:[2,70],40:[2,70],49:[2,70],54:[2,70],57:[2,70],66:[2,70],67:[2,70],68:[2,70],69:[2,70],71:[2,70],73:[2,70],74:[2,70],78:[2,70],80:[2,70],84:[2,70],85:[2,70],86:[2,70],91:[2,70],93:[2,70],102:[2,70],104:[2,70],105:[2,70],106:[2,70],110:[2,70],118:[2,70],126:[2,70],128:[2,70],129:[2,70],130:[2,70],131:[2,70],132:[2,70],133:[2,70],134:[2,70],135:[2,70],136:[2,70],137:[2,70],138:[2,70]},{7:146,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:147,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:148,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:150,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,24:149,25:[1,112],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{27:155,28:[1,71],44:156,58:157,59:158,64:151,76:[1,68],89:[1,109],90:[1,55],113:152,114:[1,153],115:154},{112:159,116:[1,160],117:[1,161]},{6:[2,90],10:165,25:[2,90],27:166,28:[1,71],29:167,30:[1,69],31:[1,70],41:163,42:164,44:168,46:[1,44],54:[2,90],77:162,78:[2,90],89:[1,109]},{1:[2,26],6:[2,26],25:[2,26],26:[2,26],43:[2,26],49:[2,26],54:[2,26],57:[2,26],66:[2,26],67:[2,26],68:[2,26],69:[2,26],71:[2,26],73:[2,26],74:[2,26],78:[2,26],84:[2,26],85:[2,26],86:[2,26],91:[2,26],93:[2,26],102:[2,26],104:[2,26],105:[2,26],106:[2,26],110:[2,26],118:[2,26],126:[2,26],128:[2,26],129:[2,26],132:[2,26],133:[2,26],134:[2,26],135:[2,26],136:[2,26],137:[2,26]},{1:[2,27],6:[2,27],25:[2,27],26:[2,27],43:[2,27],49:[2,27],54:[2,27],57:[2,27],66:[2,27],67:[2,27],68:[2,27],69:[2,27],71:[2,27],73:[2,27],74:[2,27],78:[2,27],84:[2,27],85:[2,27],86:[2,27],91:[2,27],93:[2,27],102:[2,27],104:[2,27],105:[2,27],106:[2,27],110:[2,27],118:[2,27],126:[2,27],128:[2,27],129:[2,27],132:[2,27],133:[2,27],134:[2,27],135:[2,27],136:[2,27],137:[2,27]},{1:[2,25],6:[2,25],25:[2,25],26:[2,25],40:[2,25],43:[2,25],49:[2,25],54:[2,25],57:[2,25],66:[2,25],67:[2,25],68:[2,25],69:[2,25],71:[2,25],73:[2,25],74:[2,25],78:[2,25],80:[2,25],84:[2,25],85:[2,25],86:[2,25],91:[2,25],93:[2,25],102:[2,25],104:[2,25],105:[2,25],106:[2,25],110:[2,25],116:[2,25],117:[2,25],118:[2,25],126:[2,25],128:[2,25],129:[2,25],130:[2,25],131:[2,25],132:[2,25],133:[2,25],134:[2,25],135:[2,25],136:[2,25],137:[2,25],138:[2,25]},{1:[2,5],5:169,6:[2,5],7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[2,5],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],102:[2,5],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,193],6:[2,193],25:[2,193],26:[2,193],49:[2,193],54:[2,193],57:[2,193],73:[2,193],78:[2,193],86:[2,193],91:[2,193],93:[2,193],102:[2,193],104:[2,193],105:[2,193],106:[2,193],110:[2,193],118:[2,193],126:[2,193],128:[2,193],129:[2,193],132:[2,193],133:[2,193],134:[2,193],135:[2,193],136:[2,193],137:[2,193]},{7:170,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:171,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:172,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:173,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:174,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:175,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:176,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:177,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,148],6:[2,148],25:[2,148],26:[2,148],49:[2,148],54:[2,148],57:[2,148],73:[2,148],78:[2,148],86:[2,148],91:[2,148],93:[2,148],102:[2,148],104:[2,148],105:[2,148],106:[2,148],110:[2,148],118:[2,148],126:[2,148],128:[2,148],129:[2,148],132:[2,148],133:[2,148],134:[2,148],135:[2,148],136:[2,148],137:[2,148]},{1:[2,153],6:[2,153],25:[2,153],26:[2,153],49:[2,153],54:[2,153],57:[2,153],73:[2,153],78:[2,153],86:[2,153],91:[2,153],93:[2,153],102:[2,153],104:[2,153],105:[2,153],106:[2,153],110:[2,153],118:[2,153],126:[2,153],128:[2,153],129:[2,153],132:[2,153],133:[2,153],134:[2,153],135:[2,153],136:[2,153],137:[2,153]},{7:178,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,147],6:[2,147],25:[2,147],26:[2,147],49:[2,147],54:[2,147],57:[2,147],73:[2,147],78:[2,147],86:[2,147],91:[2,147],93:[2,147],102:[2,147],104:[2,147],105:[2,147],106:[2,147],110:[2,147],118:[2,147],126:[2,147],128:[2,147],129:[2,147],132:[2,147],133:[2,147],134:[2,147],135:[2,147],136:[2,147],137:[2,147]},{1:[2,152],6:[2,152],25:[2,152],26:[2,152],49:[2,152],54:[2,152],57:[2,152],73:[2,152],78:[2,152],86:[2,152],91:[2,152],93:[2,152],102:[2,152],104:[2,152],105:[2,152],106:[2,152],110:[2,152],118:[2,152],126:[2,152],128:[2,152],129:[2,152],132:[2,152],133:[2,152],134:[2,152],135:[2,152],136:[2,152],137:[2,152]},{82:179,85:[1,101]},{1:[2,68],6:[2,68],25:[2,68],26:[2,68],40:[2,68],49:[2,68],54:[2,68],57:[2,68],66:[2,68],67:[2,68],68:[2,68],69:[2,68],71:[2,68],73:[2,68],74:[2,68],78:[2,68],80:[2,68],84:[2,68],85:[2,68],86:[2,68],91:[2,68],93:[2,68],102:[2,68],104:[2,68],105:[2,68],106:[2,68],110:[2,68],118:[2,68],126:[2,68],128:[2,68],129:[2,68],130:[2,68],131:[2,68],132:[2,68],133:[2,68],134:[2,68],135:[2,68],136:[2,68],137:[2,68],138:[2,68]},{85:[2,108]},{27:180,28:[1,71]},{27:181,28:[1,71]},{1:[2,83],6:[2,83],25:[2,83],26:[2,83],27:182,28:[1,71],40:[2,83],49:[2,83],54:[2,83],57:[2,83],66:[2,83],67:[2,83],68:[2,83],69:[2,83],71:[2,83],73:[2,83],74:[2,83],78:[2,83],80:[2,83],84:[2,83],85:[2,83],86:[2,83],91:[2,83],93:[2,83],102:[2,83],104:[2,83],105:[2,83],106:[2,83],110:[2,83],118:[2,83],126:[2,83],128:[2,83],129:[2,83],130:[2,83],131:[2,83],132:[2,83],133:[2,83],134:[2,83],135:[2,83],136:[2,83],137:[2,83],138:[2,83]},{27:183,28:[1,71]},{1:[2,84],6:[2,84],25:[2,84],26:[2,84],40:[2,84],49:[2,84],54:[2,84],57:[2,84],66:[2,84],67:[2,84],68:[2,84],69:[2,84],71:[2,84],73:[2,84],74:[2,84],78:[2,84],80:[2,84],84:[2,84],85:[2,84],86:[2,84],91:[2,84],93:[2,84],102:[2,84],104:[2,84],105:[2,84],106:[2,84],110:[2,84],118:[2,84],126:[2,84],128:[2,84],129:[2,84],130:[2,84],131:[2,84],132:[2,84],133:[2,84],134:[2,84],135:[2,84],136:[2,84],137:[2,84],138:[2,84]},{7:185,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],57:[1,189],58:45,59:46,61:34,63:23,64:24,65:25,72:184,75:186,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],92:187,93:[1,188],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{70:190,71:[1,95],74:[1,96]},{82:191,85:[1,101]},{1:[2,69],6:[2,69],25:[2,69],26:[2,69],40:[2,69],49:[2,69],54:[2,69],57:[2,69],66:[2,69],67:[2,69],68:[2,69],69:[2,69],71:[2,69],73:[2,69],74:[2,69],78:[2,69],80:[2,69],84:[2,69],85:[2,69],86:[2,69],91:[2,69],93:[2,69],102:[2,69],104:[2,69],105:[2,69],106:[2,69],110:[2,69],118:[2,69],126:[2,69],128:[2,69],129:[2,69],130:[2,69],131:[2,69],132:[2,69],133:[2,69],134:[2,69],135:[2,69],136:[2,69],137:[2,69],138:[2,69]},{6:[1,193],7:192,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,194],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,106],6:[2,106],25:[2,106],26:[2,106],49:[2,106],54:[2,106],57:[2,106],66:[2,106],67:[2,106],68:[2,106],69:[2,106],71:[2,106],73:[2,106],74:[2,106],78:[2,106],84:[2,106],85:[2,106],86:[2,106],91:[2,106],93:[2,106],102:[2,106],104:[2,106],105:[2,106],106:[2,106],110:[2,106],118:[2,106],126:[2,106],128:[2,106],129:[2,106],132:[2,106],133:[2,106],134:[2,106],135:[2,106],136:[2,106],137:[2,106]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],86:[1,195],87:196,88:[1,56],89:[1,57],90:[1,55],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,52],25:[2,52],49:[1,198],53:200,54:[1,199]},{6:[2,55],25:[2,55],26:[2,55],49:[2,55],54:[2,55]},{6:[2,59],25:[2,59],26:[2,59],40:[1,202],49:[2,59],54:[2,59],57:[1,201]},{6:[2,62],25:[2,62],26:[2,62],40:[2,62],49:[2,62],54:[2,62],57:[2,62]},{6:[2,63],25:[2,63],26:[2,63],40:[2,63],49:[2,63],54:[2,63],57:[2,63]},{6:[2,64],25:[2,64],26:[2,64],40:[2,64],49:[2,64],54:[2,64],57:[2,64]},{6:[2,65],25:[2,65],26:[2,65],40:[2,65],49:[2,65],54:[2,65],57:[2,65]},{27:145,28:[1,71]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],87:141,88:[1,56],89:[1,57],90:[1,55],91:[1,140],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,49],6:[2,49],25:[2,49],26:[2,49],49:[2,49],54:[2,49],57:[2,49],73:[2,49],78:[2,49],86:[2,49],91:[2,49],93:[2,49],102:[2,49],104:[2,49],105:[2,49],106:[2,49],110:[2,49],118:[2,49],126:[2,49],128:[2,49],129:[2,49],132:[2,49],133:[2,49],134:[2,49],135:[2,49],136:[2,49],137:[2,49]},{4:204,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,26:[1,203],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,186],6:[2,186],25:[2,186],26:[2,186],49:[2,186],54:[2,186],57:[2,186],73:[2,186],78:[2,186],86:[2,186],91:[2,186],93:[2,186],102:[2,186],103:82,104:[2,186],105:[2,186],106:[2,186],109:83,110:[2,186],111:67,118:[2,186],126:[2,186],128:[2,186],129:[2,186],132:[1,73],133:[2,186],134:[2,186],135:[2,186],136:[2,186],137:[2,186]},{103:85,104:[1,63],106:[1,64],109:86,110:[1,66],111:67,126:[1,84]},{1:[2,187],6:[2,187],25:[2,187],26:[2,187],49:[2,187],54:[2,187],57:[2,187],73:[2,187],78:[2,187],86:[2,187],91:[2,187],93:[2,187],102:[2,187],103:82,104:[2,187],105:[2,187],106:[2,187],109:83,110:[2,187],111:67,118:[2,187],126:[2,187],128:[2,187],129:[2,187],132:[1,73],133:[2,187],134:[2,187],135:[2,187],136:[2,187],137:[2,187]},{1:[2,188],6:[2,188],25:[2,188],26:[2,188],49:[2,188],54:[2,188],57:[2,188],73:[2,188],78:[2,188],86:[2,188],91:[2,188],93:[2,188],102:[2,188],103:82,104:[2,188],105:[2,188],106:[2,188],109:83,110:[2,188],111:67,118:[2,188],126:[2,188],128:[2,188],129:[2,188],132:[1,73],133:[2,188],134:[2,188],135:[2,188],136:[2,188],137:[2,188]},{1:[2,189],6:[2,189],25:[2,189],26:[2,189],49:[2,189],54:[2,189],57:[2,189],66:[2,71],67:[2,71],68:[2,71],69:[2,71],71:[2,71],73:[2,189],74:[2,71],78:[2,189],84:[2,71],85:[2,71],86:[2,189],91:[2,189],93:[2,189],102:[2,189],104:[2,189],105:[2,189],106:[2,189],110:[2,189],118:[2,189],126:[2,189],128:[2,189],129:[2,189],132:[2,189],133:[2,189],134:[2,189],135:[2,189],136:[2,189],137:[2,189]},{62:88,66:[1,90],67:[1,91],68:[1,92],69:[1,93],70:94,71:[1,95],74:[1,96],81:87,84:[1,89],85:[2,107]},{62:98,66:[1,90],67:[1,91],68:[1,92],69:[1,93],70:94,71:[1,95],74:[1,96],81:97,84:[1,89],85:[2,107]},{66:[2,74],67:[2,74],68:[2,74],69:[2,74],71:[2,74],74:[2,74],84:[2,74],85:[2,74]},{1:[2,190],6:[2,190],25:[2,190],26:[2,190],49:[2,190],54:[2,190],57:[2,190],66:[2,71],67:[2,71],68:[2,71],69:[2,71],71:[2,71],73:[2,190],74:[2,71],78:[2,190],84:[2,71],85:[2,71],86:[2,190],91:[2,190],93:[2,190],102:[2,190],104:[2,190],105:[2,190],106:[2,190],110:[2,190],118:[2,190],126:[2,190],128:[2,190],129:[2,190],132:[2,190],133:[2,190],134:[2,190],135:[2,190],136:[2,190],137:[2,190]},{1:[2,191],6:[2,191],25:[2,191],26:[2,191],49:[2,191],54:[2,191],57:[2,191],73:[2,191],78:[2,191],86:[2,191],91:[2,191],93:[2,191],102:[2,191],104:[2,191],105:[2,191],106:[2,191],110:[2,191],118:[2,191],126:[2,191],128:[2,191],129:[2,191],132:[2,191],133:[2,191],134:[2,191],135:[2,191],136:[2,191],137:[2,191]},{1:[2,192],6:[2,192],25:[2,192],26:[2,192],49:[2,192],54:[2,192],57:[2,192],73:[2,192],78:[2,192],86:[2,192],91:[2,192],93:[2,192],102:[2,192],104:[2,192],105:[2,192],106:[2,192],110:[2,192],118:[2,192],126:[2,192],128:[2,192],129:[2,192],132:[2,192],133:[2,192],134:[2,192],135:[2,192],136:[2,192],137:[2,192]},{6:[1,207],7:205,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,206],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:208,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{24:209,25:[1,112],125:[1,210]},{1:[2,132],6:[2,132],25:[2,132],26:[2,132],49:[2,132],54:[2,132],57:[2,132],73:[2,132],78:[2,132],86:[2,132],91:[2,132],93:[2,132],97:211,98:[1,212],99:[1,213],102:[2,132],104:[2,132],105:[2,132],106:[2,132],110:[2,132],118:[2,132],126:[2,132],128:[2,132],129:[2,132],132:[2,132],133:[2,132],134:[2,132],135:[2,132],136:[2,132],137:[2,132]},{1:[2,146],6:[2,146],25:[2,146],26:[2,146],49:[2,146],54:[2,146],57:[2,146],73:[2,146],78:[2,146],86:[2,146],91:[2,146],93:[2,146],102:[2,146],104:[2,146],105:[2,146],106:[2,146],110:[2,146],118:[2,146],126:[2,146],128:[2,146],129:[2,146],132:[2,146],133:[2,146],134:[2,146],135:[2,146],136:[2,146],137:[2,146]},{1:[2,154],6:[2,154],25:[2,154],26:[2,154],49:[2,154],54:[2,154],57:[2,154],73:[2,154],78:[2,154],86:[2,154],91:[2,154],93:[2,154],102:[2,154],104:[2,154],105:[2,154],106:[2,154],110:[2,154],118:[2,154],126:[2,154],128:[2,154],129:[2,154],132:[2,154],133:[2,154],134:[2,154],135:[2,154],136:[2,154],137:[2,154]},{25:[1,214],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{120:215,122:216,123:[1,217]},{1:[2,96],6:[2,96],25:[2,96],26:[2,96],49:[2,96],54:[2,96],57:[2,96],73:[2,96],78:[2,96],86:[2,96],91:[2,96],93:[2,96],102:[2,96],104:[2,96],105:[2,96],106:[2,96],110:[2,96],118:[2,96],126:[2,96],128:[2,96],129:[2,96],132:[2,96],133:[2,96],134:[2,96],135:[2,96],136:[2,96],137:[2,96]},{7:218,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,99],6:[2,99],24:219,25:[1,112],26:[2,99],49:[2,99],54:[2,99],57:[2,99],66:[2,71],67:[2,71],68:[2,71],69:[2,71],71:[2,71],73:[2,99],74:[2,71],78:[2,99],80:[1,220],84:[2,71],85:[2,71],86:[2,99],91:[2,99],93:[2,99],102:[2,99],104:[2,99],105:[2,99],106:[2,99],110:[2,99],118:[2,99],126:[2,99],128:[2,99],129:[2,99],132:[2,99],133:[2,99],134:[2,99],135:[2,99],136:[2,99],137:[2,99]},{1:[2,139],6:[2,139],25:[2,139],26:[2,139],49:[2,139],54:[2,139],57:[2,139],73:[2,139],78:[2,139],86:[2,139],91:[2,139],93:[2,139],102:[2,139],103:82,104:[2,139],105:[2,139],106:[2,139],109:83,110:[2,139],111:67,118:[2,139],126:[2,139],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,45],6:[2,45],26:[2,45],102:[2,45],103:82,104:[2,45],106:[2,45],109:83,110:[2,45],111:67,126:[2,45],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,72],102:[1,221]},{4:222,5:3,7:4,8:5,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,128],25:[2,128],54:[2,128],57:[1,224],91:[2,128],92:223,93:[1,188],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,114],6:[2,114],25:[2,114],26:[2,114],40:[2,114],49:[2,114],54:[2,114],57:[2,114],66:[2,114],67:[2,114],68:[2,114],69:[2,114],71:[2,114],73:[2,114],74:[2,114],78:[2,114],84:[2,114],85:[2,114],86:[2,114],91:[2,114],93:[2,114],102:[2,114],104:[2,114],105:[2,114],106:[2,114],110:[2,114],116:[2,114],117:[2,114],118:[2,114],126:[2,114],128:[2,114],129:[2,114],132:[2,114],133:[2,114],134:[2,114],135:[2,114],136:[2,114],137:[2,114]},{6:[2,52],25:[2,52],53:225,54:[1,226],91:[2,52]},{6:[2,123],25:[2,123],26:[2,123],54:[2,123],86:[2,123],91:[2,123]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],87:227,88:[1,56],89:[1,57],90:[1,55],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,129],25:[2,129],26:[2,129],54:[2,129],86:[2,129],91:[2,129]},{1:[2,113],6:[2,113],25:[2,113],26:[2,113],40:[2,113],43:[2,113],49:[2,113],54:[2,113],57:[2,113],66:[2,113],67:[2,113],68:[2,113],69:[2,113],71:[2,113],73:[2,113],74:[2,113],78:[2,113],80:[2,113],84:[2,113],85:[2,113],86:[2,113],91:[2,113],93:[2,113],102:[2,113],104:[2,113],105:[2,113],106:[2,113],110:[2,113],116:[2,113],117:[2,113],118:[2,113],126:[2,113],128:[2,113],129:[2,113],130:[2,113],131:[2,113],132:[2,113],133:[2,113],134:[2,113],135:[2,113],136:[2,113],137:[2,113],138:[2,113]},{24:228,25:[1,112],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,142],6:[2,142],25:[2,142],26:[2,142],49:[2,142],54:[2,142],57:[2,142],73:[2,142],78:[2,142],86:[2,142],91:[2,142],93:[2,142],102:[2,142],103:82,104:[1,63],105:[1,229],106:[1,64],109:83,110:[1,66],111:67,118:[2,142],126:[2,142],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,144],6:[2,144],25:[2,144],26:[2,144],49:[2,144],54:[2,144],57:[2,144],73:[2,144],78:[2,144],86:[2,144],91:[2,144],93:[2,144],102:[2,144],103:82,104:[1,63],105:[1,230],106:[1,64],109:83,110:[1,66],111:67,118:[2,144],126:[2,144],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,150],6:[2,150],25:[2,150],26:[2,150],49:[2,150],54:[2,150],57:[2,150],73:[2,150],78:[2,150],86:[2,150],91:[2,150],93:[2,150],102:[2,150],104:[2,150],105:[2,150],106:[2,150],110:[2,150],118:[2,150],126:[2,150],128:[2,150],129:[2,150],132:[2,150],133:[2,150],134:[2,150],135:[2,150],136:[2,150],137:[2,150]},{1:[2,151],6:[2,151],25:[2,151],26:[2,151],49:[2,151],54:[2,151],57:[2,151],73:[2,151],78:[2,151],86:[2,151],91:[2,151],93:[2,151],102:[2,151],103:82,104:[1,63],105:[2,151],106:[1,64],109:83,110:[1,66],111:67,118:[2,151],126:[2,151],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,155],6:[2,155],25:[2,155],26:[2,155],49:[2,155],54:[2,155],57:[2,155],73:[2,155],78:[2,155],86:[2,155],91:[2,155],93:[2,155],102:[2,155],104:[2,155],105:[2,155],106:[2,155],110:[2,155],118:[2,155],126:[2,155],128:[2,155],129:[2,155],132:[2,155],133:[2,155],134:[2,155],135:[2,155],136:[2,155],137:[2,155]},{116:[2,157],117:[2,157]},{27:155,28:[1,71],44:156,58:157,59:158,76:[1,68],89:[1,109],90:[1,110],113:231,115:154},{54:[1,232],116:[2,163],117:[2,163]},{54:[2,159],116:[2,159],117:[2,159]},{54:[2,160],116:[2,160],117:[2,160]},{54:[2,161],116:[2,161],117:[2,161]},{54:[2,162],116:[2,162],117:[2,162]},{1:[2,156],6:[2,156],25:[2,156],26:[2,156],49:[2,156],54:[2,156],57:[2,156],73:[2,156],78:[2,156],86:[2,156],91:[2,156],93:[2,156],102:[2,156],104:[2,156],105:[2,156],106:[2,156],110:[2,156],118:[2,156],126:[2,156],128:[2,156],129:[2,156],132:[2,156],133:[2,156],134:[2,156],135:[2,156],136:[2,156],137:[2,156]},{7:233,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:234,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,52],25:[2,52],53:235,54:[1,236],78:[2,52]},{6:[2,91],25:[2,91],26:[2,91],54:[2,91],78:[2,91]},{6:[2,38],25:[2,38],26:[2,38],43:[1,237],54:[2,38],78:[2,38]},{6:[2,41],25:[2,41],26:[2,41],54:[2,41],78:[2,41]},{6:[2,42],25:[2,42],26:[2,42],43:[2,42],54:[2,42],78:[2,42]},{6:[2,43],25:[2,43],26:[2,43],43:[2,43],54:[2,43],78:[2,43]},{6:[2,44],25:[2,44],26:[2,44],43:[2,44],54:[2,44],78:[2,44]},{1:[2,4],6:[2,4],26:[2,4],102:[2,4]},{1:[2,194],6:[2,194],25:[2,194],26:[2,194],49:[2,194],54:[2,194],57:[2,194],73:[2,194],78:[2,194],86:[2,194],91:[2,194],93:[2,194],102:[2,194],103:82,104:[2,194],105:[2,194],106:[2,194],109:83,110:[2,194],111:67,118:[2,194],126:[2,194],128:[2,194],129:[2,194],132:[1,73],133:[1,76],134:[2,194],135:[2,194],136:[2,194],137:[2,194]},{1:[2,195],6:[2,195],25:[2,195],26:[2,195],49:[2,195],54:[2,195],57:[2,195],73:[2,195],78:[2,195],86:[2,195],91:[2,195],93:[2,195],102:[2,195],103:82,104:[2,195],105:[2,195],106:[2,195],109:83,110:[2,195],111:67,118:[2,195],126:[2,195],128:[2,195],129:[2,195],132:[1,73],133:[1,76],134:[2,195],135:[2,195],136:[2,195],137:[2,195]},{1:[2,196],6:[2,196],25:[2,196],26:[2,196],49:[2,196],54:[2,196],57:[2,196],73:[2,196],78:[2,196],86:[2,196],91:[2,196],93:[2,196],102:[2,196],103:82,104:[2,196],105:[2,196],106:[2,196],109:83,110:[2,196],111:67,118:[2,196],126:[2,196],128:[2,196],129:[2,196],132:[1,73],133:[2,196],134:[2,196],135:[2,196],136:[2,196],137:[2,196]},{1:[2,197],6:[2,197],25:[2,197],26:[2,197],49:[2,197],54:[2,197],57:[2,197],73:[2,197],78:[2,197],86:[2,197],91:[2,197],93:[2,197],102:[2,197],103:82,104:[2,197],105:[2,197],106:[2,197],109:83,110:[2,197],111:67,118:[2,197],126:[2,197],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[2,197],135:[2,197],136:[2,197],137:[2,197]},{1:[2,198],6:[2,198],25:[2,198],26:[2,198],49:[2,198],54:[2,198],57:[2,198],73:[2,198],78:[2,198],86:[2,198],91:[2,198],93:[2,198],102:[2,198],103:82,104:[2,198],105:[2,198],106:[2,198],109:83,110:[2,198],111:67,118:[2,198],126:[2,198],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[2,198],136:[2,198],137:[1,80]},{1:[2,199],6:[2,199],25:[2,199],26:[2,199],49:[2,199],54:[2,199],57:[2,199],73:[2,199],78:[2,199],86:[2,199],91:[2,199],93:[2,199],102:[2,199],103:82,104:[2,199],105:[2,199],106:[2,199],109:83,110:[2,199],111:67,118:[2,199],126:[2,199],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[2,199],137:[1,80]},{1:[2,200],6:[2,200],25:[2,200],26:[2,200],49:[2,200],54:[2,200],57:[2,200],73:[2,200],78:[2,200],86:[2,200],91:[2,200],93:[2,200],102:[2,200],103:82,104:[2,200],105:[2,200],106:[2,200],109:83,110:[2,200],111:67,118:[2,200],126:[2,200],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[2,200],136:[2,200],137:[2,200]},{1:[2,185],6:[2,185],25:[2,185],26:[2,185],49:[2,185],54:[2,185],57:[2,185],73:[2,185],78:[2,185],86:[2,185],91:[2,185],93:[2,185],102:[2,185],103:82,104:[1,63],105:[2,185],106:[1,64],109:83,110:[1,66],111:67,118:[2,185],126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,184],6:[2,184],25:[2,184],26:[2,184],49:[2,184],54:[2,184],57:[2,184],73:[2,184],78:[2,184],86:[2,184],91:[2,184],93:[2,184],102:[2,184],103:82,104:[1,63],105:[2,184],106:[1,64],109:83,110:[1,66],111:67,118:[2,184],126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,103],6:[2,103],25:[2,103],26:[2,103],49:[2,103],54:[2,103],57:[2,103],66:[2,103],67:[2,103],68:[2,103],69:[2,103],71:[2,103],73:[2,103],74:[2,103],78:[2,103],84:[2,103],85:[2,103],86:[2,103],91:[2,103],93:[2,103],102:[2,103],104:[2,103],105:[2,103],106:[2,103],110:[2,103],118:[2,103],126:[2,103],128:[2,103],129:[2,103],132:[2,103],133:[2,103],134:[2,103],135:[2,103],136:[2,103],137:[2,103]},{1:[2,79],6:[2,79],25:[2,79],26:[2,79],40:[2,79],49:[2,79],54:[2,79],57:[2,79],66:[2,79],67:[2,79],68:[2,79],69:[2,79],71:[2,79],73:[2,79],74:[2,79],78:[2,79],80:[2,79],84:[2,79],85:[2,79],86:[2,79],91:[2,79],93:[2,79],102:[2,79],104:[2,79],105:[2,79],106:[2,79],110:[2,79],118:[2,79],126:[2,79],128:[2,79],129:[2,79],130:[2,79],131:[2,79],132:[2,79],133:[2,79],134:[2,79],135:[2,79],136:[2,79],137:[2,79],138:[2,79]},{1:[2,80],6:[2,80],25:[2,80],26:[2,80],40:[2,80],49:[2,80],54:[2,80],57:[2,80],66:[2,80],67:[2,80],68:[2,80],69:[2,80],71:[2,80],73:[2,80],74:[2,80],78:[2,80],80:[2,80],84:[2,80],85:[2,80],86:[2,80],91:[2,80],93:[2,80],102:[2,80],104:[2,80],105:[2,80],106:[2,80],110:[2,80],118:[2,80],126:[2,80],128:[2,80],129:[2,80],130:[2,80],131:[2,80],132:[2,80],133:[2,80],134:[2,80],135:[2,80],136:[2,80],137:[2,80],138:[2,80]},{1:[2,81],6:[2,81],25:[2,81],26:[2,81],40:[2,81],49:[2,81],54:[2,81],57:[2,81],66:[2,81],67:[2,81],68:[2,81],69:[2,81],71:[2,81],73:[2,81],74:[2,81],78:[2,81],80:[2,81],84:[2,81],85:[2,81],86:[2,81],91:[2,81],93:[2,81],102:[2,81],104:[2,81],105:[2,81],106:[2,81],110:[2,81],118:[2,81],126:[2,81],128:[2,81],129:[2,81],130:[2,81],131:[2,81],132:[2,81],133:[2,81],134:[2,81],135:[2,81],136:[2,81],137:[2,81],138:[2,81]},{1:[2,82],6:[2,82],25:[2,82],26:[2,82],40:[2,82],49:[2,82],54:[2,82],57:[2,82],66:[2,82],67:[2,82],68:[2,82],69:[2,82],71:[2,82],73:[2,82],74:[2,82],78:[2,82],80:[2,82],84:[2,82],85:[2,82],86:[2,82],91:[2,82],93:[2,82],102:[2,82],104:[2,82],105:[2,82],106:[2,82],110:[2,82],118:[2,82],126:[2,82],128:[2,82],129:[2,82],130:[2,82],131:[2,82],132:[2,82],133:[2,82],134:[2,82],135:[2,82],136:[2,82],137:[2,82],138:[2,82]},{73:[1,238]},{57:[1,189],73:[2,87],92:239,93:[1,188],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{73:[2,88]},{7:240,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,73:[2,122],76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{11:[2,116],28:[2,116],30:[2,116],31:[2,116],33:[2,116],34:[2,116],35:[2,116],36:[2,116],37:[2,116],38:[2,116],45:[2,116],46:[2,116],47:[2,116],51:[2,116],52:[2,116],73:[2,116],76:[2,116],79:[2,116],83:[2,116],88:[2,116],89:[2,116],90:[2,116],96:[2,116],100:[2,116],101:[2,116],104:[2,116],106:[2,116],108:[2,116],110:[2,116],119:[2,116],125:[2,116],127:[2,116],128:[2,116],129:[2,116],130:[2,116],131:[2,116]},{11:[2,117],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],73:[2,117],76:[2,117],79:[2,117],83:[2,117],88:[2,117],89:[2,117],90:[2,117],96:[2,117],100:[2,117],101:[2,117],104:[2,117],106:[2,117],108:[2,117],110:[2,117],119:[2,117],125:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117],131:[2,117]},{1:[2,86],6:[2,86],25:[2,86],26:[2,86],40:[2,86],49:[2,86],54:[2,86],57:[2,86],66:[2,86],67:[2,86],68:[2,86],69:[2,86],71:[2,86],73:[2,86],74:[2,86],78:[2,86],80:[2,86],84:[2,86],85:[2,86],86:[2,86],91:[2,86],93:[2,86],102:[2,86],104:[2,86],105:[2,86],106:[2,86],110:[2,86],118:[2,86],126:[2,86],128:[2,86],129:[2,86],130:[2,86],131:[2,86],132:[2,86],133:[2,86],134:[2,86],135:[2,86],136:[2,86],137:[2,86],138:[2,86]},{1:[2,104],6:[2,104],25:[2,104],26:[2,104],49:[2,104],54:[2,104],57:[2,104],66:[2,104],67:[2,104],68:[2,104],69:[2,104],71:[2,104],73:[2,104],74:[2,104],78:[2,104],84:[2,104],85:[2,104],86:[2,104],91:[2,104],93:[2,104],102:[2,104],104:[2,104],105:[2,104],106:[2,104],110:[2,104],118:[2,104],126:[2,104],128:[2,104],129:[2,104],132:[2,104],133:[2,104],134:[2,104],135:[2,104],136:[2,104],137:[2,104]},{1:[2,35],6:[2,35],25:[2,35],26:[2,35],49:[2,35],54:[2,35],57:[2,35],73:[2,35],78:[2,35],86:[2,35],91:[2,35],93:[2,35],102:[2,35],103:82,104:[2,35],105:[2,35],106:[2,35],109:83,110:[2,35],111:67,118:[2,35],126:[2,35],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{7:241,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:242,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,109],6:[2,109],25:[2,109],26:[2,109],49:[2,109],54:[2,109],57:[2,109],66:[2,109],67:[2,109],68:[2,109],69:[2,109],71:[2,109],73:[2,109],74:[2,109],78:[2,109],84:[2,109],85:[2,109],86:[2,109],91:[2,109],93:[2,109],102:[2,109],104:[2,109],105:[2,109],106:[2,109],110:[2,109],118:[2,109],126:[2,109],128:[2,109],129:[2,109],132:[2,109],133:[2,109],134:[2,109],135:[2,109],136:[2,109],137:[2,109]},{6:[2,52],25:[2,52],53:243,54:[1,226],86:[2,52]},{6:[2,128],25:[2,128],26:[2,128],54:[2,128],57:[1,244],86:[2,128],91:[2,128],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{50:245,51:[1,58],52:[1,59]},{6:[2,53],25:[2,53],26:[2,53],27:105,28:[1,71],44:106,55:246,56:104,58:107,59:108,76:[1,68],89:[1,109],90:[1,110]},{6:[1,247],25:[1,248]},{6:[2,60],25:[2,60],26:[2,60],49:[2,60],54:[2,60]},{7:249,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,23],6:[2,23],25:[2,23],26:[2,23],49:[2,23],54:[2,23],57:[2,23],73:[2,23],78:[2,23],86:[2,23],91:[2,23],93:[2,23],98:[2,23],99:[2,23],102:[2,23],104:[2,23],105:[2,23],106:[2,23],110:[2,23],118:[2,23],121:[2,23],123:[2,23],126:[2,23],128:[2,23],129:[2,23],132:[2,23],133:[2,23],134:[2,23],135:[2,23],136:[2,23],137:[2,23]},{6:[1,72],26:[1,250]},{1:[2,201],6:[2,201],25:[2,201],26:[2,201],49:[2,201],54:[2,201],57:[2,201],73:[2,201],78:[2,201],86:[2,201],91:[2,201],93:[2,201],102:[2,201],103:82,104:[2,201],105:[2,201],106:[2,201],109:83,110:[2,201],111:67,118:[2,201],126:[2,201],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{7:251,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:252,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,204],6:[2,204],25:[2,204],26:[2,204],49:[2,204],54:[2,204],57:[2,204],73:[2,204],78:[2,204],86:[2,204],91:[2,204],93:[2,204],102:[2,204],103:82,104:[2,204],105:[2,204],106:[2,204],109:83,110:[2,204],111:67,118:[2,204],126:[2,204],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,183],6:[2,183],25:[2,183],26:[2,183],49:[2,183],54:[2,183],57:[2,183],73:[2,183],78:[2,183],86:[2,183],91:[2,183],93:[2,183],102:[2,183],104:[2,183],105:[2,183],106:[2,183],110:[2,183],118:[2,183],126:[2,183],128:[2,183],129:[2,183],132:[2,183],133:[2,183],134:[2,183],135:[2,183],136:[2,183],137:[2,183]},{7:253,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,133],6:[2,133],25:[2,133],26:[2,133],49:[2,133],54:[2,133],57:[2,133],73:[2,133],78:[2,133],86:[2,133],91:[2,133],93:[2,133],98:[1,254],102:[2,133],104:[2,133],105:[2,133],106:[2,133],110:[2,133],118:[2,133],126:[2,133],128:[2,133],129:[2,133],132:[2,133],133:[2,133],134:[2,133],135:[2,133],136:[2,133],137:[2,133]},{24:255,25:[1,112]},{24:258,25:[1,112],27:256,28:[1,71],59:257,76:[1,68]},{120:259,122:216,123:[1,217]},{26:[1,260],121:[1,261],122:262,123:[1,217]},{26:[2,176],121:[2,176],123:[2,176]},{7:264,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],95:263,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,97],6:[2,97],24:265,25:[1,112],26:[2,97],49:[2,97],54:[2,97],57:[2,97],73:[2,97],78:[2,97],86:[2,97],91:[2,97],93:[2,97],102:[2,97],103:82,104:[1,63],105:[2,97],106:[1,64],109:83,110:[1,66],111:67,118:[2,97],126:[2,97],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,100],6:[2,100],25:[2,100],26:[2,100],49:[2,100],54:[2,100],57:[2,100],73:[2,100],78:[2,100],86:[2,100],91:[2,100],93:[2,100],102:[2,100],104:[2,100],105:[2,100],106:[2,100],110:[2,100],118:[2,100],126:[2,100],128:[2,100],129:[2,100],132:[2,100],133:[2,100],134:[2,100],135:[2,100],136:[2,100],137:[2,100]},{7:266,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,140],6:[2,140],25:[2,140],26:[2,140],49:[2,140],54:[2,140],57:[2,140],66:[2,140],67:[2,140],68:[2,140],69:[2,140],71:[2,140],73:[2,140],74:[2,140],78:[2,140],84:[2,140],85:[2,140],86:[2,140],91:[2,140],93:[2,140],102:[2,140],104:[2,140],105:[2,140],106:[2,140],110:[2,140],118:[2,140],126:[2,140],128:[2,140],129:[2,140],132:[2,140],133:[2,140],134:[2,140],135:[2,140],136:[2,140],137:[2,140]},{6:[1,72],26:[1,267]},{7:268,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,66],11:[2,117],25:[2,66],28:[2,117],30:[2,117],31:[2,117],33:[2,117],34:[2,117],35:[2,117],36:[2,117],37:[2,117],38:[2,117],45:[2,117],46:[2,117],47:[2,117],51:[2,117],52:[2,117],54:[2,66],76:[2,117],79:[2,117],83:[2,117],88:[2,117],89:[2,117],90:[2,117],91:[2,66],96:[2,117],100:[2,117],101:[2,117],104:[2,117],106:[2,117],108:[2,117],110:[2,117],119:[2,117],125:[2,117],127:[2,117],128:[2,117],129:[2,117],130:[2,117],131:[2,117]},{6:[1,270],25:[1,271],91:[1,269]},{6:[2,53],7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[2,53],26:[2,53],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],86:[2,53],88:[1,56],89:[1,57],90:[1,55],91:[2,53],94:272,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,52],25:[2,52],26:[2,52],53:273,54:[1,226]},{1:[2,180],6:[2,180],25:[2,180],26:[2,180],49:[2,180],54:[2,180],57:[2,180],73:[2,180],78:[2,180],86:[2,180],91:[2,180],93:[2,180],102:[2,180],104:[2,180],105:[2,180],106:[2,180],110:[2,180],118:[2,180],121:[2,180],126:[2,180],128:[2,180],129:[2,180],132:[2,180],133:[2,180],134:[2,180],135:[2,180],136:[2,180],137:[2,180]},{7:274,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:275,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{116:[2,158],117:[2,158]},{27:155,28:[1,71],44:156,58:157,59:158,76:[1,68],89:[1,109],90:[1,110],115:276},{1:[2,165],6:[2,165],25:[2,165],26:[2,165],49:[2,165],54:[2,165],57:[2,165],73:[2,165],78:[2,165],86:[2,165],91:[2,165],93:[2,165],102:[2,165],103:82,104:[2,165],105:[1,277],106:[2,165],109:83,110:[2,165],111:67,118:[1,278],126:[2,165],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,166],6:[2,166],25:[2,166],26:[2,166],49:[2,166],54:[2,166],57:[2,166],73:[2,166],78:[2,166],86:[2,166],91:[2,166],93:[2,166],102:[2,166],103:82,104:[2,166],105:[1,279],106:[2,166],109:83,110:[2,166],111:67,118:[2,166],126:[2,166],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,281],25:[1,282],78:[1,280]},{6:[2,53],10:165,25:[2,53],26:[2,53],27:166,28:[1,71],29:167,30:[1,69],31:[1,70],41:283,42:164,44:168,46:[1,44],78:[2,53],89:[1,109]},{7:284,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,285],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,85],6:[2,85],25:[2,85],26:[2,85],40:[2,85],49:[2,85],54:[2,85],57:[2,85],66:[2,85],67:[2,85],68:[2,85],69:[2,85],71:[2,85],73:[2,85],74:[2,85],78:[2,85],80:[2,85],84:[2,85],85:[2,85],86:[2,85],91:[2,85],93:[2,85],102:[2,85],104:[2,85],105:[2,85],106:[2,85],110:[2,85],118:[2,85],126:[2,85],128:[2,85],129:[2,85],130:[2,85],131:[2,85],132:[2,85],133:[2,85],134:[2,85],135:[2,85],136:[2,85],137:[2,85],138:[2,85]},{7:286,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,73:[2,120],76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{73:[2,121],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,36],6:[2,36],25:[2,36],26:[2,36],49:[2,36],54:[2,36],57:[2,36],73:[2,36],78:[2,36],86:[2,36],91:[2,36],93:[2,36],102:[2,36],103:82,104:[2,36],105:[2,36],106:[2,36],109:83,110:[2,36],111:67,118:[2,36],126:[2,36],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{26:[1,287],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,270],25:[1,271],86:[1,288]},{6:[2,66],25:[2,66],26:[2,66],54:[2,66],86:[2,66],91:[2,66]},{24:289,25:[1,112]},{6:[2,56],25:[2,56],26:[2,56],49:[2,56],54:[2,56]},{27:105,28:[1,71],44:106,55:290,56:104,58:107,59:108,76:[1,68],89:[1,109],90:[1,110]},{6:[2,54],25:[2,54],26:[2,54],27:105,28:[1,71],44:106,48:291,54:[2,54],55:103,56:104,58:107,59:108,76:[1,68],89:[1,109],90:[1,110]},{6:[2,61],25:[2,61],26:[2,61],49:[2,61],54:[2,61],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,24],6:[2,24],25:[2,24],26:[2,24],49:[2,24],54:[2,24],57:[2,24],73:[2,24],78:[2,24],86:[2,24],91:[2,24],93:[2,24],98:[2,24],99:[2,24],102:[2,24],104:[2,24],105:[2,24],106:[2,24],110:[2,24],118:[2,24],121:[2,24],123:[2,24],126:[2,24],128:[2,24],129:[2,24],132:[2,24],133:[2,24],134:[2,24],135:[2,24],136:[2,24],137:[2,24]},{26:[1,292],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,203],6:[2,203],25:[2,203],26:[2,203],49:[2,203],54:[2,203],57:[2,203],73:[2,203],78:[2,203],86:[2,203],91:[2,203],93:[2,203],102:[2,203],103:82,104:[2,203],105:[2,203],106:[2,203],109:83,110:[2,203],111:67,118:[2,203],126:[2,203],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{24:293,25:[1,112],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{24:294,25:[1,112]},{1:[2,134],6:[2,134],25:[2,134],26:[2,134],49:[2,134],54:[2,134],57:[2,134],73:[2,134],78:[2,134],86:[2,134],91:[2,134],93:[2,134],102:[2,134],104:[2,134],105:[2,134],106:[2,134],110:[2,134],118:[2,134],126:[2,134],128:[2,134],129:[2,134],132:[2,134],133:[2,134],134:[2,134],135:[2,134],136:[2,134],137:[2,134]},{24:295,25:[1,112]},{24:296,25:[1,112]},{1:[2,138],6:[2,138],25:[2,138],26:[2,138],49:[2,138],54:[2,138],57:[2,138],73:[2,138],78:[2,138],86:[2,138],91:[2,138],93:[2,138],98:[2,138],102:[2,138],104:[2,138],105:[2,138],106:[2,138],110:[2,138],118:[2,138],126:[2,138],128:[2,138],129:[2,138],132:[2,138],133:[2,138],134:[2,138],135:[2,138],136:[2,138],137:[2,138]},{26:[1,297],121:[1,298],122:262,123:[1,217]},{1:[2,174],6:[2,174],25:[2,174],26:[2,174],49:[2,174],54:[2,174],57:[2,174],73:[2,174],78:[2,174],86:[2,174],91:[2,174],93:[2,174],102:[2,174],104:[2,174],105:[2,174],106:[2,174],110:[2,174],118:[2,174],126:[2,174],128:[2,174],129:[2,174],132:[2,174],133:[2,174],134:[2,174],135:[2,174],136:[2,174],137:[2,174]},{24:299,25:[1,112]},{26:[2,177],121:[2,177],123:[2,177]},{24:300,25:[1,112],54:[1,301]},{25:[2,130],54:[2,130],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,98],6:[2,98],25:[2,98],26:[2,98],49:[2,98],54:[2,98],57:[2,98],73:[2,98],78:[2,98],86:[2,98],91:[2,98],93:[2,98],102:[2,98],104:[2,98],105:[2,98],106:[2,98],110:[2,98],118:[2,98],126:[2,98],128:[2,98],129:[2,98],132:[2,98],133:[2,98],134:[2,98],135:[2,98],136:[2,98],137:[2,98]},{1:[2,101],6:[2,101],24:302,25:[1,112],26:[2,101],49:[2,101],54:[2,101],57:[2,101],73:[2,101],78:[2,101],86:[2,101],91:[2,101],93:[2,101],102:[2,101],103:82,104:[1,63],105:[2,101],106:[1,64],109:83,110:[1,66],111:67,118:[2,101],126:[2,101],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{102:[1,303]},{91:[1,304],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,115],6:[2,115],25:[2,115],26:[2,115],40:[2,115],49:[2,115],54:[2,115],57:[2,115],66:[2,115],67:[2,115],68:[2,115],69:[2,115],71:[2,115],73:[2,115],74:[2,115],78:[2,115],84:[2,115],85:[2,115],86:[2,115],91:[2,115],93:[2,115],102:[2,115],104:[2,115],105:[2,115],106:[2,115],110:[2,115],116:[2,115],117:[2,115],118:[2,115],126:[2,115],128:[2,115],129:[2,115],132:[2,115],133:[2,115],134:[2,115],135:[2,115],136:[2,115],137:[2,115]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],94:305,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:197,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,25:[1,143],27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,60:144,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],87:306,88:[1,56],89:[1,57],90:[1,55],94:142,96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[2,124],25:[2,124],26:[2,124],54:[2,124],86:[2,124],91:[2,124]},{6:[1,270],25:[1,271],26:[1,307]},{1:[2,143],6:[2,143],25:[2,143],26:[2,143],49:[2,143],54:[2,143],57:[2,143],73:[2,143],78:[2,143],86:[2,143],91:[2,143],93:[2,143],102:[2,143],103:82,104:[1,63],105:[2,143],106:[1,64],109:83,110:[1,66],111:67,118:[2,143],126:[2,143],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,145],6:[2,145],25:[2,145],26:[2,145],49:[2,145],54:[2,145],57:[2,145],73:[2,145],78:[2,145],86:[2,145],91:[2,145],93:[2,145],102:[2,145],103:82,104:[1,63],105:[2,145],106:[1,64],109:83,110:[1,66],111:67,118:[2,145],126:[2,145],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{116:[2,164],117:[2,164]},{7:308,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:309,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:310,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,89],6:[2,89],25:[2,89],26:[2,89],40:[2,89],49:[2,89],54:[2,89],57:[2,89],66:[2,89],67:[2,89],68:[2,89],69:[2,89],71:[2,89],73:[2,89],74:[2,89],78:[2,89],84:[2,89],85:[2,89],86:[2,89],91:[2,89],93:[2,89],102:[2,89],104:[2,89],105:[2,89],106:[2,89],110:[2,89],116:[2,89],117:[2,89],118:[2,89],126:[2,89],128:[2,89],129:[2,89],132:[2,89],133:[2,89],134:[2,89],135:[2,89],136:[2,89],137:[2,89]},{10:165,27:166,28:[1,71],29:167,30:[1,69],31:[1,70],41:311,42:164,44:168,46:[1,44],89:[1,109]},{6:[2,90],10:165,25:[2,90],26:[2,90],27:166,28:[1,71],29:167,30:[1,69],31:[1,70],41:163,42:164,44:168,46:[1,44],54:[2,90],77:312,89:[1,109]},{6:[2,92],25:[2,92],26:[2,92],54:[2,92],78:[2,92]},{6:[2,39],25:[2,39],26:[2,39],54:[2,39],78:[2,39],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{7:313,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{73:[2,119],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,37],6:[2,37],25:[2,37],26:[2,37],49:[2,37],54:[2,37],57:[2,37],73:[2,37],78:[2,37],86:[2,37],91:[2,37],93:[2,37],102:[2,37],104:[2,37],105:[2,37],106:[2,37],110:[2,37],118:[2,37],126:[2,37],128:[2,37],129:[2,37],132:[2,37],133:[2,37],134:[2,37],135:[2,37],136:[2,37],137:[2,37]},{1:[2,110],6:[2,110],25:[2,110],26:[2,110],49:[2,110],54:[2,110],57:[2,110],66:[2,110],67:[2,110],68:[2,110],69:[2,110],71:[2,110],73:[2,110],74:[2,110],78:[2,110],84:[2,110],85:[2,110],86:[2,110],91:[2,110],93:[2,110],102:[2,110],104:[2,110],105:[2,110],106:[2,110],110:[2,110],118:[2,110],126:[2,110],128:[2,110],129:[2,110],132:[2,110],133:[2,110],134:[2,110],135:[2,110],136:[2,110],137:[2,110]},{1:[2,48],6:[2,48],25:[2,48],26:[2,48],49:[2,48],54:[2,48],57:[2,48],73:[2,48],78:[2,48],86:[2,48],91:[2,48],93:[2,48],102:[2,48],104:[2,48],105:[2,48],106:[2,48],110:[2,48],118:[2,48],126:[2,48],128:[2,48],129:[2,48],132:[2,48],133:[2,48],134:[2,48],135:[2,48],136:[2,48],137:[2,48]},{6:[2,57],25:[2,57],26:[2,57],49:[2,57],54:[2,57]},{6:[2,52],25:[2,52],26:[2,52],53:314,54:[1,199]},{1:[2,202],6:[2,202],25:[2,202],26:[2,202],49:[2,202],54:[2,202],57:[2,202],73:[2,202],78:[2,202],86:[2,202],91:[2,202],93:[2,202],102:[2,202],104:[2,202],105:[2,202],106:[2,202],110:[2,202],118:[2,202],126:[2,202],128:[2,202],129:[2,202],132:[2,202],133:[2,202],134:[2,202],135:[2,202],136:[2,202],137:[2,202]},{1:[2,181],6:[2,181],25:[2,181],26:[2,181],49:[2,181],54:[2,181],57:[2,181],73:[2,181],78:[2,181],86:[2,181],91:[2,181],93:[2,181],102:[2,181],104:[2,181],105:[2,181],106:[2,181],110:[2,181],118:[2,181],121:[2,181],126:[2,181],128:[2,181],129:[2,181],132:[2,181],133:[2,181],134:[2,181],135:[2,181],136:[2,181],137:[2,181]},{1:[2,135],6:[2,135],25:[2,135],26:[2,135],49:[2,135],54:[2,135],57:[2,135],73:[2,135],78:[2,135],86:[2,135],91:[2,135],93:[2,135],102:[2,135],104:[2,135],105:[2,135],106:[2,135],110:[2,135],118:[2,135],126:[2,135],128:[2,135],129:[2,135],132:[2,135],133:[2,135],134:[2,135],135:[2,135],136:[2,135],137:[2,135]},{1:[2,136],6:[2,136],25:[2,136],26:[2,136],49:[2,136],54:[2,136],57:[2,136],73:[2,136],78:[2,136],86:[2,136],91:[2,136],93:[2,136],98:[2,136],102:[2,136],104:[2,136],105:[2,136],106:[2,136],110:[2,136],118:[2,136],126:[2,136],128:[2,136],129:[2,136],132:[2,136],133:[2,136],134:[2,136],135:[2,136],136:[2,136],137:[2,136]},{1:[2,137],6:[2,137],25:[2,137],26:[2,137],49:[2,137],54:[2,137],57:[2,137],73:[2,137],78:[2,137],86:[2,137],91:[2,137],93:[2,137],98:[2,137],102:[2,137],104:[2,137],105:[2,137],106:[2,137],110:[2,137],118:[2,137],126:[2,137],128:[2,137],129:[2,137],132:[2,137],133:[2,137],134:[2,137],135:[2,137],136:[2,137],137:[2,137]},{1:[2,172],6:[2,172],25:[2,172],26:[2,172],49:[2,172],54:[2,172],57:[2,172],73:[2,172],78:[2,172],86:[2,172],91:[2,172],93:[2,172],102:[2,172],104:[2,172],105:[2,172],106:[2,172],110:[2,172],118:[2,172],126:[2,172],128:[2,172],129:[2,172],132:[2,172],133:[2,172],134:[2,172],135:[2,172],136:[2,172],137:[2,172]},{24:315,25:[1,112]},{26:[1,316]},{6:[1,317],26:[2,178],121:[2,178],123:[2,178]},{7:318,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{1:[2,102],6:[2,102],25:[2,102],26:[2,102],49:[2,102],54:[2,102],57:[2,102],73:[2,102],78:[2,102],86:[2,102],91:[2,102],93:[2,102],102:[2,102],104:[2,102],105:[2,102],106:[2,102],110:[2,102],118:[2,102],126:[2,102],128:[2,102],129:[2,102],132:[2,102],133:[2,102],134:[2,102],135:[2,102],136:[2,102],137:[2,102]},{1:[2,141],6:[2,141],25:[2,141],26:[2,141],49:[2,141],54:[2,141],57:[2,141],66:[2,141],67:[2,141],68:[2,141],69:[2,141],71:[2,141],73:[2,141],74:[2,141],78:[2,141],84:[2,141],85:[2,141],86:[2,141],91:[2,141],93:[2,141],102:[2,141],104:[2,141],105:[2,141],106:[2,141],110:[2,141],118:[2,141],126:[2,141],128:[2,141],129:[2,141],132:[2,141],133:[2,141],134:[2,141],135:[2,141],136:[2,141],137:[2,141]},{1:[2,118],6:[2,118],25:[2,118],26:[2,118],49:[2,118],54:[2,118],57:[2,118],66:[2,118],67:[2,118],68:[2,118],69:[2,118],71:[2,118],73:[2,118],74:[2,118],78:[2,118],84:[2,118],85:[2,118],86:[2,118],91:[2,118],93:[2,118],102:[2,118],104:[2,118],105:[2,118],106:[2,118],110:[2,118],118:[2,118],126:[2,118],128:[2,118],129:[2,118],132:[2,118],133:[2,118],134:[2,118],135:[2,118],136:[2,118],137:[2,118]},{6:[2,125],25:[2,125],26:[2,125],54:[2,125],86:[2,125],91:[2,125]},{6:[2,52],25:[2,52],26:[2,52],53:319,54:[1,226]},{6:[2,126],25:[2,126],26:[2,126],54:[2,126],86:[2,126],91:[2,126]},{1:[2,167],6:[2,167],25:[2,167],26:[2,167],49:[2,167],54:[2,167],57:[2,167],73:[2,167],78:[2,167],86:[2,167],91:[2,167],93:[2,167],102:[2,167],103:82,104:[2,167],105:[2,167],106:[2,167],109:83,110:[2,167],111:67,118:[1,320],126:[2,167],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,169],6:[2,169],25:[2,169],26:[2,169],49:[2,169],54:[2,169],57:[2,169],73:[2,169],78:[2,169],86:[2,169],91:[2,169],93:[2,169],102:[2,169],103:82,104:[2,169],105:[1,321],106:[2,169],109:83,110:[2,169],111:67,118:[2,169],126:[2,169],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,168],6:[2,168],25:[2,168],26:[2,168],49:[2,168],54:[2,168],57:[2,168],73:[2,168],78:[2,168],86:[2,168],91:[2,168],93:[2,168],102:[2,168],103:82,104:[2,168],105:[2,168],106:[2,168],109:83,110:[2,168],111:67,118:[2,168],126:[2,168],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[2,93],25:[2,93],26:[2,93],54:[2,93],78:[2,93]},{6:[2,52],25:[2,52],26:[2,52],53:322,54:[1,236]},{26:[1,323],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,247],25:[1,248],26:[1,324]},{26:[1,325]},{1:[2,175],6:[2,175],25:[2,175],26:[2,175],49:[2,175],54:[2,175],57:[2,175],73:[2,175],78:[2,175],86:[2,175],91:[2,175],93:[2,175],102:[2,175],104:[2,175],105:[2,175],106:[2,175],110:[2,175],118:[2,175],126:[2,175],128:[2,175],129:[2,175],132:[2,175],133:[2,175],134:[2,175],135:[2,175],136:[2,175],137:[2,175]},{26:[2,179],121:[2,179],123:[2,179]},{25:[2,131],54:[2,131],103:82,104:[1,63],106:[1,64],109:83,110:[1,66],111:67,126:[1,81],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[1,270],25:[1,271],26:[1,326]},{7:327,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{7:328,8:114,9:18,10:19,11:[1,20],12:6,13:7,14:8,15:9,16:10,17:11,18:12,19:13,20:14,21:15,22:16,23:17,27:60,28:[1,71],29:47,30:[1,69],31:[1,70],32:22,33:[1,48],34:[1,49],35:[1,50],36:[1,51],37:[1,52],38:[1,53],39:21,44:61,45:[1,43],46:[1,44],47:[1,27],50:28,51:[1,58],52:[1,59],58:45,59:46,61:34,63:23,64:24,65:25,76:[1,68],79:[1,41],83:[1,26],88:[1,56],89:[1,57],90:[1,55],96:[1,36],100:[1,42],101:[1,54],103:37,104:[1,63],106:[1,64],107:38,108:[1,65],109:39,110:[1,66],111:67,119:[1,40],124:35,125:[1,62],127:[1,29],128:[1,30],129:[1,31],130:[1,32],131:[1,33]},{6:[1,281],25:[1,282],26:[1,329]},{6:[2,40],25:[2,40],26:[2,40],54:[2,40],78:[2,40]},{6:[2,58],25:[2,58],26:[2,58],49:[2,58],54:[2,58]},{1:[2,173],6:[2,173],25:[2,173],26:[2,173],49:[2,173],54:[2,173],57:[2,173],73:[2,173],78:[2,173],86:[2,173],91:[2,173],93:[2,173],102:[2,173],104:[2,173],105:[2,173],106:[2,173],110:[2,173],118:[2,173],126:[2,173],128:[2,173],129:[2,173],132:[2,173],133:[2,173],134:[2,173],135:[2,173],136:[2,173],137:[2,173]},{6:[2,127],25:[2,127],26:[2,127],54:[2,127],86:[2,127],91:[2,127]},{1:[2,170],6:[2,170],25:[2,170],26:[2,170],49:[2,170],54:[2,170],57:[2,170],73:[2,170],78:[2,170],86:[2,170],91:[2,170],93:[2,170],102:[2,170],103:82,104:[2,170],105:[2,170],106:[2,170],109:83,110:[2,170],111:67,118:[2,170],126:[2,170],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{1:[2,171],6:[2,171],25:[2,171],26:[2,171],49:[2,171],54:[2,171],57:[2,171],73:[2,171],78:[2,171],86:[2,171],91:[2,171],93:[2,171],102:[2,171],103:82,104:[2,171],105:[2,171],106:[2,171],109:83,110:[2,171],111:67,118:[2,171],126:[2,171],128:[1,75],129:[1,74],132:[1,73],133:[1,76],134:[1,77],135:[1,78],136:[1,79],137:[1,80]},{6:[2,94],25:[2,94],26:[2,94],54:[2,94],78:[2,94]}],defaultActions:{58:[2,50],59:[2,51],89:[2,108],186:[2,88]},parseError:function(t,n){if(!n.recoverable){var r=new Error(t);throw r.location=n.loc,r}this.trace(t)},parse:function(t){function v(e){r.length=r.length-2*e,i.length=i.length-e,s.length=s.length-e}function m(){var e;return e=n.lexer.lex()||h,typeof e!="number"&&(e=n.symbols_[e]||e),e}var n=this,r=[0],i=[null],s=[],o=this.table,u="",a=0,f=0,l=0,c=2,h=1;this.lexer.setInput(t),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,this.yy.parser=this,typeof this.lexer.yylloc=="undefined"&&(this.lexer.yylloc={});var p=this.lexer.yylloc;s.push(p);var d=this.lexer.options&&this.lexer.options.ranges;typeof this.yy.parseError=="function"?this.parseError=this.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;var g,y,b,w,E,S,x={},T,N,C,k;for(;;){b=r[r.length-1];if(this.defaultActions[b])w=this.defaultActions[b];else{if(g===null||typeof g=="undefined")g=m();w=o[b]&&o[b][g]}if(typeof w=="undefined"||!w.length||!w[0]){var L="";k=[];for(T in o[b])this.terminals_[T]&&T>c&&k.push("'"+this.terminals_[T]+"'");this.lexer.showPosition?L="Expecting "+k.join(", ")+", got '"+(this.terminals_[g]||g)+"'":L="Unexpected "+(g==h?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.lexer.yylloc.first_line!==p.first_line&&(p=this.lexer.yylloc),this.parseError(L,{text:this.lexer.match,token:this.terminals_[g]||g,line:this.lexer.yylineno,loc:p,expected:k})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+g);switch(w[0]){case 1:r.push(g),i.push(this.lexer.yytext),s.push(this.lexer.yylloc),r.push(w[1]),g=null,y?(g=y,y=null):(f=this.lexer.yyleng,u=this.lexer.yytext,a=this.lexer.yylineno,p=this.lexer.yylloc,l>0&&l--);break;case 2:N=this.productions_[w[1]][1],x.$=i[i.length-N],x._$={first_line:s[s.length-(N||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(N||1)].first_column,last_column:s[s.length-1].last_column},d&&(x._$.range=[s[s.length-(N||1)].range[0],s[s.length-1].range[1]]),S=this.performAction.call(x,u,f,a,this.yy,w[1],i,s);if(typeof S!="undefined")return S;N&&(r=r.slice(0,-1*N*2),i=i.slice(0,-1*N),s=s.slice(0,-1*N)),r.push(this.productions_[w[1]][0]),i.push(x.$),s.push(x._$),C=o[r[r.length-2]][r[r.length-1]],r.push(C);break;case 3:return!0}}return!0}};undefined,i.prototype=r,r.Parser=i,n.exports=new i}),ace.define("ace/mode/coffee/scope",["require","exports","module","ace/mode/coffee/helpers"],function(e,t,n){var r,i,s,o;o=e("./helpers"),i=o.extend,s=o.last,t.Scope=r=function(){function e(t,n,r){this.parent=t,this.expressions=n,this.method=r,this.variables=[{name:"arguments",type:"arguments"}],this.positions={},this.parent||(e.root=this)}return e.root=null,e.prototype.add=function(e,t,n){return this.shared&&!n?this.parent.add(e,t,n):Object.prototype.hasOwnProperty.call(this.positions,e)?this.variables[this.positions[e]].type=t:this.positions[e]=this.variables.push({name:e,type:t})-1},e.prototype.namedMethod=function(){var e;return((e=this.method)!=null?e.name:void 0)||!this.parent?this.method:this.parent.namedMethod()},e.prototype.find=function(e){return this.check(e)?!0:(this.add(e,"var"),!1)},e.prototype.parameter=function(e){if(this.shared&&this.parent.check(e,!0))return;return this.add(e,"param")},e.prototype.check=function(e){var t;return!!(this.type(e)||((t=this.parent)!=null?t.check(e):void 0))},e.prototype.temporary=function(e,t){return e.length>1?"_"+e+(t>1?t-1:""):"_"+(t+parseInt(e,36)).toString(36).replace(/\d/g,"a")},e.prototype.type=function(e){var t,n,r,i;i=this.variables;for(n=0,r=i.length;n<r;n++){t=i[n];if(t.name===e)return t.type}return null},e.prototype.freeVariable=function(e,t){var n,r;t==null&&(t=!0),n=0;while(this.check(r=this.temporary(e,n)))n++;return t&&this.add(r,"var",!0),r},e.prototype.assign=function(e,t){return this.add(e,{value:t,assigned:!0},!0),this.hasAssignments=!0},e.prototype.hasDeclarations=function(){return!!this.declaredVariables().length},e.prototype.declaredVariables=function(){var e,t,n,r,i,s;e=[],t=[],s=this.variables;for(r=0,i=s.length;r<i;r++)n=s[r],n.type==="var"&&(n.name.charAt(0)==="_"?t:e).push(n.name);return e.sort().concat(t.sort())},e.prototype.assignedVariables=function(){var e,t,n,r,i;r=this.variables,i=[];for(t=0,n=r.length;t<n;t++)e=r[t],e.type.assigned&&i.push(""+e.name+" = "+e.type.value);return i},e}()}),ace.define("ace/mode/coffee/nodes",["require","exports","module","ace/mode/coffee/scope","ace/mode/coffee/lexer","ace/mode/coffee/helpers"],function(e,t,n){var r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E,S,x,T,N,C,k,L,A,O,M,_,D,P,H,B,j,F,I,q,R,U,z,W,X,V,$,J,K,Q,G,Y,Z,et,tt,nt,rt,it,st,ot,ut,at,ft,lt,ct,ht,pt,dt,vt,mt,gt,yt,bt,wt,Et,St,xt={}.hasOwnProperty,Tt=function(e,t){function r(){this.constructor=e}for(var n in t)xt.call(t,n)&&(e[n]=t[n]);return r.prototype=t.prototype,e.prototype=new r,e.__super__=t.prototype,e},Nt=[].indexOf||function(e){for(var t=0,n=this.length;t<n;t++)if(t in this&&this[t]===e)return t;return-1},Ct=[].slice;Error.stackTraceLimit=Infinity,W=e("./scope").Scope,Et=e("./lexer"),I=Et.RESERVED,z=Et.STRICT_PROSCRIBED,St=e("./helpers"),rt=St.compact,ut=St.flatten,ot=St.extend,pt=St.merge,it=St.del,gt=St.starts,st=St.ends,ct=St.last,mt=St.some,nt=St.addLocationDataFn,ht=St.locationDataToString,yt=St.throwSyntaxError,t.extend=ot,t.addLocationDataFn=nt,tt=function(){return!0},D=function(){return!1},K=function(){return this},_=function(){return this.negated=!this.negated,this},t.CodeFragment=c=function(){function e(e,t){var n;this.code=""+t,this.locationData=e!=null?e.locationData:void 0,this.type=(e!=null?(n=e.constructor)!=null?n.name:void 0:void 0)||"unknown"}return e.prototype.toString=function(){return""+this.code+(this.locationData?": "+ht(this.locationData):"")},e}(),at=function(e){var t;return function(){var n,r,i;i=[];for(n=0,r=e.length;n<r;n++)t=e[n],i.push(t.code);return i}().join("")},t.Base=o=function(){function e(){}return e.prototype.compile=function(e,t){return at(this.compileToFragments(e,t))},e.prototype.compileToFragments=function(e,t){var n;return e=ot({},e),t&&(e.level=t),n=this.unfoldSoak(e)||this,n.tab=e.indent,e.level===A||!n.isStatement(e)?n.compileNode(e):n.compileClosure(e)},e.prototype.compileClosure=function(e){var t,n,i,s,o;(s=this.jumps())&&s.error("cannot use a pure statement in an expression"),e.sharedScope=!0,i=new l([],u.wrap([this])),t=[];if((n=this.contains(ft))||this.contains(lt))t=[new O("this")],n?(o="apply",t.push(new O("arguments"))):o="call",i=new Z(i,[new r(new O(o))]);return(new a(i,t)).compileNode(e)},e.prototype.cache=function(e,t,n){var r,i;return this.isComplex()?(r=new O(n||e.scope.freeVariable("ref")),i=new s(r,this),t?[i.compileToFragments(e,t),[this.makeCode(r.value)]]:[i,r]):(r=t?this.compileToFragments(e,t):this,[r,r])},e.prototype.cacheToCodeFragments=function(e){return[at(e[0]),at(e[1])]},e.prototype.makeReturn=function(e){var t;return t=this.unwrapAll(),e?new a(new O(""+e+".push"),[t]):new R(t)},e.prototype.contains=function(e){var t;return t=void 0,this.traverseChildren(!1,function(n){if(e(n))return t=n,!1}),t},e.prototype.lastNonComment=function(e){var t;t=e.length;while(t--)if(!(e[t]instanceof h))return e[t];return null},e.prototype.toString=function(e,t){var n;return e==null&&(e=""),t==null&&(t=this.constructor.name),n="\n"+e+t,this.soak&&(n+="?"),this.eachChild(function(t){return n+=t.toString(e+J)}),n},e.prototype.eachChild=function(e){var t,n,r,i,s,o,u,a;if(!this.children)return this;u=this.children;for(r=0,s=u.length;r<s;r++){t=u[r];if(this[t]){a=ut([this[t]]);for(i=0,o=a.length;i<o;i++){n=a[i];if(e(n)===!1)return this}}}return this},e.prototype.traverseChildren=function(e,t){return this.eachChild(function(n){var r;r=t(n);if(r!==!1)return n.traverseChildren(e,t)})},e.prototype.invert=function(){return new B("!",this)},e.prototype.unwrapAll=function(){var e;e=this;while(e!==(e=e.unwrap()))continue;return e},e.prototype.children=[],e.prototype.isStatement=D,e.prototype.jumps=D,e.prototype.isComplex=tt,e.prototype.isChainable=D,e.prototype.isAssignable=D,e.prototype.unwrap=K,e.prototype.unfoldSoak=D,e.prototype.assigns=D,e.prototype.updateLocationDataIfMissing=function(e){return this.locationData?this:(this.locationData=e,this.eachChild(function(t){return t.updateLocationDataIfMissing(e)}))},e.prototype.error=function(e){return yt(e,this.locationData)},e.prototype.makeCode=function(e){return new c(this,e)},e.prototype.wrapInBraces=function(e){return[].concat(this.makeCode("("),e,this.makeCode(")"))},e.prototype.joinFragmentArrays=function(e,t){var n,r,i,s,o;n=[];for(i=s=0,o=e.length;s<o;i=++s)r=e[i],i&&n.push(this.makeCode(t)),n=n.concat(r);return n},e}(),t.Block=u=function(e){function t(e){this.expressions=rt(ut(e||[]))}return Tt(t,e),t.prototype.children=["expressions"],t.prototype.push=function(e){return this.expressions.push(e),this},t.prototype.pop=function(){return this.expressions.pop()},t.prototype.unshift=function(e){return this.expressions.unshift(e),this},t.prototype.unwrap=function(){return this.expressions.length===1?this.expressions[0]:this},t.prototype.isEmpty=function(){return!this.expressions.length},t.prototype.isStatement=function(e){var t,n,r,i;i=this.expressions;for(n=0,r=i.length;n<r;n++){t=i[n];if(t.isStatement(e))return!0}return!1},t.prototype.jumps=function(e){var t,n,r,i,s;s=this.expressions;for(r=0,i=s.length;r<i;r++){t=s[r];if(n=t.jumps(e))return n}},t.prototype.makeReturn=function(e){var t,n;n=this.expressions.length;while(n--){t=this.expressions[n];if(!(t instanceof h)){this.expressions[n]=t.makeReturn(e),t instanceof R&&!t.expression&&this.expressions.splice(n,1);break}}return this},t.prototype.compileToFragments=function(e,n){return e==null&&(e={}),e.scope?t.__super__.compileToFragments.call(this,e,n):this.compileRoot(e)},t.prototype.compileNode=function(e){var n,r,i,s,o,u,a,f,l;this.tab=e.indent,u=e.level===A,r=[],l=this.expressions;for(s=a=0,f=l.length;a<f;s=++a)o=l[s],o=o.unwrapAll(),o=o.unfoldSoak(e)||o,o instanceof t?r.push(o.compileNode(e)):u?(o.front=!0,i=o.compileToFragments(e),o.isStatement(e)||(i.unshift(this.makeCode(""+this.tab)),i.push(this.makeCode(";"))),r.push(i)):r.push(o.compileToFragments(e,C));return u?this.spaced?[].concat(this.joinFragmentArrays(r,"\n\n"),this.makeCode("\n")):this.joinFragmentArrays(r,"\n"):(r.length?n=this.joinFragmentArrays(r,", "):n=[this.makeCode("void 0")],r.length>1&&e.level>=C?this.wrapInBraces(n):n)},t.prototype.compileRoot=function(e){var t,n,r,i,s,o,u,a,f,l;e.indent=e.bare?"":J,e.level=A,this.spaced=!0,e.scope=new W(null,this,null),l=e.locals||[];for(a=0,f=l.length;a<f;a++)i=l[a],e.scope.parameter(i);return s=[],e.bare||(o=function(){var e,n,i,s;i=this.expressions,s=[];for(r=e=0,n=i.length;e<n;r=++e){t=i[r];if(!(t.unwrap()instanceof h))break;s.push(t)}return s}.call(this),u=this.expressions.slice(o.length),this.expressions=o,o.length&&(s=this.compileNode(pt(e,{indent:""})),s.push(this.makeCode("\n"))),this.expressions=u),n=this.compileWithDeclarations(e),e.bare?n:[].concat(s,this.makeCode("(function() {\n"),n,this.makeCode("\n}).call(this);\n"))},t.prototype.compileWithDeclarations=function(e){var t,n,r,i,s,o,u,a,f,l,c,p,d,v;i=[],o=[],p=this.expressions;for(s=l=0,c=p.length;l<c;s=++l){r=p[s],r=r.unwrap();if(!(r instanceof h||r instanceof O))break}return e=pt(e,{level:A}),s&&(u=this.expressions.splice(s,9e9),d=[this.spaced,!1],f=d[0],this.spaced=d[1],v=[this.compileNode(e),f],i=v[0],this.spaced=v[1],this.expressions=u),o=this.compileNode(e),a=e.scope,a.expressions===this&&(n=e.scope.hasDeclarations(),t=a.hasAssignments,n||t?(s&&i.push(this.makeCode("\n")),i.push(this.makeCode(""+this.tab+"var ")),n&&i.push(this.makeCode(a.declaredVariables().join(", "))),t&&(n&&i.push(this.makeCode(",\n"+(this.tab+J))),i.push(this.makeCode(a.assignedVariables().join(",\n"+(this.tab+J))))),i.push(this.makeCode(";\n"+(this.spaced?"\n":"")))):i.length&&o.length&&i.push(this.makeCode("\n"))),i.concat(o)},t.wrap=function(e){return e.length===1&&e[0]instanceof t?e[0]:new t(e)},t}(o),t.Literal=O=function(e){function t(e){this.value=e}return Tt(t,e),t.prototype.makeReturn=function(){return this.isStatement()?this:t.__super__.makeReturn.apply(this,arguments)},t.prototype.isAssignable=function(){return g.test(this.value)},t.prototype.isStatement=function(){var e;return(e=this.value)==="break"||e==="continue"||e==="debugger"},t.prototype.isComplex=D,t.prototype.assigns=function(e){return e===this.value},t.prototype.jumps=function(e){if(this.value==="break"&&!((e!=null?e.loop:void 0)||(e!=null?e.block:void 0)))return this;if(this.value==="continue"&&(e!=null?!e.loop:!void 0))return this},t.prototype.compileNode=function(e){var t,n,r;return n=this.value==="this"?((r=e.scope.method)!=null?r.bound:void 0)?e.scope.method.context:this.value:this.value.reserved?'"'+this.value+'"':this.value,t=this.isStatement()?""+this.tab+n+";":n,[this.makeCode(t)]},t.prototype.toString=function(){return' "'+this.value+'"'},t}(o),t.Undefined=function(e){function t(){return t.__super__.constructor.apply(this,arguments)}return Tt(t,e),t.prototype.isAssignable=D,t.prototype.isComplex=D,t.prototype.compileNode=function(e){return[this.makeCode(e.level>=T?"(void 0)":"void 0")]},t}(o),t.Null=function(e){function t(){return t.__super__.constructor.apply(this,arguments)}return Tt(t,e),t.prototype.isAssignable=D,t.prototype.isComplex=D,t.prototype.compileNode=function(){return[this.makeCode("null")]},t}(o),t.Bool=function(e){function t(e){this.val=e}return Tt(t,e),t.prototype.isAssignable=D,t.prototype.isComplex=D,t.prototype.compileNode=function(){return[this.makeCode(this.val)]},t}(o),t.Return=R=function(e){function t(e){e&&!e.unwrap().isUndefined&&(this.expression=e)}return Tt(t,e),t.prototype.children=["expression"],t.prototype.isStatement=tt,t.prototype.makeReturn=K,t.prototype.jumps=K,t.prototype.compileToFragments=function(e,n){var r,i;return r=(i=this.expression)!=null?i.makeReturn():void 0,!r||r instanceof t?t.__super__.compileToFragments.call(this,e,n):r.compileToFragments(e,n)},t.prototype.compileNode=function(e){var t;return t=[],t.push(this.makeCode(this.tab+("return"+(this.expression?" ":"")))),this.expression&&(t=t.concat(this.expression.compileToFragments(e,L))),t.push(this.makeCode(";")),t},t}(o),t.Value=Z=function(e){function t(e,n,r){return!n&&e instanceof t?e:(this.base=e,this.properties=n||[],r&&(this[r]=!0),this)}return Tt(t,e),t.prototype.children=["base","properties"],t.prototype.add=function(e){return this.properties=this.properties.concat(e),this},t.prototype.hasProperties=function(){return!!this.properties.length},t.prototype.bareLiteral=function(e){return!this.properties.length&&this.base instanceof e},t.prototype.isArray=function(){return this.bareLiteral(i)},t.prototype.isRange=function(){return this.bareLiteral(q)},t.prototype.isComplex=function(){return this.hasProperties()||this.base.isComplex()},t.prototype.isAssignable=function(){return this.hasProperties()||this.base.isAssignable()},t.prototype.isSimpleNumber=function(){return this.bareLiteral(O)&&U.test(this.base.value)},t.prototype.isString=function(){return this.bareLiteral(O)&&w.test(this.base.value)},t.prototype.isRegex=function(){return this.bareLiteral(O)&&b.test(this.base.value)},t.prototype.isAtomic=function(){var e,t,n,r;r=this.properties.concat(this.base);for(t=0,n=r.length;t<n;t++){e=r[t];if(e.soak||e instanceof a)return!1}return!0},t.prototype.isNotCallable=function(){return this.isSimpleNumber()||this.isString()||this.isRegex()||this.isArray()||this.isRange()||this.isSplice()||this.isObject()},t.prototype.isStatement=function(e){return!this.properties.length&&this.base.isStatement(e)},t.prototype.assigns=function(e){return!this.properties.length&&this.base.assigns(e)},t.prototype.jumps=function(e){return!this.properties.length&&this.base.jumps(e)},t.prototype.isObject=function(e){return this.properties.length?!1:this.base instanceof H&&(!e||this.base.generated)},t.prototype.isSplice=function(){return ct(this.properties)instanceof X},t.prototype.looksStatic=function(e){var t;return this.base.value===e&&this.properties.length&&((t=this.properties[0].name)!=null?t.value:void 0)!=="prototype"},t.prototype.unwrap=function(){return this.properties.length?this:this.base},t.prototype.cacheReference=function(e){var n,r,i,o;return i=ct(this.properties),this.properties.length<2&&!this.base.isComplex()&&(i!=null?!i.isComplex():!void 0)?[this,this]:(n=new t(this.base,this.properties.slice(0,-1)),n.isComplex()&&(r=new O(e.scope.freeVariable("base")),n=new t(new F(new s(r,n)))),i?(i.isComplex()&&(o=new O(e.scope.freeVariable("name")),i=new x(new s(o,i.index)),o=new x(o)),[n.add(i),new t(r||n.base,[o||i])]):[n,r])},t.prototype.compileNode=function(e){var t,n,r,i,s;this.base.front=this.front,r=this.properties,t=this.base.compileToFragments(e,r.length?T:null),(this.base instanceof F||r.length)&&U.test(at(t))&&t.push(this.makeCode("."));for(i=0,s=r.length;i<s;i++)n=r[i],t.push.apply(t,n.compileToFragments(e));return t},t.prototype.unfoldSoak=function(e){return this.unfoldedSoak!=null?this.unfoldedSoak:this.unfoldedSoak=function(n){return function(){var r,i,o,u,a,f,l,c,h,d;if(o=n.base.unfoldSoak(e))return(h=o.body.properties).push.apply(h,n.properties),o;d=n.properties;for(i=l=0,c=d.length;l<c;i=++l){u=d[i];if(!u.soak)continue;return u.soak=!1,r=new t(n.base,n.properties.slice(0,i)),f=new t(n.base,n.properties.slice(i)),r.isComplex()&&(a=new O(e.scope.freeVariable("ref")),r=new F(new s(a,r)),f.base=a),new E(new p(r),f,{soak:!0})}return!1}}(this)()},t}(o),t.Comment=h=function(e){function t(e){this.comment=e}return Tt(t,e),t.prototype.isStatement=tt,t.prototype.makeReturn=K,t.prototype.compileNode=function(e,t){var n,r;return r=this.comment.replace(/^(\s*)#/gm,"$1 *"),n="/*"+dt(r,this.tab)+(Nt.call(r,"\n")>=0?"\n"+this.tab:"")+" */",(t||e.level)===A&&(n=e.indent+n),[this.makeCode("\n"),this.makeCode(n)]},t}(o),t.Call=a=function(e){function t(e,t,n){this.args=t!=null?t:[],this.soak=n,this.isNew=!1,this.isSuper=e==="super",this.variable=this.isSuper?null:e,e instanceof Z&&e.isNotCallable()&&e.error("literal is not a function")}return Tt(t,e),t.prototype.children=["variable","args"],t.prototype.newInstance=function(){var e,n;return e=((n=this.variable)!=null?n.base:void 0)||this.variable,e instanceof t&&!e.isNew?e.newInstance():this.isNew=!0,this},t.prototype.superReference=function(e){var t,n;return n=e.scope.namedMethod(),(n!=null?n.klass:void 0)?(t=[new r(new O("__super__"))],n["static"]&&t.push(new r(new O("constructor"))),t.push(new r(new O(n.name))),(new Z(new O(n.klass),t)).compile(e)):(n!=null?n.ctor:void 0)?""+n.name+".__super__.constructor":this.error("cannot call super outside of an instance method.")},t.prototype.superThis=function(e){var t;return t=e.scope.method,t&&!t.klass&&t.context||"this"},t.prototype.unfoldSoak=function(e){var n,r,i,s,o,u,a,f,l;if(this.soak){if(this.variable){if(r=bt(e,this,"variable"))return r;f=(new Z(this.variable)).cacheReference(e),i=f[0],o=f[1]}else i=new O(this.superReference(e)),o=new Z(i);return o=new t(o,this.args),o.isNew=this.isNew,i=new O("typeof "+i.compile(e)+' === "function"'),new E(i,new Z(o),{soak:!0})}n=this,s=[];for(;;){if(n.variable instanceof t){s.push(n),n=n.variable;continue}if(!(n.variable instanceof Z))break;s.push(n);if(!((n=n.variable.base)instanceof t))break}l=s.reverse();for(u=0,a=l.length;u<a;u++)n=l[u],r&&(n.variable instanceof t?n.variable=r:n.variable.base=r),r=bt(e,n,"variable");return r},t.prototype.compileNode=function(e){var t,n,r,i,s,o,u,a,f,l;(f=this.variable)!=null&&(f.front=this.front),i=V.compileSplattedArray(e,this.args,!0);if(i.length)return this.compileSplat(e,i);r=[],l=this.args;for(n=u=0,a=l.length;u<a;n=++u)t=l[n],n&&r.push(this.makeCode(", ")),r.push.apply(r,t.compileToFragments(e,C));return s=[],this.isSuper?(o=this.superReference(e)+(".call("+this.superThis(e)),r.length&&(o+=", "),s.push(this.makeCode(o))):(this.isNew&&s.push(this.makeCode("new ")),s.push.apply(s,this.variable.compileToFragments(e,T)),s.push(this.makeCode("("))),s.push.apply(s,r),s.push(this.makeCode(")")),s},t.prototype.compileSplat=function(e,t){var n,r,i,s,o,u;return this.isSuper?[].concat(this.makeCode(""+this.superReference(e)+".apply("+this.superThis(e)+", "),t,this.makeCode(")")):this.isNew?(s=this.tab+J,[].concat(this.makeCode("(function(func, args, ctor) {\n"+s+"ctor.prototype = func.prototype;\n"+s+"var child = new ctor, result = func.apply(child, args);\n"+s+"return Object(result) === result ? result : child;\n"+this.tab+"})("),this.variable.compileToFragments(e,C),this.makeCode(", "),t,this.makeCode(", function(){})"))):(n=[],r=new Z(this.variable),(o=r.properties.pop())&&r.isComplex()?(u=e.scope.freeVariable("ref"),n=n.concat(this.makeCode("("+u+" = "),r.compileToFragments(e,C),this.makeCode(")"),o.compileToFragments(e))):(i=r.compileToFragments(e,T),U.test(at(i))&&(i=this.wrapInBraces(i)),o?(u=at(i),i.push.apply(i,o.compileToFragments(e))):u="null",n=n.concat(i)),n=n.concat(this.makeCode(".apply("+u+", "),t,this.makeCode(")")))},t}(o),t.Extends=d=function(e){function t(e,t){this.child=e,this.parent=t}return Tt(t,e),t.prototype.children=["child","parent"],t.prototype.compileToFragments=function(e){return(new a(new Z(new O(wt("extends"))),[this.child,this.parent])).compileToFragments(e)},t}(o),t.Access=r=function(e){function t(e,t){this.name=e,this.name.asKey=!0,this.soak=t==="soak"}return Tt(t,e),t.prototype.children=["name"],t.prototype.compileToFragments=function(e){var t;return t=this.name.compileToFragments(e),g.test(at(t))?t.unshift(this.makeCode(".")):(t.unshift(this.makeCode("[")),t.push(this.makeCode("]"))),t},t.prototype.isComplex=D,t}(o),t.Index=x=function(e){function t(e){this.index=e}return Tt(t,e),t.prototype.children=["index"],t.prototype.compileToFragments=function(e){return[].concat(this.makeCode("["),this.index.compileToFragments(e,L),this.makeCode("]"))},t.prototype.isComplex=function(){return this.index.isComplex()},t}(o),t.Range=q=function(e){function t(e,t,n){this.from=e,this.to=t,this.exclusive=n==="exclusive",this.equals=this.exclusive?"":"="}return Tt(t,e),t.prototype.children=["from","to"],t.prototype.compileVariables=function(e){var t,n,r,i,s;e=pt(e,{top:!0}),n=this.cacheToCodeFragments(this.from.cache(e,C)),this.fromC=n[0],this.fromVar=n[1],r=this.cacheToCodeFragments(this.to.cache(e,C)),this.toC=r[0],this.toVar=r[1];if(t=it(e,"step"))i=this.cacheToCodeFragments(t.cache(e,C)),this.step=i[0],this.stepVar=i[1];s=[this.fromVar.match(P),this.toVar.match(P)],this.fromNum=s[0],this.toNum=s[1];if(this.stepVar)return this.stepNum=this.stepVar.match(P)},t.prototype.compileNode=function(e){var t,n,r,i,s,o,u,a,f,l,c,h,p,d;return this.fromVar||this.compileVariables(e),e.index?(u=this.fromNum&&this.toNum,s=it(e,"index"),o=it(e,"name"),f=o&&o!==s,h=""+s+" = "+this.fromC,this.toC!==this.toVar&&(h+=", "+this.toC),this.step!==this.stepVar&&(h+=", "+this.step),p=[""+s+" <"+this.equals,""+s+" >"+this.equals],a=p[0],i=p[1],n=this.stepNum?vt(this.stepNum[0])>0?""+a+" "+this.toVar:""+i+" "+this.toVar:u?(d=[vt(this.fromNum[0]),vt(this.toNum[0])],r=d[0],c=d[1],d,r<=c?""+a+" "+c:""+i+" "+c):(t=this.stepVar?""+this.stepVar+" > 0":""+this.fromVar+" <= "+this.toVar,""+t+" ? "+a+" "+this.toVar+" : "+i+" "+this.toVar),l=this.stepVar?""+s+" += "+this.stepVar:u?f?r<=c?"++"+s:"--"+s:r<=c?""+s+"++":""+s+"--":f?""+t+" ? ++"+s+" : --"+s:""+t+" ? "+s+"++ : "+s+"--",f&&(h=""+o+" = "+h),f&&(l=""+o+" = "+l),[this.makeCode(""+h+"; "+n+"; "+l)]):this.compileArray(e)},t.prototype.compileArray=function(e){var t,n,r,i,s,o,u,a,f,l,c,h,p,d,v;if(this.fromNum&&this.toNum&&Math.abs(this.fromNum-this.toNum)<=20)return f=function(){v=[];for(var e=p=+this.fromNum,t=+this.toNum;p<=t?e<=t:e>=t;p<=t?e++:e--)v.push(e);return v}.apply(this),this.exclusive&&f.pop(),[this.makeCode("["+f.join(", ")+"]")];o=this.tab+J,s=e.scope.freeVariable("i"),l=e.scope.freeVariable("results"),a="\n"+o+l+" = [];",this.fromNum&&this.toNum?(e.index=s,n=at(this.compileNode(e))):(c=""+s+" = "+this.fromC+(this.toC!==this.toVar?", "+this.toC:""),r=""+this.fromVar+" <= "+this.toVar,n="var "+c+"; "+r+" ? "+s+" <"+this.equals+" "+this.toVar+" : "+s+" >"+this.equals+" "+this.toVar+"; "+r+" ? "+s+"++ : "+s+"--"),u="{ "+l+".push("+s+"); }\n"+o+"return "+l+";\n"+e.indent,i=function(e){return e!=null?e.contains(ft):void 0};if(i(this.from)||i(this.to))t=", arguments";return[this.makeCode("(function() {"+a+"\n"+o+"for ("+n+")"+u+"}).apply(this"+(t!=null?t:"")+")")]},t}(o),t.Slice=X=function(e){function t(e){this.range=e,t.__super__.constructor.call(this)}return Tt(t,e),t.prototype.children=["range"],t.prototype.compileNode=function(e){var t,n,r,i,s,o,u;u=this.range,s=u.to,r=u.from,i=r&&r.compileToFragments(e,L)||[this.makeCode("0")];if(s){t=s.compileToFragments(e,L),n=at(t);if(!!this.range.exclusive||+n!==-1)o=", "+(this.range.exclusive?n:U.test(n)?""+(+n+1):(t=s.compileToFragments(e,T),"+"+at(t)+" + 1 || 9e9"))}return[this.makeCode(".slice("+at(i)+(o||"")+")")]},t}(o),t.Obj=H=function(e){function t(e,t){this.generated=t!=null?t:!1,this.objects=this.properties=e||[]}return Tt(t,e),t.prototype.children=["properties"],t.prototype.compileNode=function(e){var t,n,r,i,o,u,a,f,l,c,p,d,v;l=this.properties;if(!l.length)return[this.makeCode(this.front?"({})":"{}")];if(this.generated)for(c=0,d=l.length;c<d;c++)a=l[c],a instanceof Z&&a.error("cannot have an implicit value in an implicit object");r=e.indent+=J,u=this.lastNonComment(this.properties),t=[];for(n=p=0,v=l.length;p<v;n=++p)f=l[n],o=n===l.length-1?"":f===u||f instanceof h?"\n":",\n",i=f instanceof h?"":r,f instanceof s&&f.variable instanceof Z&&f.variable.hasProperties()&&f.variable.error("Invalid object key"),f instanceof Z&&f["this"]&&(f=new s(f.properties[0].name,f,"object")),f instanceof h||(f instanceof s||(f=new s(f,f,"object")),(f.variable.base||f.variable).asKey=!0),i&&t.push(this.makeCode(i)),t.push.apply(t,f.compileToFragments(e,A)),o&&t.push(this.makeCode(o));return t.unshift(this.makeCode("{"+(l.length&&"\n"))),t.push(this.makeCode(""+(l.length&&"\n"+this.tab)+"}")),this.front?this.wrapInBraces(t):t},t.prototype.assigns=function(e){var t,n,r,i;i=this.properties;for(n=0,r=i.length;n<r;n++){t=i[n];if(t.assigns(e))return!0}return!1},t}(o),t.Arr=i=function(e){function t(e){this.objects=e||[]}return Tt(t,e),t.prototype.children=["objects"],t.prototype.compileNode=function(e){var t,n,r,i,s,o,u;if(!this.objects.length)return[this.makeCode("[]")];e.indent+=J,t=V.compileSplattedArray(e,this.objects);if(t.length)return t;t=[],n=function(){var t,n,r,i;r=this.objects,i=[];for(t=0,n=r.length;t<n;t++)s=r[t],i.push(s.compileToFragments(e,C));return i}.call(this);for(i=o=0,u=n.length;o<u;i=++o)r=n[i],i&&t.push(this.makeCode(", ")),t.push.apply(t,r);return at(t).indexOf("\n")>=0?(t.unshift(this.makeCode("[\n"+e.indent)),t.push(this.makeCode("\n"+this.tab+"]"))):(t.unshift(this.makeCode("[")),t.push(this.makeCode("]"))),t},t.prototype.assigns=function(e){var t,n,r,i;i=this.objects;for(n=0,r=i.length;n<r;n++){t=i[n];if(t.assigns(e))return!0}return!1},t}(o),t.Class=f=function(e){function t(e,t,n){this.variable=e,this.parent=t,this.body=n!=null?n:new u,this.boundFuncs=[],this.body.classBody=!0}return Tt(t,e),t.prototype.children=["variable","parent","body"],t.prototype.determineName=function(){var e,t;return this.variable?(e=(t=ct(this.variable.properties))?t instanceof r&&t.name.value:this.variable.base.value,Nt.call(z,e)>=0&&this.variable.error("class variable name may not be "+e),e&&(e=g.test(e)&&e)):null},t.prototype.setContext=function(e){return this.body.traverseChildren(!1,function(t){if(t.classBody)return!1;if(t instanceof O&&t.value==="this")return t.value=e;if(t instanceof l){t.klass=e;if(t.bound)return t.context=e}})},t.prototype.addBoundFunctions=function(e){var t,n,i,s,o;o=this.boundFuncs;for(i=0,s=o.length;i<s;i++)t=o[i],n=(new Z(new O("this"),[new r(t)])).compile(e),this.ctor.body.unshift(new O(""+n+" = "+wt("bind")+"("+n+", this)"))},t.prototype.addProperties=function(e,t,n){var i,o,u,a,f;return f=e.base.properties.slice(0),u=function(){var e;e=[];while(i=f.shift())i instanceof s&&(o=i.variable.base,delete i.context,a=i.value,o.value==="constructor"?(this.ctor&&i.error("cannot define more than one constructor in a class"),a.bound&&i.error("cannot define a constructor as a bound function"),a instanceof l?i=this.ctor=a:(this.externalCtor=n.classScope.freeVariable("class"),i=new s(new O(this.externalCtor),a))):i.variable["this"]?a["static"]=!0:(i.variable=new Z(new O(t),[new r(new O("prototype")),new r(o)]),a instanceof l&&a.bound&&(this.boundFuncs.push(o),a.bound=!1))),e.push(i);return e}.call(this),rt(u)},t.prototype.walkBody=function(e,n){return this.traverseChildren(!1,function(r){return function(i){var o,a,f,l,c,h,p;o=!0;if(i instanceof t)return!1;if(i instanceof u){p=a=i.expressions;for(f=c=0,h=p.length;c<h;f=++c)l=p[f],l instanceof s&&l.variable.looksStatic(e)?l.value["static"]=!0:l instanceof Z&&l.isObject(!0)&&(o=!1,a[f]=r.addProperties(l,e,n));i.expressions=a=ut(a)}return o&&!(i instanceof t)}}(this))},t.prototype.hoistDirectivePrologue=function(){var e,t,n;t=0,e=this.body.expressions;while((n=e[t])&&n instanceof h||n instanceof Z&&n.isString())++t;return this.directives=e.splice(0,t)},t.prototype.ensureConstructor=function(e){return this.ctor||(this.ctor=new l,this.externalCtor?this.ctor.body.push(new O(""+this.externalCtor+".apply(this, arguments)")):this.parent&&this.ctor.body.push(new O(""+e+".__super__.constructor.apply(this, arguments)")),this.ctor.body.makeReturn(),this.body.expressions.unshift(this.ctor)),this.ctor.ctor=this.ctor.name=e,this.ctor.klass=null,this.ctor.noReturn=!0},t.prototype.compileNode=function(e){var t,n,r,i,o,f,c,h,p;return(i=this.body.jumps())&&i.error("Class bodies cannot contain pure statements"),(n=this.body.contains(ft))&&n.error("Class bodies shouldn't reference arguments"),c=this.determineName()||"_Class",c.reserved&&(c="_"+c),f=new O(c),r=new l([],u.wrap([this.body])),t=[],e.classScope=r.makeScope(e.scope),this.hoistDirectivePrologue(),this.setContext(c),this.walkBody(c,e),this.ensureConstructor(c),this.addBoundFunctions(e),this.body.spaced=!0,this.body.expressions.push(f),this.parent&&(h=new O(e.classScope.freeVariable("super",!1)),this.body.expressions.unshift(new d(f,h)),r.params.push(new j(h)),t.push(this.parent)),(p=this.body.expressions).unshift.apply(p,this.directives),o=new F(new a(r,t)),this.variable&&(o=new s(this.variable,o)),o.compileToFragments(e)},t}(o),t.Assign=s=function(e){function t(e,t,n,r){var i,s,o;this.variable=e,this.value=t,this.context=n,this.param=r&&r.param,this.subpattern=r&&r.subpattern,i=(o=s=this.variable.unwrapAll().value,Nt.call(z,o)>=0),i&&this.context!=="object"&&this.variable.error('variable name may not be "'+s+'"')}return Tt(t,e),t.prototype.children=["variable","value"],t.prototype.isStatement=function(e){return(e!=null?e.level:void 0)===A&&this.context!=null&&Nt.call(this.context,"?")>=0},t.prototype.assigns=function(e){return this[this.context==="object"?"value":"variable"].assigns(e)},t.prototype.unfoldSoak=function(e){return bt(e,this,"variable")},t.prototype.compileNode=function(e){var t,n,r,i,s,o,u,a,f,c;if(r=this.variable instanceof Z){if(this.variable.isArray()||this.variable.isObject())return this.compilePatternMatch(e);if(this.variable.isSplice())return this.compileSplice(e);if((a=this.context)==="||="||a==="&&="||a==="?=")return this.compileConditional(e)}n=this.variable.compileToFragments(e,C),s=at(n);if(!this.context){u=this.variable.unwrapAll(),u.isAssignable()||this.variable.error('"'+this.variable.compile(e)+'" cannot be assigned');if(typeof u.hasProperties=="function"?!u.hasProperties():!void 0)this.param?e.scope.add(s,"var"):e.scope.find(s)}return this.value instanceof l&&(i=M.exec(s))&&(i[2]&&(this.value.klass=i[1]),this.value.name=(f=(c=i[3])!=null?c:i[4])!=null?f:i[5]),o=this.value.compileToFragments(e,C),this.context==="object"?n.concat(this.makeCode(": "),o):(t=n.concat(this.makeCode(" "+(this.context||"=")+" "),o),e.level<=C?t:this.wrapInBraces(t))},t.prototype.compilePatternMatch=function(e){var n,i,s,o,u,a,f,l,c,h,p,d,v,m,y,b,w,E,S,T,N,L,M,_,D,P,H,B;b=e.level===A,E=this.value,p=this.variable.base.objects;if(!(d=p.length))return s=E.compileToFragments(e),e.level>=k?this.wrapInBraces(s):s;f=this.variable.isObject();if(!b||d!==1||(h=p[0])instanceof V){S=E.compileToFragments(e,C),T=at(S),i=[],y=!1;if(!g.test(T)||this.variable.assigns(T))i.push([this.makeCode(""+(v=e.scope.freeVariable("ref"))+" = ")].concat(Ct.call(S))),S=[this.makeCode(v)],T=v;for(u=N=0,L=p.length;N<L;u=++N)h=p[u],a=u,f&&(h instanceof t?(P=h,H=P.variable,a=H.base,h=P.value):h.base instanceof F?(B=(new Z(h.unwrapAll())).cacheReference(e),h=B[0],a=B[1]):a=h["this"]?h.properties[0].name:h),!y&&h instanceof V?(c=h.name.unwrap().value,h=h.unwrap(),w=""+d+" <= "+T+".length ? "+wt("slice")+".call("+T+", "+u,(m=d-u-1)?(l=e.scope.freeVariable("i"),w+=", "+l+" = "+T+".length - "+m+") : ("+l+" = "+u+", [])"):w+=") : []",w=new O(w),y=""+l+"++"):(c=h.unwrap().value,h instanceof V&&h.error("multiple splats are disallowed in an assignment"),typeof a=="number"?(a=new O(y||a),n=!1):n=f&&g.test(a.unwrap().value||0),w=new Z(new O(T),[new(n?r:x)(a)])),c!=null&&Nt.call(I,c)>=0&&h.error("assignment to a reserved word: "+h.compile(e)),i.push((new t(h,w,null,{param:this.param,subpattern:!0})).compileToFragments(e,C));return!b&&!this.subpattern&&i.push(S),o=this.joinFragmentArrays(i,", "),e.level<C?o:this.wrapInBraces(o)}return h instanceof t?(M=h,_=M.variable,a=_.base,h=M.value):a=f?h["this"]?h.properties[0].name:h:new O(0),n=g.test(a.unwrap().value||0),E=new Z(E),E.properties.push(new(n?r:x)(a)),(D=h.unwrap().value,Nt.call(I,D)>=0)&&h.error("assignment to a reserved word: "+h.compile(e)),(new t(h,E,null,{param:this.param})).compileToFragments(e,A)},t.prototype.compileConditional=function(e){var n,r,i,s;return s=this.variable.cacheReference(e),r=s[0],i=s[1],!r.properties.length&&r.base instanceof O&&r.base.value!=="this"&&!e.scope.check(r.base.value)&&this.variable.error('the variable "'+r.base.value+"\" can't be assigned with "+this.context+" because it has not been declared before"),Nt.call(this.context,"?")>=0?(e.isExistentialEquals=!0,(new E(new p(r),i,{type:"if"})).addElse(new t(i,this.value,"=")).compileToFragments(e)):(n=(new B(this.context.slice(0,-1),r,new t(i,this.value,"="))).compileToFragments(e),e.level<=C?n:this.wrapInBraces(n))},t.prototype.compileSplice=function(e){var t,n,r,i,s,o,u,a,f,l,c,h;return l=this.variable.properties.pop().range,r=l.from,u=l.to,n=l.exclusive,o=this.variable.compile(e),r?(c=this.cacheToCodeFragments(r.cache(e,k)),i=c[0],s=c[1]):i=s="0",u?r instanceof Z&&r.isSimpleNumber()&&u instanceof Z&&u.isSimpleNumber()?(u=u.compile(e)-s,n||(u+=1)):(u=u.compile(e,T)+" - "+s,n||(u+=" + 1")):u="9e9",h=this.value.cache(e,C),a=h[0],f=h[1],t=[].concat(this.makeCode("[].splice.apply("+o+", ["+i+", "+u+"].concat("),a,this.makeCode(")), "),f),e.level>A?this.wrapInBraces(t):t},t}(o),t.Code=l=function(e){function t(e,t,n){this.params=e||[],this.body=t||new u,this.bound=n==="boundfunc"}return Tt(t,e),t.prototype.children=["params","body"],t.prototype.isStatement=function(){return!!this.ctor},t.prototype.jumps=D,t.prototype.makeScope=function(e){return new W(e,this.body,this)},t.prototype.compileNode=function(e){var n,r,o,f,l,c,h,p,d,v,m,g,y,b,w,S,x,N,C,k,L,A,M,_,D,P,H,F,I,q,R,U,z;this.bound&&((F=e.scope.method)!=null?F.bound:void 0)&&(this.context=e.scope.method.context);if(this.bound&&!this.context)return this.context="_this",w=new t([new j(new O(this.context))],new u([this])),r=new a(w,[new O("this")]),r.updateLocationDataIfMissing(this.locationData),r.compileNode(e);e.scope=it(e,"classScope")||this.makeScope(e.scope),e.scope.shared=it(e,"sharedScope"),e.indent+=J,delete e.bare,delete e.isExistentialEquals,d=[],f=[],I=this.params;for(S=0,k=I.length;S<k;S++)p=I[S],e.scope.parameter(p.asReference(e));q=this.params;for(x=0,L=q.length;x<L;x++){p=q[x];if(!p.splat)continue;R=this.params;for(N=0,A=R.length;N<A;N++)h=R[N].name,h["this"]&&(h=h.properties[0].name),h.value&&e.scope.add(h.value,"var",!0);m=new s(new Z(new i(function(){var t,n,r,i;r=this.params,i=[];for(t=0,n=r.length;t<n;t++)h=r[t],i.push(h.asReference(e));return i}.call(this))),new Z(new O("arguments")));break}U=this.params;for(C=0,M=U.length;C<M;C++)p=U[C],p.isComplex()?(y=v=p.asReference(e),p.value&&(y=new B("?",v,p.value)),f.push(new s(new Z(p.name),y,"=",{param:!0}))):(v=p,p.value&&(c=new O(v.name.value+" == null"),y=new s(new Z(p.name),p.value,"="),f.push(new E(c,y)))),m||d.push(v);b=this.body.isEmpty(),m&&f.unshift(m),f.length&&(z=this.body.expressions).unshift.apply(z,f);for(l=P=0,_=d.length;P<_;l=++P)h=d[l],d[l]=h.compileToFragments(e),e.scope.parameter(at(d[l]));g=[],this.eachParamName(function(e,t){return Nt.call(g,e)>=0&&t.error("multiple parameters named '"+e+"'"),g.push(e)}),!b&&!this.noReturn&&this.body.makeReturn(),o="function",this.ctor&&(o+=" "+this.name),o+="(",n=[this.makeCode(o)];for(l=H=0,D=d.length;H<D;l=++H)h=d[l],l&&n.push(this.makeCode(", ")),n.push.apply(n,h);return n.push(this.makeCode(") {")),this.body.isEmpty()||(n=n.concat(this.makeCode("\n"),this.body.compileWithDeclarations(e),this.makeCode("\n"+this.tab))),n.push(this.makeCode("}")),this.ctor?[this.makeCode(this.tab)].concat(Ct.call(n)):this.front||e.level>=T?this.wrapInBraces(n):n},t.prototype.eachParamName=function(e){var t,n,r,i,s;i=this.params,s=[];for(n=0,r=i.length;n<r;n++)t=i[n],s.push(t.eachName(e));return s},t.prototype.traverseChildren=function(e,n){if(e)return t.__super__.traverseChildren.call(this,e,n)},t}(o),t.Param=j=function(e){function t(e,t,n){var r;this.name=e,this.value=t,this.splat=n,(r=e=this.name.unwrapAll().value,Nt.call(z,r)>=0)&&this.name.error('parameter name "'+e+'" is not allowed')}return Tt(t,e),t.prototype.children=["name","value"],t.prototype.compileToFragments=function(e){return this.name.compileToFragments(e,C)},t.prototype.asReference=function(e){var t;return this.reference?this.reference:(t=this.name,t["this"]?(t=t.properties[0].name,t.value.reserved&&(t=new O(e.scope.freeVariable(t.value)))):t.isComplex()&&(t=new O(e.scope.freeVariable("arg"))),t=new Z(t),this.splat&&(t=new V(t)),t.updateLocationDataIfMissing(this.locationData),this.reference=t)},t.prototype.isComplex=function(){return this.name.isComplex()},t.prototype.eachName=function(e,t){var n,r,i,o,u,a;t==null&&(t=this.name),n=function(t){var n;n=t.properties[0].name;if(!n.value.reserved)return e(n.value,n)};if(t instanceof O)return e(t.value,t);if(t instanceof Z)return n(t);a=t.objects;for(o=0,u=a.length;o<u;o++)i=a[o],i instanceof s?this.eachName(e,i.value.unwrap()):i instanceof V?(r=i.name.unwrap(),e(r.value,r)):i instanceof Z?i.isArray()||i.isObject()?this.eachName(e,i.base):i["this"]?n(i):e(i.base.value,i.base):i.error("illegal parameter "+i.compile())},t}(o),t.Splat=V=function(e){function t(e){this.name=e.compile?e:new O(e)}return Tt(t,e),t.prototype.children=["name"],t.prototype.isAssignable=tt,t.prototype.assigns=function(e){return this.name.assigns(e)},t.prototype.compileToFragments=function(e){return this.name.compileToFragments(e)},t.prototype.unwrap=function(){return this.name},t.compileSplattedArray=function(e,n,r){var i,s,o,u,a,f,l,c,h,p;l=-1;while((c=n[++l])&&!(c instanceof t))continue;if(l>=n.length)return[];if(n.length===1)return c=n[0],a=c.compileToFragments(e,C),r?a:[].concat(c.makeCode(""+wt("slice")+".call("),a,c.makeCode(")"));i=n.slice(l);for(f=h=0,p=i.length;h<p;f=++h)c=i[f],o=c.compileToFragments(e,C),i[f]=c instanceof t?[].concat(c.makeCode(""+wt("slice")+".call("),o,c.makeCode(")")):[].concat(c.makeCode("["),o,c.makeCode("]"));return l===0?(c=n[0],u=c.joinFragmentArrays(i.slice(1),", "),i[0].concat(c.makeCode(".concat("),u,c.makeCode(")"))):(s=function(){var t,r,i,s;i=n.slice(0,l),s=[];for(t=0,r=i.length;t<r;t++)c=i[t],s.push(c.compileToFragments(e,C));return s}(),s=n[0].joinFragmentArrays(s,", "),u=n[l].joinFragmentArrays(i,", "),[].concat(n[0].makeCode("["),s,n[l].makeCode("].concat("),u,ct(n).makeCode(")")))},t}(o),t.While=et=function(e){function t(e,t){this.condition=(t!=null?t.invert:void 0)?e.invert():e,this.guard=t!=null?t.guard:void 0}return Tt(t,e),t.prototype.children=["condition","guard","body"],t.prototype.isStatement=tt,t.prototype.makeReturn=function(e){return e?t.__super__.makeReturn.apply(this,arguments):(this.returns=!this.jumps({loop:!0}),this)},t.prototype.addBody=function(e){return this.body=e,this},t.prototype.jumps=function(){var e,t,n,r,i;e=this.body.expressions;if(!e.length)return!1;for(r=0,i=e.length;r<i;r++){n=e[r];if(t=n.jumps({loop:!0}))return t}return!1},t.prototype.compileNode=function(e){var t,n,r,i;return e.indent+=J,i="",n=this.body,n.isEmpty()?n=this.makeCode(""):(this.returns&&(n.makeReturn(r=e.scope.freeVariable("results")),i=""+this.tab+r+" = [];\n"),this.guard&&(n.expressions.length>1?n.expressions.unshift(new E((new F(this.guard)).invert(),new O("continue"))):this.guard&&(n=u.wrap([new E(this.guard,n)]))),n=[].concat(this.makeCode("\n"),n.compileToFragments(e,A),this.makeCode("\n"+this.tab))),t=[].concat(this.makeCode(i+this.tab+"while ("),this.condition.compileToFragments(e,L),this.makeCode(") {"),n,this.makeCode("}")),this.returns&&t.push(this.makeCode("\n"+this.tab+"return "+r+";")),t},t}(o),t.Op=B=function(e){function r(e,n,r,i){if(e==="in")return new S(n,r);if(e==="do")return this.generateDo(n);if(e==="new"){if(n instanceof a&&!n["do"]&&!n.isNew)return n.newInstance();if(n instanceof l&&n.bound||n["do"])n=new F(n)}return this.operator=t[e]||e,this.first=n,this.second=r,this.flip=!!i,this}var t,n;return Tt(r,e),t={"==":"===","!=":"!==",of:"in"},n={"!==":"===","===":"!=="},r.prototype.children=["first","second"],r.prototype.isSimpleNumber=D,r.prototype.isUnary=function(){return!this.second},r.prototype.isComplex=function(){var e;return!this.isUnary()||(e=this.operator)!=="+"&&e!=="-"||this.first.isComplex()},r.prototype.isChainable=function(){var e;return(e=this.operator)==="<"||e===">"||e===">="||e==="<="||e==="==="||e==="!=="},r.prototype.invert=function(){var e,t,i,s,o;if(this.isChainable()&&this.first.isChainable()){e=!0,t=this;while(t&&t.operator)e&&(e=t.operator in n),t=t.first;if(!e)return(new F(this)).invert();t=this;while(t&&t.operator)t.invert=!t.invert,t.operator=n[t.operator],t=t.first;return this}return(s=n[this.operator])?(this.operator=s,this.first.unwrap()instanceof r&&this.first.invert(),this):this.second?(new F(this)).invert():this.operator==="!"&&(i=this.first.unwrap())instanceof r&&((o=i.operator)==="!"||o==="in"||o==="instanceof")?i:new r("!",this)},r.prototype.unfoldSoak=function(e){var t;return((t=this.operator)==="++"||t==="--"||t==="delete")&&bt(e,this,"first")},r.prototype.generateDo=function(e){var t,n,r,i,o,u,f,c;i=[],n=e instanceof s&&(o=e.value.unwrap())instanceof l?o:e,c=n.params||[];for(u=0,f=c.length;u<f;u++)r=c[u],r.value?(i.push(r.value),delete r.value):i.push(r);return t=new a(e,i),t["do"]=!0,t},r.prototype.compileNode=function(e){var t,n,r,i;return n=this.isChainable()&&this.first.isChainable(),n||(this.first.front=this.front),this.operator==="delete"&&e.scope.check(this.first.unwrapAll().value)&&this.error("delete operand may not be argument or var"),((r=this.operator)==="--"||r==="++")&&(i=this.first.unwrapAll().value,Nt.call(z,i)>=0)&&this.error('cannot increment/decrement "'+this.first.unwrapAll().value+'"'),this.isUnary()?this.compileUnary(e):n?this.compileChain(e):this.operator==="?"?this.compileExistence(e):(t=[].concat(this.first.compileToFragments(e,k),this.makeCode(" "+this.operator+" "),this.second.compileToFragments(e,k)),e.level<=k?t:this.wrapInBraces(t))},r.prototype.compileChain=function(e){var t,n,r,i;return i=this.first.second.cache(e),this.first.second=i[0],r=i[1],n=this.first.compileToFragments(e,k),t=n.concat(this.makeCode(" "+(this.invert?"&&":"||")+" "),r.compileToFragments(e),this.makeCode(" "+this.operator+" "),this.second.compileToFragments(e,k)),this.wrapInBraces(t)},r.prototype.compileExistence=function(e){var t,n;return this.first.isComplex()?(n=new O(e.scope.freeVariable("ref")),t=new F(new s(n,this.first))):(t=this.first,n=t),(new E(new p(t),n,{type:"if"})).addElse(this.second).compileToFragments(e)},r.prototype.compileUnary=function(e){var t,n,i;n=[],t=this.operator,n.push([this.makeCode(t)]);if(t==="!"&&this.first instanceof p)return this.first.negated=!this.first.negated,this.first.compileToFragments(e);if(e.level>=T)return(new F(this)).compileToFragments(e);i=t==="+"||t==="-",(t==="new"||t==="typeof"||t==="delete"||i&&this.first instanceof r&&this.first.operator===t)&&n.push([this.makeCode(" ")]);if(i&&this.first instanceof r||t==="new"&&this.first.isStatement(e))this.first=new F(this.first);return n.push(this.first.compileToFragments(e,k)),this.flip&&n.reverse(),this.joinFragmentArrays(n,"")},r.prototype.toString=function(e){return r.__super__.toString.call(this,e,this.constructor.name+" "+this.operator)},r}(o),t.In=S=function(e){function t(e,t){this.object=e,this.array=t}return Tt(t,e),t.prototype.children=["object","array"],t.prototype.invert=_,t.prototype.compileNode=function(e){var t,n,r,i,s;if(this.array instanceof Z&&this.array.isArray()){s=this.array.base.objects;for(r=0,i=s.length;r<i;r++){n=s[r];if(n instanceof V){t=!0;break}continue}if(!t)return this.compileOrTest(e)}return this.compileLoopTest(e)},t.prototype.compileOrTest=function(e){var t,n,r,i,s,o,u,a,f,l,c,h;if(this.array.base.objects.length===0)return[this.makeCode(""+!!this.negated)];l=this.object.cache(e,k),o=l[0],s=l[1],c=this.negated?[" !== "," && "]:[" === "," || "],t=c[0],n=c[1],u=[],h=this.array.base.objects;for(r=a=0,f=h.length;a<f;r=++a)i=h[r],r&&u.push(this.makeCode(n)),u=u.concat(r?s:o,this.makeCode(t),i.compileToFragments(e,T));return e.level<k?u:this.wrapInBraces(u)},t.prototype.compileLoopTest=function(e){var t,n,r,i;return i=this.object.cache(e,C),r=i[0],n=i[1],t=[].concat(this.makeCode(wt("indexOf")+".call("),this.array.compileToFragments(e,C),this.makeCode(", "),n,this.makeCode(") "+(this.negated?"< 0":">= 0"))),at(r)===at(n)?t:(t=r.concat(this.makeCode(", "),t),e.level<C?t:this.wrapInBraces(t))},t.prototype.toString=function(e){return t.__super__.toString.call(this,e,this.constructor.name+(this.negated?"!":""))},t}(o),t.Try=G=function(e){function t(e,t,n,r){this.attempt=e,this.errorVariable=t,this.recovery=n,this.ensure=r}return Tt(t,e),t.prototype.children=["attempt","recovery","ensure"],t.prototype.isStatement=tt,t.prototype.jumps=function(e){var t;return this.attempt.jumps(e)||((t=this.recovery)!=null?t.jumps(e):void 0)},t.prototype.makeReturn=function(e){return this.attempt&&(this.attempt=this.attempt.makeReturn(e)),this.recovery&&(this.recovery=this.recovery.makeReturn(e)),this},t.prototype.compileNode=function(e){var t,n,r,i;return e.indent+=J,i=this.attempt.compileToFragments(e,A),t=this.recovery?(r=new O("_error"),this.errorVariable?this.recovery.unshift(new s(this.errorVariable,r)):void 0,[].concat(this.makeCode(" catch ("),r.compileToFragments(e),this.makeCode(") {\n"),this.recovery.compileToFragments(e,A),this.makeCode("\n"+this.tab+"}"))):!this.ensure&&!this.recovery?[this.makeCode(" catch (_error) {}")]:[],n=this.ensure?[].concat(this.makeCode(" finally {\n"),this.ensure.compileToFragments(e,A),this.makeCode("\n"+this.tab+"}")):[],[].concat(this.makeCode(""+this.tab+"try {\n"),i,this.makeCode("\n"+this.tab+"}"),t,n)},t}(o),t.Throw=Q=function(e){function t(e){this.expression=e}return Tt(t,e),t.prototype.children=["expression"],t.prototype.isStatement=tt,t.prototype.jumps=D,t.prototype.makeReturn=K,t.prototype.compileNode=function(e){return[].concat(this.makeCode(this.tab+"throw "),this.expression.compileToFragments(e),this.makeCode(";"))},t}(o),t.Existence=p=function(e){function t(e){this.expression=e}return Tt(t,e),t.prototype.children=["expression"],t.prototype.invert=_,t.prototype.compileNode=function(e){var t,n,r,i;return this.expression.front=this.front,r=this.expression.compile(e,k),g.test(r)&&!e.scope.check(r)?(i=this.negated?["===","||"]:["!==","&&"],t=i[0],n=i[1],r="typeof "+r+" "+t+' "undefined" '+n+" "+r+" "+t+" null"):r=""+r+" "+(this.negated?"==":"!=")+" null",[this.makeCode(e.level<=N?r:"("+r+")")]},t}(o),t.Parens=F=function(e){function t(e){this.body=e}return Tt(t,e),t.prototype.children=["body"],t.prototype.unwrap=function(){return this.body},t.prototype.isComplex=function(){return this.body.isComplex()},t.prototype.compileNode=function(e){var t,n,r;return n=this.body.unwrap(),n instanceof Z&&n.isAtomic()?(n.front=this.front,n.compileToFragments(e)):(r=n.compileToFragments(e,L),t=e.level<k&&(n instanceof B||n instanceof a||n instanceof v&&n.returns),t?r:this.wrapInBraces(r))},t}(o),t.For=v=function(e){function t(e,t){var n;this.source=t.source,this.guard=t.guard,this.step=t.step,this.name=t.name,this.index=t.index,this.body=u.wrap([e]),this.own=!!t.own,this.object=!!t.object,this.object&&(n=[this.index,this.name],this.name=n[0],this.index=n[1]),this.index instanceof Z&&this.index.error("index cannot be a pattern matching expression"),this.range=this.source instanceof Z&&this.source.base instanceof q&&!this.source.properties.length,this.pattern=this.name instanceof Z,this.range&&this.index&&this.index.error("indexes do not apply to range loops"),this.range&&this.pattern&&this.name.error("cannot pattern match over range loops"),this.own&&!this.object&&this.name.error("cannot use own with for-in"),this.returns=!1}return Tt(t,e),t.prototype.children=["body","source","guard","step"],t.prototype.compileNode=function(e){var t,n,r,i,o,a,f,l,c,h,p,d,v,m,y,b,w,S,x,T,N,k,L,M,_,D,H,B,j,I,q,U,z,W;return t=u.wrap([this.body]),S=(z=ct(t.expressions))!=null?z.jumps():void 0,S&&S instanceof R&&(this.returns=!1),H=this.range?this.source.base:this.source,D=e.scope,T=this.name&&this.name.compile(e,C),m=this.index&&this.index.compile(e,C),T&&!this.pattern&&D.find(T),m&&D.find(m),this.returns&&(_=D.freeVariable("results")),y=this.object&&m||D.freeVariable("i"),b=this.range&&T||m||y,w=b!==y?""+b+" = ":"",this.step&&!this.range&&(W=this.cacheToCodeFragments(this.step.cache(e,C)),B=W[0],I=W[1],j=I.match(P)),this.pattern&&(T=y),U="",p="",f="",d=this.tab+J,this.range?h=H.compileToFragments(pt(e,{index:y,name:T,step:this.step})):(q=this.source.compile(e,C),(T||this.own)&&!g.test(q)&&(f+=""+this.tab+(k=D.freeVariable("ref"))+" = "+q+";\n",q=k),T&&!this.pattern&&(N=""+T+" = "+q+"["+b+"]"),this.object||(B!==I&&(f+=""+this.tab+B+";\n"),this.step&&j&&(c=vt(j[0])<0)||(x=D.freeVariable("len")),o=""+w+y+" = 0, "+x+" = "+q+".length",a=""+w+y+" = "+q+".length - 1",r=""+y+" < "+x,i=""+y+" >= 0",this.step?(j?c&&(r=i,o=a):(r=""+I+" > 0 ? "+r+" : "+i,o="("+I+" > 0 ? ("+o+") : "+a+")"),v=""+y+" += "+I):v=""+(b!==y?"++"+y:""+y+"++"),h=[this.makeCode(""+o+"; "+r+"; "+w+v)])),this.returns&&(L=""+this.tab+_+" = [];\n",M="\n"+this.tab+"return "+_+";",t.makeReturn(_)),this.guard&&(t.expressions.length>1?t.expressions.unshift(new E((new F(this.guard)).invert(),new O("continue"))):this.guard&&(t=u.wrap([new E(this.guard,t)]))),this.pattern&&t.expressions.unshift(new s(this.name,new O(""+q+"["+b+"]"))),l=[].concat(this.makeCode(f),this.pluckDirectCall(e,t)),N&&(U="\n"+d+N+";"),this.object&&(h=[this.makeCode(""+b+" in "+q)],this.own&&(p="\n"+d+"if (!"+wt("hasProp")+".call("+q+", "+b+")) continue;")),n=t.compileToFragments(pt(e,{indent:d}),A),n&&n.length>0&&(n=[].concat(this.makeCode("\n"),n,this.makeCode("\n"))),[].concat(l,this.makeCode(""+(L||"")+this.tab+"for ("),h,this.makeCode(") {"+p+U),n,this.makeCode(""+this.tab+"}"+(M||"")))},t.prototype.pluckDirectCall=function(e,t){var n,r,i,o,u,f,c,h,p,d,v,m,g,y,b,w;r=[],d=t.expressions;for(u=h=0,p=d.length;h<p;u=++h){i=d[u],i=i.unwrapAll();if(!(i instanceof a))continue;c=(v=i.variable)!=null?v.unwrapAll():void 0;if(!(c instanceof l||c instanceof Z&&((m=c.base)!=null?m.unwrapAll():void 0)instanceof l&&c.properties.length===1&&((g=(y=c.properties[0].name)!=null?y.value:void 0)==="call"||g==="apply")))continue;o=((b=c.base)!=null?b.unwrapAll():void 0)||c,f=new O(e.scope.freeVariable("fn")),n=new Z(f),c.base&&(w=[n,c],c.base=w[0],n=w[1]),t.expressions[u]=new a(n,i.args),r=r.concat(this.makeCode(this.tab),(new s(f,o)).compileToFragments(e,A),this.makeCode(";\n"))}return r},t}(et),t.Switch=$=function(e){function t(e,t,n){this.subject=e,this.cases=t,this.otherwise=n}return Tt(t,e),t.prototype.children=["subject","cases","otherwise"],t.prototype.isStatement=tt,t.prototype.jumps=function(e){var t,n,r,i,s,o,u,a;e==null&&(e={block:!0}),o=this.cases;for(i=0,s=o.length;i<s;i++){u=o[i],n=u[0],t=u[1];if(r=t.jumps(e))return r}return(a=this.otherwise)!=null?a.jumps(e):void 0},t.prototype.makeReturn=function(e){var t,n,r,i,s;i=this.cases;for(n=0,r=i.length;n<r;n++)t=i[n],t[1].makeReturn(e);return e&&(this.otherwise||(this.otherwise=new u([new O("void 0")]))),(s=this.otherwise)!=null&&s.makeReturn(e),this},t.prototype.compileNode=function(e){var t,n,r,i,s,o,u,a,f,l,c,h,p,d,v,m;a=e.indent+J,f=e.indent=a+J,o=[].concat(this.makeCode(this.tab+"switch ("),this.subject?this.subject.compileToFragments(e,L):this.makeCode("false"),this.makeCode(") {\n")),d=this.cases;for(u=l=0,h=d.length;l<h;u=++l){v=d[u],i=v[0],t=v[1],m=ut([i]);for(c=0,p=m.length;c<p;c++)r=m[c],this.subject||(r=r.invert()),o=o.concat(this.makeCode(a+"case "),r.compileToFragments(e,L),this.makeCode(":\n"));(n=t.compileToFragments(e,A)).length>0&&(o=o.concat(n,this.makeCode("\n")));if(u===this.cases.length-1&&!this.otherwise)break;s=this.lastNonComment(t.expressions);if(s instanceof R||s instanceof O&&s.jumps()&&s.value!=="debugger")continue;o.push(r.makeCode(f+"break;\n"))}return this.otherwise&&this.otherwise.expressions.length&&o.push.apply(o,[this.makeCode(a+"default:\n")].concat(Ct.call(this.otherwise.compileToFragments(e,A)),[this.makeCode("\n")])),o.push(this.makeCode(this.tab+"}")),o},t}(o),t.If=E=function(e){function t(e,t,n){this.body=t,n==null&&(n={}),this.condition=n.type==="unless"?e.invert():e,this.elseBody=null,this.isChain=!1,this.soak=n.soak}return Tt(t,e),t.prototype.children=["condition","body","elseBody"],t.prototype.bodyNode=function(){var e;return(e=this.body)!=null?e.unwrap():void 0},t.prototype.elseBodyNode=function(){var e;return(e=this.elseBody)!=null?e.unwrap():void 0},t.prototype.addElse=function(e){return this.isChain?this.elseBodyNode().addElse(e):(this.isChain=e instanceof t,this.elseBody=this.ensureBlock(e),this.elseBody.updateLocationDataIfMissing(e.locationData)),this},t.prototype.isStatement=function(e){var t;return(e!=null?e.level:void 0)===A||this.bodyNode().isStatement(e)||((t=this.elseBodyNode())!=null?t.isStatement(e):void 0)},t.prototype.jumps=function(e){var t;return this.body.jumps(e)||((t=this.elseBody)!=null?t.jumps(e):void 0)},t.prototype.compileNode=function(e){return this.isStatement(e)?this.compileStatement(e):this.compileExpression(e)},t.prototype.makeReturn=function(e){return e&&(this.elseBody||(this.elseBody=new u([new O("void 0")]))),this.body&&(this.body=new u([this.body.makeReturn(e)])),this.elseBody&&(this.elseBody=new u([this.elseBody.makeReturn(e)])),this},t.prototype.ensureBlock=function(e){return e instanceof u?e:new u([e])},t.prototype.compileStatement=function(e){var n,r,i,s,o,u,a;return i=it(e,"chainChild"),o=it(e,"isExistentialEquals"),o?(new t(this.condition.invert(),this.elseBodyNode(),{type:"if"})).compileToFragments(e):(a=e.indent+J,s=this.condition.compileToFragments(e,L),r=this.ensureBlock(this.body).compileToFragments(pt(e,{indent:a})),u=[].concat(this.makeCode("if ("),s,this.makeCode(") {\n"),r,this.makeCode("\n"+this.tab+"}")),i||u.unshift(this.makeCode(this.tab)),this.elseBody?(n=u.concat(this.makeCode(" else ")),this.isChain?(e.chainChild=!0,n=n.concat(this.elseBody.unwrap().compileToFragments(e,A))):n=n.concat(this.makeCode("{\n"),this.elseBody.compileToFragments(pt(e,{indent:a}),A),this.makeCode("\n"+this.tab+"}")),n):u)},t.prototype.compileExpression=function(e){var t,n,r,i;return r=this.condition.compileToFragments(e,N),n=this.bodyNode().compileToFragments(e,C),t=this.elseBodyNode()?this.elseBodyNode().compileToFragments(e,C):[this.makeCode("void 0")],i=r.concat(this.makeCode(" ? "),n,this.makeCode(" : "),t),e.level>=N?this.wrapInBraces(i):i},t.prototype.unfoldSoak=function(){return this.soak&&this},t}(o),Y={"extends":function(){return"function(child, parent) { for (var key in parent) { if ("+wt("hasProp")+".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }"},bind:function(){return"function(fn, me){ return function(){ return fn.apply(me, arguments); }; }"},indexOf:function(){return"[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }"},hasProp:function(){return"{}.hasOwnProperty"},slice:function(){return"[].slice"}},A=1,L=2,C=3,N=4,k=5,T=6,J="  ",y="[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*",g=RegExp("^"+y+"$"),U=/^[+-]?\d+$/,m=/^[+-]?0x[\da-f]+/i,P=/^[+-]?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)$/i,M=RegExp("^("+y+")(\\.prototype)?(?:\\.("+y+")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\])$"),w=/^['"]/,b=/^\//,wt=function(e){var t;return t="__"+e,W.root.assign(t,Y[e]()),t},dt=function(e,t){return e=e.replace(/\n/g,"$&"+t),e.replace(/\s+$/,"")},vt=function(e){return e==null?0:e.match(m)?parseInt(e,16):parseFloat(e)},ft=function(e){return e instanceof O&&e.value==="arguments"&&!e.asKey},lt=function(e){return e instanceof O&&e.value==="this"&&!e.asKey||e instanceof l&&e.bound||e instanceof a&&e.isSuper},bt=function(e,t,n){var r;if(!(r=t[n].unfoldSoak(e)))return;return t[n]=r.body,r.body=new Z(t),r}}),ace.define("ace/mode/coffee/coffee-script",["require","exports","module","ace/mode/coffee/lexer","ace/mode/coffee/parser","ace/mode/coffee/nodes"],function(e,t,n){var r=e("./lexer").Lexer,i=e("./parser"),s=new r;i.lexer={lex:function(){var e,t;return t=this.tokens[this.pos++],t?(e=t[0],this.yytext=t[1],this.yylloc=t[2],this.yylineno=this.yylloc.first_line):e="",e},setInput:function(e){return this.tokens=e,this.pos=0},upcomingInput:function(){return""}},i.yy=e("./nodes"),t.parse=function(e){return i.parse(s.tokenize(e))}}),ace.define("ace/mode/coffee_worker",["require","exports","module","ace/lib/oop","ace/worker/mirror","ace/mode/coffee/coffee-script"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../worker/mirror").Mirror,s=e("../mode/coffee/coffee-script");window.addEventListener=function(){};var o=t.Worker=function(e){i.call(this,e),this.setTimeout(250)};r.inherits(o,i),function(){this.onUpdate=function(){var e=this.doc.getValue();try{s.parse(e).compile()}catch(t){var n=t.location;n&&this.sender.emit("error",{row:n.first_line,column:n.first_column,endRow:n.last_line,endColumn:n.last_column,text:t.message,type:"error"});return}this.sender.emit("ok")}}.call(o.prototype)}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _="	\n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/worker-css.js b/dist/assets/js/vendor/ace-nc/worker-css.js
            new file mode 100644
            index 0000000000..80ea21e981
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/worker-css.js
            @@ -0,0 +1 @@
            +"no use strict";(function(e){if(typeof e.window!="undefined"&&e.document)return;e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console,e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){console.error("Worker "+(i?i.stack:e))},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(t,n){n||(n=t,t=null);if(!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;var i=n.split("/");if(!e.require.tlns)return console.log("unable to load "+n);i[0]=e.require.tlns[i[0]]||i[0];var s=i.join("/")+".js";return e.require.id=n,importScripts(s),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id),n.length||(n=["require","exports","module"]);if(t.indexOf("text!")===0)return;var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},e.initBaseUrls=function(t){require.tlns=t},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var i=r.data;if(i.command){if(!t[i.command])throw new Error("Unknown command:"+i.command);t[i.command].apply(t,i.args)}else if(i.init){initBaseUrls(i.tlns),require("ace/lib/es5-shim"),n=e.sender=initSender();var s=require(i.module)[i.classname];t=e.main=new s(n)}else i.event&&n&&n._signal(i.event,i.data)}})(this),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]=="object"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action==="insertText")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action==="insertLines"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action==="removeText"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action=="removeLines"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[""]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},"\n"+t.join("\n")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._signal("change",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._signal("change",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._signal("change",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._signal("change",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this._insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define("ace/worker/mirror",["require","exports","module","ace/document","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../document").Document,i=e("../lib/lang"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=i.delayedCall(this.onUpdate.bind(this)),s=this;e.on("change",function(e){t.applyDeltas(e.data);if(s.$timeout)return n.schedule(s.$timeout);s.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(s.prototype)}),ace.define("ace/mode/css/csslint",["require","exports","module"],function(require,exports,module){function Reporter(e,t){this.messages=[],this.stats=[],this.lines=e,this.ruleset=t}var parserlib={};(function(){function e(){this._listeners={}}function t(e){this._input=e.replace(/\n\r?/g,"\n"),this._line=1,this._col=1,this._cursor=0}function n(e,t,n){this.col=n,this.line=t,this.message=e}function r(e,t,n,r){this.col=n,this.line=t,this.text=e,this.type=r}function i(e,n){this._reader=e?new t(e.toString()):null,this._token=null,this._tokenData=n,this._lt=[],this._ltIndex=0,this._ltIndexCache=[]}e.prototype={constructor:e,addListener:function(e,t){this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push(t)},fire:function(e){typeof e=="string"&&(e={type:e}),typeof e.target!="undefined"&&(e.target=this);if(typeof e.type=="undefined")throw new Error("Event object missing 'type' property.");if(this._listeners[e.type]){var t=this._listeners[e.type].concat();for(var n=0,r=t.length;n<r;n++)t[n].call(this,e)}},removeListener:function(e,t){if(this._listeners[e]){var n=this._listeners[e];for(var r=0,i=n.length;r<i;r++)if(n[r]===t){n.splice(r,1);break}}}},t.prototype={constructor:t,getCol:function(){return this._col},getLine:function(){return this._line},eof:function(){return this._cursor==this._input.length},peek:function(e){var t=null;return e=typeof e=="undefined"?1:e,this._cursor<this._input.length&&(t=this._input.charAt(this._cursor+e-1)),t},read:function(){var e=null;return this._cursor<this._input.length&&(this._input.charAt(this._cursor)=="\n"?(this._line++,this._col=1):this._col++,e=this._input.charAt(this._cursor++)),e},mark:function(){this._bookmark={cursor:this._cursor,line:this._line,col:this._col}},reset:function(){this._bookmark&&(this._cursor=this._bookmark.cursor,this._line=this._bookmark.line,this._col=this._bookmark.col,delete this._bookmark)},readTo:function(e){var t="",n;while(t.length<e.length||t.lastIndexOf(e)!=t.length-e.length){n=this.read();if(!n)throw new Error('Expected "'+e+'" at line '+this._line+", col "+this._col+".");t+=n}return t},readWhile:function(e){var t="",n=this.read();while(n!==null&&e(n))t+=n,n=this.read();return t},readMatch:function(e){var t=this._input.substring(this._cursor),n=null;return typeof e=="string"?t.indexOf(e)===0&&(n=this.readCount(e.length)):e instanceof RegExp&&e.test(t)&&(n=this.readCount(RegExp.lastMatch.length)),n},readCount:function(e){var t="";while(e--)t+=this.read();return t}},n.prototype=new Error,r.fromToken=function(e){return new r(e.value,e.startLine,e.startCol)},r.prototype={constructor:r,valueOf:function(){return this.toString()},toString:function(){return this.text}},i.createTokenData=function(e){var t=[],n={},r=e.concat([]),i=0,s=r.length+1;r.UNKNOWN=-1,r.unshift({name:"EOF"});for(;i<s;i++)t.push(r[i].name),r[r[i].name]=i,r[i].text&&(n[r[i].text]=i);return r.name=function(e){return t[e]},r.type=function(e){return n[e]},r},i.prototype={constructor:i,match:function(e,t){e instanceof Array||(e=[e]);var n=this.get(t),r=0,i=e.length;while(r<i)if(n==e[r++])return!0;return this.unget(),!1},mustMatch:function(e,t){var r;e instanceof Array||(e=[e]);if(!this.match.apply(this,arguments))throw r=this.LT(1),new n("Expected "+this._tokenData[e[0]].name+" at line "+r.startLine+", col "+r.startCol+".",r.startLine,r.startCol)},advance:function(e,t){while(this.LA(0)!==0&&!this.match(e,t))this.get();return this.LA(0)},get:function(e){var t=this._tokenData,n=this._reader,r,i=0,s=t.length,o=!1,u,a;if(this._lt.length&&this._ltIndex>=0&&this._ltIndex<this._lt.length){i++,this._token=this._lt[this._ltIndex++],a=t[this._token.type];while(a.channel!==undefined&&e!==a.channel&&this._ltIndex<this._lt.length)this._token=this._lt[this._ltIndex++],a=t[this._token.type],i++;if((a.channel===undefined||e===a.channel)&&this._ltIndex<=this._lt.length)return this._ltIndexCache.push(i),this._token.type}return u=this._getToken(),u.type>-1&&!t[u.type].hide&&(u.channel=t[u.type].channel,this._token=u,this._lt.push(u),this._ltIndexCache.push(this._lt.length-this._ltIndex+i),this._lt.length>5&&this._lt.shift(),this._ltIndexCache.length>5&&this._ltIndexCache.shift(),this._ltIndex=this._lt.length),a=t[u.type],a&&(a.hide||a.channel!==undefined&&e!==a.channel)?this.get(e):u.type},LA:function(e){var t=e,n;if(e>0){if(e>5)throw new Error("Too much lookahead.");while(t)n=this.get(),t--;while(t<e)this.unget(),t++}else if(e<0){if(!this._lt[this._ltIndex+e])throw new Error("Too much lookbehind.");n=this._lt[this._ltIndex+e].type}else n=this._token.type;return n},LT:function(e){return this.LA(e),this._lt[this._ltIndex+e-1]},peek:function(){return this.LA(1)},token:function(){return this._token},tokenName:function(e){return e<0||e>this._tokenData.length?"UNKNOWN_TOKEN":this._tokenData[e].name},tokenType:function(e){return this._tokenData[e]||-1},unget:function(){if(!this._ltIndexCache.length)throw new Error("Too much lookahead.");this._ltIndex-=this._ltIndexCache.pop(),this._token=this._lt[this._ltIndex-1]}},parserlib.util={StringReader:t,SyntaxError:n,SyntaxUnit:r,EventTarget:e,TokenStreamBase:i}})(),function(){function Combinator(e,t,n){SyntaxUnit.call(this,e,t,n,Parser.COMBINATOR_TYPE),this.type="unknown",/^\s+$/.test(e)?this.type="descendant":e==">"?this.type="child":e=="+"?this.type="adjacent-sibling":e=="~"&&(this.type="sibling")}function MediaFeature(e,t){SyntaxUnit.call(this,"("+e+(t!==null?":"+t:"")+")",e.startLine,e.startCol,Parser.MEDIA_FEATURE_TYPE),this.name=e,this.value=t}function MediaQuery(e,t,n,r,i){SyntaxUnit.call(this,(e?e+" ":"")+(t?t:"")+(t&&n.length>0?" and ":"")+n.join(" and "),r,i,Parser.MEDIA_QUERY_TYPE),this.modifier=e,this.mediaType=t,this.features=n}function Parser(e){EventTarget.call(this),this.options=e||{},this._tokenStream=null}function PropertyName(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.PROPERTY_NAME_TYPE),this.hack=t}function PropertyValue(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n,Parser.PROPERTY_VALUE_TYPE),this.parts=e}function PropertyValueIterator(e){this._i=0,this._parts=e.parts,this._marks=[],this.value=e}function PropertyValuePart(text,line,col){SyntaxUnit.call(this,text,line,col,Parser.PROPERTY_VALUE_PART_TYPE),this.type="unknown";var temp;if(/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)){this.type="dimension",this.value=+RegExp.$1,this.units=RegExp.$2;switch(this.units.toLowerCase()){case"em":case"rem":case"ex":case"px":case"cm":case"mm":case"in":case"pt":case"pc":case"ch":case"vh":case"vw":case"vm":this.type="length";break;case"deg":case"rad":case"grad":this.type="angle";break;case"ms":case"s":this.type="time";break;case"hz":case"khz":this.type="frequency";break;case"dpi":case"dpcm":this.type="resolution"}}else/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp.$1):/^([+\-]?\d+)$/i.test(text)?(this.type="integer",this.value=+RegExp.$1):/^([+\-]?[\d\.]+)$/i.test(text)?(this.type="number",this.value=+RegExp.$1):/^#([a-f0-9]{3,6})/i.test(text)?(this.type="color",temp=RegExp.$1,temp.length==3?(this.red=parseInt(temp.charAt(0)+temp.charAt(0),16),this.green=parseInt(temp.charAt(1)+temp.charAt(1),16),this.blue=parseInt(temp.charAt(2)+temp.charAt(2),16)):(this.red=parseInt(temp.substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring(4,6),16))):/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3):/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100):/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3,this.alpha=+RegExp.$4):/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100,this.alpha=+RegExp.$4):/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100,this.lightness=+RegExp.$3/100):/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100,this.lightness=+RegExp.$3/100,this.alpha=+RegExp.$4):/^url\(["']?([^\)"']+)["']?\)/i.test(text)?(this.type="uri",this.uri=RegExp.$1):/^([^\(]+)\(/i.test(text)?(this.type="function",this.name=RegExp.$1,this.value=text):/^["'][^"']*["']/.test(text)?(this.type="string",this.value=eval(text)):Colors[text.toLowerCase()]?(this.type="color",temp=Colors[text.toLowerCase()].substring(1),this.red=parseInt(temp.substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring(4,6),16)):/^[\,\/]$/.test(text)?(this.type="operator",this.value=text):/^[a-z\-\u0080-\uFFFF][a-z0-9\-\u0080-\uFFFF]*$/i.test(text)&&(this.type="identifier",this.value=text)}function Selector(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n,Parser.SELECTOR_TYPE),this.parts=e,this.specificity=Specificity.calculate(this)}function SelectorPart(e,t,n,r,i){SyntaxUnit.call(this,n,r,i,Parser.SELECTOR_PART_TYPE),this.elementName=e,this.modifiers=t}function SelectorSubPart(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.SELECTOR_SUB_PART_TYPE),this.type=t,this.args=[]}function Specificity(e,t,n,r){this.a=e,this.b=t,this.c=n,this.d=r}function isHexDigit(e){return e!==null&&h.test(e)}function isDigit(e){return e!==null&&/\d/.test(e)}function isWhitespace(e){return e!==null&&/\s/.test(e)}function isNewLine(e){return e!==null&&nl.test(e)}function isNameStart(e){return e!==null&&/[a-z_\u0080-\uFFFF\\]/i.test(e)}function isNameChar(e){return e!==null&&(isNameStart(e)||/[0-9\-\\]/.test(e))}function isIdentStart(e){return e!==null&&(isNameStart(e)||/\-\\/.test(e))}function mix(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function TokenStream(e){TokenStreamBase.call(this,e,Tokens)}function ValidationError(e,t,n){this.col=n,this.line=t,this.message=e}var EventTarget=parserlib.util.EventTarget,TokenStreamBase=parserlib.util.TokenStreamBase,StringReader=parserlib.util.StringReader,SyntaxError=parserlib.util.SyntaxError,SyntaxUnit=parserlib.util.SyntaxUnit,Colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",activeBorder:"Active window border.",activecaption:"Active window caption.",appworkspace:"Background color of multiple document interface.",background:"Desktop background.",buttonface:"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.",buttonhighlight:"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",buttonshadow:"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",buttontext:"Text on push buttons.",captiontext:"Text in caption, size box, and scrollbar arrow box.",graytext:"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.",greytext:"Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.",highlight:"Item(s) selected in a control.",highlighttext:"Text of item(s) selected in a control.",inactiveborder:"Inactive window border.",inactivecaption:"Inactive window caption.",inactivecaptiontext:"Color of text in an inactive caption.",infobackground:"Background color for tooltip controls.",infotext:"Text color for tooltip controls.",menu:"Menu background.",menutext:"Text in menus.",scrollbar:"Scroll bar gray area.",threeddarkshadow:"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedface:"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedhighlight:"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedlightshadow:"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",threedshadow:"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",window:"Window background.",windowframe:"Window frame.",windowtext:"Text in windows."};Combinator.prototype=new SyntaxUnit,Combinator.prototype.constructor=Combinator,MediaFeature.prototype=new SyntaxUnit,MediaFeature.prototype.constructor=MediaFeature,MediaQuery.prototype=new SyntaxUnit,MediaQuery.prototype.constructor=MediaQuery,Parser.DEFAULT_TYPE=0,Parser.COMBINATOR_TYPE=1,Parser.MEDIA_FEATURE_TYPE=2,Parser.MEDIA_QUERY_TYPE=3,Parser.PROPERTY_NAME_TYPE=4,Parser.PROPERTY_VALUE_TYPE=5,Parser.PROPERTY_VALUE_PART_TYPE=6,Parser.SELECTOR_TYPE=7,Parser.SELECTOR_PART_TYPE=8,Parser.SELECTOR_SUB_PART_TYPE=9,Parser.prototype=function(){var e=new EventTarget,t,n={constructor:Parser,DEFAULT_TYPE:0,COMBINATOR_TYPE:1,MEDIA_FEATURE_TYPE:2,MEDIA_QUERY_TYPE:3,PROPERTY_NAME_TYPE:4,PROPERTY_VALUE_TYPE:5,PROPERTY_VALUE_PART_TYPE:6,SELECTOR_TYPE:7,SELECTOR_PART_TYPE:8,SELECTOR_SUB_PART_TYPE:9,_stylesheet:function(){var e=this._tokenStream,t=null,n,r,i;this.fire("startstylesheet"),this._charset(),this._skipCruft();while(e.peek()==Tokens.IMPORT_SYM)this._import(),this._skipCruft();while(e.peek()==Tokens.NAMESPACE_SYM)this._namespace(),this._skipCruft();i=e.peek();while(i>Tokens.EOF){try{switch(i){case Tokens.MEDIA_SYM:this._media(),this._skipCruft();break;case Tokens.PAGE_SYM:this._page(),this._skipCruft();break;case Tokens.FONT_FACE_SYM:this._font_face(),this._skipCruft();break;case Tokens.KEYFRAMES_SYM:this._keyframes(),this._skipCruft();break;case Tokens.VIEWPORT_SYM:this._viewport(),this._skipCruft();break;case Tokens.UNKNOWN_SYM:e.get();if(!!this.options.strict)throw new SyntaxError("Unknown @ rule.",e.LT(0).startLine,e.LT(0).startCol);this.fire({type:"error",error:null,message:"Unknown @ rule: "+e.LT(0).value+".",line:e.LT(0).startLine,col:e.LT(0).startCol}),n=0;while(e.advance([Tokens.LBRACE,Tokens.RBRACE])==Tokens.LBRACE)n++;while(n)e.advance([Tokens.RBRACE]),n--;break;case Tokens.S:this._readWhitespace();break;default:if(!this._ruleset())switch(i){case Tokens.CHARSET_SYM:throw r=e.LT(1),this._charset(!1),new SyntaxError("@charset not allowed here.",r.startLine,r.startCol);case Tokens.IMPORT_SYM:throw r=e.LT(1),this._import(!1),new SyntaxError("@import not allowed here.",r.startLine,r.startCol);case Tokens.NAMESPACE_SYM:throw r=e.LT(1),this._namespace(!1),new SyntaxError("@namespace not allowed here.",r.startLine,r.startCol);default:e.get(),this._unexpectedToken(e.token())}}}catch(s){if(!(s instanceof SyntaxError&&!this.options.strict))throw s;this.fire({type:"error",error:s,message:s.message,line:s.line,col:s.col})}i=e.peek()}i!=Tokens.EOF&&this._unexpectedToken(e.token()),this.fire("endstylesheet")},_charset:function(e){var t=this._tokenStream,n,r,i,s;t.match(Tokens.CHARSET_SYM)&&(i=t.token().startLine,s=t.token().startCol,this._readWhitespace(),t.mustMatch(Tokens.STRING),r=t.token(),n=r.value,this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),e!==!1&&this.fire({type:"charset",charset:n,line:i,col:s}))},_import:function(e){var t=this._tokenStream,n,r,i,s=[];t.mustMatch(Tokens.IMPORT_SYM),i=t.token(),this._readWhitespace(),t.mustMatch([Tokens.STRING,Tokens.URI]),r=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this._readWhitespace(),s=this._media_query_list(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace(),e!==!1&&this.fire({type:"import",uri:r,media:s,line:i.startLine,col:i.startCol})},_namespace:function(e){var t=this._tokenStream,n,r,i,s;t.mustMatch(Tokens.NAMESPACE_SYM),n=t.token().startLine,r=t.token().startCol,this._readWhitespace(),t.match(Tokens.IDENT)&&(i=t.token().value,this._readWhitespace()),t.mustMatch([Tokens.STRING,Tokens.URI]),s=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace(),e!==!1&&this.fire({type:"namespace",prefix:i,uri:s,line:n,col:r})},_media:function(){var e=this._tokenStream,t,n,r;e.mustMatch(Tokens.MEDIA_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),r=this._media_query_list(),e.mustMatch(Tokens.LBRACE),this._readWhitespace(),this.fire({type:"startmedia",media:r,line:t,col:n});for(;;)if(e.peek()==Tokens.PAGE_SYM)this._page();else if(e.peek()==Tokens.FONT_FACE_SYM)this._font_face();else if(!this._ruleset())break;e.mustMatch(Tokens.RBRACE),this._readWhitespace(),this.fire({type:"endmedia",media:r,line:t,col:n})},_media_query_list:function(){var e=this._tokenStream,t=[];this._readWhitespace(),(e.peek()==Tokens.IDENT||e.peek()==Tokens.LPAREN)&&t.push(this._media_query());while(e.match(Tokens.COMMA))this._readWhitespace(),t.push(this._media_query());return t},_media_query:function(){var e=this._tokenStream,t=null,n=null,r=null,i=[];e.match(Tokens.IDENT)&&(n=e.token().value.toLowerCase(),n!="only"&&n!="not"?(e.unget(),n=null):r=e.token()),this._readWhitespace(),e.peek()==Tokens.IDENT?(t=this._media_type(),r===null&&(r=e.token())):e.peek()==Tokens.LPAREN&&(r===null&&(r=e.LT(1)),i.push(this._media_expression()));if(t===null&&i.length===0)return null;this._readWhitespace();while(e.match(Tokens.IDENT))e.token().value.toLowerCase()!="and"&&this._unexpectedToken(e.token()),this._readWhitespace(),i.push(this._media_expression());return new MediaQuery(n,t,i,r.startLine,r.startCol)},_media_type:function(){return this._media_feature()},_media_expression:function(){var e=this._tokenStream,t=null,n,r=null;return e.mustMatch(Tokens.LPAREN),t=this._media_feature(),this._readWhitespace(),e.match(Tokens.COLON)&&(this._readWhitespace(),n=e.LT(1),r=this._expression()),e.mustMatch(Tokens.RPAREN),this._readWhitespace(),new MediaFeature(t,r?new SyntaxUnit(r,n.startLine,n.startCol):null)},_media_feature:function(){var e=this._tokenStream;return e.mustMatch(Tokens.IDENT),SyntaxUnit.fromToken(e.token())},_page:function(){var e=this._tokenStream,t,n,r=null,i=null;e.mustMatch(Tokens.PAGE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),e.match(Tokens.IDENT)&&(r=e.token().value,r.toLowerCase()==="auto"&&this._unexpectedToken(e.token())),e.peek()==Tokens.COLON&&(i=this._pseudo_page()),this._readWhitespace(),this.fire({type:"startpage",id:r,pseudo:i,line:t,col:n}),this._readDeclarations(!0,!0),this.fire({type:"endpage",id:r,pseudo:i,line:t,col:n})},_margin:function(){var e=this._tokenStream,t,n,r=this._margin_sym();return r?(t=e.token().startLine,n=e.token().startCol,this.fire({type:"startpagemargin",margin:r,line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endpagemargin",margin:r,line:t,col:n}),!0):!1},_margin_sym:function(){var e=this._tokenStream;return e.match([Tokens.TOPLEFTCORNER_SYM,Tokens.TOPLEFT_SYM,Tokens.TOPCENTER_SYM,Tokens.TOPRIGHT_SYM,Tokens.TOPRIGHTCORNER_SYM,Tokens.BOTTOMLEFTCORNER_SYM,Tokens.BOTTOMLEFT_SYM,Tokens.BOTTOMCENTER_SYM,Tokens.BOTTOMRIGHT_SYM,Tokens.BOTTOMRIGHTCORNER_SYM,Tokens.LEFTTOP_SYM,Tokens.LEFTMIDDLE_SYM,Tokens.LEFTBOTTOM_SYM,Tokens.RIGHTTOP_SYM,Tokens.RIGHTMIDDLE_SYM,Tokens.RIGHTBOTTOM_SYM])?SyntaxUnit.fromToken(e.token()):null},_pseudo_page:function(){var e=this._tokenStream;return e.mustMatch(Tokens.COLON),e.mustMatch(Tokens.IDENT),e.token().value},_font_face:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.FONT_FACE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type:"startfontface",line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endfontface",line:t,col:n})},_viewport:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.VIEWPORT_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type:"startviewport",line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endviewport",line:t,col:n})},_operator:function(e){var t=this._tokenStream,n=null;if(t.match([Tokens.SLASH,Tokens.COMMA])||e&&t.match([Tokens.PLUS,Tokens.STAR,Tokens.MINUS]))n=t.token(),this._readWhitespace();return n?PropertyValuePart.fromToken(n):null},_combinator:function(){var e=this._tokenStream,t=null,n;return e.match([Tokens.PLUS,Tokens.GREATER,Tokens.TILDE])&&(n=e.token(),t=new Combinator(n.value,n.startLine,n.startCol),this._readWhitespace()),t},_unary_operator:function(){var e=this._tokenStream;return e.match([Tokens.MINUS,Tokens.PLUS])?e.token().value:null},_property:function(){var e=this._tokenStream,t=null,n=null,r,i,s,o;return e.peek()==Tokens.STAR&&this.options.starHack&&(e.get(),i=e.token(),n=i.value,s=i.startLine,o=i.startCol),e.match(Tokens.IDENT)&&(i=e.token(),r=i.value,r.charAt(0)=="_"&&this.options.underscoreHack&&(n="_",r=r.substring(1)),t=new PropertyName(r,n,s||i.startLine,o||i.startCol),this._readWhitespace()),t},_ruleset:function(){var e=this._tokenStream,t,n;try{n=this._selectors_group()}catch(r){if(r instanceof SyntaxError&&!this.options.strict){this.fire({type:"error",error:r,message:r.message,line:r.line,col:r.col}),t=e.advance([Tokens.RBRACE]);if(t!=Tokens.RBRACE)throw r;return!0}throw r}return n&&(this.fire({type:"startrule",selectors:n,line:n[0].line,col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endrule",selectors:n,line:n[0].line,col:n[0].col})),n},_selectors_group:function(){var e=this._tokenStream,t=[],n;n=this._selector();if(n!==null){t.push(n);while(e.match(Tokens.COMMA))this._readWhitespace(),n=this._selector(),n!==null?t.push(n):this._unexpectedToken(e.LT(1))}return t.length?t:null},_selector:function(){var e=this._tokenStream,t=[],n=null,r=null,i=null;n=this._simple_selector_sequence();if(n===null)return null;t.push(n);do{r=this._combinator();if(r!==null)t.push(r),n=this._simple_selector_sequence(),n===null?this._unexpectedToken(e.LT(1)):t.push(n);else{if(!this._readWhitespace())break;i=new Combinator(e.token().value,e.token().startLine,e.token().startCol),r=this._combinator(),n=this._simple_selector_sequence(),n===null?r!==null&&this._unexpectedToken(e.LT(1)):(r!==null?t.push(r):t.push(i),t.push(n))}}while(!0);return new Selector(t,t[0].line,t[0].col)},_simple_selector_sequence:function(){var e=this._tokenStream,t=null,n=[],r="",i=[function(){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo,this._negation],s=0,o=i.length,u=null,a=!1,f,l;f=e.LT(1).startLine,l=e.LT(1).startCol,t=this._type_selector(),t||(t=this._universal()),t!==null&&(r+=t);for(;;){if(e.peek()===Tokens.S)break;while(s<o&&u===null)u=i[s++].call(this);if(u===null){if(r==="")return null;break}s=0,n.push(u),r+=u.toString(),u=null}return r!==""?new SelectorPart(t,n,r,f,l):null},_type_selector:function(){var e=this._tokenStream,t=this._namespace_prefix(),n=this._element_name();return n?(t&&(n.text=t+n.text,n.col-=t.length),n):(t&&(e.unget(),t.length>1&&e.unget()),null)},_class:function(){var e=this._tokenStream,t;return e.match(Tokens.DOT)?(e.mustMatch(Tokens.IDENT),t=e.token(),new SelectorSubPart("."+t.value,"class",t.startLine,t.startCol-1)):null},_element_name:function(){var e=this._tokenStream,t;return e.match(Tokens.IDENT)?(t=e.token(),new SelectorSubPart(t.value,"elementName",t.startLine,t.startCol)):null},_namespace_prefix:function(){var e=this._tokenStream,t="";if(e.LA(1)===Tokens.PIPE||e.LA(2)===Tokens.PIPE)e.match([Tokens.IDENT,Tokens.STAR])&&(t+=e.token().value),e.mustMatch(Tokens.PIPE),t+="|";return t.length?t:null},_universal:function(){var e=this._tokenStream,t="",n;return n=this._namespace_prefix(),n&&(t+=n),e.match(Tokens.STAR)&&(t+="*"),t.length?t:null},_attrib:function(){var e=this._tokenStream,t=null,n,r;return e.match(Tokens.LBRACKET)?(r=e.token(),t=r.value,t+=this._readWhitespace(),n=this._namespace_prefix(),n&&(t+=n),e.mustMatch(Tokens.IDENT),t+=e.token().value,t+=this._readWhitespace(),e.match([Tokens.PREFIXMATCH,Tokens.SUFFIXMATCH,Tokens.SUBSTRINGMATCH,Tokens.EQUALS,Tokens.INCLUDES,Tokens.DASHMATCH])&&(t+=e.token().value,t+=this._readWhitespace(),e.mustMatch([Tokens.IDENT,Tokens.STRING]),t+=e.token().value,t+=this._readWhitespace()),e.mustMatch(Tokens.RBRACKET),new SelectorSubPart(t+"]","attribute",r.startLine,r.startCol)):null},_pseudo:function(){var e=this._tokenStream,t=null,n=":",r,i;return e.match(Tokens.COLON)&&(e.match(Tokens.COLON)&&(n+=":"),e.match(Tokens.IDENT)?(t=e.token().value,r=e.token().startLine,i=e.token().startCol-n.length):e.peek()==Tokens.FUNCTION&&(r=e.LT(1).startLine,i=e.LT(1).startCol-n.length,t=this._functional_pseudo()),t&&(t=new SelectorSubPart(n+t,"pseudo",r,i))),t},_functional_pseudo:function(){var e=this._tokenStream,t=null;return e.match(Tokens.FUNCTION)&&(t=e.token().value,t+=this._readWhitespace(),t+=this._expression(),e.mustMatch(Tokens.RPAREN),t+=")"),t},_expression:function(){var e=this._tokenStream,t="";while(e.match([Tokens.PLUS,Tokens.MINUS,Tokens.DIMENSION,Tokens.NUMBER,Tokens.STRING,Tokens.IDENT,Tokens.LENGTH,Tokens.FREQ,Tokens.ANGLE,Tokens.TIME,Tokens.RESOLUTION,Tokens.SLASH]))t+=e.token().value,t+=this._readWhitespace();return t.length?t:null},_negation:function(){var e=this._tokenStream,t,n,r="",i,s=null;return e.match(Tokens.NOT)&&(r=e.token().value,t=e.token().startLine,n=e.token().startCol,r+=this._readWhitespace(),i=this._negation_arg(),r+=i,r+=this._readWhitespace(),e.match(Tokens.RPAREN),r+=e.token().value,s=new SelectorSubPart(r,"not",t,n),s.args.push(i)),s},_negation_arg:function(){var e=this._tokenStream,t=[this._type_selector,this._universal,function(){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo],n=null,r=0,i=t.length,s,o,u,a;o=e.LT(1).startLine,u=e.LT(1).startCol;while(r<i&&n===null)n=t[r].call(this),r++;return n===null&&this._unexpectedToken(e.LT(1)),n.type=="elementName"?a=new SelectorPart(n,[],n.toString(),o,u):a=new SelectorPart(null,[n],n.toString(),o,u),a},_declaration:function(){var e=this._tokenStream,t=null,n=null,r=null,i=null,s=null,o="";t=this._property();if(t!==null){e.mustMatch(Tokens.COLON),this._readWhitespace(),n=this._expr(),(!n||n.length===0)&&this._unexpectedToken(e.LT(1)),r=this._prio(),o=t.toString();if(this.options.starHack&&t.hack=="*"||this.options.underscoreHack&&t.hack=="_")o=t.text;try{this._validateProperty(o,n)}catch(u){s=u}return this.fire({type:"property",property:t,value:n,important:r,line:t.line,col:t.col,invalid:s}),!0}return!1},_prio:function(){var e=this._tokenStream,t=e.match(Tokens.IMPORTANT_SYM);return this._readWhitespace(),t},_expr:function(e){var t=this._tokenStream,n=[],r=null,i=null;r=this._term();if(r!==null){n.push(r);do{i=this._operator(e),i&&n.push(i),r=this._term();if(r===null)break;n.push(r)}while(!0)}return n.length>0?new PropertyValue(n,n[0].line,n[0].col):null},_term:function(){var e=this._tokenStream,t=null,n=null,r,i,s;return t=this._unary_operator(),t!==null&&(i=e.token().startLine,s=e.token().startCol),e.peek()==Tokens.IE_FUNCTION&&this.options.ieFilters?(n=this._ie_function(),t===null&&(i=e.token().startLine,s=e.token().startCol)):e.match([Tokens.NUMBER,Tokens.PERCENTAGE,Tokens.LENGTH,Tokens.ANGLE,Tokens.TIME,Tokens.FREQ,Tokens.STRING,Tokens.IDENT,Tokens.URI,Tokens.UNICODE_RANGE])?(n=e.token().value,t===null&&(i=e.token().startLine,s=e.token().startCol),this._readWhitespace()):(r=this._hexcolor(),r===null?(t===null&&(i=e.LT(1).startLine,s=e.LT(1).startCol),n===null&&(e.LA(3)==Tokens.EQUALS&&this.options.ieFilters?n=this._ie_function():n=this._function())):(n=r.value,t===null&&(i=r.startLine,s=r.startCol))),n!==null?new PropertyValuePart(t!==null?t+n:n,i,s):null},_function:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match(Tokens.FUNCTION)){t=e.token().value,this._readWhitespace(),n=this._expr(!0),t+=n;if(this.options.ieFilters&&e.peek()==Tokens.EQUALS)do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_ie_function:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match([Tokens.IE_FUNCTION,Tokens.FUNCTION])){t=e.token().value;do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_hexcolor:function(){var e=this._tokenStream,t=null,n;if(e.match(Tokens.HASH)){t=e.token(),n=t.value;if(!/#[a-f0-9]{3,6}/i.test(n))throw new SyntaxError("Expected a hex color but found '"+n+"' at line "+t.startLine+", col "+t.startCol+".",t.startLine,t.startCol);this._readWhitespace()}return t},_keyframes:function(){var e=this._tokenStream,t,n,r,i="";e.mustMatch(Tokens.KEYFRAMES_SYM),t=e.token(),/^@\-([^\-]+)\-/.test(t.value)&&(i=RegExp.$1),this._readWhitespace(),r=this._keyframe_name(),this._readWhitespace(),e.mustMatch(Tokens.LBRACE),this.fire({type:"startkeyframes",name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),n=e.peek();while(n==Tokens.IDENT||n==Tokens.PERCENTAGE)this._keyframe_rule(),this._readWhitespace(),n=e.peek();this.fire({type:"endkeyframes",name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),e.mustMatch(Tokens.RBRACE)},_keyframe_name:function(){var e=this._tokenStream,t;return e.mustMatch([Tokens.IDENT,Tokens.STRING]),SyntaxUnit.fromToken(e.token())},_keyframe_rule:function(){var e=this._tokenStream,t,n=this._key_list();this.fire({type:"startkeyframerule",keys:n,line:n[0].line,col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endkeyframerule",keys:n,line:n[0].line,col:n[0].col})},_key_list:function(){var e=this._tokenStream,t,n,r=[];r.push(this._key()),this._readWhitespace();while(e.match(Tokens.COMMA))this._readWhitespace(),r.push(this._key()),this._readWhitespace();return r},_key:function(){var e=this._tokenStream,t;if(e.match(Tokens.PERCENTAGE))return SyntaxUnit.fromToken(e.token());if(e.match(Tokens.IDENT)){t=e.token();if(/from|to/i.test(t.value))return SyntaxUnit.fromToken(t);e.unget()}this._unexpectedToken(e.LT(1))},_skipCruft:function(){while(this._tokenStream.match([Tokens.S,Tokens.CDO,Tokens.CDC]));},_readDeclarations:function(e,t){var n=this._tokenStream,r;this._readWhitespace(),e&&n.mustMatch(Tokens.LBRACE),this._readWhitespace();try{for(;;){if(!(n.match(Tokens.SEMICOLON)||t&&this._margin())){if(!this._declaration())break;if(!n.match(Tokens.SEMICOLON))break}this._readWhitespace()}n.mustMatch(Tokens.RBRACE),this._readWhitespace()}catch(i){if(!(i instanceof SyntaxError&&!this.options.strict))throw i;this.fire({type:"error",error:i,message:i.message,line:i.line,col:i.col}),r=n.advance([Tokens.SEMICOLON,Tokens.RBRACE]);if(r==Tokens.SEMICOLON)this._readDeclarations(!1,t);else if(r!=Tokens.RBRACE)throw i}},_readWhitespace:function(){var e=this._tokenStream,t="";while(e.match(Tokens.S))t+=e.token().value;return t},_unexpectedToken:function(e){throw new SyntaxError("Unexpected token '"+e.value+"' at line "+e.startLine+", col "+e.startCol+".",e.startLine,e.startCol)},_verifyEnd:function(){this._tokenStream.LA(1)!=Tokens.EOF&&this._unexpectedToken(this._tokenStream.LT(1))},_validateProperty:function(e,t){Validation.validate(e,t)},parse:function(e){this._tokenStream=new TokenStream(e,Tokens),this._stylesheet()},parseStyleSheet:function(e){return this.parse(e)},parseMediaQuery:function(e){this._tokenStream=new TokenStream(e,Tokens);var t=this._media_query();return this._verifyEnd(),t},parsePropertyValue:function(e){this._tokenStream=new TokenStream(e,Tokens),this._readWhitespace();var t=this._expr();return this._readWhitespace(),this._verifyEnd(),t},parseRule:function(e){this._tokenStream=new TokenStream(e,Tokens),this._readWhitespace();var t=this._ruleset();return this._readWhitespace(),this._verifyEnd(),t},parseSelector:function(e){this._tokenStream=new TokenStream(e,Tokens),this._readWhitespace();var t=this._selector();return this._readWhitespace(),this._verifyEnd(),t},parseStyleAttribute:function(e){e+="}",this._tokenStream=new TokenStream(e,Tokens),this._readDeclarations()}};for(t in n)n.hasOwnProperty(t)&&(e[t]=n[t]);return e}();var Properties={"align-items":"flex-start | flex-end | center | baseline | stretch","align-content":"flex-start | flex-end | center | space-between | space-around | stretch","align-self":"auto | flex-start | flex-end | center | baseline | stretch","-webkit-align-items":"flex-start | flex-end | center | baseline | stretch","-webkit-align-content":"flex-start | flex-end | center | space-between | space-around | stretch","-webkit-align-self":"auto | flex-start | flex-end | center | baseline | stretch","alignment-adjust":"auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | <percentage> | <length>","alignment-baseline":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",animation:1,"animation-delay":{multi:"<time>",comma:!0},"animation-direction":{multi:"normal | alternate",comma:!0},"animation-duration":{multi:"<time>",comma:!0},"animation-iteration-count":{multi:"<number> | infinite",comma:!0},"animation-name":{multi:"none | <ident>",comma:!0},"animation-play-state":{multi:"running | paused",comma:!0},"animation-timing-function":1,"-moz-animation-delay":{multi:"<time>",comma:!0},"-moz-animation-direction":{multi:"normal | alternate",comma:!0},"-moz-animation-duration":{multi:"<time>",comma:!0},"-moz-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-moz-animation-name":{multi:"none | <ident>",comma:!0},"-moz-animation-play-state":{multi:"running | paused",comma:!0},"-ms-animation-delay":{multi:"<time>",comma:!0},"-ms-animation-direction":{multi:"normal | alternate",comma:!0},"-ms-animation-duration":{multi:"<time>",comma:!0},"-ms-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-ms-animation-name":{multi:"none | <ident>",comma:!0},"-ms-animation-play-state":{multi:"running | paused",comma:!0},"-webkit-animation-delay":{multi:"<time>",comma:!0},"-webkit-animation-direction":{multi:"normal | alternate",comma:!0},"-webkit-animation-duration":{multi:"<time>",comma:!0},"-webkit-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-webkit-animation-name":{multi:"none | <ident>",comma:!0},"-webkit-animation-play-state":{multi:"running | paused",comma:!0},"-o-animation-delay":{multi:"<time>",comma:!0},"-o-animation-direction":{multi:"normal | alternate",comma:!0},"-o-animation-duration":{multi:"<time>",comma:!0},"-o-animation-iteration-count":{multi:"<number> | infinite",comma:!0},"-o-animation-name":{multi:"none | <ident>",comma:!0},"-o-animation-play-state":{multi:"running | paused",comma:!0},appearance:"icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal | none | inherit",azimuth:function(e){var t="<angle> | leftwards | rightwards | inherit",n="left-side | far-left | left | center-left | center | center-right | right | far-right | right-side",r=!1,i=!1,s;ValidationTypes.isAny(e,t)||(ValidationTypes.isAny(e,"behind")&&(r=!0,i=!0),ValidationTypes.isAny(e,n)&&(i=!0,r||ValidationTypes.isAny(e,"behind")));if(e.hasNext())throw s=e.next(),i?new ValidationError("Expected end of value but found '"+s+"'.",s.line,s.col):new ValidationError("Expected (<'azimuth'>) but found '"+s+"'.",s.line,s.col)},"backface-visibility":"visible | hidden",background:1,"background-attachment":{multi:"<attachment>",comma:!0},"background-clip":{multi:"<box>",comma:!0},"background-color":"<color> | inherit","background-image":{multi:"<bg-image>",comma:!0},"background-origin":{multi:"<box>",comma:!0},"background-position":{multi:"<bg-position>",comma:!0},"background-repeat":{multi:"<repeat-style>"},"background-size":{multi:"<bg-size>",comma:!0},"baseline-shift":"baseline | sub | super | <percentage> | <length>",behavior:1,binding:1,bleed:"<length>","bookmark-label":"<content> | <attr> | <string>","bookmark-level":"none | <integer>","bookmark-state":"open | closed","bookmark-target":"none | <uri> | <attr>",border:"<border-width> || <border-style> || <color>","border-bottom":"<border-width> || <border-style> || <color>","border-bottom-color":"<color> | inherit","border-bottom-left-radius":"<x-one-radius>","border-bottom-right-radius":"<x-one-radius>","border-bottom-style":"<border-style>","border-bottom-width":"<border-width>","border-collapse":"collapse | separate | inherit","border-color":{multi:"<color> | inherit",max:4},"border-image":1,"border-image-outset":{multi:"<length> | <number>",max:4},"border-image-repeat":{multi:"stretch | repeat | round",max:2},"border-image-slice":function(e){var t=!1,n="<number> | <percentage>",r=!1,i=0,s=4,o;ValidationTypes.isAny(e,"fill")&&(r=!0,t=!0);while(e.hasNext()&&i<s){t=ValidationTypes.isAny(e,n);if(!t)break;i++}r?t=!0:ValidationTypes.isAny(e,"fill");if(e.hasNext())throw o=e.next(),t?new ValidationError("Expected end of value but found '"+o+"'.",o.line,o.col):new ValidationError("Expected ([<number> | <percentage>]{1,4} && fill?) but found '"+o+"'.",o.line,o.col)},"border-image-source":"<image> | none","border-image-width":{multi:"<length> | <percentage> | <number> | auto",max:4},"border-left":"<border-width> || <border-style> || <color>","border-left-color":"<color> | inherit","border-left-style":"<border-style>","border-left-width":"<border-width>","border-radius":function(e){var t=!1,n="<length> | <percentage> | inherit",r=!1,i=!1,s=0,o=8,u;while(e.hasNext()&&s<o){t=ValidationTypes.isAny(e,n);if(!t){if(!(e.peek()=="/"&&s>0&&!r))break;r=!0,o=s+5,e.next()}s++}if(e.hasNext())throw u=e.next(),t?new ValidationError("Expected end of value but found '"+u+"'.",u.line,u.col):new ValidationError("Expected (<'border-radius'>) but found '"+u+"'.",u.line,u.col)},"border-right":"<border-width> || <border-style> || <color>","border-right-color":"<color> | inherit","border-right-style":"<border-style>","border-right-width":"<border-width>","border-spacing":{multi:"<length> | inherit",max:2},"border-style":{multi:"<border-style>",max:4},"border-top":"<border-width> || <border-style> || <color>","border-top-color":"<color> | inherit","border-top-left-radius":"<x-one-radius>","border-top-right-radius":"<x-one-radius>","border-top-style":"<border-style>","border-top-width":"<border-width>","border-width":{multi:"<border-width>",max:4},bottom:"<margin-width> | inherit","-moz-box-align":"start | end | center | baseline | stretch","-moz-box-decoration-break":"slice |clone","-moz-box-direction":"normal | reverse | inherit","-moz-box-flex":"<number>","-moz-box-flex-group":"<integer>","-moz-box-lines":"single | multiple","-moz-box-ordinal-group":"<integer>","-moz-box-orient":"horizontal | vertical | inline-axis | block-axis | inherit","-moz-box-pack":"start | end | center | justify","-webkit-box-align":"start | end | center | baseline | stretch","-webkit-box-decoration-break":"slice |clone","-webkit-box-direction":"normal | reverse | inherit","-webkit-box-flex":"<number>","-webkit-box-flex-group":"<integer>","-webkit-box-lines":"single | multiple","-webkit-box-ordinal-group":"<integer>","-webkit-box-orient":"horizontal | vertical | inline-axis | block-axis | inherit","-webkit-box-pack":"start | end | center | justify","box-shadow":function(e){var t=!1,n;if(!ValidationTypes.isAny(e,"none"))Validation.multiProperty("<shadow>",e,!0,Infinity);else if(e.hasNext())throw n=e.next(),new ValidationError("Expected end of value but found '"+n+"'.",n.line,n.col)},"box-sizing":"content-box | border-box | inherit","break-after":"auto | always | avoid | left | right | page | column | avoid-page | avoid-column","break-before":"auto | always | avoid | left | right | page | column | avoid-page | avoid-column","break-inside":"auto | avoid | avoid-page | avoid-column","caption-side":"top | bottom | inherit",clear:"none | right | left | both | inherit",clip:1,color:"<color> | inherit","color-profile":1,"column-count":"<integer> | auto","column-fill":"auto | balance","column-gap":"<length> | normal","column-rule":"<border-width> || <border-style> || <color>","column-rule-color":"<color>","column-rule-style":"<border-style>","column-rule-width":"<border-width>","column-span":"none | all","column-width":"<length> | auto",columns:1,content:1,"counter-increment":1,"counter-reset":1,crop:"<shape> | auto",cue:"cue-after | cue-before | inherit","cue-after":1,"cue-before":1,cursor:1,direction:"ltr | rtl | inherit",display:"inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | grid | inline-grid | none | inherit | -moz-box | -moz-inline-block | -moz-inline-box | -moz-inline-grid | -moz-inline-stack | -moz-inline-table | -moz-grid | -moz-grid-group | -moz-grid-line | -moz-groupbox | -moz-deck | -moz-popup | -moz-stack | -moz-marker | -webkit-box | -webkit-inline-box | -ms-flexbox | -ms-inline-flexbox | flex | -webkit-flex | inline-flex | -webkit-inline-flex","dominant-baseline":1,"drop-initial-after-adjust":"central | middle | after-edge | text-after-edge | ideographic | alphabetic | mathematical | <percentage> | <length>","drop-initial-after-align":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical","drop-initial-before-adjust":"before-edge | text-before-edge | central | middle | hanging | mathematical | <percentage> | <length>","drop-initial-before-align":"caps-height | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical","drop-initial-size":"auto | line | <length> | <percentage>","drop-initial-value":"initial | <integer>",elevation:"<angle> | below | level | above | higher | lower | inherit","empty-cells":"show | hide | inherit",filter:1,fit:"fill | hidden | meet | slice","fit-position":1,flex:"none | [ <flex-grow> <flex-shrink>? || <flex-basis>","flex-basis":"<width>","flex-direction":"row | row-reverse | column | column-reverse","flex-flow":"<flex-direction> || <flex-wrap>","flex-grow":"<number>","flex-shrink":"<number>","flex-wrap":"nowrap | wrap | wrap-reverse","-webkit-flex":"none | [ <flex-grow> <flex-shrink>? || <flex-basis>","-webkit-flex-basis":"<width>","-webkit-flex-direction":"row | row-reverse | column | column-reverse","-webkit-flex-flow":"<flex-direction> || <flex-wrap>","-webkit-flex-grow":"<number>","-webkit-flex-shrink":"<number>","-webkit-flex-wrap":"nowrap | wrap | wrap-reverse","-ms-flex":"[[ <number> <number>? ] || [ <length> || <percentage> || auto ] ] | none","-ms-flex-align":"start | end | center | stretch | baseline","-ms-flex-direction":"row | column | row-reverse | column-reverse | inherit","-ms-flex-order":"<number>","-ms-flex-pack":"start | end | center | justify","-ms-flex-wrap":"nowrap | wrap | wrap-reverse","float":"left | right | none | inherit","float-offset":1,font:1,"font-family":1,"font-size":"<absolute-size> | <relative-size> | <length> | <percentage> | inherit","font-size-adjust":"<number> | none | inherit","font-stretch":"normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | inherit","font-style":"normal | italic | oblique | inherit","font-variant":"normal | small-caps | inherit","font-weight":"normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit","grid-cell-stacking":"columns | rows | layer","grid-column":1,"grid-columns":1,"grid-column-align":"start | end | center | stretch","grid-column-sizing":1,"grid-column-span":"<integer>","grid-flow":"none | rows | columns","grid-layer":"<integer>","grid-row":1,"grid-rows":1,"grid-row-align":"start | end | center | stretch","grid-row-span":"<integer>","grid-row-sizing":1,"hanging-punctuation":1,height:"<margin-width> | inherit","hyphenate-after":"<integer> | auto","hyphenate-before":"<integer> | auto","hyphenate-character":"<string> | auto","hyphenate-lines":"no-limit | <integer>","hyphenate-resource":1,hyphens:"none | manual | auto",icon:1,"image-orientation":"angle | auto","image-rendering":1,"image-resolution":1,"inline-box-align":"initial | last | <integer>","justify-content":"flex-start | flex-end | center | space-between | space-around","-webkit-justify-content":"flex-start | flex-end | center | space-between | space-around",left:"<margin-width> | inherit","letter-spacing":"<length> | normal | inherit","line-height":"<number> | <length> | <percentage> | normal | inherit","line-break":"auto | loose | normal | strict","line-stacking":1,"line-stacking-ruby":"exclude-ruby | include-ruby","line-stacking-shift":"consider-shifts | disregard-shifts","line-stacking-strategy":"inline-line-height | block-line-height | max-height | grid-height","list-style":1,"list-style-image":"<uri> | none | inherit","list-style-position":"inside | outside | inherit","list-style-type":"disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none | inherit",margin:{multi:"<margin-width> | inherit",max:4},"margin-bottom":"<margin-width> | inherit","margin-left":"<margin-width> | inherit","margin-right":"<margin-width> | inherit","margin-top":"<margin-width> | inherit",mark:1,"mark-after":1,"mark-before":1,marks:1,"marquee-direction":1,"marquee-play-count":1,"marquee-speed":1,"marquee-style":1,"max-height":"<length> | <percentage> | none | inherit","max-width":"<length> | <percentage> | none | inherit","min-height":"<length> | <percentage> | inherit","min-width":"<length> | <percentage> | inherit","move-to":1,"nav-down":1,"nav-index":1,"nav-left":1,"nav-right":1,"nav-up":1,opacity:"<number> | inherit",order:"<integer>","-webkit-order":"<integer>",orphans:"<integer> | inherit",outline:1,"outline-color":"<color> | invert | inherit","outline-offset":1,"outline-style":"<border-style> | inherit","outline-width":"<border-width> | inherit",overflow:"visible | hidden | scroll | auto | inherit","overflow-style":1,"overflow-wrap":"normal | break-word","overflow-x":1,"overflow-y":1,padding:{multi:"<padding-width> | inherit",max:4},"padding-bottom":"<padding-width> | inherit","padding-left":"<padding-width> | inherit","padding-right":"<padding-width> | inherit","padding-top":"<padding-width> | inherit",page:1,"page-break-after":"auto | always | avoid | left | right | inherit","page-break-before":"auto | always | avoid | left | right | inherit","page-break-inside":"auto | avoid | inherit","page-policy":1,pause:1,"pause-after":1,"pause-before":1,perspective:1,"perspective-origin":1,phonemes:1,pitch:1,"pitch-range":1,"play-during":1,"pointer-events":"auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit",position:"static | relative | absolute | fixed | inherit","presentation-level":1,"punctuation-trim":1,quotes:1,"rendering-intent":1,resize:1,rest:1,"rest-after":1,"rest-before":1,richness:1,right:"<margin-width> | inherit",rotation:1,"rotation-point":1,"ruby-align":1,"ruby-overhang":1,"ruby-position":1,"ruby-span":1,size:1,speak:"normal | none | spell-out | inherit","speak-header":"once | always | inherit","speak-numeral":"digits | continuous | inherit","speak-punctuation":"code | none | inherit","speech-rate":1,src:1,stress:1,"string-set":1,"table-layout":"auto | fixed | inherit","tab-size":"<integer> | <length>",target:1,"target-name":1,"target-new":1,"target-position":1,"text-align":"left | right | center | justify | inherit","text-align-last":1,"text-decoration":1,"text-emphasis":1,"text-height":1,"text-indent":"<length> | <percentage> | inherit","text-justify":"auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida","text-outline":1,"text-overflow":1,"text-rendering":"auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit","text-shadow":1,"text-transform":"capitalize | uppercase | lowercase | none | inherit","text-wrap":"normal | none | avoid",top:"<margin-width> | inherit","-ms-touch-action":"auto | none | pan-x | pan-y","touch-action":"auto | none | pan-x | pan-y",transform:1,"transform-origin":1,"transform-style":1,transition:1,"transition-delay":1,"transition-duration":1,"transition-property":1,"transition-timing-function":1,"unicode-bidi":"normal | embed | isolate | bidi-override | isolate-override | plaintext | inherit","user-modify":"read-only | read-write | write-only | inherit","user-select":"none | text | toggle | element | elements | all | inherit","vertical-align":"auto | use-script | baseline | sub | super | top | text-top | central | middle | bottom | text-bottom | <percentage> | <length>",visibility:"visible | hidden | collapse | inherit","voice-balance":1,"voice-duration":1,"voice-family":1,"voice-pitch":1,"voice-pitch-range":1,"voice-rate":1,"voice-stress":1,"voice-volume":1,volume:1,"white-space":"normal | pre | nowrap | pre-wrap | pre-line | inherit | -pre-wrap | -o-pre-wrap | -moz-pre-wrap | -hp-pre-wrap","white-space-collapse":1,widows:"<integer> | inherit",width:"<length> | <percentage> | auto | inherit","word-break":"normal | keep-all | break-all","word-spacing":"<length> | normal | inherit","word-wrap":"normal | break-word","writing-mode":"horizontal-tb | vertical-rl | vertical-lr | lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb | inherit","z-index":"<integer> | auto | inherit",zoom:"<number> | <percentage> | normal"};PropertyName.prototype=new SyntaxUnit,PropertyName.prototype.constructor=PropertyName,PropertyName.prototype.toString=function(){return(this.hack?this.hack:"")+this.text},PropertyValue.prototype=new SyntaxUnit,PropertyValue.prototype.constructor=PropertyValue,PropertyValueIterator.prototype.count=function(){return this._parts.length},PropertyValueIterator.prototype.isFirst=function(){return this._i===0},PropertyValueIterator.prototype.hasNext=function(){return this._i<this._parts.length},PropertyValueIterator.prototype.mark=function(){this._marks.push(this._i)},PropertyValueIterator.prototype.peek=function(e){return this.hasNext()?this._parts[this._i+(e||0)]:null},PropertyValueIterator.prototype.next=function(){return this.hasNext()?this._parts[this._i++]:null},PropertyValueIterator.prototype.previous=function(){return this._i>0?this._parts[--this._i]:null},PropertyValueIterator.prototype.restore=function(){this._marks.length&&(this._i=this._marks.pop())},PropertyValuePart.prototype=new SyntaxUnit,PropertyValuePart.prototype.constructor=PropertyValuePart,PropertyValuePart.fromToken=function(e){return new PropertyValuePart(e.value,e.startLine,e.startCol)};var Pseudos={":first-letter":1,":first-line":1,":before":1,":after":1};Pseudos.ELEMENT=1,Pseudos.CLASS=2,Pseudos.isElement=function(e){return e.indexOf("::")===0||Pseudos[e.toLowerCase()]==Pseudos.ELEMENT},Selector.prototype=new SyntaxUnit,Selector.prototype.constructor=Selector,SelectorPart.prototype=new SyntaxUnit,SelectorPart.prototype.constructor=SelectorPart,SelectorSubPart.prototype=new SyntaxUnit,SelectorSubPart.prototype.constructor=SelectorSubPart,Specificity.prototype={constructor:Specificity,compare:function(e){var t=["a","b","c","d"],n,r;for(n=0,r=t.length;n<r;n++){if(this[t[n]]<e[t[n]])return-1;if(this[t[n]]>e[t[n]])return 1}return 0},valueOf:function(){return this.a*1e3+this.b*100+this.c*10+this.d},toString:function(){return this.a+","+this.b+","+this.c+","+this.d}},Specificity.calculate=function(e){function u(e){var t,n,r,a,f=e.elementName?e.elementName.text:"",l;f&&f.charAt(f.length-1)!="*"&&o++;for(t=0,r=e.modifiers.length;t<r;t++){l=e.modifiers[t];switch(l.type){case"class":case"attribute":s++;break;case"id":i++;break;case"pseudo":Pseudos.isElement(l.text)?o++:s++;break;case"not":for(n=0,a=l.args.length;n<a;n++)u(l.args[n])}}}var t,n,r,i=0,s=0,o=0;for(t=0,n=e.parts.length;t<n;t++)r=e.parts[t],r instanceof SelectorPart&&u(r);return new Specificity(0,i,s,o)};var h=/^[0-9a-fA-F]$/,nonascii=/^[\u0080-\uFFFF]$/,nl=/\n|\r\n|\r|\f/;TokenStream.prototype=mix(new TokenStreamBase,{_getToken:function(e){var t,n=this._reader,r=null,i=n.getLine(),s=n.getCol();t=n.read();while(t){switch(t){case"/":n.peek()=="*"?r=this.commentToken(t,i,s):r=this.charToken(t,i,s);break;case"|":case"~":case"^":case"$":case"*":n.peek()=="="?r=this.comparisonToken(t,i,s):r=this.charToken(t,i,s);break;case'"':case"'":r=this.stringToken(t,i,s);break;case"#":isNameChar(n.peek())?r=this.hashToken(t,i,s):r=this.charToken(t,i,s);break;case".":isDigit(n.peek())?r=this.numberToken(t,i,s):r=this.charToken(t,i,s);break;case"-":n.peek()=="-"?r=this.htmlCommentEndToken(t,i,s):isNameStart(n.peek())?r=this.identOrFunctionToken(t,i,s):r=this.charToken(t,i,s);break;case"!":r=this.importantToken(t,i,s);break;case"@":r=this.atRuleToken(t,i,s);break;case":":r=this.notToken(t,i,s);break;case"<":r=this.htmlCommentStartToken(t,i,s);break;case"U":case"u":if(n.peek()=="+"){r=this.unicodeRangeToken(t,i,s);break};default:isDigit(t)?r=this.numberToken(t,i,s):isWhitespace(t)?r=this.whitespaceToken(t,i,s):isIdentStart(t)?r=this.identOrFunctionToken(t,i,s):r=this.charToken(t,i,s)}break}return!r&&t===null&&(r=this.createToken(Tokens.EOF,null,i,s)),r},createToken:function(e,t,n,r,i){var s=this._reader;return i=i||{},{value:t,type:e,channel:i.channel,hide:i.hide||!1,startLine:n,startCol:r,endLine:s.getLine(),endCol:s.getCol()}},atRuleToken:function(e,t,n){var r=e,i=this._reader,s=Tokens.CHAR,o=!1,u,a;i.mark(),u=this.readName(),r=e+u,s=Tokens.type(r.toLowerCase());if(s==Tokens.CHAR||s==Tokens.UNKNOWN)r.length>1?s=Tokens.UNKNOWN_SYM:(s=Tokens.CHAR,r=e,i.reset());return this.createToken(s,r,t,n)},charToken:function(e,t,n){var r=Tokens.type(e);return r==-1&&(r=Tokens.CHAR),this.createToken(r,e,t,n)},commentToken:function(e,t,n){var r=this._reader,i=this.readComment(e);return this.createToken(Tokens.COMMENT,i,t,n)},comparisonToken:function(e,t,n){var r=this._reader,i=e+r.read(),s=Tokens.type(i)||Tokens.CHAR;return this.createToken(s,i,t,n)},hashToken:function(e,t,n){var r=this._reader,i=this.readName(e);return this.createToken(Tokens.HASH,i,t,n)},htmlCommentStartToken:function(e,t,n){var r=this._reader,i=e;return r.mark(),i+=r.readCount(3),i=="<!--"?this.createToken(Tokens.CDO,i,t,n):(r.reset(),this.charToken(e,t,n))},htmlCommentEndToken:function(e,t,n){var r=this._reader,i=e;return r.mark(),i+=r.readCount(2),i=="-->"?this.createToken(Tokens.CDC,i,t,n):(r.reset(),this.charToken(e,t,n))},identOrFunctionToken:function(e,t,n){var r=this._reader,i=this.readName(e),s=Tokens.IDENT;return r.peek()=="("?(i+=r.read(),i.toLowerCase()=="url("?(s=Tokens.URI,i=this.readURI(i),i.toLowerCase()=="url("&&(s=Tokens.FUNCTION)):s=Tokens.FUNCTION):r.peek()==":"&&i.toLowerCase()=="progid"&&(i+=r.readTo("("),s=Tokens.IE_FUNCTION),this.createToken(s,i,t,n)},importantToken:function(e,t,n){var r=this._reader,i=e,s=Tokens.CHAR,o,u;r.mark(),u=r.read();while(u){if(u=="/"){if(r.peek()!="*")break;o=this.readComment(u);if(o==="")break}else{if(!isWhitespace(u)){if(/i/i.test(u)){o=r.readCount(8),/mportant/i.test(o)&&(i+=u+o,s=Tokens.IMPORTANT_SYM);break}break}i+=u+this.readWhitespace()}u=r.read()}return s==Tokens.CHAR?(r.reset(),this.charToken(e,t,n)):this.createToken(s,i,t,n)},notToken:function(e,t,n){var r=this._reader,i=e;return r.mark(),i+=r.readCount(4),i.toLowerCase()==":not("?this.createToken(Tokens.NOT,i,t,n):(r.reset(),this.charToken(e,t,n))},numberToken:function(e,t,n){var r=this._reader,i=this.readNumber(e),s,o=Tokens.NUMBER,u=r.peek();return isIdentStart(u)?(s=this.readName(r.read()),i+=s,/^em$|^ex$|^px$|^gd$|^rem$|^vw$|^vh$|^vm$|^ch$|^cm$|^mm$|^in$|^pt$|^pc$/i.test(s)?o=Tokens.LENGTH:/^deg|^rad$|^grad$/i.test(s)?o=Tokens.ANGLE:/^ms$|^s$/i.test(s)?o=Tokens.TIME:/^hz$|^khz$/i.test(s)?o=Tokens.FREQ:/^dpi$|^dpcm$/i.test(s)?o=Tokens.RESOLUTION:o=Tokens.DIMENSION):u=="%"&&(i+=r.read(),o=Tokens.PERCENTAGE),this.createToken(o,i,t,n)},stringToken:function(e,t,n){var r=e,i=e,s=this._reader,o=e,u=Tokens.STRING,a=s.read();while(a){i+=a;if(a==r&&o!="\\")break;if(isNewLine(s.peek())&&a!="\\"){u=Tokens.INVALID;break}o=a,a=s.read()}return a===null&&(u=Tokens.INVALID),this.createToken(u,i,t,n)},unicodeRangeToken:function(e,t,n){var r=this._reader,i=e,s,o=Tokens.CHAR;return r.peek()=="+"&&(r.mark(),i+=r.read(),i+=this.readUnicodeRangePart(!0),i.length==2?r.reset():(o=Tokens.UNICODE_RANGE,i.indexOf("?")==-1&&r.peek()=="-"&&(r.mark(),s=r.read(),s+=this.readUnicodeRangePart(!1),s.length==1?r.reset():i+=s))),this.createToken(o,i,t,n)},whitespaceToken:function(e,t,n){var r=this._reader,i=e+this.readWhitespace();return this.createToken(Tokens.S,i,t,n)},readUnicodeRangePart:function(e){var t=this._reader,n="",r=t.peek();while(isHexDigit(r)&&n.length<6)t.read(),n+=r,r=t.peek();if(e)while(r=="?"&&n.length<6)t.read(),n+=r,r=t.peek();return n},readWhitespace:function(){var e=this._reader,t="",n=e.peek();while(isWhitespace(n))e.read(),t+=n,n=e.peek();return t},readNumber:function(e){var t=this._reader,n=e,r=e==".",i=t.peek();while(i){if(isDigit(i))n+=t.read();else{if(i!=".")break;if(r)break;r=!0,n+=t.read()}i=t.peek()}return n},readString:function(){var e=this._reader,t=e.read(),n=t,r=t,i=e.peek();while(i){i=e.read(),n+=i;if(i==t&&r!="\\")break;if(isNewLine(e.peek())&&i!="\\"){n="";break}r=i,i=e.peek()}return i===null&&(n=""),n},readURI:function(e){var t=this._reader,n=e,r="",i=t.peek();t.mark();while(i&&isWhitespace(i))t.read(),i=t.peek();i=="'"||i=='"'?r=this.readString():r=this.readURL(),i=t.peek();while(i&&isWhitespace(i))t.read(),i=t.peek();return r===""||i!=")"?(n=e,t.reset()):n+=r+t.read(),n},readURL:function(){var e=this._reader,t="",n=e.peek();while(/^[!#$%&\\*-~]$/.test(n))t+=e.read(),n=e.peek();return t},readName:function(e){var t=this._reader,n=e||"",r=t.peek();for(;;)if(r=="\\")n+=this.readEscape(t.read()),r=t.peek();else{if(!r||!isNameChar(r))break;n+=t.read(),r=t.peek()}return n},readEscape:function(e){var t=this._reader,n=e||"",r=0,i=t.peek();if(isHexDigit(i))do n+=t.read(),i=t.peek();while(i&&isHexDigit(i)&&++r<6);return n.length==3&&/\s/.test(i)||n.length==7||n.length==1?t.read():i="",n+i},readComment:function(e){var t=this._reader,n=e||"",r=t.read();if(r=="*"){while(r){n+=r;if(n.length>2&&r=="*"&&t.peek()=="/"){n+=t.read();break}r=t.read()}return n}return""}});var Tokens=[{name:"CDO"},{name:"CDC"},{name:"S",whitespace:!0},{name:"COMMENT",comment:!0,hide:!0,channel:"comment"},{name:"INCLUDES",text:"~="},{name:"DASHMATCH",text:"|="},{name:"PREFIXMATCH",text:"^="},{name:"SUFFIXMATCH",text:"$="},{name:"SUBSTRINGMATCH",text:"*="},{name:"STRING"},{name:"IDENT"},{name:"HASH"},{name:"IMPORT_SYM",text:"@import"},{name:"PAGE_SYM",text:"@page"},{name:"MEDIA_SYM",text:"@media"},{name:"FONT_FACE_SYM",text:"@font-face"},{name:"CHARSET_SYM",text:"@charset"},{name:"NAMESPACE_SYM",text:"@namespace"},{name:"VIEWPORT_SYM",text:["@viewport","@-ms-viewport"]},{name:"UNKNOWN_SYM"},{name:"KEYFRAMES_SYM",text:["@keyframes","@-webkit-keyframes","@-moz-keyframes","@-o-keyframes"]},{name:"IMPORTANT_SYM"},{name:"LENGTH"},{name:"ANGLE"},{name:"TIME"},{name:"FREQ"},{name:"DIMENSION"},{name:"PERCENTAGE"},{name:"NUMBER"},{name:"URI"},{name:"FUNCTION"},{name:"UNICODE_RANGE"},{name:"INVALID"},{name:"PLUS",text:"+"},{name:"GREATER",text:">"},{name:"COMMA",text:","},{name:"TILDE",text:"~"},{name:"NOT"},{name:"TOPLEFTCORNER_SYM",text:"@top-left-corner"},{name:"TOPLEFT_SYM",text:"@top-left"},{name:"TOPCENTER_SYM",text:"@top-center"},{name:"TOPRIGHT_SYM",text:"@top-right"},{name:"TOPRIGHTCORNER_SYM",text:"@top-right-corner"},{name:"BOTTOMLEFTCORNER_SYM",text:"@bottom-left-corner"},{name:"BOTTOMLEFT_SYM",text:"@bottom-left"},{name:"BOTTOMCENTER_SYM",text:"@bottom-center"},{name:"BOTTOMRIGHT_SYM",text:"@bottom-right"},{name:"BOTTOMRIGHTCORNER_SYM",text:"@bottom-right-corner"},{name:"LEFTTOP_SYM",text:"@left-top"},{name:"LEFTMIDDLE_SYM",text:"@left-middle"},{name:"LEFTBOTTOM_SYM",text:"@left-bottom"},{name:"RIGHTTOP_SYM",text:"@right-top"},{name:"RIGHTMIDDLE_SYM",text:"@right-middle"},{name:"RIGHTBOTTOM_SYM",text:"@right-bottom"},{name:"RESOLUTION",state:"media"},{name:"IE_FUNCTION"},{name:"CHAR"},{name:"PIPE",text:"|"},{name:"SLASH",text:"/"},{name:"MINUS",text:"-"},{name:"STAR",text:"*"},{name:"LBRACE",text:"{"},{name:"RBRACE",text:"}"},{name:"LBRACKET",text:"["},{name:"RBRACKET",text:"]"},{name:"EQUALS",text:"="},{name:"COLON",text:":"},{name:"SEMICOLON",text:";"},{name:"LPAREN",text:"("},{name:"RPAREN",text:")"},{name:"DOT",text:"."}];(function(){var e=[],t={};Tokens.UNKNOWN=-1,Tokens.unshift({name:"EOF"});for(var n=0,r=Tokens.length;n<r;n++){e.push(Tokens[n].name),Tokens[Tokens[n].name]=n;if(Tokens[n].text)if(Tokens[n].text instanceof Array)for(var i=0;i<Tokens[n].text.length;i++)t[Tokens[n].text[i]]=n;else t[Tokens[n].text]=n}Tokens.name=function(t){return e[t]},Tokens.type=function(e){return t[e]||-1}})();var Validation={validate:function(e,t){var n=e.toString().toLowerCase(),r=t.parts,i=new PropertyValueIterator(t),s=Properties[n],o,u,a,f,l,c,h,p,d,v,m;if(!s){if(n.indexOf("-")!==0)throw new ValidationError("Unknown property '"+e+"'.",e.line,e.col)}else typeof s!="number"&&(typeof s=="string"?s.indexOf("||")>-1?this.groupProperty(s,i):this.singleProperty(s,i,1):s.multi?this.multiProperty(s.multi,i,s.comma,s.max||Infinity):typeof s=="function"&&s(i))},singleProperty:function(e,t,n,r){var i=!1,s=t.value,o=0,u;while(t.hasNext()&&o<n){i=ValidationTypes.isAny(t,e);if(!i)break;o++}if(!i)throw t.hasNext()&&!t.isFirst()?(u=t.peek(),new ValidationError("Expected end of value but found '"+u+"'.",u.line,u.col)):new ValidationError("Expected ("+e+") but found '"+s+"'.",s.line,s.col);if(t.hasNext())throw u=t.next(),new ValidationError("Expected end of value but found '"+u+"'.",u.line,u.col)},multiProperty:function(e,t,n,r){var i=!1,s=t.value,o=0,u=!1,a;while(t.hasNext()&&!i&&o<r){if(!ValidationTypes.isAny(t,e))break;o++;if(!t.hasNext())i=!0;else if(n){if(t.peek()!=",")break;a=t.next()}}if(!i)throw t.hasNext()&&!t.isFirst()?(a=t.peek(),new ValidationError("Expected end of value but found '"+a+"'.",a.line,a.col)):(a=t.previous(),n&&a==","?new ValidationError("Expected end of value but found '"+a+"'.",a.line,a.col):new ValidationError("Expected ("+e+") but found '"+s+"'.",s.line,s.col));if(t.hasNext())throw a=t.next(),new ValidationError("Expected end of value but found '"+a+"'.",a.line,a.col)},groupProperty:function(e,t,n){var r=!1,i=t.value,s=e.split("||").length,o={count:0},u=!1,a,f;while(t.hasNext()&&!r){a=ValidationTypes.isAnyOfGroup(t,e);if(!a)break;if(o[a])break;o[a]=1,o.count++,u=!0;if(o.count==s||!t.hasNext())r=!0}if(!r)throw u&&t.hasNext()?(f=t.peek(),new ValidationError("Expected end of value but found '"+f+"'.",f.line,f.col)):new ValidationError("Expected ("+e+") but found '"+i+"'.",i.line,i.col);if(t.hasNext())throw f=t.next(),new ValidationError("Expected end of value but found '"+f+"'.",f.line,f.col)}};ValidationError.prototype=new Error;var ValidationTypes={isLiteral:function(e,t){var n=e.text.toString().toLowerCase(),r=t.split(" | "),i,s,o=!1;for(i=0,s=r.length;i<s&&!o;i++)n==r[i].toLowerCase()&&(o=!0);return o},isSimple:function(e){return!!this.simple[e]},isComplex:function(e){return!!this.complex[e]},isAny:function(e,t){var n=t.split(" | "),r,i,s=!1;for(r=0,i=n.length;r<i&&!s&&e.hasNext();r++)s=this.isType(e,n[r]);return s},isAnyOfGroup:function(e,t){var n=t.split(" || "),r,i,s=!1;for(r=0,i=n.length;r<i&&!s;r++)s=this.isType(e,n[r]);return s?n[r-1]:!1},isType:function(e,t){var n=e.peek(),r=!1;return t.charAt(0)!="<"?(r=this.isLiteral(n,t),r&&e.next()):this.simple[t]?(r=this.simple[t](n),r&&e.next()):r=this.complex[t](e),r},simple:{"<absolute-size>":function(e){return ValidationTypes.isLiteral(e,"xx-small | x-small | small | medium | large | x-large | xx-large")},"<attachment>":function(e){return ValidationTypes.isLiteral(e,"scroll | fixed | local")},"<attr>":function(e){return e.type=="function"&&e.name=="attr"},"<bg-image>":function(e){return this["<image>"](e)||this["<gradient>"](e)||e=="none"},"<gradient>":function(e){return e.type=="function"&&/^(?:\-(?:ms|moz|o|webkit)\-)?(?:repeating\-)?(?:radial\-|linear\-)?gradient/i.test(e)},"<box>":function(e){return ValidationTypes.isLiteral(e,"padding-box | border-box | content-box")},"<content>":function(e){return e.type=="function"&&e.name=="content"},"<relative-size>":function(e){return ValidationTypes.isLiteral(e,"smaller | larger")},"<ident>":function(e){return e.type=="identifier"},"<length>":function(e){return e.type=="function"&&/^(?:\-(?:ms|moz|o|webkit)\-)?calc/i.test(e)?!0:e.type=="length"||e.type=="number"||e.type=="integer"||e=="0"},"<color>":function(e){return e.type=="color"||e=="transparent"},"<number>":function(e){return e.type=="number"||this["<integer>"](e)},"<integer>":function(e){return e.type=="integer"},"<line>":function(e){return e.type=="integer"},"<angle>":function(e){return e.type=="angle"},"<uri>":function(e){return e.type=="uri"},"<image>":function(e){return this["<uri>"](e)},"<percentage>":function(e){return e.type=="percentage"||e=="0"},"<border-width>":function(e){return this["<length>"](e)||ValidationTypes.isLiteral(e,"thin | medium | thick")},"<border-style>":function(e){return ValidationTypes.isLiteral(e,"none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset")},"<margin-width>":function(e){return this["<length>"](e)||this["<percentage>"](e)||ValidationTypes.isLiteral(e,"auto")},"<padding-width>":function(e){return this["<length>"](e)||this["<percentage>"](e)},"<shape>":function(e){return e.type=="function"&&(e.name=="rect"||e.name=="inset-rect")},"<time>":function(e){return e.type=="time"}},complex:{"<bg-position>":function(e){var t=this,n=!1,r="<percentage> | <length>",i="left | right",s="top | bottom",o=0,u=function(){return e.hasNext()&&e.peek()!=","};while(e.peek(o)&&e.peek(o)!=",")o++;return o<3?ValidationTypes.isAny(e,i+" | center | "+r)?(n=!0,ValidationTypes.isAny(e,s+" | center | "+r)):ValidationTypes.isAny(e,s)&&(n=!0,ValidationTypes.isAny(e,i+" | center")):ValidationTypes.isAny(e,i)?ValidationTypes.isAny(e,s)?(n=!0,ValidationTypes.isAny(e,r)):ValidationTypes.isAny(e,r)&&(ValidationTypes.isAny(e,s)?(n=!0,ValidationTypes.isAny(e,r)):ValidationTypes.isAny(e,"center")&&(n=!0)):ValidationTypes.isAny(e,s)?ValidationTypes.isAny(e,i)?(n=!0,ValidationTypes.isAny(e,r)):ValidationTypes.isAny(e,r)&&(ValidationTypes.isAny(e,i)?(n=!0,ValidationTypes.isAny(e,r)):ValidationTypes.isAny(e,"center")&&(n=!0)):ValidationTypes.isAny(e,"center")&&ValidationTypes.isAny(e,i+" | "+s)&&(n=!0,ValidationTypes.isAny(e,r)),n},"<bg-size>":function(e){var t=this,n=!1,r="<percentage> | <length> | auto",i,s,o;return ValidationTypes.isAny(e,"cover | contain")?n=!0:ValidationTypes.isAny(e,r)&&(n=!0,ValidationTypes.isAny(e,r)),n},"<repeat-style>":function(e){var t=!1,n="repeat | space | round | no-repeat",r;return e.hasNext()&&(r=e.next(),ValidationTypes.isLiteral(r,"repeat-x | repeat-y")?t=!0:ValidationTypes.isLiteral(r,n)&&(t=!0,e.hasNext()&&ValidationTypes.isLiteral(e.peek(),n)&&e.next())),t},"<shadow>":function(e){var t=!1,n=0,r=!1,i=!1,s;if(e.hasNext()){ValidationTypes.isAny(e,"inset")&&(r=!0),ValidationTypes.isAny(e,"<color>")&&(i=!0);while(ValidationTypes.isAny(e,"<length>")&&n<4)n++;e.hasNext()&&(i||ValidationTypes.isAny(e,"<color>"),r||ValidationTypes.isAny(e,"inset")),t=n>=2&&n<=4}return t},"<x-one-radius>":function(e){var t=!1,n="<length> | <percentage> | inherit";return ValidationTypes.isAny(e,n)&&(t=!0,ValidationTypes.isAny(e,n)),t}}};parserlib.css={Colors:Colors,Combinator:Combinator,Parser:Parser,PropertyName:PropertyName,PropertyValue:PropertyValue,PropertyValuePart:PropertyValuePart,MediaFeature:MediaFeature,MediaQuery:MediaQuery,Selector:Selector,SelectorPart:SelectorPart,SelectorSubPart:SelectorSubPart,Specificity:Specificity,TokenStream:TokenStream,Tokens:Tokens,ValidationError:ValidationError}}(),function(){for(var e in parserlib)exports[e]=parserlib[e]}();var CSSLint=function(){function i(e,t){var r,i=e&&e.match(n),s=i&&i[1];return s&&(r={"true":2,"":1,"false":0,2:2,1:1,0:0},s.toLowerCase().split(",").forEach(function(e){var n=e.split(":"),i=n[0]||"",s=n[1]||"";t[i.trim()]=r[s.trim()]})),t}var e=[],t=[],n=/\/\*csslint([^\*]*)\*\//,r=new parserlib.util.EventTarget;return r.version="@VERSION@",r.addRule=function(t){e.push(t),e[t.id]=t},r.clearRules=function(){e=[]},r.getRules=function(){return[].concat(e).sort(function(e,t){return e.id>t.id?1:0})},r.getRuleset=function(){var t={},n=0,r=e.length;while(n<r)t[e[n++].id]=1;return t},r.addFormatter=function(e){t[e.id]=e},r.getFormatter=function(e){return t[e]},r.format=function(e,t,n,r){var i=this.getFormatter(n),s=null;return i&&(s=i.startFormat(),s+=i.formatResults(e,t,r||{}),s+=i.endFormat()),s},r.hasFormat=function(e){return t.hasOwnProperty(e)},r.verify=function(t,r){var s=0,o=e.length,u,a,f,l=new parserlib.css.Parser({starHack:!0,ieFilters:!0,underscoreHack:!0,strict:!1});a=t.replace(/\n\r?/g,"$split$").split("$split$"),r||(r=this.getRuleset()),n.test(t)&&(r=i(t,r)),u=new Reporter(a,r),r.errors=2;for(s in r)r.hasOwnProperty(s)&&r[s]&&e[s]&&e[s].init(l,u);try{l.parse(t)}catch(c){u.error("Fatal error, cannot continue: "+c.message,c.line,c.col,{})}return f={messages:u.messages,stats:u.stats,ruleset:u.ruleset},f.messages.sort(function(e,t){return e.rollup&&!t.rollup?1:!e.rollup&&t.rollup?-1:e.line-t.line}),f},r}();Reporter.prototype={constructor:Reporter,error:function(e,t,n,r){this.messages.push({type:"error",line:t,col:n,message:e,evidence:this.lines[t-1],rule:r||{}})},warn:function(e,t,n,r){this.report(e,t,n,r)},report:function(e,t,n,r){this.messages.push({type:this.ruleset[r.id]==2?"error":"warning",line:t,col:n,message:e,evidence:this.lines[t-1],rule:r})},info:function(e,t,n,r){this.messages.push({type:"info",line:t,col:n,message:e,evidence:this.lines[t-1],rule:r})},rollupError:function(e,t){this.messages.push({type:"error",rollup:!0,message:e,rule:t})},rollupWarn:function(e,t){this.messages.push({type:"warning",rollup:!0,message:e,rule:t})},stat:function(e,t){this.stats[e]=t}},CSSLint._Reporter=Reporter,CSSLint.Util={mix:function(e,t){var n;for(n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return n},indexOf:function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},forEach:function(e,t){if(e.forEach)return e.forEach(t);for(var n=0,r=e.length;n<r;n++)t(e[n],n,e)}},CSSLint.addRule({id:"adjoining-classes",name:"Disallow adjoining classes",desc:"Don't use adjoining classes.",browsers:"IE6",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l,c;for(f=0;f<i.length;f++){s=i[f];for(l=0;l<s.parts.length;l++){o=s.parts[l];if(o.type==e.SELECTOR_PART_TYPE){a=0;for(c=0;c<o.modifiers.length;c++)u=o.modifiers[c],u.type=="class"&&a++,a>1&&t.report("Don't use adjoining classes.",o.line,o.col,n)}}}})}}),CSSLint.addRule({id:"box-model",name:"Beware of broken box size",desc:"Don't use width or height when using padding or border.",browsers:"All",init:function(e,t){function u(){s={},o=!1}function a(){var e,u;if(!o){if(s.height)for(e in i)i.hasOwnProperty(e)&&s[e]&&(u=s[e].value,(e!="padding"||u.parts.length!==2||u.parts[0].value!==0)&&t.report("Using height with "+e+" can sometimes make elements larger than you expect.",s[e].line,s[e].col,n));if(s.width)for(e in r)r.hasOwnProperty(e)&&s[e]&&(u=s[e].value,(e!="padding"||u.parts.length!==2||u.parts[1].value!==0)&&t.report("Using width with "+e+" can sometimes make elements larger than you expect.",s[e].line,s[e].col,n))}}var n=this,r={border:1,"border-left":1,"border-right":1,padding:1,"padding-left":1,"padding-right":1},i={border:1,"border-bottom":1,"border-top":1,padding:1,"padding-bottom":1,"padding-top":1},s,o=!1;e.addListener("startrule",u),e.addListener("startfontface",u),e.addListener("startpage",u),e.addListener("startpagemargin",u),e.addListener("startkeyframerule",u),e.addListener("property",function(e){var t=e.property.text.toLowerCase();i[t]||r[t]?!/^0\S*$/.test(e.value)&&(t!="border"||e.value!="none")&&(s[t]={line:e.property.line,col:e.property.col,value:e.value}):/^(width|height)/i.test(t)&&/^(length|percentage)/.test(e.value.parts[0].type)?s[t]=1:t=="box-sizing"&&(o=!0)}),e.addListener("endrule",a),e.addListener("endfontface",a),e.addListener("endpage",a),e.addListener("endpagemargin",a),e.addListener("endkeyframerule",a)}}),CSSLint.addRule({id:"box-sizing",name:"Disallow use of box-sizing",desc:"The box-sizing properties isn't supported in IE6 and IE7.",browsers:"IE6, IE7",tags:["Compatibility"],init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property.text.toLowerCase();r=="box-sizing"&&t.report("The box-sizing property isn't supported in IE6 and IE7.",e.line,e.col,n)})}}),CSSLint.addRule({id:"bulletproof-font-face",name:"Use the bulletproof @font-face syntax",desc:"Use the bulletproof @font-face syntax to avoid 404's in old IE (http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax).",browsers:"All",init:function(e,t){var n=this,r=0,i=!1,s=!0,o=!1,u,a;e.addListener("startfontface",function(e){i=!0}),e.addListener("property",function(e){if(!i)return;var t=e.property.toString().toLowerCase(),n=e.value.toString();u=e.line,a=e.col;if(t==="src"){var r=/^\s?url\(['"].+\.eot\?.*['"]\)\s*format\(['"]embedded-opentype['"]\).*$/i;!n.match(r)&&s?(o=!0,s=!1):n.match(r)&&!s&&(o=!1)}}),e.addListener("endfontface",function(e){i=!1,o&&t.report("@font-face declaration doesn't follow the fontspring bulletproof syntax.",u,a,n)})}}),CSSLint.addRule({id:"compatible-vendor-prefixes",name:"Require compatible vendor prefixes",desc:"Include all compatible vendor prefixes to reach a wider range of users.",browsers:"All",init:function(e,t){var n=this,r,i,s,o,u,a,f,l=!1,c=Array.prototype.push,h=[];r={animation:"webkit moz","animation-delay":"webkit moz","animation-direction":"webkit moz","animation-duration":"webkit moz","animation-fill-mode":"webkit moz","animation-iteration-count":"webkit moz","animation-name":"webkit moz","animation-play-state":"webkit moz","animation-timing-function":"webkit moz",appearance:"webkit moz","border-end":"webkit moz","border-end-color":"webkit moz","border-end-style":"webkit moz","border-end-width":"webkit moz","border-image":"webkit moz o","border-radius":"webkit","border-start":"webkit moz","border-start-color":"webkit moz","border-start-style":"webkit moz","border-start-width":"webkit moz","box-align":"webkit moz ms","box-direction":"webkit moz ms","box-flex":"webkit moz ms","box-lines":"webkit ms","box-ordinal-group":"webkit moz ms","box-orient":"webkit moz ms","box-pack":"webkit moz ms","box-sizing":"webkit moz","box-shadow":"webkit moz","column-count":"webkit moz ms","column-gap":"webkit moz ms","column-rule":"webkit moz ms","column-rule-color":"webkit moz ms","column-rule-style":"webkit moz ms","column-rule-width":"webkit moz ms","column-width":"webkit moz ms",hyphens:"epub moz","line-break":"webkit ms","margin-end":"webkit moz","margin-start":"webkit moz","marquee-speed":"webkit wap","marquee-style":"webkit wap","padding-end":"webkit moz","padding-start":"webkit moz","tab-size":"moz o","text-size-adjust":"webkit ms",transform:"webkit moz ms o","transform-origin":"webkit moz ms o",transition:"webkit moz o","transition-delay":"webkit moz o","transition-duration":"webkit moz o","transition-property":"webkit moz o","transition-timing-function":"webkit moz o","user-modify":"webkit moz","user-select":"webkit moz ms","word-break":"epub ms","writing-mode":"epub ms"};for(s in r)if(r.hasOwnProperty(s)){o=[],u=r[s].split(" ");for(a=0,f=u.length;a<f;a++)o.push("-"+u[a]+"-"+s);r[s]=o,c.apply(h,o)}e.addListener("startrule",function(){i=[]}),e.addListener("startkeyframes",function(e){l=e.prefix||!0}),e.addListener("endkeyframes",function(e){l=!1}),e.addListener("property",function(e){var t=e.property;CSSLint.Util.indexOf(h,t.text)>-1&&(!l||typeof l!="string"||t.text.indexOf("-"+l+"-")!==0)&&i.push(t)}),e.addListener("endrule",function(e){if(!i.length)return;var s={},o,u,a,f,l,c,h,p,d,v;for(o=0,u=i.length;o<u;o++){a=i[o];for(f in r)r.hasOwnProperty(f)&&(l=r[f],CSSLint.Util.indexOf(l,a.text)>-1&&(s[f]||(s[f]={full:l.slice(0),actual:[],actualNodes:[]}),CSSLint.Util.indexOf(s[f].actual,a.text)===-1&&(s[f].actual.push(a.text),s[f].actualNodes.push(a))))}for(f in s)if(s.hasOwnProperty(f)){c=s[f],h=c.full,p=c.actual;if(h.length>p.length)for(o=0,u=h.length;o<u;o++)d=h[o],CSSLint.Util.indexOf(p,d)===-1&&(v=p.length===1?p[0]:p.length==2?p.join(" and "):p.join(", "),t.report("The property "+d+" is compatible with "+v+" and should be included as well.",c.actualNodes[0].line,c.actualNodes[0].col,n))}})}}),CSSLint.addRule({id:"display-property-grouping",name:"Require properties appropriate for display",desc:"Certain properties shouldn't be used with certain display property values.",browsers:"All",init:function(e,t){function s(e,s,o){i[e]&&(typeof r[e]!="string"||i[e].value.toLowerCase()!=r[e])&&t.report(o||e+" can't be used with display: "+s+".",i[e].line,i[e].col,n)}function o(){i={}}function u(){var e=i.display?i.display.value:null;if(e)switch(e){case"inline":s("height",e),s("width",e),s("margin",e),s("margin-top",e),s("margin-bottom",e),s("float",e,"display:inline has no effect on floated elements (but may be used to fix the IE6 double-margin bug).");break;case"block":s("vertical-align",e);break;case"inline-block":s("float",e);break;default:e.indexOf("table-")===0&&(s("margin",e),s("margin-left",e),s("margin-right",e),s("margin-top",e),s("margin-bottom",e),s("float",e))}}var n=this,r={display:1,"float":"none",height:1,width:1,margin:1,"margin-left":1,"margin-right":1,"margin-bottom":1,"margin-top":1,padding:1,"padding-left":1,"padding-right":1,"padding-bottom":1,"padding-top":1,"vertical-align":1},i;e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startkeyframerule",o),e.addListener("startpagemargin",o),e.addListener("startpage",o),e.addListener("property",function(e){var t=e.property.text.toLowerCase();r[t]&&(i[t]={value:e.value.text,line:e.property.line,col:e.property.col})}),e.addListener("endrule",u),e.addListener("endfontface",u),e.addListener("endkeyframerule",u),e.addListener("endpagemargin",u),e.addListener("endpage",u)}}),CSSLint.addRule({id:"duplicate-background-images",name:"Disallow duplicate background images",desc:"Every background-image should be unique. Use a common class for e.g. sprites.",browsers:"All",init:function(e,t){var n=this,r={};e.addListener("property",function(e){var i=e.property.text,s=e.value,o,u;if(i.match(/background/i))for(o=0,u=s.parts.length;o<u;o++)s.parts[o].type=="uri"&&(typeof r[s.parts[o].uri]=="undefined"?r[s.parts[o].uri]=e:t.report("Background image '"+s.parts[o].uri+"' was used multiple times, first declared at line "+r[s.parts[o].uri].line+", col "+r[s.parts[o].uri].col+".",e.line,e.col,n))})}}),CSSLint.addRule({id:"duplicate-properties",name:"Disallow duplicate properties",desc:"Duplicate properties must appear one after the other.",browsers:"All",init:function(e,t){function s(e){r={}}var n=this,r,i;e.addListener("startrule",s),e.addListener("startfontface",s),e.addListener("startpage",s),e.addListener("startpagemargin",s),e.addListener("startkeyframerule",s),e.addListener("property",function(e){var s=e.property,o=s.text.toLowerCase();r[o]&&(i!=o||r[o]==e.value.text)&&t.report("Duplicate property '"+e.property+"' found.",e.line,e.col,n),r[o]=e.value.text,i=o})}}),CSSLint.addRule({id:"empty-rules",name:"Disallow empty rules",desc:"Rules without any properties specified should be removed.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("startrule",function(){r=0}),e.addListener("property",function(){r++}),e.addListener("endrule",function(e){var i=e.selectors;r===0&&t.report("Rule is empty.",i[0].line,i[0].col,n)})}}),CSSLint.addRule({id:"errors",name:"Parsing Errors",desc:"This rule looks for recoverable syntax errors.",browsers:"All",init:function(e,t){var n=this;e.addListener("error",function(e){t.error(e.message,e.line,e.col,n)})}}),CSSLint.addRule({id:"fallback-colors",name:"Require fallback colors",desc:"For older browsers that don't support RGBA, HSL, or HSLA, provide a fallback color.",browsers:"IE6,IE7,IE8",init:function(e,t){function o(e){s={},r=null}var n=this,r,i={color:1,background:1,"border-color":1,"border-top-color":1,"border-right-color":1,"border-bottom-color":1,"border-left-color":1,border:1,"border-top":1,"border-right":1,"border-bottom":1,"border-left":1,"background-color":1},s;e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startpage",o),e.addListener("startpagemargin",o),e.addListener("startkeyframerule",o),e.addListener("property",function(e){var s=e.property,o=s.text.toLowerCase(),u=e.value.parts,a=0,f="",l=u.length;if(i[o])while(a<l)u[a].type=="color"&&("alpha"in u[a]||"hue"in u[a]?(/([^\)]+)\(/.test(u[a])&&(f=RegExp.$1.toUpperCase()),(!r||r.property.text.toLowerCase()!=o||r.colorType!="compat")&&t.report("Fallback "+o+" (hex or RGB) should precede "+f+" "+o+".",e.line,e.col,n)):e.colorType="compat"),a++;r=e})}}),CSSLint.addRule({id:"floats",name:"Disallow too many floats",desc:"This rule tests if the float property is used too many times",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("property",function(e){e.property.text.toLowerCase()=="float"&&e.value.text.toLowerCase()!="none"&&r++}),e.addListener("endstylesheet",function(){t.stat("floats",r),r>=10&&t.rollupWarn("Too many floats ("+r+"), you're probably using them for layout. Consider using a grid system instead.",n)})}}),CSSLint.addRule({id:"font-faces",name:"Don't use too many web fonts",desc:"Too many different web fonts in the same stylesheet.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("startfontface",function(){r++}),e.addListener("endstylesheet",function(){r>5&&t.rollupWarn("Too many @font-face declarations ("+r+").",n)})}}),CSSLint.addRule({id:"font-sizes",name:"Disallow too many font sizes",desc:"Checks the number of font-size declarations.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("property",function(e){e.property=="font-size"&&r++}),e.addListener("endstylesheet",function(){t.stat("font-sizes",r),r>=10&&t.rollupWarn("Too many font-size declarations ("+r+"), abstraction needed.",n)})}}),CSSLint.addRule({id:"gradients",name:"Require all gradient definitions",desc:"When using a vendor-prefixed gradient, make sure to use them all.",browsers:"All",init:function(e,t){var n=this,r;e.addListener("startrule",function(){r={moz:0,webkit:0,oldWebkit:0,o:0}}),e.addListener("property",function(e){/\-(moz|o|webkit)(?:\-(?:linear|radial))\-gradient/i.test(e.value)?r[RegExp.$1]=1:/\-webkit\-gradient/i.test(e.value)&&(r.oldWebkit=1)}),e.addListener("endrule",function(e){var i=[];r.moz||i.push("Firefox 3.6+"),r.webkit||i.push("Webkit (Safari 5+, Chrome)"),r.oldWebkit||i.push("Old Webkit (Safari 4+, Chrome)"),r.o||i.push("Opera 11.1+"),i.length&&i.length<4&&t.report("Missing vendor-prefixed CSS gradients for "+i.join(", ")+".",e.selectors[0].line,e.selectors[0].col,n)})}}),CSSLint.addRule({id:"ids",name:"Disallow IDs in selectors",desc:"Selectors should not contain IDs.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l,c;for(f=0;f<i.length;f++){s=i[f],a=0;for(l=0;l<s.parts.length;l++){o=s.parts[l];if(o.type==e.SELECTOR_PART_TYPE)for(c=0;c<o.modifiers.length;c++)u=o.modifiers[c],u.type=="id"&&a++}a==1?t.report("Don't use IDs in selectors.",s.line,s.col,n):a>1&&t.report(a+" IDs in the selector, really?",s.line,s.col,n)}})}}),CSSLint.addRule({id:"import",name:"Disallow @import",desc:"Don't use @import, use <link> instead.",browsers:"All",init:function(e,t){var n=this;e.addListener("import",function(e){t.report("@import prevents parallel downloads, use <link> instead.",e.line,e.col,n)})}}),CSSLint.addRule({id:"important",name:"Disallow !important",desc:"Be careful when using !important declaration",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("property",function(e){e.important===!0&&(r++,t.report("Use of !important",e.line,e.col,n))}),e.addListener("endstylesheet",function(){t.stat("important",r),r>=10&&t.rollupWarn("Too many !important declarations ("+r+"), try to use less than 10 to avoid specificity issues.",n)})}}),CSSLint.addRule({id:"known-properties",name:"Require use of known properties",desc:"Properties should be known (listed in CSS3 specification) or be a vendor-prefixed property.",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property.text.toLowerCase();e.invalid&&t.report(e.invalid.message,e.line,e.col,n)})}}),CSSLint.addRule({id:"outline-none",name:"Disallow outline: none",desc:"Use of outline: none or outline: 0 should be limited to :focus rules.",browsers:"All",tags:["Accessibility"],init:function(e,t){function i(e){e.selectors?r={line:e.line,col:e.col,selectors:e.selectors,propCount:0,outline:!1}:r=null}function s(e){r&&r.outline&&(r.selectors.toString().toLowerCase().indexOf(":focus")==-1?t.report("Outlines should only be modified using :focus.",r.line,r.col,n):r.propCount==1&&t.report("Outlines shouldn't be hidden unless other visual changes are made.",r.line,r.col,n))}var n=this,r;e.addListener("startrule",i),e.addListener("startfontface",i),e.addListener("startpage",i),e.addListener("startpagemargin",i),e.addListener("startkeyframerule",i),e.addListener("property",function(e){var t=e.property.text.toLowerCase(),n=e.value;r&&(r.propCount++,t=="outline"&&(n=="none"||n=="0")&&(r.outline=!0))}),e.addListener("endrule",s),e.addListener("endfontface",s),e.addListener("endpage",s),e.addListener("endpagemargin",s),e.addListener("endkeyframerule",s)}}),CSSLint.addRule({id:"overqualified-elements",name:"Disallow overqualified elements",desc:"Don't use classes or IDs with elements (a.foo or a#foo).",browsers:"All",init:function(e,t){var n=this,r={};e.addListener("startrule",function(i){var s=i.selectors,o,u,a,f,l,c;for(f=0;f<s.length;f++){o=s[f];for(l=0;l<o.parts.length;l++){u=o.parts[l];if(u.type==e.SELECTOR_PART_TYPE)for(c=0;c<u.modifiers.length;c++)a=u.modifiers[c],u.elementName&&a.type=="id"?t.report("Element ("+u+") is overqualified, just use "+a+" without element name.",u.line,u.col,n):a.type=="class"&&(r[a]||(r[a]=[]),r[a].push({modifier:a,part:u}))}}}),e.addListener("endstylesheet",function(){var e;for(e in r)r.hasOwnProperty(e)&&r[e].length==1&&r[e][0].part.elementName&&t.report("Element ("+r[e][0].part+") is overqualified, just use "+r[e][0].modifier+" without element name.",r[e][0].part.line,r[e][0].part.col,n)})}}),CSSLint.addRule({id:"qualified-headings",name:"Disallow qualified headings",desc:"Headings should not be qualified (namespaced).",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a;for(u=0;u<i.length;u++){s=i[u];for(a=0;a<s.parts.length;a++)o=s.parts[a],o.type==e.SELECTOR_PART_TYPE&&o.elementName&&/h[1-6]/.test(o.elementName.toString())&&a>0&&t.report("Heading ("+o.elementName+") should not be qualified.",o.line,o.col,n)}})}}),CSSLint.addRule({id:"regex-selectors",name:"Disallow selectors that look like regexs",desc:"Selectors that look like regular expressions are slow and should be avoided.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l;for(a=0;a<i.length;a++){s=i[a];for(f=0;f<s.parts.length;f++){o=s.parts[f];if(o.type==e.SELECTOR_PART_TYPE)for(l=0;l<o.modifiers.length;l++)u=o.modifiers[l],u.type=="attribute"&&/([\~\|\^\$\*]=)/.test(u)&&t.report("Attribute selectors with "+RegExp.$1+" are slow!",u.line,u.col,n)}}})}}),CSSLint.addRule({id:"rules-count",name:"Rules Count",desc:"Track how many rules there are.",browsers:"All",init:function(e,t){var n=this,r=0;e.addListener("startrule",function(){r++}),e.addListener("endstylesheet",function(){t.stat("rule-count",r)})}}),CSSLint.addRule({id:"selector-max-approaching",name:"Warn when approaching the 4095 selector limit for IE",desc:"Will warn when selector count is >= 3800 selectors.",browsers:"IE",init:function(e,t){var n=this,r=0;e.addListener("startrule",function(e){r+=e.selectors.length}),e.addListener("endstylesheet",function(){r>=3800&&t.report("You have "+r+" selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,n)})}}),CSSLint.addRule({id:"selector-max",name:"Error when past the 4095 selector limit for IE",desc:"Will error when selector count is > 4095.",browsers:"IE",init:function(e,t){var n=this,r=0;e.addListener("startrule",function(e){r+=e.selectors.length}),e.addListener("endstylesheet",function(){r>4095&&t.report("You have "+r+" selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,n)})}}),CSSLint.addRule({id:"shorthand",name:"Require shorthand properties",desc:"Use shorthand properties where possible.",browsers:"All",init:function(e,t){function f(e){u={}}function l(e){var r,i,s,o;for(r in a)if(a.hasOwnProperty(r)){o=0;for(i=0,s=a[r].length;i<s;i++)o+=u[a[r][i]]?1:0;o==a[r].length&&t.report("The properties "+a[r].join(", ")+" can be replaced by "+r+".",e.line,e.col,n)}}var n=this,r,i,s,o={},u,a={margin:["margin-top","margin-bottom","margin-left","margin-right"],padding:["padding-top","padding-bottom","padding-left","padding-right"]};for(r in a)if(a.hasOwnProperty(r))for(i=0,s=a[r].length;i<s;i++)o[a[r][i]]=r;e.addListener("startrule",f),e.addListener("startfontface",f),e.addListener("property",function(e){var t=e.property.toString().toLowerCase(),n=e.value.parts[0].value;o[t]&&(u[t]=1)}),e.addListener("endrule",l),e.addListener("endfontface",l)}}),CSSLint.addRule({id:"star-property-hack",name:"Disallow properties with a star prefix",desc:"Checks for the star property hack (targets IE6/7)",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property;r.hack=="*"&&t.report("Property with star prefix found.",e.property.line,e.property.col,n)})}}),CSSLint.addRule({id:"text-indent",name:"Disallow negative text-indent",desc:"Checks for text indent less than -99px",browsers:"All",init:function(e,t){function s(e){r=!1,i="inherit"}function o(e){r&&i!="ltr"&&t.report("Negative text-indent doesn't work well with RTL. If you use text-indent for image replacement explicitly set direction for that item to ltr.",r.line,r.col,n)}var n=this,r,i;e.addListener("startrule",s),e.addListener("startfontface",s),e.addListener("property",function(e){var t=e.property.toString().toLowerCase(),n=e.value;t=="text-indent"&&n.parts[0].value<-99?r=e.property:t=="direction"&&n=="ltr"&&(i="ltr")}),e.addListener("endrule",o),e.addListener("endfontface",o)}}),CSSLint.addRule({id:"underscore-property-hack",name:"Disallow properties with an underscore prefix",desc:"Checks for the underscore property hack (targets IE6)",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.property;r.hack=="_"&&t.report("Property with underscore prefix found.",e.property.line,e.property.col,n)})}}),CSSLint.addRule({id:"unique-headings",name:"Headings should only be defined once",desc:"Headings should be defined only once.",browsers:"All",init:function(e,t){var n=this,r={h1:0,h2:0,h3:0,h4:0,h5:0,h6:0};e.addListener("startrule",function(e){var i=e.selectors,s,o,u,a,f;for(a=0;a<i.length;a++){s=i[a],o=s.parts[s.parts.length-1];if(o.elementName&&/(h[1-6])/i.test(o.elementName.toString())){for(f=0;f<o.modifiers.length;f++)if(o.modifiers[f].type=="pseudo"){u=!0;break}u||(r[RegExp.$1]++,r[RegExp.$1]>1&&t.report("Heading ("+o.elementName+") has already been defined.",o.line,o.col,n))}}}),e.addListener("endstylesheet",function(e){var i,s=[];for(i in r)r.hasOwnProperty(i)&&r[i]>1&&s.push(r[i]+" "+i+"s");s.length&&t.rollupWarn("You have "+s.join(", ")+" defined in this stylesheet.",n)})}}),CSSLint.addRule({id:"universal-selector",name:"Disallow universal selector",desc:"The universal selector (*) is known to be slow.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(e){var r=e.selectors,i,s,o,u,a,f;for(u=0;u<r.length;u++)i=r[u],s=i.parts[i.parts.length-1],s.elementName=="*"&&t.report(n.desc,s.line,s.col,n)})}}),CSSLint.addRule({id:"unqualified-attributes",name:"Disallow unqualified attribute selectors",desc:"Unqualified attribute selectors are known to be slow.",browsers:"All",init:function(e,t){var n=this;e.addListener("startrule",function(r){var i=r.selectors,s,o,u,a,f,l;for(a=0;a<i.length;a++){s=i[a],o=s.parts[s.parts.length-1];if(o.type==e.SELECTOR_PART_TYPE)for(l=0;l<o.modifiers.length;l++)u=o.modifiers[l],u.type=="attribute"&&(!o.elementName||o.elementName=="*")&&t.report(n.desc,o.line,o.col,n)}})}}),CSSLint.addRule({id:"vendor-prefix",name:"Require standard property with vendor prefix",desc:"When using a vendor-prefixed property, make sure to include the standard one.",browsers:"All",init:function(e,t){function o(){r={},i=1}function u(e){var i,o,u,a,f,l,c=[];for(i in r)s[i]&&c.push({actual:i,needed:s[i]});for(o=0,u=c.length;o<u;o++)f=c[o].needed,l=c[o].actual,r[f]?r[f][0].pos<r[l][0].pos&&t.report("Standard property '"+f+"' should come after vendor-prefixed property '"+l+"'.",r[l][0].name.line,r[l][0].name.col,n):t.report("Missing standard property '"+f+"' to go along with '"+l+"'.",r[l][0].name.line,r[l][0].name.col,n)}var n=this,r,i,s={"-webkit-border-radius":"border-radius","-webkit-border-top-left-radius":"border-top-left-radius","-webkit-border-top-right-radius":"border-top-right-radius","-webkit-border-bottom-left-radius":"border-bottom-left-radius","-webkit-border-bottom-right-radius":"border-bottom-right-radius","-o-border-radius":"border-radius","-o-border-top-left-radius":"border-top-left-radius","-o-border-top-right-radius":"border-top-right-radius","-o-border-bottom-left-radius":"border-bottom-left-radius","-o-border-bottom-right-radius":"border-bottom-right-radius","-moz-border-radius":"border-radius","-moz-border-radius-topleft":"border-top-left-radius","-moz-border-radius-topright":"border-top-right-radius","-moz-border-radius-bottomleft":"border-bottom-left-radius","-moz-border-radius-bottomright":"border-bottom-right-radius","-moz-column-count":"column-count","-webkit-column-count":"column-count","-moz-column-gap":"column-gap","-webkit-column-gap":"column-gap","-moz-column-rule":"column-rule","-webkit-column-rule":"column-rule","-moz-column-rule-style":"column-rule-style","-webkit-column-rule-style":"column-rule-style","-moz-column-rule-color":"column-rule-color","-webkit-column-rule-color":"column-rule-color","-moz-column-rule-width":"column-rule-width","-webkit-column-rule-width":"column-rule-width","-moz-column-width":"column-width","-webkit-column-width":"column-width","-webkit-column-span":"column-span","-webkit-columns":"columns","-moz-box-shadow":"box-shadow","-webkit-box-shadow":"box-shadow","-moz-transform":"transform","-webkit-transform":"transform","-o-transform":"transform","-ms-transform":"transform","-moz-transform-origin":"transform-origin","-webkit-transform-origin":"transform-origin","-o-transform-origin":"transform-origin","-ms-transform-origin":"transform-origin","-moz-box-sizing":"box-sizing","-webkit-box-sizing":"box-sizing","-moz-user-select":"user-select","-khtml-user-select":"user-select","-webkit-user-select":"user-select"};e.addListener("startrule",o),e.addListener("startfontface",o),e.addListener("startpage",o),e.addListener("startpagemargin",o),e.addListener("startkeyframerule",o),e.addListener("property",function(e){var t=e.property.text.toLowerCase();r[t]||(r[t]=[]),r[t].push({name:e.property,value:e.value,pos:i++})}),e.addListener("endrule",u),e.addListener("endfontface",u),e.addListener("endpage",u),e.addListener("endpagemargin",u),e.addListener("endkeyframerule",u)}}),CSSLint.addRule({id:"zero-units",name:"Disallow units for 0 values",desc:"You don't need to specify units when a value is 0.",browsers:"All",init:function(e,t){var n=this;e.addListener("property",function(e){var r=e.value.parts,i=0,s=r.length;while(i<s)(r[i].units||r[i].type=="percentage")&&r[i].value===0&&r[i].type!="time"&&t.report("Values of 0 shouldn't have units specified.",r[i].line,r[i].col,n),i++})}}),function(){var e=function(e){return!e||e.constructor!==String?"":e.replace(/[\"&><]/g,function(e){switch(e){case'"':return"&quot;";case"&":return"&amp;";case"<":return"&lt;";case">":return"&gt;"}})};CSSLint.addFormatter({id:"checkstyle-xml",name:"Checkstyle XML format",startFormat:function(){return'<?xml version="1.0" encoding="utf-8"?><checkstyle>'},endFormat:function(){return"</checkstyle>"},readError:function(t,n){return'<file name="'+e(t)+'"><error line="0" column="0" severty="error" message="'+e(n)+'"></error></file>'},formatResults:function(t,n,r){var i=t.messages,s=[],o=function(e){return!!e&&"name"in e?"net.csslint."+e.name.replace(/\s/g,""):""};return i.length>0&&(s.push('<file name="'+n+'">'),CSSLint.Util.forEach(i,function(t,n){t.rollup||s.push('<error line="'+t.line+'" column="'+t.col+'" severity="'+t.type+'"'+' message="'+e(t.message)+'" source="'+o(t.rule)+'"/>')}),s.push("</file>")),s.join("")}})}(),CSSLint.addFormatter({id:"compact",name:"Compact, 'porcelain' format",startFormat:function(){return""},endFormat:function(){return""},formatResults:function(e,t,n){var r=e.messages,i="";n=n||{};var s=function(e){return e.charAt(0).toUpperCase()+e.slice(1)};return r.length===0?n.quiet?"":t+": Lint Free!":(CSSLint.Util.forEach(r,function(e,n){e.rollup?i+=t+": "+s(e.type)+" - "+e.message+"\n":i+=t+": "+"line "+e.line+", col "+e.col+", "+s(e.type)+" - "+e.message+" ("+e.rule.id+")\n"}),i)}}),CSSLint.addFormatter({id:"csslint-xml",name:"CSSLint XML format",startFormat:function(){return'<?xml version="1.0" encoding="utf-8"?><csslint>'},endFormat:function(){return"</csslint>"},formatResults:function(e,t,n){var r=e.messages,i=[],s=function(e){return!e||e.constructor!==String?"":e.replace(/\"/g,"'").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};return r.length>0&&(i.push('<file name="'+t+'">'),CSSLint.Util.forEach(r,function(e,t){e.rollup?i.push('<issue severity="'+e.type+'" reason="'+s(e.message)+'" evidence="'+s(e.evidence)+'"/>'):i.push('<issue line="'+e.line+'" char="'+e.col+'" severity="'+e.type+'"'+' reason="'+s(e.message)+'" evidence="'+s(e.evidence)+'"/>')}),i.push("</file>")),i.join("")}}),CSSLint.addFormatter({id:"junit-xml",name:"JUNIT XML format",startFormat:function(){return'<?xml version="1.0" encoding="utf-8"?><testsuites>'},endFormat:function(){return"</testsuites>"},formatResults:function(e,t,n){var r=e.messages,i=[],s={error:0,failure:0},o=function(e){return!!e&&"name"in e?"net.csslint."+e.name.replace(/\s/g,""):""},u=function(e){return!e||e.constructor!==String?"":e.replace(/\"/g,"'").replace(/</g,"&lt;").replace(/>/g,"&gt;")};return r.length>0&&(r.forEach(function(e,t){var n=e.type==="warning"?"error":e.type;e.rollup||(i.push('<testcase time="0" name="'+o(e.rule)+'">'),i.push("<"+n+' message="'+u(e.message)+'"><![CDATA['+e.line+":"+e.col+":"+u(e.evidence)+"]]></"+n+">"),i.push("</testcase>"),s[n]+=1)}),i.unshift('<testsuite time="0" tests="'+r.length+'" skipped="0" errors="'+s.error+'" failures="'+s.failure+'" package="net.csslint" name="'+t+'">'),i.push("</testsuite>")),i.join("")}}),CSSLint.addFormatter({id:"lint-xml",name:"Lint XML format",startFormat:function(){return'<?xml version="1.0" encoding="utf-8"?><lint>'},endFormat:function(){return"</lint>"},formatResults:function(e,t,n){var r=e.messages,i=[],s=function(e){return!e||e.constructor!==String?"":e.replace(/\"/g,"'").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};return r.length>0&&(i.push('<file name="'+t+'">'),CSSLint.Util.forEach(r,function(e,t){e.rollup?i.push('<issue severity="'+e.type+'" reason="'+s(e.message)+'" evidence="'+s(e.evidence)+'"/>'):i.push('<issue line="'+e.line+'" char="'+e.col+'" severity="'+e.type+'"'+' reason="'+s(e.message)+'" evidence="'+s(e.evidence)+'"/>')}),i.push("</file>")),i.join("")}}),CSSLint.addFormatter({id:"text",name:"Plain Text",startFormat:function(){return""},endFormat:function(){return""},formatResults:function(e,t,n){var r=e.messages,i="";n=n||{};if(r.length===0)return n.quiet?"":"\n\ncsslint: No errors in "+t+".";i="\n\ncsslint: There are "+r.length+" problems in "+t+".";var s=t.lastIndexOf("/"),o=t;return s===-1&&(s=t.lastIndexOf("\\")),s>-1&&(o=t.substring(s+1)),CSSLint.Util.forEach(r,function(e,t){i=i+"\n\n"+o,e.rollup?(i+="\n"+(t+1)+": "+e.type,i+="\n"+e.message):(i+="\n"+(t+1)+": "+e.type+" at line "+e.line+", col "+e.col,i+="\n"+e.message,i+="\n"+e.evidence)}),i}}),exports.CSSLint=CSSLint}),ace.define("ace/mode/css_worker",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/worker/mirror","ace/mode/css/csslint"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("../worker/mirror").Mirror,o=e("./css/csslint").CSSLint,u=t.Worker=function(e){s.call(this,e),this.setTimeout(400),this.ruleset=null,this.setDisabledRules("ids"),this.setInfoRules("adjoining-classes|qualified-headings|zero-units|gradients|import|outline-none")};r.inherits(u,s),function(){this.setInfoRules=function(e){typeof e=="string"&&(e=e.split("|")),this.infoRules=i.arrayToMap(e),this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.setDisabledRules=function(e){if(!e)this.ruleset=null;else{typeof e=="string"&&(e=e.split("|"));var t={};o.getRules().forEach(function(e){t[e.id]=!0}),e.forEach(function(e){delete t[e]}),this.ruleset=t}this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.onUpdate=function(){var e=this.doc.getValue();if(!e)return this.sender.emit("csslint",[]);var t=this.infoRules,n=o.verify(e,this.ruleset);this.sender.emit("csslint",n.messages.map(function(e){return{row:e.line-1,column:e.col-1,text:e.message,type:t[e.rule.id]?"info":e.type,rule:e.rule.name}}))}}.call(u.prototype)}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _="	\n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/worker-html.js b/dist/assets/js/vendor/ace-nc/worker-html.js
            new file mode 100644
            index 0000000000..816a592c59
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/worker-html.js
            @@ -0,0 +1 @@
            +"no use strict";(function(e){if(typeof e.window!="undefined"&&e.document)return;e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console,e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){console.error("Worker "+(i?i.stack:e))},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(t,n){n||(n=t,t=null);if(!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;var i=n.split("/");if(!e.require.tlns)return console.log("unable to load "+n);i[0]=e.require.tlns[i[0]]||i[0];var s=i.join("/")+".js";return e.require.id=n,importScripts(s),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id),n.length||(n=["require","exports","module"]);if(t.indexOf("text!")===0)return;var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},e.initBaseUrls=function(t){require.tlns=t},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var i=r.data;if(i.command){if(!t[i.command])throw new Error("Unknown command:"+i.command);t[i.command].apply(t,i.args)}else if(i.init){initBaseUrls(i.tlns),require("ace/lib/es5-shim"),n=e.sender=initSender();var s=require(i.module)[i.classname];t=e.main=new s(n)}else i.event&&n&&n._signal(i.event,i.data)}})(this),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]=="object"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action==="insertText")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action==="insertLines"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action==="removeText"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action=="removeLines"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[""]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},"\n"+t.join("\n")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._signal("change",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._signal("change",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._signal("change",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._signal("change",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this._insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define("ace/worker/mirror",["require","exports","module","ace/document","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../document").Document,i=e("../lib/lang"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=i.delayedCall(this.onUpdate.bind(this)),s=this;e.on("change",function(e){t.applyDeltas(e.data);if(s.$timeout)return n.schedule(s.$timeout);s.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(s.prototype)}),ace.define("ace/mode/html/saxparser",["require","exports","module"],function(e,t,n){n.exports=function r(t,n,i){function s(u,a){if(!n[u]){if(!t[u]){var f=typeof e=="function"&&e;if(!a&&f)return f(u,!0);if(o)return o(u,!0);throw new Error("Cannot find module '"+u+"'")}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return s(n?n:e)},l,l.exports,r,t,n,i)}return n[u].exports}var o=typeof e=="function"&&e;for(var u=0;u<i.length;u++)s(i[u]);return s}({1:[function(e,t,n){function r(e){if(e.namespaceURI==="http://www.w3.org/1999/xhtml")return e.localName==="applet"||e.localName==="caption"||e.localName==="marquee"||e.localName==="object"||e.localName==="table"||e.localName==="td"||e.localName==="th";if(e.namespaceURI==="http://www.w3.org/1998/Math/MathML")return e.localName==="mi"||e.localName==="mo"||e.localName==="mn"||e.localName==="ms"||e.localName==="mtext"||e.localName==="annotation-xml";if(e.namespaceURI==="http://www.w3.org/2000/svg")return e.localName==="foreignObject"||e.localName==="desc"||e.localName==="title"}function i(e){return r(e)||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="ol"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="ul"}function s(e){return e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="table"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="html"}function o(e){return e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="tbody"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="tfoot"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="thead"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="html"}function u(e){return e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="tr"||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="html"}function a(e){return r(e)||e.namespaceURI==="http://www.w3.org/1999/xhtml"&&e.localName==="button"}function f(e){return(e.namespaceURI!=="http://www.w3.org/1999/xhtml"||e.localName!=="optgroup")&&(e.namespaceURI!=="http://www.w3.org/1999/xhtml"||e.localName!=="option")}function l(){this.elements=[],this.rootNode=null,this.headElement=null,this.bodyElement=null}l.prototype._inScope=function(e,t){for(var n=this.elements.length-1;n>=0;n--){var r=this.elements[n];if(r.localName===e)return!0;if(t(r))return!1}},l.prototype.push=function(e){this.elements.push(e)},l.prototype.pushHtmlElement=function(e){this.rootNode=e.node,this.push(e)},l.prototype.pushHeadElement=function(e){this.headElement=e.node,this.push(e)},l.prototype.pushBodyElement=function(e){this.bodyElement=e.node,this.push(e)},l.prototype.pop=function(){return this.elements.pop()},l.prototype.remove=function(e){this.elements.splice(this.elements.indexOf(e),1)},l.prototype.popUntilPopped=function(e){var t;do t=this.pop();while(t.localName!=e)},l.prototype.popUntilTableScopeMarker=function(){while(!s(this.top))this.pop()},l.prototype.popUntilTableBodyScopeMarker=function(){while(!o(this.top))this.pop()},l.prototype.popUntilTableRowScopeMarker=function(){while(!u(this.top))this.pop()},l.prototype.item=function(e){return this.elements[e]},l.prototype.contains=function(e){return this.elements.indexOf(e)!==-1},l.prototype.inScope=function(e){return this._inScope(e,r)},l.prototype.inListItemScope=function(e){return this._inScope(e,i)},l.prototype.inTableScope=function(e){return this._inScope(e,s)},l.prototype.inButtonScope=function(e){return this._inScope(e,a)},l.prototype.inSelectScope=function(e){return this._inScope(e,f)},l.prototype.hasNumberedHeaderElementInScope=function(){for(var e=this.elements.length-1;e>=0;e--){var t=this.elements[e];if(t.isNumberedHeader())return!0;if(r(t))return!1}},l.prototype.furthestBlockForFormattingElement=function(e){var t=null;for(var n=this.elements.length-1;n>=0;n--){var r=this.elements[n];if(r.node===e)break;r.isSpecial()&&(t=r)}return t},l.prototype.findIndex=function(e){for(var t=this.elements.length-1;t>=0;t--)if(this.elements[t].localName==e)return t;return-1},l.prototype.remove_openElements_until=function(e){var t=!1,n;while(!t)n=this.elements.pop(),t=e(n);return n},Object.defineProperty(l.prototype,"top",{get:function(){return this.elements[this.elements.length-1]}}),Object.defineProperty(l.prototype,"length",{get:function(){return this.elements.length}}),n.ElementStack=l},{}],2:[function(e,t,n){function o(e){return e>="0"&&e<="9"||e>="a"&&e<="z"||e>="A"&&e<="Z"}function u(e){return e>="0"&&e<="9"||e>="a"&&e<="f"||e>="A"&&e<="F"}function a(e){return e>="0"&&e<="9"}var r=e("html5-entities"),i=e("./InputStream").InputStream,s={};Object.keys(r).forEach(function(e){for(var t=0;t<e.length;t++)s[e.substring(0,t+1)]=!0});var f={};f.consumeEntity=function(e,t,n){var f="",l="",c=e.char();if(c===i.EOF)return!1;l+=c;if(c=="	"||c=="\n"||c==""||c==" "||c=="<"||c=="&")return e.unget(l),!1;if(n===c)return e.unget(l),!1;if(c=="#"){c=e.shift(1);if(c===i.EOF)return t._parseError("expected-numeric-entity-but-got-eof"),e.unget(l),!1;l+=c;var h=10,p=a;if(c=="x"||c=="X"){h=16,p=u,c=e.shift(1);if(c===i.EOF)return t._parseError("expected-numeric-entity-but-got-eof"),e.unget(l),!1;l+=c}if(p(c)){var d="";while(c!==i.EOF&&p(c))d+=c,c=e.char();d=parseInt(d,h);var v=this.replaceEntityNumbers(d);v&&(t._parseError("invalid-numeric-entity-replaced"),d=v);if(d>65535&&d<=1114111){d-=65536;var m=((1047552&d)>>10)+55296,g=(1023&d)+56320;f=String.fromCharCode(m,g)}else f=String.fromCharCode(d);return c!==";"&&(t._parseError("numeric-entity-without-semicolon"),e.unget(c)),f}return e.unget(l),t._parseError("expected-numeric-entity"),!1}if(c>="a"&&c<="z"||c>="A"&&c<="Z"){var y="";while(s[l]){r[l]&&(y=l);if(c==";")break;c=e.char();if(c===i.EOF)break;l+=c}return y?(f=r[y],c===";"||!n||!o(c)&&c!=="="?(l.length>y.length&&e.unget(l.substring(y.length)),c!==";"&&t._parseError("named-entity-without-semicolon"),f):(e.unget(l),!1)):(t._parseError("expected-named-entity"),e.unget(l),!1)}},f.replaceEntityNumbers=function(e){switch(e){case 0:return 65533;case 19:return 16;case 128:return 8364;case 129:return 129;case 130:return 8218;case 131:return 402;case 132:return 8222;case 133:return 8230;case 134:return 8224;case 135:return 8225;case 136:return 710;case 137:return 8240;case 138:return 352;case 139:return 8249;case 140:return 338;case 141:return 141;case 142:return 381;case 143:return 143;case 144:return 144;case 145:return 8216;case 146:return 8217;case 147:return 8220;case 148:return 8221;case 149:return 8226;case 150:return 8211;case 151:return 8212;case 152:return 732;case 153:return 8482;case 154:return 353;case 155:return 8250;case 156:return 339;case 157:return 157;case 158:return 382;case 159:return 376;default:if(e>=55296&&e<=57343||e>1114111)return 65533;if(e>=1&&e<=8||e>=14&&e<=31||e>=127&&e<=159||e>=64976&&e<=65007||e==11||e==65534||e==131070||e==3145726||e==196607||e==262142||e==262143||e==327678||e==327679||e==393214||e==393215||e==458750||e==458751||e==524286||e==524287||e==589822||e==589823||e==655358||e==655359||e==720894||e==720895||e==786430||e==786431||e==851966||e==851967||e==917502||e==917503||e==983038||e==983039||e==1048574||e==1048575||e==1114110||e==1114111)return e}},n.EntityParser=f},{"./InputStream":3,"html5-entities":12}],3:[function(e,t,n){function r(){this.data="",this.start=0,this.committed=0,this.eof=!1,this.lastLocation={line:0,column:0}}r.EOF=-1,r.DRAIN=-2,r.prototype={slice:function(){if(this.start>=this.data.length){if(!this.eof)throw r.DRAIN;return r.EOF}return this.data.slice(this.start,this.data.length)},"char":function(){if(!this.eof&&this.start>=this.data.length-1)throw r.DRAIN;if(this.start>=this.data.length)return r.EOF;var e=this.data[this.start++];return e==="\r"&&(e="\n"),e},advance:function(e){this.start+=e;if(this.start>=this.data.length){if(!this.eof)throw r.DRAIN;return r.EOF}this.committed>this.data.length/2&&(this.lastLocation=this.location(),this.data=this.data.slice(this.committed),this.start=this.start-this.committed,this.committed=0)},matchWhile:function(e){if(this.eof&&this.start>=this.data.length)return"";var t=new RegExp("^"+e+"+"),n=t.exec(this.slice());if(n){if(!this.eof&&n[0].length==this.data.length-this.start)throw r.DRAIN;return this.advance(n[0].length),n[0]}return""},matchUntil:function(e){var t,n;n=this.slice();if(n===r.EOF)return"";if(t=(new RegExp(e+(this.eof?"|$":""))).exec(n)){var i=this.data.slice(this.start,this.start+t.index);return this.advance(t.index),i.replace(/\r/g,"\n").replace(/\n{2,}/g,"\n")}throw r.DRAIN},append:function(e){this.data+=e},shift:function(e){if(!this.eof&&this.start+e>=this.data.length)throw r.DRAIN;if(this.eof&&this.start>=this.data.length)return r.EOF;var t=this.data.slice(this.start,this.start+e).toString();return this.advance(Math.min(e,this.data.length-this.start)),t},peek:function(e){if(!this.eof&&this.start+e>=this.data.length)throw r.DRAIN;return this.eof&&this.start>=this.data.length?r.EOF:this.data.slice(this.start,Math.min(this.start+e,this.data.length)).toString()},length:function(){return this.data.length-this.start-1},unget:function(e){if(e===r.EOF)return;this.start-=e.length},undo:function(){this.start=this.committed},commit:function(){this.committed=this.start},location:function(){var e=this.lastLocation.line,t=this.lastLocation.column,n=this.data.slice(0,this.committed),r=n.match(/\n/g),i=r?e+r.length:e,s=r?n.length-n.lastIndexOf("\n")-1:t+n.length;return{line:i,column:s}}},n.InputStream=r},{}],4:[function(e,t,n){function i(e,t,n,r){this.localName=t,this.namespaceURI=e,this.attributes=n,this.node=r}function s(e,t){for(var n=0;n<e.attributes.length;n++)if(e.attributes[n].nodeName==t)return e.attributes[n].nodeValue;return null}var r={"http://www.w3.org/1999/xhtml":["address","applet","area","article","aside","base","basefont","bgsound","blockquote","body","br","button","caption","center","col","colgroup","dd","details","dir","div","dl","dt","embed","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","iframe","img","input","isindex","li","link","listing","main","marquee","menu","menuitem","meta","nav","noembed","noframes","noscript","object","ol","p","param","plaintext","pre","script","section","select","source","style","summary","table","tbody","td","textarea","tfoot","th","thead","title","tr","track","ul","wbr","xmp"],"http://www.w3.org/1998/Math/MathML":["mi","mo","mn","ms","mtext","annotation-xml"],"http://www.w3.org/2000/svg":["foreignObject","desc","title"]};i.prototype.isSpecial=function(){return this.namespaceURI in r&&r[this.namespaceURI].indexOf(this.localName)>-1},i.prototype.isFosterParenting=function(){return this.namespaceURI==="http://www.w3.org/1999/xhtml"?this.localName==="table"||this.localName==="tbody"||this.localName==="tfoot"||this.localName==="thead"||this.localName==="tr":!1},i.prototype.isNumberedHeader=function(){return this.namespaceURI==="http://www.w3.org/1999/xhtml"?this.localName==="h1"||this.localName==="h2"||this.localName==="h3"||this.localName==="h4"||this.localName==="h5"||this.localName==="h6":!1},i.prototype.isForeign=function(){return this.namespaceURI!="http://www.w3.org/1999/xhtml"},i.prototype.isHtmlIntegrationPoint=function(){if(this.namespaceURI==="http://www.w3.org/1998/Math/MathML"){if(this.localName!=="annotation-xml")return!1;var e=s(this,"encoding");return e?(e=e.toLowerCase(),e==="text/html"||e==="application/xhtml+xml"):!1}return this.namespaceURI==="http://www.w3.org/2000/svg"?this.localName==="foreignObject"||this.localName==="desc"||this.localName==="title":!1},i.prototype.isMathMLTextIntegrationPoint=function(){return this.namespaceURI==="http://www.w3.org/1998/Math/MathML"?this.localName==="mi"||this.localName==="mo"||this.localName==="mn"||this.localName==="ms"||this.localName==="mtext":!1},n.StackItem=i},{}],5:[function(e,t,n){function s(e){return e===" "||e==="\n"||e==="	"||e==="\r"||e==="\f"}function o(e){return e>="A"&&e<="Z"||e>="a"&&e<="z"}function u(e){this._tokenHandler=e,this._state=u.DATA,this._inputStream=new r,this._currentToken=null,this._temporaryBuffer="",this._additionalAllowedCharacter=""}var r=e("./InputStream").InputStream,i=e("./EntityParser").EntityParser;u.prototype._parseError=function(e,t){this._tokenHandler.parseError(e,t)},u.prototype._emitToken=function(e){if(e.type==="StartTag")for(var t=1;t<e.data.length;t++)e.data[t].nodeName||e.data.splice(t--,1);else e.type==="EndTag"&&(e.selfClosing&&this._parseError("self-closing-flag-on-end-tag"),e.data.length!==0&&this._parseError("attributes-in-end-tag"));this._tokenHandler.processToken(e),e.type==="StartTag"&&e.selfClosing&&!this._tokenHandler.isSelfClosingFlagAcknowledged()&&this._parseError("non-void-element-with-trailing-solidus",{name:e.name})},u.prototype._emitCurrentToken=function(){this._state=u.DATA,this._emitToken(this._currentToken)},u.prototype._currentAttribute=function(){return this._currentToken.data[this._currentToken.data.length-1]},u.prototype.setState=function(e){this._state=e},u.prototype.tokenize=function(e){function n(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="&")t.setState(a);else if(n==="<")t.setState(j);else if(n==="\0")t._emitToken({type:"Characters",data:n}),e.commit();else{var i=e.matchUntil("&|<|\0");t._emitToken({type:"Characters",data:n+i}),e.commit()}return!0}function a(e){var r=i.consumeEntity(e,t);return t.setState(n),t._emitToken({type:"Characters",data:r||"&"}),!0}function f(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="&")t.setState(l);else if(n==="<")t.setState(d);else if(n==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var i=e.matchUntil("&|<|\0");t._emitToken({type:"Characters",data:n+i}),e.commit()}return!0}function l(e){var n=i.consumeEntity(e,t);return t.setState(f),t._emitToken({type:"Characters",data:n||"&"}),!0}function c(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="<")t.setState(g);else if(n==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var i=e.matchUntil("<|\0");t._emitToken({type:"Characters",data:n+i})}return!0}function h(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var i=e.matchUntil("\0");t._emitToken({type:"Characters",data:n+i})}return!0}function p(e){var n=e.char();if(n===r.EOF)return t._emitToken({type:"EOF",data:null}),!1;if(n==="<")t.setState(w);else if(n==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var i=e.matchUntil("<|\0");t._emitToken({type:"Characters",data:n+i})}return!0}function d(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(v)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(f)),!0}function v(e){var n=e.char();return o(n)?(this._temporaryBuffer+=n,t.setState(m)):(t._emitToken({type:"Characters",data:"</"}),e.unget(n),t.setState(f)),!0}function m(e){var r=t._currentToken&&t._currentToken.name===this._temporaryBuffer.toLowerCase(),i=e.char();return s(i)&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t.setState(q)):i==="/"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t.setState(K)):i===">"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(n)):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:"</"+this._temporaryBuffer}),e.unget(i),t.setState(f)),!0}function g(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(y)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(c)),!0}function y(e){var n=e.char();return o(n)?(this._temporaryBuffer+=n,t.setState(b)):(t._emitToken({type:"Characters",data:"</"}),e.unget(n),t.setState(c)),!0}function b(e){var r=t._currentToken&&t._currentToken.name===this._temporaryBuffer.toLowerCase(),i=e.char();return s(i)&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t.setState(q)):i==="/"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t.setState(K)):i===">"&&r?(t._currentToken={type:"EndTag",name:this._temporaryBuffer,data:[],selfClosing:!1},t._emitCurrentToken(),t.setState(n)):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:"</"+this._temporaryBuffer}),e.unget(i),t.setState(c)),!0}function w(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(E)):n==="!"?(t._emitToken({type:"Characters",data:"<!"}),t.setState(x)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(p)),!0}function E(e){var n=e.char();return o(n)?(this._temporaryBuffer+=n,t.setState(S)):(t._emitToken({type:"Characters",data:"</"}),e.unget(n),t.setState(p)),!0}function S(e){var n=t._currentToken&&t._currentToken.name===this._temporaryBuffer.toLowerCase(),r=e.char();return s(r)&&n?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(q)):r==="/"&&n?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(K)):r===">"&&n?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t._emitCurrentToken()):o(r)?(this._temporaryBuffer+=r,e.commit()):(t._emitToken({type:"Characters",data:"</"+this._temporaryBuffer}),e.unget(r),t.setState(p)),!0}function x(e){var n=e.char();return n==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(T)):(e.unget(n),t.setState(p)),!0}function T(e){var n=e.char();return n==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(k)):(e.unget(n),t.setState(p)),!0}function N(e){var i=e.char();if(i===r.EOF)e.unget(i),t.setState(n);else if(i==="-")t._emitToken({type:"Characters",data:"-"}),t.setState(C);else if(i==="<")t.setState(L);else if(i==="\0")t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit();else{var s=e.matchUntil("<|-|\0");t._emitToken({type:"Characters",data:i+s})}return!0}function C(e){var i=e.char();return i===r.EOF?(e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(k)):i==="<"?t.setState(L):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(N)):(t._emitToken({type:"Characters",data:i}),t.setState(N)),!0}function k(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="<"?t.setState(L):i===">"?(t._emitToken({type:"Characters",data:">"}),t.setState(p)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(N)):(t._emitToken({type:"Characters",data:i}),t.setState(N)),!0}function L(e){var n=e.char();return n==="/"?(this._temporaryBuffer="",t.setState(A)):o(n)?(t._emitToken({type:"Characters",data:"<"+n}),this._temporaryBuffer=n,t.setState(M)):(t._emitToken({type:"Characters",data:"<"}),e.unget(n),t.setState(N)),!0}function A(e){var n=e.char();return o(n)?(this._temporaryBuffer=n,t.setState(O)):(t._emitToken({type:"Characters",data:"</"}),e.unget(n),t.setState(N)),!0}function O(e){var r=t._currentToken&&t._currentToken.name===this._temporaryBuffer.toLowerCase(),i=e.char();return s(i)&&r?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(q)):i==="/"&&r?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(K)):i===">"&&r?(t._currentToken={type:"EndTag",name:"script",data:[],selfClosing:!1},t.setState(n),t._emitCurrentToken()):o(i)?(this._temporaryBuffer+=i,e.commit()):(t._emitToken({type:"Characters",data:"</"+this._temporaryBuffer}),e.unget(i),t.setState(N)),!0}function M(e){var n=e.char();return s(n)||n==="/"||n===">"?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer.toLowerCase()==="script"?t.setState(_):t.setState(N)):o(n)?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer+=n,e.commit()):(e.unget(n),t.setState(N)),!0}function _(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(D)):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),e.commit()):(t._emitToken({type:"Characters",data:i}),e.commit()),!0}function D(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),t.setState(P)):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(_)):(t._emitToken({type:"Characters",data:i}),t.setState(_)),!0}function P(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-script"),e.unget(i),t.setState(n)):i==="-"?(t._emitToken({type:"Characters",data:"-"}),e.commit()):i==="<"?(t._emitToken({type:"Characters",data:"<"}),t.setState(H)):i===">"?(t._emitToken({type:"Characters",data:">"}),t.setState(p)):i==="\0"?(t._parseError("invalid-codepoint"),t._emitToken({type:"Characters",data:"\ufffd"}),t.setState(_)):(t._emitToken({type:"Characters",data:i}),t.setState(_)),!0}function H(e){var n=e.char();return n==="/"?(t._emitToken({type:"Characters",data:"/"}),this._temporaryBuffer="",t.setState(B)):(e.unget(n),t.setState(_)),!0}function B(e){var n=e.char();return s(n)||n==="/"||n===">"?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer.toLowerCase()==="script"?t.setState(N):t.setState(_)):o(n)?(t._emitToken({type:"Characters",data:n}),this._temporaryBuffer+=n,e.commit()):(e.unget(n),t.setState(_)),!0}function j(e){var i=e.char();return i===r.EOF?(t._parseError("bare-less-than-sign-at-eof"),t._emitToken({type:"Characters",data:"<"}),e.unget(i),t.setState(n)):o(i)?(t._currentToken={type:"StartTag",name:i.toLowerCase(),data:[]},t.setState(I)):i==="!"?t.setState(G):i==="/"?t.setState(F):i===">"?(t._parseError("expected-tag-name-but-got-right-bracket"),t._emitToken({type:"Characters",data:"<>"}),t.setState(n)):i==="?"?(t._parseError("expected-tag-name-but-got-question-mark"),e.unget(i),t.setState(Q)):(t._parseError("expected-tag-name"),t._emitToken({type:"Characters",data:"<"}),e.unget(i),t.setState(n)),!0}function F(e){var i=e.char();return i===r.EOF?(t._parseError("expected-closing-tag-but-got-eof"),t._emitToken({type:"Characters",data:"</"}),e.unget(i),t.setState(n)):o(i)?(t._currentToken={type:"EndTag",name:i.toLowerCase(),data:[]},t.setState(I)):i===">"?(t._parseError("expected-closing-tag-but-got-right-bracket"),t.setState(n)):(t._parseError("expected-closing-tag-but-got-char",{data:i}),e.unget(i),t.setState(Q)),!0}function I(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-tag-name"),e.unget(i),t.setState(n)):s(i)?t.setState(q):o(i)?t._currentToken.name+=i.toLowerCase():i===">"?t._emitCurrentToken():i==="/"?t.setState(K):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.name+="\ufffd"):t._currentToken.name+=i,e.commit(),!0}function q(e){var i=e.char();if(i===r.EOF)t._parseError("expected-attribute-name-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;o(i)?(t._currentToken.data.push({nodeName:i.toLowerCase(),nodeValue:""}),t.setState(R)):i===">"?t._emitCurrentToken():i==="/"?t.setState(K):i==="'"||i==='"'||i==="="||i==="<"?(t._parseError("invalid-character-in-attribute-name"),t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"\ufffd",nodeValue:""})):(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R))}return!0}function R(e){var i=e.char(),u=!0,a=!1;i===r.EOF?(t._parseError("eof-in-attribute-name"),e.unget(i),t.setState(n),a=!0):i==="="?t.setState(z):o(i)?(t._currentAttribute().nodeName+=i.toLowerCase(),u=!1):i===">"?a=!0:s(i)?t.setState(U):i==="/"?t.setState(K):i==="'"||i==='"'?(t._parseError("invalid-character-in-attribute-name"),t._currentAttribute().nodeName+=i,u=!1):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeName+="\ufffd"):(t._currentAttribute().nodeName+=i,u=!1);if(u){var f=t._currentToken.data,l=f[f.length-1];for(var c=f.length-2;c>=0;c--)if(l.nodeName===f[c].nodeName){t._parseError("duplicate-attribute",{name:l.nodeName}),l.nodeName=null;break}a&&t._emitCurrentToken()}else e.commit();return!0}function U(e){var i=e.char();if(i===r.EOF)t._parseError("expected-end-of-tag-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;i==="="?t.setState(z):i===">"?t._emitCurrentToken():o(i)?(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="/"?t.setState(K):i==="'"||i==='"'||i==="<"?(t._parseError("invalid-character-after-attribute-name"),t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data.push({nodeName:"\ufffd",nodeValue:""})):(t._currentToken.data.push({nodeName:i,nodeValue:""}),t.setState(R))}return!0}function z(e){var i=e.char();if(i===r.EOF)t._parseError("expected-attribute-value-but-got-eof"),e.unget(i),t.setState(n);else{if(s(i))return!0;i==='"'?t.setState(W):i==="&"?(t.setState(V),e.unget(i)):i==="'"?t.setState(X):i===">"?(t._parseError("expected-attribute-value-but-got-right-bracket"),t._emitCurrentToken()):i==="="||i==="<"||i==="`"?(t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=i,t.setState(V)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd"):(t._currentAttribute().nodeValue+=i,t.setState(V))}return!0}function W(e){var i=e.char();if(i===r.EOF)t._parseError("eof-in-attribute-value-double-quote"),e.unget(i),t.setState(n);else if(i==='"')t.setState(J);else if(i==="&")this._additionalAllowedCharacter='"',t.setState($);else if(i==="\0")t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd";else{var s=e.matchUntil('[\0"&]');i+=s,t._currentAttribute().nodeValue+=i}return!0}function X(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-attribute-value-single-quote"),e.unget(i),t.setState(n)):i==="'"?t.setState(J):i==="&"?(this._additionalAllowedCharacter="'",t.setState($)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd"):t._currentAttribute().nodeValue+=i+e.matchUntil("\0|['&]"),!0}function V(e){var i=e.char();if(i===r.EOF)t._parseError("eof-after-attribute-value"),e.unget(i),t.setState(n);else if(s(i))t.setState(q);else if(i==="&")this._additionalAllowedCharacter=">",t.setState($);else if(i===">")t._emitCurrentToken();else if(i==='"'||i==="'"||i==="="||i==="`"||i==="<")t._parseError("unexpected-character-in-unquoted-attribute-value"),t._currentAttribute().nodeValue+=i,e.commit();else if(i==="\0")t._parseError("invalid-codepoint"),t._currentAttribute().nodeValue+="\ufffd";else{var o=e.matchUntil("\0|[	\n\f \r&<>\"'=`]");o===r.EOF&&(t._parseError("eof-in-attribute-value-no-quotes"),t._emitCurrentToken()),e.commit(),t._currentAttribute().nodeValue+=i+o}return!0}function $(e){var n=i.consumeEntity(e,t,this._additionalAllowedCharacter);return this._currentAttribute().nodeValue+=n||"&",this._additionalAllowedCharacter==='"'?t.setState(W):this._additionalAllowedCharacter==="'"?t.setState(X):this._additionalAllowedCharacter===">"&&t.setState(V),!0}function J(e){var i=e.char();return i===r.EOF?(t._parseError("eof-after-attribute-value"),e.unget(i),t.setState(n)):s(i)?t.setState(q):i===">"?(t.setState(n),t._emitCurrentToken()):i==="/"?t.setState(K):(t._parseError("unexpected-character-after-attribute-value"),e.unget(i),t.setState(q)),!0}function K(e){var i=e.char();return i===r.EOF?(t._parseError("unexpected-eof-after-solidus-in-tag"),e.unget(i),t.setState(n)):i===">"?(t._currentToken.selfClosing=!0,t.setState(n),t._emitCurrentToken()):(t._parseError("unexpected-character-after-solidus-in-tag"),e.unget(i),t.setState(q)),!0}function Q(e){var r=e.matchUntil(">");return r=r.replace(/\u0000/g,"\ufffd"),e.char(),t._emitToken({type:"Comment",data:r}),t.setState(n),!0}function G(e){var n=e.shift(2);if(n==="--")t._currentToken={type:"Comment",data:""},t.setState(Z);else{var i=e.shift(5);if(i===r.EOF||n===r.EOF)return t._parseError("expected-dashes-or-doctype"),t.setState(Q),e.unget(n),!0;n+=i,n.toUpperCase()==="DOCTYPE"?(t._currentToken={type:"Doctype",name:"",publicId:null,systemId:null,forceQuirks:!1},t.setState(st)):t._tokenHandler.isCdataSectionAllowed()&&n==="[CDATA["?t.setState(Y):(t._parseError("expected-dashes-or-doctype"),e.unget(n),t.setState(Q))}return!0}function Y(e){var r=e.matchUntil("]]>");return e.shift(3),r&&t._emitToken({type:"Characters",data:r}),t.setState(n),!0}function Z(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(et):i===">"?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(n)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+=i,t.setState(tt)),!0}function et(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(rt):i===">"?(t._parseError("incorrect-comment"),t._emitToken(t._currentToken),t.setState(n)):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+="-"+i,t.setState(tt)),!0}function tt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(nt):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="\ufffd"):(t._currentToken.data+=i,e.commit()),!0}function nt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-end-dash"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i==="-"?t.setState(rt):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="-\ufffd",t.setState(tt)):(t._currentToken.data+="-"+i+e.matchUntil("\0|-"),e.char()),!0}function rt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-double-dash"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i===">"?(t._emitToken(t._currentToken),t.setState(n)):i==="!"?(t._parseError("unexpected-bang-after-double-dash-in-comment"),t.setState(it)):i==="-"?(t._parseError("unexpected-dash-after-double-dash-in-comment"),t._currentToken.data+=i):i==="\0"?(t._parseError("invalid-codepoint"),t._currentToken.data+="--\ufffd",t.setState(tt)):(t._parseError("unexpected-char-in-comment"),t._currentToken.data+="--"+i,t.setState(tt)),!0}function it(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-comment-end-bang-state"),t._emitToken(t._currentToken),e.unget(i),t.setState(n)):i===">"?(t._emitToken(t._currentToken),t.setState(n)):i==="-"?(t._currentToken.data+="--!",t.setState(nt)):(t._currentToken.data+="--!"+i,t.setState(tt)),!0}function st(e){var i=e.char();return i===r.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(ot):(t._parseError("need-space-after-doctype"),e.unget(i),t.setState(ot)),!0}function ot(e){var i=e.char();return i===r.EOF?(t._parseError("expected-doctype-name-but-got-eof"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)||(i===">"?(t._parseError("expected-doctype-name-but-got-right-bracket"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):(o(i)&&(i=i.toLowerCase()),t._currentToken.name=i,t.setState(ut))),!0}function ut(e){var i=e.char();return i===r.EOF?(t._currentToken.forceQuirks=!0,e.unget(i),t._parseError("eof-in-doctype-name"),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(at):i===">"?(t.setState(n),t._emitCurrentToken()):(o(i)&&(i=i.toLowerCase()),t._currentToken.name+=i,e.commit()),!0}function at(e){var i=e.char();if(i===r.EOF)t._currentToken.forceQuirks=!0,e.unget(i),t._parseError("eof-in-doctype"),t.setState(n),t._emitCurrentToken();else if(!s(i))if(i===">")t.setState(n),t._emitCurrentToken();else{if(["p","P"].indexOf(i)>-1){var o=[["u","U"],["b","B"],["l","L"],["i","I"],["c","C"]],u=o.every(function(t){return i=e.char(),t.indexOf(i)>-1});if(u)return t.setState(ft),!0}else if(["s","S"].indexOf(i)>-1){var o=[["y","Y"],["s","S"],["t","T"],["e","E"],["m","M"]],u=o.every(function(t){return i=e.char(),t.indexOf(i)>-1});if(u)return t.setState(vt),!0}e.unget(i),t._currentToken.forceQuirks=!0,i===r.EOF?(t._parseError("eof-in-doctype"),e.unget(i),t.setState(n),t._emitCurrentToken()):(t._parseError("expected-space-or-right-bracket-in-doctype",{data:i}),t.setState(wt))}return!0}function ft(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)?t.setState(lt):i==="'"||i==='"'?(t._parseError("unexpected-char-in-doctype"),e.unget(i),t.setState(lt)):(e.unget(i),t.setState(lt)),!0}function lt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):s(i)||(i==='"'?(t._currentToken.publicId="",t.setState(ct)):i==="'"?(t._currentToken.publicId="",t.setState(ht)):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function ct(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):i==='"'?t.setState(pt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):t._currentToken.publicId+=i,!0}function ht(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,e.unget(i),t.setState(n),t._emitCurrentToken()):i==="'"?t.setState(pt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t.setState(n),t._emitCurrentToken()):t._currentToken.publicId+=i,!0}function pt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)?t.setState(dt):i===">"?(t.setState(n),t._emitCurrentToken()):i==='"'?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._parseError("unexpected-char-in-doctype"),t._currentToken.systemId="",t.setState(yt)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt)),!0}function dt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i===">"?(t._emitCurrentToken(),t.setState(n)):i==='"'?(t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._currentToken.systemId="",t.setState(yt)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function vt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)?t.setState(mt):i==="'"||i==='"'?(t._parseError("unexpected-char-in-doctype"),e.unget(i),t.setState(mt)):(e.unget(i),t.setState(mt)),!0}function mt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i==='"'?(t._currentToken.systemId="",t.setState(gt)):i==="'"?(t._currentToken.systemId="",t.setState(yt)):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):(t._parseError("unexpected-char-in-doctype"),t._currentToken.forceQuirks=!0,t.setState(wt))),!0}function gt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):i==='"'?t.setState(bt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):t._currentToken.systemId+=i,!0}function yt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):i==="'"?t.setState(bt):i===">"?(t._parseError("unexpected-end-of-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),t.setState(n)):t._currentToken.systemId+=i,!0}function bt(e){var i=e.char();return i===r.EOF?(t._parseError("eof-in-doctype"),t._currentToken.forceQuirks=!0,t._emitCurrentToken(),e.unget(i),t.setState(n)):s(i)||(i===">"?(t._emitCurrentToken(),t.setState(n)):(t._parseError("unexpected-char-in-doctype"),t.setState(wt))),!0}function wt(e){var i=e.char();return i===r.EOF?(e.unget(i),t._emitCurrentToken(),t.setState(n)):i===">"&&(t._emitCurrentToken(),t.setState(n)),!0}u.DATA=n,u.RCDATA=f,u.RAWTEXT=c,u.SCRIPT_DATA=p,u.PLAINTEXT=h,this._state=u.DATA,this._inputStream.append(e),this._tokenHandler.startTokenization(this),this._inputStream.eof=!0;var t=this;while(this._state.call(this,this._inputStream));},Object.defineProperty(u.prototype,"lineNumber",{get:function(){return this._inputStream.location().line}}),Object.defineProperty(u.prototype,"columnNumber",{get:function(){return this._inputStream.location().column}}),n.Tokenizer=u},{"./EntityParser":2,"./InputStream":3}],6:[function(e,t,n){function c(e){return e===" "||e==="\n"||e==="	"||e==="\r"||e==="\f"}function h(e){return c(e)||e==="\ufffd"}function p(e){for(var t=0;t<e.length;t++){var n=e[t];if(!c(n))return!1}return!0}function d(e){for(var t=0;t<e.length;t++){var n=e[t];if(!h(n))return!1}return!0}function v(e,t){for(var n=0;n<e.attributes.length;n++){var r=e.attributes[n];if(r.nodeName===t)return r}return null}function m(e){this.characters=e,this.current=0,this.end=this.characters.length}function g(){this.tokenizer=null,this.errorHandler=null,this.scriptingEnabled=!1,this.document=null,this.head=null,this.form=null,this.openElements=new a,this.activeFormattingElements=[],this.insertionMode=null,this.insertionModeName="",this.originalInsertionMode="",this.inQuirksMode=!1,this.compatMode="no quirks",this.framesetOk=!0,this.redirectAttachToFosterParent=!1,this.selfClosingFlagAcknowledged=!1,this.context="",this.pendingTableCharacters=[],this.shouldSkipLeadingNewline=!1;var e=this,t=this.insertionModes={};t.base={end_tag_handlers:{"-default":"endTagOther"},start_tag_handlers:{"-default":"startTagOther"},processEOF:function(){e.generateImpliedEndTags(),e.openElements.length>2?e.parseError("expected-closing-tag-but-got-eof"):e.openElements.length==2&&e.openElements.item(1).localName!="body"?e.parseError("expected-closing-tag-but-got-eof"):e.context&&e.openElements.length>1},processComment:function(t){e.insertComment(t,e.currentStackItem().node)},processDoctype:function(t,n,r,i){e.parseError("unexpected-doctype")},processStartTag:function(e,t,n){if(this[this.start_tag_handlers[e]])this[this.start_tag_handlers[e]](e,t,n);else{if(!this[this.start_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.start_tag_handlers["-default"]](e,t,n)}},processEndTag:function(e){if(this[this.end_tag_handlers[e]])this[this.end_tag_handlers[e]](e);else{if(!this[this.end_tag_handlers["-default"]])throw new Error("No handler found for "+e);this[this.end_tag_handlers["-default"]](e)}},startTagHtml:function(e,n){t.inBody.startTagHtml(e,n)}},t.initial=Object.create(t.base),t.initial.processEOF=function(){e.parseError("expected-doctype-but-got-eof"),this.anythingElse(),e.insertionMode.processEOF()},t.initial.processComment=function(t){e.insertComment(t,e.document)},t.initial.processDoctype=function(t,n,r,i){function s(e){return n.toLowerCase().indexOf(e)===0}e.insertDoctype(t||"",n||"",r||""),i||t!="html"||n!=null&&(["+//silmaril//dtd html pro v0r11 19970101//","-//advasoft ltd//dtd html 3.0 aswedit + extensions//","-//as//dtd html 3.0 aswedit + extensions//","-//ietf//dtd html 2.0 level 1//","-//ietf//dtd html 2.0 level 2//","-//ietf//dtd html 2.0 strict level 1//","-//ietf//dtd html 2.0 strict level 2//","-//ietf//dtd html 2.0 strict//","-//ietf//dtd html 2.0//","-//ietf//dtd html 2.1e//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.0//","-//ietf//dtd html 3.2 final//","-//ietf//dtd html 3.2//","-//ietf//dtd html 3//","-//ietf//dtd html level 0//","-//ietf//dtd html level 0//","-//ietf//dtd html level 1//","-//ietf//dtd html level 1//","-//ietf//dtd html level 2//","-//ietf//dtd html level 2//","-//ietf//dtd html level 3//","-//ietf//dtd html level 3//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 0//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 1//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 2//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict level 3//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html strict//","-//ietf//dtd html//","-//ietf//dtd html//","-//ietf//dtd html//","-//metrius//dtd metrius presentational//","-//microsoft//dtd internet explorer 2.0 html strict//","-//microsoft//dtd internet explorer 2.0 html//","-//microsoft//dtd internet explorer 2.0 tables//","-//microsoft//dtd internet explorer 3.0 html strict//","-//microsoft//dtd internet explorer 3.0 html//","-//microsoft//dtd internet explorer 3.0 tables//","-//netscape comm. corp.//dtd html//","-//netscape comm. corp.//dtd strict html//","-//o'reilly and associates//dtd html 2.0//","-//o'reilly and associates//dtd html extended 1.0//","-//spyglass//dtd html 2.0 extended//","-//sq//dtd html 2.0 hotmetal + extensions//","-//sun microsystems corp.//dtd hotjava html//","-//sun microsystems corp.//dtd hotjava strict html//","-//w3c//dtd html 3 1995-03-24//","-//w3c//dtd html 3.2 draft//","-//w3c//dtd html 3.2 final//","-//w3c//dtd html 3.2//","-//w3c//dtd html 3.2s draft//","-//w3c//dtd html 4.0 frameset//","-//w3c//dtd html 4.0 transitional//","-//w3c//dtd html experimental 19960712//","-//w3c//dtd html experimental 970421//","-//w3c//dtd w3 html//","-//w3o//dtd w3 html 3.0//","-//webtechs//dtd mozilla html 2.0//","-//webtechs//dtd mozilla html//","html"].some(s)||["-//w3o//dtd w3 html strict 3.0//en//","-/w3c/dtd html 4.0 transitional/en","html"].indexOf(n.toLowerCase())>-1||r==null&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].some(s))||r!=null&&r.toLowerCase()=="http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"?(e.compatMode="quirks",e.parseError("quirky-doctype")):n!=null&&(["-//w3c//dtd xhtml 1.0 transitional//","-//w3c//dtd xhtml 1.0 frameset//"].some(s)||r!=null&&["-//w3c//dtd html 4.01 transitional//","-//w3c//dtd html 4.01 frameset//"].indexOf(n.toLowerCase())>-1)?(e.compatMode="limited quirks",e.parseError("almost-standards-doctype")):n=="-//W3C//DTD HTML 4.0//EN"&&(r==null||r=="http://www.w3.org/TR/REC-html40/strict.dtd")||n=="-//W3C//DTD HTML 4.01//EN"&&(r==null||r=="http://www.w3.org/TR/html4/strict.dtd")||n=="-//W3C//DTD XHTML 1.0 Strict//EN"&&r=="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"||n=="-//W3C//DTD XHTML 1.1//EN"&&r=="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"||(r!=null&&r!="about:legacy-compat"||n!=null)&&e.parseError("unknown-doctype"),e.setInsertionMode("beforeHTML")},t.initial.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;e.parseError("expected-doctype-but-got-chars"),this.anythingElse(),e.insertionMode.processCharacters(t)},t.initial.processStartTag=function(t,n,r){e.parseError("expected-doctype-but-got-start-tag",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.initial.processEndTag=function(t){e.parseError("expected-doctype-but-got-end-tag",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t)},t.initial.anythingElse=function(){e.compatMode="quirks",e.setInsertionMode("beforeHTML")},t.beforeHTML=Object.create(t.base),t.beforeHTML.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.beforeHTML.processEOF=function(){this.anythingElse(),e.insertionMode.processEOF()},t.beforeHTML.processComment=function(t){e.insertComment(t,e.document)},t.beforeHTML.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;this.anythingElse(),e.insertionMode.processCharacters(t)},t.beforeHTML.startTagHtml=function(t,n,r){e.insertHtmlElement(n),e.setInsertionMode("beforeHead")},t.beforeHTML.startTagOther=function(t,n,r){this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.beforeHTML.processEndTag=function(t){this.anythingElse(),e.insertionMode.processEndTag(t)},t.beforeHTML.anythingElse=function(){e.insertHtmlElement(),e.setInsertionMode("beforeHead")},t.afterAfterBody=Object.create(t.base),t.afterAfterBody.start_tag_handlers={html:"startTagHtml","-default":"startTagOther"},t.afterAfterBody.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterBody.processDoctype=function(e){t.inBody.processDoctype(e)},t.afterAfterBody.startTagHtml=function(e,n){t.inBody.startTagHtml(e,n)},t.afterAfterBody.startTagOther=function(t,n,r){e.parseError("unexpected-start-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,n,r)},t.afterAfterBody.endTagOther=function(t){e.parseError("unexpected-end-tag",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterAfterBody.processCharacters=function(n){if(!p(n.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(n);t.inBody.processCharacters(n)},t.afterBody=Object.create(t.base),t.afterBody.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterBody.processComment=function(t){e.insertComment(t,e.openElements.rootNode)},t.afterBody.processCharacters=function(n){if(!p(n.characters))return e.parseError("unexpected-char-after-body"),e.setInsertionMode("inBody"),e.insertionMode.processCharacters(n);t.inBody.processCharacters(n)},t.afterBody.processStartTag=function(t,n,r){e.parseError("unexpected-start-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processStartTag(t,n,r)},t.afterBody.endTagHtml=function(t){e.context?e.parseError("end-html-in-innerhtml"):e.setInsertionMode("afterAfterBody")},t.afterBody.endTagOther=function(t){e.parseError("unexpected-end-tag-after-body",{name:t}),e.setInsertionMode("inBody"),e.insertionMode.processEndTag(t)},t.afterFrameset=Object.create(t.base),t.afterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoframes","-default":"startTagOther"},t.afterFrameset.end_tag_handlers={html:"endTagHtml","-default":"endTagOther"},t.afterFrameset.processCharacters=function(t){var n=t.takeRemaining(),r="";for(var i=0;i<n.length;i++){var s=n[i];c(s)&&(r+=s)}r&&e.insertText(r),r.length<n.length&&e.parseError("expected-eof-but-got-char")},t.afterFrameset.startTagNoframes=function(e,n){t.inHead.processStartTag(e,n)},t.afterFrameset.startTagOther=function(t,n){e.parseError("unexpected-start-tag-after-frameset",{name:t})},t.afterFrameset.endTagHtml=function(t){e.setInsertionMode("afterAfterFrameset")},t.afterFrameset.endTagOther=function(t){e.parseError("unexpected-end-tag-after-frameset",{name:t})},t.beforeHead=Object.create(t.base),t.beforeHead.start_tag_handlers={html:"startTagHtml",head:"startTagHead","-default":"startTagOther"},t.beforeHead.end_tag_handlers={html:"endTagImplyHead",head:"endTagImplyHead",body:"endTagImplyHead",br:"endTagImplyHead","-default":"endTagOther"},t.beforeHead.processEOF=function(){this.startTagHead("head",[]),e.insertionMode.processEOF()},t.beforeHead.processCharacters=function(t){t.skipLeadingWhitespace();if(!t.length)return;this.startTagHead("head",[]),e.insertionMode.processCharacters(t)},t.beforeHead.startTagHead=function(t,n){e.insertHeadElement(n),e.setInsertionMode("inHead")},t.beforeHead.startTagOther=function(t,n,r){this.startTagHead("head",[]),e.insertionMode.processStartTag(t,n,r)},t.beforeHead.endTagImplyHead=function(t){this.startTagHead("head",[]),e.insertionMode.processEndTag(t)},t.beforeHead.endTagOther=function(t){e.parseError("end-tag-after-implied-root",{name:t})},t.inHead=Object.create(t.base),t.inHead.start_tag_handlers={html:"startTagHtml",head:"startTagHead",title:"startTagTitle",script:"startTagScript",style:"startTagNoFramesStyle",noscript:"startTagNoScript",noframes:"startTagNoFramesStyle",base:"startTagBaseBasefontBgsoundLink",basefont:"startTagBaseBasefontBgsoundLink",bgsound:"startTagBaseBasefontBgsoundLink",link:"startTagBaseBasefontBgsoundLink",meta:"startTagMeta","-default":"startTagOther"},t.inHead.end_tag_handlers={head:"endTagHead",html:"endTagHtmlBodyBr",body:"endTagHtmlBodyBr",br:"endTagHtmlBodyBr","-default":"endTagOther"},t.inHead.processEOF=function(){var t=e.currentStackItem().localName;["title","style","script"].indexOf(t)!=-1&&(e.parseError("expected-named-closing-tag-but-got-eof",{name:t}),e.popElement()),this.anythingElse(),e.insertionMode.processEOF()},t.inHead.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;this.anythingElse(),e.insertionMode.processCharacters(t)},t.inHead.startTagHtml=function(e,n){t.inBody.processStartTag(e,n)},t.inHead.startTagHead=function(t,n){e.parseError("two-heads-are-not-better-than-one")},t.inHead.startTagTitle=function(t,n){e.processGenericRCDATAStartTag(t,n)},t.inHead.startTagNoScript=function(t,n){if(e.scriptingEnabled)return e.processGenericRawTextStartTag(t,n);e.insertElement(t,n),e.setInsertionMode("inHeadNoscript")},t.inHead.startTagNoFramesStyle=function(t,n){e.processGenericRawTextStartTag(t,n)},t.inHead.startTagScript=function(t,n){e.insertElement(t,n),e.tokenizer.setState(u.SCRIPT_DATA),e.originalInsertionMode=e.insertionModeName,e.setInsertionMode("text")},t.inHead.startTagBaseBasefontBgsoundLink=function(t,n){e.insertSelfClosingElement(t,n)},t.inHead.startTagMeta=function(t,n){e.insertSelfClosingElement(t,n)},t.inHead.startTagOther=function(t,n,r){this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.inHead.endTagHead=function(t){e.openElements.item(e.openElements.length-1).localName=="head"?e.openElements.pop():e.parseError("unexpected-end-tag",{name:"head"}),e.setInsertionMode("afterHead")},t.inHead.endTagHtmlBodyBr=function(t){this.anythingElse(),e.insertionMode.processEndTag(t)},t.inHead.endTagOther=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inHead.anythingElse=function(){this.endTagHead("head")},t.afterHead=Object.create(t.base),t.afterHead.start_tag_handlers={html:"startTagHtml",head:"startTagHead",body:"startTagBody",frameset:"startTagFrameset",base:"startTagFromHead",link:"startTagFromHead",meta:"startTagFromHead",script:"startTagFromHead",style:"startTagFromHead",title:"startTagFromHead","-default":"startTagOther"},t.afterHead.end_tag_handlers={body:"endTagBodyHtmlBr",html:"endTagBodyHtmlBr",br:"endTagBodyHtmlBr","-default":"endTagOther"},t.afterHead.processEOF=function(){this.anythingElse(),e.insertionMode.processEOF()},t.afterHead.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;this.anythingElse(),e.insertionMode.processCharacters(t)},t.afterHead.startTagHtml=function(e,n){t.inBody.processStartTag(e,n)},t.afterHead.startTagBody=function(t,n){e.framesetOk=!1,e.insertBodyElement(n),e.setInsertionMode("inBody")},t.afterHead.startTagFrameset=function(t,n){e.insertElement(t,n),e.setInsertionMode("inFrameset")},t.afterHead.startTagFromHead=function(n,r,i){e.parseError("unexpected-start-tag-out-of-my-head",{name:n}),e.openElements.push(e.head),t.inHead.processStartTag(n,r,i),e.openElements.remove(e.head)},t.afterHead.startTagHead=function(t,n,r){e.parseError("unexpected-start-tag",{name:t})},t.afterHead.startTagOther=function(t,n,r){this.anythingElse(),e.insertionMode.processStartTag(t,n,r)},t.afterHead.endTagBodyHtmlBr=function(t){this.anythingElse(),e.insertionMode.processEndTag(t)},t.afterHead.endTagOther=function(t){e.parseError("unexpected-end-tag",{name:t})},t.afterHead.anythingElse=function(){e.insertBodyElement([]),e.setInsertionMode("inBody"),e.framesetOk=!0},t.inBody=Object.create(t.base),t.inBody.start_tag_handlers={html:"startTagHtml",head:"startTagMisplaced",base:"startTagProcessInHead",basefont:"startTagProcessInHead",bgsound:"startTagProcessInHead",link:"startTagProcessInHead",meta:"startTagProcessInHead",noframes:"startTagProcessInHead",script:"startTagProcessInHead",style:"startTagProcessInHead",title:"startTagProcessInHead",body:"startTagBody",form:"startTagForm",plaintext:"startTagPlaintext",a:"startTagA",button:"startTagButton",xmp:"startTagXmp",table:"startTagTable",hr:"startTagHr",image:"startTagImage",input:"startTagInput",textarea:"startTagTextarea",select:"startTagSelect",isindex:"startTagIsindex",applet:"startTagAppletMarqueeObject",marquee:"startTagAppletMarqueeObject",object:"startTagAppletMarqueeObject",li:"startTagListItem",dd:"startTagListItem",dt:"startTagListItem",address:"startTagCloseP",article:"startTagCloseP",aside:"startTagCloseP",blockquote:"startTagCloseP",center:"startTagCloseP",details:"startTagCloseP",dir:"startTagCloseP",div:"startTagCloseP",dl:"startTagCloseP",fieldset:"startTagCloseP",figcaption:"startTagCloseP",figure:"startTagCloseP",footer:"startTagCloseP",header:"startTagCloseP",hgroup:"startTagCloseP",main:"startTagCloseP",menu:"startTagCloseP",nav:"startTagCloseP",ol:"startTagCloseP",p:"startTagCloseP",section:"startTagCloseP",summary:"startTagCloseP",ul:"startTagCloseP",listing:"startTagPreListing",pre:"startTagPreListing",b:"startTagFormatting",big:"startTagFormatting",code:"startTagFormatting",em:"startTagFormatting",font:"startTagFormatting",i:"startTagFormatting",s:"startTagFormatting",small:"startTagFormatting",strike:"startTagFormatting",strong:"startTagFormatting",tt:"startTagFormatting",u:"startTagFormatting",nobr:"startTagNobr",area:"startTagVoidFormatting",br:"startTagVoidFormatting",embed:"startTagVoidFormatting",img:"startTagVoidFormatting",keygen:"startTagVoidFormatting",wbr:"startTagVoidFormatting",param:"startTagParamSourceTrack",source:"startTagParamSourceTrack",track:"startTagParamSourceTrack",iframe:"startTagIFrame",noembed:"startTagRawText",noscript:"startTagRawText",h1:"startTagHeading",h2:"startTagHeading",h3:"startTagHeading",h4:"startTagHeading",h5:"startTagHeading",h6:"startTagHeading",caption:"startTagMisplaced",col:"startTagMisplaced",colgroup:"startTagMisplaced",frame:"startTagMisplaced",frameset:"startTagFrameset",tbody:"startTagMisplaced",td:"startTagMisplaced",tfoot:"startTagMisplaced",th:"startTagMisplaced",thead:"startTagMisplaced",tr:"startTagMisplaced",option:"startTagOptionOptgroup",optgroup:"startTagOptionOptgroup",math:"startTagMath",svg:"startTagSVG",rt:"startTagRpRt",rp:"startTagRpRt","-default":"startTagOther"},t.inBody.end_tag_handlers={p:"endTagP",body:"endTagBody",html:"endTagHtml",address:"endTagBlock",article:"endTagBlock",aside:"endTagBlock",blockquote:"endTagBlock",button:"endTagBlock",center:"endTagBlock",details:"endTagBlock",dir:"endTagBlock",div:"endTagBlock",dl:"endTagBlock",fieldset:"endTagBlock",figcaption:"endTagBlock",figure:"endTagBlock",footer:"endTagBlock",header:"endTagBlock",hgroup:"endTagBlock",listing:"endTagBlock",main:"endTagBlock",menu:"endTagBlock",nav:"endTagBlock",ol:"endTagBlock",pre:"endTagBlock",section:"endTagBlock",summary:"endTagBlock",ul:"endTagBlock",form:"endTagForm",applet:"endTagAppletMarqueeObject",marquee:"endTagAppletMarqueeObject",object:"endTagAppletMarqueeObject",dd:"endTagListItem",dt:"endTagListItem",li:"endTagListItem",h1:"endTagHeading",h2:"endTagHeading",h3:"endTagHeading",h4:"endTagHeading",h5:"endTagHeading",h6:"endTagHeading",a:"endTagFormatting",b:"endTagFormatting",big:"endTagFormatting",code:"endTagFormatting",em:"endTagFormatting",font:"endTagFormatting",i:"endTagFormatting",nobr:"endTagFormatting",s:"endTagFormatting",small:"endTagFormatting",strike:"endTagFormatting",strong:"endTagFormatting",tt:"endTagFormatting",u:"endTagFormatting",br:"endTagBr","-default":"endTagOther"},t.inBody.processCharacters=function(t){e.shouldSkipLeadingNewline&&(e.shouldSkipLeadingNewline=!1,t.skipAtMostOneLeadingNewline()),e.reconstructActiveFormattingElements();var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.insertText(n),e.framesetOk&&!d(n)&&(e.framesetOk=!1)},t.inBody.startTagHtml=function(t,n){e.parseError("non-html-root"),e.addAttributesToElement(e.openElements.rootNode,n)},t.inBody.startTagProcessInHead=function(e,n){t.inHead.processStartTag(e,n)},t.inBody.startTagBody=function(t,n){e.parseError("unexpected-start-tag",{name:"body"}),e.openElements.length==1||e.openElements.item(1).localName!="body"?r.ok(e.context):(e.framesetOk=!1,e.addAttributesToElement(e.openElements.bodyElement,n))},t.inBody.startTagFrameset=function(t,n){e.parseError("unexpected-start-tag",{name:"frameset"});if(e.openElements.length==1||e.openElements.item(1).localName!="body")r.ok(e.context);else if(e.framesetOk){e.detachFromParent(e.openElements.bodyElement);while(e.openElements.length>1)e.openElements.pop();e.insertElement(t,n),e.setInsertionMode("inFrameset")}},t.inBody.startTagCloseP=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n)},t.inBody.startTagPreListing=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.framesetOk=!1,e.shouldSkipLeadingNewline=!0},t.inBody.startTagForm=function(t,n){e.form?e.parseError("unexpected-start-tag",{name:t}):(e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.form=e.currentStackItem())},t.inBody.startTagRpRt=function(t,n){e.openElements.inScope("ruby")&&(e.generateImpliedEndTags(),e.currentStackItem().localName!="ruby"&&e.parseError("unexpected-start-tag",{name:t})),e.insertElement(t,n)},t.inBody.startTagListItem=function(t,n){var r={li:["li"],dd:["dd","dt"],dt:["dd","dt"]},i=r[t],s=e.openElements;for(var o=s.length-1;o>=0;o--){var u=s.item(o);if(i.indexOf(u.localName)!=-1){e.insertionMode.processEndTag(u.localName);break}if(u.isSpecial()&&u.localName!=="p"&&u.localName!=="address"&&u.localName!=="div")break}e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.framesetOk=!1},t.inBody.startTagPlaintext=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertElement(t,n),e.tokenizer.setState(u.PLAINTEXT)},t.inBody.startTagHeading=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.currentStackItem().isNumberedHeader()&&(e.parseError("unexpected-start-tag",{name:t}),e.popElement()),e.insertElement(t,n)},t.inBody.startTagA=function(t,n){var r=e.elementInActiveFormattingElements("a");r&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"a",endName:"a"}),e.adoptionAgencyEndTag("a"),e.openElements.contains(r)&&e.openElements.remove(r),e.removeElementFromActiveFormattingElements(r)),e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,n)},t.inBody.startTagFormatting=function(t,n){e.reconstructActiveFormattingElements(),e.insertFormattingElement(t,n)},t.inBody.startTagNobr=function(t,n){e.reconstructActiveFormattingElements(),e.openElements.inScope("nobr")&&(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"nobr",endName:"nobr"}),this.processEndTag("nobr"),e.reconstructActiveFormattingElements()),e.insertFormattingElement(t,n)},t.inBody.startTagButton=function(t,n){e.openElements.inScope("button")?(e.parseError("unexpected-start-tag-implies-end-tag",{startName:"button",endName:"button"}),this.processEndTag("button"),e.insertionMode.processStartTag(t,n)):(e.framesetOk=!1,e.reconstructActiveFormattingElements(),e.insertElement(t,n))},t.inBody.startTagAppletMarqueeObject=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n),e.activeFormattingElements.push(l),e.framesetOk=!1},t.inBody.endTagAppletMarqueeObject=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t),e.clearActiveFormattingElements()):e.parseError("unexpected-end-tag",{name:t})},t.inBody.startTagXmp=function(t,n){e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.reconstructActiveFormattingElements(),e.processGenericRawTextStartTag(t,n),e.framesetOk=!1},t.inBody.startTagTable=function(t,n){e.compatMode!=="quirks"&&e.openElements.inButtonScope("p")&&this.processEndTag("p"),e.insertElement(t,n),e.setInsertionMode("inTable"),e.framesetOk=!1},t.inBody.startTagVoidFormatting=function(t,n){e.reconstructActiveFormattingElements(),e.insertSelfClosingElement(t,n),e.framesetOk=!1},t.inBody.startTagParamSourceTrack=function(t,n){e.insertSelfClosingElement(t,n)},t.inBody.startTagHr=function(t,n){e.openElements.inButtonScope("p")&&this.endTagP("p"),e.insertSelfClosingElement(t,n),e.framesetOk=!1},t.inBody.startTagImage=function(t,n){e.parseError("unexpected-start-tag-treated-as",{originalName:"image",newName:"img"}),this.processStartTag("img",n)},t.inBody.startTagInput=function(t,n){var r=e.framesetOk;this.startTagVoidFormatting(t,n);for(var i in n)if(n[i].nodeName=="type"){n[i].nodeValue.toLowerCase()=="hidden"&&(e.framesetOk=r);break}},t.inBody.startTagIsindex=function(t,n){e.parseError("deprecated-tag",{name:"isindex"}),e.selfClosingFlagAcknowledged=!0;if(e.form)return;var r=[],i=[],s="This is a searchable index. Enter search keywords: ";for(var o in n)switch(n[o].nodeName){case"action":r.push({nodeName:"action",nodeValue:n[o].nodeValue});break;case"prompt":s=n[o].nodeValue;break;case"name":break;default:i.push({nodeName:n[o].nodeName,nodeValue:n[o].nodeValue})}i.push({nodeName:"name",nodeValue:"isindex"}),this.processStartTag("form",r),this.processStartTag("hr"),this.processStartTag("label"),this.processCharacters(new m(s)),this.processStartTag("input",i),this.processEndTag("label"),this.processStartTag("hr"),this.processEndTag("form")},t.inBody.startTagTextarea=function(t,n){e.insertElement(t,n),e.tokenizer.setState(u.RCDATA),e.originalInsertionMode=e.insertionModeName,e.shouldSkipLeadingNewline=!0,e.framesetOk=!1,e.setInsertionMode("text")},t.inBody.startTagIFrame=function(t,n){e.framesetOk=!1,this.startTagRawText(t,n)},t.inBody.startTagRawText=function(t,n){e.processGenericRawTextStartTag(t,n)},t.inBody.startTagSelect=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n),e.framesetOk=!1;var r=e.insertionModeName;r=="inTable"||r=="inCaption"||r=="inColumnGroup"||r=="inTableBody"||r=="inRow"||r=="inCell"?e.setInsertionMode("inSelectInTable"):e.setInsertionMode("inSelect")},t.inBody.startTagMisplaced=function(t,n){e.parseError("unexpected-start-tag-ignored",{name:t})},t.inBody.endTagMisplaced=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagBr=function(t){e.parseError("unexpected-end-tag-treated-as",{originalName:"br",newName:"br element"}),e.reconstructActiveFormattingElements(),e.insertElement(t,[]),e.popElement()},t.inBody.startTagOptionOptgroup=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.reconstructActiveFormattingElements(),e.insertElement(t,n)},t.inBody.startTagOther=function(t,n){e.reconstructActiveFormattingElements(),e.insertElement(t,n)},t.inBody.endTagOther=function(t){var n;for(var r=e.openElements.length-1;r>0;r--){n=e.openElements.item(r);if(n.localName==t){e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("unexpected-end-tag",{name:t}),e.openElements.remove_openElements_until(function(e){return e===n});break}if(n.isSpecial()){e.parseError("unexpected-end-tag",{name:t});break}}},t.inBody.startTagMath=function(t,n,r){e.reconstructActiveFormattingElements(),n=e.adjustMathMLAttributes(n),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,"http://www.w3.org/1998/Math/MathML",r)},t.inBody.startTagSVG=function(t,n,r){e.reconstructActiveFormattingElements(),n=e.adjustSVGAttributes(n),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,"http://www.w3.org/2000/svg",r)},t.inBody.endTagP=function(t){e.openElements.inButtonScope("p")?(e.generateImpliedEndTags("p"),e.currentStackItem().localName!="p"&&e.parseError("unexpected-implied-end-tag",{name:"p"}),e.openElements.popUntilPopped(t)):(e.parseError("unexpected-end-tag",{name:"p"}),this.startTagCloseP("p",[]),this.endTagP("p"))},t.inBody.endTagBody=function(t){if(!e.openElements.inScope("body")){e.parseError("unexpected-end-tag",{name:t});return}e.currentStackItem().localName!="body"&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody")},t.inBody.endTagHtml=function(t){if(!e.openElements.inScope("body")){e.parseError("unexpected-end-tag",{name:t});return}e.currentStackItem().localName!="body"&&e.parseError("expected-one-end-tag-but-got-another",{expectedName:e.currentStackItem().localName,gotName:t}),e.setInsertionMode("afterBody"),e.insertionMode.processEndTag(t)},t.inBody.endTagBlock=function(t){e.openElements.inScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagForm=function(t){var n=e.form;e.form=null,!n||!e.openElements.inScope(t)?e.parseError("unexpected-end-tag",{name:t}):(e.generateImpliedEndTags(),e.currentStackItem()!=n&&e.parseError("end-tag-too-early-ignored",{name:"form"}),e.openElements.remove(n))},t.inBody.endTagListItem=function(t){e.openElements.inListItemScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.popUntilPopped(t)):e.parseError("unexpected-end-tag",{name:t})},t.inBody.endTagHeading=function(t){if(!e.openElements.hasNumberedHeaderElementInScope()){e.parseError("unexpected-end-tag",{name:t});return}e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early",{name:t}),e.openElements.remove_openElements_until(function(e){return e.isNumberedHeader()})},t.inBody.endTagFormatting=function(t,n){e.adoptionAgencyEndTag(t)||this.endTagOther(t,n)},t.inCaption=Object.create(t.base),t.inCaption.start_tag_handlers={html:"startTagHtml",caption:"startTagTableElement",col:"startTagTableElement",colgroup:"startTagTableElement",tbody:"startTagTableElement",td:"startTagTableElement",tfoot:"startTagTableElement",thead:"startTagTableElement",tr:"startTagTableElement","-default":"startTagOther"},t.inCaption.end_tag_handlers={caption:"endTagCaption",table:"endTagTable",body:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfood:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inCaption.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCaption.startTagTableElement=function(t,n){e.parseError("unexpected-end-tag",{name:t});var r=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),r||e.insertionMode.processStartTag(t,n)},t.inCaption.startTagOther=function(e,n,r){t.inBody.processStartTag(e,n,r)},t.inCaption.endTagCaption=function(t){e.openElements.inTableScope("caption")?(e.generateImpliedEndTags(),e.currentStackItem().localName!="caption"&&e.parseError("expected-one-end-tag-but-got-another",{gotName:"caption",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("caption"),e.clearActiveFormattingElements(),e.setInsertionMode("inTable")):(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inCaption.endTagTable=function(t){e.parseError("unexpected-end-table-in-caption");var n=!e.openElements.inTableScope("caption");e.insertionMode.processEndTag("caption"),n||e.insertionMode.processEndTag(t)},t.inCaption.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCaption.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell=Object.create(t.base),t.inCell.start_tag_handlers={html:"startTagHtml",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",td:"startTagTableOther",tfoot:"startTagTableOther",th:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inCell.end_tag_handlers={td:"endTagTableCell",th:"endTagTableCell",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",table:"endTagImply",tbody:"endTagImply",tfoot:"endTagImply",thead:"endTagImply",tr:"endTagImply","-default":"endTagOther"},t.inCell.processCharacters=function(e){t.inBody.processCharacters(e)},t.inCell.startTagTableOther=function(t,n,r){e.openElements.inTableScope("td")||e.openElements.inTableScope("th")?(this.closeCell(),e.insertionMode.processStartTag(t,n,r)):e.parseError("unexpected-start-tag",{name:t})},t.inCell.startTagOther=function(e,n,r){t.inBody.processStartTag(e,n,r)},t.inCell.endTagTableCell=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(t),e.currentStackItem().localName!=t.toLowerCase()?(e.parseError("unexpected-cell-end-tag",{name:t}),e.openElements.popUntilPopped(t)):e.popElement(),e.clearActiveFormattingElements(),e.setInsertionMode("inRow")):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagImply=function(t){e.openElements.inTableScope(t)?(this.closeCell(),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inCell.endTagOther=function(e){t.inBody.processEndTag(e)},t.inCell.closeCell=function(){e.openElements.inTableScope("td")?this.endTagTableCell("td"):e.openElements.inTableScope("th")&&this.endTagTableCell("th")},t.inColumnGroup=Object.create(t.base),t.inColumnGroup.start_tag_handlers={html:"startTagHtml",col:"startTagCol","-default":"startTagOther"},t.inColumnGroup.end_tag_handlers={colgroup:"endTagColgroup",col:"endTagCol","-default":"endTagOther"},t.inColumnGroup.ignoreEndTagColgroup=function(){return e.currentStackItem().localName=="html"},t.inColumnGroup.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;var r=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),r||e.insertionMode.processCharacters(t)},t.inColumnGroup.startTagCol=function(t,n){e.insertSelfClosingElement(t,n)},t.inColumnGroup.startTagOther=function(t,n,r){var i=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),i||e.insertionMode.processStartTag(t,n,r)},t.inColumnGroup.endTagColgroup=function(t){this.ignoreEndTagColgroup()?(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.popElement(),e.setInsertionMode("inTable"))},t.inColumnGroup.endTagCol=function(t){e.parseError("no-end-tag",{name:"col"})},t.inColumnGroup.endTagOther=function(t){var n=this.ignoreEndTagColgroup();this.endTagColgroup("colgroup"),n||e.insertionMode.processEndTag(t)},t.inForeignContent=Object.create(t.base),t.inForeignContent.processStartTag=function(t,n,r){if(["b","big","blockquote","body","br","center","code","dd","div","dl","dt","em","embed","h1","h2","h3","h4","h5","h6","head","hr","i","img","li","listing","menu","meta","nobr","ol","p","pre","ruby","s","small","span","strong","strike","sub","sup","table","tt","u","ul","var"].indexOf(t)!=-1||t=="font"&&n.some(function(e){return["color","face","size"].indexOf(e.nodeName)>=0})){e.parseError("unexpected-html-element-in-foreign-content",{name:t});while(e.currentStackItem().isForeign()&&!e.currentStackItem().isHtmlIntegrationPoint()&&!e.currentStackItem().isMathMLTextIntegrationPoint())e.openElements.pop();e.insertionMode.processStartTag(t,n,r);return}e.currentStackItem().namespaceURI=="http://www.w3.org/1998/Math/MathML"&&(n=e.adjustMathMLAttributes(n)),e.currentStackItem().namespaceURI=="http://www.w3.org/2000/svg"&&(t=e.adjustSVGTagNameCase(t),n=e.adjustSVGAttributes(n)),n=e.adjustForeignAttributes(n),e.insertForeignElement(t,n,e.currentStackItem().namespaceURI,r)},t.inForeignContent.processEndTag=function(t){var n=e.currentStackItem(),r=e.openElements.length-1;n.localName.toLowerCase()!=t&&e.parseError("unexpected-end-tag",{name:t});for(;;){if(r===0)break;if(n.localName.toLowerCase()==t){while(e.openElements.pop()!=n);break}r-=1,n=e.openElements.item(r);if(n.isForeign())continue;e.insertionMode.processEndTag(t);break}},t.inForeignContent.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),"\ufffd"}),e.framesetOk&&!d(n)&&(e.framesetOk=!1),e.insertText(n)},t.inHeadNoscript=Object.create(t.base),t.inHeadNoscript.start_tag_handlers={html:"startTagHtml",basefont:"startTagBasefontBgsoundLinkMetaNoframesStyle",bgsound:"startTagBasefontBgsoundLinkMetaNoframesStyle",link:"startTagBasefontBgsoundLinkMetaNoframesStyle",meta:"startTagBasefontBgsoundLinkMetaNoframesStyle",noframes:"startTagBasefontBgsoundLinkMetaNoframesStyle",style:"startTagBasefontBgsoundLinkMetaNoframesStyle",head:"startTagHeadNoscript",noscript:"startTagHeadNoscript","-default":"startTagOther"},t.inHeadNoscript.end_tag_handlers={noscript:"endTagNoscript",br:"endTagBr","-default":"endTagOther"},t.inHeadNoscript.processCharacters=function(t){var n=t.takeLeadingWhitespace();n&&e.insertText(n);if(!t.length)return;e.parseError("unexpected-char-in-frameset"),this.anythingElse(),e.insertionMode.processCharacters(t)},t.inHeadNoscript.processComment=function(e){t.inHead.processComment(e)},t.inHeadNoscript.startTagBasefontBgsoundLinkMetaNoframesStyle=function(e,n){t.inHead.processStartTag(e,n)},t.inHeadNoscript.startTagHeadNoscript=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inHeadNoscript.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processStartTag(t,n)},t.inHeadNoscript.endTagBr=function(t,n){e.parseError("unexpected-end-tag-in-frameset",{name:t}),this.anythingElse(),e.insertionMode.processEndTag(t,n)},t.inHeadNoscript.endTagNoscript=function(t,n){e.popElement(),e.setInsertionMode("inHead")},t.inHeadNoscript.endTagOther=function(t,n){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inHeadNoscript.anythingElse=function(){e.popElement(),e.setInsertionMode("inHead")},t.inFrameset=Object.create(t.base),t.inFrameset.start_tag_handlers={html:"startTagHtml",frameset:"startTagFrameset",frame:"startTagFrame",noframes:"startTagNoframes","-default":"startTagOther"},t.inFrameset.end_tag_handlers={frameset:"endTagFrameset",noframes:"endTagNoframes","-default":"endTagOther"},t.inFrameset.processCharacters=function(t){e.parseError("unexpected-char-in-frameset")},t.inFrameset.startTagFrameset=function(t,n){e.insertElement(t,n)},t.inFrameset.startTagFrame=function(t,n){e.insertSelfClosingElement(t,n)},t.inFrameset.startTagNoframes=function(e,n){t.inBody.processStartTag(e,n)},t.inFrameset.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-frameset",{name:t})},t.inFrameset.endTagFrameset=function(t,n){e.currentStackItem().localName=="html"?e.parseError("unexpected-frameset-in-frameset-innerhtml"):e.popElement(),!e.context&&e.currentStackItem().localName!="frameset"&&e.setInsertionMode("afterFrameset")},t.inFrameset.endTagNoframes=function(e){t.inBody.processEndTag(e)},t.inFrameset.endTagOther=function(t){e.parseError("unexpected-end-tag-in-frameset",{name:t})},t.inTable=Object.create(t.base),t.inTable.start_tag_handlers={html:"startTagHtml",caption:"startTagCaption",colgroup:"startTagColgroup",col:"startTagCol",table:"startTagTable",tbody:"startTagRowGroup",tfoot:"startTagRowGroup",thead:"startTagRowGroup",td:"startTagImplyTbody",th:"startTagImplyTbody",tr:"startTagImplyTbody",style:"startTagStyleScript",script:"startTagStyleScript",input:"startTagInput",form:"startTagForm","-default":"startTagOther"},t.inTable.end_tag_handlers={table:"endTagTable",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",tbody:"endTagIgnore",td:"endTagIgnore",tfoot:"endTagIgnore",th:"endTagIgnore",thead:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTable.processCharacters=function(n){if(e.currentStackItem().isFosterParenting()){var r=e.insertionModeName;e.setInsertionMode("inTableText"),e.originalInsertionMode=r,e.insertionMode.processCharacters(n)}else e.redirectAttachToFosterParent=!0,t.inBody.processCharacters(n),e.redirectAttachToFosterParent=!1},t.inTable.startTagCaption=function(t,n){e.openElements.popUntilTableScopeMarker(),e.activeFormattingElements.push(l),e.insertElement(t,n),e.setInsertionMode("inCaption")},t.inTable.startTagColgroup=function(t,n){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inColumnGroup")},t.inTable.startTagCol=function(t,n){this.startTagColgroup("colgroup",[]),e.insertionMode.processStartTag(t,n)},t.inTable.startTagRowGroup=function(t,n){e.openElements.popUntilTableScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inTableBody")},t.inTable.startTagImplyTbody=function(t,n){this.startTagRowGroup("tbody",[]),e.insertionMode.processStartTag(t,n)},t.inTable.startTagTable=function(t,n){e.parseError("unexpected-start-tag-implies-end-tag",{startName:"table",endName:"table"}),e.insertionMode.processEndTag("table"),e.context||e.insertionMode.processStartTag(t,n)},t.inTable.startTagStyleScript=function(e,n){t.inHead.processStartTag(e,n)},t.inTable.startTagInput=function(t,n){for(var r in n)if(n[r].nodeName.toLowerCase()=="type"){if(n[r].nodeValue.toLowerCase()=="hidden"){e.parseError("unexpected-hidden-input-in-table"),e.insertElement(t,n),e.openElements.pop();return}break}this.startTagOther(t,n)},t.inTable.startTagForm=function(t,n){e.parseError("unexpected-form-in-table"),e.form||(e.insertElement(t,n),e.form=e.currentStackItem(),e.openElements.pop())},t.inTable.startTagOther=function(n,r,i){e.parseError("unexpected-start-tag-implies-table-voodoo",{name:n}),e.redirectAttachToFosterParent=!0,t.inBody.processStartTag(n,r,i),e.redirectAttachToFosterParent=!1},t.inTable.endTagTable=function(t){e.openElements.inTableScope(t)?(e.generateImpliedEndTags(),e.currentStackItem().localName!=t&&e.parseError("end-tag-too-early-named",{gotName:"table",expectedName:e.currentStackItem().localName}),e.openElements.popUntilPopped("table"),e.resetInsertionMode()):(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t}))},t.inTable.endTagIgnore=function(t){e.parseError("unexpected-end-tag",{name:t})},t.inTable.endTagOther=function(n){e.parseError("unexpected-end-tag-implies-table-voodoo",{name:n}),e.redirectAttachToFosterParent=!0,t.inBody.processEndTag(n),e.redirectAttachToFosterParent=!1},t.inTableText=Object.create(t.base),t.inTableText.flushCharacters=function(){var t=e.pendingTableCharacters.join("");p(t)?e.insertText(t):(e.redirectAttachToFosterParent=!0,e.reconstructActiveFormattingElements(),e.insertText(t),e.framesetOk=!1,e.redirectAttachToFosterParent=!1),e.pendingTableCharacters=[]},t.inTableText.processComment=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processComment(t)},t.inTableText.processEOF=function(t){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEOF()},t.inTableText.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.pendingTableCharacters.push(n)},t.inTableText.processStartTag=function(t,n,r){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processStartTag(t,n,r)},t.inTableText.processEndTag=function(t,n){this.flushCharacters(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEndTag(t,n)},t.inTableBody=Object.create(t.base),t.inTableBody.start_tag_handlers={html:"startTagHtml",tr:"startTagTr",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther","-default":"startTagOther"},t.inTableBody.end_tag_handlers={table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore",tr:"endTagIgnore","-default":"endTagOther"},t.inTableBody.processCharacters=function(e){t.inTable.processCharacters(e)},t.inTableBody.startTagTr=function(t,n){e.openElements.popUntilTableBodyScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inRow")},t.inTableBody.startTagTableCell=function(t,n){e.parseError("unexpected-cell-in-table-body",{name:t}),this.startTagTr("tr",[]),e.insertionMode.processStartTag(t,n)},t.inTableBody.startTagTableOther=function(t,n){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processStartTag(t,n)):e.parseError("unexpected-start-tag",{name:t})},t.inTableBody.startTagOther=function(e,n){t.inTable.processStartTag(e,n)},t.inTableBody.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(e.openElements.popUntilTableBodyScopeMarker(),e.popElement(),e.setInsertionMode("inTable")):e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagTable=function(t){e.openElements.inTableScope("tbody")||e.openElements.inTableScope("thead")||e.openElements.inTableScope("tfoot")?(e.openElements.popUntilTableBodyScopeMarker(),this.endTagTableRowGroup(e.currentStackItem().localName),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inTableBody.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-body",{name:t})},t.inTableBody.endTagOther=function(e){t.inTable.processEndTag(e)},t.inSelect=Object.create(t.base),t.inSelect.start_tag_handlers={html:"startTagHtml",option:"startTagOption",optgroup:"startTagOptgroup",select:"startTagSelect",input:"startTagInput",keygen:"startTagInput",textarea:"startTagInput",script:"startTagScript","-default":"startTagOther"},t.inSelect.end_tag_handlers={option:"endTagOption",optgroup:"endTagOptgroup",select:"endTagSelect",caption:"endTagTableElements",table:"endTagTableElements",tbody:"endTagTableElements",tfoot:"endTagTableElements",thead:"endTagTableElements",tr:"endTagTableElements",td:"endTagTableElements",th:"endTagTableElements","-default":"endTagOther"},t.inSelect.processCharacters=function(t){var n=t.takeRemaining();n=n.replace(/\u0000/g,function(t,n){return e.parseError("invalid-codepoint"),""});if(!n)return;e.insertText(n)},t.inSelect.startTagOption=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.insertElement(t,n)},t.inSelect.startTagOptgroup=function(t,n){e.currentStackItem().localName=="option"&&e.popElement(),e.currentStackItem().localName=="optgroup"&&e.popElement(),e.insertElement(t,n)},t.inSelect.endTagOption=function(t){if(e.currentStackItem().localName!=="option"){e.parseError("unexpected-end-tag-in-select",{name:t});return}e.popElement()},t.inSelect.endTagOptgroup=function(t){e.currentStackItem().localName=="option"&&e.openElements.item(e.openElements.length-2).localName=="optgroup"&&e.popElement(),e.currentStackItem().localName=="optgroup"?e.popElement():e.parseError("unexpected-end-tag-in-select",{name:"optgroup"})},t.inSelect.startTagSelect=function(t){e.parseError("unexpected-select-in-select"),this.endTagSelect("select")},t.inSelect.endTagSelect=function(t){e.openElements.inTableScope("select")?(e.openElements.popUntilPopped("select"),e.resetInsertionMode()):e.parseError("unexpected-end-tag",{name:t})},t.inSelect.startTagInput=function(t,n){e.parseError("unexpected-input-in-select"),e.openElements.inSelectScope("select")&&(this.endTagSelect("select"),e.insertionMode.processStartTag(t,n))},t.inSelect.startTagScript=function(e,n){t.inHead.processStartTag(e,n)},t.inSelect.endTagTableElements=function(t){e.parseError("unexpected-end-tag-in-select",{name:t}),e.openElements.inTableScope(t)&&(this.endTagSelect("select"),e.insertionMode.processEndTag(t))},t.inSelect.startTagOther=function(t,n){e.parseError("unexpected-start-tag-in-select",{name:t})},t.inSelect.endTagOther=function(t){e.parseError("unexpected-end-tag-in-select",{name:t})},t.inSelectInTable=Object.create(t.base),t.inSelectInTable.start_tag_handlers={caption:"startTagTable",table:"startTagTable",tbody:"startTagTable",tfoot:"startTagTable",thead:"startTagTable",tr:"startTagTable",td:"startTagTable",th:"startTagTable","-default":"startTagOther"},t.inSelectInTable.end_tag_handlers={caption:"endTagTable",table:"endTagTable",tbody:"endTagTable",tfoot:"endTagTable",thead:"endTagTable",tr:"endTagTable",td:"endTagTable",th:"endTagTable","-default":"endTagOther"},t.inSelectInTable.processCharacters=function(e){t.inSelect.processCharacters(e)},t.inSelectInTable.startTagTable=function(t,n){e.parseError("unexpected-table-element-start-tag-in-select-in-table",{name:t}),this.endTagOther("select"),e.insertionMode.processStartTag(t,n)},t.inSelectInTable.startTagOther=function(e,n,r){t.inSelect.processStartTag(e,n,r)},t.inSelectInTable.endTagTable=function(t){e.parseError("unexpected-table-element-end-tag-in-select-in-table",{name:t}),e.openElements.inTableScope(t)&&(this.endTagOther("select"),e.insertionMode.processEndTag(t))},t.inSelectInTable.endTagOther=function(e){t.inSelect.processEndTag(e)},t.inRow=Object.create(t.base),t.inRow.start_tag_handlers={html:"startTagHtml",td:"startTagTableCell",th:"startTagTableCell",caption:"startTagTableOther",col:"startTagTableOther",colgroup:"startTagTableOther",tbody:"startTagTableOther",tfoot:"startTagTableOther",thead:"startTagTableOther",tr:"startTagTableOther","-default":"startTagOther"},t.inRow.end_tag_handlers={tr:"endTagTr",table:"endTagTable",tbody:"endTagTableRowGroup",tfoot:"endTagTableRowGroup",thead:"endTagTableRowGroup",body:"endTagIgnore",caption:"endTagIgnore",col:"endTagIgnore",colgroup:"endTagIgnore",html:"endTagIgnore",td:"endTagIgnore",th:"endTagIgnore","-default":"endTagOther"},t.inRow.processCharacters=function(e){t.inTable.processCharacters(e)},t.inRow.startTagTableCell=function(t,n){e.openElements.popUntilTableRowScopeMarker(),e.insertElement(t,n),e.setInsertionMode("inCell"),e.activeFormattingElements.push(l)},t.inRow.startTagTableOther=function(t,n){var r=this.ignoreEndTagTr();this.endTagTr("tr"),r||e.insertionMode.processStartTag(t,n)},t.inRow.startTagOther=function(e,n,r){t.inTable.processStartTag(e,n,r)},t.inRow.endTagTr=function(t){this.ignoreEndTagTr()?(r.ok(e.context),e.parseError("unexpected-end-tag",{name:t})):(e.openElements.popUntilTableRowScopeMarker(),e.popElement(),e.setInsertionMode("inTableBody"))},t.inRow.endTagTable=function(t){var n=this.ignoreEndTagTr();this.endTagTr("tr"),n||e.insertionMode.processEndTag(t)},t.inRow.endTagTableRowGroup=function(t){e.openElements.inTableScope(t)?(this.endTagTr("tr"),e.insertionMode.processEndTag(t)):e.parseError("unexpected-end-tag",{name:t})},t.inRow.endTagIgnore=function(t){e.parseError("unexpected-end-tag-in-table-row",{name:t})},t.inRow.endTagOther=function(e){t.inTable.processEndTag(e)},t.inRow.ignoreEndTagTr=function(){return!e.openElements.inTableScope("tr")},t.afterAfterFrameset=Object.create(t.base),t.afterAfterFrameset.start_tag_handlers={html:"startTagHtml",noframes:"startTagNoFrames","-default":"startTagOther"},t.afterAfterFrameset.processEOF=function(){},t.afterAfterFrameset.processComment=function(t){e.insertComment(t,e.document)},t.afterAfterFrameset.processCharacters=function(t){var n=t.takeRemaining(),r="";for(var i=0;i<n.length;i++){var s=n[i];c(s)&&(r+=s)}r&&(e.reconstructActiveFormattingElements(),e.insertText(r)),r.length<n.length&&e.parseError("expected-eof-but-got-char")},t.afterAfterFrameset.startTagNoFrames=function(e,n){t.inHead.processStartTag(e,n)},t.afterAfterFrameset.startTagOther=function(t,n,r){e.parseError("expected-eof-but-got-start-tag",{name:t})},t.afterAfterFrameset.processEndTag=function(t,n){e.parseError("expected-eof-but-got-end-tag",{name:t})},t.text=Object.create(t.base),t.text.start_tag_handlers={"-default":"startTagOther"},t.text.end_tag_handlers={script:"endTagScript","-default":"endTagOther"},t.text.processCharacters=function(t){e.shouldSkipLeadingNewline&&(e.shouldSkipLeadingNewline=!1,t.skipAtMostOneLeadingNewline());var n=t.takeRemaining();if(!n)return;e.insertText(n)},t.text.processEOF=function(){e.parseError("expected-named-closing-tag-but-got-eof",{name:e.currentStackItem().localName}),e.openElements.pop(),e.setInsertionMode(e.originalInsertionMode),e.insertionMode.processEOF()},t.text.startTagOther=function(e){throw"Tried to process start tag "+e+" in RCDATA/RAWTEXT mode"},t.text.endTagScript=function(t){var n=e.openElements.pop();r.ok(n.localName=="script"),e.setInsertionMode(e.originalInsertionMode)},t.text.endTagOther=function(t){e.openElements.pop(),e.setInsertionMode(e.originalInsertionMode)}}function y(e,t){return e.replace(new RegExp("{[0-9a-z-]+}","gi"),function(e){return t[e.slice(1,-1)]||e})}var r=e("assert"),i=e("./messages.json"),s=e("./constants"),o=e("events").EventEmitter,u=e("./Tokenizer").Tokenizer,a=e("./ElementStack").ElementStack,f=e("./StackItem").StackItem,l={};m.prototype.skipAtMostOneLeadingNewline=function(){this.characters[this.current]==="\n"&&this.current++},m.prototype.skipLeadingWhitespace=function(){while(c(this.characters[this.current]))if(++this.current==this.end)return},m.prototype.skipLeadingNonWhitespace=function(){while(!c(this.characters[this.current]))if(++this.current==this.end)return},m.prototype.takeRemaining=function(){return this.characters.substring(this.current)},m.prototype.takeLeadingWhitespace=function(){var e=this.current;return this.skipLeadingWhitespace(),e===this.current?"":this.characters.substring(e,this.current-e)},Object.defineProperty(m.prototype,"length",{get:function(){return this.end-this.current}}),g.prototype.setInsertionMode=function(e){this.insertionMode=this.insertionModes[e],this.insertionModeName=e},g.prototype.adoptionAgencyEndTag=function(e){function i(e){return e===r}var t=8,n=3,r,s=0;while(s++<t){r=this.elementInActiveFormattingElements(e);if(!r||this.openElements.contains(r)&&!this.openElements.inScope(r.localName))return this.parseError("adoption-agency-1.1",{name:e}),!1;if(!this.openElements.contains(r))return this.parseError("adoption-agency-1.2",{name:e}),this.removeElementFromActiveFormattingElements(r),!0;this.openElements.inScope(r.localName)||this.parseError("adoption-agency-4.4",{name:e}),r!=this.currentStackItem()&&this.parseError("adoption-agency-1.3",{name:e});var o=this.openElements.furthestBlockForFormattingElement(r.node);if(!o)return this.openElements.remove_openElements_until(i),this.removeElementFromActiveFormattingElements(r),!0;var u=this.openElements.elements.indexOf(r),a=this.openElements.item(u-1),l=this.activeFormattingElements.indexOf(r),c=o,h=o,p=this.openElements.elements.indexOf(c),d=0;while(d++<n){p-=1,c=this.openElements.item(p);if(this.activeFormattingElements.indexOf(c)<0){this.openElements.elements.splice(p,1);continue}if(c==r)break;h==o&&(l=this.activeFormattingElements.indexOf(c)+1);var v=this.createElement(c.namespaceURI,c.localName,c.attributes),m=new f(c.namespaceURI,c.localName,c.attributes,v);this.activeFormattingElements[this.activeFormattingElements.indexOf(c)]=m,this.openElements.elements[this.openElements.elements.indexOf(c)]=m,c=m,this.detachFromParent(h.node),this.attachNode(h.node,c.node),h=c}this.detachFromParent(h.node),a.isFosterParenting()?this.insertIntoFosterParent(h.node):this.attachNode(h.node,a.node);var v=this.createElement("http://www.w3.org/1999/xhtml",r.localName,r.attributes),g=new f(r.namespaceURI,r.localName,r.attributes,v);this.reparentChildren(o.node,v),this.attachNode(v,o.node),this.removeElementFromActiveFormattingElements(r),this.activeFormattingElements.splice(Math.min(l,this.activeFormattingElements.length),0,g),this.openElements.remove(r),this.openElements.elements.splice(this.openElements.elements.indexOf(o)+1,0,g)}return!0},g.prototype.start=function(){throw"Not mplemented"},g.prototype.startTokenization=function(e){this.tokenizer=e,this.compatMode="no quirks",this.originalInsertionMode="initial",this.framesetOk=!0,this.openElements=new a,this.activeFormattingElements=[],this.start();if(this.context){switch(this.context){case"title":case"textarea":this.tokenizer.setState(u.RCDATA);break;case"style":case"xmp":case"iframe":case"noembed":case"noframes":this.tokenizer.setState(u.RAWTEXT);break;case"script":this.tokenizer.setState(u.SCRIPT_DATA);break;case"noscript":this.scriptingEnabled&&this.tokenizer.setState(u.RAWTEXT);break;case"plaintext":this.tokenizer.setState(u.PLAINTEXT)}this.insertHtmlElement(),this.resetInsertionMode()}else this.setInsertionMode("initial")},g.prototype.processToken=function(e){this.selfClosingFlagAcknowledged=!1;var t=this.openElements.top||null,n;!t||!t.isForeign()||t.isMathMLTextIntegrationPoint()&&(e.type=="StartTag"&&!(e.name in{mglyph:0,malignmark:0})||e.type==="Characters")||t.namespaceURI=="http://www.w3.org/1998/Math/MathML"&&t.localName=="annotation-xml"&&e.type=="StartTag"&&e.name=="svg"||t.isHtmlIntegrationPoint()&&e.type in{StartTag:0,Characters:0}||e.type=="EOF"?n=this.insertionMode:n=this.insertionModes.inForeignContent;switch(e.type){case"Characters":var r=new m(e.data);n.processCharacters(r);break;case"Comment":n.processComment(e.data);break;case"StartTag":n.processStartTag(e.name,e.data,e.selfClosing);break;case"EndTag":n.processEndTag(e.name);break;case"Doctype":n.processDoctype(e.name,e.publicId,e.systemId,e.forceQuirks);break;case"EOF":n.processEOF()}},g.prototype.isCdataSectionAllowed=function(){return this.openElements.length>0&&this.currentStackItem().isForeign()},g.prototype.isSelfClosingFlagAcknowledged=function(){return this.selfClosingFlagAcknowledged},g.prototype.createElement=function(e,t,n){throw new Error("Not implemented")},g.prototype.attachNode=function(e,t){throw new Error("Not implemented")},g.prototype.attachNodeToFosterParent=function(e,t,n){throw new Error("Not implemented")},g.prototype.detachFromParent=function(e){throw new Error("Not implemented")},g.prototype.addAttributesToElement=function(e,t){throw new Error("Not implemented")},g.prototype.insertHtmlElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","html",e);return this.attachNode(t,this.document),this.openElements.pushHtmlElement(new f("http://www.w3.org/1999/xhtml","html",e,t)),t},g.prototype.insertHeadElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","head",e);return this.head=new f("http://www.w3.org/1999/xhtml","head",e,t),this.attachNode(t,this.openElements.top.node),this.openElements.pushHeadElement(this.head),t},g.prototype.insertBodyElement=function(e){var t=this.createElement("http://www.w3.org/1999/xhtml","body",e);return this.attachNode(t,this.openElements.top.node),this.openElements.pushBodyElement(new f("http://www.w3.org/1999/xhtml","body",e,t)),t},g.prototype.insertIntoFosterParent=function(e){var t=this.openElements.findIndex("table"),n=this.openElements.item(t).node;if(t===0)return this.attachNode(e,n);this.attachNodeToFosterParent(e,n,this.openElements.item(t-1).node)},g.prototype.insertElement=function(e,t,n,r){n||(n="http://www.w3.org/1999/xhtml");var i=this.createElement(n,e,t);this.shouldFosterParent()?this.insertIntoFosterParent(i):this.attachNode(i,this.openElements.top.node),r||this.openElements.push(new f(n,e,t,i))},g.prototype.insertFormattingElement=function(e,t){this.insertElement(e,t,"http://www.w3.org/1999/xhtml"),this.appendElementToActiveFormattingElements(this.currentStackItem())},g.prototype.insertSelfClosingElement=function(e,t){this.selfClosingFlagAcknowledged=!0,this.insertElement(e,t,"http://www.w3.org/1999/xhtml",!0)},g.prototype.insertForeignElement=function(e,t,n,r){r&&(this.selfClosingFlagAcknowledged=!0),this.insertElement(e,t,n,r)},g.prototype.insertComment=function(e,t){throw new Error("Not implemented")},g.prototype.insertDoctype=function(e,t,n){throw new Error("Not implemented")},g.prototype.insertText=function(e){throw new Error("Not implemented")},g.prototype.currentStackItem=function(){return this.openElements.top},g.prototype.popElement=function(){return this.openElements.pop()},g.prototype.shouldFosterParent=function(){return this.redirectAttachToFosterParent&&this.currentStackItem().isFosterParenting()},g.prototype.generateImpliedEndTags=function(e){var t=this.openElements.top.localName;["dd","dt","li","option","optgroup","p","rp","rt"].indexOf(t)!=-1&&t!=e&&(this.popElement(),this.generateImpliedEndTags(e))},g.prototype.reconstructActiveFormattingElements=function(){if(this.activeFormattingElements.length===0)return;var e=this.activeFormattingElements.length-1,t=this.activeFormattingElements[e];if(t==l||this.openElements.contains(t))return;while(t!=l&&!this.openElements.contains(t)){e-=1,t=this.activeFormattingElements[e];if(!t)break}for(;;){e+=1,t=this.activeFormattingElements[e],this.insertElement(t.localName,t.attributes);var n=this.currentStackItem();this.activeFormattingElements[e]=n;if(n==this.activeFormattingElements[this.activeFormattingElements.length-1])break}},g.prototype.ensureNoahsArkCondition=function(e){var t=3;if(this.activeFormattingElements.length<t)return;var n=[],r=e.attributes.length;for(var i=this.activeFormattingElements.length-1;i>=0;i--){var s=this.activeFormattingElements[i];if(s===l)break;if(e.localName!==s.localName||e.namespaceURI!==s.namespaceURI)continue;if(s.attributes.length!=r)continue;n.push(s)}if(n.length<t)return;var o=[],u=e.attributes;for(var i=0;i<u.length;i++){var a=u[i];for(var f=0;f<n.length;f++){var s=n[f],c=v(s,a.nodeName);c&&c.nodeValue===a.nodeValue&&o.push(s)}if(o.length<t)return;n=o,o=[]}for(var i=t-1;i<n.length;i++)this.removeElementFromActiveFormattingElements(n[i])},g.prototype.appendElementToActiveFormattingElements=function(e){this.ensureNoahsArkCondition(e),this.activeFormattingElements.push(e)},g.prototype.removeElementFromActiveFormattingElements=function(e){var t=this.activeFormattingElements.indexOf(e);t>=0&&this.activeFormattingElements.splice(t,1)},g.prototype.elementInActiveFormattingElements=function(e){var t=this.activeFormattingElements;for(var n=t.length-1;n>=0;n--){if(t[n]==l)break;if(t[n].localName==e)return t[n]}return!1},g.prototype.clearActiveFormattingElements=function(){while(this.activeFormattingElements.length!==0&&this.activeFormattingElements.pop()!=l);},g.prototype.reparentChildren=function(e,t){throw new Error("Not implemented")},g.prototype.setFragmentContext=function(e){this.context=e},g.prototype.parseError=function(e,t){if(!this.errorHandler)return;var n=y(i[e],t);this.errorHandler.error(n,this.tokenizer._inputStream.location(),e)},g.prototype.resetInsertionMode=function(){var e=!1,t=null;for(var n=this.openElements.length-1;n>=0;n--){t=this.openElements.item(n),n===0&&(r.ok(this.context),e=!0,t=new f("http://www.w3.org/1999/xhtml",this.context,[],null));if(t.namespaceURI==="http://www.w3.org/1999/xhtml"){if(t.localName==="select")return this.setInsertionMode("inSelect");if(t.localName==="td"||t.localName==="th")return this.setInsertionMode("inCell");if(t.localName==="tr")return this.setInsertionMode("inRow");if(t.localName==="tbody"||t.localName==="thead"||t.localName==="tfoot")return this.setInsertionMode("inTableBody");if(t.localName==="caption")return this.setInsertionMode("inCaption");if(t.localName==="colgroup")return this.setInsertionMode("inColumnGroup");if(t.localName==="table")return this.setInsertionMode("inTable");if(t.localName==="head"&&!e)return this.setInsertionMode("inHead");if(t.localName==="body")return this.setInsertionMode("inBody");if(t.localName==="frameset")return this.setInsertionMode("inFrameset");if(t.localName==="html")return this.openElements.headElement?this.setInsertionMode("afterHead"):this.setInsertionMode("beforeHead")}if(e)return this.setInsertionMode("inBody")}},g.prototype.processGenericRCDATAStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(u.RCDATA),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.processGenericRawTextStartTag=function(e,t){this.insertElement(e,t),this.tokenizer.setState(u.RAWTEXT),this.originalInsertionMode=this.insertionModeName,this.setInsertionMode("text")},g.prototype.adjustMathMLAttributes=function(e){return e.forEach(function(e){e.namespaceURI="http://www.w3.org/1998/Math/MathML",s.MATHMLAttributeMap[e.nodeName]&&(e.nodeName=s.MATHMLAttributeMap[e.nodeName])}),e},g.prototype.adjustSVGTagNameCase=function(e){return s.SVGTagMap[e]||e},g.prototype.adjustSVGAttributes=function(e){return e.forEach(function(e){e.namespaceURI="http://www.w3.org/2000/svg",s.SVGAttributeMap[e.nodeName]&&(e.nodeName=s.SVGAttributeMap[e.nodeName])}),e},g.prototype.adjustForeignAttributes=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.ForeignAttributeMap[n.nodeName];r&&(n.nodeName=r.localName,n.prefix=r.prefix,n.namespaceURI=r.namespaceURI)}return e},n.TreeBuilder=g},{"./ElementStack":1,"./StackItem":4,"./Tokenizer":5,"./constants":7,"./messages.json":8,assert:13,events:16}],7:[function(e,t,n){n.SVGTagMap={altglyph:"altGlyph",altglyphdef:"altGlyphDef",altglyphitem:"altGlyphItem",animatecolor:"animateColor",animatemotion:"animateMotion",animatetransform:"animateTransform",clippath:"clipPath",feblend:"feBlend",fecolormatrix:"feColorMatrix",fecomponenttransfer:"feComponentTransfer",fecomposite:"feComposite",feconvolvematrix:"feConvolveMatrix",fediffuselighting:"feDiffuseLighting",fedisplacementmap:"feDisplacementMap",fedistantlight:"feDistantLight",feflood:"feFlood",fefunca:"feFuncA",fefuncb:"feFuncB",fefuncg:"feFuncG",fefuncr:"feFuncR",fegaussianblur:"feGaussianBlur",feimage:"feImage",femerge:"feMerge",femergenode:"feMergeNode",femorphology:"feMorphology",feoffset:"feOffset",fepointlight:"fePointLight",fespecularlighting:"feSpecularLighting",fespotlight:"feSpotLight",fetile:"feTile",feturbulence:"feTurbulence",foreignobject:"foreignObject",glyphref:"glyphRef",lineargradient:"linearGradient",radialgradient:"radialGradient",textpath:"textPath"},n.MATHMLAttributeMap={definitionurl:"definitionURL"},n.SVGAttributeMap={attributename:"attributeName",attributetype:"attributeType",basefrequency:"baseFrequency",baseprofile:"baseProfile",calcmode:"calcMode",clippathunits:"clipPathUnits",contentscripttype:"contentScriptType",contentstyletype:"contentStyleType",diffuseconstant:"diffuseConstant",edgemode:"edgeMode",externalresourcesrequired:"externalResourcesRequired",filterres:"filterRes",filterunits:"filterUnits",glyphref:"glyphRef",gradienttransform:"gradientTransform",gradientunits:"gradientUnits",kernelmatrix:"kernelMatrix",kernelunitlength:"kernelUnitLength",keypoints:"keyPoints",keysplines:"keySplines",keytimes:"keyTimes",lengthadjust:"lengthAdjust",limitingconeangle:"limitingConeAngle",markerheight:"markerHeight",markerunits:"markerUnits",markerwidth:"markerWidth",maskcontentunits:"maskContentUnits",maskunits:"maskUnits",numoctaves:"numOctaves",pathlength:"pathLength",patterncontentunits:"patternContentUnits",patterntransform:"patternTransform",patternunits:"patternUnits",pointsatx:"pointsAtX",pointsaty:"pointsAtY",pointsatz:"pointsAtZ",preservealpha:"preserveAlpha",preserveaspectratio:"preserveAspectRatio",primitiveunits:"primitiveUnits",refx:"refX",refy:"refY",repeatcount:"repeatCount",repeatdur:"repeatDur",requiredextensions:"requiredExtensions",requiredfeatures:"requiredFeatures",specularconstant:"specularConstant",specularexponent:"specularExponent",spreadmethod:"spreadMethod",startoffset:"startOffset",stddeviation:"stdDeviation",stitchtiles:"stitchTiles",surfacescale:"surfaceScale",systemlanguage:"systemLanguage",tablevalues:"tableValues",targetx:"targetX",targety:"targetY",textlength:"textLength",viewbox:"viewBox",viewtarget:"viewTarget",xchannelselector:"xChannelSelector",ychannelselector:"yChannelSelector",zoomandpan:"zoomAndPan"},n.ForeignAttributeMap={"xlink:actuate":{prefix:"xlink",localName:"actuate",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:arcrole":{prefix:"xlink",localName:"arcrole",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:href":{prefix:"xlink",localName:"href",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:role":{prefix:"xlink",localName:"role",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:show":{prefix:"xlink",localName:"show",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:title":{prefix:"xlink",localName:"title",namespaceURI:"http://www.w3.org/1999/xlink"},"xlink:type":{prefix:"xlink",localName:"title",namespaceURI:"http://www.w3.org/1999/xlink"},"xml:base":{prefix:"xml",localName:"base",namespaceURI:"http://www.w3.org/XML/1998/namespace"},"xml:lang":{prefix:"xml",localName:"lang",namespaceURI:"http://www.w3.org/XML/1998/namespace"},"xml:space":{prefix:"xml",localName:"space",namespaceURI:"http://www.w3.org/XML/1998/namespace"},xmlns:{prefix:null,localName:"xmlns",namespaceURI:"http://www.w3.org/2000/xmlns/"},"xmlns:xlink":{prefix:"xmlns",localName:"xlink",namespaceURI:"http://www.w3.org/2000/xmlns/"}}},{}],8:[function(e,t,n){t.exports={"null-character":"Null character in input stream, replaced with U+FFFD.","invalid-codepoint":"Invalid codepoint in stream","incorrectly-placed-solidus":"Solidus (/) incorrectly placed in tag.","incorrect-cr-newline-entity":"Incorrect CR newline entity, replaced with LF.","illegal-windows-1252-entity":"Entity used with illegal number (windows-1252 reference).","cant-convert-numeric-entity":"Numeric entity couldn't be converted to character (codepoint U+{charAsInt}).","invalid-numeric-entity-replaced":"Numeric entity represents an illegal codepoint. Expanded to the C1 controls range.","numeric-entity-without-semicolon":"Numeric entity didn't end with ';'.","expected-numeric-entity-but-got-eof":"Numeric entity expected. Got end of file instead.","expected-numeric-entity":"Numeric entity expected but none found.","named-entity-without-semicolon":"Named entity didn't end with ';'.","expected-named-entity":"Named entity expected. Got none.","attributes-in-end-tag":"End tag contains unexpected attributes.","self-closing-flag-on-end-tag":"End tag contains unexpected self-closing flag.","bare-less-than-sign-at-eof":"End of file after <.","expected-tag-name-but-got-right-bracket":"Expected tag name. Got '>' instead.","expected-tag-name-but-got-question-mark":"Expected tag name. Got '?' instead. (HTML doesn't support processing instructions.)","expected-tag-name":"Expected tag name. Got something else instead.","expected-closing-tag-but-got-right-bracket":"Expected closing tag. Got '>' instead. Ignoring '</>'.","expected-closing-tag-but-got-eof":"Expected closing tag. Unexpected end of file.","expected-closing-tag-but-got-char":"Expected closing tag. Unexpected character '{data}' found.","eof-in-tag-name":"Unexpected end of file in the tag name.","expected-attribute-name-but-got-eof":"Unexpected end of file. Expected attribute name instead.","eof-in-attribute-name":"Unexpected end of file in attribute name.","invalid-character-in-attribute-name":"Invalid character in attribute name.","duplicate-attribute":"Dropped duplicate attribute '{name}' on tag.","expected-end-of-tag-but-got-eof":"Unexpected end of file. Expected = or end of tag.","expected-attribute-value-but-got-eof":"Unexpected end of file. Expected attribute value.","expected-attribute-value-but-got-right-bracket":"Expected attribute value. Got '>' instead.","unexpected-character-in-unquoted-attribute-value":"Unexpected character in unquoted attribute","invalid-character-after-attribute-name":"Unexpected character after attribute name.","unexpected-character-after-attribute-value":"Unexpected character after attribute value.","eof-in-attribute-value-double-quote":'Unexpected end of file in attribute value (").',"eof-in-attribute-value-single-quote":"Unexpected end of file in attribute value (').","eof-in-attribute-value-no-quotes":"Unexpected end of file in attribute value.","eof-after-attribute-value":"Unexpected end of file after attribute value.","unexpected-eof-after-solidus-in-tag":"Unexpected end of file in tag. Expected >.","unexpected-character-after-solidus-in-tag":"Unexpected character after / in tag. Expected >.","expected-dashes-or-doctype":"Expected '--' or 'DOCTYPE'. Not found.","unexpected-bang-after-double-dash-in-comment":"Unexpected ! after -- in comment.","incorrect-comment":"Incorrect comment.","eof-in-comment":"Unexpected end of file in comment.","eof-in-comment-end-dash":"Unexpected end of file in comment (-).","unexpected-dash-after-double-dash-in-comment":"Unexpected '-' after '--' found in comment.","eof-in-comment-double-dash":"Unexpected end of file in comment (--).","eof-in-comment-end-bang-state":"Unexpected end of file in comment.","unexpected-char-in-comment":"Unexpected character in comment found.","need-space-after-doctype":"No space after literal string 'DOCTYPE'.","expected-doctype-name-but-got-right-bracket":"Unexpected > character. Expected DOCTYPE name.","expected-doctype-name-but-got-eof":"Unexpected end of file. Expected DOCTYPE name.","eof-in-doctype-name":"Unexpected end of file in DOCTYPE name.","eof-in-doctype":"Unexpected end of file in DOCTYPE.","expected-space-or-right-bracket-in-doctype":"Expected space or '>'. Got '{data}'.","unexpected-end-of-doctype":"Unexpected end of DOCTYPE.","unexpected-char-in-doctype":"Unexpected character in DOCTYPE.","eof-in-bogus-doctype":"Unexpected end of file in bogus doctype.","eof-in-innerhtml":"Unexpected EOF in inner html mode.","unexpected-doctype":"Unexpected DOCTYPE. Ignored.","non-html-root":"html needs to be the first start tag.","expected-doctype-but-got-eof":"Unexpected End of file. Expected DOCTYPE.","unknown-doctype":"Erroneous DOCTYPE. Expected <!DOCTYPE html>.","quirky-doctype":"Quirky doctype. Expected <!DOCTYPE html>.","almost-standards-doctype":"Almost standards mode doctype. Expected <!DOCTYPE html>.","obsolete-doctype":"Obsolete doctype. Expected <!DOCTYPE html>.","expected-doctype-but-got-chars":"Non-space characters found without seeing a doctype first. Expected e.g. <!DOCTYPE html>.","expected-doctype-but-got-start-tag":"Start tag seen without seeing a doctype first. Expected e.g. <!DOCTYPE html>.","expected-doctype-but-got-end-tag":"End tag seen without seeing a doctype first. Expected e.g. <!DOCTYPE html>.","end-tag-after-implied-root":"Unexpected end tag ({name}) after the (implied) root element.","expected-named-closing-tag-but-got-eof":"Unexpected end of file. Expected end tag ({name}).","two-heads-are-not-better-than-one":"Unexpected start tag head in existing head. Ignored.","unexpected-end-tag":"Unexpected end tag ({name}). Ignored.","unexpected-implied-end-tag":"End tag {name} implied, but there were open elements.","unexpected-start-tag-out-of-my-head":"Unexpected start tag ({name}) that can be in head. Moved.","unexpected-start-tag":"Unexpected start tag ({name}).","missing-end-tag":"Missing end tag ({name}).","missing-end-tags":"Missing end tags ({name}).","unexpected-start-tag-implies-end-tag":"Unexpected start tag ({startName}) implies end tag ({endName}).","unexpected-start-tag-treated-as":"Unexpected start tag ({originalName}). Treated as {newName}.","deprecated-tag":"Unexpected start tag {name}. Don't use it!","unexpected-start-tag-ignored":"Unexpected start tag {name}. Ignored.","expected-one-end-tag-but-got-another":"Unexpected end tag ({gotName}). Missing end tag ({expectedName}).","end-tag-too-early":"End tag ({name}) seen too early. Expected other end tag.","end-tag-too-early-named":"Unexpected end tag ({gotName}). Expected end tag ({expectedName}.","end-tag-too-early-ignored":"End tag ({name}) seen too early. Ignored.","adoption-agency-1.1":"End tag ({name}) violates step 1, paragraph 1 of the adoption agency algorithm.","adoption-agency-1.2":"End tag ({name}) violates step 1, paragraph 2 of the adoption agency algorithm.","adoption-agency-1.3":"End tag ({name}) violates step 1, paragraph 3 of the adoption agency algorithm.","adoption-agency-4.4":"End tag ({name}) violates step 4, paragraph 4 of the adoption agency algorithm.","unexpected-end-tag-treated-as":"Unexpected end tag ({originalName}). Treated as {newName}.","no-end-tag":"This element ({name}) has no end tag.","unexpected-implied-end-tag-in-table":"Unexpected implied end tag ({name}) in the table phase.","unexpected-implied-end-tag-in-table-body":"Unexpected implied end tag ({name}) in the table body phase.","unexpected-char-implies-table-voodoo":"Unexpected non-space characters in table context caused voodoo mode.","unexpected-hidden-input-in-table":"Unexpected input with type hidden in table context.","unexpected-form-in-table":"Unexpected form in table context.","unexpected-start-tag-implies-table-voodoo":"Unexpected start tag ({name}) in table context caused voodoo mode.","unexpected-end-tag-implies-table-voodoo":"Unexpected end tag ({name}) in table context caused voodoo mode.","unexpected-cell-in-table-body":"Unexpected table cell start tag ({name}) in the table body phase.","unexpected-cell-end-tag":"Got table cell end tag ({name}) while required end tags are missing.","unexpected-end-tag-in-table-body":"Unexpected end tag ({name}) in the table body phase. Ignored.","unexpected-implied-end-tag-in-table-row":"Unexpected implied end tag ({name}) in the table row phase.","unexpected-end-tag-in-table-row":"Unexpected end tag ({name}) in the table row phase. Ignored.","unexpected-select-in-select":"Unexpected select start tag in the select phase treated as select end tag.","unexpected-input-in-select":"Unexpected input start tag in the select phase.","unexpected-start-tag-in-select":"Unexpected start tag token ({name}) in the select phase. Ignored.","unexpected-end-tag-in-select":"Unexpected end tag ({name}) in the select phase. Ignored.","unexpected-table-element-start-tag-in-select-in-table":"Unexpected table element start tag ({name}) in the select in table phase.","unexpected-table-element-end-tag-in-select-in-table":"Unexpected table element end tag ({name}) in the select in table phase.","unexpected-char-after-body":"Unexpected non-space characters in the after body phase.","unexpected-start-tag-after-body":"Unexpected start tag token ({name}) in the after body phase.","unexpected-end-tag-after-body":"Unexpected end tag token ({name}) in the after body phase.","unexpected-char-in-frameset":"Unepxected characters in the frameset phase. Characters ignored.","unexpected-start-tag-in-frameset":"Unexpected start tag token ({name}) in the frameset phase. Ignored.","unexpected-frameset-in-frameset-innerhtml":"Unexpected end tag token (frameset in the frameset phase (innerHTML).","unexpected-end-tag-in-frameset":"Unexpected end tag token ({name}) in the frameset phase. Ignored.","unexpected-char-after-frameset":"Unexpected non-space characters in the after frameset phase. Ignored.","unexpected-start-tag-after-frameset":"Unexpected start tag ({name}) in the after frameset phase. Ignored.","unexpected-end-tag-after-frameset":"Unexpected end tag ({name}) in the after frameset phase. Ignored.","expected-eof-but-got-char":"Unexpected non-space characters. Expected end of file.","expected-eof-but-got-start-tag":"Unexpected start tag ({name}). Expected end of file.","expected-eof-but-got-end-tag":"Unexpected end tag ({name}). Expected end of file.","unexpected-end-table-in-caption":"Unexpected end table tag in caption. Generates implied end caption.","end-html-in-innerhtml":"Unexpected html end tag in inner html mode.","eof-in-table":"Unexpected end of file. Expected table content.","eof-in-script":"Unexpected end of file. Expected script content.","non-void-element-with-trailing-solidus":"Trailing solidus not allowed on element {name}.","unexpected-html-element-in-foreign-content":'HTML start tag "{name}" in a foreign namespace context.',"unexpected-start-tag-in-table":"Unexpected {name}. Expected table content."}},{}],9:[function(e,t,n){function o(){this.contentHandler=null,this._errorHandler=null,this._treeBuilder=new r,this._tokenizer=new i(this._treeBuilder),this._scriptingEnabled=!1}var r=e("./SAXTreeBuilder").SAXTreeBuilder,i=e("../Tokenizer").Tokenizer,s=e("./TreeParser").TreeParser;o.prototype.parse=function(e){this._tokenizer.tokenize(e);var t=this._treeBuilder.document;t&&(new s(this.contentHandler)).parse(t)},o.prototype.parseFragment=function(e,t){this._treeBuilder.setFragmentContext(t),this._tokenizer.tokenize(e);var n=this._treeBuilder.getFragment();n&&(new s(this.contentHandler)).parse(n)},Object.defineProperty(o.prototype,"scriptingEnabled",{get:function(){return this._scriptingEnabled},set:function(e){this._scriptingEnabled=e,this._treeBuilder.scriptingEnabled=e}}),Object.defineProperty(o.prototype,"errorHandler",{get:function(){return this._errorHandler},set:function(e){this._errorHandler=e,this._treeBuilder.errorHandler=e}}),n.SAXParser=o},{"../Tokenizer":5,"./SAXTreeBuilder":10,"./TreeParser":11}],10:[function(e,t,n){function s(){i.call(this)}function o(e,t){for(var n=0;n<e.attributes.length;n++){var r=e.attributes[n];if(r.nodeName===t)return r.nodeValue}}function a(e){e?(this.columnNumber=e.columnNumber,this.lineNumber=e.lineNumber):(this.columnNumber=-1,this.lineNumber=-1),this.parentNode=null,this.nextSibling=null,this.firstChild=null}function f(e){a.call(this,e),this.lastChild=null,this._endLocator=null}function l(e){f.call(this,e),this.nodeType=u.DOCUMENT}function c(){f.call(this,new Locator),this.nodeType=u.DOCUMENT_FRAGMENT}function h(e,t,n,r,i,s){f.call(this,e),this.uri=t,this.localName=n,this.qName=r,this.attributes=i,this.prefixMappings=s,this.nodeType=u.ELEMENT}function p(e,t){a.call(this,e),this.data=t,this.nodeType=u.CHARACTERS}function d(e,t){a.call(this,e),this.data=t,this.nodeType=u.IGNORABLE_WHITESPACE}function v(e,t){a.call(this,e),this.data=t,this.nodeType=u.COMMENT}function m(e){f.call(this,e),this.nodeType=u.CDATA}function g(e){f.call(this),this.name=e,this.nodeType=u.ENTITY}function y(e){a.call(this),this.name=e,this.nodeType=u.SKIPPED_ENTITY}function b(e,t){a.call(this),this.target=e,this.data=t}function w(e,t,n){f.call(this),this.name=e,this.publicIdentifier=t,this.systemIdentifier=n,this.nodeType=u.DTD}var r=e("util"),i=e("../TreeBuilder").TreeBuilder;r.inherits(s,i),s.prototype.start=function(e){this.document=new l(this.tokenizer)},s.prototype.end=function(){this.document.endLocator=this.tokenizer},s.prototype.insertDoctype=function(e,t,n){var r=new w(this.tokenizer,e,t,n);r.endLocator=this.tokenizer,this.document.appendChild(r)},s.prototype.createElement=function(e,t,n){var r=new h(this.tokenizer,e,t,t,n||[]);return r},s.prototype.insertComment=function(e,t){t||(t=this.currentStackItem());var n=new v(this.tokenizer,e);t.appendChild(n)},s.prototype.appendCharacters=function(e,t){var n=new p(this.tokenizer,t);e.appendChild(n)},s.prototype.insertText=function(e){if(this.redirectAttachToFosterParent&&this.openElements.top.isFosterParenting()){var t=this.openElements.findIndex("table"),n=this.openElements.item(t),r=n.node;if(t===0)return this.appendCharacters(r,e);var i=new p(this.tokenizer,e),s=r.parentNode;if(s){s.insertBetween(i,r.previousSibling,r);return}var o=this.openElements.item(t-1).node;o.appendChild(i);return}this.appendCharacters(this.currentStackItem().node,e)},s.prototype.attachNode=function(e,t){t.appendChild(e)},s.prototype.attachNodeToFosterParent=function(e,t,n){var r=t.parentNode;r?r.insertBetween(e,t.previousSibling,t):n.appendChild(e)},s.prototype.detachFromParent=function(e){e.detach()},s.prototype.reparentChildren=function(e,t){t.appendChildren(e.firstChild)},s.prototype.getFragment=function(){var e=new c;return this.reparentChildren(this.openElements.rootNode,e),e},s.prototype.addAttributesToElement=function(e,t){for(var n=0;n<t.length;n++){var r=t[n];o(e,r.nodeName)||e.attributes.push(r)}};var u={CDATA:1,CHARACTERS:2,COMMENT:3,DOCUMENT:4,DOCUMENT_FRAGMENT:5,DTD:6,ELEMENT:7,ENTITY:8,IGNORABLE_WHITESPACE:9,PROCESSING_INSTRUCTION:10,SKIPPED_ENTITY:11};a.prototype.visit=function(e){throw new Error("Not Implemented")},a.prototype.revisit=function(e){return},a.prototype.detach=function(){this.parentNode!==null&&(this.parentNode.removeChild(this),this.parentNode=null)},Object.defineProperty(a.prototype,"previousSibling",{get:function(){var e=null,t=this.parentNode.firstChild;for(;;){if(this==t)return e;e=t,t=t.nextSibling}}}),f.prototype=Object.create(a.prototype),f.prototype.insertBefore=function(e,t){if(!t)return this.appendChild(e);e.detach(),e.parentNode=this;if(this.firstChild==t)e.nextSibling=t,this.firstChild=e;else{var n=this.firstChild,r=this.firstChild.nextSibling;while(r!=t)n=r,r=r.nextSibling;n.nextSibling=e,e.nextSibling=r}return e},f.prototype.insertBetween=function(e,t,n){return n?(e.detach(),e.parentNode=this,e.nextSibling=n,t?t.nextSibling=e:firstChild=e,e):this.appendChild(e)},f.prototype.appendChild=function(e){return e.detach(),e.parentNode=this,this.firstChild?this.lastChild.nextSibling=e:this.firstChild=e,this.lastChild=e,e},f.prototype.appendChildren=function(e){var t=e.firstChild;if(!t)return;var n=e;this.firstChild?this.lastChild.nextSibling=t:this.firstChild=t,this.lastChild=n.lastChild;do t.parentNode=this;while(t=t.nextSibling);n.firstChild=null,n.lastChild=null},f.prototype.removeChild=function(e){if(this.firstChild==e)this.firstChild=e.nextSibling,this.lastChild==e&&(this.lastChild=null);else{var t=this.firstChild,n=this.firstChild.nextSibling;while(n!=e)t=n,n=n.nextSibling;t.nextSibling=e.nextSibling,this.lastChild==e&&(this.lastChild=t)}return e.parentNode=null,e},Object.defineProperty(f.prototype,"endLocator",{get:function(){return this._endLocator},set:function(e){this._endLocator={lineNumber:e.lineNumber,columnNumber:e.columnNumber}}}),l.prototype=Object.create(f.prototype),l.prototype.visit=function(e){e.startDocument(this)},l.prototype.revisit=function(e){e.endDocument(this.endLocator)},c.prototype=Object.create(f.prototype),c.prototype.visit=function(e){},h.prototype=Object.create(f.prototype),h.prototype.visit=function(e){if(this.prefixMappings)for(var t in prefixMappings){var n=prefixMappings[t];e.startPrefixMapping(n.getPrefix(),n.getUri(),this)}e.startElement(this.uri,this.localName,this.qName,this.attributes,this)},h.prototype.revisit=function(e){e.endElement(this.uri,this.localName,this.qName,this.endLocator);if(this.prefixMappings)for(var t in prefixMappings){var n=prefixMappings[t];e.endPrefixMapping(n.getPrefix(),this.endLocator)}},p.prototype=Object.create(a.prototype),p.prototype.visit=function(e){e.characters(this.data,0,this.data.length,this)},d.prototype=Object.create(a.prototype),d.prototype.visit=function(e){e.ignorableWhitespace(this.data,0,this.data.length,this)},v.prototype=Object.create(a.prototype),v.prototype.visit=function(e){e.comment(this.data,0,this.data.length,this)},m.prototype=Object.create(f.prototype),m.prototype.visit=function(e){e.startCDATA(this)},m.prototype.revisit=function(e){e.endCDATA(this.endLocator)},g.prototype=Object.create(f.prototype),g.prototype.visit=function(e){e.startEntity(this.name,this)},g.prototype.revisit=function(e){e.endEntity(this.name)},y.prototype=Object.create(a.prototype),y.prototype.visit=function(e){e.skippedEntity(this.name,this)},b.prototype=Object.create(a.prototype),b.prototype.visit=function(e){e.processingInstruction(this.target,this.data,this)},b.prototype.getNodeType=function(){return u.PROCESSING_INSTRUCTION},w.prototype=Object.create(f.prototype),w.prototype.visit=function(e){e.startDTD(this.name,this.publicIdentifier,this.systemIdentifier,this)},w.prototype.revisit=function(e){e.endDTD()},n.SAXTreeBuilder=s},{"../TreeBuilder":6,util:20}],11:[function(e,t,n){function r(e,t){this.contentHandler,this.lexicalHandler,this.locatorDelegate;if(!e)throw new IllegalArgumentException("contentHandler was null.");this.contentHandler=e,t?this.lexicalHandler=t:this.lexicalHandler=new i}function i(){}r.prototype.parse=function(e){this.contentHandler.documentLocator=this;var t=e,n;for(;;){t.visit(this);if(n=t.firstChild){t=n;continue}for(;;){t.revisit(this);if(t==e)return;if(n=t.nextSibling){t=n;break}t=t.parentNode}}},r.prototype.characters=function(e,t,n,r){this.locatorDelegate=r,this.contentHandler.characters(e,t,n)},r.prototype.endDocument=function(e){this.locatorDelegate=e,this.contentHandler.endDocument()},r.prototype.endElement=function(e,t,n,r){this.locatorDelegate=r,this.contentHandler.endElement(e,t,n)},r.prototype.endPrefixMapping=function(e,t){this.locatorDelegate=t,this.contentHandler.endPrefixMapping(e)},r.prototype.ignorableWhitespace=function(e,t,n,r){this.locatorDelegate=r,this.contentHandler.ignorableWhitespace(e,t,n)},r.prototype.processingInstruction=function(e,t,n){this.locatorDelegate=n,this.contentHandler.processingInstruction(e,t)},r.prototype.skippedEntity=function(e,t){this.locatorDelegate=t,this.contentHandler.skippedEntity(e)},r.prototype.startDocument=function(e){this.locatorDelegate=e,this.contentHandler.startDocument()},r.prototype.startElement=function(e,t,n,r,i){this.locatorDelegate=i,this.contentHandler.startElement(e,t,n,r)},r.prototype.startPrefixMapping=function(e,t,n){this.locatorDelegate=n,this.contentHandler.startPrefixMapping(e,t)},r.prototype.comment=function(e,t,n,r){this.locatorDelegate=r,this.lexicalHandler.comment(e,t,n)},r.prototype.endCDATA=function(e){this.locatorDelegate=e,this.lexicalHandler.endCDATA()},r.prototype.endDTD=function(e){this.locatorDelegate=e,this.lexicalHandler.endDTD()},r.prototype.endEntity=function(e,t){this.locatorDelegate=t,this.lexicalHandler.endEntity(e)},r.prototype.startCDATA=function(e){this.locatorDelegate=e,this.lexicalHandler.startCDATA()},r.prototype.startDTD=function(e,t,n,r){this.locatorDelegate=r,this.lexicalHandler.startDTD(e,t,n)},r.prototype.startEntity=function(e,t){this.locatorDelegate=t,this.lexicalHandler.startEntity(e)},Object.defineProperty(r.prototype,"columnNumber",{get:function(){return this.locatorDelegate?this.locatorDelegate.columnNumber:-1}}),Object.defineProperty(r.prototype,"lineNumber",{get:function(){return this.locatorDelegate?this.locatorDelegate.lineNumber:-1}}),i.prototype.comment=function(){},i.prototype.endCDATA=function(){},i.prototype.endDTD=function(){},i.prototype.endEntity=function(){},i.prototype.startCDATA=function(){},i.prototype.startDTD=function(){},i.prototype.startEntity=function(){},n.TreeParser=r},{}],12:[function(e,t,n){t.exports={"Aacute;":"\u00c1",Aacute:"\u00c1","aacute;":"\u00e1",aacute:"\u00e1","Abreve;":"\u0102","abreve;":"\u0103","ac;":"\u223e","acd;":"\u223f","acE;":"\u223e\u0333","Acirc;":"\u00c2",Acirc:"\u00c2","acirc;":"\u00e2",acirc:"\u00e2","acute;":"\u00b4",acute:"\u00b4","Acy;":"\u0410","acy;":"\u0430","AElig;":"\u00c6",AElig:"\u00c6","aelig;":"\u00e6",aelig:"\u00e6","af;":"\u2061","Afr;":"\ud835\udd04","afr;":"\ud835\udd1e","Agrave;":"\u00c0",Agrave:"\u00c0","agrave;":"\u00e0",agrave:"\u00e0","alefsym;":"\u2135","aleph;":"\u2135","Alpha;":"\u0391","alpha;":"\u03b1","Amacr;":"\u0100","amacr;":"\u0101","amalg;":"\u2a3f","amp;":"&",amp:"&","AMP;":"&",AMP:"&","andand;":"\u2a55","And;":"\u2a53","and;":"\u2227","andd;":"\u2a5c","andslope;":"\u2a58","andv;":"\u2a5a","ang;":"\u2220","ange;":"\u29a4","angle;":"\u2220","angmsdaa;":"\u29a8","angmsdab;":"\u29a9","angmsdac;":"\u29aa","angmsdad;":"\u29ab","angmsdae;":"\u29ac","angmsdaf;":"\u29ad","angmsdag;":"\u29ae","angmsdah;":"\u29af","angmsd;":"\u2221","angrt;":"\u221f","angrtvb;":"\u22be","angrtvbd;":"\u299d","angsph;":"\u2222","angst;":"\u00c5","angzarr;":"\u237c","Aogon;":"\u0104","aogon;":"\u0105","Aopf;":"\ud835\udd38","aopf;":"\ud835\udd52","apacir;":"\u2a6f","ap;":"\u2248","apE;":"\u2a70","ape;":"\u224a","apid;":"\u224b","apos;":"'","ApplyFunction;":"\u2061","approx;":"\u2248","approxeq;":"\u224a","Aring;":"\u00c5",Aring:"\u00c5","aring;":"\u00e5",aring:"\u00e5","Ascr;":"\ud835\udc9c","ascr;":"\ud835\udcb6","Assign;":"\u2254","ast;":"*","asymp;":"\u2248","asympeq;":"\u224d","Atilde;":"\u00c3",Atilde:"\u00c3","atilde;":"\u00e3",atilde:"\u00e3","Auml;":"\u00c4",Auml:"\u00c4","auml;":"\u00e4",auml:"\u00e4","awconint;":"\u2233","awint;":"\u2a11","backcong;":"\u224c","backepsilon;":"\u03f6","backprime;":"\u2035","backsim;":"\u223d","backsimeq;":"\u22cd","Backslash;":"\u2216","Barv;":"\u2ae7","barvee;":"\u22bd","barwed;":"\u2305","Barwed;":"\u2306","barwedge;":"\u2305","bbrk;":"\u23b5","bbrktbrk;":"\u23b6","bcong;":"\u224c","Bcy;":"\u0411","bcy;":"\u0431","bdquo;":"\u201e","becaus;":"\u2235","because;":"\u2235","Because;":"\u2235","bemptyv;":"\u29b0","bepsi;":"\u03f6","bernou;":"\u212c","Bernoullis;":"\u212c","Beta;":"\u0392","beta;":"\u03b2","beth;":"\u2136","between;":"\u226c","Bfr;":"\ud835\udd05","bfr;":"\ud835\udd1f","bigcap;":"\u22c2","bigcirc;":"\u25ef","bigcup;":"\u22c3","bigodot;":"\u2a00","bigoplus;":"\u2a01","bigotimes;":"\u2a02","bigsqcup;":"\u2a06","bigstar;":"\u2605","bigtriangledown;":"\u25bd","bigtriangleup;":"\u25b3","biguplus;":"\u2a04","bigvee;":"\u22c1","bigwedge;":"\u22c0","bkarow;":"\u290d","blacklozenge;":"\u29eb","blacksquare;":"\u25aa","blacktriangle;":"\u25b4","blacktriangledown;":"\u25be","blacktriangleleft;":"\u25c2","blacktriangleright;":"\u25b8","blank;":"\u2423","blk12;":"\u2592","blk14;":"\u2591","blk34;":"\u2593","block;":"\u2588","bne;":"=\u20e5","bnequiv;":"\u2261\u20e5","bNot;":"\u2aed","bnot;":"\u2310","Bopf;":"\ud835\udd39","bopf;":"\ud835\udd53","bot;":"\u22a5","bottom;":"\u22a5","bowtie;":"\u22c8","boxbox;":"\u29c9","boxdl;":"\u2510","boxdL;":"\u2555","boxDl;":"\u2556","boxDL;":"\u2557","boxdr;":"\u250c","boxdR;":"\u2552","boxDr;":"\u2553","boxDR;":"\u2554","boxh;":"\u2500","boxH;":"\u2550","boxhd;":"\u252c","boxHd;":"\u2564","boxhD;":"\u2565","boxHD;":"\u2566","boxhu;":"\u2534","boxHu;":"\u2567","boxhU;":"\u2568","boxHU;":"\u2569","boxminus;":"\u229f","boxplus;":"\u229e","boxtimes;":"\u22a0","boxul;":"\u2518","boxuL;":"\u255b","boxUl;":"\u255c","boxUL;":"\u255d","boxur;":"\u2514","boxuR;":"\u2558","boxUr;":"\u2559","boxUR;":"\u255a","boxv;":"\u2502","boxV;":"\u2551","boxvh;":"\u253c","boxvH;":"\u256a","boxVh;":"\u256b","boxVH;":"\u256c","boxvl;":"\u2524","boxvL;":"\u2561","boxVl;":"\u2562","boxVL;":"\u2563","boxvr;":"\u251c","boxvR;":"\u255e","boxVr;":"\u255f","boxVR;":"\u2560","bprime;":"\u2035","breve;":"\u02d8","Breve;":"\u02d8","brvbar;":"\u00a6",brvbar:"\u00a6","bscr;":"\ud835\udcb7","Bscr;":"\u212c","bsemi;":"\u204f","bsim;":"\u223d","bsime;":"\u22cd","bsolb;":"\u29c5","bsol;":"\\","bsolhsub;":"\u27c8","bull;":"\u2022","bullet;":"\u2022","bump;":"\u224e","bumpE;":"\u2aae","bumpe;":"\u224f","Bumpeq;":"\u224e","bumpeq;":"\u224f","Cacute;":"\u0106","cacute;":"\u0107","capand;":"\u2a44","capbrcup;":"\u2a49","capcap;":"\u2a4b","cap;":"\u2229","Cap;":"\u22d2","capcup;":"\u2a47","capdot;":"\u2a40","CapitalDifferentialD;":"\u2145","caps;":"\u2229\ufe00","caret;":"\u2041","caron;":"\u02c7","Cayleys;":"\u212d","ccaps;":"\u2a4d","Ccaron;":"\u010c","ccaron;":"\u010d","Ccedil;":"\u00c7",Ccedil:"\u00c7","ccedil;":"\u00e7",ccedil:"\u00e7","Ccirc;":"\u0108","ccirc;":"\u0109","Cconint;":"\u2230","ccups;":"\u2a4c","ccupssm;":"\u2a50","Cdot;":"\u010a","cdot;":"\u010b","cedil;":"\u00b8",cedil:"\u00b8","Cedilla;":"\u00b8","cemptyv;":"\u29b2","cent;":"\u00a2",cent:"\u00a2","centerdot;":"\u00b7","CenterDot;":"\u00b7","cfr;":"\ud835\udd20","Cfr;":"\u212d","CHcy;":"\u0427","chcy;":"\u0447","check;":"\u2713","checkmark;":"\u2713","Chi;":"\u03a7","chi;":"\u03c7","circ;":"\u02c6","circeq;":"\u2257","circlearrowleft;":"\u21ba","circlearrowright;":"\u21bb","circledast;":"\u229b","circledcirc;":"\u229a","circleddash;":"\u229d","CircleDot;":"\u2299","circledR;":"\u00ae","circledS;":"\u24c8","CircleMinus;":"\u2296","CirclePlus;":"\u2295","CircleTimes;":"\u2297","cir;":"\u25cb","cirE;":"\u29c3","cire;":"\u2257","cirfnint;":"\u2a10","cirmid;":"\u2aef","cirscir;":"\u29c2","ClockwiseContourIntegral;":"\u2232","CloseCurlyDoubleQuote;":"\u201d","CloseCurlyQuote;":"\u2019","clubs;":"\u2663","clubsuit;":"\u2663","colon;":":","Colon;":"\u2237","Colone;":"\u2a74","colone;":"\u2254","coloneq;":"\u2254","comma;":",","commat;":"@","comp;":"\u2201","compfn;":"\u2218","complement;":"\u2201","complexes;":"\u2102","cong;":"\u2245","congdot;":"\u2a6d","Congruent;":"\u2261","conint;":"\u222e","Conint;":"\u222f","ContourIntegral;":"\u222e","copf;":"\ud835\udd54","Copf;":"\u2102","coprod;":"\u2210","Coproduct;":"\u2210","copy;":"\u00a9",copy:"\u00a9","COPY;":"\u00a9",COPY:"\u00a9","copysr;":"\u2117","CounterClockwiseContourIntegral;":"\u2233","crarr;":"\u21b5","cross;":"\u2717","Cross;":"\u2a2f","Cscr;":"\ud835\udc9e","cscr;":"\ud835\udcb8","csub;":"\u2acf","csube;":"\u2ad1","csup;":"\u2ad0","csupe;":"\u2ad2","ctdot;":"\u22ef","cudarrl;":"\u2938","cudarrr;":"\u2935","cuepr;":"\u22de","cuesc;":"\u22df","cularr;":"\u21b6","cularrp;":"\u293d","cupbrcap;":"\u2a48","cupcap;":"\u2a46","CupCap;":"\u224d","cup;":"\u222a","Cup;":"\u22d3","cupcup;":"\u2a4a","cupdot;":"\u228d","cupor;":"\u2a45","cups;":"\u222a\ufe00","curarr;":"\u21b7","curarrm;":"\u293c","curlyeqprec;":"\u22de","curlyeqsucc;":"\u22df","curlyvee;":"\u22ce","curlywedge;":"\u22cf","curren;":"\u00a4",curren:"\u00a4","curvearrowleft;":"\u21b6","curvearrowright;":"\u21b7","cuvee;":"\u22ce","cuwed;":"\u22cf","cwconint;":"\u2232","cwint;":"\u2231","cylcty;":"\u232d","dagger;":"\u2020","Dagger;":"\u2021","daleth;":"\u2138","darr;":"\u2193","Darr;":"\u21a1","dArr;":"\u21d3","dash;":"\u2010","Dashv;":"\u2ae4","dashv;":"\u22a3","dbkarow;":"\u290f","dblac;":"\u02dd","Dcaron;":"\u010e","dcaron;":"\u010f","Dcy;":"\u0414","dcy;":"\u0434","ddagger;":"\u2021","ddarr;":"\u21ca","DD;":"\u2145","dd;":"\u2146","DDotrahd;":"\u2911","ddotseq;":"\u2a77","deg;":"\u00b0",deg:"\u00b0","Del;":"\u2207","Delta;":"\u0394","delta;":"\u03b4","demptyv;":"\u29b1","dfisht;":"\u297f","Dfr;":"\ud835\udd07","dfr;":"\ud835\udd21","dHar;":"\u2965","dharl;":"\u21c3","dharr;":"\u21c2","DiacriticalAcute;":"\u00b4","DiacriticalDot;":"\u02d9","DiacriticalDoubleAcute;":"\u02dd","DiacriticalGrave;":"`","DiacriticalTilde;":"\u02dc","diam;":"\u22c4","diamond;":"\u22c4","Diamond;":"\u22c4","diamondsuit;":"\u2666","diams;":"\u2666","die;":"\u00a8","DifferentialD;":"\u2146","digamma;":"\u03dd","disin;":"\u22f2","div;":"\u00f7","divide;":"\u00f7",divide:"\u00f7","divideontimes;":"\u22c7","divonx;":"\u22c7","DJcy;":"\u0402","djcy;":"\u0452","dlcorn;":"\u231e","dlcrop;":"\u230d","dollar;":"$","Dopf;":"\ud835\udd3b","dopf;":"\ud835\udd55","Dot;":"\u00a8","dot;":"\u02d9","DotDot;":"\u20dc","doteq;":"\u2250","doteqdot;":"\u2251","DotEqual;":"\u2250","dotminus;":"\u2238","dotplus;":"\u2214","dotsquare;":"\u22a1","doublebarwedge;":"\u2306","DoubleContourIntegral;":"\u222f","DoubleDot;":"\u00a8","DoubleDownArrow;":"\u21d3","DoubleLeftArrow;":"\u21d0","DoubleLeftRightArrow;":"\u21d4","DoubleLeftTee;":"\u2ae4","DoubleLongLeftArrow;":"\u27f8","DoubleLongLeftRightArrow;":"\u27fa","DoubleLongRightArrow;":"\u27f9","DoubleRightArrow;":"\u21d2","DoubleRightTee;":"\u22a8","DoubleUpArrow;":"\u21d1","DoubleUpDownArrow;":"\u21d5","DoubleVerticalBar;":"\u2225","DownArrowBar;":"\u2913","downarrow;":"\u2193","DownArrow;":"\u2193","Downarrow;":"\u21d3","DownArrowUpArrow;":"\u21f5","DownBreve;":"\u0311","downdownarrows;":"\u21ca","downharpoonleft;":"\u21c3","downharpoonright;":"\u21c2","DownLeftRightVector;":"\u2950","DownLeftTeeVector;":"\u295e","DownLeftVectorBar;":"\u2956","DownLeftVector;":"\u21bd","DownRightTeeVector;":"\u295f","DownRightVectorBar;":"\u2957","DownRightVector;":"\u21c1","DownTeeArrow;":"\u21a7","DownTee;":"\u22a4","drbkarow;":"\u2910","drcorn;":"\u231f","drcrop;":"\u230c","Dscr;":"\ud835\udc9f","dscr;":"\ud835\udcb9","DScy;":"\u0405","dscy;":"\u0455","dsol;":"\u29f6","Dstrok;":"\u0110","dstrok;":"\u0111","dtdot;":"\u22f1","dtri;":"\u25bf","dtrif;":"\u25be","duarr;":"\u21f5","duhar;":"\u296f","dwangle;":"\u29a6","DZcy;":"\u040f","dzcy;":"\u045f","dzigrarr;":"\u27ff","Eacute;":"\u00c9",Eacute:"\u00c9","eacute;":"\u00e9",eacute:"\u00e9","easter;":"\u2a6e","Ecaron;":"\u011a","ecaron;":"\u011b","Ecirc;":"\u00ca",Ecirc:"\u00ca","ecirc;":"\u00ea",ecirc:"\u00ea","ecir;":"\u2256","ecolon;":"\u2255","Ecy;":"\u042d","ecy;":"\u044d","eDDot;":"\u2a77","Edot;":"\u0116","edot;":"\u0117","eDot;":"\u2251","ee;":"\u2147","efDot;":"\u2252","Efr;":"\ud835\udd08","efr;":"\ud835\udd22","eg;":"\u2a9a","Egrave;":"\u00c8",Egrave:"\u00c8","egrave;":"\u00e8",egrave:"\u00e8","egs;":"\u2a96","egsdot;":"\u2a98","el;":"\u2a99","Element;":"\u2208","elinters;":"\u23e7","ell;":"\u2113","els;":"\u2a95","elsdot;":"\u2a97","Emacr;":"\u0112","emacr;":"\u0113","empty;":"\u2205","emptyset;":"\u2205","EmptySmallSquare;":"\u25fb","emptyv;":"\u2205","EmptyVerySmallSquare;":"\u25ab","emsp13;":"\u2004","emsp14;":"\u2005","emsp;":"\u2003","ENG;":"\u014a","eng;":"\u014b","ensp;":"\u2002","Eogon;":"\u0118","eogon;":"\u0119","Eopf;":"\ud835\udd3c","eopf;":"\ud835\udd56","epar;":"\u22d5","eparsl;":"\u29e3","eplus;":"\u2a71","epsi;":"\u03b5","Epsilon;":"\u0395","epsilon;":"\u03b5","epsiv;":"\u03f5","eqcirc;":"\u2256","eqcolon;":"\u2255","eqsim;":"\u2242","eqslantgtr;":"\u2a96","eqslantless;":"\u2a95","Equal;":"\u2a75","equals;":"=","EqualTilde;":"\u2242","equest;":"\u225f","Equilibrium;":"\u21cc","equiv;":"\u2261","equivDD;":"\u2a78","eqvparsl;":"\u29e5","erarr;":"\u2971","erDot;":"\u2253","escr;":"\u212f","Escr;":"\u2130","esdot;":"\u2250","Esim;":"\u2a73","esim;":"\u2242","Eta;":"\u0397","eta;":"\u03b7","ETH;":"\u00d0",ETH:"\u00d0","eth;":"\u00f0",eth:"\u00f0","Euml;":"\u00cb",Euml:"\u00cb","euml;":"\u00eb",euml:"\u00eb","euro;":"\u20ac","excl;":"!","exist;":"\u2203","Exists;":"\u2203","expectation;":"\u2130","exponentiale;":"\u2147","ExponentialE;":"\u2147","fallingdotseq;":"\u2252","Fcy;":"\u0424","fcy;":"\u0444","female;":"\u2640","ffilig;":"\ufb03","fflig;":"\ufb00","ffllig;":"\ufb04","Ffr;":"\ud835\udd09","ffr;":"\ud835\udd23","filig;":"\ufb01","FilledSmallSquare;":"\u25fc","FilledVerySmallSquare;":"\u25aa","fjlig;":"fj","flat;":"\u266d","fllig;":"\ufb02","fltns;":"\u25b1","fnof;":"\u0192","Fopf;":"\ud835\udd3d","fopf;":"\ud835\udd57","forall;":"\u2200","ForAll;":"\u2200","fork;":"\u22d4","forkv;":"\u2ad9","Fouriertrf;":"\u2131","fpartint;":"\u2a0d","frac12;":"\u00bd",frac12:"\u00bd","frac13;":"\u2153","frac14;":"\u00bc",frac14:"\u00bc","frac15;":"\u2155","frac16;":"\u2159","frac18;":"\u215b","frac23;":"\u2154","frac25;":"\u2156","frac34;":"\u00be",frac34:"\u00be","frac35;":"\u2157","frac38;":"\u215c","frac45;":"\u2158","frac56;":"\u215a","frac58;":"\u215d","frac78;":"\u215e","frasl;":"\u2044","frown;":"\u2322","fscr;":"\ud835\udcbb","Fscr;":"\u2131","gacute;":"\u01f5","Gamma;":"\u0393","gamma;":"\u03b3","Gammad;":"\u03dc","gammad;":"\u03dd","gap;":"\u2a86","Gbreve;":"\u011e","gbreve;":"\u011f","Gcedil;":"\u0122","Gcirc;":"\u011c","gcirc;":"\u011d","Gcy;":"\u0413","gcy;":"\u0433","Gdot;":"\u0120","gdot;":"\u0121","ge;":"\u2265","gE;":"\u2267","gEl;":"\u2a8c","gel;":"\u22db","geq;":"\u2265","geqq;":"\u2267","geqslant;":"\u2a7e","gescc;":"\u2aa9","ges;":"\u2a7e","gesdot;":"\u2a80","gesdoto;":"\u2a82","gesdotol;":"\u2a84","gesl;":"\u22db\ufe00","gesles;":"\u2a94","Gfr;":"\ud835\udd0a","gfr;":"\ud835\udd24","gg;":"\u226b","Gg;":"\u22d9","ggg;":"\u22d9","gimel;":"\u2137","GJcy;":"\u0403","gjcy;":"\u0453","gla;":"\u2aa5","gl;":"\u2277","glE;":"\u2a92","glj;":"\u2aa4","gnap;":"\u2a8a","gnapprox;":"\u2a8a","gne;":"\u2a88","gnE;":"\u2269","gneq;":"\u2a88","gneqq;":"\u2269","gnsim;":"\u22e7","Gopf;":"\ud835\udd3e","gopf;":"\ud835\udd58","grave;":"`","GreaterEqual;":"\u2265","GreaterEqualLess;":"\u22db","GreaterFullEqual;":"\u2267","GreaterGreater;":"\u2aa2","GreaterLess;":"\u2277","GreaterSlantEqual;":"\u2a7e","GreaterTilde;":"\u2273","Gscr;":"\ud835\udca2","gscr;":"\u210a","gsim;":"\u2273","gsime;":"\u2a8e","gsiml;":"\u2a90","gtcc;":"\u2aa7","gtcir;":"\u2a7a","gt;":">",gt:">","GT;":">",GT:">","Gt;":"\u226b","gtdot;":"\u22d7","gtlPar;":"\u2995","gtquest;":"\u2a7c","gtrapprox;":"\u2a86","gtrarr;":"\u2978","gtrdot;":"\u22d7","gtreqless;":"\u22db","gtreqqless;":"\u2a8c","gtrless;":"\u2277","gtrsim;":"\u2273","gvertneqq;":"\u2269\ufe00","gvnE;":"\u2269\ufe00","Hacek;":"\u02c7","hairsp;":"\u200a","half;":"\u00bd","hamilt;":"\u210b","HARDcy;":"\u042a","hardcy;":"\u044a","harrcir;":"\u2948","harr;":"\u2194","hArr;":"\u21d4","harrw;":"\u21ad","Hat;":"^","hbar;":"\u210f","Hcirc;":"\u0124","hcirc;":"\u0125","hearts;":"\u2665","heartsuit;":"\u2665","hellip;":"\u2026","hercon;":"\u22b9","hfr;":"\ud835\udd25","Hfr;":"\u210c","HilbertSpace;":"\u210b","hksearow;":"\u2925","hkswarow;":"\u2926","hoarr;":"\u21ff","homtht;":"\u223b","hookleftarrow;":"\u21a9","hookrightarrow;":"\u21aa","hopf;":"\ud835\udd59","Hopf;":"\u210d","horbar;":"\u2015","HorizontalLine;":"\u2500","hscr;":"\ud835\udcbd","Hscr;":"\u210b","hslash;":"\u210f","Hstrok;":"\u0126","hstrok;":"\u0127","HumpDownHump;":"\u224e","HumpEqual;":"\u224f","hybull;":"\u2043","hyphen;":"\u2010","Iacute;":"\u00cd",Iacute:"\u00cd","iacute;":"\u00ed",iacute:"\u00ed","ic;":"\u2063","Icirc;":"\u00ce",Icirc:"\u00ce","icirc;":"\u00ee",icirc:"\u00ee","Icy;":"\u0418","icy;":"\u0438","Idot;":"\u0130","IEcy;":"\u0415","iecy;":"\u0435","iexcl;":"\u00a1",iexcl:"\u00a1","iff;":"\u21d4","ifr;":"\ud835\udd26","Ifr;":"\u2111","Igrave;":"\u00cc",Igrave:"\u00cc","igrave;":"\u00ec",igrave:"\u00ec","ii;":"\u2148","iiiint;":"\u2a0c","iiint;":"\u222d","iinfin;":"\u29dc","iiota;":"\u2129","IJlig;":"\u0132","ijlig;":"\u0133","Imacr;":"\u012a","imacr;":"\u012b","image;":"\u2111","ImaginaryI;":"\u2148","imagline;":"\u2110","imagpart;":"\u2111","imath;":"\u0131","Im;":"\u2111","imof;":"\u22b7","imped;":"\u01b5","Implies;":"\u21d2","incare;":"\u2105","in;":"\u2208","infin;":"\u221e","infintie;":"\u29dd","inodot;":"\u0131","intcal;":"\u22ba","int;":"\u222b","Int;":"\u222c","integers;":"\u2124","Integral;":"\u222b","intercal;":"\u22ba","Intersection;":"\u22c2","intlarhk;":"\u2a17","intprod;":"\u2a3c","InvisibleComma;":"\u2063","InvisibleTimes;":"\u2062","IOcy;":"\u0401","iocy;":"\u0451","Iogon;":"\u012e","iogon;":"\u012f","Iopf;":"\ud835\udd40","iopf;":"\ud835\udd5a","Iota;":"\u0399","iota;":"\u03b9","iprod;":"\u2a3c","iquest;":"\u00bf",iquest:"\u00bf","iscr;":"\ud835\udcbe","Iscr;":"\u2110","isin;":"\u2208","isindot;":"\u22f5","isinE;":"\u22f9","isins;":"\u22f4","isinsv;":"\u22f3","isinv;":"\u2208","it;":"\u2062","Itilde;":"\u0128","itilde;":"\u0129","Iukcy;":"\u0406","iukcy;":"\u0456","Iuml;":"\u00cf",Iuml:"\u00cf","iuml;":"\u00ef",iuml:"\u00ef","Jcirc;":"\u0134","jcirc;":"\u0135","Jcy;":"\u0419","jcy;":"\u0439","Jfr;":"\ud835\udd0d","jfr;":"\ud835\udd27","jmath;":"\u0237","Jopf;":"\ud835\udd41","jopf;":"\ud835\udd5b","Jscr;":"\ud835\udca5","jscr;":"\ud835\udcbf","Jsercy;":"\u0408","jsercy;":"\u0458","Jukcy;":"\u0404","jukcy;":"\u0454","Kappa;":"\u039a","kappa;":"\u03ba","kappav;":"\u03f0","Kcedil;":"\u0136","kcedil;":"\u0137","Kcy;":"\u041a","kcy;":"\u043a","Kfr;":"\ud835\udd0e","kfr;":"\ud835\udd28","kgreen;":"\u0138","KHcy;":"\u0425","khcy;":"\u0445","KJcy;":"\u040c","kjcy;":"\u045c","Kopf;":"\ud835\udd42","kopf;":"\ud835\udd5c","Kscr;":"\ud835\udca6","kscr;":"\ud835\udcc0","lAarr;":"\u21da","Lacute;":"\u0139","lacute;":"\u013a","laemptyv;":"\u29b4","lagran;":"\u2112","Lambda;":"\u039b","lambda;":"\u03bb","lang;":"\u27e8","Lang;":"\u27ea","langd;":"\u2991","langle;":"\u27e8","lap;":"\u2a85","Laplacetrf;":"\u2112","laquo;":"\u00ab",laquo:"\u00ab","larrb;":"\u21e4","larrbfs;":"\u291f","larr;":"\u2190","Larr;":"\u219e","lArr;":"\u21d0","larrfs;":"\u291d","larrhk;":"\u21a9","larrlp;":"\u21ab","larrpl;":"\u2939","larrsim;":"\u2973","larrtl;":"\u21a2","latail;":"\u2919","lAtail;":"\u291b","lat;":"\u2aab","late;":"\u2aad","lates;":"\u2aad\ufe00","lbarr;":"\u290c","lBarr;":"\u290e","lbbrk;":"\u2772","lbrace;":"{","lbrack;":"[","lbrke;":"\u298b","lbrksld;":"\u298f","lbrkslu;":"\u298d","Lcaron;":"\u013d","lcaron;":"\u013e","Lcedil;":"\u013b","lcedil;":"\u013c","lceil;":"\u2308","lcub;":"{","Lcy;":"\u041b","lcy;":"\u043b","ldca;":"\u2936","ldquo;":"\u201c","ldquor;":"\u201e","ldrdhar;":"\u2967","ldrushar;":"\u294b","ldsh;":"\u21b2","le;":"\u2264","lE;":"\u2266","LeftAngleBracket;":"\u27e8","LeftArrowBar;":"\u21e4","leftarrow;":"\u2190","LeftArrow;":"\u2190","Leftarrow;":"\u21d0","LeftArrowRightArrow;":"\u21c6","leftarrowtail;":"\u21a2","LeftCeiling;":"\u2308","LeftDoubleBracket;":"\u27e6","LeftDownTeeVector;":"\u2961","LeftDownVectorBar;":"\u2959","LeftDownVector;":"\u21c3","LeftFloor;":"\u230a","leftharpoondown;":"\u21bd","leftharpoonup;":"\u21bc","leftleftarrows;":"\u21c7","leftrightarrow;":"\u2194","LeftRightArrow;":"\u2194","Leftrightarrow;":"\u21d4","leftrightarrows;":"\u21c6","leftrightharpoons;":"\u21cb","leftrightsquigarrow;":"\u21ad","LeftRightVector;":"\u294e","LeftTeeArrow;":"\u21a4","LeftTee;":"\u22a3","LeftTeeVector;":"\u295a","leftthreetimes;":"\u22cb","LeftTriangleBar;":"\u29cf","LeftTriangle;":"\u22b2","LeftTriangleEqual;":"\u22b4","LeftUpDownVector;":"\u2951","LeftUpTeeVector;":"\u2960","LeftUpVectorBar;":"\u2958","LeftUpVector;":"\u21bf","LeftVectorBar;":"\u2952","LeftVector;":"\u21bc","lEg;":"\u2a8b","leg;":"\u22da","leq;":"\u2264","leqq;":"\u2266","leqslant;":"\u2a7d","lescc;":"\u2aa8","les;":"\u2a7d","lesdot;":"\u2a7f","lesdoto;":"\u2a81","lesdotor;":"\u2a83","lesg;":"\u22da\ufe00","lesges;":"\u2a93","lessapprox;":"\u2a85","lessdot;":"\u22d6","lesseqgtr;":"\u22da","lesseqqgtr;":"\u2a8b","LessEqualGreater;":"\u22da","LessFullEqual;":"\u2266","LessGreater;":"\u2276","lessgtr;":"\u2276","LessLess;":"\u2aa1","lesssim;":"\u2272","LessSlantEqual;":"\u2a7d","LessTilde;":"\u2272","lfisht;":"\u297c","lfloor;":"\u230a","Lfr;":"\ud835\udd0f","lfr;":"\ud835\udd29","lg;":"\u2276","lgE;":"\u2a91","lHar;":"\u2962","lhard;":"\u21bd","lharu;":"\u21bc","lharul;":"\u296a","lhblk;":"\u2584","LJcy;":"\u0409","ljcy;":"\u0459","llarr;":"\u21c7","ll;":"\u226a","Ll;":"\u22d8","llcorner;":"\u231e","Lleftarrow;":"\u21da","llhard;":"\u296b","lltri;":"\u25fa","Lmidot;":"\u013f","lmidot;":"\u0140","lmoustache;":"\u23b0","lmoust;":"\u23b0","lnap;":"\u2a89","lnapprox;":"\u2a89","lne;":"\u2a87","lnE;":"\u2268","lneq;":"\u2a87","lneqq;":"\u2268","lnsim;":"\u22e6","loang;":"\u27ec","loarr;":"\u21fd","lobrk;":"\u27e6","longleftarrow;":"\u27f5","LongLeftArrow;":"\u27f5","Longleftarrow;":"\u27f8","longleftrightarrow;":"\u27f7","LongLeftRightArrow;":"\u27f7","Longleftrightarrow;":"\u27fa","longmapsto;":"\u27fc","longrightarrow;":"\u27f6","LongRightArrow;":"\u27f6","Longrightarrow;":"\u27f9","looparrowleft;":"\u21ab","looparrowright;":"\u21ac","lopar;":"\u2985","Lopf;":"\ud835\udd43","lopf;":"\ud835\udd5d","loplus;":"\u2a2d","lotimes;":"\u2a34","lowast;":"\u2217","lowbar;":"_","LowerLeftArrow;":"\u2199","LowerRightArrow;":"\u2198","loz;":"\u25ca","lozenge;":"\u25ca","lozf;":"\u29eb","lpar;":"(","lparlt;":"\u2993","lrarr;":"\u21c6","lrcorner;":"\u231f","lrhar;":"\u21cb","lrhard;":"\u296d","lrm;":"\u200e","lrtri;":"\u22bf","lsaquo;":"\u2039","lscr;":"\ud835\udcc1","Lscr;":"\u2112","lsh;":"\u21b0","Lsh;":"\u21b0","lsim;":"\u2272","lsime;":"\u2a8d","lsimg;":"\u2a8f","lsqb;":"[","lsquo;":"\u2018","lsquor;":"\u201a","Lstrok;":"\u0141","lstrok;":"\u0142","ltcc;":"\u2aa6","ltcir;":"\u2a79","lt;":"<",lt:"<","LT;":"<",LT:"<","Lt;":"\u226a","ltdot;":"\u22d6","lthree;":"\u22cb","ltimes;":"\u22c9","ltlarr;":"\u2976","ltquest;":"\u2a7b","ltri;":"\u25c3","ltrie;":"\u22b4","ltrif;":"\u25c2","ltrPar;":"\u2996","lurdshar;":"\u294a","luruhar;":"\u2966","lvertneqq;":"\u2268\ufe00","lvnE;":"\u2268\ufe00","macr;":"\u00af",macr:"\u00af","male;":"\u2642","malt;":"\u2720","maltese;":"\u2720","Map;":"\u2905","map;":"\u21a6","mapsto;":"\u21a6","mapstodown;":"\u21a7","mapstoleft;":"\u21a4","mapstoup;":"\u21a5","marker;":"\u25ae","mcomma;":"\u2a29","Mcy;":"\u041c","mcy;":"\u043c","mdash;":"\u2014","mDDot;":"\u223a","measuredangle;":"\u2221","MediumSpace;":"\u205f","Mellintrf;":"\u2133","Mfr;":"\ud835\udd10","mfr;":"\ud835\udd2a","mho;":"\u2127","micro;":"\u00b5",micro:"\u00b5","midast;":"*","midcir;":"\u2af0","mid;":"\u2223","middot;":"\u00b7",middot:"\u00b7","minusb;":"\u229f","minus;":"\u2212","minusd;":"\u2238","minusdu;":"\u2a2a","MinusPlus;":"\u2213","mlcp;":"\u2adb","mldr;":"\u2026","mnplus;":"\u2213","models;":"\u22a7","Mopf;":"\ud835\udd44","mopf;":"\ud835\udd5e","mp;":"\u2213","mscr;":"\ud835\udcc2","Mscr;":"\u2133","mstpos;":"\u223e","Mu;":"\u039c","mu;":"\u03bc","multimap;":"\u22b8","mumap;":"\u22b8","nabla;":"\u2207","Nacute;":"\u0143","nacute;":"\u0144","nang;":"\u2220\u20d2","nap;":"\u2249","napE;":"\u2a70\u0338","napid;":"\u224b\u0338","napos;":"\u0149","napprox;":"\u2249","natural;":"\u266e","naturals;":"\u2115","natur;":"\u266e","nbsp;":"\u00a0",nbsp:"\u00a0","nbump;":"\u224e\u0338","nbumpe;":"\u224f\u0338","ncap;":"\u2a43","Ncaron;":"\u0147","ncaron;":"\u0148","Ncedil;":"\u0145","ncedil;":"\u0146","ncong;":"\u2247","ncongdot;":"\u2a6d\u0338","ncup;":"\u2a42","Ncy;":"\u041d","ncy;":"\u043d","ndash;":"\u2013","nearhk;":"\u2924","nearr;":"\u2197","neArr;":"\u21d7","nearrow;":"\u2197","ne;":"\u2260","nedot;":"\u2250\u0338","NegativeMediumSpace;":"\u200b","NegativeThickSpace;":"\u200b","NegativeThinSpace;":"\u200b","NegativeVeryThinSpace;":"\u200b","nequiv;":"\u2262","nesear;":"\u2928","nesim;":"\u2242\u0338","NestedGreaterGreater;":"\u226b","NestedLessLess;":"\u226a","NewLine;":"\n","nexist;":"\u2204","nexists;":"\u2204","Nfr;":"\ud835\udd11","nfr;":"\ud835\udd2b","ngE;":"\u2267\u0338","nge;":"\u2271","ngeq;":"\u2271","ngeqq;":"\u2267\u0338","ngeqslant;":"\u2a7e\u0338","nges;":"\u2a7e\u0338","nGg;":"\u22d9\u0338","ngsim;":"\u2275","nGt;":"\u226b\u20d2","ngt;":"\u226f","ngtr;":"\u226f","nGtv;":"\u226b\u0338","nharr;":"\u21ae","nhArr;":"\u21ce","nhpar;":"\u2af2","ni;":"\u220b","nis;":"\u22fc","nisd;":"\u22fa","niv;":"\u220b","NJcy;":"\u040a","njcy;":"\u045a","nlarr;":"\u219a","nlArr;":"\u21cd","nldr;":"\u2025","nlE;":"\u2266\u0338","nle;":"\u2270","nleftarrow;":"\u219a","nLeftarrow;":"\u21cd","nleftrightarrow;":"\u21ae","nLeftrightarrow;":"\u21ce","nleq;":"\u2270","nleqq;":"\u2266\u0338","nleqslant;":"\u2a7d\u0338","nles;":"\u2a7d\u0338","nless;":"\u226e","nLl;":"\u22d8\u0338","nlsim;":"\u2274","nLt;":"\u226a\u20d2","nlt;":"\u226e","nltri;":"\u22ea","nltrie;":"\u22ec","nLtv;":"\u226a\u0338","nmid;":"\u2224","NoBreak;":"\u2060","NonBreakingSpace;":"\u00a0","nopf;":"\ud835\udd5f","Nopf;":"\u2115","Not;":"\u2aec","not;":"\u00ac",not:"\u00ac","NotCongruent;":"\u2262","NotCupCap;":"\u226d","NotDoubleVerticalBar;":"\u2226","NotElement;":"\u2209","NotEqual;":"\u2260","NotEqualTilde;":"\u2242\u0338","NotExists;":"\u2204","NotGreater;":"\u226f","NotGreaterEqual;":"\u2271","NotGreaterFullEqual;":"\u2267\u0338","NotGreaterGreater;":"\u226b\u0338","NotGreaterLess;":"\u2279","NotGreaterSlantEqual;":"\u2a7e\u0338","NotGreaterTilde;":"\u2275","NotHumpDownHump;":"\u224e\u0338","NotHumpEqual;":"\u224f\u0338","notin;":"\u2209","notindot;":"\u22f5\u0338","notinE;":"\u22f9\u0338","notinva;":"\u2209","notinvb;":"\u22f7","notinvc;":"\u22f6","NotLeftTriangleBar;":"\u29cf\u0338","NotLeftTriangle;":"\u22ea","NotLeftTriangleEqual;":"\u22ec","NotLess;":"\u226e","NotLessEqual;":"\u2270","NotLessGreater;":"\u2278","NotLessLess;":"\u226a\u0338","NotLessSlantEqual;":"\u2a7d\u0338","NotLessTilde;":"\u2274","NotNestedGreaterGreater;":"\u2aa2\u0338","NotNestedLessLess;":"\u2aa1\u0338","notni;":"\u220c","notniva;":"\u220c","notnivb;":"\u22fe","notnivc;":"\u22fd","NotPrecedes;":"\u2280","NotPrecedesEqual;":"\u2aaf\u0338","NotPrecedesSlantEqual;":"\u22e0","NotReverseElement;":"\u220c","NotRightTriangleBar;":"\u29d0\u0338","NotRightTriangle;":"\u22eb","NotRightTriangleEqual;":"\u22ed","NotSquareSubset;":"\u228f\u0338","NotSquareSubsetEqual;":"\u22e2","NotSquareSuperset;":"\u2290\u0338","NotSquareSupersetEqual;":"\u22e3","NotSubset;":"\u2282\u20d2","NotSubsetEqual;":"\u2288","NotSucceeds;":"\u2281","NotSucceedsEqual;":"\u2ab0\u0338","NotSucceedsSlantEqual;":"\u22e1","NotSucceedsTilde;":"\u227f\u0338","NotSuperset;":"\u2283\u20d2","NotSupersetEqual;":"\u2289","NotTilde;":"\u2241","NotTildeEqual;":"\u2244","NotTildeFullEqual;":"\u2247","NotTildeTilde;":"\u2249","NotVerticalBar;":"\u2224","nparallel;":"\u2226","npar;":"\u2226","nparsl;":"\u2afd\u20e5","npart;":"\u2202\u0338","npolint;":"\u2a14","npr;":"\u2280","nprcue;":"\u22e0","nprec;":"\u2280","npreceq;":"\u2aaf\u0338","npre;":"\u2aaf\u0338","nrarrc;":"\u2933\u0338","nrarr;":"\u219b","nrArr;":"\u21cf","nrarrw;":"\u219d\u0338","nrightarrow;":"\u219b","nRightarrow;":"\u21cf","nrtri;":"\u22eb","nrtrie;":"\u22ed","nsc;":"\u2281","nsccue;":"\u22e1","nsce;":"\u2ab0\u0338","Nscr;":"\ud835\udca9","nscr;":"\ud835\udcc3","nshortmid;":"\u2224","nshortparallel;":"\u2226","nsim;":"\u2241","nsime;":"\u2244","nsimeq;":"\u2244","nsmid;":"\u2224","nspar;":"\u2226","nsqsube;":"\u22e2","nsqsupe;":"\u22e3","nsub;":"\u2284","nsubE;":"\u2ac5\u0338","nsube;":"\u2288","nsubset;":"\u2282\u20d2","nsubseteq;":"\u2288","nsubseteqq;":"\u2ac5\u0338","nsucc;":"\u2281","nsucceq;":"\u2ab0\u0338","nsup;":"\u2285","nsupE;":"\u2ac6\u0338","nsupe;":"\u2289","nsupset;":"\u2283\u20d2","nsupseteq;":"\u2289","nsupseteqq;":"\u2ac6\u0338","ntgl;":"\u2279","Ntilde;":"\u00d1",Ntilde:"\u00d1","ntilde;":"\u00f1",ntilde:"\u00f1","ntlg;":"\u2278","ntriangleleft;":"\u22ea","ntrianglelefteq;":"\u22ec","ntriangleright;":"\u22eb","ntrianglerighteq;":"\u22ed","Nu;":"\u039d","nu;":"\u03bd","num;":"#","numero;":"\u2116","numsp;":"\u2007","nvap;":"\u224d\u20d2","nvdash;":"\u22ac","nvDash;":"\u22ad","nVdash;":"\u22ae","nVDash;":"\u22af","nvge;":"\u2265\u20d2","nvgt;":">\u20d2","nvHarr;":"\u2904","nvinfin;":"\u29de","nvlArr;":"\u2902","nvle;":"\u2264\u20d2","nvlt;":"<\u20d2","nvltrie;":"\u22b4\u20d2","nvrArr;":"\u2903","nvrtrie;":"\u22b5\u20d2","nvsim;":"\u223c\u20d2","nwarhk;":"\u2923","nwarr;":"\u2196","nwArr;":"\u21d6","nwarrow;":"\u2196","nwnear;":"\u2927","Oacute;":"\u00d3",Oacute:"\u00d3","oacute;":"\u00f3",oacute:"\u00f3","oast;":"\u229b","Ocirc;":"\u00d4",Ocirc:"\u00d4","ocirc;":"\u00f4",ocirc:"\u00f4","ocir;":"\u229a","Ocy;":"\u041e","ocy;":"\u043e","odash;":"\u229d","Odblac;":"\u0150","odblac;":"\u0151","odiv;":"\u2a38","odot;":"\u2299","odsold;":"\u29bc","OElig;":"\u0152","oelig;":"\u0153","ofcir;":"\u29bf","Ofr;":"\ud835\udd12","ofr;":"\ud835\udd2c","ogon;":"\u02db","Ograve;":"\u00d2",Ograve:"\u00d2","ograve;":"\u00f2",ograve:"\u00f2","ogt;":"\u29c1","ohbar;":"\u29b5","ohm;":"\u03a9","oint;":"\u222e","olarr;":"\u21ba","olcir;":"\u29be","olcross;":"\u29bb","oline;":"\u203e","olt;":"\u29c0","Omacr;":"\u014c","omacr;":"\u014d","Omega;":"\u03a9","omega;":"\u03c9","Omicron;":"\u039f","omicron;":"\u03bf","omid;":"\u29b6","ominus;":"\u2296","Oopf;":"\ud835\udd46","oopf;":"\ud835\udd60","opar;":"\u29b7","OpenCurlyDoubleQuote;":"\u201c","OpenCurlyQuote;":"\u2018","operp;":"\u29b9","oplus;":"\u2295","orarr;":"\u21bb","Or;":"\u2a54","or;":"\u2228","ord;":"\u2a5d","order;":"\u2134","orderof;":"\u2134","ordf;":"\u00aa",ordf:"\u00aa","ordm;":"\u00ba",ordm:"\u00ba","origof;":"\u22b6","oror;":"\u2a56","orslope;":"\u2a57","orv;":"\u2a5b","oS;":"\u24c8","Oscr;":"\ud835\udcaa","oscr;":"\u2134","Oslash;":"\u00d8",Oslash:"\u00d8","oslash;":"\u00f8",oslash:"\u00f8","osol;":"\u2298","Otilde;":"\u00d5",Otilde:"\u00d5","otilde;":"\u00f5",otilde:"\u00f5","otimesas;":"\u2a36","Otimes;":"\u2a37","otimes;":"\u2297","Ouml;":"\u00d6",Ouml:"\u00d6","ouml;":"\u00f6",ouml:"\u00f6","ovbar;":"\u233d","OverBar;":"\u203e","OverBrace;":"\u23de","OverBracket;":"\u23b4","OverParenthesis;":"\u23dc","para;":"\u00b6",para:"\u00b6","parallel;":"\u2225","par;":"\u2225","parsim;":"\u2af3","parsl;":"\u2afd","part;":"\u2202","PartialD;":"\u2202","Pcy;":"\u041f","pcy;":"\u043f","percnt;":"%","period;":".","permil;":"\u2030","perp;":"\u22a5","pertenk;":"\u2031","Pfr;":"\ud835\udd13","pfr;":"\ud835\udd2d","Phi;":"\u03a6","phi;":"\u03c6","phiv;":"\u03d5","phmmat;":"\u2133","phone;":"\u260e","Pi;":"\u03a0","pi;":"\u03c0","pitchfork;":"\u22d4","piv;":"\u03d6","planck;":"\u210f","planckh;":"\u210e","plankv;":"\u210f","plusacir;":"\u2a23","plusb;":"\u229e","pluscir;":"\u2a22","plus;":"+","plusdo;":"\u2214","plusdu;":"\u2a25","pluse;":"\u2a72","PlusMinus;":"\u00b1","plusmn;":"\u00b1",plusmn:"\u00b1","plussim;":"\u2a26","plustwo;":"\u2a27","pm;":"\u00b1","Poincareplane;":"\u210c","pointint;":"\u2a15","popf;":"\ud835\udd61","Popf;":"\u2119","pound;":"\u00a3",pound:"\u00a3","prap;":"\u2ab7","Pr;":"\u2abb","pr;":"\u227a","prcue;":"\u227c","precapprox;":"\u2ab7","prec;":"\u227a","preccurlyeq;":"\u227c","Precedes;":"\u227a","PrecedesEqual;":"\u2aaf","PrecedesSlantEqual;":"\u227c","PrecedesTilde;":"\u227e","preceq;":"\u2aaf","precnapprox;":"\u2ab9","precneqq;":"\u2ab5","precnsim;":"\u22e8","pre;":"\u2aaf","prE;":"\u2ab3","precsim;":"\u227e","prime;":"\u2032","Prime;":"\u2033","primes;":"\u2119","prnap;":"\u2ab9","prnE;":"\u2ab5","prnsim;":"\u22e8","prod;":"\u220f","Product;":"\u220f","profalar;":"\u232e","profline;":"\u2312","profsurf;":"\u2313","prop;":"\u221d","Proportional;":"\u221d","Proportion;":"\u2237","propto;":"\u221d","prsim;":"\u227e","prurel;":"\u22b0","Pscr;":"\ud835\udcab","pscr;":"\ud835\udcc5","Psi;":"\u03a8","psi;":"\u03c8","puncsp;":"\u2008","Qfr;":"\ud835\udd14","qfr;":"\ud835\udd2e","qint;":"\u2a0c","qopf;":"\ud835\udd62","Qopf;":"\u211a","qprime;":"\u2057","Qscr;":"\ud835\udcac","qscr;":"\ud835\udcc6","quaternions;":"\u210d","quatint;":"\u2a16","quest;":"?","questeq;":"\u225f","quot;":'"',quot:'"',"QUOT;":'"',QUOT:'"',"rAarr;":"\u21db","race;":"\u223d\u0331","Racute;":"\u0154","racute;":"\u0155","radic;":"\u221a","raemptyv;":"\u29b3","rang;":"\u27e9","Rang;":"\u27eb","rangd;":"\u2992","range;":"\u29a5","rangle;":"\u27e9","raquo;":"\u00bb",raquo:"\u00bb","rarrap;":"\u2975","rarrb;":"\u21e5","rarrbfs;":"\u2920","rarrc;":"\u2933","rarr;":"\u2192","Rarr;":"\u21a0","rArr;":"\u21d2","rarrfs;":"\u291e","rarrhk;":"\u21aa","rarrlp;":"\u21ac","rarrpl;":"\u2945","rarrsim;":"\u2974","Rarrtl;":"\u2916","rarrtl;":"\u21a3","rarrw;":"\u219d","ratail;":"\u291a","rAtail;":"\u291c","ratio;":"\u2236","rationals;":"\u211a","rbarr;":"\u290d","rBarr;":"\u290f","RBarr;":"\u2910","rbbrk;":"\u2773","rbrace;":"}","rbrack;":"]","rbrke;":"\u298c","rbrksld;":"\u298e","rbrkslu;":"\u2990","Rcaron;":"\u0158","rcaron;":"\u0159","Rcedil;":"\u0156","rcedil;":"\u0157","rceil;":"\u2309","rcub;":"}","Rcy;":"\u0420","rcy;":"\u0440","rdca;":"\u2937","rdldhar;":"\u2969","rdquo;":"\u201d","rdquor;":"\u201d","rdsh;":"\u21b3","real;":"\u211c","realine;":"\u211b","realpart;":"\u211c","reals;":"\u211d","Re;":"\u211c","rect;":"\u25ad","reg;":"\u00ae",reg:"\u00ae","REG;":"\u00ae",REG:"\u00ae","ReverseElement;":"\u220b","ReverseEquilibrium;":"\u21cb","ReverseUpEquilibrium;":"\u296f","rfisht;":"\u297d","rfloor;":"\u230b","rfr;":"\ud835\udd2f","Rfr;":"\u211c","rHar;":"\u2964","rhard;":"\u21c1","rharu;":"\u21c0","rharul;":"\u296c","Rho;":"\u03a1","rho;":"\u03c1","rhov;":"\u03f1","RightAngleBracket;":"\u27e9","RightArrowBar;":"\u21e5","rightarrow;":"\u2192","RightArrow;":"\u2192","Rightarrow;":"\u21d2","RightArrowLeftArrow;":"\u21c4","rightarrowtail;":"\u21a3","RightCeiling;":"\u2309","RightDoubleBracket;":"\u27e7","RightDownTeeVector;":"\u295d","RightDownVectorBar;":"\u2955","RightDownVector;":"\u21c2","RightFloor;":"\u230b","rightharpoondown;":"\u21c1","rightharpoonup;":"\u21c0","rightleftarrows;":"\u21c4","rightleftharpoons;":"\u21cc","rightrightarrows;":"\u21c9","rightsquigarrow;":"\u219d","RightTeeArrow;":"\u21a6","RightTee;":"\u22a2","RightTeeVector;":"\u295b","rightthreetimes;":"\u22cc","RightTriangleBar;":"\u29d0","RightTriangle;":"\u22b3","RightTriangleEqual;":"\u22b5","RightUpDownVector;":"\u294f","RightUpTeeVector;":"\u295c","RightUpVectorBar;":"\u2954","RightUpVector;":"\u21be","RightVectorBar;":"\u2953","RightVector;":"\u21c0","ring;":"\u02da","risingdotseq;":"\u2253","rlarr;":"\u21c4","rlhar;":"\u21cc","rlm;":"\u200f","rmoustache;":"\u23b1","rmoust;":"\u23b1","rnmid;":"\u2aee","roang;":"\u27ed","roarr;":"\u21fe","robrk;":"\u27e7","ropar;":"\u2986","ropf;":"\ud835\udd63","Ropf;":"\u211d","roplus;":"\u2a2e","rotimes;":"\u2a35","RoundImplies;":"\u2970","rpar;":")","rpargt;":"\u2994","rppolint;":"\u2a12","rrarr;":"\u21c9","Rrightarrow;":"\u21db","rsaquo;":"\u203a","rscr;":"\ud835\udcc7","Rscr;":"\u211b","rsh;":"\u21b1","Rsh;":"\u21b1","rsqb;":"]","rsquo;":"\u2019","rsquor;":"\u2019","rthree;":"\u22cc","rtimes;":"\u22ca","rtri;":"\u25b9","rtrie;":"\u22b5","rtrif;":"\u25b8","rtriltri;":"\u29ce","RuleDelayed;":"\u29f4","ruluhar;":"\u2968","rx;":"\u211e","Sacute;":"\u015a","sacute;":"\u015b","sbquo;":"\u201a","scap;":"\u2ab8","Scaron;":"\u0160","scaron;":"\u0161","Sc;":"\u2abc","sc;":"\u227b","sccue;":"\u227d","sce;":"\u2ab0","scE;":"\u2ab4","Scedil;":"\u015e","scedil;":"\u015f","Scirc;":"\u015c","scirc;":"\u015d","scnap;":"\u2aba","scnE;":"\u2ab6","scnsim;":"\u22e9","scpolint;":"\u2a13","scsim;":"\u227f","Scy;":"\u0421","scy;":"\u0441","sdotb;":"\u22a1","sdot;":"\u22c5","sdote;":"\u2a66","searhk;":"\u2925","searr;":"\u2198","seArr;":"\u21d8","searrow;":"\u2198","sect;":"\u00a7",sect:"\u00a7","semi;":";","seswar;":"\u2929","setminus;":"\u2216","setmn;":"\u2216","sext;":"\u2736","Sfr;":"\ud835\udd16","sfr;":"\ud835\udd30","sfrown;":"\u2322","sharp;":"\u266f","SHCHcy;":"\u0429","shchcy;":"\u0449","SHcy;":"\u0428","shcy;":"\u0448","ShortDownArrow;":"\u2193","ShortLeftArrow;":"\u2190","shortmid;":"\u2223","shortparallel;":"\u2225","ShortRightArrow;":"\u2192","ShortUpArrow;":"\u2191","shy;":"\u00ad",shy:"\u00ad","Sigma;":"\u03a3","sigma;":"\u03c3","sigmaf;":"\u03c2","sigmav;":"\u03c2","sim;":"\u223c","simdot;":"\u2a6a","sime;":"\u2243","simeq;":"\u2243","simg;":"\u2a9e","simgE;":"\u2aa0","siml;":"\u2a9d","simlE;":"\u2a9f","simne;":"\u2246","simplus;":"\u2a24","simrarr;":"\u2972","slarr;":"\u2190","SmallCircle;":"\u2218","smallsetminus;":"\u2216","smashp;":"\u2a33","smeparsl;":"\u29e4","smid;":"\u2223","smile;":"\u2323","smt;":"\u2aaa","smte;":"\u2aac","smtes;":"\u2aac\ufe00","SOFTcy;":"\u042c","softcy;":"\u044c","solbar;":"\u233f","solb;":"\u29c4","sol;":"/","Sopf;":"\ud835\udd4a","sopf;":"\ud835\udd64","spades;":"\u2660","spadesuit;":"\u2660","spar;":"\u2225","sqcap;":"\u2293","sqcaps;":"\u2293\ufe00","sqcup;":"\u2294","sqcups;":"\u2294\ufe00","Sqrt;":"\u221a","sqsub;":"\u228f","sqsube;":"\u2291","sqsubset;":"\u228f","sqsubseteq;":"\u2291","sqsup;":"\u2290","sqsupe;":"\u2292","sqsupset;":"\u2290","sqsupseteq;":"\u2292","square;":"\u25a1","Square;":"\u25a1","SquareIntersection;":"\u2293","SquareSubset;":"\u228f","SquareSubsetEqual;":"\u2291","SquareSuperset;":"\u2290","SquareSupersetEqual;":"\u2292","SquareUnion;":"\u2294","squarf;":"\u25aa","squ;":"\u25a1","squf;":"\u25aa","srarr;":"\u2192","Sscr;":"\ud835\udcae","sscr;":"\ud835\udcc8","ssetmn;":"\u2216","ssmile;":"\u2323","sstarf;":"\u22c6","Star;":"\u22c6","star;":"\u2606","starf;":"\u2605","straightepsilon;":"\u03f5","straightphi;":"\u03d5","strns;":"\u00af","sub;":"\u2282","Sub;":"\u22d0","subdot;":"\u2abd","subE;":"\u2ac5","sube;":"\u2286","subedot;":"\u2ac3","submult;":"\u2ac1","subnE;":"\u2acb","subne;":"\u228a","subplus;":"\u2abf","subrarr;":"\u2979","subset;":"\u2282","Subset;":"\u22d0","subseteq;":"\u2286","subseteqq;":"\u2ac5","SubsetEqual;":"\u2286","subsetneq;":"\u228a","subsetneqq;":"\u2acb","subsim;":"\u2ac7","subsub;":"\u2ad5","subsup;":"\u2ad3","succapprox;":"\u2ab8","succ;":"\u227b","succcurlyeq;":"\u227d","Succeeds;":"\u227b","SucceedsEqual;":"\u2ab0","SucceedsSlantEqual;":"\u227d","SucceedsTilde;":"\u227f","succeq;":"\u2ab0","succnapprox;":"\u2aba","succneqq;":"\u2ab6","succnsim;":"\u22e9","succsim;":"\u227f","SuchThat;":"\u220b","sum;":"\u2211","Sum;":"\u2211","sung;":"\u266a","sup1;":"\u00b9",sup1:"\u00b9","sup2;":"\u00b2",sup2:"\u00b2","sup3;":"\u00b3",sup3:"\u00b3","sup;":"\u2283","Sup;":"\u22d1","supdot;":"\u2abe","supdsub;":"\u2ad8","supE;":"\u2ac6","supe;":"\u2287","supedot;":"\u2ac4","Superset;":"\u2283","SupersetEqual;":"\u2287","suphsol;":"\u27c9","suphsub;":"\u2ad7","suplarr;":"\u297b","supmult;":"\u2ac2","supnE;":"\u2acc","supne;":"\u228b","supplus;":"\u2ac0","supset;":"\u2283","Supset;":"\u22d1","supseteq;":"\u2287","supseteqq;":"\u2ac6","supsetneq;":"\u228b","supsetneqq;":"\u2acc","supsim;":"\u2ac8","supsub;":"\u2ad4","supsup;":"\u2ad6","swarhk;":"\u2926","swarr;":"\u2199","swArr;":"\u21d9","swarrow;":"\u2199","swnwar;":"\u292a","szlig;":"\u00df",szlig:"\u00df","Tab;":"	","target;":"\u2316","Tau;":"\u03a4","tau;":"\u03c4","tbrk;":"\u23b4","Tcaron;":"\u0164","tcaron;":"\u0165","Tcedil;":"\u0162","tcedil;":"\u0163","Tcy;":"\u0422","tcy;":"\u0442","tdot;":"\u20db","telrec;":"\u2315","Tfr;":"\ud835\udd17","tfr;":"\ud835\udd31","there4;":"\u2234","therefore;":"\u2234","Therefore;":"\u2234","Theta;":"\u0398","theta;":"\u03b8","thetasym;":"\u03d1","thetav;":"\u03d1","thickapprox;":"\u2248","thicksim;":"\u223c","ThickSpace;":"\u205f\u200a","ThinSpace;":"\u2009","thinsp;":"\u2009","thkap;":"\u2248","thksim;":"\u223c","THORN;":"\u00de",THORN:"\u00de","thorn;":"\u00fe",thorn:"\u00fe","tilde;":"\u02dc","Tilde;":"\u223c","TildeEqual;":"\u2243","TildeFullEqual;":"\u2245","TildeTilde;":"\u2248","timesbar;":"\u2a31","timesb;":"\u22a0","times;":"\u00d7",times:"\u00d7","timesd;":"\u2a30","tint;":"\u222d","toea;":"\u2928","topbot;":"\u2336","topcir;":"\u2af1","top;":"\u22a4","Topf;":"\ud835\udd4b","topf;":"\ud835\udd65","topfork;":"\u2ada","tosa;":"\u2929","tprime;":"\u2034","trade;":"\u2122","TRADE;":"\u2122","triangle;":"\u25b5","triangledown;":"\u25bf","triangleleft;":"\u25c3","trianglelefteq;":"\u22b4","triangleq;":"\u225c","triangleright;":"\u25b9","trianglerighteq;":"\u22b5","tridot;":"\u25ec","trie;":"\u225c","triminus;":"\u2a3a","TripleDot;":"\u20db","triplus;":"\u2a39","trisb;":"\u29cd","tritime;":"\u2a3b","trpezium;":"\u23e2","Tscr;":"\ud835\udcaf","tscr;":"\ud835\udcc9","TScy;":"\u0426","tscy;":"\u0446","TSHcy;":"\u040b","tshcy;":"\u045b","Tstrok;":"\u0166","tstrok;":"\u0167","twixt;":"\u226c","twoheadleftarrow;":"\u219e","twoheadrightarrow;":"\u21a0","Uacute;":"\u00da",Uacute:"\u00da","uacute;":"\u00fa",uacute:"\u00fa","uarr;":"\u2191","Uarr;":"\u219f","uArr;":"\u21d1","Uarrocir;":"\u2949","Ubrcy;":"\u040e","ubrcy;":"\u045e","Ubreve;":"\u016c","ubreve;":"\u016d","Ucirc;":"\u00db",Ucirc:"\u00db","ucirc;":"\u00fb",ucirc:"\u00fb","Ucy;":"\u0423","ucy;":"\u0443","udarr;":"\u21c5","Udblac;":"\u0170","udblac;":"\u0171","udhar;":"\u296e","ufisht;":"\u297e","Ufr;":"\ud835\udd18","ufr;":"\ud835\udd32","Ugrave;":"\u00d9",Ugrave:"\u00d9","ugrave;":"\u00f9",ugrave:"\u00f9","uHar;":"\u2963","uharl;":"\u21bf","uharr;":"\u21be","uhblk;":"\u2580","ulcorn;":"\u231c","ulcorner;":"\u231c","ulcrop;":"\u230f","ultri;":"\u25f8","Umacr;":"\u016a","umacr;":"\u016b","uml;":"\u00a8",uml:"\u00a8","UnderBar;":"_","UnderBrace;":"\u23df","UnderBracket;":"\u23b5","UnderParenthesis;":"\u23dd","Union;":"\u22c3","UnionPlus;":"\u228e","Uogon;":"\u0172","uogon;":"\u0173","Uopf;":"\ud835\udd4c","uopf;":"\ud835\udd66","UpArrowBar;":"\u2912","uparrow;":"\u2191","UpArrow;":"\u2191","Uparrow;":"\u21d1","UpArrowDownArrow;":"\u21c5","updownarrow;":"\u2195","UpDownArrow;":"\u2195","Updownarrow;":"\u21d5","UpEquilibrium;":"\u296e","upharpoonleft;":"\u21bf","upharpoonright;":"\u21be","uplus;":"\u228e","UpperLeftArrow;":"\u2196","UpperRightArrow;":"\u2197","upsi;":"\u03c5","Upsi;":"\u03d2","upsih;":"\u03d2","Upsilon;":"\u03a5","upsilon;":"\u03c5","UpTeeArrow;":"\u21a5","UpTee;":"\u22a5","upuparrows;":"\u21c8","urcorn;":"\u231d","urcorner;":"\u231d","urcrop;":"\u230e","Uring;":"\u016e","uring;":"\u016f","urtri;":"\u25f9","Uscr;":"\ud835\udcb0","uscr;":"\ud835\udcca","utdot;":"\u22f0","Utilde;":"\u0168","utilde;":"\u0169","utri;":"\u25b5","utrif;":"\u25b4","uuarr;":"\u21c8","Uuml;":"\u00dc",Uuml:"\u00dc","uuml;":"\u00fc",uuml:"\u00fc","uwangle;":"\u29a7","vangrt;":"\u299c","varepsilon;":"\u03f5","varkappa;":"\u03f0","varnothing;":"\u2205","varphi;":"\u03d5","varpi;":"\u03d6","varpropto;":"\u221d","varr;":"\u2195","vArr;":"\u21d5","varrho;":"\u03f1","varsigma;":"\u03c2","varsubsetneq;":"\u228a\ufe00","varsubsetneqq;":"\u2acb\ufe00","varsupsetneq;":"\u228b\ufe00","varsupsetneqq;":"\u2acc\ufe00","vartheta;":"\u03d1","vartriangleleft;":"\u22b2","vartriangleright;":"\u22b3","vBar;":"\u2ae8","Vbar;":"\u2aeb","vBarv;":"\u2ae9","Vcy;":"\u0412","vcy;":"\u0432","vdash;":"\u22a2","vDash;":"\u22a8","Vdash;":"\u22a9","VDash;":"\u22ab","Vdashl;":"\u2ae6","veebar;":"\u22bb","vee;":"\u2228","Vee;":"\u22c1","veeeq;":"\u225a","vellip;":"\u22ee","verbar;":"|","Verbar;":"\u2016","vert;":"|","Vert;":"\u2016","VerticalBar;":"\u2223","VerticalLine;":"|","VerticalSeparator;":"\u2758","VerticalTilde;":"\u2240","VeryThinSpace;":"\u200a","Vfr;":"\ud835\udd19","vfr;":"\ud835\udd33","vltri;":"\u22b2","vnsub;":"\u2282\u20d2","vnsup;":"\u2283\u20d2","Vopf;":"\ud835\udd4d","vopf;":"\ud835\udd67","vprop;":"\u221d","vrtri;":"\u22b3","Vscr;":"\ud835\udcb1","vscr;":"\ud835\udccb","vsubnE;":"\u2acb\ufe00","vsubne;":"\u228a\ufe00","vsupnE;":"\u2acc\ufe00","vsupne;":"\u228b\ufe00","Vvdash;":"\u22aa","vzigzag;":"\u299a","Wcirc;":"\u0174","wcirc;":"\u0175","wedbar;":"\u2a5f","wedge;":"\u2227","Wedge;":"\u22c0","wedgeq;":"\u2259","weierp;":"\u2118","Wfr;":"\ud835\udd1a","wfr;":"\ud835\udd34","Wopf;":"\ud835\udd4e","wopf;":"\ud835\udd68","wp;":"\u2118","wr;":"\u2240","wreath;":"\u2240","Wscr;":"\ud835\udcb2","wscr;":"\ud835\udccc","xcap;":"\u22c2","xcirc;":"\u25ef","xcup;":"\u22c3","xdtri;":"\u25bd","Xfr;":"\ud835\udd1b","xfr;":"\ud835\udd35","xharr;":"\u27f7","xhArr;":"\u27fa","Xi;":"\u039e","xi;":"\u03be","xlarr;":"\u27f5","xlArr;":"\u27f8","xmap;":"\u27fc","xnis;":"\u22fb","xodot;":"\u2a00","Xopf;":"\ud835\udd4f","xopf;":"\ud835\udd69","xoplus;":"\u2a01","xotime;":"\u2a02","xrarr;":"\u27f6","xrArr;":"\u27f9","Xscr;":"\ud835\udcb3","xscr;":"\ud835\udccd","xsqcup;":"\u2a06","xuplus;":"\u2a04","xutri;":"\u25b3","xvee;":"\u22c1","xwedge;":"\u22c0","Yacute;":"\u00dd",Yacute:"\u00dd","yacute;":"\u00fd",yacute:"\u00fd","YAcy;":"\u042f","yacy;":"\u044f","Ycirc;":"\u0176","ycirc;":"\u0177","Ycy;":"\u042b","ycy;":"\u044b","yen;":"\u00a5",yen:"\u00a5","Yfr;":"\ud835\udd1c","yfr;":"\ud835\udd36","YIcy;":"\u0407","yicy;":"\u0457","Yopf;":"\ud835\udd50","yopf;":"\ud835\udd6a","Yscr;":"\ud835\udcb4","yscr;":"\ud835\udcce","YUcy;":"\u042e","yucy;":"\u044e","yuml;":"\u00ff",yuml:"\u00ff","Yuml;":"\u0178","Zacute;":"\u0179","zacute;":"\u017a","Zcaron;":"\u017d","zcaron;":"\u017e","Zcy;":"\u0417","zcy;":"\u0437","Zdot;":"\u017b","zdot;":"\u017c","zeetrf;":"\u2128","ZeroWidthSpace;":"\u200b","Zeta;":"\u0396","zeta;":"\u03b6","zfr;":"\ud835\udd37","Zfr;":"\u2128","ZHcy;":"\u0416","zhcy;":"\u0436","zigrarr;":"\u21dd","zopf;":"\ud835\udd6b","Zopf;":"\u2124","Zscr;":"\ud835\udcb5","zscr;":"\ud835\udccf","zwj;":"\u200d","zwnj;":"\u200c"}},{}],13:[function(e,t,n){function u(e,t){return r.isUndefined(t)?""+t:r.isNumber(t)&&(isNaN(t)||!isFinite(t))?t.toString():r.isFunction(t)||r.isRegExp(t)?t.toString():t}function a(e,t){return r.isString(e)?e.length<t?e:e.slice(0,t):e}function f(e){return a(JSON.stringify(e.actual,u),128)+" "+e.operator+" "+a(JSON.stringify(e.expected,u),128)}function l(e,t,n,r,i){throw new o.AssertionError({message:n,actual:e,expected:t,operator:r,stackStartFunction:i})}function c(e,t){e||l(e,!0,t,"==",o.ok)}function h(e,t){if(e===t)return!0;if(r.isBuffer(e)&&r.isBuffer(t)){if(e.length!=t.length)return!1;for(var n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}return r.isDate(e)&&r.isDate(t)?e.getTime()===t.getTime():r.isRegExp(e)&&r.isRegExp(t)?e.source===t.source&&e.global===t.global&&e.multiline===t.multiline&&e.lastIndex===t.lastIndex&&e.ignoreCase===t.ignoreCase:!r.isObject(e)&&!r.isObject(t)?e==t:d(e,t)}function p(e){return Object.prototype.toString.call(e)=="[object Arguments]"}function d(e,t){if(r.isNullOrUndefined(e)||r.isNullOrUndefined(t))return!1;if(e.prototype!==t.prototype)return!1;if(p(e))return p(t)?(e=i.call(e),t=i.call(t),h(e,t)):!1;try{var n=g(e),s=g(t),o,u}catch(a){return!1}if(n.length!=s.length)return!1;n.sort(),s.sort();for(u=n.length-1;u>=0;u--)if(n[u]!=s[u])return!1;for(u=n.length-1;u>=0;u--){o=n[u];if(!h(e[o],t[o]))return!1}return!0}function v(e,t){return!e||!t?!1:Object.prototype.toString.call(t)=="[object RegExp]"?t.test(e):e instanceof t?!0:t.call({},e)===!0?!0:!1}function m(e,t,n,i){var s;r.isString(n)&&(i=n,n=null);try{t()}catch(o){s=o}i=(n&&n.name?" ("+n.name+").":".")+(i?" "+i:"."),e&&!s&&l(s,n,"Missing expected exception"+i),!e&&v(s,n)&&l(s,n,"Got unwanted exception"+i);if(e&&s&&n&&!v(s,n)||!e&&s)throw s}var r=e("util/"),i=Array.prototype.slice,s=Object.prototype.hasOwnProperty,o=t.exports=c;o.AssertionError=function(t){this.name="AssertionError",this.actual=t.actual,this.expected=t.expected,this.operator=t.operator,t.message?(this.message=t.message,this.generatedMessage=!1):(this.message=f(this),this.generatedMessage=!0);var n=t.stackStartFunction||l;if(Error.captureStackTrace)Error.captureStackTrace(this,n);else{var r=new Error;if(r.stack){var i=r.stack,s=n.name,o=i.indexOf("\n"+s);if(o>=0){var u=i.indexOf("\n",o+1);i=i.substring(u+1)}this.stack=i}}},r.inherits(o.AssertionError,Error),o.fail=l,o.ok=c,o.equal=function(t,n,r){t!=n&&l(t,n,r,"==",o.equal)},o.notEqual=function(t,n,r){t==n&&l(t,n,r,"!=",o.notEqual)},o.deepEqual=function(t,n,r){h(t,n)||l(t,n,r,"deepEqual",o.deepEqual)},o.notDeepEqual=function(t,n,r){h(t,n)&&l(t,n,r,"notDeepEqual",o.notDeepEqual)},o.strictEqual=function(t,n,r){t!==n&&l(t,n,r,"===",o.strictEqual)},o.notStrictEqual=function(t,n,r){t===n&&l(t,n,r,"!==",o.notStrictEqual)},o.throws=function(e,t,n){m.apply(this,[!0].concat(i.call(arguments)))},o.doesNotThrow=function(e,t){m.apply(this,[!1].concat(i.call(arguments)))},o.ifError=function(e){if(e)throw e};var g=Object.keys||function(e){var t=[];for(var n in e)s.call(e,n)&&t.push(n);return t}},{"util/":15}],14:[function(e,t,n){t.exports=function(t){return t&&typeof t=="object"&&typeof t.copy=="function"&&typeof t.fill=="function"&&typeof t.readUInt8=="function"}},{}],15:[function(e,t,n){(function(t,r){function u(e,t){var r={seen:[],stylize:f};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),y(t)?r.showHidden=t:t&&n._extend(r,t),T(r.showHidden)&&(r.showHidden=!1),T(r.depth)&&(r.depth=2),T(r.colors)&&(r.colors=!1),T(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=a),c(r,e,r.depth)}function a(e,t){var n=u.styles[t];return n?"["+u.colors[n][0]+"m"+e+"["+u.colors[n][1]+"m":e}function f(e,t){return e}function l(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function c(e,t,r){if(e.customInspect&&t&&A(t.inspect)&&t.inspect!==n.inspect&&(!t.constructor||t.constructor.prototype!==t)){var i=t.inspect(r,e);return S(i)||(i=c(e,i,r)),i}var s=h(e,t);if(s)return s;var o=Object.keys(t),u=l(o);e.showHidden&&(o=Object.getOwnPropertyNames(t));if(L(t)&&(o.indexOf("message")>=0||o.indexOf("description")>=0))return p(t);if(o.length===0){if(A(t)){var a=t.name?": "+t.name:"";return e.stylize("[Function"+a+"]","special")}if(N(t))return e.stylize(RegExp.prototype.toString.call(t),"regexp");if(k(t))return e.stylize(Date.prototype.toString.call(t),"date");if(L(t))return p(t)}var f="",y=!1,b=["{","}"];g(t)&&(y=!0,b=["[","]"]);if(A(t)){var w=t.name?": "+t.name:"";f=" [Function"+w+"]"}N(t)&&(f=" "+RegExp.prototype.toString.call(t)),k(t)&&(f=" "+Date.prototype.toUTCString.call(t)),L(t)&&(f=" "+p(t));if(o.length!==0||!!y&&t.length!=0){if(r<0)return N(t)?e.stylize(RegExp.prototype.toString.call(t),"regexp"):e.stylize("[Object]","special");e.seen.push(t);var E;return y?E=d(e,t,r,u,o):E=o.map(function(n){return v(e,t,r,u,n,y)}),e.seen.pop(),m(E,f,b)}return b[0]+f+b[1]}function h(e,t){if(T(t))return e.stylize("undefined","undefined");if(S(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}if(E(t))return e.stylize(""+t,"number");if(y(t))return e.stylize(""+t,"boolean");if(b(t))return e.stylize("null","null")}function p(e){return"["+Error.prototype.toString.call(e)+"]"}function d(e,t,n,r,i){var s=[];for(var o=0,u=t.length;o<u;++o)H(t,String(o))?s.push(v(e,t,n,r,String(o),!0)):s.push("");return i.forEach(function(i){i.match(/^\d+$/)||s.push(v(e,t,n,r,i,!0))}),s}function v(e,t,n,r,i,s){var o,u,a;a=Object.getOwnPropertyDescriptor(t,i)||{value:t[i]},a.get?a.set?u=e.stylize("[Getter/Setter]","special"):u=e.stylize("[Getter]","special"):a.set&&(u=e.stylize("[Setter]","special")),H(r,i)||(o="["+i+"]"),u||(e.seen.indexOf(a.value)<0?(b(n)?u=c(e,a.value,null):u=c(e,a.value,n-1),u.indexOf("\n")>-1&&(s?u=u.split("\n").map(function(e){return"  "+e}).join("\n").substr(2):u="\n"+u.split("\n").map(function(e){return"   "+e}).join("\n"))):u=e.stylize("[Circular]","special"));if(T(o)){if(s&&i.match(/^\d+$/))return u;o=JSON.stringify(""+i),o.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(o=o.substr(1,o.length-2),o=e.stylize(o,"name")):(o=o.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),o=e.stylize(o,"string"))}return o+": "+u}function m(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(t===""?"":t+"\n ")+" "+e.join(",\n  ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function g(e){return Array.isArray(e)}function y(e){return typeof e=="boolean"}function b(e){return e===null}function w(e){return e==null}function E(e){return typeof e=="number"}function S(e){return typeof e=="string"}function x(e){return typeof e=="symbol"}function T(e){return e===void 0}function N(e){return C(e)&&M(e)==="[object RegExp]"}function C(e){return typeof e=="object"&&e!==null}function k(e){return C(e)&&M(e)==="[object Date]"}function L(e){return C(e)&&(M(e)==="[object Error]"||e instanceof Error)}function A(e){return typeof e=="function"}function O(e){return e===null||typeof e=="boolean"||typeof e=="number"||typeof e=="string"||typeof e=="symbol"||typeof e=="undefined"}function M(e){return Object.prototype.toString.call(e)}function _(e){return e<10?"0"+e.toString(10):e.toString(10)}function P(){var e=new Date,t=[_(e.getHours()),_(e.getMinutes()),_(e.getSeconds())].join(":");return[e.getDate(),D[e.getMonth()],t].join(" ")}function H(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var i=/%[sdj%]/g;n.format=function(e){if(!S(e)){var t=[];for(var n=0;n<arguments.length;n++)t.push(u(arguments[n]));return t.join(" ")}var n=1,r=arguments,s=r.length,o=String(e).replace(i,function(e){if(e==="%%")return"%";if(n>=s)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"};default:return e}});for(var a=r[n];n<s;a=r[++n])b(a)||!C(a)?o+=" "+a:o+=" "+u(a);return o},n.deprecate=function(e,i){function o(){if(!s){if(t.throwDeprecation)throw new Error(i);t.traceDeprecation?console.trace(i):console.error(i),s=!0}return e.apply(this,arguments)}if(T(r.process))return function(){return n.deprecate(e,i).apply(this,arguments)};if(t.noDeprecation===!0)return e;var s=!1;return o};var s={},o;n.debuglog=function(e){T(o)&&(o=t.env.NODE_DEBUG||""),e=e.toUpperCase();if(!s[e])if((new RegExp("\\b"+e+"\\b","i")).test(o)){var r=t.pid;s[e]=function(){var t=n.format.apply(n,arguments);console.error("%s %d: %s",e,r,t)}}else s[e]=function(){};return s[e]},n.inspect=u,u.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},u.styles={special:"cyan",number:"yellow","boolean":"yellow","undefined":"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},n.isArray=g,n.isBoolean=y,n.isNull=b,n.isNullOrUndefined=w,n.isNumber=E,n.isString=S,n.isSymbol=x,n.isUndefined=T,n.isRegExp=N,n.isObject=C,n.isDate=k,n.isError=L,n.isFunction=A,n.isPrimitive=O,n.isBuffer=e("./support/isBuffer");var D=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];n.log=function(){console.log("%s - %s",P(),n.format.apply(n,arguments))},n.inherits=e("inherits"),n._extend=function(e,t){if(!t||!C(t))return e;var n=Object.keys(t),r=n.length;while(r--)e[n[r]]=t[n[r]];return e}}).call(this,e("/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"),typeof self!="undefined"?self:typeof window!="undefined"?window:{})},{"./support/isBuffer":14,"/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":18,inherits:17}],16:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||undefined}function i(e){return typeof e=="function"}function s(e){return typeof e=="number"}function o(e){return typeof e=="object"&&e!==null}function u(e){return e===void 0}t.exports=r,r.EventEmitter=r,r.prototype._events=undefined,r.prototype._maxListeners=undefined,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!s(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,s,a,f;this._events||(this._events={});if(e==="error")if(!this._events.error||o(this._events.error)&&!this._events.error.length)throw t=arguments[1],t instanceof Error?t:TypeError('Uncaught, unspecified "error" event.');n=this._events[e];if(u(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];n.apply(this,s)}else if(o(n)){r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];f=n.slice(),r=f.length;for(a=0;a<r;a++)f[a].apply(this,s)}return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t;if(o(this._events[e])&&!this._events[e].warned){var n;u(this._maxListeners)?n=r.defaultMaxListeners:n=this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var n=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,s,u;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;n=this._events[e],s=n.length,r=-1;if(n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(u=s;u-->0;)if(n[u]===t||n[u].listener&&n[u].listener===t){r=u;break}if(r<0)return this;n.length===1?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return arguments.length===0?this._events={}:this._events[e]&&delete this._events[e],this;if(arguments.length===0){for(t in this._events){if(t==="removeListener")continue;this.removeAllListeners(t)}return this.removeAllListeners("removeListener"),this._events={},this}n=this._events[e];if(i(n))this.removeListener(e,n);else while(n.length)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return!this._events||!this._events[e]?t=[]:i(this._events[e])?t=[this._events[e]]:t=this._events[e].slice(),t},r.listenerCount=function(e,t){var n;return!e._events||!e._events[t]?n=0:i(e._events[t])?n=1:n=e._events[t].length,n}},{}],17:[function(e,t,n){typeof Object.create=="function"?t.exports=function(t,n){t.super_=n,t.prototype=Object.create(n.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:t.exports=function(t,n){t.super_=n;var r=function(){};r.prototype=n.prototype,t.prototype=new r,t.prototype.constructor=t}},{}],18:[function(e,t,n){function i(){}var r=t.exports={};r.nextTick=function(){var e=typeof window!="undefined"&&window.setImmediate,t=typeof window!="undefined"&&window.postMessage&&window.addEventListener;if(e)return function(e){return window.setImmediate(e)};if(t){var n=[];return window.addEventListener("message",function(e){var t=e.source;if((t===window||t===null)&&e.data==="process-tick"){e.stopPropagation();if(n.length>0){var r=n.shift();r()}}},!0),function(t){n.push(t),window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}(),r.title="browser",r.browser=!0,r.env={},r.argv=[],r.on=i,r.once=i,r.off=i,r.emit=i,r.binding=function(e){throw new Error("process.binding is not supported")},r.cwd=function(){return"/"},r.chdir=function(e){throw new Error("process.chdir is not supported")}},{}],19:[function(e,t,n){t.exports=e(14)},{}],20:[function(e,t,n){t.exports=e(15)},{"./support/isBuffer":19,"/usr/local/lib/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":18,inherits:17}]},{},[9])(9)}),ace.define("ace/mode/html_worker",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/worker/mirror","ace/mode/html/saxparser"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../lib/lang"),s=e("../worker/mirror").Mirror,o=e("./html/saxparser").SAXParser,u={"expected-doctype-but-got-start-tag":"info","expected-doctype-but-got-chars":"info","non-html-root":"info"},a=t.Worker=function(e){s.call(this,e),this.setTimeout(400),this.context=null};r.inherits(a,s),function(){this.setOptions=function(e){this.context=e.context},this.onUpdate=function(){var e=this.doc.getValue();if(!e)return;var t=new o,n=[],r=function(){};t.contentHandler={startDocument:r,endDocument:r,startElement:r,endElement:r,characters:r},t.errorHandler={error:function(e,t,r){n.push({row:t.line,column:t.column,text:e,type:u[r]||"error"})}},this.context?t.parseFragment(e,this.context):t.parse(e),this.sender.emit("error",n)}}.call(a.prototype)}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _="	\n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/worker-javascript.js b/dist/assets/js/vendor/ace-nc/worker-javascript.js
            new file mode 100644
            index 0000000000..2ba1a1135a
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/worker-javascript.js
            @@ -0,0 +1 @@
            +"no use strict";(function(e){if(typeof e.window!="undefined"&&e.document)return;e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console,e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){console.error("Worker "+(i?i.stack:e))},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(t,n){n||(n=t,t=null);if(!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;var i=n.split("/");if(!e.require.tlns)return console.log("unable to load "+n);i[0]=e.require.tlns[i[0]]||i[0];var s=i.join("/")+".js";return e.require.id=n,importScripts(s),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id),n.length||(n=["require","exports","module"]);if(t.indexOf("text!")===0)return;var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},e.initBaseUrls=function(t){require.tlns=t},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var i=r.data;if(i.command){if(!t[i.command])throw new Error("Unknown command:"+i.command);t[i.command].apply(t,i.args)}else if(i.init){initBaseUrls(i.tlns),require("ace/lib/es5-shim"),n=e.sender=initSender();var s=require(i.module)[i.classname];t=e.main=new s(n)}else i.event&&n&&n._signal(i.event,i.data)}})(this),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action==="insertText")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action==="insertLines"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action==="removeText"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action=="removeLines"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[""]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},"\n"+t.join("\n")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._signal("change",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._signal("change",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._signal("change",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._signal("change",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this._insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]=="object"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/worker/mirror",["require","exports","module","ace/document","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../document").Document,i=e("../lib/lang"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=i.delayedCall(this.onUpdate.bind(this)),s=this;e.on("change",function(e){t.applyDeltas(e.data);if(s.$timeout)return n.schedule(s.$timeout);s.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(s.prototype)}),ace.define("ace/mode/javascript/jshint",["require","exports","module"],function(e,t,n){n.exports=function r(t,n,i){function s(u,a){if(!n[u]){if(!t[u]){var f=typeof e=="function"&&e;if(!a&&f)return f(u,!0);if(o)return o(u,!0);throw new Error("Cannot find module '"+u+"'")}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return s(n?n:e)},l,l.exports,r,t,n,i)}return n[u].exports}var o=typeof e=="function"&&e;for(var u=0;u<i.length;u++)s(i[u]);return s}({1:[function(e,t,n){var r=[];for(var i=0;i<128;i++)r[i]=i===36||i>=65&&i<=90||i===95||i>=97&&i<=122;var s=[];for(var i=0;i<128;i++)s[i]=r[i]||i>=48&&i<=57;t.exports={asciiIdentifierStartTable:r,asciiIdentifierPartTable:s}},{}],2:[function(e,t,n){(function(){var e=this,r=e._,i={},s=Array.prototype,o=Object.prototype,u=Function.prototype,a=s.push,f=s.slice,l=s.concat,c=o.toString,h=o.hasOwnProperty,p=s.forEach,d=s.map,v=s.reduce,m=s.reduceRight,g=s.filter,y=s.every,b=s.some,w=s.indexOf,E=s.lastIndexOf,S=Array.isArray,x=Object.keys,T=u.bind,N=function(e){if(e instanceof N)return e;if(!(this instanceof N))return new N(e);this._wrapped=e};typeof n!="undefined"?(typeof t!="undefined"&&t.exports&&(n=t.exports=N),n._=N):e._=N,N.VERSION="1.6.0";var C=N.each=N.forEach=function(e,t,n){if(e==null)return e;if(p&&e.forEach===p)e.forEach(t,n);else if(e.length===+e.length){for(var r=0,s=e.length;r<s;r++)if(t.call(n,e[r],r,e)===i)return}else{var o=N.keys(e);for(var r=0,s=o.length;r<s;r++)if(t.call(n,e[o[r]],o[r],e)===i)return}return e};N.map=N.collect=function(e,t,n){var r=[];return e==null?r:d&&e.map===d?e.map(t,n):(C(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var k="Reduce of empty array with no initial value";N.reduce=N.foldl=N.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(v&&e.reduce===v)return r&&(t=N.bind(t,r)),i?e.reduce(t,n):e.reduce(t);C(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(k);return n},N.reduceRight=N.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(m&&e.reduceRight===m)return r&&(t=N.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=N.keys(e);s=o.length}C(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(k);return n},N.find=N.detect=function(e,t,n){var r;return L(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},N.filter=N.select=function(e,t,n){var r=[];return e==null?r:g&&e.filter===g?e.filter(t,n):(C(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},N.reject=function(e,t,n){return N.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},N.every=N.all=function(e,t,n){t||(t=N.identity);var r=!0;return e==null?r:y&&e.every===y?e.every(t,n):(C(e,function(e,s,o){if(!(r=r&&t.call(n,e,s,o)))return i}),!!r)};var L=N.some=N.any=function(e,t,n){t||(t=N.identity);var r=!1;return e==null?r:b&&e.some===b?e.some(t,n):(C(e,function(e,s,o){if(r||(r=t.call(n,e,s,o)))return i}),!!r)};N.contains=N.include=function(e,t){return e==null?!1:w&&e.indexOf===w?e.indexOf(t)!=-1:L(e,function(e){return e===t})},N.invoke=function(e,t){var n=f.call(arguments,2),r=N.isFunction(t);return N.map(e,function(e){return(r?t:e[t]).apply(e,n)})},N.pluck=function(e,t){return N.map(e,N.property(t))},N.where=function(e,t){return N.filter(e,N.matches(t))},N.findWhere=function(e,t){return N.find(e,N.matches(t))},N.max=function(e,t,n){if(!t&&N.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);var r=-Infinity,i=-Infinity;return C(e,function(e,s,o){var u=t?t.call(n,e,s,o):e;u>i&&(r=e,i=u)}),r},N.min=function(e,t,n){if(!t&&N.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);var r=Infinity,i=Infinity;return C(e,function(e,s,o){var u=t?t.call(n,e,s,o):e;u<i&&(r=e,i=u)}),r},N.shuffle=function(e){var t,n=0,r=[];return C(e,function(e){t=N.random(n++),r[n-1]=r[t],r[t]=e}),r},N.sample=function(e,t,n){return t==null||n?(e.length!==+e.length&&(e=N.values(e)),e[N.random(e.length-1)]):N.shuffle(e).slice(0,Math.max(0,t))};var A=function(e){return e==null?N.identity:N.isFunction(e)?e:N.property(e)};N.sortBy=function(e,t,n){return t=A(t),N.pluck(N.map(e,function(e,r,i){return{value:e,index:r,criteria:t.call(n,e,r,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index-t.index}),"value")};var O=function(e){return function(t,n,r){var i={};return n=A(n),C(t,function(s,o){var u=n.call(r,s,o,t);e(i,u,s)}),i}};N.groupBy=O(function(e,t,n){N.has(e,t)?e[t].push(n):e[t]=[n]}),N.indexBy=O(function(e,t,n){e[t]=n}),N.countBy=O(function(e,t){N.has(e,t)?e[t]++:e[t]=1}),N.sortedIndex=function(e,t,n,r){n=A(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},N.toArray=function(e){return e?N.isArray(e)?f.call(e):e.length===+e.length?N.map(e,N.identity):N.values(e):[]},N.size=function(e){return e==null?0:e.length===+e.length?e.length:N.keys(e).length},N.first=N.head=N.take=function(e,t,n){return e==null?void 0:t==null||n?e[0]:t<0?[]:f.call(e,0,t)},N.initial=function(e,t,n){return f.call(e,0,e.length-(t==null||n?1:t))},N.last=function(e,t,n){return e==null?void 0:t==null||n?e[e.length-1]:f.call(e,Math.max(e.length-t,0))},N.rest=N.tail=N.drop=function(e,t,n){return f.call(e,t==null||n?1:t)},N.compact=function(e){return N.filter(e,N.identity)};var M=function(e,t,n){return t&&N.every(e,N.isArray)?l.apply(n,e):(C(e,function(e){N.isArray(e)||N.isArguments(e)?t?a.apply(n,e):M(e,t,n):n.push(e)}),n)};N.flatten=function(e,t){return M(e,t,[])},N.without=function(e){return N.difference(e,f.call(arguments,1))},N.partition=function(e,t){var n=[],r=[];return C(e,function(e){(t(e)?n:r).push(e)}),[n,r]},N.uniq=N.unique=function(e,t,n,r){N.isFunction(t)&&(r=n,n=t,t=!1);var i=n?N.map(e,n,r):e,s=[],o=[];return C(i,function(n,r){if(t?!r||o[o.length-1]!==n:!N.contains(o,n))o.push(n),s.push(e[r])}),s},N.union=function(){return N.uniq(N.flatten(arguments,!0))},N.intersection=function(e){var t=f.call(arguments,1);return N.filter(N.uniq(e),function(e){return N.every(t,function(t){return N.contains(t,e)})})},N.difference=function(e){var t=l.apply(s,f.call(arguments,1));return N.filter(e,function(e){return!N.contains(t,e)})},N.zip=function(){var e=N.max(N.pluck(arguments,"length").concat(0)),t=new Array(e);for(var n=0;n<e;n++)t[n]=N.pluck(arguments,""+n);return t},N.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},N.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=N.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(w&&e.indexOf===w)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},N.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(E&&e.lastIndexOf===E)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},N.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var _=function(){};N.bind=function(e,t){var n,r;if(T&&e.bind===T)return T.apply(e,f.call(arguments,1));if(!N.isFunction(e))throw new TypeError;return n=f.call(arguments,2),r=function(){if(this instanceof r){_.prototype=e.prototype;var i=new _;_.prototype=null;var s=e.apply(i,n.concat(f.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(f.call(arguments)))}},N.partial=function(e){var t=f.call(arguments,1);return function(){var n=0,r=t.slice();for(var i=0,s=r.length;i<s;i++)r[i]===N&&(r[i]=arguments[n++]);while(n<arguments.length)r.push(arguments[n++]);return e.apply(this,r)}},N.bindAll=function(e){var t=f.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return C(t,function(t){e[t]=N.bind(e[t],e)}),e},N.memoize=function(e,t){var n={};return t||(t=N.identity),function(){var r=t.apply(this,arguments);return N.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},N.delay=function(e,t){var n=f.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},N.defer=function(e){return N.delay.apply(N,[e,1].concat(f.call(arguments,1)))},N.throttle=function(e,t,n){var r,i,s,o=null,u=0;n||(n={});var a=function(){u=n.leading===!1?0:N.now(),o=null,s=e.apply(r,i),r=i=null};return function(){var f=N.now();!u&&n.leading===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(o),o=null,u=f,s=e.apply(r,i),r=i=null):!o&&n.trailing!==!1&&(o=setTimeout(a,l)),s}},N.debounce=function(e,t,n){var r,i,s,o,u,a=function(){var f=N.now()-o;f<t?r=setTimeout(a,t-f):(r=null,n||(u=e.apply(s,i),s=i=null))};return function(){s=this,i=arguments,o=N.now();var f=n&&!r;return r||(r=setTimeout(a,t)),f&&(u=e.apply(s,i),s=i=null),u}},N.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},N.wrap=function(e,t){return N.partial(t,e)},N.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},N.after=function(e,t){return function(){if(--e<1)return t.apply(this,arguments)}},N.keys=function(e){if(!N.isObject(e))return[];if(x)return x(e);var t=[];for(var n in e)N.has(e,n)&&t.push(n);return t},N.values=function(e){var t=N.keys(e),n=t.length,r=new Array(n);for(var i=0;i<n;i++)r[i]=e[t[i]];return r},N.pairs=function(e){var t=N.keys(e),n=t.length,r=new Array(n);for(var i=0;i<n;i++)r[i]=[t[i],e[t[i]]];return r},N.invert=function(e){var t={},n=N.keys(e);for(var r=0,i=n.length;r<i;r++)t[e[n[r]]]=n[r];return t},N.functions=N.methods=function(e){var t=[];for(var n in e)N.isFunction(e[n])&&t.push(n);return t.sort()},N.extend=function(e){return C(f.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},N.pick=function(e){var t={},n=l.apply(s,f.call(arguments,1));return C(n,function(n){n in e&&(t[n]=e[n])}),t},N.omit=function(e){var t={},n=l.apply(s,f.call(arguments,1));for(var r in e)N.contains(n,r)||(t[r]=e[r]);return t},N.defaults=function(e){return C(f.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},N.clone=function(e){return N.isObject(e)?N.isArray(e)?e.slice():N.extend({},e):e},N.tap=function(e,t){return t(e),e};var D=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof N&&(e=e._wrapped),t instanceof N&&(t=t._wrapped);var i=c.call(e);if(i!=c.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;var o=e.constructor,u=t.constructor;if(o!==u&&!(N.isFunction(o)&&o instanceof o&&N.isFunction(u)&&u instanceof u)&&"constructor"in e&&"constructor"in t)return!1;n.push(e),r.push(t);var a=0,f=!0;if(i=="[object Array]"){a=e.length,f=a==t.length;if(f)while(a--)if(!(f=D(e[a],t[a],n,r)))break}else{for(var l in e)if(N.has(e,l)){a++;if(!(f=N.has(t,l)&&D(e[l],t[l],n,r)))break}if(f){for(l in t)if(N.has(t,l)&&!(a--))break;f=!a}}return n.pop(),r.pop(),f};N.isEqual=function(e,t){return D(e,t,[],[])},N.isEmpty=function(e){if(e==null)return!0;if(N.isArray(e)||N.isString(e))return e.length===0;for(var t in e)if(N.has(e,t))return!1;return!0},N.isElement=function(e){return!!e&&e.nodeType===1},N.isArray=S||function(e){return c.call(e)=="[object Array]"},N.isObject=function(e){return e===Object(e)},C(["Arguments","Function","String","Number","Date","RegExp"],function(e){N["is"+e]=function(t){return c.call(t)=="[object "+e+"]"}}),N.isArguments(arguments)||(N.isArguments=function(e){return!!e&&!!N.has(e,"callee")}),typeof /./!="function"&&(N.isFunction=function(e){return typeof e=="function"}),N.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},N.isNaN=function(e){return N.isNumber(e)&&e!=+e},N.isBoolean=function(e){return e===!0||e===!1||c.call(e)=="[object Boolean]"},N.isNull=function(e){return e===null},N.isUndefined=function(e){return e===void 0},N.has=function(e,t){return h.call(e,t)},N.noConflict=function(){return e._=r,this},N.identity=function(e){return e},N.constant=function(e){return function(){return e}},N.property=function(e){return function(t){return t[e]}},N.matches=function(e){return function(t){if(t===e)return!0;for(var n in e)if(e[n]!==t[n])return!1;return!0}},N.times=function(e,t,n){var r=Array(Math.max(0,e));for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},N.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))},N.now=Date.now||function(){return(new Date).getTime()};var P={escape:{"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;"}};P.unescape=N.invert(P.escape);var H={escape:new RegExp("["+N.keys(P.escape).join("")+"]","g"),unescape:new RegExp("("+N.keys(P.unescape).join("|")+")","g")};N.each(["escape","unescape"],function(e){N[e]=function(t){return t==null?"":(""+t).replace(H[e],function(t){return P[e][t]})}}),N.result=function(e,t){if(e==null)return void 0;var n=e[t];return N.isFunction(n)?n.call(e):n},N.mixin=function(e){C(N.functions(e),function(t){var n=N[t]=e[t];N.prototype[t]=function(){var e=[this._wrapped];return a.apply(e,arguments),q.call(this,n.apply(N,e))}})};var B=0;N.uniqueId=function(e){var t=++B+"";return e?e+t:t},N.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var j=/(.)^/,F={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","\u2029":"u2029"},I=/\\|'|\r|\n|\t|\u2028|\u2029/g;N.template=function(e,t,n){var r;n=N.defaults({},n,N.templateSettings);var i=new RegExp([(n.escape||j).source,(n.interpolate||j).source,(n.evaluate||j).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(I,function(e){return"\\"+F[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,N);var a=function(e){return r.call(this,e,N)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},N.chain=function(e){return N(e).chain()};var q=function(e){return this._chain?N(e).chain():e};N.mixin(N),C(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=s[e];N.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],q.call(this,n)}}),C(["concat","join","slice"],function(e){var t=s[e];N.prototype[e]=function(){return q.call(this,t.apply(this._wrapped,arguments))}}),N.extend(N.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}}),typeof define=="function"&&define.amd&&ace.define("underscore",[],function(){return N})}).call(this)},{}],3:[function(e,t,n){var r=e("underscore"),i=e("events"),s=e("./vars.js"),o=e("./messages.js"),u=e("./lex.js").Lexer,a=e("./reg.js"),f=e("./state.js").state,l=e("./style.js"),c=function(){"use strict";function I(e,t){return e=e.trim(),/^[+-]W\d{3}$/g.test(e)?!0:p[e]===undefined&&h[e]===undefined&&t.type!=="jslint"&&!m[e]?(G("E001",t,e),!1):!0}function q(e){return Object.prototype.toString.call(e)==="[object String]"}function R(e,t){return e?!e.identifier||e.value!==t?!1:!0:!1}function U(e){if(!e.reserved)return!1;var t=e.meta;if(t&&t.isFutureReservedWord&&f.option.inES5()){if(!t.es5)return!1;if(t.strictOnly&&!f.option.strict&&!f.directive["use strict"])return!1;if(e.isProperty)return!1}return!0}function z(e,t){return e.replace(/\{([^{}]*)\}/g,function(e,n){var r=t[n];return typeof r=="string"||typeof r=="number"?r:e})}function W(e,t){Object.keys(t).forEach(function(n){if(r.has(c.blacklist,n))return;e[n]=t[n]})}function X(){f.option.esnext&&W(M,s.newEcmaIdentifiers),f.option.couch&&W(M,s.couch),f.option.qunit&&W(M,s.qunit),f.option.rhino&&W(M,s.rhino),f.option.shelljs&&(W(M,s.shelljs),W(M,s.node)),f.option.typed&&W(M,s.typed),f.option.phantom&&W(M,s.phantom),f.option.prototypejs&&W(M,s.prototypejs),f.option.node&&(W(M,s.node),W(M,s.typed)),f.option.devel&&W(M,s.devel),f.option.dojo&&W(M,s.dojo),f.option.browser&&(W(M,s.browser),W(M,s.typed)),f.option.nonstandard&&W(M,s.nonstandard),f.option.jasmine&&W(M,s.jasmine),f.option.jquery&&W(M,s.jquery),f.option.mootools&&W(M,s.mootools),f.option.worker&&W(M,s.worker),f.option.wsh&&W(M,s.wsh),f.option.globalstrict&&f.option.strict!==!1&&(f.option.strict=!0),f.option.yui&&W(M,s.yui),f.option.mocha&&W(M,s.mocha),f.option.inMoz=function(e){return f.option.moz},f.option.inESNext=function(e){return f.option.moz||f.option.esnext},f.option.inES5=function(){return!f.option.es3},f.option.inES3=function(e){return e?!f.option.moz&&!f.option.esnext&&f.option.es3:f.option.es3}}function V(e,t,n){var r=Math.floor(t/f.lines.length*100),i=o.errors[e].desc;throw{name:"JSHintError",line:t,character:n,message:i+" ("+r+"% scanned).",raw:i,code:e}}function $(e,t,n,r){return c.undefs.push([e,t,n,r])}function J(){var e=f.ignoredLines;if(r.isEmpty(e))return;c.errors=r.reject(c.errors,function(t){return e[t.line]})}function K(e,t,n,r,i,s){var u,a,l,h;if(/^W\d{3}$/.test(e)){if(f.ignored[e])return;h=o.warnings[e]}else/E\d{3}/.test(e)?h=o.errors[e]:/I\d{3}/.test(e)&&(h=o.info[e]);return t=t||f.tokens.next,t.id==="(end)"&&(t=f.tokens.curr),a=t.line||0,u=t.from||0,l={id:"(error)",raw:h.desc,code:h.code,evidence:f.lines[a-1]||"",line:a,character:u,scope:c.scope,a:n,b:r,c:i,d:s},l.reason=z(h.desc,l),c.errors.push(l),J(),c.errors.length>=f.option.maxerr&&V("E043",a,u),l}function Q(e,t,n,r,i,s,o){return K(e,{line:t,from:n},r,i,s,o)}function G(e,t,n,r,i,s){K(e,t,n,r,i,s)}function Y(e,t,n,r,i,s,o){return G(e,{line:t,from:n},r,i,s,o)}function Z(e,t){var n;return n={id:"(internal)",elem:e,value:t},c.internals.push(n),n}function et(e,t){t=t||{};var n=t.type,i=t.token,s=t.islet;n==="exception"&&r.has(w["(context)"],e)&&w[e]!==!0&&!f.option.node&&K("W002",f.tokens.next,e),r.has(w,e)&&!w["(global)"]&&(w[e]===!0?f.option.latedef&&(f.option.latedef===!0&&r.contains([w[e],n],"unction")||!r.contains([w[e],n],"unction"))&&K("W003",f.tokens.next,e):((!f.option.shadow||r.contains(["inner","outer"],f.option.shadow))&&n!=="exception"||w["(blockscope)"].getlabel(e))&&K("W004",f.tokens.next,e)),w["(context)"]&&r.has(w["(context)"],e)&&n!=="function"&&f.option.shadow==="outer"&&K("W123",f.tokens.next,e),s?w["(blockscope)"].current.add(e,n,f.tokens.curr):(w["(blockscope)"].shadow(e),w[e]=n,i&&(w["(tokens)"][e]=i),Xt(w,e,{unused:t.unused||!1}),w["(global)"]?(S[e]=w,r.has(x,e)&&(f.option.latedef&&(f.option.latedef===!0&&r.contains([w[e],n],"unction")||!r.contains([w[e],n],"unction"))&&K("W003",f.tokens.next,e),delete x[e])):D[e]=w)}function tt(){var e=f.tokens.next,t=e.body.match(/(-\s+)?[^\s,:]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g),n={};if(e.type==="globals"){t.forEach(function(e){e=e.split(":");var t=(e[0]||"").trim(),r=(e[1]||"").trim();t.charAt(0)==="-"?(t=t.slice(1),r=!1,c.blacklist[t]=t,delete M[t]):n[t]=r==="true"}),W(M,n);for(var i in n)r.has(n,i)&&(g[i]=e)}e.type==="exported"&&t.forEach(function(e){y[e]=!0}),e.type==="members"&&(A=A||{},t.forEach(function(e){var t=e.charAt(0),n=e.charAt(e.length-1);t===n&&(t==='"'||t==="'")&&(e=e.substr(1,e.length-2).replace('\\"','"')),A[e]=!1}));var s=["maxstatements","maxparams","maxdepth","maxcomplexity","maxerr","maxlen","indent"];if(e.type==="jshint"||e.type==="jslint")t.forEach(function(t){t=t.split(":");var n=(t[0]||"").trim(),r=(t[1]||"").trim();if(!I(n,e))return;if(s.indexOf(n)>=0){if(r!=="false"){r=+r;if(typeof r!="number"||!isFinite(r)||r<=0||Math.floor(r)!==r){G("E032",e,t[1].trim());return}f.option[n]=r}else f.option[n]=n==="indent"?4:!1;return}if(n==="validthis"){if(w["(global)"])return void G("E009");if(r!=="true"&&r!=="false")return void G("E002",e);f.option.validthis=r==="true";return}if(n==="quotmark"){switch(r){case"true":case"false":f.option.quotmark=r==="true";break;case"double":case"single":f.option.quotmark=r;break;default:G("E002",e)}return}if(n==="shadow"){switch(r){case"true":f.option.shadow=!0;break;case"outer":f.option.shadow="outer";break;case"false":case"inner":f.option.shadow="inner";break;default:G("E002",e)}return}if(n==="unused"){switch(r){case"true":f.option.unused=!0;break;case"false":f.option.unused=!1;break;case"vars":case"strict":f.option.unused=r;break;default:G("E002",e)}return}if(n==="latedef"){switch(r){case"true":f.option.latedef=!0;break;case"false":f.option.latedef=!1;break;case"nofunc":f.option.latedef="nofunc";break;default:G("E002",e)}return}if(n==="ignore"){switch(r){case"start":f.ignoreLinterErrors=!0;break;case"end":f.ignoreLinterErrors=!1;break;case"line":f.ignoredLines[e.line]=!0,J();break;default:G("E002",e)}return}var i=/^([+-])(W\d{3})$/g.exec(n);if(i){f.ignored[i[2]]=i[1]==="-";return}var o;if(r==="true"||r==="false"){e.type==="jslint"?(o=v[n]||n,f.option[o]=r==="true",d[o]!==undefined&&(f.option[o]=!f.option[o])):f.option[n]=r==="true",n==="newcap"&&(f.option["(explicitNewcap)"]=!0);return}G("E002",e)}),X()}function nt(e){var t=e||0,n=0,r;while(n<=t)r=C[n],r||(r=C[n]=k.token()),n+=1;return r}function rt(t,n){switch(f.tokens.curr.id){case"(number)":f.tokens.next.id==="."&&K("W005",f.tokens.curr);break;case"-":(f.tokens.next.id==="-"||f.tokens.next.id==="--")&&K("W006");break;case"+":(f.tokens.next.id==="+"||f.tokens.next.id==="++")&&K("W007")}if(f.tokens.curr.type==="(string)"||f.tokens.curr.identifier)e=f.tokens.curr.value;t&&f.tokens.next.id!==t&&(n?f.tokens.next.id==="(end)"?G("E019",n,n.id):G("E020",f.tokens.next,t,n.id,n.line,f.tokens.next.value):(f.tokens.next.type!=="(identifier)"||f.tokens.next.value!==t)&&K("W116",f.tokens.next,t,f.tokens.next.value)),f.tokens.prev=f.tokens.curr,f.tokens.curr=f.tokens.next;for(;;){f.tokens.next=C.shift()||k.token(),f.tokens.next||V("E041",f.tokens.curr.line);if(f.tokens.next.id==="(end)"||f.tokens.next.id==="(error)")return;f.tokens.next.check&&f.tokens.next.check();if(f.tokens.next.isSpecial)tt();else if(f.tokens.next.id!=="(endline)")break}}function it(e){return e.infix||!e.identifier&&!!e.led}function st(){var e=f.tokens.curr,t=f.tokens.next;return t.id===";"||t.id==="}"||t.id===":"?!0:it(t)===it(e)||e.id==="yield"&&f.option.inMoz(!0)?e.line!==t.line:!1}function ot(t,n){var i,s=!1,o=!1,u=!1;!n&&f.tokens.next.value==="let"&&nt(0).value==="("&&(f.option.inMoz(!0)||K("W118",f.tokens.next,"let expressions"),u=!0,w["(blockscope)"].stack(),rt("let"),rt("("),f.syntax.let.fud.call(f.syntax.let.fud,!1),rt(")")),f.tokens.next.id==="(end)"&&G("E006",f.tokens.curr);var a=f.option.asi&&f.tokens.prev.line<f.tokens.curr.line&&r.contains(["]",")"],f.tokens.prev.id)&&r.contains(["[","("],f.tokens.curr.id);a&&K("W014",f.tokens.curr,f.tokens.curr.id),rt(),n&&(e="anonymous",w["(verb)"]=f.tokens.curr.value);if(n===!0&&f.tokens.curr.fud)i=f.tokens.curr.fud();else{f.tokens.curr.nud?i=f.tokens.curr.nud():G("E030",f.tokens.curr,f.tokens.curr.id);while(t<f.tokens.next.lbp&&!st())s=f.tokens.curr.value==="Array",o=f.tokens.curr.value==="Object",i&&(i.value||i.first&&i.first.value)&&(i.value!=="new"||i.first&&i.first.value&&i.first.value===".")&&(s=!1,i.value!==f.tokens.curr.value&&(o=!1)),rt(),s&&f.tokens.curr.id==="("&&f.tokens.next.id===")"&&K("W009",f.tokens.curr),o&&f.tokens.curr.id==="("&&f.tokens.next.id===")"&&K("W010",f.tokens.curr),i&&f.tokens.curr.led?i=f.tokens.curr.led(i):G("E033",f.tokens.curr,f.tokens.curr.id)}return u&&w["(blockscope)"].unstack(),i}function ut(e,t){e=e||f.tokens.curr,t=t||f.tokens.next,!f.option.laxbreak&&e.line!==t.line&&K("W014",t,t.value)}function at(e){e=e||f.tokens.curr,e.line!==f.tokens.next.line&&K("E022",e,e.value)}function ft(e,t){e.line!==t.line&&(f.option.laxcomma||(lt.first&&(K("I001"),lt.first=!1),K("W014",e,t.value)))}function lt(e){e=e||{},e.peek?ft(f.tokens.prev,f.tokens.curr):(ft(f.tokens.curr,f.tokens.next),rt(","));if(f.tokens.next.identifier&&(!e.property||!f.option.inES5()))switch(f.tokens.next.value){case"break":case"case":case"catch":case"continue":case"default":case"do":case"else":case"finally":case"for":case"if":case"in":case"instanceof":case"return":case"switch":case"throw":case"try":case"var":case"let":case"while":case"with":return G("E024",f.tokens.next,f.tokens.next.value),!1}if(f.tokens.next.type==="(punctuator)")switch(f.tokens.next.value){case"}":case"]":case",":if(e.allowTrailing)return!0;case")":return G("E024",f.tokens.next,f.tokens.next.value),!1}return!0}function ct(e,t){var n=f.syntax[e];if(!n||typeof n!="object")f.syntax[e]=n={id:e,lbp:t,value:e};return n}function ht(e){return ct(e,0)}function pt(e,t){var n=ht(e);return n.identifier=n.reserved=!0,n.fud=t,n}function dt(e,t){var n=pt(e,t);return n.block=!0,n}function vt(e){var t=e.id.charAt(0);if(t>="a"&&t<="z"||t>="A"&&t<="Z")e.identifier=e.reserved=!0;return e}function mt(e,t){var n=ct(e,150);return vt(n),n.nud=typeof t=="function"?t:function(){this.right=ot(150),this.arity="unary";if(this.id==="++"||this.id==="--")f.option.plusplus?K("W016",this,this.id):this.right&&(!this.right.identifier||U(this.right))&&this.right.id!=="."&&this.right.id!=="["&&K("W017",this);return this},n}function gt(e,t){var n=ht(e);return n.type=e,n.nud=t,n}function yt(e,t){var n=gt(e,t);return n.identifier=!0,n.reserved=!0,n}function bt(e,t){var n=gt(e,t&&t.nud||function(){return this});return t=t||{},t.isFutureReservedWord=!0,n.value=e,n.identifier=!0,n.reserved=!0,n.meta=t,n}function wt(e,t){return yt(e,function(){return typeof t=="function"&&t(this),this})}function Et(e,t,n,r){var i=ct(e,n);return vt(i),i.infix=!0,i.led=function(i){return r||ut(f.tokens.prev,f.tokens.curr),e==="in"&&i.id==="!"&&K("W018",i,"!"),typeof t=="function"?t(i,this):(this.left=i,this.right=ot(n),this)},i}function St(e){var t=ct(e,42);return t.led=function(e){return f.option.inESNext()||K("W104",f.tokens.curr,"arrow function syntax (=>)"),ut(f.tokens.prev,f.tokens.curr),this.left=e,this.right=Jt(undefined,undefined,!1,e),this},t}function xt(e,t){var n=ct(e,100);return n.led=function(e){ut(f.tokens.prev,f.tokens.curr);var n=ot(100);return R(e,"NaN")||R(n,"NaN")?K("W019",this):t&&t.apply(this,[e,n]),(!e||!n)&&V("E041",f.tokens.curr.line),e.id==="!"&&K("W018",e,"!"),n.id==="!"&&K("W018",n,"!"),this.left=e,this.right=n,this},n}function Tt(e){return e&&(e.type==="(number)"&&+e.value===0||e.type==="(string)"&&e.value===""||e.type==="null"&&!f.option.eqnull||e.type==="true"||e.type==="false"||e.type==="undefined")}function Nt(e,t){if(f.option.notypeof)return!1;if(!e||!t)return!1;var n=["undefined","object","boolean","number","string","function","xml","object","unknown"];return t.type==="(identifier)"&&t.value==="typeof"&&e.type==="(string)"?!r.contains(n,e.value):!1}function Ct(e){function n(e){if(typeof e!="object")return;return e.right==="prototype"?e:n(e.left)}function r(e){while(!e.identifier&&typeof e.left=="object")e=e.left;if(e.identifier&&t.indexOf(e.value)>=0)return e.value}var t=["Array","ArrayBuffer","Boolean","Collator","DataView","Date","DateTimeFormat","Error","EvalError","Float32Array","Float64Array","Function","Infinity","Intl","Int16Array","Int32Array","Int8Array","Iterator","Number","NumberFormat","Object","RangeError","ReferenceError","RegExp","StopIteration","String","SyntaxError","TypeError","Uint16Array","Uint32Array","Uint8Array","Uint8ClampedArray","URIError"],i=n(e);if(i)return r(i)}function kt(e,t,n){var r=Et(e,typeof t=="function"?t:function(e,t){t.left=e;if(e){if(f.option.freeze){var n=Ct(e);n&&K("W121",e,n)}M[e.value]===!1&&D[e.value]["(global)"]===!0?K("W020",e):e["function"]&&K("W021",e,e.value),w[e.value]==="const"&&G("E013",e,e.value);if(e.id===".")return e.left?e.left.value==="arguments"&&!f.directive["use strict"]&&K("E031",t):K("E031",t),t.right=ot(10),t;if(e.id==="[")return f.tokens.curr.left.first?f.tokens.curr.left.first.forEach(function(e){e&&w[e.value]==="const"&&G("E013",e,e.value)}):e.left?e.left.value==="arguments"&&!f.directive["use strict"]&&K("E031",t):K("E031",t),t.right=ot(10),t;if(e.identifier&&!U(e))return w[e.value]==="exception"&&K("W022",e),t.right=ot(10),t;e===f.syntax["function"]&&K("W023",f.tokens.curr)}G("E031",t)},n);return r.exps=!0,r.assign=!0,r}function Lt(e,t,n){var r=ct(e,n);return vt(r),r.led=typeof t=="function"?t:function(e){return f.option.bitwise&&K("W016",this,this.id),this.left=e,this.right=ot(n),this},r}function At(e){return kt(e,function(e,t){f.option.bitwise&&K("W016",t,t.id);if(e)return e.id==="."||e.id==="["||e.identifier&&!U(e)?(ot(10),t):(e===f.syntax["function"]&&K("W023",f.tokens.curr),t);G("E031",t)},20)}function Ot(e){var t=ct(e,150);return t.led=function(e){return f.option.plusplus?K("W016",this,this.id):(!e.identifier||U(e))&&e.id!=="."&&e.id!=="["&&K("W017",this),this.left=e,this},t}function Mt(e,t){if(!f.tokens.next.identifier)return;rt();var n=f.tokens.curr,r=f.tokens.curr.value;return U(n)?t&&f.option.inES5()?r:e&&r==="undefined"?r:(K("W024",f.tokens.curr,f.tokens.curr.id),r):r}function _t(e,t){var n=Mt(e,t);if(n)return n;f.tokens.curr.id==="function"&&f.tokens.next.id==="("?K("W025"):G("E030",f.tokens.next,f.tokens.next.value)}function Dt(e){var t=0,n;if(f.tokens.next.id!==";"||O)return;for(;;){do n=nt(t),t+=1;while(n.id!="(end)"&&n.id==="(comment)");if(n.reach)return;if(n.id!=="(endline)"){if(n.id==="function"){f.option.latedef===!0&&K("W026",n);break}K("W027",n,n.value,e);break}}}function Pt(){f.tokens.next.id!==";"?f.option.asi||(!f.option.lastsemic||f.tokens.next.id!=="}"||f.tokens.next.line!==f.tokens.curr.line)&&Q("W033",f.tokens.curr.line,f.tokens.curr.character):rt(";")}function Ht(){var e,t=N,n,i=D,s=f.tokens.next;if(s.id===";"){rt(";");return}var o=U(s);o&&s.meta&&s.meta.isFutureReservedWord&&nt().id===":"&&(K("W024",s,s.id),o=!1);if(s.value==="module"&&s.type==="(identifier)"&&nt().type==="(identifier)"){f.option.inESNext()||K("W119",f.tokens.curr,"module"),rt("module");var u=_t();et(u,{type:"unused",token:f.tokens.curr}),rt("from"),rt("(string)"),Pt();return}if(r.has(["[","{"],s.value)&&on().isDestAssign){f.option.inESNext()||K("W104",f.tokens.curr,"destructuring expression"),e=Yt(),e.forEach(function(e){$(w,"W117",e.token,e.id)}),rt("="),Zt(e,ot(10,!0)),rt(";");return}s.identifier&&!o&&nt().id===":"&&(rt(),rt(":"),D=Object.create(i),et(s.value,{type:"label"}),!f.tokens.next.labelled&&f.tokens.next.value!=="{"&&K("W028",f.tokens.next,s.value,f.tokens.next.value),f.tokens.next.label=s.value,s=f.tokens.next);if(s.id==="{"){var a=w["(verb)"]==="case"&&f.tokens.curr.value===":";Ft(!0,!0,!1,!1,a);return}return n=ot(0,!0),n&&(!n.identifier||n.value!=="function")&&n.type!=="(punctuator)"&&!f.directive["use strict"]&&f.option.globalstrict&&f.option.strict&&K("E007"),s.block||(!f.option.expr&&(!n||!n.exps)?K("W030",f.tokens.curr):f.option.nonew&&n&&n.left&&n.id==="("&&n.left.id==="new"&&K("W031",s),Pt()),N=t,D=i,n}function Bt(e){var t=[],n;while(!f.tokens.next.reach&&f.tokens.next.id!=="(end)")f.tokens.next.id===";"?(n=nt(),(!n||n.id!=="("&&n.id!=="[")&&K("W032"),rt(";")):t.push(Ht(e===f.tokens.next.line));return t}function jt(){var e,t,n;for(;;){if(f.tokens.next.id==="(string)"){t=nt(0);if(t.id==="(endline)"){e=1;do n=nt(e),e+=1;while(n.id==="(endline)");if(n.id!==";"){if(n.id!=="(string)"&&n.id!=="(number)"&&n.id!=="(regexp)"&&n.identifier!==!0&&n.id!=="}")break;K("W033",f.tokens.next)}else t=n}else if(t.id==="}")K("W033",t);else if(t.id!==";")break;rt(),f.directive[f.tokens.curr.value]&&K("W034",f.tokens.curr,f.tokens.curr.value),f.tokens.curr.value==="use strict"&&(f.option["(explicitNewcap)"]||(f.option.newcap=!0),f.option.undef=!0),f.directive[f.tokens.curr.value]=!0,t.id===";"&&rt(";");continue}break}}function Ft(e,t,n,i,s){var o,u=T,a=N,l,c=D,h,p,d;T=e;if(!e||!f.option.funcscope)D=Object.create(D);h=f.tokens.next;var v=w["(metrics)"];v.nestedBlockDepth+=1,v.verifyMaxNestedBlockDepthPerFunction();if(f.tokens.next.id==="{"){rt("{"),w["(blockscope)"].stack(),p=f.tokens.curr.line;if(f.tokens.next.id!=="}"){N+=f.option.indent;while(!e&&f.tokens.next.from>N)N+=f.option.indent;if(n){l={};for(d in f.directive)r.has(f.directive,d)&&(l[d]=f.directive[d]);jt(),f.option.strict&&w["(context)"]["(global)"]&&!l["use strict"]&&!f.directive["use strict"]&&K("E007")}o=Bt(p),v.statementCount+=o.length,n&&(f.directive=l),N-=f.option.indent}rt("}",h),w["(blockscope)"].unstack(),N=a}else if(!e)if(n){l={},t&&!i&&!f.option.inMoz(!0)&&G("W118",f.tokens.curr,"function closure expressions");if(!t)for(d in f.directive)r.has(f.directive,d)&&(l[d]=f.directive[d]);ot(10),f.option.strict&&w["(context)"]["(global)"]&&!l["use strict"]&&!f.directive["use strict"]&&K("E007")}else G("E021",f.tokens.next,"{",f.tokens.next.value);else w["(nolet)"]=!0,(!t||f.option.curly)&&K("W116",f.tokens.next,"{",f.tokens.next.value),O=!0,N+=f.option.indent,o=[Ht()],N-=f.option.indent,O=!1,delete w["(nolet)"];switch(w["(verb)"]){case"break":case"continue":case"return":case"throw":if(s)break;default:w["(verb)"]=null}if(!e||!f.option.funcscope)D=c;return T=u,e&&f.option.noempty&&(!o||o.length===0)&&K("W035"),v.nestedBlockDepth-=1,o}function It(e){A&&typeof A[e]!="boolean"&&K("W036",f.tokens.curr,e),typeof L[e]=="number"?L[e]+=1:L[e]=1}function qt(e){var t=e.value,n=Object.getOwnPropertyDescriptor(x,t);n?n.value.push(e.line):x[t]=[e.line]}function Ut(){var e={};e.exps=!0,w["(comparray)"].stack();var t=!1;return f.tokens.next.value!=="for"&&(t=!0,f.option.inMoz(!0)||K("W116",f.tokens.next,"for",f.tokens.next.value),w["(comparray)"].setState("use"),e.right=ot(10)),rt("for"),f.tokens.next.value==="each"&&(rt("each"),f.option.inMoz(!0)||K("W118",f.tokens.curr,"for each")),rt("("),w["(comparray)"].setState("define"),e.left=ot(130),r.contains(["in","of"],f.tokens.next.value)?rt():G("E045",f.tokens.curr),w["(comparray)"].setState("generate"),ot(10),rt(")"),f.tokens.next.value==="if"&&(rt("if"),rt("("),w["(comparray)"].setState("filter"),e.filter=ot(10),rt(")")),t||(w["(comparray)"].setState("use"),e.right=ot(10)),rt("]"),w["(comparray)"].unstack(),e}function zt(){var e=Mt(!1,!0);return e||(f.tokens.next.id==="(string)"?(e=f.tokens.next.value,rt()):f.tokens.next.id==="(number)"&&(e=f.tokens.next.value.toString(),rt())),e==="hasOwnProperty"&&K("W001"),e}function Wt(e){var t,n,i=[],s,o=[],u,a=!1;if(e){if(Array.isArray(e)){for(var l in e){t=e[l];if(t.value==="..."){f.option.inESNext()||K("W104",t,"spread/rest operator");continue}t.value!==","&&(i.push(t.value),et(t.value,{type:"unused",token:t}))}return i}if(e.identifier===!0)return et(e.value,{type:"unused",token:e}),[e]}n=f.tokens.next,rt("(");if(f.tokens.next.id===")"){rt(")");return}for(;;){if(r.contains(["{","["],f.tokens.next.id)){o=Yt();for(u in o)u=o[u],u.id&&(i.push(u.id),et(u.id,{type:"unused",token:u.token}))}else f.tokens.next.value==="..."?(f.option.inESNext()||K("W104",f.tokens.next,"spread/rest operator"),rt("..."),s=_t(!0),i.push(s),et(s,{type:"unused",token:f.tokens.curr})):(s=_t(!0),i.push(s),et(s,{type:"unused",token:f.tokens.curr}));a&&f.tokens.next.id!=="="&&G("E051",f.tokens.current),f.tokens.next.id==="="&&(f.option.inESNext()||K("W119",f.tokens.next,"default parameters"),rt("="),a=!0,ot(10));if(f.tokens.next.id!==",")return rt(")",n),i;lt()}}function Xt(e,t,n){e["(properties)"][t]||(e["(properties)"][t]={unused:!1}),r.extend(e["(properties)"][t],n)}function Vt(e,t,n){return e["(properties)"][t]?e["(properties)"][t][n]||null:null}function $t(e,t,n,i){var s={"(name)":e,"(breakage)":0,"(loopage)":0,"(scope)":n,"(tokens)":{},"(properties)":{},"(catch)":!1,"(global)":!1,"(line)":null,"(character)":null,"(metrics)":null,"(statement)":null,"(context)":null,"(blockscope)":null,"(comparray)":null,"(generator)":null,"(params)":null};return t&&r.extend(s,{"(line)":t.line,"(character)":t.character,"(metrics)":Kt(t)}),r.extend(s,i),s["(context)"]&&(s["(blockscope)"]=s["(context)"]["(blockscope)"],s["(comparray)"]=s["(context)"]["(comparray)"]),s}function Jt(t,n,i,s){var o,u=f.option,a=f.ignored,l=D;return f.option=Object.create(f.option),f.ignored=Object.create(f.ignored),D=Object.create(D),w=$t(t||'"'+e+'"',f.tokens.next,D,{"(statement)":n,"(context)":w,"(generator)":i?!0:null}),o=w,f.tokens.curr.funct=w,E.push(w),t&&et(t,{type:"function"}),w["(params)"]=Wt(s),w["(metrics)"].verifyMaxParametersPerFunction(w["(params)"]),c.undefs=r.filter(c.undefs,function(e){return!r.contains(r.union(s),e[2])}),Ft(!1,!0,!0,s?!0:!1),!f.option.noyield&&i&&w["(generator)"]!=="yielded"&&K("W124",f.tokens.curr),w["(metrics)"].verifyMaxStatementsPerFunction(),w["(metrics)"].verifyMaxComplexityPerFunction(),w["(unusedOption)"]=f.option.unused,D=l,f.option=u,f.ignored=a,w["(last)"]=f.tokens.curr.line,w["(lastcharacter)"]=f.tokens.curr.character,r.map(Object.keys(w),function(e){if(e[0]==="(")return;w["(blockscope)"].unshadow(e)}),w=w["(context)"],o}function Kt(e){return{statementCount:0,nestedBlockDepth:-1,ComplexityCount:1,verifyMaxStatementsPerFunction:function(){f.option.maxstatements&&this.statementCount>f.option.maxstatements&&K("W071",e,this.statementCount)},verifyMaxParametersPerFunction:function(t){t=t||[],f.option.maxparams&&t.length>f.option.maxparams&&K("W072",e,t.length)},verifyMaxNestedBlockDepthPerFunction:function(){f.option.maxdepth&&this.nestedBlockDepth>0&&this.nestedBlockDepth===f.option.maxdepth+1&&K("W073",null,this.nestedBlockDepth)},verifyMaxComplexityPerFunction:function(){var t=f.option.maxcomplexity,n=this.ComplexityCount;t&&n>t&&K("W074",e,n)}}}function Qt(){w["(metrics)"].ComplexityCount+=1}function Gt(e){var t,n;e&&(t=e.id,n=e.paren,t===","&&(e=e.exprs[e.exprs.length-1])&&(t=e.id,n=n||e.paren));switch(t){case"=":case"+=":case"-=":case"*=":case"%=":case"&=":case"|=":case"^=":case"/=":!n&&!f.option.boss&&K("W084")}}function Yt(){var e,t,n=[];f.option.inESNext()||K("W104",f.tokens.curr,"destructuring expression");var i=function(){var e;if(r.contains(["[","{"],f.tokens.next.value)){t=Yt();for(var s in t)s=t[s],n.push({id:s.id,token:s.token})}else f.tokens.next.value===","?n.push({id:null,token:f.tokens.curr}):f.tokens.next.value==="("?(rt("("),i(),rt(")")):(e=_t(),e&&n.push({id:e,token:f.tokens.curr}))};if(f.tokens.next.value==="["){rt("["),i();while(f.tokens.next.value!=="]")rt(","),i();rt("]")}else if(f.tokens.next.value==="{"){rt("{"),e=_t(),f.tokens.next.value===":"?(rt(":"),i()):n.push({id:e,token:f.tokens.curr});while(f.tokens.next.value!=="}")rt(","),e=_t(),f.tokens.next.value===":"?(rt(":"),i()):n.push({id:e,token:f.tokens.curr});rt("}")}return n}function Zt(e,t){var n=t.first;if(!n)return;r.zip(e,Array.isArray(n)?n:[n]).forEach(function(e){var t=e[0],n=e[1];t&&n?t.first=n:t&&t.first&&!n&&K("W080",t.first,t.first.value)})}function rn(e){return f.option.inESNext()||K("W104",f.tokens.curr,"class"),e?(this.name=_t(),et(this.name,{type:"unused",token:f.tokens.curr})):f.tokens.next.identifier&&f.tokens.next.value!=="extends"&&(this.name=_t()),sn(this),this}function sn(e){var t=f.directive["use strict"];f.tokens.next.value==="extends"&&(rt("extends"),e.heritage=ot(10)),f.directive["use strict"]=!0,rt("{"),e.body=f.syntax["{"].nud(!0),f.directive["use strict"]=t}function un(){var e=on();e.notJson?(!f.option.inESNext()&&e.isDestAssign&&K("W104",f.tokens.curr,"destructuring assignment"),Bt()):(f.option.laxbreak=!0,f.jsonMode=!0,fn())}function fn(){function e(){var e={},t=f.tokens.next;rt("{");if(f.tokens.next.id!=="}")for(;;){if(f.tokens.next.id==="(end)")G("E026",f.tokens.next,t.line);else{if(f.tokens.next.id==="}"){K("W094",f.tokens.curr);break}f.tokens.next.id===","?G("E028",f.tokens.next):f.tokens.next.id!=="(string)"&&K("W095",f.tokens.next,f.tokens.next.value)}e[f.tokens.next.value]===!0?K("W075",f.tokens.next,f.tokens.next.value):f.tokens.next.value==="__proto__"&&!f.option.proto||f.tokens.next.value==="__iterator__"&&!f.option.iterator?K("W096",f.tokens.next,f.tokens.next.value):e[f.tokens.next.value]=!0,rt(),rt(":"),fn();if(f.tokens.next.id!==",")break;rt(",")}rt("}")}function t(){var e=f.tokens.next;rt("[");if(f.tokens.next.id!=="]")for(;;){if(f.tokens.next.id==="(end)")G("E027",f.tokens.next,e.line);else{if(f.tokens.next.id==="]"){K("W094",f.tokens.curr);break}f.tokens.next.id===","&&G("E028",f.tokens.next)}fn();if(f.tokens.next.id!==",")break;rt(",")}rt("]")}switch(f.tokens.next.id){case"{":e();break;case"[":t();break;case"true":case"false":case"null":case"(number)":case"(string)":rt();break;case"-":rt("-"),rt("(number)");break;default:G("E003",f.tokens.next)}}var e,t,n={"<":!0,"<=":!0,"==":!0,"===":!0,"!==":!0,"!=":!0,">":!0,">=":!0,"+":!0,"-":!0,"*":!0,"/":!0,"%":!0},h={asi:!0,bitwise:!0,boss:!0,browser:!0,camelcase:!0,couch:!0,curly:!0,debug:!0,devel:!0,dojo:!0,eqeqeq:!0,eqnull:!0,notypeof:!0,es3:!0,es5:!0,esnext:!0,moz:!0,evil:!0,expr:!0,forin:!0,funcscope:!0,globalstrict:!0,immed:!0,iterator:!0,jasmine:!0,jquery:!0,lastsemic:!0,laxbreak:!0,laxcomma:!0,loopfunc:!0,mootools:!0,multistr:!0,freeze:!0,newcap:!0,noarg:!0,node:!0,noempty:!0,nonbsp:!0,nonew:!0,nonstandard:!0,phantom:!0,plusplus:!0,proto:!0,prototypejs:!0,qunit:!0,rhino:!0,shelljs:!0,typed:!0,undef:!0,scripturl:!0,strict:!0,sub:!0,supernew:!0,validthis:!0,withstmt:!0,worker:!0,wsh:!0,yui:!0,mocha:!0,noyield:!0,onecase:!0,regexp:!0,regexdash:!0},p={maxlen:!1,indent:!1,maxerr:!1,predef:!1,globals:!1,quotmark:!1,scope:!1,maxstatements:!1,maxdepth:!1,maxparams:!1,maxcomplexity:!1,shadow:!1,unused:!0,latedef:!1,ignore:!1},d={bitwise:!0,forin:!0,newcap:!0,plusplus:!0,regexp:!0,undef:!0,eqeqeq:!0,strict:!0},v={eqeq:"eqeqeq",windows:"wsh",sloppy:"strict"},m={nomen:!0,onevar:!0,passfail:!0,white:!0,gcl:!0,smarttabs:!0,trailing:!0},g,y,b=["closure","exception","global","label","outer","unused","var"],w,E,S,x,T,N,C,k,L,A,O,M,D,P,H,B,j=[],F=new i.EventEmitter;gt("(number)",function(){return this}),gt("(string)",function(){return this}),gt("(template)",function(){return this}),f.syntax["(identifier)"]={type:"(identifier)",lbp:0,identifier:!0,nud:function(){var t=this.value,n=D[t],r,i;typeof n=="function"?n=undefined:!w["(blockscope)"].current.has(t)&&typeof n=="boolean"&&(r=w,w=E[0],et(t,{type:"var"}),n=w,w=r),i=w["(blockscope)"].getlabel(t);if(w===n||i)switch(i?i[t]["(type)"]:w[t]){case"unused":i?i[t]["(type)"]="var":w[t]="var";break;case"unction":i?i[t]["(type)"]="function":w[t]="function",this["function"]=!0;break;case"const":Xt(w,t,{unused:!1});break;case"function":this["function"]=!0;break;case"label":K("W037",f.tokens.curr,t)}else if(w["(global)"])typeof M[t]!="boolean"&&(e!=="typeof"&&e!=="delete"||f.tokens.next&&(f.tokens.next.value==="."||f.tokens.next.value==="["))&&(w["(comparray)"].check(t)||$(w,"W117",f.tokens.curr,t)),qt(f.tokens.curr);else switch(w[t]){case"closure":case"function":case"var":case"unused":K("W038",f.tokens.curr,t);break;case"label":K("W037",f.tokens.curr,t);break;case"outer":case"global":break;default:if(n===!0)w[t]=!0;else if(n===null)K("W039",f.tokens.curr,t),qt(f.tokens.curr);else if(typeof n!="object")(e!=="typeof"&&e!=="delete"||f.tokens.next&&(f.tokens.next.value==="."||f.tokens.next.value==="["))&&$(w,"W117",f.tokens.curr,t),w[t]=!0,qt(f.tokens.curr);else switch(n[t]){case"function":case"unction":this["function"]=!0,n[t]="closure",w[t]=n["(global)"]?"global":"outer";break;case"var":case"unused":n[t]="closure",w[t]=n["(global)"]?"global":"outer";break;case"const":Xt(n,t,{unused:!1});break;case"closure":w[t]=n["(global)"]?"global":"outer";break;case"label":K("W037",f.tokens.curr,t)}}return this},led:function(){G("E033",f.tokens.next,f.tokens.next.value)}},gt("(regexp)",function(){return this}),ht("(endline)"),ht("(begin)"),ht("(end)").reach=!0,ht("(error)").reach=!0,ht("}").reach=!0,ht(")"),ht("]"),ht('"').reach=!0,ht("'").reach=!0,ht(";"),ht(":").reach=!0,ht("#"),yt("else"),yt("case").reach=!0,yt("catch"),yt("default").reach=!0,yt("finally"),wt("arguments",function(e){f.directive["use strict"]&&w["(global)"]&&K("E008",e)}),wt("eval"),wt("false"),wt("Infinity"),wt("null"),wt("this",function(e){f.directive["use strict"]&&!f.option.validthis&&(w["(statement)"]&&w["(name)"].charAt(0)>"Z"||w["(global)"])&&K("W040",e)}),wt("true"),wt("undefined"),kt("=","assign",20),kt("+=","assignadd",20),kt("-=","assignsub",20),kt("*=","assignmult",20),kt("/=","assigndiv",20).nud=function(){G("E014")},kt("%=","assignmod",20),At("&=","assignbitand",20),At("|=","assignbitor",20),At("^=","assignbitxor",20),At("<<=","assignshiftleft",20),At(">>=","assignshiftright",20),At(">>>=","assignshiftrightunsigned",20),Et(",",function(e,t){var n;t.exprs=[e];if(!lt({peek:!0}))return t;for(;;){if(!(n=ot(10)))break;t.exprs.push(n);if(f.tokens.next.value!==","||!lt())break}return t},10,!0),Et("?",function(e,t){return Qt(),t.left=e,t.right=ot(10),rt(":"),t["else"]=ot(10),t},30);var Rt=40;Et("||",function(e,t){return Qt(),t.left=e,t.right=ot(Rt),t},Rt),Et("&&","and",50),Lt("|","bitor",70),Lt("^","bitxor",80),Lt("&","bitand",90),xt("==",function(e,t){var n=f.option.eqnull&&(e.value==="null"||t.value==="null");switch(!0){case!n&&f.option.eqeqeq:this.from=this.character,K("W116",this,"===","==");break;case Tt(e):K("W041",this,"===",e.value);break;case Tt(t):K("W041",this,"===",t.value);break;case Nt(t,e):K("W122",this,t.value);break;case Nt(e,t):K("W122",this,e.value)}return this}),xt("===",function(e,t){return Nt(t,e)?K("W122",this,t.value):Nt(e,t)&&K("W122",this,e.value),this}),xt("!=",function(e,t){var n=f.option.eqnull&&(e.value==="null"||t.value==="null");return!n&&f.option.eqeqeq?(this.from=this.character,K("W116",this,"!==","!=")):Tt(e)?K("W041",this,"!==",e.value):Tt(t)?K("W041",this,"!==",t.value):Nt(t,e)?K("W122",this,t.value):Nt(e,t)&&K("W122",this,e.value),this}),xt("!==",function(e,t){return Nt(t,e)?K("W122",this,t.value):Nt(e,t)&&K("W122",this,e.value),this}),xt("<"),xt(">"),xt("<="),xt(">="),Lt("<<","shiftleft",120),Lt(">>","shiftright",120),Lt(">>>","shiftrightunsigned",120),Et("in","in",120),Et("instanceof","instanceof",120),Et("+",function(e,t){var n=ot(130);return e&&n&&e.id==="(string)"&&n.id==="(string)"?(e.value+=n.value,e.character=n.character,!f.option.scripturl&&a.javascriptURL.test(e.value)&&K("W050",e),e):(t.left=e,t.right=n,t)},130),mt("+","num"),mt("+++",function(){return K("W007"),this.right=ot(150),this.arity="unary",this}),Et("+++",function(e){return K("W007"),this.left=e,this.right=ot(130),this},130),Et("-","sub",130),mt("-","neg"),mt("---",function(){return K("W006"),this.right=ot(150),this.arity="unary",this}),Et("---",function(e){return K("W006"),this.left=e,this.right=ot(130),this},130),Et("*","mult",140),Et("/","div",140),Et("%","mod",140),Ot("++","postinc"),mt("++","preinc"),f.syntax["++"].exps=!0,Ot("--","postdec"),mt("--","predec"),f.syntax["--"].exps=!0,mt("delete",function(){var e=ot(10);return(!e||e.id!=="."&&e.id!=="[")&&K("W051"),this.first=e,this}).exps=!0,mt("~",function(){return f.option.bitwise&&K("W052",this,"~"),ot(150),this}),mt("...",function(){return f.option.inESNext()||K("W104",this,"spread/rest operator"),f.tokens.next.identifier||G("E030",f.tokens.next,f.tokens.next.value),ot(150),this}),mt("!",function(){return this.right=ot(150),this.arity="unary",this.right||V("E041",this.line||0),n[this.right.id]===!0&&K("W018",this,"!"),this}),mt("typeof","typeof"),mt("new",function(){var e=ot(155),t;if(e&&e.id!=="function")if(e.identifier){e["new"]=!0;switch(e.value){case"Number":case"String":case"Boolean":case"Math":case"JSON":K("W053",f.tokens.prev,e.value);break;case"Function":f.option.evil||K("W054");break;case"Date":case"RegExp":case"this":break;default:e.id!=="function"&&(t=e.value.substr(0,1),f.option.newcap&&(t<"A"||t>"Z")&&!r.has(S,e.value)&&K("W055",f.tokens.curr))}}else e.id!=="."&&e.id!=="["&&e.id!=="("&&K("W056",f.tokens.curr);else f.option.supernew||K("W057",this);return f.tokens.next.id!=="("&&!f.option.supernew&&K("W058",f.tokens.curr,f.tokens.curr.value),this.first=e,this}),f.syntax["new"].exps=!0,mt("void").exps=!0,Et(".",function(e,t){var n=_t(!1,!0);return typeof n=="string"&&It(n),t.left=e,t.right=n,n&&n==="hasOwnProperty"&&f.tokens.next.value==="="&&K("W001"),!e||e.value!=="arguments"||n!=="callee"&&n!=="caller"?!f.option.evil&&e&&e.value==="document"&&(n==="write"||n==="writeln")&&K("W060",e):f.option.noarg?K("W059",e,n):f.directive["use strict"]&&G("E008"),!f.option.evil&&(n==="eval"||n==="execScript")&&K("W061"),t},160,!0),Et("(",function(e,t){f.option.immed&&e&&!e.immed&&e.id==="function"&&K("W062");var n=0,r=[];e&&e.type==="(identifier)"&&e.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)&&"Number String Boolean Date Object Error".indexOf(e.value)===-1&&(e.value==="Math"?K("W063",e):f.option.newcap&&K("W064",e));if(f.tokens.next.id!==")")for(;;){r[r.length]=ot(10),n+=1;if(f.tokens.next.id!==",")break;lt()}return rt(")"),typeof e=="object"&&(f.option.inES3()&&e.value==="parseInt"&&n===1&&K("W065",f.tokens.curr),f.option.evil||(e.value==="eval"||e.value==="Function"||e.value==="execScript"?(K("W061",e),r[0]&&[0].id==="(string)"&&Z(e,r[0].value)):!r[0]||r[0].id!=="(string)"||e.value!=="setTimeout"&&e.value!=="setInterval"?r[0]&&r[0].id==="(string)"&&e.value==="."&&e.left.value==="window"&&(e.right==="setTimeout"||e.right==="setInterval")&&(K("W066",e),Z(e,r[0].value)):(K("W066",e),Z(e,r[0].value))),!e.identifier&&e.id!=="."&&e.id!=="["&&e.id!=="("&&e.id!=="&&"&&e.id!=="||"&&e.id!=="?"&&K("W067",e)),t.left=e,t},155,!0).exps=!0,mt("(",function(){var e,t=[],n,i,s=0,o,u=1;do n=nt(s),n.value==="("?u+=1:n.value===")"&&(u-=1),s+=1,i=nt(s);while((u!==0||n.value!==")")&&i.value!=="=>"&&i.value!==";"&&i.type!=="(end)");f.tokens.next.id==="function"&&(f.tokens.next.immed=!0);var a=[];if(f.tokens.next.id!==")")for(;;){if(i.value==="=>"&&r.contains(["{","["],f.tokens.next.value)){e=f.tokens.next,e.left=Yt(),t.push(e);for(var l in e.left)a.push(e.left[l].token)}else a.push(ot(10));if(f.tokens.next.id!==",")break;lt()}rt(")",this),f.option.immed&&a[0]&&a[0].id==="function"&&f.tokens.next.id!=="("&&(f.tokens.next.id!=="."||nt().value!=="call"&&nt().value!=="apply")&&K("W068",this);if(f.tokens.next.value==="=>")return a;if(!a.length)return;return a.length>1?(o=Object.create(f.syntax[","]),o.exprs=a):o=a[0],o&&(o.paren=!0),o}),St("=>"),Et("[",function(e,t){var n=ot(10),r;return n&&n.type==="(string)"&&(!f.option.evil&&(n.value==="eval"||n.value==="execScript")&&K("W061",t),It(n.value),!f.option.sub&&a.identifier.test(n.value)&&(r=f.syntax[n.value],(!r||!U(r))&&K("W069",f.tokens.prev,n.value))),rt("]",t),n&&n.value==="hasOwnProperty"&&f.tokens.next.value==="="&&K("W001"),t.left=e,t.right=n,t},160,!0),mt("[",function(){var e=on(!0);if(e.isCompArray)return f.option.inESNext()||K("W119",f.tokens.curr,"array comprehension"),Ut();e.isDestAssign&&!f.option.inESNext()&&K("W104",f.tokens.curr,"destructuring assignment");var t=f.tokens.curr.line!==f.tokens.next.line;this.first=[],t&&(N+=f.option.indent,f.tokens.next.from===N+f.option.indent&&(N+=f.option.indent));while(f.tokens.next.id!=="(end)"){while(f.tokens.next.id===",")f.option.inES5()||K("W070"),rt(",");if(f.tokens.next.id==="]")break;this.first.push(ot(10));if(f.tokens.next.id!==",")break;lt({allowTrailing:!0});if(f.tokens.next.id==="]"&&!f.option.inES5(!0)){K("W070",f.tokens.curr);break}}return t&&(N-=f.option.indent),rt("]",this),this},160),function(e){e.nud=function(e){function c(e,t){a[e]&&r.has(a,e)?K("W075",f.tokens.next,i):a[e]={},a[e].basic=!0,a[e].basictkn=t}function h(e,t){a[e]&&r.has(a,e)?(a[e].basic||a[e].setter)&&K("W075",f.tokens.next,i):a[e]={},a[e].setter=!0,a[e].setterToken=t}function p(e){a[e]&&r.has(a,e)?(a[e].basic||a[e].getter)&&K("W075",f.tokens.next,i):a[e]={},a[e].getter=!0,a[e].getterToken=f.tokens.curr}var t,n,i,s,o,u,a={},l="";t=f.tokens.curr.line!==f.tokens.next.line,t&&(N+=f.option.indent,f.tokens.next.from===N+f.option.indent&&(N+=f.option.indent));for(;;){if(f.tokens.next.id==="}")break;e&&f.tokens.next.value==="static"&&(rt("static"),l="static ");if(f.tokens.next.value==="get"&&nt().id!==":")rt("get"),f.option.inES5(!e)||G("E034"),i=zt(),!i&&!f.option.inESNext()&&G("E035"),e&&i==="constructor"&&G("E049",f.tokens.next,"class getter method",i),i&&p(l+i),o=f.tokens.next,n=Jt(),s=n["(params)"],i&&s&&K("W076",o,s[0],i);else if(f.tokens.next.value==="set"&&nt().id!==":")rt("set"),f.option.inES5(!e)||G("E034"),i=zt(),!i&&!f.option.inESNext()&&G("E035"),e&&i==="constructor"&&G("E049",f.tokens.next,"class setter method",i),i&&h(l+i,f.tokens.next),o=f.tokens.next,n=Jt(),s=n["(params)"],i&&(!s||s.length!==1)&&K("W077",o,i);else{u=!1,f.tokens.next.value==="*"&&f.tokens.next.type==="(punctuator)"&&(f.option.inESNext()||K("W104",f.tokens.next,"generator functions"),rt("*"),u=!0),i=zt(),c(l+i,f.tokens.next);if(typeof i!="string")break;f.tokens.next.value==="("?(f.option.inESNext()||K("W104",f.tokens.curr,"concise methods"),Jt(i,undefined,u)):e||(rt(":"),ot(10))}e&&i==="prototype"&&G("E049",f.tokens.next,"class method",i),It(i);if(e){l="";continue}if(f.tokens.next.id!==",")break;lt({allowTrailing:!0,property:!0}),f.tokens.next.id===","?K("W070",f.tokens.curr):f.tokens.next.id==="}"&&!f.option.inES5(!0)&&K("W070",f.tokens.curr)}t&&(N-=f.option.indent),rt("}",this);if(f.option.inES5())for(var d in a)r.has(a,d)&&a[d].setter&&!a[d].getter&&K("W078",a[d].setterToken);return this},e.fud=function(){G("E036",f.tokens.curr)}}(ht("{"));var en=pt("const",function(e){var t,n,i;f.option.inESNext()||K("W104",f.tokens.curr,"const"),this.first=[];for(;;){var s=[];r.contains(["{","["],f.tokens.next.value)?(t=Yt(),i=!1):(t=[{id:_t(),token:f.tokens.curr}],i=!0);for(var o in t)t.hasOwnProperty(o)&&(o=t[o],w[o.id]==="const"&&K("E011",null,o.id),w["(global)"]&&M[o.id]===!1&&K("W079",o.token,o.id),o.id&&(et(o.id,{token:o.token,type:"const",unused:!0}),s.push(o.token)));if(e)break;this.first=this.first.concat(s),f.tokens.next.id!=="="&&K("E012",f.tokens.curr,f.tokens.curr.value),f.tokens.next.id==="="&&(rt("="),f.tokens.next.id==="undefined"&&K("W080",f.tokens.prev,f.tokens.prev.value),nt(0).id==="="&&f.tokens.next.identifier&&K("W120",f.tokens.next,f.tokens.next.value),n=ot(10),i?t[0].first=n:Zt(s,n));if(f.tokens.next.id!==",")break;lt()}return this});en.exps=!0;var tn=pt("var",function(e){var t,n,i;this.first=[];for(;;){var s=[];r.contains(["{","["],f.tokens.next.value)?(t=Yt(),n=!1):(t=[{id:_t(),token:f.tokens.curr}],n=!0);for(var o in t)t.hasOwnProperty(o)&&(o=t[o],f.option.inESNext()&&w[o.id]==="const"&&K("E011",null,o.id),w["(global)"]&&M[o.id]===!1&&K("W079",o.token,o.id),o.id&&(et(o.id,{type:"unused",token:o.token}),s.push(o.token)));if(e)break;this.first=this.first.concat(s),f.tokens.next.id==="="&&(rt("="),f.tokens.next.id==="undefined"&&K("W080",f.tokens.prev,f.tokens.prev.value),nt(0).id==="="&&f.tokens.next.identifier&&K("W120",f.tokens.next,f.tokens.next.value),i=ot(10),n?t[0].first=i:Zt(s,i));if(f.tokens.next.id!==",")break;lt()}return this});tn.exps=!0;var nn=pt("let",function(e){var t,n,i,s;f.option.inESNext()||K("W104",f.tokens.curr,"let"),f.tokens.next.value==="("?(f.option.inMoz(!0)||K("W118",f.tokens.next,"let block"),rt("("),w["(blockscope)"].stack(),s=!0):w["(nolet)"]&&G("E048",f.tokens.curr),this.first=[];for(;;){var o=[];r.contains(["{","["],f.tokens.next.value)?(t=Yt(),n=!1):(t=[{id:_t(),token:f.tokens.curr.value}],n=!0);for(var u in t)t.hasOwnProperty(u)&&(u=t[u],f.option.inESNext()&&w[u.id]==="const"&&K("E011",null,u.id),w["(global)"]&&M[u.id]===!1&&K("W079",u.token,u.id),u.id&&!w["(nolet)"]&&(et(u.id,{type:"unused",token:u.token,islet:!0}),o.push(u.token)));if(e)break;this.first=this.first.concat(o),f.tokens.next.id==="="&&(rt("="),f.tokens.next.id==="undefined"&&K("W080",f.tokens.prev,f.tokens.prev.value),nt(0).id==="="&&f.tokens.next.identifier&&K("W120",f.tokens.next,f.tokens.next.value),i=ot(10),n?t[0].first=i:Zt(o,i));if(f.tokens.next.id!==",")break;lt()}return s&&(rt(")"),Ft(!0,!0),this.block=!0,w["(blockscope)"].unstack()),this});nn.exps=!0,dt("class",function(){return rn.call(this,!0)}),dt("function",function(){var e=!1;f.tokens.next.value==="*"&&(rt("*"),f.option.inESNext(!0)?e=!0:K("W119",f.tokens.curr,"function*")),T&&K("W082",f.tokens.curr);var t=_t();return w[t]==="const"&&K("E011",null,t),et(t,{type:"unction",token:f.tokens.curr}),Jt(t,{statement:!0},e),f.tokens.next.id==="("&&f.tokens.next.line===f.tokens.curr.line&&G("E039"),this}),mt("function",function(){var e=!1;f.tokens.next.value==="*"&&(f.option.inESNext()||K("W119",f.tokens.curr,"function*"),rt("*"),e=!0);var t=Mt();return Jt(t,undefined,e),!f.option.loopfunc&&w["(loopage)"]&&K("W083"),this}),dt("if",function(){var e=f.tokens.next;return Qt(),f.condition=!0,rt("("),Gt(ot(0)),rt(")",e),f.condition=!1,Ft(!0,!0),f.tokens.next.id==="else"&&(rt("else"),f.tokens.next.id==="if"||f.tokens.next.id==="switch"?Ht(!0):Ft(!0,!0)),this}),dt("try",function(){function t(){var e=D,t;rt("catch"),rt("("),D=Object.create(e),t=f.tokens.next.value,f.tokens.next.type!=="(identifier)"&&(t=null,K("E030",f.tokens.next,t)),rt(),w=$t("(catch)",f.tokens.next,D,{"(context)":w,"(breakage)":w["(breakage)"],"(loopage)":w["(loopage)"],"(statement)":!1,"(catch)":!0}),t&&et(t,{type:"exception"}),f.tokens.next.value==="if"&&(f.option.inMoz(!0)||K("W118",f.tokens.curr,"catch filter"),rt("if"),ot(0)),rt(")"),f.tokens.curr.funct=w,E.push(w),Ft(!1),D=e,w["(last)"]=f.tokens.curr.line,w["(lastcharacter)"]=f.tokens.curr.character,w=w["(context)"]}var e;Ft(!0);while(f.tokens.next.id==="catch")Qt(),e&&!f.option.inMoz(!0)&&K("W118",f.tokens.next,"multiple catch blocks"),t(),e=!0;if(f.tokens.next.id==="finally"){rt("finally"),Ft(!0);return}return e||G("E021",f.tokens.next,"catch",f.tokens.next.value),this}),dt("while",function(){var e=f.tokens.next;return w["(breakage)"]+=1,w["(loopage)"]+=1,Qt(),rt("("),Gt(ot(0)),rt(")",e),Ft(!0,!0),w["(breakage)"]-=1,w["(loopage)"]-=1,this}).labelled=!0,dt("with",function(){var e=f.tokens.next;return f.directive["use strict"]?G("E010",f.tokens.curr):f.option.withstmt||K("W085",f.tokens.curr),rt("("),ot(0),rt(")",e),Ft(!0,!0),this}),dt("switch",function(){var e=f.tokens.next,t=!1,n=!1;w["(breakage)"]+=1,rt("("),Gt(ot(0)),rt(")",e),e=f.tokens.next,rt("{"),f.tokens.next.from===N&&(n=!0),n||(N+=f.option.indent),this.cases=[];for(;;)switch(f.tokens.next.id){case"case":switch(w["(verb)"]){case"yield":case"break":case"case":case"continue":case"return":case"switch":case"throw":break;default:a.fallsThrough.test(f.lines[f.tokens.next.line-2])||K("W086",f.tokens.curr,"case")}rt("case"),this.cases.push(ot(0)),Qt(),t=!0,rt(":"),w["(verb)"]="case";break;case"default":switch(w["(verb)"]){case"yield":case"break":case"continue":case"return":case"throw":break;default:this.cases.length&&(a.fallsThrough.test(f.lines[f.tokens.next.line-2])||K("W086",f.tokens.curr,"default"))}rt("default"),t=!0,rt(":");break;case"}":n||(N-=f.option.indent),rt("}",e),w["(breakage)"]-=1,w["(verb)"]=undefined;return;case"(end)":G("E023",f.tokens.next,"}");return;default:N+=f.option.indent;if(t)switch(f.tokens.curr.id){case",":G("E040");return;case":":t=!1,Bt();break;default:G("E025",f.tokens.curr);return}else{if(f.tokens.curr.id!==":"){G("E021",f.tokens.next,"case",f.tokens.next.value);return}rt(":"),G("E024",f.tokens.curr,":"),Bt()}N-=f.option.indent}}).labelled=!0,pt("debugger",function(){return f.option.debug||K("W087",this),this}).exps=!0,function(){var e=pt("do",function(){w["(breakage)"]+=1,w["(loopage)"]+=1,Qt(),this.first=Ft(!0,!0),rt("while");var e=f.tokens.next;return rt("("),Gt(ot(0)),rt(")",e),w["(breakage)"]-=1,w["(loopage)"]-=1,this});e.labelled=!0,e.exps=!0}(),dt("for",function(){var e,t=f.tokens.next,n=!1,i=null;t.value==="each"&&(i=t,rt("each"),f.option.inMoz(!0)||K("W118",f.tokens.curr,"for each")),w["(breakage)"]+=1,w["(loopage)"]+=1,Qt(),rt("(");var s,o=0,u=["in","of"];do s=nt(o),++o;while(!r.contains(u,s.value)&&s.value!==";"&&s.type!=="(end)");if(r.contains(u,s.value)){!f.option.inESNext()&&s.value==="of"&&G("W104",s,"for of");if(f.tokens.next.id==="var")rt("var"),f.syntax["var"].fud.call(f.syntax["var"].fud,!0);else if(f.tokens.next.id==="let")rt("let"),n=!0,w["(blockscope)"].stack(),f.syntax.let.fud.call(f.syntax.let.fud,!0);else if(!f.tokens.next.identifier)G("E030",f.tokens.next,f.tokens.next.type),rt();else{switch(w[f.tokens.next.value]){case"unused":w[f.tokens.next.value]="var";break;case"var":break;default:w["(blockscope)"].getlabel(f.tokens.next.value)||K("W088",f.tokens.next,f.tokens.next.value)}rt()}rt(s.value),ot(20),rt(")",t),e=Ft(!0,!0),f.option.forin&&e&&(e.length>1||typeof e[0]!="object"||e[0].value!=="if")&&K("W089",this),w["(breakage)"]-=1,w["(loopage)"]-=1}else{i&&G("E045",i);if(f.tokens.next.id!==";")if(f.tokens.next.id==="var")rt("var"),f.syntax["var"].fud.call(f.syntax["var"].fud);else if(f.tokens.next.id==="let")rt("let"),n=!0,w["(blockscope)"].stack(),f.syntax.let.fud.call(f.syntax.let.fud);else for(;;){ot(0,"for");if(f.tokens.next.id!==",")break;lt()}at(f.tokens.curr),rt(";"),f.tokens.next.id!==";"&&Gt(ot(0)),at(f.tokens.curr),rt(";"),f.tokens.next.id===";"&&G("E021",f.tokens.next,")",";");if(f.tokens.next.id!==")")for(;;){ot(0,"for");if(f.tokens.next.id!==",")break;lt()}rt(")",t),Ft(!0,!0),w["(breakage)"]-=1,w["(loopage)"]-=1}return n&&w["(blockscope)"].unstack(),this}).labelled=!0,pt("break",function(){var e=f.tokens.next.value;return w["(breakage)"]===0&&K("W052",f.tokens.next,this.value),f.option.asi||at(this),f.tokens.next.id!==";"&&!f.tokens.next.reach&&f.tokens.curr.line===f.tokens.next.line&&(w[e]!=="label"?K("W090",f.tokens.next,e):D[e]!==w&&K("W091",f.tokens.next,e),this.first=f.tokens.next,rt()),Dt("break"),this}).exps=!0,pt("continue",function(){var e=f.tokens.next.value;return w["(breakage)"]===0&&K("W052",f.tokens.next,this.value),f.option.asi||at(this),f.tokens.next.id!==";"&&!f.tokens.next.reach?f.tokens.curr.line===f.tokens.next.line&&(w[e]!=="label"?K("W090",f.tokens.next,e):D[e]!==w&&K("W091",f.tokens.next,e),this.first=f.tokens.next,rt()):w["(loopage)"]||K("W052",f.tokens.next,this.value),Dt("continue"),this}).exps=!0,pt("return",function(){return this.line===f.tokens.next.line?f.tokens.next.id!==";"&&!f.tokens.next.reach&&(this.first=ot(0),this.first&&this.first.type==="(punctuator)"&&this.first.value==="="&&!this.first.paren&&!f.option.boss&&Q("W093",this.first.line,this.first.character)):f.tokens.next.type==="(punctuator)"&&["[","{","+","-"].indexOf(f.tokens.next.value)>-1&&at(this),Dt("return"),this}).exps=!0,function(e){e.exps=!0,e.lbp=25}(mt("yield",function(){var e=f.tokens.prev;return f.option.inESNext(!0)&&!w["(generator)"]?("(catch)"!==w["(name)"]||!w["(context)"]["(generator)"])&&G("E046",f.tokens.curr,"yield"):f.option.inESNext()||K("W104",f.tokens.curr,"yield"),w["(generator)"]="yielded",this.line===f.tokens.next.line||!f.option.inMoz(!0)?(f.tokens.next.id!==";"&&!f.tokens.next.reach&&f.tokens.next.nud&&(ut(f.tokens.curr,f.tokens.next),this.first=ot(10),this.first.type==="(punctuator)"&&this.first.value==="="&&!this.first.paren&&!f.option.boss&&Q("W093",this.first.line,this.first.character)),f.option.inMoz(!0)&&f.tokens.next.id!==")"&&(e.lbp>30||!e.assign&&!st()||e.id==="yield")&&G("E050",this)):f.option.asi||at(this),this})),pt("throw",function(){return at(this),this.first=ot(20),Dt("throw"),this}).exps=!0,pt("import",function(){f.option.inESNext()||K("W119",f.tokens.curr,"import");if(f.tokens.next.type==="(string)")return rt("(string)"),this;if(f.tokens.next.identifier)this.name=_t(),et(this.name,{type:"unused",token:f.tokens.curr});else{rt("{");for(;;){if(f.tokens.next.value==="}"){rt("}");break}var e;f.tokens.next.type==="default"?(e="default",rt("default")):e=_t(),f.tokens.next.value==="as"&&(rt("as"),e=_t()),et(e,{type:"unused",token:f.tokens.curr});if(f.tokens.next.value!==","){if(f.tokens.next.value==="}"){rt("}");break}G("E024",f.tokens.next,f.tokens.next.value);break}rt(",")}}return rt("from"),rt("(string)"),this}).exps=!0,pt("export",function(){f.option.inESNext()||K("W119",f.tokens.curr,"export");if(f.tokens.next.type==="default"){rt("default");if(f.tokens.next.id==="function"||f.tokens.next.id==="class")this.block=!0;return this.exportee=ot(10),this}if(f.tokens.next.value==="{"){rt("{");for(;;){y[_t()]=!0;if(f.tokens.next.value!==","){if(f.tokens.next.value==="}"){rt("}");break}G("E024",f.tokens.next,f.tokens.next.value);break}rt(",")}return this}return f.tokens.next.id==="var"?(rt("var"),y[f.tokens.next.value]=!0,f.syntax["var"].fud.call(f.syntax["var"].fud)):f.tokens.next.id==="let"?(rt("let"),y[f.tokens.next.value]=!0,f.syntax.let.fud.call(f.syntax.let.fud)):f.tokens.next.id==="const"?(rt("const"),y[f.tokens.next.value]=!0,f.syntax["const"].fud.call(f.syntax["const"].fud)):f.tokens.next.id==="function"?(this.block=!0,rt("function"),y[f.tokens.next.value]=!0,f.syntax["function"].fud()):f.tokens.next.id==="class"?(this.block=!0,rt("class"),y[f.tokens.next.value]=!0,f.syntax["class"].fud()):G("E024",f.tokens.next,f.tokens.next.value),this}).exps=!0,bt("abstract"),bt("boolean"),bt("byte"),bt("char"),bt("class",{es5:!0,nud:rn}),bt("double"),bt("enum",{es5:!0}),bt("export",{es5:!0}),bt("extends",{es5:!0}),bt("final"),bt("float"),bt("goto"),bt("implements",{es5:!0,strictOnly:!0}),bt("import",{es5:!0}),bt("int"),bt("interface",{es5:!0,strictOnly:!0}),bt("long"),bt("native"),bt("package",{es5:!0,strictOnly:!0}),bt("private",{es5:!0,strictOnly:!0}),bt("protected",{es5:!0,strictOnly:!0}),bt("public",{es5:!0,strictOnly:!0}),bt("short"),bt("static",{es5:!0,strictOnly:!0}),bt("super",{es5:!0}),bt("synchronized"),bt("transient"),bt("volatile");var on=function(){var e,t,n=-1,i=0,s={};r.contains(["[","{"],f.tokens.curr.value)&&(i+=1);do{e=n===-1?f.tokens.next:nt(n),t=nt(n+1),n+=1,r.contains(["[","{"],e.value)?i+=1:r.contains(["]","}"],e.value)&&(i-=1);if(e.identifier&&e.value==="for"&&i===1){s.isCompArray=!0,s.notJson=!0;break}if(r.contains(["}","]"],e.value)&&t.value==="="&&i===0){s.isDestAssign=!0,s.notJson=!0;break}e.value===";"&&(s.isBlock=!0,s.notJson=!0)}while(i>0&&e.id!=="(end)"&&n<15);return s},an=function(){function i(e){var t=n.variables.filter(function(t){if(t.value===e)return t.undef=!1,e}).length;return t!==0}function s(e){var t=n.variables.filter(function(t){if(t.value===e&&!t.undef)return t.unused===!0&&(t.unused=!1),e}).length;return t===0}var e=function(){this.mode="use",this.variables=[]},t=[],n;return{stack:function(){n=new e,t.push(n)},unstack:function(){n.variables.filter(function(e){e.unused&&K("W098",e.token,e.value),e.undef&&$(e.funct,"W117",e.token,e.value)}),t.splice(-1,1),n=t[t.length-1]},setState:function(e){r.contains(["use","define","generate","filter"],e)&&(n.mode=e)},check:function(e){if(!n)return;return n&&n.mode==="use"?(s(e)&&n.variables.push({funct:w,token:f.tokens.curr,value:e,undef:!0,unused:!1}),!0):n&&n.mode==="define"?(i(e)||n.variables.push({funct:w,token:f.tokens.curr,value:e,undef:!1,unused:!0}),!0):n&&n.mode==="generate"?($(w,"W117",f.tokens.curr,e),!0):n&&n.mode==="filter"?(s(e)&&$(w,"W117",f.tokens.curr,e),!0):!1}}},ln=function(){function n(){for(var t in e)if(e[t]["(type)"]==="unused"&&f.option.unused){var n=e[t]["(token)"],r=n.line,i=n.character;Q("W098",r,i,t)}}var e={},t=[e];return{stack:function(){e={},t.push(e)},unstack:function(){n(),t.splice(t.length-1,1),e=r.last(t)},getlabel:function(e){for(var n=t.length-1;n>=0;--n)if(r.has(t[n],e)&&!t[n][e]["(shadowed)"])return t[n]},shadow:function(e){for(var n=t.length-1;n>=0;n--)r.has(t[n],e)&&(t[n][e]["(shadowed)"]=!0)},unshadow:function(e){for(var n=t.length-1;n>=0;n--)r.has(t[n],e)&&(t[n][e]["(shadowed)"]=!1)},current:{has:function(t){return r.has(e,t)},add:function(t,n,r){e[t]={"(type)":n,"(token)":r,"(shadowed)":!1}}}}},cn=function(e,n,i){function v(e,t){if(!e)return;!Array.isArray(e)&&typeof e=="object"&&(e=Object.keys(e)),e.forEach(t)}var o,a,l,h,p={},d={};n=r.clone(n),f.reset(),n&&n.scope?c.scope=n.scope:(c.errors=[],c.undefs=[],c.internals=[],c.blacklist={},c.scope="(main)"),M=Object.create(null),W(M,s.ecmaIdentifiers),W(M,s.reservedVars),W(M,i||{}),g=Object.create(null),y=Object.create(null);if(n){v(n.predef||null,function(e){var t,r;e[0]==="-"?(t=e.slice(1),c.blacklist[t]=t):(r=Object.getOwnPropertyDescriptor(n.predef,e),M[e]=r?r.value:!1)}),v(n.exported||null,function(e){y[e]=!0}),delete n.predef,delete n.exported,h=Object.keys(n);for(l=0;l<h.length;l++)/^-W\d{3}$/g.test(h[l])?d[h[l].slice(1)]=!0:(p[h[l]]=n[h[l]],h[l]==="newcap"&&n[h[l]]===!1&&(p["(explicitNewcap)"]=!0))}f.option=p,f.ignored=d,f.option.indent=f.option.indent||4,f.option.maxerr=f.option.maxerr||50,N=1,S=Object.create(M),D=S,w=$t("(global)",null,D,{"(global)":!0,"(blockscope)":ln(),"(comparray)":an(),"(metrics)":Kt(f.tokens.next)}),E=[w],B=[],P=null,L={},A=null,x={},T=!1,C=[],H=[];if(!q(e)&&!Array.isArray(e))return Y("E004",0),!1;t={get isJSON(){return f.jsonMode},getOption:function(e){return f.option[e]||null},getCache:function(e){return f.cache[e]},setCache:function(e,t){f.cache[e]=t},warn:function(e,t){Q.apply(null,[e,t.line,t.char].concat(t.data))},on:function(e,t){e.split(" ").forEach(function(e){F.on(e,t)}.bind(this))}},F.removeAllListeners(),(j||[]).forEach(function(e){e(t)}),f.tokens.prev=f.tokens.curr=f.tokens.next=f.syntax["(begin)"],k=new u(e),k.on("warning",function(e){Q.apply(null,[e.code,e.line,e.character].concat(e.data))}),k.on("error",function(e){Y.apply(null,[e.code,e.line,e.character].concat(e.data))}),k.on("fatal",function(e){V("E041",e.line,e.from)}),k.on("Identifier",function(e){F.emit("Identifier",e)}),k.on("String",function(e){F.emit("String",e)}),k.on("Number",function(e){F.emit("Number",e)}),k.start();for(var m in n)r.has(n,m)&&I(m,f.tokens.curr);X(),W(M,i||{}),lt.first=!0;try{rt();switch(f.tokens.next.id){case"{":case"[":un();break;default:jt(),f.directive["use strict"]&&!f.option.globalstrict&&!f.option.node&&!f.option.phantom&&K("W097",f.tokens.prev),Bt()}rt(f.tokens.next&&f.tokens.next.value!=="."?"(end)":undefined),w["(blockscope)"].unstack();var b=function(e,t){do{if(typeof t[e]=="string")return t[e]==="unused"?t[e]="var":t[e]==="unction"&&(t[e]="closure"),!0;t=t["(context)"]}while(t);return!1},O=function(e,t){if(!x[e])return;var n=[];for(var r=0;r<x[e].length;r+=1)x[e][r]!==t&&n.push(x[e][r]);n.length===0?delete x[e]:x[e]=n},R=function(e,t,n,r){var i=t.line,s=t.character;r===undefined&&(r=f.option.unused),r===!0&&(r="last-param");var o={vars:["var"],"last-param":["var","param"],strict:["var","param","last-param"]};r&&o[r]&&o[r].indexOf(n)!==-1&&Q("W098",i,s,e),H.push({name:e,line:i,character:s})},U=function(e,t){var n=e[t],i=e["(tokens)"][t];if(t.charAt(0)==="(")return;if(n!=="unused"&&n!=="unction"&&n!=="const")return;if(e["(params)"]&&e["(params)"].indexOf(t)!==-1)return;if(e["(global)"]&&r.has(y,t))return;if(n==="const"&&!Vt(e,t,"unused"))return;R(t,i,"var")};for(o=0;o<c.undefs.length;o+=1)a=c.undefs[o].slice(0),b(a[2].value,a[0])?O(a[2].value,a[2].line):f.option.undef&&K.apply(K,a.slice(1));E.forEach(function(e){if(e["(unusedOption)"]===!1)return;for(var t in e)r.has(e,t)&&U(e,t);if(!e["(params)"])return;var n=e["(params)"].slice(),i=n.pop(),s,o;while(i){s=e[i],o=e["(unusedOption)"]||f.option.unused,o=o===!0?"last-param":o;if(i==="undefined")return;if(s==="unused"||s==="unction")R(i,e["(tokens)"][i],"param",e["(unusedOption)"]);else if(o==="last-param")return;i=n.pop()}});for(var z in g)r.has(g,z)&&!r.has(S,z)&&!r.has(y,z)&&R(z,g[z],"var")}catch($){if(!$||$.name!=="JSHintError")throw $;var J=f.tokens.next||{};c.errors.push({scope:"(main)",raw:$.raw,code:$.code,reason:$.message,line:$.line||J.line,character:$.character||J.from},null)}if(c.scope==="(main)"){n=n||{};for(o=0;o<c.internals.length;o+=1)a=c.internals[o],n.scope=a.elem,cn(a.value,n,i)}return c.errors.length===0};return cn.addModule=function(e){j.push(e)},cn.addModule(l.register),cn.data=function(){var e={functions:[],options:f.option},t=[],n=[],i,s,o,u,a,l;cn.errors.length&&(e.errors=cn.errors),f.jsonMode&&(e.json=!0);for(a in x)r.has(x,a)&&t.push({name:a,line:x[a]});t.length>0&&(e.implieds=t),B.length>0&&(e.urls=B),l=Object.keys(D),l.length>0&&(e.globals=l);for(o=1;o<E.length;o+=1){s=E[o],i={};for(u=0;u<b.length;u+=1)i[b[u]]=[];for(u=0;u<b.length;u+=1)i[b[u]].length===0&&delete i[b[u]];i.name=s["(name)"],i.param=s["(params)"],i.line=s["(line)"],i.character=s["(character)"],i.last=s["(last)"],i.lastcharacter=s["(lastcharacter)"],i.metrics={complexity:s["(metrics)"].ComplexityCount,parameters:(s["(params)"]||[]).length,statements:s["(metrics)"].statementCount},e.functions.push(i)}H.length>0&&(e.unused=H),n=[];for(a in L)if(typeof L[a]=="number"){e.member=L;break}return e},cn.jshint=cn,cn}();typeof n=="object"&&n&&(n.JSHINT=c)},{"./lex.js":4,"./messages.js":5,"./reg.js":6,"./state.js":7,"./style.js":8,"./vars.js":9,events:10,underscore:2}],4:[function(e,t,n){"use strict";function c(){var e=[];return{push:function(t){e.push(t)},check:function(){for(var t=0;t<e.length;++t)e[t]();e.splice(0,e.length)}}}function h(e){var t=e;typeof t=="string"&&(t=t.replace(/\r\n/g,"\n").replace(/\r/g,"\n").split("\n")),t[0]&&t[0].substr(0,2)==="#!"&&(t[0].indexOf("node")!==-1&&(o.option.node=!0),t[0]=""),this.emitter=new i.EventEmitter,this.source=e,this.setLines(t),this.prereg=!0,this.line=0,this.char=1,this.from=1,this.input="",this.inComment=!1;for(var n=0;n<o.option.indent;n+=1)o.tab+=" "}var r=e("underscore"),i=e("events"),s=e("./reg.js"),o=e("./state.js").state,u=e("../data/ascii-identifier-data.js"),a=u.asciiIdentifierStartTable,f=u.asciiIdentifierPartTable,l={Identifier:1,Punctuator:2,NumericLiteral:3,StringLiteral:4,Comment:5,Keyword:6,NullLiteral:7,BooleanLiteral:8,RegExp:9,TemplateLiteral:10};h.prototype={_lines:[],getLines:function(){return this._lines=o.lines,this._lines},setLines:function(e){this._lines=e,o.lines=this._lines},peek:function(e){return this.input.charAt(e||0)},skip:function(e){e=e||1,this.char+=e,this.input=this.input.slice(e)},on:function(e,t){e.split(" ").forEach(function(e){this.emitter.on(e,t)}.bind(this))},trigger:function(){this.emitter.emit.apply(this.emitter,Array.prototype.slice.call(arguments))},triggerAsync:function(e,t,n,r){n.push(function(){r()&&this.trigger(e,t)}.bind(this))},scanPunctuator:function(){var e=this.peek(),t,n,r;switch(e){case".":if(/^[0-9]$/.test(this.peek(1)))return null;if(this.peek(1)==="."&&this.peek(2)===".")return{type:l.Punctuator,value:"..."};case"(":case")":case";":case",":case"{":case"}":case"[":case"]":case":":case"~":case"?":return{type:l.Punctuator,value:e};case"#":return{type:l.Punctuator,value:e};case"":return null}return t=this.peek(1),n=this.peek(2),r=this.peek(3),e===">"&&t===">"&&n===">"&&r==="="?{type:l.Punctuator,value:">>>="}:e==="="&&t==="="&&n==="="?{type:l.Punctuator,value:"==="}:e==="!"&&t==="="&&n==="="?{type:l.Punctuator,value:"!=="}:e===">"&&t===">"&&n===">"?{type:l.Punctuator,value:">>>"}:e==="<"&&t==="<"&&n==="="?{type:l.Punctuator,value:"<<="}:e===">"&&t===">"&&n==="="?{type:l.Punctuator,value:">>="}:e==="="&&t===">"?{type:l.Punctuator,value:e+t}:e===t&&"+-<>&|".indexOf(e)>=0?{type:l.Punctuator,value:e+t}:"<>=!+-*%&|^".indexOf(e)>=0?t==="="?{type:l.Punctuator,value:e+t}:{type:l.Punctuator,value:e}:e==="/"?t==="="&&/\/=(?!(\S*\/[gim]?))/.test(this.input)?{type:l.Punctuator,value:"/="}:{type:l.Punctuator,value:"/"}:null},scanComments:function(){function s(e,t,n){var r=["jshint","jslint","members","member","globals","global","exported"],i=!1,s=e+t,o="plain";return n=n||{},n.isMultiline&&(s+="*/"),r.forEach(function(n){if(i)return;if(e==="//"&&n!=="jshint")return;t.substr(0,n.length)===n&&(i=!0,e+=n,t=t.substr(n.length)),!i&&t.charAt(0)===" "&&t.substr(1,n.length)===n&&(i=!0,e=e+" "+n,t=t.substr(n.length+1));if(!i)return;switch(n){case"member":o="members";break;case"global":o="globals";break;default:o=n}}),{type:l.Comment,commentType:o,value:s,body:t,isSpecial:i,isMultiline:n.isMultiline||!1,isMalformed:n.isMalformed||!1}}var e=this.peek(),t=this.peek(1),n=this.input.substr(2),r=this.line,i=this.char;if(e==="*"&&t==="/")return this.trigger("error",{code:"E018",line:r,character:i}),this.skip(2),null;if(e!=="/"||t!=="*"&&t!=="/")return null;if(t==="/")return this.skip(this.input.length),s("//",n);var o="";if(t==="*"){this.inComment=!0,this.skip(2);while(this.peek()!=="*"||this.peek(1)!=="/")if(this.peek()===""){o+="\n";if(!this.nextLine())return this.trigger("error",{code:"E017",line:r,character:i}),this.inComment=!1,s("/*",o,{isMultiline:!0,isMalformed:!0})}else o+=this.peek(),this.skip();return this.skip(2),this.inComment=!1,s("/*",o,{isMultiline:!0})}},scanKeyword:function(){var e=/^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input),t=["if","in","do","var","for","new","try","let","this","else","case","void","with","enum","while","break","catch","throw","const","yield","class","super","return","typeof","delete","switch","export","import","default","finally","extends","function","continue","debugger","instanceof"];return e&&t.indexOf(e[0])>=0?{type:l.Keyword,value:e[0]}:null},scanIdentifier:function(){function i(e){return e>256}function s(e){return e>256}function o(e){return/^[0-9a-fA-F]$/.test(e)}var e="",t=0,n,r,u=function(){t+=1;if(this.peek(t)!=="u")return null;var e=this.peek(t+1),n=this.peek(t+2),r=this.peek(t+3),i=this.peek(t+4),u;return o(e)&&o(n)&&o(r)&&o(i)?(u=parseInt(e+n+r+i,16),f[u]||s(u)?(t+=5,"\\u"+e+n+r+i):null):null}.bind(this),c=function(){var e=this.peek(t),n=e.charCodeAt(0);return n===92?u():n<128?a[n]?(t+=1,e):null:i(n)?(t+=1,e):null}.bind(this),h=function(){var e=this.peek(t),n=e.charCodeAt(0);return n===92?u():n<128?f[n]?(t+=1,e):null:s(n)?(t+=1,e):null}.bind(this);r=c();if(r===null)return null;e=r;for(;;){r=h();if(r===null)break;e+=r}switch(e){case"true":case"false":n=l.BooleanLiteral;break;case"null":n=l.NullLiteral;break;default:n=l.Identifier}return{type:n,value:e}},scanNumericLiteral:function(){function s(e){return/^[0-9]$/.test(e)}function o(e){return/^[0-7]$/.test(e)}function u(e){return/^[0-9a-fA-F]$/.test(e)}function a(e){return e==="$"||e==="_"||e==="\\"||e>="a"&&e<="z"||e>="A"&&e<="Z"}var e=0,t="",n=this.input.length,r=this.peek(e),i;if(r!=="."&&!s(r))return null;if(r!=="."){t=this.peek(e),e+=1,r=this.peek(e);if(t==="0"){if(r==="x"||r==="X"){e+=1,t+=r;while(e<n){r=this.peek(e);if(!u(r))break;t+=r,e+=1}if(t.length<=2)return{type:l.NumericLiteral,value:t,isMalformed:!0};if(e<n){r=this.peek(e);if(a(r))return null}return{type:l.NumericLiteral,value:t,base:16,isMalformed:!1}}if(o(r)){e+=1,t+=r,i=!1;while(e<n){r=this.peek(e);if(s(r))i=!0;else if(!o(r))break;t+=r,e+=1}if(e<n){r=this.peek(e);if(a(r))return null}return{type:l.NumericLiteral,value:t,base:8,isMalformed:!1}}s(r)&&(e+=1,t+=r)}while(e<n){r=this.peek(e);if(!s(r))break;t+=r,e+=1}}if(r==="."){t+=r,e+=1;while(e<n){r=this.peek(e);if(!s(r))break;t+=r,e+=1}}if(r==="e"||r==="E"){t+=r,e+=1,r=this.peek(e);if(r==="+"||r==="-")t+=this.peek(e),e+=1;r=this.peek(e);if(!s(r))return null;t+=r,e+=1;while(e<n){r=this.peek(e);if(!s(r))break;t+=r,e+=1}}if(e<n){r=this.peek(e);if(a(r))return null}return{type:l.NumericLiteral,value:t,base:10,isMalformed:!isFinite(t)}},scanTemplateLiteral:function(){if(!o.option.esnext||this.peek()!=="`")return null;var e=this.line,t=this.char,n=1,r="";this.skip();while(this.peek()!=="`"){while(this.peek()===""){if(!this.nextLine())return this.trigger("error",{code:"E052",line:e,character:t}),{type:l.TemplateLiteral,value:r,isUnclosed:!0};r+="\n"}var i=this.peek();this.skip(n),r+=i}return this.skip(),{type:l.TemplateLiteral,value:r,isUnclosed:!1}},scanStringLiteral:function(e){var t=this.peek();if(t!=='"'&&t!=="'")return null;this.triggerAsync("warning",{code:"W108",line:this.line,character:this.char},e,function(){return o.jsonMode&&t!=='"'});var n="",r=this.line,i=this.char,s=!1;this.skip();e:while(this.peek()!==t){while(this.peek()===""){s?(s=!1,this.triggerAsync("warning",{code:"W043",line:this.line,character:this.char},e,function(){return!o.option.multistr}),this.triggerAsync("warning",{code:"W042",line:this.line,character:this.char},e,function(){return o.jsonMode&&o.option.multistr})):this.trigger("warning",{code:"W112",line:this.line,character:this.char});if(!this.nextLine())return this.trigger("error",{code:"E029",line:r,character:i}),{type:l.StringLiteral,value:n,isUnclosed:!0,quote:t};if(this.peek()==t)break e}s=!1;var u=this.peek(),a=1;u<" "&&this.trigger("warning",{code:"W113",line:this.line,character:this.char,data:["<non-printable>"]});if(u==="\\"){this.skip(),u=this.peek();switch(u){case"'":this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["\\'"]},e,function(){return o.jsonMode});break;case"b":u="\\b";break;case"f":u="\\f";break;case"n":u="\\n";break;case"r":u="\\r";break;case"t":u="\\t";break;case"0":u="\\0";var f=parseInt(this.peek(1),10);this.triggerAsync("warning",{code:"W115",line:this.line,character:this.char},e,function(){return f>=0&&f<=7&&o.directive["use strict"]});break;case"u":u=String.fromCharCode(parseInt(this.input.substr(1,4),16)),a=5;break;case"v":this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["\\v"]},e,function(){return o.jsonMode}),u="";break;case"x":var c=parseInt(this.input.substr(1,2),16);this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["\\x-"]},e,function(){return o.jsonMode}),u=String.fromCharCode(c),a=3;break;case"\\":u="\\\\";break;case'"':u='\\"';break;case"/":break;case"":s=!0,u="";break;case"!":if(n.slice(n.length-2)==="<")break;default:this.trigger("warning",{code:"W044",line:this.line,character:this.char})}}n+=u,this.skip(a)}return this.skip(),{type:l.StringLiteral,value:n,isUnclosed:!1,quote:t}},scanRegExp:function(){var e=0,t=this.input.length,n=this.peek(),r=n,i="",s=[],o=!1,u=!1,a,f=function(){n<" "&&(o=!0,this.trigger("warning",{code:"W048",line:this.line,character:this.char})),n==="<"&&(o=!0,this.trigger("warning",{code:"W049",line:this.line,character:this.char,data:[n]}))}.bind(this);if(!this.prereg||n!=="/")return null;e+=1,a=!1;while(e<t){n=this.peek(e),r+=n,i+=n;if(u){n==="]"&&(this.peek(e-1)!=="\\"||this.peek(e-2)==="\\")&&(u=!1),n==="\\"&&(e+=1,n=this.peek(e),i+=n,r+=n,f()),e+=1;continue}if(n==="\\"){e+=1,n=this.peek(e),i+=n,r+=n,f();if(n==="/"){e+=1;continue}if(n==="["){e+=1;continue}}if(n==="["){u=!0,e+=1;continue}if(n==="/"){i=i.substr(0,i.length-1),a=!0,e+=1;break}e+=1}if(!a)return this.trigger("error",{code:"E015",line:this.line,character:this.from}),void this.trigger("fatal",{line:this.line,from:this.from});while(e<t){n=this.peek(e);if(!/[gim]/.test(n))break;s.push(n),r+=n,e+=1}try{new RegExp(i,s.join(""))}catch(c){o=!0,this.trigger("error",{code:"E016",line:this.line,character:this.char,data:[c.message]})}return{type:l.RegExp,value:r,flags:s,isMalformed:o}},scanNonBreakingSpaces:function(){return o.option.nonbsp?this.input.search(/(\u00A0)/):-1},scanUnsafeChars:function(){return this.input.search(s.unsafeChars)},next:function(e){this.from=this.char;var t;if(/\s/.test(this.peek())){t=this.char;while(/\s/.test(this.peek()))this.from+=1,this.skip()}var n=this.scanComments()||this.scanStringLiteral(e)||this.scanTemplateLiteral();return n?n:(n=this.scanRegExp()||this.scanPunctuator()||this.scanKeyword()||this.scanIdentifier()||this.scanNumericLiteral(),n?(this.skip(n.value.length),n):null)},nextLine:function(){var e;if(this.line>=this.getLines().length)return!1;this.input=this.getLines()[this.line],this.line+=1,this.char=1,this.from=1;var t=this.input.trim(),n=function(){return r.some(arguments,function(e){return t.indexOf(e)===0})},i=function(){return r.some(arguments,function(e){return t.indexOf(e,t.length-e.length)!==-1})};o.ignoreLinterErrors===!0&&!n("/*","//")&&!i("*/")&&(this.input=""),e=this.scanNonBreakingSpaces(),e>=0&&this.trigger("warning",{code:"W125",line:this.line,character:e+1}),this.input=this.input.replace(/\t/g,o.tab),e=this.scanUnsafeChars(),e>=0&&this.trigger("warning",{code:"W100",line:this.line,character:e});if(o.option.maxlen&&o.option.maxlen<this.input.length){var u=this.inComment||n.call(t,"//")||n.call(t,"/*"),a=!u||!s.maxlenException.test(t);a&&this.trigger("warning",{code:"W101",line:this.line,character:this.input.length})}return!0},start:function(){this.nextLine()},token:function(){function n(e,t){if(!e.reserved)return!1;var n=e.meta;if(n&&n.isFutureReservedWord&&o.option.inES5()){if(!n.es5)return!1;if(n.strictOnly&&!o.option.strict&&!o.directive["use strict"])return!1;if(t)return!1}return!0}var e=c(),t,i=function(t,i,s){var u;t!=="(endline)"&&t!=="(end)"&&(this.prereg=!1);if(t==="(punctuator)"){switch(i){case".":case")":case"~":case"#":case"]":this.prereg=!1;break;default:this.prereg=!0}u=Object.create(o.syntax[i]||o.syntax["(error)"])}if(t==="(identifier)"){if(i==="return"||i==="case"||i==="typeof")this.prereg=!0;r.has(o.syntax,i)&&(u=Object.create(o.syntax[i]||o.syntax["(error)"]),n(u,s&&t==="(identifier)")||(u=null))}return u||(u=Object.create(o.syntax[t])),u.identifier=t==="(identifier)",u.type=u.type||t,u.value=i,u.line=this.line,u.character=this.char,u.from=this.from,s&&u.identifier&&(u.isProperty=s),u.check=e.check,u}.bind(this);for(;;){if(!this.input.length)return i(this.nextLine()?"(endline)":"(end)","");t=this.next(e);if(!t){this.input.length&&(this.trigger("error",{code:"E024",line:this.line,character:this.char,data:[this.peek()]}),this.input="");continue}switch(t.type){case l.StringLiteral:return this.triggerAsync("String",{line:this.line,"char":this.char,from:this.from,value:t.value,quote:t.quote},e,function(){return!0}),i("(string)",t.value);case l.TemplateLiteral:return this.trigger("Template",{line:this.line,"char":this.char,from:this.from,value:t.value}),i("(template)",t.value);case l.Identifier:this.trigger("Identifier",{line:this.line,"char":this.char,from:this.form,name:t.value,isProperty:o.tokens.curr.id==="."});case l.Keyword:case l.NullLiteral:case l.BooleanLiteral:return i("(identifier)",t.value,o.tokens.curr.id===".");case l.NumericLiteral:return t.isMalformed&&this.trigger("warning",{code:"W045",line:this.line,character:this.char,data:[t.value]}),this.triggerAsync("warning",{code:"W114",line:this.line,character:this.char,data:["0x-"]},e,function(){return t.base===16&&o.jsonMode}),this.triggerAsync("warning",{code:"W115",line:this.line,character:this.char},e,function(){return o.directive["use strict"]&&t.base===8}),this.trigger("Number",{line:this.line,"char":this.char,from:this.from,value:t.value,base:t.base,isMalformed:t.malformed}),i("(number)",t.value);case l.RegExp:return i("(regexp)",t.value);case l.Comment:o.tokens.curr.comment=!0;if(t.isSpecial)return{id:"(comment)",value:t.value,body:t.body,type:t.commentType,isSpecial:t.isSpecial,line:this.line,character:this.char,from:this.from};break;case"":break;default:return i("(punctuator)",t.value)}}}},n.Lexer=h},{"../data/ascii-identifier-data.js":1,"./reg.js":6,"./state.js":7,events:10,underscore:2}],5:[function(e,t,n){"use strict";var r=e("underscore"),i={E001:"Bad option: '{a}'.",E002:"Bad option value.",E003:"Expected a JSON value.",E004:"Input is neither a string nor an array of strings.",E005:"Input is empty.",E006:"Unexpected early end of program.",E007:'Missing "use strict" statement.',E008:"Strict violation.",E009:"Option 'validthis' can't be used in a global scope.",E010:"'with' is not allowed in strict mode.",E011:"const '{a}' has already been declared.",E012:"const '{a}' is initialized to 'undefined'.",E013:"Attempting to override '{a}' which is a constant.",E014:"A regular expression literal can be confused with '/='.",E015:"Unclosed regular expression.",E016:"Invalid regular expression.",E017:"Unclosed comment.",E018:"Unbegun comment.",E019:"Unmatched '{a}'.",E020:"Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",E021:"Expected '{a}' and instead saw '{b}'.",E022:"Line breaking error '{a}'.",E023:"Missing '{a}'.",E024:"Unexpected '{a}'.",E025:"Missing ':' on a case clause.",E026:"Missing '}' to match '{' from line {a}.",E027:"Missing ']' to match '[' from line {a}.",E028:"Illegal comma.",E029:"Unclosed string.",E030:"Expected an identifier and instead saw '{a}'.",E031:"Bad assignment.",E032:"Expected a small integer or 'false' and instead saw '{a}'.",E033:"Expected an operator and instead saw '{a}'.",E034:"get/set are ES5 features.",E035:"Missing property name.",E036:"Expected to see a statement and instead saw a block.",E037:null,E038:null,E039:"Function declarations are not invocable. Wrap the whole function invocation in parens.",E040:"Each value should have its own case label.",E041:"Unrecoverable syntax error.",E042:"Stopping.",E043:"Too many errors.",E044:null,E045:"Invalid for each loop.",E046:"A yield statement shall be within a generator function (with syntax: `function*`)",E047:null,E048:"Let declaration not directly within block.",E049:"A {a} cannot be named '{b}'.",E050:"Mozilla requires the yield expression to be parenthesized here.",E051:"Regular parameters cannot come after default parameters.",E052:"Unclosed template literal."},s={W001:"'hasOwnProperty' is a really bad name.",W002:"Value of '{a}' may be overwritten in IE 8 and earlier.",W003:"'{a}' was used before it was defined.",W004:"'{a}' is already defined.",W005:"A dot following a number can be confused with a decimal point.",W006:"Confusing minuses.",W007:"Confusing plusses.",W008:"A leading decimal point can be confused with a dot: '{a}'.",W009:"The array literal notation [] is preferable.",W010:"The object literal notation {} is preferable.",W011:null,W012:null,W013:null,W014:"Bad line breaking before '{a}'.",W015:null,W016:"Unexpected use of '{a}'.",W017:"Bad operand.",W018:"Confusing use of '{a}'.",W019:"Use the isNaN function to compare with NaN.",W020:"Read only.",W021:"'{a}' is a function.",W022:"Do not assign to the exception parameter.",W023:"Expected an identifier in an assignment and instead saw a function invocation.",W024:"Expected an identifier and instead saw '{a}' (a reserved word).",W025:"Missing name in function declaration.",W026:"Inner functions should be listed at the top of the outer function.",W027:"Unreachable '{a}' after '{b}'.",W028:"Label '{a}' on {b} statement.",W030:"Expected an assignment or function call and instead saw an expression.",W031:"Do not use 'new' for side effects.",W032:"Unnecessary semicolon.",W033:"Missing semicolon.",W034:'Unnecessary directive "{a}".',W035:"Empty block.",W036:"Unexpected /*member '{a}'.",W037:"'{a}' is a statement label.",W038:"'{a}' used out of scope.",W039:"'{a}' is not allowed.",W040:"Possible strict violation.",W041:"Use '{a}' to compare with '{b}'.",W042:"Avoid EOL escaping.",W043:"Bad escaping of EOL. Use option multistr if needed.",W044:"Bad or unnecessary escaping.",W045:"Bad number '{a}'.",W046:"Don't use extra leading zeros '{a}'.",W047:"A trailing decimal point can be confused with a dot: '{a}'.",W048:"Unexpected control character in regular expression.",W049:"Unexpected escaped character '{a}' in regular expression.",W050:"JavaScript URL.",W051:"Variables should not be deleted.",W052:"Unexpected '{a}'.",W053:"Do not use {a} as a constructor.",W054:"The Function constructor is a form of eval.",W055:"A constructor name should start with an uppercase letter.",W056:"Bad constructor.",W057:"Weird construction. Is 'new' necessary?",W058:"Missing '()' invoking a constructor.",W059:"Avoid arguments.{a}.",W060:"document.write can be a form of eval.",W061:"eval can be harmful.",W062:"Wrap an immediate function invocation in parens to assist the reader in understanding that the expression is the result of a function, and not the function itself.",W063:"Math is not a function.",W064:"Missing 'new' prefix when invoking a constructor.",W065:"Missing radix parameter.",W066:"Implied eval. Consider passing a function instead of a string.",W067:"Bad invocation.",W068:"Wrapping non-IIFE function literals in parens is unnecessary.",W069:"['{a}'] is better written in dot notation.",W070:"Extra comma. (it breaks older versions of IE)",W071:"This function has too many statements. ({a})",W072:"This function has too many parameters. ({a})",W073:"Blocks are nested too deeply. ({a})",W074:"This function's cyclomatic complexity is too high. ({a})",W075:"Duplicate key '{a}'.",W076:"Unexpected parameter '{a}' in get {b} function.",W077:"Expected a single parameter in set {a} function.",W078:"Setter is defined without getter.",W079:"Redefinition of '{a}'.",W080:"It's not necessary to initialize '{a}' to 'undefined'.",W081:null,W082:"Function declarations should not be placed in blocks. Use a function expression or move the statement to the top of the outer function.",W083:"Don't make functions within a loop.",W084:"Assignment in conditional expression",W085:"Don't use 'with'.",W086:"Expected a 'break' statement before '{a}'.",W087:"Forgotten 'debugger' statement?",W088:"Creating global 'for' variable. Should be 'for (var {a} ...'.",W089:"The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.",W090:"'{a}' is not a statement label.",W091:"'{a}' is out of scope.",W093:"Did you mean to return a conditional instead of an assignment?",W094:"Unexpected comma.",W095:"Expected a string and instead saw {a}.",W096:"The '{a}' key may produce unexpected results.",W097:'Use the function form of "use strict".',W098:"'{a}' is defined but never used.",W099:null,W100:"This character may get silently deleted by one or more browsers.",W101:"Line is too long.",W102:null,W103:"The '{a}' property is deprecated.",W104:"'{a}' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).",W105:"Unexpected {a} in '{b}'.",W106:"Identifier '{a}' is not in camel case.",W107:"Script URL.",W108:"Strings must use doublequote.",W109:"Strings must use singlequote.",W110:"Mixed double and single quotes.",W112:"Unclosed string.",W113:"Control character in string: {a}.",W114:"Avoid {a}.",W115:"Octal literals are not allowed in strict mode.",W116:"Expected '{a}' and instead saw '{b}'.",W117:"'{a}' is not defined.",W118:"'{a}' is only available in Mozilla JavaScript extensions (use moz option).",W119:"'{a}' is only available in ES6 (use esnext option).",W120:"You might be leaking a variable ({a}) here.",W121:"Extending prototype of native object: '{a}'.",W122:"Invalid typeof value '{a}'",W123:"'{a}' is already defined in outer scope.",W124:"A generator function shall contain a yield statement.",W125:"This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp"},o={I001:"Comma warnings can be turned off with 'laxcomma'.",I002:null,I003:"ES5 option is now set per default"};n.errors={},n.warnings={},n.info={},r.each(i,function(e,t){n.errors[t]={code:t,desc:e}}),r.each(s,function(e,t){n.warnings[t]={code:t,desc:e}}),r.each(o,function(e,t){n.info[t]={code:t,desc:e}})},{underscore:2}],6:[function(e,t,n){"use string";n.unsafeString=/@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i,n.unsafeChars=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,n.needEsc=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,n.needEscGlobal=/[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,n.starSlash=/\*\//,n.identifier=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,n.javascriptURL=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i,n.fallsThrough=/^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/,n.maxlenException=/^(?:(?:\/\/|\/\*|\*) ?)?[^ ]+$/},{}],7:[function(e,t,n){"use strict";var r={syntax:{},reset:function(){this.tokens={prev:null,next:null,curr:null},this.option={},this.ignored={},this.directive={},this.jsonMode=!1,this.jsonWarnings=[],this.lines=[],this.tab="",this.cache={},this.ignoredLines={},this.ignoreLinterErrors=!1}};n.state=r},{}],8:[function(e,t,n){"use strict";n.register=function(e){e.on("Identifier",function(n){if(e.getOption("proto"))return;n.name==="__proto__"&&e.warn("W103",{line:n.line,"char":n.char,data:[n.name]})}),e.on("Identifier",function(n){if(e.getOption("iterator"))return;n.name==="__iterator__"&&e.warn("W104",{line:n.line,"char":n.char,data:[n.name]})}),e.on("Identifier",function(n){if(!e.getOption("camelcase"))return;n.name.replace(/^_+|_+$/g,"").indexOf("_")>-1&&!n.name.match(/^[A-Z0-9_]*$/)&&e.warn("W106",{line:n.line,"char":n.from,data:[n.name]})}),e.on("String",function(n){var r=e.getOption("quotmark"),i;if(!r)return;r==="single"&&n.quote!=="'"&&(i="W109"),r==="double"&&n.quote!=='"'&&(i="W108"),r===!0&&(e.getCache("quotmark")||e.setCache("quotmark",n.quote),e.getCache("quotmark")!==n.quote&&(i="W110")),i&&e.warn(i,{line:n.line,"char":n.char})}),e.on("Number",function(n){n.value.charAt(0)==="."&&e.warn("W008",{line:n.line,"char":n.char,data:[n.value]}),n.value.substr(n.value.length-1)==="."&&e.warn("W047",{line:n.line,"char":n.char,data:[n.value]}),/^00+/.test(n.value)&&e.warn("W046",{line:n.line,"char":n.char,data:[n.value]})}),e.on("String",function(n){var r=/^(?:javascript|jscript|ecmascript|vbscript|livescript)\s*:/i;if(e.getOption("scripturl"))return;r.test(n.value)&&e.warn("W107",{line:n.line,"char":n.char})})}},{}],9:[function(e,t,n){"use strict";n.reservedVars={arguments:!1,NaN:!1},n.ecmaIdentifiers={Array:!1,Boolean:!1,Date:!1,decodeURI:!1,decodeURIComponent:!1,encodeURI:!1,encodeURIComponent:!1,Error:!1,eval:!1,EvalError:!1,Function:!1,hasOwnProperty:!1,isFinite:!1,isNaN:!1,JSON:!1,Math:!1,Number:!1,Object:!1,parseInt:!1,parseFloat:!1,RangeError:!1,ReferenceError:!1,RegExp:!1,String:!1,SyntaxError:!1,TypeError:!1,URIError:!1},n.newEcmaIdentifiers={Set:!1,Map:!1,WeakMap:!1,WeakSet:!1,Proxy:!1,Promise:!1},n.browser={Audio:!1,Blob:!1,addEventListener:!1,applicationCache:!1,atob:!1,blur:!1,btoa:!1,CanvasGradient:!1,CanvasPattern:!1,CanvasRenderingContext2D:!1,clearInterval:!1,clearTimeout:!1,close:!1,closed:!1,CustomEvent:!1,DOMParser:!1,defaultStatus:!1,document:!1,Element:!1,ElementTimeControl:!1,event:!1,FileReader:!1,FormData:!1,focus:!1,frames:!1,getComputedStyle:!1,HTMLElement:!1,HTMLAnchorElement:!1,HTMLBaseElement:!1,HTMLBlockquoteElement:!1,HTMLBodyElement:!1,HTMLBRElement:!1,HTMLButtonElement:!1,HTMLCanvasElement:!1,HTMLDirectoryElement:!1,HTMLDivElement:!1,HTMLDListElement:!1,HTMLFieldSetElement:!1,HTMLFontElement:!1,HTMLFormElement:!1,HTMLFrameElement:!1,HTMLFrameSetElement:!1,HTMLHeadElement:!1,HTMLHeadingElement:!1,HTMLHRElement:!1,HTMLHtmlElement:!1,HTMLIFrameElement:!1,HTMLImageElement:!1,HTMLInputElement:!1,HTMLIsIndexElement:!1,HTMLLabelElement:!1,HTMLLayerElement:!1,HTMLLegendElement:!1,HTMLLIElement:!1,HTMLLinkElement:!1,HTMLMapElement:!1,HTMLMenuElement:!1,HTMLMetaElement:!1,HTMLModElement:!1,HTMLObjectElement:!1,HTMLOListElement:!1,HTMLOptGroupElement:!1,HTMLOptionElement:!1,HTMLParagraphElement:!1,HTMLParamElement:!1,HTMLPreElement:!1,HTMLQuoteElement:!1,HTMLScriptElement:!1,HTMLSelectElement:!1,HTMLStyleElement:!1,HTMLTableCaptionElement:!1,HTMLTableCellElement:!1,HTMLTableColElement:!1,HTMLTableElement:!1,HTMLTableRowElement:!1,HTMLTableSectionElement:!1,HTMLTextAreaElement:!1,HTMLTitleElement:!1,HTMLUListElement:!1,HTMLVideoElement:!1,history:!1,Image:!1,length:!1,localStorage:!1,location:!1,matchMedia:!1,MessageChannel:!1,MessageEvent:!1,MessagePort:!1,MouseEvent:!1,moveBy:!1,moveTo:!1,MutationObserver:!1,name:!1,Node:!1,NodeFilter:!1,NodeList:!1,navigator:!1,onbeforeunload:!0,onblur:!0,onerror:!0,onfocus:!0,onload:!0,onresize:!0,onunload:!0,open:!1,openDatabase:!1,opener:!1,Option:!1,parent:!1,print:!1,removeEventListener:!1,resizeBy:!1,resizeTo:!1,screen:!1,scroll:!1,scrollBy:!1,scrollTo:!1,sessionStorage:!1,setInterval:!1,setTimeout:!1,SharedWorker:!1,status:!1,SVGAElement:!1,SVGAltGlyphDefElement:!1,SVGAltGlyphElement:!1,SVGAltGlyphItemElement:!1,SVGAngle:!1,SVGAnimateColorElement:!1,SVGAnimateElement:!1,SVGAnimateMotionElement:!1,SVGAnimateTransformElement:!1,SVGAnimatedAngle:!1,SVGAnimatedBoolean:!1,SVGAnimatedEnumeration:!1,SVGAnimatedInteger:!1,SVGAnimatedLength:!1,SVGAnimatedLengthList:!1,SVGAnimatedNumber:!1,SVGAnimatedNumberList:!1,SVGAnimatedPathData:!1,SVGAnimatedPoints:!1,SVGAnimatedPreserveAspectRatio:!1,SVGAnimatedRect:!1,SVGAnimatedString:!1,SVGAnimatedTransformList:!1,SVGAnimationElement:!1,SVGCSSRule:!1,SVGCircleElement:!1,SVGClipPathElement:!1,SVGColor:!1,SVGColorProfileElement:!1,SVGColorProfileRule:!1,SVGComponentTransferFunctionElement:!1,SVGCursorElement:!1,SVGDefsElement:!1,SVGDescElement:!1,SVGDocument:!1,SVGElement:!1,SVGElementInstance:!1,SVGElementInstanceList:!1,SVGEllipseElement:!1,SVGExternalResourcesRequired:!1,SVGFEBlendElement:!1,SVGFEColorMatrixElement:!1,SVGFEComponentTransferElement:!1,SVGFECompositeElement:!1,SVGFEConvolveMatrixElement:!1,SVGFEDiffuseLightingElement:!1,SVGFEDisplacementMapElement:!1,SVGFEDistantLightElement:!1,SVGFEFloodElement:!1,SVGFEFuncAElement:!1,SVGFEFuncBElement:!1,SVGFEFuncGElement:!1,SVGFEFuncRElement:!1,SVGFEGaussianBlurElement:!1,SVGFEImageElement:!1,SVGFEMergeElement:!1,SVGFEMergeNodeElement:!1,SVGFEMorphologyElement:!1,SVGFEOffsetElement:!1,SVGFEPointLightElement:!1,SVGFESpecularLightingElement:!1,SVGFESpotLightElement:!1,SVGFETileElement:!1,SVGFETurbulenceElement:!1,SVGFilterElement:!1,SVGFilterPrimitiveStandardAttributes:!1,SVGFitToViewBox:!1,SVGFontElement:!1,SVGFontFaceElement:!1,SVGFontFaceFormatElement:!1,SVGFontFaceNameElement:!1,SVGFontFaceSrcElement:!1,SVGFontFaceUriElement:!1,SVGForeignObjectElement:!1,SVGGElement:!1,SVGGlyphElement:!1,SVGGlyphRefElement:!1,SVGGradientElement:!1,SVGHKernElement:!1,SVGICCColor:!1,SVGImageElement:!1,SVGLangSpace:!1,SVGLength:!1,SVGLengthList:!1,SVGLineElement:!1,SVGLinearGradientElement:!1,SVGLocatable:!1,SVGMPathElement:!1,SVGMarkerElement:!1,SVGMaskElement:!1,SVGMatrix:!1,SVGMetadataElement:!1,SVGMissingGlyphElement:!1,SVGNumber:!1,SVGNumberList:!1,SVGPaint:!1,SVGPathElement:!1,SVGPathSeg:!1,SVGPathSegArcAbs:!1,SVGPathSegArcRel:!1,SVGPathSegClosePath:!1,SVGPathSegCurvetoCubicAbs:!1,SVGPathSegCurvetoCubicRel:!1,SVGPathSegCurvetoCubicSmoothAbs:!1,SVGPathSegCurvetoCubicSmoothRel:!1,SVGPathSegCurvetoQuadraticAbs:!1,SVGPathSegCurvetoQuadraticRel:!1,SVGPathSegCurvetoQuadraticSmoothAbs:!1,SVGPathSegCurvetoQuadraticSmoothRel:!1,SVGPathSegLinetoAbs:!1,SVGPathSegLinetoHorizontalAbs:!1,SVGPathSegLinetoHorizontalRel:!1,SVGPathSegLinetoRel:!1,SVGPathSegLinetoVerticalAbs:!1,SVGPathSegLinetoVerticalRel:!1,SVGPathSegList:!1,SVGPathSegMovetoAbs:!1,SVGPathSegMovetoRel:!1,SVGPatternElement:!1,SVGPoint:!1,SVGPointList:!1,SVGPolygonElement:!1,SVGPolylineElement:!1,SVGPreserveAspectRatio:!1,SVGRadialGradientElement:!1,SVGRect:!1,SVGRectElement:!1,SVGRenderingIntent:!1,SVGSVGElement:!1,SVGScriptElement:!1,SVGSetElement:!1,SVGStopElement:!1,SVGStringList:!1,SVGStylable:!1,SVGStyleElement:!1,SVGSwitchElement:!1,SVGSymbolElement:!1,SVGTRefElement:!1,SVGTSpanElement:!1,SVGTests:!1,SVGTextContentElement:!1,SVGTextElement:!1,SVGTextPathElement:!1,SVGTextPositioningElement:!1,SVGTitleElement:!1,SVGTransform:!1,SVGTransformList:!1,SVGTransformable:!1,SVGURIReference:!1,SVGUnitTypes:!1,SVGUseElement:!1,SVGVKernElement:!1,SVGViewElement:!1,SVGViewSpec:!1,SVGZoomAndPan:!1,TimeEvent:!1,top:!1,URL:!1,WebSocket:!1,window:!1,Worker:!1,XMLHttpRequest:!1,XMLSerializer:!1,XPathEvaluator:!1,XPathException:!1,XPathExpression:!1,XPathNamespace:!1,XPathNSResolver:!1,XPathResult:!1},n.devel={alert:!1,confirm:!1,console:!1,Debug:!1,opera:!1,prompt:!1},n.worker={importScripts:!0,postMessage:!0,self:!0},n.nonstandard={escape:!1,unescape:!1},n.couch={require:!1,respond:!1,getRow:!1,emit:!1,send:!1,start:!1,sum:!1,log:!1,exports:!1,module:!1,provides:!1},n.node={__filename:!1,__dirname:!1,GLOBAL:!1,global:!1,module:!1,require:!1,Buffer:!0,console:!0,exports:!0,process:!0,setTimeout:!0,clearTimeout:!0,setInterval:!0,clearInterval:!0,setImmediate:!0,clearImmediate:!0},n.phantom={phantom:!0,require:!0,WebPage:!0,console:!0,exports:!0},n.qunit={asyncTest:!1,deepEqual:!1,equal:!1,expect:!1,module:!1,notDeepEqual:!1,notEqual:!1,notPropEqual:!1,notStrictEqual:!1,ok:!1,propEqual:!1,QUnit:!1,raises:!1,start:!1,stop:!1,strictEqual:!1,test:!1,"throws":!1},n.rhino={defineClass:!1,deserialize:!1,gc:!1,help:!1,importClass:!1,importPackage:!1,java:!1,load:!1,loadClass:!1,Packages:!1,print:!1,quit:!1,readFile:!1,readUrl:!1,runCommand:!1,seal:!1,serialize:!1,spawn:!1,sync:!1,toint32:!1,version:!1},n.shelljs={target:!1,echo:!1,exit:!1,cd:!1,pwd:!1,ls:!1,find:!1,cp:!1,rm:!1,mv:!1,mkdir:!1,test:!1,cat:!1,sed:!1,grep:!1,which:!1,dirs:!1,pushd:!1,popd:!1,env:!1,exec:!1,chmod:!1,config:!1,error:!1,tempdir:!1},n.typed={ArrayBuffer:!1,ArrayBufferView:!1,DataView:!1,Float32Array:!1,Float64Array:!1,Int16Array:!1,Int32Array:!1,Int8Array:!1,Uint16Array:!1,Uint32Array:!1,Uint8Array:!1,Uint8ClampedArray:!1},n.wsh={ActiveXObject:!0,Enumerator:!0,GetObject:!0,ScriptEngine:!0,ScriptEngineBuildVersion:!0,ScriptEngineMajorVersion:!0,ScriptEngineMinorVersion:!0,VBArray:!0,WSH:!0,WScript:!0,XDomainRequest:!0},n.dojo={dojo:!1,dijit:!1,dojox:!1,define:!1,require:!1},n.jquery={$:!1,jQuery:!1},n.mootools={$:!1,$$:!1,Asset:!1,Browser:!1,Chain:!1,Class:!1,Color:!1,Cookie:!1,Core:!1,Document:!1,DomReady:!1,DOMEvent:!1,DOMReady:!1,Drag:!1,Element:!1,Elements:!1,Event:!1,Events:!1,Fx:!1,Group:!1,Hash:!1,HtmlTable:!1,IFrame:!1,IframeShim:!1,InputValidator:!1,instanceOf:!1,Keyboard:!1,Locale:!1,Mask:!1,MooTools:!1,Native:!1,Options:!1,OverText:!1,Request:!1,Scroller:!1,Slick:!1,Slider:!1,Sortables:!1,Spinner:!1,Swiff:!1,Tips:!1,Type:!1,typeOf:!1,URI:!1,Window:!1},n.prototypejs={$:!1,$$:!1,$A:!1,$F:!1,$H:!1,$R:!1,$break:!1,$continue:!1,$w:!1,Abstract:!1,Ajax:!1,Class:!1,Enumerable:!1,Element:!1,Event:!1,Field:!1,Form:!1,Hash:!1,Insertion:!1,ObjectRange:!1,PeriodicalExecuter:!1,Position:!1,Prototype:!1,Selector:!1,Template:!1,Toggle:!1,Try:!1,Autocompleter:!1,Builder:!1,Control:!1,Draggable:!1,Draggables:!1,Droppables:!1,Effect:!1,Sortable:!1,SortableObserver:!1,Sound:!1,Scriptaculous:!1},n.yui={YUI:!1,Y:!1,YUI_config:!1},n.mocha={describe:!1,it:!1,before:!1,after:!1,beforeEach:!1,afterEach:!1,suite:!1,test:!1,setup:!1,teardown:!1},n.jasmine={jasmine:!1,describe:!1,it:!1,xit:!1,beforeEach:!1,afterEach:!1,setFixtures:!1,loadFixtures:!1,spyOn:!1,expect:!1,runs:!1,waitsFor:!1,waits:!1}},{}],10:[function(e,t,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||undefined}function i(e){return typeof e=="function"}function s(e){return typeof e=="number"}function o(e){return typeof e=="object"&&e!==null}function u(e){return e===void 0}t.exports=r,r.EventEmitter=r,r.prototype._events=undefined,r.prototype._maxListeners=undefined,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(e){if(!s(e)||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},r.prototype.emit=function(e){var t,n,r,s,a,f;this._events||(this._events={});if(e==="error")if(!this._events.error||o(this._events.error)&&!this._events.error.length)throw t=arguments[1],t instanceof Error?t:TypeError('Uncaught, unspecified "error" event.');n=this._events[e];if(u(n))return!1;if(i(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];n.apply(this,s)}else if(o(n)){r=arguments.length,s=new Array(r-1);for(a=1;a<r;a++)s[a-1]=arguments[a];f=n.slice(),r=f.length;for(a=0;a<r;a++)f[a].apply(this,s)}return!0},r.prototype.addListener=function(e,t){var n;if(!i(t))throw TypeError("listener must be a function");this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t),this._events[e]?o(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t;if(o(this._events[e])&&!this._events[e].warned){var n;u(this._maxListeners)?n=r.defaultMaxListeners:n=this._maxListeners,n&&n>0&&this._events[e].length>n&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),console.trace())}return this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(e,t){function r(){this.removeListener(e,r),n||(n=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var n=!1;return r.listener=t,this.on(e,r),this},r.prototype.removeListener=function(e,t){var n,r,s,u;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;n=this._events[e],s=n.length,r=-1;if(n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(u=s;u-->0;)if(n[u]===t||n[u].listener&&n[u].listener===t){r=u;break}if(r<0)return this;n.length===1?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},r.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return arguments.length===0?this._events={}:this._events[e]&&delete this._events[e],this;if(arguments.length===0){for(t in this._events){if(t==="removeListener")continue;this.removeAllListeners(t)}return this.removeAllListeners("removeListener"),this._events={},this}n=this._events[e];if(i(n))this.removeListener(e,n);else while(n.length)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},r.prototype.listeners=function(e){var t;return!this._events||!this._events[e]?t=[]:i(this._events[e])?t=[this._events[e]]:t=this._events[e].slice(),t},r.listenerCount=function(e,t){var n;return!e._events||!e._events[t]?n=0:i(e._events[t])?n=1:n=e._events[t].length,n}},{}]},{},[3])(3)}),ace.define("ace/mode/javascript_worker",["require","exports","module","ace/lib/oop","ace/worker/mirror","ace/mode/javascript/jshint"],function(require,exports,module){"use strict";function startRegex(e){return RegExp("^("+e.join("|")+")")}var oop=require("../lib/oop"),Mirror=require("../worker/mirror").Mirror,lint=require("./javascript/jshint").JSHINT,disabledWarningsRe=startRegex(["Bad for in variable '(.+)'.",'Missing "use strict"']),errorsRe=startRegex(["Unexpected","Expected ","Confusing (plus|minus)","\\{a\\} unterminated regular expression","Unclosed ","Unmatched ","Unbegun comment","Bad invocation","Missing space after","Missing operator at"]),infoRe=startRegex(["Expected an assignment","Bad escapement of EOL","Unexpected comma","Unexpected space","Missing radix parameter.","A leading decimal point can","\\['{a}'\\] is better written in dot notation.","'{a}' used out of scope"]),JavaScriptWorker=exports.JavaScriptWorker=function(e){Mirror.call(this,e),this.setTimeout(500),this.setOptions()};oop.inherits(JavaScriptWorker,Mirror),function(){this.setOptions=function(e){this.options=e||{esnext:!0,moz:!0,devel:!0,browser:!0,node:!0,laxcomma:!0,laxbreak:!0,lastsemic:!0,onevar:!1,passfail:!1,maxerr:100,expr:!0,multistr:!0,globalstrict:!0},this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.changeOptions=function(e){oop.mixin(this.options,e),this.doc.getValue()&&this.deferredUpdate.schedule(100)},this.isValidJS=function(str){try{eval("throw 0;"+str)}catch(e){if(e===0)return!0}return!1},this.onUpdate=function(){var e=this.doc.getValue();e=e.replace(/^#!.*\n/,"\n");if(!e){this.sender.emit("jslint",[]);return}var t=[],n=this.isValidJS(e)?"warning":"error";lint(e,this.options);var r=lint.errors,i=!1;for(var s=0;s<r.length;s++){var o=r[s];if(!o)continue;var u=o.raw,a="warning";if(u=="Missing semicolon."){var f=o.evidence.substr(o.character);f=f.charAt(f.search(/\S/)),n=="error"&&f&&/[\w\d{(['"]/.test(f)?(o.reason='Missing ";" before statement',a="error"):a="info"}else{if(disabledWarningsRe.test(u))continue;infoRe.test(u)?a="info":errorsRe.test(u)?(i=!0,a=n):u=="'{a}' is not defined."?a="warning":u=="'{a}' is defined but never used."&&(a="info")}t.push({row:o.line-1,column:o.character-1,text:o.reason,type:a,raw:u}),i}this.sender.emit("jslint",t)}}.call(JavaScriptWorker.prototype)}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _="	\n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/worker-json.js b/dist/assets/js/vendor/ace-nc/worker-json.js
            new file mode 100644
            index 0000000000..58004d590b
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/worker-json.js
            @@ -0,0 +1 @@
            +"no use strict";(function(e){if(typeof e.window!="undefined"&&e.document)return;e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console,e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){console.error("Worker "+(i?i.stack:e))},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(t,n){n||(n=t,t=null);if(!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;var i=n.split("/");if(!e.require.tlns)return console.log("unable to load "+n);i[0]=e.require.tlns[i[0]]||i[0];var s=i.join("/")+".js";return e.require.id=n,importScripts(s),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id),n.length||(n=["require","exports","module"]);if(t.indexOf("text!")===0)return;var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},e.initBaseUrls=function(t){require.tlns=t},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var i=r.data;if(i.command){if(!t[i.command])throw new Error("Unknown command:"+i.command);t[i.command].apply(t,i.args)}else if(i.init){initBaseUrls(i.tlns),require("ace/lib/es5-shim"),n=e.sender=initSender();var s=require(i.module)[i.classname];t=e.main=new s(n)}else i.event&&n&&n._signal(i.event,i.data)}})(this),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action==="insertText")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action==="insertLines"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action==="removeText"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action=="removeLines"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[""]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},"\n"+t.join("\n")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._signal("change",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._signal("change",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._signal("change",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._signal("change",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this._insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]=="object"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/worker/mirror",["require","exports","module","ace/document","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../document").Document,i=e("../lib/lang"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=i.delayedCall(this.onUpdate.bind(this)),s=this;e.on("change",function(e){t.applyDeltas(e.data);if(s.$timeout)return n.schedule(s.$timeout);s.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(s.prototype)}),ace.define("ace/mode/json/json_parse",["require","exports","module"],function(e,t,n){"use strict";var r,i,s={'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:"\n",r:"\r",t:"	"},o,u=function(e){throw{name:"SyntaxError",message:e,at:r,text:o}},a=function(e){return e&&e!==i&&u("Expected '"+e+"' instead of '"+i+"'"),i=o.charAt(r),r+=1,i},f=function(){var e,t="";i==="-"&&(t="-",a("-"));while(i>="0"&&i<="9")t+=i,a();if(i==="."){t+=".";while(a()&&i>="0"&&i<="9")t+=i}if(i==="e"||i==="E"){t+=i,a();if(i==="-"||i==="+")t+=i,a();while(i>="0"&&i<="9")t+=i,a()}e=+t;if(!isNaN(e))return e;u("Bad number")},l=function(){var e,t,n="",r;if(i==='"')while(a()){if(i==='"')return a(),n;if(i==="\\"){a();if(i==="u"){r=0;for(t=0;t<4;t+=1){e=parseInt(a(),16);if(!isFinite(e))break;r=r*16+e}n+=String.fromCharCode(r)}else{if(typeof s[i]!="string")break;n+=s[i]}}else n+=i}u("Bad string")},c=function(){while(i&&i<=" ")a()},h=function(){switch(i){case"t":return a("t"),a("r"),a("u"),a("e"),!0;case"f":return a("f"),a("a"),a("l"),a("s"),a("e"),!1;case"n":return a("n"),a("u"),a("l"),a("l"),null}u("Unexpected '"+i+"'")},p,d=function(){var e=[];if(i==="["){a("["),c();if(i==="]")return a("]"),e;while(i){e.push(p()),c();if(i==="]")return a("]"),e;a(","),c()}}u("Bad array")},v=function(){var e,t={};if(i==="{"){a("{"),c();if(i==="}")return a("}"),t;while(i){e=l(),c(),a(":"),Object.hasOwnProperty.call(t,e)&&u('Duplicate key "'+e+'"'),t[e]=p(),c();if(i==="}")return a("}"),t;a(","),c()}}u("Bad object")};return p=function(){c();switch(i){case"{":return v();case"[":return d();case'"':return l();case"-":return f();default:return i>="0"&&i<="9"?f():h()}},function(e,t){var n;return o=e,r=0,i=" ",n=p(),c(),i&&u("Syntax error"),typeof t=="function"?function s(e,n){var r,i,o=e[n];if(o&&typeof o=="object")for(r in o)Object.hasOwnProperty.call(o,r)&&(i=s(o,r),i!==undefined?o[r]=i:delete o[r]);return t.call(e,n,o)}({"":n},""):n}}),ace.define("ace/mode/json_worker",["require","exports","module","ace/lib/oop","ace/worker/mirror","ace/mode/json/json_parse"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../worker/mirror").Mirror,s=e("./json/json_parse"),o=t.JsonWorker=function(e){i.call(this,e),this.setTimeout(200)};r.inherits(o,i),function(){this.onUpdate=function(){var e=this.doc.getValue();try{var t=s(e)}catch(n){var r=this.doc.indexToPosition(n.at-1);this.sender.emit("error",{row:r.row,column:r.column,text:n.message,type:"error"});return}this.sender.emit("ok")}}.call(o.prototype)}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _="	\n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/worker-lua.js b/dist/assets/js/vendor/ace-nc/worker-lua.js
            new file mode 100644
            index 0000000000..384acef523
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/worker-lua.js
            @@ -0,0 +1 @@
            +"no use strict";(function(e){if(typeof e.window!="undefined"&&e.document)return;e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console,e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){console.error("Worker "+(i?i.stack:e))},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(t,n){n||(n=t,t=null);if(!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;var i=n.split("/");if(!e.require.tlns)return console.log("unable to load "+n);i[0]=e.require.tlns[i[0]]||i[0];var s=i.join("/")+".js";return e.require.id=n,importScripts(s),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id),n.length||(n=["require","exports","module"]);if(t.indexOf("text!")===0)return;var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},e.initBaseUrls=function(t){require.tlns=t},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var i=r.data;if(i.command){if(!t[i.command])throw new Error("Unknown command:"+i.command);t[i.command].apply(t,i.args)}else if(i.init){initBaseUrls(i.tlns),require("ace/lib/es5-shim"),n=e.sender=initSender();var s=require(i.module)[i.classname];t=e.main=new s(n)}else i.event&&n&&n._signal(i.event,i.data)}})(this),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action==="insertText")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action==="insertLines"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action==="removeText"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action=="removeLines"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[""]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},"\n"+t.join("\n")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._signal("change",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._signal("change",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._signal("change",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._signal("change",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this._insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]=="object"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/worker/mirror",["require","exports","module","ace/document","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../document").Document,i=e("../lib/lang"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=i.delayedCall(this.onUpdate.bind(this)),s=this;e.on("change",function(e){t.applyDeltas(e.data);if(s.$timeout)return n.schedule(s.$timeout);s.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(s.prototype)}),ace.define("ace/mode/lua/luaparse",["require","exports","module"],function(e,t,n){(function(e,n,r){r(t)})(this,"luaparse",function(e){"use strict";function m(e){if(mt){var t=vt.pop();t.complete(),n.locations&&(e.loc=t.loc),n.ranges&&(e.range=t.range)}return e}function w(e,t,n){for(var r=0,i=e.length;r<i;r++)if(e[r][t]===n)return r;return-1}function E(e){var t=g.call(arguments,1);return e=e.replace(/%(\d)/g,function(e,n){return""+t[n-1]||""}),e}function S(){var e=g.call(arguments),t={},n,r;for(var i=0,s=e.length;i<s;i++){n=e[i];for(r in n)n.hasOwnProperty(r)&&(t[r]=n[r])}return t}function x(e){var t=E.apply(null,g.call(arguments,1)),n,r;throw"undefined"!=typeof e.line?(r=e.range[0]-e.lineStart,n=new SyntaxError(E("[%1:%2] %3",e.line,r,t)),n.line=e.line,n.index=e.range[0],n.column=r):(r=C-D+1,n=new SyntaxError(E("[%1:%2] %3",_,r,t)),n.index=C,n.line=_,n.column=r),n}function T(e,t){x(t,d.expectedToken,e,t.value)}function N(e,t){"undefined"==typeof t&&(t=A.value);if("undefined"!=typeof e.type){var n;switch(e.type){case o:n="string";break;case u:n="keyword";break;case a:n="identifier";break;case f:n="number";break;case l:n="symbol";break;case c:n="boolean";break;case h:return x(e,d.unexpected,"symbol","nil",t)}return x(e,d.unexpected,n,e.value,t)}return x(e,d.unexpected,"symbol",e,t)}function P(){H();while(45===t.charCodeAt(C)&&45===t.charCodeAt(C+1))X(),H();if(C>=r)return{type:s,value:"<eof>",line:_,lineStart:D,range:[C,C]};var e=t.charCodeAt(C),n=t.charCodeAt(C+1);M=C;if(et(e))return B();switch(e){case 39:case 34:return I();case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return R();case 46:if(Y(n))return R();if(46===n)return 46===t.charCodeAt(C+2)?F():j("..");return j(".");case 61:if(61===n)return j("==");return j("=");case 62:if(61===n)return j(">=");return j(">");case 60:if(61===n)return j("<=");return j("<");case 126:if(61===n)return j("~=");return x({},d.expected,"=","~");case 58:if(58===n)return j("::");return j(":");case 91:if(91===n||61===n)return q();return j("[");case 42:case 47:case 94:case 37:case 44:case 123:case 125:case 93:case 40:case 41:case 59:case 35:case 45:case 43:return j(t.charAt(C))}return N(t.charAt(C))}function H(){while(C<r){var e=t.charCodeAt(C);if(Q(e))C++;else{if(!G(e))break;_++,D=++C}}}function B(){var e,n;while(tt(t.charCodeAt(++C)));return e=t.slice(M,C),nt(e)?n=u:"true"===e||"false"===e?(n=c,e="true"===e):"nil"===e?(n=h,e=null):n=a,{type:n,value:e,line:_,lineStart:D,range:[M,C]}}function j(e){return C+=e.length,{type:l,value:e,line:_,lineStart:D,range:[M,C]}}function F(){return C+=3,{type:p,value:"...",line:_,lineStart:D,range:[M,C]}}function I(){var e=t.charCodeAt(C++),n=C,i="",s;while(C<r){s=t.charCodeAt(C++);if(e===s)break;if(92===s)i+=t.slice(n,C-1)+W(),n=C;else if(C>=r||G(s))i+=t.slice(n,C-1),x({},d.unfinishedString,i+String.fromCharCode(s))}return i+=t.slice(n,C-1),{type:o,value:i,line:_,lineStart:D,range:[M,C]}}function q(){var e=V();return!1===e&&x(k,d.expected,"[",k.value),{type:o,value:e,line:_,lineStart:D,range:[M,C]}}function R(){var e=t.charAt(C),n=t.charAt(C+1),r="0"===e&&"xX".indexOf(n||null)>=0?U():z();return{type:f,value:r,line:_,lineStart:D,range:[M,C]}}function U(){var e=0,n=1,r=1,i,s,o,u;u=C+=2,Z(t.charCodeAt(C))||x({},d.malformedNumber,t.slice(M,C));while(Z(t.charCodeAt(C)))C++;i=parseInt(t.slice(u,C),16);if("."===t.charAt(C)){s=++C;while(Z(t.charCodeAt(C)))C++;e=t.slice(s,C),e=s===C?0:parseInt(e,16)/Math.pow(16,C-s)}if("pP".indexOf(t.charAt(C)||null)>=0){C++,"+-".indexOf(t.charAt(C)||null)>=0&&(r="+"===t.charAt(C++)?1:-1),o=C,Y(t.charCodeAt(C))||x({},d.malformedNumber,t.slice(M,C));while(Y(t.charCodeAt(C)))C++;n=t.slice(o,C),n=Math.pow(2,n*r)}return(i+e)*n}function z(){while(Y(t.charCodeAt(C)))C++;if("."===t.charAt(C)){C++;while(Y(t.charCodeAt(C)))C++}if("eE".indexOf(t.charAt(C)||null)>=0){C++,"+-".indexOf(t.charAt(C)||null)>=0&&C++,Y(t.charCodeAt(C))||x({},d.malformedNumber,t.slice(M,C));while(Y(t.charCodeAt(C)))C++}return parseFloat(t.slice(M,C))}function W(){var e=C;switch(t.charAt(C)){case"n":return C++,"\n";case"r":return C++,"\r";case"t":return C++,"	";case"v":return C++,"";case"b":return C++,"\b";case"f":return C++,"\f";case"z":return C++,H(),"";case"x":if(Z(t.charCodeAt(C+1))&&Z(t.charCodeAt(C+2)))return C+=3,"\\"+t.slice(e,C);return"\\"+t.charAt(C++);default:if(Y(t.charCodeAt(C))){while(Y(t.charCodeAt(++C)));return"\\"+t.slice(e,C)}return t.charAt(C++)}}function X(){M=C,C+=2;var e=t.charAt(C),i="",s=!1,o=C,u=D,a=_;"["===e&&(i=V(),!1===i?i=e:s=!0);if(!s){while(C<r){if(G(t.charCodeAt(C)))break;C++}n.comments&&(i=t.slice(o,C))}if(n.comments){var f=v.comment(i,t.slice(M,C));n.locations&&(f.loc={start:{line:a,column:M-u},end:{line:_,column:C-D}}),n.ranges&&(f.range=[M,C]),O.push(f)}}function V(){var e=0,n="",i=!1,s,o;C++;while("="===t.charAt(C+e))e++;if("["!==t.charAt(C+e))return!1;C+=e+1,G(t.charCodeAt(C))&&(_++,D=C++),o=C;while(C<r){s=t.charAt(C++),G(s.charCodeAt(0))&&(_++,D=C);if("]"===s){i=!0;for(var u=0;u<e;u++)"="!==t.charAt(C+u)&&(i=!1);"]"!==t.charAt(C+e)&&(i=!1)}if(i)break}return n+=t.slice(o,C-1),C+=e+1,n}function $(){L=k,k=A,A=P()}function J(e){return e===k.value?($(),!0):!1}function K(e){e===k.value?$():x(k,d.expected,e,k.value)}function Q(e){return 9===e||32===e||11===e||12===e}function G(e){return 10===e||13===e}function Y(e){return e>=48&&e<=57}function Z(e){return e>=48&&e<=57||e>=97&&e<=102||e>=65&&e<=70}function et(e){return e>=65&&e<=90||e>=97&&e<=122||95===e}function tt(e){return e>=65&&e<=90||e>=97&&e<=122||95===e||e>=48&&e<=57}function nt(e){switch(e.length){case 2:return"do"===e||"if"===e||"in"===e||"or"===e;case 3:return"and"===e||"end"===e||"for"===e||"not"===e;case 4:return"else"===e||"goto"===e||"then"===e;case 5:return"break"===e||"local"===e||"until"===e||"while"===e;case 6:return"elseif"===e||"repeat"===e||"return"===e;case 8:return"function"===e}return!1}function rt(e){return l===e.type?"#-".indexOf(e.value)>=0:u===e.type?"not"===e.value:!1}function it(e){switch(e.type){case"CallExpression":case"TableCallExpression":case"StringCallExpression":return!0}return!1}function st(e){if(s===e.type)return!0;if(u!==e.type)return!1;switch(e.value){case"else":case"elseif":case"end":case"until":return!0;default:return!1}}function ft(){ot.push(Array.apply(null,ot[ut++]))}function lt(){ot.pop(),ut--}function ct(e){if(-1!==b(ot[ut],e))return;ot[ut].push(e)}function ht(e){ct(e.name),pt(e,!0)}function pt(e,t){!t&&-1===w(at,"name",e.name)&&at.push(e),e.isLocal=t}function dt(e){return-1!==b(ot[ut],e)}function gt(){return new yt(k)}function yt(e){n.locations&&(this.loc={start:{line:e.line,column:e.range[0]-e.lineStart},end:{line:0,column:0}}),n.ranges&&(this.range=[e.range[0],0])}function bt(){mt&&vt.push(gt())}function wt(e){mt&&vt.push(e)}function Et(){$(),bt();var e=St();return s!==k.type&&N(k),mt&&!e.length&&(L=k),m(v.chunk(e))}function St(e){var t=[],r;n.scope&&ft();while(!st(k)){if("return"===k.value){t.push(xt());break}r=xt(),r&&t.push(r)}return n.scope&&lt(),t}function xt(){bt();if(u===k.type)switch(k.value){case"local":return $(),Dt();case"if":return $(),Mt();case"return":return $(),Ot();case"function":$();var e=jt();return Bt(e);case"while":return $(),Lt();case"for":return $(),_t();case"repeat":return $(),At();case"break":return $(),Nt();case"do":return $(),kt();case"goto":return $(),Ct()}if(l===k.type&&J("::"))return Tt();mt&&vt.pop();if(J(";"))return;return Pt()}function Tt(){var e=k.value,t=Ht();return n.scope&&(ct("::"+e+"::"),pt(t,!0)),K("::"),m(v.labelStatement(t))}function Nt(){return m(v.breakStatement())}function Ct(){var e=k.value,t=Ht();return n.scope&&(t.isLabel=dt("::"+e+"::")),m(v.gotoStatement(t))}function kt(){var e=St();return K("end"),m(v.doStatement(e))}function Lt(){var e=qt();K("do");var t=St();return K("end"),m(v.whileStatement(e,t))}function At(){var e=St();K("until");var t=qt();return m(v.repeatStatement(t,e))}function Ot(){var e=[];if("end"!==k.value){var t=It();null!=t&&e.push(t);while(J(","))t=qt(),e.push(t);J(";")}return m(v.returnStatement(e))}function Mt(){var e=[],t,n,r;mt&&(r=vt[vt.length-1],vt.push(r)),t=qt(),K("then"),n=St(),e.push(m(v.ifClause(t,n))),mt&&(r=gt());while(J("elseif"))wt(r),t=qt(),K("then"),n=St(),e.push(m(v.elseifClause(t,n))),mt&&(r=gt());return J("else")&&(mt&&(r=new yt(L),vt.push(r)),n=St(),e.push(m(v.elseClause(n)))),K("end"),m(v.ifStatement(e))}function _t(){var e=Ht(),t;n.scope&&ht(e);if(J("=")){var r=qt();K(",");var i=qt(),s=J(",")?qt():null;return K("do"),t=St(),K("end"),m(v.forNumericStatement(e,r,i,s,t))}var o=[e];while(J(","))e=Ht(),n.scope&&ht(e),o.push(e);K("in");var u=[];do{var a=qt();u.push(a)}while(J(","));return K("do"),t=St(),K("end"),m(v.forGenericStatement(o,u,t))}function Dt(){var e;if(a===k.type){var t=[],r=[];do e=Ht(),t.push(e);while(J(","));if(J("="))do{var i=qt();r.push(i)}while(J(","));if(n.scope)for(var s=0,o=t.length;s<o;s++)ht(t[s]);return m(v.localStatement(t,r))}if(J("function"))return e=Ht(),n.scope&&ht(e),Bt(e,!0);T("<name>",k)}function Pt(){var e=k,t,n;mt&&(n=gt()),t=zt();if(null==t)return N(k);if(",=".indexOf(k.value)>=0){var r=[t],i=[],s;while(J(","))s=zt(),null==s&&T("<expression>",k),r.push(s);K("=");do s=qt(),i.push(s);while(J(","));return wt(n),m(v.assignmentStatement(r,i))}return it(t)?(wt(n),m(v.callStatement(t))):N(e)}function Ht(){bt();var e=k.value;return a!==k.type&&T("<name>",k),$(),m(v.identifier(e))}function Bt(e,t){var r=[];K("(");if(!J(")"))for(;;)if(a===k.type){var i=Ht();n.scope&&ht(i),r.push(i);if(J(","))continue;if(J(")"))break}else{if(p===k.type){r.push(Xt()),K(")");break}T("<name> or '...'",k)}var s=St();return K("end"),t=t||!1,m(v.functionStatement(e,r,t,s))}function jt(){var e,t,r;mt&&(r=gt()),e=Ht(),n.scope&&pt(e,!1);while(J("."))wt(r),t=Ht(),n.scope&&pt(t,!1),e=m(v.memberExpression(e,".",t));return J(":")&&(wt(r),t=Ht(),n.scope&&pt(t,!1),e=m(v.memberExpression(e,":",t))),e}function Ft(){var e=[],t,n;for(;;){bt();if(l===k.type&&J("["))t=qt(),K("]"),K("="),n=qt(),e.push(m(v.tableKey(t,n)));else if(a===k.type)t=qt(),J("=")?(n=qt(),e.push(m(v.tableKeyString(t,n)))):e.push(m(v.tableValue(t)));else{if(null==(n=It())){vt.pop();break}e.push(m(v.tableValue(n)))}if(",;".indexOf(k.value)>=0){$();continue}if("}"===k.value)break}return K("}"),m(v.tableConstructorExpression(e))}function It(){var e=Ut(0);return e}function qt(){var e=It();if(null!=e)return e;T("<expression>",k)}function Rt(e){var t=e.charCodeAt(0),n=e.length;if(1===n)switch(t){case 94:return 10;case 42:case 47:case 37:return 7;case 43:case 45:return 6;case 60:case 62:return 3}else if(2===n)switch(t){case 46:return 5;case 60:case 62:case 61:case 126:return 3;case 111:return 1}else if(97===t&&"and"===e)return 2;return 0}function Ut(e){var t=k.value,n,r;mt&&(r=gt());if(rt(k)){bt(),$();var i=Ut(8);i==null&&T("<expression>",k),n=m(v.unaryExpression(t,i))}null==n&&(n=Xt(),null==n&&(n=zt()));if(null==n)return null;var s;for(;;){t=k.value,s=l===k.type||u===k.type?Rt(t):0;if(s===0||s<=e)break;("^"===t||".."===t)&&s--,$();var o=Ut(s);null==o&&T("<expression>",k),mt&&vt.push(r),n=m(v.binaryExpression(t,n,o))}return n}function zt(){var e,t,r,i;mt&&(r=gt());if(a===k.type)t=k.value,e=Ht(),n.scope&&pt(e,i=dt(t));else{if(!J("("))return null;e=qt(),K(")"),n.scope&&(i=e.isLocal)}var s,u;for(;;)if(l===k.type)switch(k.value){case"[":wt(r),$(),s=qt(),e=m(v.indexExpression(e,s)),K("]");break;case".":wt(r),$(),u=Ht(),n.scope&&pt(u,i),e=m(v.memberExpression(e,".",u));break;case":":wt(r),$(),u=Ht(),n.scope&&pt(u,i),e=m(v.memberExpression(e,":",u)),wt(r),e=Wt(e);break;case"(":case"{":wt(r),e=Wt(e);break;default:return e}else{if(o!==k.type)break;wt(r),e=Wt(e)}return e}function Wt(e){if(l===k.type)switch(k.value){case"(":$();var t=[],n=It();null!=n&&t.push(n);while(J(","))n=qt(),t.push(n);return K(")"),m(v.callExpression(e,t));case"{":bt(),$();var r=Ft();return m(v.tableCallExpression(e,r))}else if(o===k.type)return m(v.stringCallExpression(e,Xt()));T("function arguments",k)}function Xt(){var e=o|f|c|h|p,n=k.value,r=k.type,i;mt&&(i=gt());if(r&e){wt(i);var s=t.slice(k.range[0],k.range[1]);return $(),m(v.literal(r,n,s))}if(u===r&&"function"===n)return wt(i),$(),Bt(null);if(J("{"))return wt(i),Ft()}function Vt(s,o){return"undefined"==typeof o&&"object"==typeof s&&(o=s,s=undefined),o||(o={}),t=s||"",n=S(i,o),C=0,_=1,D=0,r=t.length,ot=[[]],ut=0,at=[],vt=[],n.comments&&(O=[]),n.wait?e:Jt()}function $t(n){return t+=String(n),r=t.length,e}function Jt(e){"undefined"!=typeof e&&$t(e),r=t.length,mt=n.locations||n.ranges,A=P();var i=Et();n.comments&&(i.comments=O),n.scope&&(i.globals=at);if(vt.length>0)throw new Error("Location tracking failed. This is most likely a bug in luaparse");return i}e.version="0.1.4";var t,n,r,i=e.defaultOptions={wait:!1,comments:!0,scope:!1,locations:!1,ranges:!1},s=1,o=2,u=4,a=8,f=16,l=32,c=64,h=128,p=256;e.tokenTypes={EOF:s,StringLiteral:o,Keyword:u,Identifier:a,NumericLiteral:f,Punctuator:l,BooleanLiteral:c,NilLiteral:h,VarargLiteral:p};var d=e.errors={unexpected:"Unexpected %1 '%2' near '%3'",expected:"'%1' expected near '%2'",expectedToken:"%1 expected near '%2'",unfinishedString:"unfinished string near '%1'",malformedNumber:"malformed number near '%1'"},v=e.ast={labelStatement:function(e){return{type:"LabelStatement",label:e}},breakStatement:function(){return{type:"BreakStatement"}},gotoStatement:function(e){return{type:"GotoStatement",label:e}},returnStatement:function(e){return{type:"ReturnStatement",arguments:e}},ifStatement:function(e){return{type:"IfStatement",clauses:e}},ifClause:function(e,t){return{type:"IfClause",condition:e,body:t}},elseifClause:function(e,t){return{type:"ElseifClause",condition:e,body:t}},elseClause:function(e){return{type:"ElseClause",body:e}},whileStatement:function(e,t){return{type:"WhileStatement",condition:e,body:t}},doStatement:function(e){return{type:"DoStatement",body:e}},repeatStatement:function(e,t){return{type:"RepeatStatement",condition:e,body:t}},localStatement:function(e,t){return{type:"LocalStatement",variables:e,init:t}},assignmentStatement:function(e,t){return{type:"AssignmentStatement",variables:e,init:t}},callStatement:function(e){return{type:"CallStatement",expression:e}},functionStatement:function(e,t,n,r){return{type:"FunctionDeclaration",identifier:e,isLocal:n,parameters:t,body:r}},forNumericStatement:function(e,t,n,r,i){return{type:"ForNumericStatement",variable:e,start:t,end:n,step:r,body:i}},forGenericStatement:function(e,t,n){return{type:"ForGenericStatement",variables:e,iterators:t,body:n}},chunk:function(e){return{type:"Chunk",body:e}},identifier:function(e){return{type:"Identifier",name:e}},literal:function(e,t,n){return e=e===o?"StringLiteral":e===f?"NumericLiteral":e===c?"BooleanLiteral":e===h?"NilLiteral":"VarargLiteral",{type:e,value:t,raw:n}},tableKey:function(e,t){return{type:"TableKey",key:e,value:t}},tableKeyString:function(e,t){return{type:"TableKeyString",key:e,value:t}},tableValue:function(e){return{type:"TableValue",value:e}},tableConstructorExpression:function(e){return{type:"TableConstructorExpression",fields:e}},binaryExpression:function(e,t,n){var r="and"===e||"or"===e?"LogicalExpression":"BinaryExpression";return{type:r,operator:e,left:t,right:n}},unaryExpression:function(e,t){return{type:"UnaryExpression",operator:e,argument:t}},memberExpression:function(e,t,n){return{type:"MemberExpression",indexer:t,identifier:n,base:e}},indexExpression:function(e,t){return{type:"IndexExpression",base:e,index:t}},callExpression:function(e,t){return{type:"CallExpression",base:e,arguments:t}},tableCallExpression:function(e,t){return{type:"TableCallExpression",base:e,arguments:t}},stringCallExpression:function(e,t){return{type:"StringCallExpression",base:e,argument:t}},comment:function(e,t){return{type:"Comment",value:e,raw:t}}},g=Array.prototype.slice,y=Object.prototype.toString,b=function(t,n){for(var r=0,i=t.length;r<i;r++)if(t[r]===n)return r;return-1},C,k,L,A,O,M,_,D;e.lex=P;var ot,ut,at,vt=[],mt;yt.prototype.complete=function(){n.locations&&(this.loc.end.line=L.line,this.loc.end.column=L.range[1]-L.lineStart),n.ranges&&(this.range[1]=L.range[1])},e.parse=Vt,e.write=$t,e.end=Jt})}),ace.define("ace/mode/lua_worker",["require","exports","module","ace/lib/oop","ace/worker/mirror","ace/mode/lua/luaparse"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../worker/mirror").Mirror,s=e("../mode/lua/luaparse"),o=t.Worker=function(e){i.call(this,e),this.setTimeout(500)};r.inherits(o,i),function(){this.onUpdate=function(){var e=this.doc.getValue();try{s.parse(e)}catch(t){t instanceof SyntaxError&&this.sender.emit("error",{row:t.line-1,column:t.column,text:t.message,type:"error"});return}this.sender.emit("ok")}}.call(o.prototype)}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _="	\n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/worker-php.js b/dist/assets/js/vendor/ace-nc/worker-php.js
            new file mode 100644
            index 0000000000..a2aed54be6
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/worker-php.js
            @@ -0,0 +1 @@
            +"no use strict";(function(e){if(typeof e.window!="undefined"&&e.document)return;e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console,e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){console.error("Worker "+(i?i.stack:e))},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(t,n){n||(n=t,t=null);if(!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;var i=n.split("/");if(!e.require.tlns)return console.log("unable to load "+n);i[0]=e.require.tlns[i[0]]||i[0];var s=i.join("/")+".js";return e.require.id=n,importScripts(s),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id),n.length||(n=["require","exports","module"]);if(t.indexOf("text!")===0)return;var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},e.initBaseUrls=function(t){require.tlns=t},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var i=r.data;if(i.command){if(!t[i.command])throw new Error("Unknown command:"+i.command);t[i.command].apply(t,i.args)}else if(i.init){initBaseUrls(i.tlns),require("ace/lib/es5-shim"),n=e.sender=initSender();var s=require(i.module)[i.classname];t=e.main=new s(n)}else i.event&&n&&n._signal(i.event,i.data)}})(this),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action==="insertText")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action==="insertLines"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action==="removeText"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action=="removeLines"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[""]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},"\n"+t.join("\n")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._signal("change",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._signal("change",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._signal("change",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._signal("change",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this._insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]=="object"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/worker/mirror",["require","exports","module","ace/document","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../document").Document,i=e("../lib/lang"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=i.delayedCall(this.onUpdate.bind(this)),s=this;e.on("change",function(e){t.applyDeltas(e.data);if(s.$timeout)return n.schedule(s.$timeout);s.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(s.prototype)}),ace.define("ace/mode/php/php",["require","exports","module"],function(e,t,n){var r={Constants:{}};r.Constants.T_INCLUDE=262,r.Constants.T_INCLUDE_ONCE=261,r.Constants.T_EVAL=260,r.Constants.T_REQUIRE=259,r.Constants.T_REQUIRE_ONCE=258,r.Constants.T_LOGICAL_OR=263,r.Constants.T_LOGICAL_XOR=264,r.Constants.T_LOGICAL_AND=265,r.Constants.T_PRINT=266,r.Constants.T_PLUS_EQUAL=277,r.Constants.T_MINUS_EQUAL=276,r.Constants.T_MUL_EQUAL=275,r.Constants.T_DIV_EQUAL=274,r.Constants.T_CONCAT_EQUAL=273,r.Constants.T_MOD_EQUAL=272,r.Constants.T_AND_EQUAL=271,r.Constants.T_OR_EQUAL=270,r.Constants.T_XOR_EQUAL=269,r.Constants.T_SL_EQUAL=268,r.Constants.T_SR_EQUAL=267,r.Constants.T_BOOLEAN_OR=278,r.Constants.T_BOOLEAN_AND=279,r.Constants.T_IS_EQUAL=283,r.Constants.T_IS_NOT_EQUAL=282,r.Constants.T_IS_IDENTICAL=281,r.Constants.T_IS_NOT_IDENTICAL=280,r.Constants.T_IS_SMALLER_OR_EQUAL=285,r.Constants.T_IS_GREATER_OR_EQUAL=284,r.Constants.T_SL=287,r.Constants.T_SR=286,r.Constants.T_INSTANCEOF=288,r.Constants.T_INC=297,r.Constants.T_DEC=296,r.Constants.T_INT_CAST=295,r.Constants.T_DOUBLE_CAST=294,r.Constants.T_STRING_CAST=293,r.Constants.T_ARRAY_CAST=292,r.Constants.T_OBJECT_CAST=291,r.Constants.T_BOOL_CAST=290,r.Constants.T_UNSET_CAST=289,r.Constants.T_NEW=299,r.Constants.T_CLONE=298,r.Constants.T_EXIT=300,r.Constants.T_IF=301,r.Constants.T_ELSEIF=302,r.Constants.T_ELSE=303,r.Constants.T_ENDIF=304,r.Constants.T_LNUMBER=305,r.Constants.T_DNUMBER=306,r.Constants.T_STRING=307,r.Constants.T_STRING_VARNAME=308,r.Constants.T_VARIABLE=309,r.Constants.T_NUM_STRING=310,r.Constants.T_INLINE_HTML=311,r.Constants.T_CHARACTER=312,r.Constants.T_BAD_CHARACTER=313,r.Constants.T_ENCAPSED_AND_WHITESPACE=314,r.Constants.T_CONSTANT_ENCAPSED_STRING=315,r.Constants.T_ECHO=316,r.Constants.T_DO=317,r.Constants.T_WHILE=318,r.Constants.T_ENDWHILE=319,r.Constants.T_FOR=320,r.Constants.T_ENDFOR=321,r.Constants.T_FOREACH=322,r.Constants.T_ENDFOREACH=323,r.Constants.T_DECLARE=324,r.Constants.T_ENDDECLARE=325,r.Constants.T_AS=326,r.Constants.T_SWITCH=327,r.Constants.T_ENDSWITCH=328,r.Constants.T_CASE=329,r.Constants.T_DEFAULT=330,r.Constants.T_BREAK=331,r.Constants.T_CONTINUE=332,r.Constants.T_GOTO=333,r.Constants.T_FUNCTION=334,r.Constants.T_CONST=335,r.Constants.T_RETURN=336,r.Constants.T_TRY=337,r.Constants.T_CATCH=338,r.Constants.T_THROW=339,r.Constants.T_USE=340,r.Constants.T_GLOBAL=341,r.Constants.T_STATIC=347,r.Constants.T_ABSTRACT=346,r.Constants.T_FINAL=345,r.Constants.T_PRIVATE=344,r.Constants.T_PROTECTED=343,r.Constants.T_PUBLIC=342,r.Constants.T_VAR=348,r.Constants.T_UNSET=349,r.Constants.T_ISSET=350,r.Constants.T_EMPTY=351,r.Constants.T_HALT_COMPILER=352,r.Constants.T_CLASS=353,r.Constants.T_TRAIT=382,r.Constants.T_INTERFACE=354,r.Constants.T_EXTENDS=355,r.Constants.T_IMPLEMENTS=356,r.Constants.T_OBJECT_OPERATOR=357,r.Constants.T_DOUBLE_ARROW=358,r.Constants.T_LIST=359,r.Constants.T_ARRAY=360,r.Constants.T_CLASS_C=361,r.Constants.T_TRAIT_C=381,r.Constants.T_METHOD_C=362,r.Constants.T_FUNC_C=363,r.Constants.T_LINE=364,r.Constants.T_FILE=365,r.Constants.T_COMMENT=366,r.Constants.T_DOC_COMMENT=367,r.Constants.T_OPEN_TAG=368,r.Constants.T_OPEN_TAG_WITH_ECHO=369,r.Constants.T_CLOSE_TAG=370,r.Constants.T_WHITESPACE=371,r.Constants.T_START_HEREDOC=372,r.Constants.T_END_HEREDOC=373,r.Constants.T_DOLLAR_OPEN_CURLY_BRACES=374,r.Constants.T_CURLY_OPEN=375,r.Constants.T_PAAMAYIM_NEKUDOTAYIM=376,r.Constants.T_DOUBLE_COLON=376,r.Constants.T_NAMESPACE=377,r.Constants.T_NS_C=378,r.Constants.T_DIR=379,r.Constants.T_NS_SEPARATOR=380,r.Lexer=function(e,t){var n,i=function(e){if(e.match(/\n/)!==null){var t=e.substring(0,1);e="["+e.split(/\n/).join(t+","+t)+'].join("\\n")'}return e},s,o=t===undefined||/^(on|true|1)$/i.test(t.short_open_tag)?/(\<\?php\s|\<\?|\<\%|\<script language\=('|")?php('|")?\>)/i:/(\<\?php\s|<\?=|\<script language\=('|")?php('|")?\>)/i,u=t===undefined||/^(on|true|1)$/i.test(t.short_open_tag)?/^(\<\?php\s|\<\?|\<\%|\<script language\=('|")?php('|")?\>)/i:/^(\<\?php\s|<\?=|\<script language\=('|")?php('|")?\>)/i,a=[{value:r.Constants.T_NAMESPACE,re:/^namespace(?=\s)/i},{value:r.Constants.T_USE,re:/^use(?=\s)/i},{value:r.Constants.T_ABSTRACT,re:/^abstract(?=\s)/i},{value:r.Constants.T_IMPLEMENTS,re:/^implements(?=\s)/i},{value:r.Constants.T_INTERFACE,re:/^interface(?=\s)/i},{value:r.Constants.T_CONST,re:/^const(?=\s)/i},{value:r.Constants.T_STATIC,re:/^static(?=\s)/i},{value:r.Constants.T_FINAL,re:/^final(?=\s)/i},{value:r.Constants.T_VAR,re:/^var(?=\s)/i},{value:r.Constants.T_GLOBAL,re:/^global(?=\s)/i},{value:r.Constants.T_CLONE,re:/^clone(?=\s)/i},{value:r.Constants.T_THROW,re:/^throw(?=\s)/i},{value:r.Constants.T_EXTENDS,re:/^extends(?=\s)/i},{value:r.Constants.T_AND_EQUAL,re:/^&=/},{value:r.Constants.T_AS,re:/^as(?=\s)/i},{value:r.Constants.T_ARRAY_CAST,re:/^\(array\)/i},{value:r.Constants.T_BOOL_CAST,re:/^\((bool|boolean)\)/i},{value:r.Constants.T_DOUBLE_CAST,re:/^\((real|float|double)\)/i},{value:r.Constants.T_INT_CAST,re:/^\((int|integer)\)/i},{value:r.Constants.T_OBJECT_CAST,re:/^\(object\)/i},{value:r.Constants.T_STRING_CAST,re:/^\(string\)/i},{value:r.Constants.T_UNSET_CAST,re:/^\(unset\)/i},{value:r.Constants.T_TRY,re:/^try(?=\s*{)/i},{value:r.Constants.T_CATCH,re:/^catch(?=\s*\()/i},{value:r.Constants.T_INSTANCEOF,re:/^instanceof(?=\s)/i},{value:r.Constants.T_LOGICAL_OR,re:/^or(?=\s)/i},{value:r.Constants.T_LOGICAL_AND,re:/^and(?=\s)/i},{value:r.Constants.T_LOGICAL_XOR,re:/^xor(?=\s)/i},{value:r.Constants.T_BOOLEAN_AND,re:/^&&/},{value:r.Constants.T_BOOLEAN_OR,re:/^\|\|/},{value:r.Constants.T_CONTINUE,re:/^continue(?=\s|;)/i},{value:r.Constants.T_BREAK,re:/^break(?=\s|;)/i},{value:r.Constants.T_ENDDECLARE,re:/^enddeclare(?=\s|;)/i},{value:r.Constants.T_ENDFOR,re:/^endfor(?=\s|;)/i},{value:r.Constants.T_ENDFOREACH,re:/^endforeach(?=\s|;)/i},{value:r.Constants.T_ENDIF,re:/^endif(?=\s|;)/i},{value:r.Constants.T_ENDSWITCH,re:/^endswitch(?=\s|;)/i},{value:r.Constants.T_ENDWHILE,re:/^endwhile(?=\s|;)/i},{value:r.Constants.T_CASE,re:/^case(?=\s)/i},{value:r.Constants.T_DEFAULT,re:/^default(?=\s|:)/i},{value:r.Constants.T_SWITCH,re:/^switch(?=[ (])/i},{value:r.Constants.T_EXIT,re:/^(exit|die)(?=[ \(;])/i},{value:r.Constants.T_CLOSE_TAG,re:/^(\?\>|\%\>|\<\/script\>)\s?\s?/i,func:function(e){return c=!1,e}},{value:r.Constants.T_DOUBLE_ARROW,re:/^\=\>/},{value:r.Constants.T_DOUBLE_COLON,re:/^\:\:/},{value:r.Constants.T_METHOD_C,re:/^__METHOD__/},{value:r.Constants.T_LINE,re:/^__LINE__/},{value:r.Constants.T_FILE,re:/^__FILE__/},{value:r.Constants.T_FUNC_C,re:/^__FUNCTION__/},{value:r.Constants.T_NS_C,re:/^__NAMESPACE__/},{value:r.Constants.T_TRAIT_C,re:/^__TRAIT__/},{value:r.Constants.T_DIR,re:/^__DIR__/},{value:r.Constants.T_CLASS_C,re:/^__CLASS__/},{value:r.Constants.T_INC,re:/^\+\+/},{value:r.Constants.T_DEC,re:/^\-\-/},{value:r.Constants.T_CONCAT_EQUAL,re:/^\.\=/},{value:r.Constants.T_DIV_EQUAL,re:/^\/\=/},{value:r.Constants.T_XOR_EQUAL,re:/^\^\=/},{value:r.Constants.T_MUL_EQUAL,re:/^\*\=/},{value:r.Constants.T_MOD_EQUAL,re:/^\%\=/},{value:r.Constants.T_SL_EQUAL,re:/^<<=/},{value:r.Constants.T_START_HEREDOC,re:/^<<<[A-Z_0-9]+\s/i,func:function(e){return n=e.substring(3,e.length-1),e}},{value:r.Constants.T_SL,re:/^<</},{value:r.Constants.T_IS_SMALLER_OR_EQUAL,re:/^<=/},{value:r.Constants.T_SR_EQUAL,re:/^>>=/},{value:r.Constants.T_SR,re:/^>>/},{value:r.Constants.T_IS_GREATER_OR_EQUAL,re:/^>=/},{value:r.Constants.T_OR_EQUAL,re:/^\|\=/},{value:r.Constants.T_PLUS_EQUAL,re:/^\+\=/},{value:r.Constants.T_MINUS_EQUAL,re:/^-\=/},{value:r.Constants.T_OBJECT_OPERATOR,re:/^\-\>/i},{value:r.Constants.T_CLASS,re:/^class(?=[\s\{])/i,afterWhitespace:!0},{value:r.Constants.T_TRAIT,re:/^trait(?=[\s]+[A-Za-z])/i},{value:r.Constants.T_PUBLIC,re:/^public(?=[\s])/i},{value:r.Constants.T_PRIVATE,re:/^private(?=[\s])/i},{value:r.Constants.T_PROTECTED,re:/^protected(?=[\s])/i},{value:r.Constants.T_ARRAY,re:/^array(?=\s*?\()/i},{value:r.Constants.T_EMPTY,re:/^empty(?=[ \(])/i},{value:r.Constants.T_ISSET,re:/^isset(?=[ \(])/i},{value:r.Constants.T_UNSET,re:/^unset(?=[ \(])/i},{value:r.Constants.T_RETURN,re:/^return(?=[ "'(;])/i},{value:r.Constants.T_FUNCTION,re:/^function(?=[ "'(;])/i},{value:r.Constants.T_ECHO,re:/^echo(?=[ "'(;])/i},{value:r.Constants.T_LIST,re:/^list(?=\s*?\()/i},{value:r.Constants.T_PRINT,re:/^print(?=[ "'(;])/i},{value:r.Constants.T_INCLUDE,re:/^include(?=[ "'(;])/i},{value:r.Constants.T_INCLUDE_ONCE,re:/^include_once(?=[ "'(;])/i},{value:r.Constants.T_REQUIRE,re:/^require(?=[ "'(;])/i},{value:r.Constants.T_REQUIRE_ONCE,re:/^require_once(?=[ "'(;])/i},{value:r.Constants.T_NEW,re:/^new(?=[ ])/i},{value:r.Constants.T_COMMENT,re:/^\/\*([\S\s]*?)(?:\*\/|$)/},{value:r.Constants.T_COMMENT,re:/^\/\/.*(\s)?/},{value:r.Constants.T_COMMENT,re:/^\#.*(\s)?/},{value:r.Constants.T_ELSEIF,re:/^elseif(?=[\s(])/i},{value:r.Constants.T_GOTO,re:/^goto(?=[\s(])/i},{value:r.Constants.T_ELSE,re:/^else(?=[\s{:])/i},{value:r.Constants.T_IF,re:/^if(?=[\s(])/i},{value:r.Constants.T_DO,re:/^do(?=[ {])/i},{value:r.Constants.T_WHILE,re:/^while(?=[ (])/i},{value:r.Constants.T_FOREACH,re:/^foreach(?=[ (])/i},{value:r.Constants.T_ISSET,re:/^isset(?=[ (])/i},{value:r.Constants.T_IS_IDENTICAL,re:/^===/},{value:r.Constants.T_IS_EQUAL,re:/^==/},{value:r.Constants.T_IS_NOT_IDENTICAL,re:/^\!==/},{value:r.Constants.T_IS_NOT_EQUAL,re:/^(\!=|\<\>)/},{value:r.Constants.T_FOR,re:/^for(?=[ (])/i},{value:r.Constants.T_DNUMBER,re:/^[0-9]*\.[0-9]+([eE][-]?[0-9]*)?/},{value:r.Constants.T_LNUMBER,re:/^(0x[0-9A-F]+|[0-9]+)/i},{value:r.Constants.T_OPEN_TAG_WITH_ECHO,re:/^(\<\?=|\<\%=)/i},{value:r.Constants.T_OPEN_TAG,re:u},{value:r.Constants.T_VARIABLE,re:/^\$[a-zA-Z_\x7f-\uffff][a-zA-Z0-9_\x7f-\uffff]*/},{value:r.Constants.T_WHITESPACE,re:/^\s+/},{value:r.Constants.T_CONSTANT_ENCAPSED_STRING,re:/^("(?:[^"\\]|\\[\s\S])*"|'(?:[^'\\]|\\[\s\S])*')/,func:function(e,t){var n=0,i,s=0;if(e.substring(0,1)==="'")return e;var o=e.match(/(?:[^\\]|\\.)*[^\\]\$[a-zA-Z_\x7f-\uffff][a-zA-Z0-9_\x7f-\uffff]*/g);if(o!==null){while(e.length>0){i=e.length,o=e.match(/^[\[\]\;\:\?\(\)\!\.\,\>\<\=\+\-\/\*\|\&\@\^\%\"\'\{\}]/),o!==null&&(f.push(o[0]),e=e.substring(1),n>0&&o[0]==="}"&&n--,o[0]==="["&&s++,o[0]==="]"&&s--),o=e.match(/^\$[a-zA-Z_\x7f-\uffff][a-zA-Z0-9_\x7f-\uffff]*/);if(o!==null){f.push([parseInt(r.Constants.T_VARIABLE,10),o[0],l]),e=e.substring(o[0].length),o=e.match(/^(\-\>)\s*([a-zA-Z_\x7f-\uffff][a-zA-Z0-9_\x7f-\uffff]*)\s*(\()/),o!==null&&(f.push([parseInt(r.Constants.T_OBJECT_OPERATOR,10),o[1],l]),f.push([parseInt(r.Constants.T_STRING,10),o[2],l]),o[3]&&f.push(o[3]),e=e.substring(o[0].length));if(e.match(/^\[/g)!==null)continue}var u;n>0?u=/^([^\\\$"{}\]\(\)\->]|\\.)+/g:u=/^([^\\\$"{]|\\.|{[^\$]|\$(?=[^a-zA-Z_\x7f-\uffff]))+/g;var a,c;while((o=e.match(u))!==null){if(e.length===1)throw new Error(o);a=0,n>0?(c=o[0].match(/^[\[\]\;\:\?\(\)\!\.\,\>\<\=\+\-\/\*\|\&\{\}\@\^\%\$\~]/))?f.push(c[0]):a=r.Constants.T_STRING:a=r.Constants.T_ENCAPSED_AND_WHITESPACE,a&&f.push([parseInt(a,10),o[0].replace(/\n/g,"\\n").replace(/\r/g,""),l]),l+=o[0].split("\n").length-1,e=e.substring(o[0].length)}n>0&&e.match(/^\->/)!==null&&(f.push([parseInt(r.Constants.T_OBJECT_OPERATOR,10),"->",l]),e=e.substring(2)),e.match(/^{\$/)!==null&&(f.push([parseInt(r.Constants.T_CURLY_OPEN,10),"{",l]),e=e.substring(1),n++);if(i===e.length&&(o=e.match(/^(([^\\]|\\.)*?[^\\]\$[a-zA-Z_\x7f-\uffff][a-zA-Z0-9_\x7f-\uffff]*)/g))!==null)return}return undefined}return e=e.replace(/\r/g,""),e}},{value:r.Constants.T_NS_SEPARATOR,re:/^\\(?=[a-zA-Z_])/},{value:r.Constants.T_STRING,re:/^[a-zA-Z_\x7f-\uffff][a-zA-Z0-9_\x7f-\uffff]*/},{value:-1,re:/^[\[\]\;\:\?\(\)\!\.\,\>\<\=\+\-\/\*\|\&\{\}\@\^\%\"\'\$\~]/}],f=[],l=1,c=!1,h=!0;if(e===null)return f;typeof e!="string"&&(e=e.toString());while(e.length>0&&h===!0)if(c===!0)if(n!==undefined){var p=new RegExp("([\\S\\s]*?)(\\r\\n|\\n|\\r)("+n+")(;|\\r\\n|\\n)","i"),d=e.match(p);d!==null&&(f.push([parseInt(r.Constants.T_ENCAPSED_AND_WHITESPACE,10),d[1].replace(/^\n/g,"").replace(/\\\$/g,"$")+"\n",l]),l+=d[1].split("\n").length,f.push([parseInt(r.Constants.T_END_HEREDOC,10),d[3],l]),e=e.substring(d[1].length+d[2].length+d[3].length),n=undefined);if(d===null)throw Error("sup")}else h=a.some(function(t){if(t.afterWhitespace===!0){var n=f[f.length-1];if(!Array.isArray(n)||n[0]!==r.Constants.T_WHITESPACE&&n[0]!==r.Constants.T_OPEN_TAG&&n[0]!==r.Constants.T_COMMENT)return!1}var i=e.match(t.re);if(i!==null){if(t.value!==-1){var s=i[0];t.func!==undefined&&(s=t.func(s,t)),s!==undefined&&(f.push([parseInt(t.value,10),s,l]),l+=s.split("\n").length-1)}else f.push(i[0]);return e=e.substring(i[0].length),!0}return!1});else{var d=o.exec(e);if(d===null)return f.push([parseInt(r.Constants.T_INLINE_HTML,10),e.replace(/^\n/,""),l]),f;if(d.index>0){var v=e.substring(0,d.index);f.push([parseInt(r.Constants.T_INLINE_HTML,10),v,l]),l+=v.split("\n").length-1,e=e.substring(d.index)}c=!0}return f},r.Parser=function(e,t){var n=this.yybase,i=this.yydefault,s=this.yycheck,o=this.yyaction,u=this.yylen,a=this.yygbase,f=this.yygcheck,l=this.yyp,c=this.yygoto,h=this.yylhs,p=this.terminals,d=this.translate,v=this.yygdefault;this.pos=-1,this.line=1,this.tokenMap=this.createTokenMap(),this.dropTokens={},this.dropTokens[r.Constants.T_WHITESPACE]=1,this.dropTokens[r.Constants.T_OPEN_TAG]=1;var m=[];e.forEach(function(e,t){typeof e=="object"&&e[0]===r.Constants.T_OPEN_TAG_WITH_ECHO?(m.push([r.Constants.T_OPEN_TAG,e[1],e[2]]),m.push([r.Constants.T_ECHO,e[1],e[2]])):m.push(e)}),this.tokens=m;var g=this.TOKEN_NONE;this.startAttributes={startLine:1},this.endAttributes={};var y=[this.startAttributes],b=0,w=[b];this.yyastk=[],this.stackPos=0;var E,S;for(;;){if(n[b]===0)E=i[b];else{g===this.TOKEN_NONE&&(S=this.getNextToken(),g=S>=0&&S<this.TOKEN_MAP_SIZE?d[S]:this.TOKEN_INVALID,y[this.stackPos]=this.startAttributes);if(((E=n[b]+g)>=0&&E<this.YYLAST&&s[E]===g||b<this.YY2TBLSTATE&&(E=n[b+this.YYNLSTATES]+g)>=0&&E<this.YYLAST&&s[E]===g)&&(E=o[E])!==this.YYDEFAULT)if(E>0){++this.stackPos,w[this.stackPos]=b=E,this.yyastk[this.stackPos]=this.tokenValue,y[this.stackPos]=this.startAttributes,g=this.TOKEN_NONE;if(E<this.YYNLSTATES)continue;E-=this.YYNLSTATES}else E=-E;else E=i[b]}for(;;){if(E===0)return this.yyval;if(E===this.YYUNEXPECTED){if(t!==!0){var N=[];for(var C=0;C<this.TOKEN_MAP_SIZE;++C)if((E=n[b]+C)>=0&&E<this.YYLAST&&s[E]==C||b<this.YY2TBLSTATE&&(E=n[b+this.YYNLSTATES]+C)&&E<this.YYLAST&&s[E]==C)if(o[E]!=this.YYUNEXPECTED){if(N.length==4){N=[];break}N.push(this.terminals[C])}var k="";throw N.length&&(k=", expecting "+N.join(" or ")),new r.ParseError("syntax error, unexpected "+p[g]+k,this.startAttributes.startLine)}return this.startAttributes.startLine}for(var x in this.endAttributes)y[this.stackPos-u[E]][x]=this.endAttributes[x];try{this["yyn"+E](y[this.stackPos-u[E]])}catch(T){throw T}this.stackPos-=u[E],E=h[E],(l=a[E]+w[this.stackPos])>=0&&l<this.YYGLAST&&f[l]===E?b=c[l]:b=v[E],++this.stackPos,w[this.stackPos]=b,this.yyastk[this.stackPos]=this.yyval,y[this.stackPos]=this.startAttributes;if(b<this.YYNLSTATES)break;E=b-this.YYNLSTATES}}},r.ParseError=function(e,t){this.message=e,this.line=t},r.Parser.prototype.MODIFIER_PUBLIC=1,r.Parser.prototype.MODIFIER_PROTECTED=2,r.Parser.prototype.MODIFIER_PRIVATE=4,r.Parser.prototype.MODIFIER_STATIC=8,r.Parser.prototype.MODIFIER_ABSTRACT=16,r.Parser.prototype.MODIFIER_FINAL=32,r.Parser.prototype.getNextToken=function(){this.startAttributes={},this.endAttributes={};var e,t;while(this.tokens[++this.pos]!==undefined){e=this.tokens[this.pos];if(typeof e=="string")return this.startAttributes.startLine=this.line,this.endAttributes.endLine=this.line,'b"'===e?(this.tokenValue='b"','"'.charCodeAt(0)):(this.tokenValue=e,e.charCodeAt(0));this.line+=(t=e[1].match(/\n/g))===null?0:t.length;if(r.Constants.T_COMMENT===e[0])Array.isArray(this.startAttributes.comments)||(this.startAttributes.comments=[]),this.startAttributes.comments.push({type:"comment",comment:e[1],line:e[2]});else if(r.Constants.T_DOC_COMMENT===e[0])this.startAttributes.comments.push(new PHPParser_Comment_Doc(e[1],e[2]));else if(this.dropTokens[e[0]]===undefined)return this.tokenValue=e[1],this.startAttributes.startLine=e[2],this.endAttributes.endLine=this.line,this.tokenMap[e[0]]}return this.startAttributes.startLine=this.line,0},r.Parser.prototype.tokenName=function(e){var t=["T_INCLUDE","T_INCLUDE_ONCE","T_EVAL","T_REQUIRE","T_REQUIRE_ONCE","T_LOGICAL_OR","T_LOGICAL_XOR","T_LOGICAL_AND","T_PRINT","T_PLUS_EQUAL","T_MINUS_EQUAL","T_MUL_EQUAL","T_DIV_EQUAL","T_CONCAT_EQUAL","T_MOD_EQUAL","T_AND_EQUAL","T_OR_EQUAL","T_XOR_EQUAL","T_SL_EQUAL","T_SR_EQUAL","T_BOOLEAN_OR","T_BOOLEAN_AND","T_IS_EQUAL","T_IS_NOT_EQUAL","T_IS_IDENTICAL","T_IS_NOT_IDENTICAL","T_IS_SMALLER_OR_EQUAL","T_IS_GREATER_OR_EQUAL","T_SL","T_SR","T_INSTANCEOF","T_INC","T_DEC","T_INT_CAST","T_DOUBLE_CAST","T_STRING_CAST","T_ARRAY_CAST","T_OBJECT_CAST","T_BOOL_CAST","T_UNSET_CAST","T_NEW","T_CLONE","T_EXIT","T_IF","T_ELSEIF","T_ELSE","T_ENDIF","T_LNUMBER","T_DNUMBER","T_STRING","T_STRING_VARNAME","T_VARIABLE","T_NUM_STRING","T_INLINE_HTML","T_CHARACTER","T_BAD_CHARACTER","T_ENCAPSED_AND_WHITESPACE","T_CONSTANT_ENCAPSED_STRING","T_ECHO","T_DO","T_WHILE","T_ENDWHILE","T_FOR","T_ENDFOR","T_FOREACH","T_ENDFOREACH","T_DECLARE","T_ENDDECLARE","T_AS","T_SWITCH","T_ENDSWITCH","T_CASE","T_DEFAULT","T_BREAK","T_CONTINUE","T_GOTO","T_FUNCTION","T_CONST","T_RETURN","T_TRY","T_CATCH","T_THROW","T_USE","T_INSTEADOF","T_GLOBAL","T_STATIC","T_ABSTRACT","T_FINAL","T_PRIVATE","T_PROTECTED","T_PUBLIC","T_VAR","T_UNSET","T_ISSET","T_EMPTY","T_HALT_COMPILER","T_CLASS","T_TRAIT","T_INTERFACE","T_EXTENDS","T_IMPLEMENTS","T_OBJECT_OPERATOR","T_DOUBLE_ARROW","T_LIST","T_ARRAY","T_CALLABLE","T_CLASS_C","T_TRAIT_C","T_METHOD_C","T_FUNC_C","T_LINE","T_FILE","T_COMMENT","T_DOC_COMMENT","T_OPEN_TAG","T_OPEN_TAG_WITH_ECHO","T_CLOSE_TAG","T_WHITESPACE","T_START_HEREDOC","T_END_HEREDOC","T_DOLLAR_OPEN_CURLY_BRACES","T_CURLY_OPEN","T_PAAMAYIM_NEKUDOTAYIM","T_DOUBLE_COLON","T_NAMESPACE","T_NS_C","T_DIR","T_NS_SEPARATOR"],n="UNKNOWN";return t.some(function(t){return r.Constants[t]===e?(n=t,!0):!1}),n},r.Parser.prototype.createTokenMap=function(){var e={},t,n,i=r.Constants.T_PAAMAYIM_NEKUDOTAYIM;for(n=256;n<1e3;++n)i===n?e[n]=this.T_PAAMAYIM_NEKUDOTAYIM:r.Constants.T_OPEN_TAG_WITH_ECHO===n?e[n]=r.Constants.T_ECHO:r.Constants.T_CLOSE_TAG===n?e[n]=59:"UNKNOWN"!==(t=this.tokenName(n))&&(e[n]=this[t]);return e};var i=function(){this.yyval=this.yyastk[this.stackPos-0]};r.Parser.prototype.MakeArray=function(e){return Array.isArray(e)?e:[e]},r.Parser.prototype.parseString=function(e){var t=0;return"b"===e[0]&&(t=1),"'"===e[t]?e=e.replace(["\\\\","\\'"],["\\","'"]):e=this.parseEscapeSequences(e,'"'),e},r.Parser.prototype.parseEscapeSequences=function(e,t){undefined!==t&&(e=e.replace(new RegExp("\\"+t,"g"),t));var n={"\\":"\\",$:"$",n:"\n",r:"\r",t:"	",f:"\f",v:"",e:""};return e.replace(/~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3})~/g,function(e){var t=e[1];return n[t]!==undefined?n[t]:"x"===t[0]||"X"===t[0]?chr(hexdec(t)):chr(octdec(t))})},r.Parser.prototype.TOKEN_NONE=-1,r.Parser.prototype.TOKEN_INVALID=149,r.Parser.prototype.TOKEN_MAP_SIZE=384,r.Parser.prototype.YYLAST=913,r.Parser.prototype.YY2TBLSTATE=328,r.Parser.prototype.YYGLAST=415,r.Parser.prototype.YYNLSTATES=544,r.Parser.prototype.YYUNEXPECTED=32767,r.Parser.prototype.YYDEFAULT=-32766,r.Parser.prototype.YYERRTOK=256,r.Parser.prototype.T_INCLUDE=257,r.Parser.prototype.T_INCLUDE_ONCE=258,r.Parser.prototype.T_EVAL=259,r.Parser.prototype.T_REQUIRE=260,r.Parser.prototype.T_REQUIRE_ONCE=261,r.Parser.prototype.T_LOGICAL_OR=262,r.Parser.prototype.T_LOGICAL_XOR=263,r.Parser.prototype.T_LOGICAL_AND=264,r.Parser.prototype.T_PRINT=265,r.Parser.prototype.T_PLUS_EQUAL=266,r.Parser.prototype.T_MINUS_EQUAL=267,r.Parser.prototype.T_MUL_EQUAL=268,r.Parser.prototype.T_DIV_EQUAL=269,r.Parser.prototype.T_CONCAT_EQUAL=270,r.Parser.prototype.T_MOD_EQUAL=271,r.Parser.prototype.T_AND_EQUAL=272,r.Parser.prototype.T_OR_EQUAL=273,r.Parser.prototype.T_XOR_EQUAL=274,r.Parser.prototype.T_SL_EQUAL=275,r.Parser.prototype.T_SR_EQUAL=276,r.Parser.prototype.T_BOOLEAN_OR=277,r.Parser.prototype.T_BOOLEAN_AND=278,r.Parser.prototype.T_IS_EQUAL=279,r.Parser.prototype.T_IS_NOT_EQUAL=280,r.Parser.prototype.T_IS_IDENTICAL=281,r.Parser.prototype.T_IS_NOT_IDENTICAL=282,r.Parser.prototype.T_IS_SMALLER_OR_EQUAL=283,r.Parser.prototype.T_IS_GREATER_OR_EQUAL=284,r.Parser.prototype.T_SL=285,r.Parser.prototype.T_SR=286,r.Parser.prototype.T_INSTANCEOF=287,r.Parser.prototype.T_INC=288,r.Parser.prototype.T_DEC=289,r.Parser.prototype.T_INT_CAST=290,r.Parser.prototype.T_DOUBLE_CAST=291,r.Parser.prototype.T_STRING_CAST=292,r.Parser.prototype.T_ARRAY_CAST=293,r.Parser.prototype.T_OBJECT_CAST=294,r.Parser.prototype.T_BOOL_CAST=295,r.Parser.prototype.T_UNSET_CAST=296,r.Parser.prototype.T_NEW=297,r.Parser.prototype.T_CLONE=298,r.Parser.prototype.T_EXIT=299,r.Parser.prototype.T_IF=300,r.Parser.prototype.T_ELSEIF=301,r.Parser.prototype.T_ELSE=302,r.Parser.prototype.T_ENDIF=303,r.Parser.prototype.T_LNUMBER=304,r.Parser.prototype.T_DNUMBER=305,r.Parser.prototype.T_STRING=306,r.Parser.prototype.T_STRING_VARNAME=307,r.Parser.prototype.T_VARIABLE=308,r.Parser.prototype.T_NUM_STRING=309,r.Parser.prototype.T_INLINE_HTML=310,r.Parser.prototype.T_CHARACTER=311,r.Parser.prototype.T_BAD_CHARACTER=312,r.Parser.prototype.T_ENCAPSED_AND_WHITESPACE=313,r.Parser.prototype.T_CONSTANT_ENCAPSED_STRING=314,r.Parser.prototype.T_ECHO=315,r.Parser.prototype.T_DO=316,r.Parser.prototype.T_WHILE=317,r.Parser.prototype.T_ENDWHILE=318,r.Parser.prototype.T_FOR=319,r.Parser.prototype.T_ENDFOR=320,r.Parser.prototype.T_FOREACH=321,r.Parser.prototype.T_ENDFOREACH=322,r.Parser.prototype.T_DECLARE=323,r.Parser.prototype.T_ENDDECLARE=324,r.Parser.prototype.T_AS=325,r.Parser.prototype.T_SWITCH=326,r.Parser.prototype.T_ENDSWITCH=327,r.Parser.prototype.T_CASE=328,r.Parser.prototype.T_DEFAULT=329,r.Parser.prototype.T_BREAK=330,r.Parser.prototype.T_CONTINUE=331,r.Parser.prototype.T_GOTO=332,r.Parser.prototype.T_FUNCTION=333,r.Parser.prototype.T_CONST=334,r.Parser.prototype.T_RETURN=335,r.Parser.prototype.T_TRY=336,r.Parser.prototype.T_CATCH=337,r.Parser.prototype.T_THROW=338,r.Parser.prototype.T_USE=339,r.Parser.prototype.T_INSTEADOF=340,r.Parser.prototype.T_GLOBAL=341,r.Parser.prototype.T_STATIC=342,r.Parser.prototype.T_ABSTRACT=343,r.Parser.prototype.T_FINAL=344,r.Parser.prototype.T_PRIVATE=345,r.Parser.prototype.T_PROTECTED=346,r.Parser.prototype.T_PUBLIC=347,r.Parser.prototype.T_VAR=348,r.Parser.prototype.T_UNSET=349,r.Parser.prototype.T_ISSET=350,r.Parser.prototype.T_EMPTY=351,r.Parser.prototype.T_HALT_COMPILER=352,r.Parser.prototype.T_CLASS=353,r.Parser.prototype.T_TRAIT=354,r.Parser.prototype.T_INTERFACE=355,r.Parser.prototype.T_EXTENDS=356,r.Parser.prototype.T_IMPLEMENTS=357,r.Parser.prototype.T_OBJECT_OPERATOR=358,r.Parser.prototype.T_DOUBLE_ARROW=359,r.Parser.prototype.T_LIST=360,r.Parser.prototype.T_ARRAY=361,r.Parser.prototype.T_CALLABLE=362,r.Parser.prototype.T_CLASS_C=363,r.Parser.prototype.T_TRAIT_C=364,r.Parser.prototype.T_METHOD_C=365,r.Parser.prototype.T_FUNC_C=366,r.Parser.prototype.T_LINE=367,r.Parser.prototype.T_FILE=368,r.Parser.prototype.T_COMMENT=369,r.Parser.prototype.T_DOC_COMMENT=370,r.Parser.prototype.T_OPEN_TAG=371,r.Parser.prototype.T_OPEN_TAG_WITH_ECHO=372,r.Parser.prototype.T_CLOSE_TAG=373,r.Parser.prototype.T_WHITESPACE=374,r.Parser.prototype.T_START_HEREDOC=375,r.Parser.prototype.T_END_HEREDOC=376,r.Parser.prototype.T_DOLLAR_OPEN_CURLY_BRACES=377,r.Parser.prototype.T_CURLY_OPEN=378,r.Parser.prototype.T_PAAMAYIM_NEKUDOTAYIM=379,r.Parser.prototype.T_NAMESPACE=380,r.Parser.prototype.T_NS_C=381,r.Parser.prototype.T_DIR=382,r.Parser.prototype.T_NS_SEPARATOR=383,r.Parser.prototype.terminals=["$EOF","error","T_INCLUDE","T_INCLUDE_ONCE","T_EVAL","T_REQUIRE","T_REQUIRE_ONCE","','","T_LOGICAL_OR","T_LOGICAL_XOR","T_LOGICAL_AND","T_PRINT","'='","T_PLUS_EQUAL","T_MINUS_EQUAL","T_MUL_EQUAL","T_DIV_EQUAL","T_CONCAT_EQUAL","T_MOD_EQUAL","T_AND_EQUAL","T_OR_EQUAL","T_XOR_EQUAL","T_SL_EQUAL","T_SR_EQUAL","'?'","':'","T_BOOLEAN_OR","T_BOOLEAN_AND","'|'","'^'","'&'","T_IS_EQUAL","T_IS_NOT_EQUAL","T_IS_IDENTICAL","T_IS_NOT_IDENTICAL","'<'","T_IS_SMALLER_OR_EQUAL","'>'","T_IS_GREATER_OR_EQUAL","T_SL","T_SR","'+'","'-'","'.'","'*'","'/'","'%'","'!'","T_INSTANCEOF","'~'","T_INC","T_DEC","T_INT_CAST","T_DOUBLE_CAST","T_STRING_CAST","T_ARRAY_CAST","T_OBJECT_CAST","T_BOOL_CAST","T_UNSET_CAST","'@'","'['","T_NEW","T_CLONE","T_EXIT","T_IF","T_ELSEIF","T_ELSE","T_ENDIF","T_LNUMBER","T_DNUMBER","T_STRING","T_STRING_VARNAME","T_VARIABLE","T_NUM_STRING","T_INLINE_HTML","T_ENCAPSED_AND_WHITESPACE","T_CONSTANT_ENCAPSED_STRING","T_ECHO","T_DO","T_WHILE","T_ENDWHILE","T_FOR","T_ENDFOR","T_FOREACH","T_ENDFOREACH","T_DECLARE","T_ENDDECLARE","T_AS","T_SWITCH","T_ENDSWITCH","T_CASE","T_DEFAULT","T_BREAK","T_CONTINUE","T_GOTO","T_FUNCTION","T_CONST","T_RETURN","T_TRY","T_CATCH","T_THROW","T_USE","T_INSTEADOF","T_GLOBAL","T_STATIC","T_ABSTRACT","T_FINAL","T_PRIVATE","T_PROTECTED","T_PUBLIC","T_VAR","T_UNSET","T_ISSET","T_EMPTY","T_HALT_COMPILER","T_CLASS","T_TRAIT","T_INTERFACE","T_EXTENDS","T_IMPLEMENTS","T_OBJECT_OPERATOR","T_DOUBLE_ARROW","T_LIST","T_ARRAY","T_CALLABLE","T_CLASS_C","T_TRAIT_C","T_METHOD_C","T_FUNC_C","T_LINE","T_FILE","T_START_HEREDOC","T_END_HEREDOC","T_DOLLAR_OPEN_CURLY_BRACES","T_CURLY_OPEN","T_PAAMAYIM_NEKUDOTAYIM","T_NAMESPACE","T_NS_C","T_DIR","T_NS_SEPARATOR","';'","'{'","'}'","'('","')'","'$'","']'","'`'","'\"'","???"],r.Parser.prototype.translate=[0,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,47,148,149,145,46,30,149,143,144,44,41,7,42,43,45,149,149,149,149,149,149,149,149,149,149,25,140,35,12,37,24,59,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,60,149,146,29,149,147,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,141,28,142,49,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,1,2,3,4,5,6,8,9,10,11,13,14,15,16,17,18,19,20,21,22,23,26,27,31,32,33,34,36,38,39,40,48,50,51,52,53,54,55,56,57,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,149,149,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,149,149,149,149,149,149,131,132,133,134,135,136,137,138,139],r.Parser.prototype.yyaction=[61,62,363,63,64,-32766,-32766,-32766,509,65,708,709,710,707,706,705,-32766,-32766,-32766,-32766,-32766,-32766,132,-32766,-32766,-32766,-32766,-32766,-32767,-32767,-32767,-32767,-32766,335,-32766,-32766,-32766,-32766,-32766,66,67,351,663,664,40,68,548,69,232,233,70,71,72,73,74,75,76,77,30,246,78,336,364,-112,0,469,833,834,365,641,890,436,590,41,835,53,27,366,294,367,687,368,921,369,923,922,370,-32766,-32766,-32766,42,43,371,339,126,44,372,337,79,297,349,292,293,-32766,918,-32766,-32766,373,374,375,376,377,391,199,361,338,573,613,378,379,380,381,845,839,840,841,842,836,837,253,-32766,87,88,89,391,843,838,338,597,519,128,80,129,273,332,257,261,47,673,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,799,247,884,108,109,110,226,247,21,-32766,310,-32766,-32766,-32766,642,548,-32766,-32766,-32766,-32766,56,353,-32766,-32766,-32766,55,-32766,-32766,-32766,-32766,-32766,58,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766,557,-32766,-32766,518,-32766,548,890,-32766,390,-32766,228,252,-32766,-32766,-32766,-32766,-32766,275,-32766,234,-32766,587,588,-32766,-32766,-32766,-32766,-32766,-32766,-32766,46,236,-32766,-32766,281,-32766,682,348,-32766,390,-32766,346,333,521,-32766,-32766,-32766,271,911,262,237,446,911,-32766,894,59,700,358,135,548,123,538,35,-32766,333,122,-32766,-32766,-32766,271,-32766,124,-32766,692,-32766,-32766,-32766,-32766,700,273,22,-32766,-32766,-32766,-32766,239,-32766,-32766,612,-32766,548,134,-32766,390,-32766,462,354,-32766,-32766,-32766,-32766,-32766,227,-32766,238,-32766,845,542,-32766,856,611,200,-32766,-32766,-32766,259,280,-32766,-32766,201,-32766,855,129,-32766,390,130,202,333,206,-32766,-32766,-32766,271,-32766,-32766,-32766,125,601,-32766,136,299,700,489,28,548,105,106,107,-32766,498,499,-32766,-32766,-32766,207,-32766,133,-32766,525,-32766,-32766,-32766,-32766,663,664,527,-32766,-32766,-32766,-32766,528,-32766,-32766,610,-32766,548,427,-32766,390,-32766,532,539,-32766,-32766,-32766,-32766,-32766,240,-32766,247,-32766,697,543,-32766,554,523,608,-32766,-32766,-32766,686,535,-32766,-32766,54,-32766,57,60,-32766,390,246,-155,278,345,-32766,-32766,-32766,506,347,-152,471,402,403,-32766,405,404,272,493,416,548,318,417,505,-32766,517,548,-32766,-32766,-32766,549,-32766,562,-32766,916,-32766,-32766,-32766,-32766,564,826,848,-32766,-32766,-32766,-32766,694,-32766,-32766,485,-32766,548,487,-32766,390,-32766,504,802,-32766,-32766,-32766,-32766,-32766,279,-32766,911,-32766,502,492,-32766,413,483,269,-32766,-32766,-32766,243,337,-32766,-32766,418,-32766,454,229,-32766,390,274,373,374,344,-32766,-32766,-32766,360,614,-32766,573,613,378,379,-274,548,615,-332,844,-32766,258,51,-32766,-32766,-32766,270,-32766,346,-32766,52,-32766,260,0,-32766,-333,-32766,-32766,-32766,-32766,-32766,-32766,205,-32766,-32766,49,-32766,548,424,-32766,390,-32766,-266,264,-32766,-32766,-32766,-32766,-32766,409,-32766,343,-32766,265,312,-32766,470,513,-275,-32766,-32766,-32766,920,337,-32766,-32766,530,-32766,531,600,-32766,390,592,373,374,578,581,-32766,-32766,644,629,-32766,573,613,378,379,635,548,636,576,627,-32766,625,693,-32766,-32766,-32766,691,-32766,591,-32766,582,-32766,203,204,-32766,584,583,-32766,-32766,-32766,-32766,586,599,-32766,-32766,589,-32766,690,558,-32766,390,197,683,919,86,520,522,-32766,524,833,834,529,533,-32766,534,537,541,835,48,111,112,113,114,115,116,117,118,119,120,121,127,31,633,337,330,634,585,-32766,32,291,337,330,478,373,374,917,291,891,889,875,373,374,553,613,378,379,737,739,887,553,613,378,379,824,451,675,839,840,841,842,836,837,320,895,277,885,23,33,843,838,556,277,337,330,-32766,34,-32766,555,291,36,37,38,373,374,39,45,50,81,82,83,84,553,613,378,379,-32767,-32767,-32767,-32767,103,104,105,106,107,337,85,131,137,337,138,198,224,225,277,373,374,-332,230,373,374,24,337,231,573,613,378,379,573,613,378,379,373,374,235,248,249,250,337,251,0,573,613,378,379,276,329,331,373,374,-32766,337,574,490,792,337,609,573,613,378,379,373,374,25,300,373,374,319,337,795,573,613,378,379,573,613,378,379,373,374,516,355,359,445,482,796,507,573,613,378,379,508,548,337,890,775,791,337,604,803,808,806,698,373,374,888,807,373,374,-32766,-32766,-32766,573,613,378,379,573,613,378,379,873,832,804,872,851,-32766,809,-32766,-32766,-32766,-32766,805,20,26,29,298,480,515,770,778,827,457,0,900,455,774,0,0,0,874,870,886,823,915,852,869,488,0,391,793,0,338,0,0,0,340,0,273],r.Parser.prototype.yycheck=[2,3,4,5,6,8,9,10,70,11,104,105,106,107,108,109,8,9,10,8,9,24,60,26,27,28,29,30,31,32,33,34,24,7,26,27,28,29,30,41,42,7,123,124,7,47,70,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,144,0,75,68,69,70,25,72,70,74,7,76,77,78,79,7,81,142,83,70,85,72,73,88,8,9,10,92,93,94,95,7,97,98,95,100,7,7,103,104,24,142,26,27,105,106,111,112,113,136,7,7,139,114,115,116,117,122,123,132,125,126,127,128,129,130,131,8,8,9,10,136,137,138,139,140,141,25,143,141,145,142,147,148,24,72,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,144,48,72,44,45,46,30,48,144,64,72,8,9,10,140,70,8,9,10,74,60,25,77,78,79,60,81,24,83,26,85,60,24,88,26,27,28,92,93,94,64,140,97,98,70,100,70,72,103,104,74,145,7,77,78,79,111,81,7,83,30,85,140,140,88,8,9,10,92,93,94,133,134,97,98,145,100,140,7,103,104,24,139,96,141,140,141,111,101,75,75,30,70,75,64,70,60,110,121,12,70,141,25,143,74,96,141,77,78,79,101,81,141,83,140,85,140,141,88,110,145,144,92,93,94,64,7,97,98,142,100,70,141,103,104,74,145,141,77,78,79,111,81,7,83,30,85,132,25,88,132,142,12,92,93,94,120,60,97,98,12,100,148,141,103,104,141,12,96,12,140,141,111,101,8,9,10,141,25,64,90,91,110,65,66,70,41,42,43,74,65,66,77,78,79,12,81,25,83,25,85,140,141,88,123,124,25,92,93,94,64,25,97,98,142,100,70,120,103,104,74,25,25,77,78,79,111,81,30,83,48,85,140,141,88,140,141,30,92,93,94,140,141,97,98,60,100,60,60,103,104,61,72,75,70,140,141,111,67,70,87,99,70,70,64,70,72,102,89,70,70,71,70,70,74,70,70,77,78,79,70,81,70,83,70,85,140,141,88,70,144,70,92,93,94,64,70,97,98,72,100,70,72,103,104,74,72,72,77,78,79,111,81,75,83,75,85,89,86,88,79,101,118,92,93,94,87,95,97,98,87,100,87,87,103,104,118,105,106,95,140,141,111,95,115,64,114,115,116,117,135,70,115,120,132,74,120,140,77,78,79,119,81,139,83,140,85,120,-1,88,120,140,141,92,93,94,64,121,97,98,121,100,70,122,103,104,74,135,135,77,78,79,111,81,139,83,139,85,135,135,88,135,135,135,92,93,94,142,95,97,98,140,100,140,140,103,104,140,105,106,140,140,141,111,140,140,64,114,115,116,117,140,70,140,140,140,74,140,140,77,78,79,140,81,140,83,140,85,41,42,88,140,140,141,92,93,94,140,140,97,98,140,100,140,140,103,104,60,140,142,141,141,141,111,141,68,69,141,141,72,141,141,141,76,12,13,14,15,16,17,18,19,20,21,22,23,141,143,142,95,96,142,140,141,143,101,95,96,142,105,106,142,101,142,142,142,105,106,114,115,116,117,50,51,142,114,115,116,117,142,123,142,125,126,127,128,129,130,131,142,136,142,144,143,137,138,142,136,95,96,143,143,145,142,101,143,143,143,105,106,143,143,143,143,143,143,143,114,115,116,117,35,36,37,38,39,40,41,42,43,95,143,143,143,95,143,143,143,143,136,105,106,120,143,105,106,144,95,143,114,115,116,117,114,115,116,117,105,106,143,143,143,143,95,143,-1,114,115,116,117,143,143,143,105,106,143,95,142,80,146,95,142,114,115,116,117,105,106,144,144,105,106,144,95,142,114,115,116,117,114,115,116,117,105,106,82,144,144,144,144,142,84,114,115,116,117,144,70,95,72,144,144,95,142,144,146,144,142,105,106,146,144,105,106,8,9,10,114,115,116,117,114,115,116,117,144,144,144,144,144,24,104,26,27,28,29,144,144,144,144,144,144,144,144,144,144,144,-1,144,144,144,-1,-1,-1,146,146,146,146,146,146,146,146,-1,136,147,-1,139,-1,-1,-1,143,-1,145],r.Parser.prototype.yybase=[0,574,581,623,655,2,718,402,747,659,672,688,743,701,705,483,483,483,483,483,351,356,366,366,367,366,344,-2,-2,-2,200,200,231,231,231,231,231,231,231,231,200,231,451,482,532,316,370,115,146,285,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,44,474,429,476,481,487,488,739,740,741,734,733,416,736,539,541,342,542,543,552,557,559,536,567,737,755,569,735,738,123,123,123,123,123,123,123,123,123,122,11,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,227,227,173,577,577,577,577,577,577,577,577,577,577,577,79,178,846,8,-3,-3,-3,-3,642,706,706,706,706,157,179,242,431,431,360,431,525,368,767,767,767,767,767,767,767,767,767,767,767,767,350,375,315,315,652,652,-81,-81,-81,-81,251,185,188,184,-62,348,195,195,195,408,392,410,1,192,129,129,129,-24,-24,-24,-24,499,-24,-24,-24,113,108,108,12,161,349,526,271,398,529,438,130,206,265,427,76,414,427,288,295,76,166,44,262,422,141,491,372,494,413,71,92,93,267,135,100,34,415,745,746,742,-38,420,-10,135,147,744,498,107,26,493,144,377,363,369,332,363,400,377,588,377,376,377,360,37,582,376,377,374,376,388,363,364,412,369,377,441,443,390,106,332,377,390,377,400,64,590,591,323,592,589,593,649,608,362,500,399,407,620,625,636,365,354,614,524,425,359,355,423,570,578,357,406,414,394,352,403,531,433,403,653,434,385,417,411,444,310,318,501,425,668,757,380,637,684,403,609,387,87,325,638,382,403,639,403,696,503,615,403,697,384,435,425,352,352,352,700,66,699,583,702,707,704,748,721,749,584,750,358,583,722,751,682,215,613,422,436,389,447,221,257,752,403,403,506,499,403,395,685,397,426,753,392,391,647,683,403,418,754,221,723,587,724,450,568,507,648,509,327,725,353,497,610,454,622,455,461,404,510,373,732,612,247,361,664,463,405,692,641,464,465,511,343,437,335,409,396,665,293,467,468,472,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,0,0,0,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,0,0,0,0,0,0,0,0,0,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,767,767,767,767,767,767,767,767,767,767,767,123,123,123,123,123,123,123,123,0,129,129,129,129,-94,-94,-94,767,767,767,767,767,767,0,0,0,0,0,0,0,0,0,0,0,0,-94,-94,129,129,767,767,-24,-24,-24,-24,-24,108,108,108,-24,108,145,145,145,108,108,108,100,100,0,0,0,0,0,0,0,145,0,0,0,376,0,0,0,145,260,260,221,260,260,135,0,0,425,376,0,364,376,0,0,0,0,0,0,531,0,87,637,241,425,0,0,0,0,0,0,0,425,289,289,306,0,358,0,0,0,306,241,0,0,221],r.Parser.prototype.yydefault=[3,32767,32767,1,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,104,96,110,95,106,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,358,358,122,122,122,122,122,122,122,122,316,32767,32767,32767,32767,32767,32767,32767,32767,32767,173,173,173,32767,348,348,348,348,348,348,348,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,363,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,232,233,235,236,172,125,349,362,171,199,201,250,200,177,182,183,184,185,186,187,188,189,190,191,192,176,229,228,197,313,313,316,32767,32767,32767,32767,32767,32767,32767,32767,198,202,204,203,219,220,217,218,175,221,222,223,224,157,157,157,357,357,32767,357,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,158,32767,211,212,276,276,117,117,117,117,117,32767,32767,32767,32767,284,32767,32767,32767,32767,32767,286,32767,32767,206,207,205,32767,32767,32767,32767,32767,32767,32767,32767,32767,285,32767,32767,32767,32767,32767,32767,32767,32767,334,321,272,32767,32767,32767,265,32767,107,109,32767,32767,32767,32767,302,339,32767,32767,32767,17,32767,32767,32767,370,334,32767,32767,19,32767,32767,32767,32767,227,32767,338,332,32767,32767,32767,32767,32767,32767,63,32767,32767,32767,32767,32767,63,281,63,32767,63,32767,315,287,32767,63,74,32767,72,32767,32767,76,32767,63,93,93,254,315,54,63,254,63,32767,32767,32767,32767,4,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,267,32767,323,32767,337,336,324,32767,265,32767,215,194,266,32767,196,32767,32767,270,273,32767,32767,32767,134,32767,268,180,32767,32767,32767,32767,365,32767,32767,174,32767,32767,32767,130,32767,61,332,32767,32767,355,32767,32767,332,269,208,209,210,32767,121,32767,310,32767,32767,32767,32767,32767,32767,327,32767,333,32767,32767,32767,32767,111,32767,302,32767,32767,32767,75,32767,32767,178,126,32767,32767,364,32767,32767,32767,320,32767,32767,32767,32767,32767,62,32767,32767,77,32767,32767,32767,32767,332,32767,32767,32767,115,32767,169,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,32767,332,32767,32767,32767,32767,32767,32767,32767,4,32767,151,32767,32767,32767,32767,32767,32767,32767,25,25,3,137,3,137,25,101,25,25,137,93,93,25,25,25,144,25,25,25,25,25,25,25,25],r.Parser.prototype.yygoto=[141,141,173,173,173,173,173,173,173,173,141,173,142,143,144,148,153,155,181,175,172,172,172,172,174,174,174,174,174,174,174,168,169,170,171,179,757,758,392,760,781,782,783,784,785,786,787,789,725,145,146,147,149,150,151,152,154,177,178,180,196,208,209,210,211,212,213,214,215,217,218,219,220,244,245,266,267,268,430,431,432,182,183,184,185,186,187,188,189,190,191,192,156,157,158,159,176,160,194,161,162,163,164,195,165,193,139,166,167,452,452,452,452,452,452,452,452,452,452,452,453,453,453,453,453,453,453,453,453,453,453,551,551,551,464,491,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,394,407,552,552,552,810,810,662,662,662,662,662,594,283,595,510,399,399,567,679,632,849,850,863,660,714,426,222,622,622,622,622,223,617,623,494,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,395,465,472,514,904,398,398,425,425,459,425,419,322,421,421,393,396,412,422,428,460,463,473,481,501,5,476,284,327,1,15,2,6,7,550,550,550,8,9,10,668,16,11,17,12,18,13,19,14,704,328,881,881,643,628,626,626,624,626,526,401,652,647,847,847,847,847,847,847,847,847,847,847,847,437,438,441,447,477,479,497,290,910,910,400,400,486,880,880,263,913,910,303,255,723,306,822,821,306,896,896,896,861,304,323,410,913,913,897,316,420,769,658,559,879,671,536,324,466,565,311,311,311,801,241,676,496,439,440,442,444,448,475,631,858,311,285,286,603,495,712,0,406,321,0,0,0,314,0,0,429,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,411],r.Parser.prototype.yygcheck=[15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,35,35,35,35,35,35,35,35,35,35,35,86,86,86,86,86,86,86,86,86,86,86,6,6,6,21,21,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,71,7,7,7,35,35,35,35,35,35,35,29,44,29,35,86,86,12,12,12,12,12,12,12,12,75,40,35,35,35,35,40,35,35,35,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,36,36,36,104,82,82,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,13,42,42,42,2,13,2,13,13,5,5,5,13,13,13,54,13,13,13,13,13,13,13,13,67,67,83,83,5,5,5,5,5,5,5,5,5,5,93,93,93,93,93,93,93,93,93,93,93,52,52,52,52,52,52,52,4,105,105,89,89,94,84,84,92,105,105,26,92,71,4,91,91,4,84,84,84,97,30,70,30,105,105,102,27,30,72,50,10,84,55,46,9,30,11,90,90,90,80,30,56,30,85,85,85,85,85,85,43,96,90,44,44,34,77,69,-1,4,90,-1,-1,-1,4,-1,-1,4,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,71],r.Parser.prototype.yygbase=[0,0,-286,0,10,239,130,154,0,-10,25,-23,-29,-289,0,-30,0,0,0,0,0,83,0,0,0,0,245,84,-11,142,-28,0,0,0,-13,-88,-42,0,0,0,-344,0,-38,-12,-188,0,23,0,0,0,66,0,247,0,205,24,-18,0,0,0,0,0,0,0,0,0,0,13,0,-15,85,74,70,0,0,148,0,-14,0,0,-6,0,-35,11,47,278,-77,0,0,44,68,43,38,72,94,0,-16,109,0,0,0,0,87,0,170,34,0],r.Parser.prototype.yygdefault=[-32768,362,3,546,382,570,571,572,307,305,560,566,467,4,568,140,295,575,296,500,577,414,579,580,308,309,415,315,216,593,503,313,596,357,602,301,449,383,350,461,221,423,456,630,282,638,540,646,649,450,657,352,433,434,667,672,677,680,334,325,474,684,685,256,689,511,512,703,242,711,317,724,342,788,790,397,408,484,797,326,800,384,385,386,387,435,818,815,289,866,287,443,254,853,468,356,903,862,288,388,389,302,898,341,905,912,458],r.Parser.prototype.yylhs=[0,1,2,2,4,4,3,3,3,3,3,3,3,3,3,8,8,10,10,10,10,9,9,11,13,13,14,14,14,14,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,33,33,34,27,27,30,30,6,7,7,7,37,37,37,38,38,41,41,39,39,42,42,22,22,29,29,32,32,31,31,43,23,23,23,23,44,44,45,45,46,46,20,20,16,16,47,18,18,48,17,17,19,19,36,36,49,49,50,50,51,51,51,51,52,52,53,53,54,54,24,24,55,55,55,25,25,56,56,40,40,57,57,57,57,62,62,63,63,64,64,64,64,65,66,66,61,61,58,58,60,60,68,68,67,67,67,67,67,67,59,59,69,69,26,26,21,21,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,71,77,77,79,79,80,81,81,81,81,81,81,86,86,35,35,35,72,72,87,87,82,82,88,88,88,88,88,73,73,73,76,76,76,78,78,93,93,93,93,93,93,93,93,93,93,93,93,93,93,12,12,12,12,12,12,74,74,74,74,94,94,96,96,95,95,97,97,28,28,28,28,99,99,98,98,98,98,98,100,100,84,84,89,89,83,83,101,101,101,101,90,90,90,90,85,85,91,91,91,70,70,102,102,102,75,75,103,103,104,104,104,104,92,92,92,92,105,105,105,105,105,105,105,106,106,106],r.Parser.prototype.yylen=[1,1,2,0,1,3,1,1,1,1,3,5,4,3,3,3,1,1,3,2,4,3,1,3,2,0,1,1,1,1,3,7,10,5,7,9,5,2,3,2,3,2,3,3,3,3,1,2,5,7,8,10,5,1,5,3,3,2,1,2,8,1,3,0,1,9,7,6,5,1,2,2,0,2,0,2,0,2,1,3,1,4,1,4,1,4,1,3,3,3,4,4,5,0,2,4,3,1,1,1,4,0,2,5,0,2,6,0,2,0,3,1,0,1,3,3,5,0,1,1,1,1,0,1,3,1,2,3,1,1,2,4,3,1,1,3,2,0,3,3,8,3,1,3,0,2,4,5,4,4,3,1,1,1,3,1,1,0,1,1,2,1,1,1,1,1,1,1,3,1,3,3,1,0,1,1,6,3,4,4,1,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,5,4,4,4,2,2,4,2,2,2,2,2,2,2,2,2,2,2,1,4,3,3,2,9,10,3,0,4,1,3,2,4,6,8,4,4,4,1,1,1,2,3,1,1,1,1,1,1,0,3,3,4,4,0,2,3,0,1,1,0,3,1,1,1,1,1,1,1,1,1,1,1,3,2,1,1,3,2,2,4,3,1,3,3,3,0,2,0,1,3,1,3,1,1,1,1,1,6,4,3,6,4,4,4,1,3,1,2,1,1,4,1,3,6,4,4,4,4,1,4,0,1,1,3,1,3,1,1,4,0,0,2,3,1,3,1,4,2,2,2,1,2,1,4,3,3,3,6,3,1,1,1],r.Parser.prototype.yyn0=function(){this.yyval=this.yyastk[this.stackPos]},r.Parser.prototype.yyn1=function(e){this.yyval=this.Stmt_Namespace_postprocess(this.yyastk[this.stackPos-0])},r.Parser.prototype.yyn2=function(e){Array.isArray(this.yyastk[this.stackPos-0])?this.yyval=this.yyastk[this.stackPos-1].concat(this.yyastk[this.stackPos-0]):(this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1])},r.Parser.prototype.yyn3=function(e){this.yyval=[]},r.Parser.prototype.yyn4=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn5=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn6=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn7=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn8=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn9=function(e){this.yyval=this.Node_Stmt_HaltCompiler(e)},r.Parser.prototype.yyn10=function(e){this.yyval=this.Node_Stmt_Namespace(this.Node_Name(this.yyastk[this.stackPos-1],e),null,e)},r.Parser.prototype.yyn11=function(e){this.yyval=this.Node_Stmt_Namespace(this.Node_Name(this.yyastk[this.stackPos-3],e),this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn12=function(e){this.yyval=this.Node_Stmt_Namespace(null,this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn13=function(e){this.yyval=this.Node_Stmt_Use(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn14=function(e){this.yyval=this.Node_Stmt_Const(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn15=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn16=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn17=function(e){this.yyval=this.Node_Stmt_UseUse(this.Node_Name(this.yyastk[this.stackPos-0],e),null,e)},r.Parser.prototype.yyn18=function(e){this.yyval=this.Node_Stmt_UseUse(this.Node_Name(this.yyastk[this.stackPos-2],e),this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn19=function(e){this.yyval=this.Node_Stmt_UseUse(this.Node_Name(this.yyastk[this.stackPos-0],e),null,e)},r.Parser.prototype.yyn20=function(e){this.yyval=this.Node_Stmt_UseUse(this.Node_Name(this.yyastk[this.stackPos-2],e),this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn21=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn22=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn23=function(e){this.yyval=this.Node_Const(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn24=function(e){Array.isArray(this.yyastk[this.stackPos-0])?this.yyval=this.yyastk[this.stackPos-1].concat(this.yyastk[this.stackPos-0]):(this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1])},r.Parser.prototype.yyn25=function(e){this.yyval=[]},r.Parser.prototype.yyn26=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn27=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn28=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn29=function(e){throw new Error("__halt_compiler() can only be used from the outermost scope")},r.Parser.prototype.yyn30=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn31=function(e){this.yyval=this.Node_Stmt_If(this.yyastk[this.stackPos-4],{stmts:Array.isArray(this.yyastk[this.stackPos-2])?this.yyastk[this.stackPos-2]:[this.yyastk[this.stackPos-2]],elseifs:this.yyastk[this.stackPos-1],Else:this.yyastk[this.stackPos-0]},e)},r.Parser.prototype.yyn32=function(e){this.yyval=this.Node_Stmt_If(this.yyastk[this.stackPos-7],{stmts:this.yyastk[this.stackPos-4],elseifs:this.yyastk[this.stackPos-3],"else":this.yyastk[this.stackPos-2]},e)},r.Parser.prototype.yyn33=function(e){this.yyval=this.Node_Stmt_While(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn34=function(e){this.yyval=this.Node_Stmt_Do(this.yyastk[this.stackPos-2],Array.isArray(this.yyastk[this.stackPos-5])?this.yyastk[this.stackPos-5]:[this.yyastk[this.stackPos-5]],e)},r.Parser.prototype.yyn35=function(e){this.yyval=this.Node_Stmt_For({init:this.yyastk[this.stackPos-6],cond:this.yyastk[this.stackPos-4],loop:this.yyastk[this.stackPos-2],stmts:this.yyastk[this.stackPos-0]},e)},r.Parser.prototype.yyn36=function(e){this.yyval=this.Node_Stmt_Switch(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn37=function(e){this.yyval=this.Node_Stmt_Break(null,e)},r.Parser.prototype.yyn38=function(e){this.yyval=this.Node_Stmt_Break(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn39=function(e){this.yyval=this.Node_Stmt_Continue(null,e)},r.Parser.prototype.yyn40=function(e){this.yyval=this.Node_Stmt_Continue(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn41=function(e){this.yyval=this.Node_Stmt_Return(null,e)},r.Parser.prototype.yyn42=function(e){this.yyval=this.Node_Stmt_Return(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn43=function(e){this.yyval=this.Node_Stmt_Global(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn44=function(e){this.yyval=this.Node_Stmt_Static(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn45=function(e){this.yyval=this.Node_Stmt_Echo(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn46=function(e){this.yyval=this.Node_Stmt_InlineHTML(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn47=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn48=function(e){this.yyval=this.Node_Stmt_Unset(this.yyastk[this.stackPos-2],e)},r.Parser.prototype.yyn49=function(e){this.yyval=this.Node_Stmt_Foreach(this.yyastk[this.stackPos-4],this.yyastk[this.stackPos-2],{keyVar:null,byRef:!1,stmts:this.yyastk[this.stackPos-0]},e)},r.Parser.prototype.yyn50=function(e){this.yyval=this.Node_Stmt_Foreach(this.yyastk[this.stackPos-5],this.yyastk[this.stackPos-2],{keyVar:null,byRef:!0,stmts:this.yyastk[this.stackPos-0]},e)},r.Parser.prototype.yyn51=function(e){this.yyval=this.Node_Stmt_Foreach(this.yyastk[this.stackPos-7],this.yyastk[this.stackPos-2],{keyVar:this.yyastk[this.stackPos-5],byRef:this.yyastk[this.stackPos-3],stmts:this.yyastk[this.stackPos-0]},e)},r.Parser.prototype.yyn52=function(e){this.yyval=this.Node_Stmt_Declare(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn53=function(e){this.yyval=[]},r.Parser.prototype.yyn54=function(e){this.yyval=this.Node_Stmt_TryCatch(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn55=function(e){this.yyval=this.Node_Stmt_Throw(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn56=function(e){this.yyval=this.Node_Stmt_Goto(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn57=function(e){this.yyval=this.Node_Stmt_Label(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn58=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn59=function(e){this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn60=function(e){this.yyval=this.Node_Stmt_Catch(this.yyastk[this.stackPos-5],this.yyastk[this.stackPos-4].substring(1),this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn61=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn62=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn63=function(e){this.yyval=!1},r.Parser.prototype.yyn64=function(e){this.yyval=!0},r.Parser.prototype.yyn65=function(e){this.yyval=this.Node_Stmt_Function(this.yyastk[this.stackPos-6],{byRef:this.yyastk[this.stackPos-7],params:this.yyastk[this.stackPos-4],stmts:this.yyastk[this.stackPos-1]},e)},r.Parser.prototype.yyn66=function(e){this.yyval=this.Node_Stmt_Class(this.yyastk[this.stackPos-5],{type:this.yyastk[this.stackPos-6],Extends:this.yyastk[this.stackPos-4],Implements:this.yyastk[this.stackPos-3],stmts:this.yyastk[this.stackPos-1]},e)},r.Parser.prototype.yyn67=function(e){this.yyval=this.Node_Stmt_Interface(this.yyastk[this.stackPos-4],{Extends:this.yyastk[this.stackPos-3],stmts:this.yyastk[this.stackPos-1]},e)},r.Parser.prototype.yyn68=function(e){this.yyval=this.Node_Stmt_Trait(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn69=function(e){this.yyval=0},r.Parser.prototype.yyn70=function(e){this.yyval=this.MODIFIER_ABSTRACT},r.Parser.prototype.yyn71=function(e){this.yyval=this.MODIFIER_FINAL},r.Parser.prototype.yyn72=function(e){this.yyval=null},r.Parser.prototype.yyn73=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn74=function(e){this.yyval=[]},r.Parser.prototype.yyn75=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn76=function(e){this.yyval=[]},r.Parser.prototype.yyn77=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn78=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn79=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn80=function(e){this.yyval=Array.isArray(this.yyastk[this.stackPos-0])?this.yyastk[this.stackPos-0]:[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn81=function(e){this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn82=function(e){this.yyval=Array.isArray(this.yyastk[this.stackPos-0])?this.yyastk[this.stackPos-0]:[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn83=function(e){this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn84=function(e){this.yyval=Array.isArray(this.yyastk[this.stackPos-0])?this.yyastk[this.stackPos-0]:[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn85=function(e){this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn86=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn87=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn88=function(e){this.yyval=this.Node_Stmt_DeclareDeclare(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn89=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn90=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn91=function(e){this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn92=function(e){this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn93=function(e){this.yyval=[]},r.Parser.prototype.yyn94=function(e){this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn95=function(e){this.yyval=this.Node_Stmt_Case(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn96=function(e){this.yyval=this.Node_Stmt_Case(null,this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn97=function(){this.yyval=this.yyastk[this.stackPos]},r.Parser.prototype.yyn98=function(){this.yyval=this.yyastk[this.stackPos]},r.Parser.prototype.yyn99=function(e){this.yyval=Array.isArray(this.yyastk[this.stackPos-0])?this.yyastk[this.stackPos-0]:[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn100=function(e){this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn101=function(e){this.yyval=[]},r.Parser.prototype.yyn102=function(e){this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn103=function(e){this.yyval=this.Node_Stmt_ElseIf(this.yyastk[this.stackPos-2],Array.isArray(this.yyastk[this.stackPos-0])?this.yyastk[this.stackPos-0]:[this.yyastk[this.stackPos-0]],e)},r.Parser.prototype.yyn104=function(e){this.yyval=[]},r.Parser.prototype.yyn105=function(e){this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn106=function(e){this.yyval=this.Node_Stmt_ElseIf(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn107=function(e){this.yyval=null},r.Parser.prototype.yyn108=function(e){this.yyval=this.Node_Stmt_Else(Array.isArray(this.yyastk[this.stackPos-0])?this.yyastk[this.stackPos-0]:[this.yyastk[this.stackPos-0]],e)},r.Parser.prototype.yyn109=function(e){this.yyval=null},r.Parser.prototype.yyn110=function(e){this.yyval=this.Node_Stmt_Else(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn111=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn112=function(e){this.yyval=[]},r.Parser.prototype.yyn113=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn114=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn115=function(e){this.yyval=this.Node_Param(this.yyastk[this.stackPos-0].substring(1),null,this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn116=function(e){this.yyval=this.Node_Param(this.yyastk[this.stackPos-2].substring(1),this.yyastk[this.stackPos-0],this.yyastk[this.stackPos-4],this.yyastk[this.stackPos-3],e)},r.Parser.prototype.yyn117=function(e){this.yyval=null},r.Parser.prototype.yyn118=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn119=function(e){this.yyval="array"},r.Parser.prototype.yyn120=function(e){this.yyval="callable"},r.Parser.prototype.yyn121=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn122=function(e){this.yyval=[]},r.Parser.prototype.yyn123=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn124=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn125=function(e){this.yyval=this.Node_Arg(this.yyastk[this.stackPos-0],!1,e)},r.Parser.prototype.yyn126=function(e){this.yyval=this.Node_Arg(this.yyastk[this.stackPos-0],!0,e)},r.Parser.prototype.yyn127=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn128=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn129=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-0].substring(1),e)},r.Parser.prototype.yyn130=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn131=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn132=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn133=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn134=function(e){this.yyval=this.Node_Stmt_StaticVar(this.yyastk[this.stackPos-0].substring(1),null,e)},r.Parser.prototype.yyn135=function(e){this.yyval=this.Node_Stmt_StaticVar(this.yyastk[this.stackPos-2].substring(1),this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn136=function(e){this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn137=function(e){this.yyval=[]},r.Parser.prototype.yyn138=function(e){this.yyval=this.Node_Stmt_Property(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn139=function(e){this.yyval=this.Node_Stmt_ClassConst(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn140=function(e){this.yyval=this.Node_Stmt_ClassMethod(this.yyastk[this.stackPos-4],{type:this.yyastk[this.stackPos-7],byRef:this.yyastk[this.stackPos-5],params:this.yyastk[this.stackPos-2],stmts:this.yyastk[this.stackPos-0]},e)},r.Parser.prototype.yyn141=function(e){this.yyval=this.Node_Stmt_TraitUse(this.yyastk[this.stackPos-1],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn142=function(e){this.yyval=[]},r.Parser.prototype.yyn143=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn144=function(e){this.yyval=[]},r.Parser.prototype.yyn145=function(e){this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn146=function(e){this.yyval=this.Node_Stmt_TraitUseAdaptation_Precedence(this.yyastk[this.stackPos-3][0],this.yyastk[this.stackPos-3][1],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn147=function(e){this.yyval=this.Node_Stmt_TraitUseAdaptation_Alias(this.yyastk[this.stackPos-4][0],this.yyastk[this.stackPos-4][1],this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn148=function(e){this.yyval=this.Node_Stmt_TraitUseAdaptation_Alias(this.yyastk[this.stackPos-3][0],this.yyastk[this.stackPos-3][1],this.yyastk[this.stackPos-1],null,e)},r.Parser.prototype.yyn149=function(e){this.yyval=this.Node_Stmt_TraitUseAdaptation_Alias(this.yyastk[this.stackPos-3][0],this.yyastk[this.stackPos-3][1],null,this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn150=function(e){this.yyval=array(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0])},r.Parser.prototype.yyn151=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn152=function(e){this.yyval=array(null,this.yyastk[this.stackPos-0])},r.Parser.prototype.yyn153=function(e){this.yyval=null},r.Parser.prototype.yyn154=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn155=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn156=function(e){this.yyval=this.MODIFIER_PUBLIC},r.Parser.prototype.yyn157=function(e){this.yyval=this.MODIFIER_PUBLIC},r.Parser.prototype.yyn158=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn159=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn160=function(e){this.Stmt_Class_verifyModifier(this.yyastk[this.stackPos-1],this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1]|this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn161=function(e){this.yyval=this.MODIFIER_PUBLIC},r.Parser.prototype.yyn162=function(e){this.yyval=this.MODIFIER_PROTECTED},r.Parser.prototype.yyn163=function(e){this.yyval=this.MODIFIER_PRIVATE},r.Parser.prototype.yyn164=function(e){this.yyval=this.MODIFIER_STATIC},r.Parser.prototype.yyn165=function(e){this.yyval=this.MODIFIER_ABSTRACT},r.Parser.prototype.yyn166=function(e){this.yyval=this.MODIFIER_FINAL},r.Parser.prototype.yyn167=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn168=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn169=function(e){this.yyval=this.Node_Stmt_PropertyProperty(this.yyastk[this.stackPos-0].substring(1),null,e)},r.Parser.prototype.yyn170=function(e){this.yyval=this.Node_Stmt_PropertyProperty(this.yyastk[this.stackPos-2].substring(1),this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn171=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn172=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn173=function(e){this.yyval=[]},r.Parser.prototype.yyn174=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn175=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn176=function(e){this.yyval=this.Node_Expr_AssignList(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn177=function(e){this.yyval=this.Node_Expr_Assign(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn178=function(e){this.yyval=this.Node_Expr_AssignRef(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn179=function(e){this.yyval=this.Node_Expr_AssignRef(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn180=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn181=function(e){this.yyval=this.Node_Expr_Clone(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn182=function(e){this.yyval=this.Node_Expr_AssignPlus(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn183=function(e){this.yyval=this.Node_Expr_AssignMinus(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn184=function(e){this.yyval=this.Node_Expr_AssignMul(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn185=function(e){this.yyval=this.Node_Expr_AssignDiv(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn186=function(e){this.yyval=this.Node_Expr_AssignConcat(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn187=function(e){this.yyval=this.Node_Expr_AssignMod(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn188=function(e){this.yyval=this.Node_Expr_AssignBitwiseAnd(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn189=function(e){this.yyval=this.Node_Expr_AssignBitwiseOr(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn190=function(e){this.yyval=this.Node_Expr_AssignBitwiseXor(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn191=function(e){this.yyval=this.Node_Expr_AssignShiftLeft(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn192=function(e){this.yyval=this.Node_Expr_AssignShiftRight(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn193=function(e){this.yyval=this.Node_Expr_PostInc(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn194=function(e){this.yyval=this.Node_Expr_PreInc(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn195=function(e){this.yyval=this.Node_Expr_PostDec(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn196=function(e){this.yyval=this.Node_Expr_PreDec(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn197=function(e){this.yyval=this.Node_Expr_BooleanOr(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn198=function(e){this.yyval=this.Node_Expr_BooleanAnd(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn199=function(e){this.yyval=this.Node_Expr_LogicalOr(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn200=function(e){this.yyval=this.Node_Expr_LogicalAnd(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn201=function(e){this.yyval=this.Node_Expr_LogicalXor(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn202=function(e){this.yyval=this.Node_Expr_BitwiseOr(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn203=function(e){this.yyval=this.Node_Expr_BitwiseAnd(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn204=function(e){this.yyval=this.Node_Expr_BitwiseXor(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn205=function(e){this.yyval=this.Node_Expr_Concat(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn206=function(e){this.yyval=this.Node_Expr_Plus(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn207=function(e){this.yyval=this.Node_Expr_Minus(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn208=function(e){this.yyval=this.Node_Expr_Mul(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn209=function(e){this.yyval=this.Node_Expr_Div(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn210=function(e){this.yyval=this.Node_Expr_Mod(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn211=function(e){this.yyval=this.Node_Expr_ShiftLeft(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn212=function(e){this.yyval=this.Node_Expr_ShiftRight(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn213=function(e){this.yyval=this.Node_Expr_UnaryPlus(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn214=function(e){this.yyval=this.Node_Expr_UnaryMinus(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn215=function(e){this.yyval=this.Node_Expr_BooleanNot(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn216=function(e){this.yyval=this.Node_Expr_BitwiseNot(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn217=function(e){this.yyval=this.Node_Expr_Identical(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn218=function(e){this.yyval=this.Node_Expr_NotIdentical(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn219=function(e){this.yyval=this.Node_Expr_Equal(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn220=function(e){this.yyval=this.Node_Expr_NotEqual(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn221=function(e){this.yyval=this.Node_Expr_Smaller(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn222=function(e){this.yyval=this.Node_Expr_SmallerOrEqual(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn223=function(e){this.yyval=this.Node_Expr_Greater(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn224=function(e){this.yyval=this.Node_Expr_GreaterOrEqual(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn225=function(e){this.yyval=this.Node_Expr_Instanceof(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn226=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn227=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn228=function(e){this.yyval=this.Node_Expr_Ternary(this.yyastk[this.stackPos-4],this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn229=function(e){this.yyval=this.Node_Expr_Ternary(this.yyastk[this.stackPos-3],null,this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn230=function(e){this.yyval=this.Node_Expr_Isset(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn231=function(e){this.yyval=this.Node_Expr_Empty(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn232=function(e){this.yyval=this.Node_Expr_Include(this.yyastk[this.stackPos-0],"Node_Expr_Include",e)},r.Parser.prototype.yyn233=function(e){this.yyval=this.Node_Expr_Include(this.yyastk[this.stackPos-0],"Node_Expr_IncludeOnce",e)},r.Parser.prototype.yyn234=function(e){this.yyval=this.Node_Expr_Eval(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn235=function(e){this.yyval=this.Node_Expr_Include(this.yyastk[this.stackPos-0],"Node_Expr_Require",e)},r.Parser.prototype.yyn236=function(e){this.yyval=this.Node_Expr_Include(this.yyastk[this.stackPos-0],"Node_Expr_RequireOnce",e)},r.Parser.prototype.yyn237=function(e){this.yyval=this.Node_Expr_Cast_Int(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn238=function(e){this.yyval=this.Node_Expr_Cast_Double(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn239=function(e){this.yyval=this.Node_Expr_Cast_String(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn240=function(e){this.yyval=this.Node_Expr_Cast_Array(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn241=function(e){this.yyval=this.Node_Expr_Cast_Object(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn242=function(e){this.yyval=this.Node_Expr_Cast_Bool(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn243=function(e){this.yyval=this.Node_Expr_Cast_Unset(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn244=function(e){this.yyval=this.Node_Expr_Exit(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn245=function(e){this.yyval=this.Node_Expr_ErrorSuppress(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn246=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn247=function(e){this.yyval=this.Node_Expr_Array(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn248=function(e){this.yyval=this.Node_Expr_Array(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn249=function(e){this.yyval=this.Node_Expr_ShellExec(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn250=function(e){this.yyval=this.Node_Expr_Print(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn251=function(e){this.yyval=this.Node_Expr_Closure({"static":!1,byRef:this.yyastk[this.stackPos-7],params:this.yyastk[this.stackPos-5],uses:this.yyastk[this.stackPos-3],stmts:this.yyastk[this.stackPos-1]},e)},r.Parser.prototype.yyn252=function(e){this.yyval=this.Node_Expr_Closure({"static":!0,byRef:this.yyastk[this.stackPos-7],params:this.yyastk[this.stackPos-5],uses:this.yyastk[this.stackPos-3],stmts:this.yyastk[this.stackPos-1]},e)},r.Parser.prototype.yyn253=function(e){this.yyval=this.Node_Expr_New(this.yyastk[this.stackPos-1],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn254=function(e){this.yyval=[]},r.Parser.prototype.yyn255=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn256=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn257=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn258=function(e){this.yyval=this.Node_Expr_ClosureUse(this.yyastk[this.stackPos-0].substring(1),this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn259=function(e){this.yyval=this.Node_Expr_FuncCall(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn260=function(e){this.yyval=this.Node_Expr_StaticCall(this.yyastk[this.stackPos-5],this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn261=function(e){this.yyval=this.Node_Expr_StaticCall(this.yyastk[this.stackPos-7],this.yyastk[this.stackPos-4],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn262=function(e){if(this.yyastk[this.stackPos-3].type==="Node_Expr_StaticPropertyFetch")this.yyval=this.Node_Expr_StaticCall(this.yyastk[this.stackPos-3].Class,this.Node_Expr_Variable(this.yyastk[this.stackPos-3].name,e),this.yyastk[this.stackPos-1],e);else{if(this.yyastk[this.stackPos-3].type!=="Node_Expr_ArrayDimFetch")throw new Exception;var t=this.yyastk[this.stackPos-3];while(t.variable.type==="Node_Expr_ArrayDimFetch")t=t.variable;this.yyval=this.Node_Expr_StaticCall(t.variable.Class,this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e),t.variable=this.Node_Expr_Variable(t.variable.name,e)}},r.Parser.prototype.yyn263=function(e){this.yyval=this.Node_Expr_FuncCall(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn264=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn265=function(e){this.yyval=this.Node_Name("static",e)},r.Parser.prototype.yyn266=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn267=function(e){this.yyval=this.Node_Name(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn268=function(e){this.yyval=this.Node_Name_FullyQualified(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn269=function(e){this.yyval=this.Node_Name_Relative(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn270=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn271=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn272=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn273=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn274=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn275=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn276=function(){this.yyval=this.yyastk[this.stackPos]},r.Parser.prototype.yyn277=function(e){this.yyval=this.Node_Expr_PropertyFetch(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn278=function(e){this.yyval=this.Node_Expr_PropertyFetch(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn279=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn280=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn281=function(e){this.yyval=null},r.Parser.prototype.yyn282=function(e){this.yyval=null},r.Parser.prototype.yyn283=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn284=function(e){this.yyval=[]},r.Parser.prototype.yyn285=function(e){this.yyval=[this.Scalar_String_parseEscapeSequences(this.yyastk[this.stackPos-0],"`")]},r.Parser.prototype.yyn286=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn287=function(e){this.yyval=[]},r.Parser.prototype.yyn288=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn289=function(e){this.yyval=this.Node_Scalar_LNumber(this.Scalar_LNumber_parse(this.yyastk[this.stackPos-0]),e)},r.Parser.prototype.yyn290=function(e){this.yyval=this.Node_Scalar_DNumber(this.Scalar_DNumber_parse(this.yyastk[this.stackPos-0]),e)},r.Parser.prototype.yyn291=function(e){this.yyval=this.Scalar_String_create(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn292=function(e){this.yyval={type:"Node_Scalar_LineConst",attributes:e}},r.Parser.prototype.yyn293=function(e){this.yyval={type:"Node_Scalar_FileConst",attributes:e}},r.Parser.prototype.yyn294=function(e){this.yyval={type:"Node_Scalar_DirConst",attributes:e}},r.Parser.prototype.yyn295=function(e){this.yyval={type:"Node_Scalar_ClassConst",attributes:e}},r.Parser.prototype.yyn296=function(e){this.yyval={type:"Node_Scalar_TraitConst",attributes:e}},r.Parser.prototype.yyn297=function(e){this.yyval={type:"Node_Scalar_MethodConst",attributes:e}},r.Parser.prototype.yyn298=function(e){this.yyval={type:"Node_Scalar_FuncConst",attributes:e}},r.Parser.prototype.yyn299=function(e){this.yyval={type:"Node_Scalar_NSConst",attributes:e}},r.Parser.prototype.yyn300=function(e){this.yyval=this.Node_Scalar_String(this.Scalar_String_parseDocString(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-1]),e)},r.Parser.prototype.yyn301=function(e){this.yyval=this.Node_Scalar_String("",e)},r.Parser.prototype.yyn302=function(e){this.yyval=this.Node_Expr_ConstFetch(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn303=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn304=function(e){this.yyval=this.Node_Expr_ClassConstFetch(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn305=function(e){this.yyval=this.Node_Expr_UnaryPlus(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn306=function(e){this.yyval=this.Node_Expr_UnaryMinus(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn307=function(e){this.yyval=this.Node_Expr_Array(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn308=function(e){this.yyval=this.Node_Expr_Array(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn309=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn310=function(e){this.yyval=this.Node_Expr_ClassConstFetch(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn311=function(e){this.yyval=this.Node_Scalar_Encapsed(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn312=function(e){this.yyval=this.Node_Scalar_Encapsed(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn313=function(e){this.yyval=[]},r.Parser.prototype.yyn314=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn315=function(){this.yyval=this.yyastk[this.stackPos]},r.Parser.prototype.yyn316=function(){this.yyval=this.yyastk[this.stackPos]},r.Parser.prototype.yyn317=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn318=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn319=function(e){this.yyval=this.Node_Expr_ArrayItem(this.yyastk[this.stackPos-0],this.yyastk[this.stackPos-2],!1,e)},r.Parser.prototype.yyn320=function(e){this.yyval=this.Node_Expr_ArrayItem(this.yyastk[this.stackPos-0],null,!1,e)},r.Parser.prototype.yyn321=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn322=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn323=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn324=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn325=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-4],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn326=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn327=function(e){this.yyval=this.Node_Expr_PropertyFetch(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn328=function(e){this.yyval=this.Node_Expr_MethodCall(this.yyastk[this.stackPos-5],this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn329=function(e){this.yyval=this.Node_Expr_FuncCall(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn330=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn331=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn332=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn333=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn334=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn335=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn336=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn337=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn338=function(e){this.yyval=this.Node_Expr_StaticPropertyFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn339=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn340=function(e){this.yyval=this.Node_Expr_StaticPropertyFetch(this.yyastk[this.stackPos-2],this.yyastk[this.stackPos-0].substring(1),e)},r.Parser.prototype.yyn341=function(e){this.yyval=this.Node_Expr_StaticPropertyFetch(this.yyastk[this.stackPos-5],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn342=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn343=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn344=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn345=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.yyastk[this.stackPos-3],this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn346=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-0].substring(1),e)},r.Parser.prototype.yyn347=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn348=function(e){this.yyval=null},r.Parser.prototype.yyn349=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn350=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn351=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn352=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn353=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn354=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn355=function(e){this.yyval=this.yyastk[this.stackPos-0]},r.Parser.prototype.yyn356=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn357=function(e){this.yyval=null},r.Parser.prototype.yyn358=function(e){this.yyval=[]},r.Parser.prototype.yyn359=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn360=function(e){this.yyastk[this.stackPos-2].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-2]},r.Parser.prototype.yyn361=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn362=function(e){this.yyval=this.Node_Expr_ArrayItem(this.yyastk[this.stackPos-0],this.yyastk[this.stackPos-2],!1,e)},r.Parser.prototype.yyn363=function(e){this.yyval=this.Node_Expr_ArrayItem(this.yyastk[this.stackPos-0],null,!1,e)},r.Parser.prototype.yyn364=function(e){this.yyval=this.Node_Expr_ArrayItem(this.yyastk[this.stackPos-0],this.yyastk[this.stackPos-3],!0,e)},r.Parser.prototype.yyn365=function(e){this.yyval=this.Node_Expr_ArrayItem(this.yyastk[this.stackPos-0],null,!0,e)},r.Parser.prototype.yyn366=function(e){this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn367=function(e){this.yyastk[this.stackPos-1].push(this.yyastk[this.stackPos-0]),this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn368=function(e){this.yyval=[this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn369=function(e){this.yyval=[this.yyastk[this.stackPos-1],this.yyastk[this.stackPos-0]]},r.Parser.prototype.yyn370=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-0].substring(1),e)},r.Parser.prototype.yyn371=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.Node_Expr_Variable(this.yyastk[this.stackPos-3].substring(1),e),this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn372=function(e){this.yyval=this.Node_Expr_PropertyFetch(this.Node_Expr_Variable(this.yyastk[this.stackPos-2].substring(1),e),this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn373=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn374=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-1],e)},r.Parser.prototype.yyn375=function(e){this.yyval=this.Node_Expr_ArrayDimFetch(this.Node_Expr_Variable(this.yyastk[this.stackPos-4],e),this.yyastk[this.stackPos-2],e)},r.Parser.prototype.yyn376=function(e){this.yyval=this.yyastk[this.stackPos-1]},r.Parser.prototype.yyn377=function(e){this.yyval=this.Node_Scalar_String(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn378=function(e){this.yyval=this.Node_Scalar_String(this.yyastk[this.stackPos-0],e)},r.Parser.prototype.yyn379=function(e){this.yyval=this.Node_Expr_Variable(this.yyastk[this.stackPos-0].substring(1),e)},r.Parser.prototype.Stmt_Namespace_postprocess=function(e){return e},r.Parser.prototype.Node_Stmt_Echo=function(){return{type:"Node_Stmt_Echo",exprs:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_If=function(){return{type:"Node_Stmt_If",cond:arguments[0],stmts:arguments[1].stmts,elseifs:arguments[1].elseifs,Else:arguments[1].Else||null,attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_For=function(){return{type:"Node_Stmt_For",init:arguments[0].init,cond:arguments[0].cond,loop:arguments[0].loop,stmts:arguments[0].stmts,attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_Function=function(){return{type:"Node_Stmt_Function",name:arguments[0],byRef:arguments[1].byRef,params:arguments[1].params,stmts:arguments[1].stmts,attributes:arguments[2]}},r.Parser.prototype.Stmt_Class_verifyModifier=function(){},r.Parser.prototype.Node_Stmt_Namespace=function(){return{type:"Node_Stmt_Namespace",name:arguments[0],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Use=function(){return{type:"Node_Stmt_Use",name:arguments[0],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_UseUse=function(){return{type:"Node_Stmt_UseUse",name:arguments[0],as:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_TraitUseAdaptation_Precedence=function(){return{type:"Node_Stmt_TraitUseAdaptation_Precedence",name:arguments[0],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_TraitUseAdaptation_Alias=function(){return{type:"Node_Stmt_TraitUseAdaptation_Alias",name:arguments[0],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Trait=function(){return{type:"Node_Stmt_Trait",name:arguments[0],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_TraitUse=function(){return{type:"Node_Stmt_TraitUse",name:arguments[0],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Class=function(){return{type:"Node_Stmt_Class",name:arguments[0],Type:arguments[1].type,Extends:arguments[1].Extends,Implements:arguments[1].Implements,stmts:arguments[1].stmts,attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_ClassMethod=function(){return{type:"Node_Stmt_ClassMethod",name:arguments[0],Type:arguments[1].type,byRef:arguments[1].byRef,params:arguments[1].params,stmts:arguments[1].stmts,attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_ClassConst=function(){return{type:"Node_Stmt_ClassConst",consts:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_Interface=function(){return{type:"Node_Stmt_Interface",name:arguments[0],Extends:arguments[1].Extends,stmts:arguments[1].stmts,attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Throw=function(){return{type:"Node_Stmt_Throw",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_Catch=function(){return{type:"Node_Stmt_Catch",Type:arguments[0],variable:arguments[1],stmts:arguments[2],attributes:arguments[3]}},r.Parser.prototype.Node_Stmt_TryCatch=function(){return{type:"Node_Stmt_TryCatch",stmts:arguments[0],catches:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Foreach=function(){return{type:"Node_Stmt_Foreach",expr:arguments[0],valueVar:arguments[1],keyVar:arguments[2].keyVar,byRef:arguments[2].byRef,stmts:arguments[2].stmts,attributes:arguments[3]}},r.Parser.prototype.Node_Stmt_While=function(){return{type:"Node_Stmt_While",cond:arguments[0],stmts:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Do=function(){return{type:"Node_Stmt_Do",cond:arguments[0],stmts:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Break=function(){return{type:"Node_Stmt_Break",num:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_Continue=function(){return{type:"Node_Stmt_Continue",num:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_Return=function(){return{type:"Node_Stmt_Return",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_Case=function(){return{type:"Node_Stmt_Case",cond:arguments[0],stmts:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Switch=function(){return{type:"Node_Stmt_Switch",cond:arguments[0],cases:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Else=function(){return{type:"Node_Stmt_Else",stmts:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_ElseIf=function(){return{type:"Node_Stmt_ElseIf",cond:arguments[0],stmts:arguments[1],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_InlineHTML=function(){return{type:"Node_Stmt_InlineHTML",value:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_StaticVar=function(){return{type:"Node_Stmt_StaticVar",name:arguments[0],def:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Static=function(){return{type:"Node_Stmt_Static",vars:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_Global=function(){return{type:"Node_Stmt_Global",vars:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Stmt_PropertyProperty=function(){return{type:"Node_Stmt_PropertyProperty",name:arguments[0],def:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Property=function(){return{type:"Node_Stmt_Property",Type:arguments[0],props:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Stmt_Unset=function(){return{type:"Node_Stmt_Unset",variables:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Variable=function(e){return{type:"Node_Expr_Variable",name:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_FuncCall=function(){return{type:"Node_Expr_FuncCall",func:arguments[0],args:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_MethodCall=function(){return{type:"Node_Expr_MethodCall",variable:arguments[0],name:arguments[1],args:arguments[2],attributes:arguments[3]}},r.Parser.prototype.Node_Expr_StaticCall=function(){return{type:"Node_Expr_StaticCall",Class:arguments[0],func:arguments[1],args:arguments[2],attributes:arguments[3]}},r.Parser.prototype.Node_Expr_Ternary=function(){return{type:"Node_Expr_Ternary",cond:arguments[0],If:arguments[1],Else:arguments[2],attributes:arguments[3]}},r.Parser.prototype.Node_Expr_AssignList=function(){return{type:"Node_Expr_AssignList",assignList:arguments[0],expr:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Assign=function(){return{type:"Node_Expr_Assign",variable:arguments[0],expr:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_AssignConcat=function(){return{type:"Node_Expr_AssignConcat",variable:arguments[0],expr:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_AssignMinus=function(){return{type:"Node_Expr_AssignMinus",variable:arguments[0],expr:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_AssignPlus=function(){return{type:"Node_Expr_AssignPlus",variable:arguments[0],expr:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_AssignDiv=function(){return{type:"Node_Expr_AssignDiv",variable:arguments[0],expr:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_AssignRef=function(){return{type:"Node_Expr_AssignRef",variable:arguments[0],refVar:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_AssignMul=function(){return{type:"Node_Expr_AssignMul",variable:arguments[0],expr:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_AssignMod=function(){return{type:"Node_Expr_AssignMod",variable:arguments[0],expr:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Plus=function(){return{type:"Node_Expr_Plus",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Minus=function(){return{type:"Node_Expr_Minus",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Mul=function(){return{type:"Node_Expr_Mul",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Div=function(){return{type:"Node_Expr_Div",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Mod=function(){return{type:"Node_Expr_Mod",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Greater=function(){return{type:"Node_Expr_Greater",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Equal=function(){return{type:"Node_Expr_Equal",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_NotEqual=function(){return{type:"Node_Expr_NotEqual",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Identical=function(){return{type:"Node_Expr_Identical",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_NotIdentical=function(){return{type:"Node_Expr_NotIdentical",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_GreaterOrEqual=function(){return{type:"Node_Expr_GreaterOrEqual",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_SmallerOrEqual=function(){return{type:"Node_Expr_SmallerOrEqual",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Concat=function(){return{type:"Node_Expr_Concat",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Smaller=function(){return{type:"Node_Expr_Smaller",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_PostInc=function(){return{type:"Node_Expr_PostInc",variable:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_PostDec=function(){return{type:"Node_Expr_PostDec",variable:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_PreInc=function(){return{type:"Node_Expr_PreInc",variable:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_PreDec=function(){return{type:"Node_Expr_PreDec",variable:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Include=function(){return{expr:arguments[0],type:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_ArrayDimFetch=function(){return{type:"Node_Expr_ArrayDimFetch",variable:arguments[0],dim:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_StaticPropertyFetch=function(){return{type:"Node_Expr_StaticPropertyFetch",Class:arguments[0],name:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_ClassConstFetch=function(){return{type:"Node_Expr_ClassConstFetch",Class:arguments[0],name:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_StaticPropertyFetch=function(){return{type:"Node_Expr_StaticPropertyFetch",Class:arguments[0],name:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_ConstFetch=function(){return{type:"Node_Expr_ConstFetch",name:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_ArrayItem=function(){return{type:"Node_Expr_ArrayItem",value:arguments[0],key:arguments[1],byRef:arguments[2],attributes:arguments[3]}},r.Parser.prototype.Node_Expr_Array=function(){return{type:"Node_Expr_Array",items:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_PropertyFetch=function(){return{type:"Node_Expr_PropertyFetch",variable:arguments[0],name:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_New=function(){return{type:"Node_Expr_New",Class:arguments[0],args:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Print=function(){return{type:"Node_Expr_Print",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Exit=function(){return{type:"Node_Expr_Exit",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Cast_Bool=function(){return{type:"Node_Expr_Cast_Bool",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Cast_Int=function(){return{type:"Node_Expr_Cast_Int",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Cast_String=function(){return{type:"Node_Expr_Cast_String",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Cast_Double=function(){return{type:"Node_Expr_Cast_Double",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Cast_Array=function(){return{type:"Node_Expr_Cast_Array",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Cast_Object=function(){return{type:"Node_Expr_Cast_Object",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_ErrorSuppress=function(){return{type:"Node_Expr_ErrorSuppress",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Isset=function(){return{type:"Node_Expr_Isset",variables:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_UnaryMinus=function(){return{type:"Node_Expr_UnaryMinus",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_UnaryPlus=function(){return{type:"Node_Expr_UnaryPlus",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_Empty=function(){return{type:"Node_Expr_Empty",variable:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_BooleanOr=function(){return{type:"Node_Expr_BooleanOr",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_LogicalOr=function(){return{type:"Node_Expr_LogicalOr",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_LogicalAnd=function(){return{type:"Node_Expr_LogicalAnd",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_LogicalXor=function(){return{type:"Node_Expr_LogicalXor",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_BitwiseAnd=function(){return{type:"Node_Expr_BitwiseAnd",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_BitwiseOr=function(){return{type:"Node_Expr_BitwiseOr",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_BitwiseXor=function(){return{type:"Node_Expr_BitwiseXor",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_BitwiseNot=function(){return{type:"Node_Expr_BitwiseNot",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_BooleanNot=function(){return{type:"Node_Expr_BooleanNot",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Expr_BooleanAnd=function(){return{type:"Node_Expr_BooleanAnd",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Instanceof=function(){return{type:"Node_Expr_Instanceof",left:arguments[0],right:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Expr_Clone=function(){return{type:"Node_Expr_Clone",expr:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Scalar_LNumber_parse=function(e){return e},r.Parser.prototype.Scalar_DNumber_parse=function(e){return e},r.Parser.prototype.Scalar_String_parseDocString=function(){return'"'+arguments[1].replace(/([^"\\]*(?:\\.[^"\\]*)*)"/g,'$1\\"')+'"'},r.Parser.prototype.Node_Scalar_String=function(){return{type:"Node_Scalar_String",value:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Scalar_String_create=function(){return{type:"Node_Scalar_String",value:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Scalar_LNumber=function(){return{type:"Node_Scalar_LNumber",value:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Scalar_DNumber=function(){return{type:"Node_Scalar_DNumber",value:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Scalar_Encapsed=function(){return{type:"Node_Scalar_Encapsed",parts:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Name=function(){return{type:"Node_Name",parts:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Name_FullyQualified=function(){return{type:"Node_Name_FullyQualified",parts:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Name_Relative=function(){return{type:"Node_Name_Relative",parts:arguments[0],attributes:arguments[1]}},r.Parser.prototype.Node_Param=function(){return{type:"Node_Param",name:arguments[0],def:arguments[1],Type:arguments[2],byRef:arguments[3],attributes:arguments[4]}},r.Parser.prototype.Node_Arg=function(){return{type:"Node_Name",value:arguments[0],byRef:arguments[1],attributes:arguments[2]}},r.Parser.prototype.Node_Const=function(){return{type:"Node_Const",name:arguments[0],value:arguments[1],attributes:arguments[2]}},t.PHP=r}),ace.define("ace/mode/php_worker",["require","exports","module","ace/lib/oop","ace/worker/mirror","ace/mode/php/php"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../worker/mirror").Mirror,s=e("./php/php").PHP,o=t.PhpWorker=function(e){i.call(this,e),this.setTimeout(500)};r.inherits(o,i),function(){this.setOptions=function(e){this.inlinePhp=e&&e.inline},this.onUpdate=function(){var e=this.doc.getValue(),t=[];this.inlinePhp&&(e="<?"+e+"?>");var n=s.Lexer(e,{short_open_tag:1});try{new s.Parser(n)}catch(r){t.push({row:r.line-1,column:null,text:r.message.charAt(0).toUpperCase()+r.message.substring(1),type:"error"})}t.length?this.sender.emit("error",t):this.sender.emit("ok")}}.call(o.prototype)}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _="	\n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace-nc/worker-xquery.js b/dist/assets/js/vendor/ace-nc/worker-xquery.js
            new file mode 100644
            index 0000000000..ee9b3a38ed
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace-nc/worker-xquery.js
            @@ -0,0 +1 @@
            +"no use strict";(function(e){if(typeof e.window!="undefined"&&e.document)return;e.console=function(){var e=Array.prototype.slice.call(arguments,0);postMessage({type:"log",data:e})},e.console.error=e.console.warn=e.console.log=e.console.trace=e.console,e.window=e,e.ace=e,e.onerror=function(e,t,n,r,i){console.error("Worker "+(i?i.stack:e))},e.normalizeModule=function(t,n){if(n.indexOf("!")!==-1){var r=n.split("!");return e.normalizeModule(t,r[0])+"!"+e.normalizeModule(t,r[1])}if(n.charAt(0)=="."){var i=t.split("/").slice(0,-1).join("/");n=(i?i+"/":"")+n;while(n.indexOf(".")!==-1&&s!=n){var s=n;n=n.replace(/^\.\//,"").replace(/\/\.\//,"/").replace(/[^\/]+\/\.\.\//,"")}}return n},e.require=function(t,n){n||(n=t,t=null);if(!n.charAt)throw new Error("worker.js require() accepts only (parentId, id) as arguments");n=e.normalizeModule(t,n);var r=e.require.modules[n];if(r)return r.initialized||(r.initialized=!0,r.exports=r.factory().exports),r.exports;var i=n.split("/");if(!e.require.tlns)return console.log("unable to load "+n);i[0]=e.require.tlns[i[0]]||i[0];var s=i.join("/")+".js";return e.require.id=n,importScripts(s),e.require(t,n)},e.require.modules={},e.require.tlns={},e.define=function(t,n,r){arguments.length==2?(r=n,typeof t!="string"&&(n=t,t=e.require.id)):arguments.length==1&&(r=t,n=[],t=e.require.id),n.length||(n=["require","exports","module"]);if(t.indexOf("text!")===0)return;var i=function(n){return e.require(t,n)};e.require.modules[t]={exports:{},factory:function(){var e=this,t=r.apply(this,n.map(function(t){switch(t){case"require":return i;case"exports":return e.exports;case"module":return e;default:return i(t)}}));return t&&(e.exports=t),e}}},e.define.amd={},e.initBaseUrls=function(t){require.tlns=t},e.initSender=function(){var n=e.require("ace/lib/event_emitter").EventEmitter,r=e.require("ace/lib/oop"),i=function(){};return function(){r.implement(this,n),this.callback=function(e,t){postMessage({type:"call",id:t,data:e})},this.emit=function(e,t){postMessage({type:"event",name:e,data:t})}}.call(i.prototype),new i};var t=e.main=null,n=e.sender=null;e.onmessage=function(r){var i=r.data;if(i.command){if(!t[i.command])throw new Error("Unknown command:"+i.command);t[i.command].apply(t,i.args)}else if(i.init){initBaseUrls(i.tlns),require("ace/lib/es5-shim"),n=e.sender=initSender();var s=require(i.module)[i.classname];t=e.main=new s(n)}else i.event&&n&&n._signal(i.event,i.data)}})(this),ace.define("ace/lib/oop",["require","exports","module"],function(e,t,n){"use strict";t.inherits=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})},t.mixin=function(e,t){for(var n in t)e[n]=t[n];return e},t.implement=function(e,n){t.mixin(e,n)}}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(e,t,n){"use strict";var r={},i=function(){this.propagationStopped=!0},s=function(){this.defaultPrevented=!0};r._emit=r._dispatchEvent=function(e,t){this._eventRegistry||(this._eventRegistry={}),this._defaultHandlers||(this._defaultHandlers={});var n=this._eventRegistry[e]||[],r=this._defaultHandlers[e];if(!n.length&&!r)return;if(typeof t!="object"||!t)t={};t.type||(t.type=e),t.stopPropagation||(t.stopPropagation=i),t.preventDefault||(t.preventDefault=s),n=n.slice();for(var o=0;o<n.length;o++){n[o](t,this);if(t.propagationStopped)break}if(r&&!t.defaultPrevented)return r(t,this)},r._signal=function(e,t){var n=(this._eventRegistry||{})[e];if(!n)return;n=n.slice();for(var r=0;r<n.length;r++)n[r](t,this)},r.once=function(e,t){var n=this;t&&this.addEventListener(e,function r(){n.removeEventListener(e,r),t.apply(null,arguments)})},r.setDefaultHandler=function(e,t){var n=this._defaultHandlers;n||(n=this._defaultHandlers={_disabled_:{}});if(n[e]){var r=n[e],i=n._disabled_[e];i||(n._disabled_[e]=i=[]),i.push(r);var s=i.indexOf(t);s!=-1&&i.splice(s,1)}n[e]=t},r.removeDefaultHandler=function(e,t){var n=this._defaultHandlers;if(!n)return;var r=n._disabled_[e];if(n[e]==t){var i=n[e];r&&this.setDefaultHandler(e,r.pop())}else if(r){var s=r.indexOf(t);s!=-1&&r.splice(s,1)}},r.on=r.addEventListener=function(e,t,n){this._eventRegistry=this._eventRegistry||{};var r=this._eventRegistry[e];return r||(r=this._eventRegistry[e]=[]),r.indexOf(t)==-1&&r[n?"unshift":"push"](t),t},r.off=r.removeListener=r.removeEventListener=function(e,t){this._eventRegistry=this._eventRegistry||{};var n=this._eventRegistry[e];if(!n)return;var r=n.indexOf(t);r!==-1&&n.splice(r,1)},r.removeAllListeners=function(e){this._eventRegistry&&(this._eventRegistry[e]=[])},t.EventEmitter=r}),ace.define("ace/range",["require","exports","module"],function(e,t,n){"use strict";var r=function(e,t){return e.row-t.row||e.column-t.column},i=function(e,t,n,r){this.start={row:e,column:t},this.end={row:n,column:r}};(function(){this.isEqual=function(e){return this.start.row===e.start.row&&this.end.row===e.end.row&&this.start.column===e.start.column&&this.end.column===e.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(e,t){return this.compare(e,t)==0},this.compareRange=function(e){var t,n=e.end,r=e.start;return t=this.compare(n.row,n.column),t==1?(t=this.compare(r.row,r.column),t==1?2:t==0?1:0):t==-1?-2:(t=this.compare(r.row,r.column),t==-1?-1:t==1?42:0)},this.comparePoint=function(e){return this.compare(e.row,e.column)},this.containsRange=function(e){return this.comparePoint(e.start)==0&&this.comparePoint(e.end)==0},this.intersects=function(e){var t=this.compareRange(e);return t==-1||t==0||t==1},this.isEnd=function(e,t){return this.end.row==e&&this.end.column==t},this.isStart=function(e,t){return this.start.row==e&&this.start.column==t},this.setStart=function(e,t){typeof e=="object"?(this.start.column=e.column,this.start.row=e.row):(this.start.row=e,this.start.column=t)},this.setEnd=function(e,t){typeof e=="object"?(this.end.column=e.column,this.end.row=e.row):(this.end.row=e,this.end.column=t)},this.inside=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)||this.isStart(e,t)?!1:!0:!1},this.insideStart=function(e,t){return this.compare(e,t)==0?this.isEnd(e,t)?!1:!0:!1},this.insideEnd=function(e,t){return this.compare(e,t)==0?this.isStart(e,t)?!1:!0:!1},this.compare=function(e,t){return!this.isMultiLine()&&e===this.start.row?t<this.start.column?-1:t>this.end.column?1:0:e<this.start.row?-1:e>this.end.row?1:this.start.row===e?t>=this.start.column?0:-1:this.end.row===e?t<=this.end.column?0:1:0},this.compareStart=function(e,t){return this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.compareEnd=function(e,t){return this.end.row==e&&this.end.column==t?1:this.compare(e,t)},this.compareInside=function(e,t){return this.end.row==e&&this.end.column==t?1:this.start.row==e&&this.start.column==t?-1:this.compare(e,t)},this.clipRows=function(e,t){if(this.end.row>t)var n={row:t+1,column:0};else if(this.end.row<e)var n={row:e,column:0};if(this.start.row>t)var r={row:t+1,column:0};else if(this.start.row<e)var r={row:e,column:0};return i.fromPoints(r||this.start,n||this.end)},this.extend=function(e,t){var n=this.compare(e,t);if(n==0)return this;if(n==-1)var r={row:e,column:t};else var s={row:e,column:t};return i.fromPoints(r||this.start,s||this.end)},this.isEmpty=function(){return this.start.row===this.end.row&&this.start.column===this.end.column},this.isMultiLine=function(){return this.start.row!==this.end.row},this.clone=function(){return i.fromPoints(this.start,this.end)},this.collapseRows=function(){return this.end.column==0?new i(this.start.row,0,Math.max(this.start.row,this.end.row-1),0):new i(this.start.row,0,this.end.row,0)},this.toScreenRange=function(e){var t=e.documentToScreenPosition(this.start),n=e.documentToScreenPosition(this.end);return new i(t.row,t.column,n.row,n.column)},this.moveBy=function(e,t){this.start.row+=e,this.start.column+=t,this.end.row+=e,this.end.column+=t}}).call(i.prototype),i.fromPoints=function(e,t){return new i(e.row,e.column,t.row,t.column)},i.comparePoints=r,i.comparePoints=function(e,t){return e.row-t.row||e.column-t.column},t.Range=i}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=t.Anchor=function(e,t,n){this.$onChange=this.onChange.bind(this),this.attach(e),typeof n=="undefined"?this.setPosition(t.row,t.column):this.setPosition(t,n)};(function(){r.implement(this,i),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.$insertRight=!1,this.onChange=function(e){var t=e.data,n=t.range;if(n.start.row==n.end.row&&n.start.row!=this.row)return;if(n.start.row>this.row)return;if(n.start.row==this.row&&n.start.column>this.column)return;var r=this.row,i=this.column,s=n.start,o=n.end;if(t.action==="insertText")if(s.row===r&&s.column<=i){if(s.column!==i||!this.$insertRight)s.row===o.row?i+=o.column-s.column:(i-=s.column,r+=o.row-s.row)}else s.row!==o.row&&s.row<r&&(r+=o.row-s.row);else t.action==="insertLines"?(s.row!==r||i!==0||!this.$insertRight)&&s.row<=r&&(r+=o.row-s.row):t.action==="removeText"?s.row===r&&s.column<i?o.column>=i?i=s.column:i=Math.max(0,i-(o.column-s.column)):s.row!==o.row&&s.row<r?(o.row===r&&(i=Math.max(0,i-o.column)+s.column),r-=o.row-s.row):o.row===r&&(r-=o.row-s.row,i=Math.max(0,i-o.column)+s.column):t.action=="removeLines"&&s.row<=r&&(o.row<=r?r-=o.row-s.row:(r=s.row,i=0));this.setPosition(r,i,!0)},this.setPosition=function(e,t,n){var r;n?r={row:e,column:t}:r=this.$clipPositionToDocument(e,t);if(this.row==r.row&&this.column==r.column)return;var i={row:this.row,column:this.column};this.row=r.row,this.column=r.column,this._signal("change",{old:i,value:r})},this.detach=function(){this.document.removeEventListener("change",this.$onChange)},this.attach=function(e){this.document=e||this.document,this.document.on("change",this.$onChange)},this.$clipPositionToDocument=function(e,t){var n={};return e>=this.document.getLength()?(n.row=Math.max(0,this.document.getLength()-1),n.column=this.document.getLine(n.row).length):e<0?(n.row=0,n.column=0):(n.row=e,n.column=Math.min(this.document.getLine(n.row).length,Math.max(0,t))),t<0&&(n.column=0),n}}).call(s.prototype)}),ace.define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"],function(e,t,n){"use strict";var r=e("./lib/oop"),i=e("./lib/event_emitter").EventEmitter,s=e("./range").Range,o=e("./anchor").Anchor,u=function(e){this.$lines=[],e.length===0?this.$lines=[""]:Array.isArray(e)?this._insertLines(0,e):this.insert({row:0,column:0},e)};(function(){r.implement(this,i),this.setValue=function(e){var t=this.getLength();this.remove(new s(0,0,t,this.getLine(t-1).length)),this.insert({row:0,column:0},e)},this.getValue=function(){return this.getAllLines().join(this.getNewLineCharacter())},this.createAnchor=function(e,t){return new o(this,e,t)},"aaa".split(/a/).length===0?this.$split=function(e){return e.replace(/\r\n|\r/g,"\n").split("\n")}:this.$split=function(e){return e.split(/\r\n|\r|\n/)},this.$detectNewLine=function(e){var t=e.match(/^.*?(\r\n|\r|\n)/m);this.$autoNewLine=t?t[1]:"\n",this._signal("changeNewLineMode")},this.getNewLineCharacter=function(){switch(this.$newLineMode){case"windows":return"\r\n";case"unix":return"\n";default:return this.$autoNewLine||"\n"}},this.$autoNewLine="",this.$newLineMode="auto",this.setNewLineMode=function(e){if(this.$newLineMode===e)return;this.$newLineMode=e,this._signal("changeNewLineMode")},this.getNewLineMode=function(){return this.$newLineMode},this.isNewLine=function(e){return e=="\r\n"||e=="\r"||e=="\n"},this.getLine=function(e){return this.$lines[e]||""},this.getLines=function(e,t){return this.$lines.slice(e,t+1)},this.getAllLines=function(){return this.getLines(0,this.getLength())},this.getLength=function(){return this.$lines.length},this.getTextRange=function(e){if(e.start.row==e.end.row)return this.getLine(e.start.row).substring(e.start.column,e.end.column);var t=this.getLines(e.start.row,e.end.row);t[0]=(t[0]||"").substring(e.start.column);var n=t.length-1;return e.end.row-e.start.row==n&&(t[n]=t[n].substring(0,e.end.column)),t.join(this.getNewLineCharacter())},this.$clipPosition=function(e){var t=this.getLength();return e.row>=t?(e.row=Math.max(0,t-1),e.column=this.getLine(t-1).length):e.row<0&&(e.row=0),e},this.insert=function(e,t){if(!t||t.length===0)return e;e=this.$clipPosition(e),this.getLength()<=1&&this.$detectNewLine(t);var n=this.$split(t),r=n.splice(0,1)[0],i=n.length==0?null:n.splice(n.length-1,1)[0];return e=this.insertInLine(e,r),i!==null&&(e=this.insertNewLine(e),e=this._insertLines(e.row,n),e=this.insertInLine(e,i||"")),e},this.insertLines=function(e,t){return e>=this.getLength()?this.insert({row:e,column:0},"\n"+t.join("\n")):this._insertLines(Math.max(e,0),t)},this._insertLines=function(e,t){if(t.length==0)return{row:e,column:0};while(t.length>61440){var n=this._insertLines(e,t.slice(0,61440));t=t.slice(61440),e=n.row}var r=[e,0];r.push.apply(r,t),this.$lines.splice.apply(this.$lines,r);var i=new s(e,0,e+t.length,0),o={action:"insertLines",range:i,lines:t};return this._signal("change",{data:o}),i.end},this.insertNewLine=function(e){e=this.$clipPosition(e);var t=this.$lines[e.row]||"";this.$lines[e.row]=t.substring(0,e.column),this.$lines.splice(e.row+1,0,t.substring(e.column,t.length));var n={row:e.row+1,column:0},r={action:"insertText",range:s.fromPoints(e,n),text:this.getNewLineCharacter()};return this._signal("change",{data:r}),n},this.insertInLine=function(e,t){if(t.length==0)return e;var n=this.$lines[e.row]||"";this.$lines[e.row]=n.substring(0,e.column)+t+n.substring(e.column);var r={row:e.row,column:e.column+t.length},i={action:"insertText",range:s.fromPoints(e,r),text:t};return this._signal("change",{data:i}),r},this.remove=function(e){e instanceof s||(e=s.fromPoints(e.start,e.end)),e.start=this.$clipPosition(e.start),e.end=this.$clipPosition(e.end);if(e.isEmpty())return e.start;var t=e.start.row,n=e.end.row;if(e.isMultiLine()){var r=e.start.column==0?t:t+1,i=n-1;e.end.column>0&&this.removeInLine(n,0,e.end.column),i>=r&&this._removeLines(r,i),r!=t&&(this.removeInLine(t,e.start.column,this.getLine(t).length),this.removeNewLine(e.start.row))}else this.removeInLine(t,e.start.column,e.end.column);return e.start},this.removeInLine=function(e,t,n){if(t==n)return;var r=new s(e,t,e,n),i=this.getLine(e),o=i.substring(t,n),u=i.substring(0,t)+i.substring(n,i.length);this.$lines.splice(e,1,u);var a={action:"removeText",range:r,text:o};return this._signal("change",{data:a}),r.start},this.removeLines=function(e,t){return e<0||t>=this.getLength()?this.remove(new s(e,0,t+1,0)):this._removeLines(e,t)},this._removeLines=function(e,t){var n=new s(e,0,t+1,0),r=this.$lines.splice(e,t-e+1),i={action:"removeLines",range:n,nl:this.getNewLineCharacter(),lines:r};return this._signal("change",{data:i}),r},this.removeNewLine=function(e){var t=this.getLine(e),n=this.getLine(e+1),r=new s(e,t.length,e+1,0),i=t+n;this.$lines.splice(e,2,i);var o={action:"removeText",range:r,text:this.getNewLineCharacter()};this._signal("change",{data:o})},this.replace=function(e,t){e instanceof s||(e=s.fromPoints(e.start,e.end));if(t.length==0&&e.isEmpty())return e.start;if(t==this.getTextRange(e))return e.end;this.remove(e);if(t)var n=this.insert(e.start,t);else n=e.start;return n},this.applyDeltas=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this.insertLines(r.start.row,n.lines):n.action=="insertText"?this.insert(r.start,n.text):n.action=="removeLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="removeText"&&this.remove(r)}},this.revertDeltas=function(e){for(var t=e.length-1;t>=0;t--){var n=e[t],r=s.fromPoints(n.range.start,n.range.end);n.action=="insertLines"?this._removeLines(r.start.row,r.end.row-1):n.action=="insertText"?this.remove(r):n.action=="removeLines"?this._insertLines(r.start.row,n.lines):n.action=="removeText"&&this.insert(r.start,n.text)}},this.indexToPosition=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length;for(var i=t||0,s=n.length;i<s;i++){e-=n[i].length+r;if(e<0)return{row:i,column:e+n[i].length+r}}return{row:s-1,column:n[s-1].length}},this.positionToIndex=function(e,t){var n=this.$lines||this.getAllLines(),r=this.getNewLineCharacter().length,i=0,s=Math.min(e.row,n.length);for(var o=t||0;o<s;++o)i+=n[o].length+r;return i+e.column}}).call(u.prototype),t.Document=u}),ace.define("ace/lib/lang",["require","exports","module"],function(e,t,n){"use strict";t.last=function(e){return e[e.length-1]},t.stringReverse=function(e){return e.split("").reverse().join("")},t.stringRepeat=function(e,t){var n="";while(t>0){t&1&&(n+=e);if(t>>=1)e+=e}return n};var r=/^\s\s*/,i=/\s\s*$/;t.stringTrimLeft=function(e){return e.replace(r,"")},t.stringTrimRight=function(e){return e.replace(i,"")},t.copyObject=function(e){var t={};for(var n in e)t[n]=e[n];return t},t.copyArray=function(e){var t=[];for(var n=0,r=e.length;n<r;n++)e[n]&&typeof e[n]=="object"?t[n]=this.copyObject(e[n]):t[n]=e[n];return t},t.deepCopy=function(e){if(typeof e!="object"||!e)return e;var n=e.constructor;if(n===RegExp)return e;var r=n();for(var i in e)typeof e[i]=="object"?r[i]=t.deepCopy(e[i]):r[i]=e[i];return r},t.arrayToMap=function(e){var t={};for(var n=0;n<e.length;n++)t[e[n]]=1;return t},t.createMap=function(e){var t=Object.create(null);for(var n in e)t[n]=e[n];return t},t.arrayRemove=function(e,t){for(var n=0;n<=e.length;n++)t===e[n]&&e.splice(n,1)},t.escapeRegExp=function(e){return e.replace(/([.*+?^${}()|[\]\/\\])/g,"\\$1")},t.escapeHTML=function(e){return e.replace(/&/g,"&#38;").replace(/"/g,"&#34;").replace(/'/g,"&#39;").replace(/</g,"&#60;")},t.getMatchOffsets=function(e,t){var n=[];return e.replace(t,function(e){n.push({offset:arguments[arguments.length-2],length:e.length})}),n},t.deferredCall=function(e){var t=null,n=function(){t=null,e()},r=function(e){return r.cancel(),t=setTimeout(n,e||0),r};return r.schedule=r,r.call=function(){return this.cancel(),e(),r},r.cancel=function(){return clearTimeout(t),t=null,r},r.isPending=function(){return t},r},t.delayedCall=function(e,t){var n=null,r=function(){n=null,e()},i=function(e){n==null&&(n=setTimeout(r,e||t))};return i.delay=function(e){n&&clearTimeout(n),n=setTimeout(r,e||t)},i.schedule=i,i.call=function(){this.cancel(),e()},i.cancel=function(){n&&clearTimeout(n),n=null},i.isPending=function(){return n},i}}),ace.define("ace/worker/mirror",["require","exports","module","ace/document","ace/lib/lang"],function(e,t,n){"use strict";var r=e("../document").Document,i=e("../lib/lang"),s=t.Mirror=function(e){this.sender=e;var t=this.doc=new r(""),n=this.deferredUpdate=i.delayedCall(this.onUpdate.bind(this)),s=this;e.on("change",function(e){t.applyDeltas(e.data);if(s.$timeout)return n.schedule(s.$timeout);s.onUpdate()})};(function(){this.$timeout=500,this.setTimeout=function(e){this.$timeout=e},this.setValue=function(e){this.doc.setValue(e),this.deferredUpdate.schedule(this.$timeout)},this.getValue=function(e){this.sender.callback(this.doc.getValue(),e)},this.onUpdate=function(){},this.isPending=function(){return this.deferredUpdate.isPending()}}).call(s.prototype)}),ace.define("ace/mode/xquery/xqlint",["require","exports","module"],function(e,t,n){n.exports=function r(t,n,i){function s(u,a){if(!n[u]){if(!t[u]){var f=typeof e=="function"&&e;if(!a&&f)return f(u,!0);if(o)return o(u,!0);throw new Error("Cannot find module '"+u+"'")}var l=n[u]={exports:{}};t[u][0].call(l.exports,function(e){var n=t[u][1][e];return s(n?n:e)},l,l.exports,r,t,n,i)}return n[u].exports}var o=typeof e=="function"&&e;for(var u=0;u<i.length;u++)s(i[u]);return s}({1:[function(e,t,n){"use strict";var r={},i={};r.prototype=new Error,i.prototype=new Error,n.StaticError=r.prototype.constructor=function(e,t,n){this.getCode=function(){return e},this.getMessage=function(){return t},this.getPos=function(){return n}},n.StaticWarning=i.prototype.constructor=function(e,t,n){this.getCode=function(){return e},this.getMessage=function(){return t},this.getPos=function(){return n}}},{}],2:[function(e,t,n){"use strict";var r=e("../tree_ops").TreeOps,i=e("./errors"),s=i.StaticWarning;n.ModuleDecl=function(e,t,n){var i="";return{NCName:function(e){i=r.flatten(e)},URILiteral:function(s){s=r.flatten(s),s=s.substring(1,s.length-1),e.apply(function(){t.moduleNamespace=s,t.addNamespace(s,i,n.pos,"moduleDecl")})}}},n.ModuleImport=function(e,t,n){var i="",s;return{NCName:function(e){i=r.flatten(e)},URILiteral:function(o){if(s!==undefined)return;o=r.flatten(o),o=o.substring(1,o.length-1),s=o,e.apply(function(){t.importModule(o,i,n.pos)})}}},n.SchemaImport=function(e,t,n){var i="",s;return{SchemaPrefix:function(t){var n=function(){this.NCName=function(e){i=r.flatten(e)}};e.visitChildren(t,new n)},URILiteral:function(o){if(s!==undefined)return;o=r.flatten(o),o=o.substring(1,o.length-1),s=o,e.apply(function(){t.addNamespace(o,i,n.pos,"schema")})}}},n.DefaultNamespaceDecl=function(e,t,n){var i=!1,o="";return{TOKEN:function(e){i=i?!0:e.value==="function"},URILiteral:function(u){o=r.flatten(u),o=o.substring(1,o.length-1),i?t.defaultFunctionNamespace=o:(e.apply(function(){throw new s("Avoid default element namespace declarations.",n.pos)}),t.defaultElementNamespace=o)}}},n.NamespaceDecl=function(e,t,n){var i="";return{NCName:function(e){i=r.flatten(e)},URILiteral:function(s){s=r.flatten(s),s=s.substring(1,s.length-1),e.apply(function(){t.addNamespace(s,i,n.pos,"declare")})}}},n.VarHandler=function(e,t,n){var i=function(i){var s=r.flatten(i);e.apply(function(){var e=t.resolveQName(s,i.pos);t.addVariable(e,n.name,i.pos)})};return{ExprSingle:function(){return!0},VarValue:function(){return!0},VarDefaultValue:function(){return!0},VarName:i,EQName:i}},n.VarRefHandler=function(e,t,n){return{VarName:function(i){var s=r.flatten(i);e.apply(function(){var e=t.resolveQName(s,n.pos);e.uri!==""&&(t.root.namespaces[e.uri].used=!0),t.addVarRef(e,i.pos)})}}}},{"../tree_ops":10,"./errors":1}],3:[function(e,t,n){n.StaticContext=function(t,n){"use strict";var r=e("../tree_ops").TreeOps,i=e("./errors"),s=i.StaticError,o=i.StaticWarning,u={sl:0,sc:0,el:0,ec:0},a={},f=function(e){return e.uri+"#"+e.name},l=function(e,t){return f(e)+"#"+t};t||(a["http://jsoniq.org/functions"]={prefix:"jn",pos:u,type:"module",override:!0},a["http://www.w3.org/2005/xpath-functions"]={prefix:"fn",pos:u,type:"module",override:!0},a["http://www.w3.org/2005/xquery-local-functions"]={prefix:"local",pos:u,type:"declare",override:!0},a["http://www.w3.org/2001/XMLSchema-instance"]={prefix:"xsi",pos:u,type:"declare"},a["http://www.w3.org/2001/XMLSchema"]={prefix:"xs",pos:u,type:"declare"},a["http://www.w3.org/XML/1998/namespace"]={prefix:"xml",pos:u,type:"declare"},a["http://zorba.io/annotations"]={prefix:"an",pos:u,type:"declare",override:!0},a["http://www.w3.org/2005/xqt-errors"]={prefix:"err",pos:u,type:"declare",override:!0},a["http://zorba.io/errors"]={prefix:"zerr",pos:u,type:"declare",override:!0});var c={parent:t,children:[],pos:n,setModuleResolver:function(e){return this.root.moduleResolver=e,this},moduleNamespace:"",defaultFunctionNamespace:"",defaultElementNamespace:"",namespaces:a,availableModuleNamespaces:[],importModule:function(e,t,n){this.root.addNamespace(e,t,n,"module");if(this.root.moduleResolver)try{var i=this.root.moduleResolver(e,[]);r.concat(this.variables,i.variables),r.concat(this.functions,i.functions)}catch(o){throw new s("XQST0059",'module "'+e+'" not found: '+o,n)}return this},getAvailableModuleNamespaces:function(){return this.root.availableModuleNamespaces},getPrefixByNamespace:function(e){return this.root.namespaces[e].prefix},addNamespace:function(e,t,n,r){if(t===""&&r==="module")throw new o("W01","Avoid this type of import. Use import module namespace instead");if(e==="")throw new s("XQST0088","empty target namespace in module import or module declaration",n);var i=this.getNamespace(e);if(i&&i.type===r&&r!=="declare"&&!i.override)throw new s("XQST0047",'"'+e+'": duplicate target namespace',n);i=this.getNamespaceByPrefix(t);if(i&&!i.override)throw new s("XQST0033",'"'+t+'": namespace prefix already bound to "'+i.uri+'"',n);i=this.namespaces[e],this.namespaces[e]={prefix:t,pos:n,type:r};if(i)throw new o("W02",'"'+e+'" already bound to the "'+i.prefix+'" prefix',n)},getNamespaces:function(){return this.root.namespaces},getNamespace:function(e){var t=this;while(t){var n=t.namespaces[e];if(n)return n;t=t.parent}},getNamespaceByPrefix:function(e){var t=function(t){var r=n.namespaces[t];if(r.prefix===e)throw r.uri=t,r},n=this;while(n){try{Object.keys(n.namespaces).forEach(t)}catch(r){return r}n=n.parent}},resolveQName:function(e,t){var n={uri:"",prefix:"",name:""},r;if(e.substring(0,2)==="Q{")r=e.indexOf("}"),n.uri=e.substring(2,r),n.name=e.substring(r+1);else{r=e.indexOf(":"),n.prefix=e.substring(0,r);var i=this.getNamespaceByPrefix(n.prefix);if(!i&&n.prefix!=="")throw new s("XPST0081",'"'+n.prefix+'": can not expand prefix of lexical QName to namespace URI',t);i&&(n.uri=i.uri),n.name=e.substring(r+1)}return n},variables:{},varRefs:{},addVariable:function(e,t,n){if(t!=="VarDecl"||this.moduleNamespace===""||this.moduleNamespace===e.uri||e.uri===""&&this.defaultFunctionNamespace===this.moduleNamespace){var r=f(e);if(t==="VarDecl"&&this.variables[r])throw new s("XQST0049",'"'+e.name+'": duplicate variable declaration',n);return this.variables[r]={type:t,pos:n,qname:e},this}throw new s("XQST0048",'"'+e.prefix+":"+e.name+'": Qname not library namespace',n)},getVariables:function(){var e={},t=this,n=function(n){e[n]||(e[n]=t.variables[n])};while(t)Object.keys(t.variables).forEach(n),t=t.parent;return e},getVariable:function(e){var t=f(e),n=this;while(n){if(n.variables[t])return n.variables[t];n=n.parent}},addVarRef:function(e,t){var n=this.getVariable(e);if(!n&&(e.uri===""||this.root.moduleResolver))throw new s("XPST0008",'"'+e.name+'": undeclared variable',t);var r=f(e);this.varRefs[r]=!0},functions:{},getFunctions:function(){return this.root.functions},getFunction:function(e,t){var n=l(e,t),r=this;while(r){if(r.functions[n])return r.functions[n];r=r.parent}},addFunction:function(e,t,n){var r=n.length;if(this.moduleNamespace===""||this.moduleNamespace===e.uri||e.uri===""&&this.defaultFunctionNamespace===this.moduleNamespace){var i=l(e,r);if(this.functions[i])throw new s("XQST0034",'"'+e.name+'": duplicate function declaration',t);return this.functions[i]={pos:t,params:n},this}throw new s("XQST0048",'"'+e.prefix+":"+e.name+'": Qname not library namespace',t)}};return c.root=t?t.root:c,c}},{"../tree_ops":10,"./errors":1}],4:[function(e,t,n){n.Translator=function(t,n){"use strict";var r=e("./errors"),i=r.StaticError,s=r.StaticWarning,o=e("../tree_ops").TreeOps,u=e("./static_context").StaticContext,a=e("./handlers"),f=function(e,t){var n;return t.length===0?e:(e.children.forEach(function(e){e.name===t[0]&&(n=f(e,t.slice(1)))}),n)},l=[];this.apply=function(e){try{e()}catch(t){if(t instanceof i)c(t);else{if(!(t instanceof s))throw t;h(t.getCode(),t.getMessage(),t.getPos())}}};var c=function(e){l.push({pos:e.getPos(),type:"error",level:"error",message:"["+e.getCode()+"] "+e.getMessage()})},h=function(e,t,n){l.push({pos:n,type:"warning",level:"warning",message:"["+e+"] "+t})};this.getMarkers=function(){return l};var p=this;t.pos=n.pos;var d=t,v=function(e){d=new u(d,e),d.parent.children.push(d)},m=function(e){e!==undefined&&(d.pos.el=e.el,d.pos.ec=e.ec),Object.keys(d.varRefs).forEach(function(e){d.variables[e]||(d.parent.varRefs[e]=!0)}),Object.keys(d.variables).forEach(function(e){!d.varRefs[e]&&d.variables[e].type!=="GroupingVariable"&&h("W03",'Unused variable "$'+d.variables[e].qname.name+'"',d.variables[e].pos)}),d=d.parent};this.visitOnly=function(e,t){e.children.forEach(function(e){t.indexOf(e.name)!==-1&&p.visit(e)})},this.getFirstChild=function(e,t){var n;return e.children.forEach(function(e){e.name===t&&n===undefined&&(n=e)}),n},this.ModuleDecl=function(e){return this.visitChildren(e,a.ModuleDecl(p,t,e)),!0},this.Prolog=function(e){return this.visitOnly(e,["DefaultNamespaceDecl","Setter","NamespaceDecl","Import"]),n.index.forEach(function(e){if(e.name==="VarDecl")e.children.forEach(function(n){n.name==="VarName"&&p.apply(function(){var r=o.flatten(n),i=t.resolveQName(r,n.pos);t.addVariable(i,e.name,n.pos)})});else if(e.name==="FunctionDecl"){var n,r,i=[];e.children.forEach(function(e){e.name==="EQName"?(n=e,r=e.pos):e.name==="ParamList"&&e.children.forEach(function(e){e.name==="Param"&&i.push(o.flatten(e))})}),p.apply(function(){n=o.flatten(n),n=t.resolveQName(n,r),t.addFunction(n,r,i)})}}),this.visitOnly(e,["ContextItemDecl","AnnotatedDecl","OptionDecl"]),!0},this.ModuleImport=function(e){return this.visitChildren(e,a.ModuleImport(p,t,e)),!0},this.SchemaImport=function(e){return this.visitChildren(e,a.SchemaImport(p,t,e)),!0},this.DefaultNamespaceDecl=function(e){return this.visitChildren(e,a.DefaultNamespaceDecl(p,t,e)),!0},this.NamespaceDecl=function(e){return this.visitChildren(e,a.NamespaceDecl(p,t,e)),!0};var g={};this.AnnotatedDecl=function(e){return g=[],this.visitChildren(e,a.NamespaceDecl(p,t,e)),!0},this.Annotation=function(e){return this.visitChildren(e,{EQName:function(e){var t=o.flatten(e);p.apply(function(){var n=d.resolveQName(t,e.pos);g[n.uri+"#"+n.name]=[]})}}),!0},this.VarDecl=function(e){try{var n=p.getFirstChild(e,"VarName"),r=o.flatten(n),i=d.resolveQName(r,n.pos),s=t.getVariable(i);s&&(s.annotations=g)}catch(u){}return this.visitOnly(e,["ExprSingle","VarValue","VarDefaultValue"]),!0},this.FunctionDecl=function(e){var t=f(e,["ReturnType"]);t||h("W05","Untyped return value",e.pos);var n=!1;return e.children.forEach(function(e){if(e.name==="TOKEN"&&e.value==="external")return n=!0,!1}),n||(v(e.pos),this.visitChildren(e),m()),!0},this.VarRef=function(e){return this.visitChildren(e,a.VarRefHandler(p,d,e)),!0},this.Param=function(e){var t=f(e,["TypeDeclaration"]);return t||h("W05","Untyped function parameter",e.pos),this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.InlineFunctionExpr=function(e){return v(e.pos),this.visitChildren(e),m(),!0};var y=[],b=function(e){v(e.pos),y.push(0),p.visitChildren(e);for(var t=1;t<=y[y.length-1];t++)m(e.pos);y.pop(),m()};this.StatementsAndOptionalExpr=function(e){return b(e),!0},this.StatementsAndExpr=function(e){return b(e),!0},this.BlockStatement=function(e){return b(e),!0},this.VarDeclStatement=function(e){v(e.pos),y[y.length-1]++,this.visitChildren(e,a.VarHandler(p,d,e))};var w=[];this.FLWORExpr=function(e){v(e.pos),w.push(0),this.visitChildren(e);for(var t=1;t<=w[w.length-1];t++)m(e.pos);return w.pop(),m(),!0},this.ForBinding=function(e){return this.visitOnly(e,["ExprSingle","VarValue","VarDefaultValue"]),v(e.pos),w[w.length-1]++,this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.LetBinding=function(e){this.visitOnly(e,["ExprSingle","VarValue","VarDefaultValue"]),v(e.pos),w[w.length-1]++,this.visitChildren(e,a.VarHandler(p,d,e))},this.GroupingSpec=function(e){var t=!1;e.children.forEach(function(e){if(e.value===":=")return t=!0,!1});if(t){var n=e.children[0];return this.visitOnly(e,["ExprSingle","VarValue","VarDefaultValue"]),v(e.pos),w[w.length-1]++,this.visitChildren(n,a.VarHandler(p,d,n)),!0}},this.TumblingWindowClause=function(e){return this.visitOnly(e,["ExprSingle"]),v(e.pos),w[w.length-1]++,this.visitChildren(e,a.VarHandler(p,d,e)),this.visitOnly(e,["WindowStartCondition","WindowEndCondition"]),!0},this.WindowVars=function(e){return v(e.pos),w[w.length-1]++,this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.SlidingWindowClause=function(e){return this.visitOnly(e,["ExprSingle","VarValue","VarDefaultValue"]),v(e.pos),w[w.length-1]++,this.visitChildren(e,a.VarHandler(p,d,e)),this.visitOnly(e,["WindowStartCondition","WindowEndCondition"]),!0},this.PositionalVar=function(e){return this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.PositionalVar=function(e){return this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.CurrentItem=function(e){return this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.PreviousItem=function(e){return this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.NextItem=function(e){return this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.CountClause=function(e){return v(e.pos),w[w.length-1]++,this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.CaseClause=function(e){return v(e.pos),this.visitChildren(e,a.VarHandler(p,d,e)),this.visitOnly(e,["ExprSingle"]),m(),!0},this.TransformExpr=function(e){return v(e.pos),this.visitChildren(e),m(),!0},this.TransformSpec=function(e){return this.visitOnly(e,["ExprSingle","VarValue","VarDefaultValue"]),this.visitChildren(e,a.VarHandler(p,d,e)),!0},this.QuantifiedExpr=function(e){return v(e.pos),m(),!0},this.FunctionCall=function(e){try{var n=p.getFirstChild(e,"EQName");n=o.flatten(n);var r=t.resolveQName(n,e.pos);t.namespaces[r.uri].used=!0}catch(i){}},this.visit=function(e){var t=e.name,n=!1;typeof this[t]=="function"&&(n=this[t](e)===!0),n||this.visitChildren(e)},this.visitChildren=function(e,t){for(var n=0;n<e.children.length;n++){var r=e.children[n];t!==undefined&&typeof t[r.name]=="function"?t[r.name](r):this.visit(r)}},this.visit(n),Object.keys(t.variables).forEach(function(e){!t.varRefs[e]&&(t.variables[e].annotations["http://www.w3.org/2005/xpath-functions#private"]||t.moduleNamespace==="")&&t.variables[e].pos&&h("W03",'Unused variable "'+t.variables[e].qname.name+'"',t.variables[e].pos)}),Object.keys(t.namespaces).forEach(function(e){var n=t.namespaces[e];n.used===undefined&&!n.override&&n.type==="module"&&h("W04",'Unused module "'+e+'"',n.pos)})}},{"../tree_ops":10,"./errors":1,"./handlers":2,"./static_context":3}],5:[function(e,t,n){"use strict";function s(e,t,n){n=n||i;var r=[];for(var s=t-1;s>=0;s--){if(!n.test(e[s]))break;r.push(e[s])}return r.reverse().join("")}function o(e,t){var n=0,r=e.length-1,i=Math.floor((r+n)/2);while(r>n&&i>=0&&e[i].indexOf(t)!==0)t<e[i]?r=i-1:t>e[i]&&(n=i+1),i=Math.floor((r+r)/2);while(i>0&&e[i-1].indexOf(t)===0)i--;return i>=0?i:0}var r=e("../tree_ops").TreeOps,i=/[a-zA-Z_0-9\$]/,u=/[a-zA-Z_0-9\/\.:\-#]/,a="-._A-Za-z0-9:\u00b7\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02ff\u0300-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd",f="["+a+"]",l=new RegExp(f),c={LetBinding:"Let binding",Param:"Function parameter",QuantifiedExpr:"Quantified expression binding",VarDeclStatement:"Local variable",ForBinding:"For binding",TumblingWindowClause:"Tumbling window binding",WindowVars:"Window variable",SlidingWindowClause:"Sliding window binding",PositionalVar:"Positional variable",CurrentItem:"Current item",PreviousItem:"Previous item",NextItem:"Next item",CountClause:"Count binding",GroupingVariable:"Grouping variable",VarDecl:"Module variable"},h=function(e,t){t.sort();var n=o(t,e),r=[];for(var i=n;i<t.length&&t[i].indexOf(e)===0;i++)r.push(t[i]);return r},p=function(e,t,n){var r=e.indexOf(":");if(r===-1){var i=[],s=n.getNamespaces();Object.keys(s).forEach(function(e){s[e].type==="module"&&i.push(s[e].prefix)});var o=h(e,i),u=function(e){return{name:e+":",value:e+":",meta:"prefix"}};return o.map(u)}return[]},d=function(e,t,n){var r=[],i=n.getFunctions(),s="",o="",u=e,a=e.indexOf(":");if(a!==-1){o=e.substring(0,a),u=e.substring(a+1);var f=n.getNamespaceByPrefix(o);f&&(s=n.getNamespaceByPrefix(o).uri)}Object.keys(i).forEach(function(e){var t=i[e],s=e.substring(0,e.indexOf("#")),o=e.substring(e.indexOf("#")+1);o=o.substring(0,o.indexOf("#")),s!==""&&(o=n.getNamespaces()[s].prefix+":"+o),o+="(",o+=t.params.join(", "),o+=")",r.push(o)});var l=h(e,r),c=function(e){return{name:e,value:e,meta:"function"}};return l.map(c)},v=function(e,t,n){var r="",i="",s=e.indexOf(":");s!==-1&&(i=e.substring(0,s),r=n.getNamespaceByPrefix(i).uri);var o=n.getVariables(),u=[],a={};Object.keys(o).forEach(function(e){var t=e.indexOf("#"),r=e.substring(0,t),i=e.substring(t+1);r!==""?(u.push(n.getPrefixByNamespace(r)+":"+i),a[n.getPrefixByNamespace(r)+":"+i]=o[e].type):(u.push(i),a[i]=o[e].type)});var f=h(e,u),l=function(e){return{name:"$"+e,value:"$"+e,meta:c[a[e]]}};return f.map(l)},m=function(e,t,n){var r=s(e,t.col,l),i=e.substring(0,t.col-(r.length===0?0:r.length)),o=i[i.length-1]==="$";return o?v(r,t,n):r!==""?d(r,t,n).concat(p(r,t,n)):v(r,t,n).concat(d(r,t,n)).concat(p(r,t,n))},g=function(e,t,n){var r=s(e,t.col,u),i=h(r,n.getAvailableModuleNamespaces()),o=function(e){return{name:e,value:e,meta:"module"}};return i.map(o)};n.complete=function(e,t,n,i){var s=e.split("\n")[i.line],o=r.findNode(t,i),u=r.findNode(n,i);return u=u?u:n,o&&o.name==="URILiteral"&&o.getParent&&o.getParent.name==="ModuleImport"?g(s,i,u):m(s,i,u)}},{"../tree_ops":10}],6:[function(e,t,n){n.StyleChecker=function(e,t){"use strict";var n="    ",r=[];this.getMarkers=function(){return r},this.WS=function(e){var t=e.value.split("\n");return t.forEach(function(i,s){var o=s===0,u=s===t.length-1;/\r$/.test(i)&&r.push({pos:{sl:e.pos.sl+s,el:e.pos.sl+s,sc:i.length-1,ec:i.length},type:"warning",level:"warning",message:"[SW01] Detected CRLF"});var a=i.match(/\t+/);a!==null&&r.push({pos:{sl:e.pos.sl+s,el:e.pos.sl+s,sc:a.index,ec:a.index+a[0].length},type:"warning",level:"warning",message:"[SW02] Tabs detected"});if(!o&&u){a=i.match(/^\ +/);if(a!==null){var f=a[0].length%n.length;f!==0&&r.push({pos:{sl:e.pos.sl+s,el:e.pos.sl+s,sc:a.index,ec:a.index+a[0].length},type:"warning",level:"warning",message:"[SW03] Unexcepted indentation of "+a[0].length})}}}),!0},this.visit=function(e,t){var n=e.name,r=!1;typeof this[n]=="function"&&(r=this[n](e,t)===!0),r||this.visitChildren(e)},this.visitChildren=function(e,t){for(var n=0;n<e.children.length;n++){var r=e.children[n];t!==undefined&&typeof t[r.name]=="function"?t[r.name](r):this.visit(r)}},t.split("\n").forEach(function(e,t){var n=e.match(/\ +$/);n&&r.push({pos:{sl:t,el:t,sc:n.index,ec:n.index+n[0].length},type:"warning",level:"warning",message:"[SW04] Trailing whitespace"})}),this.visit(e)}},{}],7:[function(e,t,n){n.JSONParseTreeHandler=function(e){"use strict";function f(e){return{name:e,children:[],getParent:null,pos:{sl:0,sc:0,el:0,ec:0}}}function l(e){var t=f(e);r===null?(r=t,r.index=[],i=t):(t.getParent=i,i.children.push(t),i=i.children[i.children.length-1])}function c(){if(i.children.length>0){var e=i.children[0],s=null;for(var o=i.children.length-1;o>=0;o--){s=i.children[o];if(s.pos.el!==0||s.pos.ec!==0)break}i.pos.sl=e.pos.sl,i.pos.sc=e.pos.sc,i.pos.el=s.pos.el,i.pos.ec=s.pos.ec}i.name==="FunctionName"&&(i.name="EQName"),i.name==="EQName"&&i.value===undefined&&(i.value=i.children[0].value,i.children.pop()),t.indexOf(i.name)!==-1&&r.index.push(i),i.getParent!==null&&(i=i.getParent);if(i.children.length>0){var u=i.children[i.children.length-1];u.children.length===1&&n.indexOf(u.name)!==-1&&(i.children[i.children.length-1]=u.children[0])}}function h(e,t,n){var r=n-o;i.value=s.substring(0,r),s=s.substring(r),o=n;var f=a,l=u,c=f+i.value.split("\n").length-1,h=i.value.lastIndexOf("\n"),p=h===-1?l+i.value.length:i.value.substring(h+1).length;a=c,u=p,i.pos.sl=f,i.pos.sc=l,i.pos.el=c,i.pos.ec=p}var t=["VarDecl","FunctionDecl"],n=["OrExpr","AndExpr","ComparisonExpr","StringConcatExpr","RangeExpr","UnionExpr","IntersectExceptExpr","InstanceofExpr","TreatExpr","CastableExpr","CastExpr","UnaryExpr","ValueExpr","FTContainsExpr","SimpleMapExpr","PathExpr","RelativePathExpr","PostfixExpr","StepExpr"],r=null,i=null,s=e,o=0,u=0,a=0;this.closeParseTree=function(){while(i.getParent!==null)c();c()},this.peek=function(){return i},this.getParseTree=function(){return r},this.reset=function(){},this.startNonterminal=function(e,t){l(e,t)},this.endNonterminal=function(){c()},this.terminal=function(e,t,n){e=e.substring(0,1)==="'"&&e.substring(e.length-1)==="'"?"TOKEN":e,l(e,t),h(i,t,n),c()},this.whitespace=function(e,t){var n="WS";l(n,e),h(i,e,t),c()}}},{}],8:[function(e,t,n){var r=n.JSONiqParser=function i(e,t){function r(e,t){nc=t,oc=e,uc=e.length,s(0,0,0)}function s(e,t,n){zl=t,Wl=t,Xl=e,Vl=t,$l=n,Jl=0,fc=n,Yl=-1,rc={},nc.reset(oc)}function o(){nc.startNonterminal("Module",Wl);switch(Xl){case 170:Fl(169);break;default:Ul=Xl}(Ul==64682||Ul==137898)&&u(),jl(279);switch(Xl){case 185:Fl(144);break;default:Ul=Xl}switch(Ul){case 95929:Hl(),a();break;default:Hl(),Ga()}nc.endNonterminal("Module",Wl)}function u(){nc.startNonterminal("VersionDecl",Wl),_l(170),jl(118);switch(Xl){case 126:_l(126),jl(17),_l(11);break;default:_l(269),jl(17),_l(11),jl(111),Xl==126&&(_l(126),jl(17),_l(11))}jl(29),Hl(),c(),nc.endNonterminal("VersionDecl",Wl)}function a(){nc.startNonterminal("LibraryModule",Wl),f(),jl(140),Hl(),l(),nc.endNonterminal("LibraryModule",Wl)}function f(){nc.startNonterminal("ModuleDecl",Wl),_l(185),jl(64),_l(187),jl(241),Hl(),Ka(),jl(30),_l(61),jl(15),_l(7),jl(29),Hl(),c(),nc.endNonterminal("ModuleDecl",Wl)}function l(){nc.startNonterminal("Prolog",Wl);for(;;){jl(279);switch(Xl){case 109:Fl(208);break;case 155:Fl(170);break;default:Ul=Xl}if(Ul!=43117&&Ul!=44141&&Ul!=50797&&Ul!=53869&&Ul!=54893&&Ul!=56429&&Ul!=73325&&Ul!=94875&&Ul!=95853&&Ul!=106093&&Ul!=115821&&Ul!=117403)break;switch(Xl){case 109:Fl(199);break;default:Ul=Xl}if(Ul==56429){Ul=sc(0,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{_(),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(0,Wl,Ul)}}switch(Ul){case-1:Hl(),M();break;case 95853:Hl(),O();break;case 155:Hl(),C();break;case 73325:Hl(),D();break;default:Hl(),h()}jl(29),Hl(),c()}for(;;){jl(279);switch(Xl){case 109:Fl(201);break;default:Ul=Xl}if(Ul!=17005&&Ul!=49261&&Ul!=52333&&Ul!=75373&&Ul!=80493&&Ul!=83565&&Ul!=104045&&Ul!=134765&&Ul!=137325)break;switch(Xl){case 109:Fl(197);break;default:Ul=Xl}switch(Ul){case 52333:Hl(),R();break;case 104045:Hl(),Q();break;default:Hl(),P()}jl(29),Hl(),c()}nc.endNonterminal("Prolog",Wl)}function c(){nc.startNonterminal("Separator",Wl),_l(54),nc.endNonterminal("Separator",Wl)}function h(){nc.startNonterminal("Setter",Wl);switch(Xl){case 109:Fl(195);break;default:Ul=Xl}if(Ul==56429){Ul=sc(1,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{v(),Ul=-2}catch(a){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),w(),Ul=-6}catch(f){Ul=-9}}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(1,Wl,Ul)}}switch(Ul){case 44141:p();break;case-2:d();break;case 43117:m();break;case 50797:g();break;case 106093:y();break;case-6:b();break;case 115821:jo();break;case 53869:E();break;default:T()}nc.endNonterminal("Setter",Wl)}function p(){nc.startNonterminal("BoundarySpaceDecl",Wl),_l(109),jl(36),_l(86),jl(135);switch(Xl){case 218:_l(218);break;default:_l(246)}nc.endNonterminal("BoundarySpaceDecl",Wl)}function d(){nc.startNonterminal("DefaultCollationDecl",Wl),_l(109),jl(49),_l(110),jl(41),_l(95),jl(15),_l(7),nc.endNonterminal("DefaultCollationDecl",Wl)}function v(){Dl(109),jl(49),Dl(110),jl(41),Dl(95),jl(15),Dl(7)}function m(){nc.startNonterminal("BaseURIDecl",Wl),_l(109),jl(35),_l(84),jl(15),_l(7),nc.endNonterminal("BaseURIDecl",Wl)}function g(){nc.startNonterminal("ConstructionDecl",Wl),_l(109),jl(44),_l(99),jl(135);switch(Xl){case 246:_l(246);break;default:_l(218)}nc.endNonterminal("ConstructionDecl",Wl)}function y(){nc.startNonterminal("OrderingModeDecl",Wl),_l(109),jl(71),_l(207),jl(133);switch(Xl){case 206:_l(206);break;default:_l(262)}nc.endNonterminal("OrderingModeDecl",Wl)}function b(){nc.startNonterminal("EmptyOrderDecl",Wl),_l(109),jl(49),_l(110),jl(70),_l(205),jl(52),_l(124),jl(123);switch(Xl){case 149:_l(149);break;default:_l(176)}nc.endNonterminal("EmptyOrderDecl",Wl)}function w(){Dl(109),jl(49),Dl(110),jl(70),Dl(205),jl(52),Dl(124),jl(123);switch(Xl){case 149:Dl(149);break;default:Dl(176)}}function E(){nc.startNonterminal("CopyNamespacesDecl",Wl),_l(109),jl(47),_l(105),jl(130),Hl(),S(),jl(25),_l(42),jl(125),Hl(),x(),nc.endNonterminal("CopyNamespacesDecl",Wl)}function S(){nc.startNonterminal("PreserveMode",Wl);switch(Xl){case 218:_l(218);break;default:_l(193)}nc.endNonterminal("PreserveMode",Wl)}function x(){nc.startNonterminal("InheritMode",Wl);switch(Xl){case 159:_l(159);break;default:_l(192)}nc.endNonterminal("InheritMode",Wl)}function T(){nc.startNonterminal("DecimalFormatDecl",Wl),_l(109),jl(116);switch(Xl){case 107:_l(107),jl(247),Hl(),Xa();break;default:_l(110),jl(48),_l(107)}for(;;){jl(203);if(Xl==54)break;Hl(),N(),jl(30),_l(61),jl(17),_l(11)}nc.endNonterminal("DecimalFormatDecl",Wl)}function N(){nc.startNonterminal("DFPropertyName",Wl);switch(Xl){case 108:_l(108);break;case 151:_l(151);break;case 158:_l(158);break;case 182:_l(182);break;case 68:_l(68);break;case 213:_l(213);break;case 212:_l(212);break;case 280:_l(280);break;case 117:_l(117);break;default:_l(211)}nc.endNonterminal("DFPropertyName",Wl)}function C(){nc.startNonterminal("Import",Wl);switch(Xl){case 155:Fl(128);break;default:Ul=Xl}switch(Ul){case 117403:k();break;default:A()}nc.endNonterminal("Import",Wl)}function k(){nc.startNonterminal("SchemaImport",Wl),_l(155),jl(75),_l(229),jl(139),Xl!=7&&(Hl(),L()),jl(15),_l(7),jl(110);if(Xl==82){_l(82),jl(15),_l(7);for(;;){jl(105);if(Xl!=42)break;_l(42),jl(15),_l(7)}}nc.endNonterminal("SchemaImport",Wl)}function L(){nc.startNonterminal("SchemaPrefix",Wl);switch(Xl){case 187:_l(187),jl(241),Hl(),Ka(),jl(30),_l(61);break;default:_l(110),jl(50),_l(122),jl(64),_l(187)}nc.endNonterminal("SchemaPrefix",Wl)}function A(){nc.startNonterminal("ModuleImport",Wl),_l(155),jl(63),_l(185),jl(92),Xl==187&&(_l(187),jl(241),Hl(),Ka(),jl(30),_l(61)),jl(15),_l(7),jl(110);if(Xl==82){_l(82),jl(15),_l(7);for(;;){jl(105);if(Xl!=42)break;_l(42),jl(15),_l(7)}}nc.endNonterminal("ModuleImport",Wl)}function O(){nc.startNonterminal("NamespaceDecl",Wl),_l(109),jl(64),_l(187),jl(241),Hl(),Ka(),jl(30),_l(61),jl(15),_l(7),nc.endNonterminal("NamespaceDecl",Wl)}function M(){nc.startNonterminal("DefaultNamespaceDecl",Wl),_l(109),jl(49),_l(110),jl(117);switch(Xl){case 122:_l(122);break;default:_l(147)}jl(64),_l(187),jl(15),_l(7),nc.endNonterminal("DefaultNamespaceDecl",Wl)}function _(){Dl(109),jl(49),Dl(110),jl(117);switch(Xl){case 122:Dl(122);break;default:Dl(147)}jl(64),Dl(187),jl(15),Dl(7)}function D(){nc.startNonterminal("FTOptionDecl",Wl),_l(109),jl(55),_l(143),jl(83),Hl(),Ju(),nc.endNonterminal("FTOptionDecl",Wl)}function P(){nc.startNonterminal("AnnotatedDecl",Wl),_l(109);for(;;){jl(193);if(Xl!=33&&Xl!=263)break;switch(Xl){case 263:Hl(),H();break;default:Hl(),B()}}switch(Xl){case 268:Hl(),F();break;case 147:Hl(),Ol();break;case 96:Hl(),Ta();break;case 157:Hl(),Da();break;default:Hl(),Pa()}nc.endNonterminal("AnnotatedDecl",Wl)}function H(){nc.startNonterminal("CompatibilityAnnotation",Wl),_l(263),nc.endNonterminal("CompatibilityAnnotation",Wl)}function B(){nc.startNonterminal("Annotation",Wl),_l(33),jl(247),Hl(),Xa(),jl(194);if(Xl==35){_l(35),jl(191),Hl(),hi();for(;;){jl(103);if(Xl!=42)break;_l(42),jl(191),Hl(),hi()}_l(38)}nc.endNonterminal("Annotation",Wl)}function j(){Dl(33),jl(247),Va(),jl(194);if(Xl==35){Dl(35),jl(191),pi();for(;;){jl(103);if(Xl!=42)break;Dl(42),jl(191),pi()}Dl(38)}}function F(){nc.startNonterminal("VarDecl",Wl),_l(268),jl(21),_l(31),jl(247),Hl(),Si(),jl(156),Xl==80&&(Hl(),Ts()),jl(108);switch(Xl){case 53:_l(53),jl(268),Hl(),I();break;default:_l(134),jl(106),Xl==53&&(_l(53),jl(268),Hl(),q())}nc.endNonterminal("VarDecl",Wl)}function I(){nc.startNonterminal("VarValue",Wl),Uf(),nc.endNonterminal("VarValue",Wl)}function q(){nc.startNonterminal("VarDefaultValue",Wl),Uf(),nc.endNonterminal("VarDefaultValue",Wl)}function R(){nc.startNonterminal("ContextItemDecl",Wl),_l(109),jl(46),_l(102),jl(58),_l(167),jl(156),Xl==80&&(_l(80),jl(255),Hl(),Os()),jl(108);switch(Xl){case 53:_l(53),jl(268),Hl(),I();break;default:_l(134),jl(106),Xl==53&&(_l(53),jl(268),Hl(),q())}nc.endNonterminal("ContextItemDecl",Wl)}function U(){nc.startNonterminal("ParamList",Wl),W();for(;;){jl(103);if(Xl!=42)break;_l(42),jl(21),Hl(),W()}nc.endNonterminal("ParamList",Wl)}function z(){X();for(;;){jl(103);if(Xl!=42)break;Dl(42),jl(21),X()}}function W(){nc.startNonterminal("Param",Wl),_l(31),jl(247),Hl(),Xa(),jl(152),Xl==80&&(Hl(),Ts()),nc.endNonterminal("Param",Wl)}function X(){Dl(31),jl(247),Va(),jl(152),Xl==80&&Ns()}function V(){nc.startNonterminal("FunctionBody",Wl),J(),nc.endNonterminal("FunctionBody",Wl)}function $(){K()}function J(){nc.startNonterminal("EnclosedExpr",Wl),_l(281),jl(268),Hl(),G(),_l(287),nc.endNonterminal("EnclosedExpr",Wl)}function K(){Dl(281),jl(268),Y(),Dl(287)}function Q(){nc.startNonterminal("OptionDecl",Wl),_l(109),jl(69),_l(203),jl(247),Hl(),Xa(),jl(17),_l(11),nc.endNonterminal("OptionDecl",Wl)}function G(){nc.startNonterminal("Expr",Wl),Uf();for(;;){if(Xl!=42)break;_l(42),jl(268),Hl(),Uf()}nc.endNonterminal("Expr",Wl)}function Y(){zf();for(;;){if(Xl!=42)break;Dl(42),jl(268),zf()}}function Z(){nc.startNonterminal("FLWORExpr",Wl),tt();for(;;){jl(200);if(Xl==224||Xl==233)break;Hl(),rt()}Hl(),rn(),nc.endNonterminal("FLWORExpr",Wl)}function et(){nt();for(;;){jl(200);if(Xl==224||Xl==233)break;it()}sn()}function tt(){nc.startNonterminal("InitialClause",Wl);switch(Xl){case 139:case 142:Fl(150);break;default:Ul=Xl}switch(Ul){case 16011:case 16014:st();break;case 177:vt();break;default:bt()}nc.endNonterminal("InitialClause",Wl)}function nt(){switch(Xl){case 139:case 142:Fl(150);break;default:Ul=Xl}switch(Ul){case 16011:case 16014:ot();break;case 177:mt();break;default:wt()}}function rt(){nc.startNonterminal("IntermediateClause",Wl);switch(Xl){case 272:It();break;case 150:Rt();break;case 205:case 241:Kt();break;case 106:jt();break;default:tt()}nc.endNonterminal("IntermediateClause",Wl)}function it(){switch(Xl){case 272:qt();break;case 150:Ut();break;case 205:case 241:Qt();break;case 106:Ft();break;default:nt()}}function st(){nc.startNonterminal("ForClause",Wl);switch(Xl){case 139:_l(139);break;default:_l(142)}jl(21),Hl(),ut();for(;;){if(Xl!=42)break;_l(42),jl(21),Hl(),ut()}nc.endNonterminal("ForClause",Wl)}function ot(){switch(Xl){case 139:Dl(139);break;default:Dl(142)}jl(21),at();for(;;){if(Xl!=42)break;Dl(42),jl(21),at()}}function ut(){nc.startNonterminal("ForBinding",Wl),_l(31),jl(247),Hl(),Si(),jl(183),Xl==80&&(Hl(),Ts()),jl(174),Xl==73&&(Hl(),ft()),jl(159),Xl==82&&(Hl(),ct()),jl(124),Xl==232&&(Hl(),pt()),jl(56),_l(156),jl(268),Hl(),Uf(),nc.endNonterminal("ForBinding",Wl)}function at(){Dl(31),jl(247),xi(),jl(183),Xl==80&&Ns(),jl(174),Xl==73&&lt(),jl(159),Xl==82&&ht(),jl(124),Xl==232&&dt(),jl(56),Dl(156),jl(268),zf()}function ft(){nc.startNonterminal("AllowingEmpty",Wl),_l(73),jl(52),_l(124),nc.endNonterminal("AllowingEmpty",Wl)}function lt(){Dl(73),jl(52),Dl(124)}function ct(){nc.startNonterminal("PositionalVar",Wl),_l(82),jl(21),_l(31),jl(247),Hl(),Si(),nc.endNonterminal("PositionalVar",Wl)}function ht(){Dl(82),jl(21),Dl(31),jl(247),xi()}function pt(){nc.startNonterminal("FTScoreVar",Wl),_l(232),jl(21),_l(31),jl(247),Hl(),Si(),nc.endNonterminal("FTScoreVar",Wl)}function dt(){Dl(232),jl(21),Dl(31),jl(247),xi()}function vt(){nc.startNonterminal("LetClause",Wl),_l(177),jl(98),Hl(),gt();for(;;){if(Xl!=42)break;_l(42),jl(98),Hl(),gt()}nc.endNonterminal("LetClause",Wl)}function mt(){Dl(177),jl(98),yt();for(;;){if(Xl!=42)break;Dl(42),jl(98),yt()}}function gt(){nc.startNonterminal("LetBinding",Wl);switch(Xl){case 31:_l(31),jl(247),Hl(),Si(),jl(107),Xl==80&&(Hl(),Ts());break;default:pt()}jl(28),_l(53),jl(268),Hl(),Uf(),nc.endNonterminal("LetBinding",Wl)}function yt(){switch(Xl){case 31:Dl(31),jl(247),xi(),jl(107),Xl==80&&Ns();break;default:dt()}jl(28),Dl(53),jl(268),zf()}function bt(){nc.startNonterminal("WindowClause",Wl);switch(Xl){case 139:_l(139);break;default:_l(142)}jl(137);switch(Xl){case 257:Hl(),Et();break;default:Hl(),xt()}nc.endNonterminal("WindowClause",Wl)}function wt(){switch(Xl){case 139:Dl(139);break;default:Dl(142)}jl(137);switch(Xl){case 257:St();break;default:Tt()}}function Et(){nc.startNonterminal("TumblingWindowClause",Wl),_l(257),jl(87),_l(275),jl(21),_l(31),jl(247),Hl(),Si(),jl(112),Xl==80&&(Hl(),Ts()),jl(56),_l(156),jl(268),Hl(),Uf(),Hl(),Nt();if(Xl==127||Xl==202)Hl(),kt();nc.endNonterminal("TumblingWindowClause",Wl)}function St(){Dl(257),jl(87),Dl(275),jl(21),Dl(31),jl(247),xi(),jl(112),Xl==80&&Ns(),jl(56),Dl(156),jl(268),zf(),Ct(),(Xl==127||Xl==202)&&Lt()}function xt(){nc.startNonterminal("SlidingWindowClause",Wl),_l(239),jl(87),_l(275),jl(21),_l(31),jl(247),Hl(),Si(),jl(112),Xl==80&&(Hl(),Ts()),jl(56),_l(156),jl(268),Hl(),Uf(),Hl(),Nt(),Hl(),kt(),nc.endNonterminal("SlidingWindowClause",Wl)}function Tt(){Dl(239),jl(87),Dl(275),jl(21),Dl(31),jl(247),xi(),jl(112),Xl==80&&Ns(),jl(56),Dl(156),jl(268),zf(),Ct(),Lt()}function Nt(){nc.startNonterminal("WindowStartCondition",Wl),_l(242),jl(182),Hl(),At(),jl(85),_l(271),jl(268),Hl(),Uf(),nc.endNonterminal("WindowStartCondition",Wl)}function Ct(){Dl(242),jl(182),Ot(),jl(85),Dl(271),jl(268),zf()}function kt(){nc.startNonterminal("WindowEndCondition",Wl),Xl==202&&_l(202),jl(53),_l(127),jl(182),Hl(),At(),jl(85),_l(271),jl(268),Hl(),Uf(),nc.endNonterminal("WindowEndCondition",Wl)}function Lt(){Xl==202&&Dl(202),jl(53),Dl(127),jl(182),Ot(),jl(85),Dl(271),jl(268),zf()}function At(){nc.startNonterminal("WindowVars",Wl),Xl==31&&(_l(31),jl(247),Hl(),Mt()),jl(175),Xl==82&&(Hl(),ct()),jl(162),Xl==219&&(_l(219),jl(21),_l(31),jl(247),Hl(),Dt()),jl(129),Xl==190&&(_l(190),jl(21),_l(31),jl(247),Hl(),Ht()),nc.endNonterminal("WindowVars",Wl)}function Ot(){Xl==31&&(Dl(31),jl(247),_t()),jl(175),Xl==82&&ht(),jl(162),Xl==219&&(Dl(219),jl(21),Dl(31),jl(247),Pt()),jl(129),Xl==190&&(Dl(190),jl(21),Dl(31),jl(247),Bt())}function Mt(){nc.startNonterminal("CurrentItem",Wl),Xa(),nc.endNonterminal("CurrentItem",Wl)}function _t(){Va()}function Dt(){nc.startNonterminal("PreviousItem",Wl),Xa(),nc.endNonterminal("PreviousItem",Wl)}function Pt(){Va()}function Ht(){nc.startNonterminal("NextItem",Wl),Xa(),nc.endNonterminal("NextItem",Wl)}function Bt(){Va()}function jt(){nc.startNonterminal("CountClause",Wl),_l(106),jl(21),_l(31),jl(247),Hl(),Si(),nc.endNonterminal("CountClause",Wl)}function Ft(){Dl(106),jl(21),Dl(31),jl(247),xi()}function It(){nc.startNonterminal("WhereClause",Wl),_l(272),jl(268),Hl(),Uf(),nc.endNonterminal("WhereClause",Wl)}function qt(){Dl(272),jl(268),zf()}function Rt(){nc.startNonterminal("GroupByClause",Wl),_l(150),jl(37),_l(88),jl(268),Hl(),zt(),nc.endNonterminal("GroupByClause",Wl)}function Ut(){Dl(150),jl(37),Dl(88),jl(268),Wt()}function zt(){nc.startNonterminal("GroupingSpecList",Wl),Xt();for(;;){jl(202);if(Xl!=42)break;_l(42),jl(268),Hl(),Xt()}nc.endNonterminal("GroupingSpecList",Wl)}function Wt(){Vt();for(;;){jl(202);if(Xl!=42)break;Dl(42),jl(268),Vt()}}function Xt(){nc.startNonterminal("GroupingSpec",Wl);switch(Xl){case 31:Fl(247);break;default:Ul=Xl}if(Ul==3103||Ul==36383||Ul==37407||Ul==37919||Ul==38431||Ul==38943||Ul==39967||Ul==40479||Ul==40991||Ul==41503||Ul==42015||Ul==42527||Ul==43039||Ul==43551||Ul==44063||Ul==44575||Ul==45599||Ul==46111||Ul==46623||Ul==47135||Ul==48159||Ul==48671||Ul==49695||Ul==50207||Ul==50719||Ul==52255||Ul==52767||Ul==53279||Ul==53791||Ul==54303||Ul==54815||Ul==55839||Ul==56351||Ul==56863||Ul==57375||Ul==57887||Ul==58399||Ul==60959||Ul==61471||Ul==61983||Ul==62495||Ul==63007||Ul==63519||Ul==64031||Ul==64543||Ul==65055||Ul==66079||Ul==66591||Ul==67615||Ul==68127||Ul==68639||Ul==69151||Ul==69663||Ul==70175||Ul==70687||Ul==71199||Ul==72735||Ul==73247||Ul==75295||Ul==75807||Ul==76831||Ul==77855||Ul==78367||Ul==78879||Ul==79391||Ul==79903||Ul==80415||Ul==82463||Ul==82975||Ul==83487||Ul==83999||Ul==84511||Ul==85023||Ul==85535||Ul==86047||Ul==86559||Ul==87071||Ul==88607||Ul==89119||Ul==89631||Ul==90655||Ul==91679||Ul==92703||Ul==93727||Ul==94239||Ul==94751||Ul==95775||Ul==96287||Ul==96799||Ul==99359||Ul==99871||Ul==100895||Ul==101407||Ul==103455||Ul==103967||Ul==104479||Ul==104991||Ul==105503||Ul==106015||Ul==107551||Ul==110623||Ul==111135||Ul==112671||Ul==113695||Ul==114207||Ul==114719||Ul==115231||Ul==115743||Ul==116767||Ul==117279||Ul==117791||Ul==118303||Ul==118815||Ul==119327||Ul==119839||Ul==122399||Ul==122911||Ul==123423||Ul==123935||Ul==125471||Ul==126495||Ul==127007||Ul==127519||Ul==129567||Ul==130079||Ul==130591||Ul==131103||Ul==131615||Ul==132127||Ul==132639||Ul==133151||Ul==134175||Ul==134687||Ul==136223||Ul==136735||Ul==137247||Ul==137759||Ul==139295||Ul==139807||Ul==141343){Ul=sc(2,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Jt(),jl(207);if(Xl==53||Xl==80)Xl==80&&Ns(),jl(28),Dl(53),jl(268),zf();Xl==95&&(Dl(95),jl(15),Dl(7)),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(2,Wl,Ul)}}switch(Ul){case-1:$t(),jl(207);if(Xl==53||Xl==80)Xl==80&&(Hl(),Ts()),jl(28),_l(53),jl(268),Hl(),Uf();Xl==95&&(_l(95),jl(15),_l(7));break;default:Uf()}nc.endNonterminal("GroupingSpec",Wl)}function Vt(){switch(Xl){case 31:Fl(247);break;default:Ul=Xl}if(Ul==3103||Ul==36383||Ul==37407||Ul==37919||Ul==38431||Ul==38943||Ul==39967||Ul==40479||Ul==40991||Ul==41503||Ul==42015||Ul==42527||Ul==43039||Ul==43551||Ul==44063||Ul==44575||Ul==45599||Ul==46111||Ul==46623||Ul==47135||Ul==48159||Ul==48671||Ul==49695||Ul==50207||Ul==50719||Ul==52255||Ul==52767||Ul==53279||Ul==53791||Ul==54303||Ul==54815||Ul==55839||Ul==56351||Ul==56863||Ul==57375||Ul==57887||Ul==58399||Ul==60959||Ul==61471||Ul==61983||Ul==62495||Ul==63007||Ul==63519||Ul==64031||Ul==64543||Ul==65055||Ul==66079||Ul==66591||Ul==67615||Ul==68127||Ul==68639||Ul==69151||Ul==69663||Ul==70175||Ul==70687||Ul==71199||Ul==72735||Ul==73247||Ul==75295||Ul==75807||Ul==76831||Ul==77855||Ul==78367||Ul==78879||Ul==79391||Ul==79903||Ul==80415||Ul==82463||Ul==82975||Ul==83487||Ul==83999||Ul==84511||Ul==85023||Ul==85535||Ul==86047||Ul==86559||Ul==87071||Ul==88607||Ul==89119||Ul==89631||Ul==90655||Ul==91679||Ul==92703||Ul==93727||Ul==94239||Ul==94751||Ul==95775||Ul==96287||Ul==96799||Ul==99359||Ul==99871||Ul==100895||Ul==101407||Ul==103455||Ul==103967||Ul==104479||Ul==104991||Ul==105503||Ul==106015||Ul==107551||Ul==110623||Ul==111135||Ul==112671||Ul==113695||Ul==114207||Ul==114719||Ul==115231||Ul==115743||Ul==116767||Ul==117279||Ul==117791||Ul==118303||Ul==118815||Ul==119327||Ul==119839||Ul==122399||Ul==122911||Ul==123423||Ul==123935||Ul==125471||Ul==126495||Ul==127007||Ul==127519||Ul==129567||Ul==130079||Ul==130591||Ul==131103||Ul==131615||Ul==132127||Ul==132639||Ul==133151||Ul==134175||Ul==134687||Ul==136223||Ul==136735||Ul==137247||Ul==137759||Ul==139295||Ul==139807||Ul==141343){Ul=sc(2,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Jt(),jl(207);if(Xl==53||Xl==80)Xl==80&&Ns(),jl(28),Dl(53),jl(268),zf();Xl==95&&(Dl(95),jl(15),Dl(7)),ic(2,t,-1),Ul=-3}catch(a){Ul=-2,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(2,t,-2)}}}switch(Ul){case-1:Jt(),jl(207);if(Xl==53||Xl==80)Xl==80&&Ns(),jl(28),Dl(53),jl(268),zf();Xl==95&&(Dl(95),jl(15),Dl(7));break;case-3:break;default:zf()}}function $t(){nc.startNonterminal("GroupingVariable",Wl),_l(31),jl(247),Hl(),Si(),nc.endNonterminal("GroupingVariable",Wl)}function Jt(){Dl(31),jl(247),xi()}function Kt(){nc.startNonterminal("OrderByClause",Wl);switch(Xl){case 205:_l(205),jl(37),_l(88);break;default:_l(241),jl(70),_l(205),jl(37),_l(88)}jl(268),Hl(),Gt(),nc.endNonterminal("OrderByClause",Wl)}function Qt(){switch(Xl){case 205:Dl(205),jl(37),Dl(88);break;default:Dl(241),jl(70),Dl(205),jl(37),Dl(88)}jl(268),Yt()}function Gt(){nc.startNonterminal("OrderSpecList",Wl),Zt();for(;;){jl(202);if(Xl!=42)break;_l(42),jl(268),Hl(),Zt()}nc.endNonterminal("OrderSpecList",Wl)}function Yt(){en();for(;;){jl(202);if(Xl!=42)break;Dl(42),jl(268),en()}}function Zt(){nc.startNonterminal("OrderSpec",Wl),Uf(),Hl(),tn(),nc.endNonterminal("OrderSpec",Wl)}function en(){zf(),nn()}function tn(){nc.startNonterminal("OrderModifier",Wl);if(Xl==81||Xl==114)switch(Xl){case 81:_l(81);break;default:_l(114)}jl(206);if(Xl==124){_l(124),jl(123);switch(Xl){case 149:_l(149);break;default:_l(176)}}jl(205),Xl==95&&(_l(95),jl(15),_l(7)),nc.endNonterminal("OrderModifier",Wl)}function nn(){if(Xl==81||Xl==114)switch(Xl){case 81:Dl(81);break;default:Dl(114)}jl(206);if(Xl==124){Dl(124),jl(123);switch(Xl){case 149:Dl(149);break;default:Dl(176)}}jl(205),Xl==95&&(Dl(95),jl(15),Dl(7))}function rn(){nc.startNonterminal("ReturnClause",Wl);switch(Xl){case 224:_l(224);break;default:_l(233)}jl(268),Hl(),Uf(),nc.endNonterminal("ReturnClause",Wl)}function sn(){switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(268),zf()}function on(){nc.startNonterminal("QuantifiedExpr",Wl);switch(Xl){case 240:_l(240);break;default:_l(130)}jl(21),_l(31),jl(247),Hl(),Si(),jl(112),Xl==80&&(Hl(),Ts()),jl(56),_l(156),jl(268),Hl(),Uf();for(;;){if(Xl!=42)break;_l(42),jl(21),_l(31),jl(247),Hl(),Si(),jl(112),Xl==80&&(Hl(),Ts()),jl(56),_l(156),jl(268),Hl(),Uf()}_l(228),jl(268),Hl(),Uf(),nc.endNonterminal("QuantifiedExpr",Wl)}function un(){switch(Xl){case 240:Dl(240);break;default:Dl(130)}jl(21),Dl(31),jl(247),xi(),jl(112),Xl==80&&Ns(),jl(56),Dl(156),jl(268),zf();for(;;){if(Xl!=42)break;Dl(42),jl(21),Dl(31),jl(247),xi(),jl(112),Xl==80&&Ns(),jl(56),Dl(156),jl(268),zf()}Dl(228),jl(268),zf()}function an(){nc.startNonterminal("SwitchExpr",Wl),_l(248),jl(22),_l(35),jl(268),Hl(),G(),_l(38);for(;;){jl(38),Hl(),ln();if(Xl!=89)break}_l(110),jl(136);switch(Xl){case 224:_l(224);break;default:_l(233)}jl(268),Hl(),Uf(),nc.endNonterminal("SwitchExpr",Wl)}function fn(){Dl(248),jl(22),Dl(35),jl(268),Y(),Dl(38);for(;;){jl(38),cn();if(Xl!=89)break}Dl(110),jl(136);switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(268),zf()}function ln(){nc.startNonterminal("SwitchCaseClause",Wl);for(;;){_l(89),jl(268),Hl(),hn();if(Xl!=89)break}switch(Xl){case 224:_l(224);break;default:_l(233)}jl(268),Hl(),Uf(),nc.endNonterminal("SwitchCaseClause",Wl)}function cn(){for(;;){Dl(89),jl(268),pn();if(Xl!=89)break}switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(268),zf()}function hn(){nc.startNonterminal("SwitchCaseOperand",Wl),Uf(),nc.endNonterminal("SwitchCaseOperand",Wl)}function pn(){zf()}function dn(){nc.startNonterminal("TypeswitchExpr",Wl),_l(259),jl(22),_l(35),jl(268),Hl(),G(),_l(38);for(;;){jl(38),Hl(),mn();if(Xl!=89)break}_l(110),jl(149),Xl==31&&(_l(31),jl(247),Hl(),Si()),jl(136);switch(Xl){case 224:_l(224);break;default:_l(233)}jl(268),Hl(),Uf(),nc.endNonterminal("TypeswitchExpr",Wl)}function vn(){Dl(259),jl(22),Dl(35),jl(268),Y(),Dl(38);for(;;){jl(38),gn();if(Xl!=89)break}Dl(110),jl(149),Xl==31&&(Dl(31),jl(247),xi()),jl(136);switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(268),zf()}function mn(){nc.startNonterminal("CaseClause",Wl),_l(89),jl(259),Xl==31&&(_l(31),jl(247),Hl(),Si(),jl(33),_l(80)),jl(255),Hl(),yn();switch(Xl){case 224:_l(224);break;default:_l(233)}jl(268),Hl(),Uf(),nc.endNonterminal("CaseClause",Wl)}function gn(){Dl(89),jl(259),Xl==31&&(Dl(31),jl(247),xi(),jl(33),Dl(80)),jl(255),bn();switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(268),zf()}function yn(){nc.startNonterminal("SequenceTypeUnion",Wl),Cs();for(;;){jl(163);if(Xl!=284)break;_l(284),jl(255),Hl(),Cs()}nc.endNonterminal("SequenceTypeUnion",Wl)}function bn(){ks();for(;;){jl(163);if(Xl!=284)break;Dl(284),jl(255),ks()}}function wn(){nc.startNonterminal("IfExpr",Wl),_l(154),jl(22),_l(35),jl(268),Hl(),G(),_l(38),jl(79),_l(250),jl(268),Hl(),Uf(),_l(123),jl(268),Hl(),Uf(),nc.endNonterminal("IfExpr",Wl)}function En(){Dl(154),jl(22),Dl(35),jl(268),Y(),Dl(38),jl(79),Dl(250),jl(268),zf(),Dl(123),jl(268),zf()}function Sn(){nc.startNonterminal("TryCatchExpr",Wl),Tn();for(;;){jl(39),Hl(),Ln(),jl(209);if(Xl!=92)break}nc.endNonterminal("TryCatchExpr",Wl)}function xn(){Nn();for(;;){jl(39),An(),jl(209);if(Xl!=92)break}}function Tn(){nc.startNonterminal("TryClause",Wl),_l(256),jl(89),_l(281),jl(268),Hl(),Cn(),_l(287),nc.endNonterminal("TryClause",Wl)}function Nn(){Dl(256),jl(89),Dl(281),jl(268),kn(),Dl(287)}function Cn(){nc.startNonterminal("TryTargetExpr",Wl),G(),nc.endNonterminal("TryTargetExpr",Wl)}function kn(){Y()}function Ln(){nc.startNonterminal("CatchClause",Wl),_l(92),jl(250),Hl(),On(),_l(281),jl(268),Hl(),G(),_l(287),nc.endNonterminal("CatchClause",Wl)}function An(){Dl(92),jl(250),Mn(),Dl(281),jl(268),Y(),Dl(287)}function On(){nc.startNonterminal("CatchErrorList",Wl),Qr();for(;;){jl(138);if(Xl!=284)break;_l(284),jl(250),Hl(),Qr()}nc.endNonterminal("CatchErrorList",Wl)}function Mn(){Gr();for(;;){jl(138);if(Xl!=284)break;Dl(284),jl(250),Gr()}}function _n(){nc.startNonterminal("OrExpr",Wl),Pn();for(;;){if(Xl!=204)break;_l(204),jl(268),Hl(),Pn()}nc.endNonterminal("OrExpr",Wl)}function Dn(){Hn();for(;;){if(Xl!=204)break;Dl(204),jl(268),Hn()}}function Pn(){nc.startNonterminal("AndExpr",Wl),Bn();for(;;){if(Xl!=76)break;_l(76),jl(268),Hl(),Bn()}nc.endNonterminal("AndExpr",Wl)}function Hn(){jn();for(;;){if(Xl!=76)break;Dl(76),jl(268),jn()}}function Bn(){nc.startNonterminal("NotExpr",Wl);for(;;){jl(268);if(Xl!=196)break;_l(196)}Hl(),Fn(),nc.endNonterminal("NotExpr",Wl)}function jn(){for(;;){jl(268);if(Xl!=196)break;Dl(196)}In()}function Fn(){nc.startNonterminal("ComparisonExpr",Wl),qn();if(Xl==27||Xl==55||Xl==58||Xl==59||Xl==61||Xl==62||Xl==63||Xl==64||Xl==129||Xl==148||Xl==152||Xl==166||Xl==175||Xl==181||Xl==189){switch(Xl){case 129:case 148:case 152:case 175:case 181:case 189:Hl(),mr();break;case 58:case 64:case 166:Hl(),yr();break;default:Hl(),dr()}jl(267),Hl(),qn()}nc.endNonterminal("ComparisonExpr",Wl)}function In(){Rn();if(Xl==27||Xl==55||Xl==58||Xl==59||Xl==61||Xl==62||Xl==63||Xl==64||Xl==129||Xl==148||Xl==152||Xl==166||Xl==175||Xl==181||Xl==189){switch(Xl){case 129:case 148:case 152:case 175:case 181:case 189:gr();break;case 58:case 64:case 166:br();break;default:vr()}jl(267),Rn()}}function qn(){nc.startNonterminal("FTContainsExpr",Wl),Un(),Xl==100&&(_l(100),jl(78),_l(249),jl(178),Hl(),iu(),Xl==277&&(Hl(),Sa())),nc.endNonterminal("FTContainsExpr",Wl)}function Rn(){zn(),Xl==100&&(Dl(100),jl(78),Dl(249),jl(178),su(),Xl==277&&xa())}function Un(){nc.startNonterminal("StringConcatExpr",Wl),Wn();for(;;){if(Xl!=285)break;_l(285),jl(267),Hl(),Wn()}nc.endNonterminal("StringConcatExpr",Wl)}function zn(){Xn();for(;;){if(Xl!=285)break;Dl(285),jl(267),Xn()}}function Wn(){nc.startNonterminal("RangeExpr",Wl),Vn(),Xl==253&&(_l(253),jl(267),Hl(),Vn()),nc.endNonterminal("RangeExpr",Wl)}function Xn(){$n(),Xl==253&&(Dl(253),jl(267),$n())}function Vn(){nc.startNonterminal("AdditiveExpr",Wl),Jn();for(;;){if(Xl!=41&&Xl!=43)break;switch(Xl){case 41:_l(41);break;default:_l(43)}jl(267),Hl(),Jn()}nc.endNonterminal("AdditiveExpr",Wl)}function $n(){Kn();for(;;){if(Xl!=41&&Xl!=43)break;switch(Xl){case 41:Dl(41);break;default:Dl(43)}jl(267),Kn()}}function Jn(){nc.startNonterminal("MultiplicativeExpr",Wl),Qn();for(;;){if(Xl!=39&&Xl!=119&&Xl!=153&&Xl!=183)break;switch(Xl){case 39:_l(39);break;case 119:_l(119);break;case 153:_l(153);break;default:_l(183)}jl(267),Hl(),Qn()}nc.endNonterminal("MultiplicativeExpr",Wl)}function Kn(){Gn();for(;;){if(Xl!=39&&Xl!=119&&Xl!=153&&Xl!=183)break;switch(Xl){case 39:Dl(39);break;case 119:Dl(119);break;case 153:Dl(153);break;default:Dl(183)}jl(267),Gn()}}function Qn(){nc.startNonterminal("UnionExpr",Wl),Yn();for(;;){if(Xl!=260&&Xl!=284)break;switch(Xl){case 260:_l(260);break;default:_l(284)}jl(267),Hl(),Yn()}nc.endNonterminal("UnionExpr",Wl)}function Gn(){Zn();for(;;){if(Xl!=260&&Xl!=284)break;switch(Xl){case 260:Dl(260);break;default:Dl(284)}jl(267),Zn()}}function Yn(){nc.startNonterminal("IntersectExceptExpr",Wl),er();for(;;){jl(223);if(Xl!=132&&Xl!=164)break;switch(Xl){case 164:_l(164);break;default:_l(132)}jl(267),Hl(),er()}nc.endNonterminal("IntersectExceptExpr",Wl)}function Zn(){tr();for(;;){jl(223);if(Xl!=132&&Xl!=164)break;switch(Xl){case 164:Dl(164);break;default:Dl(132)}jl(267),tr()}}function er(){nc.startNonterminal("InstanceofExpr",Wl),nr(),jl(224),Xl==162&&(_l(162),jl(67),_l(200),jl(255),Hl(),Cs()),nc.endNonterminal("InstanceofExpr",Wl)}function tr(){rr(),jl(224),Xl==162&&(Dl(162),jl(67),Dl(200),jl(255),ks())}function nr(){nc.startNonterminal("TreatExpr",Wl),ir(),jl(225),Xl==254&&(_l(254),jl(33),_l(80),jl(255),Hl(),Cs()),nc.endNonterminal("TreatExpr",Wl)}function rr(){sr(),jl(225),Xl==254&&(Dl(254),jl(33),Dl(80),jl(255),ks())}function ir(){nc.startNonterminal("CastableExpr",Wl),or(),jl(226),Xl==91&&(_l(91),jl(33),_l(80),jl(247),Hl(),Ss()),nc.endNonterminal("CastableExpr",Wl)}function sr(){ur(),jl(226),Xl==91&&(Dl(91),jl(33),Dl(80),jl(247),xs())}function or(){nc.startNonterminal("CastExpr",Wl),ar(),jl(228),Xl==90&&(_l(90),jl(33),_l(80),jl(247),Hl(),Ss()),nc.endNonterminal("CastExpr",Wl)}function ur(){fr(),jl(228),Xl==90&&(Dl(90),jl(33),Dl(80),jl(247),xs())}function ar(){nc.startNonterminal("UnaryExpr",Wl);for(;;){jl(267);if(Xl!=41&&Xl!=43)break;switch(Xl){case 43:_l(43);break;default:_l(41)}}Hl(),lr(),nc.endNonterminal("UnaryExpr",Wl)}function fr(){for(;;){jl(267);if(Xl!=41&&Xl!=43)break;switch(Xl){case 43:Dl(43);break;default:Dl(41)}}cr()}function lr(){nc.startNonterminal("ValueExpr",Wl);switch(Xl){case 266:Fl(189);break;default:Ul=Xl}switch(Ul){case 89354:case 125706:case 132362:case 144138:wr();break;case 36:Tr();break;default:hr()}nc.endNonterminal("ValueExpr",Wl)}function cr(){switch(Xl){case 266:Fl(189);break;default:Ul=Xl}switch(Ul){case 89354:case 125706:case 132362:case 144138:Er();break;case 36:Nr();break;default:pr()}}function hr(){nc.startNonterminal("SimpleMapExpr",Wl),Lr();for(;;){if(Xl!=26)break;_l(26),jl(264),Hl(),Lr()}nc.endNonterminal("SimpleMapExpr",Wl)}function pr(){Ar();for(;;){if(Xl!=26)break;Dl(26),jl(264),Ar()}}function dr(){nc.startNonterminal("GeneralComp",Wl);switch(Xl){case 61:_l(61);break;case 27:_l(27);break;case 55:_l(55);break;case 59:_l(59);break;case 62:_l(62);break;default:_l(63)}nc.endNonterminal("GeneralComp",Wl)}function vr(){switch(Xl){case 61:Dl(61);break;case 27:Dl(27);break;case 55:Dl(55);break;case 59:Dl(59);break;case 62:Dl(62);break;default:Dl(63)}}function mr(){nc.startNonterminal("ValueComp",Wl);switch(Xl){case 129:_l(129);break;case 189:_l(189);break;case 181:_l(181);break;case 175:_l(175);break;case 152:_l(152);break;default:_l(148)}nc.endNonterminal("ValueComp",Wl)}function gr(){switch(Xl){case 129:Dl(129);break;case 189:Dl(189);break;case 181:Dl(181);break;case 175:Dl(175);break;case 152:Dl(152);break;default:Dl(148)}}function yr(){nc.startNonterminal("NodeComp",Wl);switch(Xl){case 166:_l(166);break;case 58:_l(58);break;default:_l(64)}nc.endNonterminal("NodeComp",Wl)}function br(){switch(Xl){case 166:Dl(166);break;case 58:Dl(58);break;default:Dl(64)}}function wr(){nc.startNonterminal("ValidateExpr",Wl),_l(266),jl(176);if(Xl!=281)switch(Xl){case 258:_l(258),jl(247),Hl(),ko();break;default:Hl(),Sr()}jl(89),_l(281),jl(268),Hl(),G(),_l(287),nc.endNonterminal("ValidateExpr",Wl)}function Er(){Dl(266),jl(176);if(Xl!=281)switch(Xl){case 258:Dl(258),jl(247),Lo();break;default:xr()}jl(89),Dl(281),jl(268),Y(),Dl(287)}function Sr(){nc.startNonterminal("ValidationMode",Wl);switch(Xl){case 174:_l(174);break;default:_l(245)}nc.endNonterminal("ValidationMode",Wl)}function xr(){switch(Xl){case 174:Dl(174);break;default:Dl(245)}}function Tr(){nc.startNonterminal("ExtensionExpr",Wl);for(;;){Hl(),Cr(),jl(102);if(Xl!=36)break}_l(281),jl(276),Xl!=287&&(Hl(),G()),_l(287),nc.endNonterminal("ExtensionExpr",Wl)}function Nr(){for(;;){kr(),jl(102);if(Xl!=36)break}Dl(281),jl(276),Xl!=287&&Y(),Dl(287)}function Cr(){nc.startNonterminal("Pragma",Wl),_l(36),Il(244),Xl==21&&_l(21),Xa(),Il(10),Xl==21&&(_l(21),Il(0),_l(1)),Il(5),_l(30),nc.endNonterminal("Pragma",Wl)}function kr(){Dl(36),Il(244),Xl==21&&Dl(21),Va(),Il(10),Xl==21&&(Dl(21),Il(0),Dl(1)),Il(5),Dl(30)}function Lr(){nc.startNonterminal("PathExpr",Wl);switch(Xl){case 47:_l(47),jl(290);switch(Xl){case 25:case 26:case 27:case 38:case 39:case 41:case 42:case 43:case 50:case 54:case 58:case 59:case 61:case 62:case 63:case 64:case 70:case 88:case 100:case 209:case 237:case 252:case 279:case 284:case 285:case 286:case 287:break;default:Hl(),Or()}break;case 48:_l(48),jl(261),Hl(),Or();break;default:Or()}nc.endNonterminal("PathExpr",Wl)}function Ar(){switch(Xl){case 47:Dl(47),jl(290);switch(Xl){case 25:case 26:case 27:case 38:case 39:case 41:case 42:case 43:case 50:case 54:case 58:case 59:case 61:case 62:case 63:case 64:case 70:case 88:case 100:case 209:case 237:case 252:case 279:case 284:case 285:case 286:case 287:break;default:Mr()}break;case 48:Dl(48),jl(261),Mr();break;default:Mr()}}function Or(){nc.startNonterminal("RelativePathExpr",Wl),Yr();for(;;){switch(Xl){case 26:Fl(266);break;default:Ul=Xl}if(Ul!=25&&Ul!=27&&Ul!=38&&Ul!=39&&Ul!=41&&Ul!=42&&Ul!=43&&Ul!=47&&Ul!=48&&Ul!=50&&Ul!=54&&Ul!=55&&Ul!=58&&Ul!=59&&Ul!=61&&Ul!=62&&Ul!=63&&Ul!=64&&Ul!=70&&Ul!=71&&Ul!=76&&Ul!=80&&Ul!=81&&Ul!=82&&Ul!=85&&Ul!=88&&Ul!=89&&Ul!=90&&Ul!=91&&Ul!=95&&Ul!=100&&Ul!=106&&Ul!=110&&Ul!=114&&Ul!=119&&Ul!=123&&Ul!=124&&Ul!=127&&Ul!=129&&Ul!=132&&Ul!=139&&Ul!=142&&Ul!=148&&Ul!=150&&Ul!=152&&Ul!=153&&Ul!=162&&Ul!=164&&Ul!=165&&Ul!=166&&Ul!=175&&Ul!=177&&Ul!=181&&Ul!=183&&Ul!=184&&Ul!=189&&Ul!=202&&Ul!=204&&Ul!=205&&Ul!=209&&Ul!=224&&Ul!=228&&Ul!=233&&Ul!=237&&Ul!=241&&Ul!=242&&Ul!=252&&Ul!=253&&Ul!=254&&Ul!=260&&Ul!=272&&Ul!=276&&Ul!=279&&Ul!=284&&Ul!=285&&Ul!=286&&Ul!=287&&Ul!=2586&&Ul!=23578&&Ul!=24090&&Ul!=24602&&Ul!=34330){Ul=sc(3,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{switch(Xl){case 47:Dl(47);break;case 48:Dl(48);break;default:Dl(26)}jl(265),Dr(),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(3,Wl,Ul)}}if(Ul!=-1&&Ul!=47&&Ul!=48&&Ul!=2586&&Ul!=23578&&Ul!=34330)break;switch(Xl){case 47:_l(47);break;case 48:_l(48);break;default:_l(26)}jl(265),Hl(),_r()}nc.endNonterminal("RelativePathExpr",Wl)}function Mr(){Zr();for(;;){switch(Xl){case 26:Fl(266);break;default:Ul=Xl}if(Ul!=25&&Ul!=27&&Ul!=38&&Ul!=39&&Ul!=41&&Ul!=42&&Ul!=43&&Ul!=47&&Ul!=48&&Ul!=50&&Ul!=54&&Ul!=55&&Ul!=58&&Ul!=59&&Ul!=61&&Ul!=62&&Ul!=63&&Ul!=64&&Ul!=70&&Ul!=71&&Ul!=76&&Ul!=80&&Ul!=81&&Ul!=82&&Ul!=85&&Ul!=88&&Ul!=89&&Ul!=90&&Ul!=91&&Ul!=95&&Ul!=100&&Ul!=106&&Ul!=110&&Ul!=114&&Ul!=119&&Ul!=123&&Ul!=124&&Ul!=127&&Ul!=129&&Ul!=132&&Ul!=139&&Ul!=142&&Ul!=148&&Ul!=150&&Ul!=152&&Ul!=153&&Ul!=162&&Ul!=164&&Ul!=165&&Ul!=166&&Ul!=175&&Ul!=177&&Ul!=181&&Ul!=183&&Ul!=184&&Ul!=189&&Ul!=202&&Ul!=204&&Ul!=205&&Ul!=209&&Ul!=224&&Ul!=228&&Ul!=233&&Ul!=237&&Ul!=241&&Ul!=242&&Ul!=252&&Ul!=253&&Ul!=254&&Ul!=260&&Ul!=272&&Ul!=276&&Ul!=279&&Ul!=284&&Ul!=285&&Ul!=286&&Ul!=287&&Ul!=2586&&Ul!=23578&&Ul!=24090&&Ul!=24602&&Ul!=34330){Ul=sc(3,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{switch(Xl){case 47:Dl(47);break;case 48:Dl(48);break;default:Dl(26)}jl(265),Dr(),ic(3,t,-1);continue}catch(a){zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(3,t,-2);break}}}if(Ul!=-1&&Ul!=47&&Ul!=48&&Ul!=2586&&Ul!=23578&&Ul!=34330)break;switch(Xl){case 47:Dl(47);break;case 48:Dl(48);break;default:Dl(26)}jl(265),Dr()}}function _r(){nc.startNonterminal("StepExpr",Wl);switch(Xl){case 83:Fl(289);break;case 122:Fl(288);break;case 187:case 220:Fl(286);break;case 135:case 197:case 255:Fl(238);break;case 97:case 120:case 206:case 249:case 262:Fl(240);break;case 79:case 125:case 154:case 167:case 169:case 247:case 248:case 259:Fl(231);break;case 74:case 75:case 94:case 112:case 113:case 137:case 138:case 210:case 216:case 217:case 234:Fl(239);break;case 6:case 71:case 73:case 76:case 78:case 80:case 81:case 82:case 84:case 85:case 86:case 87:case 89:case 90:case 91:case 92:case 95:case 98:case 99:case 102:case 103:case 104:case 105:case 106:case 107:case 109:case 110:case 111:case 114:case 119:case 121:case 123:case 124:case 126:case 127:case 129:case 130:case 132:case 133:case 134:case 136:case 139:case 142:case 143:case 147:case 148:case 150:case 152:case 153:case 155:case 156:case 157:case 161:case 162:case 163:case 164:case 165:case 166:case 168:case 170:case 173:case 174:case 175:case 177:case 179:case 181:case 183:case 184:case 185:case 188:case 189:case 194:case 195:case 198:case 202:case 203:case 204:case 205:case 207:case 222:case 223:case 224:case 225:case 226:case 228:case 229:case 230:case 231:case 232:case 233:case 239:case 240:case 241:case 242:case 245:case 253:case 254:case 256:case 257:case 258:case 260:case 263:case 266:case 267:case 268:case 269:case 272:case 273:case 276:Fl(235);break;default:Ul=Xl}if(Ul==12935||Ul==12997||Ul==13055||Ul==13447||Ul==13509||Ul==13567||Ul==13959||Ul==14021||Ul==14079||Ul==19591||Ul==19653||Ul==19711||Ul==20103||Ul==20165||Ul==20223||Ul==21127||Ul==21189||Ul==21247||Ul==21639||Ul==21701||Ul==21759||Ul==22151||Ul==22213||Ul==22271||Ul==24199||Ul==24261||Ul==24319||Ul==24711||Ul==24773||Ul==24831||Ul==25735||Ul==25797||Ul==25855||Ul==27783||Ul==27845||Ul==27903||Ul==28295||Ul==28357||Ul==28415||Ul==29831||Ul==29893||Ul==29951||Ul==30343||Ul==30405||Ul==30463||Ul==31367||Ul==31429||Ul==31487||Ul==31879||Ul==31941||Ul==31999||Ul==32391||Ul==32453||Ul==32511||Ul==32903||Ul==32965||Ul==33023||Ul==35463||Ul==35525||Ul==35583||Ul==35975||Ul==36037||Ul==36095||Ul==36435||Ul==36474||Ul==36487||Ul==36539||Ul==36549||Ul==36572||Ul==36607||Ul==38995||Ul==39034||Ul==39047||Ul==39099||Ul==39109||Ul==39132||Ul==39167||Ul==41043||Ul==41082||Ul==41095||Ul==41147||Ul==41157||Ul==41180||Ul==41215||Ul==41555||Ul==41594||Ul==41607||Ul==41659||Ul==41669||Ul==41692||Ul==41727||Ul==42067||Ul==42106||Ul==42119||Ul==42171||Ul==42181||Ul==42204||Ul==42239||Ul==43603||Ul==43642||Ul==43655||Ul==43707||Ul==43717||Ul==43740||Ul==43775||Ul==45191||Ul==45253||Ul==45311||Ul==45651||Ul==45690||Ul==45703||Ul==45755||Ul==45765||Ul==45788||Ul==45823||Ul==46163||Ul==46202||Ul==46215||Ul==46267||Ul==46277||Ul==46300||Ul==46335||Ul==46675||Ul==46714||Ul==46727||Ul==46779||Ul==46789||Ul==46812||Ul==46847||Ul==48723||Ul==48762||Ul==48775||Ul==48827||Ul==48837||Ul==48860||Ul==48895||Ul==51335||Ul==51397||Ul==51455||Ul==54355||Ul==54394||Ul==54407||Ul==54459||Ul==54469||Ul==54492||Ul==54527||Ul==56403||Ul==56442||Ul==56455||Ul==56507||Ul==56517||Ul==56540||Ul==56575||Ul==58451||Ul==58490||Ul==58503||Ul==58555||Ul==58565||Ul==58588||Ul==58623||Ul==61011||Ul==61050||Ul==61063||Ul==61115||Ul==61125||Ul==61148||Ul==61183||Ul==63059||Ul==63098||Ul==63111||Ul==63163||Ul==63173||Ul==63196||Ul==63231||Ul==63571||Ul==63610||Ul==63623||Ul==63675||Ul==63685||Ul==63708||Ul==63743||Ul==65107||Ul==65146||Ul==65159||Ul==65211||Ul==65221||Ul==65244||Ul==65279||Ul==66131||Ul==66170||Ul==66183||Ul==66235||Ul==66245||Ul==66268||Ul==66303||Ul==67667||Ul==67706||Ul==67719||Ul==67771||Ul==67781||Ul==67804||Ul==67839||Ul==71251||Ul==71290||Ul==71303||Ul==71355||Ul==71365||Ul==71388||Ul==71423||Ul==72787||Ul==72826||Ul==72839||Ul==72891||Ul==72901||Ul==72924||Ul==72959||Ul==75859||Ul==75898||Ul==75911||Ul==75963||Ul==75973||Ul==75996||Ul==76031||Ul==76883||Ul==76922||Ul==76935||Ul==76987||Ul==76997||Ul==77020||Ul==77055||Ul==77907||Ul==77946||Ul==77959||Ul==78011||Ul==78021||Ul==78044||Ul==78079||Ul==78419||Ul==78458||Ul==78471||Ul==78523||Ul==78533||Ul==78556||Ul==78591||Ul==83027||Ul==83066||Ul==83079||Ul==83131||Ul==83141||Ul==83164||Ul==83199||Ul==84051||Ul==84090||Ul==84103||Ul==84155||Ul==84165||Ul==84188||Ul==84223||Ul==84563||Ul==84602||Ul==84615||Ul==84667||Ul==84677||Ul==84700||Ul==84735||Ul==85075||Ul==85114||Ul==85127||Ul==85179||Ul==85189||Ul==85212||Ul==85247||Ul==89683||Ul==89722||Ul==89735||Ul==89787||Ul==89797||Ul==89820||Ul==89855||Ul==90707||Ul==90746||Ul==90759||Ul==90811||Ul==90821||Ul==90844||Ul==90879||Ul==92755||Ul==92794||Ul==92807||Ul==92859||Ul==92869||Ul==92892||Ul==92927||Ul==93779||Ul==93818||Ul==93831||Ul==93883||Ul==93893||Ul==93916||Ul==93951||Ul==94291||Ul==94330||Ul==94343||Ul==94395||Ul==94405||Ul==94428||Ul==94463||Ul==96851||Ul==96890||Ul==96903||Ul==96955||Ul==96965||Ul==96988||Ul==97023||Ul==103507||Ul==103546||Ul==103559||Ul==103611||Ul==103621||Ul==103644||Ul==103679||Ul==104531||Ul==104570||Ul==104583||Ul==104635||Ul==104645||Ul==104668||Ul==104703||Ul==105043||Ul==105082||Ul==105095||Ul==105147||Ul==105157||Ul==105180||Ul==105215||Ul==107143||Ul==107205||Ul==107263||Ul==114771||Ul==114810||Ul==114823||Ul==114875||Ul==114885||Ul==114908||Ul==114943||Ul==116819||Ul==116858||Ul==116871||Ul==116923||Ul==116933||Ul==116956||Ul==116991||Ul==119379||Ul==119418||Ul==119431||Ul==119483||Ul==119493||Ul==119516||Ul==119551||Ul==121479||Ul==121541||Ul==121599||Ul==123475||Ul==123514||Ul==123527||Ul==123579||Ul==123589||Ul==123612||Ul==123647||Ul==123987||Ul==124026||Ul==124039||Ul==124091||Ul==124101||Ul==124124||Ul==124159||Ul==129159||Ul==129221||Ul==129279||Ul==129619||Ul==129658||Ul==129671||Ul==129723||Ul==129733||Ul==129756||Ul==129791||Ul==130131||Ul==130170||Ul==130183||Ul==130235||Ul==130245||Ul==130268||Ul==130303||Ul==133203||Ul==133242||Ul==133255||Ul==133307||Ul==133317||Ul==133340||Ul==133375||Ul==139347||Ul==139386||Ul==139399||Ul==139451||Ul==139461||Ul==139484||Ul==139519||Ul==141395||Ul==141434||Ul==141447||Ul==141499||Ul==141509||Ul==141532||Ul==141567||Ul==142983||Ul==143045||Ul==143103||Ul==145543||Ul==145605||Ul==145663||Ul==146055||Ul==146117||Ul==146175||Ul==146567||Ul==146629||Ul==146687||Ul==147079||Ul==147141||Ul==147199){Ul=sc(4,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Zr(),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(4,Wl,Ul)}}switch(Ul){case-1:case 8:case 9:case 10:case 11:case 31:case 32:case 33:case 35:case 55:case 56:case 60:case 69:case 281:case 283:case 3155:case 3194:case 9915:case 9948:case 14854:case 14919:case 14921:case 14922:case 14923:case 14924:case 14926:case 14927:case 14928:case 14929:case 14930:case 14931:case 14932:case 14933:case 14934:case 14935:case 14937:case 14938:case 14939:case 14940:case 14942:case 14943:case 14945:case 14946:case 14947:case 14950:case 14951:case 14952:case 14953:case 14954:case 14955:case 14957:case 14958:case 14959:case 14960:case 14961:case 14962:case 14967:case 14968:case 14969:case 14970:case 14971:case 14972:case 14973:case 14974:case 14975:case 14977:case 14978:case 14980:case 14981:case 14982:case 14983:case 14984:case 14985:case 14986:case 14987:case 14990:case 14991:case 14995:case 14996:case 14998:case 15e3:case 15001:case 15002:case 15003:case 15004:case 15005:case 15009:case 15010:case 15011:case 15012:case 15013:case 15014:case 15015:case 15016:case 15017:case 15018:case 15021:case 15022:case 15023:case 15025:case 15027:case 15029:case 15031:case 15032:case 15033:case 15035:case 15036:case 15037:case 15042:case 15043:case 15045:case 15046:case 15050:case 15051:case 15052:case 15053:case 15054:case 15055:case 15058:case 15064:case 15065:case 15068:case 15070:case 15071:case 15072:case 15073:case 15074:case 15076:case 15077:case 15078:case 15079:case 15080:case 15081:case 15082:case 15087:case 15088:case 15089:case 15090:case 15093:case 15095:case 15096:case 15097:case 15101:case 15102:case 15103:case 15104:case 15105:case 15106:case 15107:case 15108:case 15110:case 15111:case 15114:case 15115:case 15116:case 15117:case 15120:case 15121:case 15124:case 17926:case 17991:case 17993:case 17994:case 17995:case 17996:case 17998:case 18e3:case 18001:case 18002:case 18004:case 18005:case 18006:case 18007:case 18009:case 18010:case 18011:case 18012:case 18014:case 18015:case 18018:case 18019:case 18022:case 18023:case 18024:case 18025:case 18026:case 18027:case 18029:case 18030:case 18031:case 18032:case 18033:case 18034:case 18039:case 18040:case 18043:case 18044:case 18046:case 18047:case 18049:case 18050:case 18052:case 18053:case 18054:case 18055:case 18056:case 18057:case 18058:case 18059:case 18062:case 18063:case 18067:case 18068:case 18070:case 18072:case 18073:case 18075:case 18076:case 18077:case 18081:case 18082:case 18083:case 18084:case 18085:case 18086:case 18088:case 18090:case 18093:case 18094:case 18095:case 18097:case 18099:case 18101:case 18103:case 18104:case 18105:case 18107:case 18109:case 18115:case 18117:case 18118:case 18122:case 18123:case 18124:case 18125:case 18126:case 18127:case 18130:case 18136:case 18137:case 18142:case 18143:case 18144:case 18145:case 18146:case 18148:case 18149:case 18152:case 18153:case 18154:case 18159:case 18160:case 18161:case 18162:case 18165:case 18173:case 18174:case 18175:case 18176:case 18177:case 18178:case 18180:case 18182:case 18183:case 18186:case 18187:case 18188:case 18189:case 18192:case 18193:case 18196:case 23175:case 23237:case 23295:case 37459:case 37498:case 37563:case 37596:case 37971:case 38010:case 38075:case 38108:case 38483:case 38522:case 38587:case 38620:case 40019:case 40058:case 40123:case 40156:case 40531:case 40570:case 42579:case 42618:case 42683:case 42716:case 43091:case 43130:case 43195:case 43228:case 44115:case 44154:case 44219:case 44252:case 44627:case 44666:case 44731:case 44764:case 47187:case 47226:case 47291:case 47324:case 48211:case 48250:case 48315:case 48348:case 49747:case 49786:case 49851:case 49884:case 50259:case 50298:case 50363:case 50396:case 50771:case 50810:case 50875:case 50908:case 52307:case 52346:case 52411:case 52444:case 52819:case 52858:case 52923:case 52956:case 53331:case 53370:case 53435:case 53468:case 53843:case 53882:case 53947:case 53980:case 54867:case 54906:case 54971:case 55004:case 55891:case 55930:case 55995:case 56028:case 56915:case 56954:case 57019:case 57052:case 57427:case 57466:case 57531:case 57564:case 57939:case 57978:case 58043:case 58076:case 61523:case 61562:case 61627:case 61660:case 62035:case 62074:case 62139:case 62172:case 62547:case 62586:case 62651:case 62684:case 64083:case 64122:case 64187:case 64220:case 64595:case 64634:case 64699:case 64732:case 66643:case 66682:case 66747:case 66780:case 68179:case 68218:case 68283:case 68316:case 68691:case 68730:case 68795:case 68828:case 69203:case 69242:case 69307:case 69340:case 69715:case 69754:case 69819:case 69852:case 70227:case 70266:case 70331:case 70364:case 70739:case 70778:case 70843:case 70876:case 73299:case 73338:case 73403:case 73436:case 75347:case 75386:case 75451:case 75484:case 78931:case 78970:case 79035:case 79068:case 79443:case 79482:case 79547:case 79580:case 79955:case 79994:case 80059:case 80092:case 80467:case 80506:case 80571:case 80604:case 82515:case 82554:case 82619:case 82652:case 83539:case 83578:case 83643:case 83676:case 85587:case 85626:case 85691:case 85724:case 86099:case 86138:case 86203:case 86236:case 86611:case 86650:case 87123:case 87162:case 87227:case 87260:case 88659:case 88698:case 88763:case 88796:case 89171:case 89210:case 89275:case 89308:case 91731:case 91770:case 91835:case 91868:case 94803:case 94842:case 94907:case 94940:case 95827:case 95866:case 95931:case 95964:case 96339:case 96378:case 96443:case 96476:case 99411:case 99450:case 99515:case 99548:case 99923:case 99962:case 100027:case 100060:case 100947:case 100986:case 101051:case 101084:case 101459:case 101498:case 101563:case 101596:case 104019:case 104058:case 104123:case 104156:case 105555:case 105594:case 105659:case 105692:case 106067:case 106106:case 106171:case 106204:case 107603:case 107642:case 107707:case 107740:case 110675:case 110714:case 110779:case 110812:case 111187:case 111226:case 111291:case 111324:case 112723:case 112762:case 112827:case 112860:case 113747:case 113786:case 113851:case 113884:case 114259:case 114298:case 114363:case 114396:case 115283:case 115322:case 115387:case 115420:case 115795:case 115834:case 115899:case 115932:case 117331:case 117370:case 117435:case 117468:case 117843:case 117882:case 117947:case 117980:case 118355:case 118394:case 118459:case 118492:case 118867:case 118906:case 118971:case 119004:case 119891:case 119930:case 119995:case 120028:case 122451:case 122490:case 122555:case 122588:case 122963:case 123002:case 123067:case 123100:case 125523:case 125562:case 125627:case 125660:case 126547:case 126586:case 127059:case 127098:case 127163:case 127196:case 127571:case 127610:case 127675:case 127708:case 130643:case 130682:case 130747:case 130780:case 131155:case 131194:case 131259:case 131292:case 131667:case 131706:case 131771:case 131804:case 132179:case 132218:case 132283:case 132316:case 132691:case 132730:case 132795:case 132828:case 134227:case 134266:case 134331:case 134364:case 134739:case 134778:case 134843:case 134876:case 136275:case 136314:case 136379:case 136412:case 136787:case 136826:case 136891:case 136924:case 137299:case 137338:case 137403:case 137436:case 137811:case 137850:case 137915:case 137948:case 139859:case 139898:case 139963:case 139996:case 143955:case 143969:case 143992:case 143994:case 144059:case 144078:case 144092:case 144121:case 144134:Yr();break;default:Pr()}nc.endNonterminal("StepExpr",Wl)}function Dr(){switch(Xl){case 83:Fl(289);break;case 122:Fl(288);break;case 187:case 220:Fl(286);break;case 135:case 197:case 255:Fl(238);break;case 97:case 120:case 206:case 249:case 262:Fl(240);break;case 79:case 125:case 154:case 167:case 169:case 247:case 248:case 259:Fl(231);break;case 74:case 75:case 94:case 112:case 113:case 137:case 138:case 210:case 216:case 217:case 234:Fl(239);break;case 6:case 71:case 73:case 76:case 78:case 80:case 81:case 82:case 84:case 85:case 86:case 87:case 89:case 90:case 91:case 92:case 95:case 98:case 99:case 102:case 103:case 104:case 105:case 106:case 107:case 109:case 110:case 111:case 114:case 119:case 121:case 123:case 124:case 126:case 127:case 129:case 130:case 132:case 133:case 134:case 136:case 139:case 142:case 143:case 147:case 148:case 150:case 152:case 153:case 155:case 156:case 157:case 161:case 162:case 163:case 164:case 165:case 166:case 168:case 170:case 173:case 174:case 175:case 177:case 179:case 181:case 183:case 184:case 185:case 188:case 189:case 194:case 195:case 198:case 202:case 203:case 204:case 205:case 207:case 222:case 223:case 224:case 225:case 226:case 228:case 229:case 230:case 231:case 232:case 233:case 239:case 240:case 241:case 242:case 245:case 253:case 254:case 256:case 257:case 258:case 260:case 263:case 266:case 267:case 268:case 269:case 272:case 273:case 276:Fl(235);break;default:Ul=Xl}if(Ul==12935||Ul==12997||Ul==13055||Ul==13447||Ul==13509||Ul==13567||Ul==13959||Ul==14021||Ul==14079||Ul==19591||Ul==19653||Ul==19711||Ul==20103||Ul==20165||Ul==20223||Ul==21127||Ul==21189||Ul==21247||Ul==21639||Ul==21701||Ul==21759||Ul==22151||Ul==22213||Ul==22271||Ul==24199||Ul==24261||Ul==24319||Ul==24711||Ul==24773||Ul==24831||Ul==25735||Ul==25797||Ul==25855||Ul==27783||Ul==27845||Ul==27903||Ul==28295||Ul==28357||Ul==28415||Ul==29831||Ul==29893||Ul==29951||Ul==30343||Ul==30405||Ul==30463||Ul==31367||Ul==31429||Ul==31487||Ul==31879||Ul==31941||Ul==31999||Ul==32391||Ul==32453||Ul==32511||Ul==32903||Ul==32965||Ul==33023||Ul==35463||Ul==35525||Ul==35583||Ul==35975||Ul==36037||Ul==36095||Ul==36435||Ul==36474||Ul==36487||Ul==36539||Ul==36549||Ul==36572||Ul==36607||Ul==38995||Ul==39034||Ul==39047||Ul==39099||Ul==39109||Ul==39132||Ul==39167||Ul==41043||Ul==41082||Ul==41095||Ul==41147||Ul==41157||Ul==41180||Ul==41215||Ul==41555||Ul==41594||Ul==41607||Ul==41659||Ul==41669||Ul==41692||Ul==41727||Ul==42067||Ul==42106||Ul==42119||Ul==42171||Ul==42181||Ul==42204||Ul==42239||Ul==43603||Ul==43642||Ul==43655||Ul==43707||Ul==43717||Ul==43740||Ul==43775||Ul==45191||Ul==45253||Ul==45311||Ul==45651||Ul==45690||Ul==45703||Ul==45755||Ul==45765||Ul==45788||Ul==45823||Ul==46163||Ul==46202||Ul==46215||Ul==46267||Ul==46277||Ul==46300||Ul==46335||Ul==46675||Ul==46714||Ul==46727||Ul==46779||Ul==46789||Ul==46812||Ul==46847||Ul==48723||Ul==48762||Ul==48775||Ul==48827||Ul==48837||Ul==48860||Ul==48895||Ul==51335||Ul==51397||Ul==51455||Ul==54355||Ul==54394||Ul==54407||Ul==54459||Ul==54469||Ul==54492||Ul==54527||Ul==56403||Ul==56442||Ul==56455||Ul==56507||Ul==56517||Ul==56540||Ul==56575||Ul==58451||Ul==58490||Ul==58503||Ul==58555||Ul==58565||Ul==58588||Ul==58623||Ul==61011||Ul==61050||Ul==61063||Ul==61115||Ul==61125||Ul==61148||Ul==61183||Ul==63059||Ul==63098||Ul==63111||Ul==63163||Ul==63173||Ul==63196||Ul==63231||Ul==63571||Ul==63610||Ul==63623||Ul==63675||Ul==63685||Ul==63708||Ul==63743||Ul==65107||Ul==65146||Ul==65159||Ul==65211||Ul==65221||Ul==65244||Ul==65279||Ul==66131||Ul==66170||Ul==66183||Ul==66235||Ul==66245||Ul==66268||Ul==66303||Ul==67667||Ul==67706||Ul==67719||Ul==67771||Ul==67781||Ul==67804||Ul==67839||Ul==71251||Ul==71290||Ul==71303||Ul==71355||Ul==71365||Ul==71388||Ul==71423||Ul==72787||Ul==72826||Ul==72839||Ul==72891||Ul==72901||Ul==72924||Ul==72959||Ul==75859||Ul==75898||Ul==75911||Ul==75963||Ul==75973||Ul==75996||Ul==76031||Ul==76883||Ul==76922||Ul==76935||Ul==76987||Ul==76997||Ul==77020||Ul==77055||Ul==77907||Ul==77946||Ul==77959||Ul==78011||Ul==78021||Ul==78044||Ul==78079||Ul==78419||Ul==78458||Ul==78471||Ul==78523||Ul==78533||Ul==78556||Ul==78591||Ul==83027||Ul==83066||Ul==83079||Ul==83131||Ul==83141||Ul==83164||Ul==83199||Ul==84051||Ul==84090||Ul==84103||Ul==84155||Ul==84165||Ul==84188||Ul==84223||Ul==84563||Ul==84602||Ul==84615||Ul==84667||Ul==84677||Ul==84700||Ul==84735||Ul==85075||Ul==85114||Ul==85127||Ul==85179||Ul==85189||Ul==85212||Ul==85247||Ul==89683||Ul==89722||Ul==89735||Ul==89787||Ul==89797||Ul==89820||Ul==89855||Ul==90707||Ul==90746||Ul==90759||Ul==90811||Ul==90821||Ul==90844||Ul==90879||Ul==92755||Ul==92794||Ul==92807||Ul==92859||Ul==92869||Ul==92892||Ul==92927||Ul==93779||Ul==93818||Ul==93831||Ul==93883||Ul==93893||Ul==93916||Ul==93951||Ul==94291||Ul==94330||Ul==94343||Ul==94395||Ul==94405||Ul==94428||Ul==94463||Ul==96851||Ul==96890||Ul==96903||Ul==96955||Ul==96965||Ul==96988||Ul==97023||Ul==103507||Ul==103546||Ul==103559||Ul==103611||Ul==103621||Ul==103644||Ul==103679||Ul==104531||Ul==104570||Ul==104583||Ul==104635||Ul==104645||Ul==104668||Ul==104703||Ul==105043||Ul==105082||Ul==105095||Ul==105147||Ul==105157||Ul==105180||Ul==105215||Ul==107143||Ul==107205||Ul==107263||Ul==114771||Ul==114810||Ul==114823||Ul==114875||Ul==114885||Ul==114908||Ul==114943||Ul==116819||Ul==116858||Ul==116871||Ul==116923||Ul==116933||Ul==116956||Ul==116991||Ul==119379||Ul==119418||Ul==119431||Ul==119483||Ul==119493||Ul==119516||Ul==119551||Ul==121479||Ul==121541||Ul==121599||Ul==123475||Ul==123514||Ul==123527||Ul==123579||Ul==123589||Ul==123612||Ul==123647||Ul==123987||Ul==124026||Ul==124039||Ul==124091||Ul==124101||Ul==124124||Ul==124159||Ul==129159||Ul==129221||Ul==129279||Ul==129619||Ul==129658||Ul==129671||Ul==129723||Ul==129733||Ul==129756||Ul==129791||Ul==130131||Ul==130170||Ul==130183||Ul==130235||Ul==130245||Ul==130268||Ul==130303||Ul==133203||Ul==133242||Ul==133255||Ul==133307||Ul==133317||Ul==133340||Ul==133375||Ul==139347||Ul==139386||Ul==139399||Ul==139451||Ul==139461||Ul==139484||Ul==139519||Ul==141395||Ul==141434||Ul==141447||Ul==141499||Ul==141509||Ul==141532||Ul==141567||Ul==142983||Ul==143045||Ul==143103||Ul==145543||Ul==145605||Ul==145663||Ul==146055||Ul==146117||Ul==146175||Ul==146567||Ul==146629||Ul==146687||Ul==147079||Ul==147141||Ul==147199){Ul=sc(4,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Zr(),ic(4,t,-1),Ul=-3}catch(a){Ul=-2,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(4,t,-2)}}}switch(Ul){case-1:case 8:case 9:case 10:case 11:case 31:case 32:case 33:case 35:case 55:case 56:case 60:case 69:case 281:case 283:case 3155:case 3194:case 9915:case 9948:case 14854:case 14919:case 14921:case 14922:case 14923:case 14924:case 14926:case 14927:case 14928:case 14929:case 14930:case 14931:case 14932:case 14933:case 14934:case 14935:case 14937:case 14938:case 14939:case 14940:case 14942:case 14943:case 14945:case 14946:case 14947:case 14950:case 14951:case 14952:case 14953:case 14954:case 14955:case 14957:case 14958:case 14959:case 14960:case 14961:case 14962:case 14967:case 14968:case 14969:case 14970:case 14971:case 14972:case 14973:case 14974:case 14975:case 14977:case 14978:case 14980:case 14981:case 14982:case 14983:case 14984:case 14985:case 14986:case 14987:case 14990:case 14991:case 14995:case 14996:case 14998:case 15e3:case 15001:case 15002:case 15003:case 15004:case 15005:case 15009:case 15010:case 15011:case 15012:case 15013:case 15014:case 15015:case 15016:case 15017:case 15018:case 15021:case 15022:case 15023:case 15025:case 15027:case 15029:case 15031:case 15032:case 15033:case 15035:case 15036:case 15037:case 15042:case 15043:case 15045:case 15046:case 15050:case 15051:case 15052:case 15053:case 15054:case 15055:case 15058:case 15064:case 15065:case 15068:case 15070:case 15071:case 15072:case 15073:case 15074:case 15076:case 15077:case 15078:case 15079:case 15080:case 15081:case 15082:case 15087:case 15088:case 15089:case 15090:case 15093:case 15095:case 15096:case 15097:case 15101:case 15102:case 15103:case 15104:case 15105:case 15106:case 15107:case 15108:case 15110:case 15111:case 15114:case 15115:case 15116:case 15117:case 15120:case 15121:case 15124:case 17926:case 17991:case 17993:case 17994:case 17995:case 17996:case 17998:case 18e3:case 18001:case 18002:case 18004:case 18005:case 18006:case 18007:case 18009:case 18010:case 18011:case 18012:case 18014:case 18015:case 18018:case 18019:case 18022:case 18023:case 18024:case 18025:case 18026:case 18027:case 18029:case 18030:case 18031:case 18032:case 18033:case 18034:case 18039:case 18040:case 18043:case 18044:case 18046:case 18047:case 18049:case 18050:case 18052:case 18053:case 18054:case 18055:case 18056:case 18057:case 18058:case 18059:case 18062:case 18063:case 18067:case 18068:case 18070:case 18072:case 18073:case 18075:case 18076:case 18077:case 18081:case 18082:case 18083:case 18084:case 18085:case 18086:case 18088:case 18090:case 18093:case 18094:case 18095:case 18097:case 18099:case 18101:case 18103:case 18104:case 18105:case 18107:case 18109:case 18115:case 18117:case 18118:case 18122:case 18123:case 18124:case 18125:case 18126:case 18127:case 18130:case 18136:case 18137:case 18142:case 18143:case 18144:case 18145:case 18146:case 18148:case 18149:case 18152:case 18153:case 18154:case 18159:case 18160:case 18161:case 18162:case 18165:case 18173:case 18174:case 18175:case 18176:case 18177:case 18178:case 18180:case 18182:case 18183:case 18186:case 18187:case 18188:case 18189:case 18192:case 18193:case 18196:case 23175:case 23237:case 23295:case 37459:case 37498:case 37563:case 37596:case 37971:case 38010:case 38075:case 38108:case 38483:case 38522:case 38587:case 38620:case 40019:case 40058:case 40123:case 40156:case 40531:case 40570:case 42579:case 42618:case 42683:case 42716:case 43091:case 43130:case 43195:case 43228:case 44115:case 44154:case 44219:case 44252:case 44627:case 44666:case 44731:case 44764:case 47187:case 47226:case 47291:case 47324:case 48211:case 48250:case 48315:case 48348:case 49747:case 49786:case 49851:case 49884:case 50259:case 50298:case 50363:case 50396:case 50771:case 50810:case 50875:case 50908:case 52307:case 52346:case 52411:case 52444:case 52819:case 52858:case 52923:case 52956:case 53331:case 53370:case 53435:case 53468:case 53843:case 53882:case 53947:case 53980:case 54867:case 54906:case 54971:case 55004:case 55891:case 55930:case 55995:case 56028:case 56915:case 56954:case 57019:case 57052:case 57427:case 57466:case 57531:case 57564:case 57939:case 57978:case 58043:case 58076:case 61523:case 61562:case 61627:case 61660:case 62035:case 62074:case 62139:case 62172:case 62547:case 62586:case 62651:case 62684:case 64083:case 64122:case 64187:case 64220:case 64595:case 64634:case 64699:case 64732:case 66643:case 66682:case 66747:case 66780:case 68179:case 68218:case 68283:case 68316:case 68691:case 68730:case 68795:case 68828:case 69203:case 69242:case 69307:case 69340:case 69715:case 69754:case 69819:case 69852:case 70227:case 70266:case 70331:case 70364:case 70739:case 70778:case 70843:case 70876:case 73299:case 73338:case 73403:case 73436:case 75347:case 75386:case 75451:case 75484:case 78931:case 78970:case 79035:case 79068:case 79443:case 79482:case 79547:case 79580:case 79955:case 79994:case 80059:case 80092:case 80467:case 80506:case 80571:case 80604:case 82515:case 82554:case 82619:case 82652:case 83539:case 83578:case 83643:case 83676:case 85587:case 85626:case 85691:case 85724:case 86099:case 86138:case 86203:case 86236:case 86611:case 86650:case 87123:case 87162:case 87227:case 87260:case 88659:case 88698:case 88763:case 88796:case 89171:case 89210:case 89275:case 89308:case 91731:case 91770:case 91835:case 91868:case 94803:case 94842:case 94907:case 94940:case 95827:case 95866:case 95931:case 95964:case 96339:case 96378:case 96443:case 96476:case 99411:case 99450:case 99515:case 99548:case 99923:case 99962:case 100027:case 100060:case 100947:case 100986:case 101051:case 101084:case 101459:case 101498:case 101563:case 101596:case 104019:case 104058:case 104123:case 104156:case 105555:case 105594:case 105659:case 105692:case 106067:case 106106:case 106171:case 106204:case 107603:case 107642:case 107707:case 107740:case 110675:case 110714:case 110779:case 110812:case 111187:case 111226:case 111291:case 111324:case 112723:case 112762:case 112827:case 112860:case 113747:case 113786:case 113851:case 113884:case 114259:case 114298:case 114363:case 114396:case 115283:case 115322:case 115387:case 115420:case 115795:case 115834:case 115899:case 115932:case 117331:case 117370:case 117435:case 117468:case 117843:case 117882:case 117947:case 117980:case 118355:case 118394:case 118459:case 118492:case 118867:case 118906:case 118971:case 119004:case 119891:case 119930:case 119995:case 120028:case 122451:case 122490:case 122555:case 122588:case 122963:case 123002:case 123067:case 123100:case 125523:case 125562:case 125627:case 125660:case 126547:case 126586:case 127059:case 127098:case 127163:case 127196:case 127571:case 127610:case 127675:case 127708:case 130643:case 130682:case 130747:case 130780:case 131155:case 131194:case 131259:case 131292:case 131667:case 131706:case 131771:case 131804:case 132179:case 132218:case 132283:case 132316:case 132691:case 132730:case 132795:case 132828:case 134227:case 134266:case 134331:case 134364:case 134739:case 134778:case 134843:case 134876:case 136275:case 136314:case 136379:case 136412:case 136787:case 136826:case 136891:case 136924:case 137299:case 137338:case 137403:case 137436:case 137811:case 137850:case 137915:case 137948:case 139859:case 139898:case 139963:case 139996:case 143955:case 143969:case 143992:case 143994:case 144059:case 144078:case 144092:case 144121:case 144134:Zr();break;case-3:break;default:Hr()}}function Pr(){nc.startNonterminal("AxisStep",Wl);switch(Xl){case 74:case 75:case 210:case 216:case 217:Fl(233);break;default:Ul=Xl}switch(Ul){case 46:case 26698:case 26699:case 26834:case 26840:case 26841:Ur();break;default:Br()}jl(229),Hl(),ai(),nc.endNonterminal("AxisStep",Wl)}function Hr(){switch(Xl){case 74:case 75:case 210:case 216:case 217:Fl(233);break;default:Ul=Xl}switch(Ul){case 46:case 26698:case 26699:case 26834:case 26840:case 26841:zr();break;default:jr()}jl(229),fi()}function Br(){nc.startNonterminal("ForwardStep",Wl);switch(Xl){case 83:Fl(237);break;case 94:case 112:case 113:case 137:case 138:case 234:Fl(233);break;default:Ul=Xl}switch(Ul){case 26707:case 26718:case 26736:case 26737:case 26761:case 26762:case 26858:Fr(),jl(250),Hl(),Jr();break;default:qr()}nc.endNonterminal("ForwardStep",Wl)}function jr(){switch(Xl){case 83:Fl(237);break;case 94:case 112:case 113:case 137:case 138:case 234:Fl(233);break;default:Ul=Xl}switch(Ul){case 26707:case 26718:case 26736:case 26737:case 26761:case 26762:case 26858:Ir(),jl(250),Kr();break;default:Rr()}}function Fr(){nc.startNonterminal("ForwardAxis",Wl);switch(Xl){case 94:_l(94),jl(27),_l(52);break;case 112:_l(112),jl(27),_l(52);break;case 83:_l(83),jl(27),_l(52);break;case 234:_l(234),jl(27),_l(52);break;case 113:_l(113),jl(27),_l(52);break;case 138:_l(138),jl(27),_l(52);break;default:_l(137),jl(27),_l(52)}nc.endNonterminal("ForwardAxis",Wl)}function Ir(){switch(Xl){case 94:Dl(94),jl(27),Dl(52);break;case 112:Dl(112),jl(27),Dl(52);break;case 83:Dl(83),jl(27),Dl(52);break;case 234:Dl(234),jl(27),Dl(52);break;case 113:Dl(113),jl(27),Dl(52);break;case 138:Dl(138),jl(27),Dl(52);break;default:Dl(137),jl(27),Dl(52)}}function qr(){nc.startNonterminal("AbbrevForwardStep",Wl),Xl==67&&_l(67),jl(250),Hl(),Jr(),nc.endNonterminal("AbbrevForwardStep",Wl)}function Rr(){Xl==67&&Dl(67),jl(250),Kr()}function Ur(){nc.startNonterminal("ReverseStep",Wl);switch(Xl){case 46:Vr();break;default:Wr(),jl(250),Hl(),Jr()}nc.endNonterminal("ReverseStep",Wl)}function zr(){switch(Xl){case 46:$r();break;default:Xr(),jl(250),Kr()}}function Wr(){nc.startNonterminal("ReverseAxis",Wl);switch(Xl){case 210:_l(210),jl(27),_l(52);break;case 74:_l(74),jl(27),_l(52);break;case 217:_l(217),jl(27),_l(52);break;case 216:_l(216),jl(27),_l(52);break;default:_l(75),jl(27),_l(52)}nc.endNonterminal("ReverseAxis",Wl)}function Xr(){switch(Xl){case 210:Dl(210),jl(27),Dl(52);break;case 74:Dl(74),jl(27),Dl(52);break;case 217:Dl(217),jl(27),Dl(52);break;case 216:Dl(216),jl(27),Dl(52);break;default:Dl(75),jl(27),Dl(52)}}function Vr(){nc.startNonterminal("AbbrevReverseStep",Wl),_l(46),nc.endNonterminal("AbbrevReverseStep",Wl)}function $r(){Dl(46)}function Jr(){nc.startNonterminal("NodeTest",Wl);switch(Xl){case 83:case 97:case 121:case 122:case 188:case 194:case 220:case 230:case 231:case 249:Fl(232);break;default:Ul=Xl}switch(Ul){case 18003:case 18017:case 18041:case 18042:case 18108:case 18114:case 18140:case 18150:case 18151:case 18169:Ws();break;default:Qr()}nc.endNonterminal("NodeTest",Wl)}function Kr(){switch(Xl){case 83:case 97:case 121:case 122:case 188:case 194:case 220:case 230:case 231:case 249:Fl(232);break;default:Ul=Xl}switch(Ul){case 18003:case 18017:case 18041:case 18042:case 18108:case 18114:case 18140:case 18150:case 18151:case 18169:Xs();break;default:Gr()}}function Qr(){nc.startNonterminal("NameTest",Wl);switch(Xl){case 5:_l(5);break;default:Xa()}nc.endNonterminal("NameTest",Wl)}function Gr(){switch(Xl){case 5:Dl(5);break;default:Va()}}function Yr(){nc.startNonterminal("PostfixExpr",Wl),ml();for(;;){jl(236);if(Xl!=35&&Xl!=45&&Xl!=69)break;switch(Xl){case 69:Fl(274);break;default:Ul=Xl}if(Ul==35397){Ul=sc(5,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{ci(),Ul=-1}catch(a){Ul=-4}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(5,Wl,Ul)}}switch(Ul){case 35:Hl(),oi();break;case 45:Hl(),ei();break;case-4:Hl(),ni();break;case 35909:Hl(),ii();break;default:Hl(),li()}}nc.endNonterminal("PostfixExpr",Wl)}function Zr(){gl();for(;;){jl(236);if(Xl!=35&&Xl!=45&&Xl!=69)break;switch(Xl){case 69:Fl(274);break;default:Ul=Xl}if(Ul==35397){Ul=sc(5,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{ci(),ic(5,t,-1),Ul=-6}catch(a){Ul=-4,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(5,t,-4)}}}switch(Ul){case 35:ui();break;case 45:ti();break;case-4:ri();break;case 35909:si();break;case-6:break;default:ci()}}}function ei(){nc.startNonterminal("ObjectLookup",Wl),_l(45),jl(252);switch(Xl){case 11:_l(11);break;case 35:Hl(),Ti();break;case 31:Hl(),wi();break;case 32:Hl(),Ci();break;default:Hl(),Ka()}nc.endNonterminal("ObjectLookup",Wl)}function ti(){Dl(45),jl(252);switch(Xl){case 11:Dl(11);break;case 35:Ni();break;case 31:Ei();break;case 32:ki();break;default:Qa()}}function ni(){nc.startNonterminal("ArrayLookup",Wl),_l(69),jl(31),_l(69),jl(268),Hl(),G(),_l(70),jl(32),_l(70),nc.endNonterminal("ArrayLookup",Wl)}function ri(){Dl(69),jl(31),Dl(69),jl(268),Y(),Dl(70),jl(32),Dl(70)}function ii(){nc.startNonterminal("ArrayUnboxing",Wl),_l(69),jl(32),_l(70),nc.endNonterminal("ArrayUnboxing",Wl)}function si(){Dl(69),jl(32),Dl(70)}function oi(){nc.startNonterminal("ArgumentList",Wl),_l(35),jl(281);if(Xl!=38){Hl(),Pi();for(;;){jl(103);if(Xl!=42)break;_l(42),jl(273),Hl(),Pi()}}_l(38),nc.endNonterminal("ArgumentList",Wl)}function ui(){Dl(35),jl(281);if(Xl!=38){Hi();for(;;){jl(103);if(Xl!=42)break;Dl(42),jl(273),Hi()}}Dl(38)}function ai(){nc.startNonterminal("PredicateList",Wl);for(;;){jl(229);if(Xl!=69)break;Hl(),li()}nc.endNonterminal("PredicateList",Wl)}function fi(){for(;;){jl(229);if(Xl!=69)break;ci()}}function li(){nc.startNonterminal("Predicate",Wl),_l(69),jl(268),Hl(),G(),_l(70),nc.endNonterminal("Predicate",Wl)}function ci(){Dl(69),jl(268),Y(),Dl(70)}function hi(){nc.startNonterminal("Literal",Wl);switch(Xl){case 11:_l(11);break;case 135:case 255:di();break;case 197:mi();break;default:yi()}nc.endNonterminal("Literal",Wl)}function pi(){switch(Xl){case 11:Dl(11);break;case 135:case 255:vi();break;case 197:gi();break;default:bi()}}function di(){nc.startNonterminal("BooleanLiteral",Wl);switch(Xl){case 255:_l(255);break;default:_l(135)}nc.endNonterminal("BooleanLiteral",Wl)}function vi(){switch(Xl){case 255:Dl(255);break;default:Dl(135)}}function mi(){nc.startNonterminal("NullLiteral",Wl),_l(197),nc.endNonterminal("NullLiteral",Wl)}function gi(){Dl(197)}function yi(){nc.startNonterminal("NumericLiteral",Wl);switch(Xl){case 8:_l(8);break;case 9:_l(9);break;default:_l(10)}nc.endNonterminal("NumericLiteral",Wl)}function bi(){switch(Xl){case 8:Dl(8);break;case 9:Dl(9);break;default:Dl(10)}}function wi(){nc.startNonterminal("VarRef",Wl),_l(31),jl(247),Hl(),Si(),nc.endNonterminal("VarRef",Wl)}function Ei(){Dl(31),jl(247),xi()}function Si(){nc.startNonterminal("VarName",Wl),Xa(),nc.endNonterminal("VarName",Wl)}function xi(){Va()}function Ti(){nc.startNonterminal("ParenthesizedExpr",Wl),_l(35),jl(271),Xl!=38&&(Hl(),G()),_l(38),nc.endNonterminal("ParenthesizedExpr",Wl)}function Ni(){Dl(35),jl(271),Xl!=38&&Y(),Dl(38)}function Ci(){nc.startNonterminal("ContextItemExpr",Wl),_l(32),nc.endNonterminal("ContextItemExpr",Wl)}function ki(){Dl(32)}function Li(){nc.startNonterminal("OrderedExpr",Wl),_l(206),jl(89),_l(281),jl(268),Hl(),G(),_l(287),nc.endNonterminal("OrderedExpr",Wl)}function Ai(){Dl(206),jl(89),Dl(281),jl(268),Y(),Dl(287)}function Oi(){nc.startNonterminal("UnorderedExpr",Wl),_l(262),jl(89),_l(281),jl(268),Hl(),G(),_l(287),nc.endNonterminal("UnorderedExpr",Wl)}function Mi(){Dl(262),jl(89),Dl(281),jl(268),Y(),Dl(287)}function _i(){nc.startNonterminal("FunctionCall",Wl),$a(),jl(22),Hl(),oi(),nc.endNonterminal("FunctionCall",Wl)}function Di(){Ja(),jl(22),ui()}function Pi(){nc.startNonterminal("Argument",Wl);switch(Xl){case 65:Bi();break;default:Uf()}nc.endNonterminal("Argument",Wl)}function Hi(){switch(Xl){case 65:ji();break;default:zf()}}function Bi(){nc.startNonterminal("ArgumentPlaceholder",Wl),_l(65),nc.endNonterminal("ArgumentPlaceholder",Wl)}function ji(){Dl(65)}function Fi(){nc.startNonterminal("Constructor",Wl);switch(Xl){case 55:case 56:case 60:qi();break;default:is()}nc.endNonterminal("Constructor",Wl)}function Ii(){switch(Xl){case 55:case 56:case 60:Ri();break;default:ss()}}function qi(){nc.startNonterminal("DirectConstructor",Wl);switch(Xl){case 55:Ui();break;case 56:es();break;default:ns()}nc.endNonterminal("DirectConstructor",Wl)}function Ri(){switch(Xl){case 55:zi();break;case 56:ts();break;default:rs()}}function Ui(){nc.startNonterminal("DirElemConstructor",Wl),_l(55),Il(4),_l(20),Wi();switch(Xl){case 49:_l(49);break;default:_l(62);for(;;){Il(196);if(Xl==57)break;Yi()}_l(57),Il(4),_l(20),Il(12),Xl==21&&_l(21),Il(8),_l(62)}nc.endNonterminal("DirElemConstructor",Wl)}function zi(){Dl(55),Il(4),Dl(20),Xi();switch(Xl){case 49:Dl(49);break;default:Dl(62);for(;;){Il(196);if(Xl==57)break;Zi()}Dl(57),Il(4),Dl(20),Il(12),Xl==21&&Dl(21),Il(8),Dl(62)}}function Wi(){nc.startNonterminal("DirAttributeList",Wl);for(;;){Il(19);if(Xl!=21)break;_l(21),Il(93),Xl==20&&(_l(20),Il(11),Xl==21&&_l(21),Il(7),_l(61),Il(18),Xl==21&&_l(21),Vi())}nc.endNonterminal("DirAttributeList",Wl)}function Xi(){for(;;){Il(19);if(Xl!=21)break;Dl(21),Il(93),Xl==20&&(Dl(20),Il(11),Xl==21&&Dl(21),Il(7),Dl(61),Il(18),Xl==21&&Dl(21),$i())}}function Vi(){nc.startNonterminal("DirAttributeValue",Wl),Il(14);switch(Xl){case 28:_l(28);for(;;){Il(186);if(Xl==28)break;switch(Xl){case 13:_l(13);break;default:Ji()}}_l(28);break;default:_l(34);for(;;){Il(187);if(Xl==34)break;switch(Xl){case 14:_l(14);break;default:Qi()}}_l(34)}nc.endNonterminal("DirAttributeValue",Wl)}function $i(){Il(14);switch(Xl){case 28:Dl(28);for(;;){Il(186);if(Xl==28)break;switch(Xl){case 13:Dl(13);break;default:Ki()}}Dl(28);break;default:Dl(34);for(;;){Il(187);if(Xl==34)break;switch(Xl){case 14:Dl(14);break;default:Gi()}}Dl(34)}}function Ji(){nc.startNonterminal("QuotAttrValueContent",Wl);switch(Xl){case 16:_l(16);break;default:nl()}nc.endNonterminal("QuotAttrValueContent",Wl)}function Ki(){switch(Xl){case 16:Dl(16);break;default:rl()}}function Qi(){nc.startNonterminal("AposAttrValueContent",Wl);switch(Xl){case 17:_l(17);break;default:nl()}nc.endNonterminal("AposAttrValueContent",Wl)}function Gi(){switch(Xl){case 17:Dl(17);break;default:rl()}}function Yi(){nc.startNonterminal("DirElemContent",Wl);switch(Xl){case 55:case 56:case 60:qi();break;case 4:_l(4);break;case 15:_l(15);break;default:nl()}nc.endNonterminal("DirElemContent",Wl)}function Zi(){switch(Xl){case 55:case 56:case 60:Ri();break;case 4:Dl(4);break;case 15:Dl(15);break;default:rl()}}function es(){nc.startNonterminal("DirCommentConstructor",Wl),_l(56),Il(1),_l(2),Il(6),_l(44),nc.endNonterminal("DirCommentConstructor",Wl)}function ts(){Dl(56),Il(1),Dl(2),Il(6),Dl(44)}function ns(){nc.startNonterminal("DirPIConstructor",Wl),_l(60),Il(3),_l(18),Il(13),Xl==21&&(_l(21),Il(2),_l(3)),Il(9),_l(66),nc.endNonterminal("DirPIConstructor",Wl)}function rs(){Dl(60),Il(3),Dl(18),Il(13),Xl==21&&(Dl(21),Il(2),Dl(3)),Il(9),Dl(66)}function is(){nc.startNonterminal("ComputedConstructor",Wl);switch(Xl){case 120:ol();break;case 122:os();break;case 83:al();break;case 187:as();break;case 249:dl();break;case 97:hl();break;default:ll()}nc.endNonterminal("ComputedConstructor",Wl)}function ss(){switch(Xl){case 120:ul();break;case 122:us();break;case 83:fl();break;case 187:fs();break;case 249:vl();break;case 97:pl();break;default:cl()}}function os(){nc.startNonterminal("CompElemConstructor",Wl),_l(122),jl(251);switch(Xl){case 281:_l(281),jl(268),Hl(),G(),_l(287);break;default:Hl(),Xa()}jl(89),_l(281),jl(282),Xl!=287&&(Hl(),il()),_l(287),nc.endNonterminal("CompElemConstructor",Wl)}function us(){Dl(122),jl(251);switch(Xl){case 281:Dl(281),jl(268),Y(),Dl(287);break;default:Va()}jl(89),Dl(281),jl(282),Xl!=287&&sl(),Dl(287)}function as(){nc.startNonterminal("CompNamespaceConstructor",Wl),_l(187),jl(243);switch(Xl){case 281:_l(281),jl(268),Hl(),hs(),_l(287);break;default:Hl(),ls()}jl(89),_l(281),jl(268),Hl(),ds(),_l(287),nc.endNonterminal("CompNamespaceConstructor",Wl)}function fs(){Dl(187),jl(243);switch(Xl){case 281:Dl(281),jl(268),ps(),Dl(287);break;default:cs()}jl(89),Dl(281),jl(268),vs(),Dl(287)}function ls(){nc.startNonterminal("Prefix",Wl),Ka(),nc.endNonterminal("Prefix",Wl)}function cs(){Qa()}function hs(){nc.startNonterminal("PrefixExpr",Wl),G(),nc.endNonterminal("PrefixExpr",Wl)}function ps(){Y()}function ds(){nc.startNonterminal("URIExpr",Wl),G(),nc.endNonterminal("URIExpr",Wl)}function vs(){Y()}function ms(){nc.startNonterminal("FunctionItemExpr",Wl);switch(Xl){case 147:Fl(94);break;default:Ul=Xl}switch(Ul){case 33:case 18067:ws();break;default:ys()}nc.endNonterminal("FunctionItemExpr",Wl)}function gs(){switch(Xl){case 147:Fl(94);break;default:Ul=Xl}switch(Ul){case 33:case 18067:Es();break;default:bs()}}function ys(){nc.startNonterminal("NamedFunctionRef",Wl),Xa(),jl(20),_l(29),jl(16),_l(8),nc.endNonterminal("NamedFunctionRef",Wl)}function bs(){Va(),jl(20),Dl(29),jl(16),Dl(8)}function ws(){nc.startNonterminal("InlineFunctionExpr",Wl);for(;;){jl(99);if(Xl!=33)break;Hl(),B()}_l(147),jl(22),_l(35),jl(97),Xl==31&&(Hl(),U()),_l(38),jl(113),Xl==80&&(_l(80),jl(255),Hl(),Cs()),jl(89),Hl(),V(),nc.endNonterminal("InlineFunctionExpr",Wl)}function Es(){for(;;){jl(99);if(Xl!=33)break;j()}Dl(147),jl(22),Dl(35),jl(97),Xl==31&&z(),Dl(38),jl(113),Xl==80&&(Dl(80),jl(255),ks()),jl(89),$()}function Ss(){nc.startNonterminal("SingleType",Wl),No(),jl(227),Xl==65&&_l(65),nc.endNonterminal("SingleType",Wl)}function xs(){Co(),jl(227),Xl==65&&Dl(65)}function Ts(){nc.startNonterminal("TypeDeclaration",Wl),_l(80),jl(255),Hl(),Cs(),nc.endNonterminal("TypeDeclaration",Wl)}function Ns(){Dl(80),jl(255),ks()}function Cs(){nc.startNonterminal("SequenceType",Wl);switch(Xl){case 35:Fl(260);break;case 125:Fl(234);break;default:Ul=Xl}switch(Ul){case 18045:case 19491:Xl==125&&_l(125),jl(22),_l(35),jl(23),_l(38);break;default:Os(),jl(230);switch(Xl){case 40:case 41:case 65:Hl(),Ls();break;default:}}nc.endNonterminal("SequenceType",Wl)}function ks(){switch(Xl){case 35:Fl(260);break;case 125:Fl(234);break;default:Ul=Xl}switch(Ul){case 18045:case 19491:Xl==125&&Dl(125),jl(22),Dl(35),jl(23),Dl(38);break;default:Ms(),jl(230);switch(Xl){case 40:case 41:case 65:As();break;default:}}}function Ls(){nc.startNonterminal("OccurrenceIndicator",Wl);switch(Xl){case 65:_l(65);break;case 40:_l(40);break;default:_l(41)}nc.endNonterminal("OccurrenceIndicator",Wl)}function As(){switch(Xl){case 65:Dl(65);break;case 40:Dl(40);break;default:Dl(41)}}function Os(){nc.startNonterminal("ItemType",Wl);switch(Xl){case 79:case 83:case 97:case 121:case 122:case 147:case 167:case 169:case 188:case 194:case 198:case 220:case 230:case 231:case 247:case 249:Fl(234);break;default:Ul=Xl}if(Ul==12879||Ul==12969||Ul==12998||Ul==13047||Ul==13903||Ul==13993||Ul==14022||Ul==14071||Ul==19535||Ul==19625||Ul==19654||Ul==19703||Ul==20047||Ul==20137||Ul==20166||Ul==20215||Ul==20559||Ul==20649||Ul==20678||Ul==20727||Ul==21071||Ul==21161||Ul==21190||Ul==21239||Ul==21583||Ul==21673||Ul==21702||Ul==21751||Ul==22095||Ul==22185||Ul==22214||Ul==22263||Ul==25679||Ul==25769||Ul==25798||Ul==25847||Ul==27215||Ul==27305||Ul==27334||Ul==27383||Ul==27727||Ul==27817||Ul==27846||Ul==27895||Ul==28239||Ul==28329||Ul==28358||Ul==28407||Ul==29775||Ul==29865||Ul==29894||Ul==29943||Ul==30287||Ul==30377||Ul==30406||Ul==30455||Ul==31311||Ul==31401||Ul==31430||Ul==31479||Ul==31823||Ul==31913||Ul==31942||Ul==31991||Ul==32335||Ul==32425||Ul==32454||Ul==32503||Ul==32847||Ul==32937||Ul==32966||Ul==33015||Ul==33359||Ul==33449||Ul==33478||Ul==33527||Ul==35919||Ul==36009||Ul==36038||Ul==36087||Ul==36431||Ul==36521||Ul==36550||Ul==36599||Ul==37455||Ul==37545||Ul==37574||Ul==37623||Ul==38991||Ul==39081||Ul==39110||Ul==39159||Ul==41039||Ul==41129||Ul==41158||Ul==41207||Ul==41551||Ul==41641||Ul==41670||Ul==41719||Ul==42063||Ul==42153||Ul==42182||Ul==42231||Ul==43599||Ul==43689||Ul==43718||Ul==43767||Ul==45647||Ul==45737||Ul==45766||Ul==45815||Ul==48719||Ul==48809||Ul==48838||Ul==48887||Ul==51279||Ul==51369||Ul==51398||Ul==51447||Ul==54351||Ul==54441||Ul==54470||Ul==54519||Ul==56399||Ul==56489||Ul==56518||Ul==56567||Ul==58447||Ul==58537||Ul==58566||Ul==58615||Ul==61007||Ul==61097||Ul==61126||Ul==61175||Ul==63055||Ul==63145||Ul==63174||Ul==63223||Ul==63567||Ul==63657||Ul==63686||Ul==63735||Ul==65103||Ul==65193||Ul==65222||Ul==65271||Ul==66127||Ul==66217||Ul==66246||Ul==66295||Ul==67663||Ul==67753||Ul==67782||Ul==67831||Ul==68687||Ul==68777||Ul==68806||Ul==68855||Ul==71247||Ul==71337||Ul==71366||Ul==71415||Ul==72783||Ul==72873||Ul==72902||Ul==72951||Ul==75855||Ul==75945||Ul==75974||Ul==76023||Ul==76879||Ul==76969||Ul==76998||Ul==77047||Ul==77903||Ul==77993||Ul==78022||Ul==78071||Ul==78415||Ul==78505||Ul==78534||Ul==78583||Ul==79951||Ul==80041||Ul==80070||Ul==80119||Ul==83023||Ul==83113||Ul==83142||Ul==83191||Ul==84047||Ul==84137||Ul==84166||Ul==84215||Ul==84559||Ul==84649||Ul==84678||Ul==84727||Ul==85071||Ul==85161||Ul==85190||Ul==85239||Ul==89679||Ul==89769||Ul==89798||Ul==89847||Ul==90703||Ul==90793||Ul==90822||Ul==90871||Ul==92751||Ul==92841||Ul==92870||Ul==92919||Ul==93775||Ul==93865||Ul==93894||Ul==93943||Ul==94287||Ul==94377||Ul==94406||Ul==94455||Ul==96847||Ul==96937||Ul==96966||Ul==97015||Ul==103503||Ul==103593||Ul==103622||Ul==103671||Ul==104527||Ul==104617||Ul==104646||Ul==104695||Ul==105039||Ul==105129||Ul==105158||Ul==105207||Ul==107087||Ul==107177||Ul==107206||Ul==107255||Ul==114767||Ul==114857||Ul==114886||Ul==114935||Ul==116815||Ul==116905||Ul==116934||Ul==116983||Ul==118863||Ul==118953||Ul==118982||Ul==119031||Ul==119375||Ul==119465||Ul==119494||Ul==119543||Ul==121423||Ul==121513||Ul==121542||Ul==121591||Ul==123471||Ul==123561||Ul==123590||Ul==123639||Ul==123983||Ul==124073||Ul==124102||Ul==124151||Ul==129103||Ul==129193||Ul==129222||Ul==129271||Ul==129615||Ul==129705||Ul==129734||Ul==129783||Ul==133199||Ul==133289||Ul==133318||Ul==133367||Ul==139343||Ul==139433||Ul==139462||Ul==139511||Ul==141391||Ul==141481||Ul==141510||Ul==141559||Ul==142927||Ul==143017||Ul==143046||Ul==143095||Ul==143951||Ul==144041||Ul==144070||Ul==144119||Ul==145487||Ul==145577||Ul==145606||Ul==145655||Ul==145999||Ul==146089||Ul==146118||Ul==146167||Ul==146511||Ul==146601||Ul==146630||Ul==146679||Ul==147023||Ul==147113||Ul==147142||Ul==147191){Ul=sc(6,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{zs(),Ul=-4}catch(a){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Ds(),Ul=-6}catch(f){Ul=-7}}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(6,Wl,Ul)}}switch(Ul){case 18003:case 18017:case 18041:case 18042:case 18108:case 18114:case 18140:case 18150:case 18151:case 18169:Ws();break;case 18087:_l(167),jl(22),_l(35),jl(23),_l(38);break;case 33:case 18067:Ao();break;case 35:Ho();break;case-6:case 17999:case 18089:case 18118:_s();break;case-7:case 18167:Ps();break;default:Us()}nc.endNonterminal("ItemType",Wl)}function Ms(){switch(Xl){case 79:case 83:case 97:case 121:case 122:case 147:case 167:case 169:case 188:case 194:case 198:case 220:case 230:case 231:case 247:case 249:Fl(234);break;default:Ul=Xl}if(Ul==12879||Ul==12969||Ul==12998||Ul==13047||Ul==13903||Ul==13993||Ul==14022||Ul==14071||Ul==19535||Ul==19625||Ul==19654||Ul==19703||Ul==20047||Ul==20137||Ul==20166||Ul==20215||Ul==20559||Ul==20649||Ul==20678||Ul==20727||Ul==21071||Ul==21161||Ul==21190||Ul==21239||Ul==21583||Ul==21673||Ul==21702||Ul==21751||Ul==22095||Ul==22185||Ul==22214||Ul==22263||Ul==25679||Ul==25769||Ul==25798||Ul==25847||Ul==27215||Ul==27305||Ul==27334||Ul==27383||Ul==27727||Ul==27817||Ul==27846||Ul==27895||Ul==28239||Ul==28329||Ul==28358||Ul==28407||Ul==29775||Ul==29865||Ul==29894||Ul==29943||Ul==30287||Ul==30377||Ul==30406||Ul==30455||Ul==31311||Ul==31401||Ul==31430||Ul==31479||Ul==31823||Ul==31913||Ul==31942||Ul==31991||Ul==32335||Ul==32425||Ul==32454||Ul==32503||Ul==32847||Ul==32937||Ul==32966||Ul==33015||Ul==33359||Ul==33449||Ul==33478||Ul==33527||Ul==35919||Ul==36009||Ul==36038||Ul==36087||Ul==36431||Ul==36521||Ul==36550||Ul==36599||Ul==37455||Ul==37545||Ul==37574||Ul==37623||Ul==38991||Ul==39081||Ul==39110||Ul==39159||Ul==41039||Ul==41129||Ul==41158||Ul==41207||Ul==41551||Ul==41641||Ul==41670||Ul==41719||Ul==42063||Ul==42153||Ul==42182||Ul==42231||Ul==43599||Ul==43689||Ul==43718||Ul==43767||Ul==45647||Ul==45737||Ul==45766||Ul==45815||Ul==48719||Ul==48809||Ul==48838||Ul==48887||Ul==51279||Ul==51369||Ul==51398||Ul==51447||Ul==54351||Ul==54441||Ul==54470||Ul==54519||Ul==56399||Ul==56489||Ul==56518||Ul==56567||Ul==58447||Ul==58537||Ul==58566||Ul==58615||Ul==61007||Ul==61097||Ul==61126||Ul==61175||Ul==63055||Ul==63145||Ul==63174||Ul==63223||Ul==63567||Ul==63657||Ul==63686||Ul==63735||Ul==65103||Ul==65193||Ul==65222||Ul==65271||Ul==66127||Ul==66217||Ul==66246||Ul==66295||Ul==67663||Ul==67753||Ul==67782||Ul==67831||Ul==68687||Ul==68777||Ul==68806||Ul==68855||Ul==71247||Ul==71337||Ul==71366||Ul==71415||Ul==72783||Ul==72873||Ul==72902||Ul==72951||Ul==75855||Ul==75945||Ul==75974||Ul==76023||Ul==76879||Ul==76969||Ul==76998||Ul==77047||Ul==77903||Ul==77993||Ul==78022||Ul==78071||Ul==78415||Ul==78505||Ul==78534||Ul==78583||Ul==79951||Ul==80041||Ul==80070||Ul==80119||Ul==83023||Ul==83113||Ul==83142||Ul==83191||Ul==84047||Ul==84137||Ul==84166||Ul==84215||Ul==84559||Ul==84649||Ul==84678||Ul==84727||Ul==85071||Ul==85161||Ul==85190||Ul==85239||Ul==89679||Ul==89769||Ul==89798||Ul==89847||Ul==90703||Ul==90793||Ul==90822||Ul==90871||Ul==92751||Ul==92841||Ul==92870||Ul==92919||Ul==93775||Ul==93865||Ul==93894||Ul==93943||Ul==94287||Ul==94377||Ul==94406||Ul==94455||Ul==96847||Ul==96937||Ul==96966||Ul==97015||Ul==103503||Ul==103593||Ul==103622||Ul==103671||Ul==104527||Ul==104617||Ul==104646||Ul==104695||Ul==105039||Ul==105129||Ul==105158||Ul==105207||Ul==107087||Ul==107177||Ul==107206||Ul==107255||Ul==114767||Ul==114857||Ul==114886||Ul==114935||Ul==116815||Ul==116905||Ul==116934||Ul==116983||Ul==118863||Ul==118953||Ul==118982||Ul==119031||Ul==119375||Ul==119465||Ul==119494||Ul==119543||Ul==121423||Ul==121513||Ul==121542||Ul==121591||Ul==123471||Ul==123561||Ul==123590||Ul==123639||Ul==123983||Ul==124073||Ul==124102||Ul==124151||Ul==129103||Ul==129193||Ul==129222||Ul==129271||Ul==129615||Ul==129705||Ul==129734||Ul==129783||Ul==133199||Ul==133289||Ul==133318||Ul==133367||Ul==139343||Ul==139433||Ul==139462||Ul==139511||Ul==141391||Ul==141481||Ul==141510||Ul==141559||Ul==142927||Ul==143017||Ul==143046||Ul==143095||Ul==143951||Ul==144041||Ul==144070||Ul==144119||Ul==145487||Ul==145577||Ul==145606||Ul==145655||Ul==145999||Ul==146089||Ul==146118||Ul==146167||Ul==146511||Ul==146601||Ul==146630||Ul==146679||Ul==147023||Ul==147113||Ul==147142||Ul==147191){Ul=sc(6,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{zs(),ic(6,t,-4),Ul=-8}catch(a){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Ds(),ic(6,t,-6),Ul=-8}catch(f){Ul=-7,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(6,t,-7)}}}}switch(Ul){case 18003:case 18017:case 18041:case 18042:case 18108:case 18114:case 18140:case 18150:case 18151:case 18169:Xs();break;case 18087:Dl(167),jl(22),Dl(35),jl(23),Dl(38);break;case 33:case 18067:Oo();break;case 35:Bo();break;case-6:case 17999:case 18089:case 18118:Ds();break;case-7:case 18167:Hs();break;case-8:break;default:zs()}}function _s(){nc.startNonterminal("JSONTest",Wl);switch(Xl){case 169:Bs();break;case 198:Fs();break;default:qs()}nc.endNonterminal("JSONTest",Wl)}function Ds(){switch(Xl){case 169:js();break;case 198:Is();break;default:Rs()}}function Ps(){nc.startNonterminal("StructuredItemTest",Wl),_l(247),jl(234),Xl==35&&(_l(35),jl(23),_l(38)),nc.endNonterminal("StructuredItemTest",Wl)}function Hs(){Dl(247),jl(234),Xl==35&&(Dl(35),jl(23),Dl(38))}function Bs(){nc.startNonterminal("JSONItemTest",Wl),_l(169),jl(234),Xl==35&&(_l(35),jl(23),_l(38)),nc.endNonterminal("JSONItemTest",Wl)}function js(){Dl(169),jl(234),Xl==35&&(Dl(35),jl(23),Dl(38))}function Fs(){nc.startNonterminal("JSONObjectTest",Wl),_l(198),jl(234),Xl==35&&(_l(35),jl(23),_l(38)),nc.endNonterminal("JSONObjectTest",Wl)}function Is(){Dl(198),jl(234),Xl==35&&(Dl(35),jl(23),Dl(38))}function qs(){nc.startNonterminal("JSONArrayTest",Wl),_l(79),jl(234),Xl==35&&(_l(35),jl(23),_l(38)),nc.endNonterminal("JSONArrayTest",Wl)}function Rs(){Dl(79),jl(234),Xl==35&&(Dl(35),jl(23),Dl(38))}function Us(){nc.startNonterminal("AtomicOrUnionType",Wl),Xa(),nc.endNonterminal("AtomicOrUnionType",Wl)}function zs(){Va()}function Ws(){nc.startNonterminal("KindTest",Wl);switch(Xl){case 121:Js();break;case 122:ho();break;case 83:io();break;case 231:go();break;case 230:ao();break;case 220:no();break;case 97:Ys();break;case 249:Qs();break;case 188:eo();break;default:Vs()}nc.endNonterminal("KindTest",Wl)}function Xs(){switch(Xl){case 121:Ks();break;case 122:po();break;case 83:so();break;case 231:yo();break;case 230:fo();break;case 220:ro();break;case 97:Zs();break;case 249:Gs();break;case 188:to();break;default:$s()}}function Vs(){nc.startNonterminal("AnyKindTest",Wl),_l(194),jl(22),_l(35),jl(23),_l(38),nc.endNonterminal("AnyKindTest",Wl)}function $s(){Dl(194),jl(22),Dl(35),jl(23),Dl(38)}function Js(){nc.startNonterminal("DocumentTest",Wl),_l(121),jl(22),_l(35),jl(153);if(Xl!=38)switch(Xl){case 122:Hl(),ho();break;default:Hl(),go()}jl(23),_l(38),nc.endNonterminal("DocumentTest",Wl)}function Ks(){Dl(121),jl(22),Dl(35),jl(153);if(Xl!=38)switch(Xl){case 122:po();break;default:yo()}jl(23),Dl(38)}function Qs(){nc.startNonterminal("TextTest",Wl),_l(249),jl(22),_l(35),jl(23),_l(38),nc.endNonterminal("TextTest",Wl)}function Gs(){Dl(249),jl(22),Dl(35),jl(23),Dl(38)}function Ys(){nc.startNonterminal("CommentTest",Wl),_l(97),jl(22),_l(35),jl(23),_l(38),nc.endNonterminal("CommentTest",Wl)}function Zs(){Dl(97),jl(22),Dl(35),jl(23),Dl(38)}function eo(){nc.startNonterminal("NamespaceNodeTest",Wl),_l(188),jl(22),_l(35),jl(23),_l(38),nc.endNonterminal("NamespaceNodeTest",Wl)}function to(){Dl(188),jl(22),Dl(35),jl(23),Dl(38)}function no(){nc.startNonterminal("PITest",Wl),_l(220),jl(22),_l(35),jl(245);if(Xl!=38)switch(Xl){case 11:_l(11);break;default:Hl(),Ka()}jl(23),_l(38),nc.endNonterminal("PITest",Wl)}function ro(){Dl(220),jl(22),Dl(35),jl(245);if(Xl!=38)switch(Xl){case 11:Dl(11);break;default:Qa()}jl(23),Dl(38)}function io(){nc.startNonterminal("AttributeTest",Wl),_l(83),jl(22),_l(35),jl(256),Xl!=38&&(Hl(),oo(),jl(103),Xl==42&&(_l(42),jl(247),Hl(),ko())),jl(23),_l(38),nc.endNonterminal("AttributeTest",Wl)}function so(){Dl(83),jl(22),Dl(35),jl(256),Xl!=38&&(uo(),jl(103),Xl==42&&(Dl(42),jl(247),Lo())),jl(23),Dl(38)}function oo(){nc.startNonterminal("AttribNameOrWildcard",Wl);switch(Xl){case 39:_l(39);break;default:Eo()}nc.endNonterminal("AttribNameOrWildcard",Wl)}function uo(){switch(Xl){case 39:Dl(39);break;default:So()}}function ao(){nc.startNonterminal("SchemaAttributeTest",Wl),_l(230),jl(22),_l(35),jl(247),Hl(),lo(),jl(23),_l(38),nc.endNonterminal("SchemaAttributeTest",Wl)}function fo(){Dl(230),jl(22),Dl(35),jl(247),co(),jl(23),Dl(38)}function lo(){nc.startNonterminal("AttributeDeclaration",Wl),Eo(),nc.endNonterminal("AttributeDeclaration",Wl)}function co(){So()}function ho(){nc.startNonterminal("ElementTest",Wl),_l(122),jl(22),_l(35),jl(256),Xl!=38&&(Hl(),vo(),jl(103),Xl==42&&(_l(42),jl(247),Hl(),ko(),jl(104),Xl==65&&_l(65))),jl(23),_l(38),nc.endNonterminal("ElementTest",Wl)}function po(){Dl(122),jl(22),Dl(35),jl(256),Xl!=38&&(mo(),jl(103),Xl==42&&(Dl(42),jl(247),Lo(),jl(104),Xl==65&&Dl(65))),jl(23),Dl(38)}function vo(){nc.startNonterminal("ElementNameOrWildcard",Wl);switch(Xl){case 39:_l(39);break;default:xo()}nc.endNonterminal("ElementNameOrWildcard",Wl)}function mo(){switch(Xl){case 39:Dl(39);break;default:To()}}function go(){nc.startNonterminal("SchemaElementTest",Wl),_l(231),jl(22),_l(35),jl(247),Hl(),bo(),jl(23),_l(38),nc.endNonterminal("SchemaElementTest",Wl)}function yo(){Dl(231),jl(22),Dl(35),jl(247),wo(),jl(23),Dl(38)}function bo(){nc.startNonterminal("ElementDeclaration",Wl),xo(),nc.endNonterminal("ElementDeclaration",Wl)}function wo(){To()}function Eo(){nc.startNonterminal("AttributeName",Wl),Xa(),nc.endNonterminal("AttributeName",Wl)}function So(){Va()}function xo(){nc.startNonterminal("ElementName",Wl),Xa(),nc.endNonterminal("ElementName",Wl)}function To(){Va()}function No(){nc.startNonterminal("SimpleTypeName",Wl),ko(),nc.endNonterminal("SimpleTypeName",Wl)}function Co(){Lo()}function ko(){nc.startNonterminal("TypeName",Wl),Xa(),nc.endNonterminal("TypeName",Wl)}function Lo(){Va()}function Ao(){nc.startNonterminal("FunctionTest",Wl);for(;;){jl(99);if(Xl!=33)break;Hl(),B()}switch(Xl){case 147:Fl(22);break;default:Ul=Xl}Ul=sc(7,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{_o(),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(7,Wl,Ul)}switch(Ul){case-1:Hl(),Mo();break;default:Hl(),Do()}nc.endNonterminal("FunctionTest",Wl)}function Oo(){for(;;){jl(99);if(Xl!=33)break;j()}switch(Xl){case 147:Fl(22);break;default:Ul=Xl}Ul=sc(7,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{_o(),ic(7,t,-1),Ul=-3}catch(a){Ul=-2,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(7,t,-2)}}switch(Ul){case-1:_o();break;case-3:break;default:Po()}}function Mo(){nc.startNonterminal("AnyFunctionTest",Wl),_l(147),jl(22),_l(35),jl(24),_l(39),jl(23),_l(38),nc.endNonterminal("AnyFunctionTest",Wl)}function _o(){Dl(147),jl(22),Dl(35),jl(24),Dl(39),jl(23),Dl(38)}function Do(){nc.startNonterminal("TypedFunctionTest",Wl),_l(147),jl(22),_l(35),jl(260);if(Xl!=38){Hl(),Cs();for(;;){jl(103);if(Xl!=42)break;_l(42),jl(255),Hl(),Cs()}}_l(38),jl(33),_l(80),jl(255),Hl(),Cs(),nc.endNonterminal("TypedFunctionTest",Wl)}function Po(){Dl(147),jl(22),Dl(35),jl(260);if(Xl!=38){ks();for(;;){jl(103);if(Xl!=42)break;Dl(42),jl(255),ks()}}Dl(38),jl(33),Dl(80),jl(255),ks()}function Ho(){nc.startNonterminal("ParenthesizedItemType",Wl),_l(35),jl(255),Hl(),Os(),jl(23),_l(38),nc.endNonterminal("ParenthesizedItemType",Wl)}function Bo(){Dl(35),jl(255),Ms(),jl(23),Dl(38)}function jo(){nc.startNonterminal("RevalidationDecl",Wl),_l(109),jl(74),_l(226),jl(161);switch(Xl){case 245:_l(245);break;case 174:_l(174);break;default:_l(238)}nc.endNonterminal("RevalidationDecl",Wl)}function Fo(){nc.startNonterminal("InsertExprTargetChoice",Wl);switch(Xl){case 71:_l(71);break;case 85:_l(85);break;default:if(Xl==80){_l(80),jl(121);switch(Xl){case 136:_l(136);break;default:_l(173)}}jl(57),_l(165)}nc.endNonterminal("InsertExprTargetChoice",Wl)}function Io(){switch(Xl){case 71:Dl(71);break;case 85:Dl(85);break;default:if(Xl==80){Dl(80),jl(121);switch(Xl){case 136:Dl(136);break;default:Dl(173)}}jl(57),Dl(165)}}function qo(){nc.startNonterminal("InsertExpr",Wl),_l(161),jl(131);switch(Xl){case 194:_l(194);break;default:_l(195)}jl(268),Hl(),Jo(),Hl(),Fo(),jl(268),Hl(),Qo(),nc.endNonterminal("InsertExpr",Wl)}function Ro(){Dl(161),jl(131);switch(Xl){case 194:Dl(194);break;default:Dl(195)}jl(268),Ko(),Io(),jl(268),Go()}function Uo(){nc.startNonterminal("DeleteExpr",Wl),_l(111),jl(131);switch(Xl){case 194:_l(194);break;default:_l(195)}jl(268),Hl(),Qo(),nc.endNonterminal("DeleteExpr",Wl)}function zo(){Dl(111),jl(131);switch(Xl){case 194:Dl(194);break;default:Dl(195)}jl(268),Go()}function Wo(){nc.startNonterminal("ReplaceExpr",Wl),_l(223),jl(132),Xl==267&&(_l(267),jl(67),_l(200)),jl(65),_l(194),jl(268),Hl(),Qo(),_l(276),jl(268),Hl(),Uf(),nc.endNonterminal("ReplaceExpr",Wl)}function Xo(){Dl(223),jl(132),Xl==267&&(Dl(267),jl(67),Dl(200)),jl(65),Dl(194),jl(268),Go(),Dl(276),jl(268),zf()}function Vo(){nc.startNonterminal("RenameExpr",Wl),_l(222),jl(65),_l(194),jl(268),Hl(),Qo(),_l(80),jl(268),Hl(),Yo(),nc.endNonterminal("RenameExpr",Wl)}function $o(){Dl(222),jl(65),Dl(194),jl(268),Go(),Dl(80),jl(268),Zo()}function Jo(){nc.startNonterminal("SourceExpr",Wl),Uf(),nc.endNonterminal("SourceExpr",Wl)}function Ko(){zf()}function Qo(){nc.startNonterminal("TargetExpr",Wl),Uf(),nc.endNonterminal("TargetExpr",Wl)}function Go(){zf()}function Yo(){nc.startNonterminal("NewNameExpr",Wl),Uf(),nc.endNonterminal("NewNameExpr",Wl)}function Zo(){zf()}function eu(){nc.startNonterminal("TransformExpr",Wl),_l(104),jl(21),Hl(),nu();for(;;){if(Xl!=42)break;_l(42),jl(21),Hl(),nu()}_l(184),jl(268),Hl(),Uf(),_l(224),jl(268),Hl(),Uf(),nc.endNonterminal("TransformExpr",Wl)}function tu(){Dl(104),jl(21),ru();for(;;){if(Xl!=42)break;Dl(42),jl(21),ru()}Dl(184),jl(268),zf(),Dl(224),jl(268),zf()}function nu(){nc.startNonterminal("TransformSpec",Wl),_l(31),jl(247),Hl(),Si(),jl(28),_l(53),jl(268),Hl(),Uf(),nc.endNonterminal("TransformSpec",Wl)}function ru(){Dl(31),jl(247),xi(),jl(28),Dl(53),jl(268),zf()}function iu(){nc.startNonterminal("FTSelection",Wl),au();for(;;){jl(213);switch(Xl){case 82:Fl(160);break;default:Ul=Xl}if(Ul!=116&&Ul!=118&&Ul!=128&&Ul!=206&&Ul!=227&&Ul!=275&&Ul!=65106&&Ul!=123986)break;Hl(),_u()}nc.endNonterminal("FTSelection",Wl)}function su(){fu();for(;;){jl(213);switch(Xl){case 82:Fl(160);break;default:Ul=Xl}if(Ul!=116&&Ul!=118&&Ul!=128&&Ul!=206&&Ul!=227&&Ul!=275&&Ul!=65106&&Ul!=123986)break;Du()}}function ou(){nc.startNonterminal("FTWeight",Wl),_l(270),jl(89),_l(281),jl(268),Hl(),G(),_l(287),nc.endNonterminal("FTWeight",Wl)}function uu(){Dl(270),jl(89),Dl(281),jl(268),Y(),Dl(287)}function au(){nc.startNonterminal("FTOr",Wl),lu();for(;;){if(Xl!=146)break;_l(146),jl(178),Hl(),lu()}nc.endNonterminal("FTOr",Wl)}function fu(){cu();for(;;){if(Xl!=146)break;Dl(146),jl(178),cu()}}function lu(){nc.startNonterminal("FTAnd",Wl),hu();for(;;){if(Xl!=144)break;_l(144),jl(178),Hl(),hu()}nc.endNonterminal("FTAnd",Wl)}function cu(){pu();for(;;){if(Xl!=144)break;Dl(144),jl(178),pu()}}function hu(){nc.startNonterminal("FTMildNot",Wl),du();for(;;){jl(214);if(Xl!=196)break;_l(196),jl(56),_l(156),jl(178),Hl(),du()}nc.endNonterminal("FTMildNot",Wl)}function pu(){vu();for(;;){jl(214);if(Xl!=196)break;Dl(196),jl(56),Dl(156),jl(178),vu()}}function du(){nc.startNonterminal("FTUnaryNot",Wl),Xl==145&&_l(145),jl(165),Hl(),mu(),nc.endNonterminal("FTUnaryNot",Wl)}function vu(){Xl==145&&Dl(145),jl(165),gu()}function mu(){nc.startNonterminal("FTPrimaryWithOptions",Wl),yu(),jl(215),Xl==265&&(Hl(),Ju()),Xl==270&&(Hl(),ou()),nc.endNonterminal("FTPrimaryWithOptions",Wl)}function gu(){bu(),jl(215),Xl==265&&Ku(),Xl==270&&uu()}function yu(){nc.startNonterminal("FTPrimary",Wl);switch(Xl){case 35:_l(35),jl(178),Hl(),iu(),_l(38);break;case 36:Tu();break;default:wu(),jl(217),Xl==199&&(Hl(),Lu())}nc.endNonterminal("FTPrimary",Wl)}function bu(){switch(Xl){case 35:Dl(35),jl(178),su(),Dl(38);break;case 36:Nu();break;default:Eu(),jl(217),Xl==199&&Au()}}function wu(){nc.startNonterminal("FTWords",Wl),Su(),jl(222);if(Xl==72||Xl==77||Xl==214)Hl(),Cu();nc.endNonterminal("FTWords",Wl)}function Eu(){xu(),jl(222),(Xl==72||Xl==77||Xl==214)&&ku()}function Su(){nc.startNonterminal("FTWordsValue",Wl);switch(Xl){case 11:_l(11);break;default:_l(281),jl(268),Hl(),G(),_l(287)}nc.endNonterminal("FTWordsValue",Wl)}function xu(){switch(Xl){case 11:Dl(11);break;default:Dl(281),jl(268),Y(),Dl(287)}}function Tu(){nc.startNonterminal("FTExtensionSelection",Wl);for(;;){Hl(),Cr(),jl(102);if(Xl!=36)break}_l(281),jl(185),Xl!=287&&(Hl(),iu()),_l(287),nc.endNonterminal("FTExtensionSelection",Wl)}function Nu(){for(;;){kr(),jl(102);if(Xl!=36)break}Dl(281),jl(185),Xl!=287&&su(),Dl(287)}function Cu(){nc.startNonterminal("FTAnyallOption",Wl);switch(Xl){case 77:_l(77),jl(220),Xl==278&&_l(278);break;case 72:_l(72),jl(221),Xl==279&&_l(279);break;default:_l(214)}nc.endNonterminal("FTAnyallOption",Wl)}function ku(){switch(Xl){case 77:Dl(77),jl(220),Xl==278&&Dl(278);break;case 72:Dl(72),jl(221),Xl==279&&Dl(279);break;default:Dl(214)}}function Lu(){nc.startNonterminal("FTTimes",Wl),_l(199),jl(158),Hl(),Ou(),_l(252),nc.endNonterminal("FTTimes",Wl)}function Au(){Dl(199),jl(158),Mu(),Dl(252)}function Ou(){nc.startNonterminal("FTRange",Wl);switch(Xl){case 131:_l(131),jl(267),Hl(),Vn();break;case 82:_l(82),jl(127);switch(Xl){case 176:_l(176),jl(267),Hl(),Vn();break;default:_l(186),jl(267),Hl(),Vn()}break;default:_l(142),jl(267),Hl(),Vn(),_l(253),jl(267),Hl(),Vn()}nc.endNonterminal("FTRange",Wl)}function Mu(){switch(Xl){case 131:Dl(131),jl(267),$n();break;case 82:Dl(82),jl(127);switch(Xl){case 176:Dl(176),jl(267),$n();break;default:Dl(186),jl(267),$n()}break;default:Dl(142),jl(267),$n(),Dl(253),jl(267),$n()}}function _u(){nc.startNonterminal("FTPosFilter",Wl);switch(Xl){case 206:Pu();break;case 275:Bu();break;case 118:Fu();break;case 116:case 227:Uu();break;default:Vu()}nc.endNonterminal("FTPosFilter",Wl)}function Du(){switch(Xl){case 206:Hu();break;case 275:ju();break;case 118:Iu();break;case 116:case 227:zu();break;default:$u()}}function Pu(){nc.startNonterminal("FTOrder",Wl),_l(206),nc.endNonterminal("FTOrder",Wl)}function Hu(){Dl(206)}function Bu(){nc.startNonterminal("FTWindow",Wl),_l(275),jl(267),Hl(),Vn(),Hl(),qu(),nc.endNonterminal("FTWindow",Wl)}function ju(){Dl(275),jl(267),$n(),Ru()}function Fu(){nc.startNonterminal("FTDistance",Wl),_l(118),jl(158),Hl(),Ou(),Hl(),qu(),nc.endNonterminal("FTDistance",Wl)}function Iu(){Dl(118),jl(158),Mu(),Ru()}function qu(){nc.startNonterminal("FTUnit",Wl);switch(Xl){case 279:_l(279);break;case 237:_l(237);break;default:_l(209)}nc.endNonterminal("FTUnit",Wl)}function Ru(){switch(Xl){case 279:Dl(279);break;case 237:Dl(237);break;default:Dl(209)}}function Uu(){nc.startNonterminal("FTScope",Wl);switch(Xl){case 227:_l(227);break;default:_l(116)}jl(134),Hl(),Wu(),nc.endNonterminal("FTScope",Wl)}function zu(){switch(Xl){case 227:Dl(227);break;default:Dl(116)}jl(134),Xu()}function Wu(){nc.startNonterminal("FTBigUnit",Wl);switch(Xl){case 236:_l(236);break;default:_l(208)}nc.endNonterminal("FTBigUnit",Wl)}function Xu(){switch(Xl){case 236:Dl(236);break;default:Dl(208)}}function Vu(){nc.startNonterminal("FTContent",Wl);switch(Xl){case 82:_l(82),jl(119);switch(Xl){case 242:_l(242);break;default:_l(127)}break;default:_l(128),jl(45),_l(101)}nc.endNonterminal("FTContent",Wl)}function $u(){switch(Xl){case 82:Dl(82),jl(119);switch(Xl){case 242:Dl(242);break;default:Dl(127)}break;default:Dl(128),jl(45),Dl(101)}}function Ju(){nc.startNonterminal("FTMatchOptions",Wl);for(;;){_l(265),jl(204),Hl(),Qu(),jl(215);if(Xl!=265)break}nc.endNonterminal("FTMatchOptions",Wl)}function Ku(){for(;;){Dl(265),jl(204),Gu(),jl(215);if(Xl!=265)break}}function Qu(){nc.startNonterminal("FTMatchOption",Wl);switch(Xl){case 191:Fl(177);break;default:Ul=Xl}switch(Ul){case 172:ma();break;case 274:case 140479:ya();break;case 251:case 128703:ia();break;case 243:case 124607:na();break;case 115:ea();break;case 244:case 125119:la();break;case 203:wa();break;default:Yu()}nc.endNonterminal("FTMatchOption",Wl)}function Gu(){switch(Xl){case 191:Fl(177);break;default:Ul=Xl}switch(Ul){case 172:ga();break;case 274:case 140479:ba();break;case 251:case 128703:sa();break;case 243:case 124607:ra();break;case 115:ta();break;case 244:case 125119:ca();break;case 203:Ea();break;default:Zu()}}function Yu(){nc.startNonterminal("FTCaseOption",Wl);switch(Xl){case 89:_l(89),jl(126);switch(Xl){case 160:_l(160);break;default:_l(235)}break;case 180:_l(180);break;default:_l(264)}nc.endNonterminal("FTCaseOption",Wl)}function Zu(){switch(Xl){case 89:Dl(89),jl(126);switch(Xl){case 160:Dl(160);break;default:Dl(235)}break;case 180:Dl(180);break;default:Dl(264)}}function ea(){nc.startNonterminal("FTDiacriticsOption",Wl),_l(115),jl(126);switch(Xl){case 160:_l(160);break;default:_l(235)}nc.endNonterminal("FTDiacriticsOption",Wl)}function ta(){Dl(115),jl(126);switch(Xl){case 160:Dl(160);break;default:Dl(235)}}function na(){nc.startNonterminal("FTStemOption",Wl);switch(Xl){case 243:_l(243);break;default:_l(191),jl(76),_l(243)}nc.endNonterminal("FTStemOption",Wl)}function ra(){switch(Xl){case 243:Dl(243);break;default:Dl(191),jl(76),Dl(243)}}function ia(){nc.startNonterminal("FTThesaurusOption",Wl);switch(Xl){case 251:_l(251),jl(151);switch(Xl){case 82:Hl(),oa();break;case 110:_l(110);break;default:_l(35),jl(114);switch(Xl){case 82:Hl(),oa();break;default:_l(110)}for(;;){jl(103);if(Xl!=42)break;_l(42),jl(34),Hl(),oa()}_l(38)}break;default:_l(191),jl(80),_l(251)}nc.endNonterminal("FTThesaurusOption",Wl)}function sa(){switch(Xl){case 251:Dl(251),jl(151);switch(Xl){case 82:ua();break;case 110:Dl(110);break;default:Dl(35),jl(114);switch(Xl){case 82:ua();break;default:Dl(110)}for(;;){jl(103);if(Xl!=42)break;Dl(42),jl(34),ua()}Dl(38)}break;default:Dl(191),jl(80),Dl(251)}}function oa(){nc.startNonterminal("FTThesaurusID",Wl),_l(82),jl(15),_l(7),jl(218),Xl==221&&(_l(221),jl(17),_l(11)),jl(216);switch(Xl){case 82:Fl(184);break;case 142:Fl(164);break;default:Ul=Xl}if(Ul==131||Ul==4238||Ul==90194||Ul==95314)Hl(),aa(),jl(61),_l(178);nc.endNonterminal("FTThesaurusID",Wl)}function ua(){Dl(82),jl(15),Dl(7),jl(218),Xl==221&&(Dl(221),jl(17),Dl(11)),jl(216);switch(Xl){case 82:Fl(184);break;case 142:Fl(164);break;default:Ul=Xl}if(Ul==131||Ul==4238||Ul==90194||Ul==95314)fa(),jl(61),Dl(178)}function aa(){nc.startNonterminal("FTLiteralRange",Wl);switch(Xl){case 131:_l(131),jl(16),_l(8);break;case 82:_l(82),jl(127);switch(Xl){case 176:_l(176),jl(16),_l(8);break;default:_l(186),jl(16),_l(8)}break;default:_l(142),jl(16),_l(8),jl(81),_l(253),jl(16),_l(8)}nc.endNonterminal("FTLiteralRange",Wl)}function fa(){switch(Xl){case 131:Dl(131),jl(16),Dl(8);break;case 82:Dl(82),jl(127);switch(Xl){case 176:Dl(176),jl(16),Dl(8);break;default:Dl(186),jl(16),Dl(8)}break;default:Dl(142),jl(16),Dl(8),jl(81),Dl(253),jl(16),Dl(8)}}function la(){nc.startNonterminal("FTStopWordOption",Wl);switch(Xl){case 244:_l(244),jl(88),_l(279),jl(151);switch(Xl){case 110:_l(110);for(;;){jl(219);if(Xl!=132&&Xl!=260)break;Hl(),da()}break;default:Hl(),ha();for(;;){jl(219);if(Xl!=132&&Xl!=260)break;Hl(),da()}}break;default:_l(191),jl(77),_l(244),jl(88),_l(279)}nc.endNonterminal("FTStopWordOption",Wl)}function ca(){switch(Xl){case 244:Dl(244),jl(88),Dl(279),jl(151);switch(Xl){case 110:Dl(110);for(;;){jl(219);if(Xl!=132&&Xl!=260)break;va()}break;default:pa();for(;;){jl(219);if(Xl!=132&&Xl!=260)break;va()}}break;default:Dl(191),jl(77),Dl(244),jl(88),Dl(279)}}function ha(){nc.startNonterminal("FTStopWords",Wl);switch(Xl){case 82:_l(82),jl(15),_l(7);break;default:_l(35),jl(17),_l(11);for(;;){jl(103);if(Xl!=42)break;_l(42),jl(17),_l(11)}_l(38)}nc.endNonterminal("FTStopWords",Wl)}function pa(){switch(Xl){case 82:Dl(82),jl(15),Dl(7);break;default:Dl(35),jl(17),Dl(11);for(;;){jl(103);if(Xl!=42)break;Dl(42),jl(17),Dl(11)}Dl(38)}}function da(){nc.startNonterminal("FTStopWordsInclExcl",Wl);switch(Xl){case 260:_l(260);break;default:_l(132)}jl(101),Hl(),ha(),nc.endNonterminal("FTStopWordsInclExcl",Wl)}function va(){switch(Xl){case 260:Dl(260);break;default:Dl(132)}jl(101),pa()}function ma(){nc.startNonterminal("FTLanguageOption",Wl),_l(172),jl(17),_l(11),nc.endNonterminal("FTLanguageOption",Wl)}function ga(){Dl(172),jl(17),Dl(11)}function ya(){nc.startNonterminal("FTWildCardOption",Wl);switch(Xl){case 274:_l(274);break;default:_l(191),jl(86),_l(274)}nc.endNonterminal("FTWildCardOption",Wl)}function ba(){switch(Xl){case 274:Dl(274);break;default:Dl(191),jl(86),Dl(274)}}function wa(){nc.startNonterminal("FTExtensionOption",Wl),_l(203),jl(247),Hl(),Xa(),jl(17),_l(11),nc.endNonterminal("FTExtensionOption",Wl)}function Ea(){Dl(203),jl(247),Va(),jl(17),Dl(11)}function Sa(){nc.startNonterminal("FTIgnoreOption",Wl),_l(277),jl(45),_l(101),jl(267),Hl(),Qn(),nc.endNonterminal("FTIgnoreOption",Wl)}function xa(){Dl(277),jl(45),Dl(101),jl(267),Gn()}function Ta(){nc.startNonterminal("CollectionDecl",Wl),_l(96),jl(247),Hl(),Xa(),jl(109),Xl==80&&(Hl(),Na()),nc.endNonterminal("CollectionDecl",Wl)}function Na(){nc.startNonterminal("CollectionTypeDecl",Wl),_l(80),jl(198),Hl(),Ws(),jl(172),Xl!=54&&(Hl(),Ls()),nc.endNonterminal("CollectionTypeDecl",Wl)}function Ca(){nc.startNonterminal("IndexName",Wl),Xa(),nc.endNonterminal("IndexName",Wl)}function ka(){nc.startNonterminal("IndexDomainExpr",Wl),Lr(),nc.endNonterminal("IndexDomainExpr",Wl)}function La(){nc.startNonterminal("IndexKeySpec",Wl),Aa(),Xl==80&&(Hl(),Oa()),jl(155),Xl==95&&(Hl(),_a()),nc.endNonterminal("IndexKeySpec",Wl)}function Aa(){nc.startNonterminal("IndexKeyExpr",Wl),Lr(),nc.endNonterminal("IndexKeyExpr",Wl)}function Oa(){nc.startNonterminal("IndexKeyTypeDecl",Wl),_l(80),jl(247),Hl(),Ma(),jl(190);if(Xl==40||Xl==41||Xl==65)Hl(),Ls();nc.endNonterminal("IndexKeyTypeDecl",Wl)}function Ma(){nc.startNonterminal("AtomicType",Wl),Xa(),nc.endNonterminal("AtomicType",Wl)}function _a(){nc.startNonterminal("IndexKeyCollation",Wl),_l(95),jl(15),_l(7),nc.endNonterminal("IndexKeyCollation",Wl)}function Da(){nc.startNonterminal("IndexDecl",Wl),_l(157),jl(247),Hl(),Ca(),jl(68),_l(201),jl(66),_l(195),jl(264),Hl(),ka(),_l(88),jl(264),Hl(),La();for(;;){jl(105);if(Xl!=42)break;_l(42),jl(264),Hl(),La()}nc.endNonterminal("IndexDecl",Wl)}function Pa(){nc.startNonterminal("ICDecl",Wl),_l(163),jl(43),_l(98),jl(247),Hl(),Xa(),jl(122);switch(Xl){case 201:Hl(),Ha();break;default:Hl(),Ia()}nc.endNonterminal("ICDecl",Wl)}function Ha(){nc.startNonterminal("ICCollection",Wl),_l(201),jl(42),_l(96),jl(247),Hl(),Xa(),jl(148);switch(Xl){case 31:Hl(),Ba();break;case 194:Hl(),ja();break;default:Hl(),Fa()}nc.endNonterminal("ICCollection",Wl)}function Ba(){nc.startNonterminal("ICCollSequence",Wl),wi(),jl(40),_l(93),jl(268),Hl(),Uf(),nc.endNonterminal("ICCollSequence",Wl)}function ja(){nc.startNonterminal("ICCollSequenceUnique",Wl),_l(194),jl(21),Hl(),wi(),jl(40),_l(93),jl(82),_l(261),jl(60),_l(171),jl(264),Hl(),Lr(),nc.endNonterminal("ICCollSequenceUnique",Wl)}function Fa(){nc.startNonterminal("ICCollNode",Wl),_l(140),jl(65),_l(194),jl(21),Hl(),wi(),jl(40),_l(93),jl(268),Hl(),Uf(),nc.endNonterminal("ICCollNode",Wl)}function Ia(){nc.startNonterminal("ICForeignKey",Wl),_l(141),jl(60),_l(171),jl(54),Hl(),qa(),Hl(),Ra(),nc.endNonterminal("ICForeignKey",Wl)}function qa(){nc.startNonterminal("ICForeignKeySource",Wl),_l(142),jl(42),Hl(),Ua(),nc.endNonterminal("ICForeignKeySource",Wl)}function Ra(){nc.startNonterminal("ICForeignKeyTarget",Wl),_l(253),jl(42),Hl(),Ua(),nc.endNonterminal("ICForeignKeyTarget",Wl)}function Ua(){nc.startNonterminal("ICForeignKeyValues",Wl),_l(96),jl(247),Hl(),Xa(),jl(65),_l(194),jl(21),Hl(),wi(),jl(60),_l(171),jl(264),Hl(),Lr(),nc.endNonterminal("ICForeignKeyValues",Wl)}function za(){Dl(37);for(;;){Il(91);if(Xl==51)break;switch(Xl){case 24:Dl(24);break;default:za()}}Dl(51)}function Wa(){switch(Xl){case 22:Dl(22);break;default:za()}}function Xa(){nc.startNonterminal("EQName",Wl),Il(242);switch(Xl){case 83:_l(83);break;case 97:_l(97);break;case 121:_l(121);break;case 122:_l(122);break;case 125:_l(125);break;case 147:_l(147);break;case 154:_l(154);break;case 167:_l(167);break;case 188:_l(188);break;case 194:_l(194);break;case 220:_l(220);break;case 230:_l(230);break;case 231:_l(231);break;case 248:_l(248);break;case 249:_l(249);break;case 259:_l(259);break;case 79:_l(79);break;case 169:_l(169);break;case 247:_l(247);break;default:$a()}nc.endNonterminal("EQName",Wl)}function Va(){Il(242);switch(Xl){case 83:Dl(83);break;case 97:Dl(97);break;case 121:Dl(121);break;case 122:Dl(122);break;case 125:Dl(125);break;case 147:Dl(147);break;case 154:Dl(154);break;case 167:Dl(167);break;case 188:Dl(188);break;case 194:Dl(194);break;case 220:Dl(220);break;case 230:Dl(230);break;case 231:Dl(231);break;case 248:Dl(248);break;case 249:Dl(249);break;case 259:Dl(259);break;case 79:Dl(79);break;case 169:Dl(169);break;case 247:Dl(247);break;default:Ja()}}function $a(){nc.startNonterminal("FunctionName",Wl);switch(Xl){case 6:_l(6);break;case 71:_l(71);break;case 74:_l(74);break;case 75:_l(75);break;case 76:_l(76);break;case 80:_l(80);break;case 81:_l(81);break;case 85:_l(85);break;case 89:_l(89);break;case 90:_l(90);break;case 91:_l(91);break;case 94:_l(94);break;case 95:_l(95);break;case 104:_l(104);break;case 106:_l(106);break;case 109:_l(109);break;case 110:_l(110);break;case 111:_l(111);break;case 112:_l(112);break;case 113:_l(113);break;case 114:_l(114);break;case 119:_l(119);break;case 120:_l(120);break;case 123:_l(123);break;case 124:_l(124);break;case 127:_l(127);break;case 129:_l(129);break;case 130:_l(130);break;case 132:_l(132);break;case 136:_l(136);break;case 137:_l(137);break;case 138:_l(138);break;case 139:_l(139);break;case 148:_l(148);break;case 150:_l(150);break;case 152:_l(152);break;case 153:_l(153);break;case 155:_l(155);break;case 161:_l(161);break;case 162:_l(162);break;case 164:_l(164);break;case 165:_l(165);break;case 166:_l(166);break;case 173:_l(173);break;case 175:_l(175);break;case 177:_l(177);break;case 181:_l(181);break;case 183:_l(183);break;case 184:_l(184);break;case 185:_l(185);break;case 187:_l(187);break;case 189:_l(189);break;case 202:_l(202);break;case 204:_l(204);break;case 205:_l(205);break;case 206:_l(206);break;case 210:_l(210);break;case 216:_l(216);break;case 217:_l(217);break;case 222:_l(222);break;case 223:_l(223);break;case 224:_l(224);break;case 228:_l(228);break;case 234:_l(234);break;case 240:_l(240);break;case 241:_l(241);break;case 242:_l(242);break;case 253:_l(253);break;case 254:_l(254);break;case 256:_l(256);break;case 260:_l(260);break;case 262:_l(262);break;case 266:_l(266);break;case 272:_l(272);break;case 276:_l(276);break;case 170:_l(170);break;case 73:_l(73);break;case 82:_l(82);break;case 84:_l(84);break;case 86:_l(86);break;case 87:_l(87);break;case 92:_l(92);break;case 99:_l(99);break;case 102:_l(102);break;case 103:_l(103);break;case 105:_l(105);break;case 107:_l(107);break;case 126:_l(126);break;case 133:_l(133);break;case 134:_l(134);break;case 143:_l(143);break;case 156:_l(156);break;case 157:_l(157);break;case 163:_l(163);break;case 174:_l(174);break;case 195:_l(195);break;case 203:_l(203);break;case 207:_l(207);break;case 226:_l(226);break;case 229:_l(229);break;case 232:_l(232);break;case 239:_l(239);break;case 245:_l(245);break;case 257:_l(257);break;case 258:_l(258);break;case 263:_l(263);break;case 267:_l(267);break;case 268:_l(268);break;case 269:_l(269);break;case 273:_l(273);break;case 98:_l(98);break;case 179:_l(179);break;case 225:_l(225);break;case 78:_l(78);break;case 135:_l(135);break;case 142:_l(142);break;case 197:_l(197);break;case 168:_l(168);break;case 198:_l(198);break;case 233:_l(233);break;default:_l(255)}nc.endNonterminal("FunctionName",Wl)}function Ja(){switch(Xl){case 6:Dl(6);break;case 71:Dl(71);break;case 74:Dl(74);break;case 75:Dl(75);break;case 76:Dl(76);break;case 80:Dl(80);break;case 81:Dl(81);break;case 85:Dl(85);break;case 89:Dl(89);break;case 90:Dl(90);break;case 91:Dl(91);break;case 94:Dl(94);break;case 95:Dl(95);break;case 104:Dl(104);break;case 106:Dl(106);break;case 109:Dl(109);break;case 110:Dl(110);break;case 111:Dl(111);break;case 112:Dl(112);break;case 113:Dl(113);break;case 114:Dl(114);break;case 119:Dl(119);break;case 120:Dl(120);break;case 123:Dl(123);break;case 124:Dl(124);break;case 127:Dl(127);break;case 129:Dl(129);break;case 130:Dl(130);break;case 132:Dl(132);break;case 136:Dl(136);break;case 137:Dl(137);break;case 138:Dl(138);break;case 139:Dl(139);break;case 148:Dl(148);break;case 150:Dl(150);break;case 152:Dl(152);break;case 153:Dl(153);break;case 155:Dl(155);break;case 161:Dl(161);break;case 162:Dl(162);break;case 164:Dl(164);break;case 165:Dl(165);break;case 166:Dl(166);break;case 173:Dl(173);break;case 175:Dl(175);break;case 177:Dl(177);break;case 181:Dl(181);break;case 183:Dl(183);break;case 184:Dl(184);break;case 185:Dl(185);break;case 187:Dl(187);break;case 189:Dl(189);break;case 202:Dl(202);break;case 204:Dl(204);break;case 205:Dl(205);break;case 206:Dl(206);break;case 210:Dl(210);break;case 216:Dl(216);break;case 217:Dl(217);break;case 222:Dl(222);break;case 223:Dl(223);break;case 224:Dl(224);break;case 228:Dl(228);break;case 234:Dl(234);break;case 240:Dl(240);break;case 241:Dl(241);break;case 242:Dl(242);break;case 253:Dl(253);break;case 254:Dl(254);break;case 256:Dl(256);break;case 260:Dl(260);break;case 262:Dl(262);break;case 266:Dl(266);break;case 272:Dl(272);break;case 276:Dl(276);break;case 170:Dl(170);break;case 73:Dl(73);break;case 82:Dl(82);break;case 84:Dl(84);break;case 86:Dl(86);break;case 87:Dl(87);break;case 92:Dl(92);break;case 99:Dl(99);break;case 102:Dl(102);break;case 103:Dl(103);break;case 105:Dl(105);break;case 107:Dl(107);break;case 126:Dl(126);break;case 133:Dl(133);break;case 134:Dl(134);break;case 143:Dl(143);break;case 156:Dl(156);break;case 157:Dl(157);break;case 163:Dl(163);break;case 174:Dl(174);break;case 195:Dl(195);break;case 203:Dl(203);break;case 207:Dl(207);break;case 226:Dl(226);break;case 229:Dl(229);break;case 232:Dl(232);break;case 239:Dl(239);break;case 245:Dl(245);break;case 257:Dl(257);break;case 258:Dl(258);break;case 263:Dl(263);break;case 267:Dl(267);break;case 268:Dl(268);break;case 269:Dl(269);break;case 273:Dl(273);break;case 98:Dl(98);break;case 179:Dl(179);break;case 225:Dl(225);break;case 78:Dl(78);break;case 135:Dl(135);break;case 142:Dl(142);break;case 197:Dl(197);break;case 168:Dl(168);break;case 198:Dl(198);break;case 233:Dl(233);break;default:Dl(255)}}function Ka(){nc.startNonterminal("NCName",Wl);switch(Xl){case 19:_l(19);break;case 71:_l(71);break;case 76:_l(76);break;case 80:_l(80);break;case 81:_l(81);break;case 85:_l(85);break;case 89:_l(89);break;case 90:_l(90);break;case 91:_l(91);break;case 95:_l(95);break;case 106:_l(106);break;case 110:_l(110);break;case 114:_l(114);break;case 119:_l(119);break;case 123:_l(123);break;case 124:_l(124);break;case 127:_l(127);break;case 129:_l(129);break;case 132:_l(132);break;case 139:_l(139);break;case 148:_l(148);break;case 150:_l(150);break;case 152:_l(152);break;case 153:_l(153);break;case 162:_l(162);break;case 164:_l(164);break;case 165:_l(165);break;case 166:_l(166);break;case 175:_l(175);break;case 177:_l(177);break;case 181:_l(181);break;case 183:_l(183);break;case 184:_l(184);break;case 189:_l(189);break;case 202:_l(202);break;case 204:_l(204);break;case 205:_l(205);break;case 224:_l(224);break;case 228:_l(228);break;case 241:_l(241);break;case 242:_l(242);break;case 253:_l(253);break;case 254:_l(254);break;case 260:_l(260);break;case 272:_l(272);break;case 276:_l(276);break;case 74:_l(74);break;case 75:_l(75);break;case 83:_l(83);break;case 94:_l(94);break;case 97:_l(97);break;case 104:_l(104);break;case 109:_l(109);break;case 111:_l(111);break;case 112:_l(112);break;case 113:_l(113);break;case 120:_l(120);break;case 121:_l(121);break;case 122:_l(122);break;case 125:_l(125);break;case 130:_l(130);break;case 136:_l(136);break;case 137:_l(137);break;case 138:_l(138);break;case 147:_l(147);break;case 154:_l(154);break;case 155:_l(155);break;case 161:_l(161);break;case 167:_l(167);break;case 173:_l(173);break;case 185:_l(185);break;case 187:_l(187);break;case 188:_l(188);break;case 194:_l(194);break;case 206:_l(206);break;case 210:_l(210);break;case 216:_l(216);break;case 217:_l(217);break;case 220:_l(220);break;case 222:_l(222);break;case 223:_l(223);break;case 230:_l(230);break;case 231:_l(231);break;case 234:_l(234);break;case 240:_l(240);break;case 248:_l(248);break;case 249:_l(249);break;case 256:_l(256);break;case 259:_l(259);break;case 262:_l(262);break;case 266:_l(266);break;case 268:_l(268);break;case 170:_l(170);break;case 73:_l(73);break;case 82:_l(82);break;case 84:_l(84);break;case 86:_l(86);break;case 87:_l(87);break;case 92:_l(92);break;case 99:_l(99);break;case 102:_l(102);break;case 103:_l(103);break;case 105:_l(105);break;case 107:_l(107);break;case 126:_l(126);break;case 133:_l(133);break;case 134:_l(134);break;case 143:_l(143);break;case 156:_l(156);break;case 157:_l(157);break;case 163:_l(163);break;case 174:_l(174);break;case 195:_l(195);break;case 203:_l(203);break;case 207:_l(207);break;case 226:_l(226);break;case 229:_l(229);break;case 232:_l(232);break;case 239:_l(239);break;case 245:_l(245);break;case 257:_l(257);break;case 258:_l(258);break;case 263:_l(263);break;case 267:_l(267);break;case 269:_l(269);break;case 273:_l(273);break;case 98:_l(98);break;case 179:_l(179);break;case 225:_l(225);break;case 78:_l(78);break;case 135:_l(135);break;case 142:_l(142);break;case 197:_l(197);break;case 168:_l(168);break;case 198:_l(198);break;case 233:_l(233);break;default:_l(255)}nc.endNonterminal("NCName",Wl)}function Qa(){switch(Xl){case 19:Dl(19);break;case 71:Dl(71);break;case 76:Dl(76);break;case 80:Dl(80);break;case 81:Dl(81);break;case 85:Dl(85);break;case 89:Dl(89);break;case 90:Dl(90);break;case 91:Dl(91);break;case 95:Dl(95);break;case 106:Dl(106);break;case 110:Dl(110);break;case 114:Dl(114);break;case 119:Dl(119);break;case 123:Dl(123);break;case 124:Dl(124);break;case 127:Dl(127);break;case 129:Dl(129);break;case 132:Dl(132);break;case 139:Dl(139);break;case 148:Dl(148);break;case 150:Dl(150);break;case 152:Dl(152);break;case 153:Dl(153);break;case 162:Dl(162);break;case 164:Dl(164);break;case 165:Dl(165);break;case 166:Dl(166);break;case 175:Dl(175);break;case 177:Dl(177);break;case 181:Dl(181);break;case 183:Dl(183);break;case 184:Dl(184);break;case 189:Dl(189);break;case 202:Dl(202);break;case 204:Dl(204);break;case 205:Dl(205);break;case 224:Dl(224);break;case 228:Dl(228);break;case 241:Dl(241);break;case 242:Dl(242);break;case 253:Dl(253);break;case 254:Dl(254);break;case 260:Dl(260);break;case 272:Dl(272);break;case 276:Dl(276);break;case 74:Dl(74);break;case 75:Dl(75);break;case 83:Dl(83);break;case 94:Dl(94);break;case 97:Dl(97);break;case 104:Dl(104);break;case 109:Dl(109);break;case 111:Dl(111);break;case 112:Dl(112);break;case 113:Dl(113);break;case 120:Dl(120);break;case 121:Dl(121);break;case 122:Dl(122);break;case 125:Dl(125);break;case 130:Dl(130);break;case 136:Dl(136);break;case 137:Dl(137);break;case 138:Dl(138);break;case 147:Dl(147);break;case 154:Dl(154);break;case 155:Dl(155);break;case 161:Dl(161);break;case 167:Dl(167);break;case 173:Dl(173);break;case 185:Dl(185);break;case 187:Dl(187);break;case 188:Dl(188);break;case 194:Dl(194);break;case 206:Dl(206);break;case 210:Dl(210);break;case 216:Dl(216);break;case 217:Dl(217);break;case 220:Dl(220);break;case 222:Dl(222);break;case 223:Dl(223);break;case 230:Dl(230);break;case 231:Dl(231);break;case 234:Dl(234);break;case 240:Dl(240);break;case 248:Dl(248);break;case 249:Dl(249);break;case 256:Dl(256);break;case 259:Dl(259);break;case 262:Dl(262);break;case 266:Dl(266);break;case 268:Dl(268);break;case 170:Dl(170);break;case 73:Dl(73);break;case 82:Dl(82);break;case 84:Dl(84);break;case 86:Dl(86);break;case 87:Dl(87);break;case 92:Dl(92);break;case 99:Dl(99);break;case 102:Dl(102);break;case 103:Dl(103);break;case 105:Dl(105);break;case 107:Dl(107);break;case 126:Dl(126);break;case 133:Dl(133);break;case 134:Dl(134);break;case 143:Dl(143);break;case 156:Dl(156);break;case 157:Dl(157);break;case 163:Dl(163);break;case 174:Dl(174);break;case 195:Dl(195);break;case 203:Dl(203);break;case 207:Dl(207);break;case 226:Dl(226);break;case 229:Dl(229);break;case 232:Dl(232);break;case 239:Dl(239);break;case 245:Dl(245);break;case 257:Dl(257);break;case 258:Dl(258);break;case 263:Dl(263);break;case 267:Dl(267);break;case 269:Dl(269);break;case 273:Dl(273);break;case 98:Dl(98);break;case 179:Dl(179);break;case 225:Dl(225);break;case 78:Dl(78);break;case 135:Dl(135);break;case 142:Dl(142);break;case 197:Dl(197);break;case 168:Dl(168);break;case 198:Dl(198);break;case 233:Dl(233);break;default:Dl(255)}}function Ga(){nc.startNonterminal("MainModule",Wl),l(),Hl(),Ya(),nc.endNonterminal("MainModule",Wl)}function Ya(){nc.startNonterminal("Program",Wl),rf(),nc.endNonterminal("Program",Wl)}function Za(){nc.startNonterminal("Statements",Wl);for(;;){jl(285);switch(Xl){case 35:Fl(271);break;case 36:ql(244);break;case 47:Fl(287);break;case 48:Fl(261);break;case 55:ql(4);break;case 56:ql(1);break;case 60:ql(3);break;case 69:Fl(274);break;case 78:Fl(270);break;case 133:Fl(145);break;case 161:Fl(277);break;case 177:Fl(167);break;case 187:Fl(248);break;case 196:Fl(268);break;case 220:Fl(246);break;case 223:Fl(171);break;case 266:Fl(189);break;case 281:Fl(284);break;case 283:Fl(275);break;case 31:case 33:Fl(247);break;case 41:case 43:Fl(267);break;case 83:case 122:Fl(254);break;case 87:case 103:Fl(143);break;case 97:case 249:Fl(96);break;case 111:case 222:Fl(262);break;case 139:case 142:Fl(180);break;case 135:case 197:case 255:Fl(212);break;case 104:case 130:case 240:case 268:Fl(141);break;case 120:case 206:case 256:case 262:Fl(146);break;case 8:case 9:case 10:case 11:case 32:Fl(211);break;case 79:case 121:case 125:case 167:case 169:case 188:case 194:case 230:case 231:case 247:Fl(20);break;case 6:case 71:case 73:case 74:case 75:case 76:case 80:case 81:case 82:case 84:case 85:case 86:case 89:case 90:case 91:case 92:case 94:case 95:case 98:case 99:case 102:case 105:case 106:case 107:case 109:case 110:case 112:case 113:case 114:case 119:case 123:case 124:case 126:case 127:case 129:case 132:case 134:case 136:case 137:case 138:case 143:case 147:case 148:case 150:case 152:case 153:case 154:case 155:case 156:case 157:case 162:case 163:case 164:case 165:case 166:case 168:case 170:case 173:case 174:case 175:case 179:case 181:case 183:case 184:case 185:case 189:case 195:case 198:case 202:case 203:case 204:case 205:case 207:case 210:case 216:case 217:case 224:case 225:case 226:case 228:case 229:case 232:case 233:case 234:case 239:case 241:case 242:case 245:case 248:case 253:case 254:case 257:case 258:case 259:case 260:case 263:case 267:case 269:case 272:case 273:case 276:Fl(94);break;default:Ul=Xl}if(Ul!=25&&Ul!=54&&Ul!=287&&Ul!=12808&&Ul!=12809&&Ul!=12810&&Ul!=12811&&Ul!=12832&&Ul!=12847&&Ul!=12935&&Ul!=12997&&Ul!=13055&&Ul!=16140&&Ul!=21512&&Ul!=21513&&Ul!=21514&&Ul!=21515&&Ul!=21536&&Ul!=21551&&Ul!=21639&&Ul!=21701&&Ul!=21759&&Ul!=27656&&Ul!=27657&&Ul!=27658&&Ul!=27659&&Ul!=27680&&Ul!=27695&&Ul!=27783&&Ul!=27845&&Ul!=27903&&Ul!=91735&&Ul!=91751&&Ul!=115333&&Ul!=146952&&Ul!=146953&&Ul!=146954&&Ul!=146955&&Ul!=146976&&Ul!=146991&&Ul!=147079&&Ul!=147141&&Ul!=147199){Ul=sc(8,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{uf(),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(8,Wl,Ul)}}if(Ul!=-1&&Ul!=54&&Ul!=16140&&Ul!=27656&&Ul!=27657&&Ul!=27658&&Ul!=27659&&Ul!=27680&&Ul!=27695&&Ul!=27783&&Ul!=27845&&Ul!=27903&&Ul!=91735&&Ul!=91751&&Ul!=115333)break;Hl(),of()}nc.endNonterminal("Statements",Wl)}function ef(){for(;;){jl(285);switch(Xl){case 35:Fl(271);break;case 36:ql(244);break;case 47:Fl(287);break;case 48:Fl(261);break;case 55:ql(4);break;case 56:ql(1);break;case 60:ql(3);break;case 69:Fl(274);break;case 78:Fl(270);break;case 133:Fl(145);break;case 161:Fl(277);break;case 177:Fl(167);break;case 187:Fl(248);break;case 196:Fl(268);break;case 220:Fl(246);break;case 223:Fl(171);break;case 266:Fl(189);break;case 281:Fl(284);break;case 283:Fl(275);break;case 31:case 33:Fl(247);break;case 41:case 43:Fl(267);break;case 83:case 122:Fl(254);break;case 87:case 103:Fl(143);break;case 97:case 249:Fl(96);break;case 111:case 222:Fl(262);break;case 139:case 142:Fl(180);break;case 135:case 197:case 255:Fl(212);break;case 104:case 130:case 240:case 268:Fl(141);break;case 120:case 206:case 256:case 262:Fl(146);break;case 8:case 9:case 10:case 11:case 32:Fl(211);break;case 79:case 121:case 125:case 167:case 169:case 188:case 194:case 230:case 231:case 247:Fl(20);break;case 6:case 71:case 73:case 74:case 75:case 76:case 80:case 81:case 82:case 84:case 85:case 86:case 89:case 90:case 91:case 92:case 94:case 95:case 98:case 99:case 102:case 105:case 106:case 107:case 109:case 110:case 112:case 113:case 114:case 119:case 123:case 124:case 126:case 127:case 129:case 132:case 134:case 136:case 137:case 138:case 143:case 147:case 148:case 150:case 152:case 153:case 154:case 155:case 156:case 157:case 162:case 163:case 164:case 165:case 166:case 168:case 170:case 173:case 174:case 175:case 179:case 181:case 183:case 184:case 185:case 189:case 195:case 198:case 202:case 203:case 204:case 205:case 207:case 210:case 216:case 217:case 224:case 225:case 226:case 228:case 229:case 232:case 233:case 234:case 239:case 241:case 242:case 245:case 248:case 253:case 254:case 257:case 258:case 259:case 260:case 263:case 267:case 269:case 272:case 273:case 276:Fl(94);break;default:Ul=Xl}if(Ul!=25&&Ul!=54&&Ul!=287&&Ul!=12808&&Ul!=12809&&Ul!=12810&&Ul!=12811&&Ul!=12832&&Ul!=12847&&Ul!=12935&&Ul!=12997&&Ul!=13055&&Ul!=16140&&Ul!=21512&&Ul!=21513&&Ul!=21514&&Ul!=21515&&Ul!=21536&&Ul!=21551&&Ul!=21639&&Ul!=21701&&Ul!=21759&&Ul!=27656&&Ul!=27657&&Ul!=27658&&Ul!=27659&&Ul!=27680&&Ul!=27695&&Ul!=27783&&Ul!=27845&&Ul!=27903&&Ul!=91735&&Ul!=91751&&Ul!=115333&&Ul!=146952&&Ul!=146953&&Ul!=146954&&Ul!=146955&&Ul!=146976&&Ul!=146991&&Ul!=147079&&Ul!=147141&&Ul!=147199){Ul=sc(8,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{uf(),ic(8,t,-1);continue}catch(a){zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(8,t,-2);break}}}if(Ul!=-1&&Ul!=54&&Ul!=16140&&Ul!=27656&&Ul!=27657&&Ul!=27658&&Ul!=27659&&Ul!=27680&&Ul!=27695&&Ul!=27783&&Ul!=27845&&Ul!=27903&&Ul!=91735&&Ul!=91751&&Ul!=115333)break;uf()}}function tf(){nc.startNonterminal("StatementsAndExpr",Wl),Za(),Hl(),G(),nc.endNonterminal("StatementsAndExpr",Wl)}function nf(){ef(),Y()}function rf(){nc.startNonterminal("StatementsAndOptionalExpr",Wl),Za(),Xl!=25&&Xl!=287&&(Hl(),G()),nc.endNonterminal("StatementsAndOptionalExpr",Wl)}function sf(){ef(),Xl!=25&&Xl!=287&&Y()}function of(){nc.startNonterminal("Statement",Wl);switch(Xl){case 133:Fl(145);break;case 177:Fl(167);break;case 256:Fl(146);break;case 268:Fl(141);break;case 281:Fl(284);break;case 31:case 33:Fl(247);break;case 87:case 103:Fl(143);break;case 139:case 142:Fl(180);break;case 154:case 248:case 259:case 273:Fl(94);break;default:Ul=Xl}if(Ul!=6&&Ul!=8&&Ul!=9&&Ul!=10&&Ul!=11&&Ul!=32&&Ul!=35&&Ul!=36&&Ul!=41&&Ul!=43&&Ul!=47&&Ul!=48&&Ul!=54&&Ul!=55&&Ul!=56&&Ul!=60&&Ul!=69&&Ul!=71&&Ul!=73&&Ul!=74&&Ul!=75&&Ul!=76&&Ul!=78&&Ul!=79&&Ul!=80&&Ul!=81&&Ul!=82&&Ul!=83&&Ul!=84&&Ul!=85&&Ul!=86&&Ul!=89&&Ul!=90&&Ul!=91&&Ul!=92&&Ul!=94&&Ul!=95&&Ul!=97&&Ul!=98&&Ul!=99&&Ul!=102&&Ul!=104&&Ul!=105&&Ul!=106&&Ul!=107&&Ul!=109&&Ul!=110&&Ul!=111&&Ul!=112&&Ul!=113&&Ul!=114&&Ul!=119&&Ul!=120&&Ul!=121&&Ul!=122&&Ul!=123&&Ul!=124&&Ul!=125&&Ul!=126&&Ul!=127&&Ul!=129&&Ul!=130&&Ul!=132&&Ul!=134&&Ul!=135&&Ul!=136&&Ul!=137&&Ul!=138&&Ul!=143&&Ul!=147&&Ul!=148&&Ul!=150&&Ul!=152&&Ul!=153&&Ul!=155&&Ul!=156&&Ul!=157&&Ul!=161&&Ul!=162&&Ul!=163&&Ul!=164&&Ul!=165&&Ul!=166&&Ul!=167&&Ul!=168&&Ul!=169&&Ul!=170&&Ul!=173&&Ul!=174&&Ul!=175&&Ul!=179&&Ul!=181&&Ul!=183&&Ul!=184&&Ul!=185&&Ul!=187&&Ul!=188&&Ul!=189&&Ul!=194&&Ul!=195&&Ul!=196&&Ul!=197&&Ul!=198&&Ul!=202&&Ul!=203&&Ul!=204&&Ul!=205&&Ul!=206&&Ul!=207&&Ul!=210&&Ul!=216&&Ul!=217&&Ul!=220&&Ul!=222&&Ul!=223&&Ul!=224&&Ul!=225&&Ul!=226&&Ul!=228&&Ul!=229&&Ul!=230&&Ul!=231&&Ul!=232&&Ul!=233&&Ul!=234&&Ul!=239&&Ul!=240&&Ul!=241&&Ul!=242&&Ul!=245&&Ul!=247&&Ul!=249&&Ul!=253&&Ul!=254&&Ul!=255&&Ul!=257&&Ul!=258&&Ul!=260&&Ul!=262&&Ul!=263&&Ul!=266&&Ul!=267&&Ul!=269&&Ul!=272&&Ul!=276&&Ul!=283&&Ul!=10009&&Ul!=14935&&Ul!=14951&&Ul!=14981&&Ul!=14987&&Ul!=14990&&Ul!=15002&&Ul!=15025&&Ul!=15096&&Ul!=15104&&Ul!=15107&&Ul!=15116&&Ul!=15121&&Ul!=16011&&Ul!=16014&&Ul!=16049&&Ul!=16140&&Ul!=18007&&Ul!=18023&&Ul!=18053&&Ul!=18059&&Ul!=18062&&Ul!=18074&&Ul!=18097&&Ul!=18168&&Ul!=18176&&Ul!=18179&&Ul!=18188&&Ul!=91735&&Ul!=91751&&Ul!=115333&&Ul!=118961&&Ul!=122507&&Ul!=122510&&Ul!=131723&&Ul!=131726&&Ul!=144128&&Ul!=147225){Ul=sc(9,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{ff(),Ul=-1}catch(a){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),cf(),Ul=-2}catch(f){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),pf(),Ul=-3}catch(l){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),jf(),Ul=-12}catch(c){Ul=-13}}}}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(9,Wl,Ul)}}switch(Ul){case-2:lf();break;case-3:hf();break;case 91735:df();break;case 91751:mf();break;case 115333:yf();break;case 16011:case 16014:case 16049:case 118961:case 122507:case 122510:case 131723:case 131726:wf();break;case 18074:Tf();break;case 18168:Cf();break;case 144128:Of();break;case 18179:_f();break;case-12:case 16140:Bf();break;case-13:Ff();break;case 54:qf();break;default:af()}nc.endNonterminal("Statement",Wl)}function uf(){switch(Xl){case 133:Fl(145);break;case 177:Fl(167);break;case 256:Fl(146);break;case 268:Fl(141);break;case 281:Fl(284);break;case 31:case 33:Fl(247);break;case 87:case 103:Fl(143);break;case 139:case 142:Fl(180);break;case 154:case 248:case 259:case 273:Fl(94);break;default:Ul=Xl}if(Ul!=6&&Ul!=8&&Ul!=9&&Ul!=10&&Ul!=11&&Ul!=32&&Ul!=35&&Ul!=36&&Ul!=41&&Ul!=43&&Ul!=47&&Ul!=48&&Ul!=54&&Ul!=55&&Ul!=56&&Ul!=60&&Ul!=69&&Ul!=71&&Ul!=73&&Ul!=74&&Ul!=75&&Ul!=76&&Ul!=78&&Ul!=79&&Ul!=80&&Ul!=81&&Ul!=82&&Ul!=83&&Ul!=84&&Ul!=85&&Ul!=86&&Ul!=89&&Ul!=90&&Ul!=91&&Ul!=92&&Ul!=94&&Ul!=95&&Ul!=97&&Ul!=98&&Ul!=99&&Ul!=102&&Ul!=104&&Ul!=105&&Ul!=106&&Ul!=107&&Ul!=109&&Ul!=110&&Ul!=111&&Ul!=112&&Ul!=113&&Ul!=114&&Ul!=119&&Ul!=120&&Ul!=121&&Ul!=122&&Ul!=123&&Ul!=124&&Ul!=125&&Ul!=126&&Ul!=127&&Ul!=129&&Ul!=130&&Ul!=132&&Ul!=134&&Ul!=135&&Ul!=136&&Ul!=137&&Ul!=138&&Ul!=143&&Ul!=147&&Ul!=148&&Ul!=150&&Ul!=152&&Ul!=153&&Ul!=155&&Ul!=156&&Ul!=157&&Ul!=161&&Ul!=162&&Ul!=163&&Ul!=164&&Ul!=165&&Ul!=166&&Ul!=167&&Ul!=168&&Ul!=169&&Ul!=170&&Ul!=173&&Ul!=174&&Ul!=175&&Ul!=179&&Ul!=181&&Ul!=183&&Ul!=184&&Ul!=185&&Ul!=187&&Ul!=188&&Ul!=189&&Ul!=194&&Ul!=195&&Ul!=196&&Ul!=197&&Ul!=198&&Ul!=202&&Ul!=203&&Ul!=204&&Ul!=205&&Ul!=206&&Ul!=207&&Ul!=210&&Ul!=216&&Ul!=217&&Ul!=220&&Ul!=222&&Ul!=223&&Ul!=224&&Ul!=225&&Ul!=226&&Ul!=228&&Ul!=229&&Ul!=230&&Ul!=231&&Ul!=232&&Ul!=233&&Ul!=234&&Ul!=239&&Ul!=240&&Ul!=241&&Ul!=242&&Ul!=245&&Ul!=247&&Ul!=249&&Ul!=253&&Ul!=254&&Ul!=255&&Ul!=257&&Ul!=258&&Ul!=260&&Ul!=262&&Ul!=263&&Ul!=266&&Ul!=267&&Ul!=269&&Ul!=272&&Ul!=276&&Ul!=283&&Ul!=10009&&Ul!=14935&&Ul!=14951&&Ul!=14981&&Ul!=14987&&Ul!=14990&&Ul!=15002&&Ul!=15025&&Ul!=15096&&Ul!=15104&&Ul!=15107&&Ul!=15116&&Ul!=15121&&Ul!=16011&&Ul!=16014&&Ul!=16049&&Ul!=16140&&Ul!=18007&&Ul!=18023&&Ul!=18053&&Ul!=18059&&Ul!=18062&&Ul!=18074&&Ul!=18097&&Ul!=18168&&Ul!=18176&&Ul!=18179&&Ul!=18188&&Ul!=91735&&Ul!=91751&&Ul!=115333&&Ul!=118961&&Ul!=122507&&Ul!=122510&&Ul!=131723&&Ul!=131726&&Ul!=144128&&Ul!=147225){Ul=sc(9,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{ff(),ic(9,t,-1),Ul=-15}catch(a){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),cf(),ic(9,t,-2),Ul=-15}catch(f){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),pf(),ic(9,t,-3),Ul=-15}catch(l){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),jf(),ic(9,t,-12),Ul=-15}catch(c){Ul=-13,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(9,t,-13)}}}}}}switch(Ul){case-2:cf();break;case-3:pf();break;case 91735:vf();break;case 91751:gf();break;case 115333:bf();break;case 16011:case 16014:case 16049:case 118961:case 122507:case 122510:case 131723:case 131726:Ef();break;case 18074:Nf();break;case 18168:kf();break;case 144128:Mf();break;case 18179:Df();break;case-12:case 16140:jf();break;case-13:If();break;case 54:Rf();break;case-15:break;default:ff()}}function af(){nc.startNonterminal("ApplyStatement",Wl),Wf(),_l(54),nc.endNonterminal("ApplyStatement",Wl)}function ff(){Xf(),Dl(54)}function lf(){nc.startNonterminal("AssignStatement",Wl),_l(31),jl(247),Hl(),Si(),jl(28),_l(53),jl(268),Hl(),Uf(),_l(54),nc.endNonterminal("AssignStatement",Wl)}function cf(){Dl(31),jl(247),xi(),jl(28),Dl(53),jl(268),zf(),Dl(54)}function hf(){nc.startNonterminal("BlockStatement",Wl),_l(281),jl(272),Hl(),of(),jl(282),Hl(),Za(),_l(287),nc.endNonterminal("BlockStatement",Wl)}function pf(){Dl(281),jl(272),uf(),jl(282),ef(),Dl(287)}function df(){nc.startNonterminal("BreakStatement",Wl),_l(87),jl(62),_l(179),jl(29),_l(54),nc.endNonterminal("BreakStatement",Wl)}function vf(){Dl(87),jl(62),Dl(179),jl(29),Dl(54)}function mf(){nc.startNonterminal("ContinueStatement",Wl),_l(103),jl(62),_l(179),jl(29),_l(54),nc.endNonterminal("ContinueStatement",Wl)}function gf(){Dl(103),jl(62),Dl(179),jl(29),Dl(54)}function yf(){nc.startNonterminal("ExitStatement",Wl),_l(133),jl(73),_l(225),jl(268),Hl(),Uf(),_l(54),nc.endNonterminal("ExitStatement",Wl)}function bf(){Dl(133),jl(73),Dl(225),jl(268),zf(),Dl(54)}function wf(){nc.startNonterminal("FLWORStatement",Wl),tt();for(;;){jl(200);if(Xl==224||Xl==233)break;Hl(),rt()}Hl(),Sf(),nc.endNonterminal("FLWORStatement",Wl)}function Ef(){nt();for(;;){jl(200);if(Xl==224||Xl==233)break;it()}xf()}function Sf(){nc.startNonterminal("ReturnStatement",Wl);switch(Xl){case 224:_l(224);break;default:_l(233)}jl(272),Hl(),of(),nc.endNonterminal("ReturnStatement",Wl)}function xf(){switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(272),uf()}function Tf(){nc.startNonterminal("IfStatement",Wl),_l(154),jl(22),_l(35),jl(268),Hl(),G(),_l(38),jl(79),_l(250),jl(272),Hl(),of(),jl(51),_l(123),jl(272),Hl(),of(),nc.endNonterminal("IfStatement",Wl)}function Nf(){Dl(154),jl(22),Dl(35),jl(268),Y(),Dl(38),jl(79),Dl(250),jl(272),uf(),jl(51),Dl(123),jl(272),uf()}function Cf(){nc.startNonterminal("SwitchStatement",Wl),_l(248),jl(22),_l(35),jl(268),Hl(),G(),_l(38);for(;;){jl(38),Hl(),Lf(),jl(115);if(Xl!=89)break}_l(110),jl(136);switch(Xl){case 224:_l(224);break;default:_l(233)}jl(272),Hl(),of(),nc.endNonterminal("SwitchStatement",Wl)}function kf(){Dl(248),jl(22),Dl(35),jl(268),Y(),Dl(38);for(;;){jl(38),Af(),jl(115);if(Xl!=89)break}Dl(110),jl(136);switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(272),uf()}function Lf(){nc.startNonterminal("SwitchCaseStatement",Wl);for(;;){_l(89),jl(268),Hl(),hn();if(Xl!=89)break}switch(Xl){case 224:_l(224);break;default:_l(233)}jl(272),Hl(),of(),nc.endNonterminal("SwitchCaseStatement",Wl)}function Af(){for(;;){Dl(89),jl(268),pn();if(Xl!=89)break}switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(272),uf()}function Of(){nc.startNonterminal("TryCatchStatement",Wl),_l(256),jl(89),Hl(),hf();for(;;){jl(39),_l(92),jl(250),Hl(),On(),Hl(),hf(),jl(285);switch(Xl){case 92:Fl(257);break;default:Ul=Xl}if(Ul!=2652&&Ul!=3164&&Ul!=36444&&Ul!=37468&&Ul!=37980&&Ul!=38492&&Ul!=39004&&Ul!=40028&&Ul!=40540&&Ul!=41052&&Ul!=41564&&Ul!=42076&&Ul!=42588&&Ul!=43100&&Ul!=43612&&Ul!=44124&&Ul!=44636&&Ul!=45660&&Ul!=46172&&Ul!=46684&&Ul!=47196&&Ul!=48220&&Ul!=48732&&Ul!=49756&&Ul!=50268&&Ul!=50780&&Ul!=52316&&Ul!=52828&&Ul!=53340&&Ul!=53852&&Ul!=54364&&Ul!=54876&&Ul!=55900&&Ul!=56412&&Ul!=56924&&Ul!=57436&&Ul!=57948&&Ul!=58460&&Ul!=61020&&Ul!=61532&&Ul!=62044&&Ul!=62556&&Ul!=63068&&Ul!=63580&&Ul!=64092&&Ul!=64604&&Ul!=65116&&Ul!=66140&&Ul!=66652&&Ul!=67676&&Ul!=68188&&Ul!=68700&&Ul!=69212&&Ul!=69724&&Ul!=70236&&Ul!=70748&&Ul!=71260&&Ul!=72796&&Ul!=73308&&Ul!=75356&&Ul!=75868&&Ul!=76892&&Ul!=77916&&Ul!=78428&&Ul!=78940&&Ul!=79452&&Ul!=79964&&Ul!=80476&&Ul!=82524&&Ul!=83036&&Ul!=83548&&Ul!=84060&&Ul!=84572&&Ul!=85084&&Ul!=85596&&Ul!=86108&&Ul!=86620&&Ul!=87132&&Ul!=88668&&Ul!=89180&&Ul!=89692&&Ul!=90716&&Ul!=91740&&Ul!=92764&&Ul!=93788&&Ul!=94300&&Ul!=94812&&Ul!=95836&&Ul!=96348&&Ul!=96860&&Ul!=99420&&Ul!=99932&&Ul!=100956&&Ul!=101468&&Ul!=103516&&Ul!=104028&&Ul!=104540&&Ul!=105052&&Ul!=105564&&Ul!=106076&&Ul!=107612&&Ul!=110684&&Ul!=111196&&Ul!=112732&&Ul!=113756&&Ul!=114268&&Ul!=114780&&Ul!=115292&&Ul!=115804&&Ul!=116828&&Ul!=117340&&Ul!=117852&&Ul!=118364&&Ul!=118876&&Ul!=119388&&Ul!=119900&&Ul!=122460&&Ul!=122972&&Ul!=123484&&Ul!=123996&&Ul!=125532&&Ul!=126556&&Ul!=127068&&Ul!=127580&&Ul!=129628&&Ul!=130140&&Ul!=130652&&Ul!=131164&&Ul!=131676&&Ul!=132188&&Ul!=132700&&Ul!=133212&&Ul!=134236&&Ul!=134748&&Ul!=136284&&Ul!=136796&&Ul!=137308&&Ul!=137820&&Ul!=139356&&Ul!=139868&&Ul!=141404)break}nc.endNonterminal("TryCatchStatement",Wl)}function Mf(){Dl(256),jl(89),pf();for(;;){jl(39),Dl(92),jl(250),Mn(),pf(),jl(285);switch(Xl){case 92:Fl(257);break;default:Ul=Xl}if(Ul!=2652&&Ul!=3164&&Ul!=36444&&Ul!=37468&&Ul!=37980&&Ul!=38492&&Ul!=39004&&Ul!=40028&&Ul!=40540&&Ul!=41052&&Ul!=41564&&Ul!=42076&&Ul!=42588&&Ul!=43100&&Ul!=43612&&Ul!=44124&&Ul!=44636&&Ul!=45660&&Ul!=46172&&Ul!=46684&&Ul!=47196&&Ul!=48220&&Ul!=48732&&Ul!=49756&&Ul!=50268&&Ul!=50780&&Ul!=52316&&Ul!=52828&&Ul!=53340&&Ul!=53852&&Ul!=54364&&Ul!=54876&&Ul!=55900&&Ul!=56412&&Ul!=56924&&Ul!=57436&&Ul!=57948&&Ul!=58460&&Ul!=61020&&Ul!=61532&&Ul!=62044&&Ul!=62556&&Ul!=63068&&Ul!=63580&&Ul!=64092&&Ul!=64604&&Ul!=65116&&Ul!=66140&&Ul!=66652&&Ul!=67676&&Ul!=68188&&Ul!=68700&&Ul!=69212&&Ul!=69724&&Ul!=70236&&Ul!=70748&&Ul!=71260&&Ul!=72796&&Ul!=73308&&Ul!=75356&&Ul!=75868&&Ul!=76892&&Ul!=77916&&Ul!=78428&&Ul!=78940&&Ul!=79452&&Ul!=79964&&Ul!=80476&&Ul!=82524&&Ul!=83036&&Ul!=83548&&Ul!=84060&&Ul!=84572&&Ul!=85084&&Ul!=85596&&Ul!=86108&&Ul!=86620&&Ul!=87132&&Ul!=88668&&Ul!=89180&&Ul!=89692&&Ul!=90716&&Ul!=91740&&Ul!=92764&&Ul!=93788&&Ul!=94300&&Ul!=94812&&Ul!=95836&&Ul!=96348&&Ul!=96860&&Ul!=99420&&Ul!=99932&&Ul!=100956&&Ul!=101468&&Ul!=103516&&Ul!=104028&&Ul!=104540&&Ul!=105052&&Ul!=105564&&Ul!=106076&&Ul!=107612&&Ul!=110684&&Ul!=111196&&Ul!=112732&&Ul!=113756&&Ul!=114268&&Ul!=114780&&Ul!=115292&&Ul!=115804&&Ul!=116828&&Ul!=117340&&Ul!=117852&&Ul!=118364&&Ul!=118876&&Ul!=119388&&Ul!=119900&&Ul!=122460&&Ul!=122972&&Ul!=123484&&Ul!=123996&&Ul!=125532&&Ul!=126556&&Ul!=127068&&Ul!=127580&&Ul!=129628&&Ul!=130140&&Ul!=130652&&Ul!=131164&&Ul!=131676&&Ul!=132188&&Ul!=132700&&Ul!=133212&&Ul!=134236&&Ul!=134748&&Ul!=136284&&Ul!=136796&&Ul!=137308&&Ul!=137820&&Ul!=139356&&Ul!=139868&&Ul!=141404)break}}function _f(){nc.startNonterminal("TypeswitchStatement",Wl),_l(259),jl(22),_l(35),jl(268),Hl(),G(),_l(38);for(;;){jl(38),Hl(),Pf(),jl(115);if(Xl!=89)break}_l(110),jl(149),Xl==31&&(_l(31),jl(247),Hl(),Si()),jl(136);switch(Xl){case 224:_l(224);break;default:_l(233)}jl(272),Hl(),of(),nc.endNonterminal("TypeswitchStatement",Wl)}function Df(){Dl(259),jl(22),Dl(35),jl(268),Y(),Dl(38);for(;;){jl(38),Hf(),jl(115);if(Xl!=89)break}Dl(110),jl(149),Xl==31&&(Dl(31),jl(247),xi()),jl(136);switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(272),uf()}function Pf(){nc.startNonterminal("CaseStatement",Wl),_l(89),jl(259),Xl==31&&(_l(31),jl(247),Hl(),Si(),jl(33),_l(80)),jl(255),Hl(),Cs(),jl(136);switch(Xl){case 224:_l(224);break;default:_l(233)}jl(272),Hl(),of(),nc.endNonterminal("CaseStatement",Wl)}function Hf(){Dl(89),jl(259),Xl==31&&(Dl(31),jl(247),xi(),jl(33),Dl(80)),jl(255),ks(),jl(136);switch(Xl){case 224:Dl(224);break;default:Dl(233)}jl(272),uf()}function Bf(){nc.startNonterminal("VarDeclStatement",Wl);for(;;){jl(100);if(Xl!=33)break;Hl(),B()}_l(268),jl(21),_l(31),jl(247),Hl(),Si(),jl(173),Xl==80&&(Hl(),Ts()),jl(154),Xl==53&&(_l(53),jl(268),Hl(),Uf());for(;;){if(Xl!=42)break;_l(42),jl(21),_l(31),jl(247),Hl(),Si(),jl(173),Xl==80&&(Hl(),Ts()),jl(154),Xl==53&&(_l(53),jl(268),Hl(),Uf())}_l(54),nc.endNonterminal("VarDeclStatement",Wl)}function jf(){for(;;){jl(100);if(Xl!=33)break;j()}Dl(268),jl(21),Dl(31),jl(247),xi(),jl(173),Xl==80&&Ns(),jl(154),Xl==53&&(Dl(53),jl(268),zf());for(;;){if(Xl!=42)break;Dl(42),jl(21),Dl(31),jl(247),xi(),jl(173),Xl==80&&Ns(),jl(154),Xl==53&&(Dl(53),jl(268),zf())}Dl(54)}function Ff(){nc.startNonterminal("WhileStatement",Wl),_l(273),jl(22),_l(35),jl(268),Hl(),G(),_l(38),jl(272),Hl(),of(),nc.endNonterminal("WhileStatement",Wl)}function If(){Dl(273),jl(22),Dl(35),jl(268),Y(),Dl(38),jl(272),uf()}function qf(){nc.startNonterminal("VoidStatement",Wl),_l(54),nc.endNonterminal("VoidStatement",Wl)}function Rf(){Dl(54)}function Uf(){nc.startNonterminal("ExprSingle",Wl);switch(Xl){case 177:Fl(167);break;case 256:Fl(146);break;case 139:case 142:Fl(180);break;case 154:case 248:case 259:Fl(94);break;default:Ul=Xl}switch(Ul){case 16011:case 16014:case 16049:case 118961:case 122507:case 122510:case 131723:case 131726:Z();break;case 18074:wn();break;case 18168:an();break;case 144128:Sn();break;case 18179:dn();break;default:Wf()}nc.endNonterminal("ExprSingle",Wl)}function zf(){switch(Xl){case 177:Fl(167);break;case 256:Fl(146);break;case 139:case 142:Fl(180);break;case 154:case 248:case 259:Fl(94);break;default:Ul=Xl}switch(Ul){case 16011:case 16014:case 16049:case 118961:case 122507:case 122510:case 131723:case 131726:et();break;case 18074:En();break;case 18168:fn();break;case 144128:xn();break;case 18179:vn();break;default:Xf()}}function Wf(){nc.startNonterminal("ExprSimple",Wl);switch(Xl){case 78:Fl(270);break;case 161:Fl(277);break;case 223:Fl(171);break;case 111:case 222:Fl(262);break;case 104:case 130:case 240:Fl(141);break;default:Ul=Xl}if(Ul==17998||Ul==18031||Ul==18081||Ul==18142||Ul==99439||Ul==99489||Ul==99550||Ul==99951||Ul==100001||Ul==136927){Ul=sc(10,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dn(),Ul=-2}catch(a){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Ro(),Ul=-3}catch(f){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),zo(),Ul=-4}catch(l){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),$o(),Ul=-5}catch(c){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Xo(),Ul=-6}catch(h){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),$f(),Ul=-8}catch(p){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Kf(),Ul=-9}catch(d){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Gf(),Ul=-10}catch(v){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Zf(),Ul=-11}catch(m){Ul=-12}}}}}}}}}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(10,Wl,Ul)}}switch(Ul){case 16002:case 16112:on();break;case-3:qo();break;case-4:Uo();break;case-5:Vo();break;case-6:case 99551:Wo();break;case 15976:eu();break;case-8:case 3183:case 4207:case 4719:case 5231:case 5743:case 15983:case 16495:case 17007:case 28271:case 28783:case 30831:case 35439:case 36463:case 37487:case 37999:case 38511:case 39023:case 40047:case 40559:case 41071:case 41583:case 42095:case 42607:case 43119:case 43631:case 44143:case 44655:case 45679:case 46191:case 46703:case 47215:case 48239:case 48751:case 49775:case 50287:case 50799:case 52335:case 52847:case 53359:case 53871:case 54383:case 54895:case 55919:case 56431:case 56943:case 57455:case 57967:case 58479:case 61039:case 61551:case 62063:case 62575:case 63087:case 63599:case 64111:case 64623:case 65135:case 66159:case 66671:case 67695:case 68207:case 68719:case 69231:case 69743:case 70255:case 70767:case 71279:case 72815:case 73327:case 75375:case 75887:case 76911:case 77935:case 78447:case 78959:case 79471:case 79983:case 80495:case 82543:case 83055:case 83567:case 84079:case 84591:case 85103:case 85615:case 86127:case 86639:case 87151:case 88687:case 89199:case 89711:case 90735:case 91759:case 92783:case 93807:case 94319:case 94831:case 95855:case 96367:case 96879:case 100975:case 101487:case 103535:case 104047:case 104559:case 105071:case 105583:case 106095:case 107631:case 110703:case 111215:case 112751:case 113775:case 114287:case 114799:case 115311:case 115823:case 116847:case 117359:case 117871:case 118383:case 118895:case 119407:case 119919:case 122479:case 122991:case 123503:case 124015:case 125551:case 126575:case 127087:case 127599:case 129647:case 130159:case 130671:case 131183:case 131695:case 132207:case 132719:case 133231:case 134255:case 134767:case 136303:case 136815:case 137327:case 137839:case 139375:case 139887:case 141423:case 143983:case 145007:Vf();break;case-9:case 3233:case 4257:case 4769:case 5281:case 5793:case 9889:case 16033:case 16545:case 17057:case 18593:case 21153:case 22177:case 24225:case 24737:case 28321:case 28833:case 30881:case 35489:case 36513:case 37537:case 38049:case 38561:case 39073:case 40097:case 40609:case 41121:case 41633:case 42145:case 42657:case 43169:case 43681:case 44193:case 44705:case 45729:case 46241:case 46753:case 47265:case 48289:case 48801:case 49825:case 50337:case 50849:case 52385:case 52897:case 53409:case 53921:case 54433:case 54945:case 55969:case 56481:case 56993:case 57505:case 58017:case 58529:case 61089:case 61601:case 62113:case 62625:case 63137:case 63649:case 64161:case 64673:case 65185:case 66209:case 66721:case 67745:case 68257:case 68769:case 69281:case 69793:case 70305:case 70817:case 71329:case 72865:case 73377:case 75425:case 75937:case 76961:case 77985:case 78497:case 79009:case 79521:case 80033:case 80545:case 82593:case 83105:case 83617:case 84129:case 84641:case 85153:case 85665:case 86177:case 86689:case 87201:case 88737:case 89249:case 89761:case 90785:case 91809:case 92833:case 93857:case 94369:case 94881:case 95905:case 96417:case 96929:case 100513:case 101025:case 101537:case 103585:case 104097:case 104609:case 105121:case 105633:case 106145:case 107681:case 110753:case 111265:case 112801:case 113825:case 114337:case 114849:case 115361:case 115873:case 116897:case 117409:case 117921:case 118433:case 118945:case 119457:case 119969:case 122529:case 123041:case 123553:case 124065:case 125601:case 126625:case 127137:case 127649:case 129697:case 130209:case 130721:case 131233:case 131745:case 132257:case 132769:case 133281:case 134305:case 134817:case 136353:case 136865:case 137377:case 137889:case 139425:case 139937:case 141473:case 144033:case 145057:Jf();break;case-10:case 3294:case 4318:case 4830:case 5342:case 5854:case 16094:case 16606:case 17118:case 28382:case 28894:case 30942:case 35550:case 36574:case 37598:case 38110:case 38622:case 39134:case 40158:case 40670:case 41182:case 41694:case 42206:case 42718:case 43230:case 43742:case 44254:case 44766:case 45790:case 46302:case 46814:case 47326:case 48350:case 48862:case 49886:case 50398:case 50910:case 52446:case 52958:case 53470:case 53982:case 54494:case 55006:case 56030:case 56542:case 57054:case 57566:case 58078:case 58590:case 61150:case 61662:case 62174:case 62686:case 63198:case 63710:case 64222:case 64734:case 65246:case 66270:case 66782:case 67806:case 68318:case 68830:case 69342:case 69854:case 70366:case 70878:case 71390:case 72926:case 73438:case 75486:case 75998:case 77022:case 78046:case 78558:case 79070:case 79582:case 80094:case 80606:case 82654:case 83166:case 83678:case 84190:case 84702:case 85214:case 85726:case 86238:case 86750:case 87262:case 88798:case 89310:case 89822:case 90846:case 91870:case 92894:case 93918:case 94430:case 94942:case 95966:case 96478:case 96990:case 100062:case 101086:case 101598:case 103646:case 104158:case 104670:case 105182:case 105694:case 106206:case 107742:case 110814:case 111326:case 112862:case 113886:case 114398:case 114910:case 115422:case 115934:case 116958:case 117470:case 117982:case 118494:case 119006:case 119518:case 120030:case 122590:case 123102:case 123614:case 124126:case 125662:case 126686:case 127198:case 127710:case 129758:case 130270:case 130782:case 131294:case 131806:case 132318:case 132830:case 133342:case 134366:case 134878:case 136414:case 136926:case 137438:case 137950:case 139486:case 139998:case 141534:case 144094:case 145118:Qf();break;case-11:Yf();break;case-12:case 3150:case 4174:case 4686:case 5198:case 5710:case 15950:case 16462:case 16974:case 18510:case 21070:case 22094:case 24142:case 24654:case 28238:case 28750:case 30798:case 35406:case 36430:case 37454:case 37966:case 38478:case 38990:case 40014:case 40526:case 41038:case 41550:case 42062:case 42574:case 43086:case 43598:case 44110:case 44622:case 45646:case 46158:case 46670:case 47182:case 48206:case 48718:case 49742:case 50254:case 50766:case 52302:case 52814:case 53326:case 53838:case 54350:case 54862:case 55886:case 56398:case 56910:case 57422:case 57934:case 58446:case 61006:case 61518:case 62030:case 62542:case 63054:case 63566:case 64078:case 64590:case 65102:case 66126:case 66638:case 67662:case 68174:case 68686:case 69198:case 69710:case 70222:case 70734:case 71246:case 72782:case 73294:case 75342:case 75854:case 76878:case 77902:case 78414:case 78926:case 79438:case 79950:case 80462:case 82510:case 83022:case 83534:case 84046:case 84558:case 85070:case 85582:case 86094:case 86606:case 87118:case 88654:case 89166:case 89678:case 90702:case 91726:case 92750:case 93774:case 94286:case 94798:case 95822:case 96334:case 96846:case 99406:case 99918:case 100430:case 100942:case 101454:case 103502:case 104014:case 104526:case 105038:case 105550:case 106062:case 107598:case 110670:case 111182:case 112718:case 113742:case 114254:case 114766:case 115278:case 115790:case 116814:case 117326:case 117838:case 118350:case 118862:case 119374:case 119886:case 122446:case 122958:case 123470:case 123982:case 125518:case 126542:case 127054:case 127566:case 129614:case 130126:case 130638:case 131150:case 131662:case 132174:case 132686:case 133198:case 134222:case 134734:case 136270:case 136782:case 137294:case 137806:case 139342:case 139854:case 141390:case 143950:case 144974:el();break;default:_n()}nc.endNonterminal("ExprSimple",Wl)}function Xf(){switch(Xl){case 78:Fl(270);break;case 161:Fl(277);break;case 223:Fl(171);break;case 111:case 222:Fl(262);break;case 104:case 130:case 240:Fl(141);break;default:Ul=Xl}if(Ul==17998||Ul==18031||Ul==18081||Ul==18142||Ul==99439||Ul==99489||Ul==99550||Ul==99951||Ul==100001||Ul==136927){Ul=sc(10,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dn(),ic(10,t,-2),Ul=-13}catch(a){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Ro(),ic(10,t,-3),Ul=-13}catch(f){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),zo(),ic(10,t,-4),Ul=-13}catch(l){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),$o(),ic(10,t,-5),Ul=-13}catch(c){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Xo(),ic(10,t,-6),Ul=-13}catch(h){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),$f(),ic(10,t,-8),Ul=-13}catch(p){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Kf(),ic(10,t,-9),Ul=-13}catch(d){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Gf(),ic(10,t,-10),Ul=-13}catch(v){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Zf(),ic(10,t,-11),Ul=-13}catch(m){Ul=-12,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(10,t,-12)}}}}}}}}}}}switch(Ul){case 16002:case 16112:un();break;case-3:Ro();break;case-4:zo();break;case-5:$o();break;case-6:case 99551:Xo();break;case 15976:tu();break;case-8:case 3183:case 4207:case 4719:case 5231:case 5743:case 15983:case 16495:case 17007:case 28271:case 28783:case 30831:case 35439:case 36463:case 37487:case 37999:case 38511:case 39023:case 40047:case 40559:case 41071:case 41583:case 42095:case 42607:case 43119:case 43631:case 44143:case 44655:case 45679:case 46191:case 46703:case 47215:case 48239:case 48751:case 49775:case 50287:case 50799:case 52335:case 52847:case 53359:case 53871:case 54383:case 54895:case 55919:case 56431:case 56943:case 57455:case 57967:case 58479:case 61039:case 61551:case 62063:case 62575:case 63087:case 63599:case 64111:case 64623:case 65135:case 66159:case 66671:case 67695:case 68207:case 68719:case 69231:case 69743:case 70255:case 70767:case 71279:case 72815:case 73327:case 75375:case 75887:case 76911:case 77935:case 78447:case 78959:case 79471:case 79983:case 80495:case 82543:case 83055:case 83567:case 84079:case 84591:case 85103:case 85615:case 86127:case 86639:case 87151:case 88687:case 89199:case 89711:case 90735:case 91759:case 92783:case 93807:case 94319:case 94831:case 95855:case 96367:case 96879:case 100975:case 101487:case 103535:case 104047:case 104559:case 105071:case 105583:case 106095:case 107631:case 110703:case 111215:case 112751:case 113775:case 114287:case 114799:case 115311:case 115823:case 116847:case 117359:case 117871:case 118383:case 118895:case 119407:case 119919:case 122479:case 122991:case 123503:case 124015:case 125551:case 126575:case 127087:case 127599:case 129647:case 130159:case 130671:case 131183:case 131695:case 132207:case 132719:case 133231:case 134255:case 134767:case 136303:case 136815:case 137327:case 137839:case 139375:case 139887:case 141423:case 143983:case 145007:$f();break;case-9:case 3233:case 4257:case 4769:case 5281:case 5793:case 9889:case 16033:case 16545:case 17057:case 18593:case 21153:case 22177:case 24225:case 24737:case 28321:case 28833:case 30881:case 35489:case 36513:case 37537:case 38049:case 38561:case 39073:case 40097:case 40609:case 41121:case 41633:case 42145:case 42657:case 43169:case 43681:case 44193:case 44705:case 45729:case 46241:case 46753:case 47265:case 48289:case 48801:case 49825:case 50337:case 50849:case 52385:case 52897:case 53409:case 53921:case 54433:case 54945:case 55969:case 56481:case 56993:case 57505:case 58017:case 58529:case 61089:case 61601:case 62113:case 62625:case 63137:case 63649:case 64161:case 64673:case 65185:case 66209:case 66721:case 67745:case 68257:case 68769:case 69281:case 69793:case 70305:case 70817:case 71329:case 72865:case 73377:case 75425:case 75937:case 76961:case 77985:case 78497:case 79009:case 79521:case 80033:case 80545:case 82593:case 83105:case 83617:case 84129:case 84641:case 85153:case 85665:case 86177:case 86689:case 87201:case 88737:case 89249:case 89761:case 90785:case 91809:case 92833:case 93857:case 94369:case 94881:case 95905:case 96417:case 96929:case 100513:case 101025:case 101537:case 103585:case 104097:case 104609:case 105121:case 105633:case 106145:case 107681:case 110753:case 111265:case 112801:case 113825:case 114337:case 114849:case 115361:case 115873:case 116897:case 117409:case 117921:case 118433:case 118945:case 119457:case 119969:case 122529:case 123041:case 123553:case 124065:case 125601:case 126625:case 127137:case 127649:case 129697:case 130209:case 130721:case 131233:case 131745:case 132257:case 132769:case 133281:case 134305:case 134817:case 136353:case 136865:case 137377:case 137889:case 139425:case 139937:case 141473:case 144033:case 145057:Kf();break;case-10:case 3294:case 4318:case 4830:case 5342:case 5854:case 16094:case 16606:case 17118:case 28382:case 28894:case 30942:case 35550:case 36574:case 37598:case 38110:case 38622:case 39134:case 40158:case 40670:case 41182:case 41694:case 42206:case 42718:case 43230:case 43742:case 44254:case 44766:case 45790:case 46302:case 46814:case 47326:case 48350:case 48862:case 49886:case 50398:case 50910:case 52446:case 52958:case 53470:case 53982:case 54494:case 55006:case 56030:case 56542:case 57054:case 57566:case 58078:case 58590:case 61150:case 61662:case 62174:case 62686:case 63198:case 63710:case 64222:case 64734:case 65246:case 66270:case 66782:case 67806:case 68318:case 68830:case 69342:case 69854:case 70366:case 70878:case 71390:case 72926:case 73438:case 75486:case 75998:case 77022:case 78046:case 78558:case 79070:case 79582:case 80094:case 80606:case 82654:case 83166:case 83678:case 84190:case 84702:case 85214:case 85726:case 86238:case 86750:case 87262:case 88798:case 89310:case 89822:case 90846:case 91870:case 92894:case 93918:case 94430:case 94942:case 95966:case 96478:case 96990:case 100062:case 101086:case 101598:case 103646:case 104158:case 104670:case 105182:case 105694:case 106206:case 107742:case 110814:case 111326:case 112862:case 113886:case 114398:case 114910:case 115422:case 115934:case 116958:case 117470:case 117982:case 118494:case 119006:case 119518:case 120030:case 122590:case 123102:case 123614:case 124126:case 125662:case 126686:case 127198:case 127710:case 129758:case 130270:case 130782:case 131294:case 131806:case 132318:case 132830:case 133342:case 134366:case 134878:case 136414:case 136926:case 137438:case 137950:case 139486:case 139998:case 141534:case 144094:case 145118:Gf();break;case-11:Zf();break;case-12:case 3150:case 4174:case 4686:case 5198:case 5710:case 15950:case 16462:case 16974:case 18510:case 21070:case 22094:case 24142:case 24654:case 28238:case 28750:case 30798:case 35406:case 36430:case 37454:case 37966:case 38478:case 38990:case 40014:case 40526:case 41038:case 41550:case 42062:case 42574:case 43086:case 43598:case 44110:case 44622:case 45646:case 46158:case 46670:case 47182:case 48206:case 48718:case 49742:case 50254:case 50766:case 52302:case 52814:case 53326:case 53838:case 54350:case 54862:case 55886:case 56398:case 56910:case 57422:case 57934:case 58446:case 61006:case 61518:case 62030:case 62542:case 63054:case 63566:case 64078:case 64590:case 65102:case 66126:case 66638:case 67662:case 68174:case 68686:case 69198:case 69710:case 70222:case 70734:case 71246:case 72782:case 73294:case 75342:case 75854:case 76878:case 77902:case 78414:case 78926:case 79438:case 79950:case 80462:case 82510:case 83022:case 83534:case 84046:case 84558:case 85070:case 85582:case 86094:case 86606:case 87118:case 88654:case 89166:case 89678:case 90702:case 91726:case 92750:case 93774:case 94286:case 94798:case 95822:case 96334:case 96846:case 99406:case 99918:case 100430:case 100942:case 101454:case 103502:case 104014:case 104526:case 105038:case 105550:case 106062:case 107598:case 110670:case 111182:case 112718:case 113742:case 114254:case 114766:case 115278:case 115790:case 116814:case 117326:case 117838:case 118350:case 118862:case 119374:case 119886:case 122446:case 122958:case 123470:case 123982:case 125518:case 126542:case 127054:case 127566:case 129614:case 130126:case 130638:case 131150:case 131662:case 132174:case 132686:case 133198:case 134222:case 134734:case 136270:case 136782:case 137294:case 137806:case 139342:case 139854:case 141390:case 143950:case 144974:tl();break;case-13:break;default:Dn()}}function Vf(){nc.startNonterminal("JSONDeleteExpr",Wl),_l(111),jl(261);switch(Xl){case 168:Fl(262);break;default:Ul=Xl}if(Ul==18088){Ul=sc(11,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(168),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(11,Wl,Ul)}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&_l(168),jl(261),Hl(),Yr(),nc.endNonterminal("JSONDeleteExpr",Wl)}function $f(){Dl(111),jl(261);switch(Xl){case 168:Fl(262);break;default:Ul=Xl}if(Ul==18088){Ul=sc(11,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(168),ic(11,t,-1)}catch(a){zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(11,t,-2)}Ul=-2}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&Dl(168),jl(261),Zr()}function Jf(){nc.startNonterminal("JSONInsertExpr",Wl);switch(Xl){case 161:Fl(269);break;default:Ul=Xl}if(Ul!=9889){Ul=sc(12,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(161),jl(268);switch(Xl){case 168:Fl(270);break;default:Ul=Xl}if(Ul==18088){Ul=sc(13,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(168),ic(13,f,-1)}catch(m){zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(13,f,-2)}Ul=-2}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==18600||Ul==21160||Ul==22184||Ul==24232||Ul==24744||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==100520||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&Dl(168),jl(268),zf(),Dl(165),jl(268),zf();switch(Xl){case 82:Fl(72);break;default:Ul=Xl}if(Ul==110162){Ul=sc(14,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(82),jl(72),Dl(215),jl(268),zf(),ic(14,f,-1)}catch(m){zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(14,f,-2)}Ul=-2}}Ul==-1&&(Dl(82),jl(72),Dl(215),jl(268),zf()),Ul=-1}catch(g){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(12,Wl,Ul)}}switch(Ul){case-1:_l(161),jl(268);switch(Xl){case 168:Fl(270);break;default:Ul=Xl}if(Ul==18088){Ul=sc(13,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(168),Ul=-1}catch(m){Ul=-2}zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(13,Wl,Ul)}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==18600||Ul==21160||Ul==22184||Ul==24232||Ul==24744||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==100520||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&_l(168),jl(268),Hl(),Uf(),_l(165),jl(268),Hl(),Uf();switch(Xl){case 82:Fl(72);break;default:Ul=Xl}if(Ul==110162){Ul=sc(14,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(82),jl(72),Dl(215),jl(268),zf(),Ul=-1}catch(m){Ul=-2}zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(14,Wl,Ul)}}Ul==-1&&(_l(82),jl(72),_l(215),jl(268),Hl(),Uf());break;default:_l(161),jl(269);switch(Xl){case 168:Fl(283);break;default:Ul=Xl}if(Ul==18088){Ul=sc(15,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(168),Ul=-1}catch(m){Ul=-2}zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(15,Wl,Ul)}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==9896||Ul==16040||Ul==16552||Ul==17064||Ul==18600||Ul==21160||Ul==22184||Ul==24232||Ul==24744||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==100520||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&_l(168),jl(269),Hl(),Sl(),_l(165),jl(268),Hl(),Uf()}nc.endNonterminal("JSONInsertExpr",Wl)}function Kf(){switch(Xl){case 161:Fl(269);break;default:Ul=Xl}if(Ul!=9889){Ul=sc(12,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(161),jl(268);switch(Xl){case 168:Fl(270);break;default:Ul=Xl}if(Ul==18088){Ul=sc(13,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(168),ic(13,f,-1)}catch(m){zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(13,f,-2)}Ul=-2}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==18600||Ul==21160||Ul==22184||Ul==24232||Ul==24744||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==100520||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&Dl(168),jl(268),zf(),Dl(165),jl(268),zf();switch(Xl){case 82:Fl(72);break;default:Ul=Xl}if(Ul==110162){Ul=sc(14,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(82),jl(72),Dl(215),jl(268),zf(),ic(14,f,-1)}catch(m){zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(14,f,-2)}Ul=-2}}Ul==-1&&(Dl(82),jl(72),Dl(215),jl(268),zf()),ic(12,t,-1),Ul=-3}catch(g){Ul=-2,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(12,t,-2)}}}switch(Ul){case-1:Dl(161),jl(268);switch(Xl){case 168:Fl(270);break;default:Ul=Xl}if(Ul==18088){Ul=sc(13,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(168),ic(13,f,-1)}catch(m){zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(13,f,-2)}Ul=-2}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==18600||Ul==21160||Ul==22184||Ul==24232||Ul==24744||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==100520||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&Dl(168),jl(268),zf(),Dl(165),jl(268),zf();switch(Xl){case 82:Fl(72);break;default:Ul=Xl}if(Ul==110162){Ul=sc(14,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(82),jl(72),Dl(215),jl(268),zf(),ic(14,f,-1)}catch(m){zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(14,f,-2)}Ul=-2}}Ul==-1&&(Dl(82),jl(72),Dl(215),jl(268),zf());break;case-3:break;default:Dl(161),jl(269);switch(Xl){case 168:Fl(283);break;default:Ul=Xl}if(Ul==18088){Ul=sc(15,Wl);if(Ul==0){var a=zl,f=Wl,l=Xl,c=Vl,h=$l,p=Jl,d=Kl,v=Ql;try{Dl(168),ic(15,f,-1)}catch(m){zl=a,Wl=f,Xl=l,Xl==0?fc=f:(Vl=c,$l=h,Jl=p,Jl==0?fc=h:(Kl=d,Ql=v,fc=v)),ic(15,f,-2)}Ul=-2}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==9896||Ul==16040||Ul==16552||Ul==17064||Ul==18600||Ul==21160||Ul==22184||Ul==24232||Ul==24744||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==100520||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&Dl(168),jl(269),xl(),Dl(165),jl(268),zf()}}function Qf(){nc.startNonterminal("JSONRenameExpr",Wl),_l(222),jl(261);switch(Xl){case 168:Fl(262);break;default:Ul=Xl}if(Ul==18088){Ul=sc(16,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(168),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(16,Wl,Ul)}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&_l(168),jl(261),Hl(),Yr(),_l(80),jl(268),Hl(),Uf(),nc.endNonterminal("JSONRenameExpr",Wl)}function Gf(){Dl(222),jl(261);switch(Xl){case 168:Fl(262);break;default:Ul=Xl}if(Ul==18088){Ul=sc(16,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(168),ic(16,t,-1)}catch(a){zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(16,t,-2)}Ul=-2}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&Dl(168),jl(261),Zr(),Dl(80),jl(268),zf()}function Yf(){nc.startNonterminal("JSONReplaceExpr",Wl),_l(223),jl(84),_l(267),jl(67),_l(200),jl(59),_l(168),jl(261),Hl(),Yr(),_l(276),jl(268),Hl(),Uf(),nc.endNonterminal("JSONReplaceExpr",Wl)}function Zf(){Dl(223),jl(84),Dl(267),jl(67),Dl(200),jl(59),Dl(168),jl(261),Zr(),Dl(276),jl(268),zf()}function el(){nc.startNonterminal("JSONAppendExpr",Wl),_l(78),jl(268);switch(Xl){case 168:Fl(270);break;default:Ul=Xl}if(Ul==18088){Ul=sc(17,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(168),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(17,Wl,Ul)}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==18600||Ul==21160||Ul==22184||Ul==24232||Ul==24744||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==100520||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&_l(168),jl(268),Hl(),Uf(),_l(165),jl(268),Hl(),Uf(),nc.endNonterminal("JSONAppendExpr",Wl)}function tl(){Dl(78),jl(268);switch(Xl){case 168:Fl(270);break;default:Ul=Xl}if(Ul==18088){Ul=sc(17,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(168),ic(17,t,-1)}catch(a){zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(17,t,-2)}Ul=-2}}(Ul==-1||Ul==3240||Ul==4264||Ul==4776||Ul==5288||Ul==5800||Ul==16040||Ul==16552||Ul==17064||Ul==18600||Ul==21160||Ul==22184||Ul==24232||Ul==24744||Ul==28328||Ul==28840||Ul==30888||Ul==35496||Ul==36520||Ul==37544||Ul==38056||Ul==38568||Ul==39080||Ul==40104||Ul==40616||Ul==41128||Ul==41640||Ul==42152||Ul==42664||Ul==43176||Ul==43688||Ul==44200||Ul==44712||Ul==45736||Ul==46248||Ul==46760||Ul==47272||Ul==48296||Ul==48808||Ul==49832||Ul==50344||Ul==50856||Ul==52392||Ul==52904||Ul==53416||Ul==53928||Ul==54440||Ul==54952||Ul==55976||Ul==56488||Ul==57e3||Ul==57512||Ul==58024||Ul==58536||Ul==61096||Ul==61608||Ul==62120||Ul==62632||Ul==63144||Ul==63656||Ul==64168||Ul==64680||Ul==65192||Ul==66216||Ul==66728||Ul==67752||Ul==68264||Ul==68776||Ul==69288||Ul==69800||Ul==70312||Ul==70824||Ul==71336||Ul==72872||Ul==73384||Ul==75432||Ul==75944||Ul==76968||Ul==77992||Ul==78504||Ul==79016||Ul==79528||Ul==80040||Ul==80552||Ul==82600||Ul==83112||Ul==83624||Ul==84136||Ul==84648||Ul==85160||Ul==85672||Ul==86184||Ul==86696||Ul==87208||Ul==88744||Ul==89256||Ul==89768||Ul==90792||Ul==91816||Ul==92840||Ul==93864||Ul==94376||Ul==94888||Ul==95912||Ul==96424||Ul==96936||Ul==99496||Ul==100008||Ul==100520||Ul==101032||Ul==101544||Ul==103592||Ul==104104||Ul==104616||Ul==105128||Ul==105640||Ul==106152||Ul==107688||Ul==110760||Ul==111272||Ul==112808||Ul==113832||Ul==114344||Ul==114856||Ul==115368||Ul==115880||Ul==116904||Ul==117416||Ul==117928||Ul==118440||Ul==118952||Ul==119464||Ul==119976||Ul==122536||Ul==123048||Ul==123560||Ul==124072||Ul==125608||Ul==126632||Ul==127144||Ul==127656||Ul==129704||Ul==130216||Ul==130728||Ul==131240||Ul==131752||Ul==132264||Ul==132776||Ul==133288||Ul==134312||Ul==134824||Ul==136360||Ul==136872||Ul==137384||Ul==137896||Ul==139432||Ul==139944||Ul==141480||Ul==144040||Ul==145064)&&Dl(168),jl(268),zf(),Dl(165),jl(268),zf()}function nl(){nc.startNonterminal("CommonContent",Wl);switch(Xl){case 12:_l(12);break;case 23:_l(23);break;case 282:_l(282);break;case 288:_l(288);break;default:Ll()}nc.endNonterminal("CommonContent",Wl)}function rl(){switch(Xl){case 12:Dl(12);break;case 23:Dl(23);break;case 282:Dl(282);break;case 288:Dl(288);break;default:Al()}}function il(){nc.startNonterminal("ContentExpr",Wl),tf(),nc.endNonterminal("ContentExpr",Wl)}function sl(){nf()}function ol(){nc.startNonterminal("CompDocConstructor",Wl),_l(120),jl(89),Hl(),Ll(),nc.endNonterminal("CompDocConstructor",Wl)}function ul(){Dl(120),jl(89),Al()}function al(){nc.startNonterminal("CompAttrConstructor",Wl),_l(83),jl(251);switch(Xl){case 281:_l(281),jl(268),Hl(),G(),_l(287);break;default:Hl(),Xa()}jl(89);switch(Xl){case 281:Fl(282);break;default:Ul=Xl}if(Ul==147225){Ul=sc(18,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(281),jl(90),Dl(287),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(18,Wl,Ul)}}switch(Ul){case-1:_l(281),jl(90),_l(287);break;default:Hl(),Ll()}nc.endNonterminal("CompAttrConstructor",Wl)}function fl(){Dl(83),jl(251);switch(Xl){case 281:Dl(281),jl(268),Y(),Dl(287);break;default:Va()}jl(89);switch(Xl){case 281:Fl(282);break;default:Ul=Xl}if(Ul==147225){Ul=sc(18,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(281),jl(90),Dl(287),ic(18,t,-1),Ul=-3}catch(a){Ul=-2,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(18,t,-2)}}}switch(Ul){case-1:Dl(281),jl(90),Dl(287);break;case-3:break;default:Al()}}function ll(){nc.startNonterminal("CompPIConstructor",Wl),_l(220),jl(243);switch(Xl){case 281:_l(281),jl(268),Hl(),G(),_l(287);break;default:Hl(),Ka()}jl(89);switch(Xl){case 281:Fl(282);break;default:Ul=Xl}if(Ul==147225){Ul=sc(19,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(281),jl(90),Dl(287),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(19,Wl,Ul)}}switch(Ul){case-1:_l(281),jl(90),_l(287);break;default:Hl(),Ll()}nc.endNonterminal("CompPIConstructor",Wl)}function cl(){Dl(220),jl(243);switch(Xl){case 281:Dl(281),jl(268),Y(),Dl(287);break;default:Qa()}jl(89);switch(Xl){case 281:Fl(282);break;default:Ul=Xl}if(Ul==147225){Ul=sc(19,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{Dl(281),jl(90),Dl(287),ic(19,t,-1),Ul=-3}catch(a){Ul=-2,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(19,t,-2)}}}switch(Ul){case-1:Dl(281),jl(90),Dl(287);break;case-3:break;default:Al()}}function hl(){nc.startNonterminal("CompCommentConstructor",Wl),_l(97),jl(89),Hl(),Ll(),nc.endNonterminal("CompCommentConstructor",Wl)}function pl(){Dl(97),jl(89),Al()}function dl(){nc.startNonterminal("CompTextConstructor",Wl),_l(249),jl(89),Hl(),Ll(),nc.endNonterminal("CompTextConstructor",Wl)}function vl(){Dl(249),jl(89),Al()}function ml(){nc.startNonterminal("PrimaryExpr",Wl);switch(Xl){case 187:Fl(248);break;case 220:Fl(246);break;case 281:Fl(284);break;case 83:case 122:Fl(254);break;case 97:case 249:Fl(96);break;case 120:case 206:case 262:Fl(146);break;case 135:case 197:case 255:Fl(238);break;case 6:case 71:case 73:case 74:case 75:case 76:case 78:case 80:case 81:case 82:case 84:case 85:case 86:case 87:case 89:case 90:case 91:case 92:case 94:case 95:case 98:case 99:case 102:case 103:case 104:case 105:case 106:case 107:case 109:case 110:case 111:case 112:case 113:case 114:case 119:case 123:case 124:case 126:case 127:case 129:case 130:case 132:case 133:case 134:case 136:case 137:case 138:case 139:case 142:case 143:case 148:case 150:case 152:case 153:case 155:case 156:case 157:case 161:case 162:case 163:case 164:case 165:case 166:case 168:case 170:case 173:case 174:case 175:case 177:case 179:case 181:case 183:case 184:case 185:case 189:case 195:case 198:case 202:case 203:case 204:case 205:case 207:case 210:case 216:case 217:case 222:case 223:case 224:case 225:case 226:case 228:case 229:case 232:case 233:case 234:case 239:case 240:case 241:case 242:case 245:case 253:case 254:case 256:case 257:case 258:case 260:case 263:case 266:case 267:case 268:case 269:case 272:case 273:case 276:Fl(94);break;default:Ul=Xl}if(Ul==3353||Ul==4377||Ul==4889||Ul==5401||Ul==5913||Ul==16153||Ul==16665||Ul==17177||Ul==18055||Ul==18117||Ul==18175||Ul==18201||Ul==18713||Ul==21273||Ul==22297||Ul==24345||Ul==24857||Ul==28441||Ul==28953||Ul==31001||Ul==35609||Ul==36633||Ul==37657||Ul==38169||Ul==38681||Ul==39193||Ul==40217||Ul==40729||Ul==41241||Ul==41753||Ul==42265||Ul==42777||Ul==43289||Ul==43801||Ul==44313||Ul==44825||Ul==45849||Ul==46361||Ul==46873||Ul==47385||Ul==48409||Ul==48921||Ul==49945||Ul==50457||Ul==50969||Ul==52505||Ul==53017||Ul==53529||Ul==54041||Ul==54553||Ul==55065||Ul==56089||Ul==56601||Ul==57113||Ul==57625||Ul==58137||Ul==58649||Ul==61209||Ul==61721||Ul==62233||Ul==62745||Ul==63257||Ul==63769||Ul==64281||Ul==64793||Ul==65305||Ul==66329||Ul==66841||Ul==67865||Ul==68377||Ul==68889||Ul==69401||Ul==69913||Ul==70425||Ul==70937||Ul==71449||Ul==72985||Ul==73497||Ul==75545||Ul==76057||Ul==77081||Ul==78105||Ul==78617||Ul==79129||Ul==79641||Ul==80153||Ul==80665||Ul==82713||Ul==83225||Ul==83737||Ul==84249||Ul==84761||Ul==85273||Ul==85785||Ul==86297||Ul==86809||Ul==87321||Ul==88857||Ul==89369||Ul==89881||Ul==90905||Ul==91929||Ul==92953||Ul==93977||Ul==94489||Ul==95001||Ul==96025||Ul==96537||Ul==97049||Ul==99609||Ul==100121||Ul==100633||Ul==101145||Ul==101657||Ul==103705||Ul==104217||Ul==104729||Ul==105241||Ul==105753||Ul==106265||Ul==107801||Ul==110873||Ul==111385||Ul==112921||Ul==113945||Ul==114457||Ul==114969||Ul==115481||Ul==115993||Ul==117017||Ul==117529||Ul==118041||Ul==118553||Ul==119065||Ul==119577||Ul==120089||Ul==122649||Ul==123161||Ul==123673||Ul==124185||Ul==125721||Ul==126745||Ul==127257||Ul==127769||Ul==129817||Ul==130329||Ul==130841||Ul==131353||Ul==131865||Ul==132377||Ul==132889||Ul==133401||Ul==134425||Ul==134937||Ul==136473||Ul==136985||Ul==137497||Ul==138009||Ul==139545||Ul==140057||Ul==141593||Ul==144153||Ul==145177||Ul==147225){Ul=sc(20,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{pi(),Ul=-1}catch(a){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Di(),Ul=-5}catch(f){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Al(),Ul=-10}catch(l){Ul=-11}}}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(20,Wl,Ul)}}switch(Ul){case-1:case 8:case 9:case 10:case 11:case 12935:case 12997:case 13055:case 13447:case 13509:case 13567:case 13959:case 14021:case 14079:case 19591:case 19653:case 19711:case 20103:case 20165:case 20223:case 21127:case 21189:case 21247:case 21639:case 21701:case 21759:case 22151:case 22213:case 22271:case 23175:case 23237:case 23295:case 24199:case 24261:case 24319:case 24711:case 24773:case 24831:case 25735:case 25797:case 25855:case 27783:case 27845:case 27903:case 28295:case 28357:case 28415:case 29831:case 29893:case 29951:case 30343:case 30405:case 30463:case 31367:case 31429:case 31487:case 31879:case 31941:case 31999:case 32391:case 32453:case 32511:case 32903:case 32965:case 33023:case 35463:case 35525:case 35583:case 35975:case 36037:case 36095:case 36487:case 36549:case 36607:case 39047:case 39109:case 39167:case 41095:case 41157:case 41215:case 41607:case 41669:case 41727:case 42119:case 42181:case 42239:case 43655:case 43717:case 43775:case 45191:case 45253:case 45311:case 45703:case 45765:case 45823:case 46215:case 46277:case 46335:case 46727:case 46789:case 46847:case 48775:case 48837:case 48895:case 51335:case 51397:case 51455:case 54407:case 54469:case 54527:case 56455:case 56517:case 56575:case 58503:case 58565:case 58623:case 61063:case 61125:case 61183:case 63111:case 63173:case 63231:case 63623:case 63685:case 63743:case 65159:case 65221:case 65279:case 66183:case 66245:case 66303:case 67719:case 67781:case 67839:case 71303:case 71365:case 71423:case 72839:case 72901:case 72959:case 75911:case 75973:case 76031:case 76935:case 76997:case 77055:case 77959:case 78021:case 78079:case 78471:case 78533:case 78591:case 83079:case 83141:case 83199:case 84103:case 84165:case 84223:case 84615:case 84677:case 84735:case 85127:case 85189:case 85247:case 89735:case 89797:case 89855:case 90759:case 90821:case 90879:case 92807:case 92869:case 92927:case 93831:case 93893:case 93951:case 94343:case 94405:case 94463:case 96903:case 96965:case 97023:case 103559:case 103621:case 103679:case 104583:case 104645:case 104703:case 105095:case 105157:case 105215:case 107143:case 107205:case 107263:case 114823:case 114885:case 114943:case 116871:case 116933:case 116991:case 119431:case 119493:case 119551:case 121479:case 121541:case 121599:case 123527:case 123589:case 123647:case 124039:case 124101:case 124159:case 129159:case 129221:case 129279:case 129671:case 129733:case 129791:case 130183:case 130245:case 130303:case 133255:case 133317:case 133375:case 139399:case 139461:case 139519:case 141447:case 141509:case 141567:case 142983:case 143045:case 143103:case 145543:case 145605:case 145663:case 146055:case 146117:case 146175:case 146567:case 146629:case 146687:case 147079:case 147141:case 147199:hi();break;case 31:wi();break;case 35:Ti();break;case 32:Ci();break;case-5:case 17926:case 17991:case 17993:case 17994:case 17995:case 17996:case 17998:case 18e3:case 18001:case 18002:case 18004:case 18005:case 18006:case 18007:case 18009:case 18010:case 18011:case 18012:case 18014:case 18015:case 18018:case 18019:case 18022:case 18023:case 18024:case 18025:case 18026:case 18027:case 18029:case 18030:case 18031:case 18032:case 18033:case 18034:case 18039:case 18040:case 18043:case 18044:case 18046:case 18047:case 18049:case 18050:case 18052:case 18053:case 18054:case 18056:case 18057:case 18058:case 18059:case 18062:case 18063:case 18068:case 18070:case 18072:case 18073:case 18075:case 18076:case 18077:case 18081:case 18082:case 18083:case 18084:case 18085:case 18086:case 18088:case 18090:case 18093:case 18094:case 18095:case 18097:case 18099:case 18101:case 18103:case 18104:case 18105:case 18107:case 18109:case 18115:case 18118:case 18122:case 18123:case 18124:case 18125:case 18126:case 18127:case 18130:case 18136:case 18137:case 18142:case 18143:case 18144:case 18145:case 18146:case 18148:case 18149:case 18152:case 18153:case 18154:case 18159:case 18160:case 18161:case 18162:case 18165:case 18173:case 18174:case 18176:case 18177:case 18178:case 18180:case 18182:case 18183:case 18186:case 18187:case 18188:case 18189:case 18192:case 18193:case 18196:_i();break;case 144078:Li();break;case 144134:Oi();break;case 33:case 79:case 121:case 125:case 147:case 154:case 167:case 169:case 188:case 194:case 230:case 231:case 247:case 248:case 259:case 14854:case 14919:case 14921:case 14922:case 14923:case 14924:case 14926:case 14928:case 14929:case 14930:case 14931:case 14932:case 14933:case 14934:case 14935:case 14937:case 14938:case 14939:case 14940:case 14942:case 14943:case 14945:case 14946:case 14947:case 14950:case 14951:case 14952:case 14953:case 14954:case 14955:case 14957:case 14958:case 14959:case 14960:case 14961:case 14962:case 14967:case 14968:case 14970:case 14971:case 14972:case 14974:case 14975:case 14977:case 14978:case 14980:case 14981:case 14982:case 14983:case 14984:case 14985:case 14986:case 14987:case 14990:case 14991:case 14996:case 14998:case 15e3:case 15001:case 15003:case 15004:case 15005:case 15009:case 15010:case 15011:case 15012:case 15013:case 15014:case 15016:case 15018:case 15021:case 15022:case 15023:case 15025:case 15027:case 15029:case 15031:case 15032:case 15033:case 15035:case 15037:case 15043:case 15045:case 15046:case 15050:case 15051:case 15052:case 15053:case 15054:case 15055:case 15058:case 15064:case 15065:case 15068:case 15070:case 15071:case 15072:case 15073:case 15074:case 15076:case 15077:case 15080:case 15081:case 15082:case 15087:case 15088:case 15089:case 15090:case 15093:case 15097:case 15101:case 15102:case 15103:case 15104:case 15105:case 15106:case 15108:case 15110:case 15111:case 15114:case 15115:case 15116:case 15117:case 15120:case 15121:case 15124:ms();break;case-10:case 27929:Ll();break;case-11:case 10009:wl();break;case 69:Cl();break;case 283:yl();break;default:Fi()}nc.endNonterminal("PrimaryExpr",Wl)}function gl(){switch(Xl){case 187:Fl(248);break;case 220:Fl(246);break;case 281:Fl(284);break;case 83:case 122:Fl(254);break;case 97:case 249:Fl(96);break;case 120:case 206:case 262:Fl(146);break;case 135:case 197:case 255:Fl(238);break;case 6:case 71:case 73:case 74:case 75:case 76:case 78:case 80:case 81:case 82:case 84:case 85:case 86:case 87:case 89:case 90:case 91:case 92:case 94:case 95:case 98:case 99:case 102:case 103:case 104:case 105:case 106:case 107:case 109:case 110:case 111:case 112:case 113:case 114:case 119:case 123:case 124:case 126:case 127:case 129:case 130:case 132:case 133:case 134:case 136:case 137:case 138:case 139:case 142:case 143:case 148:case 150:case 152:case 153:case 155:case 156:case 157:case 161:case 162:case 163:case 164:case 165:case 166:case 168:case 170:case 173:case 174:case 175:case 177:case 179:case 181:case 183:case 184:case 185:case 189:case 195:case 198:case 202:case 203:case 204:case 205:case 207:case 210:case 216:case 217:case 222:case 223:case 224:case 225:case 226:case 228:case 229:case 232:case 233:case 234:case 239:case 240:case 241:case 242:case 245:case 253:case 254:case 256:case 257:case 258:case 260:case 263:case 266:case 267:case 268:case 269:case 272:case 273:case 276:Fl(94);break;default:Ul=Xl}if(Ul==3353||Ul==4377||Ul==4889||Ul==5401||Ul==5913||Ul==16153||Ul==16665||Ul==17177||Ul==18055||Ul==18117||Ul==18175||Ul==18201||Ul==18713||Ul==21273||Ul==22297||Ul==24345||Ul==24857||Ul==28441||Ul==28953||Ul==31001||Ul==35609||Ul==36633||Ul==37657||Ul==38169||Ul==38681||Ul==39193||Ul==40217||Ul==40729||Ul==41241||Ul==41753||Ul==42265||Ul==42777||Ul==43289||Ul==43801||Ul==44313||Ul==44825||Ul==45849||Ul==46361||Ul==46873||Ul==47385||Ul==48409||Ul==48921||Ul==49945||Ul==50457||Ul==50969||Ul==52505||Ul==53017||Ul==53529||Ul==54041||Ul==54553||Ul==55065||Ul==56089||Ul==56601||Ul==57113||Ul==57625||Ul==58137||Ul==58649||Ul==61209||Ul==61721||Ul==62233||Ul==62745||Ul==63257||Ul==63769||Ul==64281||Ul==64793||Ul==65305||Ul==66329||Ul==66841||Ul==67865||Ul==68377||Ul==68889||Ul==69401||Ul==69913||Ul==70425||Ul==70937||Ul==71449||Ul==72985||Ul==73497||Ul==75545||Ul==76057||Ul==77081||Ul==78105||Ul==78617||Ul==79129||Ul==79641||Ul==80153||Ul==80665||Ul==82713||Ul==83225||Ul==83737||Ul==84249||Ul==84761||Ul==85273||Ul==85785||Ul==86297||Ul==86809||Ul==87321||Ul==88857||Ul==89369||Ul==89881||Ul==90905||Ul==91929||Ul==92953||Ul==93977||Ul==94489||Ul==95001||Ul==96025||Ul==96537||Ul==97049||Ul==99609||Ul==100121||Ul==100633||Ul==101145||Ul==101657||Ul==103705||Ul==104217||Ul==104729||Ul==105241||Ul==105753||Ul==106265||Ul==107801||Ul==110873||Ul==111385||Ul==112921||Ul==113945||Ul==114457||Ul==114969||Ul==115481||Ul==115993||Ul==117017||Ul==117529||Ul==118041||Ul==118553||Ul==119065||Ul==119577||Ul==120089||Ul==122649||Ul==123161||Ul==123673||Ul==124185||Ul==125721||Ul==126745||Ul==127257||Ul==127769||Ul==129817||Ul==130329||Ul==130841||Ul==131353||Ul==131865||Ul==132377||Ul==132889||Ul==133401||Ul==134425||Ul==134937||Ul==136473||Ul==136985||Ul==137497||Ul==138009||Ul==139545||Ul==140057||Ul==141593||Ul==144153||Ul==145177||Ul==147225){Ul=sc(20,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{pi(),ic(20,t,-1),Ul=-14}catch(a){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Di(),ic(20,t,-5),Ul=-14}catch(f){try{zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),Al(),ic(20,t,-10),Ul=-14}catch(l){Ul=-11,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(20,t,-11)}}}}}switch(Ul){case-1:case 8:case 9:case 10:case 11:case 12935:case 12997:case 13055:case 13447:case 13509:case 13567:case 13959:case 14021:case 14079:case 19591:case 19653:case 19711:case 20103:case 20165:case 20223:case 21127:case 21189:case 21247:case 21639:case 21701:case 21759:case 22151:case 22213:case 22271:case 23175:case 23237:case 23295:case 24199:case 24261:case 24319:case 24711:case 24773:case 24831:case 25735:case 25797:case 25855:case 27783:case 27845:case 27903:case 28295:case 28357:case 28415:case 29831:case 29893:case 29951:case 30343:case 30405:case 30463:case 31367:case 31429:case 31487:case 31879:case 31941:case 31999:case 32391:case 32453:case 32511:case 32903:case 32965:case 33023:case 35463:case 35525:case 35583:case 35975:case 36037:case 36095:case 36487:case 36549:case 36607:case 39047:case 39109:case 39167:case 41095:case 41157:case 41215:case 41607:case 41669:case 41727:case 42119:case 42181:case 42239:case 43655:case 43717:case 43775:case 45191:case 45253:case 45311:case 45703:case 45765:case 45823:case 46215:case 46277:case 46335:case 46727:case 46789:case 46847:case 48775:case 48837:case 48895:case 51335:case 51397:case 51455:case 54407:case 54469:case 54527:case 56455:case 56517:case 56575:case 58503:case 58565:case 58623:case 61063:case 61125:case 61183:case 63111:case 63173:case 63231:case 63623:case 63685:case 63743:case 65159:case 65221:case 65279:case 66183:case 66245:case 66303:case 67719:case 67781:case 67839:case 71303:case 71365:case 71423:case 72839:case 72901:case 72959:case 75911:case 75973:case 76031:case 76935:case 76997:case 77055:case 77959:case 78021:case 78079:case 78471:case 78533:case 78591:case 83079:case 83141:case 83199:case 84103:case 84165:case 84223:case 84615:case 84677:case 84735:case 85127:case 85189:case 85247:case 89735:case 89797:case 89855:case 90759:case 90821:case 90879:case 92807:case 92869:case 92927:case 93831:case 93893:case 93951:case 94343:case 94405:case 94463:case 96903:case 96965:case 97023:case 103559:case 103621:case 103679:case 104583:case 104645:case 104703:case 105095:case 105157:case 105215:case 107143:case 107205:case 107263:case 114823:case 114885:case 114943:case 116871:case 116933:case 116991:case 119431:case 119493:case 119551:case 121479:case 121541:case 121599:case 123527:case 123589:case 123647:case 124039:case 124101:case 124159:case 129159:case 129221:case 129279:case 129671:case 129733:case 129791:case 130183:case 130245:case 130303:case 133255:case 133317:case 133375:case 139399:case 139461:case 139519:case 141447:case 141509:case 141567:case 142983:case 143045:case 143103:case 145543:case 145605:case 145663:case 146055:case 146117:case 146175:case 146567:case 146629:case 146687:case 147079:case 147141:case 147199:pi();break;case 31:Ei();break;case 35:Ni();break;case 32:ki();break;case-5:case 17926:case 17991:case 17993:case 17994:case 17995:case 17996:case 17998:case 18e3:case 18001:case 18002:case 18004:case 18005:case 18006:case 18007:case 18009:case 18010:case 18011:case 18012:case 18014:case 18015:case 18018:case 18019:case 18022:case 18023:case 18024:case 18025:case 18026:case 18027:case 18029:case 18030:case 18031:case 18032:case 18033:case 18034:case 18039:case 18040:case 18043:case 18044:case 18046:case 18047:case 18049:case 18050:case 18052:case 18053:case 18054:case 18056:case 18057:case 18058:case 18059:case 18062:case 18063:case 18068:case 18070:case 18072:case 18073:case 18075:case 18076:case 18077:case 18081:case 18082:case 18083:case 18084:case 18085:case 18086:case 18088:case 18090:case 18093:case 18094:case 18095:case 18097:case 18099:case 18101:case 18103:case 18104:case 18105:case 18107:case 18109:case 18115:case 18118:case 18122:case 18123:case 18124:case 18125:case 18126:case 18127:case 18130:case 18136:case 18137:case 18142:case 18143:case 18144:case 18145:case 18146:case 18148:case 18149:case 18152:case 18153:case 18154:case 18159:case 18160:case 18161:case 18162:case 18165:case 18173:case 18174:case 18176:case 18177:case 18178:case 18180:case 18182:case 18183:case 18186:case 18187:case 18188:case 18189:case 18192:case 18193:case 18196:Di();break;case 144078:Ai();break;case 144134:Mi();break;case 33:case 79:case 121:case 125:case 147:case 154:case 167:case 169:case 188:case 194:case 230:case 231:case 247:case 248:case 259:case 14854:case 14919:case 14921:case 14922:case 14923:case 14924:case 14926:case 14928:case 14929:case 14930:case 14931:case 14932:case 14933:case 14934:case 14935:case 14937:case 14938:case 14939:case 14940:case 14942:case 14943:case 14945:case 14946:case 14947:case 14950:case 14951:case 14952:case 14953:case 14954:case 14955:case 14957:case 14958:case 14959:case 14960:case 14961:case 14962:case 14967:case 14968:case 14970:case 14971:case 14972:case 14974:case 14975:case 14977:case 14978:case 14980:case 14981:case 14982:case 14983:case 14984:case 14985:case 14986:case 14987:case 14990:case 14991:case 14996:case 14998:case 15e3:case 15001:case 15003:case 15004:case 15005:case 15009:case 15010:case 15011:case 15012:case 15013:case 15014:case 15016:case 15018:case 15021:case 15022:case 15023:case 15025:case 15027:case 15029:case 15031:case 15032:case 15033:case 15035:case 15037:case 15043:case 15045:case 15046:case 15050:case 15051:case 15052:case 15053:case 15054:case 15055:case 15058:case 15064:case 15065:case 15068:case 15070:case 15071:case 15072:case 15073:case 15074:case 15076:case 15077:case 15080:case 15081:case 15082:case 15087:case 15088:case 15089:case 15090:case 15093:case 15097:case 15101:case 15102:case 15103:case 15104:case 15105:case 15106:case 15108:case 15110:case 15111:case 15114:case 15115:case 15116:case 15117:case 15120:case 15121:case 15124:gs();break;case-10:case 27929:Al();break;case-11:case 10009:El();break;case 69:kl();break;case 283:bl();break;case-14:break;default:Ii()}}function yl(){nc.startNonterminal("JSONSimpleObjectUnion",Wl),_l(283),jl(275),Xl!=286&&(Hl(),G()),_l(286),nc.endNonterminal("JSONSimpleObjectUnion",Wl)}function bl(){Dl(283),jl(275),Xl!=286&&Y(),Dl(286)}function wl(){nc.startNonterminal("ObjectConstructor",Wl),_l(281),jl(278),Xl!=287&&(Hl(),Sl()),_l(287),nc.endNonterminal("ObjectConstructor",Wl)}function El(){Dl(281),jl(278),Xl!=287&&xl(),Dl(287)}function Sl(){nc.startNonterminal("PairConstructorList",Wl),Tl();for(;;){if(Xl!=42)break;_l(42),jl(269),Hl(),Tl()}nc.endNonterminal("PairConstructorList",Wl)}function xl(){Nl();for(;;){if(Xl!=42)break;Dl(42),jl(269),Nl()}}function Tl(){nc.startNonterminal("PairConstructor",Wl);switch(Xl){case 78:Fl(280);break;case 161:Fl(283);break;case 177:Fl(179);break;case 187:Fl(253);break;case 220:Fl(249);break;case 223:Fl(181);break;case 266:Fl(192);break;case 83:case 122:Fl(258);break;case 97:case 249:Fl(147);break;case 111:case 222:Fl(263);break;case 139:case 142:Fl(188);break;case 104:case 130:case 240:Fl(166);break;case 135:case 197:case 255:Fl(210);break;case 120:case 206:case 256:case 262:Fl(168);break;case 121:case 125:case 167:case 188:case 194:case 230:case 231:Fl(95);break;case 71:case 73:case 74:case 75:case 76:case 80:case 81:case 82:case 84:case 85:case 86:case 87:case 89:case 90:case 91:case 92:case 94:case 95:case 98:case 99:case 102:case 103:case 105:case 106:case 107:case 109:case 110:case 112:case 113:case 114:case 119:case 123:case 124:case 126:case 127:case 129:case 132:case 133:case 134:case 136:case 137:case 138:case 143:case 147:case 148:case 150:case 152:case 153:case 154:case 155:case 156:case 157:case 162:case 163:case 164:case 165:case 166:case 168:case 170:case 173:case 174:case 175:case 179:case 181:case 183:case 184:case 185:case 189:case 195:case 198:case 202:case 203:case 204:case 205:case 207:case 210:case 216:case 217:case 224:case 225:case 226:case 228:case 229:case 232:case 233:case 234:case 239:case 241:case 242:case 245:case 248:case 253:case 254:case 257:case 258:case 259:case 260:case 263:case 267:case 268:case 269:case 272:case 273:case 276:Fl(142);break;default:Ul=Xl}if(Ul==25735||Ul==25797||Ul==25855){Ul=sc(21,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{zf(),Ul=-1}catch(a){Ul=-2}zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(21,Wl,Ul)}}switch(Ul){case-2:case 19:case 25671:case 25673:case 25674:case 25675:case 25676:case 25678:case 25680:case 25681:case 25682:case 25683:case 25684:case 25685:case 25686:case 25687:case 25689:case 25690:case 25691:case 25692:case 25694:case 25695:case 25697:case 25698:case 25699:case 25702:case 25703:case 25704:case 25705:case 25706:case 25707:case 25709:case 25710:case 25711:case 25712:case 25713:case 25714:case 25719:case 25720:case 25721:case 25722:case 25723:case 25724:case 25725:case 25726:case 25727:case 25729:case 25730:case 25732:case 25733:case 25734:case 25736:case 25737:case 25738:case 25739:case 25742:case 25743:case 25747:case 25748:case 25750:case 25752:case 25753:case 25754:case 25755:case 25756:case 25757:case 25761:case 25762:case 25763:case 25764:case 25765:case 25766:case 25767:case 25768:case 25770:case 25773:case 25774:case 25775:case 25777:case 25779:case 25781:case 25783:case 25784:case 25785:case 25787:case 25788:case 25789:case 25794:case 25795:case 25798:case 25802:case 25803:case 25804:case 25805:case 25806:case 25807:case 25810:case 25816:case 25817:case 25820:case 25822:case 25823:case 25824:case 25825:case 25826:case 25828:case 25829:case 25830:case 25831:case 25832:case 25833:case 25834:case 25839:case 25840:case 25841:case 25842:case 25845:case 25848:case 25849:case 25853:case 25854:case 25856:case 25857:case 25858:case 25859:case 25860:case 25862:case 25863:case 25866:case 25867:case 25868:case 25869:case 25872:case 25873:case 25876:Ka();break;default:Uf()}jl(26),_l(50),jl(268),Hl(),Uf(),nc.endNonterminal("PairConstructor",Wl)}function Nl(){switch(Xl){case 78:Fl(280);break;case 161:Fl(283);break;case 177:Fl(179);break;case 187:Fl(253);break;case 220:Fl(249);break;case 223:Fl(181);break;case 266:Fl(192);break;case 83:case 122:Fl(258);break;case 97:case 249:Fl(147);break;case 111:case 222:Fl(263);break;case 139:case 142:Fl(188);break;case 104:case 130:case 240:Fl(166);break;case 135:case 197:case 255:Fl(210);break;case 120:case 206:case 256:case 262:Fl(168);break;case 121:case 125:case 167:case 188:case 194:case 230:case 231:Fl(95);break;case 71:case 73:case 74:case 75:case 76:case 80:case 81:case 82:case 84:case 85:case 86:case 87:case 89:case 90:case 91:case 92:case 94:case 95:case 98:case 99:case 102:case 103:case 105:case 106:case 107:case 109:case 110:case 112:case 113:case 114:case 119:case 123:case 124:case 126:case 127:case 129:case 132:case 133:case 134:case 136:case 137:case 138:case 143:case 147:case 148:case 150:case 152:case 153:case 154:case 155:case 156:case 157:case 162:case 163:case 164:case 165:case 166:case 168:case 170:case 173:case 174:case 175:case 179:case 181:case 183:case 184:case 185:case 189:case 195:case 198:case 202:case 203:case 204:case 205:case 207:case 210:case 216:case 217:case 224:case 225:case 226:case 228:case 229:case 232:case 233:case 234:case 239:case 241:case 242:case 245:case 248:case 253:case 254:case 257:case 258:case 259:case 260:case 263:case 267:case 268:case 269:case 272:case 273:case 276:Fl(142);break;default:Ul=Xl}if(Ul==25735||Ul==25797||Ul==25855){Ul=sc(21,Wl);if(Ul==0){var e=zl,t=Wl,n=Xl,r=Vl,i=$l,s=Jl,o=Kl,u=Ql;try{zf(),ic(21,t,-1),Ul=-3}catch(a){Ul=-2,zl=e,Wl=t,Xl=n,Xl==0?fc=t:(Vl=r,$l=i,Jl=s,Jl==0?fc=i:(Kl=o,Ql=u,fc=u)),ic(21,t,-2)}}}switch(Ul){case-2:case 19:case 25671:case 25673:case 25674:case 25675:case 25676:case 25678:case 25680:case 25681:case 25682:case 25683:case 25684:case 25685:case 25686:case 25687:case 25689:case 25690:case 25691:case 25692:case 25694:case 25695:case 25697:case 25698:case 25699:case 25702:case 25703:case 25704:case 25705:case 25706:case 25707:case 25709:case 25710:case 25711:case 25712:case 25713:case 25714:case 25719:case 25720:case 25721:case 25722:case 25723:case 25724:case 25725:case 25726:case 25727:case 25729:case 25730:case 25732:case 25733:case 25734:case 25736:case 25737:case 25738:case 25739:case 25742:case 25743:case 25747:case 25748:case 25750:case 25752:case 25753:case 25754:case 25755:case 25756:case 25757:case 25761:case 25762:case 25763:case 25764:case 25765:case 25766:case 25767:case 25768:case 25770:case 25773:case 25774:case 25775:case 25777:case 25779:case 25781:case 25783:case 25784:case 25785:case 25787:case 25788:case 25789:case 25794:case 25795:case 25798:case 25802:case 25803:case 25804:case 25805:case 25806:case 25807:case 25810:case 25816:case 25817:case 25820:case 25822:case 25823:case 25824:case 25825:case 25826:case 25828:case 25829:case 25830:case 25831:case 25832:case 25833:case 25834:case 25839:case 25840:case 25841:case 25842:case 25845:case 25848:case 25849:case 25853:case 25854:case 25856:case 25857:case 25858:case 25859:case 25860:case 25862:case 25863:case 25866:case 25867:case 25868:case 25869:case 25872:case 25873:case 25876:Qa();break;case-3:break;default:zf()}jl(26),Dl(50),jl(268),zf()}function Cl(){nc.startNonterminal("ArrayConstructor",Wl),_l(69),jl(274),Xl!=70&&(Hl(),G()),_l(70),nc.endNonterminal("ArrayConstructor",Wl)}function kl(){Dl(69),jl(274),Xl!=70&&Y(),Dl(70)}function Ll(){nc.startNonterminal("BlockExpr",Wl),_l(281),jl(282),Hl(),rf(),_l(287),nc.endNonterminal("BlockExpr",Wl)}function Al(){Dl(281),jl(282),sf(),Dl(287)}function Ol(){nc.startNonterminal("FunctionDecl",Wl),_l(147),jl(247),Hl(),Xa(),jl(22),_l(35),jl(97),Xl==31&&(Hl(),U()),_l(38),jl(157),Xl==80&&(Hl(),Ml()),jl(120);switch(Xl){case 281:_l(281),jl(282),Hl(),rf(),_l(287);break;default:_l(134)}nc.endNonterminal("FunctionDecl",Wl)}function Ml(){nc.startNonterminal("ReturnType",Wl),_l(80),jl(255),Hl(),Cs(),nc.endNonterminal("ReturnType",Wl)}function _l(e){Xl==e?(Hl(),nc.terminal(i.TOKEN[Xl],Vl,$l>uc?uc:$l),zl=Vl,Wl=$l,Xl=Jl,Xl!=0&&(Vl=Kl,$l=Ql,Jl=0)):Rl(Vl,$l,0,Xl,e)}function Dl(e){Xl==e?(zl=Vl,Wl=$l,Xl=Jl,Xl!=0&&(Vl=Kl,$l=Ql,Jl=0)):Rl(Vl,$l,0,Xl,e)}function Pl(e){var t=zl,n=Wl,r=Xl,i=Vl,s=$l;Xl=e,Vl=ac,$l=fc,Jl=0,Wa(),zl=t,Wl=n,Xl=r,Xl!=0&&(Vl=i,$l=s)}function Hl(){Wl!=Vl&&(zl=Wl,Wl=Vl,nc.whitespace(zl,Wl))}function Bl(e){var t;for(;;){t=lc(e);if(t!=22){if(t!=37)break;Pl(t)}}return t}function jl(e){Xl==0&&(Xl=Bl(e),Vl=ac,$l=fc)}function Fl(e){Jl==0&&(Jl=Bl(e),Kl=ac,Ql=fc),Ul=Jl<<9|Xl}function Il(e){Xl==0&&(Xl=lc(e),Vl=ac,$l=fc)}function ql(e){Jl==0&&(Jl=lc(e),Kl=ac,Ql=fc),Ul=Jl<<9|Xl}function Rl(e,t,r,i,s){throw t>Yl&&(Gl=e,Yl=t,Zl=r,ec=i,tc=s),new n.ParseException(Gl,Yl,Zl,ec,tc)}function ic(e,t,n){rc[(t<<5)+e]=n}function sc(e,t){var n=rc[(t<<5)+e];return typeof n!="undefined"?n:0}function lc(e){var t=!1;ac=fc;var n=fc,r=i.INITIAL[e],s=0;for(var o=r&8191;o!=0;){var u,a=n<uc?oc.charCodeAt(n):0;++n;if(a<128)u=i.MAP0[a];else if(a<55296){var f=a>>4;u=i.MAP1[(a&15)+i.MAP1[(f&31)+i.MAP1[f>>5]]]}else{if(a<56320){var f=n<uc?oc.charCodeAt(n):0;f>=56320&&f<57344&&(++n,a=((a&1023)<<10)+(f&1023)+65536,t=!0)}var l=0,c=5;for(var h=3;;h=c+l>>1){if(i.MAP2[h]>a)c=h-1;else{if(!(i.MAP2[6+h]<a)){u=i.MAP2[12+h];break}l=h+1}if(l>c){u=0;break}}}s=o;var p=(u<<13)+o-1;o=i.TRANSITION[(p&31)+i.TRANSITION[p>>5]],o>8191&&(r=o,o&=8191,fc=n)}r>>=13;if(r==0){fc=n-1;var f=fc<uc?oc.charCodeAt(fc):0;return f>=56320&&f<57344&&--fc,Rl(ac,fc,s,-1,-1)}if(t)for(var d=r>>9;d>0;--d){--fc;var f=fc<uc?oc.charCodeAt(fc):0;f>=56320&&f<57344&&--fc}else fc-=r>>9;return(r&511)-1}r(e,t);var n=this;this.ParseException=function(e,t,n,r,i){var s=e,o=t,u=n,a=r,f=i;this.getBegin=function(){return s},this.getEnd=function(){return o},this.getState=function(){return u},this.getExpected=function(){return f},this.getOffending=function(){return a},this.getMessage=function(){return a<0?"lexical analysis failed":"syntax error"}},this.getInput=function(){return oc},this.getOffendingToken=function(e){var t=e.getOffending();return t>=0?i.TOKEN[t]:null},this.getExpectedTokenSet=function(e){var t;return e.getExpected()<0?t=i.getTokenSet(-e.getState()):t=[i.TOKEN[e.getExpected()]],t},this.getErrorMessage=function(e){var t=this.getExpectedTokenSet(e),n=this.getOffendingToken(e),r=oc.substring(0,e.getBegin()),i=r.split("\n"),s=i.length,o=i[s-1].length+1,u=e.getEnd()-e.getBegin();return e.getMessage()+(n==null?"":", found "+n)+"\nwhile expecting "+(t.length==1?t[0]:"["+t.join(", ")+"]")+"\n"+(u==0||n!=null?"":"after successfully scanning "+u+" characters beginning ")+"at line "+s+", column "+o+":\n..."+oc.substring(e.getBegin(),Math.min(oc.length,e.getBegin()+64))+"..."},this.parse_XQuery=function(){nc.startNonterminal("XQuery",Wl),jl(279),Hl(),o(),_l(25),nc.endNonterminal("XQuery",Wl)};var Ul,zl,Wl,Xl,Vl,$l,Jl,Kl,Ql,Gl,Yl,Zl,ec,tc,nc,rc,oc,uc,ac,fc};r.getTokenSet=function(e){var t=[],n=e<0?-e:INITIAL[e]&8191;for(var i=0;i<289;i+=32){var s=i,o=(i>>5)*4323+n-1,u=o>>2,a=u>>2,f=r.EXPECTED[(o&3)+r.EXPECTED[(u&3)+r.EXPECTED[(a&7)+r.EXPECTED[a>>3]]]];for(;f!=0;f>>>=1,++s)(f&1)!=0&&t.push(r.TOKEN[s])}return t},r.MAP0=[71,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,17,17,17,17,17,17,17,17,17,18,19,20,21,22,23,24,25,26,27,28,29,26,30,30,30,30,30,31,32,33,30,30,34,30,30,35,30,30,30,36,30,30,37,38,39,40,30,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,40,40],r.MAP1=[108,124,214,214,214,214,214,214,214,214,214,214,214,214,214,214,156,181,181,181,181,181,214,215,213,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,247,261,277,293,309,355,371,387,423,423,423,415,339,331,339,331,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,440,440,440,440,440,440,440,324,339,339,339,339,339,339,339,339,401,423,423,424,422,423,423,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,338,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,423,71,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,17,17,17,17,17,17,17,17,17,18,19,20,21,22,23,24,25,26,27,28,29,26,30,30,30,30,30,31,32,33,30,30,30,30,30,30,30,30,30,30,30,30,30,30,40,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,34,30,30,35,30,30,30,36,30,30,37,38,39,40,30,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,40,40,40,40,40,40,40,40,40,40,40,40,30,30,40,40,40,40,40,40,40,70,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70],r.MAP2=[57344,63744,64976,65008,65536,983040,63743,64975,65007,65533,983039,1114111,40,30,40,30,30,40],r.INITIAL=[1,24578,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291],r.TRANSITION=[61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,18432,18517,18522,18517,18517,18484,18512,18452,18517,18554,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,61967,73090,22372,22399,61674,22448,61967,59516,61967,41832,61967,61967,55527,19522,30374,20913,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22538,61967,70056,61967,34633,62349,22589,41847,62466,62378,61967,59516,61967,22626,61967,61967,55527,19522,55520,41710,22665,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22724,61967,35451,61966,61947,33649,33678,20228,20251,22777,61967,20166,61967,22829,61967,61967,55527,19522,55520,38980,22868,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,21069,18745,27106,18633,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22927,61967,31390,22996,58037,23031,22589,71908,23095,23127,61967,59516,61967,74619,61967,61967,55527,19522,33749,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,23195,61967,73090,23262,33056,23232,23311,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,61967,63256,23363,61967,61967,23400,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,23468,18928,23545,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,23577,61967,72464,61967,57684,23628,22589,72719,23725,23657,61967,59516,61967,23757,61967,61967,55527,19522,55520,19460,23796,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,23855,23948,23953,23941,24006,23911,23985,23879,24038,24068,61967,26764,61967,74619,61967,61967,55527,19522,55520,19508,18606,24136,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,24234,61967,31390,24372,69698,73090,24290,24311,24343,24413,61967,22488,61967,74619,61967,61967,55527,19522,55520,19508,18606,24481,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,24541,61967,31390,61967,61967,67560,24598,24727,24629,24659,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,24786,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,61967,20332,24818,47893,47878,24849,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,72704,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,24917,61967,31390,22166,69121,24929,24961,24980,63830,25029,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,25081,61967,31390,61967,61967,73090,25120,40456,40441,25151,61967,59516,61967,74619,61967,61967,25386,70359,33542,44063,60878,74169,48358,73876,61967,61967,25392,25221,46058,56008,34317,59395,45145,35889,25258,33586,67359,61967,61967,74289,32691,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,34227,61967,61967,39423,61967,38058,59141,59141,42868,32848,52984,42485,53795,45145,38847,36411,45179,49739,61967,61967,31653,31517,54964,59141,46635,69258,52984,19712,25297,53636,36994,45179,49738,61967,35077,73614,59141,39309,52984,49561,45145,34410,45179,30090,25332,29726,25380,25434,58426,41951,25472,71032,68673,61967,25509,25555,25602,33496,25669,25747,56815,25790,25835,25867,25928,42600,26414,25960,26021,26093,26145,25698,41957,45600,50560,49862,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,61967,73577,26289,22949,26342,26374,61967,59516,61967,57530,61967,61967,55527,19522,60302,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,26446,61967,45837,61967,61967,73090,26514,26567,72558,26616,61967,59516,61967,43846,55593,61967,55527,19522,55520,41710,22665,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,26668,61967,31390,61967,61967,26680,22589,61967,26712,26744,61967,59516,61967,26814,61967,61967,25386,70359,27859,44063,61967,74169,61967,44524,61967,61967,25392,59141,46058,52984,34317,45145,45145,36983,45179,33586,26853,61967,61967,53249,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,45058,26893,61967,61967,23063,61967,25397,59141,59141,26933,52984,52984,42016,45145,45145,47967,45179,45179,58891,61967,61967,61967,31517,59141,59141,26972,52984,52984,27017,45145,53636,45179,45179,64222,61967,61967,73614,59141,73537,52984,39346,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,27055,61967,74626,39880,35594,36017,36045,36071,27139,27245,61967,29891,61967,74619,61967,61967,55527,29290,28935,28860,18606,27299,61967,70169,30458,18726,18778,19038,27395,27918,27454,29597,27486,59308,29378,28584,19146,19231,58583,74082,19266,19356,74753,19443,20085,28657,28641,27422,28779,28920,29492,29536,29518,28283,36556,19613,19681,19750,24509,29432,20022,19387,27518,29659,27577,20114,28406,28720,27638,28527,27732,27795,21982,20146,20198,19175,20445,20283,27891,27950,27982,59281,28751,28253,27763,28014,28075,20555,20624,28313,28345,28129,28191,28223,28377,28438,28497,28559,18808,20981,21038,18850,28616,27606,28689,29351,27669,18694,21298,21330,28811,28892,28967,28999,29031,21595,29063,29121,29095,29153,29185,27545,29217,29276,28841,28043,29322,29410,29464,28465,29568,29629,29691,28159,74475,29723,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,29758,61967,31390,19098,24381,27267,29803,29822,29771,29871,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,33022,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,29923,29951,19613,19681,29983,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,30024,21982,20146,20198,19175,20445,20283,30122,30300,20403,30275,30307,20410,20442,20477,20310,20555,20624,28313,28345,30181,20725,30247,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,61967,61967,30339,30357,30406,30438,61967,59516,61967,74619,31473,61967,55527,19522,55520,30909,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,30490,61967,31390,61967,61967,73090,30561,30579,71270,30628,61967,59516,61967,74619,45464,61967,55527,19522,55520,21356,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,30683,61967,57342,61967,61967,73090,30735,30753,72498,30802,61967,59516,61967,74619,34645,61967,55527,19522,55520,19199,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,30855,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,30961,61967,31390,70791,61967,28097,22589,31007,32778,31050,61967,59516,61967,45974,61967,61967,55527,19522,36762,32200,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,61967,73090,22589,61967,21436,31117,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,31305,61967,61967,23060,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,50599,31344,61967,61967,23063,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,58891,61967,61967,31384,31517,59141,59141,34770,52984,52984,31422,45145,53636,45179,45179,64222,61967,61967,73614,59141,73537,52984,39346,45145,45146,45179,45179,56820,49285,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,31305,61967,61967,23060,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,50599,31344,61967,61967,23063,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,58891,61967,61967,61967,31517,59141,59141,34770,52984,52984,31422,45145,53636,45179,45179,64222,61967,61967,73614,59141,73537,52984,39346,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,31305,61967,61967,27084,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,50599,31344,61967,61967,23063,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,58891,61967,61967,61967,31517,59141,59141,34770,52984,52984,31422,45145,53636,45179,45179,64222,61967,61967,73614,59141,73537,52984,39346,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,31305,61967,61967,23060,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,50599,31344,61967,61967,31460,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,58891,61967,61967,61967,31517,59141,59141,34770,52984,52984,31422,45145,53636,45179,45179,64222,61967,61967,73614,59141,73537,52984,39346,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,44659,61967,61967,25386,70359,33542,44780,61967,74169,61967,44652,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,31305,61967,61967,23060,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,50599,31344,61967,61967,23063,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,58891,61967,61967,61967,31517,59141,59141,34770,52984,52984,31422,45145,53636,45179,45179,64222,61967,61967,73614,59141,73537,52984,39346,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,71110,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,61383,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,31505,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,31550,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,60964,31586,31617,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,26782,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31685,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31722,61967,31390,61967,61967,73090,31797,31748,31850,31879,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,72035,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,31966,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,61967,73090,22589,61967,61967,31998,61967,59516,61967,74619,61967,61967,55527,19522,55520,41710,22665,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,32087,31390,61967,61967,73090,32050,32071,20592,32120,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,32172,21655,21713,21687,32267,21777,19818,32299,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,61967,73090,22589,61967,61967,31117,61967,59516,61967,74619,61967,61967,55527,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,32359,45328,32394,57696,65386,32464,32495,32603,32525,62034,70632,30651,32635,32733,19295,32810,32880,32912,32991,33054,74169,33088,33130,33163,45989,25392,59141,33241,52984,56024,45145,31428,36983,45179,70338,33310,32220,58099,27328,61967,33367,33433,25402,66092,33481,37911,33910,33528,47097,61157,33574,61753,33618,33731,31765,68742,23063,34945,33781,41368,33852,38560,52078,55949,33942,34017,27845,43023,34098,50430,34177,62248,57537,24258,43351,68443,56707,34259,34314,58276,34349,45145,34442,34495,72106,34542,34611,34677,34744,34815,73537,31252,34847,37261,34977,51083,35015,35053,31690,31518,35109,47283,58827,70275,61805,56796,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,52125,35177,35243,41332,35298,35365,33401,59626,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,35445,45328,61967,61967,73090,35483,35510,35542,35574,61967,59516,61967,61967,61967,61967,52163,48269,57216,35626,43781,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,31305,61967,62286,23060,35725,73613,59141,59141,35797,52984,52984,35865,45145,45145,35932,45179,45179,35986,31344,61967,61967,23063,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,58891,61967,36103,63318,36136,36230,59141,36264,52984,65801,36356,45145,56526,36406,45179,43758,61967,61967,73614,59141,73537,52984,39346,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,51661,67812,57941,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,32555,45328,23279,73166,19759,36443,36474,36505,36536,61967,36588,43861,44539,61967,19114,23147,36656,71728,67332,56205,74169,36716,22176,36794,36860,61640,59141,37718,36917,44877,36960,45145,37285,37026,33586,37060,26257,59568,24165,65366,73613,59968,37108,65487,55372,37167,69268,48100,37236,42027,37317,51793,50599,31344,60141,48701,23063,61967,25397,36232,55772,35138,52984,37349,35822,45145,61129,47967,45179,37426,58891,37499,31352,26821,31517,59141,52867,34770,52984,65140,31422,45145,37532,45179,54511,64222,61967,37577,58139,70018,73537,39632,39346,19718,45146,72426,45179,37613,60044,26466,37665,72228,37750,37787,43916,37853,61967,26636,59141,37904,47945,63759,45179,37943,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,46610,37980,38036,33401,34463,61516,69e3,26222,38090,38162,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,20574,45328,40138,52640,73090,38225,38256,38355,38286,61967,59516,61967,61967,43783,43782,21897,47178,42577,38387,54918,38446,38323,74131,48917,73999,38531,47646,35413,41239,38592,38624,38676,54441,43934,47786,31305,33098,65307,23060,61967,32432,59141,59141,38728,52984,52984,38807,45145,45145,38879,45179,45179,38933,39012,37500,60946,23063,26901,68795,39058,45875,68127,39093,53596,39131,70917,45145,39189,51783,45179,39260,61967,61967,20661,34712,59141,55880,62878,52984,39341,39378,25477,34983,45179,73008,64222,55507,39422,66949,46044,39455,58464,39514,67447,49193,71504,47769,46339,61967,31518,59141,50203,41951,45145,50986,45368,35693,32088,59141,39625,59730,36324,45179,39664,39725,25715,52935,49718,39701,25709,53833,42807,67039,39770,59825,42895,63165,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,36624,45328,74527,70800,39828,39925,39956,40038,39986,40262,40070,40102,40232,40170,40202,40294,40326,40358,40390,24566,30703,43994,40488,40534,52510,26061,68036,51395,40569,51336,64180,42132,40638,40717,40782,40835,40894,40926,40999,54209,41068,41100,62097,41179,41211,56932,41271,41400,48763,41502,41574,41631,41663,41742,52524,31899,41801,34206,41879,70010,41911,41990,42059,68924,42102,66773,71709,41302,42222,71091,42269,48816,36745,65446,54064,55792,42347,55288,42379,42460,42517,42632,50968,42664,51055,42716,31312,50294,26394,59852,33883,68540,64439,48450,44990,55438,42792,39669,67971,68098,42839,42962,42994,43118,43206,43294,43383,43461,43514,43571,43622,38775,43727,37872,26048,59986,48995,50587,43815,45229,43893,43966,59711,44044,44095,71632,44151,44223,44306,61516,44366,44439,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,51178,45328,44497,25348,62514,44571,44602,44698,44632,64126,59516,61967,61967,43339,43324,26535,44730,34877,44812,42739,74169,42756,61967,21098,23677,57958,59141,55717,44874,44877,73292,45145,60675,45179,33586,31305,61967,61967,23060,61967,44909,59141,59141,44946,52984,52984,45022,45145,45145,45090,45179,45180,50599,31344,61967,61967,23063,64117,25397,72876,59141,35138,72356,52984,35822,45145,45144,47967,45179,45178,58891,61967,61967,61967,45212,59141,61245,34770,52984,35200,31422,45145,45277,45179,59465,64222,61967,61967,73614,59141,73537,52984,39346,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,45322,32088,33808,52287,37755,53634,45360,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,45400,45496,45554,45632,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,22633,61967,73090,45695,45716,45748,45779,61967,59516,61967,58581,61967,61967,25386,70359,33542,35954,59106,74169,61967,61967,45831,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,36815,55188,59141,59141,71414,52984,52984,55959,45145,45145,42027,45179,45179,49730,61967,31934,74576,68206,61967,45869,63370,59141,35138,36928,52984,35822,63942,45145,47967,53519,45179,34924,61967,63249,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,66882,45907,59141,47029,52984,49058,45145,27213,45179,48216,45943,42315,46021,71814,46090,46163,60837,46218,46315,19972,21122,46371,46469,46528,46580,65851,56815,46680,46730,56489,46791,46846,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,46927,46902,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,46759,61967,46959,61967,23764,29839,23331,47009,47061,47129,72801,61967,50682,51133,63558,61967,61967,25392,59141,47210,52984,26113,45145,65189,36983,45179,47262,67359,61967,61967,61967,54284,65706,59141,59141,49630,52984,52984,35211,45145,45145,55054,45179,45179,37467,24679,61967,61967,61967,23200,68018,59141,59141,36165,52984,52984,36289,45145,45145,35333,45179,45179,49739,61967,73744,61967,31517,59141,53759,46635,52984,26985,19712,45145,35319,45179,71373,49738,61967,48906,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,70672,40537,59141,50201,41956,53634,45179,65296,50129,68862,67432,45046,47315,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,68217,45328,74693,74678,30929,47371,47403,47485,47433,61967,33699,61967,22340,47517,43262,47623,47678,47738,64840,61967,32571,70485,47818,61967,47854,39738,49620,47925,47999,41147,38696,48070,48148,48204,48248,40417,49398,57662,48301,48335,59688,37703,52883,48407,62897,33278,48482,63058,66341,60365,69403,41599,48554,61967,61967,48631,48687,61967,63187,52035,68814,46400,64057,58479,48733,72392,46437,47706,63796,25758,48795,64755,48848,48880,48949,63657,37135,49042,34282,49090,30521,49165,49244,55096,49317,49371,49430,40121,49513,49593,49662,49771,69630,49831,38004,49942,43174,49974,44666,50017,50049,64416,70861,70987,41427,60737,24104,27348,59141,50201,41956,53634,45179,69465,46870,44119,60815,44761,50105,50184,53833,42237,47591,50235,50335,41957,55454,33401,34463,50378,50476,26222,26197,50529,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,73792,45328,61967,61967,73090,22589,44012,50631,50662,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,72319,67753,52984,50714,45145,48116,36983,59064,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,31554,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,19983,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,36607,61967,61967,61967,61967,73483,59141,59141,41129,52984,52984,38753,45145,45145,56129,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,19234,45328,50303,66566,50746,50775,50796,50828,50859,62276,59516,20856,58581,20933,23823,26310,50911,51025,68602,51165,30975,41036,51210,60514,32701,51265,51368,51427,51481,51527,51559,59764,43148,51632,51693,60460,61967,74328,24433,61967,73613,44334,46283,68455,49799,46131,36198,25896,66788,62981,51755,43695,65598,61967,51825,43086,48599,61967,25397,25440,69836,35138,63904,37394,35822,45145,51871,47967,45179,51903,49739,34571,31189,61967,31517,41354,59141,46635,51935,52984,61099,45145,53636,42190,45179,49738,51972,34579,35749,52025,63478,52067,52202,27199,27023,52110,71340,37948,61967,52157,46270,40803,41951,37808,44274,45368,32362,32088,59141,52195,49116,65552,35021,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,52234,65968,57194,52266,52364,52339,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61968,45328,67360,52396,38499,52429,52460,52556,52490,62403,59516,48375,61967,62398,24754,37633,66396,52588,52672,61967,52766,25088,36885,61967,30596,52827,53355,52915,52982,53018,65538,46548,53050,53187,53120,53219,53295,61967,52734,61967,73613,35392,53344,65487,37373,53387,69268,39157,42921,42027,53429,53512,49730,40967,31637,22594,25049,61967,46698,59141,53551,70734,53594,46117,37193,53628,66323,47967,53668,41452,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,53706,61967,31518,53753,67413,41951,53791,69776,45368,61967,32088,59141,50201,53827,38831,58320,56815,39725,25715,41958,47966,34066,50346,65910,45112,49886,53865,25698,41957,55454,33401,34463,45245,53921,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,53974,22305,54043,54096,54128,54159,54241,54189,72930,39856,54273,21006,22797,54316,54348,54410,54543,54605,62497,61005,50879,47545,56426,37076,54683,54738,67753,54770,55310,42428,35833,46186,68665,54819,64899,54881,61967,72837,61967,67016,54950,58717,65487,54996,25625,69268,55042,71226,42027,55086,55128,49730,61967,61967,61463,26861,55168,55220,59141,55262,58644,52984,55342,48432,45145,21256,55421,45179,59455,55486,55559,55625,38475,55680,55749,55857,43539,55925,55991,27700,56056,56115,54472,56161,68353,73974,52795,49481,37685,56237,59357,56309,62684,56366,53088,54573,56398,61967,74387,50152,56458,49693,38644,56083,56558,56627,70421,56666,59905,56739,44254,56771,49271,56852,56902,54787,45290,46814,26482,56964,61612,67127,57019,69570,58223,39570,33401,34463,61516,57051,57083,26197,57163,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,57248,63325,57336,73090,57374,57405,57467,57435,57499,19324,57569,20778,57635,57728,57805,57878,57910,57990,73755,58069,23693,22104,54004,32235,25392,58171,58255,60004,49910,61322,73267,58308,58352,58405,38414,61967,58511,58571,66547,58615,58693,58762,40685,58804,58923,43590,58964,59018,68269,39228,59058,39796,59096,60104,61967,61967,24202,25397,66700,59140,35138,33261,59174,35822,48522,47089,47967,73355,59210,49739,61967,59250,61967,31517,59141,59141,59340,52984,51940,59389,45145,40606,45179,45179,52618,42295,61967,51839,55230,63869,65149,72175,30529,45146,59427,45179,59497,61967,45911,63422,34145,44407,34395,56987,45368,59566,32088,59141,50201,41956,53634,45179,56577,47339,73498,67679,58870,53889,70446,59600,59658,39593,59796,25698,41957,55454,33401,34463,61516,59884,64496,26197,59937,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,32327,61967,60036,60076,60173,60204,60235,60267,22836,59516,61967,34700,40956,61967,27363,60334,58986,60433,56595,74169,22999,49460,32413,61967,43482,50073,51289,60546,51449,60601,60652,60707,60387,60788,60869,60910,31137,60996,61967,73613,59141,55809,65487,52984,67662,69268,45145,66019,42027,45179,39215,49730,61037,61967,20949,24449,31919,25397,61231,59141,32841,64341,52984,40595,58849,45145,47967,34903,45179,49739,55579,61967,68732,31517,59141,61277,67644,70519,52984,61316,21266,53636,45179,37454,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,60130,65237,59141,50203,41951,45145,50986,55136,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,67868,61354,31273,61435,61505,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,59516,61967,61548,42760,41769,45799,69947,61582,38901,61672,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,53721,61967,61967,61967,73613,59141,59141,73207,52984,52984,53397,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,61706,46635,35145,52984,19712,71458,53636,45179,61745,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,64983,50497,41956,61785,54498,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,22692,61967,33191,33209,61837,61864,61896,61927,22745,62820,19946,40862,64737,62e3,62066,62154,62186,62218,43781,54011,62318,62435,54906,73915,62546,62583,62645,58446,39482,50942,39390,45584,62716,62748,67359,72280,62801,40502,62780,47568,62852,59141,62943,63013,52984,63103,70927,25300,63135,35900,37028,63219,61967,66641,32664,61967,63288,63357,63402,63469,49543,51313,63510,63038,69345,51585,64202,49339,32943,49739,63554,32018,63590,39286,63644,63689,62122,63723,52984,27170,73307,53636,43679,63791,53480,25171,63828,66889,63862,33820,63901,58932,63936,59026,63974,25265,56820,64014,57603,59141,64050,48038,71305,53178,33985,73658,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,48172,71172,51723,64089,33390,47959,46247,64158,64254,33401,34463,61516,64313,64390,64471,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,63612,64557,64528,64589,64618,64650,64681,64713,60478,32760,33131,61967,43406,44842,43429,64787,39544,64872,64944,33335,48584,61967,53263,54635,65031,52850,25570,65112,44877,34377,65181,67214,41470,33586,58017,24695,65221,45449,24088,73613,69860,59141,58730,57131,52984,55010,67270,45145,49010,65269,45179,40750,61967,65339,24869,65418,43075,65478,25226,67619,41941,52986,52307,62670,45145,65519,65584,45179,65630,65679,52722,19637,20650,68e3,59141,65749,46635,73129,65795,19712,66033,53636,45179,65833,49738,73050,69509,73614,64999,65883,68939,46496,63071,42154,69414,53075,56820,22506,57757,59141,50203,41951,45145,50986,59218,60287,67507,63691,50201,42409,51600,50993,56188,21836,65763,58661,49212,51108,57773,65942,50266,33390,47959,40667,66e3,66065,66124,66189,66277,66373,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,21376,61967,23495,23513,66428,66459,66490,66522,38306,66614,40006,22557,30149,35656,66673,66742,66820,66852,66921,22075,66991,51233,67071,57278,57304,54706,67159,68149,54849,67191,67246,34043,67302,67392,67479,74237,67539,61967,58539,67592,67711,56694,66220,67785,56265,71202,56340,38119,50408,67844,67900,67941,30770,55648,68068,68181,59534,56870,67739,33449,62613,48020,57846,66245,68249,42930,68301,68333,63982,68385,69687,51993,61967,68417,68487,71788,74412,47230,68519,30055,42548,43651,68572,68634,42684,68705,54651,68774,68846,58772,68894,73433,66303,68971,53459,69053,56820,69153,64912,38193,69234,69300,69326,69377,69446,69497,67100,45663,53942,53151,71012,69541,43050,29244,69602,60569,72779,69662,25709,53833,34510,33390,47959,25698,64358,65647,69730,69808,69892,69924,26222,26197,69979,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,53312,61967,70050,73090,70088,70119,70215,70149,61967,22468,60496,41027,24192,61967,66959,70247,70307,70391,70478,74169,61967,31818,60928,48303,35765,59141,64281,70517,25637,48506,45145,70551,45179,70576,69110,70608,39026,49985,70664,61403,55893,70704,63437,51495,70832,70893,52950,70959,64818,40734,71064,71142,61473,66582,61967,61967,71268,62551,59141,59141,54378,52984,52984,63748,71302,45145,47967,71337,45179,58373,19649,61967,61967,32140,59141,59141,48974,52984,52984,27826,45145,53636,71372,45179,26165,61967,58119,56634,71405,61713,44397,34783,71446,38130,71490,41542,71536,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,71601,55389,37545,35266,25709,53833,34510,33390,47959,25698,41957,32959,71687,71760,61516,69e3,71871,71846,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,31085,71952,71903,22895,71940,46977,71984,72015,61967,59516,61967,61967,61967,61967,65717,44465,72067,44780,36104,30823,61967,61967,61967,72138,25803,59142,67753,72171,65080,59747,37204,71655,45179,72207,67359,61967,61967,72276,61550,73613,59141,72312,65487,52984,72351,69268,45145,72388,42027,45179,72424,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,52397,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,72458,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,60756,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,22964,61967,72496,72530,72590,72621,72652,72684,61967,59516,61967,61967,61967,61967,25386,72751,60620,69083,61967,74169,61967,61967,31070,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,72833,61967,72869,59141,59141,44181,52984,52984,62968,45145,45145,30076,45179,45179,49739,23368,61967,61967,31517,73394,39061,46635,72244,42070,19712,36314,49133,53674,45179,72908,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31685,61967,45328,61967,61967,73090,22589,25523,31221,45429,61967,18574,70183,61967,47822,26584,47453,45522,72962,44780,61967,23596,23420,73040,61967,61967,25392,23163,58202,26940,62911,45145,36684,36983,50444,47157,73082,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,35683,61967,25397,55825,59141,73122,46648,52984,46426,71236,45145,47967,67909,45179,49739,73161,61967,61967,31517,73198,59141,21922,52984,52984,21232,45145,53636,61185,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,22589,25523,31221,70763,61967,59516,37581,61967,61967,61967,64966,73239,36374,43234,59108,74169,61967,61967,61967,64018,25392,59141,65058,52984,63522,45145,45145,73339,45179,34124,52699,61967,61967,61967,31152,73613,55703,53562,65487,36186,56277,69268,66146,37821,42027,72097,60401,49730,19527,61967,61967,61967,61967,25397,73387,59141,57834,73426,52984,44971,56515,45145,42174,72992,45179,49739,61967,61967,61967,73465,59141,73530,46635,39099,52984,19712,66157,53636,45179,41533,49738,61967,57590,73614,59141,61284,52984,59178,45145,45146,45179,45179,73569,72139,44914,59141,57109,44191,45145,33969,45368,61967,73609,66710,69021,41956,69756,61199,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,31184,61967,45328,61967,61967,73090,73646,25523,31221,45429,61967,59516,61967,61967,61967,61967,25386,70359,33542,44780,61967,74169,61967,61967,61967,61967,25392,59141,67753,52984,44877,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31018,73719,69179,73690,73787,69202,73824,73856,61967,59516,61967,73908,61967,61967,55527,21623,36828,19508,18606,18665,61967,70169,30458,18726,18778,19038,73947,18928,19004,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,71562,71569,74031,74114,24997,74062,61967,59516,61967,74619,61967,74163,38964,19522,24885,19508,18606,18665,61967,70169,30458,18726,18778,19038,18896,18928,18960,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,29992,61967,61967,21447,74201,74220,22416,74269,61967,59516,61967,74321,23436,61967,41694,19522,55520,19508,18606,18665,61967,70169,30458,18726,18778,19038,74360,18928,74444,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,21595,21655,21713,21687,21745,21777,19818,21809,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,22337,61967,31390,61967,61967,73090,22589,61967,61967,74507,61967,59516,61967,61967,61967,61967,25386,70359,33542,44063,61967,74169,61967,61967,61967,61967,25392,59141,46058,52984,34317,45145,45145,36983,45179,33586,67359,61967,61967,61967,61967,73613,59141,59141,65487,52984,52984,69268,45145,45145,42027,45179,45179,49730,61967,61967,61967,61967,61967,25397,59141,59141,35138,52984,52984,35822,45145,45145,47967,45179,45179,49739,61967,61967,61967,31517,59141,59141,46635,52984,52984,19712,45145,53636,45179,45179,49738,61967,61967,73614,59141,61284,52984,59178,45145,45146,45179,45179,56820,61967,31518,59141,50203,41951,45145,50986,45368,61967,32088,59141,50201,41956,53634,45179,56815,39725,25715,41958,47966,35266,25709,53833,34510,33390,47959,25698,41957,55454,33401,34463,61516,69e3,26222,26197,25989,26254,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,62021,61967,25189,74559,39893,74608,61967,61967,61967,74619,61967,61967,55527,19522,55520,19508,18606,74658,61967,70169,30458,18726,18778,19038,73947,18928,19004,18916,18992,48655,19036,19070,19146,19231,58583,74082,19266,19356,74753,19443,19917,18745,27106,74847,18746,27107,30883,74757,19492,19559,36556,19613,19681,19750,24509,29432,20022,19387,19791,30215,19854,61068,30211,19850,19886,20015,20054,19411,21982,20146,20198,19175,20445,20283,20364,30300,20403,20371,30307,20410,20442,20477,20310,20555,20624,28313,28345,20693,20725,20757,20722,20810,28340,20888,19581,20981,21038,18850,21154,21201,21169,18833,18864,18694,21298,21330,21509,21408,21531,21479,21563,74725,21655,21713,21687,74789,21777,19818,74821,20837,55524,20506,21868,20523,21954,22014,22046,22136,22208,22240,22272,22302,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,61967,1,24578,3,0,0,0,0,0,0,0,180525,180525,180525,180525,0,188718,188718,188718,180525,180525,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,0,188718,180525,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,139264,147456,188718,188718,188718,188718,131072,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,188718,368,188718,180525,188718,188718,188718,188718,188718,1,24578,3,0,0,4366336,0,0,0,180525,188718,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,368,0,0,0,0,705,0,0,0,0,0,0,0,0,0,0,0,0,4857856,4874240,0,0,4923392,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5480448,0,0,0,0,0,0,0,0,0,0,6299648,0,0,0,0,0,0,0,0,0,0,0,0,2088,0,0,0,4825088,0,0,0,0,0,0,0,0,0,5840896,5849088,0,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,368,368,0,0,0,0,0,0,0,0,5898240,5963776,0,0,6193152,0,0,5406720,6397952,5300224,5234688,5423104,0,0,0,0,5988352,0,0,6135808,6307840,0,5996544,4800512,0,5259264,0,5414912,5447680,0,0,5562368,5636096,5685248,0,5750784,5873664,0,0,0,0,5636096,5873664,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5177344,0,0,0,0,0,5242880,0,0,0,0,0,0,0,5341184,0,0,5873664,0,0,0,0,0,0,0,5480448,4358144,4358144,4358144,4358144,4857856,4874240,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5259264,4358144,4358144,4358144,915,915,915,0,0,0,0,0,0,5029888,5038080,0,0,5103616,5201920,0,0,0,0,0,0,0,0,0,0,0,0,0,6406144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4997120,4358144,4358144,5038080,4358144,4358144,4358144,5095424,5103616,4358144,4358144,5201920,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5890048,4358144,4358144,4358144,6029312,4358144,4358144,4358144,4358144,6160384,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6406144,4358144,4358144,4358144,0,0,0,4890624,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6275072,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,916,0,0,0,0,0,4857856,4874240,0,0,0,0,0,0,0,0,0,0,0,0,0,5259264,0,0,0,0,0,0,0,0,5414912,0,5447680,0,5464064,0,5480448,5562368,0,0,0,5636096,0,5685248,0,0,5750784,0,0,0,0,0,5873664,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,0,0,0,0,992,0,5464064,0,5480448,5562368,0,0,0,5636096,0,5685248,0,0,5750784,0,0,0,0,0,5873664,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5414912,4358144,5447680,4358144,5464064,4358144,5480448,5562368,4358144,4358144,4358144,5636096,4358144,5685248,4358144,4358144,5750784,4358144,4358144,4358144,4358144,4358144,5873664,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6275072,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4923392,4358144,4358144,4358144,4358144,4358144,0,4923392,0,0,0,0,0,0,0,0,0,450560,450560,0,0,450560,450560,450560,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,825,0,0,0,0,0,0,0,0,0,0,0,4366336,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5242880,0,0,0,0,0,0,0,0,6283264,6332416,0,0,0,5881856,0,5382144,0,0,0,0,0,0,6266880,4784128,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,0,0,0,368640,0,0,0,0,0,5603328,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,340,341,0,0,0,4759552,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4825088,0,0,5177344,0,0,0,0,0,0,0,649,0,0,0,0,0,0,820,0,0,0,0,0,0,0,0,0,0,0,0,0,649,0,0,0,0,0,0,0,692,0,0,0,0,0,0,699,368,368,368,0,0,0,0,0,0,0,0,0,0,0,712,0,0,0,5701632,0,0,0,0,0,0,0,0,0,0,5808128,0,0,0,0,4792320,4833280,0,0,5701632,0,0,0,0,0,4358144,4358144,4358144,4825088,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6119424,4358144,6168576,4358144,4358144,4358144,4358144,6242304,4358144,6291456,4358144,6316032,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6463488,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,0,0,0,0,0,0,0,4956160,4964352,0,5341184,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5627904,5652480,4358144,5701632,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,0,0,0,0,303,0,304,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5627904,5652480,4358144,5701632,4358144,4358144,5808128,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2314,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6299648,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,0,0,0,5029888,5038080,0,0,5103616,5201920,0,0,0,0,0,0,0,0,0,0,0,0,0,6406144,5570560,5578752,0,5668864,0,0,5791744,0,0,0,0,0,0,0,0,0,6201344,6242304,6250496,0,0,0,0,6422528,0,0,0,0,0,0,0,0,0,0,0,2813,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2800,0,0,0,0,0,0,0,0,0,0,0,5619712,0,0,0,0,0,0,0,5726208,5758976,0,0,5791744,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6152192,0,0,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60689,57917,57917,0,0,6316032,0,0,0,0,5816320,6291456,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,320,0,4358144,4358144,6463488,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4931584,4939776,0,0,0,0,0,0,5054464,0,0,0,0,0,0,0,0,0,0,6324224,0,0,5005312,0,0,0,512e4,5136384,0,0,0,0,0,0,0,0,0,0,6324224,4358144,4358144,0,0,0,5791744,5816320,0,5857280,0,0,0,0,0,0,0,0,0,0,0,0,0,6119424,0,6168576,0,0,0,0,0,6242304,0,6291456,0,6316032,0,0,0,6316032,0,0,0,0,0,0,0,0,0,6463488,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4931584,4939776,4358144,4358144,4358144,4358144,4358144,4358144,5054464,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6299648,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,4825088,0,0,0,0,0,0,0,722,0,724,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,741,0,0,0,0,0,0,0,0,0,0,3669,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,739,0,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5210112,4358144,4358144,4358144,4358144,5292032,4358144,4358144,4358144,4358144,5365760,4358144,4358144,4358144,5455872,4358144,4358144,4358144,4358144,4358144,5554176,5570560,5578752,5619712,5668864,4358144,4358144,4358144,5791744,5816320,4358144,5857280,4358144,4358144,4358144,5791744,5816320,4358144,5857280,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6119424,4358144,6168576,4358144,4358144,4358144,4358144,4358144,6242304,4358144,6291456,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6299648,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,915,915,915,4826003,915,915,915,915,915,915,6464403,0,0,0,0,991,991,991,991,991,991,991,991,991,991,991,4932575,4940767,991,991,991,991,991,991,5055455,991,0,0,0,0,6184960,5316608,0,0,5644288,0,0,0,0,0,0,0,0,0,0,6217728,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,368,0,0,0,303104,0,0,0,0,0,0,0,0,0,0,5390336,5308416,5488640,0,0,0,0,0,0,0,0,0,5070848,5431296,0,6430720,0,5160960,0,0,0,0,0,0,0,0,0,0,0,4784128,0,0,0,0,0,0,0,245760,0,0,0,245760,0,0,245760,245760,245760,0,0,0,0,0,245760,0,245760,245760,0,0,0,245760,245760,0,0,0,0,0,0,245760,0,0,0,0,0,0,245760,0,0,245760,0,0,245760,0,0,245760,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5799936,4358144,4358144,5881856,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6103040,4358144,4358144,4358144,6184960,4358144,4358144,6283264,4358144,4358144,6332416,4358144,4358144,4358144,6389760,4358144,4358144,6430720,6438912,4358144,4358144,4358144,6266880,6488064,0,0,0,6266880,6488064,0,0,0,0,0,0,0,0,0,0,0,0,344064,0,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,344064,0,4358144,4358144,6389760,4358144,4358144,6430720,6438912,0,0,0,0,0,0,4784128,0,0,0,4849664,0,0,0,0,0,4915200,0,4956160,4972544,0,0,0,0,0,0,5070848,0,0,0,0,0,0,0,5881856,0,0,0,0,0,0,0,0,0,6103040,0,0,0,6184960,0,0,0,6283264,0,0,6332416,0,0,0,6389760,0,0,6430720,6438912,4784128,4358144,4358144,4358144,4849664,4358144,4358144,4358144,4358144,4358144,4915200,4358144,4956160,4972544,4358144,4358144,4358144,4358144,4358144,4358144,5070848,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5218304,4358144,5267456,4358144,4358144,5308416,5316608,4358144,4358144,4358144,5431296,4358144,5488640,4358144,4358144,5488640,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5799936,4358144,4358144,5881856,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6103040,4358144,4358144,4358144,6184960,4358144,4358144,4358144,0,5013504,0,0,6053888,0,0,0,0,0,0,0,0,6012928,4358144,4358144,5013504,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6053888,4358144,4358144,4358144,0,0,0,0,5193728,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,5660672,5718016,0,5865472,0,0,0,0,6078464,0,0,6340608,0,6455296,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,327,328,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,581632,0,0,0,0,0,0,0,0,0,0,0,581632,0,0,0,0,0,6037504,6111232,0,0,0,5472256,0,0,0,6209536,0,0,0,0,0,0,0,0,0,0,0,6176768,0,0,0,0,0,0,0,0,0,0,2840,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2850,0,0,0,0,0,2855,0,5824512,5865472,4358144,4358144,5922816,4358144,4358144,6021120,4358144,6037504,4358144,4358144,6078464,6111232,4358144,6176768,6209536,6234112,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,4841472,0,0,0,4898816,0,0,0,0,0,0,0,0,0,0,0,5111808,0,0,0,0,0,5283840,0,0,0,0,5472256,5521408,0,0,0,0,5595136,5709824,5718016,0,5824512,5865472,0,0,5922816,0,0,6021120,0,6037504,0,0,6078464,6111232,0,6176768,6209536,0,6234112,0,0,0,0,0,0,0,0,0,0,0,0,647,757,0,759,0,761,762,676,0,0,766,767,0,0,0,0,0,0,0,0,0,5595136,5709824,5718016,0,5824512,5865472,0,0,5922816,0,0,6021120,0,6037504,0,0,6078464,6111232,0,6176768,6209536,0,6234112,0,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,731,0,0,0,0,0,0,0,0,0,742,0,0,0,0,742,4358144,4358144,5595136,5709824,5718016,4358144,5824512,5865472,4358144,4358144,5922816,4358144,4358144,6021120,4358144,6037504,4358144,4358144,6078464,6111232,4358144,6176768,6209536,4358144,6234112,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,1066,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,662,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2356,0,0,0,0,0,0,0,0,0,0,0,5357568,0,5505024,0,0,0,0,0,5890048,0,0,0,6160384,0,5095424,5349376,0,5275648,0,0,0,0,0,0,4997120,0,0,0,0,0,0,0,0,0,0,755,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,776,0,0,0,5947392,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6471680,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4997120,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6299648,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,1988,0,0,0,4825088,0,0,0,0,0,0,0,1287,0,0,0,0,0,0,0,0,0,0,0,0,0,1299,0,1177,0,0,0,0,0,0,0,0,0,0,0,3689,0,0,0,0,0,0,0,3696,0,0,0,0,0,0,0,0,0,0,0,529,4358144,4358144,4358144,4358144,6406144,0,0,0,0,0,0,0,0,4997120,0,0,5038080,0,0,0,5095424,5103616,0,0,5201920,0,0,0,0,0,0,0,0,0,0,0,5890048,0,0,0,6029312,0,0,0,0,6160384,0,0,0,0,0,5890048,0,0,0,6029312,0,0,0,0,6160384,0,0,0,0,0,0,0,6406144,0,0,0,0,0,0,0,0,4997120,0,0,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60363,57917,57917,57917,57917,57917,57917,57917,57917,57917,59997,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60389,57917,57917,57917,57917,57917,57917,57917,57917,0,6356992,0,0,0,0,0,0,0,0,5496832,0,0,0,0,0,5611520,0,0,0,0,0,4947968,5021696,5529600,0,0,5169152,0,0,0,4800512,4808704,4358144,4358144,4890624,4358144,4947968,4358144,4358144,4358144,5046272,4358144,4358144,4358144,4358144,5185536,4358144,5234688,5300224,4358144,4358144,5406720,5529600,4358144,4358144,4358144,5898240,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,491520,0,0,0,0,0,0,0,0,0,0,0,0,0,0,357,358,359,360,0,0,0,0,0,0,0,0,0,368,0,297,0,0,0,0,5898240,0,0,0,0,0,0,0,0,6307840,0,0,6356992,6381568,6397952,4800512,4808704,0,0,4890624,0,4947968,0,0,0,5046272,0,0,0,0,0,0,0,0,0,557056,557056,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2359296,420,420,0,0,0,0,4358144,4947968,4358144,4358144,4358144,5046272,4358144,4358144,4358144,4358144,5185536,4358144,5234688,5300224,4358144,4358144,5406720,5529600,4358144,4358144,4358144,4358144,5898240,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6307840,4358144,4358144,6356992,6381568,6397952,4800512,4808704,0,0,4890624,0,4947968,0,0,0,5046272,0,0,0,0,5185536,0,5234688,5300224,0,0,5406720,5529600,0,0,0,0,5898240,0,0,0,0,0,0,0,0,6307840,0,0,6356992,6381568,6397952,4800512,4808704,4358144,4358144,4890624,4358144,4358144,6356992,6381568,6397952,5021696,4358144,4358144,5021696,0,0,0,4980736,0,0,0,0,0,5373952,5734400,6045696,0,6258688,6447104,0,0,6127616,0,6348800,5906432,0,5537792,3681,4882432,0,0,0,0,0,0,0,0,5939200,0,0,5677056,6365184,4866048,0,6070272,5545984,5152768,0,0,6144e3,4358144,4866048,4882432,4358144,4980736,4358144,4358144,4358144,4358144,4358144,0,916,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,992,0,0,4358144,4358144,4358144,4358144,5324800,5373952,5537792,5545984,5734400,5971968,4358144,6045696,4358144,6070272,4358144,4358144,4358144,6348800,0,4866048,4882432,0,4980736,0,0,0,0,0,0,0,0,5324800,5586944,5734400,5971968,0,6045696,0,6070272,0,0,0,0,6348800,4358144,4866048,4882432,4358144,4980736,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5324800,5373952,5537792,5545984,5586944,5734400,5971968,0,6045696,0,6070272,0,0,0,0,6348800,0,4866048,4882432,0,4980736,0,0,0,0,0,0,0,0,5324800,5373952,5537792,5545984,4358144,6045696,4358144,6070272,4358144,4358144,4358144,4358144,6348800,4358144,6144e3,0,6144e3,0,4988928,5005312,0,0,0,0,5775360,0,0,0,3681,0,0,0,0,0,0,5693440,0,6496256,5144576,5136384,0,5914624,4358144,4358144,5005312,4358144,4358144,4358144,512e4,5136384,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6324224,0,0,5005312,0,0,0,512e4,5136384,5005312,4358144,4358144,4358144,512e4,5136384,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6324224,5914624,5914624,0,0,0,0,0,5513216,5783552,0,3681,0,0,0,0,0,0,3839,0,0,0,0,3843,0,0,0,0,0,0,0,0,3846,0,529,529,529,3848,529,529,529,3851,529,0,0,5013504,0,0,0,0,0,0,0,0,0,6053888,0,0,0,0,0,5013504,0,0,0,0,0,0,0,0,0,6053888,0,0,0,0,0,0,0,806,0,0,0,0,0,0,806,0,529,529,529,529,529,529,529,529,874,529,529,529,529,529,529,529,0,0,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60296,57894,5193728,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,5193728,0,0,0,0,0,0,0,0,0,0,0,0,0,5193728,0,0,0,0,0,0,0,0,0,5218304,0,0,0,0,5799936,0,5881856,0,0,0,0,0,0,0,0,6373376,6389760,0,0,6488064,6103040,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,5193728,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4907008,0,5079040,6094848,5742592,0,0,0,0,0,4358144,4907008,4358144,5079040,4358144,5226496,4358144,5742592,4358144,4358144,4358144,6094848,0,4907008,0,5079040,0,5226496,0,5742592,0,0,0,6094848,0,0,4907008,0,5079040,0,5226496,0,5742592,0,0,0,0,0,0,0,1194,0,0,0,1198,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,0,0,0,0,0,0,0,1202,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1275,0,0,0,1279,6094848,0,4358144,4907008,4358144,5079040,4358144,5226496,4358144,5742592,4358144,4358144,4358144,6094848,4358144,5062656,0,0,0,0,0,4358144,5062656,4358144,4358144,4358144,4358144,4358144,0,5062656,0,0,0,0,0,0,0,352256,0,352256,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1273,0,0,0,0,0,0,0,0,0,6225920,0,5062656,0,0,0,0,0,6225920,4358144,5062656,4358144,4358144,4358144,4358144,4358144,6225920,0,6086656,0,0,0,4816896,4358144,4358144,4358144,4358144,6086656,4816896,0,0,0,0,6086656,4816896,0,0,0,0,6086656,4816896,4358144,4358144,4358144,4358144,6086656,0,5087232,0,5931008,4358144,5332992,5980160,4358144,0,5332992,5980160,0,0,5332992,5980160,0,4358144,5332992,5980160,4358144,0,5439488,5128192,4358144,5128192,0,5128192,0,5128192,4358144,0,4358144,0,0,4358144,0,4358144,0,0,4358144,0,4358144,0,0,4358144,6004736,6004736,6004736,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,386,0,0,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,774,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,221654,221654,221654,470,470,470,470,470,470,470,470,470,470,470,221654,470,221654,221654,221654,470,221654,221654,221654,221654,221654,221654,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2359296,0,2359296,0,0,0,2359296,0,2359296,2359296,2359296,2359296,221654,221654,221654,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,368,0,703,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,425984,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3455,0,0,0,0,0,0,0,0,0,0,0,0,0,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,237568,303,0,307,237568,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,760,0,0,0,0,0,0,0,0,0,770,0,0,0,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2364,0,0,0,114688,0,0,0,0,0,4268032,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,383,0,0,0,0,307,0,0,4857856,4874240,0,0,4923392,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5480448,0,0,0,0,0,0,0,0,0,352,353,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,297,0,0,4210980,24578,3,0,0,298,0,0,0,0,298,0,0,0,0,0,0,0,0,0,245760,0,0,0,0,0,0,0,0,0,0,0,0,665,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,681,682,0,0,245760,245760,0,4210980,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,664,0,794,0,0,0,0,0,0,0,798,0,0,0,0,807,0,0,746,0,0,0,0,4268032,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,680,0,0,0,0,0,1160,0,4857856,4874240,0,0,4923392,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5480448,0,0,0,0,0,0,0,0,0,378,0,363,0,0,0,0,0,0,0,0,0,363,0,0,0,0,139264,147456,0,0,0,0,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,0,0,0,0,0,0,0,0,0,0,0,0,376832,0,376832,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,364,365,366,367,0,0,368,0,297,0,0,0,262144,262144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1244,0,0,0,0,0,0,262144,0,262144,262144,0,0,0,0,0,0,0,0,0,0,0,262144,262144,0,262144,0,0,0,139264,147456,262144,0,0,0,0,0,0,0,1829,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,0,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,262739,0,262739,0,0,262739,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,702,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1390,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,0,0,0,278528,278528,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2417,0,0,0,0,0,0,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,278528,0,278528,278528,0,131072,278528,0,0,0,278528,0,0,0,0,0,0,278528,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,317,0,0,0,0,0,0,0,0,0,0,0,0,0,0,278528,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,771,0,0,771,0,0,0,0,0,771,771,0,830,0,0,0,0,0,0,0,0,418,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2803,0,0,0,0,0,0,1,24578,3,0,0,4366336,0,0,0,0,0,303,639,0,4268032,307,642,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2351104,0,0,0,0,0,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6275072,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,1433,0,0,0,0,0,4857856,4874240,0,0,0,0,0,0,0,0,0,402,0,0,0,0,0,0,0,0,0,0,0,0,402,0,0,0,0,0,0,0,0,0,0,0,413,359,0,0,402,0,0,0,0,0,139264,147456,402,413,0,426,0,5750784,0,0,0,0,0,5873664,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,0,0,0,0,1528,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,286720,304,0,308,286720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1203,0,0,0,0,0,0,0,0,0,0,368,368,0,0,0,0,0,0,0,0,308,0,0,0,0,0,0,0,0,0,0,0,0,308,0,0,0,0,0,0,308,139264,287141,0,0,0,308,1,24578,3,0,0,4366336,0,0,0,0,0,303,66176,0,4268032,307,98947,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1317,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1235,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,308,0,308,0,0,0,0,122880,0,4268032,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,771,0,0,0,0,307,0,308,4857856,4874240,0,0,4923392,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5480448,0,0,0,0,0,0,0,0,0,662,0,0,0,0,0,0,0,0,0,662,0,0,662,0,0,0,828,0,0,0,662,0,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,305,305,305,0,0,305,305,295217,305,305,305,305,305,305,305,305,305,295217,305,295217,295217,295217,295217,295217,295217,295217,305,0,305,0,305,305,305,295217,305,305,305,295217,295217,305,295217,305,305,305,305,305,295286,295217,295217,295217,295217,295217,295217,305,305,305,305,305,305,295286,295217,295217,295217,305,305,305,295286,139264,147456,295217,295217,305,305,305,305,305,295217,374,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,305,369,305,0,295217,305,295217,305,295217,305,131072,305,305,305,305,295217,305,305,305,305,305,305,295217,305,295217,295217,295217,305,305,305,305,305,305,305,305,305,305,305,305,305,295217,295217,295217,295217,295217,295217,305,305,305,305,295217,305,305,305,305,305,305,305,305,305,295217,305,295217,295217,295217,295217,295217,295217,295217,295217,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295286,295217,295217,295217,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1749,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3673,3674,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5840896,5849088,0,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,4399804,4399804,0,0,0,0,0,0,0,1829,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1842,0,0,0,0,0,0,0,0,0,703,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2415,0,0,0,0,0,0,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,319488,0,0,0,0,0,0,0,0,0,0,0,2841,0,0,0,0,2843,0,0,0,0,0,0,0,0,0,2852,0,0,0,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,319488,0,0,0,319488,319488,319488,319488,319488,319488,319488,319488,319488,319488,319488,319488,319488,319488,319488,319488,319488,0,0,0,0,319488,0,0,0,0,0,0,0,0,0,0,319488,0,0,0,319488,0,0,0,0,0,0,0,0,0,0,319488,0,0,0,0,0,0,0,0,0,319488,0,0,0,0,319488,0,0,0,0,0,319488,319488,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,450560,450560,0,0,0,0,319488,319488,319488,0,24578,3,0,0,4366336,253952,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1832,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2382,0,0,0,0,2387,0,0,0,0,0,0,0,0,0,0,0,5840896,5849088,0,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,368,0,0,0,0,0,0,0,0,0,5857280,0,6463488,4939776,0,0,5455872,0,0,0,0,0,0,0,0,6062080,6463488,0,5398528,0,0,0,6479872,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,327680,0,0,0,0,0,0,0,0,0,0,1168,0,0,0,0,0,0,0,0,0,1178,0,0,0,0,0,0,0,1185,0,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,327680,327680,327680,0,0,0,0,0,0,0,0,0,0,327680,49724,0,0,0,0,0,0,0,49724,49724,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,327680,327680,327680,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2302,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1780,0,0,0,0,0,0,0,0,0,0,0,327680,327680,327680,327680,327680,327680,335872,327680,327680,327680,335872,327680,327680,327680,327680,327680,327680,0,0,0,0,0,0,0,0,0,49724,0,0,0,0,0,0,0,0,0,663,0,0,0,0,0,0,0,0,0,663,0,0,663,0,0,0,0,0,0,0,663,0,0,5750784,0,0,0,0,0,5873664,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,0,0,0,49152,992,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,344064,344064,344064,0,0,0,0,0,0,0,0,0,0,344064,344064,344064,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2319,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2326528,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,352256,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,352256,0,0,0,0,0,131072,0,0,0,0,0,352256,0,0,352256,352256,352256,0,352256,0,352256,352256,352256,352256,352256,352256,352256,352256,352256,352256,352256,352256,352256,352256,352256,352256,352256,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,469,0,0,0,0,0,0,0,0,0,0,2335239,2335206,352256,352256,352256,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2377,0,0,2380,0,0,0,0,2385,0,0,0,0,0,2391,0,0,1,293,3,0,0,0,299,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1242,0,0,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,360448,360448,360448,0,0,0,0,0,0,0,0,0,0,360448,360448,360448,1,0,3,155943,155943,297,0,637,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3162,0,3163,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,212992,0,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,529,529,529,529,1379,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2471,2472,529,529,529,57944,57944,57944,57944,57944,57944,59007,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60756,57944,57944,57944,57944,57917,57917,60373,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59507,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,0,3430,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,405,0,0,0,0,0,0,0,0,0,333,0,0,3469,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1958,529,529,1961,529,529,529,529,529,3500,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2470,529,529,529,529,529,57917,57917,57917,57917,60926,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60395,57917,57917,0,0,0,0,3683,0,0,0,0,3688,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,57894,529,57894,529,529,57894,529,529,57917,57894,529,529,57894,57894,3704,529,529,529,3707,529,529,529,529,529,529,529,529,529,3715,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,58786,57894,57894,57894,58790,529,529,529,529,529,529,529,57894,61075,57894,57894,57894,61078,57894,57894,57894,57894,57894,57894,57894,57894,57894,61086,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59386,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58858,57894,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,61115,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,61133,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61136,57944,57944,57944,57944,57944,57944,57944,57944,57944,61144,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60091,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,3681,0,0,3835,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1363,529,529,529,529,529,529,529,529,529,529,529,3857,529,529,529,3858,3859,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61219,57894,57894,57894,57894,61220,61221,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61238,57917,57917,57917,57917,57917,57917,59450,59451,57917,57917,57917,57917,59458,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59473,57917,57917,57917,61239,61240,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61257,57944,57944,57944,57944,61258,61259,57894,57894,57894,57894,57894,61311,57894,57894,57894,61315,57894,57917,57917,57917,57917,57917,57917,61321,57917,57917,57917,57917,57917,57917,61327,57917,57917,57917,61331,57917,57944,57944,57944,57944,0,0,529,529,57894,57894,57917,57917,57944,57944,0,529,57894,57917,57944,0,529,57894,57917,57944,0,529,57894,57917,57944,0,529,57944,57944,57944,57944,61337,57944,57944,57944,57944,57944,57944,61343,57944,57944,57944,61347,57944,529,57894,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,3838,0,0,3841,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,1350,529,529,529,529,529,529,1365,529,529,529,1370,529,0,0,0,0,4018,529,529,529,529,529,529,529,529,529,529,529,529,529,529,61377,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58848,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,57894,57894,57894,61393,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61409,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,0,3148,0,0,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,0,0,0,0,529,529,529,529,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,529,529,529,529,529,529,57894,57894,57917,57944,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1789,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,376832,376832,376832,0,0,0,0,0,0,0,0,0,0,0,0,742,662,0,0,529,844,529,529,529,859,529,529,529,529,529,529,529,529,529,529,0,0,0,0,0,422,422,422,422,598,598,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,0,422,0,0,422,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3216,3217,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,3946,529,529,529,529,529,529,3952,529,529,529,529,57894,57894,57894,57894,57894,57894,61305,57894,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,309,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3482,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,3950,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,393687,393687,393687,0,0,0,0,0,0,0,0,0,0,0,0,788,0,0,0,529,843,529,529,529,529,529,529,875,529,529,529,529,529,529,529,0,0,0,0,0,393687,0,393687,393687,393687,0,393687,393687,393687,393687,393687,393687,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,737,0,0,803,0,0,0,0,0,0,0,803,0,393687,393687,0,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3693,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,306,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,0,423,0,0,0,0,0,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,0,423,0,0,423,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,306,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4399804,4399804,4399804,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,750,423,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2853,2854,0,0,0,1153,1727,1728,0,0,0,1734,1735,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2388,0,0,0,0,0,2295,0,0,0,0,2297,1735,2298,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2416,0,0,0,0,0,529,529,529,2504,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58829,57894,57894,57894,57894,529,529,529,529,529,529,529,2504,2938,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60341,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,2593,3005,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60710,57917,57944,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,417792,310,311,0,0,0,0,0,0,0,1829,0,0,0,0,0,0,0,0,0,0,0,0,0,1837,0,0,0,0,0,0,0,0,0,0,0,0,5627904,5652480,0,5701632,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,417792,0,0,0,0,417792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,417792,0,0,417792,0,0,417792,0,0,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60362,57917,57917,57917,57917,57917,60367,57917,57917,57917,57917,57917,57917,60669,57917,57917,57917,57917,57917,57917,60677,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60703,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,417792,418102,417792,1,24578,3,0,0,4366972,0,0,0,0,0,303,304,311296,4268032,307,308,0,434176,0,0,0,0,0,0,0,0,0,0,0,0,450560,450560,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,450560,0,0,0,0,0,0,5840896,5849088,0,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,0,4399805,0,0,0,0,0,0,0,1829,0,0,0,0,0,0,0,0,0,0,0,1836,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3692,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,846,529,529,529,529,529,529,529,529,529,529,529,892,529,529,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6275072,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,916,915,915,915,915,915,4858771,4875155,915,915,915,915,915,915,915,915,915,915,6300563,915,915,915,915,915,915,915,915,915,915,915,0,0,991,991,991,4826079,991,991,991,991,915,5751699,915,915,915,915,915,5874579,915,915,915,915,915,915,915,915,915,915,915,6275987,915,915,915,915,915,915,915,915,915,0,0,992,991,5465055,991,5481439,5563359,991,991,991,5637087,991,5686239,991,991,5751775,991,991,991,991,991,5874655,991,991,991,991,991,991,991,991,991,991,991,6276063,4358144,4358144,6463488,0,0,0,0,915,915,915,915,915,915,915,915,915,915,915,4932499,4940691,915,915,915,915,915,915,5055379,915,915,915,915,915,915,915,915,915,915,6325139,991,991,5006303,991,991,991,5120991,5137375,991,991,991,991,991,991,991,991,991,991,6325215,4359059,4359059,5817235,915,5858195,915,915,915,915,915,915,915,915,915,915,915,915,915,6120339,915,6169491,915,915,915,915,915,6243219,915,6292371,915,6316947,915,915,915,915,5890963,915,915,915,6030227,915,915,915,915,6161299,915,915,915,915,915,915,915,6407059,991,991,991,991,991,991,991,991,4998111,991,6317023,991,991,991,991,991,991,991,991,991,6464479,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4932499,4940691,4359059,4359059,4359059,4359059,4359059,4359059,5055379,4359059,4359059,4359059,4359059,4359059,4359059,5890963,4359059,4359059,4359059,6030227,4359059,4359059,4359059,4359059,6161299,4359059,4359059,4359059,4359059,4359059,4359059,4359059,6407059,4358144,4358144,4358144,915,915,915,4890624,0,0,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60361,57917,57917,60364,60365,57917,57917,57917,57917,57917,60370,4359059,4359059,4359059,5792659,5817235,4359059,5858195,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,6120339,4359059,6169491,4359059,4359059,4359059,4359059,4359059,6243219,4359059,6292371,4359059,4359059,4359059,4916115,4359059,4957075,4973459,4359059,4359059,4359059,4359059,4359059,4359059,5071763,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5219219,4359059,5268371,4359059,4359059,5309331,5317523,4359059,4359059,4359059,5432211,6316947,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,6464403,4358144,4358144,4358144,4358144,4358144,915,915,915,915,915,0,0,0,0,0,0,0,0,4956160,4964352,0,0,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,60356,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60001,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,0,0,750,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,4358144,4358144,6389760,4358144,4358144,6430720,6438912,0,0,0,0,0,0,4785043,915,915,915,4850579,915,915,915,915,915,4916115,915,4957075,4973459,915,915,915,915,915,915,915,915,5260179,915,915,915,915,915,915,915,915,5415827,915,5448595,915,5464979,915,5481363,5563283,915,915,915,5637011,915,5686163,915,915,5071763,915,915,915,915,915,915,915,5219219,915,5268371,915,915,5309331,5317523,915,915,915,5432211,915,5489555,915,915,915,915,915,915,915,915,915,5800851,915,915,5882771,915,915,915,915,915,915,915,915,915,6103955,915,915,915,6185875,915,915,915,6284179,915,915,6333331,915,915,915,6390675,915,915,6431635,6439827,4359059,5489555,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5800851,4359059,4359059,5882771,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,6103955,4359059,4359059,4359059,6185875,4359059,4359059,4359059,0,5013504,0,0,6053888,0,0,0,0,0,0,0,0,6012928,4358144,4358144,5013504,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6053888,4358144,4358144,6284179,4359059,4359059,6333331,4359059,4359059,4359059,6390675,4359059,4359059,6431635,6439827,4358144,4358144,4358144,6266880,6488064,915,915,915,6267795,6488979,0,0,0,0,0,0,0,0,0,0,0,0,540672,0,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,540672,0,5824512,5865472,4358144,4358144,5922816,4358144,4358144,6021120,4358144,6037504,4358144,4358144,6078464,6111232,4358144,6176768,6209536,6234112,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,915,915,4842387,915,915,915,915,6087571,4817887,991,991,991,991,6087647,4817811,4359059,4359059,4359059,4359059,6087571,0,5087232,0,5931008,4358144,5332992,5980160,4358144,915,5333907,5981075,915,991,5333983,5981151,915,4899731,915,915,915,915,915,915,915,915,915,915,915,5112723,915,915,915,915,915,5284755,915,915,915,915,5473171,5522323,915,915,915,915,5596051,5710739,5718931,915,5825427,5866387,915,915,5923731,915,915,6022035,915,6038419,915,915,6079379,6112147,915,6177683,6210451,915,6235027,915,915,915,915,915,915,915,0,0,991,991,991,991,991,6104031,991,991,991,6185951,991,991,991,6284255,991,991,6333407,991,991,991,6390751,991,991,6431711,6439903,4785043,4359059,4359059,4359059,4850579,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,6300563,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4358144,4358144,4358144,4358144,4358144,915,915,915,915,915,0,0,0,0,0,0,0,4898816,0,5709824,0,0,0,5283840,0,0,0,0,5251072,0,6414336,5832704,0,5955584,0,0,4358144,4358144,4841472,4358144,4358144,4358144,4898816,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5111808,4358144,4358144,4358144,4358144,4358144,5283840,4358144,4358144,4358144,4358144,5472256,5521408,4358144,4358144,4358144,5595136,5709824,5718016,4358144,4842463,991,991,991,4899807,991,991,991,991,991,991,991,991,991,991,991,5112799,991,991,991,991,991,5284831,991,991,991,991,5473247,5522399,991,991,991,991,991,991,991,5211103,991,991,991,991,5293023,991,991,991,991,5366751,991,991,991,5456863,991,991,991,991,991,5555167,5571551,5579743,5620703,5669855,991,5596127,5710815,5719007,991,5825503,5866463,991,991,5923807,991,991,6022111,991,6038495,991,991,6079455,6112223,991,6177759,6210527,991,6235103,991,991,991,991,991,991,991,4359059,4359059,4359059,4359059,4359059,5194643,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4907008,0,5079040,6094848,5742592,0,0,0,0,0,4358144,4907008,4358144,5079040,4359059,4842387,4359059,4359059,4359059,4899731,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5112723,4359059,4359059,4359059,4359059,4359059,5284755,4359059,4359059,4359059,4359059,5473171,5522323,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5211027,4359059,4359059,4359059,4359059,5292947,4359059,4359059,4359059,4359059,5366675,4359059,4359059,4359059,5456787,4359059,4359059,4359059,4359059,4359059,5555091,5571475,5579667,5620627,5669779,4359059,4359059,5596051,5710739,5718931,4359059,5825427,5866387,4359059,4359059,5923731,4359059,4359059,6022035,4359059,6038419,4359059,4359059,6079379,6112147,4359059,6177683,6210451,4359059,6235027,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,6275987,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4923392,4358144,4358144,4358144,4358144,4358144,915,4924307,915,915,915,915,4358144,4358144,4358144,4358144,6406144,915,915,915,915,915,915,915,915,4998035,915,915,5038995,915,915,915,5096339,5104531,915,915,5202835,915,915,915,915,915,915,915,915,915,915,915,915,5628819,5653395,915,5702547,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,5178259,915,915,915,915,915,5243795,915,915,915,915,915,915,915,5342099,991,5039071,991,991,991,5096415,5104607,991,991,5202911,991,991,991,991,991,991,991,991,991,991,991,5891039,991,991,991,6030303,991,991,991,991,6161375,991,991,991,5792735,5817311,991,5858271,991,991,991,991,991,991,991,991,991,991,991,991,991,6120415,991,6169567,991,991,991,991,991,6243295,991,6292447,991,991,5219295,991,5268447,991,991,5309407,5317599,991,991,991,5432287,991,5489631,991,991,991,991,991,991,991,991,991,5800927,991,991,5882847,991,991,991,991,991,991,991,991,991,991,991,991,991,991,991,991,5178335,991,991,991,991,991,5243871,991,991,991,991,991,991,991,5342175,991,4358144,6307840,4358144,4358144,6356992,6381568,6397952,4801427,4809619,915,915,4891539,915,4948883,915,915,915,5047187,915,915,915,915,5186451,915,5235603,5301139,915,915,5407635,5530515,915,915,915,991,991,991,991,991,991,991,991,991,991,991,991,991,991,991,991,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4358144,4358144,4358144,4358144,4358144,4358144,0,915,915,915,915,915,915,0,0,0,0,0,0,915,915,5899155,915,915,915,915,915,915,915,915,6308755,915,915,6357907,6382483,6398867,4801503,4809695,991,991,4891615,991,4948959,991,991,991,5047263,991,991,991,991,991,991,991,991,991,991,991,5628895,5653471,991,5702623,991,991,991,991,991,991,991,991,991,991,991,991,991,991,991,991,991,991,0,0,0,0,915,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5186527,991,5235679,5301215,991,991,5407711,5530591,991,991,991,991,5899231,991,991,991,991,991,991,991,991,6308831,991,991,6357983,6382559,6398943,4801427,4809619,4359059,4359059,4891539,4359059,4948883,4359059,4359059,4359059,5047187,4359059,4359059,4359059,4359059,5186451,4359059,5235603,5301139,4359059,4359059,5407635,5530515,4359059,4359059,4359059,4359059,5899155,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,6308755,4359059,4359059,6357907,6382483,6398867,5021696,4358144,4358144,5022611,915,915,0,4980736,0,0,0,0,0,5373952,5734400,6045696,0,6258688,6447104,0,0,6127616,0,6348800,5906432,0,5537792,4358144,4358144,4358144,4358144,5324800,5373952,5537792,5545984,5734400,5971968,4358144,6045696,4358144,6070272,4358144,4358144,4358144,6348800,915,4866963,4883347,915,4981651,915,915,915,915,915,915,915,915,5325715,5587935,5735391,5972959,991,6046687,991,6071263,991,991,991,991,6349791,4359059,4866963,4883347,4359059,4981651,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5325715,5374867,5538707,5546899,5587859,5735315,5972883,915,6046611,915,6071187,915,915,915,915,6349715,991,4867039,4883423,991,4981727,991,991,991,991,991,991,991,991,5325791,5374943,5538783,5546975,4359059,6046611,4359059,6071187,4359059,4359059,4359059,4359059,6349715,4358144,6144e3,915,6144915,0,4988928,5005312,0,0,0,0,5775360,0,0,0,3681,0,0,0,0,0,0,5693440,0,6496256,5144576,5136384,0,5914624,4358144,4358144,5005312,4358144,4358144,4358144,512e4,5136384,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6324224,915,915,5006227,915,915,915,5120915,5137299,5006227,4359059,4359059,4359059,5120915,5137299,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,6325139,5914624,5915539,0,0,0,0,0,5513216,5783552,0,3681,0,0,0,0,3837,0,0,0,0,0,3842,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,3849,529,529,529,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,990,991,991,991,991,915,915,5014419,915,915,915,915,915,915,915,915,915,6054803,915,915,915,991,991,5014495,991,991,991,991,991,991,991,991,991,6054879,991,991,991,991,991,991,6407135,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4998035,4359059,4359059,5038995,4359059,4359059,4359059,5096339,5104531,4359059,4359059,5202835,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5415827,4359059,5448595,4359059,5464979,4359059,5481363,5563283,4359059,4359059,4359059,5637011,4359059,5686163,4359059,4359059,5751699,4359059,4359059,4359059,4359059,4359059,5874579,4359059,4359059,4359059,5014419,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,6054803,4359059,4359059,4359059,0,0,0,0,5193728,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4931584,4939776,4358144,4358144,4358144,4358144,4358144,4358144,5054464,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5193728,4358144,4358144,4358144,4358144,4358144,4358144,4358144,915,915,915,915,915,5194643,915,915,915,915,915,915,915,915,991,991,991,991,991,5194719,991,991,991,991,991,991,991,991,991,6300639,991,991,991,991,991,991,991,991,991,991,991,5809043,4359059,4359059,4359059,4826003,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5628819,5653395,4359059,5702547,4359059,4359059,5809043,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5178259,4359059,4359059,4359059,4359059,4359059,5243795,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5342099,4359059,4359059,4359059,4358144,5226496,4358144,5742592,4358144,4358144,4358144,6094848,915,4907923,915,5079955,915,5227411,915,5743507,915,915,915,6095763,915,991,4907999,991,5080031,991,5227487,991,5743583,991,991,991,991,991,4858847,4875231,991,991,991,991,991,991,991,991,991,991,991,991,991,5260255,991,991,991,991,991,991,991,991,5415903,991,5448671,6095839,991,4359059,4907923,4359059,5079955,4359059,5227411,4359059,5743507,4359059,4359059,4359059,6095763,4359059,5062656,0,0,0,0,0,4358144,5062656,4358144,4358144,4358144,4358144,4358144,915,5063571,915,915,915,5211027,915,915,915,915,5292947,915,915,915,915,5366675,915,915,915,5456787,915,915,915,915,915,5555091,5571475,5579667,5620627,5669779,915,915,915,5792659,915,915,915,6226835,991,5063647,991,991,991,991,991,6226911,4359059,5063571,4359059,4359059,4359059,4359059,4359059,6226835,0,6086656,0,0,0,4816896,4358144,4358144,4358144,4358144,6086656,4817811,6005651,6005727,6005651,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3465,0,0,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,450560,0,0,0,0,0,0,450560,0,0,450560,0,450560,450560,450560,450560,0,0,0,0,131072,0,0,0,0,0,0,450560,0,0,0,0,0,450560,0,450560,450560,450560,450560,450560,450560,450560,450560,450560,450560,450560,450560,450560,450560,450560,450560,450560,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,771,0,0,0,0,0,0,0,0,0,0,0,0,450560,450560,450560,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4399805,311296,4399805,0,0,0,311296,0,0,0,0,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6299648,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,304,0,0,308,0,0,0,308,0,0,0,4931584,0,0,0,0,0,0,0,0,0,0,0,0,5210112,0,5365760,0,5554176,0,0,6316032,0,196608,0,0,5816320,6291456,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2359296,368,0,0,0,0,6316032,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6463488,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,304,0,0,308,0,0,0,4956160,4964352,0,0,0,0,0,0,57917,57917,60352,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60360,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,60027,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60751,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,4358144,4358144,6389760,4358144,4358144,6430720,6438912,916,0,0,0,916,0,4784128,0,0,0,4849664,0,0,0,0,0,4915200,0,4956160,4972544,0,0,0,0,0,0,0,0,0,666,0,645,0,0,0,0,0,0,796,0,0,0,0,0,0,0,0,0,0,805,0,810,5824512,5865472,4358144,4358144,5922816,4358144,4358144,6021120,4358144,6037504,4358144,4358144,6078464,6111232,4358144,6176768,6209536,6234112,4358144,4358144,4358144,4358144,4358144,4358144,4358144,916,0,0,0,4841472,0,0,0,0,0,0,0,5210112,0,0,0,0,5292032,0,0,0,0,5365760,0,0,0,5455872,0,0,0,0,0,5554176,5570560,5578752,5619712,5668864,0,0,0,5791744,5718016,0,5824512,5865472,0,0,5922816,0,0,6021120,0,6037504,0,0,6078464,6111232,0,6176768,6209536,0,6234112,0,0,0,0,0,0,0,992,0,0,0,992,0,4784128,0,0,0,4849664,0,0,0,0,0,4915200,0,4956160,4972544,0,0,0,0,0,0,5070848,0,0,0,0,0,0,0,5218304,0,5267456,0,0,5308416,5316608,0,0,0,5431296,0,5488640,0,0,0,0,0,0,0,0,0,5799936,0,0,5881856,0,0,0,0,0,0,0,0,459183,0,0,0,0,0,0,0,0,0,0,0,0,0,459224,459224,459224,459224,459224,459224,459224,459224,459224,459224,459224,459224,459224,459224,459224,459224,459224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1066,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459348,459224,459380,459224,459224,459380,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5767168,0,0,0,0,4857856,0,0,0,0,0,0,0,0,0,0,0,1,24578,3,0,0,0,0,507904,0,0,0,507904,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,507904,0,0,0,0,0,0,57917,60351,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60688,57917,57917,57917,57917,57917,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,507904,507904,507904,507904,507904,507904,507904,507904,507904,507904,507904,507904,507904,507904,507904,507904,507904,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1321,0,0,0,0,0,0,0,0,0,0,0,0,507904,507904,507904,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,442368,0,0,0,0,0,0,0,0,0,0,0,726,0,0,0,0,0,0,0,0,0,0,0,738,0,0,0,0,0,0,0,0,1,24578,3,0,0,0,0,0,516096,0,0,0,516096,0,0,0,0,0,0,516096,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1201,0,0,1204,1205,0,0,0,0,1209,0,0,0,368,368,0,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,516569,516569,516569,516569,516569,516569,516569,516569,516569,516569,516569,516569,516569,516569,516569,516569,516569,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2306,2307,0,0,0,0,0,0,0,0,0,0,0,516569,516569,516569,1,24578,0,0,0,4366336,0,0,548864,0,0,303,304,0,4268032,307,308,409600,0,0,0,0,0,0,0,0,0,0,0,0,1199,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,0,0,0,5005312,4358144,4358144,4358144,512e4,5136384,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6324224,5914624,5914624,0,0,0,0,0,5513216,5783552,0,40960,0,0,0,0,0,0,0,0,0,6299648,0,0,0,0,0,0,0,0,0,0,0,5808128,4358144,4358144,4358144,4825088,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,483328,0,0,0,0,0,0,0,0,0,0,0,0,0,0,335,0,0,0,0,0,0,0,0,335,0,0,139264,147456,0,0,0,0,1,24578,4227366,0,0,0,0,0,0,300,0,0,0,300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1208,0,1210,0,0,368,368,0,0,0,0,0,0,540672,0,0,540672,0,0,0,540672,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2310144,0,368,0,0,0,0,0,0,0,1,24578,4227366,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1294,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,363,0,0,0,0,0,0,368,0,297,0,0,0,0,0,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1806,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1866,0,0,0,0,0,0,0,0,0,0,1,24578,3,155943,297,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2829,0,0,0,57894,57917,57894,57894,57894,57894,57894,57894,57894,57917,57917,57894,57894,57944,57894,57894,57894,57894,57894,57894,57894,57944,57944,57894,57894,57894,57894,57944,57944,57894,529,57894,57894,57894,57894,57894,57894,60623,57894,57894,60627,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60636,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,61317,57917,57917,61319,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,61333,1153,1727,0,0,0,0,1734,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3172,0,0,0,0,2295,0,0,0,0,2297,0,2298,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2827,0,0,0,0,0,0,0,0,0,0,2835,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,0,0,0,0,3005,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58948,57917,57917,57917,0,0,0,0,1829,0,0,0,0,0,0,0,2374,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,483328,0,0,0,0,0,0,0,0,0,0,0,0,131072,0,0,0,0,0,0,445,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,0,0,0,1283,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,339,0,0,0,57895,57918,57895,57895,57895,57895,57895,57895,57895,57918,57918,57895,57895,57945,57895,57895,57895,57895,57895,57895,57895,57945,57945,57895,57895,57895,57895,57945,57945,57895,529,57895,57895,57895,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2326,2327,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2846,0,0,0,0,0,0,0,0,0,0,0,1,24578,3,155944,297,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3464,0,0,0,1,24578,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,573440,0,573440,573440,573440,0,573440,573440,573440,573440,573440,573440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2328,0,0,0,0,0,0,0,0,0,2337,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,573440,573440,573440,0,0,0,0,0,0,0,0,0,0,0,0,1260,0,0,0,0,1265,0,0,0,0,0,0,0,0,0,0,0,1277,0,0,0,0,0,0,0,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,573440,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2351,0,0,0,0,2355,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2406,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2330,0,0,0,0,0,0,0,0,0,0,0,6356992,3681,0,0,0,0,0,0,0,5496832,0,0,0,0,0,5611520,0,0,0,0,0,4947968,5021696,5529600,0,0,5169152,0,0,0,4800512,0,0,0,1,24578,3,0,0,4366336,0,0,0,0,0,638,304,0,4268032,641,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2816,0,0,2819,0,0,0,0,0,0,2825,0,0,0,0,0,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,581632,0,0,0,581632,581632,581632,581632,581632,581632,581632,581632,581632,581632,581632,581632,581632,581632,581632,581632,581632,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,581632,581632,581632,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2868,0,0,0,0,0,0,0,0,529,529,529,529,529,529,2880,529,529,3833,4882432,0,0,0,0,0,0,0,0,5939200,0,0,5677056,6365184,4866048,0,6070272,5545984,5152768,0,0,6144e3,4358144,4866048,4882432,4358144,4980736,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,499712,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1774,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1324,0,0,0,0,0,0,0,0,0,0,4358144,6045696,4358144,6070272,4358144,4358144,4358144,4358144,6348800,4358144,6144e3,0,6144e3,0,4988928,5005312,0,0,0,0,5775360,0,0,0,3932,0,0,0,0,0,0,5693440,5005312,4358144,4358144,4358144,512e4,5136384,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6324224,5914624,5914624,0,0,0,0,0,5513216,5783552,0,3932,0,0,0,0,0,0,0,0,351,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,297,0,0,0,312,313,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3679,0,0,0,0,0,0,0,313,0,0,0,0,0,312,0,312,313,0,312,312,313,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1295,0,1175,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1888,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,0,0,0,0,131072,0,433,0,0,0,0,0,0,0,0,312,0,460,474,474,474,487,487,487,487,487,487,487,487,487,507,487,487,487,487,487,487,525,487,487,487,525,487,487,487,487,487,487,530,57896,530,57896,530,530,57896,530,530,57919,57896,530,530,57896,57896,57896,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,646,0,0,649,650,0,0,0,0,0,0,317,318,319,320,321,322,323,324,325,326,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1206,1207,0,0,0,0,0,368,368,0,0,0,57896,57919,57896,57896,57896,57896,57896,57896,57896,57919,57919,57896,57896,57946,57896,57896,57896,57896,57896,57896,57896,57946,57946,57896,57896,57896,57896,57946,57946,57896,530,57896,0,747,0,0,0,0,0,752,0,0,0,0,646,0,0,0,0,0,0,763,0,0,0,0,0,0,0,0,772,0,0,0,0,0,0,0,2346,0,0,0,0,0,2350,0,0,2352,0,0,0,0,2357,0,0,0,0,2362,0,0,0,0,0,0,0,0,0,1854,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1328,0,1330,0,0,1169,0,0,778,0,0,782,0,0,0,0,0,0,0,0,791,0,0,0,0,795,0,0,0,0,0,0,0,799,0,0,0,0,0,0,0,0,0,694,0,0,0,0,0,368,368,368,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,540672,0,0,0,0,0,0,0,540672,0,0,0,0,0,0,0,0,835,795,0,0,0,0,0,839,840,0,0,0,0,795,529,529,849,853,529,529,865,529,529,529,881,529,886,529,894,529,529,529,0,2507,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59899,57894,57894,57894,57894,57894,57894,897,529,529,911,529,57894,57894,57894,58268,58272,57894,57894,58284,57894,57894,57894,58300,57894,58305,57894,58313,57894,58316,57894,57894,58330,57894,0,57917,57917,57917,58344,58348,57917,57917,58360,57917,57917,57917,58376,57917,58381,57917,58389,57917,58392,57917,57917,58406,57917,0,0,0,0,58305,57944,57944,57944,58419,58423,57944,57944,58435,57944,57944,57944,57944,57944,57944,57944,57944,60079,57944,57944,57944,57944,57944,60085,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,4153,0,0,0,529,529,529,529,529,57944,57944,58451,57944,58456,57944,58464,57944,58467,57944,57944,58481,57944,849,853,1143,897,529,529,0,58272,58268,58493,58316,57894,57894,155943,1153,0,0,1156,0,0,0,0,0,0,196608,0,0,0,106496,0,0,4284416,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5341184,0,5652480,0,1161,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,278528,0,0,0,0,1219,0,0,0,0,1224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1785,1786,1787,0,0,0,0,1247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,644,0,1281,0,0,0,0,0,0,0,0,0,0,1292,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1304,0,0,0,0,0,0,0,0,399,0,0,0,0,0,0,0,0,352,0,0,0,399,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,0,0,529,529,529,529,529,1414,529,529,529,529,529,529,529,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59889,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59389,57894,57894,57894,57894,57894,59396,57894,57894,57894,57894,57894,57894,57894,57894,59405,57894,1153,1727,0,0,0,0,1734,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1754,0,0,0,0,0,0,0,0,0,0,1197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,0,0,0,0,0,1875,0,0,0,0,0,0,0,0,0,0,0,0,1887,0,0,0,1889,0,0,1890,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,529,529,529,529,529,1903,529,529,529,529,529,529,529,529,529,1916,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2489,529,529,529,2492,529,529,529,529,529,2497,529,529,529,529,57894,57894,57894,57894,59346,57894,57894,57894,57894,57894,57894,57894,57894,57894,59359,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,61104,57917,57917,57917,61107,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59446,57917,57917,57917,57917,57917,57917,57917,57917,57917,59459,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59542,57944,57944,57944,57944,57944,57944,57944,57944,57944,59555,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57944,57944,57944,57944,57944,57944,59614,57944,57944,57944,57944,57944,57944,59620,57944,57944,57944,57944,57944,57944,529,2285,529,529,529,57894,59634,57894,57894,57894,2294,0,0,0,0,0,0,245760,245760,245760,245760,245760,245760,0,0,0,0,0,0,0,245760,245760,245760,0,0,0,0,139264,147456,245760,245760,0,0,0,131072,0,0,0,0,245760,0,0,0,0,0,0,245760,0,245760,0,245760,0,0,0,0,0,0,0,0,0,0,0,0,697,698,0,368,368,368,0,0,0,0,0,0,0,0,0,710,0,0,0,0,2295,0,0,0,0,2297,0,2298,0,0,0,0,0,0,0,0,0,2304,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,270336,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,2404,529,529,529,529,529,529,529,529,529,529,529,2434,529,529,2437,529,529,529,529,529,529,2445,529,529,529,529,529,529,529,529,529,529,529,3712,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3265,529,529,529,529,0,0,57894,57894,57894,57894,57894,529,529,529,529,529,529,2480,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2500,529,529,529,529,529,529,529,529,3257,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2938,0,57894,57894,57894,57894,57894,57894,57894,57894,59418,57894,57894,57894,57894,57894,57894,59424,57894,57894,57894,57894,57894,57894,50679,2089,57917,57917,57917,57917,57917,59440,57917,57917,57894,57894,59933,57894,57894,57894,57894,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59954,57917,57917,59957,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,60961,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60991,57944,57944,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,57917,59965,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59985,57917,57917,57917,57917,57917,57917,57917,57917,58965,0,58966,58967,57944,57944,57944,57944,57944,58974,57944,57944,57944,57944,58980,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,0,0,3931,3681,0,0,0,0,0,0,0,57944,60048,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60068,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59049,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,60879,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60892,57894,57894,57944,57944,57944,57944,57944,57944,60105,57944,57944,57944,57944,2765,529,529,529,529,60114,57894,57894,57894,57894,2775,2295,0,2776,2298,0,0,2778,0,0,0,0,0,0,0,2401,0,0,0,0,0,0,0,0,0,0,0,0,2411,0,0,0,0,0,0,0,0,0,0,0,0,2300,0,0,0,0,0,0,0,0,0,0,2310,0,0,0,0,0,0,0,0,529,2935,529,529,529,529,529,0,2938,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,60291,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60307,57894,57894,57894,57894,57894,57894,57894,60312,57894,57894,57894,57894,57894,57894,57894,60318,57894,57894,57894,57894,57894,57894,57894,60299,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,0,992,0,3005,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,60358,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60366,57917,57917,57917,57917,57917,57917,57917,58881,57917,57917,57917,58885,57917,57917,58896,57917,57917,58900,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60934,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60702,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57917,57917,57917,57917,60402,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60413,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,529,529,529,529,57944,57944,60423,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60431,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,57894,0,0,0,0,0,0,0,0,3681,0,0,0,0,57944,57944,57944,57944,57944,57944,60478,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,303,307,0,0,0,0,3147,0,0,0,0,0,0,0,2787,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3198,0,0,0,0,3203,3151,0,0,0,0,0,0,3156,0,0,0,0,0,0,0,0,0,0,0,0,0,3166,0,0,0,0,0,0,0,0,0,0,0,303,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,532480,0,0,0,0,0,0,0,0,0,3179,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3195,0,0,0,0,0,0,0,0,0,0,0,756,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,2877,2878,529,529,529,529,0,0,0,0,3208,3209,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3221,0,529,529,529,529,529,529,529,0,2938,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60655,57894,57894,57894,57894,57894,57894,57894,57894,0,0,57917,57917,529,529,529,529,529,3232,529,529,3236,529,529,529,529,529,529,529,529,529,529,3245,529,529,529,529,529,529,529,529,529,529,529,3252,57894,60644,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,3005,0,57917,57917,57917,57917,57917,58370,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,58412,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60057,57944,57944,57944,57944,57944,57944,60062,57944,60064,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,2766,529,529,529,57894,60115,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,2404,2405,0,0,2407,0,0,0,0,2412,0,0,0,0,0,0,0,0,0,0,57917,57917,57917,57917,60693,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,60418,57944,60419,57944,57944,57944,57944,57944,57944,60742,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61158,57944,57944,529,3418,529,57894,60765,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3436,0,0,0,0,0,0,0,0,0,0,0,3185,0,0,0,0,0,0,0,0,0,0,0,0,3197,0,0,0,0,0,0,0,529,529,529,529,529,529,529,3501,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3518,529,3520,529,529,529,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60319,57894,57894,57894,57894,4014,0,4016,0,529,4019,529,4021,529,529,529,529,529,529,529,529,529,529,529,57894,61378,57894,61380,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60334,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59431,50679,0,57917,57917,57917,57917,57917,57917,57917,57917,57894,57894,57894,57917,61394,57917,61396,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,61410,57944,61412,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,57894,57894,57894,57894,61452,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,61466,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60408,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60038,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61480,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,0,4154,0,4156,529,529,529,529,529,529,529,529,529,529,1909,529,529,529,529,529,529,529,529,529,1920,529,529,529,529,529,529,529,529,529,529,529,529,529,1425,529,529,529,529,58776,916,57894,57894,58781,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,0,0,314,315,316,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,0,245760,245760,0,0,0,429,131072,0,0,429,0,0,0,0,0,0,0,0,429,461,0,0,0,461,461,461,461,461,461,461,461,461,461,461,524,461,524,524,524,461,524,524,524,524,524,524,531,57897,531,57897,531,531,57897,531,531,57920,57897,531,531,57897,57897,57897,57920,57897,57897,57897,57897,57897,57897,57897,57920,57920,57897,57897,57947,57897,57897,57897,57897,57897,57897,57897,57947,57947,57897,57897,57897,57897,57947,57947,57897,622,57897,57974,57974,57974,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,417792,0,0,0,0,417792,0,0,0,0,0,0,311,0,311,0,0,0,57944,57944,57944,57944,57944,58460,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,303,0,0,0,0,0,0,645,0,0,0,805,0,810,0,796,0,822,0,0,0,0,0,0,0,0,0,645,0,0,0,0,0,0,0,0,0,2371,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3677,0,0,0,0,0,0,1846,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1846,0,0,0,0,0,0,0,0,0,0,0,3213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,1349,529,529,529,1358,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1969,529,529,529,529,529,529,1976,529,529,529,529,529,529,529,529,529,529,58776,0,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58938,57917,57917,57917,57917,57917,57917,57917,57917,57917,57894,57894,57894,57894,59412,57894,57894,57894,57894,57894,57894,59420,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,1269,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59563,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57917,57917,57917,59512,57917,57917,57917,57917,57917,57917,59520,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,0,1157,0,57944,57944,59608,57944,57944,57944,57944,57944,57944,59616,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,2294,0,0,0,0,0,0,417792,0,417792,0,0,0,0,311,0,0,0,0,0,417792,0,417792,0,0,0,0,139264,147456,417792,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,311,0,417792,417792,0,0,417792,417792,417792,417792,417792,417792,417792,417792,417792,417792,417792,418103,417792,417792,418102,418103,417792,417792,418102,417792,418102,417792,0,0,0,0,0,0,0,0,417792,0,0,0,417792,0,0,2805,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1188,0,0,0,2860,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,2879,529,529,529,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59866,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59355,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59430,57894,50679,2090,57917,57917,57917,57917,57917,57917,57917,57917,529,2883,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2473,529,529,529,529,2936,529,529,529,0,2938,0,0,0,0,57894,57894,57894,57894,57894,57894,60288,57894,57894,57894,57894,60292,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59955,57917,57917,57917,57917,57917,57917,57917,57917,57917,60377,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61132,57917,57917,57917,57944,57944,57944,57944,57944,0,3005,0,0,0,0,57917,57917,57917,57917,57917,57917,60355,57917,57917,57917,57917,60359,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58403,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60424,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60071,57944,57944,0,321,321,430,131072,432,434,430,439,432,439,0,317,456,456,456,457,462,475,475,475,488,488,488,488,488,488,488,488,488,488,509,509,522,522,523,523,509,523,523,523,509,523,523,523,523,523,523,532,57898,532,57898,532,532,57898,532,532,57921,57898,532,532,57898,57898,57921,57898,57898,57898,57898,57898,57898,57898,57921,57921,57898,57898,57948,57898,57898,57898,57898,57898,57898,57898,57948,57948,57898,57898,57898,57898,57948,57948,57898,623,57973,57973,57973,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4931584,0,0,0,0,0,0,0,0,0,0,0,0,5210112,0,5365760,0,5554176,0,686,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,368,702,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2303,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,329,330,331,332,0,0,0,0,0,0,0,0,0,0,898,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58317,57894,57894,57894,57894,0,57917,57917,57917,57917,57917,57917,57917,58924,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58951,57917,0,1217,1176,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1243,0,0,0,0,0,0,0,2810,0,0,0,0,0,2815,0,2817,2818,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,499712,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,1284,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1298,0,0,0,0,0,0,0,0,0,0,0,0,1858,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4358144,4359060,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,1310,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1327,0,0,0,0,0,0,0,0,0,0,1257,0,0,0,0,0,0,0,0,0,0,0,0,0,1272,0,1274,0,0,0,0,0,57894,57894,58798,57894,58803,57894,57894,58807,57894,57894,58810,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59897,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,58875,57917,57917,58879,57917,57917,57917,57917,57917,57917,57917,57917,58893,57917,58898,57917,57917,58902,57917,57917,58905,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60438,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58999,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59603,57944,1153,1727,0,0,0,0,1734,0,0,0,0,0,0,0,1744,1745,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1211,0,0,0,0,0,0,0,0,0,1308,0,529,529,529,1933,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1956,1957,529,529,529,529,529,529,529,529,529,529,2916,529,529,529,529,529,529,2923,529,529,529,529,529,529,529,529,529,529,2931,529,529,529,57894,57894,59376,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59399,59400,57894,57894,57894,57894,57894,57894,57894,0,2595,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58941,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59476,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59499,59500,57917,57917,57917,57917,57917,57917,57917,57917,57917,60672,57917,57917,60676,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60685,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,58969,57944,57944,58973,57944,57944,57944,57944,57944,57944,57944,57944,58987,57944,58992,57944,57944,58996,57944,57944,57944,57944,59545,57944,57944,57944,57944,57944,57944,57944,57944,57944,59557,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59572,57894,59905,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59918,57894,57894,57894,57894,57894,59922,59923,59924,57894,57894,57894,57894,57894,57894,57894,57894,57894,59352,57894,57894,57894,57894,57894,57894,57894,57894,57894,59363,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59914,57894,57894,57894,57894,57894,57894,57894,59920,57894,57894,57894,57894,57894,57894,57894,59926,57894,57894,57894,57894,57944,57944,57944,57944,57944,60077,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60090,57944,57944,57944,57944,57944,60094,60095,60096,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60454,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59627,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,2780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2339,60398,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61256,57944,57944,57944,57944,57944,57944,57944,0,0,0,3180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,743,0,0,0,529,529,3419,57894,57894,60766,0,0,0,0,0,3428,0,0,0,0,0,0,0,3432,0,0,0,0,0,0,0,0,0,0,0,0,0,663,0,0,529,529,529,529,529,860,529,529,876,529,529,529,529,529,529,529,3497,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3512,3513,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3241,529,529,3244,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1914,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,916,57894,57894,58780,57894,57894,58784,57894,57894,57894,57894,57894,57894,57894,60896,57894,60898,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61112,57917,57917,60923,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60938,57917,60940,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60932,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59495,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,60980,57944,60982,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3832,0,529,529,3729,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59401,57894,57894,59404,57894,57894,61160,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3442,0,0,57894,61450,57894,61451,57894,57894,57894,61455,57894,57894,57894,57894,57894,57894,57894,57894,57917,61464,57917,61465,57917,57917,57917,61469,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60696,57917,57917,57917,60699,57917,60701,57917,57917,57917,57917,57917,57917,57917,57917,60706,57917,57917,57917,57917,57917,57944,57944,61478,57944,61479,57944,57944,57944,61483,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,2430,529,529,529,529,529,529,529,529,529,529,529,2442,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,4294,0,0,0,529,529,529,4297,57894,57894,57894,61643,57917,57917,57917,57917,57917,57917,59482,57917,57917,57917,59487,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60704,57917,57917,57917,57917,57917,57917,57917,57917,57944,61645,57944,57944,57944,61647,0,0,529,529,57894,57894,57917,57917,57944,57944,0,529,57894,57917,57944,0,529,57894,57917,57944,0,529,57894,57917,57944,0,529,529,529,529,529,529,529,529,3503,529,529,529,529,529,529,529,529,3511,529,529,529,529,529,529,529,529,529,529,529,529,529,3523,0,0,0,377,131072,0,435,377,0,0,0,446,452,0,0,0,377,463,476,476,476,489,489,489,489,489,489,489,489,489,489,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,533,57899,533,57899,533,533,57899,533,533,57922,57899,533,533,57899,57899,57899,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,666,0,0,669,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1233,1234,0,0,0,0,0,0,0,0,0,0,0,0,57899,57922,57899,57899,57899,57899,57899,57899,57899,57922,57922,57899,57899,57949,57899,57899,57899,57899,57899,57899,57899,57949,57949,57899,57899,57899,57899,57949,57949,57899,533,57899,58444,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1759,1760,0,1190,0,1192,1193,0,0,0,1195,1196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,0,0,0,0,0,0,0,2837,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2849,0,0,0,0,0,0,0,0,0,0,342,0,0,0,0,0,0,0,0,0,0,0,0,0,389,0,139264,147456,0,0,0,0,1334,1195,0,0,0,0,0,0,0,0,529,529,1343,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1369,529,529,529,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59865,57894,57894,59868,57894,57894,57894,57894,57894,57894,59876,57894,57894,57894,57894,58834,57894,57894,57894,57894,58839,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58864,57894,57894,57894,57894,50679,58776,992,57917,57917,58876,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58903,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60933,57917,60935,57917,57917,57917,57917,57917,57917,57917,60942,57917,57917,60944,57917,57917,57917,57917,57917,57917,57917,57917,58918,57917,57917,57917,57917,57917,57917,57917,58927,57917,57917,58929,57917,57917,57917,57917,58934,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58887,57917,57917,57917,57917,57917,57917,57917,57917,57917,58906,57917,57917,57917,57917,57917,57917,57917,57917,57917,529,529,529,1967,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,0,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59953,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61122,57917,57917,57917,57917,57917,57917,57917,57917,61130,57917,57917,57917,57917,57917,57917,57944,57944,57944,61135,57944,57894,57894,59410,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61121,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,60033,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60045,57944,57917,59510,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,0,1158,0,59606,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,2288,57894,57894,57894,57894,59637,2294,0,0,0,0,0,0,2342912,0,0,0,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,0,0,0,0,0,1155,0,2295,0,0,0,0,2297,0,2298,0,0,0,0,0,2301,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1814,0,0,0,0,0,0,0,0,0,529,529,2452,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2932,529,529,57894,57894,57894,57894,57894,59883,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60320,57894,57894,57894,59931,57894,57894,57894,57894,57894,57894,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,59952,57917,57917,57917,57917,59956,57917,57917,57917,57917,57917,57917,57917,57917,59452,57917,57917,57917,57917,57917,57917,57917,57917,57917,59463,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59474,57917,57917,60018,57917,60020,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,60035,57944,57944,57944,57944,60039,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59584,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59562,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59571,57944,57944,57944,60101,57944,60103,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,2775,2295,0,2776,2298,0,0,0,0,0,0,0,0,0,0,2865,0,0,0,0,0,0,0,0,0,2873,0,0,529,529,529,529,529,529,529,529,529,529,529,529,3261,529,529,529,529,529,529,529,529,529,529,529,529,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,60328,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,3005,0,57917,57917,0,3005,0,0,0,0,57917,57917,57917,60353,57917,60354,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58935,57917,57917,57917,57917,57917,57917,57917,58949,57917,57917,57917,3177,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2393,529,529,3253,529,529,529,529,529,529,529,3259,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2938,0,57894,57894,57894,57894,57894,57894,57894,57894,58840,57894,57894,57894,57894,57894,57894,57894,58854,57894,57894,57894,57894,57894,57894,57894,57894,58866,58867,57894,57894,50679,58776,992,57894,57894,57894,57894,60645,57894,57894,57894,57894,57894,57894,57894,60651,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,3005,0,57917,57917,57917,57917,57917,58373,58375,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,58417,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61487,57944,57944,61489,57944,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,4023,529,529,529,4027,529,529,529,529,529,57894,57894,57894,57894,57894,61382,57894,57894,57894,61386,57894,57894,57894,529,529,529,3730,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60640,57894,57894,57894,57894,57894,57944,61161,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3441,0,0,0,57944,57944,57944,57944,57944,57944,61264,57944,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,1353,529,529,529,529,529,529,529,529,529,1372,57894,57894,57894,57917,57917,57917,57917,57917,57917,61399,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,61415,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59618,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,332,0,0,0,0,0,0,0,0,376,0,0,0,0,0,0,0,0,0,0,0,0,0,0,332,0,139264,147456,0,0,0,0,0,0,0,0,693,0,0,0,0,0,0,368,368,368,0,0,0,0,0,706,0,0,0,0,0,0,0,0,0,0,311,311,311,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,212992,0,0,0,0,0,212992,212992,212992,0,0,0,0,131072,0,329,0,0,0,0,0,0,0,331,0,0,464,477,477,477,490,490,490,500,490,500,503,490,490,490,511,511,511,511,511,511,526,511,511,511,526,511,511,511,511,511,511,534,57900,534,57900,534,534,57900,534,534,57923,57900,534,534,57900,57900,57900,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,728,0,0,0,0,0,0,0,0,0,0,740,0,645,740,0,744,745,645,57900,57923,57900,57900,57900,57900,57900,57900,57900,57923,57923,57900,57900,57950,57900,57900,57900,57900,57900,57900,57900,57950,57950,57900,57900,57900,57900,57950,57950,57900,534,57900,685,0,0,0,689,0,0,0,0,0,0,0,0,0,0,368,368,368,0,0,0,0,0,0,707,708,0,0,0,0,0,714,0,0,0,718,0,720,0,0,0,0,0,0,727,0,729,730,0,0,733,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3189,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,328,328,377,0,0,0,0,0,0,0,0,0,0,0,0,779,780,0,0,0,0,0,0,0,0,0,790,0,792,0,0,0,730,0,0,0,0,0,0,0,0,0,0,804,0,809,0,812,0,0,0,0,0,0,792,0,804,0,818,0,730,0,0,812,824,0,0,826,0,0,824,824,0,0,0,792,0,0,0,0,0,0,751,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,769,730,0,0,773,0,0,0,0,0,0,659,660,0,0,0,0,0,0,0,0,0,0,671,672,0,0,0,0,0,0,0,0,0,0,0,684,0,0,0,836,0,0,0,0,0,0,0,790,0,0,0,836,529,529,850,529,856,529,529,871,529,529,882,529,887,529,529,896,899,904,529,912,529,57894,57894,57894,58269,57894,58275,57894,57894,58290,57894,57894,58301,57894,58306,57894,57894,58315,58318,58323,57894,58331,57894,0,57917,57917,57917,58345,57917,58351,57917,57917,58366,57917,57917,58377,57917,58382,57917,57917,58391,58394,58399,57917,58407,57917,0,0,0,0,58306,57944,57944,57944,58420,57944,58426,57944,57944,58441,57944,57944,58452,57944,58457,57944,57944,58466,58469,58474,57944,58482,57944,850,529,529,1144,904,529,0,57894,58269,57894,58494,58323,57894,155943,1153,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1753,0,0,0,0,0,0,0,0,0,0,0,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,360448,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1251,0,0,1201,0,0,0,0,0,751,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1838,0,0,0,0,0,0,0,0,0,0,0,1282,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3702,0,529,57894,57894,57894,57894,57894,58804,57894,57894,57894,58809,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58826,57894,57894,57894,57894,57894,57894,57894,0,2596,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60415,57917,57917,57944,57944,57944,57944,57944,57944,57944,58952,57917,57917,57917,57917,57917,57917,58963,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58978,57944,57944,57944,57944,57944,57944,58993,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4092,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1978,529,529,529,529,529,529,529,529,58776,0,57894,59337,57894,57894,57894,57894,57894,58998,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59015,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59558,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59624,57944,57944,57944,1910,529,529,529,529,59353,57894,57894,57894,57894,0,0,59031,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59047,57944,57944,57944,57944,57944,57944,59058,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60890,57894,57894,57894,57894,1153,1727,0,0,0,0,1734,0,0,0,0,1741,0,1743,0,0,0,0,0,0,0,0,0,0,0,0,1756,0,0,0,0,0,0,0,0,0,754,0,0,0,0,0,0,0,0,0,0,764,0,0,665,768,0,0,0,0,0,775,0,0,0,0,1763,0,0,1766,1767,1768,0,1770,1771,0,0,0,1775,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1791,0,0,0,0,0,1797,0,0,1800,0,1802,0,0,0,0,0,1808,1809,0,0,0,0,0,1815,0,0,0,0,1820,1821,0,0,0,0,0,0,785,0,0,0,680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2311,0,0,0,0,0,0,0,0,0,0,0,1827,0,0,1829,0,0,0,0,0,0,0,0,1833,1834,1835,0,0,0,0,0,0,1841,0,1843,0,0,0,0,0,0,0,0,753,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1240,0,0,0,0,0,0,1874,0,0,0,0,0,0,1880,1881,0,0,0,0,0,0,0,0,0,0,0,1874,0,0,0,1892,1743,1743,1894,529,1896,529,1897,1898,529,1900,529,529,529,1904,529,529,529,529,529,529,529,529,529,1917,529,529,529,529,1921,529,529,529,529,1925,529,1927,529,529,529,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59864,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58851,57894,57894,58855,57894,57894,57894,57894,57894,58862,57894,57894,57894,58869,57894,50679,58776,992,1963,529,1965,529,1968,529,529,529,529,529,1975,529,529,1977,529,529,529,529,529,529,529,529,529,58776,0,59336,57894,59338,57894,59339,57894,59341,57894,59343,57894,57894,57894,59347,57894,57894,57894,57894,57894,57894,57894,57894,57894,59360,57894,57894,57894,57894,59364,57894,57894,57894,57894,59368,57894,59370,57894,57894,57894,57894,57894,57894,57894,58808,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58823,57894,57894,57894,57894,57894,57894,57894,58832,57894,59408,57894,59411,57894,57894,57894,57894,57894,59419,57894,57894,59421,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,0,59436,57917,59438,57917,59439,57917,59441,57917,57917,57917,57917,57917,60021,57917,57917,60024,60025,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60041,57944,60043,57944,57944,57944,0,0,0,4083,0,0,0,0,0,0,0,4090,0,0,529,529,529,529,4095,529,529,529,529,529,529,529,529,529,529,529,529,529,2892,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2465,529,529,529,529,529,529,529,529,529,529,529,529,529,59443,57917,57917,57917,59447,57917,57917,57917,57917,57917,57917,57917,57917,57917,59460,57917,57917,57917,57917,59464,57917,57917,57917,57917,59468,57917,59470,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,60960,57944,57944,57944,57944,60964,57944,57944,57944,57944,57944,57944,57944,60970,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60083,57944,57944,57944,57944,60088,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59013,57944,57944,57944,59017,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59508,57917,59511,57917,57917,57917,57917,57917,59519,57917,57917,59521,57917,57917,57917,57917,57917,57917,57917,57917,57917,57894,59532,57944,59534,57944,59535,57944,59537,57944,59539,57944,57944,57944,57944,57944,57944,57944,57944,60452,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60753,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59543,57944,57944,57944,57944,57944,57944,57944,57944,57944,59556,57944,57944,57944,57944,59560,57944,57944,57944,57944,59564,57944,59566,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59585,57944,57944,57944,57944,57944,57944,59592,57944,57944,57944,57944,57944,57944,57944,57944,59601,57944,57944,57944,57944,57944,57944,59576,59577,59579,57944,57944,57944,57944,57944,57944,57944,59587,59588,57944,57944,59590,57944,57944,59593,59594,57944,57944,57944,57944,57944,57944,57944,59602,57944,59604,57944,59607,57944,57944,57944,57944,57944,59615,57944,57944,59617,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,1955,529,2287,529,57894,59398,57894,59636,57894,2294,0,0,0,0,0,0,2351104,0,0,0,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,0,0,0,0,303,0,0,2295,0,0,0,0,2297,0,2298,0,0,0,0,0,0,0,0,0,0,2305,0,0,2308,2309,0,0,0,2313,0,0,0,0,0,0,0,0,0,802,0,0,0,0,0,0,0,0,0,802,0,0,802,0,0,0,0,0,0,0,802,0,0,0,0,0,1829,0,2370,0,0,0,0,0,0,0,2376,0,0,2379,0,0,0,0,2384,0,0,0,0,0,2390,0,2392,0,0,0,0,0,0,4268032,0,0,0,0,0,0,0,758,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,307,0,0,0,0,0,0,307,0,0,0,0,0,2422,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2438,529,2440,529,529,529,529,529,529,2448,529,2450,529,529,529,2477,2478,529,529,529,529,529,529,2485,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2499,529,529,529,0,0,0,0,57894,57894,59856,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,2502,2503,529,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59869,57894,59871,57894,57894,57894,57894,57894,57894,57894,2593,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59879,57894,59881,57894,57894,57894,57894,57894,57894,57894,59887,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60343,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59932,57894,57894,59935,59936,57894,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59958,57917,59960,57917,57917,57917,57917,57917,58921,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58936,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60697,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,60030,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60433,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60051,57944,60053,57944,57944,57944,57944,57944,57944,57944,60059,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,57894,0,0,0,0,0,0,0,0,3681,0,0,4012,4013,57944,57944,57944,57944,57944,60104,57944,57944,60107,60108,57944,2440,529,2767,529,529,59871,57894,60116,57894,57894,2775,2295,0,2776,2298,0,0,0,0,0,0,0,0,0,0,3158,0,0,0,0,0,0,0,0,3164,0,0,0,0,0,0,0,0,0,0,0,0,0,3453,0,0,0,0,0,3456,0,3458,0,0,0,0,0,0,0,0,3466,0,529,529,529,529,529,2911,529,529,529,529,2915,529,529,529,2920,529,529,529,529,529,529,529,529,2928,529,529,529,529,529,529,529,2933,57894,57894,57894,57894,57894,60302,57894,60304,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60321,57894,57894,57894,57894,57894,57894,57894,61098,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58890,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58914,57917,57917,57917,57894,57894,60325,57894,57894,57894,60330,57894,57894,57894,57894,57894,57894,57894,57894,60338,57894,57894,57894,57894,57894,57894,57894,57894,60344,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,59950,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59962,57917,0,3005,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,60357,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60369,57917,57917,57917,57917,57917,60375,57917,57917,57917,57917,60378,57917,57917,60380,57917,60381,57917,57917,57917,57917,57917,57917,57917,57917,57917,60390,57917,57917,60394,57917,57917,57917,57917,57917,58369,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,0,0,0,3681,0,0,3935,0,0,0,0,60371,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60388,57917,57917,57917,57917,60392,57917,57917,57917,60397,57944,60422,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60434,57944,60436,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,3146,0,0,3149,3150,57944,57944,57944,57944,60476,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,303,307,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1177,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,802,0,0,0,60740,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60747,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,57894,0,0,0,0,0,0,0,0,3681,4010,0,0,0,529,529,3498,529,529,529,529,529,529,529,3504,529,529,529,529,529,3510,529,529,529,529,529,529,529,529,529,529,3519,3521,529,529,529,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,59861,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59873,57894,57894,57894,57894,57894,57894,57894,57894,57894,61457,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,61471,57917,57917,57917,57917,57917,57917,57917,57917,59485,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60010,57917,57917,57917,57917,60014,57917,57917,3524,529,3526,3527,529,57894,57894,57894,57894,57894,57894,60878,57894,57894,57894,57894,57894,60882,57894,57894,57894,57894,57894,57894,57894,60888,57894,57894,57894,57894,57894,60894,57894,57894,60897,57894,57894,57894,57894,57894,57894,57894,57894,60904,60906,57894,57894,57894,57894,60910,57894,60912,60913,57894,57917,57917,57917,57917,57917,57917,60920,57917,57917,57917,57917,57917,57917,60022,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60037,57944,57944,60040,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,3824,0,0,0,0,0,0,0,0,0,3829,0,0,0,0,0,0,0,0,0,0,2403,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2360,0,0,0,0,0,0,0,57917,57917,60924,57917,57917,57917,57917,57917,57917,57917,60930,57917,57917,57917,57917,57917,60936,57917,57917,60939,57917,57917,57917,57917,57917,57917,57917,57917,60946,60948,57917,57917,57917,57917,57917,58960,57917,57917,57917,0,57894,57944,58968,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58982,58989,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60745,57944,57944,57944,60748,57944,60750,57944,57944,57944,57944,57944,57944,57944,57944,60755,57944,57944,57944,57944,57944,57917,57917,60952,57917,60954,60955,57917,57944,57944,57944,57944,57944,57944,60962,57944,57944,57944,57944,57944,60966,57944,57944,57944,57944,57944,57944,57944,60972,57944,57944,57944,57944,57944,57944,57944,57944,57944,58478,57944,57944,57944,1141,529,529,529,908,529,0,57894,58492,57894,57894,58327,57894,155943,1153,0,0,0,0,0,0,0,0,816,0,0,0,0,0,0,821,0,0,821,0,0,0,0,0,821,821,0,0,0,801,0,0,57944,60978,57944,57944,60981,57944,57944,57944,57944,57944,57944,57944,57944,60988,60990,57944,57944,57944,57944,60994,57944,60996,60997,57944,529,529,3656,57894,57894,61003,0,0,0,0,0,0,788,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,788,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,2882,0,0,0,0,3665,0,0,3668,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3675,0,0,0,0,0,0,0,0,0,0,0,789,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,808,0,0,0,0,789,0,808,0,529,847,529,529,529,529,529,529,878,880,529,529,529,529,529,529,0,0,0,3682,0,3684,0,0,0,0,0,0,0,3691,0,0,0,3694,3695,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,1344,529,529,529,529,529,529,529,529,1357,529,529,529,529,1367,529,529,529,529,529,529,3706,529,529,529,529,529,529,529,3711,529,529,529,529,529,529,529,529,529,529,529,529,529,3721,529,529,529,529,529,529,529,0,0,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60294,57894,57894,60297,529,529,529,529,529,529,529,57894,57894,57894,61077,57894,57894,57894,57894,57894,57894,57894,61082,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59422,57894,57894,57894,57894,57894,57894,57894,57894,50679,0,57917,59437,57917,57917,57917,57917,57917,57917,57894,61093,57894,57894,57894,57894,57894,57894,57894,57894,61101,57894,57894,57894,57894,57894,57894,57917,57917,57917,61106,57917,57917,57917,57917,57917,57917,57917,61111,57917,57917,57917,57917,57917,57917,60403,57917,57917,57917,60406,60407,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,60417,57944,57944,57944,57944,57944,57944,57944,57944,57944,60427,57944,57944,57944,57944,57944,60432,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59589,57944,57944,57944,57944,57944,57944,57944,57944,59598,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61140,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61151,57944,57944,57944,57944,57944,57944,57944,57944,61159,57944,57944,57944,57944,57944,57944,57944,57944,60479,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,303,307,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,806,0,57944,57944,57944,57944,57944,61263,57944,57944,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,3929,3930,0,3681,0,0,0,0,0,3938,0,0,0,0,0,0,4268032,0,0,0,0,0,0,0,475136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,736,0,0,0,0,0,0,0,0,0,0,57894,61307,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,61323,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60965,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59012,57944,57944,57944,57944,57944,57944,57944,59021,57944,57944,59023,57944,57944,57944,57944,59029,57944,57944,57944,57944,57944,57944,57944,57944,61339,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,57894,0,0,0,0,0,0,0,4009,3681,0,0,0,0,0,0,0,0,1223,0,0,0,0,0,0,0,0,1232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,538,57904,538,57904,538,538,57904,538,538,57927,57904,538,538,57904,57904,57894,61391,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61407,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,0,0,0,0,0,57944,61423,57944,0,0,0,0,0,0,4085,0,0,0,0,0,0,0,529,529,529,529,529,529,4097,529,529,529,529,529,529,529,529,529,529,529,529,3861,529,529,529,529,529,57894,57894,57894,57894,57894,57894,61212,57894,57894,57894,57894,57894,57894,57894,57944,57944,57944,57944,57944,57944,61482,57944,57944,57944,57944,57944,57944,57944,57944,57944,4147,4148,0,0,0,4151,0,0,0,0,0,4157,4158,4159,529,529,529,0,0,0,0,57894,59855,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,60919,57917,57917,57917,57917,529,4162,529,4164,529,529,529,529,61513,61514,61515,57894,57894,57894,61518,57894,61520,57894,57894,57894,57894,61525,61526,61527,61528,57917,57917,57917,61531,57917,61533,57917,57917,57917,57917,57917,61118,57917,57917,57917,57917,57917,57917,57917,57917,61124,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60974,57944,57944,57917,57917,57917,61538,61539,61540,61541,57944,57944,57944,61544,57944,61546,57944,57944,57944,57944,61551,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,1907,1908,529,529,529,529,1915,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1930,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,4246,0,0,0,529,529,4251,529,529,529,4255,57894,57894,61601,57894,57894,57894,57894,57894,57894,60624,57894,60626,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,60921,57917,57917,57894,57894,61605,57894,57917,57917,61607,57917,57917,57917,61611,57917,57944,57944,61613,57944,57944,57944,61617,57944,0,0,0,0,0,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,58282,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,57917,57917,57917,57917,0,0,0,372,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,372,0,0,0,380,382,0,0,0,0,0,0,0,0,0,1255,0,0,0,750,1262,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,765,0,0,0,0,0,0,0,0,0,0,0,372,372,0,131072,372,0,334,440,372,440,0,0,440,440,440,458,440,0,0,0,440,497,497,497,497,497,497,497,497,497,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,535,57901,535,57901,535,535,57901,535,535,57924,57901,535,535,57901,57901,57901,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,751,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3463,0,0,0,0,57901,57924,57901,57901,57901,57901,57901,57901,57901,57924,57924,57901,57901,57951,57901,57901,57901,57901,57901,57901,57901,57951,57951,57901,57901,57901,57901,57951,57951,57901,535,57901,529,529,529,529,529,57894,57894,58261,57894,57894,57894,57894,57894,57894,58294,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,57917,57917,58337,57917,57917,57917,57917,57917,61242,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,61250,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,0,0,0,58445,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,303,0,0,0,0,0,0,789,0,0,0,0,808,0,0,0,0,0,0,0,0,0,0,0,694,0,0,789,0,0,0,0,808,57894,57894,58799,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,0,0,0,0,1877,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,3493,529,529,529,529,529,529,1966,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,0,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,57917,57917,57917,57917,59947,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60698,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57894,59409,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61246,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,2294,1728,59509,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61346,57944,57944,529,57894,0,0,0,4007,0,0,0,0,3681,0,0,0,0,59990,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,60073,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59605,0,0,2859,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,3948,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61572,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60401,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61255,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,3666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,297,0,0,57944,57944,57944,57944,57944,57944,57944,61141,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,4250,529,529,529,529,529,529,61600,57894,57894,57894,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1831,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,229376,0,491520,524288,0,0,0,0,0,0,0,57894,57894,57894,57894,61606,57917,57917,57917,57917,57917,57917,57917,61612,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,58283,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,57917,57917,57917,57917,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,0,0,0,0,4296,529,529,529,61642,57894,57894,57894,61644,57917,57917,57917,57917,57917,58961,58962,57917,57917,0,57894,57944,57944,57944,57944,58972,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,4161,57917,61646,57944,57944,57944,0,0,529,529,57894,57894,57917,57917,57944,57944,0,529,57894,57917,57944,0,529,57894,57917,57944,0,529,57894,57917,57944,0,529,529,529,529,529,529,529,529,3710,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3720,529,529,529,529,529,3725,529,3727,0,0,0,0,131072,0,0,0,441,0,441,447,0,441,441,441,0,441,478,478,478,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,536,57902,536,57902,536,536,57902,536,536,57925,57902,536,536,57902,57902,57902,57925,57902,57902,57902,57902,57902,57902,57902,57925,57925,57902,57902,57952,57902,57902,57902,57902,57902,57902,57902,57952,57952,57902,57902,57902,57902,57952,57952,57902,536,57902,57902,57902,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,802,0,0,529,529,529,529,529,862,529,529,529,529,529,529,529,529,529,529,0,0,0,0,0,1285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,309,0,0,0,2421,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2496,529,2498,529,529,529,0,0,0,3207,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,3495,529,529,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3433,0,0,0,3437,0,0,0,0,0,3443,0,0,0,0,0,0,4268032,0,0,0,0,0,0,0,499712,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1323,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3471,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3488,529,529,529,529,529,529,529,529,529,529,529,529,529,3240,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,0,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,529,3525,529,529,529,60872,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60889,57894,57894,57894,57894,57894,57894,57894,57894,59911,57894,57894,57894,57894,59916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59393,57894,57894,57894,57894,57894,57894,57894,57894,59402,57894,57894,57894,57894,57894,57894,57894,57894,57894,60899,57894,57894,57894,57894,57894,57894,57894,57894,57894,60908,57894,57894,60911,57894,57894,57894,60914,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58984,57944,57944,57944,57944,57944,57944,57944,60950,57917,57917,60953,57917,57917,57917,60956,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60973,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,4089,0,4091,0,529,529,529,529,529,4096,529,529,529,529,529,529,529,529,529,529,529,529,3506,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1950,529,529,529,529,529,529,529,529,1959,529,529,529,57944,57944,57944,57944,57944,57944,57944,60983,57944,57944,57944,57944,57944,57944,57944,57944,57944,60992,57944,57944,60995,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3439,0,0,0,0,0,529,3705,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3717,529,529,529,529,529,529,529,3722,529,3724,529,529,529,0,0,0,0,57894,57894,57894,57894,57894,57894,59860,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59872,57894,57894,57894,57894,57894,57894,57894,2594,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60008,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,529,529,529,529,529,529,529,57894,57894,61076,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61088,57894,57894,57894,57894,57894,57894,57894,57894,60648,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,2597,57917,57917,57894,57894,57894,61094,57894,61096,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,61105,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58928,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58947,57917,57917,57917,57917,57917,57917,57917,57917,61117,57917,57917,57917,57917,57917,57917,57917,57917,61123,57917,61125,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,61134,57944,57944,57944,4081,0,4082,0,0,0,0,0,0,0,0,0,0,0,529,4093,529,4094,529,529,529,4098,529,529,529,529,529,529,529,0,0,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,3681,0,0,0,3836,0,0,0,0,0,0,0,0,0,0,0,3844,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2444,529,529,529,529,2449,529,529,3854,529,529,529,529,529,529,529,529,3860,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61216,57894,57894,57894,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,651,0,57917,57917,57917,61241,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61254,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,0,0,0,3681,0,3934,0,0,0,0,0,61260,57944,57944,57944,57944,57944,57944,57944,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,3850,529,529,57894,61627,61628,57894,57894,57917,57917,61631,61632,57917,57917,57944,57944,61635,61636,57944,57944,0,0,0,0,529,529,529,529,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,529,529,4279,4280,529,529,57894,0,0,0,0,0,690,691,0,0,0,0,696,0,0,0,368,368,368,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,548,57914,548,57914,548,548,57914,548,548,57937,57914,548,548,57914,57914,0,0,0,0,0,771,0,0,0,0,0,0,0,0,0,0,529,529,529,854,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3262,529,529,529,529,529,529,529,529,529,529,0,0,57894,57894,57894,57894,57894,529,529,529,529,913,57894,57894,57894,57894,58273,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58332,0,57917,57917,57917,57917,57917,57917,57917,59995,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59501,57917,57917,59504,57917,57917,57917,58349,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58408,0,0,0,0,57894,57944,57944,57944,57944,58424,57944,57944,57944,57944,57944,57944,57944,57944,57944,59046,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,58293,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,57917,57917,57917,57917,529,1409,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60308,57894,57894,57894,57894,60311,57894,57894,60313,57894,60314,57894,57894,57894,57894,57894,57894,57894,57894,57894,57944,57944,57944,59038,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60885,57894,57894,57894,57894,57894,57894,57894,57894,57894,57944,57944,57944,57944,57944,57944,57944,61265,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3847,529,529,529,529,529,529,529,3852,0,427,427,0,131072,427,0,0,0,427,0,448,0,0,0,0,427,336,479,479,479,492,492,492,492,492,492,492,492,492,492,512,520,520,520,520,520,520,527,520,520,520,527,520,520,520,520,520,520,537,57903,537,57903,537,537,57903,537,537,57926,57903,537,537,57903,57903,57903,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,841,0,0,529,529,529,529,529,864,529,529,529,529,529,529,529,529,529,529,57903,57926,57903,57903,57903,57903,57903,57903,57903,57926,57926,57903,57903,57953,57903,57903,57903,57903,57903,57903,57903,57953,57953,57903,57903,57903,57903,57953,57953,57903,537,57903,777,0,0,781,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,797,0,0,0,0,0,0,0,801,0,0,0,0,0,0,0,0,1254,0,0,0,0,0,0,0,0,0,0,0,1172,0,1174,0,0,0,0,0,0,0,0,0,0,0,1884,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,4026,529,4028,4029,529,4031,529,57894,57894,57894,57894,57894,57894,57894,57894,61385,57894,61387,61388,57894,0,0,0,0,837,797,0,0,837,0,0,0,0,0,0,0,529,529,529,529,857,529,866,529,529,529,529,529,529,529,529,529,529,529,529,1384,529,529,529,529,529,529,529,1393,529,529,1395,529,529,529,529,1400,529,529,529,529,529,529,529,914,57894,57894,57894,57894,57894,58276,57894,58285,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58333,0,57917,57917,57917,57917,57917,57917,57917,60023,57917,57917,57917,57944,57944,57944,57944,57944,57944,60032,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60044,57944,57944,57917,58352,57917,58361,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58409,0,0,0,0,57894,57944,57944,57944,57944,57944,58427,57944,58436,57944,57944,57944,57944,57944,57944,57944,57944,60743,57944,57944,57944,57944,57944,57944,57944,60749,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59054,57944,57944,57944,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,0,0,1249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,803,0,0,0,0,0,0,0,0,1311,0,0,0,0,0,0,0,0,1316,0,0,0,0,0,0,0,0,1326,0,0,0,0,0,0,0,0,0,0,0,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,344064,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,1412,529,529,1416,529,529,529,529,529,1423,529,529,529,1430,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61102,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58792,57894,57894,57894,57894,57894,57894,57894,57894,57894,58811,57894,57894,57894,57894,57894,57894,57894,57894,57894,58821,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59888,57894,57894,57894,59891,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60907,57894,57894,57894,57894,57894,57894,57894,57917,60915,57917,57917,57917,57917,57917,57917,57917,57917,58916,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58946,57917,57917,58950,57917,57917,57917,57917,57917,59449,57917,57917,57917,57917,57917,57917,57917,57917,57917,59461,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58931,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58957,57917,57917,57917,58964,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58981,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,57894,57894,0,0,0,0,0,3927,0,0,0,0,0,3681,0,0,0,3936,0,0,0,57944,59e3,57944,57944,57944,57944,57944,57944,57944,57944,57944,59010,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60752,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59041,57944,57944,59045,57944,57944,57944,57944,57944,59052,57944,57944,57944,59059,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58309,57894,57894,57894,57894,57894,57894,57894,0,57917,57917,57917,57917,0,1824,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1277,0,0,0,0,1848,1849,0,1851,0,0,0,0,0,0,0,0,0,0,0,0,0,1865,0,1867,0,0,0,0,0,0,0,0,0,0,0,1226,0,0,0,0,1231,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,734,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,1971,529,529,529,529,529,529,529,529,529,529,1981,1983,529,529,529,529,58776,0,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,57917,57917,57917,59946,57917,59948,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60678,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60691,57894,57894,57894,57894,57894,59414,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59425,59427,57894,57894,57894,57894,50679,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,58883,57917,57917,57917,58892,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59978,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,59610,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59621,59623,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,1221,0,0,0,0,0,1227,0,1229,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2383,0,0,0,0,0,0,0,0,0,0,2340,0,0,0,2343,0,0,0,0,0,2349,0,0,0,0,0,0,0,0,0,0,0,0,2359,0,0,0,0,0,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4857856,4874240,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5259264,2367,0,0,0,0,0,0,0,0,0,0,0,0,2375,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2358,0,0,0,0,0,0,0,0,2366,57894,57894,57894,59934,57894,57894,57894,0,0,0,0,57917,57917,57917,57917,57917,57917,59949,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59961,57917,57917,57917,57917,57917,59480,59481,59483,57917,57917,57917,57917,57917,57917,57917,59491,59492,57917,59494,57917,57917,59497,59498,57917,57917,57917,57917,57917,57917,57917,59506,57917,57944,57944,57944,57944,57944,57944,57944,60106,57944,57944,57944,2441,529,529,529,529,59872,57894,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,2791,0,0,0,0,0,0,0,0,0,0,0,2801,0,0,0,0,0,0,0,0,0,2807,0,0,0,0,0,0,2811,0,0,0,0,0,0,0,0,0,0,0,0,0,2824,0,0,0,0,0,0,0,2832,0,0,0,0,2834,0,0,0,0,0,0,0,0,0,0,0,0,0,2844,2845,0,0,2848,0,0,2851,0,0,0,0,0,0,0,0,0,0,3184,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1301,0,0,0,0,1306,0,0,0,0,0,0,2861,0,0,0,0,0,0,0,0,0,0,0,0,0,2871,0,0,0,0,529,2875,529,529,529,529,529,529,529,0,0,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,60289,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61225,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59528,57917,57917,57917,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,2934,529,529,529,529,529,529,0,0,0,0,0,0,57894,60284,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60654,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,0,57917,57917,57894,57894,60326,57894,57894,57894,57894,57894,57894,60333,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60342,57894,57894,57894,60345,57894,57894,57894,57894,57894,57894,57894,57894,57894,61100,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60410,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57917,57917,57917,60374,57917,57917,57917,57917,57917,57917,57917,60379,57917,57917,57917,57917,57917,57917,57917,60385,57917,57917,57917,57917,57917,57917,57917,60393,57917,57917,57917,57917,57917,57917,57917,60694,57917,57917,57917,57917,57917,57917,57917,60700,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,61248,57944,57944,57944,61251,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57917,57917,60400,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60409,57917,57917,57917,60412,57917,57917,57917,57917,57917,57917,57944,60416,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,3823,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3459,0,0,0,0,0,0,0,0,0,57944,57944,57944,57944,57944,57944,60450,57944,57944,57944,57944,57944,57944,57944,60458,57944,57944,57944,57944,57944,57944,60465,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60058,57944,57944,57944,57944,57944,57944,57944,57944,60065,57944,60067,57944,60070,57944,57944,57944,57944,57944,57944,60474,57944,57944,57944,60477,57944,57944,57944,57944,57944,57944,3137,529,529,529,529,60484,57894,57894,57894,57894,0,0,0,0,3145,0,0,0,0,0,0,0,0,0,1769,0,0,1772,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1790,0,0,0,0,0,3155,0,0,0,0,0,0,3159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3173,3174,0,0,0,0,0,0,1253,0,0,0,1258,0,0,0,0,0,0,0,0,0,1175,0,0,0,0,0,0,0,0,0,0,0,0,3214,0,0,0,0,0,0,0,0,0,0,0,0,0,3223,529,529,529,529,529,0,3205,0,0,0,0,3210,0,0,0,3212,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,3225,529,529,529,0,0,0,0,59854,57894,57894,57894,57894,57894,57894,57894,59862,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60653,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,0,57917,57917,529,529,529,3230,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3246,3247,529,529,529,529,3250,529,529,529,529,529,529,529,529,529,1382,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1987,58776,0,57894,57894,57894,57894,57894,57894,57894,529,529,529,529,529,3255,529,529,529,3258,529,3260,529,529,529,529,529,529,529,3264,529,529,529,529,529,0,0,57894,57894,57894,60616,57894,57894,57894,57894,57894,57894,60900,57894,57894,60902,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,60916,57917,57917,57917,57917,57917,57917,57917,57917,57917,61245,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,57894,57894,57894,57894,60621,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60637,60638,57894,57894,57894,57894,60641,57894,57894,57894,57894,57894,57894,57894,59350,59351,57894,57894,57894,57894,59358,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59373,57894,57917,60665,57917,57917,57917,57917,57917,60670,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60686,60687,57917,57917,57917,57917,60690,57917,57917,57917,57917,57944,57944,57944,57944,61543,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,529,529,529,529,4022,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,57894,61381,57894,57894,57894,57894,57894,57894,57894,57894,57894,58842,57894,57894,58849,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58863,57894,57894,57894,57894,57894,50679,58776,992,57944,57944,60714,57944,57944,57944,57944,57944,60719,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60735,60736,57944,57944,57944,57944,60739,529,529,529,57894,57894,57894,3423,0,0,3426,3427,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1840,0,0,0,0,0,1845,0,3468,0,0,0,0,3472,0,0,0,0,3477,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,3492,529,529,529,529,3496,529,529,529,529,529,529,529,3502,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3516,529,529,529,529,529,529,529,529,529,529,529,1383,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1405,57944,57944,61261,57944,57944,57944,57944,57944,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3845,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,3507,529,3509,529,529,529,529,529,529,3515,529,529,3517,529,529,529,529,529,529,0,0,0,0,3940,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61390,57894,61392,57917,57917,57917,57917,57917,57917,57917,57917,61401,57917,61403,61404,57917,61406,57917,61408,57944,57944,57944,57944,57944,57944,57944,57944,61417,57944,61419,61420,57944,57944,57944,57944,57944,57944,57944,57944,61340,57944,61342,57944,57944,57944,57944,57944,57944,529,57894,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,0,3183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,381,0,384,0,0,0,384,61422,57944,61424,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3955,529,57894,57894,57894,57894,57894,57894,57894,57894,529,529,4217,529,4218,529,529,529,57894,57894,57894,57894,57894,57894,61568,57894,61569,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,61576,57917,61577,57917,57917,57917,57917,57917,59516,59517,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60084,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59018,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57917,57917,57944,57944,57944,57944,57944,57944,61584,57944,61585,57944,57944,57944,57944,0,0,0,0,0,0,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61087,57894,57894,57894,57894,57894,57894,57894,57894,57917,57944,57944,57944,57944,0,0,529,529,57894,57894,57917,57917,57944,57944,4309,4310,61655,61656,61657,0,529,57894,57917,57944,0,529,57894,57917,57944,0,529,529,529,529,529,529,529,529,57894,57894,57894,57894,61517,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,61530,57917,57917,57917,57917,57917,57917,57917,57917,61244,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,2294,0,57904,57927,57904,57904,57904,57904,57904,57904,57904,57927,57927,57904,57904,57954,57904,57904,57904,57904,57904,57904,57904,57954,57954,57904,57904,57904,57904,57954,57954,57904,538,57904,57904,57904,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,1200,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,0,0,0,57894,57894,57894,57894,58836,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,0,408,0,0,0,0,0,0,0,0,0,0,0,0,0,0,408,0,0,0,0,0,0,0,384,0,139264,147456,0,408,0,0,0,131072,0,0,0,442,0,442,0,453,442,442,442,0,442,480,480,480,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,539,57905,539,57905,539,539,57905,539,539,57928,57905,539,539,57905,57905,57905,57928,57905,57905,57905,57905,57905,57905,57905,57928,57928,57905,57905,57955,57905,57905,57905,57905,57905,57905,57905,57955,57955,57905,57905,57905,57905,57955,57955,57905,539,57905,57905,57905,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,1228,0,0,0,0,0,0,0,0,1237,0,0,0,0,0,0,0,0,0,900,529,529,529,529,57894,57894,58262,57894,57894,57894,58278,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58319,57894,57894,57894,57894,0,57917,57917,58338,57917,57917,57917,57917,58878,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58909,58911,57917,57917,57917,57917,57917,57917,57917,57917,60405,57917,57917,57917,57917,57917,57917,57917,57917,60411,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61156,57944,57944,57944,57944,57917,57917,58354,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58395,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,58413,57944,57944,57944,58429,57944,57944,57944,57944,57944,57944,57944,57944,57944,60453,57944,57944,57944,57944,60457,57944,57944,57944,60462,57944,57944,57944,57944,57944,57944,57944,57944,60470,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60721,57944,57944,60725,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60734,57944,57944,57944,57944,57944,57944,57944,57944,57944,3922,529,61267,57894,0,0,0,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,0,0,0,1225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1246,0,1162,0,0,0,0,0,0,0,0,0,1169,1170,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,333,334,0,0,0,0,0,0,0,0,0,0,0,0,0,1252,0,0,0,0,0,0,0,0,0,1263,1264,0,0,0,0,0,1170,0,0,0,0,0,0,0,0,0,0,0,1259,0,0,0,0,0,0,1267,0,0,0,0,1271,0,0,0,0,0,0,0,0,0,0,0,1240,0,0,0,0,0,0,529,1341,529,529,529,529,529,529,529,529,529,529,1354,1361,529,529,529,529,529,529,529,529,529,529,529,1422,529,529,529,529,529,529,58776,916,57894,57894,57894,58782,57894,57894,57894,57894,57894,57894,57894,57894,57894,59886,57894,57894,57894,57894,57894,57894,57894,57894,59893,57894,59895,57894,59898,57894,57894,57894,57894,57894,57894,57894,57894,57894,58841,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58857,57894,57894,57894,57894,57894,57894,58868,57894,50679,58776,992,1374,529,1376,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1396,529,1398,529,529,529,529,529,529,529,529,529,1418,529,529,529,529,529,529,1429,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58789,57894,529,529,1411,529,529,529,529,529,529,529,529,529,529,529,1426,529,529,529,58776,916,57894,58779,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58844,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58861,57894,57894,57894,57894,57894,57894,50679,58776,992,57894,58793,58800,57894,57894,57894,57894,57894,57894,57894,57894,58813,57894,58815,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59362,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58835,57894,58837,57894,57894,57894,57894,57894,57894,57894,58850,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58865,57894,57894,57894,50679,58776,992,57917,58874,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58888,58895,57917,57917,57917,57917,57917,57917,57917,57917,58908,57917,58910,57917,57917,57917,57917,57917,57917,57917,57917,59996,57917,57917,57917,57917,57917,60002,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61127,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,59002,57944,59004,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59025,57944,59027,57944,57944,57944,0,0,0,0,0,0,0,0,0,4088,0,0,0,0,529,529,529,529,529,529,529,529,4099,529,4101,529,529,4103,529,57944,57944,57944,57944,59040,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59055,57944,57944,57944,529,1354,529,1411,529,529,58793,57894,57894,58850,57894,57894,57894,57894,57894,57894,57894,61313,57894,57894,57894,61316,57917,57917,57917,57917,61320,57917,57917,57917,57917,57917,57917,57917,57917,57917,61329,57917,57917,57917,61332,57944,57944,57944,57944,57944,59546,59547,57944,57944,57944,57944,59554,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59569,57944,57944,57944,57944,57944,57944,57944,57944,57944,60055,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59595,59596,57944,57944,57944,57944,57944,57944,57944,57944,0,0,2316,0,2317,0,0,0,0,0,0,0,0,2325,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3220,0,0,0,529,3224,529,529,529,529,57917,59991,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60003,57917,57917,57917,57917,57917,57917,57917,60009,57917,57917,57917,57917,57917,57917,57917,60015,57944,60074,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60086,57944,57944,57944,57944,57944,57944,57944,60092,57944,57944,57944,57944,57944,57944,57944,60098,57894,57894,57894,57894,60301,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60348,57894,57894,0,3152,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3165,0,0,0,0,0,0,0,0,0,0,0,0,2814,0,0,0,0,0,0,0,0,2822,0,0,0,2826,0,0,0,2830,0,0,529,529,3229,529,529,529,529,529,529,3237,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2468,529,529,529,529,529,529,529,529,529,57894,57894,57894,60620,57894,57894,57894,57894,57894,57894,60628,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59896,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57944,57944,57944,57944,57944,57944,57944,60718,57944,57944,57944,57944,57944,57944,60726,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,57894,4004,0,4006,0,0,0,0,0,3681,0,0,0,0,0,0,3470,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,890,529,529,3728,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60661,57894,0,0,57917,57917,529,529,4163,529,4165,529,529,529,57894,57894,57894,57894,57894,57894,57894,61519,57894,61521,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,61532,57917,61534,57917,57917,61581,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61083,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59915,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59927,57894,57894,57894,61626,57894,57894,57894,57894,57917,61630,57917,57917,57917,57917,57944,61634,57944,57944,57944,57944,0,0,0,0,529,529,529,529,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,529,4278,529,529,529,529,57894,342,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3176,0,0,0,0,131072,0,0,0,0,0,0,449,0,0,0,0,0,465,481,481,481,465,465,465,465,465,465,465,465,465,465,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,540,57906,540,57906,540,540,57906,540,540,57929,57906,540,540,57906,57906,57906,1,24578,3,155943,156283,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,1315,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2331,0,0,0,0,2335,0,0,0,0,57906,57929,57906,57906,57906,57906,57906,57906,57906,57929,57929,57906,57906,57956,57906,57906,57906,57906,57906,57906,57906,57956,57956,57906,57906,57906,57906,57956,57956,57906,540,57906,57917,57917,58355,57917,57917,58371,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,58430,57944,57944,57944,57944,57944,57944,57944,57944,57944,60480,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,328,403,0,0,0,0,0,0,0,0,0,0,328,0,0,0,0,0,0,0,0,58446,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1752,0,0,0,0,0,0,0,0,0,0,0,2790,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1839,0,0,0,0,0,0,0,0,0,0,1191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,0,0,0,0,0,0,0,3182,0,0,0,0,0,0,0,3188,0,3190,0,0,0,3194,0,0,0,0,0,3199,0,0,3202,0,0,0,0,0,1337,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,1355,529,529,529,529,529,529,529,529,529,529,529,529,1385,529,529,529,1389,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2921,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1946,529,529,529,529,529,1953,529,529,529,529,529,529,529,529,1962,529,529,529,529,1413,529,529,529,529,529,1421,529,529,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61226,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59462,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57894,58794,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59903,59904,58833,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58852,57894,57894,57894,57894,57894,58860,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,57917,58955,57917,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58983,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60746,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60730,57944,57944,60733,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59042,57944,57944,57944,57944,57944,59050,57944,57944,57944,57944,57944,57944,57944,529,1355,529,529,1720,529,58794,57894,57894,57894,59069,57894,57894,57894,57894,57894,57894,61097,57894,61099,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,61110,57917,57917,57917,57917,57917,57917,57917,57944,60957,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59022,57944,57944,57944,57944,57944,57944,57944,57944,1153,0,0,1730,0,0,0,0,1737,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1755,0,0,0,1758,0,0,0,0,0,0,1255,1829,0,0,0,0,1262,1262,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1166,1300,0,0,0,0,0,0,1307,0,1761,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1776,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,361,362,0,0,0,0,0,0,0,368,0,297,0,0,529,1931,529,529,529,529,529,529,529,529,1942,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1394,529,529,529,529,529,529,529,529,529,529,59374,57894,57894,57894,57894,57894,57894,57894,57894,59385,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,2091,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,59548,57944,57944,57944,57944,57944,57944,57944,57944,57944,59559,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59570,57944,57944,57944,57944,57944,57944,57944,57944,57944,60720,57944,60723,57944,57944,57944,57944,60728,57944,57944,57944,60731,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,3138,529,529,529,57894,60485,57894,57894,57894,0,0,3143,3144,0,0,0,0,0,0,57944,57944,57944,57944,57944,57944,59581,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60069,57944,57944,57944,57944,57944,529,529,529,529,529,2479,529,529,529,529,2484,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1952,529,529,529,529,529,529,529,529,529,529,57894,59880,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59929,57894,59964,57917,57917,57917,57917,59969,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,60047,57944,57944,57944,57944,60052,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60442,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,3429,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1781,0,0,0,0,0,0,0,0,0,0,529,529,529,3499,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2930,529,529,529,529,529,57917,57917,57917,60925,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59988,57917,57917,61092,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57894,57894,57894,57917,57917,57917,57917,61397,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,61413,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,57894,57894,0,0,0,3925,0,0,3928,0,0,0,0,3681,3933,0,0,0,0,0,0,57917,61580,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61588,0,0,0,0,0,0,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,61081,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61091,343,344,345,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,343,297,0,0,0,0,0,0,1286,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1212,368,368,0,0,1215,0,390,391,393,344,0,0,0,0,0,0,343,0,0,0,0,343,0,0,0,344,0,0,0,0,0,0,0,0,0,0,0,0,2867,2817,0,0,0,0,0,2872,0,0,0,529,529,529,529,529,529,529,2881,529,0,0,390,0,0,0,0,0,0,0,0,344,0,0,0,390,0,0,0,0,0,344,390,0,0,0,139264,147456,0,0,0,425,0,0,0,0,131072,0,436,343,0,0,0,0,454,0,0,0,343,0,482,482,482,482,498,498,498,498,498,498,498,498,498,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,541,57907,541,57907,541,541,57907,541,541,57930,57907,541,541,57907,57907,57907,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,1859,1860,0,1861,1862,0,0,0,0,0,0,0,0,0,0,0,1871,0,0,57907,57930,57907,57907,57907,57907,57907,57907,57907,57930,57930,57907,57943,57957,57943,57943,57943,57943,57943,57943,57943,57957,57957,57943,57943,57943,57943,57957,57957,57943,541,57907,715,0,717,0,0,0,0,0,0,0,725,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1868,0,0,0,0,0,0,0,0,0,0,0,815,0,798,0,0,817,0,668,0,794,0,0,0,0,0,817,794,0,817,815,0,0,829,0,0,0,664,832,0,794,0,0,0,0,0,838,0,0,0,0,798,664,842,0,529,845,529,529,529,861,529,529,877,529,529,529,529,891,529,529,529,0,0,0,2509,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59877,57894,529,529,909,529,529,57894,57894,58263,57894,57894,57894,58280,57894,57894,58296,57894,57894,57894,57894,58310,57894,57894,57894,57894,58328,57894,57894,0,57917,57917,58339,57917,57917,57917,57917,58959,57917,57917,57917,57917,0,58834,57944,57944,58970,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58997,57944,57944,57944,57944,57944,57944,57944,57944,60426,57944,57944,60429,60430,57944,57944,57944,57944,57944,60435,57944,60437,57944,57944,57944,57944,60441,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61145,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60463,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57917,57917,58356,57917,57917,58372,57917,57917,57917,57917,58386,57917,57917,57917,57917,58404,57917,57917,0,0,0,0,57894,57944,57944,58414,57944,57944,57944,58431,57944,57944,57944,57944,57944,57944,57944,57944,57944,60744,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60754,57944,57944,60757,57944,57944,60760,58447,57944,57944,57944,57944,58461,57944,57944,57944,57944,58479,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,303,0,0,0,0,0,0,1312,0,0,0,0,0,0,0,0,1318,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3193,0,0,0,0,0,0,0,3200,0,0,0,0,0,0,1336,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,1356,529,529,529,529,529,529,529,529,529,529,529,529,1386,529,529,529,529,1391,529,529,529,529,529,529,529,529,529,1399,529,529,529,1406,529,529,529,529,529,1380,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1404,57894,58795,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58819,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61236,57917,57917,57917,57917,57917,57944,59033,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,1717,529,1719,529,529,59066,57894,57894,59068,57894,57894,57894,57894,57894,57894,58838,57894,57894,57894,58845,58847,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58870,50679,58776,992,0,1762,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1779,0,0,1782,0,1784,0,0,0,0,0,0,0,0,0,0,1290,1291,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1181,0,0,0,0,0,0,0,0,529,529,529,529,1902,529,529,529,529,529,529,529,529,1913,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2897,529,529,529,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,59345,57894,57894,57894,57894,57894,57894,57894,57894,59356,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59428,57894,57894,57894,50679,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59445,57917,57917,57917,57917,57917,57917,57917,57917,59456,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59531,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59541,57944,57944,57944,57944,57944,57944,57944,57944,59552,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60439,57944,57944,57944,57944,57944,57944,57944,60444,57944,57944,57944,57944,57944,57944,57944,57944,59582,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,3655,529,57894,61002,57894,0,0,0,0,0,0,0,2399,0,0,0,0,0,0,0,0,0,0,0,0,0,2410,0,0,0,0,0,0,0,0,0,0,0,0,0,1885,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,0,0,0,0,0,529,529,529,2427,2428,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3248,529,529,529,529,529,529,529,529,529,529,529,2476,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2495,529,529,529,529,529,529,529,0,2938,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,60290,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58843,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,57894,57894,57894,57894,57894,59908,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59928,57894,57894,57894,57894,57894,57894,59349,57894,57894,57894,57894,57894,57894,57894,57894,57894,59361,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61237,57917,57917,57917,57917,57917,60017,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,60029,57944,60031,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60727,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,57944,60100,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,3160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,2783,0,2785,0,0,2788,0,0,0,0,0,0,2793,0,0,0,2796,0,0,0,0,0,0,0,0,0,0,0,0,0,2792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,401408,0,0,0,0,0,0,0,0,0,0,2806,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2820,0,2821,0,2823,0,0,0,0,0,0,0,0,0,0,0,2323,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2336,0,0,0,2857,0,0,0,0,0,2863,0,0,0,0,2866,0,0,0,0,0,0,0,0,0,2874,0,529,529,529,529,529,529,529,529,529,529,529,529,1912,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,58787,57894,57894,57894,529,529,529,529,529,2885,529,529,2888,2889,529,529,529,529,529,2894,529,2896,529,529,529,529,2900,529,529,529,529,529,529,529,529,529,529,529,529,2486,529,529,529,529,529,2490,2491,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2893,529,2895,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1945,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2463,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2906,529,529,529,529,529,529,529,529,2914,529,529,529,529,529,529,2922,529,529,529,529,529,2927,529,529,529,529,529,529,529,529,529,529,529,529,2918,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1919,529,529,529,529,529,529,529,529,529,529,529,529,60298,57894,57894,57894,57894,57894,60303,57894,60305,57894,57894,57894,57894,60309,57894,57894,57894,57894,57894,57894,57894,57894,57894,60315,57894,57894,57894,57894,57894,57894,57894,57894,57894,59912,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,2090,57917,57917,57917,57917,57917,57917,57917,57917,57894,60324,57894,57894,57894,57894,57894,57894,60332,57894,57894,57894,57894,57894,60337,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58818,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58853,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,57917,60372,57917,57917,57917,57917,60376,57917,57917,57917,57917,57917,57917,57917,57917,57917,60382,57917,57917,57917,57917,57917,57917,57917,57917,57917,60391,57917,57917,57917,57917,57917,57917,57917,57944,57944,60958,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60975,57944,57917,60399,57917,57917,57917,57917,57917,60404,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60036,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60447,57944,57944,57944,57944,57944,57944,57944,57944,57944,60456,57944,57944,57944,57944,57944,57944,60464,57944,57944,57944,57944,57944,60469,57944,57944,57944,57944,57944,529,529,3819,57894,57894,61165,3822,0,0,0,0,3826,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1176,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,3254,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3263,529,529,3266,529,529,3269,0,0,60614,57894,57894,57894,57894,57894,57894,57894,59382,57894,57894,57894,59387,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59395,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60646,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60656,57894,57894,60659,57894,57894,60662,0,0,60663,57917,57917,57917,57917,59448,57917,57917,57917,57917,59454,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59465,57917,57917,57917,57917,59469,57917,57917,57917,57917,57917,57917,57917,57917,60695,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60705,57917,57917,60708,57917,57917,60711,60712,3417,529,529,60764,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3434,3435,0,0,0,0,3440,0,0,0,0,0,0,0,0,1288,0,0,0,0,1293,0,0,0,0,1296,0,0,0,0,0,0,0,0,0,0,0,0,1308,529,529,529,529,529,57894,57894,60874,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60891,57894,60893,57894,57894,57894,57894,57894,57894,61222,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61235,57917,57917,57917,57917,57917,57917,57917,57917,59971,57917,59973,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60414,57917,57917,57917,57944,57944,57944,57944,57944,57944,60420,60977,57944,57944,57944,57944,57944,57944,57944,60984,57944,57944,60986,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,0,0,3827,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1175,0,0,0,0,1180,0,0,0,0,0,0,0,0,0,3661,0,3663,0,0,0,3667,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,3226,529,529,529,529,529,529,529,3708,3709,529,529,529,529,3713,3714,529,529,529,529,529,3718,529,529,529,529,529,529,529,3723,529,529,529,529,529,529,529,529,1939,529,529,529,1944,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2925,529,529,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,57894,61095,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,61108,61109,57917,57917,57917,57917,61113,61114,57944,57944,61137,61138,57944,57944,57944,57944,61142,61143,57944,57944,57944,57944,57944,61147,57944,57944,57944,57944,57944,57944,57944,57944,61153,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60987,57944,60989,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3681,0,3834,0,0,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2439,529,529,2443,529,529,529,2447,529,529,529,529,529,3855,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61217,57894,57894,57894,57894,57894,57894,59380,59381,59383,57894,57894,57894,57894,57894,57894,57894,59391,59392,57894,59394,57894,57894,59397,59398,57894,57894,57894,57894,57894,57894,57894,59406,57894,57894,57894,61309,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61325,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,60963,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60976,57894,57894,57894,57917,57917,61395,57917,57917,57917,57917,61400,57917,57917,57917,57917,61405,57917,57917,57917,57944,57944,61411,57944,57944,57944,57944,61416,57944,57944,57944,57944,61421,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,529,529,529,4252,4253,529,529,57894,57894,57894,61602,61603,57894,57894,57894,57917,57917,57917,61608,61609,57917,57917,57917,57944,57944,57944,61614,61615,57944,57944,57944,0,0,0,0,0,529,529,529,529,529,529,57894,57894,57894,57894,57894,60877,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59353,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59371,59372,57894,57894,57917,57944,57944,57944,57944,0,0,529,529,57894,57894,57917,57917,57944,57944,0,529,57894,57917,57944,0,529,57894,57917,57944,4319,4320,61665,61666,61667,0,529,529,529,529,529,529,529,529,61565,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61573,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58385,57917,57917,57917,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,346,347,348,349,350,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,297,0,0,0,0,0,0,1313,0,0,0,0,0,0,0,0,0,1319,1280,0,1303,1322,0,1325,0,0,1239,0,0,0,0,0,1333,0,0,1216,1333,1340,529,529,529,529,1346,529,529,529,529,1352,529,529,529,529,529,529,529,529,529,529,1373,0,0,0,0,0,394,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,516096,0,0,0,0,0,350,131072,348,0,350,349,348,349,0,348,349,349,349,459,466,483,483,483,494,494,494,494,501,494,494,501,501,501,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,542,57908,542,57908,542,542,57908,542,542,57931,57908,542,542,57908,57908,57908,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,647,0,0,0,0,652,57908,57931,57908,57908,57908,57908,57908,57908,57908,57931,57931,57908,57908,57958,57908,57908,57908,57908,57908,57908,57908,57958,57958,57908,57908,57908,57908,57958,57958,57908,542,57908,653,654,655,656,657,658,0,0,0,0,0,0,0,0,0,0,0,0,0,0,673,674,0,676,677,0,0,0,0,0,683,0,0,0,0,0,0,4268782,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2828,0,0,0,0,0,716,0,0,719,0,721,0,723,0,0,0,0,0,0,0,0,0,0,0,735,0,0,0,0,0,0,0,0,0,0,0,0,3186,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,3489,529,529,529,529,529,529,529,529,0,0,0,0,783,784,0,786,787,0,0,0,0,786,0,0,793,0,0,0,0,0,0,0,0,0,800,0,0,0,0,0,0,0,0,0,1801,0,0,0,0,0,0,0,0,0,0,0,1813,0,0,0,0,0,0,0,0,0,0,0,304,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,313,312,0,0,0,312,312,313,313,811,0,0,692,0,0,0,786,0,0,0,0,0,0,0,0,767,823,0,0,0,0,0,0,827,699,0,0,831,0,0,0,0,0,0,0,3474,3475,0,0,0,0,3480,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,3949,529,3951,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,833,0,0,0,692,699,0,0,692,831,831,0,0,0,0,0,529,529,851,855,858,529,867,529,529,529,883,885,888,529,529,529,0,0,0,0,57894,57894,57894,57894,59858,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59921,57894,57894,57894,57894,59925,57894,57894,57894,57894,57894,59930,901,905,529,529,529,57894,57894,57894,58270,58274,58277,57894,58286,57894,57894,57894,58302,58304,58307,57894,57894,57894,58320,58324,57894,57894,57894,0,57917,57917,57917,58346,58350,58353,57917,58362,57917,57917,57917,58378,58380,58383,57917,57917,57917,58396,58400,57917,57917,57917,0,0,0,0,58411,57944,57944,57944,58421,58425,58428,57944,58437,57944,57944,57944,57944,57944,57944,57944,57944,61484,57944,61486,57944,57944,61488,57944,57944,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,1348,529,529,529,529,529,1360,529,529,529,529,529,529,529,529,57944,57944,58453,58455,58458,57944,57944,57944,58471,58475,57944,57944,57944,851,1142,529,901,905,1146,0,58491,58270,57894,58320,58324,58496,155943,1153,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1748,1749,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,0,0,0,0,0,0,262144,262144,262144,0,0,0,0,0,0,0,0,0,1189,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1202,0,0,0,0,0,0,0,0,0,0,0,368,368,1213,0,0,0,0,0,0,1798,0,0,0,0,0,0,0,0,0,0,0,0,1811,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3187,0,0,0,0,3192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3215,0,0,3218,0,0,0,0,0,0,0,3222,529,529,529,529,529,529,529,529,529,1378,529,529,529,1381,529,529,529,529,529,529,529,1388,529,529,1392,529,529,529,529,529,529,529,529,529,529,529,1403,529,529,529,529,529,529,529,1417,529,529,529,529,529,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61459,57894,57894,61461,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61473,57917,57917,61475,57917,529,1410,529,529,529,529,529,529,529,529,529,529,1424,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60335,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60346,57894,57894,57894,57894,57894,57917,57917,57917,58958,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61150,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59006,57944,57944,57944,59009,57944,57944,57944,57944,57944,57944,57944,59016,57944,57944,59020,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,2777,0,0,0,0,59032,57944,57944,59039,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59053,57944,57944,57944,57944,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60884,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58814,58816,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60631,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59919,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,1792,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1819,0,0,0,0,0,0,0,0,1853,0,0,0,0,0,0,1751,0,0,0,0,0,0,0,0,0,0,1869,1870,0,0,0,1873,0,0,0,1826,0,1828,0,0,0,1830,0,748,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5627904,0,0,0,1876,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1760,0,0,0,0,0,0,529,1895,529,529,529,0,0,0,0,57894,57894,57894,59857,57894,59859,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,61229,57917,57917,57917,61232,57917,57917,57917,57917,57917,57917,57917,57917,57917,529,529,529,1901,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1923,529,529,529,529,529,529,529,529,529,529,529,1943,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1984,529,529,529,58776,0,57894,57894,57894,57894,57894,57894,57894,529,529,1932,529,529,529,1936,529,529,1941,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3267,529,529,0,0,57894,57894,57894,57894,57894,57894,57894,59344,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59366,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60903,57894,60905,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59974,57917,57917,57917,57917,57917,57917,59979,57917,59981,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61247,57944,57944,57944,57944,57944,57944,57944,61252,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,2775,2295,0,2776,2298,0,0,0,0,0,0,57894,59375,57894,57894,57894,59379,57894,57894,59384,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60658,57894,57894,57894,57894,0,0,57917,57917,57917,59444,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59466,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58387,57917,57917,57917,57917,58405,57917,57917,0,0,0,0,57894,57944,57944,58415,57944,57944,57944,57944,57944,57944,59475,57917,57917,57917,59479,57917,57917,59484,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60707,57917,57917,57917,57917,57944,57944,57944,59575,57944,57944,59580,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59026,57944,57944,57944,57944,0,0,2296,0,1157,0,0,0,0,2299,0,1162,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1187,0,2474,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1407,57894,57894,57894,59906,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,0,57917,57917,57944,57944,57944,57944,57944,57944,57944,60078,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,3654,529,529,61001,57894,57894,0,0,0,0,0,2808,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2831,0,0,0,0,0,0,4785119,991,991,991,4850655,991,991,991,991,991,4916191,991,4957151,4973535,991,991,991,991,991,991,5071839,991,991,991,991,991,991,991,991,991,0,915,4359059,4359059,4359059,4359059,4359059,4858771,4875155,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,4359059,5260179,529,529,529,529,2937,529,529,0,0,0,2939,0,1990,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60632,57894,57894,60635,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,0,0,3006,0,2090,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58913,57917,57917,57917,57917,60713,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60737,57944,57944,57944,57944,57944,57944,57944,57944,57944,60080,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60466,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,3425,0,0,0,0,0,0,0,0,0,3431,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,368,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2409,0,0,0,0,0,0,0,0,0,0,0,2419,0,0,3662,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1822,0,61306,57894,57894,57894,57894,57894,61312,57894,57894,57894,57894,57917,57917,57917,61318,57917,57917,57917,57917,61322,57917,57917,57917,57917,57917,61328,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,0,4212,0,529,529,529,529,57944,61334,57944,57944,57944,57944,61338,57944,57944,57944,57944,57944,61344,57944,57944,57944,57944,529,57894,0,0,0,0,0,0,0,0,3681,0,4011,0,0,0,0,0,0,1879,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1865,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,4032,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61103,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58897,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58930,57917,58932,57917,57917,57917,57917,57917,57917,57917,58945,57917,57917,57917,57917,57917,57917,57894,57894,57894,57917,57917,57917,57917,57917,61398,57917,57917,57917,61402,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,61414,57944,57944,57944,61418,57944,57944,57944,0,0,0,0,0,0,0,4086,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,4100,529,529,529,529,529,529,529,529,529,529,3238,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3251,529,529,529,529,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,4247,0,4249,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,61079,61080,57894,57894,57894,57894,61084,61085,57894,57894,57894,57894,57894,61089,57894,57894,57894,57894,57917,57944,57944,57944,57944,0,0,529,529,57894,57894,57917,57917,57944,57944,0,529,57894,57917,57944,4314,4315,61660,61661,61662,0,529,57894,57917,57944,0,529,529,529,529,529,529,529,1906,529,529,529,529,529,529,529,529,529,1918,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3863,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58817,57894,57894,57894,58820,57894,57894,57894,57894,57894,57894,57894,58827,57894,57894,58831,57894,57894,0,0,392,0,0,0,396,392,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3462,0,0,0,0,0,351,0,410,0,0,0,0,0,0,0,0,0,0,0,0,410,0,0,0,0,0,0,410,0,351,0,139264,147456,0,0,0,0,0,0,0,0,2320,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2333,0,0,0,0,0,0,0,0,0,0,3451,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2332,0,0,0,0,0,0,0,0,0,0,0,131072,0,437,0,0,0,0,450,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,508,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,543,57909,543,57909,543,543,57909,543,543,57932,57909,543,543,57909,57909,57932,57909,57909,57909,57909,57909,57909,57909,57932,57932,57909,57909,57959,57909,57909,57909,57909,57909,57909,57909,57959,57959,57909,57909,57909,57909,57959,57959,57909,624,57909,57975,57975,57975,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,3671,3672,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,385024,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,529,529,910,529,529,57894,57894,58264,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58311,57894,57894,57894,57894,58329,57894,57894,0,57917,57917,58340,57917,57917,57917,57917,59514,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59525,59527,57917,57917,57917,57917,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59011,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59591,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58462,57944,57944,57944,57944,58480,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1746,1747,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1169,1170,0,0,0,0,0,0,1302,0,0,0,0,0,0,57894,58796,57894,57894,57894,57894,58806,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58822,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61224,57894,57894,57894,57894,57917,57917,57917,57917,57917,61230,57917,57917,57917,61234,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58877,57917,57917,57917,57917,57917,57917,57917,57917,57917,58891,57917,57917,57917,57917,58901,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58398,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57917,57917,58917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58939,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,58976,57944,57944,57944,57944,57944,58988,57944,57944,57944,57944,57944,57944,57917,57917,58956,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,58971,57944,57944,57944,57944,57944,57944,57944,57944,57944,58985,57944,57944,57944,57944,58995,57944,57944,57944,57944,57944,57944,57944,57944,57944,60985,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3830,0,3831,0,0,0,0,57944,59034,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59051,57944,57944,57944,57944,57944,57944,529,1357,529,529,529,529,58796,57894,57894,57894,57894,57894,57894,57894,57894,61223,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,61231,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60931,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60941,57917,57917,57917,57917,57917,57917,57917,57917,57917,1153,0,0,1731,0,0,0,0,1738,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1183,0,0,0,0,0,0,0,0,0,0,1764,0,0,0,0,0,0,0,0,0,0,0,0,1777,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1277,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2353,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,57895,529,57895,529,529,57895,529,529,57918,57895,529,529,57895,57895,1823,0,0,0,0,0,0,0,1259,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1211,0,368,368,0,1214,0,0,1732,0,0,0,0,0,0,1739,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2315,0,0,0,0,0,0,6463488,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4931584,4939776,0,0,0,0,0,0,5054464,0,0,0,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60368,57917,57917,57917,57917,57917,59994,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60007,57917,57917,57917,57917,57917,60011,60012,60013,57917,57917,57917,57917,57917,57917,57917,59518,57917,57917,57917,57917,57917,57917,59524,57917,57917,57917,57917,57917,57917,57894,57944,57944,57944,57944,57944,59536,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60428,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61148,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,2454,529,529,529,529,529,529,2459,529,2461,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2924,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2912,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,0,0,57894,57894,57894,57894,57894,0,0,2597,0,0,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58912,57917,57917,57917,58915,57917,3939,0,0,0,0,0,529,3942,529,529,3944,529,529,529,529,529,529,529,529,529,529,529,529,529,57894,61301,57894,57894,61303,57894,57894,57894,1,24578,3,155943,156283,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1886,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,57944,57944,61335,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,57894,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,0,2347,2348,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2312,0,0,0,0,0,0,0,4015,0,4017,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,749,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1872,0,57917,57917,58357,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,58432,57944,57944,57944,57944,57944,57944,57944,57944,57944,61341,57944,57944,57944,57944,57944,57944,57944,529,57894,0,4005,0,0,4008,0,0,0,3681,0,0,0,0,0,0,0,0,1310,0,529,529,1342,529,1345,529,529,529,529,529,529,529,529,1359,529,1364,529,529,1368,529,529,1371,0,1163,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,221654,221654,529,529,529,2909,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,0,0,57894,57894,57894,57894,60617,57944,57944,57944,57944,57944,57944,57944,60451,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59597,57944,57944,59600,57944,57944,57944,57944,57917,61116,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60969,57944,57944,57944,57944,57944,57944,57944,0,0,0,353,131072,0,0,353,399,0,399,0,0,399,399,399,353,399,0,0,0,399,399,399,399,399,502,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,399,544,57910,544,57910,544,544,57910,544,544,57933,57910,544,544,57910,57910,57910,57933,57910,57910,57910,57910,57910,57910,57910,57933,57933,57910,57910,57960,57910,57910,57910,57910,57910,57910,57910,57960,57960,57910,57910,57910,57910,57960,57960,57910,544,57910,57910,57910,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,245760,245760,245760,245760,245760,245760,245760,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,342,0,0,813,814,0,0,0,0,0,0,768,0,0,819,0,0,665,0,0,0,819,0,0,0,0,0,0,0,0,0,0,0,0,212992,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,675,0,0,0,0,0,0,0,0,0,0,834,0,0,0,0,0,0,814,0,0,0,0,0,0,0,529,529,852,529,529,529,868,872,529,529,529,529,529,893,895,529,529,529,529,529,529,529,1937,1938,1940,529,529,529,529,529,529,529,1948,1949,529,1951,529,529,1954,1955,529,529,529,529,529,529,529,0,0,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60295,57894,57894,529,906,529,529,529,57894,57894,58265,58271,57894,57894,57894,58287,58291,57894,57894,57894,57894,57894,58312,58314,57894,57894,58325,57894,57894,57894,0,57917,57917,58341,58347,57917,57917,57917,58363,58367,57917,57917,57917,57917,57917,58388,58390,57917,57917,58401,57917,57917,57917,0,0,0,0,57894,57944,57944,58416,58422,57944,57944,57944,58438,58442,57944,57944,57944,57944,57944,58463,58465,57944,57944,58476,57944,57944,57944,852,529,895,529,906,529,0,57894,58271,58314,57894,58325,57894,155943,1153,0,303,0,0,0,0,0,0,2786,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2798,0,0,0,0,0,2802,0,0,0,0,0,0,0,0,661,662,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1817,0,0,0,0,0,0,0,0,0,1218,0,1220,0,1222,0,0,0,0,0,0,0,0,0,0,0,0,0,1236,0,1238,0,0,0,0,0,0,1245,0,0,0,0,0,307,0,0,0,0,0,0,0,0,0,0,0,0,307,0,0,0,0,0,0,307,237985,147456,0,0,0,307,1,24578,3,0,0,4366336,0,0,0,0,0,65536,304,0,4268032,98304,308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,663,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1278,0,0,0,0,0,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,0,307,0,0,0,0,0,0,0,0,0,0,0,0,1171,1172,1173,1174,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,415,0,0,0,0,0,0,415,139264,147456,0,0,0,424,0,0,1335,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2446,529,529,529,529,529,1375,1377,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1401,529,529,529,0,0,2508,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59870,57894,57894,59874,57894,57894,57894,59878,529,529,529,529,529,1415,529,529,529,529,529,529,529,529,1427,1428,529,529,58776,916,57894,57894,57894,57894,58783,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,57917,57917,59945,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60681,57917,57917,60684,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,59003,59005,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59030,57944,57944,57944,57944,57944,57944,57944,59044,57944,57944,57944,57944,57944,57944,57944,57944,59056,59057,57944,57944,529,529,1718,529,529,1721,57894,57894,59067,57894,57894,59070,0,1847,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1794,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1810,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,368,0,0,0,0,0,0,0,0,0,0,0,0,713,0,529,1899,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1924,529,529,529,529,529,529,529,0,2938,0,0,0,0,57894,57894,57894,60286,57894,60287,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59357,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58856,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,529,1964,529,529,529,1970,529,529,529,529,529,529,529,529,529,1979,529,529,529,529,1985,529,529,58776,0,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,57917,59944,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59530,57917,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59342,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59367,57894,57894,57894,57894,57894,57894,57894,0,0,0,0,59943,57917,57917,57917,57917,57917,57917,57917,59951,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59457,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60683,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59407,57894,57894,57894,59413,57894,57894,57894,57894,57894,57894,57894,57894,57894,59423,57894,57894,57894,57894,59429,57894,57894,50679,0,57917,57917,57917,57917,57917,57917,57917,59442,57917,57917,57917,59513,57917,57917,57917,57917,57917,57917,57917,57917,57917,59523,57917,57917,57917,57917,59529,57917,57917,57894,57944,57944,57944,57944,57944,57944,57944,59538,57944,57944,57944,57944,57944,57944,57944,57944,57944,61485,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,2429,529,529,529,529,529,529,529,529,529,529,529,2441,529,529,529,529,529,529,529,529,529,57944,57944,59609,57944,57944,57944,57944,57944,57944,57944,57944,57944,59619,57944,57944,57944,57944,59625,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,2809,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,418,418,0,0,0,0,2394,0,2396,2397,2398,0,2400,0,0,0,0,0,0,0,0,0,0,2408,0,0,0,0,2413,2414,0,0,0,0,0,2418,0,0,0,0,0,0,2836,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,347,0,0,0,0,0,0,0,0,0,0,2424,529,529,529,529,529,529,2431,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2466,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2455,529,529,529,529,529,529,529,529,2462,529,2464,529,2467,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3508,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1982,529,529,529,529,529,58776,0,57894,57894,57894,57894,57894,57894,57894,529,2475,529,529,529,529,529,2481,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3268,529,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,59907,57894,57894,57894,57894,57894,59913,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58859,57894,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,0,2781,2782,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1276,0,0,0,0,0,0,2833,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2847,0,0,0,0,0,0,0,0,0,0,0,354,355,356,0,0,0,0,0,0,0,0,0,0,0,0,0,368,0,297,0,0,529,529,529,529,529,529,2886,529,529,529,529,529,2891,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2898,529,529,529,529,529,529,529,2903,529,529,529,529,529,2907,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3726,529,57894,57894,57894,60300,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60316,57894,57894,57894,57894,57894,57894,57894,0,0,0,2598,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61131,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,60448,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60072,57944,57944,0,3178,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,352256,352256,529,3228,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,0,0,57894,60615,57894,57894,57894,60618,57894,60619,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59902,57894,57894,57917,57917,57917,60667,57917,60668,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59986,57917,57917,57917,57917,57917,57944,57944,57944,57944,60716,57944,60717,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60093,57944,57944,57944,57944,60097,57944,57944,0,0,0,3445,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1331,0,0,0,529,529,529,529,529,57894,60873,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59900,57894,57894,57894,57894,57894,57894,57944,57944,57944,61336,57944,57944,57944,57944,57944,57944,57944,57944,57944,61345,57944,57944,57944,529,57894,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,0,2402,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,678,0,0,0,0,0,0,57894,57894,57894,57894,57894,61453,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,61467,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58884,57917,57917,57917,57917,57917,57917,58899,57917,57917,57917,58904,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60026,57944,57944,57944,57944,57944,57944,57944,60034,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,303,307,0,0,0,0,0,0,0,0,57944,57944,57944,57944,57944,61481,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,0,0,0,4155,0,529,529,529,529,529,529,529,529,529,1419,529,529,529,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,58788,57894,57894,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,4245,0,0,0,0,529,529,529,529,529,4254,529,57894,57894,57894,57894,57894,57894,57894,59885,57894,57894,57894,57894,57894,57894,59890,57894,59892,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61462,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61476,57894,61604,57894,57894,57917,57917,57917,57917,57917,61610,57917,57917,57944,57944,57944,57944,57944,61616,57944,57944,0,0,4275,0,4277,529,529,529,529,529,529,57894,57894,57894,57894,60876,57894,57894,57894,57894,60880,57894,57894,57894,57894,57894,57894,57894,60886,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60649,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,3005,0,57917,57917,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,0,0,4295,0,529,529,529,529,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,4276,0,529,529,529,529,529,529,57894,354,0,0,0,0,0,397,398,400,401,0,0,0,0,0,0,0,0,0,0,0,400,401,0,0,406,0,0,0,0,0,371,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,379,0,0,0,0,371,0,388,0,379,409,0,400,401,0,0,371,0,0,354,0,0,0,371,0,412,414,0,371,401,0,0,371,379,0,139264,147456,401,412,0,0,0,131072,0,438,0,443,0,443,0,414,443,443,443,0,467,0,0,0,495,495,495,495,495,495,495,495,495,495,516,516,516,516,516,516,516,528,516,516,516,528,516,516,516,516,516,516,545,57911,545,57911,545,545,57911,545,545,57934,57911,545,545,57911,57911,57934,57911,57911,57911,57911,57911,57911,57911,57934,57934,57911,57911,57961,57911,57911,57911,57911,57911,57911,57911,57961,57961,57911,57911,57911,57911,57961,57961,57911,625,57911,57976,57976,57976,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,644,0,0,0,0,0,0,0,0,0,0,682,0,0,0,0,0,0,681,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2794,2795,0,2797,0,2799,0,0,0,0,0,0,0,0,2804,529,529,529,529,529,57894,57894,58266,57894,57894,57894,57894,57894,57894,58297,58299,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,57917,57917,58342,57917,57917,57917,57917,59515,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59526,57917,57917,57917,57917,57917,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58484,529,529,529,529,1145,914,0,57894,57894,57894,57894,58495,58333,155943,1153,0,0,0,0,58448,58450,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,155943,1153,0,0,0,0,0,0,0,0,0,0,0,1742,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,3491,529,529,529,529,529,529,0,0,0,0,0,1164,0,0,1166,0,0,0,0,0,0,0,0,0,0,0,0,1179,0,0,0,0,0,0,0,0,0,0,0,648,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3716,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3243,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,0,0,0,0,0,1312,1338,1339,0,1312,529,529,529,529,529,529,1347,529,529,529,1351,529,529,1362,529,529,1366,529,529,529,529,529,529,529,529,529,1420,529,529,529,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58846,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,58776,992,57894,57894,58801,57894,57894,58805,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58824,57894,57894,57894,58828,57894,57894,57894,57894,57894,57894,57894,60331,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60639,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,58919,57917,57917,57917,58923,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58943,57917,57917,57917,57917,57917,57917,57917,0,1793,0,1795,0,0,0,1799,0,0,0,1803,0,0,0,1807,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3486,0,529,529,529,529,529,529,529,529,529,529,57944,57944,57944,57944,57944,57944,57944,59549,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59567,59568,57944,57944,57944,57944,57944,529,3818,529,57894,61164,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1816,0,0,0,0,0,0,0,0,0,0,0,0,2318,0,2319,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2334,0,0,0,0,0,0,0,0,0,1855,0,1857,0,0,0,0,0,0,0,1864,0,0,0,0,0,0,0,0,0,0,0,0,0,312,411,313,0,0,0,0,0,0,313,416,0,0,139264,147456,0,0,0,0,0,0,0,0,0,1259,0,0,0,0,0,0,0,0,0,0,2378,0,0,0,0,0,0,0,0,0,0,2389,0,0,0,0,0,0,0,0,2838,0,0,0,0,0,2842,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2856,2420,0,0,2423,0,529,529,2426,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,0,57894,57894,57894,57894,57894,57894,57894,57917,57917,59992,59993,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60004,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58889,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61129,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,60016,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,60028,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59626,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,57944,57944,60075,60076,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60087,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61490,0,0,4149,4150,0,0,0,0,0,0,0,529,529,529,4160,529,60099,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,2768,2769,57894,57894,57894,60117,60118,0,0,1732,0,0,1739,0,0,0,0,0,0,0,0,0,1882,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,863,529,529,529,529,529,529,529,529,529,529,529,529,2908,529,529,529,529,529,529,529,529,529,529,2919,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,61210,57894,57894,57894,61213,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60329,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60347,57894,57894,57894,57944,57944,57944,57944,57944,60449,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60461,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61146,57944,57944,57944,57944,57944,57944,57944,57944,61152,57944,61154,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,3256,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,0,2508,57894,57894,57894,57894,57894,57894,57894,57894,61314,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61330,57917,57917,57944,57944,57894,57894,61308,57894,61310,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61324,57917,61326,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,61545,57944,61547,57944,57944,57944,57944,0,0,0,0,0,0,0,0,0,0,4214,529,529,529,61449,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61463,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59488,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60384,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60396,57917,61477,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,4152,0,0,0,0,529,529,529,529,529,529,529,529,529,1974,529,529,529,529,529,529,1980,529,529,529,529,529,529,58776,1989,57894,57894,57894,57894,57894,59340,57894,529,529,529,529,529,4166,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61522,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59455,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60387,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,61535,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61548,57944,57944,57944,0,4208,0,0,0,0,0,0,0,0,529,529,4215,529,529,529,529,529,529,529,1972,1973,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,0,57894,57894,57894,57894,57894,57894,57894,0,0,2597,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59959,57917,57917,59963,4216,529,529,529,529,529,529,529,57894,57894,61566,57894,61567,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,61574,57917,61575,57917,57917,57917,57917,57917,57917,57917,57917,60671,57917,60674,57917,57917,57917,57917,60679,57917,57917,57917,60682,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,6e4,57917,57917,57917,57917,60005,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59489,57917,57917,57917,57917,57917,59496,57917,57917,57917,57917,57917,57917,57917,57917,59505,57917,57917,57917,57917,57944,57944,61582,57944,61583,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,58279,57894,57894,58295,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,57917,57917,57917,57917,413,0,0,0,131072,0,357,0,0,0,0,0,359,0,0,0,0,0,484,484,484,0,0,0,0,0,0,0,0,0,0,517,521,521,521,521,521,517,521,521,521,517,521,521,521,521,521,521,546,57912,546,57912,546,546,57912,546,546,57935,57912,546,546,57912,57912,57935,57912,57912,57912,57912,57912,57912,57912,57935,57935,57912,57912,57962,57912,57912,57912,57912,57912,57912,57912,57962,57962,57912,57912,57912,57912,57962,57962,57912,626,57912,57977,57977,57977,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,645,0,0,0,0,0,0,0,0,0,0,1856,0,0,0,0,0,0,0,1863,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,341,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2329,0,0,0,0,0,0,0,0,0,0,0,0,0,687,688,0,0,0,0,0,0,0,0,0,0,0,368,368,368,0,0,0,0,0,0,0,0,709,0,0,0,0,0,0,0,0,0,2321,2322,0,2324,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2338,0,0,0,0,796,0,0,0,0,0,0,0,0,645,0,0,796,529,848,529,529,529,529,869,873,879,529,884,529,529,529,529,529,529,529,529,529,2458,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3719,529,529,529,529,529,529,529,529,529,902,529,529,529,529,57894,57894,58267,57894,57894,57894,57894,58288,58292,58298,57894,58303,57894,57894,57894,57894,57894,58321,57894,57894,57894,57894,0,57917,57917,58343,57917,57917,57917,57917,59968,57917,59970,57917,57917,57917,57917,57917,57917,57917,59976,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59493,57917,57917,57917,57917,57917,57917,57917,57917,59502,57917,57917,57917,57917,57917,57917,57917,57917,58364,58368,58374,57917,58379,57917,57917,57917,57917,57917,58397,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,58418,57944,57944,57944,57944,58439,58443,58449,57944,58454,57944,57944,57944,57944,57944,58472,57944,57944,57944,57944,529,529,529,902,529,529,0,57894,57894,57894,58321,57894,57894,155943,1153,0,303,0,0,0,0,0,0,3181,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,3227,307,0,0,0,0,0,0,0,0,1167,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1184,0,0,0,0,0,0,0,0,3211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,870,529,529,529,529,529,889,529,529,529,1216,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1239,0,0,0,0,0,0,0,0,0,0,1883,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,4024,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,61383,57894,57894,57894,57894,57894,57894,1280,0,0,0,0,0,0,0,0,1289,0,0,0,0,0,0,0,0,0,1297,0,0,1167,0,0,0,1303,0,1305,0,0,0,0,0,0,0,3686,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3699,3700,0,0,0,0,529,529,4020,529,529,529,529,4025,529,529,529,529,4030,529,529,57894,57894,61379,57894,57894,57894,57894,61384,57894,57894,57894,57894,61389,1408,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1431,58776,916,58778,57894,57894,57894,57894,57894,58785,57894,57894,57894,57894,58791,58873,57917,57917,57917,57917,57917,58880,57917,57917,57917,57917,58886,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58907,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,58975,57944,57944,57944,58979,57944,57944,58990,57944,57944,58994,57944,57944,57944,57917,57917,57917,58920,57917,57917,57917,57917,58925,57917,57917,57917,57917,57917,57917,57917,57917,57917,58933,57917,57917,57917,58940,58942,57917,57917,57917,57917,57917,57917,57917,57917,57917,59453,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59471,59472,57917,57917,57917,57944,59001,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59014,57944,57944,57944,57944,59019,57944,57944,57944,57944,57944,59024,57944,57944,57944,59028,57944,57944,57944,57944,57944,57944,57944,57944,58468,57944,57944,57944,57944,529,529,529,898,529,529,0,57894,57894,57894,58317,57894,57894,155943,1153,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,389,57944,59035,59037,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59060,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60883,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61227,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60680,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,1153,0,0,0,1732,0,0,0,0,1739,0,0,0,0,0,0,0,0,0,0,1750,1751,0,0,0,0,0,1757,0,0,0,0,0,0,0,0,3687,0,0,0,3690,0,0,0,0,0,0,0,0,3698,0,0,0,0,0,0,3701,0,3703,529,0,0,0,0,1796,0,0,0,0,0,0,0,1804,1805,0,0,0,0,0,0,1812,0,0,0,0,0,0,0,0,0,0,0,0,335872,0,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,335872,0,0,0,0,0,0,1878,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1891,0,1893,1869,529,529,529,529,529,529,529,529,529,2483,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2494,529,529,529,529,529,529,529,0,0,2508,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59388,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61228,57917,57917,57917,57917,57917,57917,57917,61233,57917,57917,57917,57917,57917,57917,57917,57917,529,529,529,529,529,529,1905,529,529,529,529,1911,529,529,529,529,529,529,529,529,529,529,1922,529,529,529,529,1926,529,529,529,529,529,529,529,529,2457,529,529,529,2460,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,916,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59348,57894,57894,57894,57894,59354,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59365,57894,57894,57894,57894,59369,57894,57894,57894,57894,57894,57894,57894,57894,61456,57894,61458,57894,57894,61460,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,61470,57917,61472,57917,57917,61474,57917,57917,57944,57944,59544,57944,57944,57944,57944,59550,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59561,57944,57944,57944,57944,59565,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,57894,57894,3924,0,0,0,3926,0,0,0,0,0,0,3681,0,0,0,0,3937,0,0,57944,57944,57944,57944,59578,57944,57944,57944,59583,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60066,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59612,59613,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,2284,529,2286,529,529,59633,57894,59635,57894,57894,0,0,0,0,0,0,3448,3449,0,3450,0,3452,0,0,0,0,3454,0,0,0,0,0,0,0,0,0,0,0,3454,0,0,0,0,0,0,0,2864,0,0,0,0,0,0,0,0,0,2870,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,529,2435,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1387,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1402,529,0,2341,2342,0,0,2344,2345,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2365,0,0,0,0,0,0,3473,0,0,0,0,3478,3479,0,3481,0,0,3484,0,0,0,3487,529,529,529,529,529,529,3494,529,529,529,0,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,59863,57894,57894,57894,57894,59867,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58812,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58825,57894,57894,57894,57894,58830,57894,57894,57894,0,0,0,2369,0,0,0,0,0,0,0,2373,0,0,0,0,0,0,0,2381,0,0,0,0,2386,0,0,0,0,0,0,0,0,0,0,2372,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,335,336,337,0,0,0,0,0,57917,57917,57917,59967,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59977,57917,57917,57917,59980,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59522,57917,57917,57917,57917,57917,57917,57917,57917,57894,57944,59533,57944,57944,57944,57944,57944,57944,57944,59540,57917,57917,57917,60019,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60042,57944,57944,60046,57944,57944,57944,60050,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60060,57944,57944,57944,60063,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,3139,529,529,57894,57894,60486,57894,57894,0,0,0,0,0,0,0,0,0,0,57944,57944,57944,60102,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,2779,0,0,0,0,0,2862,0,0,0,0,0,0,0,0,0,0,2869,0,0,0,0,0,0,529,529,2876,529,529,529,529,529,529,529,529,529,529,529,2890,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1986,529,58776,1990,57894,57894,57894,57894,57894,57894,57894,529,529,529,529,2884,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2899,529,529,529,529,2902,529,529,2904,529,2905,60323,57894,57894,60327,57894,57894,57894,57894,57894,57894,57894,57894,57894,60336,57894,57894,57894,60339,60340,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60629,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60642,57894,57894,57894,57944,57944,57944,57944,57944,57944,57944,60425,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60440,57944,57944,57944,57944,60443,57944,57944,57944,57944,57944,57944,57944,57944,58470,57944,57944,57944,57944,529,529,529,900,529,529,0,57894,57894,57894,58319,57894,57894,295,1153,0,0,1157,0,60445,57944,60446,57944,57944,57944,57944,57944,57944,57944,57944,57944,60455,57944,57944,60459,57944,57944,57944,57944,57944,57944,57944,57944,57944,60468,57944,57944,57944,60471,60472,57944,57944,57944,57944,57944,57944,57944,59008,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,3660,0,0,3153,3154,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3171,0,0,0,0,0,0,0,0,0,2839,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2361,0,2363,0,0,0,0,3204,0,3206,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3219,0,0,0,0,0,0,529,529,529,529,529,529,529,529,2432,529,529,529,529,2436,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2487,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2501,529,529,529,529,3231,529,3234,529,529,529,529,3239,529,529,529,3242,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3864,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60622,57894,60625,57894,57894,57894,57894,60630,57894,57894,57894,60633,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60643,57894,57894,57894,57894,57894,57894,59909,59910,57894,57894,57894,57894,57894,57894,59917,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60634,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60692,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60709,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,0,0,0,0,0,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61090,57894,57944,60741,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60758,57944,57944,57944,57944,57944,57944,57944,57944,58473,57944,57944,57944,57944,529,529,529,903,529,529,0,57894,57894,57894,58322,57894,57894,155943,1153,0,0,0,0,1733,0,0,0,0,1740,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,352256,0,352256,352256,0,0,0,0,0,3444,0,0,3446,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3457,0,0,3460,0,3461,0,0,0,0,0,0,0,0,0,0,2310144,0,0,0,0,0,0,0,2310144,2310144,0,0,0,0,0,0,0,0,0,2310144,0,0,0,2310144,0,0,0,0,0,2310144,0,0,2310144,0,0,2310144,0,2310144,2310144,0,2310144,0,2310144,2310144,0,529,529,529,529,529,57894,57894,57894,60875,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60887,57894,57894,57894,57894,57894,57894,57894,57894,57894,60306,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,0,57917,57917,57917,57917,57917,57917,57917,57917,60895,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60909,57894,57894,57894,57894,57894,57917,57917,57917,60917,57917,57917,57917,57917,57917,57917,57917,57917,60929,57917,57917,57917,57917,57917,57917,57917,57917,60937,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59975,57917,57917,57917,57917,57917,57917,57917,57917,59982,57917,59984,57917,59987,57917,57917,57917,57917,57917,57917,60951,57917,57917,57917,57917,57917,57944,57944,57944,60959,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60971,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59553,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60732,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60979,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60993,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,3825,0,0,0,0,0,3828,0,0,0,0,0,0,0,0,0,0,0,0,0,3664,0,0,0,0,0,0,0,3670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3196,0,0,0,0,0,3201,0,0,57944,57944,57944,57944,61139,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61149,57944,57944,57944,57944,57944,57944,61155,57944,61157,57944,57944,57944,0,0,0,0,0,4084,0,0,4087,0,0,0,0,0,529,529,529,529,529,529,529,529,529,529,529,4102,529,529,4104,3853,529,529,529,529,529,529,529,529,529,529,529,529,529,3862,529,529,529,57894,57894,57894,57894,57894,61211,57894,57894,57894,61215,57894,57894,57894,57894,57894,57894,57894,60647,57894,57894,57894,60650,57894,60652,57894,57894,57894,57894,57894,57894,57894,57894,60657,57894,57894,57894,57894,57894,0,0,57917,57917,57944,57944,57944,57944,61262,57944,57944,57944,57944,529,529,57894,57894,0,0,0,0,0,0,0,0,0,0,0,3681,0,0,0,0,0,0,0,0,0,0,2789,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,319488,319488,0,0,0,0,0,0,529,529,529,529,529,529,529,4168,57894,57894,57894,61516,57894,57894,57894,57894,57894,57894,57894,57894,61524,57894,57917,57917,57917,61529,57917,57917,57917,57917,57917,57917,57917,57917,61119,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60967,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57917,57917,61537,57917,57944,57944,57944,61542,57944,57944,57944,57944,57944,57944,57944,57944,61550,57944,0,0,0,0,0,4209,4210,4211,0,4213,529,529,529,529,529,529,529,529,2482,529,529,529,529,529,529,529,2488,529,529,529,529,529,529,2493,529,529,529,529,529,529,529,529,529,529,529,1910,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1928,1929,529,529,529,529,529,529,4219,4220,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,61570,61571,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,61578,61579,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,61586,61587,57944,57944,0,0,0,0,4248,0,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,58281,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,57917,57917,57917,57917,57917,57944,57944,57944,57944,4304,0,529,4305,57894,61650,57917,61651,57944,61652,0,529,57894,57917,57944,0,529,57894,57917,57944,0,529,57894,57917,57944,0,529,529,529,529,529,529,529,2456,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,3249,529,529,529,529,529,529,0,0,0,0,0,395,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,303,0,0,0,0,428,428,0,131072,428,0,0,0,428,0,0,455,0,0,0,428,0,485,485,485,0,0,362,362,362,362,504,362,362,362,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,485,547,57913,547,57913,547,547,57913,547,547,57936,57913,547,547,57913,57913,57913,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,4276224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,737,0,0,0,0,0,0,0,0,0,57913,57936,57913,57913,57913,57913,57913,57913,57913,57936,57936,57913,57913,57963,57913,57913,57913,57913,57913,57913,57913,57963,57963,57913,57913,57913,57913,57963,57963,57913,547,57913,529,907,529,529,529,57894,57894,57894,57894,57894,57894,57894,58289,57894,57894,57894,57894,57894,58308,57894,57894,57894,57894,58326,57894,57894,57894,0,57917,57917,57917,57917,57917,57917,57917,60927,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60945,57917,60947,57917,57917,57917,57917,57917,58365,57917,57917,57917,57917,57917,58384,57917,57917,57917,57917,58402,57917,57917,57917,0,0,0,0,58308,57944,57944,57944,57944,57944,57944,57944,58440,57944,57944,57944,57944,57944,57944,57944,59043,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,57917,57917,57917,57917,57944,57944,57944,57944,58459,57944,57944,57944,57944,58477,57944,57944,57944,529,529,529,529,907,529,0,57894,57894,57894,57894,58326,57894,155943,1153,0,1154,0,0,0,0,0,0,3685,0,0,0,0,0,0,0,0,0,0,0,0,0,3697,0,0,0,0,0,0,0,0,0,0,529,529,529,3943,529,529,529,529,3947,529,529,529,529,529,3953,529,529,529,57894,57894,57894,61302,57894,57894,57894,57894,1159,0,0,0,0,0,1165,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1241,0,0,0,0,0,57894,58797,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60322,57894,58953,57917,57917,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,58977,57944,57944,57944,58986,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59048,57944,57944,57944,57944,57944,57944,57944,57944,529,1358,529,529,529,529,58797,57894,57894,57894,57894,57894,0,0,0,0,0,1765,0,0,0,0,0,0,0,1773,0,0,0,0,0,0,0,0,0,1783,0,0,0,0,0,0,0,0,0,0,695,0,0,0,0,368,368,368,0,0,704,0,0,0,0,0,0,0,711,0,0,0,0,0,0,0,0,1850,0,1852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3678,0,0,0,0,0,529,529,529,529,1934,529,529,529,529,529,529,529,529,529,529,529,1947,529,529,529,529,529,529,529,529,529,529,529,529,1960,529,529,529,0,2506,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59875,57894,57894,57894,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,648,0,0,0,0,0,0,0,0,540672,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,329,0,0,375,375,407,0,57894,57894,57894,59377,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59390,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59403,57894,57894,57894,57894,57894,57894,57894,60901,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,60918,57917,57917,57917,57917,60922,57894,57894,57894,57894,57894,59415,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59426,57894,57894,57894,57894,57894,50679,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,59972,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59467,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59477,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59490,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59503,57917,57917,57917,57917,57917,57917,57917,60928,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60943,57917,57917,57917,57917,57917,57917,57917,57917,57917,61120,57917,57917,57917,57917,57917,57917,61126,57917,61128,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60968,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59573,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59586,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59599,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60081,60082,57944,57944,57944,57944,57944,57944,60089,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,0,57894,57894,57894,57894,57894,57894,295,1153,0,0,0,0,57944,57944,57944,59611,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,59622,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,3941,529,529,529,529,3945,529,529,529,529,529,529,529,529,529,3954,529,529,61300,57894,57894,57894,57894,61304,57894,57894,57894,57894,57894,57894,59416,59417,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,50679,0,57917,57917,57917,57917,57917,57917,57917,57917,57917,59486,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59983,57917,57917,57917,57917,57917,57917,57917,57917,0,2395,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,507904,507904,57917,57917,59966,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60949,57944,57944,60049,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60759,57944,60421,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60473,529,529,529,529,529,3233,529,3235,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,1990,57894,57894,57894,57894,57894,57894,57894,57917,57917,60666,57917,57917,57917,57917,57917,57917,60673,57917,60675,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60386,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,60715,57944,57944,57944,57944,57944,57944,60722,57944,60724,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60729,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3438,0,0,0,0,0,0,0,0,0,0,2334720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,0,0,529,529,529,3856,529,529,529,529,529,529,529,529,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61218,57894,57894,57894,57894,57894,57894,61454,57894,57894,57894,57894,57894,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,61468,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58991,57944,57944,57944,57944,57944,529,529,529,529,529,529,4167,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,61523,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59998,59999,57917,57917,57917,57917,57917,57917,60006,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58393,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57917,61536,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,61549,57944,57944,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,2913,529,529,2917,529,529,529,529,529,529,529,529,529,2926,529,529,529,2929,529,529,529,529,529,529,529,529,529,529,529,3505,529,529,529,529,529,529,529,529,529,3514,529,529,529,529,529,529,529,529,3522,529,57894,57894,57894,61629,57894,57917,57917,57917,57917,61633,57917,57944,57944,57944,57944,61637,57944,0,0,0,0,529,529,529,529,57894,57894,57894,57894,57917,57917,57917,57917,57917,57917,57917,57917,57944,57944,57944,57944,57944,57944,57944,57944,4274,0,0,0,0,529,529,529,529,4281,529,57894,0,0,0,0,363,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,262739,0,0,0,0,373,373,0,131072,373,0,0,0,373,0,0,0,0,0,0,373,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,378,0,0,0,0,0,0,0,0,0,57914,57937,57914,57914,57914,57914,57914,57914,57914,57937,57937,57914,57914,57964,57914,57914,57914,57914,57914,57914,57914,57964,57964,57914,57914,57914,57914,57964,57964,57914,548,57914,57914,57914,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,4276224,0,0,0,0,0,0,0,1270,0,0,0,0,0,0,0,0,0,0,57917,57917,58358,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,58433,57944,57944,57944,57944,57944,57944,57944,57944,59551,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60467,57944,57944,57944,57944,57944,57944,57944,57944,1309,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3467,57894,57894,57894,58802,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,0,57917,60664,57944,59036,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60881,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60310,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,0,0,1825,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1788,0,0,0,529,529,529,529,529,1935,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,1397,529,529,529,529,529,529,57894,57894,57894,57894,59378,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,59901,57894,57894,57894,57917,57917,57917,59478,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,59989,57917,57917,57944,59574,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60738,57944,0,0,0,0,0,3447,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,304,0,0,0,0,364,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,516569,516569,0,0,364,0,0,0,0,0,0,0,0,0,0,0,0,364,0,365,0,0,0,0,364,0,0,0,139264,147456,0,0,0,0,0,0,0,0,393687,0,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,393687,0,0,0,0,0,131072,0,0,0,444,0,444,0,365,444,444,444,0,468,0,0,0,496,496,499,499,499,499,499,505,506,499,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,549,57915,549,57915,549,549,57915,549,549,57938,57915,549,549,57915,57915,57938,57915,57915,57915,57915,57915,57915,57915,57938,57938,57915,57915,57965,57915,57915,57915,57915,57915,57915,57915,57965,57965,57915,57915,57915,57915,57965,57965,57915,627,57915,57978,57978,57978,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,4276224,1261,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,308,0,0,0,0,0,0,308,0,0,0,903,529,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58322,57894,57894,57894,57894,0,57917,57917,57917,57917,57917,57917,57917,61243,57917,57917,57917,57917,57944,57944,57944,57944,57944,61249,57944,57944,57944,61253,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,58483,529,854,529,529,529,913,0,58273,57894,57894,57894,57894,58332,155943,1153,0,0,0,0,0,2368,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1844,0,0,0,0,0,0,0,0,529,2425,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2469,529,529,529,529,529,529,57944,57944,60475,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,529,529,529,529,57894,57894,57894,57894,57894,0,0,0,0,0,0,0,0,0,0,0,664,0,0,667,668,0,0,0,0,0,0,0,0,0,0,679,0,0,0,0,0,57917,57917,58359,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,0,0,0,0,57894,57944,57944,57944,57944,57944,57944,58434,57944,57944,57944,57944,57944,57944,57944,57944,60054,57944,60056,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60460,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,0,1248,0,0,0,0,0,0,0,1256,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3170,0,0,0,0,3175,0,1153,0,1729,0,0,0,0,1736,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,0,0,529,529,529,2505,0,0,0,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60317,57894,57894,57894,57894,57894,57894,0,0,0,0,2784,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,320,0,0,0,0,529,529,529,529,529,529,529,2887,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,58776,1991,57894,57894,57894,57894,57894,57894,57894,529,908,529,529,529,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,58327,57894,57894,57894,0,57917,57917,57917,57917,57917,57917,58922,57917,57917,58926,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58937,57917,57917,58944,57917,57917,57917,57917,57917,57917,57917,57917,58882,57917,57917,57917,57917,57917,58894,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,60383,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,57917,58954,57917,57917,57917,57917,57917,57917,57917,57917,0,57894,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,60061,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,57944,529,2451,529,2453,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2901,529,529,529,529,529,529,57894,57894,57894,57894,59882,57894,59884,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60660,57894,57894,0,0,57917,57917,0,2858,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,529,529,529,2433,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,61209,57894,57894,57894,57894,57894,57894,57894,61214,57894,57894,57894,57894,57894,529,529,529,529,2910,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,2938,0,57894,57894,57894,57894,57894,529,529,529,57894,57894,57894,0,3424,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139264,147456,0,0,0,422,3680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,529,529,529,529,529,0,0,0,0,131072,0,0,0,0,0,0,451,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3676,0,0,0,0,0,0,0,0,0,0,0,0,0,2310144,0,0,2310144,0,0,0,0,0,0,0,2310144,0,2310144,0,0,0,0,0,0,2310144,2310563,2310563,0,2310144,0,0,0,0,0,2310144,0,0,0,0,0,0,0,0,0,0,2310144,0,0,0,0,0,0,2310144,0,0,0,0,0,0,0,0,0,0,2812,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1182,0,0,0,0,1186,0,0,2310144,0,0,0,2310563,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0,0,0,2310144,0,0,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310741,2310144,2310741,2310144,2310144,2310741,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,4276224,1261,0,0,0,0,0,0,1269,0,0,0,0,0,0,0,0,0,0,0,0,2318336,0,0,0,4268032,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1329,0,0,1332,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6275072,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,0,0,0,0,0,0,4857856,4874240,0,0,0,0,0,0,0,0,0,3157,0,0,0,0,3161,0,0,0,0,0,0,0,3167,3168,3169,0,0,0,0,0,0,0,0,0,0,1314,0,0,0,0,0,1181,0,1320,0,0,0,0,0,0,0,0,0,1306,0,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,469,2335206,2335206,2335206,469,469,469,469,469,469,469,469,469,469,2335239,2335239,2335239,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,4284416,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5341184,0,5652480,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,2335239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1266,1268,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2342912,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,368,368,0,0,0,0,0,0,0,420,0,0,0,0,0,0,0,0,0,0,0,0,2359296,0,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,2359296,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1778,0,0,0,0,0,0,0,0,0,0,0,0,0,2359296,2359296,2359296,1,24578,3,0,0,4366336,0,0,0,0,0,303,304,0,4268032,307,308,0,0,0,0,0,0,0,0,0,0,0,0,0,4284416,0,0,0,0,0,0,466944,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2367488,0,0,4268032,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1818,0,0,0,0,0,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6275072,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,0,915,0,0,0,0,0,4857856,4874240,0,0,0,0,0,0,0,0,0,3476,0,0,0,0,0,0,3483,0,0,3485,0,0,529,529,3490,529,529,529,529,529,529,529,0,0,0,0,0,0,57894,57894,60285,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,57894,60293,57894,57894,57894,57894,0,5750784,0,0,0,0,0,5873664,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,0,0,0,0,991,4359059,5333907,5981075,4359059,0,5439488,5128192,4358144,5129107,915,5129183,991,5129107,4359059,0,4358144,915,991,4359059,0,4358144,915,991,4359059,0,4358144,915,991,4359059,6004736,6004736,0,0,0,1,24578,3,155943,155943,297,0,0,0,0,0,303,304,0,0,307,308,0,0,0,0,0,0,0,0,0,0,0,0,375,0,0,376,0,0,0,0,0,329,376,332,375,0,0,0,0,0,0,0,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,212992,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2354,0,0,0,0,0,0,0,0,0,0,0,0,0,212992,212992,212992,0,0,0,0,0,4366336,0,0,0,0,0,0,0,0,4268032,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,370,0,0,0,417792,0,0,0,0,0,5840896,5849088,0,0,0,0,0,0,0,0,0,0,0,0,6275072,0,0,0,0,0,0,0,0,0,0,0,0,404,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,335,0,0,0,0,0,0,0,0,0,0,0,335,385,387,0,0,4882432,0,0,0,0,0,0,0,0,5939200,0,0,5677056,6365184,4866048,0,6070272,5545984,5152768,0,0,6144e3,4358144,4866048,4882432,4358144,4980736,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5177344,4358144,4358144,4358144,4358144,4358144,5242880,4358144,4358144,4358144,4358144,4358144,4358144,4358144,5341184,4358144,4358144,4358144,4358144,6045696,4358144,6070272,4358144,4358144,4358144,4358144,6348800,4358144,6144e3,0,6144e3,0,4988928,5005312,0,0,0,0,5775360,0,0,0,0,0,0,0,0,0,0,5693440,5005312,4358144,4358144,4358144,512e4,5136384,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,4358144,6324224,5914624,5914624,0,0,0,0,0,5513216,5783552,0,0,0,0,0,0,0,0,0,0,6299648,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4825088,0,0,0,0],r.EXPECTED=[338,346,354,643,1667,362,993,370,376,384,457,464,421,392,905,405,418,429,683,461,437,445,472,410,480,1434,488,507,515,523,531,539,547,555,563,571,579,1039,664,971,598,598,597,883,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,589,1845,606,614,622,637,1159,672,2252,451,1636,691,654,706,1194,715,729,944,1366,737,1224,1357,1868,759,772,790,805,858,811,1898,1255,819,827,835,2141,1209,843,1935,851,873,891,899,1712,913,930,938,1362,952,960,968,979,981,1412,989,1001,1447,1016,1329,764,1024,1032,1051,1059,1067,1075,1083,1090,1098,1575,1106,1114,1122,1130,2068,1145,777,1153,1179,1167,2093,1514,1175,1187,2238,719,721,1697,1520,1517,1785,1202,1427,1558,1217,1232,1891,1240,1248,1263,1271,1279,1287,1461,1800,1307,1315,1323,1337,1345,797,742,1374,1382,585,1397,751,1352,1405,1297,1299,1929,1420,1763,1997,1442,1455,1469,2231,1477,1485,2046,2224,1493,1500,1508,598,2283,1528,2209,1536,1544,1008,1552,1682,2187,1137,1566,2138,1583,1598,1606,1043,1571,1614,1622,1630,1719,1644,1652,782,1660,1675,1690,1705,1727,1815,1735,1743,1751,1759,1771,1779,1793,1808,1823,1831,499,1839,1853,1861,2089,1876,397,629,1884,494,679,1906,1914,659,1590,1922,1990,698,1943,2040,1951,2108,1959,2156,1967,1975,1983,922,2005,2013,2025,2033,2054,2062,865,649,2076,2084,880,2101,2173,2116,2017,747,1389,2124,2132,1293,2149,2164,2181,2195,2203,2217,2246,2260,2268,2276,598,598,598,598,2169,598,920,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,709,2291,2295,2302,2302,2302,2297,2301,2302,2308,2306,2319,2312,2316,2323,2326,2330,2334,2338,2342,2346,2352,2352,3896,2351,2405,2352,2352,3897,2352,2352,5138,3782,3361,2526,2416,2416,2416,2475,2531,2531,2396,2516,2516,2516,2516,2524,2403,2352,2352,2352,2352,2352,2410,3782,2516,2516,2516,2427,2431,2352,2352,2352,2352,5037,4578,4790,4660,3361,3361,3361,3361,2415,2416,2416,2416,2417,2531,2531,2531,2495,2416,2416,2529,2531,2531,2531,2531,2531,2374,2516,2516,2496,2516,2516,2516,2516,2516,2376,3402,2416,2416,2531,2531,2531,2531,2531,2450,2516,2516,2516,2516,2517,2442,2352,2352,2352,4920,2761,2766,2352,2352,2352,4992,3361,3361,3361,3361,2414,2416,2416,2416,2416,2416,2421,2352,5036,2352,2829,3361,3361,3361,2488,2516,2516,2516,2516,2384,2352,2352,3158,2531,2531,2497,2516,2516,2382,2352,2352,2352,5037,4615,2352,2352,2352,4519,2352,2352,2352,3029,5036,4991,3361,3361,2414,2416,2416,2494,2531,2496,2516,2516,2454,2352,3882,4993,3361,2526,2527,2531,2532,2516,2464,3880,2830,2473,2528,2423,2516,2479,2486,2415,2530,2498,2506,3360,2416,2531,2516,4992,2473,2448,2515,2484,2473,2493,2503,3399,2513,2399,2521,2536,2540,2544,2548,2552,2556,2557,2557,2558,2562,2566,2557,2572,2568,2576,2580,2584,2588,2592,2596,2600,2604,2611,2352,2352,2352,2618,2352,2352,2352,5085,2352,2352,2352,2352,3168,2637,3849,2352,2353,2352,2352,2352,2352,2352,2352,2352,2352,4089,2663,2666,2669,2673,2677,2681,3991,2689,2352,2352,2352,2352,2352,2695,2703,3159,2709,2713,2352,2717,2721,2460,2352,2352,4582,4588,5123,4592,4599,3130,4274,3674,2723,2728,3992,2690,2352,2352,2358,2352,2352,2364,2352,2352,2352,4714,3949,2352,2352,2352,4537,2784,2352,2352,2352,2507,4646,2352,2352,2352,2630,2352,4452,2352,2352,2743,2747,2352,2352,2352,4538,2751,2352,2352,4614,4609,2352,2352,2352,2352,3782,2352,2352,4993,2776,2352,2352,2352,2352,3913,2780,2352,2352,4687,2352,2352,2352,3242,4732,2352,4610,2788,2352,2352,2352,2352,2352,2347,4696,2802,3554,2807,2352,2352,2352,2352,2352,4602,3509,2352,2352,2352,4661,2819,2352,2352,2352,2352,2352,2818,3617,2352,2834,4661,2847,2352,2352,2352,3002,3779,2352,2352,2352,3014,2352,2352,2352,2352,4081,3811,2352,3819,5010,2352,2352,2352,4784,2352,2352,2352,3140,2352,2352,3813,3183,5009,2352,2352,2352,4783,2352,2352,2352,3480,3485,2352,2352,2352,3839,2352,2352,2352,4464,3070,2352,2352,4771,3227,2866,2870,2352,2352,4742,4158,2352,2352,2352,4743,2791,2876,2352,3093,2870,2352,3797,4905,2352,2792,2352,2352,4904,2352,4478,4703,4241,2457,2457,2457,4703,4106,4242,4242,4242,4681,2902,4476,4241,4726,4243,4105,4477,4170,4167,4169,2906,2917,2936,2938,2942,2942,2945,2352,3221,2952,2974,2980,5136,2984,2352,2992,3405,2352,2352,4823,2352,4772,3955,4903,2352,2352,4965,2352,2352,2352,4713,4974,2986,4283,2352,3222,4906,2352,4040,2352,2352,5014,2352,2352,2352,2352,2352,3688,2352,2352,3e3,4196,3006,3010,3019,3570,4123,2918,3024,2352,2352,2352,3589,3034,2352,2352,2438,2352,2352,2352,3359,3361,2352,4683,3045,3181,3050,2352,2768,2352,2366,2352,2352,2352,2352,2352,2352,4373,4847,4756,2352,4862,3758,3020,2352,2352,3056,4228,2352,2352,2352,2352,3061,4906,2352,2352,2352,2352,2818,4906,2352,3784,3057,2352,2352,2352,4116,3069,2697,3074,2352,2386,2352,3796,4431,4865,3235,2352,4111,3080,2352,2352,2352,2352,2352,2354,2352,2352,3088,2352,2352,2352,2352,2352,3087,3092,2352,2352,3148,3119,2877,3125,2352,2352,2352,2352,2829,3361,3361,3361,3999,3129,2352,2352,2352,2877,3125,2352,2406,4093,3924,5109,4416,3439,3510,3769,2638,2352,4999,4455,3150,2882,3136,2640,4755,3145,4428,2970,3154,2352,3163,3167,2352,2970,3154,2352,2444,3173,2352,2625,2352,3698,2352,2352,2352,2352,2352,4355,2352,2352,3815,2639,4216,2607,3179,3187,2352,3460,3174,2352,3192,2352,3459,3188,3156,3204,4491,3211,4155,2352,3219,4153,4157,3255,3226,4670,3232,4156,3239,3256,4154,3548,3247,3271,3317,3317,3260,3264,3268,3275,3279,3283,3316,3313,3301,3305,3306,3310,3321,3325,3327,4192,3331,3292,3335,3353,4027,5129,3970,3365,3369,3373,3377,3381,3381,3382,2352,2352,4073,2352,4991,3386,3432,3500,3446,3396,3412,4095,3419,3423,4351,2827,3356,2724,3431,2825,2352,2654,4038,4028,4176,2837,3440,4940,4241,3028,4201,3452,3458,3464,5074,3473,3481,2352,2352,2352,4735,3490,2352,2352,2731,4325,3781,2434,2736,2352,2457,3540,4293,4512,2352,2352,3504,3509,3505,2352,2352,2352,2352,2352,3872,2352,3745,3388,3498,4300,4267,3532,4189,4302,3539,4505,4512,2352,2796,2352,2352,2352,2352,2732,4457,3587,3561,4970,3803,2352,3541,3595,2352,2798,4906,4953,2922,2927,4595,2932,3026,2352,2352,4310,2352,2352,3822,2352,2854,4228,2352,2352,2352,2976,2859,2352,4310,2352,2352,3534,2352,2352,3605,4907,3824,2352,3534,2352,4159,2352,4990,2352,4324,4304,2352,4322,2352,3614,2352,2896,2352,3253,4476,4240,2352,2459,4811,3106,2891,2352,3468,3108,2633,3107,3440,3440,3440,4811,3467,3108,3108,3108,3621,3439,3466,3440,4812,2892,3440,4968,4983,4985,3628,3629,3624,3633,2352,2352,2871,5105,2352,2352,2352,2352,4868,3860,2352,2352,2352,2988,3663,3667,2352,4081,3672,2352,4765,4769,3295,4825,3678,3686,3825,3693,3702,3706,3727,3634,3710,3715,3725,3731,2352,2352,2877,3141,2352,2352,2352,3135,4082,3673,2352,3736,2352,2632,3740,3749,3688,3753,3762,3766,2352,3297,3773,2352,2898,4680,3829,3882,2352,2352,2352,3913,2855,2352,2352,2352,3065,2352,2352,2352,2352,2823,2352,2352,2352,4081,3672,2352,4767,2691,2352,3289,3789,3689,2975,3801,2352,2352,5068,3895,2352,3013,5017,2352,2352,2352,2352,3013,2352,5101,2352,2352,2352,2352,2352,3807,3836,2352,2352,2352,2352,2352,4869,2352,3097,3221,3105,2639,2352,3001,3112,3888,3859,2352,2352,2352,2352,3865,2352,3130,3601,2352,2352,2352,3594,2352,2830,3361,3361,2489,2416,2416,2448,4261,3876,2352,2352,3083,2352,2352,2352,4e3,2352,2352,2352,5034,3927,3895,2352,2352,3785,3887,2352,2352,3041,2352,3433,2352,4556,2388,3926,3894,2352,2352,3925,3901,3250,3682,3912,2352,2352,3918,2352,3924,3454,4178,3792,2352,3931,2352,3902,3895,2352,4142,3348,3959,4654,4030,2655,4055,3965,3965,4653,4653,4030,4030,4030,4031,3964,4652,3965,4654,3969,3965,4030,2352,2352,3523,3527,2352,2352,2352,2352,3574,2352,2352,2352,2352,3831,3996,4004,4008,4012,4016,4017,4021,4025,4044,4050,4054,4914,4060,4064,3528,4080,4071,2913,4562,4078,4086,2352,2352,4515,4099,4103,2352,2352,2954,4110,2352,2352,3600,2352,2352,4159,3583,4235,4120,2352,2352,2352,3476,2352,2352,2352,4354,2352,2352,2352,2352,3347,2352,4991,4748,4134,2352,2480,2352,2352,2352,4139,2352,3207,4651,2352,2352,2352,2508,4647,4149,2352,2352,2621,2352,2367,4163,4174,4182,4186,4946,4200,2352,2352,2762,4135,2352,4354,2352,3349,4195,2352,4205,3861,4215,4029,4221,3175,4248,2352,2352,4637,4228,2352,2352,2352,2352,4226,2352,2352,3616,3469,3880,4697,2737,2772,4227,3227,4233,4379,2406,2911,4260,4239,4247,2352,2352,4252,2352,2352,2352,4465,4906,3743,2685,2909,4259,4222,4265,2352,3361,2489,2371,2531,2380,2499,2392,4271,2352,2352,4271,2352,2352,4280,2352,3493,2352,2352,2352,2352,3494,3732,2352,5045,3228,2684,2862,4584,4708,2352,3552,3582,3558,4255,4720,2352,3565,3920,2352,2352,4126,2352,2803,3348,2352,3590,2352,2352,2352,2352,3039,2352,2352,5150,2849,2352,2352,2352,4636,4125,4805,2705,4287,4291,5162,2352,5163,4330,2928,4314,4320,4490,4337,4337,4367,4329,2928,2928,2928,4056,4549,4336,4348,3855,4549,4550,4032,4334,4548,4341,4546,4345,4359,4363,4366,2352,2352,2352,3888,3870,2352,2352,2352,4371,4377,4145,4383,3195,4387,4391,4395,4399,4402,4406,4409,4410,4414,2352,2352,3832,2352,2352,2352,2352,3581,2352,4420,4425,4207,4211,4435,5117,2352,3638,3642,3646,3650,3654,3658,3662,4443,2840,4449,5144,4462,4469,3775,2352,3696,2352,4297,2843,4308,4489,4549,4475,3046,4482,2352,2352,2352,4421,4486,4495,4499,4437,4503,3130,4152,4509,3942,4523,2352,2352,2352,3030,4524,2352,2352,3908,2644,2352,4229,2652,2659,2352,4528,4532,4536,2352,2352,4543,4554,4209,3198,2923,4560,3131,3286,2850,2352,3711,4906,2352,2352,4772,3035,2365,2352,4570,2352,2352,2352,2352,2352,4574,3286,4791,2352,2352,2352,2626,4607,2352,3718,2352,3533,3609,2352,3535,2352,2881,4456,2886,2890,3408,2352,2888,4614,4609,4619,2352,2810,5061,4628,4635,4641,3215,4624,2352,2352,2352,2509,3155,4658,2352,2812,4665,4674,3130,3519,2352,3843,2352,3853,3681,3878,2352,2352,2958,4754,2352,2963,3756,2967,4276,4165,4701,4707,3794,2352,3888,4712,4730,4734,4739,4747,3157,4756,2352,4752,5019,4780,5006,2352,4788,3668,4763,4471,4799,3426,3721,4622,4622,4631,3392,4803,4809,4809,4816,4908,2647,4820,4830,4908,3846,2648,4837,2467,2469,4843,3391,2352,3883,4678,2352,2352,2352,3243,2352,3866,2352,2352,2352,3568,2654,2753,4217,4851,4855,4859,4873,4877,4881,4885,4888,4892,4896,4900,2352,2352,2352,2352,3784,3015,2352,2352,4912,3001,3339,3343,4918,4924,3200,4642,4930,4934,2352,2994,4458,4938,3577,2352,3888,4718,2352,3784,4724,2352,2352,3918,2352,3937,3946,3783,3953,2996,4944,2352,2352,3610,4950,2738,4316,3914,5055,4959,3948,2360,4682,2352,2352,4074,2352,4439,3437,3560,3444,4980,4989,2352,2352,3596,4997,3337,3341,3914,3933,4926,3214,5003,2352,2352,2352,4566,2352,2352,2352,2352,3514,3518,2352,2352,5023,2352,2352,2352,2352,2352,5027,2352,3889,2352,2352,4761,2352,3888,4776,3610,5041,3390,5049,5054,5059,5065,5072,5078,2352,2352,5082,2739,3960,5089,4690,5098,2352,2352,2352,2352,3984,2352,2352,4130,2352,2352,2352,2352,2352,2699,2352,2352,3977,4065,2352,2352,2352,2872,5113,2352,3890,4795,3392,3720,3169,2959,4763,3052,3448,4976,3121,2814,2352,2352,2352,4668,2352,2352,2352,2352,5031,5115,2352,2352,3414,5043,2352,2352,4066,5094,2352,2352,4445,4115,4839,2352,2352,2614,2352,4694,2352,2352,2352,5093,2352,5121,4833,2353,4961,2352,2352,3415,2352,2352,4514,2975,2352,4036,3433,5107,3115,2352,2352,4692,2352,2352,5091,2352,3912,3486,3895,4046,2352,2948,2352,3168,3906,2352,3254,4144,2352,3168,3545,2352,2352,2352,2352,2352,4603,5127,5133,4925,2352,2352,4067,2352,2352,4539,2752,2352,2352,2352,2757,3101,2352,4066,5142,2352,3100,3907,3426,5148,2352,5156,2352,5154,2352,5160,2753,3427,3076,2753,2352,3940,4826,4955,2352,3974,2352,2352,4757,3981,5050,3988,5167,5172,6366,6369,5182,5208,5230,5230,5224,6372,5193,5230,5230,5230,5230,6374,5201,5230,5230,5231,5190,5204,5207,5219,5215,5229,5223,5228,5230,5212,6374,5230,5235,5248,5249,5249,5245,5238,5253,5241,5257,5264,5271,5267,5260,5275,5281,5278,5285,5283,5287,5291,5168,5172,7462,5302,5325,5325,5325,5175,5323,5325,5325,5325,5325,5324,5325,5308,5314,5325,6062,5325,7497,5325,6243,5325,5325,5325,5327,5330,6892,6892,6893,5447,5432,5434,5434,5460,5365,5344,5359,5434,5434,5371,5375,5325,5325,5173,5325,6242,7516,5366,6892,5397,5405,5447,5447,5531,5434,5325,5364,5371,7023,7464,7466,5325,5325,5325,5328,5325,7029,5412,6059,5365,5371,6892,6892,6892,6892,5447,6892,6894,5447,5447,5447,5449,5434,5365,5373,5439,5406,7465,5304,5325,5174,5892,6415,5325,7032,5325,6064,5373,5464,5325,5325,5294,6251,6892,5445,5447,5447,5459,5434,5434,5370,5374,5325,5325,7202,5325,5325,5325,5882,5434,5434,5476,5376,5696,6140,5696,7271,5325,5365,5365,6892,6892,6892,6895,5534,5325,6061,5325,5325,5451,5325,5325,5365,5365,5365,5373,6892,6892,6892,5446,5447,5447,5447,5448,5434,5434,5434,5370,5449,5434,5434,5435,5325,5325,5325,5336,5340,7226,6892,5447,5447,5434,5434,5434,5434,5365,6892,5446,5448,5434,5365,5372,6892,6892,6892,5444,5447,5447,5447,5447,5434,5452,5364,5373,5446,5459,5362,5478,5450,5482,5486,5485,5484,5483,5325,5490,6205,7342,5501,5524,5494,5498,5580,5580,5580,5580,7344,5512,5518,5528,5548,5552,5580,5580,5580,5556,5562,5560,5566,5651,5575,5579,5555,5587,5584,5601,5608,5521,5615,5612,5626,5630,5630,5632,5634,5638,5642,5646,5504,5650,5514,5604,5655,5659,5663,5667,5665,5673,5669,5677,5681,5325,6422,5325,6607,6913,7034,6219,5975,5325,5325,7251,6734,7034,6607,5695,5325,5325,7252,6735,5702,5325,5325,5325,5337,5325,7143,5352,5325,5325,5325,6872,6065,5325,5325,5325,5346,5325,5325,6766,5593,7349,5325,5325,7306,5325,5325,5317,5743,5325,5325,5326,5325,6971,5774,5751,5325,5758,6647,5986,5778,5783,5782,5787,5791,5792,5796,5797,5801,5805,5806,5817,5810,5812,5816,5812,5811,5821,5824,5325,5325,7322,5325,5325,5401,5721,5325,5325,5325,5350,5830,5835,5325,5325,5326,5686,5690,6503,5543,6605,5325,5325,5327,6468,5842,5325,5325,5704,5900,5325,5325,5846,5853,5325,5325,5178,5874,6652,5884,5325,5325,5325,5354,7479,5885,5310,5325,5325,7355,5325,5325,6420,5900,5325,5325,5325,5376,5330,5907,5177,5325,5919,5946,5926,5934,5177,5927,5935,5325,5325,5325,5377,5945,5941,5928,5936,5950,5325,5325,5325,5382,6265,5720,5325,5325,5348,5325,5325,7351,6426,7166,5965,5971,5928,5983,7315,5991,5185,5392,7316,5973,5186,5393,5990,5928,5983,5325,5325,7355,6024,6030,6678,5719,5325,5325,5349,6043,5898,5325,5325,5325,5469,7460,5995,5393,5325,5325,7374,6244,5325,5325,6825,5352,7313,5990,5928,5996,5177,6e3,5721,5325,5325,5355,6434,5325,5325,5363,5365,5365,6915,6004,6243,5325,5325,7472,5325,5325,7478,5325,5327,5333,7488,5972,5929,5392,5325,5325,5325,7199,6915,5967,5973,5930,5393,5991,5929,5392,5325,5327,5838,6218,6242,5325,5325,6023,6029,5325,5325,5325,5746,5734,6030,5325,5325,5325,5753,6744,5325,5325,5325,5754,5325,6221,5325,7194,6018,5325,5325,5325,5767,5325,7193,6035,5325,5325,5379,7486,7202,5325,5325,7201,5325,6418,6416,5325,5328,6927,6218,5325,5325,6427,6819,6418,5325,5325,5325,5901,7500,5325,5176,5325,5325,5347,5325,5325,5325,5915,6056,6075,6079,6082,6084,6084,6088,6088,6090,6092,6092,6092,6092,6092,6093,6097,5325,5329,7488,6838,6758,5177,5325,5325,5383,6857,6312,5325,5325,5325,5952,5325,7097,6101,5766,7112,7161,6117,5325,5330,5295,6252,6061,6140,5325,5325,5325,5966,6107,5325,5325,6109,5826,6110,5325,7174,5325,5325,5425,6244,7172,6122,5325,5325,5455,7485,7492,5325,5325,6425,5325,5325,5325,5979,6102,5767,5325,6127,5325,6606,7110,5325,5330,5732,5736,7532,5325,6132,5325,6139,5325,6679,6155,6161,5325,5325,5507,5325,5325,5325,6245,7179,6162,5325,5325,5325,6004,5903,6157,5325,5325,5569,6701,5886,5325,5325,5325,6008,6757,6504,5325,5325,5618,6423,5330,6172,6187,6178,5393,5760,6173,6188,6715,5761,6174,6189,6716,7012,5325,5325,5325,6017,5690,6970,5325,5325,5622,5325,6183,6193,6715,5325,5330,6720,6908,5325,7e3,6184,6194,6202,6202,5325,5325,5325,6023,5325,6210,6209,5325,5330,6985,7033,5325,6228,5325,5325,5325,6060,5325,5325,6103,5768,6127,5325,5330,6985,7539,6677,6840,5325,5325,5622,7353,5297,6185,6258,5173,6259,5325,5325,5325,6061,6876,5754,6251,6193,6197,5325,5753,6250,6186,6196,5325,6102,6421,5325,6605,5325,6913,6063,6679,5325,6195,5173,5325,5325,5325,6062,5325,5325,5176,5325,6900,5296,6253,6196,5325,5325,5325,6065,7306,6257,6198,5325,5325,5325,6168,6263,6840,5325,5325,5683,5687,5691,5325,6269,6281,6198,5325,5325,5848,6271,6283,5325,5331,7234,6916,6236,5325,5325,6814,5173,6063,5683,7243,5325,5335,5339,7225,5325,6606,6913,6291,5325,6061,5325,5348,7242,6274,5325,5325,5684,5688,6758,7361,5325,5325,5325,6219,6220,7122,6421,6604,6914,6062,5325,6679,6065,6279,6275,5325,5337,7257,6585,5325,5325,7123,6422,5377,5325,7488,6837,5325,5325,5325,5848,6272,7361,7359,5325,5325,6148,7122,6421,5325,6149,7361,5325,5377,7358,7362,5325,6147,7362,5325,5377,7358,7362,5325,7356,7123,6422,7356,7360,5325,5346,5325,5379,5325,6971,6220,6220,6220,5325,5350,5325,5325,5977,6661,7359,5325,5325,7244,6421,7355,6151,5325,5325,6150,5325,5325,7357,7361,5325,7355,7359,5325,5325,6147,7362,5325,6287,7355,6222,7042,5325,7042,5325,6420,5325,6221,6420,6220,6851,6851,5325,5325,5697,5325,5332,5325,5325,6068,5856,5325,6134,6971,5325,5325,5325,6220,6606,6297,6504,5325,5353,6432,5325,5364,5365,5365,5365,5365,7486,6221,6915,6307,6322,6331,6328,6335,6338,6344,6340,6348,6350,6350,6348,6354,6359,6359,6359,6359,6355,5697,7351,6441,5177,5325,5325,5698,5325,5325,5325,6163,6840,5507,5325,5364,5365,6892,5440,7466,5325,5325,7173,5325,5325,7195,5177,5325,6387,5325,5325,5745,6986,6426,5325,7140,5325,6409,6455,5325,6449,5325,5376,5325,5325,5325,6433,5325,5325,5325,6241,5325,6439,6443,5325,5325,5766,5325,5325,5325,6222,6915,6038,5325,5325,5698,5330,6644,5325,5325,5329,5325,5377,6447,5325,5325,5325,6269,6281,5325,6453,5325,5325,5768,5325,5325,5325,6607,7154,6713,7103,5325,5384,5388,5392,5325,6942,5863,7155,6714,6714,5325,5325,5325,6315,5864,5400,6179,5325,5384,6858,6162,5325,5325,6241,6378,5325,6220,5325,5325,7329,7333,7152,5868,5868,5325,5325,5325,6421,5325,7330,7334,5865,5869,5325,5325,5325,6424,6065,7331,7335,5866,5870,5325,5325,5325,6428,6442,5325,5325,5325,6508,6607,5325,6840,5508,5325,5325,5325,6389,7331,6474,5867,7362,5325,5325,6148,5325,6212,5325,5325,5859,6013,6479,5176,5325,5325,5878,5380,5325,6063,5325,6483,5325,5427,5325,5325,6145,5325,6633,6489,6494,5325,5454,7484,6244,6214,5325,5325,6604,5698,6299,5698,6299,5325,5325,5902,6156,6162,6389,6500,5325,5325,5325,6522,6061,6509,6244,5325,5325,6212,5325,6604,6461,6607,5325,5325,5325,6523,5325,6514,5325,5325,5958,5325,6607,5325,6872,5325,5767,5767,5767,5767,6870,5766,5325,5768,6870,6871,5325,5325,5325,6612,6519,5325,7123,6231,5325,6527,5325,6234,6531,6537,6545,7221,6549,6553,6553,6555,6559,6559,6559,6559,6564,6563,6566,6570,6571,6571,6571,6571,6565,6575,5325,5325,5325,6632,5571,5428,5325,5325,5325,6657,7487,5325,6222,6837,5325,6289,5325,5922,6803,5177,5325,6877,5325,5325,5921,7362,5325,7392,5325,5472,5325,5325,6470,5325,7362,5325,5325,6865,5325,6884,5325,6885,6602,5325,5325,5325,6678,5325,6613,6603,5325,5508,5325,5325,5953,5325,5325,5325,6618,5325,6923,6600,5325,6614,5325,5325,5325,6869,5325,6425,5727,6383,5379,5325,7488,6219,6220,5325,5325,6459,7351,5325,6837,5325,6628,5325,6638,5895,5325,5537,5325,6607,6167,6914,6651,5325,5325,6224,5325,6656,6656,5325,5685,5689,6749,6665,7390,5325,5325,6006,7129,6672,6667,5325,5325,6063,5325,5325,5325,5330,6903,5325,6838,6420,6291,6065,6064,5325,6424,5325,5325,5325,6022,6223,6676,5325,5325,6063,5327,6069,6694,6688,6910,6700,6244,5325,5325,6063,6064,5683,7243,6424,6217,6382,5325,5696,6490,5325,5325,5325,6582,6290,6877,5325,6065,6634,6510,5870,6705,6684,6908,5325,5696,6623,5391,5325,6215,5327,5325,5696,7307,5325,5708,5399,5719,5378,5325,6971,5325,7488,6606,6721,6909,5325,5325,5325,6899,5325,6901,6905,6909,5325,6904,6908,5325,5325,6135,5325,6288,5325,5324,5922,5325,5325,6064,5325,5325,5325,5335,6907,5325,5325,5325,6900,7305,6841,6906,6910,5325,5325,5325,6877,5324,5326,5325,5325,5325,6903,6726,5325,5325,5325,6911,5331,6316,5325,5325,5325,6915,5325,6903,6910,5325,5325,6211,5472,5325,6242,5325,5325,5325,6902,6906,5325,6725,5325,5325,6217,5325,6242,5325,5329,5378,5325,5325,5325,7170,5325,7487,6837,5325,6291,5325,5325,5325,5325,7387,5325,5325,6221,6244,7487,5325,5325,5325,6918,7487,5325,5325,7486,5325,7487,5325,5325,7487,6220,6065,6730,6734,5325,5745,5733,5737,5325,6739,6748,5325,5747,5735,5739,6871,6244,5325,6067,5325,5325,6485,5401,6243,6065,7269,5325,5754,5298,6186,6259,7036,6324,6754,6762,6770,5413,6774,6778,6782,6787,6787,6787,6783,6791,6791,6791,6793,6795,6795,6795,6795,6799,6802,5325,5325,6244,5325,5325,6971,5325,5325,5915,5326,5325,6807,6217,5325,5325,6310,5325,5325,7370,5325,5325,6314,6318,6832,5325,5325,6813,6118,5325,5325,5325,6971,6607,6061,7277,5325,6839,6123,6222,5325,5325,5325,6983,6987,5325,6818,5325,5325,6363,5325,5325,5325,6533,6820,5325,5325,5325,6992,5571,6830,5325,6831,5325,5765,5544,5772,5837,6809,5325,5325,6398,5325,5325,6836,6846,6837,6141,6222,5325,5325,6416,6840,5325,6863,5325,5325,5325,6999,6859,5325,5325,5325,7013,6541,6839,6222,5325,5825,5325,5325,5471,5325,5325,5381,5385,5389,5393,5382,5386,5390,5177,5325,6889,5387,5391,5325,5848,6317,5325,5325,5325,6914,5325,6292,5325,6876,5325,5325,5325,7241,6273,7362,5325,5325,5325,6212,6808,6218,5325,5325,6417,5325,6417,5325,5325,6416,5325,6242,5325,7036,5325,5325,6971,6838,6420,7486,5325,5325,7458,5976,5325,5766,5325,5877,5379,6219,5325,6221,6219,5325,5325,5325,7098,6496,5325,5325,5325,7020,7253,6140,5325,5325,6419,5325,7089,7232,6916,7095,6928,5325,5325,5325,7123,6424,5325,6604,5975,5325,5325,7452,5389,5393,5325,5325,5325,5725,5325,6222,5325,5325,6420,5379,5974,5325,5325,5325,7201,5325,5325,7201,5325,6915,6849,5325,5325,6620,6624,5392,5325,5878,5380,6540,5325,6244,5325,7488,5325,6840,5325,7504,5325,5325,6460,7352,5325,6134,6934,5325,5883,5325,5325,5330,7267,5325,6133,6933,5325,5886,5325,5888,5325,7487,6604,6291,5325,7503,5325,5325,6465,5325,6938,5325,6219,6221,5325,6916,6039,5325,5325,5831,6214,6605,7503,5325,5325,6509,5325,6219,6222,5330,5325,5325,6066,6971,6948,5325,5325,6515,5325,5325,5325,6606,6947,5325,5325,5914,5325,7487,6605,7121,6971,5325,5325,7121,5913,7487,6605,5913,6404,6605,5914,5914,5325,5325,7121,5325,6413,5325,5383,5387,5391,5325,5914,6952,7487,6405,6954,6954,6954,6954,6971,5325,5325,7488,6958,6964,5325,5325,6521,6593,5325,7351,5325,5325,6591,6140,6976,7036,6420,5196,5325,6980,5197,6991,7351,6996,7004,7010,7017,7040,7046,7050,7062,7053,7056,7058,7066,7076,7076,7075,7068,7070,7071,7080,7080,7080,7080,7081,7085,5325,5325,6604,7526,5325,7374,6960,7362,5325,5325,7351,5325,6911,6062,6679,5325,5330,7350,6060,6238,5325,5325,5175,5325,5325,6605,5376,5325,6435,5325,5325,6608,5385,7104,5325,5327,5325,5910,5325,6420,5325,6604,5325,5325,5325,5453,5325,7120,5325,5325,6622,5390,5177,5325,7127,5325,5325,6631,7306,6007,5325,5325,5325,7203,5325,5325,5325,7134,5325,7159,7352,5325,6913,5325,5915,5325,5325,7121,6420,6417,5325,6420,7091,5325,7301,5976,6240,6921,6220,5325,5325,6646,5325,5347,5325,7165,5327,6484,5325,5325,5849,6732,6140,5325,7178,6641,7186,7179,7399,7187,5325,5325,5325,6246,7180,7400,6162,5325,5325,6589,6587,5325,5325,5325,7312,5940,5927,6900,6958,7191,5325,5915,5913,5325,5913,5325,5325,7121,7353,6911,5325,5325,6765,6401,6922,6221,5325,5325,6824,5325,5335,7207,7182,5714,5336,7208,5711,5715,5337,7209,5712,5393,5338,7181,5713,5177,7373,6959,6244,5325,6971,7458,7354,6912,5325,6416,7296,5976,5325,5176,5325,5960,6052,5325,6919,6220,5325,5921,7332,6475,5868,7213,5596,5714,5325,5325,5325,7314,5334,5338,7214,5597,5714,6842,6841,6971,5325,5954,5325,5325,6842,5325,6418,6420,7091,5325,5954,5325,7320,7026,5325,5325,5325,7452,5389,7218,5325,5325,5325,7456,5340,5597,7285,5325,5325,7284,5325,5325,5325,7488,5325,5325,6841,6971,7199,5325,5325,5325,7313,6417,5325,7230,5325,5961,5325,5326,7242,5325,7026,5325,5325,7238,7263,7248,5325,5325,6838,5325,5325,5325,5887,5334,7262,7258,5324,7354,5325,5325,6984,7538,5325,5325,7006,5976,6420,7275,6917,5325,5325,6839,5325,6921,5325,5325,5325,7503,7291,5325,5325,5325,7520,7509,7281,5325,5325,5325,6839,5507,7290,6140,5325,5325,6840,5325,7289,6735,5325,6841,6424,5325,5325,5330,6943,7267,5325,6416,5325,5978,6671,6666,7362,7295,5325,5325,5376,6971,6631,7300,5325,5325,6841,5325,5325,5325,5959,5325,6632,7307,5325,5325,5325,6841,6216,6381,5173,5325,5325,5958,6606,5325,7305,5325,5325,6048,6915,5325,5697,5325,6012,5973,6030,5325,6632,6918,5325,5325,6841,6971,5325,6425,5325,6068,6918,5953,6140,5325,7311,5952,6918,5325,5325,6853,5325,5953,6140,5325,5325,6871,5325,5767,5953,6140,6918,5376,5325,6577,6140,5325,6017,5325,5325,5379,5325,5325,5325,7306,6916,5698,5332,5325,6917,6578,5697,5325,5325,6876,6293,5696,5325,5698,5696,7326,5325,7350,7339,7350,5325,6213,5467,7137,5325,7146,5331,5325,7123,7380,6103,5768,5325,6128,5325,6606,5325,5330,6706,6710,6909,7149,6211,7348,7367,5420,7378,7384,5423,5320,7396,7404,7407,7410,7414,7417,7419,7417,7423,7424,7429,7428,7424,7433,7434,7434,7435,7441,7439,7445,7449,5325,6022,6028,5177,5325,5325,5325,5696,6918,6523,6595,5325,7033,5325,6972,6915,5325,5325,5325,6878,5325,6215,5325,5621,7352,5325,5325,5325,7527,5540,7363,7470,5325,5325,7476,7483,5325,5325,5325,6882,6062,7493,5325,5325,5325,6882,6915,6595,6420,6841,5325,6047,5325,5325,5380,5325,6877,5325,7354,5325,6826,5325,5729,7508,7514,5325,6060,5325,6870,5173,5325,7509,6291,5325,5325,6917,5325,5326,7521,7510,5325,6060,5766,5325,5766,5325,6872,6870,5325,5325,5325,6604,5365,5365,6594,6421,6425,5325,5325,6102,7525,5351,6840,5325,6062,6841,5325,6013,7460,6031,5325,5326,5731,6393,7532,5325,5325,5325,6967,6416,5728,5732,6394,7533,5729,6391,5738,6291,5730,6392,7531,5325,6063,6062,5325,5325,5325,5334,6595,6422,6426,5325,5325,5325,6932,5177,5333,5325,6066,5325,5325,6915,5325,5325,6216,5325,5325,6877,7351,5325,6913,5325,6677,5325,6061,5325,6069,6683,6688,7525,6742,5325,5325,6941,5862,7532,6870,5325,6140,5590,6596,6423,5325,6070,6695,6689,5325,6215,5325,5325,6983,7537,5325,5325,5325,6063,6826,5352,5325,6071,6696,6690,5734,5738,5325,5325,7035,5325,5325,7488,5738,5325,6140,6872,5325,5325,6920,6750,6912,6423,5325,5325,7090,6214,5325,6912,7033,5325,6303,5325,5698,5333,6917,5325,6114,5325,5325,5410,5417,6987,5325,5325,5325,7102,7108,6877,7352,5325,5325,7114,5388,5325,7115,5325,5325,7116,5325,7114,5325,5325,5325,7130,6971,5325,2,4,8,262144,262144,1048576,1073741824,0,0,0,2147483648,0,0,0,-1979711488,4194560,4196352,270532608,2097152,4194304,8388608,234881024,268435456,37748736,-1606418432,541065216,541065216,-2143289344,-2143289344,4194304,513,32768,0,0,-2143289344,-2143289344,-2143289344,4194304,4194304,4196352,-1606418432,541065216,-2143289344,4194304,4194304,-2143289088,4196352,-1606418432,-1606418432,541065216,4194304,4198144,4194304,4196352,276901888,8540160,8425488,4194304,4194304,4194304,16777216,4194304,541065216,4194304,4194304,4194304,4194304,4194432,541065216,37748736,742391808,239075328,239075328,171966464,775946240,4718592,64,4718592,171966464,239075328,171966464,775946240,171966464,171966464,171966464,171966464,239075328,239075328,775946240,775946240,2097216,4720640,541589504,4194368,-2143285440,-1606414528,-1606414528,541589504,541589504,4194400,4194368,541065312,541065280,-2143289280,-2142763008,541589504,541065280,4194368,-2143285440,-2143285408,-2143285408,-2143285440,-2143285440,-2143285440,-2143285440,-2142761152,-1606414528,-2143285440,-2143285440,-1605890240,-2142761152,-2109731008,776470528,-1908404416,775946304,775946304,-1908404416,2,4,8,64,128,512,1024,2048,0,256,2048,2048,2048,2048,8192,8392704,0,0,-570425344,32505856,16384,1536,1792,0,2147483648,65536,65536,4224,65536,16777216,16777216,0,0,0,0,1,0,0,0,2,0,0,0,3,4,16,224,256,512,32768,96,96,0,0,0,1073741824,0,0,16384,0,0,0,118,577408,22020096,0,1536,64,524352,0,0,524288,524288,524288,524288,0,524352,524288,524288,524288,64,64,64,0,0,0,8,0,0,0,12,32,64,1024,2048,57344,262144,50331648,268435456,1073741824,2147483648,0,0,64,64,262144,1048576,4194304,16777216,33554432,268435456,0,128,128,128,128,0,8388608,4096,4096,4096,4096,29696,4096,1536,1024,0,-2113929216,100663296,100663296,4224,0,0,262144,33554432,134217728,0,0,96,64,524352,524352,524352,524352,0,64,64,128,128,128,64,64,64,96,96,96,96,524352,524352,0,0,0,15,208,15360,96,524352,524352,524352,524288,64,64,128,2048,64,0,0,32768,50331648,268435456,0,0,524352,524288,524288,64,64,96,524288,64,96,524352,0,524288,64,96,0,4096,536870912,1073741824,1056,262176,1048608,2097184,4194336,536870944,32,32,4,1073872896,32,0,32,0,0,8388608,1073741824,0,1073872896,40,262176,32,32,41,96,32,34,34,32,32,32,40,96,160,40,48,1120,96,0,64,524352,524288,64,0,0,2101248,0,0,3751936,0,0,5242880,0,0,4195360,6291488,2097184,2097184,4194336,4194336,4194336,32,56,262184,40,262184,40,262184,40,40,40,4195104,40,40,262176,32,128,256,2048,262144,524288,96,6292512,4195360,2097184,6292512,32,32,32,32,56,0,4,262184,32,32,32,512,2048,262144,0,65536,65536,131072,262144,2097152,8388608,40,4196128,32,262184,32,42,224,34,42,32,327155712,1056,1056,2098208,42,1056,4194336,32,262144,524288,0,0,16777216,0,0,4457568,-326784344,-322851160,-322851160,-322698144,-322698144,-322698144,-322698144,-322695456,-322695456,-322695456,-322695456,-322597152,-320598176,-322597152,-322597144,-321548576,-320598168,-322597144,-322588952,-321548568,-322588952,-321548568,-322597144,96,32,32,40,1120,40,262176,42,106,293601323,293601323,293863467,293699627,293617707,293716011,293702203,293702203,293702203,293702203,293702267,297896507,293964347,297896507,293702203,293702203,297896507,293964347,297896507,-322597144,-37744981,-322597144,-321548568,-37482773,0,0,1,4,8,32,64,512,2048,16384,67108864,0,48,0,0,0,64,0,0,0,318767104,0,0,1,4096,0,32,64,65536,393216,10485760,16777216,33554432,1073741824,2147483648,0,33554432,268435456,536870912,2147483648,0,0,0,262144,65536,0,0,1,2,12,16,64,128,1024,2048,4096,8192,65536,131072,0,262144,262144,0,0,2,8,16,64,262656,262144,0,0,2,12,64,262144,328192,0,0,2,204,768,-2147483646,0,0,0,1024,0,0,524288,5242880,0,0,2,65536,201330721,201330721,201330721,-2111369023,-2111360575,-2111369023,-2111369023,-2111369023,-2111369023,-1977151295,-1977151293,-1910042431,-1893265183,-2111368509,-1893265183,-1893265183,-1893265183,-553689472,-553656704,-553689472,-553656704,-553689472,-553689472,-553656704,-553656704,-553689472,-553689472,-553656704,-553656704,-553656704,-553656704,-553656672,-553656664,-553656672,-553656672,-553656672,-553656672,-553656670,-553656608,-553656672,-553656672,-553656672,-553656664,-536912159,-553656671,-536879391,-536879391,0,0,0,1040,1040,262656,0,0,0,1536,0,328192,0,0,2,67108864,0,0,458880,2097152,-1845493760,462976,-2113929216,0,0,4,8,256,471424,0,-2113929216,0,0,67108864,0,0,134217728,128,256,3584,16384,32768,524288,4194304,33554432,134217728,536870912,0,0,-1912602624,18874368,463488,0,0,134217728,4096,0,0,104e4,15728640,-570425344,0,0,0,2014,0,0,0,128,196608,2097152,8388608,536870912,0,0,201326592,0,0,0,1998,518144,8388608,0,256,12288,0,0,486539264,0,0,33554432,268435456,0,0,167772160,234881024,0,0,4,16,0,196608,786432,1048576,2097152,4194304,8388608,134217728,268435456,4194304,8388608,503316480,1073741824,2147483648,0,7168,16384,32768,196608,786432,0,128,512,7168,16384,2147483648,16777216,0,0,4,64,128,8388608,0,512,0,0,1,1,0,234881024,128,512,3072,16384,32768,4096,16384,131072,524288,1048576,2097152,0,0,0,62,64,128,234881024,268435456,1073741824,2147483648,-2147418112,5242880,-1842937664,16384,32768,131072,524288,1048576,8388608,33554432,201326592,268435456,1073741824,0,1048576,4194304,268435456,131072,2097152,0,0,7,27756528,-503316480,0,0,512,3072,16384,131072,1048576,4194304,2147483648,0,0,0,512,3072,131072,524288,1048576,524288,1048576,4194304,134217728,2147483648,0,0,524288,4194304,2147483648,0,0,536870912,0,0,16384,18432,67108864,1073741824,16384,8192,0,0,8192,18952,0,65,100663298,18952,1024,65,1024,1024,0,0,0,16,0,0,0,4,0,0,0,6,56,128,2101248,524288,1024,268436480,1024,19017,-1744550912,8388624,8388624,-1739308032,-1739308032,-1739308032,-1739308032,-1736162288,-1736162288,-1736162288,-1736162288,-7868466,-7868466,-7868466,-7868466,-7868450,-7868450,-7868450,-7868450,-7868450,65,0,2,33554432,0,0,1024,5521408,-1744830464,0,0,-1744830464,0,0,1040,8667136,-1744830464,0,0,0,9216,-67108864,0,0,0,13312,0,4096,2097152,0,0,278528,0,0,0,16384,32768,0,16,8388608,0,0,0,12288,5242880,2147483648,0,0,8,512,2048,131072,536870912,0,518144,8388608,50331648,201326592,805306368,-1073741824,805306368,-1073741824,0,0,0,18432,72,0,0,0,24576,204,768,1024,10240,16384,32768,50331648,67108864,134217728,805306368,0,768,1024,2048,8192,16384,32768,458752,8388608,50331648,67108864,16384,32768,458752,50331648,67108864,536870912,1073741824,0,0,134217728,805306368,1073741824,0,0,536870912,1073741824,0,208,0,0,0,32768,0,0,0,65536,0,0,0,131072,0,0,0,48,25165824,16384,67108864,268435456,0,0,1073741824,16384,0,0,16384,2097152,0,1572864,0,0,0,134217728,0,0,0,7,16,64,128,512,2048,8192,16384,458752,16384,458752,50331648,67108864,805306368,1073741824,16,0,0,1048576,4194304,33554432,4,8,128,512,2048,196608,262144,33554432,536870912,0,8,512,2048,196608,262144,50331648,536870912,1073741824,512,0,0,4096,1048576,0,0,0,393216,0,64,256,8192,2097152,2147483648,0,64,64,16392,268435456,0,537395200,537395200,0,0,1073741824,18432,0,0,8,16,512,402653184,0,0,0,537395200,0,32768,0,2048,0,4212736,4212736,4212736,537395200,4212736,1082130432,537427968,4212736,51380242,51380242,22038531,22366211,22366211,22366211,55592978,22366219,22366211,22366219,22366227,55592978,55592978,55592978,55592978,324028498,55592978,55592978,1062785014,1062785014,1062785014,0,1062785014,1062785014,1062785014,1062785014,16384,32768,268435456,0,0,1075838976,2097152,2097152,268435456,4194432,3145728,541065216,541065216,541065216,541065216,4096,0,8,0,1,0,67108864,1073741824,0,0,557056,0,0,16,64,128,3072,4096,8192,65536,18,17825792,33554432,0,1,67174400,33554432,268435456,0,268435456,0,346112,0,0,11,0,82,301989888,0,0,0,2048,0,0,0,4096,0,0,8192,0,0,0,44,64576,577408,22020096,1040187392,0,0,0,393744,0,256,0,8192,2097152,0,2147483648,0,0,327680,0,0,18,33554432,80,268435456,0,0,19,0,0,524288,0,64,0,2097152,0,16,33554432,0,2,0,65536,201326592,2147483648,256,1536,16384,32768,524288,0,256,8192,2097152,1,0,0,65536,262144,1048576,256,1536,32768,524288,0,4194304,134217728,536870912,0,4194304,131072,1536,32768,524288,134217728,268435456,2147483648,0,0,0,64,1536,32768,524288,4194304,0,1536,32768,0,0,16384,1073741824,0,0,32,512,2048,32768,0,1073741824,0,67174400,8,8,0,0,60,64576,8,268435456,134217728,131072,128,536870912,0,0,8,131072,4194304,-2146430976,16908320,547389524,547389524,547389524,555909216,555909216,555909216,555909216,564297840,564297844,564297844,564297844,564297844,564297844,1001055742,1001055742,1001056254,1001055742,1001056254,1001056254,1001055742,1001055742,1001056254,1001056254,1001056254,1001056254,1001056254,1001056254,0,0,64,128,8388608,0,84,2129920,8388608,16777216,0,0,9728,268435456,0,0,2048,32768,262144,524288,8388608,0,0,1280,2809856,58720256,939524096,0,0,0,524288,0,0,0,28,0,254,1792,2809856,58720256,939524096,0,939524096,0,0,64,2048,16384,32768,262144,50331648,4096,1048576,2147483648,0,2,4,16,64,128,256,0,20,64,32768,65536,2490368,16777216,33554432,0,0,16,33554432,2147483648,163840,0,0,0,1007232,52,0,0,0,104e4,64,128,1280,24576,163840,524288,2097152,58720256,402653184,536870912,128,1792,24576,163840,524288,25165824,0,0,0,1048576,4194304,0,56,128,1280,8192,524288,16384,131072,524288,58720256,402653184,0,56,128,1792,8192,16384,131072,256,262144,524288,33554432,134217728,2,4,24,32,128,1792,8192,524288,16777216,33554432,67108864,134217728,805306368,1073741824,2147483648,4,8,16,1024,16777216,4,8,16,402653184,0,8,256,512,2048,8192,32768,8388608,0,0,67108866,12,4,16384,0,0,4194304,2147483648,0,65536,67108864,0,0,0,131584,268435460,32768,8192,2048,16384,67108864,134217728,268435456,8192,3670016,2048,8192,0,65536,0,65536,8192,8192,34816,9216,29712,29712,29712,29840,536900624,29712,29840,29840,4224144,144384,144384,144384,-754647956,144384,144384,144384,144384,-754647956,-754647956,-754647956,-754647956,-754647940,-754647940,-754647940,-754647940,-754516884,-754647956,-754516884,-754516884,0,0,0,1052672,2,67108864,12,16384,0,65536,34816,0,0,0,1114112,44,64576,319029248,-1073741824,0,0,60,0,0,0,2097152,0,0,319160320,0,0,0,3670016,28672,0,0,0,4194304,0,0,0,8192,268435456,16,0,128,536870912,4194304,131072,0,131072,0,0,131072,1024,2048,61440,262144,318767104,-1073741824,318767104,-1073741824,0,0,112,25165824,28,0,0,0,8388608,0,0,393216,0,0,0,16777216,2147483648,0,24576,0,0,116,0,0,12,16,32,64,64,64,64,32,96,96,1,0,0,2,4,8,16,512,1024,16777216,33554432,402653184,0,0,0,262144,0,0,0,128,0,0,0,192,0,0,0,254,2,67108864,16384,0,65536,16384,32768,50331648,268435456,2147483648,0,0,50331648,268435456,0,2,4,112,128,256,0,524288,536870912,0,0,0,33554432,268435456,268435456,268435456,268435456,32,524288,1048576,33554432,67108864,134217728,67108864,134217728,536870912,0,2,4,134217728,268435456,0,0,0,29696,0,256,0,2048,256,262144,2113536,0,2,8,64,128,1024,4096,0,256,0,0,32,128,0,2097152,135790592,0,2,12,192,768,256,32768,0,0,128,131072,256,262144,0,0,220,0,0,0,32768,2097152,0,2,16,1048576,128,128,128,0,2097152,0,0,8388608,8388608,4096,0,0,0,32,0,0,2147483648,2097152,0,0,512,131072,4,0,0,33554624,4,131585,0,131585,4,393745,1610612736,1610612736,393753,393753,393753,393753,0,135790592,131585,131585,805708305,805708305,1879450129,1879450129,-483948553,-475559945,-483948553,-483948553,-475559945,1879450129,1879450129,1879450129,1879450129,805708561,-475559945,-475559945,-475559945,-475559945,-215504905,-475559945,-207116297,-207116297,-207116297,0,4096,4194304,1,512,32768,0,2113536,0,0,520,0,65,401936,805306368,0,0,0,393752,0,1879048192,0,0,1024,585,0,0,8,64,0,0,402192,0,0,0,33554432,0,0,7,19367920,-503316480,0,0,0,50331648,0,19376112,-234881024,0,2,301989888,0,3,22020096,0,1,285212672,0,0,33554432,33554432,8192,0,2048,16384,32768,524288,1048576,4194304,16777216,27764720,-234881024,0,0,1024,278528,24,0,0,0,167772160,8704,268435456,0,0,1998,59238400,-67108864,0,7,16,480,1536,32768,65536,393216,2097152,33554432,536870912,-1073741824,0,0,67108864,134217728,0,0,2048,131072,524288,4194304,8192,268435456,0,0,2048,4194304,0,0,16,224,256,1536,32768,65536,256,512,1024,32768,65536,192,0,0,131072,131072,131072,134217736,32768,131072,262144,2097152,16777216,4096,1,512,32768,0,0,513,32768,0,192,131072,0,4,8,512,2048,0,0,131072,2097152,16777216,0,4,8,2048,8192,32768,512,32768,131072,2097152,8388608,4,16,224,512,32768,4,524288,134217728,0,8388608,0,64,0,4096,32768,0,0,29824,536870912,16,192,32768,8388608,16777216,1073741824,0,0,2,4,16,192,32768,0,4096,0,128,0,16384,64,128,0,0,16384,16,64,128,8388608,0,0,4,0,0,128,512,3072,4096,16384,32768,4,128,0,0,32768,8388608,8388608,33554432,2147483648,0,4,16,32,64,128,256,1536,2048,16384,4096,0,33554432,0,4,32,32,524320,32,33554436,262144,33554432,0,0,0,256,0,0,0,512,2048,131072,33554432,536870912,0,0,0,528,2,2048,32768,0,4,268435456,0,2,4,32,524288,2,33554436,0,0,32768,268435456,33554436,4224,4224,0,8,16,402653184,536870912,0,0,96,2260992,262400,65536,65536,65536,10878976,16777216,33554432,536870912,4224,-1072627712,805306384,-1342177264,-1070006272,-1070006272,-1069989376,-1069989376,-1069989376,-1069989360,-1065795072,-1061600768,-1069989376,-258932720,-258932720,-258932720,-258932720,-225378288,-258932720,-225378288,1260767,1260767,34815199,1260767,1260767,34815199,34815199,1260767,34815199,1260767,169032927,169032927,169032927,169032927,1242774751,169032927,169032927,-1978450721,169032927,-1978450721,169032927,-1978450721,-1978450721,-225231649,-1173144353,-225231649,-225231649,-91013921,0,8,64,2048,16,536870912,0,0,524288,1048576,2097152,4194304,128,128,2048,2048,2048,0,7946240,12140544,0,0,524288,3145728,0,9502720,1610612736,0,0,0,32505856,208,15360,1245184,0,0,0,268435456,0,0,0,15,9633792,0,0,3670016,0,0,16384,0,67108864,0,0,536870912,131072,0,80,128,7168,8192,196608,1048576,196608,1048576,0,0,524288,134217728,1,2,12,80,128,0,3145728,0,0,0,3735552,8192,65536,131072,1048576,0,0,128,1024,4096,8192,0,0],r.TOKEN=["(0)","PragmaContents","DirCommentContents","DirPIContents","CDataSection","Wildcard","EQName","URILiteral","IntegerLiteral","DecimalLiteral","DoubleLiteral","StringLiteral","PredefinedEntityRef","'\"\"'","EscapeApos","ElementContentChar","QuotAttrContentChar","AposAttrContentChar","PITarget","NCName","QName","S","S","CharRef","CommentContents","EOF","'!'","'!='","'\"'","'#'","'#)'","'$'","'$$'","'%'","''''","'('","'(#'","'(:'","')'","'*'","'*'","'+'","','","'-'","'-->'","'.'","'..'","'/'","'//'","'/>'","':'","':)'","'::'","':='","';'","'<'","'<!--'","'</'","'<<'","'<='","'<?'","'='","'>'","'>='","'>>'","'?'","'?>'","'@'","'NaN'","'['","']'","'after'","'all'","'allowing'","'ancestor'","'ancestor-or-self'","'and'","'any'","'append'","'array'","'as'","'ascending'","'at'","'attribute'","'base-uri'","'before'","'boundary-space'","'break'","'by'","'case'","'cast'","'castable'","'catch'","'check'","'child'","'collation'","'collection'","'comment'","'constraint'","'construction'","'contains'","'content'","'context'","'continue'","'copy'","'copy-namespaces'","'count'","'decimal-format'","'decimal-separator'","'declare'","'default'","'delete'","'descendant'","'descendant-or-self'","'descending'","'diacritics'","'different'","'digit'","'distance'","'div'","'document'","'document-node'","'element'","'else'","'empty'","'empty-sequence'","'encoding'","'end'","'entire'","'eq'","'every'","'exactly'","'except'","'exit'","'external'","'false'","'first'","'following'","'following-sibling'","'for'","'foreach'","'foreign'","'from'","'ft-option'","'ftand'","'ftnot'","'ftor'","'function'","'ge'","'greatest'","'group'","'grouping-separator'","'gt'","'idiv'","'if'","'import'","'in'","'index'","'infinity'","'inherit'","'insensitive'","'insert'","'instance'","'integrity'","'intersect'","'into'","'is'","'item'","'json'","'json-item'","'jsoniq'","'key'","'language'","'last'","'lax'","'le'","'least'","'let'","'levels'","'loop'","'lowercase'","'lt'","'minus-sign'","'mod'","'modify'","'module'","'most'","'namespace'","'namespace-node'","'ne'","'next'","'no'","'no-inherit'","'no-preserve'","'node'","'nodes'","'not'","'null'","'object'","'occurs'","'of'","'on'","'only'","'option'","'or'","'order'","'ordered'","'ordering'","'paragraph'","'paragraphs'","'parent'","'pattern-separator'","'per-mille'","'percent'","'phrase'","'position'","'preceding'","'preceding-sibling'","'preserve'","'previous'","'processing-instruction'","'relationship'","'rename'","'replace'","'return'","'returning'","'revalidation'","'same'","'satisfies'","'schema'","'schema-attribute'","'schema-element'","'score'","'select'","'self'","'sensitive'","'sentence'","'sentences'","'skip'","'sliding'","'some'","'stable'","'start'","'stemming'","'stop'","'strict'","'strip'","'structured-item'","'switch'","'text'","'then'","'thesaurus'","'times'","'to'","'treat'","'true'","'try'","'tumbling'","'type'","'typeswitch'","'union'","'unique'","'unordered'","'updating'","'uppercase'","'using'","'validate'","'value'","'variable'","'version'","'weight'","'when'","'where'","'while'","'wildcards'","'window'","'with'","'without'","'word'","'words'","'zero-digit'","'{'","'{{'","'{|'","'|'","'||'","'|}'","'}'","'}}'"]},{}],9:[function(e,t,n){var r=n.XQueryParser=function i(e,t){function r(e,t){Wl=t,Jl=e,Kl=e.length,s(0,0,0)}function s(e,t,n){Ml=t,_l=t,Dl=e,Pl=t,Hl=n,Bl=0,Gl=n,ql=-1,Xl={},Wl.reset(Jl)}function o(){Wl.startNonterminal("Module",_l);switch(Dl){case 274:Cl(199);break;default:Ol=Dl}(Ol==64274||Ol==134930)&&u(),Nl(275);switch(Dl){case 182:Cl(194);break;default:Ol=Dl}switch(Ol){case 94390:xl(),a();break;default:xl(),Ia()}Wl.endNonterminal("Module",_l)}function u(){Wl.startNonterminal("VersionDecl",_l),wl(274),Nl(116);switch(Dl){case 125:wl(125),Nl(17),wl(11);break;default:wl(263),Nl(17),wl(11),Nl(109),Dl==125&&(wl(125),Nl(17),wl(11))}Nl(28),xl(),c(),Wl.endNonterminal("VersionDecl",_l)}function a(){Wl.startNonterminal("LibraryModule",_l),f(),Nl(138),xl(),l(),Wl.endNonterminal("LibraryModule",_l)}function f(){Wl.startNonterminal("ModuleDecl",_l),wl(182),Nl(61),wl(184),Nl(249),xl(),ja(),Nl(29),wl(60),Nl(15),wl(7),Nl(28),xl(),c(),Wl.endNonterminal("ModuleDecl",_l)}function l(){Wl.startNonterminal("Prolog",_l);for(;;){Nl(275);switch(Dl){case 108:Cl(214);break;case 153:Cl(202);break;default:Ol=Dl}if(Ol!=42604&&Ol!=43628&&Ol!=50284&&Ol!=53356&&Ol!=54380&&Ol!=55916&&Ol!=72300&&Ol!=93337&&Ol!=94316&&Ol!=104044&&Ol!=113772&&Ol!=115353)break;switch(Dl){case 108:Cl(179);break;default:Ol=Dl}if(Ol==55916){Ol=$l(0,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{_(),Ol=-1}catch(a){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(0,_l,Ol)}}switch(Ol){case-1:xl(),M();break;case 94316:xl(),O();break;case 153:xl(),C();break;case 72300:xl(),D();break;default:xl(),h()}Nl(28),xl(),c()}for(;;){Nl(275);switch(Dl){case 108:Cl(211);break;default:Ol=Dl}if(Ol!=16492&&Ol!=48748&&Ol!=51820&&Ol!=74348&&Ol!=79468&&Ol!=82540&&Ol!=101996&&Ol!=131692&&Ol!=134252)break;switch(Dl){case 108:Cl(175);break;default:Ol=Dl}switch(Ol){case 51820:xl(),R();break;case 101996:xl(),Q();break;default:xl(),P()}Nl(28),xl(),c()}Wl.endNonterminal("Prolog",_l)}function c(){Wl.startNonterminal("Separator",_l),wl(53),Wl.endNonterminal("Separator",_l)}function h(){Wl.startNonterminal("Setter",_l);switch(Dl){case 108:Cl(172);break;default:Ol=Dl}if(Ol==55916){Ol=$l(1,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{v(),Ol=-2}catch(a){try{Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),w(),Ol=-6}catch(f){Ol=-9}}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(1,_l,Ol)}}switch(Ol){case 43628:p();break;case-2:d();break;case 42604:m();break;case 50284:g();break;case 104044:y();break;case-6:b();break;case 113772:No();break;case 53356:E();break;default:T()}Wl.endNonterminal("Setter",_l)}function p(){Wl.startNonterminal("BoundarySpaceDecl",_l),wl(108),Nl(33),wl(85),Nl(133);switch(Dl){case 214:wl(214);break;default:wl(241)}Wl.endNonterminal("BoundarySpaceDecl",_l)}function d(){Wl.startNonterminal("DefaultCollationDecl",_l),wl(108),Nl(46),wl(109),Nl(38),wl(94),Nl(15),wl(7),Wl.endNonterminal("DefaultCollationDecl",_l)}function v(){El(108),Nl(46),El(109),Nl(38),El(94),Nl(15),El(7)}function m(){Wl.startNonterminal("BaseURIDecl",_l),wl(108),Nl(32),wl(83),Nl(15),wl(7),Wl.endNonterminal("BaseURIDecl",_l)}function g(){Wl.startNonterminal("ConstructionDecl",_l),wl(108),Nl(41),wl(98),Nl(133);switch(Dl){case 241:wl(241);break;default:wl(214)}Wl.endNonterminal("ConstructionDecl",_l)}function y(){Wl.startNonterminal("OrderingModeDecl",_l),wl(108),Nl(68),wl(203),Nl(131);switch(Dl){case 202:wl(202);break;default:wl(256)}Wl.endNonterminal("OrderingModeDecl",_l)}function b(){Wl.startNonterminal("EmptyOrderDecl",_l),wl(108),Nl(46),wl(109),Nl(67),wl(201),Nl(49),wl(123),Nl(121);switch(Dl){case 147:wl(147);break;default:wl(173)}Wl.endNonterminal("EmptyOrderDecl",_l)}function w(){El(108),Nl(46),El(109),Nl(67),El(201),Nl(49),El(123),Nl(121);switch(Dl){case 147:El(147);break;default:El(173)}}function E(){Wl.startNonterminal("CopyNamespacesDecl",_l),wl(108),Nl(44),wl(104),Nl(128),xl(),S(),Nl(25),wl(41),Nl(123),xl(),x(),Wl.endNonterminal("CopyNamespacesDecl",_l)}function S(){Wl.startNonterminal("PreserveMode",_l);switch(Dl){case 214:wl(214);break;default:wl(190)}Wl.endNonterminal("PreserveMode",_l)}function x(){Wl.startNonterminal("InheritMode",_l);switch(Dl){case 157:wl(157);break;default:wl(189)}Wl.endNonterminal("InheritMode",_l)}function T(){Wl.startNonterminal("DecimalFormatDecl",_l),wl(108),Nl(114);switch(Dl){case 106:wl(106),Nl(255),xl(),Da();break;default:wl(109),Nl(45),wl(106)}for(;;){Nl(181);if(Dl==53)break;xl(),N(),Nl(29),wl(60),Nl(17),wl(11)}Wl.endNonterminal("DecimalFormatDecl",_l)}function N(){Wl.startNonterminal("DFPropertyName",_l);switch(Dl){case 107:wl(107);break;case 149:wl(149);break;case 156:wl(156);break;case 179:wl(179);break;case 67:wl(67);break;case 209:wl(209);break;case 208:wl(208);break;case 275:wl(275);break;case 116:wl(116);break;default:wl(207)}Wl.endNonterminal("DFPropertyName",_l)}function C(){Wl.startNonterminal("Import",_l);switch(Dl){case 153:Cl(126);break;default:Ol=Dl}switch(Ol){case 115353:k();break;default:A()}Wl.endNonterminal("Import",_l)}function k(){Wl.startNonterminal("SchemaImport",_l),wl(153),Nl(73),wl(225),Nl(137),Dl!=7&&(xl(),L()),Nl(15),wl(7),Nl(108);if(Dl==81){wl(81),Nl(15),wl(7);for(;;){Nl(103);if(Dl!=41)break;wl(41),Nl(15),wl(7)}}Wl.endNonterminal("SchemaImport",_l)}function L(){Wl.startNonterminal("SchemaPrefix",_l);switch(Dl){case 184:wl(184),Nl(249),xl(),ja(),Nl(29),wl(60);break;default:wl(109),Nl(47),wl(121),Nl(61),wl(184)}Wl.endNonterminal("SchemaPrefix",_l)}function A(){Wl.startNonterminal("ModuleImport",_l),wl(153),Nl(60),wl(182),Nl(90),Dl==184&&(wl(184),Nl(249),xl(),ja(),Nl(29),wl(60)),Nl(15),wl(7),Nl(108);if(Dl==81){wl(81),Nl(15),wl(7);for(;;){Nl(103);if(Dl!=41)break;wl(41),Nl(15),wl(7)}}Wl.endNonterminal("ModuleImport",_l)}function O(){Wl.startNonterminal("NamespaceDecl",_l),wl(108),Nl(61),wl(184),Nl(249),xl(),ja(),Nl(29),wl(60),Nl(15),wl(7),Wl.endNonterminal("NamespaceDecl",_l)}function M(){Wl.startNonterminal("DefaultNamespaceDecl",_l),wl(108),Nl(46),wl(109),Nl(115);switch(Dl){case 121:wl(121);break;default:wl(145)}Nl(61),wl(184),Nl(15),wl(7),Wl.endNonterminal("DefaultNamespaceDecl",_l)}function _(){El(108),Nl(46),El(109),Nl(115);switch(Dl){case 121:El(121);break;default:El(145)}Nl(61),El(184),Nl(15),El(7)}function D(){Wl.startNonterminal("FTOptionDecl",_l),wl(108),Nl(52),wl(141),Nl(81),xl(),Bu(),Wl.endNonterminal("FTOptionDecl",_l)}function P(){Wl.startNonterminal("AnnotatedDecl",_l),wl(108);for(;;){Nl(170);if(Dl!=32&&Dl!=257)break;switch(Dl){case 257:xl(),H();break;default:xl(),B()}}switch(Dl){case 262:xl(),F();break;case 145:xl(),yl();break;case 95:xl(),ha();break;case 155:xl(),Ea();break;default:xl(),Sa()}Wl.endNonterminal("AnnotatedDecl",_l)}function H(){Wl.startNonterminal("CompatibilityAnnotation",_l),wl(257),Wl.endNonterminal("CompatibilityAnnotation",_l)}function B(){Wl.startNonterminal("Annotation",_l),wl(32),Nl(255),xl(),Da(),Nl(171);if(Dl==34){wl(34),Nl(154),xl(),ii();for(;;){Nl(101);if(Dl!=41)break;wl(41),Nl(154),xl(),ii()}wl(37)}Wl.endNonterminal("Annotation",_l)}function j(){El(32),Nl(255),Pa(),Nl(171);if(Dl==34){El(34),Nl(154),si();for(;;){Nl(101);if(Dl!=41)break;El(41),Nl(154),si()}El(37)}}function F(){Wl.startNonterminal("VarDecl",_l),wl(262),Nl(21),wl(31),Nl(255),xl(),li(),Nl(147),Dl==79&&(xl(),hs()),Nl(106);switch(Dl){case 52:wl(52),Nl(267),xl(),I();break;default:wl(133),Nl(104),Dl==52&&(wl(52),Nl(267),xl(),q())}Wl.endNonterminal("VarDecl",_l)}function I(){Wl.startNonterminal("VarValue",_l),Of(),Wl.endNonterminal("VarValue",_l)}function q(){Wl.startNonterminal("VarDefaultValue",_l),Of(),Wl.endNonterminal("VarDefaultValue",_l)}function R(){Wl.startNonterminal("ContextItemDecl",_l),wl(108),Nl(43),wl(101),Nl(55),wl(165),Nl(147),Dl==79&&(wl(79),Nl(260),xl(),ys()),Nl(106);switch(Dl){case 52:wl(52),Nl(267),xl(),I();break;default:wl(133),Nl(104),Dl==52&&(wl(52),Nl(267),xl(),q())}Wl.endNonterminal("ContextItemDecl",_l)}function U(){Wl.startNonterminal("ParamList",_l),W();for(;;){Nl(101);if(Dl!=41)break;wl(41),Nl(21),xl(),W()}Wl.endNonterminal("ParamList",_l)}function z(){X();for(;;){Nl(101);if(Dl!=41)break;El(41),Nl(21),X()}}function W(){Wl.startNonterminal("Param",_l),wl(31),Nl(255),xl(),Da(),Nl(143),Dl==79&&(xl(),hs()),Wl.endNonterminal("Param",_l)}function X(){El(31),Nl(255),Pa(),Nl(143),Dl==79&&ps()}function V(){Wl.startNonterminal("FunctionBody",_l),J(),Wl.endNonterminal("FunctionBody",_l)}function $(){K()}function J(){Wl.startNonterminal("EnclosedExpr",_l),wl(276),Nl(267),xl(),G(),wl(282),Wl.endNonterminal("EnclosedExpr",_l)}function K(){El(276),Nl(267),Y(),El(282)}function Q(){Wl.startNonterminal("OptionDecl",_l),wl(108),Nl(66),wl(199),Nl(255),xl(),Da(),Nl(17),wl(11),Wl.endNonterminal("OptionDecl",_l)}function G(){Wl.startNonterminal("Expr",_l),Of();for(;;){if(Dl!=41)break;wl(41),Nl(267),xl(),Of()}Wl.endNonterminal("Expr",_l)}function Y(){Mf();for(;;){if(Dl!=41)break;El(41),Nl(267),Mf()}}function Z(){Wl.startNonterminal("FLWORExpr",_l),tt();for(;;){Nl(173);if(Dl==220)break;xl(),rt()}xl(),rn(),Wl.endNonterminal("FLWORExpr",_l)}function et(){nt();for(;;){Nl(173);if(Dl==220)break;it()}sn()}function tt(){Wl.startNonterminal("InitialClause",_l);switch(Dl){case 137:Cl(141);break;default:Ol=Dl}switch(Ol){case 16009:st();break;case 174:vt();break;default:bt()}Wl.endNonterminal("InitialClause",_l)}function nt(){switch(Dl){case 137:Cl(141);break;default:Ol=Dl}switch(Ol){case 16009:ot();break;case 174:mt();break;default:wt()}}function rt(){Wl.startNonterminal("IntermediateClause",_l);switch(Dl){case 137:case 174:tt();break;case 266:It();break;case 148:Rt();break;case 105:jt();break;default:Kt()}Wl.endNonterminal("IntermediateClause",_l)}function it(){switch(Dl){case 137:case 174:nt();break;case 266:qt();break;case 148:Ut();break;case 105:Ft();break;default:Qt()}}function st(){Wl.startNonterminal("ForClause",_l),wl(137),Nl(21),xl(),ut();for(;;){if(Dl!=41)break;wl(41),Nl(21),xl(),ut()}Wl.endNonterminal("ForClause",_l)}function ot(){El(137),Nl(21),at();for(;;){if(Dl!=41)break;El(41),Nl(21),at()}}function ut(){Wl.startNonterminal("ForBinding",_l),wl(31),Nl(255),xl(),li(),Nl(164),Dl==79&&(xl(),hs()),Nl(158),Dl==72&&(xl(),ft()),Nl(150),Dl==81&&(xl(),ct()),Nl(122),Dl==228&&(xl(),pt()),Nl(53),wl(154),Nl(267),xl(),Of(),Wl.endNonterminal("ForBinding",_l)}function at(){El(31),Nl(255),ci(),Nl(164),Dl==79&&ps(),Nl(158),Dl==72&&lt(),Nl(150),Dl==81&&ht(),Nl(122),Dl==228&&dt(),Nl(53),El(154),Nl(267),Mf()}function ft(){Wl.startNonterminal("AllowingEmpty",_l),wl(72),Nl(49),wl(123),Wl.endNonterminal("AllowingEmpty",_l)}function lt(){El(72),Nl(49),El(123)}function ct(){Wl.startNonterminal("PositionalVar",_l),wl(81),Nl(21),wl(31),Nl(255),xl(),li(),Wl.endNonterminal("PositionalVar",_l)}function ht(){El(81),Nl(21),El(31),Nl(255),ci()}function pt(){Wl.startNonterminal("FTScoreVar",_l),wl(228),Nl(21),wl(31),Nl(255),xl(),li(),Wl.endNonterminal("FTScoreVar",_l)}function dt(){El(228),Nl(21),El(31),Nl(255),ci()}function vt(){Wl.startNonterminal("LetClause",_l),wl(174),Nl(96),xl(),gt();for(;;){if(Dl!=41)break;wl(41),Nl(96),xl(),gt()}Wl.endNonterminal("LetClause",_l)}function mt(){El(174),Nl(96),yt();for(;;){if(Dl!=41)break;El(41),Nl(96),yt()}}function gt(){Wl.startNonterminal("LetBinding",_l);switch(Dl){case 31:wl(31),Nl(255),xl(),li(),Nl(105),Dl==79&&(xl(),hs());break;default:pt()}Nl(27),wl(52),Nl(267),xl(),Of(),Wl.endNonterminal("LetBinding",_l)}function yt(){switch(Dl){case 31:El(31),Nl(255),ci(),Nl(105),Dl==79&&ps();break;default:dt()}Nl(27),El(52),Nl(267),Mf()}function bt(){Wl.startNonterminal("WindowClause",_l),wl(137),Nl(135);switch(Dl){case 251:xl(),Et();break;default:xl(),xt()}Wl.endNonterminal("WindowClause",_l)}function wt(){El(137),Nl(135);switch(Dl){case 251:St();break;default:Tt()}}function Et(){Wl.startNonterminal("TumblingWindowClause",_l),wl(251),Nl(85),wl(269),Nl(21),wl(31),Nl(255),xl(),li(),Nl(110),Dl==79&&(xl(),hs()),Nl(53),wl(154),Nl(267),xl(),Of(),xl(),Nt();if(Dl==126||Dl==198)xl(),kt();Wl.endNonterminal("TumblingWindowClause",_l)}function St(){El(251),Nl(85),El(269),Nl(21),El(31),Nl(255),ci(),Nl(110),Dl==79&&ps(),Nl(53),El(154),Nl(267),Mf(),Ct(),(Dl==126||Dl==198)&&Lt()}function xt(){Wl.startNonterminal("SlidingWindowClause",_l),wl(234),Nl(85),wl(269),Nl(21),wl(31),Nl(255),xl(),li(),Nl(110),Dl==79&&(xl(),hs()),Nl(53),wl(154),Nl(267),xl(),Of(),xl(),Nt(),xl(),kt(),Wl.endNonterminal("SlidingWindowClause",_l)}function Tt(){El(234),Nl(85),El(269),Nl(21),El(31),Nl(255),ci(),Nl(110),Dl==79&&ps(),Nl(53),El(154),Nl(267),Mf(),Ct(),Lt()}function Nt(){Wl.startNonterminal("WindowStartCondition",_l),wl(237),Nl(163),xl(),At(),Nl(83),wl(265),Nl(267),xl(),Of(),Wl.endNonterminal("WindowStartCondition",_l)}function Ct(){El(237),Nl(163),Ot(),Nl(83),El(265),Nl(267),Mf()}function kt(){Wl.startNonterminal("WindowEndCondition",_l),Dl==198&&wl(198),Nl(50),wl(126),Nl(163),xl(),At(),Nl(83),wl(265),Nl(267),xl(),Of(),Wl.endNonterminal("WindowEndCondition",_l)}function Lt(){Dl==198&&El(198),Nl(50),El(126),Nl(163),Ot(),Nl(83),El(265),Nl(267),Mf()}function At(){Wl.startNonterminal("WindowVars",_l),Dl==31&&(wl(31),Nl(255),xl(),Mt()),Nl(159),Dl==81&&(xl(),ct()),Nl(153),Dl==215&&(wl(215),Nl(21),wl(31),Nl(255),xl(),Dt()),Nl(127),Dl==187&&(wl(187),Nl(21),wl(31),Nl(255),xl(),Ht()),Wl.endNonterminal("WindowVars",_l)}function Ot(){Dl==31&&(El(31),Nl(255),_t()),Nl(159),Dl==81&&ht(),Nl(153),Dl==215&&(El(215),Nl(21),El(31),Nl(255),Pt()),Nl(127),Dl==187&&(El(187),Nl(21),El(31),Nl(255),Bt())}function Mt(){Wl.startNonterminal("CurrentItem",_l),Da(),Wl.endNonterminal("CurrentItem",_l)}function _t(){Pa()}function Dt(){Wl.startNonterminal("PreviousItem",_l),Da(),Wl.endNonterminal("PreviousItem",_l)}function Pt(){Pa()}function Ht(){Wl.startNonterminal("NextItem",_l),Da(),Wl.endNonterminal("NextItem",_l)}function Bt(){Pa()}function jt(){Wl.startNonterminal("CountClause",_l),wl(105),Nl(21),wl(31),Nl(255),xl(),li(),Wl.endNonterminal("CountClause",_l)}function Ft(){El(105),Nl(21),El(31),Nl(255),ci()}function It(){Wl.startNonterminal("WhereClause",_l),wl(266),Nl(267),xl(),Of(),Wl.endNonterminal("WhereClause",_l)}function qt(){El(266),Nl(267),Mf()}function Rt(){Wl.startNonterminal("GroupByClause",_l),wl(148),Nl(34),wl(87),Nl(267),xl(),zt(),Wl.endNonterminal("GroupByClause",_l)}function Ut(){El(148),Nl(34),El(87),Nl(267),Wt()}function zt(){Wl.startNonterminal("GroupingSpecList",_l),Xt();for(;;){Nl(176);if(Dl!=41)break;wl(41),Nl(267),xl(),Xt()}Wl.endNonterminal("GroupingSpecList",_l)}function Wt(){Vt();for(;;){Nl(176);if(Dl!=41)break;El(41),Nl(267),Vt()}}function Xt(){Wl.startNonterminal("GroupingSpec",_l);switch(Dl){case 31:Cl(255);break;default:Ol=Dl}if(Ol==3103||Ol==35871||Ol==36895||Ol==37407||Ol==37919||Ol==38431||Ol==39455||Ol==39967||Ol==40479||Ol==40991||Ol==41503||Ol==42015||Ol==42527||Ol==43039||Ol==43551||Ol==44063||Ol==45087||Ol==45599||Ol==46111||Ol==46623||Ol==47647||Ol==48159||Ol==49183||Ol==49695||Ol==50207||Ol==51743||Ol==52255||Ol==52767||Ol==53279||Ol==53791||Ol==54303||Ol==55327||Ol==55839||Ol==56351||Ol==56863||Ol==57375||Ol==57887||Ol==60447||Ol==60959||Ol==61471||Ol==61983||Ol==62495||Ol==63007||Ol==63519||Ol==64031||Ol==64543||Ol==65567||Ol==66079||Ol==67103||Ol==67615||Ol==68127||Ol==68639||Ol==69151||Ol==69663||Ol==70175||Ol==72223||Ol==74271||Ol==74783||Ol==75807||Ol==76831||Ol==77343||Ol==77855||Ol==78367||Ol==78879||Ol==79391||Ol==81439||Ol==81951||Ol==82463||Ol==82975||Ol==83487||Ol==83999||Ol==84511||Ol==85023||Ol==85535||Ol==87071||Ol==87583||Ol==88095||Ol==89119||Ol==90143||Ol==91167||Ol==92191||Ol==92703||Ol==93215||Ol==94239||Ol==94751||Ol==95263||Ol==97823||Ol==98335||Ol==99359||Ol==101407||Ol==101919||Ol==102431||Ol==102943||Ol==103455||Ol==103967||Ol==105503||Ol==108575||Ol==109087||Ol==110623||Ol==111647||Ol==112159||Ol==112671||Ol==113183||Ol==113695||Ol==114719||Ol==115231||Ol==115743||Ol==116255||Ol==116767||Ol==117279||Ol==119839||Ol==120351||Ol==120863||Ol==121375||Ol==122911||Ol==123935||Ol==124447||Ol==124959||Ol==127007||Ol==127519||Ol==128031||Ol==128543||Ol==129055||Ol==129567||Ol==130079||Ol==131103||Ol==131615||Ol==133151||Ol==133663||Ol==134175||Ol==134687||Ol==136223||Ol==136735||Ol==138271||Ol==140319){Ol=$l(2,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Jt(),Nl(183);if(Dl==52||Dl==79)Dl==79&&ps(),Nl(27),El(52),Nl(267),Mf();Dl==94&&(El(94),Nl(15),El(7)),Ol=-1}catch(a){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(2,_l,Ol)}}switch(Ol){case-1:$t(),Nl(183);if(Dl==52||Dl==79)Dl==79&&(xl(),hs()),Nl(27),wl(52),Nl(267),xl(),Of();Dl==94&&(wl(94),Nl(15),wl(7));break;default:Of()}Wl.endNonterminal("GroupingSpec",_l)}function Vt(){switch(Dl){case 31:Cl(255);break;default:Ol=Dl}if(Ol==3103||Ol==35871||Ol==36895||Ol==37407||Ol==37919||Ol==38431||Ol==39455||Ol==39967||Ol==40479||Ol==40991||Ol==41503||Ol==42015||Ol==42527||Ol==43039||Ol==43551||Ol==44063||Ol==45087||Ol==45599||Ol==46111||Ol==46623||Ol==47647||Ol==48159||Ol==49183||Ol==49695||Ol==50207||Ol==51743||Ol==52255||Ol==52767||Ol==53279||Ol==53791||Ol==54303||Ol==55327||Ol==55839||Ol==56351||Ol==56863||Ol==57375||Ol==57887||Ol==60447||Ol==60959||Ol==61471||Ol==61983||Ol==62495||Ol==63007||Ol==63519||Ol==64031||Ol==64543||Ol==65567||Ol==66079||Ol==67103||Ol==67615||Ol==68127||Ol==68639||Ol==69151||Ol==69663||Ol==70175||Ol==72223||Ol==74271||Ol==74783||Ol==75807||Ol==76831||Ol==77343||Ol==77855||Ol==78367||Ol==78879||Ol==79391||Ol==81439||Ol==81951||Ol==82463||Ol==82975||Ol==83487||Ol==83999||Ol==84511||Ol==85023||Ol==85535||Ol==87071||Ol==87583||Ol==88095||Ol==89119||Ol==90143||Ol==91167||Ol==92191||Ol==92703||Ol==93215||Ol==94239||Ol==94751||Ol==95263||Ol==97823||Ol==98335||Ol==99359||Ol==101407||Ol==101919||Ol==102431||Ol==102943||Ol==103455||Ol==103967||Ol==105503||Ol==108575||Ol==109087||Ol==110623||Ol==111647||Ol==112159||Ol==112671||Ol==113183||Ol==113695||Ol==114719||Ol==115231||Ol==115743||Ol==116255||Ol==116767||Ol==117279||Ol==119839||Ol==120351||Ol==120863||Ol==121375||Ol==122911||Ol==123935||Ol==124447||Ol==124959||Ol==127007||Ol==127519||Ol==128031||Ol==128543||Ol==129055||Ol==129567||Ol==130079||Ol==131103||Ol==131615||Ol==133151||Ol==133663||Ol==134175||Ol==134687||Ol==136223||Ol==136735||Ol==138271||Ol==140319){Ol=$l(2,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Jt(),Nl(183);if(Dl==52||Dl==79)Dl==79&&ps(),Nl(27),El(52),Nl(267),Mf();Dl==94&&(El(94),Nl(15),El(7)),Vl(2,t,-1),Ol=-3}catch(a){Ol=-2,Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(2,t,-2)}}}switch(Ol){case-1:Jt(),Nl(183);if(Dl==52||Dl==79)Dl==79&&ps(),Nl(27),El(52),Nl(267),Mf();Dl==94&&(El(94),Nl(15),El(7));break;case-3:break;default:Mf()}}function $t(){Wl.startNonterminal("GroupingVariable",_l),wl(31),Nl(255),xl(),li(),Wl.endNonterminal("GroupingVariable",_l)}function Jt(){El(31),Nl(255),ci()}function Kt(){Wl.startNonterminal("OrderByClause",_l);switch(Dl){case 201:wl(201),Nl(34),wl(87);break;default:wl(236),Nl(67),wl(201),Nl(34),wl(87)}Nl(267),xl(),Gt(),Wl.endNonterminal("OrderByClause",_l)}function Qt(){switch(Dl){case 201:El(201),Nl(34),El(87);break;default:El(236),Nl(67),El(201),Nl(34),El(87)}Nl(267),Yt()}function Gt(){Wl.startNonterminal("OrderSpecList",_l),Zt();for(;;){Nl(176);if(Dl!=41)break;wl(41),Nl(267),xl(),Zt()}Wl.endNonterminal("OrderSpecList",_l)}function Yt(){en();for(;;){Nl(176);if(Dl!=41)break;El(41),Nl(267),en()}}function Zt(){Wl.startNonterminal("OrderSpec",_l),Of(),xl(),tn(),Wl.endNonterminal("OrderSpec",_l)}function en(){Mf(),nn()}function tn(){Wl.startNonterminal("OrderModifier",_l);if(Dl==80||Dl==113)switch(Dl){case 80:wl(80);break;default:wl(113)}Nl(180);if(Dl==123){wl(123),Nl(121);switch(Dl){case 147:wl(147);break;default:wl(173)}}Nl(177),Dl==94&&(wl(94),Nl(15),wl(7)),Wl.endNonterminal("OrderModifier",_l)}function nn(){if(Dl==80||Dl==113)switch(Dl){case 80:El(80);break;default:El(113)}Nl(180);if(Dl==123){El(123),Nl(121);switch(Dl){case 147:El(147);break;default:El(173)}}Nl(177),Dl==94&&(El(94),Nl(15),El(7))}function rn(){Wl.startNonterminal("ReturnClause",_l),wl(220),Nl(267),xl(),Of(),Wl.endNonterminal("ReturnClause",_l)}function sn(){El(220),Nl(267),Mf()}function on(){Wl.startNonterminal("QuantifiedExpr",_l);switch(Dl){case 235:wl(235);break;default:wl(129)}Nl(21),wl(31),Nl(255),xl(),li(),Nl(110),Dl==79&&(xl(),hs()),Nl(53),wl(154),Nl(267),xl(),Of();for(;;){if(Dl!=41)break;wl(41),Nl(21),wl(31),Nl(255),xl(),li(),Nl(110),Dl==79&&(xl(),hs()),Nl(53),wl(154),Nl(267),xl(),Of()}wl(224),Nl(267),xl(),Of(),Wl.endNonterminal("QuantifiedExpr",_l)}function un(){switch(Dl){case 235:El(235);break;default:El(129)}Nl(21),El(31),Nl(255),ci(),Nl(110),Dl==79&&ps(),Nl(53),El(154),Nl(267),Mf();for(;;){if(Dl!=41)break;El(41),Nl(21),El(31),Nl(255),ci(),Nl(110),Dl==79&&ps(),Nl(53),El(154),Nl(267),Mf()}El(224),Nl(267),Mf()}function an(){Wl.startNonterminal("SwitchExpr",_l),wl(243),Nl(22),wl(34),Nl(267),xl(),G(),wl(37);for(;;){Nl(35),xl(),ln();if(Dl!=88)break}wl(109),Nl(70),wl(220),Nl(267),xl(),Of(),Wl.endNonterminal("SwitchExpr",_l)}function fn(){El(243),Nl(22),El(34),Nl(267),Y(),El(37);for(;;){Nl(35),cn();if(Dl!=88)break}El(109),Nl(70),El(220),Nl(267),Mf()}function ln(){Wl.startNonterminal("SwitchCaseClause",_l);for(;;){wl(88),Nl(267),xl(),hn();if(Dl!=88)break}wl(220),Nl(267),xl(),Of(),Wl.endNonterminal("SwitchCaseClause",_l)}function cn(){for(;;){El(88),Nl(267),pn();if(Dl!=88)break}El(220),Nl(267),Mf()}function hn(){Wl.startNonterminal("SwitchCaseOperand",_l),Of(),Wl.endNonterminal("SwitchCaseOperand",_l)}function pn(){Mf()}function dn(){Wl.startNonterminal("TypeswitchExpr",_l),wl(253),Nl(22),wl(34),Nl(267),xl(),G(),wl(37);for(;;){Nl(35),xl(),mn();if(Dl!=88)break}wl(109),Nl(95),Dl==31&&(wl(31),Nl(255),xl(),li()),Nl(70),wl(220),Nl(267),xl(),Of(),Wl.endNonterminal("TypeswitchExpr",_l)}function vn(){El(253),Nl(22),El(34),Nl(267),Y(),El(37);for(;;){Nl(35),gn();if(Dl!=88)break}El(109),Nl(95),Dl==31&&(El(31),Nl(255),ci()),Nl(70),El(220),Nl(267),Mf()}function mn(){Wl.startNonterminal("CaseClause",_l),wl(88),Nl(262),Dl==31&&(wl(31),Nl(255),xl(),li(),Nl(30),wl(79)),Nl(260),xl(),yn(),wl(220),Nl(267),xl(),Of(),Wl.endNonterminal("CaseClause",_l)}function gn(){El(88),Nl(262),Dl==31&&(El(31),Nl(255),ci(),Nl(30),El(79)),Nl(260),bn(),El(220),Nl(267),Mf()}function yn(){Wl.startNonterminal("SequenceTypeUnion",_l),ds();for(;;){Nl(134);if(Dl!=279)break;wl(279),Nl(260),xl(),ds()}Wl.endNonterminal("SequenceTypeUnion",_l)}function bn(){vs();for(;;){Nl(134);if(Dl!=279)break;El(279),Nl(260),vs()}}function wn(){Wl.startNonterminal("IfExpr",_l),wl(152),Nl(22),wl(34),Nl(267),xl(),G(),wl(37),Nl(77),wl(245),Nl(267),xl(),Of(),wl(122),Nl(267),xl(),Of(),Wl.endNonterminal("IfExpr",_l)}function En(){El(152),Nl(22),El(34),Nl(267),Y(),El(37),Nl(77),El(245),Nl(267),Mf(),El(122),Nl(267),Mf()}function Sn(){Wl.startNonterminal("TryCatchExpr",_l),Tn();for(;;){Nl(36),xl(),Ln(),Nl(184);if(Dl!=91)break}Wl.endNonterminal("TryCatchExpr",_l)}function xn(){Nn();for(;;){Nl(36),An(),Nl(184);if(Dl!=91)break}}function Tn(){Wl.startNonterminal("TryClause",_l),wl(250),Nl(87),wl(276),Nl(267),xl(),Cn(),wl(282),Wl.endNonterminal("TryClause",_l)}function Nn(){El(250),Nl(87),El(276),Nl(267),kn(),El(282)}function Cn(){Wl.startNonterminal("TryTargetExpr",_l),G(),Wl.endNonterminal("TryTargetExpr",_l)}function kn(){Y()}function Ln(){Wl.startNonterminal("CatchClause",_l),wl(91),Nl(257),xl(),On(),wl(276),Nl(267),xl(),G(),wl(282),Wl.endNonterminal("CatchClause",_l)}function An(){El(91),Nl(257),Mn(),El(276),Nl(267),Y(),El(282)}function On(){Wl.startNonterminal("CatchErrorList",_l),Jr();for(;;){Nl(136);if(Dl!=279)break;wl(279),Nl(257),xl(),Jr()}Wl.endNonterminal("CatchErrorList",_l)}function Mn(){Kr();for(;;){Nl(136);if(Dl!=279)break;El(279),Nl(257),Kr()}}function _n(){Wl.startNonterminal("OrExpr",_l),Pn();for(;;){if(Dl!=200)break;wl(200),Nl(267),xl(),Pn()}Wl.endNonterminal("OrExpr",_l)}function Dn(){Hn();for(;;){if(Dl!=200)break;El(200),Nl(267),Hn()}}function Pn(){Wl.startNonterminal("AndExpr",_l),Bn();for(;;){if(Dl!=75)break;wl(75),Nl(267),xl(),Bn()}Wl.endNonterminal("AndExpr",_l)}function Hn(){jn();for(;;){if(Dl!=75)break;El(75),Nl(267),jn()}}function Bn(){Wl.startNonterminal("ComparisonExpr",_l),Fn();if(Dl==27||Dl==54||Dl==57||Dl==58||Dl==60||Dl==61||Dl==62||Dl==63||Dl==128||Dl==146||Dl==150||Dl==164||Dl==172||Dl==178||Dl==186){switch(Dl){case 128:case 146:case 150:case 172:case 178:case 186:xl(),dr();break;case 57:case 63:case 164:xl(),mr();break;default:xl(),hr()}Nl(267),xl(),Fn()}Wl.endNonterminal("ComparisonExpr",_l)}function jn(){In();if(Dl==27||Dl==54||Dl==57||Dl==58||Dl==60||Dl==61||Dl==62||Dl==63||Dl==128||Dl==146||Dl==150||Dl==164||Dl==172||Dl==178||Dl==186){switch(Dl){case 128:case 146:case 150:case 172:case 178:case 186:vr();break;case 57:case 63:case 164:gr();break;default:pr()}Nl(267),In()}}function Fn(){Wl.startNonterminal("FTContainsExpr",_l),qn(),Dl==99&&(wl(99),Nl(76),wl(244),Nl(162),xl(),Vo(),Dl==271&&(xl(),la())),Wl.endNonterminal("FTContainsExpr",_l)}function In(){Rn(),Dl==99&&(El(99),Nl(76),El(244),Nl(162),$o(),Dl==271&&ca())}function qn(){Wl.startNonterminal("StringConcatExpr",_l),Un();for(;;){if(Dl!=280)break;wl(280),Nl(267),xl(),Un()}Wl.endNonterminal("StringConcatExpr",_l)}function Rn(){zn();for(;;){if(Dl!=280)break;El(280),Nl(267),zn()}}function Un(){Wl.startNonterminal("RangeExpr",_l),Wn(),Dl==248&&(wl(248),Nl(267),xl(),Wn()),Wl.endNonterminal("RangeExpr",_l)}function zn(){Xn(),Dl==248&&(El(248),Nl(267),Xn())}function Wn(){Wl.startNonterminal("AdditiveExpr",_l),Vn();for(;;){if(Dl!=40&&Dl!=42)break;switch(Dl){case 40:wl(40);break;default:wl(42)}Nl(267),xl(),Vn()}Wl.endNonterminal("AdditiveExpr",_l)}function Xn(){$n();for(;;){if(Dl!=40&&Dl!=42)break;switch(Dl){case 40:El(40);break;default:El(42)}Nl(267),$n()}}function Vn(){Wl.startNonterminal("MultiplicativeExpr",_l),Jn();for(;;){if(Dl!=38&&Dl!=118&&Dl!=151&&Dl!=180)break;switch(Dl){case 38:wl(38);break;case 118:wl(118);break;case 151:wl(151);break;default:wl(180)}Nl(267),xl(),Jn()}Wl.endNonterminal("MultiplicativeExpr",_l)}function $n(){Kn();for(;;){if(Dl!=38&&Dl!=118&&Dl!=151&&Dl!=180)break;switch(Dl){case 38:El(38);break;case 118:El(118);break;case 151:El(151);break;default:El(180)}Nl(267),Kn()}}function Jn(){Wl.startNonterminal("UnionExpr",_l),Qn();for(;;){if(Dl!=254&&Dl!=279)break;switch(Dl){case 254:wl(254);break;default:wl(279)}Nl(267),xl(),Qn()}Wl.endNonterminal("UnionExpr",_l)}function Kn(){Gn();for(;;){if(Dl!=254&&Dl!=279)break;switch(Dl){case 254:El(254);break;default:El(279)}Nl(267),Gn()}}function Qn(){Wl.startNonterminal("IntersectExceptExpr",_l),Yn();for(;;){Nl(223);if(Dl!=131&&Dl!=162)break;switch(Dl){case 162:wl(162);break;default:wl(131)}Nl(267),xl(),Yn()}Wl.endNonterminal("IntersectExceptExpr",_l)}function Gn(){Zn();for(;;){Nl(223);if(Dl!=131&&Dl!=162)break;switch(Dl){case 162:El(162);break;default:El(131)}Nl(267),Zn()}}function Yn(){Wl.startNonterminal("InstanceofExpr",_l),er(),Nl(224),Dl==160&&(wl(160),Nl(64),wl(196),Nl(260),xl(),ds()),Wl.endNonterminal("InstanceofExpr",_l)}function Zn(){tr(),Nl(224),Dl==160&&(El(160),Nl(64),El(196),Nl(260),vs())}function er(){Wl.startNonterminal("TreatExpr",_l),nr(),Nl(225),Dl==249&&(wl(249),Nl(30),wl(79),Nl(260),xl(),ds()),Wl.endNonterminal("TreatExpr",_l)}function tr(){rr(),Nl(225),Dl==249&&(El(249),Nl(30),El(79),Nl(260),vs())}function nr(){Wl.startNonterminal("CastableExpr",_l),ir(),Nl(226),Dl==90&&(wl(90),Nl(30),wl(79),Nl(255),xl(),ls()),Wl.endNonterminal("CastableExpr",_l)}function rr(){sr(),Nl(226),Dl==90&&(El(90),Nl(30),El(79),Nl(255),cs())}function ir(){Wl.startNonterminal("CastExpr",_l),or(),Nl(228),Dl==89&&(wl(89),Nl(30),wl(79),Nl(255),xl(),ls()),Wl.endNonterminal("CastExpr",_l)}function sr(){ur(),Nl(228),Dl==89&&(El(89),Nl(30),El(79),Nl(255),cs())}function or(){Wl.startNonterminal("UnaryExpr",_l);for(;;){Nl(267);if(Dl!=40&&Dl!=42)break;switch(Dl){case 42:wl(42);break;default:wl(40)}}xl(),ar(),Wl.endNonterminal("UnaryExpr",_l)}function ur(){for(;;){Nl(267);if(Dl!=40&&Dl!=42)break;switch(Dl){case 42:El(42);break;default:El(40)}}fr()}function ar(){Wl.startNonterminal("ValueExpr",_l);switch(Dl){case 260:Cl(248);break;default:Ol=Dl}switch(Ol){case 87812:case 123140:case 129284:case 141572:yr();break;case 35:Sr();break;default:lr()}Wl.endNonterminal("ValueExpr",_l)}function fr(){switch(Dl){case 260:Cl(248);break;default:Ol=Dl}switch(Ol){case 87812:case 123140:case 129284:case 141572:br();break;case 35:xr();break;default:cr()}}function lr(){Wl.startNonterminal("SimpleMapExpr",_l),Cr();for(;;){if(Dl!=26)break;wl(26),Nl(266),xl(),Cr()}Wl.endNonterminal("SimpleMapExpr",_l)}function cr(){kr();for(;;){if(Dl!=26)break;El(26),Nl(266),kr()}}function hr(){Wl.startNonterminal("GeneralComp",_l);switch(Dl){case 60:wl(60);break;case 27:wl(27);break;case 54:wl(54);break;case 58:wl(58);break;case 61:wl(61);break;default:wl(62)}Wl.endNonterminal("GeneralComp",_l)}function pr(){switch(Dl){case 60:El(60);break;case 27:El(27);break;case 54:El(54);break;case 58:El(58);break;case 61:El(61);break;default:El(62)}}function dr(){Wl.startNonterminal("ValueComp",_l);switch(Dl){case 128:wl(128);break;case 186:wl(186);break;case 178:wl(178);break;case 172:wl(172);break;case 150:wl(150);break;default:wl(146)}Wl.endNonterminal("ValueComp",_l)}function vr(){switch(Dl){case 128:El(128);break;case 186:El(186);break;case 178:El(178);break;case 172:El(172);break;case 150:El(150);break;default:El(146)}}function mr(){Wl.startNonterminal("NodeComp",_l);switch(Dl){case 164:wl(164);break;case 57:wl(57);break;default:wl(63)}Wl.endNonterminal("NodeComp",_l)}function gr(){switch(Dl){case 164:El(164);break;case 57:El(57);break;default:El(63)}}function yr(){Wl.startNonterminal("ValidateExpr",_l),wl(260),Nl(160);if(Dl!=276)switch(Dl){case 252:wl(252),Nl(255),xl(),vo();break;default:xl(),wr()}Nl(87),wl(276),Nl(267),xl(),G(),wl(282),Wl.endNonterminal("ValidateExpr",_l)}function br(){El(260),Nl(160);if(Dl!=276)switch(Dl){case 252:El(252),Nl(255),mo();break;default:Er()}Nl(87),El(276),Nl(267),Y(),El(282)}function wr(){Wl.startNonterminal("ValidationMode",_l);switch(Dl){case 171:wl(171);break;default:wl(240)}Wl.endNonterminal("ValidationMode",_l)}function Er(){switch(Dl){case 171:El(171);break;default:El(240)}}function Sr(){Wl.startNonterminal("ExtensionExpr",_l);for(;;){xl(),Tr(),Nl(100);if(Dl!=35)break}wl(276),Nl(274),Dl!=282&&(xl(),G()),wl(282),Wl.endNonterminal("ExtensionExpr",_l)}function xr(){for(;;){Nr(),Nl(100);if(Dl!=35)break}El(276),Nl(274),Dl!=282&&Y(),El(282)}function Tr(){Wl.startNonterminal("Pragma",_l),wl(35),kl(252),Dl==21&&wl(21),Da(),kl(10),Dl==21&&(wl(21),kl(0),wl(1)),kl(5),wl(30),Wl.endNonterminal("Pragma",_l)}function Nr(){El(35),kl(252),Dl==21&&El(21),Pa(),kl(10),Dl==21&&(El(21),kl(0),El(1)),kl(5),El(30)}function Cr(){Wl.startNonterminal("PathExpr",_l);switch(Dl){case 46:wl(46),Nl(286);switch(Dl){case 25:case 26:case 27:case 37:case 38:case 40:case 41:case 42:case 49:case 53:case 57:case 58:case 60:case 61:case 62:case 63:case 69:case 87:case 99:case 205:case 232:case 247:case 273:case 279:case 280:case 281:case 282:break;default:xl(),Lr()}break;case 47:wl(47),Nl(265),xl(),Lr();break;default:Lr()}Wl.endNonterminal("PathExpr",_l)}function kr(){switch(Dl){case 46:El(46),Nl(286);switch(Dl){case 25:case 26:case 27:case 37:case 38:case 40:case 41:case 42:case 49:case 53:case 57:case 58:case 60:case 61:case 62:case 63:case 69:case 87:case 99:case 205:case 232:case 247:case 273:case 279:case 280:case 281:case 282:break;default:Ar()}break;case 47:El(47),Nl(265),Ar();break;default:Ar()}}function Lr(){Wl.startNonterminal("RelativePathExpr",_l),Or();for(;;){switch(Dl){case 26:Cl(266);break;default:Ol=Dl}if(Ol!=25&&Ol!=27&&Ol!=37&&Ol!=38&&Ol!=40&&Ol!=41&&Ol!=42&&Ol!=46&&Ol!=47&&Ol!=49&&Ol!=53&&Ol!=54&&Ol!=57&&Ol!=58&&Ol!=60&&Ol!=61&&Ol!=62&&Ol!=63&&Ol!=69&&Ol!=70&&Ol!=75&&Ol!=79&&Ol!=80&&Ol!=81&&Ol!=84&&Ol!=87&&Ol!=88&&Ol!=89&&Ol!=90&&Ol!=94&&Ol!=99&&Ol!=105&&Ol!=109&&Ol!=113&&Ol!=118&&Ol!=122&&Ol!=123&&Ol!=126&&Ol!=128&&Ol!=131&&Ol!=137&&Ol!=146&&Ol!=148&&Ol!=150&&Ol!=151&&Ol!=160&&Ol!=162&&Ol!=163&&Ol!=164&&Ol!=172&&Ol!=174&&Ol!=178&&Ol!=180&&Ol!=181&&Ol!=186&&Ol!=198&&Ol!=200&&Ol!=201&&Ol!=205&&Ol!=220&&Ol!=224&&Ol!=232&&Ol!=236&&Ol!=237&&Ol!=247&&Ol!=248&&Ol!=249&&Ol!=254&&Ol!=266&&Ol!=270&&Ol!=273&&Ol!=279&&Ol!=280&&Ol!=281&&Ol!=282&&Ol!=23578&&Ol!=24090){Ol=$l(3,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{switch(Dl){case 46:El(46);break;case 47:El(47);break;default:El(26)}Nl(265),Mr(),Ol=-1}catch(a){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(3,_l,Ol)}}if(Ol!=-1&&Ol!=46&&Ol!=47)break;switch(Dl){case 46:wl(46);break;case 47:wl(47);break;default:wl(26)}Nl(265),xl(),Or()}Wl.endNonterminal("RelativePathExpr",_l)}function Ar(){Mr();for(;;){switch(Dl){case 26:Cl(266);break;default:Ol=Dl}if(Ol!=25&&Ol!=27&&Ol!=37&&Ol!=38&&Ol!=40&&Ol!=41&&Ol!=42&&Ol!=46&&Ol!=47&&Ol!=49&&Ol!=53&&Ol!=54&&Ol!=57&&Ol!=58&&Ol!=60&&Ol!=61&&Ol!=62&&Ol!=63&&Ol!=69&&Ol!=70&&Ol!=75&&Ol!=79&&Ol!=80&&Ol!=81&&Ol!=84&&Ol!=87&&Ol!=88&&Ol!=89&&Ol!=90&&Ol!=94&&Ol!=99&&Ol!=105&&Ol!=109&&Ol!=113&&Ol!=118&&Ol!=122&&Ol!=123&&Ol!=126&&Ol!=128&&Ol!=131&&Ol!=137&&Ol!=146&&Ol!=148&&Ol!=150&&Ol!=151&&Ol!=160&&Ol!=162&&Ol!=163&&Ol!=164&&Ol!=172&&Ol!=174&&Ol!=178&&Ol!=180&&Ol!=181&&Ol!=186&&Ol!=198&&Ol!=200&&Ol!=201&&Ol!=205&&Ol!=220&&Ol!=224&&Ol!=232&&Ol!=236&&Ol!=237&&Ol!=247&&Ol!=248&&Ol!=249&&Ol!=254&&Ol!=266&&Ol!=270&&Ol!=273&&Ol!=279&&Ol!=280&&Ol!=281&&Ol!=282&&Ol!=23578&&Ol!=24090){Ol=$l(3,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{switch(Dl){case 46:El(46);break;case 47:El(47);break;default:El(26)}Nl(265),Mr(),Vl(3,t,-1);continue}catch(a){Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(3,t,-2);break}}}if(Ol!=-1&&Ol!=46&&Ol!=47)break;switch(Dl){case 46:El(46);break;case 47:El(47);break;default:El(26)}Nl(265),Mr()}}function Or(){Wl.startNonterminal("StepExpr",_l);switch(Dl){case 82:Cl(285);break;case 121:Cl(283);break;case 184:case 216:Cl(282);break;case 96:case 119:case 202:case 244:case 256:Cl(247);break;case 78:case 124:case 152:case 165:case 167:case 242:case 243:case 253:Cl(240);break;case 73:case 74:case 93:case 111:case 112:case 135:case 136:case 206:case 212:case 213:case 229:Cl(246);break;case 6:case 70:case 72:case 75:case 77:case 79:case 80:case 81:case 83:case 84:case 85:case 86:case 88:case 89:case 90:case 91:case 94:case 97:case 98:case 101:case 102:case 103:case 104:case 105:case 106:case 108:case 109:case 110:case 113:case 118:case 120:case 122:case 123:case 125:case 126:case 128:case 129:case 131:case 132:case 133:case 134:case 137:case 141:case 145:case 146:case 148:case 150:case 151:case 153:case 154:case 155:case 159:case 160:case 161:case 162:case 163:case 164:case 166:case 170:case 171:case 172:case 174:case 176:case 178:case 180:case 181:case 182:case 185:case 186:case 191:case 192:case 194:case 198:case 199:case 200:case 201:case 203:case 218:case 219:case 220:case 221:case 222:case 224:case 225:case 226:case 227:case 228:case 234:case 235:case 236:case 237:case 240:case 248:case 249:case 250:case 251:case 252:case 254:case 257:case 260:case 261:case 262:case 263:case 266:case 267:case 270:case 274:Cl(244);break;default:Ol=Dl}if(Ol==35922||Ol==35961||Ol==36024||Ol==36056||Ol==38482||Ol==38521||Ol==38584||Ol==38616||Ol==40530||Ol==40569||Ol==40632||Ol==40664||Ol==41042||Ol==41081||Ol==41144||Ol==41176||Ol==41554||Ol==41593||Ol==41656||Ol==41688||Ol==43090||Ol==43129||Ol==43192||Ol==43224||Ol==45138||Ol==45177||Ol==45240||Ol==45272||Ol==45650||Ol==45689||Ol==45752||Ol==45784||Ol==46162||Ol==46201||Ol==46264||Ol==46296||Ol==48210||Ol==48249||Ol==48312||Ol==48344||Ol==53842||Ol==53881||Ol==53944||Ol==53976||Ol==55890||Ol==55929||Ol==55992||Ol==56024||Ol==57938||Ol==57977||Ol==58040||Ol==58072||Ol==60498||Ol==60537||Ol==60600||Ol==60632||Ol==62546||Ol==62585||Ol==62648||Ol==62680||Ol==63058||Ol==63097||Ol==63160||Ol==63192||Ol==64594||Ol==64633||Ol==64696||Ol==64728||Ol==65618||Ol==65657||Ol==65720||Ol==65752||Ol==67154||Ol==67193||Ol==67256||Ol==67288||Ol==70226||Ol==70265||Ol==70328||Ol==70360||Ol==74834||Ol==74873||Ol==74936||Ol==74968||Ol==75858||Ol==75897||Ol==75960||Ol==75992||Ol==76882||Ol==76921||Ol==76984||Ol==77016||Ol==77394||Ol==77433||Ol==77496||Ol==77528||Ol==82002||Ol==82041||Ol==82104||Ol==82136||Ol==83026||Ol==83065||Ol==83128||Ol==83160||Ol==83538||Ol==83577||Ol==83640||Ol==83672||Ol==84050||Ol==84089||Ol==84152||Ol==84184||Ol==88146||Ol==88185||Ol==88248||Ol==88280||Ol==89170||Ol==89209||Ol==89272||Ol==89304||Ol==91218||Ol==91257||Ol==91320||Ol==91352||Ol==92242||Ol==92281||Ol==92344||Ol==92376||Ol==92754||Ol==92793||Ol==92856||Ol==92888||Ol==95314||Ol==95353||Ol==95416||Ol==95448||Ol==101458||Ol==101497||Ol==101560||Ol==101592||Ol==102482||Ol==102521||Ol==102584||Ol==102616||Ol==102994||Ol==103033||Ol==103096||Ol==103128||Ol==112722||Ol==112761||Ol==112824||Ol==112856||Ol==114770||Ol==114809||Ol==114872||Ol==114904||Ol==120914||Ol==120953||Ol==121016||Ol==121048||Ol==121426||Ol==121465||Ol==121528||Ol==121560||Ol==127058||Ol==127097||Ol==127160||Ol==127192||Ol==127570||Ol==127609||Ol==127672||Ol==127704||Ol==130130||Ol==130169||Ol==130232||Ol==130264||Ol==136274||Ol==136313||Ol==136376||Ol==136408||Ol==138322||Ol==138361||Ol==138424||Ol==138456){Ol=$l(4,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Gr(),Ol=-1}catch(a){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(4,_l,Ol)}}switch(Ol){case-1:case 8:case 9:case 10:case 11:case 31:case 32:case 34:case 44:case 54:case 55:case 59:case 68:case 276:case 278:case 3154:case 3193:case 9912:case 9944:case 14854:case 14918:case 14920:case 14921:case 14922:case 14923:case 14925:case 14926:case 14927:case 14928:case 14929:case 14930:case 14931:case 14932:case 14933:case 14934:case 14936:case 14937:case 14938:case 14939:case 14941:case 14942:case 14944:case 14945:case 14946:case 14949:case 14950:case 14951:case 14952:case 14953:case 14954:case 14956:case 14957:case 14958:case 14959:case 14960:case 14961:case 14966:case 14967:case 14968:case 14969:case 14970:case 14971:case 14972:case 14973:case 14974:case 14976:case 14977:case 14979:case 14980:case 14981:case 14982:case 14983:case 14984:case 14985:case 14989:case 14993:case 14994:case 14996:case 14998:case 14999:case 15e3:case 15001:case 15002:case 15003:case 15007:case 15008:case 15009:case 15010:case 15011:case 15012:case 15013:case 15014:case 15015:case 15018:case 15019:case 15020:case 15022:case 15024:case 15026:case 15028:case 15029:case 15030:case 15032:case 15033:case 15034:case 15039:case 15040:case 15042:case 15046:case 15047:case 15048:case 15049:case 15050:case 15051:case 15054:case 15060:case 15061:case 15064:case 15066:case 15067:case 15068:case 15069:case 15070:case 15072:case 15073:case 15074:case 15075:case 15076:case 15077:case 15082:case 15083:case 15084:case 15085:case 15088:case 15090:case 15091:case 15092:case 15096:case 15097:case 15098:case 15099:case 15100:case 15101:case 15102:case 15104:case 15105:case 15108:case 15109:case 15110:case 15111:case 15114:case 15115:case 15118:case 15122:case 17414:case 17478:case 17480:case 17481:case 17482:case 17483:case 17485:case 17487:case 17488:case 17489:case 17491:case 17492:case 17493:case 17494:case 17496:case 17497:case 17498:case 17499:case 17501:case 17502:case 17505:case 17506:case 17509:case 17510:case 17511:case 17512:case 17513:case 17514:case 17516:case 17517:case 17518:case 17519:case 17520:case 17521:case 17526:case 17527:case 17530:case 17531:case 17533:case 17534:case 17536:case 17537:case 17539:case 17540:case 17541:case 17542:case 17543:case 17544:case 17545:case 17549:case 17553:case 17554:case 17556:case 17558:case 17559:case 17561:case 17562:case 17563:case 17567:case 17568:case 17569:case 17570:case 17571:case 17572:case 17574:case 17578:case 17579:case 17580:case 17582:case 17584:case 17586:case 17588:case 17589:case 17590:case 17592:case 17594:case 17600:case 17602:case 17606:case 17607:case 17608:case 17609:case 17610:case 17611:case 17614:case 17620:case 17621:case 17626:case 17627:case 17628:case 17629:case 17630:case 17632:case 17633:case 17636:case 17637:case 17642:case 17643:case 17644:case 17645:case 17648:case 17656:case 17657:case 17658:case 17659:case 17660:case 17662:case 17664:case 17665:case 17668:case 17669:case 17670:case 17671:case 17674:case 17675:case 17678:case 17682:case 36946:case 36985:case 37048:case 37080:case 37458:case 37497:case 37560:case 37592:case 37970:case 38009:case 38072:case 38104:case 39506:case 39545:case 39608:case 39640:case 40018:case 40057:case 42066:case 42105:case 42168:case 42200:case 42578:case 42617:case 42680:case 42712:case 43602:case 43641:case 43704:case 43736:case 44114:case 44153:case 44216:case 44248:case 46674:case 46713:case 46776:case 46808:case 47698:case 47737:case 47800:case 47832:case 49234:case 49273:case 49336:case 49368:case 49746:case 49785:case 49848:case 49880:case 50258:case 50297:case 50360:case 50392:case 51794:case 51833:case 51896:case 51928:case 52306:case 52345:case 52408:case 52440:case 52818:case 52857:case 52920:case 52952:case 53330:case 53369:case 53432:case 53464:case 54354:case 54393:case 54456:case 54488:case 55378:case 55417:case 55480:case 55512:case 56402:case 56441:case 56504:case 56536:case 56914:case 56953:case 57016:case 57048:case 57426:case 57465:case 57528:case 57560:case 61010:case 61049:case 61112:case 61144:case 61522:case 61561:case 61624:case 61656:case 62034:case 62073:case 62136:case 62168:case 63570:case 63609:case 63672:case 63704:case 64082:case 64121:case 64184:case 64216:case 66130:case 66169:case 66232:case 66264:case 67666:case 67705:case 67768:case 67800:case 68178:case 68217:case 68280:case 68312:case 68690:case 68729:case 68792:case 68824:case 69202:case 69241:case 69304:case 69336:case 69714:case 69753:case 69816:case 69848:case 72274:case 72313:case 72376:case 72408:case 74322:case 74361:case 74424:case 74456:case 77906:case 77945:case 78008:case 78040:case 78418:case 78457:case 78520:case 78552:case 78930:case 78969:case 79032:case 79064:case 79442:case 79481:case 79544:case 79576:case 81490:case 81529:case 81592:case 81624:case 82514:case 82553:case 82616:case 82648:case 84562:case 84601:case 84664:case 84696:case 85074:case 85113:case 85176:case 85208:case 85586:case 85625:case 87122:case 87161:case 87224:case 87256:case 87634:case 87673:case 87736:case 87768:case 90194:case 90233:case 90296:case 90328:case 93266:case 93305:case 93368:case 93400:case 94290:case 94329:case 94392:case 94424:case 94802:case 94841:case 94904:case 94936:case 97874:case 97913:case 97976:case 98008:case 98386:case 98425:case 98488:case 98520:case 99410:case 99449:case 99512:case 99544:case 101970:case 102009:case 102072:case 102104:case 103506:case 103545:case 103608:case 103640:case 104018:case 104057:case 104120:case 104152:case 105554:case 105593:case 105656:case 105688:case 108626:case 108665:case 108728:case 108760:case 109138:case 109177:case 109240:case 109272:case 110674:case 110713:case 110776:case 110808:case 111698:case 111737:case 111800:case 111832:case 112210:case 112249:case 112312:case 112344:case 113234:case 113273:case 113336:case 113368:case 113746:case 113785:case 113848:case 113880:case 115282:case 115321:case 115384:case 115416:case 115794:case 115833:case 115896:case 115928:case 116306:case 116345:case 116408:case 116440:case 116818:case 116857:case 116920:case 116952:case 117330:case 117369:case 117432:case 117464:case 119890:case 119929:case 119992:case 120024:case 120402:case 120441:case 120504:case 120536:case 122962:case 123001:case 123064:case 123096:case 123986:case 124025:case 124498:case 124537:case 124600:case 124632:case 125010:case 125049:case 125112:case 125144:case 128082:case 128121:case 128184:case 128216:case 128594:case 128633:case 128696:case 128728:case 129106:case 129145:case 129208:case 129240:case 129618:case 129657:case 129720:case 129752:case 131154:case 131193:case 131256:case 131288:case 131666:case 131705:case 131768:case 131800:case 133202:case 133241:case 133304:case 133336:case 133714:case 133753:case 133816:case 133848:case 134226:case 134265:case 134328:case 134360:case 134738:case 134777:case 134840:case 134872:case 136786:case 136825:case 136888:case 136920:case 140370:case 140409:case 140472:case 140504:case 141394:case 141408:case 141431:case 141433:case 141496:case 141514:case 141528:case 141556:case 141568:Qr();break;default:_r()}Wl.endNonterminal("StepExpr",_l)}function Mr(){switch(Dl){case 82:Cl(285);break;case 121:Cl(283);break;case 184:case 216:Cl(282);break;case 96:case 119:case 202:case 244:case 256:Cl(247);break;case 78:case 124:case 152:case 165:case 167:case 242:case 243:case 253:Cl(240);break;case 73:case 74:case 93:case 111:case 112:case 135:case 136:case 206:case 212:case 213:case 229:Cl(246);break;case 6:case 70:case 72:case 75:case 77:case 79:case 80:case 81:case 83:case 84:case 85:case 86:case 88:case 89:case 90:case 91:case 94:case 97:case 98:case 101:case 102:case 103:case 104:case 105:case 106:case 108:case 109:case 110:case 113:case 118:case 120:case 122:case 123:case 125:case 126:case 128:case 129:case 131:case 132:case 133:case 134:case 137:case 141:case 145:case 146:case 148:case 150:case 151:case 153:case 154:case 155:case 159:case 160:case 161:case 162:case 163:case 164:case 166:case 170:case 171:case 172:case 174:case 176:case 178:case 180:case 181:case 182:case 185:case 186:case 191:case 192:case 194:case 198:case 199:case 200:case 201:case 203:case 218:case 219:case 220:case 221:case 222:case 224:case 225:case 226:case 227:case 228:case 234:case 235:case 236:case 237:case 240:case 248:case 249:case 250:case 251:case 252:case 254:case 257:case 260:case 261:case 262:case 263:case 266:case 267:case 270:case 274:Cl(244);break;default:Ol=Dl}if(Ol==35922||Ol==35961||Ol==36024||Ol==36056||Ol==38482||Ol==38521||Ol==38584||Ol==38616||Ol==40530||Ol==40569||Ol==40632||Ol==40664||Ol==41042||Ol==41081||Ol==41144||Ol==41176||Ol==41554||Ol==41593||Ol==41656||Ol==41688||Ol==43090||Ol==43129||Ol==43192||Ol==43224||Ol==45138||Ol==45177||Ol==45240||Ol==45272||Ol==45650||Ol==45689||Ol==45752||Ol==45784||Ol==46162||Ol==46201||Ol==46264||Ol==46296||Ol==48210||Ol==48249||Ol==48312||Ol==48344||Ol==53842||Ol==53881||Ol==53944||Ol==53976||Ol==55890||Ol==55929||Ol==55992||Ol==56024||Ol==57938||Ol==57977||Ol==58040||Ol==58072||Ol==60498||Ol==60537||Ol==60600||Ol==60632||Ol==62546||Ol==62585||Ol==62648||Ol==62680||Ol==63058||Ol==63097||Ol==63160||Ol==63192||Ol==64594||Ol==64633||Ol==64696||Ol==64728||Ol==65618||Ol==65657||Ol==65720||Ol==65752||Ol==67154||Ol==67193||Ol==67256||Ol==67288||Ol==70226||Ol==70265||Ol==70328||Ol==70360||Ol==74834||Ol==74873||Ol==74936||Ol==74968||Ol==75858||Ol==75897||Ol==75960||Ol==75992||Ol==76882||Ol==76921||Ol==76984||Ol==77016||Ol==77394||Ol==77433||Ol==77496||Ol==77528||Ol==82002||Ol==82041||Ol==82104||Ol==82136||Ol==83026||Ol==83065||Ol==83128||Ol==83160||Ol==83538||Ol==83577||Ol==83640||Ol==83672||Ol==84050||Ol==84089||Ol==84152||Ol==84184||Ol==88146||Ol==88185||Ol==88248||Ol==88280||Ol==89170||Ol==89209||Ol==89272||Ol==89304||Ol==91218||Ol==91257||Ol==91320||Ol==91352||Ol==92242||Ol==92281||Ol==92344||Ol==92376||Ol==92754||Ol==92793||Ol==92856||Ol==92888||Ol==95314||Ol==95353||Ol==95416||Ol==95448||Ol==101458||Ol==101497||Ol==101560||Ol==101592||Ol==102482||Ol==102521||Ol==102584||Ol==102616||Ol==102994||Ol==103033||Ol==103096||Ol==103128||Ol==112722||Ol==112761||Ol==112824||Ol==112856||Ol==114770||Ol==114809||Ol==114872||Ol==114904||Ol==120914||Ol==120953||Ol==121016||Ol==121048||Ol==121426||Ol==121465||Ol==121528||Ol==121560||Ol==127058||Ol==127097||Ol==127160||Ol==127192||Ol==127570||Ol==127609||Ol==127672||Ol==127704||Ol==130130||Ol==130169||Ol==130232||Ol==130264||Ol==136274||Ol==136313||Ol==136376||Ol==136408||Ol==138322||Ol==138361||Ol==138424||Ol==138456){Ol=$l(4,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Gr(),Vl(4,t,-1),Ol=-3}catch(a){Ol=-2,Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(4,t,-2)}}}switch(Ol){case-1:case 8:case 9:case 10:case 11:case 31:case 32:case 34:case 44:case 54:case 55:case 59:case 68:case 276:case 278:case 3154:case 3193:case 9912:case 9944:case 14854:case 14918:case 14920:case 14921:case 14922:case 14923:case 14925:case 14926:case 14927:case 14928:case 14929:case 14930:case 14931:case 14932:case 14933:case 14934:case 14936:case 14937:case 14938:case 14939:case 14941:case 14942:case 14944:case 14945:case 14946:case 14949:case 14950:case 14951:case 14952:case 14953:case 14954:case 14956:case 14957:case 14958:case 14959:case 14960:case 14961:case 14966:case 14967:case 14968:case 14969:case 14970:case 14971:case 14972:case 14973:case 14974:case 14976:case 14977:case 14979:case 14980:case 14981:case 14982:case 14983:case 14984:case 14985:case 14989:case 14993:case 14994:case 14996:case 14998:case 14999:case 15e3:case 15001:case 15002:case 15003:case 15007:case 15008:case 15009:case 15010:case 15011:case 15012:case 15013:case 15014:case 15015:case 15018:case 15019:case 15020:case 15022:case 15024:case 15026:case 15028:case 15029:case 15030:case 15032:case 15033:case 15034:case 15039:case 15040:case 15042:case 15046:case 15047:case 15048:case 15049:case 15050:case 15051:case 15054:case 15060:case 15061:case 15064:case 15066:case 15067:case 15068:case 15069:case 15070:case 15072:case 15073:case 15074:case 15075:case 15076:case 15077:case 15082:case 15083:case 15084:case 15085:case 15088:case 15090:case 15091:case 15092:case 15096:case 15097:case 15098:case 15099:case 15100:case 15101:case 15102:case 15104:case 15105:case 15108:case 15109:case 15110:case 15111:case 15114:case 15115:case 15118:case 15122:case 17414:case 17478:case 17480:case 17481:case 17482:case 17483:case 17485:case 17487:case 17488:case 17489:case 17491:case 17492:case 17493:case 17494:case 17496:case 17497:case 17498:case 17499:case 17501:case 17502:case 17505:case 17506:case 17509:case 17510:case 17511:case 17512:case 17513:case 17514:case 17516:case 17517:case 17518:case 17519:case 17520:case 17521:case 17526:case 17527:case 17530:case 17531:case 17533:case 17534:case 17536:case 17537:case 17539:case 17540:case 17541:case 17542:case 17543:case 17544:case 17545:case 17549:case 17553:case 17554:case 17556:case 17558:case 17559:case 17561:case 17562:case 17563:case 17567:case 17568:case 17569:case 17570:case 17571:case 17572:case 17574:case 17578:case 17579:case 17580:case 17582:case 17584:case 17586:case 17588:case 17589:case 17590:case 17592:case 17594:case 17600:case 17602:case 17606:case 17607:case 17608:case 17609:case 17610:case 17611:case 17614:case 17620:case 17621:case 17626:case 17627:case 17628:case 17629:case 17630:case 17632:case 17633:case 17636:case 17637:case 17642:case 17643:case 17644:case 17645:case 17648:case 17656:case 17657:case 17658:case 17659:case 17660:case 17662:case 17664:case 17665:case 17668:case 17669:case 17670:case 17671:case 17674:case 17675:case 17678:case 17682:case 36946:case 36985:case 37048:case 37080:case 37458:case 37497:case 37560:case 37592:case 37970:case 38009:case 38072:case 38104:case 39506:case 39545:case 39608:case 39640:case 40018:case 40057:case 42066:case 42105:case 42168:case 42200:case 42578:case 42617:case 42680:case 42712:case 43602:case 43641:case 43704:case 43736:case 44114:case 44153:case 44216:case 44248:case 46674:case 46713:case 46776:case 46808:case 47698:case 47737:case 47800:case 47832:case 49234:case 49273:case 49336:case 49368:case 49746:case 49785:case 49848:case 49880:case 50258:case 50297:case 50360:case 50392:case 51794:case 51833:case 51896:case 51928:case 52306:case 52345:case 52408:case 52440:case 52818:case 52857:case 52920:case 52952:case 53330:case 53369:case 53432:case 53464:case 54354:case 54393:case 54456:case 54488:case 55378:case 55417:case 55480:case 55512:case 56402:case 56441:case 56504:case 56536:case 56914:case 56953:case 57016:case 57048:case 57426:case 57465:case 57528:case 57560:case 61010:case 61049:case 61112:case 61144:case 61522:case 61561:case 61624:case 61656:case 62034:case 62073:case 62136:case 62168:case 63570:case 63609:case 63672:case 63704:case 64082:case 64121:case 64184:case 64216:case 66130:case 66169:case 66232:case 66264:case 67666:case 67705:case 67768:case 67800:case 68178:case 68217:case 68280:case 68312:case 68690:case 68729:case 68792:case 68824:case 69202:case 69241:case 69304:case 69336:case 69714:case 69753:case 69816:case 69848:case 72274:case 72313:case 72376:case 72408:case 74322:case 74361:case 74424:case 74456:case 77906:case 77945:case 78008:case 78040:case 78418:case 78457:case 78520:case 78552:case 78930:case 78969:case 79032:case 79064:case 79442:case 79481:case 79544:case 79576:case 81490:case 81529:case 81592:case 81624:case 82514:case 82553:case 82616:case 82648:case 84562:case 84601:case 84664:case 84696:case 85074:case 85113:case 85176:case 85208:case 85586:case 85625:case 87122:case 87161:case 87224:case 87256:case 87634:case 87673:case 87736:case 87768:case 90194:case 90233:case 90296:case 90328:case 93266:case 93305:case 93368:case 93400:case 94290:case 94329:case 94392:case 94424:case 94802:case 94841:case 94904:case 94936:case 97874:case 97913:case 97976:case 98008:case 98386:case 98425:case 98488:case 98520:case 99410:case 99449:case 99512:case 99544:case 101970:case 102009:case 102072:case 102104:case 103506:case 103545:case 103608:case 103640:case 104018:case 104057:case 104120:case 104152:case 105554:case 105593:case 105656:case 105688:case 108626:case 108665:case 108728:case 108760:case 109138:case 109177:case 109240:case 109272:case 110674:case 110713:case 110776:case 110808:case 111698:case 111737:case 111800:case 111832:case 112210:case 112249:case 112312:case 112344:case 113234:case 113273:case 113336:case 113368:case 113746:case 113785:case 113848:case 113880:case 115282:case 115321:case 115384:case 115416:case 115794:case 115833:case 115896:case 115928:case 116306:case 116345:case 116408:case 116440:case 116818:case 116857:case 116920:case 116952:case 117330:case 117369:case 117432:case 117464:case 119890:case 119929:case 119992:case 120024:case 120402:case 120441:case 120504:case 120536:case 122962:case 123001:case 123064:case 123096:case 123986:case 124025:case 124498:case 124537:case 124600:case 124632:case 125010:case 125049:case 125112:case 125144:case 128082:case 128121:case 128184:case 128216:case 128594:case 128633:case 128696:case 128728:case 129106:case 129145:case 129208:case 129240:case 129618:case 129657:case 129720:case 129752:case 131154:case 131193:case 131256:case 131288:case 131666:case 131705:case 131768:case 131800:case 133202:case 133241:case 133304:case 133336:case 133714:case 133753:case 133816:case 133848:case 134226:case 134265:case 134328:case 134360:case 134738:case 134777:case 134840:case 134872:case 136786:case 136825:case 136888:case 136920:case 140370:case 140409:case 140472:case 140504:case 141394:case 141408:case 141431:case 141433:case 141496:case 141514:case 141528:case 141556:case 141568:Gr();break;case-3:break;default:Dr()}}function _r(){Wl.startNonterminal("AxisStep",_l);switch(Dl){case 73:case 74:case 206:case 212:case 213:Cl(242);break;default:Ol=Dl}switch(Ol){case 45:case 26185:case 26186:case 26318:case 26324:case 26325:qr();break;default:Pr()}Nl(238),xl(),ei(),Wl.endNonterminal("AxisStep",_l)}function Dr(){switch(Dl){case 73:case 74:case 206:case 212:case 213:Cl(242);break;default:Ol=Dl}switch(Ol){case 45:case 26185:case 26186:case 26318:case 26324:case 26325:Rr();break;default:Hr()}Nl(238),ti()}function Pr(){Wl.startNonterminal("ForwardStep",_l);switch(Dl){case 82:Cl(245);break;case 93:case 111:case 112:case 135:case 136:case 229:Cl(242);break;default:Ol=Dl}switch(Ol){case 26194:case 26205:case 26223:case 26224:case 26247:case 26248:case 26341:Br(),Nl(257),xl(),Vr();break;default:Fr()}Wl.endNonterminal("ForwardStep",_l)}function Hr(){switch(Dl){case 82:Cl(245);break;case 93:case 111:case 112:case 135:case 136:case 229:Cl(242);break;default:Ol=Dl}switch(Ol){case 26194:case 26205:case 26223:case 26224:case 26247:case 26248:case 26341:jr(),Nl(257),$r();break;default:Ir()}}function Br(){Wl.startNonterminal("ForwardAxis",_l);switch(Dl){case 93:wl(93),Nl(26),wl(51);break;case 111:wl(111),Nl(26),wl(51);break;case 82:wl(82),Nl(26),wl(51);break;case 229:wl(229),Nl(26),wl(51);break;case 112:wl(112),Nl(26),wl(51);break;case 136:wl(136),Nl(26),wl(51);break;default:wl(135),Nl(26),wl(51)}Wl.endNonterminal("ForwardAxis",_l)}function jr(){switch(Dl){case 93:El(93),Nl(26),El(51);break;case 111:El(111),Nl(26),El(51);break;case 82:El(82),Nl(26),El(51);break;case 229:El(229),Nl(26),El(51);break;case 112:El(112),Nl(26),El(51);break;case 136:El(136),Nl(26),El(51);break;default:El(135),Nl(26),El(51)}}function Fr(){Wl.startNonterminal("AbbrevForwardStep",_l),Dl==66&&wl(66),Nl(257),xl(),Vr(),Wl.endNonterminal("AbbrevForwardStep",_l)}function Ir(){Dl==66&&El(66),Nl(257),$r()}function qr(){Wl.startNonterminal("ReverseStep",_l);switch(Dl){case 45:Wr();break;default:Ur(),Nl(257),xl(),Vr()}Wl.endNonterminal("ReverseStep",_l)}function Rr(){switch(Dl){case 45:Xr();break;default:zr(),Nl(257),$r()}}function Ur(){Wl.startNonterminal("ReverseAxis",_l);switch(Dl){case 206:wl(206),Nl(26),wl(51);break;case 73:wl(73),Nl(26),wl(51);break;case 213:wl(213),Nl(26),wl(51);break;case 212:wl(212),Nl(26),wl(51);break;default:wl(74),Nl(26),wl(51)}Wl.endNonterminal("ReverseAxis",_l)}function zr(){switch(Dl){case 206:El(206),Nl(26),El(51);break;case 73:El(73),Nl(26),El(51);break;case 213:El(213),Nl(26),El(51);break;case 212:El(212),Nl(26),El(51);break;default:El(74),Nl(26),El(51)}}function Wr(){Wl.startNonterminal("AbbrevReverseStep",_l),wl(45),Wl.endNonterminal("AbbrevReverseStep",_l)}function Xr(){El(45)}function Vr(){Wl.startNonterminal("NodeTest",_l);switch(Dl){case 82:case 96:case 120:case 121:case 185:case 191:case 216:case 226:case 227:case 244:Cl(241);break;default:Ol=Dl}switch(Ol){case 17490:case 17504:case 17528:case 17529:case 17593:case 17599:case 17624:case 17634:case 17635:case 17652:_s();break;default:Jr()}Wl.endNonterminal("NodeTest",_l)}function $r(){switch(Dl){case 82:case 96:case 120:case 121:case 185:case 191:case 216:case 226:case 227:case 244:Cl(241);break;default:Ol=Dl}switch(Ol){case 17490:case 17504:case 17528:case 17529:case 17593:case 17599:case 17624:case 17634:case 17635:case 17652:Ds();break;default:Kr()}}function Jr(){Wl.startNonterminal("NameTest",_l);switch(Dl){case 5:wl(5);break;default:Da()}Wl.endNonterminal("NameTest",_l)}function Kr(){switch(Dl){case 5:El(5);break;default:Pa()}}function Qr(){Wl.startNonterminal("PostfixExpr",_l),il();for(;;){Nl(241);if(Dl!=34&&Dl!=68)break;switch(Dl){case 68:xl(),ni();break;default:xl(),Yr()}}Wl.endNonterminal("PostfixExpr",_l)}function Gr(){sl();for(;;){Nl(241);if(Dl!=34&&Dl!=68)break;switch(Dl){case 68:ri();break;default:Zr()}}}function Yr(){Wl.startNonterminal("ArgumentList",_l),wl(34),Nl(276);if(Dl!=37){xl(),Si();for(;;){Nl(101);if(Dl!=41)break;wl(41),Nl(271),xl(),Si()}}wl(37),Wl.endNonterminal("ArgumentList",_l)}function Zr(){El(34),Nl(276);if(Dl!=37){xi();for(;;){Nl(101);if(Dl!=41)break;El(41),Nl(271),xi()}}El(37)}function ei(){Wl.startNonterminal("PredicateList",_l);for(;;){Nl(238);if(Dl!=68)break;xl(),ni()}Wl.endNonterminal("PredicateList",_l)}function ti(){for(;;){Nl(238);if(Dl!=68)break;ri()}}function ni(){Wl.startNonterminal("Predicate",_l),wl(68),Nl(267),xl(),G(),wl(69),Wl.endNonterminal("Predicate",_l)}function ri(){El(68),Nl(267),Y(),El(69)}function ii(){Wl.startNonterminal("Literal",_l);switch(Dl){case 11:wl(11);break;default:oi()}Wl.endNonterminal("Literal",_l)}function si(){switch(Dl){case 11:El(11);break;default:ui()}}function oi(){Wl.startNonterminal("NumericLiteral",_l);switch(Dl){case 8:wl(8);break;case 9:wl(9);break;default:wl(10)}Wl.endNonterminal("NumericLiteral",_l)}function ui(){switch(Dl){case 8:El(8);break;case 9:El(9);break;default:El(10)}}function ai(){Wl.startNonterminal("VarRef",_l),wl(31),Nl(255),xl(),li(),Wl.endNonterminal("VarRef",_l)}function fi(){El(31),Nl(255),ci()}function li(){Wl.startNonterminal("VarName",_l),Da(),Wl.endNonterminal("VarName",_l)}function ci(){Pa()}function hi(){Wl.startNonterminal("ParenthesizedExpr",_l),wl(34),Nl(269),Dl!=37&&(xl(),G()),wl(37),Wl.endNonterminal("ParenthesizedExpr",_l)}function pi(){El(34),Nl(269),Dl!=37&&Y(),El(37)}function di(){Wl.startNonterminal("ContextItemExpr",_l),wl(44),Wl.endNonterminal("ContextItemExpr",_l)}function vi(){El(44)}function mi(){Wl.startNonterminal("OrderedExpr",_l),wl(202),Nl(87),wl(276),Nl(267),xl(),G(),wl(282),Wl.endNonterminal("OrderedExpr",_l)}function gi(){El(202),Nl(87),El(276),Nl(267),Y(),El(282)}function yi(){Wl.startNonterminal("UnorderedExpr",_l),wl(256),Nl(87),wl(276),Nl(267),xl(),G(),wl(282),Wl.endNonterminal("UnorderedExpr",_l)}function bi(){El(256),Nl(87),El(276),Nl(267),Y(),El(282)}function wi(){Wl.startNonterminal("FunctionCall",_l),Ha(),Nl(22),xl(),Yr(),Wl.endNonterminal("FunctionCall",_l)}function Ei(){Ba(),Nl(22),Zr()}function Si(){Wl.startNonterminal("Argument",_l);switch(Dl){case 64:Ti();break;default:Of()}Wl.endNonterminal("Argument",_l)}function xi(){switch(Dl){case 64:Ni();break;default:Mf()}}function Ti(){Wl.startNonterminal("ArgumentPlaceholder",_l),wl(64),Wl.endNonterminal("ArgumentPlaceholder",_l)}function Ni(){El(64)}function Ci(){Wl.startNonterminal("Constructor",_l);switch(Dl){case 54:case 55:case 59:Li();break;default:Vi()}Wl.endNonterminal("Constructor",_l)}function ki(){switch(Dl){case 54:case 55:case 59:Ai();break;default:$i()}}function Li(){Wl.startNonterminal("DirectConstructor",_l);switch(Dl){case 54:Oi();break;case 55:Ui();break;default:Wi()}Wl.endNonterminal("DirectConstructor",_l)}function Ai(){switch(Dl){case 54:Mi();break;case 55:zi();break;default:Xi()}}function Oi(){Wl.startNonterminal("DirElemConstructor",_l),wl(54),kl(4),wl(20),_i();switch(Dl){case 48:wl(48);break;default:wl(61);for(;;){kl(174);if(Dl==56)break;qi()}wl(56),kl(4),wl(20),kl(12),Dl==21&&wl(21),kl(8),wl(61)}Wl.endNonterminal("DirElemConstructor",_l)}function Mi(){El(54),kl(4),El(20),Di();switch(Dl){case 48:El(48);break;default:El(61);for(;;){kl(174);if(Dl==56)break;Ri()}El(56),kl(4),El(20),kl(12),Dl==21&&El(21),kl(8),El(61)}}function _i(){Wl.startNonterminal("DirAttributeList",_l);for(;;){kl(19);if(Dl!=21)break;wl(21),kl(91),Dl==20&&(wl(20),kl(11),Dl==21&&wl(21),kl(7),wl(60),kl(18),Dl==21&&wl(21),Pi())}Wl.endNonterminal("DirAttributeList",_l)}function Di(){for(;;){kl(19);if(Dl!=21)break;El(21),kl(91),Dl==20&&(El(20),kl(11),Dl==21&&El(21),kl(7),El(60),kl(18),Dl==21&&El(21),Hi())}}function Pi(){Wl.startNonterminal("DirAttributeValue",_l),kl(14);switch(Dl){case 28:wl(28);for(;;){kl(167);if(Dl==28)break;switch(Dl){case 13:wl(13);break;default:Bi()}}wl(28);break;default:wl(33);for(;;){kl(168);if(Dl==33)break;switch(Dl){case 14:wl(14);break;default:Fi()}}wl(33)}Wl.endNonterminal("DirAttributeValue",_l)}function Hi(){kl(14);switch(Dl){case 28:El(28);for(;;){kl(167);if(Dl==28)break;switch(Dl){case 13:El(13);break;default:ji()}}El(28);break;default:El(33);for(;;){kl(168);if(Dl==33)break;switch(Dl){case 14:El(14);break;default:Ii()}}El(33)}}function Bi(){Wl.startNonterminal("QuotAttrValueContent",_l);switch(Dl){case 16:wl(16);break;default:Wf()}Wl.endNonterminal("QuotAttrValueContent",_l)}function ji(){switch(Dl){case 16:El(16);break;default:Xf()}}function Fi(){Wl.startNonterminal("AposAttrValueContent",_l);switch(Dl){case 17:wl(17);break;default:Wf()}Wl.endNonterminal("AposAttrValueContent",_l)}function Ii(){switch(Dl){case 17:El(17);break;default:Xf()}}function qi(){Wl.startNonterminal("DirElemContent",_l);switch(Dl){case 54:case 55:case 59:Li();break;case 4:wl(4);break;case 15:wl(15);break;default:Wf()}Wl.endNonterminal("DirElemContent",_l)}function Ri(){switch(Dl){case 54:case 55:case 59:Ai();break;case 4:El(4);break;case 15:El(15);break;default:Xf()}}function Ui(){Wl.startNonterminal("DirCommentConstructor",_l),wl(55),kl(1),wl(2),kl(6),wl(43),Wl.endNonterminal("DirCommentConstructor",_l)}function zi(){El(55),kl(1),El(2),kl(6),El(43)}function Wi(){Wl.startNonterminal("DirPIConstructor",_l),wl(59),kl(3),wl(18),kl(13),Dl==21&&(wl(21),kl(2),wl(3)),kl(9),wl(65),Wl.endNonterminal("DirPIConstructor",_l)}function Xi(){El(59),kl(3),El(18),kl(13),Dl==21&&(El(21),kl(2),El(3)),kl(9),El(65)}function Vi(){Wl.startNonterminal("ComputedConstructor",_l);switch(Dl){case 119:Jf();break;case 121:Ji();break;case 82:Qf();break;case 184:Qi();break;case 244:nl();break;case 96:el();break;default:Yf()}Wl.endNonterminal("ComputedConstructor",_l)}function $i(){switch(Dl){case 119:Kf();break;case 121:Ki();break;case 82:Gf();break;case 184:Gi();break;case 244:rl();break;case 96:tl();break;default:Zf()}}function Ji(){Wl.startNonterminal("CompElemConstructor",_l),wl(121),Nl(258);switch(Dl){case 276:wl(276),Nl(267),xl(),G(),wl(282);break;default:xl(),Da()}Nl(87),wl(276),Nl(277),Dl!=282&&(xl(),Vf()),wl(282),Wl.endNonterminal("CompElemConstructor",_l)}function Ki(){El(121),Nl(258);switch(Dl){case 276:El(276),Nl(267),Y(),El(282);break;default:Pa()}Nl(87),El(276),Nl(277),Dl!=282&&$f(),El(282)}function Qi(){Wl.startNonterminal("CompNamespaceConstructor",_l),wl(184),Nl(251);switch(Dl){case 276:wl(276),Nl(267),xl(),es(),wl(282);break;default:xl(),Yi()}Nl(87),wl(276),Nl(267),xl(),ns(),wl(282),Wl.endNonterminal("CompNamespaceConstructor",_l)}function Gi(){El(184),Nl(251);switch(Dl){case 276:El(276),Nl(267),ts(),El(282);break;default:Zi()}Nl(87),El(276),Nl(267),rs(),El(282)}function Yi(){Wl.startNonterminal("Prefix",_l),ja(),Wl.endNonterminal("Prefix",_l)}function Zi(){Fa()}function es(){Wl.startNonterminal("PrefixExpr",_l),G(),Wl.endNonterminal("PrefixExpr",_l)}function ts(){Y()}function ns(){Wl.startNonterminal("URIExpr",_l),G(),Wl.endNonterminal("URIExpr",_l)}function rs(){Y()}function is(){Wl.startNonterminal("FunctionItemExpr",_l);switch(Dl){case 145:Cl(92);break;default:Ol=Dl}switch(Ol){case 32:case 17553:as();break;default:os()}Wl.endNonterminal("FunctionItemExpr",_l)}function ss(){switch(Dl){case 145:Cl(92);break;default:Ol=Dl}switch(Ol){case 32:case 17553:fs();break;default:us()}}function os(){Wl.startNonterminal("NamedFunctionRef",_l),Da(),Nl(20),wl(29),Nl(16),wl(8),Wl.endNonterminal("NamedFunctionRef",_l)}function us(){Pa(),Nl(20),El(29),Nl(16),El(8)}function as(){Wl.startNonterminal("InlineFunctionExpr",_l);for(;;){Nl(97);if(Dl!=32)break;xl(),B()}wl(145),Nl(22),wl(34),Nl(94),Dl==31&&(xl(),U()),wl(37),Nl(111),Dl==79&&(wl(79),Nl(260),xl(),ds()),Nl(87),xl(),V(),Wl.endNonterminal("InlineFunctionExpr",_l)}function fs(){for(;;){Nl(97);if(Dl!=32)break;j()}El(145),Nl(22),El(34),Nl(94),Dl==31&&z(),El(37),Nl(111),Dl==79&&(El(79),Nl(260),vs()),Nl(87),$()}function ls(){Wl.startNonterminal("SingleType",_l),ho(),Nl(227),Dl==64&&wl(64),Wl.endNonterminal("SingleType",_l)}function cs(){po(),Nl(227),Dl==64&&El(64)}function hs(){Wl.startNonterminal("TypeDeclaration",_l),wl(79),Nl(260),xl(),ds(),Wl.endNonterminal("TypeDeclaration",_l)}function ps(){El(79),Nl(260),vs()}function ds(){Wl.startNonterminal("SequenceType",_l);switch(Dl){case 124:Cl(243);break;default:Ol=Dl}switch(Ol){case 17532:wl(124),Nl(22),wl(34),Nl(23),wl(37);break;default:ys(),Nl(239);switch(Dl){case 39:case 40:case 64:xl(),ms();break;default:}}Wl.endNonterminal("SequenceType",_l)}function vs(){switch(Dl){case 124:Cl(243);break;default:Ol=Dl}switch(Ol){case 17532:El(124),Nl(22),El(34),Nl(23),El(37);break;default:bs(),Nl(239);switch(Dl){case 39:case 40:case 64:gs();break;default:}}}function ms(){Wl.startNonterminal("OccurrenceIndicator",_l);switch(Dl){case 64:wl(64);break;case 39:wl(39);break;default:wl(40)}Wl.endNonterminal("OccurrenceIndicator",_l)}function gs(){switch(Dl){case 64:El(64);break;case 39:El(39);break;default:El(40)}}function ys(){Wl.startNonterminal("ItemType",_l);switch(Dl){case 78:case 82:case 96:case 120:case 121:case 145:case 165:case 167:case 185:case 191:case 194:case 216:case 226:case 227:case 242:case 244:Cl(243);break;default:Ol=Dl}switch(Ol){case 17490:case 17504:case 17528:case 17529:case 17593:case 17599:case 17624:case 17634:case 17635:case 17652:_s();break;case 17573:wl(165),Nl(22),wl(34),Nl(23),wl(37);break;case 32:case 17553:go();break;case 34:xo();break;case 17486:case 17575:case 17602:ws();break;case 17650:Ss();break;default:Os()}Wl.endNonterminal("ItemType",_l)}function bs(){switch(Dl){case 78:case 82:case 96:case 120:case 121:case 145:case 165:case 167:case 185:case 191:case 194:case 216:case 226:case 227:case 242:case 244:Cl(243);break;default:Ol=Dl}switch(Ol){case 17490:case 17504:case 17528:case 17529:case 17593:case 17599:case 17624:case 17634:case 17635:case 17652:Ds();break;case 17573:El(165),Nl(22),El(34),Nl(23),El(37);break;case 32:case 17553:yo();break;case 34:To();break;case 17486:case 17575:case 17602:Es();break;case 17650:xs();break;default:Ms()}}function ws(){Wl.startNonterminal("JSONTest",_l);switch(Dl){case 167:Ts();break;case 194:Cs();break;default:Ls()}Wl.endNonterminal("JSONTest",_l)}function Es(){switch(Dl){case 167:Ns();break;case 194:ks();break;default:As()}}function Ss(){Wl.startNonterminal("StructuredItemTest",_l),wl(242),Nl(22),wl(34),Nl(23),wl(37),Wl.endNonterminal("StructuredItemTest",_l)}function xs(){El(242),Nl(22),El(34),Nl(23),El(37)}function Ts(){Wl.startNonterminal("JSONItemTest",_l),wl(167),Nl(22),wl(34),Nl(23),wl(37),Wl.endNonterminal("JSONItemTest",_l)}function Ns(){El(167),Nl(22),El(34),Nl(23),El(37)}function Cs(){Wl.startNonterminal("JSONObjectTest",_l),wl(194),Nl(22),wl(34),Nl(23),wl(37),Wl.endNonterminal("JSONObjectTest",_l)}function ks(){El(194),Nl(22),El(34),Nl(23),El(37)}function Ls(){Wl.startNonterminal("JSONArrayTest",_l),wl(78),Nl(22),wl(34),Nl(23),wl(37),Wl.endNonterminal("JSONArrayTest",_l)}function As(){El(78),Nl(22),El(34),Nl(23),El(37)}function Os(){Wl.startNonterminal("AtomicOrUnionType",_l),Da(),Wl.endNonterminal("AtomicOrUnionType",_l)}function Ms(){Pa()}function _s(){Wl.startNonterminal("KindTest",_l);switch(Dl){case 120:Bs();break;case 121:eo();break;case 82:Vs();break;case 227:io();break;case 226:Qs();break;case 216:Ws();break;case 96:qs();break;case 244:Fs();break;case 185:Us();break;default:Ps()}Wl.endNonterminal("KindTest",_l)}function Ds(){switch(Dl){case 120:js();break;case 121:to();break;case 82:$s();break;case 227:so();break;case 226:Gs();break;case 216:Xs();break;case 96:Rs();break;case 244:Is();break;case 185:zs();break;default:Hs()}}function Ps(){Wl.startNonterminal("AnyKindTest",_l),wl(191),Nl(22),wl(34),Nl(23),wl(37),Wl.endNonterminal("AnyKindTest",_l)}function Hs(){El(191),Nl(22),El(34),Nl(23),El(37)}function Bs(){Wl.startNonterminal("DocumentTest",_l),wl(120),Nl(22),wl(34),Nl(144);if(Dl!=37)switch(Dl){case 121:xl(),eo();break;default:xl(),io()}Nl(23),wl(37),Wl.endNonterminal("DocumentTest",_l)}function js(){El(120),Nl(22),El(34),Nl(144);if(Dl!=37)switch(Dl){case 121:to();break;default:so()}Nl(23),El(37)}function Fs(){Wl.startNonterminal("TextTest",_l),wl(244),Nl(22),wl(34),Nl(23),wl(37),Wl.endNonterminal("TextTest",_l)}function Is(){El(244),Nl(22),El(34),Nl(23),El(37)}function qs(){Wl.startNonterminal("CommentTest",_l),wl(96),Nl(22),wl(34),Nl(23),wl(37),Wl.endNonterminal("CommentTest",_l)}function Rs(){El(96),Nl(22),El(34),Nl(23),El(37)}function Us(){Wl.startNonterminal("NamespaceNodeTest",_l),wl(185),Nl(22),wl(34),Nl(23),wl(37),Wl.endNonterminal("NamespaceNodeTest",_l)}function zs(){El(185),Nl(22),El(34),Nl(23),El(37)}function Ws(){Wl.startNonterminal("PITest",_l),wl(216),Nl(22),wl(34),Nl(253);if(Dl!=37)switch(Dl){case 11:wl(11);break;default:xl(),ja()}Nl(23),wl(37),Wl.endNonterminal("PITest",_l)}function Xs(){El(216),Nl(22),El(34),Nl(253);if(Dl!=37)switch(Dl){case 11:El(11);break;default:Fa()}Nl(23),El(37)}function Vs(){Wl.startNonterminal("AttributeTest",_l),wl(82),Nl(22),wl(34),Nl(261),Dl!=37&&(xl(),Js(),Nl(101),Dl==41&&(wl(41),Nl(255),xl(),vo())),Nl(23),wl(37),Wl.endNonterminal("AttributeTest",_l)}function $s(){El(82),Nl(22),El(34),Nl(261),Dl!=37&&(Ks(),Nl(101),Dl==41&&(El(41),Nl(255),mo())),Nl(23),El(37)}function Js(){Wl.startNonterminal("AttribNameOrWildcard",_l);switch(Dl){case 38:wl(38);break;default:ao()}Wl.endNonterminal("AttribNameOrWildcard",_l)}function Ks(){switch(Dl){case 38:El(38);break;default:fo()}}function Qs(){Wl.startNonterminal("SchemaAttributeTest",_l),wl(226),Nl(22),wl(34),Nl(255),xl(),Ys(),Nl(23),wl(37),Wl.endNonterminal("SchemaAttributeTest",_l)}function Gs(){El(226),Nl(22),El(34),Nl(255),Zs(),Nl(23),El(37)}function Ys(){Wl.startNonterminal("AttributeDeclaration",_l),ao(),Wl.endNonterminal("AttributeDeclaration",_l)}function Zs(){fo()}function eo(){Wl.startNonterminal("ElementTest",_l),wl(121),Nl(22),wl(34),Nl(261),Dl!=37&&(xl(),no(),Nl(101),Dl==41&&(wl(41),Nl(255),xl(),vo(),Nl(102),Dl==64&&wl(64))),Nl(23),wl(37),Wl.endNonterminal("ElementTest",_l)}function to(){El(121),Nl(22),El(34),Nl(261),Dl!=37&&(ro(),Nl(101),Dl==41&&(El(41),Nl(255),mo(),Nl(102),Dl==64&&El(64))),Nl(23),El(37)}function no(){Wl.startNonterminal("ElementNameOrWildcard",_l);switch(Dl){case 38:wl(38);break;default:lo()}Wl.endNonterminal("ElementNameOrWildcard",_l)}function ro(){switch(Dl){case 38:El(38);break;default:co()}}function io(){Wl.startNonterminal("SchemaElementTest",_l),wl(227),Nl(22),wl(34),Nl(255),xl(),oo(),Nl(23),wl(37),Wl.endNonterminal("SchemaElementTest",_l)}function so(){El(227),Nl(22),El(34),Nl(255),uo(),Nl(23),El(37)}function oo(){Wl.startNonterminal("ElementDeclaration",_l),lo(),Wl.endNonterminal("ElementDeclaration",_l)}function uo(){co()}function ao(){Wl.startNonterminal("AttributeName",_l),Da(),Wl.endNonterminal("AttributeName",_l)}function fo(){Pa()}function lo(){Wl.startNonterminal("ElementName",_l),Da(),Wl.endNonterminal("ElementName",_l)}function co(){Pa()}function ho(){Wl.startNonterminal("SimpleTypeName",_l),vo(),Wl.endNonterminal("SimpleTypeName",_l)}function po(){mo()}function vo(){Wl.startNonterminal("TypeName",_l),Da(),Wl.endNonterminal("TypeName",_l)}function mo(){Pa()}function go(){Wl.startNonterminal("FunctionTest",_l);for(;;){Nl(97);if(Dl!=32)break;xl(),B()}switch(Dl){case 145:Cl(22);break;default:Ol=Dl}Ol=$l(5,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{wo(),Ol=-1}catch(a){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(5,_l,Ol)}switch(Ol){case-1:xl(),bo();break;default:xl(),Eo()}Wl.endNonterminal("FunctionTest",_l)}function yo(){for(;;){Nl(97);if(Dl!=32)break;j()}switch(Dl){case 145:Cl(22);break;default:Ol=Dl}Ol=$l(5,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{wo(),Vl(5,t,-1),Ol=-3}catch(a){Ol=-2,Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(5,t,-2)}}switch(Ol){case-1:wo();break;case-3:break;default:So()}}function bo(){Wl.startNonterminal("AnyFunctionTest",_l),wl(145),Nl(22),wl(34),Nl(24),wl(38),Nl(23),wl(37),Wl.endNonterminal("AnyFunctionTest",_l)}function wo(){El(145),Nl(22),El(34),Nl(24),El(38),Nl(23),El(37)}function Eo(){Wl.startNonterminal("TypedFunctionTest",_l),wl(145),Nl(22),wl(34),Nl(263);if(Dl!=37){xl(),ds();for(;;){Nl(101);if(Dl!=41)break;wl(41),Nl(260),xl(),ds()}}wl(37),Nl(30),wl(79),Nl(260),xl(),ds(),Wl.endNonterminal("TypedFunctionTest",_l)}function So(){El(145),Nl(22),El(34),Nl(263);if(Dl!=37){vs();for(;;){Nl(101);if(Dl!=41)break;El(41),Nl(260),vs()}}El(37),Nl(30),El(79),Nl(260),vs()}function xo(){Wl.startNonterminal("ParenthesizedItemType",_l),wl(34),Nl(260),xl(),ys(),Nl(23),wl(37),Wl.endNonterminal("ParenthesizedItemType",_l)}function To(){El(34),Nl(260),bs(),Nl(23),El(37)}function No(){Wl.startNonterminal("RevalidationDecl",_l),wl(108),Nl(72),wl(222),Nl(152);switch(Dl){case 240:wl(240);break;case 171:wl(171);break;default:wl(233)}Wl.endNonterminal("RevalidationDecl",_l)}function Co(){Wl.startNonterminal("InsertExprTargetChoice",_l);switch(Dl){case 70:wl(70);break;case 84:wl(84);break;default:if(Dl==79){wl(79),Nl(119);switch(Dl){case 134:wl(134);break;default:wl(170)}}Nl(54),wl(163)}Wl.endNonterminal("InsertExprTargetChoice",_l)}function ko(){switch(Dl){case 70:El(70);break;case 84:El(84);break;default:if(Dl==79){El(79),Nl(119);switch(Dl){case 134:El(134);break;default:El(170)}}Nl(54),El(163)}}function Lo(){Wl.startNonterminal("InsertExpr",_l),wl(159),Nl(129);switch(Dl){case 191:wl(191);break;default:wl(192)}Nl(267),xl(),Bo(),xl(),Co(),Nl(267),xl(),Fo(),Wl.endNonterminal("InsertExpr",_l)}function Ao(){El(159),Nl(129);switch(Dl){case 191:El(191);break;default:El(192)}Nl(267),jo(),ko(),Nl(267),Io()}function Oo(){Wl.startNonterminal("DeleteExpr",_l),wl(110),Nl(129);switch(Dl){case 191:wl(191);break;default:wl(192)}Nl(267),xl(),Fo(),Wl.endNonterminal("DeleteExpr",_l)}function Mo(){El(110),Nl(129);switch(Dl){case 191:El(191);break;default:El(192)}Nl(267),Io()}function _o(){Wl.startNonterminal("ReplaceExpr",_l),wl(219),Nl(130),Dl==261&&(wl(261),Nl(64),wl(196)),Nl(62),wl(191),Nl(267),xl(),Fo(),wl(270),Nl(267),xl(),Of(),Wl.endNonterminal("ReplaceExpr",_l)}function Do(){El(219),Nl(130),Dl==261&&(El(261),Nl(64),El(196)),Nl(62),El(191),Nl(267),Io(),El(270),Nl(267),Mf()}function Po(){Wl.startNonterminal("RenameExpr",_l),wl(218),Nl(62),wl(191),Nl(267),xl(),Fo(),wl(79),Nl(267),xl(),qo(),Wl.endNonterminal("RenameExpr",_l)}function Ho(){El(218),Nl(62),El(191),Nl(267),Io(),El(79),Nl(267),Ro()}function Bo(){Wl.startNonterminal("SourceExpr",_l),Of(),Wl.endNonterminal("SourceExpr",_l)}function jo(){Mf()}function Fo(){Wl.startNonterminal("TargetExpr",_l),Of(),Wl.endNonterminal("TargetExpr",_l)}function Io(){Mf()}function qo(){Wl.startNonterminal("NewNameExpr",_l),Of(),Wl.endNonterminal("NewNameExpr",_l)}function Ro(){Mf()}function Uo(){Wl.startNonterminal("TransformExpr",_l),wl(103),Nl(21),xl(),Wo();for(;;){if(Dl!=41)break;wl(41),Nl(21),xl(),Wo()}wl(181),Nl(267),xl(),Of(),wl(220),Nl(267),xl(),Of(),Wl.endNonterminal("TransformExpr",_l)}function zo(){El(103),Nl(21),Xo();for(;;){if(Dl!=41)break;El(41),Nl(21),Xo()}El(181),Nl(267),Mf(),El(220),Nl(267),Mf()}function Wo(){Wl.startNonterminal("TransformSpec",_l),wl(31),Nl(255),xl(),li(),Nl(27),wl(52),Nl(267),xl(),Of(),Wl.endNonterminal("TransformSpec",_l)}function Xo(){El(31),Nl(255),ci(),Nl(27),El(52),Nl(267),Mf()}function Vo(){Wl.startNonterminal("FTSelection",_l),Qo();for(;;){Nl(212);switch(Dl){case 81:Cl(151);break;default:Ol=Dl}if(Ol!=115&&Ol!=117&&Ol!=127&&Ol!=202&&Ol!=223&&Ol!=269&&Ol!=64593&&Ol!=121425)break;xl(),wu()}Wl.endNonterminal("FTSelection",_l)}function $o(){Go();for(;;){Nl(212);switch(Dl){case 81:Cl(151);break;default:Ol=Dl}if(Ol!=115&&Ol!=117&&Ol!=127&&Ol!=202&&Ol!=223&&Ol!=269&&Ol!=64593&&Ol!=121425)break;Eu()}}function Jo(){Wl.startNonterminal("FTWeight",_l),wl(264),Nl(87),wl(276),Nl(267),xl(),G(),wl(282),Wl.endNonterminal("FTWeight",_l)}function Ko(){El(264),Nl(87),El(276),Nl(267),Y(),El(282)}function Qo(){Wl.startNonterminal("FTOr",_l),Yo();for(;;){if(Dl!=144)break;wl(144),Nl(162),xl(),Yo()}Wl.endNonterminal("FTOr",_l)}function Go(){Zo();for(;;){if(Dl!=144)break;El(144),Nl(162),Zo()}}function Yo(){Wl.startNonterminal("FTAnd",_l),eu();for(;;){if(Dl!=142)break;wl(142),Nl(162),xl(),eu()}Wl.endNonterminal("FTAnd",_l)}function Zo(){tu();for(;;){if(Dl!=142)break;El(142),Nl(162),tu()}}function eu(){Wl.startNonterminal("FTMildNot",_l),nu();for(;;){Nl(213);if(Dl!=193)break;wl(193),Nl(53),wl(154),Nl(162),xl(),nu()}Wl.endNonterminal("FTMildNot",_l)}function tu(){ru();for(;;){Nl(213);if(Dl!=193)break;El(193),Nl(53),El(154),Nl(162),ru()}}function nu(){Wl.startNonterminal("FTUnaryNot",_l),Dl==143&&wl(143),Nl(155),xl(),iu(),Wl.endNonterminal("FTUnaryNot",_l)}function ru(){Dl==143&&El(143),Nl(155),su()}function iu(){Wl.startNonterminal("FTPrimaryWithOptions",_l),ou(),Nl(215),Dl==259&&(xl(),Bu()),Dl==264&&(xl(),Jo()),Wl.endNonterminal("FTPrimaryWithOptions",_l)}function su(){uu(),Nl(215),Dl==259&&ju(),Dl==264&&Ko()}function ou(){Wl.startNonterminal("FTPrimary",_l);switch(Dl){case 34:wl(34),Nl(162),xl(),Vo(),wl(37);break;case 35:hu();break;default:au(),Nl(216),Dl==195&&(xl(),mu())}Wl.endNonterminal("FTPrimary",_l)}function uu(){switch(Dl){case 34:El(34),Nl(162),$o(),El(37);break;case 35:pu();break;default:fu(),Nl(216),Dl==195&&gu()}}function au(){Wl.startNonterminal("FTWords",_l),lu(),Nl(222);if(Dl==71||Dl==76||Dl==210)xl(),du();Wl.endNonterminal("FTWords",_l)}function fu(){cu(),Nl(222),(Dl==71||Dl==76||Dl==210)&&vu()}function lu(){Wl.startNonterminal("FTWordsValue",_l);switch(Dl){case 11:wl(11);break;default:wl(276),Nl(267),xl(),G(),wl(282)}Wl.endNonterminal("FTWordsValue",_l)}function cu(){switch(Dl){case 11:El(11);break;default:El(276),Nl(267),Y(),El(282)}}function hu(){Wl.startNonterminal("FTExtensionSelection",_l);for(;;){xl(),Tr(),Nl(100);if(Dl!=35)break}wl(276),Nl(166),Dl!=282&&(xl(),Vo()),wl(282),Wl.endNonterminal("FTExtensionSelection",_l)}function pu(){for(;;){Nr(),Nl(100);if(Dl!=35)break}El(276),Nl(166),Dl!=282&&$o(),El(282)}function du(){Wl.startNonterminal("FTAnyallOption",_l);switch(Dl){case 76:wl(76),Nl(219),Dl==272&&wl(272);break;case 71:wl(71),Nl(220),Dl==273&&wl(273);break;default:wl(210)}Wl.endNonterminal("FTAnyallOption",_l)}function vu(){switch(Dl){case 76:El(76),Nl(219),Dl==272&&El(272);break;case 71:El(71),Nl(220),Dl==273&&El(273);break;default:El(210)}}function mu(){Wl.startNonterminal("FTTimes",_l),wl(195),Nl(149),xl(),yu(),wl(247),Wl.endNonterminal("FTTimes",_l)}function gu(){El(195),Nl(149),bu(),El(247)}function yu(){Wl.startNonterminal("FTRange",_l);switch(Dl){case 130:wl(130),Nl(267),xl(),Wn();break;case 81:wl(81),Nl(125);switch(Dl){case 173:wl(173),Nl(267),xl(),Wn();break;default:wl(183),Nl(267),xl(),Wn()}break;default:wl(140),Nl(267),xl(),Wn(),wl(248),Nl(267),xl(),Wn()}Wl.endNonterminal("FTRange",_l)}function bu(){switch(Dl){case 130:El(130),Nl(267),Xn();break;case 81:El(81),Nl(125);switch(Dl){case 173:El(173),Nl(267),Xn();break;default:El(183),Nl(267),Xn()}break;default:El(140),Nl(267),Xn(),El(248),Nl(267),Xn()}}function wu(){Wl.startNonterminal("FTPosFilter",_l);switch(Dl){case 202:Su();break;case 269:Tu();break;case 117:Cu();break;case 115:case 223:Ou();break;default:Pu()}Wl.endNonterminal("FTPosFilter",_l)}function Eu(){switch(Dl){case 202:xu();break;case 269:Nu();break;case 117:ku();break;case 115:case 223:Mu();break;default:Hu()}}function Su(){Wl.startNonterminal("FTOrder",_l),wl(202),Wl.endNonterminal("FTOrder",_l)}function xu(){El(202)}function Tu(){Wl.startNonterminal("FTWindow",_l),wl(269),Nl(267),xl(),Wn(),xl(),Lu(),Wl.endNonterminal("FTWindow",_l)}function Nu(){El(269),Nl(267),Xn(),Au()}function Cu(){Wl.startNonterminal("FTDistance",_l),wl(117),Nl(149),xl(),yu(),xl(),Lu(),Wl.endNonterminal("FTDistance",_l)}function ku(){El(117),Nl(149),bu(),Au()}function Lu(){Wl.startNonterminal("FTUnit",_l);switch(Dl){case 273:wl(273);break;case 232:wl(232);break;default:wl(205)}Wl.endNonterminal("FTUnit",_l)}function Au(){switch(Dl){case 273:El(273);break;case 232:El(232);break;default:El(205)}}function Ou(){Wl.startNonterminal("FTScope",_l);switch(Dl){case 223:wl(223);break;default:wl(115)}Nl(132),xl(),_u(),Wl.endNonterminal("FTScope",_l)}function Mu(){switch(Dl){case 223:El(223);break;default:El(115)}Nl(132),Du()}function _u(){Wl.startNonterminal("FTBigUnit",_l);switch(Dl){case 231:wl(231);break;default:wl(204)}Wl.endNonterminal("FTBigUnit",_l)}function Du(){switch(Dl){case 231:El(231);break;default:El(204)}}function Pu(){Wl.startNonterminal("FTContent",_l);switch(Dl){case 81:wl(81),Nl(117);switch(Dl){case 237:wl(237);break;default:wl(126)}break;default:wl(127),Nl(42),wl(100)}Wl.endNonterminal("FTContent",_l)}function Hu(){switch(Dl){case 81:El(81),Nl(117);switch(Dl){case 237:El(237);break;default:El(126)}break;default:El(127),Nl(42),El(100)}}function Bu(){Wl.startNonterminal("FTMatchOptions",_l);for(;;){wl(259),Nl(182),xl(),Fu(),Nl(215);if(Dl!=259)break}Wl.endNonterminal("FTMatchOptions",_l)}function ju(){for(;;){El(259),Nl(182),Iu(),Nl(215);if(Dl!=259)break}}function Fu(){Wl.startNonterminal("FTMatchOption",_l);switch(Dl){case 188:Cl(161);break;default:Ol=Dl}switch(Ol){case 169:ia();break;case 268:case 137404:oa();break;case 246:case 126140:Vu();break;case 238:case 122044:Wu();break;case 114:Uu();break;case 239:case 122556:Yu();break;case 199:aa();break;default:qu()}Wl.endNonterminal("FTMatchOption",_l)}function Iu(){switch(Dl){case 188:Cl(161);break;default:Ol=Dl}switch(Ol){case 169:sa();break;case 268:case 137404:ua();break;case 246:case 126140:$u();break;case 238:case 122044:Xu();break;case 114:zu();break;case 239:case 122556:Zu();break;case 199:fa();break;default:Ru()}}function qu(){Wl.startNonterminal("FTCaseOption",_l);switch(Dl){case 88:wl(88),Nl(124);switch(Dl){case 158:wl(158);break;default:wl(230)}break;case 177:wl(177);break;default:wl(258)}Wl.endNonterminal("FTCaseOption",_l)}function Ru(){switch(Dl){case 88:El(88),Nl(124);switch(Dl){case 158:El(158);break;default:El(230)}break;case 177:El(177);break;default:El(258)}}function Uu(){Wl.startNonterminal("FTDiacriticsOption",_l),wl(114),Nl(124);switch(Dl){case 158:wl(158);break;default:wl(230)}Wl.endNonterminal("FTDiacriticsOption",_l)}function zu(){El(114),Nl(124);switch(Dl){case 158:El(158);break;default:El(230)}}function Wu(){Wl.startNonterminal("FTStemOption",_l);switch(Dl){case 238:wl(238);break;default:wl(188),Nl(74),wl(238)}Wl.endNonterminal("FTStemOption",_l)}function Xu(){switch(Dl){case 238:El(238);break;default:El(188),Nl(74),El(238)}}function Vu(){Wl.startNonterminal("FTThesaurusOption",_l);switch(Dl){case 246:wl(246),Nl(142);switch(Dl){case 81:xl(),Ju();break;case 109:wl(109);break;default:wl(34),Nl(112);switch(Dl){case 81:xl(),Ju();break;default:wl(109)}for(;;){Nl(101);if(Dl!=41)break;wl(41),Nl(31),xl(),Ju()}wl(37)}break;default:wl(188),Nl(78),wl(246)}Wl.endNonterminal("FTThesaurusOption",_l)}function $u(){switch(Dl){case 246:El(246),Nl(142);switch(Dl){case 81:Ku();break;case 109:El(109);break;default:El(34),Nl(112);switch(Dl){case 81:Ku();break;default:El(109)}for(;;){Nl(101);if(Dl!=41)break;El(41),Nl(31),Ku()}El(37)}break;default:El(188),Nl(78),El(246)}}function Ju(){Wl.startNonterminal("FTThesaurusID",_l),wl(81),Nl(15),wl(7),Nl(221),Dl==217&&(wl(217),Nl(17),wl(11)),Nl(217);switch(Dl){case 81:Cl(165);break;default:Ol=Dl}if(Ol==130||Ol==140||Ol==88657||Ol==93777)xl(),Qu(),Nl(58),wl(175);Wl.endNonterminal("FTThesaurusID",_l)}function Ku(){El(81),Nl(15),El(7),Nl(221),Dl==217&&(El(217),Nl(17),El(11)),Nl(217);switch(Dl){case 81:Cl(165);break;default:Ol=Dl}if(Ol==130||Ol==140||Ol==88657||Ol==93777)Gu(),Nl(58),El(175)}function Qu(){Wl.startNonterminal("FTLiteralRange",_l);switch(Dl){case 130:wl(130),Nl(16),wl(8);break;case 81:wl(81),Nl(125);switch(Dl){case 173:wl(173),Nl(16),wl(8);break;default:wl(183),Nl(16),wl(8)}break;default:wl(140),Nl(16),wl(8),Nl(79),wl(248),Nl(16),wl(8)}Wl.endNonterminal("FTLiteralRange",_l)}function Gu(){switch(Dl){case 130:El(130),Nl(16),El(8);break;case 81:El(81),Nl(125);switch(Dl){case 173:El(173),Nl(16),El(8);break;default:El(183),Nl(16),El(8)}break;default:El(140),Nl(16),El(8),Nl(79),El(248),Nl(16),El(8)}}function Yu(){Wl.startNonterminal("FTStopWordOption",_l);switch(Dl){case 239:wl(239),Nl(86),wl(273),Nl(142);switch(Dl){case 109:wl(109);for(;;){Nl(218);if(Dl!=131&&Dl!=254)break;xl(),na()}break;default:xl(),ea();for(;;){Nl(218);if(Dl!=131&&Dl!=254)break;xl(),na()}}break;default:wl(188),Nl(75),wl(239),Nl(86),wl(273)}Wl.endNonterminal("FTStopWordOption",_l)}function Zu(){switch(Dl){case 239:El(239),Nl(86),El(273),Nl(142);switch(Dl){case 109:El(109);for(;;){Nl(218);if(Dl!=131&&Dl!=254)break;ra()}break;default:ta();for(;;){Nl(218);if(Dl!=131&&Dl!=254)break;ra()}}break;default:El(188),Nl(75),El(239),Nl(86),El(273)}}function ea(){Wl.startNonterminal("FTStopWords",_l);switch(Dl){case 81:wl(81),Nl(15),wl(7);break;default:wl(34),Nl(17),wl(11);for(;;){Nl(101);if(Dl!=41)break;wl(41),Nl(17),wl(11)}wl(37)}Wl.endNonterminal("FTStopWords",_l)}function ta(){switch(Dl){case 81:El(81),Nl(15),El(7);break;default:El(34),Nl(17),El(11);for(;;){Nl(101);if(Dl!=41)break;El(41),Nl(17),El(11)}El(37)}}function na(){Wl.startNonterminal("FTStopWordsInclExcl",_l);switch(Dl){case 254:wl(254);break;default:wl(131)}Nl(99),xl(),ea(),Wl.endNonterminal("FTStopWordsInclExcl",_l)}function ra(){switch(Dl){case 254:El(254);break;default:El(131)}Nl(99),ta()}function ia(){Wl.startNonterminal("FTLanguageOption",_l),wl(169),Nl(17),wl(11),Wl.endNonterminal("FTLanguageOption",_l)}function sa(){El(169),Nl(17),El(11)}function oa(){Wl.startNonterminal("FTWildCardOption",_l);switch(Dl){case 268:wl(268);break;default:wl(188),Nl(84),wl(268)}Wl.endNonterminal("FTWildCardOption",_l)}function ua(){switch(Dl){case 268:El(268);break;default:El(188),Nl(84),El(268)}}function aa(){Wl.startNonterminal("FTExtensionOption",_l),wl(199),Nl(255),xl(),Da(),Nl(17),wl(11),Wl.endNonterminal("FTExtensionOption",_l)}function fa(){El(199),Nl(255),Pa(),Nl(17),El(11)}function la(){Wl.startNonterminal("FTIgnoreOption",_l),wl(271),Nl(42),wl(100),Nl(267),xl(),Jn(),Wl.endNonterminal("FTIgnoreOption",_l)}function ca(){El(271),Nl(42),El(100),Nl(267),Kn()}function ha(){Wl.startNonterminal("CollectionDecl",_l),wl(95),Nl(255),xl(),Da(),Nl(107),Dl==79&&(xl(),pa()),Wl.endNonterminal("CollectionDecl",_l)}function pa(){Wl.startNonterminal("CollectionTypeDecl",_l),wl(79),Nl(178),xl(),_s(),Nl(156),Dl!=53&&(xl(),ms()),Wl.endNonterminal("CollectionTypeDecl",_l)}function da(){Wl.startNonterminal("IndexName",_l),Da(),Wl.endNonterminal("IndexName",_l)}function va(){Wl.startNonterminal("IndexDomainExpr",_l),Cr(),Wl.endNonterminal("IndexDomainExpr",_l)}function ma(){Wl.startNonterminal("IndexKeySpec",_l),ga(),Dl==79&&(xl(),ya()),Nl(146),Dl==94&&(xl(),wa()),Wl.endNonterminal("IndexKeySpec",_l)}function ga(){Wl.startNonterminal("IndexKeyExpr",_l),Cr(),Wl.endNonterminal("IndexKeyExpr",_l)}function ya(){Wl.startNonterminal("IndexKeyTypeDecl",_l),wl(79),Nl(255),xl(),ba(),Nl(169);if(Dl==39||Dl==40||Dl==64)xl(),ms();Wl.endNonterminal("IndexKeyTypeDecl",_l)}function ba(){Wl.startNonterminal("AtomicType",_l),Da(),Wl.endNonterminal("AtomicType",_l)}function wa(){Wl.startNonterminal("IndexKeyCollation",_l),wl(94),Nl(15),wl(7),Wl.endNonterminal("IndexKeyCollation",_l)}function Ea(){Wl.startNonterminal("IndexDecl",_l),wl(155),Nl(255),xl(),da(),Nl(65),wl(197),Nl(63),wl(192),Nl(266),xl(),va(),wl(87),Nl(266),xl(),ma();for(;;){Nl(103);if(Dl!=41)break;wl(41),Nl(266),xl(),ma()}Wl.endNonterminal("IndexDecl",_l)}function Sa(){Wl.startNonterminal("ICDecl",_l),wl(161),Nl(40),wl(97),Nl(255),xl(),Da(),Nl(120);switch(Dl){case 197:xl(),xa();break;default:xl(),ka()}Wl.endNonterminal("ICDecl",_l)}function xa(){Wl.startNonterminal("ICCollection",_l),wl(197),Nl(39),wl(95),Nl(255),xl(),Da(),Nl(140);switch(Dl){case 31:xl(),Ta();break;case 191:xl(),Na();break;default:xl(),Ca()}Wl.endNonterminal("ICCollection",_l)}function Ta(){Wl.startNonterminal("ICCollSequence",_l),ai(),Nl(37),wl(92),Nl(267),xl(),Of(),Wl.endNonterminal("ICCollSequence",_l)}function Na(){Wl.startNonterminal("ICCollSequenceUnique",_l),wl(191),Nl(21),xl(),ai(),Nl(37),wl(92),Nl(80),wl(255),Nl(57),wl(168),Nl(266),xl(),Cr(),Wl.endNonterminal("ICCollSequenceUnique",_l)}function Ca(){Wl.startNonterminal("ICCollNode",_l),wl(138),Nl(62),wl(191),Nl(21),xl(),ai(),Nl(37),wl(92),Nl(267),xl(),Of(),Wl.endNonterminal("ICCollNode",_l)}function ka(){Wl.startNonterminal("ICForeignKey",_l),wl(139),Nl(57),wl(168),Nl(51),xl(),La(),xl(),Aa(),Wl.endNonterminal("ICForeignKey",_l)}function La(){Wl.startNonterminal("ICForeignKeySource",_l),wl(140),Nl(39),xl(),Oa(),Wl.endNonterminal("ICForeignKeySource",_l)}function Aa(){Wl.startNonterminal("ICForeignKeyTarget",_l),wl(248),Nl(39),xl(),Oa(),Wl.endNonterminal("ICForeignKeyTarget",_l)}function Oa(){Wl.startNonterminal("ICForeignKeyValues",_l),wl(95),Nl(255),xl(),Da(),Nl(62),wl(191),Nl(21),xl(),ai(),Nl(57),wl(168),Nl(266),xl(),Cr(),Wl.endNonterminal("ICForeignKeyValues",_l)}function Ma(){El(36);for(;;){kl(89);if(Dl==50)break;switch(Dl){case 24:El(24);break;default:Ma()}}El(50)}function _a(){switch(Dl){case 22:El(22);break;default:Ma()}}function Da(){Wl.startNonterminal("EQName",_l),kl(250);switch(Dl){case 82:wl(82);break;case 96:wl(96);break;case 120:wl(120);break;case 121:wl(121);break;case 124:wl(124);break;case 145:wl(145);break;case 152:wl(152);break;case 165:wl(165);break;case 185:wl(185);break;case 191:wl(191);break;case 216:wl(216);break;case 226:wl(226);break;case 227:wl(227);break;case 243:wl(243);break;case 244:wl(244);break;case 253:wl(253);break;case 78:wl(78);break;case 167:wl(167);break;case 242:wl(242);break;default:Ha()}Wl.endNonterminal("EQName",_l)}function Pa(){kl(250);switch(Dl){case 82:El(82);break;case 96:El(96);break;case 120:El(120);break;case 121:El(121);break;case 124:El(124);break;case 145:El(145);break;case 152:El(152);break;case 165:El(165);break;case 185:El(185);break;case 191:El(191);break;case 216:El(216);break;case 226:El(226);break;case 227:El(227);break;case 243:El(243);break;case 244:El(244);break;case 253:El(253);break;case 78:El(78);break;case 167:El(167);break;case 242:El(242);break;default:Ba()}}function Ha(){Wl.startNonterminal("FunctionName",_l);switch(Dl){case 6:wl(6);break;case 70:wl(70);break;case 73:wl(73);break;case 74:wl(74);break;case 75:wl(75);break;case 79:wl(79);break;case 80:wl(80);break;case 84:wl(84);break;case 88:wl(88);break;case 89:wl(89);break;case 90:wl(90);break;case 93:wl(93);break;case 94:wl(94);break;case 103:wl(103);break;case 105:wl(105);break;case 108:wl(108);break;case 109:wl(109);break;case 110:wl(110);break;case 111:wl(111);break;case 112:wl(112);break;case 113:wl(113);break;case 118:wl(118);break;case 119:wl(119);break;case 122:wl(122);break;case 123:wl(123);break;case 126:wl(126);break;case 128:wl(128);break;case 129:wl(129);break;case 131:wl(131);break;case 134:wl(134);break;case 135:wl(135);break;case 136:wl(136);break;case 137:wl(137);break;case 146:wl(146);break;case 148:wl(148);break;case 150:wl(150);break;case 151:wl(151);break;case 153:wl(153);break;case 159:wl(159);break;case 160:wl(160);break;case 162:wl(162);break;case 163:wl(163);break;case 164:wl(164);break;case 170:wl(170);break;case 172:wl(172);break;case 174:wl(174);break;case 178:wl(178);break;case 180:wl(180);break;case 181:wl(181);break;case 182:wl(182);break;case 184:wl(184);break;case 186:wl(186);break;case 198:wl(198);break;case 200:wl(200);break;case 201:wl(201);break;case 202:wl(202);break;case 206:wl(206);break;case 212:wl(212);break;case 213:wl(213);break;case 218:wl(218);break;case 219:wl(219);break;case 220:wl(220);break;case 224:wl(224);break;case 229:wl(229);break;case 235:wl(235);break;case 236:wl(236);break;case 237:wl(237);break;case 248:wl(248);break;case 249:wl(249);break;case 250:wl(250);break;case 254:wl(254);break;case 256:wl(256);break;case 260:wl(260);break;case 266:wl(266);break;case 270:wl(270);break;case 274:wl(274);break;case 72:wl(72);break;case 81:wl(81);break;case 83:wl(83);break;case 85:wl(85);break;case 86:wl(86);break;case 91:wl(91);break;case 98:wl(98);break;case 101:wl(101);break;case 102:wl(102);break;case 104:wl(104);break;case 106:wl(106);break;case 125:wl(125);break;case 132:wl(132);break;case 133:wl(133);break;case 141:wl(141);break;case 154:wl(154);break;case 155:wl(155);break;case 161:wl(161);break;case 171:wl(171);break;case 192:wl(192);break;case 199:wl(199);break;case 203:wl(203);break;case 222:wl(222);break;case 225:wl(225);break;case 228:wl(228);break;case 234:wl(234);break;case 240:wl(240);break;case 251:wl(251);break;case 252:wl(252);break;case 257:wl(257);break;case 261:wl(261);break;case 262:wl(262);break;case 263:wl(263);break;case 267:wl(267);break;case 97:wl(97);break;case 176:wl(176);break;case 221:wl(221);break;case 77:wl(77);break;case 166:wl(166);break;default:wl(194)}Wl.endNonterminal("FunctionName",_l)}function Ba(){switch(Dl){case 6:El(6);break;case 70:El(70);break;case 73:El(73);break;case 74:El(74);break;case 75:El(75);break;case 79:El(79);break;case 80:El(80);break;case 84:El(84);break;case 88:El(88);break;case 89:El(89);break;case 90:El(90);break;case 93:El(93);break;case 94:El(94);break;case 103:El(103);break;case 105:El(105);break;case 108:El(108);break;case 109:El(109);break;case 110:El(110);break;case 111:El(111);break;case 112:El(112);break;case 113:El(113);break;case 118:El(118);break;case 119:El(119);break;case 122:El(122);break;case 123:El(123);break;case 126:El(126);break;case 128:El(128);break;case 129:El(129);break;case 131:El(131);break;case 134:El(134);break;case 135:El(135);break;case 136:El(136);break;case 137:El(137);break;case 146:El(146);break;case 148:El(148);break;case 150:El(150);break;case 151:El(151);break;case 153:El(153);break;case 159:El(159);break;case 160:El(160);break;case 162:El(162);break;case 163:El(163);break;case 164:El(164);break;case 170:El(170);break;case 172:El(172);break;case 174:El(174);break;case 178:El(178);break;case 180:El(180);break;case 181:El(181);break;case 182:El(182);break;case 184:El(184);break;case 186:El(186);break;case 198:El(198);break;case 200:El(200);break;case 201:El(201);break;case 202:El(202);break;case 206:El(206);break;case 212:El(212);break;case 213:El(213);break;case 218:El(218);break;case 219:El(219);break;case 220:El(220);break;case 224:El(224);break;case 229:El(229);break;case 235:El(235);break;case 236:El(236);break;case 237:El(237);break;case 248:El(248);break;case 249:El(249);break;case 250:El(250);break;case 254:El(254);break;case 256:El(256);break;case 260:El(260);break;case 266:El(266);break;case 270:El(270);break;case 274:El(274);break;case 72:El(72);break;case 81:El(81);break;case 83:El(83);break;case 85:El(85);break;case 86:El(86);break;case 91:El(91);break;case 98:El(98);break;case 101:El(101);break;case 102:El(102);break;case 104:El(104);break;case 106:El(106);break;case 125:El(125);break;case 132:El(132);break;case 133:El(133);break;case 141:El(141);break;case 154:El(154);break;case 155:El(155);break;case 161:El(161);break;case 171:El(171);break;case 192:El(192);break;case 199:El(199);break;case 203:El(203);break;case 222:El(222);break;case 225:El(225);break;case 228:El(228);break;case 234:El(234);break;case 240:El(240);break;case 251:El(251);break;case 252:El(252);break;case 257:El(257);break;case 261:El(261);break;case 262:El(262);break;case 263:El(263);break;case 267:El(267);break;case 97:El(97);break;case 176:El(176);break;case 221:El(221);break;case 77:El(77);break;case 166:El(166);break;default:El(194)}}function ja(){Wl.startNonterminal("NCName",_l);switch(Dl){case 19:wl(19);break;case 70:wl(70);break;case 75:wl(75);break;case 79:wl(79);break;case 80:wl(80);break;case 84:wl(84);break;case 88:wl(88);break;case 89:wl(89);break;case 90:wl(90);break;case 94:wl(94);break;case 105:wl(105);break;case 109:wl(109);break;case 113:wl(113);break;case 118:wl(118);break;case 122:wl(122);break;case 123:wl(123);break;case 126:wl(126);break;case 128:wl(128);break;case 131:wl(131);break;case 137:wl(137);break;case 146:wl(146);break;case 148:wl(148);break;case 150:wl(150);break;case 151:wl(151);break;case 160:wl(160);break;case 162:wl(162);break;case 163:wl(163);break;case 164:wl(164);break;case 172:wl(172);break;case 174:wl(174);break;case 178:wl(178);break;case 180:wl(180);break;case 181:wl(181);break;case 186:wl(186);break;case 198:wl(198);break;case 200:wl(200);break;case 201:wl(201);break;case 220:wl(220);break;case 224:wl(224);break;case 236:wl(236);break;case 237:wl(237);break;case 248:wl(248);break;case 249:wl(249);break;case 254:wl(254);break;case 266:wl(266);break;case 270:wl(270);break;case 73:wl(73);break;case 74:wl(74);break;case 82:wl(82);break;case 93:wl(93);break;case 96:wl(96);break;case 103:wl(103);break;case 108:wl(108);break;case 110:wl(110);break;case 111:wl(111);break;case 112:wl(112);break;case 119:wl(119);break;case 120:wl(120);break;case 121:wl(121);break;case 124:wl(124);break;case 129:wl(129);break;case 134:wl(134);break;case 135:wl(135);break;case 136:wl(136);break;case 145:wl(145);break;case 152:wl(152);break;case 153:wl(153);break;case 159:wl(159);break;case 165:wl(165);break;case 170:wl(170);break;case 182:wl(182);break;case 184:wl(184);break;case 185:wl(185);break;case 191:wl(191);break;case 202:wl(202);break;case 206:wl(206);break;case 212:wl(212);break;case 213:wl(213);break;case 216:wl(216);break;case 218:wl(218);break;case 219:wl(219);break;case 226:wl(226);break;case 227:wl(227);break;case 229:wl(229);break;case 235:wl(235);break;case 243:wl(243);break;case 244:wl(244);break;case 250:wl(250);break;case 253:wl(253);break;case 256:wl(256);break;case 260:wl(260);break;case 262:wl(262);break;case 274:wl(274);break;case 72:wl(72);break;case 81:wl(81);break;case 83:wl(83);break;case 85:wl(85);break;case 86:wl(86);break;case 91:wl(91);break;case 98:wl(98);break;case 101:wl(101);break;case 102:wl(102);break;case 104:wl(104);break;case 106:wl(106);break;case 125:wl(125);break;case 132:wl(132);break;case 133:wl(133);break;case 141:wl(141);break;case 154:wl(154);break;case 155:wl(155);break;case 161:wl(161);break;case 171:wl(171);break;case 192:wl(192);break;case 199:wl(199);break;case 203:wl(203);break;case 222:wl(222);break;case 225:wl(225);break;case 228:wl(228);break;case 234:wl(234);break;case 240:wl(240);break;case 251:wl(251);break;case 252:wl(252);break;case 257:wl(257);break;case 261:wl(261);break;case 263:wl(263);break;case 267:wl(267);break;case 97:wl(97);break;case 176:wl(176);break;case 221:wl(221);break;case 77:wl(77);break;case 166:wl(166);break;default:wl(194)}Wl.endNonterminal("NCName",_l)}function Fa(){switch(Dl){case 19:El(19);break;case 70:El(70);break;case 75:El(75);break;case 79:El(79);break;case 80:El(80);break;case 84:El(84);break;case 88:El(88);break;case 89:El(89);break;case 90:El(90);break;case 94:El(94);break;case 105:El(105);break;case 109:El(109);break;case 113:El(113);break;case 118:El(118);break;case 122:El(122);break;case 123:El(123);break;case 126:El(126);break;case 128:El(128);break;case 131:El(131);break;case 137:El(137);break;case 146:El(146);break;case 148:El(148);break;case 150:El(150);break;case 151:El(151);break;case 160:El(160);break;case 162:El(162);break;case 163:El(163);break;case 164:El(164);break;case 172:El(172);break;case 174:El(174);break;case 178:El(178);break;case 180:El(180);break;case 181:El(181);break;case 186:El(186);break;case 198:El(198);break;case 200:El(200);break;case 201:El(201);break;case 220:El(220);break;case 224:El(224);break;case 236:El(236);break;case 237:El(237);break;case 248:El(248);break;case 249:El(249);break;case 254:El(254);break;case 266:El(266);break;case 270:El(270);break;case 73:El(73);break;case 74:El(74);break;case 82:El(82);break;case 93:El(93);break;case 96:El(96);break;case 103:El(103);break;case 108:El(108);break;case 110:El(110);break;case 111:El(111);break;case 112:El(112);break;case 119:El(119);break;case 120:El(120);break;case 121:El(121);break;case 124:El(124);break;case 129:El(129);break;case 134:El(134);break;case 135:El(135);break;case 136:El(136);break;case 145:El(145);break;case 152:El(152);break;case 153:El(153);break;case 159:El(159);break;case 165:El(165);break;case 170:El(170);break;case 182:El(182);break;case 184:El(184);break;case 185:El(185);break;case 191:El(191);break;case 202:El(202);break;case 206:El(206);break;case 212:El(212);break;case 213:El(213);break;case 216:El(216);break;case 218:El(218);break;case 219:El(219);break;case 226:El(226);break;case 227:El(227);break;case 229:El(229);break;case 235:El(235);break;case 243:El(243);break;case 244:El(244);break;case 250:El(250);break;case 253:El(253);break;case 256:El(256);break;case 260:El(260);break;case 262:El(262);break;case 274:El(274);break;case 72:El(72);break;case 81:El(81);break;case 83:El(83);break;case 85:El(85);break;case 86:El(86);break;case 91:El(91);break;case 98:El(98);break;case 101:El(101);break;case 102:El(102);break;case 104:El(104);break;case 106:El(106);break;case 125:El(125);break;case 132:El(132);break;case 133:El(133);break;case 141:El(141);break;case 154:El(154);break;case 155:El(155);break;case 161:El(161);break;case 171:El(171);break;case 192:El(192);break;case 199:El(199);break;case 203:El(203);break;case 222:El(222);break;case 225:El(225);break;case 228:El(228);break;case 234:El(234);break;case 240:El(240);break;case 251:El(251);break;case 252:El(252);break;case 257:El(257);break;case 261:El(261);break;case 263:El(263);break;case 267:El(267);break;case 97:El(97);break;case 176:El(176);break;case 221:El(221);break;case 77:El(77);break;case 166:El(166);break;default:El(194)}}function Ia(){Wl.startNonterminal("MainModule",_l),l(),xl(),qa(),Wl.endNonterminal("MainModule",_l)}function qa(){Wl.startNonterminal("Program",_l),Xa(),Wl.endNonterminal("Program",_l)}function Ra(){Wl.startNonterminal("Statements",_l);for(;;){Nl(278);switch(Dl){case 34:Cl(269);break;case 35:Ll(252);break;case 46:Cl(284);break;case 47:Cl(265);break;case 54:Ll(4);break;case 55:Ll(1);break;case 59:Ll(3);break;case 66:Cl(257);break;case 68:Cl(272);break;case 77:Cl(200);break;case 82:Cl(281);break;case 121:Cl(280);break;case 132:Cl(203);break;case 137:Cl(208);break;case 174:Cl(205);break;case 218:Cl(206);break;case 219:Cl(207);break;case 260:Cl(210);break;case 276:Cl(277);break;case 278:Cl(273);break;case 5:case 45:Cl(186);break;case 31:case 32:Cl(255);break;case 40:case 42:Cl(267);break;case 86:case 102:Cl(201);break;case 110:case 159:Cl(209);break;case 184:case 216:Cl(268);break;case 103:case 129:case 235:case 262:Cl(197);break;case 8:case 9:case 10:case 11:case 44:Cl(192);break;case 78:case 124:case 165:case 167:case 242:Cl(191);break;case 96:case 119:case 202:case 244:case 250:case 256:Cl(204);break;case 73:case 74:case 93:case 111:case 112:case 135:case 136:case 206:case 212:case 213:case 229:Cl(198);break;case 6:case 70:case 72:case 75:case 79:case 80:case 81:case 83:case 84:case 85:case 88:case 89:case 90:case 91:case 94:case 97:case 98:case 101:case 104:case 105:case 106:case 108:case 109:case 113:case 118:case 120:case 122:case 123:case 125:case 126:case 128:case 131:case 133:case 134:case 141:case 145:case 146:case 148:case 150:case 151:case 152:case 153:case 154:case 155:case 160:case 161:case 162:case 163:case 164:case 166:case 170:case 171:case 172:case 176:case 178:case 180:case 181:case 182:case 185:case 186:case 191:case 192:case 194:case 198:case 199:case 200:case 201:case 203:case 220:case 221:case 222:case 224:case 225:case 226:case 227:case 228:case 234:case 236:case 237:case 240:case 243:case 248:case 249:case 251:case 252:case 253:case 254:case 257:case 261:case 263:case 266:case 267:case 270:case 274:Cl(195);break;default:Ol=Dl}if(Ol!=25&&Ol!=53&&Ol!=282&&Ol!=12805&&Ol!=12806&&Ol!=12808&&Ol!=12809&&Ol!=12810&&Ol!=12811&&Ol!=12844&&Ol!=12845&&Ol!=12846&&Ol!=12870&&Ol!=12872&&Ol!=12873&&Ol!=12874&&Ol!=12875&&Ol!=12877&&Ol!=12878&&Ol!=12879&&Ol!=12880&&Ol!=12881&&Ol!=12882&&Ol!=12883&&Ol!=12884&&Ol!=12885&&Ol!=12886&&Ol!=12888&&Ol!=12889&&Ol!=12890&&Ol!=12891&&Ol!=12893&&Ol!=12894&&Ol!=12896&&Ol!=12897&&Ol!=12898&&Ol!=12901&&Ol!=12902&&Ol!=12903&&Ol!=12904&&Ol!=12905&&Ol!=12906&&Ol!=12908&&Ol!=12909&&Ol!=12910&&Ol!=12911&&Ol!=12912&&Ol!=12913&&Ol!=12918&&Ol!=12919&&Ol!=12920&&Ol!=12921&&Ol!=12922&&Ol!=12923&&Ol!=12924&&Ol!=12925&&Ol!=12926&&Ol!=12928&&Ol!=12929&&Ol!=12931&&Ol!=12932&&Ol!=12933&&Ol!=12934&&Ol!=12935&&Ol!=12936&&Ol!=12937&&Ol!=12941&&Ol!=12945&&Ol!=12946&&Ol!=12948&&Ol!=12950&&Ol!=12951&&Ol!=12952&&Ol!=12953&&Ol!=12954&&Ol!=12955&&Ol!=12959&&Ol!=12960&&Ol!=12961&&Ol!=12962&&Ol!=12963&&Ol!=12964&&Ol!=12965&&Ol!=12966&&Ol!=12967&&Ol!=12970&&Ol!=12971&&Ol!=12972&&Ol!=12974&&Ol!=12976&&Ol!=12978&&Ol!=12980&&Ol!=12981&&Ol!=12982&&Ol!=12984&&Ol!=12985&&Ol!=12986&&Ol!=12991&&Ol!=12992&&Ol!=12994&&Ol!=12998&&Ol!=12999&&Ol!=13e3&&Ol!=13001&&Ol!=13002&&Ol!=13003&&Ol!=13006&&Ol!=13012&&Ol!=13013&&Ol!=13016&&Ol!=13018&&Ol!=13019&&Ol!=13020&&Ol!=13021&&Ol!=13022&&Ol!=13024&&Ol!=13025&&Ol!=13026&&Ol!=13027&&Ol!=13028&&Ol!=13029&&Ol!=13034&&Ol!=13035&&Ol!=13036&&Ol!=13037&&Ol!=13040&&Ol!=13042&&Ol!=13043&&Ol!=13044&&Ol!=13048&&Ol!=13049&&Ol!=13050&&Ol!=13051&&Ol!=13052&&Ol!=13053&&Ol!=13054&&Ol!=13056&&Ol!=13057&&Ol!=13060&&Ol!=13061&&Ol!=13062&&Ol!=13063&&Ol!=13066&&Ol!=13067&&Ol!=13070&&Ol!=13074&&Ol!=16134&&Ol!=20997&&Ol!=20998&&Ol!=21e3&&Ol!=21001&&Ol!=21002&&Ol!=21003&&Ol!=21036&&Ol!=21037&&Ol!=21038&&Ol!=21062&&Ol!=21064&&Ol!=21065&&Ol!=21066&&Ol!=21067&&Ol!=21069&&Ol!=21070&&Ol!=21071&&Ol!=21072&&Ol!=21073&&Ol!=21074&&Ol!=21075&&Ol!=21076&&Ol!=21077&&Ol!=21078&&Ol!=21080&&Ol!=21081&&Ol!=21082&&Ol!=21083&&Ol!=21085&&Ol!=21086&&Ol!=21088&&Ol!=21089&&Ol!=21090&&Ol!=21093&&Ol!=21094&&Ol!=21095&&Ol!=21096&&Ol!=21097&&Ol!=21098&&Ol!=21100&&Ol!=21101&&Ol!=21102&&Ol!=21103&&Ol!=21104&&Ol!=21105&&Ol!=21110&&Ol!=21111&&Ol!=21112&&Ol!=21113&&Ol!=21114&&Ol!=21115&&Ol!=21116&&Ol!=21117&&Ol!=21118&&Ol!=21120&&Ol!=21121&&Ol!=21123&&Ol!=21124&&Ol!=21125&&Ol!=21126&&Ol!=21127&&Ol!=21128&&Ol!=21129&&Ol!=21133&&Ol!=21137&&Ol!=21138&&Ol!=21140&&Ol!=21142&&Ol!=21143&&Ol!=21144&&Ol!=21145&&Ol!=21146&&Ol!=21147&&Ol!=21151&&Ol!=21152&&Ol!=21153&&Ol!=21154&&Ol!=21155&&Ol!=21156&&Ol!=21157&&Ol!=21158&&Ol!=21159&&Ol!=21162&&Ol!=21163&&Ol!=21164&&Ol!=21166&&Ol!=21168&&Ol!=21170&&Ol!=21172&&Ol!=21173&&Ol!=21174&&Ol!=21176&&Ol!=21177&&Ol!=21178&&Ol!=21183&&Ol!=21184&&Ol!=21186&&Ol!=21190&&Ol!=21191&&Ol!=21192&&Ol!=21193&&Ol!=21194&&Ol!=21195&&Ol!=21198&&Ol!=21204&&Ol!=21205&&Ol!=21208&&Ol!=21210&&Ol!=21211&&Ol!=21212&&Ol!=21213&&Ol!=21214&&Ol!=21216&&Ol!=21217&&Ol!=21218&&Ol!=21219&&Ol!=21220&&Ol!=21221&&Ol!=21226&&Ol!=21227&&Ol!=21228&&Ol!=21229&&Ol!=21232&&Ol!=21234&&Ol!=21235&&Ol!=21236&&Ol!=21240&&Ol!=21241&&Ol!=21242&&Ol!=21243&&Ol!=21244&&Ol!=21245&&Ol!=21246&&Ol!=21248&&Ol!=21249&&Ol!=21252&&Ol!=21253&&Ol!=21254&&Ol!=21255&&Ol!=21258&&Ol!=21259&&Ol!=21262&&Ol!=21266&&Ol!=27141&&Ol!=27142&&Ol!=27144&&Ol!=27145&&Ol!=27146&&Ol!=27147&&Ol!=27180&&Ol!=27181&&Ol!=27182&&Ol!=27206&&Ol!=27208&&Ol!=27209&&Ol!=27210&&Ol!=27211&&Ol!=27213&&Ol!=27214&&Ol!=27215&&Ol!=27216&&Ol!=27217&&Ol!=27218&&Ol!=27219&&Ol!=27220&&Ol!=27221&&Ol!=27222&&Ol!=27224&&Ol!=27225&&Ol!=27226&&Ol!=27227&&Ol!=27229&&Ol!=27230&&Ol!=27232&&Ol!=27233&&Ol!=27234&&Ol!=27237&&Ol!=27238&&Ol!=27239&&Ol!=27240&&Ol!=27241&&Ol!=27242&&Ol!=27244&&Ol!=27245&&Ol!=27246&&Ol!=27247&&Ol!=27248&&Ol!=27249&&Ol!=27254&&Ol!=27255&&Ol!=27256&&Ol!=27257&&Ol!=27258&&Ol!=27259&&Ol!=27260&&Ol!=27261&&Ol!=27262&&Ol!=27264&&Ol!=27265&&Ol!=27267&&Ol!=27268&&Ol!=27269&&Ol!=27270&&Ol!=27271&&Ol!=27272&&Ol!=27273&&Ol!=27277&&Ol!=27281&&Ol!=27282&&Ol!=27284&&Ol!=27286&&Ol!=27287&&Ol!=27288&&Ol!=27289&&Ol!=27290&&Ol!=27291&&Ol!=27295&&Ol!=27296&&Ol!=27297&&Ol!=27298&&Ol!=27299&&Ol!=27300&&Ol!=27301&&Ol!=27302&&Ol!=27303&&Ol!=27306&&Ol!=27307&&Ol!=27308&&Ol!=27310&&Ol!=27312&&Ol!=27314&&Ol!=27316&&Ol!=27317&&Ol!=27318&&Ol!=27320&&Ol!=27321&&Ol!=27322&&Ol!=27327&&Ol!=27328&&Ol!=27330&&Ol!=27334&&Ol!=27335&&Ol!=27336&&Ol!=27337&&Ol!=27338&&Ol!=27339&&Ol!=27342&&Ol!=27348&&Ol!=27349&&Ol!=27352&&Ol!=27354&&Ol!=27355&&Ol!=27356&&Ol!=27357&&Ol!=27358&&Ol!=27360&&Ol!=27361&&Ol!=27362&&Ol!=27363&&Ol!=27364&&Ol!=27365&&Ol!=27370&&Ol!=27371&&Ol!=27372&&Ol!=27373&&Ol!=27376&&Ol!=27378&&Ol!=27379&&Ol!=27380&&Ol!=27384&&Ol!=27385&&Ol!=27386&&Ol!=27387&&Ol!=27388&&Ol!=27389&&Ol!=27390&&Ol!=27392&&Ol!=27393&&Ol!=27396&&Ol!=27397&&Ol!=27398&&Ol!=27399&&Ol!=27402&&Ol!=27403&&Ol!=27406&&Ol!=27410&&Ol!=90198&&Ol!=90214&&Ol!=113284&&Ol!=144389&&Ol!=144390&&Ol!=144392&&Ol!=144393&&Ol!=144394&&Ol!=144395&&Ol!=144428&&Ol!=144429&&Ol!=144430&&Ol!=144454&&Ol!=144456&&Ol!=144457&&Ol!=144458&&Ol!=144459&&Ol!=144461&&Ol!=144462&&Ol!=144463&&Ol!=144464&&Ol!=144465&&Ol!=144466&&Ol!=144467&&Ol!=144468&&Ol!=144469&&Ol!=144470&&Ol!=144472&&Ol!=144473&&Ol!=144474&&Ol!=144475&&Ol!=144477&&Ol!=144478&&Ol!=144480&&Ol!=144481&&Ol!=144482&&Ol!=144485&&Ol!=144486&&Ol!=144487&&Ol!=144488&&Ol!=144489&&Ol!=144490&&Ol!=144492&&Ol!=144493&&Ol!=144494&&Ol!=144495&&Ol!=144496&&Ol!=144497&&Ol!=144502&&Ol!=144503&&Ol!=144504&&Ol!=144505&&Ol!=144506&&Ol!=144507&&Ol!=144508&&Ol!=144509&&Ol!=144510&&Ol!=144512&&Ol!=144513&&Ol!=144515&&Ol!=144516&&Ol!=144517&&Ol!=144518&&Ol!=144519&&Ol!=144520&&Ol!=144521&&Ol!=144525&&Ol!=144529&&Ol!=144530&&Ol!=144532&&Ol!=144534&&Ol!=144535&&Ol!=144536&&Ol!=144537&&Ol!=144538&&Ol!=144539&&Ol!=144543&&Ol!=144544&&Ol!=144545&&Ol!=144546&&Ol!=144547&&Ol!=144548&&Ol!=144549&&Ol!=144550&&Ol!=144551&&Ol!=144554&&Ol!=144555&&Ol!=144556&&Ol!=144558&&Ol!=144560&&Ol!=144562&&Ol!=144564&&Ol!=144565&&Ol!=144566&&Ol!=144568&&Ol!=144569&&Ol!=144570&&Ol!=144575&&Ol!=144576&&Ol!=144578&&Ol!=144582&&Ol!=144583&&Ol!=144584&&Ol!=144585&&Ol!=144586&&Ol!=144587&&Ol!=144590&&Ol!=144596&&Ol!=144597&&Ol!=144600&&Ol!=144602&&Ol!=144603&&Ol!=144604&&Ol!=144605&&Ol!=144606&&Ol!=144608&&Ol!=144609&&Ol!=144610&&Ol!=144611&&Ol!=144612&&Ol!=144613&&Ol!=144618&&Ol!=144619&&Ol!=144620&&Ol!=144621&&Ol!=144624&&Ol!=144626&&Ol!=144627&&Ol!=144628&&Ol!=144632&&Ol!=144633&&Ol!=144634&&Ol!=144635&&Ol!=144636&&Ol!=144637&&Ol!=144638&&Ol!=144640&&Ol!=144641&&Ol!=144644&&Ol!=144645&&Ol!=144646&&Ol!=144647&&Ol!=144650&&Ol!=144651&&Ol!=144654&&Ol!=144658){Ol=$l(6,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Ja(),Ol=-1}catch(a){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(6,_l,Ol)}}if(Ol!=-1&&Ol!=53&&Ol!=16134&&Ol!=27141&&Ol!=27142&&Ol!=27144&&Ol!=27145&&Ol!=27146&&Ol!=27147&&Ol!=27180&&Ol!=27181&&Ol!=27182&&Ol!=27206&&Ol!=27208&&Ol!=27209&&Ol!=27210&&Ol!=27211&&Ol!=27213&&Ol!=27214&&Ol!=27215&&Ol!=27216&&Ol!=27217&&Ol!=27218&&Ol!=27219&&Ol!=27220&&Ol!=27221&&Ol!=27222&&Ol!=27224&&Ol!=27225&&Ol!=27226&&Ol!=27227&&Ol!=27229&&Ol!=27230&&Ol!=27232&&Ol!=27233&&Ol!=27234&&Ol!=27237&&Ol!=27238&&Ol!=27239&&Ol!=27240&&Ol!=27241&&Ol!=27242&&Ol!=27244&&Ol!=27245&&Ol!=27246&&Ol!=27247&&Ol!=27248&&Ol!=27249&&Ol!=27254&&Ol!=27255&&Ol!=27256&&Ol!=27257&&Ol!=27258&&Ol!=27259&&Ol!=27260&&Ol!=27261&&Ol!=27262&&Ol!=27264&&Ol!=27265&&Ol!=27267&&Ol!=27268&&Ol!=27269&&Ol!=27270&&Ol!=27271&&Ol!=27272&&Ol!=27273&&Ol!=27277&&Ol!=27281&&Ol!=27282&&Ol!=27284&&Ol!=27286&&Ol!=27287&&Ol!=27288&&Ol!=27289&&Ol!=27290&&Ol!=27291&&Ol!=27295&&Ol!=27296&&Ol!=27297&&Ol!=27298&&Ol!=27299&&Ol!=27300&&Ol!=27301&&Ol!=27302&&Ol!=27303&&Ol!=27306&&Ol!=27307&&Ol!=27308&&Ol!=27310&&Ol!=27312&&Ol!=27314&&Ol!=27316&&Ol!=27317&&Ol!=27318&&Ol!=27320&&Ol!=27321&&Ol!=27322&&Ol!=27327&&Ol!=27328&&Ol!=27330&&Ol!=27334&&Ol!=27335&&Ol!=27336&&Ol!=27337&&Ol!=27338&&Ol!=27339&&Ol!=27342&&Ol!=27348&&Ol!=27349&&Ol!=27352&&Ol!=27354&&Ol!=27355&&Ol!=27356&&Ol!=27357&&Ol!=27358&&Ol!=27360&&Ol!=27361&&Ol!=27362&&Ol!=27363&&Ol!=27364&&Ol!=27365&&Ol!=27370&&Ol!=27371&&Ol!=27372&&Ol!=27373&&Ol!=27376&&Ol!=27378&&Ol!=27379&&Ol!=27380&&Ol!=27384&&Ol!=27385&&Ol!=27386&&Ol!=27387&&Ol!=27388&&Ol!=27389&&Ol!=27390&&Ol!=27392&&Ol!=27393&&Ol!=27396&&Ol!=27397&&Ol!=27398&&Ol!=27399&&Ol!=27402&&Ol!=27403&&Ol!=27406&&Ol!=27410&&Ol!=90198&&Ol!=90214&&Ol!=113284)break;xl(),$a()}Wl.endNonterminal("Statements",_l)}function Ua(){for(;;){Nl(278);switch(Dl){case 34:Cl(269);break;case 35:Ll(252);break;case 46:Cl(284);break;case 47:Cl(265);break;case 54:Ll(4);break;case 55:Ll(1);break;case 59:Ll(3);break;case 66:Cl(257);break;case 68:Cl(272);break;case 77:Cl(200);break;case 82:Cl(281);break;case 121:Cl(280);break;case 132:Cl(203);break;case 137:Cl(208);break;case 174:Cl(205);break;case 218:Cl(206);break;case 219:Cl(207);break;case 260:Cl(210);break;case 276:Cl(277);break;case 278:Cl(273);break;case 5:case 45:Cl(186);break;case 31:case 32:Cl(255);break;case 40:case 42:Cl(267);break;case 86:case 102:Cl(201);break;case 110:case 159:Cl(209);break;case 184:case 216:Cl(268);break;case 103:case 129:case 235:case 262:Cl(197);break;case 8:case 9:case 10:case 11:case 44:Cl(192);break;case 78:case 124:case 165:case 167:case 242:Cl(191);break;case 96:case 119:case 202:case 244:case 250:case 256:Cl(204);break;case 73:case 74:case 93:case 111:case 112:case 135:case 136:case 206:case 212:case 213:case 229:Cl(198);break;case 6:case 70:case 72:case 75:case 79:case 80:case 81:case 83:case 84:case 85:case 88:case 89:case 90:case 91:case 94:case 97:case 98:case 101:case 104:case 105:case 106:case 108:case 109:case 113:case 118:case 120:case 122:case 123:case 125:case 126:case 128:case 131:case 133:case 134:case 141:case 145:case 146:case 148:case 150:case 151:case 152:case 153:case 154:case 155:case 160:case 161:case 162:case 163:case 164:case 166:case 170:case 171:case 172:case 176:case 178:case 180:case 181:case 182:case 185:case 186:case 191:case 192:case 194:case 198:case 199:case 200:case 201:case 203:case 220:case 221:case 222:case 224:case 225:case 226:case 227:case 228:case 234:case 236:case 237:case 240:case 243:case 248:case 249:case 251:case 252:case 253:case 254:case 257:case 261:case 263:case 266:case 267:case 270:case 274:Cl(195);break;default:Ol=Dl}if(Ol!=25&&Ol!=53&&Ol!=282&&Ol!=12805&&Ol!=12806&&Ol!=12808&&Ol!=12809&&Ol!=12810&&Ol!=12811&&Ol!=12844&&Ol!=12845&&Ol!=12846&&Ol!=12870&&Ol!=12872&&Ol!=12873&&Ol!=12874&&Ol!=12875&&Ol!=12877&&Ol!=12878&&Ol!=12879&&Ol!=12880&&Ol!=12881&&Ol!=12882&&Ol!=12883&&Ol!=12884&&Ol!=12885&&Ol!=12886&&Ol!=12888&&Ol!=12889&&Ol!=12890&&Ol!=12891&&Ol!=12893&&Ol!=12894&&Ol!=12896&&Ol!=12897&&Ol!=12898&&Ol!=12901&&Ol!=12902&&Ol!=12903&&Ol!=12904&&Ol!=12905&&Ol!=12906&&Ol!=12908&&Ol!=12909&&Ol!=12910&&Ol!=12911&&Ol!=12912&&Ol!=12913&&Ol!=12918&&Ol!=12919&&Ol!=12920&&Ol!=12921&&Ol!=12922&&Ol!=12923&&Ol!=12924&&Ol!=12925&&Ol!=12926&&Ol!=12928&&Ol!=12929&&Ol!=12931&&Ol!=12932&&Ol!=12933&&Ol!=12934&&Ol!=12935&&Ol!=12936&&Ol!=12937&&Ol!=12941&&Ol!=12945&&Ol!=12946&&Ol!=12948&&Ol!=12950&&Ol!=12951&&Ol!=12952&&Ol!=12953&&Ol!=12954&&Ol!=12955&&Ol!=12959&&Ol!=12960&&Ol!=12961&&Ol!=12962&&Ol!=12963&&Ol!=12964&&Ol!=12965&&Ol!=12966&&Ol!=12967&&Ol!=12970&&Ol!=12971&&Ol!=12972&&Ol!=12974&&Ol!=12976&&Ol!=12978&&Ol!=12980&&Ol!=12981&&Ol!=12982&&Ol!=12984&&Ol!=12985&&Ol!=12986&&Ol!=12991&&Ol!=12992&&Ol!=12994&&Ol!=12998&&Ol!=12999&&Ol!=13e3&&Ol!=13001&&Ol!=13002&&Ol!=13003&&Ol!=13006&&Ol!=13012&&Ol!=13013&&Ol!=13016&&Ol!=13018&&Ol!=13019&&Ol!=13020&&Ol!=13021&&Ol!=13022&&Ol!=13024&&Ol!=13025&&Ol!=13026&&Ol!=13027&&Ol!=13028&&Ol!=13029&&Ol!=13034&&Ol!=13035&&Ol!=13036&&Ol!=13037&&Ol!=13040&&Ol!=13042&&Ol!=13043&&Ol!=13044&&Ol!=13048&&Ol!=13049&&Ol!=13050&&Ol!=13051&&Ol!=13052&&Ol!=13053&&Ol!=13054&&Ol!=13056&&Ol!=13057&&Ol!=13060&&Ol!=13061&&Ol!=13062&&Ol!=13063&&Ol!=13066&&Ol!=13067&&Ol!=13070&&Ol!=13074&&Ol!=16134&&Ol!=20997&&Ol!=20998&&Ol!=21e3&&Ol!=21001&&Ol!=21002&&Ol!=21003&&Ol!=21036&&Ol!=21037&&Ol!=21038&&Ol!=21062&&Ol!=21064&&Ol!=21065&&Ol!=21066&&Ol!=21067&&Ol!=21069&&Ol!=21070&&Ol!=21071&&Ol!=21072&&Ol!=21073&&Ol!=21074&&Ol!=21075&&Ol!=21076&&Ol!=21077&&Ol!=21078&&Ol!=21080&&Ol!=21081&&Ol!=21082&&Ol!=21083&&Ol!=21085&&Ol!=21086&&Ol!=21088&&Ol!=21089&&Ol!=21090&&Ol!=21093&&Ol!=21094&&Ol!=21095&&Ol!=21096&&Ol!=21097&&Ol!=21098&&Ol!=21100&&Ol!=21101&&Ol!=21102&&Ol!=21103&&Ol!=21104&&Ol!=21105&&Ol!=21110&&Ol!=21111&&Ol!=21112&&Ol!=21113&&Ol!=21114&&Ol!=21115&&Ol!=21116&&Ol!=21117&&Ol!=21118&&Ol!=21120&&Ol!=21121&&Ol!=21123&&Ol!=21124&&Ol!=21125&&Ol!=21126&&Ol!=21127&&Ol!=21128&&Ol!=21129&&Ol!=21133&&Ol!=21137&&Ol!=21138&&Ol!=21140&&Ol!=21142&&Ol!=21143&&Ol!=21144&&Ol!=21145&&Ol!=21146&&Ol!=21147&&Ol!=21151&&Ol!=21152&&Ol!=21153&&Ol!=21154&&Ol!=21155&&Ol!=21156&&Ol!=21157&&Ol!=21158&&Ol!=21159&&Ol!=21162&&Ol!=21163&&Ol!=21164&&Ol!=21166&&Ol!=21168&&Ol!=21170&&Ol!=21172&&Ol!=21173&&Ol!=21174&&Ol!=21176&&Ol!=21177&&Ol!=21178&&Ol!=21183&&Ol!=21184&&Ol!=21186&&Ol!=21190&&Ol!=21191&&Ol!=21192&&Ol!=21193&&Ol!=21194&&Ol!=21195&&Ol!=21198&&Ol!=21204&&Ol!=21205&&Ol!=21208&&Ol!=21210&&Ol!=21211&&Ol!=21212&&Ol!=21213&&Ol!=21214&&Ol!=21216&&Ol!=21217&&Ol!=21218&&Ol!=21219&&Ol!=21220&&Ol!=21221&&Ol!=21226&&Ol!=21227&&Ol!=21228&&Ol!=21229&&Ol!=21232&&Ol!=21234&&Ol!=21235&&Ol!=21236&&Ol!=21240&&Ol!=21241&&Ol!=21242&&Ol!=21243&&Ol!=21244&&Ol!=21245&&Ol!=21246&&Ol!=21248&&Ol!=21249&&Ol!=21252&&Ol!=21253&&Ol!=21254&&Ol!=21255&&Ol!=21258&&Ol!=21259&&Ol!=21262&&Ol!=21266&&Ol!=27141&&Ol!=27142&&Ol!=27144&&Ol!=27145&&Ol!=27146&&Ol!=27147&&Ol!=27180&&Ol!=27181&&Ol!=27182&&Ol!=27206&&Ol!=27208&&Ol!=27209&&Ol!=27210&&Ol!=27211&&Ol!=27213&&Ol!=27214&&Ol!=27215&&Ol!=27216&&Ol!=27217&&Ol!=27218&&Ol!=27219&&Ol!=27220&&Ol!=27221&&Ol!=27222&&Ol!=27224&&Ol!=27225&&Ol!=27226&&Ol!=27227&&Ol!=27229&&Ol!=27230&&Ol!=27232&&Ol!=27233&&Ol!=27234&&Ol!=27237&&Ol!=27238&&Ol!=27239&&Ol!=27240&&Ol!=27241&&Ol!=27242&&Ol!=27244&&Ol!=27245&&Ol!=27246&&Ol!=27247&&Ol!=27248&&Ol!=27249&&Ol!=27254&&Ol!=27255&&Ol!=27256&&Ol!=27257&&Ol!=27258&&Ol!=27259&&Ol!=27260&&Ol!=27261&&Ol!=27262&&Ol!=27264&&Ol!=27265&&Ol!=27267&&Ol!=27268&&Ol!=27269&&Ol!=27270&&Ol!=27271&&Ol!=27272&&Ol!=27273&&Ol!=27277&&Ol!=27281&&Ol!=27282&&Ol!=27284&&Ol!=27286&&Ol!=27287&&Ol!=27288&&Ol!=27289&&Ol!=27290&&Ol!=27291&&Ol!=27295&&Ol!=27296&&Ol!=27297&&Ol!=27298&&Ol!=27299&&Ol!=27300&&Ol!=27301&&Ol!=27302&&Ol!=27303&&Ol!=27306&&Ol!=27307&&Ol!=27308&&Ol!=27310&&Ol!=27312&&Ol!=27314&&Ol!=27316&&Ol!=27317&&Ol!=27318&&Ol!=27320&&Ol!=27321&&Ol!=27322&&Ol!=27327&&Ol!=27328&&Ol!=27330&&Ol!=27334&&Ol!=27335&&Ol!=27336&&Ol!=27337&&Ol!=27338&&Ol!=27339&&Ol!=27342&&Ol!=27348&&Ol!=27349&&Ol!=27352&&Ol!=27354&&Ol!=27355&&Ol!=27356&&Ol!=27357&&Ol!=27358&&Ol!=27360&&Ol!=27361&&Ol!=27362&&Ol!=27363&&Ol!=27364&&Ol!=27365&&Ol!=27370&&Ol!=27371&&Ol!=27372&&Ol!=27373&&Ol!=27376&&Ol!=27378&&Ol!=27379&&Ol!=27380&&Ol!=27384&&Ol!=27385&&Ol!=27386&&Ol!=27387&&Ol!=27388&&Ol!=27389&&Ol!=27390&&Ol!=27392&&Ol!=27393&&Ol!=27396&&Ol!=27397&&Ol!=27398&&Ol!=27399&&Ol!=27402&&Ol!=27403&&Ol!=27406&&Ol!=27410&&Ol!=90198&&Ol!=90214&&Ol!=113284&&Ol!=144389&&Ol!=144390&&Ol!=144392&&Ol!=144393&&Ol!=144394&&Ol!=144395&&Ol!=144428&&Ol!=144429&&Ol!=144430&&Ol!=144454&&Ol!=144456&&Ol!=144457&&Ol!=144458&&Ol!=144459&&Ol!=144461&&Ol!=144462&&Ol!=144463&&Ol!=144464&&Ol!=144465&&Ol!=144466&&Ol!=144467&&Ol!=144468&&Ol!=144469&&Ol!=144470&&Ol!=144472&&Ol!=144473&&Ol!=144474&&Ol!=144475&&Ol!=144477&&Ol!=144478&&Ol!=144480&&Ol!=144481&&Ol!=144482&&Ol!=144485&&Ol!=144486&&Ol!=144487&&Ol!=144488&&Ol!=144489&&Ol!=144490&&Ol!=144492&&Ol!=144493&&Ol!=144494&&Ol!=144495&&Ol!=144496&&Ol!=144497&&Ol!=144502&&Ol!=144503&&Ol!=144504&&Ol!=144505&&Ol!=144506&&Ol!=144507&&Ol!=144508&&Ol!=144509&&Ol!=144510&&Ol!=144512&&Ol!=144513&&Ol!=144515&&Ol!=144516&&Ol!=144517&&Ol!=144518&&Ol!=144519&&Ol!=144520&&Ol!=144521&&Ol!=144525&&Ol!=144529&&Ol!=144530&&Ol!=144532&&Ol!=144534&&Ol!=144535&&Ol!=144536&&Ol!=144537&&Ol!=144538&&Ol!=144539&&Ol!=144543&&Ol!=144544&&Ol!=144545&&Ol!=144546&&Ol!=144547&&Ol!=144548&&Ol!=144549&&Ol!=144550&&Ol!=144551&&Ol!=144554&&Ol!=144555&&Ol!=144556&&Ol!=144558&&Ol!=144560&&Ol!=144562&&Ol!=144564&&Ol!=144565&&Ol!=144566&&Ol!=144568&&Ol!=144569&&Ol!=144570&&Ol!=144575&&Ol!=144576&&Ol!=144578&&Ol!=144582&&Ol!=144583&&Ol!=144584&&Ol!=144585&&Ol!=144586&&Ol!=144587&&Ol!=144590&&Ol!=144596&&Ol!=144597&&Ol!=144600&&Ol!=144602&&Ol!=144603&&Ol!=144604&&Ol!=144605&&Ol!=144606&&Ol!=144608&&Ol!=144609&&Ol!=144610&&Ol!=144611&&Ol!=144612&&Ol!=144613&&Ol!=144618&&Ol!=144619&&Ol!=144620&&Ol!=144621&&Ol!=144624&&Ol!=144626&&Ol!=144627&&Ol!=144628&&Ol!=144632&&Ol!=144633&&Ol!=144634&&Ol!=144635&&Ol!=144636&&Ol!=144637&&Ol!=144638&&Ol!=144640&&Ol!=144641&&Ol!=144644&&Ol!=144645&&Ol!=144646&&Ol!=144647&&Ol!=144650&&Ol!=144651&&Ol!=144654&&Ol!=144658){Ol=$l(6,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Ja(),Vl(6,t,-1);continue}catch(a){Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(6,t,-2);break}}}if(Ol!=-1&&Ol!=53&&Ol!=16134&&Ol!=27141&&Ol!=27142&&Ol!=27144&&Ol!=27145&&Ol!=27146&&Ol!=27147&&Ol!=27180&&Ol!=27181&&Ol!=27182&&Ol!=27206&&Ol!=27208&&Ol!=27209&&Ol!=27210&&Ol!=27211&&Ol!=27213&&Ol!=27214&&Ol!=27215&&Ol!=27216&&Ol!=27217&&Ol!=27218&&Ol!=27219&&Ol!=27220&&Ol!=27221&&Ol!=27222&&Ol!=27224&&Ol!=27225&&Ol!=27226&&Ol!=27227&&Ol!=27229&&Ol!=27230&&Ol!=27232&&Ol!=27233&&Ol!=27234&&Ol!=27237&&Ol!=27238&&Ol!=27239&&Ol!=27240&&Ol!=27241&&Ol!=27242&&Ol!=27244&&Ol!=27245&&Ol!=27246&&Ol!=27247&&Ol!=27248&&Ol!=27249&&Ol!=27254&&Ol!=27255&&Ol!=27256&&Ol!=27257&&Ol!=27258&&Ol!=27259&&Ol!=27260&&Ol!=27261&&Ol!=27262&&Ol!=27264&&Ol!=27265&&Ol!=27267&&Ol!=27268&&Ol!=27269&&Ol!=27270&&Ol!=27271&&Ol!=27272&&Ol!=27273&&Ol!=27277&&Ol!=27281&&Ol!=27282&&Ol!=27284&&Ol!=27286&&Ol!=27287&&Ol!=27288&&Ol!=27289&&Ol!=27290&&Ol!=27291&&Ol!=27295&&Ol!=27296&&Ol!=27297&&Ol!=27298&&Ol!=27299&&Ol!=27300&&Ol!=27301&&Ol!=27302&&Ol!=27303&&Ol!=27306&&Ol!=27307&&Ol!=27308&&Ol!=27310&&Ol!=27312&&Ol!=27314&&Ol!=27316&&Ol!=27317&&Ol!=27318&&Ol!=27320&&Ol!=27321&&Ol!=27322&&Ol!=27327&&Ol!=27328&&Ol!=27330&&Ol!=27334&&Ol!=27335&&Ol!=27336&&Ol!=27337&&Ol!=27338&&Ol!=27339&&Ol!=27342&&Ol!=27348&&Ol!=27349&&Ol!=27352&&Ol!=27354&&Ol!=27355&&Ol!=27356&&Ol!=27357&&Ol!=27358&&Ol!=27360&&Ol!=27361&&Ol!=27362&&Ol!=27363&&Ol!=27364&&Ol!=27365&&Ol!=27370&&Ol!=27371&&Ol!=27372&&Ol!=27373&&Ol!=27376&&Ol!=27378&&Ol!=27379&&Ol!=27380&&Ol!=27384&&Ol!=27385&&Ol!=27386&&Ol!=27387&&Ol!=27388&&Ol!=27389&&Ol!=27390&&Ol!=27392&&Ol!=27393&&Ol!=27396&&Ol!=27397&&Ol!=27398&&Ol!=27399&&Ol!=27402&&Ol!=27403&&Ol!=27406&&Ol!=27410&&Ol!=90198&&Ol!=90214&&Ol!=113284)break;Ja()}}function za(){Wl.startNonterminal("StatementsAndExpr",_l),Ra(),xl(),G(),Wl.endNonterminal("StatementsAndExpr",_l)}function Wa(){Ua(),Y()}function Xa(){Wl.startNonterminal("StatementsAndOptionalExpr",_l),Ra(),Dl!=25&&Dl!=282&&(xl(),G()),Wl.endNonterminal("StatementsAndOptionalExpr",_l)}function Va(){Ua(),Dl!=25&&Dl!=282&&Y()}function $a(){Wl.startNonterminal("Statement",_l);switch(Dl){case 132:Cl(189);break;case 137:Cl(196);break;case 174:Cl(193);break;case 250:Cl(190);break;case 262:Cl(187);break;case 276:Cl(277);break;case 31:case 32:Cl(255);break;case 86:case 102:Cl(188);break;case 152:case 243:case 253:case 267:Cl(185);break;default:Ol=Dl}if(Ol==2836||Ol==3103||Ol==3104||Ol==3348||Ol==4372||Ol==4884||Ol==5396||Ol==5908||Ol==16148||Ol==16660||Ol==17675||Ol==17684||Ol==18196||Ol==20756||Ol==21780||Ol==22804||Ol==23316||Ol==23828||Ol==24340||Ol==27412||Ol==27924||Ol==28436||Ol==30484||Ol==34068||Ol==35092||Ol==35871||Ol==35872||Ol==36116||Ol==36895||Ol==36896||Ol==37140||Ol==37407||Ol==37408||Ol==37652||Ol==37919||Ol==37920||Ol==38164||Ol==38431||Ol==38432||Ol==38676||Ol==39455||Ol==39456||Ol==39700||Ol==39967||Ol==39968||Ol==40212||Ol==40479||Ol==40480||Ol==40724||Ol==40991||Ol==40992||Ol==41236||Ol==41503||Ol==41504||Ol==41748||Ol==42015||Ol==42016||Ol==42260||Ol==42527||Ol==42528||Ol==42772||Ol==43039||Ol==43040||Ol==43284||Ol==43551||Ol==43552||Ol==43796||Ol==44063||Ol==44064||Ol==44308||Ol==45087||Ol==45088||Ol==45332||Ol==45599||Ol==45600||Ol==45844||Ol==46111||Ol==46112||Ol==46356||Ol==46623||Ol==46624||Ol==46868||Ol==47647||Ol==47648||Ol==47892||Ol==48159||Ol==48160||Ol==48404||Ol==49183||Ol==49184||Ol==49428||Ol==49695||Ol==49696||Ol==49940||Ol==50207||Ol==50208||Ol==50452||Ol==51743||Ol==51744||Ol==51988||Ol==52255||Ol==52256||Ol==52500||Ol==52767||Ol==52768||Ol==53012||Ol==53279||Ol==53280||Ol==53524||Ol==53791||Ol==53792||Ol==54036||Ol==54303||Ol==54304||Ol==54548||Ol==55327||Ol==55328||Ol==55572||Ol==55839||Ol==55840||Ol==56084||Ol==56351||Ol==56352||Ol==56596||Ol==56863||Ol==56864||Ol==57108||Ol==57375||Ol==57376||Ol==57620||Ol==57887||Ol==57888||Ol==58132||Ol==60447||Ol==60448||Ol==60692||Ol==60959||Ol==60960||Ol==61204||Ol==61471||Ol==61472||Ol==61716||Ol==61983||Ol==61984||Ol==62228||Ol==62495||Ol==62496||Ol==62740||Ol==63007||Ol==63008||Ol==63252||Ol==63519||Ol==63520||Ol==63764||Ol==64031||Ol==64032||Ol==64276||Ol==64543||Ol==64544||Ol==64788||Ol==65567||Ol==65568||Ol==65812||Ol==66079||Ol==66080||Ol==66324||Ol==67103||Ol==67104||Ol==67348||Ol==67615||Ol==67616||Ol==67860||Ol==68127||Ol==68128||Ol==68372||Ol==68639||Ol==68640||Ol==68884||Ol==69151||Ol==69152||Ol==69396||Ol==69663||Ol==69664||Ol==69908||Ol==70175||Ol==70176||Ol==70420||Ol==72223||Ol==72224||Ol==72468||Ol==74271||Ol==74272||Ol==74516||Ol==74783||Ol==74784||Ol==75028||Ol==75807||Ol==75808||Ol==76052||Ol==76831||Ol==76832||Ol==77076||Ol==77343||Ol==77344||Ol==77588||Ol==77855||Ol==77856||Ol==78100||Ol==78367||Ol==78368||Ol==78612||Ol==78879||Ol==78880||Ol==79124||Ol==79391||Ol==79392||Ol==79636||Ol==81439||Ol==81440||Ol==81684||Ol==81951||Ol==81952||Ol==82196||Ol==82463||Ol==82464||Ol==82708||Ol==82975||Ol==82976||Ol==83220||Ol==83487||Ol==83488||Ol==83732||Ol==83999||Ol==84e3||Ol==84244||Ol==84511||Ol==84512||Ol==84756||Ol==85023||Ol==85024||Ol==85268||Ol==85535||Ol==85536||Ol==85780||Ol==87071||Ol==87072||Ol==87316||Ol==87583||Ol==87584||Ol==87828||Ol==88095||Ol==88096||Ol==88340||Ol==89119||Ol==89120||Ol==89364||Ol==90143||Ol==90144||Ol==90388||Ol==91167||Ol==91168||Ol==91412||Ol==92191||Ol==92192||Ol==92436||Ol==92703||Ol==92704||Ol==92948||Ol==93215||Ol==93216||Ol==93460||Ol==94239||Ol==94240||Ol==94484||Ol==94751||Ol==94752||Ol==94996||Ol==95263||Ol==95264||Ol==95508||Ol==97823||Ol==97824||Ol==98068||Ol==98335||Ol==98336||Ol==98580||Ol==99359||Ol==99360||Ol==99604||Ol==101407||Ol==101408||Ol==101652||Ol==101919||Ol==101920||Ol==102164||Ol==102431||Ol==102432||Ol==102676||Ol==102943||Ol==102944||Ol==103188||Ol==103455||Ol==103456||Ol==103700||Ol==103967||Ol==103968||Ol==104212||Ol==105503||Ol==105504||Ol==105748||Ol==108575||Ol==108576||Ol==108820||Ol==109087||Ol==109088||Ol==109332||Ol==110623||Ol==110624||Ol==110868||Ol==111647||Ol==111648||Ol==111892||Ol==112159||Ol==112160||Ol==112404||Ol==112671||Ol==112672||Ol==112916||Ol==113183||Ol==113184||Ol==113428||Ol==113695||Ol==113696||Ol==113940||Ol==114719||Ol==114720||Ol==114964||Ol==115231||Ol==115232||Ol==115476||Ol==115743||Ol==115744||Ol==115988||Ol==116255||Ol==116256||Ol==116500||Ol==116767||Ol==116768||Ol==117012||Ol==117279||Ol==117280||Ol==117524||Ol==119839||Ol==119840||Ol==120084||Ol==120351||Ol==120352||Ol==120596||Ol==120863||Ol==120864||Ol==121108||Ol==121375||Ol==121376||Ol==121620||Ol==122911||Ol==122912||Ol==123156||Ol==123935||Ol==123936||Ol==124180||Ol==124447||Ol==124448||Ol==124692||Ol==124959||Ol==124960||Ol==125204||Ol==127007||Ol==127008||Ol==127252||Ol==127519||Ol==127520||Ol==127764||Ol==128031||Ol==128032||Ol==128276||Ol==128543||Ol==128544||Ol==128788||Ol==129055||Ol==129056||Ol==129300||Ol==129567||Ol==129568||Ol==129812||Ol==130079||Ol==130080||Ol==130324||Ol==131103||Ol==131104||Ol==131348||Ol==131615||Ol==131616||Ol==131860||Ol==133151||Ol==133152||Ol==133396||Ol==133663||Ol==133664||Ol==133908||Ol==134175||Ol==134176||Ol==134420||Ol==134687||Ol==134688||Ol==134932||Ol==136223||Ol==136224||Ol==136468||Ol==136735||Ol==136736||Ol==136980||Ol==138271||Ol==138272||Ol==138516||Ol==140319||Ol==140320||Ol==140564||Ol==141588||Ol==142612||Ol==144660){Ol=$l(7,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Qa(),Ol=-1}catch(a){try{Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Ya(),Ol=-2}catch(f){try{Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),ef(),Ol=-3}catch(l){try{Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Nf(),Ol=-12}catch(c){Ol=-13}}}}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(7,_l,Ol)}}switch(Ol){case-2:Ga();break;case-3:Za();break;case 90198:tf();break;case 90214:rf();break;case 113284:of();break;case 16009:case 16046:case 116910:case 119945:case 128649:af();break;case 17560:hf();break;case 17651:df();break;case 141562:yf();break;case 17661:wf();break;case-12:case 16134:Tf();break;case-13:Cf();break;case 53:Lf();break;default:Ka()}Wl.endNonterminal("Statement",_l)}function Ja(){switch(Dl){case 132:Cl(189);break;case 137:Cl(196);break;case 174:Cl(193);break;case 250:Cl(190);break;case 262:Cl(187);break;case 276:Cl(277);break;case 31:case 32:Cl(255);break;case 86:case 102:Cl(188);break;case 152:case 243:case 253:case 267:Cl(185);break;default:Ol=Dl}if(Ol==2836||Ol==3103||Ol==3104||Ol==3348||Ol==4372||Ol==4884||Ol==5396||Ol==5908||Ol==16148||Ol==16660||Ol==17675||Ol==17684||Ol==18196||Ol==20756||Ol==21780||Ol==22804||Ol==23316||Ol==23828||Ol==24340||Ol==27412||Ol==27924||Ol==28436||Ol==30484||Ol==34068||Ol==35092||Ol==35871||Ol==35872||Ol==36116||Ol==36895||Ol==36896||Ol==37140||Ol==37407||Ol==37408||Ol==37652||Ol==37919||Ol==37920||Ol==38164||Ol==38431||Ol==38432||Ol==38676||Ol==39455||Ol==39456||Ol==39700||Ol==39967||Ol==39968||Ol==40212||Ol==40479||Ol==40480||Ol==40724||Ol==40991||Ol==40992||Ol==41236||Ol==41503||Ol==41504||Ol==41748||Ol==42015||Ol==42016||Ol==42260||Ol==42527||Ol==42528||Ol==42772||Ol==43039||Ol==43040||Ol==43284||Ol==43551||Ol==43552||Ol==43796||Ol==44063||Ol==44064||Ol==44308||Ol==45087||Ol==45088||Ol==45332||Ol==45599||Ol==45600||Ol==45844||Ol==46111||Ol==46112||Ol==46356||Ol==46623||Ol==46624||Ol==46868||Ol==47647||Ol==47648||Ol==47892||Ol==48159||Ol==48160||Ol==48404||Ol==49183||Ol==49184||Ol==49428||Ol==49695||Ol==49696||Ol==49940||Ol==50207||Ol==50208||Ol==50452||Ol==51743||Ol==51744||Ol==51988||Ol==52255||Ol==52256||Ol==52500||Ol==52767||Ol==52768||Ol==53012||Ol==53279||Ol==53280||Ol==53524||Ol==53791||Ol==53792||Ol==54036||Ol==54303||Ol==54304||Ol==54548||Ol==55327||Ol==55328||Ol==55572||Ol==55839||Ol==55840||Ol==56084||Ol==56351||Ol==56352||Ol==56596||Ol==56863||Ol==56864||Ol==57108||Ol==57375||Ol==57376||Ol==57620||Ol==57887||Ol==57888||Ol==58132||Ol==60447||Ol==60448||Ol==60692||Ol==60959||Ol==60960||Ol==61204||Ol==61471||Ol==61472||Ol==61716||Ol==61983||Ol==61984||Ol==62228||Ol==62495||Ol==62496||Ol==62740||Ol==63007||Ol==63008||Ol==63252||Ol==63519||Ol==63520||Ol==63764||Ol==64031||Ol==64032||Ol==64276||Ol==64543||Ol==64544||Ol==64788||Ol==65567||Ol==65568||Ol==65812||Ol==66079||Ol==66080||Ol==66324||Ol==67103||Ol==67104||Ol==67348||Ol==67615||Ol==67616||Ol==67860||Ol==68127||Ol==68128||Ol==68372||Ol==68639||Ol==68640||Ol==68884||Ol==69151||Ol==69152||Ol==69396||Ol==69663||Ol==69664||Ol==69908||Ol==70175||Ol==70176||Ol==70420||Ol==72223||Ol==72224||Ol==72468||Ol==74271||Ol==74272||Ol==74516||Ol==74783||Ol==74784||Ol==75028||Ol==75807||Ol==75808||Ol==76052||Ol==76831||Ol==76832||Ol==77076||Ol==77343||Ol==77344||Ol==77588||Ol==77855||Ol==77856||Ol==78100||Ol==78367||Ol==78368||Ol==78612||Ol==78879||Ol==78880||Ol==79124||Ol==79391||Ol==79392||Ol==79636||Ol==81439||Ol==81440||Ol==81684||Ol==81951||Ol==81952||Ol==82196||Ol==82463||Ol==82464||Ol==82708||Ol==82975||Ol==82976||Ol==83220||Ol==83487||Ol==83488||Ol==83732||Ol==83999||Ol==84e3||Ol==84244||Ol==84511||Ol==84512||Ol==84756||Ol==85023||Ol==85024||Ol==85268||Ol==85535||Ol==85536||Ol==85780||Ol==87071||Ol==87072||Ol==87316||Ol==87583||Ol==87584||Ol==87828||Ol==88095||Ol==88096||Ol==88340||Ol==89119||Ol==89120||Ol==89364||Ol==90143||Ol==90144||Ol==90388||Ol==91167||Ol==91168||Ol==91412||Ol==92191||Ol==92192||Ol==92436||Ol==92703||Ol==92704||Ol==92948||Ol==93215||Ol==93216||Ol==93460||Ol==94239||Ol==94240||Ol==94484||Ol==94751||Ol==94752||Ol==94996||Ol==95263||Ol==95264||Ol==95508||Ol==97823||Ol==97824||Ol==98068||Ol==98335||Ol==98336||Ol==98580||Ol==99359||Ol==99360||Ol==99604||Ol==101407||Ol==101408||Ol==101652||Ol==101919||Ol==101920||Ol==102164||Ol==102431||Ol==102432||Ol==102676||Ol==102943||Ol==102944||Ol==103188||Ol==103455||Ol==103456||Ol==103700||Ol==103967||Ol==103968||Ol==104212||Ol==105503||Ol==105504||Ol==105748||Ol==108575||Ol==108576||Ol==108820||Ol==109087||Ol==109088||Ol==109332||Ol==110623||Ol==110624||Ol==110868||Ol==111647||Ol==111648||Ol==111892||Ol==112159||Ol==112160||Ol==112404||Ol==112671||Ol==112672||Ol==112916||Ol==113183||Ol==113184||Ol==113428||Ol==113695||Ol==113696||Ol==113940||Ol==114719||Ol==114720||Ol==114964||Ol==115231||Ol==115232||Ol==115476||Ol==115743||Ol==115744||Ol==115988||Ol==116255||Ol==116256||Ol==116500||Ol==116767||Ol==116768||Ol==117012||Ol==117279||Ol==117280||Ol==117524||Ol==119839||Ol==119840||Ol==120084||Ol==120351||Ol==120352||Ol==120596||Ol==120863||Ol==120864||Ol==121108||Ol==121375||Ol==121376||Ol==121620||Ol==122911||Ol==122912||Ol==123156||Ol==123935||Ol==123936||Ol==124180||Ol==124447||Ol==124448||Ol==124692||Ol==124959||Ol==124960||Ol==125204||Ol==127007||Ol==127008||Ol==127252||Ol==127519||Ol==127520||Ol==127764||Ol==128031||Ol==128032||Ol==128276||Ol==128543||Ol==128544||Ol==128788||Ol==129055||Ol==129056||Ol==129300||Ol==129567||Ol==129568||Ol==129812||Ol==130079||Ol==130080||Ol==130324||Ol==131103||Ol==131104||Ol==131348||Ol==131615||Ol==131616||Ol==131860||Ol==133151||Ol==133152||Ol==133396||Ol==133663||Ol==133664||Ol==133908||Ol==134175||Ol==134176||Ol==134420||Ol==134687||Ol==134688||Ol==134932||Ol==136223||Ol==136224||Ol==136468||Ol==136735||Ol==136736||Ol==136980||Ol==138271||Ol==138272||Ol==138516||Ol==140319||Ol==140320||Ol==140564||Ol==141588||Ol==142612||Ol==144660){Ol=$l(7,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Qa(),Vl(7,t,-1),Ol=-15}catch(a){try{Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Ya(),Vl(7,t,-2),Ol=-15}catch(f){try{Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),ef(),Vl(7,t,-3),Ol=-15}catch(l){try{Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Nf(),Vl(7,t,-12),Ol=-15}catch(c){Ol=-13,Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(7,t,-13)}}}}}}switch(Ol){case-2:Ya();break;case-3:ef();break;case 90198:nf();break;case 90214:sf();break;case 113284:uf();break;case 16009:case 16046:case 116910:case 119945:case 128649:ff();break;case 17560:pf();break;case 17651:vf();break;case 141562:bf();break;case 17661:Ef();break;case-12:case 16134:Nf();break;case-13:kf();break;case 53:Af();break;case-15:break;default:Qa()}}function Ka(){Wl.startNonterminal("ApplyStatement",_l),_f(),wl(53),Wl.endNonterminal("ApplyStatement",_l)}function Qa(){Df(),El(53)}function Ga(){Wl.startNonterminal("AssignStatement",_l),wl(31),Nl(255),xl(),li(),Nl(27),wl(52),Nl(267),xl(),Of(),wl(53),Wl.endNonterminal("AssignStatement",_l)}function Ya(){El(31),Nl(255),ci(),Nl(27),El(52),Nl(267),Mf(),El(53)}function Za(){Wl.startNonterminal("BlockStatement",_l),wl(276),Nl(277),xl(),Ra(),wl(282),Wl.endNonterminal("BlockStatement",_l)}function ef(){El(276),Nl(277),Ua(),El(282)}function tf(){Wl.startNonterminal("BreakStatement",_l),wl(86),Nl(59),wl(176),Nl(28),wl(53),Wl.endNonterminal("BreakStatement",_l)}function nf(){El(86),Nl(59),El(176),Nl(28),El(53)}function rf(){Wl.startNonterminal("ContinueStatement",_l),wl(102),Nl(59),wl(176),Nl(28),wl(53),Wl.endNonterminal("ContinueStatement",_l)}function sf(){El(102),Nl(59),El(176),Nl(28),El(53)}function of(){Wl.startNonterminal("ExitStatement",_l),wl(132),Nl(71),wl(221),Nl(267),xl(),Of(),wl(53),Wl.endNonterminal("ExitStatement",_l)}function uf(){El(132),Nl(71),El(221),Nl(267),Mf(),El(53)}function af(){Wl.startNonterminal("FLWORStatement",_l),tt();for(;;){Nl(173);if(Dl==220)break;xl(),rt()}xl(),lf(),Wl.endNonterminal("FLWORStatement",_l)}function ff(){nt();for(;;){Nl(173);if(Dl==220)break;it()}cf()}function lf(){Wl.startNonterminal("ReturnStatement",_l),wl(220),Nl(270),xl(),$a(),Wl.endNonterminal("ReturnStatement",_l)}function cf(){El(220),Nl(270),Ja()}function hf(){Wl.startNonterminal("IfStatement",_l),wl(152),Nl(22),wl(34),Nl(267),xl(),G(),wl(37),Nl(77),wl(245),Nl(270),xl(),$a(),Nl(48),wl(122),Nl(270),xl(),$a(),Wl.endNonterminal("IfStatement",_l)}function pf(){El(152),Nl(22),El(34),Nl(267),Y(),El(37),Nl(77),El(245),Nl(270),Ja(),Nl(48),El(122),Nl(270),Ja()}function df(){Wl.startNonterminal("SwitchStatement",_l),wl(243),Nl(22),wl(34),Nl(267),xl(),G(),wl(37);for(;;){Nl(35),xl(),mf(),Nl(113);if(Dl!=88)break}wl(109),Nl(70),wl(220),Nl(270),xl(),$a(),Wl.endNonterminal("SwitchStatement",_l)}function vf(){El(243),Nl(22),El(34),Nl(267),Y(),El(37);for(;;){Nl(35),gf(),Nl(113);if(Dl!=88)break}El(109),Nl(70),El(220),Nl(270),Ja()}function mf(){Wl.startNonterminal("SwitchCaseStatement",_l);for(;;){wl(88),Nl(267),xl(),hn();if(Dl!=88)break}wl(220),Nl(270),xl(),$a(),Wl.endNonterminal("SwitchCaseStatement",_l)}function gf(){for(;;){El(88),Nl(267),pn();if(Dl!=88)break}El(220),Nl(270),Ja()}function yf(){Wl.startNonterminal("TryCatchStatement",_l),wl(250),Nl(87),xl(),Za();for(;;){Nl(36),wl(91),Nl(257),xl(),On(),xl(),Za(),Nl(278);switch(Dl){case 91:Cl(279);break;default:Ol=Dl}if(Ol==38491||Ol==45659||Ol==46171||Ol==60507||Ol==65627||Ol==67163||Ol==74843||Ol==76891||Ol==77403||Ol==82011||Ol==83035||Ol==84059||Ol==88155||Ol==91227||Ol==92251||Ol==95323||Ol==102491||Ol==127067||Ol==127579||Ol==130139){Ol=$l(8,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Nl(36),El(91),Nl(257),Mn(),ef(),Ol=-1}catch(a){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(8,_l,Ol)}}if(Ol!=-1&&Ol!=2651&&Ol!=3163&&Ol!=35931&&Ol!=36955&&Ol!=37467&&Ol!=37979&&Ol!=39515&&Ol!=40027&&Ol!=40539&&Ol!=41051&&Ol!=41563&&Ol!=42075&&Ol!=42587&&Ol!=43099&&Ol!=43611&&Ol!=44123&&Ol!=45147&&Ol!=46683&&Ol!=47707&&Ol!=48219&&Ol!=49243&&Ol!=49755&&Ol!=50267&&Ol!=51803&&Ol!=52315&&Ol!=52827&&Ol!=53339&&Ol!=53851&&Ol!=54363&&Ol!=55387&&Ol!=55899&&Ol!=56411&&Ol!=56923&&Ol!=57435&&Ol!=57947&&Ol!=61019&&Ol!=61531&&Ol!=62043&&Ol!=62555&&Ol!=63067&&Ol!=63579&&Ol!=64091&&Ol!=64603&&Ol!=66139&&Ol!=67675&&Ol!=68187&&Ol!=68699&&Ol!=69211&&Ol!=69723&&Ol!=70235&&Ol!=72283&&Ol!=74331&&Ol!=75867&&Ol!=77915&&Ol!=78427&&Ol!=78939&&Ol!=79451&&Ol!=81499&&Ol!=82523&&Ol!=83547&&Ol!=84571&&Ol!=85083&&Ol!=85595&&Ol!=87131&&Ol!=87643&&Ol!=89179&&Ol!=90203&&Ol!=92763&&Ol!=93275&&Ol!=94299&&Ol!=94811&&Ol!=97883&&Ol!=98395&&Ol!=99419&&Ol!=101467&&Ol!=101979&&Ol!=103003&&Ol!=103515&&Ol!=104027&&Ol!=105563&&Ol!=108635&&Ol!=109147&&Ol!=110683&&Ol!=111707&&Ol!=112219&&Ol!=112731&&Ol!=113243&&Ol!=113755&&Ol!=114779&&Ol!=115291&&Ol!=115803&&Ol!=116315&&Ol!=116827&&Ol!=117339&&Ol!=119899&&Ol!=120411&&Ol!=120923&&Ol!=121435&&Ol!=122971&&Ol!=123995&&Ol!=124507&&Ol!=125019&&Ol!=128091&&Ol!=128603&&Ol!=129115&&Ol!=129627&&Ol!=131163&&Ol!=131675&&Ol!=133211&&Ol!=133723&&Ol!=134235&&Ol!=134747&&Ol!=136283&&Ol!=136795&&Ol!=138331&&Ol!=140379)break}Wl.endNonterminal("TryCatchStatement",_l)}function bf(){El(250),Nl(87),ef(),Nl(36),El(91),Nl(257),Mn(),ef();for(;;){Nl(278);switch(Dl){case 91:Cl(279);break;default:Ol=Dl}if(Ol==38491||Ol==45659||Ol==46171||Ol==60507||Ol==65627||Ol==67163||Ol==74843||Ol==76891||Ol==77403||Ol==82011||Ol==83035||Ol==84059||Ol==88155||Ol==91227||Ol==92251||Ol==95323||Ol==102491||Ol==127067||Ol==127579||Ol==130139){Ol=$l(8,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Nl(36),El(91),Nl(257),Mn(),ef(),Vl(8,t,-1);continue}catch(a){Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(8,t,-2);break}}}if(Ol!=-1&&Ol!=2651&&Ol!=3163&&Ol!=35931&&Ol!=36955&&Ol!=37467&&Ol!=37979&&Ol!=39515&&Ol!=40027&&Ol!=40539&&Ol!=41051&&Ol!=41563&&Ol!=42075&&Ol!=42587&&Ol!=43099&&Ol!=43611&&Ol!=44123&&Ol!=45147&&Ol!=46683&&Ol!=47707&&Ol!=48219&&Ol!=49243&&Ol!=49755&&Ol!=50267&&Ol!=51803&&Ol!=52315&&Ol!=52827&&Ol!=53339&&Ol!=53851&&Ol!=54363&&Ol!=55387&&Ol!=55899&&Ol!=56411&&Ol!=56923&&Ol!=57435&&Ol!=57947&&Ol!=61019&&Ol!=61531&&Ol!=62043&&Ol!=62555&&Ol!=63067&&Ol!=63579&&Ol!=64091&&Ol!=64603&&Ol!=66139&&Ol!=67675&&Ol!=68187&&Ol!=68699&&Ol!=69211&&Ol!=69723&&Ol!=70235&&Ol!=72283&&Ol!=74331&&Ol!=75867&&Ol!=77915&&Ol!=78427&&Ol!=78939&&Ol!=79451&&Ol!=81499&&Ol!=82523&&Ol!=83547&&Ol!=84571&&Ol!=85083&&Ol!=85595&&Ol!=87131&&Ol!=87643&&Ol!=89179&&Ol!=90203&&Ol!=92763&&Ol!=93275&&Ol!=94299&&Ol!=94811&&Ol!=97883&&Ol!=98395&&Ol!=99419&&Ol!=101467&&Ol!=101979&&Ol!=103003&&Ol!=103515&&Ol!=104027&&Ol!=105563&&Ol!=108635&&Ol!=109147&&Ol!=110683&&Ol!=111707&&Ol!=112219&&Ol!=112731&&Ol!=113243&&Ol!=113755&&Ol!=114779&&Ol!=115291&&Ol!=115803&&Ol!=116315&&Ol!=116827&&Ol!=117339&&Ol!=119899&&Ol!=120411&&Ol!=120923&&Ol!=121435&&Ol!=122971&&Ol!=123995&&Ol!=124507&&Ol!=125019&&Ol!=128091&&Ol!=128603&&Ol!=129115&&Ol!=129627&&Ol!=131163&&Ol!=131675&&Ol!=133211&&Ol!=133723&&Ol!=134235&&Ol!=134747&&Ol!=136283&&Ol!=136795&&Ol!=138331&&Ol!=140379)break;Nl(36),El(91),Nl(257),Mn(),ef()}}function wf(){Wl.startNonterminal("TypeswitchStatement",_l),wl(253),Nl(22),wl(34),Nl(267),xl(),G(),wl(37);for(;;){Nl(35),xl(),Sf(),Nl(113);if(Dl!=88)break}wl(109),Nl(95),Dl==31&&(wl(31),Nl(255),xl(),li()),Nl(70),wl(220),Nl(270),xl(),$a(),Wl.endNonterminal("TypeswitchStatement",_l)}function Ef(){El(253),Nl(22),El(34),Nl(267),Y(),El(37);for(;;){Nl(35),xf(),Nl(113);if(Dl!=88)break}El(109),Nl(95),Dl==31&&(El(31),Nl(255),ci()),Nl(70),El(220),Nl(270),Ja()}function Sf(){Wl.startNonterminal("CaseStatement",_l),wl(88),Nl(262),Dl==31&&(wl(31),Nl(255),xl(),li(),Nl(30),wl(79)),Nl(260),xl(),ds(),Nl(70),wl(220),Nl(270),xl(),$a(),Wl.endNonterminal("CaseStatement",_l)}function xf(){El(88),Nl(262),Dl==31&&(El(31),Nl(255),ci(),Nl(30),El(79)),Nl(260),vs(),Nl(70),El(220),Nl(270),Ja()}function Tf(){Wl.startNonterminal("VarDeclStatement",_l);for(;;){Nl(98);if(Dl!=32)break;xl(),B()}wl(262),Nl(21),wl(31),Nl(255),xl(),li(),Nl(157),Dl==79&&(xl(),hs()),Nl(145),Dl==52&&(wl(52),Nl(267),xl(),Of());for(;;){if(Dl!=41)break;wl(41),Nl(21),wl(31),Nl(255),xl(),li(),Nl(157),Dl==79&&(xl(),hs()),Nl(145),Dl==52&&(wl(52),Nl(267),xl(),Of())}wl(53),Wl.endNonterminal("VarDeclStatement",_l)}function Nf(){for(;;){Nl(98);if(Dl!=32)break;j()}El(262),Nl(21),El(31),Nl(255),ci(),Nl(157),Dl==79&&ps(),Nl(145),Dl==52&&(El(52),Nl(267),Mf());for(;;){if(Dl!=41)break;El(41),Nl(21),El(31),Nl(255),ci(),Nl(157),Dl==79&&ps(),Nl(145),Dl==52&&(El(52),Nl(267),Mf())}El(53)}function Cf(){Wl.startNonterminal("WhileStatement",_l),wl(267),Nl(22),wl(34),Nl(267),xl(),G(),wl(37),Nl(270),xl(),$a(),Wl.endNonterminal("WhileStatement",_l)}function kf(){El(267),Nl(22),El(34),Nl(267),Y(),El(37),Nl(270),Ja()}function Lf(){Wl.startNonterminal("VoidStatement",_l),wl(53),Wl.endNonterminal("VoidStatement",_l)}function Af(){El(53)}function Of(){Wl.startNonterminal("ExprSingle",_l);switch(Dl){case 137:Cl(236);break;case 174:Cl(233);break;case 250:Cl(232);break;case 152:case 243:case 253:Cl(229);break;default:Ol=Dl}switch(Ol){case 16009:case 16046:case 116910:case 119945:case 128649:Z();break;case 17560:wn();break;case 17651:an();break;case 141562:Sn();break;case 17661:dn();break;default:_f()}Wl.endNonterminal("ExprSingle",_l)}function Mf(){switch(Dl){case 137:Cl(236);break;case 174:Cl(233);break;case 250:Cl(232);break;case 152:case 243:case 253:Cl(229);break;default:Ol=Dl}switch(Ol){case 16009:case 16046:case 116910:case 119945:case 128649:et();break;case 17560:En();break;case 17651:fn();break;case 141562:xn();break;case 17661:vn();break;default:Df()}}function _f(){Wl.startNonterminal("ExprSimple",_l);switch(Dl){case 77:Cl(231);break;case 218:Cl(234);break;case 219:Cl(235);break;case 110:case 159:Cl(237);break;case 103:case 129:case 235:Cl(230);break;default:Ol=Dl}if(Ol==133851){Ol=$l(9,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Do(),Ol=-6}catch(a){Ol=-11}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(9,_l,Ol)}}switch(Ol){case 16001:case 16107:on();break;case 97951:case 98463:Lo();break;case 97902:case 98414:Oo();break;case 98010:Po();break;case-6:case 98011:_o();break;case 15975:Uo();break;case 85102:Pf();break;case 85151:Bf();break;case 85210:Ff();break;case-11:qf();break;case 85069:Uf();break;default:_n()}Wl.endNonterminal("ExprSimple",_l)}function Df(){switch(Dl){case 77:Cl(231);break;case 218:Cl(234);break;case 219:Cl(235);break;case 110:case 159:Cl(237);break;case 103:case 129:case 235:Cl(230);break;default:Ol=Dl}if(Ol==133851){Ol=$l(9,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{Do(),Vl(9,t,-6),Ol=-13}catch(a){Ol=-11,Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(9,t,-11)}}}switch(Ol){case 16001:case 16107:un();break;case 97951:case 98463:Ao();break;case 97902:case 98414:Mo();break;case 98010:Ho();break;case-6:case 98011:Do();break;case 15975:zo();break;case 85102:Hf();break;case 85151:jf();break;case 85210:If();break;case-11:Rf();break;case 85069:zf();break;case-13:break;default:Dn()}}function Pf(){Wl.startNonterminal("JSONDeleteExpr",_l),wl(110),Nl(56),wl(166),Nl(264),xl(),Qr(),Wl.endNonterminal("JSONDeleteExpr",_l)}function Hf(){El(110),Nl(56),El(166),Nl(264),Gr()}function Bf(){Wl.startNonterminal("JSONInsertExpr",_l);switch(Dl){case 159:Cl(56);break;default:Ol=Dl}Ol=$l(10,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{El(159),Nl(56),El(166),Nl(267),Mf(),El(163),Nl(267),Mf();switch(Dl){case 81:Cl(69);break;default:Ol=Dl}if(Ol==108113){Ol=$l(11,_l);if(Ol==0){var a=Ml,f=_l,l=Dl,c=Pl,h=Hl,p=Bl,d=jl,v=Fl;try{El(81),Nl(69),El(211),Nl(267),Mf(),Vl(11,f,-1)}catch(m){Ml=a,_l=f,Dl=l,Dl==0?Gl=f:(Pl=c,Hl=h,Bl=p,Bl==0?Gl=h:(jl=d,Fl=v,Gl=v)),Vl(11,f,-2)}Ol=-2}}Ol==-1&&(El(81),Nl(69),El(211),Nl(267),Mf()),Ol=-1}catch(g){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(10,_l,Ol)}switch(Ol){case-1:wl(159),Nl(56),wl(166),Nl(267),xl(),Of(),wl(163),Nl(267),xl(),Of();switch(Dl){case 81:Cl(69);break;default:Ol=Dl}if(Ol==108113){Ol=$l(11,_l);if(Ol==0){var a=Ml,f=_l,l=Dl,c=Pl,h=Hl,p=Bl,d=jl,v=Fl;try{El(81),Nl(69),El(211),Nl(267),Mf(),Ol=-1}catch(m){Ol=-2}Ml=a,_l=f,Dl=l,Dl==0?Gl=f:(Pl=c,Hl=h,Bl=p,Bl==0?Gl=h:(jl=d,Fl=v,Gl=v)),Vl(11,_l,Ol)}}Ol==-1&&(wl(81),Nl(69),wl(211),Nl(267),xl(),Of());break;default:wl(159),Nl(56),wl(166),Nl(267),xl(),ll(),wl(163),Nl(267),xl(),Of()}Wl.endNonterminal("JSONInsertExpr",_l)}function jf(){switch(Dl){case 159:Cl(56);break;default:Ol=Dl}Ol=$l(10,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{El(159),Nl(56),El(166),Nl(267),Mf(),El(163),Nl(267),Mf();switch(Dl){case 81:Cl(69);break;default:Ol=Dl}if(Ol==108113){Ol=$l(11,_l);if(Ol==0){var a=Ml,f=_l,l=Dl,c=Pl,h=Hl,p=Bl,d=jl,v=Fl;try{El(81),Nl(69),El(211),Nl(267),Mf(),Vl(11,f,-1)}catch(m){Ml=a,_l=f,Dl=l,Dl==0?Gl=f:(Pl=c,Hl=h,Bl=p,Bl==0?Gl=h:(jl=d,Fl=v,Gl=v)),Vl(11,f,-2)}Ol=-2}}Ol==-1&&(El(81),Nl(69),El(211),Nl(267),Mf()),Vl(10,t,-1),Ol=-3}catch(g){Ol=-2,Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(10,t,-2)}}switch(Ol){case-1:El(159),Nl(56),El(166),Nl(267),Mf(),El(163),Nl(267),Mf();switch(Dl){case 81:Cl(69);break;default:Ol=Dl}if(Ol==108113){Ol=$l(11,_l);if(Ol==0){var a=Ml,f=_l,l=Dl,c=Pl,h=Hl,p=Bl,d=jl,v=Fl;try{El(81),Nl(69),El(211),Nl(267),Mf(),Vl(11,f,-1)}catch(m){Ml=a,_l=f,Dl=l,Dl==0?Gl=f:(Pl=c,Hl=h,Bl=p,Bl==0?Gl=h:(jl=d,Fl=v,Gl=v)),Vl(11,f,-2)}Ol=-2}}Ol==-1&&(El(81),Nl(69),El(211),Nl(267),Mf());break;case-3:break;default:El(159),Nl(56),El(166),Nl(267),cl(),El(163),Nl(267),Mf()}}function Ff(){Wl.startNonterminal("JSONRenameExpr",_l),wl(218),Nl(56),wl(166),Nl(264),xl(),Qr(),wl(79),Nl(267),xl(),Of(),Wl.endNonterminal("JSONRenameExpr",_l)}function If(){El(218),Nl(56),El(166),Nl(264),Gr(),El(79),Nl(267),Mf()}function qf(){Wl.startNonterminal("JSONReplaceExpr",_l),wl(219),Nl(82),wl(261),Nl(64),wl(196),Nl(56),wl(166),Nl(264),xl(),Qr(),wl(270),Nl(267),xl(),Of(),Wl.endNonterminal("JSONReplaceExpr",_l)}function Rf(){El(219),Nl(82),El(261),Nl(64),El(196),Nl(56),El(166),Nl(264),Gr(),El(270),Nl(267),Mf()}function Uf(){Wl.startNonterminal("JSONAppendExpr",_l),wl(77),Nl(56),wl(166),Nl(267),xl(),Of(),wl(163),Nl(267),xl(),Of(),Wl.endNonterminal("JSONAppendExpr",_l)}function zf(){El(77),Nl(56),El(166),Nl(267),Mf(),El(163),Nl(267),Mf()}function Wf(){Wl.startNonterminal("CommonContent",_l);switch(Dl){case 12:wl(12);break;case 23:wl(23);break;case 277:wl(277);break;case 283:wl(283);break;default:ml()}Wl.endNonterminal("CommonContent",_l)}function Xf(){switch(Dl){case 12:El(12);break;case 23:El(23);break;case 277:El(277);break;case 283:El(283);break;default:gl()}}function Vf(){Wl.startNonterminal("ContentExpr",_l),za(),Wl.endNonterminal("ContentExpr",_l)}function $f(){Wa()}function Jf(){Wl.startNonterminal("CompDocConstructor",_l),wl(119),Nl(87),xl(),ml(),Wl.endNonterminal("CompDocConstructor",_l)}function Kf(){El(119),Nl(87),gl()}function Qf(){Wl.startNonterminal("CompAttrConstructor",_l),wl(82),Nl(258);switch(Dl){case 276:wl(276),Nl(267),xl(),G(),wl(282);break;default:xl(),Da()}Nl(87);switch(Dl){case 276:Cl(277);break;default:Ol=Dl}if(Ol==144660){Ol=$l(12,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{El(276),Nl(88),El(282),Ol=-1}catch(a){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(12,_l,Ol)}}switch(Ol){case-1:wl(276),Nl(88),wl(282);break;default:xl(),ml()}Wl.endNonterminal("CompAttrConstructor",_l)}function Gf(){El(82),Nl(258);switch(Dl){case 276:El(276),Nl(267),Y(),El(282);break;default:Pa()}Nl(87);switch(Dl){case 276:Cl(277);break;default:Ol=Dl}if(Ol==144660){Ol=$l(12,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{El(276),Nl(88),El(282),Vl(12,t,-1),Ol=-3}catch(a){Ol=-2,Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(12,t,-2)}}}switch(Ol){case-1:El(276),Nl(88),El(282);break;case-3:break;default:gl()}}function Yf(){Wl.startNonterminal("CompPIConstructor",_l),wl(216),Nl(251);switch(Dl){case 276:wl(276),Nl(267),xl(),G(),wl(282);break;default:xl(),ja()}Nl(87);switch(Dl){case 276:Cl(277);break;default:Ol=Dl}if(Ol==144660){Ol=$l(13,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{El(276),Nl(88),El(282),Ol=-1}catch(a){Ol=-2}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(13,_l,Ol)}}switch(Ol){case-1:wl(276),Nl(88),wl(282);break;default:xl(),ml()}Wl.endNonterminal("CompPIConstructor",_l)}function Zf(){El(216),Nl(251);switch(Dl){case 276:El(276),Nl(267),Y(),El(282);break;default:Fa()}Nl(87);switch(Dl){case 276:Cl(277);break;default:Ol=Dl}if(Ol==144660){Ol=$l(13,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{El(276),Nl(88),El(282),Vl(13,t,-1),Ol=-3}catch(a){Ol=-2,Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(13,t,-2)}}}switch(Ol){case-1:El(276),Nl(88),El(282);break;case-3:break;default:gl()}}function el(){Wl.startNonterminal("CompCommentConstructor",_l),wl(96),Nl(87),xl(),ml(),Wl.endNonterminal("CompCommentConstructor",_l)}function tl(){El(96),Nl(87),gl()}function nl(){Wl.startNonterminal("CompTextConstructor",_l),wl(244),Nl(87),xl(),ml(),Wl.endNonterminal("CompTextConstructor",_l)}function rl(){El(244),Nl(87),gl()}function il(){Wl.startNonterminal("PrimaryExpr",_l);switch(Dl){case 184:Cl(256);break;case 216:Cl(254);break;case 276:Cl(277);break;case 82:case 121:Cl(259);break;case 96:case 244:Cl(93);break;case 119:case 202:case 256:Cl(139);break;case 6:case 70:case 72:case 73:case 74:case 75:case 77:case 79:case 80:case 81:case 83:case 84:case 85:case 86:case 88:case 89:case 90:case 91:case 93:case 94:case 97:case 98:case 101:case 102:case 103:case 104:case 105:case 106:case 108:case 109:case 110:case 111:case 112:case 113:case 118:case 122:case 123:case 125:case 126:case 128:case 129:case 131:case 132:case 133:case 134:case 135:case 136:case 137:case 141:case 146:case 148:case 150:case 151:case 153:case 154:case 155:case 159:case 160:case 161:case 162:case 163:case 164:case 166:case 170:case 171:case 172:case 174:case 176:case 178:case 180:case 181:case 182:case 186:case 192:case 194:case 198:case 199:case 200:case 201:case 203:case 206:case 212:case 213:case 218:case 219:case 220:case 221:case 222:case 224:case 225:case 228:case 229:case 234:case 235:case 236:case 237:case 240:case 248:case 249:case 250:case 251:case 252:case 254:case 257:case 260:case 261:case 262:case 263:case 266:case 267:case 270:case 274:Cl(92);break;default:Ol=Dl}if(Ol==2836||Ol==3348||Ol==4372||Ol==4884||Ol==5396||Ol==5908||Ol==16148||Ol==16660||Ol==17684||Ol==18196||Ol==20756||Ol==21780||Ol==22804||Ol==23316||Ol==23828||Ol==24340||Ol==27924||Ol==28436||Ol==30484||Ol==34068||Ol==35092||Ol==36116||Ol==37140||Ol==37652||Ol==38164||Ol==38676||Ol==39700||Ol==40212||Ol==40724||Ol==41236||Ol==41748||Ol==42260||Ol==42772||Ol==43284||Ol==43796||Ol==44308||Ol==45332||Ol==45844||Ol==46356||Ol==46868||Ol==47892||Ol==48404||Ol==49428||Ol==49940||Ol==50452||Ol==51988||Ol==52500||Ol==53012||Ol==53524||Ol==54036||Ol==54548||Ol==55572||Ol==56084||Ol==56596||Ol==57108||Ol==57620||Ol==58132||Ol==60692||Ol==61204||Ol==61716||Ol==62228||Ol==62740||Ol==63252||Ol==63764||Ol==64276||Ol==64788||Ol==65812||Ol==66324||Ol==67348||Ol==67860||Ol==68372||Ol==68884||Ol==69396||Ol==69908||Ol==70420||Ol==72468||Ol==74516||Ol==75028||Ol==76052||Ol==77076||Ol==77588||Ol==78100||Ol==78612||Ol==79124||Ol==79636||Ol==81684||Ol==82196||Ol==82708||Ol==83220||Ol==83732||Ol==84244||Ol==84756||Ol==85268||Ol==85780||Ol==87316||Ol==87828||Ol==88340||Ol==89364||Ol==90388||Ol==91412||Ol==92436||Ol==92948||Ol==93460||Ol==94484||Ol==94996||Ol==95508||Ol==98068||Ol==98580||Ol==99604||Ol==101652||Ol==102164||Ol==102676||Ol==103188||Ol==103700||Ol==104212||Ol==105748||Ol==108820||Ol==109332||Ol==110868||Ol==111892||Ol==112404||Ol==112916||Ol==113428||Ol==113940||Ol==114964||Ol==115476||Ol==115988||Ol==116500||Ol==117012||Ol==117524||Ol==120084||Ol==120596||Ol==121108||Ol==121620||Ol==123156||Ol==124180||Ol==124692||Ol==125204||Ol==127252||Ol==127764||Ol==128276||Ol==128788||Ol==129300||Ol==129812||Ol==130324||Ol==131348||Ol==131860||Ol==133396||Ol==133908||Ol==134420||Ol==134932||Ol==136468||Ol==136980||Ol==138516||Ol==140564||Ol==141588||Ol==142612||Ol==144660){Ol=$l(14,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{gl(),Ol=-10}catch(a){Ol=-11}Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(14,_l,Ol)}}switch(Ol){case 8:case 9:case 10:case 11:ii();break;case 31:ai();break;case 34:hi();break;case 44:di();break;case 17414:case 17478:case 17480:case 17481:case 17482:case 17483:case 17485:case 17487:case 17488:case 17489:case 17491:case 17492:case 17493:case 17494:case 17496:case 17497:case 17498:case 17499:case 17501:case 17502:case 17505:case 17506:case 17509:case 17510:case 17511:case 17512:case 17513:case 17514:case 17516:case 17517:case 17518:case 17519:case 17520:case 17521:case 17526:case 17527:case 17530:case 17531:case 17533:case 17534:case 17536:case 17537:case 17539:case 17540:case 17541:case 17542:case 17543:case 17544:case 17545:case 17549:case 17554:case 17556:case 17558:case 17559:case 17561:case 17562:case 17563:case 17567:case 17568:case 17569:case 17570:case 17571:case 17572:case 17574:case 17578:case 17579:case 17580:case 17582:case 17584:case 17586:case 17588:case 17589:case 17590:case 17592:case 17594:case 17600:case 17602:case 17606:case 17607:case 17608:case 17609:case 17610:case 17611:case 17614:case 17620:case 17621:case 17626:case 17627:case 17628:case 17629:case 17630:case 17632:case 17633:case 17636:case 17637:case 17642:case 17643:case 17644:case 17645:case 17648:case 17656:case 17657:case 17658:case 17659:case 17660:case 17662:case 17664:case 17665:case 17668:case 17669:case 17670:case 17671:case 17674:case 17675:case 17678:case 17682:wi();break;case 141514:mi();break;case 141568:yi();break;case 32:case 78:case 120:case 124:case 145:case 152:case 165:case 167:case 185:case 191:case 226:case 227:case 242:case 243:case 253:case 14854:case 14918:case 14920:case 14921:case 14922:case 14923:case 14925:case 14927:case 14928:case 14929:case 14930:case 14931:case 14932:case 14933:case 14934:case 14936:case 14937:case 14938:case 14939:case 14941:case 14942:case 14944:case 14945:case 14946:case 14949:case 14950:case 14951:case 14952:case 14953:case 14954:case 14956:case 14957:case 14958:case 14959:case 14960:case 14961:case 14966:case 14967:case 14969:case 14970:case 14971:case 14973:case 14974:case 14976:case 14977:case 14979:case 14980:case 14981:case 14982:case 14983:case 14984:case 14985:case 14989:case 14994:case 14996:case 14998:case 14999:case 15001:case 15002:case 15003:case 15007:case 15008:case 15009:case 15010:case 15011:case 15012:case 15014:case 15018:case 15019:case 15020:case 15022:case 15024:case 15026:case 15028:case 15029:case 15030:case 15032:case 15034:case 15040:case 15042:case 15046:case 15047:case 15048:case 15049:case 15050:case 15051:case 15054:case 15060:case 15061:case 15064:case 15066:case 15067:case 15068:case 15069:case 15070:case 15072:case 15073:case 15076:case 15077:case 15082:case 15083:case 15084:case 15085:case 15088:case 15092:case 15096:case 15097:case 15098:case 15099:case 15100:case 15102:case 15104:case 15105:case 15108:case 15109:case 15110:case 15111:case 15114:case 15115:case 15118:case 15122:is();break;case-10:case 27412:ml();break;case-11:al();break;case 68:dl();break;case 278:ol();break;default:Ci()}Wl.endNonterminal("PrimaryExpr",_l)}function sl(){switch(Dl){case 184:Cl(256);break;case 216:Cl(254);break;case 276:Cl(277);break;case 82:case 121:Cl(259);break;case 96:case 244:Cl(93);break;case 119:case 202:case 256:Cl(139);break;case 6:case 70:case 72:case 73:case 74:case 75:case 77:case 79:case 80:case 81:case 83:case 84:case 85:case 86:case 88:case 89:case 90:case 91:case 93:case 94:case 97:case 98:case 101:case 102:case 103:case 104:case 105:case 106:case 108:case 109:case 110:case 111:case 112:case 113:case 118:case 122:case 123:case 125:case 126:case 128:case 129:case 131:case 132:case 133:case 134:case 135:case 136:case 137:case 141:case 146:case 148:case 150:case 151:case 153:case 154:case 155:case 159:case 160:case 161:case 162:case 163:case 164:case 166:case 170:case 171:case 172:case 174:case 176:case 178:case 180:case 181:case 182:case 186:case 192:case 194:case 198:case 199:case 200:case 201:case 203:case 206:case 212:case 213:case 218:case 219:case 220:case 221:case 222:case 224:case 225:case 228:case 229:case 234:case 235:case 236:case 237:case 240:case 248:case 249:case 250:case 251:case 252:case 254:case 257:case 260:case 261:case 262:case 263:case 266:case 267:case 270:case 274:Cl(92);break;default:Ol=Dl}if(Ol==2836||Ol==3348||Ol==4372||Ol==4884||Ol==5396||Ol==5908||Ol==16148||Ol==16660||Ol==17684||Ol==18196||Ol==20756||Ol==21780||Ol==22804||Ol==23316||Ol==23828||Ol==24340||Ol==27924||Ol==28436||Ol==30484||Ol==34068||Ol==35092||Ol==36116||Ol==37140||Ol==37652||Ol==38164||Ol==38676||Ol==39700||Ol==40212||Ol==40724||Ol==41236||Ol==41748||Ol==42260||Ol==42772||Ol==43284||Ol==43796||Ol==44308||Ol==45332||Ol==45844||Ol==46356||Ol==46868||Ol==47892||Ol==48404||Ol==49428||Ol==49940||Ol==50452||Ol==51988||Ol==52500||Ol==53012||Ol==53524||Ol==54036||Ol==54548||Ol==55572||Ol==56084||Ol==56596||Ol==57108||Ol==57620||Ol==58132||Ol==60692||Ol==61204||Ol==61716||Ol==62228||Ol==62740||Ol==63252||Ol==63764||Ol==64276||Ol==64788||Ol==65812||Ol==66324||Ol==67348||Ol==67860||Ol==68372||Ol==68884||Ol==69396||Ol==69908||Ol==70420||Ol==72468||Ol==74516||Ol==75028||Ol==76052||Ol==77076||Ol==77588||Ol==78100||Ol==78612||Ol==79124||Ol==79636||Ol==81684||Ol==82196||Ol==82708||Ol==83220||Ol==83732||Ol==84244||Ol==84756||Ol==85268||Ol==85780||Ol==87316||Ol==87828||Ol==88340||Ol==89364||Ol==90388||Ol==91412||Ol==92436||Ol==92948||Ol==93460||Ol==94484||Ol==94996||Ol==95508||Ol==98068||Ol==98580||Ol==99604||Ol==101652||Ol==102164||Ol==102676||Ol==103188||Ol==103700||Ol==104212||Ol==105748||Ol==108820||Ol==109332||Ol==110868||Ol==111892||Ol==112404||Ol==112916||Ol==113428||Ol==113940||Ol==114964||Ol==115476||Ol==115988||Ol==116500||Ol==117012||Ol==117524||Ol==120084||Ol==120596||Ol==121108||Ol==121620||Ol==123156||Ol==124180||Ol==124692||Ol==125204||Ol==127252||Ol==127764||Ol==128276||Ol==128788||Ol==129300||Ol==129812||Ol==130324||Ol==131348||Ol==131860||Ol==133396||Ol==133908||Ol==134420||Ol==134932||Ol==136468||Ol==136980||Ol==138516||Ol==140564||Ol==141588||Ol==142612||Ol==144660){Ol=$l(14,_l);if(Ol==0){var e=Ml,t=_l,n=Dl,r=Pl,i=Hl,s=Bl,o=jl,u=Fl;try{gl(),Vl(14,t,-10),Ol=-14}catch(a){Ol=-11,Ml=e,_l=t,Dl=n,Dl==0?Gl=t:(Pl=r,Hl=i,Bl=s,Bl==0?Gl=i:(jl=o,Fl=u,Gl=u)),Vl(14,t,-11)}}}switch(Ol){case 8:case 9:case 10:case 11:si();break;case 31:fi();break;case 34:pi();break;case 44:vi();break;case 17414:case 17478:case 17480:case 17481:case 17482:case 17483:case 17485:case 17487:case 17488:case 17489:case 17491:case 17492:case 17493:case 17494:case 17496:case 17497:case 17498:case 17499:case 17501:case 17502:case 17505:case 17506:case 17509:case 17510:case 17511:case 17512:case 17513:case 17514:case 17516:case 17517:case 17518:case 17519:case 17520:case 17521:case 17526:case 17527:case 17530:case 17531:case 17533:case 17534:case 17536:case 17537:case 17539:case 17540:case 17541:case 17542:case 17543:case 17544:case 17545:case 17549:case 17554:case 17556:case 17558:case 17559:case 17561:case 17562:case 17563:case 17567:case 17568:case 17569:case 17570:case 17571:case 17572:case 17574:case 17578:case 17579:case 17580:case 17582:case 17584:case 17586:case 17588:case 17589:case 17590:case 17592:case 17594:case 17600:case 17602:case 17606:case 17607:case 17608:case 17609:case 17610:case 17611:case 17614:case 17620:case 17621:case 17626:case 17627:case 17628:case 17629:case 17630:case 17632:case 17633:case 17636:case 17637:case 17642:case 17643:case 17644:case 17645:case 17648:case 17656:case 17657:case 17658:case 17659:case 17660:case 17662:case 17664:case 17665:case 17668:case 17669:case 17670:case 17671:case 17674:case 17675:case 17678:case 17682:Ei();break;case 141514:gi();break;case 141568:bi();break;case 32:case 78:case 120:case 124:case 145:case 152:case 165:case 167:case 185:case 191:case 226:case 227:case 242:case 243:case 253:case 14854:case 14918:case 14920:case 14921:case 14922:case 14923:case 14925:case 14927:case 14928:case 14929:case 14930:case 14931:case 14932:case 14933:case 14934:case 14936:case 14937:case 14938:case 14939:case 14941:case 14942:case 14944:case 14945:case 14946:case 14949:case 14950:case 14951:case 14952:case 14953:case 14954:case 14956:case 14957:case 14958:case 14959:case 14960:case 14961:case 14966:case 14967:case 14969:case 14970:case 14971:case 14973:case 14974:case 14976:case 14977:case 14979:case 14980:case 14981:case 14982:case 14983:case 14984:case 14985:case 14989:case 14994:case 14996:case 14998:case 14999:case 15001:case 15002:case 15003:case 15007:case 15008:case 15009:case 15010:case 15011:case 15012:case 15014:case 15018:case 15019:case 15020:case 15022:case 15024:case 15026:case 15028:case 15029:case 15030:case 15032:case 15034:case 15040:case 15042:case 15046:case 15047:case 15048:case 15049:case 15050:case 15051:case 15054:case 15060:case 15061:case 15064:case 15066:case 15067:case 15068:case 15069:case 15070:case 15072:case 15073:case 15076:case 15077:case 15082:case 15083:case 15084:case 15085:case 15088:case 15092:case 15096:case 15097:case 15098:case 15099:case 15100:case 15102:case 15104:case 15105:case 15108:case 15109:case 15110:case 15111:case 15114:case 15115:case 15118:case 15122:ss();break;case-10:case 27412:gl();break;case-11:fl();break;case 68:vl();break;case 278:ul();break;case-14:break;default:ki()}}function ol(){Wl.startNonterminal("JSONSimpleObjectUnion",_l),wl(278),Nl(273),Dl!=281&&(xl(),G()),wl(281),Wl.endNonterminal("JSONSimpleObjectUnion",_l)}function ul(){El(278),Nl(273),Dl!=281&&Y(),El(281)}function al(){Wl.startNonterminal("ObjectConstructor",_l),wl(276),Nl(274),Dl!=282&&(xl(),ll()),wl(282),Wl.endNonterminal("ObjectConstructor",_l)}function fl(){El(276),Nl(274),Dl!=282&&cl(),El(282)}function ll(){Wl.startNonterminal("PairConstructorList",_l),hl();for(;;){if(Dl!=41)break;wl(41),Nl(267),xl(),hl()}Wl.endNonterminal("PairConstructorList",_l)}function cl(){pl();for(;;){if(Dl!=41)break;El(41),Nl(267),pl()}}function hl(){Wl.startNonterminal("PairConstructor",_l),Of(),wl(49),Nl(267),xl(),Of(),Wl.endNonterminal("PairConstructor",_l)}function pl(){Mf(),El(49),Nl(267),Mf()}function dl(){Wl.startNonterminal("ArrayConstructor",_l),wl(68),Nl(272),Dl!=69&&(xl(),G()),wl(69),Wl.endNonterminal("ArrayConstructor",_l)}function vl(){El(68),Nl(272),Dl!=69&&Y(),El(69)}function ml(){Wl.startNonterminal("BlockExpr",_l),wl(276),Nl(277),xl(),Xa(),wl(282),Wl.endNonterminal("BlockExpr",_l)}function gl(){El(276),Nl(277),Va(),El(282)}function yl(){Wl.startNonterminal("FunctionDecl",_l),wl(145),Nl(255),xl(),Da(),Nl(22),wl(34),Nl(94),Dl==31&&(xl(),U()),wl(37),Nl(148),Dl==79&&(xl(),bl()),Nl(118);switch(Dl){case 276:wl(276),Nl(277),xl(),Xa(),wl(282);break;default:wl(133)}Wl.endNonterminal("FunctionDecl",_l)}function bl(){Wl.startNonterminal("ReturnType",_l),wl(79),Nl(260),xl(),ds(),Wl.endNonterminal("ReturnType",_l)}function wl(e){Dl==e?(xl(),Wl.terminal(i.TOKEN[Dl],Pl,Hl>Kl?Kl:Hl),Ml=Pl,_l=Hl,Dl=Bl,Dl!=0&&(Pl=jl,Hl=Fl,Bl=0)):Al(Pl,Hl,0,Dl,e)}function El(e){Dl==e?(Ml=Pl,_l=Hl,Dl=Bl,Dl!=0&&(Pl=jl,Hl=Fl,Bl=0)):Al(Pl,Hl,0,Dl,e)}function Sl(e){var t=Ml,n=_l,r=Dl,i=Pl,s=Hl;Dl=e,Pl=Ql,Hl=Gl,Bl=0,_a(),Ml=t,_l=n,Dl=r,Dl!=0&&(Pl=i,Hl=s)}function xl(){_l!=Pl&&(Ml=_l,_l=Pl,Wl.whitespace(Ml,_l))}function Tl(e){var t;for(;;){t=Yl(e);if(t!=22){if(t!=36)break;Sl(t)}}return t}function Nl(e){Dl==0&&(Dl=Tl(e),Pl=Ql,Hl=Gl)}function Cl(e){Bl==0&&(Bl=Tl(e),jl=Ql,Fl=Gl),Ol=Bl<<9|Dl}function kl(e){Dl==0&&(Dl=Yl(e),Pl=Ql,Hl=Gl)}function Ll(e){Bl==0&&(Bl=Yl(e),jl=Ql,Fl=Gl),Ol=Bl<<9|Dl}function Al(e,t,r,i,s){throw t>ql&&(Il=e,ql=t,Rl=r,Ul=i,zl=s),new n.ParseException(Il,ql,Rl,Ul,zl)}function Vl(e,t,n){Xl[(t<<4)+e]=n}function $l(e,t){var n=Xl[(t<<4)+e];return typeof n!="undefined"?n:0}function Yl(e){var t=!1;Ql=Gl;var n=Gl,r=i.INITIAL[e],s=0;for(var o=r&4095;o!=0;){var u,a=n<Kl?Jl.charCodeAt(n):0;++n;if(a<128)u=i.MAP0[a];else if(a<55296){var f=a>>4;u=i.MAP1[(a&15)+i.MAP1[(f&31)+i.MAP1[f>>5]]]}else{if(a<56320){var f=n<Kl?Jl.charCodeAt(n):0;f>=56320&&f<57344&&(++n,a=((a&1023)<<10)+(f&1023)+65536,t=!0)}var l=0,c=5;for(var h=3;;h=c+l>>1){if(i.MAP2[h]>a)c=h-1;else{if(!(i.MAP2[6+h]<a)){u=i.MAP2[12+h];break}l=h+1}if(l>c){u=0;break}}}s=o;var p=(u<<12)+o-1;o=i.TRANSITION[(p&15)+i.TRANSITION[p>>4]],o>4095&&(r=o,o&=4095,Gl=n)}r>>=12;if(r==0){Gl=n-1;var f=Gl<Kl?Jl.charCodeAt(Gl):0;return f>=56320&&f<57344&&--Gl,Al(Ql,Gl,s,-1,-1)}if(t)for(var d=r>>9;d>0;--d){--Gl;var f=Gl<Kl?Jl.charCodeAt(Gl):0;f>=56320&&f<57344&&--Gl}else Gl-=r>>9;return(r&511)-1}r(e,t);var n=this;this.ParseException=function(e,t,n,r,i){var s=e,o=t,u=n,a=r,f=i;this.getBegin=function(){return s},this.getEnd=function(){return o},this.getState=function(){return u},this.getExpected=function(){return f},this.getOffending=function(){return a},this.getMessage=function(){return a<0?"lexical analysis failed":"syntax error"}},this.getInput=function(){return Jl},this.getOffendingToken=function(e){var t=e.getOffending();return t>=0?i.TOKEN[t]:null},this.getExpectedTokenSet=function(e){var t;return e.getExpected()<0?t=i.getTokenSet(-e.getState()):t=[i.TOKEN[e.getExpected()]],t},this.getErrorMessage=function(e){var t=this.getExpectedTokenSet(e),n=this.getOffendingToken(e),r=Jl.substring(0,e.getBegin()),i=r.split("\n"),s=i.length,o=i[s-1].length+1,u=e.getEnd()-e.getBegin();return e.getMessage()+(n==null?"":", found "+n)+"\nwhile expecting "+(t.length==1?t[0]:"["+t.join(", ")+"]")+"\n"+(u==0||n!=null?"":"after successfully scanning "+u+" characters beginning ")+"at line "+s+", column "+o+":\n..."+Jl.substring(e.getBegin(),Math.min(Jl.length,e.getBegin()+64))+"..."},this.parse_XQuery=function(){Wl.startNonterminal("XQuery",_l),Nl(275),xl(),o(),wl(25),Wl.endNonterminal("XQuery",_l)};var Ol,Ml,_l,Dl,Pl,Hl,Bl,jl,Fl,Il,ql,Rl,Ul,zl,Wl,Xl,Jl,Kl,Ql,Gl};r.getTokenSet=function(e){var t=[],n=e<0?-e:INITIAL[e]&4095;for(var i=0;i<284;i+=32){var s=i,o=(i>>5)*3694+n-1,u=o>>1,a=u>>2,f=r.EXPECTED[(o&1)+r.EXPECTED[(u&3)+r.EXPECTED[(a&3)+r.EXPECTED[a>>2]]]];for(;f!=0;f>>>=1,++s)(f&1)!=0&&t.push(r.TOKEN[s])}return t},r.MAP0=[70,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,17,17,17,17,17,17,17,17,17,18,19,20,21,22,23,24,25,26,27,28,29,26,30,30,30,30,30,31,32,33,30,30,34,30,30,35,30,30,30,36,30,30,37,38,39,38,30,38,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,38,38],r.MAP1=[108,124,214,214,214,214,214,214,214,214,214,214,214,214,214,214,156,181,181,181,181,181,214,215,213,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,247,261,277,293,309,355,371,387,423,423,423,415,339,331,339,331,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,440,440,440,440,440,440,440,324,339,339,339,339,339,339,339,339,401,423,423,424,422,423,423,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,423,338,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,423,70,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,17,17,17,17,17,17,17,17,17,18,19,20,21,22,23,24,25,26,27,28,29,26,30,30,30,30,30,31,32,33,30,30,30,30,30,30,30,30,30,30,30,30,30,30,38,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,34,30,30,35,30,30,30,36,30,30,37,38,39,38,30,38,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,38,38,38,38,38,38,38,38,38,38,38,38,30,30,38,38,38,38,38,38,38,69,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69],r.MAP2=[57344,63744,64976,65008,65536,983040,63743,64975,65007,65533,983039,1114111,38,30,38,30,30,38],r.INITIAL=[1,12290,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287],r.TRANSITION=[42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,25651,25666,25670,25670,25670,18189,25670,25670,25670,25670,18201,25670,25670,25670,25670,18176,25670,25671,18217,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,42516,25917,18730,20976,20988,20999,21015,25420,18732,21040,42516,42516,42516,27632,42516,42516,51474,31122,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,21056,21084,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,23286,21107,42516,42516,42516,39416,42516,42516,43470,47286,25568,42516,42516,42516,42516,23672,41495,21126,21160,42516,42516,42516,27632,42516,42516,35938,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,25556,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21176,21248,42516,42516,42516,50595,42516,42516,42445,42516,25917,23619,21211,21279,21269,21226,21240,44419,21040,42516,42516,42516,27632,21302,42516,32247,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,19871,21321,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,21344,26008,18612,18632,18596,21349,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42510,42516,42516,42516,48894,42515,42516,51366,42516,21365,42504,21403,42515,21410,42516,27599,27612,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,21426,42516,42516,42516,22170,42516,42516,21445,42516,42516,21468,21481,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,42516,24484,42516,42516,42516,42516,42516,42516,42517,21497,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,21513,25598,18486,18508,51408,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,25358,21538,42516,42516,42516,29996,42516,42516,26519,46446,25383,42516,42516,42516,42516,25736,28473,18232,21557,42516,42516,42516,27632,42516,42516,51474,21573,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,19060,21591,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,23074,23089,21619,21619,21619,21672,21614,21619,21624,23096,21640,21745,21688,21665,21655,21732,21703,21716,21040,42516,42516,42516,33326,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,21761,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,45317,42516,42516,42516,49458,21798,42516,22640,21804,25917,45316,42516,21821,21844,21828,21860,21869,21885,42516,42516,42516,29550,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,21901,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,21944,42516,42516,42516,48069,42516,42516,42516,26308,36543,25445,25454,21937,25455,21960,21985,21998,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,18888,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,26329,37275,42655,22014,22031,22014,22046,42653,22015,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,22071,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,26891,42516,42516,42516,48069,22092,42516,23653,22130,40293,22116,22186,22191,22191,22207,26888,44587,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,18247,42516,42516,42516,42516,48069,42516,42516,42516,42516,25917,35843,22232,22249,22232,22264,35841,22233,22289,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,46363,42516,33841,42516,34304,43899,22305,22071,36154,42516,42516,42516,42516,28243,22657,22322,22657,22657,22341,33347,46316,46316,39789,38147,35514,38147,38147,22359,22382,42516,42516,42516,42516,42516,28815,42516,22405,22426,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,47355,26569,42516,42516,42516,42516,42516,45225,42516,42516,32981,50880,22657,22657,22657,30360,22467,39622,46316,22501,46316,22343,36422,42625,38147,22520,38147,27826,41766,42516,42516,42516,42516,42516,49148,42516,23255,22657,44467,22657,22657,30361,22539,42077,46316,46316,46316,30525,38147,40186,38147,38147,34440,41769,42516,42516,20027,37487,42516,28242,22657,22657,36250,37745,46316,46316,44329,37798,38147,38147,43834,27827,30836,42516,42516,19405,22558,38368,22576,22657,40730,22597,46316,36583,22617,38147,40469,22638,42516,25905,42516,34153,22656,33064,46073,46316,22674,22710,27827,22690,51145,42516,32408,22729,37572,22752,32120,22683,29050,30609,22771,38961,22813,36803,22874,22893,22911,28238,43147,27775,22913,22451,22736,46400,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,50215,25917,42516,42516,42516,42516,42516,45715,23059,23112,42516,42516,42516,27632,42516,42516,37325,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,23128,46363,42516,42516,42516,34304,42516,42516,18360,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,22341,46316,46316,46316,39789,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,28815,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,23154,42516,42516,42516,46371,42516,42516,42516,42516,25917,35960,23175,23206,23195,23229,35959,23179,21040,42516,42516,42516,27632,42516,42516,51474,27227,42516,43023,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,23254,42516,42516,42516,48069,42516,42516,42516,19968,25917,42516,42516,42516,42516,42516,42762,23271,23302,42516,42516,42516,27632,42516,42516,21380,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,23318,46363,42516,42516,42516,34304,42516,42516,23344,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,22341,46316,46316,46316,39789,38147,38147,38147,38147,40896,23370,23409,42516,42516,42516,42516,38331,23429,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,23450,23383,42516,42516,42516,42516,42516,23487,42516,42516,42516,38370,22657,22657,22657,22657,50700,22540,46316,46316,46316,46316,47852,30533,38147,38147,38147,38147,27826,35762,23510,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,29796,22539,46316,46316,46316,46316,23533,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,46191,46316,46316,46316,32038,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,48371,42516,42516,42516,31492,32078,42516,42516,23557,25917,18721,49121,23587,23594,23610,42516,43878,23635,23651,42516,42516,33439,23669,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,25038,24355,23991,25028,23804,18270,40105,18293,23688,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,23724,24084,23749,23789,24317,23827,23849,23904,24015,23917,23946,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,23969,24689,24310,25086,25092,23974,23990,24416,24845,24007,23833,24977,24993,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,24031,23930,24046,24073,24057,24100,24137,24664,24240,24198,24251,24225,24986,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,24267,24283,24299,24348,24333,24371,24167,24428,24402,23773,24444,24474,35639,19379,39467,19401,41728,19421,19500,24458,19544,24500,24558,24572,24588,24604,24182,24745,24620,24636,24767,19696,19712,19728,19753,19773,19830,19435,19514,24680,24514,19528,24705,24152,24757,19947,19984,20043,20080,20119,20157,20667,24542,24528,24731,24830,24209,24939,20235,20264,20301,24783,24799,24815,24715,24861,20381,20397,19814,23733,24877,24893,20503,25039,24968,23864,24927,24955,25015,20652,18443,23763,24386,25055,24651,25071,25108,25159,25175,25191,25243,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,27003,42516,42516,42516,48069,25296,42516,42516,25291,40518,25312,25320,25320,25320,25327,27168,25343,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25399,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,18963,25373,18652,18689,18711,18748,18695,25415,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,19337,25436,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,25471,25509,25525,20579,19301,19596,25541,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,25584,19614,19632,19650,25620,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,42516,21541,28730,28739,28739,28739,28746,47533,25636,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,27653,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,25687,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51268,23158,42516,42516,42516,48069,42516,42516,42516,42516,25917,22795,25710,25710,25710,25717,23159,22797,21040,25733,42516,42516,27632,42516,42516,51474,42516,42516,44769,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,25752,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,26066,26075,42516,42516,42516,42907,42516,42516,42516,42516,25917,26405,25775,25775,25775,25782,28588,26407,25798,25814,42516,42516,27632,42516,42516,51474,42516,42516,23413,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,25831,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,25857,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,25891,42516,42516,42516,42516,48069,25942,42516,42516,28970,33768,42516,42516,42516,25933,25960,26180,25944,25980,42516,42516,42516,27632,42516,42516,51474,27927,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,25996,26028,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,42516,25917,42516,42516,42516,42516,42516,41865,26051,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,23487,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,26115,26152,42516,42516,42516,42516,42516,23487,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,35762,23510,42516,42516,42516,42516,26178,42516,23255,22657,22657,22657,22657,22877,22539,46316,46316,46316,46316,32774,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,46191,46316,46316,46316,32038,38147,38147,38147,27827,22690,42516,42516,23464,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,23487,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,26115,26152,42516,42516,42516,42516,42516,23487,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,35762,23510,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,22877,22539,46316,46316,46316,46316,32774,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,46191,46316,46316,46316,32038,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,23487,26196,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,26115,26152,42516,42516,42516,42516,42516,23487,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,35762,23510,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,22877,22539,46316,46316,46316,46316,32774,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,46191,46316,46316,46316,32038,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,23487,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,26115,26152,42516,42516,42516,42516,42516,26216,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,35762,23510,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,22877,22539,46316,46316,46316,46316,32774,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,46191,46316,46316,46316,32038,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,31151,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,31154,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,23487,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,26115,26152,42516,42516,42516,42516,42516,23487,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,35762,23510,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,22877,22539,46316,46316,46316,46316,32774,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,46191,46316,46316,46316,32038,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,22786,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26258,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,48694,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,28605,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,47769,26274,26287,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,26303,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,26324,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,42516,25917,35004,26345,26373,26362,26396,35005,26346,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,37963,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,26423,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,42516,25917,42516,42516,42516,42516,42516,42516,42517,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,42516,25917,47727,42516,26460,26483,26467,42516,47735,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,26499,20264,20301,20317,20346,20333,20349,20365,26535,20397,20422,20606,20438,26551,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,29068,42516,42516,42516,51537,26585,26616,29663,26601,26633,26690,26699,26715,26730,26742,26758,26771,26099,19999,42516,26787,26162,26806,41856,26832,26883,26907,26946,30733,26962,26998,27019,27054,46783,31896,27070,46885,46348,36728,27120,42516,42516,34304,27137,37896,42516,27163,34995,39190,42516,27184,43650,22657,22657,22657,27203,27401,46316,46316,41985,48318,38147,38147,38147,37213,40896,22382,42516,27222,48046,42516,27243,27263,27280,42516,42516,27038,20763,27308,27328,22657,22657,27363,27386,27419,35266,46316,30482,27448,27495,27524,27566,38147,35889,38740,46095,27585,26152,27628,42516,45564,42516,47310,23487,42516,46936,27648,27669,27685,34339,22657,27729,22984,44673,27748,45967,46316,27773,39768,32782,27791,37607,38147,27824,22485,27843,27859,27882,27899,42516,27922,31758,27943,23255,33056,27962,22657,42185,33093,27982,30091,46316,35423,43042,32774,28017,38147,38147,42363,28033,23138,28062,40096,28115,41486,28137,21969,22956,28160,22657,46191,35558,28176,28197,32038,49740,47969,28214,27827,28233,42899,42516,21253,42516,38368,42934,43766,40730,37393,48025,36583,51021,44713,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,28260,28298,33550,28320,28341,28379,28401,28421,26921,40729,36585,44924,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,28445,42516,42516,51537,42516,42516,42516,42516,31409,28464,42516,28489,28496,28512,28528,28541,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,42942,46314,28557,30860,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,28583,23487,28604,45602,42516,42516,38368,22657,22657,22657,44648,28621,22541,46316,46316,46316,40008,44805,38147,38147,38147,38147,41449,32923,26115,26152,42516,42516,42516,42516,42516,23487,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,35762,23510,42516,32305,42516,42516,28652,43395,23255,28671,22657,22657,22657,28690,28706,46316,46316,46316,37589,32774,28762,38147,38147,38147,44356,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,46191,46316,46316,46316,32038,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,23013,26674,44310,41661,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,28784,42516,42516,51537,42516,28813,42516,28831,36313,28851,28860,28876,28891,28903,28919,28932,26099,42516,42516,33807,29427,42516,42516,28948,42516,28965,42516,42516,42516,25275,42516,28986,44283,46314,29021,22622,37863,32069,42516,29066,42516,34304,29084,49128,42516,45291,29103,36853,42516,39408,30216,37513,22657,22657,22657,29138,29162,46316,46316,48917,29187,29203,38147,38147,40896,22382,23471,42516,42516,37970,42516,41320,23487,39926,29222,42516,42516,38368,29257,38293,22657,29296,38374,29315,31567,38618,38779,46316,44805,42631,29346,29367,48610,38147,32923,26115,26152,42516,42516,35359,42516,36267,23487,42516,42516,42516,38370,22657,22657,38875,29587,30360,22540,46316,46316,49716,48753,22343,30533,38147,38147,47896,47206,27826,35762,29388,42516,42516,42516,29423,42516,29443,23255,22657,22657,22657,43545,22877,22539,46316,46316,49625,46316,32774,38147,38147,38147,29464,34440,41769,42516,42516,19074,42516,46902,29483,22657,45738,22657,46191,46316,28001,46316,32038,38147,48630,38147,27827,29518,29546,42516,39530,20864,38368,29566,29583,46250,46316,29603,36583,29623,29640,40469,42516,42516,42516,29661,38373,22657,29679,46316,51108,36586,38147,50541,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,29702,29722,29738,29754,28244,40729,36585,22448,28385,36584,34366,22755,31692,34720,29778,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,26790,42516,42516,51537,42516,29812,25227,42516,31450,29831,29840,29856,29871,29878,29894,29907,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,31072,31070,42516,32276,32283,40826,29686,35273,29923,34810,28721,42516,35352,29943,34304,42516,29968,36872,42516,42516,29988,30012,34471,30028,22581,34160,30064,24121,30107,48780,30128,30172,30191,29624,22523,47650,28217,40896,22382,42516,42516,42516,42735,42516,30232,23487,42516,42516,42516,27906,38368,22657,22657,22657,26867,38374,22541,46316,46316,46316,37425,44805,38147,38147,38147,38147,30252,50615,30272,30304,42516,42516,42516,30320,30338,23487,42516,42516,27104,21782,30358,30377,22657,22657,30395,30434,30481,30498,46316,46316,30515,51071,30551,30568,38147,38147,30585,35762,23510,42516,42516,42516,42516,42516,30625,23255,30648,22657,22657,30668,22877,30687,46316,46316,34855,46316,32837,38147,38147,43217,38147,34440,41769,45029,42516,30729,42516,21024,28242,29299,22657,30749,46191,50174,46316,30776,32038,38147,30812,48472,27827,22690,23708,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,37071,42516,42516,38373,22657,31523,46316,43307,36586,38147,39352,22690,34920,42516,38372,43148,46316,38137,38147,30829,36804,38368,28385,28404,30535,27085,28354,31634,30852,30600,30074,38197,42103,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,21805,30876,42516,51537,49762,30895,42516,30918,43094,30942,30951,30967,30982,30994,31010,31023,26099,42516,31039,39573,31055,20844,31088,31151,40795,31438,31118,31138,31170,31208,31224,31259,31325,39316,31341,31357,42305,39859,31243,31397,39944,31425,33906,31466,31484,36903,42516,42516,38844,42516,28243,31508,40831,43064,26242,31546,31583,49551,32501,35578,43001,31607,35023,30465,31623,22382,40777,39e3,31658,40711,31716,41838,31747,42230,41234,31783,31813,31829,31873,31912,31936,31952,31988,32019,35868,32054,38034,47598,32094,32110,32136,39813,32152,32186,47170,32233,26152,32263,42516,49503,42516,32299,32321,32337,32365,32386,32406,32424,22657,35078,32463,30760,22540,32487,46316,47681,50971,43200,30533,32517,38147,37625,38481,40265,32560,23510,18666,32576,32596,39698,32624,37664,32645,31965,32706,47478,32693,32731,32762,40433,46316,32798,32825,32774,32853,32872,49013,32893,32919,41769,42516,21429,46706,42516,42516,32939,25143,43551,27695,46191,47568,50517,33128,32038,44391,37914,44027,27827,22690,51501,22158,32960,23571,32997,33045,33080,33109,33144,33160,33196,33225,33259,33289,25257,41794,33305,33321,22943,47433,44826,33342,33363,33392,45913,37247,22690,23238,33434,38372,47456,46316,49977,38147,33455,33478,32944,28385,33515,33536,30206,38372,33571,38971,31372,39304,33587,33611,33627,33643,33674,33720,28385,36584,33273,33742,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,33784,42516,51537,33805,33823,29972,43389,33866,33897,42516,33882,33940,33947,33963,33976,26099,42516,42516,20279,27632,42516,42516,42516,42516,42516,41269,42516,41261,42516,41268,25123,41628,38176,37400,33992,34810,28721,42516,34012,42516,34304,34012,42516,42516,42516,34029,34013,37295,42516,28243,34045,22657,22657,22657,34069,34103,46316,46316,48318,47159,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,23487,42516,42516,45931,42516,38368,22657,22657,22657,44213,38374,22541,46316,46316,46316,42968,44805,38147,38147,38147,38147,34120,32923,26115,26152,42516,42516,42516,42516,42516,23487,42516,46602,42516,38370,22657,22657,30041,22657,30360,22540,46316,46316,42268,46316,22343,30533,38147,38147,44e3,38147,27826,35762,23510,42516,42516,42516,42516,42516,39273,23255,22657,22657,22657,37139,22877,22539,46316,46316,49643,46316,32774,38147,38147,38147,48815,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,46191,46316,46316,46316,32038,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,46733,42516,42516,42516,36647,22657,28384,27995,46316,49984,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,44874,43254,31692,29762,34139,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,38852,42516,42516,51280,34176,34185,34201,34208,34215,34231,34244,26099,42516,42516,42516,27632,42516,42516,34401,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,37878,42057,42516,42516,34304,42516,42516,42516,42516,34260,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,34278,42516,28081,38368,22657,22657,22657,22657,38374,42076,46316,46316,46316,46316,46212,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,47761,42516,34299,19108,42516,42516,19113,34320,22657,22657,34338,22657,30360,22540,46316,34104,46316,46316,22343,30533,38147,42837,38147,38147,27826,34355,42516,42516,42516,34399,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,38663,42516,34417,28242,22657,22657,38760,37745,46316,46316,50996,37798,38147,38147,38147,34438,22690,34456,18364,34487,34538,24114,31309,31274,34559,34565,27432,34581,44559,30458,34604,22076,42516,19757,34657,29792,34679,47804,33555,31559,34736,35451,34758,22690,41150,39051,35676,32439,38610,34776,34795,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,34833,34871,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,18277,42516,42516,34899,42516,42516,42516,36062,42516,36065,42516,42516,34947,34936,36697,22657,34963,27757,38148,48007,34986,42516,42516,29815,34304,21387,19116,42516,38636,42516,42516,42516,42516,28243,22657,22657,43325,22657,27401,46316,46316,30705,48318,38147,38147,38147,35021,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,35376,42516,35039,38368,22657,22657,22657,22657,50945,22541,46316,46316,46316,46316,38717,38147,38147,38147,38147,38147,41757,22444,42516,35059,42516,42516,42516,42516,42516,42516,42516,39196,38370,35077,22657,22657,22657,30360,46821,46316,46316,46316,46316,22343,23541,38147,38147,38147,38147,27826,41766,42516,42516,42516,50318,42516,42516,42516,23255,22657,22657,22657,46040,30361,22539,46316,46316,46316,34080,30525,38147,38147,38147,42204,34440,41769,42516,42516,46608,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,23434,42516,22428,38373,22657,28384,46316,46316,36586,38147,27827,35094,34920,22560,38372,50497,46316,40393,38147,43581,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,44978,42516,51537,30322,33499,42482,50012,50022,18763,18772,35115,35131,35143,35159,35172,26099,42516,42516,42516,36498,41847,42516,42516,42516,31671,41803,35188,36161,35205,35221,43491,35237,35256,29171,35289,37464,35305,42516,42516,42516,35339,42516,28090,35375,42516,42516,28949,35314,39266,28243,48989,48108,22657,35392,47509,37433,35422,34970,35439,27808,35467,38147,35501,35536,22382,42516,35594,39908,48509,34515,35614,42516,18299,18417,42516,35655,35672,48116,22657,43129,29280,37184,22541,48019,46316,38117,35692,47637,38147,35719,38147,35737,27472,35753,22444,42516,42516,42516,42516,35778,48535,35820,42516,42516,42516,23024,36244,22657,22657,29502,38418,35859,41980,46316,46316,48733,41934,49389,35884,38147,38147,40673,49832,35905,42516,36909,35924,35976,35997,18673,36033,34522,36081,47410,36098,36117,36141,36177,46316,36198,32809,43953,30446,38147,43626,42012,36214,36230,23328,20636,45205,36266,36283,36301,35981,36329,26662,46771,36350,36390,48253,35703,36411,36456,40231,38454,41461,37653,42516,42516,37028,36479,40577,43121,45398,22366,37772,48725,38205,36432,50457,40469,42516,25485,42516,36514,38373,22657,28384,46316,46316,36586,38147,27827,36626,36531,42516,28996,31885,36559,36579,36602,36619,36804,36642,28385,28404,30535,42423,49897,44263,36663,36694,43147,27775,22913,28244,40729,36585,22448,36713,36744,34366,22755,31692,28429,36774,36790,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,39935,42516,51537,42516,42516,42516,42516,25917,42516,29952,39942,19158,38671,36820,36833,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,44206,22657,27401,46316,46317,46316,48318,38147,38147,34588,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,19484,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,36849,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,36869,42516,42516,42516,42516,42516,42516,42516,42516,46294,22657,22657,22657,22657,30360,49232,46316,46316,46316,46316,22343,30796,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,46996,42516,51537,42516,23354,42516,42753,36888,36925,36938,36954,36961,36977,36993,37006,26099,42516,37022,42516,27632,42516,41516,26816,42516,42516,37044,42516,37049,18537,37065,37087,37117,44086,37200,37235,39844,33658,37263,42516,42516,35791,42516,42516,34914,28072,42516,37291,22389,37311,18926,37716,37348,43712,48153,37366,37382,46316,37416,40607,40193,49587,35520,37449,27508,37480,37934,42516,42516,42516,42516,41144,42516,42516,42516,42516,42516,38368,37503,36125,22657,37529,39594,37550,37566,48265,46316,37588,30713,29645,37605,37623,38799,38147,37641,22444,42516,42516,37688,42516,42516,49494,24999,42516,42516,42516,38370,22657,22657,29494,37704,37740,22540,46316,46316,40001,37761,37795,30533,38147,38147,37825,37814,37848,41766,42516,37894,42516,42516,51139,42516,42516,23255,22657,41398,22657,22657,30361,22539,42274,46316,46316,46316,30525,38147,37912,38147,38147,34440,41769,37930,36490,42516,34663,37950,28242,37986,22657,22657,46812,38013,46316,46316,45485,49261,38147,38147,48821,22690,49311,42516,42516,38050,38368,41404,22657,40730,47057,46316,36583,48937,38147,40469,42516,21575,42516,42516,38373,22657,38069,46316,45780,36586,38147,40463,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,38089,46273,22694,23034,40134,34366,22755,38105,38164,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,26200,42516,51537,42516,27946,42516,42516,47834,20951,20960,38221,38236,38243,38259,38272,26258,42516,38551,42516,27632,42516,34262,42516,42516,42516,38553,42516,38546,21091,38552,21774,38288,31700,35273,38309,34810,28721,42516,42516,38329,34304,42516,29241,23811,23953,42516,42516,42516,38347,38364,33022,22657,38390,38410,28636,46316,29607,39628,38434,42370,38147,48603,38470,47663,38504,38541,39253,39681,42516,42516,42516,42516,41197,42516,42516,42516,38368,31857,22657,38569,22657,38374,22541,38589,28198,46316,46316,44805,29206,27800,32877,38147,38147,32923,22444,42516,28144,42516,38634,42516,45188,42516,38652,42516,42516,38370,39723,22657,22657,38687,30379,22540,23043,46316,46316,38710,22895,30533,49398,38147,38147,38733,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,33462,42516,42516,42516,42516,38368,38756,22657,40730,38776,46316,36583,38795,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,38815,36586,49663,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,49485,38368,44256,40047,45820,38834,38868,32210,38891,28238,43147,27775,22913,28244,40729,36585,22448,28385,38914,38935,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,27187,42516,30926,42516,34543,38987,37672,39016,39067,39107,39092,39111,39076,39127,39140,26099,42516,25841,23701,20829,39222,20009,42516,39156,41252,39175,39212,32746,21195,39238,26847,39289,45668,39332,39368,34810,28721,32390,42516,42516,26444,30879,36010,28099,40787,39398,38525,26035,39432,39483,44460,39503,41633,22657,32003,22601,46316,49709,48318,47976,47889,30552,38147,33209,39523,39917,39159,42516,39546,42516,42516,40976,42516,42516,42516,39568,39487,37157,22657,39589,22657,38374,39610,45436,46316,39644,46316,44805,27542,39661,38313,38147,38147,32923,22444,42516,42516,42516,42516,30632,42516,42516,21187,39678,39697,39714,22657,22657,50559,22657,39739,39760,46316,46316,38818,46316,39784,39805,38147,38147,32856,38147,39829,41766,46006,39893,48391,49682,42516,39960,34641,39976,38394,40024,37997,33010,30361,22539,40063,40121,43817,40157,30525,40868,40175,40209,40247,34760,44916,20285,40281,34623,40309,51090,50324,48429,40325,40344,40364,39645,40409,40428,40449,38147,40485,49825,39382,22690,40506,42516,42516,22216,40534,39507,48098,30083,50926,38024,33595,45640,28567,40469,40559,42516,40087,26129,45371,31289,28384,40593,41927,40637,40665,40689,34614,41203,40707,27312,43148,48295,28405,40861,22683,50287,38368,40727,40746,40649,40767,40811,22827,40847,33407,49334,48207,33243,28244,40729,36585,22448,28385,36584,41673,40884,31692,28429,22929,40922,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,40951,51537,42516,42744,40972,42516,27292,40992,41001,41017,41032,41039,41055,41068,26099,20248,41084,41102,41129,21286,41166,42516,41182,41219,41286,31731,41302,41336,41352,41368,41384,34883,41420,41436,48349,41477,42516,42240,27121,34422,42516,41511,25267,41532,41575,42516,42516,41594,28243,22657,31843,41613,34053,27401,40159,35568,34847,41649,38147,27550,41689,41744,40896,22382,42516,26380,42516,41578,42516,44762,41785,42516,41828,27866,41270,19255,22657,41881,41897,22657,35406,41916,43971,44095,46316,46316,41950,22851,37219,42001,38147,29467,32923,42028,42044,42516,46644,19385,42516,42516,42516,42516,42516,34632,38370,22657,27339,43920,22657,30360,22540,46316,44514,36395,46316,22343,30533,38147,35478,49592,38147,27826,41766,42516,42516,21305,42516,31235,42516,42516,23255,22657,22657,22657,22657,20064,42074,46316,46316,46316,46316,42093,38147,38147,38147,38147,50734,41769,50664,35952,42516,42516,42516,41113,22657,42177,22657,45759,46316,43945,46316,45799,38147,45843,38147,27827,29041,42127,42516,42516,42516,48412,30671,22657,38073,44692,46316,33520,45533,38147,40469,42146,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,43588,34920,42516,42166,40348,33173,48271,42201,22683,42220,41559,42256,42290,42321,33756,44448,35547,42352,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,32531,22755,42386,28429,22929,42410,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,39045,51537,42516,42516,42439,19363,42461,42498,42516,31468,42533,42547,42563,42576,26099,42516,42516,25867,27632,42516,42516,42516,42592,26617,42516,42516,26436,25867,42516,30236,31920,49620,42612,36440,34810,28721,42516,42647,42516,34304,42516,44608,36046,42516,35598,42516,42516,36057,51481,44194,32471,36334,37148,42671,32033,42687,33121,42706,38488,30256,30569,29372,32199,42722,42778,42516,42799,42516,49524,50043,35835,42516,42516,42516,42516,38368,22657,22657,37175,22657,38374,22541,46316,46316,47563,46316,44805,38147,38147,38147,42836,38147,32923,42853,42888,35656,42516,42516,42516,50763,30902,39460,48700,42516,38370,22657,42923,22657,22657,37350,22540,46316,42958,46316,46316,27403,30533,38147,42991,38147,38147,27826,41766,42516,29233,42516,42516,42516,43017,42516,23255,22657,22657,49093,22657,22325,22539,46316,46316,43039,46316,30788,38147,38147,35485,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,36017,42516,42516,43058,22657,22657,40730,46316,46316,36583,38147,38147,48843,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,46409,43080,43110,32715,30112,30535,40935,43145,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,35061,42516,42516,42516,28279,28282,18254,28275,31684,43164,43182,29146,43216,43233,29330,43270,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,43287,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,43306,46316,46316,46316,46316,50852,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,43323,28384,43789,46316,36586,43341,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,50278,22100,42516,42516,50243,42516,29530,43375,33789,43361,43411,43418,43434,43447,26099,42516,33915,33924,27632,40956,43463,43486,41243,43507,26512,26972,26982,27147,41812,42783,43531,49966,43567,43604,44058,40078,42516,42516,42516,23213,43642,34502,43666,43684,38517,42516,42516,35323,43702,22657,43728,30048,43746,43782,42975,46316,43805,34708,43833,43850,27569,49274,49874,43871,42516,42516,42516,45270,35189,42516,42516,43894,43668,42516,42814,33726,22657,43915,22657,37724,49041,43936,46316,43969,46316,45680,43987,44022,33996,38147,38147,44043,44074,22444,42516,42516,19081,42516,44111,44127,42516,43290,44154,44166,44182,22657,37101,44229,44279,30652,44299,46316,42336,45461,44326,40412,44345,38147,44372,45987,44388,34123,41766,28121,42516,42516,24911,44407,50085,42516,44435,27732,44483,22975,22657,30361,22539,44504,42690,46316,46316,30525,28768,44537,44554,38147,40691,44575,42516,44603,44624,42516,42516,28242,44645,22657,22657,44664,44689,46316,46316,49378,44708,38147,38147,49798,22690,42516,44729,42516,42516,20056,22657,22657,34376,46316,51047,22477,38147,44538,40469,42516,22273,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,44749,26230,34694,49922,44785,36803,38372,46315,38146,47702,44821,44842,44862,21913,40729,36585,22448,28385,36584,40621,44890,44940,42111,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,46959,51537,45028,47264,44964,45002,45045,45083,45015,45108,45123,45139,45155,45168,26099,45184,28448,42516,28797,42516,42516,30342,42516,42516,45204,45221,31185,28655,31192,26648,48147,38948,50978,45241,34810,28721,45262,45286,25875,34304,35804,42516,42516,42516,42516,45307,45333,42516,45362,45387,27370,22657,22657,45422,45457,45477,46316,48318,45501,22713,45531,38147,40896,22382,41086,42516,42516,45549,45580,42516,42516,42516,42516,42516,41312,38368,32670,37166,22657,22657,33029,22541,45618,47052,46316,46316,45690,35721,38147,45637,38147,38147,45656,22444,42516,42516,45593,44733,42516,45600,35835,45706,27030,38348,45731,22657,22657,40543,26861,45754,45775,46316,46316,43191,44800,45796,45815,38147,38147,40256,45836,45859,28046,42867,49429,42516,25220,42516,19477,43271,20461,22657,22657,27347,45890,30361,22539,46316,48577,44521,46316,30525,38147,38147,46850,45910,34440,41769,42516,50831,45929,19737,42516,28242,22657,45947,43759,50887,46316,45965,46065,28181,38147,45983,46857,27827,22690,42516,42516,46003,44138,38368,22657,22657,40730,46316,46316,36583,38147,38147,29031,51383,46022,26136,47337,46039,22657,46056,46316,34383,36586,38147,46089,46111,34920,46149,46173,43148,46207,44846,46228,32903,36804,38368,46247,46266,45515,36803,38372,46315,38146,35099,35240,22504,22913,46289,46310,46333,36758,46387,47879,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,27247,51537,42516,42516,23393,42516,46425,46462,46474,46490,46505,46521,46537,46550,26099,46566,25493,25815,46587,26561,21328,46624,21598,42516,46636,46660,46669,46685,46722,46757,46799,32544,46837,46873,41704,47524,33832,37332,35627,34304,46901,42516,44629,46918,39031,46952,46975,47012,47022,48184,31972,27713,43730,47038,31642,47073,47098,47607,47121,47145,47186,47202,47222,47250,47280,47302,42058,42516,47326,47353,42516,42516,47371,47388,46928,47404,47426,47449,47472,29567,47494,47549,47584,47623,47679,36182,44805,36463,37832,40141,38147,32161,32170,47697,42516,45060,42596,50682,47718,42130,47751,46440,36515,21144,38370,47785,29270,22657,44488,47820,47850,47868,40376,46316,45441,47912,47938,47958,43617,38147,38919,47992,41766,29407,48041,42516,27096,48062,42516,50062,40568,48085,38573,48132,48169,30361,48200,48223,48241,48287,48311,47922,47129,22858,48334,43855,34440,40906,48365,50193,42516,22144,48387,48407,44243,48428,22657,49223,47234,48445,46316,47082,50795,48488,38147,33704,22690,42516,48504,48525,42516,20103,22966,48559,32447,40385,48575,48593,50156,48626,48646,48680,42516,33850,39552,21921,26930,48716,48749,48769,48802,45246,48837,48960,48859,48887,32658,28363,48910,33376,48933,48953,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,45621,46231,48976,39991,49005,49029,40039,49057,44903,22755,31692,28429,49073,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,49109,42516,42516,49144,42516,32608,18328,18337,49164,18337,18344,49180,49193,26099,42516,42516,42516,27632,20863,28835,42516,42516,42516,42516,28834,42516,20857,42516,28241,49209,31530,22841,49248,36678,30143,33493,42516,42516,34304,42516,42516,35043,49290,42516,42516,42516,38053,28243,49327,22657,22657,22658,49350,46316,46316,46316,31591,33687,38147,38147,38147,49366,49414,49451,42516,49474,49519,42516,42516,43686,45346,42516,46571,46157,38368,45949,40328,45406,25137,29005,22541,48786,34087,38601,49540,48459,38147,33697,39345,49573,33236,49608,22444,42516,19180,42516,50588,42516,42516,42516,18791,42516,42516,38370,38694,22657,22657,22657,30360,49641,32217,46316,46316,46316,22343,49659,38898,38147,38147,38147,27826,41766,46990,42516,49679,42516,42516,42516,42516,20094,31303,22657,22657,22657,30361,49698,46316,46316,46316,46316,30525,49732,38147,38147,38147,34440,35908,42516,42516,46023,49756,42516,29706,37130,22657,22657,39744,38128,46316,46316,49778,49814,38147,38147,49848,22690,22055,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,34322,43148,47105,28405,38446,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,49890,49913,49938,22448,28385,36584,34366,34779,33418,49954,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,5e4,50082,50038,50059,42516,32349,42516,20487,50078,34283,44986,50101,50114,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,50130,42394,35273,50148,34810,28721,42516,36285,32580,34304,42516,42516,42516,42516,42516,25759,42516,42516,28243,27704,22657,37534,22657,27401,50172,46316,38188,48318,29351,38147,30813,38147,40896,22382,42516,42516,42516,42516,42516,41597,42516,42516,42516,42476,42516,38368,22657,50132,22657,22657,38374,22541,46316,49557,46316,46316,44805,38147,38147,50449,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,50190,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,50209,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,50231,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,50266,42516,22306,42516,45067,50303,50340,42516,50365,50380,50394,50410,50423,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,45894,46314,50439,28325,41965,36365,42516,42516,42516,34304,42516,42516,42516,42516,25694,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,50473,42516,42516,42516,50491,22657,22657,22657,22657,30360,50513,46316,46316,46316,46316,22343,50533,38147,38147,38147,38147,27826,41766,42516,42516,29399,42516,42516,42516,42516,23255,22657,22657,50557,22657,50575,22539,46316,43245,46316,33180,30525,38147,47942,38147,38147,50611,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,26324,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,48543,50631,50644,26099,42516,42516,42516,27632,50660,42516,50680,42516,42516,42516,29122,42516,21452,29118,32973,50698,44948,35273,50716,34810,28721,42516,42516,42516,50750,27264,27883,43515,42516,42516,42516,42516,42516,28243,22657,43166,22657,49088,27401,46316,30696,30175,48318,38147,38147,50786,27533,40896,50811,50827,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,51530,42516,42516,42516,38370,22657,27966,22657,22657,27206,22540,46316,36563,46316,46316,48225,30533,38147,43345,38147,38147,27826,41766,21110,42516,42516,42516,42516,42516,42516,23255,36082,22657,22657,22657,30361,22539,50847,46316,46316,46316,30525,40490,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,42516,42516,42516,42516,46741,49861,51029,26099,24903,42516,42516,27632,42516,42516,20017,42516,42516,42516,42516,20023,42516,42516,50868,36101,46314,27462,29927,45874,41719,42516,29087,42516,34304,42516,42516,42516,42516,42516,42516,42516,42872,28243,22657,22657,22657,47797,27401,46316,46316,22542,48318,38147,38147,38147,27479,40896,22382,42516,50903,42516,42516,42516,42516,42516,42516,42150,42516,42516,38368,46183,22657,41900,22657,38374,22541,50922,46316,37779,46316,44805,36603,38147,38147,40222,38147,32923,22444,42516,50475,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,50942,22657,22657,30360,50961,30499,50994,46316,46316,22343,49789,39662,51012,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,48664,23255,22657,22657,32677,22657,28304,22539,46316,46316,51045,46316,51063,38147,38147,50725,38147,44006,41769,42516,42516,50906,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,48656,42516,42516,47372,42516,31381,22657,22657,34817,46316,46316,40751,38147,38147,40469,42516,42516,51087,42516,38373,28681,28384,46316,51106,36586,34742,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,51361,42516,42516,42516,42516,51537,42516,42516,42516,42516,25917,19962,42516,42516,42516,46741,49861,51029,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,28721,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,27401,46316,46316,46316,48318,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,46123,30288,30286,49299,30156,51124,22408,22410,49308,30152,46133,51161,51174,21040,42516,42516,42516,27632,42516,42516,31797,42516,42516,42516,42516,42516,42516,42516,32629,20505,20792,18990,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,51190,25598,18486,18508,19308,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,30409,42516,25917,39868,39877,51215,51230,51237,29448,51253,21040,42516,42516,42516,27632,42516,42516,51474,42516,42516,42516,23517,42516,42516,23514,32629,20505,21066,18953,21068,18866,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,18459,25598,18486,18508,51199,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,36374,42516,42516,42516,42516,31102,50349,51296,51323,51307,51330,32370,51346,21040,42516,42516,42516,27632,42516,42516,51474,51382,42516,26083,42516,42516,42516,26079,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,18315,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,51399,25598,18486,18508,21522,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,20235,20264,20301,20317,20346,20333,20349,20365,20381,20397,20422,20606,20438,20477,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,21141,42516,42516,42516,42516,48069,42516,42516,42516,42516,25917,42516,42516,42516,42516,42516,42516,42517,26099,42516,42516,42516,27632,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,28241,22657,46314,35273,38147,34810,46363,42516,42516,42516,34304,42516,42516,42516,42516,42516,42516,42516,42516,28243,22657,22657,22657,22657,22341,46316,46316,46316,39789,38147,38147,38147,38147,40896,22382,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38368,22657,22657,22657,22657,38374,22541,46316,46316,46316,46316,44805,38147,38147,38147,38147,38147,32923,22444,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,38370,22657,22657,22657,22657,30360,22540,46316,46316,46316,46316,22343,30533,38147,38147,38147,38147,27826,41766,42516,42516,42516,42516,42516,42516,42516,23255,22657,22657,22657,22657,30361,22539,46316,46316,46316,46316,30525,38147,38147,38147,38147,34440,41769,42516,42516,42516,42516,42516,28242,22657,22657,22657,37745,46316,46316,46316,37798,38147,38147,38147,27827,22690,42516,42516,42516,42516,38368,22657,22657,40730,46316,46316,36583,38147,38147,40469,42516,42516,42516,42516,38373,22657,28384,46316,46316,36586,38147,27827,22690,34920,42516,38372,43148,46316,28405,38147,22683,36804,38368,28385,28404,30535,36803,38372,46315,38146,28238,43147,27775,22913,28244,40729,36585,22448,28385,36584,34366,22755,31692,28429,22929,23e3,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,23494,42516,42516,45092,51424,51429,51429,51451,23492,51445,51467,42516,42516,42516,42516,42516,42516,51474,42516,42516,42516,42516,42516,42516,42516,32629,20505,21066,18953,21068,19019,18919,18270,40105,18293,51497,42516,42516,18360,42516,49435,42820,18380,18411,18395,18574,19226,18433,20169,51190,25598,18486,18508,19308,18465,25604,18492,18514,20728,18530,42516,30418,42516,42516,42516,50250,25964,50770,42516,18553,39446,18564,20175,20411,20131,20505,23879,18590,26008,18612,18632,18596,18470,18594,26012,18616,18636,20798,20741,20757,42516,18652,18689,18711,18748,18695,18788,42516,41546,48871,18807,18835,19802,18823,19840,25206,18851,18904,18942,18979,19680,19006,18851,18904,18942,18979,19680,19045,20750,46697,19097,19132,20936,31767,19148,19174,19196,20141,20921,19788,19212,19242,19278,25525,20579,19301,19596,19271,25518,20572,19294,19589,19324,19353,35639,19379,39467,19401,41728,19421,19500,24458,19544,19575,19614,19632,19650,19559,19612,19630,19648,19666,19029,19696,19712,19728,19753,19773,19830,19435,19449,19888,19905,19856,19887,19904,19921,19947,19984,20043,20080,20119,20157,20536,20191,20213,20542,20197,20219,19931,51517,20264,20301,20317,20346,20333,20349,20365,51553,20397,20422,20606,20438,20453,20503,21067,21068,20521,20558,20595,20622,20652,23888,18878,20683,20699,20715,20779,20814,20880,20890,20906,19463,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,42516,94506,94506,94506,94506,94506,94506,94506,94506,94506,94506,0,94506,90409,94506,94506,94506,94506,94506,94506,94506,94506,94506,365,94506,90409,94506,94506,94506,94506,94506,94506,94506,69632,73728,94506,94506,94506,94506,94506,65536,94506,12290,3,0,0,2183168,0,0,0,90409,94506,299,300,0,2134016,303,304,304,304,304,304,304,304,0,0,0,0,0,304,0,304,1,289,3,0,0,0,295,0,0,0,0,0,0,0,0,0,0,796,0,796,0,0,0,0,0,2424832,2433024,0,0,2457600,0,0,0,0,0,0,0,0,0,0,650,0,0,0,0,0,0,0,0,0,2904064,2908160,0,0,0,0,0,0,0,0,0,0,0,1685,1686,0,1688,0,0,0,0,3117056,0,0,0,0,0,0,0,365,365,0,0,0,0,0,0,448,0,0,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,559,582,559,582,559,559,582,0,0,0,2138112,0,0,0,0,0,0,0,0,0,0,0,0,0,2991,0,0,0,2772992,2805760,2830336,0,2863104,2920448,0,0,0,0,0,0,0,2805760,2920448,0,0,0,0,0,0,0,2732032,0,2179072,2179072,2179072,2179072,2424832,2433024,0,0,0,0,0,2920448,0,0,0,0,0,0,0,0,0,0,0,1702,0,1704,0,0,2179072,2830336,2179072,2179072,2863104,2179072,2179072,2179072,2179072,2920448,2179072,2179072,2179072,2179072,2179072,2179072,2126737,2126737,2126737,2126737,2126737,2593681,2126737,2126737,2126737,2126737,0,914,2125824,2125824,2125824,2125824,2125824,2424832,2433024,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,0,2125824,2125824,2125824,2125824,2723840,2125824,2732032,2772992,2125824,2125824,2125824,2805760,2125824,2830336,2125824,2125824,2863104,2125824,2125824,2125824,2125824,2920448,2125824,2125824,2125824,2125824,2125824,2920448,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3117056,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2457600,2125824,2125824,2125824,2125824,2183168,0,0,0,0,0,0,0,0,0,0,661,0,661,0,0,0,2408448,0,0,2584576,0,0,0,0,2838528,0,0,2838528,0,0,0,0,0,2179072,2179072,2179072,2408448,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2625536,2179072,2179072,0,2125824,2125824,2125824,2408448,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3125248,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2662400,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2801664,2813952,2125824,2125824,2801664,2813952,2125824,2838528,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2461696,0,0,0,0,0,0,0,0,0,0,0,0,2600960,0,0,0,0,0,0,2441,0,0,0,0,0,0,0,0,0,0,2493,2494,0,0,2497,0,2768896,2777088,2781184,0,2822144,0,0,2883584,0,0,0,0,0,0,0,0,0,0,0,0,3055616,0,0,0,3080192,3100672,3104768,0,0,0,0,3186688,0,0,0,0,0,0,0,307,204800,0,0,0,0,0,0,0,0,0,111051,111051,111051,111051,111051,111051,111051,111051,1,0,0,0,0,0,2797568,0,0,0,0,0,0,0,2850816,2867200,0,0,0,0,0,441,0,0,332,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,468,0,0,3133440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2131,0,0,0,0,0,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2461696,2465792,2179072,2768896,2777088,2781184,2797568,2822144,2179072,2179072,2179072,2883584,2179072,2912256,2179072,2179072,2179072,2179072,2179072,2179072,2523136,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2600960,0,0,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2461696,2465792,2125824,0,1142784,0,2179072,2125824,2125824,2179072,2179072,2179072,2179072,2179072,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2592768,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,24576,988,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2523136,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2600960,2125824,0,2125824,2125824,2125824,2125824,2125824,0,0,0,0,0,0,0,0,0,0,541,1272,541,541,541,541,2125824,2125824,2125824,2641920,2125824,2125824,2125824,2125824,2125824,2125824,2719744,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,2125824,2125824,2125824,2125824,2125824,2125824,299,0,0,0,299,0,300,0,0,0,2768896,2777088,2781184,2797568,2822144,2125824,2125824,2125824,2883584,2125824,2912256,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,2125824,2126812,2125824,2125824,2125824,2125824,2125824,2125824,3133440,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3207168,2125824,0,0,0,2179072,2125824,2125824,2179072,2179072,2179072,2179072,2179072,2125824,2125824,2125824,2125824,0,0,0,0,0,0,2510848,2514944,0,0,2125824,2125824,3133440,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3207168,2125824,2179072,2125824,0,2125824,2125824,2125824,2125824,2125824,0,0,0,0,0,0,300,0,0,0,0,0,0,2764,0,0,0,0,0,0,0,0,0,0,2059,2060,0,2062,2063,0,0,0,0,2605056,0,0,0,0,2887680,0,2924544,0,0,0,0,0,0,0,2108,0,0,0,0,0,0,0,0,0,0,0,0,0,1177,0,0,0,0,0,0,3162112,3170304,0,0,3219456,3035136,0,0,0,0,0,3072e3,3190784,0,0,0,0,0,0,0,0,2576384,0,0,0,0,0,0,0,334,0,0,334,0,0,334,0,0,0,0,0,0,0,2387968,0,0,0,0,0,0,0,0,0,0,0,2050,0,0,0,0,3121152,3141632,0,0,0,2924544,0,2682880,0,0,0,0,0,0,3112960,2387968,2924544,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3035136,2179072,2179072,3072e3,2179072,2179072,2179072,2179072,2699264,2179072,2715648,2179072,2723840,2179072,2732032,2772992,2179072,2179072,2179072,2805760,3121152,2179072,2179072,3141632,2179072,2179072,2179072,3170304,2179072,2179072,3190784,3194880,2179072,0,0,0,0,0,0,541,1734,541,541,541,541,541,541,1740,541,2125824,3190784,3194880,2125824,0,0,0,0,0,0,2387968,2125824,2125824,2125824,2420736,2125824,2125824,2125824,2125824,2125824,2453504,2125824,2473984,2125824,2736128,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2887680,2125824,2125824,2924544,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,0,0,2125824,2125824,2125824,2125824,2125824,3141632,2125824,2125824,2125824,3170304,2125824,2125824,3190784,3194880,2125824,2179072,2125824,2125824,2179072,2179072,2179072,2179072,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,299,0,300,3112960,3219456,2125824,2125824,3112960,3219456,2125824,2125824,3112960,3219456,0,0,0,0,0,0,0,347,0,405,0,0,0,0,0,405,3022848,0,0,3145728,0,3203072,0,0,0,0,0,0,0,0,0,0,0,2072,0,0,0,0,0,0,0,3067904,0,0,0,0,0,0,0,0,0,0,0,0,0,3003,0,0,0,0,0,2621440,0,3182592,2899968,0,2961408,0,0,2179072,2179072,2416640,2179072,2179072,2179072,2179072,2928640,2179072,2179072,2179072,2998272,2179072,2179072,2179072,2179072,3059712,2179072,2179072,2179072,2179072,3178496,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2494464,2125824,2125824,0,2179072,2125824,2125824,0,2179072,2125824,2125824,2985984,2985984,2985984,2985984,0,0,0,0,0,0,2490,0,0,0,0,0,0,0,0,0,335,0,0,0,0,0,0,2179072,2445312,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2551808,2179072,2179072,2179072,2179072,3178496,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2495377,2126737,2126737,2126737,2126737,2126737,3179409,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2495451,2126811,2895872,2916352,2179072,2179072,2945024,2179072,2179072,2994176,2179072,3002368,2179072,2179072,3022848,2179072,3067904,3084288,2125824,3096576,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3223552,0,0,2125824,2125824,2416640,3096576,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3223552,0,0,2125824,2125824,2416640,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3035136,2125824,2125824,3072e3,2125824,2125824,2125824,3121152,2125824,2125824,3141632,2125824,2125824,2125824,3170304,2125824,2125824,2125824,2125824,2445312,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2551808,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2637824,2125824,2125824,2125824,2125824,2727936,2752512,2125824,2125824,2125824,2125824,2842624,2846720,2842624,2846720,2125824,2895872,2916352,2125824,2125824,2945024,2125824,2125824,2994176,2125824,3002368,2125824,2125824,3022848,2125824,3067904,2125824,3067904,3084288,2125824,3096576,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3223552,2179072,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3039232,2125824,3063808,2125824,2125824,2125824,2125824,2125824,3100672,2547712,2596864,0,0,0,0,0,0,0,0,0,0,0,0,0,3178496,2670592,0,2744320,0,0,0,0,0,2928640,0,0,0,3059712,0,2543616,2666496,0,2633728,0,0,0,0,0,0,2494464,0,0,0,0,0,0,0,0,0,2780,0,0,0,0,2785,0,0,0,0,2957312,0,0,0,0,0,0,0,0,0,0,0,0,0,3188,0,0,0,0,3211264,0,0,0,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2494464,2179072,2179072,2179072,2707456,2179072,2736128,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2887680,2179072,2179072,2179072,2179072,2641920,2179072,2179072,2179072,2179072,2179072,2179072,2719744,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3137536,2126737,2126737,2499473,2126737,2126737,2126737,2556817,2565009,2179072,2514944,2179072,2179072,2179072,2543616,2547712,2179072,2179072,2596864,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3039232,2179072,3063808,2179072,2179072,2179072,2179072,3100672,2125824,2125824,2125824,2125824,2125824,3178496,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2494464,2125824,0,2125824,2125824,2125824,2125824,2125824,0,0,0,0,1080,1084,0,0,1088,2125824,2514944,2125824,2125824,2125824,2543616,2547712,2125824,2125824,2596864,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2928640,2125824,2125824,2125824,2998272,2125824,2125824,2125824,2125824,3059712,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3178496,2179072,2125824,2125824,2179072,2179072,2125824,2125824,2125824,2125824,0,2486272,0,0,0,0,0,2678784,2854912,3006464,2441216,0,0,0,0,0,0,0,0,0,2932736,2965504,0,0,3076096,0,0,0,0,0,444,0,0,0,0,0,0,0,0,0,0,407,0,0,0,0,0,0,2695168,3174400,2646016,2613248,2703360,0,0,0,0,2977792,0,0,3047424,3129344,0,0,0,0,0,645,0,0,648,649,0,0,0,0,0,0,0,725,0,0,0,0,0,0,0,0,0,743,0,0,0,0,0,0,0,0,0,0,0,0,2769,0,0,0,2981888,2396160,0,3153920,0,0,0,0,0,0,0,0,2740224,0,0,0,0,0,0,541,3027,541,541,541,541,541,541,541,541,541,2584,541,541,541,0,0,0,0,0,2793472,0,0,0,0,0,2469888,2506752,2756608,0,0,2580480,0,0,0,0,0,0,2517,0,0,0,0,0,0,0,0,541,541,541,3029,541,541,541,541,541,541,0,2396160,2400256,2179072,2179072,2441216,2179072,2469888,2179072,2179072,2179072,2519040,2179072,2179072,2179072,2179072,2179072,2179072,2801664,2813952,2179072,2838528,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2453504,2179072,2473984,2482176,2179072,2179072,2179072,2179072,2588672,2179072,2613248,2646016,2179072,2179072,2695168,2756608,2179072,2179072,2179072,2932736,2179072,2179072,2179072,2179072,2179072,3117056,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2584576,2179072,2179072,2125824,2125824,2125824,2519040,2125824,2125824,2125824,2125824,2588672,2125824,2613248,2646016,2125824,2125824,2695168,2756608,2125824,2125824,2125824,2125824,2932736,2125824,2125824,2125824,2125824,2125824,2932736,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3129344,2125824,2125824,3153920,3166208,3174400,2506752,2506752,2506752,0,3108864,3198976,0,0,3043328,0,3149824,2936832,0,2760704,3180,2437120,0,0,0,0,0,0,646,0,0,0,0,651,652,653,654,655,0,0,0,0,0,2953216,0,0,2826240,3158016,2428928,0,3018752,2764800,2572288,0,0,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,2741,0,0,0,0,0,3051520,2179072,2428928,2437120,2179072,2486272,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2654208,2678784,2760704,2764800,2854912,2969600,2179072,3006464,2179072,3018752,2179072,2179072,2179072,3149824,2125824,2428928,2437120,2969600,2125824,3006464,2125824,3018752,2125824,2125824,2125824,2125824,3149824,2125824,2428928,2437120,2125824,2486272,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2654208,2678784,2760704,2764800,2785280,2854912,2969600,2125824,3006464,2125824,3018752,2125824,2125824,2125824,2125824,3149824,2179072,3051520,2125824,3051520,2125824,3051520,0,2490368,2498560,0,0,0,0,2875392,0,0,0,3180,0,0,0,0,0,0,2834432,0,3227648,2568192,2564096,0,2940928,2179072,2179072,2498560,2179072,2179072,2179072,2555904,2564096,2179072,2179072,2179072,2617344,2179072,2179072,2179072,2179072,2179072,2179072,2662400,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3137536,2125824,2125824,2498560,2125824,2125824,2125824,2555904,2564096,2125824,2555904,2564096,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3137536,2940928,2940928,0,0,0,0,0,2748416,2879488,0,0,0,0,0,0,0,0,0,2519,0,0,0,0,0,541,2940928,0,0,0,0,0,2748416,2879488,0,3180,0,0,0,0,0,0,0,375,0,0,0,0,0,0,0,360,0,0,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2125824,0,2502656,0,0,3010560,0,0,0,0,0,0,0,0,2990080,2179072,2179072,2179072,3129344,2179072,2179072,3153920,3166208,3174400,2396160,2400256,2125824,2125824,2441216,2125824,2469888,2125824,2125824,2125824,2519040,2125824,2125824,2179072,2502656,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3010560,2179072,2179072,2125824,2125824,2125824,2125824,2125824,2125824,2605056,2125824,2629632,2125824,2125824,2650112,2125824,2125824,2125824,2707456,2125824,2736128,2125824,2125824,2125824,2125824,2125824,2502656,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3010560,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3137536,2125824,2125824,2498560,2125824,2125824,2502656,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3010560,2125824,2125824,2125824,0,0,0,0,0,0,2739,0,0,0,0,0,0,0,2743,0,0,0,2592768,0,0,0,0,0,0,2179072,2179072,2179072,2179072,2179072,2592768,2179072,2179072,2179072,3129344,2179072,2179072,3153920,3166208,3174400,2397073,2401169,2126737,2126737,2442129,2126737,2470801,2125824,2125824,2449408,0,2535424,3031040,2859008,0,0,0,0,0,2179072,2449408,2179072,2535424,2179072,2609152,2179072,2859008,2179072,2179072,2179072,3031040,2125824,2449408,2125824,2535424,2125824,2609152,2125824,2859008,2125824,2125824,2125824,3031040,2125824,2125824,2449408,2125824,2535424,2125824,2609152,2125824,2859008,2125824,2125824,2125824,0,2179072,2125824,2125824,2457600,2179072,2179072,2179072,2179072,2457600,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2179072,2125824,2125824,2179072,2179072,2179072,2179072,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,0,0,0,0,0,0,0,0,0,0,1727,0,0,1728,0,3031040,2125824,2527232,0,0,0,0,0,2179072,2527232,2179072,2179072,2179072,2179072,2179072,2125824,2126738,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3125248,2125824,2125824,2125824,2125824,2125824,2527232,2125824,2125824,2125824,2125824,2125824,3092480,2125824,2527232,2125824,2125824,2125824,2125824,2125824,3092480,0,0,0,0,0,693,0,0,0,0,0,0,365,365,365,0,0,0,0,0,707,708,0,0,0,0,0,714,0,0,0,0,0,0,703,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3020,3026944,0,0,0,2404352,2179072,2179072,2179072,2179072,3026944,2404352,2125824,2125824,2125824,2125824,3026944,0,2539520,0,2949120,2179072,2658304,2973696,2179072,2125824,2658304,2973696,2125824,2125824,2658304,2973696,2125824,0,2711552,256e4,2179072,256e4,2125824,256e4,2125824,0,2179072,2179072,2531328,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2605056,2179072,2629632,2179072,2179072,2650112,0,0,2809856,0,0,0,0,0,0,0,0,0,0,3088384,0,0,0,0,0,442,0,0,454,470,470,470,470,470,470,470,470,470,470,480,470,470,470,470,470,111051,111051,111051,111051,111051,111051,111051,111051,111051,111051,111051,111051,111051,111051,111051,111051,459,459,111051,459,459,459,459,459,459,459,459,459,111051,111051,111051,111051,111051,111051,111051,111051,111051,111051,459,111051,111051,111051,459,111051,111051,111051,111051,111051,0,0,0,0,0,0,0,0,0,2795,0,0,0,0,0,0,12290,3,0,0,2183168,0,0,0,0,0,299,300,0,2134016,303,304,2125824,1060,0,0,2179072,2125824,2125824,2179072,2179072,2179072,2179072,2179072,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,1060,2125824,2125824,2125824,2125824,2125824,0,0,0,0,0,0,0,0,0,0,662,0,662,0,0,0,0,303,118784,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2434,0,303,303,303,303,303,303,303,0,0,0,0,0,303,0,303,1,12290,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2155,0,12290,3,0,0,2183168,0,0,0,0,0,33403,300,0,2134016,49791,304,2105632,12290,3,0,0,294,0,0,0,0,294,0,0,0,0,0,0,0,2124,0,0,0,0,0,0,0,0,0,788,814,0,814,809,0,0,0,122880,122880,122880,122880,122880,122880,122880,122880,122880,122880,122880,122880,122880,122880,122880,0,0,0,122880,0,122880,122880,122880,0,0,0,0,0,122880,0,0,122880,0,0,0,0,0,0,0,0,122880,0,0,0,0,0,0,0,0,0,0,0,0,3002,0,0,0,0,0,0,0,0,122880,122880,122880,122880,122880,122880,122880,122880,122880,0,0,122880,0,0,0,0,0,0,0,0,0,0,712,0,0,0,716,0,0,0,147456,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2459,0,1092,0,2424832,2433024,0,0,2457600,0,0,0,0,0,0,0,0,0,0,728,0,0,0,0,0,1823,2125824,2125824,2125824,2408448,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,1919,2125824,2125824,2125824,0,0,0,131072,0,0,0,69632,73728,0,0,0,0,0,65536,0,0,0,0,0,740,407,0,0,0,0,0,0,0,0,0,0,1158,0,0,0,0,0,0,131072,0,0,131072,131072,0,0,0,0,0,0,0,131072,0,0,131072,0,0,131072,0,0,0,0,135168,135168,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2756,0,0,0,0,135168,0,0,135168,0,0,0,0,0,0,0,0,0,0,735,0,797,0,0,0,0,0,0,0,135168,0,135168,135168,135168,135168,135168,135168,0,135168,135168,135168,135168,135168,135168,135168,0,0,0,0,0,135168,0,135168,1,12290,3,0,0,2183168,0,0,0,0,0,636,637,0,2134016,640,641,0,1361,2125824,2125824,2125824,2125824,2125824,2424832,2433024,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,0,987,2125824,2125824,2125824,2125824,0,304,139264,0,0,0,0,0,0,0,0,0,0,0,0,0,0,225709,0,12290,3,0,0,2183168,0,0,0,0,0,299,33406,0,2134016,303,49794,0,61440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3178,0,304,2424832,2433024,0,0,2457600,0,0,0,0,0,0,0,0,0,0,757,0,0,0,0,762,301,301,301,143661,371,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,143661,301,301,143661,301,301,301,143731,301,301,301,143731,69632,73728,301,301,143661,301,301,65536,301,301,301,301,301,143661,143661,143661,143661,143661,143661,143661,143661,143661,301,301,143661,301,301,301,301,301,301,301,301,301,366,301,0,143661,301,301,301,143661,143661,143661,143661,143661,143661,143661,143661,143661,143661,143661,143661,143661,143661,143661,143661,301,301,301,143661,301,143661,143661,143661,143661,143661,143731,143661,143731,143731,143731,143731,143731,143731,143731,143661,143661,143661,143661,143661,143661,143661,143661,1,301,143661,301,143661,143661,143661,143661,143661,143661,301,0,301,0,301,301,301,301,301,301,301,301,301,143661,301,143661,143661,143661,143661,301,0,0,0,3117056,0,0,0,0,0,0,0,2200252,2200252,0,0,0,0,0,0,662,0,0,0,0,0,541,541,541,541,541,541,541,541,2168,541,541,541,0,0,0,0,0,155648,155648,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,325,0,0,0,0,155648,155648,0,155648,155648,155648,155648,155648,155648,155648,155648,155648,0,0,0,0,155648,0,0,155648,155648,155648,155648,155648,155648,155648,155648,155648,155648,155648,155648,155648,155648,155648,155648,0,0,0,0,0,155648,0,155648,0,0,0,0,0,155648,0,0,0,0,0,155648,155648,0,155648,155648,0,12290,3,0,0,2183168,126976,0,0,0,0,299,300,0,2134016,303,304,0,0,0,3117056,0,0,0,0,0,0,0,365,0,0,0,0,0,0,0,3563,0,541,541,541,541,541,541,541,541,541,3209,541,541,541,541,541,159744,159744,159744,159744,0,0,159744,0,0,0,0,0,0,0,0,159744,0,0,0,0,0,0,0,159744,159744,159744,163840,159744,159744,159744,159744,159744,0,0,0,0,0,0,0,0,0,2805,0,541,541,541,541,541,0,25162,0,0,0,159744,0,0,0,25162,25162,25162,159744,25162,25162,25162,25162,25162,25162,25162,25162,159744,159744,159744,159744,25162,159744,25162,1,167936,167936,167936,167936,167936,167936,167936,167936,167936,167936,167936,167936,167936,167936,167936,167936,1,167936,167936,167936,167936,0,0,167936,0,0,0,0,0,0,0,0,167936,167936,167936,167936,167936,167936,167936,167936,167936,0,0,0,0,0,0,0,0,0,2976,0,0,0,0,0,0,0,0,0,2138112,1183,0,0,0,0,0,0,0,0,0,0,0,0,3168,0,0,0,0,0,0,0,0,172032,0,172032,0,0,0,0,0,0,0,0,0,365,0,293,0,0,0,348,172032,172032,0,0,172032,0,0,172032,172032,0,172032,0,0,0,0,172032,172032,0,0,0,0,0,0,0,0,0,0,172032,0,0,0,0,0,0,2777,0,0,0,0,0,0,2784,0,0,0,0,0,0,2986,2987,0,2988,0,2990,0,0,0,0,0,0,0,69632,73728,0,135168,135168,0,0,65536,135168,172032,0,172032,172032,0,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,172032,0,0,0,0,0,0,0,0,0,3014,0,0,0,0,0,0,176128,176128,176128,176128,176128,176128,176128,176128,176128,176128,176128,176128,176128,176128,176128,176128,1,176128,176128,176128,176128,0,0,176128,0,0,0,0,0,0,0,0,176128,176128,176128,176128,176128,176128,176128,176128,176128,0,0,0,0,0,0,0,0,0,3175,0,0,0,0,0,0,0,3,78115,78115,293,0,634,0,0,0,299,300,0,2134016,303,304,1164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,361,541,541,1308,541,541,541,541,541,541,541,541,541,541,541,541,541,0,0,2242,0,914,563,563,563,563,563,563,563,563,563,563,563,563,563,563,0,0,587,587,587,1203,541,587,563,541,541,541,541,541,563,563,563,563,3070,563,563,563,563,3074,563,563,587,587,587,587,587,1079,0,0,0,0,0,0,0,0,0,0,1102,0,0,0,0,0,0,0,229376,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1134592,0,0,0,0,1691,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3201,563,563,587,587,587,587,0,0,0,0,0,0,0,0,0,0,541,541,541,541,3569,541,541,0,0,563,563,563,563,563,563,563,2251,563,563,563,563,563,563,587,3109,587,587,587,587,587,587,587,587,2407,587,587,587,587,587,2412,2413,563,563,2288,563,563,563,563,563,563,563,563,563,563,563,563,563,563,3541,587,587,587,2375,587,587,587,587,587,587,587,587,587,587,587,587,587,1497,587,587,0,0,0,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,1439,0,3007,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3317,541,541,541,541,3038,541,541,541,541,541,541,541,541,541,541,541,541,1300,541,541,541,563,563,563,3078,563,563,563,563,563,563,563,563,563,563,563,563,1401,563,563,563,587,587,587,587,3120,587,587,587,587,587,587,587,587,587,587,587,1042,587,587,587,587,0,3159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,155648,3214,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,1359,563,563,563,587,3259,587,587,587,3262,587,587,587,587,587,587,587,541,541,563,563,587,587,0,0,0,0,0,0,0,0,0,0,3609,541,541,541,587,587,3270,587,587,587,587,587,587,587,587,587,587,587,587,587,1498,587,587,541,541,541,3330,3331,541,541,541,541,541,541,541,541,563,563,563,563,3581,563,563,563,563,563,3349,563,563,563,563,563,563,563,563,563,587,587,587,587,587,587,587,587,0,541,541,541,3406,541,541,541,541,563,563,563,563,563,563,3415,563,0,587,587,587,587,587,291,1079,0,0,0,0,0,0,0,0,0,249856,249856,249856,249856,249856,249856,249856,249856,1,587,3431,587,587,587,587,587,587,3437,587,587,587,3441,587,541,563,563,3473,563,563,563,563,3478,563,563,563,563,3483,563,563,563,563,977,563,563,563,563,0,587,587,587,587,587,587,1931,587,587,587,587,587,587,587,587,587,2678,587,587,587,2681,587,587,0,0,3456,541,541,541,541,541,541,541,541,541,541,541,541,541,0,2586,0,541,3471,563,563,563,563,563,563,563,563,563,563,563,563,563,563,0,2327,563,3487,587,587,587,587,587,587,587,587,587,587,587,587,587,587,0,0,563,563,587,587,587,587,0,0,541,541,563,563,587,587,0,541,541,541,3205,541,541,541,541,541,541,541,3210,541,541,541,541,541,541,2816,541,541,2820,541,541,541,541,541,541,541,541,3041,541,541,541,541,541,541,541,541,2556,541,541,541,541,541,541,541,541,2233,541,541,541,541,541,0,0,563,587,0,541,563,587,0,541,563,587,0,541,563,587,0,0,0,0,0,0,0,0,0,3510,0,0,0,0,541,541,541,541,541,2165,541,541,541,541,541,541,541,541,3616,563,563,563,563,563,563,563,2265,563,563,563,563,2270,563,563,563,184932,184932,184932,184932,184932,184932,184932,0,0,0,0,0,184932,0,184932,1,12290,3,0,0,0,0,0,0,0,0,0,0,0,0,301,301,0,0,301,301,143661,301,301,301,301,301,301,301,301,301,301,301,143731,301,301,301,301,12290,3,78115,78115,293,0,0,0,0,0,299,300,0,2134016,303,304,587,0,0,188416,541,587,563,541,541,541,541,541,563,563,563,563,587,587,587,587,0,0,0,0,2731,0,0,0,0,305,0,0,0,0,0,0,0,0,0,0,0,0,0,249856,0,0,0,192972,192972,192972,192972,192972,192972,192972,192972,192972,192972,192972,192972,192972,192972,192972,192972,0,192972,0,1,0,0,0,0,0,192972,192972,192972,192972,192972,192972,192972,192972,192972,192972,0,0,192972,0,0,0,0,0,0,0,0,0,0,1145,365,365,0,0,1148,192972,192972,192972,0,192972,192972,192972,192972,192972,0,0,0,0,0,0,0,0,0,3304,0,3180,0,0,0,0,302,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,541,407,407,407,407,407,407,407,0,0,0,0,0,407,0,407,1,12290,3,0,0,0,0,0,0,0,0,0,0,0,118784,299,12290,3,78115,78115,293,0,0,0,0,0,299,300,0,302,303,304,587,0,0,740,541,587,563,541,541,541,541,541,563,563,563,563,587,587,587,587,0,0,2729,0,0,0,0,0,0,740,1184,0,0,0,0,1188,0,0,0,0,0,0,0,378,0,381,0,0,0,381,0,0,563,587,587,587,587,587,1079,1559,0,0,0,1565,0,0,0,1571,2034,0,0,0,0,1577,2036,0,0,0,0,0,0,0,397,0,0,0,0,0,397,0,0,0,0,0,1577,0,0,0,0,0,0,0,0,0,0,0,0,0,262144,0,0,0,0,0,1188,1669,0,0,0,0,0,0,0,0,0,0,0,0,3177,0,0,0,563,563,587,587,587,587,1559,2030,0,0,0,0,1565,2032,0,0,0,0,0,0,2997,0,0,0,0,0,0,0,0,0,0,1586,1587,0,0,0,0,0,0,0,0,1669,0,0,0,0,0,0,0,0,0,0,0,0,106496,0,0,0,0,0,0,2034,0,2036,0,0,0,0,0,0,0,0,0,0,0,0,0,1150976,0,0,0,0,0,563,563,563,563,2325,2652,0,0,0,0,587,587,587,587,587,587,587,587,587,587,587,587,587,2343,0,307,0,307,0,0,0,0,0,0,0,0,0,307,0,0,0,0,0,0,3011,0,0,0,0,3016,3017,0,3019,0,0,0,0,0,204800,204800,0,204800,204800,204800,204800,204800,204800,204800,204800,204800,204800,204800,204800,204800,204800,204800,205107,204800,204800,205106,205107,204800,205106,205106,204800,204800,0,0,0,0,0,0,0,0,0,122880,0,122880,122880,122880,122880,122880,12290,3,0,0,2183801,0,0,0,0,0,299,300,151552,2134016,303,304,0,212992,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,172032,0,0,151552,0,0,0,0,0,0,0,0,0,0,0,0,0,303,0,0,0,0,0,3117056,0,0,0,0,0,0,0,0,2200253,0,0,0,0,0,0,678,0,0,0,0,0,0,0,0,0,0,2977,0,0,0,0,0,0,914,2126737,2126737,2126737,2126737,2126737,2425745,2433937,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,3138449,2126811,2126811,2499547,2126811,2126811,2126737,2724753,2126737,2732945,2773905,2126737,2126737,2126737,2806673,2126737,2831249,2126737,2126737,2864017,2126737,2126737,2126737,2126737,2126811,2126811,2126811,2126811,2126811,2593755,2126811,2126811,2126811,2126811,2126811,2126811,2126811,3036123,2126811,2126811,3072987,2126811,2126811,2126811,3122139,2126811,2126737,2126737,2921361,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,3117969,2126737,0,2126811,2126811,2126811,2126811,2126811,0,0,0,0,0,0,0,0,0,0,1190,0,0,0,0,0,2126811,2425819,2434011,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,3126235,2126811,2126811,2126811,2126811,2126811,2626523,2126811,2126811,2126811,2126811,2126811,2126811,2700251,2126811,2716635,2126811,2724827,2126811,2733019,2773979,2126811,0,2502656,0,0,3010560,0,0,0,0,0,0,0,0,2990080,2179072,2179072,3125248,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2125824,2125824,2125824,2125824,2125824,2592768,2125824,2125824,2125824,2125824,2126811,2126811,2806747,2126811,2831323,2126811,2126811,2864091,2126811,2126811,2126811,2126811,2921435,2126811,2126811,2126811,0,2179072,2126811,2126737,2457600,2179072,2179072,2179072,2179072,2458513,2126737,2126737,2126737,2126737,2126737,2524049,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2601873,2126737,2126737,2458587,2126811,2126811,2126811,2126811,2183168,0,0,0,0,0,0,0,0,0,0,1206,0,1208,0,0,0,0,2126737,2126737,2126737,2409361,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,0,0,2126811,2126811,2126811,2409435,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2839515,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,3118043,2126811,2126811,2126811,2126811,2126811,2126811,2126811,0,0,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2462609,2466705,2126737,2126737,2126737,2642833,2126737,2126737,2126737,2126737,2126737,2126737,2720657,2126737,2126737,2126737,2126737,2126737,2126737,2126737,3040145,2126737,3064721,2126737,2126737,2126737,2126737,2126737,3101585,2769809,2778001,2782097,2798481,2823057,2126737,2126737,2126737,2884497,2126737,2913169,2126737,2126737,2126737,2126737,2126737,2126737,2626449,2126737,2126737,2126737,2126737,2126737,2126737,2700177,2126737,2716561,2126737,2126737,3134353,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,3208081,2126737,0,0,0,0,0,0,3026,541,541,541,541,541,541,541,541,541,541,1352,541,541,541,541,541,0,0,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2462683,2466779,2126811,2126811,2126811,2126811,2126811,2929627,2126811,2126811,2126811,2999259,2126811,2126811,2126811,2126811,3060699,2126811,2126811,2126811,2126811,2454491,2126811,2474971,2483163,2126811,2126811,2126811,2126811,2126811,2126811,2532315,2126811,2126811,2126811,2446299,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2552795,2769883,2778075,2782171,2798555,2823131,2126811,2126811,2126811,2884571,2126811,2913243,2126811,2126811,2126811,2126811,2126811,2126811,2126811,3130331,2126811,2126811,3154907,3167195,3175387,2506752,2507739,2507665,2126811,2126811,3134427,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,3208155,2126811,2179072,2126811,2126811,2126811,2642907,2126811,2126811,2126811,2126811,2126811,2126811,2720731,2126811,2126811,2126811,2126811,2126811,2126811,2126811,3040219,2126811,3064795,2126811,2126811,2126811,2126811,2126811,3101659,0,0,0,2388881,2126737,2126737,2126737,2421649,2126737,2126737,2126737,2126737,2126737,2454417,2126737,2474897,2483089,2126737,2126737,2126737,2126737,2126737,2126737,2532241,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2605969,2126737,2630545,2126737,2126737,2651025,2126737,2126737,2126737,2708369,2126737,2737041,2126737,2126737,2126737,2126737,2126737,2126737,2663313,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,0,0,988,2126811,2126811,2126811,2126811,3036049,2126737,2126737,3072913,2126737,2126737,2126737,3122065,2126737,2126737,3142545,2126737,2126737,2126737,3171217,2126737,2126737,2126737,2888593,2126737,2126737,2925457,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,986,2126811,2126811,2126811,2126811,2126811,2126811,2126737,3191697,3195793,2126737,0,0,0,0,0,0,2388955,2126811,2126811,2126811,2421723,2126811,2126811,2449408,0,2535424,3031040,2859008,0,0,0,0,0,2179072,2449408,2179072,2535424,2126811,2737115,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2888667,2126811,2126811,2925531,2126811,2126811,2126811,2126811,2126811,2585563,2126811,2126811,2126811,2126811,2126811,2618331,2126811,2126811,2126811,2126811,2126811,2126811,2606043,2126811,2630619,2126811,2126811,2651099,2126811,2126811,2126811,2708443,2126811,3142619,2126811,2126811,2126811,3171291,2126811,2126811,3191771,3195867,2126811,2179072,2126811,2126737,2179072,2179072,2179072,2637824,2179072,2179072,2179072,2179072,2727936,2752512,2179072,2179072,2179072,2842624,2846720,2179072,3112960,3219456,2126737,2126737,3113873,3220369,2126811,2126811,3113947,3220443,0,0,0,0,0,0,0,415,415,0,0,0,0,0,415,0,3096576,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3223552,0,0,2126737,2126737,2417553,2126737,2126737,2126737,2126737,2929553,2126737,2126737,2126737,2999185,2126737,2126737,2126737,2126737,3060625,2126737,2126737,2126737,2126737,2933649,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,3130257,2126737,2126737,2126737,2519953,2126737,2126737,2126737,2126737,2589585,2126737,2614161,2646929,2126737,2126737,2696081,2757521,2126737,2446225,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2552721,2126737,2126737,2126737,2638737,2126737,2126737,2126737,2126737,2728849,2753425,2126737,2126737,2126737,2126737,2843537,2847633,2126737,2896785,2917265,2126737,2126737,2945937,2126737,2126737,2995089,2126737,3003281,2126737,2126737,3023761,2126737,3068817,3085201,2126737,3097489,2126737,2126737,2126737,2126737,2126737,2126737,2126737,3224465,0,0,2126811,2126811,2417627,2843611,2847707,2126811,2896859,2917339,2126811,2126811,2946011,2126811,2126811,2995163,2126811,3003355,2126811,2126811,3023835,2126811,3068891,3085275,2126811,3097563,2126811,2126811,2126811,2126811,2126811,2126811,2126811,3224539,2179072,2126811,2126737,2126737,2126737,3031953,2126737,2126811,2450395,2126811,2536411,2126811,2610139,2126811,2859995,2126811,2126811,2126811,2126811,2126811,2524123,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2601947,2126811,2515857,2126737,2126737,2126737,2544529,2548625,2126737,2126737,2597777,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2585489,2126737,2126737,2126737,2126737,2126737,2618257,2126811,2515931,2126811,2126811,2126811,2544603,2548699,2126811,2126811,2597851,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2655195,2679771,2761691,2765787,2786267,2855899,2970587,2126811,3007451,3154833,3167121,3175313,2397147,2401243,2126811,2126811,2442203,2126811,2470875,2126811,2126811,2126811,2520027,2126811,2126811,2126811,2126811,2126811,2638811,2126811,2126811,2126811,2126811,2728923,2753499,2126811,2126811,2126811,2126811,2126811,2126811,3179483,2179072,2126811,2126737,2179072,2179072,2126737,2126737,2126811,2126811,0,0,0,0,0,0,2510848,2514944,0,0,2678784,2760704,2764800,2854912,2969600,2179072,3006464,2179072,3018752,2179072,2179072,2179072,3149824,2126737,2429841,2438033,2126737,2487185,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2655121,2679697,2761617,2765713,2786193,2855825,2970513,2126737,3007377,2126737,3019665,2126737,2126737,2126737,2126737,3150737,2126811,2429915,2438107,2126811,2487259,2126811,2126811,2589659,2126811,2614235,2647003,2126811,2126811,2696155,2757595,2126811,2126811,2126811,2126811,2933723,2126811,2126811,2663387,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2802651,2814939,2126811,3019739,2126811,2126811,2126811,2126811,3150811,2179072,3051520,2126737,3052433,2126811,3052507,0,2490368,2498560,2126811,2556891,2565083,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,3138523,2940928,2941841,2941915,0,0,0,0,0,2748416,2879488,0,3180,0,0,0,0,0,0,0,647,0,0,0,0,0,0,0,0,0,2467,0,0,2470,0,0,0,2179072,2502656,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3010560,2179072,2179072,2126737,2126737,2126811,2126811,0,2486272,0,0,0,0,0,2678784,2854912,3006464,2503569,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,3011473,2126737,2126737,2126737,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2179072,2126811,2126737,2179072,2179072,2179072,2179072,2126737,2126737,2126737,2126737,2126811,2126811,2126811,2126811,0,0,0,0,0,0,0,0,0,0,0,2112,0,0,0,0,2503643,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,2126811,3011547,2126811,2126811,2126811,0,0,0,2179072,2126811,2126737,2179072,2179072,2179072,2179072,2179072,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2179072,2609152,2179072,2859008,2179072,2179072,2179072,3031040,2126737,2450321,2126737,2536337,2126737,2610065,2126737,2859921,3032027,2126811,2527232,0,0,0,0,0,2179072,2527232,2179072,2179072,2179072,2179072,2179072,2126737,2126737,2802577,2814865,2126737,2839441,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,2126737,3126161,2126737,2528145,2126737,2126737,2126737,2126737,2126737,3093393,2126811,2528219,2126811,2126811,2126811,2126811,2126811,3093467,0,0,0,0,0,782,0,0,0,0,0,0,541,843,541,541,541,541,541,1796,541,541,541,541,541,541,541,541,541,541,541,2822,541,541,541,541,3026944,0,0,0,2404352,2179072,2179072,2179072,2179072,3026944,2405265,2126737,2126737,2126737,2126737,3027857,2405339,2126811,2126811,2126811,2126811,3027931,0,2539520,0,2949120,2179072,2658304,2973696,2179072,2126737,2659217,2974609,2126737,2126811,2659291,2974683,2126811,0,2711552,256e4,2179072,2560913,2126737,2560987,2126811,0,2179072,2179072,3133440,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3207168,2179072,0,0,0,0,0,0,2464,0,0,0,0,0,0,0,0,0,324,398,0,0,0,324,0,2126737,2126811,0,2179072,2126737,2126811,0,2179072,2126737,2126811,2985984,2985984,2986897,2986971,0,0,0,0,0,0,3164,0,0,3167,0,0,0,0,0,0,0,1135,0,0,0,0,0,0,0,0,0,824,0,0,0,0,0,0,0,221184,221184,0,0,0,0,0,0,0,0,0,221184,221184,0,0,221184,221184,221184,0,0,0,0,0,0,0,221184,0,0,221184,221184,221184,221184,221184,221184,221184,221184,221184,221184,221184,221184,221184,221184,221184,221184,0,0,0,0,0,0,0,0,0,0,221184,0,221184,221184,221184,221184,221184,221184,221184,221184,221184,221184,1,12290,3,0,0,0,0,0,0,0,0,0,0,0,139264,300,0,303,0,0,0,303,0,304,0,0,0,304,0,0,0,304,69632,139682,0,0,0,0,0,65536,0,0,0,0,98304,0,0,0,53248,0,0,0,0,0,2662400,0,2813952,0,0,3133440,0,98304,0,0,0,0,0,0,0,0,0,0,0,0,111051,0,0,0,0,303,0,304,0,0,0,2473984,2478080,0,0,0,0,0,0,0,0,0,159744,159744,159744,159744,159744,159744,159744,159744,159744,159744,159744,159744,159744,159744,159744,159744,163840,3121152,2179072,2179072,3141632,2179072,2179072,2179072,3170304,2179072,2179072,3190784,3194880,2179072,914,0,0,0,0,0,0,3172,3173,0,0,0,0,0,0,0,0,0,665,0,0,668,0,0,0,0,914,0,2387968,2125824,2125824,2125824,2420736,2125824,2125824,2125824,2125824,2125824,2453504,2125824,2473984,2482176,2125824,2125824,2125824,2125824,2125824,2125824,2531328,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2605056,2125824,3190784,3194880,2125824,988,0,0,0,988,0,2387968,2125824,2125824,2125824,2420736,2125824,0,2125824,2125824,2125824,2125824,2125824,0,0,0,299,0,0,0,303,0,0,0,303,119198,73728,0,0,0,0,0,65536,0,3096576,2179072,2179072,2179072,2179072,2179072,2179072,2179072,3223552,914,0,2125824,2125824,2416640,2125824,2125824,2125824,2125824,2125824,2125824,2625536,2125824,2125824,2125824,2125824,2125824,2125824,2699264,2125824,2715648,2125824,2723840,2125824,2732032,2772992,2125824,3084288,2125824,3096576,2125824,2125824,2125824,2125824,2125824,2125824,2125824,3223552,988,0,2125824,2125824,2416640,225890,225890,225890,225890,225890,225890,225890,225741,225741,225741,225741,225741,225906,225741,225906,1,12290,3,0,0,0,0,0,0,0,90409,90409,90409,90409,0,94506,94506,90409,90409,94506,94506,94506,94506,94506,94506,94506,94506,94506,94506,94506,94506,94506,94506,94506,94506,1,2125824,237568,2125824,2125824,2125824,2125824,2125824,0,0,0,0,0,0,0,0,0,0,1222,0,0,0,0,0,249856,249856,249856,249856,249856,249856,249856,249856,249856,249856,249856,249856,249856,249856,249856,249856,0,0,0,0,0,0,0,0,0,217088,0,0,0,0,0,0,0,0,0,0,0,0,0,304,0,0,2125824,241664,2125824,2125824,2125824,2125824,2125824,0,0,0,0,0,0,0,0,0,0,1236,0,0,0,0,0,254414,254414,254414,254414,254414,254414,254414,254414,254414,254414,254414,254414,254414,254414,254414,254414,0,0,0,0,0,0,0,12290,0,0,0,2183168,0,0,270336,0,0,299,300,0,2134016,303,304,200704,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,687,2125824,0,2125824,2125824,2125824,2125824,2125824,0,0,180224,0,0,0,0,0,0,0,663,0,0,666,667,0,0,0,0,2940928,0,0,0,0,0,2748416,2879488,0,20480,0,0,0,0,0,0,0,679,0,0,0,0,0,0,0,0,0,1129,0,0,0,0,0,0,1,12290,2113826,0,0,0,0,0,0,296,0,0,0,296,0,0,0,0,0,0,3182,0,0,0,0,3187,0,0,0,0,0,0,0,69632,73728,0,0,0,0,0,65536,0,0,0,0,266240,0,0,0,0,0,0,0,0,0,0,0,266240,0,0,0,0,0,0,0,0,0,0,1,0,0,0,266240,0,0,0,0,0,0,0,0,0,0,0,0,0,2662400,0,2813952,12290,2113826,0,0,2183168,0,0,0,0,0,299,300,0,2134016,303,304,2125824,245760,0,0,2179072,2125824,2125824,2179072,2179072,2179072,2179072,2179072,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2584576,2125824,2125824,2125824,2125824,2125824,2617344,2125824,2125824,2125824,2125824,2125824,245760,2125824,2125824,2125824,2125824,2125824,0,0,0,0,0,0,0,0,0,0,1245,0,0,0,0,0,274432,274432,274432,274432,274432,274432,274432,0,0,0,0,0,274432,0,274432,1,12290,3,0,0,0,0,0,253952,0,0,0,253952,0,0,0,0,0,0,0,0,0,0,0,0,0,1155072,0,0,0,0,0,0,12290,3,78115,78115,293,0,0,0,0,0,299,300,0,0,303,304,563,563,587,587,587,587,0,2030,0,0,0,0,0,2032,0,0,0,0,0,0,3196,0,0,0,0,0,0,0,0,0,0,3186,0,0,0,3189,0,0,0,0,2034,0,0,0,0,0,2036,0,0,0,0,0,0,0,695,0,0,0,0,365,365,365,0,0,2485,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,266240,0,0,0,1678,0,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0,0,0,0,1669,0,0,0,0,0,0,0,0,2114,0,0,0,0,0,0,3395,541,541,541,541,3399,541,541,541,541,541,541,1346,541,541,541,541,541,541,1356,541,541,12290,3,78115,78456,293,0,0,0,0,0,299,300,0,0,303,304,541,588,564,564,564,564,564,564,564,588,588,588,541,588,588,588,588,588,588,588,588,564,564,541,564,588,564,588,1,0,0,0,0,2775,0,0,0,0,0,0,0,0,0,0,0,0,163840,0,0,0,1,12290,3,78116,293,0,0,0,0,0,0,0,0,0,0,0,0,167936,0,0,0,282624,282624,282624,282624,282624,282624,282624,282624,282624,282624,282624,282624,282624,282624,282624,282624,1,0,0,0,0,0,282624,282624,282624,282624,282624,282624,282624,282624,282624,282624,0,0,282624,0,0,0,0,0,0,0,0,0,0,1600,1601,0,0,0,0,282624,282624,282624,0,282624,282624,282624,282624,282624,0,0,0,0,0,0,0,0,0,254414,254414,254414,254414,254414,254414,254414,254414,1,2981888,2396160,0,3153920,3180,0,0,0,0,0,0,0,2740224,0,0,0,0,0,0,679,751,0,0,0,0,0,0,0,0,0,1144,0,365,365,0,1147,0,0,0,0,0,286720,286720,0,286720,286720,286720,286720,286720,286720,286720,286720,286720,0,0,0,0,0,0,0,286720,286720,286720,286720,286720,286720,286720,286720,286720,286720,286720,286720,286720,286720,286720,286720,0,3108864,3198976,0,0,3043328,0,3149824,2936832,0,2760704,3305,2437120,0,0,0,0,0,0,680,0,0,0,0,0,0,0,0,0,300,0,0,0,0,0,0,0,0,0,0,2875392,0,0,0,3386,0,0,0,0,0,0,2834432,2940928,0,0,0,0,0,2748416,2879488,0,3386,0,0,0,0,0,0,0,709,0,0,0,0,0,0,0,0,0,2048,0,0,0,0,0,0,0,0,0,309,0,0,0,0,0,308,0,308,309,0,308,308,0,0,0,308,308,309,309,0,0,0,0,0,0,308,408,309,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,781,0,0,0,309,413,0,0,69632,73728,0,0,0,0,0,65536,0,0,0,0,0,783,0,802,0,0,0,0,541,847,541,541,541,541,541,2830,2831,541,541,541,541,2834,541,541,541,541,541,541,541,3521,541,3523,541,541,3525,541,563,563,0,0,432,0,0,0,0,308,449,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,463,489,489,463,489,489,489,489,489,489,489,514,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,534,489,489,489,489,489,542,565,542,565,542,542,565,542,589,565,565,565,565,565,565,565,589,589,589,542,589,589,589,589,589,589,589,589,565,565,542,565,589,565,589,1,0,0,674,0,0,0,0,0,0,0,0,0,0,0,0,0,323,324,0,0,704,0,0,0,0,0,0,0,711,0,0,0,0,0,0,0,742,0,0,0,0,742,0,748,0,0,0,736,0,0,0,0,0,0,0,0,0,0,0,747,0,0,0,0,0,792,663,841,0,0,0,0,541,845,541,541,541,541,541,2217,541,541,541,541,541,541,541,541,541,541,541,1802,541,541,541,541,0,0,0,0,645,0,0,0,0,0,0,0,0,0,0,0,0,172032,0,0,0,0,0,0,0,0,765,0,0,768,0,0,0,0,774,0,0,778,0,0,0,0,0,0,3562,0,3564,541,541,541,541,541,541,541,541,541,3219,541,541,541,541,541,3224,0,0,785,0,0,0,0,789,0,0,0,0,0,0,0,793,0,0,736,0,793,0,0,0,0,648,0,0,0,0,0,0,0,807,808,0,0,0,0,808,0,0,807,0,0,0,0,0,755,0,0,816,817,0,0,0,793,0,0,0,0,0,0,0,0,0,0,0,0,221184,0,0,0,0,0,0,648,0,0,0,0,0,834,789,0,0,0,0,0,0,0,2139,0,0,0,0,0,0,0,0,0,1712,0,0,0,0,0,0,838,839,789,789,0,0,0,0,789,736,789,0,541,541,849,853,563,964,563,967,563,563,981,563,563,0,587,587,587,996,1e3,587,0,0,0,0,0,0,0,0,3180,3448,0,0,0,0,0,0,0,2465,0,0,0,0,0,0,0,0,0,2152,0,0,0,0,0,0,1093,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1135,0,0,0,0,1152,0,0,0,0,1157,0,0,0,0,0,0,0,822,0,816,0,664,0,0,0,0,0,0,0,0,1201,0,0,0,0,0,0,0,0,0,0,0,0,221184,0,221184,0,0,0,1253,0,0,0,0,0,0,0,0,0,0,0,0,0,339,340,341,541,541,1342,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2239,0,0,0,0,0,1596,0,0,0,0,0,0,0,0,0,0,0,0,233472,0,0,0,0,0,0,1640,0,0,0,0,0,0,0,0,0,0,0,0,354,355,356,357,1653,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1163,0,0,0,0,1669,0,0,0,0,0,0,1673,0,0,0,0,0,0,0,69632,73728,0,0,0,346,345,65536,344,0,1729,0,0,0,0,541,541,541,541,541,541,541,541,541,541,541,3327,541,541,1742,541,541,541,541,541,541,541,541,541,1755,541,541,541,541,541,541,541,2193,541,541,541,541,541,541,541,541,541,2557,541,541,541,541,541,541,541,541,541,1794,541,541,1797,541,541,541,541,541,541,541,541,541,541,1314,541,541,541,1318,541,541,1809,541,541,541,541,541,1814,541,541,541,541,541,541,541,1360,914,563,563,563,563,563,563,563,563,563,563,563,563,563,563,0,2328,1824,563,563,563,563,563,1831,563,563,563,563,563,1837,563,563,563,563,563,3093,563,563,563,563,563,563,563,563,563,3102,563,563,1892,563,563,563,563,563,563,563,563,563,563,1905,563,563,563,563,978,563,563,563,563,0,587,587,587,587,587,587,1997,587,587,587,587,587,587,587,587,587,1531,587,587,587,587,587,587,563,563,563,1910,563,563,563,563,563,563,563,26028,1920,587,587,587,0,1285,1469,1377,541,541,1339,541,541,563,563,1431,563,587,587,1927,587,587,587,587,587,1933,587,587,587,587,587,587,587,1529,587,587,587,587,587,587,587,587,1932,587,587,587,587,587,587,587,587,1494,587,587,587,587,587,587,587,587,587,1946,587,587,587,587,587,587,587,587,587,587,587,587,587,1513,587,587,563,563,2026,587,587,587,0,2030,0,0,0,0,0,2032,0,0,0,0,0,0,131072,0,131072,131072,131072,131072,0,131072,131072,131072,131072,131072,131072,131072,0,0,0,0,0,131072,0,131072,1,0,0,0,2042,0,0,0,0,0,0,0,0,0,0,0,0,365,365,365,0,0,2141,0,0,2148,0,0,0,0,0,0,0,0,0,0,0,0,237568,0,0,0,0,0,0,2140,541,541,541,541,541,541,541,541,541,541,541,2170,541,541,2173,541,541,541,541,541,541,2181,541,541,541,541,541,541,541,541,2841,541,541,541,541,541,541,541,541,1294,541,541,541,541,541,541,541,541,1327,541,541,541,1334,1336,541,541,541,541,2214,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2535,541,563,2258,563,563,563,563,563,563,2266,563,563,563,563,563,563,563,983,563,0,587,587,587,587,1001,587,563,2300,563,563,563,563,563,563,563,563,563,563,563,563,563,563,587,587,587,2345,587,587,587,587,587,587,2353,587,587,587,587,587,587,587,1950,587,587,587,587,587,587,587,587,1468,587,587,587,587,587,587,587,587,2387,587,587,587,587,587,587,587,587,587,587,587,587,587,587,541,587,563,2414,541,541,541,541,563,563,563,563,587,587,587,587,2030,0,2032,0,2034,0,2036,0,0,2428,0,0,0,0,0,0,0,0,0,0,1713,0,0,0,0,0,2436,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1179,2449,0,0,0,0,0,2453,0,0,0,0,0,0,0,0,0,0,1726,0,0,0,0,0,0,0,0,0,2477,0,0,0,0,0,0,0,0,0,0,0,0,245760,0,0,0,0,0,2501,0,0,0,0,0,0,0,0,0,0,0,0,0,386,338,0,541,541,541,2539,541,541,541,541,541,541,541,541,541,541,541,541,541,2198,541,541,0,0,0,563,563,563,563,563,563,563,563,563,2595,563,563,563,563,563,3238,563,563,563,563,563,563,563,563,563,563,2880,563,563,563,563,563,587,587,587,2661,587,587,587,587,587,587,587,587,587,587,587,2669,587,587,587,587,2714,587,587,587,587,587,587,541,587,563,541,541,2417,2418,563,563,2421,2422,587,587,2425,2426,0,1563,0,0,0,2735,0,0,0,0,0,0,2740,0,0,0,0,0,0,0,1102,1101,0,0,0,0,0,0,0,0,1724,0,0,0,0,0,0,0,0,1172,0,0,0,0,0,0,0,0,1187,0,0,0,0,0,0,1104,0,0,0,0,0,2763,0,0,0,0,0,0,0,0,0,0,0,2431,2432,0,0,0,0,0,0,0,0,2792,2793,0,0,0,0,0,0,0,0,0,0,2049,0,0,0,0,0,541,541,541,541,2829,541,541,541,541,541,541,541,541,541,541,2836,563,563,563,563,2876,563,563,563,563,563,563,563,563,563,563,563,0,2329,587,587,587,2884,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,1874,587,587,2933,587,587,587,587,587,587,587,587,587,587,587,587,587,1536,587,587,2955,541,2957,563,2959,587,0,0,0,0,0,0,0,0,0,0,0,0,0,0,541,541,541,541,541,541,541,587,3442,0,3444,0,0,0,0,0,3180,0,0,0,0,3452,0,0,0,0,0,796,0,0,0,0,0,0,0,0,0,0,0,0,796,0,0,0,0,3454,0,541,3457,541,3459,541,541,541,541,541,541,541,541,541,541,541,541,2585,0,0,0,563,587,3488,587,3490,587,587,587,587,587,587,587,587,587,587,587,1047,587,587,587,587,587,0,0,0,3505,0,0,0,0,0,0,0,3512,0,0,541,541,541,541,541,541,3462,541,541,541,541,541,541,541,541,541,3334,541,541,541,563,563,563,541,541,541,3517,541,541,541,541,541,541,541,541,541,541,563,563,563,563,563,563,563,563,563,563,3530,563,563,563,563,563,563,563,563,563,563,563,587,587,587,587,587,587,587,587,3544,587,587,587,587,587,587,587,587,587,587,587,0,0,0,0,541,541,541,541,563,563,310,311,312,0,0,0,0,0,0,0,0,0,0,0,0,0,669,0,0,0,0,0,421,0,0,0,0,450,0,0,0,0,0,0,0,0,304,304,304,304,0,304,304,304,0,0,0,0,450,450,421,450,450,450,450,450,450,450,450,450,450,450,450,450,450,533,450,533,533,533,450,533,533,533,533,450,543,566,543,566,543,543,566,543,590,566,566,566,566,566,566,566,590,590,590,543,590,590,590,590,590,590,590,590,566,566,616,621,590,621,627,1,960,563,563,563,563,563,563,563,563,0,587,587,587,587,587,587,587,3136,587,587,3138,587,587,587,587,587,0,0,0,0,1657,0,0,0,0,0,0,0,0,0,0,0,0,254414,0,0,0,1676,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1211,541,541,541,1810,541,541,541,541,541,541,541,541,541,541,541,1360,914,563,563,563,563,563,563,563,563,563,563,563,563,563,1378,0,0,2486,0,0,0,0,0,0,0,0,0,0,0,0,0,694,0,0,541,541,541,541,2528,541,541,541,541,2532,541,541,541,541,541,541,541,541,3218,541,541,541,541,541,541,541,541,2583,541,541,541,541,0,2586,0,0,0,0,563,563,563,563,563,563,2592,563,563,563,563,2596,563,0,587,587,587,587,587,78115,1079,0,0,0,0,0,0,0,0,0,225741,225741,225741,225741,225741,225741,225741,225741,225741,225741,225741,225741,225741,225741,225741,225741,0,0,0,0,0,0,0,2658,587,587,587,587,2662,587,587,587,587,587,587,587,587,587,587,2665,587,587,587,587,587,0,0,0,313,314,315,316,317,318,319,320,321,322,0,0,0,0,0,0,694,0,0,0,0,0,365,365,365,0,0,313,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2142208,0,0,316,0,0,0,0,0,0,0,0,0,0,0,0,0,730,0,0,0,423,431,433,422,431,0,313,431,451,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,464,485,490,490,501,490,490,490,490,490,490,490,490,516,516,529,529,530,530,530,530,530,530,530,530,530,530,530,516,530,530,530,530,530,544,567,544,567,544,544,567,544,591,567,567,567,567,567,567,567,591,591,591,613,591,591,591,591,591,591,591,614,615,615,613,615,614,615,614,1,734,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1238,0,0,0,0,767,0,0,0,0,0,0,0,0,0,0,0,0,266240,0,0,0,0,0,702,0,0,0,0,0,702,0,0,0,541,541,541,541,541,541,3322,541,541,541,541,541,541,541,541,1816,541,541,541,541,541,541,1360,563,563,563,968,563,563,563,563,563,0,587,587,587,587,587,587,587,3150,3151,3152,541,541,563,563,587,587,0,0,2963,0,0,0,0,0,0,0,0,3180,0,0,3389,0,0,0,0,0,1108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,308,309,0,1150,1108,0,0,0,0,0,0,0,0,0,0,0,0,0,1119,0,0,1212,0,0,0,0,0,0,0,0,0,0,0,0,0,1225,0,0,0,0,0,797,0,0,0,0,0,0,0,0,0,0,0,0,797,0,1360,914,563,563,1364,563,563,1368,563,563,563,563,563,563,563,563,985,0,587,587,587,587,587,587,1382,563,1387,563,563,1391,563,563,1394,563,563,563,563,563,563,563,984,563,0,587,587,587,587,587,1004,587,1460,587,587,587,587,587,587,587,587,1474,587,1479,587,587,1483,587,587,1486,587,587,587,587,587,587,587,587,587,587,587,587,587,1939,587,587,0,1692,0,1694,0,0,0,0,0,0,1701,0,0,0,0,0,0,0,2442,0,0,0,0,0,0,0,0,0,1173,0,0,0,0,0,0,541,541,1745,541,541,541,541,541,541,541,541,541,1757,541,541,541,541,541,541,2192,541,541,2195,541,541,541,541,541,541,541,1798,541,541,541,541,541,541,1806,541,541,1792,1793,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2824,541,0,563,563,563,563,563,563,563,563,563,563,563,563,563,1840,563,0,587,587,587,587,587,78115,1079,0,0,1083,1087,0,0,1091,587,587,587,587,1948,587,587,587,587,587,587,587,587,587,587,587,1478,587,587,587,587,587,587,587,587,1961,587,587,587,587,587,587,587,587,587,587,587,1533,587,587,587,587,0,2034,0,2036,0,0,0,0,0,0,2430,0,0,0,0,0,0,0,2454,0,0,0,0,0,0,0,0,0,2429,0,0,0,0,0,0,0,0,0,2476,0,0,0,0,0,0,0,0,0,0,0,0,365,365,365,702,0,0,0,2502,2503,0,0,0,0,0,0,0,0,0,0,0,0,1147355,0,0,0,587,587,2700,587,587,587,587,587,587,587,587,587,587,587,587,587,2004,587,587,0,0,2802,0,0,0,0,0,0,0,2806,541,541,541,541,541,541,541,2204,541,541,541,541,541,541,541,541,541,2220,541,541,541,541,541,541,541,2956,563,2958,587,2960,0,0,0,0,0,2966,0,0,0,0,0,0,0,69632,73728,0,0,0,350,348,65536,0,0,0,0,2970,0,0,0,0,0,0,0,0,0,0,0,0,365,365,208896,0,3035,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,1807,541,541,3050,3051,541,541,541,541,541,541,541,541,541,541,541,541,541,2223,2224,541,563,3090,563,3092,563,563,563,563,563,563,563,563,563,563,563,563,1415,563,563,563,3117,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,1484,587,587,3132,587,3134,587,587,587,587,587,587,587,587,587,587,587,1937,1938,587,587,587,0,3192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,309,308,541,541,541,541,3228,541,541,541,541,563,563,563,563,563,563,563,563,563,945,563,563,563,563,587,3503,0,3504,0,0,0,0,0,0,0,0,0,0,0,541,541,541,541,2810,3515,541,3516,541,541,541,3520,541,541,541,541,541,541,541,563,3528,563,3529,563,563,563,3533,563,563,563,563,563,563,563,563,587,3542,587,3543,587,587,587,3547,587,587,587,587,587,587,587,587,0,0,0,0,3673,541,541,541,3675,563,563,3676,587,587,587,3678,0,0,541,541,563,563,587,587,0,541,541,3204,541,541,541,541,541,541,541,541,541,541,541,541,541,2238,2586,0,324,324,374,0,0,0,0,0,0,0,0,0,0,0,0,0,1133,0,0,0,0,434,374,0,439,445,0,452,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,465,491,491,502,491,491,491,491,491,491,491,491,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,545,568,545,568,545,545,568,545,592,568,568,568,568,568,568,568,592,592,592,545,592,592,592,592,592,592,592,592,568,568,545,568,592,568,592,1,587,587,587,1019,587,587,587,587,587,587,587,587,587,587,587,587,1052,587,587,587,1122,0,1124,1125,0,0,0,1127,1128,0,0,0,0,0,0,0,0,334,0,0,0,0,0,334,0,0,0,1166,1167,0,0,0,0,0,0,0,0,0,0,0,0,400,0,0,0,0,0,1228,0,0,0,0,1233,0,0,0,0,0,0,0,0,0,365,300,0,0,0,0,0,0,0,0,0,1241,0,0,0,0,1244,0,1194,0,1113,0,1250,1127,0,0,0,0,0,0,0,0,0,541,541,1274,541,541,541,541,541,541,2203,541,541,541,541,541,541,541,541,541,541,1329,541,541,541,541,541,541,541,1322,541,541,1324,541,541,541,1328,541,541,541,541,541,541,541,541,3522,541,541,541,541,541,563,563,3068,563,563,563,563,563,563,563,563,2603,563,563,563,563,563,563,563,1360,914,563,563,1365,563,563,563,563,563,563,563,563,563,563,563,587,3427,587,587,3429,563,563,563,1405,563,563,563,563,563,563,563,1414,563,563,1416,563,0,587,587,587,1051,587,78115,1079,0,0,0,0,0,0,0,0,1134592,0,0,0,0,0,0,1134592,0,0,0,0,563,563,1420,563,563,563,563,563,563,563,563,563,563,563,563,563,1437,563,563,563,563,563,1444,563,563,563,563,563,26028,1360,988,587,587,1457,587,0,0,0,0,0,0,0,3447,3180,0,0,0,0,0,0,0,1237,0,0,541,541,1273,541,1276,541,0,0,0,1656,0,0,0,0,0,0,0,0,0,0,0,0,541,846,541,541,587,587,587,1993,587,587,587,587,587,587,587,587,587,587,587,587,1496,587,587,587,563,2025,587,587,587,2029,0,2030,0,0,0,0,0,2032,0,0,0,0,0,0,1134592,0,0,0,0,0,0,0,0,0,0,1134592,0,0,0,2034,0,0,0,0,0,2036,0,0,0,0,0,2039,0,2078,0,0,0,0,0,0,0,0,0,0,0,0,0,0,331,0,0,0,0,2092,0,0,0,0,0,0,0,0,0,0,0,0,643,0,0,0,541,2172,541,541,541,541,541,541,541,541,541,541,541,541,541,541,0,0,0,541,2188,541,541,541,541,541,541,541,541,541,541,541,541,541,541,0,2240,541,541,541,541,2229,541,2231,541,541,541,541,541,541,541,0,0,0,0,0,0,1146880,0,1146880,0,0,0,0,0,0,0,0,2617344,0,0,0,0,0,2789376,0,0,0,563,563,563,563,563,563,563,563,563,2253,563,563,563,563,0,0,0,0,0,0,587,2654,587,587,587,587,587,587,3135,587,587,587,587,587,587,587,587,587,1530,587,587,587,587,587,587,2257,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,1889,2273,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2272,563,563,563,563,2316,563,2318,563,563,563,563,563,563,563,0,0,0,0,0,0,587,587,587,587,587,587,587,587,587,587,587,587,587,587,541,563,2344,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,1516,2360,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,1517,587,587,587,587,2403,587,2405,587,587,587,587,587,587,587,541,587,0,0,0,0,0,0,0,3508,0,0,0,0,0,0,541,541,541,541,541,541,3400,541,541,541,2499,0,0,0,0,0,2504,0,0,0,0,0,0,0,0,0,0,2086,2087,0,0,0,0,541,541,2526,2527,541,541,541,541,541,541,541,541,541,541,541,541,541,2237,0,0,541,541,2566,541,541,541,541,541,541,541,541,541,541,541,541,541,541,3046,541,0,0,0,563,563,563,2590,563,2591,563,563,563,563,563,563,563,1411,563,563,563,563,563,563,563,563,1429,563,563,563,563,563,563,563,563,1916,563,563,26028,1921,587,587,587,0,0,0,2761,0,0,0,0,0,0,0,0,0,0,0,0,674,0,0,0,541,541,2837,541,541,541,541,541,541,541,2843,541,541,541,541,541,541,541,2232,541,541,2235,2236,541,541,0,0,563,563,563,2885,563,563,563,563,563,563,563,2891,563,563,563,563,0,0,2329,0,0,0,587,587,587,587,587,587,587,587,587,587,2341,587,587,587,2920,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,1519,587,587,587,587,3373,587,587,541,541,563,563,587,587,0,0,0,0,0,0,0,0,0,2968,563,587,587,587,587,587,587,3493,587,587,587,587,587,587,587,587,1034,587,587,587,587,587,587,587,326,327,328,0,0,0,0,0,0,0,0,0,0,0,0,0,1161,0,0,0,0,0,325,373,328,372,0,0,0,0,0,0,0,0,0,0,2111,0,0,0,0,0,325,0,0,372,372,402,0,328,0,0,0,0,0,0,0,0,0,365,339,293,0,0,0,0,0,0,325,0,327,0,0,0,453,466,466,466,466,466,466,466,479,466,466,466,466,466,466,466,466,466,466,466,466,492,492,466,492,492,507,509,492,492,507,492,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,535,518,518,518,518,518,546,569,546,569,546,546,569,546,593,569,569,569,569,569,569,569,593,593,593,546,593,593,593,593,593,593,593,593,569,569,546,569,593,569,593,1,0,0,658,659,0,0,0,0,0,0,0,0,0,0,670,671,0,689,0,0,0,0,0,0,0,0,0,0,365,365,365,0,0,0,0,0,800,0,0,0,0,0,0,0,0,0,0,0,0,718,0,720,0,0,0,0,0,0,727,0,0,0,731,0,0,0,0,0,0,1159168,417,417,0,0,0,0,0,417,0,0,784,0,786,0,0,0,0,0,0,0,0,0,0,0,0,759,0,0,0,0,0,798,0,803,0,806,0,0,0,0,803,806,0,0,0,0,0,0,741,0,0,0,0,0,0,0,0,0,0,0,0,806,806,803,0,0,0,0,0,0,0,786,0,798,0,815,0,0,0,0,0,802,0,0,783,0,0,0,0,802,0,0,0,0,0,0,0,802,0,0,0,0,806,0,707,0,0,823,0,0,0,0,0,823,823,826,0,0,0,786,0,0,0,0,0,835,0,0,0,0,0,0,0,2480,0,0,0,0,0,0,0,0,0,1100,0,0,0,0,0,0,0,0,0,0,784,0,0,0,835,815,835,0,541,541,850,541,541,541,541,541,3052,541,541,541,541,541,541,541,541,3060,541,541,541,541,541,3217,541,541,541,541,541,541,541,3222,541,541,541,541,541,2529,541,541,541,541,541,541,541,541,541,541,541,3043,541,541,541,541,856,541,541,869,541,541,880,541,885,541,541,893,896,901,541,909,563,563,966,969,974,563,982,563,563,0,587,587,587,997,587,1003,587,587,1016,587,587,1027,587,1032,587,587,1040,1043,1048,587,1056,587,0,0,0,0,0,0,3507,0,0,0,0,0,0,0,541,541,541,541,541,3031,541,541,541,541,0,0,0,1110,0,0,0,0,0,0,0,1117,0,0,0,0,0,0,0,69632,73728,0,0,0,421,0,65536,0,0,1137,1138,0,0,0,0,1142,0,0,0,365,365,0,0,0,0,0,0,769,0,0,0,775,776,0,0,0,0,0,0,0,69632,73728,0,0,0,374,0,65536,0,0,1165,0,0,0,0,0,0,0,0,0,0,0,0,0,0,515,522,0,0,1182,741,0,0,0,1134,0,0,0,0,0,0,0,0,0,367,0,0,0,0,0,0,541,541,541,1281,541,541,541,541,541,541,1296,541,541,541,1301,541,541,541,541,541,3229,541,541,541,563,563,563,563,563,563,563,941,563,563,563,563,563,563,1360,914,563,563,563,563,563,563,563,563,563,563,1373,563,563,563,563,563,3249,563,3251,563,563,563,563,563,563,563,563,1852,563,563,563,563,563,563,563,563,563,563,1388,563,563,563,1393,563,563,563,563,563,563,563,563,1451,26028,1360,988,587,587,587,587,587,1485,587,587,587,587,587,587,587,587,587,587,587,587,587,1500,1540,587,587,0,541,587,563,541,541,541,541,541,563,563,563,563,563,563,3477,563,563,563,563,563,563,563,563,1396,563,563,563,563,563,563,563,0,0,1607,1608,1609,0,1611,1612,0,0,0,0,1617,0,0,0,0,0,0,770,0,0,773,0,0,777,0,0,0,0,0,0,796,0,0,0,0,0,541,541,541,541,541,541,563,563,563,563,563,563,933,563,563,947,563,563,563,563,0,0,1639,0,0,1642,0,1644,0,0,0,0,0,1650,1651,0,0,0,0,0,805,0,0,692,0,0,672,0,692,0,810,0,1667,0,0,1669,0,0,0,0,1671,1672,0,0,0,0,0,0,0,2491,2492,0,0,0,0,0,0,0,0,0,2686976,2736128,0,0,2531328,2707456,0,0,0,0,0,1708,0,0,1711,0,0,0,0,0,1715,0,0,0,0,0,0,2134016,0,0,0,0,0,0,0,0,1138688,0,1719,1720,0,0,0,0,0,0,0,0,0,0,0,0,1711,0,0,0,1731,1585,1585,1733,541,1735,541,1736,1737,541,1739,541,541,541,541,541,1310,541,541,541,541,541,541,541,1317,541,541,541,541,541,1748,541,541,541,541,541,541,541,541,541,1759,541,1743,541,541,541,541,541,541,541,541,541,1756,541,541,541,541,541,541,541,3333,541,541,541,541,541,563,563,563,922,926,563,563,563,563,563,563,952,563,957,1760,541,541,541,541,1764,541,1766,541,541,541,541,541,541,541,541,541,889,541,541,541,541,907,541,1774,1775,1777,541,541,541,541,541,541,541,1785,1786,1787,541,541,1790,1791,541,541,541,541,541,541,541,1799,541,541,541,1803,541,541,541,541,541,541,2530,541,541,541,541,541,541,541,541,541,541,1315,541,541,541,541,1320,541,541,541,541,1811,541,541,541,541,541,541,541,541,541,1822,1360,914,563,563,563,563,563,563,563,563,563,563,563,563,563,1379,0,1827,563,1829,563,1830,563,1832,563,1834,563,563,563,1838,563,563,563,563,1390,563,563,563,563,563,563,563,563,563,563,563,2652,0,587,587,587,563,1859,563,1861,563,563,563,563,563,563,563,563,1869,1870,1872,563,0,587,587,1042,587,587,78115,1079,0,0,0,0,0,0,0,0,307,307,307,0,0,0,0,0,1907,563,563,563,563,563,563,563,563,563,1918,26028,0,1923,587,1925,587,1926,587,1928,587,1930,587,587,587,1934,587,587,587,587,587,587,587,3366,587,587,587,587,3367,3368,587,587,587,587,587,1947,587,587,587,587,1951,587,587,587,587,1955,587,1957,587,587,1976,1977,1978,587,587,1981,1982,587,587,587,587,587,587,587,1999,2e3,587,587,587,587,587,587,587,2015,2016,2017,541,2019,541,541,563,2023,1990,587,587,587,1994,587,587,587,587,587,587,587,2003,587,587,587,0,1288,1472,1380,541,541,541,541,541,563,563,563,563,3475,563,563,563,563,563,563,563,563,563,563,2267,563,563,563,563,563,563,2024,563,1982,587,2028,587,0,2030,0,0,0,0,0,2032,0,0,0,0,0,0,2134016,0,0,0,0,0,0,0,746,0,0,0,0,0,2043,0,0,2046,2047,0,0,0,2051,0,0,0,0,0,0,800,0,0,0,0,0,0,0,800,0,0,0,0,541,541,541,541,2090,0,0,0,0,2094,0,0,0,0,0,0,0,0,0,0,0,2456,0,0,0,0,0,0,0,0,1669,0,0,0,0,0,0,0,2113,0,0,2116,0,0,2119,0,0,0,0,0,0,2126,0,2128,0,0,0,0,0,0,0,69632,73728,0,370,370,0,0,65536,370,0,0,0,0,2137,0,0,0,0,0,0,0,0,0,0,0,0,1159168,0,0,0,0,2047,0,2147,0,0,0,0,0,0,0,0,0,0,0,0,1103,1104,1105,1106,0,2158,0,0,541,541,541,541,541,541,541,541,541,541,541,541,541,3329,541,541,541,2174,541,2176,541,541,541,541,541,541,2184,541,2186,541,541,541,541,541,3332,541,541,541,541,541,541,541,563,563,563,3069,563,563,563,563,563,563,563,2212,541,541,541,541,541,541,2219,541,541,541,541,541,541,541,541,541,1312,541,541,541,541,541,541,563,563,2259,563,2261,563,563,563,563,563,563,2269,563,2271,563,563,563,563,1422,563,563,563,563,563,563,563,563,563,563,1438,587,587,2346,587,2348,587,587,587,587,587,587,2356,587,2358,587,587,0,0,0,3634,0,3636,541,541,541,541,541,541,541,563,563,921,563,563,563,563,940,944,950,563,955,563,563,2261,541,2416,541,541,563,2420,563,563,587,2424,587,587,2030,0,2032,0,0,0,2452,0,0,0,0,0,0,0,0,0,0,0,0,1132,0,0,0,0,0,2461,0,0,0,0,0,2466,0,2468,2469,0,0,0,0,0,0,0,69632,73728,0,420,420,0,0,65536,420,0,0,0,0,2488,0,0,0,0,0,0,0,0,0,0,0,0,2179072,2179072,2179072,2179072,0,0,0,0,2516,2468,0,0,0,0,0,2521,0,0,0,541,541,541,541,541,3321,541,541,541,3325,541,541,541,541,541,541,1749,541,541,541,541,541,541,541,541,541,541,2558,541,541,541,541,541,2563,541,541,541,2568,541,541,541,541,541,541,541,2575,541,541,541,541,541,541,2542,541,2544,541,541,541,541,541,541,541,541,563,3411,563,563,3413,563,563,563,541,541,541,541,2580,541,541,541,541,541,541,541,541,0,2586,0,0,0,0,0,812,0,809,792,0,0,814,0,667,0,788,0,0,0,563,563,563,563,563,563,563,563,2594,563,563,563,563,0,2652,0,0,0,0,587,587,587,587,587,587,587,587,587,587,587,587,2342,587,563,2624,563,563,563,563,2628,563,563,563,2633,563,563,563,563,563,563,2629,563,563,563,563,563,563,2636,563,563,563,563,2640,563,563,563,563,563,563,563,563,2646,563,563,563,563,0,2652,0,0,0,0,587,587,587,2656,587,2657,587,587,2660,587,587,587,587,587,587,587,587,587,587,587,587,587,2383,587,587,587,587,2672,587,2674,587,587,587,587,587,587,587,587,587,587,587,1970,587,587,587,587,587,2699,587,587,587,587,587,587,587,2706,587,587,587,587,587,587,587,3375,541,3376,563,3377,587,0,0,0,587,587,2712,587,587,587,587,587,587,587,587,541,587,563,541,541,541,541,563,563,2800,2801,0,0,0,0,0,0,0,0,0,541,541,541,541,541,541,541,541,541,3402,2992,0,0,0,0,0,0,0,0,0,0,0,2992,0,0,0,0,0,0,840,0,0,0,0,0,541,541,541,541,541,541,2166,541,541,541,541,541,0,3022,0,0,0,3025,541,541,541,541,541,541,3032,541,541,541,541,541,541,2570,541,541,541,541,2574,541,541,541,541,541,541,1286,541,541,541,541,541,541,541,541,541,541,1818,541,541,541,541,1360,541,541,3036,541,541,541,541,541,541,541,3042,541,541,541,541,541,541,541,2531,541,541,541,541,541,541,541,541,541,563,3230,563,563,563,3233,563,3048,541,541,541,541,541,541,541,541,541,541,3057,3059,541,541,541,541,541,541,2582,541,541,541,541,541,541,0,2586,0,3062,541,3064,3065,541,563,563,563,563,563,563,3072,563,563,563,563,563,1425,563,563,563,563,563,563,563,563,563,563,2889,563,563,563,563,563,563,563,3076,563,563,563,563,563,563,563,3082,563,563,563,563,563,3088,563,563,3091,563,563,563,563,563,563,563,563,3098,3100,563,563,563,563,563,3342,563,563,563,563,563,563,563,563,563,563,2645,563,563,563,563,563,563,563,3104,563,3106,3107,563,587,587,587,587,587,587,3114,587,587,587,0,1544,1545,1546,541,541,1548,541,541,563,563,1552,563,587,587,3118,587,587,587,587,587,587,587,3124,587,587,587,587,587,587,1998,587,587,587,587,587,587,587,587,587,3551,587,587,3553,587,0,0,3130,587,587,3133,587,587,587,587,587,587,587,587,3140,3142,587,587,0,0,3633,0,0,0,541,541,3638,541,541,541,3642,563,587,587,3146,587,3148,3149,587,541,587,563,541,3154,563,3156,587,3158,0,0,0,0,0,3181,0,3183,0,0,0,0,0,0,0,3190,0,0,0,3193,3194,0,0,0,0,0,0,0,0,0,0,0,0,2200252,2200252,2200252,0,563,563,563,563,3237,563,563,563,563,563,563,563,563,563,563,563,1400,563,563,563,563,563,563,563,3248,563,563,563,563,563,563,563,563,3256,563,563,563,563,563,3352,563,563,563,563,587,587,587,587,587,3358,563,563,563,587,587,587,3261,587,587,587,587,587,587,587,3266,587,0,0,0,0,0,3506,0,0,3509,0,0,0,0,0,541,541,541,541,3662,541,563,563,563,563,3666,563,0,3310,0,0,3313,0,0,0,0,0,0,0,0,0,0,0,0,2200253,151552,2200253,0,587,587,587,3372,587,587,587,541,541,563,563,587,587,0,0,0,0,0,0,0,0,2967,0,0,0,0,0,0,3383,3384,0,3180,0,0,0,0,0,3392,0,0,0,0,0,1097,0,0,0,0,0,0,0,0,0,0,331,382,384,0,0,0,563,3417,563,563,563,563,563,563,563,563,563,587,587,587,587,587,587,587,3115,587,587,587,587,587,587,3433,587,587,587,587,587,587,587,587,587,541,563,3472,563,3474,563,563,563,563,563,563,563,563,563,563,563,563,3243,563,563,563,3470,563,563,563,563,563,563,563,563,563,563,563,563,563,563,3485,563,563,563,563,3532,563,563,563,563,563,563,563,563,563,587,587,3110,587,587,587,587,587,587,587,587,587,587,587,3546,587,587,587,587,587,587,587,587,587,3555,3556,0,0,0,3559,0,0,0,0,0,3565,3566,3567,541,541,541,3570,541,3572,541,541,541,541,3577,3578,3579,563,563,563,3582,563,3584,563,0,587,587,1044,587,587,291,1079,0,0,1082,1086,0,0,1090,563,563,563,3589,3590,3591,3592,587,587,587,3595,587,3597,587,587,587,587,587,1464,587,587,587,1473,587,587,587,587,587,587,1949,587,587,587,587,587,587,587,587,587,2949,587,587,587,541,587,563,587,3602,0,0,0,0,0,0,0,0,0,0,541,541,541,541,541,541,1738,541,541,541,563,3644,563,563,563,3648,563,587,587,3650,587,587,587,3654,587,0,0,0,0,0,0,0,0,3180,0,3449,0,0,0,0,0,0,0,69632,73728,266240,0,0,0,0,65536,0,0,0,0,329,330,0,0,0,0,0,0,0,0,0,0,0,349,0,0,0,0,0,369,0,0,0,0,0,0,0,0,0,0,0,0,0,0,686,0,0,0,0,369,0,0,0,377,379,0,0,0,0,0,0,0,0,1099,0,0,0,0,0,0,0,0,1115,0,0,0,0,0,0,0,0,0,3185,0,0,0,0,0,0,0,0,412,0,0,0,412,69632,73728,0,369,369,0,424,65536,369,0,0,0,369,424,499,503,499,499,508,499,499,499,508,499,424,424,0,330,424,0,0,424,424,0,0,0,0,0,0,0,0,1156,0,0,0,0,0,0,0,0,664,0,0,0,0,0,0,0,0,680,681,0,0,0,0,0,0,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,547,570,547,570,547,547,570,547,594,570,570,570,570,570,570,570,594,594,594,547,594,594,594,594,594,594,594,594,570,570,547,570,594,570,594,1,587,587,587,1020,587,587,587,587,587,587,587,587,587,587,587,587,1954,587,587,587,0,0,1109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1215,0,0,0,0,0,0,0,0,0,0,0,1226,541,1279,541,541,541,541,541,1291,541,541,541,541,541,541,541,541,541,1351,541,541,541,541,541,541,1360,914,563,563,563,563,563,563,563,563,1371,563,563,563,563,563,563,2643,563,563,563,563,563,563,563,563,563,1866,563,563,563,563,563,563,1383,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2286,587,587,1992,587,587,587,587,587,587,587,587,587,587,587,587,587,2411,541,587,563,563,3677,587,587,587,0,0,541,541,563,563,587,587,0,541,3203,541,541,541,3206,541,541,541,541,541,541,541,541,541,541,1313,541,541,541,541,541,425,425,0,0,425,440,0,425,425,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,467,493,493,467,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,493,548,571,548,571,548,548,571,548,595,571,571,571,571,571,571,571,595,595,595,548,595,595,595,595,595,595,595,595,571,571,548,571,595,571,595,1,0,1213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,732,0,0,0,0,0,1695,0,0,0,0,0,0,0,0,0,0,0,360,0,0,0,0,0,0,0,0,2093,0,0,0,0,0,0,0,0,0,0,0,365,365,0,0,0,2157,0,0,0,541,541,541,541,541,541,541,541,541,541,541,541,3328,541,2201,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2200,563,2415,541,541,541,2419,563,563,563,2423,587,587,587,0,0,0,0,0,0,541,541,541,541,541,541,541,563,3067,563,563,563,563,563,563,563,563,563,3253,563,563,563,563,563,563,0,2460,0,0,0,0,0,0,0,0,0,0,0,0,0,0,748,0,0,0,0,0,2791,0,0,0,0,0,0,0,0,0,0,0,365,365,1146,0,0,2943,587,587,587,587,587,587,587,587,587,587,587,587,541,587,563,541,541,0,0,0,0,2971,0,0,0,2975,0,0,0,0,0,2981,0,0,0,0,0,1128,0,0,0,0,0,1233,0,0,0,1265,0,0,0,2994,0,2996,0,0,0,0,0,0,0,0,3004,0,0,0,0,0,1169,0,1171,0,0,0,0,1176,0,0,0,0,0,0,1643,0,0,0,0,0,0,0,0,0,0,2520,0,0,0,0,541,0,0,0,0,3009,0,0,0,0,0,0,0,0,0,0,0,383,0,0,0,387,541,3063,541,541,541,3066,563,563,563,563,563,563,563,563,563,563,3083,563,563,563,563,563,563,563,3105,563,563,563,3108,587,587,587,587,587,587,587,587,587,1509,587,587,587,587,587,587,3144,587,587,3147,587,587,587,541,587,563,541,541,563,563,587,587,0,0,3295,0,0,0,0,0,0,0,0,2766,0,0,0,0,0,0,0,0,2151,0,0,0,0,0,0,0,0,2506,0,0,0,0,0,2512,0,0,0,0,0,0,3195,0,0,0,0,0,0,0,0,0,0,0,2782,0,0,0,0,541,541,541,541,3216,541,541,541,541,541,541,541,3221,541,3223,541,541,541,541,541,3408,541,541,3410,563,563,563,563,3414,563,563,563,563,1446,1447,563,563,563,26028,1360,988,587,587,587,587,587,587,3671,0,0,0,541,541,541,3674,563,563,563,563,563,587,587,3260,587,587,587,587,587,587,587,587,587,587,3274,587,587,587,587,587,587,3280,587,587,587,587,587,587,587,587,587,587,587,541,587,563,541,2722,563,3350,563,563,563,563,563,563,563,563,587,587,587,587,587,587,587,587,3655,587,587,587,587,3363,587,587,587,587,587,587,587,587,587,3369,587,0,0,0,541,587,563,541,541,541,541,541,563,563,563,563,563,3071,563,563,563,563,563,0,0,0,0,541,541,3660,3661,541,541,563,563,3664,3665,563,563,563,563,1423,563,563,1430,563,563,563,563,563,563,563,563,2631,563,563,563,563,563,563,563,587,587,3668,3669,587,587,0,0,0,0,541,541,541,541,563,563,563,924,928,931,563,939,563,563,563,954,956,959,0,0,690,691,0,0,0,0,696,0,0,0,365,365,365,0,0,0,0,0,1185,0,0,0,0,0,0,0,0,0,0,0,3180,0,0,0,0,0,0,829,0,0,0,0,0,0,0,0,0,758,0,0,0,0,0,0,758,0,0,0,0,0,758,758,910,541,563,563,563,563,927,563,563,563,563,563,563,563,563,563,1432,563,563,1436,563,563,563,983,0,587,587,587,587,1057,78115,1079,0,0,0,0,0,0,0,0,1220,0,0,0,0,0,0,0,0,0,282624,282624,282624,282624,282624,282624,282624,282624,587,1521,587,587,587,587,587,587,587,587,587,587,587,587,587,587,1514,587,0,0,0,1721,0,0,0,0,0,0,0,0,0,0,0,0,1193,0,0,0,0,2040,0,0,0,0,0,0,0,0,0,0,0,0,0,0,749,0,2171,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2211,3288,541,3290,563,3292,587,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3514,468,468,468,486,494,494,486,494,494,494,494,494,494,494,494,519,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,536,527,527,527,527,527,549,572,549,572,549,549,572,549,596,572,572,572,572,572,572,572,596,596,596,549,596,596,596,596,596,596,596,596,572,572,549,572,596,572,596,1,795,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1652,0,818,0,0,0,795,0,0,818,0,0,0,0,0,818,818,0,0,0,0,795,0,0,0,0,0,0,836,791,0,0,836,857,541,865,541,541,541,541,541,541,541,541,541,541,541,541,541,541,3527,563,911,541,563,563,563,563,563,930,563,938,563,563,563,563,563,563,1850,563,563,563,563,563,563,563,563,563,0,587,587,587,587,587,587,587,1012,587,587,587,587,587,587,587,587,587,587,587,587,587,1058,984,0,587,587,587,1077,1058,78115,1079,0,0,0,0,0,0,0,0,1243,0,0,0,0,0,0,0,0,1259,0,0,0,1263,0,0,0,0,0,0,0,1139,1140,0,0,0,0,0,365,365,0,0,0,0,0,0,1113,0,0,0,0,0,0,0,0,0,0,2071,0,0,0,0,0,1180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1705,1340,541,541,1344,541,541,541,541,541,1350,541,541,541,1357,541,541,541,541,541,1812,541,541,541,541,541,541,541,541,541,1360,1403,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2638,563,563,1442,563,563,563,1449,563,563,26028,1360,988,587,587,587,587,587,587,3272,587,587,587,587,587,587,587,587,3278,587,587,1487,587,587,587,587,587,587,587,1495,587,587,587,587,587,587,2365,587,587,587,587,587,587,587,587,587,2691,587,587,587,587,587,587,587,587,587,1524,587,587,1528,587,587,587,587,587,1534,587,587,587,587,587,1492,587,587,587,587,587,587,587,587,587,587,1510,587,587,587,587,587,1541,587,587,0,541,587,563,541,541,541,541,541,563,563,563,563,563,3476,563,563,563,3480,563,563,563,563,563,563,2863,563,563,2867,563,563,563,563,563,563,1409,563,563,1413,563,563,563,563,563,563,1448,563,563,26028,1360,988,587,587,587,587,0,0,0,1595,0,0,0,0,0,0,0,0,0,0,0,0,1223,0,0,0,0,0,1655,0,0,0,0,0,0,0,0,0,1664,0,0,0,0,0,0,1126,0,0,0,1130,1131,0,0,0,0,0,0,0,2818048,2846720,0,2916352,0,0,3002368,0,0,1718,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2053,1702,0,0,0,0,0,541,541,541,541,541,541,541,541,541,541,3326,541,541,541,563,563,563,1893,563,563,563,563,563,563,1901,563,563,563,563,563,563,2887,563,563,563,2890,563,2892,563,563,563,587,1944,587,587,587,587,587,587,587,587,587,587,587,587,587,587,1940,587,587,1974,587,587,587,587,1980,587,587,587,587,587,587,587,587,1989,2007,2009,587,587,587,587,587,541,587,563,541,541,541,541,563,563,563,563,587,587,587,587,2030,0,2032,0,0,2079,0,0,0,2082,0,0,0,0,0,2088,0,0,0,0,0,0,1141,0,1143,0,0,365,365,0,0,0,0,0,0,1154,0,0,0,0,0,1160,0,1162,0,2104,0,0,0,0,0,0,0,0,0,0,0,0,0,2115,0,0,0,0,0,1192,0,0,0,0,0,0,0,0,0,0,0,176128,176128,176128,176128,176128,176128,176128,0,0,563,563,563,563,563,563,2250,563,563,563,563,563,563,563,1851,563,563,563,563,1855,563,563,563,587,587,587,587,2349,587,587,587,587,587,587,587,587,587,587,587,1985,587,587,1988,587,2262,541,541,541,541,563,563,563,563,587,587,587,587,0,0,0,0,0,2732,0,2450,0,0,0,0,0,0,0,0,2455,0,0,2458,0,0,0,0,0,0,2134016,0,0,0,0,0,0,57344,0,0,0,0,0,0,2748,0,0,0,0,0,0,0,0,0,0,192972,192972,192972,192972,192972,192972,192972,0,0,0,0,2462,0,0,0,0,0,0,0,0,0,0,0,541,541,541,2809,541,2473,0,0,0,0,0,0,0,2481,0,0,0,2483,0,0,0,0,0,0,1170,0,0,0,0,0,0,0,0,0,0,2989,0,0,0,0,0,0,2500,0,0,0,0,0,0,0,0,0,0,2510,0,0,0,0,0,0,1186,0,0,0,1191,0,0,0,0,1107,0,0,0,0,0,0,0,0,0,0,0,758,0,0,0,0,0,0,0,2524,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2536,541,541,2552,541,541,541,541,541,541,541,541,541,541,541,541,541,905,541,541,2564,541,541,541,541,541,541,2571,541,541,541,541,541,541,541,541,541,1768,541,541,541,541,541,541,541,2578,541,541,541,2581,541,541,541,541,541,541,541,0,0,0,0,0,0,1203,0,0,0,0,0,0,0,0,0,0,813,0,0,0,0,0,0,0,0,563,2588,563,563,563,563,563,563,563,563,563,563,563,1903,1904,563,563,563,2611,563,563,563,563,563,563,2616,563,563,563,563,563,563,563,2622,587,587,587,587,2702,587,587,587,587,587,587,587,587,587,587,2710,587,587,587,2713,587,587,587,587,587,587,587,2718,2719,2720,541,541,541,541,541,2177,541,541,541,541,541,541,541,541,541,541,541,541,2845,541,541,541,2758,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2103,0,2773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1120,0,0,0,2789,0,0,0,0,2794,0,0,0,2796,0,0,0,0,0,0,0,69632,73728,316,317,317,422,423,65536,430,541,541,541,541,2814,541,541,541,541,541,541,541,541,541,541,541,541,1333,541,541,541,541,541,2848,541,541,541,541,541,541,0,0,563,563,563,2856,563,0,587,587,1047,587,587,78115,1079,0,0,0,0,0,0,0,0,1159168,365,0,0,0,0,0,0,563,563,563,563,2861,563,563,563,563,563,563,563,563,563,563,563,2294,563,563,563,563,563,563,563,563,2897,563,563,563,563,563,563,0,0,587,587,587,587,587,587,587,2338,587,587,587,587,587,587,587,3122,587,587,587,587,587,587,587,587,1036,587,587,587,587,1054,587,587,2905,587,587,587,587,587,2910,587,587,587,587,587,587,587,587,587,1935,587,587,587,587,1941,587,3006,0,0,0,0,3010,0,0,0,0,3015,0,0,0,0,0,0,0,2749,0,0,0,0,0,0,0,0,0,697,698,0,365,365,365,0,3191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2145,3300,0,0,0,0,0,0,0,0,0,0,3180,0,0,0,0,0,0,0,69632,73728,163840,0,0,0,0,65536,0,563,563,563,3340,563,563,563,563,563,563,563,563,563,563,563,563,2283,563,563,563,563,563,563,3351,563,563,563,563,563,563,587,587,587,587,587,587,587,587,587,587,587,587,587,3359,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,1942,3370,587,587,587,587,587,587,541,541,563,563,587,587,0,0,0,0,3297,0,0,0,0,0,0,0,0,0,3394,0,541,541,541,541,541,541,541,541,541,541,541,541,3211,541,541,3486,587,587,587,587,587,587,587,587,3495,587,3497,3498,587,3500,587,0,0,0,541,587,563,541,541,541,904,541,563,563,563,977,3502,0,0,0,0,0,0,0,0,0,0,0,0,0,0,541,541,541,854,541,541,3612,541,3613,541,541,541,563,563,563,563,563,563,3619,563,0,996,1075,1041,587,587,78115,1079,0,0,1081,1085,0,0,1089,3620,563,563,563,563,587,587,587,587,587,587,3627,587,3628,587,587,0,3603,0,0,0,0,0,0,0,0,541,541,3610,541,563,563,587,587,587,587,0,0,541,541,563,563,587,587,3683,3684,3685,3686,0,541,563,587,0,541,563,587,0,541,563,587,0,0,0,0,0,0,0,0,3180,0,0,0,0,0,0,0,550,597,573,573,573,573,573,573,573,597,597,597,550,597,597,597,597,597,597,597,597,573,573,550,573,597,573,597,1,0,0,0,737,0,0,0,0,0,0,0,0,0,0,0,0,1237,0,0,0,0,0,2041,0,0,0,0,0,0,0,0,0,0,0,0,0,1194,1196,0,403,0,0,0,0,381,0,69632,73728,0,0,0,0,426,65536,0,0,0,0,0,1202,0,0,0,0,0,0,0,0,0,0,0,2444,2445,0,0,2448,426,426,0,0,426,0,446,426,426,469,469,469,476,469,469,469,469,469,469,469,469,469,476,469,469,469,469,469,469,469,469,483,469,495,495,469,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,538,551,574,551,574,551,551,574,551,598,574,574,574,574,574,574,574,598,598,598,551,598,598,598,598,598,598,598,598,574,574,551,574,598,574,598,1,0,0,0,0,660,661,0,0,0,0,0,0,0,0,0,0,0,3001,0,0,0,0,0,0,0,0,661,0,0,0,0,0,0,0,0,0,0,0,661,0,0,0,0,0,827,0,0,0,661,0,0,0,0,0,0,0,0,0,0,0,3176,0,0,0,0,0,0,0,729,0,742,661,0,0,0,0,0,541,844,541,541,541,541,541,2191,541,541,541,541,541,541,2197,541,2199,541,541,859,541,541,541,541,541,541,541,541,541,541,897,541,541,541,541,541,541,2817,541,2819,541,541,541,541,541,541,541,541,2572,541,541,541,541,541,541,541,541,1349,541,541,541,541,541,541,541,541,1752,541,541,541,541,541,541,541,541,1767,541,541,541,541,541,541,541,541,1782,541,541,541,541,541,541,541,541,1815,1817,541,541,541,541,541,1360,563,563,563,970,563,563,563,563,563,0,587,587,990,587,587,587,587,587,1526,587,587,587,587,587,587,587,587,587,587,1953,587,587,587,587,587,1006,587,587,587,587,587,587,587,587,587,587,1044,587,587,587,587,587,587,3285,587,587,587,587,587,587,541,587,563,1094,0,0,0,0,0,0,0,0,0,1101,1102,0,0,0,0,0,0,0,69632,73728,167936,0,0,0,0,65536,0,0,0,0,1229,0,0,0,0,0,0,0,0,0,0,0,0,1247,0,0,0,0,0,0,0,1102,0,0,0,0,1260,1261,0,0,1101,0,0,0,0,0,0,2134756,0,0,0,0,0,0,0,0,0,0,1116,0,0,0,0,0,541,1306,541,541,541,541,541,541,541,541,541,541,541,541,541,541,0,2241,1360,914,563,1363,563,563,563,563,563,563,563,563,563,563,563,1377,1384,563,563,563,563,563,563,563,563,563,1398,563,563,563,563,563,563,3079,563,563,563,563,563,563,563,563,563,0,587,587,989,587,587,587,1418,563,563,563,563,563,563,563,1431,563,563,563,563,563,563,563,1897,563,563,563,563,563,563,563,563,1395,563,563,563,563,563,563,563,587,587,1523,587,587,587,587,587,587,587,587,587,587,587,1537,587,0,0,0,541,587,563,541,541,541,1067,911,563,563,563,1072,563,587,587,1523,587,587,1079,0,0,0,0,0,0,0,0,0,0,2781,0,0,0,0,0,541,541,541,1746,1747,541,541,541,541,1754,541,541,541,541,541,541,541,1290,541,1295,541,541,1299,541,541,1302,541,541,541,541,1795,541,541,541,541,541,541,541,541,541,541,541,541,1335,541,541,541,1825,563,563,563,563,563,563,563,563,563,563,563,563,563,563,1841,1842,563,563,563,563,1849,563,563,563,563,563,563,563,563,563,563,3347,563,563,563,563,3348,1890,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2649,587,1945,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2372,587,587,1959,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2384,2385,587,587,587,587,2012,587,587,541,587,563,541,541,541,541,563,563,587,587,2961,0,0,2964,2965,0,0,0,0,0,0,0,2505,0,0,0,0,0,0,0,0,0,387,0,0,0,0,0,387,0,0,0,2054,0,2055,0,0,0,0,0,0,0,0,0,2064,541,541,541,541,2216,541,541,541,541,541,541,2221,541,541,541,541,541,541,1285,1292,541,541,541,541,541,541,541,541,541,1800,541,541,541,1805,541,541,541,2226,541,541,541,541,541,541,541,541,541,541,541,541,0,0,563,563,563,563,563,563,563,563,2302,563,563,563,563,563,563,2307,563,563,563,563,563,563,3080,563,563,563,563,563,563,563,563,563,1883,563,563,563,563,563,563,563,2313,563,563,563,563,563,563,563,563,563,563,563,563,0,0,587,587,587,587,587,587,2389,587,587,587,587,587,587,2394,587,587,587,587,587,587,2377,587,587,587,587,587,587,587,587,587,1952,587,587,587,587,1956,587,587,2400,587,587,587,587,587,587,587,587,587,587,587,587,541,587,0,0,0,541,587,563,541,541,895,541,541,563,563,968,563,0,587,587,587,587,587,78115,1079,0,0,1082,1086,0,0,1090,0,2437,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1178,0,587,2671,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2931,587,0,0,0,2736,0,0,0,0,0,0,0,0,0,0,0,0,1588,1589,0,0,2787,0,0,0,0,0,0,0,0,0,0,0,2797,0,0,0,0,0,0,1204,0,0,0,0,0,0,0,0,0,0,1631,0,0,0,0,0,541,541,541,2813,541,541,541,541,541,541,2821,541,541,541,541,541,541,541,2555,541,541,541,541,541,541,541,2562,563,563,563,2860,563,563,563,563,563,563,2868,563,563,563,563,563,563,3094,563,563,3096,563,563,563,563,563,563,1880,1881,1882,563,563,1885,1886,563,563,563,0,0,3008,0,0,0,0,0,0,0,0,0,0,0,0,0,1197,0,0,541,541,3227,541,541,541,541,541,541,563,563,563,563,563,563,563,3073,563,563,563,3571,541,3573,541,541,541,563,563,563,563,563,563,563,3583,563,3585,0,0,0,0,541,3659,541,541,541,541,563,3663,563,563,563,563,563,1878,563,563,563,563,1884,563,563,563,563,563,563,2864,563,2866,563,563,563,563,563,563,563,3354,563,563,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,1057,587,3667,587,587,587,587,0,0,0,0,541,541,541,541,563,563,915,563,563,563,563,563,563,946,563,563,563,563,563,1427,563,563,563,563,563,563,563,563,563,563,3535,563,563,563,563,563,563,587,587,587,587,3112,587,587,587,587,3116,470,470,470,470,454,454,470,454,454,454,454,454,454,454,454,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,552,575,552,575,552,552,575,552,599,575,575,575,575,575,575,575,599,599,599,552,599,599,599,599,599,599,599,599,575,575,552,575,599,575,599,1,541,860,541,541,874,541,541,541,541,541,541,541,541,541,541,541,541,1770,541,541,541,1007,587,587,1021,587,587,587,587,587,587,587,587,587,587,587,587,1971,587,587,587,0,1123,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1184,1184,1251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2156,0,0,0,1268,0,0,0,0,0,0,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,1360,541,541,541,1323,541,541,541,541,541,541,541,541,541,541,541,541,541,2534,541,541,541,1341,541,541,541,541,541,1348,541,541,541,541,541,541,541,541,541,2234,541,541,541,541,0,0,1440,563,563,563,563,563,563,563,563,26028,1360,988,587,587,587,587,587,587,3365,587,587,587,587,587,587,587,587,587,2936,587,587,587,2939,587,2941,587,587,587,587,587,1525,587,587,587,587,587,1532,587,587,587,587,587,587,2392,587,587,587,587,587,587,587,587,587,1472,587,587,587,587,1482,587,563,587,587,587,1557,587,1079,0,1561,0,0,0,1567,0,0,0,0,0,0,1218,1219,0,0,0,0,0,0,0,0,0,1235,0,0,0,0,0,0,1573,0,0,0,1579,0,0,0,0,0,0,0,0,0,0,0,662,0,0,0,0,0,0,0,0,0,0,0,541,541,541,1779,541,541,541,541,541,541,541,541,541,541,541,541,541,2548,541,541,563,1843,563,563,563,563,563,563,563,563,563,1854,563,563,563,563,563,1879,563,563,563,563,563,563,563,563,563,563,3344,563,563,563,563,563,563,563,563,1865,563,563,563,563,563,563,563,2065,2066,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1210,0,2117,0,0,2120,2121,0,0,0,0,0,2127,0,0,0,0,0,0,0,2765,0,0,0,0,0,0,0,0,0,550,573,550,573,550,550,573,541,2213,541,541,541,541,2218,541,541,541,541,541,541,541,541,541,541,2182,541,541,541,541,541,2299,563,563,563,563,2304,563,563,563,563,563,563,563,563,563,563,1917,563,26028,0,587,587,587,2386,587,587,587,587,2391,587,587,587,587,587,587,587,587,587,587,2001,587,587,587,587,587,2006,541,541,541,3037,541,541,541,541,541,541,541,541,541,541,541,541,541,2846,541,541,563,563,3077,563,563,563,563,563,563,563,563,563,563,563,563,563,1887,1888,563,587,587,587,3119,587,587,587,587,587,587,587,587,587,587,587,587,1986,587,587,587,563,563,3247,563,563,563,563,563,563,563,563,563,563,563,563,563,2296,563,563,587,0,0,0,3445,0,0,0,0,3180,0,0,0,0,0,0,0,1242,0,0,0,0,0,0,0,0,0,380,0,0,0,0,0,0,0,0,541,541,541,541,3460,541,541,541,541,541,541,541,541,541,541,2207,541,541,541,541,541,563,587,587,587,587,3491,587,587,587,587,587,587,587,587,587,587,2354,587,587,587,587,587,587,563,563,563,563,3623,587,587,587,587,587,587,587,587,587,587,587,2395,587,587,587,587,587,3631,0,0,0,0,0,0,541,541,541,541,541,541,541,563,563,920,563,563,563,563,563,563,949,951,563,563,563,563,563,3421,563,563,563,3425,563,587,587,587,587,587,587,587,587,587,587,587,587,587,587,3501,388,390,340,0,0,0,0,0,0,339,0,0,340,0,0,0,0,0,0,1598,0,0,0,0,0,0,0,0,1604,0,0,0,387,0,0,0,69632,73728,0,0,0,0,0,65536,0,0,0,0,0,1217,0,0,0,0,0,0,0,1224,0,0,0,0,0,347,0,0,0,0,0,0,0,0,0,0,0,3316,0,0,0,0,0,0,435,339,0,0,447,0,0,471,471,471,471,471,471,471,471,471,553,576,553,576,553,553,576,471,482,471,471,471,500,477,500,500,500,500,500,500,500,500,471,471,477,471,471,471,471,471,471,471,471,471,471,471,481,481,471,482,471,471,553,600,576,576,576,576,576,576,576,600,600,600,553,600,600,600,600,600,600,600,600,576,576,553,576,600,576,600,1,0,0,750,0,0,0,0,0,0,0,0,0,0,0,0,0,1603,0,0,0,0,0,0,663,0,788,0,0,0,0,0,0,0,792,0,0,0,0,0,1231,0,0,0,0,0,0,0,0,0,0,0,2153,0,0,0,0,0,0,0,801,0,0,0,0,0,809,0,0,0,0,706,0,0,0,0,0,0,0,0,715,0,717,0,828,0,0,0,663,831,0,788,0,0,0,0,0,837,0,0,0,0,0,1597,0,0,0,577536,0,0,1602,0,0,0,0,0,0,1257,0,0,0,0,0,0,0,0,0,0,2508,0,0,0,0,0,541,861,541,541,875,541,541,541,541,888,541,541,541,541,906,541,541,541,541,541,3519,541,541,541,541,541,541,541,541,563,563,563,923,563,929,563,563,942,563,563,953,563,958,961,563,563,563,563,979,563,563,563,0,587,587,991,587,587,587,587,587,1962,587,587,587,587,587,587,587,587,587,587,3287,587,587,587,541,587,563,1008,587,587,1022,587,587,587,587,1035,587,587,587,587,1053,587,587,587,587,587,2945,587,587,2948,587,587,2951,587,2952,2953,2954,0,0,0,0,1216,0,0,0,0,1221,0,0,0,0,0,0,0,1258,0,0,0,0,0,0,0,0,0,365,299,0,0,0,0,0,0,1144,0,0,1256,0,0,0,0,0,0,0,0,1235,0,0,0,0,0,0,2891776,0,0,0,0,0,2392064,2412544,0,0,0,0,0,0,2123,0,0,0,0,0,0,0,0,0,0,2727936,0,0,0,3084288,0,0,0,1267,0,0,0,0,0,0,0,541,541,541,541,541,541,541,541,541,1741,541,541,541,1309,541,541,541,541,541,541,541,541,541,541,541,541,541,3045,541,3047,563,587,587,1556,587,587,1079,0,0,0,0,0,0,0,0,0,0,3e3,0,0,0,0,0,1621,0,0,1624,0,1626,0,0,0,0,0,0,0,0,0,0,0,3198,3199,0,0,0,0,0,0,0,1722,0,0,0,0,0,0,0,0,0,0,0,683,684,685,0,0,541,541,541,541,1780,541,541,541,541,541,541,541,541,541,541,541,541,1820,541,541,1360,0,563,563,563,563,563,563,563,563,563,563,1836,563,563,563,563,563,2263,563,563,563,563,563,563,563,563,563,563,1433,563,563,563,563,563,1875,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2872,1943,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2359,0,0,2135,0,0,0,0,0,0,0,0,0,0,0,0,0,1618,0,0,2146,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2484,0,0,0,0,541,541,541,2163,2164,541,541,541,541,541,541,541,541,2180,541,541,541,541,2185,541,541,541,541,541,2228,541,541,541,541,541,541,541,541,541,541,0,0,563,563,563,563,2857,0,0,563,563,563,2247,563,2249,563,563,563,563,563,563,563,563,2320,563,563,563,563,563,0,0,563,563,563,2315,563,563,563,563,563,563,563,563,563,563,0,0,988,587,587,587,587,0,0,587,587,587,2334,587,2336,587,587,587,587,587,587,587,587,1965,1966,1968,587,587,587,587,587,587,587,587,2402,587,587,587,587,587,587,587,587,587,587,541,587,0,0,0,541,587,563,541,541,897,541,541,563,563,970,563,0,997,587,1076,1048,587,78115,1079,0,0,0,0,0,0,0,0,458,1147355,1147355,1147355,1147355,1147355,1147355,1147355,1147355,1147355,1147355,1147355,1147355,1147355,1147355,1147355,1147355,0,0,2438,0,0,0,0,0,0,2443,0,0,0,2446,2447,0,0,0,0,0,1610,0,0,1613,0,0,0,0,0,0,0,0,1584,0,0,0,0,0,0,0,0,1683,0,0,0,0,0,0,0,0,334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1134,0,0,0,0,2487,0,0,0,0,0,0,0,0,0,0,0,2498,0,0,0,2515,0,0,0,0,0,0,0,0,0,2523,0,541,541,541,541,541,3576,563,563,563,3580,563,563,563,563,563,563,2290,563,563,563,563,563,563,563,563,563,1899,563,563,563,563,563,1906,2537,2538,541,541,541,541,541,2543,541,2545,541,541,541,541,2549,541,541,541,541,541,3614,3615,541,563,563,563,563,563,563,563,563,3424,563,563,587,587,587,587,587,563,563,2598,563,563,2601,2602,563,563,563,563,563,2607,563,2609,563,0,999,1039,587,1050,587,78115,1079,0,0,0,0,0,0,0,0,3184,0,0,0,0,0,0,0,0,2750,0,0,0,0,0,0,0,0,0,2732032,0,0,0,0,0,0,563,563,563,2613,563,563,563,563,563,563,563,563,2619,563,563,563,563,563,3624,587,587,587,587,587,587,587,587,587,587,1967,587,587,587,1972,587,587,563,2639,563,563,563,563,563,563,563,563,563,563,563,563,563,563,1402,563,587,587,587,2673,587,2675,587,587,587,587,2679,587,587,587,587,587,587,2676,587,587,587,587,587,587,587,587,587,1469,1476,587,587,587,587,587,587,587,587,2685,587,587,587,587,587,587,587,587,2693,587,587,587,587,587,1979,587,587,587,587,587,587,587,587,587,587,2926,2927,587,587,587,587,2930,587,587,587,587,587,2701,587,587,587,587,2705,587,587,587,587,587,587,587,2378,2379,587,587,587,587,587,587,587,2406,587,587,2409,2410,587,587,2176,2348,0,2745,0,0,0,0,0,0,0,2751,2752,2753,0,0,0,0,0,0,0,69632,73728,172032,0,0,0,0,65536,0,2772,0,2774,0,0,0,0,2778,0,0,0,0,2783,0,0,2786,541,541,2828,541,541,541,541,541,541,541,541,541,541,541,541,541,1771,541,541,541,541,541,2838,541,541,541,541,541,541,541,541,541,541,541,541,541,3337,563,563,541,2847,541,541,2850,541,541,2853,541,0,0,2854,563,563,563,563,563,2277,563,563,2280,563,563,563,563,563,563,563,3081,563,563,563,563,563,563,563,563,3355,563,587,587,587,587,587,587,563,563,2875,563,563,563,563,563,563,563,563,563,563,563,563,563,2324,0,0,563,563,563,563,2886,563,563,563,563,563,563,563,563,563,563,563,2606,563,2608,563,563,563,563,563,2896,563,563,2899,563,563,2902,563,0,0,2903,587,587,587,587,587,3284,587,587,587,587,587,587,587,541,587,563,541,541,563,563,587,587,587,2921,587,587,2924,587,587,587,587,587,587,587,587,587,587,587,2666,587,587,587,587,0,0,0,0,0,2972,2973,0,0,0,0,2978,0,0,0,0,0,0,0,69632,73728,221184,0,0,0,0,65536,0,3021,0,0,3023,0,0,541,541,3028,541,541,541,541,541,541,541,541,2205,2206,541,541,541,541,541,541,0,0,3160,0,3162,0,0,0,3166,0,0,0,0,0,0,0,0,2518,0,0,0,0,0,0,541,541,541,541,3030,541,541,541,541,3034,3234,3235,563,563,563,563,3239,3240,563,563,563,563,563,3244,563,563,563,563,1445,563,563,563,563,26028,1360,988,587,1455,587,587,0,3632,0,0,0,0,541,541,541,541,541,3641,541,563,563,563,563,587,587,587,587,587,587,587,3263,3264,587,587,587,587,587,587,3435,587,587,587,587,587,587,587,541,563,3268,3269,587,587,587,587,587,3273,587,587,587,587,587,587,587,587,2393,587,587,587,587,587,587,587,3279,587,587,587,587,587,587,587,587,587,587,587,587,541,587,563,2721,541,0,0,0,3312,0,0,0,0,0,0,0,0,0,0,0,0,1633,0,0,0,541,3404,541,541,541,541,541,541,563,563,563,563,563,563,563,563,563,563,563,563,563,563,3419,563,563,563,563,563,563,563,587,587,587,587,587,3113,587,587,587,587,587,0,3443,0,0,3446,0,0,0,3180,0,0,0,0,0,0,0,1583,0,1585,0,0,0,0,0,0,0,1106,0,0,0,0,0,0,0,0,0,756,0,0,0,0,0,0,0,0,541,541,3458,541,541,541,541,3463,541,541,541,541,3468,541,541,541,541,872,541,541,541,541,541,541,541,541,541,541,541,541,1316,541,541,541,563,587,587,3489,587,587,587,587,3494,587,587,587,587,3499,587,587,587,587,587,3364,587,587,587,587,587,587,587,587,587,587,2664,587,587,2667,2668,587,587,563,563,3645,3646,563,563,563,587,587,587,3651,3652,587,587,587,0,541,587,563,541,541,541,541,541,563,563,563,563,587,587,587,587,0,0,0,2730,0,0,563,587,0,541,563,587,3691,3692,3693,3694,0,541,563,587,0,0,0,0,0,0,0,0,3180,0,0,0,0,0,3453,342,343,344,345,346,0,0,0,0,0,0,0,0,0,0,0,713,0,0,0,0,0,0,0,391,0,0,0,0,0,0,0,0,0,0,0,0,1674,0,0,0,345,345,0,346,345,0,344,345,455,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,487,496,496,504,496,506,496,496,506,506,496,506,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,554,577,554,577,554,554,577,554,601,577,577,577,577,577,577,577,601,601,601,554,601,601,601,601,601,601,601,601,577,577,554,577,601,577,601,1,656,657,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1590,1591,672,673,0,675,676,0,0,0,0,0,682,0,0,0,0,0,0,0,2804,0,0,0,541,2808,541,541,541,0,0,0,0,692,0,0,0,0,0,0,699,365,365,365,0,0,0,0,0,1658,0,0,0,0,0,0,0,0,0,0,0,3180,0,0,0,3308,0,719,0,721,0,723,0,0,0,0,0,0,0,0,0,733,0,0,0,0,646,752,753,754,0,0,0,0,0,760,761,0,0,0,0,0,1680,0,0,0,0,0,0,0,0,0,0,0,3180,0,3306,0,0,763,764,675,0,0,0,0,0,0,0,0,0,0,779,780,0,0,0,0,0,1696,1697,1698,1699,0,0,0,0,0,0,0,0,755,0,0,0,0,0,0,0,0,772,0,0,0,0,0,0,0,0,782,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1601,0,0,761,0,0,787,0,0,0,0,0,0,0,0,0,794,675,723,0,692,811,0,0,0,0,761,0,0,0,0,0,0,0,1591,0,0,0,0,0,0,0,0,0,1662,0,0,0,0,0,0,0,0,754,820,821,0,0,0,0,0,0,754,0,0,825,699,0,0,0,830,0,0,0,832,0,0,0,692,699,0,0,692,830,830,0,0,0,0,0,0,0,0,0,692,541,541,851,855,858,541,866,541,541,541,881,883,886,541,541,541,898,902,541,541,541,541,541,2541,541,541,541,541,541,541,541,541,541,541,541,541,3044,541,541,541,563,563,563,971,975,563,563,563,563,0,587,587,587,998,1002,1005,587,1013,587,587,587,1028,1030,1033,587,587,587,1045,1049,587,587,587,587,587,1995,587,587,587,587,587,2002,587,587,587,587,587,587,2946,587,587,587,587,587,587,541,587,563,1073,0,998,587,1045,1049,1078,78115,1079,0,0,0,0,0,0,0,0,2779,0,0,0,0,0,0,0,0,303,303,303,303,0,303,303,303,0,0,0,0,1168,0,0,0,0,0,0,0,0,0,0,0,729,0,0,0,0,0,0,1199,0,0,0,0,0,0,0,0,0,0,1209,0,0,0,0,0,0,2912256,0,3207168,2465792,0,0,2719744,0,0,0,0,0,0,541,541,541,3397,541,541,541,541,3401,541,0,0,1214,0,0,0,0,0,0,0,0,0,0,0,0,0,1634,0,0,0,0,1254,0,0,0,0,0,0,0,0,0,0,0,0,0,1665,0,0,1321,541,541,541,541,541,541,541,541,541,541,1331,541,541,1338,541,541,541,541,873,541,541,541,541,541,541,541,541,541,541,541,541,1332,541,541,541,563,563,1443,563,563,563,563,563,563,26028,1360,988,587,587,587,587,587,587,3548,587,3550,587,587,3552,587,587,0,0,0,0,0,0,541,541,541,3639,3640,541,541,563,1501,587,587,1505,587,587,587,587,587,587,587,587,587,587,1515,587,0,0,0,541,587,563,541,541,899,541,541,563,563,972,563,0,1074,587,587,1052,587,78115,1079,0,0,0,0,0,0,0,0,2445312,0,2842624,0,0,0,2637824,0,587,1522,587,587,587,587,587,587,587,587,587,587,1535,587,587,587,587,587,2013,587,541,587,563,541,541,541,541,563,563,563,563,587,587,587,587,0,0,0,0,0,0,1666,0,1668,0,0,0,1670,0,748,0,0,0,0,0,0,0,0,3174,0,0,0,0,0,0,0,0,791,0,0,0,0,0,0,0,0,833,0,0,0,0,0,0,808,0,0,1693,0,0,0,0,0,0,1700,0,0,0,0,0,0,0,1660,1661,0,0,0,0,0,0,0,0,710,0,0,0,0,0,0,0,0,726,0,0,0,0,0,0,0,0,0,274432,274432,274432,0,274432,274432,274432,541,541,1762,541,541,541,541,541,541,541,541,1769,541,541,541,1773,541,541,1778,541,541,541,541,541,541,541,541,541,541,541,541,541,1788,541,541,0,563,1828,563,563,563,563,563,563,563,1835,563,563,563,563,563,563,3250,563,563,563,563,563,563,563,563,563,2321,563,563,563,563,0,0,563,1908,563,563,563,563,563,563,563,563,563,26028,0,587,1924,587,0,0,0,541,587,563,541,541,900,541,541,563,563,973,563,563,563,563,2262,563,563,563,563,563,563,563,563,563,563,563,1434,563,563,563,563,587,587,587,1960,587,587,587,1964,587,587,1969,587,587,587,587,587,587,2688,587,587,587,587,587,587,2695,587,587,563,563,587,587,587,587,0,0,0,2031,0,1082,0,0,0,2033,0,1086,0,0,0,2035,0,1090,0,0,0,2037,0,1094,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1620,2587,0,1825,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2610,2650,563,563,563,0,0,0,2653,0,1921,587,587,587,587,587,587,587,3549,587,587,587,587,587,587,0,0,3672,0,541,541,541,541,563,563,0,0,2969,0,0,0,0,0,0,0,0,0,0,0,0,0,2102,0,0,0,0,0,3161,0,0,0,0,0,0,0,0,0,0,0,0,1703,0,0,0,0,0,3319,541,541,541,541,541,541,541,3324,541,541,541,541,541,541,541,2832,541,541,541,541,541,541,541,541,541,2573,541,541,541,541,541,541,587,587,3361,587,587,587,587,587,587,587,587,587,587,587,587,587,2709,587,587,3379,0,0,3382,0,0,0,0,3180,3387,0,0,0,0,0,0,0,1682,0,1684,0,0,0,0,0,0,0,1114,0,0,0,0,1118,0,0,1121,541,541,541,541,3407,541,541,541,563,563,563,3412,563,563,563,563,563,2289,563,563,563,563,563,563,563,563,563,563,2605,563,563,563,563,563,3416,563,563,563,563,563,3422,563,563,563,563,587,587,587,3428,587,0,0,0,541,587,563,850,541,1066,901,541,923,563,1071,974,587,587,587,3432,587,587,587,587,587,3438,587,587,587,587,541,563,563,563,563,2276,563,563,563,563,563,563,2282,563,2284,563,2287,563,587,587,587,587,587,3492,587,587,587,3496,587,587,587,587,587,587,2704,587,587,587,587,587,587,587,587,587,1470,587,587,587,587,587,587,0,0,3657,0,541,541,541,541,541,541,563,563,563,563,563,563,936,563,563,563,563,563,563,563,563,587,3687,3688,3689,3690,0,541,563,587,0,541,563,587,0,0,0,0,0,0,0,0,3180,0,0,3450,3451,0,0,389,0,0,0,393,389,0,0,0,0,0,0,0,0,0,0,0,122880,0,0,0,0,0,0,0,405,0,347,0,69632,73728,0,0,0,0,0,65536,0,0,0,0,0,1709,0,0,0,0,0,0,0,0,0,0,399,0,0,0,0,0,0,0,436,0,0,443,0,0,0,0,0,0,0,0,0,0,0,131072,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,522,522,522,522,522,0,0,0,0,0,0,0,0,0,522,522,522,522,522,522,522,522,522,555,578,555,578,555,555,578,555,602,578,578,578,578,578,578,578,602,602,602,555,602,602,602,602,602,602,602,602,578,578,617,622,602,622,628,1,0,0,0,751,0,0,0,0,0,0,0,0,0,0,0,0,2061,0,0,0,962,563,563,563,563,980,563,563,563,0,587,587,992,587,587,587,587,587,2350,587,587,587,587,587,587,587,587,587,587,1936,587,587,587,587,587,1107,0,0,0,0,1112,0,0,0,0,0,0,0,0,0,0,0,167936,167936,167936,167936,167936,167936,167936,1360,914,563,563,563,1366,563,563,563,563,563,563,563,563,563,1380,563,563,1404,563,563,563,563,563,563,563,563,563,563,563,563,563,2620,563,563,563,1441,563,563,563,563,563,563,563,26028,1360,988,587,587,587,1458,563,587,587,587,587,587,1079,0,1562,0,0,0,1568,0,0,0,0,0,0,1627,1628,1629,0,0,0,0,0,0,0,0,343,0,0,0,0,0,0,0,0,403,0,0,0,0,0,0,0,0,407,407,407,407,0,407,407,407,1574,0,0,0,1580,0,0,0,0,0,0,0,0,0,0,0,808,541,541,852,541,1605,0,0,0,0,0,0,0,0,0,0,0,0,0,1619,0,0,0,0,0,1723,0,0,0,0,0,0,0,0,0,0,0,2625536,0,2699264,2715648,0,1973,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2373,563,563,587,587,587,587,0,0,1563,0,0,0,0,0,1569,0,1575,0,1581,0,0,0,0,0,0,0,0,0,0,0,1262,0,0,0,0,0,0,0,0,1575,0,0,0,0,0,1581,0,0,0,0,0,0,0,2974,0,0,0,0,0,0,0,0,0,365,0,253952,0,0,0,0,541,541,541,2190,541,541,541,541,2194,541,2196,541,541,541,541,541,541,541,3039,541,541,541,541,541,541,541,541,541,887,541,541,541,541,541,541,563,563,2275,563,563,563,563,2279,563,2281,563,563,563,563,563,563,1896,563,563,563,563,563,563,563,563,563,1397,1399,563,563,563,563,563,587,587,2362,587,587,587,587,2366,587,2368,587,587,587,587,587,587,1465,587,587,587,587,587,587,1480,587,587,0,0,0,0,0,2489,0,0,0,0,0,0,0,0,0,0,0,196608,0,0,0,0,563,563,2625,563,563,563,563,563,563,563,563,563,563,563,563,563,2648,563,563,0,0,0,0,3024,0,541,541,541,541,541,541,541,541,541,541,541,1330,541,541,541,541,0,3380,0,0,0,0,0,0,3180,0,0,0,0,3391,0,0,0,0,0,328,0,69632,73728,0,0,0,0,0,65536,0,3393,0,0,0,0,0,541,3396,541,541,3398,541,541,541,541,541,541,541,3040,541,541,541,541,541,541,541,541,541,1783,541,541,541,541,1789,541,0,3455,541,541,541,541,541,541,541,541,541,541,541,541,541,541,563,563,563,541,862,541,541,541,541,541,541,541,541,541,541,541,541,541,541,1319,541,541,912,563,563,563,563,563,563,935,563,563,563,563,563,563,563,2291,2292,563,563,563,563,563,563,563,2319,563,563,2322,2323,563,563,0,0,1009,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2697,1059,0,0,0,541,587,563,541,541,541,541,541,563,563,563,563,563,2614,563,563,563,563,563,563,563,563,563,563,3649,587,587,587,587,587,587,587,0,1095,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2513,0,0,1623,0,0,0,0,0,0,0,0,0,0,0,0,0,2130,0,2132,1826,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,3258,541,3215,541,541,541,541,541,541,541,541,541,541,541,541,541,541,1337,541,587,587,587,3271,587,587,587,587,587,587,587,587,587,587,587,587,2370,587,587,587,0,0,0,0,348,348,350,348,348,348,348,348,348,513,348,348,0,350,348,0,0,348,348,0,0,0,0,349,0,0,0,0,0,329,0,0,0,0,0,0,0,0,0,0,0,2509,0,0,0,0,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,348,556,579,556,579,556,556,579,556,603,579,579,579,579,579,579,579,603,603,603,556,603,603,603,603,603,603,603,603,579,579,556,579,603,579,603,1,0,0,0,0,722,0,724,0,0,0,0,0,0,0,0,0,299,0,0,0,0,0,0,0,0,0,0,739,0,0,0,0,0,0,0,0,0,0,0,836,541,541,541,541,0,0,0,766,0,0,0,771,0,0,0,0,0,0,0,0,0,1189,0,0,0,0,0,0,541,541,541,870,541,541,541,541,541,890,892,541,541,903,541,541,541,541,541,2569,541,541,541,541,541,541,541,541,541,541,541,541,2835,541,541,541,963,965,563,563,976,563,563,563,563,0,587,587,993,999,587,587,587,587,587,3374,587,541,541,563,563,587,587,0,0,0,0,0,0,3299,0,0,0,587,587,1017,587,587,587,587,587,1037,1039,587,587,1050,587,587,587,587,587,2364,587,587,2367,587,587,587,587,587,587,587,2677,587,587,587,587,587,587,2682,587,0,0,0,1151,0,1153,0,1155,0,0,0,0,0,0,0,0,0,1231,541,541,541,541,541,541,0,1181,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1636,0,0,1198,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1675,0,0,1266,0,0,0,0,0,0,0,1181,541,541,541,541,541,541,541,1326,541,541,541,541,541,541,541,1339,1305,1307,541,541,541,541,541,541,541,541,541,541,541,541,541,541,1358,541,541,541,1343,541,541,541,541,541,541,541,541,1354,1355,541,541,541,541,541,541,2840,541,541,541,541,541,541,541,541,541,541,3056,541,3058,541,541,541,1360,914,563,563,563,563,1367,563,563,563,563,563,563,563,563,563,3242,563,563,563,563,563,563,563,563,563,1421,563,563,563,563,563,563,563,1435,563,563,563,563,563,2627,563,563,563,563,563,563,2635,563,563,563,1459,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2942,587,587,587,1489,1491,587,587,587,587,587,587,587,587,587,587,587,2707,2708,587,587,587,1554,587,1555,587,587,1558,1079,0,0,0,0,0,0,0,0,0,306,204800,204800,0,205106,204800,1,0,1677,0,0,1679,0,0,0,0,0,0,0,0,0,0,0,1159,0,0,0,0,541,541,541,541,1763,541,541,541,541,541,541,541,541,541,541,541,541,2208,541,541,541,0,563,563,563,563,563,563,563,1833,563,563,563,563,563,563,563,2879,563,563,563,563,563,563,563,563,2644,563,563,563,2647,563,563,563,1858,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,1857,563,563,563,1909,563,563,563,563,1915,563,563,563,26028,0,587,587,587,587,587,2376,587,587,587,587,587,587,587,587,587,587,2717,541,587,563,541,541,587,587,587,587,1929,587,587,587,587,587,587,587,587,587,587,587,2938,587,587,587,587,587,1991,587,587,587,1996,587,587,587,587,587,587,587,587,2005,587,0,0,0,541,587,563,852,892,541,903,541,925,965,563,976,587,587,587,2011,587,587,587,541,587,563,541,541,541,541,563,563,916,563,563,563,932,563,563,563,563,563,563,563,1864,563,563,563,1868,563,563,1873,563,2077,0,0,0,0,0,0,0,0,2085,0,0,0,0,0,2089,0,0,2091,0,0,0,0,0,0,0,2099,0,0,0,0,0,0,0,3012,3013,0,0,0,0,3018,0,0,2133,2134,0,2136,0,0,0,0,0,0,0,0,0,0,2144,0,0,2149,2150,0,0,0,0,0,2154,0,0,0,0,0,0,0,2160,541,541,541,541,541,541,2167,541,541,541,541,541,541,1288,541,541,541,541,1298,541,541,541,541,541,541,1325,541,541,541,541,541,541,541,541,541,541,1801,541,541,541,541,541,2202,541,541,541,541,541,541,541,541,541,541,541,541,2209,541,541,541,541,541,2815,541,2818,541,541,541,541,2823,541,541,541,541,541,541,3409,541,563,563,563,563,563,563,563,563,3479,563,3481,3482,563,3484,563,541,541,541,2215,541,541,541,541,541,541,541,541,541,541,541,541,895,541,541,541,0,0,2244,563,563,563,563,563,563,563,2252,563,563,563,563,563,563,3534,563,3536,563,563,3538,563,563,587,587,563,563,2301,563,563,563,563,563,563,563,563,563,563,563,563,563,2893,563,563,0,0,2331,587,587,587,587,587,587,587,2339,587,587,587,587,587,587,2715,587,587,587,587,541,587,563,541,541,587,587,587,587,2363,587,587,587,587,587,587,2369,587,2371,587,2374,587,587,2388,587,587,587,587,587,587,587,587,587,587,587,587,587,2918,587,587,0,2474,0,0,0,0,0,0,0,0,0,2482,0,0,0,0,0,0,0,122880,122880,122880,122880,122880,0,122880,0,2105632,0,0,2514,0,0,0,0,0,0,0,0,0,2522,0,0,541,541,541,541,541,3461,541,541,541,3465,541,541,541,541,541,541,1287,541,541,541,541,541,541,541,541,541,541,2546,541,541,541,541,541,541,541,541,541,2540,541,541,541,541,541,541,541,541,541,541,541,541,2222,541,541,541,563,563,563,2599,563,563,563,563,563,2604,563,563,563,563,563,563,2278,563,563,563,563,563,563,563,563,563,2632,563,563,563,563,563,563,2670,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,3143,587,587,587,587,2686,587,587,587,587,587,587,587,587,587,587,587,3125,587,587,587,587,541,541,2723,563,563,563,2725,587,587,587,2727,2728,0,0,0,0,0,0,0,172032,172032,172032,172032,172032,172032,172032,172032,1,0,0,2746,0,2747,0,0,0,0,0,0,0,0,0,0,0,1175,0,0,0,0,0,0,0,0,2762,0,0,0,0,0,0,0,0,0,0,0,1192,0,1195,0,0,2811,541,2812,541,541,541,541,541,541,541,541,541,541,541,541,541,1804,541,541,541,541,541,2849,541,541,541,541,541,0,0,563,563,563,563,563,563,563,563,563,563,563,563,2255,563,2858,563,2859,563,563,563,563,563,563,563,563,563,563,563,563,563,3086,563,563,587,587,2907,587,2908,587,587,587,587,587,587,587,587,587,587,587,3139,587,3141,587,587,0,0,0,2983,0,0,0,0,0,0,0,0,0,0,0,0,2073,0,0,0,0,0,3381,0,0,0,0,0,3180,0,0,0,3390,0,0,0,0,0,0,1659,0,0,0,0,0,0,0,0,0,0,114688,0,241664,258048,0,0,3430,587,587,587,587,587,587,587,587,587,3439,587,587,587,541,563,563,563,563,2303,563,563,563,563,563,563,563,563,563,563,563,26028,0,587,587,587,541,541,541,541,3518,541,541,541,541,541,541,541,541,541,563,563,563,3232,563,563,563,563,563,563,3531,563,563,563,563,563,563,563,563,563,563,587,587,587,3357,587,587,587,587,587,3545,587,587,587,587,587,587,587,587,587,587,0,0,0,0,0,0,3637,541,541,541,541,541,541,3643,563,563,563,563,3647,563,563,587,587,587,587,587,3653,587,587,0,0,0,0,3635,0,541,541,541,541,541,541,541,563,2724,563,563,587,2726,587,587,0,0,0,0,0,0,0,0,3607,0,541,541,541,541,0,3656,0,3658,541,541,541,541,541,541,563,563,563,563,563,563,937,563,563,563,563,563,563,563,0,0,0,0,394,395,0,396,0,0,0,0,0,396,0,0,0,0,0,331,332,333,0,0,0,0,0,0,0,0,0,560,583,560,583,560,560,583,401,0,0,0,0,0,368,376,404,0,0,0,0,0,368,0,0,396,0,0,0,0,0,351,0,0,368,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2744,409,411,0,0,368,376,0,69632,73728,0,0,0,0,427,65536,0,0,0,0,0,2044,2045,0,0,0,0,0,0,0,0,0,361,0,0,0,0,0,361,427,427,437,0,427,0,411,427,456,0,0,0,0,0,0,0,0,106496,0,106496,0,0,0,0,106496,396,0,409,0,497,497,0,497,497,497,497,497,497,497,497,523,523,523,523,523,456,456,456,456,531,456,456,532,456,523,537,523,523,523,537,523,523,523,523,539,557,580,557,580,557,557,580,557,604,580,580,580,580,580,580,580,604,604,604,557,604,604,604,604,604,604,604,604,580,580,618,623,604,623,629,1,0,0,0,643,0,0,0,0,0,0,0,0,0,0,0,0,2101,0,0,0,783,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2757,0,0,0,802,0,0,0,0,0,0,0,0,0,0,0,0,2129,0,0,0,587,587,587,1023,1025,587,587,587,587,587,587,587,587,587,587,587,3275,587,587,587,587,0,0,0,0,1096,0,0,1098,0,0,0,0,0,0,0,0,0,1630,0,0,0,0,0,1636,0,0,0,0,1111,0,0,0,0,0,0,0,0,0,0,0,1207,0,0,0,0,1098,1227,0,0,0,0,0,0,1234,0,0,0,0,0,0,0,0,155648,0,0,0,0,0,0,0,0,1239,0,0,0,0,0,0,0,0,0,0,1239,1248,0,0,0,0,0,0,1681,0,0,0,0,0,0,1687,0,1689,0,0,0,0,1239,1269,1270,0,1239,0,541,541,541,541,541,541,541,3207,3208,541,541,541,541,3212,3213,1278,541,541,541,1282,541,541,1293,541,541,1297,541,541,541,541,541,541,541,3054,541,541,541,541,541,541,541,541,541,1784,541,541,541,541,541,541,1360,914,563,563,563,563,563,563,563,1370,563,563,563,1374,563,563,563,563,1847,563,563,563,563,563,563,563,563,563,563,563,2308,563,563,563,563,1385,563,563,1389,563,563,563,563,563,563,563,563,563,563,563,563,2295,563,563,563,563,563,563,1406,563,563,563,1410,563,563,563,563,563,563,563,563,2901,563,563,0,0,587,587,587,587,587,587,1462,587,587,587,1466,587,587,1477,587,587,1481,587,587,587,587,587,3434,587,3436,587,587,587,587,587,587,541,563,587,1502,587,587,587,587,587,587,587,587,587,587,587,587,587,587,3128,587,0,1622,0,0,0,0,0,0,0,0,0,0,0,0,1635,0,0,0,0,0,2067,0,0,0,0,0,0,0,0,0,2076,1637,0,0,0,1641,0,0,0,1645,0,0,0,1649,0,0,0,0,0,0,2056,0,2057,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1676,0,563,563,1844,563,563,563,563,563,563,563,563,563,563,563,563,563,3540,587,587,1958,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,3127,587,3129,587,587,2010,587,587,587,587,1749,1940,1844,541,541,541,541,563,563,917,563,563,563,934,563,563,948,563,563,563,563,563,1895,563,563,563,1900,563,563,563,563,563,563,1914,563,563,563,563,26028,0,587,587,587,0,2118,0,0,0,0,0,0,2125,0,0,0,0,0,0,0,0,184726,184932,184932,184932,0,184932,184932,184932,0,0,2159,0,541,541,2162,541,541,541,541,541,541,541,541,541,541,2833,541,541,541,541,541,541,541,2227,541,541,541,541,541,541,541,541,541,541,541,0,0,563,2855,563,563,563,0,0,563,563,2246,563,563,563,563,563,563,563,563,563,563,563,3255,563,563,563,563,563,563,2314,563,563,563,563,563,563,563,563,563,563,563,0,0,587,2904,587,0,0,587,587,2333,587,587,587,587,587,587,587,587,587,587,587,3440,587,587,541,563,587,587,587,587,2390,587,587,587,587,587,587,587,587,587,587,587,2928,587,587,587,587,587,587,587,587,2401,587,587,587,587,587,587,587,587,587,587,587,541,587,0,0,0,541,587,563,1064,541,541,905,541,1069,563,563,978,541,541,541,2567,541,541,541,541,541,541,541,541,541,541,541,541,900,541,541,541,2698,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,3277,587,587,0,2759,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1716,0,541,2827,541,541,541,541,541,541,541,541,541,541,541,541,541,541,1758,541,563,2874,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2285,563,587,587,587,2923,587,587,587,587,587,587,587,587,587,587,587,587,2382,587,587,587,0,0,2993,0,0,0,0,0,0,0,0,0,0,0,0,0,2433,0,2435,3171,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2771,3202,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2577,3225,541,541,541,541,541,541,541,541,563,563,563,563,563,563,563,2888,563,563,563,563,563,563,563,563,3241,563,563,563,563,563,563,563,587,587,587,3282,587,587,587,587,587,587,587,587,587,541,587,563,2018,541,541,541,2022,563,541,3289,563,3291,587,3293,3294,0,0,0,0,3298,0,0,0,0,0,0,0,1134592,0,365,0,0,0,1134592,0,0,0,1134592,1134592,0,0,1134592,0,0,1134592,0,0,0,3311,0,0,0,0,3315,0,0,0,0,0,0,0,0,0,1725,0,0,0,0,0,0,3318,0,541,541,541,3320,541,541,541,3323,541,541,541,541,541,541,541,1751,541,541,541,541,541,541,541,541,541,2586,0,563,563,563,563,563,3338,563,563,563,3341,563,563,563,563,563,563,563,563,563,563,563,26028,1921,587,587,587,587,3360,587,587,587,587,587,587,587,587,587,587,587,587,587,587,3554,0,0,3403,541,3405,541,541,541,541,541,563,563,563,563,563,563,563,563,563,563,3075,563,563,3418,563,3420,563,563,563,563,563,563,587,587,587,587,587,587,587,3596,587,3598,587,587,0,0,0,0,3560,0,0,0,0,541,541,541,541,541,541,541,541,541,2169,541,541,541,541,541,3574,541,541,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,1417,3586,563,563,563,587,587,587,587,587,587,587,587,587,587,3599,587,0,0,0,853,1e3,926,849,1065,894,541,541,922,1070,967,563,0,587,587,587,587,587,78115,0,0,0,0,0,0,0,0,0,365,0,305,0,0,0,0,3611,541,541,541,541,541,541,541,563,563,3617,563,3618,563,563,563,563,587,587,587,587,3594,587,587,587,587,587,587,587,541,541,563,563,587,587,3378,0,0,410,356,0,0,0,0,0,69632,73728,0,0,0,0,0,65536,0,0,0,0,0,2122,0,0,0,0,0,0,0,0,0,0,304,304,0,0,0,0,0,0,354,0,0,0,356,0,0,473,473,473,473,473,473,473,478,473,473,473,473,473,473,473,473,473,473,473,478,473,484,473,0,0,473,0,0,0,0,0,0,0,0,524,528,528,528,528,473,473,473,473,473,473,473,478,473,528,524,528,528,528,524,528,528,528,528,540,558,581,558,581,558,558,581,558,605,581,581,581,581,581,581,581,605,605,605,558,605,605,605,605,605,605,605,605,581,581,619,624,605,624,630,1,0,0,0,0,644,0,0,0,0,0,0,0,0,0,0,0,1606,0,0,0,0,688,0,0,0,0,0,0,0,0,0,0,0,365,365,365,0,0,0,0,0,2138,0,0,0,0,0,0,0,0,0,0,0,2768,0,0,0,0,0,0,0,738,0,0,0,644,738,0,744,745,644,0,0,0,0,0,0,790,0,0,0,0,0,0,0,0,0,2058,0,0,0,0,0,0,0,0,799,0,804,0,0,0,0,0,0,804,0,0,0,0,0,644,0,0,0,799,0,804,0,790,0,819,0,0,0,665,0,0,0,0,819,0,0,0,0,0,0,0,2473984,2478080,0,0,0,0,0,0,0,0,0,2767,0,0,0,0,0,0,0,644,0,0,0,0,0,0,0,0,790,0,0,0,0,0,0,0,3165,0,0,0,0,0,0,0,0,0,541,563,541,563,541,541,563,0,0,790,790,0,644,0,0,790,804,842,0,541,848,541,541,541,541,541,2839,541,541,541,2842,541,2844,541,541,541,541,541,541,879,541,884,541,891,541,894,541,541,908,541,541,867,871,877,541,882,541,541,541,541,541,899,541,541,541,541,541,541,2852,541,541,0,0,563,563,563,563,563,563,563,563,563,563,563,563,563,2256,563,563,563,972,563,563,563,563,563,0,587,587,995,587,587,587,587,587,2687,587,587,587,587,587,587,587,587,587,587,2937,587,587,587,587,587,587,587,1014,1018,1024,587,1029,587,587,587,587,587,1046,587,587,587,587,587,1026,587,1031,587,1038,587,1041,587,587,1055,587,1149,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2799,0,0,0,1200,0,0,0,0,0,1205,0,0,0,0,0,0,0,1714,0,0,0,0,0,0,0,0,0,2140,2141,0,0,2143,0,0,1099,0,0,0,1230,0,1232,0,0,0,0,0,0,0,0,0,351,352,353,0,0,0,0,1240,0,0,0,0,0,0,0,0,0,0,1246,0,1249,1200,0,0,0,0,0,2427,0,0,0,0,0,0,0,0,0,0,336,337,0,0,0,0,1230,1252,0,1255,0,0,0,0,0,1130,0,0,0,0,1264,0,0,1149,1264,0,1271,541,541,541,541,1277,1360,914,1362,563,563,563,563,563,1369,563,563,563,563,1375,563,563,563,563,1862,563,563,563,563,563,563,563,563,563,563,563,3084,563,563,563,563,563,563,563,1407,563,563,563,563,1412,563,563,563,563,563,563,563,2900,563,563,563,0,0,587,587,587,563,1419,563,563,563,1426,1428,563,563,563,563,563,563,563,563,563,3346,563,563,563,563,563,563,587,587,1461,587,587,587,587,1467,587,587,587,587,587,587,587,587,2663,587,587,587,587,587,587,587,587,587,1488,587,587,587,587,587,587,587,587,587,587,1499,587,587,587,587,1463,587,587,587,587,587,1475,587,587,587,587,587,587,2014,541,587,563,1791,541,2020,541,1886,563,587,587,1504,587,587,587,587,587,587,587,587,1511,587,587,587,1518,1520,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2396,2397,2398,587,587,1542,587,0,541,587,563,541,541,541,541,541,563,563,563,563,563,2862,563,2865,563,563,563,563,2870,563,563,563,563,587,587,587,587,587,1079,0,0,1563,0,0,0,1569,0,0,0,0,0,376,0,0,0,0,368,0,385,0,351,0,0,1575,0,0,0,1581,0,0,0,0,0,0,0,0,0,0,303,303,0,0,0,0,1592,1593,0,0,0,0,0,1599,0,0,0,0,0,0,0,0,0,2098,0,2100,0,0,0,0,0,1638,0,0,0,0,0,0,0,1646,1647,0,0,0,0,0,0,0,3197,0,0,0,0,0,0,3200,0,0,1654,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2038,0,1690,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3005,0,1706,1707,0,0,0,1710,0,0,0,0,0,1714,0,0,1717,0,0,1730,0,1732,1706,541,541,541,541,541,541,541,541,541,541,541,2547,541,541,541,541,541,1744,541,541,541,541,1750,541,541,541,541,541,541,541,541,541,541,3220,541,541,541,541,541,541,1761,541,541,541,541,1765,541,541,541,541,541,541,541,541,541,541,3335,541,541,563,563,563,541,1776,541,541,541,1781,541,541,541,541,541,541,541,541,541,541,541,2559,541,541,541,541,1808,541,541,541,541,541,541,541,541,541,541,541,541,541,541,1360,914,563,563,563,563,563,563,563,563,563,563,563,563,1376,563,0,587,587,1046,587,587,78115,1079,0,0,0,0,0,0,0,0,225890,225890,225890,225890,225741,225890,225890,225890,0,563,563,563,563,563,563,563,563,563,563,563,563,1839,563,563,563,563,1877,563,563,563,563,563,563,563,563,563,563,563,2869,563,563,563,563,563,563,1845,563,563,563,563,563,563,563,563,563,563,1856,563,563,563,563,1894,563,563,563,1898,563,563,563,563,563,563,563,1450,563,26028,1360,988,1454,587,587,587,563,563,1860,563,563,563,563,563,563,563,563,563,563,1871,563,563,563,563,1911,1913,563,563,563,563,563,26028,0,587,587,587,587,587,1506,587,587,1508,587,587,587,1512,587,587,587,0,1286,1470,1378,541,541,541,1549,541,563,563,563,1553,563,1876,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2297,2298,563,563,587,2027,587,587,0,0,0,0,0,0,0,0,0,0,3511,0,3513,0,541,0,0,0,2080,2081,0,0,2083,2084,0,0,0,0,0,0,0,0,286720,0,0,0,0,0,0,0,0,0,286720,286720,0,286720,286720,1,0,0,0,2106,0,0,0,0,2109,2110,0,0,0,0,0,0,0,2069,0,0,0,0,0,0,0,0,0,541,564,541,564,541,541,564,541,541,541,541,2175,541,541,2179,541,541,541,2183,541,541,541,541,541,541,1347,541,541,541,541,541,541,541,541,541,563,563,3231,563,563,563,563,2225,541,541,541,541,2230,541,541,541,541,541,541,541,541,0,0,0,0,0,386,0,69632,73728,0,0,0,0,0,65536,0,2242,0,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2325,0,563,563,563,2260,563,563,2264,563,563,563,2268,563,563,563,563,563,587,587,3625,587,3626,587,587,587,587,587,587,1493,587,587,587,587,587,587,587,587,587,2380,587,587,587,587,587,587,2312,563,563,563,563,2317,563,563,563,563,563,563,563,563,0,0,0,0,0,0,587,587,2655,587,587,587,2329,0,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2680,587,587,587,587,587,587,2347,587,587,2351,587,587,587,2355,587,587,587,587,587,587,2925,587,587,587,587,587,587,587,587,587,1471,587,587,587,587,587,587,2399,587,587,587,587,2404,587,587,587,587,587,587,587,587,541,587,0,0,0,854,1001,927,541,541,541,541,910,563,563,563,563,563,1848,563,563,563,563,563,563,563,563,563,563,3097,563,3099,563,563,563,0,0,0,0,2439,0,0,0,0,0,0,0,0,0,0,0,1616,0,0,0,0,0,0,2475,0,0,0,2479,0,0,0,0,0,0,0,0,0,365,0,0,0,0,0,0,541,2525,541,541,541,541,541,541,541,541,541,541,2533,541,541,541,541,541,541,3053,541,541,3055,541,541,541,541,541,541,541,1311,541,541,541,541,541,541,541,541,541,1753,541,541,541,541,541,541,541,2551,541,541,2553,541,2554,541,541,541,541,541,541,541,2561,541,541,541,541,876,878,541,541,541,541,541,541,541,541,541,541,541,1353,541,541,541,541,541,2565,541,541,541,541,541,541,541,541,541,541,541,541,2576,541,541,541,541,1283,541,541,541,541,541,541,541,541,541,541,1304,0,0,0,563,563,2589,563,563,563,563,563,563,563,563,563,563,3537,563,563,3539,563,587,587,563,2597,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2326,0,563,563,2612,563,563,563,2615,563,563,2617,563,2618,563,563,563,563,563,2877,2878,563,563,563,563,2881,563,563,563,563,563,1863,563,563,563,563,563,563,563,563,563,563,3356,587,587,587,587,587,563,563,563,563,2626,563,563,2630,563,563,563,563,563,563,563,563,3345,563,563,563,563,563,563,563,563,563,563,563,2641,2642,563,563,563,563,563,563,563,563,563,563,26028,1360,988,587,587,587,587,2683,587,2684,587,587,587,587,587,587,587,587,2692,587,587,2696,587,0,0,0,1061,1062,1063,851,541,898,902,1068,924,563,971,975,2733,2734,0,0,2737,2738,0,0,0,0,0,0,0,0,0,0,306,307,0,0,0,0,0,2788,0,2790,0,0,0,0,0,0,0,0,0,0,0,0,2457,0,0,0,0,0,0,0,2803,0,0,0,0,0,0,541,541,541,541,541,541,541,3033,541,541,2826,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2825,2873,563,563,563,563,563,563,563,563,563,563,563,563,2883,563,563,563,563,1912,563,563,563,563,563,563,26028,0,587,587,587,587,587,2934,587,587,587,587,587,587,587,2940,587,587,587,587,2922,587,587,587,587,587,587,587,587,587,587,587,587,2932,0,2982,0,0,2984,0,0,0,0,0,0,0,0,0,0,0,1632,0,0,0,0,0,0,0,0,2995,0,0,2998,0,2999,0,0,0,0,0,0,0,2096,0,0,0,0,0,0,0,0,0,562,585,562,585,562,562,585,541,3049,541,541,541,541,541,541,541,541,541,541,541,541,541,3061,3089,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2621,563,3103,563,563,563,563,563,587,587,587,3111,587,587,587,587,587,587,1507,587,587,587,587,587,587,587,587,587,1983,1984,587,587,587,587,587,587,3131,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2929,587,587,587,587,3145,587,587,587,587,587,541,587,563,541,541,563,563,587,587,0,2962,0,0,0,0,0,0,0,0,0,2507,0,0,0,0,0,0,0,0,0,0,0,3163,0,0,0,0,0,0,0,3169,0,0,0,0,0,438,0,0,0,0,0,0,0,0,0,0,0,2142,0,0,0,0,541,3226,541,541,541,541,541,541,541,563,563,563,563,563,563,563,3095,563,563,563,563,563,563,563,563,2306,563,563,563,563,563,563,563,563,563,3236,563,563,563,563,563,563,563,563,563,563,563,563,563,2309,2310,2311,563,563,3246,563,563,563,563,563,563,3252,563,3254,563,563,563,563,563,1392,563,563,563,563,563,563,563,563,563,563,1853,563,563,563,563,563,563,563,563,587,587,587,587,587,587,587,587,587,3265,587,587,587,587,587,2703,587,587,587,587,587,587,587,587,587,587,2950,587,587,541,587,563,587,587,3281,587,3283,587,587,587,587,587,587,587,587,541,587,563,3153,541,3155,563,3157,587,0,0,0,3301,0,0,0,0,0,0,0,3180,0,0,0,0,0,0,0,3014656,3207168,0,2691072,0,0,3215360,0,0,3309,0,0,0,0,0,3314,0,0,0,0,0,0,0,0,0,365,0,0,0,0,131072,131072,563,563,3339,563,563,563,3343,563,563,563,563,563,563,563,563,563,26028,1360,988,587,587,1456,587,587,587,587,3362,587,587,587,587,587,587,587,587,587,587,587,587,3126,587,587,587,587,587,3371,587,587,587,587,541,541,563,563,587,587,0,0,0,3296,0,0,0,0,0,0,3557,3558,0,0,0,0,0,0,0,541,541,541,3568,541,541,541,541,541,1284,541,541,541,541,541,541,541,541,541,1303,563,563,3588,563,587,587,587,3593,587,587,587,587,587,587,587,587,2690,587,587,587,587,2694,587,587,3601,587,0,0,0,0,0,3604,3605,3606,0,3608,541,541,541,541,541,541,1813,541,541,541,541,1819,541,541,541,1360,563,3621,3622,563,563,587,587,587,587,587,587,587,587,587,3629,3630,563,563,587,587,587,587,3679,0,541,3680,563,3681,587,3682,0,541,541,541,541,1345,541,541,541,541,541,541,541,541,541,541,541,541,2560,541,541,541,358,359,0,0,0,0,0,0,0,365,0,293,0,0,0,0,0,0,306,0,0,0,0,0,0,0,0,0,0,1174,0,0,0,0,0,0,0,0,392,0,0,0,0,0,0,0,0,0,0,0,0,2495,0,0,0,474,474,474,488,0,0,488,359,359,359,510,359,359,359,359,474,559,606,582,582,582,582,582,582,582,606,606,606,559,606,606,606,606,606,606,606,606,582,582,559,582,606,582,606,1,541,541,868,541,541,541,541,541,541,541,541,541,541,904,541,541,541,541,541,2851,541,541,541,0,0,563,563,563,563,563,563,563,563,563,563,2254,563,563,563,587,1015,587,587,587,587,587,587,587,587,587,587,1051,587,587,587,587,587,2909,587,587,587,587,587,587,2917,587,587,587,587,587,1527,587,587,587,587,587,587,587,587,1538,1539,1197,0,0,0,0,0,0,0,1197,0,0,0,0,0,0,0,0,1134592,0,0,1134592,0,0,0,0,0,0,0,0,0,0,0,0,0,2980,0,0,541,541,1280,541,541,541,1289,541,541,541,541,541,541,541,541,541,541,3524,541,541,3526,563,563,1360,914,563,563,563,563,563,563,563,563,563,1372,563,563,563,1381,587,587,1543,0,1289,1473,1381,541,541,541,541,541,563,563,563,563,563,2898,563,563,563,563,563,0,0,587,587,587,587,587,587,2337,587,587,587,587,587,587,587,2352,587,587,587,587,2357,587,587,587,563,587,587,587,587,587,1079,0,0,0,1564,0,0,0,1570,0,0,0,0,0,2440,0,0,0,0,0,0,0,0,0,0,0,2871296,0,0,2424832,0,0,0,1576,0,0,0,1582,0,0,0,0,0,0,0,0,0,365,0,0,0,0,155648,0,0,1606,0,0,0,0,0,0,0,1614,1615,0,0,0,0,0,0,0,3385,3180,0,0,0,0,0,0,0,0,2097,0,0,0,0,0,0,0,0,2070,0,0,0,0,2074,0,0,0,0,0,0,1625,0,0,0,0,0,0,0,0,0,0,0,1648,0,0,0,0,563,1891,563,563,563,563,563,563,563,563,1902,563,563,563,563,563,1408,563,563,563,563,563,563,563,563,563,563,1867,563,563,563,563,563,587,1975,587,587,587,587,587,587,587,587,587,587,587,1987,587,587,587,587,1490,587,587,587,587,587,587,587,587,587,587,587,2381,587,587,587,587,2008,587,587,587,587,587,587,541,587,563,541,541,541,541,563,563,918,563,563,563,563,563,563,563,563,563,563,563,2634,563,563,563,563,0,2243,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2637,563,0,2330,587,587,587,587,587,587,587,587,587,587,587,587,587,587,3276,587,587,587,0,0,2451,0,0,0,0,0,0,0,0,0,0,0,0,0,2471,0,2472,0,0,0,563,563,563,563,563,563,563,2593,563,563,563,563,563,1424,563,563,563,563,563,563,563,563,563,563,2293,563,563,563,563,563,563,587,2659,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2912,587,587,2916,587,587,587,587,0,0,0,0,0,2776,0,0,0,0,0,0,0,0,0,0,372,0,0,373,0,0,563,2895,563,563,563,563,563,563,563,563,563,0,0,587,587,587,587,2335,587,587,587,587,587,587,587,587,587,2947,587,587,587,587,587,541,587,563,587,2906,587,587,587,587,587,587,2913,587,2915,587,587,587,587,587,587,2935,587,587,587,587,587,587,587,587,587,2408,587,587,587,587,2177,2349,587,587,587,2944,587,587,587,587,587,587,587,587,587,541,587,563,563,563,563,563,563,563,587,587,587,541,587,587,587,0,541,587,563,541,1547,541,541,1550,563,1551,563,563,0,0,0,0,0,3561,0,0,0,541,541,541,541,541,541,541,541,3464,541,3466,3467,541,3469,541,541,541,541,3575,541,563,563,563,563,563,563,563,563,563,563,3423,563,563,563,3426,587,587,587,587,563,3587,563,563,587,587,587,587,587,587,587,587,587,587,587,3600,587,587,587,587,3670,587,0,0,0,0,541,541,541,541,563,563,919,925,563,563,563,563,943,563,563,563,563,563,563,3353,563,563,563,587,587,587,587,587,587,587,587,587,587,587,587,3267,0,0,360,0,0,0,0,0,0,365,0,293,0,0,0,0,0,0,331,0,0,0,0,0,0,0,331,0,0,69632,73728,0,419,419,0,0,65536,419,0,0,0,0,375,0,0,0,0,0,0,0,0,0,0,0,1663,0,0,0,0,0,0,360,0,0,0,0,0,0,0,0,0,0,0,0,0,2511,0,0,0,0,0,370,0,0,370,0,0,0,0,0,0,0,0,0,0,0,0,0,2496,0,0,560,607,583,583,583,583,583,583,583,607,607,607,560,607,607,607,607,607,607,607,607,583,583,560,583,607,583,607,1,541,863,541,541,541,541,541,541,541,541,541,541,541,541,541,541,1772,541,1010,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,3123,587,587,587,587,587,587,587,563,1386,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2871,563,0,0,2760,0,0,0,0,0,0,0,0,0,0,0,0,0,2755,0,0,0,0,0,0,0,2985,0,0,0,0,0,0,0,0,0,0,406,0,0,0,0,0,0,0,0,0,3302,0,3303,0,0,0,0,3180,0,0,0,0,0,0,348,0,0,0,0,0,0,0,0,0,0,2801664,0,0,0,0,2142208,0,0,0,361,362,363,364,0,0,365,0,293,0,0,0,0,0,0,348,349,350,0,0,0,0,0,0,0,0,3180,0,3388,0,0,0,0,0,0,362,0,361,0,0,0,69632,73728,0,0,0,0,428,65536,0,0,0,0,0,2463,0,0,0,0,0,0,0,0,0,0,0,2807,541,541,541,541,428,428,0,0,428,0,362,428,457,0,0,0,0,0,0,0,0,1159168,0,1159168,0,0,0,0,1159168,0,0,0,0,498,498,0,505,505,505,505,511,512,505,505,525,525,525,525,525,457,457,457,457,457,457,457,457,457,525,525,525,525,525,525,525,525,525,561,584,561,584,561,561,584,561,608,584,584,584,584,584,584,584,608,608,608,561,608,608,608,608,608,608,608,608,584,584,620,625,608,625,631,1,563,563,563,973,563,563,563,563,563,0,587,587,587,587,587,587,1963,587,587,587,587,587,587,587,587,587,3137,587,587,587,587,587,587,587,0,2105,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2052,0,0,0,0,0,541,2161,541,541,541,541,541,541,541,541,541,541,541,3336,541,563,563,563,0,0,563,2245,563,563,563,563,563,563,563,563,563,563,563,563,2882,563,563,563,0,0,587,2332,587,587,587,587,587,587,587,587,587,587,587,587,3286,587,587,587,587,541,587,563,2550,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2210,541,541,541,2579,541,541,541,541,541,541,541,541,541,541,0,0,0,0,0,0,2068,0,0,0,0,0,0,0,0,0,365,0,0,122880,122880,0,0,2711,587,587,587,587,587,587,587,587,587,587,541,587,563,541,541,541,2021,563,563,562,609,585,585,585,585,585,585,585,609,609,609,562,609,609,609,609,609,609,609,609,585,585,562,585,609,585,609,1,0,0,0,705,0,0,0,0,0,0,0,0,0,0,0,0,2742,0,0,0,0,735,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2075,0,541,864,541,541,541,541,541,541,541,541,541,541,541,541,541,541,2238,0,1011,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2689,587,587,587,587,587,587,587,587,2716,587,587,587,541,587,563,541,541,1136,0,0,0,0,0,0,0,0,0,0,365,365,0,0,0,0,0,0,2095,0,0,0,0,0,0,0,0,0,0,2375680,0,0,0,0,0,587,1503,587,587,587,587,587,587,587,587,587,587,587,587,587,587,2911,587,2914,587,587,587,587,2919,587,563,587,587,587,587,587,1079,1560,0,0,0,1566,0,0,0,1572,0,0,0,1578,0,0,0,0,0,0,0,0,0,0,0,0,2754,0,0,0,563,563,563,563,2600,563,563,563,563,563,563,563,563,563,563,563,26028,1922,587,587,587,0,0,0,0,647,0,0,0,0,0,0,743,541,541,541,541,541,541,2178,541,541,541,541,541,541,541,541,541,0,2242,563,563,563,563,563,0,0,1594,0,0,0,0,0,0,0,0,0,0,0,0,0,2770,0,0,563,563,563,1846,563,563,563,563,563,563,563,563,563,563,563,563,3085,563,3087,563,2187,541,2189,541,541,541,541,541,541,541,541,541,541,541,541,541,1821,541,1360,0,0,563,563,563,563,2248,563,563,563,563,563,563,563,563,563,2305,563,563,563,563,563,563,563,563,563,0,587,587,994,587,587,587,563,2274,563,563,563,563,563,563,563,563,563,563,563,563,563,563,2894,563,587,2361,587,587,587,587,587,587,587,587,587,587,587,587,587,587,3121,587,587,587,587,587,587,587,587,563,563,541,563,587,563,587,1,2623,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,3101,563,563,563,563,2651,0,0,0,0,0,0,587,587,587,587,587,587,587,587,587,2340,587,587,587,587,0,0,3179,0,0,0,0,0,0,0,0,0,0,0,0,0,2798,0,0,3245,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,3257,563,1134592,0,1134592,0,0,0,1134592,1135008,1135008,0,0,0,0,0,1135008,0,0,0,0,0,2478,0,0,0,0,0,0,0,0,0,0,0,3180,0,0,3307,0,1134592,0,1134592,1134592,0,0,0,0,1135203,1135203,1135203,1135203,1134592,1135203,1135203,1135203,1135203,1135203,1135203,1135203,0,1134592,1134592,1134592,1134592,1135203,1134592,1135203,1,0,0,2125824,2125824,2125824,2125824,2125824,2424832,2433024,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,0,988,2125824,2125824,2125824,2125824,1147355,1147355,1147355,1147355,458,458,1147355,458,458,458,458,458,458,458,458,1147406,1147406,1147406,1147406,1147406,1147406,1147406,1147406,1147406,1147406,1147406,1147406,1147406,1147406,1147406,1147406,0,0,0,0,0,0,0,0,458,0,0,0,0,0,1147355,1147355,1147355,1147406,1147406,1147355,1147406,1147406,1,12290,3,0,0,0,0,249856,0,0,0,249856,0,0,0,0,0,0,0,69632,73728,0,0,0,0,425,65536,0,1159168,0,0,1159168,0,1159168,1159168,0,1159168,1159168,0,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,0,1159168,1159168,0,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,0,0,0,0,0,0,0,0,0,1159168,0,0,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1159168,1,12290,3,78115,293,0,0,0,0,0,0,0,0,0,0,0,0,131072,131072,0,0,1163264,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3170,0,913,2125824,2125824,2125824,2125824,2125824,2424832,2433024,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,2125824,0,0,1453,2125824,2125824,2125824,2125824,106496,0,106496,106496,0,106496,106496,106496,106496,106496,106496,106496,106496,106496,106496,106496,106496,106496,106496,106496,106496,0,0,0,106496,0,0,106496,106496,106496,106496,106496,106496,106496,106496,106496,0,0,0,0,0,0,0,0,0,0,0,2183168,0,0,0,0,0,0,0,0,2134016,0,0,0,0,0,0,0,0,0,0,541,541,541,1275,541,541,0,0,0,3117056,0,0,0,0,0,0,0,0,0,0,0,0,2979,0,0,0,0,3108864,3198976,0,0,3043328,0,3149824,2936832,0,2760704,0,2437120,0,0,0,0,0,0,2107,0,0,0,0,0,0,0,0,0,365,0,293,0,0,0,0,0,0,0,0,2875392,0,0,0,0,0,0,0,0,0,0,2834432],r.EXPECTED=[1039,1047,1048,1046,1042,1052,1056,1060,1064,1068,1446,1074,2948,2053,1092,1446,2490,1670,1213,1080,1084,1085,1446,1089,1446,1446,2818,1098,1103,1108,1187,1181,1181,1114,1118,1446,1933,1123,1446,1136,1098,1098,1204,1108,1108,1171,1181,1181,1130,1134,1446,1446,1140,1446,1147,1098,1152,1108,1108,1109,1181,1181,1182,1158,1446,1446,1238,1668,1098,1148,1108,1108,1206,1181,1181,1165,1446,3130,2162,1098,1099,1108,1177,1181,1215,1219,2143,1136,1098,1186,1110,1181,1191,3130,2153,1099,1108,1180,1217,2659,2819,1197,1173,1201,1104,1235,1210,1224,1154,1228,1232,1168,1243,1247,1251,1255,1259,1261,1266,1262,1270,1274,1278,1282,1286,1290,1220,1295,1890,1296,1446,1446,1446,1446,1375,2489,1446,1446,1446,2385,1446,1446,1446,1446,1446,1446,1446,1446,1076,1446,1446,1446,1446,2986,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1300,1304,1305,1309,1405,1315,1318,1322,1326,1330,1446,1446,1804,1334,2315,1338,2350,1142,1143,1342,1346,1446,1446,2834,1352,1362,1369,1446,1126,1446,2386,1379,1446,1384,1390,1446,2987,2588,1396,2688,1457,1446,1518,1446,1446,2269,1446,1446,1446,1402,1446,1441,1897,1409,1413,1446,1447,1419,1446,1447,1419,1446,1446,1193,1446,2988,3136,2482,1446,2617,1425,1446,1448,1431,1446,1918,1446,2648,1436,1457,1348,1457,1380,1440,1446,1445,3050,1452,1446,1456,1311,1446,1916,2325,1463,2125,1347,1472,2317,1909,1478,3010,2343,2076,2746,2758,1482,2765,2077,1799,1486,2744,1493,1358,1446,1446,2131,1446,2559,1386,1365,1497,1501,1505,1509,1515,2369,1569,2450,1522,2538,1526,1530,1536,2479,2088,1457,1971,1540,1544,1548,1552,1557,1446,2103,1446,1532,1446,2479,2082,1563,1568,2137,1573,1577,3026,1446,1446,2116,1446,1446,3027,1446,1586,1938,1584,2123,1647,1590,1432,1594,1446,2517,1600,1446,2517,1600,1446,2872,1606,1612,1616,1620,1626,1446,1239,1633,1446,1596,1640,3118,2782,1645,1651,1863,1446,1863,1446,1602,1446,2675,2173,1655,2685,1559,1866,2685,3124,1659,1665,2904,2903,3055,2673,1674,1678,3047,2266,2239,1682,1686,1690,1694,1698,2892,1702,1715,1719,1723,1727,1731,1446,2332,1773,1737,1744,1748,1751,1755,1758,1446,1772,2979,1777,1781,2506,1788,1792,1635,1636,1446,2668,2874,1796,1808,2784,1815,1819,1823,2304,1828,1446,2430,1446,1446,2334,1853,2583,1834,1843,1446,2069,1446,1446,1954,1446,1446,2070,1446,1446,1622,1608,1847,1851,1857,1641,1871,1446,2225,1956,1446,2225,1956,1446,2374,1885,1876,1811,1446,1883,1446,1947,1889,1446,1511,1446,1291,2287,1894,1901,1906,1446,1906,1446,1913,1446,1740,1922,1446,1932,1733,1446,1932,1830,1094,1732,1446,1937,2066,2439,2671,1945,1942,2455,1489,2323,1951,1709,1711,1629,1161,1962,1968,1977,1980,1984,1446,1119,1994,1999,2003,2007,2011,2015,2019,2023,1986,1872,2093,1928,2028,2032,2036,1802,2040,1446,1446,2044,1580,2050,2059,2063,2074,2046,1446,2024,2081,1446,2086,1446,1446,1988,2092,2097,2109,2113,1446,2120,1446,1446,2129,1446,1558,2135,1446,1446,2141,2535,2866,2147,1446,1990,1446,1446,3096,1446,1446,3096,1446,1446,1466,2151,2157,2204,1458,2161,1446,2914,1446,1446,1764,1446,3053,2166,2170,1446,2182,1446,2187,1446,2916,1957,2192,2202,2305,1446,2210,2496,1824,3112,2217,1761,1459,1558,2224,2229,2841,2969,2682,2815,2233,2248,2236,2243,1837,1839,2247,2252,2100,1446,1446,1446,1446,2918,1766,2256,2260,2273,2277,2281,2284,1446,2889,1902,2985,2524,2433,2299,2576,2212,2213,2303,1415,1457,2309,1958,2321,2329,1446,2976,1446,1398,1446,1553,2338,2342,2751,1446,2347,2503,2354,2358,1558,2363,1446,1995,2368,1446,1421,2364,2373,2733,2378,2383,2390,3044,1446,2715,1446,1446,1860,1446,1446,1860,2719,2733,2397,2176,2401,1946,2461,1446,1446,2405,1446,1473,2717,2413,2417,2427,2437,3061,1446,2105,1446,1973,2407,2443,2447,2454,2459,2379,1446,2465,2472,2476,2486,2511,2494,2701,2409,2500,2510,2516,2521,2528,2220,2532,2542,2546,2198,2312,2550,2554,2563,2567,2571,2575,1446,2580,2592,2596,2600,2604,2608,2612,2616,1446,2621,2393,1372,2628,2632,2636,2640,2652,3103,1446,2708,2468,2656,2665,2679,2692,1558,2699,1446,2705,1446,2998,2712,1446,2723,2624,1768,1879,3159,1446,2205,2727,1446,1468,2732,1446,2206,2982,1446,3004,2737,2741,3109,2750,1446,2755,1446,1446,2762,1446,1446,2762,2769,3037,2775,2420,2779,1446,2788,1446,1446,2795,1446,1427,2801,3020,2805,2646,1446,2812,1446,2809,1446,3067,2853,2823,2643,2183,2827,2863,2512,2832,2838,1707,1070,2359,2845,2851,2857,1964,1474,3084,2557,2878,2955,3090,2882,2293,2295,2886,2896,2900,2908,2912,1446,1446,1446,2922,2926,2930,2934,2938,2942,2946,1446,2055,2952,1355,2791,2178,2959,1867,2963,1784,2967,1446,2973,2423,2992,2996,3002,1446,2728,1446,1446,3008,1446,3014,3018,1446,3024,2188,3031,3147,1446,1446,2694,1446,1446,2847,1446,1446,2695,3035,1446,3041,3078,3141,3059,1446,1446,3065,1446,1446,3065,1446,1446,3071,1446,3075,1925,3153,1446,1446,3082,1446,1564,3088,1446,1661,3094,3100,2195,3116,1446,3122,1446,3128,1446,3134,1705,3140,2586,2797,1446,3145,2771,1392,3151,1446,3157,2290,2828,2661,2869,2422,3106,2860,2263,1446,1446,1446,1446,1446,1446,1446,1446,1446,1446,1473,3163,3166,3170,3182,3186,3182,3189,3181,3182,3182,3182,3182,3177,3173,3193,3182,3197,3201,3204,3210,3214,3216,3206,3220,3224,3228,3232,3235,3239,3243,3729,3929,3929,3246,3929,3929,5383,3929,3929,3300,3929,3261,3562,3273,4078,3734,3929,3929,3929,3277,3287,3294,4847,3929,3250,3929,3929,3344,3929,4873,4873,4873,4873,3266,4873,4873,3564,3564,3567,3564,3564,3564,3564,3267,3256,3305,3562,3568,3335,4081,3929,3929,3929,3323,4919,3377,4693,3929,3252,3722,3750,3365,3315,3269,3334,4080,3732,3929,3929,3559,4873,5799,4692,3929,3929,3688,3929,3929,3560,4873,4873,4873,4195,4873,4873,4873,4874,3564,3267,3264,3331,3339,3929,3342,3929,3738,3256,3367,3317,3321,3560,4873,3564,3309,3256,3256,3365,3371,3564,3564,3564,3567,3256,3256,3256,3256,3327,4195,3564,3564,3564,3310,3365,3359,3929,3929,3813,3929,3564,3564,3564,3364,3929,5741,3559,4873,4194,3564,3564,3268,3256,4193,4873,3266,3564,3310,3256,3256,3256,3366,3348,3929,3929,3929,3505,3383,3256,3373,3766,3256,3384,3929,4872,4874,3564,3268,3256,3257,3373,4694,3929,3929,3929,3355,3566,3256,3321,4194,3565,3311,3560,3563,3384,3561,3319,3360,3388,3390,4109,3394,3401,3405,3429,3429,3429,3429,3424,3430,3412,3416,3420,3428,3434,3438,3442,3397,3446,3450,3453,3457,3460,3463,3465,3469,3473,3408,3477,3481,3485,3696,3498,4473,3929,3929,3929,3512,3511,3929,3929,3929,3517,4964,4966,3929,3523,3527,3929,3929,3929,3752,3534,3543,3929,3929,3850,3854,3578,3582,3586,3589,3590,3594,3597,3601,3604,3608,3611,3614,3618,3622,3626,4965,3648,3636,5178,3647,5820,3654,4257,3659,3929,3669,4219,3694,3703,3929,5714,3525,3929,3929,3929,3770,3790,3929,5539,3707,3929,3342,5695,3904,3929,3289,3290,3906,3929,4658,4464,5227,4306,3936,3718,3726,3743,3929,3375,3631,3929,3548,5050,5064,3749,3929,3929,3929,3836,3758,3298,3929,3929,3915,3927,4893,3528,3929,3929,3921,4548,5744,4281,3929,3929,3932,5019,3929,5587,5178,3929,3553,3557,3572,5826,3929,3929,4530,3789,3794,3929,3929,3972,4899,3798,3806,3929,3929,3972,5040,3817,3826,3929,3929,3972,5490,3785,3929,3929,3929,3869,4728,4203,3770,3790,4142,3929,3929,3929,3894,4001,3929,3929,3929,3929,3252,3798,4127,4203,3850,3854,4139,3744,3929,3929,3929,3844,5313,5832,4137,4141,3929,3650,3929,3929,4854,4858,4140,3929,3929,3929,3930,5557,3873,3929,3929,3883,3929,5107,3929,5107,4780,3929,4781,5020,3929,3929,3738,5109,3929,3290,3904,3940,3947,3946,3942,3951,3955,3956,3956,3960,3962,3963,3962,3967,3971,3929,3929,4017,4021,4708,3978,3988,3929,3683,3781,3802,3995,4392,3929,5597,5363,3530,3929,4135,4005,4013,3929,3929,4065,4070,4026,3929,3929,4026,3375,3929,3929,4049,4056,4576,3997,5403,5596,3929,3856,4795,3529,3929,3929,3929,3931,4061,3929,3929,3929,3972,4199,3911,3929,3929,3929,3974,5170,3929,3929,4704,3929,4075,5320,4248,5165,3855,4657,4085,3929,3690,4699,5178,3978,3251,3929,3929,4101,3929,5319,4247,5772,5010,4113,3981,3929,3929,4164,4148,4148,4120,3929,3929,4165,4115,4709,4132,3929,3929,4247,4459,5170,3929,3929,4706,3879,4572,4576,5321,4249,4655,3929,3929,4274,3929,3972,4146,4150,3929,3735,3929,3735,4154,4158,3929,3929,4396,3929,3929,3982,3929,3929,3929,4029,4107,3929,4706,3929,4366,4574,4181,5320,5850,4644,4180,5319,4886,4217,4208,4673,3929,3929,4424,5855,3279,5321,4215,3929,3766,4873,4873,3563,3564,4228,3929,4451,4182,4233,4305,4240,4273,4435,4246,4434,4245,4708,4241,3929,3699,4502,3698,4255,5609,4272,5609,4272,3699,5199,5610,4273,4253,3281,4246,4270,3929,3809,3929,4549,3737,3929,3896,3929,5021,3770,4271,3771,4182,5163,5161,3929,3283,5762,3710,4279,4279,4211,4127,4128,4405,3712,4286,3929,3929,3929,4052,3929,5548,3754,4301,3929,3842,3574,4534,4651,5125,3745,4537,4310,4314,4318,4319,4323,4327,4333,4334,4331,4338,4339,4339,4340,3929,3844,4827,3929,3846,3929,3929,4905,3929,3376,5780,4202,3929,3929,3929,4235,4524,5352,5187,4364,4473,3342,4273,3929,3888,5737,4840,4356,4374,4378,4842,5051,4864,3929,4387,4491,3929,4413,3929,3892,5107,3929,3665,3929,3929,4681,3640,4265,4472,3929,4802,3929,4518,3670,4266,4421,3929,4204,4203,3929,4718,4428,4432,3929,3929,3929,4451,4440,4445,3929,3929,4450,4541,4470,3929,3343,3929,3897,3929,4294,3929,4296,3929,5616,3929,5461,4463,3929,5347,4362,5468,4800,3929,3929,4457,4461,5243,3929,4484,3929,3931,5074,3929,3972,4166,4116,3929,3929,3929,4035,4737,3929,3929,3929,4505,3929,5347,4495,3929,3972,5410,5415,4015,4019,3929,3929,4457,4490,4499,3929,3929,3929,4624,5347,3929,4801,3929,3997,3929,5743,4160,3929,3929,3929,4628,3929,5704,4529,3929,3998,5353,5435,3929,5703,4528,3929,4e3,3929,3929,3999,3528,4505,5352,4800,3929,4007,4653,3929,4009,3929,4642,5697,3929,3929,3929,4695,4052,3929,3929,3929,4708,4545,3929,3929,3301,4450,3929,3929,3929,4734,3929,5303,3342,3929,4030,4480,3929,3929,3929,4516,4994,3894,3929,3895,3929,3929,3351,3892,3737,3735,3929,4039,3929,3929,4086,5090,3895,5020,3895,3737,5022,3736,3737,4554,4556,3929,3929,4638,4794,3929,3929,4668,4806,4689,3929,3929,3929,4752,4504,3929,3929,5097,4566,4022,5334,4383,5691,4570,4582,4586,4590,4594,4598,4602,4605,4608,4612,4614,4618,4634,4632,4634,4621,3929,3929,3929,4757,4725,4816,3929,4648,4662,4666,5081,4672,3929,5344,4398,4352,4678,3929,3929,4678,4687,5178,3929,3929,4745,4749,4210,3929,4965,4768,5739,3929,3929,3322,5689,3899,5181,4703,5110,5214,4713,4722,3929,4051,3558,3929,4028,4478,4500,3929,5400,4741,3929,3929,4780,3929,4780,4762,3929,3929,3929,4821,4756,4761,3929,3929,4818,4822,4505,3863,3867,3929,3341,3341,3929,4766,4294,3929,3899,3929,4066,3929,3929,4087,5091,3767,5433,4817,4683,4716,3929,5809,3929,4091,4095,3751,3972,4773,4777,3929,4107,3929,3929,4137,4141,4786,4775,3929,3929,4820,3910,4788,4777,3929,3929,4828,3972,3322,4792,3929,3929,4847,3929,5432,4816,4833,4799,3929,5147,3929,3929,4872,4873,4966,4295,4304,4814,4826,3929,3929,3929,4871,4674,3929,4708,3897,5180,5433,4832,3929,4159,3929,3377,3299,3929,4503,4708,3929,4837,3929,3929,3929,4913,5207,3929,3929,3929,4965,3929,5148,3929,4008,3929,4408,3929,4172,3929,4172,3900,5432,3628,3929,3929,3929,4856,4860,3844,5313,3929,3929,4982,3929,5086,3768,5434,3630,3929,4174,3929,4562,5312,3929,3929,3929,5003,4502,5148,4878,4885,4293,3929,3929,4296,3929,4296,3929,4229,5198,5520,3928,3929,3928,3897,4293,3929,3898,3929,5228,3899,3898,3929,4296,3929,5547,3519,4911,3929,5584,4917,3769,3929,3929,3929,4240,4273,3929,3779,3800,3744,4923,4927,4934,4935,4930,4939,4943,4949,4953,4945,4957,4957,4958,4962,3929,4247,4511,3929,3972,5871,3929,3983,3929,5572,5591,3929,4731,4359,5861,5581,4990,3929,3929,3929,5111,4846,5503,4707,5051,3929,4263,4465,3929,4282,3929,3929,3860,3929,5742,3929,3929,3737,3929,3894,5322,3929,5e3,5007,3507,3929,4290,3929,3929,4449,3929,5018,3929,3929,3642,5026,3929,3929,3929,5177,4628,3929,3300,3929,4346,3674,3681,3547,3929,3539,5030,5034,3929,3929,3929,5337,5040,3822,3929,3929,3641,5042,3929,3929,3929,5368,3643,3929,3929,3929,5405,5793,3929,3929,3929,5453,4626,3377,5052,3929,3929,3929,3721,4501,4368,3929,3546,3490,5496,5308,5793,3929,3929,5485,4370,3929,3929,5068,3972,5073,4863,3929,3513,4450,5122,3375,5406,3842,3929,3655,5793,3929,3739,4707,5781,3929,3990,3929,3929,4006,3299,4452,4369,3929,4439,4444,3929,3895,4547,3886,3929,5078,3929,3929,5048,5304,3929,5095,3929,5486,5051,4451,4368,3929,4474,4050,4057,4293,4450,3929,3929,5228,3929,5453,3929,3929,5072,4862,3929,5101,3929,3512,5742,3929,5241,5105,4986,3751,5323,3296,4502,4381,3929,4486,4034,3929,3684,3783,3744,5062,3929,3929,4209,3929,3929,3929,3560,3929,5118,3929,3929,5111,4852,4515,4382,5129,3929,4502,4176,3929,4350,5314,3549,3929,5797,3929,3929,3929,5526,5795,3929,3929,3929,5603,5136,5144,5227,4451,4236,3929,4975,3676,5063,4465,3744,4042,4464,5152,3929,4507,3865,3929,4121,5622,4297,4174,3342,5169,3342,5169,4514,3537,4561,4558,3929,4559,4453,3929,5213,4466,3929,4520,3929,3929,5170,4045,5196,5187,5174,4560,5185,4558,5193,5203,5211,5218,5221,5222,5226,3929,3929,3929,5725,3929,5232,4690,3929,4524,5352,3677,3929,3929,3929,5771,3929,5740,3929,4274,4848,5238,5247,5773,5254,5251,4704,3918,5260,5266,5262,5268,5272,5276,5280,5284,5287,5291,5294,5293,5298,5302,3929,3929,3929,5742,5425,3929,4694,5050,3546,3490,3494,3929,5318,3929,5327,3923,4464,4390,5227,3929,5816,5331,5341,3929,5782,3744,3929,4547,3770,3929,4547,3929,3736,5322,3929,5189,3929,3929,5189,5361,5367,3374,3929,4693,3929,3929,3829,3929,5372,3929,5411,3929,4704,4292,3929,3892,3929,3929,4517,5713,4819,4170,3929,5416,3991,3929,4708,4852,3929,4186,4190,3929,3765,3775,3800,5841,5084,3929,3929,5111,5157,3753,5377,5381,3929,3929,5117,3929,3929,5388,3821,3929,4708,5234,4550,3929,5393,5392,3929,4751,5041,3744,3929,3929,5048,5036,3929,5373,5397,4693,3501,3929,3929,3929,5766,4862,3929,3929,3929,5789,5048,4769,3378,3492,5429,4705,5779,3929,4781,4779,3929,4505,5110,3876,3929,3929,3929,5791,3972,5439,3839,3929,4815,3929,4778,5514,5443,3839,3929,4815,3929,5108,5841,5843,3929,3929,5139,3929,5050,5457,3492,4485,5465,3770,3878,3929,4821,3929,3929,4417,3929,3929,5472,5477,3929,4881,3929,5701,5473,5482,3929,3929,5140,3929,5478,3929,5420,3877,3546,5494,3714,3632,3929,5514,5508,3929,4907,5500,3929,4890,4880,3929,4193,4873,4873,4195,5742,3379,5773,3631,5525,3929,3929,3929,5870,5524,3760,3896,3929,5819,4519,5513,3488,5530,5351,3929,4708,4846,4159,3929,3929,3929,5155,5159,5336,5518,3761,3929,3929,5512,5536,4519,4522,3989,3929,3929,3929,4913,5518,3929,4964,4293,5179,5352,3929,3929,4125,3929,3929,4247,4402,4086,3353,3929,5556,5570,3929,5570,5578,3983,3929,5573,3929,4971,3751,3929,4253,3929,4261,5594,4522,3929,5601,3984,3929,5574,3929,4978,4224,3929,3929,5608,5571,5607,5351,5349,3929,3929,3929,5206,4827,3929,3929,4897,4901,5733,5834,3662,4782,5757,3879,5132,5614,5467,5620,5626,5630,5634,5638,5642,5646,5650,5654,5658,5662,5666,5670,5673,5677,5681,5685,3929,3929,5256,4275,5756,3929,3972,3929,4996,3929,5561,5708,5718,3929,5722,5729,3929,3888,3998,5749,3929,3929,3929,5311,3929,5731,5753,5459,3929,5014,4985,3929,4344,4461,3929,3875,5420,3929,3878,3929,3929,3929,3736,4071,4506,3929,3766,4521,4967,3929,3929,3929,5387,3820,5761,4485,3929,3929,5424,4691,5113,3998,3929,3929,5435,3873,3929,5112,5770,4234,5849,3929,3929,3929,5447,3929,5732,5805,3929,3972,4093,4097,3929,3905,3929,4408,3670,5786,3929,3929,3929,5447,4693,4517,5803,5807,3929,5046,5056,3929,4434,4245,3929,3770,5321,3929,3649,3929,3929,4977,4223,3929,5830,3929,3929,5450,5042,4423,5838,3929,3929,5507,4159,4423,5838,4248,5847,4578,5805,3929,4548,3929,3929,5813,4423,5854,3929,3929,5552,5542,5859,3929,3929,3929,5564,3929,5786,4235,3929,3929,5566,4810,4103,5807,3990,3929,5059,5357,3929,4549,3929,3929,4549,5416,3929,4674,3929,4868,5532,3929,3929,3929,5710,3929,3831,3998,3929,3929,5712,4818,3973,5866,3929,3929,5739,3929,3972,5865,3929,3929,5745,3929,4964,3929,5180,4523,5824,3832,3929,3929,3929,5777,5545,4965,3929,4409,3929,3675,3738,3973,3547,3929,3929,5841,3929,6277,6502,5875,6282,5878,6547,6266,5881,6546,5889,6232,5882,6232,5892,6221,6267,5888,5883,5884,6232,6232,6232,6232,6414,5887,5883,6232,5891,6232,6232,5894,6232,6232,5922,5937,5949,5938,5939,5949,5944,5950,5944,5944,5940,5944,5941,5952,5941,5944,5946,5945,5946,5946,5946,5946,5947,5941,5948,5952,5948,5944,5942,5954,5956,5958,5962,5960,5959,5964,5966,5967,5971,5967,5968,5967,5969,5974,5973,5976,5978,6293,5998,5875,6282,5896,6871,6437,6282,6321,6282,6282,6282,5917,6456,6456,6456,6456,5991,5906,6379,6455,5990,6019,5991,5904,5904,5904,6456,6456,5926,5899,6456,6456,5997,6282,6408,6410,6282,5932,6282,5933,6464,6024,6282,6282,6379,5924,6282,6282,5924,6282,6362,6010,5984,6282,6003,6282,6362,6282,6282,6282,6004,6456,5906,6455,5990,5904,5902,6456,6456,6456,5906,6457,6019,6019,5904,5904,6456,6456,6282,6282,6282,5980,5917,6456,6456,6456,6455,5905,6456,6445,5926,5926,5926,5926,6032,6032,6008,5932,6282,6282,6282,6434,6024,6282,6019,5904,6456,6282,5896,6873,6282,6282,6282,6474,5903,6457,6019,5904,6456,6229,5904,6456,6456,6456,6018,6457,6019,5991,5905,5906,6282,6282,6282,5984,6282,6282,6282,5925,6543,5905,6456,6456,6456,6282,5905,6229,5905,6229,5905,6282,6650,6437,6043,6515,6056,6672,6088,6052,6515,6520,6054,6060,6058,6515,6515,6083,6528,6101,6761,6518,6521,6516,6517,6063,6065,6068,6061,6057,6515,6515,6519,6515,6070,6072,6066,6515,6515,6515,6515,6125,6522,6074,6515,6515,6076,6515,6523,6079,6082,6515,6081,6055,6091,6089,6090,6093,6114,6092,6113,6114,6114,6114,6114,6115,6117,6116,6117,6117,6118,6119,6120,6121,6121,6095,6097,6099,6122,6123,6124,6524,5900,6515,6518,6103,6108,6110,6104,6105,6109,6106,6112,6121,6127,6129,6282,5899,6282,5925,6463,6321,6282,6294,6006,6378,6282,6508,6282,6449,6646,6218,6604,6282,6524,6291,6282,6774,6282,6270,6282,6282,6282,6e3,6e3,6027,6161,6282,6282,5895,6375,6282,6312,6230,6366,6265,5876,6282,6282,6282,6015,6406,6282,6284,6027,6027,6137,6282,6282,6379,6281,6372,6028,6159,6282,5899,6282,6282,6282,6573,6282,6282,6467,6282,6311,6312,6372,6282,6282,6282,6019,6019,5904,5904,5904,5904,5905,6456,6456,6031,6154,6158,6282,6149,6273,6282,6163,6282,6677,6280,6166,6279,6682,6685,6501,6173,6175,6178,6178,6178,6178,6176,6181,6180,6181,6181,6183,6181,6185,6187,6188,6188,6188,6194,6193,6194,6193,6193,6189,6191,6190,6190,6196,6196,6198,6203,6202,6204,6208,6203,6205,6199,6200,6210,6206,6212,6282,6282,5896,6282,6282,6282,6512,6282,6150,6135,6320,6500,6163,6282,6282,6282,6026,6282,6026,6166,6282,6282,6282,6027,6221,6282,6505,6282,6282,6282,6032,6238,6282,6241,6282,5899,6451,6282,5913,6669,6401,6238,6282,6282,6282,6037,6245,6282,6282,6282,6040,6282,6282,6225,6248,6282,6282,5916,6722,6377,6247,6249,6282,6282,5924,6370,6252,6253,6282,6282,5932,6282,6282,6530,5924,6254,6282,6282,6254,6282,6322,6228,6282,5933,6378,6282,6378,6282,6452,6282,6432,6317,6282,5917,6086,6725,6727,6216,6086,6726,6450,6231,5926,5933,6008,6008,6008,6282,6282,6282,5918,6282,6282,6282,5923,6309,6683,6282,6282,6282,6148,6216,6308,6310,6282,6282,6282,6149,6282,5903,6397,6605,6282,6282,5933,5933,5933,6780,6282,6282,6282,6229,6282,6282,6282,5933,5924,6316,5917,6723,6377,5916,6722,6323,6448,6454,6216,6332,6436,6683,6282,5917,6328,6465,6450,6217,6231,6160,6436,6683,6328,6448,6454,6216,6610,6436,6683,6282,6221,6602,6310,6282,5984,5899,5925,6229,6435,6500,6281,6722,6013,6465,6450,6160,6603,6683,6282,6282,6231,6218,6310,6282,5984,6282,6283,6043,5914,6282,5933,6328,6465,6450,6647,6604,6282,6e3,6282,6282,6283,6277,6707,6733,6282,6722,6465,6230,6396,6282,6282,6282,6235,6686,6282,6708,6281,6282,6e3,6437,6362,6338,6279,6282,6282,6283,6444,6145,6683,6282,6282,5933,6003,6282,6282,6282,6006,6375,6465,6708,6282,6005,6282,6282,6287,6289,6282,6548,6282,6282,5933,6282,6282,6282,6137,6282,6282,6020,6282,6375,6282,6282,6282,6281,6471,6218,6683,6282,6282,6282,6370,5984,6282,6010,6795,5984,5899,6282,6282,6661,6282,6e3,6137,6282,6282,6282,6282,5896,5914,6704,6273,5928,6340,6344,6503,6348,6349,6349,6350,6355,6352,6349,6349,6349,6349,6354,6355,6355,6355,6356,6357,6357,6357,6357,6357,6358,6359,6359,6359,6359,6383,6360,6382,6382,6382,6361,6282,6282,6282,6283,6043,5903,5897,6485,6376,6395,6425,6282,6282,6282,6293,6291,6338,6282,6282,6282,6284,6282,6282,6345,6282,6282,6291,6282,6282,6282,6230,5876,6282,6407,6282,6282,6282,6286,6282,6282,6037,6411,6417,6282,6282,5979,5903,6470,6313,6647,6281,6282,6282,6408,6416,6418,6282,6282,5979,6525,6458,6342,6422,6282,6282,6282,6288,6282,6664,6731,6282,6012,6e3,6282,6012,6335,6310,5985,6504,6282,6282,6273,6470,6372,6273,6504,6385,6282,6282,6412,6257,6598,6600,6282,6411,6413,6597,6599,6599,6282,6282,6282,6291,6410,6282,6322,6451,5926,5926,6008,6008,6008,5932,6236,6282,6282,6282,6292,5982,6282,6283,6442,6050,6013,6609,6259,6424,6310,6282,5919,5920,6282,6282,6011,5916,6282,6664,6282,6282,6023,6437,6459,5983,6013,6594,6700,6437,6282,6424,6437,6282,6282,6235,6480,6481,6282,6282,6133,6282,6282,6485,6376,6647,6282,6016,6282,6282,5933,6330,6454,6217,6683,6282,6282,6484,5917,5929,6011,6608,6259,6425,6282,6486,5983,6013,6594,6786,6437,6282,6282,6282,6294,6282,6283,6484,5917,5983,6013,6531,6471,6282,6282,6146,6683,6282,6282,6155,6282,6282,6385,6282,6322,6282,6282,6275,6493,5917,5983,6324,6259,6729,6282,6019,6019,6019,5991,5904,6277,5903,6531,6011,6148,6282,6282,6282,6234,6531,6282,6282,6282,6322,6282,6133,6372,6505,6282,6230,6282,6282,6171,6756,6531,6046,6834,6437,6282,6282,6285,6530,5924,6282,6684,6282,6149,6282,6282,6282,6325,6285,6530,6045,6159,6024,6046,6386,6282,6282,6282,6372,6282,6294,6282,6530,6464,6386,6282,6282,6215,6224,5933,5924,6410,6282,6040,6282,6482,6282,6282,6282,6531,6536,6024,6282,6282,6282,6370,5987,6282,6535,6282,6282,6227,6282,6282,6282,6378,6378,6378,6282,6452,5994,6282,6282,6282,6394,6282,6282,6282,6404,6539,6333,6683,6282,6020,6282,6282,6282,6341,6282,6570,6300,6569,6301,6370,6545,6300,6302,6303,6303,6303,6303,6303,6304,6551,6554,6552,6561,6552,6555,6563,6564,6563,6563,6563,6563,6564,6556,6557,6557,6557,6557,6558,6372,6273,6282,6282,6243,6282,6509,6566,6282,6282,6271,6213,6282,6283,6568,6282,6021,6041,6282,6027,6282,6321,6282,6006,6282,6282,6027,6462,6282,6282,6282,6572,6282,6168,6282,6575,6510,6282,6029,6282,6282,6282,6588,5907,5909,5911,6282,6036,6282,6282,6388,6407,5908,5910,6282,6282,6272,6282,6526,6282,5916,6322,6282,6378,6282,6020,6282,6278,6282,6282,6394,5924,6278,6282,6283,6502,6365,6282,6579,6282,6282,6275,6525,5914,5992,6371,6048,6365,6367,6369,6282,6282,6277,6531,6046,6275,6583,5993,6047,6256,6256,6366,6368,6282,6282,6452,6e3,6282,6282,6282,6408,6282,6027,6282,6372,6526,6282,5899,6539,6664,6682,6282,6282,6282,6146,6282,6482,6282,6006,6451,6282,6282,6282,5985,6458,6342,6313,6136,6152,6282,6037,6378,6282,6282,6282,6421,6584,6020,6437,6683,6282,6027,6321,6282,6451,6646,6152,6282,6282,6282,6410,6282,6282,6282,6375,6282,6e3,6526,6322,6533,6682,6282,6408,6282,6282,6282,6505,6282,6282,6278,6282,6282,6282,6143,6371,6472,6282,6282,6282,6423,6539,6437,6683,6282,6040,6148,6040,6149,6273,6229,6682,6282,6470,6282,6282,6283,6282,6282,6282,6524,6548,5933,6282,5933,6282,6434,6410,6282,6282,6434,6537,6282,6664,6491,6866,5876,6482,6491,6282,6282,6283,6410,6282,6427,6282,6282,5980,6011,6276,6037,6285,6038,6590,6783,6607,6612,6620,6619,6620,6620,6616,6620,6620,6618,6622,6620,6614,6613,6624,6627,6626,6627,6627,6628,6630,6630,6634,6630,6632,6631,6630,6630,6630,6636,6638,6638,6637,6637,6640,6641,6282,6132,6282,6282,5895,5924,5984,6282,6640,6637,6640,6640,6640,6640,6505,5903,6644,6331,6649,6282,6282,6229,5879,6282,6527,6653,6148,6282,6137,5924,6282,6282,6282,6230,6281,6282,6282,6306,6402,6433,6346,6656,6658,6549,6282,6282,6283,6475,6423,6282,6282,6282,6437,6682,5912,6668,6400,6282,6157,6282,6282,5896,6451,5980,5917,6029,6221,6281,6282,6282,6524,6282,6282,6282,5930,6664,6282,6264,6683,6694,6282,6282,6282,6452,6282,6282,6282,6285,5897,6453,6654,6282,6346,6295,6282,6282,6283,6582,6297,6282,6681,6282,6164,6024,6282,6133,6451,6282,5988,6281,6285,5980,6458,6371,6263,6647,6281,6282,6676,6282,6676,6514,5903,6680,6465,6489,5995,6282,6282,6283,6496,6085,6282,6513,6525,6679,6688,6688,6399,6713,6281,6282,6286,6282,6037,6282,6282,6282,5899,6691,6497,6724,6488,6734,6282,6282,6282,6498,6282,6282,6282,6255,6282,6283,6691,6696,6724,6488,6698,6331,6222,6282,6282,6282,6431,6296,6282,6282,6282,6499,6282,6282,5903,6464,6231,6734,6696,6134,6733,6281,6693,6282,6282,6434,6282,6282,6282,6277,6525,6531,6471,6218,6231,6490,6282,6282,6282,6504,6548,6282,6283,6278,6282,6275,6710,6733,6282,6169,6282,6282,6509,6003,6712,6282,6282,6282,6508,5899,6702,6490,6282,6282,6283,6861,6854,6033,6858,6646,6218,6604,6282,6282,6282,6577,6286,6282,6394,6282,6229,6019,6019,6019,6019,5904,6286,6282,6137,6282,6229,6282,6292,6229,6282,6282,6372,6505,6282,6437,6683,6282,6229,6146,6265,6282,6283,6525,5927,6539,6729,6683,6282,6282,6650,6282,6282,6283,6863,6364,6024,6282,6282,6283,6869,6282,6362,6282,6362,6363,6010,6592,5925,6719,6591,6593,6718,6721,5934,5934,5935,6469,6736,5934,5934,5934,6736,6738,6742,6740,6739,6744,6746,6751,6751,6752,6753,6747,6748,6748,6748,6749,6751,6751,6751,6753,6753,6753,6753,6758,6754,6755,6282,6282,6285,6282,6282,6282,6014,6760,5981,6007,6728,6282,6763,6282,6282,6285,6496,6531,6282,6283,6768,6770,6282,6282,6282,6539,6392,6282,6282,6392,6027,6156,6282,6282,6293,6586,6282,6373,6281,6285,6507,5903,6470,6326,6505,6659,6282,6234,6229,5879,6283,6496,6703,6776,6704,6777,6282,6282,6282,6548,6282,5918,6025,6282,6282,6026,6282,6286,6505,6394,6282,6291,6370,6282,6370,6282,6496,6085,6831,6147,6603,6683,6282,6380,6282,6282,6370,6282,6282,6282,6003,6282,6294,6336,6e3,6282,6239,6846,6282,6260,6282,6282,6282,6642,6379,6282,6505,6336,6283,6702,6782,6319,6218,6604,6282,6785,5999,6282,6269,6663,6282,6140,6282,6282,6393,6282,5982,6724,6319,6218,6604,6539,6310,6282,6282,6375,6370,6375,6788,6320,6310,6e3,6e3,6282,6282,6375,6548,6282,6282,6282,6275,6084,6447,6282,6788,6429,6683,6282,6282,6664,6683,6282,6273,6541,6148,6282,6394,6e3,6282,6274,6282,6003,6318,6429,6683,6282,6275,5898,5915,6282,6282,6370,6370,6370,6664,6282,6683,6282,6410,6282,6699,6282,6275,5901,5982,6724,6291,6282,6282,6531,6689,6282,6282,6220,6282,6537,6282,6282,6282,6664,6146,6282,6282,6434,6281,6282,6282,6282,6020,6282,6006,6410,6408,6282,6027,6282,6282,6250,6843,6434,6410,6282,6434,6410,6282,6408,6282,6322,6282,6410,6410,6027,6282,6275,6702,6231,6490,6146,6282,6146,6282,6282,6282,6671,6146,6410,6408,6408,6409,6409,6409,6409,6409,6282,6282,6282,6682,6282,6282,6285,6039,6216,6221,6281,6286,6282,6282,6790,6543,6282,6505,6003,6282,6559,6282,6282,6559,6508,6792,6282,6077,6139,6282,6282,6379,6374,6793,6806,6798,6798,6801,6799,6798,6799,6798,6797,6803,6808,6807,6808,6805,6808,6809,6810,6813,6814,6815,6816,6815,6818,6811,6813,6811,6813,6820,6822,6822,6821,6821,6824,6824,6824,6824,6821,6824,6824,6828,6825,6826,6282,6282,6282,6683,6282,6282,6689,6439,6282,6277,6715,6282,6282,6282,6510,6035,6282,6282,6282,6684,6282,6282,6282,6233,6282,6716,6282,6580,6419,6282,6836,6282,6281,6282,6282,6283,6293,6337,6282,6838,6840,6282,6282,6666,6282,6143,6292,6282,6282,6292,6282,6282,6282,6378,6845,6282,6282,6845,6282,6487,6282,6282,6391,6391,6651,6282,6282,6282,6730,6512,6282,6282,6282,6830,6853,5931,6141,6428,6602,6604,6282,6282,6409,6410,6282,6852,6854,6856,6450,6002,6282,6001,6003,6282,6645,6231,6281,6282,6282,6674,6282,6167,6282,6282,6e3,6282,6e3,6034,6282,6282,6282,6848,6282,6394,6683,6282,6282,5933,6003,5933,6003,6282,6830,6645,6231,6222,6487,6282,6024,6282,6282,6693,6282,6282,6282,6464,6861,6854,6009,6377,6525,5931,6011,6465,6282,6830,5885,6282,6282,6702,5931,6319,6436,6683,5916,6282,6282,5925,6282,6282,6448,6282,6282,6931,6282,6282,6451,6282,6282,6282,6860,6044,6011,6465,6449,6647,6310,6282,6282,6142,6436,6683,6282,6282,6732,5924,5984,6861,5983,6377,6454,5982,6321,6282,6294,6138,6282,6461,6151,6437,6282,6282,6732,6772,6860,5983,6465,6151,6437,6282,6865,6282,6282,6282,6860,6337,6437,6282,6282,6466,6282,6144,6436,6282,6282,6282,6868,6219,6282,6282,6282,6468,6282,6282,6732,6282,5916,6262,6299,6282,5918,5918,5918,6378,6282,6282,6526,6282,6148,6282,6283,6293,6586,6292,6502,6437,6282,6282,6282,6294,6282,6292,6294,6282,6282,6474,5980,6293,6291,6282,6282,6292,6502,6282,6278,6294,6282,6278,6282,6282,6765,6282,6229,6362,6282,6230,6320,6500,6282,6505,6282,6292,6502,6282,6505,6233,6282,6282,6293,6282,6282,6282,6474,6478,6291,6278,6282,6282,6292,6531,6536,6875,6255,6282,6282,6476,6282,6006,6255,6282,6006,6390,6282,6314,6049,6282,6877,6878,6881,6375,6880,5930,6282,6532,6542,6883,6596,6258,6885,6596,6595,6595,6886,6889,6595,6888,6890,6889,6892,6897,6893,6894,6895,6899,6900,6905,6905,6901,6902,6912,6903,6902,6906,6905,6906,6905,6906,6907,6909,6908,6910,6914,6908,6908,6922,6922,6921,6922,6923,6916,6917,6918,6920,6926,6925,6928,6460,6371,6282,6282,6482,5932,6321,6285,6282,6282,6494,6371,6930,6282,6282,6282,6505,6494,6371,6130,6282,6282,6282,6505,6506,6282,6282,6282,6312,6933,6282,6505,6935,6282,6282,6937,6282,6282,6767,6769,6290,6282,6282,6282,6505,6692,6011,6313,6291,6233,6282,6282,6508,6282,6282,6282,5916,6030,6282,6423,6170,6282,6282,6170,6011,6372,6282,5916,6282,6282,5915,6451,6440,6282,6282,5918,6322,6283,6939,6446,6705,6447,6291,6282,6282,6294,6282,6282,6282,6438,6282,6282,6511,6282,6282,6282,6842,6149,6282,6149,6282,6282,6779,6007,6728,6310,6282,6282,6319,6310,6282,6282,6363,6282,6692,6011,6372,5916,6282,5915,6282,6282,6511,6268,6286,6282,5924,6282,6282,6833,6282,6279,6398,6282,6282,6014,6282,6282,6282,6601,6282,6439,5933,6133,6282,6148,6282,6255,6282,5914,5931,6705,6282,6282,6850,6282,6850,6282,6372,6282,6372,6282,6149,6282,6505,5914,5931,6291,6282,6282,5982,6585,6282,6282,6660,6291,6043,5914,6291,6282,6282,6283,6043,5899,6282,6282,1048576,1073741824,2147483648,1075838976,2097152,2147483648,4194560,4196352,-2143289344,-2143289344,4194304,2147483648,37748736,541065216,541065216,-2143289344,4198144,4196352,276901888,8540160,4194304,1,4,16,64,0,48,64,32,64,64,96,0,59,140224,5505024,-1887436800,0,63,64,128,0,64,256,0,110,110,8425488,4194304,1024,0,128,128,512,512,1024,1024,2048,0,256,256,257,37748736,742391808,742391808,775946240,-1371537408,775946240,4718592,775946240,775946240,171966464,171966464,775946240,239075328,-1405091840,-1371537408,239075328,171966464,64,4718592,2097216,4720640,541589504,4194368,4194368,541065280,541589504,4194400,-2143289280,4194368,-2143285440,-2143285408,-2143285408,-2109730976,775946336,776470528,-2143285408,776470528,775946304,775946304,-1908404384,775946304,-1908404384,2,8,32,128,1024,4096,0,260,8392704,0,1856,64,524288,64,896,8192,67108864,2147483648,96,262144,262144,8192,0,288,8388608,0,384,0,512,2048,2048,4096,4096,8192,8192,16384,0,520,520,96,524288,524288,0,2432,2048,268435456,0,24576,0,32768,32768,65536,1048576,128,2048,12288,0,12289,0,16384,16384,32768,0,1864,2,16,1024,98304,131072,262144,1048576,512,5120,2,536936448,80,528,528,2097168,2097168,268435472,524304,1048592,2097168,24,560,48,2097680,1048592,3145744,1048592,20,560,48,3146256,2097552,3146256,28,16,8192,2,2098064,163577856,17,21,112,128,3584,8192,2228784,-161430188,-161430188,-161429680,-161430188,-161429676,-161430188,-161298576,-160299088,-161298576,-161298572,-160774288,-160299084,146804757,146812949,146862101,146863389,146863389,148960541,-161429740,-161429676,146863421,148960541,146863389,-161429676,-160905388,-161429676,-161429676,-161429675,-161349072,-161349072,-161347728,-161347728,-161298572,-161298572,-160774284,-161298572,16,262160,-18860267,-160774284,-18729163,0,58368,159383552,0,65536,2097152,8388608,33554432,0,66048,0,77824,524288,33554432,1024,262144,2097152,16777216,67108864,0,131072,524288,134217728,2147483648,1,32768,196608,0,131328,131072,16777216,100663296,-1073741824,164096,0,131584,2621440,0,139264,0,150528,0,235712,16777216,1073774592,1226014816,100665360,-2046818288,100665360,100665360,-2044196848,1091799136,1091799136,1091803360,1091799136,1158908e3,1158908001,1192462432,1192462448,1192462448,1870638912,1870655296,1870638912,1200851056,1200851056,1091799393,1870655296,1870655296,1870655312,1870655316,1870655312,1870655312,1870638928,1870655316,1870655316,1870655317,1870655316,1879043952,1870655348,1870655316,1879027568,1879043952,1879043956,0,284672,229440,1048576,2097152,67108864,134217728,8,4194304,16777216,2147483648,1224736768,0,503616,2048,100663296,0,524288,2097152,4194304,4194304,0,40,0,44,-2046820352,0,605503,231488,1090519040,1157627904,1191182336,9437184,231744,52e4,7864320,1862270976,0,867391,1862270976,1862270976,16252928,0,1048576,4194304,25165824,25165824,33554432,8192,98304,1048576,8388608,134217728,268435456,4194432,3145728,0,24,0,29,0,32,1,2,2,4,0,2147483648,2147483648,0,0,1,0,2,0,3,240,19456,262144,0,4,8,0,6,0,7,150994944,0,1049088,1049088,12845065,12845065,147193865,128,6144,4194304,251658240,536870912,1073741824,32768,131072,1048576,4096,83886080,117440512,0,3145728,16777216,134217728,0,2048,8192,229376,0,2304,1536,8192,1536,65536,4194304,67108864,536870912,9216,33554432,262144,134217728,1073741824,50331649,9476,512,8192,134218240,1050624,0,5242880,1275208192,4194312,4194312,4194344,4194312,541065224,4203820,-869654016,-869654016,1279402504,1279402504,2143549415,2143549415,2143549423,0,8388608,4096,4194304,8388608,16777216,33554432,-1946157056,0,8192,131072,0,1792,0,1024,8192,65536,0,1536,2147483648,2143549423,2143549423,2143549415,1,16777216,268435456,512,139264,2760704,-872415232,0,19947520,0,33554432,67108864,1073741824,1073741824,262144,7340032,-2030043136,0,331776,300,4203520,4333568,1275068416,0,16777216,16777216,0,999,259072,4194304,4194432,999,29619200,2113929216,0,58720256,1007,1007,0,67108864,402653184,536870912,2048,1048576,16777216,536870912,300,0,83886080,0,2097152,134217728,536870912,0,49152,0,57344,102,384,6,96,128,3072,16384,65536,524288,1048576,0,4096,262144,524288,96,96,64,384,512,4096,65536,131072,1024,65536,262144,131072,32768,256,384,8192,33554432,2147483648,1,6,8,8388608,96,384,104,104,0,134217728,6,32,256,512,65536,7340032,50331648,0,8396800,4,32,384,4,64,1024,2097152,268435456,1073741824,8,262144,512,0,8,8,16,0,9,0,12,0,15,16,16,17,20,16,20,48,16,28,0,16,32,0,21,53,4,256,1024,524288,536870912,256,65536,16777216,1073741824,2048,524288,32,4100,1024,134217728,1049088,270532608,2097152,2097152,0,23,5505537,5587457,5591557,147202057,5587457,13894153,-1881791493,-1881791493,0,134218752,5587465,5587457,13894153,13894153,81003049,4456448,8388608,5505024,0,134348800,134348800,82432,0,142606336,5,86528,41,75497472,81920,0,184549376,2,56,64,2048,262144,536870912,2048,134217728,-2113929216,16777216,1073743872,268435968,229376,25165824,92274688,25165824,100663296,402653184,1610612736,0,100663296,134217728,805306368,1073741824,8388608,268567040,16384,229376,4194304,117440512,2113544,68423701,-2079059883,-2079059947,85200917,68423701,68423765,68489237,68423701,68423701,72618005,68423701,68425749,68423703,85200919,69488664,69488664,70537244,70537245,70537245,-2076946339,-2076946403,70537245,70537309,70539293,-2022351745,-2022351617,-2022351745,-2022351617,-2022351617,0,243269632,256,32768,1048576,33554432,134217728,-2113929216,0,268435456,49152,266240,1048576,67108864,-2080374784,-2080374784,268288,0,301989888,0,318767104,282624,0,536870912,28,3145728,192,351232,7340032,5,16,1049104,12,3145728,13,0,1073741825,192,3072,20480,0,1073741824,0,262144,2621440,-1073741824,20480,65536,268435456,14,32,512,131072,268435456,192,1024,64,32768,33554432,268435456,4,128,3840,16384,262144,128,2097152,1073741824,4,2097152,4,50331648,67108864,128,50331648,1073741824,128,268435968,268435968,268436032,256,1536,2048,16384,98304,393216,524288,268435456,536870912,9216,0,4194304,50331648,2147483648,256,536871168,-1879046336,-1879046334,-1879046326,-1879046334,1073744256,-1879046334,-1879046326,-1845491902,-1878784182,268444480,268436288,268436288,268436289,268444480,268444480,2100318149,2100318149,2100326341,0,1090519040,2100326341,2100326341,1,16,536936448,576,0,832,8192,1,4036,19939328,2080374784,0,1,1024,768,8192,16384,19922944,2080374784,1,128,4096,3584,16384,524288,8,33554432,402653184,2048,3145728,128,131072,268500992,4243456,4096,1048588,0,1258292224,1124073472,1124073472,1124073488,1124073474,1124073472,1392574464,1124073472,1073754113,12289,1124073472,12289,12289,1098920193,1132474625,1098920209,1132474625,1132474625,1124085761,1124085761,1124085777,1258304513,1124085761,1400975617,2132360255,2132622399,2132360255,2132622399,2132622399,2141011263,0,2140749119,2141011263,2,16384,3145728,12545,25165824,268435456,12305,13313,12561,0,78081,327155712,605247,1058013184,1073741824,867647,1066401792,0,1,12288,256,8388608,1,30,32,1024,2048,339968,327680,524288,1,14,16,14,1024,16384,4194304,134217728,1,12,1024,8,134217728,8,536870912,9437184,0,68157440,137363456,0,137363456,66,66,100680704,25165824,26214400,92274688,25165952,93323264,92274688,92274688,92274720,93323264,25165890,100721928,100721928,100787464,100721664,100721664,100853e3,100721928,125977600,125846528,125846528,125846560,125977600,125977600,127026176,281843,281843,1330419,281843,126895104,125846528,1330419,1330419,72633587,5524723,72633587,92556531,93605107,93605107,5524723,5524723,39079155,97799411,127290611,127290611,131484915,0,17408,33554432,1073741824,58624,0,124160,189696,148480,50331648,2,112],r.TOKEN=["(0)","PragmaContents","DirCommentContents","DirPIContents","CDataSection","Wildcard","EQName","URILiteral","IntegerLiteral","DecimalLiteral","DoubleLiteral","StringLiteral","PredefinedEntityRef","'\"\"'","EscapeApos","ElementContentChar","QuotAttrContentChar","AposAttrContentChar","PITarget","NCName","QName","S","S","CharRef","CommentContents","EOF","'!'","'!='","'\"'","'#'","'#)'","'$'","'%'","''''","'('","'(#'","'(:'","')'","'*'","'*'","'+'","','","'-'","'-->'","'.'","'..'","'/'","'//'","'/>'","':'","':)'","'::'","':='","';'","'<'","'<!--'","'</'","'<<'","'<='","'<?'","'='","'>'","'>='","'>>'","'?'","'?>'","'@'","'NaN'","'['","']'","'after'","'all'","'allowing'","'ancestor'","'ancestor-or-self'","'and'","'any'","'append'","'array'","'as'","'ascending'","'at'","'attribute'","'base-uri'","'before'","'boundary-space'","'break'","'by'","'case'","'cast'","'castable'","'catch'","'check'","'child'","'collation'","'collection'","'comment'","'constraint'","'construction'","'contains'","'content'","'context'","'continue'","'copy'","'copy-namespaces'","'count'","'decimal-format'","'decimal-separator'","'declare'","'default'","'delete'","'descendant'","'descendant-or-self'","'descending'","'diacritics'","'different'","'digit'","'distance'","'div'","'document'","'document-node'","'element'","'else'","'empty'","'empty-sequence'","'encoding'","'end'","'entire'","'eq'","'every'","'exactly'","'except'","'exit'","'external'","'first'","'following'","'following-sibling'","'for'","'foreach'","'foreign'","'from'","'ft-option'","'ftand'","'ftnot'","'ftor'","'function'","'ge'","'greatest'","'group'","'grouping-separator'","'gt'","'idiv'","'if'","'import'","'in'","'index'","'infinity'","'inherit'","'insensitive'","'insert'","'instance'","'integrity'","'intersect'","'into'","'is'","'item'","'json'","'json-item'","'key'","'language'","'last'","'lax'","'le'","'least'","'let'","'levels'","'loop'","'lowercase'","'lt'","'minus-sign'","'mod'","'modify'","'module'","'most'","'namespace'","'namespace-node'","'ne'","'next'","'no'","'no-inherit'","'no-preserve'","'node'","'nodes'","'not'","'object'","'occurs'","'of'","'on'","'only'","'option'","'or'","'order'","'ordered'","'ordering'","'paragraph'","'paragraphs'","'parent'","'pattern-separator'","'per-mille'","'percent'","'phrase'","'position'","'preceding'","'preceding-sibling'","'preserve'","'previous'","'processing-instruction'","'relationship'","'rename'","'replace'","'return'","'returning'","'revalidation'","'same'","'satisfies'","'schema'","'schema-attribute'","'schema-element'","'score'","'self'","'sensitive'","'sentence'","'sentences'","'skip'","'sliding'","'some'","'stable'","'start'","'stemming'","'stop'","'strict'","'strip'","'structured-item'","'switch'","'text'","'then'","'thesaurus'","'times'","'to'","'treat'","'try'","'tumbling'","'type'","'typeswitch'","'union'","'unique'","'unordered'","'updating'","'uppercase'","'using'","'validate'","'value'","'variable'","'version'","'weight'","'when'","'where'","'while'","'wildcards'","'window'","'with'","'without'","'word'","'words'","'xquery'","'zero-digit'","'{'","'{{'","'{|'","'|'","'||'","'|}'","'}'","'}}'"]},{}],10:[function(e,t,n){"use strict";n.TreeOps={flatten:function(e){var t=this,n="";if(!e)throw new Error("Invalid node found");return e.value===undefined?e.children.forEach(function(e){n+=t.flatten(e)}):n+=e.value,n},concat:function(e,t,n){var r=n?{}:e;n&&Object.keys(e).forEach(function(t){r[t]=e[t]});var i=Object.keys(t);return i.forEach(function(e){r[e]=t[e]}),r},removeParentPtr:function(e){e.getParent!==undefined&&delete e.getParent;for(var t in e.children){var n=e.children[t];this.removeParentPtr(n)}},inRange:function(e,t,n){if(e&&e.sl<=t.line&&t.line<=e.el){if(e.sl<t.line&&t.line<e.el)return!0;if(e.sl===t.line&&t.line<e.el)return e.sc<=t.col;if(e.sl===t.line&&e.el===t.line)return e.sc<=t.col&&t.col<=e.ec+(n?1:0);if(e.sl<t.line&&e.el===t.line)return t.col<=e.ec+(n?1:0)}},findNode:function(e,t){if(!e)return;var n=e.pos;if(this.inRange(n,t)===!0){for(var r in e.children){var i=e.children[r],s=this.findNode(i,t);if(s!==undefined)return s}return e}return},astAsXML:function(e,t){var n="";t=t?t:"",e.value&&(n+=t+"<"+e.name+">"+e.value+"</"+e.name+">\n"),n+=t+"<"+e.name+">\n";var r=this;return e.children.forEach(function(e){n+=r.astAsXML(e,t+"    ")}),n+=t+"</"+e.name+">\n",n}}},{}],11:[function(e,t,n){"use strict";var r=n.createStaticContext=function(){var t=e("./compiler/static_context").StaticContext;return new t};n.XQLint=function(t,n){n=n?n:{};var i=e("./parsers/JSONiqParser").JSONiqParser,s=e("./parsers/XQueryParser").XQueryParser,o=e("./parsers/JSONParseTreeHandler").JSONParseTreeHandler,u=e("./compiler/translator").Translator,a=e("./formatter/style_checker").StyleChecker,f=e("../lib/completion/completer"),l=function(e,t){return e?(Object.keys(t).forEach(function(n){e[n]===undefined&&(e[n]=t[n])}),e):t};n=l(n,{styleCheck:!1});var c;this.getAST=function(){return c};var h=[];this.getMarkers=function(){return h},this.getErrors=function(){var e=[];return h.forEach(function(t){t.type==="error"&&e.push(t)}),e},this.getWarnings=function(){var e=[];return h.forEach(function(t){t.type==="warning"&&e.push(t)}),e},this.getCompletions=function(e){return f.complete(t,c,v,e)};var p=!1;this.hasSyntaxError=function(){return p};var d=function(e,t,n){var r=e.substring(0,t),i=e.substring(0,n),s=r.split("\n").length,o=t-r.lastIndexOf("\n"),u=i.split("\n").length,a=n-i.lastIndexOf("\n"),f={sl:s-1,sc:o-1,el:u-1,ec:a-1};return f},v=n.staticContext?n.staticContext:r(),m=n.fileName?n.fileName:"",g=m.substring(m.length-".jq".length).indexOf(".jq")!==-1&&t.indexOf("xquery version")!==0||t.indexOf("jsoniq version")===0,y=new o(t),b=g?new i(t,y):new s(t,y);try{b.parse_XQuery()}catch(w){if(!(w instanceof b.ParseException))throw w;p=!0,y.closeParseTree();var E=d(t,w.getBegin(),w.getEnd()),S=b.getErrorMessage(w);E.sc===E.ec&&E.ec++,h.push({pos:E,type:"error",level:"error",message:S})}c=y.getParseTree(),n.styleCheck&&(h=h.concat((new a(c,t)).getMarkers()));var x=new u(v,c);h=h.concat(x.getMarkers())}},{"../lib/completion/completer":5,"./compiler/static_context":3,"./compiler/translator":4,"./formatter/style_checker":6,"./parsers/JSONParseTreeHandler":7,"./parsers/JSONiqParser":8,"./parsers/XQueryParser":9}]},{},[11])(11)}),ace.define("ace/mode/xquery/modules",["require","exports","module"],function(e,t,n){t.Modules={"http://xbrl.io/modules/bizql/components":{ns:"http://xbrl.io/modules/bizql/components",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for retrieving components.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Components help organizing the facts contained in archives\n in smaller parts that "make sense" together. A component is identified\n with a CID (component ID).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A component is made of networks (see the networks module) and hypercubes\n (see the hypercubes module).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve all components, all components belonging\n to one or several archives. You can retrieve the CID of a component or retrieve\n the components associated with a couple of CIDs.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/components",prefix:"components"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"cid",qname:"components:cid",signature:"($component-or-id as item()) as atomic",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts the input to a normalized component id (CID). The input\n can be either an CID, or an component object which contains an _id.</p>\n',summary:"<p>  Converts the input to a normalized component id (CID).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"component-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an component object or an CID.</div>'}],returns:{type:"atomic",description:"the normalized CID."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">components:INVALID_PARAMETER if the CID or component is not valid.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"components-for-archives",qname:"components:components-for-archives",signature:"($archive-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all components that belong to the supplied archives.</p>\n',summary:"<p>  Retrieves all components that belong to the supplied archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive-or-ids",type:"item()",occurrence:"*",description:""}],returns:{type:"object()*",description:"all components in the archive with this AID."},errors:[]},{isDocumented:!0,arity:0,name:"components",qname:"components:components",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all components.</p>\n',summary:"<p>  Retrieves all components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"all components."},errors:[]},{isDocumented:!0,arity:1,name:"components",qname:"components:components",signature:"($component-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the components with the given CIDs.</p>\n',summary:"<p>  Retrieves the components with the given CIDs.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"component-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the CIDs or the components themselves.</div>'}],returns:{type:"object()*",description:"the components whose _id field matches one of these CIDs."},errors:[]},{isDocumented:!0,arity:1,name:"num-abstract-primary-items-in-hypercubes",qname:"components:num-abstract-primary-items-in-hypercubes",signature:"($components-or-ids) as integer*",description:" Return the number of (distinct) abstract primary items being\n in a hypercube for each of the given components.\n",summary:"<p> Return the number of (distinct) abstract primary items being\n in a hypercube for each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of primary items"},errors:[]},{isDocumented:!0,arity:1,name:"num-concrete-primary-items-in-hypercubes",qname:"components:num-concrete-primary-items-in-hypercubes",signature:"($components-or-ids) as integer*",description:" Return the number of (distinct) concrete primary items being\n in a hypercube for each of the given components.\n",summary:"<p> Return the number of (distinct) concrete primary items being\n in a hypercube for each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of primary items"},errors:[]},{isDocumented:!0,arity:1,name:"num-concrete-primary-items-not-in-hypercubes",qname:"components:num-concrete-primary-items-not-in-hypercubes",signature:"($components-or-ids) as integer*",description:" Return the number of (distinct) concrete primary items not being\n in a hypercube for each of the given components.\n",summary:"<p> Return the number of (distinct) concrete primary items not being\n in a hypercube for each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of primary items"},errors:[]},{isDocumented:!0,arity:1,name:"num-distinct-abstract-primary-items-not-in-hypercubes",qname:"components:num-distinct-abstract-primary-items-not-in-hypercubes",signature:"($components-or-ids) as integer*",description:" Return the number of (distinct) abstract primary items not being\n in a hypercube for each of the given components.\n",summary:"<p> Return the number of (distinct) abstract primary items not being\n in a hypercube for each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of primary items"},errors:[]},{isDocumented:!0,arity:1,name:"num-domains",qname:"components:num-domains",signature:"($components-or-ids) as integer*",description:" Return the number of (distinct) domains in each of the given components.\n",summary:"<p> Return the number of (distinct) domains in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of domains"},errors:[]},{isDocumented:!0,arity:1,name:"num-explicit-dimensions",qname:"components:num-explicit-dimensions",signature:"($components-or-ids) as integer*",description:" Return the number of (distinct) explicit dimensions in each of the given components.\n",summary:"<p> Return the number of (distinct) explicit dimensions in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of dimensions"},errors:[]},{isDocumented:!0,arity:1,name:"num-hypercubes",qname:"components:num-hypercubes",signature:"($components-or-ids as item()*) as integer*",description:" Return the number of hypercubes in each of the given components.\n",summary:"<p> Return the number of hypercubes in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of hypercubes"},errors:[]},{isDocumented:!0,arity:1,name:"num-members",qname:"components:num-members",signature:"($components-or-ids) as integer*",description:" Return the number of (distinct) members in each of the given components.\n",summary:"<p> Return the number of (distinct) members in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of members"},errors:[]},{isDocumented:!0,arity:1,name:"num-networks",qname:"components:num-networks",signature:"($components-or-ids) as integer*",description:" Return the number of networks in each of the given components.\n",summary:"<p> Return the number of networks in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of networks"},errors:[]}],variables:[{name:"components:col",type:"xs:string",description:" Name of the collection the components are stored in.\n"},{name:"components:ARCHIVE",type:"xs:string",description:" Name of the field pointing to the archive.\n"}]},"http://jsound.io/modules/validate":{ns:"http://jsound.io/modules/validate",description:" JSound simple validator.\n This is a JSONiq implemenation of the JSound (the schema for JSON) validator.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Cezar Andrei</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/fetch",prefix:"fetch"},{uri:"http://jsoniq.org/functions",prefix:"jn"},{uri:"http://jsound.io/modules/validate",prefix:"jsv"},{uri:"http://jsound.io/modules/validate/map",prefix:"map"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:3,name:"jsd-valid",qname:"jsv:jsd-valid",signature:"($ns as string, $name as string, $instance as json-item()) as boolean",description:" Validates the $instance JSON item against the JSound type with name $name\n and namespace $ns, from the JSound schema definition $jsd.\n",summary:"<p> Validates the $instance JSON item against the JSound type with name $name\n and namespace $ns, from the JSound schema definition $jsd.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"ns",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the namespace of the expected type</div>'},{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the expected type</div>'},{name:"instance",type:"json-item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the instance to be validated</div>'}],returns:{type:"boolean",description:"true if the instance is valid, otherwise throws an error."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jsv:BadJSoundFormat If the schema is not a valid JSound schema</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jsv:Invalid If the instance does not conform to the JSound schema</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP0025 If the schema namespace URI cannot be resolved.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jn:JNDY0021 If the loaded schema is syntactically incorrect</xqdoc:error>']},{isDocumented:!0,arity:4,name:"jsd-valid",qname:"jsv:jsd-valid",signature:"($jsd as object(), $name as string, $ns as string, $instance as item()) as boolean",description:" Validates the $instance JSON item against the JSound type with name $name\n and namespace $ns, from the JSound schema definition $jsd.\n",summary:"<p> Validates the $instance JSON item against the JSound type with name $name\n and namespace $ns, from the JSound schema definition $jsd.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"jsd",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the JSound schema as a JSON object to be validated against</div>'},{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the expected type</div>'},{name:"ns",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the namespace of the expected type</div>'},{name:"instance",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the instance to be validated</div>'}],returns:{type:"boolean",description:"true if the instance is valid, otherwise throws an error."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jsv:BadJSoundFormat If the schema is not a valid JSound schema</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jsv:Invalid If the instance does not conform to the JSound schema</xqdoc:error>']}],variables:[]},"http://xbrl.io/modules/bizql/archives":{ns:"http://xbrl.io/modules/bizql/archives",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functions for retrieving metadata about archives.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Archives represent the granularity of "report shipping", i.e., an entity\n reports one archive at a time. An archive is identified with an AID (archive ID).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Archives are made of reported facts (see facts module),\n which are structured and organized in components (see components module).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve all archives, or a certain number of archives\n with their AIDs, or obtain the AID of archives you already have. You can also retrieve\n all archives submitted by one or several entities.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Archive information is stored in a MongoDB datasource called <b>xbrl</b>.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/entities",prefix:"entities"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"aid",qname:"archives:aid",signature:"($archives-or-ids as item()*) as atomic*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts the input to a normalized archive identifier (AID). The input\n can be either a pure AID, or an archive object which contains an AID.</p>\n',summary:"<p>  Converts the input to a normalized archive identifier (AID).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archive objects or identifiers (AID).</div>'}],returns:{type:"atomic*",description:"the normalized AIDs."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">archives:INVALID_PARAMETER if the AID or archive is not valid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"archives-for-entities",qname:"archives:archives-for-entities",signature:"($entities-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all archives created by the supplied entities.</p>\n',summary:"<p>  Return all archives created by the supplied entities.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entities-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> arbitrary number of entity objects or EIDs.</div>'}],returns:{type:"object()*",description:"all archives created by these entities."},errors:[]},{isDocumented:!0,arity:0,name:"archives",qname:"archives:archives",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all archives.</p>\n',summary:"<p>  Retrieves all archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"all archives."},errors:[]},{isDocumented:!0,arity:1,name:"archives",qname:"archives:archives",signature:"($archive-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the archives with the given AIDs.</p>\n',summary:"<p>  Retrieves the archives with the given AIDs.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive-or-ids",type:"item()",occurrence:"*",description:""}],returns:{type:"object()*",description:"the archives with the given AIDs the empty sequence if no archive was found or if the input is an empty sequence."},errors:[]},{isDocumented:!0,arity:1,name:"entities",qname:"archives:entities",signature:"($archives-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the entities that submitted the supplied archives.</p>\n',summary:"<p>  Returns the entities that submitted the supplied archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their identifiers (AID).</div>'}],returns:{type:"object()*",description:"the submitting entities."},errors:[]},{isDocumented:!0,arity:1,name:"num-abstract-primary-items-in-hypercubes",qname:"archives:num-abstract-primary-items-in-hypercubes",signature:"($archives-or-ids) as integer*",description:" Return the number of (distinct) abstract primary items being\n in a hypercube for each of the given archives.\n",summary:"<p> Return the number of (distinct) abstract primary items being\n in a hypercube for each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of primary items"},errors:[]},{isDocumented:!0,arity:1,name:"num-components",qname:"archives:num-components",signature:"($archives-or-ids) as integer*",description:" Return the number of components of each of the given archives.\n",summary:"<p> Return the number of components of each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of components"},errors:[]},{isDocumented:!0,arity:1,name:"num-concrete-primary-items-in-hypercubes",qname:"archives:num-concrete-primary-items-in-hypercubes",signature:"($archives-or-ids) as integer*",description:" Return the number of (distinct) concrete primary items being\n in a hypercube for each of the given archives.\n",summary:"<p> Return the number of (distinct) concrete primary items being\n in a hypercube for each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of primary items"},errors:[]},{isDocumented:!0,arity:1,name:"num-concrete-primary-items-not-in-hypercubes",qname:"archives:num-concrete-primary-items-not-in-hypercubes",signature:"($archives-or-ids) as integer*",description:" Return the number of (distinct) concrete primary items not being\n in a hypercube for each of the given archives.\n",summary:"<p> Return the number of (distinct) concrete primary items not being\n in a hypercube for each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of primary items"},errors:[]},{isDocumented:!0,arity:1,name:"num-distinct-abstract-primary-items-not-in-hypercubes",qname:"archives:num-distinct-abstract-primary-items-not-in-hypercubes",signature:"($archives-or-ids) as integer*",description:" Return the number of (distinct) abstract primary items not being\n in a hypercube for each of the given archives.\n",summary:"<p> Return the number of (distinct) abstract primary items not being\n in a hypercube for each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of primary items"},errors:[]},{isDocumented:!0,arity:1,name:"num-domains",qname:"archives:num-domains",signature:"($archives-or-ids) as integer*",description:" Return the number of (distinct) domains in each of the given archives.\n",summary:"<p> Return the number of (distinct) domains in each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of domains"},errors:[]},{isDocumented:!0,arity:1,name:"num-explicit-dimensions",qname:"archives:num-explicit-dimensions",signature:"($archives-or-ids) as integer*",description:" Return the number of (distinct) explicit dimensions in each of the given archives.\n",summary:"<p> Return the number of (distinct) explicit dimensions in each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of dimensions"},errors:[]},{isDocumented:!0,arity:1,name:"num-facts",qname:"archives:num-facts",signature:"($archives-or-ids) as integer*",description:" Return the number of facts of each of the given archives.\n",summary:"<p> Return the number of facts of each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of facts"},errors:[]},{isDocumented:!0,arity:1,name:"num-footnotes",qname:"archives:num-footnotes",signature:"($archives-or-ids) as integer*",description:" Return the number of XBRL footnotes of each of the given archives.\n",summary:"<p> Return the number of XBRL footnotes of each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of footnotes"},errors:[]},{isDocumented:!0,arity:1,name:"num-hypercubes",qname:"archives:num-hypercubes",signature:"($archives-or-ids as item()*) as integer*",description:" Return the number of hypercubes in each of the given archives.\n",summary:"<p> Return the number of hypercubes in each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of hypercubes"},errors:[]},{isDocumented:!0,arity:1,name:"num-members",qname:"archives:num-members",signature:"($archives-or-ids) as integer*",description:" Return the number of (distinct) members in each of the given archives.\n",summary:"<p> Return the number of (distinct) members in each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of members"},errors:[]},{isDocumented:!0,arity:1,name:"num-networks",qname:"archives:num-networks",signature:"($archives-or-ids) as integer*",description:" Return the number of networks in each of the given archives.\n",summary:"<p> Return the number of networks in each of the given archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of archives or IDs</div>'}],returns:{type:"integer*",description:"the said number of networks"},errors:[]}],variables:[{name:"archives:col",type:"string",description:" Name of the collection the archives are stored in.\n"},{name:"archives:ENTITY",type:"string",description:" Name of the field which points to the reporting entity.\n"}]},"http://www.28msec.com/modules/xmlrpc":{ns:"http://www.28msec.com/modules/xmlrpc",description:' XML RPC Client Module\n This module provides the functions necessary to execute remote call\n procedures using\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.xmlrpc.com/spec" target="_blank">XML-RPC</a>.\n The application/mashup creator does not need to know the\n specifics of <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.xmlrpc.com/spec" target="_blank">XML-RPC</a> to use this module.\n Usage:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">xmlrpc:invoke("http://www.advogato.org/XMLRPC", "test.sumprod", (5, 7))</pre>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">xmlrpc:invoke("http://www.advogato.org/XMLRPC", "test.capitalize", "HelloWorld")</pre>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">xmlrpc:invoice("http://www.example.com/XMLRPC", "test.foo", ("some-parameter",\n                      &lt;struct&gt;\n                        &lt;member&gt;\n                          &lt;name&gt;Foo&lt;/name&gt;\n                          &lt;value&gt;&lt;string&gt;Bar&lt;/string&gt;&lt;/value&gt;\n                        &lt;/member&gt;\n                      &lt;/struct&gt;))</pre>\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.xmlrpc.com/spec" target="_blank">XML-RPC Specification</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://en.wikipedia.org/wiki/XML-RPC" target="_blank">XML-RPC Wikipedia article</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">William Candillon {william.candillon@28msec.com}</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"ann"},{uri:"http://expath.org/ns/http-client",prefix:"http"},{uri:"http://expath.org/ns/http-client",prefix:"http-client"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://www.28msec.com/modules/xmlrpc",prefix:"xmlrpc"}],functions:[{isDocumented:!0,arity:2,name:"invoke",qname:"xmlrpc:invoke",signature:"($endpoint-url as xs:string, $method as xs:string) as item()*",description:" Invoke a remote method without parameters.\n Calling this function is equivalent to xmlrpc:invoke($url, $method, ())\n",summary:"<p> Invoke a remote method without parameters.</p>",annotation_str:" %ann:sequential",annotations:[{prefix:"ann",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> URL of the XML-RPC server.</div>'},{name:"method",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Name of the method to invoke.</div>'}],returns:{type:"item()*",description:"Result of the method invocation."},errors:[]},{isDocumented:!0,arity:3,name:"invoke",qname:"xmlrpc:invoke",signature:"($endpoint-url as xs:string, $method as xs:string, $parameters as item()*) as item()*",description:" Invoke a remote method with parameters.\n",summary:"<p> Invoke a remote method with parameters.</p>",annotation_str:" %ann:sequential",annotations:[{prefix:"ann",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> URL of the XML-RPC server.</div>'},{name:"method",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Name of the method to invoke.</div>'},{name:"parameters",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Method parameters. Struct and Arrays need to follow XML-RPC format. Atomic types will be automatically convert to the proper XML-RPC data format.</div>'}],returns:{type:"item()*",description:"Result of the method invocation."},errors:[]}],variables:[{name:"xmlrpc:ERR_001",type:"xs:QName",description:" XML-RPC serialization error.\n"}]},"http://zorba.io/modules/unordered-maps":{ns:"http://zorba.io/modules/unordered-maps",description:' This module defines a set of functions for working with maps. A map\n is identified by a string and can be created using the map:create function\n and dropped using the map:drop function.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n It is possible to create persistent and transient maps. The lifetime of a\n transient map is limited by the execution of the current query.\n A persistent map lives until it is explicitly dropped.\n Accordingly, it is also available to other requests.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n For example,\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">map:create("my-map", ["string", "integer"], { "persistent" : false })</pre>\n will create a transient map named my-map having two keys.\n The types of the keys are string and integer.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The key of a particular entry in the map can consist of a tuple of\n atomic values (called key attributes). The actual type of each attribute\n is determined when the map is created. The value of each entry is a\n sequence of items. If an item in this sequence is a object or array,\n this item needs to belong to a collection, otherwise, an error is raised.\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/unordered-maps",prefix:"map"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:0,name:"available-maps",qname:"map:available-maps",signature:"() as string* external",description:' The function returns a sequence of names of the maps that are\n available (persistent and non-persistent). The sequence will be\n empty if there are no maps.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> The function returns a sequence of names of the maps that are\n available (persistent and non-persistent).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"string*",description:"A sequence of string, one for each available map, or an empty sequence."},errors:[]},{isDocumented:!0,arity:2,name:"create",qname:"map:create",signature:"($name as string, $key-types as item()) as empty-sequence() external",description:' Create a persistent map with a given name and type identifiers for the key\n attributes.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the map has only one key attribute, a single type identifier is given,\n for more than one key attribute an array of type identifiers is given.\n Calling this function is equivalent to calling create with the options\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">{ "persistent" : true }</code>\n Note that the function is sequential and immediately creates the map.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Each key-type should be specified as string (e.g. "integer",\n "string", "boolean", "double", or "datetime").\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n For example,\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">map:create("my-map", "string")</pre> or\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">map:create("my-map", ["string", "integer"])</pre>.\n',summary:"<p> Create a persistent map with a given name and type identifiers for the key\n attributes.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map (the restrictions on collection names apply)</div>'},{name:"key-types",type:"item()",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately creates the corresponding map. It returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if any of the key attribute types is not a subtype of anyAtomicType.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZSTR0001 if a map with the given name already exists.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY1000 if the given name is not a legal collection name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0043 if any of the given options has an invalid type</xqdoc:error>']},{isDocumented:!0,arity:3,name:"create",qname:"map:create",signature:"($name as string, $key-types as item(), $options as object()) as empty-sequence() external",description:' Create a map with a given name, type identifiers for the key attributes, and\n options.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the map has only one key attribute, a single type identifier is given,\n for more than one key attribute an array of type identifiers is given.\n Currently only one option is supported: To create a transient map the object\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">{ "persistent" : false }</code>\n has to be passed to the $options parameter.\n Note that the function is sequential and immediately creates the map in the\n store.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Note that a map cannot be created if it already exists in a parent context.\n For example, a map that was created in an outer query cannot be\n created again in an inner query executed using the\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">reflection:eval-s</code> function.\n',summary:"<p> Create a map with a given name, type identifiers for the key attributes, and\n options.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map (the restrictions on collection names apply)</div>'},{name:"key-types",type:"item()",occurrence:null,description:""},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an object describing options for the map</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately creates the corresponding map but returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if any of the attribute types is not a subtype of anyAtomicType.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZSTR0001 if a map with the given name already exists.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY1000 if the given name is not a legal collection name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0043 if any of the given options has an invalid type</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete",qname:"map:delete",signature:"($name as string, $key as item()) as empty-sequence() external",description:' Removes an entry identified by the given key from the map.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the map has only one key attribute, a single key value is given, for\n more than one key attribute an array of key values is given.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Note that it is possible to insert entries with empty key attributes.\n However as the removing the entries is based on the "eq" comparison and\n as "eq" with an empty sequence always return false, it is not possible\n to delete these entries.\n',summary:"<p> Removes an entry identified by the given key from the map.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'},{name:"key",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> either a single attribute key or an array of keys</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately deletes the entry into the map but returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the given number of key attributes does not match the number of key attributes specified when creating the map (see the map:create function).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQD0005 if any of the given key attributes can not be cast (or is not a subtype) of the corresponding key attribute specified when creating the map.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"drop",qname:"map:drop",signature:"($name as string) as empty-sequence() external",description:' Deletes the map with the given name.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Note that a map can only be dropped in the context it was created.\n For example, a map that was created in an outer query cannot be\n dropped in an inner query executed using the\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">reflection:eval-s</code> function.\n',summary:"<p> Deletes the map with the given name.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map to drop</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately drops the map. It returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"get",qname:"map:get",signature:"($name as string, $key as item()) as item()* external",description:' Returns the value of the entry with the given key from the map.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the map has only one key attribute, a single key value is given, for\n more than one key attribute an array of key values is given.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Note that it is possible to insert entries with empty key attributes.\n However as the getting the entries is based on the "eq" comparison and\n as "eq" with an empty sequence always return false, it is not possible\n to retrieve these entries.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n For example,\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">map:get("my-map", "key")</pre> or\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">map:get("my-map", [ "key1", "key2" ])</pre>.\n',summary:"<p> Returns the value of the entry with the given key from the map.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'},{name:"key",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> either a single attribute key or an array of keys</div>'}],returns:{type:"item()*",description:"the value of the entry in the map identified by the given key. The empty-sequence will be returned if no entry with the given key is contained in the map."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the given number of key attributes does not match the number of key attributes specified when creating the map (see the map:create function).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQD0005 if any of the given key attributes can not be cast (or is not a subtype) of the corresponding key attribute specified when creating the map.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"insert",qname:"map:insert",signature:"($name as string, $key as item(), $value as item()*) as empty-sequence() external",description:' Inserts a new entry into the map with the given name.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the map has only one key attribute, a single key value is given, for\n more than one key attribute an array of key values is given.\n If an entry with the given key already exists in the map, the value\n sequences of the existing entry and the sequence passed using $value\n argument are concatenated.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If an item in the value sequence is an object or array, this\n item needs to belong to a collection, otherwise, an an error\n is raised.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Note that it is possible to insert entries with empty key attributes\n or key attributes having the value <code xmlns:xqdoc="http://www.xqdoc.org/1.0">null</code>. However, as\n the comparison with an empty sequence or null always returns false,\n it is not possible to retrieve these entries.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n For example,\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">map:insert("my-map", "key", "value")</pre> or\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">map:insert("my-map", [ "key1", "key2" ] , (42, "value"))</pre>.\n',summary:"<p> Inserts a new entry into the map with the given name.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'},{name:"key",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> either a single attribute key or an array of keys</div>'},{name:"value",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value of the entry to insert</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately inserts the entry into the map. It returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the given number of key attributes does not match the number of key attributes specified when creating the map (see the map:create function).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQD0005 if any of the given key attributes can not be cast (or is not a subtype) of the corresponding key attribute specified when creating the map.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY1003 if the value to insert is an object or array it must belong to a collection.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"keys",qname:"map:keys",signature:"($name as string) as array()* external",description:' Returns the keys of all entries of a map. The keys\n are returned as sequence of arrays.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The following condition always holds:\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">map:size($name) eq count(map:keys($name))</tt>\n',summary:"<p> Returns the keys of all entries of a map.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'}],returns:{type:"array()*",description:"an sequence of arrays each array containing the values of all attributes of one key."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"options",qname:"map:options",signature:"($name as string) as object() external",description:" The function returns the options that were passed during creation or the\n default options if no options were passed.\n",summary:"<p> The function returns the options that were passed during creation or the\n default options if no options were passed.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'}],returns:{type:"object()",description:"an options object"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"size",qname:"map:size",signature:"($name as string) as integer external",description:' Returns the number of entries in a map.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The following condition always holds:\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">map:size($name) eq count(map:keys($name))</tt>\n',summary:"<p> Returns the number of entries in a map.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'}],returns:{type:"integer",description:"the number of entries in the map."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>']}],variables:[{name:"map:PERSISTENT",type:"string",description:" Constant containing the field name of the options object\n indiciating whether a map is persistent or transient.\n"}]},"http://www.28msec.com/modules/assertion":{ns:"http://www.28msec.com/modules/assertion",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   This module provides a set of assertion functions.\n </p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/assertion",prefix:"assertion"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"equals-deep",qname:"assertion:equals-deep",signature:"($expected as item()*, $actual as item()*) as item()*",description:" Asserts that two objects are deep-equal.\n If they are not, an error containing the diff is raised.\n",summary:"<p> Asserts that two objects are deep-equal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"expected",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> expected value</div>'},{name:"actual",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> actual value</div>'}],returns:{type:"item()*",description:"actual value"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">assertion:A003 expected and actual value are not deep-equal</xqdoc:error>']},{isDocumented:!0,arity:2,name:"equals-general",qname:"assertion:equals-general",signature:"($expected as item()*, $actual as item()*) as item()*",description:" Asserts that two objects are equal (by general comarison).\n If they are not, an error containing the diff is raised.\n",summary:"<p> Asserts that two objects are equal (by general comarison).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"expected",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> expected value</div>'},{name:"actual",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> actual value</div>'}],returns:{type:"item()*",description:"actual value"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">assertion:A002 expected and actual value are not equal</xqdoc:error>']},{isDocumented:!0,arity:2,name:"equals-value",qname:"assertion:equals-value",signature:"($expected as item()?, $actual as item()?) as item()?",description:" Asserts that two objects are equal (by value comparison).\n If they are not, an error containing the diff is raised.\n",summary:"<p> Asserts that two objects are equal (by value comparison).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"expected",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> expected value</div>'},{name:"actual",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> actual value</div>'}],returns:{type:"item()?",description:"actual value"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">assertion:A001 expected and actual value are not equal</xqdoc:error>']}],variables:[{name:"assertion:A001",type:"xs:QName",description:" xs:QName with namespace URI=\"http://www.28msec.com/modules/assertion\" and\n local name 'A001'. 'equals-value' assertion failed.\n"},{name:"assertion:A002",type:"xs:QName",description:" xs:QName with namespace URI=\"http://www.28msec.com/modules/assertion\" and\n local name 'A002'. 'equals-general' assertion failed.\n"},{name:"assertion:A003",type:"xs:QName",description:" xs:QName with namespace URI=\"http://www.28msec.com/modules/assertion\" and\n local name 'A003'. 'equals-general' assertion failed.\n"}]},"http://www.zorba-xquery.com/modules/image/basic":{ns:"http://www.zorba-xquery.com/modules/image/basic",description:' This module provides function to do the following basic image operations:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>create empty images</li>\n   <li>compare images</li>\n   <li>compress image</li>\n   <li>convert an image one format to another</li>\n   <li>retrieve with, height, format, and exif information from an image</li>\n </ul>\n The following image formats are supported:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>GIF</li>\n   <li>JPEG</li>\n   <li>PNG</li>\n   <li>TIFF</li>\n   <li>BMP</li>\n </ul>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The errors raised by functions of this module have the namespace\n <tt>http://www.zorba-xquery.com/modules/image/error</tt> (associated with prefix ierr).</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Thomas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/image/basic",prefix:"basic"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.zorba-xquery.com/modules/image/error",prefix:"ierr"},{uri:"http://www.zorba-xquery.com/modules/image/image",prefix:"image"},{uri:"http://www.w3.org/2000/svg",prefix:"svg"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"compress",qname:"basic:compress",signature:"($image as xs:base64Binary, $quality as xs:unsignedInt) as xs:base64Binary external",description:" Compresses the passed image.\n Compressing means lowering the quality and reducing the size.\n",summary:"<p> Compresses the passed image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image</div>'},{name:"quality",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> compression level, 0 to 100</div>'}],returns:{type:"xs:base64Binary",description:"the compressed image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 the passed image is invalid.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"convert-svg-string",qname:"basic:convert-svg-string",signature:"($svg as xs:string, $format as xs:string) as xs:base64Binary",description:" Converts an SVG image to a supported image format.\n",summary:"<p> Converts an SVG image to a supported image format.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"svg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image to convert as string</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> target format</div>'}],returns:{type:"xs:base64Binary",description:"the resulting image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 the passed SVG is invalid.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"convert-svg",qname:"basic:convert-svg",signature:"($svg as element(svg:svg), $format as xs:string) as xs:base64Binary",description:" Converts an SVG image to a supported image format.\n",summary:"<p> Converts an SVG image to a supported image format.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"svg",type:"element(svg:svg)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image to convert</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> target format</div>'}],returns:{type:"xs:base64Binary",description:"the resulting image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 the passed SVG is invalid.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"convert",qname:"basic:convert",signature:"($image as xs:base64Binary, $format as xs:string) as xs:base64Binary",description:" Converts an image to another format.\n",summary:"<p> Converts an image to another format.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the format (see supported formats above) of the resulting image.</div>'}],returns:{type:"xs:base64Binary",description:"A new image with the same content as the passed image but with the specified file format."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 the passed image is invalid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FORG0001 unsupported image format</xqdoc:error>']},{isDocumented:!0,arity:3,name:"create",qname:"basic:create",signature:"($width as xs:unsignedInt, $height as xs:unsignedInt, $format as xs:string) as xs:base64Binary",description:" Creates an empty image with background color white.\n",summary:"<p> Creates an empty image with background color white.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"width",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the width of the new image</div>'},{name:"height",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the height of the new image</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the format of the new image</div>'}],returns:{type:"xs:base64Binary",description:"newly created image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FORG0001 unsupported image format</xqdoc:error>']},{isDocumented:!0,arity:2,name:"equals",qname:"basic:equals",signature:"($image1 as xs:base64Binary, $image2 as xs:base64Binary) as xs:boolean external",description:" Compares two images.\n",summary:"<p> Compares two images.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image1",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> first image</div>'},{name:"image2",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> second image</div>'}],returns:{type:"xs:boolean",description:"True if the images are equal."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 one of the passed images is invalid.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"exif",qname:"basic:exif",signature:"($image as xs:base64Binary, $tag as xs:string) as xs:string? external",description:" Reads exif information from an image.\n This function works for JPEG and TIFF images only.\n It returns empty sequence if no exif information matching the passed tag is found.\n",summary:"<p> Reads exif information from an image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image</div>'},{name:"tag",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the field name we want read (e.g. DateTime).</div>'}],returns:{type:"xs:string?",description:"exif field content"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 the passed image is invalid.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"format",qname:"basic:format",signature:"($image as xs:base64Binary) as xs:string external",description:" Returns the format of the passed image.\n",summary:"<p> Returns the format of the passed image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image</div>'}],returns:{type:"xs:string",description:"the format"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 the passed image is invalid.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"height",qname:"basic:height",signature:"($image as xs:base64Binary) as xs:unsignedInt external",description:" Returns the height of the passed image.\n",summary:"<p> Returns the height of the passed image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image</div>'}],returns:{type:"xs:unsignedInt",description:"the height in pixels"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 the passed image is invalid.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"width",qname:"basic:width",signature:"($image as xs:base64Binary) as xs:unsignedInt external",description:" Returns the width of the passed image.\n",summary:"<p> Returns the width of the passed image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image</div>'}],returns:{type:"xs:unsignedInt",description:"the width in pixels"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 the passed image is invalid.</xqdoc:error>']}],variables:[]},"http://api.28.io/indices":{ns:"http://api.28.io/indices",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/indices",prefix:"in"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://www.28msec.com/modules/http/response",prefix:"resp"},{uri:"http://api.28.io/util",prefix:"util"},{uri:"http://api.28.io/validation",prefix:"validate"}],functions:[{isDocumented:!1,arity:1,name:"create-index",qname:"in:create-index",signature:"($new-index as object()) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"new-index",type:"object()",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]},{isDocumented:!1,arity:1,name:"delete-index",qname:"in:delete-index",signature:"($name) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:null,occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]},{isDocumented:!1,arity:0,name:"dispatch",qname:"in:dispatch",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"get-index",qname:"in:get-index",signature:"($name as xs:string) as object()?",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""}],returns:{type:"object()?",description:""},errors:[]},{isDocumented:!1,arity:0,name:"list-indices",qname:"in:list-indices",signature:"() as array()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"array()",description:""},errors:[]},{isDocumented:!1,arity:0,name:"metadata",qname:"in:metadata",signature:"()",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"put-index",qname:"in:put-index",signature:"($name as xs:string, $new-index-obj as object()) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""},{name:"new-index-obj",type:"object()",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]},{isDocumented:!1,arity:1,name:"refresh-index",qname:"in:refresh-index",signature:"($index as xs:string) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"index",type:"xs:string",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]},{isDocumented:!1,arity:1,name:"validate-index",qname:"in:validate-index",signature:"($index as object()) as empty-sequence()",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"index",type:"object()",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]}],variables:[]},"http://api.28.io/xdmview":{ns:"http://api.28.io/xdmview",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/model",prefix:"model"},{uri:"http://zorba.io/modules/reference",prefix:"ref"},{uri:"http://www.zorba-xquery.com/schemas/xdm",prefix:"xdm"},{uri:"http://api.28.io/xdmview",prefix:"xdmview"}],functions:[{isDocumented:!1,arity:1,name:"show-namespaces",qname:"xdmview:show-namespaces",signature:"($namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"show-node",qname:"xdmview:show-node",signature:"($node, $namespaces, $include-noderef as xs:boolean)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"node",type:null,occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""},{name:"include-noderef",type:"xs:boolean",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"show-nodes",qname:"xdmview:show-nodes",signature:"($nodes, $include-noderef as xs:boolean)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""},{name:"include-noderef",type:"xs:boolean",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/xqdoc/json":{ns:"http://www.zorba-xquery.com/modules/xqdoc/json",description:' Convert an XQDoc document into an HTML document.\n This module contains a single <code xmlns:xqdoc="http://www.xqdoc.org/1.0">convert()</code> function\n that transform an XQDoc document into an HTML document.\n Usage:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n let $xqdoc := xqdoc:xqdoc("http://expath.org/ns/file")\n return html:convert($xqdoc)\n </pre>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">William Candillon <a href="?anchor=">wcandillon at gmail dot com</a></xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/xqdoc/json",prefix:"html"},{uri:"http://www.w3.org/2010/xslt-xquery-serialization",prefix:"o"},{uri:"http://www.xqdoc.org/1.0",prefix:"xq"}],functions:[{isDocumented:!1,arity:1,name:"convert",qname:"html:convert",signature:"($xqdoc as element(xq:xqdoc)) as object()",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xqdoc",type:"element(xq:xqdoc)",occurrence:null,description:""}],returns:{type:"object()",description:""},errors:[]},{isDocumented:!1,arity:1,name:"normalize-anchors",qname:"html:normalize-anchors",signature:"($node)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]}],variables:[]},"http://zorba.io/modules/math":{ns:"http://zorba.io/modules/math",description:' Extensive math library.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Turcanu, Dan Muresan</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xpath-functions/math",prefix:"W3Cmath"},{uri:"http://zorba.io/modules/math",prefix:"math"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"acosh",qname:"math:acosh",signature:"($arg as double) as double external",description:" Inverse hyperbolic cosine.\n",summary:"<p> Inverse hyperbolic cosine.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the arg</div>'}],returns:{type:"double",description:"the result of acosh(arg)"},errors:[]},{isDocumented:!0,arity:1,name:"asinh",qname:"math:asinh",signature:"($arg as double) as double external",description:" Calculate the inverse hyperbolic sine.\n",summary:"<p> Calculate the inverse hyperbolic sine.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the arg</div>'}],returns:{type:"double",description:"the result of asinh(arg)"},errors:[]},{isDocumented:!0,arity:1,name:"atanh",qname:"math:atanh",signature:"($arg as double) as double external",description:" Calculate the hyperbolic tangent.\n",summary:"<p> Calculate the hyperbolic tangent.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> must be in range -1 ... +1 (exclusive)</div>'}],returns:{type:"double",description:"the result of atanh(arg)"},errors:[]},{isDocumented:!0,arity:1,name:"avedev",qname:"math:avedev",signature:"($numbers as double+) as double",description:' Returns the average of the absolute deviations of data points from their mean.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is sum(abs(x - average_x))/n, where n is the count of x in the sequence.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the average of the absolute deviations of data points from their mean.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers. Sequence can be of any length from 1 up.</div>'}],returns:{type:"double",description:"The formula result"},errors:[]},{isDocumented:!0,arity:1,name:"cast-as-numeric",qname:"math:cast-as-numeric",signature:"($number as anyAtomicType) as anyAtomicType",description:' Cast the anyAtomicType to a numeric type.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the value is already of a numeric type then nothing is changed.\n Otherwise the value is casted to the numeric type that is most appropriate.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Cast the anyAtomicType to a numeric type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The parameter can be a number, string, boolean value.</div>'}],returns:{type:"anyAtomicType",description:"The casted value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:VALUE_NOT_NUMERIC if the value cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"ceiling",qname:"math:ceiling",signature:"($number as double, $significance as double) as double",description:' Returns number rounded up, away from zero, to the nearest multiple of significance.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Significance must have the same sign as number.\n Number and significance must be of a numeric type or castable to numeric.\n Significance must not be zero.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns number rounded up, away from zero, to the nearest multiple of significance.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value you want to round.</div>'},{name:"significance",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The multiple to which you want to round.</div>'}],returns:{type:"double",description:"The rounded value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if significance is zero or it doesn\'t have the same sign as number.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"cosh",qname:"math:cosh",signature:"($arg as double) as double external",description:' Returns the hyperbolic cosine of x.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the result it too large, INF is returned.\n',summary:"<p> Returns the hyperbolic cosine of x.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> must be smaller than 7.104760e+002</div>'}],returns:{type:"double",description:"cosh(arg)"},errors:[]},{isDocumented:!0,arity:1,name:"deg-to-rad",qname:"math:deg-to-rad",signature:"($deg as double) as double",description:' Convert angle from degrees to radians. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The parameter is first converted to value range of (-360, 360).\n',summary:"<p> Convert angle from degrees to radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"deg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> angle in degrees</div>'}],returns:{type:"double",description:"value in radians (-2PI, 2PI)"},errors:[]},{isDocumented:!0,arity:1,name:"even",qname:"math:even",signature:"($number as double) as integer",description:' Returns number rounded up to the nearest even integer.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Regardless of the sign of number, a value is rounded up when adjusted away from zero.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns number rounded up to the nearest even integer.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to round.</div>'}],returns:{type:"integer",description:"The rounded value casted as numeric type."},errors:[]},{isDocumented:!0,arity:1,name:"fact",qname:"math:fact",signature:"($number as integer) as integer",description:' Returns the factorial of a number.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the factorial of a number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The non-negative number you want the factorial of.</div>'}],returns:{type:"integer",description:"Returns the factorial of a number. The factorial of a number is equal to 1*2*3*...* number."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if the number is smaller than zero</xqdoc:error>']},{isDocumented:!0,arity:1,name:"factdouble",qname:"math:factdouble",signature:"($number as integer) as integer",description:' Returns the double factorial of a number.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Computes the double factorial of n as n(n-2)(n-4)...<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the double factorial of a number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The positive integer value.</div>'}],returns:{type:"integer",description:"The result as integer."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if the number is negative.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"floor",qname:"math:floor",signature:"($number as double, $significance as double) as double",description:' Rounds number down, toward zero, to the nearest multiple of significance.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Significance must have the same sign as number.\n Borrowed from excel module.\n',summary:"<p> Rounds number down, toward zero, to the nearest multiple of significance.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value you want to round.</div>'},{name:"significance",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The multiple to which you want to round.</div>'}],returns:{type:"double",description:"The rounded value as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if significance is zero or it doesn\'t have the same sign as number.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"fmod",qname:"math:fmod",signature:"($x as double, $y as double) as double external",description:" Function performing the modulo operation between the two arguments.\n",summary:"<p> Function performing the modulo operation between the two arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the x</div>'},{name:"y",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the y</div>'}],returns:{type:"double",description:"The remainder of x/y."},errors:[]},{isDocumented:!0,arity:1,name:"frexp",qname:"math:frexp",signature:"($arg as double) as double+ external",description:' Returns the argument split as mantissa and exponent.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The recombining formula is (mantissa * 2^exponent).\n',summary:"<p> Returns the argument split as mantissa and exponent.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the double to be split.</div>'}],returns:{type:"double+",description:"A sequence of two doubles (mantissa, exponent)"},errors:[]},{isDocumented:!0,arity:1,name:"gcd",qname:"math:gcd",signature:"($numbers as integer+) as integer",description:' Returns the greatest common divisor GCD of a sequence of integers.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The sequence can have one or more positive integers.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the greatest common divisor GCD of a sequence of integers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"integer",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of positive integers.</div>'}],returns:{type:"integer",description:"The GCD as integer."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if any number is smaller than zero.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"int",qname:"math:int",signature:"($number as double) as integer",description:' Rounds a number down to the nearest integer.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Positive numbers are rounded toward zero, negative numbers are rounded away from zero.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Rounds a number down to the nearest integer.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be rounded.</div>'}],returns:{type:"integer",description:"The rounded integer."},errors:[]},{isDocumented:!0,arity:1,name:"is-a-number",qname:"math:is-a-number",signature:"($value as anyAtomicType) as boolean",description:' Checks if the anyAtomicType argument is actually a numeric type\n or can be converted to numeric.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Checks if the anyAtomicType argument is actually a numeric type\n or can be converted to numeric.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Parameter to be checked.</div>'}],returns:{type:"boolean",description:"true if the value can be casted to numeric."},errors:[]},{isDocumented:!0,arity:1,name:"is_inf",qname:"math:is_inf",signature:"($arg as double) as boolean external",description:" Checks if the double value is positive or negative infinite.\n",summary:"<p> Checks if the double value is positive or negative infinite.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the double to be checked</div>'}],returns:{type:"boolean",description:"boolean true if argument is pos INF or neg INF"},errors:[]},{isDocumented:!0,arity:1,name:"is_nan",qname:"math:is_nan",signature:"($arg as double) as boolean external",description:" Checks if the double value is Not a Number (NaN).\n",summary:"<p> Checks if the double value is Not a Number (NaN).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the arg</div>'}],returns:{type:"boolean",description:"boolean true if the double is NaN"},errors:[]},{isDocumented:!0,arity:2,name:"large",qname:"math:large",signature:"($numbers as double+, $k as integer) as double",description:' Returns the k-th largest value in a data set. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If n is the number of data points in a range,\n   then LARGE(array,1) returns the largest value,\n   and LARGE(array,n) returns the smallest value.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Returns the k-th largest value in a data set.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers The sequence can be of any length, from 1 up.</div>'},{name:"k",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the position of largest value, with value from 1 to count of values</div>'}],returns:{type:"double",description:"The k-th largest value as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if the sequence is empty or k is not a value between 1 and the size of the sequence</xqdoc:error>']},{isDocumented:!0,arity:1,name:"lcm",qname:"math:lcm",signature:"($numbers as integer+) as integer",description:' Returns the least common multiple of integers.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n LCM for two numbers is computed by multiplying them and dividing with GCD.\n The function is applied recursively replacing the first two numbers in the sequence with their LCM.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the least common multiple of integers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"integer",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of one or more positive integers.</div>'}],returns:{type:"integer",description:"The LCM as integer."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if any number is smaller than zero.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"ldexp",qname:"math:ldexp",signature:"($x as double, $i as integer) as double external",description:' Computes a real number from the mantissa and exponent.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is (x * 2^i).\n',summary:"<p> Computes a real number from the mantissa and exponent.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the mantissa</div>'},{name:"i",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the exponent</div>'}],returns:{type:"double",description:"the computed real number"},errors:[]},{isDocumented:!0,arity:1,name:"median",qname:"math:median",signature:"($numbers as double*) as double",description:' Returns the median of the given numbers. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The median is the number in the middle of a set of numbers.\n Half the numbers have values that are greater than the median,\n and half the numbers have values that are less than the median. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the median of the given numbers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers, of any length</div>'}],returns:{type:"double",description:"for odd count of numbers return the number in the middle of the sorted sequence. For even count of numbers return the average of the two numbers in the middle."},errors:[]},{isDocumented:!0,arity:2,name:"mod",qname:"math:mod",signature:"($number as double, $divisor as double) as double",description:' Returns the remainder after number is divided by divisor.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The result has the same sign as divisor.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the remainder after number is divided by divisor.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number for which you want to find the remainder.</div>'},{name:"divisor",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number by which you want to divide number. This cannot be zero.</div>'}],returns:{type:"double",description:"The remainder from division as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:DIVIDE_BY_0 if divisor is zero after casting to numeric.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"mode",qname:"math:mode",signature:"($numbers as double*) as double",description:' Returns the most frequently occurring, or repetitive, value in a sequence.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the most frequently occurring, or repetitive, value in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers, of any length</div>'}],returns:{type:"double",description:"The most occuring number"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_INPUT if there are no duplicate numbers</xqdoc:error>']},{isDocumented:!0,arity:1,name:"modf",qname:"math:modf",signature:"($arg as double) as double+ external",description:' Splits a floating-point value into fractional and integer parts.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Both the fraction and integer keep the original sign of the value.\n',summary:"<p> Splits a floating-point value into fractional and integer parts.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the double to be split.</div>'}],returns:{type:"double+",description:"A sequence of two doubles (fraction, integer)"},errors:[]},{isDocumented:!0,arity:2,name:"mround",qname:"math:mround",signature:"($number as decimal, $multiple as double) as double",description:' Returns a number rounded to the desired multiple.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n MROUND rounds up, away from zero, if the remainder of dividing number by multiple\n is greater than or equal to half the value of multiple.\n MROUND is computed through math:floor function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns a number rounded to the desired multiple.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to round,</div>'},{name:"multiple",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The multiple to which you want to round number.</div>'}],returns:{type:"double",description:"The rounded number up to the desired multiple."},errors:[]},{isDocumented:!0,arity:1,name:"odd",qname:"math:odd",signature:"($number as double) as integer",description:' Returns number rounded up to the nearest odd integer, away from zero.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns number rounded up to the nearest odd integer, away from zero.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to round.</div>'}],returns:{type:"integer",description:"The odd integer."},errors:[]},{isDocumented:!0,arity:2,name:"percentile",qname:"math:percentile",signature:"($numbers as double*, $k_at as double) as double",description:' Returns the k-th percentile of values in a sequence.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If k is not a multiple of 1/(n - 1),\n   PERCENTILE interpolates to determine the value at the k-th percentile.\n The function is computed by (max-min)*k + min<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the k-th percentile of values in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers, of any length</div>'},{name:"k_at",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the percentile, with value between 0 .. 1 inclusive</div>'}],returns:{type:"double",description:"The computed percentile"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if percentile is not between 0 .. 1</xqdoc:error>']},{isDocumented:!0,arity:2,name:"percentrank",qname:"math:percentrank",signature:"($numbers as double*, $x as double) as double",description:' Returns the rank of a value in a data set as a percentage of the data set.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If x does not match one of the values in array,\n   PERCENTRANK interpolates to return the correct percentage rank. <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is uses: (RANK - 1) / (size - 1) .<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the rank of a value in a data set as a percentage of the data set.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers. The sequence can be of any length, from 1 up.</div>'},{name:"x",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the value for which you want to know the rank</div>'}],returns:{type:"double",description:"The percentage of rank."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if the sequence is zero length</xqdoc:error>']},{isDocumented:!0,arity:3,name:"prob",qname:"math:prob",signature:"($x_range as double+, $prob_range as double+, $range_lower_limit as double) as double",description:' This is the same as math:prob#4, only that upper_limit is not specified.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The probability is computed only for range_lower_limit.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> This is the same as math:prob#4, only that upper_limit is not specified.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x_range",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the range of numeric values of x with which there are associated probabilities. This does not need to be ordered.</div>'},{name:"prob_range",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is a set of probabilities associated with values in x_range.</div>'},{name:"range_lower_limit",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the value for which you want a probability.</div>'}],returns:{type:"double",description:"The probability of the range_lower_limit value"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if any probability is not between 0 and 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if the sum of probabilities is not equal to 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if x_range and prob_range do not have the same number of values</xqdoc:error>']},{isDocumented:!0,arity:4,name:"prob",qname:"math:prob",signature:"($x_range as double+, $prob_range as double+, $range_lower_limit as double, $upper_limit as double) as double",description:' Returns the probability that values in a range are between two limits.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the probability that values in a range are between two limits.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x_range",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the range of numeric values of x with which there are associated probabilities. This does not need to be ordered.</div>'},{name:"prob_range",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is a set of probabilities associated with values in x_range.</div>'},{name:"range_lower_limit",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the lower bound on the value for which you want a probability.</div>'},{name:"upper_limit",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the upper bound on the value for which you want a probability.</div>'}],returns:{type:"double",description:"The probability of the entire range"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if any probability is not between 0 and 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if the sum of probabilities is not equal to 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if x_range and prob_range do not have the same number of values</xqdoc:error>']},{isDocumented:!0,arity:1,name:"product",qname:"math:product",signature:"($numbers as double*) as double",description:' Multiplies all the numbers given as arguments and returns the product.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Multiplies all the numbers given as arguments and returns the product.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of arguments convertible to numeric types. The sequence can be of any length.</div>'}],returns:{type:"double",description:"The multiplication result as numeric type."},errors:[]},{isDocumented:!0,arity:2,name:"quartile",qname:"math:quartile",signature:"($numbers as double*, $quart as integer) as double",description:' Returns the quartile of a data set. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the quartile of a data set.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> sequence of numbers. The sequence can be of any length, from 1 up.</div>'},{name:"quart",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <dl>one of the values 0, 1, 2, 3, 4 with meaning: <dt>0</dt> <dd> compute minimum value</dd> <dt>1</dt> <dd> compute first quartile (25th percentile)</dd> <dt>2</dt> <dd> compute median value (50th percentile)</dd> <dt>3</dt> <dd> compute third quartile (75th percentile)</dd> <dt>4</dt> <dd> compute maximum value</dd></dl></div>'}],returns:{type:"double",description:"the computed quartile, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if the sequence is zero length or $quart is not one of the values 0,1,3,4</xqdoc:error>']},{isDocumented:!0,arity:2,name:"quotient",qname:"math:quotient",signature:"($numerator as double, $denominator as double) as integer",description:' Returns the integer portion of a division.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the integer portion of a division.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numerator",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The divider.</div>'},{name:"denominator",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The divisor. It cannot be zero.</div>'}],returns:{type:"integer",description:"The result value as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:DIVIDE_BY_0 if denominator casted as numeric type has value zero.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"rad-to-deg",qname:"math:rad-to-deg",signature:"($rad as double) as double",description:' Convert angle from radians to degrees. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Convert angle from radians to degrees.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"rad",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> value in radians</div>'}],returns:{type:"double",description:"value in degrees (-360, 360)"},errors:[]},{isDocumented:!0,arity:2,name:"rank",qname:"math:rank",signature:"($x as double, $numbers as double*) as double",description:' This RANK function is same as the above, only that $order_ascending is set by default to false.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> This RANK function is same as the above, only that $order_ascending is set by default to false.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number whose rank you want to find.</div>'},{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers. The sequence can be of any length.</div>'}],returns:{type:"double",description:"The rank of $x."},errors:[]},{isDocumented:!0,arity:3,name:"rank",qname:"math:rank",signature:"($x as double, $numbers as double*, $order_ascending as boolean) as double",description:' Returns the rank of a number in a list of numbers. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The rank of a number is its size relative to other values in a list.\n (If you were to sort the list, the rank of the number would be its position.)\n RANK gives duplicate numbers the same rank.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the rank of a number in a list of numbers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number whose rank you want to find.</div>'},{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of numbers. The sequence can be of any length.</div>'},{name:"order_ascending",type:"boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <dl>A boolean having the meaning: <dt>false</dt><dd>then rank the number as if the sequence was sorted in descending order.</dd> <dt>true</dt> <dd>then rank the number as if the sequence was sorted in ascending order.</dd></dl></div>'}],returns:{type:"double",description:"The rank of $x."},errors:[]},{isDocumented:!0,arity:1,name:"roman",qname:"math:roman",signature:"($number as integer) as string",description:' Converts an Arabic numeral to roman, as text.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Only the classic format is supported (out of all formats Excel requires).\n M is the largest digit, it represents 1000.\n Numbers bigger than 2000 will be represented by a sequence of "M".\n D = 500, C = 100, L = 50, X = 10, V = 5, I = 1.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Converts an Arabic numeral to roman, as text.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A positive integer.</div>'}],returns:{type:"string",description:"The roman string representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if the input integer is negative</xqdoc:error>']},{isDocumented:!0,arity:2,name:"round",qname:"math:round",signature:"($number as double, $precision as integer) as double",description:' Rounds a number to a specified number of digits.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If precision is greater than 0 (zero), then number is rounded\n to the specified number of decimal places.\n If num_digits is 0, then number is rounded to the nearest integer.\n If num_digits is less than 0, then number is rounded to the left of the decimal point.\n The 0.5 is rounded away from zero. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Rounds a number to a specified number of digits.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number to round.</div>'},{name:"precision",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of decimal places to keep.</div>'}],returns:{type:"double",description:"The rounded number as numeric type."},errors:[]},{isDocumented:!0,arity:2,name:"rounddown",qname:"math:rounddown",signature:"($number as double, $precision as integer) as double",description:' Rounds a number down, toward zero.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If num_digits is greater than 0 (zero), then number is rounded down\n to the specified number of decimal places.\n If num_digits is 0, then number is rounded down to the nearest integer.\n If num_digits is less than 0, then number is rounded down to the left of the decimal point. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Rounds a number down, toward zero.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number to round</div>'},{name:"precision",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of decimal places to keep.</div>'}],returns:{type:"double",description:"the truncated number toward zero, as numeric type."},errors:[]},{isDocumented:!0,arity:2,name:"roundup",qname:"math:roundup",signature:"($number as double, $precision as integer) as double",description:' Rounds a number up, away from 0 (zero).<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If num_digits is greater than 0 (zero), then number is rounded down\n to the specified number of decimal places.\n If num_digits is 0, then number is rounded down to the nearest integer.\n If num_digits is less than 0, then number is rounded down to the left of the decimal point. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Rounds a number up, away from 0 (zero).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number to round</div>'},{name:"precision",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of decimal places to keep.</div>'}],returns:{type:"double",description:"The truncated number away from zero, as numeric type."},errors:[]},{isDocumented:!0,arity:1,name:"sign",qname:"math:sign",signature:"($number as double) as integer",description:' Determines the sign of a number. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Returns 1 if the number is positive, zero (0) if the number is 0,\n and -1 if the number is negative.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Determines the sign of a number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The argument</div>'}],returns:{type:"integer",description:"The sign as (-1, 0, 1)."},errors:[]},{isDocumented:!0,arity:1,name:"sinh",qname:"math:sinh",signature:"($arg as double) as double external",description:" Calculate the hyperbolic sine.\n",summary:"<p> Calculate the hyperbolic sine.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the arg</div>'}],returns:{type:"double",description:"the result of sinh(arg)"},errors:[]},{isDocumented:!0,arity:2,name:"slope",qname:"math:slope",signature:"($known_y as double+, $known_x as double+) as double",description:' Returns the slope of the linear regression line through data points in known_y\'s and known_x\'s.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The slope is the vertical distance divided by the horizontal distance between\n   any two points on the line, which is the rate of change along the regression line.\n It computes the formula:<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n sum((x - average_x)(y - average_y)) / sum((x - average_x)^2)<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n where average_x and average_y are computed with AVERAGE function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the slope of the linear regression line through data points in known_y's and known_x's.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"known_y",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of y numbers. The sequence can be of any length, from 1 up.</div>'},{name:"known_x",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of x numbers. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"double",description:"The slope value, as numeric type"},errors:["<xqdoc:error xmlns:xqdoc=\"http://www.xqdoc.org/1.0\">math:INVALID_INPUT if there are different numbers of x's and y's or if the sequence is empty</xqdoc:error>",'<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:DIVIDE_BY_0 if all x\'s are equal</xqdoc:error>']},{isDocumented:!0,arity:2,name:"small",qname:"math:small",signature:"($numbers as double*, $k as integer) as double",description:' This function computes the k-th smallest value in a data set. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Use this function to return values with a particular relative standing in a data set.\n If n is the number of data points in array, SMALL(array,1) equals the smallest value,\n   and SMALL(array,n) equals the largest value.\n Borrowed from excel module.\n',summary:"<p> This function computes the k-th smallest value in a data set.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of numbers. The sequence can be of any length, from 1 up.</div>'},{name:"k",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The position (from the smallest) in the sequence of data to return. Must have value between 1 and size of sequence.</div>'}],returns:{type:"double",description:"The k-th smallest value of $numbers."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if the sequence is zero length or $k is not a value between 1 and the size of sequence.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"sort-numbers",qname:"math:sort-numbers",signature:"($numbers as double*) as double*",description:' Sorts a sequence of numbers or arguments castable to numeric.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n It first casts all arguments to numeric and then sorts ascending.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Helper function.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Sorts a sequence of numbers or arguments castable to numeric.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of arguments castable to numeric.</div>'}],returns:{type:"double*",description:"The sorted sequence as numeric types."},errors:[]},{isDocumented:!0,arity:3,name:"standardize",qname:"math:standardize",signature:"($x as double, $mean as double, $standard_dev as double) as double",description:' Returns a normalized value from a distribution characterized by mean and standard_dev.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is (x - mean) / standard_dev .<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns a normalized value from a distribution characterized by mean and standard_dev.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the value you want to normalize</div>'},{name:"mean",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the arithmetic mean of the distribution.</div>'},{name:"standard_dev",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the standard deviation of the distribution.</div>'}],returns:{type:"double",description:"The normalized x, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if standard_dev is a value smaller than zero or equal</xqdoc:error>']},{isDocumented:!0,arity:1,name:"stdev",qname:"math:stdev",signature:"($numbers as double+) as double",description:' Estimates standard deviation based on a sample. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The standard deviation is a measure of how widely values are dispersed\n   from the average value (the mean).\n It is computed with formula:\n sqrt( sum((x-average_x)^2) / (n-1) )    = sqrt ( VAR(numbers) )<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Estimates standard deviation based on a sample.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers The sequence can be of any length, from 1 up.</div>'}],returns:{type:"double",description:"the standard deviation, as numeric type"},errors:[]},{isDocumented:!0,arity:1,name:"stdeva",qname:"math:stdeva",signature:"($numbers as double+) as double",description:' Estimates standard deviation based on a sample. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The standard deviation is a measure of how widely values are dispersed\n   from the average value (the mean).\n It is computed with formula:\n sqrt( sum((x-average_x)^2) / (n-1) )    = sqrt ( VARA(numbers) )<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Estimates standard deviation based on a sample.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"double",description:"the standard deviation, as numeric type"},errors:[]},{isDocumented:!0,arity:1,name:"stdevp",qname:"math:stdevp",signature:"($numbers as double+) as double",description:' Calculates standard deviation based on the entire population given as arguments. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The standard deviation is a measure of how widely values are dispersed from\n   the average value (the mean).\n It is computed with formula:\n sqrt( sum((x-average_x)^2) / n )    = sqrt ( VARP(numbers) )<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Calculates standard deviation based on the entire population given as arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric The sequence can be of any length, from 1 up.</div>'}],returns:{type:"double",description:"the standard deviation, as numeric type"},errors:[]},{isDocumented:!0,arity:1,name:"stdevpa",qname:"math:stdevpa",signature:"($numbers as double+) as double",description:' Calculates standard deviation based on the entire population given as arguments. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The standard deviation is a measure of how widely values are dispersed from\n   the average value (the mean).\n It is computed with formula:\n sqrt( sum((x-average_x)^2) / n )    = sqrt ( VARPA(numbers) )<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Calculates standard deviation based on the entire population given as arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric The sequence can be of any length, from 1 up.</div>'}],returns:{type:"double",description:"the standard deviation, as numeric type"},errors:[]},{isDocumented:!0,arity:2,name:"subtotal",qname:"math:subtotal",signature:"($function_num as integer, $numbers as double*) as double",description:' Returns a subtotal in a sequence of numbers.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The function applied is given by $function_num.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns a subtotal in a sequence of numbers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"function_num",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <dl>defines the function to be applied on sequence values. The possible values are: <dt>1 or 101</dt> <dd> AVERAGE</dd> <dt>2 or 102</dt> <dd> COUNT</dd> <dt>3 or 103</dt> <dd> COUNTA</dd> <dt>4 or 104</dt> <dd> MAX</dd> <dt>5 or 105</dt> <dd> MIN</dd> <dt>6 or 106</dt> <dd> PRODUCT</dd> <dt>7 or 107</dt> <dd> STDEV</dd> <dt>8 or 108</dt> <dd> STDEVP</dd> <dt>9 or 109</dt> <dd> SUM</dd> <dt>10 or 110</dt> <dd> VAR</dd> <dt>11 or 111</dt> <dd> VARP</dd></dl> In this implementation there is no difference between x and 10x.<br/></div>'},{name:"numbers",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers. The sequence can be of any length.</div>'}],returns:{type:"double",description:"The function result, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">* depends on the function called</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">math:INVALID_ARGUMENT if $function_num is not a value between 1 .. 11 or 101 .. 111</xqdoc:error>']},{isDocumented:!0,arity:2,name:"sumproduct",qname:"math:sumproduct",signature:"($array1 as double*, $array2 as double*) as double",description:' Multiplies the elements on the same position in each sequence\n and sums up the results.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers</div>'},{name:"array2",type:"double",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers</div>'}],returns:{type:"double",description:"the sum of products"},errors:[]},{isDocumented:!0,arity:1,name:"sumsq",qname:"math:sumsq",signature:"($numbers as double+) as double",description:' Returns the sum of the squares of the arguments.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n It uses the sumproduct function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Returns the sum of the squares of the arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of one or more numbers</div>'}],returns:{type:"double",description:"the sum of squared values, as numeric type"},errors:[]},{isDocumented:!0,arity:1,name:"tanh",qname:"math:tanh",signature:"($arg as double) as double external",description:" Calculate the hyperbolic tangent.\n",summary:"<p> Calculate the hyperbolic tangent.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the arg</div>'}],returns:{type:"double",description:"the result of tanh(arg)"},errors:[]},{isDocumented:!0,arity:1,name:"trunc",qname:"math:trunc",signature:"($number as double) as integer",description:' Truncates a number to an integer by removing the fractional part of the number.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Truncates a number to an integer by removing the fractional part of the number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The argument .</div>'}],returns:{type:"integer",description:"The integer value."},errors:[]},{isDocumented:!0,arity:2,name:"trunc",qname:"math:trunc",signature:"($number as double, $precision as integer) as double",description:' Truncates a number down to precision.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This behaves exactly like rounddown.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Truncates a number down to precision.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The argument castable to numeric type.</div>'},{name:"precision",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of decimal places to keep .</div>'}],returns:{type:"double",description:"The integer value."},errors:[]},{isDocumented:!0,arity:1,name:"var",qname:"math:var",signature:"($numbers as double+) as double",description:' Estimates variance based on a sample.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is sum(x - average_x)^2 / (n - 1).\n average_x is computed with AVERAGE function.\n n is the count of numbers from the sequence, excluding empty values.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Estimates variance based on a sample.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"double",description:"The variance, as numeric type"},errors:[]},{isDocumented:!0,arity:1,name:"vara",qname:"math:vara",signature:"($numbers as double+) as double",description:' Estimates variance based on a sample.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is sum(x - average_x)^2 / (n - 1).\n average_x is computed with AVERAGE function.\n n is the size of sequence, including empty values.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Estimates variance based on a sample.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"double",description:"The variance, as numeric type"},errors:[]},{isDocumented:!0,arity:1,name:"varp",qname:"math:varp",signature:"($numbers as double+) as double",description:' Calculates variance based on the entire population.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is sum(x - average_x)^2 / n.\n average_x is computed with AVERAGE function.\n n is the count of numbers from the sequence, excluding empty values.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Calculates variance based on the entire population.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"double",description:"The variance, as numeric type"},errors:[]},{isDocumented:!0,arity:1,name:"varpa",qname:"math:varpa",signature:"($numbers as double+) as double",description:' Calculates variance based on the entire population.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is sum(x - average_x)^2 / n.\n average_x is computed with AVERAGE function.\n n is the size of sequence, including empty values.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Borrowed from excel module.\n',summary:"<p> Calculates variance based on the entire population.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"double",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"double",description:"The variance, as numeric type"},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/oauth/error":{ns:"http://www.zorba-xquery.com/modules/oauth/error",description:" Module that defines the errors raised in Oauth modules.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Stephanie Russell</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/oauth/error",prefix:"oerr"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[],variables:[{name:"oerr:errNS",type:"xs:string",description:" Errors namespace URI.\n"},{name:"oerr:OC001",type:"xs:QName",description:" xs:QName with namespace URI=\"http://www.zorba-xquery.com/modules/oauth/errors\" and local name 'OC001'. This signing method is not implemented yet.\n"},{name:"oerr:OC002",type:"xs:QName",description:" xs:QName with namespace URI=\"http://www.zorba-xquery.com/modules/oauth/errors\" and local name 'OC002'. This signing method is not supported.\n"},{name:"oerr:OC003",type:"xs:QName",description:" xs:QName with namespace URI=\"http://www.zorba-xquery.com/modules/oauth/errors\" and local name 'OC003'. Http 401 error.\n"},{name:"oerr:OC004",type:"xs:QName",description:" xs:QName with namespace URI=\"http://www.zorba-xquery.com/modules/oauth/errors\" and local name 'OC004'. Http 500 error.\n"},{name:"oerr:OC005",type:"xs:QName",description:" xs:QName with namespace URI=\"http://www.zorba-xquery.com/modules/oauth/errors\" and local name 'OC004'. Http 500 error.\n"}]},"http://jsoniq.org/functions":{ns:"http://jsoniq.org/functions",description:' This module contains all of the functions defined by the JSONiq\n specification (see http://jsoniq.org/).\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The module is always imported so you do not need to import it explicitly.\n Also, you do not need to fully qualify a function to invoke it.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Markos Zaharioudakis, Matthias Brantner, Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://jsoniq.org/errors",prefix:"jerr"},{uri:"http://jsoniq.org/functions",prefix:"jn"},{uri:"http://jsoniq.org/types",prefix:"js"},{uri:"http://zorba.io/modules/schema",prefix:"schema"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"decode-from-roundtrip",qname:"jn:decode-from-roundtrip",signature:"($items as item()*) as item()* external",description:' This function decodes non-JSON types previously encoded with\n jn:encode-for-roundtrip.\n Calling this version of the function is equivalent to calling the\n 2 argument version of the function with the second argument\n   { "prefix" : "Q{http://jsoniq.org/roundtrip}" }\n',summary:"<p> This function decodes non-JSON types previously encoded with\n jn:encode-for-roundtrip.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the items to be decoded.</div>'}],returns:{type:"item()*",description:"the decoded items."},errors:[]},{isDocumented:!0,arity:2,name:"decode-from-roundtrip",qname:"jn:decode-from-roundtrip",signature:"($items as item()*, $options as object()) as item()* external",description:' This function decodes non-JSON types previously encoded with\n jn:encode-for-roundtrip.\n The $options parameter contains options for the decoding process.\n Currently the only supported option is "prefix". It specifies the prefix\n that determines if this function decodes an item.\n Example:\n   jn:decode-from-roundtrip(\n     { "nan" : { "pre-type" : "double", "pre-value" : "NaN" } },\n     { "prefix" : "pre-" }\n   )\n returns the same instance that would be constructed by\n   { "nan" : double("NaN") }\n So\n   let $decoded := jn:decode-from-roundtrip(\n           { "nan" : { "pre-type" : "double", "pre-value" : "NaN" } },\n           { "prefix" : "pre-" }\n       )\n   let $nan := $decoded("nan")\n   return\n       ($nan instance of double, $nan)\n returns\n   true NaN\n',summary:"<p> This function decodes non-JSON types previously encoded with\n jn:encode-for-roundtrip.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the items to be decoded.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the decoding options.</div>'}],returns:{type:"item()*",description:"the decoded items."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jerr:JNTY0023 if $options("prefix") is not a string</xqdoc:error>']},{isDocumented:!0,arity:1,name:"encode-for-roundtrip",qname:"jn:encode-for-roundtrip",signature:"($items as item()*) as item()* external",description:" This function recursively encodes non-JSON types in such a way that they\n can be serialized as JSON while keeping roundtrip capability.\n",summary:"<p> This function recursively encodes non-JSON types in such a way that they\n can be serialized as JSON while keeping roundtrip capability.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the items to be encoded.</div>'}],returns:{type:"item()*",description:"the encoded items."},errors:[]},{isDocumented:!0,arity:2,name:"encode-for-roundtrip",qname:"jn:encode-for-roundtrip",signature:"($items as item()*, $options as object()) as item()* external",description:' This function recursively encodes non-JSON types in such a way that they\n can be serialized as JSON while keeping roundtrip capability.\n Example:\n   jn:encode-for-roundtrip(\n     { "nan" : double("NaN") },\n     { "prefix" : "pre-" }\n   )\n returns\n   { "nan" : { "pre-type" : "double", "pre-value" : "NaN" } }\n',summary:"<p> This function recursively encodes non-JSON types in such a way that they\n can be serialized as JSON while keeping roundtrip capability.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the items to be encoded.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the encoding options.</div>'}],returns:{type:"item()*",description:"the encoded items."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jerr:JNTY0023 if $options("prefix") is not a string</xqdoc:error>']},{isDocumented:!0,arity:1,name:"flatten",qname:"jn:flatten",signature:"($items as item()*) as item()* external",description:' For each item in the given sequence, this function returns the item itself,\n if it is not an array, or a sequence of items "flattened-out" from the array.\n Flattening an array means replacing the array with its members, and recursively\n flattening any arrays in the members sequence.\n Note: The function is equivalent to\n   define function jn:flatten($args as item()*)\n   {\n     for $arg in args\n     return\n       if ($arg instance of array())\n       then\n         for $value in $arg[]\n         return\n           if ($value instance of array())\n           then jn:flatten($value[])\n           else $value\n       else\n         $arg\n   };\n',summary:'<p> For each item in the given sequence, this function returns the item itself,\n if it is not an array, or a sequence of items "flattened-out" from the array.</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items</div>'}],returns:{type:"item()*",description:"The flattened-out items of the arrays in $items."},errors:[]},{isDocumented:!0,arity:1,name:"keys",qname:"jn:keys",signature:"($o as item()*) as string* external",description:" Returns the set of keys belonging to the objects found inside a given\n sequence of items. The keys are returned in an implementation-defined\n order. Duplicate keys are eliminated.\n",summary:"<p> Returns the set of keys belonging to the objects found inside a given\n sequence of items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"o",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items. Only object items are actually processed; items of any other kind are simply skipped.</div>'}],returns:{type:"string*",description:"The distinct keys of the objects in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"members",qname:"jn:members",signature:"($a as item()*) as item()* external",description:" Returns the items belonging to the arrays found inside a given sequence\n of items. The items are returned in an implementation-defined order.\n",summary:"<p> Returns the items belonging to the arrays found inside a given sequence\n of items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"a",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items. Only array items are actually processed; items of any other kind are simply skipped.</div>'}],returns:{type:"item()*",description:"The members of the arrays in the input sequence."},errors:[]},{isDocumented:!0,arity:0,name:"null",qname:"jn:null",signature:"() as js:null external",description:" Returns the JSON null.\n",summary:"<p> Returns the JSON null.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"js:null",description:"The JSON null."},errors:[]},{isDocumented:!0,arity:1,name:"parse-json",qname:"jn:parse-json",signature:"($j as string?) as json-item()* external",description:" This function parses a given string as JSON and returns a sequence\n of Objects or Arrays.\n Please note that this function allows to parse sequences of whitespace\n separated objects and arrays.\n",summary:"<p> This function parses a given string as JSON and returns a sequence\n of Objects or Arrays.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"j",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A string containing a valid JSON text.</div>'}],returns:{type:"json-item()*",description:"A sequence of JSON Object or Array item."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jerr:JNDY0021 if the given string is not valid JSON.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"parse-json",qname:"jn:parse-json",signature:"($j as string?, $o as object()) as json-item()* external",description:" This function parses a given string as JSON and returns a sequence\n of Objects or Arrays.\n",summary:"<p> This function parses a given string as JSON and returns a sequence\n of Objects or Arrays.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"j",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A string containing a valid JSON text.</div>'},{name:"o",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A JSON object defining options to configure the parser. Allowed options are <ul> <li>jsoniq-multiple-top-level-items: allow parsing of sequences of JSON Objects and Arrays (boolean; default: true)</li> <li>jsoniq-strip-top-level-array: if the top-level JSON item is an array, strip it and return its elements as multiple top-level items (boolean; default: false)</li> </ul></div>'}],returns:{type:"json-item()*",description:"a sequence of JSON Object or Array item."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jerr:JNDY0021 if the given string is not valid JSON or if jsoniq-multiple-top-level-items is false and there is additional content after the first JSON Object or Array.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">jerr:JNTY0020 if the value for the option jsoniq-multiple-top-level-items is not of type boolean.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"project",qname:"jn:project",signature:"($items as item()*, $keys as string*) as item()* external",description:' For each item in the given sequence, this function returns the item itself,\n if it is not an object, or its "projected" copy if it is an object. Projecting\n an object by a set of keys means creating a new object from the specified pairs\n of the source object. Specifically, for each key in $keys, if the object has a\n pair with that key, then a copy of that pair is included in the new object.\n',summary:'<p> For each item in the given sequence, this function returns the item itself,\n if it is not an object, or its "projected" copy if it is an object.</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items.</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the pairs to include from each object in $items.</div>'}],returns:{type:"item()*",description:"The projection of the original sequence."},errors:[]},{isDocumented:!0,arity:1,name:"size",qname:"jn:size",signature:"($a as array()?) as integer? external",description:" Returns the size of a JSON array, or the empty sequence if no array is given.\n The size of an Array is the number of members contained within it.\n",summary:"<p> Returns the size of a JSON array, or the empty sequence if no array is given.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"a",type:"array()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0">rray A JSON array.</div>'}],returns:{type:"integer?",description:"The number of items in $array, or the empty sequence if $array is empty."},errors:[]},{isDocumented:!0,arity:2,name:"trim",qname:"jn:trim",signature:"($items as item()*, $keys as string*) as item()* external",description:' For each item in the given sequence, this function returns the item itself,\n if it is not an object, or its "trimmed" copy, if it is an object. Trimming\n an object by a set of keys means creating a new object containing all the\n pairs of the source object except the ones whose key appears in the given\n set of keys.\n',summary:'<p> For each item in the given sequence, this function returns the item itself,\n if it is not an object, or its "trimmed" copy, if it is an object.</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items.</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the pairs to exclude from each object in $items.</div>'}],returns:{type:"item()*",description:"The trimmed version of the input sequence."},errors:[]}],variables:[]},"http://zorba.io/modules/xqdoc":{ns:"http://zorba.io/modules/xqdoc",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The goal of xqDoc is to provide a simple vendor neutral solution for\n documenting XQuery modules, as well as tools to generate a user friendly\n presentation of this documentation and cross referencing information.\n Therefore, xqDoc proposes a new commenting convention that extends the\n currently defined XQuery comment style. This convention is modeled\n after Java\'s Javadoc commenting style, and provides a simple, uniform\n way to document XQuery source code. You can find more information about\n xqDoc on the website of the <a href="http://xqdoc.org/">xqDoc project</a>.\n This library module provides XQDoc utility functions.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n Generating a user friendly presentation of the documentation is\n accomplished in the following steps:\n <ol>\n  <li>Module, variable, function, collection, and index declarations need\n      to be commented using the xqDoc commenting conventions. For example,\n      this module contains xqDoc-style comments</li>\n  <li>A xqDoc-enabled processor can parse such documentation and generate\n      a vendor neutral XML document which stores all the information about\n      the code and the comments. Such a document adheres to the xqDoc\n      Schema.</li>\n  <li>The information of an XML document generated by the second step,\n      can be transformed into arbitrary presentation formats\n      (e.g. html).</li>\n </ol>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This module implements the first and second step of this process.\n That is, Zorba can parse XQuery modules which are annotated with\n xqDoc-style documentation and generate the vendor neutral\n XML representation.\n </p>\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://xqdoc.org/" target="_blank">xqDoc specification</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.zorba-xquery.com/tutorials/xqdoc.html" target="_blank">xqDoc tutorial with Zorba</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Gabriel Petrovay</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://zorba.io/modules/fetch",prefix:"fetch"},{uri:"http://zorba.io/modules/xqdoc-options",prefix:"opt"},{uri:"http://zorba.io/modules/schema",prefix:"schema"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/modules/xqdoc",prefix:"xqd"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"xqdoc-content",qname:"xqd:xqdoc-content",signature:"($module as xs:string) as element(*)",description:" Generated the an XQDoc XML document for the module provided\n as parameter to this function.\n",summary:"<p> Generated the an XQDoc XML document for the module provided\n as parameter to this function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"module",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The module (as string) for which to generate the XQDoc documentation.</div>'}],returns:{type:"element(*)",description:'An element according to the xqdoc schema (<tt xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/xqdoc.xsd</tt>).'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr::ZXQD0002 if the xqdoc comments in the module contain invalid XML</xqdoc:error>']},{isDocumented:!0,arity:2,name:"xqdoc-content",qname:"xqd:xqdoc-content",signature:"($module as xs:string, $options as element(opt:enable)) as element(*)",description:" Generated the an XQDoc XML document for the module provided\n as parameter to this function.\n In comparison to the single parameter version, this function does not\n generate XQDoc for all language components. By default, the\n following components are deactivated: XQuery comments, import\n statements, variable declarations, function declarations, collection\n declarations,  and index declarations. The second parameter is used to\n enable the XQDoc generation of those components.\n",summary:"<p> Generated the an XQDoc XML document for the module provided\n as parameter to this function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"module",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The module (as string) for which to generate the XQDoc documentation.</div>'},{name:"options",type:"element(opt:enable)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> XQDoc generation options, e.g.: <pre> &lt;enable xmlns="http://zorba.io/modules/xqdoc-options" comments="true" functions="true" indexes="true" &gt; </pre></div>'}],returns:{type:"element(*)",description:'An element according to the xqdoc schema (<tt xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/xqdoc.xsd</tt>).'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr::ZXQD0002 if the xqdoc comments in the module contain invalid XML</xqdoc:error>']},{isDocumented:!0,arity:1,name:"xqdoc",qname:"xqd:xqdoc",signature:"($module-uri as xs:string) as element(*)",description:" Generates an XQDoc XML document for the module located\n at the URI provided as parameter to this function.\n",summary:"<p> Generates an XQDoc XML document for the module located\n at the URI provided as parameter to this function.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"module-uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL of the module for which to generate XQDoc.</div>'}],returns:{type:"element(*)",description:'An element according to the xqdoc schema (<tt xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/xqdoc.xsd</tt>).'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr::ZXQD0002 if the xqdoc comments in the module contain invalid XML</xqdoc:error>']},{isDocumented:!0,arity:2,name:"xqdoc",qname:"xqd:xqdoc",signature:"($module-uri as xs:string, $options as element(opt:enable)) as element(*)",description:" Generates an XQDoc XML document for the module located\n at the URI provided as parameter to this function.\n In comparison to the single parameter version, this function does not\n generate XQDoc for all language components. By default, the\n following components are deactivated: XQuery comments, import\n statements, variable declarations, function declarations, collection\n declarations,  and index declarations. The second parameter is used to\n enable the XQDoc generation of those components.\n",summary:"<p> Generates an XQDoc XML document for the module located\n at the URI provided as parameter to this function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"module-uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL of the module for which to generate XQDoc.</div>'},{name:"options",type:"element(opt:enable)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> XQDoc generation options, e.g.: <pre> &lt;enable xmlns="http://zorba.io/modules/xqdoc-options" comments="true" functions="true" indexes="true" /&gt; </pre></div>'}],returns:{type:"element(*)",description:'An element according to the xqdoc schema (<tt xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/xqdoc.xsd</tt>).'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr::ZXQD0002 if the xqdoc comments in the module contain invalid XML</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/data-cleaning/character-based-string-similarity":{ns:"http://zorba.io/modules/data-cleaning/character-based-string-similarity",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This library module provides character-based string similarity functions\n that view strings as sequences of characters, generally computing a similarity score\n that corresponds to the cost of transforming one string into another.\n These functions are particularly useful for matching near duplicate strings\n in the presence of typographical errors. </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The logic contained in this module is not specific to any particular XQuery implementation.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Bruno Martins and Diogo Sim\u00f5es</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/data-cleaning/character-based-string-similarity",prefix:"simc"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"edit-distance",qname:"simc:edit-distance",signature:"($s1 as xs:string, $s2 as xs:string) as xs:integer",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the edit distance between two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This distance, also refered to as the Levenshtein distance, is defined as the minimum number\n of edits needed to transform one string into the other, with the allowable edit operations\n being insertion, deletion, or substitution of a single character.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">edit-distance("FLWOR", "FLOWER")</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">2</pre></p>\n',summary:"<p>  Returns the edit distance between two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'}],returns:{type:"xs:integer",description:"The edit distance between the two strings."},errors:[]},{isDocumented:!0,arity:4,name:"jaro-winkler",qname:"simc:jaro-winkler",signature:"($s1 as xs:string, $s2 as xs:string, $prefix as xs:integer, $fact as xs:double) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Jaro-Winkler similarity coefficient between two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This similarity coefficient corresponds to an extension of the Jaro similarity coefficient that weights or\n penalizes strings based on their similarity at the beginning of the string, up to a given prefix size.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">jaro-winkler("DWAYNE", "DUANE", 4, 0.1 )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">0.8577777777777778</pre></p>\n',summary:"<p>  Returns the Jaro-Winkler similarity coefficient between two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"prefix",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of characters to consider when testing for equal prefixes in the strings.</div>'},{name:"fact",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The weighting factor to consider when the input strings have equal prefixes.</div>'}],returns:{type:"xs:double",description:"The Jaro-Winkler similarity coefficient between the two strings."},errors:[]},{isDocumented:!0,arity:2,name:"jaro",qname:"simc:jaro",signature:"($s1 as xs:string, $s2 as xs:string) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Jaro similarity coefficient between two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This similarity coefficient is based on the number of transposed characters and on a\n weighted sum of the percentage of matched characters held within the strings. The higher\n the Jaro-Winkler value is, the more similar the strings are. The coefficient is\n normalized such that 0 equates to no similarity and 1 is an exact match.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">jaro("FLWOR Found.", "FLWOR Foundation")</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">0.5853174603174603</pre></p>\n',summary:"<p>  Returns the Jaro similarity coefficient between two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'}],returns:{type:"xs:double",description:"The Jaro similarity coefficient between the two strings."},errors:[]},{isDocumented:!0,arity:4,name:"needleman-wunsch",qname:"simc:needleman-wunsch",signature:"($s1 as xs:string, $s2 as xs:string, $score as xs:integer, $penalty as xs:integer) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Needleman-Wunsch distance between two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The Needleman-Wunsch distance is similar to the basic edit distance metric, adding a\n variable cost adjustment to the cost of a gap (i.e., an insertion or deletion) in the\n distance metric.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">needleman-wunsch("KAK", "KQRK", 1, 1)</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">0</pre></p>\n',summary:"<p>  Returns the Needleman-Wunsch distance between two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"score",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The score value.</div>'},{name:"penalty",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The penalty value.</div>'}],returns:{type:"xs:double",description:"The Needleman-Wunsch distance between the two strings."},errors:[]},{isDocumented:!0,arity:4,name:"smith-waterman",qname:"simc:smith-waterman",signature:"($s1 as xs:string, $s2 as xs:string, $score as xs:integer, $penalty as xs:integer) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Smith-Waterman distance between two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">smith-waterman("ACACACTA", "AGCACACA", 2, 1)</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">12</pre></p>\n',summary:"<p>  Returns the Smith-Waterman distance between two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"score",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The score value.</div>'},{name:"penalty",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The penalty value.</div>'}],returns:{type:"xs:double",description:"The Smith-Waterman distance between the two strings."},errors:[]}],variables:[]},"http://expath.org/ns/error":{ns:"http://expath.org/ns/error",description:" This module defines all errors for the http-client module.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Markus Pilman</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://expath.org/ns/error",prefix:"err"}],functions:[],variables:[{name:"err:errNS",type:"xs:string",description:" Error namespace URI.\n"},{name:"err:HC001",type:"xs:QName",description:" An HTTP error occurred.\n"},{name:"err:HC002",type:"xs:QName",description:" Error parsing the entity content as XML or HTML.\n"},{name:"err:HC003",type:"xs:QName",description:" With a multipart response, the override-media-type must be either a multipart media type or application/octet-stream.\n"},{name:"err:HC004",type:"xs:QName",description:" The src attribute on the body element is mutually exclusive with all other attribute (except the media-type).\n"},{name:"err:HC005",type:"xs:QName",description:" The request element is not valid.\n"},{name:"err:HC006",type:"xs:QName",description:" A timeout occurred waiting for the response.\n"},{name:"err:HCV01",type:"xs:QName",description:" This error is not defined in the specification but used by the Zorba implementation.\n It gets thrown when the user gives wrong arguments which are statically correct,\n but make no sense (for example: http:send-request((), ())).\n"},{name:"err:HCV02",type:"xs:QName",description:" Zorba specific error\n This error is raised if trying to follow a redirect for a POST, PUT, or\n DELETE request\n"}]},"http://www.28msec.com/modules/s3":{ns:"http://www.28msec.com/modules/s3",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for managing S3 buckets and object.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It is not possible to access buckets whose names are not DNS-compliant. For\n instance a bucket name which contains uppercase letters or is longer than 63\n characters is not DNS-compliant. For additional details on bucket naming\n conventions refer to\n <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html">\n Bucket Restrictions and Limitations</a>.</p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0">Authentication</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For each functionality two methods are provided:\n <ul>\n   <li>one which allows to specify the credentials to use, by means of the\n   optional $credentials parameter (named). If the parameter is not specified,\n   the default credentials in the "S3" category will be used. If the parameter\n   is specified it must be either a string or an object. If it is a string it\n   will be interpreted as the name of a credentials in the "S3" category. If\n   it is an object it must have the following structure:\n   <ul>\n     <li>accessKey: the AWS access key to use (string, mandatory).</li>\n     <li>secretKey: the AWS secret key to use (string, mandatory).</li>\n     <li>useHttps: whether to use secure HTTPS connections or not.\n     (boolean, optional). The default is <code>false</code></li>\n     <li>defaultBucket: the default bucket name (string, optional).</li>\n   </ul>\n   </li>\n   <li>one which does not allow to specify which credentials to use.\n   In this case the default credentials in the "S3" category will be used.</li>\n </ul>\n </p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="determinism">Important Notice Regarding Function Determinism</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The non side-effecting functions:\n <ul>\n   <li><a href="?anchor=list-buckets-0">list-buckets#0</a></li>\n   <li><a href="?anchor=list-buckets-1">list-buckets#1</a></li>\n   <li><a href="?anchor=list-bucket-0">list-bucket#0</a></li>\n   <li><a href="?anchor=list-bucket-1">list-bucket#1</a></li>\n   <li><a href="?anchor=list-bucket-2">list-bucket#2</a></li>\n   <li><a href="?anchor=list-bucket-3">list-bucket#3</a></li>\n   <li><a href="?anchor=list-bucket-versions-0">list-bucket-versions#0</a></li>\n   <li><a href="?anchor=list-bucket-versions-1">list-bucket-versions#1</a></li>\n   <li><a href="?anchor=list-bucket-versions-2">list-bucket-versions#2</a></li>\n   <li><a href="?anchor=list-bucket-versions-3">list-bucket-versions#3</a></li>\n   <li><a href="?anchor=read-text-1">read-text#1</a></li>\n   <li><a href="?anchor=read-text-2">read-text#2</a></li>\n   <li><a href="?anchor=read-binary-1">read-binary#1</a></li>\n   <li><a href="?anchor=read-binary-2">read-binary#2</a></li>\n   <li><a href="?anchor=read-object-1">read-object#1</a></li>\n   <li><a href="?anchor=read-object-2">read-object#2</a></li>\n   <li><a href="?anchor=object-metadata-1">object-metadata#1</a></li>\n   <li><a href="?anchor=object-metadata-2">object-metadata#2</a></li>\n   <li><a href="?anchor=object-torrent-1">object-torrent#1</a></li>\n   <li><a href="?anchor=object-torrent-2">object-torrent#2</a></li>\n   <li><a href="?anchor=object-permissions-1">object-permissions#1</a></li>\n   <li><a href="?anchor=object-permissions-2">object-permissions#2</a></li>\n </ul>\n are declared deterministic, which means that their results could be cached\n when invoked multiple times with the same arguments in the same query execution.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To not use cached results you can use the following alternative functions:\n <ul>\n   <li><a href="?anchor=list-buckets-nondeterministic-0">list-buckets-nondeterministic#0</a></li>\n   <li><a href="?anchor=list-buckets-nondeterministic-1">list-buckets-nondeterministic#1</a></li>\n   <li><a href="?anchor=list-bucket-nondeterministic-0">list-bucket-nondeterministic#0</a></li>\n   <li><a href="?anchor=list-bucket-nondeterministic-1">list-bucket-nondeterministic#1</a></li>\n   <li><a href="?anchor=list-bucket-nondeterministic-2">list-bucket-nondeterministic#2</a></li>\n   <li><a href="?anchor=list-bucket-nondeterministic-3">list-bucket-nondeterministic#3</a></li>\n   <li><a href="?anchor=list-bucket-versions-nondeterministic-0">list-bucket-versions-nondeterministic#0</a></li>\n   <li><a href="?anchor=list-bucket-versions-nondeterministic-1">list-bucket-versions-nondeterministic#1</a></li>\n   <li><a href="?anchor=list-bucket-versions-nondeterministic-2">list-bucket-versions-nondeterministic#2</a></li>\n   <li><a href="?anchor=list-bucket-versions-nondeterministic-3">list-bucket-versions-nondeterministic#3</a></li>\n   <li><a href="?anchor=read-text-nondeterministic-1">read-text-nondeterministic#1</a></li>\n   <li><a href="?anchor=read-text-nondeterministic-2">read-text-nondeterministic#2</a></li>\n   <li><a href="?anchor=read-binary-nondeterministic-1">read-binary-nondeterministic#1</a></li>\n   <li><a href="?anchor=read-binary-nondeterministic-2">read-binary-nondeterministic#2</a></li>\n   <li><a href="?anchor=read-object-nondeterministic-1">read-object-nondeterministic#1</a></li>\n   <li><a href="?anchor=read-object-nondeterministic-2">read-object-nondeterministic#2</a></li>\n   <li><a href="?anchor=object-metadata-nondeterministic-1">object-metadata-nondeterministic#1</a></li>\n   <li><a href="?anchor=object-metadata-nondeterministic-2">object-metadata-nondeterministic#2</a></li>\n   <li><a href="?anchor=object-torrent-nondeterministic-1">object-torrent-nondeterministic#1</a></li>\n   <li><a href="?anchor=object-torrent-nondeterministic-2">object-torrent-nondeterministic#2</a></li>\n   <li><a href="?anchor=object-permissions-nondeterministic-1">object-permissions-nondeterministic#1</a></li>\n   <li><a href="?anchor=object-permissions-nondeterministic-2">object-permissions-nondeterministic#2</a></li>\n </ul>\n which have been declared as being non deterministic.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Alexander Kreutz</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.zorba-xquery.com/modules/cryptography/hmac",prefix:"hmac"},{uri:"http://zorba.io/modules/http-client",prefix:"http"},{uri:"http://jsoniq.org/errors",prefix:"jerr"},{uri:"http://www.28msec.com/modules/s3",prefix:"s3"},{uri:"http://s3.amazonaws.com/doc/2006-03-01/",prefix:"s3s"},{uri:"http://www.28msec.com/modules/sleep",prefix:"sleep"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"copy-object",qname:"s3:copy-object",signature:"($s3-object-source as item(), $s3-object-target as item()) as item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Copies an object already stored on s3 into a target bucket using the\n default credentials. If the target object already exists it will be overwritten.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The source object metadata is copied to the target object, unless new\n metadata is specified. In this case the target object will possess only the\n specified metadata.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Unless the permissions for the target are specified, the target object will\n have the "private" ACL, that is, the owner gets FULL_CONTROL, and no one else\n has access rights.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The source S3 object is specified through the $s3-object-source parameter.\n Either a string or a JSON object can be used. If a string is specified, it is\n interpreted as key for an object in the default bucket of the default\n credentials. If no default bucket is present in the default credentials, the\n <code>s3:BUCKET</code> error is raised. If a JSON object is used, it must have\n the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the latest version of\n   the object will be copied. If specified, only that particular version of the\n   object will be copied.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The target S3 object is specified through the $s3-object-target parameter.\n Either a string or a JSON object can be used. If a string is specified and the\n default credentials contain a default bucket, the object will be copied in\n the credentials default bucket. Otherwise, the object will be copied in the\n source object bucket. If a JSON object is used, it must have the following\n structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials contain a default bucket, the object will be\n   copied in the credentials default bucket. Otherwise, the object will be\n   copied in the source object bucket.</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).\n   If not specified, the source object metadata will be copied to the target\n   object. Otherwise the target object metadata will be the specified one.</li>\n   <li>reducedRedundancy: whether to use reduced-redundancy or not (bool,\n   optional). Default is false.</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $s3-object-source :=\n {\n   "key" : "test.xml",\n   "bucket": "28msec"\n }\n let $s3-object-target :=\n {\n   "key" : "test-copy.xml",\n   "bucket": "28msec",\n   "permisstion": $s3:ACL-GRANT-PUBLIC-READ\n   "metadata":\n   {\n     "author": "28msec"\n   }\n }\n return s3:copy-object($s3-object-source, $s3-object-target)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "sourceVersion": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo",\n   "version": "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n   "lastModified": "2009-10-28T22:32:00",\n   "eTag": "\\"9b2cf535f27731c974343645a3985328\\"",\n   "expiration": "expiry-date=\\"Fri, 21 Dec 2012 00:00:00 GMT\\", rule-id=\\"Rule for testfile.txt\\""\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>sourceVersion: the version of the copied object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When the soruce object is copied in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>version: the version of the copied object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When the soruce object is copied in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>lastModified: the last modification date of the target object. (dateTime, optional)</li>\n   <li>eTag: the entity tag is a hash of the copeid object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. The eTag returned by this method is a quoted,\n   32-digit hexadecimal string representing the MD5 digest of the object data.\n   For other objects, the eTag may or may not be an MD5 digest of the object data.\n   (string, optional).</li>\n   <li>expiration: if the object expiration is configured (see\n   <a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html">PUT Bucket lifecycle</a>),\n   this field is present. It includes the expiry-date and rule-id key value\n   pairs providing object expiration information. The value of rule-id is URL\n   encoded.(string, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Copies an object already stored on s3 into a target bucket using the\n default credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"s3-object-source",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to copy from.</div>'},{name:"s3-object-target",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object to write to.</div>'}],returns:{type:"item()*",description:"the S3 copy result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:3,name:"copy-object",qname:"s3:copy-object",signature:"($credentials as item()?, $s3-object-source as item(), $s3-object-target as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Copies an object already stored on S3 into a target bucket using the\n specified credentials. If the target object already exists it will be overwritten.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The source object metadata is copied to the target object, unless new\n metadata is specified. In this case the target object will possess only the\n specified metadata.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Unless the permissions for the target are specified, the target object will\n have the "private" ACL, that is, the owner gets FULL_CONTROL, and no one else\n has access rights.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The source S3 object is specified through the $s3-object-source parameter.\n Either a string or a JSON object can be used. If a string is specified, it is\n interpreted as key for an object in the default bucket of the specified\n credentials. If no default bucket is present in the specified credentials, the\n <code>s3:BUCKET</code> error is raised. If a JSON object is used, it must have\n the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the latest version of\n   the object will be copied. If specified, only that particular version of the\n   object will be copied.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The target S3 object is specified through the $s3-object-target parameter.\n Either a string or a JSON object can be used. If a string is specified and the\n specified credentials contain a default bucket, the object will be copied in\n the credentials default bucket. Otherwise, the object will be copied in the\n source object bucket. If a JSON object is used, it must have the following\n structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials contain a default bucket, the object will be\n   copied in the credentials default bucket. Otherwise, the object will be\n   copied in the source object bucket.</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).\n   If not specified, the source object metadata will be copied to the target\n   object. Otherwise the target object metadata will be the specified one.</li>\n   <li>reducedRedundancy: whether to use reduced-redundancy or not (bool,\n   optional). Default is false.</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $s3-object-source :=\n {\n   "key" : "test.xml",\n   "bucket": "28msec"\n }\n let $s3-object-target :=\n {\n   "key" : "test-copy.xml",\n   "bucket": "28msec",\n   "permisstion": $s3:ACL-GRANT-PUBLIC-READ\n   "metadata":\n   {\n     "author": "28msec"\n   }\n }\n return s3:copy-object("credentials", $s3-object-source, $s3-object-target)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "sourceVersion": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo",\n   "version": "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n   "lastModified": "2009-10-28T22:32:00",\n   "eTag": "\\"9b2cf535f27731c974343645a3985328\\"",\n   "expiration": "expiry-date=\\"Fri, 21 Dec 2012 00:00:00 GMT\\", rule-id=\\"Rule for testfile.txt\\""\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>sourceVersion: the version of the copied object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When the soruce object is copied in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>version: the version of the copied object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When the soruce object is copied in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>lastModified: the last modification date of the target object. (dateTime, optional)</li>\n   <li>eTag: the entity tag is a hash of the copeid object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. The eTag returned by this method is a quoted,\n   32-digit hexadecimal string representing the MD5 digest of the object data.\n   For other objects, the eTag may or may not be an MD5 digest of the object data.\n   (string, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Copies an object already stored on S3 into a target bucket using the\n specified credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object-source",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to copy from.</div>'},{name:"s3-object-target",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object to write to.</div>'}],returns:{type:"object()",description:"the S3 copy result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"create-bucket",qname:"s3:create-bucket",signature:"($bucket as string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates a bucket using the default S3 credentials. The bucket owner will\n be the account of the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The bucket is created with the S3 default bucket settings. Specifically,\n it is created in the US Standard region and the default credentials\n account becomes its owner. The bucket ACL permissions are set to "private",\n that is, the owner gets FULL_CONTROL, whereas no one else has access rights.\n The bucket name must comply with the following rules:\n <ul>\n   <li>bucket names must be no more than 255 characters long.</li>\n   <li>bucket names must be a combination of uppercase letters, lowercase letters,\n   numbers, periods (.), dashes (-) and underscores (_).</li>\n </ul>\n For more details, refer to the\n <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html">\n Amazon S3 Bucket Restrictions</a> page.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the specified bucket already exists in the US Standard region and has\n the same owner, its permissions settings are reset and its contents are\n preserved. Otherwise, if the specified bucket already exists an s3:REQUEST\n error is raised.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:create-bucket("28msec");\n </pre>\n </p>\n',summary:"<p>  Creates a bucket using the default S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket name.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:2,name:"create-bucket",qname:"s3:create-bucket",signature:"($credentials as item()?, $bucket as string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates a bucket using the specified S3 credentials. The bucket owner will\n be the account of the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The bucket is created with the S3 default bucket settings. Specifically,\n it is created in the US Standard region and the specified credentials\n account becomes its owner. The bucket ACL permissions are set to "private",\n that is, the owner gets FULL_CONTROL, whereas no one else has access rights.\n The bucket name must comply with the following rules:\n <ul>\n   <li>bucket names must be no more than 255 characters long.</li>\n   <li>bucket names must be a combination of uppercase letters, lowercase letters,\n   numbers, periods (.), dashes (-) and underscores (_).</li>\n </ul>\n For more details, refer to the\n <a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html">\n Amazon S3 Bucket Restrictions</a> page.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the specified bucket already exists in the US Standard region and has\n the same owner, its permissions settings are reset and its contents are\n preserved. Otherwise, if the specified bucket already exists an s3:REQUEST\n error is raised.</p>\n',summary:"<p>  Creates a bucket using the specified S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"bucket",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket name.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:1,name:"delete-bucket",qname:"s3:delete-bucket",signature:"($bucket as string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes a bucket using the default S3 credentials. The bucket must be owned\n by the account of the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This operation will fail if the deleted bucket is not empty. All objects,\n object versions, and delete markers have to be deleted beforehand using this\n function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:delete-bucket("28msec");\n </pre>\n </p>\n',summary:"<p>  Deletes a bucket using the default S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket name.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete-bucket",qname:"s3:delete-bucket",signature:"($credentials as item()?, $bucket as string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes a bucket using the specified S3 credentials. The bucket must be owned\n by the account of the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This operation will fail if the deleted bucket is not empty. All objects,\n object versions, and delete markers have to be deleted beforehand using this\n function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:delete-bucket("credentials", "28msec");\n </pre>\n </p>\n',summary:"<p>  Deletes a bucket using the specified S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"bucket",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket name.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:1,name:"delete-object",qname:"s3:delete-object",signature:"($s3-object as item()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes an object or a specific object version from a bucket using the\n default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If not specified, the\n   null version of the object is removed, if there is one. To remove a specific\n   version, this field must be specified.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the bucket is versioned a delete marker is inserted for the object. If\n mfa-deletion is enabled you will not be able to delete an object through\n this method. If the specified bucket exists, and the specified object does not\n exist no errors will be raised.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:delete-object(\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n });\n </pre>\n </p>\n',summary:"<p>  Deletes an object or a specific object version from a bucket using the\n default S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to delete.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete-object",qname:"s3:delete-object",signature:"($credentials as item()?, $s3-object as item()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes an object or a specific object version from a bucket using the\n specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If not specified, the\n   null version of the object is removed, if there is one. To remove a specific\n   version, this field must be specified.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the bucket is versioned a delete marker is inserted for the object. If\n mfa-deletion is enabled you will not be able to delete an object through\n this method. If the specified bucket exists, and the specified object does not\n exist no errors will be raised.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:delete-object("credentials",\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n });\n </pre>\n </p>\n',summary:"<p>  Deletes an object or a specific object version from a bucket using the\n specified S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to delete.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:0,name:"list-bucket-nondeterministic",qname:"s3:list-bucket-nondeterministic",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects in the default bucket of the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-bucket-0">list-bucket#0</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the objects in the default bucket of the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"object()",description:"the list of objects in the default bucket of the default S3 credentials"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no default bucket is present in the default S3 credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"list-bucket-nondeterministic",qname:"s3:list-bucket-nondeterministic",signature:"($bucket as string?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects in a bucket using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-bucket-1">list-bucket#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the objects in a bucket using the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the default S3 credentials will be listed.</div>'}],returns:{type:"object()",description:"the list of the objects in the specified bucket."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"list-bucket-nondeterministic",qname:"s3:list-bucket-nondeterministic",signature:"($bucket as string?, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects in a bucket using the default S3 credentials.\n This method allows the specification of additional listing options.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-bucket-2">list-bucket#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the objects in a bucket using the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the default S3 credentials will be listed.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The listing options.</div>'}],returns:{type:"object()",description:"the list of the object in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the default credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:3,name:"list-bucket-nondeterministic",qname:"s3:list-bucket-nondeterministic",signature:"($credentials as item()?, $bucket as string?, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects in a bucket using the specified credentials.\n This method allows the specification of additional listing options.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-bucket-3">list-bucket#3</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the objects in a bucket using the specified credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the specified credentials will be listed.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The listing options.</div>'}],returns:{type:"object()",description:"the list of the object in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:0,name:"list-bucket-versions-nondeterministic",qname:"s3:list-bucket-versions-nondeterministic",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects versions in the default bucket of the default S3\n credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-bucket-versions-0">list-bucket-versions#0</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the objects versions in the default bucket of the default S3\n credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"object()",description:"the list of the object versions in the default bucket of the default S3 credentials"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no default bucket is present in the default S3 credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"list-bucket-versions-nondeterministic",qname:"s3:list-bucket-versions-nondeterministic",signature:"($bucket as string?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects versions in a bucket using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-bucket-versions-1">list-bucket-versions#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the objects versions in a bucket using the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the default credentials will be listed.</div>'}],returns:{type:"object()",description:"the list of the object versions in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"list-bucket-versions-nondeterministic",qname:"s3:list-bucket-versions-nondeterministic",signature:"($bucket as string?, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects versions in a bucket using the default S3 credentials.\n This method allows the specification of additional listing options.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-bucket-versions-2">list-bucket-versions#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the objects versions in a bucket using the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the default credentials will be listed.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The listing options.</div>'}],returns:{type:"object()",description:"the list of the object versions in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the default credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:3,name:"list-bucket-versions-nondeterministic",qname:"s3:list-bucket-versions-nondeterministic",signature:"($credentials as item()?, $bucket as string?, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects versions in a bucket using the specified credentials.\n This method allows the specification of additional listing options.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-bucket-versions-3">list-bucket-versions#3</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the objects versions in a bucket using the specified credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the specified credentials will be listed.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The listing options.</div>'}],returns:{type:"object()",description:"the list of the object in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:0,name:"list-bucket-versions",qname:"s3:list-bucket-versions",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects versions in the default bucket of the default S3\n credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:list-bucket-versions()\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "name": "bucket",\n   "prefix": "",\n   "keyMarker" : "image.jpg",\n   "versionIdMarker" : "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n   "nextKeyMarker": "marker",\n   "nextVersionIdMarker": "UIORUnfndfhnw89493jJFJ",\n   "maxKeys": 1,\n   "delimiter": "/",\n   "isTruncated": true,\n   "revisions":\n   [\n     {\n       "kind": "Version",\n       "key": "image.jpg",\n       "versionId": "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n       "isLatest": false,\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "eTag": "\\"fba9dede5f27731c9771645a39863328\\"",\n       "size": 434234,\n       "storageClass": "STANDARD",\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     },\n     {\n       "kind": "DeleteMarker",\n       "key": "image.jpg",\n       "versionId": "03jpff543dhffds434rfdsFDN943fdsFkdmqnh892",\n       "isLatest": true,\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     }\n   ],\n   "commonPrefixes": ["photos/"]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>name: the bucket name (string, mandatory).</li>\n   <li>prefix: the used prefix (string, mandatory).</li>\n   <li>keyMarker: indicates from which key in the listing begins\n   (string, mandatory).</li>\n   <li>versionMarker: indicates from which version  the listing begins\n   (string, optional).</li>\n   <li>nextKeyMarker: when the number of responses exceeds the value of maxKeys,\n   nextKeyMarker specifies the first key not returned that satisfies the search\n   criteria. Use this value for the keyMarker request parameter in a subsequent\n   request. (string, optional)</li>\n   <li>nextVersionMarker: when the number of responses exceeds the value of maxKeys,\n   nextVersionIdMarker specifies the first object version not returned that\n   satisfies the search criteria. Use this value for the versionMarker request\n   parameter in a subsequent request. (string, optional)</li>\n   <li>maxKeys: the maximum number of keys returned in the response body\n   (integer, mandatory).</li>\n   <li>delimiter: the used delimiter (string, optional).</li>\n   <li>isTruncated: whether or not all of the results were returned. All of the\n   results may not be returned if the number of results exceeds that specified\n   by the maxKeys request parameter (boolean, mandatory).</li>\n   <li>revisions: an array of objects listing the bucket object versions\n   (array, mandatory). The fields of each contained object have the following\n   meaning:\n   <ul>\n     <li>kind: the revision kind. One of "Version" or "DeleteMarker" (string,\n     mandatory).</li>\n     <li>key: the object key (string, mandatory).</li>\n     <li>versionId: the object version id (string, mandatory).</li>\n     <li>lastModified: the object last modification date (dateTime, mandatory).</li>\n     <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n     changes to the contents of an object, not its metadata. The eTag is determined\n     when an object is created. For objects created by the PUT Object operation\n     and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n     string representing the MD5 digest of the object data. For other objects,\n     the eTag may or may not be an MD5 digest of the object data. If the eTag is\n     not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n     characters and/or will consist of less than 32 or more than 32 hexadecimal\n     digits.(string, mandatory for "Version" objects, not present for\n     "DeleteMarker" objects).</li>\n     <li>size: the object size in bytes (integer, mandatory for "Version" objects,\n     not present for "DeleteMarker" objects).</li>\n     <li>storageClass: the object storage class. One of "STANDARD",\n     "REDUCED_REDUNDANCY" or "GLACIER" (string, mandatory for "Version" objects,\n     not present for "DeleteMarker" objects).</li>\n     <li>owner: an object which specifies the owner of the object (object,\n     optional). It has the following fields:\n     <ul>\n       <li>id: the user identifier of the object owner (string, mandatory).</li>\n       <li>displayName: the screen name of the object owner (string, mandatory).</li>\n     </ul>\n     </li>\n   </ul>\n   </li>\n   <li>commonPrefixes: an array of strings which contains the list of the common\n   prefixes. It can be present only when the delimiter request parameter is\n   specified (array, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Lists the objects versions in the default bucket of the default S3\n credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"the list of the object versions in the default bucket of the default S3 credentials"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no default bucket is present in the default S3 credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"list-bucket-versions",qname:"s3:list-bucket-versions",signature:"($bucket as string?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects versions in a bucket using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:list-bucket-versions("28msec")\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "name": "bucket",\n   "prefix": "",\n   "keyMarker" : "image.jpg",\n   "versionIdMarker" : "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n   "nextKeyMarker": "marker",\n   "nextVersionIdMarker": "UIORUnfndfhnw89493jJFJ",\n   "maxKeys": 1,\n   "delimiter": "/",\n   "isTruncated": true,\n   "revisions":\n   [\n     {\n       "kind": "Version",\n       "key": "image.jpg",\n       "versionId": "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n       "isLatest": false,\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "eTag": "\\"fba9dede5f27731c9771645a39863328\\"",\n       "size": 434234,\n       "storageClass": "STANDARD",\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     },\n     {\n       "kind": "DeleteMarker",\n       "key": "image.jpg",\n       "versionId": "03jpff543dhffds434rfdsFDN943fdsFkdmqnh892",\n       "isLatest": true,\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     }\n   ],\n   "commonPrefixes": ["photos/"]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>name: the bucket name (string, mandatory).</li>\n   <li>prefix: the used prefix (string, mandatory).</li>\n   <li>keyMarker: indicates from which key in the listing begins\n   (string, mandatory).</li>\n   <li>versionMarker: indicates from which version  the listing begins\n   (string, optional).</li>\n   <li>nextKeyMarker: when the number of responses exceeds the value of maxKeys,\n   nextKeyMarker specifies the first key not returned that satisfies the search\n   criteria. Use this value for the keyMarker request parameter in a subsequent\n   request. (string, optional)</li>\n   <li>nextVersionMarker: when the number of responses exceeds the value of maxKeys,\n   nextVersionIdMarker specifies the first object version not returned that\n   satisfies the search criteria. Use this value for the versionMarker request\n   parameter in a subsequent request. (string, optional)</li>\n   <li>maxKeys: the maximum number of keys returned in the response body\n   (integer, mandatory).</li>\n   <li>delimiter: the used delimiter (string, optional).</li>\n   <li>isTruncated: whether or not all of the results were returned. All of the\n   results may not be returned if the number of results exceeds that specified\n   by the maxKeys request parameter (boolean, mandatory).</li>\n   <li>revisions: an array of objects listing the bucket object versions\n   (array, mandatory). The fields of each contained object have the following\n   meaning:\n   <ul>\n     <li>kind: the revision kind. One of "Version" or "DeleteMarker" (string,\n     mandatory).</li>\n     <li>key: the object key (string, mandatory).</li>\n     <li>versionId: the object version id (string, mandatory).</li>\n     <li>lastModified: the object last modification date (dateTime, mandatory).</li>\n     <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n     changes to the contents of an object, not its metadata. The eTag is determined\n     when an object is created. For objects created by the PUT Object operation\n     and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n     string representing the MD5 digest of the object data. For other objects,\n     the eTag may or may not be an MD5 digest of the object data. If the eTag is\n     not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n     characters and/or will consist of less than 32 or more than 32 hexadecimal\n     digits.(string, mandatory for "Version" objects, not present for\n     "DeleteMarker" objects).</li>\n     <li>size: the object size in bytes (integer, mandatory for "Version" objects,\n     not present for "DeleteMarker" objects).</li>\n     <li>storageClass: the object storage class. One of "STANDARD",\n     "REDUCED_REDUNDANCY" or "GLACIER" (string, mandatory for "Version" objects,\n     not present for "DeleteMarker" objects).</li>\n     <li>owner: an object which specifies the owner of the object (object,\n     optional). It has the following fields:\n     <ul>\n       <li>id: the user identifier of the object owner (string, mandatory).</li>\n       <li>displayName: the screen name of the object owner (string, mandatory).</li>\n     </ul>\n     </li>\n   </ul>\n   </li>\n   <li>commonPrefixes: an array of strings which contains the list of the common\n   prefixes. It can be present only when the delimiter request parameter is\n   specified (array, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Lists the objects versions in a bucket using the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the default credentials will be listed.</div>'}],returns:{type:"object()",description:"the list of the object versions in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"list-bucket-versions",qname:"s3:list-bucket-versions",signature:"($bucket as string?, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects versions in a bucket using the default S3 credentials.\n This method allows the specification of additional listing options.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $options :=\n {\n   "delimiter": "/",\n   "maxKeys": 2,\n   "keyMarker": "image.jpg",\n   "versionIdMarker" : "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893"\n }\n return s3:list-bucket-versions("28msec", $options)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The options object must have the following structure:\n <ul>\n   <li>delimiter: the delimiter marks where the listed results stop. For example,\n       a delimiter / lists all objects starting with $prefix plus arbitrary\n       characters but not / (string, optional). Default is the empty string,\n       that is, all objects are listed.</li>\n   <li>keyMarker: specifies a key as starting point; following keys (lexicographically\n       greater than the marker) in alphabetical order are listed (string, optional).\n       Default is the empty string, that is, all objects are listed.</li>\n   <li>versionMarker: specifies the object version you want starting from;\n       following revisions (newer than the marker) are listed (string, optional).\n       By default all versions are listed. Empty string is not allowed.</li>\n   <li>maxKeys: the maximum number of keys returned. If more keys than maxKeys\n       can be fetched, the result contains <IsTruncated>true</IsTruncated>\n       (integer, optional). Default is 1000.</li>\n   <li>prefix: only keys starting with the prefix are returned (string, optional).\n       Default is the empty string, that is, all objects are listed.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "name": "bucket",\n   "prefix": "",\n   "keyMarker" : "image.jpg",\n   "versionIdMarker" : "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n   "nextKeyMarker": "marker",\n   "nextVersionIdMarker": "UIORUnfndfhnw89493jJFJ",\n   "maxKeys": 1,\n   "delimiter": "/",\n   "isTruncated": true,\n   "revisions":\n   [\n     {\n       "kind": "Version",\n       "key": "image.jpg",\n       "versionId": "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n       "isLatest": false,\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "eTag": "\\"fba9dede5f27731c9771645a39863328\\"",\n       "size": 434234,\n       "storageClass": "STANDARD",\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     },\n     {\n       "kind": "DeleteMarker",\n       "key": "image.jpg",\n       "versionId": "03jpff543dhffds434rfdsFDN943fdsFkdmqnh892",\n       "isLatest": true,\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     }\n   ],\n   "commonPrefixes": ["photos/"]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>name: the bucket name (string, mandatory).</li>\n   <li>prefix: the used prefix (string, mandatory).</li>\n   <li>keyMarker: indicates from which key in the listing begins\n   (string, mandatory).</li>\n   <li>versionMarker: indicates from which version  the listing begins\n   (string, optional).</li>\n   <li>nextKeyMarker: when the number of responses exceeds the value of maxKeys,\n   nextKeyMarker specifies the first key not returned that satisfies the search\n   criteria. Use this value for the keyMarker request parameter in a subsequent\n   request. (string, optional)</li>\n   <li>nextVersionMarker: when the number of responses exceeds the value of maxKeys,\n   nextVersionIdMarker specifies the first object version not returned that\n   satisfies the search criteria. Use this value for the versionMarker request\n   parameter in a subsequent request. (string, optional)</li>\n   <li>maxKeys: the maximum number of keys returned in the response body\n   (integer, mandatory).</li>\n   <li>delimiter: the used delimiter (string, optional).</li>\n   <li>isTruncated: whether or not all of the results were returned. All of the\n   results may not be returned if the number of results exceeds that specified\n   by the maxKeys request parameter (boolean, mandatory).</li>\n   <li>revisions: an array of objects listing the bucket object versions\n   (array, mandatory). The fields of each contained object have the following\n   meaning:\n   <ul>\n     <li>kind: the revision kind. One of "Version" or "DeleteMarker" (string,\n     mandatory).</li>\n     <li>key: the object key (string, mandatory).</li>\n     <li>versionId: the object version id (string, mandatory).</li>\n     <li>lastModified: the object last modification date (dateTime, mandatory).</li>\n     <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n     changes to the contents of an object, not its metadata. The eTag is determined\n     when an object is created. For objects created by the PUT Object operation\n     and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n     string representing the MD5 digest of the object data. For other objects,\n     the eTag may or may not be an MD5 digest of the object data. If the eTag is\n     not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n     characters and/or will consist of less than 32 or more than 32 hexadecimal\n     digits.(string, mandatory for "Version" objects, not present for\n     "DeleteMarker" objects).</li>\n     <li>size: the object size in bytes (integer, mandatory for "Version" objects,\n     not present for "DeleteMarker" objects).</li>\n     <li>storageClass: the object storage class. One of "STANDARD",\n     "REDUCED_REDUNDANCY" or "GLACIER" (string, mandatory for "Version" objects,\n     not present for "DeleteMarker" objects).</li>\n     <li>owner: an object which specifies the owner of the object (object,\n     optional). It has the following fields:\n     <ul>\n       <li>id: the user identifier of the object owner (string, mandatory).</li>\n       <li>displayName: the screen name of the object owner (string, mandatory).</li>\n     </ul>\n     </li>\n   </ul>\n   </li>\n   <li>commonPrefixes: an array of strings which contains the list of the common\n   prefixes. It can be present only when the delimiter request parameter is\n   specified (array, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Lists the objects versions in a bucket using the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the default credentials will be listed.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The listing options.</div>'}],returns:{type:"object()",description:"the list of the object versions in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the default credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:3,name:"list-bucket-versions",qname:"s3:list-bucket-versions",signature:"($credentials as item()?, $bucket as string?, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects versions in a bucket using the specified credentials.\n This method allows the specification of additional listing options.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $options :=\n {\n   "delimiter": "/",\n   "maxKeys": 2,\n   "keyMarker": "image.jpg",\n   "versionIdMarker": "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893"\n }\n return s3:list-bucket-versions("credentials", "28msec", $options)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The options object must have the following structure:\n <ul>\n   <li>delimiter: the delimiter marks where the listed results stop. For example,\n       a delimiter / lists all objects starting with $prefix plus arbitrary\n       characters but not / (string, optional). Default is the empty string,\n       that is, all objects are listed.</li>\n   <li>keyMarker: specifies a key as starting point; following keys (lexicographically\n       greater than the marker) in alphabetical order are listed (string, optional).\n       Default is the empty string, that is, all objects are listed.</li>\n   <li>versionMarker: specifies the object version you want starting from;\n       following revisions (newer than the marker) are listed (string, optional).\n       By default all versions are listed. Empty string is not allowed.</li>\n   <li>maxKeys: the maximum number of keys returned. If more keys than maxKeys\n       can be fetched, the result contains <IsTruncated>true</IsTruncated>\n       (integer, optional). Default is 1000.</li>\n   <li>prefix: only keys starting with the prefix are returned (string, optional).\n       Default is the empty string, that is, all objects are listed.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "name": "bucket",\n   "prefix": "",\n   "keyMarker" : "image.jpg",\n   "VersionIdMarker" : "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n   "nextKeyMarker": "marker",\n   "nextVersionIdMarker": "UIORUnfndfhnw89493jJFJ",\n   "maxKeys": 1,\n   "delimiter": "/",\n   "isTruncated": true,\n   "revisions":\n   [\n     {\n       "kind": "Version",\n       "key": "image.jpg",\n       "versionId": "QUpfdndhfd8438MNFDN93jdnJFkdmqnh893",\n       "isLatest": false,\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "eTag": "\\"fba9dede5f27731c9771645a39863328\\"",\n       "size": 434234,\n       "storageClass": "STANDARD",\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     },\n     {\n       "kind": "DeleteMarker",\n       "key": "image.jpg",\n       "versionId": "03jpff543dhffds434rfdsFDN943fdsFkdmqnh892",\n       "isLatest": true,\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     }\n   ],\n   "commonPrefixes": ["photos/"]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>name: the bucket name (string, mandatory).</li>\n   <li>prefix: the used prefix (string, mandatory).</li>\n   <li>keyMarker: indicates from which key in the listing begins\n   (string, mandatory).</li>\n   <li>versionMarker: indicates from which version  the listing begins\n   (string, optional).</li>\n   <li>nextKeyMarker: when the number of responses exceeds the value of maxKeys,\n   nextKeyMarker specifies the first key not returned that satisfies the search\n   criteria. Use this value for the keyMarker request parameter in a subsequent\n   request. (string, optional)</li>\n   <li>nextVersionMarker: when the number of responses exceeds the value of maxKeys,\n   nextVersionIdMarker specifies the first object version not returned that\n   satisfies the search criteria. Use this value for the versionMarker request\n   parameter in a subsequent request. (string, optional)</li>\n   <li>maxKeys: the maximum number of keys returned in the response body\n   (integer, mandatory).</li>\n   <li>delimiter: the used delimiter (string, optional).</li>\n   <li>isTruncated: whether or not all of the results were returned. All of the\n   results may not be returned if the number of results exceeds that specified\n   by the maxKeys request parameter (boolean, mandatory).</li>\n   <li>revisions: an array of objects listing the bucket object versions\n   (array, mandatory). The fields of each contained object have the following\n   meaning:\n   <ul>\n     <li>kind: the revision kind. One of "Version" or "DeleteMarker" (string,\n     mandatory).</li>\n     <li>key: the object key (string, mandatory).</li>\n     <li>versionId: the object version id (string, mandatory).</li>\n     <li>lastModified: the object last modification date (dateTime, mandatory).</li>\n     <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n     changes to the contents of an object, not its metadata. The eTag is determined\n     when an object is created. For objects created by the PUT Object operation\n     and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n     string representing the MD5 digest of the object data. For other objects,\n     the eTag may or may not be an MD5 digest of the object data. If the eTag is\n     not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n     characters and/or will consist of less than 32 or more than 32 hexadecimal\n     digits.(string, mandatory for "Version" objects, not present for\n     "DeleteMarker" objects).</li>\n     <li>size: the object size in bytes (integer, mandatory for "Version" objects,\n     not present for "DeleteMarker" objects).</li>\n     <li>storageClass: the object storage class. One of "STANDARD",\n     "REDUCED_REDUNDANCY" or "GLACIER" (string, mandatory for "Version" objects,\n     not present for "DeleteMarker" objects).</li>\n     <li>owner: an object which specifies the owner of the object (object,\n     optional). It has the following fields:\n     <ul>\n       <li>id: the user identifier of the object owner (string, mandatory).</li>\n       <li>displayName: the screen name of the object owner (string, mandatory).</li>\n     </ul>\n     </li>\n   </ul>\n   </li>\n   <li>commonPrefixes: an array of strings which contains the list of the common\n   prefixes. It can be present only when the delimiter request parameter is\n   specified (array, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Lists the objects versions in a bucket using the specified credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the specified credentials will be listed.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The listing options.</div>'}],returns:{type:"object()",description:"the list of the object in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:0,name:"list-bucket",qname:"s3:list-bucket",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects in the default bucket of the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:list-bucket("28msec")\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "name": "28msec",\n   "prefix": "",\n   "marker" : "",\n   "nextMarker": "marker",\n   "maxKeys": 1,\n   "delimiter": "",\n   "isTruncated": true,\n   "contents":\n   [\n     {\n       "key": "image.jpg",\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "eTag": "\\"fba9dede5f27731c9771645a39863328\\"",\n       "size": 434234,\n       "storageClass": "STANDARD"\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     }\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>name: the bucket name (string, mandatory).</li>\n   <li>prefix: the used prefix (string, mandatory).</li>\n   <li>marker: indicates where in the bucket listing begins (string, mandatory).</li>\n   <li>nextMarker: when the response is truncated, you can use the key name\n   in this field as marker in the subsequent request to get next set of objects.\n   Amazon S3 lists objects in alphabetical order. This field is returned only\n   if you have specified the delimiter request parameter. If the response does\n   not include the nextMaker field and it is truncated, you can use the value\n   of the last Key in the response as the marker in the subsequent request to\n   get the next set of object keys. (string, optional)</li>\n   <li>maxKeys: the maximum number of keys returned in the response body\n   (integer, mandatory).</li>\n   <li>delimiter: the used delimiter (string, optional).</li>\n   <li>isTruncated: whether or not all of the results were returned. All of the\n   results may not be returned if the number of results exceeds that specified\n   by the maxKeys request parameter (boolean, mandatory).</li>\n   <li>contents: an array of objects listing the bucket content  (array, mandatory).\n   The fields of each contained object have the following meaning:\n   <ul>\n     <li>key: the object key (string, mandatory).</li>\n     <li>lastModified: the object last modification date (dateTime, mandatory).</li>\n     <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n     changes to the contents of an object, not its metadata. The eTag is determined\n     when an object is created. For objects created by the PUT Object operation\n     and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n     string representing the MD5 digest of the object data. For other objects,\n     the eTag may or may not be an MD5 digest of the object data. If the eTag is\n     not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n     characters and/or will consist of less than 32 or more than 32 hexadecimal\n     digits.(string, mandatory).</li>\n     <li>storageClass: the object storage class. One of "STANDARD",\n     "REDUCED_REDUNDANCY" or "GLACIER" (string, mandatory).</li>\n     <li>owner: an object which specifies the owner of the object (object,\n     optional). It has the following fields:\n     <ul>\n       <li>id: the user identifier of the object owner (string, mandatory).</li>\n       <li>displayName: the screen name of the object owner (string, mandatory).</li>\n     </ul>\n     </li>\n   </ul>\n   </li>\n </ul>\n </p>\n',summary:"<p>  Lists the objects in the default bucket of the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"the list of objects in the default bucket of the default S3 credentials"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no default bucket is present in the default S3 credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"list-bucket",qname:"s3:list-bucket",signature:"($bucket as string?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects in a bucket using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:list-bucket("28msec")\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "name": "28msec",\n   "prefix": "",\n   "marker" : "",\n   "nextMarker": "marker",\n   "maxKeys": 1,\n   "delimiter": "",\n   "isTruncated": true,\n   "contents":\n   [\n     {\n       "key": "image.jpg",\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "eTag": "\\"fba9dede5f27731c9771645a39863328\\"",\n       "size": 434234,\n       "storageClass": "STANDARD"\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     }\n   ]\n }\n </pre>\n The meanings of the fields in the return object are the following:\n <ul>\n   <li>name: the bucket name (string, mandatory).</li>\n   <li>prefix: the used prefix (string, mandatory).</li>\n   <li>marker: indicates where in the bucket listing begins (string, mandatory).</li>\n   <li>nextMarker: when the response is truncated, you can use the key name\n   in this field as marker in the subsequent request to get next set of objects.\n   Amazon S3 lists objects in alphabetical order. This field is returned only\n   if you have specified the delimiter request parameter. If the response does\n   not include the nextMaker field and it is truncated, you can use the value\n   of the last Key in the response as the marker in the subsequent request to\n   get the next set of object keys. (string, optional)</li>\n   <li>maxKeys: the maximum number of keys returned in the response body\n   (integer, mandatory).</li>\n   <li>delimiter: the used delimiter (string, optional).</li>\n   <li>isTruncated: whether or not all of the results were returned. All of the\n   results may not be returned if the number of results exceeds that specified\n   by the maxKeys request parameter (boolean, mandatory).</li>\n   <li>contents: an array of objects listing the bucket content  (array, mandatory).\n   The fields of each contained object have the following meaning:\n   <ul>\n     <li>key: the object key (string, mandatory).</li>\n     <li>lastModified: the object last modification date (dateTime, mandatory).</li>\n     <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n     changes to the contents of an object, not its metadata. The eTag is determined\n     when an object is created. For objects created by the PUT Object operation\n     and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n     string representing the MD5 digest of the object data. For other objects,\n     the eTag may or may not be an MD5 digest of the object data. If the eTag is\n     not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n     characters and/or will consist of less than 32 or more than 32 hexadecimal\n     digits.(string, mandatory).</li>\n     <li>storageClass: the object storage class. One of "STANDARD",\n     "REDUCED_REDUNDANCY" or "GLACIER" (string, mandatory).</li>\n     <li>owner: an object which specifies the owner of the object (object,\n     optional). It has the following fields:\n     <ul>\n       <li>id: the user identifier of the object owner (string, mandatory).</li>\n       <li>displayName: the screen name of the object owner (string, mandatory).</li>\n     </ul>\n     </li>\n   </ul>\n   </li>\n </ul>\n </p>\n',summary:"<p>  Lists the objects in a bucket using the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the default S3 credentials will be listed.</div>'}],returns:{type:"object()",description:"the list of the objects in the specified bucket."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"list-bucket",qname:"s3:list-bucket",signature:"($bucket as string?, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects in a bucket using the default S3 credentials.\n This method allows the specification of additional listing options.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $options :=\n {\n   "delimiter": "/",\n   "marker": "",\n   "maxKeys": 1,\n   "prefix": ""\n }\n return s3:list-bucket("credentials", "28msec", $options)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The options object must have the following structure:\n <ul>\n   <li>delimiter: the delimiter marks where the listed results stop. For example,\n       a delimiter / lists all objects starting with $prefix plus arbitrary\n       characters but not / (string, optional). Default is the empty string,\n       that is, all objects are listed.</li>\n   <li>marker: specifies a key as starting point; following keys (lexicographically\n       greater than the marker) in alphabetical order are listed (string, optional).\n       Default is the empty string, that is, all objects are listed.</li>\n   <li>maxKeys: the maximum number of keys returned. If more keys than maxKeys\n       can be fetched, the result contains <IsTruncated>true</IsTruncated>\n       (integer, optional). Default is 1000.</li>\n   <li>prefix: only keys starting with the prefix are returned (string, optional).\n       Default is the empty string, that is, all objects are listed.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "name": "bucket",\n   "prefix": "",\n   "marker" : "",\n   "nextMarker": "marker",\n   "maxKeys": 1,\n   "delimiter": "/",\n   "isTruncated": true,\n   "contents":\n   [\n     {\n       "key": "image.jpg",\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "eTag": "\\"fba9dede5f27731c9771645a39863328\\"",\n       "size": 434234,\n       "storageClass": "STANDARD"\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     }\n   ],\n   "commonPrefixes": ["photos/"]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>name: the bucket name (string, mandatory).</li>\n   <li>prefix: the used prefix (string, mandatory).</li>\n   <li>marker: indicates where in the bucket listing begins (string, mandatory).</li>\n   <li>nextMarker: when the response is truncated, you can use the key name\n   in this field as marker in the subsequent request to get next set of objects.\n   Amazon S3 lists objects in alphabetical order. This field is returned only\n   if you have specified the delimiter request parameter. If the response does\n   not include the nextMaker field and it is truncated, you can use the value\n   of the last Key in the response as the marker in the subsequent request to\n   get the next set of object keys. (string, optional)</li>\n   <li>maxKeys: the maximum number of keys returned in the response body\n   (integer, mandatory).</li>\n   <li>delimiter: the used delimiter (string, optional).</li>\n   <li>isTruncated: whether or not all of the results were returned. All of the\n   results may not be returned if the number of results exceeds that specified\n   by the maxKeys request parameter (boolean, mandatory).</li>\n   <li>contents: an array of objects listing the bucket content  (array, mandatory).\n   The fields of each contained object have the following meaning:\n   <ul>\n     <li>key: the object key (string, mandatory).</li>\n     <li>lastModified: the object last modification date (dateTime, mandatory).</li>\n     <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n     changes to the contents of an object, not its metadata. The eTag is determined\n     when an object is created. For objects created by the PUT Object operation\n     and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n     string representing the MD5 digest of the object data. For other objects,\n     the eTag may or may not be an MD5 digest of the object data. If the eTag is\n     not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n     characters and/or will consist of less than 32 or more than 32 hexadecimal\n     digits.(string, mandatory).</li>\n     <li>storageClass: the object storage class. One of "STANDARD",\n     "REDUCED_REDUNDANCY" or "GLACIER" (string, mandatory).</li>\n     <li>owner: an object which specifies the owner of the object (object,\n     optional). It has the following fields:\n     <ul>\n       <li>id: the user identifier of the object owner (string, mandatory).</li>\n       <li>displayName: the screen name of the object owner (string, mandatory).</li>\n     </ul>\n     </li>\n   </ul>\n   </li>\n   <li>commonPrefixes: an array of strings which contains the list of the common\n   prefixes. It can be present only when the delimiter request parameter is\n   specified (array, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Lists the objects in a bucket using the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the default S3 credentials will be listed.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The listing options.</div>'}],returns:{type:"object()",description:"the list of the object in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the default credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:3,name:"list-bucket",qname:"s3:list-bucket",signature:"($credentials as item()?, $bucket as string?, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the objects in a bucket using the specified credentials.\n This method allows the specification of additional listing options.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $options :=\n {\n   "delimiter": "/",\n   "marker": "",\n   "maxKeys": 1,\n   "prefix": ""\n }\n return s3:list-bucket("credentials", "28msec", $options)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The options object must have the following structure:\n <ul>\n   <li>delimiter: the delimiter marks where the listed results stop. For example,\n       a delimiter / lists all objects starting with $prefix plus arbitrary\n       characters but not / (string, optional). Default is the empty string,\n       that is, all objects are listed.</li>\n   <li>marker: specifies a key as starting point; following keys (lexicographically\n       greater than the marker) in alphabetical order are listed (string, optional).\n       Default is the empty string, that is, all objects are listed.</li>\n   <li>maxKeys: the maximum number of keys returned. If more keys than maxKeys\n       can be fetched, the result contains <IsTruncated>true</IsTruncated>\n       (integer, optional). Default is 1000.</li>\n   <li>prefix: only keys starting with the prefix are returned (string, optional).\n       Default is the empty string, that is, all objects are listed.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example result:\n <pre>\n {\n   "name": "bucket",\n   "prefix": "",\n   "marker" : "",\n   "nextMarker": "marker",\n   "maxKeys": 1,\n   "delimiter": "/",\n   "isTruncated": true,\n   "contents":\n   [\n     {\n       "key": "image.jpg",\n       "lastModified": "2009-10-12T17:50:30.000Z",\n       "eTag": "\\"fba9dede5f27731c9771645a39863328\\"",\n       "size": 434234,\n       "storageClass": "STANDARD"\n       "owner":\n       {\n         "id": "75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a"\n         "displayName": "mtd@amazon.com"\n       }\n     }\n   ],\n   "commonPrefixes": ["photos/"]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>name: the bucket name (string, mandatory).</li>\n   <li>prefix: the used prefix (string, mandatory).</li>\n   <li>marker: indicates where in the bucket listing begins (string, mandatory).</li>\n   <li>nextMarker: when the response is truncated, you can use the key name\n   in this field as marker in the subsequent request to get next set of objects.\n   Amazon S3 lists objects in alphabetical order. This field is returned only\n   if you have specified the delimiter request parameter. If the response does\n   not include the nextMaker field and it is truncated, you can use the value\n   of the last Key in the response as the marker in the subsequent request to\n   get the next set of object keys. (string, optional)</li>\n   <li>maxKeys: the maximum number of keys returned in the response body\n   (integer, mandatory).</li>\n   <li>delimiter: the used delimiter (string, optional).</li>\n   <li>isTruncated: whether or not all of the results were returned. All of the\n   results may not be returned if the number of results exceeds that specified\n   by the maxKeys request parameter (boolean, mandatory).</li>\n   <li>contents: an array of objects listing the bucket content  (array, mandatory).\n   The fields of each contained object have the following meaning:\n   <ul>\n     <li>key: the object key (string, mandatory).</li>\n     <li>lastModified: the object last modification date (dateTime, mandatory).</li>\n     <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n     changes to the contents of an object, not its metadata. The eTag is determined\n     when an object is created. For objects created by the PUT Object operation\n     and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n     string representing the MD5 digest of the object data. For other objects,\n     the eTag may or may not be an MD5 digest of the object data. If the eTag is\n     not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n     characters and/or will consist of less than 32 or more than 32 hexadecimal\n     digits.(string, mandatory).</li>\n     <li>storageClass: the object storage class. One of "STANDARD",\n     "REDUCED_REDUNDANCY" or "GLACIER" (string, mandatory).</li>\n     <li>owner: an object which specifies the owner of the object (object,\n     optional). It has the following fields:\n     <ul>\n       <li>id: the user identifier of the object owner (string, mandatory).</li>\n       <li>displayName: the screen name of the object owner (string, mandatory).</li>\n     </ul>\n     </li>\n   </ul>\n   </li>\n   <li>commonPrefixes: an array of strings which contains the list of the common\n   prefixes. It can be present only when the delimiter request parameter is\n   specified (array, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Lists the objects in a bucket using the specified credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"bucket",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The bucket to list. If the empty sequence is given, the default bucket of the specified credentials will be listed.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The listing options.</div>'}],returns:{type:"object()",description:"the list of the object in the specified bucket"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OPTIONS if the specified options are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:0,name:"list-buckets-nondeterministic",qname:"s3:list-buckets-nondeterministic",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all buckets owned by the account of the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-buckets-0">list-buckets#0</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists all buckets owned by the account of the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"object()",description:"the owned buckets list"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"list-buckets-nondeterministic",qname:"s3:list-buckets-nondeterministic",signature:"($credentials as item()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all buckets owned by the account of the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-buckets-1">list-buckets#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists all buckets owned by the account of the specified S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'}],returns:{type:"object()",description:"the owned buckets list"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:0,name:"list-buckets",qname:"s3:list-buckets",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all buckets owned by the account of the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:list-buckets()\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "owner" :\n   {\n     "id": "dfe08489302934392afe39239fe953039d9e2af0c94",\n     "displayName": "28msec"\n   },\n   "buckets" :\n   [\n     {\n       "name": "28msec",\n       "creationDate": "2010-11-03T17:42:45.000Z",\n     }\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>owner: an object which specifies the owner of the bucket (object,\n   mandatory). It has the following fields:\n   <ul>\n     <li>id: the user identifier of the bucket owner (string, mandatory).</li>\n     <li>displayName: the screen name of the bucket owner (string, mandatory).</li>\n   </ul>\n   </li>\n   <li>buckets: an array which contains an object for each owned bucket\n   (array, mandatory). Each object contains the following fields:\n   <ul>\n     <li>name: the bucket name (string, mandatory).</li>\n     <li>creationDate: the bucket creation date. (dateTime, mandatory).</li>\n   </ul>\n   </li>\n </ul>\n </p>\n',summary:"<p>  Lists all buckets owned by the account of the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"the owned buckets list"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"list-buckets",qname:"s3:list-buckets",signature:"($credentials as item()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all buckets owned by the account of the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n s3:list-buckets("credentials")\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "owner" :\n   {\n     "id": "dfe08489302934392afe39239fe953039d9e2af0c94",\n     "displayName": "28msec"\n   },\n   "buckets" :\n   [\n     {\n       "name": "28msec",\n       "creationDate": "2010-11-03T17:42:45.000Z",\n     }\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>owner: an object which specifies the owner of the bucket (object,\n   mandatory). It has the following fields:\n   <ul>\n     <li>id: the user identifier of the bucket owner (string, mandatory).</li>\n     <li>displayName: the screen name of the bucket owner (string, mandatory).</li>\n   </ul>\n   </li>\n   <li>buckets: an array which contains an object for each owned bucket\n   (array, mandatory). Each object contains the following fields:\n   <ul>\n     <li>name: the bucket name (string, mandatory).</li>\n     <li>creationDate: the bucket creation date. (dateTime, mandatory).</li>\n   </ul>\n   </li>\n </ul>\n </p>\n',summary:"<p>  Lists all buckets owned by the account of the specified S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'}],returns:{type:"object()",description:"the owned buckets list"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"object-metadata-nondeterministic",qname:"s3:object-metadata-nondeterministic",signature:"($s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves an object metadata using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#object-metadata-1">object-metadata#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves an object metadata using the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve the metadata for.</div>'}],returns:{type:"object()",description:"the specified object metadata."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"object-metadata-nondeterministic",qname:"s3:object-metadata-nondeterministic",signature:"($credentials as item()?, $s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves an object metadata using the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#object-metadata-2">object-metadata#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves an object metadata using the specified S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve the metadata for.</div>'}],returns:{type:"object()",description:"the specified object metadata."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"object-metadata",qname:"s3:object-metadata",signature:"($s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves an object metadata using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the metadata of the\n   latest version of the object will be returned. If specified, only the\n   metadata of that particular version of the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:metadata-object($object)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "metadata":\n   {\n     "author": "28msec"\n   },\n   "missing-metadata" : 1,\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "expiration": "expiry-date=\\"Fri, 21 Dec 2012 00:00:00 GMT\\", rule-id=\\"Rule for testfile.txt\\""\n   "restore": "x-amz-restore: ongoing-request=\\"false\\", expiry-date=\\"Wed, 07 Nov 2012 00:00:00 GMT\\""\n   "serverSideEncryption": "AES256",\n   "lastModified": "Mon, 15 Oct 2012 21:58:07 GMT",\n   "eTag": "1accb31fcf202eba0c0f41fa2f09b4d7",\n   "mediaType": "text/plain"\n   "length": "28"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, mandatory).</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>missing-metadata: the number of metadata entries that were not returned\n   in the metadata object. This can happen if you create metadata using an API\n   like SOAP that supports more flexible metadata than the REST API. (integer,\n   optional).</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the permissions for the\n   latest version of the object will be returned. If specified, only the\n   permissions for that particular version of the object will be returned.</li>\n   <li>expiration: if the object expiration is configured (see\n   <a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html">PUT Bucket lifecycle</a>),\n   this field is present. It includes the expiry-date and rule-id key value\n   pairs providing object expiration information. The value of rule-id is URL\n   encoded.(string, optional).</li>\n   <li>restore: if the object is an archived object (an object whose storage\n   class is Glacier), the response includes this header if either the archive\n   restoration is in progress (see\n   <a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOSTrestore.html">POST Object restore</a>),\n   or an archive copy is already restored.(string, optional).</li>\n   <li>serverSideEncryption: If the object is stored by using server-side\n   encryption, the response includes this header with a value of the encryption\n   algorithm that was used.(string, optional).</li>\n   <li>lastModified: the date in which the object was last modified (dateTime,\n   optional).</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. For objects created by the PUT Object operation\n   and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n   string representing the MD5 digest of the object data. For other objects,\n   the eTag may or may not be an MD5 digest of the object data. If the eTag is\n   not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n   characters and/or will consist of less than 32 or more than 32 hexadecimal\n   digits.(string, optional).</li>\n   <li>mediaType: the object media-type (string, mandatory).</li>\n   <li>length: the object content length (integer, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Retrieves an object metadata using the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve the metadata for.</div>'}],returns:{type:"object()",description:"the specified object metadata."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"object-metadata",qname:"s3:object-metadata",signature:"($credentials as item()?, $s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves an object metadata using the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the metadata of the\n   latest version of the object will be returned. If specified, only the\n   metadata of that particular version of the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:metadata-object("credentials", $object)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "metadata":\n   {\n     "author": "28msec"\n   },\n   "missing-metadata" : 1,\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "expiration": "expiry-date=\\"Fri, 21 Dec 2012 00:00:00 GMT\\", rule-id=\\"Rule for testfile.txt\\""\n   "restore": "x-amz-restore: ongoing-request=\\"false\\", expiry-date=\\"Wed, 07 Nov 2012 00:00:00 GMT\\""\n   "serverSideEncryption": "AES256",\n   "lastModified": "Mon, 15 Oct 2012 21:58:07 GMT",\n   "eTag": "1accb31fcf202eba0c0f41fa2f09b4d7",\n   "mediaType": "text/plain"\n   "length": "28"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, mandatory).</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>missing-metadata: the number of metadata entries that were not returned\n   in the metadata object. This can happen if you create metadata using an API\n   like SOAP that supports more flexible metadata than the REST API. (integer,\n   optional).</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the permissions for the\n   latest version of the object will be returned. If specified, only the\n   permissions for that particular version of the object will be returned.</li>\n   <li>expiration: if the object expiration is configured (see\n   <a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html">PUT Bucket lifecycle</a>),\n   this field is present. It includes the expiry-date and rule-id key value\n   pairs providing object expiration information. The value of rule-id is URL\n   encoded.(string, optional).</li>\n   <li>restore: if the object is an archived object (an object whose storage\n   class is Glacier), the response includes this header if either the archive\n   restoration is in progress (see\n   <a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOSTrestore.html">POST Object restore</a>),\n   or an archive copy is already restored.(string, optional).</li>\n   <li>serverSideEncryption: If the object is stored by using server-side\n   encryption, the response includes this header with a value of the encryption\n   algorithm that was used.(string, optional).</li>\n   <li>lastModified: the date in which the object was last modified (dateTime,\n   optional).</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. For objects created by the PUT Object operation\n   and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n   string representing the MD5 digest of the object data. For other objects,\n   the eTag may or may not be an MD5 digest of the object data. If the eTag is\n   not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n   characters and/or will consist of less than 32 or more than 32 hexadecimal\n   digits.(string, optional).</li>\n   <li>mediaType: the object media-type (string, mandatory).</li>\n   <li>length: the object content length (integer, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Retrieves an object metadata using the specified S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve the metadata for.</div>'}],returns:{type:"object()",description:"the specified object metadata."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"object-permissions-nondeterministic",qname:"s3:object-permissions-nondeterministic",signature:"($s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the access control list (ACL) of an S3 object using the default\n S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#object-permissions-1">object-permissions#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves the access control list (ACL) of an S3 object using the default\n S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve the ACL for.</div>'}],returns:{type:"object()",description:"the object ACL"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"object-permissions-nondeterministic",qname:"s3:object-permissions-nondeterministic",signature:"($credentials as item()?, $s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the access control list (ACL) of an S3 object using the specified\n credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#object-permissions-2">object-permissions#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves the access control list (ACL) of an S3 object using the specified\n credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve the ACL for.</div>'}],returns:{type:"object()",description:"the object ACL"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"object-permissions",qname:"s3:object-permissions",signature:"($s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the access control list (ACL) of an S3 object using the default\n S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the permissions for the\n   latest version of the object will be returned. If specified, only the\n   permissions for that particular version of the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:object-permissions($object)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "owner" :\n   {\n     "id" : "ea3617f5543e366a51bf51f440c221410b8001c34744e9d3a81acb79cff9d2ed",\n     "displayName" : "28msec"\n   },\n   "acl" :\n   [\n     {\n       "grantee" :\n       {\n         "type" : "CanonicalUser",\n         "id" : "ea3617f5543e366a51bf51f440c221410b8001c34744e9d3a81acb79cff9d2ed",\n         "displayName" : "28msec"\n       },\n       "permission" : "FULL_CONTROL"\n     }\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n <li>owner: an object which specifies the owner of the object (object,\n mandatory). It has the following fields:\n   <ul>\n     <li>id: the user identifier of the object owner (string, mandatory).</li>\n     <li>displayName: the screen name of the object owner (string, mandatory).</li>\n   </ul>\n </li>\n <li>acl: an array which contains an object for each grantee with the corresponding\n ACL settings (array, mandatory). Each object contains the following fields:\n   <ul>\n     <li>grantee: specifies the permissions grantee (object, mandatory). It\n     contains the following fields:\n       <ul>\n         <li>type: one of "AmazonCustomerByEmail", "CanonicalUser" or "Group".</li>\n         <li>emailAddress: the customer email address (string, present in all\n         and only AmazonCustomerByEmail grantees).</li>\n         <li>id: the user identifier (string, present in all and only CanonicalUser\n         grantees).</li>\n         <li>displayName: the user screen name (string, present in all and only\n         CanonicalUser grantees).</li>\n         <li>URI: the group URI (string, present in all and only Group grantees).</li>\n       </ul>\n     </li>\n     <li>permission: the granted permissions. One of "READ", "WRITE", "READ_ACP",\n     "WRITE_ACP", "FULL_CONTROL". (string, mandatory).</li>\n   </ul>\n </li>\n </ul>\n </p>\n',summary:"<p>  Retrieves the access control list (ACL) of an S3 object using the default\n S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve the ACL for.</div>'}],returns:{type:"object()",description:"the object ACL"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"object-permissions",qname:"s3:object-permissions",signature:"($credentials as item()?, $s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the access control list (ACL) of an S3 object using the specified\n credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials does not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the permissions for the\n   latest version of the object will be returned. If specified, only the\n   permissions for that particular version of the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:object-permissions("credentials", $object)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "owner" :\n   {\n     "id" : "ea3617f5543e366a51bf51f440c221410b8001c34744e9d3a81acb79cff9d2ed",\n     "displayName" : "28msec"\n   },\n   "acl" :\n   [\n     {\n       "grantee" :\n       {\n         "type" : "CanonicalUser",\n         "id" : "ea3617f5543e366a51bf51f440c221410b8001c34744e9d3a81acb79cff9d2ed",\n         "displayName" : "28msec"\n       },\n       "permission" : "FULL_CONTROL"\n     }\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n <li>owner: an object which specifies the owner of the object (object,\n mandatory). It has the following fields:\n   <ul>\n     <li>id: the user identifier of the object owner (string, mandatory).</li>\n     <li>displayName: the screen name of the object owner (string, mandatory).</li>\n   </ul>\n </li>\n <li>acl: an array which contains an object for each grantee with the corresponding\n ACL settings (array, mandatory). Each object contains the following fields:\n   <ul>\n     <li>grantee: specifies the permissions grantee (object, mandatory). It contains\n     the following fields:\n       <ul>\n         <li>type: one of "AmazonCustomerByEmail", "CanonicalUser" or "Group".</li>\n         <li>emailAddress: the customer email address (string, present in all\n         and only AmazonCustomerByEmail grantees).</li>\n         <li>id: the user identifier (string, present in all and only CanonicalUser\n         grantees).</li>\n         <li>displayName: the user screen name (string, present in all and only\n         CanonicalUser grantees).</li>\n         <li>URI: the group URI (string, present in all and only Group grantees).</li>\n       </ul>\n     </li>\n     <li>permission: the granted permissions. One of "READ", "WRITE", "READ_ACP",\n     "WRITE_ACP", "FULL_CONTROL". (string, mandatory).</li>\n   </ul>\n </li>\n </ul>\n </p>\n',summary:"<p>  Retrieves the access control list (ACL) of an S3 object using the specified\n credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve the ACL for.</div>'}],returns:{type:"object()",description:"the object ACL"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"object-torrent-nondeterministic",qname:"s3:object-torrent-nondeterministic",signature:"($s3-object as item()) as base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a torrent file for a given object using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#object-torrent-1">object-torrent#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns a torrent file for a given object using the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object to retrieve the torrent file for</div>'}],returns:{type:"base64Binary",description:"the base64 encoded torrent file for the specified object."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"object-torrent-nondeterministic",qname:"s3:object-torrent-nondeterministic",signature:"($credentials as item()?, $s3-object as item()) as base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a torrent file for a given object using the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#object-torrent-2">object-torrent#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns a torrent file for a given object using the specified S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object to retrieve the torrent file for</div>'}],returns:{type:"base64Binary",description:"the base64 encoded torrent file of the specified object."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"object-torrent",qname:"s3:object-torrent",signature:"($s3-object as item()) as base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a torrent file for a given object using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec"\n }\n return s3:object-torrent($object)\n </pre>\n </p>\n',summary:"<p>  Returns a torrent file for a given object using the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object to retrieve the torrent file for</div>'}],returns:{type:"base64Binary",description:"the base64 encoded torrent file for the specified object."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"object-torrent",qname:"s3:object-torrent",signature:"($credentials as item()?, $s3-object as item()) as base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a torrent file for a given object using the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec"\n }\n return s3:object-torrent($object)\n </pre>\n </p>\n',summary:"<p>  Returns a torrent file for a given object using the specified S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object to retrieve the torrent file for</div>'}],returns:{type:"base64Binary",description:"the base64 encoded torrent file of the specified object."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"read-binary-nondeterministic",qname:"s3:read-binary-nondeterministic",signature:"($s3-object as item()) as base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the binary content of an S3 object using the default S3 credentials.\n The object content is forced to be interpreted as binaryand will be returned\n as a base64Binary item.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#read-binary-1">read-binary#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves the binary content of an S3 object using the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"base64Binary",description:"the object or object version binary content."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:2,name:"read-binary-nondeterministic",qname:"s3:read-binary-nondeterministic",signature:"($credentials as item()?, $s3-object as item()) as base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the binary content of an S3 object using the specified S3 credentials.\n The object content is forced to be interpreted as binaryand will be returned\n as a base64Binary item.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#read-binary-2">read-binary#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves the binary content of an S3 object using the specified S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"base64Binary",description:"the object or object version binary content."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:1,name:"read-binary",qname:"s3:read-binary",signature:"($s3-object as item()) as base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the binary content of an S3 object using the default S3 credentials.\n The object content is forced to be interpreted as binaryand will be returned\n as a base64Binary item.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the latest version of\n   the object will be returned. If specified, only that particular version of\n   the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:read-binary($object)\n </pre>\n </p>\n',summary:"<p>  Retrieves the binary content of an S3 object using the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"base64Binary",description:"the object or object version binary content."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:2,name:"read-binary",qname:"s3:read-binary",signature:"($credentials as item()?, $s3-object as item()) as base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the binary content of an S3 object using the specified S3 credentials.\n The object content is forced to be interpreted as binaryand will be returned\n as a base64Binary item.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the latest version of\n   the object will be returned. If specified, only that particular version of\n   the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:read-binary("credentials", $object)\n </pre>\n </p>\n',summary:"<p>  Retrieves the binary content of an S3 object using the specified S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"base64Binary",description:"the object or object version binary content."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:1,name:"read-object-nondeterministic",qname:"s3:read-object-nondeterministic",signature:"($s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves an S3 object using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#read-object-1">read-object#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves an S3 object using the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"object()",description:"the specified object."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"read-object-nondeterministic",qname:"s3:read-object-nondeterministic",signature:"($credentials as item()?, $s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves an S3 object using the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#read-object-2">read-object#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves an S3 object using the specified S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"object()",description:"the specified object."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"read-object",qname:"s3:read-object",signature:"($s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves an S3 object using the default S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the latest version of\n   the object will be returned. If specified, only that particular version of\n   the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:read-object($object)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "metadata":\n   {\n     "author": "28msec"\n   },\n   "missing-metadata" : 1,\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "expiration": "expiry-date=\\"Fri, 21 Dec 2012 00:00:00 GMT\\", rule-id=\\"Rule for testfile.txt\\""\n   "restore": "x-amz-restore: ongoing-request=\\"false\\", expiry-date=\\"Wed, 07 Nov 2012 00:00:00 GMT\\""\n   "serverSideEncryption": "AES256",\n   "lastModified": "Mon, 15 Oct 2012 21:58:07 GMT",\n   "eTag": "1accb31fcf202eba0c0f41fa2f09b4d7",\n   "mediaType": "text/plain"\n   "length": "28",\n   "content: "1234567890123456789012345678"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, mandatory).</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>missing-metadata: the number of metadata entries that were not returned\n   in the metadata object. This can happen if you create metadata using an API\n   like SOAP that supports more flexible metadata than the REST API. (integer,\n   optional).</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the permissions for the\n   latest version of the object will be returned. If specified, only the\n   permissions for that particular version of the object will be returned.</li>\n   <li>expiration: if the object expiration is configured (see\n   <a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html">PUT Bucket lifecycle</a>),\n   this field is present. It includes the expiry-date and rule-id key value\n   pairs providing object expiration information. The value of rule-id is URL\n   encoded.(string, optional).</li>\n   <li>restore: if the object is an archived object (an object whose storage\n   class is Glacier), the response includes this header if either the archive\n   restoration is in progress (see\n   <a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOSTrestore.html">POST Object restore</a>),\n   or an archive copy is already restored.(string, optional).</li>\n   <li>serverSideEncryption: If the object is stored by using server-side\n   encryption, the response includes this header with a value of the encryption\n   algorithm that was used.(string, optional).</li>\n   <li>lastModified: the date in which the object was last modified (dateTime,\n   optional).</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. For objects created by the PUT Object operation\n   and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n   string representing the MD5 digest of the object data. For other objects,\n   the eTag may or may not be an MD5 digest of the object data. If the eTag is\n   not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n   characters and/or will consist of less than 32 or more than 32 hexadecimal\n   digits.(string, optional).</li>\n   <li>mediaType: the object media-type (string, mandatory).</li>\n   <li>length: the object content length (integer, optional).</li>\n   <li>content: the object content. (item, optional). The type of this field\n   is determined by the media-type returned by the server. If the media-type\n   indicates that the body content is textual, then the content has type string,\n   base64Binary otherwise. Specifically, the body content is considered textual\n   if and only if the MIME-type specified in the media-type is one of:\n   <ul>\n     <li>"application/json"</li>\n     <li>"application/x-javascript"</li>\n     <li>"application/xml"</li>\n     <li>"application/xml-external-parsed-entity"</li>\n   </ul>\n   or if the MIME-type starts with "text/" or ends with "+xml".</li>\n </ul>\n </p>\n',summary:"<p>  Retrieves an S3 object using the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"object()",description:"the specified object."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"read-object",qname:"s3:read-object",signature:"($credentials as item()?, $s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves an S3 object using the specified S3 credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the latest version of\n   the object will be returned. If specified, only that particular version of\n   the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:read-object($object)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "metadata":\n   {\n     "author": "28msec"\n   },\n   "missing-metadata" : 1,\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "expiration": "expiry-date=\\"Fri, 21 Dec 2012 00:00:00 GMT\\", rule-id=\\"Rule for testfile.txt\\""\n   "restore": "x-amz-restore: ongoing-request=\\"false\\", expiry-date=\\"Wed, 07 Nov 2012 00:00:00 GMT\\""\n   "serverSideEncryption": "AES256",\n   "lastModified": "Mon, 15 Oct 2012 21:58:07 GMT",\n   "eTag": "1accb31fcf202eba0c0f41fa2f09b4d7",\n   "mediaType": "text/plain"\n   "length": "28",\n   "content: "1234567890123456789012345678"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, mandatory).</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>missing-metadata: the number of metadata entries that were not returned\n   in the metadata object. This can happen if you create metadata using an API\n   like SOAP that supports more flexible metadata than the REST API. (integer,\n   optional).</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the permissions for the\n   latest version of the object will be returned. If specified, only the\n   permissions for that particular version of the object will be returned.</li>\n   <li>expiration: if the object expiration is configured (see\n   <a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTlifecycle.html">PUT Bucket lifecycle</a>),\n   this field is present. It includes the expiry-date and rule-id key value\n   pairs providing object expiration information. The value of rule-id is URL\n   encoded.(string, optional).</li>\n   <li>restore: if the object is an archived object (an object whose storage\n   class is Glacier), the response includes this header if either the archive\n   restoration is in progress (see\n   <a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOSTrestore.html">POST Object restore</a>),\n   or an archive copy is already restored.(string, optional).</li>\n   <li>serverSideEncryption: If the object is stored by using server-side\n   encryption, the response includes this header with a value of the encryption\n   algorithm that was used.(string, optional).</li>\n   <li>lastModified: the date in which the object was last modified (dateTime,\n   optional).</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. For objects created by the PUT Object operation\n   and the POST Object operation, the eTag is a quoted, 32-digit hexadecimal\n   string representing the MD5 digest of the object data. For other objects,\n   the eTag may or may not be an MD5 digest of the object data. If the eTag is\n   not an MD5 digest of the object data, it will contain one or more non-hexadecimal\n   characters and/or will consist of less than 32 or more than 32 hexadecimal\n   digits.(string, optional).</li>\n   <li>mediaType: the object media-type (string, mandatory).</li>\n   <li>length: the object content length (integer, optional).</li>\n   <li>content: the object content. (item, optional). The type of this field\n   is determined by the media-type returned by the server. If the media-type\n   indicates that the body content is textual,then the content has type string,\n   base64Binary otherwise. Specifically, the body content is considered textual\n   if and only if the MIME-type specified in the media-type is one of:\n   <ul>\n     <li>"application/json"</li>\n     <li>"application/x-javascript"</li>\n     <li>"application/xml"</li>\n     <li>"application/xml-external-parsed-entity"</li>\n   </ul>\n   or if the MIME-type starts with "text/" or ends with "+xml".</li>\n </ul>\n </p>\n',summary:"<p>  Retrieves an S3 object using the specified S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"object()",description:"the specified object."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"read-text-nondeterministic",qname:"s3:read-text-nondeterministic",signature:"($s3-object as item()) as string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the textual content of an S3 object using the default S3 credentials.\n The object content is forced to be interpreted as textual, with a UTF-8 charset\n and will be returned as string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#read-text-1">read-text#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves the textual content of an S3 object using the default S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"string",description:"the object or object version textual content."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"read-text-nondeterministic",qname:"s3:read-text-nondeterministic",signature:"($credentials as item()?, $s3-object as item()) as string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the textual content of an S3 object using the specified S3 credentials.\n The object content is forced to be interpreted as textual, with a UTF-8 charset\n and will be returned as string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#read-text-2">read-text#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves the textual content of an S3 object using the specified S3 credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"string",description:"the object or object version textual content."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"read-text",qname:"s3:read-text",signature:"($s3-object as item()) as string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the textual content of an S3 object using the default S3 credentials.\n The object content is forced to be interpreted as textual, with a UTF-8 charset\n and will be returned as string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the latest version of\n   the object will be returned. If specified, only that particular version of\n   the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:read-text("credentials", $object)\n </pre>\n </p>\n',summary:"<p>  Retrieves the textual content of an S3 object using the default S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"string",description:"the object or object version textual content."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"read-text",qname:"s3:read-text",signature:"($credentials as item()?, $s3-object as item()) as string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the textual content of an S3 object using the specified S3 credentials.\n The object content is forced to be interpreted as textual, with a UTF-8 charset\n and will be returned as string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the latest version of\n   the object will be returned. If specified, only that particular version of\n   the object will be returned.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo"\n }\n return s3:read-text("credentials", $object)\n </pre>\n </p>\n',summary:"<p>  Retrieves the textual content of an S3 object using the specified S3 credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version to retrieve.</div>'}],returns:{type:"string",description:"the object or object version textual content."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:RESPONSE the response received from S3 cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"set-object-permissions",qname:"s3:set-object-permissions",signature:"($s3-object as item()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the access control list (ACL) of an S3 object using the default S3\n credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the permissions for the\n   latest version of the object will be set. If specified, only the\n   permissions for that particular version of the object will be set.</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo",\n   "permission": $s3:ACL-GRANT-PUBLIC-READ\n }\n return s3:set-object-permissions($object)\n </pre>\n </p>\n',summary:"<p>  Sets the access control list (ACL) of an S3 object using the default S3\n credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version and ACL to set.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:2,name:"set-object-permissions",qname:"s3:set-object-permissions",signature:"($credentials as item()?, $s3-object as item()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the access control list (ACL) of an S3 object using the specified S3\n credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used. If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>version: the object version (string, optional). If versioning is enabled\n   for the specified object and no version is specified the permissions for the\n   latest version of the object will be set. If specified, only the\n   permissions for that particular version of the object will be set.</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n let $object :=\n {\n   "key": "object",\n   "bucket": "28msec",\n   "version": "3/L4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo",\n   "permission": $s3:ACL-GRANT-PUBLIC-READ\n }\n return s3:set-object-permissions($object)\n </pre>\n </p>\n',summary:"<p>  Sets the access control list (ACL) of an S3 object using the specified S3\n credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object or object version and ACL to set.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:2,name:"write-binary",qname:"s3:write-binary",signature:"($object as item(), $binary-content as base64Binary) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Writes a binary object in an S3 bucket using the default S3 credentials.\n If the object already exists it is overwritten.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. The object media-type will be set to "binary/octet-stream", no metadata will\n be set for the object, the object will be stored on standard redundancy storage,\n and the object permission will be set to "private", that is, the owner gets\n FULL_CONTROL, and no one else has access rights.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>mediaType: the media-type of the object (string, optional). If not specified,\n   "binary/octet-stream" is used.</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n   <li>reducedRedundancy: whether to use reduced-redundancy or not (bool,\n   optional). Default is false.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n variable $s3-object :=\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "permission": $const:ACL-GRANT-PUBLIC-READ,\n   "metadata": { "author": "28msec" },\n   "mediaType": "application/octet-stream"\n }\n s3:write-binary($s3-object, base64Binary("Mjhtc2Vj"))\n </pre>\n Example Result:\n <pre>\n {\n   "expiration": "expiry-date=\\"Fri, 23 Dec 2012 00:00:00 GMT\\", rule-id=\\"1\\"",\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "eTag": "\\"1b2cf535f27731c974343645a3985328\\""\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The meaning of the fields in the result object is the following:\n <ul>\n   <li>expiration: if the object expiration is configured, the response\n   includes this header. It includes the expiry-date and rule-id key-value\n   pairs providing object expiration information. The value of the rule-id is\n   URL encoded. (string, optional)</li>\n   <li>version: the version of the object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When you PUT an object in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. The eTag returned by this method is a quoted,\n   32-digit hexadecimal string representing the MD5 digest of the object data.\n   For other objects, the eTag may or may not be an MD5 digest of the object data.\n   (string, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Writes a binary object in an S3 bucket using the default S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"object",type:"item()",occurrence:null,description:""},{name:"binary-content",type:"base64Binary",occurrence:null,description:""}],returns:{type:"object()",description:"the S3 operation result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:3,name:"write-binary",qname:"s3:write-binary",signature:"($credentials as item()?, $object as item(), $binary-content as base64Binary) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Writes a binary object in an S3 bucket using the specified S3 credentials.\n If the object already exists it is overwritten.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. The object media-type will be set to "binary/octet-stream", no metadata will\n be set for the object, the object will be stored on standard redundancy storage,\n and the object permission will be set to "private", that is, the owner gets\n FULL_CONTROL, and no one else has access rights.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>mediaType: the media-type of the object (string, optional). If not specified,\n   "binary/octet-stream" is used.</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n   <li>reducedRedundancy: whether to use reduced-redundancy or not (bool,\n   optional). Default is false.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n variable $s3-object :=\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "permission": $const:ACL-GRANT-PUBLIC-READ,\n   "metadata": { "author": "28msec" },\n   "mediaType": "application/octet-stream"\n }\n s3:write-binary("credentials", $s3-object, base64Binary("Mjhtc2Vj"))\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "expiration": "expiry-date=\\"Fri, 23 Dec 2012 00:00:00 GMT\\", rule-id=\\"1\\"",\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "eTag": "\\"1b2cf535f27731c974343645a3985328\\""\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>expiration: if the object expiration is configured, the response\n   includes this header. It includes the expiry-date and rule-id key-value\n   pairs providing object expiration information. The value of the rule-id is\n   URL encoded. (string, optional)</li>\n   <li>version: the version of the object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When you PUT an object in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. The eTag returned by this method is a quoted,\n   32-digit hexadecimal string representing the MD5 digest of the object data.\n   For other objects, the eTag may or may not be an MD5 digest of the object data.\n   (string, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Writes a binary object in an S3 bucket using the specified S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"object",type:"item()",occurrence:null,description:""},{name:"binary-content",type:"base64Binary",occurrence:null,description:""}],returns:{type:"object()",description:"the S3 operation result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:1,name:"write-object",qname:"s3:write-object",signature:"($s3-object as item()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Writes an object in an S3 bucket using the default S3 credentials.\n If the object already exists it is overwritten.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The object to write and its contents are specified through the $s3-object\n parameter, which must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>content: the object content. It must either be a string or a base64Binary\n   atomic. (item, mandatory).</li>\n   <li>mediaType: the media-type of the object (string, optional). If not specified,\n   "text/plain" is used if the content field is of type string, "binary/octet-stream"\n   if it is of type base64Binary.</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n   <li>reducedRedundancy: whether to use reduced-redundancy or not (bool,\n   optional). Default is false.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n variable $s3-object :=\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "permission": $const:ACL-GRANT-PUBLIC-READ,\n   "metadata": { "author": "28msec" },\n   "content": serialize({ "Hello": "World" }),\n   "mediaType": "application/xml"\n }\n s3:write-object($s3-object)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "expiration": "expiry-date=\\"Fri, 23 Dec 2012 00:00:00 GMT\\", rule-id=\\"1\\"",\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "eTag": "\\"1b2cf535f27731c974343645a3985328\\""\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>expiration: if the object expiration is configured, the response\n   includes this header. It includes the expiry-date and rule-id key-value\n   pairs providing object expiration information. The value of the rule-id is\n   URL encoded. (string, optional)</li>\n   <li>version: the version of the object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When you PUT an object in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. The eTag returned by this method is a quoted,\n   32-digit hexadecimal string representing the MD5 digest of the object data.\n   For other objects, the eTag may or may not be an MD5 digest of the object data.\n   (string, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Writes an object in an S3 bucket using the default S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"s3-object",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object to write.</div>'}],returns:{type:"object()",description:"the S3 operation result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:2,name:"write-object",qname:"s3:write-object",signature:"($credentials as item()?, $s3-object as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Writes an object in an S3 bucket using the specified credentials.\n If the object already exists it is overwritten.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The object to write and its contents are specified through the $s3-object\n parameter, which must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>content: the object content. It must either be a string or a base64Binary\n   atomic. (item, mandatory).</li>\n   <li>mediaType: the media-type of the object (string, optional). If not specified,\n   "text/plain" is used if the content field is of type string, "binary/octet-stream"\n   if it is of type base64Binary.</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n   <li>reducedRedundancy: whether to use reduced-redundancy or not (bool,\n   optional). Default is false.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n variable $s3-object :=\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "permission": $const:ACL-GRANT-PUBLIC-READ,\n   "metadata": { "author": "28msec" },\n   "content": serialize({ "Hello": "World" }),\n   "mediaType": "application/xml"\n }\n s3:write-object("s3", $s3-object)\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "expiration": "expiry-date=\\"Fri, 23 Dec 2012 00:00:00 GMT\\", rule-id=\\"1\\"",\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "eTag": "\\"1b2cf535f27731c974343645a3985328\\""\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>expiration: if the object expiration is configured, the response\n   includes this header. It includes the expiry-date and rule-id key-value\n   pairs providing object expiration information. The value of the rule-id is\n   URL encoded. (string, optional)</li>\n   <li>version: the version of the object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When you PUT an object in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. The eTag returned by this method is a quoted,\n   32-digit hexadecimal string representing the MD5 digest of the object data.\n   For other objects, the eTag may or may not be an MD5 digest of the object data.\n   (string, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Writes an object in an S3 bucket using the specified credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"s3-object",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The S3 object to write.</div>'}],returns:{type:"object()",description:"the S3 operation result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:2,name:"write-text",qname:"s3:write-text",signature:"($object as item(), $text-content as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Writes a textual object in an S3 bucket using the default S3 credentials.\n If the object already exists it is overwritten.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a string is specified, it is interpreted as\n key for an object in the default bucket of the default credentials. If no default\n bucket is present in the default credentials, the <code>s3:BUCKET</code> error\n is raised. The object media-type will be set to "text/plain", no metadata will\n be set for the object, the object will be stored on standard redundancy storage,\n and the object permission will be set to "private", that is, the owner gets\n FULL_CONTROL, and no one else has access rights.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the default credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>mediaType: the media-type of the object (string, optional). If not specified,\n   "text/plain" is used.</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n   <li>reducedRedundancy: whether to use reduced-redundancy or not (bool,\n   optional). Default is false.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n variable $s3-object :=\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "permission": $const:ACL-GRANT-PUBLIC-READ,\n   "metadata": { "author": "28msec" },\n   "mediaType": "text/xml"\n }\n s3:write-text($s3-object, serialize(&lt;a/&gt;))\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "expiration": "expiry-date=\\"Fri, 23 Dec 2012 00:00:00 GMT\\", rule-id=\\"1\\"",\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "eTag": "\\"1b2cf535f27731c974343645a3985328\\""\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>expiration: if the object expiration is configured, the response\n   includes this header. It includes the expiry-date and rule-id key-value\n   pairs providing object expiration information. The value of the rule-id is\n   URL encoded. (string, optional)</li>\n   <li>version: the version of the object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When you PUT an object in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. The eTag returned by this method is a quoted,\n   32-digit hexadecimal string representing the MD5 digest of the object data.\n   For other objects, the eTag may or may not be an MD5 digest of the object data.\n   (string, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Writes a textual object in an S3 bucket using the default S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"object",type:"item()",occurrence:null,description:""},{name:"text-content",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The textual object content.</div>'}],returns:{type:"object()",description:"the S3 operation result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the default S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']},{isDocumented:!0,arity:3,name:"write-text",qname:"s3:write-text",signature:"($credentials as item()?, $object as item(), $text-content as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Writes a text object in an S3 bucket using the specified S3 credentials.\n If the object already exists it is overwritten.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The S3 object is specified through the $s3-object parameter. Either a string\n or a JSON object can be used.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a string is specified, it is interpreted as\n key for an object in the default bucket of the specified credentials. If no default\n bucket is present in the specified credentials, the <code>s3:BUCKET</code> error\n is raised. The object media-type will be set to "text/plain", no metadata will\n be set for the object, the object will be stored on standard redundancy storage,\n and the object permission will be set to "private", that is, the owner gets\n FULL_CONTROL, and no one else has access rights.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a JSON object is used, it must have the following structure:\n <ul>\n   <li>key: the object key (string, mandatory).</li>\n   <li>bucket: the bucket name (string, optional). If this field is not present\n   and the specified credentials do not have a default bucket, the\n   <code>s3:BUCKET</code> error is raised.</li>\n   <li>mediaType: the media-type of the object (string, optional). If not specified,\n   "text/plain" is used.</li>\n   <li>metadata: an object specifying additional metadata. Each metadata is a\n   name-value pair and is represented as different fields (object, optional).</li>\n   <li>permission: the permission to set (string, optional). It must be one of\n   "private", "public-read", "public-read-write", "authenticated-read",\n   "bucket-owner-read", "bucket-owner-full-control". For your convenience the\n   following variables can be used: <code>$s3:ACL-GRANT-PRIVATE</code>,\n   <code>$s3:ACL-GRANT-PUBLIC-READ</code>, <code>$s3:ACL-GRANT-PUBLIC-READ-WRITE</code>,\n   <code>$s3:ACL-GRANT-AUTHENTICATED-READ</code>, <code>$s3:ACL-GRANT-BUCKET-OWNER-READ</code>,\n   <code>$s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL</code>. If this field is not\n   specified, the "private" ACL is used, that is, the owner gets FULL_CONTROL,\n   and no one else has access rights.</li>\n   <li>reducedRedundancy: whether to use reduced-redundancy or not (bool,\n   optional). Default is false.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n variable $s3-object :=\n {\n   "key": "test.xml",\n   "bucket": "28msec",\n   "permission": $const:ACL-GRANT-PUBLIC-READ,\n   "metadata": { "author": "28msec" },\n   "mediaType": "text/xml"\n }\n s3:write-text("credentials", $s3-object, serialize(&lt;a/&gt;))\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example return object:\n <pre>\n {\n   "expiration": "expiry-date=\\"Fri, 23 Dec 2012 00:00:00 GMT\\", rule-id=\\"1\\"",\n   "version": "3GL4kqtJlcpXroDTDm3vjVBH40Nr8X8g",\n   "eTag": "\\"1b2cf535f27731c974343645a3985328\\""\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields in the returned object have the following meanings:\n <ul>\n   <li>expiration: if the object expiration is configured, the response\n   includes this header. It includes the expiry-date and rule-id key-value\n   pairs providing object expiration information. The value of the rule-id is\n   URL encoded. (string, optional)</li>\n   <li>version: the version of the object. When you enable versioning,\n   Amazon S3 generates a random number for objects added to a bucket. The value\n   is UTF-8 encoded and URL ready. When you PUT an object in a bucket where\n   versioning has been suspended, the version ID is always null. (string, optional)</li>\n   <li>eTag: the entity tag is a hash of the object. The eTag only reflects\n   changes to the contents of an object, not its metadata. The eTag is determined\n   when an object is created. The eTag returned by this method is a quoted,\n   32-digit hexadecimal string representing the MD5 digest of the object data.\n   For other objects, the eTag may or may not be an MD5 digest of the object data.\n   (string, optional).</li>\n </ul>\n </p>\n',summary:"<p>  Writes a text object in an S3 bucket using the specified S3 credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials to use.</div>'},{name:"object",type:"item()",occurrence:null,description:""},{name:"text-content",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The textual object content.</div>'}],returns:{type:"object()",description:"the S3 operation result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:CREDENTIALS if the specified S3 credentials cannot be found or are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:OBJECT if the object specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:BUCKET if no bucket has been specified and no default bucket is present in the used credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:HTTP an HTTP error occurred sending the request to S3</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">s3:REQUEST S3 refused to execute the request</xqdoc:error>']}],variables:[{name:"s3:ACL-GRANT-PRIVATE",type:"item()*",description:" The private canned ACL. It is applicable to buckets and objects.\n Owner gets FULL_CONTROL. No one else has access rights.\n"},{name:"s3:ACL-GRANT-PUBLIC-READ",type:"item()*",description:" The public-read canned ACL. Applicable to buckets and objects.\n Owner gets FULL_CONTROL. The AllUsers group gets READ access.\n"},{name:"s3:ACL-GRANT-PUBLIC-READ-WRITE",type:"item()*",description:" The public-read-write canned ACL. Applicable to buckets and objects.\n Owner gets FULL_CONTROL. The AllUsers group gets READ and WRITE access.\n Granting this on a bucket is generally not recommended.\n"},{name:"s3:ACL-GRANT-AUTHENTICATED-READ",type:"item()*",description:" The autenticated-read canned ACL. Applicable to buckets and objects.\n Owner gets FULL_CONTROL. The AuthenticatedUsers group gets READ access.\n"},{name:"s3:ACL-GRANT-BUCKET-OWNER-READ",type:"item()*",description:" The grant-bucket-owner-read canned ACL. Applicable to objects.\n Object owner gets FULL_CONTROL. Bucket owner gets READ access.\n If you specify this canned ACL when creating a bucket, Amazon S3 ignores it.\n"},{name:"s3:ACL-GRANT-BUCKET-OWNER-FULL-CONTROL",type:"item()*",description:" The grant-bucket-owner-full-control canned ACL. Applicable to objects.\n Both the object owner and the bucket owner get FULL_CONTROL over the object.\n If you specify this canned ACL when creating a bucket, Amazon S3 ignores it.\n"}]},"http://api.28.io/authorization":{ns:"http://api.28.io/authorization",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/authorization",prefix:"authorization"},{uri:"http://zorba.io/modules/base64",prefix:"base64"},{uri:"http://zorba.io/modules/hmac",prefix:"hmac"},{uri:"http://expath.org/ns/http-client",prefix:"http-client"},{uri:"http://www.28msec.com/modules/project",prefix:"project"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://www.28msec.com/modules/http/response",prefix:"res"}],functions:[{isDocumented:!1,arity:0,name:"authorized",qname:"authorization:authorized",signature:"() as xs:boolean",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!1,arity:0,name:"html-do-login",qname:"authorization:html-do-login",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"html-show-login",qname:"authorization:html-show-login",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]}],variables:[]},"http://zorba.io/modules/store/static/integrity-constraints/dml":{ns:"http://zorba.io/modules/store/static/integrity-constraints/dml",description:' This module defines a function to check if an integrity constraint is\n satisfied.\n The integrity constraint needs to be declared in the prolog of a module.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This module is part of\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/xqddf.html">Zorba\'s XQuery Data Definition Facility</a>.\n All the integrity constraints managed by this module have to be pre-declared\n in the prolog of a module.\n Please refer to the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/data_lifecycle.html">general documentation</a>\n for more information and examples.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/data_lifecycle.html">Data Lifecycle</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/xqddf.html">XQuery Data Definition Facility</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/errors</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Nicolae Brinza, Matthias Brantner, David Graf, Till Westmann, Markos Zaharioudakis</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/store/static/integrity-constraints/dml",prefix:"icdml"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"check-integrity-constraint",qname:"icdml:check-integrity-constraint",signature:"($name as xs:QName) as xs:boolean external",description:" Checks if the specified constraints are valid in the database.\n",summary:"<p> Checks if the specified constraints are valid in the database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the integrity constraint to check.</div>'}],returns:{type:"xs:boolean",description:"true if the constraints are valid; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0031 if the integrity constraint is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0032 if the integrity constraint is not available.</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/excel/statistical":{ns:"http://zorba.io/modules/excel/statistical",description:" This is a library module offering a part of the set of statistical functions\n defined by Microsoft Excel 2003.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://office.microsoft.com/en-us/excel/CH062528311033.aspx" target="_blank">Excel 2003 Documentation: Statistical Functions</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Turcanu</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/statistical",prefix:"excel"},{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/modules/excel/math",prefix:"excel-math"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"avedev",qname:"excel:avedev",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:" Returns the average of the absolute deviations of data points from their mean.\n The formula is sum(abs(x - average_x))/n, where n is the count of x in the sequence.\n",summary:"<p> Returns the average of the absolute deviations of data points from their mean.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric. Sequence can be of any length from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"The formula result"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"average",qname:"excel:average",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Returns the average (arithmetic mean) of the arguments.\n Arguments can be empty values, otherwise must be castable to numeric.\n If sequence is empty then zero is returned.\n The sequence can be of any length.\n",summary:"<p> Returns the average (arithmetic mean) of the arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of numbers or empty values.</div>'}],returns:{type:"xs:anyAtomicType",description:"The sum of all numbers divided by the number of non-empty values."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"averagea",qname:"excel:averagea",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:" Calculates the average (arithmetic mean) of the values in the sequence of arguments.\n Arguments can be of any type.\n The numbers are added, and the sum is divided by the size of entire sequence.\n",summary:"<p> Calculates the average (arithmetic mean) of the values in the sequence of arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values of any type. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"The result"},errors:[]},{isDocumented:!0,arity:1,name:"count",qname:"excel:count",signature:"($numbers as xs:anyAtomicType*) as xs:integer",description:" Counts the number of cells that contain numbers or values castable to numeric.\n",summary:"<p> Counts the number of cells that contain numbers or values castable to numeric.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of values, of any length.</div>'}],returns:{type:"xs:integer",description:"The count of numbers."},errors:[]},{isDocumented:!0,arity:1,name:"counta",qname:"excel:counta",signature:"($numbers as xs:anyAtomicType*) as xs:integer",description:' Counts the number of values that are not empty.\n Empty values are the one with string value "".\n',summary:"<p> Counts the number of values that are not empty.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values of any type, any length</div>'}],returns:{type:"xs:integer",description:"The count of non-empty values"},errors:[]},{isDocumented:!0,arity:1,name:"countblank",qname:"excel:countblank",signature:"($cells as xs:anyAtomicType*) as xs:integer",description:' Counts the empty values in a sequence.\n The empty values are the ones with string value "".\n The value 0 is not counted.\n',summary:"<p> Counts the empty values in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"cells",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values, of any length</div>'}],returns:{type:"xs:integer",description:"The count"},errors:[]},{isDocumented:!0,arity:2,name:"large",qname:"excel:large",signature:"($numbers as xs:anyAtomicType*, $k as xs:integer) as xs:anyAtomicType",description:" Returns the k-th largest value in a data set.\n If n is the number of data points in a range,\n   then LARGE(array,1) returns the largest value,\n   and LARGE(array,n) returns the smallest value.\n",summary:"<p> Returns the k-th largest value in a data set.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric. The sequence can be of any length, from 1 up.</div>'},{name:"k",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the position of largest value, with value from 1 to count of values</div>'}],returns:{type:"xs:anyAtomicType",description:"The k-th largest value as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if the sequence is empty</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if k is not a value between 1 and the sequence size</xqdoc:error>']},{isDocumented:!0,arity:1,name:"max",qname:"excel:max",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Returns the largest number in a sequence.\n",summary:"<p> Returns the largest number in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric. The sequence can be of any length.</div>'}],returns:{type:"xs:anyAtomicType",description:"The max"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"maxa",qname:"excel:maxa",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Returns the largest value in a list of arguments.\n In this implementation there is no difference between MAX and MAXA.\n",summary:"<p> Returns the largest value in a list of arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric The sequence can be of any length.</div>'}],returns:{type:"xs:anyAtomicType",description:"The max"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"median",qname:"excel:median",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Returns the median of the given numbers.\n The median is the number in the middle of a set of numbers.\n Half the numbers have values that are greater than the median,\n and half the numbers have values that are less than the median.\n",summary:"<p> Returns the median of the given numbers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers, of any length</div>'}],returns:{type:"xs:anyAtomicType",description:"for odd count of numbers return the number in the middle of the sorted sequence. For even count of numbers return the average of the two numbers in the middle."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"min",qname:"excel:min",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Returns the smallest number in a sequence.\n",summary:"<p> Returns the smallest number in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric. The sequence can be of any length.</div>'}],returns:{type:"xs:anyAtomicType",description:"The min"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"mina",qname:"excel:mina",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Returns the smallest value in a list of arguments.\n In this implementation there is no difference between MAX and MAXA.\n",summary:"<p> Returns the smallest value in a list of arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric The sequence can be of any length.</div>'}],returns:{type:"xs:anyAtomicType",description:"The min"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"mode",qname:"excel:mode",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Returns the most frequently occurring, or repetitive, value in a sequence.\n Arguments must be castable to numeric.\n",summary:"<p> Returns the most frequently occurring, or repetitive, value in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers, of any length</div>'}],returns:{type:"xs:anyAtomicType",description:"The most occuring number"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">fn:QName("http://zorba.io/modules/excel/errors", "excel-err:NA") if there are no duplicate numbers</xqdoc:error>']},{isDocumented:!0,arity:2,name:"percentile",qname:"excel:percentile",signature:"($numbers as xs:anyAtomicType*, $k_at as xs:anyAtomicType) as xs:anyAtomicType",description:" Returns the k-th percentile of values in a sequence.\n If k is not a multiple of 1/(n - 1),\n   PERCENTILE interpolates to determine the value at the k-th percentile.\n The function is computed by (max-min)*k + min\n",summary:"<p> Returns the k-th percentile of values in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers, of any length</div>'},{name:"k_at",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the percentile, with value between 0 .. 1 inclusive</div>'}],returns:{type:"xs:anyAtomicType",description:"The computed percentile"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if percentile is not between 0 .. 1</xqdoc:error>']},{isDocumented:!0,arity:2,name:"percentrank",qname:"excel:percentrank",signature:"($numbers as xs:anyAtomicType*, $x as xs:anyAtomicType) as xs:decimal",description:' Returns the rank of a value in a data set as a percentage of the data set.\n If x does not match one of the values in array,\n   PERCENTRANK interpolates to return the correct percentage rank. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is uses: (RANK - 1) / (size - 1) .\n',summary:"<p> Returns the rank of a value in a data set as a percentage of the data set.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numbers. The sequence can be of any length, from 1 up.</div>'},{name:"x",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the value for which you want to know the rank</div>'}],returns:{type:"xs:decimal",description:"The percentage of rank."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if the sequence is zero length</xqdoc:error>']},{isDocumented:!0,arity:3,name:"prob",qname:"excel:prob",signature:"($x_range as xs:anyAtomicType+, $prob_range as xs:anyAtomicType+, $range_lower_limit as xs:anyAtomicType) as xs:anyAtomicType",description:" This is the same as above, only that upper_limit is not specified.\n The probability is computed only for range_lower_limit.\n",summary:"<p> This is the same as above, only that upper_limit is not specified.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x_range",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the range of numeric values of x with which there are associated probabilities. This does not need to be ordered.</div>'},{name:"prob_range",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is a set of probabilities associated with values in x_range.</div>'},{name:"range_lower_limit",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the value for which you want a probability.</div>'}],returns:{type:"xs:anyAtomicType",description:"The probability of the range_lower_limit value"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if any probability is not between 0 and 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if the sum of probabilities is not equal to 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if any parameter is not castable to numeric</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if x_range and prob_range do not have the same number of values</xqdoc:error>']},{isDocumented:!0,arity:4,name:"prob",qname:"excel:prob",signature:"($x_range as xs:anyAtomicType+, $prob_range as xs:anyAtomicType+, $range_lower_limit as xs:anyAtomicType, $upper_limit as xs:anyAtomicType) as xs:anyAtomicType",description:" Returns the probability that values in a range are between two limits.\n",summary:"<p> Returns the probability that values in a range are between two limits.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x_range",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the range of numeric values of x with which there are associated probabilities. This does not need to be ordered.</div>'},{name:"prob_range",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is a set of probabilities associated with values in x_range.</div>'},{name:"range_lower_limit",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the lower bound on the value for which you want a probability.</div>'},{name:"upper_limit",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the upper bound on the value for which you want a probability.</div>'}],returns:{type:"xs:anyAtomicType",description:"The probability of the entire range"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if any probability is not between 0 and 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if the sum of probabilities is not equal to 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if any parameter is not castable to numeric</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if x_range and prob_range do not have the same number of values</xqdoc:error>']},{isDocumented:!0,arity:2,name:"quartile",qname:"excel:quartile",signature:"($numbers as xs:anyAtomicType*, $quart as xs:integer) as xs:anyAtomicType",description:" Returns the quartile of a data set.\n",summary:"<p> Returns the quartile of a data set.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> sequence of numbers or values castable to numbers. The sequence can be of any length, from 1 up.</div>'},{name:"quart",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <dl>one of the values 0, 1, 2, 3, 4 with meaning: <dt>0</dt> <dd> compute minimum value</dd> <dt>1</dt> <dd> compute first quartile (25th percentile)</dd> <dt>2</dt> <dd> compute median value (50th percentile)</dd> <dt>3</dt> <dd> compute third quartile (75th percentile)</dd> <dt>4</dt> <dd> compute maximum value</dd></dl></div>'}],returns:{type:"xs:anyAtomicType",description:"the computed quartile, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if the sequence is zero length</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if $quart is not one of the values 0, 1, 2, 3, 4</xqdoc:error>']},{isDocumented:!0,arity:2,name:"rank",qname:"excel:rank",signature:"($x as xs:anyAtomicType, $numbers as xs:anyAtomicType*) as xs:decimal",description:" This RANK function is same as the above, only that $order_ascending is set by default to false.\n",summary:"<p> This RANK function is same as the above, only that $order_ascending is set by default to false.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number whose rank you want to find.</div>'},{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numbers. The sequence can be of any length.</div>'}],returns:{type:"xs:decimal",description:"The rank of $x."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"rank",qname:"excel:rank",signature:"($x as xs:anyAtomicType, $numbers as xs:anyAtomicType*, $order_ascending as xs:boolean) as xs:decimal",description:" Returns the rank of a number in a list of numbers.\n The rank of a number is its size relative to other values in a list.\n (If you were to sort the list, the rank of the number would be its position.)\n RANK gives duplicate numbers the same rank.\n",summary:"<p> Returns the rank of a number in a list of numbers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number whose rank you want to find.</div>'},{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of numbers or values castable to numbers. The sequence can be of any length.</div>'},{name:"order_ascending",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <dl>A boolean having the meaning: <dt>false</dt><dd>then rank the number as if the sequence was sorted in descending order.</dd> <dt>true</dt> <dd>then rank the number as if the sequence was sorted in ascending order.</dd></dl></div>'}],returns:{type:"xs:decimal",description:"The rank of $x."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"slope",qname:"excel:slope",signature:"($known_y as xs:anyAtomicType+, $known_x as xs:anyAtomicType+) as xs:anyAtomicType",description:' Returns the slope of the linear regression line through data points in known_y\'s and known_x\'s.\n The slope is the vertical distance divided by the horizontal distance between\n   any two points on the line, which is the rate of change along the regression line.\n It computes the formula:<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n sum((x - average_x)(y - average_y)) / sum((x - average_x)^2)  <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n where average_x and average_y are computed with AVERAGE function.\n',summary:"<p> Returns the slope of the linear regression line through data points in known_y's and known_x's.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"known_y",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of y numbers. The sequence can be of any length, from 1 up.</div>'},{name:"known_x",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of x numbers. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"The slope value, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if any parameter cannot be casted to numeric</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">fn:QName("http://zorba.io/modules/excel/errors", "excel-err:NA") if there are different numbers of x\'s and y\'s</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">fn:QName("http://zorba.io/modules/excel/errors", "excel-err:NA") if any sequence is empty</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Div0 if all x\'s are equal</xqdoc:error>']},{isDocumented:!0,arity:2,name:"small",qname:"excel:small",signature:"($numbers as xs:anyAtomicType*, $k as xs:integer) as xs:anyAtomicType",description:" This function computes the k-th smallest value in a data set.\n Use this function to return values with a particular relative standing in a data set.\n If n is the number of data points in array, SMALL(array,1) equals the smallest value,\n   and SMALL(array,n) equals the largest value.\n",summary:"<p> This function computes the k-th smallest value in a data set.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of numbers or values castable to numeric. The sequence can be of any length, from 1 up.</div>'},{name:"k",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The position (from the smallest) in the sequence of data to return. Must have value between 1 and size of sequence.</div>'}],returns:{type:"xs:anyAtomicType",description:"The k-th smallest value of $numbers."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if the sequence is zero length.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if $k is not a value between 1 and the size of sequence.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"standardize",qname:"excel:standardize",signature:"($x as xs:anyAtomicType, $mean as xs:anyAtomicType, $standard_dev as xs:anyAtomicType) as xs:double",description:' Returns a normalized value from a distribution characterized by mean and standard_dev.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is (x - mean) / standard_dev .\n',summary:"<p> Returns a normalized value from a distribution characterized by mean and standard_dev.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the value you want to normalize</div>'},{name:"mean",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the arithmetic mean of the distribution.</div>'},{name:"standard_dev",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the standard deviation of the distribution.</div>'}],returns:{type:"xs:double",description:"The normalized x, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if any parameter cannot be casted to numeric</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if standard_dev is a value smaller than zero or equal</xqdoc:error>']},{isDocumented:!0,arity:1,name:"var",qname:"excel:var",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:' Estimates variance based on a sample.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is sum(x - average_x)^2 / (n - 1).<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n average_x is computed with AVERAGE function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n n is the count of numbers from the sequence, excluding empty values.\n',summary:"<p> Estimates variance based on a sample.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"The variance, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"vara",qname:"excel:vara",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:' Estimates variance based on a sample.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is sum(x - average_x)^2 / (n - 1).<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n average_x is computed with AVERAGE function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n n is the size of sequence, including empty values.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Estimates variance based on a sample.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"The variance, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"varp",qname:"excel:varp",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:' Calculates variance based on the entire population.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is sum(x - average_x)^2 / n.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n average_x is computed with AVERAGE function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n n is the count of numbers from the sequence, excluding empty values.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Calculates variance based on the entire population.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"The variance, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"varpa",qname:"excel:varpa",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:' Calculates variance based on the entire population.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The formula is sum(x - average_x)^2 / n.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n average_x is computed with AVERAGE function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n n is the size of sequence, including empty values.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Calculates variance based on the entire population.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric. The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"The variance, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']}],variables:[]},"http://www.zorba-xquery.com/modules/languages/xslt":{ns:"http://www.zorba-xquery.com/modules/languages/xslt",description:' This module provides XSLT 1.0 transformation functionality.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For details on XSLT see\n <a href="http://www.w3.org/TR/xslt">XSLT 1.0 specification</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module implements the invoking of an XSLT transformation from XQuery\n described in <a href="http://lists.w3.org/Archives/Member/w3c-xsl-wg/2008Apr/0052.html">\n    Michael Kay\'s proposal</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre class="ace-static" ace-mode="xquery">import module namespace\n        xslt = "http://www.zorba-xquery.com/modules/languages/xslt";\n let $source :=\n     &lt;catalog&gt;\n         &lt;cd&gt;\n           &lt;title&gt;Empire Burlesque&lt;/title&gt;\n           &lt;artist&gt;Bob Dylan&lt;/artist&gt;\n           &lt;country&gt;USA&lt;/country&gt;\n           &lt;company&gt;Columbia&lt;/company&gt;\n           &lt;price&gt;10.90&lt;/price&gt;\n           &lt;year&gt;1985&lt;/year&gt;\n         &lt;/cd&gt;\n         &lt;cd&gt;\n           &lt;title&gt;Hide your heart&lt;/title&gt;\n           &lt;artist&gt;Bonnie Tyler&lt;/artist&gt;\n           &lt;country&gt;UK&lt;/country&gt;\n           &lt;company&gt;CBS Records&lt;/company&gt;\n           &lt;price&gt;9.90&lt;/price&gt;\n           &lt;year&gt;1988&lt;/year&gt;\n         &lt;/cd&gt;\n     &lt;/catalog&gt;\n let $stylesheet :=\n   &lt;xsl:stylesheet version="1.0"\n       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;\n     &lt;xsl:template match="/"&gt;\n       &lt;html&gt;\n       &lt;body&gt;\n       &lt;h2&gt;Music Collection&amp;lt;/h2&gt;\n         &lt;table border="1"&gt;\n           &lt;tr bgcolor="lightblue"&gt;\n             &lt;th&gt;Title&amp;lt;/th&gt;\n             &lt;th&gt;Artist&amp;lt;/th&gt;\n           &lt;/tr&gt;\n           &lt;xsl:for-each select="catalog/cd"&gt;\n            &lt;tr&gt;\n              &lt;td&gt;&amp;lt;xsl:value-of select="title"/&gt;&lt;/td&gt;\n              &lt;td&gt;&amp;lt;xsl:value-of select="artist"/&gt;&lt;/td&gt;\n           &lt;/tr&gt;\n           &lt;/xsl:for-each&gt;\n         &lt;/table&gt;\n       &lt;/body&gt;\n       &lt;/html&gt;\n     &lt;/xsl:template&gt;\n   &lt;/xsl:stylesheet&gt;\n return\n   xslt:transform( $source, $stylesheet)</pre></p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Cezar Andrei</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://www.zorba-xquery.com/modules/languages/xslt",prefix:"xslt"}],functions:[{isDocumented:!0,arity:2,name:"transform",qname:"xslt:transform",signature:"($source as node(), $stylesheet as node()) as node() external",description:'<p xmlns:xqdoc="http://www.xqdoc.org/1.0">Invokes an XSLT transformation.</p>\n',summary:"<p>Invokes an XSLT transformation.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"source",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the input document to the transformation</div>'},{name:"stylesheet",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the XSLT stylesheet module</div>'}],returns:{type:"node()",description:"the result tree produced by the transformation"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">xslt:XSLT001 if $stylesheet is not a valid XSLT stylesheet</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">xslt:XSLT002 if result can not be imported</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/data-cleaning/phonetic-string-similarity":{ns:"http://zorba.io/modules/data-cleaning/phonetic-string-similarity",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This library module provides phonetic string similarity functions, comparing strings with basis on how they sound.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">These metrics are particularly effective in matching names, since names are often spelled in different\n ways that sound the same.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The logic contained in this module is not specific to any particular XQuery implementation.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Bruno Martins</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/data-cleaning/phonetic-string-similarity",prefix:"simp"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"metaphone-key",qname:"simp:metaphone-key",signature:"($s1 as xs:string) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Metaphone key for a given string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The Metaphone algorithm produces variable length keys as its output, as opposed to Soundex\'s fixed-length keys.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">metaphone-key("ALEKSANDER")</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">"ALKSNTR"</pre></p>\n',summary:"<p>  Returns the Metaphone key for a given string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string.</div>'}],returns:{type:"xs:string",description:"The Metaphone key for the given input string."},errors:[]},{isDocumented:!0,arity:2,name:"metaphone",qname:"simp:metaphone",signature:"($s1 as xs:string, $s2 as xs:string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Checks if two strings have the same Metaphone key.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">metaphone("ALEKSANDER", "ALEXANDRE")</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">true</pre></p>\n',summary:"<p>  Checks if two strings have the same Metaphone key.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'}],returns:{type:"xs:boolean",description:"Returns true if both strings have the same Metaphone key and false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"soundex-key",qname:"simp:soundex-key",signature:"($s1 as xs:string) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Soundex key for a given string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">soundex-key("Robert")</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">"R163"</pre></p>\n',summary:"<p>  Returns the Soundex key for a given string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string.</div>'}],returns:{type:"xs:string",description:"The Soundex key for the given input string."},errors:[]},{isDocumented:!0,arity:2,name:"soundex",qname:"simp:soundex",signature:"($s1 as xs:string, $s2 as xs:string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Checks if two strings have the same Soundex key.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">soundex( "Robert" , "Rupert" )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">true</pre></p>\n',summary:"<p>  Checks if two strings have the same Soundex key.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'}],returns:{type:"xs:boolean",description:"Returns true if both strings have the same Soundex key and false otherwise."},errors:[]}],variables:[]},"http://www.28msec.com/modules/collections":{ns:"http://www.28msec.com/modules/collections",description:" This module provides functions to work with collections. For example,\n it contains functions to retrieve the content of a collection or the\n names of all collections.\n <p xmlns:xqdoc=\"http://www.xqdoc.org/1.0\">The module is always imported so you don't need to import it explicitly.\n Also, you don't need to fully qualify a function to invoke it.</p>\n",sees:[],authors:[],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:2,name:"apply-insert",qname:"db:apply-insert",signature:"($name as string, $content as item()*) as item()* external",description:" This function does the same as the insert function and it immediately applies\n the resulting pending updates and returns the items that have been inserted.\n Note that each item in the content sequence is copied before insertion. This\n function provides an efficient way to retrieve the actual copies that have\n been inserted.\n",summary:"<p> This function does the same as the insert function and it immediately applies\n the resulting pending updates and returns the items that have been inserted.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to which the items should be added.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequences of items whose copies should be added to the collection.</div>'}],returns:{type:"item()*",description:"The result of the function is the sequence of items that have been inserted into the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection identified by <tt>$name</tt> does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if any of the items in the $content do not match the expected type (as specified in the collection declaration) or are not XML documents, XML elements, JSON objects, or JSON arrays.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"available-collections",qname:"db:available-collections",signature:"() as string* external",description:" Return the names of all existing collections.\n",summary:"<p> Return the names of all existing collections.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"string*",description:"The names of all existing collections."},errors:[]},{isDocumented:!0,arity:1,name:"collection-name",qname:"db:collection-name",signature:"($o as item()) as string external",description:" The collection-name function returns the name of the containing collection\n of the given item.\n",summary:"<p> The collection-name function returns the name of the containing collection\n of the given item.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"o",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The item for which to get the name of the collection.</div>'}],returns:{type:"string",description:"The name of the containing collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if the given item does not belong to a collection.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"collection",qname:"db:collection",signature:"($name as string) as item()* external",description:' The collection function returns the sequence of items that belong\n to the collection identified by the given name.\n Please note that the order of the items returned is not deterministic,\n i.e. it might change between invocations. You can use\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">db:collection($name, 0)</tt> to get a deterministic order.\n',summary:"<p> The collection function returns the sequence of items that belong\n to the collection identified by the given name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection.</div>'}],returns:{type:"item()*",description:"The content of the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection identified by $name does not exist.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"collection",qname:"db:collection",signature:"($name as string, $skip as integer) as item()* external",description:' The collection function returns the sequence of items that belong to\n the collection identified\n by the given name. The skip parameter allows to (efficiently) skip\n a given number of items.\n Note that the collections are generally unordered. However, there\n is an implicit deterministic ordering (i.e. sorting by the _id field\n in MongoDB) that is used by this function. This ordering is not present\n for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">db:collection#1</tt> function. In order to return items with\n a stable ordering, db:collection($name, 0) can be used.\n',summary:"<p> The collection function returns the sequence of items that belong to\n the collection identified\n by the given name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection.</div>'},{name:"skip",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of items to skip starting from the beginning.</div>'}],returns:{type:"item()*",description:'The content of the collection starting at the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$skip</tt>+1 item.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection identified by $name does not exist</xqdoc:error>']},{isDocumented:!0,arity:3,name:"collection",qname:"db:collection",signature:"($name as string, $start as string, $skip as integer) as item()* external",description:' The collection function returns the sequence of items that belong to\n the collection identified\n by the given name. The start parameter is a reference and determines\n the first item to return. The skip parameter allows to (efficiently) skip\n a given number of items starting at the item referenced by <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$start</tt>.\n The start parameter is useful for efficiently implementing pagination.\n Note that the collections are generally unordered. However, there\n is an implicit deterministic ordering (i.e. sorting by the _id field\n in MongoDB) that is used by this function. This ordering is not present\n for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">db:collection#1</tt> function. In order to return items with\n a stable ordering, db:collection($name, $start, 0) can be used.\n Example:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n import module namespace ref = "http://zorba.io/modules/reference";\n let $ref := ref:reference(db:collection("test", 1)[1])\n return\n   db:collection("test", $ref, 1)\n </pre>\n',summary:"<p> The collection function returns the sequence of items that belong to\n the collection identified\n by the given name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection.</div>'},{name:"start",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The reference to the first item to return.</div>'},{name:"skip",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of collection items to skip.</div>'}],returns:{type:"item()*",description:'The content of the collection starting at the item referenced by <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$start</tt> and skipping <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$skip</tt> items.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection identified by <tt>$name</tt> does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 If the given reference $start is not a valid reference.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZSTR0066 if the given reference $start does not reference an item of this collection.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"create",qname:"db:create",signature:"($name as string) external",description:' The create function is an updating function that creates\n a new collection with the given name.\n It is not possible to create collections that start with\n "system." or "_28" (zerr:ZDDY1000).\n Collections are identified by a name (string). Names are not allowed to\n contain the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$</tt> sign or exceed the length of 70 characters.\n This is consistent with the restrictions for names of collections in MongoDB.\n',summary:"<p> The create function is an updating function that creates\n a new collection with the given name.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to create.</div>'}],returns:{type:null,description:"The result of the function is an empty XDM instance and a pending update list which, once applied, creates a collection with the given name."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0002 if a collection with the given name already exists.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY1000 if the given name is not a legal collection name</xqdoc:error>']},{isDocumented:!0,arity:2,name:"create",qname:"db:create",signature:"($name as string, $content as item()*) external",description:' The create function is an updating function which creates\n a new collection with the given name. Moreover, it adds copies\n of the sequence <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$content</tt> to the new collection.\n It is not possible to create collections that start with\n "system." or "_28" (zerr:ZDDY1000).\n Collections are identified by a name (string). Names are not allowed to\n contain the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$</tt> sign or exceed the length of 70 characters.\n This is consistent with the restrictions for names of collections in MongoDB.\n',summary:"<p> The create function is an updating function which creates\n a new collection with the given name.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string of the collection to create.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequences of items that should be added to the new collection.</div>'}],returns:{type:null,description:"The result of the function is an empty XDM instance and a pending update list which, once applied, creates a collection with the given name and inserts the given items into it."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0002 if a collection with the given name already exists.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if any of the items in the $content do not match the expected type (as specified in the collection declaration) or are not XML documents, XML elements, JSON objects, or JSON arrays.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY1000 if the given name is not a legal collection name</xqdoc:error>']},{isDocumented:!0,arity:1,name:"delete",qname:"db:delete",signature:"($target as item()*) external",description:" The delete function is an updating function that deletes zero or more items\n (JSON objects, JSON arrays, or XML nodes) from a collection.\n Please note that the all of the items belong to the same collection\n (zerr:ZDDY0011).\n",summary:"<p> The delete function is an updating function that deletes zero or more items\n (JSON objects, JSON arrays, or XML nodes) from a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"target",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the items that should be deleted from the containing collection.</div>'}],returns:{type:null,description:"The result of this function is an empty XDM instance and a pending update list which, once applied, deletes the items from the collections."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection identified by <tt>$name</tt> does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if any item in the <tt>$target</tt> sequence is not a member of a collection or not all items belong to the same collection.</xqdoc:error>']},{isDocumented:!1,arity:1,name:"drop",qname:"db:drop",signature:"($name as string) external",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!0,arity:2,name:"edit",qname:"db:edit",signature:"($target as item(), $content as item()) external",description:" The edit function is an updating function that edits the first supplied\n item so as to make it look exactly like a copy of the second supplied item,\n while retaining its original identity.\n",summary:"<p> The edit function is an updating function that edits the first supplied\n item so as to make it look exactly like a copy of the second supplied item,\n while retaining its original identity.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"target",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The target item, that must be edited.</div>'},{name:"content",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The content item, that serves as an edit goal.</div>'}],returns:{type:null,description:"The result of the function is an empty XDM instance and a pending update list which, once applied, performs the edit."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0017 if the $target item is not a member of a collection.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0040 if the target cannot be updated to match the content (for example because the target is a node and the content is an object).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if $content does not match the expected type (as specified in the collection declaration) according to the rules for SequenceType Matching.</xqdoc:error>']},{isDocumented:!1,arity:1,name:"index-keys",qname:"db:index-keys",signature:"($index-name as string) as array()* external",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"index-name",type:"string",occurrence:null,description:""}],returns:{type:"array()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"insert",qname:"db:insert",signature:"($name as string, $content as item()*) external",description:" The insert function is an updating function that inserts copies of the given\n items into a collection.\n",summary:"<p> The insert function is an updating function that inserts copies of the given\n items into a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to which the items should be added.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequences of items whose copies should be added.</div>'}],returns:{type:null,description:"The result of the function is an empty XDM instance and a pending update list which, once applied, inserts the items into the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection identified by <tt>$name</tt> does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if any of the items in the $content do not match the expected type (as specified in the collection declaration) or are not XML documents, XML elements, JSON objects, or JSON arrays.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-available-collection",qname:"db:is-available-collection",signature:"($name as string) as boolean external",description:" Determine if the collection with the given name exists.\n",summary:"<p> Determine if the collection with the given name exists.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string of the collection in question.</div>'}],returns:{type:"boolean",description:"true if collection with the given name exists, false otherwise."},errors:[]},{isDocumented:!1,arity:2,name:"lookup",qname:"db:lookup",signature:"($index-name as string, $key as item()) as item()* external",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"index-name",type:"string",occurrence:null,description:""},{name:"key",type:"item()",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!1,arity:3,name:"lookup",qname:"db:lookup",signature:"($index-name as string, $keys as item(), $skip as integer) as item()* external",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"index-name",type:"string",occurrence:null,description:""},{name:"keys",type:"item()",occurrence:null,description:""},{name:"skip",type:"integer",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!1,arity:1,name:"refresh",qname:"db:refresh",signature:"($index-name as string) external",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"index-name",type:"string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!0,arity:1,name:"truncate",qname:"db:truncate",signature:"($name as string) external",description:" The truncate function is an updating function that deletes the\n entire content of a given collection.\n Please note that applying this function can not be undone in case\n an error happens during the application of the containing PUL.\n",summary:"<p> The truncate function is an updating function that deletes the\n entire content of a given collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection whose content to delete.</div>'}],returns:{type:null,description:"The result of this function is an empty XDM instance and a pending update list which, once applied, deletes the nodes."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection identified by <tt>$name</tt> does not exist.</xqdoc:error>']}],variables:[]},"http://expath.org/ns/http-client":{ns:"http://expath.org/ns/http-client",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This module provides an implementation of the\n <a href="http://expath.org/modules/http-client/">EXPath Http Client</a>.\n It provides functions for making HTTP requests and is a superset of the\n module specified by EXPath.\n Specifically, it implements the <code>http:send-request()</code> functions\n as specified by EXPath. Moreover, it adds an additional function\n <code>http:read()</code> (with several arities for the sake of ease).\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n In general, both functions take a description of the HTTP request to make\n as parameter, execute the request, and return a representation of the HTTP\n response. For instance, in the following code snippet, we fetch the Zorba\n home page:\n </p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">import module namespace http = "http://expath.org/ns/http-client";\n http:send-request(\n  &lt;http:request href="http://zorba.io" method="get" /&gt;\n )\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The <code>http:send-request()</code> functions are declared as sequential.\n Sequential functions are allowed to have side effects. For example, most probably,\n an HTTP POST request is a request that has side effects because it adds/changes\n a remote resource. Sequential functions are specified in the\n <a href="http://zorba.io/documentation/2.9/zorba/scripting_tutorial.html">XQuery Scripting Extension</a>.\n In contrast, the http:read() functions are not declared as sequential -\n they are declared as being non deterministic though, which\n means that several calls may return different results.\n HTTP requests performed using these functions are <b>not</b> allowed to have\n side effects.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The response is returned as a sequence of one or more items. The first\n one is an <code>http:response</code> element with quite the same\n structure as an http:request, but without the content itself.\n The content is returned as the second item (or several items in case of\n a multipart response) as a string, a document node, or a binary item.\n This depends on the content-type returned.\n Specifically, the rules are as follows:\n <ul>\n  <li>A document node is returned if the media type has a MIME type of\n     text/xml, application/xml, text/xml-external-parsed-entity, or\n     application/xml-external-parsed-entity, as defined in [RFC 3023]\n     (except that application/xml-dtd is considered a text media type).\n     MIME types ending by +xml are also XML media types.</li>\n  <li>A document node is returned if the media type has a MIME type of\n      text/html. In order to be able to make HTML parseable, tidy is automatically\n      invoked. If you want to prevent that, you can also set your own content-type\n      by setting the override-media-type attribute in the request element.\n       For tidying, the following <a href="http://tidy.sourceforge.net/docs/quickref.html">options</a>\n       will be used:\n       <ul>\n         <li>TidyXmlOut=yes</li>\n         <li>TidyDoctypeMode=TidyDoctypeOmit</li>\n         <li>TidyQuoteNbsp=yes</li>\n         <li>TidyCharEncoding="utf8"</li>\n         <li>TidyNewline="LF"</li>\n       </ul>\n  </li>\n  <li>An xs:string item is returned if the media type has a text MIME type,\n     i.e. beginning with text/.</li>\n  <li>An xs:base64Binary item is returned for all the other media types.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The structure of a request element is defined in the schema that is imported\n by this module. The details are described in the\n <a href="http://expath.org/spec/http-client#d2e183">specification</a>.\n Analogously, the response element is also described in this\n <a href="http://expath.org/spec/http-client#d2e491">specification</a>.\n </p>\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.w3.org/TR/xquery-3/#FunctionDeclns">XQuery 3.0: Function Declaration</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri, Markus Pilman</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://expath.org/ns/error",prefix:"err"},{uri:"http://expath.org/ns/http-client",prefix:"http"},{uri:"http://zorba.io/modules/http-client-wrapper",prefix:"http-wrapper"},{uri:"http://expath.org/ns/http-client",prefix:"https"},{uri:"http://www.zorba-xquery.com/modules/converters/html",prefix:"tidy"},{uri:"http://www.zorba-xquery.com/modules/converters/html-options",prefix:"tidy-options"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"send-request",qname:"http:send-request",signature:"($request as element(*)) as item()+",description:' Function for convenience.\n Calling this function is equivalent to calling\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">\n http:send-request($request, (), ())\n </code>\n',summary:"<p> Function for convenience.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"request",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> see request parameter of the sequential <a href="#send-request-3">send-request</a> function with three parameters.</div>'}],returns:{type:"item()+",description:'see return value of the sequential <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#send-request-3">send-request</a> function with three parameters.'},errors:[]},{isDocumented:!0,arity:2,name:"send-request",qname:"http:send-request",signature:"($request as element(*)?, $href as xs:string?) as item()+",description:' Function for convenience.\n Calling this function is equivalent to calling\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">\n http:send-request($request, $href, ())\n </code>\n',summary:"<p> Function for convenience.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"request",type:"element(*)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> see request parameter of the sequential <a href="#send-request-3">send-request</a> function with three parameters.</div>'},{name:"href",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> see href parameter of the sequential <a href="#send-request-3">send-request</a> function with three parameters.</div>'}],returns:{type:"item()+",description:'see return of <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#send-request-3">send-request</a>'},errors:[]},{isDocumented:!0,arity:3,name:"send-request",qname:"http:send-request",signature:"($request as element(*)?, $href as xs:string?, $bodies as item()*) as item()+",description:' This function sends an HTTP request and returns the corresponding response.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function is declared as sequential (see XQuery Scripting).\n Sequential functions are allowed to have side effects. For example, most probably,\n an HTTP POST request is a request that has side effects because it adds/changes\n a remote resource.\n </p>\n',summary:"<p> This function sends an HTTP request and returns the corresponding response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"request",type:"element(*)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Contains the various parameters of the request. See the <a href="http://expath.org/spec/http-client#d2e183">specification</a>. for a full description of the structure of this element.</div>'},{name:"href",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the HTTP or HTTPS URI to send the request to. It must be a valid xs:anyURI, but is declared as a string to be able to pass literal strings (without requiring to explicitly cast it to an xs:anyURI.)</div>'},{name:"bodies",type:"item()",occurrence:"*",description:""}],returns:{type:"item()+",description:'a sequence of items, where the first item is a element of type http:responseType. The response element is also described in the <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://expath.org/spec/http-client#d2e483">specification</a>. If there is one (or several, in case of multipart) response body, the response bodies are the next items in the sequence.'},errors:[]}],variables:[]},"http://zorba.io/modules/schema":{ns:"http://zorba.io/modules/schema",description:" This module provides function that are related to XML Schema support\n in Zorba.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Cezar Andrei, Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/schema",prefix:"schema"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"is-validated",qname:"schema:is-validated",signature:"($node as node()) as xs:boolean external",description:" This function returns true if the given node has been validated,\n and false otherwise.\n",summary:"<p> This function returns true if the given node has been validated,\n and false otherwise.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node item that should be checked for validation</div>'}],returns:{type:"xs:boolean",description:"true if the given node has been validated, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"schema-type",qname:"schema:schema-type",signature:"($item as item()) as xs:QName? external",description:" This function returns the name of the type of the item passed\n as parameter.\n",summary:"<p> This function returns the name of the type of the item passed\n as parameter.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"item",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the item from which the name of the type should be returned.</div>'}],returns:{type:"xs:QName?",description:"the name of the type (as QName) of the item passed as parameter."},errors:[]},{isDocumented:!0,arity:1,name:"validate-in-place",qname:"schema:validate-in-place",signature:"($node as node()) external",description:" Updating function that validates the document in place. After the updating\n query is applied the $node will contain the validated content.\n",summary:"<p> Updating function that validates the document in place.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"node",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the document or element to be validated, otherwise error</div>'}],returns:{type:null,description:"The result of the function is an empty XDM instance and a pending update list that consists the schema:validate-in-place($node)) primitive."},errors:[]}],variables:[]},"http://www.28msec.com/modules/mongodb":{ns:"http://www.28msec.com/modules/mongodb",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides a driver to access a\n <a href="http://www.mongodb.org/">MongoDB</a> database - similar to\n drivers for other high-level languages like e.g.\n <a href="http://api.mongodb.org/python/current/">PyMongo</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Here is a simple example of how we can raise the salary of each\n developer by 10%.\n Starting with an <em>employees</em> collection in MongoDB that contains\n <pre>\n { "name" : "Peter", "role" : "developer" , "salary" : 80 }\n { "name" : "Paul",  "role" : "developer" , "salary" : 75 }\n { "name" : "Mary",  "role" : "manager"   , "salary" : 90 } </pre>\n we can get a connection\n <pre>\n variable $conn := mongo:connect("hostname", 27017, "db", "user", "password");\n </pre>\n run this update\n <pre>\n for $emp in mongo:find($conn, "employees")\n where $emp("role") = "developer"\n let $salary := $emp("salary")\n return {\n   replace value of json $emp("salary") with $salary * 1.1;\n   mongo:save($conn, "employees", $emp)\n };\n </pre>\n and get the names and the current salaries using\n <pre>\n mongo:find($conn, "employees", {}, { "_id" : false, "role" : false }, {}) </pre>\n In this query we have removed the <em>_id</em> and <em>role</em> fields from\n the results and get\n <pre>\n { "name" : "Peter", "salary" : 88   }\n { "name" : "Paul",  "salary" : 82.5 }\n { "name" : "Mary",  "salary" : 90   }\n </pre>\n </p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="determinism">Important Notice Regarding Function Determinism</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The non side-effecting functions:\n <ul>\n   <li><a href="?anchor=connect-0">connect#0</a></li>\n   <li><a href="?anchor=connect-1">connect#1</a></li>\n   <li><a href="?anchor=connect-2">connect#2</a></li>\n   <li><a href="?anchor=connect-5">connect#5</a></li>\n   <li><a href="?anchor=collection-names-1">collection-names#1</a></li>\n   <li><a href="?anchor=count-2">count#2</a></li>\n   <li><a href="?anchor=count-3">count#3</a></li>\n   <li><a href="?anchor=find-2">find#2</a></li>\n   <li><a href="?anchor=find-3">find#3</a></li>\n   <li><a href="?anchor=find-4">find#4</a></li>\n   <li><a href="?anchor=find-5">find#5</a></li>\n </ul>\n are declared deterministic, which means that their results could be cached\n when invoked multiple times with the same arguments in the same query execution.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To not use cached results you can use the following alternative functions:\n <ul>\n   <li><a href="?anchor=connect-nondeterministic-0">connect-nondeterministic#0</a></li>\n   <li><a href="?anchor=connect-nondeterministic-1">connect-nondeterministic#1</a></li>\n   <li><a href="?anchor=connect-nondeterministic-2">connect-nondeterministic#2</a></li>\n   <li><a href="?anchor=connect-nondeterministic-5">connect-nondeterministic#5</a></li>\n   <li><a href="?anchor=collection-names-nondeterministic-1">collection-names-nondeterministic#1</a></li>\n   <li><a href="?anchor=count-nondeterministic-2">count-nondeterministic#2</a></li>\n   <li><a href="?anchor=count-nondeterministic-3">count-nondeterministic#3</a></li>\n   <li><a href="?anchor=find-nondeterministic-2">find-nondeterministic#2</a></li>\n   <li><a href="?anchor=find-nondeterministic-3">find-nondeterministic#3</a></li>\n   <li><a href="?anchor=find-nondeterministic-4">find-nondeterministic#4</a></li>\n   <li><a href="?anchor=find-nondeterministic-5">find-nondeterministic#5</a></li>\n </ul>\n which have been declared as being non deterministic.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Three different functions have been defined to run mongo commands:\n <ul>\n   <li><a href="?anchor=run-cmd-2">run-cmd#2</a></li>\n   <li><a href="?anchor=run-cmd-nondeterministic-2">run-cmd-nondeterministic#2</a></li>\n   <li><a href="?anchor=run-cmd-deterministic-2">run-cmd-deterministic#2</a></li>\n </ul>\n If your application depends on the ordering of side-effects from commands issued\n through these functions you should use <a href="?anchor=run-cmd-2">run-cmd#2</a>,\n which has been declared as sequential.\n For non-side-effecting commands you can also use\n <a href="?anchor=run-cmd-nondeterministic-2">run-cmd-nondeterministic#2</a> and\n <a href="?anchor=run-cmd-deterministic-2">run-cmd-deterministic#2</a>.\n The results of commands executed by means of\n <a href="?anchor=run-cmd-deterministic-2">run-cmd-deterministic#2</a> (which is\n declared <i>deterministic</i>) could be cached, whereas the results of\n commands executed by means of\n <a href="?anchor=run-cmd-nondeterministic-2">run-cmd-nondeterministic#2</a> (which is\n declared <i>non-deterministic</i>) are never cached.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://www.28msec.com/modules/mongodb/types",prefix:"m-schema"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"collection-names-nondeterministic",qname:"mongo:collection-names-nondeterministic",signature:"($db as xs:anyURI) as xs:string* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Get a list of all the collection names in this database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#collection-names-1">collection-names#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Get a list of all the collection names in this database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'}],returns:{type:"xs:string*",description:"a list of the names of all collection in the given database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:1,name:"collection-names",qname:"mongo:collection-names",signature:"($db as xs:anyURI) as xs:string* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Get a list of all the collection names in this database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p>  Get a list of all the collection names in this database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'}],returns:{type:"xs:string*",description:"a list of the names of all collection in the given database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:0,name:"connect-nondeterministic",qname:"mongo:connect-nondeterministic",signature:"() as xs:anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Connect to this project\'s default MongoDB database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#connect-0">connect#0</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Connect to this project's default MongoDB database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"xs:anyURI",description:"an identifier for a connection to the MongoDB database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO002 connection to MongoDB failed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO003 authentication to the MongoDB database failed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"connect-nondeterministic",qname:"mongo:connect-nondeterministic",signature:"($connection-config as item()) as xs:anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Connect to a MongoDB database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#connect-1">connect#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Connect to a MongoDB database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection-config",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the connection specification.</div>'}],returns:{type:"xs:anyURI",description:"an identifier for a connection to the MongoDB database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO001 if the connection specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO002 connection to MongoDB failed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO003 authentication to the MongoDB database failed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"connect-nondeterministic",qname:"mongo:connect-nondeterministic",signature:"($credentials-name as xs:string?, $options as object()) as xs:anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Connect to a MongoDB database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#connect-2">connect#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Connect to a MongoDB database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"credentials-name",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the credentials to use.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the credentials to use.</div>'}],returns:{type:"xs:anyURI",description:"an identifier for a connection to the MongoDB database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO001 if the connection specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO002 connection to MongoDB failed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO003 authentication to the MongoDB database failed</xqdoc:error>']},{isDocumented:!0,arity:5,name:"connect-nondeterministic",qname:"mongo:connect-nondeterministic",signature:"($host as xs:string, $port as xs:integer?, $db as xs:string, $user as xs:string?, $pass as xs:string?) as xs:anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Connect to a MongoDB database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#connect-5">connect#5</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Connect to a MongoDB database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the host to connect to</div>'},{name:"port",type:"xs:integer",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the port to connect to</div>'},{name:"db",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the database to connect to</div>'},{name:"user",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the user used to authorize access to the db</div>'},{name:"pass",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the password used to authorize access to the db</div>'}],returns:{type:"xs:anyURI",description:"an identifier for a connection to the MongoDB database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO002 connection to MongoDB failed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO003 authentication to the MongoDB database failed</xqdoc:error>']},{isDocumented:!0,arity:0,name:"connect",qname:"mongo:connect",signature:"() as xs:anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Connect to this project\'s default MongoDB database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p>  Connect to this project's default MongoDB database.</p>",annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[],returns:{type:"xs:anyURI",description:"an identifier for a connection to the MongoDB database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO002 connection to MongoDB failed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO003 authentication to the MongoDB database failed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"connect",qname:"mongo:connect",signature:"($connection-config as item()) as xs:anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Connect to a MongoDB database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The $connection-config parameter is used to specify the connection information.\n If a string is used, then the function will interpret it as the name of\n a credential in the MongoDB category.\n If an object is used, then the function will open a connection using it.\n The object structure is the following:\n <ul>\n   <li>host (string; mandatory)</li>\n   <li>port (integer; default: 27017)</li>\n   <li>db (string; mandatory)</li>\n   <li>user (string)</li>\n   <li>pass (string)</li>\n   <li>timeout (decimal; default: 0)</li>\n   <li>pre-digested (boolean; default: false)</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, using stored credential:\n <pre>mongo:connect("credentials-name")</pre>\n <p>For example, specifying the connection information:</p>\n <pre>mongo:connect(\n   {\n     "host": "hostname",\n     "port": 11011,\n     "db": "mydb",\n     "user": "myuser"\n     "password: "mypass"\n   })</pre>.\n </p>\n',summary:"<p>  Connect to a MongoDB database.</p>",annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[{name:"connection-config",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the connection specification.</div>'}],returns:{type:"xs:anyURI",description:"an identifier for a connection to the MongoDB database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO001 if the connection specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO002 connection to MongoDB failed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO003 authentication to the MongoDB database failed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"connect",qname:"mongo:connect",signature:"($credentials-name as xs:string?, $options as object()) as xs:anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Connect to a MongoDB database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The $credentials-name parameter is used to specify the connection information.\n If empty a connection will be opened to the project default MongoDB database.\n Otherwise, the function will use it to identify a credential in the MongoDB category.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"> The $options object can be used to specify connection options. The following\n fields are supported:\n <ul>\n   <li>timeout (decimal; default: 0)</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, connecting to the project default MongoDB database:\n <pre>mongo:connect((), {"timeout": 10})</pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, specifying the connection information:\n <pre>mongo:connect("credentials-name", {"timeout": 10})</pre>\n </p>\n',summary:"<p>  Connect to a MongoDB database.</p>",annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[{name:"credentials-name",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the credentials to use.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the credentials to use.</div>'}],returns:{type:"xs:anyURI",description:"an identifier for a connection to the MongoDB database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO001 if the connection specification is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO002 connection to MongoDB failed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO003 authentication to the MongoDB database failed</xqdoc:error>']},{isDocumented:!0,arity:5,name:"connect",qname:"mongo:connect",signature:"($host as xs:string, $port as xs:integer?, $db as xs:string, $user as xs:string?, $pass as xs:string?) as xs:anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Connect to a MongoDB database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p>  Connect to a MongoDB database.</p>",annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[{name:"host",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the host to connect to</div>'},{name:"port",type:"xs:integer",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the port to connect to</div>'},{name:"db",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the database to connect to</div>'},{name:"user",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the user used to authorize access to the db</div>'},{name:"pass",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the password used to authorize access to the db</div>'}],returns:{type:"xs:anyURI",description:"an identifier for a connection to the MongoDB database."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO002 connection to MongoDB failed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO003 authentication to the MongoDB database failed</xqdoc:error>']},{isDocumented:!0,arity:3,name:"copy",qname:"mongo:copy",signature:"($db as xs:anyURI, $from-db as xs:string, $to-db as xs:string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Copies a MongoDB database. Be aware, you must call\n this function on the admin database.</p>\n',summary:"<p>  Copies a MongoDB database.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"from-db",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the source database</div>'},{name:"to-db",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the target database</div>'}],returns:{type:"empty-sequence()",description:"the function has side-effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if copy operation fails</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:2,name:"count-nondeterministic",qname:"mongo:count-nondeterministic",signature:"($db as xs:anyURI, $coll as xs:string) as xs:integer external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Counts the number of documents in the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#count-2">count#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Counts the number of documents in the given collection.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'}],returns:{type:"xs:integer",description:"the said count"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:3,name:"count-nondeterministic",qname:"mongo:count-nondeterministic",signature:"($db as xs:anyURI, $coll as xs:string, $query as object()) as xs:integer external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Counts the number of documents satisfying the query in the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#count-3">count#3</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Counts the number of documents satisfying the query in the given collection.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query specifying which objects to count</div>'}],returns:{type:"xs:integer",description:"the said count"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:2,name:"count",qname:"mongo:count",signature:"($db as xs:anyURI, $coll as xs:string) as xs:integer external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Counts the number of documents in the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p>  Counts the number of documents in the given collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'}],returns:{type:"xs:integer",description:"the said count"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:3,name:"count",qname:"mongo:count",signature:"($db as xs:anyURI, $coll as xs:string, $query as object()) as xs:integer external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Counts the number of documents satisfying the query in the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p>  Counts the number of documents satisfying the query in the given collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query specifying which objects to count</div>'}],returns:{type:"xs:integer",description:"the said count"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:1,name:"disconnect",qname:"mongo:disconnect",signature:"($db as xs:anyURI) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Disconnect from a MongoDB database.</p>\n',summary:"<p>  Disconnect from a MongoDB database.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'}],returns:{type:"empty-sequence()",description:"the function has side-effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:2,name:"drop-collection",qname:"mongo:drop-collection",signature:"($db as xs:anyURI, $coll as xs:string) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Drop a collection.</p>\n',summary:"<p>  Drop a collection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'}],returns:{type:"empty-sequence()",description:"the function has side-effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:2,name:"find-nondeterministic",qname:"mongo:find-nondeterministic",signature:"($db as xs:anyURI, $coll as xs:string) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all objects of the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#find-2">find#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns all objects of the given collection.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'}],returns:{type:"object()*",description:"all objects of the given collection"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:3,name:"find-nondeterministic",qname:"mongo:find-nondeterministic",signature:"($db as xs:anyURI, $coll as xs:string, $query as object()) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs a query operation on the given collection and\n returns all matches.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#find-3">find#3</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Performs a query operation on the given collection and\n returns all matches.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query operation to perform</div>'}],returns:{type:"object()*",description:"all matches returned by the given query operation"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given query could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:4,name:"find-nondeterministic",qname:"mongo:find-nondeterministic",signature:"($db as xs:anyURI, $coll as xs:string, $query as object(), $options as object()) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs a query operation on the given collection and\n returns all matches.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#find-4">find#4</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Performs a query operation on the given collection and\n returns all matches.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query operation to perform</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the options for this operation (see find#5 for available options)</div>'}],returns:{type:"object()*",description:"all matches returned by the given query operation"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given query could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:5,name:"find-nondeterministic",qname:"mongo:find-nondeterministic",signature:"($db as xs:anyURI, $coll as xs:string, $query as object(), $projection as object(), $options as object()) as object()* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs a query operation on the given collection and\n returns all matches.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#find-5">find#5</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Performs a query operation on the given collection and\n returns all matches.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query operation to perform</div>'},{name:"projection",type:"object()",occurrence:null,description:""},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the options for this operation</div>'}],returns:{type:"object()*",description:"all matches returned by the given query operation"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given query or projection could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:2,name:"find",qname:"mongo:find",signature:"($db as xs:anyURI, $coll as xs:string) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all objects of the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p>  Returns all objects of the given collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'}],returns:{type:"object()*",description:"all objects of the given collection"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:3,name:"find",qname:"mongo:find",signature:"($db as xs:anyURI, $coll as xs:string, $query as object()) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs a query operation on the given collection and\n returns all matches.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p>  Performs a query operation on the given collection and\n returns all matches.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query operation to perform</div>'}],returns:{type:"object()*",description:"all matches returned by the given query operation"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given query could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:4,name:"find",qname:"mongo:find",signature:"($db as xs:anyURI, $coll as xs:string, $query as object(), $options as object()) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs a query operation on the given collection and\n returns all matches.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p>  Performs a query operation on the given collection and\n returns all matches.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query operation to perform</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the options for this operation (see find#5 for available options)</div>'}],returns:{type:"object()*",description:"all matches returned by the given query operation"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given query could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:5,name:"find",qname:"mongo:find",signature:"($db as xs:anyURI, $coll as xs:string, $query as object(), $projection as object(), $options as object()) as object()* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs a query operation on the given collection and\n returns all matches.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Available options:\n <ul>\n   <li>to-return: the maximum number of objects to return (0 = unlimited)</li>\n   <li>to-skip: start with the n-th object</li>\n   <li>batch-size: the number of objects to return in one batch</li>\n   <li>slave-ok: allow this query to be run against a replica secondary</li>\n   <li>await-data: the server will block for some extra time before returning,\n   waiting for more data to return</li>\n   <li>partial-results: return partial results if some shards are down instead\n   of returning an error</li>\n </ul>\n </p>\n',summary:"<p>  Performs a query operation on the given collection and\n returns all matches.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query operation to perform</div>'},{name:"projection",type:"object()",occurrence:null,description:""},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the options for this operation</div>'}],returns:{type:"object()*",description:"all matches returned by the given query operation"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given query or projection could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-connected",qname:"mongo:is-connected",signature:"($db as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Checks if the given identifiers is valid and the corresponding\n connection is open.</p>\n',summary:"<p>  Checks if the given identifiers is valid and the corresponding\n connection is open.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'}],returns:{type:"xs:boolean",description:"true if the given connection identifier is valid and the corresponding connection is open, false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:3,name:"remove",qname:"mongo:remove",signature:"($db as xs:anyURI, $coll as xs:string, $remove as object()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs a remove operation on the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The operation will be checked and an error is raised if\n one of them fails.</p>\n',summary:"<p>  Performs a remove operation on the given collection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"remove",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the remove command to be performed</div>'}],returns:{type:"empty-sequence()",description:"the function has side-effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given document could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:4,name:"remove",qname:"mongo:remove",signature:"($db as xs:anyURI, $coll as xs:string, $remove as object(), $options as object()) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs a remove operation on the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n <ul>\n   <li>safe: If to true, the operation will wait for a response from\n    the database and an error is raised if the operation fails.\n    Otherwise, the operation will not wait for a response.</li>\n  <li>just-one: true if the operation should stop after a single match\n    has been found and deleted</li>\n </ul>\n </p>\n',summary:"<p>  Performs a remove operation on the given collection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"remove",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the remove command to be performed</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the options for this operation</div>'}],returns:{type:"empty-sequence()",description:"the function has side-effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given document could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:2,name:"run-cmd-deterministic",qname:"mongo:run-cmd-deterministic",signature:"($db as xs:anyURI, $cmd as object()) as object() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Executes a\n <a href="http://docs.mongodb.org/manual/reference/commands/">database command</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is marked as deterministic and should be used whenever the\n specified command has no side-effects and result caching is desired.</p>\n',summary:"<p>  Executes a\n  database command .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"cmd",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the database command to execute</div>'}],returns:{type:"object()",description:"The result object. Typically has { ok : ..., errmsg : ... } fields set."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:2,name:"run-cmd-nondeterministic",qname:"mongo:run-cmd-nondeterministic",signature:"($db as xs:anyURI, $cmd as object()) as object() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Executes a\n <a href="http://docs.mongodb.org/manual/reference/commands/">database command</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is marked as non-deterministic and should be used whenever the\n specified command has no side-effects and result caching is undesired.</p>\n',summary:"<p>  Executes a\n  database command .</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"cmd",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the database command to execute</div>'}],returns:{type:"object()",description:"The result object. Typically has { ok : ..., errmsg : ... } fields set."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:2,name:"run-cmd",qname:"mongo:run-cmd",signature:"($db as xs:anyURI, $cmd as object()) as object() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Executes a\n <a href="http://docs.mongodb.org/manual/reference/commands/">database command</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is marked as sequential and should be used whenever the\n specified command has side-effects.</p>\n',summary:"<p>  Executes a\n  database command .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"cmd",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the database command to execute</div>'}],returns:{type:"object()",description:"The result object. Typically has { ok : ..., errmsg : ... } fields set."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if any mongodb error happens</xqdoc:error>']},{isDocumented:!0,arity:3,name:"save",qname:"mongo:save",signature:"($db as xs:anyURI, $coll as xs:string, $doc as object()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Save a sequence of documents in the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a document to be save already has an "_id" field, then an\n upsert operation is performed an any existing document with that\n id will be overwritten. Otherwise, an insert operation is performed\n and the "_id" generated for each document will be returned.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Each safe operation will be checked and an error is raised if\n one of them fails.</p>\n',summary:"<p>  Save a sequence of documents in the given collection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"doc",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the document to be saved or upserted</div>'}],returns:{type:"empty-sequence()",description:'the documents that have been inserted with "_id" fields.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given document could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:4,name:"save",qname:"mongo:save",signature:"($db as xs:anyURI, $coll as xs:string, $doc as object(), $options as object()) as m-schema:oid? external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Save a sequence of documents in the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a document to be saved already has an "_id" field, then an\n upsert operation is performed and any existing document with that\n id will be overwritten. Otherwise, an insert operation is performed.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the manipulate option is set to true, an "_id" field will be\n added to the document. The new id will be returned. Otherwise,\n the "_id" field will be added by the server.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the safe options is set to true, each operation will wait for a\n response from the database and an error is raised if the operation\n fails. Otherwise, the operation will not wait for a response.</p>\n',summary:"<p>  Save a sequence of documents in the given collection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"doc",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the document to be saved or upserted</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the options for this operation</div>'}],returns:{type:"m-schema:oid?",description:"a generated OID if the manipulate option was set to true, the empty sequence otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given document could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:4,name:"update",qname:"mongo:update",signature:"($db as xs:anyURI, $coll as xs:string, $query as object(), $update as object()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs an update command on the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The operation will be checked and an error is raised if\n one of them fails. Also, this function only modifies one\n document matching the query and does not do any upserts.</p>\n',summary:"<p>  Performs an update command on the given collection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query to select the objects that are updated</div>'},{name:"update",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the update specification to be performed</div>'}],returns:{type:"empty-sequence()",description:"the function has side-effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given objects could not be converted to BSON</xqdoc:error>']},{isDocumented:!0,arity:5,name:"update",qname:"mongo:update",signature:"($db as xs:anyURI, $coll as xs:string, $query as object(), $update as object(), $options as object()) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Performs an update operation on the given collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n <ul>\n   <li>safe: If to true, the operation will wait for a response from\n    the database and an error is raised if the operation fails.\n    Otherwise, the operation will not wait for a response.</li>\n  <li>multi: indicates if all documents matching criteria should be updated\n  rather than just one.</li>\n  <li>upsert: if this should be an "upsert" operation; that is,\n  if the record(s) do not exist, insert one. Upsert only inserts a single document.</li>\n </ul>\n </p>\n',summary:"<p>  Performs an update operation on the given collection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database connection identifier</div>'},{name:"coll",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query to select the objects that are updated</div>'},{name:"update",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the update specification to be performed</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the options for this operation</div>'}],returns:{type:"empty-sequence()",description:"the function has side-effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO004 invalid database identifier</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO005 if any mongodb error happens</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">mongo:MONGO006 if the given objects could not be converted to BSON</xqdoc:error>']}],variables:[]},"http://jsoniq.org/function-library":{ns:"http://jsoniq.org/function-library",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides extensions to the JSONiq core function library.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The module is always imported so you do not need to import it explicitly.\n Also, you do not need to fully qualify a function to invoke it.</p>\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://jsoniq.org/</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://jsoniq.org/functions",prefix:"jn"},{uri:"http://jsoniq.org/function-library",prefix:"libjn"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"accumulate",qname:"libjn:accumulate",signature:"($items as item()*) as object()",description:" This function dynamically builds an object, like the {||} syntax, except that\n it does not throw an error upon pair collision. Instead, it accumulates them\n into an array, if more than one.\n",summary:"<p> This function dynamically builds an object, like the {||} syntax, except that\n it does not throw an error upon pair collision.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items, the objects of which are going to be accumulated into a single object.</div>'}],returns:{type:"object()",description:"The accumulated object."},errors:[]},{isDocumented:!0,arity:1,name:"descendant-arrays",qname:"libjn:descendant-arrays",signature:"($items as item()*) as array()*",description:" This function returns all arrays contained at any depth within a sequence of items.\n",summary:"<p> This function returns all arrays contained at any depth within a sequence of items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items.</div>'}],returns:{type:"array()*",description:"The descendant arrays of the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"descendant-objects",qname:"libjn:descendant-objects",signature:"($items as item()*) as object()*",description:" This function returns all objects contained at any depth within a sequence of items.\n",summary:"<p> This function returns all objects contained at any depth within a sequence of items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items.</div>'}],returns:{type:"object()*",description:"The descendant objects of the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"descendant-pairs-priv",qname:"libjn:descendant-pairs-priv",signature:"($i as item()) as object()*",description:" Helper function for libjn:descendant-pairs()\n",summary:"<p> Helper function for libjn:descendant-pairs()\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"i",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An item</div>'}],returns:{type:"object()*",description:"The descendant pairs of the item"},errors:[]},{isDocumented:!0,arity:1,name:"descendant-pairs",qname:"libjn:descendant-pairs",signature:"($items as item()*) as object()*",description:" This function returns all pairs contained at any depth within an sequence of items.\n",summary:"<p> This function returns all pairs contained at any depth within an sequence of items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:""}],returns:{type:"object()*",description:"All direct and indirect descendant pairs."},errors:[]},{isDocumented:!0,arity:1,name:"intersect",qname:"libjn:intersect",signature:"($items as item()*) as object()",description:" This function returns the intersection of the objects contained in the\n given sequence of items, aggregating values corresponding to the same key\n into an array.\n",summary:"<p> This function returns the intersection of the objects contained in the\n given sequence of items, aggregating values corresponding to the same key\n into an array.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items.</div>'}],returns:{type:"object()",description:"The insersection of the objects contained in $items."},errors:[]},{isDocumented:!0,arity:1,name:"values",qname:"libjn:values",signature:"($items as item()*) as item()*",description:" This functions returns all values of all objects contained in a sequence of items.\n",summary:"<p> This functions returns all values of all objects contained in a sequence of items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of items.</div>'}],returns:{type:"item()*",description:"The values inside the objects of the sequence."},errors:[]}],variables:[]},"http://zorba.io/modules/node-position":{ns:"http://zorba.io/modules/node-position",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides a function (np:node-position) that, given a node,\n returns positional information about the node in the form of an xs:anyURI\n item. The module also defines functions that use such positional information\n to determine: (1) positional relationships between two nodes (e.g. if one\n is the ancestor of another) and (2) positional properties of a single node\n (e.g. its level in the tree).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Within this module, the term "node position" will be used to refer to an\n xs:anyURI item that is returned by the np:node-position function.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri, Markos Zaharioudakis</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/node-position",prefix:"np"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"ancestor-of",qname:"np:ancestor-of",signature:"($pos1 as xs:anyURI, $pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n an ancestor of the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is an ancestor of the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n an ancestor of the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"pos1",type:"xs:anyURI",occurrence:null,description:""},{name:"pos2",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 is an ancestor of the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"attribute-of",qname:"np:attribute-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n an attribute of the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is an attribute of the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n an attribute of the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential parent node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential attribute node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 is an attribute of the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"child-of",qname:"np:child-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n a child of the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is a child of the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n a child of the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential parent node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential child node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 is a child of the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"descendant-of",qname:"np:descendant-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n a descendant of the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is a descendant of the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n a descendant of the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential ancestor node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential descendant node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 is a descendant of the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"following-in-document-order-of",qname:"np:following-in-document-order-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n following in document order the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is following in document order the\n first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about\n the positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n following in document order the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 is following in document order the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"following-of",qname:"np:following-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n following the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is following the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n following the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following node position</div>'}],returns:{type:"xs:boolean",description:"true if node positions $n-pos1 and $n-pos2 belong to the same XML tree and $n-pos2 is following the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"following-sibling-of",qname:"np:following-sibling-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n a following-sibling of the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is a following-sibling of the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n a following-sibling of the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding-sibling node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following-sibling node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 is a following-sibling of the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"in-collection",qname:"np:in-collection",signature:"($n-pos as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether a node position belongs to a collection.</p>\n',summary:"<p>  Determines whether a node position belongs to a collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos belongs to a collection; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"in-same-collection-of",qname:"np:in-same-collection-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether two node positions belong to the same collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the two nodes belong to the same collection.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about\n the positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether two node positions belong to the same collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a node position</div>'}],returns:{type:"xs:boolean",description:"true if the two nodes whose node positions are $n-pos1 and $n-pos2 belong to the same collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"in-same-tree-of",qname:"np:in-same-tree-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether two node positions belong to the same tree.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the two nodes belong to the same tree.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about\n the positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether two node positions belong to the same tree.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a node position</div>'}],returns:{type:"xs:boolean",description:"true if the two nodes whose node positions are $n-pos1 and $n-pos2 belong to the same tree."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"in-subtree-of",qname:"np:in-subtree-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument belongs\n to the subtree rooted at the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node belongs to the subtree rooted at the\n first. Otherwise, the result of the function does not imply anything about\n the positional relationship of the two nodes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function differs from np:descendant-of in the way it treats attribute\n nodes. np:descendant-of follows the XQuery/XPath specification for the\n descendant axis, and as a result, it does not consider attributes as\n descendants of any nodes; it will always return false if $n-pos2 was\n obtained from an attribute node.In contrast, np:in-subtree-of will return\n true if $n-pos2 was obtained from an attribute node that appeared in the\n subtree of the node that $n-pos1 was obtained from.</p>\n',summary:"<p>  Determines whether the node position given as second argument belongs\n to the subtree rooted at the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential subtree root node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential node in the subtree node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 belongs to the subtree rooted at the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-attribute",qname:"np:is-attribute",signature:"($n-pos1 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether a node position corresponds to an attribute node.</p>\n',summary:"<p>  Determines whether a node position corresponds to an attribute node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:"xs:boolean",description:"true if the node position $n-pos corresponds to an attribute; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-comment",qname:"np:is-comment",signature:"($n-pos1 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether a node position corresponds to a comment node.</p>\n',summary:"<p>  Determines whether a node position corresponds to a comment node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:"xs:boolean",description:"true if the node position $n-pos corresponds to an comment; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-document",qname:"np:is-document",signature:"($n-pos1 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether a node position corresponds to a document node.</p>\n',summary:"<p>  Determines whether a node position corresponds to a document node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:"xs:boolean",description:"true if the node position $n-pos corresponds to a document; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-element",qname:"np:is-element",signature:"($n-pos1 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether a node position corresponds to an element node.</p>\n',summary:"<p>  Determines whether a node position corresponds to an element node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:"xs:boolean",description:"true if the node position $n-pos corresponds to an element; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-processing-instruction",qname:"np:is-processing-instruction",signature:"($n-pos1 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether a node position corresponds to an processing-instruction\n node.</p>\n',summary:"<p>  Determines whether a node position corresponds to an processing-instruction\n node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:"xs:boolean",description:"true if the node position $n-pos corresponds to a processing instruction; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-text",qname:"np:is-text",signature:"($n-pos1 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether a node position corresponds to a text node.</p>\n',summary:"<p>  Determines whether a node position corresponds to a text node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:"xs:boolean",description:"true if the node position $n-pos corresponds to a text; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"level",qname:"np:level",signature:"($n-pos as xs:anyURI) as xs:integer external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Computes the level of a node position in its tree.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note: The root node of a tree is at level one.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The result of the function applies to the corresponding node as well,\n that is, within the snapshot in which the position was computed, the node\n level is the returned one.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The result of the function does not imply anything about the\n node level in other snapshots.</p>\n',summary:"<p>  Computes the level of a node position in its tree.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node position of the node whose level should be determined.</div>'}],returns:{type:"xs:integer",description:"the level in the tree of the node position $n-pos as xs:integer."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"node-position",qname:"np:node-position",signature:"($arg as node()) as xs:anyURI external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return a URI item containing positional information for a given node.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Within a snapshot, each has a different positional URI. However,\n different nodes in different snapshots might have the same URI.</p>\n',summary:"<p>  Return a URI item containing positional information for a given node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node for which the positional information URI should be computed</div>'}],returns:{type:"xs:anyURI",description:"the opaque positional information URI of the node."},errors:[]},{isDocumented:!0,arity:2,name:"parent-of",qname:"np:parent-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n the parent of the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is the parent of the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n the parent of the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential child node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential parent node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 is the parent of the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"preceding-in-document-order-of",qname:"np:preceding-in-document-order-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n preceding in document order the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is preceding in document order the\n first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about\n the positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n preceding in document order the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 is preceding in document order the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"preceding-of",qname:"np:preceding-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n preceding the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is preceding the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n preceding the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding node position</div>'}],returns:{type:"xs:boolean",description:"true if node positions $n-pos1 and $n-pos2 belong to the same XML tree and $n-pos2 is preceding the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"preceding-sibling-of",qname:"np:preceding-sibling-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether the node position given as second argument is\n a preceding-sibling of the node position given as first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is a preceding-sibling of the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether the node position given as second argument is\n a preceding-sibling of the node position given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following-sibling node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding-sibling node position</div>'}],returns:{type:"xs:boolean",description:"true if the node position $n-pos2 is a preceding-sibling of the node position $n-pos1; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"sibling-of",qname:"np:sibling-of",signature:"($n-pos1 as xs:anyURI, $n-pos2 as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Determines whether two node positions are siblings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the two positions were obtained within the same snapshot S, then the\n result of the function applies to the corresponding nodes as well, that\n is, within snapshot S, the second node is a sibling of the first.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Otherwise, the result of the function does not imply anything about the\n positional relationship of the two nodes.</p>\n',summary:"<p>  Determines whether two node positions are siblings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"n-pos1",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a node position</div>'},{name:"n-pos2",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a node position</div>'}],returns:{type:"xs:boolean",description:"true if the two node positions $n-pos1 and $n-pos2 are siblings; false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 if one of the given URI is not a valid node position computed by the <tt>np:node-position</tt> function.</xqdoc:error>']}],variables:[]},"http://www.zorba-xquery.com/modules/cryptography/hash":{ns:"http://www.zorba-xquery.com/modules/cryptography/hash",description:" This module provides functions that perform different hash operations.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Gabriel Petrovay, Markus Pilman</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/cryptography/hash",prefix:"hash"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"hash-impl",qname:"hash:hash-impl",signature:"($value as xs:string, $alg as xs:string) as xs:string external",description:" This function computes a hash value of the string provided as parameter.\n The function expects the hash algorithm to be used as parameter.\n",summary:"<p> This function computes a hash value of the string provided as parameter.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to be hashed.</div>'},{name:"alg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The algorithm to use for this hashing operation. Currently only "md5" and "sha1" algorithms are available. If no valid algorithm name is given, md5 will be used.</div>'}],returns:{type:"xs:string",description:"The hash of the provided string. In case SHA1 is used, the resulting hash value is base64 encoded."},errors:[]},{isDocumented:!0,arity:1,name:"md5",qname:"hash:md5",signature:"($value as xs:string) as xs:string",description:" Computes the MD5 hash of the string provided as parameter.\n",summary:"<p> Computes the MD5 hash of the string provided as parameter.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to hash.</div>'}],returns:{type:"xs:string",description:"The MD5 hash of the provided string."},errors:[]},{isDocumented:!0,arity:1,name:"sha1",qname:"hash:sha1",signature:"($value as xs:string) as xs:string",description:" Computes the SHA1 hash of the string provided as parameter.\n",summary:"<p> Computes the SHA1 hash of the string provided as parameter.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to hash.</div>'}],returns:{type:"xs:string",description:"The base64 encoded SHA1 hash of the provided string."},errors:[]}],variables:[]},"http://zorba.io/modules/excel/lookup":{ns:"http://zorba.io/modules/excel/lookup",description:" This module implements some Excel 2003 lookup functions.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://office.microsoft.com/en-us/excel/CH062528281033.aspx" target="_blank">Excel 2003 Documentation: Lookup Functions</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Turcanu</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/lookup",prefix:"excel"},{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/modules/excel/math",prefix:"excel-math"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"choose",qname:"excel:choose",signature:"($index_num as xs:integer, $values as xs:anyAtomicType*) as xs:anyAtomicType",description:" Uses index_num to return a value from the sequence of value arguments.\n",summary:"<p> Uses index_num to return a value from the sequence of value arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"index_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The position in the sequence, 1 based.</div>'},{name:"values",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of values.</div>'}],returns:{type:"xs:anyAtomicType",description:"The value at the index position."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if index is smaller than 1 or bigger than the size of sequence.</xqdoc:error>']},{isDocumented:!0,arity:30,name:"choose",qname:"excel:choose",signature:"($index_num as xs:integer, $value_sequence1 as xs:anyAtomicType*, $value_sequence2 as xs:anyAtomicType*, $value_sequence3 as xs:anyAtomicType*, $value_sequence4 as xs:anyAtomicType*, $value_sequence5 as xs:anyAtomicType*, $value_sequence6 as xs:anyAtomicType*, $value_sequence7 as xs:anyAtomicType*, $value_sequence8 as xs:anyAtomicType*, $value_sequence9 as xs:anyAtomicType*, $value_sequence10 as xs:anyAtomicType*, $value_sequence11 as xs:anyAtomicType*, $value_sequence12 as xs:anyAtomicType*, $value_sequence13 as xs:anyAtomicType*, $value_sequence14 as xs:anyAtomicType*, $value_sequence15 as xs:anyAtomicType*, $value_sequence16 as xs:anyAtomicType*, $value_sequence17 as xs:anyAtomicType*, $value_sequence18 as xs:anyAtomicType*, $value_sequence19 as xs:anyAtomicType*, $value_sequence20 as xs:anyAtomicType*, $value_sequence21 as xs:anyAtomicType*, $value_sequence22 as xs:anyAtomicType*, $value_sequence23 as xs:anyAtomicType*, $value_sequence24 as xs:anyAtomicType*, $value_sequence25 as xs:anyAtomicType*, $value_sequence26 as xs:anyAtomicType*, $value_sequence27 as xs:anyAtomicType*, $value_sequence28 as xs:anyAtomicType*, $value_sequence29 as xs:anyAtomicType*) as xs:anyAtomicType*",description:" Uses index_num to return a sequence from the list of sequences.\n Use CHOOSE to select one of up to 29 sequences based on the index number.\n",summary:"<p> Uses index_num to return a sequence from the list of sequences.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"index_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the position in the sequence, 1 based</div>'},{name:"value_sequence1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence23",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence24",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence25",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence26",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence27",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence28",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'},{name:"value_sequence29",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of values. Specify the empty sequence () if you don\'t need it.</div>'}],returns:{type:"xs:anyAtomicType*",description:"The value at the index position"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if index is smaller than 1 or bigger than 29</xqdoc:error>']},{isDocumented:!0,arity:5,name:"hlookup",qname:"excel:hlookup",signature:"($lookup_value as xs:anyAtomicType, $table_array as xs:anyAtomicType+, $table_width as xs:integer, $table_height as xs:integer, $row_index_num as xs:integer) as xs:anyAtomicType",description:" Same as above, only that range_lookup is defaulted to true.\n That is, this Hlookup looks for the approximate value\n   and the first row must be ordered ascending.\n",summary:"<p> Same as above, only that range_lookup is defaulted to true.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lookup_value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to be searched. Allowed types are numeric, string, boolean. <p/> Boolean values are compared only with booleans. Numbers are compared only with numbers, if range_lookup is not zero. The other types are converted to string and compared to string value of all values.</div>'},{name:"table_array",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values, row after row</div>'},{name:"table_width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of values in a row</div>'},{name:"table_height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of rows</div>'},{name:"row_index_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the row index, 1 based</div>'}],returns:{type:"xs:anyAtomicType",description:"The value found, with original type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the array contains less elements than specified by table_height and table_width</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if row_index_num is outside the range 1 .. table_height</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup is true and the value searched is smaller than the first value in the header</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup=false and the value cannot be found</xqdoc:error>']},{isDocumented:!0,arity:6,name:"hlookup",qname:"excel:hlookup",signature:"($lookup_value as xs:anyAtomicType, $table_array as xs:anyAtomicType+, $table_width as xs:integer, $table_height as xs:integer, $row_index_num as xs:integer, $range_lookup as xs:boolean) as xs:anyAtomicType",description:' Searches for a value in the top row of an array of values,\n   and then returns a value in the same column from a row you specify in the array.\n <dl xmlns:xqdoc="http://www.xqdoc.org/1.0">Array is specified with 3 parameters:\n <dt>table_array</dt> <dd>is a sequence of elements, first row first, then second row and so on</dd>\n <dt>table_width</dt> <dd>specifies the number of elements in a row</dd>\n <dt>table_height</dt> <dd>specifies the number of rows</dd></dl>\n The number of elements in table_array must be equal or more than table_width * table_height.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n For wildchar matching, the XQuery regex matcher is used.\n',summary:"<p> Searches for a value in the top row of an array of values,\n   and then returns a value in the same column from a row you specify in the array.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lookup_value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to be searched. Allowed types are numeric, string, boolean. <p/> Boolean values are compared only with booleans. Numbers are compared only with numbers, if range_lookup is not zero. The other types are converted to string and compared to string value of all values.</div>'},{name:"table_array",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values, row after row</div>'},{name:"table_width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of values in a row</div>'},{name:"table_height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of rows</div>'},{name:"row_index_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the row index, 1 based</div>'},{name:"range_lookup",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <dl>specifies the algorithm to use: <dt>true</dt> <dd>find approximative match. First row of array must be sorted in ascending order.</dd> <dt>false</dt> <dd>find exact match, using xquery regex First row of array can be in any order. </dd></dl></div>'}],returns:{type:"xs:anyAtomicType",description:"The value found, with original type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the array contains less elements than specified by table_height and table_width</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if row_index_num is outside the range 1 .. table_height</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup is true and the value searched is smaller than the first value in the header</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup=false and the value cannot be found</xqdoc:error>']},{isDocumented:!0,arity:5,name:"index",qname:"excel:index",signature:"($array as xs:anyAtomicType+, $array_height as xs:integer, $array_width as xs:integer, $row_num as xs:integer, $column_num as xs:integer) as xs:anyAtomicType+",description:' Returns a value from within an array.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This is the Array form of the Excel Index function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <dl xmlns:xqdoc="http://www.xqdoc.org/1.0">Array is specified with 3 parameters:\n <dt>array</dt> <dd>is a sequence of elements, first row first, then second row and so on</dd>\n <dt>array_height</dt> <dd>specifies the number of rows</dd>\n <dt>array_width</dt> <dd>specifies the number of elements in a row</dd></dl>\n The number of elements in array must be equal or more than array_width * array_height.\n',summary:"<p> Returns a value from within an array.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values, row after row</div>'},{name:"array_height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of rows</div>'},{name:"array_width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of values in a row</div>'},{name:"row_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the row position of the value, 1 based</div>'},{name:"column_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the column position of the value, 1 based</div>'}],returns:{type:"xs:anyAtomicType+",description:"The value from x-y in the array"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the array contains less elements than specified by table_height and table_width</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Ref if row_num is outside the range</xqdoc:error>']},{isDocumented:!0,arity:3,name:"lookup",qname:"excel:lookup",signature:"($lookup_value as xs:anyAtomicType, $lookup_vector as xs:anyAtomicType+, $result_vector as xs:anyAtomicType+) as xs:anyAtomicType",description:' The Vector form. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Looks in a sequence for a value\n   and return a value from the same position in a second sequence.\n If the value is not found, then it matches the largest value in lookup_vector\n   that is less than or equal to lookup_value.\n',summary:"<p> The Vector form.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lookup_value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to be searched</div>'},{name:"lookup_vector",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence to be searched, in ascending order.</div>'},{name:"result_vector",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence containing the result values</div>'}],returns:{type:"xs:anyAtomicType",description:"a value from $result_vector"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA if lookup value is smaller than the first value in lookup_vector</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA if position found is outside the result range</xqdoc:error>']},{isDocumented:!0,arity:4,name:"lookup",qname:"excel:lookup",signature:"($lookup_value as xs:anyAtomicType, $array as xs:anyAtomicType+, $array_width as xs:integer, $array_height as xs:integer) as xs:anyAtomicType",description:' The Array form.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n It looks in the first row or column of an array for the specified value\n   and returns a value from the same position in the last row or column of the array.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If array covers an area that is wider than it is tall (more columns than rows),\n   LOOKUP searches for lookup_value in the first row.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If array is square or is taller than it is wide (more rows than columns),\n   LOOKUP searches in the first column.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The values in the first row or first column must be in ascending order.\n',summary:"<p> The Array form.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lookup_value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to be searched. If the value is not found, then it matches the largest value in lookup_vector that is less than or equal to lookup_value.</div>'},{name:"array",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the array sequence, row after row</div>'},{name:"array_width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of values in a row</div>'},{name:"array_height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of rows in the array</div>'}],returns:{type:"xs:anyAtomicType",description:"The corresponding value in the last row or column"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if array contains less values than specified by array_width and array_height or array_width = 0 or array_height = 0</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA if the lookup_value is smaller than the first value in the row or column</xqdoc:error>']},{isDocumented:!0,arity:2,name:"match",qname:"excel:match",signature:"($lookup_value as xs:anyAtomicType, $sequence as xs:anyAtomicType+) as xs:anyAtomicType",description:" Same as above, but match_type is defaulted to 1.\n It finds the largest value that is less than or equal to lookup_value.\n",summary:"<p> Same as above, but match_type is defaulted to 1.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lookup_value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> value to be searched.</div>'},{name:"sequence",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the vector where to search the value</div>'}],returns:{type:"xs:anyAtomicType",description:"The position of found value"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA for match_type 1 or -1, the lookup_value is smaller or larger than the first value in sequence</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup=0 and the value cannot be found</xqdoc:error>']},{isDocumented:!0,arity:3,name:"match",qname:"excel:match",signature:"($lookup_value as xs:anyAtomicType, $sequence as xs:anyAtomicType+, $match_type as xs:integer) as xs:anyAtomicType",description:" Returns the relative position of an item in a sequence that\n   matches a specified value in a specified order.\n Only for one dimensional vector.\n",summary:"<p> Returns the relative position of an item in a sequence that\n   matches a specified value in a specified order.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lookup_value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> value to be searched.</div>'},{name:"sequence",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the vector where to search the value</div>'},{name:"match_type",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <dl>specifies the algorithm used for searching. Possible values: <dt>1</dt> <dd> finds the largest value that is less than or equal to lookup_value. Sequence must be in ascending order.</dd> <dt>0</dt> <dd> finds the first value that is exactly equal to lookup_value. <p/> Sequence can be in any order.<p/> If lookup_value is boolean, then only booleans are compared.<p/> For other types, they are casted to string and then compared using xquery regular expressions. Lookup_value can be a xquery regular expression.</dd> <dt>-1</dt> <dd> finds the smallest value that is greater than or equal to lookup_value.<p/> Sequence must be in descending order.</dd></dl></div>'}],returns:{type:"xs:anyAtomicType",description:"The position of found value"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA for match_type 1 or -1, the lookup_value is smaller or larger than the first value in sequence</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup=0 and the value cannot be found</xqdoc:error>']},{isDocumented:!0,arity:5,name:"offset",qname:"excel:offset",signature:"($reference as xs:anyAtomicType+, $reference_height as xs:integer, $reference_width as xs:integer, $rows as xs:integer, $cols as xs:integer) as xs:anyAtomicType*",description:" Same as above, only that the sub-array is specified only by rows and cols relative position.\n The sub-array height and width is computed to contain the remaining elements of the array.\n",summary:"<p> Same as above, only that the sub-array is specified only by rows and cols relative position.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"reference",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the reference array</div>'},{name:"reference_height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of rows in the reference array</div>'},{name:"reference_width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of elements in the reference array row</div>'},{name:"rows",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the relative row position where the sub-array starts. It must be a positive value, zero relative.</div>'},{name:"cols",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the relative column position where the sub-array starts. It must be a positive value, zero relative.</div>'}],returns:{type:"xs:anyAtomicType*",description:"The sequence specifying the sub-array, row after row"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA rows or cols are negative</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA height or width are smaller than 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value reference array contains less elements than specified by reference_height and reference_width</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA the resulted sub-array is not completely contained inside reference array</xqdoc:error>']},{isDocumented:!0,arity:7,name:"offset",qname:"excel:offset",signature:"($reference as xs:anyAtomicType+, $reference_height as xs:integer, $reference_width as xs:integer, $rows as xs:integer, $cols as xs:integer, $height as xs:integer, $width as xs:integer) as xs:anyAtomicType*",description:" Returns a sub-array from an array.\n The inner array must be within the reference array\n",summary:"<p> Returns a sub-array from an array.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"reference",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the reference array</div>'},{name:"reference_height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of rows in the reference array</div>'},{name:"reference_width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of elements in the reference array row</div>'},{name:"rows",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the relative row position where the sub-array starts. It must be a positive value, zero relative.</div>'},{name:"cols",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the relative column position where the sub-array starts. It must be a positive value, zero relative.</div>'},{name:"height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the desired height of sub-array. The sub-array must be inside the reference array.</div>'},{name:"width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the desired width of sub-array. The sub-array must be inside the reference array.</div>'}],returns:{type:"xs:anyAtomicType*",description:"The sequence specifying the sub-array, row after row"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA rows or cols are negative</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA height or width are smaller than 1</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value reference array contains less elements than specified by reference_height and reference_width</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA the resulted sub-array is not completely contained inside reference array</xqdoc:error>']},{isDocumented:!0,arity:3,name:"transpose",qname:"excel:transpose",signature:"($array as xs:anyAtomicType+, $array_width as xs:integer, $array_height as xs:integer) as xs:anyAtomicType+",description:" Transposes an array. The rows become columns and vice versa.\n",summary:"<p> Transposes an array.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence specifying the array, row after row</div>'},{name:"array_width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of elements in a row</div>'},{name:"array_height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of rows in the array</div>'}],returns:{type:"xs:anyAtomicType+",description:"The transposed array. It will be a sequence specifying an array, row after row. The result width is the input height. The result height is the input width."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value the array contains less elements than specified by array_width and array_height</xqdoc:error>']},{isDocumented:!0,arity:5,name:"vlookup",qname:"excel:vlookup",signature:"($lookup_value as xs:anyAtomicType, $table_array as xs:anyAtomicType+, $table_width as xs:integer, $table_height as xs:integer, $col_index_num as xs:integer) as xs:anyAtomicType",description:" Same as above, with range_lookup defaulted to true.\n It finds the largest value that is less than or equal to lookup_value.\n First column must be in ascending order.\n",summary:"<p> Same as above, with range_lookup defaulted to true.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lookup_value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to be searched. Allowed types are numeric, string, boolean. <p/> Boolean values are compared only with booleans. Numbers are compared only with numbers, if range_lookup is not zero. The other types are converted to string and compared to string value of all values.</div>'},{name:"table_array",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values, row after row</div>'},{name:"table_width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of values in a row</div>'},{name:"table_height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of rows</div>'},{name:"col_index_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the row index, 1 based</div>'}],returns:{type:"xs:anyAtomicType",description:"The value found, with original type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the array contains less elements than specified by table_height and table_width</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if col_index_num is outside the range 1 .. table_height</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup is true and the value searched is smaller than the first value in the first column</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup=false and the value cannot be found</xqdoc:error>']},{isDocumented:!0,arity:6,name:"vlookup",qname:"excel:vlookup",signature:"($lookup_value as xs:anyAtomicType, $table_array as xs:anyAtomicType+, $table_width as xs:integer, $table_height as xs:integer, $col_index_num as xs:integer, $range_lookup as xs:boolean) as xs:anyAtomicType",description:' Searches for a value in the first column of a table array\n   and returns a value in the same row from another column in the table array.\n <dl xmlns:xqdoc="http://www.xqdoc.org/1.0">Array is specified with 3 parameters:\n <dt>table_array</dt> <dd>is a sequence of elements, first row first, then second row and so on</dd>\n <dt>table_width</dt> <dd>specifies the number of elements in a row</dd>\n <dt>table_height</dt> <dd>specifies the number of rows</dd></dl>\n For wildchar matching, the XQuery regex matcher is used.\n',summary:"<p> Searches for a value in the first column of a table array\n   and returns a value in the same row from another column in the table array.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lookup_value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to be searched. Allowed types are numeric, string, boolean. <p/> Boolean values are compared only with booleans. Numbers are compared only with numbers, if range_lookup is not zero. The other types are converted to string and compared to string value of all values.</div>'},{name:"table_array",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values, row after row</div>'},{name:"table_width",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of values in a row</div>'},{name:"table_height",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of rows</div>'},{name:"col_index_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the row index, 1 based</div>'},{name:"range_lookup",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <dl>specified the algorithm to use: <dt>true</dt> <dd> find approximative match. First column of array must be sorted in ascending order.</dd> <dt>false</dt> <dd> find exact match, using xquery regex. First column of array can be in any order.</dd></dl></div>'}],returns:{type:"xs:anyAtomicType",description:"The value found, with original type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the array contains less elements than specified by table_height and table_width</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if col_index_num is outside the range 1 .. table_height</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup is true and the value searched is smaller than the first value in the first column</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if range_lookup=false and the value cannot be found</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/datetime":{ns:"http://zorba.io/modules/datetime",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functions to retrieve the current dateTime and to\n parse dates and times.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In contrast to the current-dateTime functions specified in\n <a href="http://www.w3.org/TR/xpath-functions-30/">XQuery Functions and\n Operators</a>, the functions in this module are nondeterministic, that is,\n they do not return the current dateTime from the dynamic context, but return\n the actual value.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Dates and times are parsed according to the format given by\n <a href="http://pubs.opengroup.org/onlinepubs/007904975/functions/strptime.html">strptime</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">However, date and time values must be "complete."</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For a date, the year and either month and day or day of the year must have\n been parsed.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For a time, the hour must have been parsed.\n (If either the minute, second, or timezone has not been parsed, they default\n to 0.)</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For a dateTime, the parsing requirements of both date and time must be met.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">When a locale is given,\n it must be of the form {lang}[{sep}{country}[{encoding}]] where\n {lang} is an ISO 639-1 2-letter or 639-2 3-letter language code,\n {sep} is either \'-\' or \'_\',\n {country} is an ISO 3166-1 2-letter country code,\n and {encoding} is any string that begins with a \'.\'.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The {sep}, {country}, and {encoding} are optional;\n {encoding} is always ignored.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Examples include: de, en-US, fr_CA, ru_RU.UTF-8.</p>\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.w3.org/TR/xpath-functions/#context</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Paul J. Lucas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/datetime",prefix:"datetime"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"current-date",qname:"datetime:current-date",signature:"() as xs:date external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Gets the current date value in Universal time.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note that this function is not stable: it returns the value of the date when\n the function is invoked.</p>\n',summary:"<p>  Gets the current date value in Universal time.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"xs:date",description:"the non-stable date value"},errors:[]},{isDocumented:!0,arity:0,name:"current-dateTime",qname:"datetime:current-dateTime",signature:"() as xs:dateTimeStamp external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Gets the current dateTime value in Universal time.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note that this function is not stable: it returns the value of the date and\n time when the function is invoked.</p>\n',summary:"<p>  Gets the current dateTime value in Universal time.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"xs:dateTimeStamp",description:"the non-stable datetime value"},errors:[]},{isDocumented:!0,arity:0,name:"current-time",qname:"datetime:current-time",signature:"() as xs:time external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the current time value in Universal time.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note that this function is not stable: it returns the value of the time when\n the function is invoked.</p>\n',summary:"<p>  Return the current time value in Universal time.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"xs:time",description:"the non-stable time value"},errors:[]},{isDocumented:!0,arity:1,name:"millis-to-dateTime",qname:"datetime:millis-to-dateTime",signature:"($millis as xs:long) as xs:dateTime external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts the given number of milliseconds since epoch into its corresponding\n xs:dateTime.</p>\n',summary:"<p>  Converts the given number of milliseconds since epoch into its corresponding\n xs:dateTime.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"millis",type:"xs:long",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of milliseconds since epoch.</div>'}],returns:{type:"xs:dateTime",description:"Returns an xs:dateTime."},errors:[]},{isDocumented:!0,arity:2,name:"parse-date",qname:"datetime:parse-date",signature:"($input as xs:string, $format as xs:string) as xs:date external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parses a date from a string in the current locale.</p>\n',summary:"<p>  Parses a date from a string in the current locale.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to parse.</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The format string containing zero or more conversion specifications and ordinary characters. All ordinary characters are matched exactly with the buffer; all whitespace characters match any amount of whitespace in the buffer.</div>'}],returns:{type:"xs:date",description:"Returns an xs:date."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_SPECIFICATION if $format contains an invalid conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INSUFFICIENT_BUFFER if $input is insufficient for $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_VALUE if $input contains an invalid value for a conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:LITERAL_MISMATCH if there is a literal characer mismatch between $input and $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INCOMPLETE_DATE_OR_TIME if the date is incomplete.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"parse-date",qname:"datetime:parse-date",signature:"($input as xs:string, $format as xs:string, $locale as xs:string) as xs:date external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parses a date from a string in the given locale.</p>\n',summary:"<p>  Parses a date from a string in the given locale.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to parse.</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The format string containing zero or more conversion specifications and ordinary characters. All ordinary characters are matched exactly with the buffer; all whitespace characters match any amount of whitespace in the buffer.</div>'},{name:"locale",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The locale to use.</div>'}],returns:{type:"xs:date",description:"Returns an xs:date."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_SPECIFICATION if $format contains an invalid conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INSUFFICIENT_BUFFER if $input is insufficient for $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_VALUE if $input contains an invalid value for a conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:LITERAL_MISMATCH if there is a literal characer mismatch between $input and $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INCOMPLETE_DATE_OR_TIME if the date is incomplete.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_LOCALE if $locale is in an invalid format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:UNKNOWN_LOCALE if $locale is unknown.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:UNSUPPORTED_LOCALE if $locale is unsupported by the operating system.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"parse-dateTime",qname:"datetime:parse-dateTime",signature:"($input as xs:string, $format as xs:string) as xs:dateTime external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parses a dateTime from a string in the current locale.</p>\n',summary:"<p>  Parses a dateTime from a string in the current locale.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to parse.</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The format string containing zero or more conversion specifications and ordinary characters. All ordinary characters are matched exactly with the buffer; all whitespace characters match any amount of whitespace in the buffer.</div>'}],returns:{type:"xs:dateTime",description:"Returns an xs:dateTime."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_SPECIFICATION if $format contains an invalid conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INSUFFICIENT_BUFFER if $input is insufficient for $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_VALUE if $input contains an invalid value for a conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:LITERAL_MISMATCH if there is a literal characer mismatch between $input and $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INCOMPLETE_DATE_OR_TIME if either the date or time is incomplete.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"parse-dateTime",qname:"datetime:parse-dateTime",signature:"($input as xs:string, $format as xs:string, $locale as xs:string) as xs:dateTime external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parses a dateTime from a string in the given locale.</p>\n',summary:"<p>  Parses a dateTime from a string in the given locale.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to parse.</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The format string containing zero or more conversion specifications and ordinary characters. All ordinary characters are matched exactly with the buffer; all whitespace characters match any amount of whitespace in the buffer.</div>'},{name:"locale",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The locale to use.</div>'}],returns:{type:"xs:dateTime",description:"Returns an xs:dateTime."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_SPECIFICATION if $format contains an invalid conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INSUFFICIENT_BUFFER if $input is insufficient for $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_VALUE if $input contains an invalid value for a conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:LITERAL_MISMATCH if there is a literal characer mismatch between $input and $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INCOMPLETE_DATE_OR_TIME if either the date or time is incomplete.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_LOCALE if $locale is in an invalid format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:UNKNOWN_LOCALE if $locale is unknown.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:UNSUPPORTED_LOCALE if $locale is unsupported by the operating system.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"parse-time",qname:"datetime:parse-time",signature:"($input as xs:string, $format as xs:string) as xs:time external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parses a time from a string in the current locale.</p>\n',summary:"<p>  Parses a time from a string in the current locale.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to parse.</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The format string containing zero or more conversion specifications and ordinary characters. All ordinary characters are matched exactly with the buffer; all whitespace characters match any amount of whitespace in the buffer.</div>'}],returns:{type:"xs:time",description:"Returns an xs:time."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_SPECIFICATION if $format contains an invalid conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INSUFFICIENT_BUFFER if $input is insufficient for $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_VALUE if $input contains an invalid value for a conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:LITERAL_MISMATCH if there is a literal characer mismatch between $input and $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INCOMPLETE_DATE_OR_TIME if the hour has not been parsed.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"parse-time",qname:"datetime:parse-time",signature:"($input as xs:string, $format as xs:string, $locale as xs:string) as xs:time external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parses a time from a string in the given locale.</p>\n',summary:"<p>  Parses a time from a string in the given locale.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to parse.</div>'},{name:"format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The format string containing zero or more conversion specifications and ordinary characters. All ordinary characters are matched exactly with the buffer; all whitespace characters match any amount of whitespace in the buffer.</div>'},{name:"locale",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The locale to use.</div>'}],returns:{type:"xs:time",description:"Returns an xs:time."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_SPECIFICATION if $format contains an invalid conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INSUFFICIENT_BUFFER if $input is insufficient for $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_VALUE if $input contains an invalid value for a conversion specification.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:LITERAL_MISMATCH if there is a literal characer mismatch between $input and $format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INCOMPLETE_DATE_OR_TIME if the hour has not been parsed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:INVALID_LOCALE if $locale is in an invalid format.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:UNKNOWN_LOCALE if $locale is unknown.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">datetime:UNSUPPORTED_LOCALE if $locale is unsupported by the operating system.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"timestamp",qname:"datetime:timestamp",signature:"() as xs:long external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Gets the the number of milliseconds since epoch.</p>\n',summary:"<p>  Gets the the number of milliseconds since epoch.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"xs:long",description:"the said number of milliseconds."},errors:[]},{isDocumented:!0,arity:0,name:"utc-offset",qname:"datetime:utc-offset",signature:"() as xs:long external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Gets the offset of the current timezone from Universal time.</p>\n',summary:"<p>  Gets the offset of the current timezone from Universal time.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"xs:long",description:"the offset in seconds with positive values being east of the prime meridian."},errors:[]}],variables:[]},"http://www.28msec.com/modules/http/util/diagnostic":{ns:"http://www.28msec.com/modules/http/util/diagnostic",description:" This module provides utility functions to help with diagnostic analysis\n / debugging of RESTful Apps or webapps.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/base64",prefix:"base64"},{uri:"http://www.28msec.com/modules/http/util/diagnostic",prefix:"diagnostic"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.28msec.com/modules/http/util/multipart",prefix:"multipart"},{uri:"http://www.28msec.com/modules/http/request",prefix:"request"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"serialize-request-as-html",qname:"diagnostic:serialize-request-as-html",signature:"() as element(*)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a sequence of html elements listing all request\n characteristics.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is helpful for debugging purposes. It can be used\n to output request information within an HTML page.</p>\n',summary:"<p>  Returns a sequence of html elements listing all request\n characteristics.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(*)*",description:"HTML elements describing the request"},errors:[]},{isDocumented:!0,arity:0,name:"serialize-request-as-txt",qname:"diagnostic:serialize-request-as-txt",signature:"() as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a sequence of xs:string listing all request\n characteristics.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is helpful for debugging purposes. It can be used\n to output request information as plan text.</p>\n',summary:"<p>  Returns a sequence of xs:string listing all request\n characteristics.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"sequence of strings describing each characteristic of a request"},errors:[]}],variables:[]},"http://www.28msec.com/modules/credentials":{ns:"http://www.28msec.com/modules/credentials",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for storing credentials\n using an AES-encrypted file the project configuration folder.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the credentials will be stored in the <tt>credentials</tt>\n file in the <tt>config</tt> folder in the project root folder.\n The credentials file is encrypted using 256bit AES encryption. The AES\n key is computed using the project seed. If the project seed is changed the\n credential store is re-encrypted transparently.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Each credential has an associated name and category.\n Credentials can be retrieved specifying their name and category.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For each category, it is possible to specify the default credentials.\n A category default credentials can then be easily retrieved. </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The name of credentials and categories can contain lowercase or\n uppercase letters, digits, and the following special characters: "_" , "-",\n ".". Additionally it must not be empty and must start with a lowercase\n or uppercase letter.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://jsoniq.org/errors",prefix:"jerr"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:3,name:"add-credentials",qname:"credentials:add-credentials",signature:"($category as string, $name as string, $credentials as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Adds the given credentials to the credential store.\n The credentials are not set as default.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If credentials  with the given name and category are already present an\n error is raised.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:add-credentials("S3", "DataBucket", { ... });\n </pre>\n </p>\n',summary:"<p>  Adds the given credentials to the credential store.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"category",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials category name.</div>'},{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials name.</div>'},{name:"credentials",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object containing the credentials data.</div>'}],returns:{type:"object()",description:"the credential object"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:EXIST if credentials with the given name and category are already present.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NAME if the credentials or category name is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:MONGO-DEFAULT if the specified credentials and category name correspond with the default MongoDB credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:TEST if a connection cannot be established using the specified credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']},{isDocumented:!0,arity:4,name:"add-credentials",qname:"credentials:add-credentials",signature:"($category as string, $name as string, $credentials as object(), $default as boolean) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Adds the given credentials to the credential store,\n either as default or not.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If credentials  with the given name and category are already present an\n error is raised.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:add-credentials("S3", "DataBucket", { ... }, true);\n </pre>\n </p>\n',summary:"<p>  Adds the given credentials to the credential store,\n either as default or not.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"category",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials category name.</div>'},{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials name.</div>'},{name:"credentials",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object containing the credentials data.</div>'},{name:"default",type:"boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Whether the credentials will be default or not.</div>'}],returns:{type:"object()",description:"the credential object"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:EXIST if credentials with the given name and category are already present.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NAME if the credentials or category name is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:MONGO-DEFAULT if trying to add the default MongoDB credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:TEST if a connection cannot be established using the specified credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']},{isDocumented:!0,arity:1,name:"credentials",qname:"credentials:credentials",signature:"($category as string) as object()?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the given category\'s default credentials, if any.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If no default credentials are present for the given category\n the empty sequence is returned.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:credentials("S3")\n </pre>\n </p>\n',summary:"<p>  Returns the given category's default credentials, if any.</p>",annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[{name:"category",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The category name.</div>'}],returns:{type:"object()?",description:"The specified category default credentials, if any."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NAME if the credentials or category name is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:MONGO-DEFAULT if the specified category is MongoDB</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']},{isDocumented:!0,arity:2,name:"credentials",qname:"credentials:credentials",signature:"($category as string, $name as string) as object()?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the specified credentials, if present in the credential store.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the specified credentials are not present the empty sequence is returned.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:credentials("S3", "DataBucket")\n </pre>\n </p>\n',summary:"<p>  Returns the specified credentials, if present in the credential store.</p>",annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[{name:"category",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials category name.</div>'},{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials name.</div>'}],returns:{type:"object()?",description:"The specified credentials, if present."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NAME if the credentials or category name is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:MONGO-DEFAULT if the credentials or category name is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']},{isDocumented:!0,arity:0,name:"list-categories",qname:"credentials:list-categories",signature:"() as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all the credentials categories in the credentials store.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If no credentials are stored the empty sequence is returned.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:list-categories()\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned array contains the name of each distinct credential category.</p>\n',summary:"<p>  Lists all the credentials categories in the credentials store.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"array()",description:"An array of all the distinct credentials categories in the credentials store."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']},{isDocumented:!0,arity:1,name:"list-category-credentials",qname:"credentials:list-category-credentials",signature:"($category-name as string) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all the credentials of the specified category in the\n credentials store.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If no credentials for the given category are stored the empty\n sequence is returned.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:list-category-credentials("category-name")\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned array contains one object for each credential. Each object has\n the following structure:\n <pre>\n {\n   "category": "category-name",\n   "name": "credential-name",\n   "default": true\n }\n </pre>\n Specifically the fields of each object have the following meaning:\n <ul>\n  <li>category: the name of the credentials category (string)</li>\n  <li>name: the name of the credentials (string)</li>\n  <li>default: whether the credentials are the default credentials in\n      their category (boolean)</li>\n </ul>\n </p>\n',summary:"<p>  Lists all the credentials of the specified category in the\n credentials store.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"category-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials category name.</div>'}],returns:{type:"array()",description:"An array of all the credentials of the specified category in the credentials store."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NAME if the credentials or category name is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']},{isDocumented:!0,arity:0,name:"list-credentials",qname:"credentials:list-credentials",signature:"() as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all the credentials in the credentials store.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If no credentials are stored the empty sequence is returned.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:list-credentials()\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned array contains one object for each credential. Each object has\n the following structure:\n <pre>\n {\n   "category": "category-name",\n   "name": "credential-name",\n   "default": true\n }\n </pre>\n Specifically the fields of each object have the following meaning:\n <ul>\n  <li>category: the name of the credentials category (string)</li>\n  <li>name: the name of the credentials (string)</li>\n  <li>default: whether the credentials are the default credentials in\n      their category (boolean)</li>\n </ul>\n </p>\n',summary:"<p>  Lists all the credentials in the credentials store.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"array()",description:"An array of all credentials in the credentials store."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']},{isDocumented:!0,arity:2,name:"make-default",qname:"credentials:make-default",signature:"($category as string, $name as string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Makes the specified credentials the default for their category.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It is not allowed to call this method on credentials in the "MongoDB" category.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the specified credentials are not present an error is raised.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:make-default("S3", "DataBucket");\n </pre>\n </p>\n',summary:"<p>  Makes the specified credentials the default for their category.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"category",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials category name.</div>'},{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials name.</div>'}],returns:{type:"empty-sequence()",description:"The empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NOT-EXIST if no credentials with the given name and category are present.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NAME if the credentials or category name is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:MONGO-DEFAULT if the specified category is MongoDB</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']},{isDocumented:!0,arity:2,name:"remove-credentials",qname:"credentials:remove-credentials",signature:"($category as string, $name as string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Removes the specified credentials from the credential store.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If no credentials with the given name and category are present\n in the category store an error is raised.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:remove-credentials("S3", "DataBucket");\n </pre>\n </p>\n',summary:"<p>  Removes the specified credentials from the credential store.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"category",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials category name.</div>'},{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials name.</div>'}],returns:{type:"empty-sequence()",description:"The empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NOT-EXIST if no credentials with the given name and category exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NAME if the credentials or category name is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:MONGO-DEFAULT if the specified credentials and category name correspond with the default MongoDB credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']},{isDocumented:!0,arity:5,name:"update-credentials",qname:"credentials:update-credentials",signature:"($category as string, $name as string, $new-default as boolean?, $new-name as string?, $new-credentials as object()?) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Updates the specified credentials in the credential store.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It is possible to specify whether the credentials should become or stop being the\n default credentials in their category, rename the credentials or change the credentials\n object. These three changes are specified by means of the $new-default, $new-name and\n $new-credentials parameter. If the corresponding parameter is the empty sequence the\n corresponding property will not be changed.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example the following query renames the "DataBucket" credentials in the "S3"\n category as "Bucket":\n <pre>\n import module namespace credentials = "http://www.28msec.com/modules/credentials";\n credentials:update-credentials("S3", "DataBucket", (), "Bucket", () );\n </pre>\n </p>\n',summary:"<p>  Updates the specified credentials in the credential store.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"category",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials category name.</div>'},{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The credentials name.</div>'},{name:"new-default",type:"boolean",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Whether the credentials should become/stop being the default credentials in their category. If it is an empty sequence the current default property will not be changed.</div>'},{name:"new-name",type:"string",occurrence:"?",description:""},{name:"new-credentials",type:"object()",occurrence:"?",description:""}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NOT-EXIST if credentials with the given name and category do not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:EXIST if credentials with the given new name and category are already present.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:NAME if the credentials or category name is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:MONGO-DEFAULT if the specified credentials or category name correspond with the default MongoDB credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:TEST if a connection cannot be established using the specified credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">credentials:CREDENTIALS-STORE if an internal error arises accessing the crendentials store</xqdoc:error>']}],variables:[]},"http://www.28msec.com/modules/parallelism":{ns:"http://www.28msec.com/modules/parallelism",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for executing FLWOR queries in parallel.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">There are two kinds of parallel jobs: map jobs and shuffle jobs.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A map job runs a mapping function on the items of an input collection. The input\n collection is chunked and the mapping function is called on each chunk in parallel.\n The results are either inserted in a single collection, or on one ouptut collection\n for each chunk.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A shuffle job shuffles the items of an input collection to several output collections.\n The input collection is chunked and each chunk is processed in parallel.\n The selection of the output collection for each item is done with a shuffling function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It is also possible to run a map or shuffle job on the output of another map or shuffle\n job (piping).\n Keep in mind though that if an intermediate output is in a\n single collection, no chunking can be done: only the first job of the pipeline can chunk\n its input.\n Hence, for performance, it makes sense that all intermediate jobs\n in the pipeline (except the last one, although not compulsory) output to automatically\n generated temporary collections rather than a single collection. That way, the next job\n can be executed on these collections in parallel.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Map jobs allow the parallel execution of "simple" FLWORs: a for on a big collection, let clauses,\n small for clauses, where clauses.\n Map-shuffle-map piping allows the parallel execution of FLWORs containing a group by clause.\n Jobs can be composed in many ways, for example map-map-shuffle-map-shuffle-map. This way,\n FLWORs with several group by clauses can be parallelized.\n In some circumstances, FLWORs with order by clauses (using bucket sort) can also be\n parallelized, but one should keep in mind that collections are not ordered so that\n any ordering within a map job is susceptible to be lost in the output.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Julien Ribon</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"",prefix:"an"},{uri:"http://www.28msec.com/modules/asynchronous-jobs",prefix:"job"},{uri:"http://www.28msec.com/modules/parallelism",prefix:"parallel"},{uri:"http://zorba.io/modules/random",prefix:"rand"},{uri:"http://www.28msec.com/modules/store",prefix:"store"}],functions:[{isDocumented:!0,arity:1,name:"job-statuses",qname:"parallel:job-statuses",signature:"($id as xs:string) as object()?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the statuses of the underlying asynchronous jobs, as an object\n indicating the number of chunks in each status.</p>\n',summary:"<p>  Returns the statuses of the underlying asynchronous jobs, as an object\n indicating the number of chunks in each status.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The id of the parallel job to query, as it was returned by map or shuffle.</div>'}],returns:{type:"object()?",description:"The statuses of the underlying jobs. The empty sequence if the parallel job does not exist."},errors:[]},{isDocumented:!0,arity:2,name:"map",qname:"parallel:map",signature:"($input as xs:string, $function as function (item()*) as item()*) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Schedules a parallel map job on a collection or on the output of another\n parallel job.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The name of the output collections are randomly generated (one for\n each chunk and start with <tt>_28.temporary</tt>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example of usage:</p>\n parallel:map("input", my:function#1)\n',summary:"<p>  Schedules a parallel map job on a collection or on the output of another\n parallel job.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to process, or the id of a parallel job of which the output will be taken.</div>'},{name:"function",type:"function (item()*) as item()*",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the function which is run in parallel on the collection\'s contents.</div>'}],returns:{type:"xs:string",description:"A parallel job id that can be used to query the parallel job's properties."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0005 if the supplied function does not have a name.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0006 if the supplied function is in the local namespace.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JPDY0001 if the input is not an available collection or a parallel job id.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"map",qname:"parallel:map",signature:"($input as xs:string, $function as function (item()*) as item()*, $options as object()?) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Schedules a parallel map job on a collection or on the output of another\n parallel job.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The $options parameter allows for the specification of properties for\n the parallel job. Allowed options are:\n <ul>\n   <li><tt>output-collection as string</tt>: the name of the collection in\n     which the output of the executed query is stored. If not specified,\n     the result of the query will be stored in a collection withing the\n     MongoDB database associated with the project. The name of the\n     collection is randomly generated and starts with <tt>_28.temporary</tt>\n   </li>\n   <li><tt>chunk-size</tt>: the size of the chunks the collection must be split\n   into, if it is not already sharded (default: MongoDB sharding, or 1000).\n   </li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example of usage:</p>\n parallel:map("input", my:function#1, { "chunk-size" : xs:int(1000) })\n parallel:map("input",\n              my:function#1,\n              {\n                "chunk-size" : xs:int(1000),\n                "output-collection" : output"\n              }\n )\n',summary:"<p>  Schedules a parallel map job on a collection or on the output of another\n parallel job.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to process, or the id of a parallel job of which the output will be taken.</div>'},{name:"function",type:"function (item()*) as item()*",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The function which is run in parallel on the collection\'s contents.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying above options for the parallel job.</div>'}],returns:{type:"xs:string",description:"A parallel job id that can be used to query the parallel job's properties."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if the type of a supplied option is incorrect.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0005 if the supplied function does not have a name.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0006 if the supplied function is in the local namespace.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JPDY0001 if the input is not an available collection or a parallel job id.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"output-collections",qname:"parallel:output-collections",signature:"($id as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the output collections of the specified parallel job.</p>\n',summary:"<p>  Returns the output collections of the specified parallel job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The id of the parallel job to query, as it was returned by map or shuffle.</div>'}],returns:{type:"xs:string*",description:"The names of the output collections to which the corresponding parallel job writes. The empty sequence if the job does not exist."},errors:[]},{isDocumented:!0,arity:1,name:"results",qname:"parallel:results",signature:"($id as xs:string) as item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the results of the specified parallel job.</p>\n',summary:"<p>  Returns the results of the specified parallel job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The id of the parallel job to query, as it was returned by map or shuffle.</div>'}],returns:{type:"item()*",description:"The structured items output by the corresponding parallel job. The empty sequence if the job does not exist."},errors:[]},{isDocumented:!0,arity:2,name:"shuffle",qname:"parallel:shuffle",signature:"($input as xs:string, $function as function (item()) as xs:integer) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Schedules a parallel shuffle job on a collection or on the output of another\n parallel job.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The output collection for each item is determined by calling the shuffle function,\n which gives an integer i. The i-th output collection\n is then taken. If necessary, a modulo operation is done\n to make sure that the integer is comprised between 1 and the number of output collections.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The name of the output collections are randomly generated (10 of them) and\n start with <tt>_28.temporary</tt>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example of usage:</p>\n parallel:shuffle("input", my:function#1)\n',summary:"<p>  Schedules a parallel shuffle job on a collection or on the output of another\n parallel job.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to process, or the id of a parallel job of which the output will be taken.</div>'},{name:"function",type:"function (item()) as xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the function which is run on each item to determine where it is shuffled to.</div>'}],returns:{type:"xs:string",description:"A parallel job id that can be used to query the parallel job's properties."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0005 if the supplied function does not have a name.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0006 if the supplied function is in the local namespace.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JPDY0001 if the input is not an available collection or a parallel job id.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"shuffle",qname:"parallel:shuffle",signature:"($input as item(), $function as function (item()) as xs:integer, $options as object()?) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Schedules a parallel shuffle job on a collection or on the output of another\n parallel job.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The output collection for each item is determined by calling the shuffle function,\n which gives an integer i. The i-th output collection\n is then taken. If necessary, a modulo operation is done\n to make sure that the integer is comprised between 1 and the number of output collections.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The $options parameter allows for the specification of properties for\n the parallel shuffle job. Allowed options are:\n <ul>\n   <li><tt>number-of-output-collections as integer</tt>: the number of output collections\n     to automatically generate if none are provided. The default value is 10. An error is raised\n     if the provided value is not positive.\n   </li>\n   <li><tt>output-collections as array</tt>: an array with the names of the collections in\n     which the items of the input collections are shuffled. If not specified,\n     these collections will be automatically generated (as many as specified in the\n     <tt>number-of-output-collections</tt> option) in the\n     MongoDB database associated with the project. The name of the\n     collections are randomly generated and start with <tt>_28.temporary</tt>\n   </li>\n   <li><tt>chunk-size</tt>: the size of the chunks the collection must be split\n   into, if it is not already sharded (default: MongoDB sharding, or 1000).\n   </li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example of usage:</p>\n parallel:shuffle("input", my:function#1, { "chunk-size" : xs:int(1000) })\n parallel:shuffle("input",\n                  my:function#1,\n                  {\n                    "chunk-size" : xs:int(1000),\n                    "output-collections" : [ "output1", "output2" ]\n                  }\n )\n parallel:shuffle("input",\n                  my:function#1,\n                  {\n                    "number-of-output-collections" : 20\n                  }\n )\n',summary:"<p>  Schedules a parallel shuffle job on a collection or on the output of another\n parallel job.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"input",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to process, or the id of a parallel job of which the output will be taken.</div>'},{name:"function",type:"function (item()) as xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the function which is run on each item to determine where it is shuffled to.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying above options for the parallel shuffle job.</div>'}],returns:{type:"xs:string",description:"A parallel job id that can be used to query the parallel job's properties."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if the type of a supplied option is incorrect.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0005 if the supplied function does not have a name.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0006 if the supplied function is in the local namespace.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JPDY0001 if the input is not an available collection or a parallel job id.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FOCA0002 if number-of-output-collections is not a positive integer.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"status",qname:"parallel:status",signature:"($id as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the general status of the parallel job.</p>\n',summary:"<p>  Returns the general status of the parallel job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> id of the parallel job to query, as it was returned by map or shuffle.</div>'}],returns:{type:"xs:string?",description:"The status of the corresponding parallel job. The empty sequence if the job does not exist."},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/image/graphviz":{ns:"http://www.zorba-xquery.com/modules/image/graphviz",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Module that provides functions for generating SVG graphs.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The module provides two function for generating graphs given in the :\n <ul><li>DOT language (see <a href="http://www.graphviz.org/">\n http://www.graphviz.org</a>)</li><li>or in the XML-based Graph eXchange\n Language (see <a href="http://www.gupro.de/GXL/">http://www.gupro.de/GXL/</a>),\n respectively.</li></ul>\n Both functions use the Graphviz Visualization Library in order to\n layout and render the graphs. As a result, both return a sequence\n of (document)-nodes (one for each input graph).\n These nodes are instances of the Scalable Vector Graphics (SVG) format.\n SVG is a language for describing two-dimensional graphics and\n graphical applications in XML. More information about SVG can\n be found at <a href="http://www.w3.org/Graphics/SVG/">http://www.w3.org/Graphics/SVG/</a>.\n As second parameters, both functions take a sequence of strings that\n are parameters for the graph generation and rendering algorithms.\n Currently, only the empty-sequence is allowed here.\n These parameters exist for future use.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that this feature is only available on Unix-based\n platforms (i.e. not on Windows).</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.28msec.com/home/index">28msec</a></xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/image/graphviz",prefix:"gr"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"dot",qname:"gr:dot",signature:"($dot as xs:string*, $params as xs:string*) as node()* external",description:' Layout one ore more graphs given in the DOT language and render\n them as SVG. For example,\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"><code>\n dot("digraph mygraph { p -&gt; q }", ())\n </code></p>\n',summary:"<p> Layout one ore more graphs given in the DOT language and render\n them as SVG.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"dot",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A dot description of the graph to render.</div>'},{name:"params",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Parameters to configure the layout and rendering process. Currently, only the empty-sequence is allowed here.</div>'}],returns:{type:"node()*",description:"A graph for each item in the sequence given using the first parameter. The result sequence consists of items which are instance of the SVG data model."},errors:[]},{isDocumented:!0,arity:2,name:"gxl",qname:"gr:gxl",signature:"($gxl as node()*, $params as xs:string*) as node()* external",description:" Layout one ore more graphs given in the GXL language and render\n them as SVG.\n",summary:"<p> Layout one ore more graphs given in the GXL language and render\n them as SVG.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"gxl",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A GXL description of the graph to render.</div>'},{name:"params",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Parameters to configure the layout and rendering process. Currently, only the empty-sequence is allowed here.</div>'}],returns:{type:"node()*",description:"A graph for each item in the sequence given using the first parameter. The result sequence consists of items which are instance of the SVG data model."},errors:[]}],variables:[]},"http://zorba.io/modules/data-cleaning/token-based-string-similarity":{ns:"http://zorba.io/modules/data-cleaning/token-based-string-similarity",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This library module provides token-based string similarity functions that view strings\n as sets or multi-sets of tokens and use set-related properties to compute similarity scores.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The tokens correspond to groups of characters extracted from the strings being compared, such as\n individual words or character n-grams.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">These functions are particularly useful for matching near duplicate strings in cases where\n typographical conventions often lead to rearrangement of words (e.g., "John Smith" versus "Smith, John").</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The logic contained in this module is not specific to any particular XQuery implementation,\n although the module requires the trigonometic functions of XQuery 3.0 or a math extension\n function such as sqrt($x as numeric) for computing the square root.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Bruno Martins</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xpath-functions/math",prefix:"math"},{uri:"http://zorba.io/modules/data-cleaning/set-similarity",prefix:"set"},{uri:"http://zorba.io/modules/data-cleaning/token-based-string-similarity",prefix:"simt"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:3,name:"cosine-ngrams",qname:"simt:cosine-ngrams",signature:"($s1 as xs:string, $s2 as xs:string, $n as xs:integer) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the cosine similarity coefficient between sets of character n-grams extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The n-grams from each string are weighted according to their occurence frequency (i.e., weighted according to\n the term-frequency heuristic from Information Retrieval).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> cosine-ngrams("DWAYNE", "DUANE", 2 ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.2401922307076307 </pre></p>\n',summary:"<p>  Returns the cosine similarity coefficient between sets of character n-grams extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"n",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of characters to consider when extracting n-grams.</div>'}],returns:{type:"xs:double",description:"The cosine similarity coefficient between the sets n-grams extracted from the two strings."},errors:[]},{isDocumented:!0,arity:3,name:"cosine-tokens",qname:"simt:cosine-tokens",signature:"($s1 as xs:string, $s2 as xs:string, $r as xs:string) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the cosine similarity coefficient between sets of tokens extracted from two strings. The tokens\n from each string are weighted according to their occurence frequency (i.e., weighted according to the\n term-frequency heuristic from Information Retrieval).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> cosine-tokens("The FLWOR Foundation", "FLWOR Found.", " +" ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.408248290463863 </pre></p>\n',summary:"<p>  Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'}],returns:{type:"xs:double",description:"The cosine similarity coefficient between the sets tokens extracted from the two strings."},errors:[]},{isDocumented:!0,arity:2,name:"cosine",qname:"simt:cosine",signature:"($desc1 as xs:string*, $desc2 as xs:string*) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Auxiliary function for computing the cosine similarity coefficient between strings,\n using stringdescriptors based on sets of character n-grams or sets of tokens extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> cosine( ("aa","bb") , ("bb","aa")) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 1.0 </pre></p>\n',summary:"<p>  Auxiliary function for computing the cosine similarity coefficient between strings,\n using stringdescriptors based on sets of character n-grams or sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"desc1",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The descriptor for the first string.</div>'},{name:"desc2",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The descriptor for the second string.</div>'}],returns:{type:"xs:double",description:"The cosine similarity coefficient between the descriptors for the two strings."},errors:[]},{isDocumented:!0,arity:3,name:"dice-ngrams",qname:"simt:dice-ngrams",signature:"($s1 as xs:string, $s2 as xs:string, $n as xs:integer) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Dice similarity coefficient between sets of character n-grams extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> dice-ngrams("DWAYNE", "DUANE", 2 ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.4615384615384616 </pre></p>\n',summary:"<p>  Returns the Dice similarity coefficient between sets of character n-grams extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"n",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of characters to consider when extracting n-grams.</div>'}],returns:{type:"xs:double",description:"The Dice similarity coefficient between the sets of character n-grams extracted from the two strings."},errors:[]},{isDocumented:!0,arity:3,name:"dice-tokens",qname:"simt:dice-tokens",signature:"($s1 as xs:string, $s2 as xs:string, $r as xs:string) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Dice similarity coefficient between sets of tokens extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> dice-tokens("The FLWOR Foundation", "FLWOR Found.", " +" ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.4 </pre></p>\n',summary:"<p>  Returns the Dice similarity coefficient between sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'}],returns:{type:"xs:double",description:"The Dice similarity coefficient between the sets tokens extracted from the two strings."},errors:[]},{isDocumented:!0,arity:3,name:"jaccard-ngrams",qname:"simt:jaccard-ngrams",signature:"($s1 as xs:string, $s2 as xs:string, $n as xs:integer) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Jaccard similarity coefficient between sets of character n-grams extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> jaccard-ngrams("DWAYNE", "DUANE", 2 ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.3 </pre></p>\n',summary:"<p>  Returns the Jaccard similarity coefficient between sets of character n-grams extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"n",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of characters to consider when extracting n-grams.</div>'}],returns:{type:"xs:double",description:"The Jaccard similarity coefficient between the sets of character n-grams extracted from the two strings."},errors:[]},{isDocumented:!0,arity:3,name:"jaccard-tokens",qname:"simt:jaccard-tokens",signature:"($s1 as xs:string, $s2 as xs:string, $r as xs:string) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Jaccard similarity coefficient between sets of tokens extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> jaccard-tokens("The FLWOR Foundation", "FLWOR Found.", " +" ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.25 </pre></p>\n',summary:"<p>  Returns the Jaccard similarity coefficient between sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'}],returns:{type:"xs:double",description:"The Jaccard similarity coefficient between the sets tokens extracted from the two strings."},errors:[]},{isDocumented:!0,arity:2,name:"ngrams",qname:"simt:ngrams",signature:"($s as xs:string, $n as xs:integer) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the individual character n-grams forming a string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> ngrams("FLWOR", 2 ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> ("_F" , "FL" , "LW" , "WO" , "LW" , "WO" , "OR" , "R_") </pre></p>\n',summary:"<p>  Returns the individual character n-grams forming a string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The input string.</div>'},{name:"n",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of characters to consider when extracting n-grams.</div>'}],returns:{type:"xs:string*",description:"The sequence of strings with the extracted n-grams."},errors:[]},{isDocumented:!0,arity:3,name:"overlap-ngrams",qname:"simt:overlap-ngrams",signature:"($s1 as xs:string, $s2 as xs:string, $n as xs:integer) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the overlap similarity coefficient between sets of character n-grams extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> overlap-ngrams("DWAYNE", "DUANE", 2 ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.5 </pre></p>\n',summary:"<p>  Returns the overlap similarity coefficient between sets of character n-grams extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"n",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of characters to consider when extracting n-grams.</div>'}],returns:{type:"xs:double",description:"The overlap similarity coefficient between the sets of character n-grams extracted from the two strings."},errors:[]},{isDocumented:!0,arity:3,name:"overlap-tokens",qname:"simt:overlap-tokens",signature:"($s1 as xs:string, $s2 as xs:string, $r as xs:string) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the overlap similarity coefficient between sets of tokens extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> overlap-tokens("The FLWOR Foundation", "FLWOR Found.", " +" ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.5 </pre></p>\n',summary:"<p>  Returns the overlap similarity coefficient between sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'}],returns:{type:"xs:double",description:"The overlap similarity coefficient between the sets tokens extracted from the two strings."},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/image/paint":{ns:"http://www.zorba-xquery.com/modules/image/paint",description:' This module provides a function to extend an image with additional shapes.\n Fully supported image formats are:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>GIF</li>\n   <li>JPEG</li>\n   <li>PNG</li>\n   <li>TIFF</li>\n   <li>BMP</li>\n </ul>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The errors raised by functions of this module have the namespace\n <tt>http://www.zorba-xquery.com/modules/image/error</tt> (associated with prefix ierr).</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Thomas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.zorba-xquery.com/modules/image/error",prefix:"ierr"},{uri:"http://www.zorba-xquery.com/modules/image/image",prefix:"img"},{uri:"http://www.zorba-xquery.com/modules/image/paint",prefix:"paint"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"paint",qname:"paint:paint",signature:"($image as xs:base64Binary, $shapes as element(*)*) as xs:base64Binary",description:' Extends the passed image with a sequence of shapes.\n The shapes are passed as a sequence of elements.\n The possibilities for shape elements are:\n    <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n      <li> line:\n        <pre class="brush: xml">\n          &lt;img:line&gt;\n            &lt;img:start&gt;&lt;img:x&gt;-20&lt;/img:x&gt;&lt;img:y&gt;-20&lt;/img:y&gt;&lt;/img:start&gt;\n            &lt;img:end&gt;&lt;img:x&gt;80&lt;/img:x&gt;&lt;img:y&gt;80&lt;/img:y&gt;&lt;/img:end&gt;\n          &lt;/img:line&gt;</pre>\n      </li>\n       <li> polyline:\n         <pre class="brush: xml">\n           &lt;img:polyLine&gt;\n             &lt;img:point&gt;&lt;img:x&gt;10&lt;/img:x&gt;&lt;img:y&gt;10&lt;/img:y&gt;&lt;/img:point&gt;\n             &lt;img:point&gt;&lt;img:x&gt;40&lt;/img:x&gt;&lt;img:y&gt;80&lt;/img:y&gt;&lt;/point&gt;\n             &lt;img:point&gt;&lt;img:x&gt;50&lt;/img:x&gt;&lt;img:y&gt;30&lt;/img:y&gt;&lt;/point&gt;\n             &lt;img:point&gt;&lt;img:x&gt;200&lt;/img:x&gt;&lt;img:y&gt;200&lt;/img:y&gt;&lt;/point&gt;\n           &lt;/img:polyLine&gt;\n         </pre>\n       </li>\n       <li> stroked polyline:\n         <pre class="brush: xml">\n           &lt;img:strokedPolyLine&gt;\n             &lt;img:point&gt;&lt;img:x&gt;10&lt;/img:x&gt;&lt;img:y&gt;10&lt;/img:y&gt;&lt;/img:point&gt;\n             &lt;img:point&gt;&lt;img:x&gt;40&lt;/img:x&gt;&lt;img:y&gt;80&lt;/img:y&gt;&lt;/img:point&gt;\n             &lt;img:point&gt;&lt;img:x&gt;50&lt;/img:x&gt;&lt;img:y&gt;30&lt;/img:y&gt;&lt;/img:point&gt;\n             &lt;img:strokeLength&gt;5&lt;/img:strokeLength&gt;&lt;img:gapLength&gt;2&lt;/img:gapLength&gt;\n           &lt;/img:strokedPolyLine&gt;\n         </pre>\n       </li>\n       <li> rectangle:\n         <pre class="brush: xml">\n           &lt;img:rectangle&gt;\n             &lt;img:upperLeft&gt;&lt;img:x&gt;20&lt;/img:x&gt;&lt;img:y&gt;20&lt;/img:y&gt;&lt;/img:upperLeft&gt;\n             &lt;img:lowerRight&gt;&lt;img:x&gt;50&lt;/img:x&gt;&lt;img:y&gt;50&lt;/img:y&gt;&lt;/img:lowerRight&gt;\n           &lt;/img:rectangle&gt;\n         </pre>\n       </li>\n       <li> rounded rectangle:\n         <pre class="brush: xml">\n           &lt;img:roundedRectangle&gt;\n             &lt;img:upperLeft&gt;&lt;img:x&gt;20&lt;/img:x&gt;&lt;img:y&gt;20&lt;/img:y&gt;&lt;/img:upperLeft&gt;\n             &lt;img:lowerRight&gt;&lt;img:x&gt;50&lt;/img:x&gt;&lt;img:y&gt;50&lt;/img:y&gt;&lt;/img:lowerRight&gt;\n             &lt;img:cornerWidth&gt;10&lt;/img:cornerWidth&gt;&lt;img:cornerHeight&gt;10&lt;/img:cornerHeight&gt;\n           &lt;/img:roundedRectangle&gt;\n         </pre>\n       </li>\n       <li> circle:\n         <pre class="brush: xml">\n           &lt;img:circle&gt;\n             &lt;img:origin&gt;&lt;img:x&gt;20&lt;/img:x&gt;&lt;img:y&gt;20&lt;/img:y&gt;&lt;/img:origin&gt;\n             &lt;img:perimeter&gt;5&lt;/img:perimeter&gt;\n           &lt;/img:circle&gt;\n         </pre>\n       </li>\n       <li> ellipse:\n         <pre class="brush: xml">\n           &lt;img:ellipse&gt;\n             &lt;img:origin&gt;&lt;img:x&gt;50&lt;/img:x&gt;&lt;img:y&gt;50&lt;/img:y&gt;&lt;/img:origin&gt;\n             &lt;img:perimeterX&gt;30&lt;/img:perimeterX&gt;&lt;img:perimeterY&gt;20&lt;/img:perimeterY&gt;\n           &lt;/img:ellipse&gt;\n         </pre>\n       </li>\n       <li> arc:\n         <pre class="brush: xml">\n           &lt;img:arc&gt;\n             &lt;img:origin&gt;&lt;img:x&gt;50&lt;/img:x&gt;&lt;img:y&gt;50&lt;/img:y&gt;&lt;/img:origin&gt;\n             &lt;img:perimeterX&gt;10&lt;/img:perimeterX&gt;&lt;img:perimeterY&gt;20&lt;/img:perimeterY&gt;\n             &lt;img:startDegrees&gt;180&lt;/img:startDegrees&gt;&lt;img:endDegrees&gt;270&lt;/img:endDegrees&gt;\n           &lt;/img:arc&gt;\n         </pre>\n       </li>\n       <li> polygon:\n         <pre class="brush: xml">\n           &lt;img:polygon&gt;\n             &lt;img:point&gt;&lt;img:x&gt;10&lt;/img:x&gt;&lt;img:y&gt;10&lt;/img:y&gt;&lt;/img:point&gt;\n             &lt;img:point&gt;&lt;img:x&gt;40&lt;/img:x&gt;&lt;img:y&gt;80&lt;/img:y&gt;&lt;/img:point&gt;\n             &lt;img:point&gt;&lt;img:x&gt;50&lt;/img:x&gt;&lt;img:y&gt;30&lt;/img:y&gt;&lt;/img:point&gt;\n           &lt;/img:polygon&gt;\n         </pre>\n       </li>\n       <li> text:\n         <pre class="brush: xml">\n           &lt;img:text&gt;\n             &lt;img:origin&gt;&lt;img:x&gt;20&lt;/img:x&gt;&lt;img:y&gt;20&lt;/img:y&gt;&lt;/img:origin&gt;\n             &lt;img:text&gt;Hello Zorba&lt;/img:text&gt;&lt;img:font&gt;&lt;/img:font&gt;&lt;img:font-size&gt;12&lt;/img:font-size&gt;\n           &lt;/img:text&gt;\n         </pre>\n       </li>\n     </ul>\n Optionally, each of the shape elements can contain elements to define the stroke with, stroke color, fill color, and anti-aliasing.\n E.g.:\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <pre class="brush: xml">\n     &lt;img:rectangle&gt;\n       &lt;img:strokeWidth&gt;5&lt;/img:strokeWidth&gt;\n       &lt;img:strokeColor&gt;#00AF00&lt;/img:strokeColor&gt;\n       &lt;img:fillColor&gt;#A10000&lt;/img:fillColor&gt;\n       &lt;img:antiAliasing&gt;true&lt;/img:antiAliasing&gt;\n       &lt;img:upperLeft&gt;&lt;img:x&gt;20&lt;/img:x&gt;&lt;img:y&gt;20&lt;/img:y&gt;&lt;/img:upperLeft&gt;\n       &lt;img:lowerRight&gt;&lt;img:x&gt;50&lt;/img:x&gt;&lt;img:y&gt;50&lt;/img:y&gt;&lt;/img:lowerRight&gt;\n     &lt;/img:rectangle&gt;\n   </pre>\n  </p>\n',summary:"<p> Extends the passed image with a sequence of shapes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the passed image</div>'},{name:"shapes",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the shapes</div>'}],returns:{type:"xs:base64Binary",description:"image with additional shapes"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 the passed image is invalid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FORG0001 one of the passed shape elements is invalid.</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/fetch":{ns:"http://zorba.io/modules/fetch",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functions to fetch the content of a resource identified\n by a URI. For example, it fetches the content of file or http resources.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In order to retrieve such content, the functions use the\n URI resolution and URL resolver process as documented at\n <a href="../zorba/uriresolvers.html">\n URI Resolvers</a>.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/fetch",prefix:"fetch"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"content-binary",qname:"fetch:content-binary",signature:"($uri as xs:string) as xs:base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Tries to fetch the resource referred to by the given URI and\n returning it as base64Binary.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It queries all URI mappers and resolvers with kind\n <tt>EntityData::SOME_CONTENT</tt>.</p>\n',summary:"<p>  Tries to fetch the resource referred to by the given URI and\n returning it as base64Binary.</p>",annotation_str:" %an:streamable",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"streamable",value:""}],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the resource to fetch.</div>'}],returns:{type:"xs:base64Binary",description:"the resource referred to by the given URI as streamble base64Binary."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:URI_UNRESOLVED_OR_NOSTREAM if the URI could not be resolved or did not resolve to a <tt>StreamResource</tt>.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"content-binary",qname:"fetch:content-binary",signature:"($uri as xs:string, $entity-kind as xs:string) as xs:base64Binary external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Tries to fetch the resource referred to by the given URI and\n returning it as base64Binary.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It queries all URI mappers and resolvers with kind the specified\n entity kind.</p>\n',summary:"<p>  Tries to fetch the resource referred to by the given URI and\n returning it as base64Binary.</p>",annotation_str:" %an:streamable",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"streamable",value:""}],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the resource to fetch.</div>'},{name:"entity-kind",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the kind of resource to fetch.</div>'}],returns:{type:"xs:base64Binary",description:"the resource referred to by the given URI as streamble base64Binary."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:URI_UNRESOLVED_OR_NOSTREAM if the URI could not be resolved or did not resolve to a <tt>StreamResource</tt>.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"content",qname:"fetch:content",signature:"($uri as xs:string) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Tries to fetch the resource referred to by the given URI.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It queries all URI mappers and resolvers with kind\n <tt>EntityData::SOME_CONTENT</tt>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The content is assumed to be UTF-8 encoded.</p>\n',summary:"<p>  Tries to fetch the resource referred to by the given URI.</p>",annotation_str:" %an:streamable",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"streamable",value:""}],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the resource to fetch.</div>'}],returns:{type:"xs:string",description:"the resource referred to by the given URI as streamble string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:URI_UNRESOLVED_OR_NOSTREAM if the URI could not be resolved or did not resolve to a <tt>StreamResource</tt>.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"content",qname:"fetch:content",signature:"($uri as xs:string, $entity-kind as xs:string) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Tries to fetch the resource referred to by the given URI.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It queries all URI mappers and resolvers with kind the specified\n entity kind.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The content is assumed to be UTF-8 encoded.</p>\n',summary:"<p>  Tries to fetch the resource referred to by the given URI.</p>",annotation_str:" %an:streamable",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"streamable",value:""}],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the resource to fetch.</div>'},{name:"entity-kind",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the kind of resource to fetch.</div>'}],returns:{type:"xs:string",description:"the resource referred to by the given URI as streamble string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:URI_NOT_RESOLVED_OR_NOSTREAM if the URI could not be resolved or did not resolve to a <tt>StreamResource</tt>.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"content",qname:"fetch:content",signature:"($uri as xs:string, $entity-kind as xs:string, $encoding as xs:string) as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Tries to fetch the resource referred to by the given URI.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It queries all URI mappers and resolvers with kind the specified\n entity kind.</p>\n',summary:"<p>  Tries to fetch the resource referred to by the given URI.</p>",annotation_str:" %an:streamable",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"streamable",value:""}],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the resource to fetch.</div>'},{name:"entity-kind",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the kind of resource to fetch.</div>'},{name:"encoding",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the encoding of the content</div>'}],returns:{type:"xs:string",description:"the resource referred to by the given URI as streamble string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:URI_UNRESOLVED_OR_NOSTREAM if the URI could not be resolved or did not resolve to a <tt>StreamResource</tt>.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:CHARSET_UNKNOWN if the given encoding is invalid or not supported.</xqdoc:error>']}],variables:[]},"http://xbrl.io/modules/bizql/concept-maps":{ns:"http://xbrl.io/modules/bizql/concept-maps",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functions for storing, retrieving, and modifying\n concept maps. Concept maps can be used in BizQL queries.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A concept map is a network of concepts that can be contained in a report schema.\n It maps "virtual" concepts to reported concepts, which allows comparison across\n archives that use different vocabularies (so-called extension facts).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve the concept map associated with each report\n schema. You can also query for facts by making implicitly use of the mapping.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/concept-maps",prefix:"concept-maps"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://xbrl.io/modules/bizql/networks",prefix:"networks"},{uri:"http://xbrl.io/modules/bizql/report-schemas",prefix:"report-schemas"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"concept-maps",qname:"concept-maps:concept-maps",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all concept maps.</p>\n',summary:"<p>  Retrieves all concept maps.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"all concept maps."},errors:[]},{isDocumented:!0,arity:1,name:"concept-maps",qname:"concept-maps:concept-maps",signature:"($report-schemas-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the concept maps from the given report schemas.</p>\n',summary:"<p>  Return the concept maps from the given report schemas.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"report-schemas-or-ids",type:"item()",occurrence:"*",description:""}],returns:{type:"object()*",description:"the concept maps from the report schemas."},errors:[]},{isDocumented:!0,arity:3,name:"facts-for-archives-and-concepts",qname:"concept-maps:facts-for-archives-and-concepts",signature:"($archive-or-ids as item()*, $concepts as string*, $concept-maps as object()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Resolves the supplied concepts according to the supplied concept map.</p>\n',summary:"<p>  Resolves the supplied concepts according to the supplied concept map.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or AIDs (or $concept-maps:ALL_OF_THEM to do no filter on archives).</div>'},{name:"concepts",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of concept names (or $concept-maps:ALL_OF_THEM to do no filter on concepts).</div>'},{name:"concept-maps",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of concept maps.</div>'}],returns:{type:"object()*",description:"the resolved facts, with the concept name overriden with the new name."},errors:[]},{isDocumented:!0,arity:4,name:"facts-for-archives-and-concepts",qname:"concept-maps:facts-for-archives-and-concepts",signature:"($archive-or-ids as item()*, $concepts as string*, $concept-maps as object()+, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Resolves the supplied concepts according to the supplied concept map.</p>\n',summary:"<p>  Resolves the supplied concepts according to the supplied concept map.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or AIDs (or $concept-maps:ALL_OF_THEM to do no filter on archives).</div>'},{name:"concepts",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of concept names (or $concept-maps:ALL_OF_THEM to do no filter on concepts).</div>'},{name:"concept-maps",type:"object()",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of concept maps.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="facts#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"the resolved facts, with the concept name overriden with the new name."},errors:[]}],variables:[{name:"concept-maps:ALL_OF_THEM",type:"boolean",description:" Joker for all archives or all concepts.\n"}]},"http://www.28msec.com/modules/http/cookie":{ns:"http://www.28msec.com/modules/http/cookie",description:" The Sausalito Cookie module provides function to manipulate\n HTTP-Cookies.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/http/cookie",prefix:"cookie"},{uri:"http://www.28msec.com/modules/http/cookie",prefix:"cookie-schema"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://www.28msec.com/modules/http/response",prefix:"resp"},{uri:"http://zorba.io/modules/schema",prefix:"schema"},{uri:"http://www.zorba-xquery.com/modules/cryptography/hmac",prefix:"sec"},{uri:"http://zorba.io/modules/uri",prefix:"uri"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"create-session",qname:"cookie:create-session",signature:"($sessionData as node()) as empty-sequence()",description:' Creates a client-side cookie named "_session", containing the\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$sessionData</tt> node value together with its signature.\n The signature is generated with the server\'s private key.\n',summary:'<p> Creates a client-side cookie named "_session", containing the\n  $sessionData  node value together with its signature.</p>',annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"sessionData",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The data to be used for the session.</div>'}],returns:{type:"empty-sequence()",description:"The empty-sequence is returned."},errors:[]},{isDocumented:!0,arity:2,name:"create-session",qname:"cookie:create-session",signature:"($sessionData as node(), $expires as xs:dateTime) as empty-sequence()",description:' Creates a client-side cookie named "_session", containing the\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$sessionData</tt> node value together with its signature.\n The signature is generated with the server\'s private key.\n The cookie is also set to expire on the date specified by\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$expires</tt>.\n',summary:'<p> Creates a client-side cookie named "_session", containing the\n  $sessionData  node value together with its signature.</p>',annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"sessionData",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The data to be used for the session.</div>'},{name:"expires",type:"xs:dateTime",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The expiration time of the cookie.</div>'}],returns:{type:"empty-sequence()",description:"The empty-sequence is returned."},errors:[]},{isDocumented:!0,arity:3,name:"create-session",qname:"cookie:create-session",signature:"($sessionData as node(), $expires as xs:dateTime?, $path as xs:string?) as empty-sequence()",description:' Creates a client-side cookie named "_session", containing the\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$sessionData</tt> node value together with its signature.\n The signature is generated with the server\'s private key.\n The cookie is also set to expire on the date specified by\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$expires</tt>. The cookie is only valid for the specified path.\n',summary:'<p> Creates a client-side cookie named "_session", containing the\n  $sessionData  node value together with its signature.</p>',annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"sessionData",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The data to be used for the session.</div>'},{name:"expires",type:"xs:dateTime",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The expiration time of the cookie.</div>'},{name:"path",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The path of the URL for which the cookie is valid.</div>'}],returns:{type:"empty-sequence()",description:"The empty-sequence is returned."},errors:[]},{isDocumented:!0,arity:0,name:"delete-session",qname:"cookie:delete-session",signature:"() as empty-sequence()",description:' Delete the "_session" cookie from the client. The next\n user request will not receive a valid session cookie\n anymore\n',summary:'<p> Delete the "_session" cookie from the client.</p>',annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"empty-sequence()",description:"The empty-sequence is returned."},errors:[]},{isDocumented:!0,arity:1,name:"delete-session",qname:"cookie:delete-session",signature:"($path as xs:string?) as empty-sequence()",description:' Delete the "_session" cookie from the client. The next\n user request will not receive a valid session cookie\n anymore\n',summary:'<p> Delete the "_session" cookie from the client.</p>',annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"path",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The path of the URL for which the cookie is valid.</div>'}],returns:{type:"empty-sequence()",description:"The empty-sequence is returned."},errors:[]},{isDocumented:!0,arity:1,name:"get",qname:"cookie:get",signature:"($name as xs:string?) as element(cookie:cookie)*",description:' Returns the cookie in the request having the given name or the empty sequence\n if no such cookie exists. The cookie format returned is:\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">\n &lt;cookie:cookie\n   name=".."&gt;...&lt;/cookie:cookie&gt;</tt>.\n The content of the cookie element is the value of the cookie.\n',summary:"<p> Returns the cookie in the request having the given name or the empty sequence\n if no such cookie exists.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the cookie that should be retrieved.</div>'}],returns:{type:"element(cookie:cookie)*",description:"The cookie with the given name or the empty sequence if no cookie with the given name exist"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cookie:S003 if $decode evaluates to fn:true() and the value of the cookie cannot be parsed.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"get",qname:"cookie:get",signature:"($name as xs:string?, $decode as xs:boolean) as element(cookie:cookie)*",description:" Returns the cookies in the request having the given name. If no name is given,\n it returns all available cookies. If no cookie value decoding is wanted,\n the user must specify a second argument that evaluates to fn:false().\n",summary:"<p> Returns the cookies in the request having the given name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the cookie that should be retrieved</div>'},{name:"decode",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Boolean to specify if cookie value decoding id needed</div>'}],returns:{type:"element(cookie:cookie)*",description:"The cookie with the given name or the empty sequence if no cookie with the given name exist"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cookie:S003 if $decode evaluates to fn:true() and the value of the cookie cannot be parsed.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"session-data",qname:"cookie:session-data",signature:"() as node()",description:' Reads the "_session" cookie in the request and verifies if the signature\n matches the ad-hoc computed signature of the content of the session. If the\n verification is successful, the function returns the session data. Otherwise,\n an error is raised.\n',summary:'<p> Reads the "_session" cookie in the request and verifies if the signature\n matches the ad-hoc computed signature of the content of the session.</p>',annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"node()",description:"The session data is returned if verification succesful."},errors:[]},{isDocumented:!0,arity:1,name:"set",qname:"cookie:set",signature:"($cookie as element(cookie:cookie)) as empty-sequence()",description:' Adds a <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">Set-Cookie</tt> header to the response. This function is equivalent to\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">cookie:set($cookie, fn:true())</tt>.\n',summary:"<p> Adds a  Set-Cookie  header to the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"cookie",type:"element(cookie:cookie)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The XML representation of the cookie to be sent to the client.</div>'}],returns:{type:"empty-sequence()",description:"The empty-sequence is returned."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cookie:S002 if the cookie is bigger than 4096 bytes.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"set",qname:"cookie:set",signature:"($cookie as element(cookie:cookie), $encode as xs:boolean) as empty-sequence()",description:' Adds a <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">Set-Cookie</tt> header to the response.\n The cookie parameter needs to adhere to the cookie schema. For example,\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">\n &lt;cookie:cookie\n   name="xs:string"\n   expires="xs:datetime"\n   domain="xs:string"\n   path="xs:string"\n   secure="xs:boolean"&gt;value&lt;/cookie:cookie&gt;\n </tt>.\n If the cookie parameter is not valid according to the schema, err:XQDY0027 is raised.\n If $encode evaluates to fn:true(), then the child nodes of the cookie element will be\n serialized using XML serialization (omitting the XML declaration). In order not to\n break the cookie syntax, any occurence of whitespace or column in the value will be\n encoded on the client using the URL encoding format. For this reason also the \'%\'\n character will be encoded using the same format.\n If $encode evaluates to fn:false(), the children nodes of the cookie element will be\n serialized as text and no encoding will be performed whatsoever. It is the\n responsibility of the caller to make sure the text serialization will not produce an\n invalid cookie.\n',summary:"<p> Adds a  Set-Cookie  header to the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"cookie",type:"element(cookie:cookie)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The cookie to send to the client</div>'},{name:"encode",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> if encoding should be performed on the value or not</div>'}],returns:{type:"empty-sequence()",description:"The empty-sequence is returned."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cookie:S002 if the cookie is bigger than 4096 bytes.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"validate-session",qname:"cookie:validate-session",signature:"() as xs:boolean",description:' Reads the "_session" cookie in the request and verifies if\n the signature matches the ad-hoc computed signature of the\n content of the session. The signature is generated with a\n server private key. If no cookie named "_session" exists,\n this function returns false.\n',summary:'<p> Reads the "_session" cookie in the request and verifies if\n the signature matches the ad-hoc computed signature of the\n content of the session.</p>',annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:'Returns <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">true</tt> if the session is valid, and and false otherwise.'},errors:[]}],variables:[]},"http://www.28msec.com/modules/couchbase":{ns:"http://www.28msec.com/modules/couchbase",description:' This module provides functionality to interact with the\n Couchbase NoSQL database.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The module is built using the libcouchbase 2.0 C client library and\n exposes most of its functionality in JSONiq.\n Beyond just allowing for basic key-value store operations (e.g.\n put-/get-text or put-/get-binary, this module also allows to work\n with Couchbase views in order to allow for complex JSON query\n operations.\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Cristi Dumitru</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/couchbase",prefix:"cb"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://www.zorba-xquery.com/modules/couchbase",prefix:"zcb"}],functions:[{isDocumented:!0,arity:1,name:"connect",qname:"cb:connect",signature:"($options as object()) as anyURI",description:' Connect to the Couchbase server.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The input to the function is an object that contains the connection\n information. Specifically, it allows for the following options:\n <ul>\n   <li><tt>host</tt>: the endpoint of the Couchbase server (mandatory)</li>\n   <li><tt>user</tt>: the user used for connecting (optional)</li>\n   <li><tt>password</tt>: the password used for connecting (optional)</li>\n   <li><tt>bucket</tt>: name of an existing bucket (mandatory)</li>\n </ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $conn := cb:connect({\n   "host" : "192.168.1.56:8091",\n   "username" : (),\n   "password" : (),\n   "bucket" : "default"\n });\n </pre></li></ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns an opaque URI that represents the connection.\n This URI has to be passed to other functions of this module that require\n the <tt>$conn</tt> parameter as a first argument.</p>\n',summary:"<p> Connect to the Couchbase server.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a object that contains the host, bucket, and authentication information.</div>'}],returns:{type:"anyURI",description:"an identifier for the established connection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0001 if the connection to the given host/bucket could not be established.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0001 if mandatory connection information is missing.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0007 if a given option is not supported.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"connect",qname:"cb:connect",signature:"($host as string, $username as string?, $password as string?, $bucket as string) as anyURI",description:' Connect to the Couchbase server.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns an opaque URI that represents the connection.\n This URI has to be passed to other functions of this module that require\n the <tt>$conn</tt> parameter as a first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $conn := cb:connect("192.168.1.56:8091", (), (), "default");\n </pre></li></ul></p>\n',summary:"<p> Connect to the Couchbase server.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> address of the couchbase server (mandatory) <code>"192.168.1.56:8091"</code></div>'},{name:"username",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> username used for the connection</div>'},{name:"password",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> password used for the connection</div>'},{name:"bucket",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> name of the bucket to use (mandatory) <code>"default"</code></div>'}],returns:{type:"anyURI",description:"an identifier that represents the connection to the server."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0001 if the connection to the given host/bucket could not be established.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"create-view",qname:"cb:create-view",signature:"($conn as anyURI, $doc-name as string, $view-names as string*) as string*",description:' Create a document and views.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the document already exists, it is replaced.\n A document can hold several views that must be specified in the same call.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $views := cb:create-view($conn, "zip", ("bystate", "bycity"));\n </pre></li></ul></p>\n',summary:"<p> Create a document and views.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"doc-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the document to create</div>'},{name:"view-names",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The names of the views to create in the document</div>'}],returns:{type:"string*",description:"The paths for the views that have been created."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"create-view",qname:"cb:create-view",signature:"($conn as anyURI, $doc-name as string, $view-names as string*, $options as object()*) as string*",description:' Create a document and views.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the document already exists, it is replaced.\n A document can hold several views that must be specified in the same call.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition, the function allows to specify several options:\n <ul>\n   <li><tt>key</tt>: <tt>string</tt> name of the value that will be used\n        as key in the view</li>\n   <li><tt>values</tt>: <tt>string/array</tt> name of the value(s) that\n        will be used as values in the view</li>\n   <li><tt>function</tt>: <tt>javascript function</tt> the map function\n        that will create the connection between key and value.<br/>\n        If <tt>function</tt> is specified, the <tt>key</tt> and\n        <tt>values</tt> options are ignored.</li>\n </ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $views := cb:create-view($conn, "zip", "bystate", { "key": "doc.state", "values" : ["doc.pop", "doc.city"] });\n </pre></li>\n <li><pre>\n $views := cb:create-view($conn, "zip", "bycity", { "function": "function(doc, meta) {  emit(doc.state, null); }"});\n </pre></li></ul></p>\n',summary:"<p> Create a document and views.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"doc-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the document to create</div>'},{name:"view-names",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The names of the views to create in the document</div>'},{name:"options",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object with additional options</div>'}],returns:{type:"string*",description:"The paths for the views that have been created."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0005 if the number of options doesn\'t match the number of view-names.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0010 if any of the given options has an invalid type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete-view",qname:"cb:delete-view",signature:"($conn as anyURI, $doc as string*) as string*",description:' Delete a document and its views.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the document doesn\'t exists, the function does nothing.\n All the views hold in the document are deleted.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n cb:delete-view($conn, "zip");\n </pre></li></ul></p>\n',summary:"<p> Delete a document and its views.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"doc",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0">-name The name of the document to delete</div>'}],returns:{type:"string*",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"flush",qname:"cb:flush",signature:"($conn as anyURI) as empty-sequence()",description:' Remove all values and their keys.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n cb:flush($conn);\n </pre></li></ul></p>\n',summary:"<p> Remove all values and their keys.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"get-binary",qname:"cb:get-binary",signature:"($conn as anyURI, $key as string*) as base64Binary*",description:' Retrieve the values matching the given string keys, as base64Binary.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $result := cb:get-binary($conn, "image");\n </pre></li></ul></p>\n',summary:"<p> Retrieve the values matching the given string keys, as base64Binary.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The requested keys</div>'}],returns:{type:"base64Binary*",description:"A sequence of base64Binary values corresponding to the keys"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"get-binary",qname:"cb:get-binary",signature:"($conn as anyURI, $key as string*, $options as object()) as base64Binary*",description:' Retrieve the values matching the given string keys, as base64Binary.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition, the function allows to specify several options:\n <ul>\n   <li><tt>expiration-time</tt>: <tt>integer</tt> value for refreshing the\n        expiration time in seconds\n       (default 0, which means values are kept indefinitely)</li>\n </ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $result := cb:get-binary($conn, "image",{ "expiration-time" : 60 * 60 });\n </pre></li></ul></p>\n',summary:"<p> Retrieve the values matching the given string keys, as base64Binary.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The requested keys</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object with additional options</div>'}],returns:{type:"base64Binary*",description:"A sequence of base64Binary values corresponding to the keys"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0009 if the given expiration time is not an integer.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"get-text",qname:"cb:get-text",signature:"($conn as anyURI, $key as string*) as string*",description:' Retrieve the values matching the given string keys, as string.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $result := cb:get-text($conn, "35040");\n </pre></li></ul></p>\n',summary:"<p> Retrieve the values matching the given string keys, as string.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The requested keys</div>'}],returns:{type:"string*",description:"A sequence of string values corresponding to the keys"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"get-text",qname:"cb:get-text",signature:"($conn as anyURI, $key as string*, $options as object()) as string*",description:' Retrieve the values matching the given string keys, as string.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition, the function allows to specify several options:\n <ul>\n   <li><tt>expiration-time</tt>: <tt>integer</tt> value for refreshing the\n        expiration time in seconds\n       (default 0, which means values are kept indefinitely)</li>\n   <li><tt>encoding</tt>: <tt>string</tt> name of the encoding of the\n        returned string (default UTF-8)</li>\n </ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $result := cb:get-text($conn, "35040", { "encoding" : "ASCII" } );\n </pre></li></ul></p>\n',summary:"<p> Retrieve the values matching the given string keys, as string.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The requested key</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object with additional options</div>'}],returns:{type:"string*",description:"A sequence of string values corresponding to the keys"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0006 if the given encoding is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0009 if the given expiration time is not an integer.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"put-binary",qname:"cb:put-binary",signature:"($conn as anyURI, $key as string*, $value as base64Binary*) as empty-sequence()",description:' Store base64binary values along with their string keys.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n cb:put-binary($conn, "image",\n   http:get-binary("http://localhost:8091/images/couchbase_logo.png")[2]);\n </pre></li></ul></p>\n',summary:"<p> Store base64binary values along with their string keys.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys to store</div>'},{name:"value",type:"base64Binary",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The base64 binary values to be stored</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0005 if the number of keys doesn\'t match the number of values.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"put-binary",qname:"cb:put-binary",signature:"($conn as anyURI, $key as string*, $value as base64Binary*, $options as object()) as empty-sequence()",description:' Store base64Binary values along with their string keys.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition, the function allows to specify several options:\n <ul>\n   <li><tt>expiration-time</tt>: <tt>integer</tt> value for refreshing the\n        expiration time in seconds\n       (default 0, which means values are kept indefinitely)</li>\n   <li><tt>operation</tt>: <tt>add/replace/set/append/prepend</tt> type of\n       operation</li>\n   <li><tt>wait</tt>: <tt>persist/false</tt> if the system should wait for\n        persistence of the keys</li>\n </ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n cb:put-binary($conn, "image",\n   http:get-binary("http://localhost:8091/images/couchbase_logo.png")[2],\n   { "expiration-time" : 60 * 60 * 24 });\n </pre></li></ul></p>\n',summary:"<p> Store base64Binary values along with their string keys.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys to store</div>'},{name:"value",type:"base64Binary",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The base64Binary values to be stored</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object with additional options</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0005 if the number of keys doesn\'t match the number of values.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0009 if the given expiration time is not an integer.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0011 if the stored Variable was not stored</xqdoc:error>']},{isDocumented:!0,arity:3,name:"put-text",qname:"cb:put-text",signature:"($conn as anyURI, $key as string*, $value as string*) as empty-sequence()",description:' Store string values along with their string keys.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The values are stored with the UTF-8 encoding and a default\n expiration time 0.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n cb:put-text($conn, "35040", fn:serialize({\n                      "city" : "CALERA",\n                      "loc" : [ -86.755987, 33.1098 ],\n                      "pop" : 4675,\n                      "state" : "AL",\n                      "_id" : "35040"\n                    }));\n </pre></li></ul></p>\n',summary:"<p> Store string values along with their string keys.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys to store</div>'},{name:"value",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string values to be stored.</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0005 if the number of keys doesn\'t match the number of values.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"put-text",qname:"cb:put-text",signature:"($conn as anyURI, $key as string*, $value as string*, $options as object()) as empty-sequence()",description:' Store string values along with their string keys.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition, the function allows to specify several options:\n <ul>\n   <li><tt>expiration-time</tt>: <tt>integer</tt> value for refreshing the\n        expiration time in seconds\n       (default 0, which means values are kept indefinitely)</li>\n   <li><tt>encoding</tt>: <tt>string</tt> name of the encoding of the\n        returned string (default UTF-8)</li>\n   <li><tt>operation</tt>: <tt>add/replace/set/append/prepend</tt> type\n        of operation</li>\n   <li><tt>wait</tt>: <tt>persist/false</tt> if the system should wait for\n        persistence of the keys</li>\n </ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n cb:put-text($conn, "35040", fn:serialize({\n                      "city" : "CALERA",\n                      "loc" : [ -86.755987, 33.1098 ],\n                      "pop" : 4675,\n                      "state" : "AL",\n                      "_id" : "35040"\n                    }), { "expiration-time" : 60 * 60 * 24 });\n </pre></li></ul></p>\n',summary:"<p> Store string values along with their string keys.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys to store</div>'},{name:"value",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string values to be stored</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object with additional options</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0005 if the number of keys doesn\'t match the number of values.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0006 if the given encoding is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0009 if the given expiration time is not an integer.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0011 if the stored Variable was not stored</xqdoc:error>']},{isDocumented:!0,arity:2,name:"remove",qname:"cb:remove",signature:"($conn as anyURI, $key as string*) as empty-sequence()",description:' Remove the values matching the given string keys.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n cb:remove($conn, "35040");\n </pre></li></ul></p>\n',summary:"<p> Remove the values matching the given string keys.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The requested keys to have their values removed</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"touch",qname:"cb:touch",signature:"($conn as anyURI, $key as string*, $exp-time as integer) as empty-sequence()",description:' Refresh the expiration time of the given string keys.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n cb:touch($conn, "35040", 60 * 60 * 24);\n </pre></li></ul></p>\n',summary:"<p> Refresh the expiration time of the given string keys.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"key",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys to touch</div>'},{name:"exp-time",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> New expiration time in seconds</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"view",qname:"cb:view",signature:"($conn as anyURI, $path as string*) as object()*",description:' Retrieve the content of existing views. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $results := cb:view($conn, "_design/zip/_view/bystate");\n </pre></li></ul></p>\n',summary:"<p> Retrieve the content of existing views.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"path",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The view path</div>'}],returns:{type:"object()*",description:"information about the view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"view",qname:"cb:view",signature:"($conn as anyURI, $path as string*, $options as object()) as object()*",description:' Retrieve the content of existing views.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <ul><li><pre>\n $results := cb:view($conn, "_design/zip/_view/bystate", { "limit": 100 });\n </pre></li></ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition, the function allows to specify several options:\n <ul>\n   <li><tt>encoding</tt>: <tt>string</tt> name of the encoding of the\n        returned string (default UTF-8)</li>\n   <li><tt>stale</tt>: if the system should wait for persistence of the keys\n    <ul>\n      <li><tt>ok</tt> the view is not updated</li>\n      <li><tt>false</tt> the view is updated before the function view is\n      executed, this options needs the key to be on disk before the call of\n      the function.</li>\n      <li><tt>update_after</tt> the view is updated after the call\n      of the function.</li>\n    </ul></li>\n   <li><tt>limit</tt>: <tt>integer</tt> how many rows qill be shown\n         (default all)</li>\n </ul></p>\n',summary:"<p> Retrieve the content of existing views.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection</div>'},{name:"path",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The view path <code>"_design/test/_view/vies"</code></div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object with additional options</div>'}],returns:{type:"object()*",description:"information about the view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">CB0007 if any of the options is not supported.</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/random":{ns:"http://zorba.io/modules/random",description:" This module provides several functions for generating (pseudo-)random\n numbers and strings.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner, Sorin Nasoi</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/random",prefix:"r"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:2,name:"random-between",qname:"r:random-between",signature:"($lower as integer, $upper as integer) as integer",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function generates one random number within a given range.\n The function is nondeterministic.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function is based on <tt>r:random-between#3</tt>.\n Specifically, it returns the value of invoking\n <tt>r:random-betwen($lower, $upper, 1)</tt>.</p>\n',summary:"<p>  This function generates one random number within a given range.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"lower",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the lower bound for the random number</div>'},{name:"upper",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the upper bound for the random number</div>'}],returns:{type:"integer",description:"a random integer within the given range"},errors:[]},{isDocumented:!0,arity:3,name:"random-between",qname:"r:random-between",signature:"($lower as integer, $upper as integer, $num as integer) as integer*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function generates an arbitrary number of random numbers\n within a given range. The function is nondeterministic because\n the sequence is <b>not</b> repeatable.</p>\n',summary:"<p>  This function generates an arbitrary number of random numbers\n within a given range.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"lower",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the lower bound for every value within the sequence</div>'},{name:"upper",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the upper bound for every value within the sequence</div>'},{name:"num",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the length of the sequence returned</div>'}],returns:{type:"integer*",description:'<tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt> pseudo-random integers within (and including) the range specified by <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$lower</tt> and <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$upper</tt>. It returns <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt>-times <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$lower</tt> if <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$lower</tt> is equal to <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$upper</tt> and the empty sequence if <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt> is negative.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">r:INVALID_ARGUMENT if <tt>$lower</tt> is greater than <tt>$upper</tt></xqdoc:error>']},{isDocumented:!0,arity:0,name:"random",qname:"r:random",signature:"() as integer",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function generates one random number.\n The function is nondeterministic.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function is based on <tt>r:random#1</tt>. Specifically, it\n returns the value of invoking <tt>r:random(1)</tt>.</p>\n',summary:"<p>  This function generates one random number.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"integer",description:"a random integer"},errors:[]},{isDocumented:!0,arity:1,name:"random",qname:"r:random",signature:"($num as integer) as integer* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function generates an arbitrary number of random numbers.\n The function is nondeterministic because the sequence is\n <b>not</b> repeatable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">However, the function is based on posix function <tt>srand()</tt> and\n <tt>rand()</tt>. Specifically, it invokes <tt>srand()</tt>\n with some random number based on the current time\n and then returns the values returned by invoking\n <tt>rand()</tt> <tt>$num</tt>-times.</p>\n',summary:"<p>  This function generates an arbitrary number of random numbers.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"num",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the length of the sequence returned</div>'}],returns:{type:"integer*",description:'<tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt> random integers, or the empty sequence if <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt> is negative.'},errors:[]},{isDocumented:!0,arity:4,name:"seeded-random-between",qname:"r:seeded-random-between",signature:"($seed as integer, $lower as integer, $upper as integer, $num as integer) as integer*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function generates an arbitrary number of pseudo-random numbers\n within a given range. The sequence is repeatable by calling the\n function with the same seed and boundaries.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function is based on the function <tt>r:seeded-random#2</tt>.\n Specifically, its result is repeatable if called with the\n same arguments.</p>\n',summary:"<p>  This function generates an arbitrary number of pseudo-random numbers\n within a given range.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seed",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the initial seed value for the sequence</div>'},{name:"lower",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the lower bound for every value within the sequence</div>'},{name:"upper",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the upper bound for every value within the sequence</div>'},{name:"num",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the length of the sequence returned</div>'}],returns:{type:"integer*",description:'<tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt> pseudo-random integers within (and including) the range specified by <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$lower</tt> and <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$upper</tt>. It returns <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt>-times <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$lower</tt> if <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$lower</tt> is equal to <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$upper</tt> and the empty sequence if <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt> is negative.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZQXD0004 if the given seed is negative or great than the max value of <tt>unsigned int</tt> on the given platform.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">r:INVALID_ARGUMENT if <tt>$lower</tt> is greater than <tt>$upper</tt></xqdoc:error>']},{isDocumented:!0,arity:2,name:"seeded-random",qname:"r:seeded-random",signature:"($seed as integer, $num as integer) as integer* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function generates an arbitrary number of pseudo-random numbers.\n The sequence is repeatable by calling the function with the same\n seed.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function is based on posix function <tt>srand()</tt> and\n <tt>rand()</tt>. Specifically, it invokes <tt>srand($seed)</tt>\n and then returns the values returned by invoking <tt>rand()</tt>\n <tt>$num</tt>-times.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sequences returned by this function are not thread-safe (i.e.\n if multiple XQuery programs invoking this function are executed\n concurrently in several threads). This is because the function is\n based on <tt>srand()</tt> and <tt>rand()</tt>.</p>\n',summary:"<p>  This function generates an arbitrary number of pseudo-random numbers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seed",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the initial seed value for the sequence</div>'},{name:"num",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the length of the sequence returned</div>'}],returns:{type:"integer*",description:'<tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt> pseudo-random integers, or the empty sequence if <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$num</tt> is negative.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZQXD0004 if the given seed is negative or great than the max value of <tt>unsigned int</tt> on the given platform.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"uuid",qname:"r:uuid",signature:"() as string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function returns a uuid.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"> Note, that the function is not stable,\n that is, it returns a different UUID everytime the function is invoked.</p>\n',summary:"<p>  This function returns a uuid.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"string",description:"the generated UUID as string"},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/http-client":{ns:"http://www.zorba-xquery.com/modules/http-client",description:' <h1 xmlns:xqdoc="http://www.xqdoc.org/1.0">Introduction</h1>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This module provides provides simple functions for performing HTTP requests\n (GET, POST, DELETE etc.), as well as a more flexible general\n purpose function (<a href="?anchor=send-request-3">send-request()</a>).\n </p>\n <h1 xmlns:xqdoc="http://www.xqdoc.org/1.0">Examples of how to use this module</h1>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Simple GET Request</h4>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n import module namespace http="http://www.zorba-xquery.com/modules/http-client";\n declare namespace svg="http://www.w3.org/2000/svg";\n http:get("http://www.w3.org/Graphics/SVG/svglogo.svg")[2]/svg:svg/svg:title\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This example downloads an XML resource from the web (in this case,\n an SVG file, which is an XML-based image format) and returns it as\n a document node. Since the XML is in a namespace, we declare that\n namespace; we can then perform a path expression directly on the\n return value of http:get().\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Simple GET Request (retrieving XHTML)</h4>\n   <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n   import module namespace http="http://www.zorba-xquery.com/modules/http-client";\n   declare namespace xhtml="http://www.w3.org/1999/xhtml";\n   http:get-node( "http://www.w3.org" )[2]//xhtml:body\n   </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This example shows how to retrieve an XHTML resource. XHTML is\n XML, so the http:get-node() function will return it as a document node\n and you can operate on it with the full power of XQuery. As above, since this\n XML is in a particular namespace, the above query defines that namespace\n with the prefix "xhtml" so it can easily perform path expressions, etc.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n Note: many webservers, include www.w3.org, return XHTML with the\n HTTP Content-Type "text/html". Zorba cannot assume that "text/html"\n is actually XHTML, and so http:get() would have returned raw text\n rather than a document node. That is why the example above uses\n http:get-node(), which overrides the server\'s Content-Type and tells\n Zorba to attempt to parse the result as XML.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Simple GET Request (retrieving HTML as text)</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n Note that XQuery does <b>not</b> understand plain HTML, and so if the URL\n you retrieve contains plain HTML data (not XHTML), it will be treated as\n plain text as shown in the next example. If you want to operate on the HTML\n with XQuery, you should use the HTML language module which can transform\n HTML to XHTML. The HTML module is supported by the Zorba team, but it is\n not a "core module", meaning that it is not shipped with every Zorba\n installation and may not be available. See\n <a href="http://www.zorba-xquery.com/site2/html/downloads.html">the Zorba downloads\n page</a> for information about obtaining this module if you do not\n have it.</p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n import module namespace http="http://www.zorba-xquery.com/modules/http-client";\n http:get("http://www.example.com")[2]\n </pre>\n returns\n   <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xml">\n   &lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;\n   &lt;html&gt;\n     &lt;head&gt;\n       &lt;meta http-equiv="Content-Type"\n       content="text/html; charset=utf-8" /&gt;\n       &lt;title&gt;Example Web Page&lt;/title&gt;\n     &lt;/head&gt;\n     &lt;body&gt;\n       &lt;p&gt;You have reached this web page by typing "example.com",\n       "example.net", or "example.org" into your web browser.&lt;/p&gt;\n       &lt;p&gt;These domain names are reserved for use in documentation and are\n       Not available for registration. See\n       &lt;a href="http://www.rfc-editor.org/rfc/rfc2606.txt"&gt;RFC 2606&lt;/a&gt;,\n       Section 3.&lt;/p&gt;\n     &lt;/body&gt;\n   &lt;/html&gt;\n   </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note that the response data above is a simple\n xs:string value containing the HTML data, not actual XML data. If you\n executed the above query using the Zorba command-line client, you would\n have actually seen data like the following:</p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xml">\n   &amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&amp;gt;\n   &amp;lt;html&amp;gt;\n      ...\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">because Zorba would attempt to serialize it as XML data, and would\n escape all the raw angle brackets in the original xs:string.</p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Simple POST Request</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n Here is a simple example which sends text content by making an HTTP POST\n request.\n </p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n import module namespace http="http://www.zorba-xquery.com/modules/http-client";\n http:post( "...", "Hello World" )\n </pre>\n <h1 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="standard_return">Return Values</h1>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Most functions in this module (all except\n <a href="?anchor=options-1">options()</a>) return one or more items.\n (<a href="?anchor=head-1">head()</a> returns exactly one.) For all of these,\n the first item returned will be a &lt;http-schema:response&gt;\n element, as seen in the examples above. This element has "status" and\n "message" attributes, representing the result of the HTTP call. It\n also has any number of &lt;http-schema:header&gt; child elements that\n encode the HTTP headers returned by the HTTP server. Finally, it\n will generally contain a &lt;http-schema:body&gt; child element with\n a "media-type" attribute that identifies the content-type of the\n result data.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The full schema of this &lt;http-schema:response&gt; element is\n part of the <a href="http://expath.org/modules/http-client/">EXPath\n HTTP Client module</a>. You can see the schema\n <a href="schemas/expath.org_ns_http-client.html">here</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Any items in function return values after the initial\n &lt;http-schema:response&gt; element are the body/bodies of the HTTP\n response from the server. (MIME Multi-part responses will have\n more than one body.) The type of these items depends on the\n Content-Type for each body. Each item will be:</p>\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  <li>\n    an element node, if the returned content type is one of:\n    <ul>\n      <li>text/xml</li>\n      <li>application/xml</li>\n      <li>text/xml-external-parsed-entity</li>\n      <li>application/xml-external-parsed-entity</li>\n      <li>or if the Content-Type ends with "+xml".</li>\n    </ul>\n  </li>\n  <li>\n    an xs:string, if the returned content type starts with "text/"\n    and does not match the above XML content types strings, or if\n    it is one of:\n    <ul>\n      <li>"application/json"</li>\n      <li>"application/x-javascript"</li>\n    </ul>\n  </li>\n  <li>xs:base64Binary for all other content types.</li>\n </ul>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This return value - a sequence of items comprising one\n &lt;http-schema:response&gt; element followed by zero or more\n response items - is referred to as the "standard http-client\n return type" in the function declarations below.</p>\n <h1 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="url_string">$href Arguments to Functions</h1>\n All functions in this module accept a URL argument named $href. In\n all cases, the value passed to $href must be a valid xs:anyURI.\n However, all functions declare $href to be of type xs:string. This\n is for convenience, since you can pass a string literal value (that\n is, a URL in double-quotes spelled out explicitly in your query)\n to an xs:string parameter.\n <h1 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="get_warning">Important Notice Regarding get() Functions</h1>\n All of the get() functions in this module -\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="?anchor=get-1">get()</a>, <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="?anchor=get-node-1">get-node()</a>,\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="?anchor=get-text-1">get-text()</a>, and\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="?anchor=get-binary()">get-binary()</a> - are declared to be\n <i xmlns:xqdoc="http://www.xqdoc.org/1.0">nondeterministic</i>, which means that Zorba will not cache\n their results. However, they are <b xmlns:xqdoc="http://www.xqdoc.org/1.0">not</b> declared to be\n <i xmlns:xqdoc="http://www.xqdoc.org/1.0">sequential</i>, which means that Zorba may re-order them\n as part of its query optimization. According to the HTTP RFC,\n GET requests should only return data, and should not have any\n side-effects. However, in practice it is not uncommon for GET\n requests to have side-effects. If your application depends on\n the ordering of side-effects from making GET requests, you should\n either use the more complex <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="?anchor=send-request-3">send-request()</a>\n function (which <b xmlns:xqdoc="http://www.xqdoc.org/1.0">is</b> declared <i xmlns:xqdoc="http://www.xqdoc.org/1.0">sequential</i>), or alterately\n wrap each call to get() in your own sequential function, to ensure\n that Zorba does not place the GET requests out of order.\n <h1 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="expath_relation">Relation to the EXPath http-client module</h1>\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://expath.org/">EXPath</a> defines its own http-client\n module, which is available separately for Zorba as a non-core module.\n There are two primary differences between EXPath\'s http-client and\n Zorba\'s core http-client (this module):\n <ol xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>EXPath defines only the send-request() function, although it\n does include convenient 1- and 2-argument forms in addition to the\n full 3-argument form. EXPath does not include the simpler get(),\n post(), put(), delete(), head(), and options() functions defined by\n this module.</li>\n   <li>EXPath specifies that all HTML content returned from the\n HTTP server will be <i>tidied up</i> into valid XML, and then parsed\n into an element. As this required an additional third-party library\n dependency, Zorba\'s http-client module does not perform this tidying.\n Instead, HTML content is returned as a string (with special XML\n characters replaced with XML entity references, as shown in the\n above examples).</li>\n </ol>\n See <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.expath.org/spec/http-client">the full spec\n of the EXPath http-client module</a> for more information.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.w3.org/TR/xquery-11/#FunctionDeclns">XQuery 1.1: Function Declaration</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Markus Pilman, Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://expath.org/ns/error",prefix:"error"},{uri:"http://www.zorba-xquery.com/modules/http-client",prefix:"http"},{uri:"http://expath.org/ns/http-client",prefix:"http-schema"},{uri:"http://zorba.io/modules/http-client-wrapper",prefix:"http-wrapper"},{uri:"http://jsoniq.org/functions",prefix:"jn"},{uri:"http://zorba.io/modules/http-client",prefix:"json-http"},{uri:"http://jsoniq.org/function-library",prefix:"libjn"},{uri:"http://www.w3.org/2010/xslt-xquery-serialization",prefix:"ser"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"delete",qname:"http:delete",signature:"($href as xs:string) as item()+",description:" This function makes an HTTP DELETE request to a given URL.\n",summary:"<p> This function makes an HTTP DELETE request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HCV02 Trying to follow a redirect of a DELETE request.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"get-binary",qname:"http:get-binary",signature:"($href as xs:string) as item()+",description:" This function makes a GET request on a given URL. All returned bodies\n are forced to be interpreted as binary data, and will be returned\n as xs:base64Binary items.\n",summary:"<p> This function makes a GET request on a given URL.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"get-node",qname:"http:get-node",signature:"($href as xs:string) as item()+",description:" This function makes a GET request to a given URL. All returned bodies\n are forced to be interpreted as XML and parsed into elements.\n",summary:"<p> This function makes a GET request to a given URL.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"get-text",qname:"http:get-text",signature:"($href as xs:string) as item()+",description:" This function makes a GET request to a given URL. All returned bodies\n are forced to be interpreted as plain strings, and will be returned\n as xs:string items.\n",summary:"<p> This function makes a GET request to a given URL.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"get",qname:"http:get",signature:"($href as xs:string) as item()+",description:" This function makes a GET request to a given URL.\n",summary:"<p> This function makes a GET request to a given URL.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"head",qname:"http:head",signature:"($href as xs:string) as item()",description:" This function makes an HTTP HEAD request on a given URL.\n",summary:"<p> This function makes an HTTP HEAD request on a given URL.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"item()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a> (since HEAD never returns any body data, only the &lt;http-schema:response&gt; element will be returned).'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"options",qname:"http:options",signature:"($href as xs:string) as xs:string*",description:" This function makes an HTTP OPTIONS request, which asks the server\n which operations it supports.\n",summary:"<p> This function makes an HTTP OPTIONS request, which asks the server\n which operations it supports.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"xs:string*",description:"A sequence of xs:string values of the allowed operations."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"post",qname:"http:post",signature:"($href as xs:string, $body as item()) as item()+",description:' This function makes an HTTP POST request to a given URL. If the body\n passed to this function is an element, it will be serialized to XML\n to be sent to the server, and the Content-Type sent to the server will\n be "text/xml". Otherwise, the body will be converted to\n a plain string, and the Content-Type will be "text/plain".\n',summary:"<p> This function makes an HTTP POST request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server.</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HCV02 Trying to follow a redirect of a POST request.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"post",qname:"http:post",signature:"($href as xs:string, $body as item(), $content-type as xs:string) as item()+",description:' This function makes an HTTP POST request to a given URL. If the body\n passed to this function is an element, it will be serialized\n according to the $content-type parameter as follows:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  <li>If $content-type is "text/xml", "application/xml",\n "text/xml-external-parsed-entity", or\n "application/xml-external-parsed-entity", or if it ends with "+xml",\n $body will be serialized to XML.</li>\n  <li>If $content-type starts with "text/html", $body will be\n serialized to HTML.</li>\n  <li>Otherwise, $body will be serialized to text.</li>\n </ul>\n If $body is not an element, $body will be serialized to text\n regardless of $content-type.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In any case, Content-Type of the request sent to the server will\n be $content-type.</p>\n',summary:"<p> This function makes an HTTP POST request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server</div>'},{name:"content-type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The content type of the body as described above.</div>'}],returns:{type:"item()+",description:"The first element of the result is the metadata (like headers, status etc), the next elements are the response"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HCV02 Trying to follow a redirect of a POST request.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"put",qname:"http:put",signature:"($href as xs:string, $body as item()) as item()+",description:' This function makes an HTTP PUT request to a given URL. If the body\n passed to this function is an element, it will be serialized to XML\n to be sent to the server, and the Content-Type sent to the server will\n be "text/xml". Otherwise, the body will be converted to\n a plain string, and the Content-Type will be "text/plain".\n',summary:"<p> This function makes an HTTP PUT request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server.</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HCV02 Trying to follow a redirect of a PUT request.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"put",qname:"http:put",signature:"($href as xs:string, $body as item(), $content-type as xs:string) as item()+",description:' This function makes an HTTP PUT request to a given URL. If the body\n passed to this function is an element, it will be serialized\n according to the $content-type parameter as follows:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  <li>If $content-type is "text/xml", "application/xml",\n "text/xml-external-parsed-entity", or\n "application/xml-external-parsed-entity", or if it ends with "+xml",\n $body will be serialized to XML.</li>\n  <li>If $content-type starts with "text/html", $body will be\n serialized to HTML.</li>\n  <li>Otherwise, $body will be serialized to text.</li>\n </ul>\n If $body is not an element, $body will be serialized to text\n regardless of $content-type.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In any case, Content-Type of the request sent to the server will\n be $content-type.</p>\n',summary:"<p> This function makes an HTTP PUT request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server.</div>'},{name:"content-type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The content type of $body as described above.</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HCV02 Trying to follow a redirect of a PUT request.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"send-request",qname:"http:send-request",signature:"($request as element(http-schema:request)?, $href as xs:string?, $bodies as item()*) as item()+",description:' This function sends an HTTP request and returns the corresponding response.\n Its inputs, outputs, and behavior are identical to the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://expath.org/spec/http-client">EXPath http-client</a>\'s\n send-request() function (except that HTML responses are not tidied\n into XML - see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#expath_relation">the note above</a>). It\n is provided here for use in Zorba installations that do not have\n the EXPath module available. If you have the option of using the\n EXPath module instead of this function, please do so, as it will\n allow your application to be more interoperable between different\n XQuery engines.\n Full documentation of the $request parameter can be found in\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://expath.org/spec/http-client#d2e183">the EXPath\n specification</a>.\n',summary:"<p> This function sends an HTTP request and returns the corresponding response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"request",type:"element(http-schema:request)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Contains the various parameters of the request (see above).</div>'},{name:"href",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above). If this parameter is specified, it will override the "href" attribute of $request.</div>'},{name:"bodies",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the request body content, for HTTP methods that can contain a body in the request (i.e. POST and PUT). It is an error if this param is not the empty sequence for methods</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC003 With a multipart response, the override-media-type must be either a multipart media type or application/octet-stream.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC004 The src attribute on the body element is mutually exclusive with all other attribute (except the media-type).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC005 The input request element is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HCV02 Trying to follow a redirect of a POST, PUT, or DELETE request</xqdoc:error>']}],variables:[]},"http://xbrl.io/modules/bizql/profiles/sec/networks":{ns:"http://xbrl.io/modules/bizql/profiles/sec/networks",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for querying SEC networks in SEC filings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC Networks are actually XBRL Components. In the SEC profiles, all XBRL networks\n in an XBRL component must be consistent to each other. A way to look at it is that\n the SEC Network can be identified with the XBRL presentation network it contains.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For XBRL-generic operations on XBRL components, use the\n generic components module.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/components",prefix:"components"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/filings",prefix:"filings"},{uri:"http://xbrl.io/modules/bizql/hypercubes",prefix:"hypercubes"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://xbrl.io/modules/bizql/networks",prefix:"networks"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/core",prefix:"sec"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/networks",prefix:"sec-networks"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"abstracts",qname:"sec-networks:abstracts",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all SEC Abstracts contained in the supplied SEC Networks.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC Abstracts are XBRL abstract primary items that may or may not be associated\n with a hypercube -- except those that are SEC LineItems (i.e., source of an all relation).</p>\n',summary:"<p>  Returns all SEC Abstracts contained in the supplied SEC Networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"the SEC Abstracts."},errors:[]},{isDocumented:!0,arity:1,name:"axes",qname:"sec-networks:axes",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all SEC Axes contained in the supplied SEC Networks.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC Axes are XBRL dimensions.</p>\n',summary:"<p>  Returns all SEC Axes contained in the supplied SEC Networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"the SEC Axes."},errors:[]},{isDocumented:!0,arity:1,name:"categories",qname:"sec-networks:categories",signature:"($networks-or-ids) as string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the categories of the supplied SEC networks (Statement, Disclosure, Document or Schedule).</p>\n',summary:"<p>  Return the categories of the supplied SEC networks (Statement, Disclosure, Document or Schedule).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"string*",description:"the category of each network."},errors:[]},{isDocumented:!0,arity:1,name:"concepts",qname:"sec-networks:concepts",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all SEC Concepts contained in the supplied SEC Networks.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC Concepts are XBRL concrete primary items that may or may not be associated\n with a hypercube.</p>\n',summary:"<p>  Returns all SEC Concepts contained in the supplied SEC Networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"the SEC Concepts."},errors:[]},{isDocumented:!0,arity:1,name:"disclosures",qname:"sec-networks:disclosures",signature:"($networks-or-ids as item()*) as string+",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the disclosures of the suplied networks.</p>\n',summary:"<p>  Returns the disclosures of the suplied networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"string+",description:'the disclosure names, or "UncategorizedInformation" if none.'},errors:[]},{isDocumented:!0,arity:1,name:"fact-tables",qname:"sec-networks:fact-tables",signature:"($networks-or-ids as item()*) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts belonging to the SEC Network.</p>\n',summary:"<p>  Retrieves all facts belonging to the SEC Network.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"array()",description:"a array populated with fact values."},errors:[]},{isDocumented:!0,arity:2,name:"fact-tables",qname:"sec-networks:fact-tables",signature:"($networks-or-ids as item()*, $options as object()?) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts belonging to the SEC Network.</p>\n',summary:"<p>  Retrieves all facts belonging to the SEC Network.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="core#standard_options">standard SEC BizQL options</a>.</div>'}],returns:{type:"array()",description:"a array of arrays filled with fact values."},errors:[]},{isDocumented:!0,arity:1,name:"facts",qname:"sec-networks:facts",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts belonging to the SEC Network.</p>\n',summary:"<p>  Retrieves all facts belonging to the SEC Network.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"a sequence of facts."},errors:[]},{isDocumented:!0,arity:2,name:"facts",qname:"sec-networks:facts",signature:"($networks-or-ids as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts belonging to the SEC Network.</p>\n',summary:"<p>  Retrieves all facts belonging to the SEC Network.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="core#standard_options">standard SEC BizQL options</a>.</div>'}],returns:{type:"object()*",description:"a sequence of facts."},errors:[]},{isDocumented:!0,arity:1,name:"line-items-report-elements",qname:"sec-networks:line-items-report-elements",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all SEC LineItems report elements contained in the supplied SEC Networks.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This is not to be confused with the "line items" terminology, which includes all\n SEC Abstracts and SEC Concepts.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC LineItems report elements are XBRL abstract primary items that are top-level in their\n association with an XBRL hypercube (source of an all relation).</p>\n',summary:"<p>  Returns all SEC LineItems report elements contained in the supplied SEC Networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"the SEC LineItems report elements."},errors:[]},{isDocumented:!0,arity:1,name:"line-items",qname:"sec-networks:line-items",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all SEC Line Items (Concepts and Abstracts) contained in the\n supplied SEC Networks. Not to be confused with the LineItems report element.</p>\n',summary:"<p>  Returns all SEC Line Items (Concepts and Abstracts) contained in the\n supplied SEC Networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"the SEC Line Items."},errors:[]},{isDocumented:!0,arity:1,name:"members",qname:"sec-networks:members",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all SEC Members contained in the supplied SEC Networks.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC Members are XBRL members that are in the transitive closure of SEC Axes\n via the dimension-domain and domain-member relations.</p>\n',summary:"<p>  Returns all SEC Members contained in the supplied SEC Networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"the SEC Members."},errors:[]},{isDocumented:!0,arity:1,name:"model-structures",qname:"sec-networks:model-structures",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Computes the model structure of the supplied SEC Network, which is a hierarchy\n of SEC Report Elements (Tables, Axes, Members, LineItems, Abstracts, Concepts).</p>\n',summary:"<p>  Computes the model structure of the supplied SEC Network, which is a hierarchy\n of SEC Report Elements (Tables, Axes, Members, LineItems, Abstracts, Concepts).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"the model structures of these SEC Networks."},errors:[]},{isDocumented:!0,arity:1,name:"networks-for-disclosures",qname:"sec-networks:networks-for-disclosures",signature:"($disclosures as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all SEC Networks that bear the supplied disclosures.</p>\n',summary:"<p>  Retrieves all SEC Networks that bear the supplied disclosures.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"disclosures",type:"string",occurrence:"*",description:""}],returns:{type:"object()*",description:"all models that match one of the disclosures."},errors:[]},{isDocumented:!0,arity:2,name:"networks-for-filings-and-categories",qname:"sec-networks:networks-for-filings-and-categories",signature:"($archive-or-ids as item()*, $categories as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all models that belong to the archives given as first\n parameter and that match the supplied category.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A category can be any of "Statement", "Disclosure", "Document",\n "Schedule", or "Unknown".</p>\n',summary:"<p>  Retrieves all models that belong to the archives given as first\n parameter and that match the supplied category.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an arbitrary number of archive identifiers (AIDs) or archive objects.</div>'},{name:"categories",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a list of categories.</div>'}],returns:{type:"object()*",description:"all said models"},errors:[]},{isDocumented:!0,arity:2,name:"networks-for-filings-and-disclosures",qname:"sec-networks:networks-for-filings-and-disclosures",signature:"($archive-or-ids as item()*, $disclosures as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all models that belong to the archives given as first\n parameter and that match the supplied disclosures.</p>\n',summary:"<p>  Retrieves all models that belong to the archives given as first\n parameter and that match the supplied disclosures.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an arbitrary number of archive identifiers (AIDs) or archive objects.</div>'},{name:"disclosures",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a list of disclosures.</div>'}],returns:{type:"object()*",description:"all models in the archives and that match one of the disclosures."},errors:[]},{isDocumented:!0,arity:1,name:"networks-for-filings",qname:"sec-networks:networks-for-filings",signature:"($archives-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all SEC Networks in a given filing.</p>\n',summary:"<p>  Retrieves all SEC Networks in a given filing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:"item()",occurrence:"*",description:""}],returns:{type:"object()*",description:"all networks in the supplied filings."},errors:[]},{isDocumented:!0,arity:1,name:"num-abstracts",qname:"sec-networks:num-abstracts",signature:"($networks-or-ids as item()*) as integer*",description:" Return the number of (distinct) SEC Abstracts in each of the given components.\n",summary:"<p> Return the number of (distinct) SEC Abstracts in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of components or IDs</div>'}],returns:{type:"integer*",description:"the said number of abstracts"},errors:[]},{isDocumented:!0,arity:1,name:"num-axes",qname:"sec-networks:num-axes",signature:"($networks-or-ids as item()*) as integer*",description:" Return the number of (distinct) SEC Axes in each of the given components.\n",summary:"<p> Return the number of (distinct) SEC Axes in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of components or IDs</div>'}],returns:{type:"integer*",description:"the said number of axes"},errors:[]},{isDocumented:!0,arity:1,name:"num-concepts",qname:"sec-networks:num-concepts",signature:"($networks-or-ids as item()*) as integer*",description:" Return the number of (distinct) SEC Concepts in each of the given components.\n",summary:"<p> Return the number of (distinct) SEC Concepts in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of components or IDs</div>'}],returns:{type:"integer*",description:"the said number of concepts"},errors:[]},{isDocumented:!0,arity:1,name:"num-line-items",qname:"sec-networks:num-line-items",signature:"($networks-or-ids as item()*) as integer*",description:" Return the number of (distinct) SEC LineItems report elements in each of the given components.\n",summary:"<p> Return the number of (distinct) SEC LineItems report elements in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of components or IDs</div>'}],returns:{type:"integer*",description:"the said number of line items"},errors:[]},{isDocumented:!0,arity:1,name:"num-members",qname:"sec-networks:num-members",signature:"($networks-or-ids as item()*) as integer*",description:" Return the number of (distinct) SEC Members in each of the given components.\n",summary:"<p> Return the number of (distinct) SEC Members in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of components or IDs</div>'}],returns:{type:"integer*",description:"the said number of members"},errors:[]},{isDocumented:!0,arity:1,name:"num-report-elements",qname:"sec-networks:num-report-elements",signature:"($networks-or-ids as item()*) as integer*",description:" Return the number of (distinct) SEC report elements in each of the given components.\n",summary:"<p> Return the number of (distinct) SEC report elements in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of components or IDs</div>'}],returns:{type:"integer*",description:"the said number of report elements"},errors:[]},{isDocumented:!0,arity:1,name:"num-tables",qname:"sec-networks:num-tables",signature:"($networks-or-ids as item()*) as integer*",description:" Return the number of SEC Tables in each of the given components.\n",summary:"<p> Return the number of SEC Tables in each of the given components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of components or IDs</div>'}],returns:{type:"integer*",description:"the said number of tables"},errors:[]},{isDocumented:!0,arity:1,name:"populated-model-structures",qname:"sec-networks:populated-model-structures",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts belonging to the SEC Networks and populates the model structures.</p>\n',summary:"<p>  Retrieves all facts belonging to the SEC Networks and populates the model structures.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"the populated model structures (Facts array fields)."},errors:[]},{isDocumented:!0,arity:2,name:"populated-model-structures",qname:"sec-networks:populated-model-structures",signature:"($networks-or-ids as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts belonging to the SEC Networks and populates the model structures.</p>\n',summary:"<p>  Retrieves all facts belonging to the SEC Networks and populates the model structures.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="core#standard_options">standard SEC BizQL options</a>.</div>'}],returns:{type:"object()*",description:"the populated model structures (Facts array fields)."},errors:[]},{isDocumented:!0,arity:1,name:"sub-categories",qname:"sec-networks:sub-categories",signature:"($networks-or-ids) as string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the sub-categories of the supplied SEC networks (Detail, TextBlockLevel4, TextBLockLevel1to3).</p>\n',summary:"<p>  Return the sub-categories of the supplied SEC networks (Detail, TextBlockLevel4, TextBLockLevel1to3).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"string*",description:"the sub-category of each network."},errors:[]},{isDocumented:!0,arity:1,name:"summaries",qname:"sec-networks:summaries",signature:"($networks-or-ids) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return summary information for the supplied SEC networks.</p>\n',summary:"<p>  Return summary information for the supplied SEC networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"one object per network, containing a summary."},errors:[]},{isDocumented:!0,arity:1,name:"tables",qname:"sec-networks:tables",signature:"($networks-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all SEC Tables contained in the supplied SEC Networks.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC Tables are XBRL hypercubes.</p>\n',summary:"<p>  Returns all SEC Tables contained in the supplied SEC Networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'}],returns:{type:"object()*",description:"the SEC Tables."},errors:[]},{isDocumented:!0,arity:2,name:"tables",qname:"sec-networks:tables",signature:"($networks-or-ids as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns all SEC Tables contained in the supplied SEC Networks.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC Tables are XBRL hypercubes.</p>\n',summary:"<p>  Returns all SEC Tables contained in the supplied SEC Networks.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SEC Network objects, or their XBRL Component IDs.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="core#standard_options">standard SEC BizQL options</a>.</div>'}],returns:{type:"object()*",description:"the SEC Tables."},errors:[]}],variables:[{name:"sec-networks:BALANCE_SHEET",type:"xs:string",description:" Disclosure for the balance sheet.\n"},{name:"sec-networks:BALANCE_SHEET_PARENTHETICAL",type:"xs:string",description:" Disclosure for the parenthetical balance sheet.\n"},{name:"sec-networks:INCOME_STATEMENT",type:"xs:string",description:" Disclosure for the income statement.\n"},{name:"sec-networks:INCOME_STATEMENT_PARENTHETICAL",type:"xs:string",description:" Disclosure for the parenthetical income statement.\n"},{name:"sec-networks:STATEMENT_OF_COMPREHENSIVE_INCOME",type:"xs:string",description:" Disclosure for the statement of comprehensive income.\n"},{name:"sec-networks:CASH_FLOW_STATEMENT",type:"xs:string",description:" Disclosure for the cash flow statement.\n"},{name:"sec-networks:CASH_FLOW_STATEMENT_PARENTHETICAL",type:"xs:string",description:" Disclosure for the parenthetical cash flow statement.\n"},{name:"sec-networks:DEFAULT_COMPONENT",type:"xs:string",description:" Disclosure for the default component.\n"},{name:"sec-networks:DOCUMENT_AND_ENTITY_INFO",type:"xs:string",description:" Disclosure for the document and entity information\n"}]},"http://www.28msec.com/modules/http/request":{ns:"http://www.28msec.com/modules/http/request",description:' The Sausalito request module provides functions for accessing\n information contained in the current HTTP request. For example,\n the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">parameter-names</tt> function can be used to retrieve all\n the names of the parameters contained in a request.\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.28msec.com/modules/http/request",prefix:"request"},{uri:"http://www.zorba-xquery.com/modules/cryptography/hmac",prefix:"sec"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"binary-content",qname:"request:binary-content",signature:"() as xs:base64Binary external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the content of the request as base64Binary.</p>\n',summary:"<p>  Returns the content of the request as base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:base64Binary",description:"The content of the request as base64Binary."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-binary-content if the content contained in the body of the request cannot be treated as binary because it is a request with multipart or url-encoded content.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"binary-part",qname:"request:binary-part",signature:"($ref as xs:string) as xs:base64Binary external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the value of a part as base64Binary.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A part is identified by a reference that is the value of a\n <tt>src</tt> attribute returned by the <tt>request:parts</tt> function.</p>\n',summary:"<p>  Returns the value of a part as base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"ref",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the part</div>'}],returns:{type:"xs:base64Binary",description:"the value of the part as base64Binary"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-part if the part with the given name ($ref) does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:0,name:"content-length",qname:"request:content-length",signature:"() as xs:integer? external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the length of the content in bytes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The value returned corresponds to the value of the HTTP\n content-length header. The function returns an empty sequence\n if this header does not exist in the request or its value\n could not be converted to item of type xs:integer</p>.\n',summary:"<p>  Returns the length of the content in bytes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:integer?",description:"The content-length in bytes of the content sent with this request or the empty sequence if the content-length header does not exist in the request."},errors:[]},{isDocumented:!0,arity:0,name:"content-type",qname:"request:content-type",signature:"() as xs:string? external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the content-type of the data sent with this request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note that the content-type is only set for PUT and POST requests.</p>\n',summary:"<p>  Returns the content-type of the data sent with this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string?",description:"The content-type of the request if it is a PUT or POST request. Otherwise, it returns the empty sequence."},errors:[]},{isDocumented:!0,arity:0,name:"header-accept",qname:"request:header-accept",signature:"() as element(request:accept)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the values of the HTTP ACCEPT header.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The data is returned as a sequence of elements with name\n <tt>request:accept</tt> as shown in the following example.</p>\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  &lt;request:accept xmlns:request="http://www.28msec.com/modules/http/request"&gt;\n    &lt;request:type&gt;text&lt;/request:type&gt;\n    &lt;request:subtype&gt;html&lt;/request:subtype&gt;\n    &lt;request:quality&gt;1&lt;/request:quality&gt;\n  &lt;/request:accept&gt;\n  &lt;request:accept xmlns="http://www.28msec.com/modules/http/request"&gt;\n    &lt;request:type&gt;application&lt;/request:type&gt;\n    &lt;request:quality&gt;0.9&lt;/request:quality&gt;\n  &lt;/request:accept&gt;\n </code>\n',summary:"<p>  Returns the values of the HTTP ACCEPT header.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(request:accept)*",description:"The header values of the header ACCEPT or the empty sequence if the header is not contained in the request. The order of the returned elements reflects the order of the components in the header."},errors:[]},{isDocumented:!0,arity:0,name:"header-names",qname:"request:header-names",signature:"() as xs:string* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the names of all the HTTP headers in this request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Header fields are colon-separated name-value pairs, terminated\n by a carriage return (CR) and line feed (LF) character sequence. The\n names and values of each header are allowed to consist of US-ASCII\n characters only.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The names of the headers are returned using upper-case letters.\n If a header with the same name is contained multiple times in a request,\n its name is only returned once. The order of the names in the resulting\n sequence does not reflect the order of the headers in the request. If\n a header does not have a value, it is as if the header does not exist\n in the request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note that the header names user-agent and content-type are not\n returned by this function. They are returned by the corresponding\n functions of this module module\n (e.g. <a href="#user-agent-0">user-agent</a>).</p>\n',summary:"<p>  Returns the names of all the HTTP headers in this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"The names of the headers of this request or the empty sequence if no headers are contained in the request."},errors:[]},{isDocumented:!0,arity:1,name:"header-value",qname:"request:header-value",signature:"($name as xs:string) as xs:string? external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the value of the HTTP header with the given name.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Header fields are colon-separated name-value pairs, terminated\n by a carriage return (CR) and line feed (LF) character sequence. The\n names and values of each header are allowed to consist of US-ASCII\n characters only.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that header names are considered case-insensitive.\n Also note, that only one value is returned if multiple headers with the\n same names exist in the request. This value is a comma-separated list\n of the values of the headers in the order in which the headers appeared\n in the request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">All headers having a name that starts with SAUSALITO_ are reserved\n and will not be returned by this function.</p>\n',summary:"<p>  Returns the value of the HTTP header with the given name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The header name for which the value should be returned.</div>'}],returns:{type:"xs:string?",description:'The header value of the header with the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$name</tt> argument or the empty sequence if no header with that name is contained in the request.'},errors:[]},{isDocumented:!0,arity:0,name:"method-delete",qname:"request:method-delete",signature:"() as xs:boolean external",description:" Returns true if the HTTP method of this request is DELETE.\n",summary:"<p> Returns true if the HTTP method of this request is DELETE.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is DELETE, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-get",qname:"request:method-get",signature:"() as xs:boolean external",description:" Returns true if the HTTP method of this request is GET.\n",summary:"<p> Returns true if the HTTP method of this request is GET.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is GET, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-head",qname:"request:method-head",signature:"() as xs:boolean external",description:" Returns true if the HTTP method of this request is HEAD.\n",summary:"<p> Returns true if the HTTP method of this request is HEAD.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is HEAD, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-options",qname:"request:method-options",signature:"() as xs:boolean external",description:" Returns true if the HTTP method of this request is OPTION.\n",summary:"<p> Returns true if the HTTP method of this request is OPTION.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is OPTION, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-patch",qname:"request:method-patch",signature:"() as xs:boolean external",description:" Returns true if the HTTP method of this request is PATCH.\n",summary:"<p> Returns true if the HTTP method of this request is PATCH.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is PATCH, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-post",qname:"request:method-post",signature:"() as xs:boolean external",description:" Returns true if the HTTP method of this request is POST.\n",summary:"<p> Returns true if the HTTP method of this request is POST.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is POST, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-put",qname:"request:method-put",signature:"() as xs:boolean external",description:" Returns true if the HTTP method of this request is PUT.\n",summary:"<p> Returns true if the HTTP method of this request is PUT.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is PUT, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method",qname:"request:method",signature:"() as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the name of the HTTP method used to make this request.</p>\n',summary:"<p>  Returns the name of the HTTP method used to make this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The request method used to make this request (i.e. GET, POST, PUT, DELETE or HEAD)."},errors:[]},{isDocumented:!0,arity:0,name:"parameter-names",qname:"request:parameter-names",signature:"() as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the names of the parameters contained in the current request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parameters are name-value pairs contained in the query string of the URL\n used to make this request. As defined in RFC 1738, the query string of a\n URL starts with a "?" character and ends with the character (if any).\n Additionally, such name-value pairs may be part of the request\'s body if\n it is a PUT or POST request and the content-type of the request is\n "application/x-www-form-urlencoded". Name-value pairs are separated\n using either the "&amp;" or the ";" character.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In general, the names and the values  are precent-encoded. This function\n does the decoding of the parameters, i.e. it returns the values being\n not percent-encoded.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Also, the names of each parameter (after being precent-decoded) are\n treated as UTF-8. Please see the <tt>http:parameter-names#1</tt> function\n for retrieving parameter names submitted using a encoding other than UTF-8.\n </p>\n',summary:"<p>  Returns the names of the parameters contained in the current request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"The names of all parameters in this request. The empty sequence is returned if there are none."},errors:[]},{isDocumented:!0,arity:1,name:"parameter-names",qname:"request:parameter-names",signature:"($encoding as xs:string) as xs:string* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the names of the parameters contained in the current request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is similar to the <tt>request:parameter-names#0</tt> function.\n However, the names are treated (after precent-decoding) using the\n given encoding supplied as parameter. For example, parameters might\n be encoded using the ISO-8859-1 encoding.</p>\n',summary:"<p>  Returns the names of the parameters contained in the current request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"encoding",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The encoding of the parameters in the request (e.g. ISO-8859-1).</div>'}],returns:{type:"xs:string*",description:"The names of all parameters in this request. The empty sequence is returned if there are none."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"parameter-values",qname:"request:parameter-values",signature:"($name as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a sequence of parameter values for the given parameter name\n which are contained in the URL\'s query string or the body of a POST or PUT\n request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parameters are name-value pairs contained in the query string of the URL\n used to make this request. As defined in RFC 1738, the query string of a\n URL starts with a "?" character and ends with the character (if any).\n Additionally, such name-value pairs may be part of the request\'s body if\n it is a PUT or POST request and the content-type of the request is\n "application/x-www-form-urlencoded". Name-value pairs are separated\n using either the "&amp;" or the ";" character.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In general, the names and the values  are precent-encoded. This function\n does the decoding of the parameters, i.e. it returns the values being\n not percent-encoded.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Also, the names and the values of each parameter (after being precent-decoded)\n are treated as UTF-8. Please see the <tt>http:parameter-values#3</tt> function\n for retrieving parameters submitted using a encoding other than UTF-8.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function returns the empty-sequence if no parameter with the\n given name exists in this request. If you want the function to return\n a default value other than the empty sequence, use the\n <tt>http:parameter-values#2</tt> function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A URL could contain the following query string:\n <tt>name1=value1&amp;name2=value2;name1=value3&amp;name3</tt>.\n <tt>name1=value1&amp;name2=value2&amp;name1=value3&amp;name3</tt>.\n The name value pairs in this query string are\n <ul>\n   <li> name: <tt>name1</tt>; values: <tt>value1</tt> and <tt>value3</tt></li>\n   <li> name: <tt>name2</tt>; value: <tt>value2</tt></li>\n   <li> name: <tt>name3</tt>; value: <tt/></li>\n </ul>\n </p>\n',summary:"<p>  Returns a sequence of parameter values for the given parameter name\n which are contained in the URL's query string or the body of a POST or PUT\n request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the parameter whose value(s) should be returned.</div>'}],returns:{type:"xs:string*",description:"A sequence of values for the parameter with the given name. The empty sequence is returned if no parameter exists with the given name."},errors:[]},{isDocumented:!0,arity:2,name:"parameter-values",qname:"request:parameter-values",signature:"($name as xs:string, $default-values as xs:string*) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a sequence of parameter values for the given parameter name\n which are contained in the URL\'s query string or the body of a POST or PUT\n request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is similar to the <tt>request:parameter-values#1</tt> function.\n However, instead of returning the empty-sequence as a default value it returns\n the given default-values sequence if no parameter with the given name is found\n in this request.</p>\n',summary:"<p>  Returns a sequence of parameter values for the given parameter name\n which are contained in the URL's query string or the body of a POST or PUT\n request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the parameter whose value(s) should be returned.</div>'},{name:"default-values",type:"xs:string",occurrence:"*",description:""}],returns:{type:"xs:string*",description:"A sequence of values for the parameter with the given name. The sequence given as $default-values parameter is returned if no parameter exists with the given name."},errors:[]},{isDocumented:!0,arity:3,name:"parameter-values",qname:"request:parameter-values",signature:"($name as xs:string, $default-values as xs:string*, $encoding as xs:string) as xs:string* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a sequence of parameter values for the given parameter name\n which are contained in the URL\'s query string or the body of a POST or PUT\n request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is similar to the <tt>request:parameter-values#2</tt> function.\n However, the names and values are treated (after precent-decoding) using the\n given encoding supplied as third parameter. For example, parameters might\n be encoded using the ISO-8859-1 encoding.</p>\n',summary:"<p>  Returns a sequence of parameter values for the given parameter name\n which are contained in the URL's query string or the body of a POST or PUT\n request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the parameter whose value(s) should be returned.</div>'},{name:"default-values",type:"xs:string",occurrence:"*",description:""},{name:"encoding",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The encoding of the parameters in the request (e.g. ISO-8859-1)</div>'}],returns:{type:"xs:string*",description:"A sequence of values for the parameter with the given name. The sequence given as $default-values parameter is returned if no parameter exists with the given name."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"parts",qname:"request:parts",signature:"() as element(request:multipart) external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the metadata of all parts contained in a multipart request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The data is returned as an element with name <tt>request:mulitpart</tt>\n as shown in the following example.</p>\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  &lt;multipart xmlns="http://www.28msec.com/modules/http/request"\n    media-type="multipart/...; boundary=..."&gt;\n    &lt;header name="Content-Disposition" value=\'form-data; filename="..."\'/&gt;\n    &lt;header name="Content-Type" value="application/octet-stream"/&gt;\n    &lt;body filename="..." src="..."/&gt;\n    &lt;header name="Content-Disposition" value=\'form-data; filename="..."\'/&gt;\n    &lt;header name="Content-Type" value="application/octet-stream"/&gt;\n    &lt;body filename="..." src="..."/&gt;\n  &lt;/multipart&gt;\n </code>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The <tt>media-type</tt> is the type of the content as given in the\n request (i.e. it\'s value is equal to the value returned by\n <tt>request:header-values("Content-Type")</tt>).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Within the <tt>multipart</tt> element is a sequence of\n (<tt>header</tt>*,<tt>body</tt>) elements. Each such group corresponds to\n one part. Every <tt>header</tt> belongs to a header for this part and the\n <tt>body</tt> refers to the value of a part. The actual value of a part\n can be retrieved by passing the value of the <tt>src</tt> attribute of\n the <tt>body</tt> to the <tt>request:text-part</tt> or\n <tt>request:binary-part</tt> functions. The other attributes of the\n <tt>body</tt> element represent a parameter of the Content-Disposition\n header as described in RFC 2183 (e.g. filename, name, creation-date).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that recursive multipart content is not supported.</p>\n',summary:"<p>  Returns the metadata of all parts contained in a multipart request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(request:multipart)",description:"a multipart element representing the meta data of the multipart content"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:0,name:"path",qname:"request:path",signature:"() as xs:string",description:" Return the path component of the request URI. The path starts after the\n host and ends before the query string starts.\n",summary:"<p> Return the path component of the request URI.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The path component of the request URI"},errors:[]},{isDocumented:!0,arity:0,name:"query-string",qname:"request:query-string",signature:"() as xs:string external",description:" <p xmlns:xqdoc=\"http://www.xqdoc.org/1.0\">Returns the query string that was used to make this request.</p>\n <p xmlns:xqdoc=\"http://www.xqdoc.org/1.0\">The query string contains the part of the request URL that\n starts with the '?' character to the end or the starting of the\n fragment (i.e. the '#' character).</p>\n",summary:"<p>  Returns the query string that was used to make this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The query string part of the request's URL"},errors:[]},{isDocumented:!0,arity:0,name:"remote-addr",qname:"request:remote-addr",signature:"() as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the IP address of the client to which this request\n is connected.</p>\n',summary:"<p>  Returns the IP address of the client to which this request\n is connected.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The IP address on the client side to which this request is connected."},errors:[]},{isDocumented:!0,arity:0,name:"remote-port",qname:"request:remote-port",signature:"() as xs:int external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the port of the client to which this request is connected.</p>\n',summary:"<p>  Returns the port of the client to which this request is connected.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:int",description:"The port on the client side to which this request is connected."},errors:[]},{isDocumented:!0,arity:0,name:"server-name",qname:"request:server-name",signature:"() as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the server name of the server running the application.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The web server\'s hostname or IP address.</p>\n',summary:"<p>  Returns the server name of the server running the application.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The name of the server that runs the application accepting this request."},errors:[]},{isDocumented:!0,arity:0,name:"server-port",qname:"request:server-port",signature:"() as xs:int external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the sever port to which the client making the current request\n is connected.</p>\n',summary:"<p>  Returns the sever port to which the client making the current request\n is connected.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:int",description:"The server port to which the client is connected."},errors:[]},{isDocumented:!0,arity:0,name:"text-content",qname:"request:text-content",signature:"() as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the content of the request as string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns the content of the request only\n if the content-type refers to a type that can be treated\n as text (e.g. text/* or application/xml). The function raises\n an error if the content cannot be treated as text.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The text content is interpreted using the encoding/charset\n that is specified in the Content-Type header of the request. If\n no charset is specified, the default ISO-8859-1 is used. If a encoding\n other than the specified or default one should be used, the\n <tt>request:text-content#1</tt> function should be used.</p>\n',summary:"<p>  Returns the content of the request as string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The content of the request as a string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the encoding specified in the Content-Type header is invalid or not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the content contained in the body of the request cannot be treated as text.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"text-content",qname:"request:text-content",signature:"($overwrite-encoding as xs:string) as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the content of the request as string interpreting\n it with the given encoding.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns the content of the request only\n if the content-type refers to a type that can be treated\n as text (e.g. text/* or application/xml). The function raises\n an error if the content cannot be treated as text.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The text content is interpreted using the given encoding/charset.\n That is, the charset specified in the Content-Type header of the request\n is ignored. An error is raised if the given encoding is invalid\n or not supported.</p>\n',summary:"<p>  Returns the content of the request as string interpreting\n it with the given encoding.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"overwrite-encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:"The content of the request as a string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the encoding specified in the Content-Type header or the $overwrite-encoding parameter is invalid or not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the content contained in the body of the request cannot be treated as text.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"text-part",qname:"request:text-part",signature:"($ref as xs:string) as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the value of a part as string</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A part is identified by a reference that is the value of a\n <tt>src</tt> attribute returned by the <tt>request:parts</tt> function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The value of the text part is interpreted using the encoding/charset\n given in the headers of the part. If no encoding is given, the default\n US-ASCII is assumed.</p>\n',summary:"<p>  Returns the value of a part as string \n  A part is identified by a reference that is the value of a\n  src  attribute returned by the  request:parts  function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"ref",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the part</div>'}],returns:{type:"xs:string",description:"the value of the part as string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the encoding given in the headers of the part is invalid or not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the value of the part cannot be treated as text</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-part if the part with the given name ($ref) does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:2,name:"text-part",qname:"request:text-part",signature:"($ref as xs:string, $overwrite-encoding as xs:string) as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the value of a part as string interpreting\n it with the given encoding.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A part is identified by a reference that is the value of a\n <tt>src</tt> attribute returned by the <tt>request:parts</tt> function.</p>\n',summary:"<p>  Returns the value of a part as string interpreting\n it with the given encoding.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"ref",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the part</div>'},{name:"overwrite-encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:"the value of the part as string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the encoding given using the $overwrite-encoding parameter is invalid or not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the value of the part cannot be treated as text</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-part if the part with the given name ($ref) does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:0,name:"uri",qname:"request:uri",signature:"() as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the URI that was used to make this request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The value returned contains the part of the URL starting\n from the path to the end or the starting of the fragment (i.e.\n the \'#\' character).</p>\n',summary:"<p>  Returns the URI that was used to make this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The path and query string part of the request's URL"},errors:[]},{isDocumented:!0,arity:0,name:"user-agent",qname:"request:user-agent",signature:"() as xs:string? external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the user agent that made to perform the current request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function returns the value of the User-Agent header\n contained in the current request.</p>\n',summary:"<p>  Returns the user agent that made to perform the current request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string?",description:"The user agent used to perform this request of the empty sequence if there was no User-Agent header in the request."},errors:[]}],variables:[]},"http://www.w3.org/2005/xpath-functions":{ns:"http://www.w3.org/2005/xpath-functions",description:" This module contains all the functions specified in the\n W3C XPath and XQuery Functions and Operators 3.0.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.w3.org/TR/xpath-functions-30/</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">www.w3c.org</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[],functions:[{isDocumented:!0,arity:2,name:"QName",qname:"fn:QName",signature:"($paramURI as xs:string?, $paramQName as xs:string) as xs:QName external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Constructs an <code>xs:QName</code> value given a namespace URI and a lexical\n             QName.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="QName" return-type="xs:QName" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="paramURI" type="xs:string?"/><arg name="paramQName" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The namespace URI in the returned QName is taken from <code>$paramURI</code>. If\n                <code>$paramURI</code> is the zero-length string or the empty sequence, it represents\n             "no namespace".</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The prefix (or absence of a prefix) in <code>$paramQName</code> is retained in the\n             returned <code>xs:QName</code> value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The local name in the result is taken from the local part of\n             <code>$paramQName</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="CA" code="0002"/> if <code>$paramQName</code> does\n             not have the correct lexical form for an instance of <code>xs:QName</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="CA" code="0002"/> if <code>$paramURI</code> is the\n             zero-length string or the empty sequence, and the value of <code>$paramQName</code>\n             contains a colon (<code>:</code>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="G">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CA" code="0002"/> if <code>$paramURI</code> is not a valid URI (XML Namespaces 1.0) or\n             IRI (XML Namespaces 1.1). </p></div>\n',summary:"<p>  Constructs an  xs:QName  value given a namespace URI and a lexical\n             QName.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"paramURI",type:"xs:string",occurrence:"?",description:""},{name:"paramQName",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:QName",description:""},errors:[]},{isDocumented:!0,arity:1,name:"abs",qname:"fn:abs",signature:"($arg as numeric?) as numeric? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the absolute value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="abs" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">General rules: see <specref ref="numeric-value-functions"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is negative the function returns <code>-$arg</code>, otherwise it\n             returns <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the type of <code>$arg</code> is one of the four numeric types <code>xs:float</code>,\n                <code>xs:double</code>, <code>xs:decimal</code> or <code>xs:integer</code> the type\n             of the result is the same as the type of <code>$arg</code>. If the type of\n                <code>$arg</code> is a type derived from one of the numeric types, the result is an\n             instance of the base numeric type.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For <code>xs:float</code> and <code>xs:double</code> arguments, if the argument is\n             positive zero or negative zero, then positive zero is returned. If the argument is\n             positive or negative infinity, positive infinity is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:abs(10.5)</code> returns <code>10.5</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:abs(-10.5)</code> returns <code>10.5</code>.</p></div>\n',summary:"<p>  Returns the absolute value of  $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"numeric",occurrence:"?",description:""}],returns:{type:"numeric?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"adjust-date-to-timezone",qname:"fn:adjust-date-to-timezone",signature:"($arg as xs:date?) as xs:date? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Adjusts an <code>xs:date</code> value to a specific timezone, or to no timezone\n             at all; the result is the date in the target timezone that contains the starting instant\n             of the supplied date.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="adjust-date-to-timezone" return-type="xs:date?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:date?"/></proto></example><example role="signature"><proto name="adjust-date-to-timezone" return-type="xs:date?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:date?"/><arg name="timezone" type="xs:dayTimeDuration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$timezone</code> is not specified, then the effective value of\n                <code>$timezone</code> is the value of the implicit timezone in the dynamic\n             context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> is the empty sequence, then the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             the empty sequence, then the result is the value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             not the empty sequence, then the result is <code>$arg</code> with <code>$timezone</code>\n             as the timezone component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is the empty\n             sequence, then the result is the local value of <code>$arg</code> without its timezone\n             component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is not the\n             empty sequence, then the function returns the value of the expression:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>Let <code>$dt</code> be the value of <code>fn:dateTime($arg,\n                      xs:time(\'00:00:00\'))</code>.</p></item><item><p>Let <code>$adt</code> be the value of <code>fn:adjust-dateTime-to-timezone($dt,\n                      $timezone)</code></p></item><item><p>The function returns the value of <code>xs:date($adt)</code></p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DT" code="0003"/> if <code>$timezone</code> is less\n             than <code>-PT14H</code> or greater than <code>PT14H</code> or is not an integral number\n             of minutes.</p></div>\n',summary:"<p>  Adjusts an  xs:date  value to a specific timezone, or to no timezone\n             at all; the result is the date in the target timezone that contains the starting instant\n             of the supplied date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:date",occurrence:"?",description:""}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"adjust-date-to-timezone",qname:"fn:adjust-date-to-timezone",signature:"($arg as xs:date?, $timezone as xs:dayTimeDuration?) as xs:date? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Adjusts an <code>xs:date</code> value to a specific timezone, or to no timezone\n             at all; the result is the date in the target timezone that contains the starting instant\n             of the supplied date.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="adjust-date-to-timezone" return-type="xs:date?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:date?"/></proto></example><example role="signature"><proto name="adjust-date-to-timezone" return-type="xs:date?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:date?"/><arg name="timezone" type="xs:dayTimeDuration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$timezone</code> is not specified, then the effective value of\n                <code>$timezone</code> is the value of the implicit timezone in the dynamic\n             context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> is the empty sequence, then the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             the empty sequence, then the result is the value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             not the empty sequence, then the result is <code>$arg</code> with <code>$timezone</code>\n             as the timezone component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is the empty\n             sequence, then the result is the local value of <code>$arg</code> without its timezone\n             component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is not the\n             empty sequence, then the function returns the value of the expression:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>Let <code>$dt</code> be the value of <code>fn:dateTime($arg,\n                      xs:time(\'00:00:00\'))</code>.</p></item><item><p>Let <code>$adt</code> be the value of <code>fn:adjust-dateTime-to-timezone($dt,\n                      $timezone)</code></p></item><item><p>The function returns the value of <code>xs:date($adt)</code></p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DT" code="0003"/> if <code>$timezone</code> is less\n             than <code>-PT14H</code> or greater than <code>PT14H</code> or is not an integral number\n             of minutes.</p></div>\n',summary:"<p>  Adjusts an  xs:date  value to a specific timezone, or to no timezone\n             at all; the result is the date in the target timezone that contains the starting instant\n             of the supplied date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:date",occurrence:"?",description:""},{name:"timezone",type:"xs:dayTimeDuration",occurrence:"?",description:""}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"adjust-dateTime-to-timezone",qname:"fn:adjust-dateTime-to-timezone",signature:"($arg as xs:dateTime?) as xs:dateTime external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Adjusts an <code>xs:dateTime</code> value to a specific timezone, or to no\n             timezone at all.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="adjust-dateTime-to-timezone" return-type="xs:dateTime?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:dateTime?"/></proto></example><example role="signature"><proto name="adjust-dateTime-to-timezone" return-type="xs:dateTime?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:dateTime?"/><arg name="timezone" type="xs:dayTimeDuration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$timezone</code> is not specified, then the effective value of\n                <code>$timezone</code> is the value of the implicit timezone in the dynamic\n             context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> is the empty sequence, then the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             the empty sequence, then the result is <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             not the empty sequence, then the result is <code>$arg</code> with <code>$timezone</code>\n             as the timezone component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is the empty\n             sequence, then the result is the local value of <code>$arg</code> without its timezone\n             component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is not the\n             empty sequence, then the result is the <code>xs:dateTime</code> value that is equal to\n                <code>$arg</code> and that has a timezone component equal to\n             <code>$timezone</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DT" code="0003"/> if <code>$timezone</code> is less\n             than <code>-PT14H</code> or greater than <code>PT14H</code> or is not an integral number\n             of minutes.</p></div>\n',summary:"<p>  Adjusts an  xs:dateTime  value to a specific timezone, or to no\n             timezone at all.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:dateTime",occurrence:"?",description:""}],returns:{type:"xs:dateTime",description:""},errors:[]},{isDocumented:!0,arity:2,name:"adjust-dateTime-to-timezone",qname:"fn:adjust-dateTime-to-timezone",signature:"($arg as xs:dateTime?, $timezone as xs:dayTimeDuration?) as xs:dateTime external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Adjusts an <code>xs:dateTime</code> value to a specific timezone, or to no\n             timezone at all.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="adjust-dateTime-to-timezone" return-type="xs:dateTime?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:dateTime?"/></proto></example><example role="signature"><proto name="adjust-dateTime-to-timezone" return-type="xs:dateTime?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:dateTime?"/><arg name="timezone" type="xs:dayTimeDuration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$timezone</code> is not specified, then the effective value of\n                <code>$timezone</code> is the value of the implicit timezone in the dynamic\n             context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> is the empty sequence, then the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             the empty sequence, then the result is <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             not the empty sequence, then the result is <code>$arg</code> with <code>$timezone</code>\n             as the timezone component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is the empty\n             sequence, then the result is the local value of <code>$arg</code> without its timezone\n             component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is not the\n             empty sequence, then the result is the <code>xs:dateTime</code> value that is equal to\n                <code>$arg</code> and that has a timezone component equal to\n             <code>$timezone</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DT" code="0003"/> if <code>$timezone</code> is less\n             than <code>-PT14H</code> or greater than <code>PT14H</code> or is not an integral number\n             of minutes.</p></div>\n',summary:"<p>  Adjusts an  xs:dateTime  value to a specific timezone, or to no\n             timezone at all.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:dateTime",occurrence:"?",description:""},{name:"timezone",type:"xs:dayTimeDuration",occurrence:"?",description:""}],returns:{type:"xs:dateTime",description:""},errors:[]},{isDocumented:!0,arity:1,name:"adjust-time-to-timezone",qname:"fn:adjust-time-to-timezone",signature:"($arg as xs:time?) as xs:time? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Adjusts an <code>xs:time</code> value to a specific timezone, or to no timezone\n             at all.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="adjust-time-to-timezone" return-type="xs:time?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:time?"/></proto></example><example role="signature"><proto name="adjust-time-to-timezone" return-type="xs:time?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:time?"/><arg name="timezone" type="xs:dayTimeDuration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$timezone</code> is not specified, then the effective value of\n                <code>$timezone</code> is the value of the implicit timezone in the dynamic\n             context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> is the empty sequence, then the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             the empty sequence, then the result is <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             not the empty sequence, then the result is <code>$arg</code> with <code>$timezone</code>\n             as the timezone component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is the empty\n             sequence, then the result is the localized value of <code>$arg</code> without its\n             timezone component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is not the\n             empty sequence, then:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>Let <code>$dt</code> be the <code>xs:dateTime</code> value\n                      <code>fn:dateTime(xs:date(\'1972-12-31\'), $arg)</code>.</p></item><item><p>Let <code>$adt</code> be the value of <code>fn:adjust-dateTime-to-timezone($dt,\n                      $timezone)</code>\n                </p></item><item><p>The function returns the <code>xs:time</code> value\n                   <code>xs:time($adt)</code>.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DT" code="0003"/> if <code>$timezone</code> is less\n             than <code>-PT14H</code> or greater than <code>PT14H</code> or if does not contain an\n             integral number of minutes.</p></div>\n',summary:"<p>  Adjusts an  xs:time  value to a specific timezone, or to no timezone\n             at all.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:time",occurrence:"?",description:""}],returns:{type:"xs:time?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"adjust-time-to-timezone",qname:"fn:adjust-time-to-timezone",signature:"($arg as xs:time?, $timezone as xs:dayTimeDuration?) as xs:time? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Adjusts an <code>xs:time</code> value to a specific timezone, or to no timezone\n             at all.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="adjust-time-to-timezone" return-type="xs:time?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:time?"/></proto></example><example role="signature"><proto name="adjust-time-to-timezone" return-type="xs:time?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:time?"/><arg name="timezone" type="xs:dayTimeDuration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$timezone</code> is not specified, then the effective value of\n                <code>$timezone</code> is the value of the implicit timezone in the dynamic\n             context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> is the empty sequence, then the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             the empty sequence, then the result is <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> does not have a timezone component and <code>$timezone</code> is\n             not the empty sequence, then the result is <code>$arg</code> with <code>$timezone</code>\n             as the timezone component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is the empty\n             sequence, then the result is the localized value of <code>$arg</code> without its\n             timezone component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$arg</code> has a timezone component and <code>$timezone</code> is not the\n             empty sequence, then:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>Let <code>$dt</code> be the <code>xs:dateTime</code> value\n                      <code>fn:dateTime(xs:date(\'1972-12-31\'), $arg)</code>.</p></item><item><p>Let <code>$adt</code> be the value of <code>fn:adjust-dateTime-to-timezone($dt,\n                      $timezone)</code>\n                </p></item><item><p>The function returns the <code>xs:time</code> value\n                   <code>xs:time($adt)</code>.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DT" code="0003"/> if <code>$timezone</code> is less\n             than <code>-PT14H</code> or greater than <code>PT14H</code> or if does not contain an\n             integral number of minutes.</p></div>\n',summary:"<p>  Adjusts an  xs:time  value to a specific timezone, or to no timezone\n             at all.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:time",occurrence:"?",description:""},{name:"timezone",type:"xs:dayTimeDuration",occurrence:"?",description:""}],returns:{type:"xs:time?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"analyze-string",qname:"fn:analyze-string",signature:"($input as xs:string?, $pattern as xs:string) as element(fn:analyze-string-result) external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Analyzes a string using a regular expression, returning an XML structure that\n             identifies which parts of the input string matched or failed to match the regular\n             expression, and in the case of matched substrings, which substrings matched each\n             capturing group in the regular expression.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="analyze-string" return-type="element(fn:analyze-string-result)" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/></proto></example><example role="signature"><proto name="analyze-string" return-type="element(fn:analyze-string-result)" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="flags" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of calling the first version of this function (omitting the argument\n                <code>$flags</code>) is the same as the effect of calling the second version with the\n                <code>$flags</code> argument set to a zero-length string. Flags are defined in\n                <specref ref="flags"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$flags</code> argument is interpreted in the same way as for the\n                <code>fn:matches</code> function.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$input</code> is the empty sequence the function behaves as if\n                <code>$input</code> were the zero-length string. In this situation the result will be\n             an element node with no children.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an element node whose local name is\n                <code>analyze-string-result</code>. This element and all its descendant elements have\n             the namespace URI <code>http://www.w3.org/2005/xpath-functions</code>. The namespace\n             prefix is <termref def="implementation-dependent"/>. The children of this element are a\n             sequence of <code>fn:match</code> and <code>fn:non-match</code> elements. This sequence\n             is formed by breaking the <code>$input</code> string into a sequence of strings,\n             returning any substring that matches <code>$pattern</code> as the content of a\n                <code>match</code> element, and any intervening substring as the content of a\n                <code>non-match</code> element.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">More specifically, the function starts at the beginning of the input string and attempts\n             to find the first substring that matches the regular expression. If there are several\n             matches, the first match is defined to be the one whose starting position comes first in\n             the string. If several alternatives within the regular expression both match at the same\n             position in the input string, then the match that is chosen is the first alternative\n             that matches. For example, if the input string is <code>The quick brown fox jumps</code>\n             and the regular expression is <code>jump|jumps</code>, then the match that is chosen is\n                <code>jump</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Having found the first match, the instruction proceeds to find the second and subsequent\n             matches by repeating the search, starting at the first <termref def="character">character</termref> that was not included in the previous match.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The input string is thus partitioned into a sequence of substrings, some of which match\n             the regular expression, others which do not match it. Each substring will contain at\n             least one character. This sequence is represented in the result by the sequence of\n                <code>fn:match</code> and <code>fn:non-match</code> children of the returned element\n             node; the string value of the <code>fn:match</code> or <code>fn:non-match</code> element\n             will be the corresponding substring of <code>$input</code>, and the string value of the\n             returned element node will therefore be the same as <code>$input</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The content of an <code>fn:non-match</code> element is always a single text node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The content of a <code>fn:match</code> element, however, is in general a sequence of\n             text nodes and <code>fn:group</code> element children. An <code>fn:group</code> element\n             with a <code>nr</code> attribute having the integer value <var>N</var> identifies the\n             substring captured by the <var>Nth</var> parenthesized sub-expression in the regular\n             expression. For each capturing subexpression there will be at most one corresponding\n                <code>fn:group</code> element in each <code>fn:match</code> element in the\n             result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the function is called twice with the same arguments, it is <termref def="implementation-dependent"/> whether the two calls return the same element node\n             or distinct (but deep equal) element nodes. In this respect it is\n             <termref def="nondeterministic">nondeterministic</termref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="J">The base URI of the element nodes in the result is\n          <termref def="implementation-dependent"/></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A schema is defined for the structure of the returned element, containing the\n             definitions below. The returned element and its descendants will have type annotations\n             obtained by validating the returned element against this schema, unless the function is\n             used in an environment where type annotations are not supported (for example, a Basic\n             XSLT Processor), in which case the elements will all be annotated as\n                <code>xs:untyped</code> and the attributes as <code>xs:untypedAtomic</code>.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p diff="add" at="M">A free-standing copy of this schema can be found at <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="analyze-string.xsd" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">analyze-string.xsd</loc></p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">\n             <eg xml:space="preserve">&lt;?xml version="1.0" encoding="UTF-8"?&gt;\n &lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"\n     targetNamespace="http://www.w3.org/2005/xpath-functions"\n     xmlns:fn="http://www.w3.org/2005/xpath-functions"\n     elementFormDefault="qualified"&gt;\n     &lt;xs:element name="analyze-string-result" type="fn:analyze-string-result-type"/&gt;\n     &lt;xs:element name="match" type="fn:match-type"/&gt;\n     &lt;xs:element name="non-match" type="xs:string"/&gt;\n     &lt;xs:element name="group" type="fn:group-type"/&gt;\n     &lt;xs:complexType name="analyze-string-result-type" mixed="true"&gt;\n         &lt;xs:choice minOccurs="0" maxOccurs="unbounded"&gt;\n             &lt;xs:element ref="fn:match"/&gt;\n             &lt;xs:element ref="fn:non-match"/&gt;\n         &lt;/xs:choice&gt;\n     &lt;/xs:complexType&gt;\n     &lt;xs:complexType name="match-type" mixed="true"&gt;\n         &lt;xs:sequence&gt;\n             &lt;xs:element ref="fn:group" minOccurs="0" maxOccurs="unbounded"/&gt;\n         &lt;/xs:sequence&gt;\n     &lt;/xs:complexType&gt;\n     &lt;xs:complexType name="group-type" mixed="true"&gt;\n         &lt;xs:sequence&gt;\n             &lt;xs:element ref="fn:group" minOccurs="0" maxOccurs="unbounded"/&gt;\n         &lt;/xs:sequence&gt;\n         &lt;xs:attribute name="nr" type="xs:positiveInteger"/&gt;\n     &lt;/xs:complexType&gt;\n &lt;/xs:schema&gt;\n </eg>\n          </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0002"/> if the value of\n                <code>$pattern</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0001"/> if the value of\n                <code>$flags</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0003"/> if the supplied\n                <code>$pattern</code> matches a zero-length string, that is, if <code>fn:matches("",\n                $pattern, $flags)</code> returns <code>true</code>.</p></div>\n',summary:"<p>  Analyzes a string using a regular expression, returning an XML structure that\n             identifies which parts of the input string matched or failed to match the regular\n             expression, and in the case of matched substrings, which substrings matched each\n             capturing group in the regular expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:""},{name:"pattern",type:"xs:string",occurrence:null,description:""}],returns:{type:"element(fn:analyze-string-result)",description:""},errors:[]},{isDocumented:!0,arity:3,name:"analyze-string",qname:"fn:analyze-string",signature:"($input as xs:string?, $pattern as xs:string, $flags as xs:string) as element(fn:analyze-string-result) external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Analyzes a string using a regular expression, returning an XML structure that\n             identifies which parts of the input string matched or failed to match the regular\n             expression, and in the case of matched substrings, which substrings matched each\n             capturing group in the regular expression.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="analyze-string" return-type="element(fn:analyze-string-result)" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/></proto></example><example role="signature"><proto name="analyze-string" return-type="element(fn:analyze-string-result)" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="flags" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of calling the first version of this function (omitting the argument\n                <code>$flags</code>) is the same as the effect of calling the second version with the\n                <code>$flags</code> argument set to a zero-length string. Flags are defined in\n                <specref ref="flags"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$flags</code> argument is interpreted in the same way as for the\n                <code>fn:matches</code> function.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$input</code> is the empty sequence the function behaves as if\n                <code>$input</code> were the zero-length string. In this situation the result will be\n             an element node with no children.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an element node whose local name is\n                <code>analyze-string-result</code>. This element and all its descendant elements have\n             the namespace URI <code>http://www.w3.org/2005/xpath-functions</code>. The namespace\n             prefix is <termref def="implementation-dependent"/>. The children of this element are a\n             sequence of <code>fn:match</code> and <code>fn:non-match</code> elements. This sequence\n             is formed by breaking the <code>$input</code> string into a sequence of strings,\n             returning any substring that matches <code>$pattern</code> as the content of a\n                <code>match</code> element, and any intervening substring as the content of a\n                <code>non-match</code> element.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">More specifically, the function starts at the beginning of the input string and attempts\n             to find the first substring that matches the regular expression. If there are several\n             matches, the first match is defined to be the one whose starting position comes first in\n             the string. If several alternatives within the regular expression both match at the same\n             position in the input string, then the match that is chosen is the first alternative\n             that matches. For example, if the input string is <code>The quick brown fox jumps</code>\n             and the regular expression is <code>jump|jumps</code>, then the match that is chosen is\n                <code>jump</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Having found the first match, the instruction proceeds to find the second and subsequent\n             matches by repeating the search, starting at the first <termref def="character">character</termref> that was not included in the previous match.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The input string is thus partitioned into a sequence of substrings, some of which match\n             the regular expression, others which do not match it. Each substring will contain at\n             least one character. This sequence is represented in the result by the sequence of\n                <code>fn:match</code> and <code>fn:non-match</code> children of the returned element\n             node; the string value of the <code>fn:match</code> or <code>fn:non-match</code> element\n             will be the corresponding substring of <code>$input</code>, and the string value of the\n             returned element node will therefore be the same as <code>$input</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The content of an <code>fn:non-match</code> element is always a single text node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The content of a <code>fn:match</code> element, however, is in general a sequence of\n             text nodes and <code>fn:group</code> element children. An <code>fn:group</code> element\n             with a <code>nr</code> attribute having the integer value <var>N</var> identifies the\n             substring captured by the <var>Nth</var> parenthesized sub-expression in the regular\n             expression. For each capturing subexpression there will be at most one corresponding\n                <code>fn:group</code> element in each <code>fn:match</code> element in the\n             result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the function is called twice with the same arguments, it is <termref def="implementation-dependent"/> whether the two calls return the same element node\n             or distinct (but deep equal) element nodes. In this respect it is\n             <termref def="nondeterministic">nondeterministic</termref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="J">The base URI of the element nodes in the result is\n          <termref def="implementation-dependent"/></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A schema is defined for the structure of the returned element, containing the\n             definitions below. The returned element and its descendants will have type annotations\n             obtained by validating the returned element against this schema, unless the function is\n             used in an environment where type annotations are not supported (for example, a Basic\n             XSLT Processor), in which case the elements will all be annotated as\n                <code>xs:untyped</code> and the attributes as <code>xs:untypedAtomic</code>.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p diff="add" at="M">A free-standing copy of this schema can be found at <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="analyze-string.xsd" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">analyze-string.xsd</loc></p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">\n             <eg xml:space="preserve">&lt;?xml version="1.0" encoding="UTF-8"?&gt;\n &lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"\n     targetNamespace="http://www.w3.org/2005/xpath-functions"\n     xmlns:fn="http://www.w3.org/2005/xpath-functions"\n     elementFormDefault="qualified"&gt;\n     &lt;xs:element name="analyze-string-result" type="fn:analyze-string-result-type"/&gt;\n     &lt;xs:element name="match" type="fn:match-type"/&gt;\n     &lt;xs:element name="non-match" type="xs:string"/&gt;\n     &lt;xs:element name="group" type="fn:group-type"/&gt;\n     &lt;xs:complexType name="analyze-string-result-type" mixed="true"&gt;\n         &lt;xs:choice minOccurs="0" maxOccurs="unbounded"&gt;\n             &lt;xs:element ref="fn:match"/&gt;\n             &lt;xs:element ref="fn:non-match"/&gt;\n         &lt;/xs:choice&gt;\n     &lt;/xs:complexType&gt;\n     &lt;xs:complexType name="match-type" mixed="true"&gt;\n         &lt;xs:sequence&gt;\n             &lt;xs:element ref="fn:group" minOccurs="0" maxOccurs="unbounded"/&gt;\n         &lt;/xs:sequence&gt;\n     &lt;/xs:complexType&gt;\n     &lt;xs:complexType name="group-type" mixed="true"&gt;\n         &lt;xs:sequence&gt;\n             &lt;xs:element ref="fn:group" minOccurs="0" maxOccurs="unbounded"/&gt;\n         &lt;/xs:sequence&gt;\n         &lt;xs:attribute name="nr" type="xs:positiveInteger"/&gt;\n     &lt;/xs:complexType&gt;\n &lt;/xs:schema&gt;\n </eg>\n          </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0002"/> if the value of\n                <code>$pattern</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0001"/> if the value of\n                <code>$flags</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0003"/> if the supplied\n                <code>$pattern</code> matches a zero-length string, that is, if <code>fn:matches("",\n                $pattern, $flags)</code> returns <code>true</code>.</p></div>\n',summary:"<p>  Analyzes a string using a regular expression, returning an XML structure that\n             identifies which parts of the input string matched or failed to match the regular\n             expression, and in the case of matched substrings, which substrings matched each\n             capturing group in the regular expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:""},{name:"pattern",type:"xs:string",occurrence:null,description:""},{name:"flags",type:"xs:string",occurrence:null,description:""}],returns:{type:"element(fn:analyze-string-result)",description:""},errors:[]},{isDocumented:!0,arity:0,name:"available-environment-variables",qname:"fn:available-environment-variables",signature:"() as xs:string* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a list of environment variable names that are suitable for passing to\n                <code>fn:environment-variable</code>, as a (possibly empty) sequence of strings.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="available-environment-variables" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		environment variables.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence of strings, being the names of the environment variables\n             in the dynamic context in some <termref def="implementation-dependent">implementation-dependent</termref> order.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function is <termref def="dt-deterministic">deterministic</termref>: that is, the\n             set of available environment variables does not vary during evaluation.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a list of strings, containing no duplicates.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">It is intended that the strings in this list should be suitable for passing to\n                <code>fn:environment-variable</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See also the note on security under the definition of the\n                <code>fn:environment-variable</code> function. If access to environment variables has\n             been disabled, <code>fn:available-environment-variables</code> always returns the empty\n             sequence.</p></div>\n',summary:"<p>  Returns a list of environment variable names that are suitable for passing to\n                 fn:environment-variable , as a (possibly empty) sequence of strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:0,name:"available-environment-variables",qname:"fn:available-environment-variables",signature:"() as xs:string* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a list of environment variable names that are suitable for passing to\n                <code>fn:environment-variable</code>, as a (possibly empty) sequence of strings.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="available-environment-variables" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		environment variables.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence of strings, being the names of the environment variables\n             in the dynamic context in some <termref def="implementation-dependent">implementation-dependent</termref> order.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function is <termref def="dt-deterministic">deterministic</termref>: that is, the\n             set of available environment variables does not vary during evaluation.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a list of strings, containing no duplicates.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">It is intended that the strings in this list should be suitable for passing to\n                <code>fn:environment-variable</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See also the note on security under the definition of the\n                <code>fn:environment-variable</code> function. If access to environment variables has\n             been disabled, <code>fn:available-environment-variables</code> always returns the empty\n             sequence.</p></div>\n',summary:"<p>  Returns a list of environment variable names that are suitable for passing to\n                 fn:environment-variable , as a (possibly empty) sequence of strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"avg",qname:"fn:avg",signature:"($arg as xs:anyAtomicType*) as xs:anyAtomicType? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the average of the values in the input sequence <code>$arg</code>, that\n             is, the sum of the values divided by the number of values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="avg" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the empty sequence is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> contains values of type <code>xs:untypedAtomic</code> they are cast\n             to <code>xs:double</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Duration values must either all be <code>xs:yearMonthDuration</code> values or must all\n             be <code>xs:dayTimeDuration</code> values. For numeric values, the numeric promotion\n             rules defined in <specref ref="op.numeric"/> are used to promote all values to a single\n             common type. After these operations, <code>$arg</code> must contain items of a single\n             type, which must be one of the four numeric types, <code>xs:yearMonthDuration</code> or\n                <code>xs:dayTimeDuration</code> or one if its subtypes.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the average of the values as <code>sum($arg) div\n             count($arg)</code>; but the implementation may use an otherwise equivalent algorithm\n             that avoids arithmetic overflow.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains\n             items of incompatible types, as described above.</p></div>\n',summary:"<p>  Returns the average of the values in the input sequence  $arg , that\n             is, the sum of the values divided by the number of values.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"*",description:""}],returns:{type:"xs:anyAtomicType?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"base-uri",qname:"fn:base-uri",signature:"() as xs:anyURI? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the base URI of a node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="base-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="base-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">The zero-argument version of the function returns the base URI of the\n             context node: it is equivalent to calling <code>fn:base-uri(.)</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">The single-argument version of the function behaves as follows:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item>If <code>$arg</code> is the empty sequence, the function returns the empty\n                sequence.</item><item>Otherwise, the function returns the value of the <code>dm:base-uri</code> accessor\n                applied to the node <code>$arg</code>. This accessor is defined, for each kind of\n                node, in the XDM specification (See <xspecref spec="DM30" ref="dm-base-uri"/>).</item></olist><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">As explained in XDM, document, element and processing-instruction nodes have a\n             base-uri property which may be empty. The base-uri property for all other node kinds is\n             the empty sequence. The dm:base-uri accessor returns the base-uri property of a node if\n             it exists and is non-empty; otherwise it returns the result of applying the dm:base-uri\n             accessor to its parent, recursively. If the node does not have a parent, or if the\n             recursive ascent up the ancestor chain encounters a parentless node whose base-uri\n             property is empty, the empty sequence is returned. In the case of namespace nodes,\n             however, the result is always an empty sequence -- it does not depend on the base URI of\n             the parent element.</note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See also <code>fn:static-base-uri</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the base URI of a node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyURI?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"base-uri",qname:"fn:base-uri",signature:"($arg as node()?) as xs:anyURI? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the base URI of a node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="base-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="base-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">The zero-argument version of the function returns the base URI of the\n             context node: it is equivalent to calling <code>fn:base-uri(.)</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">The single-argument version of the function behaves as follows:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item>If <code>$arg</code> is the empty sequence, the function returns the empty\n                sequence.</item><item>Otherwise, the function returns the value of the <code>dm:base-uri</code> accessor\n                applied to the node <code>$arg</code>. This accessor is defined, for each kind of\n                node, in the XDM specification (See <xspecref spec="DM30" ref="dm-base-uri"/>).</item></olist><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">As explained in XDM, document, element and processing-instruction nodes have a\n             base-uri property which may be empty. The base-uri property for all other node kinds is\n             the empty sequence. The dm:base-uri accessor returns the base-uri property of a node if\n             it exists and is non-empty; otherwise it returns the result of applying the dm:base-uri\n             accessor to its parent, recursively. If the node does not have a parent, or if the\n             recursive ascent up the ancestor chain encounters a parentless node whose base-uri\n             property is empty, the empty sequence is returned. In the case of namespace nodes,\n             however, the result is always an empty sequence -- it does not depend on the base URI of\n             the parent element.</note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See also <code>fn:static-base-uri</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the base URI of a node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:"?",description:""}],returns:{type:"xs:anyURI?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"boolean",qname:"fn:boolean",signature:"($arg as item()*) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Computes the effective boolean value of the sequence <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="boolean" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function computes the effective boolean value of a sequence, defined according to\n             the following rules. See also <xspecref spec="XP30" ref="id-ebv"/>.</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If <code>$arg</code> is the empty sequence, <code>fn:boolean</code> returns\n                      <code>false</code>.</p></item><item><p>If <code>$arg</code> is a sequence whose first item is a node,\n                      <code>fn:boolean</code> returns <code>true</code>.</p></item><item><p>If <code>$arg</code> is a singleton value of type <code>xs:boolean</code> or a\n                   derived from <code>xs:boolean</code>, <code>fn:boolean</code> returns\n                      <code>$arg</code>.</p></item><item><p>If <code>$arg</code> is a singleton value of type <code>xs:string</code> or a type\n                   derived from <code>xs:string</code>, <code>xs:anyURI</code> or a type derived from\n                      <code>xs:anyURI</code> or <code>xs:untypedAtomic</code>,\n                      <code>fn:boolean</code> returns <code>false</code> if the operand value has\n                   zero length; otherwise it returns <code>true</code>.</p></item><item><p>If <code>$arg</code> is a singleton value of any numeric type or a type derived\n                   from a numeric type, <code>fn:boolean</code> returns <code>false</code> if the\n                   operand value is <code>NaN</code> or is numerically equal to zero; otherwise it\n                   returns <code>true</code>.</p></item><item><p>In all other cases, <code>fn:boolean</code> raises a type error <errorref class="RG" code="0006"/>.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">The static semantics of this function are described in [Formal\n             Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of this function is not necessarily the same as <code>$arg cast as\n                xs:boolean</code>. For example, <code>fn:boolean("false")</code> returns the value\n                <code>true</code> whereas <code>"false" cast as xs:boolean</code> (which can also be\n             written <code>xs:boolean("false")</code>) returns <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">let <code>$abc</code> := <code>("a", "b", "")</code></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><code>fn:boolean($abc)</code> raises a type error <errorref class="RG" code="0006"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:boolean($abc[1])</code> returns <code>true()</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:boolean($abc[0])</code> returns <code>false()</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:boolean($abc[3])</code> returns <code>false()</code>.</p></div>\n',summary:"<p>  Computes the effective boolean value of the sequence  $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"ceiling",qname:"fn:ceiling",signature:"($arg as numeric?) as numeric? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Rounds <code>$arg</code> upwards to a whole number.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="ceiling" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">General rules: see <specref ref="numeric-value-functions"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the smallest (closest to negative infinity) number with no\n             fractional part that is not less than the value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the type of <code>$arg</code> is one of the four numeric types <code>xs:float</code>,\n                <code>xs:double</code>, <code>xs:decimal</code> or <code>xs:integer</code> the type\n             of the result is the same as the type of <code>$arg</code>. If the type of\n                <code>$arg</code> is a type derived from one of the numeric types, the result is an\n             instance of the base numeric type.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For <code>xs:float</code> and <code>xs:double</code> arguments, if the argument is\n             positive zero, then positive zero is returned. If the argument is negative zero, then\n             negative zero is returned. If the argument is less than zero and greater than -1,\n             negative zero is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:ceiling(10.5)</code> returns <code>11</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:ceiling(-10.5)</code> returns <code>-10</code>.</p></div>\n',summary:"<p>  Rounds  $arg  upwards to a whole number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"numeric",occurrence:"?",description:""}],returns:{type:"numeric?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"codepoint-equal",qname:"fn:codepoint-equal",signature:"($comparand1 as xs:string?, $comparand2 as xs:string?) as xs:boolean? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if two strings are equal, considered codepoint-by-codepoint.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="codepoint-equal" return-type="xs:boolean?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="comparand1" type="xs:string?"/><arg name="comparand2" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If either argument is the empty sequence, the function returns the empty sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns <code>true</code> or <code>false</code> depending on\n             whether the value of <code>$comparand1</code> is equal to the value of\n                <code>$comparand2</code>, according to the Unicode codepoint collation\n                (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function allows <code>xs:anyURI</code> values to be compared without having to\n             specify the Unicode codepoint collation.</p></div>\n',summary:"<p>  Returns true if two strings are equal, considered codepoint-by-codepoint.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"comparand1",type:"xs:string",occurrence:"?",description:""},{name:"comparand2",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:boolean?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"codepoints-to-string",qname:"fn:codepoints-to-string",signature:"($arg as xs:integer*) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Creates an <code>xs:string</code> from a sequence of <termref def="codepoint">codepoints</termref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="codepoints-to-string" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:integer*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the string made up from the <termref def="character">characters</termref> whose Unicode <termref def="codepoint">codepoints</termref> are\n             supplied in <code>$arg</code>. This will be the zero-length string if <code>$arg</code>\n             is the empty sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="M">dynamic</phrase> error is raised <errorref class="CH" code="0001"/> if any of the codepoints in\n                <code>$arg</code> is not a permitted XML character.</p></div>\n',summary:"<p>  Creates an  xs:string  from a sequence of  codepoints .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:integer",occurrence:"*",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"codepoints-to-string",qname:"fn:codepoints-to-string",signature:"($arg as xs:integer*) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Creates an <code>xs:string</code> from a sequence of <termref def="codepoint">codepoints</termref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="codepoints-to-string" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:integer*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the string made up from the <termref def="character">characters</termref> whose Unicode <termref def="codepoint">codepoints</termref> are\n             supplied in <code>$arg</code>. This will be the zero-length string if <code>$arg</code>\n             is the empty sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="M">dynamic</phrase> error is raised <errorref class="CH" code="0001"/> if any of the codepoints in\n                <code>$arg</code> is not a permitted XML character.</p></div>\n',summary:"<p>  Creates an  xs:string  from a sequence of  codepoints .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:integer",occurrence:"*",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:0,name:"collection",qname:"fn:collection",signature:"() as node()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of nodes representing a collection of documents indentified\n             by a collection URI; or a default collection if no URI is supplied.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="collection" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="collection" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		available node collections, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function takes an <code>xs:string</code> as argument and returns a sequence of\n             nodes obtained by interpreting <code>$arg</code> as an <code>xs:anyURI</code> and\n             resolving it according to the mapping specified in <term>Available node collections</term>\n             described in <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <term>Available node collections</term> provides a mapping from this string to a sequence\n             of nodes, the function returns that sequence. If <term>Available node collections</term> maps\n             the string to an empty sequence, then the function returns an empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is not specified, the function returns the sequence of the nodes in\n             the default node collection in the dynamic context. See <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is a relative <code>xs:anyURI</code>, it is resolved\n             against the value of the base-URI property from the static context. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function behaves as if it had been\n             called without an argument. See above.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">By default, this function is <termref def="deterministic">deterministic</termref>.\n             This means that repeated\n             calls on the function with the same argument will return the same result. However, for\n             performance reasons, implementations may provide a user option to evaluate the function\n             without a guarantee of determinism. The manner in which any such option is provided is\n                <termref def="implementation-defined"/>. If the user has not selected such an option,\n             a call to this function must either return a deterministic result or must raise a <phrase diff="add" at="L">dynamic</phrase> error\n                <errorref class="DC" code="0003"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="G">There is no requirement that the returned nodes should be in document\n             order, nor is there a requirement that the result should contain no duplicates.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if no URI is supplied and the\n             value of the default collection is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="J">A <phrase diff="add" at="M">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if <term>available\n                node collections</term> provides no mapping for the absolutized URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0004"/> if <code>$arg</code> is not a\n             valid <code>xs:anyURI</code>.</p></div>\n',summary:"<p>  Returns a sequence of nodes representing a collection of documents indentified\n             by a collection URI; or a default collection if no URI is supplied.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"collection",qname:"fn:collection",signature:"($arg as xs:string?) as node()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of nodes representing a collection of documents indentified\n             by a collection URI; or a default collection if no URI is supplied.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="collection" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="collection" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		available node collections, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function takes an <code>xs:string</code> as argument and returns a sequence of\n             nodes obtained by interpreting <code>$arg</code> as an <code>xs:anyURI</code> and\n             resolving it according to the mapping specified in <term>Available node collections</term>\n             described in <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <term>Available node collections</term> provides a mapping from this string to a sequence\n             of nodes, the function returns that sequence. If <term>Available node collections</term> maps\n             the string to an empty sequence, then the function returns an empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is not specified, the function returns the sequence of the nodes in\n             the default node collection in the dynamic context. See <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is a relative <code>xs:anyURI</code>, it is resolved\n             against the value of the base-URI property from the static context. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function behaves as if it had been\n             called without an argument. See above.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">By default, this function is <termref def="deterministic">deterministic</termref>.\n             This means that repeated\n             calls on the function with the same argument will return the same result. However, for\n             performance reasons, implementations may provide a user option to evaluate the function\n             without a guarantee of determinism. The manner in which any such option is provided is\n                <termref def="implementation-defined"/>. If the user has not selected such an option,\n             a call to this function must either return a deterministic result or must raise a <phrase diff="add" at="L">dynamic</phrase> error\n                <errorref class="DC" code="0003"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="G">There is no requirement that the returned nodes should be in document\n             order, nor is there a requirement that the result should contain no duplicates.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if no URI is supplied and the\n             value of the default collection is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="J">A <phrase diff="add" at="M">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if <term>available\n                node collections</term> provides no mapping for the absolutized URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0004"/> if <code>$arg</code> is not a\n             valid <code>xs:anyURI</code>.</p></div>\n',summary:"<p>  Returns a sequence of nodes representing a collection of documents indentified\n             by a collection URI; or a default collection if no URI is supplied.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"compare",qname:"fn:compare",signature:"($comparand1 as xs:string?, $comparand2 as xs:string?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns -1, 0, or 1, depending on whether <code>$comparand1</code> collates\n             before, equal to, or after <code>$comparand2</code> according to the rules of a selected\n             collation.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="compare" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="comparand1" type="xs:string?"/><arg name="comparand2" type="xs:string?"/></proto></example><example role="signature"><proto name="compare" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="comparand1" type="xs:string?"/><arg name="comparand2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns -1, 0, or 1, depending on whether the value of the <code>$comparand1</code> is\n             respectively less than, equal to, or greater than the value of <code>$comparand2</code>,\n             according to the rules of the collation that is used. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If either <code>$comparand1</code> or <code>$comparand2</code> is the empty sequence,\n             the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function, called with the first signature, defines the semantics of the "eq", "ne",\n             "gt", "lt", "le" and "ge" operators on <code>xs:string</code> values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:compare(\'abc\', \'abc\')</code> returns <code>0</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:compare(\'Strasse\', \'Stra\u00dfe\')</code> returns <code>0</code>. <emph>(Assuming the default collation includes provisions that equate\n                      <quote>ss</quote> and the (German) character <quote>\u00df</quote>\n                      (<quote>sharp-s</quote>). Otherwise, the returned value depends on the\n                   semantics of the default collation.).</emph></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:compare(\'Strasse\', \'Stra\u00dfe\',\n                   \'http://example.com/deutsch\')</code> returns <code>0</code>. <emph>(Assuming the collation identified by the URI\n                      <code>http://example.com/deutsch</code> includes provisions that equate\n                      <quote>ss</quote> and the (German) character <quote>\u00df</quote>\n                      (<quote>sharp-s</quote>). Otherwise, the returned value depends on the\n                   semantics of that collation.).</emph></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:compare(\'Strassen\', \'Stra\u00dfe\')</code> returns <code>1</code>. <emph>(Assuming the default collation includes provisions that treat\n                   differences between <quote>ss</quote> and the (German) character <quote>\u00df</quote>\n                      (<quote>sharp-s</quote>) with less strength than the differences between the\n                   base characters, such as the final <quote>n</quote>. ).</emph></p></div>\n',summary:"<p>  Returns -1, 0, or 1, depending on whether  $comparand1  collates\n             before, equal to, or after  $comparand2  according to the rules of a selected\n             collation.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"comparand1",type:"xs:string",occurrence:"?",description:""},{name:"comparand2",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:3,name:"compare",qname:"fn:compare",signature:"($comparand1 as xs:string?, $comparand2 as xs:string?, $collation as xs:string) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns -1, 0, or 1, depending on whether <code>$comparand1</code> collates\n             before, equal to, or after <code>$comparand2</code> according to the rules of a selected\n             collation.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="compare" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="comparand1" type="xs:string?"/><arg name="comparand2" type="xs:string?"/></proto></example><example role="signature"><proto name="compare" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="comparand1" type="xs:string?"/><arg name="comparand2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns -1, 0, or 1, depending on whether the value of the <code>$comparand1</code> is\n             respectively less than, equal to, or greater than the value of <code>$comparand2</code>,\n             according to the rules of the collation that is used. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If either <code>$comparand1</code> or <code>$comparand2</code> is the empty sequence,\n             the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function, called with the first signature, defines the semantics of the "eq", "ne",\n             "gt", "lt", "le" and "ge" operators on <code>xs:string</code> values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:compare(\'abc\', \'abc\')</code> returns <code>0</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:compare(\'Strasse\', \'Stra\u00dfe\')</code> returns <code>0</code>. <emph>(Assuming the default collation includes provisions that equate\n                      <quote>ss</quote> and the (German) character <quote>\u00df</quote>\n                      (<quote>sharp-s</quote>). Otherwise, the returned value depends on the\n                   semantics of the default collation.).</emph></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:compare(\'Strasse\', \'Stra\u00dfe\',\n                   \'http://example.com/deutsch\')</code> returns <code>0</code>. <emph>(Assuming the collation identified by the URI\n                      <code>http://example.com/deutsch</code> includes provisions that equate\n                      <quote>ss</quote> and the (German) character <quote>\u00df</quote>\n                      (<quote>sharp-s</quote>). Otherwise, the returned value depends on the\n                   semantics of that collation.).</emph></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:compare(\'Strassen\', \'Stra\u00dfe\')</code> returns <code>1</code>. <emph>(Assuming the default collation includes provisions that treat\n                   differences between <quote>ss</quote> and the (German) character <quote>\u00df</quote>\n                      (<quote>sharp-s</quote>) with less strength than the differences between the\n                   base characters, such as the final <quote>n</quote>. ).</emph></p></div>\n',summary:"<p>  Returns -1, 0, or 1, depending on whether  $comparand1  collates\n             before, equal to, or after  $comparand2  according to the rules of a selected\n             collation.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"comparand1",type:"xs:string",occurrence:"?",description:""},{name:"comparand2",type:"xs:string",occurrence:"?",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"concat",qname:"fn:concat",signature:"($arg1 as xs:anyAtomicType?, $arg2 as xs:anyAtomicType?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the concatenation of the string values of the arguments.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">\n          The two-argument form of this function defines the semantics of the "||" operator.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="concat" return-type="xs:string" isOp="yes" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:anyAtomicType?"/><arg name="arg2" type="xs:anyAtomicType?"/><arg name="..." type="xs:anyAtomicType?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function accepts two or more <code>xs:anyAtomicType</code> arguments and casts each\n             one to <code>xs:string</code>. The function returns the <code>xs:string</code> that is\n             the concatenation of the values of its arguments after conversion. If any argument is\n             the empty sequence, that argument is treated as the zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E19">The <code>fn:concat</code> function is specified to allow two or\n             more arguments, which are concatenated together. This is the only function specified in\n             this document that allows a variable number of arguments. This capability is retained\n             for compatibility with <bibref ref="xpath"/>. </p></div>\n',summary:"<p>  Returns the concatenation of the string values of the arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:anyAtomicType",occurrence:"?",description:""},{name:"arg2",type:"xs:anyAtomicType",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"contains",qname:"fn:contains",signature:"($arg1 as xs:string?, $arg2 as xs:string?) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the string <code>$arg1</code> contains <code>$arg2</code> as a\n             substring, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="contains" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="contains" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n                <code>true</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> is the zero-length string, the function returns\n                <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:boolean</code> indicating whether or not the value of\n                <code>$arg1</code> contains (at the beginning, at the end, or anywhere within) at\n             least one sequence of collation units that provides a <term>minimal match</term> to the\n             collation units in the value of <code>$arg2</code>, according to the collation that is\n             used.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p><term>Minimal match</term> is defined in <bibref ref="Unicode-Collations"/>. </p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns true if the string  $arg1  contains  $arg2  as a\n             substring, taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:3,name:"contains",qname:"fn:contains",signature:"($arg1 as xs:string?, $arg2 as xs:string?, $collation as xs:string) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the string <code>$arg1</code> contains <code>$arg2</code> as a\n             substring, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="contains" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="contains" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n                <code>true</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> is the zero-length string, the function returns\n                <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:boolean</code> indicating whether or not the value of\n                <code>$arg1</code> contains (at the beginning, at the end, or anywhere within) at\n             least one sequence of collation units that provides a <term>minimal match</term> to the\n             collation units in the value of <code>$arg2</code>, according to the collation that is\n             used.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p><term>Minimal match</term> is defined in <bibref ref="Unicode-Collations"/>. </p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns true if the string  $arg1  contains  $arg2  as a\n             substring, taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"count",qname:"fn:count",signature:"($arg as item()*) as xs:integer external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the number of items in a sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="count" return-type="xs:integer" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the number of items in the value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns 0 if <code>$arg</code> is the empty sequence.</p></div>\n',summary:"<p>  Returns the number of items in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:0,name:"current-date",qname:"fn:current-date",signature:"() as xs:date external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the current date.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="current-date" return-type="xs:date" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns <code>xs:date(fn:current-dateTime())</code>. This is an <code>xs:date</code>\n             (with timezone) that is current at some time during the evaluation of a query or\n             transformation in which <code>fn:current-date</code> is executed.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic"/>. The precise instant during the query or\n             transformation represented by the value of <code>fn:current-date</code> is <termref def="implementation-dependent"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The returned date will always have an associated timezone, which will always be the same\n             as the implicit timezone in the dynamic context</p></div>\n',summary:"<p>  Returns the current date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:date",description:""},errors:[]},{isDocumented:!0,arity:0,name:"current-dateTime",qname:"fn:current-dateTime",signature:"() as xs:dateTimeStamp external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the current date and time (with timezone).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="current-dateTime" return-type="xs:dateTimeStamp" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the current dateTime (with timezone) from the dynamic context. (See <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.) This is an\n                <code>xs:dateTime</code> that is current at some time during the evaluation of a\n             query or transformation in which <code>fn:current-dateTime</code> is executed.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic"/>. The precise instant during the query or\n             transformation represented by the value of <code>fn:current-dateTime()</code> is\n                <termref def="implementation-dependent"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A">If the implementation supports data types from XSD 1.1 then the\n             returned value will be an instance of <code>xs:dateTimeStamp</code>. Otherwise, the only\n             guarantees are that it will be an instance of <code>xs:dateTime</code> and will have a\n             timezone component.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The returned <code>xs:dateTime</code> will always have an associated timezone, which\n             will always be the same as the implicit timezone in the dynamic context</p></div>\n',summary:"<p>  Returns the current date and time (with timezone).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:dateTimeStamp",description:""},errors:[]},{isDocumented:!0,arity:0,name:"current-time",qname:"fn:current-time",signature:"() as xs:time external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the current time.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="current-time" return-type="xs:time" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns <code>xs:time(fn:current-dateTime())</code>. This is an <code>xs:time</code>\n             (with timezone) that is current at some time during the evaluation of a query or\n             transformation in which <code>fn:current-time</code> is executed.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic"/>. The precise instant during the query or\n             transformation represented by the value of <code>fn:current-time()</code> is <termref def="implementation-dependent"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The returned time will always have an associated timezone, which will always be the same\n             as the implicit timezone in the dynamic context</p></div>\n',summary:"<p>  Returns the current time.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:time",description:""},errors:[]},{isDocumented:!0,arity:0,name:"data",qname:"fn:data",signature:"() as xs:anyAtomicType* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the result of atomizing a sequence, that is, replacing all nodes in the\n             sequence by their typed values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="data" return-type="xs:anyAtomicType*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="data" return-type="xs:anyAtomicType*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="F">If the argument is omitted, it defaults to the context item\n                (<code>.</code>). The behavior of the function if the argument is omitted is exactly\n             the same as if the context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> The result of <code>fn:data</code> is the sequence of atomic values produced by\n             applying the following rules to each item in <code>$arg</code>:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If the item is an atomic value, it is appended to the result sequence.</p></item><item><p> If the item is a node, the typed value of the node is appended to the result\n                   sequence. The typed value is a sequence of zero or more atomic values:\n                   specifically, the result of the <code>dm:typed-value</code> accessor as defined in\n                      <bibref ref="xpath-datamodel-30"/> (See <xspecref spec="DM30" ref="dm-typed-value"/>).</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">type</phrase> error is raised <errorref class="TY" code="0012" type="type"/> if an item in the\n             sequence <code>$arg</code> is a node that does not have a typed value. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">A <phrase diff="add" at="L">type</phrase> error is raised <errorref class="TY" code="0013" type="dynamic"/>\n             if an item in the sequence <code>$arg</code> is a function item. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="I">A <phrase diff="add" at="M">dynamic</phrase> error is raised\n             if <code>$arg</code> is omitted\n             and the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p></div>\n',summary:"<p>  Returns the result of atomizing a sequence, that is, replacing all nodes in the\n             sequence by their typed values.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyAtomicType*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"data",qname:"fn:data",signature:"($arg as item()*) as xs:anyAtomicType* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the result of atomizing a sequence, that is, replacing all nodes in the\n             sequence by their typed values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="data" return-type="xs:anyAtomicType*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="data" return-type="xs:anyAtomicType*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="F">If the argument is omitted, it defaults to the context item\n                (<code>.</code>). The behavior of the function if the argument is omitted is exactly\n             the same as if the context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> The result of <code>fn:data</code> is the sequence of atomic values produced by\n             applying the following rules to each item in <code>$arg</code>:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If the item is an atomic value, it is appended to the result sequence.</p></item><item><p> If the item is a node, the typed value of the node is appended to the result\n                   sequence. The typed value is a sequence of zero or more atomic values:\n                   specifically, the result of the <code>dm:typed-value</code> accessor as defined in\n                      <bibref ref="xpath-datamodel-30"/> (See <xspecref spec="DM30" ref="dm-typed-value"/>).</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">type</phrase> error is raised <errorref class="TY" code="0012" type="type"/> if an item in the\n             sequence <code>$arg</code> is a node that does not have a typed value. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">A <phrase diff="add" at="L">type</phrase> error is raised <errorref class="TY" code="0013" type="dynamic"/>\n             if an item in the sequence <code>$arg</code> is a function item. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="I">A <phrase diff="add" at="M">dynamic</phrase> error is raised\n             if <code>$arg</code> is omitted\n             and the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p></div>\n',summary:"<p>  Returns the result of atomizing a sequence, that is, replacing all nodes in the\n             sequence by their typed values.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"xs:anyAtomicType*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"dateTime",qname:"fn:dateTime",signature:"($arg1 as xs:date?, $arg2 as xs:time?) as xs:dateTime? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns an <code>xs:dateTime</code> value created by combining an\n                <code>xs:date</code> and an <code>xs:time</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="dateTime" return-type="xs:dateTime?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:date?"/><arg name="arg2" type="xs:time?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If either <code>$arg1</code> or <code>$arg2</code> is the empty sequence the function\n             returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:dateTime</code> whose date component is\n             equal to <code>$arg1</code> and whose time component is equal to <code>$arg2</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The timezone of the result is computed as follows:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If neither argument has a timezone, the result has no timezone.</p></item><item><p>If exactly one of the arguments has a timezone, or if both arguments have the same\n                   timezone, the result has this timezone.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0008"/> if the two arguments both have\n             timezones and the timezones are different. </p></div>\n',summary:"<p>  Returns an  xs:dateTime  value created by combining an\n                 xs:date  and an  xs:time .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:date",occurrence:"?",description:""},{name:"arg2",type:"xs:time",occurrence:"?",description:""}],returns:{type:"xs:dateTime?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"day-from-date",qname:"fn:day-from-date",signature:"($arg as xs:date?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the day component of an <code>xs:date</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="day-from-date" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:date?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> between 1 and 31, both\n             inclusive, representing the day component in the localized value of\n             <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:day-from-date(xs:date("1999-05-31-05:00"))</code> returns <code>31</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:day-from-date(xs:date("2000-01-01+05:00"))</code> returns <code>1</code>.</p></div>\n',summary:"<p>  Returns the day component of an  xs:date .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:date",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"days-from-duration",qname:"fn:days-from-duration",signature:"($arg as xs:duration?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the number of days in a duration.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="days-from-duration" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:duration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> representing the days\n             component in the value of <code>$arg</code>. The result is obtained by casting\n                <code>$arg</code> to an <code>xs:dayTimeDuration</code> (see <specref ref="casting-to-durations"/>) and then computing the days component as described in\n                <specref ref="canonical-dayTimeDuration"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a negative duration then the result will be negative..</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is an <code>xs:yearMonthDuration</code> the function returns 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:days-from-duration(xs:dayTimeDuration("P3DT10H"))</code> returns <code>3</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:days-from-duration(xs:dayTimeDuration("P3DT55H"))</code> returns <code>5</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:days-from-duration(xs:yearMonthDuration("P3Y5M"))</code> returns <code>0</code>.</p></div>\n',summary:"<p>  Returns the number of days in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:duration",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"deep-equal",qname:"fn:deep-equal",signature:"($parameter1 as item()*, $parameter2 as item()*) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> This function assesses whether two sequences are deep-equal to each other. To\n             be deep-equal, they must contain items that are pairwise deep-equal; and for two items\n             to be deep-equal, they must either be atomic values that compare equal, or nodes of the\n             same kind, with the same name, whose children are deep-equal.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="deep-equal" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="parameter1" type="item()*"/><arg name="parameter2" type="item()*"/></proto></example><example role="signature"><proto name="deep-equal" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="parameter1" type="item()*"/><arg name="parameter2" type="item()*"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$collation</code> argument identifies a collation which is used at all levels\n             of recursion when strings are compared (but not when names are compared), according to\n             the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the two sequences are both empty, the function returns <code>true</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the two sequences are of different lengths, the function returns\n             <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the two sequences are of the same length, the function returns <code>true</code> if\n             and only if every item in the sequence <code>$parameter1</code> is deep-equal to the\n             item at the same position in the sequence <code>$parameter2</code>. The rules for\n             deciding whether two items are deep-equal follow.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Call the two items <code>$i1</code> and <code>$i2</code> respectively.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$i1</code> and <code>$i2</code> are both atomic values, they are deep-equal if\n             and only if <code>($i1 eq $i2)</code> is <code>true</code>, or if both values are\n                <code>NaN</code>. If the <code>eq</code> operator is not defined for <code>$i1</code>\n             and <code>$i2</code>, the function returns <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If one of the pair <code>$i1</code> or <code>$i2</code> is an atomic value and the\n             other is not,\n             <!--<phrase diff="add" at="MAP">or if one is a node and the other is not, </phrase>-->\n             the function returns <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$i1</code> and <code>$i2</code> are both nodes, they are compared as described\n             below:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If the two nodes are of different kinds, the result is <code>false</code>.</p></item><item><p>If the two nodes are both document nodes then they are deep-equal if and only if\n                   the sequence <code>$i1/(*|text())</code> is deep-equal to the sequence\n                      <code>$i2/(*|text())</code>.</p></item><item><p> If the two nodes are both element nodes then they are deep-equal if and only if\n                   all of the following conditions are satisfied:</p><olist><item><p>The two nodes have the same name, that is <code>(node-name($i1) eq\n                            node-name($i2))</code>.</p></item><item><!-- bug 17252 --><p diff="chg" at="L">Either both nodes are both annotated as having simple content or both nodes are\n                         annotated as having complex content. For this purpose "simple content" means either a simple\n                      type or a complex type with simple content; "complex content" means a complex type whose variety\n                      is mixed, element-only, or empty.</p><note diff="add" at="L"><p>It is a consequence of this rule that validating a document\n                      <var>D</var> against a schema will usually (but not necessarily) result in a document that is not deep-equal\n                         to <var>D</var>. The exception is when the schema allows all elements to have mixed content.</p></note></item><item><p>The two nodes have the same number of attributes, and for every attribute\n                            <code>$a1</code> in <code>$i1/@*</code> there exists an attribute\n                            <code>$a2</code> in <code>$i2/@*</code> such that <code>$a1</code> and\n                            <code>$a2</code> are deep-equal.</p></item><item><p> One of the following conditions holds:</p><ulist><item><p>Both element nodes are annotated as having simple content\n                               <phrase diff="add" at="L">(as defined in 3(b) above)</phrase>, and\n                               the typed value of <code>$i1</code> is deep-equal to the typed value\n                               of <code>$i2</code>.</p></item><item><p>Both element nodes have a type annotation that is <phrase diff="chg" at="L">a complex type with\n                               variety element-only, and the sequence <code>$i1/*</code> is\n                               deep-equal to the sequence <code>$i2/*</code>.</phrase></p></item><item><p>Both element nodes have a type annotation that is <phrase diff="chg" at="L">a complex type with\n                               variety mixed</phrase>, and the sequence <code>$i1/(*|text())</code> is\n                               deep-equal to the sequence <code>$i2/(*|text())</code>.</p></item><item><p>Both element nodes have a type annotation that is <phrase diff="chg" at="L">a complex type with\n                               variety empty</phrase>.</p></item></ulist></item></olist></item><item><p>If the two nodes are both attribute nodes then they are deep-equal if and only if\n                   both the following conditions are satisfied:</p><olist><item><p>The two nodes have the same name, that is <code>(node-name($i1) eq\n                            node-name($i2))</code>.</p></item><item><p>The typed value of <code>$i1</code> is deep-equal to the typed value of\n                            <code>$i2</code>.</p></item></olist></item><item><p> If the two nodes are both processing instruction nodes<phrase diff="del" at="A-E42"> or namespace bindings</phrase>, then they are deep-equal if and\n                   only if both the following conditions are satisfied:</p><olist><item><p>The two nodes have the same name, that is <code>(node-name($i1) eq\n                            node-name($i2))</code>.</p></item><item><p>The string value of <code>$i1</code> is equal to the string value of\n                            <code>$i2</code>.</p></item></olist></item><item><p diff="add" at="A-E42"> If the two nodes are both namespace nodes, then they are deep-equal if and only\n                   if both the following conditions are satisfied:</p><olist><item><p diff="add" at="A-E42">The two nodes either have the same name or are both nameless, that is\n                            <code>fn:deep-equal(node-name($i1), node-name($i2))</code>.</p></item><item><p diff="add" at="A-E42">The string value of <code>$i1</code> is equal to the string value of\n                            <code>$i2</code> when compared using the Unicode codepoint collation.</p></item></olist></item><item><p>If the two nodes are both text nodes or comment nodes, then they are deep-equal if\n                   and only if their string-values are equal.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">A <phrase diff="add" at="L">type</phrase> error is raised <errorref class="TY" code="0015" type="type"/>\n             if either input sequence contains a function item.\n             <!--<phrase diff="add" at="MAP">that is not a map</phrase>,-->\n          </p></div>\n',summary:"<p>   This function assesses whether two sequences are deep-equal to each other.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"parameter1",type:"item()",occurrence:"*",description:""},{name:"parameter2",type:"item()",occurrence:"*",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:3,name:"deep-equal",qname:"fn:deep-equal",signature:"($parameter1 as item()*, $parameter2 as item()*, $collation as xs:string) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> This function assesses whether two sequences are deep-equal to each other. To\n             be deep-equal, they must contain items that are pairwise deep-equal; and for two items\n             to be deep-equal, they must either be atomic values that compare equal, or nodes of the\n             same kind, with the same name, whose children are deep-equal.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="deep-equal" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="parameter1" type="item()*"/><arg name="parameter2" type="item()*"/></proto></example><example role="signature"><proto name="deep-equal" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="parameter1" type="item()*"/><arg name="parameter2" type="item()*"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$collation</code> argument identifies a collation which is used at all levels\n             of recursion when strings are compared (but not when names are compared), according to\n             the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the two sequences are both empty, the function returns <code>true</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the two sequences are of different lengths, the function returns\n             <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the two sequences are of the same length, the function returns <code>true</code> if\n             and only if every item in the sequence <code>$parameter1</code> is deep-equal to the\n             item at the same position in the sequence <code>$parameter2</code>. The rules for\n             deciding whether two items are deep-equal follow.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Call the two items <code>$i1</code> and <code>$i2</code> respectively.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$i1</code> and <code>$i2</code> are both atomic values, they are deep-equal if\n             and only if <code>($i1 eq $i2)</code> is <code>true</code>, or if both values are\n                <code>NaN</code>. If the <code>eq</code> operator is not defined for <code>$i1</code>\n             and <code>$i2</code>, the function returns <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If one of the pair <code>$i1</code> or <code>$i2</code> is an atomic value and the\n             other is not,\n             <!--<phrase diff="add" at="MAP">or if one is a node and the other is not, </phrase>-->\n             the function returns <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$i1</code> and <code>$i2</code> are both nodes, they are compared as described\n             below:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If the two nodes are of different kinds, the result is <code>false</code>.</p></item><item><p>If the two nodes are both document nodes then they are deep-equal if and only if\n                   the sequence <code>$i1/(*|text())</code> is deep-equal to the sequence\n                      <code>$i2/(*|text())</code>.</p></item><item><p> If the two nodes are both element nodes then they are deep-equal if and only if\n                   all of the following conditions are satisfied:</p><olist><item><p>The two nodes have the same name, that is <code>(node-name($i1) eq\n                            node-name($i2))</code>.</p></item><item><!-- bug 17252 --><p diff="chg" at="L">Either both nodes are both annotated as having simple content or both nodes are\n                         annotated as having complex content. For this purpose "simple content" means either a simple\n                      type or a complex type with simple content; "complex content" means a complex type whose variety\n                      is mixed, element-only, or empty.</p><note diff="add" at="L"><p>It is a consequence of this rule that validating a document\n                      <var>D</var> against a schema will usually (but not necessarily) result in a document that is not deep-equal\n                         to <var>D</var>. The exception is when the schema allows all elements to have mixed content.</p></note></item><item><p>The two nodes have the same number of attributes, and for every attribute\n                            <code>$a1</code> in <code>$i1/@*</code> there exists an attribute\n                            <code>$a2</code> in <code>$i2/@*</code> such that <code>$a1</code> and\n                            <code>$a2</code> are deep-equal.</p></item><item><p> One of the following conditions holds:</p><ulist><item><p>Both element nodes are annotated as having simple content\n                               <phrase diff="add" at="L">(as defined in 3(b) above)</phrase>, and\n                               the typed value of <code>$i1</code> is deep-equal to the typed value\n                               of <code>$i2</code>.</p></item><item><p>Both element nodes have a type annotation that is <phrase diff="chg" at="L">a complex type with\n                               variety element-only, and the sequence <code>$i1/*</code> is\n                               deep-equal to the sequence <code>$i2/*</code>.</phrase></p></item><item><p>Both element nodes have a type annotation that is <phrase diff="chg" at="L">a complex type with\n                               variety mixed</phrase>, and the sequence <code>$i1/(*|text())</code> is\n                               deep-equal to the sequence <code>$i2/(*|text())</code>.</p></item><item><p>Both element nodes have a type annotation that is <phrase diff="chg" at="L">a complex type with\n                               variety empty</phrase>.</p></item></ulist></item></olist></item><item><p>If the two nodes are both attribute nodes then they are deep-equal if and only if\n                   both the following conditions are satisfied:</p><olist><item><p>The two nodes have the same name, that is <code>(node-name($i1) eq\n                            node-name($i2))</code>.</p></item><item><p>The typed value of <code>$i1</code> is deep-equal to the typed value of\n                            <code>$i2</code>.</p></item></olist></item><item><p> If the two nodes are both processing instruction nodes<phrase diff="del" at="A-E42"> or namespace bindings</phrase>, then they are deep-equal if and\n                   only if both the following conditions are satisfied:</p><olist><item><p>The two nodes have the same name, that is <code>(node-name($i1) eq\n                            node-name($i2))</code>.</p></item><item><p>The string value of <code>$i1</code> is equal to the string value of\n                            <code>$i2</code>.</p></item></olist></item><item><p diff="add" at="A-E42"> If the two nodes are both namespace nodes, then they are deep-equal if and only\n                   if both the following conditions are satisfied:</p><olist><item><p diff="add" at="A-E42">The two nodes either have the same name or are both nameless, that is\n                            <code>fn:deep-equal(node-name($i1), node-name($i2))</code>.</p></item><item><p diff="add" at="A-E42">The string value of <code>$i1</code> is equal to the string value of\n                            <code>$i2</code> when compared using the Unicode codepoint collation.</p></item></olist></item><item><p>If the two nodes are both text nodes or comment nodes, then they are deep-equal if\n                   and only if their string-values are equal.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">A <phrase diff="add" at="L">type</phrase> error is raised <errorref class="TY" code="0015" type="type"/>\n             if either input sequence contains a function item.\n             <!--<phrase diff="add" at="MAP">that is not a map</phrase>,-->\n          </p></div>\n',summary:"<p>   This function assesses whether two sequences are deep-equal to each other.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"parameter1",type:"item()",occurrence:"*",description:""},{name:"parameter2",type:"item()",occurrence:"*",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:0,name:"default-collation",qname:"fn:default-collation",signature:"() as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of the default collation property from the static context.\n          </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="default-collation" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of the default collation property from the static context. Components\n             of the static context are discussed in <xspecref spec="XP30" ref="id-xp-static-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The default collation property can never be absent. If it is not explicitly defined, a\n             system defined default can be invoked. If this is not provided, the Unicode codepoint\n             collation (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>) is\n             used. </p></div>\n',summary:"<p>  Returns the value of the default collation property from the static context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"distinct-values",qname:"fn:distinct-values",signature:"($arg as xs:anyAtomicType*) as xs:anyAtomicType* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the values that appear in a sequence, with duplicates eliminated.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="distinct-values" return-type="xs:anyAtomicType*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/></proto></example><example role="signature"><proto name="distinct-values" return-type="xs:anyAtomicType*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the sequence that results from removing from <code>$arg</code> all\n             but one of a set of values that are equal to one another. Values are compared using the\n                <code>eq</code> operator, subject to the caveats defined below.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Values of type <code>xs:untypedAtomic</code> are compared as if they were of type\n                <code>xs:string</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Values that cannot be compared, because the <code>eq</code> operator is not defined for\n             their types, are considered to be distinct.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>. This collation is used when string comparison is\n             required.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For <code>xs:float</code> and <code>xs:double</code> values, positive zero is equal to\n             negative zero and, although <code>NaN</code> does not equal itself, if <code>$arg</code>\n             contains multiple <code>NaN</code> values a single <code>NaN</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>xs:dateTime</code>, <code>xs:date</code> or <code>xs:time</code> values do not\n             have a timezone, they are considered to have the implicit timezone provided by the\n             dynamic context for the purpose of comparison. Note that <code>xs:dateTime</code>,\n                <code>xs:date</code> or <code>xs:time</code> values can compare equal even if their\n             timezones are different.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The order in which the sequence of values is returned is <termref def="implementation-dependent"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Which value of a set of values that compare equal is returned is <termref def="implementation-dependent"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">The static type of the result is a sequence of prime types as defined\n             in [Formal Semantics].</p><change xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E44">\n             <p>If the input sequence contains values of different numeric types that differ from\n                each other by small amounts, then the eq operator is not transitive, because of\n                rounding effects occurring during type promotion. In the situation where the input\n                contains three values <code>A</code>, <code>B</code>, and <code>C</code> such that\n                   <code>A eq B</code>, <code>B eq C</code>, but <code>A ne C</code>, then the number\n                of items in the result of the function (as well as the choice of which items are\n                returned) is <termref def="implementation-dependent"/>, subject only to the\n                constraints that (a) no two items in the result sequence compare equal to each other,\n                and (b) every input item that does not appear in the result sequence compares equal\n                to some item that does appear in the result sequence.</p>\n             <p>For example, this arises when computing:</p>\n             <eg xml:space="preserve">    distinct-values(\n             (xs:float(\'1.0\'),\n             xs:decimal(\'1.0000000000100000000001\',\n             xs:double( \'1.00000000001\'))</eg>\n             <p>because the values of type <code>xs:float</code> and <code>xs:double</code> both\n                compare equal to the value of type <code>xs:decimal</code> but not equal to each\n                other. </p>\n          </change><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p></div>\n',summary:"<p>  Returns the values that appear in a sequence, with duplicates eliminated.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"*",description:""}],returns:{type:"xs:anyAtomicType*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"distinct-values",qname:"fn:distinct-values",signature:"($arg as xs:anyAtomicType*, $collation as xs:string) as xs:anyAtomicType* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the values that appear in a sequence, with duplicates eliminated.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="distinct-values" return-type="xs:anyAtomicType*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/></proto></example><example role="signature"><proto name="distinct-values" return-type="xs:anyAtomicType*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the sequence that results from removing from <code>$arg</code> all\n             but one of a set of values that are equal to one another. Values are compared using the\n                <code>eq</code> operator, subject to the caveats defined below.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Values of type <code>xs:untypedAtomic</code> are compared as if they were of type\n                <code>xs:string</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Values that cannot be compared, because the <code>eq</code> operator is not defined for\n             their types, are considered to be distinct.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>. This collation is used when string comparison is\n             required.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For <code>xs:float</code> and <code>xs:double</code> values, positive zero is equal to\n             negative zero and, although <code>NaN</code> does not equal itself, if <code>$arg</code>\n             contains multiple <code>NaN</code> values a single <code>NaN</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>xs:dateTime</code>, <code>xs:date</code> or <code>xs:time</code> values do not\n             have a timezone, they are considered to have the implicit timezone provided by the\n             dynamic context for the purpose of comparison. Note that <code>xs:dateTime</code>,\n                <code>xs:date</code> or <code>xs:time</code> values can compare equal even if their\n             timezones are different.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The order in which the sequence of values is returned is <termref def="implementation-dependent"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Which value of a set of values that compare equal is returned is <termref def="implementation-dependent"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">The static type of the result is a sequence of prime types as defined\n             in [Formal Semantics].</p><change xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E44">\n             <p>If the input sequence contains values of different numeric types that differ from\n                each other by small amounts, then the eq operator is not transitive, because of\n                rounding effects occurring during type promotion. In the situation where the input\n                contains three values <code>A</code>, <code>B</code>, and <code>C</code> such that\n                   <code>A eq B</code>, <code>B eq C</code>, but <code>A ne C</code>, then the number\n                of items in the result of the function (as well as the choice of which items are\n                returned) is <termref def="implementation-dependent"/>, subject only to the\n                constraints that (a) no two items in the result sequence compare equal to each other,\n                and (b) every input item that does not appear in the result sequence compares equal\n                to some item that does appear in the result sequence.</p>\n             <p>For example, this arises when computing:</p>\n             <eg xml:space="preserve">    distinct-values(\n             (xs:float(\'1.0\'),\n             xs:decimal(\'1.0000000000100000000001\',\n             xs:double( \'1.00000000001\'))</eg>\n             <p>because the values of type <code>xs:float</code> and <code>xs:double</code> both\n                compare equal to the value of type <code>xs:decimal</code> but not equal to each\n                other. </p>\n          </change><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p></div>\n',summary:"<p>  Returns the values that appear in a sequence, with duplicates eliminated.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"*",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:anyAtomicType*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"doc-available",qname:"fn:doc-available",signature:"($uri as xs:string?) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E26">The function returns true if and only if the function\n             call <code>fn:doc($uri)</code> would return a document node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="doc-available" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="uri" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		available documents, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E26">If <code>$uri</code> is an empty sequence, this function returns\n                <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E26">If a call on <code>fn:doc($uri)</code> would return a document\n             node, this function returns <code>true</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E26">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0005"/> if\n                <code>$uri</code> is not a valid URI according to the rules applied by the\n             implementation of <code>fn:doc</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E26">Otherwise, this function returns <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If this function returns <code>true</code>, then calling <code>fn:doc($uri)</code>\n             within the same <termref def="execution-scope"/> must return a document node. However,\n             if nondeterministic processing has been selected for the <code>fn:doc</code> function,\n             this guarantee is lost.</p></div>\n',summary:"<p>  The function returns true if and only if the function\n             call  fn:doc($uri)  would return a document node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"doc",qname:"fn:doc",signature:"($uri as xs:string?) as document()? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E26">Retrieves a document using a URI supplied as an\n                <code>xs:string</code>, and returns the corresponding document node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="doc" return-type="document-node()?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="uri" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		available documents, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$uri</code> is the empty sequence, the result is an empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E26">If <code>$uri</code> is a relative URI reference, it is resolved\n             relative to the value of the <phrase diff="chg" at="L">Static Base URI property from the static context</phrase>. The resulting\n             absolute URI is promoted to an <code>xs:string</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E26">If the <term>Available documents</term> described in <xspecref spec="XP30" ref="eval_context"/> provides a mapping from this string to a document\n             node, the function returns that document node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E26">The URI may include a fragment identifier.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">By default, this function is <termref def="deterministic">deterministic</termref>. Two calls on this function\n             return the same document node if the same URI Reference (after resolution to an absolute\n             URI Reference) is supplied to both calls. Thus, the following expression (if it does not\n             raise an error) will always be true:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">doc("foo.xml") is doc("foo.xml")</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">However, for performance reasons, implementations may provide a user option to evaluate\n             the function without a guarantee of determinism. The manner in which any such option is\n             provided is implementation-defined. If the user has not selected such an option, a call\n             of the function must either return a deterministic result or must raise a <phrase diff="add" at="L">dynamic</phrase> error\n                <errorref class="DC" code="0003"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p>If <code>$uri</code> is read from a source document, it is generally appropriate to\n                resolve it relative to the base URI property of the relevant node in the source\n                document. This can be achieved by calling the <code>fn:resolve-uri</code> function,\n                and passing the resulting absolute URI as an argument to the <code>fn:doc</code>\n                function.</p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If two calls to this function supply different absolute URI References as arguments, the\n             same document node may be returned if the implementation can determine that the two\n             arguments refer to the same resource.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> By defining the semantics of this function in terms of a string-to-document-node\n             mapping in the dynamic context, the specification is acknowledging that the results of\n             this function are outside the purview of the language specification itself, and depend\n             entirely on the run-time environment in which the expression is evaluated. This run-time\n             environment includes not only an unpredictable collection of resources ("the web"), but\n             configurable machinery for locating resources and turning their contents into document\n             nodes within the XPath data model. Both the set of resources that are reachable, and the\n             mechanisms by which those resources are parsed and validated, are <termref def="implementation-dependent"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> One possible processing model for this function is as follows. The resource identified\n             by the URI Reference is retrieved. If the resource cannot be retrieved, a <phrase diff="add" at="L">dynamic</phrase> error is\n             raised <errorref class="DC" code="0002"/>. The data resulting from the retrieval action\n             is then parsed as an XML document and a tree is constructed in accordance with the\n                <bibref ref="xpath-datamodel-30"/>. If the top-level media type is known and is\n             "text", the content is parsed in the same way as if the media type were text/xml;\n             otherwise, it is parsed in the same way as if the media type were application/xml. If\n             the contents cannot be parsed successfully, a <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/>. Otherwise, the result of the function is the document node at the root\n             of the resulting tree. This tree is then optionally validated against a schema.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Various aspects of this processing are <termref def="implementation-defined"/>.\n             Implementations may provide external configuration options that allow any aspect of the\n             processing to be controlled by the user. In particular:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>The set of URI schemes that the implementation recognizes is\n                   implementation-defined. Implementations may allow the mapping of URIs to resources\n                   to be configured by the user, using mechanisms such as catalogs or user-written\n                   URI handlers.</p></item><item><p>The handling of non-XML media types is implementation-defined. Implementations may\n                   allow instances of the data model to be constructed from non-XML resources, under\n                   user control.</p></item><item><p>It is <termref def="implementation-defined"/> whether DTD validation and/or schema\n                   validation is applied to the source document.</p></item><item><p>Implementations may provide user-defined error handling options that allow\n                   processing to continue following an error in retrieving a resource, or in parsing\n                   and validating its content. When errors have been handled in this way, the\n                   function may return either an empty sequence, or a fallback document provided by\n                   the error handler.</p></item><item><p>Implementations may provide user options that relax the requirement for the\n                   function to return deterministic results.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E26">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="DC" code="0005"/> if <code>$uri</code> is not a valid URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if the\n                <term>available documents</term> provides no mapping for the absolutized URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if the resource cannot be\n             retrieved or cannot be parsed successfully as XML.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0003"/> if the implementation is not able\n             to guarantee that the result of the function will be deterministic, and the user has not\n             indicated that an unstable result is acceptable.</p></div>\n',summary:"<p>  Retrieves a document using a URI supplied as an\n                 xs:string , and returns the corresponding document node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:"?",description:""}],returns:{type:"document()?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"document-uri",qname:"fn:document-uri",signature:"() as xs:anyURI? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the URI of a resource where a document can be found, if available.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="document-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="document-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="F">If the argument is omitted, it defaults to the context item\n                (<code>.</code>). The behavior of the function if the argument is omitted is exactly\n             the same as if the context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is not a document node, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the value of the <code>document-uri</code> accessor\n             applied to <code>$arg</code>, as defined in <bibref ref="xpath-datamodel-30"/> (See\n                <xspecref spec="DM30" ref="DocumentNodeAccessors"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the URI of a resource where a document can be found, if available.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyURI?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"document-uri",qname:"fn:document-uri",signature:"($arg as node()?) as xs:anyURI? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the URI of a resource where a document can be found, if available.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="document-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="document-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="F">If the argument is omitted, it defaults to the context item\n                (<code>.</code>). The behavior of the function if the argument is omitted is exactly\n             the same as if the context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is not a document node, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the value of the <code>document-uri</code> accessor\n             applied to <code>$arg</code>, as defined in <bibref ref="xpath-datamodel-30"/> (See\n                <xspecref spec="DM30" ref="DocumentNodeAccessors"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the URI of a resource where a document can be found, if available.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:"?",description:""}],returns:{type:"xs:anyURI?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"element-with-id",qname:"fn:element-with-id",signature:"($arg as xs:string*) as element(*)* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E31"> Returns the sequence of element nodes that have an\n                <code>ID</code> value matching the value of one or more of the <code>IDREF</code>\n             values supplied in <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="element-with-id" return-type="element()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/></proto></example><example role="signature"><proto name="element-with-id" return-type="element()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/><arg name="node" type="node()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><change xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E31">\n             <note><p>The effect of this function is identical to <function>fn:id</function> in respect\n                   of elements that have an attribute with the <code>is-id</code> property. However,\n                   it behaves differently in respect of element nodes with the <code>is-id</code>\n                   property. Whereas the <code>fn:id</code>, for legacy reasons, returns the element\n                   that has the <code>is-id</code> property, this parent returns the element\n                   identified by the ID, which is the parent of the element having the\n                      <code>is-id</code> property.</p></note>\n             <p>The function returns a sequence, in document order with duplicates eliminated,\n                containing every element node <code>E</code> that satisfies all the following\n                conditions:</p>\n             <olist><item><p>\n                      <code>E</code> is in the target document. The target document is the document\n                      containing <code>$node</code>, or the document containing the context item\n                         (<code>.</code>) if the second argument is omitted. The behavior of the\n                      function if <code>$node</code> is omitted is exactly the same as if the context\n                      item had been passed as <code>$node</code>.</p></item><item><p><code>E</code> has an <code>ID</code> value equal to one of the candidate\n                         <code>IDREF</code> values, where:</p><ulist><item><p> An element has an <code>ID</code> value equal to <code>V</code> if\n                            either or both of the following conditions are true:</p><ulist><item><p>The element has an child element node whose <code>is-id</code>\n                                  property (See <xspecref spec="DM30" ref="dm-is-id"/>.) is true and\n                                  whose typed value is equal to <code>V</code> under the rules of the\n                                     <code>eq</code> operator using the Unicode code point collation\n                                     (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item><item><p>The element has an attribute node whose <code>is-id</code> property\n                                  (See <xspecref spec="DM30" ref="dm-is-id"/>.) is true and whose\n                                  typed value is equal to <code>V</code> under the rules of the\n                                     <code>eq</code> operator using the Unicode code point collation\n                                     (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item></ulist></item><item><p>Each <code>xs:string</code> in <code>$arg</code> is parsed as if it were\n                            of type <code>IDREFS</code>, that is, each <code>xs:string</code> in\n                               <code>$arg</code> is treated as a whitespace-separated sequence of\n                            tokens, each acting as an <code>IDREF</code>. These tokens are then\n                            included in the list of candidate <code>IDREF</code>s. If any of the\n                            tokens is not a lexically valid <code>IDREF</code> (that is, if it is not\n                            lexically an <code>xs:NCName</code>), it is ignored. Formally, the\n                            candidate <code>IDREF</code> values are the strings in the sequence given\n                            by the expression:</p><eg xml:space="preserve">for $s in $arg return\n    fn:tokenize(fn:normalize-space($s), \' \')[. castable as xs:IDREF]</eg></item></ulist></item><item><p> If several elements have the same <code>ID</code> value, then <code>E</code>\n                      is the one that is first in document order.</p></item></olist>\n          </change><change xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E31">\n             <p>A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0001" type="dynamic"/> if\n                   <code>$node</code>, or the context item if the second argument is omitted, is a\n                   node in a tree whose root is not a document node.</p>\n             <p>The following errors may be raised when <code>$node</code> is omitted:</p>\n             <ul><li><p>If the context\n                   item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                   <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                   node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul>\n          </change></div>\n',summary:"<p>   Returns the sequence of element nodes that have an\n                 ID  value matching the value of one or more of the  IDREF \n             values supplied in  $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"*",description:""}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"element-with-id",qname:"fn:element-with-id",signature:"($arg as xs:string*, $node as node()) as element(*)* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E31"> Returns the sequence of element nodes that have an\n                <code>ID</code> value matching the value of one or more of the <code>IDREF</code>\n             values supplied in <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="element-with-id" return-type="element()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/></proto></example><example role="signature"><proto name="element-with-id" return-type="element()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/><arg name="node" type="node()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><change xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E31">\n             <note><p>The effect of this function is identical to <function>fn:id</function> in respect\n                   of elements that have an attribute with the <code>is-id</code> property. However,\n                   it behaves differently in respect of element nodes with the <code>is-id</code>\n                   property. Whereas the <code>fn:id</code>, for legacy reasons, returns the element\n                   that has the <code>is-id</code> property, this parent returns the element\n                   identified by the ID, which is the parent of the element having the\n                      <code>is-id</code> property.</p></note>\n             <p>The function returns a sequence, in document order with duplicates eliminated,\n                containing every element node <code>E</code> that satisfies all the following\n                conditions:</p>\n             <olist><item><p>\n                      <code>E</code> is in the target document. The target document is the document\n                      containing <code>$node</code>, or the document containing the context item\n                         (<code>.</code>) if the second argument is omitted. The behavior of the\n                      function if <code>$node</code> is omitted is exactly the same as if the context\n                      item had been passed as <code>$node</code>.</p></item><item><p><code>E</code> has an <code>ID</code> value equal to one of the candidate\n                         <code>IDREF</code> values, where:</p><ulist><item><p> An element has an <code>ID</code> value equal to <code>V</code> if\n                            either or both of the following conditions are true:</p><ulist><item><p>The element has an child element node whose <code>is-id</code>\n                                  property (See <xspecref spec="DM30" ref="dm-is-id"/>.) is true and\n                                  whose typed value is equal to <code>V</code> under the rules of the\n                                     <code>eq</code> operator using the Unicode code point collation\n                                     (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item><item><p>The element has an attribute node whose <code>is-id</code> property\n                                  (See <xspecref spec="DM30" ref="dm-is-id"/>.) is true and whose\n                                  typed value is equal to <code>V</code> under the rules of the\n                                     <code>eq</code> operator using the Unicode code point collation\n                                     (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item></ulist></item><item><p>Each <code>xs:string</code> in <code>$arg</code> is parsed as if it were\n                            of type <code>IDREFS</code>, that is, each <code>xs:string</code> in\n                               <code>$arg</code> is treated as a whitespace-separated sequence of\n                            tokens, each acting as an <code>IDREF</code>. These tokens are then\n                            included in the list of candidate <code>IDREF</code>s. If any of the\n                            tokens is not a lexically valid <code>IDREF</code> (that is, if it is not\n                            lexically an <code>xs:NCName</code>), it is ignored. Formally, the\n                            candidate <code>IDREF</code> values are the strings in the sequence given\n                            by the expression:</p><eg xml:space="preserve">for $s in $arg return\n    fn:tokenize(fn:normalize-space($s), \' \')[. castable as xs:IDREF]</eg></item></ulist></item><item><p> If several elements have the same <code>ID</code> value, then <code>E</code>\n                      is the one that is first in document order.</p></item></olist>\n          </change><change xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="A-E31">\n             <p>A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0001" type="dynamic"/> if\n                   <code>$node</code>, or the context item if the second argument is omitted, is a\n                   node in a tree whose root is not a document node.</p>\n             <p>The following errors may be raised when <code>$node</code> is omitted:</p>\n             <ul><li><p>If the context\n                   item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                   <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                   node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul>\n          </change></div>\n',summary:"<p>   Returns the sequence of element nodes that have an\n                 ID  value matching the value of one or more of the  IDREF \n             values supplied in  $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"*",description:""},{name:"node",type:"node()",occurrence:null,description:""}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"empty",qname:"fn:empty",signature:"($arg as item()*) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the argument is the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="empty" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the function returns\n                <code>true</code>; otherwise, the function returns <code>false</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:empty((1,2,3)[10])</code> returns <code>true()</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:empty(fn:remove(("hello", "world"), 1))</code> returns <code>false()</code>.</p></div>\n',summary:"<p>  Returns true if the argument is the empty sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"encode-for-uri",qname:"fn:encode-for-uri",signature:"($uri-part as xs:string?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Encodes reserved characters in a string that is intended to be used in the path\n             segment of a URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="encode-for-uri" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="uri-part" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$uri-part</code> is the empty sequence, the function returns the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function applies the URI escaping rules defined in section 2 of <bibref ref="rfc3986"/> to the <code>xs:string</code> supplied as <code>$uri-part</code>. The\n             effect of the function is to escape reserved characters. Each such character in the\n             string is replaced with its percent-encoded form as described in <bibref ref="rfc3986"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Since <bibref ref="rfc3986"/> recommends that, for consistency, URI producers and\n             normalizers should use uppercase hexadecimal digits for all percent-encodings, this\n             function must always generate hexadecimal values using the upper-case letters A-F.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">All characters are escaped except those identified as "unreserved" by <bibref ref="rfc3986"/>, that is the upper- and lower-case letters A-Z, the digits 0-9,\n             HYPHEN-MINUS ("-"), LOW LINE ("_"), FULL STOP ".", and TILDE "~".</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function escapes URI delimiters and therefore cannot be used indiscriminately to\n             encode "invalid" characters in a path segment.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is invertible but not idempotent. This is because a string containing a\n             percent character will be modified by applying the function: for example\n                <code>100%</code> becomes <code>100%25</code>, while <code>100%25</code> becomes\n                <code>100%2525</code>.</p></div>\n',summary:"<p>  Encodes reserved characters in a string that is intended to be used in the path\n             segment of a URI.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri-part",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"ends-with",qname:"fn:ends-with",signature:"($arg1 as xs:string?, $arg2 as xs:string?) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the string <code>$arg1</code> contains <code>$arg2</code> as a\n             trailing substring, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="ends-with" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="ends-with" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n                <code>true</code>. If the value of <code>$arg1</code> is the zero-length string and\n             the value of <code>$arg2</code> is not the zero-length string, then the function returns\n                <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:boolean</code> indicating whether or not the value of\n                <code>$arg1</code> starts with a sequence of collation units that provides a\n                <term>match</term> to the collation units of <code>$arg2</code> according to the\n             collation that is used.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p>\n                <term>Match</term> is defined in <bibref ref="Unicode-Collations"/>. </p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns true if the string  $arg1  contains  $arg2  as a\n             trailing substring, taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:3,name:"ends-with",qname:"fn:ends-with",signature:"($arg1 as xs:string?, $arg2 as xs:string?, $collation as xs:string) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the string <code>$arg1</code> contains <code>$arg2</code> as a\n             trailing substring, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="ends-with" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="ends-with" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n                <code>true</code>. If the value of <code>$arg1</code> is the zero-length string and\n             the value of <code>$arg2</code> is not the zero-length string, then the function returns\n                <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:boolean</code> indicating whether or not the value of\n                <code>$arg1</code> starts with a sequence of collation units that provides a\n                <term>match</term> to the collation units of <code>$arg2</code> according to the\n             collation that is used.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p>\n                <term>Match</term> is defined in <bibref ref="Unicode-Collations"/>. </p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns true if the string  $arg1  contains  $arg2  as a\n             trailing substring, taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"environment-variable",qname:"fn:environment-variable",signature:"($arg as xs:string) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of a system environment variable, if it exists.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="environment-variable" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="name" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		environment variables.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The set of available <xtermref spec="XP30" ref="dt-environment-variables">environment variables</xtermref>\n             is a set of (name, value) pairs forming part\n             of the dynamic context, in which the name is unique within the set of pairs. The name\n             and value are arbitrary strings.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the <code>$name</code> argument matches the name of one of these pairs, the function\n             returns the corresponding value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If there is no environment variable with a matching name, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used for matching names is <termref def="implementation-defined"/>, but\n             must be the same as the collation used to ensure that the names of all environment\n             variables are unique.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="I">The function is <termref def="dt-deterministic">deterministic</termref>,\n             which means that if it is called several times\n          within the same <termref def="dt-execution-scope">execution scope</termref>, with the same arguments,\n             it must return the same result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">On many platforms, the term "environment variable" has a natural meaning in terms of\n             facilities provided by the operating system. This interpretation of the concept does not\n             exclude other interpretations, such as a mapping to a set of configuration parameters in\n             a database system.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Environment variable names are usually case sensitive. Names are usually of the form\n                <code>(letter|_) (letter|_|digit)*</code>, but this varies by platform.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">On some platforms, there may sometimes be multiple environment variables with the same name;\n             in this case, it is implementation-dependent as to which is returned; see for example\n                <bibref ref="POSIX.1-2008"/> (Chapter 8, Environment Variables).\n             Implementations <rfc2119>may</rfc2119> use prefixes or other naming conventions\n             to disambiguate the names.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The requirement to ensure that the function is deterministic means in practice that\n          the implementation must make a snapshot of the environment variables at some time\n          during execution, and return values obtained from this snapshot, rather than using\n          live values that are subject to change at any time.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Operating system environment variables may be associated with a particular process,\n          while queries and stylesheets may execute across multiple processes (or multiple machines).\n          In such circumstances implementations <rfc2119>may</rfc2119> choose to provide access\n          to the environment variables associated with the process in which the query or stylesheet\n          processing was initiated.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Security advice: Queries from untrusted sources should not be permitted unrestricted\n             access to environment variables. For example, the name of the account under which the\n             query is running may be useful information to a would-be intruder. An implementation may\n             therefore choose to restrict access to the environment, or may provide a facility to\n             make <code>fn:environment-variable</code> always return the empty sequence.</p></div>\n',summary:"<p>  Returns the value of a system environment variable, if it exists.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"environment-variable",qname:"fn:environment-variable",signature:"($name as xs:string) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of a system environment variable, if it exists.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="environment-variable" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="name" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		environment variables.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The set of available <xtermref spec="XP30" ref="dt-environment-variables">environment variables</xtermref>\n             is a set of (name, value) pairs forming part\n             of the dynamic context, in which the name is unique within the set of pairs. The name\n             and value are arbitrary strings.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the <code>$name</code> argument matches the name of one of these pairs, the function\n             returns the corresponding value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If there is no environment variable with a matching name, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used for matching names is <termref def="implementation-defined"/>, but\n             must be the same as the collation used to ensure that the names of all environment\n             variables are unique.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="I">The function is <termref def="dt-deterministic">deterministic</termref>,\n             which means that if it is called several times\n          within the same <termref def="dt-execution-scope">execution scope</termref>, with the same arguments,\n             it must return the same result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">On many platforms, the term "environment variable" has a natural meaning in terms of\n             facilities provided by the operating system. This interpretation of the concept does not\n             exclude other interpretations, such as a mapping to a set of configuration parameters in\n             a database system.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Environment variable names are usually case sensitive. Names are usually of the form\n                <code>(letter|_) (letter|_|digit)*</code>, but this varies by platform.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">On some platforms, there may sometimes be multiple environment variables with the same name;\n             in this case, it is implementation-dependent as to which is returned; see for example\n                <bibref ref="POSIX.1-2008"/> (Chapter 8, Environment Variables).\n             Implementations <rfc2119>may</rfc2119> use prefixes or other naming conventions\n             to disambiguate the names.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The requirement to ensure that the function is deterministic means in practice that\n          the implementation must make a snapshot of the environment variables at some time\n          during execution, and return values obtained from this snapshot, rather than using\n          live values that are subject to change at any time.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Operating system environment variables may be associated with a particular process,\n          while queries and stylesheets may execute across multiple processes (or multiple machines).\n          In such circumstances implementations <rfc2119>may</rfc2119> choose to provide access\n          to the environment variables associated with the process in which the query or stylesheet\n          processing was initiated.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Security advice: Queries from untrusted sources should not be permitted unrestricted\n             access to environment variables. For example, the name of the account under which the\n             query is running may be useful information to a would-be intruder. An implementation may\n             therefore choose to restrict access to the environment, or may provide a facility to\n             make <code>fn:environment-variable</code> always return the empty sequence.</p></div>\n',summary:"<p>  Returns the value of a system environment variable, if it exists.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"error",qname:"fn:error",signature:"() as none external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Calling the <code>fn:error</code> function raises an application-defined\n             error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName"/></proto></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName?"/><arg name="description" type="xs:string"/></proto></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName?"/><arg name="description" type="xs:string"/><arg name="error-object" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function never returns a value. Instead it always raises an error. The effect of\n             the error is identical to the effect of dynamic errors raised implicitly, for example\n             when an incorrect argument is supplied to a function.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The parameters to the <code>fn:error</code> function supply information that is\n             associated with the error condition and that is made available to a caller that asks for\n             information about the error. The error may be caught either by the host language (using\n             a try/catch construct in XSLT or XQuery, for example), or by the calling application or\n             external processing environment. The way in which error information is returned to the\n             external processing environment is <termref def="implementation-dependent"/></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>fn:error</code> is called with no arguments, then its behavior is the same as\n             the function call: </p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:error(fn:QName(\'http://www.w3.org/2005/xqt-errors\', \'err:FOER0000\')) </eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$code</code> is the empty sequence then the effective value is the\n                <code>xs:QName</code> constructed by:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:QName(\'http://www.w3.org/2005/xqt-errors\', \'err:FOER0000\')</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">There are three pieces of information that may be associated with an error:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>The <code>$code</code> is an error code that distinguishes this error from others.\n                   It is an <code>xs:QName</code>; the namespace URI conventionally identifies the\n                   component, subsystem, or authority responsible for defining the meaning of the\n                   error code, while the local part identifies the specific error condition. The\n                   namespace URI <code>http://www.w3.org/2005/xqt-errors</code> is used for errors\n                   defined in this specification; other namespace URIs may be used for errors defined\n                   by the application.</p><p>If the external processing environment expects the error code to be returned as a\n                   URI or a string rather than as an <code>xs:QName</code>, then an error code with\n                   namespace URI <code>NS</code> and local part <code>LP</code> will be returned in\n                   the form <code>NS#LP</code>. The namespace URI part of the error code should\n                   therefore not include a fragment identifier.</p></item><item><p>The <code>$description</code> is a natural-language description of the error\n                   condition.</p></item><item><p>The <code>$error-object</code> is an arbitrary value used to convey additional\n                   information about the error, and may be used in any way the application\n                   chooses.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function always raises a <phrase diff="add" at="L">dynamic</phrase> error. By default, it raises <errorref class="ER" code="0000"/></p></div>\n',summary:"<p>  Calling the  fn:error  function raises an application-defined\n             error.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"none",description:""},errors:[]},{isDocumented:!0,arity:1,name:"error",qname:"fn:error",signature:"($code as xs:QName) as none external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Calling the <code>fn:error</code> function raises an application-defined\n             error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName"/></proto></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName?"/><arg name="description" type="xs:string"/></proto></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName?"/><arg name="description" type="xs:string"/><arg name="error-object" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function never returns a value. Instead it always raises an error. The effect of\n             the error is identical to the effect of dynamic errors raised implicitly, for example\n             when an incorrect argument is supplied to a function.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The parameters to the <code>fn:error</code> function supply information that is\n             associated with the error condition and that is made available to a caller that asks for\n             information about the error. The error may be caught either by the host language (using\n             a try/catch construct in XSLT or XQuery, for example), or by the calling application or\n             external processing environment. The way in which error information is returned to the\n             external processing environment is <termref def="implementation-dependent"/></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>fn:error</code> is called with no arguments, then its behavior is the same as\n             the function call: </p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:error(fn:QName(\'http://www.w3.org/2005/xqt-errors\', \'err:FOER0000\')) </eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$code</code> is the empty sequence then the effective value is the\n                <code>xs:QName</code> constructed by:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:QName(\'http://www.w3.org/2005/xqt-errors\', \'err:FOER0000\')</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">There are three pieces of information that may be associated with an error:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>The <code>$code</code> is an error code that distinguishes this error from others.\n                   It is an <code>xs:QName</code>; the namespace URI conventionally identifies the\n                   component, subsystem, or authority responsible for defining the meaning of the\n                   error code, while the local part identifies the specific error condition. The\n                   namespace URI <code>http://www.w3.org/2005/xqt-errors</code> is used for errors\n                   defined in this specification; other namespace URIs may be used for errors defined\n                   by the application.</p><p>If the external processing environment expects the error code to be returned as a\n                   URI or a string rather than as an <code>xs:QName</code>, then an error code with\n                   namespace URI <code>NS</code> and local part <code>LP</code> will be returned in\n                   the form <code>NS#LP</code>. The namespace URI part of the error code should\n                   therefore not include a fragment identifier.</p></item><item><p>The <code>$description</code> is a natural-language description of the error\n                   condition.</p></item><item><p>The <code>$error-object</code> is an arbitrary value used to convey additional\n                   information about the error, and may be used in any way the application\n                   chooses.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function always raises a <phrase diff="add" at="L">dynamic</phrase> error. By default, it raises <errorref class="ER" code="0000"/></p></div>\n',summary:"<p>  Calling the  fn:error  function raises an application-defined\n             error.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"code",type:"xs:QName",occurrence:null,description:""}],returns:{type:"none",description:""},errors:[]},{isDocumented:!0,arity:2,name:"error",qname:"fn:error",signature:"($code as xs:QName?, $description as xs:string) as none external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Calling the <code>fn:error</code> function raises an application-defined\n             error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName"/></proto></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName?"/><arg name="description" type="xs:string"/></proto></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName?"/><arg name="description" type="xs:string"/><arg name="error-object" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function never returns a value. Instead it always raises an error. The effect of\n             the error is identical to the effect of dynamic errors raised implicitly, for example\n             when an incorrect argument is supplied to a function.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The parameters to the <code>fn:error</code> function supply information that is\n             associated with the error condition and that is made available to a caller that asks for\n             information about the error. The error may be caught either by the host language (using\n             a try/catch construct in XSLT or XQuery, for example), or by the calling application or\n             external processing environment. The way in which error information is returned to the\n             external processing environment is <termref def="implementation-dependent"/></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>fn:error</code> is called with no arguments, then its behavior is the same as\n             the function call: </p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:error(fn:QName(\'http://www.w3.org/2005/xqt-errors\', \'err:FOER0000\')) </eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$code</code> is the empty sequence then the effective value is the\n                <code>xs:QName</code> constructed by:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:QName(\'http://www.w3.org/2005/xqt-errors\', \'err:FOER0000\')</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">There are three pieces of information that may be associated with an error:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>The <code>$code</code> is an error code that distinguishes this error from others.\n                   It is an <code>xs:QName</code>; the namespace URI conventionally identifies the\n                   component, subsystem, or authority responsible for defining the meaning of the\n                   error code, while the local part identifies the specific error condition. The\n                   namespace URI <code>http://www.w3.org/2005/xqt-errors</code> is used for errors\n                   defined in this specification; other namespace URIs may be used for errors defined\n                   by the application.</p><p>If the external processing environment expects the error code to be returned as a\n                   URI or a string rather than as an <code>xs:QName</code>, then an error code with\n                   namespace URI <code>NS</code> and local part <code>LP</code> will be returned in\n                   the form <code>NS#LP</code>. The namespace URI part of the error code should\n                   therefore not include a fragment identifier.</p></item><item><p>The <code>$description</code> is a natural-language description of the error\n                   condition.</p></item><item><p>The <code>$error-object</code> is an arbitrary value used to convey additional\n                   information about the error, and may be used in any way the application\n                   chooses.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function always raises a <phrase diff="add" at="L">dynamic</phrase> error. By default, it raises <errorref class="ER" code="0000"/></p></div>\n',summary:"<p>  Calling the  fn:error  function raises an application-defined\n             error.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"code",type:"xs:QName",occurrence:"?",description:""},{name:"description",type:"xs:string",occurrence:null,description:""}],returns:{type:"none",description:""},errors:[]},{isDocumented:!0,arity:3,name:"error",qname:"fn:error",signature:"($code as xs:QName?, $description as xs:string, $error-object as item()*) as none external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Calling the <code>fn:error</code> function raises an application-defined\n             error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName"/></proto></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName?"/><arg name="description" type="xs:string"/></proto></example><example role="signature"><proto name="error" return-type="none" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName?"/><arg name="description" type="xs:string"/><arg name="error-object" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function never returns a value. Instead it always raises an error. The effect of\n             the error is identical to the effect of dynamic errors raised implicitly, for example\n             when an incorrect argument is supplied to a function.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The parameters to the <code>fn:error</code> function supply information that is\n             associated with the error condition and that is made available to a caller that asks for\n             information about the error. The error may be caught either by the host language (using\n             a try/catch construct in XSLT or XQuery, for example), or by the calling application or\n             external processing environment. The way in which error information is returned to the\n             external processing environment is <termref def="implementation-dependent"/></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>fn:error</code> is called with no arguments, then its behavior is the same as\n             the function call: </p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:error(fn:QName(\'http://www.w3.org/2005/xqt-errors\', \'err:FOER0000\')) </eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$code</code> is the empty sequence then the effective value is the\n                <code>xs:QName</code> constructed by:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:QName(\'http://www.w3.org/2005/xqt-errors\', \'err:FOER0000\')</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">There are three pieces of information that may be associated with an error:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>The <code>$code</code> is an error code that distinguishes this error from others.\n                   It is an <code>xs:QName</code>; the namespace URI conventionally identifies the\n                   component, subsystem, or authority responsible for defining the meaning of the\n                   error code, while the local part identifies the specific error condition. The\n                   namespace URI <code>http://www.w3.org/2005/xqt-errors</code> is used for errors\n                   defined in this specification; other namespace URIs may be used for errors defined\n                   by the application.</p><p>If the external processing environment expects the error code to be returned as a\n                   URI or a string rather than as an <code>xs:QName</code>, then an error code with\n                   namespace URI <code>NS</code> and local part <code>LP</code> will be returned in\n                   the form <code>NS#LP</code>. The namespace URI part of the error code should\n                   therefore not include a fragment identifier.</p></item><item><p>The <code>$description</code> is a natural-language description of the error\n                   condition.</p></item><item><p>The <code>$error-object</code> is an arbitrary value used to convey additional\n                   information about the error, and may be used in any way the application\n                   chooses.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function always raises a <phrase diff="add" at="L">dynamic</phrase> error. By default, it raises <errorref class="ER" code="0000"/></p></div>\n',summary:"<p>  Calling the  fn:error  function raises an application-defined\n             error.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"code",type:"xs:QName",occurrence:"?",description:""},{name:"description",type:"xs:string",occurrence:null,description:""},{name:"error-object",type:"item()",occurrence:"*",description:""}],returns:{type:"none",description:""},errors:[]},{isDocumented:!0,arity:1,name:"escape-html-uri",qname:"fn:escape-html-uri",signature:"($uri as xs:string?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Escapes a URI in the same way that HTML user agents handle attribute values\n             expected to contain URIs.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="escape-html-uri" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="uri" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$uri</code> is the empty sequence, the function returns the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function escapes all <termref def="character">characters</termref> except\n             printable characters of the US-ASCII coded character set, specifically the <termref def="codepoint">codepoints</termref> between 32 and 126 (decimal) inclusive. Each\n             character in <code>$uri</code> to be escaped is replaced by an escape sequence, which is\n             formed by encoding the character as a sequence of octets in UTF-8, and then representing\n             each of these octets in the form %HH, where HH is the hexadecimal representation of the\n             octet. This function must always generate hexadecimal values using the upper-case\n             letters A-F.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The behavior of this function corresponds to the recommended handling of non-ASCII\n             characters in URI attribute values as described in <bibref ref="HTML40"/> Appendix\n             B.2.1.</p></div>\n',summary:"<p>  Escapes a URI in the same way that HTML user agents handle attribute values\n             expected to contain URIs.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"exactly-one",qname:"fn:exactly-one",signature:"($arg as item()*) as item() external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns <code>$arg</code> if it contains exactly one item. Otherwise, raises an\n             error. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="exactly-one" return-type="item()" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Except in error cases, the function returns <code>$arg</code> unchanged.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0005"/> if <code>$arg</code> is an empty\n             sequence or a sequence containing more than one item.</p></div>\n',summary:"<p>  Returns  $arg  if it contains exactly one item.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"item()",description:""},errors:[]},{isDocumented:!0,arity:1,name:"exists",qname:"fn:exists",signature:"($arg as item()*) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the argument is a non-empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="exists" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is a non-empty sequence, the function returns\n                <code>true</code>; otherwise, the function returns <code>false</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:exists(fn:remove(("hello"), 1))</code> returns <code>false()</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:exists(fn:remove(("hello", "world"), 1))</code> returns <code>true()</code>.</p></div>\n',summary:"<p>  Returns true if the argument is a non-empty sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:0,name:"false",qname:"fn:false",signature:"() as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the <code>xs:boolean</code> value <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="false" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result is equivalent to <code>xs:boolean("0")</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:false()</code> returns <code>xs:boolean(0)</code>.</p></div>\n',summary:"<p>  Returns the  xs:boolean  value  false .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"filter",qname:"fn:filter",signature:"($seq as item()*, $f as function (item()) as xs:boolean) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns those items from the sequence <var>$seq</var> for which the supplied\n             function <var>$f</var> returns true.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="filter" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seq" type="item()*"/><arg name="f" type="function(item()) as xs:boolean"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of the function is equivalent to the following implementation in XQuery:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n declare function fn:filter(\n         $seq as item()*,\n         $f as function(item()) as xs:boolean)\n         as item()* {\n   if (fn:empty($seq))\n   then ()\n   else ( fn:head($seq)[$f(.) eq fn:true()],\n          fn:filter(fn:tail($seq), $f)\n        )\n };</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">or its equivalent in XSLT:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n &lt;xsl:function name="fn:filter" as="item()*"&gt;\n   &lt;xsl:param name="seq" as="item()*"/&gt;\n   &lt;xsl:param name="f" as="function(item()) as xs:boolean"/&gt;\n   &lt;xsl:if test="fn:exists($seq)"&gt;\n     &lt;xsl:sequence select="fn:head($seq)[$f(.) eq fn:true()], fn:filter(fn:tail($seq), $f)"/&gt;\n   &lt;/xsl:if&gt;\n &lt;/xsl:function&gt;\n          </eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">As a consequence of the function signature and the function calling\n             rules, a type error occurs if the supplied function <var>$f</var> returns anything other\n             than a single <code>xs:boolean</code> item; there is no conversion to an effective\n             boolean value.</p></div>\n',summary:"<p>  Returns those items from the sequence  $seq  for which the supplied\n             function  $f  returns true.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"item()",occurrence:"*",description:""},{name:"f",type:"function (item()) as xs:boolean",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"floor",qname:"fn:floor",signature:"($arg as numeric?) as numeric? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Rounds <code>$arg</code> downwards to a whole number.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="floor" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">General rules: see <specref ref="numeric-value-functions"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the largest (closest to positive infinity) number with no\n             fractional part that is not greater than the value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the type of <code>$arg</code> is one of the four numeric types <code>xs:float</code>,\n                <code>xs:double</code>, <code>xs:decimal</code> or <code>xs:integer</code> the type\n             of the result is the same as the type of <code>$arg</code>. If the type of\n                <code>$arg</code> is a type derived from one of the numeric types, the result is an\n             instance of the base numeric type.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For <code>xs:float</code> and <code>xs:double</code> arguments, if the argument is\n             positive zero, then positive zero is returned. If the argument is negative zero, then\n             negative zero is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:floor(10.5)</code> returns <code>10</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:floor(-10.5)</code> returns <code>-11</code>.</p></div>\n',summary:"<p>  Rounds  $arg  downwards to a whole number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"numeric",occurrence:"?",description:""}],returns:{type:"numeric?",description:""},errors:[]},{isDocumented:!0,arity:3,name:"fold-left",qname:"fn:fold-left",signature:"($seq as item()*, $zero as item()*, $f as function (item()*, item()) as item()*) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Processes the supplied sequence from left to right, applying the supplied\n             function repeatedly to each item in turn, together with an accumulated result value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="fold-left" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seq" type="item()*"/><arg name="zero" type="item()*"/><arg name="f" type="function(item()*, item()) as item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of the function is equivalent to the following implementation in XQuery:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n declare function fn:fold-left(\n         $seq as item()*\n         $zero as item()*,\n         $f as function(item()*, item()) as item()*)\n         as item()* {\n   if (fn:empty($seq))\n   then $zero\n   else fn:fold-left(fn:tail($seq), $f($zero, fn:head($seq)), $f)\n };</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">or its equivalent in XSLT:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n &lt;xsl:function name="fn:fold-left" as="item()*"&gt;\n   &lt;xsl:param name="seq" as="item()*"/&gt;\n   &lt;xsl:param name="zero" as="item()*"/&gt;\n   &lt;xsl:param name="f" as="function(item()*, item()) as item()*"/&gt;\n   &lt;xsl:choose&gt;\n     &lt;xsl:when test="fn:empty($seq)"&gt;\n       &lt;xsl:sequence select="$zero"/&gt;\n     &lt;/xsl:when&gt;\n     &lt;xsl:otherwise&gt;\n       &lt;xsl:sequence select="fn:fold-left(fn:tail($seq), $f($zero, fn:head($seq)), $f)"/&gt;\n     &lt;/xsl:otherwise&gt;\n   &lt;/xsl:choose&gt;\n &lt;/xsl:function&gt;\n          </eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">As a consequence of the function signature and the function calling\n             rules, a type error occurs if the supplied function <var>$f</var> cannot be applied to\n             two arguments, where the first argument is either the value of <var>$zero</var> or the\n             result of a previous application of <var>$f</var>, and the second is <var>$seq</var> or\n             any trailing subsequence of <var>$seq</var>.</p></div>\n',summary:"<p>  Processes the supplied sequence from left to right, applying the supplied\n             function repeatedly to each item in turn, together with an accumulated result value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"item()",occurrence:"*",description:""},{name:"zero",type:"item()",occurrence:"*",description:""},{name:"f",type:"function (item()*, item()) as item()*",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"fold-right",qname:"fn:fold-right",signature:"($seq as item()*, $zero as item()*, $f as function (item()*, item()) as item()*) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Processes the supplied sequence from right to left, applying the supplied\n             function repeatedly to each item in turn, together with an accumulated result value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="fold-right" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seq" type="item()*"/><arg name="zero" type="item()*"/><arg name="f" type="function(item()*, item()) as item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of the function is equivalent to the following implementation in XQuery:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n declare function fn:fold-right(\n         $seq as item()*,\n         $zero as item()*,\n         $f as function(item(), item()*) as item()*)\n         as item()* {\n   if (fn:empty($seq))\n   then $zero\n   else $f(fn:head($seq), fn:fold-right(fn:tail($seq), $zero, $f))\n };</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">or its equivalent in XSLT:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n &lt;xsl:function name="fn:fold-right" as="item()*"&gt;\n   &lt;xsl:param name="seq" as="item()*"/&gt;\n   &lt;xsl:param name="zero" as="item()*"/&gt;\n   &lt;xsl:param name="f" as="function(item(), item()*) as item()*"/&gt;\n   &lt;xsl:choose&gt;\n     &lt;xsl:when test="fn:empty($seq)"&gt;\n       &lt;xsl:sequence select="$zero"/&gt;\n     &lt;/xsl:when&gt;\n     &lt;xsl:otherwise&gt;\n       &lt;xsl:sequence select="$f(fn:head($seq), fn:fold-right(fn:tail($seq), $zero, $f))"/&gt;\n     &lt;/xsl:otherwise&gt;\n   &lt;/xsl:choose&gt;\n &lt;/xsl:function&gt;\n          </eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">As a consequence of the function signature and the function calling\n             rules, a type error occurs if the supplied function <var>$f</var> cannot be applied to\n             two arguments, where the first argument is any item in the sequence <var>$seq</var>, and\n             the second is either the value of <var>$zero</var> or the result of a previous\n             application of <var>$f</var>.</p></div>\n',summary:"<p>  Processes the supplied sequence from right to left, applying the supplied\n             function repeatedly to each item in turn, together with an accumulated result value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"item()",occurrence:"*",description:""},{name:"zero",type:"item()",occurrence:"*",description:""},{name:"f",type:"function (item()*, item()) as item()*",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"for-each-pair",qname:"fn:for-each-pair",signature:"($seq1 as item()*, $seq2 as item()*, $f as function (item(), item()) as item()*) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Applies the function item <var>$f</var> to successive pairs of items taken one\n             from <var>$seq1</var> and one from <var>$seq2</var>, returning the concatenation of the\n             resulting sequences in order.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="for-each-pair" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seq1" type="item()*"/><arg name="seq2" type="item()*"/><arg name="f" type="function(item(), item()) as item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of the function is equivalent to the following implementation in XQuery:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n declare function fn:for-each-pair($seq1, $seq2, $f)\n {\n    if(fn:exists($seq1) and fn:exists($seq2))\n    then (\n      $f(fn:head($seq1), fn:head($seq2)),\n      fn:for-each-pair(fn:tail($seq1), fn:tail($seq2), $f)\n    )\n    else ()\n };</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">or its equivalent in XSLT:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n &lt;xsl:function name="fn:for-each-pair"&gt;\n   &lt;xsl:param name="seq1/&gt;\n   &lt;xsl:param name="seq2/&gt;\n   &lt;xsl:param name="f"/&gt;\n   &lt;xsl:if test="fn:exists($seq1) and fn:exists($seq2)"&gt;\n     &lt;xsl:sequence select="$f(fn:head($seq1), fn:head($seq2))"/&gt;\n     &lt;xsl:sequence select="fn:for-each-pair(fn:tail($seq1), fn:tail($seq2), $f)"/&gt;\n   &lt;/xsl:if&gt;\n &lt;/xsl:function&gt;\n          </eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:for-each-pair(("a", "b", "c"), ("x", "y", "z"), concat#2)</code> returns <code>("ax", "by", "cz")</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:for-each-pair(1 to 5, 1 to 5, function($a, $b){10*$a + $b}</code> returns <code>(11, 22, 33, 44, 55)</code>.</p></div>\n',summary:"<p>  Applies the function item  $f  to successive pairs of items taken one\n             from  $seq1  and one from  $seq2 , returning the concatenation of the\n             resulting sequences in order.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq1",type:"item()",occurrence:"*",description:""},{name:"seq2",type:"item()",occurrence:"*",description:""},{name:"f",type:"function (item(), item()) as item()*",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"for-each",qname:"fn:for-each",signature:"($seq as item()*, $f as function (item()) as item()*) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Applies the function item <var>$f</var> to every item from the sequence\n                <var>$seq</var> in turn, returning the concatenation of the resulting sequences in\n             order.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="for-each" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seq" type="item()*"/><arg name="f" type="function(item()) as item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of the function is equivalent to the following implementation in XQuery:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n declare function fn:for-each($seq, $f) {\n   if (fn:empty($seq))\n   then ()\n   else ($f(fn:head($seq)), fn:for-each(fn:tail($seq), $f))\n };</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">or its equivalent in XSLT:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n &lt;xsl:function name="fn:for-each"&gt;\n   &lt;xsl:param name="seq"/&gt;\n   &lt;xsl:param name="f"/&gt;\n   &lt;xsl:if test="fn:exists($seq)"&gt;\n     &lt;xsl:sequence select="$f(fn:head($seq)), fn:for-each(fn:tail($seq), $f)"/&gt;\n   &lt;/xsl:if&gt;\n &lt;/xsl:function&gt;\n          </eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function call <code>fn:for-each($SEQ, $F)</code> is equivalent to the expression\n                <code>for $i in $SEQ return $F($i)</code><phrase diff="add" at="G">, assuming that\n                ordering mode is <code>ordered</code>.</phrase></p></div>\n',summary:"<p>  Applies the function item  $f  to every item from the sequence\n                 $seq  in turn, returning the concatenation of the resulting sequences in\n             order.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"item()",occurrence:"*",description:""},{name:"f",type:"function (item()) as item()*",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"format-date",qname:"fn:format-date",signature:"($value as xs:date?, $picture as xs:string) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string containing an <code>xs:date</code> value formatted for display.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-date" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-date" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?"/><arg name="calendar" type="xs:string?"/><arg name="place" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		default calendar, and default language, and default place, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The five-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone, and namespaces.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See <specref ref="rules-for-datetime-formatting"/>.</p></div>\n',summary:"<p>  Returns a string containing an  xs:date  value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:date",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:5,name:"format-date",qname:"fn:format-date",signature:"($value as xs:date?, $picture as xs:string, $language as xs:string?, $calendar as xs:string?, $place as xs:string?) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string containing an <code>xs:date</code> value formatted for display.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-date" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-date" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?"/><arg name="calendar" type="xs:string?"/><arg name="place" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		default calendar, and default language, and default place, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The five-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone, and namespaces.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See <specref ref="rules-for-datetime-formatting"/>.</p></div>\n',summary:"<p>  Returns a string containing an  xs:date  value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:date",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""},{name:"language",type:"xs:string",occurrence:"?",description:""},{name:"calendar",type:"xs:string",occurrence:"?",description:""},{name:"place",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"format-dateTime",qname:"fn:format-dateTime",signature:"($value as xs:dateTime?, $picture as xs:string) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string containing an <code>xs:dateTime</code> value formatted for display.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-dateTime" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:dateTime?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-dateTime" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:dateTime?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?"/><arg name="calendar" type="xs:string?"/><arg name="place" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		default calendar, and default language, and default place, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The five-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone, and namespaces.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See <specref ref="rules-for-datetime-formatting"/>.</p></div>\n',summary:"<p>  Returns a string containing an  xs:dateTime  value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:dateTime",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:5,name:"format-dateTime",qname:"fn:format-dateTime",signature:"($value as xs:dateTime?, $picture as xs:string, $language as xs:string?, $calendar as xs:string?, $place as xs:string?) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string containing an <code>xs:dateTime</code> value formatted for display.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-dateTime" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:dateTime?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-dateTime" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:dateTime?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?"/><arg name="calendar" type="xs:string?"/><arg name="place" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		default calendar, and default language, and default place, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The five-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone, and namespaces.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See <specref ref="rules-for-datetime-formatting"/>.</p></div>\n',summary:"<p>  Returns a string containing an  xs:dateTime  value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:dateTime",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""},{name:"language",type:"xs:string",occurrence:"?",description:""},{name:"calendar",type:"xs:string",occurrence:"?",description:""},{name:"place",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"format-integer",qname:"fn:format-integer",signature:"($value as xs:integer?, $picture as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Formats an integer according to a given picture string, using the conventions\n             of a given natural language if specified.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-integer" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:integer?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-integer" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:integer?"/><arg name="picture" type="xs:string"/><arg name="lang" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		default language.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$value</code> is an empty sequence, the function returns a zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In all other cases, the <code>$picture</code> argument describes the format in which\n                <code>$value</code> is output.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The rules that follow describe how non-negative numbers are output. If the value of\n                <code>$value</code> is negative, the rules below are applied to the absolute value of\n                <code>$value</code>, and a minus sign is prepended to the result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="L">The value of <code>$picture</code> consists of a primary format token,\n             optionally followed\n             by a format modifier. The primary format token is always present and <rfc2119>must not</rfc2119>\n             be zero-length. If the string contains one or more semicolons then everything that\n             precedes the last semicolon is taken as the primary format token and everything\n             that follows is taken as the format modifier; if the string contains no\n             semicolon then the entire picture is taken as the primary format token, and the\n             format modifier is taken to be absent (which is equivalent to supplying a\n             zero-length string).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The primary format token is classified as one of the following:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>A <var>decimal-digit-pattern</var> made up of <var>optional-digit-signs</var>,\n                      <var>mandatory-digit-signs</var>, and <var>grouping-separator-signs</var>.</p><ulist><item><p>The <var>optional-digit-sign</var> is the character "#".</p></item><item><p>A <var>mandatory-digit-sign</var> is a <termref def="character">character</termref> in Unicode category Nd. All\n                            <var>mandatory-digit-signs</var> within the format token <rfc2119>must</rfc2119> be from the\n                         same digit family, where a digit family is a sequence of ten consecutive\n                         characters in Unicode category Nd, having digit values 0 through 9. Within\n                         the format token, these digits are interchangeable: a three-digit number may\n                         thus be indicated equivalently by <code>000</code>, <code>001</code>, or\n                            <code>999</code>.</p></item><item><p>a <var>grouping-separator-sign</var> is a non-alphanumeric character, that\n                         is a <termref def="character">character</termref> whose Unicode category is\n                         other than Nd, Nl, No, Lu, Ll, Lt, Lm or Lo.</p></item></ulist><p diff="chg" at="L">If the primary format token contains at least one Unicode digit\n                   then it is taken as a decimal digit pattern, and in this case it <rfc2119>must</rfc2119>\n                   match the regular expression <code>^((\\p{Nd}|#|[^\\p{N}\\p{L}])+?)$</code>. If it contains\n                   a digit but does not match this pattern, a <phrase diff="add" at="L">dynamic</phrase> error\n                   is raised <errorref class="DF" code="1310"/>.</p><note><p diff="add" at="L">If a semicolon is to be used as a grouping separator, then the primary\n                format token as a whole must be followed by another semicolon, to ensure that\n                the grouping separator is not mistaken as a separator between the primary format\n                token and the format modifier.</p></note><p>There <rfc2119>must</rfc2119> be at least one <var>mandatory-digit-sign</var>. There may be zero or\n                   more <var>optional-digit-signs</var>, and (if present) these <rfc2119>must</rfc2119> precede all\n                      <var>mandatory-digit-signs</var>. There may be zero or more\n                      <var>grouping-separator-signs</var>. A <var>grouping-separator-sign</var> <rfc2119>must\n                   not</rfc2119> appear at the start or end of the <var>decimal-digit-pattern</var>, nor\n                   adjacent to another <var>grouping-separator-sign</var>.</p><p>The corresponding output format is a decimal number, using this digit family, with\n                   at least as many digits as there are <var>mandatory-digit-signs</var> in the\n                   format token. Thus, a format token <code>1</code> generates the sequence <code>0 1\n                      2 ... 10 11 12 ...</code>, and a format token <code>01</code> (or equivalently,\n                      <code>00</code> or <code>99</code>) generates the sequence <code>00 01 02 ...\n                      09 10 11 12 ... 99 100 101</code>. A format token of <code>&amp;#x661;</code>\n                   (Arabic-Indic digit one) generates the sequence <code>\u0661</code> then <code>\u0662</code>\n                   then <code>\u0663</code> ...</p><p>The <var>grouping-separator-signs</var> are handled as follows. The position of\n                   grouping separators within the format token, counting backwards from the last\n                   digit, indicates the position of grouping separators to appear within the\n                   formatted number, and the character used as the <var>grouping-separator-sign</var>\n                   within the format token indicates the character to be used as the corresponding\n                   grouping separator in the formatted number. If <var>grouping-separator-signs</var>\n                   appear at regular intervals within the format token, that is if the same grouping\n                   separator appears at positions forming a sequence <var>N</var>, 2<var>N</var>,\n                      3<var>N</var>, ... for some integer value <var>N</var> (including the case\n                   where there is only one number in the list), then the sequence is extrapolated to\n                   the left, so grouping separators will be used in the formatted number at every\n                   multiple of <var>N</var>. For example, if the format token is <code>0\'000</code>\n                   then the number one million will be formatted as <code>1\'000\'000</code>, while the\n                   number fifteen will be formatted as <code>0\'015</code>.</p><p>The only purpose of <var>optional-digit-signs</var> is to mark the position of\n                      <var>grouping-separator-signs</var>. For example, if the format token is\n                      <code>#\'##0</code> then the number one million will be formatted as\n                      <code>1\'000\'000</code>, while the number fifteen will be formatted as\n                      <code>15</code>. A grouping separator is included in the formatted number only\n                   if there is a digit to its left, which will only be the case if either (a) the\n                   number is large enough to require that digit, or (b) the number of\n                      <var>mandatory-digit-signs</var> in the format token requires insignificant\n                   leading zeros to be present.</p><note><p>Numbers will never be truncated. Given the <var>decimal-digit-pattern</var>\n                      <code>01</code>, the number three hundred will be output as <code>300</code>,\n                      despite the absence of any <var>optional-digit-sign</var>.</p></note></item><item><p>The format token <code>A</code>, which generates the sequence <code>A B C ... Z AA AB\n                      AC...</code>.</p></item><item><p>The format token <code>a</code>, which generates the sequence <code>a b c ... z aa ab\n                      ac...</code>.</p></item><item><p>The format token <code>i</code>, which generates the sequence <code>i ii iii iv v vi vii\n                      viii ix x ...</code>.</p></item><item><p>The format token <code>I</code>, which generates the sequence <code>I II III IV V VI VII\n                      VIII IX X ...</code>.</p></item><item><p>The format token <code>w</code>, which generates numbers written as lower-case words, for\n                   example in English, <code>one two three four ...</code>\n                </p></item><item><p>The format token <code>W</code>, which generates numbers written as upper-case words, for\n                   example in English, <code>ONE TWO THREE FOUR ...</code>\n                </p></item><item><p>The format token <code>Ww</code>, which generates numbers written as title-case words, for\n                   example in English, <code>One Two Three Four ...</code>\n                </p></item><item><p>Any other format token, which indicates a numbering sequence in which that token\n                   represents the number 1 (one) (but see the note below).\n                   <!-- Where possible (given the constraint that format tokens\n 						must be alphanumeric, and that they must be distinct) the format token\n 						used to represent a numbering sequence should be the same as the representation\n 						of the number 1 (one) in that sequence.-->\n                   It is <termref def="implementation-defined">implementation-defined</termref> which\n                   numbering sequences, additional to those listed above, are supported. If an\n                   implementation does not support a numbering sequence represented by the given\n                   token, it <rfc2119>must</rfc2119> use a format token of <code>1</code>.</p><note><p>In some traditional numbering sequences additional signs are added to denote\n                      that the letters should be interpreted as numbers; these are not included in\n                      the format token. An example (see also the example below) is classical Greek\n                      where a <emph>dexia keraia</emph> (x0374, \u0374) and sometimes an <emph>aristeri keraia</emph>\n                      (x0375, \u0375) is added.</p></note></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For all format tokens other than the first kind above (one that consists of decimal\n             digits), there <rfc2119>may</rfc2119> be <termref def="implementation-defined">implementation-defined</termref> lower and upper bounds on the range of numbers that\n             can be formatted using this format token; indeed, for some numbering sequences there may\n             be intrinsic limits. For example, the format token <code>&amp;#x2460;</code> (circled\n             digit one, \u2460) has a range <phrase diff="chg" at="M">imposed by the Unicode character repertoire \u2014 1 to 20 in\n             Unicode versions prior to 4.0, increased in subsequent versions</phrase>. For\n             the numbering sequences described above any upper bound imposed by the implementation\n                <rfc2119>must not</rfc2119> be less than 1000 (one thousand) and any lower bound must\n             not be greater than 1. Numbers that fall outside this range <rfc2119>must</rfc2119> be\n             formatted using the format token <code>1</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The above expansions of numbering sequences for format tokens such as <code>a</code> and\n                <code>i</code> are indicative but not prescriptive. There are various conventions in\n             use for how alphabetic sequences continue when the alphabet is exhausted, and differing\n             conventions for how roman numerals are written (for example, <code>IV</code> versus\n                <code>IIII</code> as the representation of the number 4). Sometimes alphabetic\n             sequences are used that omit letters such as <code>i</code> and <code>o</code>. This\n             specification does not prescribe the detail of any sequence other than those sequences\n             consisting entirely of decimal digits.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Many numbering sequences are language-sensitive. This applies especially to the sequence\n             selected by the tokens <code>w</code>, <code>W</code> and <code>Ww</code>. It also\n             applies to other sequences, for example different languages using the Cyrillic alphabet\n             use different sequences of characters, each starting with the letter #x410 (Cyrillic\n             capital letter A). In such cases, the <code>$lang</code> argument specifies which\n             language\'s conventions are to be used. <phrase diff="chg" at="L">If the argument\n             is specified, the value <rfc2119>should</rfc2119> be either an empty sequence\n             or a value that would be valid for the <code>xml:lang</code> attribute (see <bibref ref="REC-xml"/>).\n             Note that this permits the identification of sublanguages based on country codes (from ISO 3166-1)\n             as well as identification of dialects and regions within a country.</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The set of languages\n             for which numbering is supported is <termref def="implementation-defined"/>.\n             If the <code>$lang</code> argument is absent,\n             or is set to an empty sequence, or is invalid, or is not a language supported by the\n             implementation, then the number is formatted using <phrase diff="chg" at="K">the\n             default language from the dynamic context</phrase>.\n             </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The format modifier <phrase diff="chg" at="L"><rfc2119>must</rfc2119>\n             be a string that matches the regular expression <code diff="chg" at="M">^([co](\\(.+\\))?)?[at]?$</code>. </phrase>\n             That is, if it is present it must consist of one <phrase diff="add" at="G">or more</phrase> of\n             the following, in <phrase diff="del" at="K">any</phrase> order:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p diff="chg" at="G">either <code>c</code> or <code>o</code>, optionally followed by\n                   a sequence of characters enclosed between parentheses, to indicate cardinal or\n                   ordinal numbering respectively, the default being cardinal numbering</p></item><item><p diff="chg" at="G">either <code>a</code> or <code>t</code>, to indicate alphabetic\n                   or traditional numbering respectively, the default being <termref def="implementation-defined">implementation-defined</termref>.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the <code>o</code> modifier is present, this indicates a request to output ordinal\n             numbers rather than cardinal numbers. For example, in English, when used with the format\n             token <code>1</code>, this outputs the sequence <code>1st 2nd 3rd 4th ...</code>, and\n             when used with the format token <code>w</code> outputs the sequence <code>first second\n             third fourth ...</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">The string of characters between the parentheses, if present, is used to\n          select between other possible variations of cardinal or ordinal numbering sequences.\n          The interpretation of this string is <termref def="implemementation-defined">implementation-defined</termref>. No error occurs\n          if the implementation does not define any interpretation for the defined string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For example, in some languages, ordinal numbers vary depending on the grammatical context:\n             they may have different genders and may decline with the noun that they qualify.\n             In such cases the string appearing in parentheses after the letter <code>o</code> may be\n             used to indicate the variation of the ordinal number required. The way in which the\n             variation is indicated will depend on the conventions of the language. For inflected\n             languages that vary the ending of the word, the <rfc2119>recommended</rfc2119> approach is to indicate the\n             required ending, preceded by a hyphen: for example in German, appropriate values are\n                <code>o(-e)</code>, <code>o(-er)</code>, <code>o(-es)</code>, <code>o(-en)</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">It is <termref def="implementation-defined">implementation-defined</termref> what\n             combinations of values of the format token, the language, and the cardinal/ordinal\n             modifier are supported. If ordinal numbering is not supported for the combination of the\n             format token, the language, and the string appearing in parentheses, the request is\n             ignored and cardinal numbers are generated instead.</p><example xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><head>Ordinal Numbering in Italian</head><p>The specification <code>"1;o(-\u00ba)"</code> with <code>$lang</code> equal to\n                   <code>it</code>, if supported, should produce the sequence:</p><eg xml:space="preserve">1\u00ba 2\u00ba 3\u00ba 4\u00ba ...</eg><p>The specification <code>"Ww;o"</code> with <code>$lang</code> equal to\n                   <code>it</code>, if supported, should produce the sequence:</p><eg xml:space="preserve">Primo Secondo Terzo Quarto Quinto ...</eg></example><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <phrase diff="chg" at="G">use of the <code>a</code> or <code>t</code>\n                modifier</phrase> disambiguates between numbering sequences that use letters. In many\n             languages there are two commonly used numbering sequences that use letters. One\n             numbering sequence assigns numeric values to letters in alphabetic sequence, and the\n             other assigns numeric values to each letter in some other manner traditional in that\n             language. In English, these would correspond to the numbering sequences specified by the\n             format tokens <code>a</code> and <code>i</code>. In some languages, the first member of\n             each sequence is the same, and so the format token alone would be ambiguous. <phrase diff="chg" at="G">In the absence of the <code>a</code> or <code>t</code> modifier,\n                the default is <termref def="implementation-defined">implementation-defined</termref></phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DF" code="1310"/> if the format token is invalid,\n             that is, if it violates any mandatory rules (indicated by an emphasized <rfc2119>must</rfc2119>\n             or <rfc2119>required</rfc2119> keyword in the above rules). For example, the error is raised if\n             the primary format token contains a digit but does not match the required regular expression.</p></div>\n',summary:"<p>  Formats an integer according to a given picture string, using the conventions\n             of a given natural language if specified.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:integer",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"format-integer",qname:"fn:format-integer",signature:"($value as xs:integer?, $picture as xs:string, $language as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Formats an integer according to a given picture string, using the conventions\n             of a given natural language if specified.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-integer" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:integer?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-integer" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:integer?"/><arg name="picture" type="xs:string"/><arg name="lang" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		default language.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$value</code> is an empty sequence, the function returns a zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In all other cases, the <code>$picture</code> argument describes the format in which\n                <code>$value</code> is output.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The rules that follow describe how non-negative numbers are output. If the value of\n                <code>$value</code> is negative, the rules below are applied to the absolute value of\n                <code>$value</code>, and a minus sign is prepended to the result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="L">The value of <code>$picture</code> consists of a primary format token,\n             optionally followed\n             by a format modifier. The primary format token is always present and <rfc2119>must not</rfc2119>\n             be zero-length. If the string contains one or more semicolons then everything that\n             precedes the last semicolon is taken as the primary format token and everything\n             that follows is taken as the format modifier; if the string contains no\n             semicolon then the entire picture is taken as the primary format token, and the\n             format modifier is taken to be absent (which is equivalent to supplying a\n             zero-length string).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The primary format token is classified as one of the following:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>A <var>decimal-digit-pattern</var> made up of <var>optional-digit-signs</var>,\n                      <var>mandatory-digit-signs</var>, and <var>grouping-separator-signs</var>.</p><ulist><item><p>The <var>optional-digit-sign</var> is the character "#".</p></item><item><p>A <var>mandatory-digit-sign</var> is a <termref def="character">character</termref> in Unicode category Nd. All\n                            <var>mandatory-digit-signs</var> within the format token <rfc2119>must</rfc2119> be from the\n                         same digit family, where a digit family is a sequence of ten consecutive\n                         characters in Unicode category Nd, having digit values 0 through 9. Within\n                         the format token, these digits are interchangeable: a three-digit number may\n                         thus be indicated equivalently by <code>000</code>, <code>001</code>, or\n                            <code>999</code>.</p></item><item><p>a <var>grouping-separator-sign</var> is a non-alphanumeric character, that\n                         is a <termref def="character">character</termref> whose Unicode category is\n                         other than Nd, Nl, No, Lu, Ll, Lt, Lm or Lo.</p></item></ulist><p diff="chg" at="L">If the primary format token contains at least one Unicode digit\n                   then it is taken as a decimal digit pattern, and in this case it <rfc2119>must</rfc2119>\n                   match the regular expression <code>^((\\p{Nd}|#|[^\\p{N}\\p{L}])+?)$</code>. If it contains\n                   a digit but does not match this pattern, a <phrase diff="add" at="L">dynamic</phrase> error\n                   is raised <errorref class="DF" code="1310"/>.</p><note><p diff="add" at="L">If a semicolon is to be used as a grouping separator, then the primary\n                format token as a whole must be followed by another semicolon, to ensure that\n                the grouping separator is not mistaken as a separator between the primary format\n                token and the format modifier.</p></note><p>There <rfc2119>must</rfc2119> be at least one <var>mandatory-digit-sign</var>. There may be zero or\n                   more <var>optional-digit-signs</var>, and (if present) these <rfc2119>must</rfc2119> precede all\n                      <var>mandatory-digit-signs</var>. There may be zero or more\n                      <var>grouping-separator-signs</var>. A <var>grouping-separator-sign</var> <rfc2119>must\n                   not</rfc2119> appear at the start or end of the <var>decimal-digit-pattern</var>, nor\n                   adjacent to another <var>grouping-separator-sign</var>.</p><p>The corresponding output format is a decimal number, using this digit family, with\n                   at least as many digits as there are <var>mandatory-digit-signs</var> in the\n                   format token. Thus, a format token <code>1</code> generates the sequence <code>0 1\n                      2 ... 10 11 12 ...</code>, and a format token <code>01</code> (or equivalently,\n                      <code>00</code> or <code>99</code>) generates the sequence <code>00 01 02 ...\n                      09 10 11 12 ... 99 100 101</code>. A format token of <code>&amp;#x661;</code>\n                   (Arabic-Indic digit one) generates the sequence <code>\u0661</code> then <code>\u0662</code>\n                   then <code>\u0663</code> ...</p><p>The <var>grouping-separator-signs</var> are handled as follows. The position of\n                   grouping separators within the format token, counting backwards from the last\n                   digit, indicates the position of grouping separators to appear within the\n                   formatted number, and the character used as the <var>grouping-separator-sign</var>\n                   within the format token indicates the character to be used as the corresponding\n                   grouping separator in the formatted number. If <var>grouping-separator-signs</var>\n                   appear at regular intervals within the format token, that is if the same grouping\n                   separator appears at positions forming a sequence <var>N</var>, 2<var>N</var>,\n                      3<var>N</var>, ... for some integer value <var>N</var> (including the case\n                   where there is only one number in the list), then the sequence is extrapolated to\n                   the left, so grouping separators will be used in the formatted number at every\n                   multiple of <var>N</var>. For example, if the format token is <code>0\'000</code>\n                   then the number one million will be formatted as <code>1\'000\'000</code>, while the\n                   number fifteen will be formatted as <code>0\'015</code>.</p><p>The only purpose of <var>optional-digit-signs</var> is to mark the position of\n                      <var>grouping-separator-signs</var>. For example, if the format token is\n                      <code>#\'##0</code> then the number one million will be formatted as\n                      <code>1\'000\'000</code>, while the number fifteen will be formatted as\n                      <code>15</code>. A grouping separator is included in the formatted number only\n                   if there is a digit to its left, which will only be the case if either (a) the\n                   number is large enough to require that digit, or (b) the number of\n                      <var>mandatory-digit-signs</var> in the format token requires insignificant\n                   leading zeros to be present.</p><note><p>Numbers will never be truncated. Given the <var>decimal-digit-pattern</var>\n                      <code>01</code>, the number three hundred will be output as <code>300</code>,\n                      despite the absence of any <var>optional-digit-sign</var>.</p></note></item><item><p>The format token <code>A</code>, which generates the sequence <code>A B C ... Z AA AB\n                      AC...</code>.</p></item><item><p>The format token <code>a</code>, which generates the sequence <code>a b c ... z aa ab\n                      ac...</code>.</p></item><item><p>The format token <code>i</code>, which generates the sequence <code>i ii iii iv v vi vii\n                      viii ix x ...</code>.</p></item><item><p>The format token <code>I</code>, which generates the sequence <code>I II III IV V VI VII\n                      VIII IX X ...</code>.</p></item><item><p>The format token <code>w</code>, which generates numbers written as lower-case words, for\n                   example in English, <code>one two three four ...</code>\n                </p></item><item><p>The format token <code>W</code>, which generates numbers written as upper-case words, for\n                   example in English, <code>ONE TWO THREE FOUR ...</code>\n                </p></item><item><p>The format token <code>Ww</code>, which generates numbers written as title-case words, for\n                   example in English, <code>One Two Three Four ...</code>\n                </p></item><item><p>Any other format token, which indicates a numbering sequence in which that token\n                   represents the number 1 (one) (but see the note below).\n                   <!-- Where possible (given the constraint that format tokens\n 						must be alphanumeric, and that they must be distinct) the format token\n 						used to represent a numbering sequence should be the same as the representation\n 						of the number 1 (one) in that sequence.-->\n                   It is <termref def="implementation-defined">implementation-defined</termref> which\n                   numbering sequences, additional to those listed above, are supported. If an\n                   implementation does not support a numbering sequence represented by the given\n                   token, it <rfc2119>must</rfc2119> use a format token of <code>1</code>.</p><note><p>In some traditional numbering sequences additional signs are added to denote\n                      that the letters should be interpreted as numbers; these are not included in\n                      the format token. An example (see also the example below) is classical Greek\n                      where a <emph>dexia keraia</emph> (x0374, \u0374) and sometimes an <emph>aristeri keraia</emph>\n                      (x0375, \u0375) is added.</p></note></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For all format tokens other than the first kind above (one that consists of decimal\n             digits), there <rfc2119>may</rfc2119> be <termref def="implementation-defined">implementation-defined</termref> lower and upper bounds on the range of numbers that\n             can be formatted using this format token; indeed, for some numbering sequences there may\n             be intrinsic limits. For example, the format token <code>&amp;#x2460;</code> (circled\n             digit one, \u2460) has a range <phrase diff="chg" at="M">imposed by the Unicode character repertoire \u2014 1 to 20 in\n             Unicode versions prior to 4.0, increased in subsequent versions</phrase>. For\n             the numbering sequences described above any upper bound imposed by the implementation\n                <rfc2119>must not</rfc2119> be less than 1000 (one thousand) and any lower bound must\n             not be greater than 1. Numbers that fall outside this range <rfc2119>must</rfc2119> be\n             formatted using the format token <code>1</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The above expansions of numbering sequences for format tokens such as <code>a</code> and\n                <code>i</code> are indicative but not prescriptive. There are various conventions in\n             use for how alphabetic sequences continue when the alphabet is exhausted, and differing\n             conventions for how roman numerals are written (for example, <code>IV</code> versus\n                <code>IIII</code> as the representation of the number 4). Sometimes alphabetic\n             sequences are used that omit letters such as <code>i</code> and <code>o</code>. This\n             specification does not prescribe the detail of any sequence other than those sequences\n             consisting entirely of decimal digits.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Many numbering sequences are language-sensitive. This applies especially to the sequence\n             selected by the tokens <code>w</code>, <code>W</code> and <code>Ww</code>. It also\n             applies to other sequences, for example different languages using the Cyrillic alphabet\n             use different sequences of characters, each starting with the letter #x410 (Cyrillic\n             capital letter A). In such cases, the <code>$lang</code> argument specifies which\n             language\'s conventions are to be used. <phrase diff="chg" at="L">If the argument\n             is specified, the value <rfc2119>should</rfc2119> be either an empty sequence\n             or a value that would be valid for the <code>xml:lang</code> attribute (see <bibref ref="REC-xml"/>).\n             Note that this permits the identification of sublanguages based on country codes (from ISO 3166-1)\n             as well as identification of dialects and regions within a country.</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The set of languages\n             for which numbering is supported is <termref def="implementation-defined"/>.\n             If the <code>$lang</code> argument is absent,\n             or is set to an empty sequence, or is invalid, or is not a language supported by the\n             implementation, then the number is formatted using <phrase diff="chg" at="K">the\n             default language from the dynamic context</phrase>.\n             </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The format modifier <phrase diff="chg" at="L"><rfc2119>must</rfc2119>\n             be a string that matches the regular expression <code diff="chg" at="M">^([co](\\(.+\\))?)?[at]?$</code>. </phrase>\n             That is, if it is present it must consist of one <phrase diff="add" at="G">or more</phrase> of\n             the following, in <phrase diff="del" at="K">any</phrase> order:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p diff="chg" at="G">either <code>c</code> or <code>o</code>, optionally followed by\n                   a sequence of characters enclosed between parentheses, to indicate cardinal or\n                   ordinal numbering respectively, the default being cardinal numbering</p></item><item><p diff="chg" at="G">either <code>a</code> or <code>t</code>, to indicate alphabetic\n                   or traditional numbering respectively, the default being <termref def="implementation-defined">implementation-defined</termref>.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the <code>o</code> modifier is present, this indicates a request to output ordinal\n             numbers rather than cardinal numbers. For example, in English, when used with the format\n             token <code>1</code>, this outputs the sequence <code>1st 2nd 3rd 4th ...</code>, and\n             when used with the format token <code>w</code> outputs the sequence <code>first second\n             third fourth ...</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">The string of characters between the parentheses, if present, is used to\n          select between other possible variations of cardinal or ordinal numbering sequences.\n          The interpretation of this string is <termref def="implemementation-defined">implementation-defined</termref>. No error occurs\n          if the implementation does not define any interpretation for the defined string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For example, in some languages, ordinal numbers vary depending on the grammatical context:\n             they may have different genders and may decline with the noun that they qualify.\n             In such cases the string appearing in parentheses after the letter <code>o</code> may be\n             used to indicate the variation of the ordinal number required. The way in which the\n             variation is indicated will depend on the conventions of the language. For inflected\n             languages that vary the ending of the word, the <rfc2119>recommended</rfc2119> approach is to indicate the\n             required ending, preceded by a hyphen: for example in German, appropriate values are\n                <code>o(-e)</code>, <code>o(-er)</code>, <code>o(-es)</code>, <code>o(-en)</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">It is <termref def="implementation-defined">implementation-defined</termref> what\n             combinations of values of the format token, the language, and the cardinal/ordinal\n             modifier are supported. If ordinal numbering is not supported for the combination of the\n             format token, the language, and the string appearing in parentheses, the request is\n             ignored and cardinal numbers are generated instead.</p><example xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><head>Ordinal Numbering in Italian</head><p>The specification <code>"1;o(-\u00ba)"</code> with <code>$lang</code> equal to\n                   <code>it</code>, if supported, should produce the sequence:</p><eg xml:space="preserve">1\u00ba 2\u00ba 3\u00ba 4\u00ba ...</eg><p>The specification <code>"Ww;o"</code> with <code>$lang</code> equal to\n                   <code>it</code>, if supported, should produce the sequence:</p><eg xml:space="preserve">Primo Secondo Terzo Quarto Quinto ...</eg></example><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <phrase diff="chg" at="G">use of the <code>a</code> or <code>t</code>\n                modifier</phrase> disambiguates between numbering sequences that use letters. In many\n             languages there are two commonly used numbering sequences that use letters. One\n             numbering sequence assigns numeric values to letters in alphabetic sequence, and the\n             other assigns numeric values to each letter in some other manner traditional in that\n             language. In English, these would correspond to the numbering sequences specified by the\n             format tokens <code>a</code> and <code>i</code>. In some languages, the first member of\n             each sequence is the same, and so the format token alone would be ambiguous. <phrase diff="chg" at="G">In the absence of the <code>a</code> or <code>t</code> modifier,\n                the default is <termref def="implementation-defined">implementation-defined</termref></phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DF" code="1310"/> if the format token is invalid,\n             that is, if it violates any mandatory rules (indicated by an emphasized <rfc2119>must</rfc2119>\n             or <rfc2119>required</rfc2119> keyword in the above rules). For example, the error is raised if\n             the primary format token contains a digit but does not match the required regular expression.</p></div>\n',summary:"<p>  Formats an integer according to a given picture string, using the conventions\n             of a given natural language if specified.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:integer",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""},{name:"language",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"format-number",qname:"fn:format-number",signature:"($value as numeric?, $picture as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string containing a number formatted according to a given picture\n             string, taking account of decimal formats specified in the static context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-number" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="numeric?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-number" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="numeric?"/><arg name="picture" type="xs:string"/><arg name="decimal-format-name" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		decimal formats, and namespaces.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="K">The effect of the two-argument form of the function is equivalent to calling\n          the three-argument form with an empty sequence as the value of the third argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function formats <code>$value</code> as a string using the <termref def="dt-picture-string">picture string</termref> specified by the\n                <code>$picture</code> argument and the decimal-format named by the\n                <code>$decimal-format-name</code> argument, or the default decimal-format, if there\n             is no <code>$decimal-format-name</code> argument. The syntax of the picture string is\n             described in <specref ref="syntax-of-picture-string"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$value</code> argument may be of any numeric data type\n             (<code>xs:double</code>, <code>xs:float</code>, <code>xs:decimal</code>, or their\n             subtypes including <code>xs:integer</code>). Note that if an <code>xs:decimal</code> is\n             supplied, it is not automatically promoted to an <code>xs:double</code>, as such\n             promotion can involve a loss of precision.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the supplied value of the <code>$value</code> argument is an empty sequence, the\n             function behaves as if the supplied value were the <code>xs:double</code> value\n                <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The value of <code>$decimal-format-name</code>,\n             <phrase diff="add" at="K">if present and non-empty, </phrase>\n             <rfc2119>must</rfc2119> <phrase diff="chg" at="L">be a string which after removal of leading and trailing whitespace is in the form of an\n             an <code>EQName</code> as defined in the XPath 3.0 grammar, that is one of the following</phrase>:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>A lexical QName, which is expanded using the\n                <phrase diff="chg" at="J">statically known namespaces</phrase>.\n                The default namespace is not used (no prefix means no namespace).</p></item><item><p diff="add" at="L">A <code>URIQualifiedName</code> using the syntax <code>Q{uri}local</code>,\n             where the URI can be zero-length to indicate a name in no namespace.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="K">The decimal format that is used is the decimal format\n          in the static context whose name matches <code>$decimal-format-name</code> if supplied,\n          or the default decimal format in the static context otherwise.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The evaluation of the <function>format-number</function> function takes place in two\n             phases, an analysis phase described in <specref ref="analysing-picture-string"/> and a\n             formatting phase described in <specref ref="formatting-the-number"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The analysis phase takes as its inputs the <termref def="dt-picture-string">picture\n                string</termref> and the variables derived from the relevant decimal format in the\n             static context, and produces as its output a number of variables with defined values.\n             The formatting phase takes as its inputs the number to be formatted and the variables\n             produced by the analysis phase, and produces as its output a string containing a\n             formatted representation of the number.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function is the formatted string representation of the supplied\n             number.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DF" code="1280"/> if the name specified as the\n                <code>$decimal-format-name</code> argument is\n             <phrase diff="chg" at="L">neither a valid lexical QName nor a valid <code>URIQualifiedName</code></phrase>, or if it\n             uses a prefix <phrase diff="add" at="J">that is not found in the statically known namespaces</phrase>, or if the static\n             context does not contain a declaration of a decimal-format with a matching expanded\n             QName. If the processor is able to detect the error statically (for example, when the\n             argument is supplied as a string literal), then the processor <rfc2119>may</rfc2119>\n             optionally signal this as a static error.</p></div>\n',summary:"<p>  Returns a string containing a number formatted according to a given picture\n             string, taking account of decimal formats specified in the static context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"numeric",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"format-number",qname:"fn:format-number",signature:"($value as numeric?, $picture as xs:string, $decimal-format-name as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string containing a number formatted according to a given picture\n             string, taking account of decimal formats specified in the static context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-number" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="numeric?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-number" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="numeric?"/><arg name="picture" type="xs:string"/><arg name="decimal-format-name" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		decimal formats, and namespaces.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="K">The effect of the two-argument form of the function is equivalent to calling\n          the three-argument form with an empty sequence as the value of the third argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function formats <code>$value</code> as a string using the <termref def="dt-picture-string">picture string</termref> specified by the\n                <code>$picture</code> argument and the decimal-format named by the\n                <code>$decimal-format-name</code> argument, or the default decimal-format, if there\n             is no <code>$decimal-format-name</code> argument. The syntax of the picture string is\n             described in <specref ref="syntax-of-picture-string"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$value</code> argument may be of any numeric data type\n             (<code>xs:double</code>, <code>xs:float</code>, <code>xs:decimal</code>, or their\n             subtypes including <code>xs:integer</code>). Note that if an <code>xs:decimal</code> is\n             supplied, it is not automatically promoted to an <code>xs:double</code>, as such\n             promotion can involve a loss of precision.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the supplied value of the <code>$value</code> argument is an empty sequence, the\n             function behaves as if the supplied value were the <code>xs:double</code> value\n                <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The value of <code>$decimal-format-name</code>,\n             <phrase diff="add" at="K">if present and non-empty, </phrase>\n             <rfc2119>must</rfc2119> <phrase diff="chg" at="L">be a string which after removal of leading and trailing whitespace is in the form of an\n             an <code>EQName</code> as defined in the XPath 3.0 grammar, that is one of the following</phrase>:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>A lexical QName, which is expanded using the\n                <phrase diff="chg" at="J">statically known namespaces</phrase>.\n                The default namespace is not used (no prefix means no namespace).</p></item><item><p diff="add" at="L">A <code>URIQualifiedName</code> using the syntax <code>Q{uri}local</code>,\n             where the URI can be zero-length to indicate a name in no namespace.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="K">The decimal format that is used is the decimal format\n          in the static context whose name matches <code>$decimal-format-name</code> if supplied,\n          or the default decimal format in the static context otherwise.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The evaluation of the <function>format-number</function> function takes place in two\n             phases, an analysis phase described in <specref ref="analysing-picture-string"/> and a\n             formatting phase described in <specref ref="formatting-the-number"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The analysis phase takes as its inputs the <termref def="dt-picture-string">picture\n                string</termref> and the variables derived from the relevant decimal format in the\n             static context, and produces as its output a number of variables with defined values.\n             The formatting phase takes as its inputs the number to be formatted and the variables\n             produced by the analysis phase, and produces as its output a string containing a\n             formatted representation of the number.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function is the formatted string representation of the supplied\n             number.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DF" code="1280"/> if the name specified as the\n                <code>$decimal-format-name</code> argument is\n             <phrase diff="chg" at="L">neither a valid lexical QName nor a valid <code>URIQualifiedName</code></phrase>, or if it\n             uses a prefix <phrase diff="add" at="J">that is not found in the statically known namespaces</phrase>, or if the static\n             context does not contain a declaration of a decimal-format with a matching expanded\n             QName. If the processor is able to detect the error statically (for example, when the\n             argument is supplied as a string literal), then the processor <rfc2119>may</rfc2119>\n             optionally signal this as a static error.</p></div>\n',summary:"<p>  Returns a string containing a number formatted according to a given picture\n             string, taking account of decimal formats specified in the static context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"numeric",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""},{name:"decimal-format-name",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"format-time",qname:"fn:format-time",signature:"($value as xs:time?, $picture as xs:string) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string containing an <code>xs:time</code> value formatted for display.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-time" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-time" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?"/><arg name="calendar" type="xs:string?"/><arg name="place" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		default calendar, and default language, and default place, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The five-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone, and namespaces.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See <specref ref="rules-for-datetime-formatting"/>.</p></div>\n',summary:"<p>  Returns a string containing an  xs:time  value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:time",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:5,name:"format-time",qname:"fn:format-time",signature:"($value as xs:time?, $picture as xs:string, $language as xs:string?, $calendar as xs:string?, $place as xs:string?) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string containing an <code>xs:time</code> value formatted for display.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="format-time" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/><arg name="picture" type="xs:string"/></proto></example><example role="signature"><proto name="format-time" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?"/><arg name="calendar" type="xs:string?"/><arg name="place" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		default calendar, and default language, and default place, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The five-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone, and namespaces.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">See <specref ref="rules-for-datetime-formatting"/>.</p></div>\n',summary:"<p>  Returns a string containing an  xs:time  value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:time",occurrence:"?",description:""},{name:"picture",type:"xs:string",occurrence:null,description:""},{name:"language",type:"xs:string",occurrence:"?",description:""},{name:"calendar",type:"xs:string",occurrence:"?",description:""},{name:"place",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"function-arity",qname:"fn:function-arity",signature:"($func as function (*)) as xs:integer external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the arity of the function identified by a function item.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="function-arity" return-type="xs:integer" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="func" type="function(*)"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>fn:function-arity</code> function returns the arity (number of arguments) of\n             the function identified by <code>$func</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:function-arity(fn:substring#2)</code> returns <code>2</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:function-arity(function($node){name($node)})</code> returns <code>1</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>let $initial := fn:substring(?, 1, 1) return fn:function-arity($initial)</code> returns <code>1</code>.</p></div>\n',summary:"<p>  Returns the arity of the function identified by a function item.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"func",type:"function (*)",occurrence:null,description:""}],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:0,name:"generate-id",qname:"fn:generate-id",signature:"() as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function returns a string that uniquely identifies a given node. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="generate-id" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="generate-id" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is the empty sequence, the result is the zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In other cases, the function returns a string that uniquely identifies a given node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The returned identifier <rfc2119>must</rfc2119> consist of ASCII alphanumeric characters\n             and <rfc2119>must</rfc2119> start with an alphabetic character. Thus, the string is\n             syntactically an XML name.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">An implementation is free to generate an identifier in any convenient way provided that\n             it always generates the same identifier for the same node and that different identifiers\n             are always generated from different nodes. An implementation is under no obligation to\n             generate the same identifiers each time a document is transformed or queried.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  This function returns a string that uniquely identifies a given node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"generate-id",qname:"fn:generate-id",signature:"($arg as node()?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function returns a string that uniquely identifies a given node. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="generate-id" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="generate-id" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is the empty sequence, the result is the zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In other cases, the function returns a string that uniquely identifies a given node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The returned identifier <rfc2119>must</rfc2119> consist of ASCII alphanumeric characters\n             and <rfc2119>must</rfc2119> start with an alphabetic character. Thus, the string is\n             syntactically an XML name.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">An implementation is free to generate an identifier in any convenient way provided that\n             it always generates the same identifier for the same node and that different identifiers\n             are always generated from different nodes. An implementation is under no obligation to\n             generate the same identifiers each time a document is transformed or queried.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  This function returns a string that uniquely identifies a given node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:0,name:"has-children",qname:"fn:has-children",signature:"() as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the supplied node has one or more child nodes (of any kind).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="has-children" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="has-children" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><phrase diff="add" at="L">Provided that the supplied argument <code>$node</code> matches the expected\n          type <code>node()?</code>, </phrase>the result of the function call <code>fn:has-children($node)</code> is defined to be\n             the same as the result of the expression\n             <code>fn:exists($node/child::node())</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$node</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns true if the supplied node has one or more child nodes (of any kind).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"has-children",qname:"fn:has-children",signature:"($node as node()?) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the supplied node has one or more child nodes (of any kind).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="has-children" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="has-children" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><phrase diff="add" at="L">Provided that the supplied argument <code>$node</code> matches the expected\n          type <code>node()?</code>, </phrase>the result of the function call <code>fn:has-children($node)</code> is defined to be\n             the same as the result of the expression\n             <code>fn:exists($node/child::node())</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$node</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns true if the supplied node has one or more child nodes (of any kind).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:"?",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"head",qname:"fn:head",signature:"($arg as item()*) as item()? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the first item in a sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="head" return-type="item()?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the value of the expression <code>$arg[1]</code></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the empty sequence is returned. Otherwise\n             the first item in the sequence is returned.</p></div>\n',summary:"<p>  Returns the first item in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"item()?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"hours-from-duration",qname:"fn:hours-from-duration",signature:"($arg as xs:duration?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the number of hours in a duration.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="hours-from-duration" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:duration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> representing the hours\n             component in the value of <code>$arg</code>. The result is obtained by casting\n                <code>$arg</code> to an <code>xs:dayTimeDuration</code> (see <specref ref="casting-to-durations"/>) and then computing the hours component as described in\n                <specref ref="canonical-dayTimeDuration"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a negative duration then the result will be negative..</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is an <code>xs:yearMonthDuration</code> the function returns 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:hours-from-duration(xs:dayTimeDuration("P3DT10H"))</code> returns <code>10</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:hours-from-duration(xs:dayTimeDuration("P3DT12H32M12S"))</code> returns <code>12</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:hours-from-duration(xs:dayTimeDuration("PT123H"))</code> returns <code>3</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:hours-from-duration(xs:dayTimeDuration("-P3DT10H"))</code> returns <code>-10</code>.</p></div>\n',summary:"<p>  Returns the number of hours in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:duration",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"hours-from-time",qname:"fn:hours-from-time",signature:"($arg as xs:time?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the hours component of an <code>xs:time</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="hours-from-time" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:time?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> between 0 and 23, both\n             inclusive, representing the value of the hours component in the local value of\n                <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Assume that the dynamic context provides an implicit timezone value of\n                   <code>-05:00</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:hours-from-time(xs:time("11:23:00"))</code> returns <code>11</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:hours-from-time(xs:time("21:23:00"))</code> returns <code>21</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:hours-from-time(xs:time("01:23:00+05:00"))</code> returns <code>1</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:hours-from-time(fn:adjust-time-to-timezone(xs:time("01:23:00+05:00"),\n                   xs:dayTimeDuration("PT0S")))</code> returns <code>20</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:hours-from-time(xs:time("24:00:00"))</code> returns <code>0</code>.</p></div>\n',summary:"<p>  Returns the hours component of an  xs:time .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:time",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"id",qname:"fn:id",signature:"($arg as xs:string*) as element(*)* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the sequence of element nodes that have an <code>ID</code> value\n             matching the value of one or more of the <code>IDREF</code> values supplied in\n                <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="id" return-type="element()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/></proto></example><example role="signature"><proto name="id" return-type="element()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/><arg name="node" type="node()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence, in document order with duplicates eliminated,\n             containing every element node <code>E</code> that satisfies all the following\n             conditions:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>\n                   <code>E</code> is in the target document. The target document is the document\n                   containing <code>$node</code>, or the document containing the context item\n                      (<code>.</code>) if the second argument is omitted. The behavior of the\n                   function if <code>$node</code> is omitted is exactly the same as if the context\n                   item had been passed as <code>$node</code>.</p></item><item><p><code>E</code> has an <code>ID</code> value equal to one of the candidate\n                      <code>IDREF</code> values, where:</p><ulist><item><p> An element has an <code>ID</code> value equal to <code>V</code> if either\n                         or both of the following conditions are true:</p><ulist><item><p>The <code>is-id</code> property (See <xspecref spec="DM30" ref="dm-is-id"/>.) of the element node is true, and the typed value\n                               of the element node is equal to <code>V</code> under the rules of the\n                                  <code>eq</code> operator using the Unicode codepoint collation\n                                  (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item><item><p>The element has an attribute node whose <code>is-id</code> property\n                               (See <xspecref spec="DM30" ref="dm-is-id"/>.) is true and whose typed\n                               value is equal to <code>V</code> under the rules of the\n                                  <code>eq</code> operator using the Unicode code point collation\n                                  (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item></ulist></item><item><p> Each <code>xs:string</code> in <code>$arg</code> is parsed as if it were of\n                         type <code>IDREFS</code>, that is, each <code>xs:string</code> in\n                            <code>$arg</code> is treated as a whitespace-separated sequence of\n                         tokens, each acting as an <code>IDREF</code>. These tokens are then included\n                         in the list of candidate <code>IDREF</code>s. If any of the tokens is not a\n                         lexically valid <code>IDREF</code> (that is, if it is not lexically an\n                            <code>xs:NCName</code>), it is ignored. Formally, the candidate\n                            <code>IDREF</code> values are the strings in the sequence given by the\n                         expression:</p><eg xml:space="preserve">for $s in $arg return\n     fn:tokenize(fn:normalize-space($s), \' \')[. castable as xs:IDREF]</eg></item></ulist></item><item><p>If several elements have the same <code>ID</code> value, then <code>E</code> is\n                   the one that is first in document order.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0001" type="dynamic"/> if\n                <code>$node</code>, or the context item if the second argument is absent, is a node\n                in a tree whose root is not a document node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$node</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the sequence of element nodes that have an  ID  value\n             matching the value of one or more of the  IDREF  values supplied in\n                 $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"*",description:""}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"id",qname:"fn:id",signature:"($arg as xs:string*, $node as node()) as element(*)* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the sequence of element nodes that have an <code>ID</code> value\n             matching the value of one or more of the <code>IDREF</code> values supplied in\n                <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="id" return-type="element()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/></proto></example><example role="signature"><proto name="id" return-type="element()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/><arg name="node" type="node()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence, in document order with duplicates eliminated,\n             containing every element node <code>E</code> that satisfies all the following\n             conditions:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>\n                   <code>E</code> is in the target document. The target document is the document\n                   containing <code>$node</code>, or the document containing the context item\n                      (<code>.</code>) if the second argument is omitted. The behavior of the\n                   function if <code>$node</code> is omitted is exactly the same as if the context\n                   item had been passed as <code>$node</code>.</p></item><item><p><code>E</code> has an <code>ID</code> value equal to one of the candidate\n                      <code>IDREF</code> values, where:</p><ulist><item><p> An element has an <code>ID</code> value equal to <code>V</code> if either\n                         or both of the following conditions are true:</p><ulist><item><p>The <code>is-id</code> property (See <xspecref spec="DM30" ref="dm-is-id"/>.) of the element node is true, and the typed value\n                               of the element node is equal to <code>V</code> under the rules of the\n                                  <code>eq</code> operator using the Unicode codepoint collation\n                                  (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item><item><p>The element has an attribute node whose <code>is-id</code> property\n                               (See <xspecref spec="DM30" ref="dm-is-id"/>.) is true and whose typed\n                               value is equal to <code>V</code> under the rules of the\n                                  <code>eq</code> operator using the Unicode code point collation\n                                  (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item></ulist></item><item><p> Each <code>xs:string</code> in <code>$arg</code> is parsed as if it were of\n                         type <code>IDREFS</code>, that is, each <code>xs:string</code> in\n                            <code>$arg</code> is treated as a whitespace-separated sequence of\n                         tokens, each acting as an <code>IDREF</code>. These tokens are then included\n                         in the list of candidate <code>IDREF</code>s. If any of the tokens is not a\n                         lexically valid <code>IDREF</code> (that is, if it is not lexically an\n                            <code>xs:NCName</code>), it is ignored. Formally, the candidate\n                            <code>IDREF</code> values are the strings in the sequence given by the\n                         expression:</p><eg xml:space="preserve">for $s in $arg return\n     fn:tokenize(fn:normalize-space($s), \' \')[. castable as xs:IDREF]</eg></item></ulist></item><item><p>If several elements have the same <code>ID</code> value, then <code>E</code> is\n                   the one that is first in document order.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0001" type="dynamic"/> if\n                <code>$node</code>, or the context item if the second argument is absent, is a node\n                in a tree whose root is not a document node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$node</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the sequence of element nodes that have an  ID  value\n             matching the value of one or more of the  IDREF  values supplied in\n                 $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"*",description:""},{name:"node",type:"node()",occurrence:null,description:""}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"idref",qname:"fn:idref",signature:"($arg as xs:string*) as node()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the sequence of element or attribute nodes with an <code>IDREF</code>\n             value matching the value of one or more of the <code>ID</code> values supplied in\n                <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="idref" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/></proto></example><example role="signature"><proto name="idref" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/><arg name="node" type="node()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> The function returns a sequence, in document order with duplicates eliminated,\n             containing every element or attribute node <code>$N</code> that satisfies all the\n             following conditions:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p><code>$N</code> is in the target document. The target document is the document\n                   containing <code>$node</code> or the document containing the context item\n                      (<code>.</code>) if the second argument is omitted. The behavior of the\n                   function if <code>$node</code> is omitted is exactly the same as if the context\n                   item had been passed as <code>$node</code>.</p></item><item><p><code>$N</code> has an <code>IDREF</code> value equal to one of the candidate\n                      <code>ID</code> values, where:</p><ulist><item><p>A node <code>$N</code> has an <code>IDREF</code> value equal to\n                            <code>V</code> if both of the following conditions are true:</p><ulist><item><p>The <code>is-idrefs</code> property (see <xspecref spec="DM30" ref="dm-is-idrefs"/>) of <code>$N</code> is <code>true</code>.</p></item><item><p>The sequence <!--Text replaced by erratum E29 change 1"--><eg diff="chg" at="A-E29" xml:space="preserve">fn:tokenize(fn:normalize-space(fn:string($N)), \' \')</eg>\n                               <!--End of text replaced by erratum E29--> contains a string that is\n                               equal to <code>V</code> under the rules of the <code>eq</code>\n                               operator using the Unicode code point collation\n                                  (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item></ulist></item><item><p>Each <code>xs:string</code> in <code>$arg</code> is parsed as if it were of\n                         lexically of type <code>xs:ID</code>. These <code>xs:string</code>s are then\n                         included in the list of candidate <code>xs:ID</code>s. If any of the strings\n                         in <code>$arg</code> is not a lexically valid <code>xs:ID</code> (that is,\n                         if it is not lexically an <code>xs:NCName</code>), it is ignored. More\n                         formally, the candidate <code>ID</code> values are the strings in the\n                         sequence:</p><eg xml:space="preserve">$arg[. castable as xs:NCName]</eg></item></ulist></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0001" type="dynamic"/> if\n                <code>$node</code>, or the context item if the second argument is omitted, is a node\n                in a tree whose root is not a document node. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$node</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the sequence of element or attribute nodes with an  IDREF \n             value matching the value of one or more of the  ID  values supplied in\n                 $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"*",description:""}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"idref",qname:"fn:idref",signature:"($arg as xs:string*, $node as node()) as node()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the sequence of element or attribute nodes with an <code>IDREF</code>\n             value matching the value of one or more of the <code>ID</code> values supplied in\n                <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="idref" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/></proto></example><example role="signature"><proto name="idref" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string*"/><arg name="node" type="node()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> The function returns a sequence, in document order with duplicates eliminated,\n             containing every element or attribute node <code>$N</code> that satisfies all the\n             following conditions:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p><code>$N</code> is in the target document. The target document is the document\n                   containing <code>$node</code> or the document containing the context item\n                      (<code>.</code>) if the second argument is omitted. The behavior of the\n                   function if <code>$node</code> is omitted is exactly the same as if the context\n                   item had been passed as <code>$node</code>.</p></item><item><p><code>$N</code> has an <code>IDREF</code> value equal to one of the candidate\n                      <code>ID</code> values, where:</p><ulist><item><p>A node <code>$N</code> has an <code>IDREF</code> value equal to\n                            <code>V</code> if both of the following conditions are true:</p><ulist><item><p>The <code>is-idrefs</code> property (see <xspecref spec="DM30" ref="dm-is-idrefs"/>) of <code>$N</code> is <code>true</code>.</p></item><item><p>The sequence <!--Text replaced by erratum E29 change 1"--><eg diff="chg" at="A-E29" xml:space="preserve">fn:tokenize(fn:normalize-space(fn:string($N)), \' \')</eg>\n                               <!--End of text replaced by erratum E29--> contains a string that is\n                               equal to <code>V</code> under the rules of the <code>eq</code>\n                               operator using the Unicode code point collation\n                                  (<code>http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item></ulist></item><item><p>Each <code>xs:string</code> in <code>$arg</code> is parsed as if it were of\n                         lexically of type <code>xs:ID</code>. These <code>xs:string</code>s are then\n                         included in the list of candidate <code>xs:ID</code>s. If any of the strings\n                         in <code>$arg</code> is not a lexically valid <code>xs:ID</code> (that is,\n                         if it is not lexically an <code>xs:NCName</code>), it is ignored. More\n                         formally, the candidate <code>ID</code> values are the strings in the\n                         sequence:</p><eg xml:space="preserve">$arg[. castable as xs:NCName]</eg></item></ulist></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0001" type="dynamic"/> if\n                <code>$node</code>, or the context item if the second argument is omitted, is a node\n                in a tree whose root is not a document node. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$node</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the sequence of element or attribute nodes with an  IDREF \n             value matching the value of one or more of the  ID  values supplied in\n                 $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"*",description:""},{name:"node",type:"node()",occurrence:null,description:""}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:0,name:"implicit-timezone",qname:"fn:implicit-timezone",signature:"() as xs:dayTimeDuration external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of the implicit timezone property from the dynamic context.\n          </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="implicit-timezone" return-type="xs:dayTimeDuration" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of the implicit timezone property from the dynamic context. Components\n             of the dynamic context are discussed in <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p></div>\n',summary:"<p>  Returns the value of the implicit timezone property from the dynamic context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:dayTimeDuration",description:""},errors:[]},{isDocumented:!0,arity:1,name:"in-scope-prefixes",qname:"fn:in-scope-prefixes",signature:"($element as element(*)) as xs:string* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the prefixes of the in-scope namespaces for an element node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="in-scope-prefixes" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="element" type="element()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence of strings representing the prefixes of the in-scope\n             namespaces for <code>$element</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For namespace bindings that have a prefix, the function returns the prefix as an\n                <code>xs:NCName</code>. For the default namespace, which has no prefix, it returns\n             the zero-length string. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result sequence contains no duplicates.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The ordering of the result sequence is <termref def="implementation-dependent">implementation-dependent</termref>.</p></div>\n',summary:"<p>  Returns the prefixes of the in-scope namespaces for an element node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"element",type:"element(*)",occurrence:null,description:""}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"index-of",qname:"fn:index-of",signature:"($seq as xs:anyAtomicType*, $search as xs:anyAtomicType) as xs:integer* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of positive integers giving the positions within the\n             sequence <code>$seq</code> of items that are equal to <code>$search</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="index-of" return-type="xs:integer*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seq" type="xs:anyAtomicType*"/><arg name="search" type="xs:anyAtomicType"/></proto></example><example role="signature"><proto name="index-of" return-type="xs:integer*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seq" type="xs:anyAtomicType*"/><arg name="search" type="xs:anyAtomicType"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence of positive integers giving the positions within the\n             sequence <code>$seq</code> of items that are equal to <code>$search</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>. This collation is used when string comparison is\n             required.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The items in the sequence <code>$seq</code> are compared with <code>$search</code> under\n             the rules for the <code>eq</code> operator. Values of type <code>xs:untypedAtomic</code>\n             are compared as if they were of type <code>xs:string</code>. Values that cannot be\n             compared, because the <code>eq</code> operator is not defined for their types, are\n             considered to be distinct. If an item compares equal, then the position of that item in\n             the sequence <code>$seq</code> is included in the result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The first item in a sequence is at position 1, not position 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result sequence is in ascending numeric order.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$seq</code> is the empty sequence, or if no item in\n                <code>$seq</code> matches <code>$search</code>, then the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="D">No error occurs if non-comparable values are encountered. So when\n             comparing two atomic values, the effective boolean value of <code>fn:index-of($a,\n                $b)</code> is true if <code>$a</code> and <code>$b</code> are equal, false if they\n             are not equal or not comparable.</p></div>\n',summary:"<p>  Returns a sequence of positive integers giving the positions within the\n             sequence  $seq  of items that are equal to  $search .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"xs:anyAtomicType",occurrence:"*",description:""},{name:"search",type:"xs:anyAtomicType",occurrence:null,description:""}],returns:{type:"xs:integer*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"index-of",qname:"fn:index-of",signature:"($seq as xs:anyAtomicType*, $search as xs:anyAtomicType, $collation as xs:string) as xs:integer* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of positive integers giving the positions within the\n             sequence <code>$seq</code> of items that are equal to <code>$search</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="index-of" return-type="xs:integer*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seq" type="xs:anyAtomicType*"/><arg name="search" type="xs:anyAtomicType"/></proto></example><example role="signature"><proto name="index-of" return-type="xs:integer*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seq" type="xs:anyAtomicType*"/><arg name="search" type="xs:anyAtomicType"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence of positive integers giving the positions within the\n             sequence <code>$seq</code> of items that are equal to <code>$search</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>. This collation is used when string comparison is\n             required.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The items in the sequence <code>$seq</code> are compared with <code>$search</code> under\n             the rules for the <code>eq</code> operator. Values of type <code>xs:untypedAtomic</code>\n             are compared as if they were of type <code>xs:string</code>. Values that cannot be\n             compared, because the <code>eq</code> operator is not defined for their types, are\n             considered to be distinct. If an item compares equal, then the position of that item in\n             the sequence <code>$seq</code> is included in the result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The first item in a sequence is at position 1, not position 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result sequence is in ascending numeric order.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$seq</code> is the empty sequence, or if no item in\n                <code>$seq</code> matches <code>$search</code>, then the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="D">No error occurs if non-comparable values are encountered. So when\n             comparing two atomic values, the effective boolean value of <code>fn:index-of($a,\n                $b)</code> is true if <code>$a</code> and <code>$b</code> are equal, false if they\n             are not equal or not comparable.</p></div>\n',summary:"<p>  Returns a sequence of positive integers giving the positions within the\n             sequence  $seq  of items that are equal to  $search .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"xs:anyAtomicType",occurrence:"*",description:""},{name:"search",type:"xs:anyAtomicType",occurrence:null,description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:integer*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"innermost",qname:"fn:innermost",signature:"($nodes as node()*) as node()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns every node within the input sequence that is not an ancestor of another member\n             of the input sequence; the nodes are returned in document order with duplicates\n             eliminated.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="innermost" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="nodes" type="node()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of the function call <code>fn:innermost($nodes)</code> is defined to be\n             equivalent to the result of the expression <code>$nodes except\n                $nodes/ancestor::node()</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">That is, the function takes as input a sequence of nodes, and returns every node within\n             the sequence that is not an ancestor of another node within the sequence; the nodes are\n             returned in document order with duplicates eliminated.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the source document contains nested sections represented by <code>div</code>\n                elements, the expression <code>innermost(//div)</code> returns those <code>div</code>\n                elements that do not contain further <code>div</code> elements.</p></div>\n',summary:"<p>  Returns every node within the input sequence that is not an ancestor of another member\n             of the input sequence; the nodes are returned in document order with duplicates\n             eliminated.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:""}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"insert-before",qname:"fn:insert-before",signature:"($target as item()*, $position as xs:integer, $inserts as item()*) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence constructed by inserting an item or a sequence of items at a\n             given position within an existing sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="insert-before" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="target" type="item()*"/><arg name="position" type="xs:integer"/><arg name="inserts" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The value returned by the function consists of all items of <code>$target</code> whose\n             index is less than <code>$position</code>, followed by all items of\n                <code>$inserts</code>, followed by the remaining elements of <code>$target</code>, in\n             that order. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$target</code> is the empty sequence, <code>$inserts</code> is returned. If\n                <code>$inserts</code> is the empty sequence, <code>$target</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$position</code> is less than one (1), the first position, the effective value\n             of <code>$position</code> is one (1). If <code>$position</code> is greater than the\n             number of items in <code>$target</code>, then the effective value of\n                <code>$position</code> is equal to the number of items in <code>$target</code> plus\n             1. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The value of <code>$target</code> is not affected by the sequence construction.</p></div>\n',summary:"<p>  Returns a sequence constructed by inserting an item or a sequence of items at a\n             given position within an existing sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"target",type:"item()",occurrence:"*",description:""},{name:"position",type:"xs:integer",occurrence:null,description:""},{name:"inserts",type:"item()",occurrence:"*",description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"iri-to-uri",qname:"fn:iri-to-uri",signature:"($iri as xs:string?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Converts a string containing an IRI into a URI according to the rules of\n                <bibref ref="rfc3987"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="iri-to-uri" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="iri" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$iri</code> is the empty sequence, the function returns the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function converts the value of <code>$iri</code> into a URI according to\n             the rules given in Section 3.1 of <bibref ref="rfc3987"/> by percent-encoding characters\n             that are allowed in an IRI but not in a URI. If <code>$iri</code> contains a character\n             that is invalid in an IRI, such as the space character (see note below), the invalid\n             character is replaced by its percent-encoded form as described in <bibref ref="rfc3986"/> before the conversion is performed.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Since <bibref ref="rfc3986"/> recommends that, for consistency, URI producers and\n             normalizers should use uppercase hexadecimal digits for all percent-encodings, this\n             function must always generate hexadecimal values using the upper-case letters A-F.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function is idempotent but not invertible. Both the inputs <code>My Documents</code>\n             and <code>My%20Documents</code> will be converted to the output\n                <code>My%20Documents</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function does not check whether <code>$iri</code> is a valid IRI. It treats it as\n             an <termref def="string">string</termref> and operates on the <termref def="character">characters</termref> in the string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> The following printable ASCII characters are invalid in an IRI: "&lt;", "&gt;", <quote>\n                " </quote> (double quote), space, "{", "}", "|", "\\", "^", and "`". Since these\n             characters should not appear in an IRI, if they do appear in <code>$iri</code> they will\n             be percent-encoded. In addition, characters outside the range x20-<phrase diff="chg" at="A-E8">x7E</phrase> will be percent-encoded because they are invalid in a URI. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> Since this function does not escape the PERCENT SIGN "%" and this character is not\n             allowed in data within a URI, users wishing to convert character strings (such as file\n             names) that include "%" to a URI should manually escape "%" by replacing it with "%25".\n          </p></div>\n',summary:"<p>  Converts a string containing an IRI into a URI according to the rules of\n                  .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"iri",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"lang",qname:"fn:lang",signature:"($testlang as xs:string?) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function tests whether the language of <code>$node</code>, or the context\n             item if the second argument is omitted, as specified by <code>xml:lang</code> attributes\n             is the same as, or is a sublanguage of, the language specified by\n             <code>$testlang</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="lang" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="testlang" type="xs:string?"/></proto></example><example role="signature"><proto name="lang" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="testlang" type="xs:string?"/><arg name="node" type="node()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The behavior of the function if the second argument is omitted is exactly the same as if\n             the context item (<code>.</code>) had been passed as the second argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The language of the argument <code>$node</code>, or the context item if the second\n             argument is omitted, is determined by the value of the <code>xml:lang</code> attribute\n             on the node, or, if the node has no such attribute, by the value of the\n                <code>xml:lang</code> attribute on the nearest ancestor of the node that has an\n                <code>xml:lang</code> attribute. If there is no such ancestor, then the function\n             returns <code>false</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$testlang</code> is the empty sequence it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The relevant <code>xml:lang</code> attribute is determined by the value of the XPath\n             expression:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">(ancestor-or-self::*/@xml:lang)[last()]</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If this expression returns an empty sequence, the function returns <code>false</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns <code>true</code> if and only if, based on a caseless\n             default match as specified in section 3.13 of <bibref ref="Unicode"/>, either:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p diff="chg" at="A-E16">\n                   <code>$testlang</code> is equal to the string-value of the relevant\n                      <code>xml:lang</code> attribute, or</p></item><item><p diff="chg" at="A-E16">\n                   <code>$testlang</code> is equal to some substring of the string-value of the\n                   relevant <code>xml:lang</code> attribute that starts at the start of the\n                   string-value and ends immediately before a hyphen, "-" (the character "-" is\n                   HYPHEN-MINUS, #x002D).</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  This function tests whether the language of  $node , or the context\n             item if the second argument is omitted, as specified by  xml:lang  attributes\n             is the same as, or is a sublanguage of, the language specified by\n              $testlang .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"testlang",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"lang",qname:"fn:lang",signature:"($testlang as xs:string?, $node as node()) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function tests whether the language of <code>$node</code>, or the context\n             item if the second argument is omitted, as specified by <code>xml:lang</code> attributes\n             is the same as, or is a sublanguage of, the language specified by\n             <code>$testlang</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="lang" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="testlang" type="xs:string?"/></proto></example><example role="signature"><proto name="lang" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="testlang" type="xs:string?"/><arg name="node" type="node()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The behavior of the function if the second argument is omitted is exactly the same as if\n             the context item (<code>.</code>) had been passed as the second argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The language of the argument <code>$node</code>, or the context item if the second\n             argument is omitted, is determined by the value of the <code>xml:lang</code> attribute\n             on the node, or, if the node has no such attribute, by the value of the\n                <code>xml:lang</code> attribute on the nearest ancestor of the node that has an\n                <code>xml:lang</code> attribute. If there is no such ancestor, then the function\n             returns <code>false</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$testlang</code> is the empty sequence it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The relevant <code>xml:lang</code> attribute is determined by the value of the XPath\n             expression:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">(ancestor-or-self::*/@xml:lang)[last()]</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If this expression returns an empty sequence, the function returns <code>false</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns <code>true</code> if and only if, based on a caseless\n             default match as specified in section 3.13 of <bibref ref="Unicode"/>, either:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p diff="chg" at="A-E16">\n                   <code>$testlang</code> is equal to the string-value of the relevant\n                      <code>xml:lang</code> attribute, or</p></item><item><p diff="chg" at="A-E16">\n                   <code>$testlang</code> is equal to some substring of the string-value of the\n                   relevant <code>xml:lang</code> attribute that starts at the start of the\n                   string-value and ends immediately before a hyphen, "-" (the character "-" is\n                   HYPHEN-MINUS, #x002D).</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  This function tests whether the language of  $node , or the context\n             item if the second argument is omitted, as specified by  xml:lang  attributes\n             is the same as, or is a sublanguage of, the language specified by\n              $testlang .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"testlang",type:"xs:string",occurrence:"?",description:""},{name:"node",type:"node()",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:0,name:"last",qname:"fn:last",signature:"() as xs:integer external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the context size from the dynamic context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="last" return-type="xs:integer" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the context size from the dynamic context. (See <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.)</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="M">dynamic</phrase> error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/> if the\n             context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p></div>\n',summary:"<p>  Returns the context size from the dynamic context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:1,name:"local-name-from-QName",qname:"fn:local-name-from-QName",signature:"($arg as xs:QName?) as xs:NCName? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the local part of the supplied QName.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="local-name-from-QName" return-type="xs:NCName?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:QName?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:NCName</code> representing the local part of\n                <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:local-name-from-QName(fn:QName("http://www.example.com/example",\n                   "person"))</code> returns <code>"person"</code>.</p></div>\n',summary:"<p>  Returns the local part of the supplied QName.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:QName",occurrence:"?",description:""}],returns:{type:"xs:NCName?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"local-name",qname:"fn:local-name",signature:"() as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the local part of the name of <code>$arg</code> as an\n                <code>xs:string</code> that is either the zero-length string, or has the lexical form\n             of an <code>xs:NCName</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="local-name" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="local-name" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is supplied and is the empty sequence, the function returns the\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the node identified by <code>$arg</code> has no name (that is, if it is a document\n             node, a comment, a text node, or a namespace node having no name), the function returns\n             the zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the local part of the expanded-QName of the node\n             identified by <code>$arg</code>, as determined by the <code>dm:node-name</code> accessor\n             defined in <xspecref spec="DM30" ref="dm-node-name"/>). This will be an\n                <code>xs:string</code> whose lexical form is an <code>xs:NCName</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the local part of the name of  $arg  as an\n                 xs:string  that is either the zero-length string, or has the lexical form\n             of an  xs:NCName .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"local-name",qname:"fn:local-name",signature:"($arg as node()?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the local part of the name of <code>$arg</code> as an\n                <code>xs:string</code> that is either the zero-length string, or has the lexical form\n             of an <code>xs:NCName</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="local-name" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="local-name" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is supplied and is the empty sequence, the function returns the\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the node identified by <code>$arg</code> has no name (that is, if it is a document\n             node, a comment, a text node, or a namespace node having no name), the function returns\n             the zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the local part of the expanded-QName of the node\n             identified by <code>$arg</code>, as determined by the <code>dm:node-name</code> accessor\n             defined in <xspecref spec="DM30" ref="dm-node-name"/>). This will be an\n                <code>xs:string</code> whose lexical form is an <code>xs:NCName</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the local part of the name of  $arg  as an\n                 xs:string  that is either the zero-length string, or has the lexical form\n             of an  xs:NCName .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"lower-case",qname:"fn:lower-case",signature:"($arg as xs:string?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Converts a string to lower case.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="lower-case" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the zero-length string is\n             returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the value of <code>$arg</code> after translating every\n                <termref def="character">character</termref> to its lower-case correspondent as\n             defined in the appropriate case mappings section in the Unicode standard <bibref ref="Unicode"/>. For versions of Unicode beginning with the 2.1.8 update, only\n             locale-insensitive case mappings should be applied. Beginning with version 3.2.0 (and\n             likely future versions) of Unicode, precise mappings are described in default case\n             operations, which are full case mappings in the absence of tailoring for particular\n             languages and environments. Every upper-case character that does not have a lower-case\n             correspondent, as well as every lower-case character, is included in the returned value\n             in its original form. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Case mappings may change the length of a string. In general, the\n                <code>fn:upper-case</code> and <code>fn:lower-case</code> functions are not inverses\n             of each other: <code>fn:lower-case(fn:upper-case($arg))</code> is not guaranteed to\n             return <code>$arg</code>, nor is <code>fn:upper-case(fn:lower-case($arg))</code>. The\n             Latin small letter dotless i (as used in Turkish) is perhaps the most prominent\n             lower-case letter which will not round-trip. The Latin capital letter i with dot above\n             is the most prominent upper-case letter which will not round trip; there are others,\n             such as Latin capital letter Sharp S (#1E9E) which is introduced in Unicode 5.1.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> These functions may not always be linguistically appropriate (e.g. Turkish i without\n             dot) or appropriate for the application (e.g. titlecase). In cases such as Turkish, a\n             simple translation should be used first.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> Because the function is not sensitive to locale, results will not always match user\n             expectations. In Quebec, for example, the standard uppercase equivalent of "\u00e8" is "\u00c8",\n             while in metropolitan France it is more commonly "E"; only one of these is supported by\n             the functions as defined.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> Many characters of class Ll lack uppercase equivalents in the Unicode case mapping\n             tables; many characters of class Lu lack lowercase equivalents.</p></div>\n',summary:"<p>  Converts a string to lower case.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"matches",qname:"fn:matches",signature:"($input as xs:string?, $pattern as xs:string) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the supplied string matches a given regular expression.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="matches" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/></proto></example><example role="signature"><proto name="matches" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="flags" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of calling the first version of this function (omitting the argument\n                <code>$flags</code>) is the same as the effect of calling the second version with the\n                <code>$flags</code> argument set to a zero-length string. Flags are defined in\n                <specref ref="flags"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$input</code> is the empty sequence, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns <code>true</code> if <code>$input</code> or some substring of\n                <code>$input</code> matches the regular expression supplied as <code>$pattern</code>.\n             Otherwise, the function returns <code>false</code>. The matching rules are influenced by\n             the value of <code>$flags</code> if present. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0002"/> if the value of\n                <code>$pattern</code> is invalid according to the rules described in <specref ref="regex-syntax"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0001"/> if the value of\n                <code>$flags</code> is invalid according to the rules described in <specref ref="flags"/>. </p></div>\n',summary:"<p>  Returns true if the supplied string matches a given regular expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:""},{name:"pattern",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:3,name:"matches",qname:"fn:matches",signature:"($input as xs:string?, $pattern as xs:string, $flags as xs:string) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the supplied string matches a given regular expression.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="matches" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/></proto></example><example role="signature"><proto name="matches" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="flags" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of calling the first version of this function (omitting the argument\n                <code>$flags</code>) is the same as the effect of calling the second version with the\n                <code>$flags</code> argument set to a zero-length string. Flags are defined in\n                <specref ref="flags"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$input</code> is the empty sequence, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns <code>true</code> if <code>$input</code> or some substring of\n                <code>$input</code> matches the regular expression supplied as <code>$pattern</code>.\n             Otherwise, the function returns <code>false</code>. The matching rules are influenced by\n             the value of <code>$flags</code> if present. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0002"/> if the value of\n                <code>$pattern</code> is invalid according to the rules described in <specref ref="regex-syntax"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0001"/> if the value of\n                <code>$flags</code> is invalid according to the rules described in <specref ref="flags"/>. </p></div>\n',summary:"<p>  Returns true if the supplied string matches a given regular expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:""},{name:"pattern",type:"xs:string",occurrence:null,description:""},{name:"flags",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"max",qname:"fn:max",signature:"($arg as xs:anyAtomicType*) as xs:anyAtomicType? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a value that is equal to the highest value appearing in the input\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="max" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/></proto></example><example role="signature"><proto name="max" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following rules are applied to the input sequence <code>$arg</code>:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>Values of type <code>xs:untypedAtomic</code> in <code>$arg</code> are cast to\n                      <code>xs:double</code>.</p></item><item><!--Text replaced by erratum E27 change 1"--><p diff="chg" at="A-E27">Numeric and <code>xs:anyURI</code> values are converted to\n                   the least common type reachable by a combination of type promotion and subtype\n                   substitution. See <xspecref spec="XP30" ref="promotion"/> and <xspecref spec="XP30" ref="mapping"/>.</p><!--End of text replaced by erratum E27--></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The items in the resulting sequence may be reordered in an arbitrary order. The\n             resulting sequence is referred to below as the converted sequence. The function returns\n             an item from the converted sequence rather than the input sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence is empty, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">All items in the <phrase diff="chg" at="A-E47">converted sequence must be\n                derived</phrase> from a single base type for which the <code>le</code> operator is\n             defined. In addition, the values in the sequence must have a total order. If date/time\n             values do not have a timezone, they are considered to have the implicit timezone\n             provided by the dynamic context for the purpose of comparison. Duration values must\n             either all be <code>xs:yearMonthDuration</code> values or must all be\n                <code>xs:dayTimeDuration</code> values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence contains the value <code>NaN</code>, the value\n                <code>NaN</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the items in the <phrase diff="chg" at="A-E47">converted sequence</phrase> are of\n             type <code>xs:string</code> or types derived by restriction from <code>xs:string</code>,\n             then the determination of the item with the smallest value is made according to the\n             collation that is used. If the type of the items in the <phrase diff="chg" at="A-E47">converted sequence</phrase> is not <code>xs:string</code> and\n                <code>$collation</code> is specified, the collation is ignored.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the result of the expression:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n    if (every $v in $c satisfies $c[1] ge $v)\n    then $c[1]\n    else fn:max(fn:subsequence($c, 2))</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">evaluated with <code>$collation</code> as the default collation if specified, and with\n                <code>$c</code> as the converted sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains\n             items of incompatible types, as described above.</p></div>\n',summary:"<p>  Returns a value that is equal to the highest value appearing in the input\n             sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"*",description:""}],returns:{type:"xs:anyAtomicType?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"max",qname:"fn:max",signature:"($arg as xs:anyAtomicType*, $collation as xs:string) as xs:anyAtomicType? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a value that is equal to the highest value appearing in the input\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="max" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/></proto></example><example role="signature"><proto name="max" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following rules are applied to the input sequence <code>$arg</code>:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>Values of type <code>xs:untypedAtomic</code> in <code>$arg</code> are cast to\n                      <code>xs:double</code>.</p></item><item><!--Text replaced by erratum E27 change 1"--><p diff="chg" at="A-E27">Numeric and <code>xs:anyURI</code> values are converted to\n                   the least common type reachable by a combination of type promotion and subtype\n                   substitution. See <xspecref spec="XP30" ref="promotion"/> and <xspecref spec="XP30" ref="mapping"/>.</p><!--End of text replaced by erratum E27--></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The items in the resulting sequence may be reordered in an arbitrary order. The\n             resulting sequence is referred to below as the converted sequence. The function returns\n             an item from the converted sequence rather than the input sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence is empty, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">All items in the <phrase diff="chg" at="A-E47">converted sequence must be\n                derived</phrase> from a single base type for which the <code>le</code> operator is\n             defined. In addition, the values in the sequence must have a total order. If date/time\n             values do not have a timezone, they are considered to have the implicit timezone\n             provided by the dynamic context for the purpose of comparison. Duration values must\n             either all be <code>xs:yearMonthDuration</code> values or must all be\n                <code>xs:dayTimeDuration</code> values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence contains the value <code>NaN</code>, the value\n                <code>NaN</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the items in the <phrase diff="chg" at="A-E47">converted sequence</phrase> are of\n             type <code>xs:string</code> or types derived by restriction from <code>xs:string</code>,\n             then the determination of the item with the smallest value is made according to the\n             collation that is used. If the type of the items in the <phrase diff="chg" at="A-E47">converted sequence</phrase> is not <code>xs:string</code> and\n                <code>$collation</code> is specified, the collation is ignored.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the result of the expression:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n    if (every $v in $c satisfies $c[1] ge $v)\n    then $c[1]\n    else fn:max(fn:subsequence($c, 2))</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">evaluated with <code>$collation</code> as the default collation if specified, and with\n                <code>$c</code> as the converted sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains\n             items of incompatible types, as described above.</p></div>\n',summary:"<p>  Returns a value that is equal to the highest value appearing in the input\n             sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"*",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:anyAtomicType?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"min",qname:"fn:min",signature:"($arg as xs:anyAtomicType*) as xs:anyAtomicType? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a value that is equal to the lowest value appearing in the input\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="min" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/></proto></example><example role="signature"><proto name="min" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following rules are applied to the input sequence:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>Values of type <code>xs:untypedAtomic</code> in <code>$arg</code> are cast to\n                      <code>xs:double</code>.</p></item><item><!--Text replaced by erratum E27 change 2"--><p diff="chg" at="A-E27">Numeric and <code>xs:anyURI</code> values are converted to\n                   the least common type reachable by a combination of type promotion and subtype\n                   substitution. See <xspecref spec="XP30" ref="promotion"/> and <xspecref spec="XP30" ref="mapping"/>.</p><!--End of text replaced by erratum E27--></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The items in the resulting sequence may be reordered in an arbitrary order. The\n             resulting sequence is referred to below as the converted sequence. The function returns\n             an item from the converted sequence rather than the input sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence is empty, the empty sequence is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">All items in the <phrase diff="chg" at="A-E47">converted sequence must be\n                derived</phrase> from a single base type for which the <code>le</code> operator is\n             defined. In addition, the values in the sequence must have a total order. If date/time\n             values do not have a timezone, they are considered to have the implicit timezone\n             provided by the dynamic context for the purpose of comparison. Duration values must\n             either all be <code>xs:yearMonthDuration</code> values or must all be\n                <code>xs:dayTimeDuration</code> values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence contains the value <code>NaN</code>, the value\n                <code>NaN</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the items in the <phrase diff="chg" at="A-E47">converted sequence</phrase> are of\n             type <code>xs:string</code> or types derived by restriction from <code>xs:string</code>,\n             then the determination of the item with the smallest value is made according to the\n             collation that is used. If the type of the items in the <phrase diff="chg" at="A-E47">converted sequence</phrase> is not <code>xs:string</code> and\n                <code>$collation</code> is specified, the collation is ignored.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the result of the expression:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n    if (every $v in $c satisfies $c[1] le $v)\n    then $c[1]\n    else fn:min(fn:subsequence($c, 2))</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">evaluated with <code>$collation</code> as the default collation if specified, and with\n                <code>$c</code> as the converted sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains\n             items of incompatible types, as described above.</p></div>\n',summary:"<p>  Returns a value that is equal to the lowest value appearing in the input\n             sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"*",description:""}],returns:{type:"xs:anyAtomicType?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"min",qname:"fn:min",signature:"($arg as xs:anyAtomicType*, $collation as xs:string) as xs:anyAtomicType? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a value that is equal to the lowest value appearing in the input\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="min" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/></proto></example><example role="signature"><proto name="min" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri, and implicit timezone.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following rules are applied to the input sequence:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>Values of type <code>xs:untypedAtomic</code> in <code>$arg</code> are cast to\n                      <code>xs:double</code>.</p></item><item><!--Text replaced by erratum E27 change 2"--><p diff="chg" at="A-E27">Numeric and <code>xs:anyURI</code> values are converted to\n                   the least common type reachable by a combination of type promotion and subtype\n                   substitution. See <xspecref spec="XP30" ref="promotion"/> and <xspecref spec="XP30" ref="mapping"/>.</p><!--End of text replaced by erratum E27--></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The items in the resulting sequence may be reordered in an arbitrary order. The\n             resulting sequence is referred to below as the converted sequence. The function returns\n             an item from the converted sequence rather than the input sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence is empty, the empty sequence is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">All items in the <phrase diff="chg" at="A-E47">converted sequence must be\n                derived</phrase> from a single base type for which the <code>le</code> operator is\n             defined. In addition, the values in the sequence must have a total order. If date/time\n             values do not have a timezone, they are considered to have the implicit timezone\n             provided by the dynamic context for the purpose of comparison. Duration values must\n             either all be <code>xs:yearMonthDuration</code> values or must all be\n                <code>xs:dayTimeDuration</code> values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence contains the value <code>NaN</code>, the value\n                <code>NaN</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the items in the <phrase diff="chg" at="A-E47">converted sequence</phrase> are of\n             type <code>xs:string</code> or types derived by restriction from <code>xs:string</code>,\n             then the determination of the item with the smallest value is made according to the\n             collation that is used. If the type of the items in the <phrase diff="chg" at="A-E47">converted sequence</phrase> is not <code>xs:string</code> and\n                <code>$collation</code> is specified, the collation is ignored.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the result of the expression:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n    if (every $v in $c satisfies $c[1] le $v)\n    then $c[1]\n    else fn:min(fn:subsequence($c, 2))</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">evaluated with <code>$collation</code> as the default collation if specified, and with\n                <code>$c</code> as the converted sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains\n             items of incompatible types, as described above.</p></div>\n',summary:"<p>  Returns a value that is equal to the lowest value appearing in the input\n             sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"*",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:anyAtomicType?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"minutes-from-dateTime",qname:"fn:minutes-from-dateTime",signature:"($arg as xs:dateTime?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the minute component of an <code>xs:dateTime</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="minutes-from-dateTime" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:dateTime?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> value between 0 and 59, both\n             inclusive, representing the minute component in the local value of\n             <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:minutes-from-dateTime(xs:dateTime("1999-05-31T13:20:00-05:00"))</code> returns <code>20</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:minutes-from-dateTime(xs:dateTime("1999-05-31T13:30:00+05:30"))</code> returns <code>30</code>.</p></div>\n',summary:"<p>  Returns the minute component of an  xs:dateTime .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:dateTime",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"minutes-from-duration",qname:"fn:minutes-from-duration",signature:"($arg as xs:duration?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the number of minutes in a duration.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="minutes-from-duration" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:duration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> representing the minutes\n             component in the value of <code>$arg</code>. The result is obtained by casting\n                <code>$arg</code> to an <code>xs:dayTimeDuration</code> (see <specref ref="casting-to-durations"/>) and then computing the minutes component as described\n             in <specref ref="canonical-dayTimeDuration"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a negative duration then the result will be negative..</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is an <code>xs:yearMonthDuration</code> the function returns 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:minutes-from-duration(xs:dayTimeDuration("P3DT10H"))</code> returns <code>0</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:minutes-from-duration(xs:dayTimeDuration("-P5DT12H30M"))</code> returns <code>-30</code>.</p></div>\n',summary:"<p>  Returns the number of minutes in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:duration",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"minutes-from-time",qname:"fn:minutes-from-time",signature:"($arg as xs:time?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the minutes component of an <code>xs:time</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="minutes-from-time" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:time?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> value between 0 and 59, both\n             inclusive, representing the value of the minutes component in the local value of\n                <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:minutes-from-time(xs:time("13:00:00Z"))</code> returns <code>0</code>.</p></div>\n',summary:"<p>  Returns the minutes component of an  xs:time .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:time",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"month-from-date",qname:"fn:month-from-date",signature:"($arg as xs:date?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the month component of an <code>xs:date</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="month-from-date" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:date?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> between 1 and 12, both\n             inclusive, representing the month component in the local value of <code>$arg</code>.\n          </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:month-from-date(xs:date("1999-05-31-05:00"))</code> returns <code>5</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:month-from-date(xs:date("2000-01-01+05:00"))</code> returns <code>1</code>.</p></div>\n',summary:"<p>  Returns the month component of an  xs:date .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:date",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"months-from-duration",qname:"fn:months-from-duration",signature:"($arg as xs:duration?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the number of months in a duration.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="months-from-duration" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:duration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> representing the months\n             component in the value of <code>$arg</code>. The result is obtained by casting\n                <code>$arg</code> to an <code>xs:yearMonthDuration</code> (see <specref ref="casting-to-durations"/>) and then computing the months component as described in\n                <specref ref="canonical-yearMonthDuration"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a negative duration then the result will be negative..</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is an <code>xs:dayTimeDuration</code> the function returns 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:months-from-duration(xs:yearMonthDuration("P20Y15M"))</code> returns <code>3</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:months-from-duration(xs:yearMonthDuration("-P20Y18M"))</code> returns <code>-6</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:months-from-duration(xs:dayTimeDuration("-P2DT15H0M0S"))</code> returns <code>0</code>.</p></div>\n',summary:"<p>  Returns the number of months in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:duration",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"name",qname:"fn:name",signature:"() as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the name of a node, as an <code>xs:string</code> that is either the\n             zero-length string, or has the lexical form of an <code>xs:QName</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="name" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="name" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is supplied and is the empty sequence, the function returns the\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the node identified by <code>$arg</code> has no name (that is, if it is a document\n             node, a comment, a text node, or a namespace node having no name), the function returns\n             the zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the value of the expression\n                <code>fn:string(fn:node-name($arg))</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the name of a node, as an  xs:string  that is either the\n             zero-length string, or has the lexical form of an  xs:QName .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"name",qname:"fn:name",signature:"($arg as node()?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the name of a node, as an <code>xs:string</code> that is either the\n             zero-length string, or has the lexical form of an <code>xs:QName</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="name" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="name" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is supplied and is the empty sequence, the function returns the\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the node identified by <code>$arg</code> has no name (that is, if it is a document\n             node, a comment, a text node, or a namespace node having no name), the function returns\n             the zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the value of the expression\n                <code>fn:string(fn:node-name($arg))</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the name of a node, as an  xs:string  that is either the\n             zero-length string, or has the lexical form of an  xs:QName .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"namespace-uri-for-prefix",qname:"fn:namespace-uri-for-prefix",signature:"($prefix as xs:string?, $element as element(*)) as xs:anyURI? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the namespace URI of one of the in-scope namespaces for\n                <code>$element</code>, identified by its namespace prefix.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="namespace-uri-for-prefix" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="prefix" type="xs:string?"/><arg name="element" type="element()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$element</code> has an in-scope namespace whose namespace prefix is equal to\n                <code>$prefix</code>, the function returns the namespace URI of that namespace.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$element</code> has no in-scope namespace whose namespace prefix is equal to\n             <code>$prefix</code>, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="I">If <code>$prefix</code> is the zero-length string or the empty\n             sequence, then if <code>$element</code> has a default namespace (that is, a namespace\n             node with no name), the function returns the namespace URI of the default namespace. If\n                <code>$element</code> has no default namespace, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Prefixes are equal only if their Unicode codepoints match exactly.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">let <code>$e</code> := <eg xml:space="preserve">\n &lt;z:a xmlns="http://example.org/one" xmlns:z="http://example.org/two"&gt;\n   &lt;b xmlns=""/&gt;\n &lt;/z:a&gt;</eg></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:namespace-uri-for-prefix("z", $e)</code> returns <code>"http://example.org/two"</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:namespace-uri-for-prefix("", $e)</code> returns <code>"http://example.org/one"</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:namespace-uri-for-prefix((), $e)</code> returns <code>"http://example.org/one"</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:namespace-uri-for-prefix("xml", $e)</code> returns <code>"http://www.w3.org/XML/1998/namespace"</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:namespace-uri-for-prefix("xml", $e)</code> returns <code>"http://www.w3.org/XML/1998/namespace"</code>.</p></div>\n',summary:"<p>  Returns the namespace URI of one of the in-scope namespaces for\n                 $element , identified by its namespace prefix.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"prefix",type:"xs:string",occurrence:"?",description:""},{name:"element",type:"element(*)",occurrence:null,description:""}],returns:{type:"xs:anyURI?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"namespace-uri-from-QName",qname:"fn:namespace-uri-from-QName",signature:"($arg as xs:QName?) as xs:anyURI? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the namespace URI part of the supplied QName.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="namespace-uri-from-QName" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:QName?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:anyURI</code> representing the namespace URI\n             part of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is in no namespace, the function returns the zero-length\n                <code>xs:anyURI</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:namespace-uri-from-QName(fn:QName("http://www.example.com/example",\n                   "person"))</code> returns <code>xs:anyURI("http://www.example.com/example")</code>.</p></div>\n',summary:"<p>  Returns the namespace URI part of the supplied QName.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:QName",occurrence:"?",description:""}],returns:{type:"xs:anyURI?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"namespace-uri",qname:"fn:namespace-uri",signature:"() as xs:anyURI external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E15">Returns the namespace URI part of the name of\n                <code>$arg</code>, as an <code>xs:anyURI</code> value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="namespace-uri" return-type="xs:anyURI" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="namespace-uri" return-type="xs:anyURI" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context node (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the node identified by <code>$arg</code> is neither an element nor an attribute node,\n             or if it is an element or attribute node whose expanded-QName (as determined by the\n                <code>dm:node-name</code> accessor in the <xspecref spec="DM30" ref="dm-node-name"/>)\n             is in no namespace, then the function returns the zero-length <code>xs:anyURI</code>\n             value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the result will be the namespace URI part of the expanded-QName of the node\n             identified by <code>$arg</code>, as determined by the <code>dm:node-name</code> accessor\n             defined in <xspecref spec="DM30" ref="dm-node-name"/>), returned as an\n                <code>xs:anyURI</code> value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the namespace URI part of the name of\n                 $arg , as an  xs:anyURI  value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyURI",description:""},errors:[]},{isDocumented:!0,arity:1,name:"namespace-uri",qname:"fn:namespace-uri",signature:"($arg as node()?) as xs:anyURI external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E15">Returns the namespace URI part of the name of\n                <code>$arg</code>, as an <code>xs:anyURI</code> value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="namespace-uri" return-type="xs:anyURI" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="namespace-uri" return-type="xs:anyURI" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context node (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the node identified by <code>$arg</code> is neither an element nor an attribute node,\n             or if it is an element or attribute node whose expanded-QName (as determined by the\n                <code>dm:node-name</code> accessor in the <xspecref spec="DM30" ref="dm-node-name"/>)\n             is in no namespace, then the function returns the zero-length <code>xs:anyURI</code>\n             value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the result will be the namespace URI part of the expanded-QName of the node\n             identified by <code>$arg</code>, as determined by the <code>dm:node-name</code> accessor\n             defined in <xspecref spec="DM30" ref="dm-node-name"/>), returned as an\n                <code>xs:anyURI</code> value.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the namespace URI part of the name of\n                 $arg , as an  xs:anyURI  value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:"?",description:""}],returns:{type:"xs:anyURI",description:""},errors:[]},{isDocumented:!0,arity:0,name:"nilled",qname:"fn:nilled",signature:"() as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true for an element that is <term>nilled</term>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="nilled" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="nilled" return-type="xs:boolean?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise the function returns the result of the <code>dm:nilled</code> accessor as\n             defined in <bibref ref="xpath-datamodel-30"/> (see <xspecref spec="DM30" ref="dm-nilled"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="I">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns true for an element that is  nilled .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"nilled",qname:"fn:nilled",signature:"($arg as node()?) as xs:boolean? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true for an element that is <term>nilled</term>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="nilled" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="nilled" return-type="xs:boolean?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the argument is omitted, it defaults to the context item (<code>.</code>). The\n             behavior of the function if the argument is omitted is exactly the same as if the\n             context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise the function returns the result of the <code>dm:nilled</code> accessor as\n             defined in <bibref ref="xpath-datamodel-30"/> (see <xspecref spec="DM30" ref="dm-nilled"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="I">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns true for an element that is  nilled .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:"?",description:""}],returns:{type:"xs:boolean?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"node-name",qname:"fn:node-name",signature:"() as xs:QName? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the name of a node, as an <code>xs:QName</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="node-name" return-type="xs:QName?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="node-name" return-type="xs:QName?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="F">If the argument is omitted, it defaults to the context item\n                (<code>.</code>). The behavior of the function if the argument is omitted is exactly\n             the same as if the context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the empty sequence is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the result of the <code>dm:node-name</code> accessor as\n             defined in <bibref ref="xpath-datamodel-30"/> (see <xspecref spec="DM30" ref="dm-node-name"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="I">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the name of a node, as an  xs:QName .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"node-name",qname:"fn:node-name",signature:"($arg as node()?) as xs:QName? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the name of a node, as an <code>xs:QName</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="node-name" return-type="xs:QName?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="node-name" return-type="xs:QName?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="F">If the argument is omitted, it defaults to the context item\n                (<code>.</code>). The behavior of the function if the argument is omitted is exactly\n             the same as if the context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the empty sequence is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the result of the <code>dm:node-name</code> accessor as\n             defined in <bibref ref="xpath-datamodel-30"/> (see <xspecref spec="DM30" ref="dm-node-name"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="I">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the name of a node, as an  xs:QName .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:"?",description:""}],returns:{type:"xs:QName?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"normalize-space",qname:"fn:normalize-space",signature:"() as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of <code>$arg</code> with leading and trailing whitespace\n             removed, and sequences of internal whitespace reduced to a single space character.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="normalize-space" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="normalize-space" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the function returns the\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a string constructed by stripping leading and trailing whitespace\n             from the value of <code>$arg</code>, and replacing sequences of one or more adjacent\n             whitespace characters with a single space, <code>#x20</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The whitespace characters are defined in the metasymbol S (Production 3) of <bibref ref="REC-xml"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E14">If no argument is supplied, then <code>$arg</code> defaults to the\n             string value (calculated using <code>fn:string</code>) of the context item\n                (<code>.</code>). </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If no argument is supplied and the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref> then a <phrase diff="add" at="dynamic">dynamic</phrase> error is raised: <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/>.</p></div>\n',summary:"<p>  Returns the value of  $arg  with leading and trailing whitespace\n             removed, and sequences of internal whitespace reduced to a single space character.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"normalize-space",qname:"fn:normalize-space",signature:"($arg as xs:string?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of <code>$arg</code> with leading and trailing whitespace\n             removed, and sequences of internal whitespace reduced to a single space character.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="normalize-space" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="normalize-space" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the function returns the\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a string constructed by stripping leading and trailing whitespace\n             from the value of <code>$arg</code>, and replacing sequences of one or more adjacent\n             whitespace characters with a single space, <code>#x20</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The whitespace characters are defined in the metasymbol S (Production 3) of <bibref ref="REC-xml"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E14">If no argument is supplied, then <code>$arg</code> defaults to the\n             string value (calculated using <code>fn:string</code>) of the context item\n                (<code>.</code>). </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If no argument is supplied and the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref> then a <phrase diff="add" at="dynamic">dynamic</phrase> error is raised: <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/>.</p></div>\n',summary:"<p>  Returns the value of  $arg  with leading and trailing whitespace\n             removed, and sequences of internal whitespace reduced to a single space character.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"normalize-unicode",qname:"fn:normalize-unicode",signature:"($arg as xs:string?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of <code>$arg</code> after applying Unicode\n             normalization.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="normalize-unicode" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example><example role="signature"><proto name="normalize-unicode" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/><arg name="normalizationForm" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the function returns the\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the single-argument version of the function is used, the result is the same as\n             calling the two-argument version with <code>$normalizationForm</code> set to the string\n             "NFC".</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the value of <code>$arg</code> normalized according to\n             the rules of the normalization form identified by the value of\n                <code>$normalizationForm</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effective value of <code>$normalizationForm</code> is the value of the expression\n                <code>fn:upper-case(fn:normalize-space($normalizationForm))</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="D">See <bibref ref="charmod-normalization"/> for a description of the\n             normalization forms.</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If the effective value of <code>$normalizationForm</code> is <quote>NFC</quote>,\n                   then the function returns the value of <code>$arg</code> converted to Unicode\n                   Normalization Form C (NFC).</p></item><item><p>If the effective value of <code>$normalizationForm</code> is <quote>NFD</quote>,\n                   then the function returns the value of <code>$arg</code> converted to Unicode\n                   Normalization Form D (NFD).</p></item><item><p>If the effective value of <code>$normalizationForm</code> is <quote>NFKC</quote>,\n                   then the function returns the value of <code>$arg</code> in Unicode Normalization\n                   Form KC (NFKC).</p></item><item><p>If the effective value of <code>$normalizationForm</code> is <quote>NFKD</quote>,\n                   then the function returns the value of <code>$arg</code> converted to Unicode\n                   Normalization Form KD (NFKD).</p></item><item><p>If the effective value of <code>$normalizationForm</code> is\n                      <quote>FULLY-NORMALIZED</quote>, then the function returns the value of\n                      <code>$arg</code> converted to fully normalized form. </p></item><item><p>If the effective value of <code>$normalizationForm</code> is the zero-length\n                   string, no normalization is performed and <code>$arg</code> is returned.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="D">Normalization forms NFC, NFD, NFKC, and NFKD, and the algorithms to be\n             used for converting a string to each of these forms, are defined in <bibref ref="Unicode-Normalization"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="D">The motivation for normalization form FULLY-NORMALIZED is explained in\n                <bibref ref="charmod-normalization"/>. However, as that specification did not\n             progress beyond working draft status, the normative specification is as follows:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="D"><item><p>A string is <term>fully-normalized</term> if (a) it is in normalization form NFC\n                   as defined in <bibref ref="Unicode-Normalization"/>, and (b) it does not start\n                   with a composing character.</p></item><item><p>A composing character is a character that is one or both of the following:</p><ulist><item><p>the second character in the canonical decomposition mapping of some\n                         character that is not listed in the Composition Exclusion Table defined in\n                            <bibref ref="Unicode-Normalization"/>;</p></item><item><p>of non-zero canonical combining class (as defined in <bibref ref="Unicode"/>).</p></item></ulist></item><item><p>A string is converted to FULLY-NORMALIZED form as follows:</p><ulist><item><p>if the first character in the string is a composing character, prepend a\n                         single space (x20);</p></item><item><p>convert the resulting string to normalization form NFC.</p></item></ulist></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" At="L">Conforming implementations <rfc2119>must</rfc2119> support normalization form "NFC" and\n                <rfc2119>may</rfc2119> support normalization forms "NFD", "NFKC", "NFKD", and\n             "FULLY-NORMALIZED". They <rfc2119>may</rfc2119> also support other normalization forms\n             with <termref def="implementation-defined">implementation-defined</termref> semantics. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">It is <termref def="dt-implementation-defined">implementation-defined</termref> which version of\n             Unicode (and therefore, of the normalization algorithms and their underlying\n             data) is supported by the implementation. See <bibref ref="Unicode-Normalization"/> for details of the\n             stability policy regarding changes to the normalization rules in future\n             versions of Unicode. If the input string contains codepoints that are\n             unassigned in the relevant version of Unicode, or for which no normalization\n             rules are defined, the <code>fn:normalize-unicode</code> function leaves such codepoints\n             unchanged. If the implementation supports the requested normalization form then\n             it <rfc2119>must</rfc2119> be able to handle every input string without raising an error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="CH" code="0003"/> if the effective value of the\n                <code>$normalizationForm</code> argument is not one of the values supported by the\n             implementation.</p></div>\n',summary:"<p>  Returns the value of  $arg  after applying Unicode\n             normalization.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"normalize-unicode",qname:"fn:normalize-unicode",signature:"($arg as xs:string?, $normalizationForm as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of <code>$arg</code> after applying Unicode\n             normalization.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="normalize-unicode" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example><example role="signature"><proto name="normalize-unicode" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/><arg name="normalizationForm" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the function returns the\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the single-argument version of the function is used, the result is the same as\n             calling the two-argument version with <code>$normalizationForm</code> set to the string\n             "NFC".</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the value of <code>$arg</code> normalized according to\n             the rules of the normalization form identified by the value of\n                <code>$normalizationForm</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effective value of <code>$normalizationForm</code> is the value of the expression\n                <code>fn:upper-case(fn:normalize-space($normalizationForm))</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="D">See <bibref ref="charmod-normalization"/> for a description of the\n             normalization forms.</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If the effective value of <code>$normalizationForm</code> is <quote>NFC</quote>,\n                   then the function returns the value of <code>$arg</code> converted to Unicode\n                   Normalization Form C (NFC).</p></item><item><p>If the effective value of <code>$normalizationForm</code> is <quote>NFD</quote>,\n                   then the function returns the value of <code>$arg</code> converted to Unicode\n                   Normalization Form D (NFD).</p></item><item><p>If the effective value of <code>$normalizationForm</code> is <quote>NFKC</quote>,\n                   then the function returns the value of <code>$arg</code> in Unicode Normalization\n                   Form KC (NFKC).</p></item><item><p>If the effective value of <code>$normalizationForm</code> is <quote>NFKD</quote>,\n                   then the function returns the value of <code>$arg</code> converted to Unicode\n                   Normalization Form KD (NFKD).</p></item><item><p>If the effective value of <code>$normalizationForm</code> is\n                      <quote>FULLY-NORMALIZED</quote>, then the function returns the value of\n                      <code>$arg</code> converted to fully normalized form. </p></item><item><p>If the effective value of <code>$normalizationForm</code> is the zero-length\n                   string, no normalization is performed and <code>$arg</code> is returned.</p></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="D">Normalization forms NFC, NFD, NFKC, and NFKD, and the algorithms to be\n             used for converting a string to each of these forms, are defined in <bibref ref="Unicode-Normalization"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="D">The motivation for normalization form FULLY-NORMALIZED is explained in\n                <bibref ref="charmod-normalization"/>. However, as that specification did not\n             progress beyond working draft status, the normative specification is as follows:</p><ulist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="D"><item><p>A string is <term>fully-normalized</term> if (a) it is in normalization form NFC\n                   as defined in <bibref ref="Unicode-Normalization"/>, and (b) it does not start\n                   with a composing character.</p></item><item><p>A composing character is a character that is one or both of the following:</p><ulist><item><p>the second character in the canonical decomposition mapping of some\n                         character that is not listed in the Composition Exclusion Table defined in\n                            <bibref ref="Unicode-Normalization"/>;</p></item><item><p>of non-zero canonical combining class (as defined in <bibref ref="Unicode"/>).</p></item></ulist></item><item><p>A string is converted to FULLY-NORMALIZED form as follows:</p><ulist><item><p>if the first character in the string is a composing character, prepend a\n                         single space (x20);</p></item><item><p>convert the resulting string to normalization form NFC.</p></item></ulist></item></ulist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" At="L">Conforming implementations <rfc2119>must</rfc2119> support normalization form "NFC" and\n                <rfc2119>may</rfc2119> support normalization forms "NFD", "NFKC", "NFKD", and\n             "FULLY-NORMALIZED". They <rfc2119>may</rfc2119> also support other normalization forms\n             with <termref def="implementation-defined">implementation-defined</termref> semantics. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">It is <termref def="dt-implementation-defined">implementation-defined</termref> which version of\n             Unicode (and therefore, of the normalization algorithms and their underlying\n             data) is supported by the implementation. See <bibref ref="Unicode-Normalization"/> for details of the\n             stability policy regarding changes to the normalization rules in future\n             versions of Unicode. If the input string contains codepoints that are\n             unassigned in the relevant version of Unicode, or for which no normalization\n             rules are defined, the <code>fn:normalize-unicode</code> function leaves such codepoints\n             unchanged. If the implementation supports the requested normalization form then\n             it <rfc2119>must</rfc2119> be able to handle every input string without raising an error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="CH" code="0003"/> if the effective value of the\n                <code>$normalizationForm</code> argument is not one of the values supported by the\n             implementation.</p></div>\n',summary:"<p>  Returns the value of  $arg  after applying Unicode\n             normalization.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""},{name:"normalizationForm",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"not",qname:"fn:not",signature:"($arg as item()*) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns <code>true</code> if the effective boolean value of <code>$arg</code>\n             is <code>false</code>, or <code>false</code> if it is <code>true</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="not" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The value of <code>$arg</code> is first reduced to an effective boolean value by\n             applying the <code>fn:boolean()</code> function. The function returns <code>true</code>\n             if the effective boolean value is <code>false</code>, or <code>false</code> if the\n             effective boolean value is <code>true</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:not(fn:true())</code> returns <code>false()</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:not("false")</code> returns <code>false()</code>.</p></div>\n',summary:"<p>  Returns  true  if the effective boolean value of  $arg \n             is  false , or  false  if it is  true .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:0,name:"number",qname:"fn:number",signature:"() as xs:double external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value indicated by <code>$arg</code> or, if <code>$arg</code> is\n             not specified, the context item after atomization, converted to an\n                <code>xs:double</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="number" return-type="xs:double" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="number" return-type="xs:double" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Calling the zero-argument version of the function is defined to give the same result as\n             calling the single-argument version with the context item (<code>.</code>). That is,\n                <code>fn:number()</code> is equivalent to <code>fn:number(.)</code>, as\n          defined by the rules that follow.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence or if <code>$arg</code> <phrase diff="del" at="L">or the context item</phrase>\n             cannot be converted to an <code>xs:double</code>, the <code>xs:double</code> value\n                <code>NaN</code> is returned. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, <code>$arg</code> <phrase diff="del" at="L">, or the context item after atomization,</phrase> is converted to an\n                <code>xs:double</code> following the rules of <specref ref="casting-to-double"/>. If\n             the conversion to <code>xs:double</code> fails, the <code>xs:double</code> value\n                <code>NaN</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="M">dynamic</phrase> error is raised <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/> if\n                <code>$arg</code> is omitted and the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">As a consequence of the rules given above, a type error occurs if the context\n          item cannot be atomized, or if the result of atomizing the context item is a sequence containing\n          more than one atomic value.</p></div>\n',summary:"<p>  Returns the value indicated by  $arg  or, if  $arg  is\n             not specified, the context item after atomization, converted to an\n                 xs:double .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:double",description:""},errors:[]},{isDocumented:!0,arity:1,name:"number",qname:"fn:number",signature:"($arg as xs:anyAtomicType?) as xs:double external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value indicated by <code>$arg</code> or, if <code>$arg</code> is\n             not specified, the context item after atomization, converted to an\n                <code>xs:double</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="number" return-type="xs:double" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="number" return-type="xs:double" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Calling the zero-argument version of the function is defined to give the same result as\n             calling the single-argument version with the context item (<code>.</code>). That is,\n                <code>fn:number()</code> is equivalent to <code>fn:number(.)</code>, as\n          defined by the rules that follow.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence or if <code>$arg</code> <phrase diff="del" at="L">or the context item</phrase>\n             cannot be converted to an <code>xs:double</code>, the <code>xs:double</code> value\n                <code>NaN</code> is returned. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, <code>$arg</code> <phrase diff="del" at="L">, or the context item after atomization,</phrase> is converted to an\n                <code>xs:double</code> following the rules of <specref ref="casting-to-double"/>. If\n             the conversion to <code>xs:double</code> fails, the <code>xs:double</code> value\n                <code>NaN</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="M">dynamic</phrase> error is raised <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/> if\n                <code>$arg</code> is omitted and the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">As a consequence of the rules given above, a type error occurs if the context\n          item cannot be atomized, or if the result of atomizing the context item is a sequence containing\n          more than one atomic value.</p></div>\n',summary:"<p>  Returns the value indicated by  $arg  or, if  $arg  is\n             not specified, the context item after atomization, converted to an\n                 xs:double .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"?",description:""}],returns:{type:"xs:double",description:""},errors:[]},{isDocumented:!0,arity:1,name:"one-or-more",qname:"fn:one-or-more",signature:"($arg as item()*) as item()+ external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns <code>$arg</code> if it contains one or more items. Otherwise, raises\n             an error. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="one-or-more" return-type="item()+" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Except in error cases, the function returns <code>$arg</code> unchanged.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0004"/> if <code>$arg</code> is an empty\n             sequence.</p></div>\n',summary:"<p>  Returns  $arg  if it contains one or more items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"item()+",description:""},errors:[]},{isDocumented:!0,arity:1,name:"outermost",qname:"fn:outermost",signature:"($nodes as node()*) as node()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns every node within the input sequence that has no ancestor that is itself a\n             member of the input sequence; the nodes are returned in document order with duplicates\n             eliminated.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="outermost" return-type="node()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="nodes" type="node()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of the function call <code>fn:outermost($nodes)</code> is defined to be\n             equivalent to the result of the expression <code diff="chg" at="L">$nodes[not(ancestor::node() intersect\n                $nodes)]/.</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">That is, the function takes as input a sequence of nodes, and returns every node within\n             the sequence that <phrase diff="chg" at="J">does not have another node within the sequence as an ancestor</phrase>; the nodes are\n             returned in document order with duplicates eliminated.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The formulation <code>$nodes except $nodes/descendant::node()</code> might appear to be\n             simpler, but does not correctly account for attribute nodes, as these are not\n             descendants of their parent element.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The motivation for the function was based on XSLT streaming use cases. There are cases\n             where the <bibref ref="xslt-30"/> streaming rules allow the construct\n                <code>outermost(//section)</code> but do not allow <code>//section</code>; the\n             function can therefore be useful in cases where it is known that sections will not be\n             nested, as well as cases where the application actually wishes to process all sections\n             except those that are nested within another.</p></div>\n',summary:"<p>  Returns every node within the input sequence that has no ancestor that is itself a\n             member of the input sequence; the nodes are returned in document order with duplicates\n             eliminated.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:""}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"parse-xml-fragment",qname:"fn:parse-xml-fragment",signature:"($arg as xs:string?) as document(element(*,xs:untyped)) external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function takes as input an XML external entity represented as a string,\n             and returns the document node at the root of an XDM tree representing the parsed\n             document fragment.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="parse-xml-fragment" return-type="document-node()?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The input must be a namespace-well-formed external general parsed entity. More specifically,\n             it must be a string conforming to the production rule <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="xml" ref="NT-extParsedEnt" xlink:type="simple">extParsedEnt</xnt> in <bibref ref="REC-xml"/>, it must contain no entity references other\n             than references to predefined entities,\n             and it must satisfy all the rules\n             of <bibref ref="REC-xml-names"/> for namespace-well-formed documents with the exception\n             that the rule requiring it to be a well-formed document is replaced by the rule requiring\n             it to be a well-formed external general parsed entity.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The string is parsed to form a sequence of nodes which\n             become children of the new document node, in the same way as the content of any element\n             is converted into a sequence of children for the resulting element node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Schema validation is <emph>not</emph> invoked, which means that the nodes in the\n             returned document will all be untyped.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The precise process used to construct the XDM instance is <termref def="implementation-defined"/>. In\n             particular, it is implementation-defined whether an XML 1.0 or XML 1.1 parser is\n             used.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="L">The Static Base URI from the static context of the <code>fn:parse-xml-fragment</code> function call\n             is used as the base URI of the document node\n             that is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The document URI of the returned node is <termref def="absent">absent</termref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function is <emph>not</emph>\n             <termref def="deterministic">deterministic</termref>: that is, if the function is called\n             twice with the same arguments, it is <termref def="implementation-dependent">implementation-dependent</termref> whether the same node is returned on both\n                occasions.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0006"/> if the content of\n                <code>$arg</code> is not a well-formed external general parsed entity,\n             if it contains entity references other than references to predefined entities, or if a document that\n             incorporates this well-formed parsed entity would not be namespace-well-formed.</p></div>\n',summary:"<p>  This function takes as input an XML external entity represented as a string,\n             and returns the document node at the root of an XDM tree representing the parsed\n             document fragment.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"document(element(*,xs:untyped))",description:""},errors:[]},{isDocumented:!0,arity:1,name:"parse-xml",qname:"fn:parse-xml",signature:"($arg as xs:string?) as document(element(*,xs:untyped)) external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function takes as input an XML document represented as a string, and\n             returns the document node at the root of an XDM tree representing the parsed\n             document.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="parse-xml" return-type="document-node(element(*))?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="G">If <code>$arg</code> is the empty sequence, the function returns the\n             empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The precise process used to construct the XDM instance is <termref def="implementation-defined"/>. In\n             particular, it is implementation-defined whether DTD and/or schema validation is invoked, and it is\n             implementation-defined whether an XML 1.0 or XML 1.1 parser is used.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The Static Base URI property from the static context of the\n             <code>fn:parse-xml</code> function call is used both as the base URI used by the XML parser to resolve\n             relative entity references within the document, and as the base URI of the document node\n             that is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The document URI of the returned node is <termref def="absent">absent</termref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function is <emph>not</emph>\n             <termref def="deterministic">deterministic</termref>: that is, if the function is called\n             twice with the same arguments, it is <termref def="implementation-dependent">implementation-dependent</termref> whether the same node is returned on both\n             occasions.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0006"/> if the content of\n                <code>$arg</code> is not a well-formed and namespace-well-formed XML document.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="G">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0006"/> if DTD-based\n             validation is carried out and the content of <code>$arg</code> is not valid against its\n             DTD.</p></div>\n',summary:"<p>  This function takes as input an XML document represented as a string, and\n             returns the document node at the root of an XDM tree representing the parsed\n             document.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"document(element(*,xs:untyped))",description:""},errors:[]},{isDocumented:!0,arity:2,name:"parse-xml",qname:"fn:parse-xml",signature:"($arg as xs:string?, $baseURI as xs:string) as document(element(*,xs:untyped)) external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function takes as input an XML document represented as a string, and\n             returns the document node at the root of an XDM tree representing the parsed\n             document.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="parse-xml" return-type="document-node(element(*))?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="G">If <code>$arg</code> is the empty sequence, the function returns the\n             empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The precise process used to construct the XDM instance is <termref def="implementation-defined"/>. In\n             particular, it is implementation-defined whether DTD and/or schema validation is invoked, and it is\n             implementation-defined whether an XML 1.0 or XML 1.1 parser is used.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The Static Base URI property from the static context of the\n             <code>fn:parse-xml</code> function call is used both as the base URI used by the XML parser to resolve\n             relative entity references within the document, and as the base URI of the document node\n             that is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The document URI of the returned node is <termref def="absent">absent</termref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function is <emph>not</emph>\n             <termref def="deterministic">deterministic</termref>: that is, if the function is called\n             twice with the same arguments, it is <termref def="implementation-dependent">implementation-dependent</termref> whether the same node is returned on both\n             occasions.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0006"/> if the content of\n                <code>$arg</code> is not a well-formed and namespace-well-formed XML document.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="G">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0006"/> if DTD-based\n             validation is carried out and the content of <code>$arg</code> is not valid against its\n             DTD.</p></div>\n',summary:"<p>  This function takes as input an XML document represented as a string, and\n             returns the document node at the root of an XDM tree representing the parsed\n             document.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""},{name:"baseURI",type:"xs:string",occurrence:null,description:""}],returns:{type:"document(element(*,xs:untyped))",description:""},errors:[]},{isDocumented:!0,arity:0,name:"position",qname:"fn:position",signature:"() as xs:integer external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the context position from the dynamic context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="position" return-type="xs:integer" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the context position from the dynamic context. (See <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.)</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="M">dynamic</phrase> error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/> if the\n             context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p></div>\n',summary:"<p>  Returns the context position from the dynamic context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:1,name:"prefix-from-QName",qname:"fn:prefix-from-QName",signature:"($arg as xs:QName?) as xs:NCName? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the prefix component of the supplied QName.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="prefix-from-QName" return-type="xs:NCName?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:QName?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> has no prefix component the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:NCName</code> representing the prefix\n             component of <code>$arg</code>.</p></div>\n',summary:"<p>  Returns the prefix component of the supplied QName.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:QName",occurrence:"?",description:""}],returns:{type:"xs:NCName?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"remove",qname:"fn:remove",signature:"($target as item()*, $position as xs:integer) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a new sequence containing all the items of <code>$target</code> except\n             the item at position <code>$position</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="remove" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="target" type="item()*"/><arg name="position" type="xs:integer"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence consisting of all items of <code>$target</code> whose\n             index is less than <code>$position</code>, followed by all items of <code>$target</code>\n             whose index is greater than <code>$position</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$position</code> is less than 1 or greater than the number of items in\n                <code>$target</code>, <code>$target</code> is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$target</code> is the empty sequence, the empty sequence is returned.</p></div>\n',summary:"<p>  Returns a new sequence containing all the items of  $target  except\n             the item at position  $position .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"target",type:"item()",occurrence:"*",description:""},{name:"position",type:"xs:integer",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"replace",qname:"fn:replace",signature:"($input as xs:string?, $pattern as xs:string, $replacement as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string produced from the input string by replacing any substrings\n             that match a given regular expression with a supplied replacement string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="replace" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="replacement" type="xs:string"/></proto></example><example role="signature"><proto name="replace" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="replacement" type="xs:string"/><arg name="flags" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of calling the first version of this function (omitting the argument\n                <code>$flags</code>) is the same as the effect of calling the second version with the\n                <code>$flags</code> argument set to a zero-length string. Flags are defined in\n                <specref ref="flags"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$flags</code> argument is interpreted in the same manner as for the\n                <code>fn:matches</code> function. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$input</code> is the empty sequence, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the <code>xs:string</code> that is obtained by replacing each\n             non-overlapping substring of <code>$input</code> that matches the given\n                <code>$pattern</code> with an occurrence of the <code>$replacement</code> string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If two overlapping substrings of <code>$input</code> both match the\n                <code>$pattern</code>, then only the first one (that is, the one whose first <termref def="character">character</termref> comes first in the <code>$input</code> string) is\n             replaced.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">If the <code>q</code> flag is present, the replacement string is used\n                <emph>as is</emph>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><phrase diff="add" at="B">Otherwise,</phrase> within the <code>$replacement</code>\n             string, a variable <code>$N</code> may be used to refer to the substring captured by the\n             Nth parenthesized sub-expression in the regular expression. For each match of the\n             pattern, these variables are assigned the value of the content matched by the relevant\n             sub-expression, and the modified replacement string is then substituted for the <termref def="character">characters</termref> in <code>$input</code> that matched the pattern.\n                <code>$0</code> refers to the substring captured by the regular expression as a\n             whole.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">More specifically, the rules are as follows, where <code>S</code> is the number of\n             parenthesized sub-expressions in the regular expression, and <code>N</code> is the\n             decimal number formed by taking all the digits that consecutively follow the\n                <code>$</code> character:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If <code>N</code>=<code>0</code>, then the variable is replaced by the substring\n                   matched by the regular expression as a whole.</p></item><item><p>If <code>1</code>&lt;=<code>N</code>&lt;=<code>S</code>, then the variable is\n                   replaced by the substring captured by the Nth parenthesized sub-expression. If the\n                      <code>Nth</code> parenthesized sub-expression was not matched, then the\n                   variable is replaced by the zero-length string.</p></item><item><p>If <code>S</code>&lt;<code>N</code>&lt;=<code>9</code>, then the variable is\n                   replaced by the zero-length string.</p></item><item><p>Otherwise (if <code>N</code>&gt;<code>S</code> and\n                      <code>N</code>&gt;<code>9</code>), the last digit of <code>N</code> is taken to\n                   be a literal character to be included "as is" in the replacement string, and the\n                   rules are reapplied using the number <code>N</code> formed by stripping off this\n                   last digit.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For example, if the replacement string is <quote>\n                <code>$23</code>\n             </quote> and there are 5 substrings, the result contains the value of the substring that\n             matches the second sub-expression, followed by the digit <quote>\n                <code>3</code>\n             </quote>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="B">Unless the <code>q</code> flag is used, a literal <code>$</code>\n             character within the replacement string must be written as <code>\\$</code>, and a\n             literal <code>\\</code> character must be written as <code>\\\\</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If two alternatives within the pattern both match at the same position in the\n                <code>$input</code>, then the match that is chosen is the one matched by the first\n             alternative. For example:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:replace("abcd", "(ab)|(a)", "[1=$1][2=$2]") returns "[1=ab][2=]cd"</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0002"/> if the value of\n                <code>$pattern</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0001"/> if the value of\n                <code>$flags</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0003"/> if the pattern matches a\n             zero-length string, that is, if the expression <code>fn:matches("", $pattern,\n                $flags)</code> returns <code>true</code>. It is not an error, however, if a captured\n             substring is zero-length.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0004"/> if the value of\n                <code>$replacement</code> contains a "<code>$</code>" character that is not\n             immediately followed by a digit <code>0-9</code> and not immediately preceded by a\n             "\\".</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0004"/> if the value of\n                <code>$replacement</code> contains a "<code>\\</code>" character that is not part of a\n                "<code>\\\\</code>" pair, unless it is immediately followed by a "<code>$</code>"\n             character.</p></div>\n',summary:"<p>  Returns a string produced from the input string by replacing any substrings\n             that match a given regular expression with a supplied replacement string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:""},{name:"pattern",type:"xs:string",occurrence:null,description:""},{name:"replacement",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:4,name:"replace",qname:"fn:replace",signature:"($input as xs:string?, $pattern as xs:string, $replacement as xs:string, $flags as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string produced from the input string by replacing any substrings\n             that match a given regular expression with a supplied replacement string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="replace" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="replacement" type="xs:string"/></proto></example><example role="signature"><proto name="replace" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="replacement" type="xs:string"/><arg name="flags" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of calling the first version of this function (omitting the argument\n                <code>$flags</code>) is the same as the effect of calling the second version with the\n                <code>$flags</code> argument set to a zero-length string. Flags are defined in\n                <specref ref="flags"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$flags</code> argument is interpreted in the same manner as for the\n                <code>fn:matches</code> function. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$input</code> is the empty sequence, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the <code>xs:string</code> that is obtained by replacing each\n             non-overlapping substring of <code>$input</code> that matches the given\n                <code>$pattern</code> with an occurrence of the <code>$replacement</code> string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If two overlapping substrings of <code>$input</code> both match the\n                <code>$pattern</code>, then only the first one (that is, the one whose first <termref def="character">character</termref> comes first in the <code>$input</code> string) is\n             replaced.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">If the <code>q</code> flag is present, the replacement string is used\n                <emph>as is</emph>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><phrase diff="add" at="B">Otherwise,</phrase> within the <code>$replacement</code>\n             string, a variable <code>$N</code> may be used to refer to the substring captured by the\n             Nth parenthesized sub-expression in the regular expression. For each match of the\n             pattern, these variables are assigned the value of the content matched by the relevant\n             sub-expression, and the modified replacement string is then substituted for the <termref def="character">characters</termref> in <code>$input</code> that matched the pattern.\n                <code>$0</code> refers to the substring captured by the regular expression as a\n             whole.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">More specifically, the rules are as follows, where <code>S</code> is the number of\n             parenthesized sub-expressions in the regular expression, and <code>N</code> is the\n             decimal number formed by taking all the digits that consecutively follow the\n                <code>$</code> character:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If <code>N</code>=<code>0</code>, then the variable is replaced by the substring\n                   matched by the regular expression as a whole.</p></item><item><p>If <code>1</code>&lt;=<code>N</code>&lt;=<code>S</code>, then the variable is\n                   replaced by the substring captured by the Nth parenthesized sub-expression. If the\n                      <code>Nth</code> parenthesized sub-expression was not matched, then the\n                   variable is replaced by the zero-length string.</p></item><item><p>If <code>S</code>&lt;<code>N</code>&lt;=<code>9</code>, then the variable is\n                   replaced by the zero-length string.</p></item><item><p>Otherwise (if <code>N</code>&gt;<code>S</code> and\n                      <code>N</code>&gt;<code>9</code>), the last digit of <code>N</code> is taken to\n                   be a literal character to be included "as is" in the replacement string, and the\n                   rules are reapplied using the number <code>N</code> formed by stripping off this\n                   last digit.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For example, if the replacement string is <quote>\n                <code>$23</code>\n             </quote> and there are 5 substrings, the result contains the value of the substring that\n             matches the second sub-expression, followed by the digit <quote>\n                <code>3</code>\n             </quote>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="B">Unless the <code>q</code> flag is used, a literal <code>$</code>\n             character within the replacement string must be written as <code>\\$</code>, and a\n             literal <code>\\</code> character must be written as <code>\\\\</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If two alternatives within the pattern both match at the same position in the\n                <code>$input</code>, then the match that is chosen is the one matched by the first\n             alternative. For example:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:replace("abcd", "(ab)|(a)", "[1=$1][2=$2]") returns "[1=ab][2=]cd"</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0002"/> if the value of\n                <code>$pattern</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0001"/> if the value of\n                <code>$flags</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0003"/> if the pattern matches a\n             zero-length string, that is, if the expression <code>fn:matches("", $pattern,\n                $flags)</code> returns <code>true</code>. It is not an error, however, if a captured\n             substring is zero-length.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0004"/> if the value of\n                <code>$replacement</code> contains a "<code>$</code>" character that is not\n             immediately followed by a digit <code>0-9</code> and not immediately preceded by a\n             "\\".</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0004"/> if the value of\n                <code>$replacement</code> contains a "<code>\\</code>" character that is not part of a\n                "<code>\\\\</code>" pair, unless it is immediately followed by a "<code>$</code>"\n             character.</p></div>\n',summary:"<p>  Returns a string produced from the input string by replacing any substrings\n             that match a given regular expression with a supplied replacement string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:""},{name:"pattern",type:"xs:string",occurrence:null,description:""},{name:"replacement",type:"xs:string",occurrence:null,description:""},{name:"flags",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"resolve-QName",qname:"fn:resolve-QName",signature:"($qname as xs:string?, $element as element(*)) as xs:QName? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns an <code>xs:QName</code> value (that is, an expanded-QName) by taking\n             an <code>xs:string</code> that has the lexical form of an <code>xs:QName</code> (a\n             string in the form "prefix:local-name" or "local-name") and resolving it using the\n             in-scope namespaces for a given element.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="resolve-QName" return-type="xs:QName?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="qname" type="xs:string?"/><arg name="element" type="element()"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$qname</code> is the empty sequence, returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">More specifically, the function searches the namespace bindings of <code>$element</code>\n             for a binding whose name matches the prefix of <code>$qname</code>, or the zero-length\n             string if it has no prefix, and constructs an expanded-QName whose local name is taken\n             from the supplied <code>$qname</code>, and whose namespace URI is taken from the string\n             value of the namespace binding.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the <code>$qname</code> has no prefix, and there is no namespace binding for\n                <code>$element</code> corresponding to the default (unnamed) namespace, then the\n             resulting expanded-QName has no namespace part.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The prefix (or absence of a prefix) in the supplied <code>$qname</code> argument is\n             retained in the returned expanded-QName, as discussed in <xspecref spec="DM30" ref="terminology"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="CA" code="0002"/> if <code>$qname</code> does not\n             have the correct lexical form for an instance of <code>xs:QName</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="NS" code="0004"/> if <code>$qname</code> has a\n             prefix and there is no namespace binding for <code>$element</code> that matches this\n             prefix.</p></div>\n',summary:'<p>  Returns an  xs:QName  value (that is, an expanded-QName) by taking\n             an  xs:string  that has the lexical form of an  xs:QName  (a\n             string in the form "prefix:local-name" or "local-name") and resolving it using the\n             in-scope namespaces for a given element.</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"qname",type:"xs:string",occurrence:"?",description:""},{name:"element",type:"element(*)",occurrence:null,description:""}],returns:{type:"xs:QName?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"resolve-uri",qname:"fn:resolve-uri",signature:"($relative as xs:string?) as xs:anyURI? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Resolves a relative IRI reference against an absolute IRI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="resolve-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="relative" type="xs:string?"/></proto></example><example role="signature"><proto name="resolve-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="relative" type="xs:string?"/><arg name="base" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the second argument is absent, the effect is the same as calling the two-argument\n             function with the value of <code>fn:static-base-uri()</code> as the second argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function is defined to operate on IRI references as defined in <bibref ref="rfc3987"/>, and the implementation <rfc2119>must</rfc2119> permit all arguments that are valid\n             according to that specification. In addition, the implementation <rfc2119>may</rfc2119>\n             accept some or all strings that conform to the rules for (absolute or relative) Legacy\n             Extended IRI references as defined in <bibref ref="LEIRI"/>. For the purposes of this\n             section, the terms IRI and IRI reference include these extensions, insofar as the\n             implementation chooses to support them.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$relative</code> is the empty sequence, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$relative</code> is an absolute IRI (as defined above), then it is returned\n             unchanged.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function resolves the relative IRI reference <code>$relative</code>\n             against the base IRI <code>$base</code> using the algorithm defined in <bibref ref="rfc3986"/>, adapted by treating any <termref def="character">character</termref>\n             that would not be valid in an RFC3986 URI or relative reference in the same way that\n             RFC3986 treats unreserved characters. No percent-encoding takes place.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The first form of this function resolves <code>$relative</code> against the value of the\n             base-uri property from the static context. A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="NS" code="0005"/> if the base-uri property is not initialized in the static context. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0002"/> if <code>$relative</code> is not a\n             valid IRI according to the rules of RFC3987, extended with an implementation-defined\n             subset of the extensions permitted in LEIRI, or if it is not a suitable relative\n             reference to use as input to the RFC3986 resolution algorithm extended to handle\n             additional unreserved characters. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0002"/> if <code>$base</code> is not a\n             valid IRI according to the rules of RFC3987, extended with an implementation-defined\n             subset of the extensions permitted in LEIRI, or if it is not a suitable IRI to use as\n             input to the chosen resolution algorithm (for example, if it is a relative IRI\n             reference, if it is a non-hierarchic URI, or if it contains a fragment identifier). </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0009"/> if the chosen resolution algorithm\n             fails for any other reason. </p></div>\n',summary:"<p>  Resolves a relative IRI reference against an absolute IRI.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"relative",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:anyURI?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"resolve-uri",qname:"fn:resolve-uri",signature:"($relative as xs:string?, $base as xs:string) as xs:anyURI? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Resolves a relative IRI reference against an absolute IRI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="resolve-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="relative" type="xs:string?"/></proto></example><example role="signature"><proto name="resolve-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="relative" type="xs:string?"/><arg name="base" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the second argument is absent, the effect is the same as calling the two-argument\n             function with the value of <code>fn:static-base-uri()</code> as the second argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function is defined to operate on IRI references as defined in <bibref ref="rfc3987"/>, and the implementation <rfc2119>must</rfc2119> permit all arguments that are valid\n             according to that specification. In addition, the implementation <rfc2119>may</rfc2119>\n             accept some or all strings that conform to the rules for (absolute or relative) Legacy\n             Extended IRI references as defined in <bibref ref="LEIRI"/>. For the purposes of this\n             section, the terms IRI and IRI reference include these extensions, insofar as the\n             implementation chooses to support them.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$relative</code> is the empty sequence, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$relative</code> is an absolute IRI (as defined above), then it is returned\n             unchanged.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function resolves the relative IRI reference <code>$relative</code>\n             against the base IRI <code>$base</code> using the algorithm defined in <bibref ref="rfc3986"/>, adapted by treating any <termref def="character">character</termref>\n             that would not be valid in an RFC3986 URI or relative reference in the same way that\n             RFC3986 treats unreserved characters. No percent-encoding takes place.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The first form of this function resolves <code>$relative</code> against the value of the\n             base-uri property from the static context. A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="NS" code="0005"/> if the base-uri property is not initialized in the static context. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0002"/> if <code>$relative</code> is not a\n             valid IRI according to the rules of RFC3987, extended with an implementation-defined\n             subset of the extensions permitted in LEIRI, or if it is not a suitable relative\n             reference to use as input to the RFC3986 resolution algorithm extended to handle\n             additional unreserved characters. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0002"/> if <code>$base</code> is not a\n             valid IRI according to the rules of RFC3987, extended with an implementation-defined\n             subset of the extensions permitted in LEIRI, or if it is not a suitable IRI to use as\n             input to the chosen resolution algorithm (for example, if it is a relative IRI\n             reference, if it is a non-hierarchic URI, or if it contains a fragment identifier). </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0009"/> if the chosen resolution algorithm\n             fails for any other reason. </p></div>\n',summary:"<p>  Resolves a relative IRI reference against an absolute IRI.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"relative",type:"xs:string",occurrence:"?",description:""},{name:"base",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:anyURI?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"reverse",qname:"fn:reverse",signature:"($arg as item()*) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Reverses the order of items in a sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="reverse" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence containing the items in <code>$arg</code> in reverse\n             order.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the empty sequence is returned. </p></div>\n',summary:"<p>  Reverses the order of items in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:0,name:"root",qname:"fn:root",signature:"() as node() external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the root of the tree to which <code>$arg</code> belongs. This will\n             usually, but not necessarily, be a document node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="root" return-type="node()" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="root" return-type="node()?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the function is called without an argument, the context item (<code>.</code>) is used\n             as the default argument. The behavior of the function if the argument is omitted is\n             exactly the same as if the context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the value of the expression\n                <code>($arg/ancestor-or-self::node())[1]</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the root of the tree to which  $arg  belongs.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"node()",description:""},errors:[]},{isDocumented:!0,arity:1,name:"root",qname:"fn:root",signature:"($arg as node()?) as node()? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the root of the tree to which <code>$arg</code> belongs. This will\n             usually, but not necessarily, be a document node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="root" return-type="node()" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="root" return-type="node()?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="node()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the function is called without an argument, the context item (<code>.</code>) is used\n             as the default argument. The behavior of the function if the argument is omitted is\n             exactly the same as if the context item had been passed as the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the value of the expression\n                <code>($arg/ancestor-or-self::node())[1]</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The following errors may be raised when <code>$arg</code> is omitted:</p><ul xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><li><p>If the context\n                item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, <phrase diff="add" at="M">dynamic error</phrase>\n                <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/></p></li><li><p>If the context item is not a\n                node, <phrase diff="add" at="M">type error</phrase> <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></li></ul></div>\n',summary:"<p>  Returns the root of the tree to which  $arg  belongs.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"node()",occurrence:"?",description:""}],returns:{type:"node()?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"round-half-to-even",qname:"fn:round-half-to-even",signature:"($arg as numeric?) as numeric? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Rounds a value to a specified number of decimal places, rounding to make the\n             last digit even if two such values are equally near.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="round-half-to-even" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/></proto></example><example role="signature"><proto name="round-half-to-even" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/><arg name="precision" type="xs:integer"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">General rules: see <specref ref="numeric-value-functions"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the nearest (that is, numerically closest) value to\n                <code>$arg</code> that is a multiple of ten to the power of minus\n                <code>$precision</code>. If two such values are equally near (e.g. if the fractional\n             part in <code>$arg</code> is exactly .500...), the function returns the one whose least\n             significant digit is even.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the type of <code>$arg</code> is one of the four numeric types <code>xs:float</code>,\n                <code>xs:double</code>, <code>xs:decimal</code> or <code>xs:integer</code> the type\n             of the result is the same as the type of <code>$arg</code>. If the type of\n                <code>$arg</code> is a type derived from one of the numeric types, the result is an\n             instance of the base numeric type.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> The first signature of this function produces the same result as the second signature\n             with <code>$precision=0</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For arguments of type <code>xs:float</code> and <code>xs:double</code>:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If the argument is <code>NaN</code>, positive or negative zero, or positive or\n                   negative infinity, then the result is the same as the argument.</p></item><item><p>In all other cases, the argument is cast to <code>xs:decimal</code>\n                   <phrase diff="add" at="A">using an implementation of xs:decimal that imposes no\n                      limits on the number of digits that can be represented.</phrase> The function\n                   is applied to this <code>xs:decimal</code> value, and the resulting\n                      <code>xs:decimal</code> is cast back to <code>xs:float</code> or\n                      <code>xs:double</code> as appropriate to form the function result. If the\n                   resulting <code>xs:decimal</code> value is zero, then positive or negative zero is\n                   returned according to the sign of the original argument.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A">This function is typically used in financial applications where the\n             argument is of type <code>xs:decimal</code>. For arguments of type <code>xs:float</code>\n             and <code>xs:double</code> the results may be counter-intuitive. For example, consider\n                <code>round-half-to-even(xs:float(150.015), 2)</code>. The result is not 150.02 as\n             might be expected, but 150.01. This is because the conversion of the\n                <code>xs:float</code> value represented by the literal 150.015 to an\n                <code>xs:decimal</code> produces the <code>xs:decimal</code> value 150.014999389...,\n             which is closer to 150.01 than to 150.02.</p></div>\n',summary:"<p>  Rounds a value to a specified number of decimal places, rounding to make the\n             last digit even if two such values are equally near.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"numeric",occurrence:"?",description:""}],returns:{type:"numeric?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"round-half-to-even",qname:"fn:round-half-to-even",signature:"($arg as numeric?, $precision as xs:integer) as numeric? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Rounds a value to a specified number of decimal places, rounding to make the\n             last digit even if two such values are equally near.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="round-half-to-even" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/></proto></example><example role="signature"><proto name="round-half-to-even" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/><arg name="precision" type="xs:integer"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">General rules: see <specref ref="numeric-value-functions"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the nearest (that is, numerically closest) value to\n                <code>$arg</code> that is a multiple of ten to the power of minus\n                <code>$precision</code>. If two such values are equally near (e.g. if the fractional\n             part in <code>$arg</code> is exactly .500...), the function returns the one whose least\n             significant digit is even.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the type of <code>$arg</code> is one of the four numeric types <code>xs:float</code>,\n                <code>xs:double</code>, <code>xs:decimal</code> or <code>xs:integer</code> the type\n             of the result is the same as the type of <code>$arg</code>. If the type of\n                <code>$arg</code> is a type derived from one of the numeric types, the result is an\n             instance of the base numeric type.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> The first signature of this function produces the same result as the second signature\n             with <code>$precision=0</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">For arguments of type <code>xs:float</code> and <code>xs:double</code>:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If the argument is <code>NaN</code>, positive or negative zero, or positive or\n                   negative infinity, then the result is the same as the argument.</p></item><item><p>In all other cases, the argument is cast to <code>xs:decimal</code>\n                   <phrase diff="add" at="A">using an implementation of xs:decimal that imposes no\n                      limits on the number of digits that can be represented.</phrase> The function\n                   is applied to this <code>xs:decimal</code> value, and the resulting\n                      <code>xs:decimal</code> is cast back to <code>xs:float</code> or\n                      <code>xs:double</code> as appropriate to form the function result. If the\n                   resulting <code>xs:decimal</code> value is zero, then positive or negative zero is\n                   returned according to the sign of the original argument.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A">This function is typically used in financial applications where the\n             argument is of type <code>xs:decimal</code>. For arguments of type <code>xs:float</code>\n             and <code>xs:double</code> the results may be counter-intuitive. For example, consider\n                <code>round-half-to-even(xs:float(150.015), 2)</code>. The result is not 150.02 as\n             might be expected, but 150.01. This is because the conversion of the\n                <code>xs:float</code> value represented by the literal 150.015 to an\n                <code>xs:decimal</code> produces the <code>xs:decimal</code> value 150.014999389...,\n             which is closer to 150.01 than to 150.02.</p></div>\n',summary:"<p>  Rounds a value to a specified number of decimal places, rounding to make the\n             last digit even if two such values are equally near.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"numeric",occurrence:"?",description:""},{name:"precision",type:"xs:integer",occurrence:null,description:""}],returns:{type:"numeric?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"round",qname:"fn:round",signature:"($arg as numeric?) as numeric? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Rounds a value to a specified number of decimal places, rounding upwards if two\n             such values are equally near.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="round" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/></proto></example><example role="signature"><proto name="round" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/><arg name="precision" type="xs:integer"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">General rules: see <specref ref="numeric-value-functions"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the nearest (that is, numerically closest) value to\n                <code>$arg</code> that is a multiple of ten to the power of minus\n                <code>$precision</code>. If two such values are equally near (for example, if the\n             fractional part in <code>$arg</code> is exactly .5), the function returns the one that\n             is closest to positive infinity.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the type of <code>$arg</code> is one of the four numeric types <code>xs:float</code>,\n                <code>xs:double</code>, <code>xs:decimal</code> or <code>xs:integer</code> the type\n             of the result is the same as the type of <code>$arg</code>. If the type of\n                <code>$arg</code> is a type derived from one of the numeric types, the result is an\n             instance of the base numeric type.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The single-argument version of this function produces the same result as the\n             two-argument version with <code>$precision=0</code> (that is, it rounds to a whole\n             number).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">When <code>$arg</code> is of type <code>xs:float</code> and <code>xs:double</code>:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If <code>$arg</code> is NaN, positive or negative zero, or positive or negative\n                   infinity, then the result is the same as the argument.</p></item><item><p>For other values, the argument is cast to <code>xs:decimal</code> using an\n                   implementation of <code>xs:decimal</code> that imposes no limits on the number of\n                   digits that can be represented. The function is applied to this\n                      <code>xs:decimal</code> value, and the resulting <code>xs:decimal</code> is\n                   cast back to <code>xs:float</code> or <code>xs:double</code> as appropriate to\n                   form the function result. If the resulting <code>xs:decimal</code> value is zero,\n                   then positive or negative zero is returned according to the sign of\n                      <code>$arg</code>.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is typically used with a non-zero <code>$precision</code> in financial\n             applications where the argument is of type <code>xs:decimal</code>. For arguments of\n             type <code>xs:float</code> and <code>xs:double</code> the results may be\n             counter-intuitive. For example, consider <code>round(35.425e0, 2)</code>. The result is\n             not 35.43, as might be expected, but 35.42. This is because the <code>xs:double</code> written as 35.425e0\n             has an exact value equal to 35.42499999999..., which is closer\n             to 35.42 than to 35.43.</p></div>\n',summary:"<p>  Rounds a value to a specified number of decimal places, rounding upwards if two\n             such values are equally near.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"numeric",occurrence:"?",description:""}],returns:{type:"numeric?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"round",qname:"fn:round",signature:"($arg as numeric?, $precision as xs:integer) as numeric? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Rounds a value to a specified number of decimal places, rounding upwards if two\n             such values are equally near.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="round" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/></proto></example><example role="signature"><proto name="round" return-type="numeric?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="numeric?"/><arg name="precision" type="xs:integer"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">General rules: see <specref ref="numeric-value-functions"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the nearest (that is, numerically closest) value to\n                <code>$arg</code> that is a multiple of ten to the power of minus\n                <code>$precision</code>. If two such values are equally near (for example, if the\n             fractional part in <code>$arg</code> is exactly .5), the function returns the one that\n             is closest to positive infinity.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the type of <code>$arg</code> is one of the four numeric types <code>xs:float</code>,\n                <code>xs:double</code>, <code>xs:decimal</code> or <code>xs:integer</code> the type\n             of the result is the same as the type of <code>$arg</code>. If the type of\n                <code>$arg</code> is a type derived from one of the numeric types, the result is an\n             instance of the base numeric type.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The single-argument version of this function produces the same result as the\n             two-argument version with <code>$precision=0</code> (that is, it rounds to a whole\n             number).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">When <code>$arg</code> is of type <code>xs:float</code> and <code>xs:double</code>:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If <code>$arg</code> is NaN, positive or negative zero, or positive or negative\n                   infinity, then the result is the same as the argument.</p></item><item><p>For other values, the argument is cast to <code>xs:decimal</code> using an\n                   implementation of <code>xs:decimal</code> that imposes no limits on the number of\n                   digits that can be represented. The function is applied to this\n                      <code>xs:decimal</code> value, and the resulting <code>xs:decimal</code> is\n                   cast back to <code>xs:float</code> or <code>xs:double</code> as appropriate to\n                   form the function result. If the resulting <code>xs:decimal</code> value is zero,\n                   then positive or negative zero is returned according to the sign of\n                      <code>$arg</code>.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is typically used with a non-zero <code>$precision</code> in financial\n             applications where the argument is of type <code>xs:decimal</code>. For arguments of\n             type <code>xs:float</code> and <code>xs:double</code> the results may be\n             counter-intuitive. For example, consider <code>round(35.425e0, 2)</code>. The result is\n             not 35.43, as might be expected, but 35.42. This is because the <code>xs:double</code> written as 35.425e0\n             has an exact value equal to 35.42499999999..., which is closer\n             to 35.42 than to 35.43.</p></div>\n',summary:"<p>  Rounds a value to a specified number of decimal places, rounding upwards if two\n             such values are equally near.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"numeric",occurrence:"?",description:""},{name:"precision",type:"xs:integer",occurrence:null,description:""}],returns:{type:"numeric?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"seconds-from-dateTime",qname:"fn:seconds-from-dateTime",signature:"($arg as xs:dateTime?) as xs:decimal? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the seconds component of an <code>xs:dateTime</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="seconds-from-dateTime" return-type="xs:decimal?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:dateTime?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:decimal</code> value greater than or equal\n             to zero and less than 60, representing the seconds and fractional seconds in the local\n             value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:seconds-from-dateTime(xs:dateTime("1999-05-31T13:20:00-05:00"))</code> returns <code>0</code>.</p></div>\n',summary:"<p>  Returns the seconds component of an  xs:dateTime .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:dateTime",occurrence:"?",description:""}],returns:{type:"xs:decimal?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"seconds-from-duration",qname:"fn:seconds-from-duration",signature:"($arg as xs:duration?) as xs:decimal? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the number of seconds in a duration.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="seconds-from-duration" return-type="xs:decimal?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:duration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:decimal</code> representing the seconds\n             component in the value of <code>$arg</code>. The result is obtained by casting\n                <code>$arg</code> to an <code>xs:dayTimeDuration</code> (see <specref ref="casting-to-durations"/>) and then computing the seconds component as described\n             in <specref ref="canonical-dayTimeDuration"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a negative duration then the result will be negative..</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is an <code>xs:yearMonthDuration</code> the function returns 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:seconds-from-duration(xs:dayTimeDuration("P3DT10H12.5S"))</code> returns <code>12.5</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:seconds-from-duration(xs:dayTimeDuration("-PT256S"))</code> returns <code>-16.0</code>.</p></div>\n',summary:"<p>  Returns the number of seconds in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:duration",occurrence:"?",description:""}],returns:{type:"xs:decimal?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"seconds-from-time",qname:"fn:seconds-from-time",signature:"($arg as xs:time?) as xs:decimal? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the seconds component of an <code>xs:time</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="seconds-from-time" return-type="xs:decimal?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:time?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:decimal</code> value greater than or equal\n             to zero and less than 60, representing the seconds and fractional seconds in the local\n             value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:seconds-from-time(xs:time("13:20:10.5"))</code> returns <code>10.5</code>.</p></div>\n',summary:"<p>  Returns the seconds component of an  xs:time .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:time",occurrence:"?",description:""}],returns:{type:"xs:decimal?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"serialize",qname:"fn:serialize",signature:"($arg as item()*) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function serializes the supplied <phrase diff="chg" at="G">input\n                sequence</phrase>\n             <code>$arg</code> as described in <bibref ref="xslt-xquery-serialization-30"/>,\n             returning the serialized <phrase diff="chg" at="G">representation of the\n                sequence</phrase> as a string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="serialize" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example><example role="signature"><proto name="serialize" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/><arg name="params" type="element(output:serialization-parameters)?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The value of <code>$arg</code> acts as the input sequence to the serialization process,\n             which starts with sequence normalization.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">The single-argument version of this function has the same effect as\n             the two-argument version called with <code>$params</code> set to an empty sequence. This\n             in turn is the same as the effect of passing an\n                <code>output:serialization-parameters</code> element with no child elements.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">The <code>$params</code> argument is used to identify a set of\n             serialization parameters. These are supplied in the form of an\n                <code>output:serialization-parameters</code> element, having the format described in\n                <xspecref spec="SER30" ref="serparams-in-xdm-instance"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The final stage of serialization, that is, encoding, is skipped. If the serializer does\n             not allow this phase to be skipped, then the sequence of octets returned by the\n             serializer is decoded into a string by reversing the character encoding performed in the\n             final stage.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">If the host language makes serialization an optional feature and\n          the implementation does not support serialization, then a dynamic error\n             <errorref class="DC" code="0010"/> is raised.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The serialization process will raise an error if <code>$arg</code> is an attribute or\n             namespace node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If any serialization error occurs, including the detection of an invalid value for a\n             serialization parameter, this results in the <code>fn:serialize</code> call failing with\n             a dynamic error.</p></div>\n',summary:"<p>  This function serializes the supplied  input\n                sequence \n              $arg  as described in   ,\n             returning the serialized  representation of the\n                sequence  as a string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"serialize",qname:"fn:serialize",signature:"($arg as item()*, $params as element(output:serialization-parameters)?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function serializes the supplied <phrase diff="chg" at="G">input\n                sequence</phrase>\n             <code>$arg</code> as described in <bibref ref="xslt-xquery-serialization-30"/>,\n             returning the serialized <phrase diff="chg" at="G">representation of the\n                sequence</phrase> as a string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="serialize" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example><example role="signature"><proto name="serialize" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/><arg name="params" type="element(output:serialization-parameters)?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The value of <code>$arg</code> acts as the input sequence to the serialization process,\n             which starts with sequence normalization.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">The single-argument version of this function has the same effect as\n             the two-argument version called with <code>$params</code> set to an empty sequence. This\n             in turn is the same as the effect of passing an\n                <code>output:serialization-parameters</code> element with no child elements.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">The <code>$params</code> argument is used to identify a set of\n             serialization parameters. These are supplied in the form of an\n                <code>output:serialization-parameters</code> element, having the format described in\n                <xspecref spec="SER30" ref="serparams-in-xdm-instance"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The final stage of serialization, that is, encoding, is skipped. If the serializer does\n             not allow this phase to be skipped, then the sequence of octets returned by the\n             serializer is decoded into a string by reversing the character encoding performed in the\n             final stage.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">If the host language makes serialization an optional feature and\n          the implementation does not support serialization, then a dynamic error\n             <errorref class="DC" code="0010"/> is raised.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The serialization process will raise an error if <code>$arg</code> is an attribute or\n             namespace node.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If any serialization error occurs, including the detection of an invalid value for a\n             serialization parameter, this results in the <code>fn:serialize</code> call failing with\n             a dynamic error.</p></div>\n',summary:"<p>  This function serializes the supplied  input\n                sequence \n              $arg  as described in   ,\n             returning the serialized  representation of the\n                sequence  as a string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""},{name:"params",type:"element(output:serialization-parameters)",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"starts-with",qname:"fn:starts-with",signature:"($arg1 as xs:string?, $arg2 as xs:string?) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the string <code>$arg1</code> contains <code>$arg2</code> as a\n             leading substring, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="starts-with" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="starts-with" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n                <code>true</code>. If the value of <code>$arg1</code> is the zero-length string and\n             the value of <code>$arg2</code> is not the zero-length string, then the function returns\n                <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:boolean</code> indicating whether or not the value of\n                <code>$arg1</code> starts with a sequence of collation units that provides a\n                <term>match</term> to the collation units of <code>$arg2</code> according to the\n             collation that is used.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p><term>Match</term> is defined in <bibref ref="Unicode-Collations"/>.</p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns true if the string  $arg1  contains  $arg2  as a\n             leading substring, taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:3,name:"starts-with",qname:"fn:starts-with",signature:"($arg1 as xs:string?, $arg2 as xs:string?, $collation as xs:string) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns true if the string <code>$arg1</code> contains <code>$arg2</code> as a\n             leading substring, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="starts-with" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="starts-with" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n                <code>true</code>. If the value of <code>$arg1</code> is the zero-length string and\n             the value of <code>$arg2</code> is not the zero-length string, then the function returns\n                <code>false</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:boolean</code> indicating whether or not the value of\n                <code>$arg1</code> starts with a sequence of collation units that provides a\n                <term>match</term> to the collation units of <code>$arg2</code> according to the\n             collation that is used.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p><term>Match</term> is defined in <bibref ref="Unicode-Collations"/>.</p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns true if the string  $arg1  contains  $arg2  as a\n             leading substring, taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:0,name:"static-base-uri",qname:"fn:static-base-uri",signature:"() as xs:anyURI? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function returns the value of the Static Base URI property from the static context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="static-base-uri" return-type="xs:anyURI?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the value of the Static Base URI property from the static context. If the\n             property is absent, the empty sequence is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Components of the static context are discussed in <xspecref spec="XP30" ref="static_context"/> .</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">XQuery 3.0 and XSLT 3.0 give an implementation freedom to use different base URIs during the\n          static analysis phase and the dynamic evaluation phase, that is, for compile-time and run-time resources respectively.\n          In this situation, the <code>fn:static-base-uri</code> function should return a URI suitable for locating resources needed\n          during dynamic evaluation.</p></div>\n',summary:"<p>  This function returns the value of the Static Base URI property from the static context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyURI?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"string-join",qname:"fn:string-join",signature:"($arg1 as xs:string*) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string created by concatenating the items in a sequence, with a\n             defined separator between adjacent items.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="string-join" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string*"/></proto></example><example role="signature"><proto name="string-join" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string*"/><arg name="arg2" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">The effect of calling the single-argument version of this function is\n             the same as calling the two-argument version with <code>$arg2</code> set to a\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:string</code> created by concatenating the items in the\n             sequence <code>$arg1</code>, in order, using the value of <code>$arg2</code> as a\n             separator between adjacent items. If the value of <code>$arg2</code> is the zero-length\n             string, then the members of <code>$arg1</code> are concatenated without a separator.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> is the empty sequence, the function returns the\n             zero-length string.</p></div>\n',summary:"<p>  Returns a string created by concatenating the items in a sequence, with a\n             defined separator between adjacent items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"*",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"string-join",qname:"fn:string-join",signature:"($arg1 as xs:string*, $arg2 as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a string created by concatenating the items in a sequence, with a\n             defined separator between adjacent items.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="string-join" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string*"/></proto></example><example role="signature"><proto name="string-join" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string*"/><arg name="arg2" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="B">The effect of calling the single-argument version of this function is\n             the same as calling the two-argument version with <code>$arg2</code> set to a\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:string</code> created by concatenating the items in the\n             sequence <code>$arg1</code>, in order, using the value of <code>$arg2</code> as a\n             separator between adjacent items. If the value of <code>$arg2</code> is the zero-length\n             string, then the members of <code>$arg1</code> are concatenated without a separator.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> is the empty sequence, the function returns the\n             zero-length string.</p></div>\n',summary:"<p>  Returns a string created by concatenating the items in a sequence, with a\n             defined separator between adjacent items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"*",description:""},{name:"arg2",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:0,name:"string-length",qname:"fn:string-length",signature:"() as xs:integer external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the number of <termref def="character">characters</termref> in a\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="string-length" return-type="xs:integer" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="string-length" return-type="xs:integer" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:integer</code> equal to the length in <termref def="character">characters</termref> of the value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Calling the zero-argument version of the function is equivalent to calling\n                <code>fn:string-length(fn:string(.))</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the function returns the\n                <code>xs:integer</code> value zero (0).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is not specified and the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, a <phrase diff="add" at="M">dynamic</phrase> error is raised: <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/>.</p></div>\n',summary:"<p>  Returns the number of  characters  in a\n             string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:1,name:"string-length",qname:"fn:string-length",signature:"($arg as xs:string?) as xs:integer external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the number of <termref def="character">characters</termref> in a\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="string-length" return-type="xs:integer" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="string-length" return-type="xs:integer" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns an <code>xs:integer</code> equal to the length in <termref def="character">characters</termref> of the value of <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Calling the zero-argument version of the function is equivalent to calling\n                <code>fn:string-length(fn:string(.))</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the function returns the\n                <code>xs:integer</code> value zero (0).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is not specified and the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>, a <phrase diff="add" at="M">dynamic</phrase> error is raised: <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/>.</p></div>\n',summary:"<p>  Returns the number of  characters  in a\n             string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:1,name:"string-to-codepoints",qname:"fn:string-to-codepoints",signature:"($arg as xs:string?) as xs:integer* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the sequence of <termref def="codepoint">codepoints</termref> that\n             constitute an <code>xs:string</code> value. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="string-to-codepoints" return-type="xs:integer*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence of integers, each integer being the Unicode <termref def="codepoint">codepoints</termref> of the corresponding <termref def="character">character</termref> in <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a zero-length string or the empty sequence, the function returns\n             the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:string-to-codepoints("Th\u00e9r\u00e8se")</code> returns <code>(84, 104, 233, 114, 232, 115, 101)</code>.</p></div>\n',summary:"<p>  Returns the sequence of  codepoints  that\n             constitute an  xs:string  value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:integer*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"string-to-codepoints",qname:"fn:string-to-codepoints",signature:"($arg as xs:string?) as xs:integer* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the sequence of <termref def="codepoint">codepoints</termref> that\n             constitute an <code>xs:string</code> value. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="string-to-codepoints" return-type="xs:integer*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence of integers, each integer being the Unicode <termref def="codepoint">codepoints</termref> of the corresponding <termref def="character">character</termref> in <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a zero-length string or the empty sequence, the function returns\n             the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:string-to-codepoints("Th\u00e9r\u00e8se")</code> returns <code>(84, 104, 233, 114, 232, 115, 101)</code>.</p></div>\n',summary:"<p>  Returns the sequence of  codepoints  that\n             constitute an  xs:string  value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:integer*",description:""},errors:[]},{isDocumented:!0,arity:0,name:"string",qname:"fn:string",signature:"() as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of <code>$arg</code> represented as an\n             <code>xs:string</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="string" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="string" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In the zero-argument version of the function, <code>$arg</code> defaults to the context\n             item. That is, calling <code>fn:string()</code> is equivalent to calling\n                <code>fn:string(.)</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a node, the function returns the string-value of the node, as\n             obtained using the <code>dm:string-value</code> accessor defined in <bibref ref="xpath-datamodel-30"/> (see <xspecref spec="DM30" ref="dm-string-value"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is an atomic value, the function returns the result of the\n             expression <code>$arg cast as xs:string</code> (see <specref ref="casting"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="M">dynamic</phrase> error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/> by the\n             zero-argument version of the function if the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">type</phrase> error is raised <errorref class="TY" code="0014" type="type"/> if\n                <code>$arg</code> is a function item. </p></div>\n',summary:"<p>  Returns the value of  $arg  represented as an\n              xs:string .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"string",qname:"fn:string",signature:"($arg as item()?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of <code>$arg</code> represented as an\n             <code>xs:string</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="string" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="string" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In the zero-argument version of the function, <code>$arg</code> defaults to the context\n             item. That is, calling <code>fn:string()</code> is equivalent to calling\n                <code>fn:string(.)</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a node, the function returns the string-value of the node, as\n             obtained using the <code>dm:string-value</code> accessor defined in <bibref ref="xpath-datamodel-30"/> (see <xspecref spec="DM30" ref="dm-string-value"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is an atomic value, the function returns the result of the\n             expression <code>$arg cast as xs:string</code> (see <specref ref="casting"/>).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="M">dynamic</phrase> error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/> by the\n             zero-argument version of the function if the context item is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">type</phrase> error is raised <errorref class="TY" code="0014" type="type"/> if\n                <code>$arg</code> is a function item. </p></div>\n',summary:"<p>  Returns the value of  $arg  represented as an\n              xs:string .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"subsequence",qname:"fn:subsequence",signature:"($sourceSeq as item()*, $startingLoc as xs:double) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the contiguous sequence of items in the value of\n                <code>$sourceSeq</code> beginning at the position indicated by the value of\n                <code>$startingLoc</code> and continuing for the number of items indicated by the\n             value of <code>$length</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="subsequence" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="sourceSeq" type="item()*"/><arg name="startingLoc" type="xs:double"/></proto></example><example role="signature"><proto name="subsequence" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="sourceSeq" type="item()*"/><arg name="startingLoc" type="xs:double"/><arg name="length" type="xs:double"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In the two-argument case, returns:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E2" xml:space="preserve">$sourceSeq[fn:round($startingLoc) le position()]</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In the three-argument case, returns:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E2" xml:space="preserve">$sourceSeq[fn:round($startingLoc) le position()\n          and position() lt fn:round($startingLoc) + fn:round($length)]</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The first item of a sequence is located at position 1, not position 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$sourceSeq</code> is the empty sequence, the empty sequence is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$startingLoc</code> is zero or negative, the subsequence includes items from\n             the beginning of the <code>$sourceSeq</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$length</code> is not specified, the subsequence includes items to the end of\n                <code>$sourceSeq</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$length</code> is greater than the number of items in the value of\n                <code>$sourceSeq</code> following <code>$startingLoc</code>, the subsequence includes\n             items to the end of <code>$sourceSeq</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="F">As an exception to the previous two notes, if\n                <code>$startingLoc</code> is <code>-INF</code> and <code>$length</code> is\n                <code>+INF</code>, then <code>fn:round($startingLoc) + fn:round($length)</code> is\n                <code>NaN</code>; since <code>position() lt NaN</code> is always false, the result is\n             an empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The reason the function accepts arguments of type <code>xs:double</code> is that many\n             computations on untyped data return an <code>xs:double</code> result; and the reason for\n             the rounding rules is to compensate for any imprecision in these floating-point\n             computations.</p></div>\n',summary:"<p>  Returns the contiguous sequence of items in the value of\n                 $sourceSeq  beginning at the position indicated by the value of\n                 $startingLoc  and continuing for the number of items indicated by the\n             value of  $length .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sourceSeq",type:"item()",occurrence:"*",description:""},{name:"startingLoc",type:"xs:double",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"subsequence",qname:"fn:subsequence",signature:"($sourceSeq as item()*, $startingLoc as xs:double, $length as xs:double) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the contiguous sequence of items in the value of\n                <code>$sourceSeq</code> beginning at the position indicated by the value of\n                <code>$startingLoc</code> and continuing for the number of items indicated by the\n             value of <code>$length</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="subsequence" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="sourceSeq" type="item()*"/><arg name="startingLoc" type="xs:double"/></proto></example><example role="signature"><proto name="subsequence" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="sourceSeq" type="item()*"/><arg name="startingLoc" type="xs:double"/><arg name="length" type="xs:double"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In the two-argument case, returns:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E2" xml:space="preserve">$sourceSeq[fn:round($startingLoc) le position()]</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In the three-argument case, returns:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="A-E2" xml:space="preserve">$sourceSeq[fn:round($startingLoc) le position()\n          and position() lt fn:round($startingLoc) + fn:round($length)]</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The first item of a sequence is located at position 1, not position 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$sourceSeq</code> is the empty sequence, the empty sequence is returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$startingLoc</code> is zero or negative, the subsequence includes items from\n             the beginning of the <code>$sourceSeq</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$length</code> is not specified, the subsequence includes items to the end of\n                <code>$sourceSeq</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If <code>$length</code> is greater than the number of items in the value of\n                <code>$sourceSeq</code> following <code>$startingLoc</code>, the subsequence includes\n             items to the end of <code>$sourceSeq</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="F">As an exception to the previous two notes, if\n                <code>$startingLoc</code> is <code>-INF</code> and <code>$length</code> is\n                <code>+INF</code>, then <code>fn:round($startingLoc) + fn:round($length)</code> is\n                <code>NaN</code>; since <code>position() lt NaN</code> is always false, the result is\n             an empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The reason the function accepts arguments of type <code>xs:double</code> is that many\n             computations on untyped data return an <code>xs:double</code> result; and the reason for\n             the rounding rules is to compensate for any imprecision in these floating-point\n             computations.</p></div>\n',summary:"<p>  Returns the contiguous sequence of items in the value of\n                 $sourceSeq  beginning at the position indicated by the value of\n                 $startingLoc  and continuing for the number of items indicated by the\n             value of  $length .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sourceSeq",type:"item()",occurrence:"*",description:""},{name:"startingLoc",type:"xs:double",occurrence:null,description:""},{name:"length",type:"xs:double",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-after",qname:"fn:substring-after",signature:"($arg1 as xs:string?, $arg2 as xs:string?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the part of <code>$arg1</code> that follows the first occurrence of\n                <code>$arg2</code>, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="substring-after" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="substring-after" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n             the value of <code>$arg1</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> does not contain a string that is equal to the value\n             of <code>$arg2</code>, then the function returns the zero-length string. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the substring of the value of <code>$arg1</code> that follows in\n             the value of <code>$arg1</code> the first occurrence of a sequence of collation units\n             that provides a <term>minimal match</term> to the collation units of <code>$arg2</code>\n             according to the collation that is used. </p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p><term>Minimal match</term> is defined in <bibref ref="Unicode-Collations"/>. </p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns the part of  $arg1  that follows the first occurrence of\n                 $arg2 , taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"substring-after",qname:"fn:substring-after",signature:"($arg1 as xs:string?, $arg2 as xs:string?, $collation as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the part of <code>$arg1</code> that follows the first occurrence of\n                <code>$arg2</code>, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="substring-after" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="substring-after" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n             the value of <code>$arg1</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> does not contain a string that is equal to the value\n             of <code>$arg2</code>, then the function returns the zero-length string. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the substring of the value of <code>$arg1</code> that follows in\n             the value of <code>$arg1</code> the first occurrence of a sequence of collation units\n             that provides a <term>minimal match</term> to the collation units of <code>$arg2</code>\n             according to the collation that is used. </p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p><term>Minimal match</term> is defined in <bibref ref="Unicode-Collations"/>. </p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns the part of  $arg1  that follows the first occurrence of\n                 $arg2 , taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-before",qname:"fn:substring-before",signature:"($arg1 as xs:string?, $arg2 as xs:string?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the part of <code>$arg1</code> that precedes the first occurrence of\n                <code>$arg2</code>, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="substring-before" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="substring-before" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n             the zero-length string. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> does not contain a string that is equal to the value\n             of <code>$arg2</code>, then the function returns the zero-length string. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the substring of the value of <code>$arg1</code> that precedes in\n             the value of <code>$arg1</code> the first occurrence of a sequence of collation units\n             that provides a <term>minimal match</term> to the collation units of <code>$arg2</code>\n             according to the collation that is used.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p><term>Minimal match</term> is defined in <bibref ref="Unicode-Collations"/>. </p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns the part of  $arg1  that precedes the first occurrence of\n                 $arg2 , taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"substring-before",qname:"fn:substring-before",signature:"($arg1 as xs:string?, $arg2 as xs:string?, $collation as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the part of <code>$arg1</code> that precedes the first occurrence of\n                <code>$arg2</code>, taking collations into account.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="substring-before" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/></proto></example><example role="signature"><proto name="substring-before" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:string?"/><arg name="arg2" type="xs:string?"/><arg name="collation" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		collations, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If the value of <code>$arg1</code> or <code>$arg2</code> is the empty sequence, or\n             contains only ignorable collation units, it is interpreted as the zero-length\n             string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg2</code> is the zero-length string, then the function returns\n             the zero-length string. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg1</code> does not contain a string that is equal to the value\n             of <code>$arg2</code>, then the function returns the zero-length string. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the substring of the value of <code>$arg1</code> that precedes in\n             the value of <code>$arg1</code> the first occurrence of a sequence of collation units\n             that provides a <term>minimal match</term> to the collation units of <code>$arg2</code>\n             according to the collation that is used.</p><note xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><p><term>Minimal match</term> is defined in <bibref ref="Unicode-Collations"/>. </p></note><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the\n             specified collation does not support collation units.</p></div>\n',summary:"<p>  Returns the part of  $arg1  that precedes the first occurrence of\n                 $arg2 , taking collations into account.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:"?",description:""},{name:"arg2",type:"xs:string",occurrence:"?",description:""},{name:"collation",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring",qname:"fn:substring",signature:"($sourceString as xs:string?, $start as xs:double) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the portion of the value of <code>$sourceString</code> beginning at the\n             position indicated by the value of <code>$start</code> and continuing for the number of\n                <termref def="character">characters</termref> indicated by the value of\n                <code>$length</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="substring" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="sourceString" type="xs:string?"/><arg name="start" type="xs:double"/></proto></example><example role="signature"><proto name="substring" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="sourceString" type="xs:string?"/><arg name="start" type="xs:double"/><arg name="length" type="xs:double"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$sourceString</code> is the empty sequence, the function returns\n             the zero-length string. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns a string comprising those <termref def="character">characters</termref> of <code>$sourceString</code> whose index position (counting\n             from one) is greater than or equal to the value of <code>$start</code> (rounded to an\n             integer), and (if <code>$length</code> is specified) less than the sum of\n                <code>$start</code> and <code>$length</code> (both rounded to integers).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The characters returned do not extend beyond <code>$sourceString</code>. If\n                <code>$start</code> is zero or negative, only those characters in positions greater\n             than zero are returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">More specifically, the three argument version of the function returns the characters in\n                <code>$sourceString</code> whose position <code>$p</code> satisfies:</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">\n             <code>fn:round($start) &lt;= $p &lt; fn:round($start) + fn:round($length)</code>\n          </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two argument version of the function assumes that <code>$length</code> is infinite\n             and thus returns the <termref def="character">characters</termref> in\n                <code>$sourceString</code> whose position <code>$p</code> satisfies:</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">\n             <code>fn:round($start) &lt;= $p</code>\n          </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In the above computations, the rules for <code>op:numeric-less-than</code> and\n                <code>op:numeric-greater-than</code> apply.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The first character of a string is located at position 1, not position 0.</p></div>\n',summary:"<p>  Returns the portion of the value of  $sourceString  beginning at the\n             position indicated by the value of  $start  and continuing for the number of\n                 characters  indicated by the value of\n                 $length .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sourceString",type:"xs:string",occurrence:"?",description:""},{name:"start",type:"xs:double",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"substring",qname:"fn:substring",signature:"($sourceString as xs:string?, $start as xs:double, $length as xs:double) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the portion of the value of <code>$sourceString</code> beginning at the\n             position indicated by the value of <code>$start</code> and continuing for the number of\n                <termref def="character">characters</termref> indicated by the value of\n                <code>$length</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="substring" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="sourceString" type="xs:string?"/><arg name="start" type="xs:double"/></proto></example><example role="signature"><proto name="substring" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="sourceString" type="xs:string?"/><arg name="start" type="xs:double"/><arg name="length" type="xs:double"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$sourceString</code> is the empty sequence, the function returns\n             the zero-length string. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns a string comprising those <termref def="character">characters</termref> of <code>$sourceString</code> whose index position (counting\n             from one) is greater than or equal to the value of <code>$start</code> (rounded to an\n             integer), and (if <code>$length</code> is specified) less than the sum of\n                <code>$start</code> and <code>$length</code> (both rounded to integers).</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The characters returned do not extend beyond <code>$sourceString</code>. If\n                <code>$start</code> is zero or negative, only those characters in positions greater\n             than zero are returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">More specifically, the three argument version of the function returns the characters in\n                <code>$sourceString</code> whose position <code>$p</code> satisfies:</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">\n             <code>fn:round($start) &lt;= $p &lt; fn:round($start) + fn:round($length)</code>\n          </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The two argument version of the function assumes that <code>$length</code> is infinite\n             and thus returns the <termref def="character">characters</termref> in\n                <code>$sourceString</code> whose position <code>$p</code> satisfies:</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">\n             <code>fn:round($start) &lt;= $p</code>\n          </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In the above computations, the rules for <code>op:numeric-less-than</code> and\n                <code>op:numeric-greater-than</code> apply.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The first character of a string is located at position 1, not position 0.</p></div>\n',summary:"<p>  Returns the portion of the value of  $sourceString  beginning at the\n             position indicated by the value of  $start  and continuing for the number of\n                 characters  indicated by the value of\n                 $length .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sourceString",type:"xs:string",occurrence:"?",description:""},{name:"start",type:"xs:double",occurrence:null,description:""},{name:"length",type:"xs:double",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sum",qname:"fn:sum",signature:"($arg as xs:anyAtomicType*) as xs:anyAtomicType external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a value obtained by adding together the values in\n             <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="sum" return-type="xs:anyAtomicType" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/></proto></example><example role="signature"><proto name="sum" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/><arg name="zero" type="xs:anyAtomicType?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Any values of type <code>xs:untypedAtomic</code> in <code>$arg</code> are cast to\n                <code>xs:double</code>. The items in the resulting sequence may be reordered in an\n             arbitrary order. The resulting sequence is referred to below as the converted\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence is empty, then the single-argument form of the function\n             returns the <code>xs:integer</code> value <code>0</code>; the two-argument form returns\n             the value of the argument <code>$zero</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence contains the value <code>NaN</code>, <code>NaN</code> is\n             returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">All items in <code>$arg</code> must be numeric or derived from a single base type. In\n             addition, the type must support addition. Duration values must either all be\n                <code>xs:yearMonthDuration</code> values or must all be\n                <code>xs:dayTimeDuration</code> values. For numeric values, the numeric promotion\n             rules defined in <specref ref="op.numeric"/> are used to promote all values to a single\n             common type. The sum of a sequence of integers will therefore be an integer, while the\n             sum of a numeric sequence that includes at least one <code>xs:double</code> will be an\n                <code>xs:double</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function, using the second signature, is the result of the\n             expression:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n if (fn:count($c) eq 0) then\n     $zero\n else if (fn:count($c) eq 1) then\n     $c[1]\n else\n     $c[1] + fn:sum(subsequence($c, 2))</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">where <code>$c</code> is the converted sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function, using the first signature, is the result of the expression:\n                <code>fn:sum($arg, 0)</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains\n             items of incompatible types, as described above.</p></div>\n',summary:"<p>  Returns a value obtained by adding together the values in\n              $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"*",description:""}],returns:{type:"xs:anyAtomicType",description:""},errors:[]},{isDocumented:!0,arity:2,name:"sum",qname:"fn:sum",signature:"($arg as xs:anyAtomicType*, $zero as xs:anyAtomicType?) as xs:anyAtomicType? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a value obtained by adding together the values in\n             <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="sum" return-type="xs:anyAtomicType" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/></proto></example><example role="signature"><proto name="sum" return-type="xs:anyAtomicType?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:anyAtomicType*"/><arg name="zero" type="xs:anyAtomicType?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Any values of type <code>xs:untypedAtomic</code> in <code>$arg</code> are cast to\n                <code>xs:double</code>. The items in the resulting sequence may be reordered in an\n             arbitrary order. The resulting sequence is referred to below as the converted\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence is empty, then the single-argument form of the function\n             returns the <code>xs:integer</code> value <code>0</code>; the two-argument form returns\n             the value of the argument <code>$zero</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the converted sequence contains the value <code>NaN</code>, <code>NaN</code> is\n             returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">All items in <code>$arg</code> must be numeric or derived from a single base type. In\n             addition, the type must support addition. Duration values must either all be\n                <code>xs:yearMonthDuration</code> values or must all be\n                <code>xs:dayTimeDuration</code> values. For numeric values, the numeric promotion\n             rules defined in <specref ref="op.numeric"/> are used to promote all values to a single\n             common type. The sum of a sequence of integers will therefore be an integer, while the\n             sum of a numeric sequence that includes at least one <code>xs:double</code> will be an\n                <code>xs:double</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function, using the second signature, is the result of the\n             expression:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve">\n if (fn:count($c) eq 0) then\n     $zero\n else if (fn:count($c) eq 1) then\n     $c[1]\n else\n     $c[1] + fn:sum(subsequence($c, 2))</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">where <code>$c</code> is the converted sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function, using the first signature, is the result of the expression:\n                <code>fn:sum($arg, 0)</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains\n             items of incompatible types, as described above.</p></div>\n',summary:"<p>  Returns a value obtained by adding together the values in\n              $arg .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"*",description:""},{name:"zero",type:"xs:anyAtomicType",occurrence:"?",description:""}],returns:{type:"xs:anyAtomicType?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"tail",qname:"fn:tail",signature:"($arg as item()*) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns all but the first item in a sequence. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="tail" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the value of the expression <code>subsequence($arg, 2)</code></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, or a sequence containing a single item, then\n             the empty sequence is returned. </p></div>\n',summary:"<p>  Returns all but the first item in a sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"timezone-from-date",qname:"fn:timezone-from-date",signature:"($arg as xs:date?) as xs:dayTimeDuration? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the timezone component of an <code>xs:date</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="timezone-from-date" return-type="xs:dayTimeDuration?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:date?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the timezone component of <code>$arg</code>, if any. If\n                <code>$arg</code> has a timezone component, then the result is an\n                <code>xs:dayTimeDuration</code> that indicates deviation from UTC; its value may\n             range from +14:00 to -14:00 hours, both inclusive. If <code>$arg</code> has no timezone\n             component, the result is the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:timezone-from-date(xs:date("1999-05-31-05:00"))</code> returns <code>xs:dayTimeDuration("-PT5H")</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:timezone-from-date(xs:date("2000-06-12Z"))</code> returns <code>xs:dayTimeDuration("PT0S")</code>.</p></div>\n',summary:"<p>  Returns the timezone component of an  xs:date .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:date",occurrence:"?",description:""}],returns:{type:"xs:dayTimeDuration?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"timezone-from-dateTime",qname:"fn:timezone-from-dateTime",signature:"($arg as xs:dateTime?) as xs:dayTimeDuration? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the timezone component of an <code>xs:dateTime</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="timezone-from-dateTime" return-type="xs:dayTimeDuration?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:dateTime?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the timezone component of <code>$arg</code>, if any. If\n                <code>$arg</code> has a timezone component, then the result is an\n                <code>xs:dayTimeDuration</code> that indicates deviation from UTC; its value may\n             range from +14:00 to -14:00 hours, both inclusive. If <code>$arg</code> has no timezone\n             component, the result is the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:timezone-from-dateTime(xs:dateTime("1999-05-31T13:20:00-05:00"))</code> returns <code>xs:dayTimeDuration("-PT5H")</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:timezone-from-dateTime(xs:dateTime("2000-06-12T13:20:00Z"))</code> returns <code>xs:dayTimeDuration("PT0S")</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:timezone-from-dateTime(xs:dateTime("2004-08-27T00:00:00"))</code> returns <code>()</code>.</p></div>\n',summary:"<p>  Returns the timezone component of an  xs:dateTime .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:dateTime",occurrence:"?",description:""}],returns:{type:"xs:dayTimeDuration?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"timezone-from-time",qname:"fn:timezone-from-time",signature:"($arg as xs:time?) as xs:dayTimeDuration? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the timezone component of an <code>xs:time</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="timezone-from-time" return-type="xs:dayTimeDuration?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:time?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the timezone component of <code>$arg</code>, if any. If\n                <code>$arg</code> has a timezone component, then the result is an\n                <code>xs:dayTimeDuration</code> that indicates deviation from UTC; its value may\n             range from +14:00 to -14:00 hours, both inclusive. If <code>$arg</code> has no timezone\n             component, the result is the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:timezone-from-time(xs:time("13:20:00-05:00"))</code> returns <code>xs:dayTimeDuration("-PT5H")</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:timezone-from-time(xs:time("13:20:00"))</code> returns <code>()</code>.</p></div>\n',summary:"<p>  Returns the timezone component of an  xs:time .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:time",occurrence:"?",description:""}],returns:{type:"xs:dayTimeDuration?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"tokenize",qname:"fn:tokenize",signature:"($input as xs:string?, $pattern as xs:string) as xs:string* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of strings constructed by splitting the input wherever a\n             separator is found; the separator is any substring that matches a given regular\n             expression.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="tokenize" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/></proto></example><example role="signature"><proto name="tokenize" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="flags" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of calling the first version of this function (omitting the argument\n                <code>$flags</code>) is the same as the effect of calling the second version with the\n                <code>$flags</code> argument set to a zero-length string. Flags are defined in\n                <specref ref="flags"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$flags</code> argument is interpreted in the same way as for the\n                <code>fn:matches</code> function.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$input</code> is the empty sequence, or if <code>$input</code> is the\n             zero-length string, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence of strings formed by breaking the <code>$input</code>\n             string into a sequence of strings, treating any substring that matches\n                <code>$pattern</code> as a separator. The separators themselves are not returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If a separator occurs at the start of the <code>$input</code> string, the result\n             sequence will start with a zero-length string. Zero-length strings will also occur in\n             the result sequence if a separator occurs at the end of the <code>$input</code> string,\n             or if two adjacent substrings match the supplied <code>$pattern</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If two alternatives within the supplied <code>$pattern</code> both match at the same\n             position in the <code>$input</code> string, then the match that is chosen is the first.\n             For example:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:tokenize("abracadabra", "(ab)|(a)") returns ("", "r", "c", "d", "r", "")</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0002"/> if the value of\n                <code>$pattern</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0001"/> if the value of\n                <code>$flags</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0003"/> if the supplied\n                <code>$pattern</code> matches a zero-length string, that is, if <code>fn:matches("",\n                $pattern, $flags)</code> returns <code>true</code>. </p></div>\n',summary:"<p>  Returns a sequence of strings constructed by splitting the input wherever a\n             separator is found; the separator is any substring that matches a given regular\n             expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:""},{name:"pattern",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"tokenize",qname:"fn:tokenize",signature:"($input as xs:string?, $pattern as xs:string, $flags as xs:string) as xs:string* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of strings constructed by splitting the input wherever a\n             separator is found; the separator is any substring that matches a given regular\n             expression.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="tokenize" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/></proto></example><example role="signature"><proto name="tokenize" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="flags" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The effect of calling the first version of this function (omitting the argument\n                <code>$flags</code>) is the same as the effect of calling the second version with the\n                <code>$flags</code> argument set to a zero-length string. Flags are defined in\n                <specref ref="flags"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$flags</code> argument is interpreted in the same way as for the\n                <code>fn:matches</code> function.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$input</code> is the empty sequence, or if <code>$input</code> is the\n             zero-length string, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns a sequence of strings formed by breaking the <code>$input</code>\n             string into a sequence of strings, treating any substring that matches\n                <code>$pattern</code> as a separator. The separators themselves are not returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If a separator occurs at the start of the <code>$input</code> string, the result\n             sequence will start with a zero-length string. Zero-length strings will also occur in\n             the result sequence if a separator occurs at the end of the <code>$input</code> string,\n             or if two adjacent substrings match the supplied <code>$pattern</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> If two alternatives within the supplied <code>$pattern</code> both match at the same\n             position in the <code>$input</code> string, then the match that is chosen is the first.\n             For example:</p><eg xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" xml:space="preserve"> fn:tokenize("abracadabra", "(ab)|(a)") returns ("", "r", "c", "d", "r", "")</eg><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0002"/> if the value of\n                <code>$pattern</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0001"/> if the value of\n                <code>$flags</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RX" code="0003"/> if the supplied\n                <code>$pattern</code> matches a zero-length string, that is, if <code>fn:matches("",\n                $pattern, $flags)</code> returns <code>true</code>. </p></div>\n',summary:"<p>  Returns a sequence of strings constructed by splitting the input wherever a\n             separator is found; the separator is any substring that matches a given regular\n             expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:""},{name:"pattern",type:"xs:string",occurrence:null,description:""},{name:"flags",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"trace",qname:"fn:trace",signature:"($value as item()*, $label as xs:string) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Provides an execution trace intended to be used in debugging queries.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="trace" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="item()*"/><arg name="label" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the value of <code>$value</code>, unchanged.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In addition, the values of <code>$value</code>, converted to an <code>xs:string</code>,\n             and <code>$label</code>\n             <rfc2119>may</rfc2119> be directed to a trace data set. The destination of the trace\n             output is <termref def="implementation-defined"/>. The format of the trace output is\n                <termref def="implementation-dependent"/>. The ordering of output from calls of the\n                <code>fn:trace</code> function is <termref def="implementation-dependent"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Consider a situation in which a user wants to investigate the actual value passed to\n                a function. Assume that in a particular execution, <code>$v</code> is an\n                   <code>xs:decimal</code> with value <code>124.84</code>. Writing <code>fn:trace($v,\n                   \'the value of $v is:\')</code> will put the strings <code>"124.84"</code> and\n                   <code>"the value of $v is:"</code> in the trace data set in implementation\n                dependent order.</p></div>\n',summary:"<p>  Provides an execution trace intended to be used in debugging queries.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"item()",occurrence:"*",description:""},{name:"label",type:"xs:string",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"translate",qname:"fn:translate",signature:"($arg as xs:string?, $mapString as xs:string, $transString as xs:string) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of <code>$arg</code> modified by replacing or removing\n             individual characters. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="translate" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/><arg name="mapString" type="xs:string"/><arg name="transString" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the function returns the\n             zero-length string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns a result string constructed by processing each <termref def="character">character</termref> in the value of <code>$arg</code>, in order,\n             according to the following rules:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>If the character does not appear in the value of <code>$mapString</code> then it\n                   is added to the result string unchanged.</p></item><item><p>If the character first appears in the value of <code>$mapString</code> at some\n                   position <emph>M</emph>, where the value of <code>$transString</code> is\n                      <emph>M</emph> or more characters in length, then the character at position\n                      <emph>M</emph> in <code>$transString</code> is added to the result string.</p></item><item><p>If the character first appears in the value of <code>$mapString</code> at some\n                   position <emph>M</emph>, where the value of <code>$transString</code> is less than\n                      <emph>M</emph> characters in length, then the character is omitted from the\n                   result string.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$mapString</code> is the zero-length string then the function returns\n                <code>$arg</code> unchanged.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If a character occurs more than once in <code>$mapString</code>, then the first\n             occurrence determines the action taken.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$transString</code> is longer than <code>$mapString</code>, the excess\n             characters are ignored.</p></div>\n',summary:"<p>  Returns the value of  $arg  modified by replacing or removing\n             individual characters.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""},{name:"mapString",type:"xs:string",occurrence:null,description:""},{name:"transString",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:0,name:"true",qname:"fn:true",signature:"() as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the <code>xs:boolean</code> value <code>true</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="true" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result is equivalent to <code>xs:boolean("1")</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:true()</code> returns <code>xs:boolean(1)</code>.</p></div>\n',summary:"<p>  Returns the  xs:boolean  value  true .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"unordered",qname:"fn:unordered",signature:"($sourceSeq as item()*) as item()* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the items of <code>$sourceSeq</code> in an <termref def="implementation-dependent"/> order.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unordered" return-type="item()*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="sourceSeq" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The function returns the items of <code>$sourceSeq</code> in an <termref def="implementation-dependent"/> order.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Query optimizers may be able to do a better job if the order of the output sequence is\n             not specified. For example, when retrieving prices from a purchase order, if an index\n             exists on prices, it may be more efficient to return the prices in index order rather\n             than in document order.</p></div>\n',summary:"<p>  Returns the items of  $sourceSeq  in an    order.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sourceSeq",type:"item()",occurrence:"*",description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"unparsed-text-available",qname:"fn:unparsed-text-available",signature:"($href as xs:string?) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Because errors in evaluating the <function>fn:unparsed-text</function> function are\n             non-recoverable, these two functions are provided to allow an application to determine\n             whether a call with particular arguments would succeed.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text-available" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text-available" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <function>fn:unparsed-text-available</function> function determines whether a call\n             on the <function>fn:unparsed-text</function> function with identical arguments would\n             return a string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the first argument is an empty sequence, the function returns false. <phrase diff="del" at="L">If the second\n             argument is an empty sequence, the function behaves as if the second argument were\n             omitted.</phrase></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In other cases, the function returns true if a call on\n                <function>fn:unparsed-text</function> with the same arguments would succeed, and\n             false if a call on <function>fn:unparsed-text</function> with the same arguments would\n             fail with a non-recoverable dynamic error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The functions <function>fn:unparsed-text</function> and\n                <function>fn:unparsed-text-available</function> have the same requirement for\n                <termref def="deterministic">determinism</termref> as the functions\n                <code>fn:doc</code> and <code>fn:doc-available</code>. This means that unless the\n             user has explicitly stated a requirement for a reduced level of determinism, either of\n             these functions if called twice with the same arguments during the course of a\n             transformation <rfc2119>must</rfc2119> return the same results each time; moreover, the\n             results of a call on <function>fn:unparsed-text-available</function>\n             <rfc2119>must</rfc2119> be consistent with the results of a subsequent call on\n                <function>unparsed-text</function> with the same arguments.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This requires that the <function>unparsed-text-available</function> function should\n             actually attempt to read the resource identified by the URI, and check that it is\n             correctly encoded and contains no characters that are invalid in XML. Implementations\n             may avoid the cost of repeating these checks for example by caching the validated\n             contents of the resource, to anticipate a subsequent call on the\n                <function>unparsed-text</function>\n             <phrase diff="add" at="A">or <function>unparsed-text-lines</function>\n             </phrase> function. Alternatively, implementations may be able to rewrite an expression\n             such as <code>if (unparsed-text-available(A)) then unparsed-text(A) else ...</code> to\n             generate a single call internally.</p></div>\n',summary:"<p>  Because errors in evaluating the  fn:unparsed-text  function are\n             non-recoverable, these two functions are provided to allow an application to determine\n             whether a call with particular arguments would succeed.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"unparsed-text-available",qname:"fn:unparsed-text-available",signature:"($href as xs:string?) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Because errors in evaluating the <function>fn:unparsed-text</function> function are\n             non-recoverable, these two functions are provided to allow an application to determine\n             whether a call with particular arguments would succeed.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text-available" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text-available" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <function>fn:unparsed-text-available</function> function determines whether a call\n             on the <function>fn:unparsed-text</function> function with identical arguments would\n             return a string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the first argument is an empty sequence, the function returns false. <phrase diff="del" at="L">If the second\n             argument is an empty sequence, the function behaves as if the second argument were\n             omitted.</phrase></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In other cases, the function returns true if a call on\n                <function>fn:unparsed-text</function> with the same arguments would succeed, and\n             false if a call on <function>fn:unparsed-text</function> with the same arguments would\n             fail with a non-recoverable dynamic error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The functions <function>fn:unparsed-text</function> and\n                <function>fn:unparsed-text-available</function> have the same requirement for\n                <termref def="deterministic">determinism</termref> as the functions\n                <code>fn:doc</code> and <code>fn:doc-available</code>. This means that unless the\n             user has explicitly stated a requirement for a reduced level of determinism, either of\n             these functions if called twice with the same arguments during the course of a\n             transformation <rfc2119>must</rfc2119> return the same results each time; moreover, the\n             results of a call on <function>fn:unparsed-text-available</function>\n             <rfc2119>must</rfc2119> be consistent with the results of a subsequent call on\n                <function>unparsed-text</function> with the same arguments.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This requires that the <function>unparsed-text-available</function> function should\n             actually attempt to read the resource identified by the URI, and check that it is\n             correctly encoded and contains no characters that are invalid in XML. Implementations\n             may avoid the cost of repeating these checks for example by caching the validated\n             contents of the resource, to anticipate a subsequent call on the\n                <function>unparsed-text</function>\n             <phrase diff="add" at="A">or <function>unparsed-text-lines</function>\n             </phrase> function. Alternatively, implementations may be able to rewrite an expression\n             such as <code>if (unparsed-text-available(A)) then unparsed-text(A) else ...</code> to\n             generate a single call internally.</p></div>\n',summary:"<p>  Because errors in evaluating the  fn:unparsed-text  function are\n             non-recoverable, these two functions are provided to allow an application to determine\n             whether a call with particular arguments would succeed.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"unparsed-text-available",qname:"fn:unparsed-text-available",signature:"($href as xs:string?, $encoding as xs:string) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Because errors in evaluating the <function>fn:unparsed-text</function> function are\n             non-recoverable, these two functions are provided to allow an application to determine\n             whether a call with particular arguments would succeed.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text-available" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text-available" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <function>fn:unparsed-text-available</function> function determines whether a call\n             on the <function>fn:unparsed-text</function> function with identical arguments would\n             return a string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the first argument is an empty sequence, the function returns false. <phrase diff="del" at="L">If the second\n             argument is an empty sequence, the function behaves as if the second argument were\n             omitted.</phrase></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In other cases, the function returns true if a call on\n                <function>fn:unparsed-text</function> with the same arguments would succeed, and\n             false if a call on <function>fn:unparsed-text</function> with the same arguments would\n             fail with a non-recoverable dynamic error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The functions <function>fn:unparsed-text</function> and\n                <function>fn:unparsed-text-available</function> have the same requirement for\n                <termref def="deterministic">determinism</termref> as the functions\n                <code>fn:doc</code> and <code>fn:doc-available</code>. This means that unless the\n             user has explicitly stated a requirement for a reduced level of determinism, either of\n             these functions if called twice with the same arguments during the course of a\n             transformation <rfc2119>must</rfc2119> return the same results each time; moreover, the\n             results of a call on <function>fn:unparsed-text-available</function>\n             <rfc2119>must</rfc2119> be consistent with the results of a subsequent call on\n                <function>unparsed-text</function> with the same arguments.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This requires that the <function>unparsed-text-available</function> function should\n             actually attempt to read the resource identified by the URI, and check that it is\n             correctly encoded and contains no characters that are invalid in XML. Implementations\n             may avoid the cost of repeating these checks for example by caching the validated\n             contents of the resource, to anticipate a subsequent call on the\n                <function>unparsed-text</function>\n             <phrase diff="add" at="A">or <function>unparsed-text-lines</function>\n             </phrase> function. Alternatively, implementations may be able to rewrite an expression\n             such as <code>if (unparsed-text-available(A)) then unparsed-text(A) else ...</code> to\n             generate a single call internally.</p></div>\n',summary:"<p>  Because errors in evaluating the  fn:unparsed-text  function are\n             non-recoverable, these two functions are provided to allow an application to determine\n             whether a call with particular arguments would succeed.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""},{name:"encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"unparsed-text-available",qname:"fn:unparsed-text-available",signature:"($href as xs:string?, $encoding as xs:string) as xs:boolean external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Because errors in evaluating the <function>fn:unparsed-text</function> function are\n             non-recoverable, these two functions are provided to allow an application to determine\n             whether a call with particular arguments would succeed.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text-available" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text-available" return-type="xs:boolean" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <function>fn:unparsed-text-available</function> function determines whether a call\n             on the <function>fn:unparsed-text</function> function with identical arguments would\n             return a string.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the first argument is an empty sequence, the function returns false. <phrase diff="del" at="L">If the second\n             argument is an empty sequence, the function behaves as if the second argument were\n             omitted.</phrase></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In other cases, the function returns true if a call on\n                <function>fn:unparsed-text</function> with the same arguments would succeed, and\n             false if a call on <function>fn:unparsed-text</function> with the same arguments would\n             fail with a non-recoverable dynamic error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The functions <function>fn:unparsed-text</function> and\n                <function>fn:unparsed-text-available</function> have the same requirement for\n                <termref def="deterministic">determinism</termref> as the functions\n                <code>fn:doc</code> and <code>fn:doc-available</code>. This means that unless the\n             user has explicitly stated a requirement for a reduced level of determinism, either of\n             these functions if called twice with the same arguments during the course of a\n             transformation <rfc2119>must</rfc2119> return the same results each time; moreover, the\n             results of a call on <function>fn:unparsed-text-available</function>\n             <rfc2119>must</rfc2119> be consistent with the results of a subsequent call on\n                <function>unparsed-text</function> with the same arguments.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This requires that the <function>unparsed-text-available</function> function should\n             actually attempt to read the resource identified by the URI, and check that it is\n             correctly encoded and contains no characters that are invalid in XML. Implementations\n             may avoid the cost of repeating these checks for example by caching the validated\n             contents of the resource, to anticipate a subsequent call on the\n                <function>unparsed-text</function>\n             <phrase diff="add" at="A">or <function>unparsed-text-lines</function>\n             </phrase> function. Alternatively, implementations may be able to rewrite an expression\n             such as <code>if (unparsed-text-available(A)) then unparsed-text(A) else ...</code> to\n             generate a single call internally.</p></div>\n',summary:"<p>  Because errors in evaluating the  fn:unparsed-text  function are\n             non-recoverable, these two functions are provided to allow an application to determine\n             whether a call with particular arguments would succeed.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""},{name:"encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"unparsed-text-lines",qname:"fn:unparsed-text-lines",signature:"($href as xs:string?) as xs:string* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>fn:unparsed-text-lines</code> function reads an external resource (for\n             example, a file) and returns its contents as a sequence of strings, one for each line of\n             text in the  <phrase diff="chg" at="L">string representation</phrase> of the resource.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text-lines" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text-lines" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>unparsed-text-lines</code> function reads an external resource (for example, a\n             file) and returns its <phrase diff="chg" at="L">string representation</phrase> as a sequence of strings, separated at newline\n             boundaries. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the single-argument function is the same as the result of the expression\n                <code>fn:tokenize(fn:unparsed-text($href), \'\\r\\n|\\r|\\n\')[not(position()=last() and\n                .=\'\')]</code>. The result of the two-argument function is the same as the result of\n             the expression <code>fn:tokenize(fn:unparsed-text($href, $encoding),\n                \'\\r\\n|\\r|\\n\'))[not(position()=last() and .=\'\')]</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result is a thus a sequence of strings containing the text of the resource retrieved\n             using the URI, each string representing one line of text. Lines are separated by one of\n             the sequences x0A, x0D, or x0Dx0A. The characters representing the newline are not\n             included in the returned strings. If there are two adjacent newline sequences, a\n             zero-length string will be returned to represent the empty line; but if the external\n             resource ends with a newline sequence, no zero-length string will be returned as the\n             last item in the result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Error conditions are the same as for the <code>fn:unparsed-text</code> function.</p></div>\n',summary:"<p>  The  fn:unparsed-text-lines  function reads an external resource (for\n             example, a file) and returns its contents as a sequence of strings, one for each line of\n             text in the   string representation  of the resource.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"unparsed-text-lines",qname:"fn:unparsed-text-lines",signature:"($href as xs:string?, $encoding as xs:string) as xs:string* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>fn:unparsed-text-lines</code> function reads an external resource (for\n             example, a file) and returns its contents as a sequence of strings, one for each line of\n             text in the  <phrase diff="chg" at="L">string representation</phrase> of the resource.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text-lines" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text-lines" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>unparsed-text-lines</code> function reads an external resource (for example, a\n             file) and returns its <phrase diff="chg" at="L">string representation</phrase> as a sequence of strings, separated at newline\n             boundaries. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the single-argument function is the same as the result of the expression\n                <code>fn:tokenize(fn:unparsed-text($href), \'\\r\\n|\\r|\\n\')[not(position()=last() and\n                .=\'\')]</code>. The result of the two-argument function is the same as the result of\n             the expression <code>fn:tokenize(fn:unparsed-text($href, $encoding),\n                \'\\r\\n|\\r|\\n\'))[not(position()=last() and .=\'\')]</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result is a thus a sequence of strings containing the text of the resource retrieved\n             using the URI, each string representing one line of text. Lines are separated by one of\n             the sequences x0A, x0D, or x0Dx0A. The characters representing the newline are not\n             included in the returned strings. If there are two adjacent newline sequences, a\n             zero-length string will be returned to represent the empty line; but if the external\n             resource ends with a newline sequence, no zero-length string will be returned as the\n             last item in the result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Error conditions are the same as for the <code>fn:unparsed-text</code> function.</p></div>\n',summary:"<p>  The  fn:unparsed-text-lines  function reads an external resource (for\n             example, a file) and returns its contents as a sequence of strings, one for each line of\n             text in the   string representation  of the resource.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""},{name:"encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"unparsed-text-lines",qname:"fn:unparsed-text-lines",signature:"($href as xs:string?, $encoding as xs:string) as xs:string* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>fn:unparsed-text-lines</code> function reads an external resource (for\n             example, a file) and returns its contents as a sequence of strings, one for each line of\n             text in the  <phrase diff="chg" at="L">string representation</phrase> of the resource.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text-lines" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text-lines" return-type="xs:string*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>unparsed-text-lines</code> function reads an external resource (for example, a\n             file) and returns its <phrase diff="chg" at="L">string representation</phrase> as a sequence of strings, separated at newline\n             boundaries. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the single-argument function is the same as the result of the expression\n                <code>fn:tokenize(fn:unparsed-text($href), \'\\r\\n|\\r|\\n\')[not(position()=last() and\n                .=\'\')]</code>. The result of the two-argument function is the same as the result of\n             the expression <code>fn:tokenize(fn:unparsed-text($href, $encoding),\n                \'\\r\\n|\\r|\\n\'))[not(position()=last() and .=\'\')]</code>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result is a thus a sequence of strings containing the text of the resource retrieved\n             using the URI, each string representing one line of text. Lines are separated by one of\n             the sequences x0A, x0D, or x0Dx0A. The characters representing the newline are not\n             included in the returned strings. If there are two adjacent newline sequences, a\n             zero-length string will be returned to represent the empty line; but if the external\n             resource ends with a newline sequence, no zero-length string will be returned as the\n             last item in the result.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Error conditions are the same as for the <code>fn:unparsed-text</code> function.</p></div>\n',summary:"<p>  The  fn:unparsed-text-lines  function reads an external resource (for\n             example, a file) and returns its contents as a sequence of strings, one for each line of\n             text in the   string representation  of the resource.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""},{name:"encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"unparsed-text",qname:"fn:unparsed-text",signature:"($href as xs:string?) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>fn:unparsed-text</code> function reads an external resource (for example, a\n             file) and returns <phrase diff="chg" at="L">a string representation of the resource</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$href</code> argument <rfc2119>must</rfc2119> be a string in the form of a URI\n             reference, which <rfc2119>must</rfc2119> contain no fragment identifier, and\n                <rfc2119>must</rfc2119> identify a resource\n             <phrase diff="chg" at="L">for which a string representation is available</phrase>. If the URI is a\n             relative URI reference, then it is resolved relative to the\n             <phrase diff="chg" at="L">Static Base URI property from the static context</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">The mapping of URIs to the string representation of a resource is the mapping defined\n             in the <xtermref spec="XP30" ref="dt-available-text-resources">available text resources</xtermref>\n          component of the dynamic context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of the <code>$href</code> argument is an empty sequence, the function\n             returns an empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$encoding</code> argument, if present, is the name of an encoding. The values\n             for this attribute follow the same rules as for the <code>encoding</code> attribute in\n             an XML declaration. The only values which every <termref def="implementation">implementation</termref> is <rfc2119>required</rfc2119> to recognize are\n                <code>utf-8</code> and <code>utf-16</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The encoding of the external resource is determined as follows:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>external encoding information is used if available, otherwise</p></item><item><p>if the media type of the resource is <code>text/xml</code> or\n                      <code>application/xml</code> (see <bibref ref="rfc2376"/>), or if it matches\n                   the conventions <code>text/*+xml</code> or <code>application/*+xml</code> (see\n                      <bibref ref="rfc3023"/> and/or its successors), then the encoding is recognized\n                   as specified in <bibref ref="REC-xml"/>, otherwise</p></item><item><p>the value of the <code>$encoding</code> argument is used if present, otherwise</p></item><item><p>the processor <rfc2119>may</rfc2119> use <termref def="implementation-defined">implementation-defined</termref> heuristics to determine the likely encoding,\n                   otherwise</p></item><item><p>UTF-8 is assumed.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function is a string containing the\n             <phrase diff="chg" at="L">string representation</phrase> of the resource retrieved\n             using the URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1170"/> if <code>$href</code>\n             contains a fragment identifier, or if it cannot be used to retrieve the\n             <phrase diff="chg" at="L">string representation</phrase> of a resource.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1190"/> <phrase diff="add" at="L">if the value\n             of the <code>$encoding</code> argument is not a valid encoding name, </phrase>if the <termref def="dt-processor">processor</termref> does not support the specified encoding,\n             if the <phrase diff="chg" at="L">string representation</phrase> of the retrieved\n             resource contains octets that cannot be decoded into Unicode <termref def="character">characters</termref> using the specified encoding, or if the resulting characters\n             are not permitted XML characters.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1200"/> if\n                <code>$encoding</code> is absent and the <termref def="dt-processor">processor</termref> cannot infer the encoding using external information and the\n             encoding is not UTF-8.</p></div>\n',summary:"<p>  The  fn:unparsed-text  function reads an external resource (for example, a\n             file) and returns  a string representation of the resource .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"unparsed-text",qname:"fn:unparsed-text",signature:"($href as xs:string?) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>fn:unparsed-text</code> function reads an external resource (for example, a\n             file) and returns <phrase diff="chg" at="L">a string representation of the resource</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$href</code> argument <rfc2119>must</rfc2119> be a string in the form of a URI\n             reference, which <rfc2119>must</rfc2119> contain no fragment identifier, and\n                <rfc2119>must</rfc2119> identify a resource\n             <phrase diff="chg" at="L">for which a string representation is available</phrase>. If the URI is a\n             relative URI reference, then it is resolved relative to the\n             <phrase diff="chg" at="L">Static Base URI property from the static context</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">The mapping of URIs to the string representation of a resource is the mapping defined\n             in the <xtermref spec="XP30" ref="dt-available-text-resources">available text resources</xtermref>\n          component of the dynamic context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of the <code>$href</code> argument is an empty sequence, the function\n             returns an empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$encoding</code> argument, if present, is the name of an encoding. The values\n             for this attribute follow the same rules as for the <code>encoding</code> attribute in\n             an XML declaration. The only values which every <termref def="implementation">implementation</termref> is <rfc2119>required</rfc2119> to recognize are\n                <code>utf-8</code> and <code>utf-16</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The encoding of the external resource is determined as follows:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>external encoding information is used if available, otherwise</p></item><item><p>if the media type of the resource is <code>text/xml</code> or\n                      <code>application/xml</code> (see <bibref ref="rfc2376"/>), or if it matches\n                   the conventions <code>text/*+xml</code> or <code>application/*+xml</code> (see\n                      <bibref ref="rfc3023"/> and/or its successors), then the encoding is recognized\n                   as specified in <bibref ref="REC-xml"/>, otherwise</p></item><item><p>the value of the <code>$encoding</code> argument is used if present, otherwise</p></item><item><p>the processor <rfc2119>may</rfc2119> use <termref def="implementation-defined">implementation-defined</termref> heuristics to determine the likely encoding,\n                   otherwise</p></item><item><p>UTF-8 is assumed.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function is a string containing the\n             <phrase diff="chg" at="L">string representation</phrase> of the resource retrieved\n             using the URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1170"/> if <code>$href</code>\n             contains a fragment identifier, or if it cannot be used to retrieve the\n             <phrase diff="chg" at="L">string representation</phrase> of a resource.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1190"/> <phrase diff="add" at="L">if the value\n             of the <code>$encoding</code> argument is not a valid encoding name, </phrase>if the <termref def="dt-processor">processor</termref> does not support the specified encoding,\n             if the <phrase diff="chg" at="L">string representation</phrase> of the retrieved\n             resource contains octets that cannot be decoded into Unicode <termref def="character">characters</termref> using the specified encoding, or if the resulting characters\n             are not permitted XML characters.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1200"/> if\n                <code>$encoding</code> is absent and the <termref def="dt-processor">processor</termref> cannot infer the encoding using external information and the\n             encoding is not UTF-8.</p></div>\n',summary:"<p>  The  fn:unparsed-text  function reads an external resource (for example, a\n             file) and returns  a string representation of the resource .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"unparsed-text",qname:"fn:unparsed-text",signature:"($href as xs:string?, $encoding as xs:string) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>fn:unparsed-text</code> function reads an external resource (for example, a\n             file) and returns <phrase diff="chg" at="L">a string representation of the resource</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$href</code> argument <rfc2119>must</rfc2119> be a string in the form of a URI\n             reference, which <rfc2119>must</rfc2119> contain no fragment identifier, and\n                <rfc2119>must</rfc2119> identify a resource\n             <phrase diff="chg" at="L">for which a string representation is available</phrase>. If the URI is a\n             relative URI reference, then it is resolved relative to the\n             <phrase diff="chg" at="L">Static Base URI property from the static context</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">The mapping of URIs to the string representation of a resource is the mapping defined\n             in the <xtermref spec="XP30" ref="dt-available-text-resources">available text resources</xtermref>\n          component of the dynamic context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of the <code>$href</code> argument is an empty sequence, the function\n             returns an empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$encoding</code> argument, if present, is the name of an encoding. The values\n             for this attribute follow the same rules as for the <code>encoding</code> attribute in\n             an XML declaration. The only values which every <termref def="implementation">implementation</termref> is <rfc2119>required</rfc2119> to recognize are\n                <code>utf-8</code> and <code>utf-16</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The encoding of the external resource is determined as follows:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>external encoding information is used if available, otherwise</p></item><item><p>if the media type of the resource is <code>text/xml</code> or\n                      <code>application/xml</code> (see <bibref ref="rfc2376"/>), or if it matches\n                   the conventions <code>text/*+xml</code> or <code>application/*+xml</code> (see\n                      <bibref ref="rfc3023"/> and/or its successors), then the encoding is recognized\n                   as specified in <bibref ref="REC-xml"/>, otherwise</p></item><item><p>the value of the <code>$encoding</code> argument is used if present, otherwise</p></item><item><p>the processor <rfc2119>may</rfc2119> use <termref def="implementation-defined">implementation-defined</termref> heuristics to determine the likely encoding,\n                   otherwise</p></item><item><p>UTF-8 is assumed.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function is a string containing the\n             <phrase diff="chg" at="L">string representation</phrase> of the resource retrieved\n             using the URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1170"/> if <code>$href</code>\n             contains a fragment identifier, or if it cannot be used to retrieve the\n             <phrase diff="chg" at="L">string representation</phrase> of a resource.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1190"/> <phrase diff="add" at="L">if the value\n             of the <code>$encoding</code> argument is not a valid encoding name, </phrase>if the <termref def="dt-processor">processor</termref> does not support the specified encoding,\n             if the <phrase diff="chg" at="L">string representation</phrase> of the retrieved\n             resource contains octets that cannot be decoded into Unicode <termref def="character">characters</termref> using the specified encoding, or if the resulting characters\n             are not permitted XML characters.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1200"/> if\n                <code>$encoding</code> is absent and the <termref def="dt-processor">processor</termref> cannot infer the encoding using external information and the\n             encoding is not UTF-8.</p></div>\n',summary:"<p>  The  fn:unparsed-text  function reads an external resource (for example, a\n             file) and returns  a string representation of the resource .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""},{name:"encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"unparsed-text",qname:"fn:unparsed-text",signature:"($href as xs:string?, $encoding as xs:string) as xs:string? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>fn:unparsed-text</code> function reads an external resource (for example, a\n             file) and returns <phrase diff="chg" at="L">a string representation of the resource</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="unparsed-text" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/></proto></example><example role="signature"><proto name="unparsed-text" return-type="xs:string?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="encoding" type="xs:string"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$href</code> argument <rfc2119>must</rfc2119> be a string in the form of a URI\n             reference, which <rfc2119>must</rfc2119> contain no fragment identifier, and\n                <rfc2119>must</rfc2119> identify a resource\n             <phrase diff="chg" at="L">for which a string representation is available</phrase>. If the URI is a\n             relative URI reference, then it is resolved relative to the\n             <phrase diff="chg" at="L">Static Base URI property from the static context</phrase>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="add" at="L">The mapping of URIs to the string representation of a resource is the mapping defined\n             in the <xtermref spec="XP30" ref="dt-available-text-resources">available text resources</xtermref>\n          component of the dynamic context.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of the <code>$href</code> argument is an empty sequence, the function\n             returns an empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The <code>$encoding</code> argument, if present, is the name of an encoding. The values\n             for this attribute follow the same rules as for the <code>encoding</code> attribute in\n             an XML declaration. The only values which every <termref def="implementation">implementation</termref> is <rfc2119>required</rfc2119> to recognize are\n                <code>utf-8</code> and <code>utf-16</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The encoding of the external resource is determined as follows:</p><olist xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><item><p>external encoding information is used if available, otherwise</p></item><item><p>if the media type of the resource is <code>text/xml</code> or\n                      <code>application/xml</code> (see <bibref ref="rfc2376"/>), or if it matches\n                   the conventions <code>text/*+xml</code> or <code>application/*+xml</code> (see\n                      <bibref ref="rfc3023"/> and/or its successors), then the encoding is recognized\n                   as specified in <bibref ref="REC-xml"/>, otherwise</p></item><item><p>the value of the <code>$encoding</code> argument is used if present, otherwise</p></item><item><p>the processor <rfc2119>may</rfc2119> use <termref def="implementation-defined">implementation-defined</termref> heuristics to determine the likely encoding,\n                   otherwise</p></item><item><p>UTF-8 is assumed.</p></item></olist><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The result of the function is a string containing the\n             <phrase diff="chg" at="L">string representation</phrase> of the resource retrieved\n             using the URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1170"/> if <code>$href</code>\n             contains a fragment identifier, or if it cannot be used to retrieve the\n             <phrase diff="chg" at="L">string representation</phrase> of a resource.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1190"/> <phrase diff="add" at="L">if the value\n             of the <code>$encoding</code> argument is not a valid encoding name, </phrase>if the <termref def="dt-processor">processor</termref> does not support the specified encoding,\n             if the <phrase diff="chg" at="L">string representation</phrase> of the retrieved\n             resource contains octets that cannot be decoded into Unicode <termref def="character">characters</termref> using the specified encoding, or if the resulting characters\n             are not permitted XML characters.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="UT" code="1200"/> if\n                <code>$encoding</code> is absent and the <termref def="dt-processor">processor</termref> cannot infer the encoding using external information and the\n             encoding is not UTF-8.</p></div>\n',summary:"<p>  The  fn:unparsed-text  function reads an external resource (for example, a\n             file) and returns  a string representation of the resource .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"href",type:"xs:string",occurrence:"?",description:""},{name:"encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"upper-case",qname:"fn:upper-case",signature:"($arg as xs:string?) as xs:string external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Converts a string to upper case.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="upper-case" return-type="xs:string" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is the empty sequence, the zero-length string is\n             returned.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns the value of <code>$arg</code> after translating every\n                <termref def="character">character</termref> to its upper-case correspondent as\n             defined in the appropriate case mappings section in the Unicode standard <bibref ref="Unicode"/>. For versions of Unicode beginning with the 2.1.8 update, only\n             locale-insensitive case mappings should be applied. Beginning with version 3.2.0 (and\n             likely future versions) of Unicode, precise mappings are described in default case\n             operations, which are full case mappings in the absence of tailoring for particular\n             languages and environments. Every lower-case character that does not have an upper-case\n             correspondent, as well as every upper-case character, is included in the returned value\n             in its original form. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Case mappings may change the length of a string. In general, the\n                <code>fn:upper-case</code> and <code>fn:lower-case</code> functions are not inverses\n             of each other: <code>fn:lower-case(fn:upper-case($arg))</code> is not guaranteed to\n             return <code>$arg</code>, nor is <code>fn:upper-case(fn:lower-case($arg))</code>. The\n             Latin small letter dotless i (as used in Turkish) is perhaps the most prominent\n             lower-case letter which will not round-trip. The Latin capital letter i with dot above\n             is the most prominent upper-case letter which will not round trip; there are others,\n             such as Latin capital letter Sharp S (#1E9E) which is introduced in Unicode 5.1.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> These functions may not always be linguistically appropriate (e.g. Turkish i without\n             dot) or appropriate for the application (e.g. titlecase). In cases such as Turkish, a\n             simple translation should be used first.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> Because the function is not sensitive to locale, results will not always match user\n             expectations. In Quebec, for example, the standard uppercase equivalent of "\u00e8" is "\u00c8",\n             while in metropolitan France it is more commonly "E"; only one of these is supported by\n             the functions as defined.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"> Many characters of class Ll lack uppercase equivalents in the Unicode case mapping\n             tables; many characters of class Lu lack lowercase equivalents.</p></div>\n',summary:"<p>  Converts a string to upper case.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:0,name:"uri-collection",qname:"fn:uri-collection",signature:"() as xs:anyURI* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of <code>xs:anyURI</code> values representing the URIs in a resource collection.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="uri-collection" return-type="xs:anyURI*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="uri-collection" return-type="xs:anyURI*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		available resource collections, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of the function returns the URIs in the <term>Default resource collection</term>\n             described in <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is a relative <code>xs:anyURI</code>, it is resolved\n             against the value of the base-URI property from the static context. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function behaves as if it had been\n             called without an argument. See above.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The single-argument form of the function returns the sequence of URIs corresponding to the\n             supplied URI in the <term>Available resource collections</term> described in\n             <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if no URI is supplied (that is, if the\n             the function is called with no arguments, or with a single argument that evaluates to an empty sequence), and the\n             value of the default resource collection is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="J">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/>\n             if <term>available resource collections</term> provides no mapping for the absolutized URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0004"/> if <code>$arg</code> is not a\n             valid <code>xs:anyURI</code>.</p></div>\n',summary:"<p>  Returns a sequence of  xs:anyURI  values representing the URIs in a resource collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyURI*",description:""},errors:[]},{isDocumented:!0,arity:0,name:"uri-collection",qname:"fn:uri-collection",signature:"() as xs:anyURI* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of <code>xs:anyURI</code> values representing the URIs in a resource collection.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="uri-collection" return-type="xs:anyURI*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="uri-collection" return-type="xs:anyURI*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		available resource collections, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of the function returns the URIs in the <term>Default resource collection</term>\n             described in <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is a relative <code>xs:anyURI</code>, it is resolved\n             against the value of the base-URI property from the static context. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function behaves as if it had been\n             called without an argument. See above.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The single-argument form of the function returns the sequence of URIs corresponding to the\n             supplied URI in the <term>Available resource collections</term> described in\n             <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if no URI is supplied (that is, if the\n             the function is called with no arguments, or with a single argument that evaluates to an empty sequence), and the\n             value of the default resource collection is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="J">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/>\n             if <term>available resource collections</term> provides no mapping for the absolutized URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0004"/> if <code>$arg</code> is not a\n             valid <code>xs:anyURI</code>.</p></div>\n',summary:"<p>  Returns a sequence of  xs:anyURI  values representing the URIs in a resource collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyURI*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"uri-collection",qname:"fn:uri-collection",signature:"($arg as xs:string?) as xs:anyURI* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of <code>xs:anyURI</code> values representing the URIs in a resource collection.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="uri-collection" return-type="xs:anyURI*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="uri-collection" return-type="xs:anyURI*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		available resource collections, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of the function returns the URIs in the <term>Default resource collection</term>\n             described in <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is a relative <code>xs:anyURI</code>, it is resolved\n             against the value of the base-URI property from the static context. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function behaves as if it had been\n             called without an argument. See above.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The single-argument form of the function returns the sequence of URIs corresponding to the\n             supplied URI in the <term>Available resource collections</term> described in\n             <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if no URI is supplied (that is, if the\n             the function is called with no arguments, or with a single argument that evaluates to an empty sequence), and the\n             value of the default resource collection is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="J">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/>\n             if <term>available resource collections</term> provides no mapping for the absolutized URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0004"/> if <code>$arg</code> is not a\n             valid <code>xs:anyURI</code>.</p></div>\n',summary:"<p>  Returns a sequence of  xs:anyURI  values representing the URIs in a resource collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:anyURI*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"uri-collection",qname:"fn:uri-collection",signature:"($arg as xs:string?) as xs:anyURI* external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns a sequence of <code>xs:anyURI</code> values representing the URIs in a resource collection.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="uri-collection" return-type="xs:anyURI*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example><example role="signature"><proto name="uri-collection" return-type="xs:anyURI*" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:string?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on\n 		available resource collections, and static base uri.\n 	</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The zero-argument form of the function returns the URIs in the <term>Default resource collection</term>\n             described in <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If the value of <code>$arg</code> is a relative <code>xs:anyURI</code>, it is resolved\n             against the value of the base-URI property from the static context. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function behaves as if it had been\n             called without an argument. See above.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The single-argument form of the function returns the sequence of URIs corresponding to the\n             supplied URI in the <term>Available resource collections</term> described in\n             <xspecref spec="XP30" ref="id-xp-evaluation-context-components"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/> if no URI is supplied (that is, if the\n             the function is called with no arguments, or with a single argument that evaluates to an empty sequence), and the\n             value of the default resource collection is <xtermref ref="dt-absent" spec="DM30">absent</xtermref>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="J">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0002"/>\n             if <term>available resource collections</term> provides no mapping for the absolutized URI.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="DC" code="0004"/> if <code>$arg</code> is not a\n             valid <code>xs:anyURI</code>.</p></div>\n',summary:"<p>  Returns a sequence of  xs:anyURI  values representing the URIs in a resource collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:""}],returns:{type:"xs:anyURI*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"year-from-date",qname:"fn:year-from-date",signature:"($arg as xs:date?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the year component of an <code>xs:date</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="year-from-date" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:date?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> representing the year in the\n             local value of <code>$arg</code>. The value may be negative. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:year-from-date(xs:date("1999-05-31"))</code> returns <code>1999</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:year-from-date(xs:date("2000-01-01+05:00"))</code> returns <code>2000</code>.</p></div>\n',summary:"<p>  Returns the year component of an  xs:date .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:date",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"years-from-duration",qname:"fn:years-from-duration",signature:"($arg as xs:duration?) as xs:integer? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the number of years in a duration.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="years-from-duration" return-type="xs:integer?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:duration?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise, the function returns an <code>xs:integer</code> representing the years\n             component in the value of <code>$arg</code>. The result is obtained by casting\n                <code>$arg</code> to an <code>xs:yearMonthDuration</code> (see <specref ref="casting-to-durations"/>) and then computing the years component as described in\n                <specref ref="canonical-yearMonthDuration"/>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is a negative duration then the result will be negative..</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is an <code>xs:dayTimeDuration</code> the function returns 0.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:years-from-duration(xs:yearMonthDuration("P20Y15M"))</code> returns <code>21</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:years-from-duration(xs:yearMonthDuration("-P15M"))</code> returns <code>-1</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>fn:years-from-duration(xs:dayTimeDuration("-P2DT15H"))</code> returns <code>0</code>.</p></div>\n',summary:"<p>  Returns the number of years in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:duration",occurrence:"?",description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"zero-or-one",qname:"fn:zero-or-one",signature:"($arg as item()*) as item()? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns <code>$arg</code> if it contains zero or one items. Otherwise, raises\n             an error.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="zero-or-one" return-type="item()?" isOp="no" prefix="fn" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="item()*"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Except in error cases, the function returns <code>$arg</code> unchanged.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="del" at="F">For detailed type semantics, see [Formal Semantics].</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">A <phrase diff="add" at="L">dynamic</phrase> error is raised <errorref class="RG" code="0003"/> if <code>$arg</code> contains more\n             than one item.</p></div>\n',summary:"<p>  Returns  $arg  if it contains zero or one items.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:""}],returns:{type:"item()?",description:""},errors:[]}],variables:[]},"http://zorba.io/modules/csv":{ns:"http://zorba.io/modules/csv",description:" Function library providing converters from CSV/TXT to XML and back.\n The functions are optimized to work with large amounts of data, in a streaming way.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Turcanu</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/csv",prefix:"csv"},{uri:"http://zorba.io/modules/csv-options",prefix:"csv-options"},{uri:"http://zorba.io/modules/schema",prefix:"schemaOptions"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"parse",qname:"csv:parse",signature:"($csv as xs:string, $options as element(csv-options:options)?) as element(*)*",description:' Parse a CSV or fixed size text and convert to XML.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n By default each line is converted to a &lt;row&gt; element, and each field to a &lt;column&gt; element inside &lt;row&gt;.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The format of the param $options is:<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n  <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n    &lt;csv-options:options&gt;\n        &lt;csv  [separator="default comma ,"] ?\n          [quote-char="default double quotes &amp;quote;"]?\n          [quote-escape="default double double quotes &amp;quote;&amp;quote;"]? /&gt;\n        or\n        &lt;column-widths&gt;\n          &lt;column-width&gt;<i>[column fixed width, unsigned int]</i>&lt;column-width&gt;*\n        &lt;/column-widths&gt;\n        or\n        &lt;column-positions&gt;\n          &lt;column-position&gt;<i>[column position on line, unsigned int]</i>&lt;column-position&gt;*\n        &lt;/column-positions&gt;\n        &lt;first-row-is-header [line="<i>first_line[-last_line]?</i>"]?/&gt;?\n        &lt;start-from-row line="<i>first_line[-last_line]?</i>"/&gt;?\n        &lt;add-last-void-columns/&gt;?\n        &lt;xml-nodes&gt;\n          [&lt;<i>row-name</i>&gt;\n            [&lt;<i>column-name/</i>&gt;]?\n          &lt;/<i>row-name</i>&gt;]?\n        &lt;/xml-nodes&gt;?\n    &lt;/csv-options:options&gt;\n  </pre>\n    All the parameters are optional and can appear in any order.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n    All the parameters are case sensitive. The namespace used is "http://zorba.io/modules/csv-options".<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n    All strings must have UTF-8 encoding.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n    Parameters csv, column-widths, column-positions are mutually exclusive. If none is specified,\n    the input string is assumed to be csv.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n    Description of parameters:\n    <dl xmlns:xqdoc="http://www.xqdoc.org/1.0">\n     <dt><b>csv</b></dt>\n     <dd> Specifies the parameters for parsing a csv string.<br/>\n       <dl>\n        <dt><b>separator</b></dt>\n        <dd>The character or group of characters used to separating fields in a row.\n            If it is not specified, it defaults to comma \',\'.\n        </dd>\n        <dt><b>quote-char</b></dt>\n        <dd>The character or group of characters used for quoting the fields that may contain special characters,\n             like separator, new line or this quote char. The default value is double quote ".<br/>\n        </dd>\n        <dt><b>quote-escape</b></dt>\n        <dd>The group of characters used for escaping the quote char inside a field. The whole quote escape group\n           is translated to a quote char during parsing. The default value is double double quotes "".<br/>\n        </dd>\n       </dl>\n     </dd>\n     <br/>\n     <dt><b>column-widths</b></dt>\n     <dd>Specifies the column widths for fixed size text. It contains multiple column-width child elements\n        specifying the fixed width of each column, from left to right.<br/>\n        If the line has more fields than specified, they are ignored.\n     </dd>\n     <dt><b>column-positions</b></dt>\n     <dd>This is an alternative to column-widths, and specifies instead the starting position of each column.\n        Column positions are 1 based, and are specified in order from left to right.\n        The last column is read until end of line. The first column position can be greater than 1, if you want\n        to parse only a part of the input text.\n     </dd>\n     <dt><b>first-row-is-header</b></dt>\n     <dd>The presence of this element indicates that the first row is to be treated as the name of the columns.\n        If it is not present, then each field is enclosed in a &lt;column&gt; element,\n        or how it is specified in &lt;xml-nodes&gt; parameter.<br/>\n        If the first row is the header, then each field is enclosed in an element with the corresponding name from the header.<br/>\n        For example, the csv:\n        <pre>\n        <i>ID,Name,Occupation\n        1,John,student</i>\n        </pre>\n        is parsed into:\n        <pre>\n        <i>&lt;row&gt;\n        &lt;ID&gt;1&lt;/ID&gt;\n        &lt;Name&gt;John&lt;/Name&gt;\n        &lt;Occupation&gt;student&lt;/Occupation&gt;\n        &lt;/row&gt;</i>\n        </pre>\n        If the header names contain characters that cannot be used in a QName, they are replaced with underscore \'_\'.<br/>\n        The namespace for the header QNames is taken from the column name specified in xml-nodes parameter, or from\n        the row name, or if that doesn\'t exist either then empty namespace is used. <br/>\n        If the header is not the first line in the input string, the starting line can be specified in the <b>line</b> attribute.<br/>\n        If a column does not have a name, a new name is constructed in the form <i>columnN</i> where N is the position of the column,\n        starting from 1.<br/>\n        <b>Subheaders</b><br/>\n        If the header consists of more than one line, this can be specified in the <b>line</b> attribute in the form\n        "<i>first_line - last_line</i>". Having more lines as the header translates into a hierarchy of elements in the xml.<br/>\n        For example, the csv:\n        <pre>\n        <i>ID,Name,,Occupation\n        ,First Name,Last Name,\n        1,John,Howard,student</i>\n        </pre>\n        is parsed into:\n        <pre>\n        <i>&lt;row&gt;\n        &lt;ID&gt;1&lt;/ID&gt;\n        &lt;Name&gt;\n          &lt;First_Name&gt;John&lt;/First_Name&gt;\n          &lt;Last_Name&gt;Howard&lt;/Last_Name&gt;\n        &lt;/Name&gt;\n        &lt;Occupation&gt;student&lt;/Occupation&gt;\n        &lt;/row&gt;</i>\n        </pre>\n        This element can have an attribute "accept-all-lines" with values "false" or "true" (default "false").\n        When set to true it tells the parser to not report lines that do not have the same number of items as\n        the header. If set to false, the parser will raise a csv:WrongInput error for these lines.<br/>\n     </dd>\n     <dt><b>start-from-row</b></dt>\n     <dd>If the data does not start from line 1 or immediately after the header,\n        you can specify the starting line in the <b>line</b> attribute.<br/>\n        Also you can use this attribute in the form "<i>first_line - last_line</i>" to specify also the last line\n        if you don\'t want the whole csv to be parsed.\n     </dd>\n     <dt><b>add-last-void-columns</b></dt>\n     <dd>In the case when using headers and some data lines are shorter than the header, by default the excess columns are ignored\n          for those lines. You can set the add-last-void-columns parameter to make all the columns appear in xml even if they are void.\n     </dd>\n     <dt><b>xml-nodes</b></dt>\n     <dd>With this parameter you can specify the names for the row element and for the column element if there is no header.<br/>\n        The first element child of this element specifies the desired QName of the row element in the output xml.\n        The name of this element will be used as the name of the row element.<br/>\n        The element child of this row element is the column element, and its name will be used as the name of the column elements\n        that enclose the fields in the output xml if there is no header. <br/>\n        If the csv has a header, only the namespace is used from the column element.<br/>\n        For example, with parameter:\n        <pre>\n        <i>&lt;xml-nodes&gt;\n        &lt;r&gt;\n          &lt;c/&gt;\n        &lt;/r&gt;\n        &lt;/xml-nodes&gt;</i>\n        </pre>\n        the output for each line will look like:\n        <pre>\n        <i>&lt;r&gt;\n          &lt;c&gt;field1&lt;/c&gt;\n          &lt;c&gt;field2&lt;/c&gt;\n          .......\n        &lt;/r&gt;</i>\n        </pre>\n     </dd>\n    </dl>\n',summary:"<p> Parse a CSV or fixed size text and convert to XML.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"csv",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string containing the csv or fixed size text.</div>'},{name:"options",type:"element(csv-options:options)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> this parameter is validated against "http://zorba.io/modules/csv-options" schema. If this parameter is not specified, the row name is by default "row" and the column name is by default "column".</div>'}],returns:{type:"element(*)*",description:"a sequence of row elements, one for each line in csv"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">csv:CSV001 if the input string is streamable string and cannot be rewinded</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">csv:WrongInput if the input string has lines with variable number of items, and the csv has headers and the options do not specify the ignore-foreign-input attribute</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 if $options can not be validated against the csv-options schema</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0084 if the options parameter doesn\'t have the name "csv-options:options".</xqdoc:error>']},{isDocumented:!0,arity:2,name:"serialize",qname:"csv:serialize",signature:"($xml as element(*)*, $options as element(csv-options:options)?) as xs:string",description:' Convert XML into CSV or fixed size text.\n Note: if you want to serialize out the result, make sure that the serializer method is set to "text".\n For example, in zorba command line, you have to set the param --serialize-text.\n When using the <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">file:write(...)</pre> function, you have to set the\n method serialization parameter to "text":\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n &lt;output:serialization-parameters&lt;\n   &lt;output:method value="text"/&lt;\n &lt;/output:serialization-parameters&lt;\n </pre>\n The <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">$options</pre> parameter must have the following format:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n    &lt;csv-options:options&gt;<br/>\n        &lt;csv  [separator="default comma ,"] ? <br/>\n          [quote-char="default double quotes &amp;quote;"]? <br/>\n          [quote-escape="default double double quotes &amp;quote;&amp;quote;"]? /&gt; <br/>\n        <br/>\n        or<br/>\n        &lt;column-widths [align="left|right"]?&gt;<br/>\n          &lt;column-width [align="left|right"]?&gt;<i>[column fixed width, unsigned int]</i>&lt;column-width&gt;*<br/>\n        &lt;/column-widths&gt;<br/>\n        <br/>\n        or<br/>\n        &lt;column-positions [align="left|right"]?&gt;<br/>\n          &lt;column-position [align="left|right"]?&gt;<i>[column position on line, unsigned int]</i>&lt;column-position&gt;*<br/>\n        &lt;/column-positions&gt;<br/>\n        <br/>\n        &lt;first-row-is-header/&gt;?<br/>\n    &lt;/csv-options:options&gt;\n </pre>\n All the parameters are optional and can appear in any order.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n All the parameters are case sensitive. The namespace used is "http://zorba.io/modules/csv-options".<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n All strings must have UTF-8 encoding.<br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Parameters csv, column-widths, column-positions are mutually exclusive.\n If none is specified, the xml is converted to csv.\n Description of parameters:\n    <dl xmlns:xqdoc="http://www.xqdoc.org/1.0">\n     <dt><b>csv</b></dt>\n     <dd> Specifies the parameters for converting to csv.<br/>\n       <dl>\n        <dt><b>separator</b></dt>\n        <dd>The character or group of characters used to separating fields in a row.\n            If it is not specified, it defaults to comma \',\'.\n        </dd>\n        <dt><b>quote-char</b></dt>\n        <dd>The character or group of characters used for quoting the fields that may contain special characters,\n             like separator, new line or this quote char. The default value is double quote ".<br/>\n        </dd>\n        <dt><b>quote-escape</b></dt>\n        <dd>The group of characters used for escaping the quote char inside a field. The whole quote escape group\n           is translated to a quote char during parsing. The default value is double double quotes "".<br/>\n        </dd>\n       </dl>\n     </dd>\n     <br/>\n     <dt><b>column-widths</b></dt>\n     <dd>Specifies the column widths for fixed size text. It contains multiple column-width child elements\n        specifying the fixed width of each column, from left to right.<br/>\n        With the attribute <b>align</b> you can specify how to align fields that are smaller than the column width.\n        The default alignment is left.<br/>\n     </dd>\n     <dt><b>column-positions</b></dt>\n     <dd>This is an alternative to column-widths, and specifies instead the starting position of each column.\n        Column positions are 1 based, and are specified in order from left to right.\n        The last column has a variable length.<br/>\n        With the attribute <b>align</b> you can specify how to align fields that are smaller than the column width.\n        The default alignment is left. The last column does not need alignment.<br/>\n     </dd>\n     <dt><b>first-row-is-header</b></dt>\n     <dd>The presence of this element indicates that the first row will contain the header, that is, the names of\n        the column elements. Only the column names from the first row element are taken into account.<br/>\n        For example, the row xml:<br/>\n        <i>&lt;row&gt;<br/>\n        &lt;ID&gt;1&lt;/ID&gt;<br/>\n        &lt;Name&gt;John&lt;/Name&gt;<br/>\n        &lt;Occupation&gt;student&lt;/Occupation&gt;<br/>\n        &lt;/row&gt;</i><br/>\n        <br/>\n        is converted to<br/>\n        <i>ID,Name,Occupation<br/>\n        1,John,student</i><br/>\n        <br/>\n        The header names are the localnames of the column elements, and the namespace is ignored.<br/>\n        <b>Subheaders</b><br/>\n        If the row-column hierarchy is more complex, then subheaders are also generated on subsequent lines.\n        The number of subheaders depends on the depth of the column hierarchy.<br/>\n        When generating the subheaders, the non-whitespace text nodes are also taken into account,\n        and a separate column is generated for them too.<br/>\n        For example, the xml row element:<br/>\n        <i>&lt;row&gt;<br/>\n        &lt;ID&gt;1&lt;/ID&gt;<br/>\n        &lt;Name&gt;<br/>\n          Mr.<br/>\n          &lt;First_Name&gt;John&lt;/First_Name&gt;<br/>\n          &lt;Last_Name&gt;Howard&lt;/Last_Name&gt;<br/>\n        &lt;/Name&gt;<br/>\n        &lt;Occupation&gt;student&lt;/Occupation&gt;<br/>\n        &lt;/row&gt;</i><br/>\n        is converted to<br/>\n        <i>ID,Name,,Occupation<br/>\n        ,,First Name,Last Name,<br/>\n        1,Mr.,John,Howard,student</i><br/>\n        <br/>\n        If first-row-is-header is not specified and the columns have a deeper hierarchy,\n          only the first layer of columns is processed, and the fields are the string values of each column.<br/>\n        This element can have an attribute "ignore-foreign-input" with values "false" or "true" (default "false").\n        When set to true it tells the serializer to ignore elements that to not match the header names.\n        If set to false, the serializer will raise a csv:ForeignInput error for these elements.<br/>\n     </dd>\n    </dl>\n',summary:"<p> Convert XML into CSV or fixed size text.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xml",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of elements, each element representing a row. The name of each row element is ignored. The childs of each row are the column fields.</div>'},{name:"options",type:"element(csv-options:options)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The options parameter. See the function description for details. This parameter is validated against "http://zorba.io/modules/csv-options" schema.</div>'}],returns:{type:"xs:string",description:"the csv or fixed size text as string containing all the lines"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">csv:CSV003 if the serialize output is streamable string and cannot be reset</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">csv:ForeignInput if there are input elements in subsequent rows that do not match the headers, and the options specify first-row-is-header and do not specify the ignore-foreign-input attribute</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 if $options can not be validated against csv-options schema</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0084 if the options parameter doesn\'t have the name "csv-options:options".</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/reference":{ns:"http://zorba.io/modules/reference",description:" The module provides functions to compute an immutable and opaque reference\n for nodes, objects, or arrays and to retrieve such items given their\n identifier, respectively.\n The identifiers are immutable, i.e. a identifier does not change\n during the items lifetime and cannot be reused for another item after the\n original item gets deleted.\n Identifiers are unique, in that, two different items will never have the same\n identifier. A item, at any time during its lifetime, can be retrieved by its\n identifier.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/reference",prefix:"ref"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"dereference",qname:"ref:dereference",signature:"($arg as xs:string) as item()? external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the node, object, or array identified by the given reference.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns the empty sequence if the item\n that is referenced does not exist.</p>\n',summary:"<p>  Returns the node, object, or array identified by the given reference.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URI of the item to retrieve.</div>'}],returns:{type:"item()?",description:"the item identified by the URI passed as parameter or the empty-sequence if no item with that URI is found."},errors:[]},{isDocumented:!0,arity:1,name:"reference",qname:"ref:reference",signature:"($arg as item()) as xs:string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an immutable and opaque reference (with type xs:anyURI) for\n a given node, object, or array.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The generated identifier is immutable, i.e. a identifier does not\n change during the item\'s lifetime and cannot be reused for another node after\n the original item gets deleted.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Identifiers are also unique, in that, two different items will never\n have the same identifier.</p>\n A item, at any time during its lifetime, can be retrieved by its\n identifier, using the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">ref:dereference</tt> function.\n Please note that a reference can only be retrieved for a JSON object or JSON\n array if the item is a member of a collection.\n',summary:"<p>  Returns an immutable and opaque reference (with type xs:anyURI) for\n a given node, object, or array.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node, object, or array for which the URI should be computed</div>'}],returns:{type:"xs:string",description:"the opaque URI of the item."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr::ZAPI0080 is raised if the object or array passed as argument is not a member of a collection.</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/dctx":{ns:"http://zorba.io/modules/dctx",description:" This module provides functions that gets components of the dynamic context.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/dctx",prefix:"dctx"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"snapshot-id",qname:"dctx:snapshot-id",signature:"() as xs:unsignedLong external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the current snapshot id.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned id is opaque and should not be used for reasoning about time.\n The only guarantee is that the value returned by this function increases each\n time a snapshot finishes.</p>\n',summary:"<p>  Retrieves the current snapshot id.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:unsignedLong",description:"the current snapshot id."},errors:[]}],variables:[]},"http://xbrl.io/modules/bizql/facts":{ns:"http://xbrl.io/modules/bizql/facts",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functions for retrieving facts.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Facts are the smallest reportable piece of information.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Facts have a certain number of characteristics: the archive in\n which they were reported, a number of XBRL aspects (concept, entity, period,\n unit, further XBRL dimensions), as well as profile-specific information.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve facts by picking the characteristics\n you would like your results to have. You can retrieve a fact with its FID\n (Fact ID). You can extract information about facts (period, entity, etc).\n You can perform a full-text search on fact values, and obtain footnotes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If you are interested in the structures in which facts can be organized (such\n as hypercubes), look at the components module.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Facts are stored in a MongoDB datasource called <b>xbrl</b>.</p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="standard_options">Standard <code>$options</code> Parameter</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Most functions in the BizQL package allow an additional <code>$options</code>\n    parameter. The options parameter is a JSON object allowing the following\n    fields:</p>\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n <li><b>Hypercube</b>: a hypercube object can be passed with the options to apply\n     implicit filtering for it. Only facts belonging to this hypercube will be\n     returned. Hypercube semantics (such as default dimension values) apply.\n     By default, the dimensionless hypercube is used (no dimensions allowed, no filtering).\n     You can override Hypercube with null to bypass hypercube semantics.</li>\n <li><b>Filter</b>: an object specifying the fields to filter for. Filtering fields\n     can be any field contained in facts, including profile specific fields, e.g.:\n     <pre class="ace-static" ace-mode="java">\n   {\n     Filter:\n       {\n         Archive: "0000034088-13-000011",\n         Aspects:\n         {\n           "us-gaap:DefinedBenefitPlansDisclosuresDefinedBenefitPlansAxis" :\n             "us-gaap:ForeignPensionPlansDefinedBenefitMember"\n         },\n         Profiles: {\n           SEC: {\n             Fiscal: {\n               Year: [2011, 2012]\n             }\n           }\n         }\n       }\n   }\n   </pre>\n   A filter must contain at least on of the fields Archive, Aspects.xbrl:Concept,\n   Aspects.xbrl:Period, or Aspects.xbrl:Entity.</li>\n <li><b>concept-maps</b>:\n   <ol><li>a string which is a name of a report schema that is stored in the\n       reportschemas collection and from which to load a ConceptMap</li>\n       <li>an object which is a ConceptMap network object</li>\n       <li>an array of ConceptMap network objects (to learn more about concept-maps\n       refer to the concept-maps module documentation)</li>\n   </ol></li>\n <li><b>Rules</b>:\n   <ol><li>a string which is a name of a report schema that is stored in the\n       reportschemas collection and from which to load Rules</li>\n       <li>an object which is a Rule object</li>\n       <li>an array of Rule objects</li>\n   </ol></li>\n <li><b>include-footnotes</b>: include XBRL Footnotes in each fact (true | false)</li>\n <li><b>Lang</b>: language identifier according to http://www.ietf.org/rfc/rfc3066.txt,\n     i.e. only return footnotes etc. for this specific language</li>\n <li><b>audit-trail</b>: if set to "debug" the audit trails will be more verbose</li>\n <li><b>facts-for-archives-and-concept</b>: to override how underlying facts are\n     resolved, for example with finer-grained, profile-specific filtering (option value\n     must be a function item). facts:facts-for-archives-and-concepts#3 is used by\n     default, but it is possible to supply another function that, for examples, filters\n     irrelevant facts out.</li>\n </ul>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/concept-maps",prefix:"concept-maps"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/entities",prefix:"entities"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://xbrl.io/modules/bizql/footnotes",prefix:"footnotes"},{uri:"http://xbrl.io/modules/bizql/hypercubes",prefix:"hypercubes"},{uri:"http://jsoniq.org/function-library",prefix:"j"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://zorba.io/modules/reflection",prefix:"reflection"},{uri:"http://xbrl.io/modules/bizql/rules",prefix:"rules"},{uri:"http://zorba.io/modules/string",prefix:"string"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/modules/zorba-query",prefix:"zq"}],functions:[{isDocumented:!0,arity:1,name:"concept-for-fact",qname:"facts:concept-for-fact",signature:"($fact-or-id as item()) as string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the concept against which a fact is reported.</p>\n',summary:"<p>  Retrieves the concept against which a fact is reported.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a fact or its FID.</div>'}],returns:{type:"string",description:"the concept name."},errors:[]},{isDocumented:!0,arity:1,name:"decimal-value",qname:"facts:decimal-value",signature:"($facts as object()*) as decimal",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the value of the given facts in case that it\n    is castable to decimal. If no facts are given or a fact value\n    is not castable to decimal 0 is returned instead.</p>\n',summary:"<p>  Returns the value of the given facts in case that it\n    is castable to decimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"facts",type:"object()",occurrence:"*",description:""}],returns:{type:"decimal",description:"the decimal value of the facts or 0."},errors:[]},{isDocumented:!0,arity:1,name:"duration-for-fact",qname:"facts:duration-for-fact",signature:"($fact-or-id as item()) as object()?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the duration period for which a fact was reported.</p>\n',summary:"<p>  Retrieves the duration period for which a fact was reported.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a fact or its FID.</div>'}],returns:{type:"object()?",description:"the duration period as an object with Start and End, or the empty sequence if it is not instant."},errors:[]},{isDocumented:!0,arity:1,name:"entity-for-fact",qname:"facts:entity-for-fact",signature:"($fact-or-id as item()) as string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the eid of the entity who reported a fact.</p>\n',summary:"<p>  Retrieves the eid of the entity who reported a fact.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a fact or its FID.</div>'}],returns:{type:"string",description:"the eid."},errors:[]},{isDocumented:!0,arity:2,name:"facts-for-archives-and-aspects",qname:"facts:facts-for-archives-and-aspects",signature:"($archives-or-ids as item()*, $aspects as object()) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all facts reported in a given archive, and associated with a\n given entity, concept, period and/or other aspects.</p>\n',summary:"<p>  Return all facts reported in a given archive, and associated with a\n given entity, concept, period and/or other aspects.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archive or archive IDs to filter (or $facts:ALL_OF_THEM to do not filter on archives).</div>'},{name:"aspects",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an object containing aspects to filter, among which xbrl:Concept, xbrl:Entity and xbrl:Period (at least one of them is mandatory).</div>'}],returns:{type:"object()*",description:"all facts satisfying all supplied conditions."},errors:[]},{isDocumented:!0,arity:3,name:"facts-for-archives-and-aspects",qname:"facts:facts-for-archives-and-aspects",signature:"($archives-or-ids as item()*, $aspects as object(), $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all facts associated with a given entity, concept, period\n and/or other aspects.</p>\n',summary:"<p>  Return all facts associated with a given entity, concept, period\n and/or other aspects.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archive or archive IDs to filter (or $facts:ALL_OF_THEM to do not filter on archives).</div>'},{name:"aspects",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an object containing aspects to filter, among which xbrl:Concept, xbrl:Entity and xbrl:Period (all optional).</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"all facts satisfying all supplied conditions."},errors:[]},{isDocumented:!0,arity:2,name:"facts-for-archives-and-concepts",qname:"facts:facts-for-archives-and-concepts",signature:"($archives-or-ids as item()*, $concepts as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return facts associated with given concepts and archives.</p>\n',summary:"<p>  Return facts associated with given concepts and archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archive or archive IDs to filter (or $facts:ALL_OF_THEM to do not filter on archives).</div>'},{name:"concepts",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the concepts (or $facts:ALL_OF_THEM to do no filter on concepts).</div>'}],returns:{type:"object()*",description:"facts associated with these concepts and archives."},errors:[]},{isDocumented:!0,arity:3,name:"facts-for-archives-and-concepts",qname:"facts:facts-for-archives-and-concepts",signature:"($archives-or-ids as item()*, $concepts as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return facts associated with given concepts and archives.</p>\n',summary:"<p>  Return facts associated with given concepts and archives.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:"item()",occurrence:"*",description:""},{name:"concepts",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the concepts (or $facts:ALL_OF_THEM to do no filter on concepts).</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"facts associated with these concepts."},errors:[]},{isDocumented:!0,arity:1,name:"facts-for-archives",qname:"facts:facts-for-archives",signature:"($archives-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all facts reported within a given archive.</p>\n',summary:"<p>  Return all facts reported within a given archive.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archives-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or AIDs to filter.</div>'}],returns:{type:"object()*",description:"all facts reported in these archives."},errors:[]},{isDocumented:!0,arity:1,name:"facts-for-aspects",qname:"facts:facts-for-aspects",signature:"($aspects as object()) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all facts associated with the given aspects.</p>\n',summary:"<p>  Return all facts associated with the given aspects.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"aspects",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an object containing aspects to filter, among which xbrl:Concept, xbrl:Entity and xbrl:Period (at least one of them is mandatory).</div>'}],returns:{type:"object()*",description:"all facts associated with these aspects."},errors:[]},{isDocumented:!0,arity:2,name:"facts-for-aspects",qname:"facts:facts-for-aspects",signature:"($aspects as object(), $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all facts associated with the given aspects.</p>\n',summary:"<p>  Return all facts associated with the given aspects.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"aspects",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an object containing aspects to filter, among which xbrl:Concept, xbrl:Entity and xbrl:Period (at least one of them is mandatory).</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"all facts associated with these aspects."},errors:[]},{isDocumented:!0,arity:1,name:"facts-for-concepts",qname:"facts:facts-for-concepts",signature:"($concepts as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return facts associated with given concepts.</p>\n',summary:"<p>  Return facts associated with given concepts.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"concepts",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the concepts.</div>'}],returns:{type:"object()*",description:"facts associated with these concepts."},errors:[]},{isDocumented:!0,arity:2,name:"facts-for-concepts",qname:"facts:facts-for-concepts",signature:"($concepts as string*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return facts associated with given concepts.</p>\n',summary:"<p>  Return facts associated with given concepts.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"concepts",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the concepts.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"facts associated with these concepts."},errors:[]},{isDocumented:!0,arity:1,name:"facts-for-entities",qname:"facts:facts-for-entities",signature:"($entities-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return facts reported by the given entities.</p>\n',summary:"<p>  Return facts reported by the given entities.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entities-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the entities or EIDs.</div>'}],returns:{type:"object()*",description:"facts reported by the given entities."},errors:[]},{isDocumented:!0,arity:1,name:"facts-for",qname:"facts:facts-for",signature:"($options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all facts that match a given filter object optionally interpreted\n    in the context of an optionally given hypercube.</p>\n',summary:"<p>  Return all facts that match a given filter object optionally interpreted\n    in the context of an optionally given hypercube.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"all facts satisfying the filter and options."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">facts:FILTER-TOO-GENERIC The filter object must have at least one of the fields Archive, Aspects.xbrl:Concept, Aspects.xbrl:Period, or Aspects.xbrl:Entity.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"facts-search",qname:"facts:facts-search",signature:"($search as string) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all facts that match the given search term.</p>\n',summary:"<p>  Return all facts that match the given search term.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"search",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the search query</div>'}],returns:{type:"object()*",description:"all facts matching the given search query"},errors:[]},{isDocumented:!0,arity:1,name:"facts",qname:"facts:facts",signature:"($fact-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the fact with the given FIDs.</p>\n',summary:"<p>  Return the fact with the given FIDs.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the FIDs or the facts themselves.</div>'}],returns:{type:"object()*",description:"the facts with the given FIDs the empty sequence if no fact was found or if the input is an empty sequence."},errors:[]},{isDocumented:!0,arity:1,name:"fid",qname:"facts:fid",signature:"($facts-or-ids as item()*) as atomic*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts the input to a normalized fact id (FID). The input\n can be either an FID, or a fact object which contains an _id.</p>\n',summary:"<p>  Converts the input to a normalized fact id (FID).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"facts-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of fact objects or FIDs.</div>'}],returns:{type:"atomic*",description:"the normalized FIDs."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">facts:INVALID-PARAMETER if the FID or fact is not valid.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"instant-for-fact",qname:"facts:instant-for-fact",signature:"($fact-or-id as item()) as atomic?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the instant period for which a fact was reported.</p>\n',summary:"<p>  Retrieves the instant period for which a fact was reported.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a fact or its FID.</div>'}],returns:{type:"atomic?",description:"the instance period, or the empty sequence if it is not instant."},errors:[]},{isDocumented:!0,arity:1,name:"is-fact-forever",qname:"facts:is-fact-forever",signature:"($fact-or-id as item()) as boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Tests whether a fact is reported forever.</p>\n',summary:"<p>  Tests whether a fact is reported forever.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a fact or its FID.</div>'}],returns:{type:"boolean",description:"true if its period is forever, false otherwise."},errors:[]},{isDocumented:!0,arity:3,name:"merge-objects",qname:"facts:merge-objects",signature:"($o1 as object()?, $o2 as object()?, $prioritize-first-object as boolean) as object()?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Helper function to deep-merge two objects. If the two given objects have\n    fields with the same name they are merged, which means:\n      1. if the values of the fields are objects then these are merged\n      2. in any other case the fields are accumulated into an array.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The third parameter can be used to priotitize the first object. If the first\n    object is prioritized and both objects contain fields with the same name,\n    the fields are either merged (in case of two object values) or the value of\n    the first object is taken.</p>\n',summary:"<p>  Helper function to deep-merge two objects.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"o1",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> first object</div>'},{name:"o2",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> second object</div>'},{name:"prioritize-first-object",type:"boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> boolean flag to give the first object higher priority in the merge</div>'}],returns:{type:"object()?",description:"one merge object or an empty-sequence (in case both input objects are empty)."},errors:[]},{isDocumented:!0,arity:1,name:"populate-with-footnotes",qname:"facts:populate-with-footnotes",signature:"($fact-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Populates a sequence of facts with their associated footnotes.\n More in detail, in each returned fact object an additional field\n Footnotes is added which contains all connected footnotes in an\n array.</p>\n',summary:"<p>  Populates a sequence of facts with their associated footnotes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the FIDs or the facts themselves.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated Footnotes field."},errors:[]},{isDocumented:!0,arity:2,name:"populate-with-footnotes",qname:"facts:populate-with-footnotes",signature:"($fact-or-ids as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Populates a sequence of facts with their associated footnotes.\n More in detail, in each returned fact object an additional field\n Footnotes is added which contains all connected footnotes in an\n array.</p>\n',summary:"<p>  Populates a sequence of facts with their associated footnotes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the FIDs or the facts themselves.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated Footnotes field."},errors:[]},{isDocumented:!0,arity:1,name:"prefix-from-fact-concept",qname:"facts:prefix-from-fact-concept",signature:"($fact as object()) as string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Helper function to get the prefix of a given fact`s xbrl:Concept aspect.</p>\n',summary:"<p>  Helper function to get the prefix of a given fact`s xbrl:Concept aspect.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a fact object.</div>'}],returns:{type:"string?",description:"the prefix of the fact's xbrl:Concept aspect or empty sequence if the concept doesn't have a prefix."},errors:[]}],variables:[{name:"facts:col",type:"string",description:" Name of the collection the facts are stored in.\n"},{name:"facts:ID",type:"string",description:" Name of the field that points to the facts FID.\n"},{name:"facts:ARCHIVE",type:"string",description:" Name of the field that points to the archive.\n"},{name:"facts:ASPECTS",type:"string",description:" Name of the field that stores the aspects.\n"},{name:"facts:CONCEPT",type:"string",description:" Name of the concept aspect.\n"},{name:"facts:PERIOD",type:"string",description:" Name of the period aspect.\n"},{name:"facts:ENTITY",type:"string",description:" Name of the entity aspect.\n"},{name:"facts:UNIT",type:"string",description:" Name of the unit aspect.\n"},{name:"facts:FOOTNOTES",type:"string",description:" Name of the field that stores the Footnotes (if populated).\n"},{name:"facts:ALL_OF_THEM",type:"boolean",description:" Joker for all archives or all concepts.\n"}]},"http://www.w3.org/2005/xqt-errors":{ns:"http://www.w3.org/2005/xqt-errors",description:" This module contains one variable declaration for each diagnostic of the\n http://www.w3.org/2005/xqt-errors namespace.\n The variables serves as documentation for the errors but can also\n be used in the code. For example, one useful scenario is to compare\n an error caught in the catch clause of a try-catch expression with one of\n the variables.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Carlos Lopez</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"}],functions:[],variables:[{name:"err:FORG0006",type:"xs:QName",description:" Invalid argument type.\n"},{name:"err:FODF1280",type:"xs:QName",description:" Invalid decimal format name supplied to \\c fn:format-number().\n"},{name:"err:FODF1310",type:"xs:QName",description:" Invalid decimal/integer format picture string.\n"},{name:"err:FODT0001",type:"xs:QName",description:" Overflow/underflow in date/time operation.\n"},{name:"err:FODT0002",type:"xs:QName",description:" Overflow/underflow in duration operation.\n"},{name:"err:FODT0003",type:"xs:QName",description:" Invalid timezone value.\n"},{name:"err:FONS0004",type:"xs:QName",description:" No namespace found for prefix.\n"},{name:"err:FONS0005",type:"xs:QName",description:" Base-URI not defined in static context.\n"},{name:"err:FORG0001",type:"xs:QName",description:" Invalid value for cast/constructor.\n"},{name:"err:FORG0002",type:"xs:QName",description:" Invalid argument to \\c fn:resolve-uri().\n"},{name:"err:FORG0003",type:"xs:QName",description:" \\c fn:zero-or-one() called with a sequence containing more than one\n item.\n"},{name:"err:FORG0004",type:"xs:QName",description:" \\c fn:one-or-more() called with a sequence containing no items.\n"},{name:"err:FORG0005",type:"xs:QName",description:" \\c fn:exactly-one() called with a sequence containing zero or more\n than one item.\n"},{name:"err:FODC0007",type:"xs:QName",description:" Base URI passed to \\c fn:parse() is not a valid absolute URI.\n"},{name:"err:FORG0008",type:"xs:QName",description:" The two arguments to fn:dateTime() have inconsistent timezones.\n"},{name:"err:FORG0009",type:"xs:QName",description:" Error in resolving a relative URI against a base URI in\n \\c fn:resolve-uri().\n"},{name:"err:FORX0001",type:"xs:QName",description:" Invalid regular expression flags.\n"},{name:"err:FORX0002",type:"xs:QName",description:" Invalid regular expression.\n"},{name:"err:FORX0003",type:"xs:QName",description:" Regular expression matches zero-length string.\n"},{name:"err:FORX0004",type:"xs:QName",description:" Invalid replacement string.\n"},{name:"err:FOTY0012",type:"xs:QName",description:" Argument node does not have a typed value.\n"},{name:"err:FOTY0013",type:"xs:QName",description:" An argument to \\c fn:data() contains a node that does not have a typed\n value.\n"},{name:"err:FOTY0014",type:"xs:QName",description:" The argument to \\c fn:string() is a function item.\n"},{name:"err:FOTY0015",type:"xs:QName",description:" An argument to \\c fn:deep-equal() contains a function item.\n"},{name:"err:FOUT1170",type:"xs:QName",description:" Identifier cannot be used to retrive a resource containing text\n"},{name:"err:FOCA0005",type:"xs:QName",description:" NaN supplied as float/double value.\n"},{name:"err:FTDY0016",type:"xs:QName",description:" It is a dynamic error if a weight value is not within the required range\n of values; it is also a dynamic error if an implementation that does not\n support negative weights encounters a negative weight value.\n"},{name:"err:FTDY0017",type:"xs:QName",description:" It is a dynamic error if an implementation encounters a mild not\n selection, one of whose operands evaluates to an AllMatches that\n contains a StringExclude.\n"},{name:"err:FTST0018",type:"xs:QName",description:" It is a static error if, during the static analysis phase, the query is\n found to contain a thesaurus option that refers to a thesaurus that is\n not found in the statically known thesauri.\n"},{name:"err:FTST0019",type:"xs:QName",description:" It is a static error if, within a single FTMatchOptions, there is more\n than one match option of any given match option group.\n"},{name:"err:FTDY0020",type:"xs:QName",description:' It is a dynamic error if, when "wildcards" is in effect, a query string\n violates wildcard syntax.\n'},{name:"err:FOER0000",type:"xs:QName",description:" Unidentified error.\n"},{name:"err:FOAR0001",type:"xs:QName",description:" Division by zero.\n"},{name:"err:FOAR0002",type:"xs:QName",description:" Numeric operation overflow/underflow.\n"},{name:"err:FOCA0001",type:"xs:QName",description:" Input value too large for decimal.\n"},{name:"err:FOCA0002",type:"xs:QName",description:" Invalid lexical value.\n"},{name:"err:FOCA0003",type:"xs:QName",description:" Input value too large for integer.\n"},{name:"err:FOUT1190",type:"xs:QName",description:" Retrieved resource contains octets that cannot be decoded into Unicode\n using the specified encoding, the resulting characters are not\n permitted XML characters or requested encoding not supported\n"},{name:"err:FOCA0006",type:"xs:QName",description:" Raised when casting a string to xs:decimal if the string has more\n digits of precision than the implementation can represent (the\n implementation also has the option of rounding).\n"},{name:"err:FOCH0001",type:"xs:QName",description:" Code point not valid.\n"},{name:"err:FOCH0002",type:"xs:QName",description:" Unsupported collation.\n"},{name:"err:FOCH0003",type:"xs:QName",description:" Unsupported normalization form.\n"},{name:"err:FOCH0004",type:"xs:QName",description:" Collation does not support collation units.\n"},{name:"err:FODC0001",type:"xs:QName",description:" No context document.\n"},{name:"err:FODC0002",type:"xs:QName",description:" Error retrieving resource.\n"},{name:"err:FODC0003",type:"xs:QName",description:" Raised by fn:doc, fn:collection to indicate that it is not possible to\n return a result that is guaranteed deterministic.\n"},{name:"err:FODC0004",type:"xs:QName",description:" Invalid argument to \\c fn:collection().\n"},{name:"err:FODC0005",type:"xs:QName",description:" Invalid argument to \\c fn:doc() or \\c fn:doc-available().\n"},{name:"err:FODC0006",type:"xs:QName",description:" Invalid content passed to \\c fn:parse().\n"},{name:"err:SERE0005",type:"xs:QName",description:" It is an error if the serialized result would contain an NCName Names\n that contains a character that is not permitted by the version of\n Namespaces in XML specified by the version parameter.\n"},{name:"err:XUDY0024",type:"xs:QName",description:" It is a dynamic error if the effect of a set of updating expressions is\n to introduce conflicting namespace bindings into an element node.\n"},{name:"err:XUDY0027",type:"xs:QName",description:" It is a dynamic error if the target expression of an insert, replace, or\n rename expression evaluates to an empty sequence.\n"},{name:"err:XUST0028",type:"xs:QName",description:" It is a static error if a function declaration specifies both \\c updating\n and a return type.\n"},{name:"err:XUDY0029",type:"xs:QName",description:" In an insert expression where \\c before or \\c after is specified, it is\n a dynamic error if the node returned by the target expression does not\n have a parent.\n"},{name:"err:XUDY0030",type:"xs:QName",description:" It is a dynamic error if an insert expression specifies the insertion of\n an attribute node before or after a child of a document node.\n"},{name:"err:XUDY0031",type:"xs:QName",description:" It is a dynamic error if multiple calls to \\c fn:put() in the same\n snapshot specify the same URI (after resolution of relative URIs).\n"},{name:"err:FOUP0001",type:"xs:QName",description:" It is a dynamic error if the first operand of \\c fn:put() is not a node\n of a supported kind.\n"},{name:"err:FOUP0002",type:"xs:QName",description:" It is a dynamic error if the second operand of \\c fn:put() is not a valid\n lexical representation of the \\c xs:anyURI type.\n"},{name:"err:SENR0001",type:"xs:QName",description:" It is an error if an item in S6 in sequence normalization is an attribute\n node or a namespace node.\n"},{name:"err:SERE0003",type:"xs:QName",description:" It is an error if the serializer is unable to satisfy the rules for\n either a well-formed XML document entity or a well-formed XML external\n general parsed entity, or both, except for content modified by the\n character expansion phase of serialization.\n"},{name:"err:SEPM0004",type:"xs:QName",description:" It is an error to specify the doctype-system parameter, or to specify\n the standalone parameter with a value other than omit, if the instance\n of the data model contains text nodes or multiple element nodes as\n children of the root node.\n"},{name:"err:XUDY0023",type:"xs:QName",description:" It is a dynamic error if an insert, replace, or rename expression\n affects an element node by introducing a new namespace binding that\n conflicts with one of its existing namespace bindings.\n"},{name:"err:SERE0006",type:"xs:QName",description:" It is an error if the serialized result would contain a character that is\n not permitted by the version of XML specified by the version parameter.\n"},{name:"err:SESU0007",type:"xs:QName",description:" It is an error if an output encoding other than UTF-8 or UTF-16 is\n requested and the serializer does not support that encoding.\n"},{name:"err:SERE0008",type:"xs:QName",description:" It is an error if a character that cannot be represented in the encoding\n that the serializer is using for output appears in a context where\n character references are not allowed (for example if the character\n occurs in the name of an element).\n"},{name:"err:SEPM0009",type:"xs:QName",description:" It is an error if the omit-xml-declaration parameter has the value yes,\n and the standalone attribute has a value other than omit; or the version\n parameter has a value other than 1.0 and the doctype-system parameter is\n specified.\n"},{name:"err:SEPM0010",type:"xs:QName",description:" It is an error if the output method is xml, the value of the\n undeclare-prefixes parameter is yes, and the value of the version\n parameter is 1.0.\n"},{name:"err:SESU0011",type:"xs:QName",description:" It is an error if the value of the normalization-form parameter\n specifies a normalization form that is not supported by the serializer.\n"},{name:"err:SERE0012",type:"xs:QName",description:" It is an error if the value of the normalization-form parameter is\n fully-normalized and any relevant construct of the result begins with a\n combining character.\n"},{name:"err:SESU0013",type:"xs:QName",description:" It is an error if the serializer does not support the version of XML or\n HTML specified by the version parameter.\n"},{name:"err:SERE0014",type:"xs:QName",description:" It is an error to use the HTML output method when characters which are\n legal in XML but not in HTML, specifically the control characters\n #x7F-#x9F, appear in the instance of the data model.\n"},{name:"err:SERE0015",type:"xs:QName",description:" It is an error to use the HTML output method when \\c &gt; appears within a\n processing instruction in the data model instance being serialized.\n"},{name:"err:SEPM0016",type:"xs:QName",description:" It is a an error if a parameter value is invalid for the defined domain.\n"},{name:"err:XUTY0010",type:"xs:QName",description:" In a replace expression where value of is not specified and\n the target is an element, text, comment, or processing instruction node,\n it is a type error if the replacement sequence does not consist of zero\n or more element, text, comment, or processing instruction nodes.\n"},{name:"err:FOFL0001",type:"xs:QName",description:" This error is raised if the fn:function-lookup returns a context-dependent function and the context-dependent function is then called.\n"},{name:"err:FOCZ0001",type:"xs:QName",description:" Invalid content passed to \\c x:canonicalize().\n"},{name:"err:XUST0001",type:"xs:QName",description:" It is a static error if an updating expression is used in any position\n other than one of the following:\n - The topmost expression in the body of a query.\n - The \\c modify clause of a transform expression.\n - The \\c return clause of a FLWOR expression.\n - The \\c return clauses of a typeswitch expression in which every \\c\n return clause contains an updating expression or a vacuous expression.\n - The \\c then and \\c else clauses of a conditional statement in which\n both the \\c then and \\c else clauses contain either an updating\n expression or a vacuous expression.\n - An operand of a comma expression in which each operand is either an\n updating expression or a vacuous expression.\n - The content of a parenthesized expression.\n - The body of a function declaration in which the keyword \\c updating is\n specified.\n"},{name:"err:XUST0002",type:"xs:QName",description:" It is a static error if a simple expression that is not a vacuous\n expression is used in one of the following positions:\n - The \\c modify clause of a transform expression.\n - The top-level expression in the body of a function declaration in\n which the keyword \\c updating is specified.\n"},{name:"err:XUST0003",type:"xs:QName",description:" It is a static error if a Prolog contains more than one revalidation\n declaration.\n"},{name:"err:XUTY0004",type:"xs:QName",description:" It is a type error if the insertion sequence of an insert expression\n contains an attribute node following a node that is not an attribute\n node.\n"},{name:"err:XUTY0005",type:"xs:QName",description:" In an insert expression where into, as first\n into, or as last into is specified, it is a type\n error if the target expression returns a non-empty result that does not\n consist of a single element or document node.\n"},{name:"err:XUTY0006",type:"xs:QName",description:" In an insert expression where \\c before or \\c after is specified, it is\n a type error if the target expression returns a non-empty result that\n does not consist of a single element, text, comment, or processing\n instruction node.\n"},{name:"err:XUTY0007",type:"xs:QName",description:" It is a type error if the target expression of a delete expression does\n not return a sequence of zero or more nodes.\n"},{name:"err:XUTY0008",type:"xs:QName",description:" In a replace expression, it is a type error if the target expression\n returns a non-empty result that does not consist of a single element,\n attribute, text, comment, or processing instruction node.\n"},{name:"err:XUDY0009",type:"xs:QName",description:" In a replace expression where value of is not specified, it\n is a dynamic error if the node returned by the target expression does\n not have a parent.\n"},{name:"err:FTST0009",type:"xs:QName",description:" It may be a static error if, during the static analysis phase, the query\n is found to contain a language identifier in a language option that the\n implementation does not support. The implementation may choose not to\n raise this error and instead provide some other implementation-defined\n behavior.\n"},{name:"err:XUTY0011",type:"xs:QName",description:" In a replace expression where value of is not specified and\n the target is an attribute node, it is a type error if the replacement\n sequence does not consist of zero or more attribute nodes.\n"},{name:"err:XUTY0012",type:"xs:QName",description:" In a rename expression, it is a type error if the target expression\n returns a non-empty result that does not consist of a single element,\n attribute, or processing instruction node.\n"},{name:"err:XUTY0013",type:"xs:QName",description:" In a transform expression, it is a type error if a source expression in\n the \\c copy clause does not return a single node.\n"},{name:"err:XUDY0014",type:"xs:QName",description:" In a transform expression, it is a dynamic error if the \\c modify clause\n modifies any node that was not created by the \\c copy clause.\n"},{name:"err:XUDY0015",type:"xs:QName",description:" It is a dynamic error if any node is the target of more than one \\c\n rename expression within the same query.\n"},{name:"err:XUDY0016",type:"xs:QName",description:" It is a dynamic error if any node is the target of more than one \\c\n replace expression (without value of being specified)\n within the same query.\n"},{name:"err:XUDY0017",type:"xs:QName",description:" It is a dynamic error if any node is the target of more than one\n replace value of expression within the same query.\n"},{name:"err:XUDY0018",type:"xs:QName",description:" It is a dynamic error if a function that was declared to be \\c external\n but not \\c updating returns a non-empty pending update list.\n"},{name:"err:XUDY0019",type:"xs:QName",description:" It is a dynamic error if a function that was declared to be both \\c\n external and \\c updating returns a non-empty data model instance.\n"},{name:"err:XUDY0021",type:"xs:QName",description:" It is a dynamic error if the XDM instance that would result from\n applying all the updates in a query violates any constraint specified in\n [XQuery 1.0 and XPath 2.0 Data Model]. In this case, none of the updates\n in the query are made effective.\n"},{name:"err:XUTY0022",type:"xs:QName",description:" It is a type error if an insert expression specifies the insertion of an\n attribute node into a document node.\n"},{name:"err:XQST0052",type:"xs:QName",description:" The type must be the name of a type defined in the in-scope schema types,\n and the {variety} of the type must be simple.\n"},{name:"err:XQST0033",type:"xs:QName",description:" It is a static error if a module contains multiple bindings for the same\n namespace prefix.\n"},{name:"err:XQST0034",type:"xs:QName",description:" It is a static error if multiple functions declared or imported by a\n module have the same number of arguments and their expanded QNames are\n equal (as defined by the eq operator).\n"},{name:"err:XQST0035",type:"xs:QName",description:" It is a static error to import two schema components that both define the\n same name in the same symbol space and in the same scope.\n"},{name:"err:XQST0036",type:"xs:QName",description:" It is a static error to import a module if the in-scope schema\n definitions of the importing module do not include all of the following:\n -# An in-scope schema type for each type-name that appears:\n - in the type of a variable that is declared in the imported module\n and referenced in the importing module, OR\n - in a parameter-type or result-type of a function that is declared in\n the imported module and referenced in the importing module.\n -# An in-scope element declaration for each element-name \\c EN such that:\n - \\c schema-element(EN) appears in the declared type of a variable in\n the imported module, and that variable is referenced in the\n importing module, OR\n - \\c schema-element(EN) appears in a parameter-type or result-type\n of a function declared in the imported module, and that function is\n referenced in the importing module.\n -# An in-scope attribute declaration for each attribute-name \\c AN such\n that:\n - \\c schema-attribute(AN) appears in the declared type of a variable\n in the imported module, and that variable is referenced in the\n importing module, OR\n - \\c schema-attribute(AN) appears in a parameter-type or result-type\n of a function declared in the imported module, and that function is\n referenced in the importing module.\n"},{name:"err:XQST0038",type:"xs:QName",description:" It is a static error if a Prolog contains more than one default collation\n declaration, or the value specified by a default collation declaration is\n not present in statically known collations.\n"},{name:"err:XQST0039",type:"xs:QName",description:" It is a static error for a function declaration to have more than one\n parameter with the same name.\n"},{name:"err:XQST0040",type:"xs:QName",description:" It is a static error if the attributes specified by a direct element\n constructor do not have distinct expanded QNames.\n"},{name:"err:XQST0045",type:"xs:QName",description:" It is a static error if the function name in a function declaration is in\n one of the following namespaces:\n http://www.w3.org/XML/1998/namespace,\n http://www.w3.org/2001/XMLSchema,\n http://www.w3.org/2001/XMLSchema-instance,\n http://www.w3.org/2005/xpath-functions.\n"},{name:"err:XQST0046",type:"xs:QName",description:" An implementation MAY raise a static error if the value of a URILiteral\n is of nonzero length and is not in the lexical space of \\c xs:anyURI.\n"},{name:"err:XQST0047",type:"xs:QName",description:" It is a static error if multiple module imports in the same Prolog\n specify the same target namespace.\n"},{name:"err:XQST0048",type:"xs:QName",description:" It is a static error if a function or variable declared in a library\n module is not in the target namespace of the library module.\n"},{name:"err:XQST0049",type:"xs:QName",description:" It is a static error if two or more variables declared or imported by a\n module have equal expanded QNames (as defined by the eq operator.)\n"},{name:"err:XQST0032",type:"xs:QName",description:" A static error is raised if a Prolog contains more than one base URI\n declaration.\n"},{name:"err:XQST0054",type:"xs:QName",description:" It is a static error if a variable depends on itself.\n"},{name:"err:XQST0055",type:"xs:QName",description:" It is a static error if a Prolog contains more than one copy-namespaces\n declaration.\n"},{name:"err:XQST0057",type:"xs:QName",description:" It is a static error if a schema import binds a namespace prefix but\n does not specify a target namespace other than a zero-length string.\n"},{name:"err:XQST0058",type:"xs:QName",description:" It is a static error if multiple schema imports specify the same target\n namespace.\n"},{name:"err:XQST0059",type:"xs:QName",description:" It is a static error if an implementation is unable to process a schema\n or module import by finding a schema or module with the specified\n target namespace.\n"},{name:"err:XQST0060",type:"xs:QName",description:" It is a static error if the name of a function in a function declaration\n is not in a namespace (expanded QName has a null namespace URI).\n"},{name:"err:XQST0065",type:"xs:QName",description:" A static error is raised if a Prolog contains more than one ordering mode\n declaration.\n"},{name:"err:XQST0066",type:"xs:QName",description:" A static error is raised if a Prolog contains more than one default\n element/type namespace declaration, or more than one default function\n namespace declaration.\n"},{name:"err:XQST0067",type:"xs:QName",description:" A static error is raised if a Prolog contains more than one construction\n declaration.\n"},{name:"err:XQST0068",type:"xs:QName",description:" A static error is raised if a Prolog contains more than one\n boundary-space declaration.\n"},{name:"err:XQST0069",type:"xs:QName",description:" A static error is raised if a Prolog contains more than one empty order\n declaration.\n"},{name:"err:XPTY0019",type:"xs:QName",description:" It is a type error if the result of a step (other than the last step) in a\n path expression contains an atomic value.\n"},{name:"err:XPST0001",type:"xs:QName",description:" It is a static error if analysis of an expression relies on some\n component of the static context that has not been assigned a value.\n"},{name:"err:XPST0003",type:"xs:QName",description:" It is a static error if an expression is not a valid instance of the\n grammar.\n"},{name:"err:XPST0005",type:"xs:QName",description:" During the analysis phase, it is a static error if the static type\n assigned to an expression other than the expression \\c () or \\c data(())\n is \\c empty-sequence().\n"},{name:"err:XPST0008",type:"xs:QName",description:" It is a static error if an expression refers to an element name,\n attribute name, schema type name, namespace prefix, or variable name\n that is not defined in the static context, except for an ElementName in\n an ElementTest or an AttributeName in an AttributeTest.\n"},{name:"err:XPST0017",type:"xs:QName",description:" It is a static error if the expanded QName and number of arguments in a\n function call do not match the name and arity of a function signature in\n the static context.\n"},{name:"err:XPST0051",type:"xs:QName",description:" It is a static error if a QName that is used as an AtomicType in a\n SequenceType is not defined in the in-scope schema types as an atomic\n type.\n"},{name:"err:XPST0080",type:"xs:QName",description:" It is a static error if the target type of a \\c cast or \\c castable\n expression is \\c xs:NOTATION or \\c xs:anyAtomicType.\n"},{name:"err:XPST0081",type:"xs:QName",description:" It is a static error if a QName used in a query contains a namespace\n prefix that cannot be expanded into a namespace URI by using the\n statically known namespaces.\n"},{name:"err:XPST0083",type:"xs:QName",description:" It is a static error if the target type of a \\c cast expression or\n constructor function is \\c xs:QName or a type derived from \\c xs:QName\n or \\c xs:NOTATION, and the argument of the cast expression or\n constructor function is not a string literal.\n"},{name:"err:XPTY0004",type:"xs:QName",description:" It is a type error if, during the static analysis phase, an expression\n is found to have a static type that is not appropriate for the context\n in which the expression occurs, or during the dynamic evaluation phase,\n the dynamic type of a value does not match a required type as specified\n by the matching rules in 2.5.4 SequenceType Matching.\n"},{name:"err:XPTY0018",type:"xs:QName",description:" It is a type error if the result of the last step in a path expression\n contains both nodes and non-nodes.\n"},{name:"err:XQST0070",type:"xs:QName",description:" A static error is raised if one of the predefined prefixes \\c xml or \\c\n xmlns appears in a namespace declaration, or if any of the following\n conditions is statically detected in any expression or declaration:\n - The prefix \\c xml is bound to some namespace URI other than\n http://www.w3.org/XML/1998/namespace.\n - A prefix other than \\c xml is bound to the namespace URI\n http://www.w3.org/XML/1998/namespace.\n - The prefix \\c xmlns is bound to any namespace URI.\n - A prefix other than \\c xmlns is bound to the namespace URI\n http://www.w3.org/2000/xmlns/.\n"},{name:"err:XPTY0020",type:"xs:QName",description:" It is a type error if, in an axis step, the context item is not a node.\n"},{name:"err:XPTY0117",type:"xs:QName",description:" Attempt to cast to a namespace-sensitive type failed because the namespace\n bindings for the result can not be determined.\n"},{name:"err:XQTY0024",type:"xs:QName",description:" It is a type error if the content sequence in an element constructor\n contains an attribute node following a node that is not an attribute node.\n"},{name:"err:XQTY0030",type:"xs:QName",description:" It is a type error if the argument of a validate expression does not\n evaluate to exactly one document or element node.\n"},{name:"err:XQTY0086",type:"xs:QName",description:" It is a type error if the typed value of a copied element or attribute\n node is namespace-sensitive when construction mode is \\c preserve and\n copy-namespaces mode is \\c no-preserve.\n"},{name:"err:XQTY0105",type:"xs:QName",description:" It is a type error if the content sequence in an element constructor contains a function item.\n"},{name:"err:XQST0009",type:"xs:QName",description:" An implementation that does not support the Schema Import Feature must\n raise a static error if a Prolog contains a schema import.\n"},{name:"err:XQST0012",type:"xs:QName",description:" It is a static error if the set of definitions contained in all schemas\n imported by a Prolog do not satisfy the conditions for schema validity\n specified in Sections 3 and 5 of [XML Schema] Part 1--i.e., each\n definition must be valid, complete, and unique.\n"},{name:"err:XQST0013",type:"xs:QName",description:" It is a static error if an implementation recognizes a pragma but\n determines that its content is invalid.\n"},{name:"err:XQST0022",type:"xs:QName",description:" It is a static error if the value of a namespace declaration attribute is\n not a URILiteral.\n"},{name:"err:XQST0031",type:"xs:QName",description:" It is a static error if the version number specified in a version\n declaration is not supported by the implementation.\n"},{name:"err:XQDY0072",type:"xs:QName",description:" It is a dynamic error if the result of the content expression of a\n computed comment constructor contains two adjacent hyphens or ends with\n a hyphen.\n"},{name:"err:XQST0128",type:"xs:QName",description:" It is a static error if a feature name that an implementation supports appears\n in a prohibit-feature option declaration, and the implementation is unable to\n disable the feature.\n"},{name:"err:XPDY0002",type:"xs:QName",description:" It is a dynamic error if evaluation of an expression relies on some part\n of the dynamic context that has not been assigned a value.\n"},{name:"err:XPDY0050",type:"xs:QName",description:' It is a dynamic error if the dynamic type of the operand of a treat\n expression does not match the sequence type specified by the treat\n expression. This error might also be raised by a path expression\n beginning with "/" or "//" if the context node\n is not in a tree that is rooted at a document node. This is because a\n leading "/" or "//" in a path expression is an\n abbreviation for an initial step that includes the clause \\c treat as \\c\n document-node().\n'},{name:"err:XQDY0025",type:"xs:QName",description:" It is a dynamic error if any attribute of a constructed element does not\n have a name that is distinct from the names of all other attributes of\n the constructed element.\n"},{name:"err:XQDY0026",type:"xs:QName",description:' It is a dynamic error if the result of the content expression of a\n computed processing instruction constructor contains the string "?&gt;".\n'},{name:"err:XQDY0027",type:"xs:QName",description:" In a validate expression, it is a dynamic error if the root element\n information item in the PSVI resulting from validation does not have the\n expected validity property: \\c valid if validation mode is \\c strict, or\n either \\c valid or \\c notKnown if validation mode is \\c lax.\n"},{name:"err:XQDY0041",type:"xs:QName",description:" It is a dynamic error if the value of the name expression in a computed\n processing instruction constructor cannot be cast to the type\n \\c xs:NCName.\n"},{name:"err:XQDY0044",type:"xs:QName",description:" It is a static error the node-name of a node constructed by a computed\n attribute constructor has any of the following properties:\n - Its namespace prefix is \\c xmlns.\n - It has no namespace prefix and its local name is \\c xmlns.\n - Its namespace URI is http://www.w3.org/2000/xmlns/.\n - Its namespace prefix is \\c xml and its namespace URI is not\n http://www.w3.org/XML/1998/namespace.\n - Its namespace prefix is other than \\c xml and its namespace URI is\n http://www.w3.org/XML/1998/namespace.\n"},{name:"err:XQDY0054",type:"xs:QName",description:" It is a dynamic error if a cycle is encountered in the definition of a\n module's dynamic context components, for example because of a cycle in\n variable declarations.\n"},{name:"err:XQDY0061",type:"xs:QName",description:" It is a dynamic error if the operand of a validate expression is a\n document node whose children do not consist of exactly one element node\n and zero or more comment and processing instruction nodes, in any order.\n"},{name:"err:XQDY0064",type:"xs:QName",description:' It is a dynamic error if the value of the name expression in a computed\n processing instruction constructor is equal to "XML" (in any combination\n of upper and lower case).\n'},{name:"err:XQST0127",type:"xs:QName",description:" It is a static error if a given feature is both required and prohibited, directly or indirectly, in a module.\n"},{name:"err:XQDY0074",type:"xs:QName",description:" It is a dynamic error if the value of the name expression in a computed\n element or attribute constructor cannot be converted to an expanded\n QName (for example, because it contains a namespace prefix not found in\n statically known namespaces).\n"},{name:"err:XQDY0084",type:"xs:QName",description:" It is a dynamic error if the element validated by a \\c validate statement\n does not have a top-level element declaration in the in-scope element\n declarations, if validation mode is \\c strict.\n"},{name:"err:XQDY0091",type:"xs:QName",description:" An implementation MAY raise a dynamic error if an \\c xml:id error, as\n defined in [XML ID], is encountered during construction of an attribute\n named \\c xml:id.\n"},{name:"err:XQDY0092",type:"xs:QName",description:" An implementation MAY raise a dynamic error if a constructed attribute\n named \\c xml:space has a value other than \\c preserve or \\c default.\n"},{name:"err:XQDY0096",type:"xs:QName",description:" It is a dynamic error the node-name of a node constructed by a computed\n element constructor has any of the following properties:\n - Its namespace prefix is \\c xmlns.\n - Its namespace URI is http://www.w3.org/2000/xmlns/.\n - Its namespace prefix is \\c xml and its namespace URI is not\n http://www.w3.org/XML/1998/namespace.\n - Its namespace prefix is other than \\c xml and its namespace URI is\n http://www.w3.org/XML/1998/namespace.\n"},{name:"err:XQDY0101",type:"xs:QName",description:" Invalid prefix and/or uri in computed namespace constructor\n"},{name:"err:XQDY0102",type:"xs:QName",description:" In an element constructor, if two or more namespace bindings in the in-scope bindings would have the same prefix, then an error is raised if they have different URIs; if they would have the same prefix and URI, duplicate bindings are ignored.\n"},{name:"err:XTDE1310",type:"xs:QName",description:" It is a non-recoverable dynamic error if the picture string does not\n satisfy the format-number function rules.\n"},{name:"err:FOFD1340",type:"xs:QName",description:" It is a non-recoverable dynamic error if the $picture, $language,\n $calendar, or $place argument for fn:format-date, fn:format-time, or\n fn:format-dateTime is invalid.\n"},{name:"err:FOFD1350",type:"xs:QName",description:" It is a non-recoverable dynamic error if a component specifier within\n the picture refers to components that are not available in the given\n type of $value.\n"},{name:"err:FTST0008",type:"xs:QName",description:" It is a static error if, during the static analysis phase, the query is\n found to contain a stop word option that refers to a stop word list that\n is not found in the statically known stop word lists.\n"},{name:"err:XQST0098",type:"xs:QName",description:" It is a static error if, for any named or unnamed decimal format, the\n properties representing characters used in a picture string do not each\n have distinct values. These properties are decimal-separator-sign,\n grouping-separator, percent-sign, per-mille-sign, zero-digit,\n digit-sign, and pattern-separator-sign.\n"},{name:"err:XQST0071",type:"xs:QName",description:" A static error is raised if the namespace declaration attributes of a\n direct element constructor do not have distinct names.\n"},{name:"err:XQST0076",type:"xs:QName",description:" It is a static error if a \\c collation subclause in an order by clause\n of a FLWOR expression does not identify a collation that is present in\n statically known collations.\n"},{name:"err:XQST0079",type:"xs:QName",description:" It is a static error if an extension expression contains neither a\n pragma that is recognized by the implementation nor an expression\n enclosed in curly braces.\n"},{name:"err:XQST0085",type:"xs:QName",description:" It is a static error if the namespace URI in a namespace declaration\n attribute is a zero-length string, and the implementation does not\n support [XML Names 1.1].\n"},{name:"err:XQST0087",type:"xs:QName",description:" It is a static error if the encoding specified in a Version Declaration\n does not conform to the definition of \\c EncName specified in [XML 1.0]\n"},{name:"err:XQST0088",type:"xs:QName",description:" It is a static error if the literal that specifies the target namespace\n in a module import or a module declaration is of zero length.\n"},{name:"err:XQST0089",type:"xs:QName",description:" It is a static error if a variable bound in a \\c for or \\c window clause\n of a FLWOR expression, and its associated positional variable, do not\n have distinct names (expanded QNames).\n"},{name:"err:XQST0090",type:"xs:QName",description:" It is a static error if a character reference does not identify a valid\n character in the version of XML that is in use.\n"},{name:"err:XQST0093",type:"xs:QName",description:" It is a static error to import a module M1 if there exists a sequence of\n modules M1 ... Mi ... M1 such that each module directly depends on the\n next module in the sequence (informally, if M1 depends on itself through\n some chain of module dependencies.)\n"},{name:"err:XQST0094",type:"xs:QName",description:" In the group by clause of a FLWOR expression, it is a static error if the\n name of a grouping variable is not equal (by the eq operator on expanded\n QNames) to the name of a variable that is bound by a for or let clause\n that precedes the group by clause.\n"},{name:"err:XQST0097",type:"xs:QName",description:" It is a static error for a decimal-format to specify a value that is\n not valid for a given property.\n"},{name:"err:NS",type:"item()*",description:""},{name:"err:XQST0099",type:"xs:QName",description:" If a module contains more than one context item declaration, a static error is raised [err:XQST0099].\n"},{name:"err:XQST0103",type:"xs:QName",description:" All variables in a window clause must have distinct names.\n"},{name:"err:XQST0106",type:"xs:QName",description:" It is a static error if a function's annotations contain more than one\n annotation named \\c private or \\c public.  It is a static error if a\n function's annotations contain more than one annotation named \\c\n deterministic or \\c nondeterministic.\n"},{name:"err:XQST0111",type:"xs:QName",description:" It is a static error for a query prolog to contain two decimal formats\n with the same name, or to contain two default decimal formats.\n"},{name:"err:XQST0113",type:"xs:QName",description:" Specifying a VarValue or VarDefaultValue for a context item declaration\n in a library module is a static error.\n"},{name:"err:XQST0114",type:"xs:QName",description:" It is a static error for a decimal format declaration to define the\n same property more than once.\n"},{name:"err:XQST0116",type:"xs:QName",description:" It is a static error if a variable declaration contains both a %private\n and a %public annotation, more than one %private annotation, or more\n than one %public annotation.\n"},{name:"err:XQST0120",type:"xs:QName",description:" It is a static error if a feature required by require-feature is not\n supported by the implementation.\n"},{name:"err:XQST0122",type:"xs:QName",description:" It is a static error if the name of a feature in require-feature or\n prohibit-feature is not in the lexical space of QName.\n"},{name:"err:XQST0123",type:"xs:QName",description:" It is a static error if the name of a feature in require-feature is not\n recognized by the implementation.\n"},{name:"err:XQST0126",type:"xs:QName",description:" It is a static error if all-extensions appears in a require-feature option declaration.\n"}]},"http://zorba.io/modules/excel/math":{ns:"http://zorba.io/modules/excel/math",description:" This is a library module offering a part of the set of functions\n defined by Microsoft Excel 2003.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://office.microsoft.com/en-us/excel/CH062528291033.aspx" target="_blank">Excel 2003 Documentation: Math Functions</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Turcanu</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/math",prefix:"excel"},{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"abs",qname:"excel:abs",signature:"($arg as xs:anyAtomicType) as xs:anyAtomicType",description:" Compute the abs of a numeric value.\n The value can also be a string and it will be casted to the appropriate numeric first.\n",summary:"<p> Compute the abs of a numeric value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The parameter can be a number, string, boolean value.</div>'}],returns:{type:"xs:anyAtomicType",description:"The abs value as a numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if arg cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"cast-as-numeric",qname:"excel:cast-as-numeric",signature:"($number as xs:anyAtomicType) as xs:anyAtomicType",description:" Cast the xs:anyAtomicType to a numeric type.\n If the value is already of a numeric type then nothing is changed.\n Otherwise the value is casted to the numeric type that is most appropriate.\n",summary:"<p> Cast the xs:anyAtomicType to a numeric type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The parameter can be a number, string, boolean value.</div>'}],returns:{type:"xs:anyAtomicType",description:"The casted value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the value cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"ceiling",qname:"excel:ceiling",signature:"($number as xs:anyAtomicType, $significance as xs:anyAtomicType) as xs:anyAtomicType",description:" Returns number rounded up, away from zero, to the nearest multiple of significance.\n Significance must have the same sign as number.\n Number and significance must be of a numeric type or castable to numeric.\n Significance must not be zero.\n",summary:"<p> Returns number rounded up, away from zero, to the nearest multiple of significance.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value you want to round.</div>'},{name:"significance",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The multiple to which you want to round.</div>'}],returns:{type:"xs:anyAtomicType",description:"The rounded value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if significance is zero or it doesn\'t have the same sign as number.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"degrees",qname:"excel:degrees",signature:"($radian as xs:double) as xs:integer",description:" Converts radians into degrees.\n",summary:"<p> Converts radians into degrees.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"radian",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value in radians.</div>'}],returns:{type:"xs:integer",description:"The value in degrees 0 .. 360 or 0 .. -360."},errors:[]},{isDocumented:!0,arity:1,name:"even",qname:"excel:even",signature:"($number as xs:anyAtomicType) as xs:anyAtomicType",description:" Returns number rounded up to the nearest even integer.\n Regardless of the sign of number, a value is rounded up when adjusted away from zero.\n",summary:"<p> Returns number rounded up to the nearest even integer.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to round.</div>'}],returns:{type:"xs:anyAtomicType",description:"The rounded value casted as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"fact",qname:"excel:fact",signature:"($number as xs:anyAtomicType) as xs:integer",description:" Returns the factorial of a number.\n",summary:"<p> Returns the factorial of a number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The nonnegative number you want the factorial of. If number is not an integer, it is truncated.</div>'}],returns:{type:"xs:integer",description:"Returns the factorial of a number. The factorial of a number is equal to 1*2*3*...* number."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if the number is smaller than zero</xqdoc:error>']},{isDocumented:!0,arity:1,name:"factdouble",qname:"excel:factdouble",signature:"($number as xs:integer) as xs:integer",description:" Returns the double factorial of a number.\n Computes the double factorial of n as n(n-2)(n-4)...\n",summary:"<p> Returns the double factorial of a number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The positive integer value.</div>'}],returns:{type:"xs:integer",description:"The result as integer."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if the number is negative.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"floor",qname:"excel:floor",signature:"($number as xs:anyAtomicType, $significance as xs:anyAtomicType) as xs:anyAtomicType",description:" Rounds number down, toward zero, to the nearest multiple of significance.\n Significance must have the same sign as number.\n",summary:"<p> Rounds number down, toward zero, to the nearest multiple of significance.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value you want to round. The value is casted to numeric.</div>'},{name:"significance",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The multiple to which you want to round.</div>'}],returns:{type:"xs:anyAtomicType",description:"The rounded value as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if significance is zero or it doesn\'t have the same sign as number.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"gcd",qname:"excel:gcd",signature:"($numbers as xs:integer+) as xs:integer",description:" Returns the greatest common divisor GCD of a sequence of integers.\n The sequence can have one or more positive integers.\n",summary:"<p> Returns the greatest common divisor GCD of a sequence of integers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:integer",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of positive integers.</div>'}],returns:{type:"xs:integer",description:"The GCD as integer."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if any number is smaller than zero.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"int",qname:"excel:int",signature:"($number as xs:anyAtomicType) as xs:integer",description:" Rounds a number down to the nearest integer.\n Positive numbers are rounded toward zero, negative numbers are rounded away from zero.\n",summary:"<p> Rounds a number down to the nearest integer.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be rounded.</div>'}],returns:{type:"xs:integer",description:"The rounded integer."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameter cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-a-number",qname:"excel:is-a-number",signature:"($value as xs:anyAtomicType) as xs:boolean",description:" Checks if the xs:anyAtomicType argument is actually a numeric type\n or can be converted to numeric.\n",summary:"<p> Checks if the xs:anyAtomicType argument is actually a numeric type\n or can be converted to numeric.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Parameter to be checked.</div>'}],returns:{type:"xs:boolean",description:"true if the value can be casted to numeric."},errors:[]},{isDocumented:!0,arity:1,name:"lcm",qname:"excel:lcm",signature:"($numbers as xs:integer+) as xs:integer",description:' Returns the least common multiple of integers.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n LCM for two numbers is computed by multiplying them and dividing with GCD. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The function is applied recursively replacing the first two numbers in the sequence with their LCM.\n',summary:"<p> Returns the least common multiple of integers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:integer",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of one or more positive integers.</div>'}],returns:{type:"xs:integer",description:"The LCM as integer."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if any number is smaller than zero.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"mod",qname:"excel:mod",signature:"($number as xs:anyAtomicType, $divisor as xs:anyAtomicType) as xs:anyAtomicType",description:" Returns the remainder after number is divided by divisor.\n The result has the same sign as divisor.\n",summary:"<p> Returns the remainder after number is divided by divisor.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number for which you want to find the remainder.</div>'},{name:"divisor",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number by which you want to divide number. This cannot be zero.</div>'}],returns:{type:"xs:anyAtomicType",description:"The remainder from division as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Div0 if divisor is zero after casting to numeric.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"mround",qname:"excel:mround",signature:"($number as xs:anyAtomicType, $multiple as xs:anyAtomicType) as xs:anyAtomicType",description:" Returns a number rounded to the desired multiple.\n MROUND rounds up, away from zero, if the remainder of dividing number by multiple\n is greater than or equal to half the value of multiple.\n MROUND is computed through floor function.\n",summary:"<p> Returns a number rounded to the desired multiple.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to round, castable to numeric type.</div>'},{name:"multiple",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The multiple to which you want to round number.</div>'}],returns:{type:"xs:anyAtomicType",description:"The rounded number up to the desired multiple."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"odd",qname:"excel:odd",signature:"($number as xs:anyAtomicType) as xs:integer",description:" Returns number rounded up to the nearest odd integer, away from zero.\n",summary:"<p> Returns number rounded up to the nearest odd integer, away from zero.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to round.</div>'}],returns:{type:"xs:integer",description:"The odd integer."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameter cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"pi",qname:"excel:pi",signature:"() as xs:decimal",description:" Return the value of PI as decimal with 15 digits.\n",summary:"<p> Return the value of PI as decimal with 15 digits.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:decimal",description:"The value of PI with 15 digits."},errors:[]},{isDocumented:!0,arity:2,name:"power",qname:"excel:power",signature:"($number as xs:anyAtomicType, $power as xs:integer) as xs:anyAtomicType",description:" Returns the result of a number raised to a power.\n The result is computed through successive multiplications.\n",summary:"<p> Returns the result of a number raised to a power.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The base number.</div>'},{name:"power",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The exponent as integer (cannot be floating point like in Excel).</div>'}],returns:{type:"xs:anyAtomicType",description:"The result as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameter cannot be casted to numeric type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if power is smaller than zero.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"product",qname:"excel:product",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies all the numbers given as arguments and returns the product.\n",summary:"<p> Multiplies all the numbers given as arguments and returns the product.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of arguments convertable to numeric types. The sequence can be of any length.</div>'}],returns:{type:"xs:anyAtomicType",description:"The multiplication result as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"quotient",qname:"excel:quotient",signature:"($numerator as xs:anyAtomicType, $denominator as xs:anyAtomicType) as xs:integer",description:" Returns the integer portion of a division.\n",summary:"<p> Returns the integer portion of a division.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numerator",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The divident.</div>'},{name:"denominator",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The divisor. It cannot be zero.</div>'}],returns:{type:"xs:integer",description:"The result value as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Div0 if denominator casted as numeric type has value zero.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"radians",qname:"excel:radians",signature:"($degree as xs:integer) as xs:decimal",description:" Converts degrees to radians.\n",summary:"<p> Converts degrees to radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"degree",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An angle in degrees that you want to convert.</div>'}],returns:{type:"xs:decimal",description:"The value in radians."},errors:[]},{isDocumented:!0,arity:1,name:"roman",qname:"excel:roman",signature:"($number as xs:integer) as xs:string",description:' Converts an arabic numeral to roman, as text.\n Only the clasic format is supported (out of all formats Excel requires).<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n M is the largest digit, it represents 1000.\n Numbers bigger than 2000 will be represented by a sequence of "M".<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n D = 500, C = 100, L = 50, X = 10, V = 5, I = 1.\n',summary:"<p> Converts an arabic numeral to roman, as text.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A positive integer.</div>'}],returns:{type:"xs:string",description:"The roman string representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if the input integer is negative</xqdoc:error>']},{isDocumented:!0,arity:2,name:"round",qname:"excel:round",signature:"($number as xs:anyAtomicType, $precision as xs:integer) as xs:anyAtomicType",description:" Rounds a number to a specified number of digits.\n If precision is greater than 0 (zero), then number is rounded\n to the specified number of decimal places.\n If num_digits is 0, then number is rounded to the nearest integer.\n If num_digits is less than 0, then number is rounded to the left of the decimal point.\n The 0.5 is rounded away from zero.\n",summary:"<p> Rounds a number to a specified number of digits.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number to round, castable to a numeric type.</div>'},{name:"precision",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of decimal places to keep.</div>'}],returns:{type:"xs:anyAtomicType",description:"The rounded number as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"rounddown",qname:"excel:rounddown",signature:"($number as xs:anyAtomicType, $precision as xs:integer) as xs:anyAtomicType",description:" Rounds a number down, toward zero.\n If num_digits is greater than 0 (zero), then number is rounded down\n to the specified number of decimal places.\n If num_digits is 0, then number is rounded down to the nearest integer.\n If num_digits is less than 0, then number is rounded down to the left of the decimal point.\n",summary:"<p> Rounds a number down, toward zero.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number to round, castable to numeric type.</div>'},{name:"precision",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of decimal places to keep.</div>'}],returns:{type:"xs:anyAtomicType",description:"the truncated number toward zero, as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"roundup",qname:"excel:roundup",signature:"($number as xs:anyAtomicType, $precision as xs:integer) as xs:anyAtomicType",description:" Rounds a number up, away from 0 (zero).\n If num_digits is greater than 0 (zero), then number is rounded down\n to the specified number of decimal places.\n If num_digits is 0, then number is rounded down to the nearest integer.\n If num_digits is less than 0, then number is rounded down to the left of the decimal point.\n",summary:"<p> Rounds a number up, away from 0 (zero).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number to round, castable to numeric type.</div>'},{name:"precision",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of decimal places to keep.</div>'}],returns:{type:"xs:anyAtomicType",description:"The truncated number away from zero, as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"sign",qname:"excel:sign",signature:"($number as xs:anyAtomicType) as xs:integer",description:" Determines the sign of a number.\n Returns 1 if the number is positive, zero (0) if the number is 0,\n and -1 if the number is negative.\n",summary:"<p> Determines the sign of a number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The argument castable to numeric type.</div>'}],returns:{type:"xs:integer",description:"The sign as (-1, 0, 1)."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"sort-numbers",qname:"excel:sort-numbers",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType*",description:' Helper function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Sorts a sequence of numbers or arguments castable to numeric.\n It first casts all arguments to numeric and then sorts ascending.\n',summary:"<p> Helper function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of arguments castable to numeric.</div>'}],returns:{type:"xs:anyAtomicType*",description:"The sorted sequence as numeric types."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"sum",qname:"excel:sum",signature:"($numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Adds all the numbers in the sequence.\n",summary:"<p> Adds all the numbers in the sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of arguments castable to numeric types. The sequence can be of any length.</div>'}],returns:{type:"xs:anyAtomicType",description:"The sum as numeric type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameters cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"trunc",qname:"excel:trunc",signature:"($number as xs:anyAtomicType) as xs:integer",description:" Truncates a number to an integer by removing the fractional part of the number.\n",summary:"<p> Truncates a number to an integer by removing the fractional part of the number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The argument castable to numeric type.</div>'}],returns:{type:"xs:integer",description:"The integer value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameter cannot be casted to numeric type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"trunc",qname:"excel:trunc",signature:"($number as xs:anyAtomicType, $precision as xs:integer) as xs:anyAtomicType",description:" Truncates a number down to precision.\n This behaves exactly like rounddown.\n",summary:"<p> Truncates a number down to precision.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The argument castable to numeric type.</div>'},{name:"precision",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of decimal places to keep .</div>'}],returns:{type:"xs:anyAtomicType",description:"The integer value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if parameter cannot be casted to numeric type.</xqdoc:error>']}],variables:[]},"http://api.28.io/browserview":{ns:"http://api.28.io/browserview",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/browserview",prefix:"browserview"},{uri:"http://api.28.io/model",prefix:"model"},{uri:"http://zorba.io/modules/reference",prefix:"ref"}],functions:[{isDocumented:!1,arity:1,name:"node-path",qname:"browserview:node-path",signature:"($node)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"node-reference",qname:"browserview:node-reference",signature:"($node, $short as xs:boolean)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:null,occurrence:null,description:""},{name:"short",type:"xs:boolean",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"serialize",qname:"browserview:serialize",signature:"($json)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"json",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"serializeMulti",qname:"browserview:serializeMulti",signature:"($json)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"json",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"show-namespaces",qname:"browserview:show-namespaces",signature:"($namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"show-node",qname:"browserview:show-node",signature:"($node, $namespaces, $short as xs:boolean)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"node",type:null,occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""},{name:"short",type:"xs:boolean",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"show-nodes",qname:"browserview:show-nodes",signature:"($nodes)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]}],variables:[]},"http://zorba.io/modules/json-csv":{ns:"http://zorba.io/modules/json-csv",description:' This module provides an API for parsing and serializing CSV (comma-separated\n values) files.\n See RFC 4180,\n "Common Format and MIME Type for Comma-Separated Values (CSV) Files."\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Paul J. Lucas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/json-csv",prefix:"csv"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"parse",qname:"csv:parse",signature:"($csv as string) as object()*",description:' Parses a CSV (comma-separated values) string using the default options.\n A newline (U+000A), optionally preceeded by a carriage-return (U+000D),\n terminates lines, aka, "records."\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Quoted values are always considered strings;\n unquoted values are attempted to be cast to other types, e.g., integer\n (unless the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">cast-unquoted-values</code> option is <code xmlns:xqdoc="http://www.xqdoc.org/1.0">false</code>).\n Casting is attempted in the following order:\n integer, decimal, double, and boolean.\n If casting fails, the value is considered a string.\n Header field names are always considered strings even if unquoted.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n In addition to the "normal" values of\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">false</code> for boolean,\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">T</code> and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">Y</code> are also considered "true"\n and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">F</code> and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">N</code> are also considered "false."\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The default options are:\n  <dl xmlns:xqdoc="http://www.xqdoc.org/1.0">\n    <dt><code>cast-unquoted-values</code></dt>\n      <dd>\n        Whether to attempt to cast unquoted values to\n        integer, decimal, double, or boolean;\n        default: <code>true</code>.\n      </dd>\n    <dt><code>extra-name</code></dt>\n      <dd>\n        The field name for extra values, if any;\n        default: none (error <code>csv:EXTRA_VALUE</code> is raised).\n      </dd>\n    <dt><code>field-names</code></dt>\n      <dd>\n        A JSON array of strings denoting field names;\n        default: none.\n        The first CSV line is assumed to be a header line\n        and the field names are taken from this line.\n      </dd>\n    <dt><code>missing-value</code></dt>\n      <dd>\n        What should happen when a missing value is detected;\n        default: <code>"null"</code>.\n        A "missing" value is one of:\n        <ul>\n          <li>Two consecutive <code>quote-char</code> characters.</li>\n          <li>A <code>quote-char</code> character as either the first\n              or last character on a line.</li>\n          <li>Fewer values than the number of field names.</li>\n        </ul>\n        When a missing value is detected,\n        the value is set to <code>null</code>.\n      </dd>\n    <dt><code>quote-char</code></dt>\n      <dd>\n        The single ASCII character that may be used to quote values;\n        default: <code>"</code> (U+0022).\n      </dd>\n    <dt><code>quote-escape</code></dt>\n      <dd>\n        The single ASCII character used to escape <code>quote-char</code>;\n        default: same as <code>quote-char</code>.\n        This means that an escaped quote is doubled as <code>""</code>.\n      </dd>\n    <dt><code>separator</code></dt>\n      <dd>\n        The single ASCII character used to separate values;\n        default: <code>,</code> (U+002C).\n      </dd>\n  </dl>\n',summary:"<p> Parses a CSV (comma-separated values) string using the default options.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"csv",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The CSV string to parse.</div>'}],returns:{type:"object()*",description:"a sequence of zero or more JSON objects where each key is a field name and each value is a parsed value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">csv:EXTRA_VALUE if an extra value is detected.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"parse",qname:"csv:parse",signature:"($csv as string, $options as object()) as object()* external",description:' Parses a CSV (comma-separated values) string using the given options.\n A newline (U+000A), optionally preceeded by a carriage-return (U+000D),\n terminates lines, aka, "records."\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Quoted values are always considered strings;\n unquoted values are attempted to be cast to other types, e.g., integer\n (unless the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">cast-unquoted-values</code> option is <code xmlns:xqdoc="http://www.xqdoc.org/1.0">false</code>).\n Casting is attempted in the following order:\n integer, decimal, double, and boolean.\n If casting fails, the value is considered a string.\n Header field names are always considered strings even if unquoted.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n In addition to the "normal" values of\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">false</code> for boolean,\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">T</code> and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">Y</code> are also considered "true"\n and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">F</code> and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">N</code> are also considered "false."\n',summary:"<p> Parses a CSV (comma-separated values) string using the given options.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"csv",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The CSV string to parse.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The options to use: <dl> <dt><code>cast-unquoted-values</code></dt> <dd> Whether to attempt to cast unquoted values to integer, decimal, double, or boolean; default: <code>true</code>. </dd> <dt><code>extra-name</code></dt> <dd> The field name for extra values, if any; default: none (error <code>csv:EXTRA_VALUE</code> is raised). If this option is given and a line contains one or more extra values (that is, values that have no corresponding field names), then the extra values are assigned as the values for fields having <code>extra-name</code> as their names. <p/> If <code>extra-name</code> contains a <code>#</code> (U+0023), then the <code>#</code> is substituted with the field number (where field numbers start at 1). If <code>extra-name</code> does not contains a <code>#</code>, then the field number is appended. </dd> <dt><code>field-names</code></dt> <dd> A JSON array of strings denoting field names; default: none. If this option is given, then the first CSV line is assumed not to be a header line; if omitted, then the first CSV line is assumed to be a header line and the field names are taken from this line. </dd> <dt><code>missing-value</code></dt> <dd> What should happen when a missing value is detected; default: <code>"null"</code>. A "missing" value is one of: <ul> <li>Two consecutive <code>separator</code> characters.</li> <li>A <code>separator</code> character as either the first or last character on a line.</li> <li>Fewer values than the number of field names.</li> </ul> When a missing value is detected, the value of this option determines what happens: <dl> <dt><code>"error"</code></dt> <dd>Error <code>csv:MISSING_VALUE</code> is raised.</dd> <dt><code>"omit"</code></dt> <dd>Both the value and its key are omitted from the result object.</dd> <dt><code>"null"</code></dt> <dd>The value is set to <code>null</code>.</dd> </dl> </dd> <dt><code>quote-char</code></dt> <dd> The single ASCII character that may be used to quote values; default: <code>"</code> (U+0022). </dd> <dt><code>quote-escape</code></dt> <dd> The single ASCII character used to escape <code>quote-char</code>; default: same as <code>quote-char</code>. If <code>quote-escape</code> equals <code>quote-char</code>, it means that <code>quote-char</code> must be doubled to escape it. If <code>quote-escape</code> does not equal <code>quote-char</code>, it means that <code>quote-escape</code> is used to escape <code>quote-char</code>. For example, a <code>quote-char</code> of <code>"</code> (U+0022) and a <code>quote-escape</code> of <code>\\</code> (U+005C) means that quotes will be escaped by <code>\\"</code>. </dd> <dt><code>separator</code></dt> <dd> The single ASCII character used to separate values; default: <code>,</code> (U+002C). </dd> </dl></div>'}],returns:{type:"object()*",description:"a sequence of zero or more JSON objects where each key is a field name and each value is a parsed value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">csv:INVALID_OPTION if the <code>quote-char</code>, <code>quote-escape</code>, or <code>separator</code> option is given and it\'s not a single ASCII character.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">csv:MISSING_VALUE if a missing value is detected and the <code>missing-value</code> option is "<code>error</code>".</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">csv:EXTRA_VALUE if an extra value is detected and the <code>extra-name</code> option is not set.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"serialize",qname:"csv:serialize",signature:"($obj as object()*) as string*",description:' Serializes a sequence of JSON objects as CSV (comma-separated values) using\n the default options.\n The default options are:\n  <dl xmlns:xqdoc="http://www.xqdoc.org/1.0">\n    <dt><code>field-names</code></dt>\n      <dd>\n        A JSON array of strings denoting field names;\n        default: none.\n        The field names are taken from the first JSON object\n        and the order of the fields is implementation dependent.\n      </dd>\n    <dt><code>serialize-boolean-as</code></dt>\n      <dd>\n        What strings to serialize <code>true</code> and <code>false</code> as;\n        default: <code>true</code> and <code>false</code>.\n      </dd>\n    <dt><code>serialize-header</code></dt>\n      <dd>\n        Whether a header line is included;\n        default: <code>true</code>.\n        The first string result is the header line\n        comprised of all the objects\' keys\' names.\n      </dd>\n    <dt><code>serialize-null-as</code></dt>\n      <dd>\n        What string to serialize JSON <code>null</code> values as;\n        default: <code>null</code>.\n      </dd>\n    <dt><code>quote-char</code></dt>\n      <dd>\n        The single ASCII character that may be used to quote values;\n        default: <code>"</code> (U+0022).\n      </dd>\n    <dt><code>quote-escape</code></dt>\n      <dd>\n        The single ASCII character used to escape <code>quote-char</code>;\n        default: same as <code>quote-char</code>.\n        This means that <code>quote-char</code> is doubled to escape it.\n      </dd>\n    <dt><code>separator</code></dt>\n      <dd>\n        The single ASCII character used to separate values;\n        default: <code>,</code> (U+002C).\n      </dd>\n  </dl>\n',summary:"<p> Serializes a sequence of JSON objects as CSV (comma-separated values) using\n the default options.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"obj",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of JSON objects to serialize.</div>'}],returns:{type:"string*",description:'a sequence of strings where each string corresponds to a JSON object, aka, "record."'},errors:[]},{isDocumented:!0,arity:2,name:"serialize",qname:"csv:serialize",signature:"($obj as object()*, $options as object()) as string* external",description:" Serializes a sequence of JSON objects as CSV (comma-separated values) using\n the given options.\n",summary:"<p> Serializes a sequence of JSON objects as CSV (comma-separated values) using\n the given options.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"obj",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of JSON objects to serialize.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The options to use: <dl> <dt><code>field-names</code></dt> <dd> A JSON array of strings denoting field names; default: none. If this option is not set, the field names are taken from the first JSON object and the order of the fields is implementation dependent. If this option is set, the fields are serielized in the order they are in the array. In either case, every JSON object must have the same keys as the first object. </dd> <dt><code>serialize-boolean-as</code></dt> <dd> What strings to serialize <code>true</code> and <code>false</code> as; default: <code>true</code> and <code>false</code>. This must be a sub-object with the two keys <code>"true"</code> and <code>"false"</code>, e.g.: <code>{ "true" : "Y", "false" : "N" }</code>. </dd> <dt><code>serialize-header</code></dt> <dd> Whether a header line is included; default: <code>true</code>. If <code>true</code>, the first string result is the header line comprised of all the objects\' keys\' names; if <code>false</code>, the heder line is not returned. </dd> <dt><code>serialize-null-as</code></dt> <dd> What string to serialize JSON <code>null</code> values as; default: <code>null</code>. </dd> <dt><code>quote-char</code></dt> <dd> The single ASCII character that may be used to quote values; default: <code>"</code> (U+0022). </dd> <dt><code>quote-escape</code></dt> <dd> The single ASCII character used to escape <code>quote-char</code>; default: same as <code>quote-char</code>. If <code>quote-escape</code> equals <code>quote-char</code>, it means that <code>quote-char</code> must be doubled to escape it. If <code>quote-escape</code> does not equal <code>quote-char</code>, it means that <code>quote-escape</code> is used to escape <code>quote-char</code>. For example, a <code>quote-char</code> of <code>"</code> (U+0022) and a <code>quote-escape</code> of <code>\\</code> (U+005C) means that quotes will be escaped by <code>\\"</code>. </dd> <dt><code>separator</code></dt> <dd> The single ASCII character used to separate values; default: <code>,</code> (U+002C). </dd> </dl></div>'}],returns:{type:"string*",description:'a sequence of strings where each string corresponds to a JSON object, aka, "record."'},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/email/imap":{ns:"http://www.zorba-xquery.com/modules/email/imap",description:' This module provides functions for accessing and manipulating emails on mail\n servers through the IMAP protocol.\n All functions in this module receive as the first argument the IMAP host and user\n information. This is an element with the type <code xmlns:xqdoc="http://www.xqdoc.org/1.0">hostInfoType</code> as defined\n in the email schema: <code xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.zorba-xquery.com/modules/email</code>.\n For example:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n &lt;email:hostInfo&gt;\n   &lt;email:hostName&gt;imap.example.com&lt;/email:hostName&gt;\n   &lt;email:userName&gt;myuser&lt;/email:userName&gt;\n   &lt;email:password&gt;mypassword&lt;/email:password&gt;\n &lt;/email:hostInfo&gt;\n </pre>\n The <code xmlns:xqdoc="http://www.xqdoc.org/1.0">hostInfoType</code> only needs to be in the email schema namespace\n (<code xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.zorba-xquery.com/modules/email</code>). It does not need\n to be validated since it\'s validated by the module.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.washington.edu/imap/">c-client library part of UW IMAP toolkit</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Thomas, Gabriel Petrovay</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.zorba-xquery.com/modules/email",prefix:"email"},{uri:"http://www.zorba-xquery.com/modules/email/imap",prefix:"imap"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:5,name:"copy",qname:"imap:copy",signature:"($host-info as element(email:hostInfo), $mailbox-from as xs:string, $mailbox-to as xs:string, $messages as xs:long+, $uid as xs:boolean?) as empty-sequence()",description:' Copies messages between mailboxes.\n Depending on the value of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$uid</code>, the messages are either specified\n through their sequence number or through their unique id. Both mailboxes must exist.\n',summary:"<p> Copies messages between mailboxes.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox-from",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox in which the messages reside.</div>'},{name:"mailbox-to",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox in to which the messages are copied.</div>'},{name:"messages",type:"xs:long",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The messages to be copied, specified either by their sequence number or their unique id.</div>'},{name:"uid",type:"xs:boolean",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If true, <code>$messages</code> are treated as sequence numbers. Else as unique identifiers.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:2,name:"create",qname:"imap:create",signature:"($host-info as element(email:hostInfo), $mailbox-name as xs:string) as empty-sequence()",description:" Creates a new mailbox for the given user.\n",summary:"<p> Creates a new mailbox for the given user.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox-name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name for the new mailbox.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete",qname:"imap:delete",signature:"($host-info as element(email:hostInfo), $mailbox-name as xs:string) as empty-sequence()",description:" Deletes a mailbox for the given user.\n",summary:"<p> Deletes a mailbox for the given user.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox-name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the mailbox to delete.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:2,name:"expunge",qname:"imap:expunge",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string) as empty-sequence()",description:' Permanently deletes all messages of the given mailbox that have the "deleted" flag set.\n',summary:'<p> Permanently deletes all messages of the given mailbox that have the "deleted" flag set.</p>',annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox for which all messages that have the \\Deleted flag set should be permanently deleted.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:4,name:"fetch-envelope",qname:"imap:fetch-envelope",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string, $message-number as xs:long, $uid as xs:boolean?) as element(email:envelope)",description:" Fetches the envelope of a message.\n",summary:"<p> Fetches the envelope of a message.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox in which to search for the message.</div>'},{name:"message-number",type:"xs:long",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The message for which to fetch the envelope (depending on <code>$uid</code> either as message sequence number or unique identifier).</div>'},{name:"uid",type:"xs:boolean",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If true, <code>$message-number</code> is treated as sequence number. Else as unique identifier.</div>'}],returns:{type:"element(email:envelope)",description:'The <code xmlns:xqdoc="http://www.xqdoc.org/1.0">envelope</code> of the requested message. The result is validated against the schema: <code xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.zorba-xquery.com/modules/email</code>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:4,name:"fetch-flags",qname:"imap:fetch-flags",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string, $message-number as xs:long, $uid as xs:boolean?) as element(email:flags)",description:" Fetches the flags of a message.\n",summary:"<p> Fetches the flags of a message.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox containing the specified message.</div>'},{name:"message-number",type:"xs:long",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Either the message sequence number or the unique identifier of the message.</div>'},{name:"uid",type:"xs:boolean",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If true, <code>$message-number</code> is treated as sequence number. Else as unique identifier.</div>'}],returns:{type:"element(email:flags)",description:'The <code xmlns:xqdoc="http://www.xqdoc.org/1.0">flags</code> of the specified message. The result is validated against the schema: <code xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.zorba-xquery.com/modules/email</code>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:3,name:"fetch-from",qname:"imap:fetch-from",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string, $message-number as xs:long) as xs:string",description:" Fetches the 'from' string of a message.\n Please note that this function only words with message sequence numbers,\n not with unique identifiers. Only the first 255 characters of a 'from'\n string are fetched.\n",summary:"<p> Fetches the 'from' string of a message.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> The mailbox for which we want to get the 'from' string of a message.</div>"},{name:"message-number",type:"xs:long",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> Denotes the message for which we want the 'from' string.</div>"}],returns:{type:"xs:string",description:"The 'from' string of the specified message."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:3,name:"fetch-message-sequence-number",qname:"imap:fetch-message-sequence-number",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string, $message-number as xs:long) as xs:long",description:" Fetches the message sequence number for a given unique identifier.\n",summary:"<p> Fetches the message sequence number for a given unique identifier.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox for which we want to get the message sequence number of an unique identifier.</div>'},{name:"message-number",type:"xs:long",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The unique identifier for which we want the message sequence number.</div>'}],returns:{type:"xs:long",description:"The message sequence number of the of the given unique identifier."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:4,name:"fetch-message",qname:"imap:fetch-message",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string, $message-number as xs:long, $uid as xs:boolean) as element(email:message)",description:" Fetches a whole message.\n",summary:"<p> Fetches a whole message.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox in which to search for the message.</div>'},{name:"message-number",type:"xs:long",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The message to fetch, denoted either by its sequence number or unique identifier.</div>'},{name:"uid",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If true, <code>$message-number</code> is treated as sequence number. Else as unique identifier.</div>'}],returns:{type:"element(email:message)",description:'the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">message</code> with the given <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$message-number</code>. The result is validated against the schema: <code xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.zorba-xquery.com/modules/email</code>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:3,name:"fetch-subject",qname:"imap:fetch-subject",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string, $message-number as xs:long) as xs:string",description:" Fetches the subject for a message.\n Please note that this function only works with message sequence numbers,\n not with unique identifiers. Only the first 255 characters of a subject\n are fetched.\n",summary:"<p> Fetches the subject for a message.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox for which we want to get the subject of a message.</div>'},{name:"message-number",type:"xs:long",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Denotes the message for which we want the subject.</div>'}],returns:{type:"xs:string",description:"The subject of the specified message."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:3,name:"fetch-uid",qname:"imap:fetch-uid",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string, $message-number as xs:long) as xs:long",description:" Fetches the unique identifier for a given message sequence number.\n",summary:"<p> Fetches the unique identifier for a given message sequence number.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox for which we want to get the unique identifier of a message sequence number.</div>'},{name:"message-number",type:"xs:long",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The message sequence number for which we want the unique identifier.</div>'}],returns:{type:"xs:long",description:"The unique identifier of the given message sequence number."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:4,name:"list",qname:"imap:list",signature:"($host-info as element(email:hostInfo), $mailbox-ref as xs:string, $pattern as xs:string, $only-subscribed as xs:boolean) as element(email:mailbox)*",description:" Lists IMAP folders for the specified user on the host that match the pattern.\n",summary:"<p> Lists IMAP folders for the specified user on the host that match the pattern.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox-ref",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is applied to pattern in an implementation dependent fashion to search for matching mailbox names.</div>'},{name:"pattern",type:"xs:string",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> The pattern for mailboxes to look for (can include wildcards '*' and '%').</div>"},{name:"only-subscribed",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If set true, only mailboxes are listed to which the user is subscribed.</div>'}],returns:{type:"element(email:mailbox)*",description:'A sequence of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">mailbox</code> elements. The result elements are validated against the schema: <code xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.zorba-xquery.com/modules/email</code>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:5,name:"move",qname:"imap:move",signature:"($host-info as element(email:hostInfo), $mailbox-from as xs:string, $mailbox-to as xs:string, $messages as xs:long+, $uid as xs:boolean?) as empty-sequence()",description:' Moves messages between mailboxes.\n Depending on the value of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$uid</code>, the messages are either specified through\n their sequence number or through their unique id. Both mailboxes must exist.\n',summary:"<p> Moves messages between mailboxes.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox-from",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox in which the messages reside.</div>'},{name:"mailbox-to",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox in to which the messages should be moved.</div>'},{name:"messages",type:"xs:long",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The messages to be copied, specified either by their sequence number or their unique id.</div>'},{name:"uid",type:"xs:boolean",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If true, <code>$messages</code> are treated as sequence numbers. Else as unique identifiers.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:3,name:"rename",qname:"imap:rename",signature:"($host-info as element(email:hostInfo), $mailbox-old as xs:string, $mailbox-new as xs:string) as empty-sequence()",description:" Renames a mailbox.\n",summary:"<p> Renames a mailbox.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox-old",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the mailbox we want to rename.</div>'},{name:"mailbox-new",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The new name for the mailbox.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:4,name:"search",qname:"imap:search",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string, $criteria as xs:string, $uid as xs:boolean?) as xs:long*",description:" Searches a mailbox for messages that match the given criteria.\n The criteria should be a string as defined in the RFC3501 (IMAP4rev1).\n A valid example would be: 'FROM zorba@gmail.com OR NOT SUBJECT Bug'.\n Depending on the value of <code xmlns:xqdoc=\"http://www.xqdoc.org/1.0\">$uid</code>, the function will either\n return matching sequence numbers or unique identifiers.\n",summary:"<p> Searches a mailbox for messages that match the given criteria.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox to search.</div>'},{name:"criteria",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The searching criteria.</div>'},{name:"uid",type:"xs:boolean",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If true, the function returns the sequence of unique identifiers corresponding to the matching mails, else the corresponding sequence numbers are returned.</div>'}],returns:{type:"xs:long*",description:"Either the sequence of matching sequence numbers or the sequence of matching unique identifiers."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:5,name:"set-flags",qname:"imap:set-flags",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string, $message-number as xs:long, $flags as element(email:flags), $uid as xs:boolean?) as empty-sequence()",description:' Sets the flags for a given message.\n The flags are set and unset according to the passed <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$flags</code>.\n',summary:"<p> Sets the flags for a given message.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox containing the specified message.</div>'},{name:"message-number",type:"xs:long",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Either the message sequence number or the unique identifier of the message (depending on the value of <code>$uid</code>).</div>'},{name:"flags",type:"element(email:flags)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Defines which flags should be set for this message. The possibilities are "seen", "deleted", "flagged", "answered", and "draft". Setting all flags at once is done by passing the element: <code> &lt;email:flags&gt; &lt;email:seen/&gt; &lt;email:deleted/&gt; &lt;email:flagged/&gt; &lt;email:answered/&gt; &lt;email:draft/&gt; &lt;/email:flags&gt; </code>. Setting "flagged" only and unsetting all other at once can be done by passing: <code> &lt;email:flags&gt; &lt;email:flagged/&gt; &lt;/email:flags&gt; </code>.</div>'},{name:"uid",type:"xs:boolean",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If true, <code>$message-number</code> is treated as sequence number. Else as unique identifier.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0003 If no message is found with the provided sequence number/unique identifier.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:2,name:"status",qname:"imap:status",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string) as element(email:status)",description:' Returns the status of the given mailbox.\n The status of a mailbox contains:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  <li><code>messages</code>: the number of messages in the mailbox</li>\n  <li><code>recent</code>: the number of messages flagged as recent</li>\n  <li><code>unseen</code>: the number of messages flagged as unseen</li>\n  <li><code>uidnext</code>: the next unique identifier that will be assigned to a message</li>\n  <li><code>uidvalidity</code>: a value that, together with the <code>uidnext</code> value\n    forms a 64 bit number that must be unique for the server</li>\n </ul>\n',summary:"<p> Returns the status of the given mailbox.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox for which we want to have the status.</div>'}],returns:{type:"element(email:status)",description:'The <code xmlns:xqdoc="http://www.xqdoc.org/1.0">status</code> of the specified <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$mailbox</code>. The result is validated against the schema: <code xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.zorba-xquery.com/modules/email</code>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:2,name:"subscribe",qname:"imap:subscribe",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string) as empty-sequence()",description:" Subscribes the user to the specified mailbox.\n",summary:"<p> Subscribes the user to the specified mailbox.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox the user wants to subscribe to.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']},{isDocumented:!0,arity:2,name:"unsubscribe",qname:"imap:unsubscribe",signature:"($host-info as element(email:hostInfo), $mailbox as xs:string) as empty-sequence()",description:" Unsubscribes the user from the specified mailbox.\n",summary:"<p> Unsubscribes the user from the specified mailbox.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The IMAP host, user name, and password.</div>'},{name:"mailbox",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mailbox the user wants to unsubscribe from.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0001 If the IMAP operation failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">imap:IMAP0002 If the connection to the IMAP server is refused.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the value of <code>$host-info</code> is not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']}],variables:[]},"http://zorba.io/errors":{ns:"http://zorba.io/errors",description:" This module contains one variable declaration for each diagnostic of the\n http://zorba.io/errors namespace.\n The variables serves as documentation for the errors but can also\n be used in the code. For example, one useful scenario is to compare\n an error caught in the catch clause of a try-catch expression with one of\n the variables.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Carlos Lopez</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[],variables:[{name:"zerr:ZDST0032",type:"item()*",description:""},{name:"zerr:ZDST0004",type:"item()*",description:""},{name:"zerr:ZDST0006",type:"item()*",description:""},{name:"zerr:ZDST0007",type:"item()*",description:""},{name:"zerr:ZDST0021",type:"item()*",description:""},{name:"zerr:ZDST0022",type:"item()*",description:""},{name:"zerr:ZDST0023",type:"item()*",description:""},{name:"zerr:ZDST0024",type:"item()*",description:""},{name:"zerr:ZDST0025",type:"item()*",description:""},{name:"zerr:ZDST0026",type:"item()*",description:""},{name:"zerr:ZDST0027",type:"item()*",description:""},{name:"zerr:ZDST0028",type:"item()*",description:""},{name:"zerr:ZDST0029",type:"item()*",description:""},{name:"zerr:ZDST0030",type:"item()*",description:""},{name:"zerr:ZDST0031",type:"item()*",description:""},{name:"zerr:ZDST0003",type:"item()*",description:""},{name:"zerr:ZDST0033",type:"item()*",description:""},{name:"zerr:ZDST0034",type:"item()*",description:""},{name:"zerr:ZDST0035",type:"item()*",description:""},{name:"zerr:ZDST0036",type:"item()*",description:""},{name:"zerr:ZDST0041",type:"item()*",description:""},{name:"zerr:ZDST0044",type:"item()*",description:""},{name:"zerr:ZDST0048",type:"item()*",description:""},{name:"zerr:ZDST0060",type:"item()*",description:""},{name:"zerr:ZDTY0001",type:"item()*",description:""},{name:"zerr:ZDTY0010",type:"item()*",description:""},{name:"zerr:ZDTY0011",type:"item()*",description:""},{name:"zerr:ZDTY0012",type:"item()*",description:""},{name:"zerr:ZGDB0001",type:"item()*",description:""},{name:"zerr:ZOSE0001",type:"item()*",description:""},{name:"zerr:ZDDY0038",type:"item()*",description:""},{name:"zerr:ZDDY0024",type:"item()*",description:""},{name:"zerr:ZDDY0025",type:"item()*",description:""},{name:"zerr:ZDDY0026",type:"item()*",description:""},{name:"zerr:ZDDY0027",type:"item()*",description:""},{name:"zerr:ZDDY0028",type:"item()*",description:""},{name:"zerr:ZDDY0029",type:"item()*",description:""},{name:"zerr:ZDDY0030",type:"item()*",description:""},{name:"zerr:ZDDY0031",type:"item()*",description:""},{name:"zerr:ZDDY0032",type:"item()*",description:""},{name:"zerr:ZDDY0033",type:"item()*",description:""},{name:"zerr:ZDDY0034",type:"item()*",description:""},{name:"zerr:ZDDY0035",type:"item()*",description:""},{name:"zerr:ZDDY0036",type:"item()*",description:""},{name:"zerr:ZDDY0037",type:"item()*",description:""},{name:"zerr:ZOSE0002",type:"item()*",description:""},{name:"zerr:ZDDY0039",type:"item()*",description:""},{name:"zerr:ZDDY0040",type:"item()*",description:""},{name:"zerr:ZDDY0041",type:"item()*",description:""},{name:"zerr:ZDDY0042",type:"item()*",description:""},{name:"zerr:ZDDY0043",type:"item()*",description:""},{name:"zerr:ZDDY1000",type:"item()*",description:""},{name:"zerr:ZDDY1001",type:"item()*",description:""},{name:"zerr:ZDDY1003",type:"item()*",description:""},{name:"zerr:ZDDY1004",type:"item()*",description:""},{name:"zerr:ZDDY1005",type:"item()*",description:""},{name:"zerr:ZDDY1006",type:"item()*",description:""},{name:"zerr:ZDST0001",type:"item()*",description:""},{name:"zerr:ZDST0002",type:"item()*",description:""},{name:"zerr:ZJPE0005",type:"item()*",description:""},{name:"zerr:XSST0001",type:"item()*",description:""},{name:"zerr:XSST0002",type:"item()*",description:""},{name:"zerr:XSST0003",type:"item()*",description:""},{name:"zerr:XSST0004",type:"item()*",description:""},{name:"zerr:XSST0005",type:"item()*",description:""},{name:"zerr:XSST0006",type:"item()*",description:""},{name:"zerr:XSST0007",type:"item()*",description:""},{name:"zerr:XSST0008",type:"item()*",description:""},{name:"zerr:XSST0009",type:"item()*",description:""},{name:"zerr:XSST0010",type:"item()*",description:""},{name:"zerr:ZJPE0001",type:"item()*",description:""},{name:"zerr:ZJPE0002",type:"item()*",description:""},{name:"zerr:ZJPE0003",type:"item()*",description:""},{name:"zerr:ZJPE0004",type:"item()*",description:""},{name:"zerr:ZSTR0066",type:"item()*",description:""},{name:"zerr:ZJPE0006",type:"item()*",description:""},{name:"zerr:ZJPE0007",type:"item()*",description:""},{name:"zerr:ZJPE0008",type:"item()*",description:""},{name:"zerr:ZJPE0009",type:"item()*",description:""},{name:"zerr:ZJPE0010",type:"item()*",description:""},{name:"zerr:ZJSE0001",type:"item()*",description:""},{name:"zerr:ZJSE0002",type:"item()*",description:""},{name:"zerr:ZJSE0003",type:"item()*",description:""},{name:"zerr:ZJSE0004",type:"item()*",description:""},{name:"zerr:ZJSE0007",type:"item()*",description:""},{name:"zerr:ZJSE0008",type:"item()*",description:""},{name:"zerr:ZJSE0009",type:"item()*",description:""},{name:"zerr:ZJ2X0001",type:"item()*",description:""},{name:"zerr:ZSTR0012",type:"item()*",description:""},{name:"zerr:ZOSE0003",type:"item()*",description:""},{name:"zerr:ZOSE0004",type:"item()*",description:""},{name:"zerr:ZOSE0005",type:"item()*",description:""},{name:"zerr:ZOSE0006",type:"item()*",description:""},{name:"zerr:ZOSE0007",type:"item()*",description:""},{name:"zerr:ZSTR0001",type:"item()*",description:""},{name:"zerr:ZSTR0002",type:"item()*",description:""},{name:"zerr:ZSTR0003",type:"item()*",description:""},{name:"zerr:ZSTR0004",type:"item()*",description:""},{name:"zerr:ZSTR0007",type:"item()*",description:""},{name:"zerr:ZSTR0008",type:"item()*",description:""},{name:"zerr:ZSTR0009",type:"item()*",description:""},{name:"zerr:ZSTR0010",type:"item()*",description:""},{name:"zerr:ZSTR0011",type:"item()*",description:""},{name:"zerr:ZDDY0023",type:"item()*",description:""},{name:"zerr:ZSTR0013",type:"item()*",description:""},{name:"zerr:ZSTR0015",type:"item()*",description:""},{name:"zerr:ZSTR0016",type:"item()*",description:""},{name:"zerr:ZSTR0020",type:"item()*",description:""},{name:"zerr:ZSTR0021",type:"item()*",description:""},{name:"zerr:ZSTR0030",type:"item()*",description:""},{name:"zerr:ZSTR0040",type:"item()*",description:""},{name:"zerr:ZSTR0041",type:"item()*",description:""},{name:"zerr:ZSTR0045",type:"item()*",description:""},{name:"zerr:ZSTR0050",type:"item()*",description:""},{name:"zerr:ZSTR0055",type:"item()*",description:""},{name:"zerr:ZSTR0060",type:"item()*",description:""},{name:"zerr:ZSTR0065",type:"item()*",description:""},{name:"zerr:ZXQD0004",type:"item()*",description:""},{name:"zerr:ZXQP0036",type:"item()*",description:""},{name:"zerr:ZXQP0037",type:"item()*",description:""},{name:"zerr:ZXQP0038",type:"item()*",description:""},{name:"zerr:ZXQP0039",type:"item()*",description:""},{name:"zerr:ZXQP0040",type:"item()*",description:""},{name:"zerr:ZXQP0050",type:"item()*",description:""},{name:"zerr:ZXQP0060",type:"item()*",description:""},{name:"zerr:ZXQP0061",type:"item()*",description:""},{name:"zerr:ZXQP8401",type:"xs:QName",description:" The version of the thesaurus is not the expected version.\n"},{name:"zerr:ZXQP8402",type:"xs:QName",description:" The thesaurus data file's endianness does not match that of the CPU.\n"},{name:"zerr:ZXQP8403",type:"xs:QName",description:" The thesaurus data contains an unexpected value.\n"},{name:"zerr:ZXQD0001",type:"item()*",description:""},{name:"zerr:ZXQD0002",type:"item()*",description:""},{name:"zerr:ZXQD0003",type:"item()*",description:""},{name:"zerr:ZXQP0035",type:"item()*",description:""},{name:"zerr:ZXQD0005",type:"item()*",description:""},{name:"zerr:ZXQD0006",type:"item()*",description:""},{name:"zerr:ZAPI0002",type:"item()*",description:""},{name:"zerr:ZAPI0003",type:"item()*",description:""},{name:"zerr:ZAPI0004",type:"item()*",description:""},{name:"zerr:ZAPI0005",type:"item()*",description:""},{name:"zerr:ZAPI0006",type:"item()*",description:""},{name:"zerr:ZAPI0007",type:"item()*",description:""},{name:"zerr:ZAPI0008",type:"item()*",description:""},{name:"zerr:ZAPI0009",type:"item()*",description:""},{name:"zerr:ZAPI0011",type:"item()*",description:""},{name:"zerr:ZAPI0014",type:"item()*",description:""},{name:"zerr:ZAPI0015",type:"item()*",description:""},{name:"zerr:ZAPI0019",type:"item()*",description:""},{name:"zerr:ZXQP0014",type:"item()*",description:""},{name:"zerr:ZXQP0000",type:"xs:QName",description:' An "error" constant for "no error."\n'},{name:"zerr:ZXQP0001",type:"item()*",description:""},{name:"zerr:ZXQP0002",type:"xs:QName",description:" A Zorba programming assertion failed.  If this error occurs, it is a bug\n and should be reported.\n"},{name:"zerr:ZXQP0003",type:"xs:QName",description:" Something unexpected occurred in Zorba.  If this error occurs, it is a\n bug and should be reported.\n"},{name:"zerr:ZXQP0004",type:"xs:QName",description:" A particular XQuery feature has not been implemented by Zorba.\n"},{name:"zerr:ZXQP0005",type:"xs:QName",description:" A particular XQuery feature has been implemented by Zorba, but the\n feature has not been enabled in the current build.\n"},{name:"zerr:ZXQP0006",type:"item()*",description:""},{name:"zerr:ZXQP0007",type:"item()*",description:""},{name:"zerr:ZXQP0008",type:"item()*",description:""},{name:"zerr:ZXQP0009",type:"item()*",description:""},{name:"zerr:ZXQP0010",type:"item()*",description:""},{name:"zerr:ZXQP0011",type:"item()*",description:""},{name:"zerr:ZXQP0012",type:"item()*",description:""},{name:"zerr:ZXQP0013",type:"item()*",description:""},{name:"zerr:ZAPI0020",type:"item()*",description:""},{name:"zerr:ZXQP0016",type:"item()*",description:""},{name:"zerr:ZXQP0017",type:"item()*",description:""},{name:"zerr:ZXQP0020",type:"item()*",description:""},{name:"zerr:ZXQP0021",type:"item()*",description:""},{name:"zerr:ZXQP0024",type:"item()*",description:""},{name:"zerr:ZXQP0025",type:"item()*",description:""},{name:"zerr:ZXQP0026",type:"item()*",description:""},{name:"zerr:ZXQP0028",type:"item()*",description:""},{name:"zerr:ZXQP0029",type:"item()*",description:""},{name:"zerr:ZXQP0030",type:"item()*",description:""},{name:"zerr:ZXQP0031",type:"item()*",description:""},{name:"zerr:ZXQP0032",type:"item()*",description:""},{name:"zerr:ZXQP0033",type:"item()*",description:""},{name:"zerr:ZDDY0009",type:"item()*",description:""},{name:"zerr:ZCSE0012",type:"item()*",description:""},{name:"zerr:ZCSE0013",type:"item()*",description:""},{name:"zerr:ZCSE0014",type:"item()*",description:""},{name:"zerr:ZCSE0015",type:"item()*",description:""},{name:"zerr:ZCSE0016",type:"item()*",description:""},{name:"zerr:ZCSE0017",type:"item()*",description:""},{name:"zerr:ZDDY0001",type:"item()*",description:""},{name:"zerr:ZDDY0002",type:"item()*",description:""},{name:"zerr:ZDDY0003",type:"item()*",description:""},{name:"zerr:ZDDY0004",type:"item()*",description:""},{name:"zerr:ZDDY0005",type:"item()*",description:""},{name:"zerr:ZDDY0006",type:"item()*",description:""},{name:"zerr:ZDDY0007",type:"item()*",description:""},{name:"zerr:ZDDY0008",type:"item()*",description:""},{name:"zerr:ZCSE0011",type:"item()*",description:""},{name:"zerr:ZDDY0010",type:"item()*",description:""},{name:"zerr:ZDDY0011",type:"item()*",description:""},{name:"zerr:ZDDY0012",type:"item()*",description:""},{name:"zerr:ZDDY0013",type:"item()*",description:""},{name:"zerr:ZDDY0014",type:"item()*",description:""},{name:"zerr:ZDDY0015",type:"item()*",description:""},{name:"zerr:ZDDY0016",type:"item()*",description:""},{name:"zerr:ZDDY0017",type:"item()*",description:""},{name:"zerr:ZDDY0018",type:"item()*",description:""},{name:"zerr:ZDDY0020",type:"item()*",description:""},{name:"zerr:ZDDY0019",type:"item()*",description:""},{name:"zerr:ZDDY0021",type:"item()*",description:""},{name:"zerr:ZDDY0022",type:"item()*",description:""},{name:"zerr:ZAPI0045",type:"item()*",description:""},{name:"zerr:ZAPI0021",type:"item()*",description:""},{name:"zerr:ZAPI0023",type:"item()*",description:""},{name:"zerr:ZAPI0024",type:"item()*",description:""},{name:"zerr:ZAPI0025",type:"item()*",description:""},{name:"zerr:ZAPI0026",type:"item()*",description:""},{name:"zerr:ZAPI0027",type:"item()*",description:""},{name:"zerr:ZAPI0028",type:"item()*",description:""},{name:"zerr:ZAPI0029",type:"item()*",description:""},{name:"zerr:ZAPI0030",type:"item()*",description:""},{name:"zerr:ZAPI0039",type:"item()*",description:""},{name:"zerr:ZAPI0040",type:"item()*",description:""},{name:"zerr:ZAPI0041",type:"item()*",description:""},{name:"zerr:ZAPI0042",type:"item()*",description:""},{name:"zerr:ZAPI0043",type:"item()*",description:""},{name:"zerr:NS",type:"item()*",description:""},{name:"zerr:ZAPI0070",type:"item()*",description:""},{name:"zerr:ZAPI0080",type:"item()*",description:""},{name:"zerr:ZAPI0090",type:"item()*",description:""},{name:"zerr:ZCSE0001",type:"item()*",description:""},{name:"zerr:ZCSE0002",type:"item()*",description:""},{name:"zerr:ZCSE0003",type:"item()*",description:""},{name:"zerr:ZCSE0004",type:"item()*",description:""},{name:"zerr:ZCSE0005",type:"item()*",description:""},{name:"zerr:ZCSE0006",type:"item()*",description:""},{name:"zerr:ZCSE0007",type:"item()*",description:""},{name:"zerr:ZCSE0008",type:"item()*",description:""},{name:"zerr:ZCSE0009",type:"item()*",description:""},{name:"zerr:ZCSE0010",type:"item()*",description:""}]},"http://zorba.io/modules/sequence":{ns:"http://zorba.io/modules/sequence",description:" This module provides an XQuery API to perform set operations on sequences.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Paul J. Lucas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/sequence",prefix:"seq"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"value-except",qname:"seq:value-except",signature:"($seq1 as xs:anyAtomicType*, $seq2 as xs:anyAtomicType*) as xs:anyAtomicType* external",description:" Filters the first sequence of atomic items such that they are not in the\n second sequence based on their values.\n",summary:"<p> Filters the first sequence of atomic items such that they are not in the\n second sequence based on their values.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first sequence.</div>'},{name:"seq2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second sequence.</div>'}],returns:{type:"xs:anyAtomicType*",description:'a sequence only containing items from <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$seq1</code> that are not in <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$seq2</code>.'},errors:[]},{isDocumented:!0,arity:2,name:"value-intersect",qname:"seq:value-intersect",signature:"($seq1 as xs:anyAtomicType*, $seq2 as xs:anyAtomicType*) as xs:anyAtomicType* external",description:" Performs a set intersection of two sequences of atomic items based on their\n values.\n",summary:"<p> Performs a set intersection of two sequences of atomic items based on their\n values.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first sequence.</div>'},{name:"seq2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second sequence.</div>'}],returns:{type:"xs:anyAtomicType*",description:'a sequence containing only items from <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$seq1</code> that are also in <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$seq2</code>.'},errors:[]},{isDocumented:!0,arity:2,name:"value-union",qname:"seq:value-union",signature:"($seq1 as xs:anyAtomicType*, $seq2 as xs:anyAtomicType*) as xs:anyAtomicType* external",description:" Performs a set union of two sequences of atomic items based on their values.\n",summary:"<p> Performs a set union of two sequences of atomic items based on their values.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first sequence.</div>'},{name:"seq2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second sequence.</div>'}],returns:{type:"xs:anyAtomicType*",description:'a sequence containing all items from <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$seq1</code> and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">seq2$</code> but without duplicates.'},errors:[]}],variables:[]},"http://api.28.io/functions":{ns:"http://api.28.io/functions",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/functions",prefix:"functions"},{uri:"http://api.28.io/model",prefix:"model"},{uri:"http://www.zorba-xquery.com/schemas/pul",prefix:"pul"},{uri:"http://zorba.io/modules/reference",prefix:"ref"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://www.28msec.com/modules/http/response",prefix:"response"},{uri:"http://api.28.io/sandbox",prefix:"sandbox"},{uri:"http://www.zorba-xquery.com/schemas/xdm",prefix:"xdm"}],functions:[{isDocumented:!1,arity:1,name:"apply-pul",qname:"functions:apply-pul",signature:"($pul)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"pul",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"collections",qname:"functions:collections",signature:"()",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"decodeURI",qname:"functions:decodeURI",signature:"($str as xs:string) as xs:anyURI",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"str",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:anyURI",description:""},errors:[]},{isDocumented:!1,arity:1,name:"encode-for-js",qname:"functions:encode-for-js",signature:"($str as xs:string) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"str",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:5,name:"entries",qname:"functions:entries",signature:"($collection as xs:string?, $node as xs:anyURI?, $index as xs:string?, $value as xs:string?, $format as xs:string)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"collection",type:"xs:string",occurrence:"?",description:""},{name:"node",type:"xs:anyURI",occurrence:"?",description:""},{name:"index",type:"xs:string",occurrence:"?",description:""},{name:"value",type:"xs:string",occurrence:"?",description:""},{name:"format",type:"xs:string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"indexes",qname:"functions:indexes",signature:"()",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"key",qname:"functions:key",signature:"($collection as xs:string, $condition as xs:string, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"collection",type:"xs:string",occurrence:null,description:""},{name:"condition",type:"xs:string",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"namesearch",qname:"functions:namesearch",signature:"($collection as xs:string, $path as xs:string, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"collection",type:"xs:string",occurrence:null,description:""},{name:"path",type:"xs:string",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"node-to-js",qname:"functions:node-to-js",signature:"($node) as xs:string*",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:null,occurrence:null,description:""}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!1,arity:1,name:"parse-namespaces",qname:"functions:parse-namespaces",signature:"($namespaces as xs:string)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"namespaces",type:"xs:string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"pksearch",qname:"functions:pksearch",signature:"($collection as xs:string)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"collection",type:"xs:string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"startpage",qname:"functions:startpage",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"strip-whitespaces",qname:"functions:strip-whitespaces",signature:"($xml)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xml",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"tuple",qname:"functions:tuple",signature:"($collection as xs:string, $condition as xs:string, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"collection",type:"xs:string",occurrence:null,description:""},{name:"condition",type:"xs:string",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"valuesearch",qname:"functions:valuesearch",signature:"($collection as xs:string, $path as xs:string, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"collection",type:"xs:string",occurrence:null,description:""},{name:"path",type:"xs:string",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!0,arity:1,name:"xmltojs",qname:"functions:xmltojs",signature:"($content)",description:" Internal function. Converts the XML contents of a POST BODY to JavaScript calls that rebuild the given XML for the collection browser frontend\n",summary:"<p> Internal function.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"content",type:null,occurrence:null,description:""}],returns:{type:null,description:"JavaScript calls for collection browser frontend"},errors:[]}],variables:[]},"http://xbrl.io/modules/bizql/profiles/sec/companies":{ns:"http://xbrl.io/modules/bizql/profiles/sec/companies",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for querying companies (XBRL entities)\n  submitting to the SEC.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC Companies are nothing else than XBRL entities. For XBRL-generic requests on\n entities, use the generic entities module.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve a company with its CIK (without converting\n it to an EID). You can also retrieve companies by sector, by SIC code, by types,\n by tags, by tickers.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/companies",prefix:"companies"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/entities",prefix:"entities"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/core",prefix:"sec"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"companies-by-types",qname:"companies:companies-by-types",signature:"($company-types as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all companies whose company type matches the passed string(s).</p>\n',summary:"<p>  Retrieves all companies whose company type matches the passed string(s).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"company-types",type:"string",occurrence:"*",description:""}],returns:{type:"object()*",description:"all companies with matching company type."},errors:[]},{isDocumented:!0,arity:1,name:"companies-for-SIC",qname:"companies:companies-for-SIC",signature:"($sic-codes as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all companies whose type of business\n matches the SIC (Standard Industrial Classification) code.</p>\n',summary:"<p>  Retrieves all companies whose type of business\n matches the SIC (Standard Industrial Classification) code.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sic-codes",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of SIC codes.</div>'}],returns:{type:"object()*",description:"all companies with one of these SIC codes."},errors:[]},{isDocumented:!0,arity:1,name:"companies-for-sector",qname:"companies:companies-for-sector",signature:"($sectors as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all companies in the given sectors.</p>\n',summary:"<p>  Retrieves all companies in the given sectors.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sectors",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of sectors as strings.</div>'}],returns:{type:"object()*",description:"all companies in these sectors."},errors:[]},{isDocumented:!0,arity:1,name:"companies-for-tags",qname:"companies:companies-for-tags",signature:"($tags as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all companies with any of the given tags.</p>\n',summary:"<p>  Return all companies with any of the given tags.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"tags",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the tags to filter.</div>'}],returns:{type:"object()*",description:"all companies with the given tags."},errors:[]},{isDocumented:!0,arity:1,name:"companies-for-tickers",qname:"companies:companies-for-tickers",signature:"($tickers as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all companies with any of the given ticker symbols.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Tickers are case insensitive</p>\n',summary:"<p>  Return all companies with any of the given ticker symbols.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"tickers",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the tickers to filter.</div>'}],returns:{type:"object()*",description:"all companies with the given tickers."},errors:[]},{isDocumented:!0,arity:0,name:"companies",qname:"companies:companies",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all companies</p>\n',summary:"<p>  Return all companies \n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"all companies."},errors:[]},{isDocumented:!0,arity:1,name:"companies",qname:"companies:companies",signature:"($companies-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the companies with the given identifiers.</p>\n',summary:"<p>  Return the companies with the given identifiers.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"companies-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the ids of the companies or the companies themselves.</div>'}],returns:{type:"object()*",description:"the companies with the given identifiers the empty sequence if no company was found or if the input is an empty sequence."},errors:[]},{isDocumented:!0,arity:1,name:"company-type",qname:"companies:company-type",signature:"($company-name as string) as string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return company type for a given company name. Company type can be one of:</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n     <li>Corporation</li>\n     <li>Partnership</li>\n     <li>unknown</li>\n   </ul>\n </p>\n',summary:"<p>  Return company type for a given company name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"company-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of a company</div>'}],returns:{type:"string",description:'the company type string or "unknown" if the type can not be inferred'},errors:[]},{isDocumented:!0,arity:1,name:"eid",qname:"companies:eid",signature:"($companies-or-eids-or-ciks as item()*) as string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts the input to a normalized CIK. The input\n can be either a pure CIK without scheme, or an already\n normalized CIK, or an entity object which contains a CIK\n in its id field.</p>\n',summary:"<p>  Converts the input to a normalized CIK.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"companies-or-eids-or-ciks",type:"item()",occurrence:"*",description:""}],returns:{type:"string*",description:"the normalized CIK."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sec:INVALID_PARAMETER if the CIK or entity is not valid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"types",qname:"companies:types",signature:"($companies-or-ciks as item()*) as string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the type of a company.</p>\n',summary:"<p>  Retrieves the type of a company.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"companies-or-ciks",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of companies or their identifiers (CIKs).</div>'}],returns:{type:"string*",description:"all company types."},errors:[]}],variables:[]},"http://api.28.io/collections":{ns:"http://api.28.io/collections",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/collections",prefix:"cm"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://www.28msec.com/modules/http/response",prefix:"resp"},{uri:"http://api.28.io/util",prefix:"util"},{uri:"http://api.28.io/validation",prefix:"validate"}],functions:[{isDocumented:!1,arity:1,name:"definition-for-dynamic-collection",qname:"cm:definition-for-dynamic-collection",signature:"($name as xs:string) as object()",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""}],returns:{type:"object()",description:""},errors:[]},{isDocumented:!1,arity:2,name:"delete-collection-property",qname:"cm:delete-collection-property",signature:"($name as xs:string, $property as xs:string) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""},{name:"property",type:"xs:string",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]},{isDocumented:!1,arity:1,name:"delete-collection",qname:"cm:delete-collection",signature:"($name) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:null,occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]},{isDocumented:!1,arity:0,name:"dispatch",qname:"cm:dispatch",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"get-collection-property",qname:"cm:get-collection-property",signature:"($name as xs:string, $property as xs:string)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""},{name:"property",type:"xs:string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"get-collection",qname:"cm:get-collection",signature:"($name as xs:string) as object()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""}],returns:{type:"object()",description:""},errors:[]},{isDocumented:!1,arity:1,name:"get-or-create-collection-dynamic",qname:"cm:get-or-create-collection-dynamic",signature:"($name as xs:string) as object()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""}],returns:{type:"object()",description:""},errors:[]},{isDocumented:!1,arity:0,name:"list-collections",qname:"cm:list-collections",signature:"() as array()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"array()",description:""},errors:[]},{isDocumented:!1,arity:0,name:"metadata",qname:"cm:metadata",signature:"()",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"put-collection-property",qname:"cm:put-collection-property",signature:"($name as xs:string, $property as xs:string, $value) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""},{name:"property",type:"xs:string",occurrence:null,description:""},{name:"value",type:null,occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]},{isDocumented:!1,arity:2,name:"put-collection",qname:"cm:put-collection",signature:"($name as xs:string, $collection as object()) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""},{name:"collection",type:"object()",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]},{isDocumented:!1,arity:1,name:"validate-collection",qname:"cm:validate-collection",signature:"($collection as object()) as empty-sequence()",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"collection",type:"object()",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]}],variables:[]},"http://zorba.io/modules/excel/math-sumproduct":{ns:"http://zorba.io/modules/excel/math-sumproduct",description:" Module implementing the sumproduct functions from Excel 2003 math library.\n There are 30 functions defined, implementing the same function\n but with 1 to 30 parameters.\n Each parameter can be a sequence of infinite length.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://office.microsoft.com/en-us/excel/HP052092931033.aspx" target="_blank">Excel 2003 Documentation: Math-sumproduct Functions</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Turcanu</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/math-sumproduct",prefix:"excel"},{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/modules/excel/math",prefix:"excel-math"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Sums the values in the sequence.\n The sequence can be of any length.\n",summary:"<p> Sums the values in the sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:10,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:11,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:12,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:13,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:14,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:15,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:16,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:17,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:18,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:19,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:2,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:20,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:21,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:22,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*, $array22 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:23,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*, $array22 as xs:anyAtomicType*, $array23 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array23",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:24,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*, $array22 as xs:anyAtomicType*, $array23 as xs:anyAtomicType*, $array24 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array23",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array24",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:25,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*, $array22 as xs:anyAtomicType*, $array23 as xs:anyAtomicType*, $array24 as xs:anyAtomicType*, $array25 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array23",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array24",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array25",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:26,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*, $array22 as xs:anyAtomicType*, $array23 as xs:anyAtomicType*, $array24 as xs:anyAtomicType*, $array25 as xs:anyAtomicType*, $array26 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array23",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array24",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array25",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array26",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:27,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*, $array22 as xs:anyAtomicType*, $array23 as xs:anyAtomicType*, $array24 as xs:anyAtomicType*, $array25 as xs:anyAtomicType*, $array26 as xs:anyAtomicType*, $array27 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array23",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array24",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array25",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array26",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array27",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:28,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*, $array22 as xs:anyAtomicType*, $array23 as xs:anyAtomicType*, $array24 as xs:anyAtomicType*, $array25 as xs:anyAtomicType*, $array26 as xs:anyAtomicType*, $array27 as xs:anyAtomicType*, $array28 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array23",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array24",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array25",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array26",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array27",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array28",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:29,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*, $array22 as xs:anyAtomicType*, $array23 as xs:anyAtomicType*, $array24 as xs:anyAtomicType*, $array25 as xs:anyAtomicType*, $array26 as xs:anyAtomicType*, $array27 as xs:anyAtomicType*, $array28 as xs:anyAtomicType*, $array29 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array23",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array24",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array25",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array26",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array27",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array28",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array29",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:3,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:30,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*, $array10 as xs:anyAtomicType*, $array11 as xs:anyAtomicType*, $array12 as xs:anyAtomicType*, $array13 as xs:anyAtomicType*, $array14 as xs:anyAtomicType*, $array15 as xs:anyAtomicType*, $array16 as xs:anyAtomicType*, $array17 as xs:anyAtomicType*, $array18 as xs:anyAtomicType*, $array19 as xs:anyAtomicType*, $array20 as xs:anyAtomicType*, $array21 as xs:anyAtomicType*, $array22 as xs:anyAtomicType*, $array23 as xs:anyAtomicType*, $array24 as xs:anyAtomicType*, $array25 as xs:anyAtomicType*, $array26 as xs:anyAtomicType*, $array27 as xs:anyAtomicType*, $array28 as xs:anyAtomicType*, $array29 as xs:anyAtomicType*, $array30 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array10",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array11",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array12",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array13",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array14",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array15",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array16",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array17",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array18",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array19",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array20",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array21",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array22",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array23",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array24",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array25",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array26",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array27",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array28",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array29",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array30",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:4,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:5,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:6,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:7,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:8,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:9,name:"sumproduct",qname:"excel:sumproduct",signature:"($array1 as xs:anyAtomicType*, $array2 as xs:anyAtomicType*, $array3 as xs:anyAtomicType*, $array4 as xs:anyAtomicType*, $array5 as xs:anyAtomicType*, $array6 as xs:anyAtomicType*, $array7 as xs:anyAtomicType*, $array8 as xs:anyAtomicType*, $array9 as xs:anyAtomicType*) as xs:anyAtomicType",description:" Multiplies the elements on the same position in each sequence\n and sums up the results.\n",summary:"<p> Multiplies the elements on the same position in each sequence\n and sums up the results.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"array1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array3",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array4",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array5",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array6",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array7",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array8",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'},{name:"array9",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequences of numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of products"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"sumsq",qname:"excel:sumsq",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:" Returns the sum of the squares of the arguments.\n It used the sumproduct function.\n",summary:"<p> Returns the sum of the squares of the arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of one or more numbers or arguments castable to numeric</div>'}],returns:{type:"xs:anyAtomicType",description:"the sum of squared values, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/item":{ns:"http://zorba.io/modules/item",description:" This module provides utility functions on items. For example,\n it provides a function that allows estimating the size in bytes\n that a given item allocates in memory.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/item",prefix:"item"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"size",qname:"item:size",signature:"($item as item()) as xs:integer external",description:' Computes the size in bytes of the given item in main memory.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Computes the size in bytes of the given item in main memory.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"item",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the item whose size to compute.</div>'}],returns:{type:"xs:integer",description:"the size allocated by the item in bytes."},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/xqdoc/menu":{ns:"http://www.zorba-xquery.com/modules/xqdoc/menu",description:" Generate navigation for XQDoc batches.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">William Candillon</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/xqdoc/menu",prefix:"menu"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!1,arity:2,name:"categories-as-js",qname:"menu:categories-as-js",signature:"($url-prefix as xs:string, $cats as element(*)) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"url-prefix",type:"xs:string",occurrence:null,description:""},{name:"cats",type:"element(*)",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:1,name:"categories",qname:"menu:categories",signature:"($top as element(*)) as xs:string*",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"top",type:"element(*)",occurrence:null,description:""}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!1,arity:2,name:"closed-tabs",qname:"menu:closed-tabs",signature:"($item as element(section), $url-prefix as xs:string) as element(li)*",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"item",type:"element(section)",occurrence:null,description:""},{name:"url-prefix",type:"xs:string",occurrence:null,description:""}],returns:{type:"element(li)*",description:""},errors:[]},{isDocumented:!1,arity:3,name:"closed-tabs",qname:"menu:closed-tabs",signature:"($item as element(*)?, $result as element(*)*, $url-prefix as xs:string) as element(li)*",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"item",type:"element(*)",occurrence:"?",description:""},{name:"result",type:"element(*)",occurrence:"*",description:""},{name:"url-prefix",type:"xs:string",occurrence:null,description:""}],returns:{type:"element(li)*",description:""},errors:[]},{isDocumented:!1,arity:1,name:"item-uri",qname:"menu:item-uri",signature:"($item as element(*)) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"item",type:"element(*)",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:2,name:"item-uri",qname:"menu:item-uri",signature:"($item as element(*)?, $result as xs:string*) as xs:string+",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"item",type:"element(*)",occurrence:"?",description:""},{name:"result",type:"xs:string",occurrence:"*",description:""}],returns:{type:"xs:string+",description:""},errors:[]},{isDocumented:!1,arity:2,name:"item",qname:"menu:item",signature:"($ctx as element(*)?, $path as xs:string*) as element(*)?",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"ctx",type:"element(*)",occurrence:"?",description:""},{name:"path",type:"xs:string",occurrence:"*",description:""}],returns:{type:"element(*)?",description:""},errors:[]},{isDocumented:!1,arity:2,name:"menu",qname:"menu:menu",signature:"($item as element(*), $url-prefix as xs:string)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"item",type:"element(*)",occurrence:null,description:""},{name:"url-prefix",type:"xs:string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]}],variables:[{name:"menu:not-found",type:"item()*",description:""}]},"http://zorba.io/modules/dbgp-message-handler":{ns:"http://zorba.io/modules/dbgp-message-handler",description:" Zorba debugger module.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Gabriel Petrovay</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/base64",prefix:"base64"},{uri:"http://zorba.io/modules/dbgp-message-handler",prefix:"dmh"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"process",qname:"dmh:process",signature:"($message as element(*)) as xs:anyAtomicType*",description:" Process one message received from the Zorba debugger server.\n",summary:"<p> Process one message received from the Zorba debugger server.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"message",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the message.</div>'}],returns:{type:"xs:anyAtomicType*",description:"()."},errors:[]}],variables:[{name:"dmh:debug",type:"xs:boolean",description:" Set this variale to true if you want to have mode debug information when\n an error occurs.\n"}]},"http://www.28msec.com/modules/ws/mailchimp":{ns:"http://www.28msec.com/modules/ws/mailchimp",description:" Mailchimp Client Module.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://apidocs.mailchimp.com" target="_blank">http://apidocs.mailchimp.com</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">William Candillon {william.candillon@28msec.com}</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://expath.org/ns/http-client",prefix:"http-client"},{uri:"http://www.28msec.com/modules/ws/mailchimp",prefix:"mailchimp"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://www.28msec.com/modules/xmlrpc",prefix:"xmlrpc"}],functions:[{isDocumented:!0,arity:3,name:"apikey-add",qname:"mailchimp:apikey-add",signature:"($username as xs:string, $password as xs:string, $apikey as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#apikey-add-4">apikey-add#4</a>.\n',summary:"<p> Convenience function for  apikey-add#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"username",type:"xs:string",occurrence:null,description:""},{name:"password",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your MailChimp password</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Any valid API Key</div>'}],returns:{type:"item()*",description:"A new API Key that can be immediately used."},errors:[]},{isDocumented:!0,arity:4,name:"apikey-add",qname:"mailchimp:apikey-add",signature:"($endpoint-url as xs:string, $username as xs:string, $password as xs:string, $apikey as xs:string) as item()*",description:" Add an API Key to your account. We will generate a new key for you and return it.\n",summary:"<p> Add an API Key to your account.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"username",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your MailChimp user name</div>'},{name:"password",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your MailChimp password</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Any valid API Key</div>'}],returns:{type:"item()*",description:"A new API Key that can be immediately used."},errors:[]},{isDocumented:!0,arity:3,name:"apikey-expire",qname:"mailchimp:apikey-expire",signature:"($username as xs:string, $password as xs:string, $apikey as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#apikey-expire-4">apikey-expire#4</a>.\n',summary:"<p> Convenience function for  apikey-expire#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"username",type:"xs:string",occurrence:null,description:""},{name:"password",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your MailChimp password</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Any valid API Key that you wish to expire</div>'}],returns:{type:"item()*",description:"True if it worked, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:4,name:"apikey-expire",qname:"mailchimp:apikey-expire",signature:"($endpoint-url as xs:string, $username as xs:string, $password as xs:string, $apikey as xs:string) as item()*",description:' Expire a Specific API Key. Note that if you expire all of your keys, just visit <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a> to create a new one. If you are trying to shut off access to your account for an old developer, change your MailChimp password, then expire all of the keys they had access to. Note that this takes effect immediately, so make sure you replace the keys in any working application before expiring them! Consider yourself warned...\n',summary:"<p> Expire a Specific API Key.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"username",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your MailChimp user name</div>'},{name:"password",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your MailChimp password</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Any valid API Key that you wish to expire</div>'}],returns:{type:"item()*",description:"True if it worked, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:4,name:"apikeys",qname:"mailchimp:apikeys",signature:"($username as xs:string, $password as xs:string, $apikey as xs:string, $expired as xs:boolean) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#apikeys-5">apikeys#5</a>.\n',summary:"<p> Convenience function for  apikeys#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"username",type:"xs:string",occurrence:null,description:""},{name:"password",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your MailChimp password</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Any valid API Key for your account</div>'},{name:"expired",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - whether or not to include expired keys, defaults to false</div>'}],returns:{type:"item()*",description:"An array of API keys."},errors:[]},{isDocumented:!0,arity:5,name:"apikeys",qname:"mailchimp:apikeys",signature:"($endpoint-url as xs:string, $username as xs:string, $password as xs:string, $apikey as xs:string, $expired as xs:boolean) as item()*",description:" Retrieve a list of all MailChimp API Keys for this User.\n",summary:"<p> Retrieve a list of all MailChimp API Keys for this User.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"username",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your MailChimp user name</div>'},{name:"password",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your MailChimp password</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Any valid API Key for your account</div>'},{name:"expired",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - whether or not to include expired keys, defaults to false</div>'}],returns:{type:"item()*",description:"An array of API keys."},errors:[]},{isDocumented:!0,arity:5,name:"campaign-abuse-reports",qname:"mailchimp:campaign-abuse-reports",signature:"($apikey as xs:string, $cid as xs:string, $since as xs:integer, $start as xs:integer, $limit as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-abuse-reports-6">campaign-abuse-reports#6</a>.\n',summary:"<p> Convenience function for  campaign-abuse-reports#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull abuse reports for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"since",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 500, upper limit set at 1000</div>'},{name:"limit",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"Reports the abuse reports for this campaign"},errors:[]},{isDocumented:!0,arity:6,name:"campaign-abuse-reports",qname:"mailchimp:campaign-abuse-reports",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $since as xs:integer, $start as xs:integer, $limit as xs:string) as item()*",description:" Get all email addresses that complained about a given campaign.\n",summary:"<p> Get all email addresses that complained about a given campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull abuse reports for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"since",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 500, upper limit set at 1000</div>'},{name:"limit",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"Reports the abuse reports for this campaign"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-advice",qname:"mailchimp:campaign-advice",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-advice-3">campaign-advice#3</a>.\n',summary:"<p> Convenience function for  campaign-advice#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull advice text for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Advice on the campaign's performance"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-advice",qname:"mailchimp:campaign-advice",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Retrieve the text presented in our app for how a campaign performed and any advice we may have for you - best suited for display in customized reports pages.\n Note: some messages will contain HTML - clean tags as necessary.\n",summary:"<p> Retrieve the text presented in our app for how a campaign performed and any advice we may have for you - best suited for display in customized reports pages.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull advice text for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Advice on the campaign's performance"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-analytics",qname:"mailchimp:campaign-analytics",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-analytics-3">campaign-analytics#3</a>.\n',summary:"<p> Convenience function for  campaign-analytics#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Analytics we've collected for the passed campaign."},errors:[]},{isDocumented:!0,arity:3,name:"campaign-analytics",qname:"mailchimp:campaign-analytics",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Retrieve the Google Analytics data we've collected for this campaign. Note, requires Google Analytics Add-on to be installed and configured.\n",summary:"<p> Retrieve the Google Analytics data we've collected for this campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Analytics we've collected for the passed campaign."},errors:[]},{isDocumented:!0,arity:3,name:"campaign-bounce-message",qname:"mailchimp:campaign-bounce-message",signature:"($apikey as xs:string, $cid as xs:string, $email as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-bounce-message-4">campaign-bounce-message#4</a>.\n',summary:"<p> Convenience function for  campaign-bounce-message#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"email",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address or unique id of the member to pull a bounce message for.</div>'}],returns:{type:"item()*",description:"The full bounce message for this email+campaign along with some extra data."},errors:[]},{isDocumented:!0,arity:4,name:"campaign-bounce-message",qname:"mailchimp:campaign-bounce-message",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $email as xs:string) as item()*",description:" Retrieve the most recent full bounce message for a specific email address on the given campaign. Messages over 30 days old are subject to being removed.\n",summary:"<p> Retrieve the most recent full bounce message for a specific email address on the given campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"email",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address or unique id of the member to pull a bounce message for.</div>'}],returns:{type:"item()*",description:"The full bounce message for this email+campaign along with some extra data."},errors:[]},{isDocumented:!0,arity:5,name:"campaign-bounce-messages",qname:"mailchimp:campaign-bounce-messages",signature:"($apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer, $since as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-bounce-messages-6">campaign-bounce-messages#6</a>.\n',summary:"<p> Convenience function for  campaign-bounce-messages#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 25, upper limit set at 50</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD format in <strong>GMT</strong> (we only store the date, not the time)</div>'}],returns:{type:"item()*",description:"Bounces the full bounce messages for this campaign"},errors:[]},{isDocumented:!0,arity:6,name:"campaign-bounce-messages",qname:"mailchimp:campaign-bounce-messages",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer, $since as xs:string) as item()*",description:" Retrieve the full bounce messages for the given campaign. Note that this can return very large amounts of data depending on how large the campaign was and how much cruft the bounce provider returned.\n",summary:"<p> Retrieve the full bounce messages for the given campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 25, upper limit set at 50</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD format in <strong>GMT</strong> (we only store the date, not the time)</div>'}],returns:{type:"item()*",description:"Bounces the full bounce messages for this campaign"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-click-detail-AIM",qname:"mailchimp:campaign-click-detail-AIM",signature:"($apikey as xs:string, $cid as xs:string, $url as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-click-detail-AIM-6">campaign-click-detail-AIM#6</a>.\n',summary:"<p> Convenience function for  campaign-click-detail-AIM#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get click stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URL of the link that was clicked on</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"Array containing the total records matched and the specific records for this page"},errors:[]},{isDocumented:!0,arity:6,name:"campaign-click-detail-AIM",qname:"mailchimp:campaign-click-detail-AIM",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $url as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:" Return the list of email addresses that clicked on a given url, and how many times they clicked.\n",summary:"<p> Return the list of email addresses that clicked on a given url, and how many times they clicked.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get click stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URL of the link that was clicked on</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"Array containing the total records matched and the specific records for this page"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-click-stats",qname:"mailchimp:campaign-click-stats",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-click-stats-3">campaign-click-stats#3</a>.\n',summary:"<p> Convenience function for  campaign-click-stats#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"URLs will be keys and contain their associated statistics: clicks (number of times a specific link was clicked) and unique (number of unique people who clicked on the specific link)."},errors:[]},{isDocumented:!0,arity:3,name:"campaign-click-stats",qname:"mailchimp:campaign-click-stats",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Get an array of the urls being tracked, and their click counts for a given campaign.\n",summary:"<p> Get an array of the urls being tracked, and their click counts for a given campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"URLs will be keys and contain their associated statistics: clicks (number of times a specific link was clicked) and unique (number of unique people who clicked on the specific link)."},errors:[]},{isDocumented:!0,arity:3,name:"campaign-content",qname:"mailchimp:campaign-content",signature:"($apikey as xs:string, $cid as xs:string, $for_archive as xs:boolean) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-content-4">campaign-content#4</a>.\n',summary:"<p> Convenience function for  campaign-content#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get content for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"for_archive",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional controls whether we return the Archive version (true) or the Raw version (false), defaults to true</div>'}],returns:{type:"item()*",description:"Struct containing all content for the campaign"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-content",qname:"mailchimp:campaign-content",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $for_archive as xs:boolean) as item()*",description:" Get the content (both html and text) for a campaign either as it would appear in the campaign archive or as the raw, original content.\n",summary:"<p> Get the content (both html and text) for a campaign either as it would appear in the campaign archive or as the raw, original content.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get content for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"for_archive",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional controls whether we return the Archive version (true) or the Raw version (false), defaults to true</div>'}],returns:{type:"item()*",description:"Struct containing all content for the campaign"},errors:[]},{isDocumented:!0,arity:6,name:"campaign-create",qname:"mailchimp:campaign-create",signature:"($apikey as xs:string, $type as xs:string, $options as element(array), $content as element(array), $segment_opts as element(array), $type_opts as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-create-7">campaign-create#7</a>.\n',summary:"<p> Convenience function for  campaign-create#7 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the Campaign Type to create - one of "regular", "plaintext", "absplit", "rss", "trans", "auto"</div>'},{name:"options",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hash of the standard options for this campaign. See <a href="http://apidocs.mailchimp.com/rtfm/campaigncreate.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"content",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content for this campaign - use a struct with the following keys. See <a href="http://apidocs.mailchimp.com/rtfm/campaigncreate.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"segment_opts",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - if you wish to do Segmentation with this campaign this array should contain: see <a href="#campaign-segment-test-3">campaign-segment-test()</a>. It\'s suggested that you test your options against <a href="#campaign-segment-test-3">campaign-segment-test()</a>. Also, "trans" campaigns <strong>do not</strong> support segmentation.</div>'},{name:"type_opts",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional -</div>'}],returns:{type:"item()*",description:"The ID for the created campaign"},errors:[]},{isDocumented:!0,arity:7,name:"campaign-create",qname:"mailchimp:campaign-create",signature:"($endpoint-url as xs:string, $apikey as xs:string, $type as xs:string, $options as element(array), $content as element(array), $segment_opts as element(array), $type_opts as element(array)) as item()*",description:" Create a new draft campaign to send. You can not have more than 32,000 campaigns in your account.\n",summary:"<p> Create a new draft campaign to send.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the Campaign Type to create - one of "regular", "plaintext", "absplit", "rss", "trans", "auto"</div>'},{name:"options",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hash of the standard options for this campaign. See <a href="http://apidocs.mailchimp.com/rtfm/campaigncreate.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"content",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content for this campaign - use a struct with the following keys. See <a href="http://apidocs.mailchimp.com/rtfm/campaigncreate.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"segment_opts",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - if you wish to do Segmentation with this campaign this array should contain: see <a href="#campaign-segment-test-3"><a href="#campaign-segment-test-3">campaign-segment-test()</a></a>. It\'s suggested that you test your options against <a href="#campaign-segment-test-3">campaign-segment-test()</a>. Also, "trans" campaigns <strong>do not</strong> support segmentation.</div>'},{name:"type_opts",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional</div>'}],returns:{type:"item()*",description:"The ID for the created campaign"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-delete",qname:"mailchimp:campaign-delete",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-delete-3">campaign-delete#3</a>.\n',summary:"<p> Convenience function for  campaign-delete#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the Campaign Id to delete</div>'}],returns:{type:"item()*",description:"True if the delete succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-delete",qname:"mailchimp:campaign-delete",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:' Delete a campaign. Seriously, "poof, gone!" - be careful!.\n',summary:"<p> Delete a campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the Campaign Id to delete</div>'}],returns:{type:"item()*",description:"True if the delete succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-ecomm-order-add",qname:"mailchimp:campaign-ecomm-order-add",signature:"($apikey as xs:string, $order as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-ecomm-order-add-3">campaign-ecomm-order-add#3</a>.\n',summary:"<p> Convenience function for  campaign-ecomm-order-add#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"order",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of information pertaining to the order that has completed. Use the following keys. See <a href="http://apidocs.mailchimp.com/rtfm/campaignecommorderadd.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'}],returns:{type:"item()*",description:"True if the data is saved, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:3,name:"campaign-ecomm-order-add",qname:"mailchimp:campaign-ecomm-order-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $order as element(array)) as item()*",description:" Attach Ecommerce Order Information to a Campaign.\n",summary:"<p> Attach Ecommerce Order Information to a Campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"order",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of information pertaining to the order that has completed. Use the following keys. See <a href="http://apidocs.mailchimp.com/rtfm/campaignecommorderadd.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'}],returns:{type:"item()*",description:"True if the data is saved, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:5,name:"campaign-ecomm-orders",qname:"mailchimp:campaign-ecomm-orders",signature:"($apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer, $since as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-ecomm-orders-6">campaign-ecomm-orders#6</a>.\n',summary:"<p> Convenience function for  campaign-ecomm-orders#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 100, upper limit set at 500</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"The total matching orders and the specific orders for the requested page"},errors:[]},{isDocumented:!0,arity:6,name:"campaign-ecomm-orders",qname:"mailchimp:campaign-ecomm-orders",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer, $since as xs:string) as item()*",description:' Retrieve the Ecommerce Orders tracked by <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-ecomm-order-add-2">campaign-ecomm-order-add()</a>.\n',summary:"<p> Retrieve the Ecommerce Orders tracked by  campaign-ecomm-order-add() .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 100, upper limit set at 500</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"The total matching orders and the specific orders for the requested page"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-eep-url-stats",qname:"mailchimp:campaign-eep-url-stats",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-eep-url-stats-3">campaign-eep-url-stats#3</a>.\n',summary:"<p> Convenience function for  campaign-eep-url-stats#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Stats an array containing tweets, retweets, clicks, and referrer related to using the campaign's eepurl"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-eep-url-stats",qname:"mailchimp:campaign-eep-url-stats",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Retrieve the tracked eepurl mentions on Twitter.\n",summary:"<p> Retrieve the tracked eepurl mentions on Twitter.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Stats an array containing tweets, retweets, clicks, and referrer related to using the campaign's eepurl"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-email-domain-performance",qname:"mailchimp:campaign-email-domain-performance",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-email-domain-performance-3">campaign-email-domain-performance#3</a>.\n',summary:"<p> Convenience function for  campaign-email-domain-performance#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull email domain performance for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Domains email domains and their associated stats"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-email-domain-performance",qname:"mailchimp:campaign-email-domain-performance",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:' Get the top 5 performing email domains for this campaign. Users want more than 5 should use campaign <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-email-stats-AIM-3">campaign-email-stats-AIM()</a> or <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-email-stats-AIM-all-4">campaign-email-stats-AIM-all()</a> and generate any additional stats they require.\n',summary:"<p> Get the top 5 performing email domains for this campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull email domain performance for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Domains email domains and their associated stats"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-email-stats-AIM-all",qname:"mailchimp:campaign-email-stats-AIM-all",signature:"($apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-email-stats-AIM-all-5">campaign-email-stats-AIM-all#5</a>.\n',summary:"<p> Convenience function for  campaign-email-stats-AIM-all#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 100, upper limit set at 1000</div>'}],returns:{type:"item()*",description:"Array containing a total record count and data including the actions (opens and clicks) for each email, with timestamps"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-email-stats-AIM-all",qname:"mailchimp:campaign-email-stats-AIM-all",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:" Given a campaign and correct paging limits, return the entire click and open history with timestamps, ordered by time, for every user a campaign was delivered to.\n",summary:"<p> Given a campaign and correct paging limits, return the entire click and open history with timestamps, ordered by time, for every user a campaign was delivered to.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 100, upper limit set at 1000</div>'}],returns:{type:"item()*",description:"Array containing a total record count and data including the actions (opens and clicks) for each email, with timestamps"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-email-stats-AIM",qname:"mailchimp:campaign-email-stats-AIM",signature:"($apikey as xs:string, $cid as xs:string, $email_address as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-email-stats-AIM-4">campaign-email-stats-AIM#4</a>.\n',summary:"<p> Convenience function for  campaign-email-stats-AIM#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"email_address",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of up to 50 email addresses to check OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns. For backwards compatibility, if a string is passed, it will be treated as an array with a single element (will not work with XML-RPC).</div>'}],returns:{type:"item()*",description:"Array an array with the keys listed in Returned Fields below"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-email-stats-AIM",qname:"mailchimp:campaign-email-stats-AIM",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $email_address as element(array)) as item()*",description:" Given a campaign and email address, return the entire click and open history with timestamps, ordered by time.\n",summary:"<p> Given a campaign and email address, return the entire click and open history with timestamps, ordered by time.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"email_address",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of up to 50 email addresses to check OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns. For backwards compatibility, if a string is passed, it will be treated as an array with a single element (will not work with XML-RPC).</div>'}],returns:{type:"item()*",description:"Array an array with the keys listed in Returned Fields below"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-geo-opens-for-country",qname:"mailchimp:campaign-geo-opens-for-country",signature:"($apikey as xs:string, $cid as xs:string, $code as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-geo-opens-for-country-4">campaign-geo-opens-for-country#4</a>.\n',summary:"<p> Convenience function for  campaign-geo-opens-for-country#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"code",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An ISO3166 2 digit country code</div>'}],returns:{type:"item()*",description:"Regions an array of regions within the provided country where opens occurred."},errors:[]},{isDocumented:!0,arity:4,name:"campaign-geo-opens-for-country",qname:"mailchimp:campaign-geo-opens-for-country",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $code as xs:string) as item()*",description:" Retrieve the regions and number of opens tracked for a certain country. Email address are not returned.\n",summary:"<p> Retrieve the regions and number of opens tracked for a certain country.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"code",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An ISO3166 2 digit country code</div>'}],returns:{type:"item()*",description:"Regions an array of regions within the provided country where opens occurred."},errors:[]},{isDocumented:!0,arity:2,name:"campaign-geo-opens",qname:"mailchimp:campaign-geo-opens",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-geo-opens-3">campaign-geo-opens#3</a>.\n',summary:"<p> Convenience function for  campaign-geo-opens#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Countries an array of countries where opens occurred"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-geo-opens",qname:"mailchimp:campaign-geo-opens",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Retrieve the countries and number of opens tracked for each. Email address are not returned.\n",summary:"<p> Retrieve the countries and number of opens tracked for each.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Countries an array of countries where opens occurred"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-hard-bounces",qname:"mailchimp:campaign-hard-bounces",signature:"($apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-hard-bounces-5">campaign-hard-bounces#5</a>.\n',summary:"<p> Convenience function for  campaign-hard-bounces#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"array a total of all hard bounced emails and the specific emails for this page"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-hard-bounces",qname:"mailchimp:campaign-hard-bounces",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' <strong xmlns:xqdoc="http://www.xqdoc.org/1.0">DEPRECATED</strong> Get all email addresses with Hard Bounces for a given campaign the email address that bounced.\n',summary:"<p>  DEPRECATED  Get all email addresses with Hard Bounces for a given campaign the email address that bounced.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"array a total of all hard bounced emails and the specific emails for this page"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-members",qname:"mailchimp:campaign-members",signature:"($apikey as xs:string, $cid as xs:string, $status as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-members-6">campaign-members#6</a>.\n',summary:"<p> Convenience function for  campaign-members#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull members for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"status",type:"xs:string",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> optional the status to pull - one of 'sent', 'hard' (bounce), or 'soft' (bounce). By default, all records are returned</div>"},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"A total of all matching emails and the specific emails for this page"},errors:[]},{isDocumented:!0,arity:6,name:"campaign-members",qname:"mailchimp:campaign-members",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $status as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:" Get all email addresses the campaign was successfully sent to (ie, no bounces).\n",summary:"<p> Get all email addresses the campaign was successfully sent to (ie, no bounces).</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull members for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"status",type:"xs:string",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> optional the status to pull - one of 'sent', 'hard' (bounce), or 'soft' (bounce). By default, all records are returned</div>"},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"A total of all matching emails and the specific emails for this page"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-not-opened-AIM",qname:"mailchimp:campaign-not-opened-AIM",signature:"($apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-not-opened-AIM-5">campaign-not-opened-AIM#5</a>.\n',summary:"<p> Convenience function for  campaign-not-opened-AIM#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get no opens for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"Array containing the total records matched and the specific records for this page"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-not-opened-AIM",qname:"mailchimp:campaign-not-opened-AIM",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:" Retrieve the list of email addresses that did not open a given campaign string email Email address that opened the campaign.\n",summary:"<p> Retrieve the list of email addresses that did not open a given campaign string email Email address that opened the campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get no opens for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"array array containing the total records matched and the specific records for this page"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-opened-AIM",qname:"mailchimp:campaign-opened-AIM",signature:"($apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-opened-AIM-5">campaign-openedAIM#5</a>.\n',summary:"<p> Convenience function for  campaign-openedAIM#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get opens for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"Array containing the total records matched and the specific records for this page"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-opened-AIM",qname:"mailchimp:campaign-opened-AIM",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:" Retrieve the list of email addresses that opened a given campaign with how many times they opened.\n",summary:"<p> Retrieve the list of email addresses that opened a given campaign with how many times they opened.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get opens for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"Array containing the total records matched and the specific records for this page"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-pause",qname:"mailchimp:campaign-pause",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-pause-3">campaign-pause#3</a>.\n',summary:"<p> Convenience function for  campaign-pause#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to pause</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-pause",qname:"mailchimp:campaign-pause",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Pause an AutoResponder or RSS campaign from sending.\n",summary:"<p> Pause an AutoResponder or RSS campaign from sending.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to pause</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-replicate",qname:"mailchimp:campaign-replicate",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-replicate-3">campaign-replicate#3</a>.\n',summary:"<p> Convenience function for  campaign-replicate#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the Campaign Id to replicate</div>'}],returns:{type:"item()*",description:"The id of the replicated Campaign created, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-replicate",qname:"mailchimp:campaign-replicate",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Replicate a campaign.\n",summary:"<p> Replicate a campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the Campaign Id to replicate</div>'}],returns:{type:"item()*",description:"The id of the replicated Campaign created, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-resume",qname:"mailchimp:campaign-resume",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-resume-3">campaign-resume#3</a>.\n',summary:"<p> Convenience function for  campaign-resume#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to pause</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-resume",qname:"mailchimp:campaign-resume",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Resume sending an AutoResponder or RSS campaign.\n",summary:"<p> Resume sending an AutoResponder or RSS campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to pause</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-schedule",qname:"mailchimp:campaign-schedule",signature:"($apikey as xs:string, $cid as xs:string, $schedule_time as xs:string, $schedule_time_b as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-schedule-5">campaign-schedule#5</a>.\n',summary:"<p> Convenience function for  campaign-schedule#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to schedule</div>'},{name:"schedule_time",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the time to schedule the campaign. For A/B Split "schedule" campaigns, the time for Group A - in YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'},{name:"schedule_time_b",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional -the time to schedule Group B of an A/B Split "schedule" campaign - in YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"boolean True on success"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-schedule",qname:"mailchimp:campaign-schedule",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $schedule_time as xs:string, $schedule_time_b as xs:string) as item()*",description:" Schedule a campaign to be sent in the future.\n",summary:"<p> Schedule a campaign to be sent in the future.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to schedule</div>'},{name:"schedule_time",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the time to schedule the campaign. For A/B Split "schedule" campaigns, the time for Group A - in YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'},{name:"schedule_time_b",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional -the time to schedule Group B of an A/B Split "schedule" campaign - in YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"boolean True on success"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-segment-test",qname:"mailchimp:campaign-segment-test",signature:"($apikey as xs:string, $list_id as xs:string, $options as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-segment-test-4">campaign-segment-test#4</a>.\n',summary:"<p> Convenience function for  campaign-segment-test#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"list_id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list to test segmentation on - get lists using lists()</div>'},{name:"options",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> with 2 keys. See <a href="http://apidocs.mailchimp.com/rtfm/campaignsegmenttest.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'}],returns:{type:"item()*",description:"The total number of subscribers matching your segmentation options"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-segment-test",qname:"mailchimp:campaign-segment-test",signature:"($endpoint-url as xs:string, $apikey as xs:string, $list_id as xs:string, $options as element(array)) as item()*",description:" Allows one to test their segmentation rules before creating a campaign using them.\n",summary:"<p> Allows one to test their segmentation rules before creating a campaign using them.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"list_id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list to test segmentation on - get lists using <a href="#lists-4">lists()</a></div>'},{name:"options",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> with 2 keys. See <a href="http://apidocs.mailchimp.com/rtfm/campaignsegmenttest.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'}],returns:{type:"item()*",description:"The total number of subscribers matching your segmentation options"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-send-now",qname:"mailchimp:campaign-send-now",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-send-now-3">campaign-send-now#3</a>.\n',summary:"<p> Convenience function for  campaign-send-now#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to send</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-send-now",qname:"mailchimp:campaign-send-now",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:' Send a given campaign immediately. For RSS campaigns, this will "start" them.\n',summary:"<p> Send a given campaign immediately.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to send</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-send-test",qname:"mailchimp:campaign-send-test",signature:"($apikey as xs:string, $cid as xs:string, $test_emails as element(array), $send_type as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-send-test-5">campaign-send-test#5</a>.\n',summary:"<p> Convenience function for  campaign-send-test#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to test</div>'},{name:"test_emails",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of email address to receive the test message</div>'},{name:"send_type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional by default (null) both formats are sent - "html" or "text" send just that format</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-send-test",qname:"mailchimp:campaign-send-test",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $test_emails as element(array), $send_type as xs:string) as item()*",description:" Send a test of this campaign to the provided email address.\n",summary:"<p> Send a test of this campaign to the provided email address.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to test</div>'},{name:"test_emails",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of email address to receive the test message</div>'},{name:"send_type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional by default (null) both formats are sent - "html" or "text" send just that format</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-share-report",qname:"mailchimp:campaign-share-report",signature:"($apikey as xs:string, $cid as xs:string, $opts as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-share-report-4">campaign-share-report#4</a>.\n',summary:"<p> Convenience function for  campaign-share-report#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to share a report for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"opts",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> s optional various parameters which can be used to configure the shared report</div>'}],returns:{type:"item()*",description:"Struct containing details for the shared report"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-share-report",qname:"mailchimp:campaign-share-report",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $opts as element(array)) as item()*",description:' Get the URL to a customized <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://eepurl.com/gKmL" target="_blank">VIP Report</a> for the specified campaign and optionally send an email to someone with links to it. Note subsequent calls will overwrite anything already set for the same campign (eg, the password).\n',summary:"<p> Get the URL to a customized  VIP Report  for the specified campaign and optionally send an email to someone with links to it.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to share a report for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"opts",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> s optional various parameters which can be used to configure the shared report</div>'}],returns:{type:"item()*",description:"Struct containing details for the shared report"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-soft-bounces",qname:"mailchimp:campaign-soft-bounces",signature:"($apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-soft-bounces-5">campaign-soft-bounces#5</a>.\n',summary:"<p> Convenience function for  campaign-soft-bounces#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"A total of all soft bounced emails and the specific emails for this page"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-soft-bounces",qname:"mailchimp:campaign-soft-bounces",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' <strong xmlns:xqdoc="http://www.xqdoc.org/1.0">DEPRECATED</strong> Get all email addresses with Soft Bounces for a given campaign the email address that bounced.\n',summary:"<p>  DEPRECATED  Get all email addresses with Soft Bounces for a given campaign the email address that bounced.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"A total of all soft bounced emails and the specific emails for this page"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-stats",qname:"mailchimp:campaign-stats",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-stats-3">campaign-stats#3</a>.\n',summary:"<p> Convenience function for  campaign-stats#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"array struct of the statistics for this campaign"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-stats",qname:"mailchimp:campaign-stats",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Given a list and a campaign, get all the relevant campaign statistics (opens, bounces, clicks, etc.)\n",summary:"<p> Given a list and a campaign, get all the relevant campaign statistics (opens, bounces, clicks, etc.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull stats for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"array struct of the statistics for this campaign"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-template-content",qname:"mailchimp:campaign-template-content",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-template-content-3">campaign-template-content#3</a>.\n',summary:"<p> Convenience function for  campaign-template-content#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get content for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Array containing all content section for the campaign -"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-template-content",qname:"mailchimp:campaign-template-content",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:' Get the HTML template content sections for a campaign. Note that this <strong xmlns:xqdoc="http://www.xqdoc.org/1.0">will</strong> return very jagged, non-standard results based on the template a campaign is using. You only want to use this if you want to allow editing template sections in your applicaton.\n',summary:"<p> Get the HTML template content sections for a campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to get content for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'}],returns:{type:"item()*",description:"Array containing all content section for the campaign -"},errors:[]},{isDocumented:!0,arity:2,name:"campaign-unschedule",qname:"mailchimp:campaign-unschedule",signature:"($apikey as xs:string, $cid as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-unschedule-3">campaign-unschedule#3</a>.\n',summary:"<p> Convenience function for  campaign-unschedule#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to unschedule</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:3,name:"campaign-unschedule",qname:"mailchimp:campaign-unschedule",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string) as item()*",description:" Unschedule a campaign that is scheduled to be sent in the future.\n",summary:"<p> Unschedule a campaign that is scheduled to be sent in the future.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the campaign to unschedule</div>'}],returns:{type:"item()*",description:"True on success"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-unsubscribes",qname:"mailchimp:campaign-unsubscribes",signature:"($apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-unsubscribes-5">campaign-unsubscribes#5</a>.\n',summary:"<p> Convenience function for  campaign-unsubscribes#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"array email addresses that unsubscribed from this campaign along with reasons, if given array a total of all unsubscribed emails and the specific emails for this page"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-unsubscribes",qname:"mailchimp:campaign-unsubscribes",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:" Get all unsubscribed email addresses for a given campaign.\n",summary:"<p> Get all unsubscribed email addresses for a given campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the campaign id to pull bounces for (can be gathered using <a href="#campaigns-4">campaigns()</a>)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> art optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> mit optional for large data sets, the number of results to return - defaults to 1000, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"array email addresses that unsubscribed from this campaign along with reasons, if given array a total of all unsubscribed emails and the specific emails for this page"},errors:[]},{isDocumented:!0,arity:4,name:"campaign-update",qname:"mailchimp:campaign-update",signature:"($apikey as xs:string, $cid as xs:string, $name as xs:string, $value as item()) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-update-5">campaign-update#5</a>.\n',summary:"<p> Convenience function for  campaign-update#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the Campaign Id to update</div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the parameter name (see <a href="#campaign-create-6">campaigncreate()</a>). For items in the <strong>options</strong> array, this will be that parameter\'s name (subject, from_email, etc.). Additional parameters will be that option name (content, segment_opts). "type_opts" will be the name of the type - rss, auto, trans, etc.</div>'},{name:"value",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> e an appropriate value for the parameter ( see <a href="#campaign-create-6">campaigncreate()</a>). For items in the <strong>options</strong> array, this will be that parameter\'s value. For additional parameters, this is the same value passed to them.</div>'}],returns:{type:"item()*",description:"boolean true if the update succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:5,name:"campaign-update",qname:"mailchimp:campaign-update",signature:"($endpoint-url as xs:string, $apikey as xs:string, $cid as xs:string, $name as xs:string, $value as item()) as item()*",description:' Update just about any setting for a campaign that has <em xmlns:xqdoc="http://www.xqdoc.org/1.0">not</em> been sent. See <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaign-create-6">campaigncreate()</a> for details.\n Caveats: <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n  <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n    <li>If you set list_id, all segmentation options will be deleted and must be re-added.</li>\n    <li>If you set template_id, you need to follow that up by setting it\'s \'content\'</li>\n    <li>If you set segment_opts, you should have tested your options against <a href="#campaign-segment-test-3">campaign-segment-test()</a> as <a href="#campaign-update-4">campaign-update()</a> will not allow you to set a segment that includes no members.</li>\n  </ul>.\n',summary:"<p> Update just about any setting for a campaign that has  not  been sent.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"cid",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the Campaign Id to update</div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the parameter name ( see <a href="#campaign-create-6">campaigncreate()</a>). For items in the <strong>options</strong> array, this will be that parameter\'s name (subject, from_email, etc.). Additional parameters will be that option name (content, segment_opts). "type_opts" will be the name of the type - rss, auto, trans, etc.</div>'},{name:"value",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An appropriate value for the parameter ( see <a href="#campaign-create-6">campaigncreate()</a>). For items in the <strong>options</strong> array, this will be that parameter\'s value. For additional parameters, this is the same value passed to them.</div>'}],returns:{type:"item()*",description:"True if the update succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:2,name:"campaigns-for-email",qname:"mailchimp:campaigns-for-email",signature:"($apikey as xs:string, $email_address as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaigns-for-email-3">campaigns-for-email#3</a>.\n',summary:"<p> Convenience function for  campaigns-for-email#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address to unsubscribe OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns</div>'}],returns:{type:"item()*",description:"An array of campaign_ids the member received"},errors:[]},{isDocumented:!0,arity:3,name:"campaigns-for-email",qname:"mailchimp:campaigns-for-email",signature:"($endpoint-url as xs:string, $apikey as xs:string, $email_address as xs:string) as item()*",description:" Retrieve all Campaigns Ids a member was sent.\n",summary:"<p> Retrieve all Campaigns Ids a member was sent.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address to unsubscribe OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns</div>'}],returns:{type:"item()*",description:"An array of campaign_ids the member received"},errors:[]},{isDocumented:!0,arity:4,name:"campaigns",qname:"mailchimp:campaigns",signature:"($apikey as xs:string, $filters as element(array), $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#campaigns-5">campaigns#5</a>.\n',summary:"<p> Convenience function for  campaigns#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"filters",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hash of filters to apply to this query - all are optional. See <a href="http://apidocs.mailchimp.com/rtfm/campaigns.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - control paging of campaigns, start results at this campaign #, defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - control paging of campaigns, number of campaigns to return with each call, defaults to 25 (max=1000)</div>'}],returns:{type:"item()*",description:'An array containing a count of all matching campaigns and the specific ones for the current page (see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://apidocs.mailchimp.com/rtfm/campaigns.func.php">Mailchimp API documentation</a> for more information about the return type)'},errors:[]},{isDocumented:!0,arity:5,name:"campaigns",qname:"mailchimp:campaigns",signature:"($endpoint-url as xs:string, $apikey as xs:string, $filters as element(array), $start as xs:integer, $limit as xs:integer) as item()*",description:" Get the list of campaigns and their details matching the specified filters.\n",summary:"<p> Get the list of campaigns and their details matching the specified filters.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"filters",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hash of filters to apply to this query - all are optional. See <a href="http://apidocs.mailchimp.com/rtfm/campaigns.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - control paging of campaigns, start results at this campaign #, defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - control paging of campaigns, number of campaigns to return with each call, defaults to 25 (max=1000)</div>'}],returns:{type:"item()*",description:'An array containing a count of all matching campaigns and the specific ones for the current page (see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://apidocs.mailchimp.com/rtfm/campaigns.func.php">Mailchimp API documentation</a> for more information about the return type)'},errors:[]},{isDocumented:!0,arity:1,name:"chimp-chatter",qname:"mailchimp:chimp-chatter",signature:"($apikey as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#chimp-chatter-2">chimp-chatter#2</a>.\n',summary:"<p> Convenience function for  chimp-chatter#2 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""}],returns:{type:"item()*",description:"An array of chatter messages and properties"},errors:[]},{isDocumented:!0,arity:2,name:"chimp-chatter",qname:"mailchimp:chimp-chatter",signature:"($endpoint-url as xs:string, $apikey as xs:string) as item()*",description:" Return the current Chimp Chatter messages for an account.\n",summary:"<p> Return the current Chimp Chatter messages for an account.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'}],returns:{type:"item()*",description:"An array of chatter messages and properties"},errors:[]},{isDocumented:!0,arity:2,name:"ecomm-order-add",qname:"mailchimp:ecomm-order-add",signature:"($apikey as xs:string, $order as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#ecomm-order-add-3">ecomm-order-add#3</a>.\n',summary:"<p> Convenience function for  ecomm-order-add#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"order",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of information pertaining to the order that has completed. Use the following keys. See <a href="http://apidocs.mailchimp.com/rtfm/ecommorderadd.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'}],returns:{type:"item()*",description:"True if the data is saved, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:3,name:"ecomm-order-add",qname:"mailchimp:ecomm-order-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $order as element(array)) as item()*",description:" Import Ecommerce Order Information to be used for Segmentation.\n",summary:"<p> Import Ecommerce Order Information to be used for Segmentation.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"order",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of information pertaining to the order that has completed. Use the following keys. See <a href="http://apidocs.mailchimp.com/rtfm/ecommorderadd.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'}],returns:{type:"item()*",description:"True if the data is saved, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:3,name:"ecomm-order-del",qname:"mailchimp:ecomm-order-del",signature:"($apikey as xs:string, $store_id as xs:string, $order_id as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#ecomm-order-del-4">ecomm-order-del#4</a>.\n',summary:"<p> Convenience function for  ecomm-order-del#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"store_id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the store id the order belongs to</div>'},{name:"order_id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the order id (generated by the store) to delete</div>'}],returns:{type:"item()*",description:"True if an order is deleted, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:4,name:"ecomm-order-del",qname:"mailchimp:ecomm-order-del",signature:"($endpoint-url as xs:string, $apikey as xs:string, $store_id as xs:string, $order_id as xs:string) as item()*",description:' Delete Ecommerce Order Information used for segmentation. This will generally be used by ecommerce package plugins <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="/plugins/ecomm360.phtml">that we provide</a> or by 3rd part system developers.\n',summary:"<p> Delete Ecommerce Order Information used for segmentation.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"store_id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the store id the order belongs to</div>'},{name:"order_id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the order id (generated by the store) to delete</div>'}],returns:{type:"item()*",description:"True if an order is deleted, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:4,name:"ecomm-orders",qname:"mailchimp:ecomm-orders",signature:"($apikey as xs:string, $start as xs:integer, $limit as xs:integer, $since as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#ecomm-orders-5">ecomm-orders#5</a>.\n',summary:"<p> Convenience function for  ecomm-orders#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 100, upper limit set at 500</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"Array the total matching orders and the specific orders for the requested page"},errors:[]},{isDocumented:!0,arity:5,name:"ecomm-orders",qname:"mailchimp:ecomm-orders",signature:"($endpoint-url as xs:string, $apikey as xs:string, $start as xs:integer, $limit as xs:integer, $since as xs:string) as item()*",description:" Retrieve the Ecommerce Orders for an account.\n",summary:"<p> Retrieve the Ecommerce Orders for an account.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 100, upper limit set at 500</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"Array the total matching orders and the specific orders for the requested page"},errors:[]},{isDocumented:!0,arity:3,name:"folder-add",qname:"mailchimp:folder-add",signature:"($apikey as xs:string, $name as xs:string, $type as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#folder-add-4">folder-add#4</a>.\n',summary:"<p> Convenience function for  folder-add#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a unique name for a folder (max 100 bytes)</div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the type of folder to create - either "campaign" or "autoresponder". Defaults to "campaign"</div>'}],returns:{type:"item()*",description:"The folder_id of the newly created folder."},errors:[]},{isDocumented:!0,arity:4,name:"folder-add",qname:"mailchimp:folder-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $name as xs:string, $type as xs:string) as item()*",description:" Add a new folder to file campaigns or autoresponders in.\n",summary:"<p> Add a new folder to file campaigns or autoresponders in.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a unique name for a folder (max 100 bytes)</div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the type of folder to create - either "campaign" or "autoresponder". Defaults to "campaign"</div>'}],returns:{type:"item()*",description:"The folder_id of the newly created folder."},errors:[]},{isDocumented:!0,arity:3,name:"folder-del",qname:"mailchimp:folder-del",signature:"($apikey as xs:string, $fid as xs:integer, $type as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#folder-del-4">folder-del#4</a>.\n',summary:"<p> Convenience function for  folder-del#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"fid",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the folder id to update - retrieve from folders()</div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the type of folder to create - either "campaign" or "autoresponder". Defaults to "campaign"</div>'}],returns:{type:"item()*",description:"True if the delete worked, otherwise an exception is thrown"},errors:[]},{isDocumented:!0,arity:4,name:"folder-del",qname:"mailchimp:folder-del",signature:"($endpoint-url as xs:string, $apikey as xs:string, $fid as xs:integer, $type as xs:string) as item()*",description:" Delete a campaign or autoresponder folder. Note that this will simply make campaigns in the folder appear unfiled, they are not removed.\n",summary:"<p> Delete a campaign or autoresponder folder.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"fid",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the folder id to update - retrieve from folders()</div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the type of folder to create - either "campaign" or "autoresponder". Defaults to "campaign"</div>'}],returns:{type:"item()*",description:"True if the delete worked, otherwise an exception is thrown"},errors:[]},{isDocumented:!0,arity:4,name:"folder-update",qname:"mailchimp:folder-update",signature:"($apikey as xs:string, $fid as xs:integer, $name as xs:string, $type as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#folder-update-5">folder-update#5</a>.\n',summary:"<p> Convenience function for  folder-update#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"fid",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the folder id to update - retrieve from folders()</div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a new, unique name for the folder (max 100 bytes)</div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the type of folder to create - either "campaign" or "autoresponder". Defaults to "campaign"</div>'}],returns:{type:"item()*",description:"True if the update worked, otherwise an exception is thrown"},errors:[]},{isDocumented:!0,arity:5,name:"folder-update",qname:"mailchimp:folder-update",signature:"($endpoint-url as xs:string, $apikey as xs:string, $fid as xs:integer, $name as xs:string, $type as xs:string) as item()*",description:" Update the name of a folder for campaigns or autoresponders.\n",summary:"<p> Update the name of a folder for campaigns or autoresponders.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"fid",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the folder id to update - retrieve from folders()</div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a new, unique name for the folder (max 100 bytes)</div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the type of folder to create - either "campaign" or "autoresponder". Defaults to "campaign"</div>'}],returns:{type:"item()*",description:"True if the update worked, otherwise an exception is thrown"},errors:[]},{isDocumented:!0,arity:2,name:"folders",qname:"mailchimp:folders",signature:"($apikey as xs:string, $type as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#folders-3">folders#3</a>.\n',summary:"<p> Convenience function for  folders#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the type of folders to return - either "campaign" or "autoresponder". Defaults to "campaign"</div>'}],returns:{type:"item()*",description:"Array of folder structs (see Returned Fields for details)"},errors:[]},{isDocumented:!0,arity:3,name:"folders",qname:"mailchimp:folders",signature:"($endpoint-url as xs:string, $apikey as xs:string, $type as xs:string) as item()*",description:" List all the folders for a user account.\n",summary:"<p> List all the folders for a user account.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the type of folders to return - either "campaign" or "autoresponder". Defaults to "campaign"</div>'}],returns:{type:"item()*",description:"Array of folder structs (see Returned Fields for details)"},errors:[]},{isDocumented:!0,arity:3,name:"generate-text",qname:"mailchimp:generate-text",signature:"($apikey as xs:string, $type as xs:string, $content as item()) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#generate-text-4">generate-text#4</a>.\n',summary:"<p> Convenience function for  generate-text#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The type of content to parse. Must be one of: "html", "template", "url", "cid" (Campaign Id), or "tid" (Template Id)</div>'},{name:"content",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The content to use. For "html" expects a single string value, "template" expects an array like you send to campaignCreate, "url" expects a valid &amp; public URL to pull from, "cid" expects a valid Campaign Id, and "tid" expects a valid Template Id on your account.</div>'}],returns:{type:"item()*",description:"The content pass in converted to text."},errors:[]},{isDocumented:!0,arity:4,name:"generate-text",qname:"mailchimp:generate-text",signature:"($endpoint-url as xs:string, $apikey as xs:string, $type as xs:string, $content as item()) as item()*",description:' Have HTML content auto-converted to a text-only format. You can send: plain HTML, an array of Template content, an existing Campaign Id, or an existing Template Id. Note that this will <b xmlns:xqdoc="http://www.xqdoc.org/1.0">not</b> save anything to or update any of your lists, campaigns, or templates.\n',summary:"<p> Have HTML content auto-converted to a text-only format.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The type of content to parse. Must be one of: "html", "template", "url", "cid" (Campaign Id), or "tid" (Template Id)</div>'},{name:"content",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The content to use. For "html" expects a single string value, "template" expects an array like you send to campaignCreate, "url" expects a valid &amp; public URL to pull from, "cid" expects a valid Campaign Id, and "tid" expects a valid Template Id on your account.</div>'}],returns:{type:"item()*",description:"The content pass in converted to text."},errors:[]},{isDocumented:!0,arity:1,name:"get-account-details",qname:"mailchimp:get-account-details",signature:"($apikey as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#get-account-details-2">get-account-details#2</a>.\n',summary:"<p> Convenience function for  get-account-details#2 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""}],returns:{type:"item()*",description:"array containing the details for the account tied to this API Key"},errors:[]},{isDocumented:!0,arity:2,name:"get-account-details",qname:"mailchimp:get-account-details",signature:"($endpoint-url as xs:string, $apikey as xs:string) as item()*",description:" Retrieve lots of account information including payments made, plan info, some account stats, installed modules, contact info, and more.\n",summary:"<p> Retrieve lots of account information including payments made, plan info, some account stats, installed modules, contact info, and more.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'}],returns:{type:"item()*",description:"Array containing the details for the account tied to this API Key"},errors:[]},{isDocumented:!0,arity:3,name:"inline-css",qname:"mailchimp:inline-css",signature:"($apikey as xs:string, $html as xs:string, $strip_css as xs:boolean) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#inline-css-4">inline-css#4</a>.\n',summary:"<p> Convenience function for  inline-css#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"html",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your HTML content</div>'},{name:"strip_css",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional Whether you want the CSS &amp;lt;style&amp;gt; tags stripped from the returned document. Defaults to false.</div>'}],returns:{type:"item()*",description:"Your HTML content with all CSS inlined, just like if we sent it."},errors:[]},{isDocumented:!0,arity:4,name:"inline-css",qname:"mailchimp:inline-css",signature:"($endpoint-url as xs:string, $apikey as xs:string, $html as xs:string, $strip_css as xs:boolean) as item()*",description:" Send your HTML content to have the CSS inlined and optionally remove the original styles.\n",summary:"<p> Send your HTML content to have the CSS inlined and optionally remove the original styles.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"html",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Your HTML content</div>'},{name:"strip_css",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional Whether you want the CSS &amp;lt;style&amp;gt; tags stripped from the returned document. Defaults to false.</div>'}],returns:{type:"item()*",description:"Your HTML content with all CSS inlined, just like if we sent it."},errors:[]},{isDocumented:!0,arity:5,name:"list-abuse-reports",qname:"mailchimp:list-abuse-reports",signature:"($apikey as xs:string, $id as xs:string, $start as xs:integer, $limit as xs:integer, $since as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-abuse-reports-6">list-abuse-reports#6</a>.\n',summary:"<p> Convenience function for  list-abuse-reports#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to pull abuse reports for (can be gathered using lists())</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 500, upper limit set at 1000</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"The total of all reports and the specific reports reports this page"},errors:[]},{isDocumented:!0,arity:6,name:"list-abuse-reports",qname:"mailchimp:list-abuse-reports",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $start as xs:integer, $limit as xs:integer, $since as xs:string) as item()*",description:" Get all email addresses that complained about a given campaign.\n",summary:"<p> Get all email addresses that complained about a given campaign.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to pull abuse reports for (can be gathered using lists())</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 500, upper limit set at 1000</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull only messages since this time - use YYYY-MM-DD HH:II:SS format in <strong>GMT</strong></div>'}],returns:{type:"item()*",description:"The total of all reports and the specific reports reports this page"},errors:[]},{isDocumented:!0,arity:2,name:"list-activity",qname:"mailchimp:list-activity",signature:"($apikey as xs:string, $id as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-activity-3">list-activity#3</a>.\n',summary:"<p> Convenience function for  list-activity#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"Array of array of daily values."},errors:[]},{isDocumented:!0,arity:3,name:"list-activity",qname:"mailchimp:list-activity",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string) as item()*",description:" Access up to the previous 180 days of daily detailed aggregated activity stats for a given list.\n",summary:"<p> Access up to the previous 180 days of daily detailed aggregated activity stats for a given list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"array array of array of daily values."},errors:[]},{isDocumented:!0,arity:6,name:"list-batch-subscribe",qname:"mailchimp:list-batch-subscribe",signature:"($apikey as xs:string, $id as xs:string, $batch as element(array), $double_optin as xs:boolean, $update_existing as xs:boolean, $replace_interests as xs:boolean) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-batch-subscribe-7">list-batch-subscribe#7</a>.\n',summary:"<p> Convenience function for  list-batch-subscribe#7 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"batch",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of structs for each address to import with two special keys: "EMAIL" for the email address, and "EMAIL_TYPE" for the email type option (html, text, or mobile)</div>'},{name:"double_optin",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to control whether to send an opt-in confirmation email - defaults to true</div>'},{name:"update_existing",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to control whether to update members that are already subscribed to the list or to return an error, defaults to false (return error)</div>'},{name:"replace_interests",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to determine whether we replace the interest groups with the updated groups provided, or we add the provided groups to the member\'s interest groups (optional, defaults to true)</div>'}],returns:{type:"item()*",description:"Array of result counts and any errors that occurred"},errors:[]},{isDocumented:!0,arity:7,name:"list-batch-subscribe",qname:"mailchimp:list-batch-subscribe",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $batch as element(array), $double_optin as xs:boolean, $update_existing as xs:boolean, $replace_interests as xs:boolean) as item()*",description:' Subscribe a batch of email addresses to a list at once. If you are using a serialized version of the API, we strongly suggest that you only run this method as a POST request, and <em xmlns:xqdoc="http://www.xqdoc.org/1.0">not</em> a GET request. Maximum batch sizes vary based on the amount of data in each record, though you should cap them at 5k - 10k records, depending on your experience. These calls are also long, so be sure you increase your timeout values.\n',summary:"<p> Subscribe a batch of email addresses to a list at once.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"batch",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of structs for each address to import with two special keys: "EMAIL" for the email address, and "EMAIL_TYPE" for the email type option (html, text, or mobile)</div>'},{name:"double_optin",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to control whether to send an opt-in confirmation email - defaults to true</div>'},{name:"update_existing",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to control whether to update members that are already subscribed to the list or to return an error, defaults to false (return error)</div>'},{name:"replace_interests",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to determine whether we replace the interest groups with the updated groups provided, or we add the provided groups to the member\'s interest groups (optional, defaults to true)</div>'}],returns:{type:"item()*",description:"Array of result counts and any errors that occurred"},errors:[]},{isDocumented:!0,arity:6,name:"list-batch-unsubscribe",qname:"mailchimp:list-batch-unsubscribe",signature:"($apikey as xs:string, $id as xs:string, $emails as element(array), $delete_member as xs:boolean, $send_goodbye as xs:boolean, $send_notify as xs:boolean) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-batch-unsubscribe-7">list-batch-unsubscribe#7</a>.\n',summary:"<p> Convenience function for  list-batch-unsubscribe#7 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"emails",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> array of email addresses to unsubscribe</div>'},{name:"delete_member",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to completely delete the member from your list instead of just unsubscribing, default to false</div>'},{name:"send_goodbye",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to send the goodbye email to the email addresses, defaults to true</div>'},{name:"send_notify",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to send the unsubscribe notification email to the address defined in the list email notification settings, defaults to false</div>'}],returns:{type:"item()*",description:"Array of result counts and any errors that occurred"},errors:[]},{isDocumented:!0,arity:7,name:"list-batch-unsubscribe",qname:"mailchimp:list-batch-unsubscribe",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $emails as element(array), $delete_member as xs:boolean, $send_goodbye as xs:boolean, $send_notify as xs:boolean) as item()*",description:" Unsubscribe a batch of email addresses to a list.\n",summary:"<p> Unsubscribe a batch of email addresses to a list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"emails",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> array of email addresses to unsubscribe</div>'},{name:"delete_member",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to completely delete the member from your list instead of just unsubscribing, default to false</div>'},{name:"send_goodbye",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to send the goodbye email to the email addresses, defaults to true</div>'},{name:"send_notify",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to send the unsubscribe notification email to the address defined in the list email notification settings, defaults to false</div>'}],returns:{type:"item()*",description:"Array of result counts and any errors that occurred"},errors:[]},{isDocumented:!0,arity:2,name:"list-clients",qname:"mailchimp:list-clients",signature:"($apikey as xs:string, $id as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-clients-3">list-clients#3</a>.\n',summary:"<p> Convenience function for  list-clients#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"array the desktop and mobile user agents in use on the list"},errors:[]},{isDocumented:!0,arity:3,name:"list-clients",qname:"mailchimp:list-clients",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string) as item()*",description:" Retrieve the clients that the list's subscribers have been tagged as being used based on user agents seen. Made possible by <a xmlns:xqdoc=\"http://www.xqdoc.org/1.0\" href=\"http://user-agent-string.info\" target=\"_blank\">user-agent-string.info</a> double penetration the percent of desktop clients in use array clients a record containing the 'client', an 'icon' image url, the 'percent' using the client, and the total 'members' represented double penetration the percent of mobile clients in use array clients a record containing the 'client', an 'icon' image url, the 'percent' using the client, and the total 'members' represented.\n",summary:"<p> Retrieve the clients that the list's subscribers have been tagged as being used based on user agents seen.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"Array the desktop and mobile user agents in use on the list"},errors:[]},{isDocumented:!0,arity:2,name:"list-growth-history",qname:"mailchimp:list-growth-history",signature:"($apikey as xs:string, $id as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-growth-history-3">list-growth-history#3</a>.\n',summary:"<p> Convenience function for  list-growth-history#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"Array of months and growth"},errors:[]},{isDocumented:!0,arity:3,name:"list-growth-history",qname:"mailchimp:list-growth-history",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string) as item()*",description:" Access the Growth History by Month for a given list.\n",summary:"<p> Access the Growth History by Month for a given list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"Array of months and growth"},errors:[]},{isDocumented:!0,arity:4,name:"list-interest-group-add",qname:"mailchimp:list-interest-group-add",signature:"($apikey as xs:string, $id as xs:string, $group_name as xs:string, $grouping_id as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-interest-group-add-5">list-interest-group-add#5</a>.\n',summary:"<p> Convenience function for  list-interest-group-add#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"group_name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest group to add - group names must be unique within a grouping</div>'},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> ouping_id The grouping to add the new group to - get using <a href="#list-interest-groupings-2">list-interest-groupings()</a>. If not supplied, the first grouping on the list is used.</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:5,name:"list-interest-group-add",qname:"mailchimp:list-interest-group-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $group_name as xs:string, $grouping_id as xs:integer) as item()*",description:" Add a single Interest Group - if interest groups for the List are not yet enabled, adding the first group will automatically turn them on.\n",summary:"<p> Add a single Interest Group - if interest groups for the List are not yet enabled, adding the first group will automatically turn them on.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"group_name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest group to add - group names must be unique within a grouping</div>'},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> ouping_id The grouping to add the new group to - get using <a href="#list-interest-groupings-2">list-interest-groupings()</a> . If not supplied, the first grouping on the list is used.</div>'}],returns:{type:"item()*",description:"bool true if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:4,name:"list-interest-group-del",qname:"mailchimp:list-interest-group-del",signature:"($apikey as xs:string, $id as xs:string, $group_name as xs:string, $grouping_id as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-interest-group-del-5">list-interest-group-del#5</a>.\n',summary:"<p> Convenience function for  list-interest-group-del#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"group_name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest group to delete</div>'},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The grouping to delete the group from - get using <a href="#list-interest-groupings-2">list-interest-groupings()</a> . If not supplied, the first grouping on the list is used.</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:5,name:"list-interest-group-del",qname:"mailchimp:list-interest-group-del",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $group_name as xs:string, $grouping_id as xs:integer) as item()*",description:" Delete a single Interest Group - if the last group for a list is deleted, this will also turn groups for the list off.\n",summary:"<p> Delete a single Interest Group - if the last group for a list is deleted, this will also turn groups for the list off.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"group_name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest group to delete</div>'},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The grouping to delete the group from - get using <a href="#list-interest-groupings-2">list-interest-groupings()</a> . If not supplied, the first grouping on the list is used.</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:5,name:"list-interest-group-update",qname:"mailchimp:list-interest-group-update",signature:"($apikey as xs:string, $id as xs:string, $old_name as xs:string, $new_name as xs:string, $grouping_id as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-interest-group-update-6">list-interest-group-update#6</a>.\n',summary:"<p> Convenience function for  list-interest-group-update#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"old_name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest group name to be changed</div>'},{name:"new_name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the new interest group name to be set</div>'},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> ouping_id The grouping to delete the group from - get using <a href="#list-interest-groupings-2">list-interest-groupings()</a> . If not supplied, the first grouping on the list is used.</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:6,name:"list-interest-group-update",qname:"mailchimp:list-interest-group-update",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $old_name as xs:string, $new_name as xs:string, $grouping_id as xs:integer) as item()*",description:" Change the name of an Interest Group.\n",summary:"<p> Change the name of an Interest Group.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"old_name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest group name to be changed</div>'},{name:"new_name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the new interest group name to be set</div>'},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> ouping_id The grouping to delete the group from - get using <a href="#list-interest-groupings-2">list-interest-groupings()</a> . If not supplied, the first grouping on the list is used.</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:5,name:"list-interest-grouping-add",qname:"mailchimp:list-interest-grouping-add",signature:"($apikey as xs:string, $id as xs:string, $name as xs:string, $type as xs:string, $groups as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-interest-grouping-add-6">list-interest-grouping-add#6</a>.\n',summary:"<p> Convenience function for  list-interest-grouping-add#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest grouping to add - grouping names must be unique</div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The type of the grouping to add - one of "checkboxes", "hidden", "dropdown", "radio"</div>'},{name:"groups",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The lists of initial group names to be added - at least 1 is required and the names must be unique within a grouping. If the number takes you over the 60 group limit, an error will be thrown.</div>'}],returns:{type:"item()*",description:"The new grouping id if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:6,name:"list-interest-grouping-add",qname:"mailchimp:list-interest-grouping-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $name as xs:string, $type as xs:string, $groups as element(array)) as item()*",description:" Add a new Interest Grouping - if interest groups for the List are not yet enabled, adding the first grouping will automatically turn them on.\n",summary:"<p> Add a new Interest Grouping - if interest groups for the List are not yet enabled, adding the first grouping will automatically turn them on.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest grouping to add - grouping names must be unique</div>'},{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The type of the grouping to add - one of "checkboxes", "hidden", "dropdown", "radio"</div>'},{name:"groups",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The lists of initial group names to be added - at least 1 is required and the names must be unique within a grouping. If the number takes you over the 60 group limit, an error will be thrown.</div>'}],returns:{type:"item()*",description:"The new grouping id if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:2,name:"list-interest-grouping-del",qname:"mailchimp:list-interest-grouping-del",signature:"($apikey as xs:string, $grouping_id as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-interest-grouping-del-3">list-interest-grouping-del#3</a>.\n',summary:"<p> Convenience function for  list-interest-grouping-del#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest grouping id - get from <a href="#list-interest-groupings-2">list-interest-groupings()</a></div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:3,name:"list-interest-grouping-del",qname:"mailchimp:list-interest-grouping-del",signature:"($endpoint-url as xs:string, $apikey as xs:string, $grouping_id as xs:integer) as item()*",description:" Delete an existing Interest Grouping - this will permanently delete all contained interest groups and will remove those selections from all list members.\n",summary:"<p> Delete an existing Interest Grouping - this will permanently delete all contained interest groups and will remove those selections from all list members.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest grouping id - get from <a href="#list-interest-groupings-2">list-interest-groupings()</a></div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:4,name:"list-interest-grouping-update",qname:"mailchimp:list-interest-grouping-update",signature:"($apikey as xs:string, $grouping_id as xs:integer, $name as xs:string, $value as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-interest-grouping-update-5">list-interest-grouping-update#5</a>.\n',summary:"<p> Convenience function for  list-interest-grouping-update#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest grouping id - get from <a href="#list-interest-groupings-2">list-interest-groupings()</a></div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the field to update - either "name" or "type". Groups with in the grouping should be manipulated using the standard listInterestGroup* methods</div>'},{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The new value of the field. Grouping names must be unique - only "hidden" and "checkboxes" grouping types can be converted between each other.</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:5,name:"list-interest-grouping-update",qname:"mailchimp:list-interest-grouping-update",signature:"($endpoint-url as xs:string, $apikey as xs:string, $grouping_id as xs:integer, $name as xs:string, $value as xs:string) as item()*",description:" Update an existing Interest Grouping.\n",summary:"<p> Update an existing Interest Grouping.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"grouping_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the interest grouping id - get from <a href="#list-interest-groupings-2">list-interest-groupings()</a></div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the field to update - either "name" or "type". Groups with in the grouping should be manipulated using the standard listInterestGroup* methods</div>'},{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The new value of the field. Grouping names must be unique - only "hidden" and "checkboxes" grouping types can be converted between each other.</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:2,name:"list-interest-groupings",qname:"mailchimp:list-interest-groupings",signature:"($apikey as xs:string, $id as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-interest-groupings-3">list-interest-groupings#3</a>.\n',summary:"<p> Convenience function for  list-interest-groupings#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"List of interest groups for the list"},errors:[]},{isDocumented:!0,arity:3,name:"list-interest-groupings",qname:"mailchimp:list-interest-groupings",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string) as item()*",description:" Get the list of interest groupings for a given list, including the label, form information, and included groups for each.\n",summary:"<p> Get the list of interest groupings for a given list, including the label, form information, and included groups for each.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"List of interest groups for the list"},errors:[]},{isDocumented:!0,arity:2,name:"list-locations",qname:"mailchimp:list-locations",signature:"($apikey as xs:string, $id as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-locations-3">list-locations#3</a>.\n',summary:"<p> Convenience function for  list-locations#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"Array of locations"},errors:[]},{isDocumented:!0,arity:3,name:"list-locations",qname:"mailchimp:list-locations",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string) as item()*",description:" Retrieve the locations (countries) that the list's subscribers have been tagged to based on geocoding their IP address.\n",summary:"<p> Retrieve the locations (countries) that the list's subscribers have been tagged to based on geocoding their IP address.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"Array of locations"},errors:[]},{isDocumented:!0,arity:3,name:"list-member-activity",qname:"mailchimp:list-member-activity",signature:"($apikey as xs:string, $id as xs:string, $email_address as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-member-activity-4">list-member-activity#4</a>.\n',summary:"<p> Convenience function for  list-member-activity#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of up to 50 email addresses to get information for OR the "id"(s) for the member returned from listMembers, Webhooks, and Campaigns.</div>'}],returns:{type:"item()*",description:"Array of data and success/error counts"},errors:[]},{isDocumented:!0,arity:4,name:"list-member-activity",qname:"mailchimp:list-member-activity",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $email_address as element(array)) as item()*",description:" Get the most recent 100 activities for particular list members (open, click, bounce, unsub, abuse, sent to).\n",summary:"<p> Get the most recent 100 activities for particular list members (open, click, bounce, unsub, abuse, sent to).</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of up to 50 email addresses to get information for OR the "id"(s) for the member returned from listMembers, Webhooks, and Campaigns.</div>'}],returns:{type:"item()*",description:"Array of data and success/error counts"},errors:[]},{isDocumented:!0,arity:3,name:"list-member-info",qname:"mailchimp:list-member-info",signature:"($apikey as xs:string, $id as xs:string, $email_address as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-member-info-4">list-member-info#4</a>.\n',summary:"<p> Convenience function for  list-member-info#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of up to 50 email addresses to get information for OR the "id"(s) for the member returned from listMembers, Webhooks, and Campaigns. For backwards compatibility, if a string is passed, it will be treated as an array with a single element (will not work with XML-RPC).</div>'}],returns:{type:"item()*",description:"Array of list members with their info in an array (see Returned Fields for details)"},errors:[]},{isDocumented:!0,arity:4,name:"list-member-info",qname:"mailchimp:list-member-info",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $email_address as element(array)) as item()*",description:" Get all the information for particular members of a list.\n",summary:"<p> Get all the information for particular members of a list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of up to 50 email addresses to get information for OR the "id"(s) for the member returned from listMembers, Webhooks, and Campaigns. For backwards compatibility, if a string is passed, it will be treated as an array with a single element (will not work with XML-RPC).</div>'}],returns:{type:"item()*",description:"Array of list members with their info in an array (see Returned Fields for details)"},errors:[]},{isDocumented:!0,arity:6,name:"list-members",qname:"mailchimp:list-members",signature:"($apikey as xs:string, $id as xs:string, $status as xs:string, $since as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-members-7">list-members#7</a>.\n',summary:"<p> Convenience function for  list-members#7 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"status",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the status to get members for - one of(subscribed, unsubscribed, <a target="_blank" href="http://eepurl.com/dwk1">cleaned</a>, updated), defaults to subscribed</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull all members whose status (subscribed/unsubscribed/cleaned) has changed or whose profile (updated) has changed since this date/time (in GMT) - format is YYYY-MM-DD HH:mm:ss (24hr)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 100, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"Array of a the total records match and matching list member data for this page (see Returned Fields for details)"},errors:[]},{isDocumented:!0,arity:7,name:"list-members",qname:"mailchimp:list-members",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $status as xs:string, $since as xs:string, $start as xs:integer, $limit as xs:integer) as item()*",description:" Get all of the list members for a list that are of a particular status.\n",summary:"<p> Get all of the list members for a list that are of a particular status.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"status",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the status to get members for - one of(subscribed, unsubscribed, <a target="_blank" href="http://eepurl.com/dwk1">cleaned</a>, updated), defaults to subscribed</div>'},{name:"since",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional pull all members whose status (subscribed/unsubscribed/cleaned) has changed or whose profile (updated) has changed since this date/time (in GMT) - format is YYYY-MM-DD HH:mm:ss (24hr)</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the page number to start at - defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for large data sets, the number of results to return - defaults to 100, upper limit set at 15000</div>'}],returns:{type:"item()*",description:"Array of a the total records match and matching list member data for this page (see Returned Fields for details)"},errors:[]},{isDocumented:!0,arity:5,name:"list-merge-var-add",qname:"mailchimp:list-merge-var-add",signature:"($apikey as xs:string, $id as xs:string, $tag as xs:string, $name as xs:string, $options as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-merge-var-add-6">list-merge-var-add#6</a>.\n',summary:"<p> Convenience function for  list-merge-var-add#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"tag",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The merge tag to add, e.g. FNAME</div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The long description of the tag being added, used for user displays</div>'},{name:"options",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional Various options for this merge var. <em>note:</em> for historical purposes this can also take a "boolean"</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:6,name:"list-merge-var-add",qname:"mailchimp:list-merge-var-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $tag as xs:string, $name as xs:string, $options as element(array)) as item()*",description:" Add a new merge tag to a given list.\n",summary:"<p> Add a new merge tag to a given list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"tag",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The merge tag to add, e.g. FNAME</div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The long description of the tag being added, used for user displays</div>'},{name:"options",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional Various options for this merge var. <em>note:</em> for historical purposes this can also take a "boolean"</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:3,name:"list-merge-var-del",qname:"mailchimp:list-merge-var-del",signature:"($apikey as xs:string, $id as xs:string, $tag as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-merge-var-del-4">list-merge-var-del#4</a>.\n',summary:"<p> Convenience function for  list-merge-var-del#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"tag",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The merge tag to delete</div>'}],returns:{type:"item()*",description:"bool true if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:4,name:"list-merge-var-del",qname:"mailchimp:list-merge-var-del",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $tag as xs:string) as item()*",description:" Delete a merge tag from a given list and all its members. Seriously - the data is removed from all members as well! Note that on large lists this method may seem a bit slower than calls you typically make.\n",summary:"<p> Delete a merge tag from a given list and all its members.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"tag",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The merge tag to delete</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:4,name:"list-merge-var-update",qname:"mailchimp:list-merge-var-update",signature:"($apikey as xs:string, $id as xs:string, $tag as xs:string, $options as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-merge-var-update-5">list-merge-var-update#5</a>.\n',summary:"<p> Convenience function for  list-merge-var-update#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"tag",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The merge tag to update</div>'},{name:"options",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The options to change for a merge var. See <a href="#list-merge-var-add-5">list-merge-var-add()</a> for valid options</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:5,name:"list-merge-var-update",qname:"mailchimp:list-merge-var-update",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $tag as xs:string, $options as element(array)) as item()*",description:" Update most parameters for a merge tag on a given list. You cannot currently change the merge type.\n",summary:"<p> Update most parameters for a merge tag on a given list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"tag",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The merge tag to update</div>'},{name:"options",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The options to change for a merge var. See <a href="#list-merge-var-add-5">list-merge-var-add()</a> for valid options</div>'}],returns:{type:"item()*",description:"True if the request succeeds, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:2,name:"list-merge-vars",qname:"mailchimp:list-merge-vars",signature:"($apikey as xs:string, $id as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-merge-vars-3">list-merge-vars#3</a>.\n',summary:"<p> Convenience function for  list-merge-vars#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"List of merge tags for the list"},errors:[]},{isDocumented:!0,arity:3,name:"list-merge-vars",qname:"mailchimp:list-merge-vars",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string) as item()*",description:" Get the list of merge tags for a given list, including their name, tag, and required setting.\n",summary:"<p> Get the list of merge tags for a given list, including their name, tag, and required setting.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"List of merge tags for the list"},errors:[]},{isDocumented:!0,arity:3,name:"list-static-segment-add",qname:"mailchimp:list-static-segment-add",signature:"($apikey as xs:string, $id as xs:string, $name as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-static-segment-add-4">list-static-segment-add#4</a>.\n',summary:"<p> Convenience function for  list-static-segment-add#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a unique name per list for the segment - 50 byte maximum length, anything longer will throw an error</div>'}],returns:{type:"item()*",description:"The id of the new segment, otherwise an error will be thrown."},errors:[]},{isDocumented:!0,arity:4,name:"list-static-segment-add",qname:"mailchimp:list-static-segment-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $name as xs:string) as item()*",description:' Save a segment against a list for later use. There is no limit to the number of segments which can be saved. Static Segments <strong xmlns:xqdoc="http://www.xqdoc.org/1.0">are not</strong> tied to any merge data, interest groups, etc. They essentially allow you to configure an unlimited number of custom segments which will have standard performance. When using proper segments, Static Segments are one of the available options for segmentation just as if you used a merge var (and they can be used with other segmentation options), though performance may degrade at that point.\n',summary:"<p> Save a segment against a list for later use.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a unique name per list for the segment - 50 byte maximum length, anything longer will throw an error</div>'}],returns:{type:"item()*",description:"The id of the new segment, otherwise an error will be thrown."},errors:[]},{isDocumented:!0,arity:3,name:"list-static-segment-del",qname:"mailchimp:list-static-segment-del",signature:"($apikey as xs:string, $id as xs:string, $seg_id as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#listStaticSegmentDel-4">list-static-segment-del#4</a>.\n',summary:"<p> Convenience function for  list-static-segment-del#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"seg_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the static segment to delete - get from <a href="#list-static-segments-2">list-static-segments()</a></div>'}],returns:{type:"item()*",description:"True if it worked, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:4,name:"list-static-segment-del",qname:"mailchimp:list-static-segment-del",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $seg_id as xs:integer) as item()*",description:" Delete a static segment. Note that this will, of course, remove any member affiliations with the segment.\n",summary:"<p> Delete a static segment.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"seg_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the static segment to delete - get from <a href="#list-static-segments-2">list-static-segments()</a></div>'}],returns:{type:"item()*",description:"True if it worked, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:4,name:"list-static-segment-members-add",qname:"mailchimp:list-static-segment-members-add",signature:"($apikey as xs:string, $id as xs:string, $seg_id as xs:integer, $batch as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-static-segment-members-add-5">list-static-segment-members-add#5</a>.\n',summary:"<p> Convenience function for  list-static-segment-members-add#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"seg_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the static segment to modify - get from <a href="#list-static-segments-2">list-static-segments()</a></div>'},{name:"batch",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of email addresses and/or unique_ids to add to the segment</div>'}],returns:{type:"item()*",description:"An array with the results of the operation"},errors:[]},{isDocumented:!0,arity:5,name:"list-static-segment-members-add",qname:"mailchimp:list-static-segment-members-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $seg_id as xs:integer, $batch as element(array)) as item()*",description:' Add list members to a static segment. It is suggested that you limit batch size to no more than 10,000 addresses per call. Email addresses must exist on the list in order to be included - this <strong xmlns:xqdoc="http://www.xqdoc.org/1.0">will not</strong> subscribe them to the list!.\n',summary:"<p> Add list members to a static segment.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"seg_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the static segment to modify - get from <a href="#list-static-segments-2">list-static-segments()</a></div>'},{name:"batch",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of email addresses and/or unique_ids to add to the segment</div>'}],returns:{type:"item()*",description:"array an array with the results of the operation"},errors:[]},{isDocumented:!0,arity:4,name:"list-static-segment-members-del",qname:"mailchimp:list-static-segment-members-del",signature:"($apikey as xs:string, $id as xs:string, $seg_id as xs:integer, $batch as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-static-segment-members-del-5">list-static-segment-members-del#5</a>.\n',summary:"<p> Convenience function for  list-static-segment-members-del#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"seg_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the static segment to delete - get from <a href="#list-static-segments-2">list-static-segments()</a></div>'},{name:"batch",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of email addresses and/or unique_ids to remove from the segment</div>'}],returns:{type:"item()*",description:"An array with the results of the operation"},errors:[]},{isDocumented:!0,arity:5,name:"list-static-segment-members-del",qname:"mailchimp:list-static-segment-members-del",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $seg_id as xs:integer, $batch as element(array)) as item()*",description:' Remove list members from a static segment. It is suggested that you limit batch size to no more than 10,000 addresses per call. Email addresses must exist on the list in order to be removed - this <strong xmlns:xqdoc="http://www.xqdoc.org/1.0">will not</strong> unsubscribe them from the list!.\n',summary:"<p> Remove list members from a static segment.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"seg_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the static segment to delete - get from <a href="#list-static-segments-2">list-static-segments()</a></div>'},{name:"batch",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an array of email addresses and/or unique_ids to remove from the segment</div>'}],returns:{type:"item()*",description:"An array with the results of the operation"},errors:[]},{isDocumented:!0,arity:3,name:"list-static-segment-reset",qname:"mailchimp:list-static-segment-reset",signature:"($apikey as xs:string, $id as xs:string, $seg_id as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-static-segment-reset-4">list-static-segment-reset#4</a>.\n',summary:"<p> Convenience function for  list-static-segment-reset#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"seg_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the static segment to reset - get from <a href="#list-static-segments-2">list-static-segments()</a></div>'}],returns:{type:"item()*",description:"True if it worked, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:4,name:"list-static-segment-reset",qname:"mailchimp:list-static-segment-reset",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $seg_id as xs:integer) as item()*",description:' Resets a static segment - removes <strong xmlns:xqdoc="http://www.xqdoc.org/1.0">all</strong> members from the static segment. Note: does not actually affect list member data.\n',summary:"<p> Resets a static segment - removes  all  members from the static segment.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"seg_id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the static segment to reset - get from <a href="#list-static-segments-2">list-static-segments()</a></div>'}],returns:{type:"item()*",description:"True if it worked, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:2,name:"list-static-segments",qname:"mailchimp:list-static-segments",signature:"($apikey as xs:string, $id as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-static-segments-3">list-static-segments#3</a>.\n',summary:"<p> Convenience function for  list-static-segments#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"An array of parameters for each static segment"},errors:[]},{isDocumented:!0,arity:3,name:"list-static-segments",qname:"mailchimp:list-static-segments",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string) as item()*",description:" Retrieve all of the Static Segments for a list.\n",summary:"<p> Retrieve all of the Static Segments for a list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"An array of parameters for each static segment"},errors:[]},{isDocumented:!0,arity:10,name:"list-subscribe",qname:"mailchimp:list-subscribe",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $email_address as xs:string, $merge_vars as element(array), $email_type as xs:string, $double_optin as xs:boolean, $update_existing as xs:boolean, $replace_interests as xs:boolean, $send_welcome as xs:boolean) as item()*",description:" Subscribe the provided email to a list.\n",summary:"<p> Subscribe the provided email to a list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address to subscribe</div>'},{name:"merge_vars",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional merges for the email (FNAME, LNAME, etc.) (see examples below for handling "blank" arrays). Note that a merge field can only hold up to 255 bytes. Also, there are a few "special" keys. See <a href="http://apidocs.mailchimp.com/rtfm/listsubscribe.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"email_type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional email type preference for the email (html, text, or mobile defaults to html)</div>'},{name:"double_optin",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional flag to control whether a double opt-in confirmation message is sent, defaults to true. <em>Abusing this may cause your account to be suspended.</em></div>'},{name:"update_existing",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional flag to control whether a existing subscribers should be updated instead of throwing and error, defaults to false</div>'},{name:"replace_interests",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional flag to determine whether we replace the interest groups with the groups provided, or we add the provided groups to the member\'s interest groups (optional, defaults to true)</div>'},{name:"send_welcome",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional if your double_optin is false and this is true, we will send your lists Welcome Email if this subscribe succeeds - this will *not* fire if we end up updating an existing subscriber. If double_optin is true, this has no effect. defaults to false.</div>'}],returns:{type:"item()*",description:"True on success, false on failure."},errors:[]},{isDocumented:!0,arity:9,name:"list-subscribe",qname:"mailchimp:list-subscribe",signature:"($apikey as xs:string, $id as xs:string, $email_address as xs:string, $merge_vars as element(array), $email_type as xs:string, $double_optin as xs:boolean, $update_existing as xs:boolean, $replace_interests as xs:boolean, $send_welcome as xs:boolean) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-subscribe-10">list-subscribe#10</a>.\n',summary:"<p> Convenience function for  list-subscribe#10 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address to subscribe</div>'},{name:"merge_vars",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional merges for the email (FNAME, LNAME, etc.) (see examples below for handling "blank" arrays). Note that a merge field can only hold up to 255 bytes. Also, there are a few "special" keys. See <a href="http://apidocs.mailchimp.com/rtfm/listsubscribe.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"email_type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional email type preference for the email (html, text, or mobile defaults to html)</div>'},{name:"double_optin",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional flag to control whether a double opt-in confirmation message is sent, defaults to true. <em>Abusing this may cause your account to be suspended.</em></div>'},{name:"update_existing",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional flag to control whether a existing subscribers should be updated instead of throwing and error, defaults to false</div>'},{name:"replace_interests",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional flag to determine whether we replace the interest groups with the groups provided, or we add the provided groups to the member\'s interest groups (optional, defaults to true)</div>'},{name:"send_welcome",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional if your double_optin is false and this is true, we will send your lists Welcome Email if this subscribe succeeds - this will *not* fire if we end up updating an existing subscriber. If double_optin is true, this has no effect. defaults to false.</div>'}],returns:{type:"item()*",description:"True on success, false on failure."},errors:[]},{isDocumented:!0,arity:6,name:"list-unsubscribe",qname:"mailchimp:list-unsubscribe",signature:"($apikey as xs:string, $id as xs:string, $email_address as xs:string, $delete_member as xs:boolean, $send_goodbye as xs:boolean, $send_notify as xs:boolean) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-unsubscribe-7">list-unsubscribe#7</a>.\n',summary:"<p> Convenience function for  list-unsubscribe#7 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address to unsubscribe OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns</div>'},{name:"delete_member",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to completely delete the member from your list instead of just unsubscribing, default to false</div>'},{name:"send_goodbye",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to send the goodbye email to the email address, defaults to true</div>'},{name:"send_notify",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to send the unsubscribe notification email to the address defined in the list email notification settings, defaults to true</div>'}],returns:{type:"item()*",description:"True on success, false on failure."},errors:[]},{isDocumented:!0,arity:7,name:"list-unsubscribe",qname:"mailchimp:list-unsubscribe",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $email_address as xs:string, $delete_member as xs:boolean, $send_goodbye as xs:boolean, $send_notify as xs:boolean) as item()*",description:" Unsubscribe the given email address from the list.\n",summary:"<p> Unsubscribe the given email address from the list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address to unsubscribe OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns</div>'},{name:"delete_member",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to completely delete the member from your list instead of just unsubscribing, default to false</div>'},{name:"send_goodbye",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to send the goodbye email to the email address, defaults to true</div>'},{name:"send_notify",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to send the unsubscribe notification email to the address defined in the list email notification settings, defaults to true</div>'}],returns:{type:"item()*",description:"True on success, false on failure."},errors:[]},{isDocumented:!0,arity:6,name:"list-update-member",qname:"mailchimp:list-update-member",signature:"($apikey as xs:string, $id as xs:string, $email_address as xs:string, $merge_vars as element(array), $email_type as xs:string, $replace_interests as xs:boolean) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-update-member-7">list-update-member#7</a>.\n',summary:"<p> Convenience function for  list-update-member#7 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the current email address of the member to update OR the "id" for the member returned from listMemberInfo, Webhooks, and Campaigns</div>'},{name:"merge_vars",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> array of new field values to update the member with. See merge_vars in <a href="#list-subscribe-10">list-subscribe()</a> for details.</div>'},{name:"email_type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> change the email type preference for the member ("html", "text", or "mobile"). Leave blank to keep the existing preference (optional)</div>'},{name:"replace_interests",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to determine whether we replace the interest groups with the updated groups provided, or we add the provided groups to the member\'s interest groups (optional, defaults to true)</div>'}],returns:{type:"item()*",description:"True on success, false on failure."},errors:[]},{isDocumented:!0,arity:7,name:"list-update-member",qname:"mailchimp:list-update-member",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $email_address as xs:string, $merge_vars as element(array), $email_type as xs:string, $replace_interests as xs:boolean) as item()*",description:' Edit the email address, merge fields, and interest groups for a list member. If you are doing a batch update on lots of users, consider using <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-batch-subscribe-6">#list-batch-subscribe()</a> with the update_existing and possible replace_interests parameter.\n',summary:"<p> Edit the email address, merge fields, and interest groups for a list member.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the current email address of the member to update OR the "id" for the member returned from listMemberInfo, Webhooks, and Campaigns</div>'},{name:"merge_vars",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> array of new field values to update the member with. See merge_vars in <a href="#list-subscribe-10">list-subscribe()</a> for details.</div>'},{name:"email_type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> change the email type preference for the member ("html", "text", or "mobile"). Leave blank to keep the existing preference (optional)</div>'},{name:"replace_interests",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> flag to determine whether we replace the interest groups with the updated groups provided, or we add the provided groups to the member\'s interest groups (optional, defaults to true)</div>'}],returns:{type:"item()*",description:"True on success, false on failure."},errors:[]},{isDocumented:!0,arity:5,name:"list-webhook-add",qname:"mailchimp:list-webhook-add",signature:"($apikey as xs:string, $id as xs:string, $url as xs:string, $actions as element(array), $sources as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-webhook-add-6">list-webhook-add#6</a>.\n',summary:"<p> Convenience function for  list-webhook-add#6 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid URL for the Webhook - it will be validated. note that a url may only exist on a list once.</div>'},{name:"actions",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional a hash of actions to fire this Webhook for</div>'},{name:"sources",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional a hash of sources to fire this Webhook for</div>'}],returns:{type:"item()*",description:"True if the call succeeds, otherwise an exception will be thrown"},errors:[]},{isDocumented:!0,arity:6,name:"list-webhook-add",qname:"mailchimp:list-webhook-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $url as xs:string, $actions as element(array), $sources as element(array)) as item()*",description:" Add a new Webhook URL for the given list.\n",summary:"<p> Add a new Webhook URL for the given list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid URL for the Webhook - it will be validated. note that a url may only exist on a list once.</div>'},{name:"actions",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional a hash of actions to fire this Webhook for</div>'},{name:"sources",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional a hash of sources to fire this Webhook for</div>'}],returns:{type:"item()*",description:"True if the call succeeds, otherwise an exception will be thrown"},errors:[]},{isDocumented:!0,arity:3,name:"list-webhook-del",qname:"mailchimp:list-webhook-del",signature:"($apikey as xs:string, $id as xs:string, $url as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-webhook-del-4">list-webhook-del#4</a>.\n',summary:"<p> Convenience function for  list-webhook-del#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URL of a Webhook on this list</div>'}],returns:{type:"item()*",description:"True if the call succeeds, otherwise an exception will be thrown"},errors:[]},{isDocumented:!0,arity:4,name:"list-webhook-del",qname:"mailchimp:list-webhook-del",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string, $url as xs:string) as item()*",description:" Delete an existing Webhook URL from a given list.\n",summary:"<p> Delete an existing Webhook URL from a given list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'},{name:"url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URL of a Webhook on this list</div>'}],returns:{type:"item()*",description:"True if the call succeeds, otherwise an exception will be thrown"},errors:[]},{isDocumented:!0,arity:2,name:"list-webhooks",qname:"mailchimp:list-webhooks",signature:"($apikey as xs:string, $id as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#list-webhooks-3">list-webhooks#3</a>.\n',summary:"<p> Convenience function for  list-webhooks#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"List of webhooks"},errors:[]},{isDocumented:!0,arity:3,name:"list-webhooks",qname:"mailchimp:list-webhooks",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:string) as item()*",description:" Return the Webhooks configured for the given list.\n",summary:"<p> Return the Webhooks configured for the given list.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list id to connect to. Get by calling <a href="#lists-4">lists()</a></div>'}],returns:{type:"item()*",description:"List of webhooks"},errors:[]},{isDocumented:!0,arity:2,name:"lists-for-email",qname:"mailchimp:lists-for-email",signature:"($apikey as xs:string, $email_address as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#lists-for-email-3">lists-for-email#3</a>.\n',summary:"<p> Convenience function for  lists-for-email#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address to check OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns</div>'}],returns:{type:"item()*",description:"An array of list_ids the member is subscribed to."},errors:[]},{isDocumented:!0,arity:3,name:"lists-for-email",qname:"mailchimp:lists-for-email",signature:"($endpoint-url as xs:string, $apikey as xs:string, $email_address as xs:string) as item()*",description:" Retrieve all List Ids a member is subscribed to.\n",summary:"<p> Retrieve all List Ids a member is subscribed to.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"email_address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the email address to check OR the email "id" returned from listMemberInfo, Webhooks, and Campaigns</div>'}],returns:{type:"item()*",description:"An array of list_ids the member is subscribed to."},errors:[]},{isDocumented:!0,arity:4,name:"lists",qname:"mailchimp:lists",signature:"($apikey as xs:string, $filters as element(array), $start as xs:integer, $limit as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#lists-5">lists#5</a>.\n',summary:"<p> Convenience function for  lists#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"filters",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hash of filters to apply to this query - all are optional. See <a href="http://apidocs.mailchimp.com/rtfm/lists.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - control paging of lists, start results at this list #, defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - control paging of lists, number of lists to return with each call, defaults to 25 (max=100)</div>'}],returns:{type:"item()*",description:"Array with keys listed in Returned Fields below"},errors:[]},{isDocumented:!0,arity:5,name:"lists",qname:"mailchimp:lists",signature:"($endpoint-url as xs:string, $apikey as xs:string, $filters as element(array), $start as xs:integer, $limit as xs:integer) as item()*",description:" Retrieve all of the lists defined for your user account.\n",summary:"<p> Retrieve all of the lists defined for your user account.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"filters",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hash of filters to apply to this query - all are optional. See <a href="http://apidocs.mailchimp.com/rtfm/lists.func.php">Mailchimp API documentation</a> for more information about the parameter structure.</div>'},{name:"start",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - control paging of lists, start results at this list #, defaults to 1st page of data (page 0)</div>'},{name:"limit",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional - control paging of lists, number of lists to return with each call, defaults to 25 (max=100)</div>'}],returns:{type:"item()*",description:"Array with keys listed in Returned Fields below"},errors:[]},{isDocumented:!0,arity:1,name:"ping",qname:"mailchimp:ping",signature:"($apikey as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#ping-2">ping#2</a>.\n',summary:"<p> Convenience function for  ping#2 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""}],returns:{type:"item()*",description:'Returns "Everything\'s Chimpy!" if everything is chimpy, otherwise returns an error message'},errors:[]},{isDocumented:!0,arity:2,name:"ping",qname:"mailchimp:ping",signature:"($endpoint-url as xs:string, $apikey as xs:string) as item()*",description:' "Ping" the MailChimp API - a simple method you can call that will return a constant value as long as everything is good. Note than unlike most all of our methods, we don\'t throw an Exception if we are having issues. You will simply receive a different string back that will explain our view on what is going on.\n',summary:'<p> "Ping" the MailChimp API - a simple method you can call that will return a constant value as long as everything is good.</p>',annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'}],returns:{type:"item()*",description:'Returns "Everything\'s Chimpy!" if everything is chimpy, otherwise returns an error message'},errors:[]},{isDocumented:!0,arity:3,name:"template-add",qname:"mailchimp:template-add",signature:"($apikey as xs:string, $name as xs:string, $html as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#template-add-4">template-add#4</a>.\n',summary:"<p> Convenience function for  template-add#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name for the template - names must be unique and a max of 50 bytes</div>'},{name:"html",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a string specifying the entire template to be created. This is <strong>NOT</strong> campaign content. They are intended to utilize our <a href="http://www.mailchimp.com/resources/email-template-language/" target="_blank">template language</a>.</div>'}],returns:{type:"item()*",description:"The new template id, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:4,name:"template-add",qname:"mailchimp:template-add",signature:"($endpoint-url as xs:string, $apikey as xs:string, $name as xs:string, $html as xs:string) as item()*",description:' Create a new user template, <strong xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT</strong> campaign content. These templates can then be applied while creating campaigns.\n',summary:"<p> Create a new user template,  NOT  campaign content.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name for the template - names must be unique and a max of 50 bytes</div>'},{name:"html",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a string specifying the entire template to be created. This is <strong>NOT</strong> campaign content. They are intended to utilize our <a href="http://www.mailchimp.com/resources/email-template-language/" target="_blank">template language</a>.</div>'}],returns:{type:"item()*",description:"The new template id, otherwise an error is thrown."},errors:[]},{isDocumented:!0,arity:2,name:"template-del",qname:"mailchimp:template-del",signature:"($apikey as xs:string, $id as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#template-del-3">template-del#3</a>.\n',summary:"<p> Convenience function for  template-del#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the user template to delete</div>'}],returns:{type:"item()*",description:"True if the template was deleted, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:3,name:"template-del",qname:"mailchimp:template-del",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:integer) as item()*",description:" Delete (deactivate) a user template.\n",summary:"<p> Delete (deactivate) a user template.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the user template to delete</div>'}],returns:{type:"item()*",description:"True if the template was deleted, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:3,name:"template-info",qname:"mailchimp:template-info",signature:"($apikey as xs:string, $tid as xs:integer, $type as xs:string) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#template-info-4">template-info#4</a>.\n',summary:"<p> Convenience function for  template-info#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"tid",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the template id - get from templates()</div>'},{name:"type",type:"xs:string",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> the template type to load - one of 'user', 'gallery', 'base'</div>"}],returns:{type:"item()*",description:"An array of info to be used when editing"},errors:[]},{isDocumented:!0,arity:4,name:"template-info",qname:"mailchimp:template-info",signature:"($endpoint-url as xs:string, $apikey as xs:string, $tid as xs:integer, $type as xs:string) as item()*",description:" Pull details for a specific template to help support editing.\n",summary:"<p> Pull details for a specific template to help support editing.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"tid",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the template id - get from templates()</div>'},{name:"type",type:"xs:string",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> the template type to load - one of 'user', 'gallery', 'base'</div>"}],returns:{type:"item()*",description:"An array of info to be used when editing"},errors:[]},{isDocumented:!0,arity:2,name:"template-undel",qname:"mailchimp:template-undel",signature:"($apikey as xs:string, $id as xs:integer) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#template-undel-3">template-undel#3</a>.\n',summary:"<p> Convenience function for  template-undel#3 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the user template to reactivate</div>'}],returns:{type:"item()*",description:"boolean true if the template was deleted, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:3,name:"template-undel",qname:"mailchimp:template-undel",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:integer) as item()*",description:" Undelete (reactivate) a user template.\n",summary:"<p> Undelete (reactivate) a user template.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the user template to reactivate</div>'}],returns:{type:"item()*",description:"boolean true if the template was deleted, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:3,name:"template-update",qname:"mailchimp:template-update",signature:"($apikey as xs:string, $id as xs:integer, $values as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#template-update-4">template-update#4</a>.\n',summary:"<p> Convenience function for  template-update#4 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the user template to update</div>'},{name:"values",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> s the values to updates - while both are optional, at least one should be provided. Both can be updated at the same time.</div>'}],returns:{type:"item()*",description:"True if the template was updated, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:4,name:"template-update",qname:"mailchimp:template-update",signature:"($endpoint-url as xs:string, $apikey as xs:string, $id as xs:integer, $values as element(array)) as item()*",description:' Replace the content of a user template, <strong xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT</strong> campaign content.\n',summary:"<p> Replace the content of a user template,  NOT  campaign content.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"id",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the user template to update</div>'},{name:"values",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> s the values to updates - while both are optional, at least one should be provided. Both can be updated at the same time.</div>'}],returns:{type:"item()*",description:"True if the template was updated, otherwise an error will be thrown"},errors:[]},{isDocumented:!0,arity:4,name:"templates",qname:"mailchimp:templates",signature:"($apikey as xs:string, $types as element(array), $category as xs:string, $inactives as element(array)) as item()*",description:' Convenience function for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#templates-5">templates#5</a>.\n',summary:"<p> Convenience function for  templates#5 .</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"apikey",type:"xs:string",occurrence:null,description:""},{name:"types",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the types of templates to return</div>'},{name:"category",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for Gallery templates only, limit to a specific template category</div>'},{name:"inactives",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional options to control how inactive templates are returned, if at all</div>'}],returns:{type:"item()*",description:"An array of structs, one for each template (see Returned Fields for details)"},errors:[]},{isDocumented:!0,arity:5,name:"templates",qname:"mailchimp:templates",signature:"($endpoint-url as xs:string, $apikey as xs:string, $types as element(array), $category as xs:string, $inactives as element(array)) as item()*",description:' Retrieve various templates available in the system, allowing some thing similar to our template gallery to be created. boolean user Customer template for this user account. Defaults to true. boolean gallery Templates from our Gallery. Note that some templates that require extra configuration are withheld. (eg, the Etsy template). Defaults to false. boolean base Our "start from scratch" extremely basic templates boolean include user templates are not deleted, only set inactive. defaults to false. boolean only only include inactive templates. defaults to false.\n',summary:"<p> Retrieve various templates available in the system, allowing some thing similar to our template gallery to be created.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Mailchimp endpoint URL, e.g. http://us1.api.mailchimp.com/1.3/</div>'},{name:"apikey",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a valid API Key for your user account. Get by visiting <a href="http://admin.mailchimp.com/account/api" target="_blank">your API dashboard</a></div>'},{name:"types",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional the types of templates to return</div>'},{name:"category",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional for Gallery templates only, limit to a specific template category</div>'},{name:"inactives",type:"element(array)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> optional options to control how inactive templates are returned, if at all</div>'}],returns:{type:"item()*",description:"An array of structs, one for each template (see Returned Fields for details)"},errors:[]}],variables:[{name:"mailchimp:gateway",type:"item()*",description:" Mailchimp gateway where the client data is stored.\n"},{name:"mailchimp:version",type:"item()*",description:" Mailchimp API version.\n"},{name:"mailchimp:endpoint",type:"item()*",description:" Endpoint URL for the XML-RPC requests.\n"}]},"http://www.zorba-xquery.com/modules/couchbase":{ns:"http://www.zorba-xquery.com/modules/couchbase",description:" This module provides minimal functionality to interact with the\n Couchbase NoSQL database.\n The module is built using the libcouchbase C client library and\n exposes most of its functionality in XQuery with JSONiq extensions.\n Beyond just allowing for basic key-value store operations (e.g.\n put-/get-text or put-/get-binary, this module also allows to work\n with Couchbase views in order to allow for complex JSON query\n operations.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Juan Zacarias</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.zorba-xquery.com/modules/couchbase",prefix:"cb"},{uri:"http://jsoniq.org/functions",prefix:"jn"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"connect",qname:"cb:connect",signature:"($options as object()) as xs:anyURI external",description:" Connect to the Couchbase server and return an opaque identifier\n representing the established connection.\n",summary:"<p> Connect to the Couchbase server and return an opaque identifier\n representing the established connection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a JSONiq object that contains the host, bucket, and user information.</div>'}],returns:{type:"xs:anyURI",description:'an identifier for the established connection. Example: <code xmlns:xqdoc="http://www.xqdoc.org/1.0"> { "host": "localhost:8091", "username" : null, "password" : null, "bucket" : "default" } </code>'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0001 if the connection to the given host/bucket could not be established.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0001 if mandatory connection information is missing.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0007 if a given option is not supported.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"connect",qname:"cb:connect",signature:"($host as xs:string, $username as xs:string?, $password as xs:string?, $bucket as xs:string) as xs:anyURI",description:" Connect to the Couchbase server and return an opaque identifier\n representing the established connection.\n",summary:"<p> Connect to the Couchbase server and return an opaque identifier\n representing the established connection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> address of the couchbase server (e.g. "localhost:8091")</div>'},{name:"username",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> username used for the connection</div>'},{name:"password",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> password used for the connection</div>'},{name:"bucket",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> name of the bucket to use (e.g. "default")</div>'}],returns:{type:"xs:anyURI",description:"an identifier for the established connection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0001 if the connection to the given host/bucket could not be established.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"create-view",qname:"cb:create-view",signature:"($db as xs:anyURI, $doc-name as xs:string, $view-names as xs:string*) as xs:string* external",description:" Create a document/view.\n If the document already exists, it is replaced. A document can hold several\n views that must be specified in the same call of cb:create-view.\n",summary:"<p> Create a document/view.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"doc-name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> name of the document to create.</div>'},{name:"view-names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> names of the views to create in the document.</div>'}],returns:{type:"xs:string*",description:"the names of the paths for the views that have been created."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"create-view",qname:"cb:create-view",signature:"($db as xs:anyURI, $doc-name as xs:string, $view-names as xs:string*, $options as object()*) as xs:string* external",description:" Create a document/view.\n If the document already exists, it is replaced. A document can hold several\n views that must be specified in the same call of cb:create-view.\n",summary:"<p> Create a document/view.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"doc-name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> name of the document to create.</div>'},{name:"view-names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> names of the views to create in the document.</div>'},{name:"options",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> options describing how to create the view.</div>'}],returns:{type:"xs:string*",description:"the names of the paths for the views that have been created."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0005 if the number of options doesn\'t match the number of view-names.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0010 if any of the given options has an invalid type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete-view",qname:"cb:delete-view",signature:"($db as xs:anyURI, $doc as xs:string*) as xs:string* external",description:" Delete a document/view.\n If the document doesn't exists, function does nothing. All the views hold in the\n Document are deleted, this function can't delete single views.\n",summary:"<p> Delete a document/view.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"doc",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0">-name name of the document to create.</div>'}],returns:{type:"xs:string*",description:"empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"flush",qname:"cb:flush",signature:"($db as xs:anyURI) as empty-sequence() external",description:" Remove all key/value pairs from the cluster\n",summary:"<p> Remove all key/value pairs from the cluster\n</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"get-binary",qname:"cb:get-binary",signature:"($db as xs:anyURI, $key as xs:string*) as xs:base64Binary* external",description:" Return the values of the given keys (type xs:string) as base64Binary.\n",summary:"<p> Return the values of the given keys (type xs:string) as base64Binary.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the requested keys</div>'}],returns:{type:"xs:base64Binary*",description:"a sequence of xs:base64Binary items for the given keys."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"get-binary",qname:"cb:get-binary",signature:"($db as xs:anyURI, $key as xs:string*, $options as object()) as xs:base64Binary* external",description:" Return the values of the given keys (type xs:string) as base64Binary.\n",summary:"<p> Return the values of the given keys (type xs:string) as base64Binary.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the requested keys</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> JSONiq object with additional options</div>'}],returns:{type:"xs:base64Binary*",description:"a sequence of xs:base64Binary items for the given keys."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0009 if the given expiration time is not an xs:integer.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"get-text",qname:"cb:get-text",signature:"($db as xs:anyURI, $key as xs:string*) as xs:string* external",description:" Return the values of the given keys (type xs:string) as string.\n",summary:"<p> Return the values of the given keys (type xs:string) as string.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the requested keys</div>'}],returns:{type:"xs:string*",description:"A sequence of string Items corresponding to the key"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"get-text",qname:"cb:get-text",signature:"($db as xs:anyURI, $key as xs:string*, $options as object()) as xs:string* external",description:" Return the values of the given keys (type xs:string) as string.\n",summary:"<p> Return the values of the given keys (type xs:string) as string.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the requested keys</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> JSONiq object with additional options</div>'}],returns:{type:"xs:string*",description:"a sequence of strings for the given keys."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0006 if the given encoding is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0009 if the given expiration time is not an xs:integer.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"put-binary",qname:"cb:put-binary",signature:"($db as xs:anyURI, $key as xs:string*, $value as xs:base64Binary*) as empty-sequence()",description:" Store the given key-value bindings.\n",summary:"<p> Store the given key-value bindings.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the keys to store</div>'},{name:"value",type:"xs:base64Binary",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the values (as xs:base64binary) to be stored.</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0005 if the number of keys doesn\'t match the number of values.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"put-binary",qname:"cb:put-binary",signature:"($db as xs:anyURI, $key as xs:string*, $value as xs:base64Binary*, $options as object()) as empty-sequence() external",description:" Store the given key-value bindings.\n",summary:"<p> Store the given key-value bindings.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the keys to store</div>'},{name:"value",type:"xs:base64Binary",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the values (as xs:base64binary) to be stored.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> JSONiq object with additional options</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0005 if the number of keys doesn\'t match the number of values.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0009 if the given expiration time is not an xs:integer.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0011 if the stored Variable was not stored</xqdoc:error>']},{isDocumented:!0,arity:3,name:"put-text",qname:"cb:put-text",signature:"($db as xs:anyURI, $key as xs:string*, $value as xs:string*) as empty-sequence()",description:" Store the given key-value bindings.\n The values are stored with the UTF-8 encoding and a default\n expiration time of 60 seconds.\n",summary:"<p> Store the given key-value bindings.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the keys to store</div>'},{name:"value",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the values (as xs:string) to be stored.</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0005 if the number of keys doesn\'t match the number of values.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"put-text",qname:"cb:put-text",signature:"($db as xs:anyURI, $key as xs:string*, $value as xs:string*, $options as object()) as empty-sequence() external",description:" Store the given key-value bindings.\n",summary:"<p> Store the given key-value bindings.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the keys to store</div>'},{name:"value",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the values (as xs:string) to be stored.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> JSONiq object with additional options</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0005 if the number of keys doesn\'t match the number of values.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0006 if the given encoding is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0007 if any of the options is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0009 if the given expiration time is not an xs:integer.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0011 if the stored Variable was not stored</xqdoc:error>']},{isDocumented:!0,arity:2,name:"remove",qname:"cb:remove",signature:"($db as xs:anyURI, $key as xs:string*) as empty-sequence() external",description:" Remove the values matching the given keys (xs:string) from the server.\n",summary:"<p> Remove the values matching the given keys (xs:string) from the server.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the keys of the values that should be removed.</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"touch",qname:"cb:touch",signature:"($db as xs:anyURI, $key as xs:string*, $exp-time as xs:integer) as empty-sequence() external",description:" Refresh the expiration time of the given keys.\n",summary:"<p> Refresh the expiration time of the given keys.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"key",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the keys to touch</div>'},{name:"exp-time",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> new expieration time in seconds</div>'}],returns:{type:"empty-sequence()",description:"a empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"view",qname:"cb:view",signature:"($db as xs:anyURI, $path as xs:string*) as object()*",description:" Retrieve the content of existing views.\n",summary:"<p> Retrieve the content of existing views.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"path",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> contains the string of a view path (e.g. "_design/test/_view/vies").</div>'}],returns:{type:"object()*",description:"a sequence of strings (as JSON) containing information of the views."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"view",qname:"cb:view",signature:"($db as xs:anyURI, $path as xs:string*, $options as object()) as object()*",description:" Retrieve the content of existing views.\n",summary:"<p> Retrieve the content of existing views.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"db",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> connection reference</div>'},{name:"path",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> contains the string of a view path (e.g. "_design/test/_view/vies").</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> JSONiq object with additional options</div>'}],returns:{type:"object()*",description:"a sequence of strings (as JSON) containing information of the views."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:LCB0002 if any error occurs in the communication with the server.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cb:CB0007 if any of the options is not supported.</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/excel/text":{ns:"http://zorba.io/modules/excel/text",description:" This is a library module offering the same set of functions\n defined by Microsoft Excel, under Text and Data Functions.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://office.microsoft.com/en-us/excel/CH062528321033.aspx" target="_blank">Excel Documentation: Text Functions</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Sorin Nasoi</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/modules/excel/math",prefix:"excel-math"},{uri:"http://zorba.io/modules/excel/text",prefix:"excel-text"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"asc",qname:"excel-text:asc",signature:"($text as xs:string) as xs:string",description:" Returns the given $text unchanged.\n",summary:"<p> Returns the given $text unchanged.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the time</div>'}],returns:{type:"xs:string",description:"The given $text unchanged."},errors:[]},{isDocumented:!0,arity:1,name:"char",qname:"excel-text:char",signature:"($number as xs:integer) as xs:string",description:" Returns the character specified by a certain codepoint.\n",summary:"<p> Returns the character specified by a certain codepoint.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the codepoint.</div>'}],returns:{type:"xs:string",description:"the character specified by a certain codepoint."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value provided $number must be in range [1,255].</xqdoc:error>']},{isDocumented:!0,arity:1,name:"clean",qname:"excel-text:clean",signature:"($arg as xs:string?) as xs:string?",description:" Removes all nonprintable characters from text.\n",summary:"<p> Removes all nonprintable characters from text.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string.</div>'}],returns:{type:"xs:string?",description:'Removes all nonprintable characters from text. The CLEAN function was designed. to remove the first 32 nonprinting characters in the 7-bit ASCII code (values 0 through 31) from text. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> In the Unicode character set, there are additional nonprinting characters (values 127, 129, 141, 143, 144, and 157). <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> By itself, the CLEAN function does not remove these additional nonprinting characters.'},errors:[]},{isDocumented:!0,arity:1,name:"code",qname:"excel-text:code",signature:"($arg as xs:string) as xs:integer",description:" Returns a codepoint for the first character in a text string.\n",summary:"<p> Returns a codepoint for the first character in a text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string.</div>'}],returns:{type:"xs:integer",description:"A codepoint for the first character in a text string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value Provided $arg was empty.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"concatenate",qname:"excel-text:concatenate",signature:"($args as xs:anyAtomicType*) as xs:string",description:" Joins several text strings into one text string.\n",summary:"<p> Joins several text strings into one text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"args",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of strings.</div>'}],returns:{type:"xs:string",description:"Joins several text strings into one text string."},errors:[]},{isDocumented:!0,arity:2,name:"concatenate",qname:"excel-text:concatenate",signature:"($arg1 as xs:anyAtomicType?, $arg2 as xs:anyAtomicType?) as xs:string",description:" Joins two text strings into one text string.\n",summary:"<p> Joins two text strings into one text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first string.</div>'},{name:"arg2",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second string.</div>'}],returns:{type:"xs:string",description:"Joins two text strings into one text string."},errors:[]},{isDocumented:!0,arity:1,name:"dollar",qname:"excel-text:dollar",signature:"($number as xs:decimal) as xs:string",description:" Converts a number to text format and applies a currency symbol. The number of\ndigits to the right of the decimal point is 2.\n",summary:"<p> Converts a number to text format and applies a currency symbol.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number.</div>'}],returns:{type:"xs:string",description:"Converts a number to text format and applies a currency symbol. The number of digits to the right of the decimal point is 2."},errors:[]},{isDocumented:!0,arity:2,name:"dollar",qname:"excel-text:dollar",signature:"($number as xs:decimal, $decimals as xs:decimal) as xs:string",description:" Converts a number to text format and applies a currency symbol.\n",summary:"<p> Converts a number to text format and applies a currency symbol.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number.</div>'},{name:"decimals",type:"xs:decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of digits to the right of the decimal point. <p/> If decimals is negative, number is rounded to the left of the decimal point.</div>'}],returns:{type:"xs:string",description:"Converts a number to text format and applies a currency symbol."},errors:[]},{isDocumented:!0,arity:2,name:"exact",qname:"excel-text:exact",signature:"($arg1 as xs:string, $arg2 as xs:string) as xs:boolean",description:" Compares two text strings and returns TRUE if they are exactly the same,\nFALSE otherwise. EXACT is case-sensitive but ignores formatting differences.\n",summary:"<p> Compares two text strings and returns TRUE if they are exactly the same,\nFALSE otherwise.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first string.</div>'},{name:"arg2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second string.</div>'}],returns:{type:"xs:boolean",description:"Compares two text strings and returns TRUE if they are exactly the same, FALSE otherwise. EXACT is case-sensitive but ignores formatting differences."},errors:[]},{isDocumented:!0,arity:2,name:"find",qname:"excel-text:find",signature:"($find_text as xs:string, $within_text as xs:string) as xs:integer?",description:' Locate one text string within a second text string, and return the number of the\n starting position of the first text string from the first character of the second text string. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The search is case sensitive.\n',summary:"<p> Locate one text string within a second text string, and return the number of the\n starting position of the first text string from the first character of the second text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"find_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text you want to find.</div>'},{name:"within_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text in which you want to search for $find_text.</div>'}],returns:{type:"xs:integer?",description:'Locate one text string within a second text string, and return the number of the starting position of the first text string from the first character of the second text string. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> The search is case sensitive.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value the value is not greater than zero or is greater than the length of within_text.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value value was not found.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"find",qname:"excel-text:find",signature:"($find_text as xs:string, $within_text as xs:string, $start_num as xs:integer) as xs:integer?",description:' Locate one text string within a second text string, and return the number of the\n starting position of the first text string from the first character of the second text string.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The search is case sensitive.\n',summary:"<p> Locate one text string within a second text string, and return the number of the\n starting position of the first text string from the first character of the second text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"find_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text you want to find.</div>'},{name:"within_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text in which you want to search for $find_text.</div>'},{name:"start_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> specifies the character at which to start the search.</div>'}],returns:{type:"xs:integer?",description:'Locate one text string within a second text string, and return the number of the starting position of the first text string from the first character of the second text string.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> The search is case sensitive.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value the value is not greater than zero or is greater than the length of within_text.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value value was not found.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"fixed",qname:"excel-text:fixed",signature:"($number as xs:decimal, $decimals as xs:decimal) as xs:string",description:" Rounds a number to the specified number of decimals, formats the number in\n decimal format using a period and commas, and returns the result as text.\n",summary:"<p> Rounds a number to the specified number of decimals, formats the number in\n decimal format using a period and commas, and returns the result as text.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number you want to round and convert to text.</div>'},{name:"decimals",type:"xs:decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of digits to the right of the decimal point.</div>'}],returns:{type:"xs:string",description:"Rounds a number to the specified number of decimals, formats the number in decimal format using a period and commas, and returns the result as text."},errors:[]},{isDocumented:!0,arity:3,name:"fixed",qname:"excel-text:fixed",signature:"($number as xs:decimal, $decimals as xs:decimal, $no_commas as xs:boolean) as xs:string",description:" Rounds a number to the specified number of decimals, formats the number in\ndecimal format using a period and commas, and returns the result as text.\n",summary:"<p> Rounds a number to the specified number of decimals, formats the number in\ndecimal format using a period and commas, and returns the result as text.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"number",type:"xs:decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number you want to round and convert to text.</div>'},{name:"decimals",type:"xs:decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of digits to the right of the decimal point.</div>'},{name:"no_commas",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is a logical value that, if TRUE, prevents FIXED from including commas in the returned text.</div>'}],returns:{type:"xs:string",description:"Rounds a number to the specified number of decimals, formats the number in decimal format using a period and commas, and returns the result as text."},errors:[]},{isDocumented:!0,arity:1,name:"left",qname:"excel-text:left",signature:"($arg as xs:string) as xs:string",description:" Returns the first character in a text string.\n",summary:"<p> Returns the first character in a text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the text string that contains the characters you want to extract.</div>'}],returns:{type:"xs:string",description:"The first character in a text string."},errors:[]},{isDocumented:!0,arity:2,name:"left",qname:"excel-text:left",signature:"($text as xs:string, $num_chars as xs:integer) as xs:string",description:" Returns the first character or characters in $text, based on the number of $num_chars you specify.\n",summary:"<p> Returns the first character or characters in $text, based on the number of $num_chars you specify.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the text string that contains the characters you want to extract.</div>'},{name:"num_chars",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> specifies the number of characters you want to extract.</div>'}],returns:{type:"xs:string",description:"The first character or characters in $text, based on the number of $num_chars you specify."},errors:[]},{isDocumented:!0,arity:1,name:"len",qname:"excel-text:len",signature:"($arg as xs:string?) as xs:integer",description:" Returns the number of characters in a text string.\n",summary:"<p> Returns the number of characters in a text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string.</div>'}],returns:{type:"xs:integer",description:"The number of characters in a text string."},errors:[]},{isDocumented:!0,arity:1,name:"lower",qname:"excel-text:lower",signature:"($arg as xs:string?) as xs:string?",description:" Converts all uppercase letters in a text string to lowercase.\n",summary:"<p> Converts all uppercase letters in a text string to lowercase.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string.</div>'}],returns:{type:"xs:string?",description:"Converts all uppercase letters in a text string to lowercase."},errors:[]},{isDocumented:!0,arity:3,name:"mid",qname:"excel-text:mid",signature:"($text as xs:string?, $start_num as xs:integer, $num_chars as xs:integer) as xs:string?",description:" Returns a specific number of characters from a text string, starting at\nthe position you specify, based on the number of characters you specify.\n",summary:"<p> Returns a specific number of characters from a text string, starting at\nthe position you specify, based on the number of characters you specify.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"text",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the text string containing the characters you want to extract.</div>'},{name:"start_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the position of the first character you want to extract in text. The first character in text has start_num 1, and so on.</div>'},{name:"num_chars",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of characters you want to return from text.</div>'}],returns:{type:"xs:string?",description:"A specific number of characters from a text string, starting at the position you specify, based on the number of characters you specify."},errors:[]},{isDocumented:!0,arity:3,name:"pad-integer-to-length",qname:"excel-text:pad-integer-to-length",signature:"($toPad as xs:anyAtomicType?, $padChar as xs:string, $length as xs:integer) as xs:string",description:" Returns $toPad appended with enough repetitions of $padChar to make its length $length, the characters are added before the string.\n",summary:"<p> Returns $toPad appended with enough repetitions of $padChar to make its length $length, the characters are added before the string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"toPad",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to be padded.</div>'},{name:"padChar",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the character used for padding.</div>'},{name:"length",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the desired length.</div>'}],returns:{type:"xs:string",description:"$toPad appended with enough repetitions of $padChar to make its length $length, the characters are added before the string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the length of the $toPad is greater than the desired length.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"replace",qname:"excel-text:replace",signature:"($old_text as xs:string?, $start_num as xs:integer, $num_chars as xs:integer, $new_text as xs:string) as xs:string",description:" Replaces part of a text string, based on the number of characters you specify, with a different text string.\n",summary:"<p> Replaces part of a text string, based on the number of characters you specify, with a different text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"old_text",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is text in which you want to replace some characters.</div>'},{name:"start_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the position of the character in old_text that you want to replace with new_text.</div>'},{name:"num_chars",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of characters in old_text that you want REPLACE to replace with new_text.</div>'},{name:"new_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the text that will replace characters in old_text.</div>'}],returns:{type:"xs:string",description:"Replaces part of a text string, based on the number of characters you specify, with a different text string."},errors:[]},{isDocumented:!0,arity:1,name:"right",qname:"excel-text:right",signature:"($arg as xs:string) as xs:string",description:" Returns the last character in a text string.\n",summary:"<p> Returns the last character in a text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the text string containing the characters you want to extract.</div>'}],returns:{type:"xs:string",description:"The last character in a text string."},errors:[]},{isDocumented:!0,arity:2,name:"right",qname:"excel-text:right",signature:"($text as xs:string, $num_chars as xs:integer) as xs:string",description:" Returns the last character or characters in a text string, based on the number of characters you specify.\n",summary:"<p> Returns the last character or characters in a text string, based on the number of characters you specify.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the text string containing the characters you want to extract.</div>'},{name:"num_chars",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> specifies the number of characters you want RIGHT to extract.</div>'}],returns:{type:"xs:string",description:"The last character or characters in a text string, based on the number of characters you specify."},errors:[]},{isDocumented:!0,arity:2,name:"search",qname:"excel-text:search",signature:"($find_text as xs:string, $within_text as xs:string) as xs:integer?",description:' Locate one text string within a second text string, and return the number of\n the starting position of the first text string from the first character of the\n second text string. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> The search starts at position 1, and it is not case sensitive.\n',summary:"<p> Locate one text string within a second text string, and return the number of\n the starting position of the first text string from the first character of the\n second text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"find_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text you want to find.</div>'},{name:"within_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text in which you want to search for $find_text.</div>'}],returns:{type:"xs:integer?",description:'Locate one text string within a second text string, and return the number of the starting position of the first text string from the first character of the second text string. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> The search starts at position 1, and it is not case sensitive.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value the value is not greater than zero or is greater than the length of within_text.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value value was not found.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"search",qname:"excel-text:search",signature:"($find_text as xs:string, $within_text as xs:string, $start_num as xs:integer) as xs:integer?",description:' Locate one text string within a second text string, and return the number of\n the starting position of the first text string from the first character of the\n second text string.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> The search starts at $start_num, and it is not case sensitive.\n',summary:"<p> Locate one text string within a second text string, and return the number of\n the starting position of the first text string from the first character of the\n second text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"find_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text you want to find.</div>'},{name:"within_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text in which you want to search for $find_text.</div>'},{name:"start_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the character number in within_text at which you want to start searching.</div>'}],returns:{type:"xs:integer?",description:'Locate one text string within a second text string, and return the number of the starting position of the first text string from the first character of the second text string.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> The search starts at $start_num, and it is not case sensitive.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value the value is not greater than zero or is greater than the length of within_text.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value value was not found.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"substitute",qname:"excel-text:substitute",signature:"($text as xs:string, $old_text as xs:string, $new_text as xs:string) as xs:string?",description:" Substitutes new_text for old_text in a text string. Every occurrence of old_text in text is changed to new_text.\n",summary:"<p> Substitutes new_text for old_text in a text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the text or the reference to a cell containing text for which you want to substitute characters.</div>'},{name:"old_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text you want to replace.</div>'},{name:"new_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text you want to replace old_text with.</div>'}],returns:{type:"xs:string?",description:"Substitutes new_text for old_text in a text string. Every occurrence of old_text in text is changed to new_text."},errors:[]},{isDocumented:!0,arity:4,name:"substitute",qname:"excel-text:substitute",signature:"($text as xs:string, $old_text as xs:string, $new_text as xs:string, $instance_num as xs:integer?) as xs:string",description:" Substitutes new_text for old_text in a text string.\n",summary:"<p> Substitutes new_text for old_text in a text string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the text or the reference to a cell containing text for which you want to substitute characters.</div>'},{name:"old_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text you want to replace.</div>'},{name:"new_text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text you want to replace old_text with.</div>'},{name:"instance_num",type:"xs:integer",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> specifies which occurrence of old_text you want to replace with new_text. <p/> Only that instance of old_text is replaced.</div>'}],returns:{type:"xs:string",description:'Substitutes new_text for old_text in a text string. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> Use SUBSTITUTE when you want to replace specific text in a text string; use REPLACE when you want to replace any text that occurs in a specific location in a text string.'},errors:[]},{isDocumented:!0,arity:1,name:"t",qname:"excel-text:t",signature:"($value as xs:anyAtomicType?) as xs:string",description:" Converts the $value to string.\n",summary:"<p> Converts the $value to string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value</div>'}],returns:{type:"xs:string",description:"Converts the $value to string."},errors:[]},{isDocumented:!0,arity:1,name:"trim",qname:"excel-text:trim",signature:"($text as xs:string?) as xs:string?",description:" Removes all spaces from text except for single spaces between words.\n",summary:"<p> Removes all spaces from text except for single spaces between words.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"text",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> from which you want spaces removed.</div>'}],returns:{type:"xs:string?",description:"Removes all spaces from text except for single spaces between words."},errors:[]},{isDocumented:!0,arity:1,name:"upper",qname:"excel-text:upper",signature:"($text as xs:string?) as xs:string?",description:" Converts text to uppercase.\n",summary:"<p> Converts text to uppercase.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"text",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> text you want converted to uppercase.</div>'}],returns:{type:"xs:string?",description:"Converts text to uppercase."},errors:[]},{isDocumented:!0,arity:2,name:"value-except",qname:"excel-text:value-except",signature:"($arg1 as xs:anyAtomicType*, $arg2 as xs:anyAtomicType*) as xs:anyAtomicType*",description:" Returns the values in one sequence that do not appear in the second sequence in an implementation-defined order.\n",summary:"<p> Returns the values in one sequence that do not appear in the second sequence in an implementation-defined order.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first sequence.</div>'},{name:"arg2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second sequence.</div>'}],returns:{type:"xs:anyAtomicType*",description:"The values in one sequence that do not appear in the second sequence in an implementation-defined order."},errors:[]},{isDocumented:!0,arity:1,name:"value",qname:"excel-text:value",signature:"($arg as xs:anyAtomicType?) as xs:anyAtomicType?",description:" Converts a text string that represents a number to a number.\n",summary:"<p> Converts a text string that represents a number to a number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value.</div>'}],returns:{type:"xs:anyAtomicType?",description:"Converts a text string that represents a number to a number."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value provided value is not a number.</xqdoc:error>']}],variables:[]},"http://www.28msec.com/modules/http/response":{ns:"http://www.28msec.com/modules/http/response",description:' The Sausalito response module can be used to modify the HTTP response\n that will be send as a result of this request. For example, the\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">set-content-type</tt> function can be used to set the Content-Type\n header and determine the encoding of data in the response.\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/http/response",prefix:"http"},{uri:"http://www.w3.org/2010/xslt-xquery-serialization",prefix:"output"},{uri:"http://www.28msec.com/modules/http/response",prefix:"resp"},{uri:"http://zorba.io/modules/schema",prefix:"s"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"code-for-status",qname:"resp:code-for-status",signature:"($status as xs:QName) as xs:int",description:" Convert between the HTTP status code as QName and\n the integer value of that status code.\n",summary:"<p> Convert between the HTTP status code as QName and\n the integer value of that status code.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"status",type:"xs:QName",occurrence:null,description:""}],returns:{type:"xs:int",description:"the integer value of the given QName as xs:int"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-status if the given QName does not represent a valid http status code</xqdoc:error>']},{isDocumented:!0,arity:1,name:"content-type-binary",qname:"resp:content-type-binary",signature:"($type as xs:string) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a binary content-type. A\n content-type is considered to be binary if it\'s not a text\n content-type.</p>\n',summary:"<p>  Test if a given content-type is a binary content-type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is a binary content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-html",qname:"resp:content-type-html",signature:"($type as xs:string) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a HTML content-type, i.e.\n the content-type is the string "text/html".</p>\n',summary:"<p>  Test if a given content-type is a HTML content-type, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is the HTML content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-json",qname:"resp:content-type-json",signature:"($type as xs:string) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a JSON content-type, i.e.\n the content-type is the string "application/json".</p>\n',summary:"<p>  Test if a given content-type is a JSON content-type, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is the JSON content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-mixed-json-xml",qname:"resp:content-type-mixed-json-xml",signature:"($type as xs:string) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a mixed JSON-XML content-type, i.e.\n the content-type is the string "application/mixed-json-xml".</p>\n',summary:"<p>  Test if a given content-type is a mixed JSON-XML content-type, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is a mixed JSON-XML content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-text",qname:"resp:content-type-text",signature:"($type as xs:string) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a text content-type.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A text content-type starts with "text/" or contains either of\n the strings "xml" or "json".</p>\n',summary:"<p>  Test if a given content-type is a text content-type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is a text content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-xhtml",qname:"resp:content-type-xhtml",signature:"($type as xs:string) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a XHTML content-type, i.e.\n the content-type is the string "application/xhtml+xml".</p>\n',summary:"<p>  Test if a given content-type is a XHTML content-type, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is the XHTML content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-xml",qname:"resp:content-type-xml",signature:"($type as xs:string) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a XML content-type</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A XML content-type is a content-type that is "application/xml"\n or ends : with the string "+xml".</p>\n',summary:'<p>  Test if a given content-type is a XML content-type \n  A XML content-type is a content-type that is "application/xml"\n or ends : with the string "+xml".</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is a XML content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"decode-binary",qname:"resp:decode-binary",signature:"() as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the boolean indiciating whether base64Binaries returned by\n this request will be decoded.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The default if not modified using resp:set-decode-binary is false.</p>\n',summary:"<p>  Returns the boolean indiciating whether base64Binaries returned by\n this request will be decoded.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"the said boolean value"},errors:[]},{isDocumented:!0,arity:1,name:"message-for-status",qname:"resp:message-for-status",signature:"($status as xs:QName) as xs:string",description:" Convert between the HTTP status code as QName and\n the name/message of that status code.\n",summary:"<p> Convert between the HTTP status code as QName and\n the name/message of that status code.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"status",type:"xs:QName",occurrence:null,description:""}],returns:{type:"xs:string",description:"the message of the given QName as xs:string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-status if the given QName does not represent a valid http status code</xqdoc:error>']},{isDocumented:!0,arity:0,name:"serialization-parameters",qname:"resp:serialization-parameters",signature:"() as element(output:serialization-parameters)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the serialization parameters that are currently\n active, i.e. the ones that will be used to serialize the result\n of this request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This will either be the default, the defaults set when\n calling resp:set-content-type(), or the ones set by\n resp:set-serialization-parameters().</p>\n',summary:"<p>  Returns the serialization parameters that are currently\n active, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(output:serialization-parameters)",description:"the said serialization parameters"},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-html",qname:"resp:serializer-defaults-html",signature:"() as element(*)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an element that can be used to specify the\n settings of serialization parameters for the HTML serialization\n method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <ul>\n  <li>encoding: UTF-8</li>\n  <li>indent: yes</li>\n  <li>version: 4.01</li>\n  <li>doctype-system: http://www.w3.org/TR/html4/loose.dtd</li>\n  <li>doctype-public: -//W3C//DTD HTML 4.01 Transitional//EN</li>\n  <li>include-content-type: yes</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to some HTML content-type (i.e. text/html).</p>\n',summary:"<p>  Returns an element that can be used to specify the\n settings of serialization parameters for the HTML serialization\n method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(*)*",description:"an element that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-json-xml-hybrid",qname:"resp:serializer-defaults-json-xml-hybrid",signature:"() as element(output:serialization-parameters)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an element that can be used to specify the\n settings of serialization parameters for the json-xml-hybrid\n serialization method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <ul>\n  <li>encoding: UTF-8</li>\n  <li>indent: yes</li>\n  <li>method: json-xml-hybrid</li>\n  <li>omit-xml-declaration: yes</li>\n  <li>version: 1.0</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to application/mixed-json-xml.</p>\n',summary:"<p>  Returns an element that can be used to specify the\n settings of serialization parameters for the json-xml-hybrid\n serialization method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(output:serialization-parameters)",description:"an element that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-json",qname:"resp:serializer-defaults-json",signature:"() as element(output:serialization-parameters)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an element that can be used to specify the\n settings of serialization parameters for the json\n serialization method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <ul>\n  <li>encoding: UTF-8</li>\n  <li>indent: yes</li>\n  <li>method: json</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to some JSON content-type (e.g. application/json).</p>\n',summary:"<p>  Returns an element that can be used to specify the\n settings of serialization parameters for the json\n serialization method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(output:serialization-parameters)",description:"an element that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-text",qname:"resp:serializer-defaults-text",signature:"() as element(*)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an element that can be used to specify the\n settings of serialization parameters for the text serialization\n method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The only default used is\n <ul>\n  <li>encoding: UTF-8</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, this default is used when setting\n the content-type to some text content-type (e.g. text/plain).</p>\n',summary:"<p>  Returns an element that can be used to specify the\n settings of serialization parameters for the text serialization\n method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(*)*",description:"an element that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-xhtml",qname:"resp:serializer-defaults-xhtml",signature:"() as element(*)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an element that can be used to specify the\n settings of serialization parameters for the XHTML serialization\n method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <ul>\n  <li>encoding: UTF-8</li>\n  <li>indent: yes</li>\n  <li>omit-xml-declaration: yes</li>\n  <li>version: 1.0</li>\n  <li>doctype-system: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</li>\n  <li>doctype-public: -//W3C//DTD XHTML 1.0 Transitional//EN</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to some XHTML content-type (i.e. application/xhtml+xml).</p>\n',summary:"<p>  Returns an element that can be used to specify the\n settings of serialization parameters for the XHTML serialization\n method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(*)*",description:"an element that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-xml",qname:"resp:serializer-defaults-xml",signature:"() as element(output:serialization-parameters)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an element that can be used to specify the\n settings of serialization parameters for the XML serialization\n method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <ul>\n  <li>encoding: UTF-8</li>\n  <li>indent: yes</li>\n  <li>omit-xml-declaration: yes</li>\n  <li>version: 1.0</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to some XML content-type (e.g. application/atom+xml).</p>\n',summary:"<p>  Returns an element that can be used to specify the\n settings of serialization parameters for the XML serialization\n method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"element(output:serialization-parameters)",description:"an element that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:1,name:"set-content-type",qname:"resp:set-content-type",signature:"($type as xs:string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the Content-Type header for the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n For example,\n <tt>resp:set-content-type("text/plain")</tt> will cause the\n header\n <tt>Content-Type: text/plain</tt> to be added for the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addtion to setting the Content-Type header, the function also\n sets the serialization parameters to the default values for serialization\n method for the given content-type. For example, if the content-type is set to\n text/plain, the default serialization parameters for the text\n serialization method will be used. For application/atom+xml, the default\n serialization parameters for the XML serialization method will be used.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The functions resp:content-type-text/xml/html/xhtml/binary may be used\n to figure out which serialization method will be used for a specific\n content-type.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the given content-type contains a charset declaration (e.g.\n <tt>resp:set-content-type("text/plain;charset=ISO-8859-1")</tt>), the\n content of the response will be transcoded to the given encoding.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The default serialization parameters set by this function can\n be overwritten using the resp:set-serialization-parameters() function.</p>\n',summary:"<p>  Sets the Content-Type header for the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to be set</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and returns the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"set-content-type",qname:"resp:set-content-type",signature:"($type as xs:string, $params as element(output:serialization-parameters)) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the Content-Type header for the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <tt>resp:set-content-type("text/plain")</tt> will cause the\n header\n <tt>Content-Type: text/plain</tt> to be added for the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition to the content-type, the function also allows to\n specify the serialization method and parameters that will be used\n for serializing the result. For details about this parameter, please\n refer to resp:set-serialization-parameters().</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the given content-type contains a charset declaration (e.g.\n <tt>resp:set-content-type("text/plain;charset=ISO-8859-1")</tt>), the\n content of the response will be transcoded to the given encoding.\n If the serialization parameters also contain a charset declaration,\n the charset contained in the content-type will be used. to transcode\n the result.</p>\n',summary:"<p>  Sets the Content-Type header for the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to be set</div>'},{name:"params",type:"element(output:serialization-parameters)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the serialization parameters that will be used for serialization the result.</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and returns the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"set-decode-binary",qname:"resp:set-decode-binary",signature:"($decode as xs:boolean) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If this function is invoked with true, the result of the request\n will not be serialized. Instead, the result will be the binary values\n of any item that is of type xs:base64Binary. The values of all other\n items will not be part of the result.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that all serialization parameters which have been set using\n resp:set-serialization-parameters will be ignored. Also, the output encoding\n is ignored for binaries.</p>\n',summary:"<p>  If this function is invoked with true, the result of the request\n will not be serialized.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"decode",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> boolean value indicating whether base64Binaries should be decoded.</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and returns the empty sequence."},errors:[]},{isDocumented:!0,arity:1,name:"set-encoding",qname:"resp:set-encoding",signature:"($encoding as xs:string) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function sets the output encoding that will be\n used for the payload of the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <tt>resp:set-encoding("ISO-8859-1")</tt> will cause the\n content in the response to be encoded using ISO-8859-1.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that the encoding only applies to textual data.\n It is not used if the function <tt>set-decode-binary()</tt>\n was invoked passing true as parameter.</p>\n',summary:"<p>  The function sets the output encoding that will be\n used for the payload of the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"encoding",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the encoding to be used for the payload of the response.</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and returns the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"set-header-impl",qname:"resp:set-header-impl",signature:"($name as xs:string, $value as xs:string) as xs:string? external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Set an HTTP header in the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is only used for internal purposes and should\n not be called by the user.</p>\n',summary:"<p>  Set an HTTP header in the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name for the header to set</div>'},{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value for the header to set</div>'}],returns:{type:"xs:string?",description:"the value of the header previously set or the empty sequence if no header has been set with the same name."},errors:[]},{isDocumented:!0,arity:2,name:"set-header",qname:"resp:set-header",signature:"($name as xs:string, $value as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Set a HTTP header in the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a header with the same name was already set, the\n value is overwritten and the function returns the old value. As defined\n in the HTTP specification, multiple headers with the same name\n can be combined into one header whose value is a comma-separated\n list of the values.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The following headers must not be set using this function.\n Instead, other functions of this module should be used in order\n to implemented the required semantics:\n <ul>\n   <li>Status: use set-status() instead</li>\n   <li>Content-Type: use set-content-type() instead</li>\n </ul>\n </p>\n',summary:"<p>  Set a HTTP header in the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the header to set</div>'},{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value of the header to set `</div>'}],returns:{type:"xs:string?",description:"the value of the header previously set or the empty sequence if no header has been set with the same name."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">resp:invalid-header-name if an invalid name is used for the header.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"set-redirect",qname:"resp:set-redirect",signature:"($url as xs:string) as empty-sequence()",description:" This function sets the HTTP 302 redirect status code in the response. As\n a result, a redirect to the URL given as parameter will be made.\n",summary:"<p> This function sets the HTTP 302 redirect status code in the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the redirect will be made.</div>'}],returns:{type:"empty-sequence()",description:"The empty-sequence is returned."},errors:[]},{isDocumented:!0,arity:1,name:"set-serialization-parameters",qname:"resp:set-serialization-parameters",signature:"($params as element(output:serialization-parameters)) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Set the serialization parameters used for serializing the result\n of the request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The following example shows how to set several options\n for the HTML serialization method. Specifically, it sets the\n HTML method to HTML 4.01, set the doctype-system and\n doctype-public makes sure that the output is indented. In addition,\n the output is UTF-8 encoded and\n <pre>\n &lt;output:serialization-parameters&gt;\n   &lt;output:encoding value="UTF-8"/&gt;\n   &lt;output:doctype-system value="http://www.w3.org/TR/html4/loose.dtd"/&gt;\n   &lt;output:doctype-public value="-//W3C//DTD HTML 4.01 Transitional//EN"/&gt;\n &lt;/output:serialization-parameters&gt;\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The element passed as parameter need to be valid according\n to the schema http://www.w3.org/2010/xslt-xquery-serialization. This\n function validates its input (if it has not already been validated)\n and may raise an error if the input is not valid.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that serialization options set by this function can\n be overwritten by a subsequent call to resp:set-content-type. In this\n case, the options will be reset to the default for the given\n content-type. Also note, that the output encoding can be overwritten\n by subsequently calling the resp:set-encoding function.</p>\n',summary:"<p>  Set the serialization parameters used for serializing the result\n of the request.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"params",type:"element(output:serialization-parameters)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the serialization parameters that will be used to serialize the result of the request</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and, on success, returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 if the input is not valid according to the schema http://www.w3.org/2010/xslt-xquery-serialization.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-encoding if the encoding specified in the serialization options is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"set-status-code",qname:"resp:set-status-code",signature:"($status as xs:integer) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the status code of the HTTP response to the integer given as\n parameter.</p>\n For example,\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">resp:set-status(204)</tt>\n will result in "HTTP/1.1 204 No Content".\n',summary:"<p>  Sets the status code of the HTTP response to the integer given as\n parameter.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"status",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The status code of the HTTP response as integer.</div>'}],returns:{type:"empty-sequence()",description:"On success, the empty-sequence is returned"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-status-code if the given integer does not reflect a valid HTTP status code</xqdoc:error>']},{isDocumented:!0,arity:1,name:"set-status",qname:"resp:set-status",signature:"($status as xs:QName) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the status code of the HTTP response to the QName given as\n parameter.</p>\n For example,\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">resp:set-status($http:no-content)</tt>\n will result in "HTTP/1.1 204 No Content".\n',summary:"<p>  Sets the status code of the HTTP response to the QName given as\n parameter.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"status",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The status code of the HTTP response as a QName (e.g. $http:no-content)</div>'}],returns:{type:"empty-sequence()",description:"On success, the empty-sequence is returned"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-status if the given QName does not represent a valid HTTP status code;</xqdoc:error>']},{isDocumented:!0,arity:1,name:"valid-status",qname:"resp:valid-status",signature:"($status as xs:QName) as xs:boolean",description:" Test whether the given QName refers to a valid HTTP status code.\n",summary:"<p> Test whether the given QName refers to a valid HTTP status code.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"status",type:"xs:QName",occurrence:null,description:""}],returns:{type:"xs:boolean",description:"true if the given QName refers to a valid HTTP status code, false otherwise."},errors:[]}],variables:[{name:"http:precondition-required",type:"xs:QName",description:" QName representing the HTTP Status Code 428 Precondition Required (RFC 6585)\n"},{name:"http:gone",type:"xs:QName",description:" QName representing the HTTP Status Code 410 GONE\n"},{name:"http:length-required",type:"xs:QName",description:" QName representing the HTTP Status Code 411 Length Required\n"},{name:"http:precondition-failed",type:"xs:QName",description:" QName representing the HTTP Status Code 412 Precondition Failed\n"},{name:"http:request-entity-too-large",type:"xs:QName",description:" QName representing the HTTP Status Code 413 Request Entity Too Large\n"},{name:"http:request-entity-too-long",type:"xs:QName",description:" QName representing the HTTP Status Code 414 Request Entity Too Long\n"},{name:"http:unsupported-media-type",type:"xs:QName",description:" QName representing the HTTP Status Code 415 Unsupported Media Type\n"},{name:"http:request-range-not-satisfiable",type:"xs:QName",description:" QName representing the HTTP Status Code 416 Request Range Not Satisfiable\n"},{name:"http:expectation-failed",type:"xs:QName",description:" QName representing the HTTP Status Code 417 Expectation Failed\n"},{name:"http:im-a-teapot",type:"xs:QName",description:" QName representing the HTTP Status Code 418 I'm a teapot (RFC 2324)\n"},{name:"http:enhance-your-calm",type:"xs:QName",description:" QName representing the HTTP Status Code 420 Enhance Your Calm\n"},{name:"http:unprocessable-entity",type:"xs:QName",description:" QName representing the HTTP Status Code 422 Unprocessable Entity (WebDAV; RFC 4918)\n"},{name:"http:locked",type:"xs:QName",description:" QName representing the HTTP Status Code 423 Locked (WebDAV; RFC 4918)\n"},{name:"http:failed-dependency",type:"xs:QName",description:" QName representing the HTTP Status Code 424 Failed Dependency (WebDAV; RFC 4918)\n"},{name:"http:unordered-collection",type:"xs:QName",description:" QName representing the HTTP Status Code 425 Unordered Collection\n"},{name:"http:upgrade-required",type:"xs:QName",description:" QName representing the HTTP Status Code 426 Upgrade Required\n"},{name:"http:conflict",type:"xs:QName",description:" QName representing the HTTP Status Code 409 Conflict\n"},{name:"http:too-many-requests",type:"xs:QName",description:" QName representing the HTTP Status Code 429 Too Many Requests (RFC 6585)\n"},{name:"http:request-header-fields-too-large",type:"xs:QName",description:" QName representing the HTTP Status Code 431 Request Header Fields Too Large (RFC 6585)\n"},{name:"http:internal-server-error",type:"xs:QName",description:" QName representing the HTTP Status Code 500 Internal Server Error\n"},{name:"http:not-implemented",type:"xs:QName",description:" QName representing the HTTP Status Code 501 Not Implemented\n"},{name:"http:bad-gateway",type:"xs:QName",description:" QName representing the HTTP Status Code 502 Bad Gateway\n"},{name:"http:service-unavailable",type:"xs:QName",description:" QName representing the HTTP Status Code 503 Service Unavailable\n"},{name:"http:gateway-timeout",type:"xs:QName",description:" QName representing the HTTP Status Code 504 Gateway Timeout\n"},{name:"http:http-version-not-supported",type:"xs:QName",description:" QName representing the HTTP Status Code 505 HTTP Version Not Supported\n"},{name:"http:variant-also-negotiates",type:"xs:QName",description:" QName representing the HTTP Status Code 506 Variant Also Negotiates (RFC 2295)\n"},{name:"http:insufficient-storage",type:"xs:QName",description:" QName representing the HTTP Status Code 507 Insufficient Storage (WebDAV; RFC 4918)\n"},{name:"http:loop-detected",type:"xs:QName",description:" QName representing the HTTP status code 508 Loop Detected (webdav; rfc 5842)\n"},{name:"http:not-extended",type:"xs:QName",description:" QName representing the HTTP status code 510 Not Extended (RFC 2774)\n"},{name:"http:network-authentication-required",type:"xs:QName",description:" QName representing the HTTP status code 511 Network Authentication Required (RFC 6585)\n"},{name:"resp:status-info",type:"item()*",description:" Variable containing a description for all the HTTP Status Codes\n"},{name:"http:see-other",type:"xs:QName",description:" QName representing the HTTP Status Code 303 See Other\n"},{name:"http:switching-protocols",type:"xs:QName",description:" QName representing the HTTP Status Code 101 Switching Protocols\n"},{name:"http:processing",type:"xs:QName",description:" QName representing the HTTP Status Code 102 Processing (Web; RFC 2518)\n"},{name:"http:ok",type:"xs:QName",description:" QName representing the HTTP Status Code 200 OK\n"},{name:"http:created",type:"xs:QName",description:" QName representing the HTTP Status Code 201 Created\n"},{name:"http:accepted",type:"xs:QName",description:" QName representing the HTTP Status Code 202 Accepted\n"},{name:"http:non-authoritative",type:"xs:QName",description:" QName representing the HTTP Status Code 203 Non-Authoritative\n"},{name:"http:no-content",type:"xs:QName",description:" QName representing the HTTP Status Code 204 No Content\n"},{name:"http:reset-content",type:"xs:QName",description:" QName representing the HTTP Status Code 205 Reset Content\n"},{name:"http:partial-content",type:"xs:QName",description:" QName representing the HTTP Status Code 206 Partial Content\n"},{name:"http:multi-status",type:"xs:QName",description:" QName representing the HTTP Status Code 207 Multi-Status (WebDAV; RFC 5842)\n"},{name:"http:already-reported",type:"xs:QName",description:" QName representing the HTTP Status Code 208 Already Reported (WebDAV; RFC 5842)\n"},{name:"http:im-used",type:"xs:QName",description:" QName representing the HTTP Status Code 226 IM Used (RFC 3229)\n"},{name:"http:multiple-choices",type:"xs:QName",description:" QName representing the HTTP Status Code 300 Multiple Choices\n"},{name:"http:moved-permanently",type:"xs:QName",description:" QName representing the HTTP Status Code 301 Moved Permantently\n"},{name:"http:found",type:"xs:QName",description:" QName representing the HTTP Status Code 302 Found\n"},{name:"http:continue",type:"xs:QName",description:" QName representing the HTTP Status Code 100 Continue\n"},{name:"http:not-modified",type:"xs:QName",description:" QName representing the HTTP Status Code 304 Not Modified\n"},{name:"http:use-proxy",type:"xs:QName",description:" QName representing the HTTP Status Code 305 Use Proxy\n"},{name:"http:switch-proxy",type:"xs:QName",description:" QName representing the HTTP Status Code 306 Switch Proxy\n"},{name:"http:temporary-redirect",type:"xs:QName",description:" QName representing the HTTP Status Code 307 Temporary Redirect\n"},{name:"http:permanent-redirect",type:"xs:QName",description:" QName representing the HTTP Status Code 308 Permanent Redirect (http://tools.ietf.org/html/draft-reschke-http-status-308-07)\n"},{name:"http:bad-request",type:"xs:QName",description:" QName representing the HTTP Status Code 400 Bad Request\n"},{name:"http:unauthorized",type:"xs:QName",description:" QName representing the HTTP Status Code 401 Unauthorized\n"},{name:"http:payment-required",type:"xs:QName",description:" QName representing the HTTP Status Code 402 Payment Required\n"},{name:"http:forbidden",type:"xs:QName",description:" QName representing the HTTP Status Code 403 Forbidden\n"},{name:"http:not-found",type:"xs:QName",description:" QName representing the HTTP Status Code 404 Not Found\n"},{name:"http:not-allowed",type:"xs:QName",description:" QName representing the HTTP Status Code 405 Not Allowed\n"},{name:"http:not-acceptable",type:"xs:QName",description:" QName representing the HTTP Status Code 406 Not Acceptable\n"},{name:"http:proxy-authentication-required",type:"xs:QName",description:" QName representing the HTTP Status Code 407 Proxy Authentication Required\n"},{name:"http:request-timeout",type:"xs:QName",description:" QName representing the HTTP Status Code 408 Request Timeout\n"}]},"http://zorba.io/modules/uri":{ns:"http://zorba.io/modules/uri",description:" This module provides functions for processing URIs and URLs.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner, Luis Rodriguez Gonzalez</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/uri",prefix:"uri"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"decode",qname:"uri:decode",signature:"($u as xs:string) as xs:string",description:" Percent-decodes (aka URL decoding) the given string.\n All percent encoded octets will be translated into their\n decoded UTF-8 representation.\n Please note that the percent encoding guarantees that a string\n consists of ASCII characters only. Passing a string that contains\n non-ASCII characters results in undefined behavior.\n",summary:"<p> Percent-decodes (aka URL decoding) the given string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"u",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:"the percent decoded string"},errors:[]},{isDocumented:!0,arity:2,name:"decode",qname:"uri:decode",signature:"($u as xs:string, $decode-plus as xs:boolean) as xs:string",description:" Percent-decodes (aka URL decoding) the given string.\n All percent encoded octets will be translated into their\n decoded UTF-8 representation.\n If $decode-plus is specified all occurrences of the char '+'\n will be replaced with a space ' ' before the percent decoding\n happens.\n Please note that the percent encoding guarantees that a string\n consists of ASCII characters only. Passing a string that contains\n non-ASCII characters results in undefined behavior.\n",summary:"<p> Percent-decodes (aka URL decoding) the given string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"u",type:"xs:string",occurrence:null,description:""},{name:"decode-plus",type:"xs:boolean",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> whether '+' chars will be replaced with spaces</div>"}],returns:{type:"xs:string",description:"the percent decoded string"},errors:[]},{isDocumented:!0,arity:3,name:"decode",qname:"uri:decode",signature:"($s as xs:string, $decode-plus as xs:boolean, $charset as xs:string) as xs:string external",description:" Percent-decodes (aka URL decoding) the given string.\n All percent encoded octets will be translated into their\n decoded UTF-8 representation.\n If $decode-plus is specified all occurrences of the char '+'\n will be replaced with a space ' ' before the percent decoding\n happens.\n The $charset parameter specifies the source charset after precent\n decoding. It is used to convert the decoded string into UTF-8.\n Please note that the percent encoding guarantees that a string\n consists of ASCII characters only. Passing a string that contains\n non-ASCII characters results in undefined behavior.\n",summary:"<p> Percent-decodes (aka URL decoding) the given string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to decode</div>'},{name:"decode-plus",type:"xs:boolean",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> whether '+' chars will be replaced with spaces</div>"},{name:"charset",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source charset of the string after percent decoding</div>'}],returns:{type:"xs:string",description:"the percent decoded string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:CHARSET_UNKNOWN if the given charset is unknown or not supported</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0006 if there is an error transcoding the string</xqdoc:error>']},{isDocumented:!0,arity:1,name:"parse",qname:"uri:parse",signature:"($uri as xs:string) as object() external",description:' Parses the URI passed as string. The returned object\n contains only members with field names declared as constants in\n this module.\n For example,\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n let my-uri := "http://www.my.project.com/a/b/c?user=john;pass=1234#profile"\n return uri:parse(my-uri)\n </pre>\n returns\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="java">\n { "squeme" : "http", "host" : "www.my.project.com", "path" : "/a/b/c",\n   "query" : "user=john;pass=123", "fragment" : "profile" }\n </pre>\n',summary:"<p> Parses the URI passed as string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URI to parse</div>'}],returns:{type:"object()",description:"the JSON object"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQST0046 if the URI is textually invalid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"serialize",qname:"uri:serialize",signature:"($uri as object()) as xs:string external",description:" Serialize the URI passed as object into a string.\n",summary:"<p> Serialize the URI passed as object into a string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the object representing the URI</div>'}],returns:{type:"xs:string",description:"the URI as string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:OPAQUE_COMB_NOT_VALID if opaque part is specified in conjunction with host/port/path/user-info/query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:OPAQUE_WITHOUT_SCHEME if opaque part is present but no scheme is present.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">uri:INVALID_ABSOLUTE_PATH if a path component for an absolute URI doesn\'t start with "/".</xqdoc:error>']}],variables:[{name:"uri:SCHEME",type:"xs:string",description:' Constant for the "scheme" part of a URI object.\n'},{name:"uri:AUTHORITY",type:"xs:string",description:' Constant for the "authority" part of a URI object.\n'},{name:"uri:USER-INFO",type:"xs:string",description:' Constant for the "user-info" part of a URI object.\n'},{name:"uri:HOST",type:"xs:string",description:' Constant for the "host" part of a URI object.\n'},{name:"uri:PORT",type:"xs:string",description:' Constant for the "port" part of a URI object.\n'},{name:"uri:PATH",type:"xs:string",description:' Constant for the "path" part of a URI object.\n'},{name:"uri:QUERY",type:"xs:string",description:' Constant for the "query" part of a URI object.\n'},{name:"uri:FRAGMENT",type:"xs:string",description:' Constant for the "fragment" part of a URI object.\n'},{name:"uri:OPAQUE-PART",type:"xs:string",description:' Constant for the "opaque-part" part of a URI object.\n If this is set in a URI object, then none of $uri:PATH, $uri:HOST,\n $uri:PORT, $uri:USER-INFO, or : $uri:QUERY may be specified.\n If this is set in a URI object, $uri:SCHEME must also be specified\n (ie, it must be an absolute URI).\n'}]},"http://xbrl.io/modules/bizql/profiles/sec/fiscal/core":{ns:"http://xbrl.io/modules/bizql/profiles/sec/fiscal/core",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for querying fiscal reports (10-K, 10-Q)\n submitted to the SEC.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/companies",prefix:"companies"},{uri:"http://xbrl.io/modules/bizql/components",prefix:"components"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/filings",prefix:"filings"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/fiscal/core",prefix:"fiscal-core"},{uri:"http://jsoniq.org/function-library",prefix:"j"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/core",prefix:"sec"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/networks",prefix:"sec-networks"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:3,name:"balance-sheets-for-fiscal-periods-and-years",qname:"fiscal-core:balance-sheets-for-fiscal-periods-and-years",signature:"($entity-or-ids as item()*, $fiscal-period-focus as string*, $fiscal-year-focus as integer*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the balance sheet for the given entities and fiscal periods and years.</p>\n',summary:"<p>  Retrieves the balance sheet for the given entities and fiscal periods and years.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entity-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a list of entities or their EIDs.</div>'},{name:"fiscal-period-focus",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the periods (YTD1, YTD2, YTD3, Q1, Q2, Q3 or FY) or $fiscal-core:ALL_FISCAL_PERIODS to accept all.</div>'},{name:"fiscal-year-focus",type:"integer",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the years (2012) or $fiscal-core:ALL_FISCAL_YEARS to accept all.</div>'}],returns:{type:"object()*",description:"the balance sheet at that date and for that formType."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">entities:INVALID_PARAMETER if the CIK or entity is not valid.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"facts-for-aspects-and-fiscal-periods-and-years",qname:"fiscal-core:facts-for-aspects-and-fiscal-periods-and-years",signature:"($aspects as object()?, $fiscal-period-focus as string*, $fiscal-year-focus as integer*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves facts for the given aspects, fiscal periods and years.</p>\n',summary:"<p>  Retrieves facts for the given aspects, fiscal periods and years.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"aspects",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an object containing aspects to filter, among which xbrl:Concept, xbrl:Entity and xbrl:Period (all optional).</div>'},{name:"fiscal-period-focus",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the periods (YTD1, YTD2, YTD3, Q1, Q2, Q3 or FY).</div>'},{name:"fiscal-year-focus",type:"integer",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the years (2012)</div>'}],returns:{type:"object()*",description:"all facts matching the given aspects, fiscal period and year."},errors:[]},{isDocumented:!0,arity:4,name:"facts-for-aspects-and-fiscal-periods-and-years",qname:"fiscal-core:facts-for-aspects-and-fiscal-periods-and-years",signature:"($aspects as object()?, $fiscal-period-focus as string*, $fiscal-year-focus as integer*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves facts for the given aspects, fiscal periods and years.</p>\n',summary:"<p>  Retrieves facts for the given aspects, fiscal periods and years.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"aspects",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an object containing aspects to filter, among which xbrl:Concept, xbrl:Entity and xbrl:Period (all optional).</div>'},{name:"fiscal-period-focus",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the periods (YTD1, YTD2, YTD3, Q1, Q2, Q3 or FY) or $fiscal-core:ALL_FISCAL_PERIODS to accept all.</div>'},{name:"fiscal-year-focus",type:"integer",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the years (2012) or $fiscal-core:ALL_FISCAL_YEARS to accept all.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="../core#standard_options">standard SEC BizQL options</a>.</div>'}],returns:{type:"object()*",description:"all facts matching the given aspects, fiscal period and year."},errors:[]},{isDocumented:!0,arity:4,name:"facts-for-entities-and-concepts-and-fiscal-periods-and-years",qname:"fiscal-core:facts-for-entities-and-concepts-and-fiscal-periods-and-years",signature:"($entities-or-ids as item()*, $concepts as string*, $fiscal-period-focus as string*, $fiscal-year-focus as integer*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves facts for the given entities, concepts, fiscal periods and years.</p>\n',summary:"<p>  Retrieves facts for the given entities, concepts, fiscal periods and years.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entities-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a list of entities or their EIDs.</div>'},{name:"concepts",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a list of concept names (us-gaap:Assets)</div>'},{name:"fiscal-period-focus",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the periods (YTD1, YTD2, YTD3, Q1, Q2, Q3 or FY) or $fiscal-core:ALL_FISCAL_PERIODS to accept all.</div>'},{name:"fiscal-year-focus",type:"integer",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the years (2012) or $fiscal-core:ALL_FISCAL_YEARS to accept all.</div>'}],returns:{type:"object()*",description:"all facts matching entities, concepts, fiscal periods and years"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">entities:INVALID_PARAMETER if the CIK or entity is not valid.</xqdoc:error>']},{isDocumented:!0,arity:5,name:"facts-for-entities-and-concepts-and-fiscal-periods-and-years",qname:"fiscal-core:facts-for-entities-and-concepts-and-fiscal-periods-and-years",signature:"($entities-or-ids as item()*, $concepts as string*, $fiscal-period-focus as string*, $fiscal-year-focus as integer*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves facts for the given entities, concepts, fiscal periods and years.</p>\n',summary:"<p>  Retrieves facts for the given entities, concepts, fiscal periods and years.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entities-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a list of entities or their EIDs.</div>'},{name:"concepts",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a list of concept names (us-gaap:Assets)</div>'},{name:"fiscal-period-focus",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the periods (YTD1, YTD2, YTD3, Q1, Q2, Q3 or FY) or $fiscal-core:ALL_FISCAL_PERIODS to accept all.</div>'},{name:"fiscal-year-focus",type:"integer",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the years (2012) or $fiscal-core:ALL_FISCAL_YEARS to accept all.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="../core#standard_options">standard SEC BizQL options</a>.</div>'}],returns:{type:"object()*",description:"all facts matching entities, concepts, fiscal periods and years"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">entities:INVALID_PARAMETER if the CIK or entity is not valid.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"filings-for-entities-and-fiscal-periods-and-years",qname:"fiscal-core:filings-for-entities-and-fiscal-periods-and-years",signature:"($entities-or-ids as item()*, $fiscal-period-focus as string*, $fiscal-year-focus as integer*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all filings by entities and for given fiscal periods and years.</p>\n',summary:"<p>  Retrieves all filings by entities and for given fiscal periods and years.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entities-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> entities or their ids.</div>'},{name:"fiscal-period-focus",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> fiscal periods (FY, YTD1, YTD2, YTD3, Q1, Q2, Q3, Q4) or $fiscal-core:ALL_FISCAL_PERIODS to accept all..</div>'},{name:"fiscal-year-focus",type:"integer",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> fiscal years or $fiscal-core:ALL_FISCAL_YEARS to accept all..</div>'}],returns:{type:"object()*",description:"all filings that match the criteria."},errors:[]},{isDocumented:!0,arity:1,name:"fiscal-period",qname:"fiscal-core:fiscal-period",signature:"($filing-fact-or-id as item()?) as string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the fiscal period of a filing or a fact.</p>\n',summary:"<p>  Retrieves the fiscal period of a filing or a fact.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filing-fact-or-id",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a filing, a fact, or its id.</div>'}],returns:{type:"string?",description:"the fiscal period (FY, YTD2, YTD3, Q1, Q2 or Q3)."},errors:[]},{isDocumented:!0,arity:1,name:"fiscal-year",qname:"fiscal-core:fiscal-year",signature:"($filing-fact-or-id as item()?) as integer?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the fiscal year of a filing or a fact.</p>\n',summary:"<p>  Retrieves the fiscal year of a filing or a fact.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filing-fact-or-id",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a filing, a fact, or its id.</div>'}],returns:{type:"integer?",description:"the fiscal year (e.g., 2012)."},errors:[]},{isDocumented:!0,arity:1,name:"latest-reported-fiscal-period",qname:"fiscal-core:latest-reported-fiscal-period",signature:"($entity-or-id as item()) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the latest reported fiscal period and year for the\n supplied entity.</p>\n',summary:"<p>  Retrieves the latest reported fiscal period and year for the\n supplied entity.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entity-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an entity or its EID.</div>'}],returns:{type:"object()*",description:"an object with two fields: period and year."},errors:[]},{isDocumented:!0,arity:2,name:"latest-reported-fiscal-period",qname:"fiscal-core:latest-reported-fiscal-period",signature:"($entity-or-id as item(), $type as string) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the latest fiscal period and year for the\n supplied entity.</p>\n',summary:"<p>  Retrieves the latest fiscal period and year for the\n supplied entity.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entity-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an entity or its EID.</div>'},{name:"type",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> 10-K or 10-Q or FY, YTD1, YTD2, YTD3, Q1, Q2, or Q3.</div>'}],returns:{type:"object()*",description:"an object with two fields: period and year."},errors:[]}],variables:[{name:"fiscal-core:ALL_FISCAL_PERIODS",type:"string",description:" Joker for all fiscal periods.\n"},{name:"fiscal-core:ALL_FISCAL_YEARS",type:"integer",description:" Joker for all fiscal years.\n"}]},"http://zorba.io/modules/base64":{ns:"http://zorba.io/modules/base64",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Base64 encoding and decoding.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/base64",prefix:"base64"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"decode",qname:"base64:decode",signature:"($base64 as base64Binary) as string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Decode a base64Binary.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function assumes that the content after decoding is valid\n UTF-8.</p>\n',summary:"<p>  Decode a base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"base64",type:"base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The base64Binary item to decode</div>'}],returns:{type:"string",description:"the base64-decoded value as string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0006 if $base64 contains invalid base-64 data.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"decode",qname:"base64:decode",signature:"($base64 as base64Binary, $encoding as string) as string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Decode a base64Binary.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function assumes that the content after decoding has\n the given encoding.</p>\n',summary:"<p>  Decode a base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"base64",type:"base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The base64Binary item to decode</div>'},{name:"encoding",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The encoding of the string after base64-decoding it. The encoding parameter is case insensitive.</div>'}],returns:{type:"string",description:"the base64-decoded value as a string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP0006 if the given encoding is invalid or not supported. "ASCII" and "UTF-8" are guaranteed to be supported; other encodings may be supported depending on the installation.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0006 if $base64 contains invalid base-64 data.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"encode",qname:"base64:encode",signature:"($string as string) as base64Binary external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Encode a string as base64Binary.</p>\n',summary:"<p>  Encode a string as base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"string",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The item whose string-value should be encoded</div>'}],returns:{type:"base64Binary",description:"the base64-encoded string-value of the item parameter"},errors:[]}],variables:[]},"http://xbrl.io/modules/bizql/networks":{ns:"http://xbrl.io/modules/bizql/networks",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for handling networks.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A network is a graph of concepts and resources, of which the edges\n share the same semantics.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">There are several kinds of networks.\n A network can be a tree or a DAG of concepts. It can be a bipartite\n graph mapping concepts to resources.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">XBRL defines a number of standard networks: presentation, calculation,\n definition (essence-alias, general-special, requires-element, similar-tuples, domain-member),\n and label networks.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve the networks contained in a component, and you\n can retrieve a standard XBRL network with the provided short names.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/components",prefix:"components"},{uri:"http://xbrl.io/modules/bizql/networks",prefix:"networks"}],functions:[{isDocumented:!0,arity:2,name:"networks-for-components-and-short-names",qname:"networks:networks-for-components-and-short-names",signature:"($components as item()*, $short-name as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the standardized networks in the supplied components with the given short names.</p>\n',summary:"<p>  Retrieves the standardized networks in the supplied components with the given short names.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of components.</div>'},{name:"short-name",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the short names of the networks.</div>'}],returns:{type:"object()*",description:"the standardized networks with these short names."},errors:[]},{isDocumented:!0,arity:1,name:"networks-for-components",qname:"networks:networks-for-components",signature:"($components as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all networks in the supplied components.</p>\n',summary:"<p>  Retrieves all networks in the supplied components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of components.</div>'}],returns:{type:"object()*",description:"all networks."},errors:[]}],variables:[{name:"networks:PRESENTATION_NETWORK",type:"xs:string",description:" Short name of the presentation network.\n"},{name:"networks:CALCULATION_NETWORK",type:"xs:string",description:" Short name of the calculation network.\n"},{name:"networks:ESSENCE_ALIAS_NETWORK",type:"xs:string",description:" Short name of the essence-alias definition network.\n"},{name:"networks:GENERAL_SPECIAL_NETWORK",type:"xs:string",description:" Short name of the general-special definition network.\n"},{name:"networks:REQUIRES_ELEMENT_NETWORK",type:"xs:string",description:" Short name of the requires-element definition network.\n"},{name:"networks:SIMILAR_TUPLES_NETWORK",type:"xs:string",description:" Short name of the similar-tuples definition network.\n"},{name:"networks:DOMAIN_MEMBER_NETWORK",type:"xs:string",description:" Short name of the domain-member definition network.\n"}]},"http://jsound.io/modules/validate/map":{ns:"http://jsound.io/modules/validate/map",description:" Map utility\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Chris Hillery, Cezar Andrei</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://jsound.io/modules/validate/map",prefix:"map"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"get",qname:"map:get",signature:"($map as object(), $key as string) as item()",description:" Returns the value under the key.\n",summary:"<p> Returns the value under the key.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"map",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the map JSON object</div>'},{name:"key",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the key</div>'}],returns:{type:"item()",description:"the value under the $key, () if empty Example:"},errors:[]},{isDocumented:!0,arity:2,name:"has-key",qname:"map:has-key",signature:"($map as object(), $key as string) as boolean",description:" Returns true if $key exists in the map.\n",summary:"<p> Returns true if $key exists in the map.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"map",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the map JSON object</div>'},{name:"key",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the key</div>'}],returns:{type:"boolean",description:"true if $key exists, false otherwise Example:"},errors:[]},{isDocumented:!0,arity:3,name:"set-if-empty",qname:"map:set-if-empty",signature:"($map as object(), $key as xs:string, $value as item()) as boolean",description:" Only if key doesn't exist, inserts new key and value into the map and\n returns true. Otherwise returns false.\n",summary:"<p> Only if key doesn't exist, inserts new key and value into the map and\n returns true.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"map",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the map JSON object</div>'},{name:"key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the key</div>'},{name:"value",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value</div>'}],returns:{type:"boolean",description:"true if $key is empty, false otherwise Example:"},errors:[]},{isDocumented:!0,arity:3,name:"set",qname:"map:set",signature:"($map as object(), $key as xs:string, $value as item()) as boolean",description:" Inserts new key and value into the map or replaces value under the exiting key.\n Returns true all the time.\n",summary:"<p> Inserts new key and value into the map or replaces value under the exiting key.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"map",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the map JSON object</div>'},{name:"key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the key</div>'},{name:"value",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value</div>'}],returns:{type:"boolean",description:"true Example:"},errors:[]}],variables:[]},"http://zorba.io/modules/xml":{ns:"http://zorba.io/modules/xml",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This module provides functions for reading XML files from string inputs.\n It allows reading of well-formed XML documents as well as well-formed\n external parsed entities, described by\n <a href="http://www.w3.org/TR/xml/#wf-entities">XML 1.0 Well-Formed\n Parsed Entities</a>. The functions can also perform Schema and DTD\n validation of the input documents.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The following example parses a sequence of XML elements and returns\n them in a streaming fashion - each at a time:</p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n import module namespace x = "http://zorba.io/modules/xml";\n import schema namespace opt = "http://zorba.io/modules/xml-options";\n x:parse(\n   "&lt;from1&gt;Jani&lt;/from1&gt;&lt;from2&gt;Jani&lt;/from2&gt;&lt;from3&gt;Jani&lt;/from3&gt;",\n   &lt;opt:options&gt;\n     &lt;opt:parse-external-parsed-entity/&gt;\n   &lt;/opt:options&gt;\n )\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Another useful option allows to skip an arbitrary number of levels\n before returning a sequence of nodes as shown in the following example:</p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n import module namespace x = "http://zorba.io/modules/xml";\n import schema namespace opt = "http://zorba.io/modules/xml-options";\n x:parse(\n   "&lt;root&gt;\n     &lt;from1&gt;Jani1&lt;/from1&gt;\n     &lt;from2&gt;Jani2&lt;/from2&gt;\n     &lt;from3&gt;Jani3&lt;/from3&gt;\n   &lt;/root&gt;",\n   &lt;opt:options&gt;\n     &lt;opt:parse-external-parsed-entity opt:skip-root-nodes="1"/&gt;\n   &lt;/opt:options&gt;\n )\n </pre>\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.w3.org/TR/xml/#wf-entities">XML 1.0 Well-Formed Parsed Entities</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.w3.org/TR/xpath-functions-30/#func-parse-xml"> fn:parse-xml() function in XPath and XQuery Functions and Operators 3.0</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://xmlsoft.org/html/libxml-parser.html">LibXml2 parser</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Nicolae Brinza, Juan Zacarias</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/xqt-errors",prefix:"err"},{uri:"http://zorba.io/modules/xml-options",prefix:"opt"},{uri:"http://zorba.io/modules/schema",prefix:"schema"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/modules/xml",prefix:"x"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"canonicalize",qname:"x:canonicalize",signature:"($xml-string as xs:string) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A function to canonicalize the given XML string, that is, transform\n it into Canonical XML as defined by <a href="http://www.w3.org/TR/xml-c14n">Canonical XML</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note: This function is not streamable. If a streamable string is used\n as input for the function it will be materialized.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note: This function sets the\n <a href="http://xmlsoft.org/html/libxml-parser.html#xmlParserOption">XML_PARSE_NOERROR</a>\n option when parsing the XML input.</p>\n',summary:"<p>  A function to canonicalize the given XML string, that is, transform\n it into Canonical XML as defined by  Canonical XML .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xml-string",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a string representation of a well formed XML to canonicalize. XML fragments are not allowed.</div>'}],returns:{type:"xs:string",description:"the canonicalized XML string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:CANO0001 invalid input.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"canonicalize",qname:"x:canonicalize",signature:"($xml-string as xs:string, $options as element(opt:options)) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A function to canonicalize the given XML string, that is, transform\n it into Canonical XML as defined by <a href="http://www.w3.org/TR/xml-c14n">Canonical XML</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This version of the function allows specifying certain options to be\n used when initially parsing the XML string. These are of the same form\n as the options to x:parse#2(), although the following options are\n currently ignored for this function:\n <ul>\n <li>&lt;opt:no-error/&gt;</li>\n <li>&lt;opt:base-uri/&gt;</li>\n <li>&lt;opt:schema-validate/&gt;</li>\n <li>&lt;opt:parse-external-parsed-entity/&gt;</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note: This function is not streamable, if a streamable string is used\n as input for the function it will be materialized.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note: This function sets the\n <a href="http://xmlsoft.org/html/libxml-parser.html#xmlParserOption">XML_PARSE_NOERROR</a>\n option when parsing the XML input.</p>\n',summary:"<p>  A function to canonicalize the given XML string, that is, transform\n it into Canonical XML as defined by  Canonical XML .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xml-string",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a string representation of a well formed XML to canonicalize. XML fragments are not allowed.</div>'},{name:"options",type:"element(opt:options)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an XML containg options for the canonicalize function.</div>'}],returns:{type:"xs:string",description:"the canonicalized XML string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:CANO0001 invalid input.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"parse",qname:"x:parse",signature:"($xml-string as xs:string?, $options as element(opt:options)?) as node()* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A function to parse XML files and fragments (i.e.\n <a href="http://www.w3.org/TR/xml/#wf-entities">external general parsed\n entities</a>).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The functions takes two arguments: the first one is the\n string to be parsed and the second argument is an &lt;options/&gt; element that\n passes a list of options to the parsing function. They are described below.\n The options element must conform to the xml-options:options element type\n from the xml-options.xsd schema. Some of these\n will be passed to the underlying library (LibXml2) and further documentation\n for them can be found at <a href="http://xmlsoft.org/html/libxml-parser.html">\n LibXml2 parser</a>.</p>\n The list of available options:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n <li>\n &lt;base-uri/&gt; - the element must have a "value" attribute, which will provide\n the baseURI that will be used as the baseURI for every node returned by this\n function.\n </li>\n <li>\n &lt;no-error/&gt; - if present, the option will disable fatal error processing. Any\n failure to parse or validate the input in the requested manner will result\n in the function returning an empty sequence and no error will raised.\n </li>\n <li>\n &lt;schema-validate/&gt; - if present, it will request that the input string be Schema\n validated. The element accepts an attribute named "mode" which can have two\n values: "strict and "lax". Enabling the option will produce a result that is\n equivalent to processing the input with the option disabled, and then copying\n the result using the XQuery "validate strict|lax" expression. This option can not\n be used together with either the &lt;DTD-validate/&gt; or the &lt;parse-external-parsed-entity/&gt;\n option. Doing so will raise a zerr:ZXQD0003 error.\n </li>\n <li>\n &lt;DTD-validate/&gt; - the option will enable the DTD-based validation. If this\n option is enabled and the input references a DTD, then the input must be a\n well-formed and DTD-valid XML document. The &lt;DTD-load/&gt; option must be used for\n external DTD files to be loaded. If the option is enabled and the input does\n not reference a DTD then the option is ignored. If the option is disabled, the\n input is not required to reference a DTD and if it does reference a DTD then\n the DTD is ignored for validation purposes. This option can not\n be used together with either the &lt;schema-validate/&gt; or the &lt;parse-external-parsed-entity&gt;\n option. Doing so will raise a zerr:ZXQD0003 error.\n </li>\n <li>\n &lt;DTD-load/&gt; - if present, it will enable loading of external DTD files.\n </li>\n <li>\n &lt;default-DTD-attributes/&gt; - if present, it will enable the default DTD attributes.\n </li>\n <li>\n &lt;parse-external-parsed-entity/&gt; - if present, it will enable the processing of XML\n external entities. If the option\n is enabled, the input must conform to the syntax extParsedEnt (production\n [78] in XML 1.0, see <a href="http://www.w3.org/TR/xml/#wf-entities">\n Well-Formed Parsed Entities</a>). In addition, by default a DOCTYPE declaration is allowed,\n as described by the [28] doctypedecl production, see <a href="http://www.w3.org/TR/xml/#NT-doctypedecl">\n Document Type Definition</a>. A parameter is available to forbid the appearance of the DOCTYPE.\n The result of the function call is a list\n of nodes corresponding to the top-level components of the content of the\n external entity: that is, elements, processing instructions, comments, and\n text nodes. CDATA sections and character references are expanded, and\n adjacent characters are merged so the result contains no adjacent text\n nodes. If the option is disabled, the input must be a well-formed XML\n document conforming to the Document production\n (<a href="http://www.w3.org/TR/xml/#sec-well-formed">production [1] in XML 1.0</a>).\n This option can not be used together with either the &lt;schema-validate/&gt; or the &lt;DTD-validate/&gt;\n option. Doing so will raise a zerr:ZXQD0003 error.\n The &lt;parse-external-parsed-entity/&gt; option has three parameters, given by attributes. The first\n attribute is "skip-root-nodes" and it can have a non-negative value. Specifying the paramter\n tells the parser to skip the given number of root nodes and return only their children. E.g.\n skip-root-nodes="1" is equivalent to parse-xml($xml-string)/node()/node() . skip-root-nodes="2" is equivalent\n to parse-xml($xml-string)/node()/node()/node() , etc. The second attribute is "skip-top-level-text-nodes" with a\n boolean value. Specifying "true" will tell the parser to skip top level text nodes, returning\n only the top level elements, comments, PIs, etc. This parameter works in combination with\n the "skip-root-nodes" paramter, thus top level text nodes are skipped after "skip-root-nodes" has\n been applied. The third paramter is "error-on-doctype" and will generate an error if a DOCTYPE\n declaration appears in the input, which by default is allowed.\n </li>\n <li>\n &lt;substitute-entities/&gt; - if present, it will enable the XML entities substitutions.\n </li>\n <li>\n &lt;remove-redundant-ns/&gt; - if present, the parser will remove redundant namespaces declarations.\n </li>\n <li>\n &lt;no-CDATA/&gt; - if present, the parser will merge CDATA nodes as text nodes.\n </li>\n <li>\n &lt;xinclude-substitutions/&gt; - if present, it will enable the XInclude substitutions.\n </li>\n <li>\n &lt;no-xinclude-nodes/&gt; - if present, the parser will not generate XInclude START/END nodes.\n </li>\n </ul>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n An example that sets the base-uri of the parsed external entities:\n </p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n   import module namespace x = "http://zorba.io/modules/xml";\n   import schema namespace opt = "http://zorba.io/modules/xml-options";\n   x:parse("&lt;from1&gt;Jani&lt;/from1&gt;&lt;from2&gt;Jani&lt;/from2&gt;&lt;from3&gt;Jani&lt;/from3&gt;",\n     &lt;opt:options&gt;\n       &lt;opt:base-uri opt:value="urn:test"/&gt;\n       &lt;opt:parse-external-parsed-entity/&gt;\n     &lt;/opt:options&gt;\n   )\n </pre>\n',summary:"<p>  A function to parse XML files and fragments (i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xml-string",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string that holds the XML to be parsed. If empty, the function will return an empty sequence</div>'},{name:"options",type:"element(opt:options)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The options for the parsing</div>'}],returns:{type:"node()*",description:"The parsed XML as a document node or a list of nodes, or an empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQD0003 The error will be raised if the options to the function are inconsistent.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FODC0006 The error will be raised if the input string is not a valid XML document or fragment (external general parsed entity) or if DTD validation was enabled and the document has not passed it.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 The error will be raised if schema validation was enabled and the input document has not passed it or if the parsing options are not conformant to the xml-options.xsd schema.</xqdoc:error>']}],variables:[]},"http://www.zorba-xquery.com/modules/process":{ns:"http://www.zorba-xquery.com/modules/process",description:' This module provides functions to create a native process and return the result\n (i.e. exit code, result on standard out and error).\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n Example:\n<pre class="ace-static" ace-mode="xquery">\n  import module namespace proc = "http://www.zorba-xquery.com/modules/process";\n  proc:exec("ls")\n</pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n Potential result:\n <pre class="ace-static" ace-mode="xquery">\n &lt;result xmlns="http://www.zorba-xquery.com/modules/process"&gt;\n   &lt;stdout&gt;myfile.txt&lt;/stout&gt;\n   &lt;stderr/&gt;\n   &lt;exit-code&gt;0&lt;/exit-code&gt;\n &lt;/result&gt;\n </pre>\n </p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Cezar Andrei</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.zorba-xquery.com/modules/process",prefix:"process"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"exec",qname:"process:exec",signature:"($cmd as xs:string) as element(process:result) external",description:" Executes the specified string command in a separate process.\n This function does not allow arguments to be passed to\n the command.\n",summary:"<p> Executes the specified string command in a separate process.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"cmd",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> command to be executed (without arguments)</div>'}],returns:{type:"element(process:result)",description:"the result of the execution as an element as shown in the documentation of this module. The exit-code element returns the exit code of the child process. For POSIX compliant platforms: returns the process exit code. If process is terminated or stopped: 128 + termination signal code. For Windows platforms: returns the return value of the process or the exit or terminate process specified value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">process:PROC01 if an error occurred while communicating with the executed process.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"exec",qname:"process:exec",signature:"($cmd as xs:string, $args as xs:string*) as element(process:result) external",description:" Executes the specified string command in a separate process.\n Each of the strings in the sequence passed in as the second\n argument is passed as an argument to the executed command.\n",summary:"<p> Executes the specified string command in a separate process.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"cmd",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> command to be executed (without arguments)</div>'},{name:"args",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the arguments passed to the executed command (e.g. "-la")</div>'}],returns:{type:"element(process:result)",description:"the result of the execution as an element as shown in the documentation of this module. The exit-code element returns the exit code of the child process. For POSIX compliant platforms: returns the process exit code. If process is terminated or stopped: 128 + termination signal code. For Windows platforms: returns the return value of the process or the exit or terminate process specified value."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">process:PROC01 if an error occurred while communicating with the executed process.</xqdoc:error>']}],variables:[]},"http://www.28msec.com/modules/maps":{ns:"http://www.28msec.com/modules/maps",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module defines a set of functions for working with maps. A map\n is identified by a string and can be created using the map:create function\n and dropped using the map:drop function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">It is possible to create persistent and transient maps. The lifetime of a\n transient map is limited by the execution of the current query.\n A persistent map lives until it is explicitly dropped.\n Accordingly, it is also available to other requests.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre class="ace-static" ace-mode="xquery">map:create("my-map", ["string", "integer"], { "persistent" : false })</pre>\n will create a transient map named my-map having two keys.\n The types of the keys are string and integer.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The key of a particular entry in the map can consist of a tuple of\n atomic values (called key attributes). The actual type of each attribute\n is determined when the map is created. The value of each entry is a\n sequence of items. If an item in this sequence is a object or array,\n this item needs to belong to a collection, otherwise, an error is raised.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For every persistent map, 28.io will create a new collection\n in your MongoDB database. The collection will have the prefix <em>_28.map</em>.\n For example, if your map is called foo, the according collection will\n be named <em>_28.map.foo</em>.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/maps",prefix:"map"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:0,name:"available-maps",qname:"map:available-maps",signature:"() as string* external",description:" The function returns a sequence of names of the maps that are\n available (persistent and non-persistent). The sequence will be\n empty if there are no maps.\n",summary:"<p> The function returns a sequence of names of the maps that are\n available (persistent and non-persistent).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"string*",description:"A sequence of string, one for each available map, or an emtpy sequence."},errors:[]},{isDocumented:!0,arity:2,name:"create",qname:"map:create",signature:"($name as string, $key-types as item()) as empty-sequence() external",description:' Create a persistent map with a given name and type identifiers for the key\n attributes.\n If the map has only one key attribute, a single type identifier is given,\n for more than one key attribute an array of type identifiers is given.\n Calling this function is equivalent to calling create with the options\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">{ "persistent" : true }</pre>\n Note that the function is sequential and immediately creates the map.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Each key-type should be specified as string (e.g. "integer",\n "string", "boolean", "double", or "datetime").</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>map:create("my-map", "string")</pre> or\n <pre>map:create("my-map", ["string", "integer"])</pre>.</p>\n',summary:"<p> Create a persistent map with a given name and type identifiers for the key\n attributes.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map (the restrictons on collection names apply)</div>'},{name:"key-types",type:"item()",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately creates the corresponding map. It returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if any of the key attribute types is not a subtype of anyAtomicType.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZSTR0001 if a map with the given name already exists.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY1000 if the given name is not a legal collection name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0043 if any of the given options has an invalid type</xqdoc:error>']},{isDocumented:!0,arity:3,name:"create",qname:"map:create",signature:"($name as string, $key-types as item(), $options as object()) as empty-sequence() external",description:' Create a map with a given name, type identifiers for the key attributes, and\n options.\n If the map has only one key attribute, a single type identifier is given,\n for more than one key attribute an array of type identifiers is given.\n Currently only one option is supported: To create a transient map the object\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">{ "persistent" : false }</code>\n has to be passed to the $options parameter.\n Note that the function is sequential and immediately creates the map in the\n store.\n',summary:"<p> Create a map with a given name, type identifiers for the key attributes, and\n options.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map (the restrictons on collection names apply)</div>'},{name:"key-types",type:"item()",occurrence:null,description:""},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an object describing options for the map</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately creates the corresponding map but returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if any of the attribute types is not a subtype of anyAtomicType.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZSTR0001 if a map with the given name already exists.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY1000 if the given name is not a legal collection name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0043 if any of the given options has an invalid type</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete",qname:"map:delete",signature:"($name as string, $key as item()) as empty-sequence() external",description:' Removes an entry identified by the given key from the map.\n If the map has only one key attribute, a single key value is given, for\n more than one key attribute an array of key values is given.\n Note that it is possible to insert entries with empty key attributes.\n However as the removing the entries is based on the "eq" comparison and\n as "eq" with an empty sequence always return false, it is not possible\n to delete these entries.\n',summary:"<p> Removes an entry identified by the given key from the map.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'},{name:"key",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> either a single attribute key or an array of keys</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately deletes the entry into the map but returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the given number of key attributes does not match the number of key attributes specified when creating the map (see the map:create function).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQD0005 if any of the given key attributes can not be cast (or is not a subtype) of the corresponding key attribute specified when creating the map.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"drop",qname:"map:drop",signature:"($name as string) as empty-sequence() external",description:" Deletes the map with the given name.\n",summary:"<p> Deletes the map with the given name.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map to drop</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately drops the map. It returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"get",qname:"map:get",signature:"($name as string, $key as item()) as item()* external",description:' Returns the value of the entry with the given key from the map.\n If the map has only one key attribute, a single key value is given, for\n more than one key attribute an array of key values is given.\n Note that it is possible to insert entries with empty key attributes.\n However as the getting the entries is based on the "eq" comparison and\n as "eq" with an empty sequence always return false, it is not possible\n to retrieve these entries.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>map:get("my-map", "key")</pre> or\n <pre>map:get("my-map", [ "key1", "key2" ])</pre>.</p>\n',summary:"<p> Returns the value of the entry with the given key from the map.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'},{name:"key",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> either a single attribute key or an array of keys</div>'}],returns:{type:"item()*",description:"the value of the entry in the map identified by the given key. The empty-sequence will be returned if no entry with the given key is contained in the map."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the given number of key attributes does not match the number of key attributes specified when creating the map (see the map:create function).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQD0005 if any of the given key attributes can not be cast (or is not a subtype) of the corresponding key attribute specified when creating the map.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"insert",qname:"map:insert",signature:"($name as string, $key as item(), $value as item()*) as empty-sequence() external",description:' Inserts a new entry into the map with the given name.\n If the map has only one key attribute, a single key value is given, for\n more than one key attribute an array of key values is given.\n If an entry with the given key already exists in the map, the value\n sequences of the existing entry and the sequence passed using $value\n argument are concatenated.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a map is persistent and if an item in the value sequence\n is an object or array, this item needs to belong to a collection,\n otherwise, an an error is raised.</p>\n Note that it is possible to insert entries with empty key attributes\n or key attributes having the value <code xmlns:xqdoc="http://www.xqdoc.org/1.0">null</code>. However, as\n the comparison with an empty sequence or null always returns false,\n it is not possible to retrieve these entries.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>map:insert("my-map", "key", "value")</pre> or\n <pre>map:insert("my-map", [ "key1", "key2" ] , (42, "value"))</pre>.</p>\n',summary:"<p> Inserts a new entry into the map with the given name.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'},{name:"key",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> either a single attribute key or an array of keys</div>'},{name:"value",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value of the entry to insert</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and immediately inserts the entry into the map. It returns the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the given number of key attributes does not match the number of key attributes specified when creating the map (see the map:create function).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQD0005 if any of the given key attributes can not be cast (or is not a subtype) of the corresponding key attribute specified when creating the map.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY1003 if the value to insert is an object or array it must belong to a collection.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"keys",qname:"map:keys",signature:"($name as string) as array()* external",description:' Returns the keys of all entries of a map. The keys\n are returned as sequence of arrays.\n The following condition always holds:\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">map:size($name) eq count(map:keys($name))</tt>\n',summary:"<p> Returns the keys of all entries of a map.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'}],returns:{type:"array()*",description:"an sequence of arrays each array containing the values of all attributes of one key."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"options",qname:"map:options",signature:"($name as string) as object() external",description:" The function returns the options that were passed during creation or the\n default options if no options were passed.\n",summary:"<p> The function returns the options that were passed during creation or the\n default options if no options were passed.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'}],returns:{type:"object()",description:"an options object"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"size",qname:"map:size",signature:"($name as string) as integer external",description:' The number of entries in a map.\n The following condition always holds:\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">map:size($name) eq count(map:keys($name))</tt>\n',summary:"<p> The number of entries in a map.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the map</div>'}],returns:{type:"integer",description:"the number of entries in the map."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if a map with the given name does not exist.</xqdoc:error>']}],variables:[]},"http://www.w3.org/2005/xpath-functions/math":{ns:"http://www.w3.org/2005/xpath-functions/math",description:' This module contains all the functions part of the\n W3C XPath and XQuery Functions and Operators 3.0\n section "4.7 Trigonometric and exponential functions".\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.w3.org/TR/xpath-functions-30/#trigonometry</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">www.w3c.org</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xpath-functions/math",prefix:"math"}],functions:[{isDocumented:!0,arity:1,name:"acos",qname:"math:acos",signature:"($arg as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the arc cosine of the argument, the result being in the range zero to\n                +<var>\u03c0</var> radians.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="acos" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the arc cosine of <code>$</code><var>\u03b8</var>,\n             treated as an angle in radians, as defined in the <bibref ref="ieee754-2008"/>\n             specification of the <code>acos</code> function applied to 64-bit binary floating point\n             values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of the <code>invalidOperation</code> exception is defined in <specref ref="op.numeric"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is <code>NaN</code>, or if its absolute value is greater than one,\n             then the result is <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In other cases the result is an <code>xs:double</code> value representing an angle\n                <var>\u03b8</var> in radians in the range <code>0 &lt;= $</code><var>\u03b8</var><code> &lt;=\n                +</code><var>\u03c0</var>. </p></div>\n',summary:"<p>  Returns the arc cosine of the argument, the result being in the range zero to\n                + \u03c0  radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"asin",qname:"math:asin",signature:"($arg as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the arc sine of the argument, the result being in the range\n                -<var>\u03c0</var>/2 to +<var>\u03c0</var>/2 radians.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="asin" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the arc sine of <code>$</code><var>\u03b8</var>,\n             treated as an angle in radians, as defined in the <bibref ref="ieee754-2008"/>\n             specification of the <code>asin</code> function applied to 64-bit binary floating point\n             values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of the <code>invalidOperation</code> and <code>underflow</code> exceptions\n             is defined in <specref ref="op.numeric"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is positive or negative zero, the result is <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is <code>NaN</code>, or if its absolute value is greater than one,\n             then the result is <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In other cases the result is an <code>xs:double</code> value representing an angle\n                <var>\u03b8</var> in radians in the range -<var>\u03c0</var><code>/2 &lt;=\n                $</code><var>\u03b8</var><code> &lt;= +</code><var>\u03c0</var><code>/2</code>. </p></div>\n',summary:"<p>  Returns the arc sine of the argument, the result being in the range\n                - \u03c0 /2 to + \u03c0 /2 radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"atan",qname:"math:atan",signature:"($arg as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the arc tangent of the argument, the result being in the range\n                -<var>\u03c0</var>/2 to +<var>\u03c0</var>/2 radians.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="atan" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the arc tangent of <code>$</code><var>\u03b8</var>,\n             treated as an angle in radians, as defined in the <bibref ref="ieee754-2008"/>\n             specification of the <code>atan</code> function applied to 64-bit binary floating point\n             values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of the <code>underflow</code> exception is defined in <specref ref="op.numeric"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is positive or negative zero, the result is <code>$arg</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is <code>NaN</code> then the result is <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">In other cases the result is an <code>xs:double</code> value representing an angle\n                <var>\u03b8</var> in radians in the range -<var>\u03c0</var><code>/2 &lt;=\n                $</code><var>\u03b8</var><code> &lt;= +</code><var>\u03c0</var><code>/2</code>. </p></div>\n',summary:"<p>  Returns the arc tangent of the argument, the result being in the range\n                - \u03c0 /2 to + \u03c0 /2 radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"atan2",qname:"math:atan2",signature:"($y as xs:double, $x as xs:double) as xs:double external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the angle in radians subtended at the origin by the point on a plane\n             with coordinates (x, y) and the positive x-axis, the result being in the range\n                -<var>\u03c0</var> to +<var>\u03c0</var>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="atan2" return-type="xs:double" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="y" type="xs:double"/><arg name="x" type="xs:double"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">The result is the value of <code>atan2(y, x)</code> as defined in the\n                <bibref ref="ieee754-2008"/> specification of the <code>atan2</code> function applied\n             to 64-bit binary floating point values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of the <code>underflow</code> exception is defined in <specref ref="op.numeric"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <phrase diff="chg" at="L">either argument</phrase> is <code>NaN</code>\n             then the result is <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$y</code> is positive and <code>$x</code> is positive and finite, then\n             (subject to rules for overflow, underflow and approximation)\n          the value of <code>atan2($y, $x)</code> is <code>atan($y div $x)</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$y</code> is positive and <code>$x</code> is negative and finite, then\n             (subject to the same caveats)\n             the value of <code>atan2($y, $x)</code> is <var>\u03c0</var> <code>- atan($y div $x)</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Some results for special values of the arguments are shown in the examples below.</p></div>\n',summary:"<p>  Returns the angle in radians subtended at the origin by the point on a plane\n             with coordinates (x, y) and the positive x-axis, the result being in the range\n                - \u03c0  to + \u03c0 .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"y",type:"xs:double",occurrence:null,description:""},{name:"x",type:"xs:double",occurrence:null,description:""}],returns:{type:"xs:double",description:""},errors:[]},{isDocumented:!0,arity:1,name:"cos",qname:"math:cos",signature:"($theta as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the cosine of the argument, expressed in radians.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="cos" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="\u03b8" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$</code><var>\u03b8</var> is the empty sequence, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$</code><var>\u03b8</var> is positive or negative infinity, or <code>NaN</code>,\n             then the result is <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the cosine of <code>$</code><var>\u03b8</var>,\n             treated as an angle in radians, as defined in the <bibref ref="ieee754-2008"/>\n             specification of the <code>cos</code> function applied to 64-bit binary floating point\n             values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of the <code>invalidOperation</code> exception is defined in <specref ref="op.numeric"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$</code><var>\u03b8</var> is positive or negative zero, the result is\n                <code>$</code><var>\u03b8</var>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$</code><var>\u03b8</var> is positive or negative infinity, or <code>NaN</code>,\n             then the result is <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise the result is always in the range -1.0e0 to +1.0e0</p></div>\n',summary:"<p>  Returns the cosine of the argument, expressed in radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"theta",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"exp",qname:"math:exp",signature:"($arg as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of <var>e</var><sup><var>x</var></sup>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="exp" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the mathematical constant <var>e</var>\n             raised to the power of <code>$arg</code>, as defined in the <bibref ref="ieee754-2008"/>\n             specification of the <code>exp</code> function applied to 64-bit binary floating point\n             values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of overflow and underflow is defined in <specref ref="op.numeric"/>.</p></div>\n',summary:"<p>  Returns the value of  e x .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"exp10",qname:"math:exp10",signature:"($arg as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the value of <code>10</code><sup><var>x</var></sup>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="exp10" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is ten raised to the power of <code>$arg</code>,\n             as defined in the <bibref ref="ieee754-2008"/> specification of the <code>exp10</code>\n             function applied to 64-bit binary floating point values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of overflow and underflow is defined in <specref ref="op.numeric"/>.</p></div>\n',summary:"<p>  Returns the value of  10 x .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"log",qname:"math:log",signature:"($arg as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the natural logarithm of the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="log" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the natural logarithm of <code>$arg</code>, as\n             defined in the <bibref ref="ieee754-2008"/> specification of the <code>log</code>\n             function applied to 64-bit binary floating point values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of <code>divideByZero</code> and <code>invalidOperation</code> exceptions\n             is defined in <specref ref="op.numeric"/>. The effect is that if the argument is less\n             than or equal to zero, the result is <code>NaN</code>.</p></div>\n',summary:"<p>  Returns the natural logarithm of the argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"log10",qname:"math:log10",signature:"($arg as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the base-ten logarithm of the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="log10" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the base-10 logarithm of <code>$arg</code>, as\n             defined in the <bibref ref="ieee754-2008"/> specification of the <code>log10</code>\n             function applied to 64-bit binary floating point values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of <code>divideByZero</code> and <code>invalidOperation</code> exceptions\n             is defined in <specref ref="op.numeric"/>. The effect is that if the argument is less\n             than or equal to zero, the result is <code>NaN</code>.</p></div>\n',summary:"<p>  Returns the base-ten logarithm of the argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"pi",qname:"math:pi",signature:"() as xs:double external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns an approximation to the mathematical constant <var>\u03c0</var>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="pi" return-type="xs:double" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function returns the <code>xs:double</code> value whose lexical representation is\n             3.141592653589793e0</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>2*math:pi()</code> returns <code>6.283185307179586e0</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The expression <code>60 * (math:pi() div 180)</code> converts an angle of 60 degrees\n                to radians. </p></div>\n',summary:"<p>  Returns an approximation to the mathematical constant  \u03c0 .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:double",description:""},errors:[]},{isDocumented:!0,arity:2,name:"pow",qname:"math:pow",signature:"($x as xs:double?, $y as numeric) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the result of raising the first argument to the power of the\n             second.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="pow" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="x" type="xs:double?"/><arg name="y" type="numeric"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$x</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$y</code> is an instance of <code>xs:integer</code>, the result is\n                <code>$x</code> raised to the power of <code>$y</code> as defined in the <bibref ref="ieee754-2008"/> specification of the <code>pown</code> function applied to a\n             64-bit binary floating point value and an integer.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise <code>$y</code> is converted to an <code>xs:double</code> by numeric\n             promotion, and the result is the value of <code>$x</code> raised to the power of\n                <code>$y</code> as defined in the <bibref ref="ieee754-2008"/> specification of the\n                <code>pow</code> function applied to two 64-bit binary floating point values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of the <code>divideByZero</code> and <code>invalidOperation</code>\n             exceptions is defined in <specref ref="op.numeric"/>. Some of the consequences are\n             illustrated in the examples below.</p></div>\n',summary:"<p>  Returns the result of raising the first argument to the power of the\n             second.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"xs:double",occurrence:"?",description:""},{name:"y",type:"numeric",occurrence:null,description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sin",qname:"math:sin",signature:"($theta as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the sine of the argument, expressed in radians.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="sin" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="\u03b8" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$</code><var>\u03b8</var> is the empty sequence, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the sine of <code>$</code><var>\u03b8</var>,\n             treated as an angle in radians, as defined in the <bibref ref="ieee754-2008"/>\n             specification of the <code>sin</code> function applied to 64-bit binary floating point\n             values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of the <code>invalidOperation</code> and <code>underflow</code> exceptions\n             is defined in <specref ref="op.numeric"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$</code><var>\u03b8</var> is positive or negative zero, the result is\n                <code>$</code><var>\u03b8</var>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$</code><var>\u03b8</var> is positive or negative infinity, or <code>NaN</code>,\n             then the result is <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Otherwise the result is always in the range -1.0e0 to +1.0e0</p></div>\n',summary:"<p>  Returns the sine of the argument, expressed in radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"theta",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sqrt",qname:"math:sqrt",signature:"($arg as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the non-negative square root of the argument.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="sqrt" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is the empty sequence, the function returns the empty sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the mathematical non-negative square root of\n                <code>$arg</code> as defined in the <bibref ref="ieee754-2008"/> specification of the\n                <code>squareRoot</code> function applied to 64-bit binary floating point values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of the <code>invalidOperation</code> exception is defined in <specref ref="op.numeric"/>. The effect is that if the argument is less than zero, the result\n             is <code>NaN</code>.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$arg</code> is positive or negative zero, positive infinity, or\n                <code>NaN</code>, then the result is <code>$arg</code>. (Negative zero is the only\n             case where the result can have negative sign)</p></div>\n',summary:"<p>  Returns the non-negative square root of the argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"tan",qname:"math:tan",signature:"($theta as xs:double?) as xs:double? external",description:' <div xmlns:xqdoc="http://www.xqdoc.org/1.0"><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">Returns the tangent of the argument, expressed in radians.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax"><example role="signature"><proto name="tan" return-type="xs:double?" isOp="no" prefix="math" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="\u03b8" type="xs:double?"/></proto></example></p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$</code><var>\u03b8</var> is the empty sequence, the function returns the empty\n             sequence.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" diff="chg" at="G">Otherwise the result is the tangent of <code>$</code><var>\u03b8</var>,\n             treated as an angle in radians, as defined in the <bibref ref="ieee754-2008"/>\n             specification of the <code>tan</code> function applied to 64-bit binary floating point\n             values.</p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">The treatment of the <code>invalidOperation</code> and <code>underflow</code> exceptions\n             is defined in <specref ref="op.numeric"/>. </p><p xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax">If <code>$</code><var>\u03b8</var> is positive or negative infinity, or <code>NaN</code>,\n             then the result is <code>NaN</code>.</p></div>\n',summary:"<p>  Returns the tangent of the argument, expressed in radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"theta",type:"xs:double",occurrence:"?",description:""}],returns:{type:"xs:double?",description:""},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/oauth/client":{ns:"http://www.zorba-xquery.com/modules/oauth/client",description:' This module provides the functions necessary to acquire access to the personal\n resources of a user through the open standard called\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://oauth.net/" target="_blank">OAuth</a>.\n The application/mashup creator does not need to know the\n specifics of <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://oauth.net/" target="_blank">OAuth</a> to use this module.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://oauth.net/" target="_blank">OAuth Website</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Stephanie Russell</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="mailto:william.candillon@28msec.com">William Candillon</a></xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/base64",prefix:"base64"},{uri:"http://zorba.io/features",prefix:"f"},{uri:"http://zorba.io/modules/hmac",prefix:"hmac"},{uri:"http://expath.org/ns/http-client",prefix:"http"},{uri:"http://expath.org/ns/http-client",prefix:"http-client"},{uri:"http://www.zorba-xquery.com/modules/oauth/client",prefix:"oauth"},{uri:"http://www.zorba-xquery.com/modules/oauth/error",prefix:"oerr"},{uri:"http://zorba.io/options/features",prefix:"op"},{uri:"http://www.zorba-xquery.com/schemas/oauth/parameters",prefix:"p"},{uri:"http://zorba.io/modules/random",prefix:"ra"},{uri:"http://www.zorba-xquery.com/schemas/oauth/service-provider",prefix:"sp"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"access-token",qname:"oauth:access-token",signature:"($service-provider as schema-element(sp:service-provider), $parameters as schema-element(p:parameters)) as schema-element(p:parameters)",description:" This function allows the client to obtain a set of token credentials from the service provider by making an authenticated HTTP request to the Token Request endpoint.\n This function is provided for convenience.\n",summary:"<p> This function allows the client to obtain a set of token credentials from the service provider by making an authenticated HTTP request to the Token Request endpoint.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"service-provider",type:"schema-element(sp:service-provider)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Contains service provider information</div>'},{name:"parameters",type:"schema-element(p:parameters)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> parameters</div>'}],returns:{type:"schema-element(p:parameters)",description:'token credentials correctly parsed as parameter elements, or an error if http response status is not 200 OK <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery"> let $service-provider := oauth:service-provider(...) let $parameters := oauth:parameters("oauth_token", "#") let $parameters := oauth:add-parameter($parameters, "oauth_token_secret", "#") let $tokens := oauth:access-token($service-provider, $parameters) ... </pre>'},errors:[]},{isDocumented:!0,arity:3,name:"add-parameter",qname:"oauth:add-parameter",signature:"($parameters as schema-element(p:parameters)?, $name as xs:string, $value as xs:string) as schema-element(p:parameters)",description:' Adds an OAuth parameter to an OAuth Parameters instance.\n Instances of OAuth parameters are used to\n contain value/pair data such as <em xmlns:xqdoc="http://www.xqdoc.org/1.0">oauth_token</em>\n and <em xmlns:xqdoc="http://www.xqdoc.org/1.0">oauth_token_secret</em>.\n For instance the following code snippet:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n  let $params := oauth:parameters("oauth_token", "#")\n  let $params := oauth:add-parameter($params, "oauth_token_secret", "#")\n  return $params\n </pre>\n Returns the following XML schema instance:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n <p:parameters xmlns:p="http://www.zorba-xquery.com/schemas/oauth/parameters">\n   <p:parameter name="oauth_token" value="#"/>\n   <p:parameter name="oauth_token_secret" value="#"/>\n </p:parameters>\n </pre>\n',summary:"<p> Adds an OAuth parameter to an OAuth Parameters instance.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"parameters",type:"schema-element(p:parameters)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> parameters</div>'},{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> parameter name</div>'},{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> parameter value</div>'}],returns:{type:"schema-element(p:parameters)",description:"instance of the OAuth parameters XML schema."},errors:[]},{isDocumented:!0,arity:2,name:"parameter",qname:"oauth:parameter",signature:"($params as schema-element(p:parameters), $string as xs:string) as xs:string",description:" This function returns the string value of the parameters whose key matches a $string input.\n",summary:"<p> This function returns the string value of the parameters whose key matches a $string input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"params",type:"schema-element(p:parameters)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> element parameters</div>'},{name:"string",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> string as the "key" name</div>'}],returns:{type:"xs:string",description:'string value of the parameter with key $string <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery"> let $params := oauth:parameters("oauth_token", "token") let $params := oauth:add-parameter($params, "oauth_token_secret", "secret") let $token-secret := oauth:parameter($params, "oauth_token_secret") return $token-secret </pre>'},errors:[]},{isDocumented:!0,arity:2,name:"parameters",qname:"oauth:parameters",signature:"($name as xs:string, $value as xs:string) as element(p:parameters)",description:' Create an OAuth Parameters instance.\n Instances of OAuth parameters are used to\n contain value/pair data such as <em xmlns:xqdoc="http://www.xqdoc.org/1.0">oauth_token</em>\n and <em xmlns:xqdoc="http://www.xqdoc.org/1.0">oauth_token_secret</em>.\n For instance the following code snippet:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n  oauth:parameters("oauth_token", "#")\n </pre>\n Returns the following XML schema instance:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xml">\n <p:parameters xmlns:p="http://www.zorba-xquery.com/schemas/oauth/parameters">\n   <p:parameter name="oauth_token" value="#"/>\n </p:parameters>\n </pre>\n',summary:"<p> Create an OAuth Parameters instance.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> parameter name</div>'},{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> parameter value</div>'}],returns:{type:"element(p:parameters)",description:"instance of the OAuth parameters XML schema."},errors:[]},{isDocumented:!0,arity:3,name:"protected-resource",qname:"oauth:protected-resource",signature:"($protected-resource as schema-element(http:request), $service-provider as schema-element(sp:service-provider), $parameters as schema-element(p:parameters)) as item()*",description:" This function allows the client access to the protected resources of the user.\n This function is provided for convenience.\n",summary:"<p> This function allows the client access to the protected resources of the user.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"protected-resource",type:"schema-element(http:request)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> (Not schema-validated) http:request element with http method and href.</div>'},{name:"service-provider",type:"schema-element(sp:service-provider)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Information about the service provider</div>'},{name:"parameters",type:"schema-element(p:parameters)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> parameters</div>'}],returns:{type:"item()*",description:'protected resources parsed as parameter elements, or an error if http response status is not 200 OK <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery"> let $tokens := oauth:parameters("oauth_token", "#") let $tokens := oauth:add-parameter($tokens, "oauth_token_secret", "#") let $service-provider := oauth:service-provider(...) let $request := validate { <request xmlns="http://expath.org/ns/http-client" href="http://twitter.com/account/verify_credentials.xml" method="GET"/> } return oauth:protected-resource($request, $service-provider, $tokens) </pre>'},errors:[]},{isDocumented:!0,arity:1,name:"request-token",qname:"oauth:request-token",signature:"($service-provider as schema-element(sp:service-provider)) as schema-element(p:parameters)",description:' This function allows the client to obtain a set of temporary credentials from the service provider by making an authenticated HTTP request to the Temporary Credential Request endpoint.\n This function is provided for convenience for <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#request-token-2">request-token#2</a>.\n Invoking this function is equivalent to:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n oauth:request-token($service-provider, ())\n </pre>\n',summary:"<p> This function allows the client to obtain a set of temporary credentials from the service provider by making an authenticated HTTP request to the Temporary Credential Request endpoint.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"service-provider",type:"schema-element(sp:service-provider)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Information about the service provider</div>'}],returns:{type:"schema-element(p:parameters)",description:"temporary credentials correctly parsed as parameter elements, or an error if http response status is not 200 OK"},errors:[]},{isDocumented:!0,arity:2,name:"request-token",qname:"oauth:request-token",signature:"($service-provider as schema-element(sp:service-provider), $parameters as schema-element(p:parameters)?) as schema-element(p:parameters)",description:" This function allows the client to obtain a set of temporary credentials from the service provider by making an authenticated HTTP request to the Temporary Credential Request endpoint.\n This function is provided for convenience.\n",summary:"<p> This function allows the client to obtain a set of temporary credentials from the service provider by making an authenticated HTTP request to the Temporary Credential Request endpoint.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"service-provider",type:"schema-element(sp:service-provider)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Information about the service provider</div>'},{name:"parameters",type:"schema-element(p:parameters)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Additionnal parameters to the request</div>'}],returns:{type:"schema-element(p:parameters)",description:'temporary credentials correctly parsed as parameter elements, or an error if http response status is not 200 OK <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery"> let $twitter-config := oauth:service-provider(...) let $additional-parameter := oauth:parameters("foo", "bar") let $tokens := oauth:request-token($twitter-config, $additional-parameter) let $token := oauth:parameter($tokens, "oauth_token") let $token-secret := oauth:parameter($tokens, "oauth_token_secret") ... </pre>'},errors:[]},{isDocumented:!0,arity:10,name:"service-provider",qname:"oauth:service-provider",signature:"($consumer-key as xs:string, $consumer-secret as xs:string, $signature-method as xs:string, $realm as xs:string, $authorize-url as xs:string, $request-token-method as xs:string, $request-token-url as xs:string, $request-token-callback-url as xs:string, $access-token-method as xs:string, $access-token-url as xs:string) as schema-element(sp:service-provider)",description:' Utility function to build a service provider object.\n This object contains the information required by the\n OAuth client to interact with an OAuth service provider.\n For instance the following expression:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n let $consumer-key     := "#"\n let $consumer-secret  := "#"\n let $signature-method := "HMAC-SHA1"\n let $realm            := "twitter.com"\n let $authorize-url    := "http://api.twitter.com/oauth/authorize"\n let $request-token-method := "POST"\n let $request-token-url := "https://twitter.com/oauth/request_token"\n let $request-token-callback-url := "https://twitter.com/oauth/request_token"\n let $access-token-method := "POST"\n let $access-token-url := "https://api.twitter.com/oauth/access_token"\n return oauth:service-provider(\n   $consumer-key, $consumer-secret, $signature-method,\n   $realm, $authorize-url, $request-token-method,\n   $request-token-url, $request-token-callback-url,\n   $access-token-method, $access-token-url\n )\n </pre>\n Will return the following XML schema instance:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xml">\n <sp:service-provider xmlns:sp="http://www.zorba-xquery.com/schemas/oauth/service-provider" consumer-key="#" consumer-secret="#" signature-method="HMAC-SHA1" realm="twitter.com" authorize-url="http://api.twitter.com/oauth/authorize">\n   <sp:request-token method="POST" href="https://twitter.com/oauth/request_token" callback-url="https://twitter.com/oauth/request_token"/>\n   <sp:access-token method="POST" href="https://api.twitter.com/oauth/access_token"/>\n </sp:service-provider>\n </pre>\n',summary:"<p> Utility function to build a service provider object.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"consumer-key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Client Identifier, also known as the consumer-key</div>'},{name:"consumer-secret",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Client Shared-Secret, also known as the consumer-secret</div>'},{name:"signature-method",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Method with which the signing key is signed (typically HMAC-SHA1)</div>'},{name:"realm",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Realm that defines the protection space</div>'},{name:"authorize-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> authorize-url</div>'},{name:"request-token-method",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> request-token-method</div>'},{name:"request-token-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> request-token-url</div>'},{name:"request-token-callback-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> request-token-callback-url</div>'},{name:"access-token-method",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> access-token-method</div>'},{name:"access-token-url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> access-token-url</div>'}],returns:{type:"schema-element(sp:service-provider)",description:"instance of the OAuth service provider XML schema."},errors:[]}],variables:[]},"http://www.28msec.com/modules/http/util/multipart":{ns:"http://www.28msec.com/modules/http/util/multipart",description:" This module provides utility functions to help dealing with the\n content of multipart requests.\n In their implementation, all the functions use the multipart\n related functions of the request module (e.g. parts() or text-part()).\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.28msec.com/modules/http/util/multipart",prefix:"multipart"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"binary-content",qname:"multipart:binary-content",signature:"($name as xs:string) as xs:base64Binary*",description:" Returns the contents of the parts/files in the multipart requests with\n the given part name as xs:base64Binary.\n",summary:"<p> Returns the contents of the parts/files in the multipart requests with\n the given part name as xs:base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the requested part.</div>'}],returns:{type:"xs:base64Binary*",description:"the said content or the empty sequence if no part with the given name exists."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:1,name:"binary-file",qname:"multipart:binary-file",signature:"($filename as xs:string) as xs:base64Binary*",description:" Returns the contents of the part/file in the multipart requests with\n the given filename as xs:base64Binary.\n Please note that the file is identified by the filename (and not the\n name of the part) that is contained in the Content-Disposition header\n of the part.\n",summary:"<p> Returns the contents of the part/file in the multipart requests with\n the given filename as xs:base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filename",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the requested file.</div>'}],returns:{type:"xs:base64Binary*",description:"the said content or the empty sequence if no part with the given filename exists."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:1,name:"content-length",qname:"multipart:content-length",signature:"($name as xs:string) as xs:integer*",description:" Returns the content length of the parts/files in the multipart requests with\n the given part name as xs:integer.\n",summary:"<p> Returns the content length of the parts/files in the multipart requests with\n the given part name as xs:integer.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the requested part.</div>'}],returns:{type:"xs:integer*",description:"The content-length in bytes of the parts/files or the empty sequence if the part does not exist"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:1,name:"content-type",qname:"multipart:content-type",signature:"($name as xs:string) as xs:string*",description:" Returns the content type of the parts/files in the multipart requests with\n the given part name as xs:string.\n",summary:"<p> Returns the content type of the parts/files in the multipart requests with\n the given part name as xs:string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the requested part.</div>'}],returns:{type:"xs:string*",description:"The content-types of the parts/files or the empty sequence if the part does not exist"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:1,name:"filename",qname:"multipart:filename",signature:"($name as xs:string) as xs:string*",description:" Returns the filenames of the parts/files in the multipart requests with\n the given part name as xs:string.\n",summary:"<p> Returns the filenames of the parts/files in the multipart requests with\n the given part name as xs:string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the requested part.</div>'}],returns:{type:"xs:string*",description:"The filename of the parts/files or the empty sequence if the part does not exist"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:0,name:"filenames",qname:"multipart:filenames",signature:"() as xs:string*",description:" Returns the filenames of all the parts contained in the multipart\n content of the given request.\n",summary:"<p> Returns the filenames of all the parts contained in the multipart\n content of the given request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"the said filenames"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:0,name:"names",qname:"multipart:names",signature:"() as xs:string*",description:" Returns the names of all the parts contained in the multipart\n content of the given request.\n",summary:"<p> Returns the names of all the parts contained in the multipart\n content of the given request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"the said names"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:1,name:"part",qname:"multipart:part",signature:"($name as xs:string) as element(req:part)*",description:' Returns the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">req:part</tt> element among all the parts contained\n in the multipart requests with the given name.\n',summary:"<p> Returns the  req:part  element among all the parts contained\n in the multipart requests with the given name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the requested part.</div>'}],returns:{type:"element(req:part)*",description:"the said part elements or the empty sequence if no part with the given name exists."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:1,name:"text-content",qname:"multipart:text-content",signature:"($name as xs:string) as xs:string*",description:" Returns the contents of the parts/files in the multipart requests with\n the given part name as a string.\n It is assumed that the character set of the file is UTF-8.\n",summary:"<p> Returns the contents of the parts/files in the multipart requests with\n the given part name as a string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the requested part.</div>'}],returns:{type:"xs:string*",description:"the said content or the empty sequence if no part with the given filename exists."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the value of the part cannot be treated as text</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:1,name:"text-file",qname:"multipart:text-file",signature:"($filename as xs:string) as xs:string*",description:" Returns the contents of the part/file in the multipart requests with\n the given filename as a string.\n It is assumed that the character set of the file is UTF-8.\n Please note that the file is identified by the filename (and not the\n name of the part) that is contained in the Content-Disposition header\n of the part.\n",summary:"<p> Returns the contents of the part/file in the multipart requests with\n the given filename as a string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filename",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the requested file.</div>'}],returns:{type:"xs:string*",description:"the said content or the empty sequence if no part with the given filename exists."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the value of the part cannot be treated as text</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/excel/statistical-zorba":{ns:"http://zorba.io/modules/excel/statistical-zorba",description:" This module implements some Excel 2003 statistical functions\n that cannot be implemented with standard XQuery functions.\n It uses Zorba specific functions.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://office.microsoft.com/en-us/excel/CH062528311033.aspx</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Turcanu</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/statistical-zorba",prefix:"excel"},{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/modules/excel/math",prefix:"excel-math"},{uri:"http://zorba.io/modules/excel/statistical",prefix:"excel-statistical"},{uri:"http://www.w3.org/2005/xpath-functions/math",prefix:"math"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"stdev",qname:"excel:stdev",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:" Estimates standard deviation based on a sample.\n The standard deviation is a measure of how widely values are dispersed\n   from the average value (the mean).\n It is computed with formula:\n sqrt( sum((x-average_x)^2) / (n-1) )    = sqrt ( VAR(numbers) )\n",summary:"<p> Estimates standard deviation based on a sample.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"the standard deviation, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"stdeva",qname:"excel:stdeva",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:" Estimates standard deviation based on a sample.\n The standard deviation is a measure of how widely values are dispersed\n   from the average value (the mean).\n It is computed with formula:\n sqrt( sum((x-average_x)^2) / (n-1) )    = sqrt ( VARA(numbers) )\n",summary:"<p> Estimates standard deviation based on a sample.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"the standard deviation, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"stdevp",qname:"excel:stdevp",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:" Calculates standard deviation based on the entire population given as arguments.\n The standard deviation is a measure of how widely values are dispersed from\n   the average value (the mean).\n It is computed with formula:\n sqrt( sum((x-average_x)^2) / n )    = sqrt ( VARP(numbers) )\n",summary:"<p> Calculates standard deviation based on the entire population given as arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"the standard deviation, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:1,name:"stdevpa",qname:"excel:stdevpa",signature:"($numbers as xs:anyAtomicType+) as xs:anyAtomicType",description:" Calculates standard deviation based on the entire population given as arguments.\n The standard deviation is a measure of how widely values are dispersed from\n   the average value (the mean).\n It is computed with formula:\n sqrt( sum((x-average_x)^2) / n )    = sqrt ( VARPA(numbers) )\n",summary:"<p> Calculates standard deviation based on the entire population given as arguments.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"numbers",type:"xs:anyAtomicType",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric The sequence can be of any length, from 1 up.</div>'}],returns:{type:"xs:anyAtomicType",description:"the standard deviation, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if the parameters cannot be casted to numeric type</xqdoc:error>']},{isDocumented:!0,arity:2,name:"subtotal",qname:"excel:subtotal",signature:"($function_num as xs:integer, $numbers as xs:anyAtomicType*) as xs:anyAtomicType",description:" Moved from math module.\n Returns a subtotal in a sequence of numbers.\n The function applied is given by $function_num.\n",summary:"<p> Moved from math module.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"function_num",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <dl>defines the function to be applied on sequence values. The possible values are: <dt>1 or 101</dt> <dd> AVERAGE</dd> <dt>2 or 102</dt> <dd> COUNT</dd> <dt>3 or 103</dt> <dd> COUNTA</dd> <dt>4 or 104</dt> <dd> MAX</dd> <dt>5 or 105</dt> <dd> MIN</dd> <dt>6 or 106</dt> <dd> PRODUCT</dd> <dt>7 or 107</dt> <dd> STDEV</dd> <dt>8 or 108</dt> <dd> STDEVP</dd> <dt>9 or 109</dt> <dd> SUM</dd> <dt>10 or 110</dt> <dd> VAR</dd> <dt>11 or 111</dt> <dd> VARP</dd></dl> In this implementation there is no difference between x and 10x.<p/></div>'},{name:"numbers",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of numbers or values castable to numeric. The sequence can be of any length.</div>'}],returns:{type:"xs:anyAtomicType",description:"The function result, as numeric type"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">depends on the function called</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if $function_num is not a value between 1 .. 11 or 101 .. 111</xqdoc:error>']}],variables:[]},"http://www.28msec.com/modules/debug":{ns:"http://www.28msec.com/modules/debug",description:" This module contains internal debug functions.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/debug",prefix:"debug"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"non-seeakable-streamable-string",qname:"debug:non-seeakable-streamable-string",signature:"() as string external",description:" Returns a non seekable streamable string\n",summary:"<p> Returns a non seekable streamable string\n</p>",annotation_str:" %an:deterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"deterministic",value:""}],updating:!1,parameters:[],returns:{type:"string",description:"a non seekable streamable string"},errors:[]},{isDocumented:!0,arity:1,name:"test-01-cache",qname:"debug:test-01-cache",signature:"($arg as xs:integer) as item()* external",description:' Equivalent to:\n declare %an:cache function local:test-01-cache($x as xs:integer)\n {\n  if ($x &lt; 10)\n  then $x * $x\n  else if ($x &lt; 20)\n  then ()\n  else ($x, " == ", $x * $x)\n };\n',summary:'<p> Equivalent to:\n declare %an:cache function local:test-01-cache($x as xs:integer)\n {\n  if ($x &lt; 10)\n  then $x * $x\n  else if ($x &lt; 20)\n  then ()\n  else ($x, " == ", $x * $x)\n };\n</p>',annotation_str:" %an:cache",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"cache",value:""}],updating:!1,parameters:[{name:"arg",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'}],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:1,name:"test-01-sd",qname:"debug:test-01-sd",signature:"($arg as xs:integer) as item()* external",description:' Equivalent to:\n declare %an:strictlydeterministic function local:test-01-sd($x as xs:integer)\n {\n  if ($x &lt; 10)\n  then $x * $x\n  else if ($x &lt; 20)\n  then ()\n  else ($x, " == ", $x * $x)\n };\n',summary:'<p> Equivalent to:\n declare %an:strictlydeterministic function local:test-01-sd($x as xs:integer)\n {\n  if ($x &lt; 10)\n  then $x * $x\n  else if ($x &lt; 20)\n  then ()\n  else ($x, " == ", $x * $x)\n };\n</p>',annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[{name:"arg",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'}],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:1,name:"test-02-cache",qname:"debug:test-02-cache",signature:"($arg) as item()* external",description:" Equivalent to:\n declare %an:cache function local:test-02-cache($arg)\n {\n   serialize($arg),\n   uuid:uuid()\n };\n",summary:"<p> Equivalent to:\n declare %an:cache function local:test-02-cache($arg)\n {\n   serialize($arg),\n   uuid:uuid()\n };\n</p>",annotation_str:" %an:cache",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"cache",value:""}],updating:!1,parameters:[{name:"arg",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'}],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:1,name:"test-02-sd",qname:"debug:test-02-sd",signature:"($arg) as item()* external",description:" Equivalent to:\n declare %an:strictlydeterministic function local:test-02-sd($arg)\n {\n   serialize($arg),\n   uuid:uuid()\n };\n",summary:"<p> Equivalent to:\n declare %an:strictlydeterministic function local:test-02-sd($arg)\n {\n   serialize($arg),\n   uuid:uuid()\n };\n</p>",annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[{name:"arg",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'}],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:0,name:"test-03-cache",qname:"debug:test-03-cache",signature:"() as item()* external",description:' Equivalent to:\n declare %an:cache function local:test-03-cache()\n {\n   { "a" : 1 },\n   [1],\n   &lt;a/&gt;,\n   1\n };\n',summary:'<p> Equivalent to:\n declare %an:cache function local:test-03-cache()\n {\n   { "a" : 1 },\n   [1],\n   &lt;a/&gt;,\n   1\n };\n</p>',annotation_str:" %an:cache",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"cache",value:""}],updating:!1,parameters:[],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:0,name:"test-03-sd",qname:"debug:test-03-sd",signature:"() as item()* external",description:' Equivalent to:\n declare %an:strictlydeterministic function local:test-03-sd()\n {\n   { "a" : 1 },\n   [1],\n   &lt;a/&gt;,\n   1\n };\n',summary:'<p> Equivalent to:\n declare %an:strictlydeterministic function local:test-03-sd()\n {\n   { "a" : 1 },\n   [1],\n   &lt;a/&gt;,\n   1\n };\n</p>',annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:2,name:"test-04-cache",qname:"debug:test-04-cache",signature:"($x, $y) as item()* external",description:' Equivalent to:\n declare %an:cache function local:test-04-cache($x, $y)\n {\n   debug:non-seeakable-streamable-string(),\n   {"key" : debug:non-seeakable-streamable-string()},\n   [debug:non-seeakable-streamable-string()],\n   &lt;a&gt;{debug:non-seeakable-streamable-string()}&lt;/a&gt;\n   serialize($x),\n   serialize($y)\n };\n',summary:'<p> Equivalent to:\n declare %an:cache function local:test-04-cache($x, $y)\n {\n   debug:non-seeakable-streamable-string(),\n   {"key" : debug:non-seeakable-streamable-string()},\n   [debug:non-seeakable-streamable-string()],\n   &lt;a&gt;{debug:non-seeakable-streamable-string()}&lt;/a&gt;\n   serialize($x),\n   serialize($y)\n };\n</p>',annotation_str:" %an:cache",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"cache",value:""}],updating:!1,parameters:[{name:"x",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'},{name:"y",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'}],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:2,name:"test-04-sd",qname:"debug:test-04-sd",signature:"($x, $y) as item()* external",description:' Equivalent to:\n declare %an:strictlydeterministic function local:test-04-sd($x, $y)\n {\n   debug:non-seeakable-streamable-string(),\n   {"key" : debug:non-seeakable-streamable-string()},\n   [debug:non-seeakable-streamable-string()],\n   &lt;a&gt;{debug:non-seeakable-streamable-string()}&lt;/a&gt;\n   serialize($x),\n   serialize($y)\n };\n',summary:'<p> Equivalent to:\n declare %an:strictlydeterministic function local:test-04-sd($x, $y)\n {\n   debug:non-seeakable-streamable-string(),\n   {"key" : debug:non-seeakable-streamable-string()},\n   [debug:non-seeakable-streamable-string()],\n   &lt;a&gt;{debug:non-seeakable-streamable-string()}&lt;/a&gt;\n   serialize($x),\n   serialize($y)\n };\n</p>',annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[{name:"x",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'},{name:"y",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'}],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:2,name:"test-05-cache",qname:"debug:test-05-cache",signature:"($x as xs:boolean, $y) as item()* external",description:" Equivalent to:\n declare %an:cache function local:test-05-cache($x as xs:boolean, $y)\n {\n   if ($x)\n   then $y\n   else $x\n };\n",summary:"<p> Equivalent to:\n declare %an:cache function local:test-05-cache($x as xs:boolean, $y)\n {\n   if ($x)\n   then $y\n   else $x\n };\n</p>",annotation_str:" %an:cache",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"cache",value:""}],updating:!1,parameters:[{name:"x",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'},{name:"y",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'}],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:2,name:"test-05-sd",qname:"debug:test-05-sd",signature:"($x as xs:boolean, $y) as item()* external",description:" Equivalent to:\n declare %an:strictlydeterministic function local:test-05-sd($x as xs:boolean, $y)\n {\n   if ($x)\n   then $y\n   else $x\n };\n",summary:"<p> Equivalent to:\n declare %an:strictlydeterministic function local:test-05-sd($x as xs:boolean, $y)\n {\n   if ($x)\n   then $y\n   else $x\n };\n</p>",annotation_str:" %an:strictlydeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"strictlydeterministic",value:""}],updating:!1,parameters:[{name:"x",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'},{name:"y",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> as described above</div>'}],returns:{type:"item()*",description:"as described above"},errors:[]},{isDocumented:!0,arity:0,name:"uuid",qname:"debug:uuid",signature:"() as string external",description:" This function is not deterministic despite the annotation\n",summary:"<p> This function is not deterministic despite the annotation\n</p>",annotation_str:" %an:deterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"deterministic",value:""}],updating:!1,parameters:[],returns:{type:"string",description:"a uuid"},errors:[]}],variables:[]},"http://zorba.io/modules/json-xml":{ns:"http://zorba.io/modules/json-xml",description:' Using this module, you can parse JSON data into XML, manipulate it like any\n other XML data using XQuery, and serialize the result back as JSON.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n There are many ways to represent JSON data in XML, some loss-less ("round\n tripable") and some lossy ("one way").  Loss-less representations preserve\n the JSON data types <i xmlns:xqdoc="http://www.xqdoc.org/1.0">boolean</i>, <i xmlns:xqdoc="http://www.xqdoc.org/1.0">number</i>, and <i xmlns:xqdoc="http://www.xqdoc.org/1.0">null</i>; lossy\n representations convert all data to strings.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n For a loss-less representation, this module implements that proposed by\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://john.snelson.org.uk/parsing-json-into-xquery">John Snelson</a>.\n For example:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="java">\n   {\n     "firstName" : "John",\n     "lastName" : "Smith",\n     "address" : {\n       "streetAddress" : "21 2nd Street",\n       "city" : "New York",\n       "state" : "NY",\n       "postalCode" : 10021\n     },\n     "phoneNumbers" : [ "212 732-1234", "646 123-4567" ]\n   }\n </pre>\n would be represented as:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n   &lt;json type="object"&gt;\n     &lt;pair name="firstName" type="string"&gt;John&lt;/pair&gt;\n     &lt;pair name="lastName" type="string"&gt;Smith&lt;/pair&gt;\n     &lt;pair name="address" type="object"&gt;\n       &lt;pair name="streetAddress" type="string"&gt;21 2nd Street&lt;/pair&gt;\n       &lt;pair name="city" type="string"&gt;New York&lt;/pair&gt;\n       &lt;pair name="state" type="string"&gt;NY&lt;/pair&gt;\n       &lt;pair name="postalCode" type="number"&gt;10021&lt;/pair&gt;\n     &lt;/pair&gt;\n     &lt;pair name="phoneNumbers" type="array"&gt;\n       &lt;item type="string"&gt;212 732-1234&lt;/item&gt;\n       &lt;item type="string"&gt;646 123-4567&lt;/item&gt;\n     &lt;/pair&gt;\n   &lt;/json&gt;\n </pre>\n For a lossy representation, this module implements\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://jsonml.org/">JsonML</a> (the array form).\n For example:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="java">\n   [ "person",\n     { "created" : "2006-11-11T19:23",\n       "modified" : "2006-12-31T23:59" },\n     [ "firstName", "Robert" ],\n     [ "lastName", "Smith" ],\n     [ "address",\n       { "type" : "home" },\n       [ "street", "12345 Sixth Ave" ],\n       [ "city", "Anytown" ],\n       [ "state", "CA" ],\n       [ "postalCode", "98765-4321" ]\n     ]\n   ]\n </pre>\n would be represented as:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n   &lt;person created="2006-11-11T19:23" modified="2006-12-31T23:59"&gt;\n     &lt;firstName&gt;Robert&lt;/firstName&gt;\n     &lt;lastName&gt;Smith&lt;/lastName&gt;\n     &lt;address type="home"&gt;\n       &lt;street&gt;12345 Sixth Ave&lt;/street&gt;\n       &lt;city&gt;Anytown&lt;/city&gt;\n       &lt;state&gt;CA&lt;/state&gt;\n       &lt;postalCode&gt;98765-4321&lt;/postalCode&gt;\n     &lt;/address&gt;\n   &lt;/person&gt;\n </pre>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Paul J. Lucas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://zorba.io/modules/json-xml",prefix:"jx"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"json-to-xml",qname:"jx:json-to-xml",signature:"($json as json-item()?) as element(*,xs:untyped)?",description:' Converts JSON data into an XDM instance using the Snelson representation\n described above.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Converts JSON data into an XDM instance using the Snelson representation\n described above.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"json",type:"json-item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The JSON data.</div>'}],returns:{type:"element(*,xs:untyped)?",description:"said XDM instance."},errors:[]},{isDocumented:!0,arity:2,name:"json-to-xml",qname:"jx:json-to-xml",signature:"($json as json-item()?, $options as object()) as element(*,xs:untyped)?",description:' Converts JSON data into an XDM instance using one of the representations\n described above.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Converts JSON data into an XDM instance using one of the representations\n described above.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"json",type:"json-item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The JSON data.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The JSON conversion options, for example: <pre> { "json-format" : "JsonML-array" } </pre></div>'}],returns:{type:"element(*,xs:untyped)?",description:"said XDM instance."},errors:[]},{isDocumented:!0,arity:1,name:"xml-to-json",qname:"jx:xml-to-json",signature:"($xml as item()*) as json-item()*",description:' Converts XML data into a JSON item using the Snelson representation\n described above.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Converts XML data into a JSON item using the Snelson representation\n described above.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xml",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The XML data to convert.</div>'}],returns:{type:"json-item()*",description:"said JSON items."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0001 if $xml is not a document or element node.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0002 if $xml contains an element that is missing a required attribute.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0003 if $xml contains an attribute having an illegal value.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0004 if $xml contains an illegal element. type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0007 if $xml contains an element that is missing a required value.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0008 if $xml contains an illegal value for a JSON type.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"xml-to-json",qname:"jx:xml-to-json",signature:"($xml as item()*, $options as object()) as json-item()*",description:' Converts XML data into a JSON item using one of the respresentations\n described above.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Converts XML data into a JSON item using one of the respresentations\n described above.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xml",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The XML data to convert.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The conversion options, for example: <pre> { "json-format" : "JsonML-array" } </pre></div>'}],returns:{type:"json-item()*",description:"said JSON items."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0001 if $xml is not a document or element node.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0002 if $xml contains an element that is missing a required attribute.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0003 if $xml contains an attribute having an illegal value.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0004 if $xml contains an illegal element. type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0007 if $xml contains an element that is missing a required value.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZJSE0008 if $xml contains an illegal value for a JSON type.</xqdoc:error>']}],variables:[]},"http://www.zorba-xquery.com/modules/image/manipulation":{ns:"http://www.zorba-xquery.com/modules/image/manipulation",description:' This module provides functions to handle image manipulations like resizing, zooming,\n special effects etc.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The errors raised by functions of this module have the namespace\n <tt>http://www.zorba-xquery.com/modules/image/error</tt> (associated with prefix ierr).</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Thomas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.zorba-xquery.com/modules/image/error",prefix:"ierr"},{uri:"http://www.zorba-xquery.com/modules/image/image",prefix:"image"},{uri:"http://www.zorba-xquery.com/modules/image/manipulation",prefix:"man"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"add-noise",qname:"man:add-noise",signature:"($image as xs:base64Binary, $noise-type as xs:string) as xs:base64Binary",description:' Add noise to an image.\n Allowed noise types are:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  <li>UniformNoise</li>\n  <li>GaussianNoise</li>\n  <li>MultiplicativeGaussianNoise</li>\n  <li>ImpulseNoise</li>\n  <li>LaplaceianNoise</li>\n  <li>PoissonNoise</li>\n </ul>\n',summary:"<p> Add noise to an image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"noise-type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> specifies the type of noise to add</div>'}],returns:{type:"xs:base64Binary",description:"A copy of $image with added noise"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FORG0001 unsupported noise type</xqdoc:error>']},{isDocumented:!0,arity:3,name:"blur",qname:"man:blur",signature:"($image as xs:base64Binary, $radius as xs:int, $sigma as xs:int) as xs:base64Binary external",description:" Blur an image.\n",summary:"<p> Blur an image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"radius",type:"xs:int",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the radius of the Gaussian in pixels.</div>'},{name:"sigma",type:"xs:int",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the standard deviation of the Laplacian in pixels.</div>'}],returns:{type:"xs:base64Binary",description:"A blured copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:3,name:"charcoal",qname:"man:charcoal",signature:"($image as xs:base64Binary, $radius as xs:double, $sigma as xs:double) as xs:base64Binary external",description:" Apply a charcoal effect to the image (looks like a charcoal sketch).\n",summary:"<p> Apply a charcoal effect to the image (looks like a charcoal sketch).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"radius",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> radius of the Gaussian in pixels</div>'},{name:"sigma",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> standard deviation of the Laplacian in pixels</div>'}],returns:{type:"xs:base64Binary",description:"A charcoaled copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:3,name:"chop",qname:"man:chop",signature:"($image as xs:base64Binary, $upper-left-x as xs:unsignedInt, $upper-left-y as xs:unsignedInt) as xs:base64Binary external",description:" Copy a part of a source image as new image.\n The copied part is all right of $upper-left-x and below $upper-left-y.\n",summary:"<p> Copy a part of a source image as new image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> source image</div>'},{name:"upper-left-x",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> x position of the upper left corner of the part to copy</div>'},{name:"upper-left-y",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> y position of the upper left corner of the part to copy</div>'}],returns:{type:"xs:base64Binary",description:"A new image copied from a part of source image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"contrast",qname:"man:contrast",signature:"($image as xs:base64Binary, $sharpen as xs:double) as xs:base64Binary external",description:" Contrast an image (enhances image intensity differences) by a given value.\n",summary:"<p> Contrast an image (enhances image intensity differences) by a given value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"sharpen",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> defines how much the image is contrasted.</div>'}],returns:{type:"xs:base64Binary",description:"A contrasted copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:3,name:"crop",qname:"man:crop",signature:"($image as xs:base64Binary, $lower-right-x as xs:unsignedInt, $lower-right-y as xs:unsignedInt) as xs:base64Binary external",description:" Copy a part of a source image as new image.\n The copied part is all left of $lower-right-x and above $lower-right-y.\n",summary:"<p> Copy a part of a source image as new image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> source image</div>'},{name:"lower-right-x",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> x position of the lower right corner of the part to copy</div>'},{name:"lower-right-y",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> y position of the lower right corner of the part to copy</div>'}],returns:{type:"xs:base64Binary",description:"A new image copied from a part of source image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"despeckle",qname:"man:despeckle",signature:"($image as xs:base64Binary) as xs:base64Binary external",description:" Despeckle an image.\n",summary:"<p> Despeckle an image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'}],returns:{type:"xs:base64Binary",description:"A despeckled copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"edge",qname:"man:edge",signature:"($image as xs:base64Binary, $radius as xs:unsignedInt) as xs:base64Binary external",description:" Highlight edges in an image.\n",summary:"<p> Highlight edges in an image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"radius",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> radius of the pixel neighborhood (0 for automatic selection)</div>'}],returns:{type:"xs:base64Binary",description:"An edged copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:3,name:"emboss",qname:"man:emboss",signature:"($image as xs:base64Binary, $radius as xs:double, $sigma as xs:double) as xs:base64Binary external",description:" Emboss an images (highlights edges with 3D effect).\n",summary:"<p> Emboss an images (highlights edges with 3D effect).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"radius",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> radius of the Gaussian in pixels</div>'},{name:"sigma",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> standard deviation of the Laplacian in pixels</div>'}],returns:{type:"xs:base64Binary",description:"An embossed copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"enhance",qname:"man:enhance",signature:"($image as xs:base64Binary) as xs:base64Binary external",description:" Enhance an images (minimizes noise).\n",summary:"<p> Enhance an images (minimizes noise).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'}],returns:{type:"xs:base64Binary",description:"An enhanced copy of $image."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"equalize",qname:"man:equalize",signature:"($image as xs:base64Binary) as xs:base64Binary external",description:" Equalize an images (histogramm equalization).\n",summary:"<p> Equalize an images (histogramm equalization).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'}],returns:{type:"xs:base64Binary",description:"An equalized copy of $image."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"erase",qname:"man:erase",signature:"($image as xs:base64Binary) as xs:base64Binary external",description:" Set all pixels of the image to the current backround color.\n In most cases, this will result in all pixels to be set to white.\n",summary:"<p> Set all pixels of the image to the current backround color.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> image to erase</div>'}],returns:{type:"xs:base64Binary",description:"A copy of image with all pixels set to the current background color"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"flip",qname:"man:flip",signature:"($image as xs:base64Binary) as xs:base64Binary external",description:" Flip an image (vertical rotation).\n",summary:"<p> Flip an image (vertical rotation).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> source image</div>'}],returns:{type:"xs:base64Binary",description:"A vertically rotated copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"flop",qname:"man:flop",signature:"($image as xs:base64Binary) as xs:base64Binary external",description:" Flop an image (horizontal rotation).\n",summary:"<p> Flop an image (horizontal rotation).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> source image</div>'}],returns:{type:"xs:base64Binary",description:"A horizontally rotated copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"gamma",qname:"man:gamma",signature:"($image as xs:base64Binary, $gamma-value as xs:double) as xs:base64Binary external",description:" Gamma correct an image.\n Gamma values less than zero will erase the image.\n",summary:"<p> Gamma correct an image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"gamma-value",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> value for which to gamma correct the image</div>'}],returns:{type:"xs:base64Binary",description:"A gamma corrected copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:4,name:"gamma",qname:"man:gamma",signature:"($image as xs:base64Binary, $gamma-red as xs:double, $gamma-green as xs:double, $gamma-blue as xs:double) as xs:base64Binary external",description:" Gamma correct an image for every color channel seperately.\n Gamma values less than zero for any color will erase the corresponding color.\n",summary:"<p> Gamma correct an image for every color channel seperately.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"gamma-red",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> value to gamma correct the red channel of the image</div>'},{name:"gamma-green",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> value to gamma correct the green channel of the image</div>'},{name:"gamma-blue",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> value to gamma correct the blue channel of the image</div>'}],returns:{type:"xs:base64Binary",description:"A gamma corrected copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"implode",qname:"man:implode",signature:"($image as xs:base64Binary, $factor as xs:double) as xs:base64Binary external",description:" Apply an implode effect to an image (a sort of special effect).\n",summary:"<p> Apply an implode effect to an image (a sort of special effect).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"factor",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> factor to implode to</div>'}],returns:{type:"xs:base64Binary",description:"An imploded copy of $image."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"oil-paint",qname:"man:oil-paint",signature:"($image as xs:base64Binary, $radius as xs:double) as xs:base64Binary external",description:" Apply an oil paint effect to an image (makes the image look as if it was\n an oil paint).\n",summary:"<p> Apply an oil paint effect to an image (makes the image look as if it was\n an oil paint).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"radius",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> radius with which to oil paint</div>'}],returns:{type:"xs:base64Binary",description:"A oil-painted copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:5,name:"overlay",qname:"man:overlay",signature:"($image as xs:base64Binary, $overlay-image as xs:base64Binary, $overlay-upper-left-x as xs:unsignedInt, $overlay-upper-left-y as xs:unsignedInt, $operator as xs:string) as xs:base64Binary",description:' Overlay $image with $overlay-image at the specfied position.\n The $operator defines the details of the overlay and can have one of the\n following values:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>OverCompositeOp: The result is the union of the two image shapes\n       with the overlay image obscuring image in the region of overlap.</li>\n   <li>InCompositeOp: The result is a simple overlay image cut by the shape\n       of image. None of the image data of image is included in the result.</li>\n   <li>OutCompositeOp: The resulting image is the overlay image with the shape\n       of image cut out.</li>\n   <li>AtopCompositeOp: The result is the same shape as image, with overlay\n       image obscuring image there the image shapes overlap. Note that this\n       differs from OverCompositeOp because the portion of composite image\n       outside of image\'s shape does not appear in the result.</li>\n   <li>XorCompositeOp: The result is the image data from both overlay image\n       and image that is outside the overlap region. The overlap region will\n       be blank.</li>\n   <li>PlusCompositeOp: The result is just the sum of the image data of both\n       images. Output values are cropped to 255 (no overflow). This operation\n       is independent of the matte channels.</li>\n   <li>MinusCompositeOp: The result of overlay image - image, with overflow\n       cropped to zero. The matte chanel is ignored (set to 255, full\n       coverage).</li>\n   <li>AddCompositeOp: The result of overlay image + image, with overflow\n       wrapping around (mod 256).</li>\n   <li>SubtractCompositeOp: The result of overlay image - image, with underflow\n       wrapping around (mod 256). The add and subtract operators can be used to\n       perform reverible transformations.</li>\n   <li>DifferenceCompositeOp: The result of abs(overlay image - image). This is\n       useful for comparing two very similar images.</li>\n   <li>BumpmapCompositeOp: The result image shaded by overlay image.</li>\n </ul>\n',summary:"<p> Overlay $image with $overlay-image at the specfied position.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> base image</div>'},{name:"overlay-image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> image to overlay.</div>'},{name:"overlay-upper-left-x",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> horizontal position within $image where the left upper edge of the $overlay-image is placed</div>'},{name:"overlay-upper-left-y",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> vertical position within $image where the left upper edge of the $overlay-image is placed</div>'},{name:"operator",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> defines how the overlay image should be overlayed (see details in operator listing above)</div>'}],returns:{type:"xs:base64Binary",description:"A new image consisting of $image overlayed with $overlay-image."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FORG0001 unsupported operator</xqdoc:error>']},{isDocumented:!0,arity:2,name:"reduce-noise",qname:"man:reduce-noise",signature:"($image as xs:base64Binary, $order as xs:double) as xs:base64Binary external",description:" Reduce noise of an image using a noise peak elemination filter.\n",summary:"<p> Reduce noise of an image using a noise peak elemination filter.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"order",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> defines how much the noise is reduced</div>'}],returns:{type:"xs:base64Binary",description:"A copy of $image with reduced noise"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:3,name:"resize",qname:"man:resize",signature:"($image as xs:base64Binary, $width as xs:unsignedInt, $height as xs:unsignedInt) as xs:base64Binary external",description:" Get a copy of the passed image with changed width and height (without\n zooming the image's content).\n To change the size of the actual contents of an image, use the zoom function.\n More in detail: If the new dimensions are greater than the current dimensions\n the new image will have the passed image in the upper left corner and the rest\n will be filled with the current background color.\n If the passed dimensions are less than the current dimensions, the new image\n will contain the specified rectangle of the passed image beginning at the upper\n left corner.\n",summary:"<p> Get a copy of the passed image with changed width and height (without\n zooming the image's content).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> image to resize</div>'},{name:"width",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> new width</div>'},{name:"height",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> new height</div>'}],returns:{type:"xs:base64Binary",description:"resized copy of the source image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"rotate",qname:"man:rotate",signature:"($image as xs:base64Binary, $angle as xs:int) as xs:base64Binary external",description:" Get a new image as rotated copy of a passed source image (rotated by -360 to\n 360 degrees).\n The image is enlarged if this is required for containing the rotated image,\n but never shrunk even if the rotation would make a smaller image possible.\n",summary:"<p> Get a new image as rotated copy of a passed source image (rotated by -360 to\n 360 degrees).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> source image.</div>'},{name:"angle",type:"xs:int",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> between -360 to 360 degrees. Other values will be adjusted by modulo 360</div>'}],returns:{type:"xs:base64Binary",description:"A rotated copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"solarize",qname:"man:solarize",signature:"($image as xs:base64Binary, $factor as xs:double) as xs:base64Binary external",description:" Apply a solarize effect to the image (similar to the effect seen when\n exposing a photographic film to light during the development process).\n",summary:"<p> Apply a solarize effect to the image (similar to the effect seen when\n exposing a photographic film to light during the development process).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"factor",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> strength of the solarization (0 to 65535; 65535=100%)</div>'}],returns:{type:"xs:base64Binary",description:"A solarized copy of $image."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"stereo",qname:"man:stereo",signature:"($left-image as xs:base64Binary, $right-image as xs:base64Binary) as xs:base64Binary external",description:" Make two passed images appear as stereo image when viewed with red-blue glasses.\n Both images should be same but from a slightly different angle for this to work.\n Both images should have the same size, if not, the size of the left image will\n be taken.\n",summary:"<p> Make two passed images appear as stereo image when viewed with red-blue glasses.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"left-image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> left image for the stereo image.</div>'},{name:"right-image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> right image for the stereo image.</div>'}],returns:{type:"xs:base64Binary",description:"A new image as combined stereo image of both source images"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 one of the passed images is invalid</xqdoc:error>']},{isDocumented:!0,arity:5,name:"sub-image",qname:"man:sub-image",signature:"($image as xs:base64Binary, $left-upper-x as xs:unsignedInt, $left-upper-y as xs:unsignedInt, $width as xs:unsignedInt, $height as xs:unsignedInt) as xs:base64Binary external",description:" Copy a part of the source image specified by a rectangle.\n If the passed parameters for the sub-image specify a rectangle that isn't\n entirely within the source image only the area that lies within the image\n boundaries will be returned.\n",summary:"<p> Copy a part of the source image specified by a rectangle.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image from which to extract a sub-image</div>'},{name:"left-upper-x",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the x value of the upper left corner of the rectangle to cut out</div>'},{name:"left-upper-y",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the y value of the upper left corner of the rectangle to cut out.</div>'},{name:"width",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> width of the rectangle to cut out</div>'},{name:"height",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> height of the rectangle to cut out</div>'}],returns:{type:"xs:base64Binary",description:"A new image containing parts of the source image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"swirl",qname:"man:swirl",signature:"($image as xs:base64Binary, $degree as xs:double) as xs:base64Binary external",description:" Swirl an image (image pixels are rotated by degree).\n",summary:"<p> Swirl an image (image pixels are rotated by degree).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"degree",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> degree to swirl image pixels</div>'}],returns:{type:"xs:base64Binary",description:"A swirled copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"transparent",qname:"man:transparent",signature:"($image as xs:base64Binary, $color as xs:string) as xs:base64Binary",description:" Make all pixels of the specfied color transparent.\n This works correctly only with image types supporting transparency\n (e.g GIF or PNG).\n",summary:"<p> Make all pixels of the specfied color transparent.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"color",type:"xs:string",occurrence:null,description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> color to make transparent (e.g. '#FFFFFF')</div>"}],returns:{type:"xs:base64Binary",description:"A copy of $image with the specified color made transparent."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FORG0001 unsupported color</xqdoc:error>']},{isDocumented:!0,arity:1,name:"trim",qname:"man:trim",signature:"($image as xs:base64Binary) as xs:base64Binary external",description:" Trim edges of the image's background color from the image.\n",summary:"<p> Trim edges of the image's background color from the image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'}],returns:{type:"xs:base64Binary",description:"A trimmed copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"watermark",qname:"man:watermark",signature:"($image as xs:base64Binary, $watermark as xs:base64Binary) as xs:base64Binary external",description:" Add a $watermark image to $image.\n",summary:"<p> Add a $watermark image to $image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the source image</div>'},{name:"watermark",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the watermark image</div>'}],returns:{type:"xs:base64Binary",description:"A watermarked copy of $image"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 one of the passed images is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"zoom-by-height",qname:"man:zoom-by-height",signature:"($image as xs:base64Binary, $height as xs:unsignedInt) as xs:base64Binary external",description:" Zoom the passed image to a given new height while keeping the ratio between\n width and height.\n So, the width is scaled accordingly.\n Important note: this function does not change the size information stored\n in the image (e.g. basic:width will not show a different value).\n",summary:"<p> Zoom the passed image to a given new height while keeping the ratio between\n width and height.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> image to resize</div>'},{name:"height",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> new height for the image in pixels</div>'}],returns:{type:"xs:base64Binary",description:"A copy of $image with given $height and width adjusted accordingly"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"zoom-by-width",qname:"man:zoom-by-width",signature:"($image as xs:base64Binary, $width as xs:unsignedInt) as xs:base64Binary external",description:" Zoom the passed image to a given new width while keeping the ratio between\n width and height.\n So, the height is scaled accordingly.\n Important note: this function does not change the size information stored\n in the image (e.g. basic:width will not show a different value).\n",summary:"<p> Zoom the passed image to a given new width while keeping the ratio between\n width and height.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> image to resize</div>'},{name:"width",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> new width for the image in pixels</div>'}],returns:{type:"xs:base64Binary",description:"A copy of $image with given $width and height changed accordingly"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']},{isDocumented:!0,arity:2,name:"zoom",qname:"man:zoom",signature:"($image as xs:base64Binary, $ratio as xs:double) as xs:base64Binary external",description:" Zoom the passed image by the specified factor while keeping the ratio between\n width and height.\n A ratio of less than 1 will make the image smaller.\n A ratio of less or equal than 0 will not effect the image.\n Important note: this function does not change the size information stored in the\n image (e.g. basic:width will not show a different value).\n",summary:"<p> Zoom the passed image by the specified factor while keeping the ratio between\n width and height.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"image",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> image to resize</div>'},{name:"ratio",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> ratio to zoom width and height by</div>'}],returns:{type:"xs:base64Binary",description:"A copy of $image with resized content"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 passed image is invalid</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/http-client-wrapper":{ns:"http://zorba.io/modules/http-client-wrapper",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides conversion functions between the\n XML Expath http-client request and response formats and the\n JSON http-client request and response formats used by the\n <code>http://zorba.io/modules/http-client</code> module.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module is reserved for internal use by the\n <code>http://www.zorba-xquery.com/modules/http-client</code> and the\n <code>http://expath.org/ns/http-client</code> modules.\n This module may be removed at any time. Method signature and\n semantics may change.\n </p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://expath.org/ns/error",prefix:"error"},{uri:"http://expath.org/ns/http-client",prefix:"http-schema"},{uri:"http://zorba.io/modules/http-client-wrapper",prefix:"http-wrapper"},{uri:"http://jsoniq.org/functions",prefix:"jn"},{uri:"http://zorba.io/modules/http-client",prefix:"json-http"},{uri:"http://jsoniq.org/function-library",prefix:"libjn"},{uri:"http://www.w3.org/2010/xslt-xquery-serialization",prefix:"ser"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:3,name:"http-nondeterministic-request",qname:"http-wrapper:http-nondeterministic-request",signature:"($request as element(*)?, $href as xs:string?, $bodies as item()*) as item()+",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function sends an HTTP request and returns the corresponding response.\n This function is declared non-deterministic and should only be used to issue\n requests which do not change the state of the server.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Its inputs, outputs, and behavior are identical to the\n <a href="http://expath.org/spec/http-client">EXPath http-client</a>\'s\n send-request() function (except that HTML responses are not tidied\n into XML - see <a href="#expath_relation">the note above</a>). It\n is provided here for use in Zorba installations that do not have\n the EXPath module available. If you have the option of using the\n EXPath module instead of this function, please do so, as it will\n allow your application to be more interoperable between different\n XQuery engines.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Full documentation of the $request parameter can be found in\n <a href="http://expath.org/spec/http-client#d2e183">the EXPath\n specification</a>.</p>\n',summary:"<p>  This function sends an HTTP request and returns the corresponding response.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"request",type:"element(*)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Contains the various parameters of the request (see above).</div>'},{name:"href",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above). If this parameter is specified, it will override the "href" attribute of $request.</div>'},{name:"bodies",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the request body content, for HTTP methods that can contain a body in the request (i.e. POST and PUT). It is an error if this param is not the empty sequence for methods</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC003 With a multipart response, the override-media-type must be either a multipart media type or application/octet-stream.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC004 The src attribute on the body element is mutually exclusive with all other attribute (except the media-type).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC005 The input request element is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HCV02 Trying to follow a redirect of a POST, PUT, or DELETE request</xqdoc:error>']},{isDocumented:!0,arity:3,name:"http-sequential-request",qname:"http-wrapper:http-sequential-request",signature:"($request as element(*)?, $href as xs:string?, $bodies as item()*) as item()+",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function sends an HTTP request and returns the corresponding response.\n This function is declared sequential and can be used to issue\n requests which change the state of the server.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Its inputs, outputs, and behavior are identical to the\n <a href="http://expath.org/spec/http-client">EXPath http-client</a>\'s\n send-request() function (except that HTML responses are not tidied\n into XML - see <a href="#expath_relation">the note above</a>). It\n is provided here for use in Zorba installations that do not have\n the EXPath module available. If you have the option of using the\n EXPath module instead of this function, please do so, as it will\n allow your application to be more interoperable between different\n XQuery engines.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Full documentation of the $request parameter can be found in\n <a href="http://expath.org/spec/http-client#d2e183">the EXPath\n specification</a>.</p>\n',summary:"<p>  This function sends an HTTP request and returns the corresponding response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"request",type:"element(*)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Contains the various parameters of the request (see above).</div>'},{name:"href",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above). If this parameter is specified, it will override the "href" attribute of $request.</div>'},{name:"bodies",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the request body content, for HTTP methods that can contain a body in the request (i.e. POST and PUT). It is an error if this param is not the empty sequence for methods</div>'}],returns:{type:"item()+",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC001 An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC002 Error parsing the response content as XML.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC003 With a multipart response, the override-media-type must be either a multipart media type or application/octet-stream.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC004 The src attribute on the body element is mutually exclusive with all other attribute (except the media-type).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC005 The input request element is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HC006 A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">error:HCV02 Trying to follow a redirect of a POST, PUT, or DELETE request</xqdoc:error>']}],variables:[]},"http://www.28msec.com/modules/cloudsearch":{ns:"http://www.28msec.com/modules/cloudsearch",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module offers functionality to search, add, update and remove documents in\n an Amazon CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For each functionality two methods are provided\n <ul>\n  <li>one which accepts a single $options parameter. In this case the default\n      credentials for the "CloudSearch" category will be used to determine the\n      CloudSearch endpoint to use.</li>\n  <li>one which accepts both an $endpoint and an $options parameter.\n      In this case, if the $endpoint parameter is of type string, it will be\n      interpreted as the name of a credentials in the "CloudSearch" category.\n      Otherwise, if the $endpoint parameter is of type anyURI, it will be\n      interpreted as the endpoint URI.</li>\n </ul>\n </p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="determinism">Important Notice Regarding Function Determinism</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The search functions (<a href="?anchor=search-1">search#1</a> and\n <a href="?anchor=search-2">search#2</a>) are declared deterministic, which means that\n their results could be cached when invoked multiple times with the same arguments\n in the same query execution.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To not use cached results you can use two alternative search functions\n (<a href="?anchor=search-nondeterministic-1">search-nondeterministic#1</a> and\n <a href="?anchor=search-nondeterministic-2">search-nondeterministic#2</a>), which have\n been declared as being non deterministic.</p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="search-options">Search options</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The search settings are specified by means of an object whose form\n is described in the following. The two most important fields are the\n "q" and "bq" fields. At least one of them must be specified. If the "bq"\n field is specified in conjunction with the "q" parameter, the values\n are joined with a top-level AND.\n <ul>\n   <li>bq: one or more match expressions that define a Boolean search. Multiple\n       expressions are joined with a top-level AND.\n       <p>Type: string</p>\n   </li>\n   <li>q: the string to search for. You use the q parameter to perform simple text\n       searches. This searches the default search field for the specified text.\n       <p>Type: string</p>\n   </li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Additional documentation on the format of the query and boolean query strings can\n be found at:\n <a href="http://docs.aws.amazon.com/cloudsearch/latest/developerguide/Search.Requests.html#Search.MatchSetExpression">\n Expression Syntax for Boolean Queries</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The following additional optional parameters can be specified.\n <ul>\n   <li>facet: a comma-separated list of the fields for which you want to compute facets.\n       The specified fields must be numeric fields or defined as facet enabled in the\n       domain configuration.\n       <p>Type: string</p>\n   </li>\n   <li>facet-<i>FIELD</i>-constraints: the field values (facet constraints) that\n       you want to count for a particular field. FIELD is the name of the field.\n       Constraints are specified as a comma-separated list of ranges or\n       single-quoted strings. If you don\'t specify facet constraints, counts\n       are computed for all field values.\n       <p>Type: string</p>\n   </li>\n   <li>facet-<i>FIELD</i>-sort: how you want to sort facet values for a\n       particular field. FIELD is the name of the field. There are four sorting options:\n       <ul>\n         <li>alpha: Sort the facet values alphabetically (in ascending order).</li>\n         <li>count: Sort the facet values by their counts (in descending order).</li>\n         <li>max: Sort the facet values according to the maximum values in the specified\n             field. This option is specified as <code>max(FIELD)</code>. By default, the\n             facet values are sorted in ascending order. To sort in descending order,\n             prefix the sort option with - (minus): <code>-max(FIELD)</code>.\n         </li>\n         <li>sum: Sort the facet values according to the sum of the values in the\n             specified field (in ascending order). This option is specified as\n             <code>sum(FIELD)</code>.\n         </li>\n       </ul>\n   </li>\n   <li>facet-<i>FIELD</i>-top-n: set the maximum number of facet constraints to\n       be included for the specified field in the search results. By default,\n       the results include counts for the top 40 constraints.\n        <p>Type: integer</p>\n   </li>\n   <li>no-cache: if false, a cached result can be returned. If true, a revalidation of the\n        results is forced. Default is false.\n        <p>Type: boolean</p>\n   </li>\n   <li>rank: a comma-separated list of fields or rank expressions to use for ranking. A\n        maximum of 10 fields and rank expressions can be specified. You can use any uint\n        field to rank results numerically. Any result-enabled text or literal field can be\n        used to rank results alphabetically. To rank results by relevance, you can specify\n        the name of a custom rank expression or text_relevance. Hits are ordered according\n        to the specified rank field(s). By default, hits are ranked in ascending order.\n        <p>You can prefix a field name with a minus (-) to rank in descending order. If no\n        rank parameter is specified, it defaults to <code>rank=-text_relevance</code>, which\n        lists results according to their text_relevance scores with the highest-scoring\n        documents first.</p>\n       <p>Type: string</p>\n   </li>\n   <li>rank-<i>RANKNAME</i>: define a rank expression that can be used with the\n       rank parameter. You can also specify the new rank expression as a return\n       field and use it to set thresholds for the search results with the\n       t-<i>FIELD</i> parameter. For more information about constructing\n       rank expressions, see\n       <a href="http://docs.aws.amazon.com/cloudsearch/latest/developerguide/tuneranking.html">\n       Customizing Result Ranking with Amazon CloudSearch</a>.\n       <p>Type: string</p>\n   </li>\n   <li>return-fields: the document fields to include in the response. Up to 2 KB\n       of data can be returned from a text field. If the field contents exceed\n       2 KB, only the first 2 KB is included in the results. Specified as a\n       comma-separated list of field names. If no return-fields are specified,\n       only the document ids of the hits are returned.\n       <p>Type: string</p>\n   </li>\n   <li>size: the maximum number of search hits to return. The default is 10.\n       <p>Type: integer</p>\n   </li>\n   <li>start: the offset of the first search hit you want to return. The default is 0\n       (the first hit).\n       <p>Type: integer</p>\n   </li>\n   <li>t-<i>FIELD</i>: restrict the match set used in subsequent post-processing\n       steps according to the specified rank expression. Only hits that have a\n       score within the specified range are included. Ranges are specified as\n       described in\n       <a href="http://docs.aws.amazon.com/cloudsearch/latest/developerguide/Search.Requests.html#Search.MatchSetExpression">\n       Expression Syntax for Boolean Queries</a>.\n       <p>Type: integer</p>\n   </li>\n </ul>\n For additional details on the search parameters you can refer to the\n <a href="http://docs.aws.amazon.com/cloudsearch/latest/developerguide/Search.Requests.html">\n Amazon CloudSearch search requests documentation</a>.</p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="search-results">Search Results</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The format of the returned object is the following:\n <pre>\n {\n   "rank" : "-text_relevance",\n   "match-expr" : "(label \'star wars\')",\n   "hits" :\n   {\n     "found" : 2,\n     "start" : 0,\n     "hit" :\n     [\n       {\n         "id" : "tt1185834",\n         "data" :\n         {\n           "actor" : ["Abercrombie, Ian","Baker, Dee","Burton, Corey"],\n           "title" : ["Star Wars: The Clone Wars"]\n         }\n       },\n       {\n         "id" :"tt0121766",\n         "data" :\n         {\n           "actor" : ["Bai, Ling","Bryant, Gene","Castle-Hughes, Keisha"],\n           "title" : ["Star Wars: Episode III - Revenge of the Sith"]\n         }\n       }\n     ]\n   },\n   "info" :\n   {\n     "rid" : "b7c167f6c2da6d93531b9a7b314ad030b3a74803b4b7797edb905ba5a6a08",\n     "time-ms" : 2,\n     "cpu-time-ms" : 0\n   }\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object fields have the following meaning:\n <ul>\n   <li>match-expr: Shows the match expression constructed from the search\n       parameters.</li>\n   <li>hits: Contains hit statistics (found, start) and a hit array that lists\n       the document ids and data for each hit.</li>\n   <li>found: The total number of hits that match the search request after\n       Amazon CloudSearch finished processing the match set.</li>\n   <li>start: The index of the first hit returned in this response.</li>\n   <li>hit: An array that lists the document ids and data for each hit.</li>\n   <li>id: The unique identifier for a document.</li>\n   <li>data: A list of returned fields.</li>\n   <li>facets: Contains facet information and facet counts.</li>\n   <li><i>FacetFieldName</i>: A field for which facets were calculated.</li>\n   <li>constraints: An array of the facet values and counts.</li>\n   <li>value: The facet value being counted.</li>\n   <li>count: The number of hits that contain the facet value in <i>FacetFieldName</i>.\n       </li>\n   <li>info: Contains information about the request processing.</li>\n   <li>rank: Lists the fields that were used to rank the search hits.</li>\n   <li>rid: The encrypted Resource ID.</li>\n   <li>time-ms: How long it took to process the search request in milliseconds.\n       </li>\n   <li>cpu-time-ms: The CPU time required to process the search request in\n       milliseconds.</li>\n   <li>messages: Contains any error messages returned by the search service.\n       The severity, code, and message properties are included for each item.</li>\n   <li>severity: The severity of the message. It is always warning, which indicates\n       a problem with the query string that did not prevent the request from being\n       processed.</li>\n   <li>code: The error code. The search service returns the following error codes:\n     <ul>\n       <li>CS-InvalidFieldOrRankAliasInRankParameter: the specified ranking field\n           could not be found.</li>\n       <li>CS-RankExpressionParseError: one of the specified rank expressions could\n           not be parsed. No query-time rank expressions will be used. </li>\n       <li>CS-RankExpressionValidationError: one of the specified rank expressions\n           could not be validated. No query-time rank expressions will be used.</li>\n       <li>CS-UndefinedField: an unknown field was specified in the match\n           expression.</li>\n       <li>CS-UnknownFieldInMatchExpression: a field specified in the bq parameter\n           could not be found.</li>\n       <li>CS-WildcardTermLimit: more than 2000 terms matched the wildcard in the\n           search request. The number of terms matched was limited to 2000.</li>\n     </ul>\n   </li>\n   <li>message: A description of the error that was returned by the search service.</li>\n </ul>\n </p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/cloudsearch",prefix:"cloudsearch"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://zorba.io/modules/http-client",prefix:"http"}],functions:[{isDocumented:!0,arity:1,name:"add-document",qname:"cloudsearch:add-document",signature:"($options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Adds or replaces a document in the default Amazon CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An add operation is applied only if a document with the same id is not\n present or if the version number specified in the operation is greater than\n the existing document\'s version number.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The document to add or replace is specified through an object with\n the following form:\n <pre>\n {\n   "id" : "tt0484562",\n   "version" : 1,\n   "lang" : "en",\n   "fields" :\n   {\n     "title" : "The Seeker: The Dark Is Rising",\n     "genre" : ["Adventure","Drama","Fantasy","Thriller"]\n   }\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the request object have the following meaning:\n <ul>\n   <li>id: An alphanumeric string. Allowed characters are: a-z, 0-9, and _.\n       Document IDs cannot begin with an underscore. The max length is 128\n       characters.</li>\n   <li>version: Any non-negative number less than 2^32.</li>\n   <li>lang: An ISO-639-1 two-letter language code.</li>\n   <li>fields: An object containing one or more fields. Each field specifies\n       a field within the document being added. Field names must begin with a\n       lowercase letter and can contain the following characters: a-z, 0-9,\n       and _. Field names must be at least 3 and no more than 64 characters.\n       The names "body", "docid", and "text_relevance" are reserved names and\n       cannot be used as field names. To specify multiple values for a field,\n       you can specify an array of values instead of a single value.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object lists all warnings that were generated.\n <pre>\n {\n   "status" : "success",\n   "warning" :\n   [\n     {"message" : "Warning message."}\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the response object have the following meaning:\n <ul>\n   <li>status: the result status, always "success". In case an error occurred\n       processing the request, an error is raised.</li>\n   <li>warning: provides information about warnings generated during parsing\n       or validation. The field is not present if no warning were generated.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, specifying endpoint URI:\n <pre>\n cloudsearch:add-document(\n anyURI("http://doc-movies-h2pc7ftfnsdlqh6pqqawbftrhu.us-east-1.cloudsearch.amazonaws.com"),\n {\n   "id" : "tt0484562",\n   "version" : 1,\n   "lang" : "en",\n   "fields" :\n   {\n     "title" : "The Seeker: The Dark Is Rising",\n     "genre" : ["Adventure","Drama","Fantasy","Thriller"]\n   }\n });\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using stored credentials:\n <pre>\n cloudsearch:add-document("movies",\n {\n   "id" : "tt0484562",\n   "version" : 1,\n   "lang" : "en",\n   "fields" :\n   {\n     "title" : "The Seeker: The Dark Is Rising",\n     "genre" : ["Adventure","Drama","Fantasy","Thriller"]\n   }\n });\n </pre>\n </p>\n',summary:"<p>  Adds or replaces a document in the default Amazon CloudSearch domain.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying the request options</div>'}],returns:{type:"object()",description:"The request response"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the default credentials endpoint is invalid or not present</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESOURCES if the server storage or bandwidth resources are insufficient to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"add-document",qname:"cloudsearch:add-document",signature:"($endpoint as atomic, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Adds or replaces a document in the specified Amazon CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An add operation is applied only if a document with the same id is not\n present or if the version number specified in the operation is greater than\n the existing document\'s version number.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The document to add or replace is specified through an object with\n the following form:\n <pre>\n {\n   "id" : "tt0484562",\n   "version" : 1,\n   "lang" : "en",\n   "fields" :\n   {\n     "title" : "The Seeker: The Dark Is Rising",\n     "genre" : ["Adventure","Drama","Fantasy","Thriller"]\n   }\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the request object have the following meaning:\n <ul>\n   <li>id: An alphanumeric string. Allowed characters are: a-z, 0-9, and _.\n       Document IDs cannot begin with an underscore. The max length is 128\n       characters.</li>\n   <li>version: Any non-negative number less than 2^32.</li>\n   <li>lang: An ISO-639-1 two-letter language code.</li>\n   <li>fields: An object containing one or more fields. Each field specifies\n       a field within the document being added. Field names must begin with a\n       lowercase letter and can contain the following characters: a-z, 0-9,\n       and _. Field names must be at least 3 and no more than 64 characters.\n       The names "body", "docid", and "text_relevance" are reserved names and\n       cannot be used as field names. To specify multiple values for a field,\n       you can specify an array of values instead of a single value.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object lists all warnings that were generated.\n <pre>\n {\n   "status" : "success",\n   "warning" :\n   [\n     {"message" : "Warning message."}\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the response object have the following meaning:\n <ul>\n   <li>status: the result status, always "success". In case an error occurred\n       processing the request, an error is raised.</li>\n   <li>warning: provides information about warnings generated during parsing\n       or validation. The field is not present if no warning were generated.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, specifying endpoint URI:\n <pre>\n cloudsearch:add-document(\n anyURI("http://doc-movies-h2pc7ftfnsdlqh6pqqawbftrhu.us-east-1.cloudsearch.amazonaws.com"),\n {\n   "id" : "tt0484562",\n   "version" : 1,\n   "lang" : "en",\n   "fields" :\n   {\n     "title" : "The Seeker: The Dark Is Rising",\n     "genre" : ["Adventure","Drama","Fantasy","Thriller"]\n   }\n });\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using stored credentials:\n <pre>\n cloudsearch:add-document("movies",\n {\n   "id" : "tt0484562",\n   "version" : 1,\n   "lang" : "en",\n   "fields" :\n   {\n     "title" : "The Seeker: The Dark Is Rising",\n     "genre" : ["Adventure","Drama","Fantasy","Thriller"]\n   }\n });\n </pre>\n </p>\n',summary:"<p>  Adds or replaces a document in the specified Amazon CloudSearch domain.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The endpoint URI or the name of a stored CloudSearch credentials</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying the request options</div>'}],returns:{type:"object()",description:"The request response"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the specified endpoint is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESOURCES if the server storage or bandwidth resources are insufficient to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"batch-document",qname:"cloudsearch:batch-document",signature:"($options as array()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Adds, replaces or removes one or more documents from the default Amazon\n CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An add or delete operation is only applied to an existing document if the\n version number specified in the operation is greater than the existing document\n version number.\n If multiple add or delete operations for the same document are specified, the\n operation with the highest version number is applied. If multiple operations in\n a batch specify the same document and version number, the document service\n arbitrarily picks which one to apply.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The documents to add, replace or delete can be specified through an array with\n the following form:\n <pre>\n [\n   {\n     "type" : "add",\n     "id" :   "tt0484562",\n     "version" : 1,\n     "lang" : "en",\n     "fields" :\n     {\n       "title" : "The Seeker: The Dark Is Rising",\n       "genre" : ["Adventure","Drama","Fantasy","Thriller"],\n     }\n   },\n   {\n     "type" : "delete",\n     "id" :   "tt0484575",\n     "version" : 2\n   }\n ]\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the request array have the following meaning:\n <ul>\n   <li>type: The operation type, "add" or "delete".</li>\n   <li>id: An alphanumeric string. Allowed characters are: a-z, 0-9, and _.\n       Document IDs cannot begin with an underscore. The max length is 128\n       characters.</li>\n   <li>version: Any non-negative number less than 2^32.</li>\n   <li>lang: An ISO-639-1 two-letter language code.</li>\n   <li>fields: An object containing one or more fields. Each field specifies\n       a field within the document being added. Field names must begin with a\n       lowercase letter and can contain the following characters: a-z, 0-9,\n       and _. Field names must be at least 3 and no more than 64 characters.\n       The names "body", "docid", and "text_relevance" are reserved names and\n       cannot be used as field names. To specify multiple values for a field,\n       you can specify an array of values instead of a single value.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The response body lists any warning that was generated.\n <pre>\n {\n   "status" : "success",\n   "adds" : 1,\n   "deletes: 1,\n   "warning" :\n   [\n     {"message" : "Warning message."}\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the response object have the following meaning:\n <ul>\n   <li>status: the result status, which is either success or error.</li>\n   <li>adds: the number of add document operations that were performed.</li>\n   <li>deletes: the number of delete document operations that were performed.</li>\n   <li>warning: provides information about a warning generated during parsing\n       or validation. The field is not present if no warning was generated.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using specified endpoint URI:\n <pre>\n cloudsearch:batch-document(\n anyURI("http://doc-movies-h2pc7ftfnsdlqh6pqqawbftrhu.us-east-1.cloudsearch.amazonaws.com"),\n [\n   {\n     "type" : "add",\n     "id" :   "tt0484562",\n     "version" : 1,\n     "lang" : "en",\n     "fields" :\n     {\n       "title" : "The Seeker: The Dark Is Rising",\n       "genre" : ["Adventure","Drama","Fantasy","Thriller"],\n     }\n   },\n   {\n     "type" : "delete",\n     "id" :   "tt0484575",\n     "version" : 2\n   }\n ]);\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using specified endpoint URI:\n <pre>\n cloudsearch:batch-document("movies",\n [\n   {\n     "type" : "add",\n     "id" :   "tt0484562",\n     "version" : 1,\n     "lang" : "en",\n     "fields" :\n     {\n       "title" : "The Seeker: The Dark Is Rising",\n       "genre" : ["Adventure","Drama","Fantasy","Thriller"],\n     }\n   },\n   {\n     "type" : "delete",\n     "id" :   "tt0484575",\n     "version" : 2\n   }\n ]);\n </pre>\n </p>\n',summary:"<p>  Adds, replaces or removes one or more documents from the default Amazon\n CloudSearch domain.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"options",type:"array()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying the request options</div>'}],returns:{type:"object()",description:"The request response"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the default credentials endpoint is invalid or not present</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESOURCES if the server storage or bandwidth resources are insufficient to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"batch-document",qname:"cloudsearch:batch-document",signature:"($endpoint as atomic, $options as array()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Adds, replaces or removes one or more documents from the specified Amazon\n CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An add or delete operation is only applied to an existing document if the\n version number specified in the operation is greater than the existing document\n version number.\n If multiple add or delete operations for the same document are specified, the\n operation with the highest version number is applied. If multiple operations in\n a batch specify the same document and version number, the document service\n arbitrarily picks which one to apply.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The documents to add, replace or delete can be specified through an array with\n the following form:\n <pre>\n [\n   {\n     "type" : "add",\n     "id" :   "tt0484562",\n     "version" : 1,\n     "lang" : "en",\n     "fields" :\n     {\n       "title" : "The Seeker: The Dark Is Rising",\n       "genre" : ["Adventure","Drama","Fantasy","Thriller"],\n     }\n   },\n   {\n     "type" : "delete",\n     "id" :   "tt0484575",\n     "version" : 2\n   }\n ]\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the request array have the following meaning:\n <ul>\n   <li>type: The operation type, "add" or "delete".</li>\n   <li>id: An alphanumeric string. Allowed characters are: a-z, 0-9, and _.\n       Document IDs cannot begin with an underscore. The max length is 128\n       characters.</li>\n   <li>version: Any non-negative number less than 2^32.</li>\n   <li>lang: An ISO-639-1 two-letter language code.</li>\n   <li>fields: An object containing one or more fields. Each field specifies\n       a field within the document being added. Field names must begin with a\n       lowercase letter and can contain the following characters: a-z, 0-9,\n       and _. Field names must be at least 3 and no more than 64 characters.\n       The names "body", "docid", and "text_relevance" are reserved names and\n       cannot be used as field names. To specify multiple values for a field,\n       you can specify an array of values instead of a single value.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The response body lists any warning that was generated.\n <pre>\n {\n   "status" : "success",\n   "adds" : 1,\n   "deletes: 1,\n   "warning" :\n   [\n     {"message" : "Warning message."}\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the response object have the following meaning:\n <ul>\n   <li>status: the result status, which is either success or error.</li>\n   <li>adds: the number of add document operations that were performed.</li>\n   <li>deletes: the number of delete document operations that were performed.</li>\n   <li>warning: provides information about a warning generated during parsing\n       or validation. The field is not present if no warning was generated.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using specified endpoint URI:\n <pre>\n cloudsearch:batch-document(\n anyURI("http://doc-movies-h2pc7ftfnsdlqh6pqqawbftrhu.us-east-1.cloudsearch.amazonaws.com"),\n [\n   {\n     "type" : "add",\n     "id" :   "tt0484562",\n     "version" : 1,\n     "lang" : "en",\n     "fields" :\n     {\n       "title" : "The Seeker: The Dark Is Rising",\n       "genre" : ["Adventure","Drama","Fantasy","Thriller"],\n     }\n   },\n   {\n     "type" : "delete",\n     "id" :   "tt0484575",\n     "version" : 2\n   }\n ]);\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using specified endpoint URI:\n <pre>\n cloudsearch:batch-document("movies",\n [\n   {\n     "type" : "add",\n     "id" :   "tt0484562",\n     "version" : 1,\n     "lang" : "en",\n     "fields" :\n     {\n       "title" : "The Seeker: The Dark Is Rising",\n       "genre" : ["Adventure","Drama","Fantasy","Thriller"],\n     }\n   },\n   {\n     "type" : "delete",\n     "id" :   "tt0484575",\n     "version" : 2\n   }\n ]);\n </pre>\n </p>\n',summary:"<p>  Adds, replaces or removes one or more documents from the specified Amazon\n CloudSearch domain.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The endpoint URI or the name of a stored CloudSearch credentials</div>'},{name:"options",type:"array()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying the request options</div>'}],returns:{type:"object()",description:"The request response"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the specified endpoint is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESOURCES if the server storage or bandwidth resources are insufficient to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"delete-document",qname:"cloudsearch:delete-document",signature:"($options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes a document from the default Amazon CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A delete operation is only applied to an existing document if the\n version number specified in the operation is greater than the existing\n document\'s version number.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The document to remove is specified through an object with the\n following form:\n <pre>\n {\n   "id" : "tt0484562",\n   "version" : 2\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the request object have the following meaning:\n <ul>\n   <li>id: An alphanumeric string. Allowed characters are: a-z, 0-9, and _.\n       Document IDs cannot begin with an underscore. The max length is 128\n       characters.</li>\n   <li>version: Any non-negative number less than 2^32.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The response body lists any warning that was generated.\n <pre>\n {\n   "status" : "success",\n   "warning" :\n   [\n     {"message" : "Warning message."}\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the response object have the following meaning:\n <ul>\n   <li>status: the result status, always "success". In case of errors an error is\n       raised.</li>\n   <li>warning: provides information about a warning generated during parsing or\n       validation. The field is not present if no warning was generated.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using specified endpoint URI:\n <pre>\n cloudsearch:delete-document(\n anyURI("http://doc-movies-h2pc7ftfnsdlqh6pqqawbftrhu.us-east-1.cloudsearch.amazonaws.com"),\n {\n   "id" : "tt0484562",\n   "version" : 2\n });\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using specified stored endpoing:\n <pre>\n cloudsearch:delete-document("movies",\n {\n   "id" : "tt0484562",\n   "version" : 2\n });\n </pre>\n </p>\n',summary:"<p>  Deletes a document from the default Amazon CloudSearch domain.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying the request options</div>'}],returns:{type:"object()",description:"The request response"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the default credentials endpoint is invalid or not present</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESOURCES if the server storage or bandwidth resources are insufficient to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete-document",qname:"cloudsearch:delete-document",signature:"($endpoint as atomic, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes a document from the specified Amazon CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A delete operation is only applied to an existing document if the\n version number specified in the operation is greater than the existing\n document\'s version number.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The document to remove is specified through an object with the\n following form:\n <pre>\n {\n   "id" : "tt0484562",\n   "version" : 2\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the request object have the following meaning:\n <ul>\n   <li>id: An alphanumeric string. Allowed characters are: a-z, 0-9, and _.\n       Document IDs cannot begin with an underscore. The max length is 128\n       characters.</li>\n   <li>version: Any non-negative number less than 2^32.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The response body lists any warning that was generated.\n <pre>\n {\n   "status" : "success",\n   "warning" :\n   [\n     {"message" : "Warning message."}\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Specifically, the fields in the response object have the following meaning:\n <ul>\n   <li>status: the result status, always "success". In case of errors an error is\n       raised.</li>\n   <li>warning: provides information about a warning generated during parsing or\n       validation. The field is not present if no warning was generated.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using specified endpoint URI:\n <pre>\n cloudsearch:delete-document(\n anyURI("http://doc-movies-h2pc7ftfnsdlqh6pqqawbftrhu.us-east-1.cloudsearch.amazonaws.com"),\n {\n   "id" : "tt0484562",\n   "version" : 2\n });\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using specified stored endpoing:\n <pre>\n cloudsearch:delete-document("movies",\n {\n   "id" : "tt0484562",\n   "version" : 2\n });\n </pre>\n </p>\n',summary:"<p>  Deletes a document from the specified Amazon CloudSearch domain.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"endpoint",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The endpoint URI or the name of a stored CloudSearch credentials</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying the request options</div>'}],returns:{type:"object()",description:"The request response"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the specified endpoint is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESOURCES if the server storage or bandwidth resources are insufficient to execute the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"search-nondeterministic",qname:"cloudsearch:search-nondeterministic",signature:"($options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Searches the documents in the default Amazon CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#search-1">search#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Searches the documents in the default Amazon CloudSearch domain.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="#search-options">search options</a> object</div>'}],returns:{type:"object()",description:'The <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#search-results">search results</a> object'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the default credentials endpoint is invalid or not present</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"search-nondeterministic",qname:"cloudsearch:search-nondeterministic",signature:"($endpoint as atomic, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Searches the documents in the specified Amazon CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#search-2">search#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Searches the documents in the specified Amazon CloudSearch domain.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"endpoint",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The endpoint URI or the name of a stored CloudSearch credentials</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="search-options">search options</a> object</div>'}],returns:{type:"object()",description:'The <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="search-results">search results</a> object'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the specified endpoint is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:1,name:"search",qname:"cloudsearch:search",signature:"($options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Searches the documents in the default Amazon CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The format of the <a href="search-options">search options</a> object and\n of the <a href="search-results">search results</a> object is documented in\n the module introduction.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:\n <pre>\n cloudsearch:search({"q" : "star+wars", "return-fields" : "title"})\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example returned object:\n <pre>\n {\n   "rank" : "-text_relevance",\n   "match-expr" : "(label \'star wars\')",\n   "hits" :\n   {\n     "found" : 2,\n     "start" : 0,\n     "hit" :\n     [\n       {\n         "id" : "tt1185834",\n         "data" :\n         {\n           "actor" : ["Abercrombie, Ian","Baker, Dee","Burton, Corey"],\n           "title" : ["Star Wars: The Clone Wars"]\n         }\n       },\n       {\n         "id" :"tt0121766",\n         "data" :\n         {\n           "actor" : ["Bai, Ling","Bryant, Gene","Castle-Hughes, Keisha"],\n           "title" : ["Star Wars: Episode III - Revenge of the Sith"]\n         }\n       }\n     ]\n   },\n   "info" :\n   {\n     "rid" : "b7c167f6c2da6d93531b9a7b314ad030b3a74803b4b7797edb905ba5a6a08",\n     "time-ms" : 2,\n     "cpu-time-ms" : 0\n   }\n }\n </pre>\n </p>\n',summary:"<p>  Searches the documents in the default Amazon CloudSearch domain.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="search-options">search options</a> object</div>'}],returns:{type:"object()",description:'The <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="search-results">search results</a> object'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the default credentials endpoint is invalid or not present</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:2,name:"search",qname:"cloudsearch:search",signature:"($endpoint as atomic, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Searches the documents in the specified Amazon CloudSearch domain.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The format of the <a href="search-options">search options</a> object and\n of the <a href="search-results">search results</a> object is documented in\n the module introduction.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The following examples performs a simple text search for all documents\n containing both the word "star" and "trek" and returns the matching document\n title field.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using specified endpoint URI:\n <pre>\n cloudsearch:search(\n anyURI("http://doc-movies-h2pc7ftfnsdlqh6pqqawbftrhu.us-east-1.cloudsearch.amazonaws.com"),\n {"q" : "star+wars", "return-fields" : "title"})\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example, using a stored endpoint:\n <pre>\n cloudsearch:search("movies",\n {"q" : "star+wars", "return-fields" : "title"})\n </pre>\n </p>\n',summary:"<p>  Searches the documents in the specified Amazon CloudSearch domain.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"endpoint",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The endpoint URI or the name of a stored CloudSearch credentials</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="search-options">search options</a> object</div>'}],returns:{type:"object()",description:'The <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="search-results">search results</a> object'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:ENDPOINT if the specified endpoint is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:AUTHORIZATION if the request was unauthorized</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:HTTP if an HTTP error has occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:REQUEST if the request is malformed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:INTERNAL if an internal server error occurred</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudsearch:RESPONSE if the CloudSearch response cannot be parsed</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/store/static/indexes/ddl":{ns:"http://zorba.io/modules/store/static/indexes/ddl",description:' This modules defines a set of functions for managing indexes that are\n declared in the prolog of a module.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This module is part of\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/xqddf.html">Zorba\'s XQuery Data Definition Facility</a>.\n All the indexes managed by this module have to be pre-declared in the prolog\n of a module.\n Please refer to the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/data_lifecycle.html">general documentation</a>\n for more information and examples.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/data_lifecycle.html">Data Lifecycle</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/xqddf.html">XQuery Data Definition Facility</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/errors</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Nicolae Brinza, Matthias Brantner, David Graf, Till Westmann, Markos Zaharioudakis</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/store/static/indexes/ddl",prefix:"iddl"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:0,name:"available-indexes",qname:"iddl:available-indexes",signature:"() as xs:QName* external",description:" Gets the available indexes.\n",summary:"<p> Gets the available indexes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each available index, or an empty sequence if none are."},errors:[]},{isDocumented:!0,arity:1,name:"create",qname:"iddl:create",signature:"($name as xs:QName) external",description:" Creates an index.\n",summary:"<p> Creates an index.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the index to create.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, creates the index with the given name."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0021 if <code>$name</code> is not equal to the name of any resource in the statically known indexes.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0022 if an index with <code>$name</code> already exists.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"declared-indexes",qname:"iddl:declared-indexes",signature:"() as xs:QName* external",description:" Gets a sequence of QNames representing the indexes that have been declared\n in the prolog of the static context.\n",summary:"<p> Gets a sequence of QNames representing the indexes that have been declared\n in the prolog of the static context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each created collection, or an emtpy sequence."},errors:[]},{isDocumented:!0,arity:1,name:"delete",qname:"iddl:delete",signature:"($name as xs:QName) external",description:" Deletes an index.\n",summary:"<p> Deletes an index.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the index to delete.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, deletes the index with the given name."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0009 if the index does not exist.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-available-index",qname:"iddl:is-available-index",signature:"($name as xs:QName) as xs:boolean external",description:" Gets whether an index exists.\n",summary:"<p> Gets whether an index exists.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the index that is being checked.</div>'}],returns:{type:"xs:boolean",description:"true if the index is available; false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"is-declared-index",qname:"iddl:is-declared-index",signature:"($name as xs:QName) as xs:boolean external",description:" Gets whether an index has been declared in the prolog of the static context.\n",summary:"<p> Gets whether an index has been declared in the prolog of the static context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the index that is being checked.</div>'}],returns:{type:"xs:boolean",description:"true if the index was declared; false otherwise."},errors:[]}],variables:[]},"http://zorba.io/modules/excel/datetime":{ns:"http://zorba.io/modules/excel/datetime",description:" This is a library module offering the same set of functions\n defined by Microsoft Excel.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://office.microsoft.com/en-us/excel/CH062528231033.aspx" target="_blank">Excel Documentation: Datetime Functions</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Sorin Nasoi</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/datetime",prefix:"excel-datetime"},{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/modules/excel/text",prefix:"excel-text"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:3,name:"date",qname:"excel-datetime:date",signature:"($year as xs:integer, $month as xs:integer, $day as xs:integer) as xs:date?",description:" Constructs a date given the hours, months and days.\n",summary:"<p> Constructs a date given the hours, months and days.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"year",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the year</div>'},{name:"month",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the month</div>'},{name:"day",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the day</div>'}],returns:{type:"xs:date?",description:"A date given the hours, months and days"},errors:[]},{isDocumented:!0,arity:1,name:"day",qname:"excel-datetime:day",signature:"($date as xs:date) as xs:integer?",description:" Returns the day of a $date, represented by a serial number.\n",summary:"<p> Returns the day of a $date, represented by a serial number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date.</div>'}],returns:{type:"xs:integer?",description:"The day of a $date, represented by a serial number. The day is given as an integer ranging from 1 to 31."},errors:[]},{isDocumented:!0,arity:2,name:"days360",qname:"excel-datetime:days360",signature:"($start_date as xs:date, $end_date as xs:date) as xs:integer",description:" Returns the number of days between two dates based on a 360-day year.\n",summary:"<p> Returns the number of days between two dates based on a 360-day year.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"start_date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the start date.</div>'},{name:"end_date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the end date.</div>'}],returns:{type:"xs:integer",description:'The number of days between two dates based on a 360-day year (twelve 30-day months), which is used in some accounting calculations.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> Use this function to help compute payments if your accounting system is based on twelve 30-day months.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> The metod used is U.S. (NASD). If the starting date is the last day of a month, it becomes equal to the 30th of the same month. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> If the ending date is the last day of a month and the starting date is earlier than the 30th of a month, the ending date becomes equal to the 1st of the next month; otherwise the ending date becomes equal to the 30th of the same month.'},errors:[]},{isDocumented:!0,arity:3,name:"days360",qname:"excel-datetime:days360",signature:"($start_date as xs:date, $end_date as xs:date, $method as xs:boolean) as xs:integer",description:" Returns the number of days between two dates based on a 360-day year.\n",summary:"<p> Returns the number of days between two dates based on a 360-day year.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"start_date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the start date.</div>'},{name:"end_date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the end date.</div>'},{name:"method",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> if false then US/NASD Method is used, otherwise the European Method is used.</div>'}],returns:{type:"xs:integer",description:'The number of days between two dates based on a 360-day year (twelve 30-day months), which is used in some accounting calculations. Use this function to help compute payments if your accounting system is based on twelve 30-day months. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> The European Method (30E/360)<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> - If either date A or B falls on the 31st of the month, that date will be changed to the 30th;<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> - Where date B falls on the last day of February, the actual date B will be used.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> The US/NASD Method (30US/360)<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> - If both date A and B fall on the last day of February, then date B will be changed to the 30th.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> - If date A falls on the 31st of a month or last day of February, then date A will be changed to the 30th.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> - If date A falls on the 30th of a month after applying (2) above and date B falls on the 31st of a month, then date B will be changed to the 30th.'},errors:[]},{isDocumented:!0,arity:1,name:"hour",qname:"excel-datetime:hour",signature:"($time as xs:time) as xs:integer?",description:" Returns the hour of a time value.\n",summary:"<p> Returns the hour of a time value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"time",type:"xs:time",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the time.</div>'}],returns:{type:"xs:integer?",description:"The hour of a time value. The hour is as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.)."},errors:[]},{isDocumented:!0,arity:1,name:"minute",qname:"excel-datetime:minute",signature:"($time as xs:time) as xs:integer?",description:" Returns the minutes of a time value.\n",summary:"<p> Returns the minutes of a time value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"time",type:"xs:time",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the time.</div>'}],returns:{type:"xs:integer?",description:"The minutes of a time value. The minute is given as an integer, ranging from 0 to 59."},errors:[]},{isDocumented:!0,arity:1,name:"month",qname:"excel-datetime:month",signature:"($date as xs:date) as xs:integer?",description:" Returns the month of a $date.\n",summary:"<p> Returns the month of a $date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date.</div>'}],returns:{type:"xs:integer?",description:"the month of a $date. The month is given as an integer, ranging from 1 (January) to 12 (December)."},errors:[]},{isDocumented:!0,arity:2,name:"networkdays",qname:"excel-datetime:networkdays",signature:"($start_date as xs:date, $end_date as xs:date) as xs:integer*",description:" Returns the number of whole working days between $start_date and $end_date.\n",summary:"<p> Returns the number of whole working days between $start_date and $end_date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"start_date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the start date.</div>'},{name:"end_date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the end date.</div>'}],returns:{type:"xs:integer*",description:'The number of whole working days between start_date and end_date.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> Working days exclude weekends and any dates identified in holidays.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days worked during a specific term.'},errors:[]},{isDocumented:!0,arity:3,name:"networkdays",qname:"excel-datetime:networkdays",signature:"($start_date as xs:date, $end_date as xs:date, $holidays as xs:date*) as xs:integer*",description:" Returns the number of whole working days between $start_date and $end_date.\n",summary:"<p> Returns the number of whole working days between $start_date and $end_date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"start_date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the start date.</div>'},{name:"end_date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the end date.</div>'},{name:"holidays",type:"xs:date",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> one or more dates to exclude from the working calendar, such as state and federal holidays and floating holidays.</div>'}],returns:{type:"xs:integer*",description:'The number of whole working days between start_date and end_date.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> Working days exclude weekends and any dates identified in holidays.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days worked during a specific term.'},errors:[]},{isDocumented:!0,arity:0,name:"now",qname:"excel-datetime:now",signature:"() as xs:dateTime?",description:" Returns the current date and time.\n",summary:"<p> Returns the current date and time.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:dateTime?",description:"The current date and time."},errors:[]},{isDocumented:!0,arity:1,name:"second",qname:"excel-datetime:second",signature:"($time as xs:time) as xs:decimal?",description:" Returns the seconds of a $time value.\n",summary:"<p> Returns the seconds of a $time value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"time",type:"xs:time",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the time.</div>'}],returns:{type:"xs:decimal?",description:"The seconds of a $time value. The second is given as an integer in the range 0 (zero) to 59."},errors:[]},{isDocumented:!0,arity:3,name:"time",qname:"excel-datetime:time",signature:"($hour as xs:integer, $minute as xs:integer, $second as xs:integer) as xs:time?",description:" Constructs a time given the hours, minutes and seconds.\n",summary:"<p> Constructs a time given the hours, minutes and seconds.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"hour",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the hour.</div>'},{name:"minute",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the minute.</div>'},{name:"second",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second.</div>'}],returns:{type:"xs:time?",description:"A time given the hours, minutes and seconds."},errors:[]},{isDocumented:!0,arity:0,name:"today",qname:"excel-datetime:today",signature:"() as xs:date?",description:" Returns the current date.\n",summary:"<p> Returns the current date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:date?",description:"The current date."},errors:[]},{isDocumented:!0,arity:1,name:"weekday",qname:"excel-datetime:weekday",signature:"($date as xs:date) as xs:integer?",description:" Returns the day of the week corresponding to a $date.\n",summary:"<p> Returns the day of the week corresponding to a $date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date.</div>'}],returns:{type:"xs:integer?",description:"The day of the week corresponding to a $date. The day is given as an integer, ranging from 1 (Sunday) to 7 (Saturday)."},errors:[]},{isDocumented:!0,arity:2,name:"weekday",qname:"excel-datetime:weekday",signature:"($date as xs:date, $return_type as xs:integer) as xs:integer?",description:" Returns the day of the week corresponding to a $date depending on $return_type.\n",summary:"<p> Returns the day of the week corresponding to a $date depending on $return_type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date.</div>'},{name:"return_type",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> 1 for Numbers 1 (Sunday) through 7 (Saturday). 2 for Numbers 1 (Monday) through 7 (Sunday). 3 for Numbers 0 (Monday) through 6 (Sunday).</div>'}],returns:{type:"xs:integer?",description:"The day of the week corresponding to a $date depending on $return_type."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if $return_type is outside the range [1,3].</xqdoc:error>']},{isDocumented:!0,arity:1,name:"year",qname:"excel-datetime:year",signature:"($date as xs:date) as xs:integer?",description:" Returns the year corresponding to a date.\n",summary:"<p> Returns the year corresponding to a date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:date",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date.</div>'}],returns:{type:"xs:integer?",description:"The year corresponding to a date."},errors:[]}],variables:[]},"http://xbrl.io/modules/bizql/profiles/sec/filings":{ns:"http://xbrl.io/modules/bizql/profiles/sec/filings",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for querying financial reports (filings)\n submitted to the SEC.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">SEC Filings are nothing else than XBRL archives. For XBRL-generic requests on archives,\n use the generic archives module.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can access a number of properties of an SEC filing, such as\n its document type. You can also retrieve an SEC filing given an SEC company (or its CIK).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">You can also access SEC filings statistics (the number of SEC Networks, of SEC Axes, etc).</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/companies",prefix:"companies"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://zorba.io/modules/datetime",prefix:"datetime"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/filings",prefix:"filings"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/core",prefix:"sec"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"acceptance-dateTimes",qname:"filings:acceptance-dateTimes",signature:"($filings-or-ids as item()*) as dateTime*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the acceptance date of filings.</p>\n',summary:"<p>  Retrieves the acceptance date of filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of filings or their IDs.</div>'}],returns:{type:"dateTime*",description:"the acceptance dateTimes."},errors:[]},{isDocumented:!0,arity:1,name:"document-types",qname:"filings:document-types",signature:"($filings-or-ids as item()*) as string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the document type of the filings.</p>\n',summary:"<p>  Retrieves the document type of the filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of filings or their ids.</div>'}],returns:{type:"string?",description:"the document types (10-K, 10-Q)."},errors:[]},{isDocumented:!0,arity:1,name:"filing-dates",qname:"filings:filing-dates",signature:"($filings-or-ids as item()*) as date*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the submission date of filings.</p>\n',summary:"<p>  Retrieves the submission date of filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of filings or their IDs.</div>'}],returns:{type:"date*",description:"the submission dates."},errors:[]},{isDocumented:!0,arity:1,name:"filings-for-companies",qname:"filings:filings-for-companies",signature:"($companies-or-ciks as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all filings submitted by the supplied companies.</p>\n',summary:"<p>  Return all filings submitted by the supplied companies.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"companies-or-ciks",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> arbitrary number of company objects or CIKs.</div>'}],returns:{type:"object()*",description:"all filings submitted by these companies."},errors:[]},{isDocumented:!0,arity:1,name:"generators",qname:"filings:generators",signature:"($filings-or-ids as item()*) as string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the generators of filings.</p>\n',summary:"<p>  Retrieves the generators of filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of filings or their IDs.</div>'}],returns:{type:"string*",description:"the generators used."},errors:[]},{isDocumented:!0,arity:1,name:"num-abstracts",qname:"filings:num-abstracts",signature:"($filings-or-ids) as integer*",description:" Return the number of (distinct) abstracts in each of the given filings.\n",summary:"<p> Return the number of (distinct) abstracts in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of abstracts"},errors:[]},{isDocumented:!0,arity:1,name:"num-axes",qname:"filings:num-axes",signature:"($filings-or-ids) as integer*",description:" Return the number of (distinct) axes in each of the given filings.\n",summary:"<p> Return the number of (distinct) axes in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of axes"},errors:[]},{isDocumented:!0,arity:1,name:"num-concepts",qname:"filings:num-concepts",signature:"($filings-or-ids) as integer*",description:" Return the number of (distinct) concepts in each of the given filings.\n",summary:"<p> Return the number of (distinct) concepts in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of concepts"},errors:[]},{isDocumented:!0,arity:1,name:"num-extension-abstracts",qname:"filings:num-extension-abstracts",signature:"($filings-or-ids) as integer*",description:" Return the number of extension abstracts in each of the given filings.\n",summary:"<p> Return the number of extension abstracts in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of abstracts"},errors:[]},{isDocumented:!0,arity:1,name:"num-extension-concepts",qname:"filings:num-extension-concepts",signature:"($filings-or-ids) as integer*",description:" Return the number of extension concepts in each of the given filings.\n",summary:"<p> Return the number of extension concepts in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of concepts"},errors:[]},{isDocumented:!0,arity:1,name:"num-extension-facts",qname:"filings:num-extension-facts",signature:"($filings-or-ids) as integer*",description:" Return the number of extension facts in each of the given filings.\n",summary:"<p> Return the number of extension facts in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of facts"},errors:[]},{isDocumented:!0,arity:1,name:"num-facts",qname:"filings:num-facts",signature:"($filings-or-ids) as integer*",description:" Return the number of facts in each of the given filings.\n",summary:"<p> Return the number of facts in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of facts"},errors:[]},{isDocumented:!0,arity:1,name:"num-footnotes",qname:"filings:num-footnotes",signature:"($filings-or-ids) as integer*",description:" Return the number of footnotes in each of the given filings.\n",summary:"<p> Return the number of footnotes in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of facts"},errors:[]},{isDocumented:!0,arity:1,name:"num-line-items",qname:"filings:num-line-items",signature:"($filings-or-ids) as integer*",description:" Return the number of (distinct) line items in each of the given filings.\n",summary:"<p> Return the number of (distinct) line items in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of line items"},errors:[]},{isDocumented:!0,arity:1,name:"num-members",qname:"filings:num-members",signature:"($filings-or-ids) as integer*",description:" Return the number of (distinct) members in each of the given filings.\n",summary:"<p> Return the number of (distinct) members in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of members"},errors:[]},{isDocumented:!0,arity:1,name:"num-networks",qname:"filings:num-networks",signature:"($filings-or-ids) as integer*",description:" Return the number of networks in each of the given filings.\n",summary:"<p> Return the number of networks in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of networks"},errors:[]},{isDocumented:!0,arity:1,name:"num-report-elements",qname:"filings:num-report-elements",signature:"($filings-or-ids) as integer*",description:" Return the number of (distinct) report elements in each of the given filings.\n",summary:"<p> Return the number of (distinct) report elements in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of report elements"},errors:[]},{isDocumented:!0,arity:1,name:"num-tables",qname:"filings:num-tables",signature:"($filings-or-ids) as integer*",description:" Return the number of tables in each of the given filings.\n",summary:"<p> Return the number of tables in each of the given filings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filings-or-ids",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> list of filings or IDs</div>'}],returns:{type:"integer*",description:"the said number of tables"},errors:[]}],variables:[]},"http://zorba.io/modules/string":{ns:"http://zorba.io/modules/string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides string related functions.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Mostly, the functions in this module provide primitives\n to work with streamable strings. For example, it allows to\n check whether a given string is streamable or seekable.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/string",prefix:"string"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"analyze-string",qname:"string:analyze-string",signature:"($input as xs:string?, $pattern as xs:string) as array()",description:' Analyzes a string using a regular expression, returning sequence of JSON\n objects that identify which parts of the input string matched or failed to\n match the regular expression; and in the case of matched substrings, which\n substrings matched each capturing group in the regular expression.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This function behaves like\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-analyze-string"><code>fn:analyze-string</code></a>\n but returns a JSON array rather than an XML element.\n',summary:"<p> Analyzes a string using a regular expression, returning sequence of JSON\n objects that identify which parts of the input string matched or failed to\n match the regular expression; and in the case of matched substrings, which\n substrings matched each capturing group in the regular expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to analyze. If the empty sequence, the function behaves as if <code>$input</code> were a zero-length string.</div>'},{name:"pattern",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The regular expression.</div>'}],returns:{type:"array()",description:'a JSON array of objects where each object contains a single key/value pair. Each key is either <code xmlns:xqdoc="http://www.xqdoc.org/1.0">match</code> or <code xmlns:xqdoc="http://www.xqdoc.org/1.0">non-match</code>. For <code xmlns:xqdoc="http://www.xqdoc.org/1.0">non-match</code>, the value is a string that is the part of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$input</code> that did not match; for <code xmlns:xqdoc="http://www.xqdoc.org/1.0">match</code>, the value is either a string that is the part of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$input</code> that matched (when <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$pattern</code> contains no capturing groups) or an array containing values for both capturing groups and other matches. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> Capturing group matches are themselves arrays where the first element is the group number (1-based) and subsequent elements are either a string that is the part of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$input</code> that matched or sub-arrays for nested capturing groups.'},errors:[]},{isDocumented:!0,arity:3,name:"analyze-string",qname:"string:analyze-string",signature:"($input as xs:string?, $pattern as xs:string, $flags as xs:string) as array() external",description:' Analyzes a string using a regular expression, returning sequence of JSON\n objects that identify which parts of the input string matched or failed to\n match the regular expression; and in the case of matched substrings, which\n substrings matched each capturing group in the regular expression.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This function behaves like\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-analyze-string"><code>fn:analyze-string</code></a>\n but returns a JSON array rather than an XML element.\n',summary:"<p> Analyzes a string using a regular expression, returning sequence of JSON\n objects that identify which parts of the input string matched or failed to\n match the regular expression; and in the case of matched substrings, which\n substrings matched each capturing group in the regular expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to analyze. If the empty sequence, the function behaves as if <code>$input</code> were a zero-length string.</div>'},{name:"pattern",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The regular expression.</div>'},{name:"flags",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The  argument is interpreted in the same way as for the <a href="http://www.w3.org/TR/xpath-functions-30/#func-matches"><code>fn:matches</code></a> function.</div>'}],returns:{type:"array()",description:'a JSON array of objects where each object contains a single key/value pair. Each key is either <code xmlns:xqdoc="http://www.xqdoc.org/1.0">match</code> or <code xmlns:xqdoc="http://www.xqdoc.org/1.0">non-match</code>. For <code xmlns:xqdoc="http://www.xqdoc.org/1.0">non-match</code>, the value is a string that is the part of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$input</code> that did not match; for <code xmlns:xqdoc="http://www.xqdoc.org/1.0">match</code>, the value is either a string that is the part of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$input</code> that matched (when <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$pattern</code> contains no capturing groups) or an array containing values for both capturing groups and other matches. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> Capturing group matches are themselves arrays where the first element is the group number (1-based) and subsequent elements are either a string that is the part of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$input</code> that matched or sub-arrays for nested capturing groups.'},errors:[]},{isDocumented:!0,arity:1,name:"is-seekable",qname:"string:is-seekable",signature:"($s as string) as boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function checks whether a given string item is a\n seekable stream string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, a seekable streamable string is returned by the\n file module.</p>\n',summary:"<p>  This function checks whether a given string item is a\n seekable stream string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to check</div>'}],returns:{type:"boolean",description:"true if the given item is a seekable stream string or false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"is-streamable",qname:"string:is-streamable",signature:"($s as string) as boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function checks whether a given string item is implemented by a\n streamable string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A streamable string is produced by some functions of a module.\n It\'s an optimized implementation of an string to handle arbitrary\n sized data. The drawback is that its value can only be consumed once.\n That is, only one function can access the value of a streamable string\n item.</p>\n',summary:"<p>  This function checks whether a given string item is implemented by a\n streamable string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to check</div>'}],returns:{type:"boolean",description:"true if the given item is implemented using a streamable string or false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"materialize",qname:"string:materialize",signature:"($s as string) as string external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function materializes a streamable string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The drawback of a streamable (non-seekable) string is that\n its value can only be consumed once. That is, only one function\n can access the value of a streamable string item.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In order to remedy this situation, this function can be used to\n convert a streamable string into its non-streamable counterpart. As a\n result, the string returned by this function has the same value as its\n input but is materialized and, hence, can be consumed multiple times.</p>\n',summary:"<p>  This function materializes a streamable string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the streamable string item to materialize</div>'}],returns:{type:"string",description:"a materialized string of its input or the input if the input item was not a streamable string."},errors:[]},{isDocumented:!0,arity:2,name:"split",qname:"string:split",signature:"($s as string, $separator as string) as string* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a sequence of strings constructed by splitting the input wherever\n the given separator is found.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function is different from tokenize. It doesn\'t allow\n the separator to be a regular expression. This restriction allows for more\n performant implementation. Specifically, the function processes\n streamable strings as input in a streamable way which is particularly useful\n to tokenize huge strings.</p>\n',summary:"<p>  Returns a sequence of strings constructed by splitting the input wherever\n the given separator is found.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the input string to split</div>'},{name:"separator",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the separator used for splitting the input string $s</div>'}],returns:{type:"string*",description:"a sequence of strings constructed by splitting the input"},errors:[]}],variables:[]},"http://www.28msec.com/modules/store":{ns:"http://www.28msec.com/modules/store",description:" This module provides functions to perform MongoDB query operations\n (i.e. find and aggregate) on the database associated with the\n project.\n <p xmlns:xqdoc=\"http://www.xqdoc.org/1.0\">The module is always imported so you don't need to import it explicitly.\n Also, you don't need to fully qualify the function if you want to invoke it.</p>\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/mongodb/types",prefix:"mongo"},{uri:"http://www.28msec.com/modules/store",prefix:"store"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"aggregate",qname:"store:aggregate",signature:"($collection as string, $pipeline as array()) as object() external",description:' Performs a MongoDB aggregation framework job on the given collection.\n The <em xmlns:xqdoc="http://www.xqdoc.org/1.0">$pipeline</em> parameter needs to specify a valid aggregation\n framework pipeline. For example,\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  [\n    { $project : {\n       author : 1,\n       tags : 1,\n    } },\n    { $unwind : "$tags" },\n    { $group : {\n       _id : { tags : "$tags" },\n       authors : { $addToSet : "$author" }\n    } }\n ]\n </pre>\n The function returns the result as one object. The object contains\n the field named "ok" with value 0 if the execution failed or 1 if\n it succeeded. If it succeeded, the result is contained as an array\n in the result field. Otherwise, the errmsg field contains the description\n of the error. For exampl,e\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n {\n   "result" : [ ... ],\n   "ok" : 1\n }\n </pre>\n',summary:"<p> Performs a MongoDB aggregation framework job on the given collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"collection",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection to execute the job on</div>'},{name:"pipeline",type:"array()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the specification of the pipeline to execute</div>'}],returns:{type:"object()",description:"an object with the result or the error message."},errors:[]},{isDocumented:!1,arity:1,name:"clear-if",qname:"store:clear-if",signature:"($cond as boolean) as integer",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"cond",type:"boolean",occurrence:null,description:""}],returns:{type:"integer",description:""},errors:[]},{isDocumented:!1,arity:0,name:"clear",qname:"store:clear",signature:"() as integer external",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"integer",description:""},errors:[]},{isDocumented:!1,arity:1,name:"collection-chunk-specs",qname:"store:collection-chunk-specs",signature:"($name as string) as object()*",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:""}],returns:{type:"object()*",description:""},errors:[]},{isDocumented:!1,arity:2,name:"collection-chunk-specs",qname:"store:collection-chunk-specs",signature:"($name as string, $chunk-size as integer) as object()* external",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:""},{name:"chunk-size",type:"integer",occurrence:null,description:""}],returns:{type:"object()*",description:""},errors:[]},{isDocumented:!1,arity:2,name:"collection-chunk",qname:"store:collection-chunk",signature:"($name as string, $chunk as object()) as item()* external",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"string",occurrence:null,description:""},{name:"chunk",type:"object()",occurrence:null,description:""}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"find",qname:"store:find",signature:"($coll as string, $query as object()) as object()*",description:" Performs a MongoDB query operation on the given collection and\n returns all matches.\n",summary:"<p> Performs a MongoDB query operation on the given collection and\n returns all matches.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"coll",type:"string",occurrence:null,description:""},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query operation to perform</div>'}],returns:{type:"object()*",description:"all matches returned by the given query operation"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZSTR0009 if the given collection does not exist</xqdoc:error>']},{isDocumented:!0,arity:3,name:"find",qname:"store:find",signature:"($coll as string, $query as object(), $options as object()) as object()* external",description:' Performs a MongoDB query operation on the given collection and\n returns all matches.\n Available options:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>to-return: the maximum number of objects to return (0 = unlimited)</li>\n   <li>to-skip: start with the n-th object</li>\n   <li>batch-size: the number of objects to return in one batch</li>\n   <li>slave-ok: allow this query to be run against a replica secondary</li>\n   <li>await-data: the server will block for some extra time before returning,\n   waiting for more data to return</li>\n   <li>partial-results: return partial results if some shards are down instead\n   of returning an error</li>\n </ul>\n',summary:"<p> Performs a MongoDB query operation on the given collection and\n returns all matches.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"coll",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection</div>'},{name:"query",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query operation to perform</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the options for this operation</div>'}],returns:{type:"object()*",description:"all matches returned by the given query operation"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZSTR0009 if the given collection does not exist</xqdoc:error>']},{isDocumented:!1,arity:1,name:"flush-if",qname:"store:flush-if",signature:"($cond as boolean) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"cond",type:"boolean",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]},{isDocumented:!1,arity:0,name:"flush",qname:"store:flush",signature:"() as empty-sequence() external",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"empty-sequence()",description:""},errors:[]}],variables:[]},"http://zorba.io/modules/hash":{ns:"http://zorba.io/modules/hash",description:" This module provides functions that perform different hash operations.\n For example, they compute MD5 and various SHA functions on either\n strings or binary. The result is the base64 encoded value of the hash.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Gabriel Petrovay, Markus Pilman, Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/hash",prefix:"hash"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"hash-binary",qname:"hash:hash-binary",signature:"($value as xs:base64Binary, $alg as xs:string) as xs:base64Binary external",description:" This function computes a hash value of the binary form of the given\n base64Binary item, i.e. the item is base64-decoded before hashing.\n",summary:"<p> This function computes a hash value of the binary form of the given\n base64Binary item, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The binary item to be hashed.</div>'},{name:"alg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The algorithm to use for this hashing operation. Supported algorithms are "md5", "sha1", and "sha256".</div>'}],returns:{type:"xs:base64Binary",description:"The hash as xs:base64Binary of the provided binary"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">hash:UNSUPPORTED-ALGORITHM if the given hash algorithm is not supported</xqdoc:error>']},{isDocumented:!0,arity:2,name:"hash",qname:"hash:hash",signature:"($value as xs:string, $alg as xs:string) as xs:base64Binary external",description:" This function computes a hash value of the string provided as parameter.\n The function expects the hash algorithm to be used as parameter.\n",summary:"<p> This function computes a hash value of the string provided as parameter.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to be hashed.</div>'},{name:"alg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The algorithm to use for this hashing operation. Supported algorithms are "md5", "sha1", and "sha256".</div>'}],returns:{type:"xs:base64Binary",description:"The hash as xs:base64binary of the provided string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">hash:UNSUPPORTED-ALGORITHM if the given hash algorithm is not supported</xqdoc:error>']},{isDocumented:!0,arity:1,name:"md5-binary",qname:"hash:md5-binary",signature:"($value as xs:base64Binary) as xs:base64Binary",description:" This function computes the MD5 hash value of the binary form of the given\n base64Binary item, i.e. the item is base64-decoded before hashing.\n",summary:"<p> This function computes the MD5 hash value of the binary form of the given\n base64Binary item, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The binary item to hash.</div>'}],returns:{type:"xs:base64Binary",description:"The MD5 hash of the provided binary."},errors:[]},{isDocumented:!0,arity:1,name:"md5",qname:"hash:md5",signature:"($value as xs:string) as xs:base64Binary",description:" Computes the MD5 hash of the string provided as parameter.\n",summary:"<p> Computes the MD5 hash of the string provided as parameter.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to hash</div>'}],returns:{type:"xs:base64Binary",description:"The MD5 hash as xs:base64Binary"},errors:[]},{isDocumented:!0,arity:1,name:"sha1-binary",qname:"hash:sha1-binary",signature:"($value as xs:base64Binary) as xs:base64Binary",description:" This function computes the SHA1 hash value of the binary form of the given\n base64Binary item, i.e. the item is base64-decoded before hashing.\n",summary:"<p> This function computes the SHA1 hash value of the binary form of the given\n base64Binary item, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The binary item to hash.</div>'}],returns:{type:"xs:base64Binary",description:"The base64 encoded SHA1 hash of the provided binary."},errors:[]},{isDocumented:!0,arity:1,name:"sha1",qname:"hash:sha1",signature:"($value as xs:string) as xs:base64Binary",description:" Computes the SHA1 hash of the string provided as parameter.\n",summary:"<p> Computes the SHA1 hash of the string provided as parameter.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to hash.</div>'}],returns:{type:"xs:base64Binary",description:"The SHA1 hash as xs:base64Binary"},errors:[]}],variables:[]},"http://zorba.io/modules/xsl-fo":{ns:"http://zorba.io/modules/xsl-fo",description:' This module converts <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3schools.com/xslfo/default.asp">XSL-FO</a> documents\n to various formats such as PDF, EPS, PCL, AFP, Text, PNG, Postscript, RTF, and TIFF.\n For instance, the following example converts a simple XSL-FO document to PDF:\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">import module namespace fop = "http://zorba.io/modules/xsl-fo";\n import module namespace file = "http://expath.org/ns/file";\n declare namespace fo = "http://www.w3.org/1999/XSL/Format";\n let $xsl-fo := &lt;fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"&gt;\n   &lt;fo:layout-master-set&gt;\n     &lt;fo:simple-page-master master-name="my-page"&gt;\n       &lt;fo:region-body margin="1in"/&gt;\n     &lt;/fo:simple-page-master&gt;\n   &lt;/fo:layout-master-set&gt;\n   &lt;fo:page-sequence master-reference="my-page"&gt;\n     &lt;fo:flow flow-name="xsl-region-body"&gt;\n       &lt;fo:block&gt;Hello, world!&lt;/fo:block&gt;\n     &lt;/fo:flow&gt;\n   &lt;/fo:page-sequence&gt;\n  &lt;/fo:root&gt;\n let $pdf := fop:generator($fop:PDF, $xsl-fo)\n return file:write-binary("simple.pdf", $pdf)</pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This module uses Apache-FOP to generate content from an XSL-FO document.\n See <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://xmlgraphics.apache.org/fop/">the Apache FOP documentation</a> for further information.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <b xmlns:xqdoc="http://www.xqdoc.org/1.0">Note for Windows users</b>: On Windows, this module won\'t work out of the box, since\n this module uses Java. But the Java VM dll is not in the system path by default. To make\n this module work, you need to add the directory where the jvm.dll is located to the\n system path. This dll is located at JRE_DIR\\bin\\client. On a standard installation, this would\n be something a path like "C:\\Program Files\\Java\\jre6\\bin\\client".\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://xmlgraphics.apache.org/fop/</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Markus Pilman</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.zorba-xquery.com/modules/util-jvm",prefix:"util-jvm"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/modules/xsl-fo",prefix:"xsl-fo"}],functions:[{isDocumented:!0,arity:2,name:"generator",qname:"xsl-fo:generator",signature:"($output-format as xs:string, $xsl-fo-document as node()) as xs:base64Binary",description:' The generator function takes an XSL-FO document as input and generates output\n in the format given as input.\n The output format can be given as a MIME type - for example "application/pdf"\n - or one of the predefined variables can be used - like $xsl-fo:PDF. Please\n refer to the Apache FOP documentation for\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://xmlgraphics.apache.org/fop/0.95/output.html">supported output formats</a>.\n Apache FOP does not support 100% of the XSL-FO standard.\n Please consult the <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://xmlgraphics.apache.org/fop/">official\n documentation for further information</a>.\n This function tries to find the needed Java libraries itself.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n On a Mac OS X computer, it should be sufficient to install Apache FOP via Mac\n Ports.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n On Ubuntu it should be sufficient to install the fop packages via apt-get.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n On Windows, the classpath needs to be set manually using\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#generator#3">generator#3</a>.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This function tries to find the jar files via environment variables. The user can set the\n variable FOP_HOME to the root directory of an Apache FOP distribution. If you have all\n JAR files in the same directory, you can set the environment variable FOP_LIB_DIR to this\n directory.\n',summary:"<p> The generator function takes an XSL-FO document as input and generates output\n in the format given as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"output-format",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The mime of the output format, to tell Apache FOP which kind of document it should create.</div>'},{name:"xsl-fo-document",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The XSL-FO document from which the output should be generated.</div>'}],returns:{type:"xs:base64Binary",description:"The generated output document."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">xsl-fo:JVM-NOT-STARTED If zorba was unable to start the JVM.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">xsl-fo:JAVA-EXCEPTION If Apache FOP throws an exception - i.e. if the input format is not correct/supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">xsl-fo:JAR-NOT-FOUND If a needed Java library could not be found.</xqdoc:error>']}],variables:[{name:"xsl-fo:AFP",type:"xs:string",description:" The mime type of IBMs AFP format (application/x-afp).\n"},{name:"xsl-fo:EPS",type:"xs:string",description:" The mime type of the EPS format (application/postscript).\n"},{name:"xsl-fo:PCL",type:"xs:string",description:" The mime type of the PCL format (application/x-pcl).\n"},{name:"xsl-fo:PDF",type:"xs:string",description:" The mime type of the PDF format (application/pdf).\n"},{name:"xsl-fo:PLAIN_TEXT",type:"xs:string",description:" The mime type for plain text files (text/plain).\n"},{name:"xsl-fo:PNG",type:"xs:string",description:" The mime type of the PNG format (image/png).\n"},{name:"xsl-fo:POSTSCRIPT",type:"xs:string",description:" The mime type of the postscript format (application/postscript).\n"},{name:"xsl-fo:RTF",type:"xs:string",description:" The mime type of the RTF format (application/rtf).\n"},{name:"xsl-fo:TIFF",type:"xs:string",description:" The mime type of TIFF format (application/tiff).\n"}]},"http://zorba.io/warnings":{ns:"http://zorba.io/warnings",description:" This module contains one variable declaration for each diagnostic of the\n http://zorba.io/warnings namespace.\n The variables serves as documentation for the errors but can also\n be used in the code. For example, one useful scenario is to compare\n an error caught in the catch clause of a try-catch expression with one of\n the variables.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Carlos Lopez</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/warnings",prefix:"zwarn"}],functions:[],variables:[{name:"zwarn:NS",type:"item()*",description:""},{name:"zwarn:ZWST0002",type:"xs:QName",description:" This warning is reported if the declaration of a function, variable,\n collection, or index contains an annotation that is not in the\n http://zorba.io/annotations namespace and Zorba doesn't know how to\n handle.\n"},{name:"zwarn:ZWST0003",type:"item()*",description:""},{name:"zwarn:ZWST0004",type:"item()*",description:""},{name:"zwarn:ZWST0005",type:"xs:QName",description:" This warning is raised if the user explicitly enables caching\n of function results (using the %an:cache or %an:strictlydeterministic\n annotation) but the function cannot be cached.\n For %an:cache this happens if the function is updating or variadic.\n For %an:strictlydeterministic this happens if the function is updating,\n variadic or sequential.\n"},{name:"zwarn:ZWST0006",type:"xs:QName",description:" This warning is raised if the user explicitly enables caching\n of function results (using the %an:cache annotation) and the function\n is annotated as sequential or nondeterministic.\n"},{name:"zwarn:ZWST0007",type:"item()*",description:""},{name:"zwarn:ZWST0008",type:"item()*",description:""},{name:"zwarn:ZWST0009",type:"xs:QName",description:' This warning is enabled when the "common-language" option is employed. It will raise warnings\n for language features that are not supported by both XQuery and JSONiq grammars.\n'}]},"http://www.28msec.com/modules/sparql":{ns:"http://www.28msec.com/modules/sparql",description:' This module contains functions to interact with a SPARQL endpoint.\n Requests to an endpoint are made using HTTP.\n Specifically, this module allows SELECT, ASK, CONSTRUCT and DESCRIBE queries. Additionally, it also allows for UPDATE statements.\n Various result formats are supported (e.g. XML, JSON, CSV)\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0">Configuration</h2>\n For this module you may use a preconfigured default or named datasource of the SPARQL category.\n You can also provide a configuration object directly.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">As config parameter you can either pass a string that will be interpreted as a SPARQL endpoint datasource name or\n  an object with the following properties:\n <ul>\n  <li><tt>href</tt>: The URL of the SPARQL endpoint to use. Required.</li>\n  <li><tt>auth_method</tt>: The HTTP authentication method to use.</li>\n  <li><tt>username</tt>: The username to use for HTTP authentication.</li>\n  <li><tt>password</tt>: The password to use for HTTP authentication.</li>\n </ul>\n </p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0">Options</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The options object that can be passed to plenty of the functions in this module. It may have the following properties:\n <ul>\n   <li><tt>default-graph-uri</tt>: A string or an array of strings with the graph URIs to be used by the query.</li>\n   <li><tt>named-graph-uri</tt>: A string or an array of strings with the named graph URIs to be used by the query.</li>\n   <li><tt>using-graph-uri</tt>: A string or an array of strings with the graph URIs to be used by an update statement.</li>\n   <li><tt>using-named-graph-uri</tt>: A string or an array of strings with the named graph URIs to be used by an update statement.</li>\n   <li><tt>method</tt>: The request method to be used. Available method values are $sparql:METHOD-GET, $sparql:METHOD-POST-URLENCODED or $sparql:METHOD-POST-SPARQL.</li>\n   <li><tt>format</tt> : The result format to request. Possible format values are $sparql:FORMAT-XML, $sparql:FORMAT-JSON, $sparql:FORMAT-CSV, $sparql:FORMAT-TSV, $sparql:FORMAT-ANY. For CONSTRUCT or DESCRIBE queries $sparql:FORMAT-RDF is available.</li>\n   <li><tt>parameters</tt>: Many SPARQL endpoints support additional parameters which are not part of the SPARQL endpoint specification. They can be provided here.</li>\n   <li><tt>http-headers</tt>: object that will be used as the headers property for the requests made by the http-client.</li>\n   <li><tt>http-options</tt>: object that will be used as the options property for the requests made by the http-client.</li>\n  </ul>\n <p>All those properties are optional.</p>\n </p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Alexander.Kreutz@28msec.com</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"",prefix:"an"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://zorba.io/modules/http-client",prefix:"http-client"},{uri:"http://www.w3.org/1999/02/22-rdf-syntax-ns#",prefix:"rdf"},{uri:"http://www.w3.org/2005/sparql-results#",prefix:"s"},{uri:"http://www.28msec.com/modules/sparql",prefix:"sparql"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"ask",qname:"sparql:ask",signature:"($query as string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL ASK query to an endpoint and returns the result as boolean value.\n The default datasource for SPARQL will be used.\n </p>\n',summary:"<p>  \n This function sends a SPARQL ASK query to an endpoint and returns the result as boolean value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL ASK query as string.</div>'}],returns:{type:"xs:boolean",description:"The boolean ASK query result."},errors:[]},{isDocumented:!0,arity:2,name:"ask",qname:"sparql:ask",signature:"($query as string, $options as object()?) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL ASK query to an endpoint and returns the result as boolean value.\n The default datasource for SPARQL will be used.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object may be used to request a specific result format. However this function will try to extract only the boolean answer from the result.</li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL ASK query to an endpoint and returns the result as boolean value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL ASK query as string.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"xs:boolean",description:"The boolean ASK query result."},errors:[]},{isDocumented:!0,arity:3,name:"ask",qname:"sparql:ask",signature:"($config as item()?, $query as string, $options as object()?) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL ASK query to an endpoint and returns the result as boolean value.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object may be used to request a specific result format. However this function will try to extract only the boolean answer from the result.</li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL ASK query to an endpoint and returns the result as boolean value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"config",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the credentials to use as string or a config object as described in the module description.</div>'},{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL ASK query as string.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"xs:boolean",description:"The boolean ASK query result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-RESPONSE-TYPE if the response format cannot be handled by this function</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:ERROR if any http or endpoint error occurs</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-PARAMETER invalid option specification</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-NOT-FOUND credential information not found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-INVALID credential information not valid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"query-json",qname:"sparql:query-json",signature:"($query as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL JSON format object.\n If the endpoint fails to deliver SPARQL JSON result format this function will try to convert the results to JSON if possible.\n The default datasource for SPARQL will be used.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Link to the specification of the result format at W3C: <a href="http://www.w3.org/TR/sparql11-results-json" target="_blank">SPARQL 1.1 Query Results JSON Format</a></p>\n',summary:"<p>  \n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL JSON format object.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL SELECT or ASK query as string.</div>'}],returns:{type:"object()",description:"The query result in SPARQL JSON format."},errors:[]},{isDocumented:!0,arity:2,name:"query-json",qname:"sparql:query-json",signature:"($query as string, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL JSON format object.\n If the endpoint fails to deliver SPARQL JSON result format this function will try to convert the results to JSON if possible.\n The default datasource for SPARQL will be used.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Link to the specification of the result format at W3C: <a href="http://www.w3.org/TR/sparql11-results-json" target="_blank">SPARQL 1.1 Query Results JSON Format</a></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object will be ignored. "application/sparql-results+json" will be requested as result format. </li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL JSON format object.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL SELECT or ASK query as string.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"object()",description:"The query result in SPARQL JSON format."},errors:[]},{isDocumented:!0,arity:3,name:"query-json",qname:"sparql:query-json",signature:"($config as item()?, $query as string, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL JSON format object.\n If the endpoint fails to deliver SPARQL JSON result format this function will try to convert the results to JSON if possible.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Link to the specification of the result format at W3C: <a href="http://www.w3.org/TR/sparql11-results-json" target="_blank">SPARQL 1.1 Query Results JSON Format</a></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object will be ignored. "application/sparql-results+json" will be requested as result format. </li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL JSON format object.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"config",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the credentials to use as string or a config object as described in the module description.</div>'},{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL SELECT or ASK query as string.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"object()",description:"The query result in SPARQL JSON format."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-RESPONSE-TYPE if the response format cannot be handled by this function</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:ERROR if any http or endpoint error occurs</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-PARAMETER invalid option specification</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-NOT-FOUND credential information not found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-INVALID credential information not valid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"query-rdf",qname:"sparql:query-rdf",signature:"($query as string) as element(rdf:RDF)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL CONSTRUCT or DESCRIBE query to an endpoint and returns the query response as RDF.\n The default datasource for SPARQL will be used.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Link to the specification of the result format at W3C: <a href="http://www.w3.org/TR/rdf-syntax-grammar" target="_blank">RDF/XML Syntax Specification</a></p>\n',summary:"<p>  \n This function sends a SPARQL CONSTRUCT or DESCRIBE query to an endpoint and returns the query response as RDF.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL CONSTRUCT or DESCRIBE query as string.</div>'}],returns:{type:"element(rdf:RDF)",description:"The query result as RDF XML element."},errors:[]},{isDocumented:!0,arity:2,name:"query-rdf",qname:"sparql:query-rdf",signature:"($query as string, $options as object()?) as element(rdf:RDF)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL CONSTRUCT or DESCRIBE query to an endpoint and returns the query response as RDF.\n The default datasource for SPARQL will be used.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Link to the specification of the result format at W3C: <a href="http://www.w3.org/TR/rdf-syntax-grammar" target="_blank">RDF/XML Syntax Specification</a></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object will be ignored. "application/rdf+xml" will be requested as result format. </li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL CONSTRUCT or DESCRIBE query to an endpoint and returns the query response as RDF.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL CONSTRUCT or DESCRIBE query as string.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"element(rdf:RDF)",description:"The query result as RDF XML element."},errors:[]},{isDocumented:!0,arity:3,name:"query-rdf",qname:"sparql:query-rdf",signature:"($config as item()?, $query as string, $options as object()?) as element(rdf:RDF)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL CONSTRUCT or DESCRIBE query to an endpoint and returns the query response as RDF.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Link to the specification of the result format at W3C: <a href="http://www.w3.org/TR/rdf-syntax-grammar" target="_blank">RDF/XML Syntax Specification</a></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object will be ignored. "application/rdf+xml" will be requested as result format. </li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL CONSTRUCT or DESCRIBE query to an endpoint and returns the query response as RDF.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"config",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the credentials to use as string or a config object as described in the module description.</div>'},{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL CONSTRUCT or DESCRIBE query as string.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"element(rdf:RDF)",description:"The query result as RDF XML element."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-RESPONSE-TYPE if the response format cannot be handled by this function</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:ERROR if any http or endpoint error occurs</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-PARAMETER invalid option specification</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-NOT-FOUND credential information not found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-INVALID credential information not valid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"query-xml",qname:"sparql:query-xml",signature:"($query as string) as element(s:sparql)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL XML format element.\n If the endpoint fails to deliver SPARQL XML result format this function will try to convert the results to XML if possible.\n The default datasource for SPARQL will be used.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Link to the specification of the result format at W3C: <a href="http://www.w3.org/TR/rdf-sparql-XMLres/" target="_blank">SPARQL Query Results XML Format</a></p>\n',summary:"<p>  \n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL XML format element.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL SELECT or ASK query as string.</div>'}],returns:{type:"element(s:sparql)",description:"The query result in SPARQL XML format."},errors:[]},{isDocumented:!0,arity:2,name:"query-xml",qname:"sparql:query-xml",signature:"($query as string, $options as object()?) as element(s:sparql)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL XML format element.\n If the endpoint fails to deliver SPARQL XML result format this function will try to convert the results to XML if possible.\n The default datasource for SPARQL will be used.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Link to the specification of the result format at W3C: <a href="http://www.w3.org/TR/rdf-sparql-XMLres/" target="_blank">SPARQL Query Results XML Format</a></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object will be ignored. "application/sparql-results+xml" will be requested as result format. </li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL XML format element.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL SELECT or ASK query as string.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"element(s:sparql)",description:"The query result in SPARQL XML format."},errors:[]},{isDocumented:!0,arity:3,name:"query-xml",qname:"sparql:query-xml",signature:"($config as item()?, $query as string, $options as object()?) as element(s:sparql)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL XML format element.\n If the endpoint fails to deliver SPARQL XML result format this function will try to convert the results to XML if possible.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Link to the specification of the result format at W3C: <a href="http://www.w3.org/TR/rdf-sparql-XMLres/" target="_blank">SPARQL Query Results XML Format</a></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object will be ignored. "application/sparql-results+xml" will be requested as result format. </li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL SELECT or ASK query to an endpoint and returns the query response as SPARQL XML format element.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"config",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the credentials to use as string or a config object as described in the module description.</div>'},{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL SELECT or ASK query as string.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"element(s:sparql)",description:"The query result in SPARQL XML format."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-RESPONSE-TYPE if the response format cannot be handled by this function</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:ERROR if any http or endpoint error occurs</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-PARAMETER invalid option specification</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-NOT-FOUND credential information not found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-INVALID credential information not valid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"query",qname:"sparql:query",signature:"($query as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL query to an endpoint and directly returns the corresponding HTTP response.\n The default datasource for SPARQL will be used.\n </p>\n',summary:"<p>  \n This function sends a SPARQL query to an endpoint and directly returns the corresponding HTTP response.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL query as string. May be any kind of query but not an update.</div>'}],returns:{type:"object()",description:"The endpoints response. This function returns the plain response object from the http-client."},errors:[]},{isDocumented:!0,arity:2,name:"query",qname:"sparql:query",signature:"($query as string, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL query to an endpoint and directly returns the corresponding HTTP response.\n The default datasource for SPARQL will be used.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object may be used to request a specific result format. XML will be used as default. However, note that this function does not interpret the result.</li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL query to an endpoint and directly returns the corresponding HTTP response.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL query as string. May be any kind of query but not an update.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"object()",description:"The endpoints response. This function returns the plain response object from the http-client."},errors:[]},{isDocumented:!0,arity:3,name:"query",qname:"sparql:query",signature:"($config as item()?, $query as string, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL query to an endpoint and directly returns the corresponding HTTP response.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>default-graph-uri</tt> and <tt>named-graph-uri</tt> properties of the options object may be used to pass default graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. GET will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object may be used to request a specific result format. XML will be used as default. However, note that this function does not interpret the result.</li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL query to an endpoint and directly returns the corresponding HTTP response.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"config",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the credentials to use as string or a config object as described in the module description.</div>'},{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A SPARQL query as string. May be any kind of query but not an update.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"object()",description:"The endpoints response. This function returns the plain response object from the http-client."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-PARAMETER invalid option specification</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-NOT-FOUND credential information not found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-INVALID credential information not valid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"update",qname:"sparql:update",signature:"($update-statement as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL update statement to an endpoint and directly returns the corresponding HTTP response.\n The default datasource for SPARQL will be used.\n </p>\n',summary:"<p>  \n This function sends a SPARQL update statement to an endpoint and directly returns the corresponding HTTP response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"update-statement",type:"string",occurrence:null,description:""}],returns:{type:"object()",description:"The endpoints response. This function returns the plain response object from the http-client."},errors:[]},{isDocumented:!0,arity:2,name:"update",qname:"sparql:update",signature:"($update-statement as string, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL update statement to an endpoint and directly returns the corresponding HTTP response.\n The default datasource for SPARQL will be used.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>using-graph-uri</tt> and <tt>using-named-graph-uri</tt> properties of the options object may be used to pass graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. POST-URLENCODED will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object may be used to request a specific result format. XML will be used as default. However, note that this function does not interpret the result.</li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL update statement to an endpoint and directly returns the corresponding HTTP response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"update-statement",type:"string",occurrence:null,description:""},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"object()",description:"The endpoints response. This function returns the plain response object from the http-client."},errors:[]},{isDocumented:!0,arity:3,name:"update",qname:"sparql:update",signature:"($config as item()?, $update-statement as string, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends a SPARQL update statement to an endpoint and directly returns the corresponding HTTP response.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <ul>\n    <li>The <tt>using-graph-uri</tt> and <tt>using-named-graph-uri</tt> properties of the options object may be used to pass graph URIs or named graph URIs to the endpoint.</li>\n    <li>The <tt>method</tt> property of the options object may be used to set the request method to be used. POST-URLENCODED will be used as default.</li>\n    <li>The <tt>format</tt> property of the options object may be used to request a specific result format. XML will be used as default. However, note that this function does not interpret the result.</li>\n   </ul>\n </p>\n',summary:"<p>  \n This function sends a SPARQL update statement to an endpoint and directly returns the corresponding HTTP response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"config",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the credentials to use as string or a config object as described in the module description.</div>'},{name:"update-statement",type:"string",occurrence:null,description:""},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An optional options object as described in the module description.</div>'}],returns:{type:"object()",description:"The endpoints response. This function returns the plain response object from the http-client."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:INVALID-PARAMETER invalid option specification</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-NOT-FOUND credential information not found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">sparql:CREDENTIALS-INVALID credential information not valid</xqdoc:error>']}],variables:[{name:"sparql:CREDENTIALS-CATEGORY",type:"string",description:" This variable represents the category of the datasource.\n"},{name:"sparql:METHOD-GET",type:"string",description:' This variable represents the request method using HTTP GET requests. May be used for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">method</tt> property of the options object.\n'},{name:"sparql:METHOD-POST-URLENCODED",type:"string",description:' This variable represents the request method using HTTP POST with URL-encoded parameters. May be used for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">method</tt> property of the options object.\n'},{name:"sparql:METHOD-POST-SPARQL",type:"string",description:' This variable represents the request method using HTTP POST with the application/sparql-query content type. May be used for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">method</tt> property of the options object.\n'},{name:"sparql:FORMAT-XML",type:"string",description:' This variable represents the SPARQL XML result format.May be used for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">format</tt> property of the options object.\n'},{name:"sparql:FORMAT-JSON",type:"string",description:' This variable represents the SPARQL JSON result format.May be used for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">format</tt> property of the options object.\n'},{name:"sparql:FORMAT-RDF",type:"string",description:' This variable represents the RDF+XML result format.May be used for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">format</tt> property of the options object.\n'},{name:"sparql:FORMAT-CSV",type:"string",description:' This variable represents the CSV result format.May be used for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">format</tt> property of the options object.\n'},{name:"sparql:FORMAT-TSV",type:"string",description:' This variable represents the TSV result format.May be used for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">format</tt> property of the options object.\n'},{name:"sparql:FORMAT-ANY",type:"string",description:' This variable represents any result format. May be used for the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">format</tt> property of the options object to not specify a requested format.\n'}]},"http://api.28.io/dispatcher":{ns:"http://api.28.io/dispatcher",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/browserview",prefix:"browserview"},{uri:"http://api.28.io/csvview",prefix:"csvview"},{uri:"http://api.28.io/dispatcher",prefix:"dispatcher"},{uri:"http://api.28.io/functions",prefix:"functions"},{uri:"http://api.28.io/model",prefix:"model"},{uri:"http://zorba.io/modules/xml",prefix:"parse-xml"},{uri:"http://www.zorba-xquery.com/schemas/pul",prefix:"pul"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://www.28msec.com/modules/http/response",prefix:"response"},{uri:"http://www.zorba-xquery.com/schemas/xdm",prefix:"xdm"},{uri:"http://api.28.io/xdmview",prefix:"xdmview"}],functions:[{isDocumented:!0,arity:0,name:"restapi",qname:"dispatcher:restapi",signature:"()",description:" Main function for the collection browser. May be called from a handler function.\n Uses the call URL to determine which page needs to be returned.\n The URL for the initial page needs to end with /index\n",summary:"<p> Main function for the collection browser.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:"the requested page of the collection browser"},errors:[]}],variables:[]},"http://zorba.io/modules/store/static/collections/ddl":{ns:"http://zorba.io/modules/store/static/collections/ddl",description:' This modules defines a set of functions for managing collections that are\n declared in the prolog of a module.\n For example, it provides functions to create, delete, or introspect\n collections.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This module is part of <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/xqddf.html">Zorba\'s XQuery Data\n Definition Facility</a>. All the collections managed by this module\n have to be pre-declared in the prolog of a module. Please refer to the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/data_lifecycle.html">general documentation</a>\n for more information and examples.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/data_lifecycle.html">Data Lifecycle</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/xqddf.html">XQuery Data Definition Facility</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/errors</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Nicolae Brinza, Matthias Brantner, David Graf, Till Westmann, Markos Zaharioudakis</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/store/static/collections/ddl",prefix:"cddl"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:0,name:"available-collections",qname:"cddl:available-collections",signature:"() as xs:QName* external",description:" Gets the QNames of the collections that have been statically declared and\n are available, if any.\n",summary:"<p> Gets the QNames of the collections that have been statically declared and\n are available, if any.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence comprising one QName for each statically declared and available collection or an emtpy sequence if no such collections are available."},errors:[]},{isDocumented:!0,arity:1,name:"create",qname:"cddl:create",signature:"($name as xs:QName) external",description:" Creates a collection.\n",summary:"<p> Creates a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The of the collection to create.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, creates a collection with the given name."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if <code>$name</code> is not equal to any of the declared collections in the static context.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0002 if a collection with <code>$name</code> already exists.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"create",qname:"cddl:create",signature:"($name as xs:QName, $content as item()*) external",description:" Creates a collection and adds the given sequence as content to the new\n collection.\n",summary:"<p> Creates a collection and adds the given sequence as content to the new\n collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to create.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequences of items (nodes or JSON items) to be added to the new collection.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, creates a collection with the given name and inserts the given items into it."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if <code>$name</code> is not equal to any of the declared collections in the static context.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0002 if a collection with <code>$name</code> already exists.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type declared by the collection according to the rules for SequenceType Matching.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"declared-collections",qname:"cddl:declared-collections",signature:"() as xs:QName* external",description:" Gets the collections that have been declared in the prolog of the static\n context.\n",summary:"<p> Gets the collections that have been declared in the prolog of the static\n context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each collection created in the static context, or an emtpy sequence."},errors:[]},{isDocumented:!0,arity:1,name:"delete",qname:"cddl:delete",signature:"($name as xs:QName) external",description:" Deletes a collection.\n",summary:"<p> Deletes a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The collection to delete.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, deletes the collection with the given name."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if <code>$name</code> is not equal to any of the declared collections in the static context.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection identified by <code>$name</code> is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0013 if the domain or key expression of any of the available indexes access the collection having <code>$name</code>.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0015 if any of the in-scope variables references an item that belongs to the collection having <code>$name</code></xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-available-collection",qname:"cddl:is-available-collection",signature:"($name as xs:QName) as xs:boolean external",description:" Gets whether a collection is statically declared and available.\n",summary:"<p> Gets whether a collection is statically declared and available.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to check.</div>'}],returns:{type:"xs:boolean",description:"true if the collection was statically declared and is available; false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"is-declared-collection",qname:"cddl:is-declared-collection",signature:"($name as xs:QName) as xs:boolean external",description:" Gers whether a collection was declared in the prolog of the static context.\n",summary:"<p> Gers whether a collection was declared in the prolog of the static context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to check.</div>'}],returns:{type:"xs:boolean",description:"true if the collection was declared; false otherwise."},errors:[]}],variables:[]},"http://www.28msec.com/modules/math":{ns:"http://www.28msec.com/modules/math",description:' The functions in this module perform trigonometric and other mathematical\n calculations on double values.\n For a more detailed description of the semantics of each function, please\n refer to <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#trigonometry">\n Trigonometric and exponential functions</a>.\n',sees:[],authors:[],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xpath-functions/math",prefix:"fnmath"},{uri:"http://www.28msec.com/modules/math",prefix:"math"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"acos",qname:"math:acos",signature:"($arg as double?) as double?",description:" Returns the arc cosine of the argument, the result being in the range zero to +\u03c0 radians.\n",summary:"<p> Returns the arc cosine of the argument, the result being in the range zero to +\u03c0 radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"asin",qname:"math:asin",signature:"($arg as double?) as double?",description:" Returns the arc sine of the argument, the result being in the range -\u03c0/2 to +\u03c0/2 radians.\n",summary:"<p> Returns the arc sine of the argument, the result being in the range -\u03c0/2 to +\u03c0/2 radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"atan",qname:"math:atan",signature:"($arg as double?) as double?",description:" Returns the arc tangent of the argument, the result being in the range -\u03c0/2 to +\u03c0/2 radians.\n",summary:"<p> Returns the arc tangent of the argument, the result being in the range -\u03c0/2 to +\u03c0/2 radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"atan2",qname:"math:atan2",signature:"($y as double, $x as double) as double",description:" Returns the angle in radians subtended at the origin by the point on a plane with\n coordinates (x, y) and the positive x-axis, the result being in the range -\u03c0 to +\u03c0.\n",summary:"<p> Returns the angle in radians subtended at the origin by the point on a plane with\n coordinates (x, y) and the positive x-axis, the result being in the range -\u03c0 to +\u03c0.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"y",type:"double",occurrence:null,description:""},{name:"x",type:"double",occurrence:null,description:""}],returns:{type:"double",description:""},errors:[]},{isDocumented:!0,arity:1,name:"cos",qname:"math:cos",signature:"($theta as double?) as double?",description:" Returns the cosine of the argument, expressed in radians.\n",summary:"<p> Returns the cosine of the argument, expressed in radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"theta",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"exp",qname:"math:exp",signature:"($arg as double?) as double?",description:" Returns the value of ex.\n",summary:"<p> Returns the value of ex.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"exp10",qname:"math:exp10",signature:"($arg as double?) as double?",description:" Returns the value of 10x.\n",summary:"<p> Returns the value of 10x.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"log",qname:"math:log",signature:"($arg as double?) as double?",description:" Returns the natural logarithm of the argument.\n",summary:"<p> Returns the natural logarithm of the argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"log10",qname:"math:log10",signature:"($arg as double?) as double?",description:" Returns the base-ten logarithm of the argument.\n",summary:"<p> Returns the base-ten logarithm of the argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:0,name:"pi",qname:"math:pi",signature:"() as double",description:" Returns an approximation to the mathematical constant \u03c0.\n",summary:"<p> Returns an approximation to the mathematical constant \u03c0.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"double",description:""},errors:[]},{isDocumented:!0,arity:2,name:"pow",qname:"math:pow",signature:"($x as double?, $y) as double?",description:" Returns the result of raising the first argument to the power of the second.\n",summary:"<p> Returns the result of raising the first argument to the power of the second.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"x",type:"double",occurrence:"?",description:""},{name:"y",type:null,occurrence:null,description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sin",qname:"math:sin",signature:"($theta as double?) as double?",description:" Returns the sine of the argument, expressed in radians.\n",summary:"<p> Returns the sine of the argument, expressed in radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"theta",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sqrt",qname:"math:sqrt",signature:"($arg as double?) as double?",description:" Returns the non-negative square root of the argument.\n",summary:"<p> Returns the non-negative square root of the argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"tan",qname:"math:tan",signature:"($theta as double?) as double?",description:" Returns the tangent of the argument, expressed in radians.\n",summary:"<p> Returns the tangent of the argument, expressed in radians.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"theta",type:"double",occurrence:"?",description:""}],returns:{type:"double?",description:""},errors:[]}],variables:[]},"http://zorba.io/modules/data-cleaning/normalization":{ns:"http://zorba.io/modules/data-cleaning/normalization",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This library module provides data normalization functions for processing calendar dates,\n temporal values, currency values, units of measurement, location names and postal addresses.\n These functions are particularly useful for converting different data representations into cannonical formats.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The logic contained in this module is not specific to any particular XQuery implementation.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Bruno Martins and Diogo Sim\u00f5es</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.zorba-xquery.com/modules/http-client",prefix:"http"},{uri:"http://zorba.io/modules/data-cleaning/normalization",prefix:"normalization"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"normalize-address",qname:"normalization:normalize-address",signature:"($addr as xs:string*) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses an address normalization Web service to convert a postal address given as input into a\n cannonical representation format.</p>\n',summary:"<p>  Uses an address normalization Web service to convert a postal address given as input into a\n cannonical representation format.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"addr",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings encoding an address, where each string in the sequence corresponds to a different component (e.g., street, city, country, etc.) of the address.</div>'}],returns:{type:"xs:string*",description:"A sequence of strings with the address encoded in a cannonical format, where each string in the sequence corresponds to a different component (e.g., street, city, country, etc.) of the address."},errors:[]},{isDocumented:!0,arity:1,name:"normalize-phone",qname:"normalization:normalize-phone",signature:"($addr as xs:string*) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses an phone number normalization Web service to convert a phone number given as input into a\n cannonical representation.</p>\n',summary:"<p>  Uses an phone number normalization Web service to convert a phone number given as input into a\n cannonical representation.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"addr",type:"xs:string",occurrence:"*",description:""}],returns:{type:"xs:string*",description:'A strings with the phone number encoded in a cannonical format. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/> <p xmlns:xqdoc="http://www.xqdoc.org/1.0"><b> Attention : This function is still not implemented. </b></p>'},errors:[]},{isDocumented:!0,arity:2,name:"to-date",qname:"normalization:to-date",signature:"($sd as xs:string, $format as xs:string?) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts a given string representation of a date value into a date representation valid according\n to the corresponding XML Schema type.</p>\n',summary:"<p>  Converts a given string representation of a date value into a date representation valid according\n to the corresponding XML Schema type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sd",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string representation for the date</div>'},{name:"format",type:"xs:string",occurrence:"?",description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> An optional parameter denoting the format used to represent the date in the string, according to a sequence of conversion specifications. In the format string, a conversion specification is introduced by '%', usually followed by a single letter or 'O' or 'E' and then a single letter. Any character in the format string that is not part of a conversion specification is interpreted literally, and the string '%%' gives '%'. The supported conversion specifications are as follows: <pre> '%b' Abbreviated month name in the current locale. '%B' Full month name in the current locale. '%d' Day of the month as decimal number (01-31). '%m' Month as decimal number (01-12). '%x' Date, locale-specific. '%y' Year without century (00-99). '%Y' Year with century. '%C' Century (00-99): the integer part of the year divided by 100. '%D' Locale-specific date format such as '%m/%d/%y'. '%e' Day of the month as decimal number (1-31), with a leading pace for a single-digit number. '%F' Equivalent to %Y-%m-%d (the ISO 8601 date format). '%h' Equivalent to '%b'. </pre></div>"}],returns:{type:"xs:string",description:"The date value resulting from the conversion."},errors:[]},{isDocumented:!0,arity:2,name:"to-dateTime",qname:"normalization:to-dateTime",signature:"($sd as xs:string, $format as xs:string?) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts a given string representation of a dateTime value into a dateTime representation\n valid according to the corresponding XML Schema type.</p>\n',summary:"<p>  Converts a given string representation of a dateTime value into a dateTime representation\n valid according to the corresponding XML Schema type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sd",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string representation for the dateTime.</div>'},{name:"format",type:"xs:string",occurrence:"?",description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> An optional parameter denoting the format used to represent the dateTime in the string, according to a sequence of conversion specifications. In the format string, a conversion specification is introduced by '%', usually followed by a single letter or 'O' or 'E' and then a single letter. Any character in the format string that is not part of a conversion specification is interpreted literally, and the string '%%' gives '%'. The supported conversion specifications are as follows: <p/> <pre class=\"ace-static\"> '%b' Abbreviated month name in the current locale. '%B' Full month name in the current locale. '%c' Date and time, locale-specific. '%C' Century (00-99): the integer part of the year divided by 100. '%d' Day of the month as decimal number (01-31). '%H' Hours as decimal number (00-23). '%I' Hours as decimal number (01-12). '%j' Day of year as decimal number (001-366). '%m' Month as decimal number (01-12). '%M' Minute as decimal number (00-59). '%p' AM/PM indicator in the locale. Used in conjunction with '%I' and *not* with '%H'. '%S' Second as decimal number (00-61), allowing for up to two leap-seconds. '%x' Date, locale-specific. '%X' Time, locale-specific. '%y' Year without century (00-99). '%Y' Year with century. '%z' Offset from Greenwich, so '-0900' is 9 hours west of Greenwich. '%Z' Time zone as a character string. '%D' Locale-specific date format such as '%m/%d/%y': ISO C99 says it should be that exact format. '%e' Day of the month as decimal number (1-31), with a leading pace for a single-digit number. '%F' Equivalent to %Y-%m-%d (the ISO 8601 date format). '%g' The last two digits of the week-based year (see '%V'). '%G' The week-based year (see '%V') as a decimal number. '%h' Equivalent to '%b'. '%k' The 24-hour clock time with single digits preceded by a blank. '%l' The 12-hour clock time with single digits preceded by a blank. '%r' The 12-hour clock time (using the locale's AM or PM). '%R' Equivalent to '%H:%M'. '%T' Equivalent to '%H:%M:%S'. </pre></div>"}],returns:{type:"xs:string",description:"The dateTime value resulting from the conversion."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">normalization:NOTSUPPORTED if the dateTime type is not known to the service.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"to-time",qname:"normalization:to-time",signature:"($sd as xs:string, $format as xs:string?) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts a given string representation of a time value into a time representation valid according to\n the corresponding XML Schema type.</p>\n',summary:"<p>  Converts a given string representation of a time value into a time representation valid according to\n the corresponding XML Schema type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sd",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string representation for the time.</div>'},{name:"format",type:"xs:string",occurrence:"?",description:"<div xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> An optional parameter denoting the format used to represent the time in the string, according to a sequence of conversion specifications. In the format string, a conversion specification is introduced by '%', usually followed by a single letter or 'O' or 'E' and then a single letter. Any character in the format string that is not part of a conversion specification is interpreted literally, and the string '%%' gives '%'. The supported conversion specifications are as follows: <p/> <pre class=\"ace-static\"> '%H' Hours as decimal number (00-23). '%I' Hours as decimal number (01-12). '%M' Minute as decimal number (00-59). '%p' AM/PM indicator in the locale. Used in conjunction with '%I' and *not* with '%H'. '%S' Second as decimal number (00-61), allowing for up to two leap-seconds. '%X' Time, locale-specific. '%z' Offset from Greenwich, so '-0900' is 9 hours west of Greenwich. '%Z' Time zone as a character string. '%k' The 24-hour clock time with single digits preceded by a blank. '%l' The 12-hour clock time with single digits preceded by a blank. '%r' The 12-hour clock time (using the locale's AM or PM). '%R' Equivalent to '%H:%M'. '%T' Equivalent to '%H:%M:%S'. </pre></div>"}],returns:{type:"xs:string?",description:"The time value resulting from the conversion."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">normalization:NOTSUPPORTED if the date type is not known to the service.</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/excel/engineering":{ns:"http://zorba.io/modules/excel/engineering",description:"  This is a library module offering the same set of functions\n defined by Microsoft Excel, under Engineering Functions.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://office.microsoft.com/en-us/excel/CH062528241033.aspx" target="_blank">Excel Documentation: Engineering Functions</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Sorin Nasoi</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/engineering",prefix:"excel-engineering"},{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/modules/excel/math",prefix:"excel-math"},{uri:"http://zorba.io/modules/excel/text",prefix:"excel-text"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"bin2dec",qname:"excel-engineering:bin2dec",signature:"($arg as xs:anyAtomicType) as xs:integer",description:" Converts a binary number to decimal.\n",summary:"<p> Converts a binary number to decimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:integer",description:"A decimal representation of a number given it's binary representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a binary representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"bin2hex",qname:"excel-engineering:bin2hex",signature:"($arg as xs:anyAtomicType) as xs:string",description:" Converts a binary number to hexadecimal.\n",summary:"<p> Converts a binary number to hexadecimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:string",description:"A hexadecimal representation of a number given it's binary representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a binary representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"bin2hex",qname:"excel-engineering:bin2hex",signature:"($arg as xs:anyAtomicType, $places as xs:anyAtomicType) as xs:string",description:" Converts a binary number to hexadecimal.\n",summary:"<p> Converts a binary number to hexadecimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'},{name:"places",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of characters to use. Places is useful for padding the return value with leading 0s (zeros).</div>'}],returns:{type:"xs:string",description:"A hexadecimal representation of a number given it's binary representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a binary representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $places is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is zero or negative.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is too small.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"bin2oct",qname:"excel-engineering:bin2oct",signature:"($arg as xs:anyAtomicType) as xs:string",description:" Converts a binary number to octal.\n",summary:"<p> Converts a binary number to octal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:string",description:"A octal representation of a number given it's binary representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a binary representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"bin2oct",qname:"excel-engineering:bin2oct",signature:"($arg as xs:anyAtomicType, $places as xs:anyAtomicType) as xs:string",description:" Converts a binary number to octal.\n",summary:"<p> Converts a binary number to octal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'},{name:"places",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of characters to use. Places is useful for padding the return value with leading 0s (zeros).</div>'}],returns:{type:"xs:string",description:"A octal representation of a number given it's binary representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a binary representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $places is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is zero or negative.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is too small.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"dec2bin",qname:"excel-engineering:dec2bin",signature:"($arg as xs:anyAtomicType) as xs:string",description:" Converts a decimal number to binary.\n",summary:"<p> Converts a decimal number to binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:string",description:"A binary representation of a number given it's decimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $arg is smaller than -512 or bigger than 511.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"dec2bin",qname:"excel-engineering:dec2bin",signature:"($arg as xs:anyAtomicType, $places as xs:anyAtomicType) as xs:string",description:" Converts a decimal number to binary.\n",summary:"<p> Converts a decimal number to binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'},{name:"places",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of characters to use. Places is useful for padding the return value with leading 0s (zeros).</div>'}],returns:{type:"xs:string",description:"A binary representation of a number given it's decimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $places is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is zero or negative.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is too small.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $arg is smaller than -512 or bigger than 511.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"dec2hex",qname:"excel-engineering:dec2hex",signature:"($arg as xs:anyAtomicType) as xs:string",description:" Converts a decimal number to hexadecimal.\n",summary:"<p> Converts a decimal number to hexadecimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:string",description:"A hexadecimal representation of a number given it's decimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $arg is smaller than -549755813888 or bigger than 549755813887</xqdoc:error>']},{isDocumented:!0,arity:2,name:"dec2hex",qname:"excel-engineering:dec2hex",signature:"($arg as xs:anyAtomicType, $places as xs:anyAtomicType) as xs:string",description:" Converts a decimal number to hexadecimal.\n",summary:"<p> Converts a decimal number to hexadecimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'},{name:"places",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of characters to use. Places is useful for padding the return value with leading 0s (zeros).</div>'}],returns:{type:"xs:string",description:"A hexadecimal representation of a number given it's decimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $places is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is zero or negative.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is too small.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $arg is smaller than -549755813888 or bigger than 549755813887.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"dec2oct",qname:"excel-engineering:dec2oct",signature:"($arg as xs:anyAtomicType) as xs:string",description:" Converts a decimal number to octal.\n",summary:"<p> Converts a decimal number to octal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:string",description:"An octal representation of a number given it's decimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $arg is smaller than -536870912 or bigger than 536870911.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"dec2oct",qname:"excel-engineering:dec2oct",signature:"($arg as xs:anyAtomicType, $places as xs:anyAtomicType) as xs:string",description:" Converts a decimal number to octal.\n",summary:"<p> Converts a decimal number to octal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number</div>'},{name:"places",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of characters to use. Places is useful for padding the return value with leading 0s (zeros).</div>'}],returns:{type:"xs:string",description:"An octal representation of a number given it's decimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not numeric</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $places is not numeric</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is zero or negative</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is too small</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $arg is smaller than -536870912 or bigger than 536870911</xqdoc:error>']},{isDocumented:!0,arity:1,name:"hex2bin",qname:"excel-engineering:hex2bin",signature:"($arg as xs:anyAtomicType) as xs:string",description:" Converts a hexadecimal number to binary.\n",summary:"<p> Converts a hexadecimal number to binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:string",description:"A binary representation of a number given it's hexadecimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a hexadecimal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"hex2bin",qname:"excel-engineering:hex2bin",signature:"($arg as xs:anyAtomicType, $places as xs:anyAtomicType) as xs:string",description:" Converts a hexadecimal number to binary.\n",summary:"<p> Converts a hexadecimal number to binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'},{name:"places",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of characters to use. Places is useful for padding the return value with leading 0s (zeros).</div>'}],returns:{type:"xs:string",description:"A binary representation of a number given it's hexadecimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a hexadecimal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $places is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is zero or negative.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is too small.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"hex2dec",qname:"excel-engineering:hex2dec",signature:"($arg as xs:string) as xs:integer",description:" Converts a hexadecimal number to decimal.\n",summary:"<p> Converts a hexadecimal number to decimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:integer",description:"A decimal representation of a number given it's hexadecimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a hexadecimal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"hex2oct",qname:"excel-engineering:hex2oct",signature:"($arg as xs:anyAtomicType) as xs:string",description:" Converts a hexadecimal number to octal.\n",summary:"<p> Converts a hexadecimal number to octal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:string",description:"A octal representation of a number given it's hexadecimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a hexadecimal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"hex2oct",qname:"excel-engineering:hex2oct",signature:"($arg as xs:anyAtomicType, $places as xs:anyAtomicType) as xs:string",description:" Converts a hexadecimal number to octal.\n",summary:"<p> Converts a hexadecimal number to octal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'},{name:"places",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of characters to use. Places is useful for padding the return value with leading 0s (zeros).</div>'}],returns:{type:"xs:string",description:"A octal representation of a number given it's hexadecimal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not a hexadecimal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $places is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is zero or negative.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is too small.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"oct2bin",qname:"excel-engineering:oct2bin",signature:"($arg as xs:anyAtomicType) as xs:string",description:" Converts an octal number to binary.\n",summary:"<p> Converts an octal number to binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:string",description:"A binary representation of a number given it's octal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not an octal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"oct2bin",qname:"excel-engineering:oct2bin",signature:"($arg as xs:anyAtomicType, $places as xs:anyAtomicType) as xs:string",description:" Converts an octal number to binary.\n",summary:"<p> Converts an octal number to binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'},{name:"places",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of characters to use. Places is useful for padding the return value with leading 0s (zeros).</div>'}],returns:{type:"xs:string",description:"A binary representation of a number given it's octal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not an octal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $places is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is zero or negative.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is too small.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"oct2dec",qname:"excel-engineering:oct2dec",signature:"($arg as xs:anyAtomicType) as xs:integer",description:" Converts an octal number to decimal.\n",summary:"<p> Converts an octal number to decimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:integer",description:"A decimal representation of a number given it's octal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not an octal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"oct2hex",qname:"excel-engineering:oct2hex",signature:"($arg as xs:anyAtomicType) as xs:string",description:" Converts an octal number to hexadecimal.\n",summary:"<p> Converts an octal number to hexadecimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'}],returns:{type:"xs:string",description:"A hexadecimal representation of a number given it's octal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not an octal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"oct2hex",qname:"excel-engineering:oct2hex",signature:"($arg as xs:anyAtomicType, $places as xs:anyAtomicType) as xs:string",description:" Converts an octal number to hexadecimal.\n",summary:"<p> Converts an octal number to hexadecimal.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number.</div>'},{name:"places",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is the number of characters to use. Places is useful for padding the return value with leading 0s (zeros).</div>'}],returns:{type:"xs:string",description:"A hexadecimal representation of a number given it's octal representation."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg is not an octal representation of a number.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $arg contains more than 10 characters.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value for $places is not numeric.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is zero or negative.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Num if provided value for $places is too small.</xqdoc:error>']}],variables:[]},"http://www.zorba-xquery.com/modules/util-jvm":{ns:"http://www.zorba-xquery.com/modules/util-jvm",description:' This module provides common functionality for modules that use java\n implementations.\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Modules using java implementations must import this module\n to specify the dependency.\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <b xmlns:xqdoc="http://www.xqdoc.org/1.0">Note:</b> Since this module has a Java library dependency a JVM is required\n to be installed on the system. For Windows: jvm.dll is required on the system\n path (usually located in "C:\\Program Files\\Java\\jre\\bin\\client").\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Cezar Andrei</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/util-jvm",prefix:"util-jvm"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[],variables:[]},"http://www.28msec.com/modules/asynchronous-jobs":{ns:"http://www.28msec.com/modules/asynchronous-jobs",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for executing asynchronous jobs.\n There are three kinds of jobs: (1) a job for executing a (public or private)\n query of your project, (2) a job for mapping an input\n collection into an output collection, and (3) a job for shuffling the items\n of an input collection to several output collections.\n Map and Shuffle jobs are mostly used within\n the parallelism framework and are not meant to be created directly.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Jobs that have been scheduled for execution can be referred to by\n an opaque identifier being returned by the corresponding scheduling\n function (e.g. job:execute or job:map). Specifically,\n the job\'s identifier can be used to retrieve the status of a job\n (e.g. job:status) or the names of its input and output collections.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Julien Ribon</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"",prefix:"an"},{uri:"http://zorba.io/modules/base64",prefix:"base64"},{uri:"http://zorba.io/modules/fetch",prefix:"fetch"},{uri:"http://www.zorba-xquery.com/modules/http-client",prefix:"http-client"},{uri:"http://www.28msec.com/modules/asynchronous-jobs",prefix:"job"},{uri:"http://www.28msec.com/modules/project",prefix:"project"},{uri:"http://zorba.io/modules/random",prefix:"rand"},{uri:"http://www.28msec.com/modules/http/request",prefix:"request"},{uri:"http://www.28msec.com/modules/store",prefix:"store"}],functions:[{isDocumented:!0,arity:2,name:"build-map-shuffle",qname:"job:build-map-shuffle",signature:"($input-collection as xs:string, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Builds an object describing an asynchronous job (map or shuffle).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This object can then be sent to the scheduler.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The $options parameter allows for the specification of properties for\n the shuffle job. Allowed options are:\n <ul>\n   <li><tt>kind</tt>: the kind of job ("map" or "shuffle").</li>\n   <li><tt>map-function</tt> (map jobs only): a function with any signature\n   (item()* to item()*),\n   and that is used to map the input collection to the output collection.</li>\n   <li><tt>shuffle-function</tt> (shuffle jobs only): a function taking an item\n   and returning an integer.\n   It is used to select the output collection to which each item is sent.</li>\n   <li><tt>output-collection as string</tt> (map jobs only): the name of the collection in\n     which the output of the executed query is stored. If not specified,\n     the result of the query will be stored in a collection withing the\n     MongoDB database associated with the project. The name of the\n     collection is randomly generated and starts with <tt>_28.temporary</tt>\n   </li>\n   <li><tt>output-collections as array</tt> (shuffle jobs only): an array with the names of the collections in\n     which the items of the input collections are shuffled. Compulsory.\n   </li>\n   <li><tt>chunk-info as object</tt>: an object containing the specification of a chunk\n     of the input collection. The shuffling will only occur on this chunk.\n     If not specified, the entire input collection will be mapped.\n   </li>\n   <li><tt>allow-streaming as boolean</tt> (map jobs only): a boolean indicating if calling the map function can\n     be distributed over partitions of the input collection. If false, the map function will\n     be called only once on the entire input collection. This might result\n     in a cache overflow if the number of items is too big. If true,\n     the input will be arbitrarily partitioned and the map function will be called for each\n     partition. The size of a partition is chosen in order to be smaller than the cache size.\n     The default is false.\n   </li>\n   <li><tt>dependencies as array</tt>: an array containing the ids of all asynchronous jobs that must\n     be completed before this job starts. This job will be hold pending until all these dependencies\n     are completed.\n   </li>\n </ul>\n </p>\n',summary:"<p>  Builds an object describing an asynchronous job (map or shuffle).</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"input-collection",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection that the job processes.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying above options for the asynchronous job.</div>'}],returns:{type:"object()",description:"the id of the scheduled job, which can be used to pull for the status and results."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if the type of a supplied option is incorrect.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0005 if the supplied function does not have a name.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0006 if the supplied function is in the local namespace.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0008 if the supplied input collection is not available.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"error",qname:"job:error",signature:"($id as xs:string) as object()?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the error object output by an asynchronous job, in case of a failed job.</p>\n',summary:"<p>  Returns the error object output by an asynchronous job, in case of a failed job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the asynchronous job to query.</div>'}],returns:{type:"object()?",description:"the error object output by the corresponding asynchronous job."},errors:[]},{isDocumented:!0,arity:1,name:"execute",qname:"job:execute",signature:"($query as xs:string) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Schedules an asynchronous job executing the given (public or private)\n query from your project.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The result of the query will be stored in a collection withing the\n MongoDB database associated with the project. The name of the collection\n is randomly generated and starts with <tt>_28.temporary</tt>.</p>\n',summary:"<p>  Schedules an asynchronous job executing the given (public or private)\n query from your project.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"query",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The path of the query to execute, which must begin with /public or /private. (examples: /public/query.xq, /private/query.jq).</div>'}],returns:{type:"xs:string",description:"The id of the scheduled job."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0003 if the supplied query path does not begin with /public or /private.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0004 if the supplied query path cannot be resolved.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"execute",qname:"job:execute",signature:"($query as xs:string, $options as object()?) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Schedules an asynchronous job executing the given (public or private)\n query from your project.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The $options parameter allows for the specification of properties for\n the asynchronously executed job. Allowed options are:\n <ul>\n   <li><tt>output-collection as string</tt>: the name of the collection in\n     which the output of the executed query is stored. If not specified,\n     the result of the query will be stored in a collection withing the\n     MongoDB database associated with the project. The name of the\n     collection is randomly generated and starts with <tt>_28.temporary</tt>\n   </li>\n </ul>\n </p>\n',summary:"<p>  Schedules an asynchronous job executing the given (public or private)\n query from your project.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"query",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The path of the query to execute, which must begin with /public or /private. (examples: /public/query.xq, /private/query.jq).</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying above options for the asynchronous job.</div>'}],returns:{type:"xs:string",description:"The id of the scheduled job."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if the type of a supplied option is incorrect.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0003 if the supplied query path does not begin with /public or /private.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0004 if the supplied query path cannot be resolved.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"function",qname:"job:function",signature:"($id as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the name of the map or shuffle function used by an asynchronous job.</p>\n',summary:"<p>  Returns the name of the map or shuffle function used by an asynchronous job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the asynchronous job to query.</div>'}],returns:{type:"xs:string?",description:"the name of the map or shuffle function of the corresponding asynchronous job."},errors:[]},{isDocumented:!0,arity:1,name:"get",qname:"job:get",signature:"($id as xs:string) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the asynchronous job associated with the supplied asynchronous job id,\n or the asynchronous jobs associated with the supplied parallel job id.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is internal and should only be used by the parallelism module.</p>\n',summary:"<p>  Returns the asynchronous job associated with the supplied asynchronous job id,\n or the asynchronous jobs associated with the supplied parallel job id.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the asynchronous or parallel job to query.</div>'}],returns:{type:"object()*",description:"the objects describing the asynchronous jobs."},errors:[]},{isDocumented:!0,arity:1,name:"input-collection",qname:"job:input-collection",signature:"($id as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the name of the input collection of a mapping asynchronous job.</p>\n',summary:"<p>  Returns the name of the input collection of a mapping asynchronous job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the asynchronous job to query.</div>'}],returns:{type:"xs:string?",description:"the name of the input collection of the corresponding asynchronous job."},errors:[]},{isDocumented:!0,arity:0,name:"jobs",qname:"job:jobs",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the ids of all jobs created by this project.</p>\n',summary:"<p>  Returns the ids of all jobs created by this project.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"object()*",description:"the sequence of the ids of all jobs created so far."},errors:[]},{isDocumented:!0,arity:1,name:"kind",qname:"job:kind",signature:"($id as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the kind of the asynchronous job.</p>\n',summary:"<p>  Returns the kind of the asynchronous job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the asynchronous job to query.</div>'}],returns:{type:"xs:string?",description:"the kind of the asynchronous job."},errors:[]},{isDocumented:!0,arity:2,name:"map",qname:"job:map",signature:"($input-collection as xs:string, $map-function as function (item()*) as item()*) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Schedules an asynchronous job mapping the input collection\n to an output collection with the specified function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The name of the output collection is randomly generated and\n starts with <tt>_28.temporary</tt>.</p>\n',summary:"<p>  Schedules an asynchronous job mapping the input collection\n to an output collection with the specified function.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"input-collection",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection that the job processes.</div>'},{name:"map-function",type:"function (item()*) as item()*",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The function which is run on the input collection\'s contents.</div>'}],returns:{type:"xs:string",description:"The id of the scheduled job, which can be used to pull for the status and results."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0005 if the supplied function does not have a name.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0006 if the supplied function is in the local namespace.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0008 if the supplied input collection does not exist.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"map",qname:"job:map",signature:"($input-collection as xs:string, $map-function as function (item()*) as item()*, $options as object()?) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Schedules an asynchronous job mapping the input collection\n to an output collection with the specified function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The $options parameter allows for the specification of properties for\n the map job. Allowed options are:\n <ul>\n   <li><tt>output-collection as string</tt>: the name of the collection in\n     which the output of the executed query is stored. If not specified,\n     the result of the query will be stored in a collection withing the\n     MongoDB database associated with the project. The name of the\n     collection is randomly generated and starts with <tt>_28.temporary</tt>\n   </li>\n   <li><tt>chunk-info as object</tt>: an object containing the specification of a chunk\n     of the input collection. The mapping will only occur on this chunk.\n     If not specified, the entire input collection will be mapped.\n   </li>\n   <li><tt>allow-streaming as boolean</tt>: a boolean indicating if calling the map function can\n     be distributed over partitions of the input collection. If false, the map function will\n     be called only once on the entire input collection. This might result\n     in a cache overflow if the number of items is too big. If true,\n     the input will be arbitrarily partitioned and the map function will be called for each\n     partition. The size of a partition is chosen in order to be smaller than the cache size.\n     The default is false.\n   </li>\n   <li><tt>dependencies as array</tt>: an array containing the ids of all asynchronous jobs that must\n     be completed before this job starts. This job will be hold pending until all these dependencies\n     are completed.\n   </li>\n </ul>\n </p>\n',summary:"<p>  Schedules an asynchronous job mapping the input collection\n to an output collection with the specified function.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"input-collection",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection that the job processes.</div>'},{name:"map-function",type:"function (item()*) as item()*",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The function which is run on the collection\'s contents.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying above options for the asynchronous job.</div>'}],returns:{type:"xs:string",description:"the id of the scheduled job, which can be used to pull for the status and results."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if the type of a supplied option is incorrect.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0005 if the supplied function does not have a name.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0006 if the supplied function is in the local namespace.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0008 if the supplied input collection does not exist.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"output-collection",qname:"job:output-collection",signature:"($id as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the name of the output collection of a mapping or executing asynchronous job.</p>\n',summary:"<p>  Returns the name of the output collection of a mapping or executing asynchronous job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the asynchronous job to query.</div>'}],returns:{type:"xs:string?",description:"the name of the output collection of the corresponding asynchronous job."},errors:[]},{isDocumented:!0,arity:1,name:"output-collections",qname:"job:output-collections",signature:"($id as xs:string) as xs:string*",description:" Returns the name of the output collections of a shuffle asynchronous job.\n",summary:"<p> Returns the name of the output collections of a shuffle asynchronous job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string*",description:"the name of the output collections of the corresponding asynchronous job."},errors:[]},{isDocumented:!0,arity:1,name:"properties",qname:"job:properties",signature:"($id as xs:string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the properties of an asynchronous job as an object with the following\n fields:</p>\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  <li><tt>accessed</tt>: the time at which the job was last accessed.</li>\n  <li><tt>completed</tt>: the time at which the job was completed.</li>\n  <li><tt>created</tt>: the time at which the job was created.</li>\n  <li><tt>lock-acquired</tt>: the time at which a processing lock was taken on the job.</li>\n  <li><tt>status</tt>: the status of the job. One of <tt>pending</tt>, <tt>in progress</tt>,\n  <tt>completed</tt>, <tt>failed</tt>, <tt>timed out</tt>.</li>\n  <li><tt>error</tt>: An object containing error information in case of failure.</li>\n </ul>\n',summary:"<p>  Returns the properties of an asynchronous job as an object with the following\n fields: \n  \n   accessed : the time at which the job was last accessed.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the asynchronous job to query.</div>'}],returns:{type:"object()",description:"the time at which the corresponding asynchronous job was last accessed."},errors:[]},{isDocumented:!0,arity:1,name:"query-name",qname:"job:query-name",signature:"($id as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the name of the query executed by an executing asynchronous job.</p>\n',summary:"<p>  Returns the name of the query executed by an executing asynchronous job.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"id",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the id of the asynchronous job to query.</div>'}],returns:{type:"xs:string?",description:"the name of the query executed by the corresponding asynchronous job."},errors:[]},{isDocumented:!0,arity:1,name:"schedule",qname:"job:schedule",signature:"($jobs as object()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sends jobs to the job queue.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is internal and should only be used by this and the parallelism module.</p>\n',summary:"<p>  Sends jobs to the job queue.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"jobs",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The job to send, as generated by job:build-map-shuffle().</div>'}],returns:{type:"object()*",description:"Objects containing the new ids."},errors:[]},{isDocumented:!0,arity:3,name:"shuffle",qname:"job:shuffle",signature:"($input-collection as xs:string, $shuffle-function as function (item()) as xs:integer, $options as object()?) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Schedules an asynchronous job shuffling the items of the input collections to output collections\n using the specified shuffle function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The $options parameter allows for the specification of properties for\n the shuffle job. Allowed options are:\n <ul>\n   <li><tt>output-collections as array</tt>: an array with the names of the collections in\n     which the items of the input collections are shuffled. Compulsory.\n   </li>\n   <li><tt>chunk-info as object</tt>: an object containing the specification of a chunk\n     of the input collection. The shuffling will only occur on this chunk.\n     If not specified, the entire input collection will be mapped.\n   </li>\n   <li><tt>dependencies as array</tt>: an array containing the ids of all asynchronous jobs that must\n     be completed before this job starts. This job will be hold pending until all these dependencies\n     are completed.\n   </li>\n </ul>\n </p>\n',summary:"<p>  Schedules an asynchronous job shuffling the items of the input collections to output collections\n using the specified shuffle function.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"input-collection",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection that the job processes.</div>'},{name:"shuffle-function",type:"function (item()) as xs:integer",occurrence:null,description:""},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying above options for the asynchronous job.</div>'}],returns:{type:"xs:string",description:"the id of the scheduled job, which can be used to pull for the status and results."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if the type of a supplied option is incorrect.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0005 if the supplied function does not have a name.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0006 if the supplied function is in the local namespace.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">job:JBDY0008 if the supplied input collection does not exist.</xqdoc:error>']}],variables:[]},"http://www.28msec.com/modules/datetime":{ns:"http://www.28msec.com/modules/datetime",description:" This modules contains function that operate on items of type date, time,\n dateTime, and duration.\n <p xmlns:xqdoc=\"http://www.xqdoc.org/1.0\">The module is always imported so you don't need to import it explicitly.\n Also, you don't need to fully qualify a function to invoke it.</p>\n",sees:[],authors:[],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.28msec.com/modules/datetime",prefix:"datetime"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"adjust-date-to-timezone",qname:"datetime:adjust-date-to-timezone",signature:"($arg as date?) as date?",description:" Adjusts a date value to the implicit timezone.\n",summary:"<p> Adjusts a date value to the implicit timezone.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"date",occurrence:"?",description:""}],returns:{type:"date?",description:'the date in the implicit timezone that contains the starting instant of the supplied date. For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-adjust-date-to-timezone">adjust-date-to-timezone</a>.'},errors:[]},{isDocumented:!0,arity:2,name:"adjust-date-to-timezone",qname:"datetime:adjust-date-to-timezone",signature:"($arg as date?, $timezone as dayTimeDuration?) as date?",description:" Adjusts a date value to a specific timezone, or to no timezone at all.\n",summary:"<p> Adjusts a date value to a specific timezone, or to no timezone at all.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"date",occurrence:"?",description:""},{name:"timezone",type:"dayTimeDuration",occurrence:"?",description:""}],returns:{type:"date?",description:'the date in the target timezone that contains the starting instant of the supplied date. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>adjust-date-to-timezone(date("2002-03-07"), dayTimeDuration("-PT10H"))</code> returns <code>date("2002-03-06-10:00")</code>.</li> <li><code>adjust-date-to-timezone(date("2002-03-07-07:00"), ())</code> returns <code>date("2002-03-07")</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-adjust-date-to-timezone">adjust-date-to-timezone</a>'},errors:[]},{isDocumented:!0,arity:1,name:"adjust-dateTime-to-timezone",qname:"datetime:adjust-dateTime-to-timezone",signature:"($arg as dateTime?) as dateTime",description:" Adjusts a dateTime value to the implicit timezone.\n",summary:"<p> Adjusts a dateTime value to the implicit timezone.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"dateTime",occurrence:"?",description:""}],returns:{type:"dateTime",description:'the dateTime in the implicit timezone. For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-adjust-dateTime-to-timezone">adjust-dateTime-to-timezone</a>'},errors:[]},{isDocumented:!0,arity:2,name:"adjust-dateTime-to-timezone",qname:"datetime:adjust-dateTime-to-timezone",signature:"($arg as dateTime?, $timezone as dayTimeDuration?) as dateTime",description:" Adjusts a dateTime value to the specified timezone, or to no timezone at all.\n",summary:"<p> Adjusts a dateTime value to the specified timezone, or to no timezone at all.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"dateTime",occurrence:"?",description:""},{name:"timezone",type:"dayTimeDuration",occurrence:"?",description:""}],returns:{type:"dateTime",description:"the dateTime in the specified timezone. <ul xmlns:xqdoc=\"http://www.xqdoc.org/1.0\"> <li><code>adjust-dateTime-to-timezone(dateTime('2002-03-07T10:00:00-07:00'), dayTimeDuration(\"-PT10H\"))</code> returns <code>dateTime('2002-03-07T07:00:00-10:00')</code>.</li> <li><code>adjust-dateTime-to-timezone(dateTime('2002-03-07T10:00:00'), ())</code> returns <code>dateTime('2002-03-07T10:00:00')</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc=\"http://www.xqdoc.org/1.0\" href=\"http://www.w3.org/TR/xpath-functions-30/#func-adjust-dateTime-to-timezone\">adjust-dateTime-to-timezone</a>"},errors:[]},{isDocumented:!0,arity:1,name:"adjust-time-to-timezone",qname:"datetime:adjust-time-to-timezone",signature:"($arg as time?) as time?",description:" Adjusts a time value to an implicit timezone.\n",summary:"<p> Adjusts a time value to an implicit timezone.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"time",occurrence:"?",description:""}],returns:{type:"time?",description:'the time in the implicit timezone. For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-adjust-time-to-timezone">adjust-time-to-timezone</a>'},errors:[]},{isDocumented:!0,arity:2,name:"adjust-time-to-timezone",qname:"datetime:adjust-time-to-timezone",signature:"($arg as time?, $timezone as dayTimeDuration?) as time?",description:" Adjusts a time value to a specific timezone, or to no timezone at all.\n",summary:"<p> Adjusts a time value to a specific timezone, or to no timezone at all.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"time",occurrence:"?",description:""},{name:"timezone",type:"dayTimeDuration",occurrence:"?",description:""}],returns:{type:"time?",description:'the time in the specified timezone. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>adjust-time-to-timezone(time("10:00:00"), dayTimeDuration("-PT10H"))</code> returns <code>time("07:00:00-10:00")</code>.</li> <li><code>adjust-time-to-timezone(time("10:00:00-07:00"), ())</code> returns <code>time("10:00:00")</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-adjust-time-to-timezone">adjust-time-to-timezone</a>'},errors:[]},{isDocumented:!0,arity:0,name:"current-date",qname:"datetime:current-date",signature:"() as date external",description:' Returns the current date.\n For a detailed description of the semantics of this function, please see\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-current-date">current-date</a>\n',summary:"<p> Returns the current date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"date",description:""},errors:[]},{isDocumented:!0,arity:0,name:"current-dateTime",qname:"datetime:current-dateTime",signature:"() as dateTimeStamp external",description:' Returns the current dateTime.\n For a detailed description of the semantics of this function, please see\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-current-dateTime">current-dateTime</a>\n',summary:"<p> Returns the current dateTime.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"dateTimeStamp",description:""},errors:[]},{isDocumented:!0,arity:0,name:"current-time",qname:"datetime:current-time",signature:"() as time external",description:' Returns the current time.\n For a detailed description of the semantics of this function, please see\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-current-time">current-time</a>\n',summary:"<p> Returns the current time.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"time",description:""},errors:[]},{isDocumented:!0,arity:2,name:"dateTime",qname:"datetime:dateTime",signature:"($arg1 as date?, $arg2 as time?) as dateTime?",description:" Returns a dateTime value created by combining a date and a time.\n",summary:"<p> Returns a dateTime value created by combining a date and a time.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"date",occurrence:"?",description:""},{name:"arg2",type:"time",occurrence:"?",description:""}],returns:{type:"dateTime?",description:'the dateTime value created by combinding the given date and time. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>dateTime(date("1999-12-31"), time("12:00:00"))</code> returns <code>dateTime("1999-12-31T12:00:00")</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-dateTime">dateTime</a>'},errors:[]},{isDocumented:!0,arity:1,name:"day-from-date",qname:"datetime:day-from-date",signature:"($arg as date?) as integer?",description:" Returns the day component of a date.\n",summary:"<p> Returns the day component of a date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"date",occurrence:"?",description:""}],returns:{type:"integer?",description:'the day component of the given date. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>day-from-date(date("1999-05-31-05:00"))</code> returns <code>31</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-day-from-date">day-from-date</a>'},errors:[]},{isDocumented:!0,arity:1,name:"day-from-dateTime",qname:"datetime:day-from-dateTime",signature:"($arg as dateTime?) as integer?",description:" Returns the day component of a dateTime.\n",summary:"<p> Returns the day component of a dateTime.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"dateTime",occurrence:"?",description:""}],returns:{type:"integer?",description:'the day component of the given dateTime. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>day-from-dateTime(dateTime("1999-12-31T20:00:00-05:00"))</code> returns <code>31</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-day-from-dateTime">day-from-dateTime</a>'},errors:[]},{isDocumented:!0,arity:1,name:"days-from-duration",qname:"datetime:days-from-duration",signature:"($arg as duration?) as integer?",description:" Returns the number of days in a duration.\n",summary:"<p> Returns the number of days in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"duration",occurrence:"?",description:""}],returns:{type:"integer?",description:'the number of days in the given duration. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>days-from-duration(dayTimeDuration("P3DT55H"))</code> returns <code>5</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-days-from-duration">days-from-duration</a>'},errors:[]},{isDocumented:!0,arity:2,name:"format-date",qname:"datetime:format-date",signature:"($value as date?, $picture as string) as string?",description:" Returns a string containing a date value formatted for display.\n",summary:"<p> Returns a string containing a date value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"date",occurrence:"?",description:""},{name:"picture",type:"string",occurrence:null,description:""}],returns:{type:"string?",description:'the string formatted according to the given picture. The following examples assume <code xmlns:xqdoc="http://www.xqdoc.org/1.0">let $d := date("2002-12-31")</code> and the Gregorian calendar as the default calendar. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>format-date($d, "[Y0001]-[M01]-[D01]")</code> returns <code>2002-12-31</code>.</li> <li><code>format-date($d, "[D1] [MI] [Y]")</code> returns <code>31 XII 2002</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-format-date">format-date</a>'},errors:[]},{isDocumented:!0,arity:5,name:"format-date",qname:"datetime:format-date",signature:"($value as date?, $picture as string, $language as string?, $calendar as string?, $place as string?) as string?",description:" Returns a string containing a date value formatted for display.\n",summary:"<p> Returns a string containing a date value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"date",occurrence:"?",description:""},{name:"picture",type:"string",occurrence:null,description:""},{name:"language",type:"string",occurrence:"?",description:""},{name:"calendar",type:"string",occurrence:"?",description:""},{name:"place",type:"string",occurrence:"?",description:""}],returns:{type:"string?",description:'the string formatted according to the given picture. The following examples assume <code xmlns:xqdoc="http://www.xqdoc.org/1.0">let $d := date("2002-12-31")</code> and the Gregorian calendar as the default calendar. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>format-date($d, "[YWw]", "en", (), ())</code> returns <code>Two Thousand and Three</code>.</li> <li><code>format-date($d, "[D] [MNn], [Y]", "de", (), ())</code> returns <code>31 Dezember, 2002</code>.</li> <li><code>format-date($d, "[D\\u0E51] [Mn] [Y\\u0E51]", "th", "BE", ())</code> returns <code>\u0e53\u0e51 \u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21 \u0e52\u0e50\u0e50\u0e52</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-format-date">format-date</a>'},errors:[]},{isDocumented:!0,arity:2,name:"format-dateTime",qname:"datetime:format-dateTime",signature:"($value as dateTime?, $picture as string) as string?",description:" Returns a string containing a dateTime value formatted for display.\n",summary:"<p> Returns a string containing a dateTime value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"dateTime",occurrence:"?",description:""},{name:"picture",type:"string",occurrence:null,description:""}],returns:{type:"string?",description:'the string formatted according to the given picture. The following examples assume <code xmlns:xqdoc="http://www.xqdoc.org/1.0">let $dt := dateTime("2002-12-31T15:58:45")</code> and the Gregorian calendar as the default calendar. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>format-dateTime($dt, "[h].[m01][Pn] on [FNn], [D1o] [MNn]")</code> returns <code>3.58pm on Tuesday, 31st December</code>.</li> <li><code>format-dateTime($dt, "[M01]/[D01]/[Y0001] at [H01]:[m01]:[s01]")</code> returns <code>12/31/2002 at 15:58:45</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-format-dateTime">format-dateTime</a>'},errors:[]},{isDocumented:!0,arity:5,name:"format-dateTime",qname:"datetime:format-dateTime",signature:"($value as dateTime?, $picture as string, $language as string?, $calendar as string?, $place as string?) as string?",description:" Returns a string containing a dateTime value formatted for display.\n",summary:"<p> Returns a string containing a dateTime value formatted for display.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"dateTime",occurrence:"?",description:""},{name:"picture",type:"string",occurrence:null,description:""},{name:"language",type:"string",occurrence:"?",description:""},{name:"calendar",type:"string",occurrence:"?",description:""},{name:"place",type:"string",occurrence:"?",description:""}],returns:{type:"string?",description:'the string formatted according to the given picture. For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-format-dateTime">format-dateTime</a>'},errors:[]},{isDocumented:!0,arity:1,name:"hours-from-dateTime",qname:"datetime:hours-from-dateTime",signature:"($arg as dateTime?) as integer?",description:" Returns the hours component of a dateTime.\n",summary:"<p> Returns the hours component of a dateTime.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"dateTime",occurrence:"?",description:""}],returns:{type:"integer?",description:'the hours component of the given dateTime. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>hours-from-dateTime(dateTime("1999-12-31T21:20:00-05:00"))</code> returns <code>21</code>.</li> <li><code>hours-from-dateTime(adjust-dateTime-to-timezone(dateTime("1999-12-31T21:20:00-05:00"), dayTimeDuration("PT0S")))</code> returns <code>2</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-hours-from-time">hours-from-dateTime</a>'},errors:[]},{isDocumented:!0,arity:1,name:"hours-from-duration",qname:"datetime:hours-from-duration",signature:"($arg as duration?) as integer?",description:" Returns the number of hours in a duration.\n",summary:"<p> Returns the number of hours in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"duration",occurrence:"?",description:""}],returns:{type:"integer?",description:'the number of hours in the given duration. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>hours-from-duration(dayTimeDuration("P3DT10H"))</code> returns <code>10</code>.</li> <li><code>hours-from-duration(dayTimeDuration("-P3DT10H"))</code> returns <code>-10</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-hours-from-duration">hours-from-duration</a>'},errors:[]},{isDocumented:!0,arity:1,name:"hours-from-time",qname:"datetime:hours-from-time",signature:"($arg as time?) as integer?",description:" Returns the hours component of a time.\n",summary:"<p> Returns the hours component of a time.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"time",occurrence:"?",description:""}],returns:{type:"integer?",description:'the hours component of the given time. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>hours-from-time(time("11:23:00"))</code> returns <code>11</code>.</li> <li><code>hours-from-time(time("24:00:00"))</code> returns <code>0</code>.</li> <li><code>hours-from-time(adjust-time-to-timezone(time("01:23:00+05:00"), dayTimeDuration("PT0S")))</code> returns <code>20</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-hours-from-time">hours-from-time</a>'},errors:[]},{isDocumented:!0,arity:0,name:"implicit-timezone",qname:"datetime:implicit-timezone",signature:"() as dayTimeDuration",description:" Returns the value of the implicit timezone property set in the platform.\n",summary:"<p> Returns the value of the implicit timezone property set in the platform.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"dayTimeDuration",description:'the implicit timezone property. For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-implicit-timezone">implicit-timezone</a>'},errors:[]},{isDocumented:!0,arity:1,name:"minutes-from-dateTime",qname:"datetime:minutes-from-dateTime",signature:"($arg as dateTime?) as integer?",description:" Returns the minute component of a dateTime.\n",summary:"<p> Returns the minute component of a dateTime.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"dateTime",occurrence:"?",description:""}],returns:{type:"integer?",description:'the minute component of the given dateTime. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>minutes-from-dateTime(dateTime("1999-05-31T13:20:00-05:00"))</code> returns <code>20</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-minutes-from-dateTime">minutes-from-dateTime</a>'},errors:[]},{isDocumented:!0,arity:1,name:"minutes-from-duration",qname:"datetime:minutes-from-duration",signature:"($arg as duration?) as integer?",description:" Returns the number of minutes in a duration.\n",summary:"<p> Returns the number of minutes in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"duration",occurrence:"?",description:""}],returns:{type:"integer?",description:'the number of minutes of the given duration. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>minutes-from-duration(dayTimeDuration("P3DT10H"))</code> returns <code>0</code>.</li> <li><code>minutes-from-duration(dayTimeDuration("-P5DT12H30M"))</code> returns <code>-30</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-minutes-from-duration">minutes-from-duration</a>'},errors:[]},{isDocumented:!0,arity:1,name:"minutes-from-time",qname:"datetime:minutes-from-time",signature:"($arg as time?) as integer?",description:" Returns the minutes component of a time.\n",summary:"<p> Returns the minutes component of a time.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"time",occurrence:"?",description:""}],returns:{type:"integer?",description:'the minutes component of the given time. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>minutes-from-time(time("13:00:00Z"))</code> returns <code>0</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-minutes-from-time">minutes-from-time</a>'},errors:[]},{isDocumented:!0,arity:1,name:"month-from-date",qname:"datetime:month-from-date",signature:"($arg as date?) as integer?",description:" Returns the month component of a date.\n",summary:"<p> Returns the month component of a date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"date",occurrence:"?",description:""}],returns:{type:"integer?",description:'the month component of the given date. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>month-from-date(date("1999-05-31-05:00"))</code> returns <code>5</code>.</li> <li><code>month-from-date(date("2000-01-01+05:00"))</code> returns <code>1</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-month-from-date">month-from-date</a>'},errors:[]},{isDocumented:!0,arity:1,name:"month-from-dateTime",qname:"datetime:month-from-dateTime",signature:"($arg as dateTime?) as integer?",description:" Returns the month component of a dateTime.\n",summary:"<p> Returns the month component of a dateTime.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"dateTime",occurrence:"?",description:""}],returns:{type:"integer?",description:'the month component of the given dateTime. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>month-from-dateTime(dateTime("1999-05-31T21:20:00-05:00"))</code> returns <code>5</code>.</li> <li><code>month-from-dateTime(dateTime("2000-01-01T11:05:00+05:00"))</code> returns <code>1</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-month-from-dateTime">month-from-dateTime</a>'},errors:[]},{isDocumented:!0,arity:1,name:"months-from-duration",qname:"datetime:months-from-duration",signature:"($arg as duration?) as integer?",description:" Returns the number of months in a duration.\n",summary:"<p> Returns the number of months in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"duration",occurrence:"?",description:""}],returns:{type:"integer?",description:'the number of months in the given duration. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>months-from-duration(yearMonthDuration("P20Y15M"))</code> returns <code>3</code>.</li> <li><code>months-from-duration(yearMonthDuration("-P20Y18M"))</code> returns <code>6</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-months-from-duration">months-from-duration</a>'},errors:[]},{isDocumented:!0,arity:1,name:"seconds-from-dateTime",qname:"datetime:seconds-from-dateTime",signature:"($arg as dateTime?) as decimal?",description:" Returns the seconds component of a dateTime.\n",summary:"<p> Returns the seconds component of a dateTime.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"dateTime",occurrence:"?",description:""}],returns:{type:"decimal?",description:'the seconds component of the given dateTime. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>seconds-from-dateTime(dateTime("1999-05-31T13:20:00-05:00"))</code> returns <code>0</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-seconds-from-dateTime">seconds-from-dateTime</a>'},errors:[]},{isDocumented:!0,arity:1,name:"seconds-from-duration",qname:"datetime:seconds-from-duration",signature:"($arg as duration?) as decimal?",description:" Returns the number of seconds in a duration.\n",summary:"<p> Returns the number of seconds in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"duration",occurrence:"?",description:""}],returns:{type:"decimal?",description:'the number of seconds in the given duration. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>seconds-from-duration(dayTimeDuration("P3DT10H12.5S"))</code> returns <code>12.5</code>.</li> <li><code>seconds-from-duration(dayTimeDuration("-PT256S"))</code> returns <code>-16.0</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-seconds-from-duration">seconds-from-duration</a>'},errors:[]},{isDocumented:!0,arity:1,name:"seconds-from-time",qname:"datetime:seconds-from-time",signature:"($arg as time?) as decimal?",description:" Returns the seconds component of a time.\n",summary:"<p> Returns the seconds component of a time.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"time",occurrence:"?",description:""}],returns:{type:"decimal?",description:'the seconds component of the given time. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>seconds-from-time(time("13:20:10.5"))</code> returns <code>10.5</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-seconds-from-time">seconds-from-time</a>'},errors:[]},{isDocumented:!0,arity:1,name:"timezone-from-date",qname:"datetime:timezone-from-date",signature:"($arg as date?) as dayTimeDuration?",description:" Returns the timezone component of a date.\n",summary:"<p> Returns the timezone component of a date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"date",occurrence:"?",description:""}],returns:{type:"dayTimeDuration?",description:'the timezone component of the given date. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>timezone-from-date(date("1999-05-31-05:00"))</code> returns <code>dayTimeDuration("-PT5H")</code>.</li> <li><code>timezone-from-date(date("2000-06-12Z"))</code> returns <code>dayTimeDuration("PT0S")</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-timezone-from-date">timezone-from-date</a>'},errors:[]},{isDocumented:!0,arity:1,name:"timezone-from-dateTime",qname:"datetime:timezone-from-dateTime",signature:"($arg as dateTime?) as dayTimeDuration?",description:" Returns the timezone component of a dateTime.\n",summary:"<p> Returns the timezone component of a dateTime.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"dateTime",occurrence:"?",description:""}],returns:{type:"dayTimeDuration?",description:'the timezone component of the given dateTime. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>timezone-from-dateTime(dateTime("1999-05-31T13:20:00-05:00"))</code> returns <code>dayTimeDuration("-PT5H")</code>.</li> <li><code>timezone-from-dateTime(dateTime("2000-06-12T13:20:00Z"))</code> returns <code>dayTimeDuration("PT0S")</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-timezone-from-dateTime">timezone-from-dateTime</a>'},errors:[]},{isDocumented:!0,arity:1,name:"timezone-from-time",qname:"datetime:timezone-from-time",signature:"($arg as time?) as dayTimeDuration?",description:" Returns the timezone component of a time.\n",summary:"<p> Returns the timezone component of a time.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"time",occurrence:"?",description:""}],returns:{type:"dayTimeDuration?",description:'the timezone component of the given time. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>timezone-from-time(time("13:20:00-05:00"))</code> returns <code>dayTimeDuration("-PT5H")</code>.</li> <li><code>timezone-from-time(time("13:20:00"))</code> returns <code>()</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-timezone-from-time">timezone-from-time</a>'},errors:[]},{isDocumented:!0,arity:1,name:"year-from-date",qname:"datetime:year-from-date",signature:"($arg as date?) as integer?",description:" Returns the year component of a date.\n",summary:"<p> Returns the year component of a date.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"date",occurrence:"?",description:""}],returns:{type:"integer?",description:'the year component of the given date. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>year-from-date(date("2000-01-01+05:00"))</code> returns <code>2000</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-year-from-date">year-from-date</a>'},errors:[]},{isDocumented:!0,arity:1,name:"year-from-dateTime",qname:"datetime:year-from-dateTime",signature:"($arg as dateTime?) as integer?",description:" Returns the year component of a dateTime.\n",summary:"<p> Returns the year component of a dateTime.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"dateTime",occurrence:"?",description:""}],returns:{type:"integer?",description:'the year component of the given dateTime. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>year-from-dateTime(dateTime("1999-05-31T13:20:00-05:00"))</code> returns <code>1999</code>.</li> <li><code>year-from-dateTime(dateTime("1999-12-31T24:00:00"))</code> returns <code>2000</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-year-from-dateTime">year-from-dateTime</a>'},errors:[]},{isDocumented:!0,arity:1,name:"years-from-duration",qname:"datetime:years-from-duration",signature:"($arg as duration?) as integer?",description:" Returns the number of years in a duration.\n",summary:"<p> Returns the number of years in a duration.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"duration",occurrence:"?",description:""}],returns:{type:"integer?",description:'the number of years in the given duration. <ul xmlns:xqdoc="http://www.xqdoc.org/1.0"> <li><code>years-from-duration(yearMonthDuration("P20Y15M"))</code> returns <code>21</code>.</li> <li><code>years-from-duration(yearMonthDuration("-P15M"))</code> returns <code>-1</code>.</li> </ul> For a detailed description of the semantics of this function, please see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-functions-30/#func-years-from-duration">years-from-duration</a>'},errors:[]}],variables:[]},"http://api.28.io/jdbc":{ns:"http://api.28.io/jdbc",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/jdbc",prefix:"api"},{uri:"http://www.28msec.com/modules/jdbc",prefix:"jdbc"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://www.28msec.com/modules/http/response",prefix:"res"},{uri:"http://www.28msec.com/modules/store",prefix:"store"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!1,arity:0,name:"dispatch",qname:"api:dispatch",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"import",qname:"api:import",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"tables",qname:"api:tables",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]}],variables:[]},"http://zorba.io/modules/excel/information":{ns:"http://zorba.io/modules/excel/information",description:" This is a library module offering the same set of functions\n defined by Microsoft Excel, under Information Functions.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://office.microsoft.com/en-us/excel/CH062528261033.aspx" target="_blank">Excel Documentation: Information Functions</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Sorin Nasoi</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/modules/excel/information",prefix:"excel-information"},{uri:"http://zorba.io/modules/excel/math",prefix:"excel-math"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"is-blank",qname:"excel-information:is-blank",signature:"($value as xs:anyAtomicType?) as xs:boolean",description:" Test if the passed argument is empty of not.\n",summary:"<p> Test if the passed argument is empty of not.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value.</div>'}],returns:{type:"xs:boolean",description:"If the value of $arg is the empty sequence, the function returns true, otherwise the function returns false."},errors:[]},{isDocumented:!0,arity:1,name:"is-even",qname:"excel-information:is-even",signature:"($value as xs:anyAtomicType?) as xs:boolean",description:" Test is a number is even.\n",summary:"<p> Test is a number is even.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value.</div>'}],returns:{type:"xs:boolean",description:"TRUE if number is even, FALSE if number is odd."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value is not a number.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-odd",qname:"excel-information:is-odd",signature:"($value as xs:anyAtomicType?) as xs:boolean",description:" Test is a number is odd.\n",summary:"<p> Test is a number is odd.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value.</div>'}],returns:{type:"xs:boolean",description:"TRUE if number is odd, FALSE if number is even."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value if provided value is not a number.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"islogical",qname:"excel-information:islogical",signature:"($value as xs:anyAtomicType?) as xs:boolean",description:" Tests if the passed $value is a logical value.\n",summary:"<p> Tests if the passed $value is a logical value.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value.</div>'}],returns:{type:"xs:boolean",description:"TRUE if $value refers to a logical value."},errors:[]},{isDocumented:!0,arity:1,name:"isnumber",qname:"excel-information:isnumber",signature:"($value as xs:anyAtomicType?) as xs:boolean",description:" Tests if the passed $value is a number.\n",summary:"<p> Tests if the passed $value is a number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value.</div>'}],returns:{type:"xs:boolean",description:"TRUE if $value refers to a number."},errors:[]},{isDocumented:!0,arity:1,name:"istext",qname:"excel-information:istext",signature:"($value as xs:anyAtomicType?) as xs:boolean",description:" Tests if the passed $value is a string.\n",summary:"<p> Tests if the passed $value is a string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value.</div>'}],returns:{type:"xs:boolean",description:"TRUE if $value refers to text."},errors:[]},{isDocumented:!0,arity:1,name:"n",qname:"excel-information:n",signature:"($value as xs:anyAtomicType?) as xs:anyAtomicType",description:" Converts a $value to a number.\n",summary:"<p> Converts a $value to a number.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value.</div>'}],returns:{type:"xs:anyAtomicType",description:"A $value converted to a number."},errors:[]},{isDocumented:!0,arity:0,name:"na",qname:"excel-information:na",signature:"() as xs:anyAtomicType",description:" Raises the error value #N/A.\n",summary:"<p> Raises the error value #N/A.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyAtomicType",description:'The error value #N/A. #N/A is the error value that means "no value is available."'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:NA the purpose of this function is to raise this error</xqdoc:error>']}],variables:[]},"http://www.zorba-xquery.com/modules/image/animation":{ns:"http://www.zorba-xquery.com/modules/image/animation",description:" This module provides functions to create animated GIF images.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Daniel Thomas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/image/animation",prefix:"anim"},{uri:"http://www.zorba-xquery.com/modules/image/error",prefix:"ierr"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:3,name:"create-animated-gif",qname:"anim:create-animated-gif",signature:"($images as xs:base64Binary+, $delay as xs:unsignedInt, $iterations as xs:unsignedInt) as xs:base64Binary external",description:" Creates an animated GIF image.\n The resulting animated GIF shows the passed images consecutively.\n It has the same width and height as the first passed image.\n",summary:"<p> Creates an animated GIF image.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"images",type:"xs:base64Binary",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image sequence</div>'},{name:"delay",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the hundredths of seconds an image is shown</div>'},{name:"iterations",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the amount of times all images are shown. 0 for infinite.</div>'}],returns:{type:"xs:base64Binary",description:"the animated GIF"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 one of the passed images is invalid.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"create-morphed-gif",qname:"anim:create-morphed-gif",signature:"($images as xs:base64Binary+, $delay as xs:unsignedInt, $iterations as xs:unsignedInt, $nr-of-morph-images as xs:unsignedInt) as xs:base64Binary external",description:" Creates an animated GIF image with morph effect.\n The resulting animated GIF shows the passed images consecutively with morph effect between the changes.\n It has the same width and height as the first passed image.\n",summary:"<p> Creates an animated GIF image with morph effect.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"images",type:"xs:base64Binary",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the image sequence</div>'},{name:"delay",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the hundredths of seconds an image is shown</div>'},{name:"iterations",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the amount of times all images are shown. 0 for infinite.</div>'},{name:"nr-of-morph-images",type:"xs:unsignedInt",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of additionally added images to create the morph effect between two passed images.</div>'}],returns:{type:"xs:base64Binary",description:"the animated GIF"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ierr:IM001 one of the passed images is invalid.</xqdoc:error>']}],variables:[]},"http://28.io/modules/error":{ns:"http://28.io/modules/error",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Applications written with Sausalito use this default error module\n if an error happens inside a Sausalito project.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An error can occur during the run time of a Sausalito project on one\n of the following cases:</p>\n <ol xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>If the XQuery code raises a dynamic error that is not caught in a\n     try-catch block.</li>\n   <li>If the given XQuery program is syntactically incorrect or contains\n     other static errors.</li>\n   <li>If an explicit call to fn:error() was made and the error is not\n     caught in a try-catch block.</li>\n   <li>If a request is made to a module or a function which does\n     not exist.</li>\n   <li>If any other unexpected error happens during the processing of\n     the request.</li>\n </ol>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://28.io/modules/error",prefix:"err"},{uri:"http://www.28msec.com/modules/http/request",prefix:"request"},{uri:"http://www.28msec.com/modules/http/response",prefix:"resp"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:4,name:"handle",qname:"err:handle",signature:"($code as xs:QName, $description as xs:string?, $value as item()*, $stack) as item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This is the default function that is called if an error happens.\n The default can be overridden by adding an error.xq library module\n into the Sausalito project. This module needs to declare a function\n with the same signature as the err:handle function in this module.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The value returned by this function is sent to the client. If the\n default is overridden, the implementation is free to define all\n parameters of the response (e.g. set the corresponding HTTP status\n code or an arbitrary header).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the default is used, the status code is 500 if the $code QName\n is not equal to one of the status code QNames declared in HTTP module.\n Otherwise, the corresponding status code is set.</p>\n',summary:"<p>  This is the default function that is called if an error happens.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"code",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the error code that triggered the problem as a QName</div>'},{name:"description",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a description of the error</div>'},{name:"value",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a potentially empty list of items that were involved in causing the error</div>'},{name:"stack",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the stacktrace leading to the error as an element. For example, <tt> &lt;stack&gt; &lt;call ns="http://www.example.com/" localName="my-function" arity="3"/&gt; &lt;/stack&gt; </tt></div>'}],returns:{type:"item()*",description:"content of the response message"},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/internal-debug":{ns:"http://www.zorba-xquery.com/modules/internal-debug",description:" This internal module provides functions for testing error handling and\n internal function caching.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/internal-debug",prefix:"debug"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"cpp-error",qname:"debug:cpp-error",signature:"() as empty-sequence() external",description:" Raises a c++ exception.\n",summary:"<p> Raises a c++ exception.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"empty-sequence()",description:"empty sequence"},errors:[]},{isDocumented:!0,arity:0,name:"cpp-exit",qname:"debug:cpp-exit",signature:"() as empty-sequence() external",description:" C++ exit is invoked.\n",summary:"<p> C++ exit is invoked.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"empty-sequence()",description:"empty sequence"},errors:[]},{isDocumented:!0,arity:0,name:"user-error-no-location",qname:"debug:user-error-no-location",signature:"() as empty-sequence() external",description:" Raises a user error without query location.\n",summary:"<p> Raises a user error without query location.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"empty-sequence()",description:"empty sequence"},errors:[]},{isDocumented:!0,arity:0,name:"user-error",qname:"debug:user-error",signature:"() as empty-sequence() external",description:" Raises a user error.\n",summary:"<p> Raises a user error.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"empty-sequence()",description:"empty sequence"},errors:[]},{isDocumented:!0,arity:0,name:"zorba-error",qname:"debug:zorba-error",signature:"() as empty-sequence() external",description:" Raises a zorba error.\n",summary:"<p> Raises a zorba error.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"empty-sequence()",description:"empty sequence"},errors:[]}],variables:[]},"http://zorba.io/modules/reflection":{ns:"http://zorba.io/modules/reflection",description:" This module provides functions to dynamically invoke functions or main modules,\n respectively. Each of the functions (invoke or eval) come in four variants depending\n whether the expression being invoked is simple, nondeterministic, updating,\n or sequential.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Nicolae Brinza</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://zorba.io/modules/reflection",prefix:"reflection"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"eval-n",qname:"reflection:eval-n",signature:"($query as xs:string) as item()* external",description:" See documentation of reflection:eval() except the main module that is to\n be executed may be nondeterministc.\n",summary:"<p> See documentation of reflection:eval() except the main module that is to\n be executed may be nondeterministc.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"query",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query string to be evaluated</div>'}],returns:{type:"item()*",description:"the result of evaluating the query"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">whatever error the evaluated XQuery may return</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQST0031 If the XQuery version of the inner program is greater than the version of the outer program.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"eval-s",qname:"reflection:eval-s",signature:"($query as xs:string) as item()* external",description:" See documentation of reflection:eval() except the main module that is to\n be executed may be sequential, i.e. may have side-effects.\n",summary:"<p> See documentation of reflection:eval() except the main module that is to\n be executed may be sequential, i.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"query",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query string to be evaluated</div>'}],returns:{type:"item()*",description:"the result of evaluating the query (the result is not supposed to contain any PUL)."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">whatever error the evaluated XQuery may return</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQST0031 If the XQuery version of the inner program is greater than the version of the outer program.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"eval-u",qname:"reflection:eval-u",signature:"($query as xs:string) external",description:" See documentation of reflection:eval() except the main module that is to\n be executed may be updating, i.e. return a pending update list.\n",summary:"<p> See documentation of reflection:eval() except the main module that is to\n be executed may be updating, i.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!0,parameters:[{name:"query",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query string to be evaluated</div>'}],returns:{type:null,description:"the PUL resulting from evaluating the query"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">whatever error the evaluated XQuery may return</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQST0031 If the XQuery version of the inner program is greater than the version of the outer program.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"eval",qname:"reflection:eval",signature:"($query as xs:string) as item()* external",description:' The purpose of this function is to (dynamically) execute an XQuery program\n from inside another XQuery program.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The XQuery program that invokes the\n eval function will be referred to as the "outer" program and the XQuery\n program that is executed by the eval invocation will be referred to as\n the "inner" program. The function is given as a string argument.\n Typically, the outer program constructs this string dynamically,\n e.g., based on data extracted from documents and/or the values of\n external variables. The eval function treats this string as\n an XQuery main module. That is, it parses the string, compiles the\n resulting parse tree, executes the resulting execution plan, and finally\n returns the result or error (if any) to the outer program.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The given XQuery program needs to be a valid according to XQuery\'s\n MainModule production (see <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xquery/#doc-xquery-MainModule">\n http://www.w3.org/TR/xquery/#doc-xquery-MainModule</a>. Please note\n that the inner pogram must at least have the XQuery version of the\n outer program [err:XQST0031].<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The inner program "inherits" the static and dynamic context of the outer\n program. Specifically, evaluation of the inner program is done in static and\n dynamic contextes that are initialized as copies of the static and dynamic\n contextes of the outer program at the place where the eval invocation appears\n at. This means that, for example, all variables that are in-scope at the place\n where the eval function is invoked from, are also in-scope inside the inner\n program and can be referenced there without having to be re-declared. On the other\n hand, declarations that appear in the prolog of the inner main module or are\n imported by the inner main module from library modules, hide their corresponding\n inherited declarations. For example, if the inner main module declares\n a variable or function with the same name as an inherited variable or function,\n the inner variable/function hides the inherited one.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n If the inner program declares an external variable with the same name as an\n inherited variable, the value of the inherited variable is used to initialize\n the inner external variable. If, however, an inner external variable has no\n default initializer and no corresponding inherited variable, it will remain\n uninitialized, causing the inner program to raise an error when executed.\n',summary:"<p> The purpose of this function is to (dynamically) execute an XQuery program\n from inside another XQuery program.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query string to be evaluated</div>'}],returns:{type:"item()*",description:"the result of evaluating the query"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">whatever error the evaluated XQuery may return.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQST0031 If the XQuery version of the inner program is greater than the version of the outer program.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"invoke-n",qname:"reflection:invoke-n",signature:"($name as xs:QName) as item()* external",description:" See documentation for reflection:invoke except the function that\n is to be invoked may be nondeterministic.\n",summary:"<p> See documentation for reflection:invoke except the function that\n is to be invoked may be nondeterministic.</p>",annotation_str:" %an:nondeterministic %an:variadic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""},{prefix:"an",ns:"http://zorba.io/annotations",name:"variadic",value:""}],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the QName of the function that is to be invoked</div>'}],returns:{type:"item()*",description:"the result that is returned by the invoked function"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">whatever error the invoked function may return</xqdoc:error>']},{isDocumented:!0,arity:1,name:"invoke-s",qname:"reflection:invoke-s",signature:"($name as xs:QName) as item()* external",description:" See documentation for reflection:invoke except the function that\n is to be invoked may be sequential, i.e. may have side-effects.\n",summary:"<p> See documentation for reflection:invoke except the function that\n is to be invoked may be sequential, i.</p>",annotation_str:" %an:variadic %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"variadic",value:""},{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the QName of the function that is to be invoked</div>'}],returns:{type:"item()*",description:"the result that is returned by the invoked function"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">whatever error the invoked function may return</xqdoc:error>']},{isDocumented:!0,arity:1,name:"invoke-u",qname:"reflection:invoke-u",signature:"($name as xs:QName) external",description:" See documentation for reflection:invoke-n except the function that\n is to be invoked may be updating, i.e. return a pending update list.\n",summary:"<p> See documentation for reflection:invoke-n except the function that\n is to be invoked may be updating, i.</p>",annotation_str:" %an:nondeterministic %an:variadic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""},{prefix:"an",ns:"http://zorba.io/annotations",name:"variadic",value:""}],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the QName of the function that is to be invoked</div>'}],returns:{type:null,description:"the result that is returned by the invoked function"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">whatever error the invoked function may return</xqdoc:error>']},{isDocumented:!0,arity:1,name:"invoke",qname:"reflection:invoke",signature:"($name as xs:QName) as item()* external",description:' The invoke function allows to dynamically call a function given its QName\n and parameters.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n It is possible to invoke a function whose name is not known\n at compilation time -- it can be computed, passed through an external\n variable, taken from a file, etc. The first parameter must always be a\n QName identifying a known function.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The function is declared with the %an:variadic annotation. Hence, it allows\n for an arbitrary number of parameters. All of these parameters (except the\n first one) will be passed to the function that is called.\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Example usage : <pre xmlns:xqdoc="http://www.xqdoc.org/1.0"> reflection:invoke ( xs:QName("fn:max"), (1,2,3) ) </pre>\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Returns <pre xmlns:xqdoc="http://www.xqdoc.org/1.0"> 3 </pre>.\n',summary:"<p> The invoke function allows to dynamically call a function given its QName\n and parameters.</p>",annotation_str:" %an:variadic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"variadic",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the QName of the function that is to be invoked</div>'}],returns:{type:"item()*",description:"the result that is returned by the invoked function"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">whatever error the invoked function may return</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/hmac":{ns:"http://zorba.io/modules/hmac",description:" This module provides functions that perform HMAC\n (hash-based message authentication code) operations.\n For example, they calculate message codes involving hash functions such\n as MD5 and various SHA variants. The result is the base64 encoded value\n of the hash. A hash may be used to verify the data integrity and\n the authenticity of a message.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">William Candillon, Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/hmac",prefix:"hmac"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:3,name:"compute-binary",qname:"hmac:compute-binary",signature:"($message as xs:base64Binary, $secret-key as xs:string, $hash-algo as xs:string) as xs:base64Binary external",description:" Calculate the HMAC for the given message and secret-key involving\n an custom hash function. Before calculating the code, the given\n base64-encoded message is base64-decoded.\n",summary:"<p> Calculate the HMAC for the given message and secret-key involving\n an custom hash function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"message",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the message to be authenticated</div>'},{name:"secret-key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the secret key used for calculating the authentication</div>'},{name:"hash-algo",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:base64Binary",description:"the base64 encoded message authentication code"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">hash:UNSUPPORTED-ALGORITHM if the given hash algorithm is not supported</xqdoc:error>']},{isDocumented:!0,arity:3,name:"compute",qname:"hmac:compute",signature:"($message as xs:string, $secret-key as xs:string, $alg as xs:string) as xs:base64Binary external",description:" Calculate the HMAC for the given message and secret-key involving\n an custom hash function.\n",summary:"<p> Calculate the HMAC for the given message and secret-key involving\n an custom hash function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"message",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the message to be authenticated</div>'},{name:"secret-key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the secret key used for calculating the authentication</div>'},{name:"alg",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The algorithm to use for the hashing operation. Supported algorithms are "md5", "sha1", and "sha256".</div>'}],returns:{type:"xs:base64Binary",description:"the base64 encoded message authentication code"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">hash:UNSUPPORTED-ALGORITHM if the given hash algorithm is not supported</xqdoc:error>']},{isDocumented:!0,arity:2,name:"md5-binary",qname:"hmac:md5-binary",signature:"($message as xs:base64Binary, $secret-key as xs:string) as xs:base64Binary",description:" Calculate the HMAC for the given message and secret-key involving\n the MD5 hash function. Before calculating the code, the given\n base64-encoded message is base64-decoded.\n",summary:"<p> Calculate the HMAC for the given message and secret-key involving\n the MD5 hash function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"message",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the message to be authenticated</div>'},{name:"secret-key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the secret key used for calculating the authentication</div>'}],returns:{type:"xs:base64Binary",description:"the base64 encoded message authentication code"},errors:[]},{isDocumented:!0,arity:2,name:"md5",qname:"hmac:md5",signature:"($message as xs:string, $secret-key as xs:string) as xs:base64Binary",description:" Calculate the HMAC for the given message and secret-key involving\n the MD5 hash function.\n",summary:"<p> Calculate the HMAC for the given message and secret-key involving\n the MD5 hash function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"message",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the message to be authenticated</div>'},{name:"secret-key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the secret key used for calculating the authentication</div>'}],returns:{type:"xs:base64Binary",description:"the base64 encoded message authentication code"},errors:[]},{isDocumented:!0,arity:2,name:"sha1-binary",qname:"hmac:sha1-binary",signature:"($message as xs:base64Binary, $secret-key as xs:string) as xs:base64Binary",description:" Calculate the HMAC for the given message and secret-key involving\n the SHA1 hash function. Before calculating the code, the given\n base64-encoded message is base64-decoded.\n",summary:"<p> Calculate the HMAC for the given message and secret-key involving\n the SHA1 hash function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"message",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the message to be authenticated</div>'},{name:"secret-key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the secret key used for calculating the authentication</div>'}],returns:{type:"xs:base64Binary",description:"the base64 encoded message authentication code"},errors:[]},{isDocumented:!0,arity:2,name:"sha1",qname:"hmac:sha1",signature:"($message as xs:string, $secret-key as xs:string) as xs:base64Binary",description:" Calculate the HMAC for the given message and secret-key involving\n the SHA1 hash function.\n",summary:"<p> Calculate the HMAC for the given message and secret-key involving\n the SHA1 hash function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"message",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the message to be authenticated</div>'},{name:"secret-key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the secret key used for calculating the authentication</div>'}],returns:{type:"xs:base64Binary",description:"the base64 encoded message authentication code"},errors:[]}],variables:[]},"http://www.28msec.com/modules/sleep":{ns:"http://www.28msec.com/modules/sleep",description:" This module provides a function to put the currently executing request\n to sleep.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/sleep",prefix:"sleep"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"millis",qname:"sleep:millis",signature:"($millis as xs:integer) as empty-sequence() external",description:' Puts the currently executing request to sleep.\n This function is mainly useful in development e.g. to simulate the\n effects of long-running tasks wrt. the concurrent execution of\n requests.\n Here the function is used to simulate a request that runs for 1 second\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n declare $acquired := lock:try-acquire("my-lock");\n if ($acquired)\n   sleep:millis(1000);\n else\n   fn:error(xs:QName("..."), "failed to acquire lock");\n </pre>\n',summary:"<p> Puts the currently executing request to sleep.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"millis",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of milliseconds to sleep</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and returns the empty sequence"},errors:[]}],variables:[]},"http://www.28msec.com/modules/cloudant":{ns:"http://www.28msec.com/modules/cloudant",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for creating, reading, updating,\n deleting and searching data in <a href="https://cloudant.com/">Cloudant</a>\n databases.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Before issuing a request to Cloudant it is mandatory to create\n a new connection through one of the <code>connect</code> functions.\n These functions return a connection identifier which needs to be used\n to access data in Cloudant through the other functions.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In these functions Cloudant databases will be identified through\n their names. By default, the functions will assume that the database is owned by\n the user for which the given connection has been created.\n To specify a different database owner, most functions accept an\n <code>$options</code> parameter that allows a <code>database-owner</code>\n option to specify a different database owner for a single request.\n Moreover, when connecting, it is possible to specify the default\n database owner using the <code>connect#3</code> function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Additional information on the Cloudant APIs can be found\n <a href="https://cloudant.com/for-developers/">on the Cloudant website</a>.</p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="determinism">Important Notice Regarding Function Determinism</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The non side-effecting functions:\n <ul>\n   <li><a href="?anchor=list-databases-1">list-databases#1</a></li>\n   <li><a href="?anchor=list-databases-2">list-databases#2</a></li>\n   <li><a href="?anchor=database-info-2">database-info#2</a></li>\n   <li><a href="?anchor=database-info-3">database-info#3</a></li>\n   <li><a href="?anchor=all-documents-2">all-documents#2</a></li>\n   <li><a href="?anchor=all-documents-3">all-documents#3</a></li>\n   <li><a href="?anchor=multiple-documents-3">multiple-documents#3</a></li>\n   <li><a href="?anchor=multiple-documents-4">multiple-documents#4</a></li>\n   <li><a href="?anchor=document-3">document#3</a></li>\n   <li><a href="?anchor=document-4">document#4</a></li>\n   <li><a href="?anchor=document-info-3">document-info#3</a></li>\n   <li><a href="?anchor=document-info-4">document-info#4</a></li>\n   <li><a href="?anchor=attachment-4">attachment#4</a></li>\n   <li><a href="?anchor=attachment-5">attachment#5</a></li>\n   <li><a href="?anchor=all-view-documents-4">all-view-documents#4</a></li>\n   <li><a href="?anchor=all-view-documents-5">all-view-documents#5</a></li>\n   <li><a href="?anchor=multiple-view-documents-5">multiple-view-documents#5</a></li>\n   <li><a href="?anchor=multiple-view-documents-6">multiple-view-documents#6</a></li>\n   <li><a href="?anchor=lucene-query-5">lucene-query#5</a></li>\n   <li><a href="?anchor=lucene-query-6">lucene-query#6</a></li>\n </ul>\n are declared deterministic, which means that their results could be cached\n when invoked multiple times with the same arguments in the same query execution.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To not use cached results you can use the following alternative functions:\n <ul>\n   <li><a href="?anchor=list-databases-nondeterministic-1">list-databases-nondeterministic#1</a></li>\n   <li><a href="?anchor=list-databases-nondeterministic-2">list-databases-nondeterministic#2</a></li>\n   <li><a href="?anchor=database-info-nondeterministic-2">database-info-nondeterministic#2</a></li>\n   <li><a href="?anchor=database-info-nondeterministic-3">database-info-nondeterministic#3</a></li>\n   <li><a href="?anchor=all-documents-nondeterministic-2">all-documents-nondeterministic#2</a></li>\n   <li><a href="?anchor=all-documents-nondeterministic-3">all-documents-nondeterministic#3</a></li>\n   <li><a href="?anchor=multiple-documents-nondeterministic-3">multiple-documents-nondeterministic#3</a></li>\n   <li><a href="?anchor=multiple-documents-nondeterministic-4">multiple-documents-nondeterministic#4</a></li>\n   <li><a href="?anchor=document-nondeterministic-3">document-nondeterministic#3</a></li>\n   <li><a href="?anchor=document-nondeterministic-4">document-nondeterministic#4</a></li>\n   <li><a href="?anchor=document-info-nondeterministic-3">document-info-nondeterministic#3</a></li>\n   <li><a href="?anchor=document-info-nondeterministic-4">document-info-nondeterministic#4</a></li>\n   <li><a href="?anchor=attachment-nondeterministic-4">attachment-nondeterministic#4</a></li>\n   <li><a href="?anchor=attachment-nondeterministic-5">attachment-nondeterministic#5</a></li>\n   <li><a href="?anchor=all-view-documents-nondeterministic-4">all-view-documents-nondeterministic#4</a></li>\n   <li><a href="?anchor=all-view-documents-nondeterministic-5">all-view-documents-nondeterministic#5</a></li>\n   <li><a href="?anchor=multiple-view-documents-nondeterministic-5">multiple-view-documents-nondeterministic#5</a></li>\n   <li><a href="?anchor=multiple-view-documents-nondeterministic-6">multiple-view-documents-nondeterministic#6</a></li>\n   <li><a href="?anchor=lucene-query-nondeterministic-5">lucene-query-nondeterministic#5</a></li>\n   <li><a href="?anchor=lucene-query-nondeterministic-6">lucene-query-nondeterministic#6</a></li>\n </ul>\n which have been declared as being non deterministic.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/cloudant",prefix:"cloudant"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://zorba.io/modules/http-client",prefix:"http"},{uri:"http://www.28msec.com/modules/maps",prefix:"map"},{uri:"http://zorba.io/modules/random",prefix:"random"},{uri:"http://www.zorba-xquery.com/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"all-documents-nondeterministic",qname:"cloudant:all-documents-nondeterministic",signature:"($connection as anyURI, $database as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all the documents in a given database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#all-documents-2">all-documents#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists all the documents in a given database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'}],returns:{type:"object()",description:"An object listing the documents in the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:3,name:"all-documents-nondeterministic",qname:"cloudant:all-documents-nondeterministic",signature:"($connection as anyURI, $database as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all the documents in a given database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#all-documents-3">all-documents#3</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists all the documents in a given database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object listing the documents in the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:2,name:"all-documents",qname:"cloudant:all-documents",signature:"($connection as anyURI, $database as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all the documents in a given database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:all-documents($connection, "db")</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "total_rows":3,\n   "offset":0,\n   "rows":[\n   {\n     "id":"5a049246-179f-42ad-87ac-8f080426c17c",\n     "key":"5a049246-179f-42ad-87ac-8f080426c17c",\n     "value":\n     {\n       "rev":"2-9d5401898196997853b5ac4163857a29"\n     }\n   },\n   {\n     "id":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n     "key":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n     "value":\n     {\n       "rev":"2-ff7b85665c4c297838963c80ecf481a3"\n      }\n   },\n   {\n     "id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "key":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "value":\n     {\n       "rev":"2-cbdef49ef3ddc127eff86350844a6108"\n     }\n   }]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>offset: offset where the document list started.</li>\n  <li>rows: array of document objects, each containing id, key and revision number.</li>\n  <li>total_rows: number of documents in the database.</li>\n  <li>update_seq: current update sequence database.</li>\n </ul>\n </p>\n',summary:"<p>  Lists all the documents in a given database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'}],returns:{type:"object()",description:"An object listing the documents in the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:3,name:"all-documents",qname:"cloudant:all-documents",signature:"($connection as anyURI, $database as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists all the documents in a given database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>descending: return the documents in descending by key order (boolean,\n   default: false).</li>\n   <li>endkey: stop returning records when the specified key is reached (string).</li>\n   <li>endkey_docid: stop returning records when the specified document ID is\n   reached (string).</li>\n   <li>group: group the results using the reduce function to a group or single\n   row (boolean, default: false).</li>\n   <li>group_level: specify the group level to be used (numeric).</li>\n   <li>include_docs: include the full content of the documents in the return\n   (boolean, default: false).</li>\n   <li>inclusive_end: specifies whether the specified end key should be included\n   in the result (boolean, default: true).</li>\n   <li>key: return only documents that match the specified key (string).</li>\n   <li>limit: limit the number of the returned documents to the specified number\n   (numeric).</li>\n   <li>reduce: use the reduction function (boolean, default: true).</li>\n   <li>skip: skip this number of records before starting to return the results\n   (numeric, default: 0).</li>\n   <li>stale: allow the results from a stale view to be used (string, allowed\n   value: "ok").</li>\n   <li>startkey: start returning records when the specified key is reached (string).</li>\n   <li>startkey_docid: start returning records when the specified document ID\n   is reached (string).</li>\n   <li>database-owner: specifies the database owner (string, default: connection\n   user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:all-documents($connection, "db", {"database-owner": "username"})</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "total_rows":3,\n   "offset":0,\n   "rows":[\n   {\n     "id":"5a049246-179f-42ad-87ac-8f080426c17c",\n     "key":"5a049246-179f-42ad-87ac-8f080426c17c",\n     "value":\n     {\n       "rev":"2-9d5401898196997853b5ac4163857a29"\n     }\n   },\n   {\n     "id":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n     "key":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n     "value":\n     {\n       "rev":"2-ff7b85665c4c297838963c80ecf481a3"\n      }\n   },\n   {\n     "id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "key":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "value":\n     {\n       "rev":"2-cbdef49ef3ddc127eff86350844a6108"\n     }\n   }]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>offset: offset where the document list started.</li>\n  <li>rows: array of document objects, each containing id, key and revision number.</li>\n  <li>total_rows: number of documents in the database.</li>\n  <li>update_seq: current update sequence database.</li>\n </ul>\n </p>\n',summary:"<p>  Lists all the documents in a given database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object listing the documents in the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:4,name:"all-view-documents-nondeterministic",qname:"cloudant:all-view-documents-nondeterministic",signature:"($connection as anyURI, $database as string, $design-document as string, $view as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a JSON object describing all the documents in a given view.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#all-view-documents-4">all-view-documents#4</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns a JSON object describing all the documents in a given view.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"view",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A view name</div>'}],returns:{type:"object()",description:"An object listing all documents in the specified view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:5,name:"all-view-documents-nondeterministic",qname:"cloudant:all-view-documents-nondeterministic",signature:"($connection as anyURI, $database as string, $design-document as string, $view as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a JSON object describing all the documents in a given view.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#all-view-documents-5">all-view-documents#5</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns a JSON object describing all the documents in a given view.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"view",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A view name</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object listing all documents in the specified view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:4,name:"all-view-documents",qname:"cloudant:all-view-documents",signature:"($connection as anyURI, $database as string, $design-document as string, $view as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a JSON object describing all the documents in a given view.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:all-view-documents($connection, "db", "recipes", "by_title")</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "offset" : 0,\n   "rows" :\n   [\n     {\n       "id" : "3-tiersalmonspinachandavocadoterrine",\n       "key" : "3-tier salmon, spinach and avocado terrine",\n       "value" : ["3-tier salmon, spinach and avocado terrine"]\n     },\n     {\n       "id" : "Aberffrawcake",\n       "key" : "Aberffraw cake",\n       "value" : ["Aberffraw cake"]\n     },\n     {\n       "id" : "Adukiandorangecasserole-microwave",\n       "key" : "Aduki and orange casserole - microwave",\n       "value" : ["Aduki and orange casserole - microwave"]\n     }\n   ],\n   "total_rows" : 3\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>offset: offset where the document list started.</li>\n  <li>rows: array of document objects, each containing id, key and revision number.</li>\n  <li>total_rows: number of documents in the database.</li>\n </ul>\n </p>\n',summary:"<p>  Returns a JSON object describing all the documents in a given view.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"view",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A view name</div>'}],returns:{type:"object()",description:"An object listing all documents in the specified view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:5,name:"all-view-documents",qname:"cloudant:all-view-documents",signature:"($connection as anyURI, $database as string, $design-document as string, $view as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a JSON object describing all the documents in a given view.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>descending: return the documents in descending by key order (boolean,\n   default: false)</li>\n   <li>endkey: stop returning records when the specified key is reached (string)</li>\n   <li>endkey_docid: stop returning records when the specified document ID is\n   reached (string)</li>\n   <li>group: group the results using the reduce function to a group or single\n   row (boolean, default: false)</li>\n   <li>group_level: specify the group level to be used (numeric)</li>\n   <li>include_docs: include the full content of the documents in the return\n   (boolean, default: false)</li>\n   <li>inclusive_end: specifies whether the specified end key should be included\n   in the result (boolean, default: true)</li>\n   <li>key: return only documents that match the specified key (string)</li>\n   <li>limit: limit the number of the returned documents to the specified number\n   (numeric)</li>\n   <li>reduce: use the reduction function (boolean, default: true)</li>\n   <li>skip: skip this number of records before starting to return the results\n   (numeric, default: 0)</li>\n   <li>stale: allow the results from a stale view to be used (string, allowed\n   value: "ok")</li>\n   <li>startkey: start returning records when the specified key is reached\n   (string)</li>\n   <li>startkey_docid: start returning records when the specified document ID\n   is reached (string)</li>\n   <li>database-owner: specifies the database owner (string, default:\n   connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:all-view-documents($connection, "db", "recipes", "by_title",\n   {"database-owner" : "username"})</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "offset" : 0,\n   "rows" :\n   [\n     {\n       "id" : "3-tiersalmonspinachandavocadoterrine",\n       "key" : "3-tier salmon, spinach and avocado terrine",\n       "value" : ["3-tier salmon, spinach and avocado terrine"]\n     },\n     {\n       "id" : "Aberffrawcake",\n       "key" : "Aberffraw cake",\n       "value" : ["Aberffraw cake"]\n     },\n     {\n       "id" : "Adukiandorangecasserole-microwave",\n       "key" : "Aduki and orange casserole - microwave",\n       "value" : ["Aduki and orange casserole - microwave"]\n     }\n   ],\n   "total_rows" : 3\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>offset: offset where the document list started.</li>\n  <li>rows: array of document objects, each containing id, key and revision\n  number.</li>\n  <li>total_rows: number of documents in the database.</li>\n </ul>\n </p>\n',summary:"<p>  Returns a JSON object describing all the documents in a given view.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"view",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A view name</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object listing all documents in the specified view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:4,name:"attachment-nondeterministic",qname:"cloudant:attachment-nondeterministic",signature:"($connection as anyURI, $database as string, $document-id as string, $attachment-name as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the specified document attachment.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#attachment-4">attachment#4</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves the specified document attachment.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"attachment-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An attchment name</div>'}],returns:{type:"object()",description:"The specified document attachment"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:5,name:"attachment-nondeterministic",qname:"cloudant:attachment-nondeterministic",signature:"($connection as anyURI, $database as string, $document-id as string, $attachment-name as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the specified document attachment.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#attachment-5">attachment#5</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves the specified document attachment.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"attachment-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An attchment name</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"The specified document attachment"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:ATTACHMENT-NOT-EXISTS Attachment does not exists</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:4,name:"attachment",qname:"cloudant:attachment",signature:"($connection as anyURI, $database as string, $document-id as string, $attachment-name as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the specified document attachment.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:attachment($connection, "db", "DocID", "Attachment")</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieving a design document attachment.</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To retrieve a design document attachment the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:attachment($connection, "db", "_design/DocID", "Attachment")</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object reports the media-type of the attachment as\n it was specified when the attachment was submitted to the database and\n its raw content.\n The format of the returned object is the following:\n <pre>\n {\n   "media-type": "text/plain",\n   "content" : "Hello World"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The type of the content field is determined by the media-type returned by the\n server. If the media-type indicates that the body content is textual,\n then the content has type string, base64Binary otherwise.\n Specifically, the body content is considered textual only if the MIME-type specified in\n the media-type is one of:\n <ul>\n   <li>"application/json"</li>\n   <li>"application/x-javascript"</li>\n   <li>"application/xml"</li>\n   <li>"application/xml-external-parsed-entity"</li>\n </ul>\n or if the MIME-type starts with "text/" or ends with "+xml".</p>\n',summary:"<p>  Retrieves the specified document attachment.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"attachment-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An attchment name</div>'}],returns:{type:"object()",description:"The specified document attachment"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:5,name:"attachment",qname:"cloudant:attachment",signature:"($connection as anyURI, $database as string, $document-id as string, $attachment-name as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the specified document attachment.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>database-owner: specifies the database owner (string, default: connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:attachment($connection, "db", "DocID", "Attachment",\n   {"database-owner": "username"})</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieving a design document attachment.</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To retrieve a design document attachment the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:attachment($connection, "db", "_design/DocID", "Attachment",\n   {"database-owner": "username"})</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object reports the media-type of the attachment as\n it was specified when the attachment was submitted to the database and\n its raw content.\n The format of the returned object is the following:\n <pre>\n {\n   "media-type": "text/plain",\n   "content" : "Hello World"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The type of the content field is determined by the media-type returned by the\n server. If the media-type indicates that the body content is textual,\n then the content has type string, base64Binary otherwise.\n Specifically, the body content is considered textual only if the MIME-type specified in\n the media-type is one of:\n <ul>\n   <li>"application/json"</li>\n   <li>"application/x-javascript"</li>\n   <li>"application/xml"</li>\n   <li>"application/xml-external-parsed-entity"</li>\n </ul>\n or if the MIME-type starts with "text/" or ends with "+xml".</p>\n',summary:"<p>  Retrieves the specified document attachment.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"attachment-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An attchment name</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"The specified document attachment"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:ATTACHMENT-NOT-EXISTS Attachment does not exists</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:3,name:"bulk-crud",qname:"cloudant:bulk-crud",signature:"($connection as anyURI, $database as string, $documents as object()*) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates, updates or deletes multiple documents with a single request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">When creating new documents the document ID is optional. For updating\n existing documents, you must provide the document ID, revision information,\n and new document values. To delete existing documents, you must provide the\n document ID, revision information and add a field <code>_deleted</code> having\n value <code>true</code>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:bulk-crud($connection, "db",\n (\n   {\n     "name":"Nicholas",\n     "age":45,\n     "gender":"male",\n   },\n   {\n     "name":"Taylor",\n     "age":50,\n     "gender":"male",\n     "_id":"5a049246-179f-42ad-87ac-8f080426c17c",\n   },\n   {\n     "name":"Owen",\n     "age":51,\n     "gender":"male",\n     "_id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "_rev":"2-f29c836d0bedc4b4b95cfaa6d99e95df",\n   },\n   {\n     "_id":"b675e932-9bb6-4fc9-b889-50238ac3512b",\n     "_rev":"2-abd3942fdab3515bfed224abed2451feb",\n     "_deleted": true\n   }\n ))\n </pre>\n requires to insert the first document with a system-generated identifier, to\n insert the second one with a user-specified identifier, to update the third\n one and, finally,to delete the last one.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The JSON returned by the_bulk_docs operation consists of an array\n of JSON structures, one for each submitted document.\n The returned JSON structure should be examined to ensure that all of\n the documents submitted in the original request were successfully added\n to the database. When no errors are raised, the revision of the new\n document is reported for all documents.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n <pre>\n [{\n    "id":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n    "rev":"2-ff7b85665c4c297838963c80ecf481a3"\n  },\n  {\n    "id":"5a049246-179f-42ad-87ac-8f080426c17c",\n    "rev":"2-9d5401898196997853b5ac4163857a29"\n  },\n  {\n    "id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n    "rev":"2-cbdef49ef3ddc127eff86350844a6108"\n  },\n  {\n    "id": "b675e932-9bb6-4fc9-b889-50238ac3512b",\n    "rev":"2-12356bafb1232167befabb32127823943d"\n  }]\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Cloudant will only guarantee that some of the documents will be\n saved when you send the request. The response will contain the list of\n documents successfully inserted or updated during the process.\n In the event of a crash, some of the documents may have been successfully\n saved, and some will have been lost.\n The response structure will indicate whether the document was updated by\n supplying the <code>rev</code> parameter indicating a new document revision\n was created. If the update failed, then you will get an error of type\n <code>conflict</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example:\n <pre>\n [\n   {\n     "id":"FishStew",\n     "error":"conflict",\n     "reason":"Document update conflict."\n   },\n   {\n     "id":"LambStew",\n     "error":"conflict",\n     "reason":"Document update conflict."\n   },\n   {\n     "id":"7f7638c86173eb440b8890839ff35433",\n     "error":"conflict",\n     "reason":"Document update conflict."\n   }\n ]\n </pre>\n In this case no new revision has been created and you will need to submit\n the document update with the correct revision tag, to update the document.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The exact structure of each document in the returned array is:\n <ul>\n   <li>id: the document ID</li>\n   <li>rev: the new document revision, if a new revision was created</li>\n   <li>error: the error type, if an error was raised</li>\n   <li>reason: a description of the raised error, if an error was raised</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The error type can either be conflict or forbidden. The first type means that\n the document as submitted is in conflict. The new revision has not been created\n and you will need to re-submit the document to the database. Entries with forbidden\n error type indicate that the validation routine applied to the document during submission\n has returned an error.</p>\n',summary:"<p>  Creates, updates or deletes multiple documents with a single request.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"documents",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An sequence of documents</div>'}],returns:{type:"array()",description:"An object describing the performed operations"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"bulk-crud",qname:"cloudant:bulk-crud",signature:"($connection as anyURI, $database as string, $documents as object()*, $options as object()) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates, updates or deletes multiple documents with a single request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">When creating new documents the document ID is optional. For updating\n existing documents, you must provide the document ID, revision information,\n and new document values. To delete existing documents, you must provide the\n document ID, revision information and add a field <code>_deleted</code> having\n value <code>true</code>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>all_or_nothing: sets the database commit mode to use all-or-nothing\n   semantics (boolean, default: false).</li>\n   <li>database-owner: specifies the database owner (string, default: connection\n   user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:bulk-crud($connection, "db",\n (\n   {\n     "name":"Nicholas",\n     "age":45,\n     "gender":"male",\n   },\n   {\n     "name":"Taylor",\n     "age":50,\n     "gender":"male",\n     "_id":"5a049246-179f-42ad-87ac-8f080426c17c",\n   },\n   {\n     "name":"Owen",\n     "age":51,\n     "gender":"male",\n     "_id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "_rev":"2-f29c836d0bedc4b4b95cfaa6d99e95df",\n   },\n   {\n     "_id":"b675e932-9bb6-4fc9-b889-50238ac3512b",\n     "_rev":"2-abd3942fdab3515bfed224abed2451feb",\n     "_deleted": true\n   }\n ),{"database-owner": "username"})\n </pre>\n requires to insert the first document with a system-generated identifier, to\n insert the second one with a user-specified identifier, to update the third\n one and, finally, to delete the last one.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The JSON returned by the_bulk_docs operation consists of an array\n of JSON structures, one for each document in the original submission.\n The returned JSON structure should be examined to ensure that all of\n the documents submitted in the original request were successfully added\n to the database. When no errors are raised, the revision of the new\n document is reported for all documents.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n <pre>\n [{\n    "id":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n    "rev":"2-ff7b85665c4c297838963c80ecf481a3"\n  },\n  {\n    "id":"5a049246-179f-42ad-87ac-8f080426c17c",\n    "rev":"2-9d5401898196997853b5ac4163857a29"\n  },\n  {\n    "id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n    "rev":"2-cbdef49ef3ddc127eff86350844a6108"\n  },\n  {\n    "id": "b675e932-9bb6-4fc9-b889-50238ac3512b",\n    "rev":"2-12356bafb1232167befabb32127823943d"\n  }]\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Cloudant will only guarantee that some of the documents will be\n saved when you send the request. The response will contain the list of\n documents successfully inserted or updated during the process.\n In the event of a crash, some of the documents may have been successfully\n saved, and some will have been lost.\n The response structure will indicate whether the document was updated by\n supplying the <code>rev</code> parameter indicating a new document revision\n was created. If the update failed, then you will get an error of type\n <code>conflict</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example:\n <pre>\n [\n   {\n     "id":"FishStew",\n     "error":"conflict",\n     "reason":"Document update conflict."\n   },\n   {\n     "id":"LambStew",\n     "error":"conflict",\n     "reason":"Document update conflict."\n   },\n   {\n     "id":"7f7638c86173eb440b8890839ff35433",\n     "error":"conflict",\n     "reason":"Document update conflict."\n   }\n ]\n </pre>\n In this case no new revision has been created and you will need to submit\n the document update with the correct revision tag, to update the document.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The exact structure of each document in the returned array is:\n <ul>\n   <li>id: the document ID</li>\n   <li>rev: the new document revision, if a new revision was created</li>\n   <li>error: the error type, if an error was raised</li>\n   <li>reason: a description of the raised error, if an error was raised</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The error type can either be conflict or forbidden. The first type means that\n the document as submitted is in conflict. The new revision has not been created\n and you will need to re-submit the document to the database. Entries with forbidden\n error type indicate that the validation routine applied to the document during submission\n has returned an error.</p>\n',summary:"<p>  Creates, updates or deletes multiple documents with a single request.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"documents",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An sequence of documents</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"array()",description:"An object describing the performed operations"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:2,name:"commit-changes",qname:"cloudant:commit-changes",signature:"($connection as anyURI, $database as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Commits any recent changes to the specified database to disk.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:commit-changes($connection, "db")</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "ok" : true,\n   "instance_start_time" : "0"\n }\n </pre>\n </p>\n',summary:"<p>  Commits any recent changes to the specified database to disk.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'}],returns:{type:"object()",description:"An object reporting the instance start time"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NOT-EXISTS The specified database does not exists</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:3,name:"commit-changes",qname:"cloudant:commit-changes",signature:"($connection as anyURI, $database as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Commits any recent changes to the specified database to disk.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>database-owner: specifies the database owner (string, default: connection\n   user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>\n cloudant:commit-changes($connection, "db", {"database-owner": "username"})\n </pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "ok" : true,\n   "instance_start_time" : "0"\n }\n </pre>\n </p>\n',summary:"<p>  Commits any recent changes to the specified database to disk.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object reporting the instance start time"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NOT-EXISTS The specified database does not exists</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:0,name:"connect",qname:"cloudant:connect",signature:"() as anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Opens a connection to Cloudant using the default credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns an opaque URI that can represents the connection.\n This URI has to be passed to other functions of this module that require\n a <code>$connection</code> parameter as a first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function requires to specify an options object.\n The following options are supported:\n <ul>\n   <li>username: the username used for connecting (string, mandatory).</li>\n   <li>password: the password used for connecting (string, mandatory).</li>\n   <li>default-database-owner: the default database owner which will be\n       used when calling the other module functions (string).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:connect()</pre>.\n </p>\n',summary:"<p>  Opens a connection to Cloudant using the default credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"anyURI",description:"An identifier that represents the connection to the server"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CREDENTIALS Missing or invalid credentials</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authentication error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:1,name:"connect",qname:"cloudant:connect",signature:"($credentials as item()) as anyURI",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Opens a connection to Cloudant using the specified credentials.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns an opaque URI that can represents the connection.\n This URI has to be passed to other functions of this module that require\n a <code>$connection</code> parameter as a first argument.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The $credentials parameter is used to specify the connection information.\n If a string is used, then the function will interpret it as the name of\n a credential in the Cloudant category.\n If an object is used, then the function will open a connection using it.\n The object structure is the following:\n <ul>\n   <li>username: the username used for connecting (string, mandatory).</li>\n   <li>password: the password used for connecting (string, mandatory).</li>\n   <li>default-database-owner: the default database owner which will be\n       used when calling the other module functions (string, optional).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, using stored credential:\n <pre>cloudant:connect("credentials-name")</pre>\n For example, specifying the connection information:\n <pre>cloudant:connect(\n   {\n     "username": "user",\n     "password: "pass",\n     "owner": "another-user"\n   })</pre>.\n </p>\n',summary:"<p>  Opens a connection to Cloudant using the specified credentials.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"credentials",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The connection specification</div>'}],returns:{type:"anyURI",description:"An identifier that represents the connection to the server"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authentication error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CREDENTIALS Missing or malformed credentials</xqdoc:error>']},{isDocumented:!0,arity:2,name:"create-database",qname:"cloudant:create-database",signature:"($connection as anyURI, $database as string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates a new database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The database name must be composed of one or more of the following\n characters:\n <ul>\n  <li>Lowercase characters (a-z).</li>\n  <li>Digits (0-9).</li>\n  <li>Any of the characters: _,$,(,),+,- and /.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-database($connection, "db")</pre>.\n </p>\n',summary:"<p>  Creates a new database.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'}],returns:{type:"empty-sequence()",description:"Empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-EXISTS Database already exists</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:3,name:"create-document",qname:"cloudant:create-document",signature:"($connection as anyURI, $database as string, $document as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates a new document in the specified database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates a new document in the specified database,\n using the supplied JSON document structure. If the JSON\n structure includes the _id field, then the document will\n be created with the specified document ID. If the _id\n field is not specified, a new unique ID will be generated.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">You can include one or more attachments with a given document\n by incorporating the attachment information within the JSON of\n the document. This provides a simpler alternative to loading\n documents with attachments than making a separate call.\n To do so add you can add the <code>_attachments</code> object\n field to the document. It can have one ore more fields, each\n defining a different attachment.\n The name of the field is the name of the attachment.\n Its value is an object containing the following fields:\n <ul>\n  <li>content_type: MIME Content type string</li>\n  <li>data: File attachment content, Base64 encoded</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-document($connection, "db",\n   {\n     "_id" : "FishStew",\n     "servings" : 4,\n     "subtitle" : "Delicious with fresh bread",\n     "title" : "Fish Stew"\n     "_attachments" : {\n       "styling.css" : {\n       "content-type" : "text/css",\n       "data" : "cCB7IGZvbnQtc2l6ZTogMTJwdDsgfQo="\n       }\n     }\n   })\n </pre>\n creates a document with an attachment named <code>styling.css</code>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Creating a design document</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To create a design document the <code>_id</code> field must be present and must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, the following expression creates a design document\n <pre>cloudant:create-document($connection, "db",\n   {\n     "_id": "_design/DesDocID",\n     "views": {\n       "view1": {\n       "map":"function(doc){emit(doc.field, 1)}",\n       "reduce": "function(key, value, rereduce){return sum(values)}"\n       }\n     },\n     "indexes": {\n       "mysearch" : {\n         "analyzer": {"name": "portuguese", "stopwords":["foo", "bar, "baz"]},\n         "index": "function(doc){ ... }"\n       },\n     }\n   }, {"database-owner": "username"})\n </pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned JSON object will report the new document revision\n and has the following form:\n <pre>\n {\n   "id":"64575eef70ab90a2b8d55fc09e00440d",\n   "ok":true,\n   "rev":"1-9c65296036141e575d32ba9c034dd3ee"\n }\n </pre>\n </p>\n',summary:"<p>  Creates a new document in the specified database.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document</div>'}],returns:{type:"object()",description:"An object which contains the document id and revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT Document creation conflict</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"create-document",qname:"cloudant:create-document",signature:"($connection as anyURI, $database as string, $document as object(), $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates a new document in the specified database</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates a new document in the specified database,\n using the supplied JSON document structure. If the JSON\n structure includes the _id field, then the document will\n be created with the specified document ID. If the _id\n field is not specified, a new unique ID will be generated.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">You can include one or more attachments with a given document\n by incorporating the attachment information within the JSON of\n the document. This provides a simpler alternative to loading\n documents with attachments than making a separate call.\n To do so add you can add the <code>_attachments</code> object\n field to the document. It can have one ore more fields, each\n defining a different attachment.\n The name of the field is the name of the attachment.\n Its value is an object containing the following fields:\n <ul>\n  <li>content_type: MIME Content type string</li>\n  <li>data: File attachment content, Base64 encoded</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-document($connection, "db",\n   {\n     "_id" : "FishStew",\n     "servings" : 4,\n     "subtitle" : "Delicious with fresh bread",\n     "title" : "Fish Stew"\n     "_attachments" : {\n       "styling.css" : {\n       "content-type" : "text/css",\n       "data" : "cCB7IGZvbnQtc2l6ZTogMTJwdDsgfQo="\n       }\n     }\n   }, {"database-owner": "username"})\n </pre>\n creates a document with an attachment named <code>styling.css</code>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>batch: requires batch mode for insertions (string, allowed value: "ok")</li>\n   <li>database-owner: specifies the database owner (string, default: connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">You can write documents to the database at a higher rate\n by using the batch option. This collects document writes\n together in memory (on a user-by-user basis) before they are\n committed to disk. This increases the risk of the documents\n not being stored in the event of a failure, since the documents\n are not written to disk immediately.</p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Creating a design document</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To create a design document the <code>_id</code> field must be present and must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, the following expression creates a design document\n <pre>cloudant:create-document($connection, "db",\n   {\n     "_id": "_design/DesDocID",\n     "views": {\n       "view1": {\n       "map":"function(doc){emit(doc.field, 1)}",\n       "reduce": "function(key, value, rereduce){return sum(values)}"\n       }\n     },\n     "indexes": {\n       "mysearch" : {\n         "analyzer": {"name": "portuguese", "stopwords":["foo", "bar, "baz"]},\n         "index": "function(doc){ ... }"\n       },\n     }\n   }, {"database-owner": "username"})\n </pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned JSON object will report the new document revision\n and has the following form:\n <pre>\n {\n   "id":"64575eef70ab90a2b8d55fc09e00440d",\n   "ok":true,\n   "rev":"1-9c65296036141e575d32ba9c034dd3ee"\n }\n </pre>\n </p>\n',summary:"<p>  Creates a new document in the specified database \n  Creates a new document in the specified database,\n using the supplied JSON document structure.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object which contains the document id and revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT Document creation conflict</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:7,name:"create-or-update-attachment",qname:"cloudant:create-or-update-attachment",signature:"($connection as anyURI, $database as string, $document-id as string, $document-rev as string, $attachment-name as string, $media-type as string, $attachment as atomic) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates or updates a document attachment.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The latest document revision must be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-or-update-attachment($connection, "db", "FishStew",\n   "8-7c4740b4dcf26683e941d6641c00c39d", "AttachmentName", "text/plain",\n   "AttachmentContent")</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Creating or updating a design document attachment.</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To create or update a design document attachment the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-or-update-attachment($connection, "db", "_design/DesDocId",\n   "8-7c4740b4dcf26683e941d6641c00c39d", "AttachmentName", "text/plain",\n   "AttachmentContent")</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object reports the document id and its new\n revision, as follows:\n <pre>\n {\n   "id":"FishStew",\n   "ok":true,\n   "rev":"9-247bb19a41bfd9bfdaf5ee6e2e05be74"\n }\n </pre>\n </p>\n',summary:"<p>  Creates or updates a document attachment.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"document-rev",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document revision</div>'},{name:"attachment-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the attachment</div>'},{name:"media-type",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The media-type of the attachment</div>'},{name:"attachment",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0">-name The name of the attachment</div>'}],returns:{type:"object()",description:"An object containing the document id and its new revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:ATTACHMENT-TYPE Attachment type must be string, base64Binary or hexBinary</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:8,name:"create-or-update-attachment",qname:"cloudant:create-or-update-attachment",signature:"($connection as anyURI, $database as string, $document-id as string, $document-rev as string, $attachment-name as string, $media-type as string, $attachment as atomic, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates or updates a document attachment.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The latest document revision must be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>database-owner: specifies the database owner (string, default: connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-or-update-attachment($connection, "db", "FishStew",\n   "8-7c4740b4dcf26683e941d6641c00c39d", "AttachmentName", "text/plain",\n   "AttachmentContent", {"database-owner": "username"})</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Creating or updating a design document attachment.</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To create or update a design document attachment the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-or-update-attachment($connection, "db", "_design/DesDocId",\n   "8-7c4740b4dcf26683e941d6641c00c39d", "AttachmentName", "text/plain",\n   "AttachmentContent", {"database-owner": "username"})</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object reports the document id and its new\n revision, as follows:\n <pre>\n {\n   "id":"FishStew",\n   "ok":true,\n   "rev":"9-247bb19a41bfd9bfdaf5ee6e2e05be74"\n }\n </pre>\n </p>\n',summary:"<p>  Creates or updates a document attachment.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"document-rev",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document revision</div>'},{name:"attachment-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the attachment</div>'},{name:"media-type",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The media-type of the attachment</div>'},{name:"attachment",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0">-name The name of the attachment</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object containing the document id and its new revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:ATTACHMENT-TYPE Attachment type must be string, base64Binary or hexBinary</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:3,name:"create-or-update-document",qname:"cloudant:create-or-update-document",signature:"($connection as anyURI, $database as string, $document as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates or updates a document.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">When creating a new document, the <code>_id</code> field must\n be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-or-update-document($connection, "db",\n   {\n     "name":"Hannah",\n     "age":120,\n     "gender":"female",\n     "_id":"DocID"\n   })</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">When updating a document, the <code>_id</code> and the\n <code>_rev</code> field, which contains the last document revision,\n must be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-or-update-document($connection, "db",\n   {\n     "name":"Hannah",\n     "age":40,\n     "gender":"female",\n     "_id":"DocID",\n     "_rev":"1-764b9b11845fd0b73cfa0e61acc74ecf"\n   })</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Creating or updating a design document</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To create or update a design document the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, the following expression creates a design document\n <pre>cloudant:create-or-update-document($connection, "db",\n   {\n     "_id": "_design/DesDocID",\n     "views": {\n       "view1": {\n       "map":"function(doc){emit(doc.field, 1)}",\n       "reduce": "function(key, value, rereduce){return sum(values)}"\n       }\n     },\n     "indexes": {\n       "mysearch" : {\n         "analyzer": {"name": "portuguese", "stopwords":["foo", "bar, "baz"]},\n         "index": "function(doc){ ... }"\n       },\n     }\n   })\n </pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, the following expression updates a design document\n <pre>cloudant:create-or-update-document($connection, "db",\n   {\n     "_id": "_design/DesDocID",\n     "_rev": "2-f29c836d0bedc4b4b95cfaa6d99e95df",\n     "views": {\n       "view1": {\n       "map":"function(doc){emit(doc.field, 1)}",\n       "reduce": "function(key, value, rereduce){return sum(values)}"\n       }\n     },\n     "indexes": {\n       "mysearch" : {\n         "analyzer": {"name": "portuguese", "stopwords":["foo", "bar, "baz"]},\n         "index": "function(doc){ ... }"\n       },\n     }\n   })\n </pre>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The meaning of the fields in the design document is the following:\n <ul>\n   <li>_id: document ID</li>\n   <li>_rev: document revision</li>\n   <li>views: object defining the views. Each field defines a different view.\n       The field name is the name of the view and has the following content:\n     <ul>\n       <li>map: view map function</li>\n       <li>reduce: view reduce function (optional)</li>\n     </ul>\n   </li>\n   <li>indexes: object defining the view indexes. Each field defines a different index.\n       The field name is the name of the index and has the following content:\n     <ul>\n       <li>analyzer: Name of the analyzer to be used or an object with the\n       following fields:\n         <ul>\n           <li>name: Name of the analyzer</li>\n           <li>stopwords: An array of stop words. Stop words are words that\n           should not be indexed.</li>\n         </ul>\n       </li>\n       <li>index: Function that handles the indexing</li>\n     </ul>\n   </li>\n </ul>\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The format of the returned object is the following and contains\n the document id and revision.\n <pre>\n {\n   "ok":true,\n   "id":"DocID",\n   "rev":"1-764b9b11845fd0b73cfa0e61acc74ecf"\n }\n </pre>\n </p>\n',summary:"<p>  Creates or updates a document.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document</div>'}],returns:{type:"object()",description:"An object which specifies the document id and its new revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT-MALFORMED Malformed document object</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"create-or-update-document",qname:"cloudant:create-or-update-document",signature:"($connection as anyURI, $database as string, $document as object(), $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Creates or updates a document.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">When creating a new document, the <code>_id</code> field must\n be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-or-update-document($connection, "db", "DocID",\n   {\n     "name":"Hannah",\n     "age":120,\n     "gender":"female",\n     "_id":"DocID"\n   }, {"database-owner": "username"})</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">When updating a document, the <code>_id</code> and the\n <code>_rev</code> field, which contains the last document revision,\n must be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:create-or-update-document($connection, "db", "DocID",\n   {\n     "name":"Hannah",\n     "age":40,\n     "gender":"female",\n     "_id":"DocID",\n     "_rev":"1-764b9b11845fd0b73cfa0e61acc74ecf"\n   }, {"database-owner": "username"})</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Creating or updating a design document</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To create or update a design document the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, the following expression creates a design document\n <pre>cloudant:create-or-update-document($connection, "db",\n   {\n     "_id": "_design/DesDocID",\n     "views": {\n       "view1": {\n       "map":"function(doc){emit(doc.field, 1)}",\n       "reduce": "function(key, value, rereduce){return sum(values)}"\n       }\n     },\n     "indexes": {\n       "mysearch" : {\n         "analyzer": {"name": "portuguese", "stopwords":["foo", "bar, "baz"]},\n         "index": "function(doc){ ... }"\n       },\n     }\n   }, {"database-owner": "username"})\n </pre>.\n </p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:create-or-update-document($connection, "db",\n   {\n     "_id": "_design/DesDocID",\n     "_rev": "2-f29c836d0bedc4b4b95cfaa6d99e95df",\n     "views": {\n       "view1": {\n       "map":"function(doc){emit(doc.field, 1)}",\n       "reduce": "function(key, value, rereduce){return sum(values)}"\n       }\n     },\n     "indexes": {\n       "mysearch" : {\n         "analyzer": {"name": "portuguese", "stopwords":["foo", "bar, "baz"]},\n         "index": "function(doc){ ... }"\n       },\n     }\n   }, {"database-owner": "username"})\n </pre>.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The meaning of the fields in the design document is the following:\n <ul>\n   <li>_id: document ID</li>\n   <li>_rev: document revision</li>\n   <li>views: object defining the views. Each field defines a different view.\n       The field name is the name of the view and has the following content:\n     <ul>\n       <li>map: view map function</li>\n       <li>reduce: view reduce function (optional)</li>\n     </ul>\n   </li>\n   <li>indexes: object defining the view indexes. Each field defines a different index.\n       The field name is the name of the index and has the following content:\n     <ul>\n       <li>analyzer: Name of the analyzer to be used or an object with the\n       following fields:\n         <ul>\n           <li>name: Name of the analyzer</li>\n           <li>stopwords: An array of stop words. Stop words are words that\n           should not be indexed.</li>\n         </ul>\n       </li>\n       <li>index: Function that handles the indexing</li>\n     </ul>\n   </li>\n </ul>\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The format of the returned object is the following and contains\n the document id and revision.\n <pre>\n {\n   "ok":true,\n   "id":"DocID",\n   "rev":"1-764b9b11845fd0b73cfa0e61acc74ecf"\n }\n </pre>\n </p>\n',summary:"<p>  Creates or updates a document.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object which specifies the document id and its new revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT-MALFORMED Malformed document object</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:2,name:"database-info-nondeterministic",qname:"cloudant:database-info-nondeterministic",signature:"($connection as anyURI, $database as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns information about a database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#database-info-2">database-info#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns information about a database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'}],returns:{type:"object()",description:"An object describing the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:3,name:"database-info-nondeterministic",qname:"cloudant:database-info-nondeterministic",signature:"($connection as anyURI, $database as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns information about a database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#database-info-3">database-info#3</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns information about a database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database name</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object describing the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:2,name:"database-info",qname:"cloudant:database-info",signature:"($connection as anyURI, $database as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns information about a database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:database-info($connection, "db")</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "update_seq": "0-g1AAAADneJzLYWBg...",\n   "db_name": "db",\n   "purge_seq": 0,\n   "other": {\n     "data_size": 0\n   },\n   "doc_del_count": 0,\n   "doc_count": 0,\n   "disk_size": 316,\n   "disk_format_version": 5,\n   "compact_running": false,\n   "instance_start_time": "0"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>compact_running: set to true if the database compaction routine is\n  operating on this database.</li>\n  <li>db_name: the name of the database.</li>\n  <li>disk_format_version: the version of the physical format used for the data\n  when it is stored on disk.</li>\n  <li>disk_size: size in bytes of the data as stored on the disk. Views indexes\n  are not included in the calculation.</li>\n  <li>doc_count: a count of the documents in the specified database.</li>\n  <li>doc_del_count: number of deleted documents.</li>\n  <li>instance_start_time: always 0.</li>\n  <li>purge_seq: the number of purge operations on the database.</li>\n  <li>update_seq: the current number of updates to the database.</li>\n  <li>other: JSON object containing a data_size field.</li>\n </ul>\n </p>\n',summary:"<p>  Returns information about a database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'}],returns:{type:"object()",description:"An object describing the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:3,name:"database-info",qname:"cloudant:database-info",signature:"($connection as anyURI, $database as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns information about a database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>database-owner: specifies the database owner (string, default: connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:database-info($connection, "db", {"database-owner": "username"})</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "update_seq": "0-g1AAAADneJzLYWBg...",\n   "db_name": "db",\n   "purge_seq": 0,\n   "other": {\n     "data_size": 0\n   },\n   "doc_del_count": 0,\n   "doc_count": 0,\n   "disk_size": 316,\n   "disk_format_version": 5,\n   "compact_running": false,\n   "instance_start_time": "0"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>compact_running: set to true if the database compaction routine is\n  operating on this database.</li>\n  <li>db_name: the name of the database.</li>\n  <li>disk_format_version: the version of the physical format used for the data\n  when it is stored on disk.</li>\n  <li>disk_size: size in bytes of the data as stored on the disk. Views indexes\n  are not included in the calculation.</li>\n  <li>doc_count: a count of the documents in the specified database.</li>\n  <li>doc_del_count: number of deleted documents.</li>\n  <li>instance_start_time: always 0.</li>\n  <li>purge_seq: the number of purge operations on the database.</li>\n  <li>update_seq: the current number of updates to the database.</li>\n  <li>other: JSON object containing a data_size field.</li>\n </ul>\n </p>\n',summary:"<p>  Returns information about a database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a database name</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object describing the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:5,name:"delete-attachment",qname:"cloudant:delete-attachment",signature:"($connection as anyURI, $database as string, $document-id as string, $document-rev as string, $attachment-name as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes the specified attachment.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The latest document revision must be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:delete-attachment($connection, "db", "FishStew",\n   "8-7c4740b4dcf26683e941d6641c00c39d", "AttachmentName")</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Deleting a design document attachment.</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To delete a design document attachment the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:delete-attachment($connection, "db", "_design/DesDocId",\n   "8-7c4740b4dcf26683e941d6641c00c39d",\n   "AttachmentName", "text/plain", "AttachmentContent")</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object reports the document id and its new\n revision, as follows:\n <pre>\n {\n   "id":"FishStew",\n   "ok":true,\n   "rev":"9-247bb19a41bfd9bfdaf5ee6e2e05be74"\n }\n </pre>\n </p>\n',summary:"<p>  Deletes the specified attachment.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"document-rev",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document revision</div>'},{name:"attachment-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the attachment</div>'}],returns:{type:"object()",description:"An object containing the document id and its new revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:ATTACHMENT-NOT-EXISTS Attachment does not exists</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:ATTACHMENT-TYPE Attachment type must be string, base64Binary or hexBinary</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:6,name:"delete-attachment",qname:"cloudant:delete-attachment",signature:"($connection as anyURI, $database as string, $document-id as string, $document-rev as string, $attachment-name as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes the specified attachment.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The latest document revision must be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>database-owner: specifies the database owner (string, default: connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:delete-attachment($connection, "db", "FishStew",\n "8-7c4740b4dcf26683e941d6641c00c39d", "AttachmentName",\n {"database-owner": "username"})</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Deleting a design document attachment.</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To delete a design document attachment the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:delete-attachment($connection, "db", "_design/DesDocId",\n   "8-7c4740b4dcf26683e941d6641c00c39d", "AttachmentName", "text/plain",\n   "AttachmentContent", {"database-owner": "username"})</pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object reports the document id and its new\n revision, as follows:\n <pre>\n {\n   "id":"FishStew",\n   "ok":true,\n   "rev":"9-247bb19a41bfd9bfdaf5ee6e2e05be74"\n }\n </pre>\n </p>\n',summary:"<p>  Deletes the specified attachment.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"document-rev",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document revision</div>'},{name:"attachment-name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the attachment</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object containing the document id and its new revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:ATTACHMENT-NOT-EXISTS Attachment does not exists</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:ATTACHMENT-TYPE Attachment type must be string, base64Binary or hexBinary</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete-database",qname:"cloudant:delete-database",signature:"($connection as anyURI, $database as string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes a database and all the documents and attachments contained in it.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The database name must be composed of one or more of the following characters:\n <ul>\n  <li>Lowercase characters (a-z).</li>\n  <li>Digits (0-9).</li>\n  <li>Any of the characters: _,$,(,),+,- and /.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:delete-database($connection, "db")</pre>.\n </p>\n',summary:"<p>  Deletes a database and all the documents and attachments contained in it.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'}],returns:{type:"empty-sequence()",description:"Empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NOT-EXISTS Database does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"delete-document",qname:"cloudant:delete-document",signature:"($connection as anyURI, $database as string, $document-id as string, $document-rev as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes the specified document from a database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The latest document revision must be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>\n cloudant:delete-document($connection, "db", "DocID", "3-7c4740b4dcf26683e941d6641c00c39d")\n </pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Deleting a design document</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To delete a design document the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>\n cloudant:delete-document($connection, "db", "_design/DesDocID", "3-7c4740b4dcf26683e941d6641c00c39d")\n </pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object reports the document id and its\n new revision, as follows:\n <pre>\n {\n   "id":"DocID",\n   "ok":true,\n   "rev":"4-2719fd41187c60762ff584761b714cfb"\n }\n </pre>\n </p>\n',summary:"<p>  Deletes the specified document from a database.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"document-rev",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document revision</div>'}],returns:{type:"object()",description:"An object which specifies the document id and its new revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:REVISION Specified revision is missing, invalid or not the latest.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:5,name:"delete-document",qname:"cloudant:delete-document",signature:"($connection as anyURI, $database as string, $document-id as string, $document-rev as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes the specified document from a database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The latest document revision must be specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>database-owner: specifies the database owner (string, default: connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>\n cloudant:delete-document($connection, "db", "DocID", "3-7c4740b4dcf26683e941d6641c00c39d",\n   {"database-owner": "username"})\n </pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Deleting a design document</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To delete a design document the document id must\n start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>\n cloudant:delete-document($connection, "db", "_design/DesDocID", "3-7c4740b4dcf26683e941d6641c00c39d",\n   {"database-owner": "username"})\n </pre>.\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Return value</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned object reports the document id and its\n new revision, as follows:\n <pre>\n {\n   "id":"DocID",\n   "ok":true,\n   "rev":"4-2719fd41187c60762ff584761b714cfb"\n }\n </pre>\n </p>\n',summary:"<p>  Deletes the specified document from a database.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"document-rev",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document revision</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object which specifies the document id and its new revision"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:REVISION Specified revision is missing, invalid or not the latest.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:3,name:"document-info-nondeterministic",qname:"cloudant:document-info-nondeterministic",signature:"($connection as anyURI, $database as string, $document-id as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the latest revision and size for a given document.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#document-info-3">document-info#3</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns the latest revision and size for a given document.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'}],returns:{type:"object()",description:"An object specifying the document id, revision and size"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT The specified document or revision cannot be found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"document-info-nondeterministic",qname:"cloudant:document-info-nondeterministic",signature:"($connection as anyURI, $database as string, $document-id as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the latest revision and size for a given document.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#document-info-4">document-info#4</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns the latest revision and size for a given document.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object specifying the document id, revision and size"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT The specified document or revision cannot be found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:3,name:"document-info",qname:"cloudant:document-info",signature:"($connection as anyURI, $database as string, $document-id as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the latest revision and size for a given document.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:document-info($connection, "db", "DocID")</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The format of the returned object is the following and contains\n the document id, latest revision and size.\n <pre>\n {\n   "ok": true,\n   "id": "DocID",\n   "rev": "1-764b9b11845fd0b73cfa0e61acc74ecf",\n   "size": 500\n }\n </pre>\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Returning the latest revision and size for a given design document</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To return the latest revision and size of a design document the document\n id must start with\n <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:document-info($connection, "db", "_design/DesDocID")</pre>.\n </p>\n',summary:"<p>  Returns the latest revision and size for a given document.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'}],returns:{type:"object()",description:"An object specifying the document id, revision and size"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT The specified document or revision cannot be found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"document-info",qname:"cloudant:document-info",signature:"($connection as anyURI, $database as string, $document-id as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the latest revision and size for a given document.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>database-owner: specifies the database owner (string, default: connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>\n cloudant:document-info($connection, "db", "DocID", {"database-owner": "username"})\n </pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The format of the returned object is the following and contains\n the document id, latest revision and size.\n <pre>\n {\n   "ok": true,\n   "id": "DocID",\n   "rev": "1-764b9b11845fd0b73cfa0e61acc74ecf",\n   "size": 500\n }\n </pre>\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Returning the latest revision and size for a given design document</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To return the latest revision and size of a design document the document\n id must start with <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>\n cloudant:document-info($connection, "db", "_design/DesDocID", {"database-owner": "username"})\n </pre>.\n </p>\n',summary:"<p>  Returns the latest revision and size for a given document.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object specifying the document id, revision and size"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT The specified document or revision cannot be found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:3,name:"document-nondeterministic",qname:"cloudant:document-nondeterministic",signature:"($connection as anyURI, $database as string, $document-id as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves a document from the specified database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#document-3">document#3</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves a document from the specified database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'}],returns:{type:"object()",description:"The specified document"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT The specified document or revision cannot be found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"document-nondeterministic",qname:"cloudant:document-nondeterministic",signature:"($connection as anyURI, $database as string, $document-id as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves a document from the specified database</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#document-4">document#4</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Retrieves a document from the specified database \n  This function has the same semantics as  document#4 ,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"The specified document"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT The specified document or revision cannot be found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:3,name:"document",qname:"cloudant:document",signature:"($connection as anyURI, $database as string, $document-id as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves a document from the specified database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The latest revision of the document will be returned.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the document includes attachments, then the\n returned structure will contain a summary of the\n attachments associated with the document, but not the\n attachment data itself.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:document($connection, "db", "DocID")</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned JSON object will contain the document\n and has the following format:\n <pre>\n {\n   "_id": "DocID",\n   "_rev": "2-f29c836d0bedc4b4b95cfaa6d99e95df",\n   "name": "Anna",\n   "age": 89,\n   "gender": "female",\n   "_attachments": {\n     "my attachment": {\n       "content_type": "application/json; charset=UTF-8",\n       "revpos": 2,\n       "digest": "md5-37IZysiyWLRWx31J/1WQHw==",\n       "length": 12,\n       "stub": true\n       }\n     }\n   }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The meaning of the fields in the returned object is the following:\n <ul>\n   <li>_id: document ID</li>\n   <li>_rev: document revision</li>\n   <li>attachments: document attachments (optional), each field denotes the name\n       of a different attachment\n     <ul>\n       <li>content_type: attachment MIME Content type string</li>\n       <li>length: attachment length in bytes</li>\n       <li>revpos: revision where this attachment exists</li>\n       <li>digest: MD5 checksum of the attachment</li>\n       <li>stub: indicates whether the attachment is a stub</li>\n    </ul>\n  </li>\n </ul>\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieving a design document from the specified database</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To retrieve a design document the document id must start with\n <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:document($connection, "db", "_design/DesDocID")</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A JSON object with the following format is returned:\n <pre>\n {\n  "_id": "_design/DesDocID",\n   "views": {\n     "view1": {\n       "map":"function(doc){emit(doc.field, 1)}",\n       "reduce": "function(key, value, rereduce){return sum(values)}"\n     }\n   },\n   "indexes": {\n     "mysearch" : {\n       "analyzer": {"name": "portuguese", "stopwords":["foo", "bar, "baz"]},\n       "index": "function(doc){ ... }"\n     },\n   }\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The meaning of the fields in the returned object is the following:\n <ul>\n   <li>_id: document ID</li>\n   <li>_rev: document revision</li>\n   <li>views: object defining the views. Each field defines a different view.\n       The field name is the name of the view and has the following content:\n     <ul>\n       <li>map: view map function</li>\n       <li>reduce: view reduce function (optional)</li>\n     </ul>\n   </li>\n   <li>indexes: object defining the view indexes. Each field defines a different index.\n       The field name is the name of the index and has the following content:\n     <ul>\n       <li>analyzer: Name of the analyzer to be used or an object with the\n       following fields:\n         <ul>\n           <li>name: Name of the analyzer</li>\n           <li>stopwords: An array of stop words. Stop words are words that\n           should not be indexed.</li>\n         </ul>\n       </li>\n       <li>index: Function that handles the indexing</li>\n     </ul>\n   </li>\n </ul>\n </p>\n',summary:"<p>  Retrieves a document from the specified database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'}],returns:{type:"object()",description:"The specified document"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT The specified document or revision cannot be found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"document",qname:"cloudant:document",signature:"($connection as anyURI, $database as string, $document-id as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves a document from the specified database</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Unless you request a specific revision, the latest\n revision of the document will always be returned.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>conflict: returns the conflict tree for the document (boolean)</li>\n   <li>rev: specifies the revision to return (string)</li>\n   <li>revs: return a list of the revisions for the document (boolean)</li>\n   <li>revs_info: return a list of detailed revision information for the document\n   (boolean, allowed value: true)</li>\n   <li>database-owner: specifies the database owner (string, default: connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the document includes attachments, then the\n returned structure will contain a summary of the\n attachments associated with the document, but not the\n attachment data itself.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>\n cloudant:document($connection, "db", "DocID", {"database-owner": "username"})\n </pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned JSON object will contain the document\n and has the following format:\n <pre>\n {\n   "_id": "DocID",\n   "_rev": "2-f29c836d0bedc4b4b95cfaa6d99e95df",\n   "name": "Anna",\n   "age": 89,\n   "gender": "female",\n   "_attachments": {\n     "my attachment": {\n       "content_type": "application/json; charset=UTF-8",\n       "revpos": 2,\n       "digest": "md5-37IZysiyWLRWx31J/1WQHw==",\n       "length": 12,\n       "stub": true\n       }\n     }\n   }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The meaning of the fields in the returned object is the following:\n <ul>\n   <li>_id: document ID</li>\n   <li>_rev: document revision</li>\n   <li>attachments: document attachments (optional), each field denotes the name\n       of a different attachment:\n   <ul>\n     <li>content_type: attachment MIME Content type string</li>\n     <li>length: attachment length in bytes</li>\n     <li>revpos: revision where this attachment exists</li>\n     <li>digest: MD5 checksum of the attachment</li>\n     <li>stub: indicates whether the attachment is a stub</li>\n  </ul>\n  </li>\n </ul>\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieving a design document from the specified database</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To retrieve a design document the document id must start with\n <code>_design/</code>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:document($connection, "db", "_design/DesDocID", {"database-owner": "username"})</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A JSON object with the following format is returned:\n <pre>\n {\n  "_id": "_design/DesDocID",\n  "_rev": "2-f29c836d0bedc4b4b95cfaa6d99e95df",\n   "views": {\n     "view1": {\n       "map":"function(doc){emit(doc.field, 1)}",\n       "reduce": "function(key, value, rereduce){return sum(values)}"\n     }\n   },\n   "indexes": {\n     "mysearch" : {\n       "analyzer": {"name": "portuguese", "stopwords":["foo", "bar, "baz"]},\n       "index": "function(doc){ ... }"\n     },\n   }\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The meaning of the fields in the returned object is the following:\n <ul>\n   <li>_id: document ID</li>\n   <li>_rev: document revision</li>\n   <li>views: object defining the views. Each field defines a different view.\n       The field name is the name of the view and has the following content:\n     <ul>\n       <li>map: view map function</li>\n       <li>reduce: view reduce function (optional)</li>\n     </ul>\n   </li>\n   <li>indexes: object defining the view indexes. Each field defines a different index.\n       The field name is the name of the index and has the following content:\n     <ul>\n       <li>analyzer: Name of the analyzer to be used or an object with the\n       following fields:\n         <ul>\n           <li>name: Name of the analyzer</li>\n           <li>stopwords: An array of stop words. Stop words are words that\n           should not be indexed.</li>\n         </ul>\n       </li>\n       <li>index: Function that handles the indexing</li>\n     </ul>\n   </li>\n </ul>\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Getting a List of Revisions</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">You can obtain a list of the revisions for a given document\n by the revs option.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:document($connection, "db", "DocID", {"revs": true})</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned JSON object includes the original document and\n a <code>_revisions</code> structure that includes the revision\n information:\n <pre>\n {\n   "servings":4,\n   "subtitle":"Delicious with a green salad",\n   "_id":"FishStew",\n   "title":"Irish Fish Stew",\n   "_revisions":\n   {\n     "ids": [\n       "a1a9b39ee3cc39181b796a69cb48521c",\n       "7c4740b4dcf26683e941d6641c00c39d",\n       "9c65296036141e575d32ba9c034dd3ee"\n      ],\n     "start":3\n  },\n  "_rev":"3-a1a9b39ee3cc39181b796a69cb48521c"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The meaning of the additional fields is the following:\n <ul>\n   <li>_revisions: document revisions</li>\n   <li>_ids: array of valid revision IDs, in reverse order (latest first)</li>\n   <li>start: prefix number for the latest revision</li>\n </ul>\n </p>\n <h4 xmlns:xqdoc="http://www.xqdoc.org/1.0">Obtaining an Extended Revision History</h4>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">You can get additional information about the revisions for a given document\n with the <code>revs_info</code> option.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:document($connection, "db", "DocID", {"revs_info": true})</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This returns extended revision information, including the availability and status\n of each revision:\n <pre>\n {\n   "servings":4,\n   "subtitle":"Delicious with a green salad",\n   "_id":"FishStew",\n   "_revs_info":[\n     {\n       "status":"available",\n       "rev":"3-a1a9b39ee3cc39181b796a69cb48521c"\n     },\n     {\n       "status":"available",\n       "rev":"2-7c4740b4dcf26683e941d6641c00c39d"\n     },\n     {\n       "status":"available",\n       "rev":"1-9c65296036141e575d32ba9c034dd3ee"\n     }\n   ],\n   "title":"Irish Fish Stew",\n   "_rev":"3-a1a9b39ee3cc39181b796a69cb48521c"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The meaning of the additional fields is the following:\n <ul>\n   <li>_revs_info: document extended revision info</li>\n   <li>rev: revision ID</li>\n   <li>status: revision status</li>\n </ul>\n </p>\n',summary:"<p>  Retrieves a document from the specified database \n  This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"document-id",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A document identifier</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"The specified document"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DATABASE-NAME Invalid database name</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:DOCUMENT The specified document or revision cannot be found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:1,name:"list-databases-nondeterministic",qname:"cloudant:list-databases-nondeterministic",signature:"($connection as anyURI) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an array containing the names of all the user\'s databases.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-databases-1">list-databases#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns an array containing the names of all the user's databases.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'}],returns:{type:"array()",description:"An array of all the database names"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:2,name:"list-databases-nondeterministic",qname:"cloudant:list-databases-nondeterministic",signature:"($connection as anyURI, $options as object()) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an array containing the names of all the user\'s databases.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#list-databases-2">list-databases#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Returns an array containing the names of all the user's databases.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"array()",description:"An array of all the databases names"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:1,name:"list-databases",qname:"cloudant:list-databases",signature:"($connection as anyURI) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an array containing the names of all the user\'s databases.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:list-databases($connection)</pre>.\n </p>\n',summary:"<p>  Returns an array containing the names of all the user's databases.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'}],returns:{type:"array()",description:"An array of all the database names"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:2,name:"list-databases",qname:"cloudant:list-databases",signature:"($connection as anyURI, $options as object()) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an array containing the names of all the user\'s databases.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>database-owner: specifies the database owner (string, default: connection user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:list-databases($connection, {"database-owner" : "username"})</pre>.\n </p>\n',summary:"<p>  Returns an array containing the names of all the user's databases.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"array()",description:"An array of all the databases names"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:5,name:"lucene-query-nondeterministic",qname:"cloudant:lucene-query-nondeterministic",signature:"($connection as anyURI, $database as string, $design-document as string, $index as string, $query as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Executes a Lucene query against a view and returns the query result.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#lucene-query-5">lucene-query#5</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Executes a Lucene query against a view and returns the query result.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"index",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An index name</div>'},{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A Lucene query</div>'}],returns:{type:"object()",description:"The Lucene query results"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:6,name:"lucene-query-nondeterministic",qname:"cloudant:lucene-query-nondeterministic",signature:"($connection as anyURI, $database as string, $design-document as string, $index as string, $query as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Executes a Lucene query against a view and returns the query result.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#lucene-query-6">lucene-query#6</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Executes a Lucene query against a view and returns the query result.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"index",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An index name</div>'},{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A Lucene query</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"The Lucene query results"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:5,name:"lucene-query",qname:"cloudant:lucene-query",signature:"($connection as anyURI, $database as string, $design-document as string, $index as string, $query as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Executes a Lucene query against a view and returns the query result.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This method searches for documents whose index fields match the Lucene query.\n Which fields of a document are indexed and how is determined by the index functions\n in the design document.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:lucene-query($connection, "db", "designdoc", "view", "a*")</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "total_rows": 3,\n   "bookmark": "g1AAAACWeJzLYWBgYMpgTmFQSElKzi9KdUhJMtbLTS3KLElMT9VLzskvTUnMK9HLSy3JAalMcgCSSfX____PAvPdQHwQSGTIIt6UPBaQlgNA6j_CJPsPcJOyANNEKzY",\n   "rows":\n   [\n     {\n       "id": "dd828eb4-c3f1-470f-aeff-c375ef70e4ad",\n       "order": [0.0, 1],\n       "fields":\n       {\n         "default": "aa",\n         "foo": 0.0\n       }\n     },\n     {\n       "id": "ea522cf1-eb8e-4477-aa92-d1fa459bb216",\n       "order": [1.0, 0],\n       "fields":\n       {\n         "default": "ab",\n         "foo": 1.0\n       }\n     },\n     {\n       "id": "c838baed-d573-43ea-9c34-621cf0f13301",\n       "order": [2.0, 0],\n       "fields":\n       {\n         "default": "ac",\n         "foo": 2.0\n       }\n     }\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>total_rows: number of results returned.</li>\n  <li>bookmark: string to be submitted in the next query to page through results.\n      If this response contained no results, the bookmark will be the same as the\n      one used to obtain this response.</li>\n  <li>rows: array of document objects, each document contains the following fields:\n    <ul>\n      <li>order: specifies the order with regard to the indexed fields.</li>\n      <li>fields: Object containing other search indexes.</li>\n    </ul>\n  </li>\n </ul>\n </p>\n',summary:"<p>  Executes a Lucene query against a view and returns the query result.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"index",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An index name</div>'},{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A Lucene query</div>'}],returns:{type:"object()",description:"The Lucene query results"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:6,name:"lucene-query",qname:"cloudant:lucene-query",signature:"($connection as anyURI, $database as string, $design-document as string, $index as string, $query as string, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Executes a Lucene query against a view and returns the query result.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This method searches for documents whose index fields match the Lucene query.\n Which fields of a document are indexed and how is determined by the index functions\n in the design document.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>bookmark: A bookmark that was received from a previous search. This\n   allows you to page through the results. If there are no more results after\n   the bookmark, you will get a response with an empty rows array and the\n   same bookmark. That way you can determine that you have reached the end\n   of the result list (string).</li>\n   <li>stale: allow the results from a stale view to be used (string, allowed\n   value: "ok").</li>\n   <li>limit: limit the number of the returned documents to the specified\n   number (numeric).</li>\n   <li>include_docs: include the full content of the documents in the return\n   (boolean, default: false).</li>\n   <li>sort: specifies the sort order of the results. A JSON string of the\n   form <code>"fieldname&lt;type&gt;"</code> or <code>-fieldname&lt;type&gt;</code>\n   for descending order, where fieldname is the name of a string or number field\n   and type is either number or string. The type part is optional and defaults\n   to number. Some examples are <code>"foo"</code>, <code>"-foo"</code>,\n   <code>"bar&lt;string&gt;"</code>, <code>"-foo&lt;number&gt;"</code>. String\n   fields used for sorting must not be analyzed fields. The field(s) used for\n   sorting must be indexed by the same indexer used for the search query.\n   Alternatively, a JSON array of such strings is allowed.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:lucene-query($connection, "db", "designdoc", "view", "a*",\n {"database-owner": "username"})</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "total_rows": 3,\n   "bookmark": "g1AAAACWeJzLYWBgYMpgTmFQSElKzi9KdUhJMtbLTS3KLElMT9VLzskvTUnMK9HLSy3JAalMcgCSSfX____PAvPdQHwQSGTIIt6UPBaQlgNA6j_CJPsPcJOyANNEKzY",\n   "rows":\n   [\n     {\n       "id": "dd828eb4-c3f1-470f-aeff-c375ef70e4ad",\n       "order": [0.0, 1],\n       "fields":\n       {\n         "default": "aa",\n         "foo": 0.0\n       }\n     },\n     {\n       "id": "ea522cf1-eb8e-4477-aa92-d1fa459bb216",\n       "order": [1.0, 0],\n       "fields":\n       {\n         "default": "ab",\n         "foo": 1.0\n       }\n     },\n     {\n       "id": "c838baed-d573-43ea-9c34-621cf0f13301",\n       "order": [2.0, 0],\n       "fields":\n       {\n         "default": "ac",\n         "foo": 2.0\n       }\n     }\n   ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>total_rows: number of results returned.</li>\n  <li>bookmark: string to be submitted in the next query to page through results.\n      If this response contained no results, the bookmark will be the same as the\n      one used to obtain this response.</li>\n  <li>rows: array of document objects, each document contains the following fields:\n    <ul>\n      <li>order: specifies the order with regard to the indexed fields.</li>\n      <li>fields: Object containing other search indexes.</li>\n    </ul>\n  </li>\n </ul>\n </p>\n',summary:"<p>  Executes a Lucene query against a view and returns the query result.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"index",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An index name</div>'},{name:"query",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A Lucene query</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"The Lucene query results"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:3,name:"multiple-documents-nondeterministic",qname:"cloudant:multiple-documents-nondeterministic",signature:"($connection as anyURI, $database as string, $keys as string*) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">List the specified documents in a given database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#multiple-documents-3">multiple-documents#3</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  List the specified documents in a given database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the documents which must be retrieved</div>'}],returns:{type:"object()",description:"An object listing the specified documents in the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"multiple-documents-nondeterministic",qname:"cloudant:multiple-documents-nondeterministic",signature:"($connection as anyURI, $database as string, $keys as string*, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the specified documents in a given database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#multiple-documents-4">multiple-documents#4</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the specified documents in a given database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the documents which must be retrieved</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object listing the specified documents in the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:3,name:"multiple-documents",qname:"cloudant:multiple-documents",signature:"($connection as anyURI, $database as string, $keys as string*) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">List the specified documents in a given database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:multiple-documents($connection, "db",\n   ("5a049246-179f-42ad-87ac-8f080426c17c",\n    "d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n    "96f898f0-f6ff-4a9b-aac4-503992f31b01"))</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "total_rows":3,\n   "offset":0,\n   "rows":[\n   {\n     "id":"5a049246-179f-42ad-87ac-8f080426c17c",\n     "key":"5a049246-179f-42ad-87ac-8f080426c17c",\n     "value":\n     {\n       "rev":"2-9d5401898196997853b5ac4163857a29"\n     }\n   },\n   {\n     "id":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n     "key":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n     "value":\n     {\n       "rev":"2-ff7b85665c4c297838963c80ecf481a3"\n      }\n   },\n   {\n     "id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "key":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "value":\n     {\n       "rev":"2-cbdef49ef3ddc127eff86350844a6108"\n     }\n   }]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>offset: offset where the document list started.</li>\n  <li>rows: array of document objects, each containing id, key and revision number.</li>\n  <li>total_rows: number of documents in the database.</li>\n  <li>update_seq: current update sequence database.</li>\n </ul>\n </p>\n',summary:"<p>  List the specified documents in a given database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the documents which must be retrieved</div>'}],returns:{type:"object()",description:"An object listing the specified documents in the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:4,name:"multiple-documents",qname:"cloudant:multiple-documents",signature:"($connection as anyURI, $database as string, $keys as string*, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the specified documents in a given database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>descending: return the documents in descending by key order (boolean,\n   default: false).</li>\n   <li>endkey: stop returning records when the specified key is reached (string).</li>\n   <li>endkey_docid: stop returning records when the specified document ID is\n   reached (string).</li>\n   <li>group: group the results using the reduce function to a group or single\n   row (boolean, default: false).</li>\n   <li>group_level: specify the group level to be used (numeric).</li>\n   <li>include_docs: include the full content of the documents in the return\n   (boolean, default: false).</li>\n   <li>inclusive_end: specifies whether the specified end key should be included\n   in the result (boolean, default: true).</li>\n   <li>key: return only documents that match the specified key (string).</li>\n   <li>limit: limit the number of the returned documents to the specified number\n   (numeric).</li>\n   <li>reduce: use the reduction function (boolean, default: true).</li>\n   <li>skip: skip this number of records before starting to return the results\n   (numeric, default: 0).</li>\n   <li>stale: allow the results from a stale view to be used (string, allowed\n   value: "ok").</li>\n   <li>startkey: start returning records when the specified key is reached\n   (string).</li>\n   <li>startkey_docid: start returning records when the specified document ID\n   is reached (string).</li>\n   <li>database-owner: specifies the database owner (string, default: connection\n   user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:multiple-documents($connection, "db",\n   ("5a049246-179f-42ad-87ac-8f080426c17c",\n    "d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n    "96f898f0-f6ff-4a9b-aac4-503992f31b01"),\n   {"database-owner": "username"})</pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "total_rows":3,\n   "offset":0,\n   "rows":[\n   {\n     "id":"5a049246-179f-42ad-87ac-8f080426c17c",\n     "key":"5a049246-179f-42ad-87ac-8f080426c17c",\n     "value":\n     {\n       "rev":"2-9d5401898196997853b5ac4163857a29"\n     }\n   },\n   {\n     "id":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n     "key":"96f898f0-f6ff-4a9b-aac4-503992f31b01",\n     "value":\n     {\n       "rev":"2-ff7b85665c4c297838963c80ecf481a3"\n      }\n   },\n   {\n     "id":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "key":"d1f61e66-7708-4da6-aa05-7cbc33b44b7e",\n     "value":\n     {\n       "rev":"2-cbdef49ef3ddc127eff86350844a6108"\n     }\n   }]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>offset: offset where the document list started.</li>\n  <li>rows: array of document objects, each containing id, key and revision number.</li>\n  <li>total_rows: number of documents in the database.</li>\n  <li>update_seq: current update sequence database.</li>\n </ul>\n </p>\n',summary:"<p>  Lists the specified documents in a given database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the documents which must be retrieved</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object listing the specified documents in the specified database"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:5,name:"multiple-view-documents-nondeterministic",qname:"cloudant:multiple-view-documents-nondeterministic",signature:"($connection as anyURI, $database as string, $design-document as string, $view as string, $keys as string*) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">List the specified documents in a given view.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#multiple-view-documents-5">multiple-view-documents#5</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  List the specified documents in a given view.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"view",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A view name</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the documents which must be retrieved</div>'}],returns:{type:"object()",description:"An object listing all the specified documents in the specified view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:6,name:"multiple-view-documents-nondeterministic",qname:"cloudant:multiple-view-documents-nondeterministic",signature:"($connection as anyURI, $database as string, $design-document as string, $view as string, $keys as string*, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the specified documents in a given view.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#multiple-view-documents-6">multiple-view-documents#6</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p>  Lists the specified documents in a given view.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"view",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A view name</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the documents which must be retrieved</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object listing all the specified documents in the specified view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']},{isDocumented:!0,arity:5,name:"multiple-view-documents",qname:"cloudant:multiple-view-documents",signature:"($connection as anyURI, $database as string, $design-document as string, $view as string, $keys as string*) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">List the specified documents in a given view.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:multiple-view-documents($connection, "db", "recipes", "by_ingredient",\n ("claret", "clear apple juice"))\n </pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "total_rows" : 26484,\n   "rows" : [\n     {\n       "value" : ["Scotch collops"]],\n       "id" : "Scotchcollops",\n       "key" : "claret"\n     },\n     {\n       "value" : ["Stand pie"],\n       "id" : "Standpie",\n       "key" : "clear apple juice"\n     }\n   ],\n   "offset" : 6324\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>offset: offset where the document list started.</li>\n  <li>rows: array of document objects, each containing id, key and revision\n  number.</li>\n  <li>total_rows: number of documents in the database.</li>\n  <li>update_seq: current update sequence database.</li>\n </ul>\n </p>\n',summary:"<p>  List the specified documents in a given view.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"view",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A view name</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the documents which must be retrieved</div>'}],returns:{type:"object()",description:"An object listing all the specified documents in the specified view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>']},{isDocumented:!0,arity:6,name:"multiple-view-documents",qname:"cloudant:multiple-view-documents",signature:"($connection as anyURI, $database as string, $design-document as string, $view as string, $keys as string*, $options as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Lists the specified documents in a given view.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The information is returned as a JSON structure containing meta information\n about the return structure, and the list of documents each with its ID, revision\n and key. The key is generated from the document ID.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function allows to specify an additional options object.\n The following options are supported:\n <ul>\n   <li>descending: return the documents in descending by key order (boolean,\n   default: false).</li>\n   <li>endkey: stop returning records when the specified key is reached (string).</li>\n   <li>endkey_docid: stop returning records when the specified document ID is\n   reached (string).</li>\n   <li>group: group the results using the reduce function to a group or single\n   row (boolean, default: false).</li>\n   <li>group_level: specify the group level to be used (numeric).</li>\n   <li>include_docs: include the full content of the documents in the return\n   (boolean, default: false).</li>\n   <li>inclusive_end: specifies whether the specified end key should be included\n   in the result (boolean, default: true).</li>\n   <li>key: return only documents that match the specified key (string).</li>\n   <li>limit: limit the number of the returned documents to the specified number\n   (numeric).</li>\n   <li>reduce: use the reduction function (boolean, default: true).</li>\n   <li>skip: skip this number of records before starting to return the results\n   (numeric, default: 0).</li>\n   <li>stale: allow the results from a stale view to be used (string, allowed\n   value: "ok").</li>\n   <li>startkey: start returning records when the specified key is reached\n   (string).</li>\n   <li>startkey_docid: start returning records when the specified document ID\n   is reached (string).</li>\n   <li>database-owner: specifies the database owner (string, default: connection\n   user).</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <pre>cloudant:multiple-view-documents($connection, "db", "recipes",\n   "by_ingredient", ("claret", "clear apple juice"),\n   {"database-owner": "username"})\n </pre>.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">An object with the following format is returned:\n <pre>\n {\n   "total_rows" : 26484,\n   "rows" : [\n     {\n       "value" : ["Scotch collops"]],\n       "id" : "Scotchcollops",\n       "key" : "claret"\n     },\n     {\n       "value" : ["Stand pie"],\n       "id" : "Standpie",\n       "key" : "clear apple juice"\n     }\n   ],\n   "offset" : 6324\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The fields have the following meaning:\n <ul>\n  <li>offset: offset where the document list started.</li>\n  <li>rows: array of document objects, each containing id, key and revision number.</li>\n  <li>total_rows: number of documents in the database.</li>\n  <li>update_seq: current update sequence database.</li>\n </ul>\n </p>\n',summary:"<p>  Lists the specified documents in a given view.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A connection identifier</div>'},{name:"database",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A database name</div>'},{name:"design-document",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A design document name</div>'},{name:"view",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A view name</div>'},{name:"keys",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The keys of the documents which must be retrieved</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An object specifying additional request options</div>'}],returns:{type:"object()",description:"An object listing all the specified documents in the specified view"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:AUTHORIZATION Authorization error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:HTTP An HTTP error occurred when issuing the request</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:RESPONSE An error occurred parsing the server response</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:CONNECTION The specified connection does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:INTERNAL Cloudant internal error</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">cloudant:OPTIONS Malformed options object</xqdoc:error>']}],variables:[]},"http://api.28.io/exportimport":{ns:"http://api.28.io/exportimport",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/collections",prefix:"cm"},{uri:"http://api.28.io/exportimport",prefix:"exportimport"},{uri:"http://zorba.io/modules/fetch",prefix:"fetch"},{uri:"http://api.28.io/indices",prefix:"in"},{uri:"http://www.28msec.com/modules/maps",prefix:"map"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://www.28msec.com/modules/http/response",prefix:"resp"},{uri:"http://www.28msec.com/modules/store",prefix:"store"},{uri:"http://api.28.io/validation",prefix:"validate"}],functions:[{isDocumented:!1,arity:1,name:"create-map",qname:"exportimport:create-map",signature:"($map as object())",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"map",type:"object()",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"export",qname:"exportimport:export",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"import",qname:"exportimport:import",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"import",qname:"exportimport:import",signature:"($import as object(), $overwrite as xs:boolean)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"import",type:"object()",occurrence:null,description:""},{name:"overwrite",type:"xs:boolean",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"is-system-collection",qname:"exportimport:is-system-collection",signature:"($name as xs:string) as xs:boolean",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!1,arity:1,name:"validate-map",qname:"exportimport:validate-map",signature:"($map as object()) as empty-sequence()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"map",type:"object()",occurrence:null,description:""}],returns:{type:"empty-sequence()",description:""},errors:[]}],variables:[]},"http://jsoniq.org/errors":{ns:"http://jsoniq.org/errors",description:" This module contains one variable declaration for each diagnostic of the\n http://jsoniq.org/errors namespace.\n The variables serves as documentation for the errors but can also\n be used in the code. For example, one useful scenario is to compare\n an error caught in the catch clause of a try-catch expression with one of\n the variables.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Carlos Lopez</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://jsoniq.org/errors",prefix:"jerr"}],functions:[],variables:[{name:"jerr:JNSE0013",type:"xs:QName",description:"It is a dynamic error to serialize an atomic value not\n supported by JSON or a node with the JSON output method and with\n the jsoniq-serialization-extensions serialization parameter\n set to false.\n"},{name:"jerr:JNDY0021",type:"xs:QName",description:"parser error raised by jn:parse-json\n"},{name:"jerr:JNTY0021",type:"xs:QName",description:"array or object selector on heterogeneous sequence\n"},{name:"jerr:JNTY0020",type:"xs:QName",description:"parser error for invalid option type\n"},{name:"jerr:JNTY0024",type:"xs:QName",description:"objects or arrays don't have a string value\n"},{name:"jerr:JNTY0023",type:"xs:QName",description:"It is a type error if the prefix is not a string or if the\n serialization parameters are not an element.\n"},{name:"jerr:JNUP0019",type:"xs:QName",description:"It is a dynamic error if the content expression, in an object insert expression, does not evaluate to a sequence of objects.\n"},{name:"jerr:JNTY0018",type:"xs:QName",description:"It is a dynamic error if there is not exactly one supplied parameter for an object or array selector.\n"},{name:"jerr:JNUP0017",type:"xs:QName",description:" It is a dynamic error if the value in a replace expression is not exactly a single item.\n"},{name:"jerr:JNUP0016",type:"xs:QName",description:"It is a dynamic error if it is attempted to create a replace, delete or rename update primitive with a selector that cannot be resolved against the target array or object.\n"},{name:"jerr:JNSE0022",type:"xs:QName",description:"It is a dynamic error to serialize a sequence that does\n not exist of exactly one document node with XML, HTML, XHTML, Text.\n"},{name:"jerr:JNSE0014",type:"xs:QName",description:"It is a dynamic error to serialize a function or a node with the\n JSON output method.\n"},{name:"jerr:NS",type:"item()*",description:""},{name:"jerr:JNSE0012",type:"xs:QName",description:"It is a dynamic error to serialize a sequence of less\n or more than one item with the JSON output method if the\n jsoniq-serialization-multiple-items is set to no.\n"},{name:"jerr:JNTY0011",type:"xs:QName",description:"It is a type error if the content sequence in a node constructor or in an XQUF insert or replace update expression contains an object or an array.\n"},{name:"jerr:JNUP0010",type:"xs:QName",description:"It is a dynamic error if a pending update list contains two renaming update primitives on the same object and with the same selector.\n"},{name:"jerr:JNUP0009",type:"xs:QName",description:"It is a dynamic error if a pending update list contains two replacing update primitives on the same object or array, and with the same selector.\n"},{name:"jerr:JNUP0008",type:"xs:QName",description:"It is a dynamic error if the target of a deleting or replacing expression is not an array or an object.\n It is a dynamic error if the target of a renaming expression is not an object.\n It is a dynamic error if the target of an appending expression is not an array.\n It is a dynamic error if the target of a position-inserting expression is not an array.\n It is a dynamic error if the target of a non-position-inserting expression is not an object.\n"},{name:"jerr:JNUP0007",type:"xs:QName",description:"It is a type error if, in an updating expression, an array selector cannot be cast to xs:integer or if an object selector cannot be cast to xs:string.\n"},{name:"jerr:JNUP0006",type:"xs:QName",description:"It is a dynamic error if upd:applyUpdates causes an object to contain two pairs with the same name.\n"},{name:"jerr:JNUP0005",type:"xs:QName",description:"It is a dynamic error if a pending update list contains two inserting update primitives on the same object and pair name.\n"},{name:"jerr:JNTY0004",type:"xs:QName",description:"It is a type error to call fn:data on a sequence containing an array or an object.\n"},{name:"jerr:JNDY0003",type:"xs:QName",description:"It is a dynamic error if two pairs in an object constructor or in a simple object union have the same name.\n"},{name:"jerr:JNTY0002",type:"xs:QName",description:"It is a type error if the right-hand-side expression of a pair constructor does not return exactly one item.\n"}]},"http://zorba.io/modules/sctx":{ns:"http://zorba.io/modules/sctx",description:" This module provides functions that gets components of the static context.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.w3.org/TR/xquery/#id-xq-static-context-components</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Nicolae Brinza</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/sctx",prefix:"sctx"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"base-uri",qname:"sctx:base-uri",signature:"() as xs:string? external",description:" Gets the base URI.\n",summary:"<p> Gets the base URI.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string?",description:"The base URI."},errors:[]},{isDocumented:!0,arity:0,name:"boundary-space-policy",qname:"sctx:boundary-space-policy",signature:"() as xs:string external",description:" Gets the boundary whitespace policy used by direct element constructors.\n",summary:"<p> Gets the boundary whitespace policy used by direct element constructors.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:'Either <code xmlns:xqdoc="http://www.xqdoc.org/1.0">preserve</code> or <code xmlns:xqdoc="http://www.xqdoc.org/1.0">strip</code>.'},errors:[]},{isDocumented:!0,arity:0,name:"construction-mode",qname:"sctx:construction-mode",signature:"() as xs:string external",description:" Gets the static context construction mode of element and document nodes.\n",summary:"<p> Gets the static context construction mode of element and document nodes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:'Either <code xmlns:xqdoc="http://www.xqdoc.org/1.0">preserve</code> or <code xmlns:xqdoc="http://www.xqdoc.org/1.0">strip</code>.'},errors:[]},{isDocumented:!0,arity:0,name:"copy-namespaces-mode",qname:"sctx:copy-namespaces-mode",signature:"() as xs:string+ external",description:" Gets the static context components that control the the namespace bindings\n that are assigned when an existing element node is copied\n by an element constructor.\n",summary:"<p> Gets the static context components that control the the namespace bindings\n that are assigned when an existing element node is copied\n by an element constructor.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string+",description:'A sequence of two strings: the first is either <code xmlns:xqdoc="http://www.xqdoc.org/1.0">preserve</code> or <code xmlns:xqdoc="http://www.xqdoc.org/1.0">no-preserve</code> and the second is either <code xmlns:xqdoc="http://www.xqdoc.org/1.0">inherit</code> or <code xmlns:xqdoc="http://www.xqdoc.org/1.0">no-inherit</code>.'},errors:[]},{isDocumented:!0,arity:0,name:"default-collation",qname:"sctx:default-collation",signature:"() as xs:string external",description:' Gets one of statically known collations used by functions and operators\n for comparing and ordering values of type <code xmlns:xqdoc="http://www.xqdoc.org/1.0">xs:string</code>\n or <code xmlns:xqdoc="http://www.xqdoc.org/1.0">xs:anyURI</code> when no explicit collation is specified.\n',summary:"<p> Gets one of statically known collations used by functions and operators\n for comparing and ordering values of type  xs:string \n or  xs:anyURI  when no explicit collation is specified.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The collations that is used by default."},errors:[]},{isDocumented:!0,arity:0,name:"default-collection-type",qname:"sctx:default-collection-type",signature:"() as xs:string external",description:' Gets the statically known default collection type.\n This is the type of the sequence of nodes that would result from calling the\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">fn:collection</code> function with no arguments.\n',summary:"<p> Gets the statically known default collection type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The type of the default collection."},errors:[]},{isDocumented:!0,arity:0,name:"default-function-namespace",qname:"sctx:default-function-namespace",signature:"() as xs:string external",description:" Gets the URI of the default function namespace.\n",summary:"<p> Gets the URI of the default function namespace.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The URI of the of the default function namespace."},errors:[]},{isDocumented:!0,arity:0,name:"default-order",qname:"sctx:default-order",signature:"() as xs:string external",description:' Gets the component that controls the processing of empty sequences and NaN\n values as ordering keys in an <code xmlns:xqdoc="http://www.xqdoc.org/1.0">order by</code> clause\n in a FLWOR expression.\n',summary:"<p> Gets the component that controls the processing of empty sequences and NaN\n values as ordering keys in an  order by  clause\n in a FLWOR expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:'Either <code xmlns:xqdoc="http://www.xqdoc.org/1.0">greatest</code> or <code xmlns:xqdoc="http://www.xqdoc.org/1.0">least</code>.'},errors:[]},{isDocumented:!0,arity:2,name:"function-annotations",qname:"sctx:function-annotations",signature:"($name as xs:QName, $arity as xs:integer) as xs:QName* external",description:" Gets the list of annotations declared for the given function.\n",summary:"<p> Gets the list of annotations declared for the given function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the function.</div>'},{name:"arity",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of arguments the function takes.</div>'}],returns:{type:"xs:QName*",description:"the list of annotations"},errors:[]},{isDocumented:!0,arity:1,name:"function-arguments-count",qname:"sctx:function-arguments-count",signature:"($function as xs:QName) as xs:int* external",description:" Gets the number of arguments the given XQuery function takes.\n",summary:"<p> Gets the number of arguments the given XQuery function takes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"function",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A QName identifying a function.</div>'}],returns:{type:"xs:int*",description:"Either a sequence of zero or more integers (one for each overloaded version of the given function) or an empty sequence if the function is not defined."},errors:[]},{isDocumented:!0,arity:0,name:"function-names",qname:"sctx:function-names",signature:"() as xs:QName* external",description:" Gets a sequence containing the QNames of all defined functions\n that are available to be called from within an expression.\n",summary:"<p> Gets a sequence containing the QNames of all defined functions\n that are available to be called from within an expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence for QNames identifying all functions."},errors:[]},{isDocumented:!0,arity:0,name:"functions",qname:"sctx:functions",signature:"() as object()* external",description:" Gets a sequence of JSON objects containing the name, arity, and annotations\n of all defined functions that are available to be called form within an\n expression.\n",summary:"<p> Gets a sequence of JSON objects containing the name, arity, and annotations\n of all defined functions that are available to be called form within an\n expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"A sequence of objects."},errors:[]},{isDocumented:!0,arity:0,name:"in-scope-attribute-declarations",qname:"sctx:in-scope-attribute-declarations",signature:"() as xs:QName* external",description:" Gets a sequence of QNames identifying declared attributes\n in the imported schemas.\n",summary:"<p> Gets a sequence of QNames identifying declared attributes\n in the imported schemas.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each attribute."},errors:[]},{isDocumented:!0,arity:0,name:"in-scope-attribute-groups",qname:"sctx:in-scope-attribute-groups",signature:"() as xs:QName* external",description:" Gets a sequence of QNames identifying declared in-scope\n schema attribute groups.\n",summary:"<p> Gets a sequence of QNames identifying declared in-scope\n schema attribute groups.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each attribute group."},errors:[]},{isDocumented:!0,arity:0,name:"in-scope-element-declarations",qname:"sctx:in-scope-element-declarations",signature:"() as xs:QName* external",description:" Gets a sequence of QNames identifying declared elements\n in the imported schemas.\n",summary:"<p> Gets a sequence of QNames identifying declared elements\n in the imported schemas.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each declared element."},errors:[]},{isDocumented:!0,arity:0,name:"in-scope-element-groups",qname:"sctx:in-scope-element-groups",signature:"() as xs:QName* external",description:" Gets a sequence of QNames identifying declared in-scope\n schema element groups.\n",summary:"<p> Gets a sequence of QNames identifying declared in-scope\n schema element groups.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each element group."},errors:[]},{isDocumented:!0,arity:0,name:"in-scope-schema-types",qname:"sctx:in-scope-schema-types",signature:"() as xs:QName* external",description:" Gets a sequence of QNames identifying in-scope schema types\n including all the predefined schema types and all definitions\n found in imported schemas.\n",summary:"<p> Gets a sequence of QNames identifying in-scope schema types\n including all the predefined schema types and all definitions\n found in imported schemas.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each defined type."},errors:[]},{isDocumented:!0,arity:0,name:"in-scope-variables",qname:"sctx:in-scope-variables",signature:"() as xs:QName* external",description:" Gets a sequence of QNames identifying declared variables\n from the static context.\n",summary:"<p> Gets a sequence of QNames identifying declared variables\n from the static context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each variable."},errors:[]},{isDocumented:!0,arity:1,name:"option",qname:"sctx:option",signature:"($name as xs:QName) as xs:string? external",description:" Gets the value of an option that is declared in the prolog of the module.\n",summary:"<p> Gets the value of an option that is declared in the prolog of the module.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the option value to retrieve</div>'}],returns:{type:"xs:string?",description:"the value of the option if contained in the static context or the empty sequence otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"ordering-mode",qname:"sctx:ordering-mode",signature:"() as xs:string external",description:" Gets the ordering mode that affects the ordering of the result sequences\n returned by certain expressions.\n",summary:"<p> Gets the ordering mode that affects the ordering of the result sequences\n returned by certain expressions.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:'Either <code xmlns:xqdoc="http://www.xqdoc.org/1.0">ordered</code> or <code xmlns:xqdoc="http://www.xqdoc.org/1.0">unordered</code>.'},errors:[]},{isDocumented:!0,arity:0,name:"statically-known-collations",qname:"sctx:statically-known-collations",signature:"() as xs:anyURI* external",description:" Gets a sequence that contains the statically known collations.\n",summary:"<p> Gets a sequence that contains the statically known collations.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyURI*",description:"The sequence of collations."},errors:[]},{isDocumented:!0,arity:1,name:"statically-known-document-type",qname:"sctx:statically-known-document-type",signature:"($document as xs:string) as xs:QName external",description:" For the given document, returns the static type of its root node.\n",summary:"<p> For the given document, returns the static type of its root node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"document",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A URI of a document.</div>'}],returns:{type:"xs:QName",description:"The static type of the given document."},errors:[]},{isDocumented:!0,arity:0,name:"statically-known-documents",qname:"sctx:statically-known-documents",signature:"() as xs:anyURI* external",description:" Gets a sequence that contains the URIs of all statically known documents.\n",summary:"<p> Gets a sequence that contains the URIs of all statically known documents.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:anyURI*",description:"The sequence of document URIs."},errors:[]},{isDocumented:!0,arity:1,name:"statically-known-namespace-binding",qname:"sctx:statically-known-namespace-binding",signature:"($prefix as xs:string) as xs:string? external",description:" Gets the bound URI for the given prefix.\n",summary:"<p> Gets the bound URI for the given prefix.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"prefix",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The prefix of the known namespace for which the bound URI is being requested.</div>'}],returns:{type:"xs:string?",description:"The URI bound to the prefix is returned, or an empty sequence if the prefix is not known."},errors:[]},{isDocumented:!0,arity:0,name:"statically-known-namespaces",qname:"sctx:statically-known-namespaces",signature:"() as xs:string* external",description:" Gets a list of known statically known namespaces as prefixes\n (fn, xml, xs, xsi, etc).\n",summary:"<p> Gets a list of known statically known namespaces as prefixes\n (fn, xml, xs, xsi, etc).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"A sequence of xs:strings, one for each known namespace prefix."},errors:[]},{isDocumented:!0,arity:0,name:"xpath10-compatibility-mode",qname:"sctx:xpath10-compatibility-mode",signature:"() as xs:boolean external",description:" Gets true or false depending on whether rules for compatibility\n with XPath 1.0 are in effect.\n XQuery set the value of this component to false.\n",summary:"<p> Gets true or false depending on whether rules for compatibility\n with XPath 1.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:'The function should return <code xmlns:xqdoc="http://www.xqdoc.org/1.0">false</code>.'},errors:[]}],variables:[]},"http://xbrl.io/modules/bizql/profiles/sec/import":{ns:"http://xbrl.io/modules/bizql/profiles/sec/import",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for querying XBRL Infosets of financial reports submitted to the SEC.\n </p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/entities",prefix:"entities"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/import",prefix:"imp"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"m"},{uri:"http://zorba.io/modules/string",prefix:"string"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"disclosure-for-network-label",qname:"imp:disclosure-for-network-label",signature:"($component as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n Compute the disclore for a component\'s network label.\n </p>\n',summary:"<p>  \n Compute the disclore for a component's network label.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"component",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the component</div>'}],returns:{type:"object()",description:"returns the given component ammended with the disclosure"},errors:[]}],variables:[{name:"imp:disclosure-matching",type:"object()",description:" Declarative description of the disclosure matching heuristics.\n"}]},"http://xbrl.io/modules/bizql/profiles/sec/core":{ns:"http://xbrl.io/modules/bizql/profiles/sec/core",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for querying XBRL Models of financial reports submitted to the SEC.\n </p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="standard_options">Standard <code>$options</code> Parameter</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Most functions in the BizQL package allow an additional <code>$options</code>\n    parameter. The options parameter is a JSON object which is defined in the documentation\n    of the <a href="../../facts#standard_options">facts module</a>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition to the option fields defined in the\n    <a href="../../facts#standard_options">facts module</a> the following\n    fields can be used in the options of a function in the SEC profile:</p>\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n <li><b>HideAmendedFacts</b>: if set to true (default behavior) all facts that have been\n     amended are not included in the result.</li>\n <li><b>IncludeImpliedTable</b>: set to true in order to output the implied table if\n     there is no Table (default is false).</li>\n </ul>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/concept-maps",prefix:"concept-maps"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/entities",prefix:"entities"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://xbrl.io/modules/bizql/hypercubes",prefix:"hypercubes"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"m"},{uri:"http://xbrl.io/modules/bizql/report-schemas",prefix:"report-schemas"},{uri:"http://xbrl.io/modules/bizql/profiles/sec/core",prefix:"sec"},{uri:"http://zorba.io/modules/string",prefix:"string"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"edgar-facts-for-archives",qname:"sec:edgar-facts-for-archives",signature:"($archive_or_ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all facts for concepts that are defined by one of the common\n edgar taxonomies. In particular, this function returns facts for concepts\n having one of the following prefixes:</p>\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>xbrli</li>\n   <li>link</li>\n   <li>xl</li>\n   <li>xlink</li>\n   <li>xbrldt</li>\n   <li>xbrldi</li>\n   <li>nonnum</li>\n   <li>num</li>\n   <li>ref</li>\n   <li>us-gaap</li>\n   <li>dei</li>\n   <li>us-types</li>\n   <li>invest</li>\n   <li>country</li>\n   <li>currency</li>\n   <li>exch</li>\n   <li>naics</li>\n   <li>sic</li>\n   <li>stpr</li>\n   <li>rr</li>\n   <li>rr-ent</li>\n   <li>rr-cal</li>\n   <li>rr-def</li>\n   <li>rr-pre</li>\n </ul>\n',summary:"<p>  Return all facts for concepts that are defined by one of the common\n edgar taxonomies.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive_or_ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archive or archive IDs to filter.</div>'}],returns:{type:"object()*",description:"all facts having one of the above prefixes."},errors:[]},{isDocumented:!0,arity:1,name:"end-date",qname:"sec:end-date",signature:"($filing-fact-or-id as item()?) as xs:date?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the document end date of a filing or a fact.</p>\n',summary:"<p>  Retrieves the document end date of a filing or a fact.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"filing-fact-or-id",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a filing, a fact, or its id.</div>'}],returns:{type:"xs:date?",description:'the document end date (e.g., xs:date("2011-04-30")).'},errors:[]},{isDocumented:!0,arity:1,name:"extension-facts-for-archives",qname:"sec:extension-facts-for-archives",signature:"($archive_or_ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all facts for concepts that are NOT defined by one of the common\n edgar taxonomies. In particular, this function returns facts for concepts\n having none of the prefixes listed under function\n sec:edgar-facts-for-archives.</p>\n',summary:"<p>  Return all facts for concepts that are NOT defined by one of the common\n edgar taxonomies.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive_or_ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archive or archive IDs to filter.</div>'}],returns:{type:"object()*",description:"all facts having none of the common edgar prefixes."},errors:[]},{isDocumented:!0,arity:2,name:"fact-table-for-schema",qname:"sec:fact-table-for-schema",signature:"($schema as item(), $archives as item()*) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a report schema or its RID.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $sec:ALL_OF_THEM for no filtering.</div>'}],returns:{type:"array()",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:2,name:"facts-for-archives-and-concepts",qname:"sec:facts-for-archives-and-concepts",signature:"($archive_or_ids as item()*, $concepts as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the facts associated with the supplied concepts\n from the supplied archive, that match the fiscal focus of the archive.</p>\n',summary:"<p>  Retrieves the facts associated with the supplied concepts\n from the supplied archive, that match the fiscal focus of the archive.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive_or_ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their ids or $sec:ALL_OF_THEM for no filtering.</div>'},{name:"concepts",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the concepts or $sec:ALL_OF_THEM for no filtering.</div>'}],returns:{type:"object()*",description:"the latest facts associated with the supplied concept."},errors:[]},{isDocumented:!0,arity:3,name:"facts-for-archives-and-concepts",qname:"sec:facts-for-archives-and-concepts",signature:"($archive_or_ids as item()*, $concepts as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves the facts associated with the supplied concepts\n from the supplied archive, that match the fiscal focus of the archive.</p>\n',summary:"<p>  Retrieves the facts associated with the supplied concepts\n from the supplied archive, that match the fiscal focus of the archive.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive_or_ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their ids or $sec:ALL_OF_THEM for no filtering.</div>'},{name:"concepts",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the concepts or $sec:ALL_OF_THEM for no filtering.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="#standard_options">standard SEC BizQL options</a>.</div>'}],returns:{type:"object()*",description:"the latest facts associated with the supplied concept."},errors:[]},{isDocumented:!0,arity:2,name:"facts-for-schema",qname:"sec:facts-for-schema",signature:"($schema as item(), $archives as item()*) as item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema and to the fiscal focus, and populates\n them with the default dimension values when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema and to the fiscal focus, and populates\n them with the default dimension values when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a schema.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $sec:ALL_OF_THEM for no filtering.</div>'}],returns:{type:"item()*",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:1,name:"hide-amended-facts",qname:"sec:hide-amended-facts",signature:"($facts as object()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Filters a list of facts and returns only the latest amending facts.\n    Accordingly, all amended facts are filtered out.</p>\n',summary:"<p>  Filters a list of facts and returns only the latest amending facts.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"facts",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a list of facts.</div>'}],returns:{type:"object()*",description:"a sequence of facts without amended facts."},errors:[]},{isDocumented:!0,arity:2,name:"populate-schema-with-facts",qname:"sec:populate-schema-with-facts",signature:"($schema as item(), $archives as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied schema. Default dimension values are added to the facts\n when missing.</p>\n',summary:"<p>  Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied schema.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a report schema or its RID.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:3,name:"populate-schema-with-facts",qname:"sec:populate-schema-with-facts",signature:"($schema as item(), $archives as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied schema. Default dimension values are added to the facts\n when missing.</p>\n',summary:"<p>  Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied schema.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a report schema or its RID.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $sec:ALL_OF_THEM for no filtering.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="#standard_options">standard SEC BizQL options</a>.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated dimension values."},errors:[]}],variables:[{name:"sec:CIK",type:"xs:string",description:" Scheme for the SEC entity identifiers (i.e. http://www.sec.gov/CIK)\n"},{name:"sec:ALL_OF_THEM",type:"boolean",description:" Joker value for all archives or all concepts.\n"},{name:"sec:EDGAR_PREFIXES",type:"item()*",description:" All prefixes pre-declared in SEC's EDGAR.\n"}]},"http://zorba.io/modules/excel/logical":{ns:"http://zorba.io/modules/excel/logical",description:" This is a library module offering the same set of functions\n defined by Microsoft Excel, under Logical Functions.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://office.microsoft.com/en-us/excel/CH062528271033.aspx" target="_blank">Excel Documentation: Logical Functions</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Sorin Nasoi</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/excel/errors",prefix:"excel-err"},{uri:"http://zorba.io/modules/excel/logical",prefix:"excel-logical"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"and",qname:"excel-logical:and",signature:"($values as xs:anyAtomicType*) as xs:boolean",description:" Returns TRUE if all its arguments are TRUE; FALSE if one or more arguments are FALSE.\n",summary:"<p> Returns TRUE if all its arguments are TRUE; FALSE if one or more arguments are FALSE.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"values",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of arguments.</div>'}],returns:{type:"xs:boolean",description:"TRUE if all its arguments are TRUE; FALSE if one or more arguments are FALSE."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value provided sequence is empty.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"and",qname:"excel-logical:and",signature:"($arg1 as xs:anyAtomicType, $arg2 as xs:anyAtomicType) as xs:boolean",description:" Returns TRUE if all its arguments are TRUE; FALSE if one or more arguments are FALSE.\n",summary:"<p> Returns TRUE if all its arguments are TRUE; FALSE if one or more arguments are FALSE.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first argument.</div>'},{name:"arg2",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second argument.</div>'}],returns:{type:"xs:boolean",description:"TRUE if all its arguments are TRUE; FALSE if one or more arguments are FALSE."},errors:[]},{isDocumented:!0,arity:3,name:"if",qname:"excel-logical:if",signature:"($logical_test as xs:boolean, $value_if_true as item()*, $value_if_false as item()*) as item()*",description:" Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE.\n",summary:"<p> Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"logical_test",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> is any value or expression that can be evaluated to TRUE or FALSE.</div>'},{name:"value_if_true",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value that is returned if logical_test is TRUE.</div>'},{name:"value_if_false",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value that is returned if logical_test is FALSE.</div>'}],returns:{type:"item()*",description:"One value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE."},errors:[]},{isDocumented:!0,arity:1,name:"or",qname:"excel-logical:or",signature:"($values as xs:anyAtomicType*) as xs:boolean",description:" Returns TRUE if any argument is TRUE; FALSE if all arguments are FALSE.\n",summary:"<p> Returns TRUE if any argument is TRUE; FALSE if all arguments are FALSE.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"values",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of arguments.</div>'}],returns:{type:"xs:boolean",description:"TRUE if any argument is TRUE; FALSE if all arguments are FALSE."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">excel-err:Value provided sequence is empty.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"or",qname:"excel-logical:or",signature:"($arg1 as xs:anyAtomicType, $arg2 as xs:anyAtomicType) as xs:boolean",description:" Returns TRUE if any argument is TRUE; FALSE if all arguments are FALSE.\n",summary:"<p> Returns TRUE if any argument is TRUE; FALSE if all arguments are FALSE.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first argument.</div>'},{name:"arg2",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second argument.</div>'}],returns:{type:"xs:boolean",description:"TRUE if any argument is TRUE; FALSE if all arguments are FALSE."},errors:[]}],variables:[]},"http://www.28msec.com/modules/sequence":{ns:"http://www.28msec.com/modules/sequence",description:" The sequence module allows you to generate consecutive\n application-unique xs:integer ids. This is required e.g. in accounting\n applications as some legislations require consecutive invoice numbers.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/store/static/collections/dml",prefix:"cdml"},{uri:"http://zorba.io/modules/store/static/indexes/dml",prefix:"idml"},{uri:"http://www.28msec.com/modules/lock",prefix:"lock"},{uri:"http://www.28msec.com/modules/sequence",prefix:"seq"},{uri:"http://www.28msec.com/modules/sleep",prefix:"sleep"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"id",qname:"seq:id",signature:"($uri as xs:string) as xs:integer",description:' Returns a unique (sequentially incremented) id for the\n uri specified as parameter.\n Here the function is used to create consecutive invoice numbers:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n if (order:fulfilled($order-id))\n then\n   {\n     variable $invoice-id := seq:id("invoice");\n     invoice:create($invoice-id, $order-id);\n   }\n else\n   ...\n </pre>\n',summary:"<p> Returns a unique (sequentially incremented) id for the\n uri specified as parameter.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the sequence counter as uri.</div>'}],returns:{type:"xs:integer",description:"A sequentially incremented id."},errors:[]},{isDocumented:!0,arity:1,name:"reset",qname:"seq:reset",signature:"($uri as xs:string) as empty-sequence()",description:" Resets the unique (sequentially incremented) id generation\n for the uri specified as parameter.\n",summary:"<p> Resets the unique (sequentially incremented) id generation\n for the uri specified as parameter.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the sequence counter as uri.</div>'}],returns:{type:"empty-sequence()",description:"empty-sequence()"},errors:[]},{isDocumented:!0,arity:1,name:"value",qname:"seq:value",signature:"($uri as xs:string) as xs:integer",description:" Returns the id for the uri specified as parameter without incrementing it.\n",summary:"<p> Returns the id for the uri specified as parameter without incrementing it.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the sequence counter as uri.</div>'}],returns:{type:"xs:integer",description:"The current value"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">seq:not-found if no counter with the given $uri was found</xqdoc:error>']}],variables:[{name:"seq:counters",type:"item()*",description:" The QName for the counters collection.\n"},{name:"seq:counters-by-uri",type:"item()*",description:" The QName for the counters-by-uri collection.\n"}]},"http://api.28.io/databrowser":{ns:"http://api.28.io/databrowser",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/databrowser",prefix:"api"},{uri:"http://zorba.io/modules/base64",prefix:"base64"},{uri:"http://zorba.io/modules/store/static/collections/dml",prefix:"dml"},{uri:"http://www.zorba-xquery.com/extensions",prefix:"ext"},{uri:"http://www.functx.com",prefix:"functx"},{uri:"http://expath.org/ns/http-client",prefix:"http"},{uri:"http://www.zorba-xquery.com/modules/http-client",prefix:"http-client"},{uri:"http://zorba.io/modules/xml-options",prefix:"opt"},{uri:"http://www.28msec.com/modules/project",prefix:"project"},{uri:"http://zorba.io/modules/reflection",prefix:"r"},{uri:"http://zorba.io/modules/reference",prefix:"ref"},{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://www.28msec.com/modules/http/response",prefix:"res"},{uri:"http://zorba.io/modules/xml",prefix:"xmlmod"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!1,arity:1,name:"collection",qname:"api:collection",signature:"($name as xs:string)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"delete",qname:"api:delete",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!0,arity:0,name:"dispatch",qname:"api:dispatch",signature:"()",description:" Data Browser API dispatched.\n Handles API authorization to the portal and dispatching.\n",summary:"<p> Data Browser API dispatched.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"edit",qname:"api:edit",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:0,name:"options",qname:"api:options",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"run",qname:"api:run",signature:"($sequential as xs:boolean) as object()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"sequential",type:"xs:boolean",occurrence:null,description:""}],returns:{type:"object()",description:""},errors:[]},{isDocumented:!1,arity:1,name:"serialize",qname:"api:serialize",signature:"($items as item()*) as object()",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:""}],returns:{type:"object()",description:""},errors:[]},{isDocumented:!1,arity:0,name:"upload",qname:"api:upload",signature:"()",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:null,description:""},errors:[]}],variables:[]},"http://xbrl.io/modules/bizql/footnotes":{ns:"http://xbrl.io/modules/bizql/footnotes",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functions for retrieving XBRL footnotes\n (see section 4.11 Footnotes of the XBRL 2.1 specification).</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/entities",prefix:"entities"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://xbrl.io/modules/bizql/footnotes",prefix:"footnotes"},{uri:"http://www.28msec.com/modules/mongodb/types",prefix:"m"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://zorba.io/modules/string",prefix:"string"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"fnid",qname:"footnotes:fnid",signature:"($footnote-or-id as item()) as atomic",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts the input to a normalized footnote id (FNID). The input\n can be either an FNID, or a footnote object which contains an _id.</p>\n',summary:"<p>  Converts the input to a normalized footnote id (FNID).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"footnote-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an footnote object or FNID.</div>'}],returns:{type:"atomic",description:"the normalized FNID."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">footnotes:INVALID-PARAMETER if the FNID or footnote is not valid.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"footnotes-for-archives",qname:"footnotes:footnotes-for-archives",signature:"($archive-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all footnotes reported within a given archive.</p>\n',summary:"<p>  Return all footnotes reported within a given archive.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or AIDs to filter.</div>'}],returns:{type:"object()*",description:"all footnotes reported in these archives."},errors:[]},{isDocumented:!0,arity:1,name:"footnotes-for-facts",qname:"footnotes:footnotes-for-facts",signature:"($facts-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all footnotes associated with the given facts.</p>\n',summary:"<p>  Return all footnotes associated with the given facts.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"facts-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of facts or fact IDs to filter</div>'}],returns:{type:"object()*",description:"all footnotes associated with these facts."},errors:[]},{isDocumented:!0,arity:2,name:"footnotes-for-facts",qname:"footnotes:footnotes-for-facts",signature:"($facts-or-ids as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all footnotes associated with the given facts.</p>\n',summary:"<p>  Return all footnotes associated with the given facts.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"facts-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of facts or fact IDs to filter</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="facts#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"all footnotes associated with these facts."},errors:[]},{isDocumented:!0,arity:1,name:"footnotes-search",qname:"footnotes:footnotes-search",signature:"($search as string) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all footnotes that match the given search term.</p>\n',summary:"<p>  Return all footnotes that match the given search term.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"search",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the search query</div>'}],returns:{type:"object()*",description:"all footnotes matching the given search query"},errors:[]},{isDocumented:!0,arity:0,name:"footnotes",qname:"footnotes:footnotes",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all footnotes.</p>\n',summary:"<p>  Return all footnotes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"all footnotes."},errors:[]},{isDocumented:!0,arity:1,name:"footnotes",qname:"footnotes:footnotes",signature:"($footnote-or-ids as item()*) as object()?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the footnote with the given FNIDs.</p>\n',summary:"<p>  Return the footnote with the given FNIDs.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"footnote-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the FNIDs or the footnotes themselves.</div>'}],returns:{type:"object()?",description:"the footnotes with the given FNIDs the empty sequence if no footnote was found or if the input is an empty sequence."},errors:[]}],variables:[{name:"footnotes:col",type:"string",description:" Name of the collection the footnotes are stored in.\n"},{name:"footnotes:ARCHIVE",type:"string",description:" Name of the field that points to the archive.\n"},{name:"footnotes:FACTS",type:"string",description:" Name of the field that points to the facts linked to this footnote.\n"},{name:"footnotes:LANG",type:"string",description:" Name of the field that holds the language attribute of the footnote.\n"}]},"http://zorba.io/modules/store/static/indexes/dml":{ns:"http://zorba.io/modules/store/static/indexes/dml",description:' This module defines a set of functions to probe and refresh indexes which are\n declared in the prolog of a module.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This module is part of\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/xqddf.html">Zorba\'s XQuery Data Definition Facility</a>.\n All the indexes managed by this module have to be pre-declared in the prolog\n of a library module.\n Please refer to the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/data_lifecycle.html">general documentation</a>\n for more information and examples.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/data_lifecycle.html">Data Lifecycle</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/xqddf.html">XQuery Data Definition Facility</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/errors</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Zorba Team</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/store/static/indexes/dml",prefix:"idml"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"keys",qname:"idml:keys",signature:"($name as xs:QName) as node()* external",description:' Gets a sequence of all keys contained in the index with the given name.\n Each element has the following structure:\n  <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="brush: xml;">\n   &lt;key xmlns="http://zorba.io/modules/store/static/indexes/dml"&gt;\n     &lt;attribute value="key1_value"/&gt;\n     &lt;attribute value="key2_value"/&gt;\n     &lt;attribute value="key3_value"/&gt;\n   &lt;/key&gt;\n  </pre>\n Note that the order of the attribute elements reflects the order of\n the keys in the index specification. Also note that the values in\n these attributes have the type that is declared in the corresponding\n index specification.\n',summary:"<p> Gets a sequence of all keys contained in the index with the given name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the index to get the keys for.</div>'}],returns:{type:"node()*",description:"A sequence of elements comprising the keys in the index."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0021 if the index was not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if the index does not exist.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"probe-index-point-general",qname:"idml:probe-index-point-general",signature:"($name as xs:QName, $key as xs:anyAtomicType*) as node()* external",description:' Gets from an index the domain nodes associated by general equality with a\n given <em xmlns:xqdoc="http://www.xqdoc.org/1.0">search sequence </em>.\n The search sequence consists of an arbitrary number of <em xmlns:xqdoc="http://www.xqdoc.org/1.0">search keys</em>\n where each search key is an atomic item.\n The function is supported by general indexes only.\n',summary:"<p> Gets from an index the domain nodes associated by general equality with a\n given  search sequence  .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the index to probe.</div>'},{name:"key",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The search sequence.</div>'}],returns:{type:"node()*",description:'The set of domain nodes for which the following XQuery expression returns true: <pre xmlns:xqdoc="http://www.xqdoc.org/1.0"> $keys = $node/keyExpr </pre> where keyExpr is the expression specified in the keyspec of the index (remember that for general indexes, there can be only one keyspec).'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if the search sequence contains a search key whose type does not match the sequence type specified in the keyspec of the index.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0021 if the index with name $name is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if the index with name $name does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0029 if the index is not general.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"probe-index-point-value-skip",qname:"idml:probe-index-point-value-skip",signature:"($name as xs:QName, $skip as xs:integer, $key_i as xs:anyAtomicType?) as node()* external",description:' This is an extension of the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">probe-index-point-value()</code> function\n in that it allows index items to be skipped.\n',summary:"<p> This is an extension of the  probe-index-point-value()  function\n in that it allows index items to be skipped.</p>",annotation_str:" %an:variadic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"variadic",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the index to probe.</div>'},{name:"skip",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of index items to skip.</div>'},{name:"key_i",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The search keys used to probe the index with. The i-th search key corresponds to the i-th key expression in the index declaration.</div>'}],returns:{type:"node()*",description:"The set of domain nodes that satisfy the search condition."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0021 if the index is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if the index does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the number of search keys passed as arguments is not the same as the number of keys declared for the index.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if a non-empty seach key is given whose type does not match the sequence type specified in the corresponding keyspec.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"probe-index-point-value",qname:"idml:probe-index-point-value",signature:"($name as xs:QName, $key_i as xs:anyAtomicType?) as node()* external",description:' Gets the domain nodes from an index associated by value equality with a\n given <em xmlns:xqdoc="http://www.xqdoc.org/1.0">search tuple</em>.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The search tuple consists of a number of <em xmlns:xqdoc="http://www.xqdoc.org/1.0">search keys</em> where each\n search key is either an atomic item or the empty sequence.  The number of\n search keys given must be equal to the number of keys declared for the\n index. Since the number of keys differs from one index to another, this\n function is variadic.\n',summary:"<p> Gets the domain nodes from an index associated by value equality with a\n given  search tuple .</p>",annotation_str:" %an:variadic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"variadic",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The of the index to probe.</div>'},{name:"key_i",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A search key used to probe the index with. The i-th search key corresponds to the i-th key expression in the index declaration.</div>'}],returns:{type:"node()*",description:'The set of domain nodes for which the following XQuery expression returns true: <pre xmlns:xqdoc="http://www.xqdoc.org/1.0"> $key1 eq $node/keyExpr1 and ... and $keyM eq $node/keyExprM </pre> where <i xmlns:xqdoc="http://www.xqdoc.org/1.0">keyExpr<sub>i</sub></i> is the expression specified in the i-th keyspec of the index.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0021 if the index is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if the index does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the number of search keys passed as arguments is not the same as the number of keys declared for the index.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if a non-empty seach key is given whose type does not match the sequence type specified in the corresponding keyspec.</xqdoc:error>']},{isDocumented:!0,arity:7,name:"probe-index-range-general",qname:"idml:probe-index-range-general",signature:"($name as xs:QName, $lowerBound as xs:anyAtomicType*, $upperBound as xs:anyAtomicType*, $haveLowerBound as xs:boolean, $haveUpperBound as xs:boolean, $lowerBoundIncluded as xs:boolean, $upperBoundIncluded as xs:boolean) as node()* external",description:' Gets the domain nodes associated by general order-comparison (operators\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">&lt;=</code>, <code xmlns:xqdoc="http://www.xqdoc.org/1.0">&lt;</code>, <code xmlns:xqdoc="http://www.xqdoc.org/1.0">&gt;=</code>,\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">&gt;</code>) with one or two <em xmlns:xqdoc="http://www.xqdoc.org/1.0">search sequences</em>.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Each search sequence consists of an arbitrary number of\n <em xmlns:xqdoc="http://www.xqdoc.org/1.0">search keys</em> where each search key is an atomic item.\n This method is supported by general range indexes only.\n Its result is either an error or the set of domain nodes for which the\n following XQuery expression returns true:\n  <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n    if ( $haveLowerBound and $haveUpperBound ) then\n      $lowerBoundKeys lop $node/keyExpr and $node/keyExpr uop $upperBoundKeys\n    else if ( $haveLowerBound ) then\n      $lowerBoundKeys lop $node/keyExpr\n    else if ( $haveUpperBound ) then\n      $node/keyExpr uop $upperBoundKeys\n    else\n      fn:true()\n  </pre>\n where <i xmlns:xqdoc="http://www.xqdoc.org/1.0">keyExpr</i> is the expression specified in the keyspec of the\n index, <i xmlns:xqdoc="http://www.xqdoc.org/1.0">lop</i> is either the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">&lt;=</code> or the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">&lt;</code>\n operator depending on whether <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$lowerBoundsIncluded</code> is true or\n false, and <i xmlns:xqdoc="http://www.xqdoc.org/1.0">uop</i> is either the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">&lt;=</code> or the\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">&lt;</code> operator depending on whether\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$upperBoundsIncluded</code> is true or false.\n',summary:"<p> Gets the domain nodes associated by general order-comparison (operators\n  &lt;= ,  &lt; ,  &gt;= ,\n  &gt; ) with one or two  search sequences .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The of the index to probe.</div>'},{name:"lowerBound",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The lower bound search sequence.</div>'},{name:"upperBound",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The upper bound search sequence.</div>'},{name:"haveLowerBound",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Whether a lower bound search sequence exists or not.</div>'},{name:"haveUpperBound",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Whether an upper bound search sequence exists or not.</div>'},{name:"lowerBoundIncluded",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Whether to use the <code>&lt;=</code> or the <code>&lt;</code> operator when comparing a search key from <code>$lowerBound</code> with an index key.</div>'},{name:"upperBoundIncluded",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Whether to use the <code>&lt;=</code> or the <code>&lt;</code> operator when comparing an index key with a search key from <code>$upperBound</code>.</div>'}],returns:{type:"node()*",description:"The set of domain nodes that satisfy the search condition."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0021 if the index was not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if the index does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0030 if the index is not a general range index.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if <code>$haveLowerBound</code> is true and <code>$lowerBoundKeys</code> contains an atomic item whose type does not match the sequence type specified by the index keyspec, or <code>$haveUpperBound</code> is true and <code>$upperBoundKeys</code> contains an atomic item whose type does not match the sequence type specified by the index keyspec.</xqdoc:error>']},{isDocumented:!0,arity:8,name:"probe-index-range-value-skip",qname:"idml:probe-index-range-value-skip",signature:"($name as xs:QName, $skip as xs:integer, $lowerBound-i as xs:anyAtomicType?, $upperBound-i as xs:anyAtomicType?, $haveLowerBound-i as xs:boolean, $haveUpperBound-i as xs:boolean, $lowerBoundIncluded-i as xs:boolean, $upperBoundIncluded-i as xs:boolean) as node()* external",description:' This function is an extension of the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">probe-index-range-value()</code>\n function that index items to be skipped.\n',summary:"<p> This function is an extension of the  probe-index-range-value() \n function that index items to be skipped.</p>",annotation_str:" %an:variadic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"variadic",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The QName of the index to probe</div>'},{name:"skip",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of index items to skip.</div>'},{name:"lowerBound-i",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The lower bound in a range of key values.</div>'},{name:"upperBound-i",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The upper bound in a range of key values.</div>'},{name:"haveLowerBound-i",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If false, then there is no lower bound, or equivalently, the lower bound is -INFINITY. Otherwise, the lower bound is the one given by the <code>$lowerBound-i</code> value.</div>'},{name:"haveUpperBound-i",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If false, then there is no upper bound, or equivalently, the upper bound is +INFINITY. Otherwise, the upper bound is the one given by the <code>$upperBound-i</code> value.</div>'},{name:"lowerBoundIncluded-i",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If false, then the range is open from below, i.e., the lowerBound-i value is not considered part of the range. Otherwise, the range is closed from below, i.e., the <code>$lowerBound-i</code> value is part of the range.</div>'},{name:"upperBoundIncluded-i",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If false, then the range is open from above, i.e., the upperBound-i value is not considered part of the range. Otherwise, the range is closed from above, i.e., the <code>$upperBound-i</code> value is part of the range.</div>'}],returns:{type:"node()*",description:"The set of domain nodes that satisfy the search condition."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0021 if the index with name $name is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if the index with name $name does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the number of rangespecs passed as arguments is zero or greater than the number of keys declared for the index.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0026 if the index is not a range index.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if <code>$haveLowerBound-i</code> is true and <code>$lowerBound-i</code> is an atomic item whose type does not match the sequence type specified by the i<sup>th</sup> keyspec, or <code>$haveUpperBound-i</code> is true and <code>$upperBound-i</code> is an atomic item whose type does not match the sequence type specified by the i<sup>th</sup> keyspec.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0034 if (a) the index is general (in which case there is only one rangespac), (b) the index is untyped, (c) there is both a lower and an upper bound, and (d) if T1 and T2 are the types of the lower and upper bound, neither T1 is a subtype of T2 nor T2 is a subtype of T1.</xqdoc:error>']},{isDocumented:!0,arity:7,name:"probe-index-range-value",qname:"idml:probe-index-range-value",signature:"($name as xs:QName, $lowerBound-i as xs:anyAtomicType?, $upperBound-i as xs:anyAtomicType?, $haveLowerBound-i as xs:boolean, $haveUpperBound-i as xs:boolean, $lowerBoundIncluded-i as xs:boolean, $upperBoundIncluded-i as xs:boolean) as node()* external",description:' Gets the domain nodes associated by value order-comparison (operators\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">le</code>, <code xmlns:xqdoc="http://www.xqdoc.org/1.0">lt</code>, <code xmlns:xqdoc="http://www.xqdoc.org/1.0">ge</code>, <code xmlns:xqdoc="http://www.xqdoc.org/1.0">gt</code>) with a\n given <em xmlns:xqdoc="http://www.xqdoc.org/1.0">search box</em>.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The search box is specified as a number <i xmlns:xqdoc="http://www.xqdoc.org/1.0">M</i> of <em xmlns:xqdoc="http://www.xqdoc.org/1.0">rangespecs</em>\n where each rangespec consists of six values.\n The number <i xmlns:xqdoc="http://www.xqdoc.org/1.0">M</i> must be greater than 0 and less than or equal to the\n number <i xmlns:xqdoc="http://www.xqdoc.org/1.0">N</i> of keyspecs found in the index declaration.\n If <i xmlns:xqdoc="http://www.xqdoc.org/1.0">M</i> &lt; <i xmlns:xqdoc="http://www.xqdoc.org/1.0">N</i>, then the "missing" rangespecs are assumed to have\n the following value: [(), (), false, false, false, false].\n As a result, we can assume that <i xmlns:xqdoc="http://www.xqdoc.org/1.0">M</i> = <i xmlns:xqdoc="http://www.xqdoc.org/1.0">N</i>.\n Remember that for general indexes, there can be only one IndexKeySpec and,\n as a result for general indexes, <i xmlns:xqdoc="http://www.xqdoc.org/1.0">M</i> = <i xmlns:xqdoc="http://www.xqdoc.org/1.0">N</i> = 1.\n Since the number of keys differs from one index to another,\n this function is variadic.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The i<sup xmlns:xqdoc="http://www.xqdoc.org/1.0">th</sup> rangespec corresponds to the i<sup xmlns:xqdoc="http://www.xqdoc.org/1.0">th</sup> keyspec, and\n specifies a search condition on the key values that are produced by\n evaluating that keyspec for every domain node.\n Specifically, we define the i<sup xmlns:xqdoc="http://www.xqdoc.org/1.0">th</sup> <em xmlns:xqdoc="http://www.xqdoc.org/1.0">rangespec result</em> as the\n set of domain nodes for which the following XQuery expression returns\n true:\n  <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n    if ( $haveLowerBound-i and $haveUpperBound-i ) then\n      $lowerBound-i lop $node/keyExpr-i and $node/keyExpr-i uop $upperBound-i\n    else if ( $haveLowerBound-i ) then\n      $lowerBound-i lop $node/keyExpr-i\n    else if ( $haveUpperBound-i ) then\n      $node/keyExpr-i uop $upperBound-i\n    else\n      fn:true()\n  </pre>\n where <i xmlns:xqdoc="http://www.xqdoc.org/1.0">keyExpr-i</i> is the expression specified by the i<sup xmlns:xqdoc="http://www.xqdoc.org/1.0">th</sup>\n keyspec of the index, <i xmlns:xqdoc="http://www.xqdoc.org/1.0">lop</i> is either the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">le</code> or the\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">lt</code> operator depending on whether\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$lowerBoundsIncluded-i</code> is true or false, and <i xmlns:xqdoc="http://www.xqdoc.org/1.0">uop</i> is\n either the <i xmlns:xqdoc="http://www.xqdoc.org/1.0">le</i> or the <i xmlns:xqdoc="http://www.xqdoc.org/1.0">lt</i> operator depending on whether\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$upperBoundsIncluded-i</code> is true or false.\n',summary:"<p> Gets the domain nodes associated by value order-comparison (operators\n  le ,  lt ,  ge ,  gt ) with a\n given  search box .</p>",annotation_str:" %an:variadic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"variadic",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the index to probe.</div>'},{name:"lowerBound-i",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The lower bound in a range of key values.</div>'},{name:"upperBound-i",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The upper bound in a range of key values.</div>'},{name:"haveLowerBound-i",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If false, then there is no lower bound, or equivalently, the lower bound is -INFINITY. Otherwise, the lower bound is the one given by the <code>$lowerBound-i</code> value.</div>'},{name:"haveUpperBound-i",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If false, then there is no upper bound, or equivalently, the upper bound is +INFINITY. Otherwise, the upper bound is the one given by the <code>$upperBound-i</code> value.</div>'},{name:"lowerBoundIncluded-i",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If false, then the range is open from below, i.e., the <code>$lowerBound-i</code> value is not considered part of the range. Otherwise, the range is closed from below, i.e., the <code>$lowerBound-i</code> value is part of the range.</div>'},{name:"upperBoundIncluded-i",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> If false, then the range is open from above, i.e., the <code>$upperBound-i</code> value is not considered part of the range. Otherwise, the range is closed from above, i.e., the <code>$upperBound-i</code> value is part of the range.</div>'}],returns:{type:"node()*",description:"The intersection of all the rangespec results."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0021 if the index is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if the index does not exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0025 if the number of rangespecs passed as arguments is zero or greater than the number of keys declared for the index.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0026 if the index is not a range index.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XPTY0004 if <code>$haveLowerBound-i</code> is true and <code>$lowerBound-i</code> is an atomic item whose type does not match the sequence type specified by the i<sup>th</sup> keyspec, or <code>$haveUpperBound-i</code> is true and <code>$upperBound-i</code> is an atomic item whose type does not match the sequence type specified by the i<sup>th</sup> keyspec.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0034 if (a) the index is general (in which case there is only one rangespac), (b) the index is untyped, (c) there is both a lower and an upper bound, and (d) if T1 and T2 are the types of the lower and upper bound, neither T1 is a subtype of T2 nor T2 is a subtype of T1.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"refresh-index",qname:"idml:refresh-index",signature:"($name as xs:QName) external",description:" Updates the index with the given name.  Note that if the maintenance\n property of the index is automatic, this function does nothing.\n",summary:"<p> Updates the index with the given name.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the index to refresh.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, when applied, refreshes the contents of the index."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0021 if the index is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0023 if the index does not exist.</xqdoc:error>']}],variables:[]},"http://www.28msec.com/modules/full-text":{ns:"http://www.28msec.com/modules/full-text",description:' This module provides an API to full-text functions such as tokenization,\n stemming, or stop word detection. The default language is set to english\n for all functions that don\'t take an explicit language parameter.\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0">Notes on stemming</h2>\n The <code xmlns:xqdoc="http://www.xqdoc.org/1.0">stem()</code> functions return the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://en.wikipedia.org/wiki/Word_stem">stem</a>\n of a word.\n On 28.io,\n the stem of a word itself, however, is not guaranteed to be a word.\n It is best to consider a stem as an opaque byte sequence.\n All that is guaranteed about a stem is that,\n for a given word,\n the stem of that word will always be the same byte sequence.\n Hence,\n you sould never compare the result of one of the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">stem()</code>\n functions against a non-stemmed string,\n for example:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static">\n  if ( ft:stem( "apples" ) eq "apple" )             ** WRONG **\n </pre>\n Instead do:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static">\n  if ( ft:stem( "apples" ) eq ft:stem( "apple" ) )  ** CORRECT **\n </pre>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0">Notes on the thesaurus</h2>\n 28msec uses the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://wordnet.princeton.edu/">WordNet lexical database</a> version 3.0,\n In WordNet, the number of "levels" that two phrases are apart\n are how many hierarchical meanings apart they are.\n For example,\n "canary" is 5 levels away from "vertebrate"\n (carary &gt; finch &gt; oscine &gt; passerine &gt; bird &gt; vertebrate).\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n When using the WordNet implementation,\n 28msec supports all of the relationships (and their abbreviations)\n specified by\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=7776">ISO 2788</a>\n and\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.niso.org/kst/reports/standards?step=2&amp;gid=&amp;project_key=7cc9b583cb5a62e8c15d3099e0bb46bbae9cf38a">ANSI/NISO Z39.19-2005</a>\n with the exceptions of "HN" (history note)\n and "X SN" (see scope note for).\n These relationships are:\n  <table xmlns:xqdoc="http://www.xqdoc.org/1.0" class="table table-bordered">\n    <tr>\n      <th>Rel.</th>\n      <th>Meaning</th>\n      <th>WordNet Rel.</th>\n    </tr>\n    <tr>\n      <td>BT</td>\n      <td>broader term</td>\n      <td>hypernym</td>\n    </tr>\n    <tr>\n      <td>BTG</td>\n      <td>broader term generic</td>\n      <td>hypernym</td>\n    </tr>\n    <tr>\n      <td>BTI</td>\n      <td>broader term instance</td>\n      <td>instance hypernym</td>\n    </tr>\n    <tr>\n      <td>BTP</td>\n      <td>broader term partitive</td>\n      <td>part meronym</td>\n    </tr>\n    <tr>\n      <td>NT</td>\n      <td>narrower term</td>\n      <td>hyponym</td>\n    </tr>\n    <tr>\n      <td>NTG</td>\n      <td>narrower term generic</td>\n      <td>hyponym</td>\n    </tr>\n    <tr>\n      <td>NTI</td>\n      <td>narrower term instance</td>\n      <td>instance hyponym</td>\n    </tr>\n    <tr>\n      <td>NTP</td>\n      <td>narrower term partitive</td>\n      <td>part holonym</td>\n    </tr>\n    <tr>\n      <td>RT</td>\n      <td>related term</td>\n      <td>also see</td>\n    </tr>\n    <tr>\n      <td>SN</td>\n      <td>scope note</td>\n      <td>n/a</td>\n    </tr>\n    <tr>\n      <td>TT</td>\n      <td>top term</td>\n      <td>hypernym</td>\n    </tr>\n    <tr>\n      <td>UF</td>\n      <td>non-preferred term</td>\n      <td>n/a</td>\n    </tr>\n    <tr>\n      <td>USE</td>\n      <td>preferred term</td>\n      <td>n/a</td>\n    </tr>\n  </table>\n Note that you can specify relationships\n either by their abbreviation\n or their meaning.\n Relationships are case-insensitive.\n In addition to the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=7776">ISO 2788</a>\n and\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.niso.org/kst/reports/standards?step=2&amp;gid=&amp;project_key=7cc9b583cb5a62e8c15d3099e0bb46bbae9cf38a">ANSI/NISO Z39.19-2005</a>\n relationships,\n 28msec also supports all of the relationships offered by WordNet.\n These relationships are:\n  <table xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ft_rels table table-bordered">\n    <tr>\n      <th>Relationship</th>\n      <th>Meaning</th>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">also see</td>\n      <td>\n        A word that is related to another,\n        e.g., for "varnished" (furniture)\n        one should <em>also see</em> "finished."\n      </td>\n    </tr>\n    <tr>\n      <td>antonym</td>\n      <td>\n        A word opposite in meaning to another,\n        e.g., "light" is an <em>antonym</em> for "heavy."\n      </td>\n    </tr>\n    <tr>\n      <td>attribute</td>\n      <td>\n        A noun for which adjectives express values,\n        e.g., "weight" is an <em>attribute</em>\n        for which the adjectives "light" and "heavy"\n        express values.\n      </td>\n    </tr>\n    <tr>\n      <td>cause</td>\n      <td>\n        A verb that causes another,\n        e.g., "show" is a <em>cause</em> of "see."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">derivationally related form</td>\n      <td>\n        A word that is derived from a root word,\n        e.g., "metric" is a <em>derivationally related form</em> of "meter."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">derived from adjective</td>\n      <td>\n        An adverb that is derived from an adjective,\n        e.g., "correctly" is <em>derived from the adjective</em> "correct."\n      </td>\n    </tr>\n    <tr>\n      <td>entailment</td>\n      <td>\n        A verb that presupposes another,\n        e.g., "snoring" <em>entails</em> "sleeping."\n      </td>\n    </tr>\n    <tr>\n      <td>hypernym</td>\n      <td>\n        A word with a broad meaning that more specific words fall under,\n        e.g., "meal" is a <em>hypernym</em> of "breakfast."\n      </td>\n    </tr>\n    <tr>\n      <td>hyponym</td>\n      <td>\n        A word of more specific meaning than a general term applicable to it,\n        e.g., "breakfast" is a <em>hyponym</em> of "meal."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">instance hypernym</td>\n      <td>\n        A word that denotes a category of some specific instance,\n        e.g., "author" is an <em>instance hypernym</em> of "Asimov."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">instance hyponym</td>\n      <td>\n        A term that donotes a specific instance of some general category,\n        e.g., "Asimov" is an <em>instance hyponym</em> of "author."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">member holonym</td>\n      <td>\n        A word that denotes a collection of individuals,\n        e.g., "faculty" is a <em>member holonym</em> of "professor."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">member meronym</td>\n      <td>\n        A word that denotes a member of a larger group,\n        e.g., a "person" is a <em>member meronym</em> of a "crowd."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">part holonym</td>\n      <td>\n        A word that denotes a larger whole comprised of some part,\n        e.g., "car" is a <em>part holonym</em> of "engine."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">part meronym</td>\n      <td>\n        A word that denotes a part of a larger whole,\n        e.g., an "engine" is <em>part meronym</em> of a "car."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">participle of verb</td>\n      <td>\n        An adjective that is the participle of some verb,\n        e.g., "breaking" is the <em>participle of the verb</em> "break."\n      </td>\n    </tr>\n    <tr>\n      <td>pertainym</td>\n      <td>\n        An adjective that classifies its noun,\n        e.g., "musical" is a <em>pertainym</em> in "musical instrument."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">similar to</td>\n      <td>\n        Similar, though not necessarily interchangeable, adjectives.\n        For example, "shiny" is <em>similar to</em> "bright",\n        but they have subtle differences.\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">substance holonym</td>\n      <td>\n        A word that denotes a larger whole containing some constituent\n        substance, e.g., "bread" is a <em>substance holonym</em> of "flour."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">substance meronym</td>\n      <td>\n        A word that denotes a constituant substance of some larger whole,\n        e.g., "flour" is a <em>substance meronym</em> of "bread."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">verb group</td>\n      <td>\n        A verb that is a member of a group of similar verbs,\n        e.g., "live" is in the <em>verb group</em>\n        of "dwell", "live", "inhabit", etc.\n      </td>\n    </tr>\n  </table>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Paul J. Lucas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.28msec.com/modules/full-text",prefix:"ft"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"},{uri:"http://zorba.io/modules/full-text",prefix:"zft"}],functions:[{isDocumented:!0,arity:1,name:"is-stem-lang-supported",qname:"ft:is-stem-lang-supported",signature:"($lang as language) as boolean",description:" Checks whether the given language is supported for stemming.\n",summary:"<p> Checks whether the given language is supported for stemming.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lang",type:"language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language to check.</div>'}],returns:{type:"boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if the language is supported.'},errors:[]},{isDocumented:!0,arity:1,name:"is-stop-word-lang-supported",qname:"ft:is-stop-word-lang-supported",signature:"($lang as language) as boolean",description:" Checks whether the given language\n is supported for stop words.\n",summary:"<p> Checks whether the given language\n is supported for stop words.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lang",type:"language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language to check.</div>'}],returns:{type:"boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if the language is supported.'},errors:[]},{isDocumented:!0,arity:1,name:"is-stop-word",qname:"ft:is-stop-word",signature:"($word as string) as boolean",description:" Checks whether the given word is a stop-word.\n",summary:"<p> Checks whether the given word is a stop-word.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"word",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The word to check. The word\'s language is assumed to be the one returned by <code>ft:current-lang()</code>.</div>'}],returns:{type:"boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$word</code> is a stop-word.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"is-stop-word",qname:"ft:is-stop-word",signature:"($word as string, $lang as language) as boolean",description:" Checks whether the given word is a stop-word.\n",summary:"<p> Checks whether the given word is a stop-word.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"word",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The word to check.</div>'},{name:"lang",type:"language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language of <code>$word</code>.</div>'}],returns:{type:"boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$word</code> is a stop-word.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-thesaurus-lang-supported",qname:"ft:is-thesaurus-lang-supported",signature:"($lang as language) as boolean",description:" Checks whether the given language\n is supported for look-up using the Wordnet thesaurus.\n",summary:"<p> Checks whether the given language\n is supported for look-up using the Wordnet thesaurus.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lang",type:"language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language to check.</div>'}],returns:{type:"boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if the language is supported.'},errors:[]},{isDocumented:!0,arity:1,name:"is-tokenizer-lang-supported",qname:"ft:is-tokenizer-lang-supported",signature:"($lang as language) as boolean",description:" Checks whether the given language\n is supported for tokenization.\n",summary:"<p> Checks whether the given language\n is supported for tokenization.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lang",type:"language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language to check.</div>'}],returns:{type:"boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if the language is supported.'},errors:[]},{isDocumented:!0,arity:1,name:"stem",qname:"ft:stem",signature:"($word as string) as string",description:" Stems the given word.\n",summary:"<p> Stems the given word.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"word",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The word to stem. The word\'s language is assumed to be the one returned by <code>ft:current-lang()</code>.</div>'}],returns:{type:"string",description:'the stem of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$word</code>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"stem",qname:"ft:stem",signature:"($word as string, $lang as language) as string",description:" Stems the given word.\n",summary:"<p> Stems the given word.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"word",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The word to stem.</div>'},{name:"lang",type:"language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language of <code>$word</code>.</div>'}],returns:{type:"string",description:'the stem of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$word</code>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"strip-diacritics",qname:"ft:strip-diacritics",signature:"($string as string) as string",description:" Strips all diacritical marks from all characters.\n",summary:"<p> Strips all diacritical marks from all characters.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"string",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to strip diacritical marks from.</div>'}],returns:{type:"string",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">$string</code> with diacritical marks stripped.'},errors:[]},{isDocumented:!0,arity:1,name:"thesaurus-lookup",qname:"ft:thesaurus-lookup",signature:"($phrase as string) as string*",description:" Looks-up the given phrase in the Wordnet thesaurus.\n",summary:"<p> Looks-up the given phrase in the Wordnet thesaurus.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"phrase",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The phrase to look up.</div>'}],returns:{type:"string*",description:'the related phrases if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$phrase</code> is found in the thesaurus or the empty sequence if not.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8401 if the thesaurus data file\'s version is not supported by the currently running version of Zorba.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8402 if the thesaurus data file\'s endianness does not match that of the CPU on which Zorba is currently running.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8403 if there was an error reading the thesaurus data.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"thesaurus-lookup",qname:"ft:thesaurus-lookup",signature:"($phrase as string, $relationship as string) as string*",description:" Looks-up the given phrase in a thesaurus.\n",summary:"<p> Looks-up the given phrase in a thesaurus.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"phrase",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The phrase to look up.</div>'},{name:"relationship",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The relationship the results are to have to <code>$phrase</code>.</div>'}],returns:{type:"string*",description:'the related phrases if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$phrase</code> is found in the thesaurus or the empty sequence if not.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0018 if <code>$uri</code> refers to a thesaurus that is not found in the statically known thesauri.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0001 if the thesaurus data file could not be found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0002 if the thesaurus data file is not a plain file.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8401 if the thesaurus data file\'s version is not supported by the currently running version of Zorba.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8402 if the thesaurus data file\'s endianness does not match that of the CPU on which Zorba is currently running.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8403 if there was an error reading the thesaurus data file.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"thesaurus-lookup",qname:"ft:thesaurus-lookup",signature:"($phrase as string, $relationship as string, $level-least as integer, $level-most as integer) as string*",description:" Looks-up the given phrase in a thesaurus.\n",summary:"<p> Looks-up the given phrase in a thesaurus.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"phrase",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The phrase to look up.</div>'},{name:"relationship",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The relationship the results are to have to <code>$phrase</code>.</div>'},{name:"level-least",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The minimum number of levels within the thesaurus to be traversed.</div>'},{name:"level-most",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The maximum number of levels within the thesaurus to be traversed.</div>'}],returns:{type:"string*",description:'the related phrases if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$phrase</code> is found in the thesaurus or the empty sequence if not.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FOCA0003 if either <code>$level-least</code> or <code>$level-most</code> is either negative or too large.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0018 if <code>$uri</code> refers to a thesaurus that is not found in the statically known thesauri.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0001 if the thesaurus data file could not be found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0002 if the thesaurus data file is not a plain file.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8401 if the thesaurus data file\'s version is not supported by the currently running version of Zorba.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8402 if the thesaurus data file\'s endianness does not match that of the CPU on which Zorba is currently running.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8403 if there was an error reading the thesaurus data file.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"tokenize",qname:"ft:tokenize",signature:"($string as string) as string*",description:" Tokenizes the given string.\n",summary:"<p> Tokenizes the given string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"string",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to tokenize. The string\'s language is assumed to be the one returned by <code>ft:current-lang()</code>.</div>'}],returns:{type:"string*",description:"a (possibly empty) sequence of tokens."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"tokenize",qname:"ft:tokenize",signature:"($string as string, $lang as language) as string*",description:" Tokenizes the given string.\n",summary:"<p> Tokenizes the given string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"string",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to tokenize.</div>'},{name:"lang",type:"language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language of <code>$string</code>.</div>'}],returns:{type:"string*",description:"a (possibly empty) sequence of tokens."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>']}],variables:[{name:"ft:lang-da",type:"language",description:" Predeclared constant for the Danish language.\n"},{name:"ft:lang-de",type:"language",description:" Predeclared constant for the German language.\n"},{name:"ft:lang-en",type:"language",description:" Predeclared constant for the English language.\n"},{name:"ft:lang-es",type:"language",description:" Predeclared constant for the Spanish language.\n"},{name:"ft:lang-fi",type:"language",description:" Predeclared constant for the Finnish language.\n"},{name:"ft:lang-fr",type:"language",description:" Predeclared constant for the French language.\n"},{name:"ft:lang-hu",type:"language",description:" Predeclared constant for the Hungarian language.\n"},{name:"ft:lang-it",type:"language",description:" Predeclared constant for the Italian language.\n"},{name:"ft:lang-nl",type:"language",description:" Predeclared constant for the Dutch language.\n"},{name:"ft:lang-no",type:"language",description:" Predeclared constant for the Norwegian language.\n"},{name:"ft:lang-pt",type:"language",description:" Predeclared constant for the Portuguese language.\n"},{name:"ft:lang-ro",type:"language",description:" Predeclared constant for the Romanian language.\n"},{name:"ft:lang-ru",type:"language",description:" Predeclared constant for the Russian language.\n"},{name:"ft:lang-sv",type:"language",description:" Predeclared constant for the Swedish language.\n"},{name:"ft:lang-tr",type:"language",description:" Predeclared constant for the Turkish language.\n"}]},"http://xbrl.io/modules/bizql/report-schemas":{ns:"http://xbrl.io/modules/bizql/report-schemas",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functions for storing, retrieving, and modifying\n report schemas. Report schemas can be used in BizQL queries. They can be\n instantiated generating a business report.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Report schemas are nothing else than a user-defined component. However,\n one of their hypercubes (the default hypercube), as well as two of their\n networks (presentation, concept-map) are special. A report schema is identified\n with an RID (Report schema ID).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve facts from an archive according to a report\n schema. You can retrieve them as a (2D) fact table, or populate the presentation\n network of the report schema with them. The concept map network will be used\n by default to map the report schema concepts to reported concepts.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Report schemas are stored in the collection reportschemas in\n the project\'s MongoDB database.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A report schema needs to be a syntactically valid JSound document.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"",prefix:"an"},{uri:"http://xbrl.io/modules/bizql/hypercubes",prefix:"hypercubes"},{uri:"http://xbrl.io/modules/bizql/networks",prefix:"networks"},{uri:"http://xbrl.io/modules/bizql/report-schemas",prefix:"report-schemas"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"add",qname:"report-schemas:add",signature:"($report-schema as object()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Adds the given report schema to the database.</p>\n',summary:"<p>  Adds the given report schema to the database.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"report-schema",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the report schema to add.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">report-schemas:INVALID-SCHEMA if the given report schema object does not contain a name field</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">report-schemas:EXISTS if a report schema with the given name already exists</xqdoc:error>']},{isDocumented:!0,arity:1,name:"delete",qname:"report-schemas:delete",signature:"($report-schema-or-id as item()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes a report schema from the database.</p>\n',summary:"<p>  Deletes a report schema from the database.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"report-schema-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the report schema to delete or its RID.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">report-schemas:DOES-NOT-EXIST if no report schema with the given RID exists.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"fact-table",qname:"report-schemas:fact-table",signature:"($schema as item(), $archives as item()*) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a schema or its RID,</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs.</div>'}],returns:{type:"array()",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:3,name:"fact-table",qname:"report-schemas:fact-table",signature:"($schema as item(), $archives as item()*, $options as object()?) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a schema or its RID,</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $report-schemas:ALL_ARCHIVES for no filtering.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="facts#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"array()",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:2,name:"facts",qname:"report-schemas:facts",signature:"($schema as item(), $archives as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a report schema or its RID,</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $report-schemas:ALL_ARCHIVES for no filtering.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:3,name:"facts",qname:"report-schemas:facts",signature:"($schema as item(), $archives as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied schema, and populates them with the default dimension values\n when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a report schema or its RID,</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $report-schemas:ALL_ARCHIVES for no filtering.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="facts#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:2,name:"populate-with-facts",qname:"report-schemas:populate-with-facts",signature:"($schema as item(), $archives as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied schema. Default dimension values are added to the facts\n when missing.</p>\n',summary:"<p>  Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied schema.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0">.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $report-schemas:ALL_ARCHIVES for no filtering.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:3,name:"populate-with-facts",qname:"report-schemas:populate-with-facts",signature:"($schema as item(), $archives as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied schema. Default dimension values are added to the facts\n when missing.</p>\n',summary:"<p>  Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied schema.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schema",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0">.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $report-schemas:ALL_ARCHIVES for no filtering.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="facts#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:0,name:"report-schemas",qname:"report-schemas:report-schemas",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all report schemas.</p>\n',summary:"<p>  Retrieves all report schemas.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"all report schemas."},errors:[]},{isDocumented:!0,arity:1,name:"report-schemas",qname:"report-schemas:report-schemas",signature:"($report-schemas-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the report schemas with the given names (RIDs).</p>\n',summary:"<p>  Return the report schemas with the given names (RIDs).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"report-schemas-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the ids of the report schemas (RIDs) or the report schemas themselves.</div>'}],returns:{type:"object()*",description:"the report schemas with the given RIDs or the empty sequence if no report schema was found or the input is an empty sequence."},errors:[]},{isDocumented:!0,arity:1,name:"rid",qname:"report-schemas:rid",signature:"($report-schema-or-id as item()) as atomic",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts the input to a normalized report schema identifier (RID). The input\n can be either a pure RID, or a report schema object which contains an RID.</p>\n',summary:"<p>  Converts the input to a normalized report schema identifier (RID).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"report-schema-or-id",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a report schema identifier (RID)) or a report schema object.</div>'}],returns:{type:"atomic",description:"the normalized RID."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">report-schemas:INVALID_PARAMETER if the RID or report schema is not valid</xqdoc:error>']},{isDocumented:!0,arity:1,name:"update",qname:"report-schemas:update",signature:"($report-schema as object()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Updates a report schema.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Replaces a report schema in the database with the given schema.\n The schema to be replaced is identified by the value of the _id\n field of the given schema (RID).</p>\n',summary:"<p>  Updates a report schema.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"report-schema",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the new report schema</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">report-schemas:DOES-NOT-EXIST if a report schema with the given name does not exist.</xqdoc:error>']}],variables:[{name:"report-schemas:col",type:"string",description:" Name of the collection the report schemas are stored in.\n"},{name:"report-schemas:ALL_ARCHIVES",type:"boolean",description:" Joker for all archives.\n"}]},"http://zorba.io/modules/store/static/integrity-constraints/ddl":{ns:"http://zorba.io/modules/store/static/integrity-constraints/ddl",description:' This module defines a set of functions to manage integrity constraints\n that are declared in the prolog of a module.\n For example, it provides functions to activate or deactivate integrity\n constraints.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This module is part of\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/xqddf.html">Zorba\'s XQuery Data Definition Facility</a>.\n All the integrity constraints managed by this module have to be pre-declared\n in the prolog of a module.\n Please refer to the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/data_lifecycle.html">general documentation</a>\n for more information and examples.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/data_lifecycle.html">Data Lifecycle</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/xqddf.html">XQuery Data Definition Facility</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/errors</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Nicolae Brinza, Matthias Brantner, David Graf, Till Westmann, Markos Zaharioudakis</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/store/static/integrity-constraints/ddl",prefix:"icddl"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:1,name:"activate",qname:"icddl:activate",signature:"($name as xs:QName) external",description:" Activates an integrity constraint in the dynamic context.\n",summary:"<p> Activates an integrity constraint in the dynamic context.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the integrity constraint to activate.</div>'}],returns:{type:null,description:'An empty XDM instance and a pending update list that consists of a <code xmlns:xqdoc="http://www.xqdoc.org/1.0">upd:activateIntegrityConstraint($name)</code> update primitive.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0031 if the integrity constraint does not exist in the static context.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"activated-integrity-constraints",qname:"icddl:activated-integrity-constraints",signature:"() as xs:QName* external",description:" Gets the integrity constraints that are activated, if any.\n",summary:"<p> Gets the integrity constraints that are activated, if any.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each activated integrity constraint, or an empty sequence if none."},errors:[]},{isDocumented:!0,arity:1,name:"deactivate",qname:"icddl:deactivate",signature:"($name as xs:QName) external",description:" Deactivates the integrity constraint.\n",summary:"<p> Deactivates the integrity constraint.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the integrity constraint to deactivate.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, deactivates the integrity constraint."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0032 if the integrity constraint was not declared in the the static context.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0032 if the integrity constraints is not activated.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"declared-integrity-constraints",qname:"icddl:declared-integrity-constraints",signature:"() as xs:QName* external",description:" Gets the sequence of QNames representing the integrity constraints that have\n been declared in the prolog of the static context.\n",summary:"<p> Gets the sequence of QNames representing the integrity constraints that have\n been declared in the prolog of the static context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:QName*",description:"A sequence of QNames, one for each created integrity constraints, or an emtpy sequence if none."},errors:[]},{isDocumented:!0,arity:1,name:"is-activated-integrity-constraint",qname:"icddl:is-activated-integrity-constraint",signature:"($name as xs:QName) as xs:boolean external",description:" Gets whether an integrity constraints is activated.\n",summary:"<p> Gets whether an integrity constraints is activated.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the constraint to check.</div>'}],returns:{type:"xs:boolean",description:"true if the integrity constraint is activated; false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"is-declared-integrity-constraint",qname:"icddl:is-declared-integrity-constraint",signature:"($name as xs:QName) as xs:boolean external",description:" Gets whether an integrity constraint is declared in the prolog of the static\n context.\n",summary:"<p> Gets whether an integrity constraint is declared in the prolog of the static\n context.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the constraint to check.</div>'}],returns:{type:"xs:boolean",description:"true if the constraint is declared; false otherwise."},errors:[]}],variables:[]},"http://www.functx.com":{ns:"http://www.functx.com",description:" --------------------------------\n The FunctX XQuery Function Library\n --------------------------------\n Copyright (C) 2007 Datypic\n This library is free software; you can redistribute it and/or\n modify it under the terms of the GNU Lesser General Public\n License as published by the Free Software Foundation; either\n version 2.1 of the License.\n This library is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n Lesser General Public License for more details.\n You should have received a copy of the GNU Lesser General Public\n License along with this library; if not, write to the Free Software\n Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n For more information on the FunctX XQuery library, contact contrib@functx.com.\n",sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.xqueryfunctions.com</xqdoc:see>'],authors:[],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.functx.com",prefix:"functx"}],functions:[{isDocumented:!0,arity:3,name:"add-attributes",qname:"functx:add-attributes",signature:"($elements as element(*)*, $attrNames as xs:QName*, $attrValues as xs:anyAtomicType*) as element(*)?",description:" Adds attributes to XML elements\n",summary:"<p> Adds attributes to XML elements\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"elements",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the element(s) to which you wish to add the attribute</div>'},{name:"attrNames",type:"xs:QName",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name(s) of the attribute(s) to add</div>'},{name:"attrValues",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value(s) of the attribute(s) to add</div>'}],returns:{type:"element(*)?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"add-months",qname:"functx:add-months",signature:"($date as xs:anyAtomicType?, $months as xs:integer) as xs:date?",description:" Adds months to a date\n",summary:"<p> Adds months to a date\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'},{name:"months",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of months to add</div>'}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:3,name:"add-or-update-attributes",qname:"functx:add-or-update-attributes",signature:"($elements as element(*)*, $attrNames as xs:QName*, $attrValues as xs:anyAtomicType*) as element(*)?",description:" Adds attributes to XML elements\n",summary:"<p> Adds attributes to XML elements\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"elements",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the element(s) to which you wish to add the attribute</div>'},{name:"attrNames",type:"xs:QName",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name(s) of the attribute(s) to add</div>'},{name:"attrValues",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value(s) of the attribute(s) to add</div>'}],returns:{type:"element(*)?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"all-whitespace",qname:"functx:all-whitespace",signature:"($arg as xs:string?) as xs:boolean",description:" Whether a value is all whitespace or a zero-length string\n",summary:"<p> Whether a value is all whitespace or a zero-length string\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string (or node) to test</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"are-distinct-values",qname:"functx:are-distinct-values",signature:"($seq as xs:anyAtomicType*) as xs:boolean",description:" Whether all the values in a sequence are distinct\n",summary:"<p> Whether all the values in a sequence are distinct\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"atomic-type",qname:"functx:atomic-type",signature:"($values as xs:anyAtomicType*) as xs:string*",description:" The built-in type of an atomic value\n",summary:"<p> The built-in type of an atomic value\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"values",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value(s) whose type you want to determine</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"avg-empty-is-zero",qname:"functx:avg-empty-is-zero",signature:"($values as xs:anyAtomicType*, $allNodes as node()*) as xs:double",description:' The average, counting "empty" values as zero\n',summary:'<p> The average, counting "empty" values as zero\n</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"values",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the values to be averaged</div>'},{name:"allNodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of all nodes to find the average over</div>'}],returns:{type:"xs:double",description:""},errors:[]},{isDocumented:!0,arity:3,name:"between-exclusive",qname:"functx:between-exclusive",signature:"($value as xs:anyAtomicType?, $minValue as xs:anyAtomicType, $maxValue as xs:anyAtomicType) as xs:boolean",description:" Whether a value is between two provided values\n",summary:"<p> Whether a value is between two provided values\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to be tested</div>'},{name:"minValue",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the minimum value</div>'},{name:"maxValue",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the maximum value</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:3,name:"between-inclusive",qname:"functx:between-inclusive",signature:"($value as xs:anyAtomicType?, $minValue as xs:anyAtomicType, $maxValue as xs:anyAtomicType) as xs:boolean",description:" Whether a value is between two provided values, or equal to one of them\n",summary:"<p> Whether a value is between two provided values, or equal to one of them\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to be tested</div>'},{name:"minValue",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the minimum value</div>'},{name:"maxValue",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the maximum value</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"camel-case-to-words",qname:"functx:camel-case-to-words",signature:"($arg as xs:string?, $delim as xs:string) as xs:string",description:" Turns a camelCase string into space-separated words\n",summary:"<p> Turns a camelCase string into space-separated words\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to modify</div>'},{name:"delim",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the delimiter for the words (e.g. a space)</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"capitalize-first",qname:"functx:capitalize-first",signature:"($arg as xs:string?) as xs:string?",description:" Capitalizes the first character of a string\n",summary:"<p> Capitalizes the first character of a string\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the word or phrase to capitalize</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:3,name:"change-element-names-deep",qname:"functx:change-element-names-deep",signature:"($nodes as node()*, $oldNames as xs:QName*, $newNames as xs:QName*) as node()*",description:" Changes the names of elements in an XML fragment\n",summary:"<p> Changes the names of elements in an XML fragment\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the element(s) to change</div>'},{name:"oldNames",type:"xs:QName",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of names to change from</div>'},{name:"newNames",type:"xs:QName",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of names to change to</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"change-element-ns-deep",qname:"functx:change-element-ns-deep",signature:"($nodes as node()*, $newns as xs:string, $prefix as xs:string) as node()*",description:" Changes the namespace of XML elements and its descendants\n",summary:"<p> Changes the namespace of XML elements and its descendants\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the nodes to change</div>'},{name:"newns",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the new namespace</div>'},{name:"prefix",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the prefix to use for the new namespace</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"change-element-ns",qname:"functx:change-element-ns",signature:"($elements as element(*)*, $newns as xs:string, $prefix as xs:string) as element(*)?",description:" Changes the namespace of XML elements\n",summary:"<p> Changes the namespace of XML elements\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"elements",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the elements to change</div>'},{name:"newns",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the new namespace</div>'},{name:"prefix",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the prefix to use for the new namespace</div>'}],returns:{type:"element(*)?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"chars",qname:"functx:chars",signature:"($arg as xs:string?) as xs:string*",description:" Converts a string to a sequence of characters\n",summary:"<p> Converts a string to a sequence of characters\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to split</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"contains-any-of",qname:"functx:contains-any-of",signature:"($arg as xs:string?, $searchStrings as xs:string*) as xs:boolean",description:" Whether a string contains any of a sequence of strings\n",summary:"<p> Whether a string contains any of a sequence of strings\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to test</div>'},{name:"searchStrings",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the strings to look for</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"contains-case-insensitive",qname:"functx:contains-case-insensitive",signature:"($arg as xs:string?, $substring as xs:string) as xs:boolean?",description:" Whether one string contains another, without regard to case\n",summary:"<p> Whether one string contains another, without regard to case\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to search</div>'},{name:"substring",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the substring to find</div>'}],returns:{type:"xs:boolean?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"contains-word",qname:"functx:contains-word",signature:"($arg as xs:string?, $word as xs:string) as xs:boolean",description:" Whether one string contains another, as a separate word\n",summary:"<p> Whether one string contains another, as a separate word\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to search</div>'},{name:"word",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the word to find</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"copy-attributes",qname:"functx:copy-attributes",signature:"($copyTo as element(*), $copyFrom as element(*)) as element(*)",description:" Copies attributes from one element to another\n",summary:"<p> Copies attributes from one element to another\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"copyTo",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the element to copy attributes to</div>'},{name:"copyFrom",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the element to copy attributes from</div>'}],returns:{type:"element(*)",description:""},errors:[]},{isDocumented:!0,arity:3,name:"date",qname:"functx:date",signature:"($year as xs:anyAtomicType, $month as xs:anyAtomicType, $day as xs:anyAtomicType) as xs:date",description:" Construct a date from a year, month and day\n",summary:"<p> Construct a date from a year, month and day\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"year",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the year</div>'},{name:"month",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the month</div>'},{name:"day",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the day</div>'}],returns:{type:"xs:date",description:""},errors:[]},{isDocumented:!0,arity:6,name:"dateTime",qname:"functx:dateTime",signature:"($year as xs:anyAtomicType, $month as xs:anyAtomicType, $day as xs:anyAtomicType, $hour as xs:anyAtomicType, $minute as xs:anyAtomicType, $second as xs:anyAtomicType) as xs:dateTime",description:" Construct a date/time from individual components\n",summary:"<p> Construct a date/time from individual components\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"year",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the year</div>'},{name:"month",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the month</div>'},{name:"day",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the day</div>'},{name:"hour",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the hour</div>'},{name:"minute",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the minute</div>'},{name:"second",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second</div>'}],returns:{type:"xs:dateTime",description:""},errors:[]},{isDocumented:!0,arity:1,name:"day-in-year",qname:"functx:day-in-year",signature:"($date as xs:anyAtomicType?) as xs:integer?",description:" The day of the year (a number between 1 and 366)\n",summary:"<p> The day of the year (a number between 1 and 366)\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"day-of-week-abbrev-en",qname:"functx:day-of-week-abbrev-en",signature:"($date as xs:anyAtomicType?) as xs:string?",description:" The abbreviated day of the week, from a date, in English\n",summary:"<p> The abbreviated day of the week, from a date, in English\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"day-of-week-name-en",qname:"functx:day-of-week-name-en",signature:"($date as xs:anyAtomicType?) as xs:string?",description:" The name of the day of the week, from a date, in English\n",summary:"<p> The name of the day of the week, from a date, in English\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"day-of-week",qname:"functx:day-of-week",signature:"($date as xs:anyAtomicType?) as xs:integer?",description:" The day of the week, from a date\n",summary:"<p> The day of the week, from a date\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:4,name:"dayTimeDuration",qname:"functx:dayTimeDuration",signature:"($days as xs:decimal?, $hours as xs:decimal?, $minutes as xs:decimal?, $seconds as xs:decimal?) as xs:dayTimeDuration",description:" Construct a dayTimeDuration from a number of days, hours, etc.\n",summary:"<p> Construct a dayTimeDuration from a number of days, hours, etc.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"days",type:"xs:decimal",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of days</div>'},{name:"hours",type:"xs:decimal",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of hours</div>'},{name:"minutes",type:"xs:decimal",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of minutes</div>'},{name:"seconds",type:"xs:decimal",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of seconds</div>'}],returns:{type:"xs:dayTimeDuration",description:""},errors:[]},{isDocumented:!0,arity:1,name:"days-in-month",qname:"functx:days-in-month",signature:"($date as xs:anyAtomicType?) as xs:integer?",description:" Number of days in the month\n",summary:"<p> Number of days in the month\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"depth-of-node",qname:"functx:depth-of-node",signature:"($node as node()?) as xs:integer",description:" The depth (level) of a node in an XML tree\n",summary:"<p> The depth (level) of a node in an XML tree\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node to check</div>'}],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:1,name:"distinct-attribute-names",qname:"functx:distinct-attribute-names",signature:"($nodes as node()*) as xs:string*",description:" The distinct names of all attributes in an XML fragment\n",summary:"<p> The distinct names of all attributes in an XML fragment\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root to start from</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"distinct-deep",qname:"functx:distinct-deep",signature:"($nodes as node()*) as node()*",description:" The XML nodes with distinct values, taking into account attributes and descendants\n",summary:"<p> The XML nodes with distinct values, taking into account attributes and descendants\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of nodes to test</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"distinct-element-names",qname:"functx:distinct-element-names",signature:"($nodes as node()*) as xs:string*",description:" The distinct names of all elements in an XML fragment\n",summary:"<p> The distinct names of all elements in an XML fragment\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root(s) to start from</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"distinct-element-paths",qname:"functx:distinct-element-paths",signature:"($nodes as node()*) as xs:string*",description:" The distinct paths of all descendant elements in an XML fragment\n",summary:"<p> The distinct paths of all descendant elements in an XML fragment\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root(s) to start from</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"distinct-nodes",qname:"functx:distinct-nodes",signature:"($nodes as node()*) as node()*",description:" The distinct XML nodes in a sequence (by node identity)\n",summary:"<p> The distinct XML nodes in a sequence (by node identity)\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node sequence</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"duration-from-timezone",qname:"functx:duration-from-timezone",signature:"($timezone as xs:string) as xs:dayTimeDuration",description:' Converts a timezone like "-05:00" or "Z" into xs:dayTimeDuration\n',summary:'<p> Converts a timezone like "-05:00" or "Z" into xs:dayTimeDuration\n</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"timezone",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the time zone, in (+|-)HH:MM format</div>'}],returns:{type:"xs:dayTimeDuration",description:""},errors:[]},{isDocumented:!0,arity:2,name:"dynamic-path",qname:"functx:dynamic-path",signature:"($parent as node(), $path as xs:string) as item()*",description:" Dynamically evaluates a simple XPath path\n",summary:"<p> Dynamically evaluates a simple XPath path\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"parent",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root to start from</div>'},{name:"path",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the path expression</div>'}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"escape-for-regex",qname:"functx:escape-for-regex",signature:"($arg as xs:string?) as xs:string",description:" Escapes regex special characters\n",summary:"<p> Escapes regex special characters\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to escape</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"exclusive-or",qname:"functx:exclusive-or",signature:"($arg1 as xs:boolean?, $arg2 as xs:boolean?) as xs:boolean?",description:" Whether one (and only one) of two boolean values is true\n",summary:"<p> Whether one (and only one) of two boolean values is true\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:boolean",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first boolean value</div>'},{name:"arg2",type:"xs:boolean",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second boolean value</div>'}],returns:{type:"xs:boolean?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"first-day-of-month",qname:"functx:first-day-of-month",signature:"($date as xs:anyAtomicType?) as xs:date?",description:" The first day of the month of a date\n",summary:"<p> The first day of the month of a date\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"first-day-of-year",qname:"functx:first-day-of-year",signature:"($date as xs:anyAtomicType?) as xs:date?",description:" The first day of the year of a date\n",summary:"<p> The first day of the year of a date\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"first-node",qname:"functx:first-node",signature:"($nodes as node()*) as node()?",description:" The XML node in a sequence that appears first in document order\n",summary:"<p> The XML node in a sequence that appears first in document order\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of nodes</div>'}],returns:{type:"node()?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"follows-not-descendant",qname:"functx:follows-not-descendant",signature:"($a as node()?, $b as node()?) as xs:boolean",description:" Whether an XML node follows another without being its descendant\n",summary:"<p> Whether an XML node follows another without being its descendant\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"a",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first node</div>'},{name:"b",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second node</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"format-as-title-en",qname:"functx:format-as-title-en",signature:"($titles as xs:string*) as xs:string*",description:' Moves title words like "the" and "a" to the end of strings\n',summary:'<p> Moves title words like "the" and "a" to the end of strings\n</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"titles",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the titles to format</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"fragment-from-uri",qname:"functx:fragment-from-uri",signature:"($uri as xs:string?) as xs:string?",description:" Returns the fragment from a URI\n",summary:"<p> Returns the fragment from a URI\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URI</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"get-matches-and-non-matches",qname:"functx:get-matches-and-non-matches",signature:"($string as xs:string?, $regex as xs:string) as element(*)*",description:" Splits a string into matching and non-matching regions\n",summary:"<p> Splits a string into matching and non-matching regions\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"string",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to split</div>'},{name:"regex",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the pattern</div>'}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"get-matches",qname:"functx:get-matches",signature:"($string as xs:string?, $regex as xs:string) as xs:string*",description:" Return the matching regions of a string\n",summary:"<p> Return the matching regions of a string\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"string",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to split</div>'},{name:"regex",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the pattern</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"has-element-only-content",qname:"functx:has-element-only-content",signature:"($element as element(*)) as xs:boolean",description:" Whether an element has element-only content\n",summary:"<p> Whether an element has element-only content\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"element",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the XML element to test</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"has-empty-content",qname:"functx:has-empty-content",signature:"($element as element(*)) as xs:boolean",description:" Whether an element has empty content\n",summary:"<p> Whether an element has empty content\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"element",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the XML element to test</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"has-mixed-content",qname:"functx:has-mixed-content",signature:"($element as element(*)) as xs:boolean",description:" Whether an element has mixed content\n",summary:"<p> Whether an element has mixed content\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"element",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the XML element to test</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"has-simple-content",qname:"functx:has-simple-content",signature:"($element as element(*)) as xs:boolean",description:" Whether an element has simple content\n",summary:"<p> Whether an element has simple content\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"element",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the XML element to test</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"id-from-element",qname:"functx:id-from-element",signature:"($element as element(*)?) as xs:string?",description:" Gets the ID of an XML element\n",summary:"<p> Gets the ID of an XML element\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"element",type:"element(*)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the element</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"id-untyped",qname:"functx:id-untyped",signature:"($node as node()*, $id as xs:anyAtomicType) as element(*)*",description:" Gets XML element(s) that have an attribute with a particular value\n",summary:"<p> Gets XML element(s) that have an attribute with a particular value\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root node(s) to start from</div>'},{name:"id",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the "id" to find</div>'}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"if-absent",qname:"functx:if-absent",signature:"($arg as item()*, $value as item()*) as item()*",description:" The first argument if it is not empty, otherwise the second argument\n",summary:"<p> The first argument if it is not empty, otherwise the second argument\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the item(s) that may be absent</div>'},{name:"value",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the item(s) to use if the item is absent</div>'}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"if-empty",qname:"functx:if-empty",signature:"($arg as item()?, $value as item()*) as item()*",description:" The first argument if it is not blank, otherwise the second argument\n",summary:"<p> The first argument if it is not blank, otherwise the second argument\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node that may be empty</div>'},{name:"value",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the item(s) to use if the node is empty</div>'}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"index-of-deep-equal-node",qname:"functx:index-of-deep-equal-node",signature:"($nodes as node()*, $nodeToFind as node()) as xs:integer*",description:" The position of a node in a sequence, based on contents and attributes\n",summary:"<p> The position of a node in a sequence, based on contents and attributes\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node sequence</div>'},{name:"nodeToFind",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node to find in the sequence</div>'}],returns:{type:"xs:integer*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"index-of-match-first",qname:"functx:index-of-match-first",signature:"($arg as xs:string?, $pattern as xs:string) as xs:integer?",description:" The first position of a matching substring\n",summary:"<p> The first position of a matching substring\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string</div>'},{name:"pattern",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the pattern to match</div>'}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"index-of-node",qname:"functx:index-of-node",signature:"($nodes as node()*, $nodeToFind as node()) as xs:integer*",description:" The position of a node in a sequence, based on node identity\n",summary:"<p> The position of a node in a sequence, based on node identity\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node sequence</div>'},{name:"nodeToFind",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node to find in the sequence</div>'}],returns:{type:"xs:integer*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"index-of-string-first",qname:"functx:index-of-string-first",signature:"($arg as xs:string?, $substring as xs:string) as xs:integer?",description:" The first position of a substring\n",summary:"<p> The first position of a substring\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string</div>'},{name:"substring",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the substring to find</div>'}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"index-of-string-last",qname:"functx:index-of-string-last",signature:"($arg as xs:string?, $substring as xs:string) as xs:integer?",description:" The last position of a substring\n",summary:"<p> The last position of a substring\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string</div>'},{name:"substring",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the substring to find</div>'}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"index-of-string",qname:"functx:index-of-string",signature:"($arg as xs:string?, $substring as xs:string) as xs:integer*",description:" The position(s) of a substring\n",summary:"<p> The position(s) of a substring\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string</div>'},{name:"substring",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the substring to find</div>'}],returns:{type:"xs:integer*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"insert-string",qname:"functx:insert-string",signature:"($originalString as xs:string?, $stringToInsert as xs:string?, $pos as xs:integer) as xs:string",description:" Inserts a string at a specified position\n",summary:"<p> Inserts a string at a specified position\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"originalString",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the original string to insert into</div>'},{name:"stringToInsert",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to insert</div>'},{name:"pos",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the position</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"is-a-number",qname:"functx:is-a-number",signature:"($value as xs:anyAtomicType?) as xs:boolean",description:" Whether a value is numeric\n",summary:"<p> Whether a value is numeric\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value to test</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"is-absolute-uri",qname:"functx:is-absolute-uri",signature:"($uri as xs:string?) as xs:boolean",description:" Whether a URI is absolute\n",summary:"<p> Whether a URI is absolute\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URI to test</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"is-ancestor",qname:"functx:is-ancestor",signature:"($node1 as node(), $node2 as node()) as xs:boolean",description:" Whether an XML node is an ancestor of another node\n",summary:"<p> Whether an XML node is an ancestor of another node\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first node</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second node</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"is-descendant",qname:"functx:is-descendant",signature:"($node1 as node(), $node2 as node()) as xs:boolean",description:" Whether an XML node is a descendant of another node\n",summary:"<p> Whether an XML node is a descendant of another node\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first node</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second node</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"is-leap-year",qname:"functx:is-leap-year",signature:"($date as xs:anyAtomicType?) as xs:boolean",description:" Whether a date falls in a leap year\n",summary:"<p> Whether a date falls in a leap year\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date or year</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"is-node-among-descendants-deep-equal",qname:"functx:is-node-among-descendants-deep-equal",signature:"($node as node()?, $seq as node()*) as xs:boolean",description:" Whether an XML node is among the descendants of a sequence, based on contents and attributes\n",summary:"<p> Whether an XML node is among the descendants of a sequence, based on contents and attributes\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node to test</div>'},{name:"seq",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of nodes to search</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"is-node-among-descendants",qname:"functx:is-node-among-descendants",signature:"($node as node()?, $seq as node()*) as xs:boolean",description:" Whether an XML node is among the descendants of a sequence, based on node identity\n",summary:"<p> Whether an XML node is among the descendants of a sequence, based on node identity\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node to test</div>'},{name:"seq",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of nodes to search</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"is-node-in-sequence-deep-equal",qname:"functx:is-node-in-sequence-deep-equal",signature:"($node as node()?, $seq as node()*) as xs:boolean",description:" Whether an XML node is in a sequence, based on contents and attributes\n",summary:"<p> Whether an XML node is in a sequence, based on contents and attributes\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node to test</div>'},{name:"seq",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of nodes to search</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"is-node-in-sequence",qname:"functx:is-node-in-sequence",signature:"($node as node()?, $seq as node()*) as xs:boolean",description:" Whether an XML node is in a sequence, based on node identity\n",summary:"<p> Whether an XML node is in a sequence, based on node identity\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node to test</div>'},{name:"seq",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of nodes to search</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"is-value-in-sequence",qname:"functx:is-value-in-sequence",signature:"($value as xs:anyAtomicType?, $seq as xs:anyAtomicType*) as xs:boolean",description:" Whether an atomic value appears in a sequence\n",summary:"<p> Whether an atomic value appears in a sequence\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"value",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the atomic value to test</div>'},{name:"seq",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values to search</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"last-day-of-month",qname:"functx:last-day-of-month",signature:"($date as xs:anyAtomicType?) as xs:date?",description:" The last day of the month of a date\n",summary:"<p> The last day of the month of a date\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"last-day-of-year",qname:"functx:last-day-of-year",signature:"($date as xs:anyAtomicType?) as xs:date?",description:" The last day of the month of a date\n",summary:"<p> The last day of the month of a date\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"last-node",qname:"functx:last-node",signature:"($nodes as node()*) as node()?",description:" The XML node in a sequence that is last in document order\n",summary:"<p> The XML node in a sequence that is last in document order\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of nodes</div>'}],returns:{type:"node()?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"leaf-elements",qname:"functx:leaf-elements",signature:"($root as node()?) as element(*)*",description:" All XML elements that don't have any child elements\n",summary:"<p> All XML elements that don't have any child elements\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"root",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root</div>'}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"left-trim",qname:"functx:left-trim",signature:"($arg as xs:string?) as xs:string",description:" Trims leading whitespace\n",summary:"<p> Trims leading whitespace\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to trim</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"line-count",qname:"functx:line-count",signature:"($arg as xs:string?) as xs:integer",description:" The number of lines\n",summary:"<p> The number of lines\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to test</div>'}],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:1,name:"lines",qname:"functx:lines",signature:"($arg as xs:string?) as xs:string*",description:" Split a string into separate lines\n",summary:"<p> Split a string into separate lines\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to split</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"max-depth",qname:"functx:max-depth",signature:"($root as node()?) as xs:integer?",description:" The maximum depth of elements in an XML tree\n",summary:"<p> The maximum depth of elements in an XML tree\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"root",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root to start from</div>'}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"max-determine-type",qname:"functx:max-determine-type",signature:"($seq as xs:anyAtomicType*) as xs:anyAtomicType?",description:" The maximum value in a sequence, figuring out its type (numeric or string)\n",summary:"<p> The maximum value in a sequence, figuring out its type (numeric or string)\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values to test</div>'}],returns:{type:"xs:anyAtomicType?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"max-line-length",qname:"functx:max-line-length",signature:"($arg as xs:string?) as xs:integer",description:" The maximum line length\n",summary:"<p> The maximum line length\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to test</div>'}],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:1,name:"max-node",qname:"functx:max-node",signature:"($nodes as node()*) as node()*",description:" The XML node whose typed value is the maximum\n",summary:"<p> The XML node whose typed value is the maximum\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of nodes to test</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"max-string",qname:"functx:max-string",signature:"($strings as xs:anyAtomicType*) as xs:string?",description:" The maximum of a sequence of values, treating them like strings\n",summary:"<p> The maximum of a sequence of values, treating them like strings\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"strings",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"min-determine-type",qname:"functx:min-determine-type",signature:"($seq as xs:anyAtomicType*) as xs:anyAtomicType?",description:" The minimum value in a sequence, figuring out its type (numeric or string)\n",summary:"<p> The minimum value in a sequence, figuring out its type (numeric or string)\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values to test</div>'}],returns:{type:"xs:anyAtomicType?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"min-node",qname:"functx:min-node",signature:"($nodes as node()*) as node()*",description:" The XML node whose typed value is the minimum\n",summary:"<p> The XML node whose typed value is the minimum\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of nodes to test</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"min-non-empty-string",qname:"functx:min-non-empty-string",signature:"($strings as xs:string*) as xs:string?",description:' The minimum of a sequence of strings, ignoring "empty" values\n',summary:'<p> The minimum of a sequence of strings, ignoring "empty" values\n</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"strings",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of strings to search</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"min-string",qname:"functx:min-string",signature:"($strings as xs:anyAtomicType*) as xs:string?",description:" The minimum of a sequence of values, treating them like strings\n",summary:"<p> The minimum of a sequence of values, treating them like strings\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"strings",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of strings</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"mmddyyyy-to-date",qname:"functx:mmddyyyy-to-date",signature:"($dateString as xs:string?) as xs:date?",description:" Converts a string with format MMDDYYYY (with any delimiters) to a date\n",summary:"<p> Converts a string with format MMDDYYYY (with any delimiters) to a date\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"dateString",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the MMDDYYYY string</div>'}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"month-abbrev-en",qname:"functx:month-abbrev-en",signature:"($date as xs:anyAtomicType?) as xs:string?",description:" The month of a date as an abbreviated word (Jan, Feb, etc.)\n",summary:"<p> The month of a date as an abbreviated word (Jan, Feb, etc.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"month-name-en",qname:"functx:month-name-en",signature:"($date as xs:anyAtomicType?) as xs:string?",description:" The month of a date as a word (January, February, etc.)\n",summary:"<p> The month of a date as a word (January, February, etc.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"name-test",qname:"functx:name-test",signature:"($testname as xs:string?, $names as xs:string*) as xs:boolean",description:" Whether a name matches a list of names or name wildcards\n",summary:"<p> Whether a name matches a list of names or name wildcards\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"testname",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name to test</div>'},{name:"names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the list of names or name wildcards</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"namespaces-in-use",qname:"functx:namespaces-in-use",signature:"($root as node()?) as xs:anyURI*",description:" A list of namespaces used in element/attribute names in an XML fragment\n",summary:"<p> A list of namespaces used in element/attribute names in an XML fragment\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"root",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root node to start from</div>'}],returns:{type:"xs:anyURI*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"next-day",qname:"functx:next-day",signature:"($date as xs:anyAtomicType?) as xs:date?",description:" The next day\n",summary:"<p> The next day\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"node-kind",qname:"functx:node-kind",signature:"($nodes as node()*) as xs:string*",description:" The XML node kind (element, attribute, text, etc.)\n",summary:"<p> The XML node kind (element, attribute, text, etc.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node(s) whose kind you want to determine</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"non-distinct-values",qname:"functx:non-distinct-values",signature:"($seq as xs:anyAtomicType*) as xs:anyAtomicType*",description:" Returns any values that appear more than once in a sequence\n",summary:"<p> Returns any values that appear more than once in a sequence\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of values</div>'}],returns:{type:"xs:anyAtomicType*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"number-of-matches",qname:"functx:number-of-matches",signature:"($arg as xs:string?, $pattern as xs:string) as xs:integer",description:" The number of regions that match a pattern\n",summary:"<p> The number of regions that match a pattern\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to test</div>'},{name:"pattern",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the regular expression</div>'}],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:1,name:"ordinal-number-en",qname:"functx:ordinal-number-en",signature:"($num as xs:integer?) as xs:string",description:" Reformats a number as an ordinal number, e.g. 1st, 2nd, 3rd.\n",summary:"<p> Reformats a number as an ordinal number, e.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"num",type:"xs:integer",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"pad-integer-to-length",qname:"functx:pad-integer-to-length",signature:"($integerToPad as xs:anyAtomicType?, $length as xs:integer) as xs:string",description:" Pads an integer to a desired length by adding leading zeros\n",summary:"<p> Pads an integer to a desired length by adding leading zeros\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"integerToPad",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the integer to pad</div>'},{name:"length",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the desired length</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"pad-string-to-length",qname:"functx:pad-string-to-length",signature:"($stringToPad as xs:string?, $padChar as xs:string, $length as xs:integer) as xs:string",description:" Pads a string to a desired length\n",summary:"<p> Pads a string to a desired length\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"stringToPad",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to pad</div>'},{name:"padChar",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the character(s) to use as padding</div>'},{name:"length",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the desired length</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"path-to-node-with-pos",qname:"functx:path-to-node-with-pos",signature:"($node as node()?) as xs:string",description:" A unique path to an XML node (or sequence of nodes)\n",summary:"<p> A unique path to an XML node (or sequence of nodes)\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node sequence</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"path-to-node",qname:"functx:path-to-node",signature:"($nodes as node()*) as xs:string*",description:" A path to an XML node (or sequence of nodes)\n",summary:"<p> A path to an XML node (or sequence of nodes)\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node sequence</div>'}],returns:{type:"xs:string*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"precedes-not-ancestor",qname:"functx:precedes-not-ancestor",signature:"($a as node()?, $b as node()?) as xs:boolean",description:" Whether an XML node precedes another without being its ancestor\n",summary:"<p> Whether an XML node precedes another without being its ancestor\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"a",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first node</div>'},{name:"b",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second node</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"previous-day",qname:"functx:previous-day",signature:"($date as xs:anyAtomicType?) as xs:date?",description:" The previous day\n",summary:"<p> The previous day\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"date",type:"xs:anyAtomicType",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the date</div>'}],returns:{type:"xs:date?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"remove-attributes-deep",qname:"functx:remove-attributes-deep",signature:"($nodes as node()*, $names as xs:string*) as node()*",description:" Removes attributes from an XML fragment, based on name\n",summary:"<p> Removes attributes from an XML fragment, based on name\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root(s) to start from</div>'},{name:"names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the names of the attributes to remove, or * for all attributes</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"remove-attributes",qname:"functx:remove-attributes",signature:"($elements as element(*)*, $names as xs:string*) as element(*)",description:" Removes attributes from an XML element, based on name\n",summary:"<p> Removes attributes from an XML element, based on name\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"elements",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the element(s) from which to remove the attributes</div>'},{name:"names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the names of the attributes to remove, or * for all attributes</div>'}],returns:{type:"element(*)",description:""},errors:[]},{isDocumented:!0,arity:2,name:"remove-elements-deep",qname:"functx:remove-elements-deep",signature:"($nodes as node()*, $names as xs:string*) as node()*",description:" Removes descendant elements from an XML node, based on name\n",summary:"<p> Removes descendant elements from an XML node, based on name\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> root(s) to start from</div>'},{name:"names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the names of the elements to remove</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"remove-elements-not-contents",qname:"functx:remove-elements-not-contents",signature:"($nodes as node()*, $names as xs:string*) as node()*",description:" Removes descendant XML elements but keeps their content\n",summary:"<p> Removes descendant XML elements but keeps their content\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the root(s) to start from</div>'},{name:"names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the names of the elements to remove</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"remove-elements",qname:"functx:remove-elements",signature:"($elements as element(*)*, $names as xs:string*) as element(*)*",description:" Removes child elements from an XML node, based on name\n",summary:"<p> Removes child elements from an XML node, based on name\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"elements",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the element(s) from which you wish to remove the children</div>'},{name:"names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the names of the child elements to remove</div>'}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"repeat-string",qname:"functx:repeat-string",signature:"($stringToRepeat as xs:string?, $count as xs:integer) as xs:string",description:" Repeats a string a given number of times\n",summary:"<p> Repeats a string a given number of times\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"stringToRepeat",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to repeat</div>'},{name:"count",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the desired number of copies</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"replace-beginning",qname:"functx:replace-beginning",signature:"($arg as xs:string?, $pattern as xs:string, $replacement as xs:string) as xs:string",description:" Replaces the beginning of a string, up to a matched pattern\n",summary:"<p> Replaces the beginning of a string, up to a matched pattern\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the entire string to change</div>'},{name:"pattern",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the pattern of characters to replace up to</div>'},{name:"replacement",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the replacement string</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"replace-element-values",qname:"functx:replace-element-values",signature:"($elements as element(*)*, $values as xs:anyAtomicType*) as element(*)*",description:" Updates the content of one or more elements\n",summary:"<p> Updates the content of one or more elements\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"elements",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the elements whose content you wish to replace</div>'},{name:"values",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the replacement values</div>'}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:3,name:"replace-first",qname:"functx:replace-first",signature:"($arg as xs:string?, $pattern as xs:string, $replacement as xs:string) as xs:string",description:" Replaces the first match of a pattern\n",summary:"<p> Replaces the first match of a pattern\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the entire string to change</div>'},{name:"pattern",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the pattern of characters to replace</div>'},{name:"replacement",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the replacement string</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"replace-multi",qname:"functx:replace-multi",signature:"($arg as xs:string?, $changeFrom as xs:string*, $changeTo as xs:string*) as xs:string?",description:" Performs multiple replacements, using pairs of replace parameters\n",summary:"<p> Performs multiple replacements, using pairs of replace parameters\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to manipulate</div>'},{name:"changeFrom",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of strings or patterns to change from</div>'},{name:"changeTo",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence of strings to change to</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"reverse-string",qname:"functx:reverse-string",signature:"($arg as xs:string?) as xs:string",description:" Reverses the order of characters\n",summary:"<p> Reverses the order of characters\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to reverse</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"right-trim",qname:"functx:right-trim",signature:"($arg as xs:string?) as xs:string",description:" Trims trailing whitespace\n",summary:"<p> Trims trailing whitespace\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to trim</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"scheme-from-uri",qname:"functx:scheme-from-uri",signature:"($uri as xs:string?) as xs:string?",description:" Returns the scheme from a URI\n",summary:"<p> Returns the scheme from a URI\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URI</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"sequence-deep-equal",qname:"functx:sequence-deep-equal",signature:"($seq1 as item()*, $seq2 as item()*) as xs:boolean",description:" Whether two sequences have the same XML node content and/or values\n",summary:"<p> Whether two sequences have the same XML node content and/or values\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq1",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first sequence</div>'},{name:"seq2",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second sequence</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"sequence-node-equal-any-order",qname:"functx:sequence-node-equal-any-order",signature:"($seq1 as node()*, $seq2 as node()*) as xs:boolean",description:" Whether two sequences contain the same XML nodes, regardless of order\n",summary:"<p> Whether two sequences contain the same XML nodes, regardless of order\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq1",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first sequence of nodes</div>'},{name:"seq2",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second sequence of nodes</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:2,name:"sequence-node-equal",qname:"functx:sequence-node-equal",signature:"($seq1 as node()*, $seq2 as node()*) as xs:boolean",description:" Whether two sequences contain the same XML nodes, in the same order\n",summary:"<p> Whether two sequences contain the same XML nodes, in the same order\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq1",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first sequence of nodes</div>'},{name:"seq2",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second sequence of nodes</div>'}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sequence-type",qname:"functx:sequence-type",signature:"($items as item()*) as xs:string",description:" The sequence type that represents a sequence of nodes or values\n",summary:"<p> The sequence type that represents a sequence of nodes or values\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the items whose sequence type you want to determine</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"siblings-same-name",qname:"functx:siblings-same-name",signature:"($element as element(*)?) as element(*)*",description:" The siblings of an XML element that have the same name\n",summary:"<p> The siblings of an XML element that have the same name\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"element",type:"element(*)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node</div>'}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"siblings",qname:"functx:siblings",signature:"($node as node()?) as node()*",description:" The siblings of an XML node\n",summary:"<p> The siblings of an XML node\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sort-as-numeric",qname:"functx:sort-as-numeric",signature:"($seq as item()*) as item()*",description:" Sorts a sequence of numeric values or nodes\n",summary:"<p> Sorts a sequence of numeric values or nodes\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence to sort</div>'}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sort-case-insensitive",qname:"functx:sort-case-insensitive",signature:"($seq as item()*) as item()*",description:" Sorts a sequence of values or nodes regardless of capitalization\n",summary:"<p> Sorts a sequence of values or nodes regardless of capitalization\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence to sort</div>'}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sort-document-order",qname:"functx:sort-document-order",signature:"($seq as node()*) as node()*",description:" Sorts a sequence of nodes in document order\n",summary:"<p> Sorts a sequence of nodes in document order\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence to sort</div>'}],returns:{type:"node()*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"sort",qname:"functx:sort",signature:"($seq as item()*) as item()*",description:" Sorts a sequence of values or nodes\n",summary:"<p> Sorts a sequence of values or nodes\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"seq",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence to sort</div>'}],returns:{type:"item()*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-after-if-contains",qname:"functx:substring-after-if-contains",signature:"($arg as xs:string?, $delim as xs:string) as xs:string?",description:" Performs substring-after, returning the entire string if it does not contain the delimiter\n",summary:"<p> Performs substring-after, returning the entire string if it does not contain the delimiter\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to substring</div>'},{name:"delim",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the delimiter</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-after-last-match",qname:"functx:substring-after-last-match",signature:"($arg as xs:string?, $regex as xs:string) as xs:string",description:" The substring after the last text that matches a regex\n",summary:"<p> The substring after the last text that matches a regex\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to substring</div>'},{name:"regex",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the regular expression</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-after-last",qname:"functx:substring-after-last",signature:"($arg as xs:string?, $delim as xs:string) as xs:string",description:" The substring after the last occurrence of a delimiter\n",summary:"<p> The substring after the last occurrence of a delimiter\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to substring</div>'},{name:"delim",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the delimiter</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-after-match",qname:"functx:substring-after-match",signature:"($arg as xs:string?, $regex as xs:string) as xs:string?",description:" The substring after the first text that matches a regex\n",summary:"<p> The substring after the first text that matches a regex\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to substring</div>'},{name:"regex",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the regular expression</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-before-if-contains",qname:"functx:substring-before-if-contains",signature:"($arg as xs:string?, $delim as xs:string) as xs:string?",description:" Performs substring-before, returning the entire string if it does not contain the delimiter\n",summary:"<p> Performs substring-before, returning the entire string if it does not contain the delimiter\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to substring</div>'},{name:"delim",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the delimiter</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-before-last-match",qname:"functx:substring-before-last-match",signature:"($arg as xs:string?, $regex as xs:string) as xs:string?",description:" The substring after the first text that matches a regex\n",summary:"<p> The substring after the first text that matches a regex\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to substring</div>'},{name:"regex",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the regular expression</div>'}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-before-last",qname:"functx:substring-before-last",signature:"($arg as xs:string?, $delim as xs:string) as xs:string",description:" The substring before the last occurrence of a delimiter\n",summary:"<p> The substring before the last occurrence of a delimiter\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to substring</div>'},{name:"delim",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the delimiter</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"substring-before-match",qname:"functx:substring-before-match",signature:"($arg as xs:string?, $regex as xs:string) as xs:string",description:" The substring before the last text that matches a regex\n",summary:"<p> The substring before the last text that matches a regex\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to substring</div>'},{name:"regex",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the regular expression</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"time",qname:"functx:time",signature:"($hour as xs:anyAtomicType, $minute as xs:anyAtomicType, $second as xs:anyAtomicType) as xs:time",description:" Construct a time from an hour, minute and second\n",summary:"<p> Construct a time from an hour, minute and second\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"hour",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the hour</div>'},{name:"minute",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the minute</div>'},{name:"second",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second</div>'}],returns:{type:"xs:time",description:""},errors:[]},{isDocumented:!0,arity:1,name:"timezone-from-duration",qname:"functx:timezone-from-duration",signature:"($duration as xs:dayTimeDuration) as xs:string",description:' Converts an xs:dayTimeDuration into a timezone like "-05:00" or "Z"\n',summary:'<p> Converts an xs:dayTimeDuration into a timezone like "-05:00" or "Z"\n</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"duration",type:"xs:dayTimeDuration",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the duration</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:1,name:"total-days-from-duration",qname:"functx:total-days-from-duration",signature:"($duration as xs:dayTimeDuration?) as xs:decimal?",description:" The total number of days in a dayTimeDuration\n",summary:"<p> The total number of days in a dayTimeDuration\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"duration",type:"xs:dayTimeDuration",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the duration</div>'}],returns:{type:"xs:decimal?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"total-hours-from-duration",qname:"functx:total-hours-from-duration",signature:"($duration as xs:dayTimeDuration?) as xs:decimal?",description:" The total number of hours in a dayTimeDuration\n",summary:"<p> The total number of hours in a dayTimeDuration\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"duration",type:"xs:dayTimeDuration",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the duration</div>'}],returns:{type:"xs:decimal?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"total-minutes-from-duration",qname:"functx:total-minutes-from-duration",signature:"($duration as xs:dayTimeDuration?) as xs:decimal?",description:" The total number of minutes in a dayTimeDuration\n",summary:"<p> The total number of minutes in a dayTimeDuration\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"duration",type:"xs:dayTimeDuration",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the duration</div>'}],returns:{type:"xs:decimal?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"total-months-from-duration",qname:"functx:total-months-from-duration",signature:"($duration as xs:yearMonthDuration?) as xs:decimal?",description:" The total number of months in a yearMonthDuration\n",summary:"<p> The total number of months in a yearMonthDuration\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"duration",type:"xs:yearMonthDuration",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the duration</div>'}],returns:{type:"xs:decimal?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"total-seconds-from-duration",qname:"functx:total-seconds-from-duration",signature:"($duration as xs:dayTimeDuration?) as xs:decimal?",description:" The total number of seconds in a dayTimeDuration\n",summary:"<p> The total number of seconds in a dayTimeDuration\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"duration",type:"xs:dayTimeDuration",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the duration</div>'}],returns:{type:"xs:decimal?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"total-years-from-duration",qname:"functx:total-years-from-duration",signature:"($duration as xs:yearMonthDuration?) as xs:decimal?",description:" The total number of years in a yearMonthDuration\n",summary:"<p> The total number of years in a yearMonthDuration\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"duration",type:"xs:yearMonthDuration",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the duration</div>'}],returns:{type:"xs:decimal?",description:""},errors:[]},{isDocumented:!0,arity:1,name:"trim",qname:"functx:trim",signature:"($arg as xs:string?) as xs:string",description:" Trims leading and trailing whitespace\n",summary:"<p> Trims leading and trailing whitespace\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to trim</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:3,name:"update-attributes",qname:"functx:update-attributes",signature:"($elements as element(*)*, $attrNames as xs:QName*, $attrValues as xs:anyAtomicType*) as element(*)?",description:" Updates the attribute value of an XML element\n",summary:"<p> Updates the attribute value of an XML element\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"elements",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the element(s) for which you wish to update the attribute</div>'},{name:"attrNames",type:"xs:QName",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name(s) of the attribute(s) to add</div>'},{name:"attrValues",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value(s) of the attribute(s) to add</div>'}],returns:{type:"element(*)?",description:""},errors:[]},{isDocumented:!0,arity:2,name:"value-except",qname:"functx:value-except",signature:"($arg1 as xs:anyAtomicType*, $arg2 as xs:anyAtomicType*) as xs:anyAtomicType*",description:" The values in one sequence that aren't in another sequence\n",summary:"<p> The values in one sequence that aren't in another sequence\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first sequence</div>'},{name:"arg2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second sequence</div>'}],returns:{type:"xs:anyAtomicType*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"value-intersect",qname:"functx:value-intersect",signature:"($arg1 as xs:anyAtomicType*, $arg2 as xs:anyAtomicType*) as xs:anyAtomicType*",description:" The intersection of two sequences of values\n",summary:"<p> The intersection of two sequences of values\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first sequence</div>'},{name:"arg2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second sequence</div>'}],returns:{type:"xs:anyAtomicType*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"value-union",qname:"functx:value-union",signature:"($arg1 as xs:anyAtomicType*, $arg2 as xs:anyAtomicType*) as xs:anyAtomicType*",description:" The union of two sequences of values\n",summary:"<p> The union of two sequences of values\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg1",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first sequence</div>'},{name:"arg2",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second sequence</div>'}],returns:{type:"xs:anyAtomicType*",description:""},errors:[]},{isDocumented:!0,arity:1,name:"word-count",qname:"functx:word-count",signature:"($arg as xs:string?) as xs:integer",description:" The number of words\n",summary:"<p> The number of words\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to measure</div>'}],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:1,name:"words-to-camel-case",qname:"functx:words-to-camel-case",signature:"($arg as xs:string?) as xs:string",description:" Turns a string of words into camelCase\n",summary:"<p> Turns a string of words into camelCase\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the string to modify</div>'}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:2,name:"wrap-values-in-elements",qname:"functx:wrap-values-in-elements",signature:"($values as xs:anyAtomicType*, $elementName as xs:QName) as element(*)*",description:" Wraps a sequence of atomic values in XML elements\n",summary:"<p> Wraps a sequence of atomic values in XML elements\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"values",type:"xs:anyAtomicType",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the values to wrap in elements</div>'},{name:"elementName",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the elements to construct</div>'}],returns:{type:"element(*)*",description:""},errors:[]},{isDocumented:!0,arity:2,name:"yearMonthDuration",qname:"functx:yearMonthDuration",signature:"($years as xs:decimal?, $months as xs:integer?) as xs:yearMonthDuration",description:" Construct a yearMonthDuration from a number of years and months\n",summary:"<p> Construct a yearMonthDuration from a number of years and months\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"years",type:"xs:decimal",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of years</div>'},{name:"months",type:"xs:integer",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the number of months</div>'}],returns:{type:"xs:yearMonthDuration",description:""},errors:[]}],variables:[]},"http://zorba.io/modules/zorba-query":{ns:"http://zorba.io/modules/zorba-query",description:" This module contains functions to compile and evaluate queries\n written in either JSONiq or XQuery. Also, it contains function that\n allow to parameterize the static or dynamic evaluation phase.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Juan Zacarias</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/features",prefix:"f"},{uri:"http://zorba.io/options/features",prefix:"op"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/modules/zorba-query",prefix:"zq"}],functions:[{isDocumented:!0,arity:2,name:"bind-context-item",qname:"zq:bind-context-item",signature:"($query-key as xs:anyURI, $dot as item()) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function binds the context-item of the prepared query\n identified by the given key to the $dot argument.</p>\n',summary:"<p>  This function binds the context-item of the prepared query\n identified by the given key to the $dot argument.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'},{name:"dot",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the context item to bind</div>'}],returns:{type:"empty-sequence()",description:"the function has side effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"bind-variable",qname:"zq:bind-variable",signature:"($query-key as xs:anyURI, $var as xs:QName, $value as item()*) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function binds the variable with name $name of\n the prepared query identified by $query-key to the given sequence.</p>\n',summary:"<p>  This function binds the variable with name $name of\n the prepared query identified by $query-key to the given sequence.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'},{name:"var",type:"xs:QName",occurrence:null,description:""},{name:"value",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the sequence to which the external variable $name should be bound</div>'}],returns:{type:"empty-sequence()",description:"the function has side effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:UNDECLARED_VARIABLE if the given variable is not declared in the query.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"delete-query",qname:"zq:delete-query",signature:"($query-key as xs:anyURI) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Deletes the prepared query associated with the given identifier.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">After the query is deleted, the corresponding identifier should\n not be used as argument to any of the functions of this module.</p>\n',summary:"<p>  Deletes the prepared query associated with the given identifier.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'}],returns:{type:"empty-sequence()",description:"the function has side effects and returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"evaluate-sequential",qname:"zq:evaluate-sequential",signature:"($query-key as xs:string) as item()* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Evaluates the given prepared query and returns the result\n of the evaluation. The query must be sequential.</p>\n',summary:"<p>  Evaluates the given prepared query and returns the result\n of the evaluation.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"query-key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'}],returns:{type:"item()*",description:"the result of evaluating the query."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:QUERY_NOT_SEQUENTIAL if the query is not sequential.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:QUERY_IS_UPDATING if the query is an updating query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">any dynamic error that is raised by evaluating the given query.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"evaluate-updating",qname:"zq:evaluate-updating",signature:"($query-key as xs:anyURI) external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Evaluates the given prepared query and applies the updates\n computed by this query. The query must be an updating query.</p>\n',summary:"<p>  Evaluates the given prepared query and applies the updates\n computed by this query.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'}],returns:{type:null,description:"the function has side effects because it applies the updates of the query. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:QUERY_NOT_UPDATING if the query is not an updating query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:QUERY_IS_SEQUENTIAL if the query is sequential.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">any dynamic error that is raised by evaluating the given query or applying its updates.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"evaluate",qname:"zq:evaluate",signature:"($query-key as xs:anyURI) as item()* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Evaluates the given prepared query and returns the result\n of the evaluation. The query must not be sequential or\n updating.</p>\n',summary:"<p>  Evaluates the given prepared query and returns the result\n of the evaluation.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'}],returns:{type:"item()*",description:"the result of evaluating the given query"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:QUERY_IS_UPDATING if the query is an updating query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:QUERY_IS_SEQUENTIAL if the query is sequential.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">any dynamic error that is raised by evaluating the given query.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"external-variables",qname:"zq:external-variables",signature:"($query-key as xs:anyURI) as xs:QName* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns the names of the external variables that\n are declared in the given query (either in the main module or\n in any of the imported library modules).</p>\n',summary:"<p>  The function returns the names of the external variables that\n are declared in the given query (either in the main module or\n in any of the imported library modules).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'}],returns:{type:"xs:QName*",description:"the sequence of names of the said external variables."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-bound-context-item",qname:"zq:is-bound-context-item",signature:"($query-key as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function tests if the context-item is bound for the\n execution of the query referred to by the given query identifier.</p>\n',summary:"<p>  The function tests if the context-item is bound for the\n execution of the query referred to by the given query identifier.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'}],returns:{type:"xs:boolean",description:"true if the context-item is bound, false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"is-bound-variable",qname:"zq:is-bound-variable",signature:"($query-key as xs:anyURI, $var-name as xs:QName) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function tests if the given variable is bound for the\n execution of the query referred to by the given query identifier.</p>\n',summary:"<p>  The function tests if the given variable is bound for the\n execution of the query referred to by the given query identifier.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'},{name:"var-name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the variable</div>'}],returns:{type:"xs:boolean",description:"true if the variable is bound, false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:UNDECLARED_VARIABLE if the given variable is not declared in the query.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-sequential",qname:"zq:is-sequential",signature:"($query-key as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function tests if the query identified by the given key\n is sequential query.</p>\n',summary:"<p>  The function tests if the query identified by the given key\n is sequential query.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'}],returns:{type:"xs:boolean",description:"true if the query is a sequential, false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-updating",qname:"zq:is-updating",signature:"($query-key as xs:anyURI) as xs:boolean external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function tests if the query identified by the given key\n is an updating query.</p>\n',summary:"<p>  The function tests if the query identified by the given key\n is an updating query.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier for a compiled query</div>'}],returns:{type:"xs:boolean",description:"true if the query is an updating query, false otherwise."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"load-from-query-plan",qname:"zq:load-from-query-plan",signature:"($plan as xs:base64Binary) as xs:anyURI external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function loads a given query for execution from a\n xs:base64Binary query plan, obtained through the zq:query-plan function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the query was successfully loaded, the function returns an\n identifier as xs:anyURI. This URI can be passed to other functions\n of this module (e.g. to actually evaluate the query). The URI\n is opaque and its lifetime is bound by the lifetime of the query\n that invoked this function. Further reference or uses\n of the identifier lead to unexpected results.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Successfully prepared queries need to be deleted by passing the resulting\n identifier to the zq:delete-query function of this module.</p>\n',summary:"<p>  The function loads a given query for execution from a\n xs:base64Binary query plan, obtained through the zq:query-plan function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"plan",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the binary query plan.</div>'}],returns:{type:"xs:anyURI",description:"an identifier for the compiled query that can be passed as arguments to other functions of this module."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">any (static or type) error that may be raised during the compilation of the query. For example, err:XPST0003 if the given query could not be parsed.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"load-from-query-plan",qname:"zq:load-from-query-plan",signature:"($plan as xs:base64Binary, $resolver as item()?, $mapper as item()?) as xs:anyURI external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function loads a given query for execution from a\n xs:base64Binary query plan, obtained through the zq:query-plan function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the query was successfully loaded, the function returns an\n identifier as xs:anyURI. This URI can be passed to other functions\n of this module (e.g. to actually evaluate the query). The URI\n is opaque and its lilfetime is bound by the lifetime of the query\n that invoked this function. Further reference or uses\n of the identifier lead to unexpected results.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For important notes regarding the second and third parameters of the\n function, review the comments in zq:prepare-main-module#3.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Successfully prepared queries need to be deleted by passing the resulting\n identifier to the zq:delete-query function of this module.</p>\n',summary:"<p>  The function loads a given query for execution from a\n xs:base64Binary query plan, obtained through the zq:query-plan function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"plan",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the binary query plan.</div>'},{name:"resolver",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URL resolver function.</div>'},{name:"mapper",type:"item()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URI mapper function.</div>'}],returns:{type:"xs:anyURI",description:"an identifier for the compiled query that can be passed as arguments to other functions of this module."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">any (static or type) error that may be raised during the compilation of the query. For example, err:XPST0003 if the given query could not be parsed.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"prepare-library-module",qname:"zq:prepare-library-module",signature:"($library-module-text as xs:string) as empty-sequence() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function compiles a given XQuery or JSONiq library module.\n It can be used to compile-check a module.</p>\n',summary:"<p>  This function compiles a given XQuery or JSONiq library module.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"library-module-text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the library module that should be prepared.</div>'}],returns:{type:"empty-sequence()",description:"the empty-sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">any (static or type) error that may be raised during the compilation of the library module. For example, err:XPST0003 if the given library module could not be parsed.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"prepare-main-module",qname:"zq:prepare-main-module",signature:"($main-module-text as xs:string) as xs:anyURI external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function prepares a given a query for execution.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the query was successfully compiled, the function returns an\n identifier as xs:anyURI. This URI can be passed to other functions\n of this module (e.g. to actually evaluate the query). The URI\n is opaque and its lifetime is bound by the lifetime of the query\n that invoked this function. Further reference or uses\n of the identifier lead to unexpected results.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Successfully prepared queries need to be deleted by passing the resulting\n identifier to the zq:delete-query function of this module.</p>\n',summary:"<p>  The function prepares a given a query for execution.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"main-module-text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query that should be prepared. The query needs to be a XQuery or JSONiq main module.</div>'}],returns:{type:"xs:anyURI",description:"an identifier for the compiled query that can be passed as arguments to other functions of this module."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">any (static or type) error that may be raised during the compilation of the query. For example, err:XPST0003 if the given query could not be parsed.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"prepare-main-module",qname:"zq:prepare-main-module",signature:"($main-module-text as xs:string, $resolver as function (xs:string, xs:string) as item()??, $mapper as function (xs:string, xs:string) as xs:string*?) as xs:anyURI external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function prepares a given query for execution.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the query was successfully compiled, the function returns an\n identifier as xs:anyURI. This URI can be passed to other functions\n of this module (e.g. to actually evaluate the query). The URI\n is opaque and its lifetime is bound by the lifetime of the query\n that invoked this function. Further reference or uses\n of the identifier lead to unexpected results.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Important notes regarding the second and third parameters of the function:</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">--------------------------------------------------------------------------</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">These parameters allow you to specify a URL resolver and a URI mapper\n for Zorba to use when executing this query. See\n <a href="http://www.zorba-xquery.com/html/documentation/2.7.0/zorba/uriresolvers">here</a></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">The second parameter is a function item for a URL\n resolver. The URL resolver function must recive 2 parameters:\n <li>A $namespace as xs:string that will contain the url to be resolved.</li>\n <li>A $entity as xs:string that will contain the type of resolving needed.\n   This can be one of two values: "module" or "schema".</li>\n </ul>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function must return the empty sequence when the specified $namespace\n or $entity are not the ones to be resolved.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">declare function mymod:url-resolver($namespace as xs:string, $entity as xs:string) as item()?\n {\n  if($namespace = \'http://test.xq\')\n  then "module namespace test = \'http://test\'; declare function test:foo(){\'foo\'};"\n  else ()\n };</pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The URL resolver function\'s namespace, name, and parameter naming are\n not restricted by ZQ.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The URL resolver function\'s return type is not restricted, it could be a string, a sequence,\n a node, etc. All the outputs types are to be serialized as a string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The third parameter is a function item for a URI mapper.</p>\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">The URI mapper function, just like the URL resolver, receives 2 parameters:\n <li>A $namespace as xs:string that will contain the URI to be mapped.</li>\n <li>A $entity as xs:string that will contain the type of resolving needed.\n   This can be one of two values: "module" or "schema".</li>\n </ul>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The URI mapper must return an empty sequence when the specified $namesapce or $entity\n are not to be mapped. Unlike the URL resolver this function must return a sequence of strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example:</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">declare function mymod:uri-mapper($namespace as xs:string, $entity as xs:string)\n {\n  if($namespace = \'http://test\')\n  then ("http://zorba.io/test", "http://foo.com/schema/test")\n  else ()\n };</pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The URI mapper function\'s namespace, name, and parameter naming are\n not restricted by ZQ.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In order to pass the above URL resolver and URI mapper to this function,\n use the following syntax:</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n   <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">variable $queryID := zq:prepare-main-module("..query text..",\n      mymod:url-resolver#2, mymod:uri-mapper#2);</pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">That is, the QName of the function followed by "#2". This is XQuery\n "higher-order function" syntax, meaning the function with the specified\n QName which takes two arguments. Since URL resolvers and URI mappers\n must take two arguments, both will always be specified with "#2".</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Both the URL resolver and URI mapper functions are optional, meaning you\n may pass the empty-sequence () for either.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Successfully prepared queries need to be deleted by passing the resulting\n identifier to the zq:delete-query function of this module.</p>\n',summary:"<p>  The function prepares a given query for execution.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"main-module-text",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the query that should be prepared. The query needs to be a XQuery or JSONiq main module.</div>'},{name:"resolver",type:"function (xs:string, xs:string) as item()?",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URL resolver function.</div>'},{name:"mapper",type:"function (xs:string, xs:string) as xs:string*",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the URI mapper function.</div>'}],returns:{type:"xs:anyURI",description:"an identifier for the compiled query that can be passed as arguments to other functions of this module."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">any (static or type) error that may be raised during the compilation of the query. For example, err:XPST0003 if the given query could not be parsed.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"query-plan",qname:"zq:query-plan",signature:"($query-key as xs:anyURI) as xs:base64Binary external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the compiled query identified by the given query-key\n as binary data.</p>\n',summary:"<p>  Returns the compiled query identified by the given query-key\n as binary data.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier of a compiled query.</div>'}],returns:{type:"xs:base64Binary",description:"the query as xs:base64Binary."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_PLAN if there is an error serializing the query.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"variable-value",qname:"zq:variable-value",signature:"($query-key as xs:anyURI, $var-name as xs:QName) as item()* external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function returns the value of a variable that is bound in the\n given query.</p>\n',summary:"<p>  This function returns the value of a variable that is bound in the\n given query.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"query-key",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier of a compiled query.</div>'},{name:"var-name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the variable whose value should be returned.</div>'}],returns:{type:"item()*",description:"the value bound to the given variable."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:NO_QUERY_MATCH if no query with the given identifier was prepared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:UNDECLARED_VARIABLE if the given variable is not declared in the query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zq:UNBOUND_VARIABLE if the given variable doesn\'t have a value.</xqdoc:error>']}],variables:[]},"http://xbrl.io/modules/bizql/hypercubes":{ns:"http://xbrl.io/modules/bizql/hypercubes",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functionality for manipulating hypercubes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A hypercube provides a multi-dimensional structure to organize facts.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The dimensions of a hypercube correspond to XBRL aspects (concepts, entities, periods,\n units, further XBRL dimensions). An XBRL hypercube only is made of XBRL dimensions, however\n including the other aspects as well is very useful in the context of NOLAP, so that xbrl.io\n does so.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">xbrl.io introduces the notion of default hypercube. A default hypercube is implicitly added\n to each component, and only contains the concept, entity, period and unit aspects.\n In other words, the default hypercube\n of a component contains all these facts that do not have any XBRL dimensions.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve all hypercubes contained in a component. You can\n retrieve all facts contained in a hypercube (default dimension values are processed automatically),\n either in raw form, or organized as a (2D) fact table. You can also populate a network (for example,\n a presentation network) with the facts contained in a hypercube.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/concept-maps",prefix:"concept-maps"},{uri:"http://xbrl.io/modules/bizql/entities",prefix:"entities"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://xbrl.io/modules/bizql/hypercubes",prefix:"hypercubes"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"dimensionless-hypercube",qname:"hypercubes:dimensionless-hypercube",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an instantiation of a dimensionless Hypercube containing only the basic\n    characteristics (xbrl:Concept, xbrl:Period, xbrl:Entity, and xbrl:Unit).\n    For each of those included aspects the value space is not limited.</p>\n',summary:"<p>  Returns an instantiation of a dimensionless Hypercube containing only the basic\n    characteristics (xbrl:Concept, xbrl:Period, xbrl:Entity, and xbrl:Unit).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"dimensionless hypercube instantiation."},errors:[]},{isDocumented:!0,arity:1,name:"dimensionless-hypercube",qname:"hypercubes:dimensionless-hypercube",signature:"($options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an instantiation of a dimensionless Hypercube containing only the basic\n    characteristics (xbrl:Concept, xbrl:Period, xbrl:Entity, and xbrl:Unit).\n    For each of those included aspects the value space is not limited.</p>\n',summary:"<p>  Returns an instantiation of a dimensionless Hypercube containing only the basic\n    characteristics (xbrl:Concept, xbrl:Period, xbrl:Entity, and xbrl:Unit).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0">: additional options among which: - Concepts: an array of concept names to include in the hypercube. - Periods: an array of periods to include in the hypercube. - Entities: an array of EIDs to include in the hypercube. - Units: an array of units to include in the hypercube.</div>'}],returns:{type:"object()",description:"dimensionless hypercube instantiation."},errors:[]},{isDocumented:!0,arity:2,name:"fact-table-for-hypercube",qname:"hypercubes:fact-table-for-hypercube",signature:"($hypercube as object(), $archives as item()*) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied hypercube, and populates them with the default dimension values\n when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied hypercube, and populates them with the default dimension values\n when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"hypercube",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hypercube.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $hypercubes:ALL_ARCHIVES for no filtering.</div>'}],returns:{type:"array()",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:3,name:"fact-table-for-hypercube",qname:"hypercubes:fact-table-for-hypercube",signature:"($hypercube as object(), $archives as item()*, $options as object()?) as array()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied hypercube, and populates them with the default dimension values\n when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied hypercube, and populates them with the default dimension values\n when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"hypercube",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hypercube.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="facts#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"array()",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:2,name:"facts-for-hypercube",qname:"hypercubes:facts-for-hypercube",signature:"($hypercube as object(), $archives as item()*) as item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied hypercube, and populates them with the default dimension values\n when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied hypercube, and populates them with the default dimension values\n when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"hypercube",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hypercube.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $hypercubes:ALL_ARCHIVES for no filtering.</div>'}],returns:{type:"item()*",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:3,name:"facts-for-hypercube",qname:"hypercubes:facts-for-hypercube",signature:"($hypercube as object(), $archives as item()*, $options as object()?) as item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all facts from the supplied archives, that are relevant to the\n supplied hypercube, and populates them with the default dimension values\n when missing.</p>\n',summary:"<p>  Retrieves all facts from the supplied archives, that are relevant to the\n supplied hypercube, and populates them with the default dimension values\n when missing.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"hypercube",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hypercube.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $hypercubes:ALL_ARCHIVES for no filtering.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="facts#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"item()*",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:1,name:"hypercubes-for-components",qname:"hypercubes:hypercubes-for-components",signature:"($components as object()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all hypercubes in the supplied components.</p>\n',summary:"<p>  Retrieves all hypercubes in the supplied components.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of components.</div>'}],returns:{type:"object()*",description:"all hypercubes."},errors:[]},{isDocumented:!0,arity:2,name:"hypercubes-for-components",qname:"hypercubes:hypercubes-for-components",signature:"($components as object()*, $names as string*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all hypercubes in the supplied components and\n with the given names.</p>\n',summary:"<p>  Retrieves all hypercubes in the supplied components and\n with the given names.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"components",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of components.</div>'},{name:"names",type:"string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of names.</div>'}],returns:{type:"object()*",description:"all hypercubes."},errors:[]},{isDocumented:!0,arity:3,name:"populate-networks-with-facts",qname:"hypercubes:populate-networks-with-facts",signature:"($networks as object()*, $hypercube as object(), $archives as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied hypercube. Default dimension values are added to the facts\n when missing.</p>\n',summary:"<p>  Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied hypercube.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> networks.</div>'},{name:"hypercube",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hypercube.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs or $hypercubes:ALL_ARCHIVES for no filtering.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated dimension values."},errors:[]},{isDocumented:!0,arity:4,name:"populate-networks-with-facts",qname:"hypercubes:populate-networks-with-facts",signature:"($networks as object()*, $hypercube as object(), $archives as item()*, $options as object()?) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied hypercube. Default dimension values are added to the facts\n when missing.</p>\n',summary:"<p>  Populates a concept-tree network with all facts from the supplied archives,\n that are relevant to the\n supplied hypercube.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"networks",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> networks.</div>'},{name:"hypercube",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a hypercube.</div>'},{name:"archives",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of archives or their AIDs.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="facts#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()*",description:"a sequence of facts with populated dimension values."},errors:[]}],variables:[{name:"hypercubes:ALL_ARCHIVES",type:"boolean",description:" Joker for all archives.\n"}]},"http://www.zorba-xquery.com/modules/xqdoc/batch":{ns:"http://www.zorba-xquery.com/modules/xqdoc/batch",description:" Process XQDoc batches.\n This module generates XQDoc HTML documentation from multiple\n XQuery modules.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">William Candillon <a href="?anchor=">wcandillon at gmail dot com</a></xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.zorba-xquery.com/modules/xqdoc/batch",prefix:"batch"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://expath.org/ns/file",prefix:"file"},{uri:"http://www.functx.com",prefix:"functx"},{uri:"http://www.w3.org/1999/xhtml",prefix:"h"},{uri:"http://www.zorba-xquery.com/modules/xqdoc/html",prefix:"html"},{uri:"http://www.zorba-xquery.com/modules/xqdoc/menu",prefix:"menu"},{uri:"http://www.w3.org/2010/xslt-xquery-serialization",prefix:"out"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://www.xqdoc.org/1.0",prefix:"xq"},{uri:"http://zorba.io/modules/xqdoc",prefix:"xqdoc"}],functions:[{isDocumented:!1,arity:2,name:"add-predeclared-namespaces",qname:"batch:add-predeclared-namespaces",signature:"($xqdoc as element(xq:xqdoc), $namespaces as element(namespace)*) as element(xq:xqdoc)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xqdoc",type:"element(xq:xqdoc)",occurrence:null,description:""},{name:"namespaces",type:"element(namespace)",occurrence:"*",description:""}],returns:{type:"element(xq:xqdoc)",description:""},errors:[]},{isDocumented:!1,arity:1,name:"add-trailing-slash",qname:"batch:add-trailing-slash",signature:"($path as xs:string) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"path",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!0,arity:4,name:"build-xqdoc",qname:"batch:build-xqdoc",signature:"($output-folder as xs:string, $static-folders as xs:string*, $template as element(*), $modules as element(modules))",description:" Run an XQDoc batch.\n",summary:"<p> Run an XQDoc batch.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"output-folder",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Where to write the generated files.</div>'},{name:"static-folders",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Where to copy the static files from.</div>'},{name:"template",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> HTML layout of the generated files. The layount can contains different variables. For instance: <pre class="ace-static" ace-mode="xml"><body><var name="page"/></body></pre> is a valid example. Three variable names are available: <code>page</code>, <code>title</code>, and <code>menu</code>.</div>'},{name:"modules",type:"element(modules)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Document describing the documentation project. For instance: <pre class="ace-static" ace-mode="xml"> <modules> <namespace prefix="ann" uri="http://zorba.io/annotations"/> <main id="modules" label="My Modules"> <!-- Location hints are optionnals --> <module ns="http://example.com/mymodule" label="My Module" id="module" file="module.xq"/> </main> </modules> </pre></div>'}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"copy-static-folders",qname:"batch:copy-static-folders",signature:"($output-folder as xs:string, $static-folders as xs:string*)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"output-folder",type:"xs:string",occurrence:null,description:""},{name:"static-folders",type:"xs:string",occurrence:"*",description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"create-page",qname:"batch:create-page",signature:"($output-folder as xs:string, $page-name as xs:string, $page as element(h:html))",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"output-folder",type:"xs:string",occurrence:null,description:""},{name:"page-name",type:"xs:string",occurrence:null,description:""},{name:"page",type:"element(h:html)",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"create-xml-folder",qname:"batch:create-xml-folder",signature:"($folder as xs:string)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"folder",type:"xs:string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"page",qname:"batch:page",signature:"($template as element(*), $menu as element(ul), $section as element(*)) as element(h:html)",description:"",summary:"",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"template",type:"element(*)",occurrence:null,description:""},{name:"menu",type:"element(ul)",occurrence:null,description:""},{name:"section",type:"element(*)",occurrence:null,description:""}],returns:{type:"element(h:html)",description:""},errors:[]},{isDocumented:!1,arity:2,name:"save-xml",qname:"batch:save-xml",signature:"($output-file, $page)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"output-file",type:null,occurrence:null,description:""},{name:"page",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"section",qname:"batch:section",signature:"($sections as element(section)+) as element(section)+",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sections",type:"element(section)",occurrence:"+",description:""}],returns:{type:"element(section)+",description:""},errors:[]},{isDocumented:!1,arity:2,name:"section",qname:"batch:section",signature:"($sections as element(section)+, $level as xs:integer) as element(section)+",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"sections",type:"element(section)",occurrence:"+",description:""},{name:"level",type:"xs:integer",occurrence:null,description:""}],returns:{type:"element(section)+",description:""},errors:[]},{isDocumented:!1,arity:1,name:"xqdoc",qname:"batch:xqdoc",signature:"($module as element(module)) as element(xq:xqdoc)",description:"",summary:"",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"module",type:"element(module)",occurrence:null,description:""}],returns:{type:"element(xq:xqdoc)",description:""},errors:[]}],variables:[]},"http://zorba.io/modules/data-cleaning/hybrid-string-similarity":{ns:"http://zorba.io/modules/data-cleaning/hybrid-string-similarity",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This library module provides hybrid string similarity functions, combining the properties of\n character-based string similarity functions and token-based string similarity functions.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The logic contained in this module is not specific to any particular XQuery implementation,\n although the module requires the trigonometic functions of XQuery 3.0 or a math extension\n function such as sqrt($x as numeric) for computing the square root.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Bruno Martins and Diogo Sim\u00f5es</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xpath-functions/math",prefix:"math"},{uri:"http://zorba.io/modules/data-cleaning/set-similarity",prefix:"set"},{uri:"http://zorba.io/modules/data-cleaning/character-based-string-similarity",prefix:"simc"},{uri:"http://zorba.io/modules/data-cleaning/hybrid-string-similarity",prefix:"simh"},{uri:"http://zorba.io/modules/data-cleaning/phonetic-string-similarity",prefix:"simp"},{uri:"http://zorba.io/modules/data-cleaning/token-based-string-similarity",prefix:"simt"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:4,name:"monge-elkan-jaro-winkler",qname:"simh:monge-elkan-jaro-winkler",signature:"($s1 as xs:string, $s2 as xs:string, $prefix as xs:integer, $fact as xs:double) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Monge-Elkan similarity coefficient between two strings, using the Jaro-Winkler</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">similarity function to discover token identity.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> monge-elkan-jaro-winkler("Comput. Sci. and Eng. Dept., University of California, San Diego", "Department of Computer Scinece, Univ. Calif., San Diego", 4, 0.1) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.992 </pre></p>\n',summary:"<p>  Returns the Monge-Elkan similarity coefficient between two strings, using the Jaro-Winkler \n  similarity function to discover token identity.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"prefix",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of characters to consider when testing for equal prefixes with the Jaro-Winkler metric.</div>'},{name:"fact",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The weighting factor to consider when the input strings have equal prefixes with the Jaro-Winkler metric.</div>'}],returns:{type:"xs:double",description:"The Monge-Elkan similarity coefficient between the two strings."},errors:[]},{isDocumented:!0,arity:4,name:"soft-cosine-tokens-edit-distance",qname:"simh:soft-cosine-tokens-edit-distance",signature:"($s1 as xs:string, $s2 as xs:string, $r as xs:string, $t as xs:integer) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The tokens from each string are weighted according to their occurence frequency (i.e., weighted according to the\n term-frequency heuristic from Information Retrieval).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The Edit Distance similarity function is used to discover token identity, and tokens having an edit distance\n bellow a given threshold are considered as matching tokens.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> soft-cosine-tokens-edit-distance("The FLWOR Foundation", "FLWOR Found.", " +", 0 ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.408248290463863 </pre></p>\n',summary:"<p>  Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'},{name:"t",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A threshold for the similarity function used to discover token identity.</div>'}],returns:{type:"xs:double",description:"The cosine similarity coefficient between the sets tokens extracted from the two strings."},errors:[]},{isDocumented:!0,arity:6,name:"soft-cosine-tokens-jaro-winkler",qname:"simh:soft-cosine-tokens-jaro-winkler",signature:"($s1 as xs:string, $s2 as xs:string, $r as xs:string, $t as xs:double, $prefix as xs:integer?, $fact as xs:double?) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The tokens from each string are weighted according to their occurence frequency (i.e., weighted according to the\n term-frequency heuristic from Information Retrieval).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The Jaro-Winkler similarity function is used to discover token identity, and tokens having a Jaro-Winkler\n similarity above a given threshold are considered as matching tokens.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> soft-cosine-tokens-jaro-winkler("The FLWOR Foundation", "FLWOR Found.", " +", 1, 4, 0.1 ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.45 </pre></p>\n',summary:"<p>  Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'},{name:"t",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A threshold for the similarity function used to discover token identity.</div>'},{name:"prefix",type:"xs:integer",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of characters to consider when testing for equal prefixes with the Jaro-Winkler metric.</div>'},{name:"fact",type:"xs:double",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The weighting factor to consider when the input strings have equal prefixes with the Jaro-Winkler metric.</div>'}],returns:{type:"xs:double",description:"The cosine similarity coefficient between the sets tokens extracted from the two strings."},errors:[]},{isDocumented:!0,arity:4,name:"soft-cosine-tokens-jaro",qname:"simh:soft-cosine-tokens-jaro",signature:"($s1 as xs:string, $s2 as xs:string, $r as xs:string, $t as xs:double) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The tokens from each string are weighted according to their occurence frequency (i.e., weighted according to the\n term-frequency heuristic from Information Retrieval).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The Jaro similarity function is used to discover token identity, and tokens having a Jaro similarity above\n a given threshold are considered as matching tokens.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> soft-cosine-tokens-jaro("The FLWOR Foundation", "FLWOR Found.", " +", 1 ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.5 </pre></p>\n',summary:"<p>  Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'},{name:"t",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A threshold for the similarity function used to discover token identity.</div>'}],returns:{type:"xs:double",description:"The cosine similarity coefficient between the sets tokens extracted from the two strings."},errors:[]},{isDocumented:!0,arity:3,name:"soft-cosine-tokens-metaphone",qname:"simh:soft-cosine-tokens-metaphone",signature:"($s1 as xs:string, $s2 as xs:string, $r as xs:string) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The tokens from each string are weighted according to their occurence frequency (i.e., weighted according to the\n term-frequency heuristic from Information Retrieval).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The Metaphone phonetic similarity function is used to discover token identity, which is equivalent to saying that\n this function returns the cosine similarity coefficient between sets of Metaphone keys.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> soft-cosine-tokens-metaphone("ALEKSANDER SMITH", "ALEXANDER SMYTH", " +" ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 1.0 </pre></p>\n',summary:"<p>  Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'}],returns:{type:"xs:double",description:"The cosine similarity coefficient between the sets Metaphone keys extracted from the two strings."},errors:[]},{isDocumented:!0,arity:3,name:"soft-cosine-tokens-soundex",qname:"simh:soft-cosine-tokens-soundex",signature:"($s1 as xs:string, $s2 as xs:string, $r as xs:string) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The tokens from each string are weighted according to their occurence frequency (i.e., weighted according to the\n term-frequency heuristic from Information Retrieval).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The Soundex phonetic similarity function is used to discover token identity, which is equivalent to saying that\n this function returns the cosine similarity coefficient between sets of Soundex keys.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> soft-cosine-tokens-soundex("ALEKSANDER SMITH", "ALEXANDER SMYTH", " +") </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 1.0 </pre></p>\n',summary:"<p>  Returns the cosine similarity coefficient between sets of tokens extracted from two strings.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first string.</div>'},{name:"s2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second string.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'}],returns:{type:"xs:double",description:"The cosine similarity coefficient between the sets of Soundex keys extracted from the two strings."},errors:[]}],variables:[]},"http://xbrl.io/modules/bizql/rules":{ns:"http://xbrl.io/modules/bizql/rules",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functions for storing, retrieving, and modifying\n rules. Rules can be used in BizQL queries to:</p>\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>Impute Facts that were not reported within an instance, yet can be\n       derived from reported facts.</li>\n   <li>Compute arbitrary new Facts (Ratios, Calculated Facts, Facts from different\n       Datasources/Instances, etc.).</li>\n   <li>Run validation and/or verification rules</li>\n </ul>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A Rule is an object containing a BizQL fomula to execute if a condition is met.\n For example if a user queries for a certain concept and a rule exists for this\n concept then the rule is applied to get the fact.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve the rules associated with each report\n schema. You can also query for facts by making implicitly use of the mapping.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://xbrl.io/modules/bizql/archives",prefix:"archives"},{uri:"http://xbrl.io/modules/bizql/facts",prefix:"facts"},{uri:"http://xbrl.io/modules/bizql/networks",prefix:"networks"},{uri:"http://xbrl.io/modules/bizql/report-schemas",prefix:"report-schemas"},{uri:"http://xbrl.io/modules/bizql/rules",prefix:"rules"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:7,name:"create-computed-fact",qname:"rules:create-computed-fact",signature:"($template-fact as object(), $concept-name-or-aspects as item(), $value as item(), $rule as object(), $audit-trail-message as string, $source-facts as object()*, $options as object()?) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Helper function to create a new fact within a rule.</p>\n',summary:"<p>  Helper function to create a new fact within a rule.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"template-fact",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a fact object that will be used as a template for the newly created fact</div>'},{name:"concept-name-or-aspects",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> either a name of the concept for the newly created fact or a complete aspects object to be used in the new fact.</div>'},{name:"value",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a value for the newly created fact</div>'},{name:"rule",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the rule in which this fact has been created</div>'},{name:"audit-trail-message",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a verbose string message explaining how and why this fact has been created</div>'},{name:"source-facts",type:"object()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> sequence of facts that have been used to compute the new fact (this will only be added to the AuditTrails if the audit-trail option is set to "debug")</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> <a href="facts#standard_options">standard fact retrieving options</a>.</div>'}],returns:{type:"object()",description:"the decimal value of the fact or 0."},errors:[]},{isDocumented:!0,arity:1,name:"fact-trail",qname:"rules:fact-trail",signature:"($fact as object()?) as string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Serializes a fact to a simple string format that can be used in\n    audit trail messages to trail the value of the fact.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned string follows the pattern: fact-concept-name[fact-value]</p>\n',summary:"<p>  Serializes a fact to a simple string format that can be used in\n    audit trail messages to trail the value of the fact.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a single fact to serialize to a simple informative string</div>'}],returns:{type:"string",description:"the string with key information about the fact."},errors:[]},{isDocumented:!0,arity:2,name:"fact-trail",qname:"rules:fact-trail",signature:"($fact as object()?, $name as string) as string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Serializes a fact to a simple string format that can be used in\n    audit trail messages to trail the value of the fact.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The returned string follows the pattern: fact-concept-name[fact-value]</p>\n',summary:"<p>  Serializes a fact to a simple string format that can be used in\n    audit trail messages to trail the value of the fact.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"fact",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an empty-sequence or a single fact to serialize to a simple informative string</div>'},{name:"name",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> an alternative name to use if the $fact is an empty-sequence otherwise the name will be taken from the fact</div>'}],returns:{type:"string",description:"the string with key information about the fact."},errors:[]},{isDocumented:!0,arity:0,name:"rules",qname:"rules:rules",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Retrieves all rules from all report schemas.</p>\n',summary:"<p>  Retrieves all rules from all report schemas.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"all rules."},errors:[]},{isDocumented:!0,arity:1,name:"rules",qname:"rules:rules",signature:"($report-schemas-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the rules from the given report schemas.</p>\n',summary:"<p>  Return the rules from the given report schemas.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"report-schemas-or-ids",type:"item()",occurrence:"*",description:""}],returns:{type:"object()*",description:"the rules from the report schemas."},errors:[]}],variables:[]},"http://www.28msec.com/modules/lock":{ns:"http://www.28msec.com/modules/lock",description:" Sausalito provides a an application level locking mechanism that can be\n used e.g. to ensure exclusive access to data.\n As the store ensures atomicity of of single document updates, atomic\n updates to multiple documents are implemented using this mechanism.\n Locks can be acquired and re-acquired at any time during a request and\n are released at the end of the request.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/lock",prefix:"lock"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"try-acquire",qname:"lock:try-acquire",signature:"($lock-name as xs:string) as xs:boolean external",description:' Tries to acquire a lock.\n This operation is non-blocking if the lock cannot be acquired immediately.\n To check and modify the stock of a product wihtout interference from\n concurrent requests a lock could be used like this:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n if (lock:try-acquire("stock-update"))\n then\n   if (stock:check($product-id))\n   then\n     {\n       order:finalize($order-id);\n       stock:decrement($product-id);\n     }\n   else\n     order:hold($order-id);\n else\n   ...\n </pre>\n',summary:"<p> Tries to acquire a lock.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"lock-name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the lock.</div>'}],returns:{type:"xs:boolean",description:"true if the lock could be acquired, false otherwise."},errors:[]},{isDocumented:!0,arity:2,name:"try-acquire",qname:"lock:try-acquire",signature:"($lock-name as xs:string, $reason as xs:string) as xs:boolean external",description:" tries to acquire a lock\n",summary:"<p> tries to acquire a lock\n</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"lock-name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the lock.</div>'},{name:"reason",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a reason for the acquisition of the lock that can be used for</div>'}],returns:{type:"xs:boolean",description:"true if the lock could be acquired, false otherwise."},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/xqdoc/html":{ns:"http://www.zorba-xquery.com/modules/xqdoc/html",description:' Convert an XQDoc document into an HTML document.\n This module contains a single <code xmlns:xqdoc="http://www.xqdoc.org/1.0">convert()</code> function\n that transform an XQDoc document into an HTML document.\n Usage:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n let $xqdoc := xqdoc:xqdoc("http://expath.org/ns/file")\n return html:convert($xqdoc)\n </pre>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">William Candillon <a href="?anchor=">wcandillon at gmail dot com</a></xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/xqdoc/html",prefix:"html"},{uri:"http://www.w3.org/2010/xslt-xquery-serialization",prefix:"o"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://www.xqdoc.org/1.0",prefix:"xq"}],functions:[{isDocumented:!1,arity:1,name:"convert",qname:"html:convert",signature:"($xqdoc as element(xq:xqdoc)) as element(div)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"xqdoc",type:"element(xq:xqdoc)",occurrence:null,description:""}],returns:{type:"element(div)",description:""},errors:[]}],variables:[]},"http://api.28.io/model":{ns:"http://api.28.io/model",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://zorba.io/modules/store/static/collections/ddl",prefix:"cddl"},{uri:"http://zorba.io/modules/store/static/collections/dml",prefix:"cdml"},{uri:"http://zorba.io/modules/store/static/indexes/ddl",prefix:"iddl"},{uri:"http://zorba.io/modules/store/static/indexes/dml",prefix:"idml"},{uri:"http://api.28.io/model",prefix:"model"},{uri:"http://www.zorba-xquery.com/schemas/pul",prefix:"pul"},{uri:"http://zorba.io/modules/reference",prefix:"ref"},{uri:"http://www.zorba-xquery.com/schemas/xdm",prefix:"xdm"}],functions:[{isDocumented:!1,arity:1,name:"applyPUL",qname:"model:applyPUL",signature:"($pul as schema-element(pul:pending-update-list))",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"pul",type:"schema-element(pul:pending-update-list)",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"applyPULOp",qname:"model:applyPULOp",signature:"($pul)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"pul",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"build-nodes",qname:"model:build-nodes",signature:"($definition)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"definition",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!0,arity:1,name:"collection-qname",qname:"model:collection-qname",signature:"($name as xs:string) as xs:QName",description:" Returns the QName for a collection. Returns the empty sequence if no collection with the given name exists.\n",summary:"<p> Returns the QName for a collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection as string</div>'}],returns:{type:"xs:QName",description:"the QName for the collection or the empty sequence"},errors:[]},{isDocumented:!1,arity:2,name:"delete-node-collection",qname:"model:delete-node-collection",signature:"($collection as xs:QName, $noderef as xs:anyURI?)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"collection",type:"xs:QName",occurrence:null,description:""},{name:"noderef",type:"xs:anyURI",occurrence:"?",description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"delete-node",qname:"model:delete-node",signature:"($noderef as xs:anyURI)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"noderef",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"element-node",qname:"model:element-node",signature:"($definition as schema-element(xdm:element))",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"definition",type:"schema-element(xdm:element)",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"find-keys",qname:"model:find-keys",signature:"($collection)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"collection",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!0,arity:0,name:"get-collection-names",qname:"model:get-collection-names",signature:"() as xs:string*",description:" Returns all collection names\n",summary:"<p> Returns all collection names\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"collection names as a sequence of strings"},errors:[]},{isDocumented:!0,arity:1,name:"get-collection-size",qname:"model:get-collection-size",signature:"($name as xs:string) as xs:integer",description:" Returns the size of a collection\n",summary:"<p> Returns the size of a collection\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection as string</div>'}],returns:{type:"xs:integer",description:"the size of the collection"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">if the collection chosen by $name does not exist</xqdoc:error>']},{isDocumented:!0,arity:1,name:"get-collection",qname:"model:get-collection",signature:"($name as xs:string) as node()*",description:" Returns the whole collection with a given name\n",summary:"<p> Returns the whole collection with a given name\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> name of collection to return</div>'}],returns:{type:"node()*",description:"sequence of nodes of the collection"},errors:[]},{isDocumented:!0,arity:4,name:"get-collection",qname:"model:get-collection",signature:"($name as xs:string, $first-noderef as xs:anyURI?, $offset as xs:integer?, $limit as xs:integer)",description:' Returns "a page" of the collection (a part)\n',summary:'<p> Returns "a page" of the collection (a part)\n</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the collection as string</div>'},{name:"first-noderef",type:"xs:anyURI",occurrence:"?",description:""},{name:"offset",type:"xs:integer",occurrence:"?",description:""},{name:"limit",type:"xs:integer",occurrence:null,description:""}],returns:{type:null,description:"a sequence of nodes from the collection"},errors:[]},{isDocumented:!1,arity:4,name:"get-column-id",qname:"model:get-column-id",signature:"($basepath as xs:string?, $name as xs:string, $isattribute as xs:boolean, $columns) as xs:integer",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"basepath",type:"xs:string",occurrence:"?",description:""},{name:"name",type:"xs:string",occurrence:null,description:""},{name:"isattribute",type:"xs:boolean",occurrence:null,description:""},{name:"columns",type:null,occurrence:null,description:""}],returns:{type:"xs:integer",description:""},errors:[]},{isDocumented:!0,arity:0,name:"get-index-names",qname:"model:get-index-names",signature:"() as xs:string*",description:" Returns all index names\n",summary:"<p> Returns all index names\n</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"index names as a sequence of strings"},errors:[]},{isDocumented:!1,arity:2,name:"get-index-point",qname:"model:get-index-point",signature:"($index-name as xs:string, $index-key)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"index-name",type:"xs:string",occurrence:null,description:""},{name:"index-key",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"get-node-group",qname:"model:get-node-group",signature:"($noderef as xs:anyURI)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"noderef",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"get-node-path",qname:"model:get-node-path",signature:"($node)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"get-node",qname:"model:get-node",signature:"($noderef as xs:anyURI)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"noderef",type:"xs:anyURI",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!0,arity:1,name:"index-qname",qname:"model:index-qname",signature:"($name as xs:string) as xs:QName",description:" Returns the QName for an index. Returns the empty sequence if no index with the given name exists.\n",summary:"<p> Returns the QName for an index.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the index as string</div>'}],returns:{type:"xs:QName",description:"the QName for the index or the empty sequence"},errors:[]},{isDocumented:!1,arity:3,name:"insert-attribute",qname:"model:insert-attribute",signature:"($noderef as xs:anyURI, $attribute as xs:string, $value)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"noderef",type:"xs:anyURI",occurrence:null,description:""},{name:"attribute",type:"xs:string",occurrence:null,description:""},{name:"value",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:4,name:"insert-node-collection-ordered",qname:"model:insert-node-collection-ordered",signature:"($collection as xs:QName, $noderef as xs:anyURI?, $position as xs:string, $nodes)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"collection",type:"xs:QName",occurrence:null,description:""},{name:"noderef",type:"xs:anyURI",occurrence:"?",description:""},{name:"position",type:"xs:string",occurrence:null,description:""},{name:"nodes",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:4,name:"insert-node-collection",qname:"model:insert-node-collection",signature:"($collection as xs:QName, $noderef as xs:anyURI?, $position as xs:string, $nodes)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"collection",type:"xs:QName",occurrence:null,description:""},{name:"noderef",type:"xs:anyURI",occurrence:"?",description:""},{name:"position",type:"xs:string",occurrence:null,description:""},{name:"nodes",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:5,name:"insert-node-collection",qname:"model:insert-node-collection",signature:"($collection as xs:QName, $noderef as xs:anyURI?, $position as xs:string, $nodes, $validate as xs:boolean)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"collection",type:"xs:QName",occurrence:null,description:""},{name:"noderef",type:"xs:anyURI",occurrence:"?",description:""},{name:"position",type:"xs:string",occurrence:null,description:""},{name:"nodes",type:null,occurrence:null,description:""},{name:"validate",type:"xs:boolean",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"insert-node",qname:"model:insert-node",signature:"($noderef as xs:anyURI, $position as xs:string, $newnodes)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"noderef",type:"xs:anyURI",occurrence:null,description:""},{name:"position",type:"xs:string",occurrence:null,description:""},{name:"newnodes",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:4,name:"make-table-row",qname:"model:make-table-row",signature:"($idx, $node, $columns, $namespaces)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"idx",type:null,occurrence:null,description:""},{name:"node",type:null,occurrence:null,description:""},{name:"columns",type:null,occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:5,name:"make-table-row",qname:"model:make-table-row",signature:"($node, $path as xs:string?, $row, $columns, $namespaces)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"node",type:null,occurrence:null,description:""},{name:"path",type:"xs:string",occurrence:"?",description:""},{name:"row",type:null,occurrence:null,description:""},{name:"columns",type:null,occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"make-table",qname:"model:make-table",signature:"($nodes, $namespaces)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"node-name",qname:"model:node-name",signature:"($node as element(*), $namespaces) as xs:string",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"node",type:"element(*)",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:2,name:"node-path-index",qname:"model:node-path-index",signature:"($node as node(), $parent as node()) as xs:integer?",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:null,description:""},{name:"parent",type:"node()",occurrence:null,description:""}],returns:{type:"xs:integer?",description:""},errors:[]},{isDocumented:!1,arity:2,name:"node-prefix",qname:"model:node-prefix",signature:"($node as element(*), $namespaces) as xs:string?",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"node",type:"element(*)",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!1,arity:1,name:"node-reference",qname:"model:node-reference",signature:"($node) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:null,occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:1,name:"node",qname:"model:node",signature:"($definition)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"definition",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"rename-node",qname:"model:rename-node",signature:"($noderef as xs:anyURI, $name as xs:QName)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"noderef",type:"xs:anyURI",occurrence:null,description:""},{name:"name",type:"xs:QName",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"replace-node",qname:"model:replace-node",signature:"($noderef as xs:anyURI, $nodes)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"noderef",type:"xs:anyURI",occurrence:null,description:""},{name:"nodes",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"replace-value",qname:"model:replace-value",signature:"($noderef as xs:anyURI, $value)",description:"",summary:"",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"noderef",type:"xs:anyURI",occurrence:null,description:""},{name:"value",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"resolve-qname",qname:"model:resolve-qname",signature:"($name as xs:QName, $namespaces) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:1,name:"type-save",qname:"model:type-save",signature:"($val) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"val",type:null,occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:1,name:"type",qname:"model:type",signature:"($val as xs:anyAtomicType?) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"val",type:"xs:anyAtomicType",occurrence:"?",description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:1,name:"unused-prefix",qname:"model:unused-prefix",signature:"($namespaces) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]}],variables:[]},"http://api.28.io/validation":{ns:"http://api.28.io/validation",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"http://zorba.io/modules/reflection",prefix:"reflection"},{uri:"http://www.28msec.com/modules/http/response",prefix:"resp"},{uri:"http://api.28.io/validation",prefix:"validate"}],functions:[{isDocumented:!1,arity:3,name:"by-schema-array",qname:"validate:by-schema-array",signature:"($obj, $schema as array(), $path as xs:string)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"obj",type:null,occurrence:null,description:""},{name:"schema",type:"array()",occurrence:null,description:""},{name:"path",type:"xs:string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"by-schema-obj",qname:"validate:by-schema-obj",signature:"($obj as object(), $schema as object(), $path as xs:string)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"obj",type:"object()",occurrence:null,description:""},{name:"schema",type:"object()",occurrence:null,description:""},{name:"path",type:"xs:string",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"by-schema-primitive",qname:"validate:by-schema-primitive",signature:"($obj, $schema-type as xs:string, $path)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"obj",type:null,occurrence:null,description:""},{name:"schema-type",type:"xs:string",occurrence:null,description:""},{name:"path",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"by-schema",qname:"validate:by-schema",signature:"($obj as object(), $schema as object())",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"obj",type:"object()",occurrence:null,description:""},{name:"schema",type:"object()",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"expression",qname:"validate:expression",signature:"($expression as xs:string, $is-domain-expr as xs:boolean) as xs:boolean",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"expression",type:"xs:string",occurrence:null,description:""},{name:"is-domain-expr",type:"xs:boolean",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]},{isDocumented:!1,arity:1,name:"type",qname:"validate:type",signature:"($type as xs:string) as xs:boolean",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:""},errors:[]}],variables:[]},"http://api.28.io/sandbox":{ns:"http://api.28.io/sandbox",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"http://zorba.io/modules/reference",prefix:"ref"},{uri:"http://zorba.io/modules/reflection",prefix:"reflection"},{uri:"http://api.28.io/sandbox",prefix:"sandbox"}],functions:[{isDocumented:!1,arity:3,name:"filter",qname:"sandbox:filter",signature:"($nodes, $xpath as xs:string, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""},{name:"xpath",type:"xs:string",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"get-names",qname:"sandbox:get-names",signature:"($nodes, $path as xs:string, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""},{name:"path",type:"xs:string",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"get-values",qname:"sandbox:get-values",signature:"($nodes, $path as xs:string, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""},{name:"path",type:"xs:string",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"key-constraint",qname:"sandbox:key-constraint",signature:"($nodes, $condition as xs:string, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""},{name:"condition",type:"xs:string",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:1,name:"ns-declarations",qname:"sandbox:ns-declarations",signature:"($namespaces) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:4,name:"order",qname:"sandbox:order",signature:"($nodes, $path as xs:string, $descending as xs:boolean, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""},{name:"path",type:"xs:string",occurrence:null,description:""},{name:"descending",type:"xs:boolean",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:3,name:"tuple-constraint",qname:"sandbox:tuple-constraint",signature:"($nodes, $condition as xs:string, $namespaces)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""},{name:"condition",type:"xs:string",occurrence:null,description:""},{name:"namespaces",type:null,occurrence:null,description:""}],returns:{type:null,description:""},errors:[]}],variables:[]},"http://zorba.io/modules/store/static/collections/dml":{ns:"http://zorba.io/modules/store/static/collections/dml",description:' This modules provides a set of functions to modify a collection\n and retrieve the items contained in a particular collection.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n This module is part of\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/xqddf.html">Zorba\'s XQuery Data Definition Facility</a>.\n All the collections managed by this module have to be pre-declared in the\n prolog of a module.\n Please refer to the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/data_lifecycle.html">general documentation</a>\n for more information and examples.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/data_lifecycle.html">Data Lifecycle</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../zorba/xqddf.html">XQuery Data Definition Facility</a></xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/collections/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/indexes/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/ddl</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/modules/store/static/integrity-constraints/dml</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://zorba.io/errors</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Nicolae Brinza, Matthias Brantner, David Graf, Till Westmann, Markos Zaharioudakis</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/store/static/collections/dml",prefix:"cdml"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:3,name:"apply-insert-after",qname:"cdml:apply-insert-after",signature:"($name as xs:QName, $pos as item(), $content as item()*) as item()* external",description:' This function does the same thing as the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">insert-after()</code>\n function except it immediately applies the resulting pending updates and\n returns the items that have been inserted.\n',summary:"<p> This function does the same thing as the  insert-after() \n function except it immediately applies the resulting pending updates and\n returns the items that have been inserted.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"pos",type:"item()",occurrence:null,description:""},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of items whose copies to insert.</div>'}],returns:{type:"item()*",description:"The sequence of items that have been inserted."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is const, append-only, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if <code>$target</code> is not in the collection.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"apply-insert-before",qname:"cdml:apply-insert-before",signature:"($name as xs:QName, $target as item(), $content as item()*) as item()* external",description:' This function does the same thing as <code xmlns:xqdoc="http://www.xqdoc.org/1.0">insert-before()</code> except it\n immediately applies the resulting pending updates and returns the items that\n have been inserted.\n',summary:"<p> This function does the same thing as  insert-before()  except it\n immediately applies the resulting pending updates and returns the items that\n have been inserted.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"target",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The item in the collection before which <code>$content</code> will be inserted.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of items whose copies to insert.</div>'}],returns:{type:"item()*",description:"The sequence of items that have been inserted."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection $name is const, append-only, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if <code>$target</code> is not an item that is contained in the collection.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"apply-insert-first",qname:"cdml:apply-insert-first",signature:"($name as xs:QName, $content as item()*) as item()* external",description:' This function does the same thing as <code xmlns:xqdoc="http://www.xqdoc.org/1.0">insert-first()</code> except it\n immediately applies the resulting pending updates and returns the items that\n have been inserted.\n',summary:"<p> This function does the same thing as  insert-first()  except it\n immediately applies the resulting pending updates and returns the items that\n have been inserted.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of items whose copies to insert.</div>'}],returns:{type:"item()*",description:"The Sequence of items that have been inserted."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection $name is append-only, const, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"apply-insert-last",qname:"cdml:apply-insert-last",signature:"($name as xs:QName, $content as item()*) as item()* external",description:' This function does the same thing as <code xmlns:xqdoc="http://www.xqdoc.org/1.0">insert-last()</code> except it\n immediately applies the resulting pending updates and returns the items that\n have been inserted.\n',summary:"<p> This function does the same thing as  insert-last()  except it\n immediately applies the resulting pending updates and returns the items that\n have been inserted.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of items whose copies to insert.</div>'}],returns:{type:"item()*",description:"The sequence of items that have been inserted."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is const.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"apply-insert",qname:"cdml:apply-insert",signature:"($name as xs:QName, $content as item()*) as item()* external",description:' This function does the same thing as <code xmlns:xqdoc="http://www.xqdoc.org/1.0">insert()</code> except it\n immediately applies the resulting pending updates and returns the items that\n have been inserted.\n',summary:"<p> This function does the same thing as  insert()  except it\n immediately applies the resulting pending updates and returns the items that\n have been inserted.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of items whose copies to insert.</div>'}],returns:{type:"item()*",description:"The sequence of items that have been inserted."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is append-only, const, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"collection-name",qname:"cdml:collection-name",signature:"($item as item()) as xs:QName external",description:" Gets the name of the collection the given item (node or JSON item) belongs\n to.\n",summary:"<p> Gets the name of the collection the given item (node or JSON item) belongs\n to.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"item",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The item for which to get the name of its collection.</div>'}],returns:{type:"xs:QName",description:"The name of the collection to which the given item belongs."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if <code>$item</code> does not belong to a collection.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"collection",qname:"cdml:collection",signature:"($name as xs:QName) as item()* external",description:" Gets the sequence of nodes or JSON items from a collection.\n",summary:"<p> Gets the sequence of nodes or JSON items from a collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection.</div>'}],returns:{type:"item()*",description:"The seqnence of items from the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"collection",qname:"cdml:collection",signature:"($name as xs:QName, $skip as xs:integer) as item()* external",description:" Gets the sequence of nodes or JSON items from a collection.\n",summary:"<p> Gets the sequence of nodes or JSON items from a collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection.</div>'},{name:"skip",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The initial number of items to skip.</div>'}],returns:{type:"item()*",description:"The (sub)sequence of items from the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"collection",qname:"cdml:collection",signature:"($name as xs:QName, $start as xs:anyURI, $skip as xs:integer) as item()* external",description:' Gets the sequence of items (nodes or JSON items) from a collection.\n The parameters <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$start</code> and <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$skip</code> can be used to\n skip over some items at the beginning of the collection.\n If both are given, both are applied:\n first <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$start</code> to skip to the referenced item\n and then <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$skip</code> to skip that additional number of items.\n',summary:"<p> Gets the sequence of items (nodes or JSON items) from a collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection.</div>'},{name:"start",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The reference to the first item to return.</div>'},{name:"skip",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of additional items to skip.</div>'}],returns:{type:"item()*",description:"The sub-sequence from the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZAPI0028 If the given URI is not a valid node position computed by the <code>np:node-position</code> function.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZSTR0066 if <code>$start</code> does not reference a node from the collection.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"delete-first",qname:"cdml:delete-first",signature:"($name as xs:QName) external",description:" Deletes the first item from a collection.\n",summary:"<p> Deletes the first item from a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to delete from.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, deletes the first item from the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is const or append-only.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if the collection is empty.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete-first",qname:"cdml:delete-first",signature:"($name as xs:QName, $number as xs:integer) external",description:' Deletes the first <i xmlns:xqdoc="http://www.xqdoc.org/1.0">N</i> items from a collection.\n',summary:"<p> Deletes the first  N  items from a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to delete from.</div>'},{name:"number",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of items to delete.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, deletes the items from the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is const or append-only.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if the collection contains less than <code>$number</code> items.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"delete-last",qname:"cdml:delete-last",signature:"($name as xs:QName) external",description:" Deletes the last item from a collection.\n",summary:"<p> Deletes the last item from a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to delete from.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, deletes the last item from the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is const, append-only, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if the collection is empty.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete-last",qname:"cdml:delete-last",signature:"($name as xs:QName, $number as xs:integer) external",description:' Deletes the last <i xmlns:xqdoc="http://www.xqdoc.org/1.0">N</i> items from a collection.\n',summary:"<p> Deletes the last  N  items from a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to delete from.</div>'},{name:"number",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The number of items to delete.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, deletes the items."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if the collection contains less than <code>$number</code> items.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"delete",qname:"cdml:delete",signature:"($items as item()*) external",description:" Deletes items (nodes or JSON items) from a collection.\n",summary:"<p> Deletes items (nodes or JSON items) from a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"items",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The items in the collection to delete.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, deletes the items from their collections."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is const, append-only, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if any item in <code>$items</code> is not a member of a collection or not all items belong to the same collection.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"edit",qname:"cdml:edit",signature:"($target as item(), $content as item()) external",description:" Edits the first supplied item so as to make it look exactly like a copy of\n the second supplied item while retaining its original identity.\n",summary:"<p> Edits the first supplied item so as to make it look exactly like a copy of\n the second supplied item while retaining its original identity.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"target",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The target item to be edited.</div>'},{name:"content",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The item that serves as an edit goal.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, performs the edit."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection to which <code>$target</code> belongs is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection to which <code>$target</code> belongs is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection to which <code>$target</code> belongs is append-only, const, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0017 if <code>$target</code> is not a member of a collection.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0037 if the collection is append-only.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0038 if the collection is a queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0039 if <code>$target</code> is not a root.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0040 if <code>$target</code> cannot be updated to match the content (for example, because the target is a node and the content is an object).</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type (as specified in the collection declaration) according to the rules for SequenceType Matching.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"index-of",qname:"cdml:index-of",signature:"($item as item()) as xs:integer external",description:" Gets the position of the given item (node or JSON item) within its\n collection.\n",summary:"<p> Gets the position of the given item (node or JSON item) within its\n collection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"item",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The item to get the index of.</div>'}],returns:{type:"xs:integer",description:'The position of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$item</code> in its collection.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if <code>$item</code> does not belong to a collection.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"insert-after",qname:"cdml:insert-after",signature:"($name as xs:QName, $target as item(), $content as item()*) external",description:" The insert-after function is an updating function that inserts copies of the\n given items (nodes or JSON items) into a collection at the position\n directly following the given target item.\n",summary:"<p> The insert-after function is an updating function that inserts copies of the\n given items (nodes or JSON items) into a collection at the position\n directly following the given target item.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"target",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The item in the collection after which <code>$content</code> will be inserted.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of items whose copies to insert.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, inserts the items into the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is const, append-only, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if <code>$target</code> is not a node that is contained in the collection.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"insert-before",qname:"cdml:insert-before",signature:"($name as xs:QName, $target as item(), $content as item()*) external",description:" Inserts copies of the given items (nodes or JSON items) into a collection at\n the position directly preceding the given target item.\n",summary:"<p> Inserts copies of the given items (nodes or JSON items) into a collection at\n the position directly preceding the given target item.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"target",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The item in the collection before which <code>$content</code> will be inserted.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of items whose copies to insert.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, inserts the items into the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is const, append-only, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0011 if <code>$target</code> is not an item that is contained in the collection.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"insert-first",qname:"cdml:insert-first",signature:"($name as xs:QName, $content as item()*) external",description:" Inserts copies of the given items (nodes or JSON items) at the beginning of\n a collection.\n",summary:"<p> Inserts copies of the given items (nodes or JSON items) at the beginning of\n a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of items whose copies to insert.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, inserts the items into the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is append-only, const, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"insert-last",qname:"cdml:insert-last",signature:"($name as xs:QName, $content as item()*) external",description:" Inserts copies of the given items (nodes or JSON items) at the end of a\n collection.\n",summary:"<p> Inserts copies of the given items (nodes or JSON items) at the end of a\n collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of itemss whose copies to insert.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, inserts the items into the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is const.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0012 if the collection is unordered.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"insert",qname:"cdml:insert",signature:"($name as xs:QName, $content as item()*) external",description:" Inserts copies of the given items (nodes or JSON items) into a collection.\n Note that the insertion position of the items in the collection is not\n defined.\n",summary:"<p> Inserts copies of the given items (nodes or JSON items) into a collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection to insert into.</div>'},{name:"content",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The sequence of items whose copies to insert.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, inserts the items into the collection."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0006 if the collection is append-only, const, or queue.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDTY0001 if <code>$content</code> does not match the expected type as specified in the collection declaration according to the rules for SequenceType Matching.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"truncate",qname:"cdml:truncate",signature:"($name as xs:QName) external",description:" Deletes the entire contents of collection.\n Please note that applying this function can not be undone in case\n an error happens during the application of the containing PUL.\n",summary:"<p> Deletes the entire contents of collection.</p>",annotation_str:"",annotations:[],updating:!0,parameters:[{name:"name",type:"xs:QName",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the collection whose content to delete.</div>'}],returns:{type:null,description:"An empty XDM instance and a pending update list that, once applied, deletes the nodes."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0001 if the collection is not declared.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZDDY0003 if the collection is not available.</xqdoc:error>']}],variables:[]},"http://www.28msec.com/modules/http-request":{ns:"http://www.28msec.com/modules/http-request",description:' The request module provides functions for accessing\n information contained in the HTTP request used to evaluate the current\n query. For example, the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">param-names</tt> function can be used to\n retrieve all the names of the parameters contained in a request.\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.28msec.com/modules/http/request#2.0",prefix:"req"},{uri:"http://www.28msec.com/modules/http-request",prefix:"request"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"binary-content",qname:"request:binary-content",signature:"() as xs:base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the content of the request as base64Binary.</p>\n',summary:"<p>  Returns the content of the request as base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:base64Binary",description:"The content of the request as base64Binary."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-binary-content if the content contained in the body of the request cannot be treated as binary because it is a request with multipart or url-encoded content.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"binary-part",qname:"request:binary-part",signature:"($ref as xs:string) as xs:base64Binary",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the value of a part as base64Binary.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A part is identified by a reference that is the value of a\n <tt>src</tt> field returned by the <tt>request:parts</tt> function.</p>\n',summary:"<p>  Returns the value of a part as base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"ref",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the part</div>'}],returns:{type:"xs:base64Binary",description:"the value of the part as base64Binary"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-part if the part with the given name ($ref) does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:0,name:"content-length",qname:"request:content-length",signature:"() as xs:integer?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the length of the content in bytes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The value returned corresponds to the value of the HTTP\n content-length header. The function returns an empty sequence\n if this header does not exist in the request or its value\n could not be converted to item of type xs:integer</p>.\n',summary:"<p>  Returns the length of the content in bytes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:integer?",description:"The content-length in bytes of the content sent with this request or the empty sequence if the content-length header does not exist in the request."},errors:[]},{isDocumented:!0,arity:0,name:"content-type",qname:"request:content-type",signature:"() as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the content-type of the data sent with this request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note that the content-type is only set for PUT and POST requests.</p>\n',summary:"<p>  Returns the content-type of the data sent with this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string?",description:"The content-type of the request if it is a PUT or POST request. Otherwise, it returns the empty sequence."},errors:[]},{isDocumented:!0,arity:0,name:"header-accept",qname:"request:header-accept",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the values of the HTTP ACCEPT header.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The data is returned as a sequence of objects\n as shown in the following example.</p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n {\n   "type" : "text",\n   "subtype" : "html",\n   "quality" : 1\n }\n </pre>\n',summary:"<p>  Returns the values of the HTTP ACCEPT header.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"The header values of the header ACCEPT or the empty sequence if the header is not contained in the request. The order of the returned objects reflects the order of the components in the header."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-header if the accept header cannot be parsed</xqdoc:error>']},{isDocumented:!0,arity:0,name:"header-names",qname:"request:header-names",signature:"() as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the names of all the HTTP headers in this request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Header fields are colon-separated name-value pairs, terminated\n by a carriage return (CR) and line feed (LF) character sequence. The\n names and values of each header are allowed to consist of US-ASCII\n characters only.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The names of the headers are returned using upper-case letters.\n If a header with the same name is contained multiple times in a request,\n its name is only returned once. The order of the names in the resulting\n sequence does not reflect the order of the headers in the request. If\n a header does not have a value, it is as if the header does not exist\n in the request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Note that the header names user-agent and content-type are not\n returned by this function. They are returned by the corresponding\n functions of this module module\n (e.g. <a href="#user-agent-0">user-agent</a>).</p>\n',summary:"<p>  Returns the names of all the HTTP headers in this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"The names of the headers of this request or the empty sequence if no headers are contained in the request."},errors:[]},{isDocumented:!0,arity:1,name:"header-value",qname:"request:header-value",signature:"($name as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the value of the HTTP header with the given name.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Header fields are colon-separated name-value pairs, terminated\n by a carriage return (CR) and line feed (LF) character sequence. The\n names and values of each header are allowed to consist of US-ASCII\n characters only.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that header names are considered case-insensitive.\n Also note, that only one value is returned if multiple headers with the\n same names exist in the request. This value is a comma-separated list\n of the values of the headers in the order in which the headers appeared\n in the request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">All headers having a name that starts with SAUSALITO_ are reserved\n and will not be returned by this function.</p>\n',summary:"<p>  Returns the value of the HTTP header with the given name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The header name for which the value should be returned.</div>'}],returns:{type:"xs:string?",description:'The header value of the header with the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$name</tt> argument or the empty sequence if no header with that name is contained in the request.'},errors:[]},{isDocumented:!0,arity:0,name:"headers",qname:"request:headers",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an object containing the request\'s HTTP header names and\n values.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Header fields are colon-separated name-value pairs, terminated\n by a carriage return (CR) and line feed (LF) character sequence. The\n names and values of each header are allowed to consist of US-ASCII\n characters only.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The structure of the object is as shown in the following example:\n <pre>\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">All headers having a name that starts with SAUSALITO_ are reserved\n and will not be returned by this function.</p>\n',summary:"<p>  Returns an object containing the request's HTTP header names and\n values.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:'The header value of the header with the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">$name</tt> argument or the empty sequence if no header with that name is contained in the request.'},errors:[]},{isDocumented:!0,arity:0,name:"method-delete",qname:"request:method-delete",signature:"() as xs:boolean",description:" Returns true if the HTTP method of this request is DELETE.\n",summary:"<p> Returns true if the HTTP method of this request is DELETE.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is DELETE, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-get",qname:"request:method-get",signature:"() as xs:boolean",description:" Returns true if the HTTP method of this request is GET.\n",summary:"<p> Returns true if the HTTP method of this request is GET.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is GET, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-head",qname:"request:method-head",signature:"() as xs:boolean",description:" Returns true if the HTTP method of this request is HEAD.\n",summary:"<p> Returns true if the HTTP method of this request is HEAD.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is HEAD, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-options",qname:"request:method-options",signature:"() as xs:boolean",description:" Returns true if the HTTP method of this request is OPTION.\n",summary:"<p> Returns true if the HTTP method of this request is OPTION.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is OPTION, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-post",qname:"request:method-post",signature:"() as xs:boolean",description:" Returns true if the HTTP method of this request is POST.\n",summary:"<p> Returns true if the HTTP method of this request is POST.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is POST, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method-put",qname:"request:method-put",signature:"() as xs:boolean",description:" Returns true if the HTTP method of this request is PUT.\n",summary:"<p> Returns true if the HTTP method of this request is PUT.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"true if the HTTP method of this request is PUT, false otherwise."},errors:[]},{isDocumented:!0,arity:0,name:"method",qname:"request:method",signature:"() as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the name of the HTTP method used to make this request.</p>\n',summary:"<p>  Returns the name of the HTTP method used to make this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The request method used to make this request (i.e. GET, POST, PUT, DELETE or HEAD)."},errors:[]},{isDocumented:!0,arity:0,name:"param-names",qname:"request:param-names",signature:"() as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the names of the parameters contained in the current request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parameters are name-value pairs contained in the query string of the URL\n used to make this request. As defined in RFC 1738, the query string of a\n URL starts with a "?" character and ends with the character (if any).\n Additionally, such name-value pairs may be part of the request\'s body if\n it is a PUT or POST request and the content-type of the request is\n "application/x-www-form-urlencoded". Name-value pairs are separated\n using either the "&amp;" or the ";" character.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In general, the names and the values  are precent-encoded. This function\n does the decoding of the parameters, i.e. it returns the values being\n not percent-encoded.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Also, the names of each parameter (after being precent-decoded) are\n treated as UTF-8. Please see the <tt>http:param-names#1</tt> function\n for retrieving parameter names submitted using a encoding other than UTF-8.\n </p>\n',summary:"<p>  Returns the names of the parameters contained in the current request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string*",description:"The names of all parameters in this request. The empty sequence is returned if there are none."},errors:[]},{isDocumented:!0,arity:1,name:"param-names",qname:"request:param-names",signature:"($encoding as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the names of the parameters contained in the current request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is similar to the <tt>request:param-names#0</tt> function.\n However, the names are treated (after precent-decoding) using the\n given encoding supplied as parameter. For example, parameters might\n be encoded using the ISO-8859-1 encoding.</p>\n',summary:"<p>  Returns the names of the parameters contained in the current request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"encoding",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The encoding of the parameters in the request (e.g. ISO-8859-1).</div>'}],returns:{type:"xs:string*",description:"The names of all parameters in this request. The empty sequence is returned if there are none."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"param-values",qname:"request:param-values",signature:"($name as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a sequence of parameter values for the given parameter name\n which are contained in the URL\'s query string or the body of a POST or PUT\n request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parameters are name-value pairs contained in the query string of the URL\n used to make this request. As defined in RFC 1738, the query string of a\n URL starts with a "?" character and ends with the character (if any).\n Additionally, such name-value pairs may be part of the request\'s body if\n it is a PUT or POST request and the content-type of the request is\n "application/x-www-form-urlencoded". Name-value pairs are separated\n using either the "&amp;" or the ";" character.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In general, the names and the values  are precent-encoded. This function\n does the decoding of the parameters, i.e. it returns the values being\n not percent-encoded.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Also, the names and the values of each parameter (after being precent-decoded)\n are treated as UTF-8. Please see the <tt>http:param-values#3</tt> function\n for retrieving parameters submitted using a encoding other than UTF-8.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function returns the empty-sequence if no parameter with the\n given name exists in this request. If you want the function to return\n a default value other than the empty sequence, use the\n <tt>http:param-values#2</tt> function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A URL could contain the following query string:\n <tt>name1=value1&amp;name2=value2;name1=value3&amp;name3</tt>.\n <tt>name1=value1&amp;name2=value2&amp;name1=value3&amp;name3</tt>.\n The name value pairs in this query string are\n <ul>\n   <li> name: <tt>name1</tt>; values: <tt>value1</tt> and <tt>value3</tt></li>\n   <li> name: <tt>name2</tt>; value: <tt>value2</tt></li>\n   <li> name: <tt>name3</tt>; value: <tt/></li>\n </ul>\n </p>\n',summary:"<p>  Returns a sequence of parameter values for the given parameter name\n which are contained in the URL's query string or the body of a POST or PUT\n request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the parameter whose value(s) should be returned.</div>'}],returns:{type:"xs:string*",description:"A sequence of values for the parameter with the given name. The empty sequence is returned if no parameter exists with the given name."},errors:[]},{isDocumented:!0,arity:2,name:"param-values",qname:"request:param-values",signature:"($name as xs:string, $default-values as xs:string*) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a sequence of parameter values for the given parameter name\n which are contained in the URL\'s query string or the body of a POST or PUT\n request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is similar to the <tt>request:param-values#1</tt> function.\n However, instead of returning the empty-sequence as a default value it returns\n the given default-values sequence if no parameter with the given name is found\n in this request.</p>\n',summary:"<p>  Returns a sequence of parameter values for the given parameter name\n which are contained in the URL's query string or the body of a POST or PUT\n request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the parameter whose value(s) should be returned.</div>'},{name:"default-values",type:"xs:string",occurrence:"*",description:""}],returns:{type:"xs:string*",description:"A sequence of values for the parameter with the given name. The sequence given as $default-values parameter is returned if no parameter exists with the given name."},errors:[]},{isDocumented:!0,arity:3,name:"param-values",qname:"request:param-values",signature:"($name as xs:string, $default-values as xs:string*, $encoding as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a sequence of parameter values for the given parameter name\n which are contained in the URL\'s query string or the body of a POST or PUT\n request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is similar to the <tt>request:param-values#2</tt> function.\n However, the names and values are treated (after precent-decoding) using the\n given encoding supplied as third parameter. For example, parameters might\n be encoded using the ISO-8859-1 encoding.</p>\n',summary:"<p>  Returns a sequence of parameter values for the given parameter name\n which are contained in the URL's query string or the body of a POST or PUT\n request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of the parameter whose value(s) should be returned.</div>'},{name:"default-values",type:"xs:string",occurrence:"*",description:""},{name:"encoding",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The encoding of the parameters in the request (e.g. ISO-8859-1)</div>'}],returns:{type:"xs:string*",description:"A sequence of values for the parameter with the given name. The sequence given as $default-values parameter is returned if no parameter exists with the given name."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"params",qname:"request:params",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an object containg the parameter names and values contained\n in the URL\'s query string or the body of a POST or PUT\n request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The structure of the object for the query string\n "param1=value1;param2&amp;param2=value2"\n <pre>\n {\n   "param1" : "value1",\n   "param2" : [ "", "value2" ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parameters are name-value pairs contained in the query string of the URL\n used to make this request. As defined in RFC 1738, the query string of a\n URL starts with a "?" character and ends with the character (if any).\n Additionally, such name-value pairs may be part of the request\'s body if\n it is a PUT or POST request and the content-type of the request is\n "application/x-www-form-urlencoded". Name-value pairs are separated\n using either the "&amp;" or the ";" character.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In general, the names and the values  are precent-encoded. This function\n does the decoding of the parameters, i.e. it returns the values being\n not percent-encoded.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Also, the names and the values of each parameter (after being precent-decoded)\n are treated as UTF-8. Please see the <tt>http:params#1</tt> function\n for retrieving parameters submitted using a encoding other than UTF-8.</p>\n',summary:"<p>  Returns an object containg the parameter names and values contained\n in the URL's query string or the body of a POST or PUT\n request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"An object containing all the parameter names and values. An empty object is returned if the request doesn't contain any parameters."},errors:[]},{isDocumented:!0,arity:1,name:"params",qname:"request:params",signature:"($encoding as xs:string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an object containg the parameter names and values contained\n in the URL\'s query string or the body of a POST or PUT\n request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The structure of the object for the query string\n "param1=value1;param2&amp;param2=value2"\n <pre>\n {\n   "param1" : "value1",\n   "param2" : [ "", "value2" ]\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Parameters are name-value pairs contained in the query string of the URL\n used to make this request. As defined in RFC 1738, the query string of a\n URL starts with a "?" character and ends with the character (if any).\n Additionally, such name-value pairs may be part of the request\'s body if\n it is a PUT or POST request and the content-type of the request is\n "application/x-www-form-urlencoded". Name-value pairs are separated\n using either the "&amp;" or the ";" character.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In general, the names and the values  are precent-encoded. This function\n does the decoding of the parameters, i.e. it returns the values being\n not percent-encoded.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The name and value of each parameter (after being percent-decoded) are treated\n in the encoding given by the <tt>$encoding</tt> paramter.</p>\n',summary:"<p>  Returns an object containg the parameter names and values contained\n in the URL's query string or the body of a POST or PUT\n request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"encoding",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The encoding of the parameters in the request (e.g. ISO-8859-1)</div>'}],returns:{type:"object()",description:"An object containing all the parameter names and values. An empty object is returned if the request doesn't contain any parameters."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"parts",qname:"request:parts",signature:"() as object()?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the metadata of all parts contained in a multipart request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The metadata is returned as an object\n as shown in the following example.</p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n {\n   "media-type" : "multipart/form-data; boundary=----------------------------93298e7a66a4",\n   "parts" : [ {\n     "headers" : {\n       "Content-Disposition" : "form-data; name=\\"upload\\"; filename=\\"tmp.txt\\"",\n       "Content-Type" : "text/plain"\n     },\n     "filename" : "tmp.txt",\n     "name" : "upload",\n     "src" : "urn:uuid:09be48d1-da0e-42c1-a115-a697e1779c45",\n     "size" : "153"\n   }, {\n     "headers" : {\n       "Content-Disposition" : "form-data; name=\\"press\\""\n     },\n     "name" : "press",\n     "src" : "urn:uuid:c80e0609-b703-4d47-9171-441eb397a562",\n     "size" : "2"\n   } ]\n }\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The <tt>media-type</tt> field describes the content-type as given in the\n request. Specifically, its value is equal to the value returned by\n <tt>request:header-values("Content-Type")</tt>).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Each of the array members of the <tt>parts</tt> field represents one\n part of the multipart request. Each such part contains a header field\n containing one field for each headers belonging to that part.\n The value of the <tt>src</tt> field can be used to retrieve the actual value\n of the part by passing it to the <tt>http:text-part</tt> or\n <tt>http:binary-part</tt> functions. The remaining fields represent a\n parameter of the Content-Disposition header as described in RFC 2183\n (e.g. filename, name, creation-date).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that recursive multipart content is not supported.</p>\n',summary:"<p>  Returns the metadata of all parts contained in a multipart request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()?",description:"an object representing the metadata of the multipart content or an empty sequence if there is no content."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:0,name:"path",qname:"request:path",signature:"() as xs:string",description:" Return the path component of the request URI. The path starts after the\n host and ends before the query string starts.\n",summary:"<p> Return the path component of the request URI.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The path component of the request URI"},errors:[]},{isDocumented:!0,arity:0,name:"query",qname:"request:query",signature:"() as xs:string",description:" <p xmlns:xqdoc=\"http://www.xqdoc.org/1.0\">Returns the query string that was used to make this request.</p>\n <p xmlns:xqdoc=\"http://www.xqdoc.org/1.0\">The query string contains the part of the request URL that\n starts with the '?' character to the end or the starting of the\n fragment (i.e. the '#' character).</p>\n",summary:"<p>  Returns the query string that was used to make this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The query string part of the request's URL"},errors:[]},{isDocumented:!0,arity:0,name:"remote-addr",qname:"request:remote-addr",signature:"() as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the IP address of the client to which this request\n is connected.</p>\n',summary:"<p>  Returns the IP address of the client to which this request\n is connected.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The IP address on the client side to which this request is connected."},errors:[]},{isDocumented:!0,arity:0,name:"remote-port",qname:"request:remote-port",signature:"() as xs:int",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the port of the client to which this request is connected.</p>\n',summary:"<p>  Returns the port of the client to which this request is connected.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:int",description:"The port on the client side to which this request is connected."},errors:[]},{isDocumented:!0,arity:0,name:"server-name",qname:"request:server-name",signature:"() as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the server name of the server running the application.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The web server\'s hostname or IP address.</p>\n',summary:"<p>  Returns the server name of the server running the application.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The name of the server that runs the application accepting this request."},errors:[]},{isDocumented:!0,arity:0,name:"server-port",qname:"request:server-port",signature:"() as xs:int",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the sever port to which the client making the current request\n is connected.</p>\n',summary:"<p>  Returns the sever port to which the client making the current request\n is connected.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:int",description:"The server port to which the client is connected."},errors:[]},{isDocumented:!0,arity:0,name:"text-content",qname:"request:text-content",signature:"() as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the content of the request as string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns the content of the request only\n if the content-type refers to a type that can be treated\n as text (e.g. text/* or application/xml). The function raises\n an error if the content cannot be treated as text.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The text content is interpreted using the encoding/charset\n that is specified in the Content-Type header of the request. If\n no charset is specified, the default ISO-8859-1 is used. If a encoding\n other than the specified or default one should be used, the\n <tt>request:text-content#1</tt> function should be used.</p>\n',summary:"<p>  Returns the content of the request as string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The content of the request as a string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the encoding specified in the Content-Type header is invalid or not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the content contained in the body of the request cannot be treated as text.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"text-content",qname:"request:text-content",signature:"($overwrite-encoding as xs:string) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the content of the request as string interpreting\n it with the given encoding.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns the content of the request only\n if the content-type refers to a type that can be treated\n as text (e.g. text/* or application/xml). The function raises\n an error if the content cannot be treated as text.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The text content is interpreted using the given encoding/charset.\n That is, the charset specified in the Content-Type header of the request\n is ignored. An error is raised if the given encoding is invalid\n or not supported.</p>\n',summary:"<p>  Returns the content of the request as string interpreting\n it with the given encoding.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"overwrite-encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:"The content of the request as a string."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the encoding specified in the Content-Type header or the $overwrite-encoding parameter is invalid or not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the content contained in the body of the request cannot be treated as text.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"text-part",qname:"request:text-part",signature:"($ref as xs:string) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the value of a part as string</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A part is identified by a reference that is the value of a\n <tt>src</tt> field returned by the <tt>request:parts</tt> function.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The value of the text part is interpreted using the encoding/charset\n given in the headers of the part. If no encoding is given, the default\n US-ASCII is assumed.</p>\n',summary:"<p>  Returns the value of a part as string \n  A part is identified by a reference that is the value of a\n  src  field returned by the  request:parts  function.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"ref",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the part</div>'}],returns:{type:"xs:string",description:"the value of the part as string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the encoding given in the headers of the part is invalid or not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the value of the part cannot be treated as text</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-part if the part with the given name ($ref) does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:2,name:"text-part",qname:"request:text-part",signature:"($ref as xs:string, $overwrite-encoding as xs:string) as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the value of a part as string interpreting\n it with the given encoding.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A part is identified by a reference that is the value of a\n <tt>src</tt> field returned by the <tt>request:parts</tt> function.</p>\n',summary:"<p>  Returns the value of a part as string interpreting\n it with the given encoding.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"ref",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the part</div>'},{name:"overwrite-encoding",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:"the value of the part as string"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-encoding if the encoding given using the $overwrite-encoding parameter is invalid or not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:no-text-content if the value of the part cannot be treated as text</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-part if the part with the given name ($ref) does not exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:non-multipart if the current request does not contain multipart content</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">request:invalid-multipart if the multipart content is invalid (e.g. the boundary is missing)</xqdoc:error>']},{isDocumented:!0,arity:0,name:"uri",qname:"request:uri",signature:"() as xs:string",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the URI that was used to make this request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The value returned contains the part of the URL starting\n from the path to the end or the starting of the fragment (i.e.\n the \'#\' character).</p>\n',summary:"<p>  Returns the URI that was used to make this request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string",description:"The path and query string part of the request's URL"},errors:[]},{isDocumented:!0,arity:0,name:"user-agent",qname:"request:user-agent",signature:"() as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the user agent that made to perform the current request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function returns the value of the User-Agent header\n contained in the current request.</p>\n',summary:"<p>  Returns the user agent that made to perform the current request.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:string?",description:"The user agent used to perform this request of the empty sequence if there was no User-Agent header in the request."},errors:[]}],variables:[]},"http://www.28msec.com/modules/physical-reference":{ns:"http://www.28msec.com/modules/physical-reference",description:' The module provides functions to compute an immutable and opaque reference\n for nodes, objects, or arrays and to retrieve such items given their\n identifier, respectively.\n The identifiers are immutable, i.e. a identifier does not change\n during the items lifetime and cannot be reused for another item after the\n original item gets deleted.\n Identifiers are unique, in that, two different items will never have the same\n identifier. A item, at any time during its lifetime, can be retrieved by its\n identifier. Identifiers can only be computed for items stored in a MongoDB\n collection.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please see the <a href="../../html/data_lifecycle.html">data lifecycle\n documentation</a> about details on storing items.</p>\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="../../html/data_lifecycle.html">Data Lifecycle</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.28msec.com/modules/physical-reference",prefix:"ref"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"dereference",qname:"ref:dereference",signature:"($arg as object()) as item()? external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the node, object, or array identified by the given reference.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns the empty sequence if the item\n that is referenced does not exist.</p>\n',summary:"<p>  Returns the node, object, or array identified by the given reference.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the identifier of the item to retrieve.</div>'}],returns:{type:"item()?",description:"the item identified by the identifier passed as parameter or the empty-sequence if no item with that URI is found."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ref::REFERENCE is if the given identifier is invalid.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"reference",qname:"ref:reference",signature:"($arg as item()) as object() external",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an immutable and opaque reference (with type xs:anyURI) for\n a given node, object, or array.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The generated identifier is immutable, i.e. a identifier does not\n change during the item\'s lifetime and cannot be reused for another node after\n the original item gets deleted.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Identifiers are also unique, in that, two different items will never\n have the same identifier.</p>\n A item, at any time during its lifetime, can be retrieved by its\n identifier, using the <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">ref:dereference</tt> function.\n Please note that a reference can only be retrieved for a JSON object or JSON\n array if the item is a member of a collection.\n',summary:"<p>  Returns an immutable and opaque reference (with type xs:anyURI) for\n a given node, object, or array.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"arg",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node, object, or array for which the URI should be computed</div>'}],returns:{type:"object()",description:"the opaque URI of the item."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">ref::COLLECTION is raised if the object or array passed as argument is not a member of a collection.</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/data-cleaning/conversion":{ns:"http://zorba.io/modules/data-cleaning/conversion",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This library module provides data conversion functions for processing calendar dates,\n temporal values, currency values, units of measurement, location names and postal addresses.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The logic contained in this module is not specific to any particular XQuery implementation.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Bruno Martins and Diogo Sim\u00f5es</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/data-cleaning/conversion",prefix:"conversion"},{uri:"http://www.ecb.int/vocabulary/2002-08-01/eurofxref",prefix:"exref"},{uri:"http://www.zorba-xquery.com/modules/http-client",prefix:"http"},{uri:"http://zorba.io/modules/reflection",prefix:"reflection"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://api.whitepages.com/schema/",prefix:"wp"}],functions:[{isDocumented:!0,arity:1,name:"address-from-domain",qname:"conversion:address-from-domain",signature:"($domain as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses a whois service to discover information about a given domain name, returning a sequence of strings\n for the addresses associated to the name.</p>\n',summary:"<p>  Uses a whois service to discover information about a given domain name, returning a sequence of strings\n for the addresses associated to the name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"domain",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string*",description:'A sequence of strings for the addresses associated to the domain name. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"><b> Attention : This function is still not implemented. </b></p>'},errors:[]},{isDocumented:!0,arity:2,name:"address-from-geocode",qname:"conversion:address-from-geocode",signature:"($lat as xs:double, $lon as xs:double) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Geospatial coordinates to placename converter, acting as a wrapper over the Yahoo! reverse geocoder service.</p>\n',summary:"<p>  Geospatial coordinates to placename converter, acting as a wrapper over the Yahoo! reverse geocoder service.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"lat",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Geospatial latitude.</div>'},{name:"lon",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Geospatial longitude.</div>'}],returns:{type:"xs:string*",description:"The sequence of strings corresponding to the different components (e.g., street, city, country, etc.) of the place name that corresponds to the input geospatial coordinates."},errors:[]},{isDocumented:!0,arity:1,name:"address-from-phone",qname:"conversion:address-from-phone",signature:"($phone-number as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses a White-pages Web service to discover information about a given phone number,\n returning a string for the address associated to the phone number.</p>\n',summary:"<p>  Uses a White-pages Web service to discover information about a given phone number,\n returning a string for the address associated to the phone number.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"phone-number",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A string with 10 digits corresponding to the phone number.</div>'}],returns:{type:"xs:string*",description:"A string for the addresses associated to the phone number."},errors:[]},{isDocumented:!0,arity:1,name:"address-from-user",qname:"conversion:address-from-user",signature:"($name as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses a White-pages Web service to discover information about a given name,\n returning a sequence of strings for the addresses associated to the name.</p>\n',summary:"<p>  Uses a White-pages Web service to discover information about a given name,\n returning a sequence of strings for the addresses associated to the name.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of person or organization.</div>'}],returns:{type:"xs:string*",description:"A sequence of strings for the addresses associated to the name."},errors:[]},{isDocumented:!0,arity:4,name:"currency-convert",qname:"conversion:currency-convert",signature:"($v as xs:double, $m1 as xs:string, $m2 as xs:string, $date as xs:string) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Currency conversion function, acting as a wrapper over the WebService from the European Central Bank.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">WebService documentation at <a src="http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html">http://www.ecb.int/stats/exchange/eurofxref/html/index.en.html</a></p>\n',summary:"<p>  Currency conversion function, acting as a wrapper over the WebService from the European Central Bank.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"v",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The amount we wish to convert.</div>'},{name:"m1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The source currency (e.g., "EUR").</div>'},{name:"m2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The target currency (e.g., "USD").</div>'},{name:"date",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The reference date.</div>'}],returns:{type:"xs:double",description:"The value resulting from the conversion."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">conversion:NOTSUPPORTED if the date, the source currency type or the target currency type are not known to the service.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"geocode-from-address",qname:"conversion:geocode-from-address",signature:"($q as xs:string*) as xs:double*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Placename to geospatial coordinates converter, acting as a wrapper over the Yahoo! geocoder service.</p>\n',summary:"<p>  Placename to geospatial coordinates converter, acting as a wrapper over the Yahoo! geocoder service.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"q",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings corresponding to the different components (e.g., street, city, country, etc.) of the place name.</div>'}],returns:{type:"xs:double*",description:"The pair of latitude and longitude coordinates associated with the input address."},errors:[]},{isDocumented:!0,arity:1,name:"name-from-domain",qname:"conversion:name-from-domain",signature:"($domain as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses a whois service to discover information about a given domain name, returning a sequence of strings\n for the person or organization names associated to the name.</p>\n',summary:"<p>  Uses a whois service to discover information about a given domain name, returning a sequence of strings\n for the person or organization names associated to the name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"domain",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string*",description:'A sequence of strings for the person or organization names associated to the domain name. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"><b> Attention : This function is still not implemented. </b></p>'},errors:[]},{isDocumented:!0,arity:1,name:"phone-from-address",qname:"conversion:phone-from-address",signature:"($address as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses a White-pages Web service to discover information about a given address,\n returning a sequence of strings for the phone number associated to the address.</p>\n',summary:"<p>  Uses a White-pages Web service to discover information about a given address,\n returning a sequence of strings for the phone number associated to the address.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A string corresponding to the address (ex: 5655 E Gaskill Rd, Willcox, AZ, US).</div>'}],returns:{type:"xs:string*",description:"A sequence of strings for the phone number or organization's names associated to the address."},errors:[]},{isDocumented:!0,arity:1,name:"phone-from-domain",qname:"conversion:phone-from-domain",signature:"($domain as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses a whois service to discover information about a given domain name, returning a sequence of strings\n for the phone numbers associated to the name.</p>\n',summary:"<p>  Uses a whois service to discover information about a given domain name, returning a sequence of strings\n for the phone numbers associated to the name.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"domain",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string*",description:'A sequence of strings for the phone numbers associated to the domain name. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"><b> Attention : This function is still not implemented. </b></p>'},errors:[]},{isDocumented:!0,arity:1,name:"phone-from-user",qname:"conversion:phone-from-user",signature:"($name as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses a White-pages Web service to discover information about a given name,\n returning a sequence of strings for the phone numbers associated to the name.</p>\n',summary:"<p>  Uses a White-pages Web service to discover information about a given name,\n returning a sequence of strings for the phone numbers associated to the name.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The name of person or organization.</div>'}],returns:{type:"xs:string*",description:"A sequence of strings for the phone numbers associated to the name."},errors:[]},{isDocumented:!0,arity:4,name:"unit-convert",qname:"conversion:unit-convert",signature:"($v as xs:double, $t as xs:string, $m1 as xs:string, $m2 as xs:string) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Conversion function for units of measurement, acting as a wrapper over the CuppaIT WebService.</p>\n',summary:"<p>  Conversion function for units of measurement, acting as a wrapper over the CuppaIT WebService.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"v",type:"xs:double",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The amount we wish to convert.</div>'},{name:"t",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The type of metric (e.g., "Distance")</div>'},{name:"m1",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The source measurement unit metric (e.g., "meter")</div>'},{name:"m2",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The target measurement unit metric (e.g., "mile")</div>'}],returns:{type:"xs:double",description:"The value resulting from the conversion"},errors:[]},{isDocumented:!0,arity:1,name:"user-from-address",qname:"conversion:user-from-address",signature:"($address as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses a White-pages Web service to discover information about a given address,\n returning a sequence of strings for the names associated to the address.</p>\n',summary:"<p>  Uses a White-pages Web service to discover information about a given address,\n returning a sequence of strings for the names associated to the address.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"address",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A string corresponding to the address (ex: 5655 E Gaskill Rd, Willcox, AZ, US).</div>'}],returns:{type:"xs:string*",description:"A sequence of strings for the person or organization's names associated to the address."},errors:[]},{isDocumented:!0,arity:1,name:"user-from-phone",qname:"conversion:user-from-phone",signature:"($phone-number as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Uses a White-pages Web service to discover information about a given phone number,\n returning a sequence of strings for the name associated to the phone number.</p>\n',summary:"<p>  Uses a White-pages Web service to discover information about a given phone number,\n returning a sequence of strings for the name associated to the phone number.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"phone-number",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A string with 10 digits corresponding to the phone number.</div>'}],returns:{type:"xs:string*",description:"A sequence of strings for the person or organization's name associated to the phone number."},errors:[]}],variables:[{name:"conversion:key",type:"item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The key to be used when accessing the White Pages Web service</p>\n'}]},"http://www.28msec.com/modules/jdbc":{ns:"http://www.28msec.com/modules/jdbc",description:' This module allows connecting, querying, and updating JDBC datasources.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The results of a query are returned as a sequence of objects:\n <code> { column: value } </code>.\n The type of the value depends on the type of the column in the database:\n <table class="table table-bordered">\n   <tr><th>JDBC Types</th><th>JSONiq Type</th></tr>\n   <tr><td>integer, bigint, smallint, tinyint</td><td>integer</td></tr>\n   <tr><td>decimal, double, float, numeric, real</td><td>double</td></tr>\n   <tr><td>boolean, bit</td><td>boolean</td></tr>\n   <tr><td>char, blob, longvarchar, longnvarchar, nchar, nclob, nvarchar,\n  varchar, sqlxml, date, time, timestamp</td><td>string</td></tr>\n   <tr><td>binary, blob, longvarbinary, varbinary, array, datalink,\n  java_object, other, ref</td><td>base64Binary</td></tr>\n </table>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n If the value of a column is null, it is mapped to the JSONiq null value.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Connecting to a JDBC source requires the following options:\n <ul>\n   <li><tt>url</tt>: the JDBC connection URI (mandatory)</li>\n   <li><tt>user</tt>: the user used for connecting (optional)</li>\n   <li><tt>password</tt>: the password used for connecting (optional)</li>\n </ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Examples:\n <ul>\n  <li><pre>\n {\n   "url" : "jdbc:mysql://localhost/testdb",\n   "user" : "root",\n   "password" : ""\n }</pre></li>\n  <li><pre>\n {\n   "url" : "jdbc:sqlserver://192.168.1.1;databaseName=testdb",\n   "user" : "sa",\n   "password" : ""\n }</pre></li>\n  <li><pre>\n {\n   "url" : "jdbc:postgresql://localhost/testdb",\n   "user" : "root",\n   "password" : ""\n }</pre></li>\n </ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Currently, the 28.io platform supports connections to\n <ul>\n   <li>MySQL using the mariadb-java-client.jar version 1.1.2,</li>\n   <li>PostgreSQL using postgresql.jar version 9.2, and </li>\n   <li>Microsoft SQL Server using sqljdbc4.jar version 4.0.</li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If you are interested in connecting to other JDBC datasources,\n please contact us at support@28.io.</p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="determinism">Important Notice Regarding Function Determinism</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The non side-effecting functions:\n <ul>\n   <li><a href="?anchor=connect-0">connect#0</a></li>\n   <li><a href="?anchor=connect-1">connect#1</a></li>\n   <li><a href="?anchor=connect-2">connect#2</a></li>\n   <li><a href="?anchor=execute-query-2">execute-query#2</a></li>\n   <li><a href="?anchor=execute-query-prepared-1">execute-query-prepared#1</a></li>\n   <li><a href="?anchor=tables-1">tables#1</a></li>\n   <li><a href="?anchor=tables-4">tables#4</a></li>\n </ul>\n are declared deterministic, which means that their results could be cached\n when invoked multiple times with the same arguments in the same query execution.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To not use cached results you can use the following alternative functions:\n <ul>\n   <li><a href="?anchor=connect-notdeterministic-0">connect-notdeterministic#0</a></li>\n   <li><a href="?anchor=connect-notdeterministic-1">connect-notdeterministic#1</a></li>\n   <li><a href="?anchor=connect-notdeterministic-2">connect-notdeterministic#2</a></li>\n   <li><a href="?anchor=execute-query-notdeterministic-2">execute-query-notdeterministic#2</a></li>\n   <li><a href="?anchor=execute-query-prepared-notdeterministic-1">execute-query-prepared-notdeterministic#1</a></li>\n   <li><a href="?anchor=tables-notdeterministic-1">tables-notdeterministic#1</a></li>\n   <li><a href="?anchor=tables-notdeterministic-4">tables-notdeterministic#4</a></li>\n </ul>\n which have been declared as being non deterministic.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Cristi Dumitru</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://www.28msec.com/modules/jdbc",prefix:"jdbc"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://www.zorba-xquery.com/modules/jdbc",prefix:"zjdbc"}],functions:[{isDocumented:!0,arity:1,name:"affected-rows",qname:"jdbc:affected-rows",signature:"($dataset as anyURI) as integer",description:" Return the number of affected rows of an updating DataSet.\n",summary:"<p> Return the number of affected rows of an updating DataSet.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"dataset",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the DataSet.</div>'}],returns:{type:"integer",description:"the number of affected rows."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL008 DataSet doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"clear-params",qname:"jdbc:clear-params",signature:"($prepared-statement as anyURI) as empty-sequence()",description:" Clear all the parameters of the statement.\n",summary:"<p> Clear all the parameters of the statement.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'}],returns:{type:"empty-sequence()",description:"an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"commit",qname:"jdbc:commit",signature:"($conn as anyURI) as empty-sequence()",description:" Commit current transaction from an active connection.\n",summary:"<p> Commit current transaction from an active connection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the connection with a transaction to be commited.</div>'}],returns:{type:"empty-sequence()",description:"an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message</xqdoc:error>']},{isDocumented:!0,arity:0,name:"connect-nondeterministic",qname:"jdbc:connect-nondeterministic",signature:"() as anyURI",description:' Open a connection to a database using the default credentials.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#connect-0">connect#0</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Open a connection to a database using the default credentials.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"anyURI",description:"an identifier that represents the connection to the server."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-FOUND The default credentials not found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"connect-nondeterministic",qname:"jdbc:connect-nondeterministic",signature:"($connection-config as item()) as anyURI",description:' Open a connection to a database.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#connect-1">connect#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Open a connection to a database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection-config",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> object containing the configuration information.</div>'}],returns:{type:"anyURI",description:"an identifier that represents the connection to the server."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-FOUND The specified credentials have not been found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-VALID Invalid connection information.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"connect-nondeterministic",qname:"jdbc:connect-nondeterministic",signature:"($connection-config as item(), $options as object()?) as anyURI",description:' Open a connection to a database.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#connect-2">connect#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Open a connection to a database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection-config",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> object containing the configuration information.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> object to specify additional connection options.</div>'}],returns:{type:"anyURI",description:"an identifier that represents the connection to the server."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-FOUND The specified credentials have not been found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-VALID Invalid connection information.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"connect",qname:"jdbc:connect",signature:"() as anyURI",description:' Open a connection to a database using the default credentials.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns an opaque URI that can represents the connection.\n This URI has to be passed to other functions of this module that require\n the <tt>$conn</tt> parameter as a first argument.</p>\n',summary:"<p> Open a connection to a database using the default credentials.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"anyURI",description:"an identifier that represents the connection to the server."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-FOUND The default credentials not found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"connect",qname:"jdbc:connect",signature:"($connection-config as item()) as anyURI",description:' Open a connection to a database.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The input to the function contains the connection information.\n If a string is used, then the function will interpret it as credential name\n and will connect using the JDBC credentials with the specified name.\n If an object is used, then the function will open a connection using it.\n The object\'s required structure is described in the module\'s description.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns an opaque URI that can represents the connection.\n This URI has to be passed to other functions of this module that require\n the <tt>$conn</tt> parameter as a first argument.</p>\n',summary:"<p> Open a connection to a database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection-config",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> object containing the configuration information.</div>'}],returns:{type:"anyURI",description:"an identifier that represents the connection to the server."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-FOUND The specified credentials have not been found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-VALID Invalid connection information.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"connect",qname:"jdbc:connect",signature:"($connection-config as item(), $options as object()?) as anyURI",description:' Open a connection to a database.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The input to the function contains the connection information.\n If a string is used, then the function will interpret it as credential name\n and will connect using the JDBC credentials with the specified name.\n If an object is used, then the function will open a connection using it.\n The object\'s required structure is described in the module\'s description.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition to the connection configuration, the function allows to\n specify several options:\n <ul>\n   <li><tt>autocommit</tt>: <tt>true/false</tt> turn on/off auto commit\n (default: true)</li>\n   <li><tt>readonly</tt>: <tt>true/false</tt> configure readonly/write on this\n connection (default: false)</li>\n   <li><tt>isolation-level</tt>: configure the isolation level for this connection\n     <ul>\n       <li><tt>READ-COMMITTED</tt>: set the isolation level read-committed</li>\n       <li><tt>READ-UNCOMMITTED</tt>: set the isolation level read-uncommitted</li>\n       <li><tt>READ-REPEATABLE</tt>: set the isolation level repeatable-read</li>\n       <li><tt>SERIALIZABLE</tt>: set the isolation level serializable</li>\n     </ul>\n   If no isolation level is provided by the user the connection will be created\n   with the default isolation level of the database.</li>\n </ul></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function returns an opaque URI that represents the connection.\n This URI has to be passed to other functions of this module that require\n the <tt>$conn</tt> parameter as a first argument.</p>\n',summary:"<p> Open a connection to a database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection-config",type:"item()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> object containing the configuration information.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> object to specify additional connection options.</div>'}],returns:{type:"anyURI",description:"an identifier that represents the connection to the server."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-FOUND The specified credentials have not been found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">NOT-VALID Invalid connection information.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"connection-options",qname:"jdbc:connection-options",signature:"($conn as anyURI) as object()",description:' Return a set with options for a specified connection.\n The returned options are equal to the options specified in function jdbc:connect.\n Consequently, the options are specified as follows:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li><tt>autocommit</tt>: <tt>true/false</tt> shows auto commit</li>\n   <li><tt>readonly</tt>: <tt>true/false</tt> shows if the connection is readonly/write</li>\n   <li><tt>isolation-level</tt>: shows the isolation level for this connection\n     <ul>\n       <li><tt>READ-COMMITTED</tt>: isolation level is read-committed</li>\n       <li><tt>READ-UNCOMMITTED</tt>: isolation level is read-uncommitted</li>\n       <li><tt>READ-REPEATABLE</tt>: isolation level is repeatable-read</li>\n       <li><tt>SERIALIZABLE</tt>: isolation level is serializable</li>\n     </ul></li>\n </ul>\n',summary:"<p> Return a set with options for a specified connection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the connection.</div>'}],returns:{type:"object()",description:"an object with the connection options."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message</xqdoc:error>']},{isDocumented:!0,arity:1,name:"execute-prepared",qname:"jdbc:execute-prepared",signature:"($prepared-statement as anyURI) as anyURI",description:" Execute SQL statements prepared with jdbc:prepare-statement,\n after setting the parameters values accordingly and returns an identifier to\n a Dataset.\n",summary:"<p> Execute SQL statements prepared with jdbc:prepare-statement,\n after setting the parameters values accordingly and returns an identifier to\n a Dataset.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'}],returns:{type:"anyURI",description:"the identifier of a DataSet."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"execute-query-nondeterministic",qname:"jdbc:execute-query-nondeterministic",signature:"($conn as anyURI, $sql as string) as object()*",description:' Execute non-updating SQL statements.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#execute-query-2">execute-query#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Execute non-updating SQL statements.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection.</div>'},{name:"sql",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"object()*",description:"an object with the result data rows from the query provided."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The statement is Updating type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"execute-query-prepared-nondeterministic",qname:"jdbc:execute-query-prepared-nondeterministic",signature:"($prepared-statement as anyURI) as object()*",description:' Execute non-updating SQL statements prepared with jdbc:prepare-statement,\n after setting the parameters values accordingly.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#execute-query-prepared-1">execute-query-prepared#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Execute non-updating SQL statements prepared with jdbc:prepare-statement,\n after setting the parameters values accordingly.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'}],returns:{type:"object()*",description:"an object with the result data rows from the query processed with the parameters provided."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The prepared statement is an updating query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"execute-query-prepared",qname:"jdbc:execute-query-prepared",signature:"($prepared-statement as anyURI) as object()*",description:' Execute non-updating SQL statements prepared with jdbc:prepare-statement,\n after setting the parameters values accordingly.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Every row is represented by an object of column-value representation, as\n in the module description.</p>\n',summary:"<p> Execute non-updating SQL statements prepared with jdbc:prepare-statement,\n after setting the parameters values accordingly.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'}],returns:{type:"object()*",description:"an object with the result data rows from the query processed with the parameters provided."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The prepared statement is an updating query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"execute-query",qname:"jdbc:execute-query",signature:"($conn as anyURI, $sql as string) as object()*",description:' Execute non-updating SQL statements.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Every row is represented by an object of column-value representation, as in\n the module description.</p>\n',summary:"<p> Execute non-updating SQL statements.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection.</div>'},{name:"sql",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"object()*",description:"an object with the result data rows from the query provided."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The statement is Updating type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"execute-update-prepared",qname:"jdbc:execute-update-prepared",signature:"($prepared-statement as anyURI) as integer",description:" Execute updating SQL statements prepared with jdbc:prepare-statement.\n",summary:"<p> Execute updating SQL statements prepared with jdbc:prepare-statement.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'}],returns:{type:"integer",description:"the number of affected rows."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL006 The prepared statement is a non-updating query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"execute-update",qname:"jdbc:execute-update",signature:"($conn as anyURI, $sql as string) as integer",description:" Execute updating SQL statements.\n",summary:"<p> Execute updating SQL statements.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection.</div>'},{name:"sql",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"integer",description:"the number of affected rows."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The statement is Read-only type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"execute",qname:"jdbc:execute",signature:"($conn as anyURI, $sql as string) as anyURI",description:" Execute any kind of SQL statement.\n",summary:"<p> Execute any kind of SQL statement.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection.</div>'},{name:"sql",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"anyURI",description:"an identifier of a DataSet."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-connected",qname:"jdbc:is-connected",signature:"($conn as anyURI) as boolean",description:" Verify if a connection is still active.\n",summary:"<p> Verify if a connection is still active.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the connection to be verified.</div>'}],returns:{type:"boolean",description:"true if connected, false otherwise"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message</xqdoc:error>']},{isDocumented:!0,arity:1,name:"metadata",qname:"jdbc:metadata",signature:"($dataset as anyURI) as object()",description:' Return the metadata of the result of a DataSet.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n More in detail, it returns information about column names, types, and whether\n a column can contain a null value.\n The metadata information can only be returned for DataSets that have been\n executed explicitly using the jdbc:execute function.\n The metadata node returned has the following structure:\n <pre>{\n   "columns": [ {\n       "name": string,\n       "type": string,\n       "autoincrement"? = boolean,\n       "nillable"? = boolean } * ]\n }</pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n If the query is an updating query, then the result object will return the\n number of affected rows like:\n <pre>{ "affectedrows": integer }</pre>\n </p>\n',summary:"<p> Return the metadata of the result of a DataSet.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"dataset",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the DataSet.</div>'}],returns:{type:"object()",description:"the metadata associated with an executed DataSet."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL008 DataSet doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"parameter-metadata",qname:"jdbc:parameter-metadata",signature:"($prepared-statement as anyURI) as object()",description:' Retrieve the names and types of the prepared statement parameters.\n The metadata returned has the following structure:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">  {\n     columns: [{\n       "name": string,\n       "type": string\n       }]\n   } </pre>\n',summary:"<p> Retrieve the names and types of the prepared statement parameters.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'}],returns:{type:"object()",description:"parameters metadata (name and type) associated with a prepared statement."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"prepare-statement",qname:"jdbc:prepare-statement",signature:"($conn as anyURI, $sql as string) as anyURI",description:' Create a prepared statement for multiple executions with diferent parameters.\n Example:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n jdbc:prepare-statement($connection, "SELECT * FROM users WHERE id=? AND age&gt;?")\n </pre>\n',summary:"<p> Create a prepared statement for multiple executions with diferent parameters.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the active connection.</div>'},{name:"sql",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"anyURI",description:"the identifier of the prepared statement."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"result-set",qname:"jdbc:result-set",signature:"($dataset as anyURI) as object()*",description:" Extract the data rows from a non-updating DataSet.\n Every row is represented by an object of column-value representation, as in\n the module description.\n",summary:"<p> Extract the data rows from a non-updating DataSet.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"dataset",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the DataSet.</div>'}],returns:{type:"object()*",description:"an object with the result data rows from the DataSet provided."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL008 DataSet doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"rollback",qname:"jdbc:rollback",signature:"($conn as anyURI) as empty-sequence()",description:" Rollback the current transaction of a connection.\n",summary:"<p> Rollback the current transaction of a connection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the connection with a transaction to be rollbacked.</div>'}],returns:{type:"empty-sequence()",description:"an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message</xqdoc:error>']},{isDocumented:!0,arity:3,name:"set-boolean",qname:"jdbc:set-boolean",signature:"($prepared-statement as anyURI, $parameter-index as integer, $value as boolean) as empty-sequence()",description:' Set the value of the designated parameter with a <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">boolean</tt> value.\n',summary:"<p> Set the value of the designated parameter with a  boolean  value.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'},{name:"parameter-index",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'},{name:"value",type:"boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be set.</div>'}],returns:{type:"empty-sequence()",description:"an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"set-null",qname:"jdbc:set-null",signature:"($prepared-statement as anyURI, $parameter-index as integer) as empty-sequence()",description:' Set the value of the designated parameter with a <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">NULL</tt> value.\n',summary:"<p> Set the value of the designated parameter with a  NULL  value.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'},{name:"parameter-index",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'}],returns:{type:"empty-sequence()",description:"an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"set-numeric",qname:"jdbc:set-numeric",signature:"($prepared-statement as anyURI, $parameter-index as decimal, $value as anyAtomicType) as empty-sequence()",description:' Set the value of the designated parameter with a <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">numeric</tt> value.\n',summary:"<p> Set the value of the designated parameter with a  numeric  value.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'},{name:"parameter-index",type:"decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'},{name:"value",type:"anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be set.</div>'}],returns:{type:"empty-sequence()",description:"an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"set-string",qname:"jdbc:set-string",signature:"($prepared-statement as anyURI, $parameter-index as integer, $value as string) as empty-sequence()",description:' Set the value of the designated parameter with a <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">string</tt> value.\n',summary:"<p> Set the value of the designated parameter with a  string  value.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'},{name:"parameter-index",type:"integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'},{name:"value",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be set.</div>'}],returns:{type:"empty-sequence()",description:"an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"set-value",qname:"jdbc:set-value",signature:"($prepared-statement as anyURI, $parameter-index as decimal, $value as anyAtomicType) as empty-sequence()",description:" Set the value of the designated parameter with the given value.\n The function will try to cast the value to the correct data type and assign\n it to the parameter.\n",summary:"<p> Set the value of the designated parameter with the given value.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier of the prepared statement.</div>'},{name:"parameter-index",type:"decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'},{name:"value",type:"anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be set.</div>'}],returns:{type:"empty-sequence()",description:"an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"tables-nondeterministic",qname:"jdbc:tables-nondeterministic",signature:"($conn as anyURI) as object()*",description:' Return the list of tables from a connection.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#tables-1">tables#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Return the list of tables from a connection.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a connection.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"tables-nondeterministic",qname:"jdbc:tables-nondeterministic",signature:"($conn as anyURI, $catalog as string?, $schema as string?, $table as string?) as object()*",description:' Return the list of tables from a connection.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#tables-4">tables#4</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Return the list of tables from a connection.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a connection.</div>'},{name:"catalog",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the catalog name of the tables. Send empty-sequence for all tables.</div>'},{name:"schema",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the schema name of the tables. Send empty-sequence for all tables.</div>'},{name:"table",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the name of the tables. Send empty-sequence for all tables.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"tables",qname:"jdbc:tables",signature:"($conn as anyURI) as object()*",description:' Return the list of tables from a connection.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p> Return the list of tables from a connection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a connection.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"tables",qname:"jdbc:tables",signature:"($conn as anyURI, $catalog as string?, $schema as string?, $table as string?) as object()*",description:' Return the list of tables from a connection.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p> Return the list of tables from a connection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"conn",type:"anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a connection.</div>'},{name:"catalog",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the catalog name of the tables. Send empty-sequence for all tables.</div>'},{name:"schema",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the schema name of the tables. Send empty-sequence for all tables.</div>'},{name:"table",type:"string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the name of the tables. Send empty-sequence for all tables.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']}],variables:[{name:"jdbc:READ-COMMITTED",type:"item()*",description:" This variable represents the READ-COMMITTED Isolation Level.\n"},{name:"jdbc:READ-UNCOMMITTED",type:"item()*",description:" This variable represents the READ-UNCOMMITTED Isolation Level.\n"},{name:"jdbc:REPEATABLE-READ",type:"item()*",description:" This variable represents the REPEATABLE-READ Isolation Levels.\n"},{name:"jdbc:SERIALIZABLE",type:"item()*",description:" This variable represents the SERIALIZABLE Isolation Levels.\n"},{name:"jdbc:CREDENTIALS-CATEGORY",type:"item()*",description:" This variable represents the category for the credentials used.\n"}]},"http://zorba.io/modules/full-text":{ns:"http://zorba.io/modules/full-text",description:' This module provides an XQuery API to full-text functions.\n For general information about this implementation of the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xpath-full-text-10/">XQuery and XPath Full Text 1.0 specification</a>\n as well as instructions for building an installing a thesaurus,\n see the <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/ft_thesaurus.html">Full Text Thesaurus documentation</a>.\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0">Notes on languages</h2>\n To refer to particular human languages,\n uses either the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://en.wikipedia.org/wiki/ISO_639-1">ISO 639-1</a>\n or\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://en.wikipedia.org/wiki/ISO_639-2">ISO 639-2</a>\n languages codes.\n Note that only a subset of the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes">complete list of language codes</a>\n are supported and not every function supports the same subset.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Most functions in this module take a language as a parameter\n using the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>\n XML schema data type.\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0">Notes on stemming</h2>\n The <code xmlns:xqdoc="http://www.xqdoc.org/1.0">stem()</code> functions return the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://en.wikipedia.org/wiki/Word_stem">stem</a>\n of a word.\n The stem of a word itself, however, is not guaranteed to be a word.\n It is best to consider a stem as an opaque byte sequence.\n All that is guaranteed about a stem is that,\n for a given word,\n the stem of that word will always be the same byte sequence.\n Hence,\n you should never compare the result of one of the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">stem()</code>\n functions against a non-stemmed string,\n for example:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  if ( ft:stem( "apples" ) eq "apple" )             ** WRONG **\n </pre>\n Instead do:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n  if ( ft:stem( "apples" ) eq ft:stem( "apple" ) )  ** CORRECT **\n </pre>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0">Notes on the thesaurus</h2>\n The <code xmlns:xqdoc="http://www.xqdoc.org/1.0">thesaurus-lookup()</code> functions have "levels"\n and "relationship" parameters.\n The values for these are implementation-defined.\n The default implementation uses the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://wordnet.princeton.edu/">WordNet lexical database</a>,\n version 3.0.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n In WordNet,\n the number of "levels" that two phrases are apart\n are how many hierarchical meanings apart they are.\n For example,\n "canary" is 5 levels away from "vertebrate"\n (carary &gt; finch &gt; oscine &gt; passerine &gt; bird &gt; vertebrate).\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n When using the WordNet implementation,\n all of the relationships (and their abbreviations)\n specified by\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=7776">ISO 2788</a>\n and\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.niso.org/kst/reports/standards?step=2&amp;gid=&amp;project_key=7cc9b583cb5a62e8c15d3099e0bb46bbae9cf38a">ANSI/NISO Z39.19-2005</a>\n with the exceptions of "HN" (history note)\n and "X SN" (see scope note for) are supported.\n These relationships are:\n  <table xmlns:xqdoc="http://www.xqdoc.org/1.0">\n    <tr>\n      <th>Rel.</th>\n      <th>Meaning</th>\n      <th>WordNet Rel.</th>\n    </tr>\n    <tr>\n      <td>BT</td>\n      <td>broader term</td>\n      <td>hypernym</td>\n    </tr>\n    <tr>\n      <td>BTG</td>\n      <td>broader term generic</td>\n      <td>hypernym</td>\n    </tr>\n    <tr>\n      <td>BTI</td>\n      <td>broader term instance</td>\n      <td>instance hypernym</td>\n    </tr>\n    <tr>\n      <td>BTP</td>\n      <td>broader term partitive</td>\n      <td>part meronym</td>\n    </tr>\n    <tr>\n      <td>NT</td>\n      <td>narrower term</td>\n      <td>hyponym</td>\n    </tr>\n    <tr>\n      <td>NTG</td>\n      <td>narrower term generic</td>\n      <td>hyponym</td>\n    </tr>\n    <tr>\n      <td>NTI</td>\n      <td>narrower term instance</td>\n      <td>instance hyponym</td>\n    </tr>\n    <tr>\n      <td>NTP</td>\n      <td>narrower term partitive</td>\n      <td>part holonym</td>\n    </tr>\n    <tr>\n      <td>RT</td>\n      <td>related term</td>\n      <td>also see</td>\n    </tr>\n    <tr>\n      <td>SN</td>\n      <td>scope note</td>\n      <td>n/a</td>\n    </tr>\n    <tr>\n      <td>TT</td>\n      <td>top term</td>\n      <td>hypernym</td>\n    </tr>\n    <tr>\n      <td>UF</td>\n      <td>non-preferred term</td>\n      <td>n/a</td>\n    </tr>\n    <tr>\n      <td>USE</td>\n      <td>preferred term</td>\n      <td>n/a</td>\n    </tr>\n  </table>\n Note that you can specify relationships\n either by their abbreviation\n or their meaning.\n Relationships are case-insensitive.\n In addition to the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=7776">ISO 2788</a>\n and\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.niso.org/kst/reports/standards?step=2&amp;gid=&amp;project_key=7cc9b583cb5a62e8c15d3099e0bb46bbae9cf38a">ANSI/NISO Z39.19-2005</a>\n relationships,\n All of the relationships offered by WordNet are also supported.\n These relationships are:\n  <table xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ft_rels">\n    <tr>\n      <th>Relationship</th>\n      <th>Meaning</th>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">also see</td>\n      <td>\n        A word that is related to another,\n        e.g., for "varnished" (furniture)\n        one should <em>also see</em> "finished."\n      </td>\n    </tr>\n    <tr>\n      <td>antonym</td>\n      <td>\n        A word opposite in meaning to another,\n        e.g., "light" is an <em>antonym</em> for "heavy."\n      </td>\n    </tr>\n    <tr>\n      <td>attribute</td>\n      <td>\n        A noun for which adjectives express values,\n        e.g., "weight" is an <em>attribute</em>\n        for which the adjectives "light" and "heavy"\n        express values.\n      </td>\n    </tr>\n    <tr>\n      <td>cause</td>\n      <td>\n        A verb that causes another,\n        e.g., "show" is a <em>cause</em> of "see."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">derivationally related form</td>\n      <td>\n        A word that is derived from a root word,\n        e.g., "metric" is a <em>derivationally related form</em> of "meter."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">derived from adjective</td>\n      <td>\n        An adverb that is derived from an adjective,\n        e.g., "correctly" is <em>derived from the adjective</em> "correct."\n      </td>\n    </tr>\n    <tr>\n      <td>entailment</td>\n      <td>\n        A verb that presupposes another,\n        e.g., "snoring" <em>entails</em> "sleeping."\n      </td>\n    </tr>\n    <tr>\n      <td>hypernym</td>\n      <td>\n        A word with a broad meaning that more specific words fall under,\n        e.g., "meal" is a <em>hypernym</em> of "breakfast."\n      </td>\n    </tr>\n    <tr>\n      <td>hyponym</td>\n      <td>\n        A word of more specific meaning than a general term applicable to it,\n        e.g., "breakfast" is a <em>hyponym</em> of "meal."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">instance hypernym</td>\n      <td>\n        A word that denotes a category of some specific instance,\n        e.g., "author" is an <em>instance hypernym</em> of "Asimov."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">instance hyponym</td>\n      <td>\n        A term that donotes a specific instance of some general category,\n        e.g., "Asimov" is an <em>instance hyponym</em> of "author."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">member holonym</td>\n      <td>\n        A word that denotes a collection of individuals,\n        e.g., "faculty" is a <em>member holonym</em> of "professor."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">member meronym</td>\n      <td>\n        A word that denotes a member of a larger group,\n        e.g., a "person" is a <em>member meronym</em> of a "crowd."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">part holonym</td>\n      <td>\n        A word that denotes a larger whole comprised of some part,\n        e.g., "car" is a <em>part holonym</em> of "engine."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">part meronym</td>\n      <td>\n        A word that denotes a part of a larger whole,\n        e.g., an "engine" is <em>part meronym</em> of a "car."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">participle of verb</td>\n      <td>\n        An adjective that is the participle of some verb,\n        e.g., "breaking" is the <em>participle of the verb</em> "break."\n      </td>\n    </tr>\n    <tr>\n      <td>pertainym</td>\n      <td>\n        An adjective that classifies its noun,\n        e.g., "musical" is a <em>pertainym</em> in "musical instrument."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">similar to</td>\n      <td>\n        Similar, though not necessarily interchangeable, adjectives.\n        For example, "shiny" is <em>similar to</em> "bright",\n        but they have subtle differences.\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">substance holonym</td>\n      <td>\n        A word that denotes a larger whole containing some constituent\n        substance, e.g., "bread" is a <em>substance holonym</em> of "flour."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">substance meronym</td>\n      <td>\n        A word that denotes a constituant substance of some larger whole,\n        e.g., "flour" is a <em>substance meronym</em> of "bread."\n      </td>\n    </tr>\n    <tr>\n      <td nowrap="nowrap">verb group</td>\n      <td>\n        A verb that is a member of a group of similar verbs,\n        e.g., "live" is in the <em>verb group</em>\n        of "dwell", "live", "inhabit", etc.\n      </td>\n    </tr>\n  </table>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0">Notes on tokenization</h2>\n For general information about the implementation of tokenization,\n including what constitutes a token,\n see the <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="../zorba/ft_tokenizer.html">Full Text Tokenizer</a> documentation.\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Paul J. Lucas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://zorba.io/modules/full-text",prefix:"ft"},{uri:"http://zorba.io/options/versioning",prefix:"ver"},{uri:"http://zorba.io/errors",prefix:"zerr"}],functions:[{isDocumented:!0,arity:0,name:"current-compare-options",qname:"ft:current-compare-options",signature:"() as object() external",description:" Gets the current compare options.\n",summary:"<p> Gets the current compare options.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"said compare options."},errors:[]},{isDocumented:!0,arity:0,name:"current-lang",qname:"ft:current-lang",signature:"() as xs:language external",description:' Gets the current\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language">language</a>:\n either the language specified by the\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.w3.org/TR/xpath-full-text-10/#doc-xquery10-FTOptionDecl">declare ft-option using</a>\n <a href="http://www.w3.org/TR/xpath-full-text-10/#ftlanguageoption">language</a></code>\n statement (if any)\n or the one returned by <code xmlns:xqdoc="http://www.xqdoc.org/1.0">ft:host-lang()</code> (if none).\n',summary:"<p> Gets the current\n  language :\n either the language specified by the\n  declare ft-option using \n  language \n statement (if any)\n or the one returned by  ft:host-lang()  (if none).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:language",description:"said language."},errors:[]},{isDocumented:!0,arity:0,name:"host-lang",qname:"ft:host-lang",signature:"() as xs:language external",description:' Gets the host\'s current\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language">language</a>.\n The "host" is the computer on which the software is running.\n The host\'s current language is obtained as follows:\n  <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n    <li>\n      For *nix systems:\n      <ol>\n        <li>\n          If <a ref="http://www.cplusplus.com/reference/clibrary/clocale/setlocale/"><code>setlocale</code>(3)</a> returns non-null,\n          the language corresponding to that locale is used.\n        </li>\n        <li>\n          Else, if the <code>LANG</code> environment variable is set,\n          that language is ued.\n        </li>\n        <li>\n          Otherwise, there is no default language.\n        </li>\n      </ol>\n    </li>\n    <li>\n      For Windows systems,\n      the language corresponding to the locale returned by the\n      <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd318101(v=vs.85).aspx"><code>GetLocaleInfo()</code></a>\n      function is used.\n    </li>\n  </ul>\n',summary:"<p> Gets the host's current\n  language .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"xs:language",description:"said language."},errors:[]},{isDocumented:!0,arity:1,name:"is-stem-lang-supported",qname:"ft:is-stem-lang-supported",signature:"($lang as xs:language) as xs:boolean external",description:' Checks whether the given\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language">language</a>\n is supported for stemming.\n',summary:"<p> Checks whether the given\n  language \n is supported for stemming.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language to check.</div>'}],returns:{type:"xs:boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if the language is supported.'},errors:[]},{isDocumented:!0,arity:1,name:"is-stop-word-lang-supported",qname:"ft:is-stop-word-lang-supported",signature:"($lang as xs:language) as xs:boolean external",description:' Checks whether the given\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language">language</a>\n is supported for stop words.\n',summary:"<p> Checks whether the given\n  language \n is supported for stop words.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language to check.</div>'}],returns:{type:"xs:boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if the language is supported.'},errors:[]},{isDocumented:!0,arity:1,name:"is-stop-word",qname:"ft:is-stop-word",signature:"($word as xs:string) as xs:boolean external",description:" Checks whether the given word is a stop-word.\n",summary:"<p> Checks whether the given word is a stop-word.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"word",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The word to check. The word\'s <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> is assumed to be the one returned by <code>ft:current-lang()</code>.</div>'}],returns:{type:"xs:boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$word</code> is a stop-word.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"is-stop-word",qname:"ft:is-stop-word",signature:"($word as xs:string, $lang as xs:language) as xs:boolean external",description:" Checks whether the given word is a stop-word.\n",summary:"<p> Checks whether the given word is a stop-word.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"word",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The word to check.</div>'},{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> of <code>$word</code>.</div>'}],returns:{type:"xs:boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$word</code> is a stop-word.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-thesaurus-lang-supported",qname:"ft:is-thesaurus-lang-supported",signature:"($lang as xs:language) as xs:boolean external",description:' Checks whether the given\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language">language</a>\n is supported for look-up using the default thesaurus.\n',summary:"<p> Checks whether the given\n  language \n is supported for look-up using the default thesaurus.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language to check.</div>'}],returns:{type:"xs:boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if the language is supported.'},errors:[]},{isDocumented:!0,arity:2,name:"is-thesaurus-lang-supported",qname:"ft:is-thesaurus-lang-supported",signature:"($uri as xs:string, $lang as xs:language) as xs:boolean external",description:' Checks whether the given\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language">language</a>\n is supported for look-up using the thesaurus specified by the given URI.\n',summary:"<p> Checks whether the given\n  language \n is supported for look-up using the thesaurus specified by the given URI.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URI specifying the thesaurus to use.</div>'},{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language to check.</div>'}],returns:{type:"xs:boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if the language is supported.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0018 if <code>$uri</code> refers to a thesaurus that is not found in the statically known thesauri.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-tokenizer-lang-supported",qname:"ft:is-tokenizer-lang-supported",signature:"($lang as xs:language) as xs:boolean external",description:' Checks whether the given\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language">language</a>\n is supported for tokenization.\n',summary:"<p> Checks whether the given\n  language \n is supported for tokenization.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language to check.</div>'}],returns:{type:"xs:boolean",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">true</code> only if the language is supported.'},errors:[]},{isDocumented:!0,arity:1,name:"stem",qname:"ft:stem",signature:"($word as xs:string) as xs:string external",description:" Stems the given word.\n",summary:"<p> Stems the given word.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"word",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The word to stem. The word\'s <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> is assumed to be the one returned by <code>ft:current-lang()</code>.</div>'}],returns:{type:"xs:string",description:'the stem of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$word</code>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"stem",qname:"ft:stem",signature:"($word as xs:string, $lang as xs:language) as xs:string external",description:" Stems the given word.\n",summary:"<p> Stems the given word.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"word",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The word to stem.</div>'},{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> of <code>$word</code>.</div>'}],returns:{type:"xs:string",description:'the stem of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$word</code>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"strip-diacritics",qname:"ft:strip-diacritics",signature:"($string as xs:string) as xs:string external",description:" Strips all diacritical marks from all characters.\n",summary:"<p> Strips all diacritical marks from all characters.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"string",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to strip diacritical marks from.</div>'}],returns:{type:"xs:string",description:'<code xmlns:xqdoc="http://www.xqdoc.org/1.0">$string</code> with diacritical marks stripped.'},errors:[]},{isDocumented:!0,arity:1,name:"thesaurus-lookup",qname:"ft:thesaurus-lookup",signature:"($phrase as xs:string) as xs:string* external",description:" Looks-up the given phrase in the default thesaurus.\n",summary:"<p> Looks-up the given phrase in the default thesaurus.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"phrase",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The phrase to look up. The phrase\'s <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> is assumed to be the one returned by <code>ft:current-lang()</code>.</div>'}],returns:{type:"xs:string*",description:'the related phrases if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$phrase</code> is found in the thesaurus or the empty sequence if not.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8401 if the thesaurus data file\'s version is not supported by the currently running version of the software.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8402 if the thesaurus data file\'s endianness does not match that of the CPU on which the software is currently running.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8403 if there was an error reading the thesaurus data.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"thesaurus-lookup",qname:"ft:thesaurus-lookup",signature:"($uri as xs:string, $phrase as xs:string) as xs:string* external",description:" Looks-up the given phrase in a thesaurus.\n",summary:"<p> Looks-up the given phrase in a thesaurus.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URI specifying the thesaurus to use.</div>'},{name:"phrase",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The phrase to look up. The phrase\'s <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> is assumed to be the one the one returned by <code>ft:current-lang()</code>.</div>'}],returns:{type:"xs:string*",description:'the related phrases if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$phrase</code> is found in the thesaurus or the empty sequence if not.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is unsupported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0018 if <code>$uri</code> refers to a thesaurus that is not found in the statically known thesauri.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0001 if the thesaurus data file could not be found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0002 if the thesaurus data file is not a plain file.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8401 if the thesaurus data file\'s version is not supported by the currently running version of the software.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8402 if the thesaurus data file\'s endianness does not match that of the CPU on which the software is currently running.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8403 if there was an error reading the thesaurus data file.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"thesaurus-lookup",qname:"ft:thesaurus-lookup",signature:"($uri as xs:string, $phrase as xs:string, $lang as xs:language) as xs:string* external",description:" Looks-up the given phrase in the thesaurus specified by the given URI.\n",summary:"<p> Looks-up the given phrase in the thesaurus specified by the given URI.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URI specifying the thesaurus to use.</div>'},{name:"phrase",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The phrase to look up.</div>'},{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> of <code>$phrase</code>.</div>'}],returns:{type:"xs:string*",description:'the related phrases if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$phrase</code> is found in the thesaurus or the empty sequence if not.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0018 if <code>$uri</code> refers to a thesaurus that is not found in the statically known thesauri.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0001 if the thesaurus data file could not be found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0002 if the thesaurus data file is not a plain file.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8401 if the thesaurus data file\'s version is not supported by the currently running version of the software.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8402 if the thesaurus data file\'s endianness does not match that of the CPU on which the software is currently running.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8403 if there was an error reading the thesaurus data file.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"thesaurus-lookup",qname:"ft:thesaurus-lookup",signature:"($uri as xs:string, $phrase as xs:string, $lang as xs:language, $relationship as xs:string) as xs:string* external",description:" Looks-up the given phrase in a thesaurus.\n",summary:"<p> Looks-up the given phrase in a thesaurus.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URI specifying the thesaurus to use.</div>'},{name:"phrase",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The phrase to look up.</div>'},{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> of <code>$phrase</code>.</div>'},{name:"relationship",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The relationship the results are to have to <code>$phrase</code>.</div>'}],returns:{type:"xs:string*",description:'the related phrases if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$phrase</code> is found in the thesaurus or the empty sequence if not.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0018 if <code>$uri</code> refers to a thesaurus that is not found in the statically known thesauri.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0001 if the thesaurus data file could not be found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0002 if the thesaurus data file is not a plain file.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8401 if the thesaurus data file\'s version is not supported by the currently running version of the software.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8402 if the thesaurus data file\'s endianness does not match that of the CPU on which the software is currently running.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8403 if there was an error reading the thesaurus data file.</xqdoc:error>']},{isDocumented:!0,arity:6,name:"thesaurus-lookup",qname:"ft:thesaurus-lookup",signature:"($uri as xs:string, $phrase as xs:string, $lang as xs:language, $relationship as xs:string, $level-least as xs:integer, $level-most as xs:integer) as xs:string* external",description:" Looks-up the given phrase in a thesaurus.\n",summary:"<p> Looks-up the given phrase in a thesaurus.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"uri",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URI specifying the thesaurus to use.</div>'},{name:"phrase",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The phrase to look up.</div>'},{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> of <code>$phrase</code>.</div>'},{name:"relationship",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The relationship the results are to have to <code>$phrase</code>.</div>'},{name:"level-least",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The minimum number of levels within the thesaurus to be traversed.</div>'},{name:"level-most",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The maximum number of levels within the thesaurus to be traversed.</div>'}],returns:{type:"xs:string*",description:'the related phrases if <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$phrase</code> is found in the thesaurus or the empty sequence if not.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FOCA0003 if either <code>$level-least</code> or <code>$level-most</code> is either negative or too large.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0018 if <code>$uri</code> refers to a thesaurus that is not found in the statically known thesauri.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0001 if the thesaurus data file could not be found.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZOSE0002 if the thesaurus data file is not a plain file.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8401 if the thesaurus data file\'s version is not supported by the currently running version of the software.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8402 if the thesaurus data file\'s endianness does not match that of the CPU on which the software is currently running.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">zerr:ZXQP8403 if there was an error reading the thesaurus data file.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"tokenize-node",qname:"ft:tokenize-node",signature:"($node as node()) as object()* external",description:" Tokenizes the given node and all of its descendants.\n",summary:"<p> Tokenizes the given node and all of its descendants.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The node to tokenize. The node\'s default <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> is assumed to be the one returned by <code>ft:current-lang()</code>.</div>'}],returns:{type:"object()*",description:"a (possibly empty) sequence of tokens."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"tokenize-node",qname:"ft:tokenize-node",signature:"($node as node(), $lang as xs:language) as object()* external",description:" Tokenizes the given node and all of its decendants.\n",summary:"<p> Tokenizes the given node and all of its decendants.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The node to tokenize.</div>'},{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The default <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> of <code>$node</code>.</div>'}],returns:{type:"object()*",description:"a (possibly empty) sequence of tokens."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"tokenize-nodes",qname:"ft:tokenize-nodes",signature:"($includes as node()+, $excludes as node()*) as object()* external",description:' Tokenizes the set of nodes comprising <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$includes</code> (and all of its\n descendants) but excluding <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$excludes</code> (and all of its\n descendants), if any.\n',summary:"<p> Tokenizes the set of nodes comprising  $includes  (and all of its\n descendants) but excluding  $excludes  (and all of its\n descendants), if any.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"includes",type:"node()",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The set of nodes (and its descendants) to include. The default <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> is assumed to be the one returned by <code>ft:current-lang()</code>.</div>'},{name:"excludes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The set of nodes (and its descendants) to exclude.</div>'}],returns:{type:"object()*",description:"a (possibly empty) sequence of tokens."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"tokenize-nodes",qname:"ft:tokenize-nodes",signature:"($includes as node()+, $excludes as node()*, $lang as xs:language) as object()* external",description:' Tokenizes the set of nodes comprising <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$includes</code> (and all of its\n descendants) but excluding <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$excludes</code> (and all of its\n descendants), if any.\n',summary:"<p> Tokenizes the set of nodes comprising  $includes  (and all of its\n descendants) but excluding  $excludes  (and all of its\n descendants), if any.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"includes",type:"node()",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The set of nodes (and its descendants) to include.</div>'},{name:"excludes",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The set of nodes (and its descendants) to exclude.</div>'},{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The default <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> for nodes.</div>'}],returns:{type:"object()*",description:"a (possibly empty) sequence of tokens."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"tokenize-string",qname:"ft:tokenize-string",signature:"($string as xs:string) as xs:string* external",description:" Tokenizes the given string.\n",summary:"<p> Tokenizes the given string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"string",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to tokenize. The string\'s <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> is assumed to be the one returned by <code>ft:current-lang()</code>.</div>'}],returns:{type:"xs:string*",description:"a (possibly empty) sequence of tokens."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"tokenize-string",qname:"ft:tokenize-string",signature:"($string as xs:string, $lang as xs:language) as xs:string* external",description:" Tokenizes the given string.\n",summary:"<p> Tokenizes the given string.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"string",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string to tokenize.</div>'},{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The <a href="http://www.w3.org/TR/xmlschema-2/#language">language</a> of <code>$string</code>.</div>'}],returns:{type:"xs:string*",description:"a (possibly empty) sequence of tokens."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"tokenizer-properties",qname:"ft:tokenizer-properties",signature:"() as object() external",description:' Gets properties of the tokenizer for the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language">language</a>\n returned by <code xmlns:xqdoc="http://www.xqdoc.org/1.0">ft:current-lang()</code>.\n',summary:"<p> Gets properties of the tokenizer for the\n  language \n returned by  ft:current-lang() .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"said properties."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>ft:current-lang()</code> is not supported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"tokenizer-properties",qname:"ft:tokenizer-properties",signature:"($lang as xs:language) as object() external",description:' Gets properties of the tokenizer for the given\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language">language</a>.\n',summary:"<p> Gets properties of the tokenizer for the given\n  language .</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"lang",type:"xs:language",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The language of the tokenizer to get the properties of.</div>'}],returns:{type:"object()",description:"said properties."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FTST0009 if <code>$lang</code> is not supported. tokenization specifically.</xqdoc:error>']}],variables:[{name:"ft:LANG-DA",type:"xs:language",description:' Predeclared constant for the Danish\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-DE",type:"xs:language",description:' Predeclared constant for the German\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-EN",type:"xs:language",description:' Predeclared constant for the English\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-ES",type:"xs:language",description:' Predeclared constant for the Spanish\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-FI",type:"xs:language",description:' Predeclared constant for the Finnish\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-FR",type:"xs:language",description:' Predeclared constant for the French\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-HU",type:"xs:language",description:' Predeclared constant for the Hungarian\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-IT",type:"xs:language",description:' Predeclared constant for the Italian\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-NL",type:"xs:language",description:' Predeclared constant for the Dutch\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-NO",type:"xs:language",description:' Predeclared constant for the Norwegian\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-PT",type:"xs:language",description:' Predeclared constant for the Portuguese\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-RO",type:"xs:language",description:' Predeclared constant for the Romanian\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-RU",type:"xs:language",description:' Predeclared constant for the Russian\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-SV",type:"xs:language",description:' Predeclared constant for the Swedish\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'},{name:"ft:LANG-TR",type:"xs:language",description:' Predeclared constant for the Turkish\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.w3.org/TR/xmlschema-2/#language"><code>xs:language</code></a>.\n'}]},"http://www.zorba-xquery.com/modules/jdbc":{ns:"http://www.zorba-xquery.com/modules/jdbc",description:' This module contains functions to connect to any JDBC datasource\n using jvm-util module to handle Java interaction.\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="determinism">Important Notice Regarding Function Determinism</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The non side-effecting functions:\n <ul>\n   <li><a href="?anchor=connect-1">connect#1</a></li>\n   <li><a href="?anchor=connect-2">connect#2</a></li>\n   <li><a href="?anchor=execute-query-2">execute-query#2</a></li>\n   <li><a href="?anchor=execute-query-prepared-1">execute-query-prepared#1</a></li>\n   <li><a href="?anchor=tables-1">tables#1</a></li>\n   <li><a href="?anchor=tables-4">tables#4</a></li>\n </ul>\n are declared deterministic, which means that their results could be cached\n when invoked multiple times with the same arguments in the same query execution.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">To not use cached results you can use the following alternative functions:\n <ul>\n   <li><a href="?anchor=connect-notdeterministic-0">connect-notdeterministic#0</a></li>\n   <li><a href="?anchor=connect-notdeterministic-1">connect-notdeterministic#1</a></li>\n   <li><a href="?anchor=connect-notdeterministic-2">connect-notdeterministic#2</a></li>\n   <li><a href="?anchor=execute-query-notdeterministic-2">execute-query-notdeterministic#2</a></li>\n   <li><a href="?anchor=execute-query-prepared-notdeterministic-1">execute-query-prepared-notdeterministic#1</a></li>\n   <li><a href="?anchor=tables-notdeterministic-1">tables-notdeterministic#1</a></li>\n   <li><a href="?anchor=tables-notdeterministic-4">tables-notdeterministic#4</a></li>\n </ul>\n which have been declared as being non deterministic.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Rodolfo Ochoa</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.zorba-xquery.com/modules/jdbc",prefix:"jdbc"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"affected-rows",qname:"jdbc:affected-rows",signature:"($dataset-id as xs:anyURI) as xs:integer external",description:" Return the number of affected rows of a particular DataSet.\n",summary:"<p> Return the number of affected rows of a particular DataSet.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"dataset-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a DataSet.</div>'}],returns:{type:"xs:integer",description:"Returns an xs:integer with the number of affected rows."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL008 DataSet doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"clear-params",qname:"jdbc:clear-params",signature:"($prepared-statement as xs:anyURI) as empty-sequence() external",description:" Clears the current parameter values immediately.\n",summary:"<p> Clears the current parameter values immediately.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"close-dataset",qname:"jdbc:close-dataset",signature:"($dataset-id as xs:anyURI) as empty-sequence() external",description:" Closes and free resources from a particular DataSet.\n",summary:"<p> Closes and free resources from a particular DataSet.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"dataset-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a DataSet.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL008 DataSet doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"close-prepared",qname:"jdbc:close-prepared",signature:"($prepared-statement as xs:anyURI) as empty-sequence() external",description:" Closes and frees from memory any prepared SQL statement created with jdbc:prepare-statement\n",summary:"<p> Closes and frees from memory any prepared SQL statement created with jdbc:prepare-statement\n</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"commit",qname:"jdbc:commit",signature:"($connection-id as xs:anyURI) as empty-sequence() external",description:" Commit current transaction from an active connection.\n",summary:"<p> Commit current transaction from an active connection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to the connection to be commited.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message</xqdoc:error>']},{isDocumented:!0,arity:1,name:"connect-nondeterministic",qname:"jdbc:connect-nondeterministic",signature:"($connection-config as object()) as xs:anyURI external",description:' Opens a connection to a database.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#connect-1">connect#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Opens a connection to a database.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection-config",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> json object that has the host and user informations.</div>'}],returns:{type:"xs:anyURI",description:"Return an identifier that represents the connection to the server."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"connect-nondeterministic",qname:"jdbc:connect-nondeterministic",signature:"($connection-config as object(), $options as object()?) as xs:anyURI external",description:' Opens a connection to a database with specified options.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#connect-2">connect#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Opens a connection to a database with specified options.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection-config",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> json object that has the host and user informations.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> json object that specifies the connection options.</div>'}],returns:{type:"xs:anyURI",description:"Return an identifier that represents the connection to the server."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"connect",qname:"jdbc:connect",signature:"($connection-config as object()) as xs:anyURI external",description:' Opens a connection to a database.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a URI identifying the connection that has been opened. The\n implementing code determines from the $connection-config either explicitly\n (interpreting the driver attribute) or implicitly (using the type attribute)\n which driver it has to load.</p>\n',summary:"<p> Opens a connection to a database.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection-config",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> json object that has the host and user informations.</div>'}],returns:{type:"xs:anyURI",description:'Return an identifier that represents the connection to the server. Connection coonfiguration example: { "url" : "jdbc:mysql://localhost/", "user" : "root", "password" : "" }'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"connect",qname:"jdbc:connect",signature:"($connection-config as object(), $options as object()?) as xs:anyURI external",description:' Opens a connection to a database with specified options.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns a URI identifying the connection that has been opened. The\n implementing code determines from the $connection-config either explicitly\n (interpreting the driver attribute) or implicitly (using the type attribute)\n which driver it has to load.</p>\n',summary:"<p> Opens a connection to a database with specified options.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection-config",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> json object that has the host and user informations.</div>'},{name:"options",type:"object()",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> json object that specifies the connection options.</div>'}],returns:{type:"xs:anyURI",description:'Return an identifier that represents the connection to the server. Connection options example: { "autocommit" : false, "readonly"? : true, "isolation-level"? : $jdbc:READ-COMMITTED }'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL28000 Authentication failed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08001 Connection error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL40003 Isolation level not supported.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"connection-options",qname:"jdbc:connection-options",signature:"($connection-id as xs:anyURI) as object() external",description:" Returns a set with options for a specified connection.\n",summary:"<p> Returns a set with options for a specified connection.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to the connection to be verify.</div>'}],returns:{type:"object()",description:'Returns and object with the connection options. The returned options are equal to the options specified in function jdbc:connect. Consequently, the options are specified as follows: { "autocommit" : xs:boolean, "readonly" : xs:boolean, "isolation-level" : xs:string }'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message</xqdoc:error>']},{isDocumented:!0,arity:1,name:"execute-prepared",qname:"jdbc:execute-prepared",signature:"($prepared-statement as xs:anyURI) as xs:anyURI external",description:" Executes SQL statements prepared with 5.1 jsql:prepare-statement with values set\n and returns an identifier to a Dataset.\n",summary:"<p> Executes SQL statements prepared with 5.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'}],returns:{type:"xs:anyURI",description:"Return an identifier that represents a DataSet."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"execute-query-nondeterministic",qname:"jdbc:execute-query-nondeterministic",signature:"($connection-id as xs:anyURI, $sql as xs:string) as object()* external",description:' Executes non-updating SQL statements.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#execute-query-2">execute-query#2</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Executes non-updating SQL statements.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to an active connection.</div>'},{name:"sql",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The statement is Updating type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"execute-query-prepared-nondeterministic",qname:"jdbc:execute-query-prepared-nondeterministic",signature:"($prepared-statement as xs:anyURI) as object()* external",description:' Executes a non-updating SQL statement prepared with 5.1 jsql:prepare-statement.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as\n <a href="#execute-query-prepared-1">execute-query-prepared#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Executes a non-updating SQL statement prepared with 5.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query processed with the parameter values provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The prepared statement is an updating query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"execute-query-prepared",qname:"jdbc:execute-query-prepared",signature:"($prepared-statement as xs:anyURI) as object()* external",description:' Executes a non-updating SQL statement prepared with 5.1 jsql:prepare-statement.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p> Executes a non-updating SQL statement prepared with 5.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query processed with the parameter values provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The prepared statement is an updating query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"execute-query",qname:"jdbc:execute-query",signature:"($connection-id as xs:anyURI, $sql as xs:string) as object()* external",description:' Executes non-updating SQL statements.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p> Executes non-updating SQL statements.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to an active connection.</div>'},{name:"sql",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The statement is Updating type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"execute-update-prepared",qname:"jdbc:execute-update-prepared",signature:"($prepared-statement as xs:anyURI) as xs:integer external",description:" Executes an updating SQL statement prepared with 5.1 jsql:prepare-statement.\n",summary:"<p> Executes an updating SQL statement prepared with 5.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'}],returns:{type:"xs:integer",description:"Returns an xs:integer with the number of affected rows."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL006 The prepared statement is a non-updating query.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"execute-update",qname:"jdbc:execute-update",signature:"($connection-id as xs:anyURI, $sql as xs:string) as xs:integer external",description:" Executes updating SQL statements.\n",summary:"<p> Executes updating SQL statements.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to an active connection.</div>'},{name:"sql",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"xs:integer",description:"Returns an xs:integer with the number of affected rows."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL005 The statement is Read-only type.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"execute",qname:"jdbc:execute",signature:"($connection-id as xs:anyURI, $sql as xs:string) as xs:anyURI external",description:" Executes any kind of SQL statement.\n",summary:"<p> Executes any kind of SQL statement.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to an active connection.</div>'},{name:"sql",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"xs:anyURI",description:"Return an identifier that represents a DataSet."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"is-connected",qname:"jdbc:is-connected",signature:"($connection-id as xs:anyURI) as xs:boolean external",description:" Verify if a connection is still active.\n",summary:"<p> Verify if a connection is still active.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to the connection to be verify.</div>'}],returns:{type:"xs:boolean",description:"Returns true if connected."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message</xqdoc:error>']},{isDocumented:!0,arity:1,name:"metadata",qname:"jdbc:metadata",signature:"($dataset-id as xs:anyURI) as object() external",description:" Return the metadata of the result of a particular DataSet.\n",summary:"<p> Return the metadata of the result of a particular DataSet.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"dataset-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a DataSet.</div>'}],returns:{type:"object()",description:'This function returns the metadata associated with an executed DataSet. More in detail, it returns information about column names, types, and whether a column can contain a null value. The metadata information can only be returned for DataSets that have been executed explicitly using the jsql:execute function. The metadata node returned by this function is defined as follows: { "columns": [ { "name": xs:string, "type": xs:string, "autoincrement"? = xs:boolean, "nillable"? = xs:boolean } * ] }'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL008 DataSet doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"parameter-metadata",qname:"jdbc:parameter-metadata",signature:"($prepared-statement as xs:anyURI) as object() external",description:" Retrieves the number, types and properties of the prepared statement parameters.\n",summary:"<p> Retrieves the number, types and properties of the prepared statement parameters.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'}],returns:{type:"object()",description:'This function returns the parameters metadata associated with a prepared statement. In other words, it returns information about the column name associated with the parameter, the type, etc. The metadata node returned by this function is defined as follows: { columns: [{ "name": xs:string, "type": xs:string }] }'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"prepare-statement",qname:"jdbc:prepare-statement",signature:"($connection-id as xs:anyURI, $sql as xs:string) as xs:anyURI external",description:"  Creates a prepared statement for multiple executions with diferent values.\n",summary:"<p>  Creates a prepared statement for multiple executions with diferent values.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to an active connection.</div>'},{name:"sql",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The query string to be executed.</div>'}],returns:{type:"xs:anyURI",description:'Return an identifier that represents the prepared statement. Example: jsql:prepare-statement($connection, "SELECT * FROM users WHERE id=? AND age&gt;?")'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"result-set",qname:"jdbc:result-set",signature:"($dataset-id as xs:anyURI) as object()* external",description:" This function returns a sequence of objects representing the rows of data from a non-updating query.\n",summary:"<p> This function returns a sequence of objects representing the rows of data from a non-updating query.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"dataset-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a DataSet.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the DataSet provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL008 DataSet doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"rollback",qname:"jdbc:rollback",signature:"($connection-id as xs:anyURI) as empty-sequence() external",description:" Rollback the current transaction of a connection.\n",summary:"<p> Rollback the current transaction of a connection.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to the connection to be rollbacked.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08003 Connection doesn\'t exist</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message</xqdoc:error>']},{isDocumented:!0,arity:3,name:"set-boolean",qname:"jdbc:set-boolean",signature:"($prepared-statement as xs:anyURI, $parameter-index as xs:integer, $value as xs:boolean) as empty-sequence() external",description:" Set the value of the designated parameter with the given value, this function will assign only boolean values.\n",summary:"<p> Set the value of the designated parameter with the given value, this function will assign only boolean values.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'},{name:"parameter-index",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'},{name:"value",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be set.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"set-null",qname:"jdbc:set-null",signature:"($prepared-statement as xs:anyURI, $parameter-index as xs:integer) as empty-sequence() external",description:" Set the value of the designated parameter with the given value, this function\n will assign only null values if possible.\n",summary:"<p> Set the value of the designated parameter with the given value, this function\n will assign only null values if possible.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'},{name:"parameter-index",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"set-numeric",qname:"jdbc:set-numeric",signature:"($prepared-statement as xs:anyURI, $parameter-index as xs:decimal, $value as xs:anyAtomicType) as empty-sequence() external",description:" Set the value of the designated parameter with the given value, this function will assign only numeric values.\n",summary:"<p> Set the value of the designated parameter with the given value, this function will assign only numeric values.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'},{name:"parameter-index",type:"xs:decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'},{name:"value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be set.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"set-string",qname:"jdbc:set-string",signature:"($prepared-statement as xs:anyURI, $parameter-index as xs:integer, $value as xs:string) as empty-sequence() external",description:" Set the value of the designated parameter with the given value, this function will assign only string values.\n",summary:"<p> Set the value of the designated parameter with the given value, this function will assign only string values.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'},{name:"parameter-index",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'},{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be set.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"set-value",qname:"jdbc:set-value",signature:"($prepared-statement as xs:anyURI, $parameter-index as xs:decimal, $value as xs:anyAtomicType) as empty-sequence() external",description:" Set the value of the designated parameter with the given value,\n this function will assign any value you send\n and it will try to cast to the correct type.\n",summary:"<p> Set the value of the designated parameter with the given value,\n this function will assign any value you send\n and it will try to cast to the correct type.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"prepared-statement",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a prepared statement.</div>'},{name:"parameter-index",type:"xs:decimal",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The index from the parameter to be set.</div>'},{name:"value",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The value to be set.</div>'}],returns:{type:"empty-sequence()",description:"This function returns an empty-sequence()"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL003 Prepared statement doesn\'t exist.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL007 Parameter casting error.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"tables-nondeterministic",qname:"jdbc:tables-nondeterministic",signature:"($connection-id as xs:anyURI) as object()*",description:' Return the list of tables from a connection\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#tables-1">tables#1</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Return the list of tables from a connection\n  This function has the same semantics as  tables#1 ,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a connection.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"tables-nondeterministic",qname:"jdbc:tables-nondeterministic",signature:"($connection-id as xs:anyURI, $catalog as xs:string?, $schema as xs:string?, $table as xs:string?) as object()* external",description:' Return the list of tables from a connection.\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function has the same semantics as <a href="#tables-4">tables#4</a>,\n but is declared as being non deterministic and thus should only be used when\n result caching is not desired.</p>\n',summary:"<p> Return the list of tables from a connection.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a connection.</div>'},{name:"catalog",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the catalog name of the tables. Send empty-sequence for all tables.</div>'},{name:"schema",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the schema name of the tables. Send empty-sequence for all tables.</div>'},{name:"table",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the name of the tables. Send empty-sequence for all tables.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"tables",qname:"jdbc:tables",signature:"($connection-id as xs:anyURI) as object()*",description:' Return the list of tables from a connection\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p> Return the list of tables from a connection\n  This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a connection.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']},{isDocumented:!0,arity:4,name:"tables",qname:"jdbc:tables",signature:"($connection-id as xs:anyURI, $catalog as xs:string?, $schema as xs:string?, $table as xs:string?) as object()* external",description:' Return the list of tables from a connection\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>\n',summary:"<p> Return the list of tables from a connection\n  This function is declared as deterministic and should be used whenever result\n caching is acceptable.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"connection-id",type:"xs:anyURI",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The identifier to a connection.</div>'},{name:"catalog",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the catalog name of the tables. Send empty-sequence for all tables.</div>'},{name:"schema",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the schema name of the tables. Send empty-sequence for all tables.</div>'},{name:"table",type:"xs:string",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A filter of the name of the tables. Send empty-sequence for all tables.</div>'}],returns:{type:"object()*",description:"Return an object with the result data rows from the query provided, the data rows are defined as follows: { column:value* }* Every row is represented by an object of column-value representation of the returned SQL result."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL08000 Connection is closed.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">SQL001 Descriptive error, see error in attached message.</xqdoc:error>']}],variables:[{name:"jdbc:NOT-SUPPORTED",type:"item()*",description:" This variable represents the NOT-SUPPORTED level for Isolation Levels in $options for 2.2 connect function.\n"},{name:"jdbc:READ-COMMITTED",type:"item()*",description:" This variable represents the READ-COMMITTED level for Isolation Levels in $options for 2.2 connect function.\n"},{name:"jdbc:READ-UNCOMMITTED",type:"item()*",description:" This variable represents the READ-UNCOMMITTED level for Isolation Levels in $options for 2.2 connect function.\n"},{name:"jdbc:REPEATABLE-READ",type:"item()*",description:" This variable represents the REPEATABLE-READ level for Isolation Levels in $options for 2.2 connect function.\n"},{name:"jdbc:SERIALIZABLE",type:"item()*",description:" This variable represents the SERIALIZABLE level for Isolation Levels in $options for 2.2 connect function.\n"}]},"http://www.28msec.com/modules/http-response":{ns:"http://www.28msec.com/modules/http-response",description:' The response module can be used to modify the HTTP response\n that will be send as a result. For example, the\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">content-type</tt> function can be used to set the\n Content-Type header and determine the encoding of data in the\n response.\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/http-response",prefix:"http"},{uri:"http://www.w3.org/2010/xslt-xquery-serialization",prefix:"output"},{uri:"http://www.28msec.com/modules/http/response#2.0",prefix:"res"},{uri:"http://www.28msec.com/modules/http-response",prefix:"resp"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"code-for-status",qname:"resp:code-for-status",signature:"($status as xs:string) as xs:integer",description:" Convert between the name of the HTTP status code and\n the integer value of that status code.\n",summary:"<p> Convert between the name of the HTTP status code and\n the integer value of that status code.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"status",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:integer",description:"the integer value of the given status code."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-status if the given name does not represent a valid http status code</xqdoc:error>']},{isDocumented:!0,arity:1,name:"content-type-binary",qname:"resp:content-type-binary",signature:"($type as xs:string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a binary content-type. A\n content-type is considered to be binary if it\'s not a text\n content-type.</p>\n',summary:"<p>  Test if a given content-type is a binary content-type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is a binary content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-html",qname:"resp:content-type-html",signature:"($type as xs:string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a HTML content-type, i.e.\n the content-type is the string "text/html".</p>\n',summary:"<p>  Test if a given content-type is a HTML content-type, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is the HTML content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-json",qname:"resp:content-type-json",signature:"($type as xs:string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a JSON content-type, i.e.\n the content-type is the string "application/json".</p>\n',summary:"<p>  Test if a given content-type is a JSON content-type, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is the JSON content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-mixed-json-xml",qname:"resp:content-type-mixed-json-xml",signature:"($type as xs:string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a mixed JSON-XML content-type, i.e.\n the content-type is the string "application/mixed-json-xml".</p>\n',summary:"<p>  Test if a given content-type is a mixed JSON-XML content-type, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is a mixed JSON-XML content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-text",qname:"resp:content-type-text",signature:"($type as xs:string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a text content-type.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A text content-type starts with "text/" or contains either of\n the strings "xml" or "json".</p>\n',summary:"<p>  Test if a given content-type is a text content-type.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is a text content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-xhtml",qname:"resp:content-type-xhtml",signature:"($type as xs:string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a XHTML content-type, i.e.\n the content-type is the string "application/xhtml+xml".</p>\n',summary:"<p>  Test if a given content-type is a XHTML content-type, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is the XHTML content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type-xml",qname:"resp:content-type-xml",signature:"($type as xs:string) as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Test if a given content-type is a XML content-type</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A XML content-type is a content-type that is "application/xml"\n or ends : with the string "+xml".</p>\n',summary:'<p>  Test if a given content-type is a XML content-type \n  A XML content-type is a content-type that is "application/xml"\n or ends : with the string "+xml".</p>',annotation_str:"",annotations:[],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to test.</div>'}],returns:{type:"xs:boolean",description:"true if the given content-type is a XML content-type, false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"content-type",qname:"resp:content-type",signature:"($type as xs:string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the Content-Type header for the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n For example,\n <tt>resp:content-type("text/plain")</tt> will cause the\n header\n <tt>Content-Type: text/plain</tt> to be added for the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addtion to setting the Content-Type header, the function also\n sets the serialization parameters to the default values for serialization\n method for the given content-type. For example, if the content-type is set to\n text/plain, the default serialization parameters for the text\n serialization method will be used.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The functions resp:content-type-text/xml/html/xhtml/binary may be used\n to figure out which serialization method will be used for a specific\n content-type.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the given content-type contains a charset declaration (e.g.\n <tt>resp:content-type("text/plain;charset=ISO-8859-1")</tt>), the\n content of the response will be transcoded to the given encoding.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The default serialization parameters set by this function can\n be overwritten using the resp:serialization-parameters() function.</p>\n',summary:"<p>  Sets the Content-Type header for the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to be set</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and returns the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"content-type",qname:"resp:content-type",signature:"($type as xs:string, $params as object()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the Content-Type header for the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <tt>resp:content-type("text/plain")</tt> will cause the\n header\n <tt>Content-Type: text/plain</tt> to be added for the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">In addition to the content-type, the function also allows to\n specify the serialization method and parameters that will be used\n for serializing the result. For details about this parameter, please\n refer to resp:serialization-parameters#1.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the content-type suggest using a binary serialization,\n resp:decode-binary#1 will be called and set to true except if\n the serialization method is specified at the same time. In this\n case, the serialization method will be used as specified.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If the given content-type contains a charset declaration (e.g.\n <tt>resp:content-type("text/plain;charset=ISO-8859-1")</tt>), the\n content of the response will be transcoded to the given encoding.\n If the serialization parameters also contain a charset declaration,\n the charset contained in the content-type will be used. to transcode\n the result.</p>\n',summary:"<p>  Sets the Content-Type header for the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"type",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content-type to be set</div>'},{name:"params",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the serialization parameters that will be used for serialization the result.</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and returns the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"decode-binary",qname:"resp:decode-binary",signature:"() as xs:boolean",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the boolean indiciating whether base64Binary returned by\n this request will be decoded.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The default if not modified using resp:decode-binary is false.</p>\n',summary:"<p>  Returns the boolean indiciating whether base64Binary returned by\n this request will be decoded.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"xs:boolean",description:"the said boolean value"},errors:[]},{isDocumented:!0,arity:1,name:"decode-binary",qname:"resp:decode-binary",signature:"($decode as xs:boolean) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If this function is invoked with true, the result of the request\n will not be serialized. Instead, the result will be the binary values\n of any item that is of type base64Binary. The values of all other\n items will not be part of the result.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that all serialization parameters which have been set using\n resp:serialization-parameters will be ignored. Also, the output encoding\n is ignored for binaries.</p>\n',summary:"<p>  If this function is invoked with true, the result of the request\n will not be serialized.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"decode",type:"xs:boolean",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> boolean value indicating whether base64Binary should be decoded.</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and returns the empty sequence."},errors:[]},{isDocumented:!0,arity:1,name:"encoding",qname:"resp:encoding",signature:"($encoding as xs:string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function sets the output encoding that will be\n used for the payload of the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <tt>resp:encoding("ISO-8859-1")</tt> will cause the\n content in the response to be encoded using ISO-8859-1.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that the encoding only applies to textual data.\n It is not used if the function <tt>decode-binary()</tt>\n was invoked passing true as parameter.</p>\n',summary:"<p>  The function sets the output encoding that will be\n used for the payload of the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"encoding",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the encoding to be used for the payload of the response.</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and returns the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-encoding if the given encoding is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"header",qname:"resp:header",signature:"($name as xs:string, $value as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Set a HTTP header in the response.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If a header with the same name was already set, the\n value is overwritten and the function returns the old value. As defined\n in the HTTP specification, multiple headers with the same name\n can be combined into one header whose value is a comma-separated\n list of the values.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The following headers must not be set using this function.\n Instead, other functions of this module should be used in order\n to implemented the required semantics:\n <ul>\n   <li>Status: use status() instead</li>\n   <li>Content-Type: use content-type() instead</li>\n </ul>\n </p>\n',summary:"<p>  Set a HTTP header in the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"name",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the name of the header to set</div>'},{name:"value",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the value of the header to set `</div>'}],returns:{type:"xs:string?",description:"the value of the header previously set or the empty sequence if no header has been set with the same name."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">resp:invalid-header-name if an invalid name is used for the header.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"message-for-status",qname:"resp:message-for-status",signature:"($status as xs:string) as xs:string",description:" Convert between the HTTP status code as string and\n the name/message of that status code.\n",summary:"<p> Convert between the HTTP status code as string and\n the name/message of that status code.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"status",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string",description:"the message for the given name"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-status if the given name does not represent a valid http status code</xqdoc:error>']},{isDocumented:!0,arity:1,name:"redirect",qname:"resp:redirect",signature:"($url as xs:string) as empty-sequence()",description:" This function sets the HTTP 302 redirect status code in the response. As\n a result, a redirect to the URL given as parameter will be made.\n",summary:"<p> This function sets the HTTP 302 redirect status code in the response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"url",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the redirect will be made.</div>'}],returns:{type:"empty-sequence()",description:"The empty-sequence is returned."},errors:[]},{isDocumented:!0,arity:0,name:"serialization-parameters",qname:"resp:serialization-parameters",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the serialization parameters that are currently\n active, i.e. the ones that will be used to serialize the result\n of this request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This will either be the default, the defaults set when\n calling resp:content-type(), or the ones set by\n resp:serialization-parameters().</p>\n',summary:"<p>  Returns the serialization parameters that are currently\n active, i.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"the said serialization parameters"},errors:[]},{isDocumented:!0,arity:1,name:"serialization-parameters",qname:"resp:serialization-parameters",signature:"($params as object()) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Set the serialization parameters used for serializing the result\n of the request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The following example shows how to set several options\n for the JSON serialization method.\n <pre>\n {\n   "method" : "json",\n   "indent" : false,\n   "encoding" : "UTF-16"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Please note that serialization options set by this function can\n be overwritten by a subsequent call to resp:content-type. In this\n case, the options will be reset to the default for the given\n content-type. Also note, that the output encoding can be overwritten\n by subsequently calling the resp:encoding function.</p>\n',summary:"<p>  Set the serialization parameters used for serializing the result\n of the request.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"params",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the serialization parameters that will be used to serialize the result of the request</div>'}],returns:{type:"empty-sequence()",description:"the function is sequential and, on success, returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 if the input is not valid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-encoding if the encoding specified in the serialization options is invalid or not supported.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"serializer-defaults-html",qname:"resp:serializer-defaults-html",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an object that can be used to specify the\n settings of serialization parameters for the HTML serialization\n method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <pre>\n {\n   "encoding" : "UTF-8",\n   "indent" : true,\n   "method" : "html",\n   "version" : "4.01",\n   "doctype-system" : "http://www.w3.org/TR/html4/loose.dtd",\n   "doctype-public" : "-//W3C//DTD HTML 4.01 Transitional//EN"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to some HTML content-type (i.e. text/html).</p>\n',summary:"<p>  Returns an object that can be used to specify the\n settings of serialization parameters for the HTML serialization\n method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"an object that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-json-xml-hybrid",qname:"resp:serializer-defaults-json-xml-hybrid",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an object that can be used to specify the\n settings of serialization parameters for the json\n serialization method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <pre>\n {\n   "encoding" : "UTF-8",\n   "indent" : "yes",\n   "method" : "json"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to some XML content-type (e.g. application/atom+xml).</p>\n',summary:"<p>  Returns an object that can be used to specify the\n settings of serialization parameters for the json\n serialization method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"an object that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-json",qname:"resp:serializer-defaults-json",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an object that can be used to specify the\n settings of serialization parameters for the json-xml hybrid\n serialization method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <pre>\n {\n   "encoding" : "UTF-8",\n   "indent" : "yes",\n   "method" : "json"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to application/mixed-json-xml.</p>\n',summary:"<p>  Returns an object that can be used to specify the\n settings of serialization parameters for the json-xml hybrid\n serialization method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"an object that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-text",qname:"resp:serializer-defaults-text",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an object that can be used to specify the\n settings of serialization parameters for the text serialization\n method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The only default used is\n <pre>\n {\n  "method" : "text",\n  "encoding" : "UTF-8",\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, this default is used when setting\n the content-type to some text content-type (e.g. text/plain).</p>\n',summary:"<p>  Returns an object that can be used to specify the\n settings of serialization parameters for the text serialization\n method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"an object that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-xhtml",qname:"resp:serializer-defaults-xhtml",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an object that can be used to specify the\n settings of serialization parameters for the XHTML serialization\n method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <pre>\n {\n   "encoding" : "UTF-8",\n   "indent" : true,\n   "method" : "xhtml",\n   "omit-xml-declaration" : true,\n   "version" : "1.0",\n   "doctype-system" : "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd",\n   "doctype-public" : "-//W3C//DTD XHTML 1.0 Transitional//EN"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to some XHTML content-type (i.e. application/xhtml+xml).</p>\n',summary:"<p>  Returns an object that can be used to specify the\n settings of serialization parameters for the XHTML serialization\n method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"an object that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:0,name:"serializer-defaults-xml",qname:"resp:serializer-defaults-xml",signature:"() as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns an object that can be used to specify the\n settings of serialization parameters for the XML serialization\n method.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The defaults are\n <pre>\n {\n  "method" : "xml",\n  "encoding" : "UTF-8",\n  "indent" : true,\n  "omit-xml-declaration" : true,\n  "version" : "1.0"\n }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example, those defaults are used when setting\n the content-type to some XML content-type (e.g. application/atom+xml).</p>\n',summary:"<p>  Returns an object that can be used to specify the\n settings of serialization parameters for the XML serialization\n method.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()",description:"an object that can be used to specify the above serialization parameters."},errors:[]},{isDocumented:!0,arity:1,name:"status-code",qname:"resp:status-code",signature:"($status as xs:integer) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the status code of the HTTP response to the integer given as\n parameter.</p>\n For example,\n <tt xmlns:xqdoc="http://www.xqdoc.org/1.0">resp:status(204)</tt>\n will result in "HTTP/1.1 204 No Content".\n',summary:"<p>  Sets the status code of the HTTP response to the integer given as\n parameter.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"status",type:"xs:integer",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The status code of the HTTP response as integer.</div>'}],returns:{type:"empty-sequence()",description:"On success, the empty-sequence is returned"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-status-code if the given integer does not reflect a valid HTTP status code</xqdoc:error>']},{isDocumented:!0,arity:1,name:"status",qname:"resp:status",signature:"($status as xs:string) as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Sets the status code of the HTTP response to code associated\n with the given string.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For example,\n <tt>resp:status($http:no-content)</tt>\n will result in "HTTP/1.1 204 No Content".</p>\n',summary:"<p>  Sets the status code of the HTTP response to code associated\n with the given string.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"status",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The status code of the HTTP response as a string (e.g. $http:no-content)</div>'}],returns:{type:"empty-sequence()",description:"On success, the empty-sequence is returned"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:invalid-status if the given string does not represent a valid HTTP status code;</xqdoc:error>']},{isDocumented:!0,arity:1,name:"valid-status",qname:"resp:valid-status",signature:"($status as xs:string) as xs:boolean",description:" Test whether the given name refers to a valid HTTP status code.\n",summary:"<p> Test whether the given name refers to a valid HTTP status code.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"status",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:boolean",description:"true if the given name refers to a valid HTTP status code, false otherwise."},errors:[]}],variables:[{name:"http:precondition-required",type:"item()*",description:" A string representing the HTTP Status Code 428 Precondition Required (RFC 6585)\n"},{name:"http:gone",type:"item()*",description:" A string representing the HTTP Status Code 410 GONE\n"},{name:"http:length-required",type:"item()*",description:" A string representing the HTTP Status Code 411 Length Required\n"},{name:"http:precondition-failed",type:"item()*",description:" A string representing the HTTP Status Code 412 Precondition Failed\n"},{name:"http:request-entity-too-large",type:"item()*",description:" A string representing the HTTP Status Code 413 Request Entity Too Large\n"},{name:"http:request-entity-too-long",type:"item()*",description:" A string representing the HTTP Status Code 414 Request Entity Too Long\n"},{name:"http:unsupported-media-type",type:"item()*",description:" A string representing the HTTP Status Code 415 Unsupported Media Type\n"},{name:"http:request-range-not-satisfiable",type:"item()*",description:" A string representing the HTTP Status Code 416 Request Range Not Satisfiable\n"},{name:"http:expectation-failed",type:"item()*",description:" A string representing the HTTP Status Code 417 Expectation Failed\n"},{name:"http:im-a-teapot",type:"item()*",description:" A string representing the HTTP Status Code 418 I'm a teapot (RFC 2324)\n"},{name:"http:enhance-your-calm",type:"item()*",description:" A string representing the HTTP Status Code 420 Enhance Your Calm\n"},{name:"http:unprocessable-entity",type:"item()*",description:" A string representing the HTTP Status Code 422 Unprocessable Entity (WebDAV; RFC 4918)\n"},{name:"http:locked",type:"item()*",description:" A string representing the HTTP Status Code 423 Locked (WebDAV; RFC 4918)\n"},{name:"http:failed-dependency",type:"item()*",description:" A string representing the HTTP Status Code 424 Failed Dependency (WebDAV; RFC 4918)\n"},{name:"http:unordered-collection",type:"item()*",description:" A string representing the HTTP Status Code 425 Unordered Collection\n"},{name:"http:upgrade-required",type:"item()*",description:" A string representing the HTTP Status Code 426 Upgrade Required\n"},{name:"http:conflict",type:"item()*",description:" A string representing the HTTP Status Code 409 Conflict\n"},{name:"http:too-many-requests",type:"item()*",description:" A string representing the HTTP Status Code 429 Too Many Requests (RFC 6585)\n"},{name:"http:request-header-fields-too-large",type:"item()*",description:" A string representing the HTTP Status Code 431 Request Header Fields Too Large (RFC 6585)\n"},{name:"http:internal-server-error",type:"item()*",description:" A string representing the HTTP Status Code 500 Internal Server Error\n"},{name:"http:not-implemented",type:"item()*",description:" A string representing the HTTP Status Code 501 Not Implemented\n"},{name:"http:bad-gateway",type:"item()*",description:" A string representing the HTTP Status Code 502 Bad Gateway\n"},{name:"http:service-unavailable",type:"item()*",description:" A string representing the HTTP Status Code 503 Service Unavailable\n"},{name:"http:gateway-timeout",type:"item()*",description:" A string representing the HTTP Status Code 504 Gateway Timeout\n"},{name:"http:http-version-not-supported",type:"item()*",description:" A string representing the HTTP Status Code 505 HTTP Version Not Supported\n"},{name:"http:variant-also-negotiates",type:"item()*",description:" A string representing the HTTP Status Code 506 Variant Also Negotiates (RFC 2295)\n"},{name:"http:insufficient-storage",type:"item()*",description:" A string representing the HTTP Status Code 507 Insufficient Storage (WebDAV; RFC 4918)\n"},{name:"http:loop-detected",type:"item()*",description:" A string representing the HTTP status code 508 Loop Detected (webdav; rfc 5842)\n"},{name:"http:not-extended",type:"item()*",description:" A string representing the HTTP status code 510 Not Extended (RFC 2774)\n"},{name:"http:network-authentication-required",type:"item()*",description:" A string representing the HTTP status code 511 Network Authentication Required (RFC 6585)\n"},{name:"resp:status-info",type:"object()",description:" Variable containing a description for all the HTTP Status Codes\n"},{name:"http:see-other",type:"item()*",description:" A string representing the HTTP Status Code 303 See Other\n"},{name:"http:switching-protocols",type:"item()*",description:" A string representing the HTTP Status Code 101 Switching Protocols\n"},{name:"http:processing",type:"item()*",description:" A string representing the HTTP Status Code 102 Processing (Web; RFC 2518)\n"},{name:"http:ok",type:"item()*",description:" A string representing the HTTP Status Code 200 OK\n"},{name:"http:created",type:"item()*",description:" A string representing the HTTP Status Code 201 Created\n"},{name:"http:accepted",type:"item()*",description:" A string representing the HTTP Status Code 202 Accepted\n"},{name:"http:non-authoritative",type:"item()*",description:" A string representing the HTTP Status Code 203 Non-Authoritative\n"},{name:"http:no-content",type:"item()*",description:" A string representing the HTTP Status Code 204 No Content\n"},{name:"http:reset-content",type:"item()*",description:" A string representing the HTTP Status Code 205 Reset Content\n"},{name:"http:partial-content",type:"item()*",description:" A string representing the HTTP Status Code 206 Partial Content\n"},{name:"http:multi-status",type:"item()*",description:" A string representing the HTTP Status Code 207 Multi-Status (WebDAV; RFC 5842)\n"},{name:"http:already-reported",type:"item()*",description:" A string representing the HTTP Status Code 208 Already Reported (WebDAV; RFC 5842)\n"},{name:"http:im-used",type:"item()*",description:" A string representing the HTTP Status Code 226 IM Used (RFC 3229)\n"},{name:"http:multiple-choices",type:"item()*",description:" A string representing the HTTP Status Code 300 Multiple Choices\n"},{name:"http:moved-permanently",type:"item()*",description:" A string representing the HTTP Status Code 301 Moved Permantently\n"},{name:"http:found",type:"item()*",description:" A string representing the HTTP Status Code 302 Found\n"},{name:"http:continue",type:"item()*",description:" A string representing the HTTP Status Code 100 Continue\n"},{name:"http:not-modified",type:"item()*",description:" A string representing the HTTP Status Code 304 Not Modified\n"},{name:"http:use-proxy",type:"item()*",description:" A string representing the HTTP Status Code 305 Use Proxy\n"},{name:"http:switch-proxy",type:"item()*",description:" A string representing the HTTP Status Code 306 Switch Proxy\n"},{name:"http:temporary-redirect",type:"item()*",description:" A string representing the HTTP Status Code 307 Temporary Redirect\n"},{name:"http:permanent-redirect",type:"item()*",description:" A string representing the HTTP Status Code 308 Permanent Redirect (http://tools.ietf.org/html/draft-reschke-http-status-308-07)\n"},{name:"http:bad-request",type:"item()*",description:" A string representing the HTTP Status Code 400 Bad Request\n"},{name:"http:unauthorized",type:"item()*",description:" A string representing the HTTP Status Code 401 Unauthorized\n"},{name:"http:payment-required",type:"item()*",description:" A string representing the HTTP Status Code 402 Payment Required\n"},{name:"http:forbidden",type:"item()*",description:" A string representing the HTTP Status Code 403 Forbidden\n"},{name:"http:not-found",type:"item()*",description:" A string representing the HTTP Status Code 404 Not Found\n"},{name:"http:not-allowed",type:"item()*",description:" A string representing the HTTP Status Code 405 Not Allowed\n"},{name:"http:not-acceptable",type:"item()*",description:" A string representing the HTTP Status Code 406 Not Acceptable\n"},{name:"http:proxy-authentication-required",type:"item()*",description:" A string representing the HTTP Status Code 407 Proxy Authentication Required\n"},{name:"http:request-timeout",type:"item()*",description:" A string representing the HTTP Status Code 408 Request Timeout\n"}]},"http://www.zorba-xquery.com/modules/email/smtp":{ns:"http://www.zorba-xquery.com/modules/email/smtp",description:' This module can be used for sending emails.\n The SMTP module contains only one public function that receives two parameters.\n The SMTP server access information passed as an <code xmlns:xqdoc="http://www.xqdoc.org/1.0">hostInfo</code> element\n and the email message representation as a <code xmlns:xqdoc="http://www.xqdoc.org/1.0">message</code> element.\n For a quick start see the examples associates with the <code xmlns:xqdoc="http://www.xqdoc.org/1.0">send(...)</code>\n function. For a complete specification read, the description and the\n documentation associated with this function.\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.washington.edu/imap/">c-client Library part of UW IMAP toolkit</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Sorin Nasoi, Daniel Thomas</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.zorba-xquery.com/modules/email",prefix:"email"},{uri:"http://www.zorba-xquery.com/modules/email/smtp",prefix:"smtp"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"send",qname:"smtp:send",signature:"($host-info as element(email:hostInfo), $message as element(email:message)) as empty-sequence()",description:' This function sends an email message from the specified account.\n The <code xmlns:xqdoc="http://www.xqdoc.org/1.0">hostName</code> child element of <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$host-info</code> must have the form:\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0"><b>remote_system_name</b> [":" <b>port</b>] [<b>flags</b>]</code>. This syntax is part of the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://www.washington.edu/imap/documentation/naming.txt.html" target="_blank">Remote names</a>\n syntax defined in the UW IMAP toolkit. The <code xmlns:xqdoc="http://www.xqdoc.org/1.0"><b>remote_system_name</b></code> and\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0"><b>flags</b></code> fragments are explained in the section <code xmlns:xqdoc="http://www.xqdoc.org/1.0">III</code> of this document.\n For example the hostName could look like:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li><code>&lt;hostName&gt;smtp.gmail.com:587/tls/novalidate-cert&lt;hostName&gt;</code></li>\n   <li><code>&lt;hostName&gt;[209.85.129.111]:587/tls/novalidate-cert&lt;hostName&gt;</code></li>\n </ul>\n The <code xmlns:xqdoc="http://www.xqdoc.org/1.0">$host-info</code> parameter could then look like this:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n &lt;hostInfo&gt;\n   &lt;hostName&gt;smtp.gmail.com:587/tls/novalidate-cert&lt;/hostName&gt;\n   &lt;userName&gt;username&lt;/userName&gt;\n   &lt;password&gt;password&lt;/password&gt;\n &lt;/hostInfo&gt;\n </pre>\n For a complete of the structure of an email message, see the imported email\n schema: <code xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.zorba-xquery.com/modules/email</code>\n All the data passed to this function does not need to be validated.\n The only requirement is that they have a valid format and are in the\n correct namespace according to the schema:\n <code xmlns:xqdoc="http://www.xqdoc.org/1.0">http://www.zorba-xquery.com/modules/email</code>.\n',summary:"<p> This function sends an email message from the specified account.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"host-info",type:"element(email:hostInfo)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The SMTP host, user name, and password.</div>'},{name:"message",type:"element(email:message)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The message to send as defined in the email XML schema.</div>'}],returns:{type:"empty-sequence()",description:"The function is declared as sequential and has side-effects. It returns the empty sequence."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">smtp:SMTP0001 The message format is invalid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">smtp:SMTP0002 The message has no recipient.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">smtp:SMTP0003 The message could not be sent.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">smtp:SMTP9999 If any other error occurs.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 If the values of the arguments are not not valid according to the email schema: <code>http://www.zorba-xquery.com/modules/email</code></xqdoc:error>']}],variables:[]},"http://www.28msec.com/modules/project":{ns:"http://www.28msec.com/modules/project",description:" This module contains functions to introspect a project.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://zorba.io/modules/base64",prefix:"base64"},{uri:"http://zorba.io/modules/hmac",prefix:"hmac"},{uri:"http://www.28msec.com/modules/project",prefix:"project"},{uri:"http://zorba.io/modules/random",prefix:"random"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"create-seed",qname:"project:create-seed",signature:"() as string",description:" Creates and return new random project seed.\n",summary:"<p> Creates and return new random project seed.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"string",description:"the project seed"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED-EXISTS the project already has a seed file</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED-FILE error writing the seed file</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED the specified seed is not at least 8 characters long</xqdoc:error>']},{isDocumented:!0,arity:1,name:"create-seed",qname:"project:create-seed",signature:"($seed as string) as empty-sequence()",description:" Creates a new project seed.\n The specified seed must be at least 8 characters long.\n",summary:"<p> Creates a new project seed.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"seed",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The new project seed.</div>'}],returns:{type:"empty-sequence()",description:"the empty sequence"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED-EXISTS the project already has a seed file</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED-FILE error writing the seed file</xqdoc:error>']},{isDocumented:!0,arity:0,name:"has-seed",qname:"project:has-seed",signature:"() as boolean external",description:" Checks if the project has a seed file.\n",summary:"<p> Checks if the project has a seed file.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"boolean",description:"whether the project has a seed file or not"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED-FILE error accessing the seed file</xqdoc:error>']},{isDocumented:!0,arity:0,name:"name",qname:"project:name",signature:"() as string external",description:" Returns the name of the project.\n",summary:"<p> Returns the name of the project.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"string",description:"the said name"},errors:[]},{isDocumented:!0,arity:0,name:"read-or-create-seed",qname:"project:read-or-create-seed",signature:"() as string",description:" Returns the project seed. If the project has no seed a new random one is created.\n",summary:"<p> Returns the project seed.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"string",description:"the project seed"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED-FILE error reading or writing the seed file</xqdoc:error>']},{isDocumented:!0,arity:0,name:"scheduler-host",qname:"project:scheduler-host",signature:"() as string external",description:" Returns the host of the scheduler.\n",summary:"<p> Returns the host of the scheduler.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"string",description:"the scheduler host."},errors:[]},{isDocumented:!0,arity:0,name:"seed",qname:"project:seed",signature:"() as string external",description:" Returns the project seed.\n",summary:"<p> Returns the project seed.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"string",description:"the project seed"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:NO-SEED the project seed file cannot be found</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED-FILE error reading the seed file</xqdoc:error>']},{isDocumented:!0,arity:0,name:"set-seed",qname:"project:set-seed",signature:"() as string",description:" Sets a new random project seed.\n",summary:"<p> Sets a new random project seed.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"string",description:"the project seed"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED-FILE error reading or writing the seed file</xqdoc:error>']},{isDocumented:!0,arity:1,name:"set-seed",qname:"project:set-seed",signature:"($seed as string) as empty-sequence()",description:" Sets the project seed.\n The specified seed must be at least 8 characters long.\n",summary:"<p> Sets the project seed.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"seed",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The new project seed.</div>'}],returns:{type:"empty-sequence()",description:"the project seed"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED-FILE error reading or writing the seed file</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:SEED the specified seed is not at least 8 characters long</xqdoc:error>']},{isDocumented:!0,arity:0,name:"token",qname:"project:token",signature:"() as xs:base64Binary",description:" Creates a new project token, that expires after 12 hours.\n",summary:"<p> Creates a new project token, that expires after 12 hours.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[],returns:{type:"xs:base64Binary",description:"the project token"},errors:[]},{isDocumented:!0,arity:1,name:"token",qname:"project:token",signature:"($expiration as xs:anyAtomicType) as xs:base64Binary",description:" Creates a new project token, that expires at the desired date.\n The input to the function contains the expiration information.\n If a duration is used, then the function will create a token expiring after the specified duration.\n If a dateTime is used, then the function will create a token expiring that date.\n If an integer is used, then the function will create a token expiring after the specified number of seconds.\n",summary:"<p> Creates a new project token, that expires at the desired date.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"expiration",type:"xs:anyAtomicType",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> describes the expiration date of the token.</div>'}],returns:{type:"xs:base64Binary",description:"the new project token"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">project:INVALID-PARAMETER expiration information is invalid (not a duration, date or number of seconds)</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/http-client":{ns:"http://zorba.io/modules/http-client",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This module provides functions for performing HTTP requests.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">A simple GET request using the get#1 convenience function</p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n import module namespace http="http://zorba.io/modules/http-client";\n http:get("http://www.example.com")\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This example makes a GET request to example.com and returns the server\'s response\n as a JSON object.\n </p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="java">\n {\n   "status" : 200,\n   "message" : "OK",\n   "headers" : {\n     "Content-Length" : "1270",\n     "Date" : "Tue, 11 Jun 2013 22:27:10 GMT",\n     ...\n   },\n   "body" : {\n     "media-type" : "text/html",\n     "content" : "..."\n   }\n }\n </pre>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="standard_return">Response format</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Most functions in this module (all except <a href="?anchor=options-1">options#1</a>)\n return a single JSON item, describing the server\'s response, as in the previous\n example.\n The server status (integer) and message (string) fields are always present.\n If the server replied sending one or more headers, they are reported\n in an optional headers object. Each header is represented as a single (string)\n field.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For non-multipart responses, as in the previous example, the response body,\n if any, is reported as a body object. This object contains both the (string)\n media-type returned by the server and its content.\n The type of the content field is determined by the media-type returned by the\n server. If the media-type indicates that the body content is textual,\n then the content has type string, base64Binary otherwise.\n Specifically, the body content is considered textual only if the MIME-type specified in\n the media-type is one of:\n <ul>\n   <li>"application/json"</li>\n   <li>"application/x-javascript"</li>\n   <li>"application/xml"</li>\n   <li>"application/xml-external-parsed-entity"</li>\n </ul>\n or if the MIME-type starts with "text/" or ends with "+xml".</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For multipart responses, multiple bodies are returned, as in the following example: </p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="java">\n {\n   "status" : 200,\n   "message" : "OK",\n   "headers" : {\n     "Date" : "Tue, 11 Jun 2013 22:34:13 GMT",\n     ...\n   },\n   "multipart" : {\n     "boundary": "--AaB03x",\n     "parts": [\n       {\n         "headers" : {\n            "Content Disposition: file",\n            ...\n         },\n         "body": {\n           "media-type" : "image/gif",\n           "content" : "..."\n         }\n       },\n       {\n         "body" : {\n           "media-type" : "text/html",\n           "content" : "..."\n         }\n       }\n    ]\n }\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The multipart field contains both the boundary used to separate parts\n and an array containing all parts. Each part contains its specific headers,\n if any, and the corresponding body.</p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="nondeterministic_warning">Important Notice Regarding Nondeterministic Functions</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The following functions in this module -\n <a href="?anchor=get-1">get#1</a>,\n <a href="?anchor=get-text-1">get-text#1</a>,\n <a href="?anchor=get-binary-1">get-binary#1</a>,\n <a href="?anchor=send-nondeterministic-request-1">send-nondeterministic-request-1</a>,\n <a href="?anchor=head-1">head#1</a>, and\n <a href="?anchor=options-1">options#1</a>\n are declared to be <i>nondeterministic</i>, which means that their results\n will not be cached.\n However, they are <b>not</b> declared to be\n <i>sequential</i>, which means that they may be re-ordered during query optimization.\n According to the HTTP RFC, GET, HEAD an OPTIONS requests should not have any side-effects.\n However, in practice it is not uncommon, especially for GET requests, to have side-effects.\n If your application depends on the ordering of side-effects from requests issued through\n these functions, you should either use the <a href="?anchor=send-request-1">send-request()</a>\n function (which is declared <i>sequential</i>), or alternatively\n wrap each call to get() in your own sequential function, to ensure\n that the requests are not reordered.\n Conversely, if you want their results to be cached you can use the\n <a href="?anchor=send-deterministic-request-3">send-deterministic-request()</a>\n function (which is declared <i>deterministic</i>).\n </p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="url_string">$href Arguments to Functions</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Several functions in this module accept a URL argument named $href. In\n all cases, the value passed to $href must be a valid anyURI.\n However, all functions declare $href to be of type string. This\n is for convenience, since you can pass a string literal value (that\n is, a URL in double-quotes spelled out explicitly in your query)\n to an string parameter.</p>\n <h2 xmlns:xqdoc="http://www.xqdoc.org/1.0" id="expath_relation">Relation to the EXPath http-client module</h2>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://expath.org/">EXPath</a> defines its own http-client\n module, which is available separately.\n There are two primary differences between EXPath\'s http-client and\n this module:\n <ol>\n   <li>EXPath does not include the simpler get(), post(), put(), delete(),\n head(), options() and patch() functions defined by this module.</li>\n <li>EXPath uses XML to represent request for its send-request() function,\n whereas this module uses JSON.</li>\n <li>EXPath specifies that all XML content returned by an HTTP server\n will be parsed and returned as an XML document, whereas all HTML content\n will be <i>tidied up</i> into valid XML, and then parsed into an element.\n This module returns any textual content as string and any binary content\n as base6Binary.</li>\n <li>EXPath accepts XML nodes as body in the send-request() function and\n automatically serializes them into a string. The send-request() function\n defined in this module only allows string, base64Binary, and hexBinary\n as body types.\n </li>\n </ol>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n See <a href="http://www.expath.org/spec/http-client">the full spec\n of the EXPath http-client module</a> for more information.\n </p>\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0"><a href="http://www.w3.org/TR/xquery-11/#FunctionDeclns">XQuery 1.1: Function Declaration</a></xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Federico Cavalieri</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://zorba.io/modules/http-client",prefix:"http"},{uri:"http://jsoniq.org/function-library",prefix:"libjn"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"delete",qname:"http:delete",signature:"($href as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes an HTTP DELETE request to a given URL.\n </p>\n',summary:"<p>  \n This function makes an HTTP DELETE request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"get-binary",qname:"http:get-binary",signature:"($href as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes a GET request on a given URL. All returned bodies\n are forced to be interpreted as binary data, and will be returned\n as base64Binary items.\n </p>\n',summary:"<p>  \n This function makes a GET request on a given URL.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified href is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"get-text",qname:"http:get-text",signature:"($href as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes a GET request to a given URL. All returned bodies\n are forced to be interpreted as textual, with a UTF-8 charset and will\n be returned as string items.\n </p>\n',summary:"<p>  \n This function makes a GET request to a given URL.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified href is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"get",qname:"http:get",signature:"($href as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes a GET request to a given URL.\n </p>\n',summary:"<p>  \n This function makes a GET request to a given URL.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified href is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"head",qname:"http:head",signature:"($href as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes an HTTP HEAD request on a given URL.\n </p>\n',summary:"<p>  \n This function makes an HTTP HEAD request on a given URL.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified href is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"options",qname:"http:options",signature:"($href as string) as string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes an HTTP OPTIONS request, which asks the server\n which operations it supports.\n </p>\n',summary:"<p>  \n This function makes an HTTP OPTIONS request, which asks the server\n which operations it supports.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'}],returns:{type:"string*",description:"A sequence of string values of the allowed operations."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified href is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"patch",qname:"http:patch",signature:"($href as string, $body as atomic) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes an HTTP PATCH request to a given URL.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The body passed to this function must be either a string, a base64Binary or\n an hexBinary.\n If it is a string, the Content-Type sent to the server will be "text/plain",\n "application/octet-stream" otherwise.\n </p>\n',summary:"<p>  \n This function makes an HTTP PATCH request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server.</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"patch",qname:"http:patch",signature:"($href as string, $body as atomic, $content-type as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes an HTTP PATCH request to a given URL.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The body passed to this function must be either a string, a base64Binary, or\n an hexBinary.\n In any case, Content-Type of the request sent to the server will\n be $content-type.\n </p>\n',summary:"<p>  \n This function makes an HTTP PATCH request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server.</div>'},{name:"content-type",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The content type of $body to send to the server.</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:CHARSET The specified charset is unsupported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"post",qname:"http:post",signature:"($href as string, $body as atomic) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes an HTTP POST request to a given URL.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The body passed to this function must be either a string, a base64Binary, or an\n hexBinary.\n If it is a string, the Content-Type sent to the server will be "text/plain",\n "application/octet-stream" otherwise.\n </p>\n',summary:"<p>  \n This function makes an HTTP POST request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server.</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"post",qname:"http:post",signature:"($href as string, $body as atomic, $content-type as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes an HTTP POST request to a given URL.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The body passed to this function must be either a string, a base64Binary,\n or an hexBinary.\n In any case, Content-Type of the request sent to the server will\n be $content-type.\n </p>\n',summary:"<p>  \n This function makes an HTTP POST request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server</div>'},{name:"content-type",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The content type of the body as described above.</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:CHARSET The specified charset is unsupported.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"put",qname:"http:put",signature:"($href as string, $body as atomic) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes an HTTP PUT request to a given URL.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The body passed to this function must be either a string, a base64Binary or\n an hexBinary.\n If it is a string, the Content-Type sent to the server will be "text/plain",\n "application/octet-stream" otherwise.\n </p>\n',summary:"<p>  \n This function makes an HTTP PUT request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server.</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"put",qname:"http:put",signature:"($href as string, $body as atomic, $content-type as string) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function makes an HTTP PUT request to a given URL.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The body passed to this function must be either a string, a base64Binary, or\n an hexBinary.\n In any case, Content-Type of the request sent to the server will\n be $content-type.\n </p>\n',summary:"<p>  \n This function makes an HTTP PUT request to a given URL.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"href",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The URL to which the request will be made (see <a href="#url_string">note</a> above).</div>'},{name:"body",type:"atomic",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The body which will be sent to the server.</div>'},{name:"content-type",type:"string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The content type of $body to send to the server.</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:CHARSET The specified charset is unsupported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"send-deterministic-request",qname:"http:send-deterministic-request",signature:"($request as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends an HTTP request and returns the corresponding response.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function has the same semantics as <a href="#send-request-1">send-request-1</a>,\n but is declared as deterministic and thus should only be used when\n the request has no side-effects and behaves deterministic as required by the\n application.\n </p>\n',summary:"<p>  \n This function sends an HTTP request and returns the corresponding response.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"request",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> see request parameter of <a href="#send-request-1">send-request#1</a></div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:FOLLOW Cannot follow a redirect of a POST, PUT, or DELETE request.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:CHARSET The specified charset is unsupported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"send-nondeterministic-request",qname:"http:send-nondeterministic-request",signature:"($request as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends an HTTP request and returns the corresponding response.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function has the same semantics as <a href="#send-request-1">send-request-1</a>,\n but is declared as being non deterministic and thus should only be used when\n the request has no side-effects.\n </p>\n',summary:"<p>  \n This function sends an HTTP request and returns the corresponding response.</p>",annotation_str:" %an:nondeterministic",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"nondeterministic",value:""}],updating:!1,parameters:[{name:"request",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> see request parameter of <a href="#send-request-1">send-request#1</a></div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:FOLLOW Cannot follow a redirect of a POST, PUT, or DELETE request.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:CHARSET The specified charset is unsupported.</xqdoc:error>']},{isDocumented:!0,arity:1,name:"send-request",qname:"http:send-request",signature:"($request as object()) as object()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function sends an HTTP request and returns the corresponding response.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This function is declared as sequential and should be used whenever the\n request may have side-effects.\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The request parameters are specified in the $request JSON object, which\n has the following minimal structure:\n <pre class="ace-static" ace-mode="java">\n   {\n     "href": "http://www.example.com"\n   }\n </pre>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This object specifies a GET request of the URI "http://www.example.com"</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Additional optional parameters can be specified when issuing a request,\n using the following structure:</p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="java">\n  {\n    "method": "POST",\n    "href": "http://www.example.com",\n    "authentication":\n    {\n      "username" : "user",\n      "password" : "pass",\n      "auth-method" : "Basic"\n    },\n    "options":\n    {\n      "status-only": true,\n      "override-media-type": "text/plain",\n      "follow-redirect": false,\n      "timeout": 30,\n      "user-agent": "Mozilla/5.0",\n      "retry":\n      {\n        "delay": [1000, 2000, 5000],\n        "on-connection-error": false,\n        "on-statuses": [500, 501]\n      }\n    },\n    "headers":\n    {\n      "name": "value",\n      ...\n    },\n    "body":\n    {\n      "media-type": "text/plain",\n      "content": "..."\n    }\n  }\n</pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n The method field (string) defines the HTTP verb to use in the HTTP request (i.e., GET, HEAD, OPTIONS,\n POST, PUT, DELETE). If not specified GET will be used.\n The authentication field can be used to specify the credentials and authentication method\n used when issuing a request (e.g, Basic). If the authentication field is specified, all its (string)\n subfields must be specified. If an authentication object is provided, it overrides any\n Authorization header specified in the request.\n Additionally, the following options can be specified:\n <ul>\n    <li>status-only. If true, the response body contents are omitted from the response object.</li>\n    <li>override-media-type. Is a MIME type that will override the Content-Type header returned\n        by the server. It affects the type of the result body content.</li>\n    <li>follow-redirect. Control whether an http redirect is automatically followed or not. If\n        it is false, the http redirect is returned as the response. If it is\n        true (the default) the function tries to follow the redirect, by\n        sending the same request to the new address (including body, headers,\n         and authentication credentials.) Maximum one redirect is followed\n        (there is no attempt to follow a redirect in response to following a\n          first redirect).</li>\n    <li>timeout. Is the maximum number of seconds to wait for the server to respond.\n         If no response is received withing this time duration, an error is thrown.</li>\n    <li>user-agent. The user agent sent to the server when issuing the request.\n        If not specified libcurl-agent/1.0 is used.</li>\n    <li>retry. The request will be automatically retried in case of connection error\n        following mandatory suboptions:\n        <ul>\n            <li>delay: an array specifying the milliseconds of wait before each retry.</li>\n            <li>on-connection-error: whether to retry the request if a connection to the\n                server cannot be estabilished</li>\n            <li>on-statuses: an array containing the statuses which will trigger a retry</li>\n        </ul></li>\n </ul>\n </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">One or more headers can be sent to the server, specifying them in an optional headers object.\n Each header is represented as a single (string) field. These headers are overridden if the corresponding\n option/authentication has been specified in the request.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For non-multipart request a body object can be specified.\n This object must contain both the desired (string) media-type and its content.\n The type of the content field must be either string, base64Binary, or hexBinary. </p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">For multipart requests, multipart object can be specified in place of the body object.\n The multipart object has the following structure: </p>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="java">\n  "multipart" : {\n    "boundary": "--AaB03x",\n    "parts": [\n      {\n        "headers" : {\n           "Content Disposition: file",\n           ...\n        },\n        "body": {\n          "media-type" : "image/gif",\n          "content" : "..."\n        }\n      },\n      {\n        "body" : {\n          "media-type" : "text/html",\n          "content" : "..."\n        }\n      }\n   ]\n }\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The multipart field contains an optional (string) field which specifies\n the boundary used to separate each part and an array containing all parts.\n Each part contains its specific headers, if any, and the corresponding body.\n </p>\n',summary:"<p>  \n This function sends an HTTP request and returns the corresponding response.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[{name:"request",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a JSON http-client request object</div>'}],returns:{type:"object()",description:'<a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="#standard_return">standard http-client return type</a>.'},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:HTTP An HTTP error occurred.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:REQUEST The specified request is not valid.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:TIMEOUT A timeout occurred waiting for the response.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:FOLLOW Cannot follow a redirect of a POST, PUT, or DELETE request.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">http:CHARSET The specified charset is unsupported.</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/data-cleaning/consolidation":{ns:"http://zorba.io/modules/data-cleaning/consolidation",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This library module provides data consolidation functions that generally take as input a sequence of XML nodes\n and apply some rule in order do decide which node is better suited to represent the entire sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The logic contained in this module is not specific to any particular XQuery implementation,\n although the consolidation functions based on matching sequences against XPath expressions require\n some form of dynamic evaluation for XPath expressions.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Bruno Martins</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/data-cleaning/consolidation",prefix:"con"},{uri:"http://zorba.io/modules/data-cleaning/set-similarity",prefix:"set"},{uri:"http://zorba.io/modules/data-cleaning/character-based-string-similarity",prefix:"simc"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"all-xpaths",qname:"con:all-xpaths",signature:"($s as element(*)*, $paths as xs:string*) as element(*)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the elements from an input sequence of elements that, when matched to a given set of XPath expressions,\n produce a non-empty set of nodes in all the cases.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> all-xpaths( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;c&gt;&lt;d/&gt;&lt;/c&gt;, &lt;d/&gt;), (".//b") ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> (&lt;a&gt;&lt;b/&gt;&lt;/a&gt;) </pre></p>\n',summary:"<p>  Returns the elements from an input sequence of elements that, when matched to a given set of XPath expressions,\n produce a non-empty set of nodes in all the cases.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of elements.</div>'},{name:"paths",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings denoting XPath expressions.</div>'}],returns:{type:"element(*)*",description:"The elements that, when matched to the given set of XPath expressions, always return a non-empty set of nodes."},errors:[]},{isDocumented:!0,arity:1,name:"least-attributes",qname:"con:least-attributes",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the smallest number of descending attributes (attributes at any given depth)\n in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">least-attributes( ( &lt;a att1="a1" att2="a2"/&gt;, &lt;b att1="a1" /&gt;, &lt;c/&gt; ) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">(&lt;c/&gt;)</pre></p>\n',summary:"<p>  Returns the single node having the smallest number of descending attributes (attributes at any given depth)\n in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the smallest number of descending attributes in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"least-distinct-attributes",qname:"con:least-distinct-attributes",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the smallest number of distinct descending attributes (attributes at any\n given depth) in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> least-distinct-attributes( ( &lt;a att1="a1" att2="a2"/&gt;, &lt;b att1="a1" /&gt;, &lt;c/&gt; ) ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> (&lt;c/&gt;) </pre></p>\n',summary:"<p>  Returns the single node having the smallest number of distinct descending attributes (attributes at any\n given depth) in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the smallest number of distinct descending attributes in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"least-distinct-elements",qname:"con:least-distinct-elements",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the smallest number of distinct descending elements (sub-elements at any\n given depth) in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> least-distinct-elements( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;b&gt;&lt;c/&gt;&lt;/b&gt;, &lt;d/&gt;) ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> (&lt;d/&gt;) </pre></p>\n',summary:"<p>  Returns the single node having the smallest number of distinct descending elements (sub-elements at any\n given depth) in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the smallest number of distinct descending elements in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"least-distinct-nodes",qname:"con:least-distinct-nodes",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the smallest number of distinct descending nodes (sub-nodes at any given depth)\n in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> least-distinct-nodes( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;b&gt;&lt;c/&gt;&lt;/b&gt;, &lt;d/&gt;) ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> (&lt;d/&gt;) </pre></p>\n',summary:"<p>  Returns the single node having the smallest number of distinct descending nodes (sub-nodes at any given depth)\n in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the smallest number of distinct descending nodes in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"least-elements",qname:"con:least-elements",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the smallest number of descending elements (sub-elements at any given depth)\n in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">least-elements( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;b&gt;&lt;c/&gt;&lt;/b&gt;, &lt;d/&gt;) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">(&lt;d/&gt;)</pre></p>\n',summary:"<p>  Returns the single node having the smallest number of descending elements (sub-elements at any given depth)\n in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the smallest number of descending elements in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"least-frequent",qname:"con:least-frequent",signature:"($s) as item()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single less frequent node in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">least-frequent( ( "a", "a", "b") )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">("b")</pre></p>\n',summary:"<p>  Returns the single less frequent node in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"item()",description:"The least frequent node in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"least-nodes",qname:"con:least-nodes",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the smallest number of descending nodes (sub-nodes at any given depth)\n in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">least-nodes( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;b&gt;&lt;c/&gt;&lt;/b&gt;, &lt;d/&gt;) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">(&lt;d/&gt;)</pre></p>\n',summary:"<p>  Returns the single node having the smallest number of descending nodes (sub-nodes at any given depth)\n in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the smallest number of descending nodes in the input sequence."},errors:[]},{isDocumented:!0,arity:2,name:"least-similar-edit-distance",qname:"con:least-similar-edit-distance",signature:"($s as xs:string*, $m as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single least similar string, in terms of the edit distance metric towards an input string,\n in a sequence of strings provided as input. If more than one string has a minimum similarity (a maximum\n value for the edit distance metric), return the first string according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">least-similar-edit-distance( ( "aaabbbccc", "aaabbb", "eeefff" ), "aaab" )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">( "eeefff" )</pre></p>\n',summary:"<p>  Returns the single least similar string, in terms of the edit distance metric towards an input string,\n in a sequence of strings provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings.</div>'},{name:"m",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string towards which we want to measure the edit distance.</div>'}],returns:{type:"xs:string?",description:"The least similar string in the input sequence."},errors:[]},{isDocumented:!0,arity:2,name:"least-tokens",qname:"con:least-tokens",signature:"($s as xs:string*, $r as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single shortest string, in terms of the number of tokens, in a sequence of strings provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first string according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">least-tokens( ( "a b c", "a b", "a"), " +" )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">("a")</pre></p>\n',summary:"<p>  Returns the single shortest string, in terms of the number of tokens, in a sequence of strings provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'}],returns:{type:"xs:string?",description:"The shortest string in the input sequence, in terms of the number of tokens."},errors:[]},{isDocumented:!0,arity:2,name:"least-xpaths",qname:"con:least-xpaths",signature:"($s as element(*)*, $paths as xs:string*) as element(*)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single element from an input sequence of elements that matches the smallest number of\n XPath expressions from a given set, producing a non-empty set of nodes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first element according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> least-xpaths( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;d&gt;&lt;c/&gt;&lt;b/&gt;&lt;/d&gt;, &lt;d/&gt;) , (".//b", ".//c") ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> ( $lt;d/&gt; ) </pre></p>\n',summary:"<p>  Returns the single element from an input sequence of elements that matches the smallest number of\n XPath expressions from a given set, producing a non-empty set of nodes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of elements.</div>'},{name:"paths",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings denoting XPath expressions.</div>'}],returns:{type:"element(*)*",description:"The element that matches the smallest number of XPath expressions producing a non-empty set of nodes."},errors:[]},{isDocumented:!0,arity:1,name:"longest",qname:"con:longest",signature:"($s as xs:string*) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single longest string, in terms of the number of characters, in a sequence of strings provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first string according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">con:longest( ( "a", "aa", "aaa") )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">("aaa")</pre></p>\n',summary:"<p>  Returns the single longest string, in terms of the number of characters, in a sequence of strings provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings.</div>'}],returns:{type:"xs:string?",description:"The longest string in the input sequence."},errors:[]},{isDocumented:!0,arity:2,name:"matching",qname:"con:matching",signature:"($s as xs:string*, $r as xs:string) as xs:string*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the strings from an input sequence of strings that match a particular regular expression.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">matching( ( "a A b", "c AAA d", "e BB f"), "A+" )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">( "a A b", "c AAA d")</pre></p>\n',summary:"<p>  Returns the strings from an input sequence of strings that match a particular regular expression.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The regular expression to be used in the matching.</div>'}],returns:{type:"xs:string*",description:"The strings in the input sequence that match the input regular expression."},errors:[]},{isDocumented:!0,arity:1,name:"most-attributes",qname:"con:most-attributes",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the largest number of descending attributes (attributes at any given depth)\n in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">most-attributes( ( &lt;a att1="a1" att2="a2"/&gt;, &lt;b att1="a1" /&gt;, &lt;c/&gt; ) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">(&lt;a att1="a1" att2="a2"/&gt;)</pre></p>\n',summary:"<p>  Returns the single node having the largest number of descending attributes (attributes at any given depth)\n in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the largest number of descending attributes in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"most-distinct-attributes",qname:"con:most-distinct-attributes",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the largest number of distinct descending attributes (attributes at any\n given depth) in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">most-distinct-attributes( ( &lt;a att1="a1" att2="a2" att3="a3"/&gt;, &lt;a att1="a1" att2="a2"&gt;&lt;b att2="a2" /&gt;&lt;/a&gt;, &lt;c/&gt; ) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">(&lt;a att1="a1" att2="a2" att3="a3"/&gt;)</pre></p>\n',summary:"<p>  Returns the single node having the largest number of distinct descending attributes (attributes at any\n given depth) in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the largest number of distinct descending attributes in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"most-distinct-elements",qname:"con:most-distinct-elements",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the largest number of distinct descending elements (sub-elements at any\n given depth) in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">most-distinct-elements( ( &lt;a&gt;&lt;b/&gt;&lt;c/&gt;&lt;d/&gt;&lt;/a&gt;, &lt;a&gt;&lt;b/&gt;&lt;b/&gt;&lt;c/&gt;&lt;/a&gt;, &lt;a/&gt; ) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">(&lt;a&gt;&lt;b/&gt;&lt;c/&gt;&lt;d/&gt;&lt;/a&gt;)</pre></p>\n',summary:"<p>  Returns the single node having the largest number of distinct descending elements (sub-elements at any\n given depth) in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the largest number of distinct descending elements in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"most-distinct-nodes",qname:"con:most-distinct-nodes",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the largest number of distinct descending nodes (sub-nodes at any given depth) in\n a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">most-distinct-nodes( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;a&gt;&lt;a/&gt;&lt;/a&gt;, &lt;b/&gt;) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">(&lt;a&gt;&lt;b/&gt;&lt;/a&gt;)</pre></p>\n',summary:"<p>  Returns the single node having the largest number of distinct descending nodes (sub-nodes at any given depth) in\n a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the largest number of distinct descending nodes in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"most-elements",qname:"con:most-elements",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the largest number of descending elements (sub-elements at any given depth)\n in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">most-elements( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;a/&gt;, &lt;b/&gt;) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">(&lt;a&gt;&lt;b/&gt;&lt;/a&gt;)</pre></p>\n',summary:"<p>  Returns the single node having the largest number of descending elements (sub-elements at any given depth)\n in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the largest number of descending elements in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"most-frequent",qname:"con:most-frequent",signature:"($s) as item()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single most frequent node in a sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, returns the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">most-frequent( ( "a", "a", "b") )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">("a")</pre></p>\n',summary:"<p>  Returns the single most frequent node in a sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"item()",description:"The most frequent node in the input sequence."},errors:[]},{isDocumented:!0,arity:1,name:"most-nodes",qname:"con:most-nodes",signature:"($s) as element(*)",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single node having the largest number of descending nodes (sub-nodes at any given depth) in a\n sequence of nodes provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first node according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">most-nodes( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;a/&gt;, &lt;b/&gt;) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">(&lt;a&gt;&lt;b/&gt;&lt;/a&gt;)</pre></p>\n',summary:"<p>  Returns the single node having the largest number of descending nodes (sub-nodes at any given depth) in a\n sequence of nodes provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of nodes.</div>'}],returns:{type:"element(*)",description:"The node having the largest number of descending nodes in the input sequence."},errors:[]},{isDocumented:!0,arity:2,name:"most-similar-edit-distance",qname:"con:most-similar-edit-distance",signature:"($s as xs:string*, $m as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single most similar string, in terms of the edit distance metric towards an input string,\n in a sequence of strings provided as input. If more than one string has a maximum similarity (a minimum\n value for the edit distance metric), the function return the first string according to the order of the\n input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">most-similar-edit-distance( ( "aaabbbccc", "aaabbb", "eeefff" ), "aaab" )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">( "aaabbb" )</pre></p>\n',summary:"<p>  Returns the single most similar string, in terms of the edit distance metric towards an input string,\n in a sequence of strings provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings.</div>'},{name:"m",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The string towards which we want to measure the edit distance.</div>'}],returns:{type:"xs:string?",description:"The most similar string in the input sequence."},errors:[]},{isDocumented:!0,arity:2,name:"most-tokens",qname:"con:most-tokens",signature:"($s as xs:string*, $r as xs:string) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single longest string, in terms of the number of tokens, in a sequence of strings provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first string according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">most-tokens( ( "a b c", "a b", "a"), " +" )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">("a b c")</pre></p>\n',summary:"<p>  Returns the single longest string, in terms of the number of tokens, in a sequence of strings provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings.</div>'},{name:"r",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A regular expression forming the delimiter character(s) which mark the boundaries between adjacent tokens.</div>'}],returns:{type:"xs:string?",description:"The longest string in the input sequence, in terms of the number of tokens."},errors:[]},{isDocumented:!0,arity:2,name:"most-xpaths",qname:"con:most-xpaths",signature:"($s as element(*)*, $paths as xs:string*) as element(*)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single element from an input sequence of elements that matches the largest number of\n XPath expressions from a given set, producing a non-empty set of nodes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first element according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> most-xpaths( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;d&gt;&lt;c/&gt;&lt;b/&gt;&lt;/d&gt;, &lt;d/&gt;) , (".//b", ".//c") ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> ( &lt;d&gt;&lt;c/&gt;&lt;b/&gt;&lt;/d&gt; ) </pre></p>\n',summary:"<p>  Returns the single element from an input sequence of elements that matches the largest number of\n XPath expressions from a given set, producing a non-empty set of nodes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of elements.</div>'},{name:"paths",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings denoting XPath expressions.</div>'}],returns:{type:"element(*)*",description:"The element that matches the largest number of XPath expressions producing a non-empty set of nodes."},errors:[]},{isDocumented:!0,arity:1,name:"shortest",qname:"con:shortest",signature:"($s as xs:string*) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single shortest string, in terms of the number of characters, in a sequence of strings provided as input.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, return the first string according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">shortest( ( "a", "aa", "aaa") )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">("a")</pre></p>\n',summary:"<p>  Returns the single shortest string, in terms of the number of characters, in a sequence of strings provided as input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings.</div>'}],returns:{type:"xs:string?",description:"The shortest string in the input sequence."},errors:[]},{isDocumented:!0,arity:2,name:"some-xpaths",qname:"con:some-xpaths",signature:"($s as element(*)*, $paths as xs:string*) as element(*)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the elements from a sequence of elements that, when matched to a given set of XPath expressions,\n produce a non-empty set of nodes for some of the cases.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> some-xpaths( ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt;, &lt;d&gt;&lt;c/&gt;&lt;/d&gt;, &lt;d/&gt;), (".//b", ".//c") ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> ( &lt;a&gt;&lt;b/&gt;&lt;/a&gt; , &lt;d&gt;&lt;c/&gt;&lt;/d&gt; ) </pre></p>\n',summary:"<p>  Returns the elements from a sequence of elements that, when matched to a given set of XPath expressions,\n produce a non-empty set of nodes for some of the cases.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of elements.</div>'},{name:"paths",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings denoting XPath expressions.</div>'}],returns:{type:"element(*)*",description:"The elements that, when matched to the given set of XPath expressions, return a non-empty set of nodes for at least one of the cases."},errors:[]},{isDocumented:!0,arity:1,name:"superstring",qname:"con:superstring",signature:"($s as xs:string*) as xs:string?",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the single string, from an input sequence of strings, that appears more frequently as part\n of the other strings in the sequence. If no such string exists, the function returns an empty sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">If more then one answer is possible, the function returns the first string according to the order of the input sequence.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery">super-string( ( "aaa bbb ccc", "aaa bbb", "aaa ddd", "eee fff" ) )</pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery">( "aaa bbb" )</pre></p>\n',summary:"<p>  Returns the single string, from an input sequence of strings, that appears more frequently as part\n of the other strings in the sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of strings.</div>'}],returns:{type:"xs:string?",description:"The string that appears more frequently as part of the other strings in the sequence."},errors:[]},{isDocumented:!0,arity:2,name:"validating-schema",qname:"con:validating-schema",signature:"($s as element(*)*, $schema as element(*)) as element(*)*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the nodes from an input sequence of nodes that validate against a given XML Schema.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> validating-schema ( ( &lt;a/&gt; , &lt;b/&gt; ), &lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;&lt;xs:element name="a" /&gt;&lt;/xs:schema&gt; ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> ( &lt;a/&gt; ) </pre></p>\n',summary:"<p>  Returns the nodes from an input sequence of nodes that validate against a given XML Schema.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:"element(*)",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A sequence of elements.</div>'},{name:"schema",type:"element(*)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> An element encoding an XML Schema.</div>'}],returns:{type:"element(*)*",description:'The nodes that validate against the XML Schema. <b xmlns:xqdoc="http://www.xqdoc.org/1.0"> Attention : This function is still not implemented. </b>'},errors:[]}],variables:[]},"http://zorba.io/modules/node":{ns:"http://zorba.io/modules/node",description:" This module defines a set of function which can be used\n to determine (1) the relationship between two nodes (e.g. if one\n is the ancestor if another) and (2) properties of given\n nodes (e.g. their level in the tree).\n The same functionality can be achieved with simple XPath expressions.\n However, please note that using the functions in this modules instead\n of path expressions guarantees better performance.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/node",prefix:"node"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"ancestor-of",qname:"node:ancestor-of",signature:"($node1 as node(), $node2 as node()) as xs:boolean external",description:" Determines whether the node given as second argument is an\n ancestor of the node given as first argument.\n",summary:"<p> Determines whether the node given as second argument is an\n ancestor of the node given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential descendant</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential ancestor</div>'}],returns:{type:"xs:boolean",description:"true if $node2 is an ancestor of $node1; false otherwise."},errors:[]},{isDocumented:!0,arity:2,name:"child-of",qname:"node:child-of",signature:"($node1 as node(), $node2 as node()) as xs:boolean external",description:" Determines whether the node given as second argument is a\n child of the node given as first argument.\n",summary:"<p> Determines whether the node given as second argument is a\n child of the node given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential parent</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential child</div>'}],returns:{type:"xs:boolean",description:"true if $node2 is a child of $node1; false otherwise."},errors:[]},{isDocumented:!0,arity:1,name:"copy",qname:"node:copy",signature:"($input as node()*) as node()* external",description:' Return a deep copy of every given node according to the properties\n specified in the static context of the invoking module.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Please note that a copy of a node is parentless.\n',summary:"<p> Return a deep copy of every given node according to the properties\n specified in the static context of the invoking module.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"input",type:"node()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node to copy</div>'}],returns:{type:"node()*",description:"a deep copy of every node in the input sequence or the empty sequence if $input is the empty sequence."},errors:[]},{isDocumented:!0,arity:2,name:"descendant-of",qname:"node:descendant-of",signature:"($node1 as node(), $node2 as node()) as xs:boolean external",description:" Determines whether the node given as second argument is a\n descendant of the node given as first argument.\n",summary:"<p> Determines whether the node given as second argument is a\n descendant of the node given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential ancestor</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential descendant</div>'}],returns:{type:"xs:boolean",description:"true if $node2 is a descendant of $node1; false otherwise."},errors:[]},{isDocumented:!0,arity:2,name:"following-of",qname:"node:following-of",signature:"($node1 as node(), $node2 as node()) as xs:boolean external",description:" Determines whether the node given as second argument is\n following the node given as first argument.\n",summary:"<p> Determines whether the node given as second argument is\n following the node given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding node</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following node</div>'}],returns:{type:"xs:boolean",description:"true if $node2 is following the node $node1; false otherwise."},errors:[]},{isDocumented:!0,arity:2,name:"following-sibling-of",qname:"node:following-sibling-of",signature:"($node1 as node(), $node2 as node()) as xs:boolean external",description:" Determines whether the node given as second argument is a\n following-sibling of the node given as first argument.\n",summary:"<p> Determines whether the node given as second argument is a\n following-sibling of the node given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding-sibling</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following-sibling</div>'}],returns:{type:"xs:boolean",description:"true if $node2 is a following-sibling of $node1; false otherwise."},errors:[]},{isDocumented:!0,arity:2,name:"least-common-ancestor",qname:"node:least-common-ancestor",signature:"($node1 as node(), $node2 as node()) as node()? external",description:" Computes the least common ancestor of two given nodes in\n the tree.\n",summary:"<p> Computes the least common ancestor of two given nodes in\n the tree.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the first node</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the second node</div>'}],returns:{type:"node()?",description:"the least common ancestor of the two given nodes or the empty sequence if the two nodes are not part of the same tree."},errors:[]},{isDocumented:!0,arity:1,name:"level",qname:"node:level",signature:"($node as node()) as xs:integer external",description:" Computes the level of a given node in the tree.\n Note: The first level has the number one.\n",summary:"<p> Computes the level of a given node in the tree.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the node for which the level should be computed</div>'}],returns:{type:"xs:integer",description:"The level as xs:integer of the given node in the tree."},errors:[]},{isDocumented:!0,arity:2,name:"parent-of",qname:"node:parent-of",signature:"($node1 as node(), $node2 as node()) as xs:boolean external",description:" Determines whether the node given as second argument is a\n parent of the node given as first argument.\n",summary:"<p> Determines whether the node given as second argument is a\n parent of the node given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential child</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential parent</div>'}],returns:{type:"xs:boolean",description:"true if $node2 is a parent of $node1; false otherwise."},errors:[]},{isDocumented:!0,arity:2,name:"preceding-of",qname:"node:preceding-of",signature:"($node1 as node(), $node2 as node()) as xs:boolean external",description:" Determines whether the node given as second argument is\n preceding the node given as first argument.\n",summary:"<p> Determines whether the node given as second argument is\n preceding the node given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following node</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding node</div>'}],returns:{type:"xs:boolean",description:"true if $node2 is preceding the node $node1; false otherwise."},errors:[]},{isDocumented:!0,arity:2,name:"preceding-sibling-of",qname:"node:preceding-sibling-of",signature:"($node1 as node(), $node2 as node()) as xs:boolean external",description:" Determines whether the node given as second argument is a\n preceding-sibling of the node given as first argument.\n",summary:"<p> Determines whether the node given as second argument is a\n preceding-sibling of the node given as first argument.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"node1",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential following-sibling</div>'},{name:"node2",type:"node()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the potential preceding-sibling</div>'}],returns:{type:"xs:boolean",description:"true if $node2 is a preceding-sibling of $node1; false otherwise."},errors:[]}],variables:[]},"http://zorba.io/modules/archive":{ns:"http://zorba.io/modules/archive",description:' This module provides functionality to work with (possibly compressed)\n archives. For example, it provides functions to retrieve the names or\n extract the values of several entries in a ZIP archive. Moreover,\n there exist functions that allow to create or update archives.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The following archive formats and compression algorithms are supported:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li>ZIP (with compression DEFLATE or STORE)</li>\n   <li>TAR (with compression GZIP)</li>\n </ul>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Luis Rodgriguez, Juan Zacarias, and Matthias Brantner</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/archive",prefix:"a"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"create",qname:"a:create",signature:"($entries as item()*, $contents as item()*) as xs:base64Binary external",description:' Creates a new ZIP archive out of the given entries and contents. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n All entries are compressed with the DEFLATE compression algorithm.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The parameters $entries and $contents have the same meaning as for\n the function a:create with three arguments.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Entry entries can include a type element, this element can have one\n of two possible values: "regular" or "directory". If "regular" is\n specified then the entry will be created as a regular file; if "directory"\n is specified then the entry will be created as a directory, no contents\n will be read from $contents in this case. If no value is specified for type\n then it will be set to "regular". <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Example:\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0">\n $zip-file := a:create(\n    ({ "encoding" : "ISO-8859-1", "type" : "directory", "name" : "dir1" }, "dir1/file1"),\n    ("file contents"))\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Creates a new ZIP archive out of the given entries and contents.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entries",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the meta data for the entries in the archive. Each entry can be of type xs:string or a JSON oibject describing the entry.</div>'},{name:"contents",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content for the archive. Each item in the sequence can be of type xs:string or xs:base64Binary.</div>'}],returns:{type:"xs:base64Binary",description:"the generated archive as xs:base64Binary"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:ENTRY-COUNT-MISMATCH if the number of entries that don\'t describe directories differs from the number of items in the $contents sequence: count($non-directory-entries) ne count($contents)</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:INVALID-ENTRY-VALS if a values in an entry object are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:INVALID-ENCODING if a given encoding is invalid or not supported</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FORG0006 if an item in the contents sequence is not of type xs:string or xs:base64Binary</xqdoc:error>']},{isDocumented:!0,arity:3,name:"create",qname:"a:create",signature:"($entries as item()*, $contents as item()*, $options as object()) as xs:base64Binary external",description:' Creates a new archive out of the given entries and contents. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The $entries arguments provides meta data for each entry in the archive.\n For example, the name of the entry (mandatory) or the last-modified date\n (optional). An entry can either be of type xs:string to describe the entry\n name or of type xs:base64Binary to provide additional meta data.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The $contents sequence provides the data (xs:string or xs:base64Binary) for\n the entries that should be included in the archive. Its length needs to\n match the length of the entries in the $entries sequence that don\'t describe\n directory entries (a:ARCH0001). All items of type xs:base64Binary are decoded\n before being added to the archive.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n For each entry, the name, last-modified date and time, and compression\n can be specified. In addition, an encoding can be specified which is used to\n store entries of type xs:string. If no last-modified attribute is given, the\n default is the current date and time. The compression is useful if various\n entries in a ZIP archive are compressed using different compression\n algorithms (i.e. store or deflate).<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n For example, the following sequence may be used to describe an archive\n containing two elements: <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">{\n   "last-modified" : "{fn:current-dateTime()}"\n   "name" : "myfile.txt"\n },\n {\n   "encoding" : "ISO-8859-1",\n   "compression" : "store",\n   "name" : "dir/myfile.xml"\n }\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The $options argument may be used to describe general options for the\n archive.  For example, the following options can be used to create a ZIP\n archive in which all entries are compressed with the DEFLATE compression\n algorithm: <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">{\n   "format" : "ZIP",\n   "compression" : "DEFLATE"\n }\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The result of the function is the generated archive as a item of type\n xs:base64Binary.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Creates a new archive out of the given entries and contents.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entries",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the meta data for the entries in the archive. Each entry can be of type xs:string or an JSON object describing the entry.</div>'},{name:"contents",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content for the archive. Each item in the sequence can be of type xs:string or xs:base64Binary.</div>'},{name:"options",type:"object()",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the options used to generate the archive.</div>'}],returns:{type:"xs:base64Binary",description:"the generated archive as xs:base64Binary"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:ENTRY-COUNT-MISMATCH if the number of entries describing non-directories differs from the number of items in the $contents sequence: count($non-directoy-entries) ne count($contents)</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:INVALID-OPTIONS if the options argument contains invalid values</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:INVALID-ENTRY-VALS if any values in an entry are invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:INVALID-ENCODING if a given encoding is invalid or not supported</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:DIFFERENT-COMPRESSIONS-NOT-SUPPORTED if different compression algorithms were selected but the actual version of libarchive doesn\'t support it.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FORG0006 if an item in the contents sequence is not of type xs:string or xs:base64Binary</xqdoc:error>']},{isDocumented:!0,arity:2,name:"delete",qname:"a:delete",signature:"($archive as xs:base64Binary, $entry-names as xs:string*) as xs:base64Binary external",description:' Deletes entries from an archive. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Deletes entries from an archive.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the archive to extract the entries from as xs:base64Binary</div>'},{name:"entry-names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of names for entries which should be deleted</div>'}],returns:{type:"xs:base64Binary",description:"the updated base64Binary"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:CORRUPTED-ARCHIVE if $archive is not an archive or corrupted</xqdoc:error>']},{isDocumented:!0,arity:1,name:"entries",qname:"a:entries",signature:"($archive as xs:base64Binary) as object()* external",description:' Returns the header information of all entries in the given archive as a JSON\n objects sequence. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Such information includes the name of the entry, the uncompressed size,\n as well as the last-modified timestamp. Note that not all values are\n available in every archive.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Returns the header information of all entries in the given archive as a JSON\n objects sequence.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the archive to list the entries from as xs:base64Binary</div>'}],returns:{type:"object()*",description:"a sequence of strings, one for each entry in the archive"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:CORRUPTED-ARCHIVE if $archive is not an archive or corrupted</xqdoc:error>']},{isDocumented:!0,arity:1,name:"extract-binary",qname:"a:extract-binary",signature:"($archive as xs:base64Binary) as xs:base64Binary* external",description:' Returns the entries identified by the given paths from the archive\n as base64Binary. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Returns the entries identified by the given paths from the archive\n as base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the archive to extract the entries from as xs:base64Binary</div>'}],returns:{type:"xs:base64Binary*",description:"one xs:base64Binary item for the contents of each entry in the archive"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:CORRUPTED-ARCHIVE if $archive is not an archive or corrupted</xqdoc:error>']},{isDocumented:!0,arity:2,name:"extract-binary",qname:"a:extract-binary",signature:"($archive as xs:base64Binary, $entry-names as xs:string*) as xs:base64Binary* external",description:' Returns the entries identified by the given paths from the archive\n as base64Binary. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Returns the entries identified by the given paths from the archive\n as base64Binary.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the archive to extract the entries from as xs:base64Binary</div>'},{name:"entry-names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of names for entries which should be extracted</div>'}],returns:{type:"xs:base64Binary*",description:"a sequence of xs:base64Binary itmes for the given sequence of names or the empty sequence if no entries match the given names."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:CORRUPTED-ARCHIVE if $archive is not an archive or corrupted</xqdoc:error>']},{isDocumented:!0,arity:1,name:"extract-text",qname:"a:extract-text",signature:"($archive as xs:base64Binary) as xs:string* external",description:' Extracts the contents of all entries in the given archive as text\n using UTF-8 as default encoding. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Extracts the contents of all entries in the given archive as text\n using UTF-8 as default encoding.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the archive to extract the entries from as xs:base64Binary</div>'}],returns:{type:"xs:string*",description:"one string for the contents of each entry in the archive"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:CORRUPTED-ARCHIVE if $archive is not an archive or corrupted</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FOCH0001 if any of the entries contains invalid utf-8 characters</xqdoc:error>']},{isDocumented:!0,arity:2,name:"extract-text",qname:"a:extract-text",signature:"($archive as xs:base64Binary, $entry-names as xs:string*) as xs:string* external",description:' Extracts the contets of the entries identified by a given sequence of\n names as text.\n The default encoding used to read the string is UTF-8. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Extracts the contets of the entries identified by a given sequence of\n names as text.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the archive to extract the entries from as xs:base64Binary</div>'},{name:"entry-names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of names for entries which should be extracted</div>'}],returns:{type:"xs:string*",description:"a sequence of strings for the given sequence of names or the empty sequence if no entries match the given names."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:CORRUPTED-ARCHIVE if $archive is not an archive or corrupted</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FOCH0001 if any of the entries requested contains invalid utf-8 characters</xqdoc:error>']},{isDocumented:!0,arity:3,name:"extract-text",qname:"a:extract-text",signature:"($archive as xs:base64Binary, $entry-names as xs:string*, $encoding as xs:string) as xs:string* external",description:' Extracts the contets of the entries identified by a given sequence of\n names as text. Each entry is treated with the given encoding. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Extracts the contets of the entries identified by a given sequence of\n names as text.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the archive to extract the entries from as xs:base64Binary</div>'},{name:"entry-names",type:"xs:string",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a sequence of entry names that should be extracted</div>'},{name:"encoding",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a encoding for transcoding each of the extracted entries</div>'}],returns:{type:"xs:string*",description:"a sequence of strings for the given sequence of names or the empty sequence if no entries match the given names."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:CORRUPTED-ARCHIVE if $archive is not an archive or corrupted</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:INVALID-ENCODING if the given $encoding is invalid or not supported</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FOCH0001 if a transcoding error happens</xqdoc:error>']},{isDocumented:!0,arity:1,name:"options",qname:"a:options",signature:"($archive as xs:base64Binary) as object() external",description:' Returns the algorithm and format options as a JSON object for a given archive.\n For example, for a ZIP archive, the following options element\n would be returned: <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">{\n   "format" : "ZIP",\n   "compression" : "DEFLATE"\n }\n </pre>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Returns the algorithm and format options as a JSON object for a given archive.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the archive as xs:base64Binary</div>'}],returns:{type:"object()",description:"the algorithm and format options as a JSON object"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:CORRUPTED-ARCHIVE if $archive is not an archive or corrupted</xqdoc:error>']},{isDocumented:!0,arity:3,name:"update",qname:"a:update",signature:"($archive as xs:base64Binary, $entries as item()*, $contents as item()*) as xs:base64Binary external",description:' Adds and replaces entries in an archive according to\n the given spec. The contents can be string and base64Binary items. <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n The parameters $entries and $contents have the same meaning as for\n the function a:create with three arguments.<p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> Adds and replaces entries in an archive according to\n the given spec.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"archive",type:"xs:base64Binary",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the archive to add or replace content</div>'},{name:"entries",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the meta data for the entries in the archive. Each entry can be of type xs:string or a JSON object. For mandatory fields in the JSON object see create function.</div>'},{name:"contents",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the content for the archive. Each item in the sequence can be of type xs:string or xs:base64Binary.</div>'}],returns:{type:"xs:base64Binary",description:"the updated xs:base64Binary"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:ENTRY-COUNT-MISMATCH if the number of entry elements differs from the number of items in the $contents sequence: count($non-directory-entries) ne count($contents)</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:INVALID-ENTRY-VALS if a value for an entry element is invalid</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:INVALID-ENCODING if a given encoding is invalid or not supported</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:DIFFERENT-COMPRESSIONS-NOT-SUPPORTED if different compression algorithms were selected but the actual version of libarchive doesn\'t support it.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:FORG0006 if an item in the contents sequence is not of type xs:string or xs:base64Binary</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">a:CORRUPTED-ARCHIVE if $archive is not an archive or corrupted</xqdoc:error>']}],variables:[]},"http://www.zorba-xquery.com/modules/converters/html":{ns:"http://www.zorba-xquery.com/modules/converters/html",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">\n This module provides functions to <a href="http://www.w3.org/People/Raggett/tidy/" target="_blank">tidy</a> a HTML document. <br/>\n The functions in this module take an HTML document (a string) as parameter,\n tidy it in order to result in valid XHTML, and return this XHTML document as a document-node.\n </p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Sorin Nasoi</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://ww.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://www.zorba-xquery.com/modules/converters/html",prefix:"html"},{uri:"http://www.zorba-xquery.com/modules/converters/html-options",prefix:"html-options"},{uri:"http://zorba.io/modules/schema",prefix:"schema"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"parse",qname:"html:parse",signature:"($html as xs:string) as document()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function tidies the given HTML string and returns\n a valid XHTML document node.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This functions automatically sets the following tidying parameters:\n   <ul>\n    <li>output-xml=yes</li>\n    <li>doctype=omit</li>\n    <li>quote-nbsp=no</li>\n    <li>char-encoding=utf8</li>\n    <li>newline=LF</li>\n    <li>tidy-mark=no</li>\n   </ul>\n </p>\n',summary:"<p>  This function tidies the given HTML string and returns\n a valid XHTML document node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"html",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the HTML string to tidy</div>'}],returns:{type:"document()",description:"the tidied XML document"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">html:InternalError if an internal error occurred while tidying the string.</xqdoc:error>']},{isDocumented:!0,arity:2,name:"parse",qname:"html:parse",signature:"($html as xs:string, $options as element(html-options:options)) as document()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This function tidies the given HTML string and returns\n a valid XHTML document node.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The second parameter allows to specify options that\n configure the tidy process. This parameter is a sequence\n of name=value pairs. Allowed parameter names and values\n are documented at <a href="http://tidy.sourceforge.net/docs/quickref.html">\n http://tidy.sourceforge.net/docs/quickref.html</a>.</p>\n',summary:"<p>  This function tidies the given HTML string and returns\n a valid XHTML document node.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"html",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the HTML string to tidy</div>'},{name:"options",type:"element(html-options:options)",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> a set of name and value pairs that provide options to configure the tidy process that have to be validated against the "http://www.zorba-xquery.com/modules/converters/html-options" schema.</div>'}],returns:{type:"document()",description:"the tidied XHTML document node"},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">err:XQDY0027 if $options can not be validated against the html-options schema</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">html:TidyOption if there was an error with one of the options in the $options parameter that couldn\'t have been caught by validating against the schema</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">html:InternalError if an internal error occurred while tidying the string.</xqdoc:error>']}],variables:[]},"http://zorba.io/modules/data-cleaning/set-similarity":{ns:"http://zorba.io/modules/data-cleaning/set-similarity",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This library module provides similarity functions for comparing sets of XML\n nodes (e.g., sets of XML elements, attributes or atomic values).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">These functions are particularly useful for matching near duplicate sets of XML nodes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The logic contained in this module is not specific to any particular XQuery implementation.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Bruno Martins</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/modules/data-cleaning/set-similarity",prefix:"set"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"deep-intersect",qname:"set:deep-intersect",signature:"($s1, $s2) as item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the intersection between two sets, using the deep-equal() function to compare the XML nodes from the sets.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> deep-intersect ( ( "a", "b", "c") , ( "a", "a", <d/> ) ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> ("a") </pre></p>\n',summary:"<p>  Returns the intersection between two sets, using the deep-equal() function to compare the XML nodes from the sets.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first set.</div>'},{name:"s2",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second set.</div>'}],returns:{type:"item()*",description:"The intersection of both sets."},errors:[]},{isDocumented:!0,arity:2,name:"deep-union",qname:"set:deep-union",signature:"($s1, $s2) as item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the union between two sets, using the deep-equal() function to compare the XML nodes from the sets.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> deep-union ( ( "a", "b", "c") , ( "a", "a", <d/> ) ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> ("a", "b", "c", <d/> ) </pre></p>\n',summary:"<p>  Returns the union between two sets, using the deep-equal() function to compare the XML nodes from the sets.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first set.</div>'},{name:"s2",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second set.</div>'}],returns:{type:"item()*",description:"The union of both sets."},errors:[]},{isDocumented:!0,arity:2,name:"dice",qname:"set:dice",signature:"($s1, $s2) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Dice similarity coefficient between two sets of XML nodes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The Dice coefficient is defined as defined as twice the shared information between the input sets\n (i.e., the size of the intersection) over the sum of the cardinalities for the input sets.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> dice ( ( "a", "b", <c/> ) , ( "a", "a", "d") ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.4 </pre></p>\n',summary:"<p>  Returns the Dice similarity coefficient between two sets of XML nodes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first set.</div>'},{name:"s2",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second set.</div>'}],returns:{type:"xs:double",description:"The Dice similarity coefficient between the two sets."},errors:[]},{isDocumented:!0,arity:1,name:"distinct",qname:"set:distinct",signature:"($s) as item()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Removes exact duplicates from a set, using the deep-equal() function to compare the XML nodes from the sets.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> distinct ( ( "a", "a", <b/> ) ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> ("a", <b/> ) </pre></p>\n',summary:"<p>  Removes exact duplicates from a set, using the deep-equal() function to compare the XML nodes from the sets.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> A set.</div>'}],returns:{type:"item()*",description:"The set provided as input without the exact duplicates (i.e., returns the distinct nodes from the set provided as input)."},errors:[]},{isDocumented:!0,arity:2,name:"jaccard",qname:"set:jaccard",signature:"($s1, $s2) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the Jaccard similarity coefficient between two sets of XML nodes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The Jaccard coefficient is defined as the size of the intersection divided by the size of the\n union of the input sets.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> jaccard ( ( "a", "b", <c/> ) , ( "a", "a", "d") ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 0.25 </pre></p>\n',summary:"<p>  Returns the Jaccard similarity coefficient between two sets of XML nodes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first set.</div>'},{name:"s2",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second set.</div>'}],returns:{type:"xs:double",description:"The Jaccard similarity coefficient between the two sets."},errors:[]},{isDocumented:!0,arity:2,name:"overlap",qname:"set:overlap",signature:"($s1, $s2) as xs:double",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Returns the overlap coefficient between two sets of XML nodes.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The overlap coefficient is defined as the shared information between the input sets\n (i.e., the size of the intersection) over the size of the smallest input set.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Example usage : <pre class="ace-static" ace-mode="xquery"> overlap ( ( "a", "b", <c/> ) , ( "a", "a", "b" ) ) </pre></p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">The function invocation in the example above returns : <pre class="ace-static" ace-mode="xquery"> 1.0 </pre></p>\n',summary:"<p>  Returns the overlap coefficient between two sets of XML nodes.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"s1",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The first set.</div>'},{name:"s2",type:null,occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The second set.</div>'}],returns:{type:"xs:double",description:"The overlap coefficient between the two sets."},errors:[]}],variables:[]},"http://www.28msec.com/modules/http/util/cache":{ns:"http://www.28msec.com/modules/http/util/cache",description:" This module contains a collection of convenience functions to help\n developers work with HTTP caching options.\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">28msec</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://zorba.io/annotations",prefix:"an"},{uri:"http://www.28msec.com/modules/http/util/cache",prefix:"cache"},{uri:"http://www.28msec.com/modules/http/response",prefix:"resp"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:0,name:"no-cache",qname:"cache:no-cache",signature:"() as empty-sequence()",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Forces a client not to cache the response by setting the appropriate\n HTTP headers.</p>\n In detail, the following HTTP headers will be set in the response:\n <ul xmlns:xqdoc="http://www.xqdoc.org/1.0">\n   <li><tt>Cache-Control: no-cache</tt></li>\n   <li><tt>Pragma: no-cache</tt></li>\n   <li><tt>Expires: 0</tt></li>\n </ul>\n',summary:"<p>  Forces a client not to cache the response by setting the appropriate\n HTTP headers.</p>",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"http://zorba.io/annotations",name:"sequential",value:""}],updating:!1,parameters:[],returns:{type:"empty-sequence()",description:"On success, the empty-sequence is returned"},errors:[]}],variables:[]},"http://www.zorba-xquery.com/modules/schema-tools":{ns:"http://www.zorba-xquery.com/modules/schema-tools",description:' This module provides funtionality to get sample XMLSchema from XML instances\n and sample XML instances from XMLSchema.\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://xmlbeans.apache.org/">Apache XMLBeans</a> library is used to implement\n inst2xsd and xsd2inst functions.\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n <b xmlns:xqdoc="http://www.xqdoc.org/1.0">Note:</b> Since this module has a Java library dependency a JVM required\n to be installed on the system. For Windows: jvm.dll is required on the system\n path ( usually located in "C:\\Program Files\\Java\\jre6\\bin\\client".\n',sees:['<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://xmlbeans.apache.org/</xqdoc:see>','<xqdoc:see xmlns:xqdoc="http://www.xqdoc.org/1.0">http://xmlbeans.apache.org</xqdoc:see>'],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Cezar Andrei</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.w3.org/2005/xqt-errors",prefix:"err"},{uri:"http://zorba.io/modules/schema",prefix:"schema-options"},{uri:"http://www.zorba-xquery.com/modules/schema-tools",prefix:"schema-tools"},{uri:"http://www.zorba-xquery.com/modules/schema-tools/schema-tools-options",prefix:"st-options"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"inst2xsd",qname:"schema-tools:inst2xsd",signature:"($instances as element(*)+, $options as element(st-options:inst2xsd-options)?) as document()*",description:' The inst2xsd function takes a set of sample XML instance elements as input and\n generates a set of sample XMLSchema documents that define\n the content of the given input.\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Please consult the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://xmlbeans.apache.org/">official documentation for further\n information</a>.\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Example:<pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-mode="xquery">\n  import module namespace st = "http://www.zorba-xquery.com/modules/schema-tools";\n  declare namespace sto =\n      "http://www.zorba-xquery.com/modules/schema-tools/schema-tools-options";\n  let $instances := (&lt;a&gt;&lt;b/&gt;&lt;c/&gt;&lt;/a&gt;, &lt;b/&gt;, &lt;c&gt;ccc&lt;/c&gt;)\n  let $options  :=\n     &lt;sto:inst2xsd-options xmlns:sto=\n       "http://www.zorba-xquery.com/modules/schema-tools/schema-tools-options"&gt;\n       &lt;sto:design&gt;vbd&lt;/sto:design&gt;\n       &lt;sto:simple-content-types&gt;smart&lt;/sto:simple-content-types&gt;\n       &lt;sto:use-enumeration&gt;10&lt;/sto:use-enumeration&gt;\n     &lt;/sto:inst2xsd-options&gt;\n  return\n      st:inst2xsd($instances, $options)\n </pre>\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> The inst2xsd function takes a set of sample XML instance elements as input and\n generates a set of sample XMLSchema documents that define\n the content of the given input.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"instances",type:"element(*)",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The input XML instance elements</div>'},{name:"options",type:"element(st-options:inst2xsd-options)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Options:<br/> <ul> <li>design: Choose the generated schema design<br/> - rdd: Russian Doll Design - local elements and local types<br/> - ssd: Salami Slice Design - global elements and local types<br/> - vbd (default): Venetian Blind Design - local elements and global complex types</li> <li>simple-content-types: type of leaf nodes<br/> - smart (default): try to find the right simple XMLSchema type<br/> - always-string: use xsd:string for all simple types</li> <li>use-enumeration: - when there are multiple valid values in a list<br/> - 1: never use enumeration<br/> - 2 or more (default 10): use enumeration if less than this number of occurrences - number option</li> <li>verbose: - stdout verbose info<br/> - true: - output type holder information<br/> - false (default): no output</li></ul></div>'}],returns:{type:"document()*",description:"The generated XMLSchema documents."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">schema-tools:VM001 If Zorba was unable to start the JVM.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">schema-tools:JAVA-EXCEPTION If Apache XMLBeans throws an exception.</xqdoc:error>']},{isDocumented:!0,arity:3,name:"xsd2inst",qname:"schema-tools:xsd2inst",signature:"($schemas as element(*)+, $rootElementName as xs:string, $options as element(st-options:xsd2inst-options)?) as document()",description:' The xsd2inst function takes a set of XML Schema elements as input and the\n local name of the root element and\n generates a document that represents one sample XML instance of the given\n input schemas. The local name is searched in schema global element definitions\n in the order of schemas parameter.\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Please consult the\n <a xmlns:xqdoc="http://www.xqdoc.org/1.0" href="http://xmlbeans.apache.org/">official documentation for further\n   information</a>.\n <br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n Example: <pre xmlns:xqdoc="http://www.xqdoc.org/1.0" class="ace-static" ace-static="xquery">\n  import module namespace st = "http://www.zorba-xquery.com/modules/schema-tools";\n  declare namespace sto =\n      "http://www.zorba-xquery.com/modules/schema-tools/schema-tools-options";\n  let $xsds  :=\n     ( &lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"\n           attributeFormDefault="unqualified"\n           elementFormDefault="qualified"&gt;\n         &lt;xs:element name="a" type="aType"/&gt;\n         &lt;xs:complexType name="aType"&gt;\n           &lt;xs:sequence&gt;\n             &lt;xs:element type="xs:string" name="b"/&gt;\n             &lt;xs:element type="xs:string" name="c"/&gt;\n           &lt;/xs:sequence&gt;\n         &lt;/xs:complexType&gt;\n       &lt;/xs:schema&gt; )\n  let $options :=\n    &lt;sto:xsd2inst-options xmlns:sto=\n      "http://www.zorba-xquery.com/modules/schema-tools/schema-tools-options"&gt;\n      &lt;sto:network-downloads&gt;false&lt;/sto:network-downloads&gt;\n      &lt;sto:no-pvr&gt;false&lt;/sto:no-pvr&gt;\n      &lt;sto:no-upa&gt;false&lt;/sto:no-upa&gt;\n    &lt;/sto:xsd2inst-options&gt;\n  return\n      st:xsd2inst($xsds, "a", $options)\n </pre><br xmlns:xqdoc="http://www.xqdoc.org/1.0"/>\n',summary:"<p> The xsd2inst function takes a set of XML Schema elements as input and the\n local name of the root element and\n generates a document that represents one sample XML instance of the given\n input schemas.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"schemas",type:"element(*)",occurrence:"+",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> elements representing XMLSchema definitions</div>'},{name:"rootElementName",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> The local name of the instance root element. If multiple target namespaces are used, first one found - using the sequence order - will be used.</div>'},{name:"options",type:"element(st-options:xsd2inst-options)",occurrence:"?",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> Options:<br/><ul> <li>network-downloads: boolean (default false)<br/> - true allows XMLBeans to use network when resolving schema imports and includes</li> <li>no-pvr: boolean (default false)<br/> - true to disable particle valid (restriction) rule, false otherwise</li> <li>no-upa: boolean (default false)<br/> - true to disable unique particle attribution rule, false otherwise</li></ul></div>'}],returns:{type:"document()",description:"The generated output document, representing a sample XML instance."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">schema-tools:VM001 If Zorba was unable to start the JVM.</xqdoc:error>','<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">schema-tools:JAVA-EXCEPTION If Apache XMLBeans throws an exception.</xqdoc:error>']}],variables:[]},"http://xbrl.io/modules/bizql/entities":{ns:"http://xbrl.io/modules/bizql/entities",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">This module provides functions for retrieving information about entities.\n Entities submit archives (see archives module),\n for example, to a reporting authority. Entities\n are identified with an EID (Entity ID).</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">With this module, you can retrieve all entities, or a certain number of entities\n with their EIDs, or obtain the EID of entities you already have.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Entities are stored in a MongoDB datasource called <b>xbrl</b>.</p>\n <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Each entity can be associated with a set of tags that makes it easier\n to manage them. The e:entities#1 function\n allows to retrieve all entities with a given tag.</p>\n',sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Charles Hoffman</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Matthias Brantner</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Dennis Knochenwefel</xqdoc:author>','<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">Ghislain Fourny</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.28msec.com/modules/credentials",prefix:"credentials"},{uri:"http://xbrl.io/modules/bizql/entities",prefix:"entities"},{uri:"http://www.28msec.com/modules/mongodb",prefix:"mongo"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:1,name:"eid",qname:"entities:eid",signature:"($entities-or-ids as item()*) as atomic*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Converts the input to a normalized entity identifier (EID). The input\n can be either an EID, or an entity object which contains an _id.</p>\n',summary:"<p>  Converts the input to a normalized entity identifier (EID).</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entities-or-ids",type:"item()",occurrence:"*",description:""}],returns:{type:"atomic*",description:"the normalized EIDs."},errors:['<xqdoc:error xmlns:xqdoc="http://www.xqdoc.org/1.0">entities:INVALID_PARAMETER if the EID or entity is not valid.</xqdoc:error>']},{isDocumented:!0,arity:0,name:"entities",qname:"entities:entities",signature:"() as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return all entities.</p>\n',summary:"<p>  Return all entities.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[],returns:{type:"object()*",description:"all entities."},errors:[]},{isDocumented:!0,arity:1,name:"entities",qname:"entities:entities",signature:"($entities-or-ids as item()*) as object()*",description:' <p xmlns:xqdoc="http://www.xqdoc.org/1.0">Return the entities with the given EIDs.</p>\n',summary:"<p>  Return the entities with the given EIDs.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entities-or-ids",type:"item()",occurrence:"*",description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the ids of the entities (EIDs) or the entities themselves.</div>'}],returns:{type:"object()*",description:"the entities with the given EIDs the empty sequence if no entity was found or if the input is an empty sequence."},errors:[]}],variables:[{name:"entities:col",type:"string",description:" Name of the collection the entities are stored in.\n"}]},"http://www.zorba-xquery.com/modules/cryptography/hmac":{ns:"http://www.zorba-xquery.com/modules/cryptography/hmac",description:" This module provides a function to generate hash-based\n message authentication codes (HMAC) involving a cryptographic\n hash function (e.g. SHA1).\n",sees:[],authors:['<xqdoc:author xmlns:xqdoc="http://www.xqdoc.org/1.0">William Candillon</xqdoc:author>'],version:null,encoding:"utf-8",namespaces:[{uri:"http://www.zorba-xquery.com/modules/cryptography/hmac",prefix:"hmac"},{uri:"http://zorba.io/options/versioning",prefix:"ver"}],functions:[{isDocumented:!0,arity:2,name:"sha1",qname:"hmac:sha1",signature:"($message as xs:string, $secret-key as xs:string) as xs:string external",description:" This function provides hash-based message authentication code using\n the SHA1 algorithm.\n",summary:"<p> This function provides hash-based message authentication code using\n the SHA1 algorithm.</p>",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"message",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the message to be authenticated</div>'},{name:"secret-key",type:"xs:string",occurrence:null,description:'<div xmlns:xqdoc="http://www.xqdoc.org/1.0"> the secret key used for calculating the authentication</div>'}],returns:{type:"xs:string",description:"hash-based base64 encoded message authentication code"},errors:[]}],variables:[]},"http://api.28.io/csvview":{ns:"http://api.28.io/csvview",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"",prefix:"an"},{uri:"http://api.28.io/csvview",prefix:"csvview"},{uri:"http://api.28.io/model",prefix:"model"}],functions:[{isDocumented:!1,arity:1,name:"column",qname:"csvview:column",signature:"($data) as xs:string",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"data",type:null,occurrence:null,description:""}],returns:{type:"xs:string",description:""},errors:[]},{isDocumented:!1,arity:1,name:"line",qname:"csvview:line",signature:"($entries as xs:string*)",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"entries",type:"xs:string",occurrence:"*",description:""}],returns:{type:null,description:""},errors:[]},{isDocumented:!1,arity:2,name:"show-nodes",qname:"csvview:show-nodes",signature:"($nodes, $show-headers as xs:boolean)",description:"",summary:"",annotation_str:" %an:sequential",annotations:[{prefix:"an",ns:"",name:"sequential",value:""}],updating:!1,parameters:[{name:"nodes",type:null,occurrence:null,description:""},{name:"show-headers",type:"xs:boolean",occurrence:null,description:""}],returns:{type:null,description:""},errors:[]}],variables:[]},"http://api.28.io/util":{ns:"http://api.28.io/util",description:"",sees:[],authors:[],version:null,encoding:null,namespaces:[{uri:"http://www.28msec.com/modules/http/request",prefix:"req"},{uri:"http://api.28.io/util",prefix:"util"}],functions:[{isDocumented:!1,arity:1,name:"param-or-body",qname:"util:param-or-body",signature:"($param-name as xs:string) as xs:string?",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"param-name",type:"xs:string",occurrence:null,description:""}],returns:{type:"xs:string?",description:""},errors:[]},{isDocumented:!1,arity:1,name:"path",qname:"util:path",signature:"($from as xs:integer) as xs:string*",description:"",summary:"",annotation_str:"",annotations:[],updating:!1,parameters:[{name:"from",type:"xs:integer",occurrence:null,description:""}],returns:{type:"xs:string*",description:""},errors:[]}],variables:[{name:"util:collection-namespace",type:"item()*",description:""}]}}}),ace.define("ace/mode/xquery_worker",["require","exports","module","ace/lib/oop","ace/worker/mirror","ace/mode/xquery/xqlint","ace/mode/xquery/modules"],function(e,t,n){"use strict";var r=e("../lib/oop"),i=e("../worker/mirror").Mirror,s=e("./xquery/xqlint"),o=s.XQLint,u=e("./xquery/modules").Modules,a=function(e){return function(t){var n=e,r=n[t],i={},s={};return r.functions.forEach(function(e){s[t+"#"+e.name+"#"+e.arity]={params:[]},e.parameters.forEach(function(n){s[t+"#"+e.name+"#"+e.arity].params.push("$"+n.name)})}),r.variables.forEach(function(e){var n=e.name.substring(e.name.indexOf(":")+1);i[t+"#"+n]={type:"VarDecl",annotations:[]}}),{variables:i,functions:s}}},f=t.XQueryWorker=function(e){i.call(this,e),this.setTimeout(200),this.opts={styleCheck:!1},this.availableModuleNamespaces=Object.keys(u),this.moduleResolver=a(u);var t=this;this.sender.on("complete",function(e){if(t.xqlint){var n={line:e.data.pos.row,col:e.data.pos.column},r=t.xqlint.getCompletions(n);t.sender.emit("complete",r)}}),this.sender.on("setAvailableModuleNamespaces",function(e){t.availableModuleNamespaces=e.data}),this.sender.on("setModuleResolver",function(e){t.moduleResolver=a(e.data)})};r.inherits(f,i),function(){this.onUpdate=function(){this.sender.emit("start");var e=this.doc.getValue(),t=s.createStaticContext();this.moduleResolver&&t.setModuleResolver(this.moduleResolver),this.availableModuleNamespaces&&(t.availableModuleNamespaces=this.availableModuleNamespaces);var n={styleCheck:this.styleCheck,staticContext:t};this.xqlint=new o(e,n),this.sender.emit("markers",this.xqlint.getMarkers())}}.call(f.prototype)}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(e,t,n){function r(){}function w(e){try{return Object.defineProperty(e,"sentinel",{}),"sentinel"in e}catch(t){}}function H(e){return e=+e,e!==e?e=0:e!==0&&e!==1/0&&e!==-1/0&&(e=(e>0||-1)*Math.floor(Math.abs(e))),e}function B(e){var t=typeof e;return e===null||t==="undefined"||t==="boolean"||t==="number"||t==="string"}function j(e){var t,n,r;if(B(e))return e;n=e.valueOf;if(typeof n=="function"){t=n.call(e);if(B(t))return t}r=e.toString;if(typeof r=="function"){t=r.call(e);if(B(t))return t}throw new TypeError}Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if(typeof n!="function")throw new TypeError("Function.prototype.bind called on incompatible "+n);var i=u.call(arguments,1),s=function(){if(this instanceof s){var e=n.apply(this,i.concat(u.call(arguments)));return Object(e)===e?e:this}return n.apply(t,i.concat(u.call(arguments)))};return n.prototype&&(r.prototype=n.prototype,s.prototype=new r,r.prototype=null),s});var i=Function.prototype.call,s=Array.prototype,o=Object.prototype,u=s.slice,a=i.bind(o.toString),f=i.bind(o.hasOwnProperty),l,c,h,p,d;if(d=f(o,"__defineGetter__"))l=i.bind(o.__defineGetter__),c=i.bind(o.__defineSetter__),h=i.bind(o.__lookupGetter__),p=i.bind(o.__lookupSetter__);if([1,2].splice(0).length!=2)if(!function(){function e(e){var t=new Array(e+2);return t[0]=t[1]=0,t}var t=[],n;t.splice.apply(t,e(20)),t.splice.apply(t,e(26)),n=t.length,t.splice(5,0,"XXX"),n+1==t.length;if(n+1==t.length)return!0}())Array.prototype.splice=function(e,t){var n=this.length;e>0?e>n&&(e=n):e==void 0?e=0:e<0&&(e=Math.max(n+e,0)),e+t<n||(t=n-e);var r=this.slice(e,e+t),i=u.call(arguments,2),s=i.length;if(e===n)s&&this.push.apply(this,i);else{var o=Math.min(t,n-e),a=e+o,f=a+s-o,l=n-a,c=n-o;if(f<a)for(var h=0;h<l;++h)this[f+h]=this[a+h];else if(f>a)for(h=l;h--;)this[f+h]=this[a+h];if(s&&e===c)this.length=c,this.push.apply(this,i);else{this.length=c+s;for(h=0;h<s;++h)this[e+h]=i[h]}}return r};else{var v=Array.prototype.splice;Array.prototype.splice=function(e,t){return arguments.length?v.apply(this,[e===void 0?0:e,t===void 0?this.length-e:t].concat(u.call(arguments,2))):[]}}Array.isArray||(Array.isArray=function(t){return a(t)=="[object Array]"});var m=Object("a"),g=m[0]!="a"||!(0 in m);Array.prototype.forEach||(Array.prototype.forEach=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=arguments[1],s=-1,o=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError;while(++s<o)s in r&&t.call(i,r[s],s,n)}),Array.prototype.map||(Array.prototype.map=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=Array(i),o=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var u=0;u<i;u++)u in r&&(s[u]=t.call(o,r[u],u,n));return s}),Array.prototype.filter||(Array.prototype.filter=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=[],o,u=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var f=0;f<i;f++)f in r&&(o=r[f],t.call(u,o,f,n)&&s.push(o));return s}),Array.prototype.every||(Array.prototype.every=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&!t.call(s,r[o],o,n))return!1;return!0}),Array.prototype.some||(Array.prototype.some=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0,s=arguments[1];if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");for(var o=0;o<i;o++)if(o in r&&t.call(s,r[o],o,n))return!0;return!1}),Array.prototype.reduce||(Array.prototype.reduce=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var s=0,o;if(arguments.length>=2)o=arguments[1];else do{if(s in r){o=r[s++];break}if(++s>=i)throw new TypeError("reduce of empty array with no initial value")}while(!0);for(;s<i;s++)s in r&&(o=t.call(void 0,o,r[s],s,n));return o}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(t){var n=F(this),r=g&&a(this)=="[object String]"?this.split(""):n,i=r.length>>>0;if(a(t)!="[object Function]")throw new TypeError(t+" is not a function");if(!i&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var s,o=i-1;if(arguments.length>=2)s=arguments[1];else do{if(o in r){s=r[o--];break}if(--o<0)throw new TypeError("reduceRight of empty array with no initial value")}while(!0);do o in this&&(s=t.call(void 0,s,r[o],o,n));while(o--);return s});if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1)Array.prototype.indexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=0;arguments.length>1&&(i=H(arguments[1])),i=i>=0?i:Math.max(0,r+i);for(;i<r;i++)if(i in n&&n[i]===t)return i;return-1};if(!Array.prototype.lastIndexOf||[0,1].lastIndexOf(0,-3)!=-1)Array.prototype.lastIndexOf=function(t){var n=g&&a(this)=="[object String]"?this.split(""):F(this),r=n.length>>>0;if(!r)return-1;var i=r-1;arguments.length>1&&(i=Math.min(i,H(arguments[1]))),i=i>=0?i:r-Math.abs(i);for(;i>=0;i--)if(i in n&&t===n[i])return i;return-1};Object.getPrototypeOf||(Object.getPrototypeOf=function(t){return t.__proto__||(t.constructor?t.constructor.prototype:o)});if(!Object.getOwnPropertyDescriptor){var y="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(t,n){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(y+t);if(!f(t,n))return;var r,i,s;r={enumerable:!0,configurable:!0};if(d){var u=t.__proto__;t.__proto__=o;var i=h(t,n),s=p(t,n);t.__proto__=u;if(i||s)return i&&(r.get=i),s&&(r.set=s),r}return r.value=t[n],r}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(t){return Object.keys(t)});if(!Object.create){var b;Object.prototype.__proto__===null?b=function(){return{__proto__:null}}:b=function(){var e={};for(var t in e)e[t]=null;return e.constructor=e.hasOwnProperty=e.propertyIsEnumerable=e.isPrototypeOf=e.toLocaleString=e.toString=e.valueOf=e.__proto__=null,e},Object.create=function(t,n){var r;if(t===null)r=b();else{if(typeof t!="object")throw new TypeError("typeof prototype["+typeof t+"] != 'object'");var i=function(){};i.prototype=t,r=new i,r.__proto__=t}return n!==void 0&&Object.defineProperties(r,n),r}}if(Object.defineProperty){var E=w({}),S=typeof document=="undefined"||w(document.createElement("div"));if(!E||!S)var x=Object.defineProperty}if(!Object.defineProperty||x){var T="Property description must be an object: ",N="Object.defineProperty called on non-object: ",C="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(t,n,r){if(typeof t!="object"&&typeof t!="function"||t===null)throw new TypeError(N+t);if(typeof r!="object"&&typeof r!="function"||r===null)throw new TypeError(T+r);if(x)try{return x.call(Object,t,n,r)}catch(i){}if(f(r,"value"))if(d&&(h(t,n)||p(t,n))){var s=t.__proto__;t.__proto__=o,delete t[n],t[n]=r.value,t.__proto__=s}else t[n]=r.value;else{if(!d)throw new TypeError(C);f(r,"get")&&l(t,n,r.get),f(r,"set")&&c(t,n,r.set)}return t}}Object.defineProperties||(Object.defineProperties=function(t,n){for(var r in n)f(n,r)&&Object.defineProperty(t,r,n[r]);return t}),Object.seal||(Object.seal=function(t){return t}),Object.freeze||(Object.freeze=function(t){return t});try{Object.freeze(function(){})}catch(k){Object.freeze=function(t){return function(n){return typeof n=="function"?n:t(n)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(t){return t}),Object.isSealed||(Object.isSealed=function(t){return!1}),Object.isFrozen||(Object.isFrozen=function(t){return!1}),Object.isExtensible||(Object.isExtensible=function(t){if(Object(t)===t)throw new TypeError;var n="";while(f(t,n))n+="?";t[n]=!0;var r=f(t,n);return delete t[n],r});if(!Object.keys){var L=!0,A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],O=A.length;for(var M in{toString:null})L=!1;Object.keys=function I(e){if(typeof e!="object"&&typeof e!="function"||e===null)throw new TypeError("Object.keys called on a non-object");var I=[];for(var t in e)f(e,t)&&I.push(t);if(L)for(var n=0,r=O;n<r;n++){var i=A[n];f(e,i)&&I.push(i)}return I}}Date.now||(Date.now=function(){return(new Date).getTime()});var _="	\n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";if(!String.prototype.trim||_.trim()){_="["+_+"]";var D=new RegExp("^"+_+_+"*"),P=new RegExp(_+_+"*$");String.prototype.trim=function(){return String(this).replace(D,"").replace(P,"")}}var F=function(e){if(e==null)throw new TypeError("can't convert "+e+" to object");return Object(e)}})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace/ace.js b/dist/assets/js/vendor/ace/ace.js
            new file mode 100644
            index 0000000000..9beffbf823
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace/ace.js
            @@ -0,0 +1,18095 @@
            +/* ***** BEGIN LICENSE BLOCK *****
            + * Distributed under the BSD license:
            + *
            + * Copyright (c) 2010, Ajax.org B.V.
            + * All rights reserved.
            + * 
            + * Redistribution and use in source and binary forms, with or without
            + * modification, are permitted provided that the following conditions are met:
            + *     * Redistributions of source code must retain the above copyright
            + *       notice, this list of conditions and the following disclaimer.
            + *     * Redistributions in binary form must reproduce the above copyright
            + *       notice, this list of conditions and the following disclaimer in the
            + *       documentation and/or other materials provided with the distribution.
            + *     * Neither the name of Ajax.org B.V. nor the
            + *       names of its contributors may be used to endorse or promote products
            + *       derived from this software without specific prior written permission.
            + * 
            + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
            + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
            + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
            + * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
            + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
            + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
            + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
            + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
            + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
            + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
            + *
            + * ***** END LICENSE BLOCK ***** */
            +
            +/**
            + * Define a module along with a payload
            + * @param module a name for the payload
            + * @param payload a function to call with (require, exports, module) params
            + */
            +
            +(function() {
            +
            +var ACE_NAMESPACE = "";
            +
            +var global = (function() {
            +    return this;
            +})();
            +
            +
            +if (!ACE_NAMESPACE && typeof requirejs !== "undefined")
            +    return;
            +
            +
            +var _define = function(module, deps, payload) {
            +    if (typeof module !== 'string') {
            +        if (_define.original)
            +            _define.original.apply(window, arguments);
            +        else {
            +            console.error('dropping module because define wasn\'t a string.');
            +            console.trace();
            +        }
            +        return;
            +    }
            +
            +    if (arguments.length == 2)
            +        payload = deps;
            +
            +    if (!_define.modules) {
            +        _define.modules = {};
            +        _define.payloads = {};
            +    }
            +    
            +    _define.payloads[module] = payload;
            +    _define.modules[module] = null;
            +};
            +
            +/**
            + * Get at functionality define()ed using the function above
            + */
            +var _require = function(parentId, module, callback) {
            +    if (Object.prototype.toString.call(module) === "[object Array]") {
            +        var params = [];
            +        for (var i = 0, l = module.length; i < l; ++i) {
            +            var dep = lookup(parentId, module[i]);
            +            if (!dep && _require.original)
            +                return _require.original.apply(window, arguments);
            +            params.push(dep);
            +        }
            +        if (callback) {
            +            callback.apply(null, params);
            +        }
            +    }
            +    else if (typeof module === 'string') {
            +        var payload = lookup(parentId, module);
            +        if (!payload && _require.original)
            +            return _require.original.apply(window, arguments);
            +
            +        if (callback) {
            +            callback();
            +        }
            +
            +        return payload;
            +    }
            +    else {
            +        if (_require.original)
            +            return _require.original.apply(window, arguments);
            +    }
            +};
            +
            +var normalizeModule = function(parentId, moduleName) {
            +    // normalize plugin requires
            +    if (moduleName.indexOf("!") !== -1) {
            +        var chunks = moduleName.split("!");
            +        return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
            +    }
            +    // normalize relative requires
            +    if (moduleName.charAt(0) == ".") {
            +        var base = parentId.split("/").slice(0, -1).join("/");
            +        moduleName = base + "/" + moduleName;
            +
            +        while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
            +            var previous = moduleName;
            +            moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
            +        }
            +    }
            +
            +    return moduleName;
            +};
            +
            +/**
            + * Internal function to lookup moduleNames and resolve them by calling the
            + * definition function if needed.
            + */
            +var lookup = function(parentId, moduleName) {
            +
            +    moduleName = normalizeModule(parentId, moduleName);
            +
            +    var module = _define.modules[moduleName];
            +    if (!module) {
            +        module = _define.payloads[moduleName];
            +        if (typeof module === 'function') {
            +            var exports = {};
            +            var mod = {
            +                id: moduleName,
            +                uri: '',
            +                exports: exports,
            +                packaged: true
            +            };
            +
            +            var req = function(module, callback) {
            +                return _require(moduleName, module, callback);
            +            };
            +
            +            var returnValue = module(req, exports, mod);
            +            exports = returnValue || mod.exports;
            +            _define.modules[moduleName] = exports;
            +            delete _define.payloads[moduleName];
            +        }
            +        module = _define.modules[moduleName] = exports || module;
            +    }
            +    return module;
            +};
            +
            +function exportAce(ns) {
            +    var require = function(module, callback) {
            +        return _require("", module, callback);
            +    };    
            +
            +    var root = global;
            +    if (ns) {
            +        if (!global[ns])
            +            global[ns] = {};
            +        root = global[ns];
            +    }
            +
            +    if (!root.define || !root.define.packaged) {
            +        _define.original = root.define;
            +        root.define = _define;
            +        root.define.packaged = true;
            +    }
            +
            +    if (!root.require || !root.require.packaged) {
            +        _require.original = root.require;
            +        root.require = require;
            +        root.require.packaged = true;
            +    }
            +}
            +
            +exportAce(ACE_NAMESPACE);
            +
            +})();
            +
            +define("ace/lib/regexp",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +
            +    var real = {
            +            exec: RegExp.prototype.exec,
            +            test: RegExp.prototype.test,
            +            match: String.prototype.match,
            +            replace: String.prototype.replace,
            +            split: String.prototype.split
            +        },
            +        compliantExecNpcg = real.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups
            +        compliantLastIndexIncrement = function () {
            +            var x = /^/g;
            +            real.test.call(x, "");
            +            return !x.lastIndex;
            +        }();
            +
            +    if (compliantLastIndexIncrement && compliantExecNpcg)
            +        return;
            +    RegExp.prototype.exec = function (str) {
            +        var match = real.exec.apply(this, arguments),
            +            name, r2;
            +        if ( typeof(str) == 'string' && match) {
            +            if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
            +                r2 = RegExp(this.source, real.replace.call(getNativeFlags(this), "g", ""));
            +                real.replace.call(str.slice(match.index), r2, function () {
            +                    for (var i = 1; i < arguments.length - 2; i++) {
            +                        if (arguments[i] === undefined)
            +                            match[i] = undefined;
            +                    }
            +                });
            +            }
            +            if (this._xregexp && this._xregexp.captureNames) {
            +                for (var i = 1; i < match.length; i++) {
            +                    name = this._xregexp.captureNames[i - 1];
            +                    if (name)
            +                       match[name] = match[i];
            +                }
            +            }
            +            if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))
            +                this.lastIndex--;
            +        }
            +        return match;
            +    };
            +    if (!compliantLastIndexIncrement) {
            +        RegExp.prototype.test = function (str) {
            +            var match = real.exec.call(this, str);
            +            if (match && this.global && !match[0].length && (this.lastIndex > match.index))
            +                this.lastIndex--;
            +            return !!match;
            +        };
            +    }
            +
            +    function getNativeFlags (regex) {
            +        return (regex.global     ? "g" : "") +
            +               (regex.ignoreCase ? "i" : "") +
            +               (regex.multiline  ? "m" : "") +
            +               (regex.extended   ? "x" : "") + // Proposed for ES4; included in AS3
            +               (regex.sticky     ? "y" : "");
            +    }
            +
            +    function indexOf (array, item, from) {
            +        if (Array.prototype.indexOf) // Use the native array method if available
            +            return array.indexOf(item, from);
            +        for (var i = from || 0; i < array.length; i++) {
            +            if (array[i] === item)
            +                return i;
            +        }
            +        return -1;
            +    }
            +
            +});
            +
            +define("ace/lib/es5-shim",["require","exports","module"], function(require, exports, module) {
            +
            +function Empty() {}
            +
            +if (!Function.prototype.bind) {
            +    Function.prototype.bind = function bind(that) { // .length is 1
            +        var target = this;
            +        if (typeof target != "function") {
            +            throw new TypeError("Function.prototype.bind called on incompatible " + target);
            +        }
            +        var args = slice.call(arguments, 1); // for normal call
            +        var bound = function () {
            +
            +            if (this instanceof bound) {
            +
            +                var result = target.apply(
            +                    this,
            +                    args.concat(slice.call(arguments))
            +                );
            +                if (Object(result) === result) {
            +                    return result;
            +                }
            +                return this;
            +
            +            } else {
            +                return target.apply(
            +                    that,
            +                    args.concat(slice.call(arguments))
            +                );
            +
            +            }
            +
            +        };
            +        if(target.prototype) {
            +            Empty.prototype = target.prototype;
            +            bound.prototype = new Empty();
            +            Empty.prototype = null;
            +        }
            +        return bound;
            +    };
            +}
            +var call = Function.prototype.call;
            +var prototypeOfArray = Array.prototype;
            +var prototypeOfObject = Object.prototype;
            +var slice = prototypeOfArray.slice;
            +var _toString = call.bind(prototypeOfObject.toString);
            +var owns = call.bind(prototypeOfObject.hasOwnProperty);
            +var defineGetter;
            +var defineSetter;
            +var lookupGetter;
            +var lookupSetter;
            +var supportsAccessors;
            +if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
            +    defineGetter = call.bind(prototypeOfObject.__defineGetter__);
            +    defineSetter = call.bind(prototypeOfObject.__defineSetter__);
            +    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
            +    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
            +}
            +if ([1,2].splice(0).length != 2) {
            +    if(function() { // test IE < 9 to splice bug - see issue #138
            +        function makeArray(l) {
            +            var a = new Array(l+2);
            +            a[0] = a[1] = 0;
            +            return a;
            +        }
            +        var array = [], lengthBefore;
            +        
            +        array.splice.apply(array, makeArray(20));
            +        array.splice.apply(array, makeArray(26));
            +
            +        lengthBefore = array.length; //46
            +        array.splice(5, 0, "XXX"); // add one element
            +
            +        lengthBefore + 1 == array.length
            +
            +        if (lengthBefore + 1 == array.length) {
            +            return true;// has right splice implementation without bugs
            +        }
            +    }()) {//IE 6/7
            +        var array_splice = Array.prototype.splice;
            +        Array.prototype.splice = function(start, deleteCount) {
            +            if (!arguments.length) {
            +                return [];
            +            } else {
            +                return array_splice.apply(this, [
            +                    start === void 0 ? 0 : start,
            +                    deleteCount === void 0 ? (this.length - start) : deleteCount
            +                ].concat(slice.call(arguments, 2)))
            +            }
            +        };
            +    } else {//IE8
            +        Array.prototype.splice = function(pos, removeCount){
            +            var length = this.length;
            +            if (pos > 0) {
            +                if (pos > length)
            +                    pos = length;
            +            } else if (pos == void 0) {
            +                pos = 0;
            +            } else if (pos < 0) {
            +                pos = Math.max(length + pos, 0);
            +            }
            +
            +            if (!(pos+removeCount < length))
            +                removeCount = length - pos;
            +
            +            var removed = this.slice(pos, pos+removeCount);
            +            var insert = slice.call(arguments, 2);
            +            var add = insert.length;            
            +            if (pos === length) {
            +                if (add) {
            +                    this.push.apply(this, insert);
            +                }
            +            } else {
            +                var remove = Math.min(removeCount, length - pos);
            +                var tailOldPos = pos + remove;
            +                var tailNewPos = tailOldPos + add - remove;
            +                var tailCount = length - tailOldPos;
            +                var lengthAfterRemove = length - remove;
            +
            +                if (tailNewPos < tailOldPos) { // case A
            +                    for (var i = 0; i < tailCount; ++i) {
            +                        this[tailNewPos+i] = this[tailOldPos+i];
            +                    }
            +                } else if (tailNewPos > tailOldPos) { // case B
            +                    for (i = tailCount; i--; ) {
            +                        this[tailNewPos+i] = this[tailOldPos+i];
            +                    }
            +                } // else, add == remove (nothing to do)
            +
            +                if (add && pos === lengthAfterRemove) {
            +                    this.length = lengthAfterRemove; // truncate array
            +                    this.push.apply(this, insert);
            +                } else {
            +                    this.length = lengthAfterRemove + add; // reserves space
            +                    for (i = 0; i < add; ++i) {
            +                        this[pos+i] = insert[i];
            +                    }
            +                }
            +            }
            +            return removed;
            +        };
            +    }
            +}
            +if (!Array.isArray) {
            +    Array.isArray = function isArray(obj) {
            +        return _toString(obj) == "[object Array]";
            +    };
            +}
            +var boxedString = Object("a"),
            +    splitString = boxedString[0] != "a" || !(0 in boxedString);
            +
            +if (!Array.prototype.forEach) {
            +    Array.prototype.forEach = function forEach(fun /*, thisp*/) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            thisp = arguments[1],
            +            i = -1,
            +            length = self.length >>> 0;
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(); // TODO message
            +        }
            +
            +        while (++i < length) {
            +            if (i in self) {
            +                fun.call(thisp, self[i], i, object);
            +            }
            +        }
            +    };
            +}
            +if (!Array.prototype.map) {
            +    Array.prototype.map = function map(fun /*, thisp*/) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0,
            +            result = Array(length),
            +            thisp = arguments[1];
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +
            +        for (var i = 0; i < length; i++) {
            +            if (i in self)
            +                result[i] = fun.call(thisp, self[i], i, object);
            +        }
            +        return result;
            +    };
            +}
            +if (!Array.prototype.filter) {
            +    Array.prototype.filter = function filter(fun /*, thisp */) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                    object,
            +            length = self.length >>> 0,
            +            result = [],
            +            value,
            +            thisp = arguments[1];
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +
            +        for (var i = 0; i < length; i++) {
            +            if (i in self) {
            +                value = self[i];
            +                if (fun.call(thisp, value, i, object)) {
            +                    result.push(value);
            +                }
            +            }
            +        }
            +        return result;
            +    };
            +}
            +if (!Array.prototype.every) {
            +    Array.prototype.every = function every(fun /*, thisp */) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0,
            +            thisp = arguments[1];
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +
            +        for (var i = 0; i < length; i++) {
            +            if (i in self && !fun.call(thisp, self[i], i, object)) {
            +                return false;
            +            }
            +        }
            +        return true;
            +    };
            +}
            +if (!Array.prototype.some) {
            +    Array.prototype.some = function some(fun /*, thisp */) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0,
            +            thisp = arguments[1];
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +
            +        for (var i = 0; i < length; i++) {
            +            if (i in self && fun.call(thisp, self[i], i, object)) {
            +                return true;
            +            }
            +        }
            +        return false;
            +    };
            +}
            +if (!Array.prototype.reduce) {
            +    Array.prototype.reduce = function reduce(fun /*, initial*/) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0;
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +        if (!length && arguments.length == 1) {
            +            throw new TypeError("reduce of empty array with no initial value");
            +        }
            +
            +        var i = 0;
            +        var result;
            +        if (arguments.length >= 2) {
            +            result = arguments[1];
            +        } else {
            +            do {
            +                if (i in self) {
            +                    result = self[i++];
            +                    break;
            +                }
            +                if (++i >= length) {
            +                    throw new TypeError("reduce of empty array with no initial value");
            +                }
            +            } while (true);
            +        }
            +
            +        for (; i < length; i++) {
            +            if (i in self) {
            +                result = fun.call(void 0, result, self[i], i, object);
            +            }
            +        }
            +
            +        return result;
            +    };
            +}
            +if (!Array.prototype.reduceRight) {
            +    Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0;
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +        if (!length && arguments.length == 1) {
            +            throw new TypeError("reduceRight of empty array with no initial value");
            +        }
            +
            +        var result, i = length - 1;
            +        if (arguments.length >= 2) {
            +            result = arguments[1];
            +        } else {
            +            do {
            +                if (i in self) {
            +                    result = self[i--];
            +                    break;
            +                }
            +                if (--i < 0) {
            +                    throw new TypeError("reduceRight of empty array with no initial value");
            +                }
            +            } while (true);
            +        }
            +
            +        do {
            +            if (i in this) {
            +                result = fun.call(void 0, result, self[i], i, object);
            +            }
            +        } while (i--);
            +
            +        return result;
            +    };
            +}
            +if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
            +    Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
            +        var self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                toObject(this),
            +            length = self.length >>> 0;
            +
            +        if (!length) {
            +            return -1;
            +        }
            +
            +        var i = 0;
            +        if (arguments.length > 1) {
            +            i = toInteger(arguments[1]);
            +        }
            +        i = i >= 0 ? i : Math.max(0, length + i);
            +        for (; i < length; i++) {
            +            if (i in self && self[i] === sought) {
            +                return i;
            +            }
            +        }
            +        return -1;
            +    };
            +}
            +if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
            +    Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
            +        var self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                toObject(this),
            +            length = self.length >>> 0;
            +
            +        if (!length) {
            +            return -1;
            +        }
            +        var i = length - 1;
            +        if (arguments.length > 1) {
            +            i = Math.min(i, toInteger(arguments[1]));
            +        }
            +        i = i >= 0 ? i : length - Math.abs(i);
            +        for (; i >= 0; i--) {
            +            if (i in self && sought === self[i]) {
            +                return i;
            +            }
            +        }
            +        return -1;
            +    };
            +}
            +if (!Object.getPrototypeOf) {
            +    Object.getPrototypeOf = function getPrototypeOf(object) {
            +        return object.__proto__ || (
            +            object.constructor ?
            +            object.constructor.prototype :
            +            prototypeOfObject
            +        );
            +    };
            +}
            +if (!Object.getOwnPropertyDescriptor) {
            +    var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
            +                         "non-object: ";
            +    Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
            +        if ((typeof object != "object" && typeof object != "function") || object === null)
            +            throw new TypeError(ERR_NON_OBJECT + object);
            +        if (!owns(object, property))
            +            return;
            +
            +        var descriptor, getter, setter;
            +        descriptor =  { enumerable: true, configurable: true };
            +        if (supportsAccessors) {
            +            var prototype = object.__proto__;
            +            object.__proto__ = prototypeOfObject;
            +
            +            var getter = lookupGetter(object, property);
            +            var setter = lookupSetter(object, property);
            +            object.__proto__ = prototype;
            +
            +            if (getter || setter) {
            +                if (getter) descriptor.get = getter;
            +                if (setter) descriptor.set = setter;
            +                return descriptor;
            +            }
            +        }
            +        descriptor.value = object[property];
            +        return descriptor;
            +    };
            +}
            +if (!Object.getOwnPropertyNames) {
            +    Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
            +        return Object.keys(object);
            +    };
            +}
            +if (!Object.create) {
            +    var createEmpty;
            +    if (Object.prototype.__proto__ === null) {
            +        createEmpty = function () {
            +            return { "__proto__": null };
            +        };
            +    } else {
            +        createEmpty = function () {
            +            var empty = {};
            +            for (var i in empty)
            +                empty[i] = null;
            +            empty.constructor =
            +            empty.hasOwnProperty =
            +            empty.propertyIsEnumerable =
            +            empty.isPrototypeOf =
            +            empty.toLocaleString =
            +            empty.toString =
            +            empty.valueOf =
            +            empty.__proto__ = null;
            +            return empty;
            +        }
            +    }
            +
            +    Object.create = function create(prototype, properties) {
            +        var object;
            +        if (prototype === null) {
            +            object = createEmpty();
            +        } else {
            +            if (typeof prototype != "object")
            +                throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
            +            var Type = function () {};
            +            Type.prototype = prototype;
            +            object = new Type();
            +            object.__proto__ = prototype;
            +        }
            +        if (properties !== void 0)
            +            Object.defineProperties(object, properties);
            +        return object;
            +    };
            +}
            +
            +function doesDefinePropertyWork(object) {
            +    try {
            +        Object.defineProperty(object, "sentinel", {});
            +        return "sentinel" in object;
            +    } catch (exception) {
            +    }
            +}
            +if (Object.defineProperty) {
            +    var definePropertyWorksOnObject = doesDefinePropertyWork({});
            +    var definePropertyWorksOnDom = typeof document == "undefined" ||
            +        doesDefinePropertyWork(document.createElement("div"));
            +    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
            +        var definePropertyFallback = Object.defineProperty;
            +    }
            +}
            +
            +if (!Object.defineProperty || definePropertyFallback) {
            +    var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
            +    var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
            +    var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
            +                                      "on this javascript engine";
            +
            +    Object.defineProperty = function defineProperty(object, property, descriptor) {
            +        if ((typeof object != "object" && typeof object != "function") || object === null)
            +            throw new TypeError(ERR_NON_OBJECT_TARGET + object);
            +        if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
            +            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
            +        if (definePropertyFallback) {
            +            try {
            +                return definePropertyFallback.call(Object, object, property, descriptor);
            +            } catch (exception) {
            +            }
            +        }
            +        if (owns(descriptor, "value")) {
            +
            +            if (supportsAccessors && (lookupGetter(object, property) ||
            +                                      lookupSetter(object, property)))
            +            {
            +                var prototype = object.__proto__;
            +                object.__proto__ = prototypeOfObject;
            +                delete object[property];
            +                object[property] = descriptor.value;
            +                object.__proto__ = prototype;
            +            } else {
            +                object[property] = descriptor.value;
            +            }
            +        } else {
            +            if (!supportsAccessors)
            +                throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
            +            if (owns(descriptor, "get"))
            +                defineGetter(object, property, descriptor.get);
            +            if (owns(descriptor, "set"))
            +                defineSetter(object, property, descriptor.set);
            +        }
            +
            +        return object;
            +    };
            +}
            +if (!Object.defineProperties) {
            +    Object.defineProperties = function defineProperties(object, properties) {
            +        for (var property in properties) {
            +            if (owns(properties, property))
            +                Object.defineProperty(object, property, properties[property]);
            +        }
            +        return object;
            +    };
            +}
            +if (!Object.seal) {
            +    Object.seal = function seal(object) {
            +        return object;
            +    };
            +}
            +if (!Object.freeze) {
            +    Object.freeze = function freeze(object) {
            +        return object;
            +    };
            +}
            +try {
            +    Object.freeze(function () {});
            +} catch (exception) {
            +    Object.freeze = (function freeze(freezeObject) {
            +        return function freeze(object) {
            +            if (typeof object == "function") {
            +                return object;
            +            } else {
            +                return freezeObject(object);
            +            }
            +        };
            +    })(Object.freeze);
            +}
            +if (!Object.preventExtensions) {
            +    Object.preventExtensions = function preventExtensions(object) {
            +        return object;
            +    };
            +}
            +if (!Object.isSealed) {
            +    Object.isSealed = function isSealed(object) {
            +        return false;
            +    };
            +}
            +if (!Object.isFrozen) {
            +    Object.isFrozen = function isFrozen(object) {
            +        return false;
            +    };
            +}
            +if (!Object.isExtensible) {
            +    Object.isExtensible = function isExtensible(object) {
            +        if (Object(object) === object) {
            +            throw new TypeError(); // TODO message
            +        }
            +        var name = '';
            +        while (owns(object, name)) {
            +            name += '?';
            +        }
            +        object[name] = true;
            +        var returnValue = owns(object, name);
            +        delete object[name];
            +        return returnValue;
            +    };
            +}
            +if (!Object.keys) {
            +    var hasDontEnumBug = true,
            +        dontEnums = [
            +            "toString",
            +            "toLocaleString",
            +            "valueOf",
            +            "hasOwnProperty",
            +            "isPrototypeOf",
            +            "propertyIsEnumerable",
            +            "constructor"
            +        ],
            +        dontEnumsLength = dontEnums.length;
            +
            +    for (var key in {"toString": null}) {
            +        hasDontEnumBug = false;
            +    }
            +
            +    Object.keys = function keys(object) {
            +
            +        if (
            +            (typeof object != "object" && typeof object != "function") ||
            +            object === null
            +        ) {
            +            throw new TypeError("Object.keys called on a non-object");
            +        }
            +
            +        var keys = [];
            +        for (var name in object) {
            +            if (owns(object, name)) {
            +                keys.push(name);
            +            }
            +        }
            +
            +        if (hasDontEnumBug) {
            +            for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
            +                var dontEnum = dontEnums[i];
            +                if (owns(object, dontEnum)) {
            +                    keys.push(dontEnum);
            +                }
            +            }
            +        }
            +        return keys;
            +    };
            +
            +}
            +if (!Date.now) {
            +    Date.now = function now() {
            +        return new Date().getTime();
            +    };
            +}
            +var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
            +    "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
            +    "\u2029\uFEFF";
            +if (!String.prototype.trim || ws.trim()) {
            +    ws = "[" + ws + "]";
            +    var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
            +        trimEndRegexp = new RegExp(ws + ws + "*$");
            +    String.prototype.trim = function trim() {
            +        return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
            +    };
            +}
            +
            +function toInteger(n) {
            +    n = +n;
            +    if (n !== n) { // isNaN
            +        n = 0;
            +    } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
            +        n = (n > 0 || -1) * Math.floor(Math.abs(n));
            +    }
            +    return n;
            +}
            +
            +function isPrimitive(input) {
            +    var type = typeof input;
            +    return (
            +        input === null ||
            +        type === "undefined" ||
            +        type === "boolean" ||
            +        type === "number" ||
            +        type === "string"
            +    );
            +}
            +
            +function toPrimitive(input) {
            +    var val, valueOf, toString;
            +    if (isPrimitive(input)) {
            +        return input;
            +    }
            +    valueOf = input.valueOf;
            +    if (typeof valueOf === "function") {
            +        val = valueOf.call(input);
            +        if (isPrimitive(val)) {
            +            return val;
            +        }
            +    }
            +    toString = input.toString;
            +    if (typeof toString === "function") {
            +        val = toString.call(input);
            +        if (isPrimitive(val)) {
            +            return val;
            +        }
            +    }
            +    throw new TypeError();
            +}
            +var toObject = function (o) {
            +    if (o == null) { // this matches both null and undefined
            +        throw new TypeError("can't convert "+o+" to object");
            +    }
            +    return Object(o);
            +};
            +
            +});
            +
            +define("ace/lib/fixoldbrowsers",["require","exports","module","ace/lib/regexp","ace/lib/es5-shim"], function(require, exports, module) {
            +"use strict";
            +
            +require("./regexp");
            +require("./es5-shim");
            +
            +});
            +
            +define("ace/lib/dom",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +
            +if (typeof document == "undefined")
            +    return;
            +
            +var XHTML_NS = "http://www.w3.org/1999/xhtml";
            +
            +exports.getDocumentHead = function(doc) {
            +    if (!doc)
            +        doc = document;
            +    return doc.head || doc.getElementsByTagName("head")[0] || doc.documentElement;
            +}
            +
            +exports.createElement = function(tag, ns) {
            +    return document.createElementNS ?
            +           document.createElementNS(ns || XHTML_NS, tag) :
            +           document.createElement(tag);
            +};
            +
            +exports.hasCssClass = function(el, name) {
            +    var classes = el.className.split(/\s+/g);
            +    return classes.indexOf(name) !== -1;
            +};
            +exports.addCssClass = function(el, name) {
            +    if (!exports.hasCssClass(el, name)) {
            +        el.className += " " + name;
            +    }
            +};
            +exports.removeCssClass = function(el, name) {
            +    var classes = el.className.split(/\s+/g);
            +    while (true) {
            +        var index = classes.indexOf(name);
            +        if (index == -1) {
            +            break;
            +        }
            +        classes.splice(index, 1);
            +    }
            +    el.className = classes.join(" ");
            +};
            +
            +exports.toggleCssClass = function(el, name) {
            +    var classes = el.className.split(/\s+/g), add = true;
            +    while (true) {
            +        var index = classes.indexOf(name);
            +        if (index == -1) {
            +            break;
            +        }
            +        add = false;
            +        classes.splice(index, 1);
            +    }
            +    if(add)
            +        classes.push(name);
            +
            +    el.className = classes.join(" ");
            +    return add;
            +};
            +exports.setCssClass = function(node, className, include) {
            +    if (include) {
            +        exports.addCssClass(node, className);
            +    } else {
            +        exports.removeCssClass(node, className);
            +    }
            +};
            +
            +exports.hasCssString = function(id, doc) {
            +    var index = 0, sheets;
            +    doc = doc || document;
            +
            +    if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
            +        while (index < sheets.length)
            +            if (sheets[index++].owningElement.id === id) return true;
            +    } else if ((sheets = doc.getElementsByTagName("style"))) {
            +        while (index < sheets.length)
            +            if (sheets[index++].id === id) return true;
            +    }
            +
            +    return false;
            +};
            +
            +exports.importCssString = function importCssString(cssText, id, doc) {
            +    doc = doc || document;
            +    if (id && exports.hasCssString(id, doc))
            +        return null;
            +    
            +    var style;
            +    
            +    if (doc.createStyleSheet) {
            +        style = doc.createStyleSheet();
            +        style.cssText = cssText;
            +        if (id)
            +            style.owningElement.id = id;
            +    } else {
            +        style = doc.createElementNS
            +            ? doc.createElementNS(XHTML_NS, "style")
            +            : doc.createElement("style");
            +
            +        style.appendChild(doc.createTextNode(cssText));
            +        if (id)
            +            style.id = id;
            +
            +        exports.getDocumentHead(doc).appendChild(style);
            +    }
            +};
            +
            +exports.importCssStylsheet = function(uri, doc) {
            +    if (doc.createStyleSheet) {
            +        doc.createStyleSheet(uri);
            +    } else {
            +        var link = exports.createElement('link');
            +        link.rel = 'stylesheet';
            +        link.href = uri;
            +
            +        exports.getDocumentHead(doc).appendChild(link);
            +    }
            +};
            +
            +exports.getInnerWidth = function(element) {
            +    return (
            +        parseInt(exports.computedStyle(element, "paddingLeft"), 10) +
            +        parseInt(exports.computedStyle(element, "paddingRight"), 10) + 
            +        element.clientWidth
            +    );
            +};
            +
            +exports.getInnerHeight = function(element) {
            +    return (
            +        parseInt(exports.computedStyle(element, "paddingTop"), 10) +
            +        parseInt(exports.computedStyle(element, "paddingBottom"), 10) +
            +        element.clientHeight
            +    );
            +};
            +
            +if (window.pageYOffset !== undefined) {
            +    exports.getPageScrollTop = function() {
            +        return window.pageYOffset;
            +    };
            +
            +    exports.getPageScrollLeft = function() {
            +        return window.pageXOffset;
            +    };
            +}
            +else {
            +    exports.getPageScrollTop = function() {
            +        return document.body.scrollTop;
            +    };
            +
            +    exports.getPageScrollLeft = function() {
            +        return document.body.scrollLeft;
            +    };
            +}
            +
            +if (window.getComputedStyle)
            +    exports.computedStyle = function(element, style) {
            +        if (style)
            +            return (window.getComputedStyle(element, "") || {})[style] || "";
            +        return window.getComputedStyle(element, "") || {};
            +    };
            +else
            +    exports.computedStyle = function(element, style) {
            +        if (style)
            +            return element.currentStyle[style];
            +        return element.currentStyle;
            +    };
            +
            +exports.scrollbarWidth = function(document) {
            +    var inner = exports.createElement("ace_inner");
            +    inner.style.width = "100%";
            +    inner.style.minWidth = "0px";
            +    inner.style.height = "200px";
            +    inner.style.display = "block";
            +
            +    var outer = exports.createElement("ace_outer");
            +    var style = outer.style;
            +
            +    style.position = "absolute";
            +    style.left = "-10000px";
            +    style.overflow = "hidden";
            +    style.width = "200px";
            +    style.minWidth = "0px";
            +    style.height = "150px";
            +    style.display = "block";
            +
            +    outer.appendChild(inner);
            +
            +    var body = document.documentElement;
            +    body.appendChild(outer);
            +
            +    var noScrollbar = inner.offsetWidth;
            +
            +    style.overflow = "scroll";
            +    var withScrollbar = inner.offsetWidth;
            +
            +    if (noScrollbar == withScrollbar) {
            +        withScrollbar = outer.clientWidth;
            +    }
            +
            +    body.removeChild(outer);
            +
            +    return noScrollbar-withScrollbar;
            +};
            +exports.setInnerHtml = function(el, innerHtml) {
            +    var element = el.cloneNode(false);//document.createElement("div");
            +    element.innerHTML = innerHtml;
            +    el.parentNode.replaceChild(element, el);
            +    return element;
            +};
            +
            +if ("textContent" in document.documentElement) {
            +    exports.setInnerText = function(el, innerText) {
            +        el.textContent = innerText;
            +    };
            +
            +    exports.getInnerText = function(el) {
            +        return el.textContent;
            +    };
            +}
            +else {
            +    exports.setInnerText = function(el, innerText) {
            +        el.innerText = innerText;
            +    };
            +
            +    exports.getInnerText = function(el) {
            +        return el.innerText;
            +    };
            +}
            +
            +exports.getParentWindow = function(document) {
            +    return document.defaultView || document.parentWindow;
            +};
            +
            +});
            +
            +define("ace/lib/oop",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +
            +exports.inherits = function(ctor, superCtor) {
            +    ctor.super_ = superCtor;
            +    ctor.prototype = Object.create(superCtor.prototype, {
            +        constructor: {
            +            value: ctor,
            +            enumerable: false,
            +            writable: true,
            +            configurable: true
            +        }
            +    });
            +};
            +
            +exports.mixin = function(obj, mixin) {
            +    for (var key in mixin) {
            +        obj[key] = mixin[key];
            +    }
            +    return obj;
            +};
            +
            +exports.implement = function(proto, mixin) {
            +    exports.mixin(proto, mixin);
            +};
            +
            +});
            +
            +define("ace/lib/keys",["require","exports","module","ace/lib/oop"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./oop");
            +var Keys = (function() {
            +    var ret = {
            +        MODIFIER_KEYS: {
            +            16: 'Shift', 17: 'Ctrl', 18: 'Alt', 224: 'Meta'
            +        },
            +
            +        KEY_MODS: {
            +            "ctrl": 1, "alt": 2, "option" : 2, "shift": 4,
            +            "super": 8, "meta": 8, "command": 8, "cmd": 8
            +        },
            +
            +        FUNCTION_KEYS : {
            +            8  : "Backspace",
            +            9  : "Tab",
            +            13 : "Return",
            +            19 : "Pause",
            +            27 : "Esc",
            +            32 : "Space",
            +            33 : "PageUp",
            +            34 : "PageDown",
            +            35 : "End",
            +            36 : "Home",
            +            37 : "Left",
            +            38 : "Up",
            +            39 : "Right",
            +            40 : "Down",
            +            44 : "Print",
            +            45 : "Insert",
            +            46 : "Delete",
            +            96 : "Numpad0",
            +            97 : "Numpad1",
            +            98 : "Numpad2",
            +            99 : "Numpad3",
            +            100: "Numpad4",
            +            101: "Numpad5",
            +            102: "Numpad6",
            +            103: "Numpad7",
            +            104: "Numpad8",
            +            105: "Numpad9",
            +            '-13': "NumpadEnter",
            +            112: "F1",
            +            113: "F2",
            +            114: "F3",
            +            115: "F4",
            +            116: "F5",
            +            117: "F6",
            +            118: "F7",
            +            119: "F8",
            +            120: "F9",
            +            121: "F10",
            +            122: "F11",
            +            123: "F12",
            +            144: "Numlock",
            +            145: "Scrolllock"
            +        },
            +
            +        PRINTABLE_KEYS: {
            +           32: ' ',  48: '0',  49: '1',  50: '2',  51: '3',  52: '4', 53:  '5',
            +           54: '6',  55: '7',  56: '8',  57: '9',  59: ';',  61: '=', 65:  'a',
            +           66: 'b',  67: 'c',  68: 'd',  69: 'e',  70: 'f',  71: 'g', 72:  'h',
            +           73: 'i',  74: 'j',  75: 'k',  76: 'l',  77: 'm',  78: 'n', 79:  'o',
            +           80: 'p',  81: 'q',  82: 'r',  83: 's',  84: 't',  85: 'u', 86:  'v',
            +           87: 'w',  88: 'x',  89: 'y',  90: 'z', 107: '+', 109: '-', 110: '.',
            +          187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`', 219: '[',
            +          220: '\\',221: ']', 222: '\''
            +        }
            +    };
            +    var name, i;
            +    for (i in ret.FUNCTION_KEYS) {
            +        name = ret.FUNCTION_KEYS[i].toLowerCase();
            +        ret[name] = parseInt(i, 10);
            +    }
            +    for (i in ret.PRINTABLE_KEYS) {
            +        name = ret.PRINTABLE_KEYS[i].toLowerCase();
            +        ret[name] = parseInt(i, 10);
            +    }
            +    oop.mixin(ret, ret.MODIFIER_KEYS);
            +    oop.mixin(ret, ret.PRINTABLE_KEYS);
            +    oop.mixin(ret, ret.FUNCTION_KEYS);
            +    ret.enter = ret["return"];
            +    ret.escape = ret.esc;
            +    ret.del = ret["delete"];
            +    ret[173] = '-';
            +    
            +    (function() {
            +        var mods = ["cmd", "ctrl", "alt", "shift"];
            +        for (var i = Math.pow(2, mods.length); i--;) {
            +            ret.KEY_MODS[i] = mods.filter(function(x) {
            +                return i & ret.KEY_MODS[x];
            +            }).join("-") + "-";
            +        }
            +    })();
            +
            +    return ret;
            +})();
            +oop.mixin(exports, Keys);
            +
            +exports.keyCodeToString = function(keyCode) {
            +    var keyString = Keys[keyCode];
            +    if (typeof keyString != "string")
            +        keyString = String.fromCharCode(keyCode);
            +    return keyString.toLowerCase();
            +};
            +
            +});
            +
            +define("ace/lib/useragent",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +exports.OS = {
            +    LINUX: "LINUX",
            +    MAC: "MAC",
            +    WINDOWS: "WINDOWS"
            +};
            +exports.getOS = function() {
            +    if (exports.isMac) {
            +        return exports.OS.MAC;
            +    } else if (exports.isLinux) {
            +        return exports.OS.LINUX;
            +    } else {
            +        return exports.OS.WINDOWS;
            +    }
            +};
            +if (typeof navigator != "object")
            +    return;
            +
            +var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
            +var ua = navigator.userAgent;
            +exports.isWin = (os == "win");
            +exports.isMac = (os == "mac");
            +exports.isLinux = (os == "linux");
            +exports.isIE = 
            +    (navigator.appName == "Microsoft Internet Explorer" || navigator.appName.indexOf("MSAppHost") >= 0)
            +    ? parseFloat((ua.match(/(?:MSIE |Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1])
            +    : parseFloat((ua.match(/(?:Trident\/[0-9]+[\.0-9]+;.*rv:)([0-9]+[\.0-9]+)/)||[])[1]); // for ie
            +    
            +exports.isOldIE = exports.isIE && exports.isIE < 9;
            +exports.isGecko = exports.isMozilla = (window.Controllers || window.controllers) && window.navigator.product === "Gecko";
            +exports.isOldGecko = exports.isGecko && parseInt((ua.match(/rv\:(\d+)/)||[])[1], 10) < 4;
            +exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]";
            +exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined;
            +
            +exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined;
            +
            +exports.isAIR = ua.indexOf("AdobeAIR") >= 0;
            +
            +exports.isIPad = ua.indexOf("iPad") >= 0;
            +
            +exports.isTouchPad = ua.indexOf("TouchPad") >= 0;
            +
            +exports.isChromeOS = ua.indexOf(" CrOS ") >= 0;
            +
            +});
            +
            +define("ace/lib/event",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) {
            +"use strict";
            +
            +var keys = require("./keys");
            +var useragent = require("./useragent");
            +
            +exports.addListener = function(elem, type, callback) {
            +    if (elem.addEventListener) {
            +        return elem.addEventListener(type, callback, false);
            +    }
            +    if (elem.attachEvent) {
            +        var wrapper = function() {
            +            callback.call(elem, window.event);
            +        };
            +        callback._wrapper = wrapper;
            +        elem.attachEvent("on" + type, wrapper);
            +    }
            +};
            +
            +exports.removeListener = function(elem, type, callback) {
            +    if (elem.removeEventListener) {
            +        return elem.removeEventListener(type, callback, false);
            +    }
            +    if (elem.detachEvent) {
            +        elem.detachEvent("on" + type, callback._wrapper || callback);
            +    }
            +};
            +exports.stopEvent = function(e) {
            +    exports.stopPropagation(e);
            +    exports.preventDefault(e);
            +    return false;
            +};
            +
            +exports.stopPropagation = function(e) {
            +    if (e.stopPropagation)
            +        e.stopPropagation();
            +    else
            +        e.cancelBubble = true;
            +};
            +
            +exports.preventDefault = function(e) {
            +    if (e.preventDefault)
            +        e.preventDefault();
            +    else
            +        e.returnValue = false;
            +};
            +exports.getButton = function(e) {
            +    if (e.type == "dblclick")
            +        return 0;
            +    if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey)))
            +        return 2;
            +    if (e.preventDefault) {
            +        return e.button;
            +    }
            +    else {
            +        return {1:0, 2:2, 4:1}[e.button];
            +    }
            +};
            +
            +exports.capture = function(el, eventHandler, releaseCaptureHandler) {
            +    function onMouseUp(e) {
            +        eventHandler && eventHandler(e);
            +        releaseCaptureHandler && releaseCaptureHandler(e);
            +
            +        exports.removeListener(document, "mousemove", eventHandler, true);
            +        exports.removeListener(document, "mouseup", onMouseUp, true);
            +        exports.removeListener(document, "dragstart", onMouseUp, true);
            +    }
            +
            +    exports.addListener(document, "mousemove", eventHandler, true);
            +    exports.addListener(document, "mouseup", onMouseUp, true);
            +    exports.addListener(document, "dragstart", onMouseUp, true);
            +    
            +    return onMouseUp;
            +};
            +
            +exports.addMouseWheelListener = function(el, callback) {
            +    if ("onmousewheel" in el) {
            +        exports.addListener(el, "mousewheel", function(e) {
            +            var factor = 8;
            +            if (e.wheelDeltaX !== undefined) {
            +                e.wheelX = -e.wheelDeltaX / factor;
            +                e.wheelY = -e.wheelDeltaY / factor;
            +            } else {
            +                e.wheelX = 0;
            +                e.wheelY = -e.wheelDelta / factor;
            +            }
            +            callback(e);
            +        });
            +    } else if ("onwheel" in el) {
            +        exports.addListener(el, "wheel",  function(e) {
            +            var factor = 0.35;
            +            switch (e.deltaMode) {
            +                case e.DOM_DELTA_PIXEL:
            +                    e.wheelX = e.deltaX * factor || 0;
            +                    e.wheelY = e.deltaY * factor || 0;
            +                    break;
            +                case e.DOM_DELTA_LINE:
            +                case e.DOM_DELTA_PAGE:
            +                    e.wheelX = (e.deltaX || 0) * 5;
            +                    e.wheelY = (e.deltaY || 0) * 5;
            +                    break;
            +            }
            +            
            +            callback(e);
            +        });
            +    } else {
            +        exports.addListener(el, "DOMMouseScroll", function(e) {
            +            if (e.axis && e.axis == e.HORIZONTAL_AXIS) {
            +                e.wheelX = (e.detail || 0) * 5;
            +                e.wheelY = 0;
            +            } else {
            +                e.wheelX = 0;
            +                e.wheelY = (e.detail || 0) * 5;
            +            }
            +            callback(e);
            +        });
            +    }
            +};
            +
            +exports.addMultiMouseDownListener = function(el, timeouts, eventHandler, callbackName) {
            +    var clicks = 0;
            +    var startX, startY, timer; 
            +    var eventNames = {
            +        2: "dblclick",
            +        3: "tripleclick",
            +        4: "quadclick"
            +    };
            +
            +    exports.addListener(el, "mousedown", function(e) {
            +        if (exports.getButton(e) !== 0) {
            +            clicks = 0;
            +        } else if (e.detail > 1) {
            +            clicks++;
            +            if (clicks > 4)
            +                clicks = 1;
            +        } else {
            +            clicks = 1;
            +        }
            +        if (useragent.isIE) {
            +            var isNewClick = Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5;
            +            if (!timer || isNewClick)
            +                clicks = 1;
            +            if (timer)
            +                clearTimeout(timer);
            +            timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600);
            +
            +            if (clicks == 1) {
            +                startX = e.clientX;
            +                startY = e.clientY;
            +            }
            +        }
            +
            +        eventHandler[callbackName]("mousedown", e);
            +
            +        if (clicks > 4)
            +            clicks = 0;
            +        else if (clicks > 1)
            +            return eventHandler[callbackName](eventNames[clicks], e);
            +    });
            +
            +    if (useragent.isOldIE) {
            +        exports.addListener(el, "dblclick", function(e) {
            +            clicks = 2;
            +            if (timer)
            +                clearTimeout(timer);
            +            timer = setTimeout(function() {timer = null}, timeouts[clicks - 1] || 600);
            +            eventHandler[callbackName]("mousedown", e);
            +            eventHandler[callbackName](eventNames[clicks], e);
            +        });
            +    }
            +};
            +
            +var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window)
            +    ? function(e) {
            +        return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0);
            +    }
            +    : function(e) {
            +        return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
            +    };
            +
            +exports.getModifierString = function(e) {
            +    return keys.KEY_MODS[getModifierHash(e)];
            +};
            +
            +function normalizeCommandKeys(callback, e, keyCode) {
            +    var hashId = getModifierHash(e);
            +
            +    if (!useragent.isMac && pressedKeys) {
            +        if (pressedKeys[91] || pressedKeys[92])
            +            hashId |= 8;
            +        if (pressedKeys.altGr) {
            +            if ((3 & hashId) != 3)
            +                pressedKeys.altGr = 0;
            +            else
            +                return;
            +        }
            +        if (keyCode === 18 || keyCode === 17) {
            +            var location = e.location || e.keyLocation;
            +            if (keyCode === 17 && location === 1) {
            +                ts = e.timeStamp;
            +            } else if (keyCode === 18 && hashId === 3 && location === 2) {
            +                var dt = -ts;
            +                ts = e.timeStamp;
            +                dt += ts;
            +                if (dt < 3)
            +                    pressedKeys.altGr = true;
            +            }
            +        }
            +    }
            +    
            +    if (keyCode in keys.MODIFIER_KEYS) {
            +        switch (keys.MODIFIER_KEYS[keyCode]) {
            +            case "Alt":
            +                hashId = 2;
            +                break;
            +            case "Shift":
            +                hashId = 4;
            +                break;
            +            case "Ctrl":
            +                hashId = 1;
            +                break;
            +            default:
            +                hashId = 8;
            +                break;
            +        }
            +        keyCode = -1;
            +    }
            +
            +    if (hashId & 8 && (keyCode === 91 || keyCode === 93)) {
            +        keyCode = -1;
            +    }
            +    
            +    if (!hashId && keyCode === 13) {
            +        if (e.location || e.keyLocation === 3) {
            +            callback(e, hashId, -keyCode);
            +            if (e.defaultPrevented)
            +                return;
            +        }
            +    }
            +    
            +    if (useragent.isChromeOS && hashId & 8) {
            +        callback(e, hashId, keyCode);
            +        if (e.defaultPrevented)
            +            return;
            +        else
            +            hashId &= ~8;
            +    }
            +    if (!hashId && !(keyCode in keys.FUNCTION_KEYS) && !(keyCode in keys.PRINTABLE_KEYS)) {
            +        return false;
            +    }
            +    
            +    return callback(e, hashId, keyCode);
            +}
            +
            +var pressedKeys = null;
            +var ts = 0;
            +exports.addCommandKeyListener = function(el, callback) {
            +    var addListener = exports.addListener;
            +    if (useragent.isOldGecko || (useragent.isOpera && !("KeyboardEvent" in window))) {
            +        var lastKeyDownKeyCode = null;
            +        addListener(el, "keydown", function(e) {
            +            lastKeyDownKeyCode = e.keyCode;
            +        });
            +        addListener(el, "keypress", function(e) {
            +            return normalizeCommandKeys(callback, e, lastKeyDownKeyCode);
            +        });
            +    } else {
            +        var lastDefaultPrevented = null;
            +
            +        addListener(el, "keydown", function(e) {
            +            pressedKeys[e.keyCode] = true;
            +            var result = normalizeCommandKeys(callback, e, e.keyCode);
            +            lastDefaultPrevented = e.defaultPrevented;
            +            return result;
            +        });
            +
            +        addListener(el, "keypress", function(e) {
            +            if (lastDefaultPrevented && (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) {
            +                exports.stopEvent(e);
            +                lastDefaultPrevented = null;
            +            }
            +        });
            +
            +        addListener(el, "keyup", function(e) {
            +            pressedKeys[e.keyCode] = null;
            +        });
            +
            +        if (!pressedKeys) {
            +            pressedKeys = Object.create(null);
            +            addListener(window, "focus", function(e) {
            +                pressedKeys = Object.create(null);
            +            });
            +        }
            +    }
            +};
            +
            +if (window.postMessage && !useragent.isOldIE) {
            +    var postMessageId = 1;
            +    exports.nextTick = function(callback, win) {
            +        win = win || window;
            +        var messageName = "zero-timeout-message-" + postMessageId;
            +        exports.addListener(win, "message", function listener(e) {
            +            if (e.data == messageName) {
            +                exports.stopPropagation(e);
            +                exports.removeListener(win, "message", listener);
            +                callback();
            +            }
            +        });
            +        win.postMessage(messageName, "*");
            +    };
            +}
            +
            +
            +exports.nextFrame = window.requestAnimationFrame ||
            +    window.mozRequestAnimationFrame ||
            +    window.webkitRequestAnimationFrame ||
            +    window.msRequestAnimationFrame ||
            +    window.oRequestAnimationFrame;
            +
            +if (exports.nextFrame)
            +    exports.nextFrame = exports.nextFrame.bind(window);
            +else
            +    exports.nextFrame = function(callback) {
            +        setTimeout(callback, 17);
            +    };
            +});
            +
            +define("ace/lib/lang",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +
            +exports.last = function(a) {
            +    return a[a.length - 1];
            +};
            +
            +exports.stringReverse = function(string) {
            +    return string.split("").reverse().join("");
            +};
            +
            +exports.stringRepeat = function (string, count) {
            +    var result = '';
            +    while (count > 0) {
            +        if (count & 1)
            +            result += string;
            +
            +        if (count >>= 1)
            +            string += string;
            +    }
            +    return result;
            +};
            +
            +var trimBeginRegexp = /^\s\s*/;
            +var trimEndRegexp = /\s\s*$/;
            +
            +exports.stringTrimLeft = function (string) {
            +    return string.replace(trimBeginRegexp, '');
            +};
            +
            +exports.stringTrimRight = function (string) {
            +    return string.replace(trimEndRegexp, '');
            +};
            +
            +exports.copyObject = function(obj) {
            +    var copy = {};
            +    for (var key in obj) {
            +        copy[key] = obj[key];
            +    }
            +    return copy;
            +};
            +
            +exports.copyArray = function(array){
            +    var copy = [];
            +    for (var i=0, l=array.length; i<l; i++) {
            +        if (array[i] && typeof array[i] == "object")
            +            copy[i] = this.copyObject( array[i] );
            +        else 
            +            copy[i] = array[i];
            +    }
            +    return copy;
            +};
            +
            +exports.deepCopy = function (obj) {
            +    if (typeof obj !== "object" || !obj)
            +        return obj;
            +    var cons = obj.constructor;
            +    if (cons === RegExp)
            +        return obj;
            +    
            +    var copy = cons();
            +    for (var key in obj) {
            +        if (typeof obj[key] === "object") {
            +            copy[key] = exports.deepCopy(obj[key]);
            +        } else {
            +            copy[key] = obj[key];
            +        }
            +    }
            +    return copy;
            +};
            +
            +exports.arrayToMap = function(arr) {
            +    var map = {};
            +    for (var i=0; i<arr.length; i++) {
            +        map[arr[i]] = 1;
            +    }
            +    return map;
            +
            +};
            +
            +exports.createMap = function(props) {
            +    var map = Object.create(null);
            +    for (var i in props) {
            +        map[i] = props[i];
            +    }
            +    return map;
            +};
            +exports.arrayRemove = function(array, value) {
            +  for (var i = 0; i <= array.length; i++) {
            +    if (value === array[i]) {
            +      array.splice(i, 1);
            +    }
            +  }
            +};
            +
            +exports.escapeRegExp = function(str) {
            +    return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
            +};
            +
            +exports.escapeHTML = function(str) {
            +    return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
            +};
            +
            +exports.getMatchOffsets = function(string, regExp) {
            +    var matches = [];
            +
            +    string.replace(regExp, function(str) {
            +        matches.push({
            +            offset: arguments[arguments.length-2],
            +            length: str.length
            +        });
            +    });
            +
            +    return matches;
            +};
            +exports.deferredCall = function(fcn) {
            +
            +    var timer = null;
            +    var callback = function() {
            +        timer = null;
            +        fcn();
            +    };
            +
            +    var deferred = function(timeout) {
            +        deferred.cancel();
            +        timer = setTimeout(callback, timeout || 0);
            +        return deferred;
            +    };
            +
            +    deferred.schedule = deferred;
            +
            +    deferred.call = function() {
            +        this.cancel();
            +        fcn();
            +        return deferred;
            +    };
            +
            +    deferred.cancel = function() {
            +        clearTimeout(timer);
            +        timer = null;
            +        return deferred;
            +    };
            +    
            +    deferred.isPending = function() {
            +        return timer;
            +    };
            +
            +    return deferred;
            +};
            +
            +
            +exports.delayedCall = function(fcn, defaultTimeout) {
            +    var timer = null;
            +    var callback = function() {
            +        timer = null;
            +        fcn();
            +    };
            +
            +    var _self = function(timeout) {
            +        if (timer == null)
            +            timer = setTimeout(callback, timeout || defaultTimeout);
            +    };
            +
            +    _self.delay = function(timeout) {
            +        timer && clearTimeout(timer);
            +        timer = setTimeout(callback, timeout || defaultTimeout);
            +    };
            +    _self.schedule = _self;
            +
            +    _self.call = function() {
            +        this.cancel();
            +        fcn();
            +    };
            +
            +    _self.cancel = function() {
            +        timer && clearTimeout(timer);
            +        timer = null;
            +    };
            +
            +    _self.isPending = function() {
            +        return timer;
            +    };
            +
            +    return _self;
            +};
            +});
            +
            +define("ace/keyboard/textinput",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/lib/dom","ace/lib/lang"], function(require, exports, module) {
            +"use strict";
            +
            +var event = require("../lib/event");
            +var useragent = require("../lib/useragent");
            +var dom = require("../lib/dom");
            +var lang = require("../lib/lang");
            +var BROKEN_SETDATA = useragent.isChrome < 18;
            +var USE_IE_MIME_TYPE =  useragent.isIE;
            +
            +var TextInput = function(parentNode, host) {
            +    var text = dom.createElement("textarea");
            +    text.className = "ace_text-input";
            +
            +    if (useragent.isTouchPad)
            +        text.setAttribute("x-palm-disable-auto-cap", true);
            +
            +    text.wrap = "off";
            +    text.autocorrect = "off";
            +    text.autocapitalize = "off";
            +    text.spellcheck = false;
            +
            +    text.style.opacity = "0";
            +    parentNode.insertBefore(text, parentNode.firstChild);
            +
            +    var PLACEHOLDER = "\x01\x01";
            +
            +    var copied = false;
            +    var pasted = false;
            +    var inComposition = false;
            +    var tempStyle = '';
            +    var isSelectionEmpty = true;
            +    try { var isFocused = document.activeElement === text; } catch(e) {}
            +    
            +    event.addListener(text, "blur", function() {
            +        host.onBlur();
            +        isFocused = false;
            +    });
            +    event.addListener(text, "focus", function() {
            +        isFocused = true;
            +        host.onFocus();
            +        resetSelection();
            +    });
            +    this.focus = function() { text.focus(); };
            +    this.blur = function() { text.blur(); };
            +    this.isFocused = function() {
            +        return isFocused;
            +    };
            +    var syncSelection = lang.delayedCall(function() {
            +        isFocused && resetSelection(isSelectionEmpty);
            +    });
            +    var syncValue = lang.delayedCall(function() {
            +         if (!inComposition) {
            +            text.value = PLACEHOLDER;
            +            isFocused && resetSelection();
            +         }
            +    });
            +
            +    function resetSelection(isEmpty) {
            +        if (inComposition)
            +            return;
            +        if (inputHandler) {
            +            selectionStart = 0;
            +            selectionEnd = isEmpty ? 0 : text.value.length - 1;
            +        } else {
            +            var selectionStart = isEmpty ? 2 : 1;
            +            var selectionEnd = 2;
            +        }
            +        try {
            +            text.setSelectionRange(selectionStart, selectionEnd);
            +        } catch(e){}
            +    }
            +
            +    function resetValue() {
            +        if (inComposition)
            +            return;
            +        text.value = PLACEHOLDER;
            +        if (useragent.isWebKit)
            +            syncValue.schedule();
            +    }
            +
            +    useragent.isWebKit || host.addEventListener('changeSelection', function() {
            +        if (host.selection.isEmpty() != isSelectionEmpty) {
            +            isSelectionEmpty = !isSelectionEmpty;
            +            syncSelection.schedule();
            +        }
            +    });
            +
            +    resetValue();
            +    if (isFocused)
            +        host.onFocus();
            +
            +
            +    var isAllSelected = function(text) {
            +        return text.selectionStart === 0 && text.selectionEnd === text.value.length;
            +    };
            +    if (!text.setSelectionRange && text.createTextRange) {
            +        text.setSelectionRange = function(selectionStart, selectionEnd) {
            +            var range = this.createTextRange();
            +            range.collapse(true);
            +            range.moveStart('character', selectionStart);
            +            range.moveEnd('character', selectionEnd);
            +            range.select();
            +        };
            +        isAllSelected = function(text) {
            +            try {
            +                var range = text.ownerDocument.selection.createRange();
            +            }catch(e) {}
            +            if (!range || range.parentElement() != text) return false;
            +                return range.text == text.value;
            +        }
            +    }
            +    if (useragent.isOldIE) {
            +        var inPropertyChange = false;
            +        var onPropertyChange = function(e){
            +            if (inPropertyChange)
            +                return;
            +            var data = text.value;
            +            if (inComposition || !data || data == PLACEHOLDER)
            +                return;
            +            if (e && data == PLACEHOLDER[0])
            +                return syncProperty.schedule();
            +
            +            sendText(data);
            +            inPropertyChange = true;
            +            resetValue();
            +            inPropertyChange = false;
            +        };
            +        var syncProperty = lang.delayedCall(onPropertyChange);
            +        event.addListener(text, "propertychange", onPropertyChange);
            +
            +        var keytable = { 13:1, 27:1 };
            +        event.addListener(text, "keyup", function (e) {
            +            if (inComposition && (!text.value || keytable[e.keyCode]))
            +                setTimeout(onCompositionEnd, 0);
            +            if ((text.value.charCodeAt(0)||0) < 129) {
            +                return syncProperty.call();
            +            }
            +            inComposition ? onCompositionUpdate() : onCompositionStart();
            +        });
            +        event.addListener(text, "keydown", function (e) {
            +            syncProperty.schedule(50);
            +        });
            +    }
            +
            +    var onSelect = function(e) {
            +        if (copied) {
            +            copied = false;
            +        } else if (isAllSelected(text)) {
            +            host.selectAll();
            +            resetSelection();
            +        } else if (inputHandler) {
            +            resetSelection(host.selection.isEmpty());
            +        }
            +    };
            +
            +    var inputHandler = null;
            +    this.setInputHandler = function(cb) {inputHandler = cb};
            +    this.getInputHandler = function() {return inputHandler};
            +    var afterContextMenu = false;
            +    
            +    var sendText = function(data) {
            +        if (inputHandler) {
            +            data = inputHandler(data);
            +            inputHandler = null;
            +        }
            +        if (pasted) {
            +            resetSelection();
            +            if (data)
            +                host.onPaste(data);
            +            pasted = false;
            +        } else if (data == PLACEHOLDER.charAt(0)) {
            +            if (afterContextMenu)
            +                host.execCommand("del", {source: "ace"});
            +            else // some versions of android do not fire keydown when pressing backspace
            +                host.execCommand("backspace", {source: "ace"});
            +        } else {
            +            if (data.substring(0, 2) == PLACEHOLDER)
            +                data = data.substr(2);
            +            else if (data.charAt(0) == PLACEHOLDER.charAt(0))
            +                data = data.substr(1);
            +            else if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
            +                data = data.slice(0, -1);
            +            if (data.charAt(data.length - 1) == PLACEHOLDER.charAt(0))
            +                data = data.slice(0, -1);
            +            
            +            if (data)
            +                host.onTextInput(data);
            +        }
            +        if (afterContextMenu)
            +            afterContextMenu = false;
            +    };
            +    var onInput = function(e) {
            +        if (inComposition)
            +            return;
            +        var data = text.value;
            +        sendText(data);
            +        resetValue();
            +    };
            +    
            +    var handleClipboardData = function(e, data) {
            +        var clipboardData = e.clipboardData || window.clipboardData;
            +        if (!clipboardData || BROKEN_SETDATA)
            +            return;
            +        var mime = USE_IE_MIME_TYPE ? "Text" : "text/plain";
            +        if (data) {
            +            return clipboardData.setData(mime, data) !== false;
            +        } else {
            +            return clipboardData.getData(mime);
            +        }
            +    }
            +
            +    var doCopy = function(e, isCut) {
            +        var data = host.getCopyText();
            +        if (!data)
            +            return event.preventDefault(e);
            +
            +        if (handleClipboardData(e, data)) {
            +            isCut ? host.onCut() : host.onCopy();
            +            event.preventDefault(e);
            +        } else {
            +            copied = true;
            +            text.value = data;
            +            text.select();
            +            setTimeout(function(){
            +                copied = false;
            +                resetValue();
            +                resetSelection();
            +                isCut ? host.onCut() : host.onCopy();
            +            });
            +        }
            +    };
            +    
            +    var onCut = function(e) {
            +        doCopy(e, true);
            +    }
            +    
            +    var onCopy = function(e) {
            +        doCopy(e, false);
            +    }
            +    
            +    var onPaste = function(e) {
            +        var data = handleClipboardData(e);
            +        if (typeof data == "string") {
            +            if (data)
            +                host.onPaste(data);
            +            if (useragent.isIE)
            +                setTimeout(resetSelection);
            +            event.preventDefault(e);
            +        }
            +        else {
            +            text.value = "";
            +            pasted = true;
            +        }
            +    };
            +
            +    event.addCommandKeyListener(text, host.onCommandKey.bind(host));
            +
            +    event.addListener(text, "select", onSelect);
            +
            +    event.addListener(text, "input", onInput);
            +
            +    event.addListener(text, "cut", onCut);
            +    event.addListener(text, "copy", onCopy);
            +    event.addListener(text, "paste", onPaste);
            +    if (!('oncut' in text) || !('oncopy' in text) || !('onpaste' in text)){
            +        event.addListener(parentNode, "keydown", function(e) {
            +            if ((useragent.isMac && !e.metaKey) || !e.ctrlKey)
            +                return;
            +
            +            switch (e.keyCode) {
            +                case 67:
            +                    onCopy(e);
            +                    break;
            +                case 86:
            +                    onPaste(e);
            +                    break;
            +                case 88:
            +                    onCut(e);
            +                    break;
            +            }
            +        });
            +    }
            +    var onCompositionStart = function(e) {
            +        if (inComposition || !host.onCompositionStart) return;
            +        inComposition = {};
            +        host.onCompositionStart();
            +        setTimeout(onCompositionUpdate, 0);
            +        host.on("mousedown", onCompositionEnd);
            +        if (!host.selection.isEmpty()) {
            +            host.insert("");
            +            host.session.markUndoGroup();
            +            host.selection.clearSelection();
            +        }
            +        host.session.markUndoGroup();
            +    };
            +
            +    var onCompositionUpdate = function() {
            +        if (!inComposition || !host.onCompositionUpdate) return;
            +        var val = text.value.replace(/\x01/g, "");
            +        if (inComposition.lastValue === val) return;
            +        
            +        host.onCompositionUpdate(val);
            +        if (inComposition.lastValue)
            +            host.undo();
            +        inComposition.lastValue = val;
            +        if (inComposition.lastValue) {
            +            var r = host.selection.getRange();
            +            host.insert(inComposition.lastValue);
            +            host.session.markUndoGroup();
            +            inComposition.range = host.selection.getRange();
            +            host.selection.setRange(r);
            +            host.selection.clearSelection();
            +        }
            +    };
            +
            +    var onCompositionEnd = function(e) {
            +        if (!host.onCompositionEnd) return;
            +        var c = inComposition;
            +        inComposition = false;
            +        var timer = setTimeout(function() {
            +            timer = null;
            +            var str = text.value.replace(/\x01/g, "");
            +            if (inComposition)
            +                return
            +            else if (str == c.lastValue)
            +                resetValue();
            +            else if (!c.lastValue && str) {
            +                resetValue();
            +                sendText(str);
            +            }
            +        });
            +        inputHandler = function compositionInputHandler(str) {
            +            if (timer)
            +                clearTimeout(timer);
            +            str = str.replace(/\x01/g, "");
            +            if (str == c.lastValue)
            +                return "";
            +            if (c.lastValue && timer)
            +                host.undo();
            +            return str;
            +        };
            +        host.onCompositionEnd();
            +        host.removeListener("mousedown", onCompositionEnd);
            +        if (e.type == "compositionend" && c.range) {
            +            host.selection.setRange(c.range);
            +        }
            +    };
            +    
            +    
            +
            +    var syncComposition = lang.delayedCall(onCompositionUpdate, 50);
            +
            +    event.addListener(text, "compositionstart", onCompositionStart);
            +    if (useragent.isGecko) {
            +        event.addListener(text, "text", function(){syncComposition.schedule()});
            +    } else {
            +        event.addListener(text, "keyup", function(){syncComposition.schedule()});
            +        event.addListener(text, "keydown", function(){syncComposition.schedule()});
            +    }
            +    event.addListener(text, "compositionend", onCompositionEnd);
            +
            +    this.getElement = function() {
            +        return text;
            +    };
            +
            +    this.setReadOnly = function(readOnly) {
            +       text.readOnly = readOnly;
            +    };
            +
            +    this.onContextMenu = function(e) {
            +        afterContextMenu = true;
            +        resetSelection(host.selection.isEmpty());
            +        host._emit("nativecontextmenu", {target: host, domEvent: e});
            +        this.moveToMouse(e, true);
            +    };
            +    
            +    this.moveToMouse = function(e, bringToFront) {
            +        if (!tempStyle)
            +            tempStyle = text.style.cssText;
            +        text.style.cssText = (bringToFront ? "z-index:100000;" : "")
            +            + (useragent.isIE ? "opacity:0.1;" : "");
            +
            +        var rect = host.container.getBoundingClientRect();
            +        var style = dom.computedStyle(host.container);
            +        var top = rect.top + (parseInt(style.borderTopWidth) || 0);
            +        var left = rect.left + (parseInt(rect.borderLeftWidth) || 0);
            +        var maxTop = rect.bottom - top - text.clientHeight;
            +        var move = function(e) {
            +            text.style.left = e.clientX - left - 2 + "px";
            +            text.style.top = Math.min(e.clientY - top - 2, maxTop) + "px";
            +        }; 
            +        move(e);
            +
            +        if (e.type != "mousedown")
            +            return;
            +
            +        if (host.renderer.$keepTextAreaAtCursor)
            +            host.renderer.$keepTextAreaAtCursor = null;
            +        if (useragent.isWin)
            +            event.capture(host.container, move, onContextMenuClose);
            +    };
            +
            +    this.onContextMenuClose = onContextMenuClose;
            +    function onContextMenuClose() {
            +        setTimeout(function () {
            +            if (tempStyle) {
            +                text.style.cssText = tempStyle;
            +                tempStyle = '';
            +            }
            +            if (host.renderer.$keepTextAreaAtCursor == null) {
            +                host.renderer.$keepTextAreaAtCursor = true;
            +                host.renderer.$moveTextAreaToCursor();
            +            }
            +        }, 0);
            +    }
            +    if (!useragent.isGecko || useragent.isMac) {
            +        var onContextMenu = function(e) {
            +            host.textInput.onContextMenu(e);
            +            onContextMenuClose();
            +        };
            +        event.addListener(host.renderer.scroller, "contextmenu", onContextMenu);
            +        event.addListener(text, "contextmenu", onContextMenu);
            +    }
            +};
            +
            +exports.TextInput = TextInput;
            +});
            +
            +define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(require, exports, module) {
            +"use strict";
            +
            +var dom = require("../lib/dom");
            +var event = require("../lib/event");
            +var useragent = require("../lib/useragent");
            +
            +var DRAG_OFFSET = 0; // pixels
            +
            +function DefaultHandlers(mouseHandler) {
            +    mouseHandler.$clickSelection = null;
            +
            +    var editor = mouseHandler.editor;
            +    editor.setDefaultHandler("mousedown", this.onMouseDown.bind(mouseHandler));
            +    editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(mouseHandler));
            +    editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(mouseHandler));
            +    editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler));
            +    editor.setDefaultHandler("mousewheel", this.onMouseWheel.bind(mouseHandler));
            +
            +    var exports = ["select", "startSelect", "selectEnd", "selectAllEnd", "selectByWordsEnd",
            +        "selectByLinesEnd", "dragWait", "dragWaitEnd", "focusWait"];
            +
            +    exports.forEach(function(x) {
            +        mouseHandler[x] = this[x];
            +    }, this);
            +
            +    mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
            +    mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
            +}
            +
            +(function() {
            +
            +    this.onMouseDown = function(ev) {
            +        var inSelection = ev.inSelection();
            +        var pos = ev.getDocumentPosition();
            +        this.mousedownEvent = ev;
            +        var editor = this.editor;
            +
            +        var button = ev.getButton();
            +        if (button !== 0) {
            +            var selectionRange = editor.getSelectionRange();
            +            var selectionEmpty = selectionRange.isEmpty();
            +
            +            if (selectionEmpty) {
            +                editor.selection.moveToPosition(pos);
            +            }
            +            editor.textInput.onContextMenu(ev.domEvent);
            +            return; // stopping event here breaks contextmenu on ff mac
            +        }
            +        if (inSelection && !editor.isFocused()) {
            +            editor.focus();
            +            if (this.$focusTimout && !this.$clickSelection && !editor.inMultiSelectMode) {
            +                this.mousedownEvent.time = Date.now();
            +                this.setState("focusWait");
            +                this.captureMouse(ev);
            +                return;
            +            }
            +        }
            +
            +        this.captureMouse(ev);
            +        if (!inSelection || this.$clickSelection || ev.getShiftKey() || editor.inMultiSelectMode) {
            +            this.startSelect(pos);
            +        } else if (inSelection) {
            +            this.mousedownEvent.time = Date.now();
            +            this.startSelect(pos);
            +        }
            +        return ev.preventDefault();
            +    };
            +
            +    this.startSelect = function(pos) {
            +        pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);
            +        var editor = this.editor;
            +        var shiftPressed = this.mousedownEvent.getShiftKey();
            +        setTimeout(function(){
            +            if (shiftPressed) {
            +                editor.selection.selectToPosition(pos);
            +            }
            +            else if (!this.$clickSelection) {
            +                editor.selection.moveToPosition(pos);
            +            }
            +            this.select();
            +        }.bind(this), 0);
            +        if (editor.renderer.scroller.setCapture) {
            +            editor.renderer.scroller.setCapture();
            +        }
            +        editor.setStyle("ace_selecting");
            +        this.setState("select");
            +    };
            +
            +    this.select = function() {
            +        var anchor, editor = this.editor;
            +        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
            +
            +        if (this.$clickSelection) {
            +            var cmp = this.$clickSelection.comparePoint(cursor);
            +
            +            if (cmp == -1) {
            +                anchor = this.$clickSelection.end;
            +            } else if (cmp == 1) {
            +                anchor = this.$clickSelection.start;
            +            } else {
            +                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
            +                cursor = orientedRange.cursor;
            +                anchor = orientedRange.anchor;
            +            }
            +            editor.selection.setSelectionAnchor(anchor.row, anchor.column);
            +        }
            +        editor.selection.selectToPosition(cursor);
            +
            +        editor.renderer.scrollCursorIntoView();
            +    };
            +
            +    this.extendSelectionBy = function(unitName) {
            +        var anchor, editor = this.editor;
            +        var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
            +        var range = editor.selection[unitName](cursor.row, cursor.column);
            +
            +        if (this.$clickSelection) {
            +            var cmpStart = this.$clickSelection.comparePoint(range.start);
            +            var cmpEnd = this.$clickSelection.comparePoint(range.end);
            +
            +            if (cmpStart == -1 && cmpEnd <= 0) {
            +                anchor = this.$clickSelection.end;
            +                if (range.end.row != cursor.row || range.end.column != cursor.column)
            +                    cursor = range.start;
            +            } else if (cmpEnd == 1 && cmpStart >= 0) {
            +                anchor = this.$clickSelection.start;
            +                if (range.start.row != cursor.row || range.start.column != cursor.column)
            +                    cursor = range.end;
            +            } else if (cmpStart == -1 && cmpEnd == 1) {
            +                cursor = range.end;
            +                anchor = range.start;
            +            } else {
            +                var orientedRange = calcRangeOrientation(this.$clickSelection, cursor);
            +                cursor = orientedRange.cursor;
            +                anchor = orientedRange.anchor;
            +            }
            +            editor.selection.setSelectionAnchor(anchor.row, anchor.column);
            +        }
            +        editor.selection.selectToPosition(cursor);
            +
            +        editor.renderer.scrollCursorIntoView();
            +    };
            +
            +    this.selectEnd =
            +    this.selectAllEnd =
            +    this.selectByWordsEnd =
            +    this.selectByLinesEnd = function() {
            +        this.$clickSelection = null;
            +        this.editor.unsetStyle("ace_selecting");
            +        if (this.editor.renderer.scroller.releaseCapture) {
            +            this.editor.renderer.scroller.releaseCapture();
            +        }
            +    };
            +
            +    this.focusWait = function() {
            +        var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
            +        var time = Date.now();
            +
            +        if (distance > DRAG_OFFSET || time - this.mousedownEvent.time > this.$focusTimout)
            +            this.startSelect(this.mousedownEvent.getDocumentPosition());
            +    };
            +
            +    this.onDoubleClick = function(ev) {
            +        var pos = ev.getDocumentPosition();
            +        var editor = this.editor;
            +        var session = editor.session;
            +
            +        var range = session.getBracketRange(pos);
            +        if (range) {
            +            if (range.isEmpty()) {
            +                range.start.column--;
            +                range.end.column++;
            +            }
            +            this.setState("select");
            +        } else {
            +            range = editor.selection.getWordRange(pos.row, pos.column);
            +            this.setState("selectByWords");
            +        }
            +        this.$clickSelection = range;
            +    };
            +
            +    this.onTripleClick = function(ev) {
            +        var pos = ev.getDocumentPosition();
            +        var editor = this.editor;
            +
            +        this.setState("selectByLines");
            +        var range = editor.getSelectionRange();
            +        if (range.isMultiLine() && range.contains(pos.row, pos.column)) {
            +            this.$clickSelection = editor.selection.getLineRange(range.start.row);
            +            this.$clickSelection.end = editor.selection.getLineRange(range.end.row).end;
            +        } else {
            +            this.$clickSelection = editor.selection.getLineRange(pos.row);
            +        }
            +    };
            +
            +    this.onQuadClick = function(ev) {
            +        var editor = this.editor;
            +
            +        editor.selectAll();
            +        this.$clickSelection = editor.getSelectionRange();
            +        this.setState("selectAll");
            +    };
            +
            +    this.onMouseWheel = function(ev) {
            +        if (ev.getAccelKey())
            +            return;
            +        if (ev.getShiftKey() && ev.wheelY && !ev.wheelX) {
            +            ev.wheelX = ev.wheelY;
            +            ev.wheelY = 0;
            +        }
            +
            +        var t = ev.domEvent.timeStamp;
            +        var dt = t - (this.$lastScrollTime||0);
            +        
            +        var editor = this.editor;
            +        var isScrolable = editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
            +        if (isScrolable || dt < 200) {
            +            this.$lastScrollTime = t;
            +            editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
            +            return ev.stop();
            +        }
            +    };
            +
            +}).call(DefaultHandlers.prototype);
            +
            +exports.DefaultHandlers = DefaultHandlers;
            +
            +function calcDistance(ax, ay, bx, by) {
            +    return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
            +}
            +
            +function calcRangeOrientation(range, cursor) {
            +    if (range.start.row == range.end.row)
            +        var cmp = 2 * cursor.column - range.start.column - range.end.column;
            +    else if (range.start.row == range.end.row - 1 && !range.start.column && !range.end.column)
            +        var cmp = cursor.column - 4;
            +    else
            +        var cmp = 2 * cursor.row - range.start.row - range.end.row;
            +
            +    if (cmp < 0)
            +        return {cursor: range.start, anchor: range.end};
            +    else
            +        return {cursor: range.end, anchor: range.start};
            +}
            +
            +});
            +
            +define("ace/tooltip",["require","exports","module","ace/lib/oop","ace/lib/dom"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./lib/oop");
            +var dom = require("./lib/dom");
            +function Tooltip (parentNode) {
            +    this.isOpen = false;
            +    this.$element = null;
            +    this.$parentNode = parentNode;
            +}
            +
            +(function() {
            +    this.$init = function() {
            +        this.$element = dom.createElement("div");
            +        this.$element.className = "ace_tooltip";
            +        this.$element.style.display = "none";
            +        this.$parentNode.appendChild(this.$element);
            +        return this.$element;
            +    };
            +    this.getElement = function() {
            +        return this.$element || this.$init();
            +    };
            +    this.setText = function(text) {
            +        dom.setInnerText(this.getElement(), text);
            +    };
            +    this.setHtml = function(html) {
            +        this.getElement().innerHTML = html;
            +    };
            +    this.setPosition = function(x, y) {
            +        this.getElement().style.left = x + "px";
            +        this.getElement().style.top = y + "px";
            +    };
            +    this.setClassName = function(className) {
            +        dom.addCssClass(this.getElement(), className);
            +    };
            +    this.show = function(text, x, y) {
            +        if (text != null)
            +            this.setText(text);
            +        if (x != null && y != null)
            +            this.setPosition(x, y);
            +        if (!this.isOpen) {
            +            this.getElement().style.display = "block";
            +            this.isOpen = true;
            +        }
            +    };
            +
            +    this.hide = function() {
            +        if (this.isOpen) {
            +            this.getElement().style.display = "none";
            +            this.isOpen = false;
            +        }
            +    };
            +    this.getHeight = function() {
            +        return this.getElement().offsetHeight;
            +    };
            +    this.getWidth = function() {
            +        return this.getElement().offsetWidth;
            +    };
            +
            +}).call(Tooltip.prototype);
            +
            +exports.Tooltip = Tooltip;
            +});
            +
            +define("ace/mouse/default_gutter_handler",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event","ace/tooltip"], function(require, exports, module) {
            +"use strict";
            +var dom = require("../lib/dom");
            +var oop = require("../lib/oop");
            +var event = require("../lib/event");
            +var Tooltip = require("../tooltip").Tooltip;
            +
            +function GutterHandler(mouseHandler) {
            +    var editor = mouseHandler.editor;
            +    var gutter = editor.renderer.$gutterLayer;
            +    var tooltip = new GutterTooltip(editor.container);
            +
            +    mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
            +        if (!editor.isFocused() || e.getButton() != 0)
            +            return;
            +        var gutterRegion = gutter.getRegion(e);
            +
            +        if (gutterRegion == "foldWidgets")
            +            return;
            +
            +        var row = e.getDocumentPosition().row;
            +        var selection = editor.session.selection;
            +
            +        if (e.getShiftKey())
            +            selection.selectTo(row, 0);
            +        else {
            +            if (e.domEvent.detail == 2) {
            +                editor.selectAll();
            +                return e.preventDefault();
            +            }
            +            mouseHandler.$clickSelection = editor.selection.getLineRange(row);
            +        }
            +        mouseHandler.setState("selectByLines");
            +        mouseHandler.captureMouse(e);
            +        return e.preventDefault();
            +    });
            +
            +
            +    var tooltipTimeout, mouseEvent, tooltipAnnotation;
            +
            +    function showTooltip() {
            +        var row = mouseEvent.getDocumentPosition().row;
            +        var annotation = gutter.$annotations[row];
            +        if (!annotation)
            +            return hideTooltip();
            +
            +        var maxRow = editor.session.getLength();
            +        if (row == maxRow) {
            +            var screenRow = editor.renderer.pixelToScreenCoordinates(0, mouseEvent.y).row;
            +            var pos = mouseEvent.$pos;
            +            if (screenRow > editor.session.documentToScreenRow(pos.row, pos.column))
            +                return hideTooltip();
            +        }
            +
            +        if (tooltipAnnotation == annotation)
            +            return;
            +        tooltipAnnotation = annotation.text.join("<br/>");
            +
            +        tooltip.setHtml(tooltipAnnotation);
            +        tooltip.show();
            +        editor.on("mousewheel", hideTooltip);
            +
            +        if (mouseHandler.$tooltipFollowsMouse) {
            +            moveTooltip(mouseEvent);
            +        } else {
            +            var gutterElement = gutter.$cells[editor.session.documentToScreenRow(row, 0)].element;
            +            var rect = gutterElement.getBoundingClientRect();
            +            var style = tooltip.getElement().style;
            +            style.left = rect.right + "px";
            +            style.top = rect.bottom + "px";
            +        }
            +    }
            +
            +    function hideTooltip() {
            +        if (tooltipTimeout)
            +            tooltipTimeout = clearTimeout(tooltipTimeout);
            +        if (tooltipAnnotation) {
            +            tooltip.hide();
            +            tooltipAnnotation = null;
            +            editor.removeEventListener("mousewheel", hideTooltip);
            +        }
            +    }
            +
            +    function moveTooltip(e) {
            +        tooltip.setPosition(e.x, e.y);
            +    }
            +
            +    mouseHandler.editor.setDefaultHandler("guttermousemove", function(e) {
            +        var target = e.domEvent.target || e.domEvent.srcElement;
            +        if (dom.hasCssClass(target, "ace_fold-widget"))
            +            return hideTooltip();
            +
            +        if (tooltipAnnotation && mouseHandler.$tooltipFollowsMouse)
            +            moveTooltip(e);
            +
            +        mouseEvent = e;
            +        if (tooltipTimeout)
            +            return;
            +        tooltipTimeout = setTimeout(function() {
            +            tooltipTimeout = null;
            +            if (mouseEvent && !mouseHandler.isMousePressed)
            +                showTooltip();
            +            else
            +                hideTooltip();
            +        }, 50);
            +    });
            +
            +    event.addListener(editor.renderer.$gutter, "mouseout", function(e) {
            +        mouseEvent = null;
            +        if (!tooltipAnnotation || tooltipTimeout)
            +            return;
            +
            +        tooltipTimeout = setTimeout(function() {
            +            tooltipTimeout = null;
            +            hideTooltip();
            +        }, 50);
            +    });
            +    
            +    editor.on("changeSession", hideTooltip);
            +}
            +
            +function GutterTooltip(parentNode) {
            +    Tooltip.call(this, parentNode);
            +}
            +
            +oop.inherits(GutterTooltip, Tooltip);
            +
            +(function(){
            +    this.setPosition = function(x, y) {
            +        var windowWidth = window.innerWidth || document.documentElement.clientWidth;
            +        var windowHeight = window.innerHeight || document.documentElement.clientHeight;
            +        var width = this.getWidth();
            +        var height = this.getHeight();
            +        x += 15;
            +        y += 15;
            +        if (x + width > windowWidth) {
            +            x -= (x + width) - windowWidth;
            +        }
            +        if (y + height > windowHeight) {
            +            y -= 20 + height;
            +        }
            +        Tooltip.prototype.setPosition.call(this, x, y);
            +    };
            +
            +}).call(GutterTooltip.prototype);
            +
            +
            +
            +exports.GutterHandler = GutterHandler;
            +
            +});
            +
            +define("ace/mouse/mouse_event",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(require, exports, module) {
            +"use strict";
            +
            +var event = require("../lib/event");
            +var useragent = require("../lib/useragent");
            +var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
            +    this.domEvent = domEvent;
            +    this.editor = editor;
            +    
            +    this.x = this.clientX = domEvent.clientX;
            +    this.y = this.clientY = domEvent.clientY;
            +
            +    this.$pos = null;
            +    this.$inSelection = null;
            +    
            +    this.propagationStopped = false;
            +    this.defaultPrevented = false;
            +};
            +
            +(function() {  
            +    
            +    this.stopPropagation = function() {
            +        event.stopPropagation(this.domEvent);
            +        this.propagationStopped = true;
            +    };
            +    
            +    this.preventDefault = function() {
            +        event.preventDefault(this.domEvent);
            +        this.defaultPrevented = true;
            +    };
            +    
            +    this.stop = function() {
            +        this.stopPropagation();
            +        this.preventDefault();
            +    };
            +    this.getDocumentPosition = function() {
            +        if (this.$pos)
            +            return this.$pos;
            +        
            +        this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);
            +        return this.$pos;
            +    };
            +    this.inSelection = function() {
            +        if (this.$inSelection !== null)
            +            return this.$inSelection;
            +            
            +        var editor = this.editor;
            +        
            +
            +        var selectionRange = editor.getSelectionRange();
            +        if (selectionRange.isEmpty())
            +            this.$inSelection = false;
            +        else {
            +            var pos = this.getDocumentPosition();
            +            this.$inSelection = selectionRange.contains(pos.row, pos.column);
            +        }
            +
            +        return this.$inSelection;
            +    };
            +    this.getButton = function() {
            +        return event.getButton(this.domEvent);
            +    };
            +    this.getShiftKey = function() {
            +        return this.domEvent.shiftKey;
            +    };
            +    
            +    this.getAccelKey = useragent.isMac
            +        ? function() { return this.domEvent.metaKey; }
            +        : function() { return this.domEvent.ctrlKey; };
            +    
            +}).call(MouseEvent.prototype);
            +
            +});
            +
            +define("ace/mouse/dragdrop_handler",["require","exports","module","ace/lib/dom","ace/lib/event","ace/lib/useragent"], function(require, exports, module) {
            +"use strict";
            +
            +var dom = require("../lib/dom");
            +var event = require("../lib/event");
            +var useragent = require("../lib/useragent");
            +
            +var AUTOSCROLL_DELAY = 200;
            +var SCROLL_CURSOR_DELAY = 200;
            +var SCROLL_CURSOR_HYSTERESIS = 5;
            +
            +function DragdropHandler(mouseHandler) {
            +
            +    var editor = mouseHandler.editor;
            +
            +    var blankImage = dom.createElement("img");
            +    blankImage.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
            +    if (useragent.isOpera)
            +        blankImage.style.cssText = "width:1px;height:1px;position:fixed;top:0;left:0;z-index:2147483647;opacity:0;";
            +
            +    var exports = ["dragWait", "dragWaitEnd", "startDrag", "dragReadyEnd", "onMouseDrag"];
            +
            +     exports.forEach(function(x) {
            +         mouseHandler[x] = this[x];
            +    }, this);
            +    editor.addEventListener("mousedown", this.onMouseDown.bind(mouseHandler));
            +
            +
            +    var mouseTarget = editor.container;
            +    var dragSelectionMarker, x, y;
            +    var timerId, range;
            +    var dragCursor, counter = 0;
            +    var dragOperation;
            +    var isInternal;
            +    var autoScrollStartTime;
            +    var cursorMovedTime;
            +    var cursorPointOnCaretMoved;
            +
            +    this.onDragStart = function(e) {
            +        if (this.cancelDrag || !mouseTarget.draggable) {
            +            var self = this;
            +            setTimeout(function(){
            +                self.startSelect();
            +                self.captureMouse(e);
            +            }, 0);
            +            return e.preventDefault();
            +        }
            +        range = editor.getSelectionRange();
            +
            +        var dataTransfer = e.dataTransfer;
            +        dataTransfer.effectAllowed = editor.getReadOnly() ? "copy" : "copyMove";
            +        if (useragent.isOpera) {
            +            editor.container.appendChild(blankImage);
            +            blankImage._top = blankImage.offsetTop;
            +        }
            +        dataTransfer.setDragImage && dataTransfer.setDragImage(blankImage, 0, 0);
            +        if (useragent.isOpera) {
            +            editor.container.removeChild(blankImage);
            +        }
            +        dataTransfer.clearData();
            +        dataTransfer.setData("Text", editor.session.getTextRange());
            +
            +        isInternal = true;
            +        this.setState("drag");
            +    };
            +
            +    this.onDragEnd = function(e) {
            +        mouseTarget.draggable = false;
            +        isInternal = false;
            +        this.setState(null);
            +        if (!editor.getReadOnly()) {
            +            var dropEffect = e.dataTransfer.dropEffect;
            +            if (!dragOperation && dropEffect == "move")
            +                editor.session.remove(editor.getSelectionRange());
            +            editor.renderer.$cursorLayer.setBlinking(true);
            +        }
            +        this.editor.unsetStyle("ace_dragging");
            +    };
            +
            +    this.onDragEnter = function(e) {
            +        if (editor.getReadOnly() || !canAccept(e.dataTransfer))
            +            return;
            +        if (!dragSelectionMarker)
            +            addDragMarker();
            +        counter++;
            +        e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);
            +        return event.preventDefault(e);
            +    };
            +
            +    this.onDragOver = function(e) {
            +        if (editor.getReadOnly() || !canAccept(e.dataTransfer))
            +            return;
            +        if (!dragSelectionMarker) {
            +            addDragMarker();
            +            counter++;
            +        }
            +        if (onMouseMoveTimer !== null)
            +            onMouseMoveTimer = null;
            +        x = e.clientX;
            +        y = e.clientY;
            +
            +        e.dataTransfer.dropEffect = dragOperation = getDropEffect(e);
            +        return event.preventDefault(e);
            +    };
            +
            +    this.onDragLeave = function(e) {
            +        counter--;
            +        if (counter <= 0 && dragSelectionMarker) {
            +            clearDragMarker();
            +            dragOperation = null;
            +            return event.preventDefault(e);
            +        }
            +    };
            +
            +    this.onDrop = function(e) {
            +        if (!dragSelectionMarker)
            +            return;
            +        var dataTransfer = e.dataTransfer;
            +        if (isInternal) {
            +            switch (dragOperation) {
            +                case "move":
            +                    if (range.contains(dragCursor.row, dragCursor.column)) {
            +                        range = {
            +                            start: dragCursor,
            +                            end: dragCursor
            +                        };
            +                    } else {
            +                        range = editor.moveText(range, dragCursor);
            +                    }
            +                    break;
            +                case "copy":
            +                    range = editor.moveText(range, dragCursor, true);
            +                    break;
            +            }
            +        } else {
            +            var dropData = dataTransfer.getData('Text');
            +            range = {
            +                start: dragCursor,
            +                end: editor.session.insert(dragCursor, dropData)
            +            };
            +            editor.focus();
            +            dragOperation = null;
            +        }
            +        clearDragMarker();
            +        return event.preventDefault(e);
            +    };
            +
            +    event.addListener(mouseTarget, "dragstart", this.onDragStart.bind(mouseHandler));
            +    event.addListener(mouseTarget, "dragend", this.onDragEnd.bind(mouseHandler));
            +    event.addListener(mouseTarget, "dragenter", this.onDragEnter.bind(mouseHandler));
            +    event.addListener(mouseTarget, "dragover", this.onDragOver.bind(mouseHandler));
            +    event.addListener(mouseTarget, "dragleave", this.onDragLeave.bind(mouseHandler));
            +    event.addListener(mouseTarget, "drop", this.onDrop.bind(mouseHandler));
            +
            +    function scrollCursorIntoView(cursor, prevCursor) {
            +        var now = Date.now();
            +        var vMovement = !prevCursor || cursor.row != prevCursor.row;
            +        var hMovement = !prevCursor || cursor.column != prevCursor.column;
            +        if (!cursorMovedTime || vMovement || hMovement) {
            +            editor.$blockScrolling += 1;
            +            editor.moveCursorToPosition(cursor);
            +            editor.$blockScrolling -= 1;
            +            cursorMovedTime = now;
            +            cursorPointOnCaretMoved = {x: x, y: y};
            +        } else {
            +            var distance = calcDistance(cursorPointOnCaretMoved.x, cursorPointOnCaretMoved.y, x, y);
            +            if (distance > SCROLL_CURSOR_HYSTERESIS) {
            +                cursorMovedTime = null;
            +            } else if (now - cursorMovedTime >= SCROLL_CURSOR_DELAY) {
            +                editor.renderer.scrollCursorIntoView();
            +                cursorMovedTime = null;
            +            }
            +        }
            +    }
            +
            +    function autoScroll(cursor, prevCursor) {
            +        var now = Date.now();
            +        var lineHeight = editor.renderer.layerConfig.lineHeight;
            +        var characterWidth = editor.renderer.layerConfig.characterWidth;
            +        var editorRect = editor.renderer.scroller.getBoundingClientRect();
            +        var offsets = {
            +           x: {
            +               left: x - editorRect.left,
            +               right: editorRect.right - x
            +           },
            +           y: {
            +               top: y - editorRect.top,
            +               bottom: editorRect.bottom - y
            +           }
            +        };
            +        var nearestXOffset = Math.min(offsets.x.left, offsets.x.right);
            +        var nearestYOffset = Math.min(offsets.y.top, offsets.y.bottom);
            +        var scrollCursor = {row: cursor.row, column: cursor.column};
            +        if (nearestXOffset / characterWidth <= 2) {
            +            scrollCursor.column += (offsets.x.left < offsets.x.right ? -3 : +2);
            +        }
            +        if (nearestYOffset / lineHeight <= 1) {
            +            scrollCursor.row += (offsets.y.top < offsets.y.bottom ? -1 : +1);
            +        }
            +        var vScroll = cursor.row != scrollCursor.row;
            +        var hScroll = cursor.column != scrollCursor.column;
            +        var vMovement = !prevCursor || cursor.row != prevCursor.row;
            +        if (vScroll || (hScroll && !vMovement)) {
            +            if (!autoScrollStartTime)
            +                autoScrollStartTime = now;
            +            else if (now - autoScrollStartTime >= AUTOSCROLL_DELAY)
            +                editor.renderer.scrollCursorIntoView(scrollCursor);
            +        } else {
            +            autoScrollStartTime = null;
            +        }
            +    }
            +
            +    function onDragInterval() {
            +        var prevCursor = dragCursor;
            +        dragCursor = editor.renderer.screenToTextCoordinates(x, y);
            +        scrollCursorIntoView(dragCursor, prevCursor);
            +        autoScroll(dragCursor, prevCursor);
            +    }
            +
            +    function addDragMarker() {
            +        range = editor.selection.toOrientedRange();
            +        dragSelectionMarker = editor.session.addMarker(range, "ace_selection", editor.getSelectionStyle());
            +        editor.clearSelection();
            +        if (editor.isFocused())
            +            editor.renderer.$cursorLayer.setBlinking(false);
            +        clearInterval(timerId);
            +        timerId = setInterval(onDragInterval, 20);
            +        counter = 0;
            +        event.addListener(document, "mousemove", onMouseMove);
            +    }
            +
            +    function clearDragMarker() {
            +        clearInterval(timerId);
            +        editor.session.removeMarker(dragSelectionMarker);
            +        dragSelectionMarker = null;
            +        editor.$blockScrolling += 1;
            +        editor.selection.fromOrientedRange(range);
            +        editor.$blockScrolling -= 1;
            +        if (editor.isFocused() && !isInternal)
            +            editor.renderer.$cursorLayer.setBlinking(!editor.getReadOnly());
            +        range = null;
            +        counter = 0;
            +        autoScrollStartTime = null;
            +        cursorMovedTime = null;
            +        event.removeListener(document, "mousemove", onMouseMove);
            +    }
            +    var onMouseMoveTimer = null;
            +    function onMouseMove() {
            +        if (onMouseMoveTimer == null) {
            +            onMouseMoveTimer = setTimeout(function() {
            +                if (onMouseMoveTimer != null && dragSelectionMarker)
            +                    clearDragMarker();
            +            }, 20);
            +        }
            +    }
            +
            +    function canAccept(dataTransfer) {
            +        var types = dataTransfer.types;
            +        return !types || Array.prototype.some.call(types, function(type) {
            +            return type == 'text/plain' || type == 'Text';
            +        });
            +    }
            +
            +    function getDropEffect(e) {
            +        var copyAllowed = ['copy', 'copymove', 'all', 'uninitialized'];
            +        var moveAllowed = ['move', 'copymove', 'linkmove', 'all', 'uninitialized'];
            +
            +        var copyModifierState = useragent.isMac ? e.altKey : e.ctrlKey;
            +        var effectAllowed = "uninitialized";
            +        try {
            +            effectAllowed = e.dataTransfer.effectAllowed.toLowerCase();
            +        } catch (e) {}
            +        var dropEffect = "none";
            +
            +        if (copyModifierState && copyAllowed.indexOf(effectAllowed) >= 0)
            +            dropEffect = "copy";
            +        else if (moveAllowed.indexOf(effectAllowed) >= 0)
            +            dropEffect = "move";
            +        else if (copyAllowed.indexOf(effectAllowed) >= 0)
            +            dropEffect = "copy";
            +
            +        return dropEffect;
            +    }
            +}
            +
            +(function() {
            +
            +    this.dragWait = function() {
            +        var interval = Date.now() - this.mousedownEvent.time;
            +        if (interval > this.editor.getDragDelay())
            +            this.startDrag();
            +    };
            +
            +    this.dragWaitEnd = function() {
            +        var target = this.editor.container;
            +        target.draggable = false;
            +        this.startSelect(this.mousedownEvent.getDocumentPosition());
            +        this.selectEnd();
            +    };
            +
            +    this.dragReadyEnd = function(e) {
            +        this.editor.renderer.$cursorLayer.setBlinking(!this.editor.getReadOnly());
            +        this.editor.unsetStyle("ace_dragging");
            +        this.dragWaitEnd();
            +    };
            +
            +    this.startDrag = function(){
            +        this.cancelDrag = false;
            +        var target = this.editor.container;
            +        target.draggable = true;
            +        this.editor.renderer.$cursorLayer.setBlinking(false);
            +        this.editor.setStyle("ace_dragging");
            +        this.setState("dragReady");
            +    };
            +
            +    this.onMouseDrag = function(e) {
            +        var target = this.editor.container;
            +        if (useragent.isIE && this.state == "dragReady") {
            +            var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
            +            if (distance > 3)
            +                target.dragDrop();
            +        }
            +        if (this.state === "dragWait") {
            +            var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
            +            if (distance > 0) {
            +                target.draggable = false;
            +                this.startSelect(this.mousedownEvent.getDocumentPosition());
            +            }
            +        }
            +    };
            +
            +    this.onMouseDown = function(e) {
            +        if (!this.$dragEnabled)
            +            return;
            +        this.mousedownEvent = e;
            +        var editor = this.editor;
            +
            +        var inSelection = e.inSelection();
            +        var button = e.getButton();
            +        var clickCount = e.domEvent.detail || 1;
            +        if (clickCount === 1 && button === 0 && inSelection) {
            +            if (e.editor.inMultiSelectMode && (e.getAccelKey() || e.getShiftKey()))
            +                return;
            +            this.mousedownEvent.time = Date.now();
            +            var eventTarget = e.domEvent.target || e.domEvent.srcElement;
            +            if ("unselectable" in eventTarget)
            +                eventTarget.unselectable = "on";
            +            if (editor.getDragDelay()) {
            +                if (useragent.isWebKit) {
            +                    this.cancelDrag = true;
            +                    var mouseTarget = editor.container;
            +                    mouseTarget.draggable = true;
            +                }
            +                this.setState("dragWait");
            +            } else {
            +                this.startDrag();
            +            }
            +            this.captureMouse(e, this.onMouseDrag.bind(this));
            +            e.defaultPrevented = true;
            +        }
            +    };
            +
            +}).call(DragdropHandler.prototype);
            +
            +
            +function calcDistance(ax, ay, bx, by) {
            +    return Math.sqrt(Math.pow(bx - ax, 2) + Math.pow(by - ay, 2));
            +}
            +
            +exports.DragdropHandler = DragdropHandler;
            +
            +});
            +
            +define("ace/lib/net",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
            +"use strict";
            +var dom = require("./dom");
            +
            +exports.get = function (url, callback) {
            +    var xhr = new XMLHttpRequest();
            +    xhr.open('GET', url, true);
            +    xhr.onreadystatechange = function () {
            +        if (xhr.readyState === 4) {
            +            callback(xhr.responseText);
            +        }
            +    };
            +    xhr.send(null);
            +};
            +
            +exports.loadScript = function(path, callback) {
            +    var head = dom.getDocumentHead();
            +    var s = document.createElement('script');
            +
            +    s.src = path;
            +    head.appendChild(s);
            +
            +    s.onload = s.onreadystatechange = function(_, isAbort) {
            +        if (isAbort || !s.readyState || s.readyState == "loaded" || s.readyState == "complete") {
            +            s = s.onload = s.onreadystatechange = null;
            +            if (!isAbort)
            +                callback();
            +        }
            +    };
            +};
            +exports.qualifyURL = function(url) {
            +    var a = document.createElement('a');
            +    a.href = url;
            +    return a.href;
            +}
            +
            +});
            +
            +define("ace/lib/event_emitter",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +
            +var EventEmitter = {};
            +var stopPropagation = function() { this.propagationStopped = true; };
            +var preventDefault = function() { this.defaultPrevented = true; };
            +
            +EventEmitter._emit =
            +EventEmitter._dispatchEvent = function(eventName, e) {
            +    this._eventRegistry || (this._eventRegistry = {});
            +    this._defaultHandlers || (this._defaultHandlers = {});
            +
            +    var listeners = this._eventRegistry[eventName] || [];
            +    var defaultHandler = this._defaultHandlers[eventName];
            +    if (!listeners.length && !defaultHandler)
            +        return;
            +
            +    if (typeof e != "object" || !e)
            +        e = {};
            +
            +    if (!e.type)
            +        e.type = eventName;
            +    if (!e.stopPropagation)
            +        e.stopPropagation = stopPropagation;
            +    if (!e.preventDefault)
            +        e.preventDefault = preventDefault;
            +
            +    listeners = listeners.slice();
            +    for (var i=0; i<listeners.length; i++) {
            +        listeners[i](e, this);
            +        if (e.propagationStopped)
            +            break;
            +    }
            +    
            +    if (defaultHandler && !e.defaultPrevented)
            +        return defaultHandler(e, this);
            +};
            +
            +
            +EventEmitter._signal = function(eventName, e) {
            +    var listeners = (this._eventRegistry || {})[eventName];
            +    if (!listeners)
            +        return;
            +    listeners = listeners.slice();
            +    for (var i=0; i<listeners.length; i++)
            +        listeners[i](e, this);
            +};
            +
            +EventEmitter.once = function(eventName, callback) {
            +    var _self = this;
            +    callback && this.addEventListener(eventName, function newCallback() {
            +        _self.removeEventListener(eventName, newCallback);
            +        callback.apply(null, arguments);
            +    });
            +};
            +
            +
            +EventEmitter.setDefaultHandler = function(eventName, callback) {
            +    var handlers = this._defaultHandlers
            +    if (!handlers)
            +        handlers = this._defaultHandlers = {_disabled_: {}};
            +    
            +    if (handlers[eventName]) {
            +        var old = handlers[eventName];
            +        var disabled = handlers._disabled_[eventName];
            +        if (!disabled)
            +            handlers._disabled_[eventName] = disabled = [];
            +        disabled.push(old);
            +        var i = disabled.indexOf(callback);
            +        if (i != -1) 
            +            disabled.splice(i, 1);
            +    }
            +    handlers[eventName] = callback;
            +};
            +EventEmitter.removeDefaultHandler = function(eventName, callback) {
            +    var handlers = this._defaultHandlers
            +    if (!handlers)
            +        return;
            +    var disabled = handlers._disabled_[eventName];
            +    
            +    if (handlers[eventName] == callback) {
            +        var old = handlers[eventName];
            +        if (disabled)
            +            this.setDefaultHandler(eventName, disabled.pop());
            +    } else if (disabled) {
            +        var i = disabled.indexOf(callback);
            +        if (i != -1)
            +            disabled.splice(i, 1);
            +    }
            +};
            +
            +EventEmitter.on =
            +EventEmitter.addEventListener = function(eventName, callback, capturing) {
            +    this._eventRegistry = this._eventRegistry || {};
            +
            +    var listeners = this._eventRegistry[eventName];
            +    if (!listeners)
            +        listeners = this._eventRegistry[eventName] = [];
            +
            +    if (listeners.indexOf(callback) == -1)
            +        listeners[capturing ? "unshift" : "push"](callback);
            +    return callback;
            +};
            +
            +EventEmitter.off =
            +EventEmitter.removeListener =
            +EventEmitter.removeEventListener = function(eventName, callback) {
            +    this._eventRegistry = this._eventRegistry || {};
            +
            +    var listeners = this._eventRegistry[eventName];
            +    if (!listeners)
            +        return;
            +
            +    var index = listeners.indexOf(callback);
            +    if (index !== -1)
            +        listeners.splice(index, 1);
            +};
            +
            +EventEmitter.removeAllListeners = function(eventName) {
            +    if (this._eventRegistry) this._eventRegistry[eventName] = [];
            +};
            +
            +exports.EventEmitter = EventEmitter;
            +
            +});
            +
            +define("ace/config",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/lib/net","ace/lib/event_emitter"], function(require, exports, module) {
            +"no use strict";
            +
            +var lang = require("./lib/lang");
            +var oop = require("./lib/oop");
            +var net = require("./lib/net");
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +
            +var global = (function() {
            +    return this;
            +})();
            +
            +var options = {
            +    packaged: false,
            +    workerPath: null,
            +    modePath: null,
            +    themePath: null,
            +    basePath: "",
            +    suffix: ".js",
            +    $moduleUrls: {}
            +};
            +
            +exports.get = function(key) {
            +    if (!options.hasOwnProperty(key))
            +        throw new Error("Unknown config key: " + key);
            +
            +    return options[key];
            +};
            +
            +exports.set = function(key, value) {
            +    if (!options.hasOwnProperty(key))
            +        throw new Error("Unknown config key: " + key);
            +
            +    options[key] = value;
            +};
            +
            +exports.all = function() {
            +    return lang.copyObject(options);
            +};
            +oop.implement(exports, EventEmitter);
            +
            +exports.moduleUrl = function(name, component) {
            +    if (options.$moduleUrls[name])
            +        return options.$moduleUrls[name];
            +
            +    var parts = name.split("/");
            +    component = component || parts[parts.length - 2] || "";
            +    var sep = component == "snippets" ? "/" : "-";
            +    var base = parts[parts.length - 1];    
            +    if (sep == "-") {
            +        var re = new RegExp("^" + component + "[\\-_]|[\\-_]" + component + "$", "g");
            +        base = base.replace(re, "");
            +    }
            +
            +    if ((!base || base == component) && parts.length > 1)
            +        base = parts[parts.length - 2];
            +    var path = options[component + "Path"];
            +    if (path == null) {
            +        path = options.basePath;
            +    } else if (sep == "/") {
            +        component = sep = "";
            +    }
            +    if (path && path.slice(-1) != "/")
            +        path += "/";
            +    return path + component + sep + base + this.get("suffix");
            +};
            +
            +exports.setModuleUrl = function(name, subst) {
            +    return options.$moduleUrls[name] = subst;
            +};
            +
            +exports.$loading = {};
            +exports.loadModule = function(moduleName, onLoad) {
            +    var module, moduleType;
            +    if (Array.isArray(moduleName)) {
            +        moduleType = moduleName[0];
            +        moduleName = moduleName[1];
            +    }
            +
            +    try {
            +        module = require(moduleName);
            +    } catch (e) {}
            +    if (module && !exports.$loading[moduleName])
            +        return onLoad && onLoad(module);
            +
            +    if (!exports.$loading[moduleName])
            +        exports.$loading[moduleName] = [];
            +
            +    exports.$loading[moduleName].push(onLoad);
            +
            +    if (exports.$loading[moduleName].length > 1)
            +        return;
            +
            +    var afterLoad = function() {
            +        require([moduleName], function(module) {
            +            exports._emit("load.module", {name: moduleName, module: module});
            +            var listeners = exports.$loading[moduleName];
            +            exports.$loading[moduleName] = null;
            +            listeners.forEach(function(onLoad) {
            +                onLoad && onLoad(module);
            +            });
            +        });
            +    };
            +
            +    if (!exports.get("packaged"))
            +        return afterLoad();
            +    net.loadScript(exports.moduleUrl(moduleName, moduleType), afterLoad);
            +};
            +init(true);function init(packaged) {
            +
            +    options.packaged = packaged || require.packaged || module.packaged || (global.define && define.packaged);
            +
            +    if (!global.document)
            +        return "";
            +
            +    var scriptOptions = {};
            +    var scriptUrl = "";
            +    var currentScript = (document.currentScript || document._currentScript ); // native or polyfill
            +    var currentDocument = currentScript && currentScript.ownerDocument || document;
            +    
            +    var scripts = currentDocument.getElementsByTagName("script");
            +    for (var i=0; i<scripts.length; i++) {
            +        var script = scripts[i];
            +
            +        var src = script.src || script.getAttribute("src");
            +        if (!src)
            +            continue;
            +
            +        var attributes = script.attributes;
            +        for (var j=0, l=attributes.length; j < l; j++) {
            +            var attr = attributes[j];
            +            if (attr.name.indexOf("data-ace-") === 0) {
            +                scriptOptions[deHyphenate(attr.name.replace(/^data-ace-/, ""))] = attr.value;
            +            }
            +        }
            +
            +        var m = src.match(/^(.*)\/ace(\-\w+)?\.js(\?|$)/);
            +        if (m)
            +            scriptUrl = m[1];
            +    }
            +
            +    if (scriptUrl) {
            +        scriptOptions.base = scriptOptions.base || scriptUrl;
            +        scriptOptions.packaged = true;
            +    }
            +
            +    scriptOptions.basePath = scriptOptions.base;
            +    scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;
            +    scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;
            +    scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;
            +    delete scriptOptions.base;
            +
            +    for (var key in scriptOptions)
            +        if (typeof scriptOptions[key] !== "undefined")
            +            exports.set(key, scriptOptions[key]);
            +};
            +
            +exports.init = init;
            +
            +function deHyphenate(str) {
            +    return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
            +}
            +
            +var optionsProvider = {
            +    setOptions: function(optList) {
            +        Object.keys(optList).forEach(function(key) {
            +            this.setOption(key, optList[key]);
            +        }, this);
            +    },
            +    getOptions: function(optionNames) {
            +        var result = {};
            +        if (!optionNames) {
            +            optionNames = Object.keys(this.$options);
            +        } else if (!Array.isArray(optionNames)) {
            +            result = optionNames;
            +            optionNames = Object.keys(result);
            +        }
            +        optionNames.forEach(function(key) {
            +            result[key] = this.getOption(key);
            +        }, this);
            +        return result;
            +    },
            +    setOption: function(name, value) {
            +        if (this["$" + name] === value)
            +            return;
            +        var opt = this.$options[name];
            +        if (!opt) {
            +            if (typeof console != "undefined" && console.warn)
            +                console.warn('misspelled option "' + name + '"');
            +            return undefined;
            +        }
            +        if (opt.forwardTo)
            +            return this[opt.forwardTo] && this[opt.forwardTo].setOption(name, value);
            +
            +        if (!opt.handlesSet)
            +            this["$" + name] = value;
            +        if (opt && opt.set)
            +            opt.set.call(this, value);
            +    },
            +    getOption: function(name) {
            +        var opt = this.$options[name];
            +        if (!opt) {
            +            if (typeof console != "undefined" && console.warn)
            +                console.warn('misspelled option "' + name + '"');
            +            return undefined;
            +        }
            +        if (opt.forwardTo)
            +            return this[opt.forwardTo] && this[opt.forwardTo].getOption(name);
            +        return opt && opt.get ? opt.get.call(this) : this["$" + name];
            +    }
            +};
            +
            +var defaultOptions = {};
            +exports.defineOptions = function(obj, path, options) {
            +    if (!obj.$options)
            +        defaultOptions[path] = obj.$options = {};
            +
            +    Object.keys(options).forEach(function(key) {
            +        var opt = options[key];
            +        if (typeof opt == "string")
            +            opt = {forwardTo: opt};
            +
            +        opt.name || (opt.name = key);
            +        obj.$options[opt.name] = opt;
            +        if ("initialValue" in opt)
            +            obj["$" + opt.name] = opt.initialValue;
            +    });
            +    oop.implement(obj, optionsProvider);
            +
            +    return this;
            +};
            +
            +exports.resetOptions = function(obj) {
            +    Object.keys(obj.$options).forEach(function(key) {
            +        var opt = obj.$options[key];
            +        if ("value" in opt)
            +            obj.setOption(key, opt.value);
            +    });
            +};
            +
            +exports.setDefaultValue = function(path, name, value) {
            +    var opts = defaultOptions[path] || (defaultOptions[path] = {});
            +    if (opts[name]) {
            +        if (opts.forwardTo)
            +            exports.setDefaultValue(opts.forwardTo, name, value);
            +        else
            +            opts[name].value = value;
            +    }
            +};
            +
            +exports.setDefaultValues = function(path, optionHash) {
            +    Object.keys(optionHash).forEach(function(key) {
            +        exports.setDefaultValue(path, key, optionHash[key]);
            +    });
            +};
            +
            +});
            +
            +define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/lib/useragent","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event","ace/mouse/dragdrop_handler","ace/config"], function(require, exports, module) {
            +"use strict";
            +
            +var event = require("../lib/event");
            +var useragent = require("../lib/useragent");
            +var DefaultHandlers = require("./default_handlers").DefaultHandlers;
            +var DefaultGutterHandler = require("./default_gutter_handler").GutterHandler;
            +var MouseEvent = require("./mouse_event").MouseEvent;
            +var DragdropHandler = require("./dragdrop_handler").DragdropHandler;
            +var config = require("../config");
            +
            +var MouseHandler = function(editor) {
            +    var _self = this;
            +    this.editor = editor;
            +
            +    new DefaultHandlers(this);
            +    new DefaultGutterHandler(this);
            +    new DragdropHandler(this);
            +    
            +    var focusEditor = function(e) { 
            +        if (!editor.isFocused() && editor.textInput)
            +            editor.textInput.moveToMouse(e);
            +        editor.focus() 
            +    };
            +    
            +    var mouseTarget = editor.renderer.getMouseEventTarget();
            +    event.addListener(mouseTarget, "click", this.onMouseEvent.bind(this, "click"));
            +    event.addListener(mouseTarget, "mousemove", this.onMouseMove.bind(this, "mousemove"));
            +    event.addMultiMouseDownListener(mouseTarget, [400, 300, 250], this, "onMouseEvent");
            +    if (editor.renderer.scrollBarV) {
            +        event.addMultiMouseDownListener(editor.renderer.scrollBarV.inner, [400, 300, 250], this, "onMouseEvent");
            +        event.addMultiMouseDownListener(editor.renderer.scrollBarH.inner, [400, 300, 250], this, "onMouseEvent");
            +        if (useragent.isIE) {
            +            event.addListener(editor.renderer.scrollBarV.element, "mousedown", focusEditor);
            +            event.addListener(editor.renderer.scrollBarH.element, "mousemove", focusEditor);
            +        }
            +    }
            +    event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel"));
            +
            +    var gutterEl = editor.renderer.$gutter;
            +    event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown"));
            +    event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick"));
            +    event.addListener(gutterEl, "dblclick", this.onMouseEvent.bind(this, "gutterdblclick"));
            +    event.addListener(gutterEl, "mousemove", this.onMouseEvent.bind(this, "guttermousemove"));
            +
            +    event.addListener(mouseTarget, "mousedown", focusEditor);
            +
            +    event.addListener(gutterEl, "mousedown", function(e) {
            +        editor.focus();
            +        return event.preventDefault(e);
            +    });
            +
            +    editor.on("mousemove", function(e){
            +        if (_self.state || _self.$dragDelay || !_self.$dragEnabled)
            +            return;
            +        
            +        var char = editor.renderer.screenToTextCoordinates(e.x, e.y);
            +        var range = editor.session.selection.getRange();
            +        var renderer = editor.renderer;
            +
            +        if (!range.isEmpty() && range.insideStart(char.row, char.column)) {
            +            renderer.setCursorStyle("default");
            +        } else {
            +            renderer.setCursorStyle("");
            +        }
            +    });
            +};
            +
            +(function() {
            +    this.onMouseEvent = function(name, e) {
            +        this.editor._emit(name, new MouseEvent(e, this.editor));
            +    };
            +
            +    this.onMouseMove = function(name, e) {
            +        var listeners = this.editor._eventRegistry && this.editor._eventRegistry.mousemove;
            +        if (!listeners || !listeners.length)
            +            return;
            +
            +        this.editor._emit(name, new MouseEvent(e, this.editor));
            +    };
            +
            +    this.onMouseWheel = function(name, e) {
            +        var mouseEvent = new MouseEvent(e, this.editor);
            +        mouseEvent.speed = this.$scrollSpeed * 2;
            +        mouseEvent.wheelX = e.wheelX;
            +        mouseEvent.wheelY = e.wheelY;
            +
            +        this.editor._emit(name, mouseEvent);
            +    };
            +
            +    this.setState = function(state) {
            +        this.state = state;
            +    };
            +
            +    this.captureMouse = function(ev, mouseMoveHandler) {
            +        this.x = ev.x;
            +        this.y = ev.y;
            +
            +        this.isMousePressed = true;
            +        var renderer = this.editor.renderer;
            +        if (renderer.$keepTextAreaAtCursor)
            +            renderer.$keepTextAreaAtCursor = null;
            +
            +        var self = this;
            +        var onMouseMove = function(e) {
            +            if (!e) return;
            +            if (useragent.isWebKit && !e.which && self.releaseMouse)
            +                return self.releaseMouse();
            +
            +            self.x = e.clientX;
            +            self.y = e.clientY;
            +            mouseMoveHandler && mouseMoveHandler(e);
            +            self.mouseEvent = new MouseEvent(e, self.editor);
            +            self.$mouseMoved = true;
            +        };
            +
            +        var onCaptureEnd = function(e) {
            +            clearInterval(timerId);
            +            onCaptureInterval();
            +            self[self.state + "End"] && self[self.state + "End"](e);
            +            self.state = "";
            +            if (renderer.$keepTextAreaAtCursor == null) {
            +                renderer.$keepTextAreaAtCursor = true;
            +                renderer.$moveTextAreaToCursor();
            +            }
            +            self.isMousePressed = false;
            +            self.$onCaptureMouseMove = self.releaseMouse = null;
            +            e && self.onMouseEvent("mouseup", e);
            +        };
            +
            +        var onCaptureInterval = function() {
            +            self[self.state] && self[self.state]();
            +            self.$mouseMoved = false;
            +        };
            +
            +        if (useragent.isOldIE && ev.domEvent.type == "dblclick") {
            +            return setTimeout(function() {onCaptureEnd(ev);});
            +        }
            +
            +        self.$onCaptureMouseMove = onMouseMove;
            +        self.releaseMouse = event.capture(this.editor.container, onMouseMove, onCaptureEnd);
            +        var timerId = setInterval(onCaptureInterval, 20);
            +    };
            +    this.releaseMouse = null;
            +    this.cancelContextMenu = function() {
            +        var stop = function(e) {
            +            if (e && e.domEvent && e.domEvent.type != "contextmenu")
            +                return;
            +            this.editor.off("nativecontextmenu", stop);
            +            if (e && e.domEvent)
            +                event.stopEvent(e.domEvent);
            +        }.bind(this);
            +        setTimeout(stop, 10);
            +        this.editor.on("nativecontextmenu", stop);
            +    };
            +}).call(MouseHandler.prototype);
            +
            +config.defineOptions(MouseHandler.prototype, "mouseHandler", {
            +    scrollSpeed: {initialValue: 2},
            +    dragDelay: {initialValue: (useragent.isMac ? 150 : 0)},
            +    dragEnabled: {initialValue: true},
            +    focusTimout: {initialValue: 0},
            +    tooltipFollowsMouse: {initialValue: true}
            +});
            +
            +
            +exports.MouseHandler = MouseHandler;
            +});
            +
            +define("ace/mouse/fold_handler",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +
            +function FoldHandler(editor) {
            +
            +    editor.on("click", function(e) {
            +        var position = e.getDocumentPosition();
            +        var session = editor.session;
            +        var fold = session.getFoldAt(position.row, position.column, 1);
            +        if (fold) {
            +            if (e.getAccelKey())
            +                session.removeFold(fold);
            +            else
            +                session.expandFold(fold);
            +
            +            e.stop();
            +        }
            +    });
            +
            +    editor.on("gutterclick", function(e) {
            +        var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
            +
            +        if (gutterRegion == "foldWidgets") {
            +            var row = e.getDocumentPosition().row;
            +            var session = editor.session;
            +            if (session.foldWidgets && session.foldWidgets[row])
            +                editor.session.onFoldWidgetClick(row, e);
            +            if (!editor.isFocused())
            +                editor.focus();
            +            e.stop();
            +        }
            +    });
            +
            +    editor.on("gutterdblclick", function(e) {
            +        var gutterRegion = editor.renderer.$gutterLayer.getRegion(e);
            +
            +        if (gutterRegion == "foldWidgets") {
            +            var row = e.getDocumentPosition().row;
            +            var session = editor.session;
            +            var data = session.getParentFoldRangeData(row, true);
            +            var range = data.range || data.firstRange;
            +
            +            if (range) {
            +                row = range.start.row;
            +                var fold = session.getFoldAt(row, session.getLine(row).length, 1);
            +
            +                if (fold) {
            +                    session.removeFold(fold);
            +                } else {
            +                    session.addFold("...", range);
            +                    editor.renderer.scrollCursorIntoView({row: range.start.row, column: 0});
            +                }
            +            }
            +            e.stop();
            +        }
            +    });
            +}
            +
            +exports.FoldHandler = FoldHandler;
            +
            +});
            +
            +define("ace/keyboard/keybinding",["require","exports","module","ace/lib/keys","ace/lib/event"], function(require, exports, module) {
            +"use strict";
            +
            +var keyUtil  = require("../lib/keys");
            +var event = require("../lib/event");
            +
            +var KeyBinding = function(editor) {
            +    this.$editor = editor;
            +    this.$data = {editor: editor};
            +    this.$handlers = [];
            +    this.setDefaultHandler(editor.commands);
            +};
            +
            +(function() {
            +    this.setDefaultHandler = function(kb) {
            +        this.removeKeyboardHandler(this.$defaultHandler);
            +        this.$defaultHandler = kb;
            +        this.addKeyboardHandler(kb, 0);
            +    };
            +
            +    this.setKeyboardHandler = function(kb) {
            +        var h = this.$handlers;
            +        if (h[h.length - 1] == kb)
            +            return;
            +
            +        while (h[h.length - 1] && h[h.length - 1] != this.$defaultHandler)
            +            this.removeKeyboardHandler(h[h.length - 1]);
            +
            +        this.addKeyboardHandler(kb, 1);
            +    };
            +
            +    this.addKeyboardHandler = function(kb, pos) {
            +        if (!kb)
            +            return;
            +        if (typeof kb == "function" && !kb.handleKeyboard)
            +            kb.handleKeyboard = kb;
            +        var i = this.$handlers.indexOf(kb);
            +        if (i != -1)
            +            this.$handlers.splice(i, 1);
            +
            +        if (pos == undefined)
            +            this.$handlers.push(kb);
            +        else
            +            this.$handlers.splice(pos, 0, kb);
            +
            +        if (i == -1 && kb.attach)
            +            kb.attach(this.$editor);
            +    };
            +
            +    this.removeKeyboardHandler = function(kb) {
            +        var i = this.$handlers.indexOf(kb);
            +        if (i == -1)
            +            return false;
            +        this.$handlers.splice(i, 1);
            +        kb.detach && kb.detach(this.$editor);
            +        return true;
            +    };
            +
            +    this.getKeyboardHandler = function() {
            +        return this.$handlers[this.$handlers.length - 1];
            +    };
            +
            +    this.$callKeyboardHandlers = function (hashId, keyString, keyCode, e) {
            +        var toExecute;
            +        var success = false;
            +        var commands = this.$editor.commands;
            +
            +        for (var i = this.$handlers.length; i--;) {
            +            toExecute = this.$handlers[i].handleKeyboard(
            +                this.$data, hashId, keyString, keyCode, e
            +            );
            +            if (!toExecute || !toExecute.command)
            +                continue;
            +            if (toExecute.command == "null") {
            +                success = true;
            +            } else {
            +                success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);                
            +            }
            +            if (success && e && hashId != -1 && 
            +                toExecute.passEvent != true && toExecute.command.passEvent != true
            +            ) {
            +                event.stopEvent(e);
            +            }
            +            if (success)
            +                break;
            +        }
            +        return success;
            +    };
            +
            +    this.onCommandKey = function(e, hashId, keyCode) {
            +        var keyString = keyUtil.keyCodeToString(keyCode);
            +        this.$callKeyboardHandlers(hashId, keyString, keyCode, e);
            +    };
            +
            +    this.onTextInput = function(text) {
            +        var success = this.$callKeyboardHandlers(-1, text);
            +        if (!success)
            +            this.$editor.commands.exec("insertstring", this.$editor, text);
            +    };
            +
            +}).call(KeyBinding.prototype);
            +
            +exports.KeyBinding = KeyBinding;
            +});
            +
            +define("ace/range",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +var comparePoints = function(p1, p2) {
            +    return p1.row - p2.row || p1.column - p2.column;
            +};
            +var Range = function(startRow, startColumn, endRow, endColumn) {
            +    this.start = {
            +        row: startRow,
            +        column: startColumn
            +    };
            +
            +    this.end = {
            +        row: endRow,
            +        column: endColumn
            +    };
            +};
            +
            +(function() {
            +    this.isEqual = function(range) {
            +        return this.start.row === range.start.row &&
            +            this.end.row === range.end.row &&
            +            this.start.column === range.start.column &&
            +            this.end.column === range.end.column;
            +    };
            +    this.toString = function() {
            +        return ("Range: [" + this.start.row + "/" + this.start.column +
            +            "] -> [" + this.end.row + "/" + this.end.column + "]");
            +    };
            +
            +    this.contains = function(row, column) {
            +        return this.compare(row, column) == 0;
            +    };
            +    this.compareRange = function(range) {
            +        var cmp,
            +            end = range.end,
            +            start = range.start;
            +
            +        cmp = this.compare(end.row, end.column);
            +        if (cmp == 1) {
            +            cmp = this.compare(start.row, start.column);
            +            if (cmp == 1) {
            +                return 2;
            +            } else if (cmp == 0) {
            +                return 1;
            +            } else {
            +                return 0;
            +            }
            +        } else if (cmp == -1) {
            +            return -2;
            +        } else {
            +            cmp = this.compare(start.row, start.column);
            +            if (cmp == -1) {
            +                return -1;
            +            } else if (cmp == 1) {
            +                return 42;
            +            } else {
            +                return 0;
            +            }
            +        }
            +    };
            +    this.comparePoint = function(p) {
            +        return this.compare(p.row, p.column);
            +    };
            +    this.containsRange = function(range) {
            +        return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
            +    };
            +    this.intersects = function(range) {
            +        var cmp = this.compareRange(range);
            +        return (cmp == -1 || cmp == 0 || cmp == 1);
            +    };
            +    this.isEnd = function(row, column) {
            +        return this.end.row == row && this.end.column == column;
            +    };
            +    this.isStart = function(row, column) {
            +        return this.start.row == row && this.start.column == column;
            +    };
            +    this.setStart = function(row, column) {
            +        if (typeof row == "object") {
            +            this.start.column = row.column;
            +            this.start.row = row.row;
            +        } else {
            +            this.start.row = row;
            +            this.start.column = column;
            +        }
            +    };
            +    this.setEnd = function(row, column) {
            +        if (typeof row == "object") {
            +            this.end.column = row.column;
            +            this.end.row = row.row;
            +        } else {
            +            this.end.row = row;
            +            this.end.column = column;
            +        }
            +    };
            +    this.inside = function(row, column) {
            +        if (this.compare(row, column) == 0) {
            +            if (this.isEnd(row, column) || this.isStart(row, column)) {
            +                return false;
            +            } else {
            +                return true;
            +            }
            +        }
            +        return false;
            +    };
            +    this.insideStart = function(row, column) {
            +        if (this.compare(row, column) == 0) {
            +            if (this.isEnd(row, column)) {
            +                return false;
            +            } else {
            +                return true;
            +            }
            +        }
            +        return false;
            +    };
            +    this.insideEnd = function(row, column) {
            +        if (this.compare(row, column) == 0) {
            +            if (this.isStart(row, column)) {
            +                return false;
            +            } else {
            +                return true;
            +            }
            +        }
            +        return false;
            +    };
            +    this.compare = function(row, column) {
            +        if (!this.isMultiLine()) {
            +            if (row === this.start.row) {
            +                return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
            +            };
            +        }
            +
            +        if (row < this.start.row)
            +            return -1;
            +
            +        if (row > this.end.row)
            +            return 1;
            +
            +        if (this.start.row === row)
            +            return column >= this.start.column ? 0 : -1;
            +
            +        if (this.end.row === row)
            +            return column <= this.end.column ? 0 : 1;
            +
            +        return 0;
            +    };
            +    this.compareStart = function(row, column) {
            +        if (this.start.row == row && this.start.column == column) {
            +            return -1;
            +        } else {
            +            return this.compare(row, column);
            +        }
            +    };
            +    this.compareEnd = function(row, column) {
            +        if (this.end.row == row && this.end.column == column) {
            +            return 1;
            +        } else {
            +            return this.compare(row, column);
            +        }
            +    };
            +    this.compareInside = function(row, column) {
            +        if (this.end.row == row && this.end.column == column) {
            +            return 1;
            +        } else if (this.start.row == row && this.start.column == column) {
            +            return -1;
            +        } else {
            +            return this.compare(row, column);
            +        }
            +    };
            +    this.clipRows = function(firstRow, lastRow) {
            +        if (this.end.row > lastRow)
            +            var end = {row: lastRow + 1, column: 0};
            +        else if (this.end.row < firstRow)
            +            var end = {row: firstRow, column: 0};
            +
            +        if (this.start.row > lastRow)
            +            var start = {row: lastRow + 1, column: 0};
            +        else if (this.start.row < firstRow)
            +            var start = {row: firstRow, column: 0};
            +
            +        return Range.fromPoints(start || this.start, end || this.end);
            +    };
            +    this.extend = function(row, column) {
            +        var cmp = this.compare(row, column);
            +
            +        if (cmp == 0)
            +            return this;
            +        else if (cmp == -1)
            +            var start = {row: row, column: column};
            +        else
            +            var end = {row: row, column: column};
            +
            +        return Range.fromPoints(start || this.start, end || this.end);
            +    };
            +
            +    this.isEmpty = function() {
            +        return (this.start.row === this.end.row && this.start.column === this.end.column);
            +    };
            +    this.isMultiLine = function() {
            +        return (this.start.row !== this.end.row);
            +    };
            +    this.clone = function() {
            +        return Range.fromPoints(this.start, this.end);
            +    };
            +    this.collapseRows = function() {
            +        if (this.end.column == 0)
            +            return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
            +        else
            +            return new Range(this.start.row, 0, this.end.row, 0)
            +    };
            +    this.toScreenRange = function(session) {
            +        var screenPosStart = session.documentToScreenPosition(this.start);
            +        var screenPosEnd = session.documentToScreenPosition(this.end);
            +
            +        return new Range(
            +            screenPosStart.row, screenPosStart.column,
            +            screenPosEnd.row, screenPosEnd.column
            +        );
            +    };
            +    this.moveBy = function(row, column) {
            +        this.start.row += row;
            +        this.start.column += column;
            +        this.end.row += row;
            +        this.end.column += column;
            +    };
            +
            +}).call(Range.prototype);
            +Range.fromPoints = function(start, end) {
            +    return new Range(start.row, start.column, end.row, end.column);
            +};
            +Range.comparePoints = comparePoints;
            +
            +Range.comparePoints = function(p1, p2) {
            +    return p1.row - p2.row || p1.column - p2.column;
            +};
            +
            +
            +exports.Range = Range;
            +});
            +
            +define("ace/selection",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter","ace/range"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./lib/oop");
            +var lang = require("./lib/lang");
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +var Range = require("./range").Range;
            +var Selection = function(session) {
            +    this.session = session;
            +    this.doc = session.getDocument();
            +
            +    this.clearSelection();
            +    this.lead = this.selectionLead = this.doc.createAnchor(0, 0);
            +    this.anchor = this.selectionAnchor = this.doc.createAnchor(0, 0);
            +
            +    var self = this;
            +    this.lead.on("change", function(e) {
            +        self._emit("changeCursor");
            +        if (!self.$isEmpty)
            +            self._emit("changeSelection");
            +        if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column)
            +            self.$desiredColumn = null;
            +    });
            +
            +    this.selectionAnchor.on("change", function() {
            +        if (!self.$isEmpty)
            +            self._emit("changeSelection");
            +    });
            +};
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +    this.isEmpty = function() {
            +        return (this.$isEmpty || (
            +            this.anchor.row == this.lead.row &&
            +            this.anchor.column == this.lead.column
            +        ));
            +    };
            +    this.isMultiLine = function() {
            +        if (this.isEmpty()) {
            +            return false;
            +        }
            +
            +        return this.getRange().isMultiLine();
            +    };
            +    this.getCursor = function() {
            +        return this.lead.getPosition();
            +    };
            +    this.setSelectionAnchor = function(row, column) {
            +        this.anchor.setPosition(row, column);
            +
            +        if (this.$isEmpty) {
            +            this.$isEmpty = false;
            +            this._emit("changeSelection");
            +        }
            +    };
            +    this.getSelectionAnchor = function() {
            +        if (this.$isEmpty)
            +            return this.getSelectionLead()
            +        else
            +            return this.anchor.getPosition();
            +    };
            +    this.getSelectionLead = function() {
            +        return this.lead.getPosition();
            +    };
            +    this.shiftSelection = function(columns) {
            +        if (this.$isEmpty) {
            +            this.moveCursorTo(this.lead.row, this.lead.column + columns);
            +            return;
            +        };
            +
            +        var anchor = this.getSelectionAnchor();
            +        var lead = this.getSelectionLead();
            +
            +        var isBackwards = this.isBackwards();
            +
            +        if (!isBackwards || anchor.column !== 0)
            +            this.setSelectionAnchor(anchor.row, anchor.column + columns);
            +
            +        if (isBackwards || lead.column !== 0) {
            +            this.$moveSelection(function() {
            +                this.moveCursorTo(lead.row, lead.column + columns);
            +            });
            +        }
            +    };
            +    this.isBackwards = function() {
            +        var anchor = this.anchor;
            +        var lead = this.lead;
            +        return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
            +    };
            +    this.getRange = function() {
            +        var anchor = this.anchor;
            +        var lead = this.lead;
            +
            +        if (this.isEmpty())
            +            return Range.fromPoints(lead, lead);
            +
            +        if (this.isBackwards()) {
            +            return Range.fromPoints(lead, anchor);
            +        }
            +        else {
            +            return Range.fromPoints(anchor, lead);
            +        }
            +    };
            +    this.clearSelection = function() {
            +        if (!this.$isEmpty) {
            +            this.$isEmpty = true;
            +            this._emit("changeSelection");
            +        }
            +    };
            +    this.selectAll = function() {
            +        var lastRow = this.doc.getLength() - 1;
            +        this.setSelectionAnchor(0, 0);
            +        this.moveCursorTo(lastRow, this.doc.getLine(lastRow).length);
            +    };
            +    this.setRange =
            +    this.setSelectionRange = function(range, reverse) {
            +        if (reverse) {
            +            this.setSelectionAnchor(range.end.row, range.end.column);
            +            this.selectTo(range.start.row, range.start.column);
            +        } else {
            +            this.setSelectionAnchor(range.start.row, range.start.column);
            +            this.selectTo(range.end.row, range.end.column);
            +        }
            +        if (this.getRange().isEmpty())
            +            this.$isEmpty = true;
            +        this.$desiredColumn = null;
            +    };
            +
            +    this.$moveSelection = function(mover) {
            +        var lead = this.lead;
            +        if (this.$isEmpty)
            +            this.setSelectionAnchor(lead.row, lead.column);
            +
            +        mover.call(this);
            +    };
            +    this.selectTo = function(row, column) {
            +        this.$moveSelection(function() {
            +            this.moveCursorTo(row, column);
            +        });
            +    };
            +    this.selectToPosition = function(pos) {
            +        this.$moveSelection(function() {
            +            this.moveCursorToPosition(pos);
            +        });
            +    };
            +    this.moveTo = function(row, column) {
            +        this.clearSelection();
            +        this.moveCursorTo(row, column);
            +    };
            +    this.moveToPosition = function(pos) {
            +        this.clearSelection();
            +        this.moveCursorToPosition(pos);
            +    };
            +    this.selectUp = function() {
            +        this.$moveSelection(this.moveCursorUp);
            +    };
            +    this.selectDown = function() {
            +        this.$moveSelection(this.moveCursorDown);
            +    };
            +    this.selectRight = function() {
            +        this.$moveSelection(this.moveCursorRight);
            +    };
            +    this.selectLeft = function() {
            +        this.$moveSelection(this.moveCursorLeft);
            +    };
            +    this.selectLineStart = function() {
            +        this.$moveSelection(this.moveCursorLineStart);
            +    };
            +    this.selectLineEnd = function() {
            +        this.$moveSelection(this.moveCursorLineEnd);
            +    };
            +    this.selectFileEnd = function() {
            +        this.$moveSelection(this.moveCursorFileEnd);
            +    };
            +    this.selectFileStart = function() {
            +        this.$moveSelection(this.moveCursorFileStart);
            +    };
            +    this.selectWordRight = function() {
            +        this.$moveSelection(this.moveCursorWordRight);
            +    };
            +    this.selectWordLeft = function() {
            +        this.$moveSelection(this.moveCursorWordLeft);
            +    };
            +    this.getWordRange = function(row, column) {
            +        if (typeof column == "undefined") {
            +            var cursor = row || this.lead;
            +            row = cursor.row;
            +            column = cursor.column;
            +        }
            +        return this.session.getWordRange(row, column);
            +    };
            +    this.selectWord = function() {
            +        this.setSelectionRange(this.getWordRange());
            +    };
            +    this.selectAWord = function() {
            +        var cursor = this.getCursor();
            +        var range = this.session.getAWordRange(cursor.row, cursor.column);
            +        this.setSelectionRange(range);
            +    };
            +
            +    this.getLineRange = function(row, excludeLastChar) {
            +        var rowStart = typeof row == "number" ? row : this.lead.row;
            +        var rowEnd;
            +
            +        var foldLine = this.session.getFoldLine(rowStart);
            +        if (foldLine) {
            +            rowStart = foldLine.start.row;
            +            rowEnd = foldLine.end.row;
            +        } else {
            +            rowEnd = rowStart;
            +        }
            +        if (excludeLastChar === true)
            +            return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);
            +        else
            +            return new Range(rowStart, 0, rowEnd + 1, 0);
            +    };
            +    this.selectLine = function() {
            +        this.setSelectionRange(this.getLineRange());
            +    };
            +    this.moveCursorUp = function() {
            +        this.moveCursorBy(-1, 0);
            +    };
            +    this.moveCursorDown = function() {
            +        this.moveCursorBy(1, 0);
            +    };
            +    this.moveCursorLeft = function() {
            +        var cursor = this.lead.getPosition(),
            +            fold;
            +
            +        if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {
            +            this.moveCursorTo(fold.start.row, fold.start.column);
            +        } else if (cursor.column == 0) {
            +            if (cursor.row > 0) {
            +                this.moveCursorTo(cursor.row - 1, this.doc.getLine(cursor.row - 1).length);
            +            }
            +        }
            +        else {
            +            var tabSize = this.session.getTabSize();
            +            if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column-tabSize, cursor.column).split(" ").length-1 == tabSize)
            +                this.moveCursorBy(0, -tabSize);
            +            else
            +                this.moveCursorBy(0, -1);
            +        }
            +    };
            +    this.moveCursorRight = function() {
            +        var cursor = this.lead.getPosition(),
            +            fold;
            +        if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {
            +            this.moveCursorTo(fold.end.row, fold.end.column);
            +        }
            +        else if (this.lead.column == this.doc.getLine(this.lead.row).length) {
            +            if (this.lead.row < this.doc.getLength() - 1) {
            +                this.moveCursorTo(this.lead.row + 1, 0);
            +            }
            +        }
            +        else {
            +            var tabSize = this.session.getTabSize();
            +            var cursor = this.lead;
            +            if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column, cursor.column+tabSize).split(" ").length-1 == tabSize)
            +                this.moveCursorBy(0, tabSize);
            +            else
            +                this.moveCursorBy(0, 1);
            +        }
            +    };
            +    this.moveCursorLineStart = function() {
            +        var row = this.lead.row;
            +        var column = this.lead.column;
            +        var screenRow = this.session.documentToScreenRow(row, column);
            +        var firstColumnPosition = this.session.screenToDocumentPosition(screenRow, 0);
            +        var beforeCursor = this.session.getDisplayLine(
            +            row, null, firstColumnPosition.row,
            +            firstColumnPosition.column
            +        );
            +
            +        var leadingSpace = beforeCursor.match(/^\s*/);
            +        if (leadingSpace[0].length != column && !this.session.$useEmacsStyleLineStart)
            +            firstColumnPosition.column += leadingSpace[0].length;
            +        this.moveCursorToPosition(firstColumnPosition);
            +    };
            +    this.moveCursorLineEnd = function() {
            +        var lead = this.lead;
            +        var lineEnd = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);
            +        if (this.lead.column == lineEnd.column) {
            +            var line = this.session.getLine(lineEnd.row);
            +            if (lineEnd.column == line.length) {
            +                var textEnd = line.search(/\s+$/);
            +                if (textEnd > 0)
            +                    lineEnd.column = textEnd;
            +            }
            +        }
            +
            +        this.moveCursorTo(lineEnd.row, lineEnd.column);
            +    };
            +    this.moveCursorFileEnd = function() {
            +        var row = this.doc.getLength() - 1;
            +        var column = this.doc.getLine(row).length;
            +        this.moveCursorTo(row, column);
            +    };
            +    this.moveCursorFileStart = function() {
            +        this.moveCursorTo(0, 0);
            +    };
            +    this.moveCursorLongWordRight = function() {
            +        var row = this.lead.row;
            +        var column = this.lead.column;
            +        var line = this.doc.getLine(row);
            +        var rightOfCursor = line.substring(column);
            +
            +        var match;
            +        this.session.nonTokenRe.lastIndex = 0;
            +        this.session.tokenRe.lastIndex = 0;
            +        var fold = this.session.getFoldAt(row, column, 1);
            +        if (fold) {
            +            this.moveCursorTo(fold.end.row, fold.end.column);
            +            return;
            +        }
            +        if (match = this.session.nonTokenRe.exec(rightOfCursor)) {
            +            column += this.session.nonTokenRe.lastIndex;
            +            this.session.nonTokenRe.lastIndex = 0;
            +            rightOfCursor = line.substring(column);
            +        }
            +        if (column >= line.length) {
            +            this.moveCursorTo(row, line.length);
            +            this.moveCursorRight();
            +            if (row < this.doc.getLength() - 1)
            +                this.moveCursorWordRight();
            +            return;
            +        }
            +        if (match = this.session.tokenRe.exec(rightOfCursor)) {
            +            column += this.session.tokenRe.lastIndex;
            +            this.session.tokenRe.lastIndex = 0;
            +        }
            +
            +        this.moveCursorTo(row, column);
            +    };
            +    this.moveCursorLongWordLeft = function() {
            +        var row = this.lead.row;
            +        var column = this.lead.column;
            +        var fold;
            +        if (fold = this.session.getFoldAt(row, column, -1)) {
            +            this.moveCursorTo(fold.start.row, fold.start.column);
            +            return;
            +        }
            +
            +        var str = this.session.getFoldStringAt(row, column, -1);
            +        if (str == null) {
            +            str = this.doc.getLine(row).substring(0, column)
            +        }
            +
            +        var leftOfCursor = lang.stringReverse(str);
            +        var match;
            +        this.session.nonTokenRe.lastIndex = 0;
            +        this.session.tokenRe.lastIndex = 0;
            +        if (match = this.session.nonTokenRe.exec(leftOfCursor)) {
            +            column -= this.session.nonTokenRe.lastIndex;
            +            leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);
            +            this.session.nonTokenRe.lastIndex = 0;
            +        }
            +        if (column <= 0) {
            +            this.moveCursorTo(row, 0);
            +            this.moveCursorLeft();
            +            if (row > 0)
            +                this.moveCursorWordLeft();
            +            return;
            +        }
            +        if (match = this.session.tokenRe.exec(leftOfCursor)) {
            +            column -= this.session.tokenRe.lastIndex;
            +            this.session.tokenRe.lastIndex = 0;
            +        }
            +
            +        this.moveCursorTo(row, column);
            +    };
            +
            +    this.$shortWordEndIndex = function(rightOfCursor) {
            +        var match, index = 0, ch;
            +        var whitespaceRe = /\s/;
            +        var tokenRe = this.session.tokenRe;
            +
            +        tokenRe.lastIndex = 0;
            +        if (match = this.session.tokenRe.exec(rightOfCursor)) {
            +            index = this.session.tokenRe.lastIndex;
            +        } else {
            +            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
            +                index ++;
            +
            +            if (index < 1) {
            +                tokenRe.lastIndex = 0;
            +                 while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) {
            +                    tokenRe.lastIndex = 0;
            +                    index ++;
            +                    if (whitespaceRe.test(ch)) {
            +                        if (index > 2) {
            +                            index--
            +                            break;
            +                        } else {
            +                            while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
            +                                index ++;
            +                            if (index > 2)
            +                                break
            +                        }
            +                    }
            +                }
            +            }
            +        }
            +        tokenRe.lastIndex = 0;
            +
            +        return index;
            +    };
            +
            +    this.moveCursorShortWordRight = function() {
            +        var row = this.lead.row;
            +        var column = this.lead.column;
            +        var line = this.doc.getLine(row);
            +        var rightOfCursor = line.substring(column);
            +
            +        var fold = this.session.getFoldAt(row, column, 1);
            +        if (fold)
            +            return this.moveCursorTo(fold.end.row, fold.end.column);
            +
            +        if (column == line.length) {
            +            var l = this.doc.getLength();
            +            do {
            +                row++;
            +                rightOfCursor = this.doc.getLine(row)
            +            } while (row < l && /^\s*$/.test(rightOfCursor))
            +
            +            if (!/^\s+/.test(rightOfCursor))
            +                rightOfCursor = ""
            +            column = 0;
            +        }
            +
            +        var index = this.$shortWordEndIndex(rightOfCursor);
            +
            +        this.moveCursorTo(row, column + index);
            +    };
            +
            +    this.moveCursorShortWordLeft = function() {
            +        var row = this.lead.row;
            +        var column = this.lead.column;
            +
            +        var fold;
            +        if (fold = this.session.getFoldAt(row, column, -1))
            +            return this.moveCursorTo(fold.start.row, fold.start.column);
            +
            +        var line = this.session.getLine(row).substring(0, column);
            +        if (column == 0) {
            +            do {
            +                row--;
            +                line = this.doc.getLine(row);
            +            } while (row > 0 && /^\s*$/.test(line))
            +
            +            column = line.length;
            +            if (!/\s+$/.test(line))
            +                line = ""
            +        }
            +
            +        var leftOfCursor = lang.stringReverse(line);
            +        var index = this.$shortWordEndIndex(leftOfCursor);
            +
            +        return this.moveCursorTo(row, column - index);
            +    };
            +
            +    this.moveCursorWordRight = function() {
            +        if (this.session.$selectLongWords)
            +            this.moveCursorLongWordRight();
            +        else
            +            this.moveCursorShortWordRight();
            +    };
            +
            +    this.moveCursorWordLeft = function() {
            +        if (this.session.$selectLongWords)
            +            this.moveCursorLongWordLeft();
            +        else
            +            this.moveCursorShortWordLeft();
            +    };
            +    this.moveCursorBy = function(rows, chars) {
            +        var screenPos = this.session.documentToScreenPosition(
            +            this.lead.row,
            +            this.lead.column
            +        );
            +
            +        if (chars === 0) {
            +            if (this.$desiredColumn)
            +                screenPos.column = this.$desiredColumn;
            +            else
            +                this.$desiredColumn = screenPos.column;
            +        }
            +
            +        var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column);
            +        
            +        if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) {
            +            if (this.session.lineWidgets && this.session.lineWidgets[docPos.row])
            +                docPos.row++;
            +        }
            +        this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);
            +    };
            +    this.moveCursorToPosition = function(position) {
            +        this.moveCursorTo(position.row, position.column);
            +    };
            +    this.moveCursorTo = function(row, column, keepDesiredColumn) {
            +        var fold = this.session.getFoldAt(row, column, 1);
            +        if (fold) {
            +            row = fold.start.row;
            +            column = fold.start.column;
            +        }
            +
            +        this.$keepDesiredColumnOnChange = true;
            +        this.lead.setPosition(row, column);
            +        this.$keepDesiredColumnOnChange = false;
            +
            +        if (!keepDesiredColumn)
            +            this.$desiredColumn = null;
            +    };
            +    this.moveCursorToScreen = function(row, column, keepDesiredColumn) {
            +        var pos = this.session.screenToDocumentPosition(row, column);
            +        this.moveCursorTo(pos.row, pos.column, keepDesiredColumn);
            +    };
            +    this.detach = function() {
            +        this.lead.detach();
            +        this.anchor.detach();
            +        this.session = this.doc = null;
            +    }
            +
            +    this.fromOrientedRange = function(range) {
            +        this.setSelectionRange(range, range.cursor == range.start);
            +        this.$desiredColumn = range.desiredColumn || this.$desiredColumn;
            +    }
            +
            +    this.toOrientedRange = function(range) {
            +        var r = this.getRange();
            +        if (range) {
            +            range.start.column = r.start.column;
            +            range.start.row = r.start.row;
            +            range.end.column = r.end.column;
            +            range.end.row = r.end.row;
            +        } else {
            +            range = r;
            +        }
            +
            +        range.cursor = this.isBackwards() ? range.start : range.end;
            +        range.desiredColumn = this.$desiredColumn;
            +        return range;
            +    }
            +    this.getRangeOfMovements = function(func) {
            +        var start = this.getCursor();
            +        try {
            +            func.call(null, this);
            +            var end = this.getCursor();
            +            return Range.fromPoints(start,end);
            +        } catch(e) {
            +            return Range.fromPoints(start,start);
            +        } finally {
            +            this.moveCursorToPosition(start);
            +        }
            +    }
            +
            +    this.toJSON = function() {
            +        if (this.rangeCount) {
            +            var data = this.ranges.map(function(r) {
            +                var r1 = r.clone();
            +                r1.isBackwards = r.cursor == r.start;
            +                return r1;
            +            });
            +        } else {
            +            var data = this.getRange();
            +            data.isBackwards = this.isBackwards();
            +        }
            +        return data;
            +    };
            +
            +    this.fromJSON = function(data) {
            +        if (data.start == undefined) {
            +            if (this.rangeList) {
            +                this.toSingleRange(data[0]);
            +                for (var i = data.length; i--; ) {
            +                    var r = Range.fromPoints(data[i].start, data[i].end);
            +                    if (data.isBackwards)
            +                        r.cursor = r.start;
            +                    this.addRange(r, true);
            +                }
            +                return;
            +            } else
            +                data = data[0];
            +        }
            +        if (this.rangeList)
            +            this.toSingleRange(data);
            +        this.setSelectionRange(data, data.isBackwards);
            +    };
            +
            +    this.isEqual = function(data) {
            +        if ((data.length || this.rangeCount) && data.length != this.rangeCount)
            +            return false;
            +        if (!data.length || !this.ranges)
            +            return this.getRange().isEqual(data);
            +
            +        for (var i = this.ranges.length; i--; ) {
            +            if (!this.ranges[i].isEqual(data[i]))
            +                return false
            +        }
            +        return true;
            +    }
            +
            +}).call(Selection.prototype);
            +
            +exports.Selection = Selection;
            +});
            +
            +define("ace/tokenizer",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +var MAX_TOKEN_COUNT = 1000;
            +var Tokenizer = function(rules) {
            +    this.states = rules;
            +
            +    this.regExps = {};
            +    this.matchMappings = {};
            +    for (var key in this.states) {
            +        var state = this.states[key];
            +        var ruleRegExps = [];
            +        var matchTotal = 0;
            +        var mapping = this.matchMappings[key] = {defaultToken: "text"};
            +        var flag = "g";
            +
            +        var splitterRurles = [];
            +        for (var i = 0; i < state.length; i++) {
            +            var rule = state[i];
            +            if (rule.defaultToken)
            +                mapping.defaultToken = rule.defaultToken;
            +            if (rule.caseInsensitive)
            +                flag = "gi";
            +            if (rule.regex == null)
            +                continue;
            +
            +            if (rule.regex instanceof RegExp)
            +                rule.regex = rule.regex.toString().slice(1, -1);
            +            var adjustedregex = rule.regex;
            +            var matchcount = new RegExp("(?:(" + adjustedregex + ")|(.))").exec("a").length - 2;
            +            if (Array.isArray(rule.token)) {
            +                if (rule.token.length == 1 || matchcount == 1) {
            +                    rule.token = rule.token[0];
            +                } else if (matchcount - 1 != rule.token.length) {
            +                    throw new Error("number of classes and regexp groups in '" + 
            +                        rule.token + "'\n'" + rule.regex +  "' doesn't match\n"
            +                        + (matchcount - 1) + "!=" + rule.token.length);
            +                } else {
            +                    rule.tokenArray = rule.token;
            +                    rule.token = null;
            +                    rule.onMatch = this.$arrayTokens;
            +                }
            +            } else if (typeof rule.token == "function" && !rule.onMatch) {
            +                if (matchcount > 1)
            +                    rule.onMatch = this.$applyToken;
            +                else
            +                    rule.onMatch = rule.token;
            +            }
            +
            +            if (matchcount > 1) {
            +                if (/\\\d/.test(rule.regex)) {
            +                    adjustedregex = rule.regex.replace(/\\([0-9]+)/g, function(match, digit) {
            +                        return "\\" + (parseInt(digit, 10) + matchTotal + 1);
            +                    });
            +                } else {
            +                    matchcount = 1;
            +                    adjustedregex = this.removeCapturingGroups(rule.regex);
            +                }
            +                if (!rule.splitRegex && typeof rule.token != "string")
            +                    splitterRurles.push(rule); // flag will be known only at the very end
            +            }
            +
            +            mapping[matchTotal] = i;
            +            matchTotal += matchcount;
            +
            +            ruleRegExps.push(adjustedregex);
            +            if (!rule.onMatch)
            +                rule.onMatch = null;
            +        }
            +        
            +        if (!ruleRegExps.length) {
            +            mapping[0] = 0;
            +            ruleRegExps.push("$");
            +        }
            +        
            +        splitterRurles.forEach(function(rule) {
            +            rule.splitRegex = this.createSplitterRegexp(rule.regex, flag);
            +        }, this);
            +
            +        this.regExps[key] = new RegExp("(" + ruleRegExps.join(")|(") + ")|($)", flag);
            +    }
            +};
            +
            +(function() {
            +    this.$setMaxTokenCount = function(m) {
            +        MAX_TOKEN_COUNT = m | 0;
            +    };
            +    
            +    this.$applyToken = function(str) {
            +        var values = this.splitRegex.exec(str).slice(1);
            +        var types = this.token.apply(this, values);
            +        if (typeof types === "string")
            +            return [{type: types, value: str}];
            +
            +        var tokens = [];
            +        for (var i = 0, l = types.length; i < l; i++) {
            +            if (values[i])
            +                tokens[tokens.length] = {
            +                    type: types[i],
            +                    value: values[i]
            +                };
            +        }
            +        return tokens;
            +    },
            +
            +    this.$arrayTokens = function(str) {
            +        if (!str)
            +            return [];
            +        var values = this.splitRegex.exec(str);
            +        if (!values)
            +            return "text";
            +        var tokens = [];
            +        var types = this.tokenArray;
            +        for (var i = 0, l = types.length; i < l; i++) {
            +            if (values[i + 1])
            +                tokens[tokens.length] = {
            +                    type: types[i],
            +                    value: values[i + 1]
            +                };
            +        }
            +        return tokens;
            +    };
            +
            +    this.removeCapturingGroups = function(src) {
            +        var r = src.replace(
            +            /\[(?:\\.|[^\]])*?\]|\\.|\(\?[:=!]|(\()/g,
            +            function(x, y) {return y ? "(?:" : x;}
            +        );
            +        return r;
            +    };
            +
            +    this.createSplitterRegexp = function(src, flag) {
            +        if (src.indexOf("(?=") != -1) {
            +            var stack = 0;
            +            var inChClass = false;
            +            var lastCapture = {};
            +            src.replace(/(\\.)|(\((?:\?[=!])?)|(\))|([\[\]])/g, function(
            +                m, esc, parenOpen, parenClose, square, index
            +            ) {
            +                if (inChClass) {
            +                    inChClass = square != "]";
            +                } else if (square) {
            +                    inChClass = true;
            +                } else if (parenClose) {
            +                    if (stack == lastCapture.stack) {
            +                        lastCapture.end = index+1;
            +                        lastCapture.stack = -1;
            +                    }
            +                    stack--;
            +                } else if (parenOpen) {
            +                    stack++;
            +                    if (parenOpen.length != 1) {
            +                        lastCapture.stack = stack
            +                        lastCapture.start = index;
            +                    }
            +                }
            +                return m;
            +            });
            +
            +            if (lastCapture.end != null && /^\)*$/.test(src.substr(lastCapture.end)))
            +                src = src.substring(0, lastCapture.start) + src.substr(lastCapture.end);
            +        }
            +        return new RegExp(src, (flag||"").replace("g", ""));
            +    };
            +    this.getLineTokens = function(line, startState) {
            +        if (startState && typeof startState != "string") {
            +            var stack = startState.slice(0);
            +            startState = stack[0];
            +        } else
            +            var stack = [];
            +
            +        var currentState = startState || "start";
            +        var state = this.states[currentState];
            +        if (!state) {
            +            currentState = "start";
            +            state = this.states[currentState];
            +        }
            +        var mapping = this.matchMappings[currentState];
            +        var re = this.regExps[currentState];
            +        re.lastIndex = 0;
            +
            +        var match, tokens = [];
            +        var lastIndex = 0;
            +
            +        var token = {type: null, value: ""};
            +
            +        while (match = re.exec(line)) {
            +            var type = mapping.defaultToken;
            +            var rule = null;
            +            var value = match[0];
            +            var index = re.lastIndex;
            +
            +            if (index - value.length > lastIndex) {
            +                var skipped = line.substring(lastIndex, index - value.length);
            +                if (token.type == type) {
            +                    token.value += skipped;
            +                } else {
            +                    if (token.type)
            +                        tokens.push(token);
            +                    token = {type: type, value: skipped};
            +                }
            +            }
            +
            +            for (var i = 0; i < match.length-2; i++) {
            +                if (match[i + 1] === undefined)
            +                    continue;
            +
            +                rule = state[mapping[i]];
            +
            +                if (rule.onMatch)
            +                    type = rule.onMatch(value, currentState, stack);
            +                else
            +                    type = rule.token;
            +
            +                if (rule.next) {
            +                    if (typeof rule.next == "string")
            +                        currentState = rule.next;
            +                    else
            +                        currentState = rule.next(currentState, stack);
            +
            +                    state = this.states[currentState];
            +                    if (!state) {
            +                        window.console && console.error && console.error(currentState, "doesn't exist");
            +                        currentState = "start";
            +                        state = this.states[currentState];
            +                    }
            +                    mapping = this.matchMappings[currentState];
            +                    lastIndex = index;
            +                    re = this.regExps[currentState];
            +                    re.lastIndex = index;
            +                }
            +                break;
            +            }
            +
            +            if (value) {
            +                if (typeof type == "string") {
            +                    if ((!rule || rule.merge !== false) && token.type === type) {
            +                        token.value += value;
            +                    } else {
            +                        if (token.type)
            +                            tokens.push(token);
            +                        token = {type: type, value: value};
            +                    }
            +                } else if (type) {
            +                    if (token.type)
            +                        tokens.push(token);
            +                    token = {type: null, value: ""};
            +                    for (var i = 0; i < type.length; i++)
            +                        tokens.push(type[i]);
            +                }
            +            }
            +
            +            if (lastIndex == line.length)
            +                break;
            +
            +            lastIndex = index;
            +
            +            if (tokens.length > MAX_TOKEN_COUNT) {
            +                while (lastIndex < line.length) {
            +                    if (token.type)
            +                        tokens.push(token);
            +                    token = {
            +                        value: line.substring(lastIndex, lastIndex += 2000),
            +                        type: "overflow"
            +                    };
            +                }
            +                currentState = "start";
            +                stack = [];
            +                break;
            +            }
            +        }
            +
            +        if (token.type)
            +            tokens.push(token);
            +        
            +        if (stack.length > 1) {
            +            if (stack[0] !== currentState)
            +                stack.unshift(currentState);
            +        }
            +        return {
            +            tokens : tokens,
            +            state : stack.length ? stack : currentState
            +        };
            +    };
            +
            +}).call(Tokenizer.prototype);
            +
            +exports.Tokenizer = Tokenizer;
            +});
            +
            +define("ace/mode/text_highlight_rules",["require","exports","module","ace/lib/lang"], function(require, exports, module) {
            +"use strict";
            +
            +var lang = require("../lib/lang");
            +
            +var TextHighlightRules = function() {
            +
            +    this.$rules = {
            +        "start" : [{
            +            token : "empty_line",
            +            regex : '^$'
            +        }, {
            +            defaultToken : "text"
            +        }]
            +    };
            +};
            +
            +(function() {
            +
            +    this.addRules = function(rules, prefix) {
            +        if (!prefix) {
            +            for (var key in rules)
            +                this.$rules[key] = rules[key];
            +            return;
            +        }
            +        for (var key in rules) {
            +            var state = rules[key];
            +            for (var i = 0; i < state.length; i++) {
            +                var rule = state[i];
            +                if (rule.next) {
            +                    if (typeof rule.next != "string") {
            +                        if (rule.nextState && rule.nextState.indexOf(prefix) !== 0)
            +                            rule.nextState = prefix + rule.nextState;
            +                    } else {
            +                        if (rule.next.indexOf(prefix) !== 0)
            +                            rule.next = prefix + rule.next;
            +                    }
            +
            +                }
            +            }
            +            this.$rules[prefix + key] = state;
            +        }
            +    };
            +
            +    this.getRules = function() {
            +        return this.$rules;
            +    };
            +
            +    this.embedRules = function (HighlightRules, prefix, escapeRules, states, append) {
            +        var embedRules = typeof HighlightRules == "function"
            +            ? new HighlightRules().getRules()
            +            : HighlightRules;
            +        if (states) {
            +            for (var i = 0; i < states.length; i++)
            +                states[i] = prefix + states[i];
            +        } else {
            +            states = [];
            +            for (var key in embedRules)
            +                states.push(prefix + key);
            +        }
            +
            +        this.addRules(embedRules, prefix);
            +
            +        if (escapeRules) {
            +            var addRules = Array.prototype[append ? "push" : "unshift"];
            +            for (var i = 0; i < states.length; i++)
            +                addRules.apply(this.$rules[states[i]], lang.deepCopy(escapeRules));
            +        }
            +
            +        if (!this.$embeds)
            +            this.$embeds = [];
            +        this.$embeds.push(prefix);
            +    };
            +
            +    this.getEmbeds = function() {
            +        return this.$embeds;
            +    };
            +
            +    var pushState = function(currentState, stack) {
            +        if (currentState != "start" || stack.length)
            +            stack.unshift(this.nextState, currentState);
            +        return this.nextState;
            +    };
            +    var popState = function(currentState, stack) {
            +        stack.shift();
            +        return stack.shift() || "start";
            +    };
            +
            +    this.normalizeRules = function() {
            +        var id = 0;
            +        var rules = this.$rules;
            +        function processState(key) {
            +            var state = rules[key];
            +            state.processed = true;
            +            for (var i = 0; i < state.length; i++) {
            +                var rule = state[i];
            +                if (!rule.regex && rule.start) {
            +                    rule.regex = rule.start;
            +                    if (!rule.next)
            +                        rule.next = [];
            +                    rule.next.push({
            +                        defaultToken: rule.token
            +                    }, {
            +                        token: rule.token + ".end",
            +                        regex: rule.end || rule.start,
            +                        next: "pop"
            +                    });
            +                    rule.token = rule.token + ".start";
            +                    rule.push = true;
            +                }
            +                var next = rule.next || rule.push;
            +                if (next && Array.isArray(next)) {
            +                    var stateName = rule.stateName;
            +                    if (!stateName)  {
            +                        stateName = rule.token;
            +                        if (typeof stateName != "string")
            +                            stateName = stateName[0] || "";
            +                        if (rules[stateName])
            +                            stateName += id++;
            +                    }
            +                    rules[stateName] = next;
            +                    rule.next = stateName;
            +                    processState(stateName);
            +                } else if (next == "pop") {
            +                    rule.next = popState;
            +                }
            +
            +                if (rule.push) {
            +                    rule.nextState = rule.next || rule.push;
            +                    rule.next = pushState;
            +                    delete rule.push;
            +                }
            +
            +                if (rule.rules) {
            +                    for (var r in rule.rules) {
            +                        if (rules[r]) {
            +                            if (rules[r].push)
            +                                rules[r].push.apply(rules[r], rule.rules[r]);
            +                        } else {
            +                            rules[r] = rule.rules[r];
            +                        }
            +                    }
            +                }
            +                if (rule.include || typeof rule == "string") {
            +                    var includeName = rule.include || rule;
            +                    var toInsert = rules[includeName];
            +                } else if (Array.isArray(rule))
            +                    toInsert = rule;
            +
            +                if (toInsert) {
            +                    var args = [i, 1].concat(toInsert);
            +                    if (rule.noEscape)
            +                        args = args.filter(function(x) {return !x.next;});
            +                    state.splice.apply(state, args);
            +                    i--;
            +                    toInsert = null;
            +                }
            +                
            +                if (rule.keywordMap) {
            +                    rule.token = this.createKeywordMapper(
            +                        rule.keywordMap, rule.defaultToken || "text", rule.caseInsensitive
            +                    );
            +                    delete rule.defaultToken;
            +                }
            +            }
            +        }
            +        Object.keys(rules).forEach(processState, this);
            +    };
            +
            +    this.createKeywordMapper = function(map, defaultToken, ignoreCase, splitChar) {
            +        var keywords = Object.create(null);
            +        Object.keys(map).forEach(function(className) {
            +            var a = map[className];
            +            if (ignoreCase)
            +                a = a.toLowerCase();
            +            var list = a.split(splitChar || "|");
            +            for (var i = list.length; i--; )
            +                keywords[list[i]] = className;
            +        });
            +        if (Object.getPrototypeOf(keywords)) {
            +            keywords.__proto__ = null;
            +        }
            +        this.$keywordList = Object.keys(keywords);
            +        map = null;
            +        return ignoreCase
            +            ? function(value) {return keywords[value.toLowerCase()] || defaultToken }
            +            : function(value) {return keywords[value] || defaultToken };
            +    };
            +
            +    this.getKeywords = function() {
            +        return this.$keywords;
            +    };
            +
            +}).call(TextHighlightRules.prototype);
            +
            +exports.TextHighlightRules = TextHighlightRules;
            +});
            +
            +define("ace/mode/behaviour",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +
            +var Behaviour = function() {
            +   this.$behaviours = {};
            +};
            +
            +(function () {
            +
            +    this.add = function (name, action, callback) {
            +        switch (undefined) {
            +          case this.$behaviours:
            +              this.$behaviours = {};
            +          case this.$behaviours[name]:
            +              this.$behaviours[name] = {};
            +        }
            +        this.$behaviours[name][action] = callback;
            +    }
            +    
            +    this.addBehaviours = function (behaviours) {
            +        for (var key in behaviours) {
            +            for (var action in behaviours[key]) {
            +                this.add(key, action, behaviours[key][action]);
            +            }
            +        }
            +    }
            +    
            +    this.remove = function (name) {
            +        if (this.$behaviours && this.$behaviours[name]) {
            +            delete this.$behaviours[name];
            +        }
            +    }
            +    
            +    this.inherit = function (mode, filter) {
            +        if (typeof mode === "function") {
            +            var behaviours = new mode().getBehaviours(filter);
            +        } else {
            +            var behaviours = mode.getBehaviours(filter);
            +        }
            +        this.addBehaviours(behaviours);
            +    }
            +    
            +    this.getBehaviours = function (filter) {
            +        if (!filter) {
            +            return this.$behaviours;
            +        } else {
            +            var ret = {}
            +            for (var i = 0; i < filter.length; i++) {
            +                if (this.$behaviours[filter[i]]) {
            +                    ret[filter[i]] = this.$behaviours[filter[i]];
            +                }
            +            }
            +            return ret;
            +        }
            +    }
            +
            +}).call(Behaviour.prototype);
            +
            +exports.Behaviour = Behaviour;
            +});
            +
            +define("ace/unicode",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +exports.packages = {};
            +
            +addUnicodePackage({
            +    L:  "0041-005A0061-007A00AA00B500BA00C0-00D600D8-00F600F8-02C102C6-02D102E0-02E402EC02EE0370-037403760377037A-037D03860388-038A038C038E-03A103A3-03F503F7-0481048A-05250531-055605590561-058705D0-05EA05F0-05F20621-064A066E066F0671-06D306D506E506E606EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA07F407F507FA0800-0815081A082408280904-0939093D09500958-0961097109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E460E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EC60EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10A0-10C510D0-10FA10FC1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317D717DC1820-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541AA71B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C7D1CE9-1CEC1CEE-1CF11D00-1DBF1E00-1F151F18-1F1D1F20-1F451F48-1F4D1F50-1F571F591F5B1F5D1F5F-1F7D1F80-1FB41FB6-1FBC1FBE1FC2-1FC41FC6-1FCC1FD0-1FD31FD6-1FDB1FE0-1FEC1FF2-1FF41FF6-1FFC2071207F2090-209421022107210A-211321152119-211D212421262128212A-212D212F-2139213C-213F2145-2149214E218321842C00-2C2E2C30-2C5E2C60-2CE42CEB-2CEE2D00-2D252D30-2D652D6F2D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE2E2F300530063031-3035303B303C3041-3096309D-309F30A1-30FA30FC-30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A48CA4D0-A4FDA500-A60CA610-A61FA62AA62BA640-A65FA662-A66EA67F-A697A6A0-A6E5A717-A71FA722-A788A78BA78CA7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2A9CFAA00-AA28AA40-AA42AA44-AA4BAA60-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADB-AADDABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB00-FB06FB13-FB17FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF21-FF3AFF41-FF5AFF66-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",
            +    Ll: "0061-007A00AA00B500BA00DF-00F600F8-00FF01010103010501070109010B010D010F01110113011501170119011B011D011F01210123012501270129012B012D012F01310133013501370138013A013C013E014001420144014601480149014B014D014F01510153015501570159015B015D015F01610163016501670169016B016D016F0171017301750177017A017C017E-0180018301850188018C018D019201950199-019B019E01A101A301A501A801AA01AB01AD01B001B401B601B901BA01BD-01BF01C601C901CC01CE01D001D201D401D601D801DA01DC01DD01DF01E101E301E501E701E901EB01ED01EF01F001F301F501F901FB01FD01FF02010203020502070209020B020D020F02110213021502170219021B021D021F02210223022502270229022B022D022F02310233-0239023C023F0240024202470249024B024D024F-02930295-02AF037103730377037B-037D039003AC-03CE03D003D103D5-03D703D903DB03DD03DF03E103E303E503E703E903EB03ED03EF-03F303F503F803FB03FC0430-045F04610463046504670469046B046D046F04710473047504770479047B047D047F0481048B048D048F04910493049504970499049B049D049F04A104A304A504A704A904AB04AD04AF04B104B304B504B704B904BB04BD04BF04C204C404C604C804CA04CC04CE04CF04D104D304D504D704D904DB04DD04DF04E104E304E504E704E904EB04ED04EF04F104F304F504F704F904FB04FD04FF05010503050505070509050B050D050F05110513051505170519051B051D051F0521052305250561-05871D00-1D2B1D62-1D771D79-1D9A1E011E031E051E071E091E0B1E0D1E0F1E111E131E151E171E191E1B1E1D1E1F1E211E231E251E271E291E2B1E2D1E2F1E311E331E351E371E391E3B1E3D1E3F1E411E431E451E471E491E4B1E4D1E4F1E511E531E551E571E591E5B1E5D1E5F1E611E631E651E671E691E6B1E6D1E6F1E711E731E751E771E791E7B1E7D1E7F1E811E831E851E871E891E8B1E8D1E8F1E911E931E95-1E9D1E9F1EA11EA31EA51EA71EA91EAB1EAD1EAF1EB11EB31EB51EB71EB91EBB1EBD1EBF1EC11EC31EC51EC71EC91ECB1ECD1ECF1ED11ED31ED51ED71ED91EDB1EDD1EDF1EE11EE31EE51EE71EE91EEB1EED1EEF1EF11EF31EF51EF71EF91EFB1EFD1EFF-1F071F10-1F151F20-1F271F30-1F371F40-1F451F50-1F571F60-1F671F70-1F7D1F80-1F871F90-1F971FA0-1FA71FB0-1FB41FB61FB71FBE1FC2-1FC41FC61FC71FD0-1FD31FD61FD71FE0-1FE71FF2-1FF41FF61FF7210A210E210F2113212F21342139213C213D2146-2149214E21842C30-2C5E2C612C652C662C682C6A2C6C2C712C732C742C76-2C7C2C812C832C852C872C892C8B2C8D2C8F2C912C932C952C972C992C9B2C9D2C9F2CA12CA32CA52CA72CA92CAB2CAD2CAF2CB12CB32CB52CB72CB92CBB2CBD2CBF2CC12CC32CC52CC72CC92CCB2CCD2CCF2CD12CD32CD52CD72CD92CDB2CDD2CDF2CE12CE32CE42CEC2CEE2D00-2D25A641A643A645A647A649A64BA64DA64FA651A653A655A657A659A65BA65DA65FA663A665A667A669A66BA66DA681A683A685A687A689A68BA68DA68FA691A693A695A697A723A725A727A729A72BA72DA72F-A731A733A735A737A739A73BA73DA73FA741A743A745A747A749A74BA74DA74FA751A753A755A757A759A75BA75DA75FA761A763A765A767A769A76BA76DA76FA771-A778A77AA77CA77FA781A783A785A787A78CFB00-FB06FB13-FB17FF41-FF5A",
            +    Lu: "0041-005A00C0-00D600D8-00DE01000102010401060108010A010C010E01100112011401160118011A011C011E01200122012401260128012A012C012E01300132013401360139013B013D013F0141014301450147014A014C014E01500152015401560158015A015C015E01600162016401660168016A016C016E017001720174017601780179017B017D018101820184018601870189-018B018E-0191019301940196-0198019C019D019F01A001A201A401A601A701A901AC01AE01AF01B1-01B301B501B701B801BC01C401C701CA01CD01CF01D101D301D501D701D901DB01DE01E001E201E401E601E801EA01EC01EE01F101F401F6-01F801FA01FC01FE02000202020402060208020A020C020E02100212021402160218021A021C021E02200222022402260228022A022C022E02300232023A023B023D023E02410243-02460248024A024C024E03700372037603860388-038A038C038E038F0391-03A103A3-03AB03CF03D2-03D403D803DA03DC03DE03E003E203E403E603E803EA03EC03EE03F403F703F903FA03FD-042F04600462046404660468046A046C046E04700472047404760478047A047C047E0480048A048C048E04900492049404960498049A049C049E04A004A204A404A604A804AA04AC04AE04B004B204B404B604B804BA04BC04BE04C004C104C304C504C704C904CB04CD04D004D204D404D604D804DA04DC04DE04E004E204E404E604E804EA04EC04EE04F004F204F404F604F804FA04FC04FE05000502050405060508050A050C050E05100512051405160518051A051C051E0520052205240531-055610A0-10C51E001E021E041E061E081E0A1E0C1E0E1E101E121E141E161E181E1A1E1C1E1E1E201E221E241E261E281E2A1E2C1E2E1E301E321E341E361E381E3A1E3C1E3E1E401E421E441E461E481E4A1E4C1E4E1E501E521E541E561E581E5A1E5C1E5E1E601E621E641E661E681E6A1E6C1E6E1E701E721E741E761E781E7A1E7C1E7E1E801E821E841E861E881E8A1E8C1E8E1E901E921E941E9E1EA01EA21EA41EA61EA81EAA1EAC1EAE1EB01EB21EB41EB61EB81EBA1EBC1EBE1EC01EC21EC41EC61EC81ECA1ECC1ECE1ED01ED21ED41ED61ED81EDA1EDC1EDE1EE01EE21EE41EE61EE81EEA1EEC1EEE1EF01EF21EF41EF61EF81EFA1EFC1EFE1F08-1F0F1F18-1F1D1F28-1F2F1F38-1F3F1F48-1F4D1F591F5B1F5D1F5F1F68-1F6F1FB8-1FBB1FC8-1FCB1FD8-1FDB1FE8-1FEC1FF8-1FFB21022107210B-210D2110-211221152119-211D212421262128212A-212D2130-2133213E213F214521832C00-2C2E2C602C62-2C642C672C692C6B2C6D-2C702C722C752C7E-2C802C822C842C862C882C8A2C8C2C8E2C902C922C942C962C982C9A2C9C2C9E2CA02CA22CA42CA62CA82CAA2CAC2CAE2CB02CB22CB42CB62CB82CBA2CBC2CBE2CC02CC22CC42CC62CC82CCA2CCC2CCE2CD02CD22CD42CD62CD82CDA2CDC2CDE2CE02CE22CEB2CEDA640A642A644A646A648A64AA64CA64EA650A652A654A656A658A65AA65CA65EA662A664A666A668A66AA66CA680A682A684A686A688A68AA68CA68EA690A692A694A696A722A724A726A728A72AA72CA72EA732A734A736A738A73AA73CA73EA740A742A744A746A748A74AA74CA74EA750A752A754A756A758A75AA75CA75EA760A762A764A766A768A76AA76CA76EA779A77BA77DA77EA780A782A784A786A78BFF21-FF3A",
            +    Lt: "01C501C801CB01F21F88-1F8F1F98-1F9F1FA8-1FAF1FBC1FCC1FFC",
            +    Lm: "02B0-02C102C6-02D102E0-02E402EC02EE0374037A0559064006E506E607F407F507FA081A0824082809710E460EC610FC17D718431AA71C78-1C7D1D2C-1D611D781D9B-1DBF2071207F2090-20942C7D2D6F2E2F30053031-3035303B309D309E30FC-30FEA015A4F8-A4FDA60CA67FA717-A71FA770A788A9CFAA70AADDFF70FF9EFF9F",
            +    Lo: "01BB01C0-01C3029405D0-05EA05F0-05F20621-063F0641-064A066E066F0671-06D306D506EE06EF06FA-06FC06FF07100712-072F074D-07A507B107CA-07EA0800-08150904-0939093D09500958-096109720979-097F0985-098C098F09900993-09A809AA-09B009B209B6-09B909BD09CE09DC09DD09DF-09E109F009F10A05-0A0A0A0F0A100A13-0A280A2A-0A300A320A330A350A360A380A390A59-0A5C0A5E0A72-0A740A85-0A8D0A8F-0A910A93-0AA80AAA-0AB00AB20AB30AB5-0AB90ABD0AD00AE00AE10B05-0B0C0B0F0B100B13-0B280B2A-0B300B320B330B35-0B390B3D0B5C0B5D0B5F-0B610B710B830B85-0B8A0B8E-0B900B92-0B950B990B9A0B9C0B9E0B9F0BA30BA40BA8-0BAA0BAE-0BB90BD00C05-0C0C0C0E-0C100C12-0C280C2A-0C330C35-0C390C3D0C580C590C600C610C85-0C8C0C8E-0C900C92-0CA80CAA-0CB30CB5-0CB90CBD0CDE0CE00CE10D05-0D0C0D0E-0D100D12-0D280D2A-0D390D3D0D600D610D7A-0D7F0D85-0D960D9A-0DB10DB3-0DBB0DBD0DC0-0DC60E01-0E300E320E330E40-0E450E810E820E840E870E880E8A0E8D0E94-0E970E99-0E9F0EA1-0EA30EA50EA70EAA0EAB0EAD-0EB00EB20EB30EBD0EC0-0EC40EDC0EDD0F000F40-0F470F49-0F6C0F88-0F8B1000-102A103F1050-1055105A-105D106110651066106E-10701075-1081108E10D0-10FA1100-1248124A-124D1250-12561258125A-125D1260-1288128A-128D1290-12B012B2-12B512B8-12BE12C012C2-12C512C8-12D612D8-13101312-13151318-135A1380-138F13A0-13F41401-166C166F-167F1681-169A16A0-16EA1700-170C170E-17111720-17311740-17511760-176C176E-17701780-17B317DC1820-18421844-18771880-18A818AA18B0-18F51900-191C1950-196D1970-19741980-19AB19C1-19C71A00-1A161A20-1A541B05-1B331B45-1B4B1B83-1BA01BAE1BAF1C00-1C231C4D-1C4F1C5A-1C771CE9-1CEC1CEE-1CF12135-21382D30-2D652D80-2D962DA0-2DA62DA8-2DAE2DB0-2DB62DB8-2DBE2DC0-2DC62DC8-2DCE2DD0-2DD62DD8-2DDE3006303C3041-3096309F30A1-30FA30FF3105-312D3131-318E31A0-31B731F0-31FF3400-4DB54E00-9FCBA000-A014A016-A48CA4D0-A4F7A500-A60BA610-A61FA62AA62BA66EA6A0-A6E5A7FB-A801A803-A805A807-A80AA80C-A822A840-A873A882-A8B3A8F2-A8F7A8FBA90A-A925A930-A946A960-A97CA984-A9B2AA00-AA28AA40-AA42AA44-AA4BAA60-AA6FAA71-AA76AA7AAA80-AAAFAAB1AAB5AAB6AAB9-AABDAAC0AAC2AADBAADCABC0-ABE2AC00-D7A3D7B0-D7C6D7CB-D7FBF900-FA2DFA30-FA6DFA70-FAD9FB1DFB1F-FB28FB2A-FB36FB38-FB3CFB3EFB40FB41FB43FB44FB46-FBB1FBD3-FD3DFD50-FD8FFD92-FDC7FDF0-FDFBFE70-FE74FE76-FEFCFF66-FF6FFF71-FF9DFFA0-FFBEFFC2-FFC7FFCA-FFCFFFD2-FFD7FFDA-FFDC",
            +    M:  "0300-036F0483-04890591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DE-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0903093C093E-094E0951-0955096209630981-098309BC09BE-09C409C709C809CB-09CD09D709E209E30A01-0A030A3C0A3E-0A420A470A480A4B-0A4D0A510A700A710A750A81-0A830ABC0ABE-0AC50AC7-0AC90ACB-0ACD0AE20AE30B01-0B030B3C0B3E-0B440B470B480B4B-0B4D0B560B570B620B630B820BBE-0BC20BC6-0BC80BCA-0BCD0BD70C01-0C030C3E-0C440C46-0C480C4A-0C4D0C550C560C620C630C820C830CBC0CBE-0CC40CC6-0CC80CCA-0CCD0CD50CD60CE20CE30D020D030D3E-0D440D46-0D480D4A-0D4D0D570D620D630D820D830DCA0DCF-0DD40DD60DD8-0DDF0DF20DF30E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F3E0F3F0F71-0F840F860F870F90-0F970F99-0FBC0FC6102B-103E1056-1059105E-10601062-10641067-106D1071-10741082-108D108F109A-109D135F1712-17141732-1734175217531772177317B6-17D317DD180B-180D18A91920-192B1930-193B19B0-19C019C819C91A17-1A1B1A55-1A5E1A60-1A7C1A7F1B00-1B041B34-1B441B6B-1B731B80-1B821BA1-1BAA1C24-1C371CD0-1CD21CD4-1CE81CED1CF21DC0-1DE61DFD-1DFF20D0-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66F-A672A67CA67DA6F0A6F1A802A806A80BA823-A827A880A881A8B4-A8C4A8E0-A8F1A926-A92DA947-A953A980-A983A9B3-A9C0AA29-AA36AA43AA4CAA4DAA7BAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE3-ABEAABECABEDFB1EFE00-FE0FFE20-FE26",
            +    Mn: "0300-036F0483-04870591-05BD05BF05C105C205C405C505C70610-061A064B-065E067006D6-06DC06DF-06E406E706E806EA-06ED07110730-074A07A6-07B007EB-07F30816-0819081B-08230825-08270829-082D0900-0902093C0941-0948094D0951-095509620963098109BC09C1-09C409CD09E209E30A010A020A3C0A410A420A470A480A4B-0A4D0A510A700A710A750A810A820ABC0AC1-0AC50AC70AC80ACD0AE20AE30B010B3C0B3F0B41-0B440B4D0B560B620B630B820BC00BCD0C3E-0C400C46-0C480C4A-0C4D0C550C560C620C630CBC0CBF0CC60CCC0CCD0CE20CE30D41-0D440D4D0D620D630DCA0DD2-0DD40DD60E310E34-0E3A0E47-0E4E0EB10EB4-0EB90EBB0EBC0EC8-0ECD0F180F190F350F370F390F71-0F7E0F80-0F840F860F870F90-0F970F99-0FBC0FC6102D-10301032-10371039103A103D103E10581059105E-10601071-1074108210851086108D109D135F1712-17141732-1734175217531772177317B7-17BD17C617C9-17D317DD180B-180D18A91920-19221927192819321939-193B1A171A181A561A58-1A5E1A601A621A65-1A6C1A73-1A7C1A7F1B00-1B031B341B36-1B3A1B3C1B421B6B-1B731B801B811BA2-1BA51BA81BA91C2C-1C331C361C371CD0-1CD21CD4-1CE01CE2-1CE81CED1DC0-1DE61DFD-1DFF20D0-20DC20E120E5-20F02CEF-2CF12DE0-2DFF302A-302F3099309AA66FA67CA67DA6F0A6F1A802A806A80BA825A826A8C4A8E0-A8F1A926-A92DA947-A951A980-A982A9B3A9B6-A9B9A9BCAA29-AA2EAA31AA32AA35AA36AA43AA4CAAB0AAB2-AAB4AAB7AAB8AABEAABFAAC1ABE5ABE8ABEDFB1EFE00-FE0FFE20-FE26",
            +    Mc: "0903093E-09400949-094C094E0982098309BE-09C009C709C809CB09CC09D70A030A3E-0A400A830ABE-0AC00AC90ACB0ACC0B020B030B3E0B400B470B480B4B0B4C0B570BBE0BBF0BC10BC20BC6-0BC80BCA-0BCC0BD70C01-0C030C41-0C440C820C830CBE0CC0-0CC40CC70CC80CCA0CCB0CD50CD60D020D030D3E-0D400D46-0D480D4A-0D4C0D570D820D830DCF-0DD10DD8-0DDF0DF20DF30F3E0F3F0F7F102B102C10311038103B103C105610571062-10641067-106D108310841087-108C108F109A-109C17B617BE-17C517C717C81923-19261929-192B193019311933-193819B0-19C019C819C91A19-1A1B1A551A571A611A631A641A6D-1A721B041B351B3B1B3D-1B411B431B441B821BA11BA61BA71BAA1C24-1C2B1C341C351CE11CF2A823A824A827A880A881A8B4-A8C3A952A953A983A9B4A9B5A9BAA9BBA9BD-A9C0AA2FAA30AA33AA34AA4DAA7BABE3ABE4ABE6ABE7ABE9ABEAABEC",
            +    Me: "0488048906DE20DD-20E020E2-20E4A670-A672",
            +    N:  "0030-003900B200B300B900BC-00BE0660-066906F0-06F907C0-07C90966-096F09E6-09EF09F4-09F90A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BF20C66-0C6F0C78-0C7E0CE6-0CEF0D66-0D750E50-0E590ED0-0ED90F20-0F331040-10491090-10991369-137C16EE-16F017E0-17E917F0-17F91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C5920702074-20792080-20892150-21822185-21892460-249B24EA-24FF2776-27932CFD30073021-30293038-303A3192-31953220-32293251-325F3280-328932B1-32BFA620-A629A6E6-A6EFA830-A835A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",
            +    Nd: "0030-00390660-066906F0-06F907C0-07C90966-096F09E6-09EF0A66-0A6F0AE6-0AEF0B66-0B6F0BE6-0BEF0C66-0C6F0CE6-0CEF0D66-0D6F0E50-0E590ED0-0ED90F20-0F291040-10491090-109917E0-17E91810-18191946-194F19D0-19DA1A80-1A891A90-1A991B50-1B591BB0-1BB91C40-1C491C50-1C59A620-A629A8D0-A8D9A900-A909A9D0-A9D9AA50-AA59ABF0-ABF9FF10-FF19",
            +    Nl: "16EE-16F02160-21822185-218830073021-30293038-303AA6E6-A6EF",
            +    No: "00B200B300B900BC-00BE09F4-09F90BF0-0BF20C78-0C7E0D70-0D750F2A-0F331369-137C17F0-17F920702074-20792080-20892150-215F21892460-249B24EA-24FF2776-27932CFD3192-31953220-32293251-325F3280-328932B1-32BFA830-A835",
            +    P:  "0021-00230025-002A002C-002F003A003B003F0040005B-005D005F007B007D00A100AB00B700BB00BF037E0387055A-055F0589058A05BE05C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F3A-0F3D0F850FD0-0FD4104A-104F10FB1361-13681400166D166E169B169C16EB-16ED1735173617D4-17D617D8-17DA1800-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD32010-20272030-20432045-20512053-205E207D207E208D208E2329232A2768-277527C527C627E6-27EF2983-299829D8-29DB29FC29FD2CF9-2CFC2CFE2CFF2E00-2E2E2E302E313001-30033008-30113014-301F3030303D30A030FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFD3EFD3FFE10-FE19FE30-FE52FE54-FE61FE63FE68FE6AFE6BFF01-FF03FF05-FF0AFF0C-FF0FFF1AFF1BFF1FFF20FF3B-FF3DFF3FFF5BFF5DFF5F-FF65",
            +    Pd: "002D058A05BE140018062010-20152E172E1A301C303030A0FE31FE32FE58FE63FF0D",
            +    Ps: "0028005B007B0F3A0F3C169B201A201E2045207D208D23292768276A276C276E27702772277427C527E627E827EA27EC27EE2983298529872989298B298D298F299129932995299729D829DA29FC2E222E242E262E283008300A300C300E3010301430163018301A301DFD3EFE17FE35FE37FE39FE3BFE3DFE3FFE41FE43FE47FE59FE5BFE5DFF08FF3BFF5BFF5FFF62",
            +    Pe: "0029005D007D0F3B0F3D169C2046207E208E232A2769276B276D276F27712773277527C627E727E927EB27ED27EF298429862988298A298C298E2990299229942996299829D929DB29FD2E232E252E272E293009300B300D300F3011301530173019301B301E301FFD3FFE18FE36FE38FE3AFE3CFE3EFE40FE42FE44FE48FE5AFE5CFE5EFF09FF3DFF5DFF60FF63",
            +    Pi: "00AB2018201B201C201F20392E022E042E092E0C2E1C2E20",
            +    Pf: "00BB2019201D203A2E032E052E0A2E0D2E1D2E21",
            +    Pc: "005F203F20402054FE33FE34FE4D-FE4FFF3F",
            +    Po: "0021-00230025-0027002A002C002E002F003A003B003F0040005C00A100B700BF037E0387055A-055F058905C005C305C605F305F40609060A060C060D061B061E061F066A-066D06D40700-070D07F7-07F90830-083E0964096509700DF40E4F0E5A0E5B0F04-0F120F850FD0-0FD4104A-104F10FB1361-1368166D166E16EB-16ED1735173617D4-17D617D8-17DA1800-18051807-180A1944194519DE19DF1A1E1A1F1AA0-1AA61AA8-1AAD1B5A-1B601C3B-1C3F1C7E1C7F1CD3201620172020-20272030-2038203B-203E2041-20432047-205120532055-205E2CF9-2CFC2CFE2CFF2E002E012E06-2E082E0B2E0E-2E162E182E192E1B2E1E2E1F2E2A-2E2E2E302E313001-3003303D30FBA4FEA4FFA60D-A60FA673A67EA6F2-A6F7A874-A877A8CEA8CFA8F8-A8FAA92EA92FA95FA9C1-A9CDA9DEA9DFAA5C-AA5FAADEAADFABEBFE10-FE16FE19FE30FE45FE46FE49-FE4CFE50-FE52FE54-FE57FE5F-FE61FE68FE6AFE6BFF01-FF03FF05-FF07FF0AFF0CFF0EFF0FFF1AFF1BFF1FFF20FF3CFF61FF64FF65",
            +    S:  "0024002B003C-003E005E0060007C007E00A2-00A900AC00AE-00B100B400B600B800D700F702C2-02C502D2-02DF02E5-02EB02ED02EF-02FF03750384038503F604820606-0608060B060E060F06E906FD06FE07F609F209F309FA09FB0AF10B700BF3-0BFA0C7F0CF10CF20D790E3F0F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-139917DB194019E0-19FF1B61-1B6A1B74-1B7C1FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE20442052207A-207C208A-208C20A0-20B8210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B2140-2144214A-214D214F2190-2328232B-23E82400-24262440-244A249C-24E92500-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE27C0-27C427C7-27CA27CC27D0-27E527F0-29822999-29D729DC-29FB29FE-2B4C2B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F309B309C319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A700-A716A720A721A789A78AA828-A82BA836-A839AA77-AA79FB29FDFCFDFDFE62FE64-FE66FE69FF04FF0BFF1C-FF1EFF3EFF40FF5CFF5EFFE0-FFE6FFE8-FFEEFFFCFFFD",
            +    Sm: "002B003C-003E007C007E00AC00B100D700F703F60606-060820442052207A-207C208A-208C2140-2144214B2190-2194219A219B21A021A321A621AE21CE21CF21D221D421F4-22FF2308-230B23202321237C239B-23B323DC-23E125B725C125F8-25FF266F27C0-27C427C7-27CA27CC27D0-27E527F0-27FF2900-29822999-29D729DC-29FB29FE-2AFF2B30-2B442B47-2B4CFB29FE62FE64-FE66FF0BFF1C-FF1EFF5CFF5EFFE2FFE9-FFEC",
            +    Sc: "002400A2-00A5060B09F209F309FB0AF10BF90E3F17DB20A0-20B8A838FDFCFE69FF04FFE0FFE1FFE5FFE6",
            +    Sk: "005E006000A800AF00B400B802C2-02C502D2-02DF02E5-02EB02ED02EF-02FF0375038403851FBD1FBF-1FC11FCD-1FCF1FDD-1FDF1FED-1FEF1FFD1FFE309B309CA700-A716A720A721A789A78AFF3EFF40FFE3",
            +    So: "00A600A700A900AE00B000B60482060E060F06E906FD06FE07F609FA0B700BF3-0BF80BFA0C7F0CF10CF20D790F01-0F030F13-0F170F1A-0F1F0F340F360F380FBE-0FC50FC7-0FCC0FCE0FCF0FD5-0FD8109E109F13601390-1399194019E0-19FF1B61-1B6A1B74-1B7C210021012103-21062108210921142116-2118211E-2123212521272129212E213A213B214A214C214D214F2195-2199219C-219F21A121A221A421A521A7-21AD21AF-21CD21D021D121D321D5-21F32300-2307230C-231F2322-2328232B-237B237D-239A23B4-23DB23E2-23E82400-24262440-244A249C-24E92500-25B625B8-25C025C2-25F72600-266E2670-26CD26CF-26E126E326E8-26FF2701-27042706-2709270C-27272729-274B274D274F-27522756-275E2761-276727942798-27AF27B1-27BE2800-28FF2B00-2B2F2B452B462B50-2B592CE5-2CEA2E80-2E992E9B-2EF32F00-2FD52FF0-2FFB300430123013302030363037303E303F319031913196-319F31C0-31E33200-321E322A-32503260-327F328A-32B032C0-32FE3300-33FF4DC0-4DFFA490-A4C6A828-A82BA836A837A839AA77-AA79FDFDFFE4FFE8FFEDFFEEFFFCFFFD",
            +    Z:  "002000A01680180E2000-200A20282029202F205F3000",
            +    Zs: "002000A01680180E2000-200A202F205F3000",
            +    Zl: "2028",
            +    Zp: "2029",
            +    C:  "0000-001F007F-009F00AD03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-0605061C061D0620065F06DD070E070F074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17B417B517DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF200B-200F202A-202E2060-206F20722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-F8FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFD-FF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFFBFFFEFFFF",
            +    Cc: "0000-001F007F-009F",
            +    Cf: "00AD0600-060306DD070F17B417B5200B-200F202A-202E2060-2064206A-206FFEFFFFF9-FFFB",
            +    Co: "E000-F8FF",
            +    Cs: "D800-DFFF",
            +    Cn: "03780379037F-0383038B038D03A20526-05300557055805600588058B-059005C8-05CF05EB-05EF05F5-05FF06040605061C061D0620065F070E074B074C07B2-07BF07FB-07FF082E082F083F-08FF093A093B094F095609570973-097809800984098D098E0991099209A909B109B3-09B509BA09BB09C509C609C909CA09CF-09D609D8-09DB09DE09E409E509FC-0A000A040A0B-0A0E0A110A120A290A310A340A370A3A0A3B0A3D0A43-0A460A490A4A0A4E-0A500A52-0A580A5D0A5F-0A650A76-0A800A840A8E0A920AA90AB10AB40ABA0ABB0AC60ACA0ACE0ACF0AD1-0ADF0AE40AE50AF00AF2-0B000B040B0D0B0E0B110B120B290B310B340B3A0B3B0B450B460B490B4A0B4E-0B550B58-0B5B0B5E0B640B650B72-0B810B840B8B-0B8D0B910B96-0B980B9B0B9D0BA0-0BA20BA5-0BA70BAB-0BAD0BBA-0BBD0BC3-0BC50BC90BCE0BCF0BD1-0BD60BD8-0BE50BFB-0C000C040C0D0C110C290C340C3A-0C3C0C450C490C4E-0C540C570C5A-0C5F0C640C650C70-0C770C800C810C840C8D0C910CA90CB40CBA0CBB0CC50CC90CCE-0CD40CD7-0CDD0CDF0CE40CE50CF00CF3-0D010D040D0D0D110D290D3A-0D3C0D450D490D4E-0D560D58-0D5F0D640D650D76-0D780D800D810D840D97-0D990DB20DBC0DBE0DBF0DC7-0DC90DCB-0DCE0DD50DD70DE0-0DF10DF5-0E000E3B-0E3E0E5C-0E800E830E850E860E890E8B0E8C0E8E-0E930E980EA00EA40EA60EA80EA90EAC0EBA0EBE0EBF0EC50EC70ECE0ECF0EDA0EDB0EDE-0EFF0F480F6D-0F700F8C-0F8F0F980FBD0FCD0FD9-0FFF10C6-10CF10FD-10FF1249124E124F12571259125E125F1289128E128F12B112B612B712BF12C112C612C712D7131113161317135B-135E137D-137F139A-139F13F5-13FF169D-169F16F1-16FF170D1715-171F1737-173F1754-175F176D17711774-177F17DE17DF17EA-17EF17FA-17FF180F181A-181F1878-187F18AB-18AF18F6-18FF191D-191F192C-192F193C-193F1941-1943196E196F1975-197F19AC-19AF19CA-19CF19DB-19DD1A1C1A1D1A5F1A7D1A7E1A8A-1A8F1A9A-1A9F1AAE-1AFF1B4C-1B4F1B7D-1B7F1BAB-1BAD1BBA-1BFF1C38-1C3A1C4A-1C4C1C80-1CCF1CF3-1CFF1DE7-1DFC1F161F171F1E1F1F1F461F471F4E1F4F1F581F5A1F5C1F5E1F7E1F7F1FB51FC51FD41FD51FDC1FF01FF11FF51FFF2065-206920722073208F2095-209F20B9-20CF20F1-20FF218A-218F23E9-23FF2427-243F244B-245F26CE26E226E4-26E727002705270A270B2728274C274E2753-2755275F27602795-279727B027BF27CB27CD-27CF2B4D-2B4F2B5A-2BFF2C2F2C5F2CF2-2CF82D26-2D2F2D66-2D6E2D70-2D7F2D97-2D9F2DA72DAF2DB72DBF2DC72DCF2DD72DDF2E32-2E7F2E9A2EF4-2EFF2FD6-2FEF2FFC-2FFF3040309730983100-3104312E-3130318F31B8-31BF31E4-31EF321F32FF4DB6-4DBF9FCC-9FFFA48D-A48FA4C7-A4CFA62C-A63FA660A661A674-A67BA698-A69FA6F8-A6FFA78D-A7FAA82C-A82FA83A-A83FA878-A87FA8C5-A8CDA8DA-A8DFA8FC-A8FFA954-A95EA97D-A97FA9CEA9DA-A9DDA9E0-A9FFAA37-AA3FAA4EAA4FAA5AAA5BAA7C-AA7FAAC3-AADAAAE0-ABBFABEEABEFABFA-ABFFD7A4-D7AFD7C7-D7CAD7FC-D7FFFA2EFA2FFA6EFA6FFADA-FAFFFB07-FB12FB18-FB1CFB37FB3DFB3FFB42FB45FBB2-FBD2FD40-FD4FFD90FD91FDC8-FDEFFDFEFDFFFE1A-FE1FFE27-FE2FFE53FE67FE6C-FE6FFE75FEFDFEFEFF00FFBF-FFC1FFC8FFC9FFD0FFD1FFD8FFD9FFDD-FFDFFFE7FFEF-FFF8FFFEFFFF"
            +});
            +
            +function addUnicodePackage (pack) {
            +    var codePoint = /\w{4}/g;
            +    for (var name in pack)
            +        exports.packages[name] = pack[name].replace(codePoint, "\\u$&");
            +};
            +
            +});
            +
            +define("ace/token_iterator",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +var TokenIterator = function(session, initialRow, initialColumn) {
            +    this.$session = session;
            +    this.$row = initialRow;
            +    this.$rowTokens = session.getTokens(initialRow);
            +
            +    var token = session.getTokenAt(initialRow, initialColumn);
            +    this.$tokenIndex = token ? token.index : -1;
            +};
            +
            +(function() { 
            +    this.stepBackward = function() {
            +        this.$tokenIndex -= 1;
            +        
            +        while (this.$tokenIndex < 0) {
            +            this.$row -= 1;
            +            if (this.$row < 0) {
            +                this.$row = 0;
            +                return null;
            +            }
            +                
            +            this.$rowTokens = this.$session.getTokens(this.$row);
            +            this.$tokenIndex = this.$rowTokens.length - 1;
            +        }
            +            
            +        return this.$rowTokens[this.$tokenIndex];
            +    };   
            +    this.stepForward = function() {
            +        this.$tokenIndex += 1;
            +        var rowCount;
            +        while (this.$tokenIndex >= this.$rowTokens.length) {
            +            this.$row += 1;
            +            if (!rowCount)
            +                rowCount = this.$session.getLength();
            +            if (this.$row >= rowCount) {
            +                this.$row = rowCount - 1;
            +                return null;
            +            }
            +
            +            this.$rowTokens = this.$session.getTokens(this.$row);
            +            this.$tokenIndex = 0;
            +        }
            +            
            +        return this.$rowTokens[this.$tokenIndex];
            +    };      
            +    this.getCurrentToken = function () {
            +        return this.$rowTokens[this.$tokenIndex];
            +    };      
            +    this.getCurrentTokenRow = function () {
            +        return this.$row;
            +    };     
            +    this.getCurrentTokenColumn = function() {
            +        var rowTokens = this.$rowTokens;
            +        var tokenIndex = this.$tokenIndex;
            +        var column = rowTokens[tokenIndex].start;
            +        if (column !== undefined)
            +            return column;
            +            
            +        column = 0;
            +        while (tokenIndex > 0) {
            +            tokenIndex -= 1;
            +            column += rowTokens[tokenIndex].value.length;
            +        }
            +        
            +        return column;  
            +    };
            +            
            +}).call(TokenIterator.prototype);
            +
            +exports.TokenIterator = TokenIterator;
            +});
            +
            +define("ace/mode/text",["require","exports","module","ace/tokenizer","ace/mode/text_highlight_rules","ace/mode/behaviour","ace/unicode","ace/lib/lang","ace/token_iterator","ace/range"], function(require, exports, module) {
            +"use strict";
            +
            +var Tokenizer = require("../tokenizer").Tokenizer;
            +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
            +var Behaviour = require("./behaviour").Behaviour;
            +var unicode = require("../unicode");
            +var lang = require("../lib/lang");
            +var TokenIterator = require("../token_iterator").TokenIterator;
            +var Range = require("../range").Range;
            +
            +var Mode = function() {
            +    this.HighlightRules = TextHighlightRules;
            +    this.$behaviour = new Behaviour();
            +};
            +
            +(function() {
            +
            +    this.tokenRe = new RegExp("^["
            +        + unicode.packages.L
            +        + unicode.packages.Mn + unicode.packages.Mc
            +        + unicode.packages.Nd
            +        + unicode.packages.Pc + "\\$_]+", "g"
            +    );
            +
            +    this.nonTokenRe = new RegExp("^(?:[^"
            +        + unicode.packages.L
            +        + unicode.packages.Mn + unicode.packages.Mc
            +        + unicode.packages.Nd
            +        + unicode.packages.Pc + "\\$_]|\\s])+", "g"
            +    );
            +
            +    this.getTokenizer = function() {
            +        if (!this.$tokenizer) {
            +            this.$highlightRules = this.$highlightRules || new this.HighlightRules();
            +            this.$tokenizer = new Tokenizer(this.$highlightRules.getRules());
            +        }
            +        return this.$tokenizer;
            +    };
            +
            +    this.lineCommentStart = "";
            +    this.blockComment = "";
            +
            +    this.toggleCommentLines = function(state, session, startRow, endRow) {
            +        var doc = session.doc;
            +
            +        var ignoreBlankLines = true;
            +        var shouldRemove = true;
            +        var minIndent = Infinity;
            +        var tabSize = session.getTabSize();
            +        var insertAtTabStop = false;
            +
            +        if (!this.lineCommentStart) {
            +            if (!this.blockComment)
            +                return false;
            +            var lineCommentStart = this.blockComment.start;
            +            var lineCommentEnd = this.blockComment.end;
            +            var regexpStart = new RegExp("^(\\s*)(?:" + lang.escapeRegExp(lineCommentStart) + ")");
            +            var regexpEnd = new RegExp("(?:" + lang.escapeRegExp(lineCommentEnd) + ")\\s*$");
            +
            +            var comment = function(line, i) {
            +                if (testRemove(line, i))
            +                    return;
            +                if (!ignoreBlankLines || /\S/.test(line)) {
            +                    doc.insertInLine({row: i, column: line.length}, lineCommentEnd);
            +                    doc.insertInLine({row: i, column: minIndent}, lineCommentStart);
            +                }
            +            };
            +
            +            var uncomment = function(line, i) {
            +                var m;
            +                if (m = line.match(regexpEnd))
            +                    doc.removeInLine(i, line.length - m[0].length, line.length);
            +                if (m = line.match(regexpStart))
            +                    doc.removeInLine(i, m[1].length, m[0].length);
            +            };
            +
            +            var testRemove = function(line, row) {
            +                if (regexpStart.test(line))
            +                    return true;
            +                var tokens = session.getTokens(row);
            +                for (var i = 0; i < tokens.length; i++) {
            +                    if (tokens[i].type === 'comment')
            +                        return true;
            +                }
            +            };
            +        } else {
            +            if (Array.isArray(this.lineCommentStart)) {
            +                var regexpStart = this.lineCommentStart.map(lang.escapeRegExp).join("|");
            +                var lineCommentStart = this.lineCommentStart[0];
            +            } else {
            +                var regexpStart = lang.escapeRegExp(this.lineCommentStart);
            +                var lineCommentStart = this.lineCommentStart;
            +            }
            +            regexpStart = new RegExp("^(\\s*)(?:" + regexpStart + ") ?");
            +            
            +            insertAtTabStop = session.getUseSoftTabs();
            +
            +            var uncomment = function(line, i) {
            +                var m = line.match(regexpStart);
            +                if (!m) return;
            +                var start = m[1].length, end = m[0].length;
            +                if (!shouldInsertSpace(line, start, end) && m[0][end - 1] == " ")
            +                    end--;
            +                doc.removeInLine(i, start, end);
            +            };
            +            var commentWithSpace = lineCommentStart + " ";
            +            var comment = function(line, i) {
            +                if (!ignoreBlankLines || /\S/.test(line)) {
            +                    if (shouldInsertSpace(line, minIndent, minIndent))
            +                        doc.insertInLine({row: i, column: minIndent}, commentWithSpace);
            +                    else
            +                        doc.insertInLine({row: i, column: minIndent}, lineCommentStart);
            +                }
            +            };
            +            var testRemove = function(line, i) {
            +                return regexpStart.test(line);
            +            };
            +            
            +            var shouldInsertSpace = function(line, before, after) {
            +                var spaces = 0;
            +                while (before-- && line.charAt(before) == " ")
            +                    spaces++;
            +                if (spaces % tabSize != 0)
            +                    return false;
            +                var spaces = 0;
            +                while (line.charAt(after++) == " ")
            +                    spaces++;
            +                if (tabSize > 2)
            +                    return spaces % tabSize != tabSize - 1;
            +                else
            +                    return spaces % tabSize == 0;
            +                return true;
            +            };
            +        }
            +
            +        function iter(fun) {
            +            for (var i = startRow; i <= endRow; i++)
            +                fun(doc.getLine(i), i);
            +        }
            +
            +
            +        var minEmptyLength = Infinity;
            +        iter(function(line, i) {
            +            var indent = line.search(/\S/);
            +            if (indent !== -1) {
            +                if (indent < minIndent)
            +                    minIndent = indent;
            +                if (shouldRemove && !testRemove(line, i))
            +                    shouldRemove = false;
            +            } else if (minEmptyLength > line.length) {
            +                minEmptyLength = line.length;
            +            }
            +        });
            +
            +        if (minIndent == Infinity) {
            +            minIndent = minEmptyLength;
            +            ignoreBlankLines = false;
            +            shouldRemove = false;
            +        }
            +
            +        if (insertAtTabStop && minIndent % tabSize != 0)
            +            minIndent = Math.floor(minIndent / tabSize) * tabSize;
            +
            +        iter(shouldRemove ? uncomment : comment);
            +    };
            +
            +    this.toggleBlockComment = function(state, session, range, cursor) {
            +        var comment = this.blockComment;
            +        if (!comment)
            +            return;
            +        if (!comment.start && comment[0])
            +            comment = comment[0];
            +
            +        var iterator = new TokenIterator(session, cursor.row, cursor.column);
            +        var token = iterator.getCurrentToken();
            +
            +        var sel = session.selection;
            +        var initialRange = session.selection.toOrientedRange();
            +        var startRow, colDiff;
            +
            +        if (token && /comment/.test(token.type)) {
            +            var startRange, endRange;
            +            while (token && /comment/.test(token.type)) {
            +                var i = token.value.indexOf(comment.start);
            +                if (i != -1) {
            +                    var row = iterator.getCurrentTokenRow();
            +                    var column = iterator.getCurrentTokenColumn() + i;
            +                    startRange = new Range(row, column, row, column + comment.start.length);
            +                    break;
            +                }
            +                token = iterator.stepBackward();
            +            }
            +
            +            var iterator = new TokenIterator(session, cursor.row, cursor.column);
            +            var token = iterator.getCurrentToken();
            +            while (token && /comment/.test(token.type)) {
            +                var i = token.value.indexOf(comment.end);
            +                if (i != -1) {
            +                    var row = iterator.getCurrentTokenRow();
            +                    var column = iterator.getCurrentTokenColumn() + i;
            +                    endRange = new Range(row, column, row, column + comment.end.length);
            +                    break;
            +                }
            +                token = iterator.stepForward();
            +            }
            +            if (endRange)
            +                session.remove(endRange);
            +            if (startRange) {
            +                session.remove(startRange);
            +                startRow = startRange.start.row;
            +                colDiff = -comment.start.length;
            +            }
            +        } else {
            +            colDiff = comment.start.length;
            +            startRow = range.start.row;
            +            session.insert(range.end, comment.end);
            +            session.insert(range.start, comment.start);
            +        }
            +        if (initialRange.start.row == startRow)
            +            initialRange.start.column += colDiff;
            +        if (initialRange.end.row == startRow)
            +            initialRange.end.column += colDiff;
            +        session.selection.fromOrientedRange(initialRange);
            +    };
            +
            +    this.getNextLineIndent = function(state, line, tab) {
            +        return this.$getIndent(line);
            +    };
            +
            +    this.checkOutdent = function(state, line, input) {
            +        return false;
            +    };
            +
            +    this.autoOutdent = function(state, doc, row) {
            +    };
            +
            +    this.$getIndent = function(line) {
            +        return line.match(/^\s*/)[0];
            +    };
            +
            +    this.createWorker = function(session) {
            +        return null;
            +    };
            +
            +    this.createModeDelegates = function (mapping) {
            +        this.$embeds = [];
            +        this.$modes = {};
            +        for (var i in mapping) {
            +            if (mapping[i]) {
            +                this.$embeds.push(i);
            +                this.$modes[i] = new mapping[i]();
            +            }
            +        }
            +
            +        var delegations = ['toggleBlockComment', 'toggleCommentLines', 'getNextLineIndent', 
            +            'checkOutdent', 'autoOutdent', 'transformAction', 'getCompletions'];
            +
            +        for (var i = 0; i < delegations.length; i++) {
            +            (function(scope) {
            +              var functionName = delegations[i];
            +              var defaultHandler = scope[functionName];
            +              scope[delegations[i]] = function() {
            +                  return this.$delegator(functionName, arguments, defaultHandler);
            +              };
            +            } (this));
            +        }
            +    };
            +
            +    this.$delegator = function(method, args, defaultHandler) {
            +        var state = args[0];
            +        if (typeof state != "string")
            +            state = state[0];
            +        for (var i = 0; i < this.$embeds.length; i++) {
            +            if (!this.$modes[this.$embeds[i]]) continue;
            +
            +            var split = state.split(this.$embeds[i]);
            +            if (!split[0] && split[1]) {
            +                args[0] = split[1];
            +                var mode = this.$modes[this.$embeds[i]];
            +                return mode[method].apply(mode, args);
            +            }
            +        }
            +        var ret = defaultHandler.apply(this, args);
            +        return defaultHandler ? ret : undefined;
            +    };
            +
            +    this.transformAction = function(state, action, editor, session, param) {
            +        if (this.$behaviour) {
            +            var behaviours = this.$behaviour.getBehaviours();
            +            for (var key in behaviours) {
            +                if (behaviours[key][action]) {
            +                    var ret = behaviours[key][action].apply(this, arguments);
            +                    if (ret) {
            +                        return ret;
            +                    }
            +                }
            +            }
            +        }
            +    };
            +    
            +    this.getKeywords = function(append) {
            +        if (!this.completionKeywords) {
            +            var rules = this.$tokenizer.rules;
            +            var completionKeywords = [];
            +            for (var rule in rules) {
            +                var ruleItr = rules[rule];
            +                for (var r = 0, l = ruleItr.length; r < l; r++) {
            +                    if (typeof ruleItr[r].token === "string") {
            +                        if (/keyword|support|storage/.test(ruleItr[r].token))
            +                            completionKeywords.push(ruleItr[r].regex);
            +                    }
            +                    else if (typeof ruleItr[r].token === "object") {
            +                        for (var a = 0, aLength = ruleItr[r].token.length; a < aLength; a++) {    
            +                            if (/keyword|support|storage/.test(ruleItr[r].token[a])) {
            +                                var rule = ruleItr[r].regex.match(/\(.+?\)/g)[a];
            +                                completionKeywords.push(rule.substr(1, rule.length - 2));
            +                            }
            +                        }
            +                    }
            +                }
            +            }
            +            this.completionKeywords = completionKeywords;
            +        }
            +        if (!append)
            +            return this.$keywordList;
            +        return completionKeywords.concat(this.$keywordList || []);
            +    };
            +    
            +    this.$createKeywordList = function() {
            +        if (!this.$highlightRules)
            +            this.getTokenizer();
            +        return this.$keywordList = this.$highlightRules.$keywordList || [];
            +    };
            +
            +    this.getCompletions = function(state, session, pos, prefix) {
            +        var keywords = this.$keywordList || this.$createKeywordList();
            +        return keywords.map(function(word) {
            +            return {
            +                name: word,
            +                value: word,
            +                score: 0,
            +                meta: "keyword"
            +            };
            +        });
            +    };
            +
            +    this.$id = "ace/mode/text";
            +}).call(Mode.prototype);
            +
            +exports.Mode = Mode;
            +});
            +
            +define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./lib/oop");
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +
            +var Anchor = exports.Anchor = function(doc, row, column) {
            +    this.$onChange = this.onChange.bind(this);
            +    this.attach(doc);
            +    
            +    if (typeof column == "undefined")
            +        this.setPosition(row.row, row.column);
            +    else
            +        this.setPosition(row, column);
            +};
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +    this.getPosition = function() {
            +        return this.$clipPositionToDocument(this.row, this.column);
            +    };
            +    this.getDocument = function() {
            +        return this.document;
            +    };
            +    this.$insertRight = false;
            +    this.onChange = function(e) {
            +        var delta = e.data;
            +        var range = delta.range;
            +
            +        if (range.start.row == range.end.row && range.start.row != this.row)
            +            return;
            +
            +        if (range.start.row > this.row)
            +            return;
            +
            +        if (range.start.row == this.row && range.start.column > this.column)
            +            return;
            +
            +        var row = this.row;
            +        var column = this.column;
            +        var start = range.start;
            +        var end = range.end;
            +
            +        if (delta.action === "insertText") {
            +            if (start.row === row && start.column <= column) {
            +                if (start.column === column && this.$insertRight) {
            +                } else if (start.row === end.row) {
            +                    column += end.column - start.column;
            +                } else {
            +                    column -= start.column;
            +                    row += end.row - start.row;
            +                }
            +            } else if (start.row !== end.row && start.row < row) {
            +                row += end.row - start.row;
            +            }
            +        } else if (delta.action === "insertLines") {
            +            if (start.row === row && column === 0 && this.$insertRight) {
            +            }
            +            else if (start.row <= row) {
            +                row += end.row - start.row;
            +            }
            +        } else if (delta.action === "removeText") {
            +            if (start.row === row && start.column < column) {
            +                if (end.column >= column)
            +                    column = start.column;
            +                else
            +                    column = Math.max(0, column - (end.column - start.column));
            +
            +            } else if (start.row !== end.row && start.row < row) {
            +                if (end.row === row)
            +                    column = Math.max(0, column - end.column) + start.column;
            +                row -= (end.row - start.row);
            +            } else if (end.row === row) {
            +                row -= end.row - start.row;
            +                column = Math.max(0, column - end.column) + start.column;
            +            }
            +        } else if (delta.action == "removeLines") {
            +            if (start.row <= row) {
            +                if (end.row <= row)
            +                    row -= end.row - start.row;
            +                else {
            +                    row = start.row;
            +                    column = 0;
            +                }
            +            }
            +        }
            +
            +        this.setPosition(row, column, true);
            +    };
            +    this.setPosition = function(row, column, noClip) {
            +        var pos;
            +        if (noClip) {
            +            pos = {
            +                row: row,
            +                column: column
            +            };
            +        } else {
            +            pos = this.$clipPositionToDocument(row, column);
            +        }
            +
            +        if (this.row == pos.row && this.column == pos.column)
            +            return;
            +
            +        var old = {
            +            row: this.row,
            +            column: this.column
            +        };
            +
            +        this.row = pos.row;
            +        this.column = pos.column;
            +        this._signal("change", {
            +            old: old,
            +            value: pos
            +        });
            +    };
            +    this.detach = function() {
            +        this.document.removeEventListener("change", this.$onChange);
            +    };
            +    this.attach = function(doc) {
            +        this.document = doc || this.document;
            +        this.document.on("change", this.$onChange);
            +    };
            +    this.$clipPositionToDocument = function(row, column) {
            +        var pos = {};
            +
            +        if (row >= this.document.getLength()) {
            +            pos.row = Math.max(0, this.document.getLength() - 1);
            +            pos.column = this.document.getLine(pos.row).length;
            +        }
            +        else if (row < 0) {
            +            pos.row = 0;
            +            pos.column = 0;
            +        }
            +        else {
            +            pos.row = row;
            +            pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
            +        }
            +
            +        if (column < 0)
            +            pos.column = 0;
            +
            +        return pos;
            +    };
            +
            +}).call(Anchor.prototype);
            +
            +});
            +
            +define("ace/document",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/range","ace/anchor"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./lib/oop");
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +var Range = require("./range").Range;
            +var Anchor = require("./anchor").Anchor;
            +
            +var Document = function(text) {
            +    this.$lines = [];
            +    if (text.length === 0) {
            +        this.$lines = [""];
            +    } else if (Array.isArray(text)) {
            +        this._insertLines(0, text);
            +    } else {
            +        this.insert({row: 0, column:0}, text);
            +    }
            +};
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +    this.setValue = function(text) {
            +        var len = this.getLength();
            +        this.remove(new Range(0, 0, len, this.getLine(len-1).length));
            +        this.insert({row: 0, column:0}, text);
            +    };
            +    this.getValue = function() {
            +        return this.getAllLines().join(this.getNewLineCharacter());
            +    };
            +    this.createAnchor = function(row, column) {
            +        return new Anchor(this, row, column);
            +    };
            +    if ("aaa".split(/a/).length === 0)
            +        this.$split = function(text) {
            +            return text.replace(/\r\n|\r/g, "\n").split("\n");
            +        };
            +    else
            +        this.$split = function(text) {
            +            return text.split(/\r\n|\r|\n/);
            +        };
            +
            +
            +    this.$detectNewLine = function(text) {
            +        var match = text.match(/^.*?(\r\n|\r|\n)/m);
            +        this.$autoNewLine = match ? match[1] : "\n";
            +        this._signal("changeNewLineMode");
            +    };
            +    this.getNewLineCharacter = function() {
            +        switch (this.$newLineMode) {
            +          case "windows":
            +            return "\r\n";
            +          case "unix":
            +            return "\n";
            +          default:
            +            return this.$autoNewLine || "\n";
            +        }
            +    };
            +
            +    this.$autoNewLine = "";
            +    this.$newLineMode = "auto";
            +    this.setNewLineMode = function(newLineMode) {
            +        if (this.$newLineMode === newLineMode)
            +            return;
            +
            +        this.$newLineMode = newLineMode;
            +        this._signal("changeNewLineMode");
            +    };
            +    this.getNewLineMode = function() {
            +        return this.$newLineMode;
            +    };
            +    this.isNewLine = function(text) {
            +        return (text == "\r\n" || text == "\r" || text == "\n");
            +    };
            +    this.getLine = function(row) {
            +        return this.$lines[row] || "";
            +    };
            +    this.getLines = function(firstRow, lastRow) {
            +        return this.$lines.slice(firstRow, lastRow + 1);
            +    };
            +    this.getAllLines = function() {
            +        return this.getLines(0, this.getLength());
            +    };
            +    this.getLength = function() {
            +        return this.$lines.length;
            +    };
            +    this.getTextRange = function(range) {
            +        if (range.start.row == range.end.row) {
            +            return this.getLine(range.start.row)
            +                .substring(range.start.column, range.end.column);
            +        }
            +        var lines = this.getLines(range.start.row, range.end.row);
            +        lines[0] = (lines[0] || "").substring(range.start.column);
            +        var l = lines.length - 1;
            +        if (range.end.row - range.start.row == l)
            +            lines[l] = lines[l].substring(0, range.end.column);
            +        return lines.join(this.getNewLineCharacter());
            +    };
            +
            +    this.$clipPosition = function(position) {
            +        var length = this.getLength();
            +        if (position.row >= length) {
            +            position.row = Math.max(0, length - 1);
            +            position.column = this.getLine(length-1).length;
            +        } else if (position.row < 0)
            +            position.row = 0;
            +        return position;
            +    };
            +    this.insert = function(position, text) {
            +        if (!text || text.length === 0)
            +            return position;
            +
            +        position = this.$clipPosition(position);
            +        if (this.getLength() <= 1)
            +            this.$detectNewLine(text);
            +
            +        var lines = this.$split(text);
            +        var firstLine = lines.splice(0, 1)[0];
            +        var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0];
            +
            +        position = this.insertInLine(position, firstLine);
            +        if (lastLine !== null) {
            +            position = this.insertNewLine(position); // terminate first line
            +            position = this._insertLines(position.row, lines);
            +            position = this.insertInLine(position, lastLine || "");
            +        }
            +        return position;
            +    };
            +    this.insertLines = function(row, lines) {
            +        if (row >= this.getLength())
            +            return this.insert({row: row, column: 0}, "\n" + lines.join("\n"));
            +        return this._insertLines(Math.max(row, 0), lines);
            +    };
            +    this._insertLines = function(row, lines) {
            +        if (lines.length == 0)
            +            return {row: row, column: 0};
            +        while (lines.length > 0xF000) {
            +            var end = this._insertLines(row, lines.slice(0, 0xF000));
            +            lines = lines.slice(0xF000);
            +            row = end.row;
            +        }
            +
            +        var args = [row, 0];
            +        args.push.apply(args, lines);
            +        this.$lines.splice.apply(this.$lines, args);
            +
            +        var range = new Range(row, 0, row + lines.length, 0);
            +        var delta = {
            +            action: "insertLines",
            +            range: range,
            +            lines: lines
            +        };
            +        this._signal("change", { data: delta });
            +        return range.end;
            +    };
            +    this.insertNewLine = function(position) {
            +        position = this.$clipPosition(position);
            +        var line = this.$lines[position.row] || "";
            +
            +        this.$lines[position.row] = line.substring(0, position.column);
            +        this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));
            +
            +        var end = {
            +            row : position.row + 1,
            +            column : 0
            +        };
            +
            +        var delta = {
            +            action: "insertText",
            +            range: Range.fromPoints(position, end),
            +            text: this.getNewLineCharacter()
            +        };
            +        this._signal("change", { data: delta });
            +
            +        return end;
            +    };
            +    this.insertInLine = function(position, text) {
            +        if (text.length == 0)
            +            return position;
            +
            +        var line = this.$lines[position.row] || "";
            +
            +        this.$lines[position.row] = line.substring(0, position.column) + text
            +                + line.substring(position.column);
            +
            +        var end = {
            +            row : position.row,
            +            column : position.column + text.length
            +        };
            +
            +        var delta = {
            +            action: "insertText",
            +            range: Range.fromPoints(position, end),
            +            text: text
            +        };
            +        this._signal("change", { data: delta });
            +
            +        return end;
            +    };
            +    this.remove = function(range) {
            +        if (!(range instanceof Range))
            +            range = Range.fromPoints(range.start, range.end);
            +        range.start = this.$clipPosition(range.start);
            +        range.end = this.$clipPosition(range.end);
            +
            +        if (range.isEmpty())
            +            return range.start;
            +
            +        var firstRow = range.start.row;
            +        var lastRow = range.end.row;
            +
            +        if (range.isMultiLine()) {
            +            var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1;
            +            var lastFullRow = lastRow - 1;
            +
            +            if (range.end.column > 0)
            +                this.removeInLine(lastRow, 0, range.end.column);
            +
            +            if (lastFullRow >= firstFullRow)
            +                this._removeLines(firstFullRow, lastFullRow);
            +
            +            if (firstFullRow != firstRow) {
            +                this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
            +                this.removeNewLine(range.start.row);
            +            }
            +        }
            +        else {
            +            this.removeInLine(firstRow, range.start.column, range.end.column);
            +        }
            +        return range.start;
            +    };
            +    this.removeInLine = function(row, startColumn, endColumn) {
            +        if (startColumn == endColumn)
            +            return;
            +
            +        var range = new Range(row, startColumn, row, endColumn);
            +        var line = this.getLine(row);
            +        var removed = line.substring(startColumn, endColumn);
            +        var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
            +        this.$lines.splice(row, 1, newLine);
            +
            +        var delta = {
            +            action: "removeText",
            +            range: range,
            +            text: removed
            +        };
            +        this._signal("change", { data: delta });
            +        return range.start;
            +    };
            +    this.removeLines = function(firstRow, lastRow) {
            +        if (firstRow < 0 || lastRow >= this.getLength())
            +            return this.remove(new Range(firstRow, 0, lastRow + 1, 0));
            +        return this._removeLines(firstRow, lastRow);
            +    };
            +
            +    this._removeLines = function(firstRow, lastRow) {
            +        var range = new Range(firstRow, 0, lastRow + 1, 0);
            +        var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
            +
            +        var delta = {
            +            action: "removeLines",
            +            range: range,
            +            nl: this.getNewLineCharacter(),
            +            lines: removed
            +        };
            +        this._signal("change", { data: delta });
            +        return removed;
            +    };
            +    this.removeNewLine = function(row) {
            +        var firstLine = this.getLine(row);
            +        var secondLine = this.getLine(row+1);
            +
            +        var range = new Range(row, firstLine.length, row+1, 0);
            +        var line = firstLine + secondLine;
            +
            +        this.$lines.splice(row, 2, line);
            +
            +        var delta = {
            +            action: "removeText",
            +            range: range,
            +            text: this.getNewLineCharacter()
            +        };
            +        this._signal("change", { data: delta });
            +    };
            +    this.replace = function(range, text) {
            +        if (!(range instanceof Range))
            +            range = Range.fromPoints(range.start, range.end);
            +        if (text.length == 0 && range.isEmpty())
            +            return range.start;
            +        if (text == this.getTextRange(range))
            +            return range.end;
            +
            +        this.remove(range);
            +        if (text) {
            +            var end = this.insert(range.start, text);
            +        }
            +        else {
            +            end = range.start;
            +        }
            +
            +        return end;
            +    };
            +    this.applyDeltas = function(deltas) {
            +        for (var i=0; i<deltas.length; i++) {
            +            var delta = deltas[i];
            +            var range = Range.fromPoints(delta.range.start, delta.range.end);
            +
            +            if (delta.action == "insertLines")
            +                this.insertLines(range.start.row, delta.lines);
            +            else if (delta.action == "insertText")
            +                this.insert(range.start, delta.text);
            +            else if (delta.action == "removeLines")
            +                this._removeLines(range.start.row, range.end.row - 1);
            +            else if (delta.action == "removeText")
            +                this.remove(range);
            +        }
            +    };
            +    this.revertDeltas = function(deltas) {
            +        for (var i=deltas.length-1; i>=0; i--) {
            +            var delta = deltas[i];
            +
            +            var range = Range.fromPoints(delta.range.start, delta.range.end);
            +
            +            if (delta.action == "insertLines")
            +                this._removeLines(range.start.row, range.end.row - 1);
            +            else if (delta.action == "insertText")
            +                this.remove(range);
            +            else if (delta.action == "removeLines")
            +                this._insertLines(range.start.row, delta.lines);
            +            else if (delta.action == "removeText")
            +                this.insert(range.start, delta.text);
            +        }
            +    };
            +    this.indexToPosition = function(index, startRow) {
            +        var lines = this.$lines || this.getAllLines();
            +        var newlineLength = this.getNewLineCharacter().length;
            +        for (var i = startRow || 0, l = lines.length; i < l; i++) {
            +            index -= lines[i].length + newlineLength;
            +            if (index < 0)
            +                return {row: i, column: index + lines[i].length + newlineLength};
            +        }
            +        return {row: l-1, column: lines[l-1].length};
            +    };
            +    this.positionToIndex = function(pos, startRow) {
            +        var lines = this.$lines || this.getAllLines();
            +        var newlineLength = this.getNewLineCharacter().length;
            +        var index = 0;
            +        var row = Math.min(pos.row, lines.length);
            +        for (var i = startRow || 0; i < row; ++i)
            +            index += lines[i].length + newlineLength;
            +
            +        return index + pos.column;
            +    };
            +
            +}).call(Document.prototype);
            +
            +exports.Document = Document;
            +});
            +
            +define("ace/background_tokenizer",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./lib/oop");
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +
            +var BackgroundTokenizer = function(tokenizer, editor) {
            +    this.running = false;
            +    this.lines = [];
            +    this.states = [];
            +    this.currentLine = 0;
            +    this.tokenizer = tokenizer;
            +
            +    var self = this;
            +
            +    this.$worker = function() {
            +        if (!self.running) { return; }
            +
            +        var workerStart = new Date();
            +        var currentLine = self.currentLine;
            +        var endLine = -1;
            +        var doc = self.doc;
            +
            +        while (self.lines[currentLine])
            +            currentLine++;
            +
            +        var startLine = currentLine;
            +
            +        var len = doc.getLength();
            +        var processedLines = 0;
            +        self.running = false;
            +        while (currentLine < len) {
            +            self.$tokenizeRow(currentLine);
            +            endLine = currentLine;
            +            do {
            +                currentLine++;
            +            } while (self.lines[currentLine]);
            +            processedLines ++;
            +            if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) {                
            +                self.running = setTimeout(self.$worker, 20);
            +                self.currentLine = currentLine;
            +                return;
            +            }
            +        }
            +        self.currentLine = currentLine;
            +        
            +        if (startLine <= endLine)
            +            self.fireUpdateEvent(startLine, endLine);
            +    };
            +};
            +
            +(function(){
            +
            +    oop.implement(this, EventEmitter);
            +    this.setTokenizer = function(tokenizer) {
            +        this.tokenizer = tokenizer;
            +        this.lines = [];
            +        this.states = [];
            +
            +        this.start(0);
            +    };
            +    this.setDocument = function(doc) {
            +        this.doc = doc;
            +        this.lines = [];
            +        this.states = [];
            +
            +        this.stop();
            +    };
            +    this.fireUpdateEvent = function(firstRow, lastRow) {
            +        var data = {
            +            first: firstRow,
            +            last: lastRow
            +        };
            +        this._signal("update", {data: data});
            +    };
            +    this.start = function(startRow) {
            +        this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());
            +        this.lines.splice(this.currentLine, this.lines.length);
            +        this.states.splice(this.currentLine, this.states.length);
            +
            +        this.stop();
            +        this.running = setTimeout(this.$worker, 700);
            +    };
            +    
            +    this.scheduleStart = function() {
            +        if (!this.running)
            +            this.running = setTimeout(this.$worker, 700);
            +    }
            +
            +    this.$updateOnChange = function(delta) {
            +        var range = delta.range;
            +        var startRow = range.start.row;
            +        var len = range.end.row - startRow;
            +
            +        if (len === 0) {
            +            this.lines[startRow] = null;
            +        } else if (delta.action == "removeText" || delta.action == "removeLines") {
            +            this.lines.splice(startRow, len + 1, null);
            +            this.states.splice(startRow, len + 1, null);
            +        } else {
            +            var args = Array(len + 1);
            +            args.unshift(startRow, 1);
            +            this.lines.splice.apply(this.lines, args);
            +            this.states.splice.apply(this.states, args);
            +        }
            +
            +        this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
            +
            +        this.stop();
            +    };
            +    this.stop = function() {
            +        if (this.running)
            +            clearTimeout(this.running);
            +        this.running = false;
            +    };
            +    this.getTokens = function(row) {
            +        return this.lines[row] || this.$tokenizeRow(row);
            +    };
            +    this.getState = function(row) {
            +        if (this.currentLine == row)
            +            this.$tokenizeRow(row);
            +        return this.states[row] || "start";
            +    };
            +
            +    this.$tokenizeRow = function(row) {
            +        var line = this.doc.getLine(row);
            +        var state = this.states[row - 1];
            +
            +        var data = this.tokenizer.getLineTokens(line, state, row);
            +
            +        if (this.states[row] + "" !== data.state + "") {
            +            this.states[row] = data.state;
            +            this.lines[row + 1] = null;
            +            if (this.currentLine > row + 1)
            +                this.currentLine = row + 1;
            +        } else if (this.currentLine == row) {
            +            this.currentLine = row + 1;
            +        }
            +
            +        return this.lines[row] = data.tokens;
            +    };
            +
            +}).call(BackgroundTokenizer.prototype);
            +
            +exports.BackgroundTokenizer = BackgroundTokenizer;
            +});
            +
            +define("ace/search_highlight",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(require, exports, module) {
            +"use strict";
            +
            +var lang = require("./lib/lang");
            +var oop = require("./lib/oop");
            +var Range = require("./range").Range;
            +
            +var SearchHighlight = function(regExp, clazz, type) {
            +    this.setRegexp(regExp);
            +    this.clazz = clazz;
            +    this.type = type || "text";
            +};
            +
            +(function() {
            +    this.MAX_RANGES = 500;
            +    
            +    this.setRegexp = function(regExp) {
            +        if (this.regExp+"" == regExp+"")
            +            return;
            +        this.regExp = regExp;
            +        this.cache = [];
            +    };
            +
            +    this.update = function(html, markerLayer, session, config) {
            +        if (!this.regExp)
            +            return;
            +        var start = config.firstRow, end = config.lastRow;
            +
            +        for (var i = start; i <= end; i++) {
            +            var ranges = this.cache[i];
            +            if (ranges == null) {
            +                ranges = lang.getMatchOffsets(session.getLine(i), this.regExp);
            +                if (ranges.length > this.MAX_RANGES)
            +                    ranges = ranges.slice(0, this.MAX_RANGES);
            +                ranges = ranges.map(function(match) {
            +                    return new Range(i, match.offset, i, match.offset + match.length);
            +                });
            +                this.cache[i] = ranges.length ? ranges : "";
            +            }
            +
            +            for (var j = ranges.length; j --; ) {
            +                markerLayer.drawSingleLineMarker(
            +                    html, ranges[j].toScreenRange(session), this.clazz, config);
            +            }
            +        }
            +    };
            +
            +}).call(SearchHighlight.prototype);
            +
            +exports.SearchHighlight = SearchHighlight;
            +});
            +
            +define("ace/edit_session/fold_line",["require","exports","module","ace/range"], function(require, exports, module) {
            +"use strict";
            +
            +var Range = require("../range").Range;
            +function FoldLine(foldData, folds) {
            +    this.foldData = foldData;
            +    if (Array.isArray(folds)) {
            +        this.folds = folds;
            +    } else {
            +        folds = this.folds = [ folds ];
            +    }
            +
            +    var last = folds[folds.length - 1]
            +    this.range = new Range(folds[0].start.row, folds[0].start.column,
            +                           last.end.row, last.end.column);
            +    this.start = this.range.start;
            +    this.end   = this.range.end;
            +
            +    this.folds.forEach(function(fold) {
            +        fold.setFoldLine(this);
            +    }, this);
            +}
            +
            +(function() {
            +    this.shiftRow = function(shift) {
            +        this.start.row += shift;
            +        this.end.row += shift;
            +        this.folds.forEach(function(fold) {
            +            fold.start.row += shift;
            +            fold.end.row += shift;
            +        });
            +    }
            +
            +    this.addFold = function(fold) {
            +        if (fold.sameRow) {
            +            if (fold.start.row < this.startRow || fold.endRow > this.endRow) {
            +                throw new Error("Can't add a fold to this FoldLine as it has no connection");
            +            }
            +            this.folds.push(fold);
            +            this.folds.sort(function(a, b) {
            +                return -a.range.compareEnd(b.start.row, b.start.column);
            +            });
            +            if (this.range.compareEnd(fold.start.row, fold.start.column) > 0) {
            +                this.end.row = fold.end.row;
            +                this.end.column =  fold.end.column;
            +            } else if (this.range.compareStart(fold.end.row, fold.end.column) < 0) {
            +                this.start.row = fold.start.row;
            +                this.start.column = fold.start.column;
            +            }
            +        } else if (fold.start.row == this.end.row) {
            +            this.folds.push(fold);
            +            this.end.row = fold.end.row;
            +            this.end.column = fold.end.column;
            +        } else if (fold.end.row == this.start.row) {
            +            this.folds.unshift(fold);
            +            this.start.row = fold.start.row;
            +            this.start.column = fold.start.column;
            +        } else {
            +            throw new Error("Trying to add fold to FoldRow that doesn't have a matching row");
            +        }
            +        fold.foldLine = this;
            +    }
            +
            +    this.containsRow = function(row) {
            +        return row >= this.start.row && row <= this.end.row;
            +    }
            +
            +    this.walk = function(callback, endRow, endColumn) {
            +        var lastEnd = 0,
            +            folds = this.folds,
            +            fold,
            +            comp, stop, isNewRow = true;
            +
            +        if (endRow == null) {
            +            endRow = this.end.row;
            +            endColumn = this.end.column;
            +        }
            +
            +        for (var i = 0; i < folds.length; i++) {
            +            fold = folds[i];
            +
            +            comp = fold.range.compareStart(endRow, endColumn);
            +            if (comp == -1) {
            +                callback(null, endRow, endColumn, lastEnd, isNewRow);
            +                return;
            +            }
            +
            +            stop = callback(null, fold.start.row, fold.start.column, lastEnd, isNewRow);
            +            stop = !stop && callback(fold.placeholder, fold.start.row, fold.start.column, lastEnd);
            +            if (stop || comp == 0) {
            +                return;
            +            }
            +            isNewRow = !fold.sameRow;
            +            lastEnd = fold.end.column;
            +        }
            +        callback(null, endRow, endColumn, lastEnd, isNewRow);
            +    }
            +
            +    this.getNextFoldTo = function(row, column) {
            +        var fold, cmp;
            +        for (var i = 0; i < this.folds.length; i++) {
            +            fold = this.folds[i];
            +            cmp = fold.range.compareEnd(row, column);
            +            if (cmp == -1) {
            +                return {
            +                    fold: fold,
            +                    kind: "after"
            +                };
            +            } else if (cmp == 0) {
            +                return {
            +                    fold: fold,
            +                    kind: "inside"
            +                }
            +            }
            +        }
            +        return null;
            +    }
            +
            +    this.addRemoveChars = function(row, column, len) {
            +        var ret = this.getNextFoldTo(row, column),
            +            fold, folds;
            +        if (ret) {
            +            fold = ret.fold;
            +            if (ret.kind == "inside"
            +                && fold.start.column != column
            +                && fold.start.row != row)
            +            {
            +                window.console && window.console.log(row, column, fold);
            +            } else if (fold.start.row == row) {
            +                folds = this.folds;
            +                var i = folds.indexOf(fold);
            +                if (i == 0) {
            +                    this.start.column += len;
            +                }
            +                for (i; i < folds.length; i++) {
            +                    fold = folds[i];
            +                    fold.start.column += len;
            +                    if (!fold.sameRow) {
            +                        return;
            +                    }
            +                    fold.end.column += len;
            +                }
            +                this.end.column += len;
            +            }
            +        }
            +    }
            +
            +    this.split = function(row, column) {
            +        var fold = this.getNextFoldTo(row, column).fold;
            +        var folds = this.folds;
            +        var foldData = this.foldData;
            +
            +        if (!fold)
            +            return null;
            +
            +        var i = folds.indexOf(fold);
            +        var foldBefore = folds[i - 1];
            +        this.end.row = foldBefore.end.row;
            +        this.end.column = foldBefore.end.column;
            +        folds = folds.splice(i, folds.length - i);
            +
            +        var newFoldLine = new FoldLine(foldData, folds);
            +        foldData.splice(foldData.indexOf(this) + 1, 0, newFoldLine);
            +        return newFoldLine;
            +    }
            +
            +    this.merge = function(foldLineNext) {
            +        var folds = foldLineNext.folds;
            +        for (var i = 0; i < folds.length; i++) {
            +            this.addFold(folds[i]);
            +        }
            +        var foldData = this.foldData;
            +        foldData.splice(foldData.indexOf(foldLineNext), 1);
            +    }
            +
            +    this.toString = function() {
            +        var ret = [this.range.toString() + ": [" ];
            +
            +        this.folds.forEach(function(fold) {
            +            ret.push("  " + fold.toString());
            +        });
            +        ret.push("]")
            +        return ret.join("\n");
            +    }
            +
            +    this.idxToPosition = function(idx) {
            +        var lastFoldEndColumn = 0;
            +        var fold;
            +
            +        for (var i = 0; i < this.folds.length; i++) {
            +            var fold = this.folds[i];
            +
            +            idx -= fold.start.column - lastFoldEndColumn;
            +            if (idx < 0) {
            +                return {
            +                    row: fold.start.row,
            +                    column: fold.start.column + idx
            +                };
            +            }
            +
            +            idx -= fold.placeholder.length;
            +            if (idx < 0) {
            +                return fold.start;
            +            }
            +
            +            lastFoldEndColumn = fold.end.column;
            +        }
            +
            +        return {
            +            row: this.end.row,
            +            column: this.end.column + idx
            +        };
            +    }
            +}).call(FoldLine.prototype);
            +
            +exports.FoldLine = FoldLine;
            +});
            +
            +define("ace/range_list",["require","exports","module","ace/range"], function(require, exports, module) {
            +"use strict";
            +var Range = require("./range").Range;
            +var comparePoints = Range.comparePoints;
            +
            +var RangeList = function() {
            +    this.ranges = [];
            +};
            +
            +(function() {
            +    this.comparePoints = comparePoints;
            +
            +    this.pointIndex = function(pos, excludeEdges, startIndex) {
            +        var list = this.ranges;
            +
            +        for (var i = startIndex || 0; i < list.length; i++) {
            +            var range = list[i];
            +            var cmpEnd = comparePoints(pos, range.end);
            +            if (cmpEnd > 0)
            +                continue;
            +            var cmpStart = comparePoints(pos, range.start);
            +            if (cmpEnd === 0)
            +                return excludeEdges && cmpStart !== 0 ? -i-2 : i;
            +            if (cmpStart > 0 || (cmpStart === 0 && !excludeEdges))
            +                return i;
            +
            +            return -i-1;
            +        }
            +        return -i - 1;
            +    };
            +
            +    this.add = function(range) {
            +        var excludeEdges = !range.isEmpty();
            +        var startIndex = this.pointIndex(range.start, excludeEdges);
            +        if (startIndex < 0)
            +            startIndex = -startIndex - 1;
            +
            +        var endIndex = this.pointIndex(range.end, excludeEdges, startIndex);
            +
            +        if (endIndex < 0)
            +            endIndex = -endIndex - 1;
            +        else
            +            endIndex++;
            +        return this.ranges.splice(startIndex, endIndex - startIndex, range);
            +    };
            +
            +    this.addList = function(list) {
            +        var removed = [];
            +        for (var i = list.length; i--; ) {
            +            removed.push.call(removed, this.add(list[i]));
            +        }
            +        return removed;
            +    };
            +
            +    this.substractPoint = function(pos) {
            +        var i = this.pointIndex(pos);
            +
            +        if (i >= 0)
            +            return this.ranges.splice(i, 1);
            +    };
            +    this.merge = function() {
            +        var removed = [];
            +        var list = this.ranges;
            +        
            +        list = list.sort(function(a, b) {
            +            return comparePoints(a.start, b.start);
            +        });
            +        
            +        var next = list[0], range;
            +        for (var i = 1; i < list.length; i++) {
            +            range = next;
            +            next = list[i];
            +            var cmp = comparePoints(range.end, next.start);
            +            if (cmp < 0)
            +                continue;
            +
            +            if (cmp == 0 && !range.isEmpty() && !next.isEmpty())
            +                continue;
            +
            +            if (comparePoints(range.end, next.end) < 0) {
            +                range.end.row = next.end.row;
            +                range.end.column = next.end.column;
            +            }
            +
            +            list.splice(i, 1);
            +            removed.push(next);
            +            next = range;
            +            i--;
            +        }
            +        
            +        this.ranges = list;
            +
            +        return removed;
            +    };
            +
            +    this.contains = function(row, column) {
            +        return this.pointIndex({row: row, column: column}) >= 0;
            +    };
            +
            +    this.containsPoint = function(pos) {
            +        return this.pointIndex(pos) >= 0;
            +    };
            +
            +    this.rangeAtPoint = function(pos) {
            +        var i = this.pointIndex(pos);
            +        if (i >= 0)
            +            return this.ranges[i];
            +    };
            +
            +
            +    this.clipRows = function(startRow, endRow) {
            +        var list = this.ranges;
            +        if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow)
            +            return [];
            +
            +        var startIndex = this.pointIndex({row: startRow, column: 0});
            +        if (startIndex < 0)
            +            startIndex = -startIndex - 1;
            +        var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex);
            +        if (endIndex < 0)
            +            endIndex = -endIndex - 1;
            +
            +        var clipped = [];
            +        for (var i = startIndex; i < endIndex; i++) {
            +            clipped.push(list[i]);
            +        }
            +        return clipped;
            +    };
            +
            +    this.removeAll = function() {
            +        return this.ranges.splice(0, this.ranges.length);
            +    };
            +
            +    this.attach = function(session) {
            +        if (this.session)
            +            this.detach();
            +
            +        this.session = session;
            +        this.onChange = this.$onChange.bind(this);
            +
            +        this.session.on('change', this.onChange);
            +    };
            +
            +    this.detach = function() {
            +        if (!this.session)
            +            return;
            +        this.session.removeListener('change', this.onChange);
            +        this.session = null;
            +    };
            +
            +    this.$onChange = function(e) {
            +        var changeRange = e.data.range;
            +        if (e.data.action[0] == "i"){
            +            var start = changeRange.start;
            +            var end = changeRange.end;
            +        } else {
            +            var end = changeRange.start;
            +            var start = changeRange.end;
            +        }
            +        var startRow = start.row;
            +        var endRow = end.row;
            +        var lineDif = endRow - startRow;
            +
            +        var colDiff = -start.column + end.column;
            +        var ranges = this.ranges;
            +
            +        for (var i = 0, n = ranges.length; i < n; i++) {
            +            var r = ranges[i];
            +            if (r.end.row < startRow)
            +                continue;
            +            if (r.start.row > startRow)
            +                break;
            +
            +            if (r.start.row == startRow && r.start.column >= start.column ) {
            +                if (r.start.column == start.column && this.$insertRight) {
            +                } else {
            +                    r.start.column += colDiff;
            +                    r.start.row += lineDif;
            +                }
            +            }
            +            if (r.end.row == startRow && r.end.column >= start.column) {
            +                if (r.end.column == start.column && this.$insertRight) {
            +                    continue;
            +                }
            +                if (r.end.column == start.column && colDiff > 0 && i < n - 1) {                
            +                    if (r.end.column > r.start.column && r.end.column == ranges[i+1].start.column)
            +                        r.end.column -= colDiff;
            +                }
            +                r.end.column += colDiff;
            +                r.end.row += lineDif;
            +            }
            +        }
            +
            +        if (lineDif != 0 && i < n) {
            +            for (; i < n; i++) {
            +                var r = ranges[i];
            +                r.start.row += lineDif;
            +                r.end.row += lineDif;
            +            }
            +        }
            +    };
            +
            +}).call(RangeList.prototype);
            +
            +exports.RangeList = RangeList;
            +});
            +
            +define("ace/edit_session/fold",["require","exports","module","ace/range","ace/range_list","ace/lib/oop"], function(require, exports, module) {
            +"use strict";
            +
            +var Range = require("../range").Range;
            +var RangeList = require("../range_list").RangeList;
            +var oop = require("../lib/oop")
            +var Fold = exports.Fold = function(range, placeholder) {
            +    this.foldLine = null;
            +    this.placeholder = placeholder;
            +    this.range = range;
            +    this.start = range.start;
            +    this.end = range.end;
            +
            +    this.sameRow = range.start.row == range.end.row;
            +    this.subFolds = this.ranges = [];
            +};
            +
            +oop.inherits(Fold, RangeList);
            +
            +(function() {
            +
            +    this.toString = function() {
            +        return '"' + this.placeholder + '" ' + this.range.toString();
            +    };
            +
            +    this.setFoldLine = function(foldLine) {
            +        this.foldLine = foldLine;
            +        this.subFolds.forEach(function(fold) {
            +            fold.setFoldLine(foldLine);
            +        });
            +    };
            +
            +    this.clone = function() {
            +        var range = this.range.clone();
            +        var fold = new Fold(range, this.placeholder);
            +        this.subFolds.forEach(function(subFold) {
            +            fold.subFolds.push(subFold.clone());
            +        });
            +        fold.collapseChildren = this.collapseChildren;
            +        return fold;
            +    };
            +
            +    this.addSubFold = function(fold) {
            +        if (this.range.isEqual(fold))
            +            return;
            +
            +        if (!this.range.containsRange(fold))
            +            throw new Error("A fold can't intersect already existing fold" + fold.range + this.range);
            +        consumeRange(fold, this.start);
            +
            +        var row = fold.start.row, column = fold.start.column;
            +        for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
            +            cmp = this.subFolds[i].range.compare(row, column);
            +            if (cmp != 1)
            +                break;
            +        }
            +        var afterStart = this.subFolds[i];
            +
            +        if (cmp == 0)
            +            return afterStart.addSubFold(fold);
            +        var row = fold.range.end.row, column = fold.range.end.column;
            +        for (var j = i, cmp = -1; j < this.subFolds.length; j++) {
            +            cmp = this.subFolds[j].range.compare(row, column);
            +            if (cmp != 1)
            +                break;
            +        }
            +        var afterEnd = this.subFolds[j];
            +
            +        if (cmp == 0)
            +            throw new Error("A fold can't intersect already existing fold" + fold.range + this.range);
            +
            +        var consumedFolds = this.subFolds.splice(i, j - i, fold);
            +        fold.setFoldLine(this.foldLine);
            +
            +        return fold;
            +    };
            +    
            +    this.restoreRange = function(range) {
            +        return restoreRange(range, this.start);
            +    };
            +
            +}).call(Fold.prototype);
            +
            +function consumePoint(point, anchor) {
            +    point.row -= anchor.row;
            +    if (point.row == 0)
            +        point.column -= anchor.column;
            +}
            +function consumeRange(range, anchor) {
            +    consumePoint(range.start, anchor);
            +    consumePoint(range.end, anchor);
            +}
            +function restorePoint(point, anchor) {
            +    if (point.row == 0)
            +        point.column += anchor.column;
            +    point.row += anchor.row;
            +}
            +function restoreRange(range, anchor) {
            +    restorePoint(range.start, anchor);
            +    restorePoint(range.end, anchor);
            +}
            +
            +});
            +
            +define("ace/edit_session/folding",["require","exports","module","ace/range","ace/edit_session/fold_line","ace/edit_session/fold","ace/token_iterator"], function(require, exports, module) {
            +"use strict";
            +
            +var Range = require("../range").Range;
            +var FoldLine = require("./fold_line").FoldLine;
            +var Fold = require("./fold").Fold;
            +var TokenIterator = require("../token_iterator").TokenIterator;
            +
            +function Folding() {
            +    this.getFoldAt = function(row, column, side) {
            +        var foldLine = this.getFoldLine(row);
            +        if (!foldLine)
            +            return null;
            +
            +        var folds = foldLine.folds;
            +        for (var i = 0; i < folds.length; i++) {
            +            var fold = folds[i];
            +            if (fold.range.contains(row, column)) {
            +                if (side == 1 && fold.range.isEnd(row, column)) {
            +                    continue;
            +                } else if (side == -1 && fold.range.isStart(row, column)) {
            +                    continue;
            +                }
            +                return fold;
            +            }
            +        }
            +    };
            +    this.getFoldsInRange = function(range) {
            +        var start = range.start;
            +        var end = range.end;
            +        var foldLines = this.$foldData;
            +        var foundFolds = [];
            +
            +        start.column += 1;
            +        end.column -= 1;
            +
            +        for (var i = 0; i < foldLines.length; i++) {
            +            var cmp = foldLines[i].range.compareRange(range);
            +            if (cmp == 2) {
            +                continue;
            +            }
            +            else if (cmp == -2) {
            +                break;
            +            }
            +
            +            var folds = foldLines[i].folds;
            +            for (var j = 0; j < folds.length; j++) {
            +                var fold = folds[j];
            +                cmp = fold.range.compareRange(range);
            +                if (cmp == -2) {
            +                    break;
            +                } else if (cmp == 2) {
            +                    continue;
            +                } else
            +                if (cmp == 42) {
            +                    break;
            +                }
            +                foundFolds.push(fold);
            +            }
            +        }
            +        start.column -= 1;
            +        end.column += 1;
            +
            +        return foundFolds;
            +    };
            +
            +    this.getFoldsInRangeList = function(ranges) {
            +        if (Array.isArray(ranges)) {
            +            var folds = [];
            +            ranges.forEach(function(range) {
            +                folds = folds.concat(this.getFoldsInRange(range));
            +            }, this);
            +        } else {
            +            var folds = this.getFoldsInRange(ranges);
            +        }
            +        return folds;
            +    }
            +    this.getAllFolds = function() {
            +        var folds = [];
            +        var foldLines = this.$foldData;
            +        
            +        for (var i = 0; i < foldLines.length; i++)
            +            for (var j = 0; j < foldLines[i].folds.length; j++)
            +                folds.push(foldLines[i].folds[j]);
            +
            +        return folds;
            +    };
            +    this.getFoldStringAt = function(row, column, trim, foldLine) {
            +        foldLine = foldLine || this.getFoldLine(row);
            +        if (!foldLine)
            +            return null;
            +
            +        var lastFold = {
            +            end: { column: 0 }
            +        };
            +        var str, fold;
            +        for (var i = 0; i < foldLine.folds.length; i++) {
            +            fold = foldLine.folds[i];
            +            var cmp = fold.range.compareEnd(row, column);
            +            if (cmp == -1) {
            +                str = this
            +                    .getLine(fold.start.row)
            +                    .substring(lastFold.end.column, fold.start.column);
            +                break;
            +            }
            +            else if (cmp === 0) {
            +                return null;
            +            }
            +            lastFold = fold;
            +        }
            +        if (!str)
            +            str = this.getLine(fold.start.row).substring(lastFold.end.column);
            +
            +        if (trim == -1)
            +            return str.substring(0, column - lastFold.end.column);
            +        else if (trim == 1)
            +            return str.substring(column - lastFold.end.column);
            +        else
            +            return str;
            +    };
            +
            +    this.getFoldLine = function(docRow, startFoldLine) {
            +        var foldData = this.$foldData;
            +        var i = 0;
            +        if (startFoldLine)
            +            i = foldData.indexOf(startFoldLine);
            +        if (i == -1)
            +            i = 0;
            +        for (i; i < foldData.length; i++) {
            +            var foldLine = foldData[i];
            +            if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {
            +                return foldLine;
            +            } else if (foldLine.end.row > docRow) {
            +                return null;
            +            }
            +        }
            +        return null;
            +    };
            +    this.getNextFoldLine = function(docRow, startFoldLine) {
            +        var foldData = this.$foldData;
            +        var i = 0;
            +        if (startFoldLine)
            +            i = foldData.indexOf(startFoldLine);
            +        if (i == -1)
            +            i = 0;
            +        for (i; i < foldData.length; i++) {
            +            var foldLine = foldData[i];
            +            if (foldLine.end.row >= docRow) {
            +                return foldLine;
            +            }
            +        }
            +        return null;
            +    };
            +
            +    this.getFoldedRowCount = function(first, last) {
            +        var foldData = this.$foldData, rowCount = last-first+1;
            +        for (var i = 0; i < foldData.length; i++) {
            +            var foldLine = foldData[i],
            +                end = foldLine.end.row,
            +                start = foldLine.start.row;
            +            if (end >= last) {
            +                if(start < last) {
            +                    if(start >= first)
            +                        rowCount -= last-start;
            +                    else
            +                        rowCount = 0;//in one fold
            +                }
            +                break;
            +            } else if(end >= first){
            +                if (start >= first) //fold inside range
            +                    rowCount -=  end-start;
            +                else
            +                    rowCount -=  end-first+1;
            +            }
            +        }
            +        return rowCount;
            +    };
            +
            +    this.$addFoldLine = function(foldLine) {
            +        this.$foldData.push(foldLine);
            +        this.$foldData.sort(function(a, b) {
            +            return a.start.row - b.start.row;
            +        });
            +        return foldLine;
            +    };
            +    this.addFold = function(placeholder, range) {
            +        var foldData = this.$foldData;
            +        var added = false;
            +        var fold;
            +        
            +        if (placeholder instanceof Fold)
            +            fold = placeholder;
            +        else {
            +            fold = new Fold(range, placeholder);
            +            fold.collapseChildren = range.collapseChildren;
            +        }
            +        this.$clipRangeToDocument(fold.range);
            +
            +        var startRow = fold.start.row;
            +        var startColumn = fold.start.column;
            +        var endRow = fold.end.row;
            +        var endColumn = fold.end.column;
            +        if (!(startRow < endRow || 
            +            startRow == endRow && startColumn <= endColumn - 2))
            +            throw new Error("The range has to be at least 2 characters width");
            +
            +        var startFold = this.getFoldAt(startRow, startColumn, 1);
            +        var endFold = this.getFoldAt(endRow, endColumn, -1);
            +        if (startFold && endFold == startFold)
            +            return startFold.addSubFold(fold);
            +
            +        if (
            +            (startFold && !startFold.range.isStart(startRow, startColumn))
            +            || (endFold && !endFold.range.isEnd(endRow, endColumn))
            +        ) {
            +            throw new Error("A fold can't intersect already existing fold" + fold.range + startFold.range);
            +        }
            +        var folds = this.getFoldsInRange(fold.range);
            +        if (folds.length > 0) {
            +            this.removeFolds(folds);
            +            folds.forEach(function(subFold) {
            +                fold.addSubFold(subFold);
            +            });
            +        }
            +
            +        for (var i = 0; i < foldData.length; i++) {
            +            var foldLine = foldData[i];
            +            if (endRow == foldLine.start.row) {
            +                foldLine.addFold(fold);
            +                added = true;
            +                break;
            +            } else if (startRow == foldLine.end.row) {
            +                foldLine.addFold(fold);
            +                added = true;
            +                if (!fold.sameRow) {
            +                    var foldLineNext = foldData[i + 1];
            +                    if (foldLineNext && foldLineNext.start.row == endRow) {
            +                        foldLine.merge(foldLineNext);
            +                        break;
            +                    }
            +                }
            +                break;
            +            } else if (endRow <= foldLine.start.row) {
            +                break;
            +            }
            +        }
            +
            +        if (!added)
            +            foldLine = this.$addFoldLine(new FoldLine(this.$foldData, fold));
            +
            +        if (this.$useWrapMode)
            +            this.$updateWrapData(foldLine.start.row, foldLine.start.row);
            +        else
            +            this.$updateRowLengthCache(foldLine.start.row, foldLine.start.row);
            +        this.$modified = true;
            +        this._emit("changeFold", { data: fold, action: "add" });
            +
            +        return fold;
            +    };
            +
            +    this.addFolds = function(folds) {
            +        folds.forEach(function(fold) {
            +            this.addFold(fold);
            +        }, this);
            +    };
            +
            +    this.removeFold = function(fold) {
            +        var foldLine = fold.foldLine;
            +        var startRow = foldLine.start.row;
            +        var endRow = foldLine.end.row;
            +
            +        var foldLines = this.$foldData;
            +        var folds = foldLine.folds;
            +        if (folds.length == 1) {
            +            foldLines.splice(foldLines.indexOf(foldLine), 1);
            +        } else
            +        if (foldLine.range.isEnd(fold.end.row, fold.end.column)) {
            +            folds.pop();
            +            foldLine.end.row = folds[folds.length - 1].end.row;
            +            foldLine.end.column = folds[folds.length - 1].end.column;
            +        } else
            +        if (foldLine.range.isStart(fold.start.row, fold.start.column)) {
            +            folds.shift();
            +            foldLine.start.row = folds[0].start.row;
            +            foldLine.start.column = folds[0].start.column;
            +        } else
            +        if (fold.sameRow) {
            +            folds.splice(folds.indexOf(fold), 1);
            +        } else
            +        {
            +            var newFoldLine = foldLine.split(fold.start.row, fold.start.column);
            +            folds = newFoldLine.folds;
            +            folds.shift();
            +            newFoldLine.start.row = folds[0].start.row;
            +            newFoldLine.start.column = folds[0].start.column;
            +        }
            +
            +        if (!this.$updating) {
            +            if (this.$useWrapMode)
            +                this.$updateWrapData(startRow, endRow);
            +            else
            +                this.$updateRowLengthCache(startRow, endRow);
            +        }
            +        this.$modified = true;
            +        this._emit("changeFold", { data: fold, action: "remove" });
            +    };
            +
            +    this.removeFolds = function(folds) {
            +        var cloneFolds = [];
            +        for (var i = 0; i < folds.length; i++) {
            +            cloneFolds.push(folds[i]);
            +        }
            +
            +        cloneFolds.forEach(function(fold) {
            +            this.removeFold(fold);
            +        }, this);
            +        this.$modified = true;
            +    };
            +
            +    this.expandFold = function(fold) {
            +        this.removeFold(fold);
            +        fold.subFolds.forEach(function(subFold) {
            +            fold.restoreRange(subFold);
            +            this.addFold(subFold);
            +        }, this);
            +        if (fold.collapseChildren > 0) {
            +            this.foldAll(fold.start.row+1, fold.end.row, fold.collapseChildren-1);
            +        }
            +        fold.subFolds = [];
            +    };
            +
            +    this.expandFolds = function(folds) {
            +        folds.forEach(function(fold) {
            +            this.expandFold(fold);
            +        }, this);
            +    };
            +
            +    this.unfold = function(location, expandInner) {
            +        var range, folds;
            +        if (location == null) {
            +            range = new Range(0, 0, this.getLength(), 0);
            +            expandInner = true;
            +        } else if (typeof location == "number")
            +            range = new Range(location, 0, location, this.getLine(location).length);
            +        else if ("row" in location)
            +            range = Range.fromPoints(location, location);
            +        else
            +            range = location;
            +        
            +        folds = this.getFoldsInRangeList(range);
            +        if (expandInner) {
            +            this.removeFolds(folds);
            +        } else {
            +            var subFolds = folds;
            +            while (subFolds.length) {
            +                this.expandFolds(subFolds);
            +                subFolds = this.getFoldsInRangeList(range);
            +            }
            +        }
            +        if (folds.length)
            +            return folds;
            +    };
            +    this.isRowFolded = function(docRow, startFoldRow) {
            +        return !!this.getFoldLine(docRow, startFoldRow);
            +    };
            +
            +    this.getRowFoldEnd = function(docRow, startFoldRow) {
            +        var foldLine = this.getFoldLine(docRow, startFoldRow);
            +        return foldLine ? foldLine.end.row : docRow;
            +    };
            +
            +    this.getRowFoldStart = function(docRow, startFoldRow) {
            +        var foldLine = this.getFoldLine(docRow, startFoldRow);
            +        return foldLine ? foldLine.start.row : docRow;
            +    };
            +
            +    this.getFoldDisplayLine = function(foldLine, endRow, endColumn, startRow, startColumn) {
            +        if (startRow == null)
            +            startRow = foldLine.start.row;
            +        if (startColumn == null)
            +            startColumn = 0;
            +        if (endRow == null)
            +            endRow = foldLine.end.row;
            +        if (endColumn == null)
            +            endColumn = this.getLine(endRow).length;
            +        var doc = this.doc;
            +        var textLine = "";
            +
            +        foldLine.walk(function(placeholder, row, column, lastColumn) {
            +            if (row < startRow)
            +                return;
            +            if (row == startRow) {
            +                if (column < startColumn)
            +                    return;
            +                lastColumn = Math.max(startColumn, lastColumn);
            +            }
            +
            +            if (placeholder != null) {
            +                textLine += placeholder;
            +            } else {
            +                textLine += doc.getLine(row).substring(lastColumn, column);
            +            }
            +        }, endRow, endColumn);
            +        return textLine;
            +    };
            +
            +    this.getDisplayLine = function(row, endColumn, startRow, startColumn) {
            +        var foldLine = this.getFoldLine(row);
            +
            +        if (!foldLine) {
            +            var line;
            +            line = this.doc.getLine(row);
            +            return line.substring(startColumn || 0, endColumn || line.length);
            +        } else {
            +            return this.getFoldDisplayLine(
            +                foldLine, row, endColumn, startRow, startColumn);
            +        }
            +    };
            +
            +    this.$cloneFoldData = function() {
            +        var fd = [];
            +        fd = this.$foldData.map(function(foldLine) {
            +            var folds = foldLine.folds.map(function(fold) {
            +                return fold.clone();
            +            });
            +            return new FoldLine(fd, folds);
            +        });
            +
            +        return fd;
            +    };
            +
            +    this.toggleFold = function(tryToUnfold) {
            +        var selection = this.selection;
            +        var range = selection.getRange();
            +        var fold;
            +        var bracketPos;
            +
            +        if (range.isEmpty()) {
            +            var cursor = range.start;
            +            fold = this.getFoldAt(cursor.row, cursor.column);
            +
            +            if (fold) {
            +                this.expandFold(fold);
            +                return;
            +            } else if (bracketPos = this.findMatchingBracket(cursor)) {
            +                if (range.comparePoint(bracketPos) == 1) {
            +                    range.end = bracketPos;
            +                } else {
            +                    range.start = bracketPos;
            +                    range.start.column++;
            +                    range.end.column--;
            +                }
            +            } else if (bracketPos = this.findMatchingBracket({row: cursor.row, column: cursor.column + 1})) {
            +                if (range.comparePoint(bracketPos) == 1)
            +                    range.end = bracketPos;
            +                else
            +                    range.start = bracketPos;
            +
            +                range.start.column++;
            +            } else {
            +                range = this.getCommentFoldRange(cursor.row, cursor.column) || range;
            +            }
            +        } else {
            +            var folds = this.getFoldsInRange(range);
            +            if (tryToUnfold && folds.length) {
            +                this.expandFolds(folds);
            +                return;
            +            } else if (folds.length == 1 ) {
            +                fold = folds[0];
            +            }
            +        }
            +
            +        if (!fold)
            +            fold = this.getFoldAt(range.start.row, range.start.column);
            +
            +        if (fold && fold.range.toString() == range.toString()) {
            +            this.expandFold(fold);
            +            return;
            +        }
            +
            +        var placeholder = "...";
            +        if (!range.isMultiLine()) {
            +            placeholder = this.getTextRange(range);
            +            if(placeholder.length < 4)
            +                return;
            +            placeholder = placeholder.trim().substring(0, 2) + "..";
            +        }
            +
            +        this.addFold(placeholder, range);
            +    };
            +
            +    this.getCommentFoldRange = function(row, column, dir) {
            +        var iterator = new TokenIterator(this, row, column);
            +        var token = iterator.getCurrentToken();
            +        if (token && /^comment|string/.test(token.type)) {
            +            var range = new Range();
            +            var re = new RegExp(token.type.replace(/\..*/, "\\."));
            +            if (dir != 1) {
            +                do {
            +                    token = iterator.stepBackward();
            +                } while(token && re.test(token.type));
            +                iterator.stepForward();
            +            }
            +            
            +            range.start.row = iterator.getCurrentTokenRow();
            +            range.start.column = iterator.getCurrentTokenColumn() + 2;
            +
            +            iterator = new TokenIterator(this, row, column);
            +            
            +            if (dir != -1) {
            +                do {
            +                    token = iterator.stepForward();
            +                } while(token && re.test(token.type));
            +                token = iterator.stepBackward();
            +            } else
            +                token = iterator.getCurrentToken();
            +
            +            range.end.row = iterator.getCurrentTokenRow();
            +            range.end.column = iterator.getCurrentTokenColumn() + token.value.length - 2;
            +            return range;
            +        }
            +    };
            +
            +    this.foldAll = function(startRow, endRow, depth) {
            +        if (depth == undefined)
            +            depth = 100000; // JSON.stringify doesn't hanle Infinity
            +        var foldWidgets = this.foldWidgets;
            +        if (!foldWidgets)
            +            return; // mode doesn't support folding
            +        endRow = endRow || this.getLength();
            +        startRow = startRow || 0;
            +        for (var row = startRow; row < endRow; row++) {
            +            if (foldWidgets[row] == null)
            +                foldWidgets[row] = this.getFoldWidget(row);
            +            if (foldWidgets[row] != "start")
            +                continue;
            +
            +            var range = this.getFoldWidgetRange(row);
            +            if (range && range.isMultiLine()
            +                && range.end.row <= endRow
            +                && range.start.row >= startRow
            +            ) {
            +                row = range.end.row;
            +                try {
            +                    var fold = this.addFold("...", range);
            +                    if (fold)
            +                        fold.collapseChildren = depth;
            +                } catch(e) {}
            +            }
            +        }
            +    };
            +    this.$foldStyles = {
            +        "manual": 1,
            +        "markbegin": 1,
            +        "markbeginend": 1
            +    };
            +    this.$foldStyle = "markbegin";
            +    this.setFoldStyle = function(style) {
            +        if (!this.$foldStyles[style])
            +            throw new Error("invalid fold style: " + style + "[" + Object.keys(this.$foldStyles).join(", ") + "]");
            +        
            +        if (this.$foldStyle == style)
            +            return;
            +
            +        this.$foldStyle = style;
            +        
            +        if (style == "manual")
            +            this.unfold();
            +        var mode = this.$foldMode;
            +        this.$setFolding(null);
            +        this.$setFolding(mode);
            +    };
            +
            +    this.$setFolding = function(foldMode) {
            +        if (this.$foldMode == foldMode)
            +            return;
            +            
            +        this.$foldMode = foldMode;
            +        
            +        this.removeListener('change', this.$updateFoldWidgets);
            +        this._emit("changeAnnotation");
            +        
            +        if (!foldMode || this.$foldStyle == "manual") {
            +            this.foldWidgets = null;
            +            return;
            +        }
            +        
            +        this.foldWidgets = [];
            +        this.getFoldWidget = foldMode.getFoldWidget.bind(foldMode, this, this.$foldStyle);
            +        this.getFoldWidgetRange = foldMode.getFoldWidgetRange.bind(foldMode, this, this.$foldStyle);
            +        
            +        this.$updateFoldWidgets = this.updateFoldWidgets.bind(this);
            +        this.on('change', this.$updateFoldWidgets);
            +        
            +    };
            +
            +    this.getParentFoldRangeData = function (row, ignoreCurrent) {
            +        var fw = this.foldWidgets;
            +        if (!fw || (ignoreCurrent && fw[row]))
            +            return {};
            +
            +        var i = row - 1, firstRange;
            +        while (i >= 0) {
            +            var c = fw[i];
            +            if (c == null)
            +                c = fw[i] = this.getFoldWidget(i);
            +
            +            if (c == "start") {
            +                var range = this.getFoldWidgetRange(i);
            +                if (!firstRange)
            +                    firstRange = range;
            +                if (range && range.end.row >= row)
            +                    break;
            +            }
            +            i--;
            +        }
            +
            +        return {
            +            range: i !== -1 && range,
            +            firstRange: firstRange
            +        };
            +    }
            +
            +    this.onFoldWidgetClick = function(row, e) {
            +        e = e.domEvent;
            +        var options = {
            +            children: e.shiftKey,
            +            all: e.ctrlKey || e.metaKey,
            +            siblings: e.altKey
            +        };
            +        
            +        var range = this.$toggleFoldWidget(row, options);
            +        if (!range) {
            +            var el = (e.target || e.srcElement)
            +            if (el && /ace_fold-widget/.test(el.className))
            +                el.className += " ace_invalid";
            +        }
            +    };
            +    
            +    this.$toggleFoldWidget = function(row, options) {
            +        if (!this.getFoldWidget)
            +            return;
            +        var type = this.getFoldWidget(row);
            +        var line = this.getLine(row);
            +
            +        var dir = type === "end" ? -1 : 1;
            +        var fold = this.getFoldAt(row, dir === -1 ? 0 : line.length, dir);
            +
            +        if (fold) {
            +            if (options.children || options.all)
            +                this.removeFold(fold);
            +            else
            +                this.expandFold(fold);
            +            return;
            +        }
            +
            +        var range = this.getFoldWidgetRange(row, true);
            +        if (range && !range.isMultiLine()) {
            +            fold = this.getFoldAt(range.start.row, range.start.column, 1);
            +            if (fold && range.isEqual(fold.range)) {
            +                this.removeFold(fold);
            +                return;
            +            }
            +        }
            +        
            +        if (options.siblings) {
            +            var data = this.getParentFoldRangeData(row);
            +            if (data.range) {
            +                var startRow = data.range.start.row + 1;
            +                var endRow = data.range.end.row;
            +            }
            +            this.foldAll(startRow, endRow, options.all ? 10000 : 0);
            +        } else if (options.children) {
            +            endRow = range ? range.end.row : this.getLength();
            +            this.foldAll(row + 1, range.end.row, options.all ? 10000 : 0);
            +        } else if (range) {
            +            if (options.all) 
            +                range.collapseChildren = 10000;
            +            this.addFold("...", range);
            +        }
            +        
            +        return range;
            +    };
            +    
            +    
            +    
            +    this.toggleFoldWidget = function(toggleParent) {
            +        var row = this.selection.getCursor().row;
            +        row = this.getRowFoldStart(row);
            +        var range = this.$toggleFoldWidget(row, {});
            +        
            +        if (range)
            +            return;
            +        var data = this.getParentFoldRangeData(row, true);
            +        range = data.range || data.firstRange;
            +        
            +        if (range) {
            +            row = range.start.row;
            +            var fold = this.getFoldAt(row, this.getLine(row).length, 1);
            +
            +            if (fold) {
            +                this.removeFold(fold);
            +            } else {
            +                this.addFold("...", range);
            +            }
            +        }
            +    };
            +
            +    this.updateFoldWidgets = function(e) {
            +        var delta = e.data;
            +        var range = delta.range;
            +        var firstRow = range.start.row;
            +        var len = range.end.row - firstRow;
            +
            +        if (len === 0) {
            +            this.foldWidgets[firstRow] = null;
            +        } else if (delta.action == "removeText" || delta.action == "removeLines") {
            +            this.foldWidgets.splice(firstRow, len + 1, null);
            +        } else {
            +            var args = Array(len + 1);
            +            args.unshift(firstRow, 1);
            +            this.foldWidgets.splice.apply(this.foldWidgets, args);
            +        }
            +    };
            +
            +}
            +
            +exports.Folding = Folding;
            +
            +});
            +
            +define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator","ace/range"], function(require, exports, module) {
            +"use strict";
            +
            +var TokenIterator = require("../token_iterator").TokenIterator;
            +var Range = require("../range").Range;
            +
            +
            +function BracketMatch() {
            +
            +    this.findMatchingBracket = function(position, chr) {
            +        if (position.column == 0) return null;
            +
            +        var charBeforeCursor = chr || this.getLine(position.row).charAt(position.column-1);
            +        if (charBeforeCursor == "") return null;
            +
            +        var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/);
            +        if (!match)
            +            return null;
            +
            +        if (match[1])
            +            return this.$findClosingBracket(match[1], position);
            +        else
            +            return this.$findOpeningBracket(match[2], position);
            +    };
            +    
            +    this.getBracketRange = function(pos) {
            +        var line = this.getLine(pos.row);
            +        var before = true, range;
            +
            +        var chr = line.charAt(pos.column-1);
            +        var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
            +        if (!match) {
            +            chr = line.charAt(pos.column);
            +            pos = {row: pos.row, column: pos.column + 1};
            +            match = chr && chr.match(/([\(\[\{])|([\)\]\}])/);
            +            before = false;
            +        }
            +        if (!match)
            +            return null;
            +
            +        if (match[1]) {
            +            var bracketPos = this.$findClosingBracket(match[1], pos);
            +            if (!bracketPos)
            +                return null;
            +            range = Range.fromPoints(pos, bracketPos);
            +            if (!before) {
            +                range.end.column++;
            +                range.start.column--;
            +            }
            +            range.cursor = range.end;
            +        } else {
            +            var bracketPos = this.$findOpeningBracket(match[2], pos);
            +            if (!bracketPos)
            +                return null;
            +            range = Range.fromPoints(bracketPos, pos);
            +            if (!before) {
            +                range.start.column++;
            +                range.end.column--;
            +            }
            +            range.cursor = range.start;
            +        }
            +        
            +        return range;
            +    };
            +
            +    this.$brackets = {
            +        ")": "(",
            +        "(": ")",
            +        "]": "[",
            +        "[": "]",
            +        "{": "}",
            +        "}": "{"
            +    };
            +
            +    this.$findOpeningBracket = function(bracket, position, typeRe) {
            +        var openBracket = this.$brackets[bracket];
            +        var depth = 1;
            +
            +        var iterator = new TokenIterator(this, position.row, position.column);
            +        var token = iterator.getCurrentToken();
            +        if (!token)
            +            token = iterator.stepForward();
            +        if (!token)
            +            return;
            +        
            +         if (!typeRe){
            +            typeRe = new RegExp(
            +                "(\\.?" +
            +                token.type.replace(".", "\\.").replace("rparen", ".paren")
            +                + ")+"
            +            );
            +        }
            +        var valueIndex = position.column - iterator.getCurrentTokenColumn() - 2;
            +        var value = token.value;
            +        
            +        while (true) {
            +        
            +            while (valueIndex >= 0) {
            +                var chr = value.charAt(valueIndex);
            +                if (chr == openBracket) {
            +                    depth -= 1;
            +                    if (depth == 0) {
            +                        return {row: iterator.getCurrentTokenRow(),
            +                            column: valueIndex + iterator.getCurrentTokenColumn()};
            +                    }
            +                }
            +                else if (chr == bracket) {
            +                    depth += 1;
            +                }
            +                valueIndex -= 1;
            +            }
            +            do {
            +                token = iterator.stepBackward();
            +            } while (token && !typeRe.test(token.type));
            +
            +            if (token == null)
            +                break;
            +                
            +            value = token.value;
            +            valueIndex = value.length - 1;
            +        }
            +        
            +        return null;
            +    };
            +
            +    this.$findClosingBracket = function(bracket, position, typeRe) {
            +        var closingBracket = this.$brackets[bracket];
            +        var depth = 1;
            +
            +        var iterator = new TokenIterator(this, position.row, position.column);
            +        var token = iterator.getCurrentToken();
            +        if (!token)
            +            token = iterator.stepForward();
            +        if (!token)
            +            return;
            +
            +        if (!typeRe){
            +            typeRe = new RegExp(
            +                "(\\.?" +
            +                token.type.replace(".", "\\.").replace("lparen", ".paren")
            +                + ")+"
            +            );
            +        }
            +        var valueIndex = position.column - iterator.getCurrentTokenColumn();
            +
            +        while (true) {
            +
            +            var value = token.value;
            +            var valueLength = value.length;
            +            while (valueIndex < valueLength) {
            +                var chr = value.charAt(valueIndex);
            +                if (chr == closingBracket) {
            +                    depth -= 1;
            +                    if (depth == 0) {
            +                        return {row: iterator.getCurrentTokenRow(),
            +                            column: valueIndex + iterator.getCurrentTokenColumn()};
            +                    }
            +                }
            +                else if (chr == bracket) {
            +                    depth += 1;
            +                }
            +                valueIndex += 1;
            +            }
            +            do {
            +                token = iterator.stepForward();
            +            } while (token && !typeRe.test(token.type));
            +
            +            if (token == null)
            +                break;
            +
            +            valueIndex = 0;
            +        }
            +        
            +        return null;
            +    };
            +}
            +exports.BracketMatch = BracketMatch;
            +
            +});
            +
            +define("ace/edit_session",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/config","ace/lib/event_emitter","ace/selection","ace/mode/text","ace/range","ace/document","ace/background_tokenizer","ace/search_highlight","ace/edit_session/folding","ace/edit_session/bracket_match"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./lib/oop");
            +var lang = require("./lib/lang");
            +var config = require("./config");
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +var Selection = require("./selection").Selection;
            +var TextMode = require("./mode/text").Mode;
            +var Range = require("./range").Range;
            +var Document = require("./document").Document;
            +var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer;
            +var SearchHighlight = require("./search_highlight").SearchHighlight;
            +
            +var EditSession = function(text, mode) {
            +    this.$breakpoints = [];
            +    this.$decorations = [];
            +    this.$frontMarkers = {};
            +    this.$backMarkers = {};
            +    this.$markerId = 1;
            +    this.$undoSelect = true;
            +
            +    this.$foldData = [];
            +    this.$foldData.toString = function() {
            +        return this.join("\n");
            +    }
            +    this.on("changeFold", this.onChangeFold.bind(this));
            +    this.$onChange = this.onChange.bind(this);
            +
            +    if (typeof text != "object" || !text.getLine)
            +        text = new Document(text);
            +
            +    this.setDocument(text);
            +    this.selection = new Selection(this);
            +
            +    config.resetOptions(this);
            +    this.setMode(mode);
            +    config._signal("session", this);
            +};
            +
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +    this.setDocument = function(doc) {
            +        if (this.doc)
            +            this.doc.removeListener("change", this.$onChange);
            +
            +        this.doc = doc;
            +        doc.on("change", this.$onChange);
            +
            +        if (this.bgTokenizer)
            +            this.bgTokenizer.setDocument(this.getDocument());
            +
            +        this.resetCaches();
            +    };
            +    this.getDocument = function() {
            +        return this.doc;
            +    };
            +    this.$resetRowCache = function(docRow) {
            +        if (!docRow) {
            +            this.$docRowCache = [];
            +            this.$screenRowCache = [];
            +            return;
            +        }
            +        var l = this.$docRowCache.length;
            +        var i = this.$getRowCacheIndex(this.$docRowCache, docRow) + 1;
            +        if (l > i) {
            +            this.$docRowCache.splice(i, l);
            +            this.$screenRowCache.splice(i, l);
            +        }
            +    };
            +
            +    this.$getRowCacheIndex = function(cacheArray, val) {
            +        var low = 0;
            +        var hi = cacheArray.length - 1;
            +
            +        while (low <= hi) {
            +            var mid = (low + hi) >> 1;
            +            var c = cacheArray[mid];
            +
            +            if (val > c)
            +                low = mid + 1;
            +            else if (val < c)
            +                hi = mid - 1;
            +            else
            +                return mid;
            +        }
            +
            +        return low -1;
            +    };
            +
            +    this.resetCaches = function() {
            +        this.$modified = true;
            +        this.$wrapData = [];
            +        this.$rowLengthCache = [];
            +        this.$resetRowCache(0);
            +        if (this.bgTokenizer)
            +            this.bgTokenizer.start(0);
            +    };
            +
            +    this.onChangeFold = function(e) {
            +        var fold = e.data;
            +        this.$resetRowCache(fold.start.row);
            +    };
            +
            +    this.onChange = function(e) {
            +        var delta = e.data;
            +        this.$modified = true;
            +
            +        this.$resetRowCache(delta.range.start.row);
            +
            +        var removedFolds = this.$updateInternalDataOnChange(e);
            +        if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
            +            this.$deltasDoc.push(delta);
            +            if (removedFolds && removedFolds.length != 0) {
            +                this.$deltasFold.push({
            +                    action: "removeFolds",
            +                    folds:  removedFolds
            +                });
            +            }
            +
            +            this.$informUndoManager.schedule();
            +        }
            +
            +        this.bgTokenizer.$updateOnChange(delta);
            +        this._signal("change", e);
            +    };
            +    this.setValue = function(text) {
            +        this.doc.setValue(text);
            +        this.selection.moveTo(0, 0);
            +
            +        this.$resetRowCache(0);
            +        this.$deltas = [];
            +        this.$deltasDoc = [];
            +        this.$deltasFold = [];
            +        this.setUndoManager(this.$undoManager);
            +        this.getUndoManager().reset();
            +    };
            +    this.getValue =
            +    this.toString = function() {
            +        return this.doc.getValue();
            +    };
            +    this.getSelection = function() {
            +        return this.selection;
            +    };
            +    this.getState = function(row) {
            +        return this.bgTokenizer.getState(row);
            +    };
            +    this.getTokens = function(row) {
            +        return this.bgTokenizer.getTokens(row);
            +    };
            +    this.getTokenAt = function(row, column) {
            +        var tokens = this.bgTokenizer.getTokens(row);
            +        var token, c = 0;
            +        if (column == null) {
            +            i = tokens.length - 1;
            +            c = this.getLine(row).length;
            +        } else {
            +            for (var i = 0; i < tokens.length; i++) {
            +                c += tokens[i].value.length;
            +                if (c >= column)
            +                    break;
            +            }
            +        }
            +        token = tokens[i];
            +        if (!token)
            +            return null;
            +        token.index = i;
            +        token.start = c - token.value.length;
            +        return token;
            +    };
            +    this.setUndoManager = function(undoManager) {
            +        this.$undoManager = undoManager;
            +        this.$deltas = [];
            +        this.$deltasDoc = [];
            +        this.$deltasFold = [];
            +
            +        if (this.$informUndoManager)
            +            this.$informUndoManager.cancel();
            +
            +        if (undoManager) {
            +            var self = this;
            +
            +            this.$syncInformUndoManager = function() {
            +                self.$informUndoManager.cancel();
            +
            +                if (self.$deltasFold.length) {
            +                    self.$deltas.push({
            +                        group: "fold",
            +                        deltas: self.$deltasFold
            +                    });
            +                    self.$deltasFold = [];
            +                }
            +
            +                if (self.$deltasDoc.length) {
            +                    self.$deltas.push({
            +                        group: "doc",
            +                        deltas: self.$deltasDoc
            +                    });
            +                    self.$deltasDoc = [];
            +                }
            +
            +                if (self.$deltas.length > 0) {
            +                    undoManager.execute({
            +                        action: "aceupdate",
            +                        args: [self.$deltas, self],
            +                        merge: self.mergeUndoDeltas
            +                    });
            +                }
            +                self.mergeUndoDeltas = false;
            +                self.$deltas = [];
            +            };
            +            this.$informUndoManager = lang.delayedCall(this.$syncInformUndoManager);
            +        }
            +    };
            +    this.markUndoGroup = function() {
            +        if (this.$syncInformUndoManager)
            +            this.$syncInformUndoManager();
            +    };
            +    
            +    this.$defaultUndoManager = {
            +        undo: function() {},
            +        redo: function() {},
            +        reset: function() {}
            +    };
            +    this.getUndoManager = function() {
            +        return this.$undoManager || this.$defaultUndoManager;
            +    };
            +    this.getTabString = function() {
            +        if (this.getUseSoftTabs()) {
            +            return lang.stringRepeat(" ", this.getTabSize());
            +        } else {
            +            return "\t";
            +        }
            +    };
            +    this.setUseSoftTabs = function(val) {
            +        this.setOption("useSoftTabs", val);
            +    };
            +    this.getUseSoftTabs = function() {
            +        return this.$useSoftTabs && !this.$mode.$indentWithTabs;
            +    };
            +    this.setTabSize = function(tabSize) {
            +        this.setOption("tabSize", tabSize);
            +    };
            +    this.getTabSize = function() {
            +        return this.$tabSize;
            +    };
            +    this.isTabStop = function(position) {
            +        return this.$useSoftTabs && (position.column % this.$tabSize === 0);
            +    };
            +
            +    this.$overwrite = false;
            +    this.setOverwrite = function(overwrite) {
            +        this.setOption("overwrite", overwrite);
            +    };
            +    this.getOverwrite = function() {
            +        return this.$overwrite;
            +    };
            +    this.toggleOverwrite = function() {
            +        this.setOverwrite(!this.$overwrite);
            +    };
            +    this.addGutterDecoration = function(row, className) {
            +        if (!this.$decorations[row])
            +            this.$decorations[row] = "";
            +        this.$decorations[row] += " " + className;
            +        this._signal("changeBreakpoint", {});
            +    };
            +    this.removeGutterDecoration = function(row, className) {
            +        this.$decorations[row] = (this.$decorations[row] || "").replace(" " + className, "");
            +        this._signal("changeBreakpoint", {});
            +    };
            +    this.getBreakpoints = function() {
            +        return this.$breakpoints;
            +    };
            +    this.setBreakpoints = function(rows) {
            +        this.$breakpoints = [];
            +        for (var i=0; i<rows.length; i++) {
            +            this.$breakpoints[rows[i]] = "ace_breakpoint";
            +        }
            +        this._signal("changeBreakpoint", {});
            +    };
            +    this.clearBreakpoints = function() {
            +        this.$breakpoints = [];
            +        this._signal("changeBreakpoint", {});
            +    };
            +    this.setBreakpoint = function(row, className) {
            +        if (className === undefined)
            +            className = "ace_breakpoint";
            +        if (className)
            +            this.$breakpoints[row] = className;
            +        else
            +            delete this.$breakpoints[row];
            +        this._signal("changeBreakpoint", {});
            +    };
            +    this.clearBreakpoint = function(row) {
            +        delete this.$breakpoints[row];
            +        this._signal("changeBreakpoint", {});
            +    };
            +    this.addMarker = function(range, clazz, type, inFront) {
            +        var id = this.$markerId++;
            +
            +        var marker = {
            +            range : range,
            +            type : type || "line",
            +            renderer: typeof type == "function" ? type : null,
            +            clazz : clazz,
            +            inFront: !!inFront,
            +            id: id
            +        };
            +
            +        if (inFront) {
            +            this.$frontMarkers[id] = marker;
            +            this._signal("changeFrontMarker");
            +        } else {
            +            this.$backMarkers[id] = marker;
            +            this._signal("changeBackMarker");
            +        }
            +
            +        return id;
            +    };
            +    this.addDynamicMarker = function(marker, inFront) {
            +        if (!marker.update)
            +            return;
            +        var id = this.$markerId++;
            +        marker.id = id;
            +        marker.inFront = !!inFront;
            +
            +        if (inFront) {
            +            this.$frontMarkers[id] = marker;
            +            this._signal("changeFrontMarker");
            +        } else {
            +            this.$backMarkers[id] = marker;
            +            this._signal("changeBackMarker");
            +        }
            +
            +        return marker;
            +    };
            +    this.removeMarker = function(markerId) {
            +        var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];
            +        if (!marker)
            +            return;
            +
            +        var markers = marker.inFront ? this.$frontMarkers : this.$backMarkers;
            +        if (marker) {
            +            delete (markers[markerId]);
            +            this._signal(marker.inFront ? "changeFrontMarker" : "changeBackMarker");
            +        }
            +    };
            +    this.getMarkers = function(inFront) {
            +        return inFront ? this.$frontMarkers : this.$backMarkers;
            +    };
            +
            +    this.highlight = function(re) {
            +        if (!this.$searchHighlight) {
            +            var highlight = new SearchHighlight(null, "ace_selected-word", "text");
            +            this.$searchHighlight = this.addDynamicMarker(highlight);
            +        }
            +        this.$searchHighlight.setRegexp(re);
            +    };
            +    this.highlightLines = function(startRow, endRow, clazz, inFront) {
            +        if (typeof endRow != "number") {
            +            clazz = endRow;
            +            endRow = startRow;
            +        }
            +        if (!clazz)
            +            clazz = "ace_step";
            +
            +        var range = new Range(startRow, 0, endRow, Infinity);
            +        range.id = this.addMarker(range, clazz, "fullLine", inFront);
            +        return range;
            +    };
            +    this.setAnnotations = function(annotations) {
            +        this.$annotations = annotations;
            +        this._signal("changeAnnotation", {});
            +    };
            +    this.getAnnotations = function() {
            +        return this.$annotations || [];
            +    };
            +    this.clearAnnotations = function() {
            +        this.setAnnotations([]);
            +    };
            +    this.$detectNewLine = function(text) {
            +        var match = text.match(/^.*?(\r?\n)/m);
            +        if (match) {
            +            this.$autoNewLine = match[1];
            +        } else {
            +            this.$autoNewLine = "\n";
            +        }
            +    };
            +    this.getWordRange = function(row, column) {
            +        var line = this.getLine(row);
            +
            +        var inToken = false;
            +        if (column > 0)
            +            inToken = !!line.charAt(column - 1).match(this.tokenRe);
            +
            +        if (!inToken)
            +            inToken = !!line.charAt(column).match(this.tokenRe);
            +
            +        if (inToken)
            +            var re = this.tokenRe;
            +        else if (/^\s+$/.test(line.slice(column-1, column+1)))
            +            var re = /\s/;
            +        else
            +            var re = this.nonTokenRe;
            +
            +        var start = column;
            +        if (start > 0) {
            +            do {
            +                start--;
            +            }
            +            while (start >= 0 && line.charAt(start).match(re));
            +            start++;
            +        }
            +
            +        var end = column;
            +        while (end < line.length && line.charAt(end).match(re)) {
            +            end++;
            +        }
            +
            +        return new Range(row, start, row, end);
            +    };
            +    this.getAWordRange = function(row, column) {
            +        var wordRange = this.getWordRange(row, column);
            +        var line = this.getLine(wordRange.end.row);
            +
            +        while (line.charAt(wordRange.end.column).match(/[ \t]/)) {
            +            wordRange.end.column += 1;
            +        }
            +        return wordRange;
            +    };
            +    this.setNewLineMode = function(newLineMode) {
            +        this.doc.setNewLineMode(newLineMode);
            +    };
            +    this.getNewLineMode = function() {
            +        return this.doc.getNewLineMode();
            +    };
            +    this.setUseWorker = function(useWorker) { this.setOption("useWorker", useWorker); };
            +    this.getUseWorker = function() { return this.$useWorker; };
            +    this.onReloadTokenizer = function(e) {
            +        var rows = e.data;
            +        this.bgTokenizer.start(rows.first);
            +        this._signal("tokenizerUpdate", e);
            +    };
            +
            +    this.$modes = {};
            +    this.$mode = null;
            +    this.$modeId = null;
            +    this.setMode = function(mode, cb) {
            +        if (mode && typeof mode === "object") {
            +            if (mode.getTokenizer)
            +                return this.$onChangeMode(mode);
            +            var options = mode;
            +            var path = options.path;
            +        } else {
            +            path = mode || "ace/mode/text";
            +        }
            +        if (!this.$modes["ace/mode/text"])
            +            this.$modes["ace/mode/text"] = new TextMode();
            +
            +        if (this.$modes[path] && !options) {
            +            this.$onChangeMode(this.$modes[path]);
            +            cb && cb();
            +            return;
            +        }
            +        this.$modeId = path;
            +        config.loadModule(["mode", path], function(m) {
            +            if (this.$modeId !== path)
            +                return cb && cb();
            +            if (this.$modes[path] && !options)
            +                return this.$onChangeMode(this.$modes[path]);
            +            if (m && m.Mode) {
            +                m = new m.Mode(options);
            +                if (!options) {
            +                    this.$modes[path] = m;
            +                    m.$id = path;
            +                }
            +                this.$onChangeMode(m);
            +                cb && cb();
            +            }
            +        }.bind(this));
            +        if (!this.$mode)
            +            this.$onChangeMode(this.$modes["ace/mode/text"], true);
            +    };
            +
            +    this.$onChangeMode = function(mode, $isPlaceholder) {
            +        if (!$isPlaceholder)
            +            this.$modeId = mode.$id;
            +        if (this.$mode === mode) 
            +            return;
            +
            +        this.$mode = mode;
            +
            +        this.$stopWorker();
            +
            +        if (this.$useWorker)
            +            this.$startWorker();
            +
            +        var tokenizer = mode.getTokenizer();
            +
            +        if(tokenizer.addEventListener !== undefined) {
            +            var onReloadTokenizer = this.onReloadTokenizer.bind(this);
            +            tokenizer.addEventListener("update", onReloadTokenizer);
            +        }
            +
            +        if (!this.bgTokenizer) {
            +            this.bgTokenizer = new BackgroundTokenizer(tokenizer);
            +            var _self = this;
            +            this.bgTokenizer.addEventListener("update", function(e) {
            +                _self._signal("tokenizerUpdate", e);
            +            });
            +        } else {
            +            this.bgTokenizer.setTokenizer(tokenizer);
            +        }
            +
            +        this.bgTokenizer.setDocument(this.getDocument());
            +
            +        this.tokenRe = mode.tokenRe;
            +        this.nonTokenRe = mode.nonTokenRe;
            +
            +        
            +        if (!$isPlaceholder) {
            +            this.$options.wrapMethod.set.call(this, this.$wrapMethod);
            +            this.$setFolding(mode.foldingRules);
            +            this.bgTokenizer.start(0);
            +            this._emit("changeMode");
            +        }
            +    };
            +
            +
            +    this.$stopWorker = function() {
            +        if (this.$worker)
            +            this.$worker.terminate();
            +
            +        this.$worker = null;
            +    };
            +
            +    this.$startWorker = function() {
            +        if (typeof Worker !== "undefined" && !require.noWorker) {
            +            try {
            +                this.$worker = this.$mode.createWorker(this);
            +            } catch (e) {
            +                console.log("Could not load worker");
            +                console.log(e);
            +                this.$worker = null;
            +            }
            +        }
            +        else
            +            this.$worker = null;
            +    };
            +    this.getMode = function() {
            +        return this.$mode;
            +    };
            +
            +    this.$scrollTop = 0;
            +    this.setScrollTop = function(scrollTop) {
            +        if (this.$scrollTop === scrollTop || isNaN(scrollTop))
            +            return;
            +
            +        this.$scrollTop = scrollTop;
            +        this._signal("changeScrollTop", scrollTop);
            +    };
            +    this.getScrollTop = function() {
            +        return this.$scrollTop;
            +    };
            +
            +    this.$scrollLeft = 0;
            +    this.setScrollLeft = function(scrollLeft) {
            +        if (this.$scrollLeft === scrollLeft || isNaN(scrollLeft))
            +            return;
            +
            +        this.$scrollLeft = scrollLeft;
            +        this._signal("changeScrollLeft", scrollLeft);
            +    };
            +    this.getScrollLeft = function() {
            +        return this.$scrollLeft;
            +    };
            +    this.getScreenWidth = function() {
            +        this.$computeWidth();
            +        if (this.lineWidgets) 
            +            return Math.max(this.getLineWidgetMaxWidth(), this.screenWidth);
            +        return this.screenWidth;
            +    };
            +    
            +    this.getLineWidgetMaxWidth = function() {
            +        if (this.lineWidgetsWidth != null) return this.lineWidgetsWidth;
            +        var width = 0;
            +        this.lineWidgets.forEach(function(w) {
            +            if (w && w.screenWidth > width)
            +                width = w.screenWidth;
            +        });
            +        return this.lineWidgetWidth = width;
            +    };
            +
            +    this.$computeWidth = function(force) {
            +        if (this.$modified || force) {
            +            this.$modified = false;
            +
            +            if (this.$useWrapMode)
            +                return this.screenWidth = this.$wrapLimit;
            +
            +            var lines = this.doc.getAllLines();
            +            var cache = this.$rowLengthCache;
            +            var longestScreenLine = 0;
            +            var foldIndex = 0;
            +            var foldLine = this.$foldData[foldIndex];
            +            var foldStart = foldLine ? foldLine.start.row : Infinity;
            +            var len = lines.length;
            +
            +            for (var i = 0; i < len; i++) {
            +                if (i > foldStart) {
            +                    i = foldLine.end.row + 1;
            +                    if (i >= len)
            +                        break;
            +                    foldLine = this.$foldData[foldIndex++];
            +                    foldStart = foldLine ? foldLine.start.row : Infinity;
            +                }
            +
            +                if (cache[i] == null)
            +                    cache[i] = this.$getStringScreenWidth(lines[i])[0];
            +
            +                if (cache[i] > longestScreenLine)
            +                    longestScreenLine = cache[i];
            +            }
            +            this.screenWidth = longestScreenLine;
            +        }
            +    };
            +    this.getLine = function(row) {
            +        return this.doc.getLine(row);
            +    };
            +    this.getLines = function(firstRow, lastRow) {
            +        return this.doc.getLines(firstRow, lastRow);
            +    };
            +    this.getLength = function() {
            +        return this.doc.getLength();
            +    };
            +    this.getTextRange = function(range) {
            +        return this.doc.getTextRange(range || this.selection.getRange());
            +    };
            +    this.insert = function(position, text) {
            +        return this.doc.insert(position, text);
            +    };
            +    this.remove = function(range) {
            +        return this.doc.remove(range);
            +    };
            +    this.undoChanges = function(deltas, dontSelect) {
            +        if (!deltas.length)
            +            return;
            +
            +        this.$fromUndo = true;
            +        var lastUndoRange = null;
            +        for (var i = deltas.length - 1; i != -1; i--) {
            +            var delta = deltas[i];
            +            if (delta.group == "doc") {
            +                this.doc.revertDeltas(delta.deltas);
            +                lastUndoRange =
            +                    this.$getUndoSelection(delta.deltas, true, lastUndoRange);
            +            } else {
            +                delta.deltas.forEach(function(foldDelta) {
            +                    this.addFolds(foldDelta.folds);
            +                }, this);
            +            }
            +        }
            +        this.$fromUndo = false;
            +        lastUndoRange &&
            +            this.$undoSelect &&
            +            !dontSelect &&
            +            this.selection.setSelectionRange(lastUndoRange);
            +        return lastUndoRange;
            +    };
            +    this.redoChanges = function(deltas, dontSelect) {
            +        if (!deltas.length)
            +            return;
            +
            +        this.$fromUndo = true;
            +        var lastUndoRange = null;
            +        for (var i = 0; i < deltas.length; i++) {
            +            var delta = deltas[i];
            +            if (delta.group == "doc") {
            +                this.doc.applyDeltas(delta.deltas);
            +                lastUndoRange =
            +                    this.$getUndoSelection(delta.deltas, false, lastUndoRange);
            +            }
            +        }
            +        this.$fromUndo = false;
            +        lastUndoRange &&
            +            this.$undoSelect &&
            +            !dontSelect &&
            +            this.selection.setSelectionRange(lastUndoRange);
            +        return lastUndoRange;
            +    };
            +    this.setUndoSelect = function(enable) {
            +        this.$undoSelect = enable;
            +    };
            +
            +    this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
            +        function isInsert(delta) {
            +            var insert =
            +                delta.action === "insertText" || delta.action === "insertLines";
            +            return isUndo ? !insert : insert;
            +        }
            +
            +        var delta = deltas[0];
            +        var range, point;
            +        var lastDeltaIsInsert = false;
            +        if (isInsert(delta)) {
            +            range = Range.fromPoints(delta.range.start, delta.range.end);
            +            lastDeltaIsInsert = true;
            +        } else {
            +            range = Range.fromPoints(delta.range.start, delta.range.start);
            +            lastDeltaIsInsert = false;
            +        }
            +
            +        for (var i = 1; i < deltas.length; i++) {
            +            delta = deltas[i];
            +            if (isInsert(delta)) {
            +                point = delta.range.start;
            +                if (range.compare(point.row, point.column) == -1) {
            +                    range.setStart(delta.range.start);
            +                }
            +                point = delta.range.end;
            +                if (range.compare(point.row, point.column) == 1) {
            +                    range.setEnd(delta.range.end);
            +                }
            +                lastDeltaIsInsert = true;
            +            } else {
            +                point = delta.range.start;
            +                if (range.compare(point.row, point.column) == -1) {
            +                    range =
            +                        Range.fromPoints(delta.range.start, delta.range.start);
            +                }
            +                lastDeltaIsInsert = false;
            +            }
            +        }
            +        if (lastUndoRange != null) {
            +            if (Range.comparePoints(lastUndoRange.start, range.start) === 0) {
            +                lastUndoRange.start.column += range.end.column - range.start.column;
            +                lastUndoRange.end.column += range.end.column - range.start.column;
            +            }
            +
            +            var cmp = lastUndoRange.compareRange(range);
            +            if (cmp == 1) {
            +                range.setStart(lastUndoRange.start);
            +            } else if (cmp == -1) {
            +                range.setEnd(lastUndoRange.end);
            +            }
            +        }
            +
            +        return range;
            +    };
            +    this.replace = function(range, text) {
            +        return this.doc.replace(range, text);
            +    };
            +    this.moveText = function(fromRange, toPosition, copy) {
            +        var text = this.getTextRange(fromRange);
            +        var folds = this.getFoldsInRange(fromRange);
            +
            +        var toRange = Range.fromPoints(toPosition, toPosition);
            +        if (!copy) {
            +            this.remove(fromRange);
            +            var rowDiff = fromRange.start.row - fromRange.end.row;
            +            var collDiff = rowDiff ? -fromRange.end.column : fromRange.start.column - fromRange.end.column;
            +            if (collDiff) {
            +                if (toRange.start.row == fromRange.end.row && toRange.start.column > fromRange.end.column)
            +                    toRange.start.column += collDiff;
            +                if (toRange.end.row == fromRange.end.row && toRange.end.column > fromRange.end.column)
            +                    toRange.end.column += collDiff;
            +            }
            +            if (rowDiff && toRange.start.row >= fromRange.end.row) {
            +                toRange.start.row += rowDiff;
            +                toRange.end.row += rowDiff;
            +            }
            +        }
            +
            +        toRange.end = this.insert(toRange.start, text);
            +        if (folds.length) {
            +            var oldStart = fromRange.start;
            +            var newStart = toRange.start;
            +            var rowDiff = newStart.row - oldStart.row;
            +            var collDiff = newStart.column - oldStart.column;
            +            this.addFolds(folds.map(function(x) {
            +                x = x.clone();
            +                if (x.start.row == oldStart.row)
            +                    x.start.column += collDiff;
            +                if (x.end.row == oldStart.row)
            +                    x.end.column += collDiff;
            +                x.start.row += rowDiff;
            +                x.end.row += rowDiff;
            +                return x;
            +            }));
            +        }
            +
            +        return toRange;
            +    };
            +    this.indentRows = function(startRow, endRow, indentString) {
            +        indentString = indentString.replace(/\t/g, this.getTabString());
            +        for (var row=startRow; row<=endRow; row++)
            +            this.insert({row: row, column:0}, indentString);
            +    };
            +    this.outdentRows = function (range) {
            +        var rowRange = range.collapseRows();
            +        var deleteRange = new Range(0, 0, 0, 0);
            +        var size = this.getTabSize();
            +
            +        for (var i = rowRange.start.row; i <= rowRange.end.row; ++i) {
            +            var line = this.getLine(i);
            +
            +            deleteRange.start.row = i;
            +            deleteRange.end.row = i;
            +            for (var j = 0; j < size; ++j)
            +                if (line.charAt(j) != ' ')
            +                    break;
            +            if (j < size && line.charAt(j) == '\t') {
            +                deleteRange.start.column = j;
            +                deleteRange.end.column = j + 1;
            +            } else {
            +                deleteRange.start.column = 0;
            +                deleteRange.end.column = j;
            +            }
            +            this.remove(deleteRange);
            +        }
            +    };
            +
            +    this.$moveLines = function(firstRow, lastRow, dir) {
            +        firstRow = this.getRowFoldStart(firstRow);
            +        lastRow = this.getRowFoldEnd(lastRow);
            +        if (dir < 0) {
            +            var row = this.getRowFoldStart(firstRow + dir);
            +            if (row < 0) return 0;
            +            var diff = row-firstRow;
            +        } else if (dir > 0) {
            +            var row = this.getRowFoldEnd(lastRow + dir);
            +            if (row > this.doc.getLength()-1) return 0;
            +            var diff = row-lastRow;
            +        } else {
            +            firstRow = this.$clipRowToDocument(firstRow);
            +            lastRow = this.$clipRowToDocument(lastRow);
            +            var diff = lastRow - firstRow + 1;
            +        }
            +
            +        var range = new Range(firstRow, 0, lastRow, Number.MAX_VALUE);
            +        var folds = this.getFoldsInRange(range).map(function(x){
            +            x = x.clone();
            +            x.start.row += diff;
            +            x.end.row += diff;
            +            return x;
            +        });
            +
            +        var lines = dir == 0
            +            ? this.doc.getLines(firstRow, lastRow)
            +            : this.doc.removeLines(firstRow, lastRow);
            +        this.doc.insertLines(firstRow+diff, lines);
            +        folds.length && this.addFolds(folds);
            +        return diff;
            +    };
            +    this.moveLinesUp = function(firstRow, lastRow) {
            +        return this.$moveLines(firstRow, lastRow, -1);
            +    };
            +    this.moveLinesDown = function(firstRow, lastRow) {
            +        return this.$moveLines(firstRow, lastRow, 1);
            +    };
            +    this.duplicateLines = function(firstRow, lastRow) {
            +        return this.$moveLines(firstRow, lastRow, 0);
            +    };
            +
            +
            +    this.$clipRowToDocument = function(row) {
            +        return Math.max(0, Math.min(row, this.doc.getLength()-1));
            +    };
            +
            +    this.$clipColumnToRow = function(row, column) {
            +        if (column < 0)
            +            return 0;
            +        return Math.min(this.doc.getLine(row).length, column);
            +    };
            +
            +
            +    this.$clipPositionToDocument = function(row, column) {
            +        column = Math.max(0, column);
            +
            +        if (row < 0) {
            +            row = 0;
            +            column = 0;
            +        } else {
            +            var len = this.doc.getLength();
            +            if (row >= len) {
            +                row = len - 1;
            +                column = this.doc.getLine(len-1).length;
            +            } else {
            +                column = Math.min(this.doc.getLine(row).length, column);
            +            }
            +        }
            +
            +        return {
            +            row: row,
            +            column: column
            +        };
            +    };
            +
            +    this.$clipRangeToDocument = function(range) {
            +        if (range.start.row < 0) {
            +            range.start.row = 0;
            +            range.start.column = 0;
            +        } else {
            +            range.start.column = this.$clipColumnToRow(
            +                range.start.row,
            +                range.start.column
            +            );
            +        }
            +
            +        var len = this.doc.getLength() - 1;
            +        if (range.end.row > len) {
            +            range.end.row = len;
            +            range.end.column = this.doc.getLine(len).length;
            +        } else {
            +            range.end.column = this.$clipColumnToRow(
            +                range.end.row,
            +                range.end.column
            +            );
            +        }
            +        return range;
            +    };
            +    this.$wrapLimit = 80;
            +    this.$useWrapMode = false;
            +    this.$wrapLimitRange = {
            +        min : null,
            +        max : null
            +    };
            +    this.setUseWrapMode = function(useWrapMode) {
            +        if (useWrapMode != this.$useWrapMode) {
            +            this.$useWrapMode = useWrapMode;
            +            this.$modified = true;
            +            this.$resetRowCache(0);
            +            if (useWrapMode) {
            +                var len = this.getLength();
            +                this.$wrapData = Array(len);
            +                this.$updateWrapData(0, len - 1);
            +            }
            +
            +            this._signal("changeWrapMode");
            +        }
            +    };
            +    this.getUseWrapMode = function() {
            +        return this.$useWrapMode;
            +    };
            +    this.setWrapLimitRange = function(min, max) {
            +        if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {
            +            this.$wrapLimitRange = {
            +                min: min,
            +                max: max
            +            };
            +            this.$modified = true;
            +            this._signal("changeWrapMode");
            +        }
            +    };
            +    this.adjustWrapLimit = function(desiredLimit, $printMargin) {
            +        var limits = this.$wrapLimitRange
            +        if (limits.max < 0)
            +            limits = {min: $printMargin, max: $printMargin};
            +        var wrapLimit = this.$constrainWrapLimit(desiredLimit, limits.min, limits.max);
            +        if (wrapLimit != this.$wrapLimit && wrapLimit > 1) {
            +            this.$wrapLimit = wrapLimit;
            +            this.$modified = true;
            +            if (this.$useWrapMode) {
            +                this.$updateWrapData(0, this.getLength() - 1);
            +                this.$resetRowCache(0);
            +                this._signal("changeWrapLimit");
            +            }
            +            return true;
            +        }
            +        return false;
            +    };
            +
            +    this.$constrainWrapLimit = function(wrapLimit, min, max) {
            +        if (min)
            +            wrapLimit = Math.max(min, wrapLimit);
            +
            +        if (max)
            +            wrapLimit = Math.min(max, wrapLimit);
            +
            +        return wrapLimit;
            +    };
            +    this.getWrapLimit = function() {
            +        return this.$wrapLimit;
            +    };
            +    this.setWrapLimit = function (limit) {
            +        this.setWrapLimitRange(limit, limit);
            +    };
            +    this.getWrapLimitRange = function() {
            +        return {
            +            min : this.$wrapLimitRange.min,
            +            max : this.$wrapLimitRange.max
            +        };
            +    };
            +
            +    this.$updateInternalDataOnChange = function(e) {
            +        var useWrapMode = this.$useWrapMode;
            +        var len;
            +        var action = e.data.action;
            +        var firstRow = e.data.range.start.row;
            +        var lastRow = e.data.range.end.row;
            +        var start = e.data.range.start;
            +        var end = e.data.range.end;
            +        var removedFolds = null;
            +
            +        if (action.indexOf("Lines") != -1) {
            +            if (action == "insertLines") {
            +                lastRow = firstRow + (e.data.lines.length);
            +            } else {
            +                lastRow = firstRow;
            +            }
            +            len = e.data.lines ? e.data.lines.length : lastRow - firstRow;
            +        } else {
            +            len = lastRow - firstRow;
            +        }
            +
            +        this.$updating = true;
            +        if (len != 0) {
            +            if (action.indexOf("remove") != -1) {
            +                this[useWrapMode ? "$wrapData" : "$rowLengthCache"].splice(firstRow, len);
            +
            +                var foldLines = this.$foldData;
            +                removedFolds = this.getFoldsInRange(e.data.range);
            +                this.removeFolds(removedFolds);
            +
            +                var foldLine = this.getFoldLine(end.row);
            +                var idx = 0;
            +                if (foldLine) {
            +                    foldLine.addRemoveChars(end.row, end.column, start.column - end.column);
            +                    foldLine.shiftRow(-len);
            +
            +                    var foldLineBefore = this.getFoldLine(firstRow);
            +                    if (foldLineBefore && foldLineBefore !== foldLine) {
            +                        foldLineBefore.merge(foldLine);
            +                        foldLine = foldLineBefore;
            +                    }
            +                    idx = foldLines.indexOf(foldLine) + 1;
            +                }
            +
            +                for (idx; idx < foldLines.length; idx++) {
            +                    var foldLine = foldLines[idx];
            +                    if (foldLine.start.row >= end.row) {
            +                        foldLine.shiftRow(-len);
            +                    }
            +                }
            +
            +                lastRow = firstRow;
            +            } else {
            +                var args = Array(len);
            +                args.unshift(firstRow, 0);
            +                var arr = useWrapMode ? this.$wrapData : this.$rowLengthCache
            +                arr.splice.apply(arr, args);
            +                var foldLines = this.$foldData;
            +                var foldLine = this.getFoldLine(firstRow);
            +                var idx = 0;
            +                if (foldLine) {
            +                    var cmp = foldLine.range.compareInside(start.row, start.column)
            +                    if (cmp == 0) {
            +                        foldLine = foldLine.split(start.row, start.column);
            +                        foldLine.shiftRow(len);
            +                        foldLine.addRemoveChars(
            +                            lastRow, 0, end.column - start.column);
            +                    } else
            +                    if (cmp == -1) {
            +                        foldLine.addRemoveChars(firstRow, 0, end.column - start.column);
            +                        foldLine.shiftRow(len);
            +                    }
            +                    idx = foldLines.indexOf(foldLine) + 1;
            +                }
            +
            +                for (idx; idx < foldLines.length; idx++) {
            +                    var foldLine = foldLines[idx];
            +                    if (foldLine.start.row >= firstRow) {
            +                        foldLine.shiftRow(len);
            +                    }
            +                }
            +            }
            +        } else {
            +            len = Math.abs(e.data.range.start.column - e.data.range.end.column);
            +            if (action.indexOf("remove") != -1) {
            +                removedFolds = this.getFoldsInRange(e.data.range);
            +                this.removeFolds(removedFolds);
            +
            +                len = -len;
            +            }
            +            var foldLine = this.getFoldLine(firstRow);
            +            if (foldLine) {
            +                foldLine.addRemoveChars(firstRow, start.column, len);
            +            }
            +        }
            +
            +        if (useWrapMode && this.$wrapData.length != this.doc.getLength()) {
            +            console.error("doc.getLength() and $wrapData.length have to be the same!");
            +        }
            +        this.$updating = false;
            +
            +        if (useWrapMode)
            +            this.$updateWrapData(firstRow, lastRow);
            +        else
            +            this.$updateRowLengthCache(firstRow, lastRow);
            +
            +        return removedFolds;
            +    };
            +
            +    this.$updateRowLengthCache = function(firstRow, lastRow, b) {
            +        this.$rowLengthCache[firstRow] = null;
            +        this.$rowLengthCache[lastRow] = null;
            +    };
            +
            +    this.$updateWrapData = function(firstRow, lastRow) {
            +        var lines = this.doc.getAllLines();
            +        var tabSize = this.getTabSize();
            +        var wrapData = this.$wrapData;
            +        var wrapLimit = this.$wrapLimit;
            +        var tokens;
            +        var foldLine;
            +
            +        var row = firstRow;
            +        lastRow = Math.min(lastRow, lines.length - 1);
            +        while (row <= lastRow) {
            +            foldLine = this.getFoldLine(row, foldLine);
            +            if (!foldLine) {
            +                tokens = this.$getDisplayTokens(lines[row]);
            +                wrapData[row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
            +                row ++;
            +            } else {
            +                tokens = [];
            +                foldLine.walk(function(placeholder, row, column, lastColumn) {
            +                        var walkTokens;
            +                        if (placeholder != null) {
            +                            walkTokens = this.$getDisplayTokens(
            +                                            placeholder, tokens.length);
            +                            walkTokens[0] = PLACEHOLDER_START;
            +                            for (var i = 1; i < walkTokens.length; i++) {
            +                                walkTokens[i] = PLACEHOLDER_BODY;
            +                            }
            +                        } else {
            +                            walkTokens = this.$getDisplayTokens(
            +                                lines[row].substring(lastColumn, column),
            +                                tokens.length);
            +                        }
            +                        tokens = tokens.concat(walkTokens);
            +                    }.bind(this),
            +                    foldLine.end.row,
            +                    lines[foldLine.end.row].length + 1
            +                );
            +
            +                wrapData[foldLine.start.row] = this.$computeWrapSplits(tokens, wrapLimit, tabSize);
            +                row = foldLine.end.row + 1;
            +            }
            +        }
            +    };
            +    var CHAR = 1,
            +        CHAR_EXT = 2,
            +        PLACEHOLDER_START = 3,
            +        PLACEHOLDER_BODY =  4,
            +        PUNCTUATION = 9,
            +        SPACE = 10,
            +        TAB = 11,
            +        TAB_SPACE = 12;
            +
            +
            +    this.$computeWrapSplits = function(tokens, wrapLimit) {
            +        if (tokens.length == 0) {
            +            return [];
            +        }
            +
            +        var splits = [];
            +        var displayLength = tokens.length;
            +        var lastSplit = 0, lastDocSplit = 0;
            +
            +        var isCode = this.$wrapAsCode;
            +
            +        function addSplit(screenPos) {
            +            var displayed = tokens.slice(lastSplit, screenPos);
            +            var len = displayed.length;
            +            displayed.join("").
            +                replace(/12/g, function() {
            +                    len -= 1;
            +                }).
            +                replace(/2/g, function() {
            +                    len -= 1;
            +                });
            +
            +            lastDocSplit += len;
            +            splits.push(lastDocSplit);
            +            lastSplit = screenPos;
            +        }
            +
            +        while (displayLength - lastSplit > wrapLimit) {
            +            var split = lastSplit + wrapLimit;
            +            if (tokens[split - 1] >= SPACE && tokens[split] >= SPACE) {
            +                addSplit(split);
            +                continue;
            +            }
            +            if (tokens[split] == PLACEHOLDER_START || tokens[split] == PLACEHOLDER_BODY) {
            +                for (split; split != lastSplit - 1; split--) {
            +                    if (tokens[split] == PLACEHOLDER_START) {
            +                        break;
            +                    }
            +                }
            +                if (split > lastSplit) {
            +                    addSplit(split);
            +                    continue;
            +                }
            +                split = lastSplit + wrapLimit;
            +                for (split; split < tokens.length; split++) {
            +                    if (tokens[split] != PLACEHOLDER_BODY) {
            +                        break;
            +                    }
            +                }
            +                if (split == tokens.length) {
            +                    break;  // Breaks the while-loop.
            +                }
            +                addSplit(split);
            +                continue;
            +            }
            +            var minSplit = Math.max(split - (isCode ? 10 : wrapLimit-(wrapLimit>>2)), lastSplit - 1);
            +            while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
            +                split --;
            +            }
            +            if (isCode) {
            +                while (split > minSplit && tokens[split] < PLACEHOLDER_START) {
            +                    split --;
            +                }
            +                while (split > minSplit && tokens[split] == PUNCTUATION) {
            +                    split --;
            +                }
            +            } else {
            +                while (split > minSplit && tokens[split] < SPACE) {
            +                    split --;
            +                }
            +            }
            +            if (split > minSplit) {
            +                addSplit(++split);
            +                continue;
            +            }
            +            split = lastSplit + wrapLimit;
            +            addSplit(split);
            +        }
            +        return splits;
            +    };
            +    this.$getDisplayTokens = function(str, offset) {
            +        var arr = [];
            +        var tabSize;
            +        offset = offset || 0;
            +
            +        for (var i = 0; i < str.length; i++) {
            +            var c = str.charCodeAt(i);
            +            if (c == 9) {
            +                tabSize = this.getScreenTabSize(arr.length + offset);
            +                arr.push(TAB);
            +                for (var n = 1; n < tabSize; n++) {
            +                    arr.push(TAB_SPACE);
            +                }
            +            }
            +            else if (c == 32) {
            +                arr.push(SPACE);
            +            } else if((c > 39 && c < 48) || (c > 57 && c < 64)) {
            +                arr.push(PUNCTUATION);
            +            }
            +            else if (c >= 0x1100 && isFullWidth(c)) {
            +                arr.push(CHAR, CHAR_EXT);
            +            } else {
            +                arr.push(CHAR);
            +            }
            +        }
            +        return arr;
            +    };
            +    this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
            +        if (maxScreenColumn == 0)
            +            return [0, 0];
            +        if (maxScreenColumn == null)
            +            maxScreenColumn = Infinity;
            +        screenColumn = screenColumn || 0;
            +
            +        var c, column;
            +        for (column = 0; column < str.length; column++) {
            +            c = str.charCodeAt(column);
            +            if (c == 9) {
            +                screenColumn += this.getScreenTabSize(screenColumn);
            +            }
            +            else if (c >= 0x1100 && isFullWidth(c)) {
            +                screenColumn += 2;
            +            } else {
            +                screenColumn += 1;
            +            }
            +            if (screenColumn > maxScreenColumn) {
            +                break;
            +            }
            +        }
            +
            +        return [screenColumn, column];
            +    };
            +
            +    this.lineWidgets = null;
            +    this.getRowLength = function(row) {
            +        if (this.lineWidgets)
            +            var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
            +        else 
            +            h = 0
            +        if (!this.$useWrapMode || !this.$wrapData[row]) {
            +            return 1 + h;
            +        } else {
            +            return this.$wrapData[row].length + 1 + h;
            +        }
            +    };
            +    this.getRowLineCount = function(row) {
            +        if (!this.$useWrapMode || !this.$wrapData[row]) {
            +            return 1;
            +        } else {
            +            return this.$wrapData[row].length + 1;
            +        }
            +    };
            +    this.getScreenLastRowColumn = function(screenRow) {
            +        var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE);
            +        return this.documentToScreenColumn(pos.row, pos.column);
            +    };
            +    this.getDocumentLastRowColumn = function(docRow, docColumn) {
            +        var screenRow = this.documentToScreenRow(docRow, docColumn);
            +        return this.getScreenLastRowColumn(screenRow);
            +    };
            +    this.getDocumentLastRowColumnPosition = function(docRow, docColumn) {
            +        var screenRow = this.documentToScreenRow(docRow, docColumn);
            +        return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);
            +    };
            +    this.getRowSplitData = function(row) {
            +        if (!this.$useWrapMode) {
            +            return undefined;
            +        } else {
            +            return this.$wrapData[row];
            +        }
            +    };
            +    this.getScreenTabSize = function(screenColumn) {
            +        return this.$tabSize - screenColumn % this.$tabSize;
            +    };
            +
            +
            +    this.screenToDocumentRow = function(screenRow, screenColumn) {
            +        return this.screenToDocumentPosition(screenRow, screenColumn).row;
            +    };
            +
            +
            +    this.screenToDocumentColumn = function(screenRow, screenColumn) {
            +        return this.screenToDocumentPosition(screenRow, screenColumn).column;
            +    };
            +    this.screenToDocumentPosition = function(screenRow, screenColumn) {
            +        if (screenRow < 0)
            +            return {row: 0, column: 0};
            +
            +        var line;
            +        var docRow = 0;
            +        var docColumn = 0;
            +        var column;
            +        var row = 0;
            +        var rowLength = 0;
            +
            +        var rowCache = this.$screenRowCache;
            +        var i = this.$getRowCacheIndex(rowCache, screenRow);
            +        var l = rowCache.length;
            +        if (l && i >= 0) {
            +            var row = rowCache[i];
            +            var docRow = this.$docRowCache[i];
            +            var doCache = screenRow > rowCache[l - 1];
            +        } else {
            +            var doCache = !l;
            +        }
            +
            +        var maxRow = this.getLength() - 1;
            +        var foldLine = this.getNextFoldLine(docRow);
            +        var foldStart = foldLine ? foldLine.start.row : Infinity;
            +
            +        while (row <= screenRow) {
            +            rowLength = this.getRowLength(docRow);
            +            if (row + rowLength > screenRow || docRow >= maxRow) {
            +                break;
            +            } else {
            +                row += rowLength;
            +                docRow++;
            +                if (docRow > foldStart) {
            +                    docRow = foldLine.end.row+1;
            +                    foldLine = this.getNextFoldLine(docRow, foldLine);
            +                    foldStart = foldLine ? foldLine.start.row : Infinity;
            +                }
            +            }
            +
            +            if (doCache) {
            +                this.$docRowCache.push(docRow);
            +                this.$screenRowCache.push(row);
            +            }
            +        }
            +
            +        if (foldLine && foldLine.start.row <= docRow) {
            +            line = this.getFoldDisplayLine(foldLine);
            +            docRow = foldLine.start.row;
            +        } else if (row + rowLength <= screenRow || docRow > maxRow) {
            +            return {
            +                row: maxRow,
            +                column: this.getLine(maxRow).length
            +            }
            +        } else {
            +            line = this.getLine(docRow);
            +            foldLine = null;
            +        }
            +
            +        if (this.$useWrapMode) {
            +            var splits = this.$wrapData[docRow];
            +            if (splits) {
            +                var splitIndex = Math.floor(screenRow - row);
            +                column = splits[splitIndex];
            +                if(splitIndex > 0 && splits.length) {
            +                    docColumn = splits[splitIndex - 1] || splits[splits.length - 1];
            +                    line = line.substring(docColumn);
            +                }
            +            }
            +        }
            +
            +        docColumn += this.$getStringScreenWidth(line, screenColumn)[1];
            +        if (this.$useWrapMode && docColumn >= column)
            +            docColumn = column - 1;
            +
            +        if (foldLine)
            +            return foldLine.idxToPosition(docColumn);
            +
            +        return {row: docRow, column: docColumn};
            +    };
            +    this.documentToScreenPosition = function(docRow, docColumn) {
            +        if (typeof docColumn === "undefined")
            +            var pos = this.$clipPositionToDocument(docRow.row, docRow.column);
            +        else
            +            pos = this.$clipPositionToDocument(docRow, docColumn);
            +
            +        docRow = pos.row;
            +        docColumn = pos.column;
            +
            +        var screenRow = 0;
            +        var foldStartRow = null;
            +        var fold = null;
            +        fold = this.getFoldAt(docRow, docColumn, 1);
            +        if (fold) {
            +            docRow = fold.start.row;
            +            docColumn = fold.start.column;
            +        }
            +
            +        var rowEnd, row = 0;
            +
            +
            +        var rowCache = this.$docRowCache;
            +        var i = this.$getRowCacheIndex(rowCache, docRow);
            +        var l = rowCache.length;
            +        if (l && i >= 0) {
            +            var row = rowCache[i];
            +            var screenRow = this.$screenRowCache[i];
            +            var doCache = docRow > rowCache[l - 1];
            +        } else {
            +            var doCache = !l;
            +        }
            +
            +        var foldLine = this.getNextFoldLine(row);
            +        var foldStart = foldLine ?foldLine.start.row :Infinity;
            +
            +        while (row < docRow) {
            +            if (row >= foldStart) {
            +                rowEnd = foldLine.end.row + 1;
            +                if (rowEnd > docRow)
            +                    break;
            +                foldLine = this.getNextFoldLine(rowEnd, foldLine);
            +                foldStart = foldLine ?foldLine.start.row :Infinity;
            +            }
            +            else {
            +                rowEnd = row + 1;
            +            }
            +
            +            screenRow += this.getRowLength(row);
            +            row = rowEnd;
            +
            +            if (doCache) {
            +                this.$docRowCache.push(row);
            +                this.$screenRowCache.push(screenRow);
            +            }
            +        }
            +        var textLine = "";
            +        if (foldLine && row >= foldStart) {
            +            textLine = this.getFoldDisplayLine(foldLine, docRow, docColumn);
            +            foldStartRow = foldLine.start.row;
            +        } else {
            +            textLine = this.getLine(docRow).substring(0, docColumn);
            +            foldStartRow = docRow;
            +        }
            +        if (this.$useWrapMode) {
            +            var wrapRow = this.$wrapData[foldStartRow];
            +            if (wrapRow) {
            +                var screenRowOffset = 0;
            +                while (textLine.length >= wrapRow[screenRowOffset]) {
            +                    screenRow ++;
            +                    screenRowOffset++;
            +                }
            +                textLine = textLine.substring(
            +                    wrapRow[screenRowOffset - 1] || 0, textLine.length
            +                );
            +            }
            +        }
            +
            +        return {
            +            row: screenRow,
            +            column: this.$getStringScreenWidth(textLine)[0]
            +        };
            +    };
            +    this.documentToScreenColumn = function(row, docColumn) {
            +        return this.documentToScreenPosition(row, docColumn).column;
            +    };
            +    this.documentToScreenRow = function(docRow, docColumn) {
            +        return this.documentToScreenPosition(docRow, docColumn).row;
            +    };
            +    this.getScreenLength = function() {
            +        var screenRows = 0;
            +        var fold = null;
            +        if (!this.$useWrapMode) {
            +            screenRows = this.getLength();
            +            var foldData = this.$foldData;
            +            for (var i = 0; i < foldData.length; i++) {
            +                fold = foldData[i];
            +                screenRows -= fold.end.row - fold.start.row;
            +            }
            +        } else {
            +            var lastRow = this.$wrapData.length;
            +            var row = 0, i = 0;
            +            var fold = this.$foldData[i++];
            +            var foldStart = fold ? fold.start.row :Infinity;
            +
            +            while (row < lastRow) {
            +                var splits = this.$wrapData[row];
            +                screenRows += splits ? splits.length + 1 : 1;
            +                row ++;
            +                if (row > foldStart) {
            +                    row = fold.end.row+1;
            +                    fold = this.$foldData[i++];
            +                    foldStart = fold ?fold.start.row :Infinity;
            +                }
            +            }
            +        }
            +        if (this.lineWidgets)
            +            screenRows += this.$getWidgetScreenLength();
            +
            +        return screenRows;
            +    };
            +    this.$setFontMetrics = function(fm) {
            +    }
            +    function isFullWidth(c) {
            +        if (c < 0x1100)
            +            return false;
            +        return c >= 0x1100 && c <= 0x115F ||
            +               c >= 0x11A3 && c <= 0x11A7 ||
            +               c >= 0x11FA && c <= 0x11FF ||
            +               c >= 0x2329 && c <= 0x232A ||
            +               c >= 0x2E80 && c <= 0x2E99 ||
            +               c >= 0x2E9B && c <= 0x2EF3 ||
            +               c >= 0x2F00 && c <= 0x2FD5 ||
            +               c >= 0x2FF0 && c <= 0x2FFB ||
            +               c >= 0x3000 && c <= 0x303E ||
            +               c >= 0x3041 && c <= 0x3096 ||
            +               c >= 0x3099 && c <= 0x30FF ||
            +               c >= 0x3105 && c <= 0x312D ||
            +               c >= 0x3131 && c <= 0x318E ||
            +               c >= 0x3190 && c <= 0x31BA ||
            +               c >= 0x31C0 && c <= 0x31E3 ||
            +               c >= 0x31F0 && c <= 0x321E ||
            +               c >= 0x3220 && c <= 0x3247 ||
            +               c >= 0x3250 && c <= 0x32FE ||
            +               c >= 0x3300 && c <= 0x4DBF ||
            +               c >= 0x4E00 && c <= 0xA48C ||
            +               c >= 0xA490 && c <= 0xA4C6 ||
            +               c >= 0xA960 && c <= 0xA97C ||
            +               c >= 0xAC00 && c <= 0xD7A3 ||
            +               c >= 0xD7B0 && c <= 0xD7C6 ||
            +               c >= 0xD7CB && c <= 0xD7FB ||
            +               c >= 0xF900 && c <= 0xFAFF ||
            +               c >= 0xFE10 && c <= 0xFE19 ||
            +               c >= 0xFE30 && c <= 0xFE52 ||
            +               c >= 0xFE54 && c <= 0xFE66 ||
            +               c >= 0xFE68 && c <= 0xFE6B ||
            +               c >= 0xFF01 && c <= 0xFF60 ||
            +               c >= 0xFFE0 && c <= 0xFFE6;
            +    };
            +
            +}).call(EditSession.prototype);
            +
            +require("./edit_session/folding").Folding.call(EditSession.prototype);
            +require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype);
            +
            +
            +config.defineOptions(EditSession.prototype, "session", {
            +    wrap: {
            +        set: function(value) {
            +            if (!value || value == "off")
            +                value = false;
            +            else if (value == "free")
            +                value = true;
            +            else if (value == "printMargin")
            +                value = -1;
            +            else if (typeof value == "string")
            +                value = parseInt(value, 10) || false;
            +
            +            if (this.$wrap == value)
            +                return;
            +            if (!value) {
            +                this.setUseWrapMode(false);
            +            } else {
            +                var col = typeof value == "number" ? value : null;
            +                this.setWrapLimitRange(col, col);
            +                this.setUseWrapMode(true);
            +            }
            +            this.$wrap = value;
            +        },
            +        get: function() {
            +            if (this.getUseWrapMode()) {
            +                if (this.$wrap == -1)
            +                    return "printMargin";
            +                if (!this.getWrapLimitRange().min)
            +                    return "free";
            +                return this.$wrap;
            +            }
            +            return "off";
            +        },
            +        handlesSet: true
            +    },    
            +    wrapMethod: {
            +        set: function(val) {
            +            val = val == "auto"
            +                ? this.$mode.type != "text"
            +                : val != "text";
            +            if (val != this.$wrapAsCode) {
            +                this.$wrapAsCode = val;
            +                if (this.$useWrapMode) {
            +                    this.$modified = true;
            +                    this.$resetRowCache(0);
            +                    this.$updateWrapData(0, this.getLength() - 1);
            +                }
            +            }
            +        },
            +        initialValue: "auto"
            +    },
            +    firstLineNumber: {
            +        set: function() {this._signal("changeBreakpoint");},
            +        initialValue: 1
            +    },
            +    useWorker: {
            +        set: function(useWorker) {
            +            this.$useWorker = useWorker;
            +
            +            this.$stopWorker();
            +            if (useWorker)
            +                this.$startWorker();
            +        },
            +        initialValue: true
            +    },
            +    useSoftTabs: {initialValue: true},
            +    tabSize: {
            +        set: function(tabSize) {
            +            if (isNaN(tabSize) || this.$tabSize === tabSize) return;
            +
            +            this.$modified = true;
            +            this.$rowLengthCache = [];
            +            this.$tabSize = tabSize;
            +            this._signal("changeTabSize");
            +        },
            +        initialValue: 4,
            +        handlesSet: true
            +    },
            +    overwrite: {
            +        set: function(val) {this._signal("changeOverwrite");},
            +        initialValue: false
            +    },
            +    newLineMode: {
            +        set: function(val) {this.doc.setNewLineMode(val)},
            +        get: function() {return this.doc.getNewLineMode()},
            +        handlesSet: true
            +    },
            +    mode: {
            +        set: function(val) { this.setMode(val) },
            +        get: function() { return this.$modeId }
            +    }
            +});
            +
            +exports.EditSession = EditSession;
            +});
            +
            +define("ace/search",["require","exports","module","ace/lib/lang","ace/lib/oop","ace/range"], function(require, exports, module) {
            +"use strict";
            +
            +var lang = require("./lib/lang");
            +var oop = require("./lib/oop");
            +var Range = require("./range").Range;
            +
            +var Search = function() {
            +    this.$options = {};
            +};
            +
            +(function() {
            +    this.set = function(options) {
            +        oop.mixin(this.$options, options);
            +        return this;
            +    };
            +    this.getOptions = function() {
            +        return lang.copyObject(this.$options);
            +    };
            +    this.setOptions = function(options) {
            +        this.$options = options;
            +    };
            +    this.find = function(session) {
            +        var iterator = this.$matchIterator(session, this.$options);
            +
            +        if (!iterator)
            +            return false;
            +
            +        var firstRange = null;
            +        iterator.forEach(function(range, row, offset) {
            +            if (!range.start) {
            +                var column = range.offset + (offset || 0);
            +                firstRange = new Range(row, column, row, column+range.length);
            +            } else
            +                firstRange = range;
            +            return true;
            +        });
            +
            +        return firstRange;
            +    };
            +    this.findAll = function(session) {
            +        var options = this.$options;
            +        if (!options.needle)
            +            return [];
            +        this.$assembleRegExp(options);
            +
            +        var range = options.range;
            +        var lines = range
            +            ? session.getLines(range.start.row, range.end.row)
            +            : session.doc.getAllLines();
            +
            +        var ranges = [];
            +        var re = options.re;
            +        if (options.$isMultiLine) {
            +            var len = re.length;
            +            var maxRow = lines.length - len;
            +            var prevRange;
            +            outer: for (var row = re.offset || 0; row <= maxRow; row++) {
            +                for (var j = 0; j < len; j++)
            +                    if (lines[row + j].search(re[j]) == -1)
            +                        continue outer;
            +                
            +                var startLine = lines[row];
            +                var line = lines[row + len - 1];
            +                var startIndex = startLine.length - startLine.match(re[0])[0].length;
            +                var endIndex = line.match(re[len - 1])[0].length;
            +                
            +                if (prevRange && prevRange.end.row === row &&
            +                    prevRange.end.column > startIndex
            +                ) {
            +                    continue;
            +                }
            +                ranges.push(prevRange = new Range(
            +                    row, startIndex, row + len - 1, endIndex
            +                ));
            +                if (len > 2)
            +                    row = row + len - 2;
            +            }
            +        } else {
            +            for (var i = 0; i < lines.length; i++) {
            +                var matches = lang.getMatchOffsets(lines[i], re);
            +                for (var j = 0; j < matches.length; j++) {
            +                    var match = matches[j];
            +                    ranges.push(new Range(i, match.offset, i, match.offset + match.length));
            +                }
            +            }
            +        }
            +
            +        if (range) {
            +            var startColumn = range.start.column;
            +            var endColumn = range.start.column;
            +            var i = 0, j = ranges.length - 1;
            +            while (i < j && ranges[i].start.column < startColumn && ranges[i].start.row == range.start.row)
            +                i++;
            +
            +            while (i < j && ranges[j].end.column > endColumn && ranges[j].end.row == range.end.row)
            +                j--;
            +            
            +            ranges = ranges.slice(i, j + 1);
            +            for (i = 0, j = ranges.length; i < j; i++) {
            +                ranges[i].start.row += range.start.row;
            +                ranges[i].end.row += range.start.row;
            +            }
            +        }
            +
            +        return ranges;
            +    };
            +    this.replace = function(input, replacement) {
            +        var options = this.$options;
            +
            +        var re = this.$assembleRegExp(options);
            +        if (options.$isMultiLine)
            +            return replacement;
            +
            +        if (!re)
            +            return;
            +
            +        var match = re.exec(input);
            +        if (!match || match[0].length != input.length)
            +            return null;
            +        
            +        replacement = input.replace(re, replacement);
            +        if (options.preserveCase) {
            +            replacement = replacement.split("");
            +            for (var i = Math.min(input.length, input.length); i--; ) {
            +                var ch = input[i];
            +                if (ch && ch.toLowerCase() != ch)
            +                    replacement[i] = replacement[i].toUpperCase();
            +                else
            +                    replacement[i] = replacement[i].toLowerCase();
            +            }
            +            replacement = replacement.join("");
            +        }
            +        
            +        return replacement;
            +    };
            +
            +    this.$matchIterator = function(session, options) {
            +        var re = this.$assembleRegExp(options);
            +        if (!re)
            +            return false;
            +
            +        var self = this, callback, backwards = options.backwards;
            +
            +        if (options.$isMultiLine) {
            +            var len = re.length;
            +            var matchIterator = function(line, row, offset) {
            +                var startIndex = line.search(re[0]);
            +                if (startIndex == -1)
            +                    return;
            +                for (var i = 1; i < len; i++) {
            +                    line = session.getLine(row + i);
            +                    if (line.search(re[i]) == -1)
            +                        return;
            +                }
            +
            +                var endIndex = line.match(re[len - 1])[0].length;
            +
            +                var range = new Range(row, startIndex, row + len - 1, endIndex);
            +                if (re.offset == 1) {
            +                    range.start.row--;
            +                    range.start.column = Number.MAX_VALUE;
            +                } else if (offset)
            +                    range.start.column += offset;
            +
            +                if (callback(range))
            +                    return true;
            +            };
            +        } else if (backwards) {
            +            var matchIterator = function(line, row, startIndex) {
            +                var matches = lang.getMatchOffsets(line, re);
            +                for (var i = matches.length-1; i >= 0; i--)
            +                    if (callback(matches[i], row, startIndex))
            +                        return true;
            +            };
            +        } else {
            +            var matchIterator = function(line, row, startIndex) {
            +                var matches = lang.getMatchOffsets(line, re);
            +                for (var i = 0; i < matches.length; i++)
            +                    if (callback(matches[i], row, startIndex))
            +                        return true;
            +            };
            +        }
            +
            +        return {
            +            forEach: function(_callback) {
            +                callback = _callback;
            +                self.$lineIterator(session, options).forEach(matchIterator);
            +            }
            +        };
            +    };
            +
            +    this.$assembleRegExp = function(options, $disableFakeMultiline) {
            +        if (options.needle instanceof RegExp)
            +            return options.re = options.needle;
            +
            +        var needle = options.needle;
            +
            +        if (!options.needle)
            +            return options.re = false;
            +
            +        if (!options.regExp)
            +            needle = lang.escapeRegExp(needle);
            +
            +        if (options.wholeWord)
            +            needle = "\\b" + needle + "\\b";
            +
            +        var modifier = options.caseSensitive ? "g" : "gi";
            +
            +        options.$isMultiLine = !$disableFakeMultiline && /[\n\r]/.test(needle);
            +        if (options.$isMultiLine)
            +            return options.re = this.$assembleMultilineRegExp(needle, modifier);
            +
            +        try {
            +            var re = new RegExp(needle, modifier);
            +        } catch(e) {
            +            re = false;
            +        }
            +        return options.re = re;
            +    };
            +
            +    this.$assembleMultilineRegExp = function(needle, modifier) {
            +        var parts = needle.replace(/\r\n|\r|\n/g, "$\n^").split("\n");
            +        var re = [];
            +        for (var i = 0; i < parts.length; i++) try {
            +            re.push(new RegExp(parts[i], modifier));
            +        } catch(e) {
            +            return false;
            +        }
            +        if (parts[0] == "") {
            +            re.shift();
            +            re.offset = 1;
            +        } else {
            +            re.offset = 0;
            +        }
            +        return re;
            +    };
            +
            +    this.$lineIterator = function(session, options) {
            +        var backwards = options.backwards == true;
            +        var skipCurrent = options.skipCurrent != false;
            +
            +        var range = options.range;
            +        var start = options.start;
            +        if (!start)
            +            start = range ? range[backwards ? "end" : "start"] : session.selection.getRange();
            +         
            +        if (start.start)
            +            start = start[skipCurrent != backwards ? "end" : "start"];
            +
            +        var firstRow = range ? range.start.row : 0;
            +        var lastRow = range ? range.end.row : session.getLength() - 1;
            +
            +        var forEach = backwards ? function(callback) {
            +                var row = start.row;
            +
            +                var line = session.getLine(row).substring(0, start.column);
            +                if (callback(line, row))
            +                    return;
            +
            +                for (row--; row >= firstRow; row--)
            +                    if (callback(session.getLine(row), row))
            +                        return;
            +
            +                if (options.wrap == false)
            +                    return;
            +
            +                for (row = lastRow, firstRow = start.row; row >= firstRow; row--)
            +                    if (callback(session.getLine(row), row))
            +                        return;
            +            } : function(callback) {
            +                var row = start.row;
            +
            +                var line = session.getLine(row).substr(start.column);
            +                if (callback(line, row, start.column))
            +                    return;
            +
            +                for (row = row+1; row <= lastRow; row++)
            +                    if (callback(session.getLine(row), row))
            +                        return;
            +
            +                if (options.wrap == false)
            +                    return;
            +
            +                for (row = firstRow, lastRow = start.row; row <= lastRow; row++)
            +                    if (callback(session.getLine(row), row))
            +                        return;
            +            };
            +        
            +        return {forEach: forEach};
            +    };
            +
            +}).call(Search.prototype);
            +
            +exports.Search = Search;
            +});
            +
            +define("ace/keyboard/hash_handler",["require","exports","module","ace/lib/keys","ace/lib/useragent"], function(require, exports, module) {
            +"use strict";
            +
            +var keyUtil = require("../lib/keys");
            +var useragent = require("../lib/useragent");
            +
            +function HashHandler(config, platform) {
            +    this.platform = platform || (useragent.isMac ? "mac" : "win");
            +    this.commands = {};
            +    this.commandKeyBinding = {};
            +    if (this.__defineGetter__ && this.__defineSetter__ && typeof console != "undefined" && console.error) {
            +        var warned = false;
            +        var warn = function() {
            +            if (!warned) {
            +                warned = true;
            +                console.error("commmandKeyBinding has too many m's. use commandKeyBinding");
            +            }
            +        };
            +        this.__defineGetter__("commmandKeyBinding", function() {
            +            warn();
            +            return this.commandKeyBinding;
            +        });
            +        this.__defineSetter__("commmandKeyBinding", function(val) {
            +            warn();
            +            return this.commandKeyBinding = val;
            +        });
            +    } else {
            +        this.commmandKeyBinding = this.commandKeyBinding;
            +    }
            +
            +    this.addCommands(config);
            +};
            +
            +(function() {
            +
            +    this.addCommand = function(command) {
            +        if (this.commands[command.name])
            +            this.removeCommand(command);
            +
            +        this.commands[command.name] = command;
            +
            +        if (command.bindKey)
            +            this._buildKeyHash(command);
            +    };
            +
            +    this.removeCommand = function(command) {
            +        var name = (typeof command === 'string' ? command : command.name);
            +        command = this.commands[name];
            +        delete this.commands[name];
            +        var ckb = this.commandKeyBinding;
            +        for (var hashId in ckb) {
            +            for (var key in ckb[hashId]) {
            +                if (ckb[hashId][key] == command)
            +                    delete ckb[hashId][key];
            +            }
            +        }
            +    };
            +
            +    this.bindKey = function(key, command) {
            +        if(!key)
            +            return;
            +        if (typeof command == "function") {
            +            this.addCommand({exec: command, bindKey: key, name: command.name || key});
            +            return;
            +        }
            +
            +        var ckb = this.commandKeyBinding;
            +        key.split("|").forEach(function(keyPart) {
            +            var binding = this.parseKeys(keyPart, command);
            +            var hashId = binding.hashId;
            +            (ckb[hashId] || (ckb[hashId] = {}))[binding.key] = command;
            +        }, this);
            +    };
            +
            +    this.addCommands = function(commands) {
            +        commands && Object.keys(commands).forEach(function(name) {
            +            var command = commands[name];
            +            if (!command)
            +                return;
            +            
            +            if (typeof command === "string")
            +                return this.bindKey(command, name);
            +
            +            if (typeof command === "function")
            +                command = { exec: command };
            +
            +            if (typeof command !== "object")
            +                return;
            +
            +            if (!command.name)
            +                command.name = name;
            +
            +            this.addCommand(command);
            +        }, this);
            +    };
            +
            +    this.removeCommands = function(commands) {
            +        Object.keys(commands).forEach(function(name) {
            +            this.removeCommand(commands[name]);
            +        }, this);
            +    };
            +
            +    this.bindKeys = function(keyList) {
            +        Object.keys(keyList).forEach(function(key) {
            +            this.bindKey(key, keyList[key]);
            +        }, this);
            +    };
            +
            +    this._buildKeyHash = function(command) {
            +        var binding = command.bindKey;
            +        if (!binding)
            +            return;
            +
            +        var key = typeof binding == "string" ? binding: binding[this.platform];
            +        this.bindKey(key, command);
            +    };
            +    this.parseKeys = function(keys) {
            +        if (keys.indexOf(" ") != -1)
            +            keys = keys.split(/\s+/).pop();
            +
            +        var parts = keys.toLowerCase().split(/[\-\+]([\-\+])?/).filter(function(x){return x});
            +        var key = parts.pop();
            +
            +        var keyCode = keyUtil[key];
            +        if (keyUtil.FUNCTION_KEYS[keyCode])
            +            key = keyUtil.FUNCTION_KEYS[keyCode].toLowerCase();
            +        else if (!parts.length)
            +            return {key: key, hashId: -1};
            +        else if (parts.length == 1 && parts[0] == "shift")
            +            return {key: key.toUpperCase(), hashId: -1};
            +
            +        var hashId = 0;
            +        for (var i = parts.length; i--;) {
            +            var modifier = keyUtil.KEY_MODS[parts[i]];
            +            if (modifier == null) {
            +                if (typeof console != "undefined")
            +                console.error("invalid modifier " + parts[i] + " in " + keys);
            +                return false;
            +            }
            +            hashId |= modifier;
            +        }
            +        return {key: key, hashId: hashId};
            +    };
            +
            +    this.findKeyCommand = function findKeyCommand(hashId, keyString) {
            +        var ckbr = this.commandKeyBinding;
            +        return ckbr[hashId] && ckbr[hashId][keyString];
            +    };
            +
            +    this.handleKeyboard = function(data, hashId, keyString, keyCode) {
            +        return {
            +            command: this.findKeyCommand(hashId, keyString)
            +        };
            +    };
            +
            +}).call(HashHandler.prototype)
            +
            +exports.HashHandler = HashHandler;
            +});
            +
            +define("ace/commands/command_manager",["require","exports","module","ace/lib/oop","ace/keyboard/hash_handler","ace/lib/event_emitter"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("../lib/oop");
            +var HashHandler = require("../keyboard/hash_handler").HashHandler;
            +var EventEmitter = require("../lib/event_emitter").EventEmitter;
            +
            +var CommandManager = function(platform, commands) {
            +    HashHandler.call(this, commands, platform);
            +    this.byName = this.commands;
            +    this.setDefaultHandler("exec", function(e) {
            +        return e.command.exec(e.editor, e.args || {});
            +    });
            +};
            +
            +oop.inherits(CommandManager, HashHandler);
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +
            +    this.exec = function(command, editor, args) {
            +        if (typeof command === 'string')
            +            command = this.commands[command];
            +
            +        if (!command)
            +            return false;
            +
            +        if (editor && editor.$readOnly && !command.readOnly)
            +            return false;
            +
            +        var e = {editor: editor, command: command, args: args};
            +        var retvalue = this._emit("exec", e);
            +        this._signal("afterExec", e);
            +
            +        return retvalue === false ? false : true;
            +    };
            +
            +    this.toggleRecording = function(editor) {
            +        if (this.$inReplay)
            +            return;
            +
            +        editor && editor._emit("changeStatus");
            +        if (this.recording) {
            +            this.macro.pop();
            +            this.removeEventListener("exec", this.$addCommandToMacro);
            +
            +            if (!this.macro.length)
            +                this.macro = this.oldMacro;
            +
            +            return this.recording = false;
            +        }
            +        if (!this.$addCommandToMacro) {
            +            this.$addCommandToMacro = function(e) {
            +                this.macro.push([e.command, e.args]);
            +            }.bind(this);
            +        }
            +
            +        this.oldMacro = this.macro;
            +        this.macro = [];
            +        this.on("exec", this.$addCommandToMacro);
            +        return this.recording = true;
            +    };
            +
            +    this.replay = function(editor) {
            +        if (this.$inReplay || !this.macro)
            +            return;
            +
            +        if (this.recording)
            +            return this.toggleRecording(editor);
            +
            +        try {
            +            this.$inReplay = true;
            +            this.macro.forEach(function(x) {
            +                if (typeof x == "string")
            +                    this.exec(x, editor);
            +                else
            +                    this.exec(x[0], editor, x[1]);
            +            }, this);
            +        } finally {
            +            this.$inReplay = false;
            +        }
            +    };
            +
            +    this.trimMacro = function(m) {
            +        return m.map(function(x){
            +            if (typeof x[0] != "string")
            +                x[0] = x[0].name;
            +            if (!x[1])
            +                x = x[0];
            +            return x;
            +        });
            +    };
            +
            +}).call(CommandManager.prototype);
            +
            +exports.CommandManager = CommandManager;
            +
            +});
            +
            +define("ace/commands/default_commands",["require","exports","module","ace/lib/lang","ace/config","ace/range"], function(require, exports, module) {
            +"use strict";
            +
            +var lang = require("../lib/lang");
            +var config = require("../config");
            +var Range = require("../range").Range;
            +
            +function bindKey(win, mac) {
            +    return {win: win, mac: mac};
            +}
            +exports.commands = [{
            +    name: "showSettingsMenu",
            +    bindKey: bindKey("Ctrl-,", "Command-,"),
            +    exec: function(editor) {
            +        config.loadModule("ace/ext/settings_menu", function(module) {
            +            module.init(editor);
            +            editor.showSettingsMenu();
            +        });
            +    },
            +    readOnly: true
            +}, {
            +    name: "goToNextError",
            +    bindKey: bindKey("Alt-E", "Ctrl-E"),
            +    exec: function(editor) {
            +        config.loadModule("ace/ext/error_marker", function(module) {
            +            module.showErrorMarker(editor, 1);
            +        });
            +    },
            +    scrollIntoView: "animate",
            +    readOnly: true
            +}, {
            +    name: "goToPreviousError",
            +    bindKey: bindKey("Alt-Shift-E", "Ctrl-Shift-E"),
            +    exec: function(editor) {
            +        config.loadModule("ace/ext/error_marker", function(module) {
            +            module.showErrorMarker(editor, -1);
            +        });
            +    },
            +    scrollIntoView: "animate",
            +    readOnly: true
            +}, {
            +    name: "selectall",
            +    bindKey: bindKey("Ctrl-A", "Command-A"),
            +    exec: function(editor) { editor.selectAll(); },
            +    readOnly: true
            +}, {
            +    name: "centerselection",
            +    bindKey: bindKey(null, "Ctrl-L"),
            +    exec: function(editor) { editor.centerSelection(); },
            +    readOnly: true
            +}, {
            +    name: "gotoline",
            +    bindKey: bindKey("Ctrl-L", "Command-L"),
            +    exec: function(editor) {
            +        var line = parseInt(prompt("Enter line number:"), 10);
            +        if (!isNaN(line)) {
            +            editor.gotoLine(line);
            +        }
            +    },
            +    readOnly: true
            +}, {
            +    name: "fold",
            +    bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
            +    exec: function(editor) { editor.session.toggleFold(false); },
            +    scrollIntoView: "center",
            +    readOnly: true
            +}, {
            +    name: "unfold",
            +    bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
            +    exec: function(editor) { editor.session.toggleFold(true); },
            +    scrollIntoView: "center",
            +    readOnly: true
            +}, {
            +    name: "toggleFoldWidget",
            +    bindKey: bindKey("F2", "F2"),
            +    exec: function(editor) { editor.session.toggleFoldWidget(); },
            +    scrollIntoView: "center",
            +    readOnly: true
            +}, {
            +    name: "toggleParentFoldWidget",
            +    bindKey: bindKey("Alt-F2", "Alt-F2"),
            +    exec: function(editor) { editor.session.toggleFoldWidget(true); },
            +    scrollIntoView: "center",
            +    readOnly: true
            +}, {
            +    name: "foldall",
            +    bindKey: bindKey("Ctrl-Alt-0", "Ctrl-Command-Option-0"),
            +    exec: function(editor) { editor.session.foldAll(); },
            +    scrollIntoView: "center",
            +    readOnly: true
            +}, {
            +    name: "foldOther",
            +    bindKey: bindKey("Alt-0", "Command-Option-0"),
            +    exec: function(editor) { 
            +        editor.session.foldAll();
            +        editor.session.unfold(editor.selection.getAllRanges());
            +    },
            +    scrollIntoView: "center",
            +    readOnly: true
            +}, {
            +    name: "unfoldall",
            +    bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
            +    exec: function(editor) { editor.session.unfold(); },
            +    scrollIntoView: "center",
            +    readOnly: true
            +}, {
            +    name: "findnext",
            +    bindKey: bindKey("Ctrl-K", "Command-G"),
            +    exec: function(editor) { editor.findNext(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "center",
            +    readOnly: true
            +}, {
            +    name: "findprevious",
            +    bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
            +    exec: function(editor) { editor.findPrevious(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "center",
            +    readOnly: true
            +}, {
            +    name: "selectOrFindNext",
            +    bindKey: bindKey("Alt-K", "Ctrl-G"),
            +    exec: function(editor) {
            +        if (editor.selection.isEmpty())
            +            editor.selection.selectWord();
            +        else
            +            editor.findNext(); 
            +    },
            +    readOnly: true
            +}, {
            +    name: "selectOrFindPrevious",
            +    bindKey: bindKey("Alt-Shift-K", "Ctrl-Shift-G"),
            +    exec: function(editor) { 
            +        if (editor.selection.isEmpty())
            +            editor.selection.selectWord();
            +        else
            +            editor.findPrevious();
            +    },
            +    readOnly: true
            +}, {
            +    name: "find",
            +    bindKey: bindKey("Ctrl-F", "Command-F"),
            +    exec: function(editor) {
            +        config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor)});
            +    },
            +    readOnly: true
            +}, {
            +    name: "overwrite",
            +    bindKey: "Insert",
            +    exec: function(editor) { editor.toggleOverwrite(); },
            +    readOnly: true
            +}, {
            +    name: "selecttostart",
            +    bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"),
            +    exec: function(editor) { editor.getSelection().selectFileStart(); },
            +    multiSelectAction: "forEach",
            +    readOnly: true,
            +    scrollIntoView: "animate",
            +    aceCommandGroup: "fileJump"
            +}, {
            +    name: "gotostart",
            +    bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
            +    exec: function(editor) { editor.navigateFileStart(); },
            +    multiSelectAction: "forEach",
            +    readOnly: true,
            +    scrollIntoView: "animate",
            +    aceCommandGroup: "fileJump"
            +}, {
            +    name: "selectup",
            +    bindKey: bindKey("Shift-Up", "Shift-Up"),
            +    exec: function(editor) { editor.getSelection().selectUp(); },
            +    multiSelectAction: "forEach",
            +    readOnly: true
            +}, {
            +    name: "golineup",
            +    bindKey: bindKey("Up", "Up|Ctrl-P"),
            +    exec: function(editor, args) { editor.navigateUp(args.times); },
            +    multiSelectAction: "forEach",
            +    readOnly: true
            +}, {
            +    name: "selecttoend",
            +    bindKey: bindKey("Ctrl-Shift-End", "Command-Shift-Down"),
            +    exec: function(editor) { editor.getSelection().selectFileEnd(); },
            +    multiSelectAction: "forEach",
            +    readOnly: true,
            +    scrollIntoView: "animate",
            +    aceCommandGroup: "fileJump"
            +}, {
            +    name: "gotoend",
            +    bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"),
            +    exec: function(editor) { editor.navigateFileEnd(); },
            +    multiSelectAction: "forEach",
            +    readOnly: true,
            +    scrollIntoView: "animate",
            +    aceCommandGroup: "fileJump"
            +}, {
            +    name: "selectdown",
            +    bindKey: bindKey("Shift-Down", "Shift-Down"),
            +    exec: function(editor) { editor.getSelection().selectDown(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "golinedown",
            +    bindKey: bindKey("Down", "Down|Ctrl-N"),
            +    exec: function(editor, args) { editor.navigateDown(args.times); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "selectwordleft",
            +    bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
            +    exec: function(editor) { editor.getSelection().selectWordLeft(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "gotowordleft",
            +    bindKey: bindKey("Ctrl-Left", "Option-Left"),
            +    exec: function(editor) { editor.navigateWordLeft(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "selecttolinestart",
            +    bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"),
            +    exec: function(editor) { editor.getSelection().selectLineStart(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "gotolinestart",
            +    bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
            +    exec: function(editor) { editor.navigateLineStart(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "selectleft",
            +    bindKey: bindKey("Shift-Left", "Shift-Left"),
            +    exec: function(editor) { editor.getSelection().selectLeft(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "gotoleft",
            +    bindKey: bindKey("Left", "Left|Ctrl-B"),
            +    exec: function(editor, args) { editor.navigateLeft(args.times); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "selectwordright",
            +    bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
            +    exec: function(editor) { editor.getSelection().selectWordRight(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "gotowordright",
            +    bindKey: bindKey("Ctrl-Right", "Option-Right"),
            +    exec: function(editor) { editor.navigateWordRight(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "selecttolineend",
            +    bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"),
            +    exec: function(editor) { editor.getSelection().selectLineEnd(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "gotolineend",
            +    bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
            +    exec: function(editor) { editor.navigateLineEnd(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "selectright",
            +    bindKey: bindKey("Shift-Right", "Shift-Right"),
            +    exec: function(editor) { editor.getSelection().selectRight(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "gotoright",
            +    bindKey: bindKey("Right", "Right|Ctrl-F"),
            +    exec: function(editor, args) { editor.navigateRight(args.times); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "selectpagedown",
            +    bindKey: "Shift-PageDown",
            +    exec: function(editor) { editor.selectPageDown(); },
            +    readOnly: true
            +}, {
            +    name: "pagedown",
            +    bindKey: bindKey(null, "Option-PageDown"),
            +    exec: function(editor) { editor.scrollPageDown(); },
            +    readOnly: true
            +}, {
            +    name: "gotopagedown",
            +    bindKey: bindKey("PageDown", "PageDown|Ctrl-V"),
            +    exec: function(editor) { editor.gotoPageDown(); },
            +    readOnly: true
            +}, {
            +    name: "selectpageup",
            +    bindKey: "Shift-PageUp",
            +    exec: function(editor) { editor.selectPageUp(); },
            +    readOnly: true
            +}, {
            +    name: "pageup",
            +    bindKey: bindKey(null, "Option-PageUp"),
            +    exec: function(editor) { editor.scrollPageUp(); },
            +    readOnly: true
            +}, {
            +    name: "gotopageup",
            +    bindKey: "PageUp",
            +    exec: function(editor) { editor.gotoPageUp(); },
            +    readOnly: true
            +}, {
            +    name: "scrollup",
            +    bindKey: bindKey("Ctrl-Up", null),
            +    exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },
            +    readOnly: true
            +}, {
            +    name: "scrolldown",
            +    bindKey: bindKey("Ctrl-Down", null),
            +    exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },
            +    readOnly: true
            +}, {
            +    name: "selectlinestart",
            +    bindKey: "Shift-Home",
            +    exec: function(editor) { editor.getSelection().selectLineStart(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "selectlineend",
            +    bindKey: "Shift-End",
            +    exec: function(editor) { editor.getSelection().selectLineEnd(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "togglerecording",
            +    bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"),
            +    exec: function(editor) { editor.commands.toggleRecording(editor); },
            +    readOnly: true
            +}, {
            +    name: "replaymacro",
            +    bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"),
            +    exec: function(editor) { editor.commands.replay(editor); },
            +    readOnly: true
            +}, {
            +    name: "jumptomatching",
            +    bindKey: bindKey("Ctrl-P", "Ctrl-P"),
            +    exec: function(editor) { editor.jumpToMatching(); },
            +    multiSelectAction: "forEach",
            +    readOnly: true
            +}, {
            +    name: "selecttomatching",
            +    bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
            +    exec: function(editor) { editor.jumpToMatching(true); },
            +    multiSelectAction: "forEach",
            +    readOnly: true
            +}, {
            +    name: "passKeysToBrowser",
            +    bindKey: bindKey("null", "null"),
            +    exec: function() {},
            +    passEvent: true,
            +    readOnly: true
            +},
            +{
            +    name: "cut",
            +    exec: function(editor) {
            +        var range = editor.getSelectionRange();
            +        editor._emit("cut", range);
            +
            +        if (!editor.selection.isEmpty()) {
            +            editor.session.remove(range);
            +            editor.clearSelection();
            +        }
            +    },
            +    scrollIntoView: "cursor",
            +    multiSelectAction: "forEach"
            +}, {
            +    name: "removeline",
            +    bindKey: bindKey("Ctrl-D", "Command-D"),
            +    exec: function(editor) { editor.removeLines(); },
            +    scrollIntoView: "cursor",
            +    multiSelectAction: "forEachLine"
            +}, {
            +    name: "duplicateSelection",
            +    bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
            +    exec: function(editor) { editor.duplicateSelection(); },
            +    scrollIntoView: "cursor",
            +    multiSelectAction: "forEach"
            +}, {
            +    name: "sortlines",
            +    bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
            +    exec: function(editor) { editor.sortLines(); },
            +    scrollIntoView: "selection",
            +    multiSelectAction: "forEachLine"
            +}, {
            +    name: "togglecomment",
            +    bindKey: bindKey("Ctrl-/", "Command-/"),
            +    exec: function(editor) { editor.toggleCommentLines(); },
            +    multiSelectAction: "forEachLine",
            +    scrollIntoView: "selectionPart"
            +}, {
            +    name: "toggleBlockComment",
            +    bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"),
            +    exec: function(editor) { editor.toggleBlockComment(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "selectionPart"
            +}, {
            +    name: "modifyNumberUp",
            +    bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
            +    exec: function(editor) { editor.modifyNumber(1); },
            +    multiSelectAction: "forEach"
            +}, {
            +    name: "modifyNumberDown",
            +    bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"),
            +    exec: function(editor) { editor.modifyNumber(-1); },
            +    multiSelectAction: "forEach"
            +}, {
            +    name: "replace",
            +    bindKey: bindKey("Ctrl-H", "Command-Option-F"),
            +    exec: function(editor) {
            +        config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true)});
            +    }
            +}, {
            +    name: "undo",
            +    bindKey: bindKey("Ctrl-Z", "Command-Z"),
            +    exec: function(editor) { editor.undo(); }
            +}, {
            +    name: "redo",
            +    bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
            +    exec: function(editor) { editor.redo(); }
            +}, {
            +    name: "copylinesup",
            +    bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"),
            +    exec: function(editor) { editor.copyLinesUp(); },
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "movelinesup",
            +    bindKey: bindKey("Alt-Up", "Option-Up"),
            +    exec: function(editor) { editor.moveLinesUp(); },
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "copylinesdown",
            +    bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"),
            +    exec: function(editor) { editor.copyLinesDown(); },
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "movelinesdown",
            +    bindKey: bindKey("Alt-Down", "Option-Down"),
            +    exec: function(editor) { editor.moveLinesDown(); },
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "del",
            +    bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"),
            +    exec: function(editor) { editor.remove("right"); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "backspace",
            +    bindKey: bindKey(
            +        "Shift-Backspace|Backspace",
            +        "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"
            +    ),
            +    exec: function(editor) { editor.remove("left"); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "cut_or_delete",
            +    bindKey: bindKey("Shift-Delete", null),
            +    exec: function(editor) { 
            +        if (editor.selection.isEmpty()) {
            +            editor.remove("left");
            +        } else {
            +            return false;
            +        }
            +    },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "removetolinestart",
            +    bindKey: bindKey("Alt-Backspace", "Command-Backspace"),
            +    exec: function(editor) { editor.removeToLineStart(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "removetolineend",
            +    bindKey: bindKey("Alt-Delete", "Ctrl-K"),
            +    exec: function(editor) { editor.removeToLineEnd(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "removewordleft",
            +    bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
            +    exec: function(editor) { editor.removeWordLeft(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "removewordright",
            +    bindKey: bindKey("Ctrl-Delete", "Alt-Delete"),
            +    exec: function(editor) { editor.removeWordRight(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "outdent",
            +    bindKey: bindKey("Shift-Tab", "Shift-Tab"),
            +    exec: function(editor) { editor.blockOutdent(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "selectionPart"
            +}, {
            +    name: "indent",
            +    bindKey: bindKey("Tab", "Tab"),
            +    exec: function(editor) { editor.indent(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "selectionPart"
            +}, {
            +    name: "blockoutdent",
            +    bindKey: bindKey("Ctrl-[", "Ctrl-["),
            +    exec: function(editor) { editor.blockOutdent(); },
            +    multiSelectAction: "forEachLine",
            +    scrollIntoView: "selectionPart"
            +}, {
            +    name: "blockindent",
            +    bindKey: bindKey("Ctrl-]", "Ctrl-]"),
            +    exec: function(editor) { editor.blockIndent(); },
            +    multiSelectAction: "forEachLine",
            +    scrollIntoView: "selectionPart"
            +}, {
            +    name: "insertstring",
            +    exec: function(editor, str) { editor.insert(str); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "inserttext",
            +    exec: function(editor, args) {
            +        editor.insert(lang.stringRepeat(args.text  || "", args.times || 1));
            +    },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "splitline",
            +    bindKey: bindKey(null, "Ctrl-O"),
            +    exec: function(editor) { editor.splitLine(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "transposeletters",
            +    bindKey: bindKey("Ctrl-T", "Ctrl-T"),
            +    exec: function(editor) { editor.transposeLetters(); },
            +    multiSelectAction: function(editor) {editor.transposeSelections(1); },
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "touppercase",
            +    bindKey: bindKey("Ctrl-U", "Ctrl-U"),
            +    exec: function(editor) { editor.toUpperCase(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "tolowercase",
            +    bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"),
            +    exec: function(editor) { editor.toLowerCase(); },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor"
            +}, {
            +    name: "expandtoline",
            +    bindKey: bindKey("Ctrl-Shift-L", "Command-Shift-L"),
            +    exec: function(editor) {
            +        var range = editor.selection.getRange();
            +
            +        range.start.column = range.end.column = 0;
            +        range.end.row++;
            +        editor.selection.setRange(range, false);
            +    },
            +    multiSelectAction: "forEach",
            +    scrollIntoView: "cursor",
            +    readOnly: true
            +}, {
            +    name: "joinlines",
            +    bindKey: bindKey(null, null),
            +    exec: function(editor) {
            +        var isBackwards = editor.selection.isBackwards();
            +        var selectionStart = isBackwards ? editor.selection.getSelectionLead() : editor.selection.getSelectionAnchor();
            +        var selectionEnd = isBackwards ? editor.selection.getSelectionAnchor() : editor.selection.getSelectionLead();
            +        var firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length
            +        var selectedText = editor.session.doc.getTextRange(editor.selection.getRange());
            +        var selectedCount = selectedText.replace(/\n\s*/, " ").length;
            +        var insertLine = editor.session.doc.getLine(selectionStart.row);
            +
            +        for (var i = selectionStart.row + 1; i <= selectionEnd.row + 1; i++) {
            +            var curLine = lang.stringTrimLeft(lang.stringTrimRight(editor.session.doc.getLine(i)));
            +            if (curLine.length !== 0) {
            +                curLine = " " + curLine;
            +            }
            +            insertLine += curLine;
            +        };
            +
            +        if (selectionEnd.row + 1 < (editor.session.doc.getLength() - 1)) {
            +            insertLine += editor.session.doc.getNewLineCharacter();
            +        }
            +
            +        editor.clearSelection();
            +        editor.session.doc.replace(new Range(selectionStart.row, 0, selectionEnd.row + 2, 0), insertLine);
            +
            +        if (selectedCount > 0) {
            +            editor.selection.moveCursorTo(selectionStart.row, selectionStart.column);
            +            editor.selection.selectTo(selectionStart.row, selectionStart.column + selectedCount);
            +        } else {
            +            firstLineEndCol = editor.session.doc.getLine(selectionStart.row).length > firstLineEndCol ? (firstLineEndCol + 1) : firstLineEndCol;
            +            editor.selection.moveCursorTo(selectionStart.row, firstLineEndCol);
            +        }
            +    },
            +    multiSelectAction: "forEach",
            +    readOnly: true
            +}, {
            +    name: "invertSelection",
            +    bindKey: bindKey(null, null),
            +    exec: function(editor) {
            +        var endRow = editor.session.doc.getLength() - 1;
            +        var endCol = editor.session.doc.getLine(endRow).length;
            +        var ranges = editor.selection.rangeList.ranges;
            +        var newRanges = [];
            +        if (ranges.length < 1) {
            +            ranges = [editor.selection.getRange()];
            +        }
            +
            +        for (var i = 0; i < ranges.length; i++) {
            +            if (i == (ranges.length - 1)) {
            +                if (!(ranges[i].end.row === endRow && ranges[i].end.column === endCol)) {
            +                    newRanges.push(new Range(ranges[i].end.row, ranges[i].end.column, endRow, endCol));
            +                }
            +            }
            +
            +            if (i === 0) {
            +                if (!(ranges[i].start.row === 0 && ranges[i].start.column === 0)) {
            +                    newRanges.push(new Range(0, 0, ranges[i].start.row, ranges[i].start.column));
            +                }
            +            } else {
            +                newRanges.push(new Range(ranges[i-1].end.row, ranges[i-1].end.column, ranges[i].start.row, ranges[i].start.column));
            +            }
            +        }
            +
            +        editor.exitMultiSelectMode();
            +        editor.clearSelection();
            +
            +        for(var i = 0; i < newRanges.length; i++) {
            +            editor.selection.addRange(newRanges[i], false);
            +        }
            +    },
            +    readOnly: true,
            +    scrollIntoView: "none"
            +}];
            +
            +});
            +
            +define("ace/editor",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/keyboard/textinput","ace/mouse/mouse_handler","ace/mouse/fold_handler","ace/keyboard/keybinding","ace/edit_session","ace/search","ace/range","ace/lib/event_emitter","ace/commands/command_manager","ace/commands/default_commands","ace/config","ace/token_iterator"], function(require, exports, module) {
            +"use strict";
            +
            +require("./lib/fixoldbrowsers");
            +
            +var oop = require("./lib/oop");
            +var dom = require("./lib/dom");
            +var lang = require("./lib/lang");
            +var useragent = require("./lib/useragent");
            +var TextInput = require("./keyboard/textinput").TextInput;
            +var MouseHandler = require("./mouse/mouse_handler").MouseHandler;
            +var FoldHandler = require("./mouse/fold_handler").FoldHandler;
            +var KeyBinding = require("./keyboard/keybinding").KeyBinding;
            +var EditSession = require("./edit_session").EditSession;
            +var Search = require("./search").Search;
            +var Range = require("./range").Range;
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +var CommandManager = require("./commands/command_manager").CommandManager;
            +var defaultCommands = require("./commands/default_commands").commands;
            +var config = require("./config");
            +var TokenIterator = require("./token_iterator").TokenIterator;
            +var Editor = function(renderer, session) {
            +    var container = renderer.getContainerElement();
            +    this.container = container;
            +    this.renderer = renderer;
            +
            +    this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
            +    this.textInput  = new TextInput(renderer.getTextAreaContainer(), this);
            +    this.renderer.textarea = this.textInput.getElement();
            +    this.keyBinding = new KeyBinding(this);
            +    this.$mouseHandler = new MouseHandler(this);
            +    new FoldHandler(this);
            +
            +    this.$blockScrolling = 0;
            +    this.$search = new Search().set({
            +        wrap: true
            +    });
            +
            +    this.$historyTracker = this.$historyTracker.bind(this);
            +    this.commands.on("exec", this.$historyTracker);
            +
            +    this.$initOperationListeners();
            +    
            +    this._$emitInputEvent = lang.delayedCall(function() {
            +        this._signal("input", {});
            +        this.session.bgTokenizer && this.session.bgTokenizer.scheduleStart();
            +    }.bind(this));
            +    
            +    this.on("change", function(_, _self) {
            +        _self._$emitInputEvent.schedule(31);
            +    });
            +
            +    this.setSession(session || new EditSession(""));
            +    config.resetOptions(this);
            +    config._signal("editor", this);
            +};
            +
            +(function(){
            +
            +    oop.implement(this, EventEmitter);
            +
            +    this.$initOperationListeners = function() {
            +        function last(a) {return a[a.length - 1]}
            +
            +        this.selections = [];
            +        this.commands.on("exec", function(e) {
            +            this.startOperation(e);
            +
            +            var command = e.command;
            +            if (command.aceCommandGroup == "fileJump") {
            +                var prev = this.prevOp;
            +                if (!prev || prev.command.aceCommandGroup != "fileJump") {
            +                    this.lastFileJumpPos = last(this.selections);
            +                }
            +            } else {
            +                this.lastFileJumpPos = null;
            +            }
            +        }.bind(this), true);
            +
            +        this.commands.on("afterExec", function(e) {
            +            var command = e.command;
            +
            +            if (command.aceCommandGroup == "fileJump") {
            +                if (this.lastFileJumpPos && !this.curOp.selectionChanged) {
            +                    this.selection.fromJSON(this.lastFileJumpPos);
            +                }
            +            }
            +            this.endOperation(e);
            +        }.bind(this), true);
            +
            +        this.$opResetTimer = lang.delayedCall(this.endOperation.bind(this));
            +
            +        this.on("change", function() {
            +            this.curOp || this.startOperation();
            +            this.curOp.docChanged = true;
            +        }.bind(this), true);
            +
            +        this.on("changeSelection", function() {
            +            this.curOp || this.startOperation();
            +            this.curOp.selectionChanged = true;
            +        }.bind(this), true);
            +    };
            +
            +    this.curOp = null;
            +    this.prevOp = {};
            +    this.startOperation = function(commadEvent) {
            +        if (this.curOp) {
            +            if (!commadEvent || this.curOp.command)
            +                return;
            +            this.prevOp = this.curOp;
            +        }
            +        if (!commadEvent) {
            +            this.previousCommand = null;
            +            commadEvent = {};
            +        }
            +
            +        this.$opResetTimer.schedule();
            +        this.curOp = {
            +            command: commadEvent.command || {},
            +            args: commadEvent.args,
            +            scrollTop: this.renderer.scrollTop
            +        };
            +        
            +        var command = this.curOp.command;
            +        if (command && command.scrollIntoView)
            +            this.$blockScrolling++;
            +
            +        this.selections.push(this.selection.toJSON());
            +    };
            +
            +    this.endOperation = function() {
            +        if (this.curOp) {
            +            var command = this.curOp.command;
            +            if (command && command.scrollIntoView) {
            +                this.$blockScrolling--;
            +                switch (command.scrollIntoView) {
            +                    case "center":
            +                        this.renderer.scrollCursorIntoView(null, 0.5);
            +                        break;
            +                    case "animate":
            +                    case "cursor":
            +                        this.renderer.scrollCursorIntoView();
            +                        break;
            +                    case "selectionPart":
            +                        var range = this.selection.getRange();
            +                        var config = this.renderer.layerConfig;
            +                        if (range.start.row >= config.lastRow || range.end.row <= config.firstRow) {
            +                            this.renderer.scrollSelectionIntoView(this.selection.anchor, this.selection.lead);
            +                        }
            +                        break;
            +                    default:
            +                        break;
            +                }
            +                if (command.scrollIntoView == "animate")
            +                    this.renderer.animateScrolling(this.curOp.scrollTop);
            +            }
            +            
            +            this.prevOp = this.curOp;
            +            this.curOp = null;
            +        }
            +    };
            +    this.$mergeableCommands = ["backspace", "del", "insertstring"];
            +    this.$historyTracker = function(e) {
            +        if (!this.$mergeUndoDeltas)
            +            return;
            +
            +        var prev = this.prevOp;
            +        var mergeableCommands = this.$mergeableCommands;
            +        var shouldMerge = prev.command && (e.command.name == prev.command.name);
            +        if (e.command.name == "insertstring") {
            +            var text = e.args;
            +            if (this.mergeNextCommand === undefined)
            +                this.mergeNextCommand = true;
            +
            +            shouldMerge = shouldMerge
            +                && this.mergeNextCommand // previous command allows to coalesce with
            +                && (!/\s/.test(text) || /\s/.test(prev.args)); // previous insertion was of same type
            +
            +            this.mergeNextCommand = true;
            +        } else {
            +            shouldMerge = shouldMerge
            +                && mergeableCommands.indexOf(e.command.name) !== -1; // the command is mergeable
            +        }
            +
            +        if (
            +            this.$mergeUndoDeltas != "always"
            +            && Date.now() - this.sequenceStartTime > 2000
            +        ) {
            +            shouldMerge = false; // the sequence is too long
            +        }
            +
            +        if (shouldMerge)
            +            this.session.mergeUndoDeltas = true;
            +        else if (mergeableCommands.indexOf(e.command.name) !== -1)
            +            this.sequenceStartTime = Date.now();
            +    };
            +    this.setKeyboardHandler = function(keyboardHandler) {
            +        if (!keyboardHandler) {
            +            this.keyBinding.setKeyboardHandler(null);
            +        } else if (typeof keyboardHandler === "string") {
            +            this.$keybindingId = keyboardHandler;
            +            var _self = this;
            +            config.loadModule(["keybinding", keyboardHandler], function(module) {
            +                if (_self.$keybindingId == keyboardHandler)
            +                    _self.keyBinding.setKeyboardHandler(module && module.handler);
            +            });
            +        } else {
            +            this.$keybindingId = null;
            +            this.keyBinding.setKeyboardHandler(keyboardHandler);
            +        }
            +    };
            +    this.getKeyboardHandler = function() {
            +        return this.keyBinding.getKeyboardHandler();
            +    };
            +    this.setSession = function(session) {
            +        if (this.session == session)
            +            return;
            +
            +        var oldSession = this.session;
            +        if (oldSession) {
            +            this.session.removeEventListener("change", this.$onDocumentChange);
            +            this.session.removeEventListener("changeMode", this.$onChangeMode);
            +            this.session.removeEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
            +            this.session.removeEventListener("changeTabSize", this.$onChangeTabSize);
            +            this.session.removeEventListener("changeWrapLimit", this.$onChangeWrapLimit);
            +            this.session.removeEventListener("changeWrapMode", this.$onChangeWrapMode);
            +            this.session.removeEventListener("onChangeFold", this.$onChangeFold);
            +            this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker);
            +            this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker);
            +            this.session.removeEventListener("changeBreakpoint", this.$onChangeBreakpoint);
            +            this.session.removeEventListener("changeAnnotation", this.$onChangeAnnotation);
            +            this.session.removeEventListener("changeOverwrite", this.$onCursorChange);
            +            this.session.removeEventListener("changeScrollTop", this.$onScrollTopChange);
            +            this.session.removeEventListener("changeScrollLeft", this.$onScrollLeftChange);
            +
            +            var selection = this.session.getSelection();
            +            selection.removeEventListener("changeCursor", this.$onCursorChange);
            +            selection.removeEventListener("changeSelection", this.$onSelectionChange);
            +        }
            +
            +        this.session = session;
            +        if (session) {
            +            this.$onDocumentChange = this.onDocumentChange.bind(this);
            +            session.addEventListener("change", this.$onDocumentChange);
            +            this.renderer.setSession(session);
            +    
            +            this.$onChangeMode = this.onChangeMode.bind(this);
            +            session.addEventListener("changeMode", this.$onChangeMode);
            +    
            +            this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this);
            +            session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate);
            +    
            +            this.$onChangeTabSize = this.renderer.onChangeTabSize.bind(this.renderer);
            +            session.addEventListener("changeTabSize", this.$onChangeTabSize);
            +    
            +            this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this);
            +            session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit);
            +    
            +            this.$onChangeWrapMode = this.onChangeWrapMode.bind(this);
            +            session.addEventListener("changeWrapMode", this.$onChangeWrapMode);
            +    
            +            this.$onChangeFold = this.onChangeFold.bind(this);
            +            session.addEventListener("changeFold", this.$onChangeFold);
            +    
            +            this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this);
            +            this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker);
            +    
            +            this.$onChangeBackMarker = this.onChangeBackMarker.bind(this);
            +            this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker);
            +    
            +            this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this);
            +            this.session.addEventListener("changeBreakpoint", this.$onChangeBreakpoint);
            +    
            +            this.$onChangeAnnotation = this.onChangeAnnotation.bind(this);
            +            this.session.addEventListener("changeAnnotation", this.$onChangeAnnotation);
            +    
            +            this.$onCursorChange = this.onCursorChange.bind(this);
            +            this.session.addEventListener("changeOverwrite", this.$onCursorChange);
            +    
            +            this.$onScrollTopChange = this.onScrollTopChange.bind(this);
            +            this.session.addEventListener("changeScrollTop", this.$onScrollTopChange);
            +    
            +            this.$onScrollLeftChange = this.onScrollLeftChange.bind(this);
            +            this.session.addEventListener("changeScrollLeft", this.$onScrollLeftChange);
            +    
            +            this.selection = session.getSelection();
            +            this.selection.addEventListener("changeCursor", this.$onCursorChange);
            +    
            +            this.$onSelectionChange = this.onSelectionChange.bind(this);
            +            this.selection.addEventListener("changeSelection", this.$onSelectionChange);
            +    
            +            this.onChangeMode();
            +    
            +            this.$blockScrolling += 1;
            +            this.onCursorChange();
            +            this.$blockScrolling -= 1;
            +    
            +            this.onScrollTopChange();
            +            this.onScrollLeftChange();
            +            this.onSelectionChange();
            +            this.onChangeFrontMarker();
            +            this.onChangeBackMarker();
            +            this.onChangeBreakpoint();
            +            this.onChangeAnnotation();
            +            this.session.getUseWrapMode() && this.renderer.adjustWrapLimit();
            +            this.renderer.updateFull();
            +        }
            +
            +        this._signal("changeSession", {
            +            session: session,
            +            oldSession: oldSession
            +        });
            +        
            +        oldSession && oldSession._signal("changeEditor", {oldEditor: this});
            +        session && session._signal("changeEditor", {editor: this});
            +    };
            +    this.getSession = function() {
            +        return this.session;
            +    };
            +    this.setValue = function(val, cursorPos) {
            +        this.session.doc.setValue(val);
            +
            +        if (!cursorPos)
            +            this.selectAll();
            +        else if (cursorPos == 1)
            +            this.navigateFileEnd();
            +        else if (cursorPos == -1)
            +            this.navigateFileStart();
            +
            +        return val;
            +    };
            +    this.getValue = function() {
            +        return this.session.getValue();
            +    };
            +    this.getSelection = function() {
            +        return this.selection;
            +    };
            +    this.resize = function(force) {
            +        this.renderer.onResize(force);
            +    };
            +    this.setTheme = function(theme, cb) {
            +        this.renderer.setTheme(theme, cb);
            +    };
            +    this.getTheme = function() {
            +        return this.renderer.getTheme();
            +    };
            +    this.setStyle = function(style) {
            +        this.renderer.setStyle(style);
            +    };
            +    this.unsetStyle = function(style) {
            +        this.renderer.unsetStyle(style);
            +    };
            +    this.getFontSize = function () {
            +        return this.getOption("fontSize") ||
            +           dom.computedStyle(this.container, "fontSize");
            +    };
            +    this.setFontSize = function(size) {
            +        this.setOption("fontSize", size);
            +    };
            +
            +    this.$highlightBrackets = function() {
            +        if (this.session.$bracketHighlight) {
            +            this.session.removeMarker(this.session.$bracketHighlight);
            +            this.session.$bracketHighlight = null;
            +        }
            +
            +        if (this.$highlightPending) {
            +            return;
            +        }
            +        var self = this;
            +        this.$highlightPending = true;
            +        setTimeout(function() {
            +            self.$highlightPending = false;
            +
            +            var pos = self.session.findMatchingBracket(self.getCursorPosition());
            +            if (pos) {
            +                var range = new Range(pos.row, pos.column, pos.row, pos.column+1);
            +            } else if (self.session.$mode.getMatching) {
            +                var range = self.session.$mode.getMatching(self.session);
            +            }
            +            if (range)
            +                self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text");
            +        }, 50);
            +    };
            +    this.$highlightTags = function() {
            +        var session = this.session;
            +
            +        if (this.$highlightTagPending) {
            +            return;
            +        }
            +        var self = this;
            +        this.$highlightTagPending = true;
            +        setTimeout(function() {
            +            self.$highlightTagPending = false;
            +            
            +            var pos = self.getCursorPosition();
            +            var iterator = new TokenIterator(self.session, pos.row, pos.column);
            +            var token = iterator.getCurrentToken();
            +            
            +            if (!token || token.type.indexOf('tag-name') === -1) {
            +                session.removeMarker(session.$tagHighlight);
            +                session.$tagHighlight = null;
            +                return;
            +            }
            +
            +            var tag = token.value;
            +            var depth = 0;
            +            var prevToken = iterator.stepBackward();
            +            
            +            if (prevToken.value == '<'){
            +                do {
            +                    prevToken = token;
            +                    token = iterator.stepForward();
            +                    
            +                    if (token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
            +                        if (prevToken.value==='<'){
            +                            depth++;
            +                        } else if (prevToken.value==='</'){
            +                            depth--;
            +                        }
            +                    }
            +                    
            +                } while (token && depth>=0);
            +            }else{
            +                do {
            +                    token = prevToken;
            +                    prevToken = iterator.stepBackward();
            +                    
            +                    if(token && token.value === tag && token.type.indexOf('tag-name') !== -1) {
            +                        if (prevToken.value==='<') {
            +                            depth++;
            +                        } else if( prevToken.value==='</') {
            +                            depth--;
            +                        }
            +                    }
            +                } while (prevToken && depth<=0);
            +                iterator.stepForward();
            +            }
            +            
            +            if (!token) {
            +                session.removeMarker(session.$tagHighlight);
            +                session.$tagHighlight = null;
            +                return;
            +            }
            +            
            +            var row = iterator.getCurrentTokenRow();
            +            var column = iterator.getCurrentTokenColumn();
            +            var range = new Range(row, column, row, column+token.value.length);
            +            if (session.$tagHighlight && range.compareRange(session.$backMarkers[session.$tagHighlight].range)!==0) {
            +                session.removeMarker(session.$tagHighlight);
            +                session.$tagHighlight = null;
            +            }
            +            
            +            if (range && !session.$tagHighlight)
            +                session.$tagHighlight = session.addMarker(range, "ace_bracket", "text");
            +        }, 50);
            +    };
            +    this.focus = function() {
            +        var _self = this;
            +        setTimeout(function() {
            +            _self.textInput.focus();
            +        });
            +        this.textInput.focus();
            +    };
            +    this.isFocused = function() {
            +        return this.textInput.isFocused();
            +    };
            +    this.blur = function() {
            +        this.textInput.blur();
            +    };
            +    this.onFocus = function() {
            +        if (this.$isFocused)
            +            return;
            +        this.$isFocused = true;
            +        this.renderer.showCursor();
            +        this.renderer.visualizeFocus();
            +        this._emit("focus");
            +    };
            +    this.onBlur = function() {
            +        if (!this.$isFocused)
            +            return;
            +        this.$isFocused = false;
            +        this.renderer.hideCursor();
            +        this.renderer.visualizeBlur();
            +        this._emit("blur");
            +    };
            +
            +    this.$cursorChange = function() {
            +        this.renderer.updateCursor();
            +    };
            +    this.onDocumentChange = function(e) {
            +        var delta = e.data;
            +        var range = delta.range;
            +        var lastRow;
            +
            +        if (range.start.row == range.end.row && delta.action != "insertLines" && delta.action != "removeLines")
            +            lastRow = range.end.row;
            +        else
            +            lastRow = Infinity;
            +        this.renderer.updateLines(range.start.row, lastRow);
            +
            +        this._signal("change", e);
            +        this.$cursorChange();
            +    };
            +
            +    this.onTokenizerUpdate = function(e) {
            +        var rows = e.data;
            +        this.renderer.updateLines(rows.first, rows.last);
            +    };
            +
            +
            +    this.onScrollTopChange = function() {
            +        this.renderer.scrollToY(this.session.getScrollTop());
            +    };
            +
            +    this.onScrollLeftChange = function() {
            +        this.renderer.scrollToX(this.session.getScrollLeft());
            +    };
            +    this.onCursorChange = function() {
            +        this.$cursorChange();
            +
            +        if (!this.$blockScrolling) {
            +            this.renderer.scrollCursorIntoView();
            +        }
            +
            +        this.$highlightBrackets();
            +        this.$highlightTags();
            +        this.$updateHighlightActiveLine();
            +        this._signal("changeSelection");
            +    };
            +
            +    this.$updateHighlightActiveLine = function() {
            +        var session = this.getSession();
            +
            +        var highlight;
            +        if (this.$highlightActiveLine) {
            +            if ((this.$selectionStyle != "line" || !this.selection.isMultiLine()))
            +                highlight = this.getCursorPosition();
            +            if (this.renderer.$maxLines && this.session.getLength() === 1 && !(this.renderer.$minLines > 1))
            +                highlight = false;
            +        }
            +
            +        if (session.$highlightLineMarker && !highlight) {
            +            session.removeMarker(session.$highlightLineMarker.id);
            +            session.$highlightLineMarker = null;
            +        } else if (!session.$highlightLineMarker && highlight) {
            +            var range = new Range(highlight.row, highlight.column, highlight.row, Infinity);
            +            range.id = session.addMarker(range, "ace_active-line", "screenLine");
            +            session.$highlightLineMarker = range;
            +        } else if (highlight) {
            +            session.$highlightLineMarker.start.row = highlight.row;
            +            session.$highlightLineMarker.end.row = highlight.row;
            +            session.$highlightLineMarker.start.column = highlight.column;
            +            session._signal("changeBackMarker");
            +        }
            +    };
            +
            +    this.onSelectionChange = function(e) {
            +        var session = this.session;
            +
            +        if (session.$selectionMarker) {
            +            session.removeMarker(session.$selectionMarker);
            +        }
            +        session.$selectionMarker = null;
            +
            +        if (!this.selection.isEmpty()) {
            +            var range = this.selection.getRange();
            +            var style = this.getSelectionStyle();
            +            session.$selectionMarker = session.addMarker(range, "ace_selection", style);
            +        } else {
            +            this.$updateHighlightActiveLine();
            +        }
            +
            +        var re = this.$highlightSelectedWord && this.$getSelectionHighLightRegexp();
            +        this.session.highlight(re);
            +
            +        this._signal("changeSelection");
            +    };
            +
            +    this.$getSelectionHighLightRegexp = function() {
            +        var session = this.session;
            +
            +        var selection = this.getSelectionRange();
            +        if (selection.isEmpty() || selection.isMultiLine())
            +            return;
            +
            +        var startOuter = selection.start.column - 1;
            +        var endOuter = selection.end.column + 1;
            +        var line = session.getLine(selection.start.row);
            +        var lineCols = line.length;
            +        var needle = line.substring(Math.max(startOuter, 0),
            +                                    Math.min(endOuter, lineCols));
            +        if ((startOuter >= 0 && /^[\w\d]/.test(needle)) ||
            +            (endOuter <= lineCols && /[\w\d]$/.test(needle)))
            +            return;
            +
            +        needle = line.substring(selection.start.column, selection.end.column);
            +        if (!/^[\w\d]+$/.test(needle))
            +            return;
            +
            +        var re = this.$search.$assembleRegExp({
            +            wholeWord: true,
            +            caseSensitive: true,
            +            needle: needle
            +        });
            +
            +        return re;
            +    };
            +
            +
            +    this.onChangeFrontMarker = function() {
            +        this.renderer.updateFrontMarkers();
            +    };
            +
            +    this.onChangeBackMarker = function() {
            +        this.renderer.updateBackMarkers();
            +    };
            +
            +
            +    this.onChangeBreakpoint = function() {
            +        this.renderer.updateBreakpoints();
            +    };
            +
            +    this.onChangeAnnotation = function() {
            +        this.renderer.setAnnotations(this.session.getAnnotations());
            +    };
            +
            +
            +    this.onChangeMode = function(e) {
            +        this.renderer.updateText();
            +        this._emit("changeMode", e);
            +    };
            +
            +
            +    this.onChangeWrapLimit = function() {
            +        this.renderer.updateFull();
            +    };
            +
            +    this.onChangeWrapMode = function() {
            +        this.renderer.onResize(true);
            +    };
            +
            +
            +    this.onChangeFold = function() {
            +        this.$updateHighlightActiveLine();
            +        this.renderer.updateFull();
            +    };
            +    this.getSelectedText = function() {
            +        return this.session.getTextRange(this.getSelectionRange());
            +    };
            +    this.getCopyText = function() {
            +        var text = this.getSelectedText();
            +        this._signal("copy", text);
            +        return text;
            +    };
            +    this.onCopy = function() {
            +        this.commands.exec("copy", this);
            +    };
            +    this.onCut = function() {
            +        this.commands.exec("cut", this);
            +    };
            +    this.onPaste = function(text) {
            +        if (this.$readOnly)
            +            return;
            +        var e = {text: text};
            +        this._signal("paste", e);
            +        this.insert(e.text, true);
            +    };
            +
            +
            +    this.execCommand = function(command, args) {
            +        this.commands.exec(command, this, args);
            +    };
            +    this.insert = function(text, pasted) {
            +        var session = this.session;
            +        var mode = session.getMode();
            +        var cursor = this.getCursorPosition();
            +
            +        if (this.getBehavioursEnabled() && !pasted) {
            +            var transform = mode.transformAction(session.getState(cursor.row), 'insertion', this, session, text);
            +            if (transform) {
            +                if (text !== transform.text) {
            +                    this.session.mergeUndoDeltas = false;
            +                    this.$mergeNextCommand = false;
            +                }
            +                text = transform.text;
            +
            +            }
            +        }
            +        
            +        if (text == "\t")
            +            text = this.session.getTabString();
            +        if (!this.selection.isEmpty()) {
            +            var range = this.getSelectionRange();
            +            cursor = this.session.remove(range);
            +            this.clearSelection();
            +        }
            +        else if (this.session.getOverwrite()) {
            +            var range = new Range.fromPoints(cursor, cursor);
            +            range.end.column += text.length;
            +            this.session.remove(range);
            +        }
            +
            +        if (text == "\n" || text == "\r\n") {
            +            var line = session.getLine(cursor.row);
            +            if (cursor.column > line.search(/\S|$/)) {
            +                var d = line.substr(cursor.column).search(/\S|$/);
            +                session.doc.removeInLine(cursor.row, cursor.column, cursor.column + d);
            +            }
            +        }
            +        this.clearSelection();
            +
            +        var start = cursor.column;
            +        var lineState = session.getState(cursor.row);
            +        var line = session.getLine(cursor.row);
            +        var shouldOutdent = mode.checkOutdent(lineState, line, text);
            +        var end = session.insert(cursor, text);
            +
            +        if (transform && transform.selection) {
            +            if (transform.selection.length == 2) { // Transform relative to the current column
            +                this.selection.setSelectionRange(
            +                    new Range(cursor.row, start + transform.selection[0],
            +                              cursor.row, start + transform.selection[1]));
            +            } else { // Transform relative to the current row.
            +                this.selection.setSelectionRange(
            +                    new Range(cursor.row + transform.selection[0],
            +                              transform.selection[1],
            +                              cursor.row + transform.selection[2],
            +                              transform.selection[3]));
            +            }
            +        }
            +
            +        if (session.getDocument().isNewLine(text)) {
            +            var lineIndent = mode.getNextLineIndent(lineState, line.slice(0, cursor.column), session.getTabString());
            +
            +            session.insert({row: cursor.row+1, column: 0}, lineIndent);
            +        }
            +        if (shouldOutdent)
            +            mode.autoOutdent(lineState, session, cursor.row);
            +    };
            +
            +    this.onTextInput = function(text) {
            +        this.keyBinding.onTextInput(text);
            +    };
            +
            +    this.onCommandKey = function(e, hashId, keyCode) {
            +        this.keyBinding.onCommandKey(e, hashId, keyCode);
            +    };
            +    this.setOverwrite = function(overwrite) {
            +        this.session.setOverwrite(overwrite);
            +    };
            +    this.getOverwrite = function() {
            +        return this.session.getOverwrite();
            +    };
            +    this.toggleOverwrite = function() {
            +        this.session.toggleOverwrite();
            +    };
            +    this.setScrollSpeed = function(speed) {
            +        this.setOption("scrollSpeed", speed);
            +    };
            +    this.getScrollSpeed = function() {
            +        return this.getOption("scrollSpeed");
            +    };
            +    this.setDragDelay = function(dragDelay) {
            +        this.setOption("dragDelay", dragDelay);
            +    };
            +    this.getDragDelay = function() {
            +        return this.getOption("dragDelay");
            +    };
            +    this.setSelectionStyle = function(val) {
            +        this.setOption("selectionStyle", val);
            +    };
            +    this.getSelectionStyle = function() {
            +        return this.getOption("selectionStyle");
            +    };
            +    this.setHighlightActiveLine = function(shouldHighlight) {
            +        this.setOption("highlightActiveLine", shouldHighlight);
            +    };
            +    this.getHighlightActiveLine = function() {
            +        return this.getOption("highlightActiveLine");
            +    };
            +    this.setHighlightGutterLine = function(shouldHighlight) {
            +        this.setOption("highlightGutterLine", shouldHighlight);
            +    };
            +
            +    this.getHighlightGutterLine = function() {
            +        return this.getOption("highlightGutterLine");
            +    };
            +    this.setHighlightSelectedWord = function(shouldHighlight) {
            +        this.setOption("highlightSelectedWord", shouldHighlight);
            +    };
            +    this.getHighlightSelectedWord = function() {
            +        return this.$highlightSelectedWord;
            +    };
            +
            +    this.setAnimatedScroll = function(shouldAnimate){
            +        this.renderer.setAnimatedScroll(shouldAnimate);
            +    };
            +
            +    this.getAnimatedScroll = function(){
            +        return this.renderer.getAnimatedScroll();
            +    };
            +    this.setShowInvisibles = function(showInvisibles) {
            +        this.renderer.setShowInvisibles(showInvisibles);
            +    };
            +    this.getShowInvisibles = function() {
            +        return this.renderer.getShowInvisibles();
            +    };
            +
            +    this.setDisplayIndentGuides = function(display) {
            +        this.renderer.setDisplayIndentGuides(display);
            +    };
            +
            +    this.getDisplayIndentGuides = function() {
            +        return this.renderer.getDisplayIndentGuides();
            +    };
            +    this.setShowPrintMargin = function(showPrintMargin) {
            +        this.renderer.setShowPrintMargin(showPrintMargin);
            +    };
            +    this.getShowPrintMargin = function() {
            +        return this.renderer.getShowPrintMargin();
            +    };
            +    this.setPrintMarginColumn = function(showPrintMargin) {
            +        this.renderer.setPrintMarginColumn(showPrintMargin);
            +    };
            +    this.getPrintMarginColumn = function() {
            +        return this.renderer.getPrintMarginColumn();
            +    };
            +    this.setReadOnly = function(readOnly) {
            +        this.setOption("readOnly", readOnly);
            +    };
            +    this.getReadOnly = function() {
            +        return this.getOption("readOnly");
            +    };
            +    this.setBehavioursEnabled = function (enabled) {
            +        this.setOption("behavioursEnabled", enabled);
            +    };
            +    this.getBehavioursEnabled = function () {
            +        return this.getOption("behavioursEnabled");
            +    };
            +    this.setWrapBehavioursEnabled = function (enabled) {
            +        this.setOption("wrapBehavioursEnabled", enabled);
            +    };
            +    this.getWrapBehavioursEnabled = function () {
            +        return this.getOption("wrapBehavioursEnabled");
            +    };
            +    this.setShowFoldWidgets = function(show) {
            +        this.setOption("showFoldWidgets", show);
            +
            +    };
            +    this.getShowFoldWidgets = function() {
            +        return this.getOption("showFoldWidgets");
            +    };
            +
            +    this.setFadeFoldWidgets = function(fade) {
            +        this.setOption("fadeFoldWidgets", fade);
            +    };
            +
            +    this.getFadeFoldWidgets = function() {
            +        return this.getOption("fadeFoldWidgets");
            +    };
            +    this.remove = function(dir) {
            +        if (this.selection.isEmpty()){
            +            if (dir == "left")
            +                this.selection.selectLeft();
            +            else
            +                this.selection.selectRight();
            +        }
            +
            +        var range = this.getSelectionRange();
            +        if (this.getBehavioursEnabled()) {
            +            var session = this.session;
            +            var state = session.getState(range.start.row);
            +            var new_range = session.getMode().transformAction(state, 'deletion', this, session, range);
            +
            +            if (range.end.column === 0) {
            +                var text = session.getTextRange(range);
            +                if (text[text.length - 1] == "\n") {
            +                    var line = session.getLine(range.end.row);
            +                    if (/^\s+$/.test(line)) {
            +                        range.end.column = line.length;
            +                    }
            +                }
            +            }
            +            if (new_range)
            +                range = new_range;
            +        }
            +
            +        this.session.remove(range);
            +        this.clearSelection();
            +    };
            +    this.removeWordRight = function() {
            +        if (this.selection.isEmpty())
            +            this.selection.selectWordRight();
            +
            +        this.session.remove(this.getSelectionRange());
            +        this.clearSelection();
            +    };
            +    this.removeWordLeft = function() {
            +        if (this.selection.isEmpty())
            +            this.selection.selectWordLeft();
            +
            +        this.session.remove(this.getSelectionRange());
            +        this.clearSelection();
            +    };
            +    this.removeToLineStart = function() {
            +        if (this.selection.isEmpty())
            +            this.selection.selectLineStart();
            +
            +        this.session.remove(this.getSelectionRange());
            +        this.clearSelection();
            +    };
            +    this.removeToLineEnd = function() {
            +        if (this.selection.isEmpty())
            +            this.selection.selectLineEnd();
            +
            +        var range = this.getSelectionRange();
            +        if (range.start.column == range.end.column && range.start.row == range.end.row) {
            +            range.end.column = 0;
            +            range.end.row++;
            +        }
            +
            +        this.session.remove(range);
            +        this.clearSelection();
            +    };
            +    this.splitLine = function() {
            +        if (!this.selection.isEmpty()) {
            +            this.session.remove(this.getSelectionRange());
            +            this.clearSelection();
            +        }
            +
            +        var cursor = this.getCursorPosition();
            +        this.insert("\n");
            +        this.moveCursorToPosition(cursor);
            +    };
            +    this.transposeLetters = function() {
            +        if (!this.selection.isEmpty()) {
            +            return;
            +        }
            +
            +        var cursor = this.getCursorPosition();
            +        var column = cursor.column;
            +        if (column === 0)
            +            return;
            +
            +        var line = this.session.getLine(cursor.row);
            +        var swap, range;
            +        if (column < line.length) {
            +            swap = line.charAt(column) + line.charAt(column-1);
            +            range = new Range(cursor.row, column-1, cursor.row, column+1);
            +        }
            +        else {
            +            swap = line.charAt(column-1) + line.charAt(column-2);
            +            range = new Range(cursor.row, column-2, cursor.row, column);
            +        }
            +        this.session.replace(range, swap);
            +    };
            +    this.toLowerCase = function() {
            +        var originalRange = this.getSelectionRange();
            +        if (this.selection.isEmpty()) {
            +            this.selection.selectWord();
            +        }
            +
            +        var range = this.getSelectionRange();
            +        var text = this.session.getTextRange(range);
            +        this.session.replace(range, text.toLowerCase());
            +        this.selection.setSelectionRange(originalRange);
            +    };
            +    this.toUpperCase = function() {
            +        var originalRange = this.getSelectionRange();
            +        if (this.selection.isEmpty()) {
            +            this.selection.selectWord();
            +        }
            +
            +        var range = this.getSelectionRange();
            +        var text = this.session.getTextRange(range);
            +        this.session.replace(range, text.toUpperCase());
            +        this.selection.setSelectionRange(originalRange);
            +    };
            +    this.indent = function() {
            +        var session = this.session;
            +        var range = this.getSelectionRange();
            +
            +        if (range.start.row < range.end.row) {
            +            var rows = this.$getSelectedRows();
            +            session.indentRows(rows.first, rows.last, "\t");
            +            return;
            +        } else if (range.start.column < range.end.column) {
            +            var text = session.getTextRange(range);
            +            if (!/^\s+$/.test(text)) {
            +                var rows = this.$getSelectedRows();
            +                session.indentRows(rows.first, rows.last, "\t");
            +                return;
            +            }
            +        }
            +        
            +        var line = session.getLine(range.start.row);
            +        var position = range.start;
            +        var size = session.getTabSize();
            +        var column = session.documentToScreenColumn(position.row, position.column);
            +
            +        if (this.session.getUseSoftTabs()) {
            +            var count = (size - column % size);
            +            var indentString = lang.stringRepeat(" ", count);
            +        } else {
            +            var count = column % size;
            +            while (line[range.start.column] == " " && count) {
            +                range.start.column--;
            +                count--;
            +            }
            +            this.selection.setSelectionRange(range);
            +            indentString = "\t";
            +        }
            +        return this.insert(indentString);
            +    };
            +    this.blockIndent = function() {
            +        var rows = this.$getSelectedRows();
            +        this.session.indentRows(rows.first, rows.last, "\t");
            +    };
            +    this.blockOutdent = function() {
            +        var selection = this.session.getSelection();
            +        this.session.outdentRows(selection.getRange());
            +    };
            +    this.sortLines = function() {
            +        var rows = this.$getSelectedRows();
            +        var session = this.session;
            +
            +        var lines = [];
            +        for (i = rows.first; i <= rows.last; i++)
            +            lines.push(session.getLine(i));
            +
            +        lines.sort(function(a, b) {
            +            if (a.toLowerCase() < b.toLowerCase()) return -1;
            +            if (a.toLowerCase() > b.toLowerCase()) return 1;
            +            return 0;
            +        });
            +
            +        var deleteRange = new Range(0, 0, 0, 0);
            +        for (var i = rows.first; i <= rows.last; i++) {
            +            var line = session.getLine(i);
            +            deleteRange.start.row = i;
            +            deleteRange.end.row = i;
            +            deleteRange.end.column = line.length;
            +            session.replace(deleteRange, lines[i-rows.first]);
            +        }
            +    };
            +    this.toggleCommentLines = function() {
            +        var state = this.session.getState(this.getCursorPosition().row);
            +        var rows = this.$getSelectedRows();
            +        this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
            +    };
            +
            +    this.toggleBlockComment = function() {
            +        var cursor = this.getCursorPosition();
            +        var state = this.session.getState(cursor.row);
            +        var range = this.getSelectionRange();
            +        this.session.getMode().toggleBlockComment(state, this.session, range, cursor);
            +    };
            +    this.getNumberAt = function(row, column) {
            +        var _numberRx = /[\-]?[0-9]+(?:\.[0-9]+)?/g;
            +        _numberRx.lastIndex = 0;
            +
            +        var s = this.session.getLine(row);
            +        while (_numberRx.lastIndex < column) {
            +            var m = _numberRx.exec(s);
            +            if(m.index <= column && m.index+m[0].length >= column){
            +                var number = {
            +                    value: m[0],
            +                    start: m.index,
            +                    end: m.index+m[0].length
            +                };
            +                return number;
            +            }
            +        }
            +        return null;
            +    };
            +    this.modifyNumber = function(amount) {
            +        var row = this.selection.getCursor().row;
            +        var column = this.selection.getCursor().column;
            +        var charRange = new Range(row, column-1, row, column);
            +
            +        var c = this.session.getTextRange(charRange);
            +        if (!isNaN(parseFloat(c)) && isFinite(c)) {
            +            var nr = this.getNumberAt(row, column);
            +            if (nr) {
            +                var fp = nr.value.indexOf(".") >= 0 ? nr.start + nr.value.indexOf(".") + 1 : nr.end;
            +                var decimals = nr.start + nr.value.length - fp;
            +
            +                var t = parseFloat(nr.value);
            +                t *= Math.pow(10, decimals);
            +
            +
            +                if(fp !== nr.end && column < fp){
            +                    amount *= Math.pow(10, nr.end - column - 1);
            +                } else {
            +                    amount *= Math.pow(10, nr.end - column);
            +                }
            +
            +                t += amount;
            +                t /= Math.pow(10, decimals);
            +                var nnr = t.toFixed(decimals);
            +                var replaceRange = new Range(row, nr.start, row, nr.end);
            +                this.session.replace(replaceRange, nnr);
            +                this.moveCursorTo(row, Math.max(nr.start +1, column + nnr.length - nr.value.length));
            +
            +            }
            +        }
            +    };
            +    this.removeLines = function() {
            +        var rows = this.$getSelectedRows();
            +        var range;
            +        if (rows.first === 0 || rows.last+1 < this.session.getLength())
            +            range = new Range(rows.first, 0, rows.last+1, 0);
            +        else
            +            range = new Range(
            +                rows.first-1, this.session.getLine(rows.first-1).length,
            +                rows.last, this.session.getLine(rows.last).length
            +            );
            +        this.session.remove(range);
            +        this.clearSelection();
            +    };
            +
            +    this.duplicateSelection = function() {
            +        var sel = this.selection;
            +        var doc = this.session;
            +        var range = sel.getRange();
            +        var reverse = sel.isBackwards();
            +        if (range.isEmpty()) {
            +            var row = range.start.row;
            +            doc.duplicateLines(row, row);
            +        } else {
            +            var point = reverse ? range.start : range.end;
            +            var endPoint = doc.insert(point, doc.getTextRange(range), false);
            +            range.start = point;
            +            range.end = endPoint;
            +
            +            sel.setSelectionRange(range, reverse);
            +        }
            +    };
            +    this.moveLinesDown = function() {
            +        this.$moveLines(function(firstRow, lastRow) {
            +            return this.session.moveLinesDown(firstRow, lastRow);
            +        });
            +    };
            +    this.moveLinesUp = function() {
            +        this.$moveLines(function(firstRow, lastRow) {
            +            return this.session.moveLinesUp(firstRow, lastRow);
            +        });
            +    };
            +    this.moveText = function(range, toPosition, copy) {
            +        return this.session.moveText(range, toPosition, copy);
            +    };
            +    this.copyLinesUp = function() {
            +        this.$moveLines(function(firstRow, lastRow) {
            +            this.session.duplicateLines(firstRow, lastRow);
            +            return 0;
            +        });
            +    };
            +    this.copyLinesDown = function() {
            +        this.$moveLines(function(firstRow, lastRow) {
            +            return this.session.duplicateLines(firstRow, lastRow);
            +        });
            +    };
            +    this.$moveLines = function(mover) {
            +        var selection = this.selection;
            +        if (!selection.inMultiSelectMode || this.inVirtualSelectionMode) {
            +            var range = selection.toOrientedRange();
            +            var rows = this.$getSelectedRows(range);
            +            var linesMoved = mover.call(this, rows.first, rows.last);
            +            range.moveBy(linesMoved, 0);
            +            selection.fromOrientedRange(range);
            +        } else {
            +            var ranges = selection.rangeList.ranges;
            +            selection.rangeList.detach(this.session);
            +
            +            for (var i = ranges.length; i--; ) {
            +                var rangeIndex = i;
            +                var rows = ranges[i].collapseRows();
            +                var last = rows.end.row;
            +                var first = rows.start.row;
            +                while (i--) {
            +                    rows = ranges[i].collapseRows();
            +                    if (first - rows.end.row <= 1)
            +                        first = rows.end.row;
            +                    else
            +                        break;
            +                }
            +                i++;
            +
            +                var linesMoved = mover.call(this, first, last);
            +                while (rangeIndex >= i) {
            +                    ranges[rangeIndex].moveBy(linesMoved, 0);
            +                    rangeIndex--;
            +                }
            +            }
            +            selection.fromOrientedRange(selection.ranges[0]);
            +            selection.rangeList.attach(this.session);
            +        }
            +    };
            +    this.$getSelectedRows = function() {
            +        var range = this.getSelectionRange().collapseRows();
            +
            +        return {
            +            first: this.session.getRowFoldStart(range.start.row),
            +            last: this.session.getRowFoldEnd(range.end.row)
            +        };
            +    };
            +
            +    this.onCompositionStart = function(text) {
            +        this.renderer.showComposition(this.getCursorPosition());
            +    };
            +
            +    this.onCompositionUpdate = function(text) {
            +        this.renderer.setCompositionText(text);
            +    };
            +
            +    this.onCompositionEnd = function() {
            +        this.renderer.hideComposition();
            +    };
            +    this.getFirstVisibleRow = function() {
            +        return this.renderer.getFirstVisibleRow();
            +    };
            +    this.getLastVisibleRow = function() {
            +        return this.renderer.getLastVisibleRow();
            +    };
            +    this.isRowVisible = function(row) {
            +        return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
            +    };
            +    this.isRowFullyVisible = function(row) {
            +        return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
            +    };
            +    this.$getVisibleRowCount = function() {
            +        return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
            +    };
            +
            +    this.$moveByPage = function(dir, select) {
            +        var renderer = this.renderer;
            +        var config = this.renderer.layerConfig;
            +        var rows = dir * Math.floor(config.height / config.lineHeight);
            +
            +        this.$blockScrolling++;
            +        if (select === true) {
            +            this.selection.$moveSelection(function(){
            +                this.moveCursorBy(rows, 0);
            +            });
            +        } else if (select === false) {
            +            this.selection.moveCursorBy(rows, 0);
            +            this.selection.clearSelection();
            +        }
            +        this.$blockScrolling--;
            +
            +        var scrollTop = renderer.scrollTop;
            +
            +        renderer.scrollBy(0, rows * config.lineHeight);
            +        if (select != null)
            +            renderer.scrollCursorIntoView(null, 0.5);
            +
            +        renderer.animateScrolling(scrollTop);
            +    };
            +    this.selectPageDown = function() {
            +        this.$moveByPage(1, true);
            +    };
            +    this.selectPageUp = function() {
            +        this.$moveByPage(-1, true);
            +    };
            +    this.gotoPageDown = function() {
            +       this.$moveByPage(1, false);
            +    };
            +    this.gotoPageUp = function() {
            +        this.$moveByPage(-1, false);
            +    };
            +    this.scrollPageDown = function() {
            +        this.$moveByPage(1);
            +    };
            +    this.scrollPageUp = function() {
            +        this.$moveByPage(-1);
            +    };
            +    this.scrollToRow = function(row) {
            +        this.renderer.scrollToRow(row);
            +    };
            +    this.scrollToLine = function(line, center, animate, callback) {
            +        this.renderer.scrollToLine(line, center, animate, callback);
            +    };
            +    this.centerSelection = function() {
            +        var range = this.getSelectionRange();
            +        var pos = {
            +            row: Math.floor(range.start.row + (range.end.row - range.start.row) / 2),
            +            column: Math.floor(range.start.column + (range.end.column - range.start.column) / 2)
            +        };
            +        this.renderer.alignCursor(pos, 0.5);
            +    };
            +    this.getCursorPosition = function() {
            +        return this.selection.getCursor();
            +    };
            +    this.getCursorPositionScreen = function() {
            +        return this.session.documentToScreenPosition(this.getCursorPosition());
            +    };
            +    this.getSelectionRange = function() {
            +        return this.selection.getRange();
            +    };
            +    this.selectAll = function() {
            +        this.$blockScrolling += 1;
            +        this.selection.selectAll();
            +        this.$blockScrolling -= 1;
            +    };
            +    this.clearSelection = function() {
            +        this.selection.clearSelection();
            +    };
            +    this.moveCursorTo = function(row, column) {
            +        this.selection.moveCursorTo(row, column);
            +    };
            +    this.moveCursorToPosition = function(pos) {
            +        this.selection.moveCursorToPosition(pos);
            +    };
            +    this.jumpToMatching = function(select) {
            +        var cursor = this.getCursorPosition();
            +        var iterator = new TokenIterator(this.session, cursor.row, cursor.column);
            +        var prevToken = iterator.getCurrentToken();
            +        var token = prevToken;
            +
            +        if (!token)
            +            token = iterator.stepForward();
            +
            +        if (!token)
            +            return;
            +        var matchType;
            +        var found = false;
            +        var depth = {};
            +        var i = cursor.column - token.start;
            +        var bracketType;
            +        var brackets = {
            +            ")": "(",
            +            "(": "(",
            +            "]": "[",
            +            "[": "[",
            +            "{": "{",
            +            "}": "{"
            +        };
            +        
            +        do {
            +            if (token.value.match(/[{}()\[\]]/g)) {
            +                for (; i<token.value.length && !found; i++) {
            +                    if (!brackets[token.value[i]]) {
            +                        continue;
            +                    }
            +
            +                    bracketType = brackets[token.value[i]]+'.'+token.type.replace("rparen", "lparen");
            +
            +                    if (isNaN(depth[bracketType])) {
            +                        depth[bracketType] = 0;
            +                    }
            +
            +                    switch (token.value[i]) {
            +                        case '(':
            +                        case '[':
            +                        case '{':
            +                            depth[bracketType]++;
            +                        break;
            +                        case ')':
            +                        case ']':
            +                        case '}':
            +                            depth[bracketType]--;
            +                            
            +                            if (depth[bracketType]===-1) {
            +                                matchType = 'bracket';
            +                                found = true;
            +                            }
            +                        break;
            +                    }
            +                }
            +            } else if (token && token.type.indexOf('tag-name') !== -1) {
            +                if (isNaN(depth[token.value])) {
            +                    depth[token.value] = 0;
            +                }
            +                
            +                if (prevToken.value === '<') {
            +                    depth[token.value]++;
            +                } else if (prevToken.value === '</') {
            +                    depth[token.value]--;
            +                }
            +                
            +                if (depth[token.value] === -1) {
            +                    matchType = 'tag';
            +                    found = true;
            +                }
            +            }
            +
            +            if (!found) {
            +                prevToken = token;
            +                token = iterator.stepForward();
            +                i = 0;
            +            }
            +        } while (token && !found);
            +        if (!matchType) {
            +            return;
            +        }
            +
            +        var range;
            +        if (matchType==='bracket') {
            +            range = this.session.getBracketRange(cursor);
            +            if (!range) {
            +                range = new Range(
            +                    iterator.getCurrentTokenRow(), 
            +                    iterator.getCurrentTokenColumn()+i-1,
            +                    iterator.getCurrentTokenRow(), 
            +                    iterator.getCurrentTokenColumn()+i-1
            +                );
            +                if (!range)
            +                    return;
            +                var pos = range.start;
            +                if (pos.row === cursor.row && Math.abs(pos.column - cursor.column) < 2)
            +                    range = this.session.getBracketRange(pos);
            +            }
            +        } else if(matchType==='tag') {
            +            if (token && token.type.indexOf('tag-name') !== -1)
            +                var tag = token.value;
            +            else
            +                return;
            +
            +            var range = new Range(
            +                iterator.getCurrentTokenRow(), 
            +                iterator.getCurrentTokenColumn()-2, 
            +                iterator.getCurrentTokenRow(), 
            +                iterator.getCurrentTokenColumn()-2
            +            );
            +            if (range.compare(cursor.row, cursor.column) === 0) {
            +                found = false;
            +                do {
            +                    token = prevToken;
            +                    prevToken = iterator.stepBackward();
            +                    
            +                    if (prevToken) {
            +                        if (prevToken.type.indexOf('tag-close') !== -1) {
            +                            range.setEnd(iterator.getCurrentTokenRow(), iterator.getCurrentTokenColumn()+1);
            +                        }
            +
            +                        if (token.value === tag && token.type.indexOf('tag-name') !== -1) {
            +                            if (prevToken.value === '<') {
            +                                depth[tag]++;
            +                            } else if ( prevToken.value === '</') {
            +                                depth[tag]--;
            +                            }
            +                            
            +                            if (depth[tag]===0)
            +                                found = true;
            +                        }
            +                    }
            +                } while (prevToken && !found);
            +            }
            +            if (token && token.type.indexOf('tag-name')) {
            +                var pos = range.start;
            +                if (pos.row == cursor.row && Math.abs(pos.column - cursor.column) < 2)
            +                    pos = range.end;
            +            }
            +        }
            +
            +        pos = range && range.cursor || pos;
            +        if (pos) {
            +            if (select) {
            +                if (range && range.isEqual(this.getSelectionRange()))
            +                    this.clearSelection();
            +                else
            +                    this.selection.selectTo(pos.row, pos.column);
            +            } else {
            +                this.selection.moveTo(pos.row, pos.column);
            +            }
            +        }
            +    };
            +    this.gotoLine = function(lineNumber, column, animate) {
            +        this.selection.clearSelection();
            +        this.session.unfold({row: lineNumber - 1, column: column || 0});
            +
            +        this.$blockScrolling += 1;
            +        this.exitMultiSelectMode && this.exitMultiSelectMode();
            +        this.moveCursorTo(lineNumber - 1, column || 0);
            +        this.$blockScrolling -= 1;
            +
            +        if (!this.isRowFullyVisible(lineNumber - 1))
            +            this.scrollToLine(lineNumber - 1, true, animate);
            +    };
            +    this.navigateTo = function(row, column) {
            +        this.selection.moveTo(row, column);
            +    };
            +    this.navigateUp = function(times) {
            +        if (this.selection.isMultiLine() && !this.selection.isBackwards()) {
            +            var selectionStart = this.selection.anchor.getPosition();
            +            return this.moveCursorToPosition(selectionStart);
            +        }
            +        this.selection.clearSelection();
            +        this.selection.moveCursorBy(-times || -1, 0);
            +    };
            +    this.navigateDown = function(times) {
            +        if (this.selection.isMultiLine() && this.selection.isBackwards()) {
            +            var selectionEnd = this.selection.anchor.getPosition();
            +            return this.moveCursorToPosition(selectionEnd);
            +        }
            +        this.selection.clearSelection();
            +        this.selection.moveCursorBy(times || 1, 0);
            +    };
            +    this.navigateLeft = function(times) {
            +        if (!this.selection.isEmpty()) {
            +            var selectionStart = this.getSelectionRange().start;
            +            this.moveCursorToPosition(selectionStart);
            +        }
            +        else {
            +            times = times || 1;
            +            while (times--) {
            +                this.selection.moveCursorLeft();
            +            }
            +        }
            +        this.clearSelection();
            +    };
            +    this.navigateRight = function(times) {
            +        if (!this.selection.isEmpty()) {
            +            var selectionEnd = this.getSelectionRange().end;
            +            this.moveCursorToPosition(selectionEnd);
            +        }
            +        else {
            +            times = times || 1;
            +            while (times--) {
            +                this.selection.moveCursorRight();
            +            }
            +        }
            +        this.clearSelection();
            +    };
            +    this.navigateLineStart = function() {
            +        this.selection.moveCursorLineStart();
            +        this.clearSelection();
            +    };
            +    this.navigateLineEnd = function() {
            +        this.selection.moveCursorLineEnd();
            +        this.clearSelection();
            +    };
            +    this.navigateFileEnd = function() {
            +        this.selection.moveCursorFileEnd();
            +        this.clearSelection();
            +    };
            +    this.navigateFileStart = function() {
            +        this.selection.moveCursorFileStart();
            +        this.clearSelection();
            +    };
            +    this.navigateWordRight = function() {
            +        this.selection.moveCursorWordRight();
            +        this.clearSelection();
            +    };
            +    this.navigateWordLeft = function() {
            +        this.selection.moveCursorWordLeft();
            +        this.clearSelection();
            +    };
            +    this.replace = function(replacement, options) {
            +        if (options)
            +            this.$search.set(options);
            +
            +        var range = this.$search.find(this.session);
            +        var replaced = 0;
            +        if (!range)
            +            return replaced;
            +
            +        if (this.$tryReplace(range, replacement)) {
            +            replaced = 1;
            +        }
            +        if (range !== null) {
            +            this.selection.setSelectionRange(range);
            +            this.renderer.scrollSelectionIntoView(range.start, range.end);
            +        }
            +
            +        return replaced;
            +    };
            +    this.replaceAll = function(replacement, options) {
            +        if (options) {
            +            this.$search.set(options);
            +        }
            +
            +        var ranges = this.$search.findAll(this.session);
            +        var replaced = 0;
            +        if (!ranges.length)
            +            return replaced;
            +
            +        this.$blockScrolling += 1;
            +
            +        var selection = this.getSelectionRange();
            +        this.selection.moveTo(0, 0);
            +
            +        for (var i = ranges.length - 1; i >= 0; --i) {
            +            if(this.$tryReplace(ranges[i], replacement)) {
            +                replaced++;
            +            }
            +        }
            +
            +        this.selection.setSelectionRange(selection);
            +        this.$blockScrolling -= 1;
            +
            +        return replaced;
            +    };
            +
            +    this.$tryReplace = function(range, replacement) {
            +        var input = this.session.getTextRange(range);
            +        replacement = this.$search.replace(input, replacement);
            +        if (replacement !== null) {
            +            range.end = this.session.replace(range, replacement);
            +            return range;
            +        } else {
            +            return null;
            +        }
            +    };
            +    this.getLastSearchOptions = function() {
            +        return this.$search.getOptions();
            +    };
            +    this.find = function(needle, options, animate) {
            +        if (!options)
            +            options = {};
            +
            +        if (typeof needle == "string" || needle instanceof RegExp)
            +            options.needle = needle;
            +        else if (typeof needle == "object")
            +            oop.mixin(options, needle);
            +
            +        var range = this.selection.getRange();
            +        if (options.needle == null) {
            +            needle = this.session.getTextRange(range)
            +                || this.$search.$options.needle;
            +            if (!needle) {
            +                range = this.session.getWordRange(range.start.row, range.start.column);
            +                needle = this.session.getTextRange(range);
            +            }
            +            this.$search.set({needle: needle});
            +        }
            +
            +        this.$search.set(options);
            +        if (!options.start)
            +            this.$search.set({start: range});
            +
            +        var newRange = this.$search.find(this.session);
            +        if (options.preventScroll)
            +            return newRange;
            +        if (newRange) {
            +            this.revealRange(newRange, animate);
            +            return newRange;
            +        }
            +        if (options.backwards)
            +            range.start = range.end;
            +        else
            +            range.end = range.start;
            +        this.selection.setRange(range);
            +    };
            +    this.findNext = function(options, animate) {
            +        this.find({skipCurrent: true, backwards: false}, options, animate);
            +    };
            +    this.findPrevious = function(options, animate) {
            +        this.find(options, {skipCurrent: true, backwards: true}, animate);
            +    };
            +
            +    this.revealRange = function(range, animate) {
            +        this.$blockScrolling += 1;
            +        this.session.unfold(range);
            +        this.selection.setSelectionRange(range);
            +        this.$blockScrolling -= 1;
            +
            +        var scrollTop = this.renderer.scrollTop;
            +        this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
            +        if (animate !== false)
            +            this.renderer.animateScrolling(scrollTop);
            +    };
            +    this.undo = function() {
            +        this.$blockScrolling++;
            +        this.session.getUndoManager().undo();
            +        this.$blockScrolling--;
            +        this.renderer.scrollCursorIntoView(null, 0.5);
            +    };
            +    this.redo = function() {
            +        this.$blockScrolling++;
            +        this.session.getUndoManager().redo();
            +        this.$blockScrolling--;
            +        this.renderer.scrollCursorIntoView(null, 0.5);
            +    };
            +    this.destroy = function() {
            +        this.renderer.destroy();
            +        this._signal("destroy", this);
            +    };
            +    this.setAutoScrollEditorIntoView = function(enable) {
            +        if (!enable)
            +            return;
            +        var rect;
            +        var self = this;
            +        var shouldScroll = false;
            +        if (!this.$scrollAnchor)
            +            this.$scrollAnchor = document.createElement("div");
            +        var scrollAnchor = this.$scrollAnchor;
            +        scrollAnchor.style.cssText = "position:absolute";
            +        this.container.insertBefore(scrollAnchor, this.container.firstChild);
            +        var onChangeSelection = this.on("changeSelection", function() {
            +            shouldScroll = true;
            +        });
            +        var onBeforeRender = this.renderer.on("beforeRender", function() {
            +            if (shouldScroll)
            +                rect = self.renderer.container.getBoundingClientRect();
            +        });
            +        var onAfterRender = this.renderer.on("afterRender", function() {
            +            if (shouldScroll && rect && self.isFocused()) {
            +                var renderer = self.renderer;
            +                var pos = renderer.$cursorLayer.$pixelPos;
            +                var config = renderer.layerConfig;
            +                var top = pos.top - config.offset;
            +                if (pos.top >= 0 && top + rect.top < 0) {
            +                    shouldScroll = true;
            +                } else if (pos.top < config.height &&
            +                    pos.top + rect.top + config.lineHeight > window.innerHeight) {
            +                    shouldScroll = false;
            +                } else {
            +                    shouldScroll = null;
            +                }
            +                if (shouldScroll != null) {
            +                    scrollAnchor.style.top = top + "px";
            +                    scrollAnchor.style.left = pos.left + "px";
            +                    scrollAnchor.style.height = config.lineHeight + "px";
            +                    scrollAnchor.scrollIntoView(shouldScroll);
            +                }
            +                shouldScroll = rect = null;
            +            }
            +        });
            +        this.setAutoScrollEditorIntoView = function(enable) {
            +            if (enable)
            +                return;
            +            delete this.setAutoScrollEditorIntoView;
            +            this.removeEventListener("changeSelection", onChangeSelection);
            +            this.renderer.removeEventListener("afterRender", onAfterRender);
            +            this.renderer.removeEventListener("beforeRender", onBeforeRender);
            +        };
            +    };
            +
            +
            +    this.$resetCursorStyle = function() {
            +        var style = this.$cursorStyle || "ace";
            +        var cursorLayer = this.renderer.$cursorLayer;
            +        if (!cursorLayer)
            +            return;
            +        cursorLayer.setSmoothBlinking(/smooth/.test(style));
            +        cursorLayer.isBlinking = !this.$readOnly && style != "wide";
            +        dom.setCssClass(cursorLayer.element, "ace_slim-cursors", /slim/.test(style));
            +    };
            +
            +}).call(Editor.prototype);
            +
            +
            +
            +config.defineOptions(Editor.prototype, "editor", {
            +    selectionStyle: {
            +        set: function(style) {
            +            this.onSelectionChange();
            +            this._signal("changeSelectionStyle", {data: style});
            +        },
            +        initialValue: "line"
            +    },
            +    highlightActiveLine: {
            +        set: function() {this.$updateHighlightActiveLine();},
            +        initialValue: true
            +    },
            +    highlightSelectedWord: {
            +        set: function(shouldHighlight) {this.$onSelectionChange();},
            +        initialValue: true
            +    },
            +    readOnly: {
            +        set: function(readOnly) {
            +            this.$resetCursorStyle(); 
            +        },
            +        initialValue: false
            +    },
            +    cursorStyle: {
            +        set: function(val) { this.$resetCursorStyle(); },
            +        values: ["ace", "slim", "smooth", "wide"],
            +        initialValue: "ace"
            +    },
            +    mergeUndoDeltas: {
            +        values: [false, true, "always"],
            +        initialValue: true
            +    },
            +    behavioursEnabled: {initialValue: true},
            +    wrapBehavioursEnabled: {initialValue: true},
            +    autoScrollEditorIntoView: {
            +        set: function(val) {this.setAutoScrollEditorIntoView(val)}
            +    },
            +
            +    hScrollBarAlwaysVisible: "renderer",
            +    vScrollBarAlwaysVisible: "renderer",
            +    highlightGutterLine: "renderer",
            +    animatedScroll: "renderer",
            +    showInvisibles: "renderer",
            +    showPrintMargin: "renderer",
            +    printMarginColumn: "renderer",
            +    printMargin: "renderer",
            +    fadeFoldWidgets: "renderer",
            +    showFoldWidgets: "renderer",
            +    showLineNumbers: "renderer",
            +    showGutter: "renderer",
            +    displayIndentGuides: "renderer",
            +    fontSize: "renderer",
            +    fontFamily: "renderer",
            +    maxLines: "renderer",
            +    minLines: "renderer",
            +    scrollPastEnd: "renderer",
            +    fixedWidthGutter: "renderer",
            +    theme: "renderer",
            +
            +    scrollSpeed: "$mouseHandler",
            +    dragDelay: "$mouseHandler",
            +    dragEnabled: "$mouseHandler",
            +    focusTimout: "$mouseHandler",
            +    tooltipFollowsMouse: "$mouseHandler",
            +
            +    firstLineNumber: "session",
            +    overwrite: "session",
            +    newLineMode: "session",
            +    useWorker: "session",
            +    useSoftTabs: "session",
            +    tabSize: "session",
            +    wrap: "session",
            +    foldStyle: "session",
            +    mode: "session"
            +});
            +
            +exports.Editor = Editor;
            +});
            +
            +define("ace/undomanager",["require","exports","module"], function(require, exports, module) {
            +"use strict";
            +var UndoManager = function() {
            +    this.reset();
            +};
            +
            +(function() {
            +    this.execute = function(options) {
            +        var deltas = options.args[0];
            +        this.$doc  = options.args[1];
            +        if (options.merge && this.hasUndo()){
            +            this.dirtyCounter--;
            +            deltas = this.$undoStack.pop().concat(deltas);
            +        }
            +        this.$undoStack.push(deltas);
            +        this.$redoStack = [];
            +
            +        if (this.dirtyCounter < 0) {
            +            this.dirtyCounter = NaN;
            +        }
            +        this.dirtyCounter++;
            +    };
            +    this.undo = function(dontSelect) {
            +        var deltas = this.$undoStack.pop();
            +        var undoSelectionRange = null;
            +        if (deltas) {
            +            undoSelectionRange =
            +                this.$doc.undoChanges(deltas, dontSelect);
            +            this.$redoStack.push(deltas);
            +            this.dirtyCounter--;
            +        }
            +
            +        return undoSelectionRange;
            +    };
            +    this.redo = function(dontSelect) {
            +        var deltas = this.$redoStack.pop();
            +        var redoSelectionRange = null;
            +        if (deltas) {
            +            redoSelectionRange =
            +                this.$doc.redoChanges(deltas, dontSelect);
            +            this.$undoStack.push(deltas);
            +            this.dirtyCounter++;
            +        }
            +
            +        return redoSelectionRange;
            +    };
            +    this.reset = function() {
            +        this.$undoStack = [];
            +        this.$redoStack = [];
            +        this.dirtyCounter = 0;
            +    };
            +    this.hasUndo = function() {
            +        return this.$undoStack.length > 0;
            +    };
            +    this.hasRedo = function() {
            +        return this.$redoStack.length > 0;
            +    };
            +    this.markClean = function() {
            +        this.dirtyCounter = 0;
            +    };
            +    this.isClean = function() {
            +        return this.dirtyCounter === 0;
            +    };
            +
            +}).call(UndoManager.prototype);
            +
            +exports.UndoManager = UndoManager;
            +});
            +
            +define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/lang","ace/lib/event_emitter"], function(require, exports, module) {
            +"use strict";
            +
            +var dom = require("../lib/dom");
            +var oop = require("../lib/oop");
            +var lang = require("../lib/lang");
            +var EventEmitter = require("../lib/event_emitter").EventEmitter;
            +
            +var Gutter = function(parentEl) {
            +    this.element = dom.createElement("div");
            +    this.element.className = "ace_layer ace_gutter-layer";
            +    parentEl.appendChild(this.element);
            +    this.setShowFoldWidgets(this.$showFoldWidgets);
            +    
            +    this.gutterWidth = 0;
            +
            +    this.$annotations = [];
            +    this.$updateAnnotations = this.$updateAnnotations.bind(this);
            +
            +    this.$cells = [];
            +};
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +
            +    this.setSession = function(session) {
            +        if (this.session)
            +            this.session.removeEventListener("change", this.$updateAnnotations);
            +        this.session = session;
            +        session.on("change", this.$updateAnnotations);
            +    };
            +
            +    this.addGutterDecoration = function(row, className){
            +        if (window.console)
            +            console.warn && console.warn("deprecated use session.addGutterDecoration");
            +        this.session.addGutterDecoration(row, className);
            +    };
            +
            +    this.removeGutterDecoration = function(row, className){
            +        if (window.console)
            +            console.warn && console.warn("deprecated use session.removeGutterDecoration");
            +        this.session.removeGutterDecoration(row, className);
            +    };
            +
            +    this.setAnnotations = function(annotations) {
            +        this.$annotations = [];
            +        for (var i = 0; i < annotations.length; i++) {
            +            var annotation = annotations[i];
            +            var row = annotation.row;
            +            var rowInfo = this.$annotations[row];
            +            if (!rowInfo)
            +                rowInfo = this.$annotations[row] = {text: []};
            +           
            +            var annoText = annotation.text;
            +            annoText = annoText ? lang.escapeHTML(annoText) : annotation.html || "";
            +
            +            if (rowInfo.text.indexOf(annoText) === -1)
            +                rowInfo.text.push(annoText);
            +
            +            var type = annotation.type;
            +            if (type == "error")
            +                rowInfo.className = " ace_error";
            +            else if (type == "warning" && rowInfo.className != " ace_error")
            +                rowInfo.className = " ace_warning";
            +            else if (type == "info" && (!rowInfo.className))
            +                rowInfo.className = " ace_info";
            +        }
            +    };
            +
            +    this.$updateAnnotations = function (e) {
            +        if (!this.$annotations.length)
            +            return;
            +        var delta = e.data;
            +        var range = delta.range;
            +        var firstRow = range.start.row;
            +        var len = range.end.row - firstRow;
            +        if (len === 0) {
            +        } else if (delta.action == "removeText" || delta.action == "removeLines") {
            +            this.$annotations.splice(firstRow, len + 1, null);
            +        } else {
            +            var args = new Array(len + 1);
            +            args.unshift(firstRow, 1);
            +            this.$annotations.splice.apply(this.$annotations, args);
            +        }
            +    };
            +
            +    this.update = function(config) {
            +        var session = this.session;
            +        var firstRow = config.firstRow;
            +        var lastRow = Math.min(config.lastRow + config.gutterOffset,  // needed to compensate for hor scollbar
            +            session.getLength() - 1);
            +        var fold = session.getNextFoldLine(firstRow);
            +        var foldStart = fold ? fold.start.row : Infinity;
            +        var foldWidgets = this.$showFoldWidgets && session.foldWidgets;
            +        var breakpoints = session.$breakpoints;
            +        var decorations = session.$decorations;
            +        var firstLineNumber = session.$firstLineNumber;
            +        var lastLineNumber = 0;
            +        
            +        var gutterRenderer = session.gutterRenderer || this.$renderer;
            +
            +        var cell = null;
            +        var index = -1;
            +        var row = firstRow;
            +        while (true) {
            +            if (row > foldStart) {
            +                row = fold.end.row + 1;
            +                fold = session.getNextFoldLine(row, fold);
            +                foldStart = fold ? fold.start.row : Infinity;
            +            }
            +            if (row > lastRow) {
            +                while (this.$cells.length > index + 1) {
            +                    cell = this.$cells.pop();
            +                    this.element.removeChild(cell.element);
            +                }
            +                break;
            +            }
            +
            +            cell = this.$cells[++index];
            +            if (!cell) {
            +                cell = {element: null, textNode: null, foldWidget: null};
            +                cell.element = dom.createElement("div");
            +                cell.textNode = document.createTextNode('');
            +                cell.element.appendChild(cell.textNode);
            +                this.element.appendChild(cell.element);
            +                this.$cells[index] = cell;
            +            }
            +
            +            var className = "ace_gutter-cell ";
            +            if (breakpoints[row])
            +                className += breakpoints[row];
            +            if (decorations[row])
            +                className += decorations[row];
            +            if (this.$annotations[row])
            +                className += this.$annotations[row].className;
            +            if (cell.element.className != className)
            +                cell.element.className = className;
            +
            +            var height = session.getRowLength(row) * config.lineHeight + "px";
            +            if (height != cell.element.style.height)
            +                cell.element.style.height = height;
            +
            +            if (foldWidgets) {
            +                var c = foldWidgets[row];
            +                if (c == null)
            +                    c = foldWidgets[row] = session.getFoldWidget(row);
            +            }
            +
            +            if (c) {
            +                if (!cell.foldWidget) {
            +                    cell.foldWidget = dom.createElement("span");
            +                    cell.element.appendChild(cell.foldWidget);
            +                }
            +                var className = "ace_fold-widget ace_" + c;
            +                if (c == "start" && row == foldStart && row < fold.end.row)
            +                    className += " ace_closed";
            +                else
            +                    className += " ace_open";
            +                if (cell.foldWidget.className != className)
            +                    cell.foldWidget.className = className;
            +
            +                var height = config.lineHeight + "px";
            +                if (cell.foldWidget.style.height != height)
            +                    cell.foldWidget.style.height = height;
            +            } else {
            +                if (cell.foldWidget) {
            +                    cell.element.removeChild(cell.foldWidget);
            +                    cell.foldWidget = null;
            +                }
            +            }
            +            
            +            var text = lastLineNumber = gutterRenderer
            +                ? gutterRenderer.getText(session, row)
            +                : row + firstLineNumber;
            +            if (text != cell.textNode.data)
            +                cell.textNode.data = text;
            +
            +            row++;
            +        }
            +
            +        this.element.style.height = config.minHeight + "px";
            +
            +        if (this.$fixedWidth || session.$useWrapMode)
            +            lastLineNumber = session.getLength() + firstLineNumber;
            +
            +        var gutterWidth = gutterRenderer 
            +            ? gutterRenderer.getWidth(session, lastLineNumber, config)
            +            : lastLineNumber.toString().length * config.characterWidth;
            +        
            +        var padding = this.$padding || this.$computePadding();
            +        gutterWidth += padding.left + padding.right;
            +        if (gutterWidth !== this.gutterWidth && !isNaN(gutterWidth)) {
            +            this.gutterWidth = gutterWidth;
            +            this.element.style.width = Math.ceil(this.gutterWidth) + "px";
            +            this._emit("changeGutterWidth", gutterWidth);
            +        }
            +    };
            +
            +    this.$fixedWidth = false;
            +    
            +    this.$showLineNumbers = true;
            +    this.$renderer = "";
            +    this.setShowLineNumbers = function(show) {
            +        this.$renderer = !show && {
            +            getWidth: function() {return ""},
            +            getText: function() {return ""}
            +        };
            +    };
            +    
            +    this.getShowLineNumbers = function() {
            +        return this.$showLineNumbers;
            +    };
            +    
            +    this.$showFoldWidgets = true;
            +    this.setShowFoldWidgets = function(show) {
            +        if (show)
            +            dom.addCssClass(this.element, "ace_folding-enabled");
            +        else
            +            dom.removeCssClass(this.element, "ace_folding-enabled");
            +
            +        this.$showFoldWidgets = show;
            +        this.$padding = null;
            +    };
            +    
            +    this.getShowFoldWidgets = function() {
            +        return this.$showFoldWidgets;
            +    };
            +
            +    this.$computePadding = function() {
            +        if (!this.element.firstChild)
            +            return {left: 0, right: 0};
            +        var style = dom.computedStyle(this.element.firstChild);
            +        this.$padding = {};
            +        this.$padding.left = parseInt(style.paddingLeft) + 1 || 0;
            +        this.$padding.right = parseInt(style.paddingRight) || 0;
            +        return this.$padding;
            +    };
            +
            +    this.getRegion = function(point) {
            +        var padding = this.$padding || this.$computePadding();
            +        var rect = this.element.getBoundingClientRect();
            +        if (point.x < padding.left + rect.left)
            +            return "markers";
            +        if (this.$showFoldWidgets && point.x > rect.right - padding.right)
            +            return "foldWidgets";
            +    };
            +
            +}).call(Gutter.prototype);
            +
            +exports.Gutter = Gutter;
            +
            +});
            +
            +define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"], function(require, exports, module) {
            +"use strict";
            +
            +var Range = require("../range").Range;
            +var dom = require("../lib/dom");
            +
            +var Marker = function(parentEl) {
            +    this.element = dom.createElement("div");
            +    this.element.className = "ace_layer ace_marker-layer";
            +    parentEl.appendChild(this.element);
            +};
            +
            +(function() {
            +
            +    this.$padding = 0;
            +
            +    this.setPadding = function(padding) {
            +        this.$padding = padding;
            +    };
            +    this.setSession = function(session) {
            +        this.session = session;
            +    };
            +    
            +    this.setMarkers = function(markers) {
            +        this.markers = markers;
            +    };
            +
            +    this.update = function(config) {
            +        var config = config || this.config;
            +        if (!config)
            +            return;
            +
            +        this.config = config;
            +
            +
            +        var html = [];
            +        for (var key in this.markers) {
            +            var marker = this.markers[key];
            +
            +            if (!marker.range) {
            +                marker.update(html, this, this.session, config);
            +                continue;
            +            }
            +
            +            var range = marker.range.clipRows(config.firstRow, config.lastRow);
            +            if (range.isEmpty()) continue;
            +
            +            range = range.toScreenRange(this.session);
            +            if (marker.renderer) {
            +                var top = this.$getTop(range.start.row, config);
            +                var left = this.$padding + range.start.column * config.characterWidth;
            +                marker.renderer(html, range, left, top, config);
            +            } else if (marker.type == "fullLine") {
            +                this.drawFullLineMarker(html, range, marker.clazz, config);
            +            } else if (marker.type == "screenLine") {
            +                this.drawScreenLineMarker(html, range, marker.clazz, config);
            +            } else if (range.isMultiLine()) {
            +                if (marker.type == "text")
            +                    this.drawTextMarker(html, range, marker.clazz, config);
            +                else
            +                    this.drawMultiLineMarker(html, range, marker.clazz, config);
            +            } else {
            +                this.drawSingleLineMarker(html, range, marker.clazz + " ace_start", config);
            +            }
            +        }
            +        this.element.innerHTML = html.join("");
            +    };
            +
            +    this.$getTop = function(row, layerConfig) {
            +        return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
            +    };
            +    this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig, extraStyle) {
            +        var row = range.start.row;
            +
            +        var lineRange = new Range(
            +            row, range.start.column,
            +            row, this.session.getScreenLastRowColumn(row)
            +        );
            +        this.drawSingleLineMarker(stringBuilder, lineRange, clazz + " ace_start", layerConfig, 1, extraStyle);
            +        row = range.end.row;
            +        lineRange = new Range(row, 0, row, range.end.column);
            +        this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 0, extraStyle);
            +
            +        for (row = range.start.row + 1; row < range.end.row; row++) {
            +            lineRange.start.row = row;
            +            lineRange.end.row = row;
            +            lineRange.end.column = this.session.getScreenLastRowColumn(row);
            +            this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig, 1, extraStyle);
            +        }
            +    };
            +    this.drawMultiLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
            +        var padding = this.$padding;
            +        var height = config.lineHeight;
            +        var top = this.$getTop(range.start.row, config);
            +        var left = padding + range.start.column * config.characterWidth;
            +        extraStyle = extraStyle || "";
            +
            +        stringBuilder.push(
            +            "<div class='", clazz, " ace_start' style='",
            +            "height:", height, "px;",
            +            "right:0;",
            +            "top:", top, "px;",
            +            "left:", left, "px;", extraStyle, "'></div>"
            +        );
            +        top = this.$getTop(range.end.row, config);
            +        var width = range.end.column * config.characterWidth;
            +
            +        stringBuilder.push(
            +            "<div class='", clazz, "' style='",
            +            "height:", height, "px;",
            +            "width:", width, "px;",
            +            "top:", top, "px;",
            +            "left:", padding, "px;", extraStyle, "'></div>"
            +        );
            +        height = (range.end.row - range.start.row - 1) * config.lineHeight;
            +        if (height < 0)
            +            return;
            +        top = this.$getTop(range.start.row + 1, config);
            +
            +        stringBuilder.push(
            +            "<div class='", clazz, "' style='",
            +            "height:", height, "px;",
            +            "right:0;",
            +            "top:", top, "px;",
            +            "left:", padding, "px;", extraStyle, "'></div>"
            +        );
            +    };
            +    this.drawSingleLineMarker = function(stringBuilder, range, clazz, config, extraLength, extraStyle) {
            +        var height = config.lineHeight;
            +        var width = (range.end.column + (extraLength || 0) - range.start.column) * config.characterWidth;
            +
            +        var top = this.$getTop(range.start.row, config);
            +        var left = this.$padding + range.start.column * config.characterWidth;
            +
            +        stringBuilder.push(
            +            "<div class='", clazz, "' style='",
            +            "height:", height, "px;",
            +            "width:", width, "px;",
            +            "top:", top, "px;",
            +            "left:", left, "px;", extraStyle || "", "'></div>"
            +        );
            +    };
            +
            +    this.drawFullLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
            +        var top = this.$getTop(range.start.row, config);
            +        var height = config.lineHeight;
            +        if (range.start.row != range.end.row)
            +            height += this.$getTop(range.end.row, config) - top;
            +
            +        stringBuilder.push(
            +            "<div class='", clazz, "' style='",
            +            "height:", height, "px;",
            +            "top:", top, "px;",
            +            "left:0;right:0;", extraStyle || "", "'></div>"
            +        );
            +    };
            +    
            +    this.drawScreenLineMarker = function(stringBuilder, range, clazz, config, extraStyle) {
            +        var top = this.$getTop(range.start.row, config);
            +        var height = config.lineHeight;
            +
            +        stringBuilder.push(
            +            "<div class='", clazz, "' style='",
            +            "height:", height, "px;",
            +            "top:", top, "px;",
            +            "left:0;right:0;", extraStyle || "", "'></div>"
            +        );
            +    };
            +
            +}).call(Marker.prototype);
            +
            +exports.Marker = Marker;
            +
            +});
            +
            +define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("../lib/oop");
            +var dom = require("../lib/dom");
            +var lang = require("../lib/lang");
            +var useragent = require("../lib/useragent");
            +var EventEmitter = require("../lib/event_emitter").EventEmitter;
            +
            +var Text = function(parentEl) {
            +    this.element = dom.createElement("div");
            +    this.element.className = "ace_layer ace_text-layer";
            +    parentEl.appendChild(this.element);
            +    this.$updateEolChar = this.$updateEolChar.bind(this);
            +};
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +
            +    this.EOF_CHAR = "\xB6";
            +    this.EOL_CHAR_LF = "\xAC";
            +    this.EOL_CHAR_CRLF = "\xa4";
            +    this.EOL_CHAR = this.EOL_CHAR_LF;
            +    this.TAB_CHAR = "\u2192"; //"\u21E5";
            +    this.SPACE_CHAR = "\xB7";
            +    this.$padding = 0;
            +
            +    this.$updateEolChar = function() {
            +        var EOL_CHAR = this.session.doc.getNewLineCharacter() == "\n"
            +           ? this.EOL_CHAR_LF
            +           : this.EOL_CHAR_CRLF;
            +        if (this.EOL_CHAR != EOL_CHAR) {
            +            this.EOL_CHAR = EOL_CHAR;
            +            return true;
            +        }
            +    }
            +
            +    this.setPadding = function(padding) {
            +        this.$padding = padding;
            +        this.element.style.padding = "0 " + padding + "px";
            +    };
            +
            +    this.getLineHeight = function() {
            +        return this.$fontMetrics.$characterSize.height || 0;
            +    };
            +
            +    this.getCharacterWidth = function() {
            +        return this.$fontMetrics.$characterSize.width || 0;
            +    };
            +    
            +    this.$setFontMetrics = function(measure) {
            +        this.$fontMetrics = measure;
            +        this.$fontMetrics.on("changeCharacterSize", function(e) {
            +            this._signal("changeCharacterSize", e);
            +        }.bind(this));
            +        this.$pollSizeChanges();
            +    }
            +
            +    this.checkForSizeChanges = function() {
            +        this.$fontMetrics.checkForSizeChanges();
            +    };
            +    this.$pollSizeChanges = function() {
            +        return this.$pollSizeChangesTimer = this.$fontMetrics.$pollSizeChanges();
            +    };
            +    this.setSession = function(session) {
            +        this.session = session;
            +        this.$computeTabString();
            +    };
            +
            +    this.showInvisibles = false;
            +    this.setShowInvisibles = function(showInvisibles) {
            +        if (this.showInvisibles == showInvisibles)
            +            return false;
            +
            +        this.showInvisibles = showInvisibles;
            +        this.$computeTabString();
            +        return true;
            +    };
            +
            +    this.displayIndentGuides = true;
            +    this.setDisplayIndentGuides = function(display) {
            +        if (this.displayIndentGuides == display)
            +            return false;
            +
            +        this.displayIndentGuides = display;
            +        this.$computeTabString();
            +        return true;
            +    };
            +
            +    this.$tabStrings = [];
            +    this.onChangeTabSize =
            +    this.$computeTabString = function() {
            +        var tabSize = this.session.getTabSize();
            +        this.tabSize = tabSize;
            +        var tabStr = this.$tabStrings = [0];
            +        for (var i = 1; i < tabSize + 1; i++) {
            +            if (this.showInvisibles) {
            +                tabStr.push("<span class='ace_invisible ace_invisible_tab'>"
            +                    + this.TAB_CHAR
            +                    + lang.stringRepeat("\xa0", i - 1)
            +                    + "</span>");
            +            } else {
            +                tabStr.push(lang.stringRepeat("\xa0", i));
            +            }
            +        }
            +        if (this.displayIndentGuides) {
            +            this.$indentGuideRe =  /\s\S| \t|\t |\s$/;
            +            var className = "ace_indent-guide";
            +            var spaceClass = "";
            +            var tabClass = "";
            +            if (this.showInvisibles) {
            +                className += " ace_invisible";
            +                spaceClass = " ace_invisible_space";
            +                tabClass = " ace_invisible_tab";
            +                var spaceContent = lang.stringRepeat(this.SPACE_CHAR, this.tabSize);
            +                var tabContent = this.TAB_CHAR + lang.stringRepeat("\xa0", this.tabSize - 1);
            +            } else{
            +                var spaceContent = lang.stringRepeat("\xa0", this.tabSize);
            +                var tabContent = spaceContent;
            +            }
            +
            +            this.$tabStrings[" "] = "<span class='" + className + spaceClass + "'>" + spaceContent + "</span>";
            +            this.$tabStrings["\t"] = "<span class='" + className + tabClass + "'>" + tabContent + "</span>";
            +        }
            +    };
            +
            +    this.updateLines = function(config, firstRow, lastRow) {
            +        if (this.config.lastRow != config.lastRow ||
            +            this.config.firstRow != config.firstRow) {
            +            this.scrollLines(config);
            +        }
            +        this.config = config;
            +
            +        var first = Math.max(firstRow, config.firstRow);
            +        var last = Math.min(lastRow, config.lastRow);
            +
            +        var lineElements = this.element.childNodes;
            +        var lineElementsIdx = 0;
            +
            +        for (var row = config.firstRow; row < first; row++) {
            +            var foldLine = this.session.getFoldLine(row);
            +            if (foldLine) {
            +                if (foldLine.containsRow(first)) {
            +                    first = foldLine.start.row;
            +                    break;
            +                } else {
            +                    row = foldLine.end.row;
            +                }
            +            }
            +            lineElementsIdx ++;
            +        }
            +
            +        var row = first;
            +        var foldLine = this.session.getNextFoldLine(row);
            +        var foldStart = foldLine ? foldLine.start.row : Infinity;
            +
            +        while (true) {
            +            if (row > foldStart) {
            +                row = foldLine.end.row+1;
            +                foldLine = this.session.getNextFoldLine(row, foldLine);
            +                foldStart = foldLine ? foldLine.start.row :Infinity;
            +            }
            +            if (row > last)
            +                break;
            +
            +            var lineElement = lineElements[lineElementsIdx++];
            +            if (lineElement) {
            +                var html = [];
            +                this.$renderLine(
            +                    html, row, !this.$useLineGroups(), row == foldStart ? foldLine : false
            +                );
            +                lineElement.style.height = config.lineHeight * this.session.getRowLength(row) + "px";
            +                lineElement.innerHTML = html.join("");
            +            }
            +            row++;
            +        }
            +    };
            +
            +    this.scrollLines = function(config) {
            +        var oldConfig = this.config;
            +        this.config = config;
            +
            +        if (!oldConfig || oldConfig.lastRow < config.firstRow)
            +            return this.update(config);
            +
            +        if (config.lastRow < oldConfig.firstRow)
            +            return this.update(config);
            +
            +        var el = this.element;
            +        if (oldConfig.firstRow < config.firstRow)
            +            for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)
            +                el.removeChild(el.firstChild);
            +
            +        if (oldConfig.lastRow > config.lastRow)
            +            for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)
            +                el.removeChild(el.lastChild);
            +
            +        if (config.firstRow < oldConfig.firstRow) {
            +            var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1);
            +            if (el.firstChild)
            +                el.insertBefore(fragment, el.firstChild);
            +            else
            +                el.appendChild(fragment);
            +        }
            +
            +        if (config.lastRow > oldConfig.lastRow) {
            +            var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow);
            +            el.appendChild(fragment);
            +        }
            +    };
            +
            +    this.$renderLinesFragment = function(config, firstRow, lastRow) {
            +        var fragment = this.element.ownerDocument.createDocumentFragment();
            +        var row = firstRow;
            +        var foldLine = this.session.getNextFoldLine(row);
            +        var foldStart = foldLine ? foldLine.start.row : Infinity;
            +
            +        while (true) {
            +            if (row > foldStart) {
            +                row = foldLine.end.row+1;
            +                foldLine = this.session.getNextFoldLine(row, foldLine);
            +                foldStart = foldLine ? foldLine.start.row : Infinity;
            +            }
            +            if (row > lastRow)
            +                break;
            +
            +            var container = dom.createElement("div");
            +
            +            var html = [];
            +            this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
            +            container.innerHTML = html.join("");
            +            if (this.$useLineGroups()) {
            +                container.className = 'ace_line_group';
            +                fragment.appendChild(container);
            +                container.style.height = config.lineHeight * this.session.getRowLength(row) + "px";
            +
            +            } else {
            +                while(container.firstChild)
            +                    fragment.appendChild(container.firstChild);
            +            }
            +
            +            row++;
            +        }
            +        return fragment;
            +    };
            +
            +    this.update = function(config) {
            +        this.config = config;
            +
            +        var html = [];
            +        var firstRow = config.firstRow, lastRow = config.lastRow;
            +
            +        var row = firstRow;
            +        var foldLine = this.session.getNextFoldLine(row);
            +        var foldStart = foldLine ? foldLine.start.row : Infinity;
            +
            +        while (true) {
            +            if (row > foldStart) {
            +                row = foldLine.end.row+1;
            +                foldLine = this.session.getNextFoldLine(row, foldLine);
            +                foldStart = foldLine ? foldLine.start.row :Infinity;
            +            }
            +            if (row > lastRow)
            +                break;
            +
            +            if (this.$useLineGroups())
            +                html.push("<div class='ace_line_group' style='height:", config.lineHeight*this.session.getRowLength(row), "px'>")
            +
            +            this.$renderLine(html, row, false, row == foldStart ? foldLine : false);
            +
            +            if (this.$useLineGroups())
            +                html.push("</div>"); // end the line group
            +
            +            row++;
            +        }
            +        this.element.innerHTML = html.join("");
            +    };
            +
            +    this.$textToken = {
            +        "text": true,
            +        "rparen": true,
            +        "lparen": true
            +    };
            +
            +    this.$renderToken = function(stringBuilder, screenColumn, token, value) {
            +        var self = this;
            +        var replaceReg = /\t|&|<|( +)|([\x00-\x1f\x80-\xa0\u1680\u180E\u2000-\u200f\u2028\u2029\u202F\u205F\u3000\uFEFF])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g;
            +        var replaceFunc = function(c, a, b, tabIdx, idx4) {
            +            if (a) {
            +                return self.showInvisibles ?
            +                    "<span class='ace_invisible ace_invisible_space'>" + lang.stringRepeat(self.SPACE_CHAR, c.length) + "</span>" :
            +                    lang.stringRepeat("\xa0", c.length);
            +            } else if (c == "&") {
            +                return "&#38;";
            +            } else if (c == "<") {
            +                return "&#60;";
            +            } else if (c == "\t") {
            +                var tabSize = self.session.getScreenTabSize(screenColumn + tabIdx);
            +                screenColumn += tabSize - 1;
            +                return self.$tabStrings[tabSize];
            +            } else if (c == "\u3000") {
            +                var classToUse = self.showInvisibles ? "ace_cjk ace_invisible ace_invisible_space" : "ace_cjk";
            +                var space = self.showInvisibles ? self.SPACE_CHAR : "";
            +                screenColumn += 1;
            +                return "<span class='" + classToUse + "' style='width:" +
            +                    (self.config.characterWidth * 2) +
            +                    "px'>" + space + "</span>";
            +            } else if (b) {
            +                return "<span class='ace_invisible ace_invisible_space ace_invalid'>" + self.SPACE_CHAR + "</span>";
            +            } else {
            +                screenColumn += 1;
            +                return "<span class='ace_cjk' style='width:" +
            +                    (self.config.characterWidth * 2) +
            +                    "px'>" + c + "</span>";
            +            }
            +        };
            +
            +        var output = value.replace(replaceReg, replaceFunc);
            +
            +        if (!this.$textToken[token.type]) {
            +            var classes = "ace_" + token.type.replace(/\./g, " ace_");
            +            var style = "";
            +            if (token.type == "fold")
            +                style = " style='width:" + (token.value.length * this.config.characterWidth) + "px;' ";
            +            stringBuilder.push("<span class='", classes, "'", style, ">", output, "</span>");
            +        }
            +        else {
            +            stringBuilder.push(output);
            +        }
            +        return screenColumn + value.length;
            +    };
            +
            +    this.renderIndentGuide = function(stringBuilder, value, max) {
            +        var cols = value.search(this.$indentGuideRe);
            +        if (cols <= 0 || cols >= max)
            +            return value;
            +        if (value[0] == " ") {
            +            cols -= cols % this.tabSize;
            +            stringBuilder.push(lang.stringRepeat(this.$tabStrings[" "], cols/this.tabSize));
            +            return value.substr(cols);
            +        } else if (value[0] == "\t") {
            +            stringBuilder.push(lang.stringRepeat(this.$tabStrings["\t"], cols));
            +            return value.substr(cols);
            +        }
            +        return value;
            +    };
            +
            +    this.$renderWrappedLine = function(stringBuilder, tokens, splits, onlyContents) {
            +        var chars = 0;
            +        var split = 0;
            +        var splitChars = splits[0];
            +        var screenColumn = 0;
            +
            +        for (var i = 0; i < tokens.length; i++) {
            +            var token = tokens[i];
            +            var value = token.value;
            +            if (i == 0 && this.displayIndentGuides) {
            +                chars = value.length;
            +                value = this.renderIndentGuide(stringBuilder, value, splitChars);
            +                if (!value)
            +                    continue;
            +                chars -= value.length;
            +            }
            +
            +            if (chars + value.length < splitChars) {
            +                screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
            +                chars += value.length;
            +            } else {
            +                while (chars + value.length >= splitChars) {
            +                    screenColumn = this.$renderToken(
            +                        stringBuilder, screenColumn,
            +                        token, value.substring(0, splitChars - chars)
            +                    );
            +                    value = value.substring(splitChars - chars);
            +                    chars = splitChars;
            +
            +                    if (!onlyContents) {
            +                        stringBuilder.push("</div>",
            +                            "<div class='ace_line' style='height:",
            +                            this.config.lineHeight, "px'>"
            +                        );
            +                    }
            +
            +                    split ++;
            +                    screenColumn = 0;
            +                    splitChars = splits[split] || Number.MAX_VALUE;
            +                }
            +                if (value.length != 0) {
            +                    chars += value.length;
            +                    screenColumn = this.$renderToken(
            +                        stringBuilder, screenColumn, token, value
            +                    );
            +                }
            +            }
            +        }
            +    };
            +
            +    this.$renderSimpleLine = function(stringBuilder, tokens) {
            +        var screenColumn = 0;
            +        var token = tokens[0];
            +        var value = token.value;
            +        if (this.displayIndentGuides)
            +            value = this.renderIndentGuide(stringBuilder, value);
            +        if (value)
            +            screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
            +        for (var i = 1; i < tokens.length; i++) {
            +            token = tokens[i];
            +            value = token.value;
            +            screenColumn = this.$renderToken(stringBuilder, screenColumn, token, value);
            +        }
            +    };
            +    this.$renderLine = function(stringBuilder, row, onlyContents, foldLine) {
            +        if (!foldLine && foldLine != false)
            +            foldLine = this.session.getFoldLine(row);
            +
            +        if (foldLine)
            +            var tokens = this.$getFoldLineTokens(row, foldLine);
            +        else
            +            var tokens = this.session.getTokens(row);
            +
            +
            +        if (!onlyContents) {
            +            stringBuilder.push(
            +                "<div class='ace_line' style='height:", 
            +                    this.config.lineHeight * (
            +                        this.$useLineGroups() ? 1 :this.session.getRowLength(row)
            +                    ), "px'>"
            +            );
            +        }
            +
            +        if (tokens.length) {
            +            var splits = this.session.getRowSplitData(row);
            +            if (splits && splits.length)
            +                this.$renderWrappedLine(stringBuilder, tokens, splits, onlyContents);
            +            else
            +                this.$renderSimpleLine(stringBuilder, tokens);
            +        }
            +
            +        if (this.showInvisibles) {
            +            if (foldLine)
            +                row = foldLine.end.row
            +
            +            stringBuilder.push(
            +                "<span class='ace_invisible ace_invisible_eol'>",
            +                row == this.session.getLength() - 1 ? this.EOF_CHAR : this.EOL_CHAR,
            +                "</span>"
            +            );
            +        }
            +        if (!onlyContents)
            +            stringBuilder.push("</div>");
            +    };
            +
            +    this.$getFoldLineTokens = function(row, foldLine) {
            +        var session = this.session;
            +        var renderTokens = [];
            +
            +        function addTokens(tokens, from, to) {
            +            var idx = 0, col = 0;
            +            while ((col + tokens[idx].value.length) < from) {
            +                col += tokens[idx].value.length;
            +                idx++;
            +
            +                if (idx == tokens.length)
            +                    return;
            +            }
            +            if (col != from) {
            +                var value = tokens[idx].value.substring(from - col);
            +                if (value.length > (to - from))
            +                    value = value.substring(0, to - from);
            +
            +                renderTokens.push({
            +                    type: tokens[idx].type,
            +                    value: value
            +                });
            +
            +                col = from + value.length;
            +                idx += 1;
            +            }
            +
            +            while (col < to && idx < tokens.length) {
            +                var value = tokens[idx].value;
            +                if (value.length + col > to) {
            +                    renderTokens.push({
            +                        type: tokens[idx].type,
            +                        value: value.substring(0, to - col)
            +                    });
            +                } else
            +                    renderTokens.push(tokens[idx]);
            +                col += value.length;
            +                idx += 1;
            +            }
            +        }
            +
            +        var tokens = session.getTokens(row);
            +        foldLine.walk(function(placeholder, row, column, lastColumn, isNewRow) {
            +            if (placeholder != null) {
            +                renderTokens.push({
            +                    type: "fold",
            +                    value: placeholder
            +                });
            +            } else {
            +                if (isNewRow)
            +                    tokens = session.getTokens(row);
            +
            +                if (tokens.length)
            +                    addTokens(tokens, lastColumn, column);
            +            }
            +        }, foldLine.end.row, this.session.getLine(foldLine.end.row).length);
            +
            +        return renderTokens;
            +    };
            +
            +    this.$useLineGroups = function() {
            +        return this.session.getUseWrapMode();
            +    };
            +
            +    this.destroy = function() {
            +        clearInterval(this.$pollSizeChangesTimer);
            +        if (this.$measureNode)
            +            this.$measureNode.parentNode.removeChild(this.$measureNode);
            +        delete this.$measureNode;
            +    };
            +
            +}).call(Text.prototype);
            +
            +exports.Text = Text;
            +
            +});
            +
            +define("ace/layer/cursor",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
            +"use strict";
            +
            +var dom = require("../lib/dom");
            +var IE8;
            +
            +var Cursor = function(parentEl) {
            +    this.element = dom.createElement("div");
            +    this.element.className = "ace_layer ace_cursor-layer";
            +    parentEl.appendChild(this.element);
            +    
            +    if (IE8 === undefined)
            +        IE8 = "opacity" in this.element;
            +
            +    this.isVisible = false;
            +    this.isBlinking = true;
            +    this.blinkInterval = 1000;
            +    this.smoothBlinking = false;
            +
            +    this.cursors = [];
            +    this.cursor = this.addCursor();
            +    dom.addCssClass(this.element, "ace_hidden-cursors");
            +    this.$updateCursors = this.$updateVisibility.bind(this);
            +};
            +
            +(function() {
            +    
            +    this.$updateVisibility = function(val) {
            +        var cursors = this.cursors;
            +        for (var i = cursors.length; i--; )
            +            cursors[i].style.visibility = val ? "" : "hidden";
            +    };
            +    this.$updateOpacity = function(val) {
            +        var cursors = this.cursors;
            +        for (var i = cursors.length; i--; )
            +            cursors[i].style.opacity = val ? "" : "0";
            +    };
            +    
            +
            +    this.$padding = 0;
            +    this.setPadding = function(padding) {
            +        this.$padding = padding;
            +    };
            +
            +    this.setSession = function(session) {
            +        this.session = session;
            +    };
            +
            +    this.setBlinking = function(blinking) {
            +        if (blinking != this.isBlinking){
            +            this.isBlinking = blinking;
            +            this.restartTimer();
            +        }
            +    };
            +
            +    this.setBlinkInterval = function(blinkInterval) {
            +        if (blinkInterval != this.blinkInterval){
            +            this.blinkInterval = blinkInterval;
            +            this.restartTimer();
            +        }
            +    };
            +
            +    this.setSmoothBlinking = function(smoothBlinking) {
            +        if (smoothBlinking != this.smoothBlinking && !IE8) {
            +            this.smoothBlinking = smoothBlinking;
            +            dom.setCssClass(this.element, "ace_smooth-blinking", smoothBlinking);
            +            this.$updateCursors(true);
            +            this.$updateCursors = (smoothBlinking 
            +                ? this.$updateOpacity
            +                : this.$updateVisibility).bind(this);
            +            this.restartTimer();
            +        }
            +    };
            +
            +    this.addCursor = function() {
            +        var el = dom.createElement("div");
            +        el.className = "ace_cursor";
            +        this.element.appendChild(el);
            +        this.cursors.push(el);
            +        return el;
            +    };
            +
            +    this.removeCursor = function() {
            +        if (this.cursors.length > 1) {
            +            var el = this.cursors.pop();
            +            el.parentNode.removeChild(el);
            +            return el;
            +        }
            +    };
            +
            +    this.hideCursor = function() {
            +        this.isVisible = false;
            +        dom.addCssClass(this.element, "ace_hidden-cursors");
            +        this.restartTimer();
            +    };
            +
            +    this.showCursor = function() {
            +        this.isVisible = true;
            +        dom.removeCssClass(this.element, "ace_hidden-cursors");
            +        this.restartTimer();
            +    };
            +
            +    this.restartTimer = function() {
            +        var update = this.$updateCursors;
            +        clearInterval(this.intervalId);
            +        clearTimeout(this.timeoutId);
            +        if (this.smoothBlinking) {
            +            dom.removeCssClass(this.element, "ace_smooth-blinking");
            +        }
            +        
            +        update(true);
            +
            +        if (!this.isBlinking || !this.blinkInterval || !this.isVisible)
            +            return;
            +
            +        if (this.smoothBlinking) {
            +            setTimeout(function(){
            +                dom.addCssClass(this.element, "ace_smooth-blinking");
            +            }.bind(this));
            +        }
            +        
            +        var blink = function(){
            +            this.timeoutId = setTimeout(function() {
            +                update(false);
            +            }, 0.6 * this.blinkInterval);
            +        }.bind(this);
            +
            +        this.intervalId = setInterval(function() {
            +            update(true);
            +            blink();
            +        }, this.blinkInterval);
            +
            +        blink();
            +    };
            +
            +    this.getPixelPosition = function(position, onScreen) {
            +        if (!this.config || !this.session)
            +            return {left : 0, top : 0};
            +
            +        if (!position)
            +            position = this.session.selection.getCursor();
            +        var pos = this.session.documentToScreenPosition(position);
            +        var cursorLeft = this.$padding + pos.column * this.config.characterWidth;
            +        var cursorTop = (pos.row - (onScreen ? this.config.firstRowScreen : 0)) *
            +            this.config.lineHeight;
            +
            +        return {left : cursorLeft, top : cursorTop};
            +    };
            +
            +    this.update = function(config) {
            +        this.config = config;
            +
            +        var selections = this.session.$selectionMarkers;
            +        var i = 0, cursorIndex = 0;
            +
            +        if (selections === undefined || selections.length === 0){
            +            selections = [{cursor: null}];
            +        }
            +
            +        for (var i = 0, n = selections.length; i < n; i++) {
            +            var pixelPos = this.getPixelPosition(selections[i].cursor, true);
            +            if ((pixelPos.top > config.height + config.offset ||
            +                 pixelPos.top < 0) && i > 1) {
            +                continue;
            +            }
            +
            +            var style = (this.cursors[cursorIndex++] || this.addCursor()).style;
            +
            +            style.left = pixelPos.left + "px";
            +            style.top = pixelPos.top + "px";
            +            style.width = config.characterWidth + "px";
            +            style.height = config.lineHeight + "px";
            +        }
            +        while (this.cursors.length > cursorIndex)
            +            this.removeCursor();
            +
            +        var overwrite = this.session.getOverwrite();
            +        this.$setOverwrite(overwrite);
            +        this.$pixelPos = pixelPos;
            +        this.restartTimer();
            +    };
            +
            +    this.$setOverwrite = function(overwrite) {
            +        if (overwrite != this.overwrite) {
            +            this.overwrite = overwrite;
            +            if (overwrite)
            +                dom.addCssClass(this.element, "ace_overwrite-cursors");
            +            else
            +                dom.removeCssClass(this.element, "ace_overwrite-cursors");
            +        }
            +    };
            +
            +    this.destroy = function() {
            +        clearInterval(this.intervalId);
            +        clearTimeout(this.timeoutId);
            +    };
            +
            +}).call(Cursor.prototype);
            +
            +exports.Cursor = Cursor;
            +
            +});
            +
            +define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./lib/oop");
            +var dom = require("./lib/dom");
            +var event = require("./lib/event");
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +var ScrollBar = function(parent) {
            +    this.element = dom.createElement("div");
            +    this.element.className = "ace_scrollbar ace_scrollbar" + this.classSuffix;
            +
            +    this.inner = dom.createElement("div");
            +    this.inner.className = "ace_scrollbar-inner";
            +    this.element.appendChild(this.inner);
            +
            +    parent.appendChild(this.element);
            +
            +    this.setVisible(false);
            +    this.skipEvent = false;
            +
            +    event.addListener(this.element, "scroll", this.onScroll.bind(this));
            +    event.addListener(this.element, "mousedown", event.preventDefault);
            +};
            +
            +(function() {
            +    oop.implement(this, EventEmitter);
            +
            +    this.setVisible = function(isVisible) {
            +        this.element.style.display = isVisible ? "" : "none";
            +        this.isVisible = isVisible;
            +    };
            +}).call(ScrollBar.prototype);
            +var VScrollBar = function(parent, renderer) {
            +    ScrollBar.call(this, parent);
            +    this.scrollTop = 0;
            +    renderer.$scrollbarWidth = 
            +    this.width = dom.scrollbarWidth(parent.ownerDocument);
            +    this.inner.style.width =
            +    this.element.style.width = (this.width || 15) + 5 + "px";
            +};
            +
            +oop.inherits(VScrollBar, ScrollBar);
            +
            +(function() {
            +
            +    this.classSuffix = '-v';
            +    this.onScroll = function() {
            +        if (!this.skipEvent) {
            +            this.scrollTop = this.element.scrollTop;
            +            this._emit("scroll", {data: this.scrollTop});
            +        }
            +        this.skipEvent = false;
            +    };
            +    this.getWidth = function() {
            +        return this.isVisible ? this.width : 0;
            +    };
            +    this.setHeight = function(height) {
            +        this.element.style.height = height + "px";
            +    };
            +    this.setInnerHeight = function(height) {
            +        this.inner.style.height = height + "px";
            +    };
            +    this.setScrollHeight = function(height) {
            +        this.inner.style.height = height + "px";
            +    };
            +    this.setScrollTop = function(scrollTop) {
            +        if (this.scrollTop != scrollTop) {
            +            this.skipEvent = true;
            +            this.scrollTop = this.element.scrollTop = scrollTop;
            +        }
            +    };
            +
            +}).call(VScrollBar.prototype);
            +var HScrollBar = function(parent, renderer) {
            +    ScrollBar.call(this, parent);
            +    this.scrollLeft = 0;
            +    this.height = renderer.$scrollbarWidth;
            +    this.inner.style.height =
            +    this.element.style.height = (this.height || 15) + 5 + "px";
            +};
            +
            +oop.inherits(HScrollBar, ScrollBar);
            +
            +(function() {
            +
            +    this.classSuffix = '-h';
            +    this.onScroll = function() {
            +        if (!this.skipEvent) {
            +            this.scrollLeft = this.element.scrollLeft;
            +            this._emit("scroll", {data: this.scrollLeft});
            +        }
            +        this.skipEvent = false;
            +    };
            +    this.getHeight = function() {
            +        return this.isVisible ? this.height : 0;
            +    };
            +    this.setWidth = function(width) {
            +        this.element.style.width = width + "px";
            +    };
            +    this.setInnerWidth = function(width) {
            +        this.inner.style.width = width + "px";
            +    };
            +    this.setScrollWidth = function(width) {
            +        this.inner.style.width = width + "px";
            +    };
            +    this.setScrollLeft = function(scrollLeft) {
            +        if (this.scrollLeft != scrollLeft) {
            +            this.skipEvent = true;
            +            this.scrollLeft = this.element.scrollLeft = scrollLeft;
            +        }
            +    };
            +
            +}).call(HScrollBar.prototype);
            +
            +
            +exports.ScrollBar = VScrollBar; // backward compatibility
            +exports.ScrollBarV = VScrollBar; // backward compatibility
            +exports.ScrollBarH = HScrollBar; // backward compatibility
            +
            +exports.VScrollBar = VScrollBar;
            +exports.HScrollBar = HScrollBar;
            +});
            +
            +define("ace/renderloop",["require","exports","module","ace/lib/event"], function(require, exports, module) {
            +"use strict";
            +
            +var event = require("./lib/event");
            +
            +
            +var RenderLoop = function(onRender, win) {
            +    this.onRender = onRender;
            +    this.pending = false;
            +    this.changes = 0;
            +    this.window = win || window;
            +};
            +
            +(function() {
            +
            +
            +    this.schedule = function(change) {
            +        this.changes = this.changes | change;
            +        if (!this.pending && this.changes) {
            +            this.pending = true;
            +            var _self = this;
            +            event.nextFrame(function() {
            +                _self.pending = false;
            +                var changes;
            +                while (changes = _self.changes) {
            +                    _self.changes = 0;
            +                    _self.onRender(changes);
            +                }
            +            }, this.window);
            +        }
            +    };
            +
            +}).call(RenderLoop.prototype);
            +
            +exports.RenderLoop = RenderLoop;
            +});
            +
            +define("ace/layer/font_metrics",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"], function(require, exports, module) {
            +
            +var oop = require("../lib/oop");
            +var dom = require("../lib/dom");
            +var lang = require("../lib/lang");
            +var useragent = require("../lib/useragent");
            +var EventEmitter = require("../lib/event_emitter").EventEmitter;
            +
            +var CHAR_COUNT = 0;
            +
            +var FontMetrics = exports.FontMetrics = function(parentEl, interval) {
            +    this.el = dom.createElement("div");
            +    this.$setMeasureNodeStyles(this.el.style, true);
            +    
            +    this.$main = dom.createElement("div");
            +    this.$setMeasureNodeStyles(this.$main.style);
            +    
            +    this.$measureNode = dom.createElement("div");
            +    this.$setMeasureNodeStyles(this.$measureNode.style);
            +    
            +    
            +    this.el.appendChild(this.$main);
            +    this.el.appendChild(this.$measureNode);
            +    parentEl.appendChild(this.el);
            +    
            +    if (!CHAR_COUNT)
            +        this.$testFractionalRect();
            +    this.$measureNode.innerHTML = lang.stringRepeat("X", CHAR_COUNT);
            +    
            +    this.$characterSize = {width: 0, height: 0};
            +    this.checkForSizeChanges();
            +};
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +        
            +    this.$characterSize = {width: 0, height: 0};
            +    
            +    this.$testFractionalRect = function() {
            +        var el = dom.createElement("div");
            +        this.$setMeasureNodeStyles(el.style);
            +        el.style.width = "0.2px";
            +        document.documentElement.appendChild(el);
            +        var w = el.getBoundingClientRect().width;
            +        if (w > 0 && w < 1)
            +            CHAR_COUNT = 1;
            +        else
            +            CHAR_COUNT = 100;
            +        el.parentNode.removeChild(el);
            +    };
            +    
            +    this.$setMeasureNodeStyles = function(style, isRoot) {
            +        style.width = style.height = "auto";
            +        style.left = style.top = "-100px";
            +        style.visibility = "hidden";
            +        style.position = "fixed";
            +        style.whiteSpace = "pre";
            +
            +        if (useragent.isIE < 8) {
            +            style["font-family"] = "inherit";
            +        } else {
            +            style.font = "inherit";
            +        }
            +        style.overflow = isRoot ? "hidden" : "visible";
            +    };
            +
            +    this.checkForSizeChanges = function() {
            +        var size = this.$measureSizes();
            +        if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {
            +            this.$measureNode.style.fontWeight = "bold";
            +            var boldSize = this.$measureSizes();
            +            this.$measureNode.style.fontWeight = "";
            +            this.$characterSize = size;
            +            this.charSizes = Object.create(null);
            +            this.allowBoldFonts = boldSize && boldSize.width === size.width && boldSize.height === size.height;
            +            this._emit("changeCharacterSize", {data: size});
            +        }
            +    };
            +
            +    this.$pollSizeChanges = function() {
            +        if (this.$pollSizeChangesTimer)
            +            return this.$pollSizeChangesTimer;
            +        var self = this;
            +        return this.$pollSizeChangesTimer = setInterval(function() {
            +            self.checkForSizeChanges();
            +        }, 500);
            +    };
            +    
            +    this.setPolling = function(val) {
            +        if (val) {
            +            this.$pollSizeChanges();
            +        } else {
            +            if (this.$pollSizeChangesTimer)
            +                this.$pollSizeChangesTimer;
            +        }
            +    };
            +
            +    this.$measureSizes = function() {
            +        if (CHAR_COUNT === 1) {
            +            var rect = this.$measureNode.getBoundingClientRect();
            +            var size = {
            +                height: rect.height,
            +                width: rect.width
            +            };
            +        } else {
            +            var size = {
            +                height: this.$measureNode.clientHeight,
            +                width: this.$measureNode.clientWidth / CHAR_COUNT
            +            };
            +        }
            +        if (size.width === 0 || size.height === 0)
            +            return null;
            +        return size;
            +    };
            +
            +    this.$measureCharWidth = function(ch) {
            +        this.$main.innerHTML = lang.stringRepeat(ch, CHAR_COUNT);
            +        var rect = this.$main.getBoundingClientRect();
            +        return rect.width / CHAR_COUNT;
            +    };
            +    
            +    this.getCharacterWidth = function(ch) {
            +        var w = this.charSizes[ch];
            +        if (w === undefined) {
            +            this.charSizes[ch] = this.$measureCharWidth(ch) / this.$characterSize.width;
            +        }
            +        return w;
            +    };
            +
            +    this.destroy = function() {
            +        clearInterval(this.$pollSizeChangesTimer);
            +        if (this.el && this.el.parentNode)
            +            this.el.parentNode.removeChild(this.el);
            +    };
            +
            +}).call(FontMetrics.prototype);
            +
            +});
            +
            +define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/config","ace/lib/useragent","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/scrollbar","ace/renderloop","ace/layer/font_metrics","ace/lib/event_emitter"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./lib/oop");
            +var dom = require("./lib/dom");
            +var config = require("./config");
            +var useragent = require("./lib/useragent");
            +var GutterLayer = require("./layer/gutter").Gutter;
            +var MarkerLayer = require("./layer/marker").Marker;
            +var TextLayer = require("./layer/text").Text;
            +var CursorLayer = require("./layer/cursor").Cursor;
            +var HScrollBar = require("./scrollbar").HScrollBar;
            +var VScrollBar = require("./scrollbar").VScrollBar;
            +var RenderLoop = require("./renderloop").RenderLoop;
            +var FontMetrics = require("./layer/font_metrics").FontMetrics;
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +var editorCss = ".ace_editor {\
            +position: relative;\
            +overflow: hidden;\
            +font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;\
            +font-size: 12px;\
            +line-height: normal;\
            +direction: ltr;\
            +}\
            +.ace_scroller {\
            +position: absolute;\
            +overflow: hidden;\
            +top: 0;\
            +bottom: 0;\
            +background-color: inherit;\
            +-ms-user-select: none;\
            +-moz-user-select: none;\
            +-webkit-user-select: none;\
            +user-select: none;\
            +}\
            +.ace_content {\
            +position: absolute;\
            +-moz-box-sizing: border-box;\
            +-webkit-box-sizing: border-box;\
            +box-sizing: border-box;\
            +cursor: text;\
            +min-width: 100%;\
            +}\
            +.ace_dragging, .ace_dragging * {\
            +cursor: move !important;\
            +}\
            +.ace_dragging .ace_scroller:before{\
            +position: absolute;\
            +top: 0;\
            +left: 0;\
            +right: 0;\
            +bottom: 0;\
            +content: '';\
            +background: rgba(250, 250, 250, 0.01);\
            +z-index: 1000;\
            +}\
            +.ace_dragging.ace_dark .ace_scroller:before{\
            +background: rgba(0, 0, 0, 0.01);\
            +}\
            +.ace_selecting, .ace_selecting * {\
            +cursor: text !important;\
            +}\
            +.ace_gutter {\
            +position: absolute;\
            +overflow : hidden;\
            +width: auto;\
            +top: 0;\
            +bottom: 0;\
            +left: 0;\
            +cursor: default;\
            +z-index: 4;\
            +-ms-user-select: none;\
            +-moz-user-select: none;\
            +-webkit-user-select: none;\
            +user-select: none;\
            +}\
            +.ace_gutter-active-line {\
            +position: absolute;\
            +left: 0;\
            +right: 0;\
            +}\
            +.ace_scroller.ace_scroll-left {\
            +box-shadow: 17px 0 16px -16px rgba(0, 0, 0, 0.4) inset;\
            +}\
            +.ace_gutter-cell {\
            +padding-left: 19px;\
            +padding-right: 6px;\
            +background-repeat: no-repeat;\
            +}\
            +.ace_gutter-cell.ace_error {\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABOFBMVEX/////////QRswFAb/Ui4wFAYwFAYwFAaWGAfDRymzOSH/PxswFAb/SiUwFAYwFAbUPRvjQiDllog5HhHdRybsTi3/Tyv9Tir+Syj/UC3////XurebMBIwFAb/RSHbPx/gUzfdwL3kzMivKBAwFAbbvbnhPx66NhowFAYwFAaZJg8wFAaxKBDZurf/RB6mMxb/SCMwFAYwFAbxQB3+RB4wFAb/Qhy4Oh+4QifbNRcwFAYwFAYwFAb/QRzdNhgwFAYwFAbav7v/Uy7oaE68MBK5LxLewr/r2NXewLswFAaxJw4wFAbkPRy2PyYwFAaxKhLm1tMwFAazPiQwFAaUGAb/QBrfOx3bvrv/VC/maE4wFAbRPBq6MRO8Qynew8Dp2tjfwb0wFAbx6eju5+by6uns4uH9/f36+vr/GkHjAAAAYnRSTlMAGt+64rnWu/bo8eAA4InH3+DwoN7j4eLi4xP99Nfg4+b+/u9B/eDs1MD1mO7+4PHg2MXa347g7vDizMLN4eG+Pv7i5evs/v79yu7S3/DV7/498Yv24eH+4ufQ3Ozu/v7+y13sRqwAAADLSURBVHjaZc/XDsFgGIBhtDrshlitmk2IrbHFqL2pvXf/+78DPokj7+Fz9qpU/9UXJIlhmPaTaQ6QPaz0mm+5gwkgovcV6GZzd5JtCQwgsxoHOvJO15kleRLAnMgHFIESUEPmawB9ngmelTtipwwfASilxOLyiV5UVUyVAfbG0cCPHig+GBkzAENHS0AstVF6bacZIOzgLmxsHbt2OecNgJC83JERmePUYq8ARGkJx6XtFsdddBQgZE2nPR6CICZhawjA4Fb/chv+399kfR+MMMDGOQAAAABJRU5ErkJggg==\");\
            +background-repeat: no-repeat;\
            +background-position: 2px center;\
            +}\
            +.ace_gutter-cell.ace_warning {\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAmVBMVEX///8AAAD///8AAAAAAABPSzb/5sAAAAB/blH/73z/ulkAAAAAAAD85pkAAAAAAAACAgP/vGz/rkDerGbGrV7/pkQICAf////e0IsAAAD/oED/qTvhrnUAAAD/yHD/njcAAADuv2r/nz//oTj/p064oGf/zHAAAAA9Nir/tFIAAAD/tlTiuWf/tkIAAACynXEAAAAAAAAtIRW7zBpBAAAAM3RSTlMAABR1m7RXO8Ln31Z36zT+neXe5OzooRDfn+TZ4p3h2hTf4t3k3ucyrN1K5+Xaks52Sfs9CXgrAAAAjklEQVR42o3PbQ+CIBQFYEwboPhSYgoYunIqqLn6/z8uYdH8Vmdnu9vz4WwXgN/xTPRD2+sgOcZjsge/whXZgUaYYvT8QnuJaUrjrHUQreGczuEafQCO/SJTufTbroWsPgsllVhq3wJEk2jUSzX3CUEDJC84707djRc5MTAQxoLgupWRwW6UB5fS++NV8AbOZgnsC7BpEAAAAABJRU5ErkJggg==\");\
            +background-position: 2px center;\
            +}\
            +.ace_gutter-cell.ace_info {\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAJ0Uk5TAAB2k804AAAAPklEQVQY02NgIB68QuO3tiLznjAwpKTgNyDbMegwisCHZUETUZV0ZqOquBpXj2rtnpSJT1AEnnRmL2OgGgAAIKkRQap2htgAAAAASUVORK5CYII=\");\
            +background-position: 2px center;\
            +}\
            +.ace_dark .ace_gutter-cell.ace_info {\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAChoaGAgIAqKiq+vr6tra1ZWVmUlJSbm5s8PDxubm56enrdgzg3AAAAAXRSTlMAQObYZgAAAClJREFUeNpjYMAPdsMYHegyJZFQBlsUlMFVCWUYKkAZMxZAGdxlDMQBAG+TBP4B6RyJAAAAAElFTkSuQmCC\");\
            +}\
            +.ace_scrollbar {\
            +position: absolute;\
            +right: 0;\
            +bottom: 0;\
            +z-index: 6;\
            +}\
            +.ace_scrollbar-inner {\
            +position: absolute;\
            +cursor: text;\
            +left: 0;\
            +top: 0;\
            +}\
            +.ace_scrollbar-v{\
            +overflow-x: hidden;\
            +overflow-y: scroll;\
            +top: 0;\
            +}\
            +.ace_scrollbar-h {\
            +overflow-x: scroll;\
            +overflow-y: hidden;\
            +left: 0;\
            +}\
            +.ace_print-margin {\
            +position: absolute;\
            +height: 100%;\
            +}\
            +.ace_text-input {\
            +position: absolute;\
            +z-index: 0;\
            +width: 0.5em;\
            +height: 1em;\
            +opacity: 0;\
            +background: transparent;\
            +-moz-appearance: none;\
            +appearance: none;\
            +border: none;\
            +resize: none;\
            +outline: none;\
            +overflow: hidden;\
            +font: inherit;\
            +padding: 0 1px;\
            +margin: 0 -1px;\
            +text-indent: -1em;\
            +-ms-user-select: text;\
            +-moz-user-select: text;\
            +-webkit-user-select: text;\
            +user-select: text;\
            +}\
            +.ace_text-input.ace_composition {\
            +background: #f8f8f8;\
            +color: #111;\
            +z-index: 1000;\
            +opacity: 1;\
            +text-indent: 0;\
            +}\
            +.ace_layer {\
            +z-index: 1;\
            +position: absolute;\
            +overflow: hidden;\
            +white-space: pre;\
            +height: 100%;\
            +width: 100%;\
            +-moz-box-sizing: border-box;\
            +-webkit-box-sizing: border-box;\
            +box-sizing: border-box;\
            +pointer-events: none;\
            +}\
            +.ace_gutter-layer {\
            +position: relative;\
            +width: auto;\
            +text-align: right;\
            +pointer-events: auto;\
            +}\
            +.ace_text-layer {\
            +font: inherit !important;\
            +}\
            +.ace_cjk {\
            +display: inline-block;\
            +text-align: center;\
            +}\
            +.ace_cursor-layer {\
            +z-index: 4;\
            +}\
            +.ace_cursor {\
            +z-index: 4;\
            +position: absolute;\
            +-moz-box-sizing: border-box;\
            +-webkit-box-sizing: border-box;\
            +box-sizing: border-box;\
            +border-left: 2px solid\
            +}\
            +.ace_slim-cursors .ace_cursor {\
            +border-left-width: 1px;\
            +}\
            +.ace_overwrite-cursors .ace_cursor {\
            +border-left-width: 0px;\
            +border-bottom: 1px solid;\
            +}\
            +.ace_hidden-cursors .ace_cursor {\
            +opacity: 0.2;\
            +}\
            +.ace_smooth-blinking .ace_cursor {\
            +-moz-transition: opacity 0.18s;\
            +-webkit-transition: opacity 0.18s;\
            +-o-transition: opacity 0.18s;\
            +-ms-transition: opacity 0.18s;\
            +transition: opacity 0.18s;\
            +}\
            +.ace_editor.ace_multiselect .ace_cursor {\
            +border-left-width: 1px;\
            +}\
            +.ace_marker-layer .ace_step, .ace_marker-layer .ace_stack {\
            +position: absolute;\
            +z-index: 3;\
            +}\
            +.ace_marker-layer .ace_selection {\
            +position: absolute;\
            +z-index: 5;\
            +}\
            +.ace_marker-layer .ace_bracket {\
            +position: absolute;\
            +z-index: 6;\
            +}\
            +.ace_marker-layer .ace_active-line {\
            +position: absolute;\
            +z-index: 2;\
            +}\
            +.ace_marker-layer .ace_selected-word {\
            +position: absolute;\
            +z-index: 4;\
            +-moz-box-sizing: border-box;\
            +-webkit-box-sizing: border-box;\
            +box-sizing: border-box;\
            +}\
            +.ace_line .ace_fold {\
            +-moz-box-sizing: border-box;\
            +-webkit-box-sizing: border-box;\
            +box-sizing: border-box;\
            +display: inline-block;\
            +height: 11px;\
            +margin-top: -2px;\
            +vertical-align: middle;\
            +background-image:\
            +url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\
            +url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACJJREFUeNpi+P//fxgTAwPDBxDxD078RSX+YeEyDFMCIMAAI3INmXiwf2YAAAAASUVORK5CYII=\");\
            +background-repeat: no-repeat, repeat-x;\
            +background-position: center center, top left;\
            +color: transparent;\
            +border: 1px solid black;\
            +-moz-border-radius: 2px;\
            +-webkit-border-radius: 2px;\
            +border-radius: 2px;\
            +cursor: pointer;\
            +pointer-events: auto;\
            +}\
            +.ace_dark .ace_fold {\
            +}\
            +.ace_fold:hover{\
            +background-image:\
            +url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAJCAYAAADU6McMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJpJREFUeNpi/P//PwOlgAXGYGRklAVSokD8GmjwY1wasKljQpYACtpCFeADcHVQfQyMQAwzwAZI3wJKvCLkfKBaMSClBlR7BOQikCFGQEErIH0VqkabiGCAqwUadAzZJRxQr/0gwiXIal8zQQPnNVTgJ1TdawL0T5gBIP1MUJNhBv2HKoQHHjqNrA4WO4zY0glyNKLT2KIfIMAAQsdgGiXvgnYAAAAASUVORK5CYII=\"),\
            +url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA3CAYAAADNNiA5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACBJREFUeNpi+P//fz4TAwPDZxDxD5X4i5fLMEwJgAADAEPVDbjNw87ZAAAAAElFTkSuQmCC\");\
            +}\
            +.ace_tooltip {\
            +background-color: #FFF;\
            +background-image: -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.1));\
            +background-image: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.1));\
            +border: 1px solid gray;\
            +border-radius: 1px;\
            +box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\
            +color: black;\
            +display: block;\
            +max-width: 100%;\
            +padding: 3px 4px;\
            +position: fixed;\
            +z-index: 999999;\
            +-moz-box-sizing: border-box;\
            +-webkit-box-sizing: border-box;\
            +box-sizing: border-box;\
            +cursor: default;\
            +white-space: pre;\
            +word-wrap: break-word;\
            +line-height: normal;\
            +font-style: normal;\
            +font-weight: normal;\
            +letter-spacing: normal;\
            +pointer-events: none;\
            +}\
            +.ace_folding-enabled > .ace_gutter-cell {\
            +padding-right: 13px;\
            +}\
            +.ace_fold-widget {\
            +-moz-box-sizing: border-box;\
            +-webkit-box-sizing: border-box;\
            +box-sizing: border-box;\
            +margin: 0 -12px 0 1px;\
            +display: none;\
            +width: 11px;\
            +vertical-align: top;\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42mWKsQ0AMAzC8ixLlrzQjzmBiEjp0A6WwBCSPgKAXoLkqSot7nN3yMwR7pZ32NzpKkVoDBUxKAAAAABJRU5ErkJggg==\");\
            +background-repeat: no-repeat;\
            +background-position: center;\
            +border-radius: 3px;\
            +border: 1px solid transparent;\
            +cursor: pointer;\
            +}\
            +.ace_folding-enabled .ace_fold-widget {\
            +display: inline-block;   \
            +}\
            +.ace_fold-widget.ace_end {\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAANElEQVR42m3HwQkAMAhD0YzsRchFKI7sAikeWkrxwScEB0nh5e7KTPWimZki4tYfVbX+MNl4pyZXejUO1QAAAABJRU5ErkJggg==\");\
            +}\
            +.ace_fold-widget.ace_closed {\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAGCAYAAAAG5SQMAAAAOUlEQVR42jXKwQkAMAgDwKwqKD4EwQ26sSOkVWjgIIHAzPiCgaqiqnJHZnKICBERHN194O5b9vbLuAVRL+l0YWnZAAAAAElFTkSuQmCCXA==\");\
            +}\
            +.ace_fold-widget:hover {\
            +border: 1px solid rgba(0, 0, 0, 0.3);\
            +background-color: rgba(255, 255, 255, 0.2);\
            +-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
            +-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
            +box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\
            +}\
            +.ace_fold-widget:active {\
            +border: 1px solid rgba(0, 0, 0, 0.4);\
            +background-color: rgba(0, 0, 0, 0.05);\
            +-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
            +-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
            +box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\
            +}\
            +.ace_dark .ace_fold-widget {\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHklEQVQIW2P4//8/AzoGEQ7oGCaLLAhWiSwB146BAQCSTPYocqT0AAAAAElFTkSuQmCC\");\
            +}\
            +.ace_dark .ace_fold-widget.ace_end {\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAH0lEQVQIW2P4//8/AxQ7wNjIAjDMgC4AxjCVKBirIAAF0kz2rlhxpAAAAABJRU5ErkJggg==\");\
            +}\
            +.ace_dark .ace_fold-widget.ace_closed {\
            +background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAFCAYAAACAcVaiAAAAHElEQVQIW2P4//+/AxAzgDADlOOAznHAKgPWAwARji8UIDTfQQAAAABJRU5ErkJggg==\");\
            +}\
            +.ace_dark .ace_fold-widget:hover {\
            +box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
            +background-color: rgba(255, 255, 255, 0.1);\
            +}\
            +.ace_dark .ace_fold-widget:active {\
            +-moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
            +-webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
            +box-shadow: 0 1px 1px rgba(255, 255, 255, 0.2);\
            +}\
            +.ace_fold-widget.ace_invalid {\
            +background-color: #FFB4B4;\
            +border-color: #DE5555;\
            +}\
            +.ace_fade-fold-widgets .ace_fold-widget {\
            +-moz-transition: opacity 0.4s ease 0.05s;\
            +-webkit-transition: opacity 0.4s ease 0.05s;\
            +-o-transition: opacity 0.4s ease 0.05s;\
            +-ms-transition: opacity 0.4s ease 0.05s;\
            +transition: opacity 0.4s ease 0.05s;\
            +opacity: 0;\
            +}\
            +.ace_fade-fold-widgets:hover .ace_fold-widget {\
            +-moz-transition: opacity 0.05s ease 0.05s;\
            +-webkit-transition: opacity 0.05s ease 0.05s;\
            +-o-transition: opacity 0.05s ease 0.05s;\
            +-ms-transition: opacity 0.05s ease 0.05s;\
            +transition: opacity 0.05s ease 0.05s;\
            +opacity:1;\
            +}\
            +.ace_underline {\
            +text-decoration: underline;\
            +}\
            +.ace_bold {\
            +font-weight: bold;\
            +}\
            +.ace_nobold .ace_bold {\
            +font-weight: normal;\
            +}\
            +.ace_italic {\
            +font-style: italic;\
            +}\
            +.ace_error-marker {\
            +background-color: rgba(255, 0, 0,0.2);\
            +position: absolute;\
            +z-index: 9;\
            +}\
            +.ace_highlight-marker {\
            +background-color: rgba(255, 255, 0,0.2);\
            +position: absolute;\
            +z-index: 8;\
            +}\
            +";
            +
            +dom.importCssString(editorCss, "ace_editor");
            +
            +var VirtualRenderer = function(container, theme) {
            +    var _self = this;
            +
            +    this.container = container || dom.createElement("div");
            +    this.$keepTextAreaAtCursor = !useragent.isOldIE;
            +
            +    dom.addCssClass(this.container, "ace_editor");
            +
            +    this.setTheme(theme);
            +
            +    this.$gutter = dom.createElement("div");
            +    this.$gutter.className = "ace_gutter";
            +    this.container.appendChild(this.$gutter);
            +
            +    this.scroller = dom.createElement("div");
            +    this.scroller.className = "ace_scroller";
            +    this.container.appendChild(this.scroller);
            +
            +    this.content = dom.createElement("div");
            +    this.content.className = "ace_content";
            +    this.scroller.appendChild(this.content);
            +
            +    this.$gutterLayer = new GutterLayer(this.$gutter);
            +    this.$gutterLayer.on("changeGutterWidth", this.onGutterResize.bind(this));
            +
            +    this.$markerBack = new MarkerLayer(this.content);
            +
            +    var textLayer = this.$textLayer = new TextLayer(this.content);
            +    this.canvas = textLayer.element;
            +
            +    this.$markerFront = new MarkerLayer(this.content);
            +
            +    this.$cursorLayer = new CursorLayer(this.content);
            +    this.$horizScroll = false;
            +    this.$vScroll = false;
            +
            +    this.scrollBar = 
            +    this.scrollBarV = new VScrollBar(this.container, this);
            +    this.scrollBarH = new HScrollBar(this.container, this);
            +    this.scrollBarV.addEventListener("scroll", function(e) {
            +        if (!_self.$scrollAnimation)
            +            _self.session.setScrollTop(e.data - _self.scrollMargin.top);
            +    });
            +    this.scrollBarH.addEventListener("scroll", function(e) {
            +        if (!_self.$scrollAnimation)
            +            _self.session.setScrollLeft(e.data - _self.scrollMargin.left);
            +    });
            +
            +    this.scrollTop = 0;
            +    this.scrollLeft = 0;
            +
            +    this.cursorPos = {
            +        row : 0,
            +        column : 0
            +    };
            +
            +    this.$fontMetrics = new FontMetrics(this.container, 500);
            +    this.$textLayer.$setFontMetrics(this.$fontMetrics);
            +    this.$textLayer.addEventListener("changeCharacterSize", function(e) {
            +        _self.updateCharacterSize();
            +        _self.onResize(true, _self.gutterWidth, _self.$size.width, _self.$size.height);
            +        _self._signal("changeCharacterSize", e);
            +    });
            +
            +    this.$size = {
            +        width: 0,
            +        height: 0,
            +        scrollerHeight: 0,
            +        scrollerWidth: 0,
            +        $dirty: true
            +    };
            +
            +    this.layerConfig = {
            +        width : 1,
            +        padding : 0,
            +        firstRow : 0,
            +        firstRowScreen: 0,
            +        lastRow : 0,
            +        lineHeight : 0,
            +        characterWidth : 0,
            +        minHeight : 1,
            +        maxHeight : 1,
            +        offset : 0,
            +        height : 1,
            +        gutterOffset: 1
            +    };
            +    
            +    this.scrollMargin = {
            +        left: 0,
            +        right: 0,
            +        top: 0,
            +        bottom: 0,
            +        v: 0,
            +        h: 0
            +    };
            +
            +    this.$loop = new RenderLoop(
            +        this.$renderChanges.bind(this),
            +        this.container.ownerDocument.defaultView
            +    );
            +    this.$loop.schedule(this.CHANGE_FULL);
            +
            +    this.updateCharacterSize();
            +    this.setPadding(4);
            +    config.resetOptions(this);
            +    config._emit("renderer", this);
            +};
            +
            +(function() {
            +
            +    this.CHANGE_CURSOR = 1;
            +    this.CHANGE_MARKER = 2;
            +    this.CHANGE_GUTTER = 4;
            +    this.CHANGE_SCROLL = 8;
            +    this.CHANGE_LINES = 16;
            +    this.CHANGE_TEXT = 32;
            +    this.CHANGE_SIZE = 64;
            +    this.CHANGE_MARKER_BACK = 128;
            +    this.CHANGE_MARKER_FRONT = 256;
            +    this.CHANGE_FULL = 512;
            +    this.CHANGE_H_SCROLL = 1024;
            +
            +    oop.implement(this, EventEmitter);
            +
            +    this.updateCharacterSize = function() {
            +        if (this.$textLayer.allowBoldFonts != this.$allowBoldFonts) {
            +            this.$allowBoldFonts = this.$textLayer.allowBoldFonts;
            +            this.setStyle("ace_nobold", !this.$allowBoldFonts);
            +        }
            +
            +        this.layerConfig.characterWidth =
            +        this.characterWidth = this.$textLayer.getCharacterWidth();
            +        this.layerConfig.lineHeight =
            +        this.lineHeight = this.$textLayer.getLineHeight();
            +        this.$updatePrintMargin();
            +    };
            +    this.setSession = function(session) {
            +        if (this.session)
            +            this.session.doc.off("changeNewLineMode", this.onChangeNewLineMode);
            +            
            +        this.session = session;
            +        if (!session)
            +            return;
            +        
            +        if (this.scrollMargin.top && session.getScrollTop() <= 0)
            +            session.setScrollTop(-this.scrollMargin.top);
            +
            +        this.$cursorLayer.setSession(session);
            +        this.$markerBack.setSession(session);
            +        this.$markerFront.setSession(session);
            +        this.$gutterLayer.setSession(session);
            +        this.$textLayer.setSession(session);
            +        this.$loop.schedule(this.CHANGE_FULL);
            +        this.session.$setFontMetrics(this.$fontMetrics);
            +        
            +        this.onChangeNewLineMode = this.onChangeNewLineMode.bind(this);
            +        this.onChangeNewLineMode()
            +        this.session.doc.on("changeNewLineMode", this.onChangeNewLineMode);
            +    };
            +    this.updateLines = function(firstRow, lastRow) {
            +        if (lastRow === undefined)
            +            lastRow = Infinity;
            +
            +        if (!this.$changedLines) {
            +            this.$changedLines = {
            +                firstRow: firstRow,
            +                lastRow: lastRow
            +            };
            +        }
            +        else {
            +            if (this.$changedLines.firstRow > firstRow)
            +                this.$changedLines.firstRow = firstRow;
            +
            +            if (this.$changedLines.lastRow < lastRow)
            +                this.$changedLines.lastRow = lastRow;
            +        }
            +
            +        if (this.$changedLines.firstRow > this.layerConfig.lastRow ||
            +            this.$changedLines.lastRow < this.layerConfig.firstRow)
            +            return;
            +        this.$loop.schedule(this.CHANGE_LINES);
            +    };
            +
            +    this.onChangeNewLineMode = function() {
            +        this.$loop.schedule(this.CHANGE_TEXT);
            +        this.$textLayer.$updateEolChar();
            +    };
            +    
            +    this.onChangeTabSize = function() {
            +        this.$loop.schedule(this.CHANGE_TEXT | this.CHANGE_MARKER);
            +        this.$textLayer.onChangeTabSize();
            +    };
            +    this.updateText = function() {
            +        this.$loop.schedule(this.CHANGE_TEXT);
            +    };
            +    this.updateFull = function(force) {
            +        if (force)
            +            this.$renderChanges(this.CHANGE_FULL, true);
            +        else
            +            this.$loop.schedule(this.CHANGE_FULL);
            +    };
            +    this.updateFontSize = function() {
            +        this.$textLayer.checkForSizeChanges();
            +    };
            +
            +    this.$changes = 0;
            +    this.$updateSizeAsync = function() {
            +        if (this.$loop.pending)
            +            this.$size.$dirty = true;
            +        else
            +            this.onResize();
            +    };
            +    this.onResize = function(force, gutterWidth, width, height) {
            +        if (this.resizing > 2)
            +            return;
            +        else if (this.resizing > 0)
            +            this.resizing++;
            +        else
            +            this.resizing = force ? 1 : 0;
            +        var el = this.container;
            +        if (!height)
            +            height = el.clientHeight || el.scrollHeight;
            +        if (!width)
            +            width = el.clientWidth || el.scrollWidth;
            +        var changes = this.$updateCachedSize(force, gutterWidth, width, height);
            +
            +        
            +        if (!this.$size.scrollerHeight || (!width && !height))
            +            return this.resizing = 0;
            +
            +        if (force)
            +            this.$gutterLayer.$padding = null;
            +
            +        if (force)
            +            this.$renderChanges(changes | this.$changes, true);
            +        else
            +            this.$loop.schedule(changes | this.$changes);
            +
            +        if (this.resizing)
            +            this.resizing = 0;
            +    };
            +    
            +    this.$updateCachedSize = function(force, gutterWidth, width, height) {
            +        height -= (this.$extraHeight || 0);
            +        var changes = 0;
            +        var size = this.$size;
            +        var oldSize = {
            +            width: size.width,
            +            height: size.height,
            +            scrollerHeight: size.scrollerHeight,
            +            scrollerWidth: size.scrollerWidth
            +        };
            +        if (height && (force || size.height != height)) {
            +            size.height = height;
            +            changes |= this.CHANGE_SIZE;
            +
            +            size.scrollerHeight = size.height;
            +            if (this.$horizScroll)
            +                size.scrollerHeight -= this.scrollBarH.getHeight();
            +            this.scrollBarV.element.style.bottom = this.scrollBarH.getHeight() + "px";
            +
            +            changes = changes | this.CHANGE_SCROLL;
            +        }
            +
            +        if (width && (force || size.width != width)) {
            +            changes |= this.CHANGE_SIZE;
            +            size.width = width;
            +            
            +            if (gutterWidth == null)
            +                gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
            +            
            +            this.gutterWidth = gutterWidth;
            +            
            +            this.scrollBarH.element.style.left = 
            +            this.scroller.style.left = gutterWidth + "px";
            +            size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBarV.getWidth());           
            +            
            +            this.scrollBarH.element.style.right = 
            +            this.scroller.style.right = this.scrollBarV.getWidth() + "px";
            +            this.scroller.style.bottom = this.scrollBarH.getHeight() + "px";
            +
            +            if (this.session && this.session.getUseWrapMode() && this.adjustWrapLimit() || force)
            +                changes |= this.CHANGE_FULL;
            +        }
            +        
            +        size.$dirty = !width || !height;
            +
            +        if (changes)
            +            this._signal("resize", oldSize);
            +
            +        return changes;
            +    };
            +
            +    this.onGutterResize = function() {
            +        var gutterWidth = this.$showGutter ? this.$gutter.offsetWidth : 0;
            +        if (gutterWidth != this.gutterWidth)
            +            this.$changes |= this.$updateCachedSize(true, gutterWidth, this.$size.width, this.$size.height);
            +
            +        if (this.session.getUseWrapMode() && this.adjustWrapLimit()) {
            +            this.$loop.schedule(this.CHANGE_FULL);
            +        } else if (this.$size.$dirty) {
            +            this.$loop.schedule(this.CHANGE_FULL);
            +        } else {
            +            this.$computeLayerConfig();
            +            this.$loop.schedule(this.CHANGE_MARKER);
            +        }
            +    };
            +    this.adjustWrapLimit = function() {
            +        var availableWidth = this.$size.scrollerWidth - this.$padding * 2;
            +        var limit = Math.floor(availableWidth / this.characterWidth);
            +        return this.session.adjustWrapLimit(limit, this.$showPrintMargin && this.$printMarginColumn);
            +    };
            +    this.setAnimatedScroll = function(shouldAnimate){
            +        this.setOption("animatedScroll", shouldAnimate);
            +    };
            +    this.getAnimatedScroll = function() {
            +        return this.$animatedScroll;
            +    };
            +    this.setShowInvisibles = function(showInvisibles) {
            +        this.setOption("showInvisibles", showInvisibles);
            +    };
            +    this.getShowInvisibles = function() {
            +        return this.getOption("showInvisibles");
            +    };
            +    this.getDisplayIndentGuides = function() {
            +        return this.getOption("displayIndentGuides");
            +    };
            +
            +    this.setDisplayIndentGuides = function(display) {
            +        this.setOption("displayIndentGuides", display);
            +    };
            +    this.setShowPrintMargin = function(showPrintMargin) {
            +        this.setOption("showPrintMargin", showPrintMargin);
            +    };
            +    this.getShowPrintMargin = function() {
            +        return this.getOption("showPrintMargin");
            +    };
            +    this.setPrintMarginColumn = function(showPrintMargin) {
            +        this.setOption("printMarginColumn", showPrintMargin);
            +    };
            +    this.getPrintMarginColumn = function() {
            +        return this.getOption("printMarginColumn");
            +    };
            +    this.getShowGutter = function(){
            +        return this.getOption("showGutter");
            +    };
            +    this.setShowGutter = function(show){
            +        return this.setOption("showGutter", show);
            +    };
            +
            +    this.getFadeFoldWidgets = function(){
            +        return this.getOption("fadeFoldWidgets")
            +    };
            +
            +    this.setFadeFoldWidgets = function(show) {
            +        this.setOption("fadeFoldWidgets", show);
            +    };
            +
            +    this.setHighlightGutterLine = function(shouldHighlight) {
            +        this.setOption("highlightGutterLine", shouldHighlight);
            +    };
            +
            +    this.getHighlightGutterLine = function() {
            +        return this.getOption("highlightGutterLine");
            +    };
            +
            +    this.$updateGutterLineHighlight = function() {
            +        var pos = this.$cursorLayer.$pixelPos;
            +        var height = this.layerConfig.lineHeight;
            +        if (this.session.getUseWrapMode()) {
            +            var cursor = this.session.selection.getCursor();
            +            cursor.column = 0;
            +            pos = this.$cursorLayer.getPixelPosition(cursor, true);
            +            height *= this.session.getRowLength(cursor.row);
            +        }
            +        this.$gutterLineHighlight.style.top = pos.top - this.layerConfig.offset + "px";
            +        this.$gutterLineHighlight.style.height = height + "px";
            +    };
            +
            +    this.$updatePrintMargin = function() {
            +        if (!this.$showPrintMargin && !this.$printMarginEl)
            +            return;
            +
            +        if (!this.$printMarginEl) {
            +            var containerEl = dom.createElement("div");
            +            containerEl.className = "ace_layer ace_print-margin-layer";
            +            this.$printMarginEl = dom.createElement("div");
            +            this.$printMarginEl.className = "ace_print-margin";
            +            containerEl.appendChild(this.$printMarginEl);
            +            this.content.insertBefore(containerEl, this.content.firstChild);
            +        }
            +
            +        var style = this.$printMarginEl.style;
            +        style.left = ((this.characterWidth * this.$printMarginColumn) + this.$padding) + "px";
            +        style.visibility = this.$showPrintMargin ? "visible" : "hidden";
            +        
            +        if (this.session && this.session.$wrap == -1)
            +            this.adjustWrapLimit();
            +    };
            +    this.getContainerElement = function() {
            +        return this.container;
            +    };
            +    this.getMouseEventTarget = function() {
            +        return this.content;
            +    };
            +    this.getTextAreaContainer = function() {
            +        return this.container;
            +    };
            +    this.$moveTextAreaToCursor = function() {
            +        if (!this.$keepTextAreaAtCursor)
            +            return;
            +        var config = this.layerConfig;
            +        var posTop = this.$cursorLayer.$pixelPos.top;
            +        var posLeft = this.$cursorLayer.$pixelPos.left;
            +        posTop -= config.offset;
            +
            +        var h = this.lineHeight;
            +        if (posTop < 0 || posTop > config.height - h)
            +            return;
            +
            +        var w = this.characterWidth;
            +        if (this.$composition) {
            +            var val = this.textarea.value.replace(/^\x01+/, "");
            +            w *= (this.session.$getStringScreenWidth(val)[0]+2);
            +            h += 2;
            +            posTop -= 1;
            +        }
            +        posLeft -= this.scrollLeft;
            +        if (posLeft > this.$size.scrollerWidth - w)
            +            posLeft = this.$size.scrollerWidth - w;
            +
            +        posLeft -= this.scrollBar.width;
            +
            +        this.textarea.style.height = h + "px";
            +        this.textarea.style.width = w + "px";
            +        this.textarea.style.right = Math.max(0, this.$size.scrollerWidth - posLeft - w) + "px";
            +        this.textarea.style.bottom = Math.max(0, this.$size.height - posTop - h) + "px";
            +    };
            +    this.getFirstVisibleRow = function() {
            +        return this.layerConfig.firstRow;
            +    };
            +    this.getFirstFullyVisibleRow = function() {
            +        return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1);
            +    };
            +    this.getLastFullyVisibleRow = function() {
            +        var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight);
            +        return this.layerConfig.firstRow - 1 + flint;
            +    };
            +    this.getLastVisibleRow = function() {
            +        return this.layerConfig.lastRow;
            +    };
            +
            +    this.$padding = null;
            +    this.setPadding = function(padding) {
            +        this.$padding = padding;
            +        this.$textLayer.setPadding(padding);
            +        this.$cursorLayer.setPadding(padding);
            +        this.$markerFront.setPadding(padding);
            +        this.$markerBack.setPadding(padding);
            +        this.$loop.schedule(this.CHANGE_FULL);
            +        this.$updatePrintMargin();
            +    };
            +    
            +    this.setScrollMargin = function(top, bottom, left, right) {
            +        var sm = this.scrollMargin;
            +        sm.top = top|0;
            +        sm.bottom = bottom|0;
            +        sm.right = right|0;
            +        sm.left = left|0;
            +        sm.v = sm.top + sm.bottom;
            +        sm.h = sm.left + sm.right;
            +        if (sm.top && this.scrollTop <= 0 && this.session)
            +            this.session.setScrollTop(-sm.top);
            +        this.updateFull();
            +    };
            +    this.getHScrollBarAlwaysVisible = function() {
            +        return this.$hScrollBarAlwaysVisible;
            +    };
            +    this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
            +        this.setOption("hScrollBarAlwaysVisible", alwaysVisible);
            +    };
            +    this.getVScrollBarAlwaysVisible = function() {
            +        return this.$hScrollBarAlwaysVisible;
            +    };
            +    this.setVScrollBarAlwaysVisible = function(alwaysVisible) {
            +        this.setOption("vScrollBarAlwaysVisible", alwaysVisible);
            +    };
            +
            +    this.$updateScrollBarV = function() {
            +        var scrollHeight = this.layerConfig.maxHeight;
            +        var scrollerHeight = this.$size.scrollerHeight;
            +        if (!this.$maxLines && this.$scrollPastEnd) {
            +            scrollHeight -= (scrollerHeight - this.lineHeight) * this.$scrollPastEnd;
            +            if (this.scrollTop > scrollHeight - scrollerHeight) {
            +                scrollHeight = this.scrollTop + scrollerHeight;
            +                this.scrollBarV.scrollTop = null;
            +            }
            +        }
            +        this.scrollBarV.setScrollHeight(scrollHeight + this.scrollMargin.v);
            +        this.scrollBarV.setScrollTop(this.scrollTop + this.scrollMargin.top);
            +    };
            +    this.$updateScrollBarH = function() {
            +        this.scrollBarH.setScrollWidth(this.layerConfig.width + 2 * this.$padding + this.scrollMargin.h);
            +        this.scrollBarH.setScrollLeft(this.scrollLeft + this.scrollMargin.left);
            +    };
            +    
            +    this.$frozen = false;
            +    this.freeze = function() {
            +        this.$frozen = true;
            +    };
            +    
            +    this.unfreeze = function() {
            +        this.$frozen = false;
            +    };
            +
            +    this.$renderChanges = function(changes, force) {
            +        if (this.$changes) {
            +            changes |= this.$changes;
            +            this.$changes = 0;
            +        }
            +        if ((!this.session || !this.container.offsetWidth || this.$frozen) || (!changes && !force)) {
            +            this.$changes |= changes;
            +            return; 
            +        } 
            +        if (this.$size.$dirty) {
            +            this.$changes |= changes;
            +            return this.onResize(true);
            +        }
            +        if (!this.lineHeight) {
            +            this.$textLayer.checkForSizeChanges();
            +        }
            +        
            +        this._signal("beforeRender");
            +        var config = this.layerConfig;
            +        if (changes & this.CHANGE_FULL ||
            +            changes & this.CHANGE_SIZE ||
            +            changes & this.CHANGE_TEXT ||
            +            changes & this.CHANGE_LINES ||
            +            changes & this.CHANGE_SCROLL ||
            +            changes & this.CHANGE_H_SCROLL
            +        ) {
            +            changes |= this.$computeLayerConfig();
            +            config = this.layerConfig;
            +            this.$updateScrollBarV();
            +            if (changes & this.CHANGE_H_SCROLL)
            +                this.$updateScrollBarH();
            +            this.$gutterLayer.element.style.marginTop = (-config.offset) + "px";
            +            this.content.style.marginTop = (-config.offset) + "px";
            +            this.content.style.width = config.width + 2 * this.$padding + "px";
            +            this.content.style.height = config.minHeight + "px";
            +        }
            +        if (changes & this.CHANGE_H_SCROLL) {
            +            this.content.style.marginLeft = -this.scrollLeft + "px";
            +            this.scroller.className = this.scrollLeft <= 0 ? "ace_scroller" : "ace_scroller ace_scroll-left";
            +        }
            +        if (changes & this.CHANGE_FULL) {
            +            this.$textLayer.update(config);
            +            if (this.$showGutter)
            +                this.$gutterLayer.update(config);
            +            this.$markerBack.update(config);
            +            this.$markerFront.update(config);
            +            this.$cursorLayer.update(config);
            +            this.$moveTextAreaToCursor();
            +            this.$highlightGutterLine && this.$updateGutterLineHighlight();
            +            this._signal("afterRender");
            +            return;
            +        }
            +        if (changes & this.CHANGE_SCROLL) {
            +            if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)
            +                this.$textLayer.update(config);
            +            else
            +                this.$textLayer.scrollLines(config);
            +
            +            if (this.$showGutter)
            +                this.$gutterLayer.update(config);
            +            this.$markerBack.update(config);
            +            this.$markerFront.update(config);
            +            this.$cursorLayer.update(config);
            +            this.$highlightGutterLine && this.$updateGutterLineHighlight();
            +            this.$moveTextAreaToCursor();
            +            this._signal("afterRender");
            +            return;
            +        }
            +
            +        if (changes & this.CHANGE_TEXT) {
            +            this.$textLayer.update(config);
            +            if (this.$showGutter)
            +                this.$gutterLayer.update(config);
            +        }
            +        else if (changes & this.CHANGE_LINES) {
            +            if (this.$updateLines() || (changes & this.CHANGE_GUTTER) && this.$showGutter)
            +                this.$gutterLayer.update(config);
            +        }
            +        else if (changes & this.CHANGE_TEXT || changes & this.CHANGE_GUTTER) {
            +            if (this.$showGutter)
            +                this.$gutterLayer.update(config);
            +        }
            +
            +        if (changes & this.CHANGE_CURSOR) {
            +            this.$cursorLayer.update(config);
            +            this.$moveTextAreaToCursor();
            +            this.$highlightGutterLine && this.$updateGutterLineHighlight();
            +        }
            +
            +        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
            +            this.$markerFront.update(config);
            +        }
            +
            +        if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_BACK)) {
            +            this.$markerBack.update(config);
            +        }
            +
            +        this._signal("afterRender");
            +    };
            +
            +    
            +    this.$autosize = function() {
            +        var height = this.session.getScreenLength() * this.lineHeight;
            +        var maxHeight = this.$maxLines * this.lineHeight;
            +        var desiredHeight = Math.max(
            +            (this.$minLines||1) * this.lineHeight,
            +            Math.min(maxHeight, height)
            +        ) + this.scrollMargin.v + (this.$extraHeight || 0);
            +        var vScroll = height > maxHeight;
            +        
            +        if (desiredHeight != this.desiredHeight ||
            +            this.$size.height != this.desiredHeight || vScroll != this.$vScroll) {
            +            if (vScroll != this.$vScroll) {
            +                this.$vScroll = vScroll;
            +                this.scrollBarV.setVisible(vScroll);
            +            }
            +            
            +            var w = this.container.clientWidth;
            +            this.container.style.height = desiredHeight + "px";
            +            this.$updateCachedSize(true, this.$gutterWidth, w, desiredHeight);
            +            this.desiredHeight = desiredHeight;
            +        }
            +    };
            +    
            +    this.$computeLayerConfig = function() {
            +        if (this.$maxLines && this.lineHeight > 1)
            +            this.$autosize();
            +
            +        var session = this.session;
            +        var size = this.$size;
            +        
            +        var hideScrollbars = size.height <= 2 * this.lineHeight;
            +        var screenLines = this.session.getScreenLength();
            +        var maxHeight = screenLines * this.lineHeight;
            +
            +        var offset = this.scrollTop % this.lineHeight;
            +        var minHeight = size.scrollerHeight + this.lineHeight;
            +
            +        var longestLine = this.$getLongestLine();
            +        
            +        var horizScroll = !hideScrollbars && (this.$hScrollBarAlwaysVisible ||
            +            size.scrollerWidth - longestLine - 2 * this.$padding < 0);
            +
            +        var hScrollChanged = this.$horizScroll !== horizScroll;
            +        if (hScrollChanged) {
            +            this.$horizScroll = horizScroll;
            +            this.scrollBarH.setVisible(horizScroll);
            +        }
            +        
            +        if (!this.$maxLines && this.$scrollPastEnd) {
            +            maxHeight += (size.scrollerHeight - this.lineHeight) * this.$scrollPastEnd;
            +        }
            +        
            +        var vScroll = !hideScrollbars && (this.$vScrollBarAlwaysVisible ||
            +            size.scrollerHeight - maxHeight < 0);
            +        var vScrollChanged = this.$vScroll !== vScroll;
            +        if (vScrollChanged) {
            +            this.$vScroll = vScroll;
            +            this.scrollBarV.setVisible(vScroll);
            +        }
            +        
            +        this.session.setScrollTop(Math.max(-this.scrollMargin.top,
            +            Math.min(this.scrollTop, maxHeight - size.scrollerHeight + this.scrollMargin.bottom)));
            +
            +        this.session.setScrollLeft(Math.max(-this.scrollMargin.left, Math.min(this.scrollLeft, 
            +            longestLine + 2 * this.$padding - size.scrollerWidth + this.scrollMargin.right)));
            +
            +        var lineCount = Math.ceil(minHeight / this.lineHeight) - 1;
            +        var firstRow = Math.max(0, Math.round((this.scrollTop - offset) / this.lineHeight));
            +        var lastRow = firstRow + lineCount;
            +        var firstRowScreen, firstRowHeight;
            +        var lineHeight = this.lineHeight;
            +        firstRow = session.screenToDocumentRow(firstRow, 0);
            +        var foldLine = session.getFoldLine(firstRow);
            +        if (foldLine) {
            +            firstRow = foldLine.start.row;
            +        }
            +
            +        firstRowScreen = session.documentToScreenRow(firstRow, 0);
            +        firstRowHeight = session.getRowLength(firstRow) * lineHeight;
            +
            +        lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1);
            +        minHeight = size.scrollerHeight + session.getRowLength(lastRow) * lineHeight +
            +                                                firstRowHeight;
            +
            +        offset = this.scrollTop - firstRowScreen * lineHeight;
            +
            +        var changes = 0;
            +        if (this.layerConfig.width != longestLine) 
            +            changes = this.CHANGE_H_SCROLL;
            +        if (hScrollChanged || vScrollChanged) {
            +            changes = this.$updateCachedSize(true, this.gutterWidth, size.width, size.height);
            +            this._signal("scrollbarVisibilityChanged");
            +            if (vScrollChanged)
            +                longestLine = this.$getLongestLine();
            +        }
            +        
            +        this.layerConfig = {
            +            width : longestLine,
            +            padding : this.$padding,
            +            firstRow : firstRow,
            +            firstRowScreen: firstRowScreen,
            +            lastRow : lastRow,
            +            lineHeight : lineHeight,
            +            characterWidth : this.characterWidth,
            +            minHeight : minHeight,
            +            maxHeight : maxHeight,
            +            offset : offset,
            +            gutterOffset : Math.max(0, Math.ceil((offset + size.height - size.scrollerHeight) / lineHeight)),
            +            height : this.$size.scrollerHeight
            +        };
            +
            +        return changes;
            +    };
            +
            +    this.$updateLines = function() {
            +        var firstRow = this.$changedLines.firstRow;
            +        var lastRow = this.$changedLines.lastRow;
            +        this.$changedLines = null;
            +
            +        var layerConfig = this.layerConfig;
            +
            +        if (firstRow > layerConfig.lastRow + 1) { return; }
            +        if (lastRow < layerConfig.firstRow) { return; }
            +        if (lastRow === Infinity) {
            +            if (this.$showGutter)
            +                this.$gutterLayer.update(layerConfig);
            +            this.$textLayer.update(layerConfig);
            +            return;
            +        }
            +        this.$textLayer.updateLines(layerConfig, firstRow, lastRow);
            +        return true;
            +    };
            +
            +    this.$getLongestLine = function() {
            +        var charCount = this.session.getScreenWidth();
            +        if (this.showInvisibles && !this.session.$useWrapMode)
            +            charCount += 1;
            +
            +        return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth));
            +    };
            +    this.updateFrontMarkers = function() {
            +        this.$markerFront.setMarkers(this.session.getMarkers(true));
            +        this.$loop.schedule(this.CHANGE_MARKER_FRONT);
            +    };
            +    this.updateBackMarkers = function() {
            +        this.$markerBack.setMarkers(this.session.getMarkers());
            +        this.$loop.schedule(this.CHANGE_MARKER_BACK);
            +    };
            +    this.addGutterDecoration = function(row, className){
            +        this.$gutterLayer.addGutterDecoration(row, className);
            +    };
            +    this.removeGutterDecoration = function(row, className){
            +        this.$gutterLayer.removeGutterDecoration(row, className);
            +    };
            +    this.updateBreakpoints = function(rows) {
            +        this.$loop.schedule(this.CHANGE_GUTTER);
            +    };
            +    this.setAnnotations = function(annotations) {
            +        this.$gutterLayer.setAnnotations(annotations);
            +        this.$loop.schedule(this.CHANGE_GUTTER);
            +    };
            +    this.updateCursor = function() {
            +        this.$loop.schedule(this.CHANGE_CURSOR);
            +    };
            +    this.hideCursor = function() {
            +        this.$cursorLayer.hideCursor();
            +    };
            +    this.showCursor = function() {
            +        this.$cursorLayer.showCursor();
            +    };
            +
            +    this.scrollSelectionIntoView = function(anchor, lead, offset) {
            +        this.scrollCursorIntoView(anchor, offset);
            +        this.scrollCursorIntoView(lead, offset);
            +    };
            +    this.scrollCursorIntoView = function(cursor, offset, $viewMargin) {
            +        if (this.$size.scrollerHeight === 0)
            +            return;
            +
            +        var pos = this.$cursorLayer.getPixelPosition(cursor);
            +
            +        var left = pos.left;
            +        var top = pos.top;
            +        
            +        var topMargin = $viewMargin && $viewMargin.top || 0;
            +        var bottomMargin = $viewMargin && $viewMargin.bottom || 0;
            +        
            +        var scrollTop = this.$scrollAnimation ? this.session.getScrollTop() : this.scrollTop;
            +        
            +        if (scrollTop + topMargin > top) {
            +            if (offset)
            +                top -= offset * this.$size.scrollerHeight;
            +            if (top === 0)
            +                top = -this.scrollMargin.top;
            +            this.session.setScrollTop(top);
            +        } else if (scrollTop + this.$size.scrollerHeight - bottomMargin < top + this.lineHeight) {
            +            if (offset)
            +                top += offset * this.$size.scrollerHeight;
            +            this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight);
            +        }
            +
            +        var scrollLeft = this.scrollLeft;
            +
            +        if (scrollLeft > left) {
            +            if (left < this.$padding + 2 * this.layerConfig.characterWidth)
            +                left = -this.scrollMargin.left;
            +            this.session.setScrollLeft(left);
            +        } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
            +            this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
            +        } else if (scrollLeft <= this.$padding && left - scrollLeft < this.characterWidth) {
            +            this.session.setScrollLeft(0);
            +        }
            +    };
            +    this.getScrollTop = function() {
            +        return this.session.getScrollTop();
            +    };
            +    this.getScrollLeft = function() {
            +        return this.session.getScrollLeft();
            +    };
            +    this.getScrollTopRow = function() {
            +        return this.scrollTop / this.lineHeight;
            +    };
            +    this.getScrollBottomRow = function() {
            +        return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1);
            +    };
            +    this.scrollToRow = function(row) {
            +        this.session.setScrollTop(row * this.lineHeight);
            +    };
            +
            +    this.alignCursor = function(cursor, alignment) {
            +        if (typeof cursor == "number")
            +            cursor = {row: cursor, column: 0};
            +
            +        var pos = this.$cursorLayer.getPixelPosition(cursor);
            +        var h = this.$size.scrollerHeight - this.lineHeight;
            +        var offset = pos.top - h * (alignment || 0);
            +
            +        this.session.setScrollTop(offset);
            +        return offset;
            +    };
            +
            +    this.STEPS = 8;
            +    this.$calcSteps = function(fromValue, toValue){
            +        var i = 0;
            +        var l = this.STEPS;
            +        var steps = [];
            +
            +        var func  = function(t, x_min, dx) {
            +            return dx * (Math.pow(t - 1, 3) + 1) + x_min;
            +        };
            +
            +        for (i = 0; i < l; ++i)
            +            steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));
            +
            +        return steps;
            +    };
            +    this.scrollToLine = function(line, center, animate, callback) {
            +        var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0});
            +        var offset = pos.top;
            +        if (center)
            +            offset -= this.$size.scrollerHeight / 2;
            +
            +        var initialScroll = this.scrollTop;
            +        this.session.setScrollTop(offset);
            +        if (animate !== false)
            +            this.animateScrolling(initialScroll, callback);
            +    };
            +
            +    this.animateScrolling = function(fromValue, callback) {
            +        var toValue = this.scrollTop;
            +        if (!this.$animatedScroll)
            +            return;
            +        var _self = this;
            +        
            +        if (fromValue == toValue)
            +            return;
            +        
            +        if (this.$scrollAnimation) {
            +            var oldSteps = this.$scrollAnimation.steps;
            +            if (oldSteps.length) {
            +                fromValue = oldSteps[0];
            +                if (fromValue == toValue)
            +                    return;
            +            }
            +        }
            +        
            +        var steps = _self.$calcSteps(fromValue, toValue);
            +        this.$scrollAnimation = {from: fromValue, to: toValue, steps: steps};
            +
            +        clearInterval(this.$timer);
            +
            +        _self.session.setScrollTop(steps.shift());
            +        _self.session.$scrollTop = toValue;
            +        this.$timer = setInterval(function() {
            +            if (steps.length) {
            +                _self.session.setScrollTop(steps.shift());
            +                _self.session.$scrollTop = toValue;
            +            } else if (toValue != null) {
            +                _self.session.$scrollTop = -1;
            +                _self.session.setScrollTop(toValue);
            +                toValue = null;
            +            } else {
            +                _self.$timer = clearInterval(_self.$timer);
            +                _self.$scrollAnimation = null;
            +                callback && callback();
            +            }
            +        }, 10);
            +    };
            +    this.scrollToY = function(scrollTop) {
            +        if (this.scrollTop !== scrollTop) {
            +            this.$loop.schedule(this.CHANGE_SCROLL);
            +            this.scrollTop = scrollTop;
            +        }
            +    };
            +    this.scrollToX = function(scrollLeft) {
            +        if (this.scrollLeft !== scrollLeft)
            +            this.scrollLeft = scrollLeft;
            +        this.$loop.schedule(this.CHANGE_H_SCROLL);
            +    };
            +    this.scrollTo = function(x, y) {
            +        this.session.setScrollTop(y);
            +        this.session.setScrollLeft(y);
            +    };
            +    this.scrollBy = function(deltaX, deltaY) {
            +        deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY);
            +        deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX);
            +    };
            +    this.isScrollableBy = function(deltaX, deltaY) {
            +        if (deltaY < 0 && this.session.getScrollTop() >= 1 - this.scrollMargin.top)
            +           return true;
            +        if (deltaY > 0 && this.session.getScrollTop() + this.$size.scrollerHeight
            +            - this.layerConfig.maxHeight < -1 + this.scrollMargin.bottom)
            +           return true;
            +        if (deltaX < 0 && this.session.getScrollLeft() >= 1 - this.scrollMargin.left)
            +            return true;
            +        if (deltaX > 0 && this.session.getScrollLeft() + this.$size.scrollerWidth
            +            - this.layerConfig.width < -1 + this.scrollMargin.right)
            +           return true;
            +    };
            +
            +    this.pixelToScreenCoordinates = function(x, y) {
            +        var canvasPos = this.scroller.getBoundingClientRect();
            +
            +        var offset = (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth;
            +        var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);
            +        var col = Math.round(offset);
            +
            +        return {row: row, column: col, side: offset - col > 0 ? 1 : -1};
            +    };
            +
            +    this.screenToTextCoordinates = function(x, y) {
            +        var canvasPos = this.scroller.getBoundingClientRect();
            +
            +        var col = Math.round(
            +            (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth
            +        );
            +
            +        var row = (y + this.scrollTop - canvasPos.top) / this.lineHeight;
            +
            +        return this.session.screenToDocumentPosition(row, Math.max(col, 0));
            +    };
            +    this.textToScreenCoordinates = function(row, column) {
            +        var canvasPos = this.scroller.getBoundingClientRect();
            +        var pos = this.session.documentToScreenPosition(row, column);
            +
            +        var x = this.$padding + Math.round(pos.column * this.characterWidth);
            +        var y = pos.row * this.lineHeight;
            +
            +        return {
            +            pageX: canvasPos.left + x - this.scrollLeft,
            +            pageY: canvasPos.top + y - this.scrollTop
            +        };
            +    };
            +    this.visualizeFocus = function() {
            +        dom.addCssClass(this.container, "ace_focus");
            +    };
            +    this.visualizeBlur = function() {
            +        dom.removeCssClass(this.container, "ace_focus");
            +    };
            +    this.showComposition = function(position) {
            +        if (!this.$composition)
            +            this.$composition = {
            +                keepTextAreaAtCursor: this.$keepTextAreaAtCursor,
            +                cssText: this.textarea.style.cssText
            +            };
            +
            +        this.$keepTextAreaAtCursor = true;
            +        dom.addCssClass(this.textarea, "ace_composition");
            +        this.textarea.style.cssText = "";
            +        this.$moveTextAreaToCursor();
            +    };
            +    this.setCompositionText = function(text) {
            +        this.$moveTextAreaToCursor();
            +    };
            +    this.hideComposition = function() {
            +        if (!this.$composition)
            +            return;
            +
            +        dom.removeCssClass(this.textarea, "ace_composition");
            +        this.$keepTextAreaAtCursor = this.$composition.keepTextAreaAtCursor;
            +        this.textarea.style.cssText = this.$composition.cssText;
            +        this.$composition = null;
            +    };
            +    this.setTheme = function(theme, cb) {
            +        var _self = this;
            +        this.$themeId = theme;
            +        _self._dispatchEvent('themeChange',{theme:theme});
            +
            +        if (!theme || typeof theme == "string") {
            +            var moduleName = theme || this.$options.theme.initialValue;
            +            config.loadModule(["theme", moduleName], afterLoad);
            +        } else {
            +            afterLoad(theme);
            +        }
            +
            +        function afterLoad(module) {
            +            if (_self.$themeId != theme)
            +                return cb && cb();
            +            if (!module.cssClass)
            +                return;
            +            dom.importCssString(
            +                module.cssText,
            +                module.cssClass,
            +                _self.container.ownerDocument
            +            );
            +
            +            if (_self.theme)
            +                dom.removeCssClass(_self.container, _self.theme.cssClass);
            +
            +            var padding = "padding" in module ? module.padding 
            +                : "padding" in (_self.theme || {}) ? 4 : _self.$padding;
            +            if (_self.$padding && padding != _self.$padding)
            +                _self.setPadding(padding);
            +            _self.$theme = module.cssClass;
            +
            +            _self.theme = module;
            +            dom.addCssClass(_self.container, module.cssClass);
            +            dom.setCssClass(_self.container, "ace_dark", module.isDark);
            +            if (_self.$size) {
            +                _self.$size.width = 0;
            +                _self.$updateSizeAsync();
            +            }
            +
            +            _self._dispatchEvent('themeLoaded', {theme:module});
            +            cb && cb();
            +        }
            +    };
            +    this.getTheme = function() {
            +        return this.$themeId;
            +    };
            +    this.setStyle = function(style, include) {
            +        dom.setCssClass(this.container, style, include !== false);
            +    };
            +    this.unsetStyle = function(style) {
            +        dom.removeCssClass(this.container, style);
            +    };
            +    
            +    this.setCursorStyle = function(style) {
            +        if (this.content.style.cursor != style)
            +            this.content.style.cursor = style;
            +    };
            +    this.setMouseCursor = function(cursorStyle) {
            +        this.content.style.cursor = cursorStyle;
            +    };
            +    this.destroy = function() {
            +        this.$textLayer.destroy();
            +        this.$cursorLayer.destroy();
            +    };
            +
            +}).call(VirtualRenderer.prototype);
            +
            +
            +config.defineOptions(VirtualRenderer.prototype, "renderer", {
            +    animatedScroll: {initialValue: false},
            +    showInvisibles: {
            +        set: function(value) {
            +            if (this.$textLayer.setShowInvisibles(value))
            +                this.$loop.schedule(this.CHANGE_TEXT);
            +        },
            +        initialValue: false
            +    },
            +    showPrintMargin: {
            +        set: function() { this.$updatePrintMargin(); },
            +        initialValue: true
            +    },
            +    printMarginColumn: {
            +        set: function() { this.$updatePrintMargin(); },
            +        initialValue: 80
            +    },
            +    printMargin: {
            +        set: function(val) {
            +            if (typeof val == "number")
            +                this.$printMarginColumn = val;
            +            this.$showPrintMargin = !!val;
            +            this.$updatePrintMargin();
            +        },
            +        get: function() {
            +            return this.$showPrintMargin && this.$printMarginColumn; 
            +        }
            +    },
            +    showGutter: {
            +        set: function(show){
            +            this.$gutter.style.display = show ? "block" : "none";
            +            this.$loop.schedule(this.CHANGE_FULL);
            +            this.onGutterResize();
            +        },
            +        initialValue: true
            +    },
            +    fadeFoldWidgets: {
            +        set: function(show) {
            +            dom.setCssClass(this.$gutter, "ace_fade-fold-widgets", show);
            +        },
            +        initialValue: false
            +    },
            +    showFoldWidgets: {
            +        set: function(show) {this.$gutterLayer.setShowFoldWidgets(show)},
            +        initialValue: true
            +    },
            +    showLineNumbers: {
            +        set: function(show) {
            +            this.$gutterLayer.setShowLineNumbers(show);
            +            this.$loop.schedule(this.CHANGE_GUTTER);
            +        },
            +        initialValue: true
            +    },
            +    displayIndentGuides: {
            +        set: function(show) {
            +            if (this.$textLayer.setDisplayIndentGuides(show))
            +                this.$loop.schedule(this.CHANGE_TEXT);
            +        },
            +        initialValue: true
            +    },
            +    highlightGutterLine: {
            +        set: function(shouldHighlight) {
            +            if (!this.$gutterLineHighlight) {
            +                this.$gutterLineHighlight = dom.createElement("div");
            +                this.$gutterLineHighlight.className = "ace_gutter-active-line";
            +                this.$gutter.appendChild(this.$gutterLineHighlight);
            +                return;
            +            }
            +
            +            this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none";
            +            if (this.$cursorLayer.$pixelPos)
            +                this.$updateGutterLineHighlight();
            +        },
            +        initialValue: false,
            +        value: true
            +    },
            +    hScrollBarAlwaysVisible: {
            +        set: function(val) {
            +            if (!this.$hScrollBarAlwaysVisible || !this.$horizScroll)
            +                this.$loop.schedule(this.CHANGE_SCROLL);
            +        },
            +        initialValue: false
            +    },
            +    vScrollBarAlwaysVisible: {
            +        set: function(val) {
            +            if (!this.$vScrollBarAlwaysVisible || !this.$vScroll)
            +                this.$loop.schedule(this.CHANGE_SCROLL);
            +        },
            +        initialValue: false
            +    },
            +    fontSize:  {
            +        set: function(size) {
            +            if (typeof size == "number")
            +                size = size + "px";
            +            this.container.style.fontSize = size;
            +            this.updateFontSize();
            +        },
            +        initialValue: 12
            +    },
            +    fontFamily: {
            +        set: function(name) {
            +            this.container.style.fontFamily = name;
            +            this.updateFontSize();
            +        }
            +    },
            +    maxLines: {
            +        set: function(val) {
            +            this.updateFull();
            +        }
            +    },
            +    minLines: {
            +        set: function(val) {
            +            this.updateFull();
            +        }
            +    },
            +    scrollPastEnd: {
            +        set: function(val) {
            +            val = +val || 0;
            +            if (this.$scrollPastEnd == val)
            +                return;
            +            this.$scrollPastEnd = val;
            +            this.$loop.schedule(this.CHANGE_SCROLL);
            +        },
            +        initialValue: 0,
            +        handlesSet: true
            +    },
            +    fixedWidthGutter: {
            +        set: function(val) {
            +            this.$gutterLayer.$fixedWidth = !!val;
            +            this.$loop.schedule(this.CHANGE_GUTTER);
            +        }
            +    },
            +    theme: {
            +        set: function(val) { this.setTheme(val) },
            +        get: function() { return this.$themeId || this.theme; },
            +        initialValue: "./theme/textmate",
            +        handlesSet: true
            +    }
            +});
            +
            +exports.VirtualRenderer = VirtualRenderer;
            +});
            +
            +define("ace/worker/worker_client",["require","exports","module","ace/lib/oop","ace/lib/net","ace/lib/event_emitter","ace/config"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("../lib/oop");
            +var net = require("../lib/net");
            +var EventEmitter = require("../lib/event_emitter").EventEmitter;
            +var config = require("../config");
            +
            +var WorkerClient = function(topLevelNamespaces, mod, classname, workerUrl) {
            +    this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
            +    this.changeListener = this.changeListener.bind(this);
            +    this.onMessage = this.onMessage.bind(this);
            +    if (require.nameToUrl && !require.toUrl)
            +        require.toUrl = require.nameToUrl;
            +    
            +    if (config.get("packaged") || !require.toUrl) {
            +        workerUrl = workerUrl || config.moduleUrl(mod, "worker");
            +    } else {
            +        var normalizePath = this.$normalizePath;
            +        workerUrl = workerUrl || normalizePath(require.toUrl("ace/worker/worker.js", null, "_"));
            +
            +        var tlns = {};
            +        topLevelNamespaces.forEach(function(ns) {
            +            tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/(\.js)?(\?.*)?$/, ""));
            +        });
            +    }
            +
            +    try {
            +        this.$worker = new Worker(workerUrl);
            +    } catch(e) {
            +        if (e instanceof window.DOMException) {
            +            var blob = this.$workerBlob(workerUrl);
            +            var URL = window.URL || window.webkitURL;
            +            var blobURL = URL.createObjectURL(blob);
            +
            +            this.$worker = new Worker(blobURL);
            +            URL.revokeObjectURL(blobURL);
            +        } else {
            +            throw e;
            +        }
            +    }
            +    this.$worker.postMessage({
            +        init : true,
            +        tlns : tlns,
            +        module : mod,
            +        classname : classname
            +    });
            +
            +    this.callbackId = 1;
            +    this.callbacks = {};
            +
            +    this.$worker.onmessage = this.onMessage;
            +};
            +
            +(function(){
            +
            +    oop.implement(this, EventEmitter);
            +
            +    this.onMessage = function(e) {
            +        var msg = e.data;
            +        switch(msg.type) {
            +            case "log":
            +                window.console && console.log && console.log.apply(console, msg.data);
            +                break;
            +
            +            case "event":
            +                this._signal(msg.name, {data: msg.data});
            +                break;
            +
            +            case "call":
            +                var callback = this.callbacks[msg.id];
            +                if (callback) {
            +                    callback(msg.data);
            +                    delete this.callbacks[msg.id];
            +                }
            +                break;
            +        }
            +    };
            +
            +    this.$normalizePath = function(path) {
            +        return net.qualifyURL(path);
            +    };
            +
            +    this.terminate = function() {
            +        this._signal("terminate", {});
            +        this.deltaQueue = null;
            +        this.$worker.terminate();
            +        this.$worker = null;
            +        this.$doc.removeEventListener("change", this.changeListener);
            +        this.$doc = null;
            +    };
            +
            +    this.send = function(cmd, args) {
            +        this.$worker.postMessage({command: cmd, args: args});
            +    };
            +
            +    this.call = function(cmd, args, callback) {
            +        if (callback) {
            +            var id = this.callbackId++;
            +            this.callbacks[id] = callback;
            +            args.push(id);
            +        }
            +        this.send(cmd, args);
            +    };
            +
            +    this.emit = function(event, data) {
            +        try {
            +            this.$worker.postMessage({event: event, data: {data: data.data}});
            +        }
            +        catch(ex) {
            +            console.error(ex.stack);
            +        }
            +    };
            +
            +    this.attachToDocument = function(doc) {
            +        if(this.$doc)
            +            this.terminate();
            +
            +        this.$doc = doc;
            +        this.call("setValue", [doc.getValue()]);
            +        doc.on("change", this.changeListener);
            +    };
            +
            +    this.changeListener = function(e) {
            +        if (!this.deltaQueue) {
            +            this.deltaQueue = [e.data];
            +            setTimeout(this.$sendDeltaQueue, 0);
            +        } else
            +            this.deltaQueue.push(e.data);
            +    };
            +
            +    this.$sendDeltaQueue = function() {
            +        var q = this.deltaQueue;
            +        if (!q) return;
            +        this.deltaQueue = null;
            +        if (q.length > 20 && q.length > this.$doc.getLength() >> 1) {
            +            this.call("setValue", [this.$doc.getValue()]);
            +        } else
            +            this.emit("change", {data: q});
            +    };
            +
            +    this.$workerBlob = function(workerUrl) {
            +        var script = "importScripts('" + net.qualifyURL(workerUrl) + "');";
            +        try {
            +            return new Blob([script], {"type": "application/javascript"});
            +        } catch (e) { // Backwards-compatibility
            +            var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
            +            var blobBuilder = new BlobBuilder();
            +            blobBuilder.append(script);
            +            return blobBuilder.getBlob("application/javascript");
            +        }
            +    };
            +
            +}).call(WorkerClient.prototype);
            +
            +
            +var UIWorkerClient = function(topLevelNamespaces, mod, classname) {
            +    this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
            +    this.changeListener = this.changeListener.bind(this);
            +    this.callbackId = 1;
            +    this.callbacks = {};
            +    this.messageBuffer = [];
            +
            +    var main = null;
            +    var emitSync = false;
            +    var sender = Object.create(EventEmitter);
            +    var _self = this;
            +
            +    this.$worker = {};
            +    this.$worker.terminate = function() {};
            +    this.$worker.postMessage = function(e) {
            +        _self.messageBuffer.push(e);
            +        if (main) {
            +            if (emitSync)
            +                setTimeout(processNext);
            +            else
            +                processNext();
            +        }
            +    };
            +    this.setEmitSync = function(val) { emitSync = val };
            +
            +    var processNext = function() {
            +        var msg = _self.messageBuffer.shift();
            +        if (msg.command)
            +            main[msg.command].apply(main, msg.args);
            +        else if (msg.event)
            +            sender._signal(msg.event, msg.data);
            +    };
            +
            +    sender.postMessage = function(msg) {
            +        _self.onMessage({data: msg});
            +    };
            +    sender.callback = function(data, callbackId) {
            +        this.postMessage({type: "call", id: callbackId, data: data});
            +    };
            +    sender.emit = function(name, data) {
            +        this.postMessage({type: "event", name: name, data: data});
            +    };
            +
            +    config.loadModule(["worker", mod], function(Main) {
            +        main = new Main[classname](sender);
            +        while (_self.messageBuffer.length)
            +            processNext();
            +    });
            +};
            +
            +UIWorkerClient.prototype = WorkerClient.prototype;
            +
            +exports.UIWorkerClient = UIWorkerClient;
            +exports.WorkerClient = WorkerClient;
            +
            +});
            +
            +define("ace/placeholder",["require","exports","module","ace/range","ace/lib/event_emitter","ace/lib/oop"], function(require, exports, module) {
            +"use strict";
            +
            +var Range = require("./range").Range;
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +var oop = require("./lib/oop");
            +
            +var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) {
            +    var _self = this;
            +    this.length = length;
            +    this.session = session;
            +    this.doc = session.getDocument();
            +    this.mainClass = mainClass;
            +    this.othersClass = othersClass;
            +    this.$onUpdate = this.onUpdate.bind(this);
            +    this.doc.on("change", this.$onUpdate);
            +    this.$others = others;
            +    
            +    this.$onCursorChange = function() {
            +        setTimeout(function() {
            +            _self.onCursorChange();
            +        });
            +    };
            +    
            +    this.$pos = pos;
            +    var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1};
            +    this.$undoStackDepth =  undoStack.length;
            +    this.setup();
            +
            +    session.selection.on("changeCursor", this.$onCursorChange);
            +};
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +    this.setup = function() {
            +        var _self = this;
            +        var doc = this.doc;
            +        var session = this.session;
            +        var pos = this.$pos;
            +
            +        this.pos = doc.createAnchor(pos.row, pos.column);
            +        this.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);
            +        this.pos.on("change", function(event) {
            +            session.removeMarker(_self.markerId);
            +            _self.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.mainClass, null, false);
            +        });
            +        this.others = [];
            +        this.$others.forEach(function(other) {
            +            var anchor = doc.createAnchor(other.row, other.column);
            +            _self.others.push(anchor);
            +        });
            +        session.setUndoSelect(false);
            +    };
            +    this.showOtherMarkers = function() {
            +        if(this.othersActive) return;
            +        var session = this.session;
            +        var _self = this;
            +        this.othersActive = true;
            +        this.others.forEach(function(anchor) {
            +            anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false);
            +            anchor.on("change", function(event) {
            +                session.removeMarker(anchor.markerId);
            +                anchor.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.othersClass, null, false);
            +            });
            +        });
            +    };
            +    this.hideOtherMarkers = function() {
            +        if(!this.othersActive) return;
            +        this.othersActive = false;
            +        for (var i = 0; i < this.others.length; i++) {
            +            this.session.removeMarker(this.others[i].markerId);
            +        }
            +    };
            +    this.onUpdate = function(event) {
            +        var delta = event.data;
            +        var range = delta.range;
            +        if(range.start.row !== range.end.row) return;
            +        if(range.start.row !== this.pos.row) return;
            +        if (this.$updating) return;
            +        this.$updating = true;
            +        var lengthDiff = delta.action === "insertText" ? range.end.column - range.start.column : range.start.column - range.end.column;
            +        
            +        if(range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1) {
            +            var distanceFromStart = range.start.column - this.pos.column;
            +            this.length += lengthDiff;
            +            if(!this.session.$fromUndo) {
            +                if(delta.action === "insertText") {
            +                    for (var i = this.others.length - 1; i >= 0; i--) {
            +                        var otherPos = this.others[i];
            +                        var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
            +                        if(otherPos.row === range.start.row && range.start.column < otherPos.column)
            +                            newPos.column += lengthDiff;
            +                        this.doc.insert(newPos, delta.text);
            +                    }
            +                } else if(delta.action === "removeText") {
            +                    for (var i = this.others.length - 1; i >= 0; i--) {
            +                        var otherPos = this.others[i];
            +                        var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
            +                        if(otherPos.row === range.start.row && range.start.column < otherPos.column)
            +                            newPos.column += lengthDiff;
            +                        this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));
            +                    }
            +                }
            +                if(range.start.column === this.pos.column && delta.action === "insertText") {
            +                    setTimeout(function() {
            +                        this.pos.setPosition(this.pos.row, this.pos.column - lengthDiff);
            +                        for (var i = 0; i < this.others.length; i++) {
            +                            var other = this.others[i];
            +                            var newPos = {row: other.row, column: other.column - lengthDiff};
            +                            if(other.row === range.start.row && range.start.column < other.column)
            +                                newPos.column += lengthDiff;
            +                            other.setPosition(newPos.row, newPos.column);
            +                        }
            +                    }.bind(this), 0);
            +                }
            +                else if(range.start.column === this.pos.column && delta.action === "removeText") {
            +                    setTimeout(function() {
            +                        for (var i = 0; i < this.others.length; i++) {
            +                            var other = this.others[i];
            +                            if(other.row === range.start.row && range.start.column < other.column) {
            +                                other.setPosition(other.row, other.column - lengthDiff);
            +                            }
            +                        }
            +                    }.bind(this), 0);
            +                }
            +            }
            +            this.pos._emit("change", {value: this.pos});
            +            for (var i = 0; i < this.others.length; i++) {
            +                this.others[i]._emit("change", {value: this.others[i]});
            +            }
            +        }
            +        this.$updating = false;
            +    };
            +
            +    this.onCursorChange = function(event) {
            +        if (this.$updating) return;
            +        var pos = this.session.selection.getCursor();
            +        if(pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {
            +            this.showOtherMarkers();
            +            this._emit("cursorEnter", event);
            +        } else {
            +            this.hideOtherMarkers();
            +            this._emit("cursorLeave", event);
            +        }
            +    };    
            +    this.detach = function() {
            +        this.session.removeMarker(this.markerId);
            +        this.hideOtherMarkers();
            +        this.doc.removeEventListener("change", this.$onUpdate);
            +        this.session.selection.removeEventListener("changeCursor", this.$onCursorChange);
            +        this.pos.detach();
            +        for (var i = 0; i < this.others.length; i++) {
            +            this.others[i].detach();
            +        }
            +        this.session.setUndoSelect(true);
            +    };
            +    this.cancel = function() {
            +        if(this.$undoStackDepth === -1)
            +            throw Error("Canceling placeholders only supported with undo manager attached to session.");
            +        var undoManager = this.session.getUndoManager();
            +        var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth;
            +        for (var i = 0; i < undosRequired; i++) {
            +            undoManager.undo(true);
            +        }
            +    };
            +}).call(PlaceHolder.prototype);
            +
            +
            +exports.PlaceHolder = PlaceHolder;
            +});
            +
            +define("ace/mouse/multi_select_handler",["require","exports","module","ace/lib/event","ace/lib/useragent"], function(require, exports, module) {
            +
            +var event = require("../lib/event");
            +var useragent = require("../lib/useragent");
            +function isSamePoint(p1, p2) {
            +    return p1.row == p2.row && p1.column == p2.column;
            +}
            +
            +function onMouseDown(e) {
            +    var ev = e.domEvent;
            +    var alt = ev.altKey;
            +    var shift = ev.shiftKey;
            +    var ctrl = ev.ctrlKey;
            +    var accel = e.getAccelKey();
            +    var button = e.getButton();
            +    
            +    if (ctrl && useragent.isMac)
            +        button = ev.button;
            +
            +    if (e.editor.inMultiSelectMode && button == 2) {
            +        e.editor.textInput.onContextMenu(e.domEvent);
            +        return;
            +    }
            +    
            +    if (!ctrl && !alt && !accel) {
            +        if (button === 0 && e.editor.inMultiSelectMode)
            +            e.editor.exitMultiSelectMode();
            +        return;
            +    }
            +    
            +    if (button !== 0)
            +        return;
            +
            +    var editor = e.editor;
            +    var selection = editor.selection;
            +    var isMultiSelect = editor.inMultiSelectMode;
            +    var pos = e.getDocumentPosition();
            +    var cursor = selection.getCursor();
            +    var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
            +
            +    var mouseX = e.x, mouseY = e.y;
            +    var onMouseSelection = function(e) {
            +        mouseX = e.clientX;
            +        mouseY = e.clientY;
            +    };
            +    
            +    var session = editor.session;
            +    var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
            +    var screenCursor = screenAnchor;
            +    
            +    var selectionMode;
            +    if (editor.$mouseHandler.$enableJumpToDef) {
            +        if (ctrl && alt || accel && alt)
            +            selectionMode = "add";
            +        else if (alt)
            +            selectionMode = "block";
            +    } else {
            +        if (accel && !alt) {
            +            selectionMode = "add";
            +            if (!isMultiSelect && shift)
            +                return;
            +        } else if (alt) {
            +            selectionMode = "block";
            +        }
            +    }
            +    
            +    if (selectionMode && useragent.isMac && ev.ctrlKey) {
            +        editor.$mouseHandler.cancelContextMenu();
            +    }
            +
            +    if (selectionMode == "add") {
            +        if (!isMultiSelect && inSelection)
            +            return; // dragging
            +
            +        if (!isMultiSelect) {
            +            var range = selection.toOrientedRange();
            +            editor.addSelectionMarker(range);
            +        }
            +
            +        var oldRange = selection.rangeList.rangeAtPoint(pos);
            +        
            +        
            +        editor.$blockScrolling++;
            +        editor.inVirtualSelectionMode = true;
            +        
            +        if (shift) {
            +            oldRange = null;
            +            range = selection.ranges[0];
            +            editor.removeSelectionMarker(range);
            +        }
            +        editor.once("mouseup", function() {
            +            var tmpSel = selection.toOrientedRange();
            +
            +            if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))
            +                selection.substractPoint(tmpSel.cursor);
            +            else {
            +                if (shift) {
            +                    selection.substractPoint(range.cursor);
            +                } else if (range) {
            +                    editor.removeSelectionMarker(range);
            +                    selection.addRange(range);
            +                }
            +                selection.addRange(tmpSel);
            +            }
            +            editor.$blockScrolling--;
            +            editor.inVirtualSelectionMode = false;
            +        });
            +
            +    } else if (selectionMode == "block") {
            +        e.stop();
            +        editor.inVirtualSelectionMode = true;        
            +        var initialRange;
            +        var rectSel = [];
            +        var blockSelect = function() {
            +            var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
            +            var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column);
            +
            +            if (isSamePoint(screenCursor, newCursor) && isSamePoint(cursor, selection.lead))
            +                return;
            +            screenCursor = newCursor;
            +
            +            editor.selection.moveToPosition(cursor);
            +            editor.renderer.scrollCursorIntoView();
            +
            +            editor.removeSelectionMarkers(rectSel);
            +            rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
            +            if (editor.$mouseHandler.$clickSelection && rectSel.length == 1 && rectSel[0].isEmpty())
            +                rectSel[0] = editor.$mouseHandler.$clickSelection.clone();
            +            rectSel.forEach(editor.addSelectionMarker, editor);
            +            editor.updateSelectionMarkers();
            +        };
            +        
            +        if (isMultiSelect && !accel) {
            +            selection.toSingleRange();
            +        } else if (!isMultiSelect && accel) {
            +            initialRange = selection.toOrientedRange();
            +            editor.addSelectionMarker(initialRange);
            +        }
            +        
            +        if (shift)
            +            screenAnchor = session.documentToScreenPosition(selection.lead);            
            +        else
            +            selection.moveToPosition(pos);
            +        
            +        screenCursor = {row: -1, column: -1};
            +
            +        var onMouseSelectionEnd = function(e) {
            +            clearInterval(timerId);
            +            editor.removeSelectionMarkers(rectSel);
            +            if (!rectSel.length)
            +                rectSel = [selection.toOrientedRange()];
            +            editor.$blockScrolling++;
            +            if (initialRange) {
            +                editor.removeSelectionMarker(initialRange);
            +                selection.toSingleRange(initialRange);
            +            }
            +            for (var i = 0; i < rectSel.length; i++)
            +                selection.addRange(rectSel[i]);
            +            editor.inVirtualSelectionMode = false;
            +            editor.$mouseHandler.$clickSelection = null;
            +            editor.$blockScrolling--;
            +        };
            +
            +        var onSelectionInterval = blockSelect;
            +
            +        event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
            +        var timerId = setInterval(function() {onSelectionInterval();}, 20);
            +
            +        return e.preventDefault();
            +    }
            +}
            +
            +
            +exports.onMouseDown = onMouseDown;
            +
            +});
            +
            +define("ace/commands/multi_select_commands",["require","exports","module","ace/keyboard/hash_handler"], function(require, exports, module) {
            +exports.defaultCommands = [{
            +    name: "addCursorAbove",
            +    exec: function(editor) { editor.selectMoreLines(-1); },
            +    bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
            +    readonly: true
            +}, {
            +    name: "addCursorBelow",
            +    exec: function(editor) { editor.selectMoreLines(1); },
            +    bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
            +    readonly: true
            +}, {
            +    name: "addCursorAboveSkipCurrent",
            +    exec: function(editor) { editor.selectMoreLines(-1, true); },
            +    bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
            +    readonly: true
            +}, {
            +    name: "addCursorBelowSkipCurrent",
            +    exec: function(editor) { editor.selectMoreLines(1, true); },
            +    bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"},
            +    readonly: true
            +}, {
            +    name: "selectMoreBefore",
            +    exec: function(editor) { editor.selectMore(-1); },
            +    bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
            +    readonly: true
            +}, {
            +    name: "selectMoreAfter",
            +    exec: function(editor) { editor.selectMore(1); },
            +    bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
            +    readonly: true
            +}, {
            +    name: "selectNextBefore",
            +    exec: function(editor) { editor.selectMore(-1, true); },
            +    bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
            +    readonly: true
            +}, {
            +    name: "selectNextAfter",
            +    exec: function(editor) { editor.selectMore(1, true); },
            +    bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
            +    readonly: true
            +}, {
            +    name: "splitIntoLines",
            +    exec: function(editor) { editor.multiSelect.splitIntoLines(); },
            +    bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"},
            +    readonly: true
            +}, {
            +    name: "alignCursors",
            +    exec: function(editor) { editor.alignCursors(); },
            +    bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"}
            +}, {
            +    name: "findAll",
            +    exec: function(editor) { editor.findAll(); },
            +    bindKey: {win: "Ctrl-Alt-K", mac: "Ctrl-Alt-G"},
            +    readonly: true
            +}];
            +exports.multiSelectCommands = [{
            +    name: "singleSelection",
            +    bindKey: "esc",
            +    exec: function(editor) { editor.exitMultiSelectMode(); },
            +    readonly: true,
            +    isAvailable: function(editor) {return editor && editor.inMultiSelectMode}
            +}];
            +
            +var HashHandler = require("../keyboard/hash_handler").HashHandler;
            +exports.keyboardHandler = new HashHandler(exports.multiSelectCommands);
            +
            +});
            +
            +define("ace/multi_select",["require","exports","module","ace/range_list","ace/range","ace/selection","ace/mouse/multi_select_handler","ace/lib/event","ace/lib/lang","ace/commands/multi_select_commands","ace/search","ace/edit_session","ace/editor","ace/config"], function(require, exports, module) {
            +
            +var RangeList = require("./range_list").RangeList;
            +var Range = require("./range").Range;
            +var Selection = require("./selection").Selection;
            +var onMouseDown = require("./mouse/multi_select_handler").onMouseDown;
            +var event = require("./lib/event");
            +var lang = require("./lib/lang");
            +var commands = require("./commands/multi_select_commands");
            +exports.commands = commands.defaultCommands.concat(commands.multiSelectCommands);
            +var Search = require("./search").Search;
            +var search = new Search();
            +
            +function find(session, needle, dir) {
            +    search.$options.wrap = true;
            +    search.$options.needle = needle;
            +    search.$options.backwards = dir == -1;
            +    return search.find(session);
            +}
            +var EditSession = require("./edit_session").EditSession;
            +(function() {
            +    this.getSelectionMarkers = function() {
            +        return this.$selectionMarkers;
            +    };
            +}).call(EditSession.prototype);
            +(function() {
            +    this.ranges = null;
            +    this.rangeList = null;
            +    this.addRange = function(range, $blockChangeEvents) {
            +        if (!range)
            +            return;
            +
            +        if (!this.inMultiSelectMode && this.rangeCount === 0) {
            +            var oldRange = this.toOrientedRange();
            +            this.rangeList.add(oldRange);
            +            this.rangeList.add(range);
            +            if (this.rangeList.ranges.length != 2) {
            +                this.rangeList.removeAll();
            +                return $blockChangeEvents || this.fromOrientedRange(range);
            +            }
            +            this.rangeList.removeAll();
            +            this.rangeList.add(oldRange);
            +            this.$onAddRange(oldRange);
            +        }
            +
            +        if (!range.cursor)
            +            range.cursor = range.end;
            +
            +        var removed = this.rangeList.add(range);
            +
            +        this.$onAddRange(range);
            +
            +        if (removed.length)
            +            this.$onRemoveRange(removed);
            +
            +        if (this.rangeCount > 1 && !this.inMultiSelectMode) {
            +            this._signal("multiSelect");
            +            this.inMultiSelectMode = true;
            +            this.session.$undoSelect = false;
            +            this.rangeList.attach(this.session);
            +        }
            +
            +        return $blockChangeEvents || this.fromOrientedRange(range);
            +    };
            +
            +    this.toSingleRange = function(range) {
            +        range = range || this.ranges[0];
            +        var removed = this.rangeList.removeAll();
            +        if (removed.length)
            +            this.$onRemoveRange(removed);
            +
            +        range && this.fromOrientedRange(range);
            +    };
            +    this.substractPoint = function(pos) {
            +        var removed = this.rangeList.substractPoint(pos);
            +        if (removed) {
            +            this.$onRemoveRange(removed);
            +            return removed[0];
            +        }
            +    };
            +    this.mergeOverlappingRanges = function() {
            +        var removed = this.rangeList.merge();
            +        if (removed.length)
            +            this.$onRemoveRange(removed);
            +        else if(this.ranges[0])
            +            this.fromOrientedRange(this.ranges[0]);
            +    };
            +
            +    this.$onAddRange = function(range) {
            +        this.rangeCount = this.rangeList.ranges.length;
            +        this.ranges.unshift(range);
            +        this._signal("addRange", {range: range});
            +    };
            +
            +    this.$onRemoveRange = function(removed) {
            +        this.rangeCount = this.rangeList.ranges.length;
            +        if (this.rangeCount == 1 && this.inMultiSelectMode) {
            +            var lastRange = this.rangeList.ranges.pop();
            +            removed.push(lastRange);
            +            this.rangeCount = 0;
            +        }
            +
            +        for (var i = removed.length; i--; ) {
            +            var index = this.ranges.indexOf(removed[i]);
            +            this.ranges.splice(index, 1);
            +        }
            +
            +        this._signal("removeRange", {ranges: removed});
            +
            +        if (this.rangeCount === 0 && this.inMultiSelectMode) {
            +            this.inMultiSelectMode = false;
            +            this._signal("singleSelect");
            +            this.session.$undoSelect = true;
            +            this.rangeList.detach(this.session);
            +        }
            +
            +        lastRange = lastRange || this.ranges[0];
            +        if (lastRange && !lastRange.isEqual(this.getRange()))
            +            this.fromOrientedRange(lastRange);
            +    };
            +    this.$initRangeList = function() {
            +        if (this.rangeList)
            +            return;
            +
            +        this.rangeList = new RangeList();
            +        this.ranges = [];
            +        this.rangeCount = 0;
            +    };
            +    this.getAllRanges = function() {
            +        return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()];
            +    };
            +
            +    this.splitIntoLines = function () {
            +        if (this.rangeCount > 1) {
            +            var ranges = this.rangeList.ranges;
            +            var lastRange = ranges[ranges.length - 1];
            +            var range = Range.fromPoints(ranges[0].start, lastRange.end);
            +
            +            this.toSingleRange();
            +            this.setSelectionRange(range, lastRange.cursor == lastRange.start);
            +        } else {
            +            var range = this.getRange();
            +            var isBackwards = this.isBackwards();
            +            var startRow = range.start.row;
            +            var endRow = range.end.row;
            +            if (startRow == endRow) {
            +                if (isBackwards)
            +                    var start = range.end, end = range.start;
            +                else
            +                    var start = range.start, end = range.end;
            +                
            +                this.addRange(Range.fromPoints(end, end));
            +                this.addRange(Range.fromPoints(start, start));
            +                return;
            +            }
            +
            +            var rectSel = [];
            +            var r = this.getLineRange(startRow, true);
            +            r.start.column = range.start.column;
            +            rectSel.push(r);
            +
            +            for (var i = startRow + 1; i < endRow; i++)
            +                rectSel.push(this.getLineRange(i, true));
            +
            +            r = this.getLineRange(endRow, true);
            +            r.end.column = range.end.column;
            +            rectSel.push(r);
            +
            +            rectSel.forEach(this.addRange, this);
            +        }
            +    };
            +    this.toggleBlockSelection = function () {
            +        if (this.rangeCount > 1) {
            +            var ranges = this.rangeList.ranges;
            +            var lastRange = ranges[ranges.length - 1];
            +            var range = Range.fromPoints(ranges[0].start, lastRange.end);
            +
            +            this.toSingleRange();
            +            this.setSelectionRange(range, lastRange.cursor == lastRange.start);
            +        } else {
            +            var cursor = this.session.documentToScreenPosition(this.selectionLead);
            +            var anchor = this.session.documentToScreenPosition(this.selectionAnchor);
            +
            +            var rectSel = this.rectangularRangeBlock(cursor, anchor);
            +            rectSel.forEach(this.addRange, this);
            +        }
            +    };
            +    this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
            +        var rectSel = [];
            +
            +        var xBackwards = screenCursor.column < screenAnchor.column;
            +        if (xBackwards) {
            +            var startColumn = screenCursor.column;
            +            var endColumn = screenAnchor.column;
            +        } else {
            +            var startColumn = screenAnchor.column;
            +            var endColumn = screenCursor.column;
            +        }
            +
            +        var yBackwards = screenCursor.row < screenAnchor.row;
            +        if (yBackwards) {
            +            var startRow = screenCursor.row;
            +            var endRow = screenAnchor.row;
            +        } else {
            +            var startRow = screenAnchor.row;
            +            var endRow = screenCursor.row;
            +        }
            +
            +        if (startColumn < 0)
            +            startColumn = 0;
            +        if (startRow < 0)
            +            startRow = 0;
            +
            +        if (startRow == endRow)
            +            includeEmptyLines = true;
            +
            +        for (var row = startRow; row <= endRow; row++) {
            +            var range = Range.fromPoints(
            +                this.session.screenToDocumentPosition(row, startColumn),
            +                this.session.screenToDocumentPosition(row, endColumn)
            +            );
            +            if (range.isEmpty()) {
            +                if (docEnd && isSamePoint(range.end, docEnd))
            +                    break;
            +                var docEnd = range.end;
            +            }
            +            range.cursor = xBackwards ? range.start : range.end;
            +            rectSel.push(range);
            +        }
            +
            +        if (yBackwards)
            +            rectSel.reverse();
            +
            +        if (!includeEmptyLines) {
            +            var end = rectSel.length - 1;
            +            while (rectSel[end].isEmpty() && end > 0)
            +                end--;
            +            if (end > 0) {
            +                var start = 0;
            +                while (rectSel[start].isEmpty())
            +                    start++;
            +            }
            +            for (var i = end; i >= start; i--) {
            +                if (rectSel[i].isEmpty())
            +                    rectSel.splice(i, 1);
            +            }
            +        }
            +
            +        return rectSel;
            +    };
            +}).call(Selection.prototype);
            +var Editor = require("./editor").Editor;
            +(function() {
            +    this.updateSelectionMarkers = function() {
            +        this.renderer.updateCursor();
            +        this.renderer.updateBackMarkers();
            +    };
            +    this.addSelectionMarker = function(orientedRange) {
            +        if (!orientedRange.cursor)
            +            orientedRange.cursor = orientedRange.end;
            +
            +        var style = this.getSelectionStyle();
            +        orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style);
            +
            +        this.session.$selectionMarkers.push(orientedRange);
            +        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
            +        return orientedRange;
            +    };
            +    this.removeSelectionMarker = function(range) {
            +        if (!range.marker)
            +            return;
            +        this.session.removeMarker(range.marker);
            +        var index = this.session.$selectionMarkers.indexOf(range);
            +        if (index != -1)
            +            this.session.$selectionMarkers.splice(index, 1);
            +        this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
            +    };
            +
            +    this.removeSelectionMarkers = function(ranges) {
            +        var markerList = this.session.$selectionMarkers;
            +        for (var i = ranges.length; i--; ) {
            +            var range = ranges[i];
            +            if (!range.marker)
            +                continue;
            +            this.session.removeMarker(range.marker);
            +            var index = markerList.indexOf(range);
            +            if (index != -1)
            +                markerList.splice(index, 1);
            +        }
            +        this.session.selectionMarkerCount = markerList.length;
            +    };
            +
            +    this.$onAddRange = function(e) {
            +        this.addSelectionMarker(e.range);
            +        this.renderer.updateCursor();
            +        this.renderer.updateBackMarkers();
            +    };
            +
            +    this.$onRemoveRange = function(e) {
            +        this.removeSelectionMarkers(e.ranges);
            +        this.renderer.updateCursor();
            +        this.renderer.updateBackMarkers();
            +    };
            +
            +    this.$onMultiSelect = function(e) {
            +        if (this.inMultiSelectMode)
            +            return;
            +        this.inMultiSelectMode = true;
            +
            +        this.setStyle("ace_multiselect");
            +        this.keyBinding.addKeyboardHandler(commands.keyboardHandler);
            +        this.commands.setDefaultHandler("exec", this.$onMultiSelectExec);
            +
            +        this.renderer.updateCursor();
            +        this.renderer.updateBackMarkers();
            +    };
            +
            +    this.$onSingleSelect = function(e) {
            +        if (this.session.multiSelect.inVirtualMode)
            +            return;
            +        this.inMultiSelectMode = false;
            +
            +        this.unsetStyle("ace_multiselect");
            +        this.keyBinding.removeKeyboardHandler(commands.keyboardHandler);
            +
            +        this.commands.removeDefaultHandler("exec", this.$onMultiSelectExec);
            +        this.renderer.updateCursor();
            +        this.renderer.updateBackMarkers();
            +        this._emit("changeSelection");
            +    };
            +
            +    this.$onMultiSelectExec = function(e) {
            +        var command = e.command;
            +        var editor = e.editor;
            +        if (!editor.multiSelect)
            +            return;
            +        if (!command.multiSelectAction) {
            +            var result = command.exec(editor, e.args || {});
            +            editor.multiSelect.addRange(editor.multiSelect.toOrientedRange());
            +            editor.multiSelect.mergeOverlappingRanges();
            +        } else if (command.multiSelectAction == "forEach") {
            +            result = editor.forEachSelection(command, e.args);
            +        } else if (command.multiSelectAction == "forEachLine") {
            +            result = editor.forEachSelection(command, e.args, true);
            +        } else if (command.multiSelectAction == "single") {
            +            editor.exitMultiSelectMode();
            +            result = command.exec(editor, e.args || {});
            +        } else {
            +            result = command.multiSelectAction(editor, e.args || {});
            +        }
            +        return result;
            +    }; 
            +    this.forEachSelection = function(cmd, args, options) {
            +        if (this.inVirtualSelectionMode)
            +            return;
            +        var keepOrder = options && options.keepOrder;
            +        var $byLines = options == true || options && options.$byLines
            +        var session = this.session;
            +        var selection = this.selection;
            +        var rangeList = selection.rangeList;
            +        var ranges = (keepOrder ? selection : rangeList).ranges;
            +        var result;
            +        
            +        if (!ranges.length)
            +            return cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});
            +        
            +        var reg = selection._eventRegistry;
            +        selection._eventRegistry = {};
            +
            +        var tmpSel = new Selection(session);
            +        this.inVirtualSelectionMode = true;
            +        for (var i = ranges.length; i--;) {
            +            if ($byLines) {
            +                while (i > 0 && ranges[i].start.row == ranges[i - 1].end.row)
            +                    i--;
            +            }
            +            tmpSel.fromOrientedRange(ranges[i]);
            +            tmpSel.index = i;
            +            this.selection = session.selection = tmpSel;
            +            var cmdResult = cmd.exec ? cmd.exec(this, args || {}) : cmd(this, args || {});
            +            if (!result && cmdResult !== undefined)
            +                result = cmdResult;
            +            tmpSel.toOrientedRange(ranges[i]);
            +        }
            +        tmpSel.detach();
            +
            +        this.selection = session.selection = selection;
            +        this.inVirtualSelectionMode = false;
            +        selection._eventRegistry = reg;
            +        selection.mergeOverlappingRanges();
            +        
            +        var anim = this.renderer.$scrollAnimation;
            +        this.onCursorChange();
            +        this.onSelectionChange();
            +        if (anim && anim.from == anim.to)
            +            this.renderer.animateScrolling(anim.from);
            +        
            +        return result;
            +    };
            +    this.exitMultiSelectMode = function() {
            +        if (!this.inMultiSelectMode || this.inVirtualSelectionMode)
            +            return;
            +        this.multiSelect.toSingleRange();
            +    };
            +
            +    this.getSelectedText = function() {
            +        var text = "";
            +        if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
            +            var ranges = this.multiSelect.rangeList.ranges;
            +            var buf = [];
            +            for (var i = 0; i < ranges.length; i++) {
            +                buf.push(this.session.getTextRange(ranges[i]));
            +            }
            +            var nl = this.session.getDocument().getNewLineCharacter();
            +            text = buf.join(nl);
            +            if (text.length == (buf.length - 1) * nl.length)
            +                text = "";
            +        } else if (!this.selection.isEmpty()) {
            +            text = this.session.getTextRange(this.getSelectionRange());
            +        }
            +        return text;
            +    };
            +    
            +    this.$checkMultiselectChange = function(e, anchor) {
            +        if (this.inMultiSelectMode && !this.inVirtualSelectionMode) {
            +            var range = this.multiSelect.ranges[0];
            +            if (this.multiSelect.isEmpty() && anchor == this.multiSelect.anchor)
            +                return;
            +            var pos = anchor == this.multiSelect.anchor
            +                ? range.cursor == range.start ? range.end : range.start
            +                : range.cursor;
            +            if (!isSamePoint(pos, anchor))
            +                this.multiSelect.toSingleRange(this.multiSelect.toOrientedRange());
            +        }
            +    };
            +    this.onPaste = function(text) {
            +        if (this.$readOnly)
            +            return;
            +
            +
            +        var e = {text: text};
            +        this._signal("paste", e);
            +        text = e.text;
            +        if (!this.inMultiSelectMode || this.inVirtualSelectionMode)
            +            return this.insert(text);
            +
            +        var lines = text.split(/\r\n|\r|\n/);
            +        var ranges = this.selection.rangeList.ranges;
            +
            +        if (lines.length > ranges.length || lines.length < 2 || !lines[1])
            +            return this.commands.exec("insertstring", this, text);
            +
            +        for (var i = ranges.length; i--;) {
            +            var range = ranges[i];
            +            if (!range.isEmpty())
            +                this.session.remove(range);
            +
            +            this.session.insert(range.start, lines[i]);
            +        }
            +    };
            +    this.findAll = function(needle, options, additive) {
            +        options = options || {};
            +        options.needle = needle || options.needle;
            +        if (options.needle == undefined) {
            +            var range = this.selection.isEmpty()
            +                ? this.selection.getWordRange()
            +                : this.selection.getRange();
            +            options.needle = this.session.getTextRange(range);
            +        }    
            +        this.$search.set(options);
            +        
            +        var ranges = this.$search.findAll(this.session);
            +        if (!ranges.length)
            +            return 0;
            +
            +        this.$blockScrolling += 1;
            +        var selection = this.multiSelect;
            +
            +        if (!additive)
            +            selection.toSingleRange(ranges[0]);
            +
            +        for (var i = ranges.length; i--; )
            +            selection.addRange(ranges[i], true);
            +        if (range && selection.rangeList.rangeAtPoint(range.start))
            +            selection.addRange(range, true);
            +        
            +        this.$blockScrolling -= 1;
            +
            +        return ranges.length;
            +    };
            +    this.selectMoreLines = function(dir, skip) {
            +        var range = this.selection.toOrientedRange();
            +        var isBackwards = range.cursor == range.end;
            +
            +        var screenLead = this.session.documentToScreenPosition(range.cursor);
            +        if (this.selection.$desiredColumn)
            +            screenLead.column = this.selection.$desiredColumn;
            +
            +        var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
            +
            +        if (!range.isEmpty()) {
            +            var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);
            +            var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
            +        } else {
            +            var anchor = lead;
            +        }
            +
            +        if (isBackwards) {
            +            var newRange = Range.fromPoints(lead, anchor);
            +            newRange.cursor = newRange.start;
            +        } else {
            +            var newRange = Range.fromPoints(anchor, lead);
            +            newRange.cursor = newRange.end;
            +        }
            +
            +        newRange.desiredColumn = screenLead.column;
            +        if (!this.selection.inMultiSelectMode) {
            +            this.selection.addRange(range);
            +        } else {
            +            if (skip)
            +                var toRemove = range.cursor;
            +        }
            +
            +        this.selection.addRange(newRange);
            +        if (toRemove)
            +            this.selection.substractPoint(toRemove);
            +    };
            +    this.transposeSelections = function(dir) {
            +        var session = this.session;
            +        var sel = session.multiSelect;
            +        var all = sel.ranges;
            +
            +        for (var i = all.length; i--; ) {
            +            var range = all[i];
            +            if (range.isEmpty()) {
            +                var tmp = session.getWordRange(range.start.row, range.start.column);
            +                range.start.row = tmp.start.row;
            +                range.start.column = tmp.start.column;
            +                range.end.row = tmp.end.row;
            +                range.end.column = tmp.end.column;
            +            }
            +        }
            +        sel.mergeOverlappingRanges();
            +
            +        var words = [];
            +        for (var i = all.length; i--; ) {
            +            var range = all[i];
            +            words.unshift(session.getTextRange(range));
            +        }
            +
            +        if (dir < 0)
            +            words.unshift(words.pop());
            +        else
            +            words.push(words.shift());
            +
            +        for (var i = all.length; i--; ) {
            +            var range = all[i];
            +            var tmp = range.clone();
            +            session.replace(range, words[i]);
            +            range.start.row = tmp.start.row;
            +            range.start.column = tmp.start.column;
            +        }
            +    };
            +    this.selectMore = function(dir, skip) {
            +        var session = this.session;
            +        var sel = session.multiSelect;
            +
            +        var range = sel.toOrientedRange();
            +        if (range.isEmpty()) {
            +            range = session.getWordRange(range.start.row, range.start.column);
            +            range.cursor = dir == -1 ? range.start : range.end;
            +            this.multiSelect.addRange(range);
            +        }
            +        var needle = session.getTextRange(range);
            +
            +        var newRange = find(session, needle, dir);
            +        if (newRange) {
            +            newRange.cursor = dir == -1 ? newRange.start : newRange.end;
            +            this.$blockScrolling += 1;
            +            this.session.unfold(newRange);
            +            this.multiSelect.addRange(newRange);
            +            this.$blockScrolling -= 1;
            +            this.renderer.scrollCursorIntoView(null, 0.5);
            +        }
            +        if (skip)
            +            this.multiSelect.substractPoint(range.cursor);
            +    };
            +    this.alignCursors = function() {
            +        var session = this.session;
            +        var sel = session.multiSelect;
            +        var ranges = sel.ranges;
            +        var row = -1;
            +        var sameRowRanges = ranges.filter(function(r) {
            +            if (r.cursor.row == row)
            +                return true;
            +            row = r.cursor.row;
            +        });
            +        
            +        if (!ranges.length || sameRowRanges.length == ranges.length - 1) {
            +            var range = this.selection.getRange();
            +            var fr = range.start.row, lr = range.end.row;
            +            var guessRange = fr == lr;
            +            if (guessRange) {
            +                var max = this.session.getLength();
            +                var line;
            +                do {
            +                    line = this.session.getLine(lr);
            +                } while (/[=:]/.test(line) && ++lr < max);
            +                do {
            +                    line = this.session.getLine(fr);
            +                } while (/[=:]/.test(line) && --fr > 0);
            +                
            +                if (fr < 0) fr = 0;
            +                if (lr >= max) lr = max - 1;
            +            }
            +            var lines = this.session.doc.removeLines(fr, lr);
            +            lines = this.$reAlignText(lines, guessRange);
            +            this.session.doc.insert({row: fr, column: 0}, lines.join("\n") + "\n");
            +            if (!guessRange) {
            +                range.start.column = 0;
            +                range.end.column = lines[lines.length - 1].length;
            +            }
            +            this.selection.setRange(range);
            +        } else {
            +            sameRowRanges.forEach(function(r) {
            +                sel.substractPoint(r.cursor);
            +            });
            +
            +            var maxCol = 0;
            +            var minSpace = Infinity;
            +            var spaceOffsets = ranges.map(function(r) {
            +                var p = r.cursor;
            +                var line = session.getLine(p.row);
            +                var spaceOffset = line.substr(p.column).search(/\S/g);
            +                if (spaceOffset == -1)
            +                    spaceOffset = 0;
            +
            +                if (p.column > maxCol)
            +                    maxCol = p.column;
            +                if (spaceOffset < minSpace)
            +                    minSpace = spaceOffset;
            +                return spaceOffset;
            +            });
            +            ranges.forEach(function(r, i) {
            +                var p = r.cursor;
            +                var l = maxCol - p.column;
            +                var d = spaceOffsets[i] - minSpace;
            +                if (l > d)
            +                    session.insert(p, lang.stringRepeat(" ", l - d));
            +                else
            +                    session.remove(new Range(p.row, p.column, p.row, p.column - l + d));
            +
            +                r.start.column = r.end.column = maxCol;
            +                r.start.row = r.end.row = p.row;
            +                r.cursor = r.end;
            +            });
            +            sel.fromOrientedRange(ranges[0]);
            +            this.renderer.updateCursor();
            +            this.renderer.updateBackMarkers();
            +        }
            +    };
            +
            +    this.$reAlignText = function(lines, forceLeft) {
            +        var isLeftAligned = true, isRightAligned = true;
            +        var startW, textW, endW;
            +
            +        return lines.map(function(line) {
            +            var m = line.match(/(\s*)(.*?)(\s*)([=:].*)/);
            +            if (!m)
            +                return [line];
            +
            +            if (startW == null) {
            +                startW = m[1].length;
            +                textW = m[2].length;
            +                endW = m[3].length;
            +                return m;
            +            }
            +
            +            if (startW + textW + endW != m[1].length + m[2].length + m[3].length)
            +                isRightAligned = false;
            +            if (startW != m[1].length)
            +                isLeftAligned = false;
            +
            +            if (startW > m[1].length)
            +                startW = m[1].length;
            +            if (textW < m[2].length)
            +                textW = m[2].length;
            +            if (endW > m[3].length)
            +                endW = m[3].length;
            +
            +            return m;
            +        }).map(forceLeft ? alignLeft :
            +            isLeftAligned ? isRightAligned ? alignRight : alignLeft : unAlign);
            +
            +        function spaces(n) {
            +            return lang.stringRepeat(" ", n);
            +        }
            +
            +        function alignLeft(m) {
            +            return !m[2] ? m[0] : spaces(startW) + m[2]
            +                + spaces(textW - m[2].length + endW)
            +                + m[4].replace(/^([=:])\s+/, "$1 ");
            +        }
            +        function alignRight(m) {
            +            return !m[2] ? m[0] : spaces(startW + textW - m[2].length) + m[2]
            +                + spaces(endW, " ")
            +                + m[4].replace(/^([=:])\s+/, "$1 ");
            +        }
            +        function unAlign(m) {
            +            return !m[2] ? m[0] : spaces(startW) + m[2]
            +                + spaces(endW)
            +                + m[4].replace(/^([=:])\s+/, "$1 ");
            +        }
            +    };
            +}).call(Editor.prototype);
            +
            +
            +function isSamePoint(p1, p2) {
            +    return p1.row == p2.row && p1.column == p2.column;
            +}
            +exports.onSessionChange = function(e) {
            +    var session = e.session;
            +    if (!session.multiSelect) {
            +        session.$selectionMarkers = [];
            +        session.selection.$initRangeList();
            +        session.multiSelect = session.selection;
            +    }
            +    this.multiSelect = session.multiSelect;
            +
            +    var oldSession = e.oldSession;
            +    if (oldSession) {
            +        oldSession.multiSelect.off("addRange", this.$onAddRange);
            +        oldSession.multiSelect.off("removeRange", this.$onRemoveRange);
            +        oldSession.multiSelect.off("multiSelect", this.$onMultiSelect);
            +        oldSession.multiSelect.off("singleSelect", this.$onSingleSelect);
            +        oldSession.multiSelect.lead.off("change",  this.$checkMultiselectChange);
            +        oldSession.multiSelect.anchor.off("change",  this.$checkMultiselectChange);
            +    }
            +
            +    session.multiSelect.on("addRange", this.$onAddRange);
            +    session.multiSelect.on("removeRange", this.$onRemoveRange);
            +    session.multiSelect.on("multiSelect", this.$onMultiSelect);
            +    session.multiSelect.on("singleSelect", this.$onSingleSelect);
            +    session.multiSelect.lead.on("change",  this.$checkMultiselectChange);
            +    session.multiSelect.anchor.on("change",  this.$checkMultiselectChange);
            +
            +    if (this.inMultiSelectMode != session.selection.inMultiSelectMode) {
            +        if (session.selection.inMultiSelectMode)
            +            this.$onMultiSelect();
            +        else
            +            this.$onSingleSelect();
            +    }
            +};
            +function MultiSelect(editor) {
            +    if (editor.$multiselectOnSessionChange)
            +        return;
            +    editor.$onAddRange = editor.$onAddRange.bind(editor);
            +    editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
            +    editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
            +    editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
            +    editor.$multiselectOnSessionChange = exports.onSessionChange.bind(editor);
            +    editor.$checkMultiselectChange = editor.$checkMultiselectChange.bind(editor);
            +
            +    editor.$multiselectOnSessionChange(editor);
            +    editor.on("changeSession", editor.$multiselectOnSessionChange);
            +
            +    editor.on("mousedown", onMouseDown);
            +    editor.commands.addCommands(commands.defaultCommands);
            +
            +    addAltCursorListeners(editor);
            +}
            +
            +function addAltCursorListeners(editor){
            +    var el = editor.textInput.getElement();
            +    var altCursor = false;
            +    event.addListener(el, "keydown", function(e) {
            +        if (e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey)) {
            +            if (!altCursor) {
            +                editor.renderer.setMouseCursor("crosshair");
            +                altCursor = true;
            +            }
            +        } else if (altCursor) {
            +            reset();
            +        }
            +    });
            +
            +    event.addListener(el, "keyup", reset);
            +    event.addListener(el, "blur", reset);
            +    function reset(e) {
            +        if (altCursor) {
            +            editor.renderer.setMouseCursor("");
            +            altCursor = false;
            +        }
            +    }
            +}
            +
            +exports.MultiSelect = MultiSelect;
            +
            +
            +require("./config").defineOptions(Editor.prototype, "editor", {
            +    enableMultiselect: {
            +        set: function(val) {
            +            MultiSelect(this);
            +            if (val) {
            +                this.on("changeSession", this.$multiselectOnSessionChange);
            +                this.on("mousedown", onMouseDown);
            +            } else {
            +                this.off("changeSession", this.$multiselectOnSessionChange);
            +                this.off("mousedown", onMouseDown);
            +            }
            +        },
            +        value: true
            +    }
            +});
            +
            +
            +
            +});
            +
            +define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"], function(require, exports, module) {
            +"use strict";
            +
            +var Range = require("../../range").Range;
            +
            +var FoldMode = exports.FoldMode = function() {};
            +
            +(function() {
            +
            +    this.foldingStartMarker = null;
            +    this.foldingStopMarker = null;
            +    this.getFoldWidget = function(session, foldStyle, row) {
            +        var line = session.getLine(row);
            +        if (this.foldingStartMarker.test(line))
            +            return "start";
            +        if (foldStyle == "markbeginend"
            +                && this.foldingStopMarker
            +                && this.foldingStopMarker.test(line))
            +            return "end";
            +        return "";
            +    };
            +
            +    this.getFoldWidgetRange = function(session, foldStyle, row) {
            +        return null;
            +    };
            +
            +    this.indentationBlock = function(session, row, column) {
            +        var re = /\S/;
            +        var line = session.getLine(row);
            +        var startLevel = line.search(re);
            +        if (startLevel == -1)
            +            return;
            +
            +        var startColumn = column || line.length;
            +        var maxRow = session.getLength();
            +        var startRow = row;
            +        var endRow = row;
            +
            +        while (++row < maxRow) {
            +            var level = session.getLine(row).search(re);
            +
            +            if (level == -1)
            +                continue;
            +
            +            if (level <= startLevel)
            +                break;
            +
            +            endRow = row;
            +        }
            +
            +        if (endRow > startRow) {
            +            var endColumn = session.getLine(endRow).length;
            +            return new Range(startRow, startColumn, endRow, endColumn);
            +        }
            +    };
            +
            +    this.openingBracketBlock = function(session, bracket, row, column, typeRe) {
            +        var start = {row: row, column: column + 1};
            +        var end = session.$findClosingBracket(bracket, start, typeRe);
            +        if (!end)
            +            return;
            +
            +        var fw = session.foldWidgets[end.row];
            +        if (fw == null)
            +            fw = session.getFoldWidget(end.row);
            +
            +        if (fw == "start" && end.row > start.row) {
            +            end.row --;
            +            end.column = session.getLine(end.row).length;
            +        }
            +        return Range.fromPoints(start, end);
            +    };
            +
            +    this.closingBracketBlock = function(session, bracket, row, column, typeRe) {
            +        var end = {row: row, column: column};
            +        var start = session.$findOpeningBracket(bracket, end);
            +
            +        if (!start)
            +            return;
            +
            +        start.column++;
            +        end.column--;
            +
            +        return  Range.fromPoints(start, end);
            +    };
            +}).call(FoldMode.prototype);
            +
            +});
            +
            +define("ace/theme/textmate",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
            +"use strict";
            +
            +exports.isDark = false;
            +exports.cssClass = "ace-tm";
            +exports.cssText = ".ace-tm .ace_gutter {\
            +background: #f0f0f0;\
            +color: #333;\
            +}\
            +.ace-tm .ace_print-margin {\
            +width: 1px;\
            +background: #e8e8e8;\
            +}\
            +.ace-tm .ace_fold {\
            +background-color: #6B72E6;\
            +}\
            +.ace-tm {\
            +background-color: #FFFFFF;\
            +color: black;\
            +}\
            +.ace-tm .ace_cursor {\
            +color: black;\
            +}\
            +.ace-tm .ace_invisible {\
            +color: rgb(191, 191, 191);\
            +}\
            +.ace-tm .ace_storage,\
            +.ace-tm .ace_keyword {\
            +color: blue;\
            +}\
            +.ace-tm .ace_constant {\
            +color: rgb(197, 6, 11);\
            +}\
            +.ace-tm .ace_constant.ace_buildin {\
            +color: rgb(88, 72, 246);\
            +}\
            +.ace-tm .ace_constant.ace_language {\
            +color: rgb(88, 92, 246);\
            +}\
            +.ace-tm .ace_constant.ace_library {\
            +color: rgb(6, 150, 14);\
            +}\
            +.ace-tm .ace_invalid {\
            +background-color: rgba(255, 0, 0, 0.1);\
            +color: red;\
            +}\
            +.ace-tm .ace_support.ace_function {\
            +color: rgb(60, 76, 114);\
            +}\
            +.ace-tm .ace_support.ace_constant {\
            +color: rgb(6, 150, 14);\
            +}\
            +.ace-tm .ace_support.ace_type,\
            +.ace-tm .ace_support.ace_class {\
            +color: rgb(109, 121, 222);\
            +}\
            +.ace-tm .ace_keyword.ace_operator {\
            +color: rgb(104, 118, 135);\
            +}\
            +.ace-tm .ace_string {\
            +color: rgb(3, 106, 7);\
            +}\
            +.ace-tm .ace_comment {\
            +color: rgb(76, 136, 107);\
            +}\
            +.ace-tm .ace_comment.ace_doc {\
            +color: rgb(0, 102, 255);\
            +}\
            +.ace-tm .ace_comment.ace_doc.ace_tag {\
            +color: rgb(128, 159, 191);\
            +}\
            +.ace-tm .ace_constant.ace_numeric {\
            +color: rgb(0, 0, 205);\
            +}\
            +.ace-tm .ace_variable {\
            +color: rgb(49, 132, 149);\
            +}\
            +.ace-tm .ace_xml-pe {\
            +color: rgb(104, 104, 91);\
            +}\
            +.ace-tm .ace_entity.ace_name.ace_function {\
            +color: #0000A2;\
            +}\
            +.ace-tm .ace_heading {\
            +color: rgb(12, 7, 255);\
            +}\
            +.ace-tm .ace_list {\
            +color:rgb(185, 6, 144);\
            +}\
            +.ace-tm .ace_meta.ace_tag {\
            +color:rgb(0, 22, 142);\
            +}\
            +.ace-tm .ace_string.ace_regex {\
            +color: rgb(255, 0, 0)\
            +}\
            +.ace-tm .ace_marker-layer .ace_selection {\
            +background: rgb(181, 213, 255);\
            +}\
            +.ace-tm.ace_multiselect .ace_selection.ace_start {\
            +box-shadow: 0 0 3px 0px white;\
            +border-radius: 2px;\
            +}\
            +.ace-tm .ace_marker-layer .ace_step {\
            +background: rgb(252, 255, 0);\
            +}\
            +.ace-tm .ace_marker-layer .ace_stack {\
            +background: rgb(164, 229, 101);\
            +}\
            +.ace-tm .ace_marker-layer .ace_bracket {\
            +margin: -1px 0 0 -1px;\
            +border: 1px solid rgb(192, 192, 192);\
            +}\
            +.ace-tm .ace_marker-layer .ace_active-line {\
            +background: rgba(0, 0, 0, 0.07);\
            +}\
            +.ace-tm .ace_gutter-active-line {\
            +background-color : #dcdcdc;\
            +}\
            +.ace-tm .ace_marker-layer .ace_selected-word {\
            +background: rgb(250, 250, 255);\
            +border: 1px solid rgb(200, 200, 250);\
            +}\
            +.ace-tm .ace_indent-guide {\
            +background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAE0lEQVQImWP4////f4bLly//BwAmVgd1/w11/gAAAABJRU5ErkJggg==\") right repeat-y;\
            +}\
            +";
            +
            +var dom = require("../lib/dom");
            +dom.importCssString(exports.cssText, exports.cssClass);
            +});
            +
            +define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"], function(require, exports, module) {
            +"use strict";
            +
            +var oop = require("./lib/oop");
            +var dom = require("./lib/dom");
            +var Range = require("./range").Range;
            +
            +
            +function LineWidgets(session) {
            +    this.session = session;
            +    this.session.widgetManager = this;
            +    this.session.getRowLength = this.getRowLength;
            +    this.session.$getWidgetScreenLength = this.$getWidgetScreenLength;
            +    this.updateOnChange = this.updateOnChange.bind(this);
            +    this.renderWidgets = this.renderWidgets.bind(this);
            +    this.measureWidgets = this.measureWidgets.bind(this);
            +    this.session._changedWidgets = [];
            +    this.detach = this.detach.bind(this);
            +    
            +    this.session.on("change", this.updateOnChange);
            +}
            +
            +(function() {
            +    this.getRowLength = function(row) {
            +        var h;
            +        if (this.lineWidgets)
            +            h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0;
            +        else 
            +            h = 0;
            +        if (!this.$useWrapMode || !this.$wrapData[row]) {
            +            return 1 + h;
            +        } else {
            +            return this.$wrapData[row].length + 1 + h;
            +        }
            +    };
            +
            +    this.$getWidgetScreenLength = function() {
            +        var screenRows = 0;
            +        this.lineWidgets.forEach(function(w){
            +            if (w && w.rowCount)
            +                screenRows +=w.rowCount;
            +        });
            +        return screenRows;
            +    };    
            +    
            +    this.attach = function(editor) {
            +        if (editor.widgetManager && editor.widgetManager != this)
            +            editor.widgetManager.detach();
            +
            +        if (this.editor == editor)
            +            return;
            +
            +        this.detach();
            +        this.editor = editor;
            +        
            +        this.editor.on("changeSession", this.detach);
            +        
            +        editor.widgetManager = this;
            +
            +        editor.renderer.on("beforeRender", this.measureWidgets);
            +        editor.renderer.on("afterRender", this.renderWidgets);
            +    };
            +    this.detach = function(e) {
            +        if (e && e.session == this.session)
            +            return; // sometimes attach can be called before setSession
            +        var editor = this.editor;
            +        if (!editor)
            +            return;
            +
            +        editor.off("changeSession", this.detach);
            +        
            +        this.editor = null;
            +        editor.widgetManager = null;
            +        
            +        editor.renderer.off("beforeRender", this.measureWidgets);
            +        editor.renderer.off("afterRender", this.renderWidgets);
            +        var lineWidgets = this.session.lineWidgets;
            +        lineWidgets && lineWidgets.forEach(function(w) {
            +            if (w && w.el && w.el.parentNode) {
            +                w._inDocument = false;
            +                w.el.parentNode.removeChild(w.el);
            +            }
            +        });
            +    };
            +
            +    this.updateOnChange = function(e) {
            +        var lineWidgets = this.session.lineWidgets;
            +        if (!lineWidgets) return;
            +            
            +        var delta = e.data;
            +        var range = delta.range;
            +        var startRow = range.start.row;
            +        var len = range.end.row - startRow;
            +
            +        if (len === 0) {
            +        } else if (delta.action == "removeText" || delta.action == "removeLines") {
            +            var removed = lineWidgets.splice(startRow + 1, len);
            +            removed.forEach(function(w) {
            +                w && this.removeLineWidget(w);
            +            }, this);
            +            this.$updateRows();
            +        } else {
            +            var args = new Array(len);
            +            args.unshift(startRow, 0);
            +            lineWidgets.splice.apply(lineWidgets, args);
            +            this.$updateRows();
            +        }
            +    };
            +    
            +    this.$updateRows = function() {
            +        var lineWidgets = this.session.lineWidgets;
            +        if (!lineWidgets) return;
            +        var noWidgets = true;
            +        lineWidgets.forEach(function(w, i) {
            +            if (w) {
            +                noWidgets = false;
            +                w.row = i;
            +            }
            +        });
            +        if (noWidgets)
            +            this.session.lineWidgets = null;
            +    };
            +
            +    this.addLineWidget = function(w) {
            +        if (!this.session.lineWidgets)
            +            this.session.lineWidgets = new Array(this.session.getLength());
            +        
            +        this.session.lineWidgets[w.row] = w;
            +        
            +        var renderer = this.editor.renderer;
            +        if (w.html && !w.el) {
            +            w.el = dom.createElement("div");
            +            w.el.innerHTML = w.html;
            +        }
            +        if (w.el) {
            +            dom.addCssClass(w.el, "ace_lineWidgetContainer");
            +            w.el.style.position = "absolute";
            +            w.el.style.zIndex = 5;
            +            renderer.container.appendChild(w.el);
            +            w._inDocument = true;
            +        }
            +        
            +        if (!w.coverGutter) {
            +            w.el.style.zIndex = 3;
            +        }
            +        if (!w.pixelHeight) {
            +            w.pixelHeight = w.el.offsetHeight;
            +        }
            +        if (w.rowCount == null)
            +            w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight;
            +        
            +        this.session._emit("changeFold", {data:{start:{row: w.row}}});
            +        
            +        this.$updateRows();
            +        this.renderWidgets(null, renderer);
            +        return w;
            +    };
            +    
            +    this.removeLineWidget = function(w) {
            +        w._inDocument = false;
            +        if (w.el && w.el.parentNode)
            +            w.el.parentNode.removeChild(w.el);
            +        if (w.editor && w.editor.destroy) try {
            +            w.editor.destroy();
            +        } catch(e){}
            +        if (this.session.lineWidgets)
            +            this.session.lineWidgets[w.row] = undefined;
            +        this.session._emit("changeFold", {data:{start:{row: w.row}}});
            +        this.$updateRows();
            +    };
            +    
            +    this.onWidgetChanged = function(w) {
            +        this.session._changedWidgets.push(w);
            +        this.editor && this.editor.renderer.updateFull();
            +    };
            +    
            +    this.measureWidgets = function(e, renderer) {
            +        var changedWidgets = this.session._changedWidgets;
            +        var config = renderer.layerConfig;
            +        
            +        if (!changedWidgets || !changedWidgets.length) return;
            +        var min = Infinity;
            +        for (var i = 0; i < changedWidgets.length; i++) {
            +            var w = changedWidgets[i];
            +            if (!w._inDocument) {
            +                w._inDocument = true;
            +                renderer.container.appendChild(w.el);
            +            }
            +            
            +            w.h = w.el.offsetHeight;
            +            
            +            if (!w.fixedWidth) {
            +                w.w = w.el.offsetWidth;
            +                w.screenWidth = Math.ceil(w.w / config.characterWidth);
            +            }
            +            
            +            var rowCount = w.h / config.lineHeight;
            +            if (w.coverLine) {
            +                rowCount -= this.session.getRowLineCount(w.row);
            +                if (rowCount < 0)
            +                    rowCount = 0;
            +            }
            +            if (w.rowCount != rowCount) {
            +                w.rowCount = rowCount;
            +                if (w.row < min)
            +                    min = w.row;
            +            }
            +        }
            +        if (min != Infinity) {
            +            this.session._emit("changeFold", {data:{start:{row: min}}});
            +            this.session.lineWidgetWidth = null;
            +        }
            +        this.session._changedWidgets = [];
            +    };
            +    
            +    this.renderWidgets = function(e, renderer) {
            +        var config = renderer.layerConfig;
            +        var lineWidgets = this.session.lineWidgets;
            +        if (!lineWidgets)
            +            return;
            +        var first = Math.min(this.firstRow, config.firstRow);
            +        var last = Math.max(this.lastRow, config.lastRow, lineWidgets.length);
            +        
            +        while (first > 0 && !lineWidgets[first])
            +            first--;
            +        
            +        this.firstRow = config.firstRow;
            +        this.lastRow = config.lastRow;
            +
            +        renderer.$cursorLayer.config = config;
            +        for (var i = first; i <= last; i++) {
            +            var w = lineWidgets[i];
            +            if (!w || !w.el) continue;
            +
            +            if (!w._inDocument) {
            +                w._inDocument = true;
            +                renderer.container.appendChild(w.el);
            +            }
            +            var top = renderer.$cursorLayer.getPixelPosition({row: i, column:0}, true).top;
            +            if (!w.coverLine)
            +                top += config.lineHeight * this.session.getRowLineCount(w.row);
            +            w.el.style.top = top - config.offset + "px";
            +            
            +            var left = w.coverGutter ? 0 : renderer.gutterWidth;
            +            if (!w.fixedWidth)
            +                left -= renderer.scrollLeft;
            +            w.el.style.left = left + "px";
            +
            +            if (w.fixedWidth) {
            +                w.el.style.right = renderer.scrollBar.getWidth() + "px";
            +            } else {
            +                w.el.style.right = "";
            +            }
            +        }
            +    };
            +    
            +}).call(LineWidgets.prototype);
            +
            +
            +exports.LineWidgets = LineWidgets;
            +
            +});
            +
            +define("ace/ext/error_marker",["require","exports","module","ace/line_widgets","ace/lib/dom","ace/range"], function(require, exports, module) {
            +"use strict";
            +var LineWidgets = require("ace/line_widgets").LineWidgets;
            +var dom = require("ace/lib/dom");
            +var Range = require("ace/range").Range;
            +
            +function binarySearch(array, needle, comparator) {
            +    var first = 0;
            +    var last = array.length - 1;
            +
            +    while (first <= last) {
            +        var mid = (first + last) >> 1;
            +        var c = comparator(needle, array[mid]);
            +        if (c > 0)
            +            first = mid + 1;
            +        else if (c < 0)
            +            last = mid - 1;
            +        else
            +            return mid;
            +    }
            +    return -(first + 1);
            +}
            +
            +function findAnnotations(session, row, dir) {
            +    var annotations = session.getAnnotations().sort(Range.comparePoints);
            +    if (!annotations.length)
            +        return;
            +    
            +    var i = binarySearch(annotations, {row: row, column: -1}, Range.comparePoints);
            +    if (i < 0)
            +        i = -i - 1;
            +    
            +    if (i >= annotations.length - 1)
            +        i = dir > 0 ? 0 : annotations.length - 1;
            +    else if (i === 0 && dir < 0)
            +        i = annotations.length - 1;
            +    
            +    var annotation = annotations[i];
            +    if (!annotation || !dir)
            +        return;
            +
            +    if (annotation.row === row) {
            +        do {
            +            annotation = annotations[i += dir];
            +        } while (annotation && annotation.row === row);
            +        if (!annotation)
            +            return annotations.slice();
            +    }
            +    
            +    
            +    var matched = [];
            +    row = annotation.row;
            +    do {
            +        matched[dir < 0 ? "unshift" : "push"](annotation);
            +        annotation = annotations[i += dir];
            +    } while (annotation && annotation.row == row);
            +    return matched.length && matched;
            +}
            +
            +exports.showErrorMarker = function(editor, dir) {
            +    var session = editor.session;
            +    if (!session.widgetManager) {
            +        session.widgetManager = new LineWidgets(session);
            +        session.widgetManager.attach(editor);
            +    }
            +    
            +    var pos = editor.getCursorPosition();
            +    var row = pos.row;
            +    var oldWidget = session.lineWidgets && session.lineWidgets[row];
            +    if (oldWidget) {
            +        oldWidget.destroy();
            +    } else {
            +        row -= dir;
            +    }
            +    var annotations = findAnnotations(session, row, dir);
            +    var gutterAnno;
            +    if (annotations) {
            +        var annotation = annotations[0];
            +        pos.column = (annotation.pos && typeof annotation.column != "number"
            +            ? annotation.pos.sc
            +            : annotation.column) || 0;
            +        pos.row = annotation.row;
            +        gutterAnno = editor.renderer.$gutterLayer.$annotations[pos.row];
            +    } else if (oldWidget) {
            +        return;
            +    } else {
            +        gutterAnno = {
            +            text: ["Looks good!"],
            +            className: "ace_ok"
            +        };
            +    }
            +    editor.session.unfold(pos.row);
            +    editor.selection.moveToPosition(pos);
            +    
            +    var w = {
            +        row: pos.row, 
            +        fixedWidth: true,
            +        coverGutter: true,
            +        el: dom.createElement("div")
            +    };
            +    var el = w.el.appendChild(dom.createElement("div"));
            +    var arrow = w.el.appendChild(dom.createElement("div"));
            +    arrow.className = "error_widget_arrow " + gutterAnno.className;
            +    
            +    var left = editor.renderer.$cursorLayer
            +        .getPixelPosition(pos).left;
            +    arrow.style.left = left + editor.renderer.gutterWidth - 5 + "px";
            +    
            +    w.el.className = "error_widget_wrapper";
            +    el.className = "error_widget " + gutterAnno.className;
            +    el.innerHTML = gutterAnno.text.join("<br>");
            +    
            +    el.appendChild(dom.createElement("div"));
            +    
            +    var kb = function(_, hashId, keyString) {
            +        if (hashId === 0 && (keyString === "esc" || keyString === "return")) {
            +            w.destroy();
            +            return {command: "null"};
            +        }
            +    };
            +    
            +    w.destroy = function() {
            +        if (editor.$mouseHandler.isMousePressed)
            +            return;
            +        editor.keyBinding.removeKeyboardHandler(kb);
            +        session.widgetManager.removeLineWidget(w);
            +        editor.off("changeSelection", w.destroy);
            +        editor.off("changeSession", w.destroy);
            +        editor.off("mouseup", w.destroy);
            +        editor.off("change", w.destroy);
            +    };
            +    
            +    editor.keyBinding.addKeyboardHandler(kb);
            +    editor.on("changeSelection", w.destroy);
            +    editor.on("changeSession", w.destroy);
            +    editor.on("mouseup", w.destroy);
            +    editor.on("change", w.destroy);
            +    
            +    editor.session.widgetManager.addLineWidget(w);
            +    
            +    w.el.onmousedown = editor.focus.bind(editor);
            +    
            +    editor.renderer.scrollCursorIntoView(null, 0.5, {bottom: w.el.offsetHeight});
            +};
            +
            +
            +dom.importCssString("\
            +    .error_widget_wrapper {\
            +        background: inherit;\
            +        color: inherit;\
            +        border:none\
            +    }\
            +    .error_widget {\
            +        border-top: solid 2px;\
            +        border-bottom: solid 2px;\
            +        margin: 5px 0;\
            +        padding: 10px 40px;\
            +        white-space: pre-wrap;\
            +    }\
            +    .error_widget.ace_error, .error_widget_arrow.ace_error{\
            +        border-color: #ff5a5a\
            +    }\
            +    .error_widget.ace_warning, .error_widget_arrow.ace_warning{\
            +        border-color: #F1D817\
            +    }\
            +    .error_widget.ace_info, .error_widget_arrow.ace_info{\
            +        border-color: #5a5a5a\
            +    }\
            +    .error_widget.ace_ok, .error_widget_arrow.ace_ok{\
            +        border-color: #5aaa5a\
            +    }\
            +    .error_widget_arrow {\
            +        position: absolute;\
            +        border: solid 5px;\
            +        border-top-color: transparent!important;\
            +        border-right-color: transparent!important;\
            +        border-left-color: transparent!important;\
            +        top: -5px;\
            +    }\
            +", "");
            +
            +});
            +
            +define("ace/ace",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/dom","ace/lib/event","ace/editor","ace/edit_session","ace/undomanager","ace/virtual_renderer","ace/worker/worker_client","ace/keyboard/hash_handler","ace/placeholder","ace/multi_select","ace/mode/folding/fold_mode","ace/theme/textmate","ace/ext/error_marker","ace/config"], function(require, exports, module) {
            +"use strict";
            +
            +require("./lib/fixoldbrowsers");
            +
            +var dom = require("./lib/dom");
            +var event = require("./lib/event");
            +
            +var Editor = require("./editor").Editor;
            +var EditSession = require("./edit_session").EditSession;
            +var UndoManager = require("./undomanager").UndoManager;
            +var Renderer = require("./virtual_renderer").VirtualRenderer;
            +require("./worker/worker_client");
            +require("./keyboard/hash_handler");
            +require("./placeholder");
            +require("./multi_select");
            +require("./mode/folding/fold_mode");
            +require("./theme/textmate");
            +require("./ext/error_marker");
            +
            +exports.config = require("./config");
            +exports.require = require;
            +exports.edit = function(el) {
            +    if (typeof(el) == "string") {
            +        var _id = el;
            +        el = document.getElementById(_id);
            +        if (!el)
            +            throw new Error("ace.edit can't find div #" + _id);
            +    }
            +
            +    if (el.env && el.env.editor instanceof Editor)
            +        return el.env.editor;
            +
            +    var doc = exports.createEditSession(dom.getInnerText(el));
            +    el.innerHTML = '';
            +
            +    var editor = new Editor(new Renderer(el));
            +    editor.setSession(doc);
            +
            +    var env = {
            +        document: doc,
            +        editor: editor,
            +        onResize: editor.resize.bind(editor, null)
            +    };
            +    event.addListener(window, "resize", env.onResize);
            +    editor.on("destroy", function() {
            +        event.removeListener(window, "resize", env.onResize);
            +    });
            +    el.env = editor.env = env;
            +    return editor;
            +};
            +exports.createEditSession = function(text, mode) {
            +    var doc = new EditSession(text, mode);
            +    doc.setUndoManager(new UndoManager());
            +    return doc;
            +}
            +exports.EditSession = EditSession;
            +exports.UndoManager = UndoManager;
            +});
            +;
            +            (function() {
            +                window.require(["ace/ace"], function(a) {
            +                    a && a.config.init(true);
            +                    if (!window.ace)
            +                        window.ace = a;
            +                    for (var key in a) if (a.hasOwnProperty(key))
            +                        window.ace[key] = a[key];
            +                });
            +            })();
            +        
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace/mode-javascript.js b/dist/assets/js/vendor/ace/mode-javascript.js
            new file mode 100644
            index 0000000000..da4f93ed83
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace/mode-javascript.js
            @@ -0,0 +1 @@
            +define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/range","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"],function(e,t,n){var r=e("../lib/oop"),i=e("./text").Mode,s=e("./javascript_highlight_rules").JavaScriptHighlightRules,o=e("./matching_brace_outdent").MatchingBraceOutdent,u=e("../range").Range,a=e("../worker/worker_client").WorkerClient,f=e("./behaviour/cstyle").CstyleBehaviour,l=e("./folding/cstyle").FoldMode,c=function(){this.HighlightRules=s,this.$outdent=new o,this.$behaviour=new f,this.foldingRules=new l};r.inherits(c,i),function(){this.lineCommentStart="//",this.blockComment={start:"/*",end:"*/"},this.getNextLineIndent=function(e,t,n){var r=this.$getIndent(t),i=this.getTokenizer().getLineTokens(t,e),s=i.tokens,o=i.state;if(s.length&&s[s.length-1].type=="comment")return r;if(e=="start"||e=="no_regex"){var u=t.match(/^.*(?:\bcase\b.*\:|[\{\(\[])\s*$/);u&&(r+=n)}else if(e=="doc-start"){if(o=="start"||o=="no_regex")return"";var u=t.match(/^\s*(\/?)\*/);u&&(u[1]&&(r+=" "),r+="* ")}return r},this.checkOutdent=function(e,t,n){return this.$outdent.checkOutdent(t,n)},this.autoOutdent=function(e,t,n){this.$outdent.autoOutdent(t,n)},this.createWorker=function(e){var t=new a(["ace"],"ace/mode/javascript_worker","JavaScriptWorker");return t.attachToDocument(e.getDocument()),t.on("jslint",function(t){e.setAnnotations(t.data)}),t.on("terminate",function(){e.clearAnnotations()}),t},this.$id="ace/mode/javascript"}.call(c.prototype),t.Mode=c}),define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./doc_comment_highlight_rules").DocCommentHighlightRules,s=e("./text_highlight_rules").TextHighlightRules,o=function(){var e=this.createKeywordMapper({"variable.language":"Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|Namespace|QName|XML|XMLList|ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|SyntaxError|TypeError|URIError|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|isNaN|parseFloat|parseInt|JSON|Math|this|arguments|prototype|window|document",keyword:"const|yield|import|get|set|break|case|catch|continue|default|delete|do|else|finally|for|function|if|in|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|__parent__|__count__|escape|unescape|with|__proto__|class|enum|extends|super|export|implements|private|public|interface|package|protected|static","storage.type":"const|let|var|function","constant.language":"null|Infinity|NaN|undefined","support.function":"alert","constant.language.boolean":"true|false"},"identifier"),t="case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void",n="[a-zA-Z\\$_¡-￿][a-zA-Z\\d\\$_¡-￿]*\\b",r="\\\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|[0-2][0-7]{0,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.)";this.$rules={no_regex:[{token:"comment",regex:"\\/\\/",next:"line_comment"},i.getStartRule("doc-start"),{token:"comment",regex:/\/\*/,next:"comment"},{token:"string",regex:"'(?=.)",next:"qstring"},{token:"string",regex:'"(?=.)',next:"qqstring"},{token:"constant.numeric",regex:/0[xX][0-9a-fA-F]+\b/},{token:"constant.numeric",regex:/[+-]?\d+(?:(?:\.\d*)?(?:[eE][+-]?\d+)?)?\b/},{token:["storage.type","punctuation.operator","support.function","punctuation.operator","entity.name.function","text","keyword.operator"],regex:"("+n+")(\\.)(prototype)(\\.)("+n+")(\\s*)(=)",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","keyword.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(=)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","punctuation.operator","entity.name.function","text","keyword.operator","text","storage.type","text","entity.name.function","text","paren.lparen"],regex:"("+n+")(\\.)("+n+")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()",next:"function_arguments"},{token:["storage.type","text","entity.name.function","text","paren.lparen"],regex:"(function)(\\s+)("+n+")(\\s*)(\\()",next:"function_arguments"},{token:["entity.name.function","text","punctuation.operator","text","storage.type","text","paren.lparen"],regex:"("+n+")(\\s*)(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:["text","text","storage.type","text","paren.lparen"],regex:"(:)(\\s*)(function)(\\s*)(\\()",next:"function_arguments"},{token:"keyword",regex:"(?:"+t+")\\b",next:"start"},{token:["punctuation.operator","support.function"],regex:/(\.)(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/},{token:["punctuation.operator","support.function.dom"],regex:/(\.)(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/},{token:["punctuation.operator","support.constant"],regex:/(\.)(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/},{token:["storage.type","punctuation.operator","support.function.firebug"],regex:/(console)(\.)(warn|info|log|error|time|timeEnd|assert)\b/},{token:e,regex:n},{token:"keyword.operator",regex:/--|\+\+|[!$%&*+\-~]|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\|\||\?\:|\*=|%=|\+=|\-=|&=|\^=/,next:"start"},{token:"punctuation.operator",regex:/\?|\:|\,|\;|\./,next:"start"},{token:"paren.lparen",regex:/[\[({]/,next:"start"},{token:"paren.rparen",regex:/[\])}]/},{token:"keyword.operator",regex:/\/=?/,next:"start"},{token:"comment",regex:/^#!.*$/}],start:[i.getStartRule("doc-start"),{token:"comment",regex:"\\/\\*",next:"comment_regex_allowed"},{token:"comment",regex:"\\/\\/",next:"line_comment_regex_allowed"},{token:"string.regexp",regex:"\\/",next:"regex"},{token:"text",regex:"\\s+|^$",next:"start"},{token:"empty",regex:"",next:"no_regex"}],regex:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"string.regexp",regex:"/[sxngimy]*",next:"no_regex"},{token:"invalid",regex:/\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/},{token:"constant.language.escape",regex:/\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/},{token:"constant.language.delimiter",regex:/\|/},{token:"constant.language.escape",regex:/\[\^?/,next:"regex_character_class"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp"}],regex_character_class:[{token:"regexp.keyword.operator",regex:"\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)"},{token:"constant.language.escape",regex:"]",next:"regex"},{token:"constant.language.escape",regex:"-"},{token:"empty",regex:"$",next:"no_regex"},{defaultToken:"string.regexp.charachterclass"}],function_arguments:[{token:"variable.parameter",regex:n},{token:"punctuation.operator",regex:"[, ]+"},{token:"punctuation.operator",regex:"$"},{token:"empty",regex:"",next:"no_regex"}],comment_regex_allowed:[{token:"comment",regex:"\\*\\/",next:"start"},{defaultToken:"comment"}],comment:[{token:"comment",regex:"\\*\\/",next:"no_regex"},{defaultToken:"comment"}],line_comment_regex_allowed:[{token:"comment",regex:"$|^",next:"start"},{defaultToken:"comment"}],line_comment:[{token:"comment",regex:"$|^",next:"no_regex"},{defaultToken:"comment"}],qqstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qqstring"},{token:"string",regex:'"|$',next:"no_regex"},{defaultToken:"string"}],qstring:[{token:"constant.language.escape",regex:r},{token:"string",regex:"\\\\$",next:"qstring"},{token:"string",regex:"'|$",next:"no_regex"},{defaultToken:"string"}]},this.embedRules(i,"doc-",[i.getEndRule("no_regex")])};r.inherits(o,s),t.JavaScriptHighlightRules=o}),define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(e,t,n){var r=e("../lib/oop"),i=e("./text_highlight_rules").TextHighlightRules,s=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc.tag",regex:"\\bTODO\\b"},{defaultToken:"comment.doc"}]}};r.inherits(s,i),s.getStartRule=function(e){return{token:"comment.doc",regex:"\\/\\*(?=\\*)",next:e}},s.getEndRule=function(e){return{token:"comment.doc",regex:"\\*\\/",next:e}},t.DocCommentHighlightRules=s}),define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(e,t,n){var r=e("../range").Range,i=function(){};(function(){this.checkOutdent=function(e,t){return/^\s+$/.test(e)?/^\s*\}/.test(t):!1},this.autoOutdent=function(e,t){var n=e.getLine(t),i=n.match(/^(\s*\})/);if(!i)return 0;var s=i[1].length,o=e.findMatchingBracket({row:t,column:s});if(!o||o.row==t)return 0;var u=this.$getIndent(e.getLine(o.row));e.replace(new r(t,0,t,s-1),u)},this.$getIndent=function(e){return e.match(/^\s*/)[0]}}).call(i.prototype),t.MatchingBraceOutdent=i}),define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"],function(e,t,n){var r=e("../../lib/oop"),i=e("../behaviour").Behaviour,s=e("../../token_iterator").TokenIterator,o=e("../../lib/lang"),u=["text","paren.rparen","punctuation.operator"],a=["text","paren.rparen","punctuation.operator","comment"],f,l={},c=function(e){var t=-1;e.multiSelect&&(t=e.selection.id,l.rangeCount!=e.multiSelect.rangeCount&&(l={rangeCount:e.multiSelect.rangeCount}));if(l[t])return f=l[t];f=l[t]={autoInsertedBrackets:0,autoInsertedRow:-1,autoInsertedLineEnd:"",maybeInsertedBrackets:0,maybeInsertedRow:-1,maybeInsertedLineStart:"",maybeInsertedLineEnd:""}},h=function(){this.add("braces","insertion",function(e,t,n,r,i){var s=n.getCursorPosition(),u=r.doc.getLine(s.row);if(i=="{"){c(n);var a=n.getSelectionRange(),l=r.doc.getTextRange(a);if(l!==""&&l!=="{"&&n.getWrapBehavioursEnabled())return{text:"{"+l+"}",selection:!1};if(h.isSaneInsertion(n,r))return/[\]\}\)]/.test(u[s.column])||n.inMultiSelectMode?(h.recordAutoInsert(n,r,"}"),{text:"{}",selection:[1,1]}):(h.recordMaybeInsert(n,r,"{"),{text:"{",selection:[1,1]})}else if(i=="}"){c(n);var p=u.substring(s.column,s.column+1);if(p=="}"){var d=r.$findOpeningBracket("}",{column:s.column+1,row:s.row});if(d!==null&&h.isAutoInsertedClosing(s,u,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}else{if(i=="\n"||i=="\r\n"){c(n);var v="";h.isMaybeInsertedClosing(s,u)&&(v=o.stringRepeat("}",f.maybeInsertedBrackets),h.clearMaybeInsertedClosing());var p=u.substring(s.column,s.column+1);if(p==="}"){var m=r.findMatchingBracket({row:s.row,column:s.column+1},"}");if(!m)return null;var g=this.$getIndent(r.getLine(m.row))}else{if(!v){h.clearMaybeInsertedClosing();return}var g=this.$getIndent(u)}var y=g+r.getTabString();return{text:"\n"+y+"\n"+g+v,selection:[1,y.length,1,y.length]}}h.clearMaybeInsertedClosing()}}),this.add("braces","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="{"){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.end.column,i.end.column+1);if(u=="}")return i.end.column++,i;f.maybeInsertedBrackets--}}),this.add("parens","insertion",function(e,t,n,r,i){if(i=="("){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"("+o+")",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,")"),{text:"()",selection:[1,1]}}else if(i==")"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f==")"){var l=r.$findOpeningBracket(")",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="("){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==")")return i.end.column++,i}}),this.add("brackets","insertion",function(e,t,n,r,i){if(i=="["){c(n);var s=n.getSelectionRange(),o=r.doc.getTextRange(s);if(o!==""&&n.getWrapBehavioursEnabled())return{text:"["+o+"]",selection:!1};if(h.isSaneInsertion(n,r))return h.recordAutoInsert(n,r,"]"),{text:"[]",selection:[1,1]}}else if(i=="]"){c(n);var u=n.getCursorPosition(),a=r.doc.getLine(u.row),f=a.substring(u.column,u.column+1);if(f=="]"){var l=r.$findOpeningBracket("]",{column:u.column+1,row:u.row});if(l!==null&&h.isAutoInsertedClosing(u,a,i))return h.popAutoInsertedClosing(),{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&s=="["){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u=="]")return i.end.column++,i}}),this.add("string_dquotes","insertion",function(e,t,n,r,i){if(i=='"'||i=="'"){c(n);var s=i,o=n.getSelectionRange(),u=r.doc.getTextRange(o);if(u!==""&&u!=="'"&&u!='"'&&n.getWrapBehavioursEnabled())return{text:s+u+s,selection:!1};var a=n.getCursorPosition(),f=r.doc.getLine(a.row),l=f.substring(a.column-1,a.column);if(l=="\\")return null;var p=r.getTokens(o.start.row),d=0,v,m=-1;for(var g=0;g<p.length;g++){v=p[g],v.type=="string"?m=-1:m<0&&(m=v.value.indexOf(s));if(v.value.length+d>o.start.column)break;d+=p[g].value.length}if(!v||m<0&&v.type!=="comment"&&(v.type!=="string"||o.start.column!==v.value.length+d-1&&v.value.lastIndexOf(s)===v.value.length-1)){if(!h.isSaneInsertion(n,r))return;return{text:s+s,selection:[1,1]}}if(v&&v.type==="string"){var y=f.substring(a.column,a.column+1);if(y==s)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(e,t,n,r,i){var s=r.doc.getTextRange(i);if(!i.isMultiLine()&&(s=='"'||s=="'")){c(n);var o=r.doc.getLine(i.start.row),u=o.substring(i.start.column+1,i.start.column+2);if(u==s)return i.end.column++,i}})};h.isSaneInsertion=function(e,t){var n=e.getCursorPosition(),r=new s(t,n.row,n.column);if(!this.$matchTokenType(r.getCurrentToken()||"text",u)){var i=new s(t,n.row,n.column+1);if(!this.$matchTokenType(i.getCurrentToken()||"text",u))return!1}return r.stepForward(),r.getCurrentTokenRow()!==n.row||this.$matchTokenType(r.getCurrentToken()||"text",a)},h.$matchTokenType=function(e,t){return t.indexOf(e.type||e)>-1},h.recordAutoInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isAutoInsertedClosing(r,i,f.autoInsertedLineEnd[0])||(f.autoInsertedBrackets=0),f.autoInsertedRow=r.row,f.autoInsertedLineEnd=n+i.substr(r.column),f.autoInsertedBrackets++},h.recordMaybeInsert=function(e,t,n){var r=e.getCursorPosition(),i=t.doc.getLine(r.row);this.isMaybeInsertedClosing(r,i)||(f.maybeInsertedBrackets=0),f.maybeInsertedRow=r.row,f.maybeInsertedLineStart=i.substr(0,r.column)+n,f.maybeInsertedLineEnd=i.substr(r.column),f.maybeInsertedBrackets++},h.isAutoInsertedClosing=function(e,t,n){return f.autoInsertedBrackets>0&&e.row===f.autoInsertedRow&&n===f.autoInsertedLineEnd[0]&&t.substr(e.column)===f.autoInsertedLineEnd},h.isMaybeInsertedClosing=function(e,t){return f.maybeInsertedBrackets>0&&e.row===f.maybeInsertedRow&&t.substr(e.column)===f.maybeInsertedLineEnd&&t.substr(0,e.column)==f.maybeInsertedLineStart},h.popAutoInsertedClosing=function(){f.autoInsertedLineEnd=f.autoInsertedLineEnd.substr(1),f.autoInsertedBrackets--},h.clearMaybeInsertedClosing=function(){f&&(f.maybeInsertedBrackets=0,f.maybeInsertedRow=-1)},r.inherits(h,i),t.CstyleBehaviour=h}),define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(e,t,n){var r=e("../../lib/oop"),i=e("../../range").Range,s=e("./fold_mode").FoldMode,o=t.FoldMode=function(e){e&&(this.foldingStartMarker=new RegExp(this.foldingStartMarker.source.replace(/\|[^|]*?$/,"|"+e.start)),this.foldingStopMarker=new RegExp(this.foldingStopMarker.source.replace(/\|[^|]*?$/,"|"+e.end)))};r.inherits(o,s),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(e,t,n,r){var i=e.getLine(n),s=i.match(this.foldingStartMarker);if(s){var o=s.index;if(s[1])return this.openingBracketBlock(e,s[1],n,o);var u=e.getCommentFoldRange(n,o+s[0].length,1);return u&&!u.isMultiLine()&&(r?u=this.getSectionRange(e,n):t!="all"&&(u=null)),u}if(t==="markbegin")return;var s=i.match(this.foldingStopMarker);if(s){var o=s.index+s[0].length;return s[1]?this.closingBracketBlock(e,s[1],n,o):e.getCommentFoldRange(n,o,-1)}},this.getSectionRange=function(e,t){var n=e.getLine(t),r=n.search(/\S/),s=t,o=n.length;t+=1;var u=t,a=e.getLength();while(++t<a){n=e.getLine(t);var f=n.search(/\S/);if(f===-1)continue;if(r>f)break;var l=this.getFoldWidgetRange(e,"all",t);if(l){if(l.start.row<=s)break;if(l.isMultiLine())t=l.end.row;else if(r==f)break}u=t}return new i(s,o,u,e.getLine(u).length)}}.call(o.prototype)})
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/ace/worker-javascript.js b/dist/assets/js/vendor/ace/worker-javascript.js
            new file mode 100644
            index 0000000000..5cf7b6cceb
            --- /dev/null
            +++ b/dist/assets/js/vendor/ace/worker-javascript.js
            @@ -0,0 +1,10255 @@
            +"no use strict";
            +;(function(window) {
            +if (typeof window.window != "undefined" && window.document) {
            +    return;
            +}
            +
            +window.console = function() {
            +    var msgs = Array.prototype.slice.call(arguments, 0);
            +    postMessage({type: "log", data: msgs});
            +};
            +window.console.error =
            +window.console.warn = 
            +window.console.log =
            +window.console.trace = window.console;
            +
            +window.window = window;
            +window.ace = window;
            +
            +window.onerror = function(message, file, line, col, err) {
            +    console.error("Worker " + (err ? err.stack : message));
            +};
            +
            +window.normalizeModule = function(parentId, moduleName) {
            +    if (moduleName.indexOf("!") !== -1) {
            +        var chunks = moduleName.split("!");
            +        return window.normalizeModule(parentId, chunks[0]) + "!" + window.normalizeModule(parentId, chunks[1]);
            +    }
            +    if (moduleName.charAt(0) == ".") {
            +        var base = parentId.split("/").slice(0, -1).join("/");
            +        moduleName = (base ? base + "/" : "") + moduleName;
            +        
            +        while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
            +            var previous = moduleName;
            +            moduleName = moduleName.replace(/^\.\//, "").replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
            +        }
            +    }
            +    
            +    return moduleName;
            +};
            +
            +window.require = function(parentId, id) {
            +    if (!id) {
            +        id = parentId;
            +        parentId = null;
            +    }
            +    if (!id.charAt)
            +        throw new Error("worker.js require() accepts only (parentId, id) as arguments");
            +
            +    id = window.normalizeModule(parentId, id);
            +
            +    var module = window.require.modules[id];
            +    if (module) {
            +        if (!module.initialized) {
            +            module.initialized = true;
            +            module.exports = module.factory().exports;
            +        }
            +        return module.exports;
            +    }
            +    
            +    var chunks = id.split("/");
            +    if (!window.require.tlns)
            +        return console.log("unable to load " + id);
            +    chunks[0] = window.require.tlns[chunks[0]] || chunks[0];
            +    var path = chunks.join("/") + ".js";
            +    
            +    window.require.id = id;
            +    importScripts(path);
            +    return window.require(parentId, id);
            +};
            +window.require.modules = {};
            +window.require.tlns = {};
            +
            +window.define = function(id, deps, factory) {
            +    if (arguments.length == 2) {
            +        factory = deps;
            +        if (typeof id != "string") {
            +            deps = id;
            +            id = window.require.id;
            +        }
            +    } else if (arguments.length == 1) {
            +        factory = id;
            +        deps = [];
            +        id = window.require.id;
            +    }
            +
            +    if (!deps.length)
            +        deps = ['require', 'exports', 'module'];
            +
            +    if (id.indexOf("text!") === 0) 
            +        return;
            +    
            +    var req = function(childId) {
            +        return window.require(id, childId);
            +    };
            +
            +    window.require.modules[id] = {
            +        exports: {},
            +        factory: function() {
            +            var module = this;
            +            var returnExports = factory.apply(this, deps.map(function(dep) {
            +              switch(dep) {
            +                  case 'require': return req;
            +                  case 'exports': return module.exports;
            +                  case 'module':  return module;
            +                  default:        return req(dep);
            +              }
            +            }));
            +            if (returnExports)
            +                module.exports = returnExports;
            +            return module;
            +        }
            +    };
            +};
            +window.define.amd = {};
            +
            +window.initBaseUrls  = function initBaseUrls(topLevelNamespaces) {
            +    require.tlns = topLevelNamespaces;
            +};
            +
            +window.initSender = function initSender() {
            +
            +    var EventEmitter = window.require("ace/lib/event_emitter").EventEmitter;
            +    var oop = window.require("ace/lib/oop");
            +    
            +    var Sender = function() {};
            +    
            +    (function() {
            +        
            +        oop.implement(this, EventEmitter);
            +                
            +        this.callback = function(data, callbackId) {
            +            postMessage({
            +                type: "call",
            +                id: callbackId,
            +                data: data
            +            });
            +        };
            +    
            +        this.emit = function(name, data) {
            +            postMessage({
            +                type: "event",
            +                name: name,
            +                data: data
            +            });
            +        };
            +        
            +    }).call(Sender.prototype);
            +    
            +    return new Sender();
            +};
            +
            +var main = window.main = null;
            +var sender = window.sender = null;
            +
            +window.onmessage = function(e) {
            +    var msg = e.data;
            +    if (msg.command) {
            +        if (main[msg.command])
            +            main[msg.command].apply(main, msg.args);
            +        else
            +            throw new Error("Unknown command:" + msg.command);
            +    }
            +    else if (msg.init) {        
            +        initBaseUrls(msg.tlns);
            +        require("ace/lib/es5-shim");
            +        sender = window.sender = initSender();
            +        var clazz = require(msg.module)[msg.classname];
            +        main = window.main = new clazz(sender);
            +    } 
            +    else if (msg.event && sender) {
            +        sender._signal(msg.event, msg.data);
            +    }
            +};
            +})(this);
            +
            +define('ace/mode/javascript_worker', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/worker/mirror', 'ace/mode/javascript/jshint'], function(require, exports, module) {
            +
            +
            +var oop = require("../lib/oop");
            +var Mirror = require("../worker/mirror").Mirror;
            +var lint = require("./javascript/jshint").JSHINT;
            +
            +function startRegex(arr) {
            +    return RegExp("^(" + arr.join("|") + ")");
            +}
            +
            +var disabledWarningsRe = startRegex([
            +    "Bad for in variable '(.+)'.",
            +    'Missing "use strict"'
            +]);
            +var errorsRe = startRegex([
            +    "Unexpected",
            +    "Expected ",
            +    "Confusing (plus|minus)",
            +    "\\{a\\} unterminated regular expression",
            +    "Unclosed ",
            +    "Unmatched ",
            +    "Unbegun comment",
            +    "Bad invocation",
            +    "Missing space after",
            +    "Missing operator at"
            +]);
            +var infoRe = startRegex([
            +    "Expected an assignment",
            +    "Bad escapement of EOL",
            +    "Unexpected comma",
            +    "Unexpected space",
            +    "Missing radix parameter.",
            +    "A leading decimal point can",
            +    "\\['{a}'\\] is better written in dot notation.",
            +    "'{a}' used out of scope"
            +]);
            +
            +var JavaScriptWorker = exports.JavaScriptWorker = function(sender) {
            +    Mirror.call(this, sender);
            +    this.setTimeout(500);
            +    this.setOptions();
            +};
            +
            +oop.inherits(JavaScriptWorker, Mirror);
            +
            +(function() {
            +    this.setOptions = function(options) {
            +        this.options = options || {
            +            esnext: true,
            +            moz: true,
            +            devel: true,
            +            browser: true,
            +            node: true,
            +            laxcomma: true,
            +            laxbreak: true,
            +            lastsemic: true,
            +            onevar: false,
            +            passfail: false,
            +            maxerr: 100,
            +            expr: true,
            +            multistr: true,
            +            globalstrict: true
            +        };
            +        this.doc.getValue() && this.deferredUpdate.schedule(100);
            +    };
            +
            +    this.changeOptions = function(newOptions) {
            +        oop.mixin(this.options, newOptions);
            +        this.doc.getValue() && this.deferredUpdate.schedule(100);
            +    };
            +
            +    this.isValidJS = function(str) {
            +        try {
            +            eval("throw 0;" + str);
            +        } catch(e) {
            +            if (e === 0)
            +                return true;
            +        }
            +        return false
            +    };
            +
            +    this.onUpdate = function() {
            +        var value = this.doc.getValue();
            +        value = value.replace(/^#!.*\n/, "\n");
            +        if (!value) {
            +            this.sender.emit("jslint", []);
            +            return;
            +        }
            +        var errors = [];
            +        var maxErrorLevel = this.isValidJS(value) ? "warning" : "error";
            +        lint(value, this.options);
            +        var results = lint.errors;
            +
            +        var errorAdded = false
            +        for (var i = 0; i < results.length; i++) {
            +            var error = results[i];
            +            if (!error)
            +                continue;
            +            var raw = error.raw;
            +            var type = "warning";
            +
            +            if (raw == "Missing semicolon.") {
            +                var str = error.evidence.substr(error.character);
            +                str = str.charAt(str.search(/\S/));
            +                if (maxErrorLevel == "error" && str && /[\w\d{(['"]/.test(str)) {
            +                    error.reason = 'Missing ";" before statement';
            +                    type = "error";
            +                } else {
            +                    type = "info";
            +                }
            +            }
            +            else if (disabledWarningsRe.test(raw)) {
            +                continue;
            +            }
            +            else if (infoRe.test(raw)) {
            +                type = "info"
            +            }
            +            else if (errorsRe.test(raw)) {
            +                errorAdded  = true;
            +                type = maxErrorLevel;
            +            }
            +            else if (raw == "'{a}' is not defined.") {
            +                type = "warning";
            +            }
            +            else if (raw == "'{a}' is defined but never used.") {
            +                type = "info";
            +            }
            +
            +            errors.push({
            +                row: error.line-1,
            +                column: error.character-1,
            +                text: error.reason,
            +                type: type,
            +                raw: raw
            +            });
            +
            +            if (errorAdded) {
            +            }
            +        }
            +
            +        this.sender.emit("jslint", errors);
            +    };
            +
            +}).call(JavaScriptWorker.prototype);
            +
            +});
            +
            +define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
            +
            +
            +exports.inherits = function(ctor, superCtor) {
            +    ctor.super_ = superCtor;
            +    ctor.prototype = Object.create(superCtor.prototype, {
            +        constructor: {
            +            value: ctor,
            +            enumerable: false,
            +            writable: true,
            +            configurable: true
            +        }
            +    });
            +};
            +
            +exports.mixin = function(obj, mixin) {
            +    for (var key in mixin) {
            +        obj[key] = mixin[key];
            +    }
            +    return obj;
            +};
            +
            +exports.implement = function(proto, mixin) {
            +    exports.mixin(proto, mixin);
            +};
            +
            +});
            +define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
            +
            +
            +var Document = require("../document").Document;
            +var lang = require("../lib/lang");
            +    
            +var Mirror = exports.Mirror = function(sender) {
            +    this.sender = sender;
            +    var doc = this.doc = new Document("");
            +    
            +    var deferredUpdate = this.deferredUpdate = lang.delayedCall(this.onUpdate.bind(this));
            +    
            +    var _self = this;
            +    sender.on("change", function(e) {
            +        doc.applyDeltas(e.data);
            +        if (_self.$timeout)
            +            return deferredUpdate.schedule(_self.$timeout);
            +        _self.onUpdate();
            +    });
            +};
            +
            +(function() {
            +    
            +    this.$timeout = 500;
            +    
            +    this.setTimeout = function(timeout) {
            +        this.$timeout = timeout;
            +    };
            +    
            +    this.setValue = function(value) {
            +        this.doc.setValue(value);
            +        this.deferredUpdate.schedule(this.$timeout);
            +    };
            +    
            +    this.getValue = function(callbackId) {
            +        this.sender.callback(this.doc.getValue(), callbackId);
            +    };
            +    
            +    this.onUpdate = function() {
            +    };
            +    
            +    this.isPending = function() {
            +        return this.deferredUpdate.isPending();
            +    };
            +    
            +}).call(Mirror.prototype);
            +
            +});
            +
            +define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
            +
            +function Empty() {}
            +
            +if (!Function.prototype.bind) {
            +    Function.prototype.bind = function bind(that) { // .length is 1
            +        var target = this;
            +        if (typeof target != "function") {
            +            throw new TypeError("Function.prototype.bind called on incompatible " + target);
            +        }
            +        var args = slice.call(arguments, 1); // for normal call
            +        var bound = function () {
            +
            +            if (this instanceof bound) {
            +
            +                var result = target.apply(
            +                    this,
            +                    args.concat(slice.call(arguments))
            +                );
            +                if (Object(result) === result) {
            +                    return result;
            +                }
            +                return this;
            +
            +            } else {
            +                return target.apply(
            +                    that,
            +                    args.concat(slice.call(arguments))
            +                );
            +
            +            }
            +
            +        };
            +        if(target.prototype) {
            +            Empty.prototype = target.prototype;
            +            bound.prototype = new Empty();
            +            Empty.prototype = null;
            +        }
            +        return bound;
            +    };
            +}
            +var call = Function.prototype.call;
            +var prototypeOfArray = Array.prototype;
            +var prototypeOfObject = Object.prototype;
            +var slice = prototypeOfArray.slice;
            +var _toString = call.bind(prototypeOfObject.toString);
            +var owns = call.bind(prototypeOfObject.hasOwnProperty);
            +var defineGetter;
            +var defineSetter;
            +var lookupGetter;
            +var lookupSetter;
            +var supportsAccessors;
            +if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
            +    defineGetter = call.bind(prototypeOfObject.__defineGetter__);
            +    defineSetter = call.bind(prototypeOfObject.__defineSetter__);
            +    lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
            +    lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
            +}
            +if ([1,2].splice(0).length != 2) {
            +    if(function() { // test IE < 9 to splice bug - see issue #138
            +        function makeArray(l) {
            +            var a = new Array(l+2);
            +            a[0] = a[1] = 0;
            +            return a;
            +        }
            +        var array = [], lengthBefore;
            +        
            +        array.splice.apply(array, makeArray(20));
            +        array.splice.apply(array, makeArray(26));
            +
            +        lengthBefore = array.length; //46
            +        array.splice(5, 0, "XXX"); // add one element
            +
            +        lengthBefore + 1 == array.length
            +
            +        if (lengthBefore + 1 == array.length) {
            +            return true;// has right splice implementation without bugs
            +        }
            +    }()) {//IE 6/7
            +        var array_splice = Array.prototype.splice;
            +        Array.prototype.splice = function(start, deleteCount) {
            +            if (!arguments.length) {
            +                return [];
            +            } else {
            +                return array_splice.apply(this, [
            +                    start === void 0 ? 0 : start,
            +                    deleteCount === void 0 ? (this.length - start) : deleteCount
            +                ].concat(slice.call(arguments, 2)))
            +            }
            +        };
            +    } else {//IE8
            +        Array.prototype.splice = function(pos, removeCount){
            +            var length = this.length;
            +            if (pos > 0) {
            +                if (pos > length)
            +                    pos = length;
            +            } else if (pos == void 0) {
            +                pos = 0;
            +            } else if (pos < 0) {
            +                pos = Math.max(length + pos, 0);
            +            }
            +
            +            if (!(pos+removeCount < length))
            +                removeCount = length - pos;
            +
            +            var removed = this.slice(pos, pos+removeCount);
            +            var insert = slice.call(arguments, 2);
            +            var add = insert.length;            
            +            if (pos === length) {
            +                if (add) {
            +                    this.push.apply(this, insert);
            +                }
            +            } else {
            +                var remove = Math.min(removeCount, length - pos);
            +                var tailOldPos = pos + remove;
            +                var tailNewPos = tailOldPos + add - remove;
            +                var tailCount = length - tailOldPos;
            +                var lengthAfterRemove = length - remove;
            +
            +                if (tailNewPos < tailOldPos) { // case A
            +                    for (var i = 0; i < tailCount; ++i) {
            +                        this[tailNewPos+i] = this[tailOldPos+i];
            +                    }
            +                } else if (tailNewPos > tailOldPos) { // case B
            +                    for (i = tailCount; i--; ) {
            +                        this[tailNewPos+i] = this[tailOldPos+i];
            +                    }
            +                } // else, add == remove (nothing to do)
            +
            +                if (add && pos === lengthAfterRemove) {
            +                    this.length = lengthAfterRemove; // truncate array
            +                    this.push.apply(this, insert);
            +                } else {
            +                    this.length = lengthAfterRemove + add; // reserves space
            +                    for (i = 0; i < add; ++i) {
            +                        this[pos+i] = insert[i];
            +                    }
            +                }
            +            }
            +            return removed;
            +        };
            +    }
            +}
            +if (!Array.isArray) {
            +    Array.isArray = function isArray(obj) {
            +        return _toString(obj) == "[object Array]";
            +    };
            +}
            +var boxedString = Object("a"),
            +    splitString = boxedString[0] != "a" || !(0 in boxedString);
            +
            +if (!Array.prototype.forEach) {
            +    Array.prototype.forEach = function forEach(fun /*, thisp*/) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            thisp = arguments[1],
            +            i = -1,
            +            length = self.length >>> 0;
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(); // TODO message
            +        }
            +
            +        while (++i < length) {
            +            if (i in self) {
            +                fun.call(thisp, self[i], i, object);
            +            }
            +        }
            +    };
            +}
            +if (!Array.prototype.map) {
            +    Array.prototype.map = function map(fun /*, thisp*/) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0,
            +            result = Array(length),
            +            thisp = arguments[1];
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +
            +        for (var i = 0; i < length; i++) {
            +            if (i in self)
            +                result[i] = fun.call(thisp, self[i], i, object);
            +        }
            +        return result;
            +    };
            +}
            +if (!Array.prototype.filter) {
            +    Array.prototype.filter = function filter(fun /*, thisp */) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                    object,
            +            length = self.length >>> 0,
            +            result = [],
            +            value,
            +            thisp = arguments[1];
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +
            +        for (var i = 0; i < length; i++) {
            +            if (i in self) {
            +                value = self[i];
            +                if (fun.call(thisp, value, i, object)) {
            +                    result.push(value);
            +                }
            +            }
            +        }
            +        return result;
            +    };
            +}
            +if (!Array.prototype.every) {
            +    Array.prototype.every = function every(fun /*, thisp */) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0,
            +            thisp = arguments[1];
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +
            +        for (var i = 0; i < length; i++) {
            +            if (i in self && !fun.call(thisp, self[i], i, object)) {
            +                return false;
            +            }
            +        }
            +        return true;
            +    };
            +}
            +if (!Array.prototype.some) {
            +    Array.prototype.some = function some(fun /*, thisp */) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0,
            +            thisp = arguments[1];
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +
            +        for (var i = 0; i < length; i++) {
            +            if (i in self && fun.call(thisp, self[i], i, object)) {
            +                return true;
            +            }
            +        }
            +        return false;
            +    };
            +}
            +if (!Array.prototype.reduce) {
            +    Array.prototype.reduce = function reduce(fun /*, initial*/) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0;
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +        if (!length && arguments.length == 1) {
            +            throw new TypeError("reduce of empty array with no initial value");
            +        }
            +
            +        var i = 0;
            +        var result;
            +        if (arguments.length >= 2) {
            +            result = arguments[1];
            +        } else {
            +            do {
            +                if (i in self) {
            +                    result = self[i++];
            +                    break;
            +                }
            +                if (++i >= length) {
            +                    throw new TypeError("reduce of empty array with no initial value");
            +                }
            +            } while (true);
            +        }
            +
            +        for (; i < length; i++) {
            +            if (i in self) {
            +                result = fun.call(void 0, result, self[i], i, object);
            +            }
            +        }
            +
            +        return result;
            +    };
            +}
            +if (!Array.prototype.reduceRight) {
            +    Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
            +        var object = toObject(this),
            +            self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                object,
            +            length = self.length >>> 0;
            +        if (_toString(fun) != "[object Function]") {
            +            throw new TypeError(fun + " is not a function");
            +        }
            +        if (!length && arguments.length == 1) {
            +            throw new TypeError("reduceRight of empty array with no initial value");
            +        }
            +
            +        var result, i = length - 1;
            +        if (arguments.length >= 2) {
            +            result = arguments[1];
            +        } else {
            +            do {
            +                if (i in self) {
            +                    result = self[i--];
            +                    break;
            +                }
            +                if (--i < 0) {
            +                    throw new TypeError("reduceRight of empty array with no initial value");
            +                }
            +            } while (true);
            +        }
            +
            +        do {
            +            if (i in this) {
            +                result = fun.call(void 0, result, self[i], i, object);
            +            }
            +        } while (i--);
            +
            +        return result;
            +    };
            +}
            +if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
            +    Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
            +        var self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                toObject(this),
            +            length = self.length >>> 0;
            +
            +        if (!length) {
            +            return -1;
            +        }
            +
            +        var i = 0;
            +        if (arguments.length > 1) {
            +            i = toInteger(arguments[1]);
            +        }
            +        i = i >= 0 ? i : Math.max(0, length + i);
            +        for (; i < length; i++) {
            +            if (i in self && self[i] === sought) {
            +                return i;
            +            }
            +        }
            +        return -1;
            +    };
            +}
            +if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) {
            +    Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
            +        var self = splitString && _toString(this) == "[object String]" ?
            +                this.split("") :
            +                toObject(this),
            +            length = self.length >>> 0;
            +
            +        if (!length) {
            +            return -1;
            +        }
            +        var i = length - 1;
            +        if (arguments.length > 1) {
            +            i = Math.min(i, toInteger(arguments[1]));
            +        }
            +        i = i >= 0 ? i : length - Math.abs(i);
            +        for (; i >= 0; i--) {
            +            if (i in self && sought === self[i]) {
            +                return i;
            +            }
            +        }
            +        return -1;
            +    };
            +}
            +if (!Object.getPrototypeOf) {
            +    Object.getPrototypeOf = function getPrototypeOf(object) {
            +        return object.__proto__ || (
            +            object.constructor ?
            +            object.constructor.prototype :
            +            prototypeOfObject
            +        );
            +    };
            +}
            +if (!Object.getOwnPropertyDescriptor) {
            +    var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a " +
            +                         "non-object: ";
            +    Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
            +        if ((typeof object != "object" && typeof object != "function") || object === null)
            +            throw new TypeError(ERR_NON_OBJECT + object);
            +        if (!owns(object, property))
            +            return;
            +
            +        var descriptor, getter, setter;
            +        descriptor =  { enumerable: true, configurable: true };
            +        if (supportsAccessors) {
            +            var prototype = object.__proto__;
            +            object.__proto__ = prototypeOfObject;
            +
            +            var getter = lookupGetter(object, property);
            +            var setter = lookupSetter(object, property);
            +            object.__proto__ = prototype;
            +
            +            if (getter || setter) {
            +                if (getter) descriptor.get = getter;
            +                if (setter) descriptor.set = setter;
            +                return descriptor;
            +            }
            +        }
            +        descriptor.value = object[property];
            +        return descriptor;
            +    };
            +}
            +if (!Object.getOwnPropertyNames) {
            +    Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
            +        return Object.keys(object);
            +    };
            +}
            +if (!Object.create) {
            +    var createEmpty;
            +    if (Object.prototype.__proto__ === null) {
            +        createEmpty = function () {
            +            return { "__proto__": null };
            +        };
            +    } else {
            +        createEmpty = function () {
            +            var empty = {};
            +            for (var i in empty)
            +                empty[i] = null;
            +            empty.constructor =
            +            empty.hasOwnProperty =
            +            empty.propertyIsEnumerable =
            +            empty.isPrototypeOf =
            +            empty.toLocaleString =
            +            empty.toString =
            +            empty.valueOf =
            +            empty.__proto__ = null;
            +            return empty;
            +        }
            +    }
            +
            +    Object.create = function create(prototype, properties) {
            +        var object;
            +        if (prototype === null) {
            +            object = createEmpty();
            +        } else {
            +            if (typeof prototype != "object")
            +                throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
            +            var Type = function () {};
            +            Type.prototype = prototype;
            +            object = new Type();
            +            object.__proto__ = prototype;
            +        }
            +        if (properties !== void 0)
            +            Object.defineProperties(object, properties);
            +        return object;
            +    };
            +}
            +
            +function doesDefinePropertyWork(object) {
            +    try {
            +        Object.defineProperty(object, "sentinel", {});
            +        return "sentinel" in object;
            +    } catch (exception) {
            +    }
            +}
            +if (Object.defineProperty) {
            +    var definePropertyWorksOnObject = doesDefinePropertyWork({});
            +    var definePropertyWorksOnDom = typeof document == "undefined" ||
            +        doesDefinePropertyWork(document.createElement("div"));
            +    if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
            +        var definePropertyFallback = Object.defineProperty;
            +    }
            +}
            +
            +if (!Object.defineProperty || definePropertyFallback) {
            +    var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
            +    var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
            +    var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
            +                                      "on this javascript engine";
            +
            +    Object.defineProperty = function defineProperty(object, property, descriptor) {
            +        if ((typeof object != "object" && typeof object != "function") || object === null)
            +            throw new TypeError(ERR_NON_OBJECT_TARGET + object);
            +        if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null)
            +            throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
            +        if (definePropertyFallback) {
            +            try {
            +                return definePropertyFallback.call(Object, object, property, descriptor);
            +            } catch (exception) {
            +            }
            +        }
            +        if (owns(descriptor, "value")) {
            +
            +            if (supportsAccessors && (lookupGetter(object, property) ||
            +                                      lookupSetter(object, property)))
            +            {
            +                var prototype = object.__proto__;
            +                object.__proto__ = prototypeOfObject;
            +                delete object[property];
            +                object[property] = descriptor.value;
            +                object.__proto__ = prototype;
            +            } else {
            +                object[property] = descriptor.value;
            +            }
            +        } else {
            +            if (!supportsAccessors)
            +                throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
            +            if (owns(descriptor, "get"))
            +                defineGetter(object, property, descriptor.get);
            +            if (owns(descriptor, "set"))
            +                defineSetter(object, property, descriptor.set);
            +        }
            +
            +        return object;
            +    };
            +}
            +if (!Object.defineProperties) {
            +    Object.defineProperties = function defineProperties(object, properties) {
            +        for (var property in properties) {
            +            if (owns(properties, property))
            +                Object.defineProperty(object, property, properties[property]);
            +        }
            +        return object;
            +    };
            +}
            +if (!Object.seal) {
            +    Object.seal = function seal(object) {
            +        return object;
            +    };
            +}
            +if (!Object.freeze) {
            +    Object.freeze = function freeze(object) {
            +        return object;
            +    };
            +}
            +try {
            +    Object.freeze(function () {});
            +} catch (exception) {
            +    Object.freeze = (function freeze(freezeObject) {
            +        return function freeze(object) {
            +            if (typeof object == "function") {
            +                return object;
            +            } else {
            +                return freezeObject(object);
            +            }
            +        };
            +    })(Object.freeze);
            +}
            +if (!Object.preventExtensions) {
            +    Object.preventExtensions = function preventExtensions(object) {
            +        return object;
            +    };
            +}
            +if (!Object.isSealed) {
            +    Object.isSealed = function isSealed(object) {
            +        return false;
            +    };
            +}
            +if (!Object.isFrozen) {
            +    Object.isFrozen = function isFrozen(object) {
            +        return false;
            +    };
            +}
            +if (!Object.isExtensible) {
            +    Object.isExtensible = function isExtensible(object) {
            +        if (Object(object) === object) {
            +            throw new TypeError(); // TODO message
            +        }
            +        var name = '';
            +        while (owns(object, name)) {
            +            name += '?';
            +        }
            +        object[name] = true;
            +        var returnValue = owns(object, name);
            +        delete object[name];
            +        return returnValue;
            +    };
            +}
            +if (!Object.keys) {
            +    var hasDontEnumBug = true,
            +        dontEnums = [
            +            "toString",
            +            "toLocaleString",
            +            "valueOf",
            +            "hasOwnProperty",
            +            "isPrototypeOf",
            +            "propertyIsEnumerable",
            +            "constructor"
            +        ],
            +        dontEnumsLength = dontEnums.length;
            +
            +    for (var key in {"toString": null}) {
            +        hasDontEnumBug = false;
            +    }
            +
            +    Object.keys = function keys(object) {
            +
            +        if (
            +            (typeof object != "object" && typeof object != "function") ||
            +            object === null
            +        ) {
            +            throw new TypeError("Object.keys called on a non-object");
            +        }
            +
            +        var keys = [];
            +        for (var name in object) {
            +            if (owns(object, name)) {
            +                keys.push(name);
            +            }
            +        }
            +
            +        if (hasDontEnumBug) {
            +            for (var i = 0, ii = dontEnumsLength; i < ii; i++) {
            +                var dontEnum = dontEnums[i];
            +                if (owns(object, dontEnum)) {
            +                    keys.push(dontEnum);
            +                }
            +            }
            +        }
            +        return keys;
            +    };
            +
            +}
            +if (!Date.now) {
            +    Date.now = function now() {
            +        return new Date().getTime();
            +    };
            +}
            +var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
            +    "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" +
            +    "\u2029\uFEFF";
            +if (!String.prototype.trim || ws.trim()) {
            +    ws = "[" + ws + "]";
            +    var trimBeginRegexp = new RegExp("^" + ws + ws + "*"),
            +        trimEndRegexp = new RegExp(ws + ws + "*$");
            +    String.prototype.trim = function trim() {
            +        return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
            +    };
            +}
            +
            +function toInteger(n) {
            +    n = +n;
            +    if (n !== n) { // isNaN
            +        n = 0;
            +    } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) {
            +        n = (n > 0 || -1) * Math.floor(Math.abs(n));
            +    }
            +    return n;
            +}
            +
            +function isPrimitive(input) {
            +    var type = typeof input;
            +    return (
            +        input === null ||
            +        type === "undefined" ||
            +        type === "boolean" ||
            +        type === "number" ||
            +        type === "string"
            +    );
            +}
            +
            +function toPrimitive(input) {
            +    var val, valueOf, toString;
            +    if (isPrimitive(input)) {
            +        return input;
            +    }
            +    valueOf = input.valueOf;
            +    if (typeof valueOf === "function") {
            +        val = valueOf.call(input);
            +        if (isPrimitive(val)) {
            +            return val;
            +        }
            +    }
            +    toString = input.toString;
            +    if (typeof toString === "function") {
            +        val = toString.call(input);
            +        if (isPrimitive(val)) {
            +            return val;
            +        }
            +    }
            +    throw new TypeError();
            +}
            +var toObject = function (o) {
            +    if (o == null) { // this matches both null and undefined
            +        throw new TypeError("can't convert "+o+" to object");
            +    }
            +    return Object(o);
            +};
            +
            +});
            +
            +define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
            +
            +
            +var EventEmitter = {};
            +var stopPropagation = function() { this.propagationStopped = true; };
            +var preventDefault = function() { this.defaultPrevented = true; };
            +
            +EventEmitter._emit =
            +EventEmitter._dispatchEvent = function(eventName, e) {
            +    this._eventRegistry || (this._eventRegistry = {});
            +    this._defaultHandlers || (this._defaultHandlers = {});
            +
            +    var listeners = this._eventRegistry[eventName] || [];
            +    var defaultHandler = this._defaultHandlers[eventName];
            +    if (!listeners.length && !defaultHandler)
            +        return;
            +
            +    if (typeof e != "object" || !e)
            +        e = {};
            +
            +    if (!e.type)
            +        e.type = eventName;
            +    if (!e.stopPropagation)
            +        e.stopPropagation = stopPropagation;
            +    if (!e.preventDefault)
            +        e.preventDefault = preventDefault;
            +
            +    listeners = listeners.slice();
            +    for (var i=0; i<listeners.length; i++) {
            +        listeners[i](e, this);
            +        if (e.propagationStopped)
            +            break;
            +    }
            +    
            +    if (defaultHandler && !e.defaultPrevented)
            +        return defaultHandler(e, this);
            +};
            +
            +
            +EventEmitter._signal = function(eventName, e) {
            +    var listeners = (this._eventRegistry || {})[eventName];
            +    if (!listeners)
            +        return;
            +    listeners = listeners.slice();
            +    for (var i=0; i<listeners.length; i++)
            +        listeners[i](e, this);
            +};
            +
            +EventEmitter.once = function(eventName, callback) {
            +    var _self = this;
            +    callback && this.addEventListener(eventName, function newCallback() {
            +        _self.removeEventListener(eventName, newCallback);
            +        callback.apply(null, arguments);
            +    });
            +};
            +
            +
            +EventEmitter.setDefaultHandler = function(eventName, callback) {
            +    var handlers = this._defaultHandlers
            +    if (!handlers)
            +        handlers = this._defaultHandlers = {_disabled_: {}};
            +    
            +    if (handlers[eventName]) {
            +        var old = handlers[eventName];
            +        var disabled = handlers._disabled_[eventName];
            +        if (!disabled)
            +            handlers._disabled_[eventName] = disabled = [];
            +        disabled.push(old);
            +        var i = disabled.indexOf(callback);
            +        if (i != -1) 
            +            disabled.splice(i, 1);
            +    }
            +    handlers[eventName] = callback;
            +};
            +EventEmitter.removeDefaultHandler = function(eventName, callback) {
            +    var handlers = this._defaultHandlers
            +    if (!handlers)
            +        return;
            +    var disabled = handlers._disabled_[eventName];
            +    
            +    if (handlers[eventName] == callback) {
            +        var old = handlers[eventName];
            +        if (disabled)
            +            this.setDefaultHandler(eventName, disabled.pop());
            +    } else if (disabled) {
            +        var i = disabled.indexOf(callback);
            +        if (i != -1)
            +            disabled.splice(i, 1);
            +    }
            +};
            +
            +EventEmitter.on =
            +EventEmitter.addEventListener = function(eventName, callback, capturing) {
            +    this._eventRegistry = this._eventRegistry || {};
            +
            +    var listeners = this._eventRegistry[eventName];
            +    if (!listeners)
            +        listeners = this._eventRegistry[eventName] = [];
            +
            +    if (listeners.indexOf(callback) == -1)
            +        listeners[capturing ? "unshift" : "push"](callback);
            +    return callback;
            +};
            +
            +EventEmitter.off =
            +EventEmitter.removeListener =
            +EventEmitter.removeEventListener = function(eventName, callback) {
            +    this._eventRegistry = this._eventRegistry || {};
            +
            +    var listeners = this._eventRegistry[eventName];
            +    if (!listeners)
            +        return;
            +
            +    var index = listeners.indexOf(callback);
            +    if (index !== -1)
            +        listeners.splice(index, 1);
            +};
            +
            +EventEmitter.removeAllListeners = function(eventName) {
            +    if (this._eventRegistry) this._eventRegistry[eventName] = [];
            +};
            +
            +exports.EventEmitter = EventEmitter;
            +
            +});
            +
            +define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
            +
            +var comparePoints = function(p1, p2) {
            +    return p1.row - p2.row || p1.column - p2.column;
            +};
            +var Range = function(startRow, startColumn, endRow, endColumn) {
            +    this.start = {
            +        row: startRow,
            +        column: startColumn
            +    };
            +
            +    this.end = {
            +        row: endRow,
            +        column: endColumn
            +    };
            +};
            +
            +(function() {
            +    this.isEqual = function(range) {
            +        return this.start.row === range.start.row &&
            +            this.end.row === range.end.row &&
            +            this.start.column === range.start.column &&
            +            this.end.column === range.end.column;
            +    };
            +    this.toString = function() {
            +        return ("Range: [" + this.start.row + "/" + this.start.column +
            +            "] -> [" + this.end.row + "/" + this.end.column + "]");
            +    };
            +
            +    this.contains = function(row, column) {
            +        return this.compare(row, column) == 0;
            +    };
            +    this.compareRange = function(range) {
            +        var cmp,
            +            end = range.end,
            +            start = range.start;
            +
            +        cmp = this.compare(end.row, end.column);
            +        if (cmp == 1) {
            +            cmp = this.compare(start.row, start.column);
            +            if (cmp == 1) {
            +                return 2;
            +            } else if (cmp == 0) {
            +                return 1;
            +            } else {
            +                return 0;
            +            }
            +        } else if (cmp == -1) {
            +            return -2;
            +        } else {
            +            cmp = this.compare(start.row, start.column);
            +            if (cmp == -1) {
            +                return -1;
            +            } else if (cmp == 1) {
            +                return 42;
            +            } else {
            +                return 0;
            +            }
            +        }
            +    };
            +    this.comparePoint = function(p) {
            +        return this.compare(p.row, p.column);
            +    };
            +    this.containsRange = function(range) {
            +        return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
            +    };
            +    this.intersects = function(range) {
            +        var cmp = this.compareRange(range);
            +        return (cmp == -1 || cmp == 0 || cmp == 1);
            +    };
            +    this.isEnd = function(row, column) {
            +        return this.end.row == row && this.end.column == column;
            +    };
            +    this.isStart = function(row, column) {
            +        return this.start.row == row && this.start.column == column;
            +    };
            +    this.setStart = function(row, column) {
            +        if (typeof row == "object") {
            +            this.start.column = row.column;
            +            this.start.row = row.row;
            +        } else {
            +            this.start.row = row;
            +            this.start.column = column;
            +        }
            +    };
            +    this.setEnd = function(row, column) {
            +        if (typeof row == "object") {
            +            this.end.column = row.column;
            +            this.end.row = row.row;
            +        } else {
            +            this.end.row = row;
            +            this.end.column = column;
            +        }
            +    };
            +    this.inside = function(row, column) {
            +        if (this.compare(row, column) == 0) {
            +            if (this.isEnd(row, column) || this.isStart(row, column)) {
            +                return false;
            +            } else {
            +                return true;
            +            }
            +        }
            +        return false;
            +    };
            +    this.insideStart = function(row, column) {
            +        if (this.compare(row, column) == 0) {
            +            if (this.isEnd(row, column)) {
            +                return false;
            +            } else {
            +                return true;
            +            }
            +        }
            +        return false;
            +    };
            +    this.insideEnd = function(row, column) {
            +        if (this.compare(row, column) == 0) {
            +            if (this.isStart(row, column)) {
            +                return false;
            +            } else {
            +                return true;
            +            }
            +        }
            +        return false;
            +    };
            +    this.compare = function(row, column) {
            +        if (!this.isMultiLine()) {
            +            if (row === this.start.row) {
            +                return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
            +            };
            +        }
            +
            +        if (row < this.start.row)
            +            return -1;
            +
            +        if (row > this.end.row)
            +            return 1;
            +
            +        if (this.start.row === row)
            +            return column >= this.start.column ? 0 : -1;
            +
            +        if (this.end.row === row)
            +            return column <= this.end.column ? 0 : 1;
            +
            +        return 0;
            +    };
            +    this.compareStart = function(row, column) {
            +        if (this.start.row == row && this.start.column == column) {
            +            return -1;
            +        } else {
            +            return this.compare(row, column);
            +        }
            +    };
            +    this.compareEnd = function(row, column) {
            +        if (this.end.row == row && this.end.column == column) {
            +            return 1;
            +        } else {
            +            return this.compare(row, column);
            +        }
            +    };
            +    this.compareInside = function(row, column) {
            +        if (this.end.row == row && this.end.column == column) {
            +            return 1;
            +        } else if (this.start.row == row && this.start.column == column) {
            +            return -1;
            +        } else {
            +            return this.compare(row, column);
            +        }
            +    };
            +    this.clipRows = function(firstRow, lastRow) {
            +        if (this.end.row > lastRow)
            +            var end = {row: lastRow + 1, column: 0};
            +        else if (this.end.row < firstRow)
            +            var end = {row: firstRow, column: 0};
            +
            +        if (this.start.row > lastRow)
            +            var start = {row: lastRow + 1, column: 0};
            +        else if (this.start.row < firstRow)
            +            var start = {row: firstRow, column: 0};
            +
            +        return Range.fromPoints(start || this.start, end || this.end);
            +    };
            +    this.extend = function(row, column) {
            +        var cmp = this.compare(row, column);
            +
            +        if (cmp == 0)
            +            return this;
            +        else if (cmp == -1)
            +            var start = {row: row, column: column};
            +        else
            +            var end = {row: row, column: column};
            +
            +        return Range.fromPoints(start || this.start, end || this.end);
            +    };
            +
            +    this.isEmpty = function() {
            +        return (this.start.row === this.end.row && this.start.column === this.end.column);
            +    };
            +    this.isMultiLine = function() {
            +        return (this.start.row !== this.end.row);
            +    };
            +    this.clone = function() {
            +        return Range.fromPoints(this.start, this.end);
            +    };
            +    this.collapseRows = function() {
            +        if (this.end.column == 0)
            +            return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
            +        else
            +            return new Range(this.start.row, 0, this.end.row, 0)
            +    };
            +    this.toScreenRange = function(session) {
            +        var screenPosStart = session.documentToScreenPosition(this.start);
            +        var screenPosEnd = session.documentToScreenPosition(this.end);
            +
            +        return new Range(
            +            screenPosStart.row, screenPosStart.column,
            +            screenPosEnd.row, screenPosEnd.column
            +        );
            +    };
            +    this.moveBy = function(row, column) {
            +        this.start.row += row;
            +        this.start.column += column;
            +        this.end.row += row;
            +        this.end.column += column;
            +    };
            +
            +}).call(Range.prototype);
            +Range.fromPoints = function(start, end) {
            +    return new Range(start.row, start.column, end.row, end.column);
            +};
            +Range.comparePoints = comparePoints;
            +
            +Range.comparePoints = function(p1, p2) {
            +    return p1.row - p2.row || p1.column - p2.column;
            +};
            +
            +
            +exports.Range = Range;
            +});
            +
            +define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
            +
            +
            +var oop = require("./lib/oop");
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +
            +var Anchor = exports.Anchor = function(doc, row, column) {
            +    this.$onChange = this.onChange.bind(this);
            +    this.attach(doc);
            +    
            +    if (typeof column == "undefined")
            +        this.setPosition(row.row, row.column);
            +    else
            +        this.setPosition(row, column);
            +};
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +    this.getPosition = function() {
            +        return this.$clipPositionToDocument(this.row, this.column);
            +    };
            +    this.getDocument = function() {
            +        return this.document;
            +    };
            +    this.$insertRight = false;
            +    this.onChange = function(e) {
            +        var delta = e.data;
            +        var range = delta.range;
            +
            +        if (range.start.row == range.end.row && range.start.row != this.row)
            +            return;
            +
            +        if (range.start.row > this.row)
            +            return;
            +
            +        if (range.start.row == this.row && range.start.column > this.column)
            +            return;
            +
            +        var row = this.row;
            +        var column = this.column;
            +        var start = range.start;
            +        var end = range.end;
            +
            +        if (delta.action === "insertText") {
            +            if (start.row === row && start.column <= column) {
            +                if (start.column === column && this.$insertRight) {
            +                } else if (start.row === end.row) {
            +                    column += end.column - start.column;
            +                } else {
            +                    column -= start.column;
            +                    row += end.row - start.row;
            +                }
            +            } else if (start.row !== end.row && start.row < row) {
            +                row += end.row - start.row;
            +            }
            +        } else if (delta.action === "insertLines") {
            +            if (start.row === row && column === 0 && this.$insertRight) {
            +            }
            +            else if (start.row <= row) {
            +                row += end.row - start.row;
            +            }
            +        } else if (delta.action === "removeText") {
            +            if (start.row === row && start.column < column) {
            +                if (end.column >= column)
            +                    column = start.column;
            +                else
            +                    column = Math.max(0, column - (end.column - start.column));
            +
            +            } else if (start.row !== end.row && start.row < row) {
            +                if (end.row === row)
            +                    column = Math.max(0, column - end.column) + start.column;
            +                row -= (end.row - start.row);
            +            } else if (end.row === row) {
            +                row -= end.row - start.row;
            +                column = Math.max(0, column - end.column) + start.column;
            +            }
            +        } else if (delta.action == "removeLines") {
            +            if (start.row <= row) {
            +                if (end.row <= row)
            +                    row -= end.row - start.row;
            +                else {
            +                    row = start.row;
            +                    column = 0;
            +                }
            +            }
            +        }
            +
            +        this.setPosition(row, column, true);
            +    };
            +    this.setPosition = function(row, column, noClip) {
            +        var pos;
            +        if (noClip) {
            +            pos = {
            +                row: row,
            +                column: column
            +            };
            +        } else {
            +            pos = this.$clipPositionToDocument(row, column);
            +        }
            +
            +        if (this.row == pos.row && this.column == pos.column)
            +            return;
            +
            +        var old = {
            +            row: this.row,
            +            column: this.column
            +        };
            +
            +        this.row = pos.row;
            +        this.column = pos.column;
            +        this._signal("change", {
            +            old: old,
            +            value: pos
            +        });
            +    };
            +    this.detach = function() {
            +        this.document.removeEventListener("change", this.$onChange);
            +    };
            +    this.attach = function(doc) {
            +        this.document = doc || this.document;
            +        this.document.on("change", this.$onChange);
            +    };
            +    this.$clipPositionToDocument = function(row, column) {
            +        var pos = {};
            +
            +        if (row >= this.document.getLength()) {
            +            pos.row = Math.max(0, this.document.getLength() - 1);
            +            pos.column = this.document.getLine(pos.row).length;
            +        }
            +        else if (row < 0) {
            +            pos.row = 0;
            +            pos.column = 0;
            +        }
            +        else {
            +            pos.row = row;
            +            pos.column = Math.min(this.document.getLine(pos.row).length, Math.max(0, column));
            +        }
            +
            +        if (column < 0)
            +            pos.column = 0;
            +
            +        return pos;
            +    };
            +
            +}).call(Anchor.prototype);
            +
            +});
            +
            +define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
            +
            +
            +exports.last = function(a) {
            +    return a[a.length - 1];
            +};
            +
            +exports.stringReverse = function(string) {
            +    return string.split("").reverse().join("");
            +};
            +
            +exports.stringRepeat = function (string, count) {
            +    var result = '';
            +    while (count > 0) {
            +        if (count & 1)
            +            result += string;
            +
            +        if (count >>= 1)
            +            string += string;
            +    }
            +    return result;
            +};
            +
            +var trimBeginRegexp = /^\s\s*/;
            +var trimEndRegexp = /\s\s*$/;
            +
            +exports.stringTrimLeft = function (string) {
            +    return string.replace(trimBeginRegexp, '');
            +};
            +
            +exports.stringTrimRight = function (string) {
            +    return string.replace(trimEndRegexp, '');
            +};
            +
            +exports.copyObject = function(obj) {
            +    var copy = {};
            +    for (var key in obj) {
            +        copy[key] = obj[key];
            +    }
            +    return copy;
            +};
            +
            +exports.copyArray = function(array){
            +    var copy = [];
            +    for (var i=0, l=array.length; i<l; i++) {
            +        if (array[i] && typeof array[i] == "object")
            +            copy[i] = this.copyObject( array[i] );
            +        else 
            +            copy[i] = array[i];
            +    }
            +    return copy;
            +};
            +
            +exports.deepCopy = function (obj) {
            +    if (typeof obj !== "object" || !obj)
            +        return obj;
            +    var cons = obj.constructor;
            +    if (cons === RegExp)
            +        return obj;
            +    
            +    var copy = cons();
            +    for (var key in obj) {
            +        if (typeof obj[key] === "object") {
            +            copy[key] = exports.deepCopy(obj[key]);
            +        } else {
            +            copy[key] = obj[key];
            +        }
            +    }
            +    return copy;
            +};
            +
            +exports.arrayToMap = function(arr) {
            +    var map = {};
            +    for (var i=0; i<arr.length; i++) {
            +        map[arr[i]] = 1;
            +    }
            +    return map;
            +
            +};
            +
            +exports.createMap = function(props) {
            +    var map = Object.create(null);
            +    for (var i in props) {
            +        map[i] = props[i];
            +    }
            +    return map;
            +};
            +exports.arrayRemove = function(array, value) {
            +  for (var i = 0; i <= array.length; i++) {
            +    if (value === array[i]) {
            +      array.splice(i, 1);
            +    }
            +  }
            +};
            +
            +exports.escapeRegExp = function(str) {
            +    return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
            +};
            +
            +exports.escapeHTML = function(str) {
            +    return str.replace(/&/g, "&#38;").replace(/"/g, "&#34;").replace(/'/g, "&#39;").replace(/</g, "&#60;");
            +};
            +
            +exports.getMatchOffsets = function(string, regExp) {
            +    var matches = [];
            +
            +    string.replace(regExp, function(str) {
            +        matches.push({
            +            offset: arguments[arguments.length-2],
            +            length: str.length
            +        });
            +    });
            +
            +    return matches;
            +};
            +exports.deferredCall = function(fcn) {
            +
            +    var timer = null;
            +    var callback = function() {
            +        timer = null;
            +        fcn();
            +    };
            +
            +    var deferred = function(timeout) {
            +        deferred.cancel();
            +        timer = setTimeout(callback, timeout || 0);
            +        return deferred;
            +    };
            +
            +    deferred.schedule = deferred;
            +
            +    deferred.call = function() {
            +        this.cancel();
            +        fcn();
            +        return deferred;
            +    };
            +
            +    deferred.cancel = function() {
            +        clearTimeout(timer);
            +        timer = null;
            +        return deferred;
            +    };
            +    
            +    deferred.isPending = function() {
            +        return timer;
            +    };
            +
            +    return deferred;
            +};
            +
            +
            +exports.delayedCall = function(fcn, defaultTimeout) {
            +    var timer = null;
            +    var callback = function() {
            +        timer = null;
            +        fcn();
            +    };
            +
            +    var _self = function(timeout) {
            +        if (timer == null)
            +            timer = setTimeout(callback, timeout || defaultTimeout);
            +    };
            +
            +    _self.delay = function(timeout) {
            +        timer && clearTimeout(timer);
            +        timer = setTimeout(callback, timeout || defaultTimeout);
            +    };
            +    _self.schedule = _self;
            +
            +    _self.call = function() {
            +        this.cancel();
            +        fcn();
            +    };
            +
            +    _self.cancel = function() {
            +        timer && clearTimeout(timer);
            +        timer = null;
            +    };
            +
            +    _self.isPending = function() {
            +        return timer;
            +    };
            +
            +    return _self;
            +};
            +});
            +define('ace/mode/javascript/jshint', ['require', 'exports', 'module' ], function(require, exports, module) {
            +module.exports = (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({
            +1:[function(_dereq_,module,exports){
            +var identifierStartTable = [];
            +
            +for (var i = 0; i < 128; i++) {
            +  identifierStartTable[i] =
            +    i === 36 ||           // $
            +    i >= 65 && i <= 90 || // A-Z
            +    i === 95 ||           // _
            +    i >= 97 && i <= 122;  // a-z
            +}
            +
            +var identifierPartTable = [];
            +
            +for (var i = 0; i < 128; i++) {
            +  identifierPartTable[i] =
            +    identifierStartTable[i] || // $, _, A-Z, a-z
            +    i >= 48 && i <= 57;        // 0-9
            +}
            +
            +module.exports = {
            +  asciiIdentifierStartTable: identifierStartTable,
            +  asciiIdentifierPartTable: identifierPartTable
            +};
            +
            +},
            +{}],
            +2:[function(_dereq_,module,exports){
            +
            +(function() {
            +  var root = this;
            +  var previousUnderscore = root._;
            +  var breaker = {};
            +  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
            +  var push             = ArrayProto.push,
            +      slice            = ArrayProto.slice,
            +      concat           = ArrayProto.concat,
            +      toString         = ObjProto.toString,
            +      hasOwnProperty   = ObjProto.hasOwnProperty;
            +  var
            +    nativeForEach      = ArrayProto.forEach,
            +    nativeMap          = ArrayProto.map,
            +    nativeReduce       = ArrayProto.reduce,
            +    nativeReduceRight  = ArrayProto.reduceRight,
            +    nativeFilter       = ArrayProto.filter,
            +    nativeEvery        = ArrayProto.every,
            +    nativeSome         = ArrayProto.some,
            +    nativeIndexOf      = ArrayProto.indexOf,
            +    nativeLastIndexOf  = ArrayProto.lastIndexOf,
            +    nativeIsArray      = Array.isArray,
            +    nativeKeys         = Object.keys,
            +    nativeBind         = FuncProto.bind;
            +  var _ = function(obj) {
            +    if (obj instanceof _) return obj;
            +    if (!(this instanceof _)) return new _(obj);
            +    this._wrapped = obj;
            +  };
            +  if (typeof exports !== 'undefined') {
            +    if (typeof module !== 'undefined' && module.exports) {
            +      exports = module.exports = _;
            +    }
            +    exports._ = _;
            +  } else {
            +    root._ = _;
            +  }
            +  _.VERSION = '1.4.4';
            +  var each = _.each = _.forEach = function(obj, iterator, context) {
            +    if (obj == null) return;
            +    if (nativeForEach && obj.forEach === nativeForEach) {
            +      obj.forEach(iterator, context);
            +    } else if (obj.length === +obj.length) {
            +      for (var i = 0, l = obj.length; i < l; i++) {
            +        if (iterator.call(context, obj[i], i, obj) === breaker) return;
            +      }
            +    } else {
            +      for (var key in obj) {
            +        if (_.has(obj, key)) {
            +          if (iterator.call(context, obj[key], key, obj) === breaker) return;
            +        }
            +      }
            +    }
            +  };
            +  _.map = _.collect = function(obj, iterator, context) {
            +    var results = [];
            +    if (obj == null) return results;
            +    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
            +    each(obj, function(value, index, list) {
            +      results[results.length] = iterator.call(context, value, index, list);
            +    });
            +    return results;
            +  };
            +
            +  var reduceError = 'Reduce of empty array with no initial value';
            +  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
            +    var initial = arguments.length > 2;
            +    if (obj == null) obj = [];
            +    if (nativeReduce && obj.reduce === nativeReduce) {
            +      if (context) iterator = _.bind(iterator, context);
            +      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
            +    }
            +    each(obj, function(value, index, list) {
            +      if (!initial) {
            +        memo = value;
            +        initial = true;
            +      } else {
            +        memo = iterator.call(context, memo, value, index, list);
            +      }
            +    });
            +    if (!initial) throw new TypeError(reduceError);
            +    return memo;
            +  };
            +  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
            +    var initial = arguments.length > 2;
            +    if (obj == null) obj = [];
            +    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
            +      if (context) iterator = _.bind(iterator, context);
            +      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
            +    }
            +    var length = obj.length;
            +    if (length !== +length) {
            +      var keys = _.keys(obj);
            +      length = keys.length;
            +    }
            +    each(obj, function(value, index, list) {
            +      index = keys ? keys[--length] : --length;
            +      if (!initial) {
            +        memo = obj[index];
            +        initial = true;
            +      } else {
            +        memo = iterator.call(context, memo, obj[index], index, list);
            +      }
            +    });
            +    if (!initial) throw new TypeError(reduceError);
            +    return memo;
            +  };
            +  _.find = _.detect = function(obj, iterator, context) {
            +    var result;
            +    any(obj, function(value, index, list) {
            +      if (iterator.call(context, value, index, list)) {
            +        result = value;
            +        return true;
            +      }
            +    });
            +    return result;
            +  };
            +  _.filter = _.select = function(obj, iterator, context) {
            +    var results = [];
            +    if (obj == null) return results;
            +    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
            +    each(obj, function(value, index, list) {
            +      if (iterator.call(context, value, index, list)) results[results.length] = value;
            +    });
            +    return results;
            +  };
            +  _.reject = function(obj, iterator, context) {
            +    return _.filter(obj, function(value, index, list) {
            +      return !iterator.call(context, value, index, list);
            +    }, context);
            +  };
            +  _.every = _.all = function(obj, iterator, context) {
            +    iterator || (iterator = _.identity);
            +    var result = true;
            +    if (obj == null) return result;
            +    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
            +    each(obj, function(value, index, list) {
            +      if (!(result = result && iterator.call(context, value, index, list))) return breaker;
            +    });
            +    return !!result;
            +  };
            +  var any = _.some = _.any = function(obj, iterator, context) {
            +    iterator || (iterator = _.identity);
            +    var result = false;
            +    if (obj == null) return result;
            +    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
            +    each(obj, function(value, index, list) {
            +      if (result || (result = iterator.call(context, value, index, list))) return breaker;
            +    });
            +    return !!result;
            +  };
            +  _.contains = _.include = function(obj, target) {
            +    if (obj == null) return false;
            +    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
            +    return any(obj, function(value) {
            +      return value === target;
            +    });
            +  };
            +  _.invoke = function(obj, method) {
            +    var args = slice.call(arguments, 2);
            +    var isFunc = _.isFunction(method);
            +    return _.map(obj, function(value) {
            +      return (isFunc ? method : value[method]).apply(value, args);
            +    });
            +  };
            +  _.pluck = function(obj, key) {
            +    return _.map(obj, function(value){ return value[key]; });
            +  };
            +  _.where = function(obj, attrs, first) {
            +    if (_.isEmpty(attrs)) return first ? null : [];
            +    return _[first ? 'find' : 'filter'](obj, function(value) {
            +      for (var key in attrs) {
            +        if (attrs[key] !== value[key]) return false;
            +      }
            +      return true;
            +    });
            +  };
            +  _.findWhere = function(obj, attrs) {
            +    return _.where(obj, attrs, true);
            +  };
            +  _.max = function(obj, iterator, context) {
            +    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
            +      return Math.max.apply(Math, obj);
            +    }
            +    if (!iterator && _.isEmpty(obj)) return -Infinity;
            +    var result = {computed : -Infinity, value: -Infinity};
            +    each(obj, function(value, index, list) {
            +      var computed = iterator ? iterator.call(context, value, index, list) : value;
            +      computed >= result.computed && (result = {value : value, computed : computed});
            +    });
            +    return result.value;
            +  };
            +  _.min = function(obj, iterator, context) {
            +    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
            +      return Math.min.apply(Math, obj);
            +    }
            +    if (!iterator && _.isEmpty(obj)) return Infinity;
            +    var result = {computed : Infinity, value: Infinity};
            +    each(obj, function(value, index, list) {
            +      var computed = iterator ? iterator.call(context, value, index, list) : value;
            +      computed < result.computed && (result = {value : value, computed : computed});
            +    });
            +    return result.value;
            +  };
            +  _.shuffle = function(obj) {
            +    var rand;
            +    var index = 0;
            +    var shuffled = [];
            +    each(obj, function(value) {
            +      rand = _.random(index++);
            +      shuffled[index - 1] = shuffled[rand];
            +      shuffled[rand] = value;
            +    });
            +    return shuffled;
            +  };
            +  var lookupIterator = function(value) {
            +    return _.isFunction(value) ? value : function(obj){ return obj[value]; };
            +  };
            +  _.sortBy = function(obj, value, context) {
            +    var iterator = lookupIterator(value);
            +    return _.pluck(_.map(obj, function(value, index, list) {
            +      return {
            +        value : value,
            +        index : index,
            +        criteria : iterator.call(context, value, index, list)
            +      };
            +    }).sort(function(left, right) {
            +      var a = left.criteria;
            +      var b = right.criteria;
            +      if (a !== b) {
            +        if (a > b || a === void 0) return 1;
            +        if (a < b || b === void 0) return -1;
            +      }
            +      return left.index < right.index ? -1 : 1;
            +    }), 'value');
            +  };
            +  var group = function(obj, value, context, behavior) {
            +    var result = {};
            +    var iterator = lookupIterator(value || _.identity);
            +    each(obj, function(value, index) {
            +      var key = iterator.call(context, value, index, obj);
            +      behavior(result, key, value);
            +    });
            +    return result;
            +  };
            +  _.groupBy = function(obj, value, context) {
            +    return group(obj, value, context, function(result, key, value) {
            +      (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
            +    });
            +  };
            +  _.countBy = function(obj, value, context) {
            +    return group(obj, value, context, function(result, key) {
            +      if (!_.has(result, key)) result[key] = 0;
            +      result[key]++;
            +    });
            +  };
            +  _.sortedIndex = function(array, obj, iterator, context) {
            +    iterator = iterator == null ? _.identity : lookupIterator(iterator);
            +    var value = iterator.call(context, obj);
            +    var low = 0, high = array.length;
            +    while (low < high) {
            +      var mid = (low + high) >>> 1;
            +      iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
            +    }
            +    return low;
            +  };
            +  _.toArray = function(obj) {
            +    if (!obj) return [];
            +    if (_.isArray(obj)) return slice.call(obj);
            +    if (obj.length === +obj.length) return _.map(obj, _.identity);
            +    return _.values(obj);
            +  };
            +  _.size = function(obj) {
            +    if (obj == null) return 0;
            +    return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
            +  };
            +  _.first = _.head = _.take = function(array, n, guard) {
            +    if (array == null) return void 0;
            +    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
            +  };
            +  _.initial = function(array, n, guard) {
            +    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
            +  };
            +  _.last = function(array, n, guard) {
            +    if (array == null) return void 0;
            +    if ((n != null) && !guard) {
            +      return slice.call(array, Math.max(array.length - n, 0));
            +    } else {
            +      return array[array.length - 1];
            +    }
            +  };
            +  _.rest = _.tail = _.drop = function(array, n, guard) {
            +    return slice.call(array, (n == null) || guard ? 1 : n);
            +  };
            +  _.compact = function(array) {
            +    return _.filter(array, _.identity);
            +  };
            +  var flatten = function(input, shallow, output) {
            +    each(input, function(value) {
            +      if (_.isArray(value)) {
            +        shallow ? push.apply(output, value) : flatten(value, shallow, output);
            +      } else {
            +        output.push(value);
            +      }
            +    });
            +    return output;
            +  };
            +  _.flatten = function(array, shallow) {
            +    return flatten(array, shallow, []);
            +  };
            +  _.without = function(array) {
            +    return _.difference(array, slice.call(arguments, 1));
            +  };
            +  _.uniq = _.unique = function(array, isSorted, iterator, context) {
            +    if (_.isFunction(isSorted)) {
            +      context = iterator;
            +      iterator = isSorted;
            +      isSorted = false;
            +    }
            +    var initial = iterator ? _.map(array, iterator, context) : array;
            +    var results = [];
            +    var seen = [];
            +    each(initial, function(value, index) {
            +      if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
            +        seen.push(value);
            +        results.push(array[index]);
            +      }
            +    });
            +    return results;
            +  };
            +  _.union = function() {
            +    return _.uniq(concat.apply(ArrayProto, arguments));
            +  };
            +  _.intersection = function(array) {
            +    var rest = slice.call(arguments, 1);
            +    return _.filter(_.uniq(array), function(item) {
            +      return _.every(rest, function(other) {
            +        return _.indexOf(other, item) >= 0;
            +      });
            +    });
            +  };
            +  _.difference = function(array) {
            +    var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
            +    return _.filter(array, function(value){ return !_.contains(rest, value); });
            +  };
            +  _.zip = function() {
            +    var args = slice.call(arguments);
            +    var length = _.max(_.pluck(args, 'length'));
            +    var results = new Array(length);
            +    for (var i = 0; i < length; i++) {
            +      results[i] = _.pluck(args, "" + i);
            +    }
            +    return results;
            +  };
            +  _.object = function(list, values) {
            +    if (list == null) return {};
            +    var result = {};
            +    for (var i = 0, l = list.length; i < l; i++) {
            +      if (values) {
            +        result[list[i]] = values[i];
            +      } else {
            +        result[list[i][0]] = list[i][1];
            +      }
            +    }
            +    return result;
            +  };
            +  _.indexOf = function(array, item, isSorted) {
            +    if (array == null) return -1;
            +    var i = 0, l = array.length;
            +    if (isSorted) {
            +      if (typeof isSorted == 'number') {
            +        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
            +      } else {
            +        i = _.sortedIndex(array, item);
            +        return array[i] === item ? i : -1;
            +      }
            +    }
            +    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
            +    for (; i < l; i++) if (array[i] === item) return i;
            +    return -1;
            +  };
            +  _.lastIndexOf = function(array, item, from) {
            +    if (array == null) return -1;
            +    var hasIndex = from != null;
            +    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
            +      return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
            +    }
            +    var i = (hasIndex ? from : array.length);
            +    while (i--) if (array[i] === item) return i;
            +    return -1;
            +  };
            +  _.range = function(start, stop, step) {
            +    if (arguments.length <= 1) {
            +      stop = start || 0;
            +      start = 0;
            +    }
            +    step = arguments[2] || 1;
            +
            +    var len = Math.max(Math.ceil((stop - start) / step), 0);
            +    var idx = 0;
            +    var range = new Array(len);
            +
            +    while(idx < len) {
            +      range[idx++] = start;
            +      start += step;
            +    }
            +
            +    return range;
            +  };
            +  _.bind = function(func, context) {
            +    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
            +    var args = slice.call(arguments, 2);
            +    return function() {
            +      return func.apply(context, args.concat(slice.call(arguments)));
            +    };
            +  };
            +  _.partial = function(func) {
            +    var args = slice.call(arguments, 1);
            +    return function() {
            +      return func.apply(this, args.concat(slice.call(arguments)));
            +    };
            +  };
            +  _.bindAll = function(obj) {
            +    var funcs = slice.call(arguments, 1);
            +    if (funcs.length === 0) funcs = _.functions(obj);
            +    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
            +    return obj;
            +  };
            +  _.memoize = function(func, hasher) {
            +    var memo = {};
            +    hasher || (hasher = _.identity);
            +    return function() {
            +      var key = hasher.apply(this, arguments);
            +      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
            +    };
            +  };
            +  _.delay = function(func, wait) {
            +    var args = slice.call(arguments, 2);
            +    return setTimeout(function(){ return func.apply(null, args); }, wait);
            +  };
            +  _.defer = function(func) {
            +    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
            +  };
            +  _.throttle = function(func, wait) {
            +    var context, args, timeout, result;
            +    var previous = 0;
            +    var later = function() {
            +      previous = new Date;
            +      timeout = null;
            +      result = func.apply(context, args);
            +    };
            +    return function() {
            +      var now = new Date;
            +      var remaining = wait - (now - previous);
            +      context = this;
            +      args = arguments;
            +      if (remaining <= 0) {
            +        clearTimeout(timeout);
            +        timeout = null;
            +        previous = now;
            +        result = func.apply(context, args);
            +      } else if (!timeout) {
            +        timeout = setTimeout(later, remaining);
            +      }
            +      return result;
            +    };
            +  };
            +  _.debounce = function(func, wait, immediate) {
            +    var timeout, result;
            +    return function() {
            +      var context = this, args = arguments;
            +      var later = function() {
            +        timeout = null;
            +        if (!immediate) result = func.apply(context, args);
            +      };
            +      var callNow = immediate && !timeout;
            +      clearTimeout(timeout);
            +      timeout = setTimeout(later, wait);
            +      if (callNow) result = func.apply(context, args);
            +      return result;
            +    };
            +  };
            +  _.once = function(func) {
            +    var ran = false, memo;
            +    return function() {
            +      if (ran) return memo;
            +      ran = true;
            +      memo = func.apply(this, arguments);
            +      func = null;
            +      return memo;
            +    };
            +  };
            +  _.wrap = function(func, wrapper) {
            +    return function() {
            +      var args = [func];
            +      push.apply(args, arguments);
            +      return wrapper.apply(this, args);
            +    };
            +  };
            +  _.compose = function() {
            +    var funcs = arguments;
            +    return function() {
            +      var args = arguments;
            +      for (var i = funcs.length - 1; i >= 0; i--) {
            +        args = [funcs[i].apply(this, args)];
            +      }
            +      return args[0];
            +    };
            +  };
            +  _.after = function(times, func) {
            +    if (times <= 0) return func();
            +    return function() {
            +      if (--times < 1) {
            +        return func.apply(this, arguments);
            +      }
            +    };
            +  };
            +  _.keys = nativeKeys || function(obj) {
            +    if (obj !== Object(obj)) throw new TypeError('Invalid object');
            +    var keys = [];
            +    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
            +    return keys;
            +  };
            +  _.values = function(obj) {
            +    var values = [];
            +    for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
            +    return values;
            +  };
            +  _.pairs = function(obj) {
            +    var pairs = [];
            +    for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
            +    return pairs;
            +  };
            +  _.invert = function(obj) {
            +    var result = {};
            +    for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
            +    return result;
            +  };
            +  _.functions = _.methods = function(obj) {
            +    var names = [];
            +    for (var key in obj) {
            +      if (_.isFunction(obj[key])) names.push(key);
            +    }
            +    return names.sort();
            +  };
            +  _.extend = function(obj) {
            +    each(slice.call(arguments, 1), function(source) {
            +      if (source) {
            +        for (var prop in source) {
            +          obj[prop] = source[prop];
            +        }
            +      }
            +    });
            +    return obj;
            +  };
            +  _.pick = function(obj) {
            +    var copy = {};
            +    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
            +    each(keys, function(key) {
            +      if (key in obj) copy[key] = obj[key];
            +    });
            +    return copy;
            +  };
            +  _.omit = function(obj) {
            +    var copy = {};
            +    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
            +    for (var key in obj) {
            +      if (!_.contains(keys, key)) copy[key] = obj[key];
            +    }
            +    return copy;
            +  };
            +  _.defaults = function(obj) {
            +    each(slice.call(arguments, 1), function(source) {
            +      if (source) {
            +        for (var prop in source) {
            +          if (obj[prop] == null) obj[prop] = source[prop];
            +        }
            +      }
            +    });
            +    return obj;
            +  };
            +  _.clone = function(obj) {
            +    if (!_.isObject(obj)) return obj;
            +    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
            +  };
            +  _.tap = function(obj, interceptor) {
            +    interceptor(obj);
            +    return obj;
            +  };
            +  var eq = function(a, b, aStack, bStack) {
            +    if (a === b) return a !== 0 || 1 / a == 1 / b;
            +    if (a == null || b == null) return a === b;
            +    if (a instanceof _) a = a._wrapped;
            +    if (b instanceof _) b = b._wrapped;
            +    var className = toString.call(a);
            +    if (className != toString.call(b)) return false;
            +    switch (className) {
            +      case '[object String]':
            +        return a == String(b);
            +      case '[object Number]':
            +        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
            +      case '[object Date]':
            +      case '[object Boolean]':
            +        return +a == +b;
            +      case '[object RegExp]':
            +        return a.source == b.source &&
            +               a.global == b.global &&
            +               a.multiline == b.multiline &&
            +               a.ignoreCase == b.ignoreCase;
            +    }
            +    if (typeof a != 'object' || typeof b != 'object') return false;
            +    var length = aStack.length;
            +    while (length--) {
            +      if (aStack[length] == a) return bStack[length] == b;
            +    }
            +    aStack.push(a);
            +    bStack.push(b);
            +    var size = 0, result = true;
            +    if (className == '[object Array]') {
            +      size = a.length;
            +      result = size == b.length;
            +      if (result) {
            +        while (size--) {
            +          if (!(result = eq(a[size], b[size], aStack, bStack))) break;
            +        }
            +      }
            +    } else {
            +      var aCtor = a.constructor, bCtor = b.constructor;
            +      if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
            +                               _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
            +        return false;
            +      }
            +      for (var key in a) {
            +        if (_.has(a, key)) {
            +          size++;
            +          if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
            +        }
            +      }
            +      if (result) {
            +        for (key in b) {
            +          if (_.has(b, key) && !(size--)) break;
            +        }
            +        result = !size;
            +      }
            +    }
            +    aStack.pop();
            +    bStack.pop();
            +    return result;
            +  };
            +  _.isEqual = function(a, b) {
            +    return eq(a, b, [], []);
            +  };
            +  _.isEmpty = function(obj) {
            +    if (obj == null) return true;
            +    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
            +    for (var key in obj) if (_.has(obj, key)) return false;
            +    return true;
            +  };
            +  _.isElement = function(obj) {
            +    return !!(obj && obj.nodeType === 1);
            +  };
            +  _.isArray = nativeIsArray || function(obj) {
            +    return toString.call(obj) == '[object Array]';
            +  };
            +  _.isObject = function(obj) {
            +    return obj === Object(obj);
            +  };
            +  each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
            +    _['is' + name] = function(obj) {
            +      return toString.call(obj) == '[object ' + name + ']';
            +    };
            +  });
            +  if (!_.isArguments(arguments)) {
            +    _.isArguments = function(obj) {
            +      return !!(obj && _.has(obj, 'callee'));
            +    };
            +  }
            +  if (typeof (/./) !== 'function') {
            +    _.isFunction = function(obj) {
            +      return typeof obj === 'function';
            +    };
            +  }
            +  _.isFinite = function(obj) {
            +    return isFinite(obj) && !isNaN(parseFloat(obj));
            +  };
            +  _.isNaN = function(obj) {
            +    return _.isNumber(obj) && obj != +obj;
            +  };
            +  _.isBoolean = function(obj) {
            +    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
            +  };
            +  _.isNull = function(obj) {
            +    return obj === null;
            +  };
            +  _.isUndefined = function(obj) {
            +    return obj === void 0;
            +  };
            +  _.has = function(obj, key) {
            +    return hasOwnProperty.call(obj, key);
            +  };
            +  _.noConflict = function() {
            +    root._ = previousUnderscore;
            +    return this;
            +  };
            +  _.identity = function(value) {
            +    return value;
            +  };
            +  _.times = function(n, iterator, context) {
            +    var accum = Array(n);
            +    for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
            +    return accum;
            +  };
            +  _.random = function(min, max) {
            +    if (max == null) {
            +      max = min;
            +      min = 0;
            +    }
            +    return min + Math.floor(Math.random() * (max - min + 1));
            +  };
            +  var entityMap = {
            +    escape: {
            +      '&': '&amp;',
            +      '<': '&lt;',
            +      '>': '&gt;',
            +      '"': '&quot;',
            +      "'": '&#x27;',
            +      '/': '&#x2F;'
            +    }
            +  };
            +  entityMap.unescape = _.invert(entityMap.escape);
            +  var entityRegexes = {
            +    escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
            +    unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
            +  };
            +  _.each(['escape', 'unescape'], function(method) {
            +    _[method] = function(string) {
            +      if (string == null) return '';
            +      return ('' + string).replace(entityRegexes[method], function(match) {
            +        return entityMap[method][match];
            +      });
            +    };
            +  });
            +  _.result = function(object, property) {
            +    if (object == null) return null;
            +    var value = object[property];
            +    return _.isFunction(value) ? value.call(object) : value;
            +  };
            +  _.mixin = function(obj) {
            +    each(_.functions(obj), function(name){
            +      var func = _[name] = obj[name];
            +      _.prototype[name] = function() {
            +        var args = [this._wrapped];
            +        push.apply(args, arguments);
            +        return result.call(this, func.apply(_, args));
            +      };
            +    });
            +  };
            +  var idCounter = 0;
            +  _.uniqueId = function(prefix) {
            +    var id = ++idCounter + '';
            +    return prefix ? prefix + id : id;
            +  };
            +  _.templateSettings = {
            +    evaluate    : /<%([\s\S]+?)%>/g,
            +    interpolate : /<%=([\s\S]+?)%>/g,
            +    escape      : /<%-([\s\S]+?)%>/g
            +  };
            +  var noMatch = /(.)^/;
            +  var escapes = {
            +    "'":      "'",
            +    '\\':     '\\',
            +    '\r':     'r',
            +    '\n':     'n',
            +    '\t':     't',
            +    '\u2028': 'u2028',
            +    '\u2029': 'u2029'
            +  };
            +
            +  var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
            +  _.template = function(text, data, settings) {
            +    var render;
            +    settings = _.defaults({}, settings, _.templateSettings);
            +    var matcher = new RegExp([
            +      (settings.escape || noMatch).source,
            +      (settings.interpolate || noMatch).source,
            +      (settings.evaluate || noMatch).source
            +    ].join('|') + '|$', 'g');
            +    var index = 0;
            +    var source = "__p+='";
            +    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
            +      source += text.slice(index, offset)
            +        .replace(escaper, function(match) { return '\\' + escapes[match]; });
            +
            +      if (escape) {
            +        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
            +      }
            +      if (interpolate) {
            +        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
            +      }
            +      if (evaluate) {
            +        source += "';\n" + evaluate + "\n__p+='";
            +      }
            +      index = offset + match.length;
            +      return match;
            +    });
            +    source += "';\n";
            +    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
            +
            +    source = "var __t,__p='',__j=Array.prototype.join," +
            +      "print=function(){__p+=__j.call(arguments,'');};\n" +
            +      source + "return __p;\n";
            +
            +    try {
            +      render = new Function(settings.variable || 'obj', '_', source);
            +    } catch (e) {
            +      e.source = source;
            +      throw e;
            +    }
            +
            +    if (data) return render(data, _);
            +    var template = function(data) {
            +      return render.call(this, data, _);
            +    };
            +    template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
            +
            +    return template;
            +  };
            +  _.chain = function(obj) {
            +    return _(obj).chain();
            +  };
            +  var result = function(obj) {
            +    return this._chain ? _(obj).chain() : obj;
            +  };
            +  _.mixin(_);
            +  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
            +    var method = ArrayProto[name];
            +    _.prototype[name] = function() {
            +      var obj = this._wrapped;
            +      method.apply(obj, arguments);
            +      if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
            +      return result.call(this, obj);
            +    };
            +  });
            +  each(['concat', 'join', 'slice'], function(name) {
            +    var method = ArrayProto[name];
            +    _.prototype[name] = function() {
            +      return result.call(this, method.apply(this._wrapped, arguments));
            +    };
            +  });
            +
            +  _.extend(_.prototype, {
            +    chain: function() {
            +      this._chain = true;
            +      return this;
            +    },
            +    value: function() {
            +      return this._wrapped;
            +    }
            +
            +  });
            +
            +}).call(this);
            +
            +},
            +{}],
            +3:[function(_dereq_,module,exports){
            +
            +var _        = _dereq_("underscore");
            +var events   = _dereq_("events");
            +var vars     = _dereq_("./vars.js");
            +var messages = _dereq_("./messages.js");
            +var Lexer    = _dereq_("./lex.js").Lexer;
            +var reg      = _dereq_("./reg.js");
            +var state    = _dereq_("./state.js").state;
            +var style    = _dereq_("./style.js");
            +
            +var JSHINT = (function () {
            +  
            +
            +  var anonname, // The guessed name for anonymous functions.
            +    api, // Extension API
            +    bang = {
            +      "<"  : true,
            +      "<=" : true,
            +      "==" : true,
            +      "===": true,
            +      "!==": true,
            +      "!=" : true,
            +      ">"  : true,
            +      ">=" : true,
            +      "+"  : true,
            +      "-"  : true,
            +      "*"  : true,
            +      "/"  : true,
            +      "%"  : true
            +    },
            +    boolOptions = {
            +      asi         : true, // if automatic semicolon insertion should be tolerated
            +      bitwise     : true, // if bitwise operators should not be allowed
            +      boss        : true, // if advanced usage of assignments should be allowed
            +      browser     : true, // if the standard browser globals should be predefined
            +      camelcase   : true, // if identifiers should be required in camel case
            +      couch       : true, // if CouchDB globals should be predefined
            +      curly       : true, // if curly braces around all blocks should be required
            +      debug       : true, // if debugger statements should be allowed
            +      devel       : true, // if logging globals should be predefined (console, alert, etc.)
            +      dojo        : true, // if Dojo Toolkit globals should be predefined
            +      eqeqeq      : true, // if === should be required
            +      eqnull      : true, // if == null comparisons should be tolerated
            +      notypeof    : true, // if should report typos in typeof comparisons
            +      es3         : true, // if ES3 syntax should be allowed
            +      es5         : true, // if ES5 syntax should be allowed (is now set per default)
            +      esnext      : true, // if es.next specific syntax should be allowed
            +      moz         : true, // if mozilla specific syntax should be allowed
            +      evil        : true, // if eval should be allowed
            +      expr        : true, // if ExpressionStatement should be allowed as Programs
            +      forin       : true, // if for in statements must filter
            +      funcscope   : true, // if only function scope should be used for scope tests
            +      globalstrict: true, // if global  should be allowed (also enables 'strict')
            +      immed       : true, // if immediate invocations must be wrapped in parens
            +      iterator    : true, // if the `__iterator__` property should be allowed
            +      jquery      : true, // if jQuery globals should be predefined
            +      lastsemic   : true, // if semicolons may be ommitted for the trailing
            +      laxbreak    : true, // if line breaks should not be checked
            +      laxcomma    : true, // if line breaks should not be checked around commas
            +      loopfunc    : true, // if functions should be allowed to be defined within
            +      mootools    : true, // if MooTools globals should be predefined
            +      multistr    : true, // allow multiline strings
            +      freeze      : true, // if modifying native object prototypes should be disallowed
            +      newcap      : true, // if constructor names must be capitalized
            +      noarg       : true, // if arguments.caller and arguments.callee should be
            +      node        : true, // if the Node.js environment globals should be
            +      noempty     : true, // if empty blocks should be disallowed
            +      nonbsp      : true, // if non-breaking spaces should be disallowed
            +      nonew       : true, // if using `new` for side-effects should be disallowed
            +      nonstandard : true, // if non-standard (but widely adopted) globals should
            +      phantom     : true, // if PhantomJS symbols should be allowed
            +      plusplus    : true, // if increment/decrement should not be allowed
            +      proto       : true, // if the `__proto__` property should be allowed
            +      prototypejs : true, // if Prototype and Scriptaculous globals should be
            +      rhino       : true, // if the Rhino environment globals should be predefined
            +      shelljs     : true, // if ShellJS globals should be predefined
            +      typed       : true, // if typed array globals should be predefined
            +      undef       : true, // if variables should be declared before used
            +      scripturl   : true, // if script-targeted URLs should be tolerated
            +      strict      : true, // require the  pragma
            +      sub         : true, // if all forms of subscript notation are tolerated
            +      supernew    : true, // if `new function () { ... };` and `new Object;`
            +      validthis   : true, // if 'this' inside a non-constructor function is valid.
            +      withstmt    : true, // if with statements should be allowed
            +      worker      : true, // if Web Worker script symbols should be allowed
            +      wsh         : true, // if the Windows Scripting Host environment globals
            +      yui         : true, // YUI variables should be predefined
            +      mocha       : true, // Mocha functions should be predefined
            +      noyield     : true, // allow generators without a yield
            +      onecase     : true, // if one case switch statements should be allowed
            +      regexp      : true, // if the . should not be allowed in regexp literals
            +      regexdash   : true  // if unescaped first/last dash (-) inside brackets
            +    },
            +    valOptions = {
            +      maxlen       : false,
            +      indent       : false,
            +      maxerr       : false,
            +      predef       : false, // predef is deprecated and being replaced by globals
            +      globals      : false,
            +      quotmark     : false, // 'single'|'double'|true
            +      scope        : false,
            +      maxstatements: false, // {int} max statements per function
            +      maxdepth     : false, // {int} max nested block depth per function
            +      maxparams    : false, // {int} max params per function
            +      maxcomplexity: false, // {int} max cyclomatic complexity per function
            +      shadow       : false, // if variable shadowing should be tolerated
            +      unused       : true,  // warn if variables are unused. Available options:
            +      latedef      : false, // warn if the variable is used before its definition
            +      ignore       : false  // start/end ignoring lines of code, bypassing the lexer
            +    },
            +    invertedOptions = {
            +      bitwise : true,
            +      forin   : true,
            +      newcap  : true,
            +      plusplus: true,
            +      regexp  : true,
            +      undef   : true,
            +      eqeqeq  : true,
            +      strict  : true
            +    },
            +    renamedOptions = {
            +      eqeq   : "eqeqeq",
            +      windows: "wsh",
            +      sloppy : "strict"
            +    },
            +
            +    removedOptions = {
            +      nomen: true,
            +      onevar: true,
            +      passfail: true,
            +      white: true,
            +      gcl: true,
            +      smarttabs: true,
            +      trailing: true
            +    },
            +
            +    declared, // Globals that were declared using /*global ... */ syntax.
            +    exported, // Variables that are used outside of the current file.
            +
            +    functionicity = [
            +      "closure", "exception", "global", "label",
            +      "outer", "unused", "var"
            +    ],
            +
            +    funct, // The current function
            +    functions, // All of the functions
            +
            +    global, // The global scope
            +    implied, // Implied globals
            +    inblock,
            +    indent,
            +    lookahead,
            +    lex,
            +    member,
            +    membersOnly,
            +    noreach,
            +    predefined,    // Global variables defined by option
            +
            +    scope,  // The current scope
            +    stack,
            +    unuseds,
            +    urls,
            +
            +    extraModules = [],
            +    emitter = new events.EventEmitter();
            +
            +  function checkOption(name, t) {
            +    name = name.trim();
            +
            +    if (/^[+-]W\d{3}$/g.test(name)) {
            +      return true;
            +    }
            +
            +    if (valOptions[name] === undefined && boolOptions[name] === undefined) {
            +      if (t.type !== "jslint" && !removedOptions[name]) {
            +        error("E001", t, name);
            +        return false;
            +      }
            +    }
            +
            +    return true;
            +  }
            +
            +  function isString(obj) {
            +    return Object.prototype.toString.call(obj) === "[object String]";
            +  }
            +
            +  function isIdentifier(tkn, value) {
            +    if (!tkn)
            +      return false;
            +
            +    if (!tkn.identifier || tkn.value !== value)
            +      return false;
            +
            +    return true;
            +  }
            +
            +  function isReserved(token) {
            +    if (!token.reserved) {
            +      return false;
            +    }
            +    var meta = token.meta;
            +
            +    if (meta && meta.isFutureReservedWord && state.option.inES5()) {
            +      if (!meta.es5) {
            +        return false;
            +      }
            +      if (meta.strictOnly) {
            +        if (!state.option.strict && !state.directive["use strict"]) {
            +          return false;
            +        }
            +      }
            +
            +      if (token.isProperty) {
            +        return false;
            +      }
            +    }
            +
            +    return true;
            +  }
            +
            +  function supplant(str, data) {
            +    return str.replace(/\{([^{}]*)\}/g, function (a, b) {
            +      var r = data[b];
            +      return typeof r === "string" || typeof r === "number" ? r : a;
            +    });
            +  }
            +
            +  function combine(dest, src) {
            +    Object.keys(src).forEach(function (name) {
            +      if (JSHINT.blacklist.hasOwnProperty(name)) return;
            +      dest[name] = src[name];
            +    });
            +  }
            +
            +  function assume() {
            +    if (state.option.esnext) {
            +      combine(predefined, vars.newEcmaIdentifiers);
            +    }
            +
            +    if (state.option.couch) {
            +      combine(predefined, vars.couch);
            +    }
            +
            +    if (state.option.rhino) {
            +      combine(predefined, vars.rhino);
            +    }
            +
            +    if (state.option.shelljs) {
            +      combine(predefined, vars.shelljs);
            +      combine(predefined, vars.node);
            +    }
            +    if (state.option.typed) {
            +      combine(predefined, vars.typed);
            +    }
            +
            +    if (state.option.phantom) {
            +      combine(predefined, vars.phantom);
            +    }
            +
            +    if (state.option.prototypejs) {
            +      combine(predefined, vars.prototypejs);
            +    }
            +
            +    if (state.option.node) {
            +      combine(predefined, vars.node);
            +      combine(predefined, vars.typed);
            +    }
            +
            +    if (state.option.devel) {
            +      combine(predefined, vars.devel);
            +    }
            +
            +    if (state.option.dojo) {
            +      combine(predefined, vars.dojo);
            +    }
            +
            +    if (state.option.browser) {
            +      combine(predefined, vars.browser);
            +      combine(predefined, vars.typed);
            +    }
            +
            +    if (state.option.nonstandard) {
            +      combine(predefined, vars.nonstandard);
            +    }
            +
            +    if (state.option.jquery) {
            +      combine(predefined, vars.jquery);
            +    }
            +
            +    if (state.option.mootools) {
            +      combine(predefined, vars.mootools);
            +    }
            +
            +    if (state.option.worker) {
            +      combine(predefined, vars.worker);
            +    }
            +
            +    if (state.option.wsh) {
            +      combine(predefined, vars.wsh);
            +    }
            +
            +    if (state.option.globalstrict && state.option.strict !== false) {
            +      state.option.strict = true;
            +    }
            +
            +    if (state.option.yui) {
            +      combine(predefined, vars.yui);
            +    }
            +
            +    if (state.option.mocha) {
            +      combine(predefined, vars.mocha);
            +    }
            +
            +    state.option.inMoz = function (strict) {
            +      return state.option.moz;
            +    };
            +
            +    state.option.inESNext = function (strict) {
            +      return state.option.moz || state.option.esnext;
            +    };
            +
            +    state.option.inES5 = function (/* strict */) {
            +      return !state.option.es3;
            +    };
            +
            +    state.option.inES3 = function (strict) {
            +      if (strict) {
            +        return !state.option.moz && !state.option.esnext && state.option.es3;
            +      }
            +      return state.option.es3;
            +    };
            +  }
            +  function quit(code, line, chr) {
            +    var percentage = Math.floor((line / state.lines.length) * 100);
            +    var message = messages.errors[code].desc;
            +
            +    throw {
            +      name: "JSHintError",
            +      line: line,
            +      character: chr,
            +      message: message + " (" + percentage + "% scanned).",
            +      raw: message,
            +      code: code
            +    };
            +  }
            +
            +  function isundef(scope, code, token, a) {
            +    return JSHINT.undefs.push([scope, code, token, a]);
            +  }
            +
            +  function removeIgnoredMessages() {
            +    var ignored = state.ignoredLines;
            +
            +    if (_.isEmpty(ignored)) return;
            +    JSHINT.errors = _.reject(JSHINT.errors, function (err) { return ignored[err.line] });
            +  }
            +
            +  function warning(code, t, a, b, c, d) {
            +    var ch, l, w, msg;
            +
            +    if (/^W\d{3}$/.test(code)) {
            +      if (state.ignored[code])
            +        return;
            +
            +      msg = messages.warnings[code];
            +    } else if (/E\d{3}/.test(code)) {
            +      msg = messages.errors[code];
            +    } else if (/I\d{3}/.test(code)) {
            +      msg = messages.info[code];
            +    }
            +
            +    t = t || state.tokens.next;
            +    if (t.id === "(end)") {  // `~
            +      t = state.tokens.curr;
            +    }
            +
            +    l = t.line || 0;
            +    ch = t.from || 0;
            +
            +    w = {
            +      id: "(error)",
            +      raw: msg.desc,
            +      code: msg.code,
            +      evidence: state.lines[l - 1] || "",
            +      line: l,
            +      character: ch,
            +      scope: JSHINT.scope,
            +      a: a,
            +      b: b,
            +      c: c,
            +      d: d
            +    };
            +
            +    w.reason = supplant(msg.desc, w);
            +    JSHINT.errors.push(w);
            +
            +    removeIgnoredMessages();
            +
            +    if (JSHINT.errors.length >= state.option.maxerr)
            +      quit("E043", l, ch);
            +
            +    return w;
            +  }
            +
            +  function warningAt(m, l, ch, a, b, c, d) {
            +    return warning(m, {
            +      line: l,
            +      from: ch
            +    }, a, b, c, d);
            +  }
            +
            +  function error(m, t, a, b, c, d) {
            +    warning(m, t, a, b, c, d);
            +  }
            +
            +  function errorAt(m, l, ch, a, b, c, d) {
            +    return error(m, {
            +      line: l,
            +      from: ch
            +    }, a, b, c, d);
            +  }
            +  function addInternalSrc(elem, src) {
            +    var i;
            +    i = {
            +      id: "(internal)",
            +      elem: elem,
            +      value: src
            +    };
            +    JSHINT.internals.push(i);
            +    return i;
            +  }
            +  function addlabel(name, opts) {
            +    opts = opts || {};
            +
            +    var type  = opts.type;
            +    var token = opts.token;
            +    var islet = opts.islet;
            +    if (type === "exception") {
            +      if (_.has(funct["(context)"], name)) {
            +        if (funct[name] !== true && !state.option.node) {
            +          warning("W002", state.tokens.next, name);
            +        }
            +      }
            +    }
            +
            +    if (_.has(funct, name) && !funct["(global)"]) {
            +      if (funct[name] === true) {
            +        if (state.option.latedef) {
            +          if ((state.option.latedef === true && _.contains([funct[name], type], "unction")) ||
            +              !_.contains([funct[name], type], "unction")) {
            +            warning("W003", state.tokens.next, name);
            +          }
            +        }
            +      } else {
            +        if ((!state.option.shadow || _.contains([ "inner", "outer" ], state.option.shadow)) &&
            +            type !== "exception" || funct["(blockscope)"].getlabel(name)) {
            +          warning("W004", state.tokens.next, name);
            +        }
            +      }
            +    }
            +
            +    if (funct["(context)"] && _.has(funct["(context)"], name) && type !== "function") {
            +      if (state.option.shadow === "outer") {
            +        warning("W123", state.tokens.next, name);
            +      }
            +    }
            +    if (islet) {
            +      funct["(blockscope)"].current.add(name, type, state.tokens.curr);
            +    } else {
            +      funct["(blockscope)"].shadow(name);
            +      funct[name] = type;
            +
            +      if (token) {
            +        funct["(tokens)"][name] = token;
            +      }
            +
            +      setprop(funct, name, { unused: opts.unused || false });
            +
            +      if (funct["(global)"]) {
            +        global[name] = funct;
            +        if (_.has(implied, name)) {
            +          if (state.option.latedef) {
            +            if ((state.option.latedef === true && _.contains([funct[name], type], "unction")) ||
            +                !_.contains([funct[name], type], "unction")) {
            +              warning("W003", state.tokens.next, name);
            +            }
            +          }
            +
            +          delete implied[name];
            +        }
            +      } else {
            +        scope[name] = funct;
            +      }
            +    }
            +  }
            +
            +  function doOption() {
            +    var nt = state.tokens.next;
            +    var body = nt.body.match(/(-\s+)?[^\s,:]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g);
            +    var predef = {};
            +
            +    if (nt.type === "globals") {
            +      body.forEach(function (g) {
            +        g = g.split(":");
            +        var key = (g[0] || "").trim();
            +        var val = (g[1] || "").trim();
            +
            +        if (key.charAt(0) === "-") {
            +          key = key.slice(1);
            +          val = false;
            +
            +          JSHINT.blacklist[key] = key;
            +          delete predefined[key];
            +        } else {
            +          predef[key] = (val === "true");
            +        }
            +      });
            +
            +      combine(predefined, predef);
            +
            +      for (var key in predef) {
            +        if (_.has(predef, key)) {
            +          declared[key] = nt;
            +        }
            +      }
            +    }
            +
            +    if (nt.type === "exported") {
            +      body.forEach(function (e) {
            +        exported[e] = true;
            +      });
            +    }
            +
            +    if (nt.type === "members") {
            +      membersOnly = membersOnly || {};
            +
            +      body.forEach(function (m) {
            +        var ch1 = m.charAt(0);
            +        var ch2 = m.charAt(m.length - 1);
            +
            +        if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) {
            +          m = m
            +            .substr(1, m.length - 2)
            +            .replace("\\\"", "\"");
            +        }
            +
            +        membersOnly[m] = false;
            +      });
            +    }
            +
            +    var numvals = [
            +      "maxstatements",
            +      "maxparams",
            +      "maxdepth",
            +      "maxcomplexity",
            +      "maxerr",
            +      "maxlen",
            +      "indent"
            +    ];
            +
            +    if (nt.type === "jshint" || nt.type === "jslint") {
            +      body.forEach(function (g) {
            +        g = g.split(":");
            +        var key = (g[0] || "").trim();
            +        var val = (g[1] || "").trim();
            +
            +        if (!checkOption(key, nt)) {
            +          return;
            +        }
            +
            +        if (numvals.indexOf(key) >= 0) {
            +          if (val !== "false") {
            +            val = +val;
            +
            +            if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) {
            +              error("E032", nt, g[1].trim());
            +              return;
            +            }
            +
            +            state.option[key] = val;
            +          } else {
            +            state.option[key] = key === "indent" ? 4 : false;
            +          }
            +
            +          return;
            +        }
            +
            +        if (key === "validthis") {
            +
            +          if (funct["(global)"])
            +            return void error("E009");
            +
            +          if (val !== "true" && val !== "false")
            +            return void error("E002", nt);
            +
            +          state.option.validthis = (val === "true");
            +          return;
            +        }
            +
            +        if (key === "quotmark") {
            +          switch (val) {
            +          case "true":
            +          case "false":
            +            state.option.quotmark = (val === "true");
            +            break;
            +          case "double":
            +          case "single":
            +            state.option.quotmark = val;
            +            break;
            +          default:
            +            error("E002", nt);
            +          }
            +          return;
            +        }
            +
            +        if (key === "shadow") {
            +          switch (val) {
            +          case "true":
            +            state.option.shadow = true;
            +            break;
            +          case "outer":
            +            state.option.shadow = "outer";
            +            break;
            +          case "false":
            +          case "inner":
            +            state.option.shadow = "inner";
            +            break;
            +          default:
            +            error("E002", nt);
            +          }
            +          return;
            +        }
            +
            +        if (key === "unused") {
            +          switch (val) {
            +          case "true":
            +            state.option.unused = true;
            +            break;
            +          case "false":
            +            state.option.unused = false;
            +            break;
            +          case "vars":
            +          case "strict":
            +            state.option.unused = val;
            +            break;
            +          default:
            +            error("E002", nt);
            +          }
            +          return;
            +        }
            +
            +        if (key === "latedef") {
            +          switch (val) {
            +          case "true":
            +            state.option.latedef = true;
            +            break;
            +          case "false":
            +            state.option.latedef = false;
            +            break;
            +          case "nofunc":
            +            state.option.latedef = "nofunc";
            +            break;
            +          default:
            +            error("E002", nt);
            +          }
            +          return;
            +        }
            +
            +        if (key === "ignore") {
            +          switch (val) {
            +          case "start":
            +            state.ignoreLinterErrors = true;
            +            break;
            +          case "end":
            +            state.ignoreLinterErrors = false;
            +            break;
            +          case "line":
            +            state.ignoredLines[nt.line] = true;
            +            removeIgnoredMessages();
            +            break;
            +          default:
            +            error("E002", nt);
            +          }
            +          return;
            +        }
            +
            +        var match = /^([+-])(W\d{3})$/g.exec(key);
            +        if (match) {
            +          state.ignored[match[2]] = (match[1] === "-");
            +          return;
            +        }
            +
            +        var tn;
            +        if (val === "true" || val === "false") {
            +          if (nt.type === "jslint") {
            +            tn = renamedOptions[key] || key;
            +            state.option[tn] = (val === "true");
            +
            +            if (invertedOptions[tn] !== undefined) {
            +              state.option[tn] = !state.option[tn];
            +            }
            +          } else {
            +            state.option[key] = (val === "true");
            +          }
            +
            +          if (key === "newcap") {
            +            state.option["(explicitNewcap)"] = true;
            +          }
            +          return;
            +        }
            +
            +        error("E002", nt);
            +      });
            +
            +      assume();
            +    }
            +  }
            +
            +  function peek(p) {
            +    var i = p || 0, j = 0, t;
            +
            +    while (j <= i) {
            +      t = lookahead[j];
            +      if (!t) {
            +        t = lookahead[j] = lex.token();
            +      }
            +      j += 1;
            +    }
            +    return t;
            +  }
            +
            +  function advance(id, t) {
            +    switch (state.tokens.curr.id) {
            +    case "(number)":
            +      if (state.tokens.next.id === ".") {
            +        warning("W005", state.tokens.curr);
            +      }
            +      break;
            +    case "-":
            +      if (state.tokens.next.id === "-" || state.tokens.next.id === "--") {
            +        warning("W006");
            +      }
            +      break;
            +    case "+":
            +      if (state.tokens.next.id === "+" || state.tokens.next.id === "++") {
            +        warning("W007");
            +      }
            +      break;
            +    }
            +
            +    if (state.tokens.curr.type === "(string)" || state.tokens.curr.identifier) {
            +      anonname = state.tokens.curr.value;
            +    }
            +
            +    if (id && state.tokens.next.id !== id) {
            +      if (t) {
            +        if (state.tokens.next.id === "(end)") {
            +          error("E019", t, t.id);
            +        } else {
            +          error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value);
            +        }
            +      } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) {
            +        warning("W116", state.tokens.next, id, state.tokens.next.value);
            +      }
            +    }
            +
            +    state.tokens.prev = state.tokens.curr;
            +    state.tokens.curr = state.tokens.next;
            +    for (;;) {
            +      state.tokens.next = lookahead.shift() || lex.token();
            +
            +      if (!state.tokens.next) { // No more tokens left, give up
            +        quit("E041", state.tokens.curr.line);
            +      }
            +
            +      if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") {
            +        return;
            +      }
            +
            +      if (state.tokens.next.check) {
            +        state.tokens.next.check();
            +      }
            +
            +      if (state.tokens.next.isSpecial) {
            +        doOption();
            +      } else {
            +        if (state.tokens.next.id !== "(endline)") {
            +          break;
            +        }
            +      }
            +    }
            +  }
            +
            +  function isInfix(token) {
            +    return token.infix || (!token.identifier && !!token.led);
            +  }
            +
            +  function isEndOfExpr() {
            +    var curr = state.tokens.curr;
            +    var next = state.tokens.next;
            +    if (next.id === ";" || next.id === "}" || next.id === ":") {
            +      return true;
            +    }
            +    if (isInfix(next) === isInfix(curr) || (curr.id === "yield" && state.option.inMoz(true))) {
            +      return curr.line !== next.line;
            +    }
            +    return false;
            +  }
            +
            +  function expression(rbp, initial) {
            +    var left, isArray = false, isObject = false, isLetExpr = false;
            +    if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") {
            +      if (!state.option.inMoz(true)) {
            +        warning("W118", state.tokens.next, "let expressions");
            +      }
            +      isLetExpr = true;
            +      funct["(blockscope)"].stack();
            +      advance("let");
            +      advance("(");
            +      state.syntax["let"].fud.call(state.syntax["let"].fud, false);
            +      advance(")");
            +    }
            +
            +    if (state.tokens.next.id === "(end)")
            +      error("E006", state.tokens.curr);
            +
            +    if (state.option.asi &&
            +        (state.tokens.curr.id === "[" ||
            +          state.tokens.curr.id === "(" ||
            +          state.tokens.curr.id === "/") &&
            +        state.tokens.prev.line < state.tokens.curr.line)
            +      warning("W014", state.tokens.curr, state.tokens.curr.id);
            +
            +    advance();
            +
            +    if (initial) {
            +      anonname = "anonymous";
            +      funct["(verb)"] = state.tokens.curr.value;
            +    }
            +
            +    if (initial === true && state.tokens.curr.fud) {
            +      left = state.tokens.curr.fud();
            +    } else {
            +      if (state.tokens.curr.nud) {
            +        left = state.tokens.curr.nud();
            +      } else {
            +        error("E030", state.tokens.curr, state.tokens.curr.id);
            +      }
            +
            +      while (rbp < state.tokens.next.lbp && !isEndOfExpr()) {
            +        isArray = state.tokens.curr.value === "Array";
            +        isObject = state.tokens.curr.value === "Object";
            +        if (left && (left.value || (left.first && left.first.value))) {
            +          if (left.value !== "new" ||
            +            (left.first && left.first.value && left.first.value === ".")) {
            +            isArray = false;
            +            if (left.value !== state.tokens.curr.value) {
            +              isObject = false;
            +            }
            +          }
            +        }
            +
            +        advance();
            +
            +        if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
            +          warning("W009", state.tokens.curr);
            +        }
            +
            +        if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") {
            +          warning("W010", state.tokens.curr);
            +        }
            +
            +        if (left && state.tokens.curr.led) {
            +          left = state.tokens.curr.led(left);
            +        } else {
            +          error("E033", state.tokens.curr, state.tokens.curr.id);
            +        }
            +      }
            +    }
            +    if (isLetExpr) {
            +      funct["(blockscope)"].unstack();
            +    }
            +    return left;
            +  }
            +
            +  function nobreaknonadjacent(left, right) {
            +    left = left || state.tokens.curr;
            +    right = right || state.tokens.next;
            +    if (!state.option.laxbreak && left.line !== right.line) {
            +      warning("W014", right, right.value);
            +    }
            +  }
            +
            +  function nolinebreak(t) {
            +    t = t || state.tokens.curr;
            +    if (t.line !== state.tokens.next.line) {
            +      warning("E022", t, t.value);
            +    }
            +  }
            +
            +  function nobreakcomma(left, right) {
            +    if (left.line !== right.line) {
            +      if (!state.option.laxcomma) {
            +        if (comma.first) {
            +          warning("I001");
            +          comma.first = false;
            +        }
            +        warning("W014", left, right.value);
            +      }
            +    }
            +  }
            +
            +  function comma(opts) {
            +    opts = opts || {};
            +
            +    if (!opts.peek) {
            +      nobreakcomma(state.tokens.curr, state.tokens.next);
            +      advance(",");
            +    } else {
            +      nobreakcomma(state.tokens.prev, state.tokens.curr);
            +    }
            +
            +    if (state.tokens.next.identifier && !(opts.property && state.option.inES5())) {
            +      switch (state.tokens.next.value) {
            +      case "break":
            +      case "case":
            +      case "catch":
            +      case "continue":
            +      case "default":
            +      case "do":
            +      case "else":
            +      case "finally":
            +      case "for":
            +      case "if":
            +      case "in":
            +      case "instanceof":
            +      case "return":
            +      case "switch":
            +      case "throw":
            +      case "try":
            +      case "var":
            +      case "let":
            +      case "while":
            +      case "with":
            +        error("E024", state.tokens.next, state.tokens.next.value);
            +        return false;
            +      }
            +    }
            +
            +    if (state.tokens.next.type === "(punctuator)") {
            +      switch (state.tokens.next.value) {
            +      case "}":
            +      case "]":
            +      case ",":
            +        if (opts.allowTrailing) {
            +          return true;
            +        }
            +      case ")":
            +        error("E024", state.tokens.next, state.tokens.next.value);
            +        return false;
            +      }
            +    }
            +    return true;
            +  }
            +
            +  function symbol(s, p) {
            +    var x = state.syntax[s];
            +    if (!x || typeof x !== "object") {
            +      state.syntax[s] = x = {
            +        id: s,
            +        lbp: p,
            +        value: s
            +      };
            +    }
            +    return x;
            +  }
            +
            +  function delim(s) {
            +    return symbol(s, 0);
            +  }
            +
            +  function stmt(s, f) {
            +    var x = delim(s);
            +    x.identifier = x.reserved = true;
            +    x.fud = f;
            +    return x;
            +  }
            +
            +  function blockstmt(s, f) {
            +    var x = stmt(s, f);
            +    x.block = true;
            +    return x;
            +  }
            +
            +  function reserveName(x) {
            +    var c = x.id.charAt(0);
            +    if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) {
            +      x.identifier = x.reserved = true;
            +    }
            +    return x;
            +  }
            +
            +  function prefix(s, f) {
            +    var x = symbol(s, 150);
            +    reserveName(x);
            +
            +    x.nud = (typeof f === "function") ? f : function () {
            +      this.right = expression(150);
            +      this.arity = "unary";
            +
            +      if (this.id === "++" || this.id === "--") {
            +        if (state.option.plusplus) {
            +          warning("W016", this, this.id);
            +        } else if (this.right && (!this.right.identifier || isReserved(this.right)) &&
            +            this.right.id !== "." && this.right.id !== "[") {
            +          warning("W017", this);
            +        }
            +      }
            +
            +      return this;
            +    };
            +
            +    return x;
            +  }
            +
            +  function type(s, f) {
            +    var x = delim(s);
            +    x.type = s;
            +    x.nud = f;
            +    return x;
            +  }
            +
            +  function reserve(name, func) {
            +    var x = type(name, func);
            +    x.identifier = true;
            +    x.reserved = true;
            +    return x;
            +  }
            +
            +  function FutureReservedWord(name, meta) {
            +    var x = type(name, (meta && meta.nud) || function () {
            +      return this;
            +    });
            +
            +    meta = meta || {};
            +    meta.isFutureReservedWord = true;
            +
            +    x.value = name;
            +    x.identifier = true;
            +    x.reserved = true;
            +    x.meta = meta;
            +
            +    return x;
            +  }
            +
            +  function reservevar(s, v) {
            +    return reserve(s, function () {
            +      if (typeof v === "function") {
            +        v(this);
            +      }
            +      return this;
            +    });
            +  }
            +
            +  function infix(s, f, p, w) {
            +    var x = symbol(s, p);
            +    reserveName(x);
            +    x.infix = true;
            +    x.led = function (left) {
            +      if (!w) {
            +        nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
            +      }
            +      if (s === "in" && left.id === "!") {
            +        warning("W018", left, "!");
            +      }
            +      if (typeof f === "function") {
            +        return f(left, this);
            +      } else {
            +        this.left = left;
            +        this.right = expression(p);
            +        return this;
            +      }
            +    };
            +    return x;
            +  }
            +
            +
            +  function application(s) {
            +    var x = symbol(s, 42);
            +
            +    x.led = function (left) {
            +      if (!state.option.inESNext()) {
            +        warning("W104", state.tokens.curr, "arrow function syntax (=>)");
            +      }
            +
            +      nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
            +
            +      this.left = left;
            +      this.right = doFunction(undefined, undefined, false, left);
            +      return this;
            +    };
            +    return x;
            +  }
            +
            +  function relation(s, f) {
            +    var x = symbol(s, 100);
            +
            +    x.led = function (left) {
            +      nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
            +      var right = expression(100);
            +
            +      if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) {
            +        warning("W019", this);
            +      } else if (f) {
            +        f.apply(this, [left, right]);
            +      }
            +
            +      if (!left || !right) {
            +        quit("E041", state.tokens.curr.line);
            +      }
            +
            +      if (left.id === "!") {
            +        warning("W018", left, "!");
            +      }
            +
            +      if (right.id === "!") {
            +        warning("W018", right, "!");
            +      }
            +
            +      this.left = left;
            +      this.right = right;
            +      return this;
            +    };
            +    return x;
            +  }
            +
            +  function isPoorRelation(node) {
            +    return node &&
            +        ((node.type === "(number)" && +node.value === 0) ||
            +         (node.type === "(string)" && node.value === "") ||
            +         (node.type === "null" && !state.option.eqnull) ||
            +        node.type === "true" ||
            +        node.type === "false" ||
            +        node.type === "undefined");
            +  }
            +
            +  function isTypoTypeof(left, right) {
            +    if (state.option.notypeof)
            +      return false;
            +
            +    if (!left || !right)
            +      return false;
            +
            +    var values = [
            +      "undefined", "object", "boolean", "number",
            +      "string", "function", "xml", "object", "unknown"
            +    ];
            +
            +    if (right.type === "(identifier)" && right.value === "typeof" && left.type === "(string)")
            +      return !_.contains(values, left.value);
            +
            +    return false;
            +  }
            +
            +  function findNativePrototype(left) {
            +    var natives = [
            +      "Array", "ArrayBuffer", "Boolean", "Collator", "DataView", "Date",
            +      "DateTimeFormat", "Error", "EvalError", "Float32Array", "Float64Array",
            +      "Function", "Infinity", "Intl", "Int16Array", "Int32Array", "Int8Array",
            +      "Iterator", "Number", "NumberFormat", "Object", "RangeError",
            +      "ReferenceError", "RegExp", "StopIteration", "String", "SyntaxError",
            +      "TypeError", "Uint16Array", "Uint32Array", "Uint8Array", "Uint8ClampedArray",
            +      "URIError"
            +    ];
            +
            +    function walkPrototype(obj) {
            +      if (typeof obj !== "object") return;
            +      return obj.right === "prototype" ? obj : walkPrototype(obj.left);
            +    }
            +
            +    function walkNative(obj) {
            +      while (!obj.identifier && typeof obj.left === "object")
            +        obj = obj.left;
            +
            +      if (obj.identifier && natives.indexOf(obj.value) >= 0)
            +        return obj.value;
            +    }
            +
            +    var prototype = walkPrototype(left);
            +    if (prototype) return walkNative(prototype);
            +  }
            +
            +  function assignop(s, f, p) {
            +    var x = infix(s, typeof f === "function" ? f : function (left, that) {
            +      that.left = left;
            +
            +      if (left) {
            +        if (state.option.freeze) {
            +          var nativeObject = findNativePrototype(left);
            +          if (nativeObject)
            +            warning("W121", left, nativeObject);
            +        }
            +
            +        if (predefined[left.value] === false &&
            +            scope[left.value]["(global)"] === true) {
            +          warning("W020", left);
            +        } else if (left["function"]) {
            +          warning("W021", left, left.value);
            +        }
            +
            +        if (funct[left.value] === "const") {
            +          error("E013", left, left.value);
            +        }
            +
            +        if (left.id === ".") {
            +          if (!left.left) {
            +            warning("E031", that);
            +          } else if (left.left.value === "arguments" && !state.directive["use strict"]) {
            +            warning("E031", that);
            +          }
            +
            +          that.right = expression(10);
            +          return that;
            +        } else if (left.id === "[") {
            +          if (state.tokens.curr.left.first) {
            +            state.tokens.curr.left.first.forEach(function (t) {
            +              if (t && funct[t.value] === "const") {
            +                error("E013", t, t.value);
            +              }
            +            });
            +          } else if (!left.left) {
            +            warning("E031", that);
            +          } else if (left.left.value === "arguments" && !state.directive["use strict"]) {
            +            warning("E031", that);
            +          }
            +          that.right = expression(10);
            +          return that;
            +        } else if (left.identifier && !isReserved(left)) {
            +          if (funct[left.value] === "exception") {
            +            warning("W022", left);
            +          }
            +          that.right = expression(10);
            +          return that;
            +        }
            +
            +        if (left === state.syntax["function"]) {
            +          warning("W023", state.tokens.curr);
            +        }
            +      }
            +
            +      error("E031", that);
            +    }, p);
            +
            +    x.exps = true;
            +    x.assign = true;
            +    return x;
            +  }
            +
            +
            +  function bitwise(s, f, p) {
            +    var x = symbol(s, p);
            +    reserveName(x);
            +    x.led = (typeof f === "function") ? f : function (left) {
            +      if (state.option.bitwise) {
            +        warning("W016", this, this.id);
            +      }
            +      this.left = left;
            +      this.right = expression(p);
            +      return this;
            +    };
            +    return x;
            +  }
            +
            +
            +  function bitwiseassignop(s) {
            +    return assignop(s, function (left, that) {
            +      if (state.option.bitwise) {
            +        warning("W016", that, that.id);
            +      }
            +
            +      if (left) {
            +        if (left.id === "." || left.id === "[" ||
            +            (left.identifier && !isReserved(left))) {
            +          expression(10);
            +          return that;
            +        }
            +        if (left === state.syntax["function"]) {
            +          warning("W023", state.tokens.curr);
            +        }
            +        return that;
            +      }
            +      error("E031", that);
            +    }, 20);
            +  }
            +
            +
            +  function suffix(s) {
            +    var x = symbol(s, 150);
            +
            +    x.led = function (left) {
            +      if (state.option.plusplus) {
            +        warning("W016", this, this.id);
            +      } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") {
            +        warning("W017", this);
            +      }
            +
            +      this.left = left;
            +      return this;
            +    };
            +    return x;
            +  }
            +
            +  function optionalidentifier(fnparam, prop) {
            +    if (!state.tokens.next.identifier) {
            +      return;
            +    }
            +
            +    advance();
            +
            +    var curr = state.tokens.curr;
            +    var val  = state.tokens.curr.value;
            +
            +    if (!isReserved(curr)) {
            +      return val;
            +    }
            +
            +    if (prop) {
            +      if (state.option.inES5()) {
            +        return val;
            +      }
            +    }
            +
            +    if (fnparam && val === "undefined") {
            +      return val;
            +    }
            +
            +    warning("W024", state.tokens.curr, state.tokens.curr.id);
            +    return val;
            +  }
            +  function identifier(fnparam, prop) {
            +    var i = optionalidentifier(fnparam, prop);
            +    if (i) {
            +      return i;
            +    }
            +    if (state.tokens.curr.id === "function" && state.tokens.next.id === "(") {
            +      warning("W025");
            +    } else {
            +      error("E030", state.tokens.next, state.tokens.next.value);
            +    }
            +  }
            +
            +
            +  function reachable(s) {
            +    var i = 0, t;
            +    if (state.tokens.next.id !== ";" || noreach) {
            +      return;
            +    }
            +    for (;;) {
            +      do {
            +        t = peek(i);
            +        i += 1;
            +      } while (t.id != "(end)" && t.id === "(comment)");
            +
            +      if (t.reach) {
            +        return;
            +      }
            +      if (t.id !== "(endline)") {
            +        if (t.id === "function") {
            +          if (state.option.latedef === true) {
            +            warning("W026", t);
            +          }
            +          break;
            +        }
            +
            +        warning("W027", t, t.value, s);
            +        break;
            +      }
            +    }
            +  }
            +
            +
            +  function statement() {
            +    var values;
            +    var i = indent, r, s = scope, t = state.tokens.next;
            +
            +    if (t.id === ";") {
            +      advance(";");
            +      return;
            +    }
            +    var res = isReserved(t);
            +
            +    if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") {
            +      warning("W024", t, t.id);
            +      res = false;
            +    }
            +    if (_.has(["[", "{"], t.value)) {
            +      if (lookupBlockType().isDestAssign) {
            +        if (!state.option.inESNext()) {
            +          warning("W104", state.tokens.curr, "destructuring expression");
            +        }
            +        values = destructuringExpression();
            +        values.forEach(function (tok) {
            +          isundef(funct, "W117", tok.token, tok.id);
            +        });
            +        advance("=");
            +        destructuringExpressionMatch(values, expression(10, true));
            +        advance(";");
            +        return;
            +      }
            +    }
            +    if (t.identifier && !res && peek().id === ":") {
            +      advance();
            +      advance(":");
            +      scope = Object.create(s);
            +      addlabel(t.value, { type: "label" });
            +
            +      if (!state.tokens.next.labelled && state.tokens.next.value !== "{") {
            +        warning("W028", state.tokens.next, t.value, state.tokens.next.value);
            +      }
            +
            +      state.tokens.next.label = t.value;
            +      t = state.tokens.next;
            +    }
            +
            +    if (t.id === "{") {
            +      var iscase = (funct["(verb)"] === "case" && state.tokens.curr.value === ":");
            +      block(true, true, false, false, iscase);
            +      return;
            +    }
            +
            +    r = expression(0, true);
            +
            +    if (r && (!r.identifier || r.value !== "function") && (r.type !== "(punctuator)")) {
            +      if (!state.directive["use strict"] &&
            +          state.option.globalstrict &&
            +          state.option.strict) {
            +        warning("E007");
            +      }
            +    }
            +
            +    if (!t.block) {
            +      if (!state.option.expr && (!r || !r.exps)) {
            +        warning("W030", state.tokens.curr);
            +      } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") {
            +        warning("W031", t);
            +      }
            +
            +      if (state.tokens.next.id !== ";") {
            +        if (!state.option.asi) {
            +          if (!state.option.lastsemic || state.tokens.next.id !== "}" ||
            +            state.tokens.next.line !== state.tokens.curr.line) {
            +            warningAt("W033", state.tokens.curr.line, state.tokens.curr.character);
            +          }
            +        }
            +      } else {
            +        advance(";");
            +      }
            +    }
            +
            +    indent = i;
            +    scope = s;
            +    return r;
            +  }
            +
            +
            +  function statements(startLine) {
            +    var a = [], p;
            +
            +    while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") {
            +      if (state.tokens.next.id === ";") {
            +        p = peek();
            +
            +        if (!p || (p.id !== "(" && p.id !== "[")) {
            +          warning("W032");
            +        }
            +
            +        advance(";");
            +      } else {
            +        a.push(statement(startLine === state.tokens.next.line));
            +      }
            +    }
            +    return a;
            +  }
            +  function directives() {
            +    var i, p, pn;
            +
            +    for (;;) {
            +      if (state.tokens.next.id === "(string)") {
            +        p = peek(0);
            +        if (p.id === "(endline)") {
            +          i = 1;
            +          do {
            +            pn = peek(i);
            +            i = i + 1;
            +          } while (pn.id === "(endline)");
            +
            +          if (pn.id !== ";") {
            +            if (pn.id !== "(string)" && pn.id !== "(number)" &&
            +              pn.id !== "(regexp)" && pn.identifier !== true &&
            +              pn.id !== "}") {
            +              break;
            +            }
            +            warning("W033", state.tokens.next);
            +          } else {
            +            p = pn;
            +          }
            +        } else if (p.id === "}") {
            +          warning("W033", p);
            +        } else if (p.id !== ";") {
            +          break;
            +        }
            +
            +        advance();
            +        if (state.directive[state.tokens.curr.value]) {
            +          warning("W034", state.tokens.curr, state.tokens.curr.value);
            +        }
            +
            +        if (state.tokens.curr.value === "use strict") {
            +          if (!state.option["(explicitNewcap)"])
            +            state.option.newcap = true;
            +          state.option.undef = true;
            +        }
            +        state.directive[state.tokens.curr.value] = true;
            +
            +        if (p.id === ";") {
            +          advance(";");
            +        }
            +        continue;
            +      }
            +      break;
            +    }
            +  }
            +  function block(ordinary, stmt, isfunc, isfatarrow, iscase) {
            +    var a,
            +      b = inblock,
            +      old_indent = indent,
            +      m,
            +      s = scope,
            +      t,
            +      line,
            +      d;
            +
            +    inblock = ordinary;
            +
            +    if (!ordinary || !state.option.funcscope)
            +      scope = Object.create(scope);
            +
            +    t = state.tokens.next;
            +
            +    var metrics = funct["(metrics)"];
            +    metrics.nestedBlockDepth += 1;
            +    metrics.verifyMaxNestedBlockDepthPerFunction();
            +
            +    if (state.tokens.next.id === "{") {
            +      advance("{");
            +      funct["(blockscope)"].stack();
            +
            +      line = state.tokens.curr.line;
            +      if (state.tokens.next.id !== "}") {
            +        indent += state.option.indent;
            +        while (!ordinary && state.tokens.next.from > indent) {
            +          indent += state.option.indent;
            +        }
            +
            +        if (isfunc) {
            +          m = {};
            +          for (d in state.directive) {
            +            if (_.has(state.directive, d)) {
            +              m[d] = state.directive[d];
            +            }
            +          }
            +          directives();
            +
            +          if (state.option.strict && funct["(context)"]["(global)"]) {
            +            if (!m["use strict"] && !state.directive["use strict"]) {
            +              warning("E007");
            +            }
            +          }
            +        }
            +
            +        a = statements(line);
            +
            +        metrics.statementCount += a.length;
            +
            +        if (isfunc) {
            +          state.directive = m;
            +        }
            +
            +        indent -= state.option.indent;
            +      }
            +
            +      advance("}", t);
            +
            +      funct["(blockscope)"].unstack();
            +
            +      indent = old_indent;
            +    } else if (!ordinary) {
            +      if (isfunc) {
            +        m = {};
            +        if (stmt && !isfatarrow && !state.option.inMoz(true)) {
            +          error("W118", state.tokens.curr, "function closure expressions");
            +        }
            +
            +        if (!stmt) {
            +          for (d in state.directive) {
            +            if (_.has(state.directive, d)) {
            +              m[d] = state.directive[d];
            +            }
            +          }
            +        }
            +        expression(10);
            +
            +        if (state.option.strict && funct["(context)"]["(global)"]) {
            +          if (!m["use strict"] && !state.directive["use strict"]) {
            +            warning("E007");
            +          }
            +        }
            +      } else {
            +        error("E021", state.tokens.next, "{", state.tokens.next.value);
            +      }
            +    } else {
            +      funct["(nolet)"] = true;
            +
            +      if (!stmt || state.option.curly) {
            +        warning("W116", state.tokens.next, "{", state.tokens.next.value);
            +      }
            +
            +      noreach = true;
            +      indent += state.option.indent;
            +      a = [statement()];
            +      indent -= state.option.indent;
            +      noreach = false;
            +
            +      delete funct["(nolet)"];
            +    }
            +    switch (funct["(verb)"]) {
            +    case "break":
            +    case "continue":
            +    case "return":
            +    case "throw":
            +      if (iscase) {
            +        break;
            +      }
            +    default:
            +      funct["(verb)"] = null;
            +    }
            +
            +    if (!ordinary || !state.option.funcscope) scope = s;
            +    inblock = b;
            +    if (ordinary && state.option.noempty && (!a || a.length === 0)) {
            +      warning("W035");
            +    }
            +    metrics.nestedBlockDepth -= 1;
            +    return a;
            +  }
            +
            +
            +  function countMember(m) {
            +    if (membersOnly && typeof membersOnly[m] !== "boolean") {
            +      warning("W036", state.tokens.curr, m);
            +    }
            +    if (typeof member[m] === "number") {
            +      member[m] += 1;
            +    } else {
            +      member[m] = 1;
            +    }
            +  }
            +
            +
            +  function note_implied(tkn) {
            +    var name = tkn.value;
            +    var desc = Object.getOwnPropertyDescriptor(implied, name);
            +
            +    if (!desc)
            +      implied[name] = [tkn.line];
            +    else
            +      desc.value.push(tkn.line);
            +  }
            +
            +  type("(number)", function () {
            +    return this;
            +  });
            +
            +  type("(string)", function () {
            +    return this;
            +  });
            +
            +  type("(template)", function () {
            +    return this;
            +  });
            +
            +  state.syntax["(identifier)"] = {
            +    type: "(identifier)",
            +    lbp: 0,
            +    identifier: true,
            +
            +    nud: function () {
            +      var v = this.value;
            +      var s = scope[v];
            +      var f;
            +      var block;
            +
            +      if (typeof s === "function") {
            +        s = undefined;
            +      } else if (!funct["(blockscope)"].current.has(v) && typeof s === "boolean") {
            +        f = funct;
            +        funct = functions[0];
            +        addlabel(v, { type: "var" });
            +        s = funct;
            +        funct = f;
            +      }
            +
            +      block = funct["(blockscope)"].getlabel(v);
            +      if (funct === s || block) {
            +        switch (block ? block[v]["(type)"] : funct[v]) {
            +        case "unused":
            +          if (block) block[v]["(type)"] = "var";
            +          else funct[v] = "var";
            +          break;
            +        case "unction":
            +          if (block) block[v]["(type)"] = "function";
            +          else funct[v] = "function";
            +          this["function"] = true;
            +          break;
            +        case "const":
            +          setprop(funct, v, { unused: false });
            +          break;
            +        case "function":
            +          this["function"] = true;
            +          break;
            +        case "label":
            +          warning("W037", state.tokens.curr, v);
            +          break;
            +        }
            +      } else if (funct["(global)"]) {
            +
            +        if (typeof predefined[v] !== "boolean") {
            +          if (!(anonname === "typeof" || anonname === "delete") ||
            +            (state.tokens.next && (state.tokens.next.value === "." ||
            +              state.tokens.next.value === "["))) {
            +
            +            if (!funct["(comparray)"].check(v)) {
            +              isundef(funct, "W117", state.tokens.curr, v);
            +            }
            +          }
            +        }
            +
            +        note_implied(state.tokens.curr);
            +      } else {
            +
            +        switch (funct[v]) {
            +        case "closure":
            +        case "function":
            +        case "var":
            +        case "unused":
            +          warning("W038", state.tokens.curr, v);
            +          break;
            +        case "label":
            +          warning("W037", state.tokens.curr, v);
            +          break;
            +        case "outer":
            +        case "global":
            +          break;
            +        default:
            +          if (s === true) {
            +            funct[v] = true;
            +          } else if (s === null) {
            +            warning("W039", state.tokens.curr, v);
            +            note_implied(state.tokens.curr);
            +          } else if (typeof s !== "object") {
            +            if (!(anonname === "typeof" || anonname === "delete") ||
            +              (state.tokens.next &&
            +                (state.tokens.next.value === "." || state.tokens.next.value === "["))) {
            +
            +              isundef(funct, "W117", state.tokens.curr, v);
            +            }
            +            funct[v] = true;
            +            note_implied(state.tokens.curr);
            +          } else {
            +            switch (s[v]) {
            +            case "function":
            +            case "unction":
            +              this["function"] = true;
            +              s[v] = "closure";
            +              funct[v] = s["(global)"] ? "global" : "outer";
            +              break;
            +            case "var":
            +            case "unused":
            +              s[v] = "closure";
            +              funct[v] = s["(global)"] ? "global" : "outer";
            +              break;
            +            case "const":
            +              setprop(s, v, { unused: false });
            +              break;
            +            case "closure":
            +              funct[v] = s["(global)"] ? "global" : "outer";
            +              break;
            +            case "label":
            +              warning("W037", state.tokens.curr, v);
            +            }
            +          }
            +        }
            +      }
            +      return this;
            +    },
            +
            +    led: function () {
            +      error("E033", state.tokens.next, state.tokens.next.value);
            +    }
            +  };
            +
            +  type("(regexp)", function () {
            +    return this;
            +  });
            +
            +  delim("(endline)");
            +  delim("(begin)");
            +  delim("(end)").reach = true;
            +  delim("(error)").reach = true;
            +  delim("}").reach = true;
            +  delim(")");
            +  delim("]");
            +  delim("\"").reach = true;
            +  delim("'").reach = true;
            +  delim(";");
            +  delim(":").reach = true;
            +  delim("#");
            +
            +  reserve("else");
            +  reserve("case").reach = true;
            +  reserve("catch");
            +  reserve("default").reach = true;
            +  reserve("finally");
            +  reservevar("arguments", function (x) {
            +    if (state.directive["use strict"] && funct["(global)"]) {
            +      warning("E008", x);
            +    }
            +  });
            +  reservevar("eval");
            +  reservevar("false");
            +  reservevar("Infinity");
            +  reservevar("null");
            +  reservevar("this", function (x) {
            +    if (state.directive["use strict"] && !state.option.validthis && ((funct["(statement)"] &&
            +        funct["(name)"].charAt(0) > "Z") || funct["(global)"])) {
            +      warning("W040", x);
            +    }
            +  });
            +  reservevar("true");
            +  reservevar("undefined");
            +
            +  assignop("=", "assign", 20);
            +  assignop("+=", "assignadd", 20);
            +  assignop("-=", "assignsub", 20);
            +  assignop("*=", "assignmult", 20);
            +  assignop("/=", "assigndiv", 20).nud = function () {
            +    error("E014");
            +  };
            +  assignop("%=", "assignmod", 20);
            +
            +  bitwiseassignop("&=", "assignbitand", 20);
            +  bitwiseassignop("|=", "assignbitor", 20);
            +  bitwiseassignop("^=", "assignbitxor", 20);
            +  bitwiseassignop("<<=", "assignshiftleft", 20);
            +  bitwiseassignop(">>=", "assignshiftright", 20);
            +  bitwiseassignop(">>>=", "assignshiftrightunsigned", 20);
            +  infix(",", function (left, that) {
            +    var expr;
            +    that.exprs = [left];
            +    if (!comma({peek: true})) {
            +      return that;
            +    }
            +    while (true) {
            +      if (!(expr = expression(10)))  {
            +        break;
            +      }
            +      that.exprs.push(expr);
            +      if (state.tokens.next.value !== "," || !comma()) {
            +        break;
            +      }
            +    }
            +    return that;
            +  }, 10, true);
            +
            +  infix("?", function (left, that) {
            +    increaseComplexityCount();
            +    that.left = left;
            +    that.right = expression(10);
            +    advance(":");
            +    that["else"] = expression(10);
            +    return that;
            +  }, 30);
            +
            +  var orPrecendence = 40;
            +  infix("||", function (left, that) {
            +    increaseComplexityCount();
            +    that.left = left;
            +    that.right = expression(orPrecendence);
            +    return that;
            +  }, orPrecendence);
            +  infix("&&", "and", 50);
            +  bitwise("|", "bitor", 70);
            +  bitwise("^", "bitxor", 80);
            +  bitwise("&", "bitand", 90);
            +  relation("==", function (left, right) {
            +    var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null");
            +
            +    switch (true) {
            +      case !eqnull && state.option.eqeqeq:
            +        this.from = this.character;
            +        warning("W116", this, "===", "==");
            +        break;
            +      case isPoorRelation(left):
            +        warning("W041", this, "===", left.value);
            +        break;
            +      case isPoorRelation(right):
            +        warning("W041", this, "===", right.value);
            +        break;
            +      case isTypoTypeof(right, left):
            +        warning("W122", this, right.value);
            +        break;
            +      case isTypoTypeof(left, right):
            +        warning("W122", this, left.value);
            +        break;
            +    }
            +
            +    return this;
            +  });
            +  relation("===", function (left, right) {
            +    if (isTypoTypeof(right, left)) {
            +      warning("W122", this, right.value);
            +    } else if (isTypoTypeof(left, right)) {
            +      warning("W122", this, left.value);
            +    }
            +    return this;
            +  });
            +  relation("!=", function (left, right) {
            +    var eqnull = state.option.eqnull &&
            +        (left.value === "null" || right.value === "null");
            +
            +    if (!eqnull && state.option.eqeqeq) {
            +      this.from = this.character;
            +      warning("W116", this, "!==", "!=");
            +    } else if (isPoorRelation(left)) {
            +      warning("W041", this, "!==", left.value);
            +    } else if (isPoorRelation(right)) {
            +      warning("W041", this, "!==", right.value);
            +    } else if (isTypoTypeof(right, left)) {
            +      warning("W122", this, right.value);
            +    } else if (isTypoTypeof(left, right)) {
            +      warning("W122", this, left.value);
            +    }
            +    return this;
            +  });
            +  relation("!==", function (left, right) {
            +    if (isTypoTypeof(right, left)) {
            +      warning("W122", this, right.value);
            +    } else if (isTypoTypeof(left, right)) {
            +      warning("W122", this, left.value);
            +    }
            +    return this;
            +  });
            +  relation("<");
            +  relation(">");
            +  relation("<=");
            +  relation(">=");
            +  bitwise("<<", "shiftleft", 120);
            +  bitwise(">>", "shiftright", 120);
            +  bitwise(">>>", "shiftrightunsigned", 120);
            +  infix("in", "in", 120);
            +  infix("instanceof", "instanceof", 120);
            +  infix("+", function (left, that) {
            +    var right = expression(130);
            +    if (left && right && left.id === "(string)" && right.id === "(string)") {
            +      left.value += right.value;
            +      left.character = right.character;
            +      if (!state.option.scripturl && reg.javascriptURL.test(left.value)) {
            +        warning("W050", left);
            +      }
            +      return left;
            +    }
            +    that.left = left;
            +    that.right = right;
            +    return that;
            +  }, 130);
            +  prefix("+", "num");
            +  prefix("+++", function () {
            +    warning("W007");
            +    this.right = expression(150);
            +    this.arity = "unary";
            +    return this;
            +  });
            +  infix("+++", function (left) {
            +    warning("W007");
            +    this.left = left;
            +    this.right = expression(130);
            +    return this;
            +  }, 130);
            +  infix("-", "sub", 130);
            +  prefix("-", "neg");
            +  prefix("---", function () {
            +    warning("W006");
            +    this.right = expression(150);
            +    this.arity = "unary";
            +    return this;
            +  });
            +  infix("---", function (left) {
            +    warning("W006");
            +    this.left = left;
            +    this.right = expression(130);
            +    return this;
            +  }, 130);
            +  infix("*", "mult", 140);
            +  infix("/", "div", 140);
            +  infix("%", "mod", 140);
            +
            +  suffix("++", "postinc");
            +  prefix("++", "preinc");
            +  state.syntax["++"].exps = true;
            +
            +  suffix("--", "postdec");
            +  prefix("--", "predec");
            +  state.syntax["--"].exps = true;
            +  prefix("delete", function () {
            +    var p = expression(10);
            +    if (!p || (p.id !== "." && p.id !== "[")) {
            +      warning("W051");
            +    }
            +    this.first = p;
            +    return this;
            +  }).exps = true;
            +
            +  prefix("~", function () {
            +    if (state.option.bitwise) {
            +      warning("W052", this, "~");
            +    }
            +    expression(150);
            +    return this;
            +  });
            +
            +  prefix("...", function () {
            +    if (!state.option.inESNext()) {
            +      warning("W104", this, "spread/rest operator");
            +    }
            +    if (!state.tokens.next.identifier) {
            +      error("E030", state.tokens.next, state.tokens.next.value);
            +    }
            +    expression(150);
            +    return this;
            +  });
            +
            +  prefix("!", function () {
            +    this.right = expression(150);
            +    this.arity = "unary";
            +
            +    if (!this.right) { // '!' followed by nothing? Give up.
            +      quit("E041", this.line || 0);
            +    }
            +
            +    if (bang[this.right.id] === true) {
            +      warning("W018", this, "!");
            +    }
            +    return this;
            +  });
            +
            +  prefix("typeof", "typeof");
            +  prefix("new", function () {
            +    var c = expression(155), i;
            +    if (c && c.id !== "function") {
            +      if (c.identifier) {
            +        c["new"] = true;
            +        switch (c.value) {
            +        case "Number":
            +        case "String":
            +        case "Boolean":
            +        case "Math":
            +        case "JSON":
            +          warning("W053", state.tokens.prev, c.value);
            +          break;
            +        case "Function":
            +          if (!state.option.evil) {
            +            warning("W054");
            +          }
            +          break;
            +        case "Date":
            +        case "RegExp":
            +        case "this":
            +          break;
            +        default:
            +          if (c.id !== "function") {
            +            i = c.value.substr(0, 1);
            +            if (state.option.newcap && (i < "A" || i > "Z") && !_.has(global, c.value)) {
            +              warning("W055", state.tokens.curr);
            +            }
            +          }
            +        }
            +      } else {
            +        if (c.id !== "." && c.id !== "[" && c.id !== "(") {
            +          warning("W056", state.tokens.curr);
            +        }
            +      }
            +    } else {
            +      if (!state.option.supernew)
            +        warning("W057", this);
            +    }
            +    if (state.tokens.next.id !== "(" && !state.option.supernew) {
            +      warning("W058", state.tokens.curr, state.tokens.curr.value);
            +    }
            +    this.first = c;
            +    return this;
            +  });
            +  state.syntax["new"].exps = true;
            +
            +  prefix("void").exps = true;
            +
            +  infix(".", function (left, that) {
            +    var m = identifier(false, true);
            +
            +    if (typeof m === "string") {
            +      countMember(m);
            +    }
            +
            +    that.left = left;
            +    that.right = m;
            +
            +    if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") {
            +      warning("W001");
            +    }
            +
            +    if (left && left.value === "arguments" && (m === "callee" || m === "caller")) {
            +      if (state.option.noarg)
            +        warning("W059", left, m);
            +      else if (state.directive["use strict"])
            +        error("E008");
            +    } else if (!state.option.evil && left && left.value === "document" &&
            +        (m === "write" || m === "writeln")) {
            +      warning("W060", left);
            +    }
            +
            +    if (!state.option.evil && (m === "eval" || m === "execScript")) {
            +      warning("W061");
            +    }
            +
            +    return that;
            +  }, 160, true);
            +
            +  infix("(", function (left, that) {
            +    if (state.option.immed && left && !left.immed && left.id === "function") {
            +      warning("W062");
            +    }
            +
            +    var n = 0;
            +    var p = [];
            +
            +    if (left) {
            +      if (left.type === "(identifier)") {
            +        if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) {
            +          if ("Number String Boolean Date Object Error".indexOf(left.value) === -1) {
            +            if (left.value === "Math") {
            +              warning("W063", left);
            +            } else if (state.option.newcap) {
            +              warning("W064", left);
            +            }
            +          }
            +        }
            +      }
            +    }
            +
            +    if (state.tokens.next.id !== ")") {
            +      for (;;) {
            +        p[p.length] = expression(10);
            +        n += 1;
            +        if (state.tokens.next.id !== ",") {
            +          break;
            +        }
            +        comma();
            +      }
            +    }
            +
            +    advance(")");
            +
            +    if (typeof left === "object") {
            +      if (state.option.inES3() && left.value === "parseInt" && n === 1) {
            +        warning("W065", state.tokens.curr);
            +      }
            +      if (!state.option.evil) {
            +        if (left.value === "eval" || left.value === "Function" ||
            +            left.value === "execScript") {
            +          warning("W061", left);
            +
            +          if (p[0] && [0].id === "(string)") {
            +            addInternalSrc(left, p[0].value);
            +          }
            +        } else if (p[0] && p[0].id === "(string)" &&
            +             (left.value === "setTimeout" ||
            +            left.value === "setInterval")) {
            +          warning("W066", left);
            +          addInternalSrc(left, p[0].value);
            +        } else if (p[0] && p[0].id === "(string)" &&
            +             left.value === "." &&
            +             left.left.value === "window" &&
            +             (left.right === "setTimeout" ||
            +            left.right === "setInterval")) {
            +          warning("W066", left);
            +          addInternalSrc(left, p[0].value);
            +        }
            +      }
            +      if (!left.identifier && left.id !== "." && left.id !== "[" &&
            +          left.id !== "(" && left.id !== "&&" && left.id !== "||" &&
            +          left.id !== "?") {
            +        warning("W067", left);
            +      }
            +    }
            +
            +    that.left = left;
            +    return that;
            +  }, 155, true).exps = true;
            +
            +  prefix("(", function () {
            +    var bracket, brackets = [];
            +    var pn, pn1, i = 0;
            +    var ret;
            +    var parens = 1;
            +
            +    do {
            +      pn = peek(i);
            +
            +      if (pn.value === "(") {
            +        parens += 1;
            +      } else if (pn.value === ")") {
            +        parens -= 1;
            +      }
            +
            +      i += 1;
            +      pn1 = peek(i);
            +    } while (!(parens === 0 && pn.value === ")") &&
            +             pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)");
            +
            +    if (state.tokens.next.id === "function") {
            +      state.tokens.next.immed = true;
            +    }
            +
            +    var exprs = [];
            +
            +    if (state.tokens.next.id !== ")") {
            +      for (;;) {
            +        if (pn1.value === "=>" && _.contains(["{", "["], state.tokens.next.value)) {
            +          bracket = state.tokens.next;
            +          bracket.left = destructuringExpression();
            +          brackets.push(bracket);
            +          for (var t in bracket.left) {
            +            exprs.push(bracket.left[t].token);
            +          }
            +        } else {
            +          exprs.push(expression(10));
            +        }
            +        if (state.tokens.next.id !== ",") {
            +          break;
            +        }
            +        comma();
            +      }
            +    }
            +
            +    advance(")", this);
            +    if (state.option.immed && exprs[0] && exprs[0].id === "function") {
            +      if (state.tokens.next.id !== "(" &&
            +        (state.tokens.next.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) {
            +        warning("W068", this);
            +      }
            +    }
            +
            +    if (state.tokens.next.value === "=>") {
            +      return exprs;
            +    }
            +    if (!exprs.length) {
            +      return;
            +    }
            +    if (exprs.length > 1) {
            +      ret = Object.create(state.syntax[","]);
            +      ret.exprs = exprs;
            +    } else {
            +      ret = exprs[0];
            +    }
            +    if (ret) {
            +      ret.paren = true;
            +    }
            +    return ret;
            +  });
            +
            +  application("=>");
            +
            +  infix("[", function (left, that) {
            +    var e = expression(10), s;
            +    if (e && e.type === "(string)") {
            +      if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) {
            +        warning("W061", that);
            +      }
            +
            +      countMember(e.value);
            +      if (!state.option.sub && reg.identifier.test(e.value)) {
            +        s = state.syntax[e.value];
            +        if (!s || !isReserved(s)) {
            +          warning("W069", state.tokens.prev, e.value);
            +        }
            +      }
            +    }
            +    advance("]", that);
            +
            +    if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") {
            +      warning("W001");
            +    }
            +
            +    that.left = left;
            +    that.right = e;
            +    return that;
            +  }, 160, true);
            +
            +  function comprehensiveArrayExpression() {
            +    var res = {};
            +    res.exps = true;
            +    funct["(comparray)"].stack();
            +    var reversed = false;
            +    if (state.tokens.next.value !== "for") {
            +      reversed = true;
            +      if (!state.option.inMoz(true)) {
            +        warning("W116", state.tokens.next, "for", state.tokens.next.value);
            +      }
            +      funct["(comparray)"].setState("use");
            +      res.right = expression(10);
            +    }
            +
            +    advance("for");
            +    if (state.tokens.next.value === "each") {
            +      advance("each");
            +      if (!state.option.inMoz(true)) {
            +        warning("W118", state.tokens.curr, "for each");
            +      }
            +    }
            +    advance("(");
            +    funct["(comparray)"].setState("define");
            +    res.left = expression(130);
            +    if (_.contains(["in", "of"], state.tokens.next.value)) {
            +      advance();
            +    } else {
            +      error("E045", state.tokens.curr);
            +    }
            +    funct["(comparray)"].setState("generate");
            +    expression(10);
            +
            +    advance(")");
            +    if (state.tokens.next.value === "if") {
            +      advance("if");
            +      advance("(");
            +      funct["(comparray)"].setState("filter");
            +      res.filter = expression(10);
            +      advance(")");
            +    }
            +
            +    if (!reversed) {
            +      funct["(comparray)"].setState("use");
            +      res.right = expression(10);
            +    }
            +
            +    advance("]");
            +    funct["(comparray)"].unstack();
            +    return res;
            +  }
            +
            +  prefix("[", function () {
            +    var blocktype = lookupBlockType(true);
            +    if (blocktype.isCompArray) {
            +      if (!state.option.inESNext()) {
            +        warning("W119", state.tokens.curr, "array comprehension");
            +      }
            +      return comprehensiveArrayExpression();
            +    } else if (blocktype.isDestAssign && !state.option.inESNext()) {
            +      warning("W104", state.tokens.curr, "destructuring assignment");
            +    }
            +    var b = state.tokens.curr.line !== state.tokens.next.line;
            +    this.first = [];
            +    if (b) {
            +      indent += state.option.indent;
            +      if (state.tokens.next.from === indent + state.option.indent) {
            +        indent += state.option.indent;
            +      }
            +    }
            +    while (state.tokens.next.id !== "(end)") {
            +      while (state.tokens.next.id === ",") {
            +        if (!state.option.inES5())
            +          warning("W070");
            +        advance(",");
            +      }
            +
            +      if (state.tokens.next.id === "]") {
            +        break;
            +      }
            +
            +      this.first.push(expression(10));
            +      if (state.tokens.next.id === ",") {
            +        comma({ allowTrailing: true });
            +        if (state.tokens.next.id === "]" && !state.option.inES5(true)) {
            +          warning("W070", state.tokens.curr);
            +          break;
            +        }
            +      } else {
            +        break;
            +      }
            +    }
            +    if (b) {
            +      indent -= state.option.indent;
            +    }
            +    advance("]", this);
            +    return this;
            +  }, 160);
            +
            +
            +  function property_name() {
            +    var id = optionalidentifier(false, true);
            +
            +    if (!id) {
            +      if (state.tokens.next.id === "(string)") {
            +        id = state.tokens.next.value;
            +        advance();
            +      } else if (state.tokens.next.id === "(number)") {
            +        id = state.tokens.next.value.toString();
            +        advance();
            +      }
            +    }
            +
            +    if (id === "hasOwnProperty") {
            +      warning("W001");
            +    }
            +
            +    return id;
            +  }
            +
            +  function functionparams(parsed) {
            +    var curr, next;
            +    var params = [];
            +    var ident;
            +    var tokens = [];
            +    var t;
            +    var pastDefault = false;
            +
            +    if (parsed) {
            +      if (Array.isArray(parsed)) {
            +        for (var i in parsed) {
            +          curr = parsed[i];
            +          if (curr.value === "...") {
            +            if (!state.option.inESNext()) {
            +              warning("W104", curr, "spread/rest operator");
            +            }
            +            continue;
            +          } else if (curr.value !== ",") {
            +            params.push(curr.value);
            +            addlabel(curr.value, { type: "unused", token: curr });
            +          }
            +        }
            +        return params;
            +      } else {
            +        if (parsed.identifier === true) {
            +          addlabel(parsed.value, { type: "unused", token: parsed });
            +          return [parsed];
            +        }
            +      }
            +    }
            +
            +    next = state.tokens.next;
            +
            +    advance("(");
            +
            +    if (state.tokens.next.id === ")") {
            +      advance(")");
            +      return;
            +    }
            +
            +    for (;;) {
            +      if (_.contains(["{", "["], state.tokens.next.id)) {
            +        tokens = destructuringExpression();
            +        for (t in tokens) {
            +          t = tokens[t];
            +          if (t.id) {
            +            params.push(t.id);
            +            addlabel(t.id, { type: "unused", token: t.token });
            +          }
            +        }
            +      } else if (state.tokens.next.value === "...") {
            +        if (!state.option.inESNext()) {
            +          warning("W104", state.tokens.next, "spread/rest operator");
            +        }
            +        advance("...");
            +        ident = identifier(true);
            +        params.push(ident);
            +        addlabel(ident, { type: "unused", token: state.tokens.curr });
            +      } else {
            +        ident = identifier(true);
            +        params.push(ident);
            +        addlabel(ident, { type: "unused", token: state.tokens.curr });
            +      }
            +      if (pastDefault) {
            +        if (state.tokens.next.id !== "=") {
            +          error("E051", state.tokens.current);
            +        }
            +      }
            +      if (state.tokens.next.id === "=") {
            +        if (!state.option.inESNext()) {
            +          warning("W119", state.tokens.next, "default parameters");
            +        }
            +        advance("=");
            +        pastDefault = true;
            +        expression(10);
            +      }
            +      if (state.tokens.next.id === ",") {
            +        comma();
            +      } else {
            +        advance(")", next);
            +        return params;
            +      }
            +    }
            +  }
            +
            +  function setprop(funct, name, values) {
            +    if (!funct["(properties)"][name]) {
            +      funct["(properties)"][name] = { unused: false };
            +    }
            +
            +    _.extend(funct["(properties)"][name], values);
            +  }
            +
            +  function getprop(funct, name, prop) {
            +    if (!funct["(properties)"][name])
            +      return null;
            +
            +    return funct["(properties)"][name][prop] || null;
            +  }
            +
            +  function functor(name, token, scope, overwrites) {
            +    var funct = {
            +      "(name)"      : name,
            +      "(breakage)"  : 0,
            +      "(loopage)"   : 0,
            +      "(scope)"     : scope,
            +      "(tokens)"    : {},
            +      "(properties)": {},
            +
            +      "(catch)"     : false,
            +      "(global)"    : false,
            +
            +      "(line)"      : null,
            +      "(character)" : null,
            +      "(metrics)"   : null,
            +      "(statement)" : null,
            +      "(context)"   : null,
            +      "(blockscope)": null,
            +      "(comparray)" : null,
            +      "(generator)" : null,
            +      "(params)"    : null
            +    };
            +
            +    if (token) {
            +      _.extend(funct, {
            +        "(line)"     : token.line,
            +        "(character)": token.character,
            +        "(metrics)"  : createMetrics(token)
            +      });
            +    }
            +
            +    _.extend(funct, overwrites);
            +
            +    if (funct["(context)"]) {
            +      funct["(blockscope)"] = funct["(context)"]["(blockscope)"];
            +      funct["(comparray)"]  = funct["(context)"]["(comparray)"];
            +    }
            +
            +    return funct;
            +  }
            +
            +  function doFunction(name, statement, generator, fatarrowparams) {
            +    var f;
            +    var oldOption = state.option;
            +    var oldIgnored = state.ignored;
            +    var oldScope  = scope;
            +
            +    state.option = Object.create(state.option);
            +    state.ignored = Object.create(state.ignored);
            +    scope = Object.create(scope);
            +
            +    funct = functor(name || "\"" + anonname + "\"", state.tokens.next, scope, {
            +      "(statement)": statement,
            +      "(context)":   funct,
            +      "(generator)": generator ? true : null
            +    });
            +
            +    f = funct;
            +    state.tokens.curr.funct = funct;
            +
            +    functions.push(funct);
            +
            +    if (name) {
            +      addlabel(name, { type: "function" });
            +    }
            +
            +    funct["(params)"] = functionparams(fatarrowparams);
            +    funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]);
            +
            +    JSHINT.undefs = _.filter(JSHINT.undefs, function (item) {
            +      return !_.contains(_.union(fatarrowparams), item[2]);
            +    });
            +
            +    block(false, true, true, fatarrowparams ? true : false);
            +
            +    if (!state.option.noyield && generator && funct["(generator)"] !== "yielded") {
            +      warning("W124", state.tokens.curr);
            +    }
            +
            +    funct["(metrics)"].verifyMaxStatementsPerFunction();
            +    funct["(metrics)"].verifyMaxComplexityPerFunction();
            +    funct["(unusedOption)"] = state.option.unused;
            +
            +    scope = oldScope;
            +    state.option = oldOption;
            +    state.ignored = oldIgnored;
            +    funct["(last)"] = state.tokens.curr.line;
            +    funct["(lastcharacter)"] = state.tokens.curr.character;
            +
            +    _.map(Object.keys(funct), function (key) {
            +      if (key[0] === "(") return;
            +      funct["(blockscope)"].unshadow(key);
            +    });
            +
            +    funct = funct["(context)"];
            +
            +    return f;
            +  }
            +
            +  function createMetrics(functionStartToken) {
            +    return {
            +      statementCount: 0,
            +      nestedBlockDepth: -1,
            +      ComplexityCount: 1,
            +
            +      verifyMaxStatementsPerFunction: function () {
            +        if (state.option.maxstatements &&
            +          this.statementCount > state.option.maxstatements) {
            +          warning("W071", functionStartToken, this.statementCount);
            +        }
            +      },
            +
            +      verifyMaxParametersPerFunction: function (params) {
            +        params = params || [];
            +
            +        if (state.option.maxparams && params.length > state.option.maxparams) {
            +          warning("W072", functionStartToken, params.length);
            +        }
            +      },
            +
            +      verifyMaxNestedBlockDepthPerFunction: function () {
            +        if (state.option.maxdepth &&
            +          this.nestedBlockDepth > 0 &&
            +          this.nestedBlockDepth === state.option.maxdepth + 1) {
            +          warning("W073", null, this.nestedBlockDepth);
            +        }
            +      },
            +
            +      verifyMaxComplexityPerFunction: function () {
            +        var max = state.option.maxcomplexity;
            +        var cc = this.ComplexityCount;
            +        if (max && cc > max) {
            +          warning("W074", functionStartToken, cc);
            +        }
            +      }
            +    };
            +  }
            +
            +  function increaseComplexityCount() {
            +    funct["(metrics)"].ComplexityCount += 1;
            +  }
            +
            +  function checkCondAssignment(expr) {
            +    var id, paren;
            +    if (expr) {
            +      id = expr.id;
            +      paren = expr.paren;
            +      if (id === "," && (expr = expr.exprs[expr.exprs.length - 1])) {
            +        id = expr.id;
            +        paren = paren || expr.paren;
            +      }
            +    }
            +    switch (id) {
            +    case "=":
            +    case "+=":
            +    case "-=":
            +    case "*=":
            +    case "%=":
            +    case "&=":
            +    case "|=":
            +    case "^=":
            +    case "/=":
            +      if (!paren && !state.option.boss) {
            +        warning("W084");
            +      }
            +    }
            +  }
            +
            +
            +  (function (x) {
            +    x.nud = function (isclassdef) {
            +      var b, f, i, p, t, g;
            +      var props = {}; // All properties, including accessors
            +      var tag = "";
            +
            +      function saveProperty(name, tkn) {
            +        if (props[name] && _.has(props, name))
            +          warning("W075", state.tokens.next, i);
            +        else
            +          props[name] = {};
            +
            +        props[name].basic = true;
            +        props[name].basictkn = tkn;
            +      }
            +
            +      function saveSetter(name, tkn) {
            +        if (props[name] && _.has(props, name)) {
            +          if (props[name].basic || props[name].setter)
            +            warning("W075", state.tokens.next, i);
            +        } else {
            +          props[name] = {};
            +        }
            +
            +        props[name].setter = true;
            +        props[name].setterToken = tkn;
            +      }
            +
            +      function saveGetter(name) {
            +        if (props[name] && _.has(props, name)) {
            +          if (props[name].basic || props[name].getter)
            +            warning("W075", state.tokens.next, i);
            +        } else {
            +          props[name] = {};
            +        }
            +
            +        props[name].getter = true;
            +        props[name].getterToken = state.tokens.curr;
            +      }
            +
            +      b = state.tokens.curr.line !== state.tokens.next.line;
            +      if (b) {
            +        indent += state.option.indent;
            +        if (state.tokens.next.from === indent + state.option.indent) {
            +          indent += state.option.indent;
            +        }
            +      }
            +
            +      for (;;) {
            +        if (state.tokens.next.id === "}") {
            +          break;
            +        }
            +
            +        if (isclassdef && state.tokens.next.value === "static") {
            +          advance("static");
            +          tag = "static ";
            +        }
            +
            +        if (state.tokens.next.value === "get" && peek().id !== ":") {
            +          advance("get");
            +
            +          if (!state.option.inES5(!isclassdef)) {
            +            error("E034");
            +          }
            +
            +          i = property_name();
            +          if (!i && !state.option.inESNext()) {
            +            error("E035");
            +          }
            +          if (isclassdef && i === "constructor") {
            +            error("E049", state.tokens.next, "class getter method", i);
            +          }
            +          if (i) {
            +            saveGetter(tag + i);
            +          }
            +
            +          t = state.tokens.next;
            +          f = doFunction();
            +          p = f["(params)"];
            +          if (i && p) {
            +            warning("W076", t, p[0], i);
            +          }
            +        } else if (state.tokens.next.value === "set" && peek().id !== ":") {
            +          advance("set");
            +
            +          if (!state.option.inES5(!isclassdef)) {
            +            error("E034");
            +          }
            +
            +          i = property_name();
            +          if (!i && !state.option.inESNext()) {
            +            error("E035");
            +          }
            +          if (isclassdef && i === "constructor") {
            +            error("E049", state.tokens.next, "class setter method", i);
            +          }
            +          if (i) {
            +            saveSetter(tag + i, state.tokens.next);
            +          }
            +
            +          t = state.tokens.next;
            +          f = doFunction();
            +          p = f["(params)"];
            +          if (i && (!p || p.length !== 1)) {
            +            warning("W077", t, i);
            +          }
            +        } else {
            +          g = false;
            +          if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") {
            +            if (!state.option.inESNext()) {
            +              warning("W104", state.tokens.next, "generator functions");
            +            }
            +            advance("*");
            +            g = true;
            +          }
            +          i = property_name();
            +          saveProperty(tag + i, state.tokens.next);
            +
            +          if (typeof i !== "string") {
            +            break;
            +          }
            +
            +          if (state.tokens.next.value === "(") {
            +            if (!state.option.inESNext()) {
            +              warning("W104", state.tokens.curr, "concise methods");
            +            }
            +            doFunction(i, undefined, g);
            +          } else if (!isclassdef) {
            +            advance(":");
            +            expression(10);
            +          }
            +        }
            +        if (isclassdef && i === "prototype") {
            +          error("E049", state.tokens.next, "class method", i);
            +        }
            +
            +        countMember(i);
            +        if (isclassdef) {
            +          tag = "";
            +          continue;
            +        }
            +        if (state.tokens.next.id === ",") {
            +          comma({ allowTrailing: true, property: true });
            +          if (state.tokens.next.id === ",") {
            +            warning("W070", state.tokens.curr);
            +          } else if (state.tokens.next.id === "}" && !state.option.inES5(true)) {
            +            warning("W070", state.tokens.curr);
            +          }
            +        } else {
            +          break;
            +        }
            +      }
            +      if (b) {
            +        indent -= state.option.indent;
            +      }
            +      advance("}", this);
            +      if (state.option.inES5()) {
            +        for (var name in props) {
            +          if (_.has(props, name) && props[name].setter && !props[name].getter) {
            +            warning("W078", props[name].setterToken);
            +          }
            +        }
            +      }
            +      return this;
            +    };
            +    x.fud = function () {
            +      error("E036", state.tokens.curr);
            +    };
            +  }(delim("{")));
            +
            +  function destructuringExpression() {
            +    var id, ids;
            +    var identifiers = [];
            +    if (!state.option.inESNext()) {
            +      warning("W104", state.tokens.curr, "destructuring expression");
            +    }
            +    var nextInnerDE = function () {
            +      var ident;
            +      if (_.contains(["[", "{"], state.tokens.next.value)) {
            +        ids = destructuringExpression();
            +        for (var id in ids) {
            +          id = ids[id];
            +          identifiers.push({ id: id.id, token: id.token });
            +        }
            +      } else if (state.tokens.next.value === ",") {
            +        identifiers.push({ id: null, token: state.tokens.curr });
            +      } else if (state.tokens.next.value === "(") {
            +        advance("(");
            +        nextInnerDE();
            +        advance(")");
            +      } else {
            +        ident = identifier();
            +        if (ident)
            +          identifiers.push({ id: ident, token: state.tokens.curr });
            +      }
            +    };
            +    if (state.tokens.next.value === "[") {
            +      advance("[");
            +      nextInnerDE();
            +      while (state.tokens.next.value !== "]") {
            +        advance(",");
            +        nextInnerDE();
            +      }
            +      advance("]");
            +    } else if (state.tokens.next.value === "{") {
            +      advance("{");
            +      id = identifier();
            +      if (state.tokens.next.value === ":") {
            +        advance(":");
            +        nextInnerDE();
            +      } else {
            +        identifiers.push({ id: id, token: state.tokens.curr });
            +      }
            +      while (state.tokens.next.value !== "}") {
            +        advance(",");
            +        id = identifier();
            +        if (state.tokens.next.value === ":") {
            +          advance(":");
            +          nextInnerDE();
            +        } else {
            +          identifiers.push({ id: id, token: state.tokens.curr });
            +        }
            +      }
            +      advance("}");
            +    }
            +    return identifiers;
            +  }
            +
            +  function destructuringExpressionMatch(tokens, value) {
            +    var first = value.first;
            +
            +    if (!first)
            +      return;
            +
            +    _.zip(tokens, Array.isArray(first) ? first : [ first ]).forEach(function (val) {
            +      var token = val[0];
            +      var value = val[1];
            +
            +      if (token && value)
            +        token.first = value;
            +      else if (token && token.first && !value)
            +        warning("W080", token.first, token.first.value);
            +    });
            +  }
            +
            +  var conststatement = stmt("const", function (prefix) {
            +    var tokens;
            +    var value;
            +    var lone; // State variable to know if it is a lone identifier, or a destructuring statement.
            +
            +    if (!state.option.inESNext())
            +      warning("W104", state.tokens.curr, "const");
            +
            +    this.first = [];
            +    for (;;) {
            +      var names = [];
            +      if (_.contains(["{", "["], state.tokens.next.value)) {
            +        tokens = destructuringExpression();
            +        lone = false;
            +      } else {
            +        tokens = [ { id: identifier(), token: state.tokens.curr } ];
            +        lone = true;
            +      }
            +      for (var t in tokens) {
            +        if (tokens.hasOwnProperty(t)) {
            +          t = tokens[t];
            +          if (funct[t.id] === "const") {
            +            warning("E011", null, t.id);
            +          }
            +          if (funct["(global)"] && predefined[t.id] === false) {
            +            warning("W079", t.token, t.id);
            +          }
            +          if (t.id) {
            +            addlabel(t.id, { token: t.token, type: "const", unused: true });
            +            names.push(t.token);
            +          }
            +        }
            +      }
            +      if (prefix) {
            +        break;
            +      }
            +
            +      this.first = this.first.concat(names);
            +
            +      if (state.tokens.next.id !== "=") {
            +        warning("E012", state.tokens.curr, state.tokens.curr.value);
            +      }
            +
            +      if (state.tokens.next.id === "=") {
            +        advance("=");
            +        if (state.tokens.next.id === "undefined") {
            +          warning("W080", state.tokens.prev, state.tokens.prev.value);
            +        }
            +        if (peek(0).id === "=" && state.tokens.next.identifier) {
            +          warning("W120", state.tokens.next, state.tokens.next.value);
            +        }
            +        value = expression(10);
            +        if (lone) {
            +          tokens[0].first = value;
            +        } else {
            +          destructuringExpressionMatch(names, value);
            +        }
            +      }
            +
            +      if (state.tokens.next.id !== ",") {
            +        break;
            +      }
            +      comma();
            +    }
            +    return this;
            +  });
            +
            +  conststatement.exps = true;
            +  var varstatement = stmt("var", function (prefix) {
            +    var tokens, lone, value;
            +
            +    this.first = [];
            +    for (;;) {
            +      var names = [];
            +      if (_.contains(["{", "["], state.tokens.next.value)) {
            +        tokens = destructuringExpression();
            +        lone = false;
            +      } else {
            +        tokens = [ { id: identifier(), token: state.tokens.curr } ];
            +        lone = true;
            +      }
            +      for (var t in tokens) {
            +        if (tokens.hasOwnProperty(t)) {
            +          t = tokens[t];
            +          if (state.option.inESNext() && funct[t.id] === "const") {
            +            warning("E011", null, t.id);
            +          }
            +          if (funct["(global)"] && predefined[t.id] === false) {
            +            warning("W079", t.token, t.id);
            +          }
            +          if (t.id) {
            +            addlabel(t.id, { type: "unused", token: t.token });
            +            names.push(t.token);
            +          }
            +        }
            +      }
            +      if (prefix) {
            +        break;
            +      }
            +
            +      this.first = this.first.concat(names);
            +
            +      if (state.tokens.next.id === "=") {
            +        advance("=");
            +        if (state.tokens.next.id === "undefined") {
            +          warning("W080", state.tokens.prev, state.tokens.prev.value);
            +        }
            +        if (peek(0).id === "=" && state.tokens.next.identifier) {
            +          warning("W120", state.tokens.next, state.tokens.next.value);
            +        }
            +        value = expression(10);
            +        if (lone) {
            +          tokens[0].first = value;
            +        } else {
            +          destructuringExpressionMatch(names, value);
            +        }
            +      }
            +
            +      if (state.tokens.next.id !== ",") {
            +        break;
            +      }
            +      comma();
            +    }
            +    return this;
            +  });
            +  varstatement.exps = true;
            +
            +  var letstatement = stmt("let", function (prefix) {
            +    var tokens, lone, value, letblock;
            +
            +    if (!state.option.inESNext()) {
            +      warning("W104", state.tokens.curr, "let");
            +    }
            +
            +    if (state.tokens.next.value === "(") {
            +      if (!state.option.inMoz(true)) {
            +        warning("W118", state.tokens.next, "let block");
            +      }
            +      advance("(");
            +      funct["(blockscope)"].stack();
            +      letblock = true;
            +    } else if (funct["(nolet)"]) {
            +      error("E048", state.tokens.curr);
            +    }
            +
            +    this.first = [];
            +    for (;;) {
            +      var names = [];
            +      if (_.contains(["{", "["], state.tokens.next.value)) {
            +        tokens = destructuringExpression();
            +        lone = false;
            +      } else {
            +        tokens = [ { id: identifier(), token: state.tokens.curr.value } ];
            +        lone = true;
            +      }
            +      for (var t in tokens) {
            +        if (tokens.hasOwnProperty(t)) {
            +          t = tokens[t];
            +          if (state.option.inESNext() && funct[t.id] === "const") {
            +            warning("E011", null, t.id);
            +          }
            +          if (funct["(global)"] && predefined[t.id] === false) {
            +            warning("W079", t.token, t.id);
            +          }
            +          if (t.id && !funct["(nolet)"]) {
            +            addlabel(t.id, { type: "unused", token: t.token, islet: true });
            +            names.push(t.token);
            +          }
            +        }
            +      }
            +      if (prefix) {
            +        break;
            +      }
            +
            +      this.first = this.first.concat(names);
            +
            +      if (state.tokens.next.id === "=") {
            +        advance("=");
            +        if (state.tokens.next.id === "undefined") {
            +          warning("W080", state.tokens.prev, state.tokens.prev.value);
            +        }
            +        if (peek(0).id === "=" && state.tokens.next.identifier) {
            +          warning("W120", state.tokens.next, state.tokens.next.value);
            +        }
            +        value = expression(10);
            +        if (lone) {
            +          tokens[0].first = value;
            +        } else {
            +          destructuringExpressionMatch(names, value);
            +        }
            +      }
            +
            +      if (state.tokens.next.id !== ",") {
            +        break;
            +      }
            +      comma();
            +    }
            +    if (letblock) {
            +      advance(")");
            +      block(true, true);
            +      this.block = true;
            +      funct["(blockscope)"].unstack();
            +    }
            +
            +    return this;
            +  });
            +  letstatement.exps = true;
            +
            +  blockstmt("class", function () {
            +    return classdef.call(this, true);
            +  });
            +
            +  function classdef(stmt) {
            +    if (!state.option.inESNext()) {
            +      warning("W104", state.tokens.curr, "class");
            +    }
            +    if (stmt) {
            +      this.name = identifier();
            +      addlabel(this.name, { type: "unused", token: state.tokens.curr });
            +    } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") {
            +      this.name = identifier();
            +    }
            +    classtail(this);
            +    return this;
            +  }
            +
            +  function classtail(c) {
            +    var strictness = state.directive["use strict"];
            +    if (state.tokens.next.value === "extends") {
            +      advance("extends");
            +      c.heritage = expression(10);
            +    }
            +    state.directive["use strict"] = true;
            +    advance("{");
            +    c.body = state.syntax["{"].nud(true);
            +    state.directive["use strict"] = strictness;
            +  }
            +
            +  blockstmt("function", function () {
            +    var generator = false;
            +    if (state.tokens.next.value === "*") {
            +      advance("*");
            +      if (state.option.inESNext(true)) {
            +        generator = true;
            +      } else {
            +        warning("W119", state.tokens.curr, "function*");
            +      }
            +    }
            +    if (inblock) {
            +      warning("W082", state.tokens.curr);
            +
            +    }
            +    var i = identifier();
            +    if (funct[i] === "const") {
            +      warning("E011", null, i);
            +    }
            +    addlabel(i, { type: "unction", token: state.tokens.curr });
            +
            +    doFunction(i, { statement: true }, generator);
            +    if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) {
            +      error("E039");
            +    }
            +    return this;
            +  });
            +
            +  prefix("function", function () {
            +    var generator = false;
            +    if (state.tokens.next.value === "*") {
            +      if (!state.option.inESNext()) {
            +        warning("W119", state.tokens.curr, "function*");
            +      }
            +      advance("*");
            +      generator = true;
            +    }
            +    var i = optionalidentifier();
            +    doFunction(i, undefined, generator);
            +    if (!state.option.loopfunc && funct["(loopage)"]) {
            +      warning("W083");
            +    }
            +    return this;
            +  });
            +
            +  blockstmt("if", function () {
            +    var t = state.tokens.next;
            +    increaseComplexityCount();
            +    state.condition = true;
            +    advance("(");
            +    checkCondAssignment(expression(0));
            +    advance(")", t);
            +    state.condition = false;
            +    block(true, true);
            +    if (state.tokens.next.id === "else") {
            +      advance("else");
            +      if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") {
            +        statement(true);
            +      } else {
            +        block(true, true);
            +      }
            +    }
            +    return this;
            +  });
            +
            +  blockstmt("try", function () {
            +    var b;
            +
            +    function doCatch() {
            +      var oldScope = scope;
            +      var e;
            +
            +      advance("catch");
            +      advance("(");
            +
            +      scope = Object.create(oldScope);
            +
            +      e = state.tokens.next.value;
            +      if (state.tokens.next.type !== "(identifier)") {
            +        e = null;
            +        warning("E030", state.tokens.next, e);
            +      }
            +
            +      advance();
            +
            +      funct = functor("(catch)", state.tokens.next, scope, {
            +        "(context)"  : funct,
            +        "(breakage)" : funct["(breakage)"],
            +        "(loopage)"  : funct["(loopage)"],
            +        "(statement)": false,
            +        "(catch)"    : true
            +      });
            +
            +      if (e) {
            +        addlabel(e, { type: "exception" });
            +      }
            +
            +      if (state.tokens.next.value === "if") {
            +        if (!state.option.inMoz(true)) {
            +          warning("W118", state.tokens.curr, "catch filter");
            +        }
            +        advance("if");
            +        expression(0);
            +      }
            +
            +      advance(")");
            +
            +      state.tokens.curr.funct = funct;
            +      functions.push(funct);
            +
            +      block(false);
            +
            +      scope = oldScope;
            +
            +      funct["(last)"] = state.tokens.curr.line;
            +      funct["(lastcharacter)"] = state.tokens.curr.character;
            +      funct = funct["(context)"];
            +    }
            +
            +    block(true);
            +
            +    while (state.tokens.next.id === "catch") {
            +      increaseComplexityCount();
            +      if (b && (!state.option.inMoz(true))) {
            +        warning("W118", state.tokens.next, "multiple catch blocks");
            +      }
            +      doCatch();
            +      b = true;
            +    }
            +
            +    if (state.tokens.next.id === "finally") {
            +      advance("finally");
            +      block(true);
            +      return;
            +    }
            +
            +    if (!b) {
            +      error("E021", state.tokens.next, "catch", state.tokens.next.value);
            +    }
            +
            +    return this;
            +  });
            +
            +  blockstmt("while", function () {
            +    var t = state.tokens.next;
            +    funct["(breakage)"] += 1;
            +    funct["(loopage)"] += 1;
            +    increaseComplexityCount();
            +    advance("(");
            +    checkCondAssignment(expression(0));
            +    advance(")", t);
            +    block(true, true);
            +    funct["(breakage)"] -= 1;
            +    funct["(loopage)"] -= 1;
            +    return this;
            +  }).labelled = true;
            +
            +  blockstmt("with", function () {
            +    var t = state.tokens.next;
            +    if (state.directive["use strict"]) {
            +      error("E010", state.tokens.curr);
            +    } else if (!state.option.withstmt) {
            +      warning("W085", state.tokens.curr);
            +    }
            +
            +    advance("(");
            +    expression(0);
            +    advance(")", t);
            +    block(true, true);
            +
            +    return this;
            +  });
            +
            +  blockstmt("switch", function () {
            +    var t = state.tokens.next;
            +    var g = false;
            +    var noindent = false;
            +
            +    funct["(breakage)"] += 1;
            +    advance("(");
            +    checkCondAssignment(expression(0));
            +    advance(")", t);
            +    t = state.tokens.next;
            +    advance("{");
            +
            +    if (state.tokens.next.from === indent)
            +      noindent = true;
            +
            +    if (!noindent)
            +      indent += state.option.indent;
            +
            +    this.cases = [];
            +
            +    for (;;) {
            +      switch (state.tokens.next.id) {
            +      case "case":
            +        switch (funct["(verb)"]) {
            +        case "yield":
            +        case "break":
            +        case "case":
            +        case "continue":
            +        case "return":
            +        case "switch":
            +        case "throw":
            +          break;
            +        default:
            +          if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
            +            warning("W086", state.tokens.curr, "case");
            +          }
            +        }
            +
            +        advance("case");
            +        this.cases.push(expression(0));
            +        increaseComplexityCount();
            +        g = true;
            +        advance(":");
            +        funct["(verb)"] = "case";
            +        break;
            +      case "default":
            +        switch (funct["(verb)"]) {
            +        case "yield":
            +        case "break":
            +        case "continue":
            +        case "return":
            +        case "throw":
            +          break;
            +        default:
            +          if (this.cases.length) {
            +            if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) {
            +              warning("W086", state.tokens.curr, "default");
            +            }
            +          }
            +        }
            +
            +        advance("default");
            +        g = true;
            +        advance(":");
            +        break;
            +      case "}":
            +        if (!noindent)
            +          indent -= state.option.indent;
            +
            +        advance("}", t);
            +        funct["(breakage)"] -= 1;
            +        funct["(verb)"] = undefined;
            +        return;
            +      case "(end)":
            +        error("E023", state.tokens.next, "}");
            +        return;
            +      default:
            +        indent += state.option.indent;
            +        if (g) {
            +          switch (state.tokens.curr.id) {
            +          case ",":
            +            error("E040");
            +            return;
            +          case ":":
            +            g = false;
            +            statements();
            +            break;
            +          default:
            +            error("E025", state.tokens.curr);
            +            return;
            +          }
            +        } else {
            +          if (state.tokens.curr.id === ":") {
            +            advance(":");
            +            error("E024", state.tokens.curr, ":");
            +            statements();
            +          } else {
            +            error("E021", state.tokens.next, "case", state.tokens.next.value);
            +            return;
            +          }
            +        }
            +        indent -= state.option.indent;
            +      }
            +    }
            +  }).labelled = true;
            +
            +  stmt("debugger", function () {
            +    if (!state.option.debug) {
            +      warning("W087", this);
            +    }
            +    return this;
            +  }).exps = true;
            +
            +  (function () {
            +    var x = stmt("do", function () {
            +      funct["(breakage)"] += 1;
            +      funct["(loopage)"] += 1;
            +      increaseComplexityCount();
            +
            +      this.first = block(true, true);
            +      advance("while");
            +      var t = state.tokens.next;
            +      advance("(");
            +      checkCondAssignment(expression(0));
            +      advance(")", t);
            +      funct["(breakage)"] -= 1;
            +      funct["(loopage)"] -= 1;
            +      return this;
            +    });
            +    x.labelled = true;
            +    x.exps = true;
            +  }());
            +
            +  blockstmt("for", function () {
            +    var s, t = state.tokens.next;
            +    var letscope = false;
            +    var foreachtok = null;
            +
            +    if (t.value === "each") {
            +      foreachtok = t;
            +      advance("each");
            +      if (!state.option.inMoz(true)) {
            +        warning("W118", state.tokens.curr, "for each");
            +      }
            +    }
            +
            +    funct["(breakage)"] += 1;
            +    funct["(loopage)"] += 1;
            +    increaseComplexityCount();
            +    advance("(");
            +    var nextop; // contains the token of the "in" or "of" operator
            +    var i = 0;
            +    var inof = ["in", "of"];
            +    do {
            +      nextop = peek(i);
            +      ++i;
            +    } while (!_.contains(inof, nextop.value) && nextop.value !== ";" &&
            +          nextop.type !== "(end)");
            +    if (_.contains(inof, nextop.value)) {
            +      if (!state.option.inESNext() && nextop.value === "of") {
            +        error("W104", nextop, "for of");
            +      }
            +
            +      if (state.tokens.next.id === "var") {
            +        advance("var");
            +        state.syntax["var"].fud.call(state.syntax["var"].fud, true);
            +      } else if (state.tokens.next.id === "let") {
            +        advance("let");
            +        letscope = true;
            +        funct["(blockscope)"].stack();
            +        state.syntax["let"].fud.call(state.syntax["let"].fud, true);
            +      } else if (!state.tokens.next.identifier) {
            +        error("E030", state.tokens.next, state.tokens.next.type);
            +        advance();
            +      } else {
            +        switch (funct[state.tokens.next.value]) {
            +        case "unused":
            +          funct[state.tokens.next.value] = "var";
            +          break;
            +        case "var":
            +          break;
            +        default:
            +          if (!funct["(blockscope)"].getlabel(state.tokens.next.value))
            +            warning("W088", state.tokens.next, state.tokens.next.value);
            +        }
            +        advance();
            +      }
            +      advance(nextop.value);
            +      expression(20);
            +      advance(")", t);
            +      s = block(true, true);
            +      if (state.option.forin && s && (s.length > 1 || typeof s[0] !== "object" ||
            +          s[0].value !== "if")) {
            +        warning("W089", this);
            +      }
            +      funct["(breakage)"] -= 1;
            +      funct["(loopage)"] -= 1;
            +    } else {
            +      if (foreachtok) {
            +        error("E045", foreachtok);
            +      }
            +      if (state.tokens.next.id !== ";") {
            +        if (state.tokens.next.id === "var") {
            +          advance("var");
            +          state.syntax["var"].fud.call(state.syntax["var"].fud);
            +        } else if (state.tokens.next.id === "let") {
            +          advance("let");
            +          letscope = true;
            +          funct["(blockscope)"].stack();
            +          state.syntax["let"].fud.call(state.syntax["let"].fud);
            +        } else {
            +          for (;;) {
            +            expression(0, "for");
            +            if (state.tokens.next.id !== ",") {
            +              break;
            +            }
            +            comma();
            +          }
            +        }
            +      }
            +      nolinebreak(state.tokens.curr);
            +      advance(";");
            +      if (state.tokens.next.id !== ";") {
            +        checkCondAssignment(expression(0));
            +      }
            +      nolinebreak(state.tokens.curr);
            +      advance(";");
            +      if (state.tokens.next.id === ";") {
            +        error("E021", state.tokens.next, ")", ";");
            +      }
            +      if (state.tokens.next.id !== ")") {
            +        for (;;) {
            +          expression(0, "for");
            +          if (state.tokens.next.id !== ",") {
            +            break;
            +          }
            +          comma();
            +        }
            +      }
            +      advance(")", t);
            +      block(true, true);
            +      funct["(breakage)"] -= 1;
            +      funct["(loopage)"] -= 1;
            +
            +    }
            +    if (letscope) {
            +      funct["(blockscope)"].unstack();
            +    }
            +    return this;
            +  }).labelled = true;
            +
            +
            +  stmt("break", function () {
            +    var v = state.tokens.next.value;
            +
            +    if (funct["(breakage)"] === 0)
            +      warning("W052", state.tokens.next, this.value);
            +
            +    if (!state.option.asi)
            +      nolinebreak(this);
            +
            +    if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
            +      if (state.tokens.curr.line === state.tokens.next.line) {
            +        if (funct[v] !== "label") {
            +          warning("W090", state.tokens.next, v);
            +        } else if (scope[v] !== funct) {
            +          warning("W091", state.tokens.next, v);
            +        }
            +        this.first = state.tokens.next;
            +        advance();
            +      }
            +    }
            +    reachable("break");
            +    return this;
            +  }).exps = true;
            +
            +
            +  stmt("continue", function () {
            +    var v = state.tokens.next.value;
            +
            +    if (funct["(breakage)"] === 0)
            +      warning("W052", state.tokens.next, this.value);
            +
            +    if (!state.option.asi)
            +      nolinebreak(this);
            +
            +    if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
            +      if (state.tokens.curr.line === state.tokens.next.line) {
            +        if (funct[v] !== "label") {
            +          warning("W090", state.tokens.next, v);
            +        } else if (scope[v] !== funct) {
            +          warning("W091", state.tokens.next, v);
            +        }
            +        this.first = state.tokens.next;
            +        advance();
            +      }
            +    } else if (!funct["(loopage)"]) {
            +      warning("W052", state.tokens.next, this.value);
            +    }
            +    reachable("continue");
            +    return this;
            +  }).exps = true;
            +
            +
            +  stmt("return", function () {
            +    if (this.line === state.tokens.next.line) {
            +      if (state.tokens.next.id !== ";" && !state.tokens.next.reach) {
            +        this.first = expression(0);
            +
            +        if (this.first &&
            +            this.first.type === "(punctuator)" && this.first.value === "=" &&
            +            !this.first.paren && !state.option.boss) {
            +          warningAt("W093", this.first.line, this.first.character);
            +        }
            +      }
            +    } else {
            +      if (state.tokens.next.type === "(punctuator)" &&
            +        ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) {
            +        nolinebreak(this); // always warn (Line breaking error)
            +      }
            +    }
            +    reachable("return");
            +    return this;
            +  }).exps = true;
            +
            +  (function (x) {
            +    x.exps = true;
            +    x.lbp = 25;
            +  }(prefix("yield", function () {
            +    var prev = state.tokens.prev;
            +    if (state.option.inESNext(true) && !funct["(generator)"]) {
            +      if (!("(catch)" === funct["(name)"] && funct["(context)"]["(generator)"])) {
            +        error("E046", state.tokens.curr, "yield");
            +      }
            +    } else if (!state.option.inESNext()) {
            +      warning("W104", state.tokens.curr, "yield");
            +    }
            +    funct["(generator)"] = "yielded";
            +    if (this.line === state.tokens.next.line || !state.option.inMoz(true)) {
            +      if (state.tokens.next.id !== ";" && !state.tokens.next.reach && state.tokens.next.nud) {
            +        nobreaknonadjacent(state.tokens.curr, state.tokens.next);
            +        this.first = expression(10);
            +
            +        if (this.first.type === "(punctuator)" && this.first.value === "=" &&
            +            !this.first.paren && !state.option.boss) {
            +          warningAt("W093", this.first.line, this.first.character);
            +        }
            +      }
            +
            +      if (state.option.inMoz(true) && state.tokens.next.id !== ")" &&
            +          (prev.lbp > 30 || (!prev.assign && !isEndOfExpr()) || prev.id === "yield")) {
            +        error("E050", this);
            +      }
            +    } else if (!state.option.asi) {
            +      nolinebreak(this); // always warn (Line breaking error)
            +    }
            +    return this;
            +  })));
            +
            +
            +  stmt("throw", function () {
            +    nolinebreak(this);
            +    this.first = expression(20);
            +    reachable("throw");
            +    return this;
            +  }).exps = true;
            +
            +  stmt("import", function () {
            +    if (!state.option.inESNext()) {
            +      warning("W119", state.tokens.curr, "import");
            +    }
            +
            +    if (state.tokens.next.type === "(string)") {
            +      advance("(string)");
            +      return this;
            +    }
            +    if (state.tokens.next.identifier) {
            +      this.name = identifier();
            +      addlabel(this.name, { type: "unused", token: state.tokens.curr });
            +    } else {
            +      advance("{");
            +      for (;;) {
            +        if (state.tokens.next.value === "}") {
            +          advance("}");
            +          break;
            +        }
            +        var importName;
            +        if (state.tokens.next.type === "default") {
            +          importName = "default";
            +          advance("default");
            +        } else {
            +          importName = identifier();
            +        }
            +        if (state.tokens.next.value === "as") {
            +          advance("as");
            +          importName = identifier();
            +        }
            +        addlabel(importName, { type: "unused", token: state.tokens.curr });
            +
            +        if (state.tokens.next.value === ",") {
            +          advance(",");
            +        } else if (state.tokens.next.value === "}") {
            +          advance("}");
            +          break;
            +        } else {
            +          error("E024", state.tokens.next, state.tokens.next.value);
            +          break;
            +        }
            +      }
            +    }
            +
            +    advance("from");
            +    advance("(string)");
            +    return this;
            +  }).exps = true;
            +
            +  stmt("export", function () {
            +    if (!state.option.inESNext()) {
            +      warning("W119", state.tokens.curr, "export");
            +    }
            +
            +    if (state.tokens.next.type === "default") {
            +      advance("default");
            +      if (state.tokens.next.id === "function" || state.tokens.next.id === "class") {
            +        this.block = true;
            +      }
            +      this.exportee = expression(10);
            +
            +      return this;
            +    }
            +
            +    if (state.tokens.next.value === "{") {
            +      advance("{");
            +      for (;;) {
            +        exported[identifier()] = true;
            +
            +        if (state.tokens.next.value === ",") {
            +          advance(",");
            +        } else if (state.tokens.next.value === "}") {
            +          advance("}");
            +          break;
            +        } else {
            +          error("E024", state.tokens.next, state.tokens.next.value);
            +          break;
            +        }
            +      }
            +      return this;
            +    }
            +
            +    if (state.tokens.next.id === "var") {
            +      advance("var");
            +      exported[state.tokens.next.value] = true;
            +      state.syntax["var"].fud.call(state.syntax["var"].fud);
            +    } else if (state.tokens.next.id === "let") {
            +      advance("let");
            +      exported[state.tokens.next.value] = true;
            +      state.syntax["let"].fud.call(state.syntax["let"].fud);
            +    } else if (state.tokens.next.id === "const") {
            +      advance("const");
            +      exported[state.tokens.next.value] = true;
            +      state.syntax["const"].fud.call(state.syntax["const"].fud);
            +    } else if (state.tokens.next.id === "function") {
            +      this.block = true;
            +      advance("function");
            +      exported[state.tokens.next.value] = true;
            +      state.syntax["function"].fud();
            +    } else if (state.tokens.next.id === "class") {
            +      this.block = true;
            +      advance("class");
            +      exported[state.tokens.next.value] = true;
            +      state.syntax["class"].fud();
            +    } else {
            +      error("E024", state.tokens.next, state.tokens.next.value);
            +    }
            +
            +    return this;
            +  }).exps = true;
            +
            +  FutureReservedWord("abstract");
            +  FutureReservedWord("boolean");
            +  FutureReservedWord("byte");
            +  FutureReservedWord("char");
            +  FutureReservedWord("class", { es5: true, nud: classdef });
            +  FutureReservedWord("double");
            +  FutureReservedWord("enum", { es5: true });
            +  FutureReservedWord("export", { es5: true });
            +  FutureReservedWord("extends", { es5: true });
            +  FutureReservedWord("final");
            +  FutureReservedWord("float");
            +  FutureReservedWord("goto");
            +  FutureReservedWord("implements", { es5: true, strictOnly: true });
            +  FutureReservedWord("import", { es5: true });
            +  FutureReservedWord("int");
            +  FutureReservedWord("interface", { es5: true, strictOnly: true });
            +  FutureReservedWord("long");
            +  FutureReservedWord("native");
            +  FutureReservedWord("package", { es5: true, strictOnly: true });
            +  FutureReservedWord("private", { es5: true, strictOnly: true });
            +  FutureReservedWord("protected", { es5: true, strictOnly: true });
            +  FutureReservedWord("public", { es5: true, strictOnly: true });
            +  FutureReservedWord("short");
            +  FutureReservedWord("static", { es5: true, strictOnly: true });
            +  FutureReservedWord("super", { es5: true });
            +  FutureReservedWord("synchronized");
            +  FutureReservedWord("throws");
            +  FutureReservedWord("transient");
            +  FutureReservedWord("volatile");
            +
            +  var lookupBlockType = function () {
            +    var pn, pn1;
            +    var i = -1;
            +    var bracketStack = 0;
            +    var ret = {};
            +    if (_.contains(["[", "{"], state.tokens.curr.value))
            +      bracketStack += 1;
            +    do {
            +      pn = (i === -1) ? state.tokens.next : peek(i);
            +      pn1 = peek(i + 1);
            +      i = i + 1;
            +      if (_.contains(["[", "{"], pn.value)) {
            +        bracketStack += 1;
            +      } else if (_.contains(["]", "}"], pn.value)) {
            +        bracketStack -= 1;
            +      }
            +      if (pn.identifier && pn.value === "for" && bracketStack === 1) {
            +        ret.isCompArray = true;
            +        ret.notJson = true;
            +        break;
            +      }
            +      if (_.contains(["}", "]"], pn.value) && pn1.value === "=" && bracketStack === 0) {
            +        ret.isDestAssign = true;
            +        ret.notJson = true;
            +        break;
            +      }
            +      if (pn.value === ";") {
            +        ret.isBlock = true;
            +        ret.notJson = true;
            +      }
            +    } while (bracketStack > 0 && pn.id !== "(end)" && i < 15);
            +    return ret;
            +  };
            +  function destructuringAssignOrJsonValue() {
            +
            +    var block = lookupBlockType();
            +    if (block.notJson) {
            +      if (!state.option.inESNext() && block.isDestAssign) {
            +        warning("W104", state.tokens.curr, "destructuring assignment");
            +      }
            +      statements();
            +    } else {
            +      state.option.laxbreak = true;
            +      state.jsonMode = true;
            +      jsonValue();
            +    }
            +  }
            +
            +  var arrayComprehension = function () {
            +    var CompArray = function () {
            +      this.mode = "use";
            +      this.variables = [];
            +    };
            +    var _carrays = [];
            +    var _current;
            +    function declare(v) {
            +      var l = _current.variables.filter(function (elt) {
            +        if (elt.value === v) {
            +          elt.undef = false;
            +          return v;
            +        }
            +      }).length;
            +      return l !== 0;
            +    }
            +    function use(v) {
            +      var l = _current.variables.filter(function (elt) {
            +        if (elt.value === v && !elt.undef) {
            +          if (elt.unused === true) {
            +            elt.unused = false;
            +          }
            +          return v;
            +        }
            +      }).length;
            +      return (l === 0);
            +    }
            +    return {stack: function () {
            +          _current = new CompArray();
            +          _carrays.push(_current);
            +        },
            +        unstack: function () {
            +          _current.variables.filter(function (v) {
            +            if (v.unused)
            +              warning("W098", v.token, v.value);
            +            if (v.undef)
            +              isundef(v.funct, "W117", v.token, v.value);
            +          });
            +          _carrays.splice(-1, 1);
            +          _current = _carrays[_carrays.length - 1];
            +        },
            +        setState: function (s) {
            +          if (_.contains(["use", "define", "generate", "filter"], s))
            +            _current.mode = s;
            +        },
            +        check: function (v) {
            +          if (!_current) {
            +            return;
            +          }
            +          if (_current && _current.mode === "use") {
            +            if (use(v)) {
            +              _current.variables.push({
            +                funct: funct,
            +                token: state.tokens.curr,
            +                value: v,
            +                undef: true,
            +                unused: false
            +              });
            +            }
            +            return true;
            +          } else if (_current && _current.mode === "define") {
            +            if (!declare(v)) {
            +              _current.variables.push({
            +                funct: funct,
            +                token: state.tokens.curr,
            +                value: v,
            +                undef: false,
            +                unused: true
            +              });
            +            }
            +            return true;
            +          } else if (_current && _current.mode === "generate") {
            +            isundef(funct, "W117", state.tokens.curr, v);
            +            return true;
            +          } else if (_current && _current.mode === "filter") {
            +            if (use(v)) {
            +              isundef(funct, "W117", state.tokens.curr, v);
            +            }
            +            return true;
            +          }
            +          return false;
            +        }
            +        };
            +  };
            +
            +  function jsonValue() {
            +    function jsonObject() {
            +      var o = {}, t = state.tokens.next;
            +      advance("{");
            +      if (state.tokens.next.id !== "}") {
            +        for (;;) {
            +          if (state.tokens.next.id === "(end)") {
            +            error("E026", state.tokens.next, t.line);
            +          } else if (state.tokens.next.id === "}") {
            +            warning("W094", state.tokens.curr);
            +            break;
            +          } else if (state.tokens.next.id === ",") {
            +            error("E028", state.tokens.next);
            +          } else if (state.tokens.next.id !== "(string)") {
            +            warning("W095", state.tokens.next, state.tokens.next.value);
            +          }
            +          if (o[state.tokens.next.value] === true) {
            +            warning("W075", state.tokens.next, state.tokens.next.value);
            +          } else if ((state.tokens.next.value === "__proto__" &&
            +            !state.option.proto) || (state.tokens.next.value === "__iterator__" &&
            +            !state.option.iterator)) {
            +            warning("W096", state.tokens.next, state.tokens.next.value);
            +          } else {
            +            o[state.tokens.next.value] = true;
            +          }
            +          advance();
            +          advance(":");
            +          jsonValue();
            +          if (state.tokens.next.id !== ",") {
            +            break;
            +          }
            +          advance(",");
            +        }
            +      }
            +      advance("}");
            +    }
            +
            +    function jsonArray() {
            +      var t = state.tokens.next;
            +      advance("[");
            +      if (state.tokens.next.id !== "]") {
            +        for (;;) {
            +          if (state.tokens.next.id === "(end)") {
            +            error("E027", state.tokens.next, t.line);
            +          } else if (state.tokens.next.id === "]") {
            +            warning("W094", state.tokens.curr);
            +            break;
            +          } else if (state.tokens.next.id === ",") {
            +            error("E028", state.tokens.next);
            +          }
            +          jsonValue();
            +          if (state.tokens.next.id !== ",") {
            +            break;
            +          }
            +          advance(",");
            +        }
            +      }
            +      advance("]");
            +    }
            +
            +    switch (state.tokens.next.id) {
            +    case "{":
            +      jsonObject();
            +      break;
            +    case "[":
            +      jsonArray();
            +      break;
            +    case "true":
            +    case "false":
            +    case "null":
            +    case "(number)":
            +    case "(string)":
            +      advance();
            +      break;
            +    case "-":
            +      advance("-");
            +      advance("(number)");
            +      break;
            +    default:
            +      error("E003", state.tokens.next);
            +    }
            +  }
            +
            +  var blockScope = function () {
            +    var _current = {};
            +    var _variables = [_current];
            +
            +    function _checkBlockLabels() {
            +      for (var t in _current) {
            +        if (_current[t]["(type)"] === "unused") {
            +          if (state.option.unused) {
            +            var tkn = _current[t]["(token)"];
            +            var line = tkn.line;
            +            var chr  = tkn.character;
            +            warningAt("W098", line, chr, t);
            +          }
            +        }
            +      }
            +    }
            +
            +    return {
            +      stack: function () {
            +        _current = {};
            +        _variables.push(_current);
            +      },
            +
            +      unstack: function () {
            +        _checkBlockLabels();
            +        _variables.splice(_variables.length - 1, 1);
            +        _current = _.last(_variables);
            +      },
            +
            +      getlabel: function (l) {
            +        for (var i = _variables.length - 1 ; i >= 0; --i) {
            +          if (_.has(_variables[i], l) && !_variables[i][l]["(shadowed)"]) {
            +            return _variables[i];
            +          }
            +        }
            +      },
            +
            +      shadow: function (name) {
            +        for (var i = _variables.length - 1; i >= 0; i--) {
            +          if (_.has(_variables[i], name)) {
            +            _variables[i][name]["(shadowed)"] = true;
            +          }
            +        }
            +      },
            +
            +      unshadow: function (name) {
            +        for (var i = _variables.length - 1; i >= 0; i--) {
            +          if (_.has(_variables[i], name)) {
            +            _variables[i][name]["(shadowed)"] = false;
            +          }
            +        }
            +      },
            +
            +      current: {
            +        has: function (t) {
            +          return _.has(_current, t);
            +        },
            +
            +        add: function (t, type, tok) {
            +          _current[t] = { "(type)" : type, "(token)": tok, "(shadowed)": false };
            +        }
            +      }
            +    };
            +  };
            +  var itself = function (s, o, g) {
            +    var i, k, x;
            +    var optionKeys;
            +    var newOptionObj = {};
            +    var newIgnoredObj = {};
            +
            +    o = _.clone(o);
            +    state.reset();
            +
            +    if (o && o.scope) {
            +      JSHINT.scope = o.scope;
            +    } else {
            +      JSHINT.errors = [];
            +      JSHINT.undefs = [];
            +      JSHINT.internals = [];
            +      JSHINT.blacklist = {};
            +      JSHINT.scope = "(main)";
            +    }
            +
            +    predefined = Object.create(null);
            +    combine(predefined, vars.ecmaIdentifiers);
            +    combine(predefined, vars.reservedVars);
            +
            +    combine(predefined, g || {});
            +
            +    declared = Object.create(null);
            +    exported = Object.create(null);
            +
            +    function each(obj, cb) {
            +      if (!obj)
            +        return;
            +
            +      if (!Array.isArray(obj) && typeof obj === "object")
            +        obj = Object.keys(obj);
            +
            +      obj.forEach(cb);
            +    }
            +
            +    if (o) {
            +      each(o.predef || null, function (item) {
            +        var slice, prop;
            +
            +        if (item[0] === "-") {
            +          slice = item.slice(1);
            +          JSHINT.blacklist[slice] = slice;
            +        } else {
            +          prop = Object.getOwnPropertyDescriptor(o.predef, item);
            +          predefined[item] = prop ? prop.value : false;
            +        }
            +      });
            +
            +      each(o.exported || null, function (item) {
            +        exported[item] = true;
            +      });
            +
            +      delete o.predef;
            +      delete o.exported;
            +
            +      optionKeys = Object.keys(o);
            +      for (x = 0; x < optionKeys.length; x++) {
            +        if (/^-W\d{3}$/g.test(optionKeys[x])) {
            +          newIgnoredObj[optionKeys[x].slice(1)] = true;
            +        } else {
            +          newOptionObj[optionKeys[x]] = o[optionKeys[x]];
            +
            +          if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false)
            +            newOptionObj["(explicitNewcap)"] = true;
            +        }
            +      }
            +    }
            +
            +    state.option = newOptionObj;
            +    state.ignored = newIgnoredObj;
            +
            +    state.option.indent = state.option.indent || 4;
            +    state.option.maxerr = state.option.maxerr || 50;
            +
            +    indent = 1;
            +    global = Object.create(predefined);
            +    scope = global;
            +
            +    funct = functor("(global)", null, scope, {
            +      "(global)"    : true,
            +      "(blockscope)": blockScope(),
            +      "(comparray)" : arrayComprehension(),
            +      "(metrics)"   : createMetrics(state.tokens.next)
            +    });
            +
            +    functions = [funct];
            +    urls = [];
            +    stack = null;
            +    member = {};
            +    membersOnly = null;
            +    implied = {};
            +    inblock = false;
            +    lookahead = [];
            +    unuseds = [];
            +
            +    if (!isString(s) && !Array.isArray(s)) {
            +      errorAt("E004", 0);
            +      return false;
            +    }
            +
            +    api = {
            +      get isJSON() {
            +        return state.jsonMode;
            +      },
            +
            +      getOption: function (name) {
            +        return state.option[name] || null;
            +      },
            +
            +      getCache: function (name) {
            +        return state.cache[name];
            +      },
            +
            +      setCache: function (name, value) {
            +        state.cache[name] = value;
            +      },
            +
            +      warn: function (code, data) {
            +        warningAt.apply(null, [ code, data.line, data.char ].concat(data.data));
            +      },
            +
            +      on: function (names, listener) {
            +        names.split(" ").forEach(function (name) {
            +          emitter.on(name, listener);
            +        }.bind(this));
            +      }
            +    };
            +
            +    emitter.removeAllListeners();
            +    (extraModules || []).forEach(function (func) {
            +      func(api);
            +    });
            +
            +    state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"];
            +
            +    lex = new Lexer(s);
            +
            +    lex.on("warning", function (ev) {
            +      warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data));
            +    });
            +
            +    lex.on("error", function (ev) {
            +      errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data));
            +    });
            +
            +    lex.on("fatal", function (ev) {
            +      quit("E041", ev.line, ev.from);
            +    });
            +
            +    lex.on("Identifier", function (ev) {
            +      emitter.emit("Identifier", ev);
            +    });
            +
            +    lex.on("String", function (ev) {
            +      emitter.emit("String", ev);
            +    });
            +
            +    lex.on("Number", function (ev) {
            +      emitter.emit("Number", ev);
            +    });
            +
            +    lex.start();
            +    for (var name in o) {
            +      if (_.has(o, name)) {
            +        checkOption(name, state.tokens.curr);
            +      }
            +    }
            +
            +    assume();
            +    combine(predefined, g || {});
            +    comma.first = true;
            +
            +    try {
            +      advance();
            +      switch (state.tokens.next.id) {
            +      case "{":
            +      case "[":
            +        destructuringAssignOrJsonValue();
            +        break;
            +      default:
            +        directives();
            +
            +        if (state.directive["use strict"]) {
            +          if (!state.option.globalstrict && !(state.option.node || state.option.phantom)) {
            +            warning("W097", state.tokens.prev);
            +          }
            +        }
            +
            +        statements();
            +      }
            +      advance((state.tokens.next && state.tokens.next.value !== ".")  ? "(end)" : undefined);
            +      funct["(blockscope)"].unstack();
            +
            +      var markDefined = function (name, context) {
            +        do {
            +          if (typeof context[name] === "string") {
            +
            +            if (context[name] === "unused")
            +              context[name] = "var";
            +            else if (context[name] === "unction")
            +              context[name] = "closure";
            +
            +            return true;
            +          }
            +
            +          context = context["(context)"];
            +        } while (context);
            +
            +        return false;
            +      };
            +
            +      var clearImplied = function (name, line) {
            +        if (!implied[name])
            +          return;
            +
            +        var newImplied = [];
            +        for (var i = 0; i < implied[name].length; i += 1) {
            +          if (implied[name][i] !== line)
            +            newImplied.push(implied[name][i]);
            +        }
            +
            +        if (newImplied.length === 0)
            +          delete implied[name];
            +        else
            +          implied[name] = newImplied;
            +      };
            +
            +      var warnUnused = function (name, tkn, type, unused_opt) {
            +        var line = tkn.line;
            +        var chr  = tkn.character;
            +
            +        if (unused_opt === undefined) {
            +          unused_opt = state.option.unused;
            +        }
            +
            +        if (unused_opt === true) {
            +          unused_opt = "last-param";
            +        }
            +
            +        var warnable_types = {
            +          "vars": ["var"],
            +          "last-param": ["var", "param"],
            +          "strict": ["var", "param", "last-param"]
            +        };
            +
            +        if (unused_opt) {
            +          if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) {
            +            warningAt("W098", line, chr, name);
            +          }
            +        }
            +
            +        unuseds.push({
            +          name: name,
            +          line: line,
            +          character: chr
            +        });
            +      };
            +
            +      var checkUnused = function (func, key) {
            +        var type = func[key];
            +        var tkn = func["(tokens)"][key];
            +
            +        if (key.charAt(0) === "(")
            +          return;
            +
            +        if (type !== "unused" && type !== "unction" && type !== "const")
            +          return;
            +        if (func["(params)"] && func["(params)"].indexOf(key) !== -1)
            +          return;
            +        if (func["(global)"] && _.has(exported, key))
            +          return;
            +        if (type === "const" && !getprop(func, key, "unused"))
            +          return;
            +
            +        warnUnused(key, tkn, "var");
            +      };
            +      for (i = 0; i < JSHINT.undefs.length; i += 1) {
            +        k = JSHINT.undefs[i].slice(0);
            +
            +        if (markDefined(k[2].value, k[0])) {
            +          clearImplied(k[2].value, k[2].line);
            +        } else if (state.option.undef) {
            +          warning.apply(warning, k.slice(1));
            +        }
            +      }
            +
            +      functions.forEach(function (func) {
            +        if (func["(unusedOption)"] === false) {
            +          return;
            +        }
            +
            +        for (var key in func) {
            +          if (_.has(func, key)) {
            +            checkUnused(func, key);
            +          }
            +        }
            +
            +        if (!func["(params)"])
            +          return;
            +
            +        var params = func["(params)"].slice();
            +        var param  = params.pop();
            +        var type, unused_opt;
            +
            +        while (param) {
            +          type = func[param];
            +          unused_opt = func["(unusedOption)"] || state.option.unused;
            +          unused_opt = unused_opt === true ? "last-param" : unused_opt;
            +
            +          if (param === "undefined")
            +            return;
            +
            +          if (type === "unused" || type === "unction") {
            +            warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]);
            +          } else if (unused_opt === "last-param") {
            +            return;
            +          }
            +
            +          param = params.pop();
            +        }
            +      });
            +
            +      for (var key in declared) {
            +        if (_.has(declared, key) && !_.has(global, key) && !_.has(exported, key)) {
            +          warnUnused(key, declared[key], "var");
            +        }
            +      }
            +
            +    } catch (err) {
            +      if (err && err.name === "JSHintError") {
            +        var nt = state.tokens.next || {};
            +        JSHINT.errors.push({
            +          scope     : "(main)",
            +          raw       : err.raw,
            +          code      : err.code,
            +          reason    : err.message,
            +          line      : err.line || nt.line,
            +          character : err.character || nt.from
            +        }, null);
            +      } else {
            +        throw err;
            +      }
            +    }
            +
            +    if (JSHINT.scope === "(main)") {
            +      o = o || {};
            +
            +      for (i = 0; i < JSHINT.internals.length; i += 1) {
            +        k = JSHINT.internals[i];
            +        o.scope = k.elem;
            +        itself(k.value, o, g);
            +      }
            +    }
            +
            +    return JSHINT.errors.length === 0;
            +  };
            +  itself.addModule = function (func) {
            +    extraModules.push(func);
            +  };
            +
            +  itself.addModule(style.register);
            +  itself.data = function () {
            +    var data = {
            +      functions: [],
            +      options: state.option
            +    };
            +
            +    var implieds = [];
            +    var members = [];
            +    var fu, f, i, j, n, globals;
            +
            +    if (itself.errors.length) {
            +      data.errors = itself.errors;
            +    }
            +
            +    if (state.jsonMode) {
            +      data.json = true;
            +    }
            +
            +    for (n in implied) {
            +      if (_.has(implied, n)) {
            +        implieds.push({
            +          name: n,
            +          line: implied[n]
            +        });
            +      }
            +    }
            +
            +    if (implieds.length > 0) {
            +      data.implieds = implieds;
            +    }
            +
            +    if (urls.length > 0) {
            +      data.urls = urls;
            +    }
            +
            +    globals = Object.keys(scope);
            +    if (globals.length > 0) {
            +      data.globals = globals;
            +    }
            +
            +    for (i = 1; i < functions.length; i += 1) {
            +      f = functions[i];
            +      fu = {};
            +
            +      for (j = 0; j < functionicity.length; j += 1) {
            +        fu[functionicity[j]] = [];
            +      }
            +
            +      for (j = 0; j < functionicity.length; j += 1) {
            +        if (fu[functionicity[j]].length === 0) {
            +          delete fu[functionicity[j]];
            +        }
            +      }
            +
            +      fu.name = f["(name)"];
            +      fu.param = f["(params)"];
            +      fu.line = f["(line)"];
            +      fu.character = f["(character)"];
            +      fu.last = f["(last)"];
            +      fu.lastcharacter = f["(lastcharacter)"];
            +
            +      fu.metrics = {
            +        complexity: f["(metrics)"].ComplexityCount,
            +        parameters: (f["(params)"] || []).length,
            +        statements: f["(metrics)"].statementCount
            +      };
            +
            +      data.functions.push(fu);
            +    }
            +
            +    if (unuseds.length > 0) {
            +      data.unused = unuseds;
            +    }
            +
            +    members = [];
            +    for (n in member) {
            +      if (typeof member[n] === "number") {
            +        data.member = member;
            +        break;
            +      }
            +    }
            +
            +    return data;
            +  };
            +
            +  itself.jshint = itself;
            +
            +  return itself;
            +}());
            +if (typeof exports === "object" && exports) {
            +  exports.JSHINT = JSHINT;
            +}
            +
            +},
            +{"./lex.js":4,"./messages.js":5,"./reg.js":6,"./state.js":7,"./style.js":8,"./vars.js":9,"events":10,"underscore":2}],
            +4:[function(_dereq_,module,exports){
            +
            +
            +
            +var _      = _dereq_("underscore");
            +var events = _dereq_("events");
            +var reg    = _dereq_("./reg.js");
            +var state  = _dereq_("./state.js").state;
            +
            +var unicodeData = _dereq_("../data/ascii-identifier-data.js");
            +var asciiIdentifierStartTable = unicodeData.asciiIdentifierStartTable;
            +var asciiIdentifierPartTable = unicodeData.asciiIdentifierPartTable;
            +
            +var Token = {
            +  Identifier: 1,
            +  Punctuator: 2,
            +  NumericLiteral: 3,
            +  StringLiteral: 4,
            +  Comment: 5,
            +  Keyword: 6,
            +  NullLiteral: 7,
            +  BooleanLiteral: 8,
            +  RegExp: 9,
            +  TemplateLiteral: 10
            +};
            +
            +function asyncTrigger() {
            +  var _checks = [];
            +
            +  return {
            +    push: function (fn) {
            +      _checks.push(fn);
            +    },
            +
            +    check: function () {
            +      for (var check = 0; check < _checks.length; ++check) {
            +        _checks[check]();
            +      }
            +
            +      _checks.splice(0, _checks.length);
            +    }
            +  };
            +}
            +function Lexer(source) {
            +  var lines = source;
            +
            +  if (typeof lines === "string") {
            +    lines = lines
            +      .replace(/\r\n/g, "\n")
            +      .replace(/\r/g, "\n")
            +      .split("\n");
            +  }
            +
            +  if (lines[0] && lines[0].substr(0, 2) === "#!") {
            +    if (lines[0].indexOf("node") !== -1) {
            +      state.option.node = true;
            +    }
            +    lines[0] = "";
            +  }
            +
            +  this.emitter = new events.EventEmitter();
            +  this.source = source;
            +  this.setLines(lines);
            +  this.prereg = true;
            +
            +  this.line = 0;
            +  this.char = 1;
            +  this.from = 1;
            +  this.input = "";
            +  this.inComment = false;
            +
            +  for (var i = 0; i < state.option.indent; i += 1) {
            +    state.tab += " ";
            +  }
            +}
            +
            +Lexer.prototype = {
            +  _lines: [],
            +
            +  getLines: function () {
            +    this._lines = state.lines;
            +    return this._lines;
            +  },
            +
            +  setLines: function (val) {
            +    this._lines = val;
            +    state.lines = this._lines;
            +  },
            +  peek: function (i) {
            +    return this.input.charAt(i || 0);
            +  },
            +  skip: function (i) {
            +    i = i || 1;
            +    this.char += i;
            +    this.input = this.input.slice(i);
            +  },
            +  on: function (names, listener) {
            +    names.split(" ").forEach(function (name) {
            +      this.emitter.on(name, listener);
            +    }.bind(this));
            +  },
            +  trigger: function () {
            +    this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments));
            +  },
            +  triggerAsync: function (type, args, checks, fn) {
            +    checks.push(function () {
            +      if (fn()) {
            +        this.trigger(type, args);
            +      }
            +    }.bind(this));
            +  },
            +  scanPunctuator: function () {
            +    var ch1 = this.peek();
            +    var ch2, ch3, ch4;
            +
            +    switch (ch1) {
            +    case ".":
            +      if ((/^[0-9]$/).test(this.peek(1))) {
            +        return null;
            +      }
            +      if (this.peek(1) === "." && this.peek(2) === ".") {
            +        return {
            +          type: Token.Punctuator,
            +          value: "..."
            +        };
            +      }
            +    case "(":
            +    case ")":
            +    case ";":
            +    case ",":
            +    case "{":
            +    case "}":
            +    case "[":
            +    case "]":
            +    case ":":
            +    case "~":
            +    case "?":
            +      return {
            +        type: Token.Punctuator,
            +        value: ch1
            +      };
            +    case "#":
            +      return {
            +        type: Token.Punctuator,
            +        value: ch1
            +      };
            +    case "":
            +      return null;
            +    }
            +
            +    ch2 = this.peek(1);
            +    ch3 = this.peek(2);
            +    ch4 = this.peek(3);
            +
            +    if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") {
            +      return {
            +        type: Token.Punctuator,
            +        value: ">>>="
            +      };
            +    }
            +
            +    if (ch1 === "=" && ch2 === "=" && ch3 === "=") {
            +      return {
            +        type: Token.Punctuator,
            +        value: "==="
            +      };
            +    }
            +
            +    if (ch1 === "!" && ch2 === "=" && ch3 === "=") {
            +      return {
            +        type: Token.Punctuator,
            +        value: "!=="
            +      };
            +    }
            +
            +    if (ch1 === ">" && ch2 === ">" && ch3 === ">") {
            +      return {
            +        type: Token.Punctuator,
            +        value: ">>>"
            +      };
            +    }
            +
            +    if (ch1 === "<" && ch2 === "<" && ch3 === "=") {
            +      return {
            +        type: Token.Punctuator,
            +        value: "<<="
            +      };
            +    }
            +
            +    if (ch1 === ">" && ch2 === ">" && ch3 === "=") {
            +      return {
            +        type: Token.Punctuator,
            +        value: ">>="
            +      };
            +    }
            +    if (ch1 === "=" && ch2 === ">") {
            +      return {
            +        type: Token.Punctuator,
            +        value: ch1 + ch2
            +      };
            +    }
            +    if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) {
            +      return {
            +        type: Token.Punctuator,
            +        value: ch1 + ch2
            +      };
            +    }
            +
            +    if ("<>=!+-*%&|^".indexOf(ch1) >= 0) {
            +      if (ch2 === "=") {
            +        return {
            +          type: Token.Punctuator,
            +          value: ch1 + ch2
            +        };
            +      }
            +
            +      return {
            +        type: Token.Punctuator,
            +        value: ch1
            +      };
            +    }
            +
            +    if (ch1 === "/") {
            +      if (ch2 === "=" && /\/=(?!(\S*\/[gim]?))/.test(this.input)) {
            +        return {
            +          type: Token.Punctuator,
            +          value: "/="
            +        };
            +      }
            +
            +      return {
            +        type: Token.Punctuator,
            +        value: "/"
            +      };
            +    }
            +
            +    return null;
            +  },
            +  scanComments: function () {
            +    var ch1 = this.peek();
            +    var ch2 = this.peek(1);
            +    var rest = this.input.substr(2);
            +    var startLine = this.line;
            +    var startChar = this.char;
            +
            +    function commentToken(label, body, opt) {
            +      var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"];
            +      var isSpecial = false;
            +      var value = label + body;
            +      var commentType = "plain";
            +      opt = opt || {};
            +
            +      if (opt.isMultiline) {
            +        value += "*/";
            +      }
            +
            +      special.forEach(function (str) {
            +        if (isSpecial) {
            +          return;
            +        }
            +        if (label === "//" && str !== "jshint") {
            +          return;
            +        }
            +
            +        if (body.substr(0, str.length) === str) {
            +          isSpecial = true;
            +          label = label + str;
            +          body = body.substr(str.length);
            +        }
            +
            +        if (!isSpecial && body.charAt(0) === " " && body.substr(1, str.length) === str) {
            +          isSpecial = true;
            +          label = label + " " + str;
            +          body = body.substr(str.length + 1);
            +        }
            +
            +        if (!isSpecial) {
            +          return;
            +        }
            +
            +        switch (str) {
            +        case "member":
            +          commentType = "members";
            +          break;
            +        case "global":
            +          commentType = "globals";
            +          break;
            +        default:
            +          commentType = str;
            +        }
            +      });
            +
            +      return {
            +        type: Token.Comment,
            +        commentType: commentType,
            +        value: value,
            +        body: body,
            +        isSpecial: isSpecial,
            +        isMultiline: opt.isMultiline || false,
            +        isMalformed: opt.isMalformed || false
            +      };
            +    }
            +    if (ch1 === "*" && ch2 === "/") {
            +      this.trigger("error", {
            +        code: "E018",
            +        line: startLine,
            +        character: startChar
            +      });
            +
            +      this.skip(2);
            +      return null;
            +    }
            +    if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) {
            +      return null;
            +    }
            +    if (ch2 === "/") {
            +      this.skip(this.input.length); // Skip to the EOL.
            +      return commentToken("//", rest);
            +    }
            +
            +    var body = "";
            +    if (ch2 === "*") {
            +      this.inComment = true;
            +      this.skip(2);
            +
            +      while (this.peek() !== "*" || this.peek(1) !== "/") {
            +        if (this.peek() === "") { // End of Line
            +          body += "\n";
            +          if (!this.nextLine()) {
            +            this.trigger("error", {
            +              code: "E017",
            +              line: startLine,
            +              character: startChar
            +            });
            +
            +            this.inComment = false;
            +            return commentToken("/*", body, {
            +              isMultiline: true,
            +              isMalformed: true
            +            });
            +          }
            +        } else {
            +          body += this.peek();
            +          this.skip();
            +        }
            +      }
            +
            +      this.skip(2);
            +      this.inComment = false;
            +      return commentToken("/*", body, { isMultiline: true });
            +    }
            +  },
            +  scanKeyword: function () {
            +    var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input);
            +    var keywords = [
            +      "if", "in", "do", "var", "for", "new",
            +      "try", "let", "this", "else", "case",
            +      "void", "with", "enum", "while", "break",
            +      "catch", "throw", "const", "yield", "class",
            +      "super", "return", "typeof", "delete",
            +      "switch", "export", "import", "default",
            +      "finally", "extends", "function", "continue",
            +      "debugger", "instanceof"
            +    ];
            +
            +    if (result && keywords.indexOf(result[0]) >= 0) {
            +      return {
            +        type: Token.Keyword,
            +        value: result[0]
            +      };
            +    }
            +
            +    return null;
            +  },
            +  scanIdentifier: function () {
            +    var id = "";
            +    var index = 0;
            +    var type, char;
            +
            +    function isNonAsciiIdentifierStart(code) {
            +      return code > 256;
            +    }
            +
            +    function isNonAsciiIdentifierPart(code) {
            +      return code > 256;
            +    }
            +
            +    function isHexDigit(str) {
            +      return (/^[0-9a-fA-F]$/).test(str);
            +    }
            +
            +    var readUnicodeEscapeSequence = function () {
            +      index += 1;
            +
            +      if (this.peek(index) !== "u") {
            +        return null;
            +      }
            +
            +      var ch1 = this.peek(index + 1);
            +      var ch2 = this.peek(index + 2);
            +      var ch3 = this.peek(index + 3);
            +      var ch4 = this.peek(index + 4);
            +      var code;
            +
            +      if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) {
            +        code = parseInt(ch1 + ch2 + ch3 + ch4, 16);
            +
            +        if (asciiIdentifierPartTable[code] || isNonAsciiIdentifierPart(code)) {
            +          index += 5;
            +          return "\\u" + ch1 + ch2 + ch3 + ch4;
            +        }
            +
            +        return null;
            +      }
            +
            +      return null;
            +    }.bind(this);
            +
            +    var getIdentifierStart = function () {
            +      var chr = this.peek(index);
            +      var code = chr.charCodeAt(0);
            +
            +      if (code === 92) {
            +        return readUnicodeEscapeSequence();
            +      }
            +
            +      if (code < 128) {
            +        if (asciiIdentifierStartTable[code]) {
            +          index += 1;
            +          return chr;
            +        }
            +
            +        return null;
            +      }
            +
            +      if (isNonAsciiIdentifierStart(code)) {
            +        index += 1;
            +        return chr;
            +      }
            +
            +      return null;
            +    }.bind(this);
            +
            +    var getIdentifierPart = function () {
            +      var chr = this.peek(index);
            +      var code = chr.charCodeAt(0);
            +
            +      if (code === 92) {
            +        return readUnicodeEscapeSequence();
            +      }
            +
            +      if (code < 128) {
            +        if (asciiIdentifierPartTable[code]) {
            +          index += 1;
            +          return chr;
            +        }
            +
            +        return null;
            +      }
            +
            +      if (isNonAsciiIdentifierPart(code)) {
            +        index += 1;
            +        return chr;
            +      }
            +
            +      return null;
            +    }.bind(this);
            +
            +    char = getIdentifierStart();
            +    if (char === null) {
            +      return null;
            +    }
            +
            +    id = char;
            +    for (;;) {
            +      char = getIdentifierPart();
            +
            +      if (char === null) {
            +        break;
            +      }
            +
            +      id += char;
            +    }
            +
            +    switch (id) {
            +    case "true":
            +    case "false":
            +      type = Token.BooleanLiteral;
            +      break;
            +    case "null":
            +      type = Token.NullLiteral;
            +      break;
            +    default:
            +      type = Token.Identifier;
            +    }
            +
            +    return {
            +      type: type,
            +      value: id
            +    };
            +  },
            +  scanNumericLiteral: function () {
            +    var index = 0;
            +    var value = "";
            +    var length = this.input.length;
            +    var char = this.peek(index);
            +    var bad;
            +
            +    function isDecimalDigit(str) {
            +      return (/^[0-9]$/).test(str);
            +    }
            +
            +    function isOctalDigit(str) {
            +      return (/^[0-7]$/).test(str);
            +    }
            +
            +    function isHexDigit(str) {
            +      return (/^[0-9a-fA-F]$/).test(str);
            +    }
            +
            +    function isIdentifierStart(ch) {
            +      return (ch === "$") || (ch === "_") || (ch === "\\") ||
            +        (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z");
            +    }
            +
            +    if (char !== "." && !isDecimalDigit(char)) {
            +      return null;
            +    }
            +
            +    if (char !== ".") {
            +      value = this.peek(index);
            +      index += 1;
            +      char = this.peek(index);
            +
            +      if (value === "0") {
            +        if (char === "x" || char === "X") {
            +          index += 1;
            +          value += char;
            +
            +          while (index < length) {
            +            char = this.peek(index);
            +            if (!isHexDigit(char)) {
            +              break;
            +            }
            +            value += char;
            +            index += 1;
            +          }
            +
            +          if (value.length <= 2) { // 0x
            +            return {
            +              type: Token.NumericLiteral,
            +              value: value,
            +              isMalformed: true
            +            };
            +          }
            +
            +          if (index < length) {
            +            char = this.peek(index);
            +            if (isIdentifierStart(char)) {
            +              return null;
            +            }
            +          }
            +
            +          return {
            +            type: Token.NumericLiteral,
            +            value: value,
            +            base: 16,
            +            isMalformed: false
            +          };
            +        }
            +        if (isOctalDigit(char)) {
            +          index += 1;
            +          value += char;
            +          bad = false;
            +
            +          while (index < length) {
            +            char = this.peek(index);
            +
            +            if (isDecimalDigit(char)) {
            +              bad = true;
            +            } else if (!isOctalDigit(char)) {
            +              break;
            +            }
            +            value += char;
            +            index += 1;
            +          }
            +
            +          if (index < length) {
            +            char = this.peek(index);
            +            if (isIdentifierStart(char)) {
            +              return null;
            +            }
            +          }
            +
            +          return {
            +            type: Token.NumericLiteral,
            +            value: value,
            +            base: 8,
            +            isMalformed: false
            +          };
            +        }
            +
            +        if (isDecimalDigit(char)) {
            +          index += 1;
            +          value += char;
            +        }
            +      }
            +
            +      while (index < length) {
            +        char = this.peek(index);
            +        if (!isDecimalDigit(char)) {
            +          break;
            +        }
            +        value += char;
            +        index += 1;
            +      }
            +    }
            +
            +    if (char === ".") {
            +      value += char;
            +      index += 1;
            +
            +      while (index < length) {
            +        char = this.peek(index);
            +        if (!isDecimalDigit(char)) {
            +          break;
            +        }
            +        value += char;
            +        index += 1;
            +      }
            +    }
            +
            +    if (char === "e" || char === "E") {
            +      value += char;
            +      index += 1;
            +      char = this.peek(index);
            +
            +      if (char === "+" || char === "-") {
            +        value += this.peek(index);
            +        index += 1;
            +      }
            +
            +      char = this.peek(index);
            +      if (isDecimalDigit(char)) {
            +        value += char;
            +        index += 1;
            +
            +        while (index < length) {
            +          char = this.peek(index);
            +          if (!isDecimalDigit(char)) {
            +            break;
            +          }
            +          value += char;
            +          index += 1;
            +        }
            +      } else {
            +        return null;
            +      }
            +    }
            +
            +    if (index < length) {
            +      char = this.peek(index);
            +      if (isIdentifierStart(char)) {
            +        return null;
            +      }
            +    }
            +
            +    return {
            +      type: Token.NumericLiteral,
            +      value: value,
            +      base: 10,
            +      isMalformed: !isFinite(value)
            +    };
            +  },
            +  scanTemplateLiteral: function () {
            +    if (!state.option.esnext || this.peek() !== "`") {
            +      return null;
            +    }
            +
            +    var startLine = this.line;
            +    var startChar = this.char;
            +    var jump = 1;
            +    var value = "";
            +    this.skip();
            +
            +    while (this.peek() !== "`") {
            +      while (this.peek() === "") {
            +        if (!this.nextLine()) {
            +          this.trigger("error", {
            +            code: "E052",
            +            line: startLine,
            +            character: startChar
            +          });
            +
            +          return {
            +            type: Token.TemplateLiteral,
            +            value: value,
            +            isUnclosed: true
            +          };
            +        }
            +        value += "\n";
            +      }
            +      var char = this.peek();
            +      this.skip(jump);
            +      value += char;
            +    }
            +
            +    this.skip();
            +    return {
            +      type: Token.TemplateLiteral,
            +      value: value,
            +      isUnclosed: false
            +    };
            +  },
            +  scanStringLiteral: function (checks) {
            +    var quote = this.peek();
            +    if (quote !== "\"" && quote !== "'") {
            +      return null;
            +    }
            +    this.triggerAsync("warning", {
            +      code: "W108",
            +      line: this.line,
            +      character: this.char // +1?
            +    }, checks, function () { return state.jsonMode && quote !== "\""; });
            +
            +    var value = "";
            +    var startLine = this.line;
            +    var startChar = this.char;
            +    var allowNewLine = false;
            +
            +    this.skip();
            +
            +    outer: while (this.peek() !== quote) {
            +      while (this.peek() === "") { // End Of Line
            +
            +        if (!allowNewLine) {
            +          this.trigger("warning", {
            +            code: "W112",
            +            line: this.line,
            +            character: this.char
            +          });
            +        } else {
            +          allowNewLine = false;
            +
            +          this.triggerAsync("warning", {
            +            code: "W043",
            +            line: this.line,
            +            character: this.char
            +          }, checks, function () { return !state.option.multistr; });
            +
            +          this.triggerAsync("warning", {
            +            code: "W042",
            +            line: this.line,
            +            character: this.char
            +          }, checks, function () { return state.jsonMode && state.option.multistr; });
            +        }
            +
            +        if (!this.nextLine()) {
            +          this.trigger("error", {
            +            code: "E029",
            +            line: startLine,
            +            character: startChar
            +          });
            +
            +          return {
            +            type: Token.StringLiteral,
            +            value: value,
            +            isUnclosed: true,
            +            quote: quote
            +          };
            +        }
            +        
            +        if (this.peek() == quote)
            +          break outer;
            +      }
            +
            +      allowNewLine = false;
            +      var char = this.peek();
            +      var jump = 1; // A length of a jump, after we're done
            +
            +      if (char < " ") {
            +        this.trigger("warning", {
            +          code: "W113",
            +          line: this.line,
            +          character: this.char,
            +          data: [ "<non-printable>" ]
            +        });
            +      }
            +
            +      if (char === "\\") {
            +        this.skip();
            +        char = this.peek();
            +
            +        switch (char) {
            +        case "'":
            +          this.triggerAsync("warning", {
            +            code: "W114",
            +            line: this.line,
            +            character: this.char,
            +            data: [ "\\'" ]
            +          }, checks, function () {return state.jsonMode; });
            +          break;
            +        case "b":
            +          char = "\\b";
            +          break;
            +        case "f":
            +          char = "\\f";
            +          break;
            +        case "n":
            +          char = "\\n";
            +          break;
            +        case "r":
            +          char = "\\r";
            +          break;
            +        case "t":
            +          char = "\\t";
            +          break;
            +        case "0":
            +          char = "\\0";
            +          var n = parseInt(this.peek(1), 10);
            +          this.triggerAsync("warning", {
            +            code: "W115",
            +            line: this.line,
            +            character: this.char
            +          }, checks,
            +          function () { return n >= 0 && n <= 7 && state.directive["use strict"]; });
            +          break;
            +        case "u":
            +          char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16));
            +          jump = 5;
            +          break;
            +        case "v":
            +          this.triggerAsync("warning", {
            +            code: "W114",
            +            line: this.line,
            +            character: this.char,
            +            data: [ "\\v" ]
            +          }, checks, function () { return state.jsonMode; });
            +
            +          char = "\v";
            +          break;
            +        case "x":
            +          var  x = parseInt(this.input.substr(1, 2), 16);
            +
            +          this.triggerAsync("warning", {
            +            code: "W114",
            +            line: this.line,
            +            character: this.char,
            +            data: [ "\\x-" ]
            +          }, checks, function () { return state.jsonMode; });
            +
            +          char = String.fromCharCode(x);
            +          jump = 3;
            +          break;
            +        case "\\":
            +          char = "\\\\";
            +          break;
            +        case "\"":
            +          char = "\\\"";
            +          break;
            +        case "/":
            +          break;
            +        case "":
            +          allowNewLine = true;
            +          char = "";
            +          break;
            +        case "!":
            +          if (value.slice(value.length - 2) === "<") {
            +            break;
            +          }
            +        default:
            +          this.trigger("warning", {
            +            code: "W044",
            +            line: this.line,
            +            character: this.char
            +          });
            +        }
            +      }
            +
            +      value += char;
            +      this.skip(jump);
            +    }
            +
            +    this.skip();
            +    return {
            +      type: Token.StringLiteral,
            +      value: value,
            +      isUnclosed: false,
            +      quote: quote
            +    };
            +  },
            +  scanRegExp: function () {
            +    var index = 0;
            +    var length = this.input.length;
            +    var char = this.peek();
            +    var value = char;
            +    var body = "";
            +    var flags = [];
            +    var malformed = false;
            +    var isCharSet = false;
            +    var terminated;
            +
            +    var scanUnexpectedChars = function () {
            +      if (char < " ") {
            +        malformed = true;
            +        this.trigger("warning", {
            +          code: "W048",
            +          line: this.line,
            +          character: this.char
            +        });
            +      }
            +      if (char === "<") {
            +        malformed = true;
            +        this.trigger("warning", {
            +          code: "W049",
            +          line: this.line,
            +          character: this.char,
            +          data: [ char ]
            +        });
            +      }
            +    }.bind(this);
            +    if (!this.prereg || char !== "/") {
            +      return null;
            +    }
            +
            +    index += 1;
            +    terminated = false;
            +
            +    while (index < length) {
            +      char = this.peek(index);
            +      value += char;
            +      body += char;
            +
            +      if (isCharSet) {
            +        if (char === "]") {
            +          if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") {
            +            isCharSet = false;
            +          }
            +        }
            +
            +        if (char === "\\") {
            +          index += 1;
            +          char = this.peek(index);
            +          body += char;
            +          value += char;
            +
            +          scanUnexpectedChars();
            +        }
            +
            +        index += 1;
            +        continue;
            +      }
            +
            +      if (char === "\\") {
            +        index += 1;
            +        char = this.peek(index);
            +        body += char;
            +        value += char;
            +
            +        scanUnexpectedChars();
            +
            +        if (char === "/") {
            +          index += 1;
            +          continue;
            +        }
            +
            +        if (char === "[") {
            +          index += 1;
            +          continue;
            +        }
            +      }
            +
            +      if (char === "[") {
            +        isCharSet = true;
            +        index += 1;
            +        continue;
            +      }
            +
            +      if (char === "/") {
            +        body = body.substr(0, body.length - 1);
            +        terminated = true;
            +        index += 1;
            +        break;
            +      }
            +
            +      index += 1;
            +    }
            +
            +    if (!terminated) {
            +      this.trigger("error", {
            +        code: "E015",
            +        line: this.line,
            +        character: this.from
            +      });
            +
            +      return void this.trigger("fatal", {
            +        line: this.line,
            +        from: this.from
            +      });
            +    }
            +
            +    while (index < length) {
            +      char = this.peek(index);
            +      if (!/[gim]/.test(char)) {
            +        break;
            +      }
            +      flags.push(char);
            +      value += char;
            +      index += 1;
            +    }
            +
            +    try {
            +      new RegExp(body, flags.join(""));
            +    } catch (err) {
            +      malformed = true;
            +      this.trigger("error", {
            +        code: "E016",
            +        line: this.line,
            +        character: this.char,
            +        data: [ err.message ] // Platform dependent!
            +      });
            +    }
            +
            +    return {
            +      type: Token.RegExp,
            +      value: value,
            +      flags: flags,
            +      isMalformed: malformed
            +    };
            +  },
            +  scanNonBreakingSpaces: function () {
            +    return state.option.nonbsp ?
            +      this.input.search(/(\u00A0)/) : -1;
            +  },
            +  scanUnsafeChars: function () {
            +    return this.input.search(reg.unsafeChars);
            +  },
            +  next: function (checks) {
            +    this.from = this.char;
            +    var start;
            +    if (/\s/.test(this.peek())) {
            +      start = this.char;
            +
            +      while (/\s/.test(this.peek())) {
            +        this.from += 1;
            +        this.skip();
            +      }
            +    }
            +
            +    var match = this.scanComments() ||
            +      this.scanStringLiteral(checks) ||
            +      this.scanTemplateLiteral();
            +
            +    if (match) {
            +      return match;
            +    }
            +
            +    match =
            +      this.scanRegExp() ||
            +      this.scanPunctuator() ||
            +      this.scanKeyword() ||
            +      this.scanIdentifier() ||
            +      this.scanNumericLiteral();
            +
            +    if (match) {
            +      this.skip(match.value.length);
            +      return match;
            +    }
            +
            +    return null;
            +  },
            +  nextLine: function () {
            +    var char;
            +
            +    if (this.line >= this.getLines().length) {
            +      return false;
            +    }
            +
            +    this.input = this.getLines()[this.line];
            +    this.line += 1;
            +    this.char = 1;
            +    this.from = 1;
            +
            +    var inputTrimmed = this.input.trim();
            +
            +    var startsWith = function () {
            +      return _.some(arguments, function (prefix) {
            +        return inputTrimmed.indexOf(prefix) === 0;
            +      });
            +    };
            +
            +    var endsWith = function () {
            +      return _.some(arguments, function (suffix) {
            +        return inputTrimmed.indexOf(suffix, inputTrimmed.length - suffix.length) !== -1;
            +      });
            +    };
            +    if (state.ignoreLinterErrors === true) {
            +      if (!startsWith("/*", "//") && !endsWith("*/")) {
            +        this.input = "";
            +      }
            +    }
            +
            +    char = this.scanNonBreakingSpaces();
            +    if (char >= 0) {
            +      this.trigger("warning", { code: "W125", line: this.line, character: char + 1 });
            +    }
            +
            +    this.input = this.input.replace(/\t/g, state.tab);
            +    char = this.scanUnsafeChars();
            +
            +    if (char >= 0) {
            +      this.trigger("warning", { code: "W100", line: this.line, character: char });
            +    }
            +
            +    if (state.option.maxlen && state.option.maxlen < this.input.length) {
            +      var inComment = this.inComment ||
            +        startsWith.call(inputTrimmed, "//") ||
            +        startsWith.call(inputTrimmed, "/*");
            +
            +      var shouldTriggerError = !inComment || !reg.maxlenException.test(inputTrimmed);
            +
            +      if (shouldTriggerError) {
            +        this.trigger("warning", { code: "W101", line: this.line, character: this.input.length });
            +      }
            +    }
            +
            +    return true;
            +  },
            +  start: function () {
            +    this.nextLine();
            +  },
            +  token: function () {
            +    var checks = asyncTrigger();
            +    var token;
            +
            +
            +    function isReserved(token, isProperty) {
            +      if (!token.reserved) {
            +        return false;
            +      }
            +      var meta = token.meta;
            +
            +      if (meta && meta.isFutureReservedWord && state.option.inES5()) {
            +        if (!meta.es5) {
            +          return false;
            +        }
            +        if (meta.strictOnly) {
            +          if (!state.option.strict && !state.directive["use strict"]) {
            +            return false;
            +          }
            +        }
            +
            +        if (isProperty) {
            +          return false;
            +        }
            +      }
            +
            +      return true;
            +    }
            +    var create = function (type, value, isProperty) {
            +      var obj;
            +
            +      if (type !== "(endline)" && type !== "(end)") {
            +        this.prereg = false;
            +      }
            +
            +      if (type === "(punctuator)") {
            +        switch (value) {
            +        case ".":
            +        case ")":
            +        case "~":
            +        case "#":
            +        case "]":
            +          this.prereg = false;
            +          break;
            +        default:
            +          this.prereg = true;
            +        }
            +
            +        obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
            +      }
            +
            +      if (type === "(identifier)") {
            +        if (value === "return" || value === "case" || value === "typeof") {
            +          this.prereg = true;
            +        }
            +
            +        if (_.has(state.syntax, value)) {
            +          obj = Object.create(state.syntax[value] || state.syntax["(error)"]);
            +          if (!isReserved(obj, isProperty && type === "(identifier)")) {
            +            obj = null;
            +          }
            +        }
            +      }
            +
            +      if (!obj) {
            +        obj = Object.create(state.syntax[type]);
            +      }
            +
            +      obj.identifier = (type === "(identifier)");
            +      obj.type = obj.type || type;
            +      obj.value = value;
            +      obj.line = this.line;
            +      obj.character = this.char;
            +      obj.from = this.from;
            +
            +      if (isProperty && obj.identifier) {
            +        obj.isProperty = isProperty;
            +      }
            +
            +      obj.check = checks.check;
            +
            +      return obj;
            +    }.bind(this);
            +
            +    for (;;) {
            +      if (!this.input.length) {
            +        return create(this.nextLine() ? "(endline)" : "(end)", "");
            +      }
            +
            +      token = this.next(checks);
            +
            +      if (!token) {
            +        if (this.input.length) {
            +          this.trigger("error", {
            +            code: "E024",
            +            line: this.line,
            +            character: this.char,
            +            data: [ this.peek() ]
            +          });
            +
            +          this.input = "";
            +        }
            +
            +        continue;
            +      }
            +
            +      switch (token.type) {
            +      case Token.StringLiteral:
            +        this.triggerAsync("String", {
            +          line: this.line,
            +          char: this.char,
            +          from: this.from,
            +          value: token.value,
            +          quote: token.quote
            +        }, checks, function () { return true; });
            +
            +        return create("(string)", token.value);
            +
            +      case Token.TemplateLiteral:
            +        this.trigger("Template", {
            +          line: this.line,
            +          char: this.char,
            +          from: this.from,
            +          value: token.value
            +        });
            +        return create("(template)", token.value);
            +
            +      case Token.Identifier:
            +        this.trigger("Identifier", {
            +          line: this.line,
            +          char: this.char,
            +          from: this.form,
            +          name: token.value,
            +          isProperty: state.tokens.curr.id === "."
            +        });
            +      case Token.Keyword:
            +      case Token.NullLiteral:
            +      case Token.BooleanLiteral:
            +        return create("(identifier)", token.value, state.tokens.curr.id === ".");
            +
            +      case Token.NumericLiteral:
            +        if (token.isMalformed) {
            +          this.trigger("warning", {
            +            code: "W045",
            +            line: this.line,
            +            character: this.char,
            +            data: [ token.value ]
            +          });
            +        }
            +
            +        this.triggerAsync("warning", {
            +          code: "W114",
            +          line: this.line,
            +          character: this.char,
            +          data: [ "0x-" ]
            +        }, checks, function () { return token.base === 16 && state.jsonMode; });
            +
            +        this.triggerAsync("warning", {
            +          code: "W115",
            +          line: this.line,
            +          character: this.char
            +        }, checks, function () {
            +          return state.directive["use strict"] && token.base === 8;
            +        });
            +
            +        this.trigger("Number", {
            +          line: this.line,
            +          char: this.char,
            +          from: this.from,
            +          value: token.value,
            +          base: token.base,
            +          isMalformed: token.malformed
            +        });
            +
            +        return create("(number)", token.value);
            +
            +      case Token.RegExp:
            +        return create("(regexp)", token.value);
            +
            +      case Token.Comment:
            +        state.tokens.curr.comment = true;
            +
            +        if (token.isSpecial) {
            +          return {
            +            id: '(comment)',
            +            value: token.value,
            +            body: token.body,
            +            type: token.commentType,
            +            isSpecial: token.isSpecial,
            +            line: this.line,
            +            character: this.char,
            +            from: this.from
            +          };
            +        }
            +
            +        break;
            +
            +      case "":
            +        break;
            +
            +      default:
            +        return create("(punctuator)", token.value);
            +      }
            +    }
            +  }
            +};
            +
            +exports.Lexer = Lexer;
            +
            +},
            +{"../data/ascii-identifier-data.js":1,"./reg.js":6,"./state.js":7,"events":10,"underscore":2}],
            +5:[function(_dereq_,module,exports){
            +
            +
            +var _ = _dereq_("underscore");
            +
            +var errors = {
            +  E001: "Bad option: '{a}'.",
            +  E002: "Bad option value.",
            +  E003: "Expected a JSON value.",
            +  E004: "Input is neither a string nor an array of strings.",
            +  E005: "Input is empty.",
            +  E006: "Unexpected early end of program.",
            +  E007: "Missing \"use strict\" statement.",
            +  E008: "Strict violation.",
            +  E009: "Option 'validthis' can't be used in a global scope.",
            +  E010: "'with' is not allowed in strict mode.",
            +  E011: "const '{a}' has already been declared.",
            +  E012: "const '{a}' is initialized to 'undefined'.",
            +  E013: "Attempting to override '{a}' which is a constant.",
            +  E014: "A regular expression literal can be confused with '/='.",
            +  E015: "Unclosed regular expression.",
            +  E016: "Invalid regular expression.",
            +  E017: "Unclosed comment.",
            +  E018: "Unbegun comment.",
            +  E019: "Unmatched '{a}'.",
            +  E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.",
            +  E021: "Expected '{a}' and instead saw '{b}'.",
            +  E022: "Line breaking error '{a}'.",
            +  E023: "Missing '{a}'.",
            +  E024: "Unexpected '{a}'.",
            +  E025: "Missing ':' on a case clause.",
            +  E026: "Missing '}' to match '{' from line {a}.",
            +  E027: "Missing ']' to match '[' from line {a}.",
            +  E028: "Illegal comma.",
            +  E029: "Unclosed string.",
            +  E030: "Expected an identifier and instead saw '{a}'.",
            +  E031: "Bad assignment.", // FIXME: Rephrase
            +  E032: "Expected a small integer or 'false' and instead saw '{a}'.",
            +  E033: "Expected an operator and instead saw '{a}'.",
            +  E034: "get/set are ES5 features.",
            +  E035: "Missing property name.",
            +  E036: "Expected to see a statement and instead saw a block.",
            +  E037: null,
            +  E038: null,
            +  E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.",
            +  E040: "Each value should have its own case label.",
            +  E041: "Unrecoverable syntax error.",
            +  E042: "Stopping.",
            +  E043: "Too many errors.",
            +  E044: null,
            +  E045: "Invalid for each loop.",
            +  E046: "A yield statement shall be within a generator function (with syntax: `function*`)",
            +  E047: null, // Vacant
            +  E048: "Let declaration not directly within block.",
            +  E049: "A {a} cannot be named '{b}'.",
            +  E050: "Mozilla requires the yield expression to be parenthesized here.",
            +  E051: "Regular parameters cannot come after default parameters.",
            +  E052: "Unclosed template literal."
            +};
            +
            +var warnings = {
            +  W001: "'hasOwnProperty' is a really bad name.",
            +  W002: "Value of '{a}' may be overwritten in IE 8 and earlier.",
            +  W003: "'{a}' was used before it was defined.",
            +  W004: "'{a}' is already defined.",
            +  W005: "A dot following a number can be confused with a decimal point.",
            +  W006: "Confusing minuses.",
            +  W007: "Confusing plusses.",
            +  W008: "A leading decimal point can be confused with a dot: '{a}'.",
            +  W009: "The array literal notation [] is preferable.",
            +  W010: "The object literal notation {} is preferable.",
            +  W011: null,
            +  W012: null,
            +  W013: null,
            +  W014: "Bad line breaking before '{a}'.",
            +  W015: null,
            +  W016: "Unexpected use of '{a}'.",
            +  W017: "Bad operand.",
            +  W018: "Confusing use of '{a}'.",
            +  W019: "Use the isNaN function to compare with NaN.",
            +  W020: "Read only.",
            +  W021: "'{a}' is a function.",
            +  W022: "Do not assign to the exception parameter.",
            +  W023: "Expected an identifier in an assignment and instead saw a function invocation.",
            +  W024: "Expected an identifier and instead saw '{a}' (a reserved word).",
            +  W025: "Missing name in function declaration.",
            +  W026: "Inner functions should be listed at the top of the outer function.",
            +  W027: "Unreachable '{a}' after '{b}'.",
            +  W028: "Label '{a}' on {b} statement.",
            +  W030: "Expected an assignment or function call and instead saw an expression.",
            +  W031: "Do not use 'new' for side effects.",
            +  W032: "Unnecessary semicolon.",
            +  W033: "Missing semicolon.",
            +  W034: "Unnecessary directive \"{a}\".",
            +  W035: "Empty block.",
            +  W036: "Unexpected /*member '{a}'.",
            +  W037: "'{a}' is a statement label.",
            +  W038: "'{a}' used out of scope.",
            +  W039: "'{a}' is not allowed.",
            +  W040: "Possible strict violation.",
            +  W041: "Use '{a}' to compare with '{b}'.",
            +  W042: "Avoid EOL escaping.",
            +  W043: "Bad escaping of EOL. Use option multistr if needed.",
            +  W044: "Bad or unnecessary escaping.",
            +  W045: "Bad number '{a}'.",
            +  W046: "Don't use extra leading zeros '{a}'.",
            +  W047: "A trailing decimal point can be confused with a dot: '{a}'.",
            +  W048: "Unexpected control character in regular expression.",
            +  W049: "Unexpected escaped character '{a}' in regular expression.",
            +  W050: "JavaScript URL.",
            +  W051: "Variables should not be deleted.",
            +  W052: "Unexpected '{a}'.",
            +  W053: "Do not use {a} as a constructor.",
            +  W054: "The Function constructor is a form of eval.",
            +  W055: "A constructor name should start with an uppercase letter.",
            +  W056: "Bad constructor.",
            +  W057: "Weird construction. Is 'new' necessary?",
            +  W058: "Missing '()' invoking a constructor.",
            +  W059: "Avoid arguments.{a}.",
            +  W060: "document.write can be a form of eval.",
            +  W061: "eval can be harmful.",
            +  W062: "Wrap an immediate function invocation in parens " +
            +    "to assist the reader in understanding that the expression " +
            +    "is the result of a function, and not the function itself.",
            +  W063: "Math is not a function.",
            +  W064: "Missing 'new' prefix when invoking a constructor.",
            +  W065: "Missing radix parameter.",
            +  W066: "Implied eval. Consider passing a function instead of a string.",
            +  W067: "Bad invocation.",
            +  W068: "Wrapping non-IIFE function literals in parens is unnecessary.",
            +  W069: "['{a}'] is better written in dot notation.",
            +  W070: "Extra comma. (it breaks older versions of IE)",
            +  W071: "This function has too many statements. ({a})",
            +  W072: "This function has too many parameters. ({a})",
            +  W073: "Blocks are nested too deeply. ({a})",
            +  W074: "This function's cyclomatic complexity is too high. ({a})",
            +  W075: "Duplicate key '{a}'.",
            +  W076: "Unexpected parameter '{a}' in get {b} function.",
            +  W077: "Expected a single parameter in set {a} function.",
            +  W078: "Setter is defined without getter.",
            +  W079: "Redefinition of '{a}'.",
            +  W080: "It's not necessary to initialize '{a}' to 'undefined'.",
            +  W081: null,
            +  W082: "Function declarations should not be placed in blocks. " +
            +    "Use a function expression or move the statement to the top of " +
            +    "the outer function.",
            +  W083: "Don't make functions within a loop.",
            +  W084: "Assignment in conditional expression",
            +  W085: "Don't use 'with'.",
            +  W086: "Expected a 'break' statement before '{a}'.",
            +  W087: "Forgotten 'debugger' statement?",
            +  W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.",
            +  W089: "The body of a for in should be wrapped in an if statement to filter " +
            +    "unwanted properties from the prototype.",
            +  W090: "'{a}' is not a statement label.",
            +  W091: "'{a}' is out of scope.",
            +  W093: "Did you mean to return a conditional instead of an assignment?",
            +  W094: "Unexpected comma.",
            +  W095: "Expected a string and instead saw {a}.",
            +  W096: "The '{a}' key may produce unexpected results.",
            +  W097: "Use the function form of \"use strict\".",
            +  W098: "'{a}' is defined but never used.",
            +  W099: null,
            +  W100: "This character may get silently deleted by one or more browsers.",
            +  W101: "Line is too long.",
            +  W102: null,
            +  W103: "The '{a}' property is deprecated.",
            +  W104: "'{a}' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).",
            +  W105: "Unexpected {a} in '{b}'.",
            +  W106: "Identifier '{a}' is not in camel case.",
            +  W107: "Script URL.",
            +  W108: "Strings must use doublequote.",
            +  W109: "Strings must use singlequote.",
            +  W110: "Mixed double and single quotes.",
            +  W112: "Unclosed string.",
            +  W113: "Control character in string: {a}.",
            +  W114: "Avoid {a}.",
            +  W115: "Octal literals are not allowed in strict mode.",
            +  W116: "Expected '{a}' and instead saw '{b}'.",
            +  W117: "'{a}' is not defined.",
            +  W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).",
            +  W119: "'{a}' is only available in ES6 (use esnext option).",
            +  W120: "You might be leaking a variable ({a}) here.",
            +  W121: "Extending prototype of native object: '{a}'.",
            +  W122: "Invalid typeof value '{a}'",
            +  W123: "'{a}' is already defined in outer scope.",
            +  W124: "A generator function shall contain a yield statement.",
            +  W125: "This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp"
            +};
            +
            +var info = {
            +  I001: "Comma warnings can be turned off with 'laxcomma'.",
            +  I002: null,
            +  I003: "ES5 option is now set per default"
            +};
            +
            +exports.errors = {};
            +exports.warnings = {};
            +exports.info = {};
            +
            +_.each(errors, function (desc, code) {
            +  exports.errors[code] = { code: code, desc: desc };
            +});
            +
            +_.each(warnings, function (desc, code) {
            +  exports.warnings[code] = { code: code, desc: desc };
            +});
            +
            +_.each(info, function (desc, code) {
            +  exports.info[code] = { code: code, desc: desc };
            +});
            +
            +},
            +{"underscore":2}],
            +6:[function(_dereq_,module,exports){
            +
            +"use string";
            +exports.unsafeString =
            +  /@cc|<\/?|script|\]\s*\]|<\s*!|&lt/i;
            +exports.unsafeChars =
            +  /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
            +exports.needEsc =
            +  /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/;
            +
            +exports.needEscGlobal =
            +  /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
            +exports.starSlash = /\*\//;
            +exports.identifier = /^([a-zA-Z_$][a-zA-Z0-9_$]*)$/;
            +exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
            +exports.fallsThrough = /^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/;
            +exports.maxlenException = /^(?:(?:\/\/|\/\*|\*) ?)?[^ ]+$/;
            +
            +},
            +{}],
            +7:[function(_dereq_,module,exports){
            +
            +
            +var state = {
            +  syntax: {},
            +
            +  reset: function () {
            +    this.tokens = {
            +      prev: null,
            +      next: null,
            +      curr: null
            +    };
            +
            +    this.option = {};
            +    this.ignored = {};
            +    this.directive = {};
            +    this.jsonMode = false;
            +    this.jsonWarnings = [];
            +    this.lines = [];
            +    this.tab = "";
            +    this.cache = {}; // Node.JS doesn't have Map. Sniff.
            +    this.ignoredLines = {};
            +    this.ignoreLinterErrors = false;
            +  }
            +};
            +
            +exports.state = state;
            +
            +},
            +{}],
            +8:[function(_dereq_,module,exports){
            +
            +
            +exports.register = function (linter) {
            +
            +  linter.on("Identifier", function style_scanProto(data) {
            +    if (linter.getOption("proto")) {
            +      return;
            +    }
            +
            +    if (data.name === "__proto__") {
            +      linter.warn("W103", {
            +        line: data.line,
            +        char: data.char,
            +        data: [ data.name ]
            +      });
            +    }
            +  });
            +
            +  linter.on("Identifier", function style_scanIterator(data) {
            +    if (linter.getOption("iterator")) {
            +      return;
            +    }
            +
            +    if (data.name === "__iterator__") {
            +      linter.warn("W104", {
            +        line: data.line,
            +        char: data.char,
            +        data: [ data.name ]
            +      });
            +    }
            +  });
            +
            +  linter.on("Identifier", function style_scanCamelCase(data) {
            +    if (!linter.getOption("camelcase")) {
            +      return;
            +    }
            +
            +    if (data.name.replace(/^_+|_+$/g, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) {
            +      linter.warn("W106", {
            +        line: data.line,
            +        char: data.from,
            +        data: [ data.name ]
            +      });
            +    }
            +  });
            +
            +  linter.on("String", function style_scanQuotes(data) {
            +    var quotmark = linter.getOption("quotmark");
            +    var code;
            +
            +    if (!quotmark) {
            +      return;
            +    }
            +
            +    if (quotmark === "single" && data.quote !== "'") {
            +      code = "W109";
            +    }
            +
            +    if (quotmark === "double" && data.quote !== "\"") {
            +      code = "W108";
            +    }
            +
            +    if (quotmark === true) {
            +      if (!linter.getCache("quotmark")) {
            +        linter.setCache("quotmark", data.quote);
            +      }
            +
            +      if (linter.getCache("quotmark") !== data.quote) {
            +        code = "W110";
            +      }
            +    }
            +
            +    if (code) {
            +      linter.warn(code, {
            +        line: data.line,
            +        char: data.char,
            +      });
            +    }
            +  });
            +
            +  linter.on("Number", function style_scanNumbers(data) {
            +    if (data.value.charAt(0) === ".") {
            +      linter.warn("W008", {
            +        line: data.line,
            +        char: data.char,
            +        data: [ data.value ]
            +      });
            +    }
            +
            +    if (data.value.substr(data.value.length - 1) === ".") {
            +      linter.warn("W047", {
            +        line: data.line,
            +        char: data.char,
            +        data: [ data.value ]
            +      });
            +    }
            +
            +    if (/^00+/.test(data.value)) {
            +      linter.warn("W046", {
            +        line: data.line,
            +        char: data.char,
            +        data: [ data.value ]
            +      });
            +    }
            +  });
            +
            +  linter.on("String", function style_scanJavaScriptURLs(data) {
            +    var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i;
            +
            +    if (linter.getOption("scripturl")) {
            +      return;
            +    }
            +
            +    if (re.test(data.value)) {
            +      linter.warn("W107", {
            +        line: data.line,
            +        char: data.char
            +      });
            +    }
            +  });
            +};
            +
            +},
            +{}],
            +9:[function(_dereq_,module,exports){
            +
            +exports.reservedVars = {
            +  arguments : false,
            +  NaN       : false
            +};
            +
            +exports.ecmaIdentifiers = {
            +  Array              : false,
            +  Boolean            : false,
            +  Date               : false,
            +  decodeURI          : false,
            +  decodeURIComponent : false,
            +  encodeURI          : false,
            +  encodeURIComponent : false,
            +  Error              : false,
            +  "eval"             : false,
            +  EvalError          : false,
            +  Function           : false,
            +  hasOwnProperty     : false,
            +  isFinite           : false,
            +  isNaN              : false,
            +  JSON               : false,
            +  Math               : false,
            +  Number             : false,
            +  Object             : false,
            +  parseInt           : false,
            +  parseFloat         : false,
            +  RangeError         : false,
            +  ReferenceError     : false,
            +  RegExp             : false,
            +  String             : false,
            +  SyntaxError        : false,
            +  TypeError          : false,
            +  URIError           : false,
            +};
            +
            +exports.newEcmaIdentifiers = {
            +  Set     : false,
            +  Map     : false,
            +  WeakMap : false,
            +  WeakSet : false,
            +  Proxy   : false,
            +  Promise : false
            +};
            +
            +exports.browser = {
            +  Audio                : false,
            +  Blob                 : false,
            +  addEventListener     : false,
            +  applicationCache     : false,
            +  atob                 : false,
            +  blur                 : false,
            +  btoa                 : false,
            +  CanvasGradient       : false,
            +  CanvasPattern        : false,
            +  CanvasRenderingContext2D: false,
            +  clearInterval        : false,
            +  clearTimeout         : false,
            +  close                : false,
            +  closed               : false,
            +  CustomEvent          : false,
            +  DOMParser            : false,
            +  defaultStatus        : false,
            +  document             : false,
            +  Element              : false,
            +  ElementTimeControl   : false,
            +  event                : false,
            +  FileReader           : false,
            +  FormData             : false,
            +  focus                : false,
            +  frames               : false,
            +  getComputedStyle     : false,
            +  HTMLElement          : false,
            +  HTMLAnchorElement    : false,
            +  HTMLBaseElement      : false,
            +  HTMLBlockquoteElement: false,
            +  HTMLBodyElement      : false,
            +  HTMLBRElement        : false,
            +  HTMLButtonElement    : false,
            +  HTMLCanvasElement    : false,
            +  HTMLDirectoryElement : false,
            +  HTMLDivElement       : false,
            +  HTMLDListElement     : false,
            +  HTMLFieldSetElement  : false,
            +  HTMLFontElement      : false,
            +  HTMLFormElement      : false,
            +  HTMLFrameElement     : false,
            +  HTMLFrameSetElement  : false,
            +  HTMLHeadElement      : false,
            +  HTMLHeadingElement   : false,
            +  HTMLHRElement        : false,
            +  HTMLHtmlElement      : false,
            +  HTMLIFrameElement    : false,
            +  HTMLImageElement     : false,
            +  HTMLInputElement     : false,
            +  HTMLIsIndexElement   : false,
            +  HTMLLabelElement     : false,
            +  HTMLLayerElement     : false,
            +  HTMLLegendElement    : false,
            +  HTMLLIElement        : false,
            +  HTMLLinkElement      : false,
            +  HTMLMapElement       : false,
            +  HTMLMenuElement      : false,
            +  HTMLMetaElement      : false,
            +  HTMLModElement       : false,
            +  HTMLObjectElement    : false,
            +  HTMLOListElement     : false,
            +  HTMLOptGroupElement  : false,
            +  HTMLOptionElement    : false,
            +  HTMLParagraphElement : false,
            +  HTMLParamElement     : false,
            +  HTMLPreElement       : false,
            +  HTMLQuoteElement     : false,
            +  HTMLScriptElement    : false,
            +  HTMLSelectElement    : false,
            +  HTMLStyleElement     : false,
            +  HTMLTableCaptionElement: false,
            +  HTMLTableCellElement : false,
            +  HTMLTableColElement  : false,
            +  HTMLTableElement     : false,
            +  HTMLTableRowElement  : false,
            +  HTMLTableSectionElement: false,
            +  HTMLTextAreaElement  : false,
            +  HTMLTitleElement     : false,
            +  HTMLUListElement     : false,
            +  HTMLVideoElement     : false,
            +  history              : false,
            +  Image                : false,
            +  length               : false,
            +  localStorage         : false,
            +  location             : false,
            +  matchMedia           : false,
            +  MessageChannel       : false,
            +  MessageEvent         : false,
            +  MessagePort          : false,
            +  MouseEvent           : false,
            +  moveBy               : false,
            +  moveTo               : false,
            +  MutationObserver     : false,
            +  name                 : false,
            +  Node                 : false,
            +  NodeFilter           : false,
            +  NodeList             : false,
            +  navigator            : false,
            +  onbeforeunload       : true,
            +  onblur               : true,
            +  onerror              : true,
            +  onfocus              : true,
            +  onload               : true,
            +  onresize             : true,
            +  onunload             : true,
            +  open                 : false,
            +  openDatabase         : false,
            +  opener               : false,
            +  Option               : false,
            +  parent               : false,
            +  print                : false,
            +  removeEventListener  : false,
            +  resizeBy             : false,
            +  resizeTo             : false,
            +  screen               : false,
            +  scroll               : false,
            +  scrollBy             : false,
            +  scrollTo             : false,
            +  sessionStorage       : false,
            +  setInterval          : false,
            +  setTimeout           : false,
            +  SharedWorker         : false,
            +  status               : false,
            +  SVGAElement          : false,
            +  SVGAltGlyphDefElement: false,
            +  SVGAltGlyphElement   : false,
            +  SVGAltGlyphItemElement: false,
            +  SVGAngle             : false,
            +  SVGAnimateColorElement: false,
            +  SVGAnimateElement    : false,
            +  SVGAnimateMotionElement: false,
            +  SVGAnimateTransformElement: false,
            +  SVGAnimatedAngle     : false,
            +  SVGAnimatedBoolean   : false,
            +  SVGAnimatedEnumeration: false,
            +  SVGAnimatedInteger   : false,
            +  SVGAnimatedLength    : false,
            +  SVGAnimatedLengthList: false,
            +  SVGAnimatedNumber    : false,
            +  SVGAnimatedNumberList: false,
            +  SVGAnimatedPathData  : false,
            +  SVGAnimatedPoints    : false,
            +  SVGAnimatedPreserveAspectRatio: false,
            +  SVGAnimatedRect      : false,
            +  SVGAnimatedString    : false,
            +  SVGAnimatedTransformList: false,
            +  SVGAnimationElement  : false,
            +  SVGCSSRule           : false,
            +  SVGCircleElement     : false,
            +  SVGClipPathElement   : false,
            +  SVGColor             : false,
            +  SVGColorProfileElement: false,
            +  SVGColorProfileRule  : false,
            +  SVGComponentTransferFunctionElement: false,
            +  SVGCursorElement     : false,
            +  SVGDefsElement       : false,
            +  SVGDescElement       : false,
            +  SVGDocument          : false,
            +  SVGElement           : false,
            +  SVGElementInstance   : false,
            +  SVGElementInstanceList: false,
            +  SVGEllipseElement    : false,
            +  SVGExternalResourcesRequired: false,
            +  SVGFEBlendElement    : false,
            +  SVGFEColorMatrixElement: false,
            +  SVGFEComponentTransferElement: false,
            +  SVGFECompositeElement: false,
            +  SVGFEConvolveMatrixElement: false,
            +  SVGFEDiffuseLightingElement: false,
            +  SVGFEDisplacementMapElement: false,
            +  SVGFEDistantLightElement: false,
            +  SVGFEFloodElement    : false,
            +  SVGFEFuncAElement    : false,
            +  SVGFEFuncBElement    : false,
            +  SVGFEFuncGElement    : false,
            +  SVGFEFuncRElement    : false,
            +  SVGFEGaussianBlurElement: false,
            +  SVGFEImageElement    : false,
            +  SVGFEMergeElement    : false,
            +  SVGFEMergeNodeElement: false,
            +  SVGFEMorphologyElement: false,
            +  SVGFEOffsetElement   : false,
            +  SVGFEPointLightElement: false,
            +  SVGFESpecularLightingElement: false,
            +  SVGFESpotLightElement: false,
            +  SVGFETileElement     : false,
            +  SVGFETurbulenceElement: false,
            +  SVGFilterElement     : false,
            +  SVGFilterPrimitiveStandardAttributes: false,
            +  SVGFitToViewBox      : false,
            +  SVGFontElement       : false,
            +  SVGFontFaceElement   : false,
            +  SVGFontFaceFormatElement: false,
            +  SVGFontFaceNameElement: false,
            +  SVGFontFaceSrcElement: false,
            +  SVGFontFaceUriElement: false,
            +  SVGForeignObjectElement: false,
            +  SVGGElement          : false,
            +  SVGGlyphElement      : false,
            +  SVGGlyphRefElement   : false,
            +  SVGGradientElement   : false,
            +  SVGHKernElement      : false,
            +  SVGICCColor          : false,
            +  SVGImageElement      : false,
            +  SVGLangSpace         : false,
            +  SVGLength            : false,
            +  SVGLengthList        : false,
            +  SVGLineElement       : false,
            +  SVGLinearGradientElement: false,
            +  SVGLocatable         : false,
            +  SVGMPathElement      : false,
            +  SVGMarkerElement     : false,
            +  SVGMaskElement       : false,
            +  SVGMatrix            : false,
            +  SVGMetadataElement   : false,
            +  SVGMissingGlyphElement: false,
            +  SVGNumber            : false,
            +  SVGNumberList        : false,
            +  SVGPaint             : false,
            +  SVGPathElement       : false,
            +  SVGPathSeg           : false,
            +  SVGPathSegArcAbs     : false,
            +  SVGPathSegArcRel     : false,
            +  SVGPathSegClosePath  : false,
            +  SVGPathSegCurvetoCubicAbs: false,
            +  SVGPathSegCurvetoCubicRel: false,
            +  SVGPathSegCurvetoCubicSmoothAbs: false,
            +  SVGPathSegCurvetoCubicSmoothRel: false,
            +  SVGPathSegCurvetoQuadraticAbs: false,
            +  SVGPathSegCurvetoQuadraticRel: false,
            +  SVGPathSegCurvetoQuadraticSmoothAbs: false,
            +  SVGPathSegCurvetoQuadraticSmoothRel: false,
            +  SVGPathSegLinetoAbs  : false,
            +  SVGPathSegLinetoHorizontalAbs: false,
            +  SVGPathSegLinetoHorizontalRel: false,
            +  SVGPathSegLinetoRel  : false,
            +  SVGPathSegLinetoVerticalAbs: false,
            +  SVGPathSegLinetoVerticalRel: false,
            +  SVGPathSegList       : false,
            +  SVGPathSegMovetoAbs  : false,
            +  SVGPathSegMovetoRel  : false,
            +  SVGPatternElement    : false,
            +  SVGPoint             : false,
            +  SVGPointList         : false,
            +  SVGPolygonElement    : false,
            +  SVGPolylineElement   : false,
            +  SVGPreserveAspectRatio: false,
            +  SVGRadialGradientElement: false,
            +  SVGRect              : false,
            +  SVGRectElement       : false,
            +  SVGRenderingIntent   : false,
            +  SVGSVGElement        : false,
            +  SVGScriptElement     : false,
            +  SVGSetElement        : false,
            +  SVGStopElement       : false,
            +  SVGStringList        : false,
            +  SVGStylable          : false,
            +  SVGStyleElement      : false,
            +  SVGSwitchElement     : false,
            +  SVGSymbolElement     : false,
            +  SVGTRefElement       : false,
            +  SVGTSpanElement      : false,
            +  SVGTests             : false,
            +  SVGTextContentElement: false,
            +  SVGTextElement       : false,
            +  SVGTextPathElement   : false,
            +  SVGTextPositioningElement: false,
            +  SVGTitleElement      : false,
            +  SVGTransform         : false,
            +  SVGTransformList     : false,
            +  SVGTransformable     : false,
            +  SVGURIReference      : false,
            +  SVGUnitTypes         : false,
            +  SVGUseElement        : false,
            +  SVGVKernElement      : false,
            +  SVGViewElement       : false,
            +  SVGViewSpec          : false,
            +  SVGZoomAndPan        : false,
            +  TimeEvent            : false,
            +  top                  : false,
            +  URL                  : false,
            +  WebSocket            : false,
            +  window               : false,
            +  Worker               : false,
            +  XMLHttpRequest       : false,
            +  XMLSerializer        : false,
            +  XPathEvaluator       : false,
            +  XPathException       : false,
            +  XPathExpression      : false,
            +  XPathNamespace       : false,
            +  XPathNSResolver      : false,
            +  XPathResult          : false
            +};
            +
            +exports.devel = {
            +  alert  : false,
            +  confirm: false,
            +  console: false,
            +  Debug  : false,
            +  opera  : false,
            +  prompt : false
            +};
            +
            +exports.worker = {
            +  importScripts: true,
            +  postMessage  : true,
            +  self         : true
            +};
            +exports.nonstandard = {
            +  escape  : false,
            +  unescape: false
            +};
            +
            +exports.couch = {
            +  "require" : false,
            +  respond   : false,
            +  getRow    : false,
            +  emit      : false,
            +  send      : false,
            +  start     : false,
            +  sum       : false,
            +  log       : false,
            +  exports   : false,
            +  module    : false,
            +  provides  : false
            +};
            +
            +exports.node = {
            +  __filename    : false,
            +  __dirname     : false,
            +  GLOBAL        : false,
            +  global        : false,
            +  module        : false,
            +  require       : false,
            +
            +  Buffer        : true,
            +  console       : true,
            +  exports       : true,
            +  process       : true,
            +  setTimeout    : true,
            +  clearTimeout  : true,
            +  setInterval   : true,
            +  clearInterval : true,
            +  setImmediate  : true, // v0.9.1+
            +  clearImmediate: true  // v0.9.1+
            +};
            +
            +exports.phantom = {
            +  phantom      : true,
            +  require      : true,
            +  WebPage      : true,
            +  console      : true, // in examples, but undocumented
            +  exports      : true  // v1.7+
            +};
            +
            +exports.rhino = {
            +  defineClass  : false,
            +  deserialize  : false,
            +  gc           : false,
            +  help         : false,
            +  importClass  : false,
            +  importPackage: false,
            +  "java"       : false,
            +  load         : false,
            +  loadClass    : false,
            +  Packages     : false,
            +  print        : false,
            +  quit         : false,
            +  readFile     : false,
            +  readUrl      : false,
            +  runCommand   : false,
            +  seal         : false,
            +  serialize    : false,
            +  spawn        : false,
            +  sync         : false,
            +  toint32      : false,
            +  version      : false
            +};
            +
            +exports.shelljs = {
            +  target       : false,
            +  echo         : false,
            +  exit         : false,
            +  cd           : false,
            +  pwd          : false,
            +  ls           : false,
            +  find         : false,
            +  cp           : false,
            +  rm           : false,
            +  mv           : false,
            +  mkdir        : false,
            +  test         : false,
            +  cat          : false,
            +  sed          : false,
            +  grep         : false,
            +  which        : false,
            +  dirs         : false,
            +  pushd        : false,
            +  popd         : false,
            +  env          : false,
            +  exec         : false,
            +  chmod        : false,
            +  config       : false,
            +  error        : false,
            +  tempdir      : false
            +};
            +
            +exports.typed = {
            +  ArrayBuffer         : false,
            +  ArrayBufferView     : false,
            +  DataView            : false,
            +  Float32Array        : false,
            +  Float64Array        : false,
            +  Int16Array          : false,
            +  Int32Array          : false,
            +  Int8Array           : false,
            +  Uint16Array         : false,
            +  Uint32Array         : false,
            +  Uint8Array          : false,
            +  Uint8ClampedArray   : false
            +};
            +
            +exports.wsh = {
            +  ActiveXObject            : true,
            +  Enumerator               : true,
            +  GetObject                : true,
            +  ScriptEngine             : true,
            +  ScriptEngineBuildVersion : true,
            +  ScriptEngineMajorVersion : true,
            +  ScriptEngineMinorVersion : true,
            +  VBArray                  : true,
            +  WSH                      : true,
            +  WScript                  : true,
            +  XDomainRequest           : true
            +};
            +
            +exports.dojo = {
            +  dojo     : false,
            +  dijit    : false,
            +  dojox    : false,
            +  define   : false,
            +  "require": false
            +};
            +
            +exports.jquery = {
            +  "$"    : false,
            +  jQuery : false
            +};
            +
            +exports.mootools = {
            +  "$"           : false,
            +  "$$"          : false,
            +  Asset         : false,
            +  Browser       : false,
            +  Chain         : false,
            +  Class         : false,
            +  Color         : false,
            +  Cookie        : false,
            +  Core          : false,
            +  Document      : false,
            +  DomReady      : false,
            +  DOMEvent      : false,
            +  DOMReady      : false,
            +  Drag          : false,
            +  Element       : false,
            +  Elements      : false,
            +  Event         : false,
            +  Events        : false,
            +  Fx            : false,
            +  Group         : false,
            +  Hash          : false,
            +  HtmlTable     : false,
            +  Iframe        : false,
            +  IframeShim    : false,
            +  InputValidator: false,
            +  instanceOf    : false,
            +  Keyboard      : false,
            +  Locale        : false,
            +  Mask          : false,
            +  MooTools      : false,
            +  Native        : false,
            +  Options       : false,
            +  OverText      : false,
            +  Request       : false,
            +  Scroller      : false,
            +  Slick         : false,
            +  Slider        : false,
            +  Sortables     : false,
            +  Spinner       : false,
            +  Swiff         : false,
            +  Tips          : false,
            +  Type          : false,
            +  typeOf        : false,
            +  URI           : false,
            +  Window        : false
            +};
            +
            +exports.prototypejs = {
            +  "$"               : false,
            +  "$$"              : false,
            +  "$A"              : false,
            +  "$F"              : false,
            +  "$H"              : false,
            +  "$R"              : false,
            +  "$break"          : false,
            +  "$continue"       : false,
            +  "$w"              : false,
            +  Abstract          : false,
            +  Ajax              : false,
            +  Class             : false,
            +  Enumerable        : false,
            +  Element           : false,
            +  Event             : false,
            +  Field             : false,
            +  Form              : false,
            +  Hash              : false,
            +  Insertion         : false,
            +  ObjectRange       : false,
            +  PeriodicalExecuter: false,
            +  Position          : false,
            +  Prototype         : false,
            +  Selector          : false,
            +  Template          : false,
            +  Toggle            : false,
            +  Try               : false,
            +  Autocompleter     : false,
            +  Builder           : false,
            +  Control           : false,
            +  Draggable         : false,
            +  Draggables        : false,
            +  Droppables        : false,
            +  Effect            : false,
            +  Sortable          : false,
            +  SortableObserver  : false,
            +  Sound             : false,
            +  Scriptaculous     : false
            +};
            +
            +exports.yui = {
            +  YUI       : false,
            +  Y         : false,
            +  YUI_config: false
            +};
            +
            +exports.mocha = {
            +  describe    : false,
            +  it          : false,
            +  before      : false,
            +  after       : false,
            +  beforeEach  : false,
            +  afterEach   : false,
            +  suite       : false,
            +  test        : false,
            +  setup       : false,
            +  teardown    : false
            +};
            +
            +},
            +{}],
            +10:[function(_dereq_,module,exports){
            +
            +function EventEmitter() {
            +  this._events = this._events || {};
            +  this._maxListeners = this._maxListeners || undefined;
            +}
            +module.exports = EventEmitter;
            +EventEmitter.EventEmitter = EventEmitter;
            +
            +EventEmitter.prototype._events = undefined;
            +EventEmitter.prototype._maxListeners = undefined;
            +EventEmitter.defaultMaxListeners = 10;
            +EventEmitter.prototype.setMaxListeners = function(n) {
            +  if (!isNumber(n) || n < 0 || isNaN(n))
            +    throw TypeError('n must be a positive number');
            +  this._maxListeners = n;
            +  return this;
            +};
            +
            +EventEmitter.prototype.emit = function(type) {
            +  var er, handler, len, args, i, listeners;
            +
            +  if (!this._events)
            +    this._events = {};
            +  if (type === 'error') {
            +    if (!this._events.error ||
            +        (isObject(this._events.error) && !this._events.error.length)) {
            +      er = arguments[1];
            +      if (er instanceof Error) {
            +        throw er; // Unhandled 'error' event
            +      } else {
            +        throw TypeError('Uncaught, unspecified "error" event.');
            +      }
            +      return false;
            +    }
            +  }
            +
            +  handler = this._events[type];
            +
            +  if (isUndefined(handler))
            +    return false;
            +
            +  if (isFunction(handler)) {
            +    switch (arguments.length) {
            +      case 1:
            +        handler.call(this);
            +        break;
            +      case 2:
            +        handler.call(this, arguments[1]);
            +        break;
            +      case 3:
            +        handler.call(this, arguments[1], arguments[2]);
            +        break;
            +      default:
            +        len = arguments.length;
            +        args = new Array(len - 1);
            +        for (i = 1; i < len; i++)
            +          args[i - 1] = arguments[i];
            +        handler.apply(this, args);
            +    }
            +  } else if (isObject(handler)) {
            +    len = arguments.length;
            +    args = new Array(len - 1);
            +    for (i = 1; i < len; i++)
            +      args[i - 1] = arguments[i];
            +
            +    listeners = handler.slice();
            +    len = listeners.length;
            +    for (i = 0; i < len; i++)
            +      listeners[i].apply(this, args);
            +  }
            +
            +  return true;
            +};
            +
            +EventEmitter.prototype.addListener = function(type, listener) {
            +  var m;
            +
            +  if (!isFunction(listener))
            +    throw TypeError('listener must be a function');
            +
            +  if (!this._events)
            +    this._events = {};
            +  if (this._events.newListener)
            +    this.emit('newListener', type,
            +              isFunction(listener.listener) ?
            +              listener.listener : listener);
            +
            +  if (!this._events[type])
            +    this._events[type] = listener;
            +  else if (isObject(this._events[type]))
            +    this._events[type].push(listener);
            +  else
            +    this._events[type] = [this._events[type], listener];
            +  if (isObject(this._events[type]) && !this._events[type].warned) {
            +    var m;
            +    if (!isUndefined(this._maxListeners)) {
            +      m = this._maxListeners;
            +    } else {
            +      m = EventEmitter.defaultMaxListeners;
            +    }
            +
            +    if (m && m > 0 && this._events[type].length > m) {
            +      this._events[type].warned = true;
            +      console.error('(node) warning: possible EventEmitter memory ' +
            +                    'leak detected. %d listeners added. ' +
            +                    'Use emitter.setMaxListeners() to increase limit.',
            +                    this._events[type].length);
            +      console.trace();
            +    }
            +  }
            +
            +  return this;
            +};
            +
            +EventEmitter.prototype.on = EventEmitter.prototype.addListener;
            +
            +EventEmitter.prototype.once = function(type, listener) {
            +  if (!isFunction(listener))
            +    throw TypeError('listener must be a function');
            +
            +  var fired = false;
            +
            +  function g() {
            +    this.removeListener(type, g);
            +
            +    if (!fired) {
            +      fired = true;
            +      listener.apply(this, arguments);
            +    }
            +  }
            +
            +  g.listener = listener;
            +  this.on(type, g);
            +
            +  return this;
            +};
            +EventEmitter.prototype.removeListener = function(type, listener) {
            +  var list, position, length, i;
            +
            +  if (!isFunction(listener))
            +    throw TypeError('listener must be a function');
            +
            +  if (!this._events || !this._events[type])
            +    return this;
            +
            +  list = this._events[type];
            +  length = list.length;
            +  position = -1;
            +
            +  if (list === listener ||
            +      (isFunction(list.listener) && list.listener === listener)) {
            +    delete this._events[type];
            +    if (this._events.removeListener)
            +      this.emit('removeListener', type, listener);
            +
            +  } else if (isObject(list)) {
            +    for (i = length; i-- > 0;) {
            +      if (list[i] === listener ||
            +          (list[i].listener && list[i].listener === listener)) {
            +        position = i;
            +        break;
            +      }
            +    }
            +
            +    if (position < 0)
            +      return this;
            +
            +    if (list.length === 1) {
            +      list.length = 0;
            +      delete this._events[type];
            +    } else {
            +      list.splice(position, 1);
            +    }
            +
            +    if (this._events.removeListener)
            +      this.emit('removeListener', type, listener);
            +  }
            +
            +  return this;
            +};
            +
            +EventEmitter.prototype.removeAllListeners = function(type) {
            +  var key, listeners;
            +
            +  if (!this._events)
            +    return this;
            +  if (!this._events.removeListener) {
            +    if (arguments.length === 0)
            +      this._events = {};
            +    else if (this._events[type])
            +      delete this._events[type];
            +    return this;
            +  }
            +  if (arguments.length === 0) {
            +    for (key in this._events) {
            +      if (key === 'removeListener') continue;
            +      this.removeAllListeners(key);
            +    }
            +    this.removeAllListeners('removeListener');
            +    this._events = {};
            +    return this;
            +  }
            +
            +  listeners = this._events[type];
            +
            +  if (isFunction(listeners)) {
            +    this.removeListener(type, listeners);
            +  } else {
            +    while (listeners.length)
            +      this.removeListener(type, listeners[listeners.length - 1]);
            +  }
            +  delete this._events[type];
            +
            +  return this;
            +};
            +
            +EventEmitter.prototype.listeners = function(type) {
            +  var ret;
            +  if (!this._events || !this._events[type])
            +    ret = [];
            +  else if (isFunction(this._events[type]))
            +    ret = [this._events[type]];
            +  else
            +    ret = this._events[type].slice();
            +  return ret;
            +};
            +
            +EventEmitter.listenerCount = function(emitter, type) {
            +  var ret;
            +  if (!emitter._events || !emitter._events[type])
            +    ret = 0;
            +  else if (isFunction(emitter._events[type]))
            +    ret = 1;
            +  else
            +    ret = emitter._events[type].length;
            +  return ret;
            +};
            +
            +function isFunction(arg) {
            +  return typeof arg === 'function';
            +}
            +
            +function isNumber(arg) {
            +  return typeof arg === 'number';
            +}
            +
            +function isObject(arg) {
            +  return typeof arg === 'object' && arg !== null;
            +}
            +
            +function isUndefined(arg) {
            +  return arg === void 0;
            +}
            +
            +},
            +{}]},{},[3])
            +(3)
            +
            +});
            +
            +define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
            +
            +
            +var oop = require("./lib/oop");
            +var EventEmitter = require("./lib/event_emitter").EventEmitter;
            +var Range = require("./range").Range;
            +var Anchor = require("./anchor").Anchor;
            +
            +var Document = function(text) {
            +    this.$lines = [];
            +    if (text.length === 0) {
            +        this.$lines = [""];
            +    } else if (Array.isArray(text)) {
            +        this._insertLines(0, text);
            +    } else {
            +        this.insert({row: 0, column:0}, text);
            +    }
            +};
            +
            +(function() {
            +
            +    oop.implement(this, EventEmitter);
            +    this.setValue = function(text) {
            +        var len = this.getLength();
            +        this.remove(new Range(0, 0, len, this.getLine(len-1).length));
            +        this.insert({row: 0, column:0}, text);
            +    };
            +    this.getValue = function() {
            +        return this.getAllLines().join(this.getNewLineCharacter());
            +    };
            +    this.createAnchor = function(row, column) {
            +        return new Anchor(this, row, column);
            +    };
            +    if ("aaa".split(/a/).length === 0)
            +        this.$split = function(text) {
            +            return text.replace(/\r\n|\r/g, "\n").split("\n");
            +        };
            +    else
            +        this.$split = function(text) {
            +            return text.split(/\r\n|\r|\n/);
            +        };
            +
            +
            +    this.$detectNewLine = function(text) {
            +        var match = text.match(/^.*?(\r\n|\r|\n)/m);
            +        this.$autoNewLine = match ? match[1] : "\n";
            +        this._signal("changeNewLineMode");
            +    };
            +    this.getNewLineCharacter = function() {
            +        switch (this.$newLineMode) {
            +          case "windows":
            +            return "\r\n";
            +          case "unix":
            +            return "\n";
            +          default:
            +            return this.$autoNewLine || "\n";
            +        }
            +    };
            +
            +    this.$autoNewLine = "";
            +    this.$newLineMode = "auto";
            +    this.setNewLineMode = function(newLineMode) {
            +        if (this.$newLineMode === newLineMode)
            +            return;
            +
            +        this.$newLineMode = newLineMode;
            +        this._signal("changeNewLineMode");
            +    };
            +    this.getNewLineMode = function() {
            +        return this.$newLineMode;
            +    };
            +    this.isNewLine = function(text) {
            +        return (text == "\r\n" || text == "\r" || text == "\n");
            +    };
            +    this.getLine = function(row) {
            +        return this.$lines[row] || "";
            +    };
            +    this.getLines = function(firstRow, lastRow) {
            +        return this.$lines.slice(firstRow, lastRow + 1);
            +    };
            +    this.getAllLines = function() {
            +        return this.getLines(0, this.getLength());
            +    };
            +    this.getLength = function() {
            +        return this.$lines.length;
            +    };
            +    this.getTextRange = function(range) {
            +        if (range.start.row == range.end.row) {
            +            return this.getLine(range.start.row)
            +                .substring(range.start.column, range.end.column);
            +        }
            +        var lines = this.getLines(range.start.row, range.end.row);
            +        lines[0] = (lines[0] || "").substring(range.start.column);
            +        var l = lines.length - 1;
            +        if (range.end.row - range.start.row == l)
            +            lines[l] = lines[l].substring(0, range.end.column);
            +        return lines.join(this.getNewLineCharacter());
            +    };
            +
            +    this.$clipPosition = function(position) {
            +        var length = this.getLength();
            +        if (position.row >= length) {
            +            position.row = Math.max(0, length - 1);
            +            position.column = this.getLine(length-1).length;
            +        } else if (position.row < 0)
            +            position.row = 0;
            +        return position;
            +    };
            +    this.insert = function(position, text) {
            +        if (!text || text.length === 0)
            +            return position;
            +
            +        position = this.$clipPosition(position);
            +        if (this.getLength() <= 1)
            +            this.$detectNewLine(text);
            +
            +        var lines = this.$split(text);
            +        var firstLine = lines.splice(0, 1)[0];
            +        var lastLine = lines.length == 0 ? null : lines.splice(lines.length - 1, 1)[0];
            +
            +        position = this.insertInLine(position, firstLine);
            +        if (lastLine !== null) {
            +            position = this.insertNewLine(position); // terminate first line
            +            position = this._insertLines(position.row, lines);
            +            position = this.insertInLine(position, lastLine || "");
            +        }
            +        return position;
            +    };
            +    this.insertLines = function(row, lines) {
            +        if (row >= this.getLength())
            +            return this.insert({row: row, column: 0}, "\n" + lines.join("\n"));
            +        return this._insertLines(Math.max(row, 0), lines);
            +    };
            +    this._insertLines = function(row, lines) {
            +        if (lines.length == 0)
            +            return {row: row, column: 0};
            +        while (lines.length > 0xF000) {
            +            var end = this._insertLines(row, lines.slice(0, 0xF000));
            +            lines = lines.slice(0xF000);
            +            row = end.row;
            +        }
            +
            +        var args = [row, 0];
            +        args.push.apply(args, lines);
            +        this.$lines.splice.apply(this.$lines, args);
            +
            +        var range = new Range(row, 0, row + lines.length, 0);
            +        var delta = {
            +            action: "insertLines",
            +            range: range,
            +            lines: lines
            +        };
            +        this._signal("change", { data: delta });
            +        return range.end;
            +    };
            +    this.insertNewLine = function(position) {
            +        position = this.$clipPosition(position);
            +        var line = this.$lines[position.row] || "";
            +
            +        this.$lines[position.row] = line.substring(0, position.column);
            +        this.$lines.splice(position.row + 1, 0, line.substring(position.column, line.length));
            +
            +        var end = {
            +            row : position.row + 1,
            +            column : 0
            +        };
            +
            +        var delta = {
            +            action: "insertText",
            +            range: Range.fromPoints(position, end),
            +            text: this.getNewLineCharacter()
            +        };
            +        this._signal("change", { data: delta });
            +
            +        return end;
            +    };
            +    this.insertInLine = function(position, text) {
            +        if (text.length == 0)
            +            return position;
            +
            +        var line = this.$lines[position.row] || "";
            +
            +        this.$lines[position.row] = line.substring(0, position.column) + text
            +                + line.substring(position.column);
            +
            +        var end = {
            +            row : position.row,
            +            column : position.column + text.length
            +        };
            +
            +        var delta = {
            +            action: "insertText",
            +            range: Range.fromPoints(position, end),
            +            text: text
            +        };
            +        this._signal("change", { data: delta });
            +
            +        return end;
            +    };
            +    this.remove = function(range) {
            +        if (!(range instanceof Range))
            +            range = Range.fromPoints(range.start, range.end);
            +        range.start = this.$clipPosition(range.start);
            +        range.end = this.$clipPosition(range.end);
            +
            +        if (range.isEmpty())
            +            return range.start;
            +
            +        var firstRow = range.start.row;
            +        var lastRow = range.end.row;
            +
            +        if (range.isMultiLine()) {
            +            var firstFullRow = range.start.column == 0 ? firstRow : firstRow + 1;
            +            var lastFullRow = lastRow - 1;
            +
            +            if (range.end.column > 0)
            +                this.removeInLine(lastRow, 0, range.end.column);
            +
            +            if (lastFullRow >= firstFullRow)
            +                this._removeLines(firstFullRow, lastFullRow);
            +
            +            if (firstFullRow != firstRow) {
            +                this.removeInLine(firstRow, range.start.column, this.getLine(firstRow).length);
            +                this.removeNewLine(range.start.row);
            +            }
            +        }
            +        else {
            +            this.removeInLine(firstRow, range.start.column, range.end.column);
            +        }
            +        return range.start;
            +    };
            +    this.removeInLine = function(row, startColumn, endColumn) {
            +        if (startColumn == endColumn)
            +            return;
            +
            +        var range = new Range(row, startColumn, row, endColumn);
            +        var line = this.getLine(row);
            +        var removed = line.substring(startColumn, endColumn);
            +        var newLine = line.substring(0, startColumn) + line.substring(endColumn, line.length);
            +        this.$lines.splice(row, 1, newLine);
            +
            +        var delta = {
            +            action: "removeText",
            +            range: range,
            +            text: removed
            +        };
            +        this._signal("change", { data: delta });
            +        return range.start;
            +    };
            +    this.removeLines = function(firstRow, lastRow) {
            +        if (firstRow < 0 || lastRow >= this.getLength())
            +            return this.remove(new Range(firstRow, 0, lastRow + 1, 0));
            +        return this._removeLines(firstRow, lastRow);
            +    };
            +
            +    this._removeLines = function(firstRow, lastRow) {
            +        var range = new Range(firstRow, 0, lastRow + 1, 0);
            +        var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
            +
            +        var delta = {
            +            action: "removeLines",
            +            range: range,
            +            nl: this.getNewLineCharacter(),
            +            lines: removed
            +        };
            +        this._signal("change", { data: delta });
            +        return removed;
            +    };
            +    this.removeNewLine = function(row) {
            +        var firstLine = this.getLine(row);
            +        var secondLine = this.getLine(row+1);
            +
            +        var range = new Range(row, firstLine.length, row+1, 0);
            +        var line = firstLine + secondLine;
            +
            +        this.$lines.splice(row, 2, line);
            +
            +        var delta = {
            +            action: "removeText",
            +            range: range,
            +            text: this.getNewLineCharacter()
            +        };
            +        this._signal("change", { data: delta });
            +    };
            +    this.replace = function(range, text) {
            +        if (!(range instanceof Range))
            +            range = Range.fromPoints(range.start, range.end);
            +        if (text.length == 0 && range.isEmpty())
            +            return range.start;
            +        if (text == this.getTextRange(range))
            +            return range.end;
            +
            +        this.remove(range);
            +        if (text) {
            +            var end = this.insert(range.start, text);
            +        }
            +        else {
            +            end = range.start;
            +        }
            +
            +        return end;
            +    };
            +    this.applyDeltas = function(deltas) {
            +        for (var i=0; i<deltas.length; i++) {
            +            var delta = deltas[i];
            +            var range = Range.fromPoints(delta.range.start, delta.range.end);
            +
            +            if (delta.action == "insertLines")
            +                this.insertLines(range.start.row, delta.lines);
            +            else if (delta.action == "insertText")
            +                this.insert(range.start, delta.text);
            +            else if (delta.action == "removeLines")
            +                this._removeLines(range.start.row, range.end.row - 1);
            +            else if (delta.action == "removeText")
            +                this.remove(range);
            +        }
            +    };
            +    this.revertDeltas = function(deltas) {
            +        for (var i=deltas.length-1; i>=0; i--) {
            +            var delta = deltas[i];
            +
            +            var range = Range.fromPoints(delta.range.start, delta.range.end);
            +
            +            if (delta.action == "insertLines")
            +                this._removeLines(range.start.row, range.end.row - 1);
            +            else if (delta.action == "insertText")
            +                this.remove(range);
            +            else if (delta.action == "removeLines")
            +                this._insertLines(range.start.row, delta.lines);
            +            else if (delta.action == "removeText")
            +                this.insert(range.start, delta.text);
            +        }
            +    };
            +    this.indexToPosition = function(index, startRow) {
            +        var lines = this.$lines || this.getAllLines();
            +        var newlineLength = this.getNewLineCharacter().length;
            +        for (var i = startRow || 0, l = lines.length; i < l; i++) {
            +            index -= lines[i].length + newlineLength;
            +            if (index < 0)
            +                return {row: i, column: index + lines[i].length + newlineLength};
            +        }
            +        return {row: l-1, column: lines[l-1].length};
            +    };
            +    this.positionToIndex = function(pos, startRow) {
            +        var lines = this.$lines || this.getAllLines();
            +        var newlineLength = this.getNewLineCharacter().length;
            +        var index = 0;
            +        var row = Math.min(pos.row, lines.length);
            +        for (var i = startRow || 0; i < row; ++i)
            +            index += lines[i].length + newlineLength;
            +
            +        return index + pos.column;
            +    };
            +
            +}).call(Document.prototype);
            +
            +exports.Document = Document;
            +});
            diff --git a/dist/assets/js/vendor/jquery-1.12.4.min.js b/dist/assets/js/vendor/jquery-1.12.4.min.js
            new file mode 100644
            index 0000000000..e836475870
            --- /dev/null
            +++ b/dist/assets/js/vendor/jquery-1.12.4.min.js
            @@ -0,0 +1,5 @@
            +/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */
            +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;
            +}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"<table>"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d="on"+b;a.detachEvent&&("undefined"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?n.prop(b,"form"):void 0;c&&!n._data(c,"submit")&&(n.event.add(c,"submit._submit",function(a){a._submitBubble=!0}),n._data(c,"submit",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,"click._change",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate("change",this,a)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,"change")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a)}),n._data(b,"change",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\d+="(?:null|\d+)"/g,ua=new RegExp("<(?:"+ba+")[\\s/>]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/<script|<style|<link/i,xa=/checked\s*(?:[^=]|=\s*.checked.)/i,ya=/^true\/(.*)/,za=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement("div"),j=d.createElement("div");if(j.style){j.style.cssText="float:left;opacity:.5",l.opacity="0.5"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip="content-box",j.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===j.style.backgroundClip,i=d.createElement("div"),i.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",j.innerHTML="",i.appendChild(j),l.boxSizing=""===j.style.boxSizing||""===j.style.MozBoxSizing||""===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b="1%"!==(l||{}).top,h="2px"===(l||{}).marginLeft,e="4px"===(l||{width:"4px"}).width,j.style.marginRight="50%",c="4px"===(l||{marginRight:"4px"}).marginRight,k=j.appendChild(d.createElement("div")),k.style.cssText=j.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",k.style.marginRight=k.style.width="0",j.style.width="1px",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display="none",f=0===j.getClientRects().length,f&&(j.style.display="",j.innerHTML="<table><tr><td></td><td>t</td></tr></table>",j.childNodes[0].style.borderCollapse="separate",k=j.getElementsByTagName("td"),k[0].style.cssText="margin:0;border:0;padding:0;display:none",f=0===k[0].offsetHeight,f&&(k[0].style.display="",k[1].style.display="none",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0===g?g:g+""}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\([^)]*\)/i,Wa=/opacity\s*=\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp("^("+T+")(.*)$","i"),Za={position:"absolute",visibility:"hidden",display:"block"},$a={letterSpacing:"0",fontWeight:"400"},_a=["Webkit","O","Moz","ms"],ab=d.createElement("div").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&W(d)&&(f[g]=n._data(d,"olddisplay",Ma(d.nodeName)))):(e=W(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function eb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+V[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+V[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+V[f]+"Width",!0,e))):(g+=n.css(a,"padding"+V[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+V[f]+"Width",!0,e)));return g}function fb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),"normal"===f&&b in $a&&(f=$a[b]),""===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,"display"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Va,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+" "+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:"inline-block"},Sa,[a,"marginRight"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{
            +marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb("show"),slideUp:mb("hide"),slideToggle:mb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement("input"),c=d.createElement("div"),e=d.createElement("select"),f=e.appendChild(d.createElement("option"));c=d.createElement("div"),c.setAttribute("className","t"),c.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],b.setAttribute("type","checkbox"),c.appendChild(b),a=c.getElementsByTagName("a")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==c.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement("form").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value}();var rb=/\r/g,sb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(sb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var Bb=/[\t\r\n\f]/g;function Cb(a){return n.attr(a,"class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=Cb(this),b&&n._data(this,"__className__",b),n.attr(this,"class",b||a===!1?"":n._data(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+Cb(c)+" ").replace(Bb," ").indexOf(b)>-1)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,"text/xml")):(c=new a.ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\/\//,Nb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ob={},Pb={},Qb="*/".concat("*"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:"GET",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Qb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks("once memory"),r=l.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+"").replace(Hb,"").replace(Mb,Sb[1]+"//"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||"*").toLowerCase().match(G)||[""],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Sb[3]||("http:"===Sb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&w.setRequestHeader("If-None-Match",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Qb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v="abort";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger("ajaxSend",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort("timeout")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,"No Transport");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||"",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader("Last-Modified"),x&&(n.lastModified[f]=x),x=w.getResponseHeader("etag"),x&&(n.etag[f]=x)),204===b||"HEAD"===l.type?y="nocontent":304===b?y="notmodified":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+"",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?"ajaxSuccess":"ajaxError",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger("ajaxComplete",[w,l]),--n.active||n.event.trigger("ajaxStop")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,"display")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if("none"===Yb(a)||"hidden"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\[\]$/,ac=/\r?\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)dc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join("&").replace($b,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,"\r\n")}}):{name:b.name,value:c.replace(ac,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&"withCredentials"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d["X-Requested-With"]||(d["X-Requested-With"]="XMLHttpRequest");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+"");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,"string"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=""}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=d.head||n("head")[0]||d.documentElement;return{send:function(e,f){b=d.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=jc.pop()||n.expando+"_"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&kc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?("undefined"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({
            +padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});
            diff --git a/dist/assets/js/vendor/pangu.min.js b/dist/assets/js/vendor/pangu.min.js
            new file mode 100644
            index 0000000000..e8f4305b37
            --- /dev/null
            +++ b/dist/assets/js/vendor/pangu.min.js
            @@ -0,0 +1,10 @@
            +/*!
            + * pangu.js
            + * --------
            + * @version: 3.3.0
            + * @homepage: https://github.com/vinta/pangu.js
            + * @license: MIT
            + * @author: Vinta Chen <vinta.chen@gmail.com> (https://github.com/vinta)
            + */
            +!function(e,u){"object"==typeof exports&&"object"==typeof module?module.exports=u():"function"==typeof define&&define.amd?define("pangu",[],u):"object"==typeof exports?exports.pangu=u():e.pangu=u()}(this,function(){return function(e){function u(a){if(f[a])return f[a].exports;var t=f[a]={exports:{},id:a,loaded:!1};return e[a].call(t.exports,t,t.exports,u),t.loaded=!0,t.exports}var f={};return u.m=e,u.c=f,u.p="",u(0)}([function(e,u,f){"use strict";function a(e,u){if(!(e instanceof u))throw new TypeError("Cannot call a class as a function")}function t(e,u){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!u||"object"!=typeof u&&"function"!=typeof u?e:u}function n(e,u){if("function"!=typeof u&&null!==u)throw new TypeError("Super expression must either be null or a function, not "+typeof u);e.prototype=Object.create(u&&u.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),u&&(Object.setPrototypeOf?Object.setPrototypeOf(e,u):e.__proto__=u)}var i=function(){function e(e,u){for(var f=0;f<u.length;f++){var a=u[f];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}return function(u,f,a){return f&&e(u.prototype,f),a&&e(u,a),u}}(),r=f(1).Pangu,o=8,s=function(e){function u(){a(this,u);var e=t(this,Object.getPrototypeOf(u).call(this));return e.topTags=/^(html|head|body|#document)$/i,e.ignoreTags=/^(script|code|pre|textarea)$/i,e.spaceSensitiveTags=/^(a|del|pre|s|strike|u)$/i,e.spaceLikeTags=/^(br|hr|i|img|pangu)$/i,e.blockTags=/^(div|h1|h2|h3|h4|h5|h6|p)$/i,e}return n(u,e),i(u,[{key:"canIgnoreNode",value:function(e){for(var u=e.parentNode;u&&u.nodeName&&u.nodeName.search(this.topTags)===-1;){if(u.nodeName.search(this.ignoreTags)>=0||u.isContentEditable||"true"===u.getAttribute("g_editable"))return!0;u=u.parentNode}return!1}},{key:"isFirstTextChild",value:function(e,u){for(var f=e.childNodes,a=0;a<f.length;a++){var t=f[a];if(t.nodeType!==o&&t.textContent)return t===u}return!1}},{key:"isLastTextChild",value:function(e,u){for(var f=e.childNodes,a=f.length-1;a>-1;a--){var t=f[a];if(t.nodeType!==o&&t.textContent)return t===u}return!1}},{key:"spacingNodeByXPath",value:function(e,u){for(var f=document.evaluate(e,u,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null),a=void 0,t=void 0,n=f.snapshotLength-1;n>-1;--n)if(a=f.snapshotItem(n),this.canIgnoreNode(a))t=a;else{var i=this.spacing(a.data);if(a.data!==i&&(a.data=i),t){if(a.nextSibling&&a.nextSibling.nodeName.search(this.spaceLikeTags)>=0){t=a;continue}var r=a.data.toString().substr(-1)+t.data.toString().substr(0,1),o=this.spacing(r);if(o!==r){for(var s=t;s.parentNode&&s.nodeName.search(this.spaceSensitiveTags)===-1&&this.isFirstTextChild(s.parentNode,s);)s=s.parentNode;for(var c=a;c.parentNode&&c.nodeName.search(this.spaceSensitiveTags)===-1&&this.isLastTextChild(c.parentNode,c);)c=c.parentNode;if(c.nextSibling&&c.nextSibling.nodeName.search(this.spaceLikeTags)>=0){t=a;continue}if(c.nodeName.search(this.blockTags)===-1)if(s.nodeName.search(this.spaceSensitiveTags)===-1)s.nodeName.search(this.ignoreTags)===-1&&s.nodeName.search(this.blockTags)===-1&&(t.previousSibling?t.previousSibling.nodeName.search(this.spaceLikeTags)===-1&&(t.data=" "+t.data):this.canIgnoreNode(t)||(t.data=" "+t.data));else if(c.nodeName.search(this.spaceSensitiveTags)===-1)a.data=a.data+" ";else{var d=document.createElement("pangu");d.innerHTML=" ",s.previousSibling?s.previousSibling.nodeName.search(this.spaceLikeTags)===-1&&s.parentNode.insertBefore(d,s):s.parentNode.insertBefore(d,s),d.previousElementSibling||d.parentNode&&d.parentNode.removeChild(d)}}}t=a}}},{key:"spacingNode",value:function(e){var u=".//*/text()[normalize-space(.)]";this.spacingNodeByXPath(u,e)}},{key:"spacingElementById",value:function(e){var u='id("'+e+'")//text()';this.spacingNodeByXPath(u,document)}},{key:"spacingElementByClassName",value:function(e){var u='//*[contains(concat(" ", normalize-space(@class), " "), "'+e+'")]//text()';this.spacingNodeByXPath(u,document)}},{key:"spacingElementByTagName",value:function(e){var u="//"+e+"//text()";this.spacingNodeByXPath(u,document)}},{key:"spacingPageTitle",value:function(){var e="/html/head/title/text()";this.spacingNodeByXPath(e,document)}},{key:"spacingPageBody",value:function(){for(var e="/html/body//*/text()[normalize-space(.)]",u=["script","style","textarea"],f=0;f<u.length;f++){var a=u[f];e+='[translate(name(..),"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")!="'+a+'"]'}this.spacingNodeByXPath(e,document)}},{key:"spacingPage",value:function(){this.spacingPageTitle(),this.spacingPageBody()}}]),u}(r),c=new s;u=e.exports=c,u.Pangu=s},function(e,u){"use strict";function f(e,u){if(!(e instanceof u))throw new TypeError("Cannot call a class as a function")}var a=function(){function e(e,u){for(var f=0;f<u.length;f++){var a=u[f];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}return function(u,f,a){return f&&e(u.prototype,f),a&&e(u,a),u}}(),t=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(["])/g,n=/(["])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,i=/(["']+)(\s*)(.+?)(\s*)(["']+)/g,r=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])( )(')([A-Za-z])/g,o=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(#)([A-Za-z0-9\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]+)(#)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,s=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(#([^ ]))/g,c=/(([^ ])#)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,d=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\+\-\*\/=&\\|<>])([A-Za-z0-9])/g,p=/([A-Za-z0-9])([\+\-\*\/=&\\|<>])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,l=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c]+(.*?)[\)\]\}>\u201d]+)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,g=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c>])/g,h=/([\)\]\}>\u201d<])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,v=/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/,b=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([~!;:,\.\?\u2026])([A-Za-z0-9])/g,y=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([A-Za-z0-9`\$%\^&\*\-=\+\\\|\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])/g,m=/([A-Za-z0-9`~\$%\^&\*\-=\+\\\|\/!;:,\.\?\u00a1-\u00ff\u2022\u2026\u2027\u2150-\u218f])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,$=function(){function e(){f(this,e)}return a(e,[{key:"spacing",value:function(e){var u=e;u=u.replace(t,"$1 $2"),u=u.replace(n,"$1 $2"),u=u.replace(i,"$1$3$5"),u=u.replace(r,"$1$3$4"),u=u.replace(o,"$1 $2$3$4 $5"),u=u.replace(s,"$1 $2"),u=u.replace(c,"$1 $3"),u=u.replace(d,"$1 $2 $3"),u=u.replace(p,"$1 $2 $3");var f=u,a=u.replace(l,"$1 $2 $4");return u=a,f===a&&(u=u.replace(g,"$1 $2"),u=u.replace(h,"$1 $2")),u=u.replace(v,"$1$3$5"),u=u.replace(b,"$1$2 $3"),u=u.replace(y,"$1 $2"),u=u.replace(m,"$1 $2")}},{key:"spacingText",value:function(e){var u=arguments.length<=1||void 0===arguments[1]?function(){}:arguments[1];try{var f=this.spacing(e);u(null,f)}catch(a){u(a)}}}]),e}(),N=new $;u=e.exports=N,u.Pangu=$}])});
            +//# sourceMappingURL=pangu.min.js.map
            \ No newline at end of file
            diff --git a/dist/assets/js/vendor/prism.js b/dist/assets/js/vendor/prism.js
            new file mode 100644
            index 0000000000..1a99ea34c6
            --- /dev/null
            +++ b/dist/assets/js/vendor/prism.js
            @@ -0,0 +1,10 @@
            +/* http://prismjs.com/download.html?themes=prism-coy&languages=markup+css+clike+javascript+css-extras+java&plugins=line-numbers+normalize-whitespace */
            +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function(e){var t=n.util.type(e);switch(t){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=n.util.clone(e[r]));return a;case"Array":return e.map&&e.map(function(e){return n.util.clone(e)})}return e}},languages:{extend:function(e,t){var a=n.util.clone(n.languages[e]);for(var r in t)a[r]=t[r];return a},insertBefore:function(e,t,a,r){r=r||n.languages;var i=r[e];if(2==arguments.length){a=arguments[1];for(var l in a)a.hasOwnProperty(l)&&(i[l]=a[l]);return i}var o={};for(var s in i)if(i.hasOwnProperty(s)){if(s==t)for(var l in a)a.hasOwnProperty(l)&&(o[l]=a[l]);o[s]=i[s]}return n.languages.DFS(n.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=o)}),r[e]=o},DFS:function(e,t,a,r){r=r||{};for(var i in e)e.hasOwnProperty(i)&&(t.call(e,i,e[i],a||i),"Object"!==n.util.type(e[i])||r[n.util.objId(e[i])]?"Array"!==n.util.type(e[i])||r[n.util.objId(e[i])]||(r[n.util.objId(e[i])]=!0,n.languages.DFS(e[i],t,i,r)):(r[n.util.objId(e[i])]=!0,n.languages.DFS(e[i],t,null,r)))}},plugins:{},highlightAll:function(e,t){var a={callback:t,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};n.hooks.run("before-highlightall",a);for(var r,i=a.elements||document.querySelectorAll(a.selector),l=0;r=i[l++];)n.highlightElement(r,e===!0,a.callback)},highlightElement:function(t,a,r){for(var i,l,o=t;o&&!e.test(o.className);)o=o.parentNode;o&&(i=(o.className.match(e)||[,""])[1].toLowerCase(),l=n.languages[i]),t.className=t.className.replace(e,"").replace(/\s+/g," ")+" language-"+i,o=t.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+i);var s=t.textContent,u={element:t,language:i,grammar:l,code:s};if(n.hooks.run("before-sanity-check",u),!u.code||!u.grammar)return n.hooks.run("complete",u),void 0;if(n.hooks.run("before-highlight",u),a&&_self.Worker){var c=new Worker(n.filename);c.onmessage=function(e){u.highlightedCode=e.data,n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(u.element),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},c.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else u.highlightedCode=n.highlight(u.code,u.grammar,u.language),n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(t),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},highlight:function(e,t,r){var i=n.tokenize(e,t);return a.stringify(n.util.encode(i),r)},tokenize:function(e,t){var a=n.Token,r=[e],i=t.rest;if(i){for(var l in i)t[l]=i[l];delete t.rest}e:for(var l in t)if(t.hasOwnProperty(l)&&t[l]){var o=t[l];o="Array"===n.util.type(o)?o:[o];for(var s=0;s<o.length;++s){var u=o[s],c=u.inside,g=!!u.lookbehind,h=!!u.greedy,f=0,d=u.alias;if(h&&!u.pattern.global){var p=u.pattern.toString().match(/[imuy]*$/)[0];u.pattern=RegExp(u.pattern.source,p+"g")}u=u.pattern||u;for(var m=0,y=0;m<r.length;y+=(r[m].matchedStr||r[m]).length,++m){var v=r[m];if(r.length>e.length)break e;if(!(v instanceof a)){u.lastIndex=0;var b=u.exec(v),k=1;if(!b&&h&&m!=r.length-1){if(u.lastIndex=y,b=u.exec(e),!b)break;for(var w=b.index+(g?b[1].length:0),_=b.index+b[0].length,A=m,S=y,P=r.length;P>A&&_>S;++A)S+=(r[A].matchedStr||r[A]).length,w>=S&&(++m,y=S);if(r[m]instanceof a||r[A-1].greedy)continue;k=A-m,v=e.slice(y,S),b.index-=y}if(b){g&&(f=b[1].length);var w=b.index+f,b=b[0].slice(f),_=w+b.length,x=v.slice(0,w),O=v.slice(_),j=[m,k];x&&j.push(x);var N=new a(l,c?n.tokenize(b,c):b,d,b,h);j.push(N),O&&j.push(O),Array.prototype.splice.apply(r,j)}}}}}return r},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,i=0;r=a[i++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.matchedStr=a||null,this.greedy=!!r};if(a.stringify=function(e,t,r){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join("");var i={type:e.type,content:a.stringify(e.content,t,r),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:r};if("comment"==i.type&&(i.attributes.spellcheck="true"),e.alias){var l="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(i.classes,l)}n.hooks.run("wrap",i);var o="";for(var s in i.attributes)o+=(o?" ":"")+s+'="'+(i.attributes[s]||"")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+(o?" "+o:"")+">"+i.content+"</"+i.tag+">"},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,r=t.code,i=t.immediateClose;_self.postMessage(n.highlight(r,n.languages[a],a)),i&&_self.close()},!1),_self.Prism):_self.Prism;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(n.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
            +Prism.languages.markup={comment:/<!--[\w\W]*?-->/,prolog:/<\?[\w\W]+?\?>/,doctype:/<!DOCTYPE[\w\W]+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&amp;/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup;
            +Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:{pattern:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/(<style[\w\W]*?>)[\w\W]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag));
            +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/};
            +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*\*?|\/|~|\^|%|\.{3}/}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\\\|\\?[^\\])*?`/,greedy:!0,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<script[\w\W]*?>)[\w\W]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript;
            +Prism.languages.css.selector={pattern:/[^\{\}\s][^\{\}]*(?=\s*\{)/,inside:{"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+(?:\(.*\))?/,"class":/\.[-:\.\w]+/,id:/#[-:\.\w]+/,attribute:/\[[^\]]+\]/}},Prism.languages.insertBefore("css","function",{hexcode:/#[\da-f]{3,6}/i,entity:/\\[\da-f]{1,8}/i,number:/[\d%\.]+/});
            +Prism.languages.java=Prism.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,operator:{pattern:/(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<<?=?|>>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,lookbehind:!0}}),Prism.languages.insertBefore("java","function",{annotation:{alias:"punctuation",pattern:/(^|[^.])@\w+/,lookbehind:!0}});
            +!function(){"undefined"!=typeof self&&self.Prism&&self.document&&Prism.hooks.add("complete",function(e){if(e.code){var t=e.element.parentNode,s=/\s*\bline-numbers\b\s*/;if(t&&/pre/i.test(t.nodeName)&&(s.test(t.className)||s.test(e.element.className))&&!e.element.querySelector(".line-numbers-rows")){s.test(e.element.className)&&(e.element.className=e.element.className.replace(s,"")),s.test(t.className)||(t.className+=" line-numbers");var n,a=e.code.match(/\n(?!$)/g),l=a?a.length+1:1,r=new Array(l+1);r=r.join("<span></span>"),n=document.createElement("span"),n.setAttribute("aria-hidden","true"),n.className="line-numbers-rows",n.innerHTML=r,t.hasAttribute("data-start")&&(t.style.counterReset="linenumber "+(parseInt(t.getAttribute("data-start"),10)-1)),e.element.appendChild(n)}}})}();
            +!function(){function e(e){this.defaults=r({},e)}function n(e){return e.replace(/-(\w)/g,function(e,n){return n.toUpperCase()})}function t(e){for(var n=0,t=0;t<e.length;++t)e.charCodeAt(t)=="	".charCodeAt(0)&&(n+=3);return e.length+n}if("undefined"!=typeof self&&self.Prism&&self.document){var r=Object.assign||function(e,n){for(var t in n)n.hasOwnProperty(t)&&(e[t]=n[t]);return e};e.prototype={setDefaults:function(e){this.defaults=r(this.defaults,e)},normalize:function(e,t){t=r(this.defaults,t);for(var i in t){var o=n(i);"normalize"!==i&&"setDefaults"!==o&&t[i]&&this[o]&&(e=this[o].call(this,e,t[i]))}return e},leftTrim:function(e){return e.replace(/^\s+/,"")},rightTrim:function(e){return e.replace(/\s+$/,"")},tabsToSpaces:function(e,n){return n=0|n||4,e.replace(/\t/g,new Array(++n).join(" "))},spacesToTabs:function(e,n){return n=0|n||4,e.replace(new RegExp(" {"+n+"}","g"),"	")},removeTrailing:function(e){return e.replace(/\s*?$/gm,"")},removeInitialLineFeed:function(e){return e.replace(/^(?:\r?\n|\r)/,"")},removeIndent:function(e){var n=e.match(/^[^\S\n\r]*(?=\S)/gm);return n&&n[0].length?(n.sort(function(e,n){return e.length-n.length}),n[0].length?e.replace(new RegExp("^"+n[0],"gm"),""):e):e},indent:function(e,n){return e.replace(/^[^\S\n\r]*(?=\S)/gm,new Array(++n).join("	")+"$&")},breakLines:function(e,n){n=n===!0?80:0|n||80;for(var r=e.split("\n"),i=0;i<r.length;++i)if(!(t(r[i])<=n)){for(var o=r[i].split(/(\s+)/g),a=0,s=0;s<o.length;++s){var l=t(o[s]);a+=l,a>n&&(o[s]="\n"+o[s],a=l)}r[i]=o.join("")}return r.join("\n")}},Prism.plugins.NormalizeWhitespace=new e({"remove-trailing":!0,"remove-indent":!0,"left-trim":!0,"right-trim":!0}),Prism.hooks.add("before-highlight",function(e){var n=e.element.parentNode,t=/\bno-whitespace-normalization\b/;if(!(!e.code||!n||"pre"!==n.nodeName.toLowerCase()||e.settings&&e.settings["whitespace-normalization"]===!1||t.test(n.className)||t.test(e.element.className))){for(var r=n.childNodes,i="",o="",a=!1,s=Prism.plugins.NormalizeWhitespace,l=0;l<r.length;++l){var c=r[l];c==e.element?a=!0:"#text"===c.nodeName&&(a?o+=c.nodeValue:i+=c.nodeValue,n.removeChild(c),--l)}if(e.element.children.length&&Prism.plugins.KeepMarkup){var u=i+e.element.innerHTML+o;e.element.innerHTML=s.normalize(u,e.settings),e.code=e.element.textContent}else e.code=i+e.code+o,e.code=s.normalize(e.code,e.settings)}})}}();
            diff --git a/dist/assets/js/vendor/require.min.js b/dist/assets/js/vendor/require.min.js
            new file mode 100644
            index 0000000000..e599a6abe0
            --- /dev/null
            +++ b/dist/assets/js/vendor/require.min.js
            @@ -0,0 +1,36 @@
            +/*
            + RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
            + Available via the MIT or new BSD license.
            + see: http://github.com/jrburke/requirejs for details
            +*/
            +var requirejs,require,define;
            +(function(ca){function G(b){return"[object Function]"===M.call(b)}function H(b){return"[object Array]"===M.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function U(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function j(b,c){return s(b,c)&&b[c]}function B(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function V(b,c,d,g){c&&B(c,function(c,h){if(d||!s(b,h))g&&"object"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof
            +RegExp)?(b[h]||(b[h]={}),V(b[h],c,d,g)):b[h]=c});return b}function t(b,c){return function(){return c.apply(b,arguments)}}function da(b){throw b;}function ea(b){if(!b)return b;var c=ca;v(b.split("."),function(b){c=c[b]});return c}function C(b,c,d,g){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=g;d&&(c.originalError=d);return c}function ha(b){function c(a,e,b){var f,n,c,d,g,h,i,I=e&&e.split("/");n=I;var m=l.map,k=m&&m["*"];if(a&&"."===a.charAt(0))if(e){n=
            +I.slice(0,I.length-1);a=a.split("/");e=a.length-1;l.nodeIdCompat&&R.test(a[e])&&(a[e]=a[e].replace(R,""));n=a=n.concat(a);d=n.length;for(e=0;e<d;e++)if(c=n[e],"."===c)n.splice(e,1),e-=1;else if(".."===c)if(1===e&&(".."===n[2]||".."===n[0]))break;else 0<e&&(n.splice(e-1,2),e-=2);a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&m&&(I||k)){n=a.split("/");e=n.length;a:for(;0<e;e-=1){d=n.slice(0,e).join("/");if(I)for(c=I.length;0<c;c-=1)if(b=j(m,I.slice(0,c).join("/")))if(b=j(b,d)){f=b;
            +g=e;break a}!h&&(k&&j(k,d))&&(h=j(k,d),i=e)}!f&&h&&(f=h,g=i);f&&(n.splice(0,g,f),a=n.join("/"))}return(f=j(l.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName("script"),function(e){if(e.getAttribute("data-requiremodule")===a&&e.getAttribute("data-requirecontext")===i.contextName)return e.parentNode.removeChild(e),!0})}function g(a){var e=j(l.paths,a);if(e&&H(e)&&1<e.length)return e.shift(),i.require.undef(a),i.require([a]),!0}function u(a){var e,b=a?a.indexOf("!"):-1;-1<b&&(e=a.substring(0,
            +b),a=a.substring(b+1,a.length));return[e,a]}function m(a,e,b,f){var n,d,g=null,h=e?e.name:null,l=a,m=!0,k="";a||(m=!1,a="_@r"+(M+=1));a=u(a);g=a[0];a=a[1];g&&(g=c(g,h,f),d=j(p,g));a&&(g?k=d&&d.normalize?d.normalize(a,function(a){return c(a,h,f)}):c(a,h,f):(k=c(a,h,f),a=u(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!d&&!b?"_unnormalized"+(Q+=1):"";return{prefix:g,name:k,parentMap:e,unnormalized:!!b,url:n,originalName:l,isDefine:m,id:(g?g+"!"+k:k)+b}}function q(a){var e=a.id,b=j(k,e);b||(b=k[e]=new i.Module(a));
            +return b}function r(a,e,b){var f=a.id,n=j(k,f);if(s(p,f)&&(!n||n.defineEmitComplete))"defined"===e&&b(p[f]);else if(n=q(a),n.error&&"error"===e)b(n.error);else n.on(e,b)}function w(a,e){var b=a.requireModules,f=!1;if(e)e(a);else if(v(b,function(e){if(e=j(k,e))e.error=a,e.events.error&&(f=!0,e.emit("error",a))}),!f)h.onError(a)}function x(){S.length&&(ia.apply(A,[A.length,0].concat(S)),S=[])}function y(a){delete k[a];delete W[a]}function F(a,e,b){var f=a.map.id;a.error?a.emit("error",a.error):(e[f]=
            +!0,v(a.depMaps,function(f,c){var d=f.id,g=j(k,d);g&&(!a.depMatched[c]&&!b[d])&&(j(e,d)?(a.defineDep(c,p[d]),a.check()):F(g,e,b))}),b[f]=!0)}function D(){var a,e,b=(a=1E3*l.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],c=[],h=!1,k=!0;if(!X){X=!0;B(W,function(a){var i=a.map,m=i.id;if(a.enabled&&(i.isDefine||c.push(a),!a.error))if(!a.inited&&b)g(m)?h=e=!0:(f.push(m),d(m));else if(!a.inited&&(a.fetched&&i.isDefine)&&(h=!0,!i.prefix))return k=!1});if(b&&f.length)return a=C("timeout","Load timeout for modules: "+
            +f,null,f),a.contextName=i.contextName,w(a);k&&v(c,function(a){F(a,{},{})});if((!b||e)&&h)if((z||fa)&&!Y)Y=setTimeout(function(){Y=0;D()},50);X=!1}}function E(a){s(p,a[0])||q(m(a[0],null,!0)).init(a[1],a[2])}function K(a){var a=a.currentTarget||a.srcElement,e=i.onScriptLoad;a.detachEvent&&!Z?a.detachEvent("onreadystatechange",e):a.removeEventListener("load",e,!1);e=i.onScriptError;(!a.detachEvent||Z)&&a.removeEventListener("error",e,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function L(){var a;
            +for(x();A.length;){a=A.shift();if(null===a[0])return w(C("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));E(a)}}var X,$,i,N,Y,l={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},k={},W={},aa={},A=[],p={},T={},ba={},M=1,Q=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?p[a.map.id]=a.exports:a.exports=p[a.map.id]={}},module:function(a){return a.module?
            +a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return j(l.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};$=function(a){this.events=j(aa,a.id)||{};this.map=a;this.shim=j(l.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};$.prototype={init:function(a,e,b,f){f=f||{};if(!this.inited){this.factory=e;if(b)this.on("error",b);else this.events.error&&(b=t(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=
            +b;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,e){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=e)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],t(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=
            +this.map.url;T[a]||(T[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,e,b=this.map.id;e=this.depExports;var f=this.exports,c=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&&
            +(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=
            +this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f);
            +if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval",
            +"fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b,
            +a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(N,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m,
            +nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b,
            +a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild=
            +!0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(N,f))return N[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}L();i.nextTick(function(){L();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==
            +d&&(!("."===g||".."===g)||1<d))e=b.substring(d,b.length),b=b.substring(0,d);return i.nameToUrl(c(b,a&&a.id,!0),e,!0)},defined:function(b){return s(p,m(b,a,!1,!0).id)},specified:function(b){b=m(b,a,!1,!0).id;return s(p,b)||s(k,b)}});a||(g.undef=function(b){x();var c=m(b,a,!0),e=j(k,b);d(b);delete p[b];delete T[c.url];delete aa[b];U(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&(aa[b]=e.events),y(b))});return g},enable:function(a){j(k,a.id)&&q(a).enable()},completeLoad:function(a){var b,
            +c,f=j(l.shim,a)||{},d=f.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=j(k,a);if(!b&&!s(p,a)&&c&&!c.inited){if(l.enforceDefine&&(!d||!ea(d)))return g(a)?void 0:w(C("nodefine","No define call for "+a,null,[a]));E([a,f.deps||[],f.exportsFn])}D()},nameToUrl:function(a,b,c){var f,d,g;(f=j(l.pkgs,a))&&(a=f);if(f=j(ba,a))return i.nameToUrl(f,b,c);if(h.jsExtRegExp.test(a))f=a+(b||"");else{f=l.paths;a=a.split("/");for(d=a.length;0<d;d-=1)if(g=a.slice(0,
            +d).join("/"),g=j(f,g)){H(g)&&(g=g[0]);a.splice(0,d,g);break}f=a.join("/");f+=b||(/^data\:|\?/.test(f)||c?"":".js");f=("/"===f.charAt(0)||f.match(/^[\w\+\.\-]+:/)?"":l.baseUrl)+f}return l.urlArgs?f+((-1===f.indexOf("?")?"?":"&")+l.urlArgs):f},load:function(a,b){h.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=K(a),i.completeLoad(a.id)},onScriptError:function(a){var b=K(a);if(!g(b.id))return w(C("scripterror",
            +"Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var h,x,y,D,K,E,P,L,q,Q,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,R=/\.js$/,ja=/^\.\//;x=Object.prototype;var M=x.toString,ga=x.hasOwnProperty,ia=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),fa=!z&&"undefined"!==typeof importScripts,ka=z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,
            +Z="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},r={},S=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(G(requirejs))return;r=requirejs;requirejs=void 0}"undefined"!==typeof require&&!G(require)&&(r=require,require=void 0);h=requirejs=function(b,c,d,g){var u,m="_";!H(b)&&"string"!==typeof b&&(u=b,H(c)?(b=c,c=d,d=g):b=[]);u&&u.context&&(m=u.context);(g=j(F,m))||(g=F[m]=h.s.newContext(m));u&&g.configure(u);return g.require(b,c,d)};h.config=function(b){return h(b)};
            +h.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=h);h.version="2.1.11";h.jsExtRegExp=/^\/|:|\?|\.js$/;h.isBrowser=z;x=h.s={contexts:F,newContext:ha};h({});v(["toUrl","undef","defined","specified"],function(b){h[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))y=x.head=D.parentNode;h.onError=da;h.createNode=function(b){var c=
            +b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};h.load=function(b,c,d){var g=b&&b.config||{};if(z)return g=h.createNode(g,c,d),g.setAttribute("data-requirecontext",b.contextName),g.setAttribute("data-requiremodule",c),g.attachEvent&&!(g.attachEvent.toString&&0>g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)):
            +(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,L=g,D?y.insertBefore(g,D):y.appendChild(g),L=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(K=b.getAttribute("data-main"))return q=K,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl=
            +Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=K),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=L))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b||
            +(b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this);
            diff --git a/dist/assets/learn/basics/ellipse.svg b/dist/assets/learn/basics/ellipse.svg
            new file mode 100644
            index 0000000000..48e4fe0735
            --- /dev/null
            +++ b/dist/assets/learn/basics/ellipse.svg
            @@ -0,0 +1,174 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="14 0 576.2 792" enable-background="new 14 0 576.2 792" xml:space="preserve">
            +<g>
            +	<rect x="136.5" y="135.3" fill="none" stroke="#999999" stroke-width="1.3" width="434.3" height="434.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="136.5" y1="497.3" x2="570.8" y2="497.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="136.5" y1="424.8" x2="570.8" y2="424.8"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="136.5" y1="352.4" x2="570.8" y2="352.4"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="136.5" y1="280.2" x2="570.8" y2="280.2"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="136.5" y1="207.6" x2="570.8" y2="207.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="498.3" y1="135.3" x2="498.3" y2="569.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="426.2" y1="135.3" x2="426.2" y2="569.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="353.5" y1="135.3" x2="353.5" y2="569.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="281.2" y1="135.3" x2="281.2" y2="569.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="208.9" y1="135.3" x2="208.9" y2="569.6"/>
            +</g>
            +<g>
            +	<path d="M145.1,30.7l-3.9-6.4l-3.9,6.4H132v-2c1-0.2,2-0.5,2.9-0.5l4.2-6.3l-4.1-6.3c-1,0-1.9-0.3-2.9-0.5v-1.9h5.4l3.7,6.3
            +		l3.7-6.3h5.1v1.9c-1,0.2-2,0.5-2.9,0.5l-3.9,6.1l4.2,6.4c1,0,1.9,0.3,2.9,0.5v1.9h-5.4V30.7z"/>
            +</g>
            +<g>
            +	<path d="M37.8,125.3l-6.1,17c-1.9,5.4-3.7,7.1-7.6,7.1c-0.7,0-1.7,0-2.4-0.2l0.3-2.9c0.8,0.3,1.5,0.3,2.2,0.3c1.9,0,2.9-1,4.2-4.4
            +		l0.8-1.9h-0.8l-5.4-15.1c-0.8,0-1.7-0.2-2.2-0.5v-1.9h8v1.9c-0.7,0.2-1.5,0.3-2.2,0.5l2.5,7.5c0.5,1.7,1,2.9,1.4,4.4l0,0
            +		c0.3-1.2,1-3.2,1.7-5.3l2.2-6.6c-0.8,0-1.7-0.2-2.2-0.5v-1.9h8.1v1.9C39.5,125.1,38.7,125.3,37.8,125.3z"/>
            +</g>
            +<g>
            +	<path d="M142.9,90.8c-4.8,0-8.7-2.7-8.7-10.9c0-7,4.2-10.9,9.3-10.9c4.6,0,8.7,2.5,8.7,10.7C151.9,86.9,147.8,90.8,142.9,90.8z
            +		 M143.1,71.6c-2.9,0-5.6,2.5-5.6,8.1c0,5.8,2.2,8.3,5.6,8.3c2.9,0,5.6-2.4,5.6-8.1C148.5,74.2,146.5,71.6,143.1,71.6z"/>
            +	<path d="M206.4,90.5v-2.9h6.4V72.8l-5.9,3.9l-1.2-2.7l7.8-4.8h2.7v18.3h5.6v2.9H206.4z"/>
            +	<path d="M275.6,90.5v-2.5l5.1-4.6c4.4-3.7,5.6-5.3,5.6-7.6c0-2.2-1.4-3.9-4.4-3.9c-2,0-3.9,1-5.1,1.9l-0.7-2.7
            +		c1.9-1.2,3.9-1.9,6.4-1.9c4.8,0,7.1,2.5,7.1,6.1c0,2.9-1.7,5.3-5.4,8.7l-4.2,3.6h-0.2c1.7-0.2,5.6-0.2,10.7-0.2v3.1L275.6,90.5
            +		L275.6,90.5z"/>
            +	<path d="M350.5,93.7c-1.5,0-3.1-0.2-4.4-0.5l0.5-2.9c1.2,0.5,2.7,0.7,4.2,0.7c3.7,0,6.1-2,6.1-4.8s-2-4.4-5.8-4.4
            +		c-1.2,0-2,0-3.1,0.2v-2.5h0.8c5.1,0,7.5-1.5,7.5-4.4c0-2.2-1.9-3.4-4.2-3.4c-1.9,0-3.6,0.5-5.1,1.4l-0.5-2.7
            +		c1.9-0.8,3.7-1.4,5.9-1.4c4.8,0,7,2.2,7,5.6c0,2.7-1.9,4.8-4.2,5.6l0,0c2.9,0.3,5.1,2.7,5.1,5.6C360.5,90.5,356.2,93.7,350.5,93.7z
            +		"/>
            +	<path d="M428.4,87.6v5.8h-3.1v-5.8h-10.7l-0.3-2.5l9.7-15.6h4.4v15.3h4.1v2.9H428.4z M425.3,72.3L425.3,72.3l-8,12.4c2,0,6.4,0,8,0
            +		V72.3z"/>
            +	<path d="M490.5,93.7c-1.2,0-2.5-0.2-3.9-0.3l0.3-2.7c1.2,0.3,2.7,0.5,3.9,0.5c4.2,0,6.4-2.4,6.4-5.3c0-2.9-2.4-4.6-6.3-4.6
            +		c-1.5,0-2.7,0.2-3.6,0.3v-12h12.4v3.1h-9.3v6.1c0.7,0,1.4,0,1.9,0c5.8,0,8.8,2.9,8.8,6.6C500.8,90,496.8,93.7,490.5,93.7z"/>
            +	<path d="M563.6,90.8c-4.9,0-8-3.7-8-10c0-10,5.1-14.3,11.7-14.3c0.7,0,1.7,0,2,0.2v2.7c-0.8-0.2-1.5-0.2-2.2-0.2
            +		c-4.6,0-7,2.5-8,7.5c-0.2,0.3-0.2,1-0.3,1.9l0,0c1.2-1.9,3.2-3.1,5.6-3.1c4.8,0,7.3,3.1,7.3,6.8C571.6,87.6,568.6,90.8,563.6,90.8z
            +		 M563.8,78.1c-2.9,0-4.6,2.5-4.6,4.6c0,2.9,1.7,5.4,4.8,5.4c2.7,0,4.6-2,4.6-5.3C568.6,80.1,567,78.1,563.8,78.1z"/>
            +</g>
            +<circle fill="#808080" cx="355" cy="356.1" r="11.4"/>
            +<g>
            +	<path d="M88.4,151.1c-4.8,0-8.7-2.7-8.7-10.9c0-7,4.2-10.9,9.3-10.9c4.6,0,8.7,2.5,8.7,10.7C97.4,147.3,93.2,151.1,88.4,151.1z
            +		 M88.6,132.1c-2.9,0-5.6,2.5-5.6,8.1c0,5.8,2.2,8.3,5.6,8.3c2.9,0,5.6-2.4,5.6-8.1C94,134.6,92,132.1,88.6,132.1z"/>
            +	<path d="M81.6,221v-2.9h6.4v-14.8l-5.9,3.9l-1.2-2.7l7.8-4.8h2.7v18.3h5.6v2.9L81.6,221L81.6,221z"/>
            +	<path d="M81,291.1v-2.7l5.1-4.6c4.4-3.7,5.6-5.3,5.6-7.6c0-2.2-1.4-3.9-4.4-3.9c-2,0-3.9,1-5.1,1.9l-0.7-2.7
            +		c1.9-1.2,3.9-1.9,6.4-1.9c4.8,0,7.1,2.5,7.1,6.1c0,2.9-1.7,5.3-5.4,8.7l-4.2,3.6h-0.2c1.7-0.2,5.6-0.2,10.7-0.2v3.1L81,291.1
            +		L81,291.1z"/>
            +	<path d="M85.5,364.4c-1.5,0-3.1-0.2-4.4-0.5l0.5-2.9c1.2,0.5,2.7,0.7,4.2,0.7c3.7,0,6.1-2,6.1-4.8c0-2.5-2-4.4-5.8-4.4
            +		c-1.2,0-2,0-3.1,0.2v-2.5H84c5.1,0,7.5-1.5,7.5-4.4c0-2.2-1.9-3.4-4.2-3.4c-1.9,0-3.6,0.5-5.1,1.4l-0.5-2.7
            +		c1.9-0.8,3.7-1.4,5.9-1.4c4.8,0,7,2.2,7,5.6c0,2.7-1.9,4.8-4.2,5.6l0,0c2.9,0.3,5.1,2.7,5.1,5.6C95.7,361.2,91.5,364.4,85.5,364.4z
            +		"/>
            +	<path d="M93.3,428.4v5.8h-3.1v-5.8H79.6l-0.3-2.5l9.7-15.4h4.4v15.3h4.1v2.9L93.3,428.4L93.3,428.4z M90.3,413.1L90.3,413.1
            +		l-8,12.4c2,0,6.4,0,8,0V413.1z"/>
            +	<path d="M85.4,504.6c-1.2,0-2.5-0.2-3.9-0.3l0.3-2.7c1.2,0.3,2.7,0.5,3.9,0.5c4.2,0,6.4-2.4,6.4-5.3c0-2.9-2.4-4.6-6.3-4.6
            +		c-1.5,0-2.7,0.2-3.6,0.3v-12h12.4v3.1h-9.3v6.1c0.7,0,1.4,0,1.9,0c5.8,0,8.8,2.9,8.8,6.6C95.9,500.9,91.6,504.6,85.4,504.6z"/>
            +	<path d="M88.6,571.8c-4.9,0-8-3.7-8-10c0-10,5.1-14.3,11.7-14.3c0.7,0,1.7,0,2,0.2v2.7c-0.8-0.2-1.5-0.2-2.2-0.2
            +		c-4.6,0-7,2.5-8,7.5c-0.2,0.3-0.2,1-0.3,1.9l0,0c1.2-1.9,3.2-3.1,5.6-3.1c4.8,0,7.3,3.1,7.3,6.8C96.4,568.6,93.3,571.8,88.6,571.8z
            +		 M88.8,559.2c-2.9,0-4.6,2.5-4.6,4.6c0,2.9,1.7,5.4,4.8,5.4c2.7,0,4.6-2,4.6-5.3C93.3,561.1,91.8,559.2,88.8,559.2z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="138.1" y1="135.3" x2="124.4" y2="135.3"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="138.1" y1="207.9" x2="124.4" y2="207.9"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="138.1" y1="280.1" x2="124.4" y2="280.1"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="138.1" y1="352.2" x2="124.4" y2="352.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="138.1" y1="424.8" x2="124.4" y2="424.8"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="138.1" y1="498.1" x2="124.4" y2="498.1"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="138.1" y1="568.9" x2="124.4" y2="568.9"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="570.1" y1="135.1" x2="570.1" y2="121.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="497.3" y1="135.1" x2="497.3" y2="121.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="425.3" y1="135.1" x2="425.3" y2="121.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="353" y1="135.1" x2="353" y2="121.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="280.5" y1="135.1" x2="280.5" y2="121.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="207.2" y1="135.1" x2="207.2" y2="121.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="137.1" y1="135.1" x2="137.1" y2="121.2"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="38.7,267.8 30,276.5 21.6,267.8 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="30" y1="276.5" x2="30" y2="174.7"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="269.3,11.6 278,20.2 269.3,28.7 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="279.9" y1="20.2" x2="178" y2="20.2"/>
            +<g>
            +	<path d="M373.2,340.5c-5.8-5.4-8.7-10.9-8.7-17.7c0-7.1,3.4-13.1,8.8-17.8l1.9,1.9c-4.8,4.8-7.3,10-7.3,15.8
            +		c0,5.8,2.4,11.2,7.3,16.1L373.2,340.5z"/>
            +	<path d="M387.5,336.1c-1.5,0-3.1-0.2-4.4-0.5l0.5-2.9c1.2,0.5,2.7,0.7,4.2,0.7c3.7,0,6.1-2,6.1-4.8c0-2.5-2-4.4-5.8-4.4
            +		c-1.2,0-2,0-3.1,0.2v-2.5h0.8c5.1,0,7.5-1.5,7.5-4.4c0-2.2-1.9-3.4-4.2-3.4c-1.9,0-3.6,0.5-5.1,1.4l-0.5-2.7
            +		c1.9-0.8,3.7-1.4,5.9-1.4c4.8,0,7,2.2,7,5.6c0,2.7-1.9,4.8-4.2,5.6l0,0c2.9,0.3,5.1,2.7,5.1,5.6
            +		C397.3,332.7,393.2,336.1,387.5,336.1z"/>
            +	<path d="M405.6,337.3c3.6-1,4.8-2.5,4.8-3.9c0-2.2-1.9-2.2-1.9-4.1c0-1.5,1-2.5,2.4-2.5c2.2,0,3.2,2,3.2,4.4c0,4.4-2.9,7-8.1,8.1
            +		L405.6,337.3z"/>
            +	<path d="M429.6,336.1c-1.5,0-3.1-0.2-4.4-0.5l0.5-2.9c1.2,0.5,2.7,0.7,4.2,0.7c3.7,0,6.1-2,6.1-4.8c0-2.5-2-4.4-5.8-4.4
            +		c-1.2,0-2,0-3.1,0.2v-2.5h0.8c5.1,0,7.5-1.5,7.5-4.4c0-2.2-1.9-3.4-4.2-3.4c-1.9,0-3.6,0.5-5.1,1.4l-0.5-2.7
            +		c1.9-0.8,3.7-1.4,5.9-1.4c4.8,0,7,2.2,7,5.6c0,2.7-1.9,4.8-4.2,5.6l0,0c2.9,0.3,5.1,2.7,5.1,5.6
            +		C439.6,332.7,435.3,336.1,429.6,336.1z"/>
            +	<path d="M449.9,305c5.8,5.4,8.7,10.9,8.7,17.7c0,7.1-3.4,13.1-8.8,17.8l-1.9-1.9c4.8-4.8,7.3-10,7.3-15.8s-2.4-11.2-7.3-16.1
            +		L449.9,305z"/>
            +</g>
            +<g>
            +	<path fill="#808080" d="M104.4,667.9V666c1-0.2,1.9-0.3,3.1-0.5v-19c-1,0-2-0.3-3.1-0.5v-1.9h15.3v5.6h-2.2c-0.2-1.2-0.3-2-0.5-2.9
            +		h-6.3v7.8h5.1c0.2-0.8,0.3-1.7,0.5-2.4h1.9v7.1h-1.9c-0.2-0.8-0.3-1.7-0.5-2.4h-5.1v8.5h6.3c0.2-1,0.3-1.9,0.5-3.1h2.2v5.6
            +		L104.4,667.9L104.4,667.9z"/>
            +	<path fill="#808080" d="M135.1,667.9l-3.9-6.4l-3.9,6.4H122V666c1-0.2,2-0.5,2.9-0.5l4.2-6.3l-4.1-6.3c-1,0-1.9-0.3-2.9-0.5v-1.9
            +		h5.4l3.7,6.3l3.7-6.3h5.1v1.9c-1,0.2-2,0.5-2.9,0.5l-3.9,6.1l4.2,6.4c1,0,1.9,0.3,2.9,0.5v1.9L135.1,667.9L135.1,667.9z"/>
            +	<path fill="#808080" d="M153.1,667.9c0-1.4,0-2.4,0.2-3.4l0,0c-0.8,2-3.1,3.7-5.9,3.7c-2.9,0-4.9-1.9-4.9-4.6
            +		c0-3.7,3.9-5.9,10.4-5.9v-1.4c0-2.4-0.8-3.9-3.6-3.9c-1,0-2.2,0.2-3.2,0.5c0,0.8-0.3,1.9-0.5,2.9h-1.9v-4.8c1.9-0.5,3.9-1,5.9-1
            +		c5.3,0,6.4,2.2,6.4,5.8v9.3c0.8,0.2,1.9,0.3,2.9,0.3v1.9C157.3,667.7,155,667.9,153.1,667.9z M152.9,659.7c-5.6,0-7.3,1.4-7.3,3.2
            +		c0,1.5,1,2.5,2.5,2.5c2.7,0,4.8-2.7,4.8-5.6V659.7z"/>
            +	<path fill="#808080" d="M185.5,667.9v-11.2c0-2.4-0.5-3.9-2.7-3.9c-2.4,0-4.9,2.5-4.9,6.8v5.9c1,0,1.9,0.2,2.9,0.5v1.9h-6.1v-11.2
            +		c0-2.2-0.5-3.9-2.9-3.9c-2.5,0-4.9,2.9-4.9,6.8v5.9c1,0,1.9,0.2,2.7,0.5v1.9h-9.2V666c1-0.2,1.9-0.3,3.1-0.5v-12.7
            +		c-0.8-0.2-2-0.3-3.1-0.3v-1.9c1.9-0.2,4.2-0.3,6.1-0.3c0,1-0.2,2.5-0.3,3.7l0,0c1-2.4,3.2-4.1,5.9-4.1c3.7,0,4.8,2.5,4.9,3.9
            +		c0.7-1.7,2.5-3.9,5.9-3.9c3.2,0,5.3,1.9,5.3,5.6v9.7c1,0,2,0.3,2.9,0.5v1.9L185.5,667.9L185.5,667.9z"/>
            +	<path fill="#808080" d="M201.5,668c-1.2,0-1.9,0-2.9-0.2v6.3c1,0,2,0.3,3.1,0.5v1.9h-9.3v-1.9c1-0.2,1.9-0.3,2.9-0.5v-21.2
            +		c-0.8-0.2-1.9-0.3-2.9-0.3v-1.9c1.9-0.2,4.1-0.3,5.9-0.3c0,1-0.2,2.5-0.3,3.6l0,0c1-2.4,3.1-3.9,5.8-3.9c4.1,0,6.4,2.9,6.4,8.3
            +		C210.5,664.5,207.2,668,201.5,668z M203.3,652.6c-3.1,0-4.8,3.7-4.8,6.6v5.6c1,0.3,1.9,0.5,3.1,0.5c3.2,0,5.6-1.9,5.6-7
            +		C207.2,654.8,205.9,652.6,203.3,652.6z"/>
            +	<path fill="#808080" d="M212.5,667.9V666c0.8-0.2,1.9-0.3,2.9-0.5v-20.7c-0.8-0.2-1.9-0.3-3.1-0.3v-1.9c1.9-0.2,4.1-0.3,6.1-0.3
            +		v23.3c1,0,2,0.3,2.9,0.5v1.9H212.5L212.5,667.9z"/>
            +	<path fill="#808080" d="M238.3,659.2h-11.4c-0.2,4.6,1.9,6.4,5.6,6.4c1.7,0,3.4-0.3,5.1-1l0.5,2.4c-1.9,0.7-3.9,1.2-5.9,1.2
            +		c-5.4,0-8.1-2.7-8.1-9c0-5.3,2.9-9.2,7.8-9.2c4.9,0,7,3.2,7,7.1C238.3,657.7,238.3,658.4,238.3,659.2z M231.2,652.4
            +		c-2.2,0-3.9,1.7-4.2,4.4h8.1C235.1,654.1,233.7,652.4,231.2,652.4z"/>
            +	<path fill="#808080" d="M245.6,657.8c-1.2,0-2-1-2-2s1-2,2-2c1.2,0,2,1,2,2S246.6,657.8,245.6,657.8z M245.6,668.2c-1.2,0-2-1-2-2
            +		s1-2,2-2c1.2,0,2,1,2,2S246.6,668.2,245.6,668.2z"/>
            +	<path d="M282.6,661.6h-11.4c-0.2,4.6,1.9,6.4,5.6,6.4c1.7,0,3.4-0.3,5.1-1l0.5,2.4c-1.9,0.7-3.9,1.2-5.9,1.2c-5.4,0-8.1-2.7-8.1-9
            +		c0-5.3,2.9-9.2,7.8-9.2c4.9,0,7,3.2,7,7.1C282.8,660.2,282.6,660.9,282.6,661.6z M275.5,655c-2.2,0-3.9,1.7-4.2,4.4h8.1
            +		C279.4,656.8,278,655,275.5,655z"/>
            +	<path d="M284.8,670.4v-1.9c0.8-0.2,1.9-0.3,2.9-0.5v-20.7c-0.8-0.2-1.9-0.3-3.1-0.3v-1.9c1.9-0.2,4.1-0.3,6.1-0.3V668
            +		c1,0,2,0.3,2.9,0.5v1.9H284.8L284.8,670.4z"/>
            +	<path d="M295.2,670.4v-1.9c0.8-0.2,1.9-0.3,2.9-0.5v-20.7c-0.8-0.2-1.9-0.3-3.1-0.3v-1.9c1.9-0.2,4.1-0.3,6.1-0.3V668
            +		c1,0,2,0.3,2.9,0.5v1.9H295.2L295.2,670.4z"/>
            +	<path d="M305.8,670.4v-1.9c1-0.2,1.9-0.3,3.1-0.5v-12.7c-0.8-0.2-2-0.3-3.1-0.3v-1.7c1.9-0.2,4.2-0.3,6.1-0.3V668
            +		c1,0,2,0.3,2.9,0.5v1.9H305.8L305.8,670.4z M310.6,649.5c-1.2,0-2-0.8-2-2c0-1.4,1-2,2-2s2,1,2,2
            +		C312.5,648.5,311.6,649.5,310.6,649.5z"/>
            +	<path d="M325,670.6c-1.2,0-1.9,0-2.9-0.2v6.3c1,0,2,0.3,3.1,0.5v1.9H316v-1.9c1-0.2,1.9-0.3,2.9-0.5v-21.2
            +		c-0.8-0.2-1.9-0.3-2.9-0.3v-1.9c1.9-0.2,4.1-0.3,5.9-0.3c0,1-0.2,2.5-0.3,3.6l0,0c1-2.4,3.1-3.9,5.8-3.9c4.1,0,6.4,2.9,6.4,8.3
            +		C334,667,330.6,670.6,325,670.6z M326.9,655.1c-3.1,0-4.8,3.7-4.8,6.6v5.6c1,0.3,1.9,0.5,3.1,0.5c3.2,0,5.6-1.9,5.6-7
            +		C330.6,657.5,329.4,655.1,326.9,655.1z"/>
            +	<path d="M341.7,670.7c-1.4,0-2.9-0.2-4.1-0.5v-4.9h1.9c0.2,0.8,0.3,1.9,0.5,2.7c0.7,0.2,1.4,0.2,2,0.2c2.2,0,3.9-1,3.9-2.7
            +		c0-3.9-8.8-1.7-8.8-7.6c0-2.9,2.4-5.3,7-5.3c1.4,0,2.7,0.2,4.1,0.5v4.8h-1.9c-0.2-0.8-0.3-1.9-0.5-2.7c-0.7-0.2-1.4-0.2-1.9-0.2
            +		c-2.2,0-3.6,1-3.6,2.5c0,3.9,8.8,1.9,8.8,7.5C349.1,668.2,346.1,670.7,341.7,670.7z"/>
            +	<path d="M366.8,661.6h-11.4c-0.2,4.6,1.9,6.4,5.6,6.4c1.7,0,3.4-0.3,5.1-1l0.5,2.4c-1.9,0.7-3.9,1.2-5.9,1.2c-5.4,0-8.1-2.7-8.1-9
            +		c0-5.3,2.9-9.2,7.8-9.2c4.9,0,7,3.2,7,7.1C366.9,660.2,366.9,660.9,366.8,661.6z M359.8,655c-2.2,0-3.9,1.7-4.2,4.4h8.1
            +		C363.9,656.8,362.2,655,359.8,655z"/>
            +	<path d="M390.5,678.2c-5.8-5.4-8.7-10.9-8.7-17.7c0-7.1,3.4-13.1,8.8-17.8l1.9,1.9c-4.8,4.8-7.3,10-7.3,15.8
            +		c0,5.8,2.4,11.2,7.3,16.1L390.5,678.2z"/>
            +	<path d="M405,673.6c-1.5,0-3.1-0.2-4.4-0.5l0.5-2.9c1.2,0.5,2.7,0.7,4.2,0.7c3.7,0,6.1-2,6.1-4.8c0-2.7-2-4.4-5.8-4.4
            +		c-1.2,0-2,0-3.1,0.2v-2.5h0.8c5.1,0,7.5-1.5,7.5-4.4c0-2.2-1.9-3.4-4.2-3.4c-1.9,0-3.6,0.5-5.1,1.4l-0.5-2.7
            +		c1.9-0.8,3.7-1.4,5.9-1.4c4.8,0,7,2.2,7,5.6c0,2.7-1.9,4.8-4.2,5.6l0,0c2.9,0.3,5.1,2.7,5.1,5.6C414.8,670.2,410.7,673.6,405,673.6
            +		z"/>
            +	<path d="M423.1,675c3.6-1,4.8-2.5,4.8-3.9c0-2.2-1.9-2.2-1.9-4.1c0-1.5,1-2.5,2.4-2.5c2.2,0,3.2,2,3.2,4.4c0,4.4-2.9,7-8.1,8.1
            +		L423.1,675z"/>
            +	<path d="M446.9,673.6c-1.5,0-3.1-0.2-4.4-0.5l0.5-2.9c1.2,0.5,2.7,0.7,4.2,0.7c3.7,0,6.1-2,6.1-4.8c0-2.7-2-4.4-5.8-4.4
            +		c-1.2,0-2,0-3.1,0.2v-2.5h0.8c5.1,0,7.5-1.5,7.5-4.4c0-2.2-1.9-3.4-4.2-3.4c-1.9,0-3.6,0.5-5.1,1.4l-0.5-2.7
            +		c1.9-0.8,3.7-1.4,5.9-1.4c4.8,0,7,2.2,7,5.6c0,2.7-1.9,4.8-4.2,5.6l0,0c2.9,0.3,5.1,2.7,5.1,5.6
            +		C456.9,670.2,452.8,673.6,446.9,673.6z"/>
            +	<path d="M465,675c3.6-1,4.8-2.5,4.8-3.9c0-2.2-1.9-2.2-1.9-4.1c0-1.5,1-2.5,2.4-2.5c2.2,0,3.2,2,3.2,4.4c0,4.4-2.9,7-8.1,8.1
            +		L465,675z"/>
            +	<path d="M496.8,667.4v5.8h-3.1v-5.8H483l-0.3-2.5l9.7-15.4h4.4v15.3h4.1v2.9L496.8,667.4L496.8,667.4z M493.7,652.2L493.7,652.2
            +		l-8,12.4c2,0,6.4,0,8,0V652.2z"/>
            +	<path d="M507.1,675c3.6-1,4.8-2.5,4.8-3.9c0-2.2-1.9-2.2-1.9-4.1c0-1.5,1-2.5,2.4-2.5c2.2,0,3.2,2,3.2,4.4c0,4.4-2.9,7-8.1,8.1
            +		L507.1,675z"/>
            +	<path d="M533.9,670.7c-4.9,0-8-3.7-8-10c0-10,5.1-14.3,11.7-14.3c0.7,0,1.7,0,2,0.2v2.7c-0.8-0.2-1.5-0.2-2.2-0.2
            +		c-4.6,0-7,2.5-8,7.5c-0.2,0.3-0.2,1-0.3,1.9l0,0c1.2-1.9,3.2-3.1,5.6-3.1c4.8,0,7.3,3.1,7.3,6.8
            +		C541.9,667.4,538.7,670.7,533.9,670.7z M534.1,658c-2.9,0-4.6,2.5-4.6,4.6c0,2.9,1.7,5.4,4.8,5.4c2.7,0,4.6-2,4.6-5.3
            +		C538.7,660.1,537.2,658,534.1,658z"/>
            +	<path d="M551.3,642.7c5.8,5.4,8.7,10.9,8.7,17.7c0,7.1-3.4,13.1-8.8,17.8l-1.9-1.9c4.8-4.8,7.3-10,7.3-15.8
            +		c0-5.8-2.4-11.2-7.3-16.1L551.3,642.7z"/>
            +	<path d="M576.9,675.8l-1.4-1.2c2.2-2.4,2.2-4.1,1.5-5.1c-1-1.4-0.2-3.1,1.5-3.1C581.1,666.3,582.5,670.9,576.9,675.8z M578.7,660.4
            +		c-1.2,0-2-1-2-2s1-2,2-2c1.2,0,2,1,2,2C580.8,659.5,579.8,660.4,578.7,660.4z"/>
            +</g>
            +<ellipse fill="none" stroke="#000000" stroke-width="2" cx="353.5" cy="352.4" rx="144.8" ry="217.1"/>
            +</svg>
            diff --git a/dist/assets/learn/basics/graph.svg b/dist/assets/learn/basics/graph.svg
            new file mode 100644
            index 0000000000..2c8216df5c
            --- /dev/null
            +++ b/dist/assets/learn/basics/graph.svg
            @@ -0,0 +1,139 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="-48.9 0 660.9 792" enable-background="new -48.9 0 660.9 792" xml:space="preserve">
            +<rect x="97.1" y="157.9" opacity="0.5" fill="#FFFF00" enable-background="new    " width="512.9" height="515.1"/>
            +<g enable-background="new    ">
            +	<path d="M245.1,774.6c-8.4,0-12.8-5.4-12.8-13.8c0-8.4,4.6-15,13.4-15c2.2,0,4.6,0.3,6.8,0.8v6.8h-2.7c-0.3-1.5-0.5-2.7-0.5-3.8
            +		c-1.5-0.5-2.7-0.5-4.1-0.5c-6,0-8.8,4.9-8.8,11.1c0,6.8,3.1,10.9,9.5,10.9c2.2,0,4.9-0.5,6.5-1.5l0.8,3.1
            +		C250.7,773.8,248,774.6,245.1,774.6z"/>
            +	<path d="M264.5,774.6c-5.5,0-9.2-3.1-9.2-10.4c0-6.3,3.8-10.9,10.1-10.9c5.4,0,9.2,2.8,9.2,10.4
            +		C274.5,769.7,270.9,774.6,264.5,774.6z M265,756.2c-3.1,0-5.8,2.2-5.8,7.4c0,4.9,1.9,7.4,5.8,7.4c3.1,0,5.8-2.4,5.8-7.4
            +		C270.6,759.1,268.7,756.2,265,756.2z"/>
            +	<path d="M306.6,774.1v-13.3c0-2.8-0.8-4.6-3.4-4.6c-2.8,0-5.8,3.1-5.8,8.2v6.9c1.2,0,2.4,0.3,3.4,0.5v2.2h-6.9v-13.3
            +		c0-2.7-0.5-4.6-3.4-4.6c-3.1,0-5.8,3.4-5.8,8.2v6.9c1.2,0,2.4,0.3,3.4,0.5v2.2h-10.6v-2.2c0.9-0.3,2.4-0.5,3.6-0.5v-15
            +		c-0.9-0.3-2.4-0.3-3.6-0.5v-2.2c2.2-0.3,5-0.5,7.3-0.3c0,1.2-0.3,3.1-0.3,4.3l0,0c1.2-2.8,3.8-4.9,6.9-4.9c4.3,0,5.5,2.8,5.8,4.6
            +		c0.8-1.9,3.1-4.6,6.9-4.6s6,2.2,6,6.8v11.4c1.2,0,2.4,0.3,3.4,0.5v2.2L306.6,774.1L306.6,774.1z"/>
            +	<path d="M325.6,774.3c-1.2,0-2.2,0-3.6-0.3v7.4c1.2,0,2.4,0.3,3.6,0.5v2.2h-10.9v-2.2c0.9-0.3,2.2-0.5,3.4-0.5v-25.2
            +		c-0.9-0.3-2.2-0.3-3.4-0.5v-2.2c1.9-0.3,4.9-0.5,6.9-0.3c0,1.2-0.3,3.1-0.3,4.1l0,0c1.2-2.8,3.6-4.6,6.8-4.6c4.9,0,7.4,3.4,7.4,9.6
            +		C336.2,770.2,332.4,774.3,325.6,774.3z M327.8,756.2c-3.6,0-5.5,4.3-5.5,7.9v6.8c1.2,0.3,2.2,0.5,3.6,0.5c3.8,0,6.5-2.4,6.5-8.2
            +		C332.4,758.9,331,756.2,327.8,756.2z"/>
            +	<path d="M355.3,774.1c0-1.2,0-3.1,0.3-4.3l0,0c-1.2,2.8-3.6,4.9-7.3,4.9c-4.9,0-6.3-2.8-6.3-6.5v-11.4c-0.9-0.3-2.4-0.3-3.4-0.5
            +		v-2.2c1.9-0.3,4.9-0.5,7.3-0.3v13.3c0,2.8,0.8,4.6,3.6,4.6c3.4,0,5.8-3.4,5.8-7.9v-6.9c-0.9-0.3-2.2-0.3-3.4-0.5v-2.2
            +		c1.9-0.3,4.9-0.5,6.9-0.3v17.6c0.9,0.3,2.4,0.3,3.4,0.5v2.2C360.4,774.1,357.5,774.3,355.3,774.1z"/>
            +	<path d="M372.7,774.6c-4.1,0-5.5-1.8-5.5-6.3v-11.9h-4.1v-2.8h4.1v-6.8l3.6-0.9v7.7h5.8v2.8h-5.8V767c0,3.4,0.8,4.3,2.8,4.3
            +		c0.9,0,1.9-0.3,2.7-0.3l0.5,3.1C375.5,774.3,373.9,774.6,372.7,774.6z"/>
            +	<path d="M397.1,763.7h-13.4c-0.3,5.4,1.9,7.7,6.5,7.7c1.9,0,4.1-0.5,5.8-1.2l0.5,2.8c-2.2,0.8-4.6,1.2-7.3,1.2
            +		c-6.3,0-9.6-3.4-9.6-10.6c0-6,3.4-10.9,9.2-10.9s8.2,3.8,8.2,8.4C397.4,762.1,397.4,763,397.1,763.7z M388.8,756
            +		c-2.7,0-4.6,1.9-5,5h9.6C393.4,758,391.7,756,388.8,756z"/>
            +	<path d="M414.4,757c-4.9-0.8-6.8,2.4-6.8,8.8v5.5c1.2,0,2.4,0.3,3.6,0.5v2.2h-10.9v-2.2c0.9-0.3,2.4-0.5,3.6-0.5v-15
            +		c-0.9-0.3-2.4-0.3-3.6-0.5v-2.2c2.2-0.3,4.9-0.5,7.3-0.3c0,1.2-0.3,3.1-0.5,4.9l0,0c0.9-2.8,2.8-5.8,7.4-5.4L414.4,757z"/>
            +</g>
            +<g>
            +	<rect x="97.1" y="160" fill="none" stroke="#999999" stroke-width="1.3" width="512.9" height="512.9"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="97.1" y1="587.5" x2="609.9" y2="587.5"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="97.1" y1="501.7" x2="609.9" y2="501.7"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="97.1" y1="416.5" x2="609.9" y2="416.5"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="97.1" y1="331" x2="609.9" y2="331"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="97.1" y1="245.5" x2="609.9" y2="245.5"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="524.5" y1="160" x2="524.5" y2="673.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="439.1" y1="160" x2="439.1" y2="673.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="353.4" y1="160" x2="353.4" y2="673.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="267.7" y1="160" x2="267.7" y2="673.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="182.5" y1="160" x2="182.5" y2="673.1"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M107.2,36.8l-4.6-7.7L98,36.8h-6.3v-2.4c1.2-0.3,2.4-0.5,3.6-0.5l5-7.4l-4.9-7.4c-1.2,0-2.4-0.3-3.4-0.5v-2.2h6.3l4.3,7.4
            +		l4.6-7.4h6v2.2c-1.2,0.3-2.4,0.5-3.6,0.5l-4.6,7.3l5,7.7c1.2,0,2.2,0.3,3.4,0.5v2.2H107.2L107.2,36.8L107.2,36.8z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-19.4,148.5l-7.3,20.1c-2.2,6.3-4.3,8.4-8.8,8.4c-0.8,0-1.9,0-2.8-0.3l0.3-3.4c0.9,0.3,1.8,0.5,2.7,0.5c2.2,0,3.6-1.2,5-5
            +		l0.9-2.4h-0.9l-6.3-17.9c-0.9,0-1.9-0.3-2.7-0.5v-2.2h9.5v2.2c-0.8,0.3-1.8,0.5-2.7,0.5l3.1,8.8c0.8,1.9,1.2,3.4,1.8,5l0,0
            +		c0.3-1.5,1.2-3.8,1.9-6l2.7-7.9c-0.9,0-1.9-0.3-2.7-0.5v-2.2h9.2v2.2C-17.5,148.3-18.4,148.3-19.4,148.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M104.4,107.7c-5.5,0-10.1-3.1-10.1-12.8c0-8.2,5-12.8,10.9-12.8c5.4,0,10.1,3.1,10.1,12.5
            +		C115.3,103.1,110.4,107.7,104.4,107.7z M104.8,85.1c-3.4,0-6.5,2.8-6.5,9.6c0,6.9,2.7,10,6.5,10c3.4,0,6.5-2.8,6.5-9.5
            +		C111.3,88.2,108.8,85.1,104.8,85.1z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M179.5,107.2v-3.4h7.4V86.5l-7.3,4.6l-1.2-3.1l9.2-5.5h3.1V104h6.5v3.4L179.5,107.2L179.5,107.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M261.4,107.2v-3.1l6-5.4c5.4-4.3,6.5-6.3,6.5-8.8c0-2.6-1.8-4.6-5-4.6c-2.4,0-4.6,1.2-6,2.2l-0.7-3.4
            +		c2.2-1.2,4.6-2.2,7.4-2.2c5.5,0,8.4,3.1,8.4,7.4c0,3.6-1.9,6.3-6.5,10.1l-5,4.3h-0.3c1.9-0.3,6.5-0.3,12.5-0.3v3.6L261.4,107.2
            +		L261.4,107.2L261.4,107.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M349.8,111.1c-1.8,0-3.6-0.3-5-0.8l0.8-3.4c1.5,0.5,3.1,0.8,5,0.8c4.3,0,7.3-2.4,7.3-5.5s-2.4-5-6.8-5
            +		c-1.5,0-2.4,0-3.6,0.3v-3.1h0.9c6,0,8.8-1.8,8.8-5c0-2.7-1.9-4.1-5-4.1c-2.2,0-4.1,0.8-5.8,1.8l-0.8-3.1c2.2-0.9,4.3-1.5,7.3-1.5
            +		c5.5,0,8.2,2.7,8.2,6.5c0,3.1-1.9,5.5-5,6.5l0,0c3.4,0.5,6,3.4,6,6.8C361.6,107.2,356.7,111.1,349.8,111.1z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M441.6,103.5v6.9H438v-6.9h-12.8l-0.3-3.1l11.5-18.3h5.4V100h4.9v3.4h-5v0.1H441.6z M438,85.6L438,85.6l-9.5,14.7
            +		c2.4,0,7.7,0,9.5,0V85.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M515,111.1c-1.2,0-3.1-0.3-4.6-0.5l0.3-3.4c1.5,0.5,3.4,0.5,4.6,0.5c5,0,7.7-2.8,7.7-6.3c0-3.6-2.8-5.4-7.4-5.4
            +		c-1.8,0-3.1,0.3-4.3,0.3V82.1h14.5v3.6h-11.1V93c0.8,0,1.5,0,1.9,0c6.8,0,10.4,3.6,10.4,7.9C527.3,106.7,522.3,111.1,515,111.1z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M601.7,107.7c-5.8,0-9.5-4.3-9.5-11.9c0-11.9,5.8-16.9,13.8-16.9c0.8,0,1.9,0,2.4,0.3v3.4c-0.9-0.3-1.8-0.3-2.7-0.3
            +		c-5.4,0-8.2,3.1-9.5,8.8c-0.3,0.5-0.3,1.2-0.5,2.2l0,0c1.5-2.4,3.8-3.6,6.5-3.6c5.5,0,8.4,3.6,8.4,8.2
            +		C611.2,103.5,607.2,107.7,601.7,107.7z M601.7,92.8c-3.4,0-5.4,2.8-5.4,5.4c0,3.4,1.9,6.3,5.5,6.3c3.4,0,5.4-2.4,5.4-6
            +		C607.2,94.8,605.3,92.8,601.7,92.8z"/>
            +</g>
            +<circle cx="97.1" cy="160" r="13.3"/>
            +<g enable-background="new    ">
            +	<path d="M40.2,178.8c-5.5,0-10.1-3.1-10.1-12.8c0-8.2,5-12.8,10.9-12.8c5.4,0,10.1,3.1,10.1,12.5C51.1,174.2,46,178.8,40.2,178.8z
            +		 M40.5,156.6c-3.4,0-6.5,2.8-6.5,9.6c0,6.9,2.7,10,6.5,10c3.4,0,6.5-2.8,6.5-9.5C47,159.4,44.3,156.6,40.5,156.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M32.3,261.4V258h7.4v-17.4l-7.3,4.6l-1.2-3.1l9.2-5.5h3.1v21.5H50v3.4L32.3,261.4L32.3,261.4z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M31.5,344.2v-3.1l6-5.4c5.4-4.3,6.5-6.3,6.5-8.8c0-2.7-1.8-4.6-5-4.6c-2.4,0-4.6,1.2-6,2.2l-0.8-3.4
            +		c2.2-1.2,4.6-2.2,7.4-2.2c5.5,0,8.4,3.1,8.4,7.4c0,3.6-1.9,6.3-6.5,10.1l-5,4.3h-0.3c1.9-0.3,6.5-0.3,12.5-0.3v3.6L31.5,344.2
            +		L31.5,344.2L31.5,344.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M37,430.8c-1.8,0-3.6-0.3-5-0.8l0.8-3.4c1.5,0.5,3.1,0.8,5,0.8c4.3,0,7.3-2.4,7.3-5.5s-2.4-5-6.8-5c-1.5,0-2.4,0-3.6,0.3
            +		v-3.1h0.9c6,0,8.8-1.8,8.8-5c0-2.7-1.9-4.1-5-4.1c-2.2,0-4.1,0.8-5.8,1.8l-0.8-3.1c2.2-0.9,4.3-1.5,7.3-1.5c5.5,0,8.2,2.7,8.2,6.5
            +		c0,3.1-1.9,5.5-5,6.5l0,0c3.4,0.5,6,3.4,6,6.8C48.7,426.9,43.9,430.8,37,430.8z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M46.2,506.1v6.9h-3.6v-6.9H29.8l-0.3-3.1L41,484.7h5.4v17.9h4.9v3.4L46.2,506.1L46.2,506.1z M42.5,488.2L42.5,488.2
            +		L33,502.9c2.4,0,7.7,0,9.5,0V488.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M36.9,596.2c-1.2,0-3.1-0.3-4.6-0.5l0.3-3.4c1.5,0.5,3.4,0.5,4.6,0.5c5,0,7.7-2.8,7.7-6.3c0-3.6-2.8-5.4-7.4-5.4
            +		c-1.8,0-3.1,0.3-4.3,0.3v-14.1h14.5v3.6H36.6v7.3c0.8,0,1.5,0,1.9,0c6.8,0,10.4,3.6,10.4,7.9C48.9,592,44.2,596.2,36.9,596.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M40.5,675.6c-5.8,0-9.5-4.3-9.5-11.9c0-11.9,5.8-16.9,13.8-16.9c0.8,0,1.9,0,2.4,0.3v3.4c-0.9-0.3-1.8-0.3-2.7-0.3
            +		c-5.4,0-8.2,3.1-9.5,8.8c-0.3,0.5-0.3,1.2-0.5,2.2l0,0c1.5-2.4,3.8-3.6,6.5-3.6c5.5,0,8.7,3.6,8.7,8.2
            +		C49.8,671.8,46,675.6,40.5,675.6z M40.6,660.8c-3.4,0-5.4,2.8-5.4,5.4c0,3.4,1.9,6.3,5.5,6.3c3.4,0,5.4-2.4,5.4-6
            +		C46,663.1,44.2,660.8,40.6,660.8z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="99" y1="160" x2="82.9" y2="160"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="99" y1="246" x2="82.9" y2="246"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="99" y1="331" x2="82.9" y2="331"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="99" y1="416.3" x2="82.9" y2="416.3"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="99" y1="502.2" x2="82.9" y2="502.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="99" y1="588.5" x2="82.9" y2="588.5"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="99" y1="672.3" x2="82.9" y2="672.3"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="609" y1="159.8" x2="609" y2="143.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="523.3" y1="159.8" x2="523.3" y2="143.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="438" y1="159.8" x2="438" y2="143.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="352.9" y1="159.8" x2="352.9" y2="143.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="267.2" y1="159.8" x2="267.2" y2="143.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="180.4" y1="159.8" x2="180.4" y2="143.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="97.1" y1="159.8" x2="97.1" y2="143.7"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="-18.4,316.8 -28.6,326.8 -38.7,316.8 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-28.6" y1="326.8" x2="-28.6" y2="206.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="253.9,14.1 263.9,24.2 253.9,34.3 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="266.3" y1="24.2" x2="146.4" y2="24.2"/>
            +<g id="Layer_2">
            +</g>
            +</svg>
            diff --git a/dist/assets/learn/basics/line.svg b/dist/assets/learn/basics/line.svg
            new file mode 100644
            index 0000000000..1fbbe2e460
            --- /dev/null
            +++ b/dist/assets/learn/basics/line.svg
            @@ -0,0 +1,280 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 349 523" enable-background="new 0 0 349 523" xml:space="preserve">
            +<g>
            +	<rect x="76" y="186.7" fill="none" stroke="#999999" stroke-width="1.3" width="265.6" height="265.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="76" y1="408.2" x2="341.6" y2="408.2"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="76" y1="363.8" x2="341.6" y2="363.8"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="76" y1="319.5" x2="341.6" y2="319.5"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="76" y1="275.3" x2="341.6" y2="275.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="76" y1="231" x2="341.6" y2="231"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="297.3" y1="186.7" x2="297.3" y2="452.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="253" y1="186.7" x2="253" y2="452.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="208.8" y1="186.7" x2="208.8" y2="452.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="164.5" y1="186.7" x2="164.5" y2="452.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="120.3" y1="186.7" x2="120.3" y2="452.3"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M81.3,122.9l-2.4-4l-2.3,4h-3.2v-1.2c0.6-0.1,1.2-0.3,1.8-0.3l2.6-3.8l-2.5-3.8c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.2l2.2,3.9
            +		l2.3-3.9h3.3v1.2c-0.6,0.1-1.2,0.3-1.8,0.3l-2.4,3.7l2.6,3.9c0.6,0,1.2,0.2,1.8,0.3v1.2H81.3L81.3,122.9z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M15.7,180.7L11.9,191c-1.2,3.2-2.2,4.3-4.6,4.3c-0.4,0-1,0-1.5-0.1l0.1-1.7c0.5,0.1,0.9,0.2,1.4,0.2c1.2,0,1.8-0.6,2.6-2.6
            +		l0.4-1.2H9.8l-3.3-9.2c-0.5,0-1-0.1-1.4-0.3v-1.2H10v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6c0.3,1,0.6,1.8,0.8,2.7l0,0
            +		c0.2-0.7,0.6-1.9,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.7v1.2C16.8,180.5,16.3,180.6,15.7,180.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M79.9,159.5c-2.8,0-5.3-1.7-5.3-6.6c0-4.3,2.6-6.6,5.6-6.6c2.7,0,5.3,1.6,5.3,6.5C85.5,157.1,82.9,159.5,79.9,159.5z
            +		 M80,147.9c-1.7,0-3.4,1.5-3.4,4.9c0,3.6,1.3,5.1,3.4,5.1c1.7,0,3.4-1.5,3.4-4.9C83.4,149.4,82.1,147.9,80,147.9z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M118.7,159.4v-1.7h3.9v-9.1l-3.7,2.4l-0.7-1.6l4.7-2.9h1.7v11.1h3.3v1.7H118.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M161.1,159.4v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.6s-0.8-2.4-2.6-2.4c-1.2,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.3-1.1,3.9-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-0.9,3.2-3.3,5.2l-2.6,2.2h-0.1c1-0.1,3.3-0.1,6.5-0.1v1.8h-9.2L161.1,159.4
            +		L161.1,159.4z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M206.9,161.4c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.7c0.7,0.3,1.6,0.4,2.6,0.4c2.3,0,3.7-1.3,3.7-2.9s-1.3-2.6-3.5-2.6
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.4c3.1,0,4.6-0.9,4.6-2.6c0-1.3-1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3,0.8l-0.3-1.7c1.1-0.5,2.3-0.7,3.7-0.7
            +		c2.9,0,4.3,1.4,4.3,3.4c0,1.7-1,2.9-2.6,3.3l0,0c1.8,0.2,3.1,1.7,3.1,3.4C212.9,159.4,210.5,161.4,206.9,161.4z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M254.6,157.6v3.6h-1.9v-3.6H246l-0.1-1.6l5.9-9.4h2.7v9.3h2.5v1.7L254.6,157.6L254.6,157.6z M252.6,148.2L252.6,148.2
            +		l-4.8,7.6c1.3,0,4,0,4.8,0V148.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M292.5,161.4c-0.7,0-1.6-0.1-2.4-0.2l0.1-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.8-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.1v-7.3h7.5v1.8h-5.7v3.8c0.4,0,0.8,0,1,0c3.5,0,5.3,1.8,5.3,4.1C298.8,159.1,296.3,161.4,292.5,161.4z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M337.3,159.5c-3,0-4.8-2.2-4.8-6.1c0-6.2,3-8.7,7.1-8.7c0.4,0,0.9,0,1.3,0.1v1.7c-0.4-0.1-0.9-0.1-1.4-0.1
            +		c-2.7,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1l0,0c0.7-1.2,2-1.9,3.4-1.9c2.8,0,4.4,1.8,4.4,4.2
            +		C342.2,157.6,340.2,159.5,337.3,159.5z M337.3,151.8c-1.8,0-2.8,1.5-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.7-1.3,2.7-3.2
            +		C340.2,153,339.1,151.8,337.3,151.8z"/>
            +</g>
            +<circle fill="#808080" cx="120.3" cy="275.3" r="6.9"/>
            +<circle fill="#808080" cx="296.6" cy="275.3" r="6.9"/>
            +<g enable-background="new    ">
            +	<path d="M46.5,196.4c-2.8,0-5.3-1.7-5.3-6.6c0-4.3,2.6-6.6,5.6-6.6c2.7,0,5.3,1.6,5.3,6.5C52.2,194.1,49.5,196.4,46.5,196.4z
            +		 M46.7,184.8c-1.7,0-3.4,1.5-3.4,4.9c0,3.6,1.3,5.1,3.4,5.1c1.7,0,3.4-1.5,3.4-4.9C50.1,186.4,48.7,184.8,46.7,184.8z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M42.5,239.2v-1.7h3.9v-9l-3.7,2.4l-0.7-1.6l4.7-2.9h1.7v11.1h3.3v1.7L42.5,239.2L42.5,239.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M42,282.1v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.6c0-1.4-0.8-2.4-2.6-2.4c-1.2,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.3-1.1,3.9-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-0.9,3.2-3.3,5.2l-2.6,2.2h-0.1c1-0.1,3.3-0.1,6.5-0.1v1.8H42V282.1z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M44.9,326.9c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.7c0.7,0.3,1.6,0.4,2.6,0.4c2.3,0,3.7-1.3,3.7-2.9c0-1.6-1.3-2.6-3.5-2.6
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.4c3.1,0,4.6-0.9,4.6-2.6c0-1.3-1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3,0.8l-0.3-1.7c1.1-0.5,2.3-0.7,3.7-0.7
            +		c2.9,0,4.3,1.4,4.3,3.4c0,1.7-1,2.9-2.6,3.3l0,0c1.8,0.2,3.1,1.7,3.1,3.4C51,324.9,48.5,326.9,44.9,326.9z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M49.7,366v3.6h-1.9V366h-6.6l-0.1-1.6L47,355h2.7v9.3h2.5v1.7H49.7z M47.8,356.6L47.8,356.6l-4.8,7.6c1.3,0,4,0,4.8,0
            +		V356.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M44.8,412.6c-0.7,0-1.6-0.1-2.4-0.2l0.1-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.8-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.1v-7.3h7.5v1.8h-5.7v3.8c0.4,0,0.8,0,1,0c3.5,0,5.3,1.8,5.3,4.1C51.1,410.4,48.5,412.6,44.8,412.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M46.7,453.7c-3,0-4.8-2.2-4.8-6.1c0-6.2,3-8.7,7.1-8.7c0.4,0,0.9,0,1.3,0.1v1.7c-0.4-0.1-0.9-0.1-1.4-0.1
            +		c-2.7,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1l0,0c0.7-1.2,2-1.9,3.4-1.9c2.8,0,4.4,1.8,4.4,4.2
            +		C51.6,451.7,49.6,453.7,46.7,453.7z M46.8,446c-1.8,0-2.8,1.5-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.7-1.3,2.7-3.2
            +		C49.6,447.2,48.6,446,46.8,446z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="77.1" y1="186.7" x2="68.6" y2="186.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="77.1" y1="231.1" x2="68.6" y2="231.1"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="77.1" y1="275.3" x2="68.6" y2="275.3"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="77.1" y1="319.5" x2="68.6" y2="319.5"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="77.1" y1="363.9" x2="68.6" y2="363.9"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="77.1" y1="408.6" x2="68.6" y2="408.6"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="77.1" y1="451.9" x2="68.6" y2="451.9"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="341.3" y1="186.6" x2="341.3" y2="178.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="296.7" y1="186.6" x2="296.7" y2="178.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="252.5" y1="186.6" x2="252.5" y2="178.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="208.4" y1="186.6" x2="208.4" y2="178.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="164.1" y1="186.6" x2="164.1" y2="178.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="119.2" y1="186.6" x2="119.2" y2="178.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="76.4" y1="186.6" x2="76.4" y2="178.2"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="16.3,267.8 10.9,273 5.7,267.8 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="10.9" y1="273" x2="10.9" y2="210.9"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="157.2,111.1 162.5,116.3 157.2,121.6 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="163.6" y1="116.3" x2="101.4" y2="116.3"/>
            +<g enable-background="new    ">
            +	<path d="M49.5,22.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3V8.4c-0.5-0.1-1.2-0.2-1.8-0.2V7c1.1-0.1,2.5-0.2,3.8-0.1v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2L49.5,22.7L49.5,22.7z"/>
            +	<path d="M56.1,22.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.7c-0.5-0.1-1.2-0.2-1.9-0.2V12c1.1-0.1,2.5-0.2,3.8-0.2V21
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2h-5.6V22.7z M59,9.8c-0.7,0-1.3-0.5-1.3-1.2s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C60.2,9.3,59.7,9.8,59,9.8z"/>
            +	<path d="M71.3,22.7v-6.8c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.1v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.6-0.1,1.2-0.2,1.9-0.3v-7.7c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6,0,1.6-0.1,2.2l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2L71.3,22.7L71.3,22.7z"/>
            +	<path d="M85.3,17.3h-6.9c-0.1,2.8,1,4,3.4,4c1,0,2.1-0.2,3-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.2,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6s4.2,2,4.2,4.4C85.3,16.4,85.3,16.8,85.3,17.3z M81,13.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C83.4,14.3,82.5,13.2,81,13.2z"/>
            +	<path d="M95.7,27.2c-2.5-4-3.1-7.4-3.1-10.5S93.3,9.8,95.7,6l1.4,0.7c-1.7,3-2.7,6.4-2.7,9.9c0,3.7,0.9,6.9,2.7,9.9L95.7,27.2z"/>
            +	<path d="M110.3,22.7l-2.4-4l-2.3,4h-3.2v-1.2c0.6-0.1,1.2-0.3,1.8-0.3l2.6-3.8l-2.5-3.8c-0.6,0-1.2-0.2-1.8-0.3V12h3.2l2.2,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.2,0.3-1.8,0.3l-2.4,3.7l2.6,3.9c0.6,0,1.2,0.2,1.8,0.3v1.2H110.3L110.3,22.7z"/>
            +	<path d="M116,22.7V21h3.9v-9l-3.7,2.4l-0.7-1.6l4.7-2.9h1.6V21h3.3v1.7L116,22.7L116,22.7z"/>
            +	<path d="M132.8,26l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.7-0.1-1.9,0.9-1.9C135.4,20.3,136.1,23,132.8,26z"/>
            +	<path d="M150.5,13.4l-3.8,10.3c-1.2,3.2-2.2,4.3-4.6,4.3c-0.4,0-1,0-1.5-0.1l0.1-1.7c0.5,0.1,0.9,0.2,1.4,0.2
            +		c1.2,0,1.8-0.6,2.6-2.6l0.4-1.2h-0.5l-3.3-9.2c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6
            +		c0.3,1,0.6,1.8,0.8,2.7l0,0c0.2-0.7,0.6-1.9,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.7v1.2C151.4,13.2,151,13.3,150.5,13.4z"/>
            +	<path d="M154.2,22.7V21h3.9v-9l-3.7,2.4l-0.7-1.6l4.7-2.9h1.6V21h3.3v1.7L154.2,22.7L154.2,22.7z"/>
            +	<path d="M171,26l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.7-0.1-1.9,0.9-1.9C173.6,20.3,174.3,23,171,26z"/>
            +	<path d="M186.3,22.7l-2.4-4l-2.3,4h-3.2v-1.2c0.6-0.1,1.2-0.3,1.8-0.3l2.6-3.8l-2.5-3.8c-0.6,0-1.2-0.2-1.8-0.3V12h3.2l2.2,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.2,0.3-1.8,0.3l-2.4,3.7l2.6,3.9c0.6,0,1.2,0.2,1.8,0.3v1.2H186.3L186.3,22.7z"/>
            +	<path d="M191.6,22.7v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.6c0-1.4-0.8-2.4-2.6-2.4c-1.2,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.3-1.1,3.9-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-0.9,3.2-3.3,5.2l-2.6,2.2h-0.1c1-0.1,3.3-0.1,6.5-0.1v1.8h-9.2V22.7z"/>
            +	<path d="M208.8,26l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.7-0.1-1.9,0.9-1.9C211.4,20.3,212.1,23,208.8,26z"/>
            +	<path d="M226.5,13.4l-3.8,10.3c-1.2,3.2-2.2,4.3-4.6,4.3c-0.4,0-1,0-1.5-0.1l0.1-1.7c0.5,0.1,0.9,0.2,1.4,0.2
            +		c1.2,0,1.8-0.6,2.6-2.6l0.4-1.2h-0.5l-3.3-9.2c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6
            +		c0.3,1,0.6,1.8,0.8,2.7l0,0c0.2-0.7,0.6-1.9,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.7v1.2C227.5,13.2,227,13.3,226.5,13.4z"/>
            +	<path d="M229.8,22.7v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.6c0-1.4-0.8-2.4-2.6-2.4c-1.2,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.3-1.1,3.9-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-0.9,3.2-3.3,5.2l-2.6,2.2h-0.1c1-0.1,3.3-0.1,6.5-0.1v1.8h-9.2L229.8,22.7
            +		L229.8,22.7z"/>
            +	<path d="M247.6,27.2l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.8c0-3.7-0.9-6.9-2.7-10l1.5-0.7c2.5,4,3.1,7.4,3.1,10.5
            +		C250.7,19.6,250,23.3,247.6,27.2z"/>
            +	<path d="M259.1,26l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.7-0.1-1.9,0.9-1.9C261.7,20.3,262.4,23,259.1,26z M260.1,16.6
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C261.5,16,260.9,16.6,260.1,16.6z"/>
            +</g>
            +<text transform="matrix(1 0 0 1 49.1954 68.3887)" fill="#999999" font-family="'TheSansMonoCd-W5Regular'" font-size="16.673" letter-spacing="36"> </text>
            +<g enable-background="new    ">
            +	<path fill="#999999" d="M107.6,64.5c-0.5,0-0.9,0-1.2-0.1v2.8c0.5,0,1,0.1,1.4,0.2v0.9h-4.4v-0.9c0.4-0.1,0.9-0.2,1.4-0.2v-9
            +		c-0.5,0-1-0.1-1.4-0.2V57h1.4c0.5,0,1.9-0.1,2.9-0.1c3,0,4.3,1.6,4.3,3.5C112.1,62.9,110.3,64.5,107.6,64.5z M107.6,58.4
            +		c-0.4,0-0.9,0-1.2,0v4.8c0.3,0,0.8,0.1,1.3,0.1c1.9,0,2.8-1.1,2.8-2.5C110.5,59.6,109.8,58.4,107.6,58.4z"/>
            +	<path fill="#999999" d="M116.9,68.5c-2.3,0-3.7-1.3-3.7-4.2c0-2.5,1.5-4.4,4-4.4c2.1,0,3.7,1.1,3.7,4.2
            +		C121,66.6,119.4,68.5,116.9,68.5z M117,61.1c-1.2,0-2.3,0.9-2.3,3c0,1.9,0.8,3,2.3,3c1.2,0,2.3-1,2.3-3
            +		C119.3,62.3,118.6,61.1,117,61.1z"/>
            +	<path fill="#999999" d="M122.2,68.4v-0.9c0.4-0.1,0.9-0.2,1.4-0.2v-6c-0.4-0.1-1-0.1-1.4-0.2v-0.9c0.8-0.1,2-0.2,2.9-0.1v7.2
            +		c0.5,0,1,0.1,1.4,0.2v0.9L122.2,68.4L122.2,68.4L122.2,68.4z M124.3,58.5c-0.5,0-1-0.4-1-1s0.4-1,1-1c0.5,0,1,0.4,1,1
            +		C125.3,58.1,124.8,58.5,124.3,58.5z"/>
            +	<path fill="#999999" d="M134,68.4v-5.3c0-1.2-0.3-1.9-1.4-1.9c-1.4,0-2.4,1.4-2.4,3.2v2.8c0.4,0,0.9,0.1,1.3,0.2v0.9h-4.3v-0.9
            +		c0.4-0.1,0.9-0.2,1.4-0.2v-6c-0.4-0.1-1-0.1-1.4-0.2v-0.9c0.8-0.1,2-0.2,2.9-0.1c0,0.5,0,1.2-0.1,1.7l0,0c0.5-1.1,1.5-1.9,2.9-1.9
            +		c1.9,0,2.5,1.2,2.5,2.6V67c0.5,0,1,0.1,1.4,0.2v0.9H134L134,68.4L134,68.4z"/>
            +	<path fill="#999999" d="M140.9,68.5c-1.7,0-2.2-0.7-2.2-2.5v-4.8H137v-1.2h1.7v-2.7l1.5-0.4v3.1h2.3v1.2h-2.3v4.2
            +		c0,1.4,0.3,1.7,1.2,1.7c0.4,0,0.7,0,1-0.1l0.2,1.2C142.1,68.5,141.5,68.5,140.9,68.5z"/>
            +	<path fill="#999999" d="M154.1,68.4v-0.9c0.4-0.1,0.9-0.2,1.3-0.2l-0.6-1.8h-4.7l-0.6,1.8c0.4,0,0.9,0.1,1.3,0.2v0.9h-3.9v-0.9
            +		c0.3-0.1,0.7-0.2,1-0.2l3.7-10.1h1.9l3.7,10.1c0.3,0,0.7,0.1,1,0.2v0.9H154.1z M153,60.3c-0.2-0.6-0.4-1.1-0.5-1.6l0,0
            +		c-0.1,0.5-0.3,1-0.5,1.6l-1.4,4h3.9L153,60.3z"/>
            +	<path fill="#999999" d="M177.5,64.5c-0.5,0-0.9,0-1.2-0.1v2.8c0.5,0,1,0.1,1.4,0.2v0.9h-4.4v-0.9c0.4-0.1,0.9-0.2,1.4-0.2v-9
            +		c-0.5,0-1-0.1-1.4-0.2V57h1.4c0.5,0,1.9-0.1,2.9-0.1c3,0,4.3,1.6,4.3,3.5C182,62.9,180.2,64.5,177.5,64.5z M177.5,58.4
            +		c-0.4,0-0.9,0-1.2,0v4.8c0.3,0,0.8,0.1,1.3,0.1c1.9,0,2.8-1.1,2.8-2.5C180.4,59.6,179.7,58.4,177.5,58.4z"/>
            +	<path fill="#999999" d="M186.8,68.5c-2.3,0-3.7-1.3-3.7-4.2c0-2.5,1.5-4.4,4-4.4c2.1,0,3.7,1.1,3.7,4.2
            +		C190.8,66.6,189.3,68.5,186.8,68.5z M186.9,61.1c-1.2,0-2.3,0.9-2.3,3c0,1.9,0.8,3,2.3,3c1.2,0,2.3-1,2.3-3
            +		C189.2,62.3,188.4,61.1,186.9,61.1z"/>
            +	<path fill="#999999" d="M191.9,68.4v-0.9c0.4-0.1,0.9-0.2,1.4-0.2v-6c-0.4-0.1-1-0.1-1.4-0.2v-0.9c0.8-0.1,2-0.2,2.9-0.1v7.2
            +		c0.5,0,1,0.1,1.4,0.2v0.9L191.9,68.4L191.9,68.4L191.9,68.4z M194.2,58.5c-0.5,0-1-0.4-1-1s0.4-1,1-1c0.5,0,1,0.4,1,1
            +		C195.1,58.1,194.7,58.5,194.2,58.5z"/>
            +	<path fill="#999999" d="M203.9,68.4v-5.3c0-1.2-0.3-1.9-1.4-1.9c-1.4,0-2.4,1.4-2.4,3.2v2.8c0.4,0,0.9,0.1,1.3,0.2v0.9H197v-0.9
            +		c0.4-0.1,0.9-0.2,1.4-0.2v-6c-0.4-0.1-1-0.1-1.4-0.2v-0.9c0.8-0.1,2-0.2,2.9-0.1c0,0.5,0,1.2-0.1,1.7l0,0c0.5-1.1,1.5-1.9,2.9-1.9
            +		c1.9,0,2.5,1.2,2.5,2.6V67c0.5,0,1,0.1,1.4,0.2v0.9h-2.8L203.9,68.4L203.9,68.4z"/>
            +	<path fill="#999999" d="M210.8,68.5c-1.7,0-2.2-0.7-2.2-2.5v-4.8h-1.7v-1.2h1.7v-2.7l1.5-0.4v3.1h2.3v1.2h-2.3v4.2
            +		c0,1.4,0.3,1.7,1.2,1.7c0.4,0,0.7,0,1-0.1l0.2,1.2C212,68.5,211.4,68.5,210.8,68.5z"/>
            +	<path fill="#999999" d="M221.5,68.4c-0.6,0-1.7,0-2.9,0h-1.5v-0.9c0.4-0.1,0.9-0.2,1.4-0.2v-9c-0.5,0-1-0.1-1.4-0.2v-0.9h1.4
            +		c0.8,0,1.9,0,3.2,0c2.4,0,3.6,1,3.6,2.7c0,1.2-0.6,2.2-1.8,2.6l0,0c1.6,0.3,2.3,1.4,2.3,2.6C225.8,66.4,225,68.4,221.5,68.4z
            +		 M221.5,58.4c-0.5,0-0.9,0-1.4,0V62c0.3,0,0.6,0,1,0c1.8,0,2.6-0.7,2.6-2C223.8,59.1,223.3,58.4,221.5,58.4z M221.2,63.2
            +		c-0.2,0-0.8,0-1.1,0v3.9c0.3,0,0.8,0.1,1.5,0.1c1.8,0,2.6-0.9,2.6-2.1C224.2,63.6,222.9,63.2,221.2,63.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M98.5,262.5v-1.2c0.5-0.1,1.1-0.2,1.7-0.3l-0.8-2.4h-6l-0.8,2.4c0.6,0,1.2,0.1,1.7,0.3v1.2h-5v-1.2
            +		c0.4-0.1,0.9-0.2,1.3-0.2l4.7-13.1h2.4l4.8,13.1c0.4,0,0.9,0.1,1.3,0.2v1.2H98.5z M97,252c-0.3-0.7-0.5-1.4-0.7-2.1l0,0
            +		c-0.2,0.7-0.4,1.3-0.6,2.1l-1.9,5.1h5L97,252z"/>
            +	<path d="M117.2,267.3c-3.6-3.3-5.3-6.6-5.3-10.8c0-4.4,2.1-8,5.3-10.9l1.1,1.1c-2.9,2.8-4.5,6.2-4.5,9.6c0,3.6,1.5,6.8,4.5,9.7
            +		L117.2,267.3z"/>
            +	<path d="M123.6,262.5v-1.7h3.9v-9l-3.7,2.4l-0.7-1.6l4.7-2.9h1.6v11.1h3.3v1.7L123.6,262.5L123.6,262.5z"/>
            +	<path d="M137,265.3c2.2-0.6,2.9-1.6,2.9-2.4c0-1.3-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.3,0,2,1.3,2,2.7c0,2.6-1.8,4.2-4.9,5
            +		L137,265.3z"/>
            +	<path d="M148.8,262.5v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.6c0-1.4-0.8-2.4-2.6-2.4c-1.2,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.3-1.1,3.9-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-0.9,3.2-3.3,5.2l-2.6,2.2h-0.1c1-0.1,3.3-0.1,6.5-0.1v1.8h-9.2L148.8,262.5
            +		L148.8,262.5z"/>
            +	<path d="M164.2,245.6c3.6,3.3,5.3,6.6,5.3,10.8c0,4.4-2.1,8-5.3,10.9l-1.1-1.1c2.9-2.8,4.5-6.2,4.5-9.6c0-3.6-1.5-6.9-4.5-9.7
            +		L164.2,245.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M267.4,261.2c-0.8,0-2.2-0.1-3.7-0.1h-1.9v-1.2c0.6-0.1,1.2-0.2,1.9-0.3V248c-0.6,0-1.3-0.2-1.9-0.3v-1.2h1.8
            +		c1,0,2.4-0.1,4.1-0.1c3.1,0,4.6,1.3,4.6,3.5c0,1.5-0.8,2.8-2.4,3.4l0,0c2,0.3,2.9,1.8,2.9,3.3C272.9,258.4,272,261.2,267.4,261.2z
            +		 M267.4,248.1c-0.7,0-1.2,0-1.8,0v4.7c0.4,0,0.8,0,1.3,0c2.4,0,3.4-0.9,3.4-2.5C270.3,249,269.7,248.1,267.4,248.1z M267,254.3
            +		c-0.3,0-1,0-1.4,0v5c0.4,0.1,1,0.1,1.9,0.1c2.4,0,3.4-1.2,3.4-2.7C270.9,254.9,269.2,254.3,267,254.3z"/>
            +	<path d="M287.5,265.9c-3.6-3.3-5.3-6.6-5.3-10.8c0-4.4,2.1-8,5.3-10.9l1.1,1.1c-2.9,2.8-4.5,6.2-4.5,9.6c0,3.6,1.5,6.8,4.5,9.7
            +		L287.5,265.9z"/>
            +	<path d="M296.1,263.1c-0.7,0-1.6-0.1-2.4-0.2l0.1-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.8-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.1v-7.3h7.5v1.8H296v3.8c0.4,0,0.8,0,1,0c3.5,0,5.3,1.8,5.3,4.1C302.4,260.8,299.9,263.1,296.1,263.1z"/>
            +	<path d="M307.3,263.8c2.2-0.6,2.9-1.6,2.9-2.4c0-1.3-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.3,0,2,1.3,2,2.7c0,2.6-1.8,4.2-4.9,5
            +		L307.3,263.8z"/>
            +	<path d="M319.1,261v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.6c0-1.4-0.8-2.4-2.6-2.4c-1.2,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.3-1.1,3.9-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-0.9,3.2-3.3,5.2l-2.6,2.2h-0.1c1-0.1,3.3-0.1,6.5-0.1v1.8H319L319.1,261
            +		L319.1,261z"/>
            +	<path d="M334.4,244.1c3.6,3.3,5.3,6.6,5.3,10.8c0,4.4-2.1,8-5.3,10.9l-1.1-1.1c2.9-2.8,4.5-6.2,4.5-9.6c0-3.6-1.5-6.9-4.5-9.7
            +		L334.4,244.1z"/>
            +</g>
            +<line fill="none" stroke="#999999" stroke-width="5" x1="102.8" y1="38.3" x2="155.8" y2="38.3"/>
            +<line fill="none" stroke="#999999" stroke-width="5" x1="168.3" y1="38.3" x2="228.2" y2="38.3"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="118.9" y1="276" x2="297.3" y2="276"/>
            +<g enable-background="new    ">
            +	<path fill="#808080" d="M78.4,510.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.6c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.3v3.3h-1.4
            +		c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9v4.7h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.4-0.2-1-0.3-1.5h-3.1v5.1H86
            +		c0.1-0.6,0.2-1.2,0.3-1.8h1.4v3.4h-9.3V510.6z"/>
            +	<path fill="#808080" d="M97.3,510.6l-2.4-4l-2.3,4h-3.2v-1.2c0.6-0.1,1.2-0.3,1.8-0.3l2.6-3.8l-2.5-3.8c-0.6,0-1.2-0.2-1.8-0.3
            +		v-1.2h3.2l2.2,3.9l2.3-3.9h3.1v1.2c-0.6,0.1-1.2,0.3-1.8,0.3l-2.4,3.7l2.6,3.9c0.6,0,1.2,0.2,1.8,0.3v1.2H97.3L97.3,510.6z"/>
            +	<path fill="#808080" d="M108.2,510.6c0-0.7,0-1.5,0.1-2.1l0,0c-0.5,1.3-1.9,2.3-3.6,2.3s-3-1.1-3-2.8c0-2.3,2.4-3.6,6.4-3.6v-0.9
            +		c0-1.5-0.5-2.3-2.2-2.3c-0.6,0-1.4,0.1-2,0.3c0,0.5-0.1,1.1-0.3,1.7h-1.2v-2.9c1.1-0.3,2.4-0.6,3.6-0.6c3.1,0,4,1.4,4,3.5v5.8
            +		c0.5,0.1,1.2,0.2,1.8,0.2v1.2C110.9,510.5,109.4,510.6,108.2,510.6z M108.1,505.7c-3.3,0-4.5,0.8-4.5,2c0,0.9,0.6,1.6,1.6,1.6
            +		c1.7,0,2.9-1.7,2.9-3.4L108.1,505.7L108.1,505.7z"/>
            +	<path fill="#808080" d="M128,510.6v-6.8c0-1.5-0.3-2.4-1.7-2.4c-1.5,0-3,1.6-3,4.2v3.6c0.6,0,1.2,0.1,1.7,0.3v1.2h-3.6v-6.8
            +		c0-1.3-0.3-2.4-1.7-2.4c-1.6,0-3,1.8-3,4.2v3.6c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.2-0.2-1.9-0.2V500c1.1-0.1,2.6-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,2-2.5,3.7-2.5c2.2,0,2.8,1.5,3,2.4
            +		c0.4-1,1.6-2.4,3.6-2.4s3.1,1.1,3.1,3.5v5.9c0.6,0,1.3,0.2,1.8,0.3v1.2H128V510.6z"/>
            +	<path fill="#808080" d="M137.9,510.7c-0.7,0-1.2,0-1.8-0.1v3.8c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.6v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.5-2.4c2.5,0,3.9,1.8,3.9,5
            +		C143.4,508.4,141.3,510.7,137.9,510.7z M139,501.2c-1.9,0-2.9,2.2-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C141.3,502.5,140.6,501.2,139,501.2z"/>
            +	<path fill="#808080" d="M144.7,510.6v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.6c-0.5-0.1-1.2-0.2-1.8-0.2V495c1.1-0.1,2.5-0.2,3.8-0.1
            +		v14.3c0.6,0,1.3,0.2,1.8,0.3v1.2h-5.6V510.6z"/>
            +	<path fill="#808080" d="M160.3,505.2h-6.9c-0.1,2.8,1,4,3.4,4c1,0,2.1-0.2,3-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7
            +		c-3.2,0-5-1.7-5-5.5c0-3.2,1.8-5.6,4.8-5.6s4.2,2,4.2,4.4C160.3,504.3,160.3,504.7,160.3,505.2z M156,501.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C158.4,502.2,157.5,501.1,156,501.1z"/>
            +	<path fill="#808080" d="M164.8,504.5c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3S165.5,504.5,164.8,504.5z
            +		 M164.8,510.7c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C166.1,510.1,165.5,510.7,164.8,510.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M177.6,510.6v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.6c-0.5-0.1-1.2-0.2-1.8-0.2V495c1.1-0.1,2.5-0.2,3.8-0.1v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2h-5.6V510.6z"/>
            +	<path d="M184.2,510.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.6c-0.5-0.1-1.2-0.2-1.9-0.2V500c1.1-0.1,2.5-0.2,3.8-0.2v9.2
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2L184.2,510.6L184.2,510.6z M187,497.7c-0.7,0-1.3-0.5-1.3-1.2s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		S187.7,497.7,187,497.7z"/>
            +	<path d="M199.5,510.6v-6.8c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.1v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.6-0.1,1.2-0.2,1.9-0.3v-7.7c-0.5-0.1-1.2-0.2-1.9-0.2V500c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6,0,1.6-0.1,2.2l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2L199.5,510.6L199.5,510.6L199.5,510.6z"/>
            +	<path d="M213.3,505.2h-6.9c-0.1,2.8,1,4,3.4,4c1,0,2.1-0.2,3-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.2,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.2,2,4.2,4.4C213.4,504.3,213.4,504.7,213.3,505.2z M209.1,501.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C211.5,502.2,210.5,501.1,209.1,501.1z"/>
            +	<path d="M227.8,515.4c-3.6-3.3-5.3-6.6-5.3-10.8c0-4.4,2.1-8,5.3-10.9l1.1,1.1c-2.9,2.8-4.5,6.2-4.5,9.6c0,3.6,1.5,6.8,4.5,9.7
            +		L227.8,515.4z"/>
            +	<path d="M234.1,510.6v-1.7h3.9v-9.1l-3.7,2.4l-0.7-1.6l4.7-2.9h1.6v11.1h3.3v1.7H234.1z"/>
            +	<path d="M247.6,513.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.3-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.3,0,2,1.3,2,2.7c0,2.6-1.8,4.2-4.9,5
            +		L247.6,513.4z"/>
            +	<path d="M259.4,510.6V509l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.6c0-1.4-0.8-2.4-2.6-2.4c-1.2,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.3-1.1,3.9-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-0.9,3.2-3.3,5.2l-2.6,2.2h-0.1c1-0.1,3.3-0.1,6.5-0.1v1.8h-9.2L259.4,510.6
            +		L259.4,510.6z"/>
            +	<path d="M273.4,513.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.3-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.3,0,2,1.3,2,2.7c0,2.6-1.8,4.2-4.9,5
            +		L273.4,513.4z"/>
            +	<path d="M287.9,512.5c-0.7,0-1.6-0.1-2.4-0.2l0.1-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.8-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.1v-7.3h7.5v1.8h-5.7v3.8c0.4,0,0.8,0,1,0c3.5,0,5.3,1.8,5.3,4.1C294.1,510.2,291.7,512.5,287.9,512.5z"/>
            +	<path d="M299.1,513.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.3-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.3,0,2,1.3,2,2.7c0,2.6-1.8,4.2-4.9,5
            +		L299.1,513.4z"/>
            +	<path d="M310.8,510.6V509l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.6c0-1.4-0.8-2.4-2.6-2.4c-1.2,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.3-1.1,3.9-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-0.9,3.2-3.3,5.2l-2.6,2.2h-0.1c1-0.1,3.3-0.1,6.5-0.1v1.8h-9.2L310.8,510.6
            +		L310.8,510.6z"/>
            +	<path d="M326.2,493.6c3.6,3.3,5.3,6.6,5.3,10.8c0,4.4-2.1,8-5.3,10.9l-1.1-1.1c2.9-2.8,4.5-6.2,4.5-9.6c0-3.6-1.5-6.9-4.5-9.7
            +		L326.2,493.6z"/>
            +	<path d="M339.4,513.9l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.7-0.1-1.9,0.9-1.9C342,508.2,342.7,510.7,339.4,513.9z M340.4,504.5
            +		c-0.7,0-1.3-0.6-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3S341.2,504.5,340.4,504.5z"/>
            +</g>
            +</svg>
            diff --git a/dist/assets/learn/basics/rect.svg b/dist/assets/learn/basics/rect.svg
            new file mode 100644
            index 0000000000..ee45a9407e
            --- /dev/null
            +++ b/dist/assets/learn/basics/rect.svg
            @@ -0,0 +1,229 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 62.1 612 702" enable-background="new 0 62.1 612 702" xml:space="preserve">
            +<g>
            +	<rect x="121.7" y="197.9" fill="none" stroke="#999999" stroke-width="1.3" width="444.1" height="444.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="121.7" y1="568.1" x2="565.6" y2="568.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="121.7" y1="493.8" x2="565.6" y2="493.8"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="121.7" y1="420" x2="565.6" y2="420"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="121.7" y1="346.1" x2="565.6" y2="346.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="121.7" y1="271.8" x2="565.6" y2="271.8"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="491.7" y1="197.9" x2="491.7" y2="642"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="417.8" y1="197.9" x2="417.8" y2="642"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="343.7" y1="197.9" x2="343.7" y2="642"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="269.7" y1="197.9" x2="269.7" y2="642"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="195.6" y1="197.9" x2="195.6" y2="642"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M130.5,91.1l-4-6.7l-3.9,6.7h-5.4V89c1.1-0.2,2.1-0.4,3-0.6l4.3-6.5l-4.1-6.3c-0.9,0-2.1-0.4-3-0.6v-2.1h5.4l3.7,6.5
            +		l3.9-6.5h5.2V75c-1.1,0.2-2.1,0.4-3,0.6l-3.9,6.3l4.3,6.5c0.9,0,2.1,0.4,3,0.6v2.1H130.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M20.9,187.8l-6.3,17.4c-1.9,5.4-3.7,7.3-7.7,7.3c-0.7,0-1.7,0-2.4-0.2l0.2-3c0.7,0.2,1.5,0.4,2.4,0.4c1.9,0,3-0.9,4.3-4.5
            +		l0.7-2.1h-0.7L6,187.6c-0.7,0-1.7-0.2-2.2-0.4v-1.8H12v1.9c-0.7,0.2-1.5,0.4-2.2,0.4l2.6,7.7c0.6,1.7,0.9,3,1.3,4.5l0,0
            +		c0.4-1.3,0.9-3.2,1.7-5.2l2.4-6.9c-0.9,0-1.7-0.2-2.2-0.4v-2h8v1.9C22.6,187.6,21.8,187.8,20.9,187.8z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M128.2,152.5c-4.9,0-8.8-2.8-8.8-11c0-7.1,4.3-11.2,9.3-11.2c4.7,0,8.8,2.6,8.8,11C137.6,148.6,133.3,152.5,128.2,152.5z
            +		 M128.4,132.9c-3,0-5.6,2.6-5.6,8.2c0,6,2.2,8.6,5.8,8.6c3,0,5.6-2.4,5.6-8.2C134.2,135.5,131.8,132.9,128.4,132.9z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M193.2,152.1v-3h6.5V134l-6.2,4.1l-1.1-2.8l7.8-4.9h2.8v18.7h5.6v3H193.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M263.9,152.1v-2.6l5-4.7c4.5-3.9,5.6-5.4,5.6-7.8c0-2.4-1.3-3.9-4.5-3.9c-2.1,0-4.1,0.9-5.2,1.9l-0.7-2.8
            +		c1.9-1.1,3.9-1.9,6.5-1.9c4.9,0,7.3,2.8,7.3,6.3c0,3-1.5,5.4-5.6,8.8l-4.3,3.7h-0.2c1.7-0.2,5.6-0.2,11-0.2v3.2H263.9z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M340.5,155.5c-1.5,0-3.2-0.2-4.5-0.6l0.6-3c1.3,0.4,2.8,0.7,4.3,0.7c3.7,0,6.3-2.2,6.3-4.9c0-2.6-2.1-4.5-6-4.5
            +		c-1.3,0-2.2,0-3.2,0.2v-2.6h0.7c5,0,7.7-1.5,7.7-4.5c0-2.2-1.7-3.5-4.3-3.5c-2.1,0-3.5,0.6-5,1.3l-0.6-2.8c1.9-0.7,3.9-1.3,6.2-1.3
            +		c4.9,0,7.3,2.4,7.3,5.8c0,2.8-1.7,4.9-4.3,5.6l0,0c3,0.4,5.2,2.8,5.2,5.8C350.7,152.1,346.5,155.5,340.5,155.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M420.2,149.1v6H417v-6h-11l-0.2-2.6l9.9-15.9h4.5v15.5h4.1v3H420.2z M417,133.5L417,133.5l-8,12.7c2.1,0,6.7,0,8,0V133.5z"
            +		/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M483.7,155.5c-1.1,0-2.6-0.2-3.9-0.4l0.2-2.8c1.1,0.4,2.8,0.4,4.1,0.4c4.3,0,6.7-2.4,6.7-5.4c0-3-2.4-4.7-6.5-4.7
            +		c-1.5,0-2.8,0.2-3.7,0.2v-12.3h12.7v3.2h-9.5v6.3c0.6,0,1.3,0,1.7,0c6,0,9,3,9,6.9C494.1,151.8,490,155.5,483.7,155.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M558.5,152.5c-5,0-8-3.7-8-10.3c0-10.3,5-14.6,11.9-14.6c0.7,0,1.5,0,2.1,0.2v2.8c-0.7-0.2-1.5-0.2-2.4-0.2
            +		c-4.7,0-7.3,2.8-8.2,7.7c-0.2,0.4-0.2,1.1-0.4,1.9l0,0c1.1-2.1,3.4-3.2,5.6-3.2c4.9,0,7.5,3.2,7.5,7.1
            +		C566.7,149,563.4,152.5,558.5,152.5z M558.7,139.6c-3,0-4.7,2.6-4.7,4.7c0,3,1.7,5.6,4.9,5.6c2.8,0,4.7-2.2,4.7-5.2
            +		C563.4,141.5,561.7,139.6,558.7,139.6z"/>
            +</g>
            +<circle fill="#808080" cx="195.6" cy="346.1" r="11.6"/>
            +<g enable-background="new    ">
            +	<path d="M72.4,214.1c-4.9,0-8.8-2.8-8.8-11c0-7.1,4.3-11.2,9.3-11.2c4.7,0,8.8,2.6,8.8,11C81.7,210.2,77.4,214.1,72.4,214.1z
            +		 M72.6,194.7c-3,0-5.6,2.6-5.6,8.2c0,6,2.2,8.6,5.8,8.6c3,0,5.6-2.4,5.6-8.2C78.4,197.3,76.1,194.7,72.6,194.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M65.7,285.6v-3h6.5v-15.1l-6.2,4.1l-1.1-2.8l7.8-4.9h2.8v18.7h5.6v3H65.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M64.9,357.3v-2.6l5-4.7c4.5-3.9,5.6-5.4,5.6-7.8s-1.3-3.9-4.5-3.9c-2.1,0-4.1,0.9-5.2,1.9l-0.7-2.8
            +		c1.9-1.1,3.9-1.9,6.5-1.9c4.9,0,7.3,2.8,7.3,6.3c0,3-1.5,5.4-5.6,8.8l-4.3,3.7h-0.2c1.7-0.2,5.6-0.2,11-0.2v3.2H64.9z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M69.8,432.2c-1.5,0-3.2-0.2-4.5-0.6l0.6-3c1.3,0.4,2.8,0.7,4.3,0.7c3.7,0,6.3-2.2,6.3-4.9c0-2.6-2.1-4.5-6-4.5
            +		c-1.3,0-2.2,0-3.2,0.2v-2.6H68c5,0,7.7-1.5,7.7-4.5c0-2.2-1.7-3.5-4.3-3.5c-2.1,0-3.5,0.6-5,1.3l-0.6-2.8c1.9-0.7,3.9-1.3,6.2-1.3
            +		c4.9,0,7.3,2.4,7.3,5.8c0,2.8-1.7,4.9-4.3,5.6l0,0c3,0.4,5.2,2.8,5.2,5.8C79.9,428.8,75.8,432.2,69.8,432.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M77.6,497.5v6h-3.2v-6h-11l-0.2-2.6l9.9-15.9h4.5v15.5h4.1v3H77.6L77.6,497.5z M74.5,482L74.5,482l-8,12.7c2.1,0,6.7,0,8,0
            +		V482z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M69.6,575.5c-1.1,0-2.6-0.2-3.9-0.4l0.2-2.8c1.1,0.4,2.8,0.4,4.1,0.4c4.3,0,6.7-2.4,6.7-5.4s-2.4-4.7-6.5-4.7
            +		c-1.5,0-2.8,0.2-3.7,0.2v-12.3H79v3.2h-9.5v6.3c0.6,0,1.3,0,1.7,0c6,0,9,3,9,6.9C80.1,571.8,75.8,575.5,69.6,575.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M72.8,644.2c-5,0-8-3.7-8-10.3c0-10.3,5-14.6,11.9-14.6c0.7,0,1.5,0,2.1,0.2v2.8c-0.7-0.2-1.5-0.2-2.4-0.2
            +		c-4.7,0-7.3,2.8-8.2,7.7c-0.2,0.4-0.2,1.1-0.4,1.9l0,0c1.1-2.1,3.4-3.2,5.6-3.2c4.9,0,7.5,3.2,7.5,7.1
            +		C80.8,640.9,77.6,644.2,72.8,644.2z M72.8,631.3c-3,0-4.7,2.6-4.7,4.7c0,3,1.7,5.6,4.9,5.6c2.8,0,4.7-2.2,4.7-5.2
            +		S75.9,631.3,72.8,631.3z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="123.6" y1="197.9" x2="109.4" y2="197.9"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="123.6" y1="272.2" x2="109.4" y2="272.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="123.6" y1="345.9" x2="109.4" y2="345.9"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="123.6" y1="419.6" x2="109.4" y2="419.6"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="123.6" y1="493.9" x2="109.4" y2="493.9"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="123.6" y1="568.8" x2="109.4" y2="568.8"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="123.6" y1="641.4" x2="109.4" y2="641.4"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="565.1" y1="197.7" x2="565.1" y2="183.5"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="490.8" y1="197.7" x2="490.8" y2="183.5"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="417" y1="197.7" x2="417" y2="183.5"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="343.1" y1="197.7" x2="343.1" y2="183.5"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="269" y1="197.7" x2="269" y2="183.5"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="193.9" y1="197.7" x2="193.9" y2="183.5"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="122.2" y1="197.7" x2="122.2" y2="183.5"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="21.8,333.6 13,342.2 4.3,333.6 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="13" y1="342.2" x2="13" y2="238.2"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="537.1,544.2 528.3,552.9 519.5,544.2 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="528.3" y1="552.9" x2="528.3" y2="501.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="519.5,369.2 528.3,360.5 537.1,369.2 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="528.3" y1="360.5" x2="528.3" y2="411.6"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="257.4,71.5 266.2,80.3 257.4,89 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="268.2" y1="80.3" x2="164.2" y2="80.3"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="462.6,593.5 471.3,602.2 462.6,610.8 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="473.4" y1="602.2" x2="402.5" y2="602.2"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="222.1,610.8 213.3,602.2 222.1,593.5 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="211.3" y1="602.2" x2="282.2" y2="602.2"/>
            +<g enable-background="new    ">
            +	<path d="M218,333.2c-6-5.4-8.8-11.2-8.8-18.1c0-7.3,3.5-13.4,9-18.3l1.9,1.9c-4.9,4.7-7.5,10.3-7.5,16.1c0,6,2.4,11.4,7.5,16.4
            +		L218,333.2z"/>
            +	<path d="M228.5,325v-2.8h6.5v-15.1l-6.2,4.1l-1.1-2.8l8-4.9h2.8v18.7h5.6v3h-15.7L228.5,325L228.5,325z"/>
            +	<path d="M251.2,329.9c3.7-0.9,4.9-2.6,4.9-3.9c0-2.2-1.9-2.2-1.9-4.3c0-1.5,1.1-2.6,2.6-2.6c2.2,0,3.4,2.2,3.4,4.5
            +		c0,4.5-3,7.1-8.2,8.4L251.2,329.9z"/>
            +	<path d="M270.8,325v-2.6l5-4.7c4.5-3.9,5.6-5.4,5.6-7.8s-1.3-3.9-4.5-3.9c-2.1,0-4.1,0.9-5.2,1.9l-0.7-2.8c1.9-1.1,3.9-1.9,6.5-1.9
            +		c4.9,0,7.3,2.8,7.3,6.3c0,3-1.5,5.4-5.6,8.8l-4.3,3.7h-0.2c1.7-0.2,5.6-0.2,11-0.2v3.2H270.8z"/>
            +	<path d="M296.4,296.8c6,5.6,8.8,11.2,8.8,18.1c0,7.3-3.5,13.4-9,18.3l-1.9-1.9c4.9-4.7,7.5-10.3,7.5-16.1c0-6-2.4-11.6-7.5-16.4
            +		L296.4,296.8z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="193.4" y1="347.2" x2="491.7" y2="347.2"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="193.4" y1="566.4" x2="491.7" y2="566.4"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="489.8" y1="568.1" x2="489.8" y2="346.1"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="195.1" y1="568.1" x2="195.1" y2="346.1"/>
            +<g enable-background="new    ">
            +	<path fill="#808080" d="M134.8,742.4v-1.9c0.9-0.2,2.1-0.4,3.2-0.4v-19.4c-1.1,0-2.2-0.2-3.2-0.4v-1.9h15.7v5.6h-2.2
            +		c-0.2-1.1-0.4-2.2-0.4-3h-6.5v8h5.2c0.2-0.9,0.4-1.7,0.6-2.4h2.1v7.3h-2.1c-0.2-0.7-0.4-1.7-0.6-2.4h-5.2v8.6h6.5
            +		c0.2-0.9,0.4-2.1,0.6-3.2h2.2v5.8h-15.9V742.4z"/>
            +	<path fill="#808080" d="M166.3,742.4l-3.9-6.7l-3.9,6.7H153v-2c1.1-0.2,2.1-0.4,3-0.6l4.3-6.5l-4.1-6.3c-0.9,0-2.1-0.4-3-0.6v-2.1
            +		h5.4l3.7,6.5l3.9-6.5h5.2v2.1c-1.1,0.2-2.1,0.4-3,0.6l-3.9,6.3l4.3,6.5c0.9,0,2.1,0.4,3,0.6v2.1L166.3,742.4L166.3,742.4z"/>
            +	<path fill="#808080" d="M184.8,742.4c0-1.3,0-2.6,0.2-3.5l0,0c-0.9,2.2-3.2,3.9-6,3.9c-3,0-4.9-1.9-4.9-4.7c0-3.9,3.9-6.2,10.6-6.2
            +		v-1.3c0-2.4-0.9-3.9-3.7-3.9c-1.1,0-2.2,0.2-3.4,0.6c0,0.9-0.2,1.9-0.4,3h-2.1v-4.9c1.9-0.6,3.9-0.9,6-0.9c5.2,0,6.7,2.4,6.7,6v9.7
            +		c0.9,0.2,2.1,0.4,3,0.4v1.9C189.1,742.4,186.6,742.6,184.8,742.4z M184.6,734.2c-5.6,0-7.5,1.3-7.5,3.4c0,1.5,1.1,2.6,2.8,2.6
            +		c2.8,0,4.9-2.8,4.9-5.6v-0.4H184.6z"/>
            +	<path fill="#808080" d="M217.8,742.4V731c0-2.4-0.6-4.1-2.8-4.1c-2.6,0-5,2.6-5,7.1v6c0.9,0,2.1,0.2,3,0.4v1.9h-6.2v-11.2
            +		c0-2.2-0.4-4.1-3-4.1s-5,3-5,7.1v6c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.1v-2c0.9-0.2,2.1-0.4,3.2-0.4v-12.9c-0.9-0.2-2.1-0.4-3.2-0.4
            +		v-1.9c1.9-0.2,4.3-0.4,6.3-0.2c0,1.1-0.2,2.6-0.4,3.7l0,0c0.9-2.4,3.4-4.1,6.2-4.1c3.7,0,4.9,2.6,4.9,4.1c0.7-1.7,2.6-4.1,6.2-4.1
            +		c3.4,0,5.2,1.9,5.2,5.8v9.9c1.1,0,2.1,0.2,3,0.4v1.9h-6L217.8,742.4L217.8,742.4z"/>
            +	<path fill="#808080" d="M234.3,742.6c-1.1,0-2.1,0-3-0.2v6.5c1.1,0,2.2,0.2,3.2,0.4v1.9h-9.3v-1.9c0.9-0.2,1.9-0.4,3-0.4v-21.7
            +		c-0.9-0.2-2.1-0.4-3-0.4v-1.9c1.7-0.2,4.1-0.4,6.2-0.2c0,0.9-0.2,2.6-0.4,3.5l0,0c0.9-2.4,3.2-3.9,6-3.9c4.1,0,6.5,3,6.5,8.4
            +		C243.4,739.1,240,742.6,234.3,742.6z M236.1,726.9c-3.2,0-4.9,3.7-4.9,6.9v5.8c0.9,0.4,2.1,0.4,3.2,0.4c3.4,0,5.6-2.1,5.6-7.1
            +		C240,729.2,238.7,726.9,236.1,726.9z"/>
            +	<path fill="#808080" d="M245.6,742.4v-1.9c0.9-0.2,2.1-0.4,3-0.4v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2V740
            +		c1.1,0,2.1,0.2,3,0.4v1.9L245.6,742.4C245.6,742.3,245.6,742.4,245.6,742.4z"/>
            +	<path fill="#808080" d="M271.8,733.5H260c-0.2,4.7,1.7,6.7,5.6,6.7c1.7,0,3.5-0.4,5-1.1l0.4,2.6c-1.9,0.7-3.9,1.1-6.2,1.1
            +		c-5.4,0-8.4-2.8-8.4-9.1c0-5.2,3-9.3,8-9.3s7.1,3.4,7.1,7.3C271.8,732,271.8,732.8,271.8,733.5z M264.5,726.8
            +		c-2.2,0-3.9,1.7-4.3,4.5h8.4C268.6,728.4,267.1,726.8,264.5,726.8z"/>
            +	<path fill="#808080" d="M279.2,732.3c-1.3,0-2.2-0.9-2.2-2.2s0.9-2.2,2.2-2.2s2.2,0.9,2.2,2.2C281.5,731.2,280.4,732.3,279.2,732.3
            +		z M279.2,742.8c-1.3,0-2.2-0.9-2.2-2.2s0.9-2.2,2.2-2.2s2.2,0.9,2.2,2.2C281.5,741.8,280.4,742.8,279.2,742.8z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M313.4,727.5c-4.1-0.7-6,2.1-6,7.8v4.9c1.1,0,2.2,0.2,3.2,0.4v1.9h-9.5v-1.9c0.9-0.2,2.1-0.4,3.2-0.4v-12.9
            +		c-0.9-0.2-2.1-0.4-3.2-0.4V725c1.9-0.2,4.3-0.4,6.2-0.2c0,1.1-0.2,2.8-0.4,4.3l0,0c0.7-2.4,2.6-4.9,6.5-4.5V727.5L313.4,727.5z"/>
            +	<path d="M330.6,733.5H319c-0.2,4.7,1.7,6.7,5.6,6.7c1.7,0,3.5-0.4,5-1.1l0.4,2.6c-1.9,0.7-3.9,1.1-6.2,1.1c-5.4,0-8.4-2.8-8.4-9.1
            +		c0-5.2,3-9.3,8-9.3s7.1,3.4,7.1,7.3C330.6,732,330.6,732.8,330.6,733.5z M323.5,726.8c-2.2,0-3.9,1.7-4.3,4.5h8.4
            +		C327.4,728.4,325.9,726.8,323.5,726.8z"/>
            +	<path d="M341.8,742.8c-4.5,0-8-2.1-8-8.6c0-5.8,3-9.7,8.8-9.7c1.5,0,3.2,0.2,4.3,0.6v5.2h-2.1c-0.2-1.1-0.4-2.1-0.4-3
            +		c-0.6-0.2-1.5-0.4-2.4-0.4c-3.2,0-5,2.6-5,6.5c0,3.5,1.1,6.3,5.4,6.3c1.5,0,3-0.4,4.3-0.9l0.6,2.6
            +		C345.9,742.2,344,742.8,341.8,742.8z"/>
            +	<path d="M356.9,742.8c-3.7,0-4.9-1.5-4.9-5.4v-10.3h-3.7v-2.4h3.7v-5.8l3.2-0.9v6.7h5v2.4h-5v9.1c0,3,0.6,3.7,2.6,3.7
            +		c0.7,0,1.7-0.2,2.2-0.4l0.4,2.6C359.3,742.6,358,742.8,356.9,742.8z"/>
            +	<path d="M384,750.5c-6-5.4-8.8-11.2-8.8-18.1c0-7.3,3.5-13.4,9-18.3l1.9,1.9c-4.9,4.7-7.5,10.3-7.5,16.1c0,6,2.4,11.4,7.5,16.4
            +		L384,750.5z"/>
            +	<path d="M394.6,742.4v-3h6.5v-15.1l-6.1,4.1l-1.1-2.8l7.8-4.9h2.8v18.7h5.6v3H394.6L394.6,742.4z"/>
            +	<path d="M417.4,747.1c3.7-0.9,4.9-2.6,4.9-3.9c0-2.2-1.9-2.2-1.9-4.3c0-1.5,1.1-2.6,2.6-2.6c2.2,0,3.4,2.2,3.4,4.5
            +		c0,4.5-3,7.1-8.2,8.4L417.4,747.1z"/>
            +	<path d="M436.8,742.4v-2.6l5-4.7c4.5-3.9,5.6-5.4,5.6-7.8c0-2.4-1.3-3.9-4.5-3.9c-2.1,0-4.1,0.9-5.2,1.9l-0.7-2.8
            +		c1.9-1.1,3.9-1.9,6.5-1.9c4.9,0,7.3,2.8,7.3,6.3c0,3-1.5,5.4-5.6,8.8l-4.3,3.7h-0.2c1.7-0.2,5.6-0.2,11-0.2v3.2H436.8L436.8,742.4z
            +		"/>
            +	<path d="M460.3,747.1c3.7-0.9,4.9-2.6,4.9-3.9c0-2.2-1.9-2.2-1.9-4.3c0-1.5,1.1-2.6,2.6-2.6c2.2,0,3.4,2.2,3.4,4.5
            +		c0,4.5-3,7.1-8.2,8.4L460.3,747.1z"/>
            +	<path d="M492.6,739.4v6h-3.2v-6h-11l-0.2-2.6l9.9-15.9h4.5v15.5h4.1v3H492.6L492.6,739.4z M489.5,723.9L489.5,723.9l-8,12.7
            +		c2.1,0,6.7,0,8,0V723.9z"/>
            +	<path d="M503.3,747.1c3.7-0.9,4.9-2.6,4.9-3.9c0-2.2-1.9-2.2-1.9-4.3c0-1.5,1.1-2.6,2.6-2.6c2.2,0,3.4,2.2,3.4,4.5
            +		c0,4.5-3,7.1-8.2,8.4L503.3,747.1z"/>
            +	<path d="M527.7,745.8c-1.5,0-3.2-0.2-4.5-0.6l0.6-3c1.3,0.4,2.8,0.7,4.3,0.7c3.7,0,6.3-2.2,6.3-4.9c0-2.6-2.1-4.5-6-4.5
            +		c-1.3,0-2.2,0-3.2,0.2v-2.6h0.7c5,0,7.7-1.5,7.7-4.5c0-2.2-1.7-3.5-4.3-3.5c-2.1,0-3.5,0.6-5,1.3l-0.6-2.8c1.9-0.7,3.9-1.3,6.2-1.3
            +		c4.9,0,7.3,2.4,7.3,5.8c0,2.8-1.7,4.9-4.3,5.6l0,0c3,0.4,5.2,2.8,5.2,5.8C538,742.4,533.7,745.8,527.7,745.8z"/>
            +	<path d="M548.4,714.2c6,5.6,8.8,11.2,8.8,18.1c0,7.3-3.5,13.4-9,18.3l-1.9-1.9c4.9-4.7,7.5-10.3,7.5-16.1c0-6-2.4-11.6-7.5-16.4
            +		L548.4,714.2z"/>
            +	<path d="M574.8,748l-1.3-1.3c2.2-2.4,2.4-4.1,1.5-5.2c-0.9-1.3-0.2-3.2,1.5-3.2C579.1,738.3,580.2,743,574.8,748z M576.4,732.3
            +		c-1.3,0-2.2-0.9-2.2-2.2s0.9-2.2,2.2-2.2s2.2,0.9,2.2,2.2C578.7,731.2,577.6,732.3,576.4,732.3z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M316.2,594.6l-4.9,15.5h-3.7l-3.5-10.5c-0.4-1.1-0.7-2.2-0.9-3.5l0,0c-0.4,1.5-0.7,3-1.3,4.5l-3,9.5h-3.7l-4.7-15.5
            +		c-0.7,0-1.5-0.2-2.2-0.4v-1.9h8.2v1.9c-0.7,0.2-1.5,0.4-2.4,0.4l2.2,8c0.4,1.5,0.7,3,1.1,4.1l0,0c0.4-1.5,0.7-3,1.3-4.3l3.2-10.1
            +		h3.4l3.2,10.1c0.6,2.1,0.9,3.2,1.3,4.3l0,0c0.4-1.3,0.6-2.2,1.1-3.9l2.2-8c-0.7,0-1.7-0.2-2.4-0.4v-1.9h8v1.9
            +		C317.7,594.4,317,594.6,316.2,594.6z"/>
            +	<path d="M319.8,610.1v-1.9c0.9-0.2,2.1-0.4,3.2-0.4v-13.1c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v15.5
            +		c1.1,0,2.1,0.2,3,0.4v1.9h-9.3V610.1z M324.4,588.8c-1.1,0-2.2-0.9-2.2-2.1s0.9-2.1,2.2-2.1c1.1,0,2.1,0.9,2.1,2.1
            +		C326.7,587.9,325.5,588.8,324.4,588.8z"/>
            +	<path d="M343.5,610.1c0-0.9,0-2.6,0.4-3.5l0,0c-0.9,2.4-3.2,3.9-6,3.9c-4.3,0-6.5-3.2-6.5-8.4c0-6.2,3.5-10.1,9.1-10.1
            +		c0.9,0,1.9,0,3,0.2v-5.8c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v23.5c0.9,0.2,2.1,0.4,3,0.4v1.9
            +		C347.9,610.1,345.5,610.3,343.5,610.1z M343.5,594.9c-1.1-0.2-2.2-0.4-3.2-0.4c-3.4,0-5.6,2.1-5.6,7.1c0,3.9,1.3,6,3.9,6
            +		c3.2,0,4.9-3.7,4.9-6.9V594.9L343.5,594.9z"/>
            +	<path d="M358.2,610.4c-3.7,0-4.9-1.5-4.9-5.4v-10.3h-3.7v-2.4h3.7v-5.8l3.2-0.9v6.7h5v2.4h-5v9.1c0,3,0.6,3.7,2.6,3.7
            +		c0.7,0,1.7-0.2,2.2-0.4l0.4,2.6C360.6,610.3,359.3,610.4,358.2,610.4z"/>
            +	<path d="M378,610.1v-11.4c0-2.4-0.7-4.1-3-4.1c-3,0-5,3-5,6.9v6.2c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.1v-1.9c0.9-0.2,2.1-0.4,3-0.4
            +		v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v8.4c0,1.1,0,2.6-0.4,3.5l0,0c1.1-2.4,3.2-3.9,6.2-3.9
            +		c4.1,0,5.4,2.6,5.4,5.8v10.1c0.9,0,2.1,0.2,3,0.4v1.9L378,610.1L378,610.1z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M521,468.7v-11.3c0-2.4-0.7-4.1-3-4.1c-3,0-5,3-5,6.9v6.2c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.1v-1.9c0.9-0.2,2.1-0.4,3-0.4
            +		v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v8.4c0,1.1,0,2.6-0.4,3.5l0,0c1.1-2.4,3.2-3.9,6.2-3.9
            +		c4.1,0,5.4,2.6,5.4,5.8v10.1c0.9,0,2.1,0.2,3,0.4v1.9L521,468.7L521,468.7z"/>
            +	<path d="M544.3,459.8h-11.8c-0.2,4.7,1.7,6.7,5.6,6.7c1.7,0,3.5-0.4,5-1.1l0.4,2.6c-1.9,0.7-3.9,1.1-6.2,1.1
            +		c-5.4,0-8.4-2.8-8.4-9.1c0-5.2,3-9.3,8-9.3s7.1,3.4,7.1,7.3C544.3,458.3,544.3,459,544.3,459.8z M537.1,453.1
            +		c-2.2,0-3.9,1.7-4.3,4.5h8.4C541.2,454.7,539.7,453.1,537.1,453.1z"/>
            +	<path d="M547.1,468.7v-1.9c0.9-0.2,2.1-0.4,3.2-0.4v-12.9c-0.9-0.2-2.1-0.4-3.2-0.4v-1.7c1.9-0.2,4.3-0.4,6.3-0.2v15.5
            +		c1.1,0,2.1,0.2,3,0.4v1.9h-9.3V468.7L547.1,468.7z M551.8,447.3c-1.1,0-2.2-0.9-2.2-2.1s0.9-2.1,2.2-2.1c1.1,0,2.1,0.9,2.1,2.1
            +		C553.9,446.3,552.9,447.3,551.8,447.3z"/>
            +	<path d="M566,477.9c-4.7,0-7.5-1.9-7.5-5.4c0-2.1,1.3-3.9,3-4.7c-1.1-0.4-1.7-1.5-1.7-2.6c0-1.3,0.7-2.4,2.1-3
            +		c-1.7-0.9-2.6-2.6-2.6-4.9c0-3.5,2.6-6.7,7.5-6.7c0.9,0,1.7,0.2,2.4,0.4h6v2.6h-3c0.9,0.7,1.5,1.9,1.5,3.4c0,3.7-2.4,6.5-7.5,6.5
            +		c-0.7,0-1.3,0-1.9-0.2c-0.7,0.4-1.1,0.9-1.1,1.5c0,0.9,0.9,1.3,3,1.3l3.2,0.2c3.9,0.2,6,1.9,6,5.2
            +		C575.3,474.9,571.6,477.9,566,477.9z M568.4,468.6l-3.4-0.2c-0.4,0-0.7,0-1.1,0c-1.3,0.9-2.2,2.2-2.2,3.5c0,2.1,2.1,3.4,4.9,3.4
            +		c3.5,0,5.6-1.7,5.6-3.9C572.2,469.9,571,468.7,568.4,468.6z M566.6,453.1c-2.6,0-4.3,1.7-4.3,3.9c0,2.4,1.5,3.9,4.1,3.9
            +		s4.1-1.5,4.1-3.9S569,453.1,566.6,453.1z"/>
            +	<path d="M591.4,468.7v-11.3c0-2.4-0.7-4.1-3-4.1c-3,0-5,3-5,6.9v6.2c0.9,0,2.1,0.2,2.8,0.4v1.9H577v-1.9c0.9-0.2,2.1-0.4,3-0.4
            +		v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v8.4c0,1.1,0,2.6-0.4,3.5l0,0c1.1-2.4,3.2-3.9,6.2-3.9
            +		c4.1,0,5.4,2.6,5.4,5.8v10.1c0.9,0,2.1,0.2,3,0.4v1.9L591.4,468.7L591.4,468.7z"/>
            +	<path d="M606.5,468.9c-3.7,0-4.9-1.5-4.9-5.4v-10.3h-3.7v-2.4h3.7V445l3.2-0.9v6.7h5v2.4h-5v9.1c0,3,0.6,3.7,2.6,3.7
            +		c0.7,0,1.7-0.2,2.2-0.4l0.4,2.6C608.9,468.9,607.6,468.9,606.5,468.9z"/>
            +</g>
            +</svg>
            diff --git a/dist/assets/learn/color/grayscale.svg b/dist/assets/learn/color/grayscale.svg
            new file mode 100644
            index 0000000000..b595283e90
            --- /dev/null
            +++ b/dist/assets/learn/color/grayscale.svg
            @@ -0,0 +1,24 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 645 200" enable-background="new 0 0 645 200" xml:space="preserve">
            +<rect x="102.5" y="48" fill="#020202" stroke="#000000" stroke-miterlimit="10" width="74" height="75"/>
            +<rect x="176.5" y="48" fill="#323232" stroke="#000000" stroke-miterlimit="10" width="74" height="75"/>
            +<rect x="250.5" y="48" fill="#575757" stroke="#000000" stroke-miterlimit="10" width="74" height="75"/>
            +<rect x="324.5" y="48" fill="#A2A2A2" stroke="#000000" stroke-miterlimit="10" width="74" height="75"/>
            +<rect x="398.5" y="48" fill="#D1D1D1" stroke="#000000" stroke-miterlimit="10" width="74" height="75"/>
            +<rect x="471.5" y="48" fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" width="74" height="75"/>
            +<rect x="133" y="133.2" fill="none" width="17.5" height="25.5"/>
            +<text transform="matrix(1 0 0 1 133 146.3896)" font-family="'TheSansMono-W5Regular'" font-size="18">0</text>
            +<rect x="204.8" y="133.2" fill="none" width="34.5" height="25.5"/>
            +<text transform="matrix(1 0 0 1 204.75 146.3896)" font-family="'TheSansMono-W5Regular'" font-size="18">50</text>
            +<rect x="271.2" y="134.2" fill="none" width="34.5" height="25.5"/>
            +<text transform="matrix(1 0 0 1 271.25 147.3896)" font-family="'TheSansMono-W5Regular'" font-size="18">87</text>
            +<rect x="344.2" y="134.2" fill="none" width="34.5" height="25.5"/>
            +<text transform="matrix(1 0 0 1 344.25 147.3896)" font-family="'TheSansMono-W5Regular'" font-size="18">167</text>
            +<rect x="418.2" y="133.2" fill="none" width="34.5" height="25.5"/>
            +<text transform="matrix(1 0 0 1 418.25 146.3896)" font-family="'TheSansMono-W5Regular'" font-size="18">209</text>
            +<rect x="493.2" y="134.2" fill="none" width="34.5" height="25.5"/>
            +<text transform="matrix(1 0 0 1 493.25 147.3896)" font-family="'TheSansMono-W5Regular'" font-size="18">255</text>
            +</svg>
            diff --git a/dist/assets/learn/color/hsb.png b/dist/assets/learn/color/hsb.png
            new file mode 100644
            index 0000000000..502d438713
            Binary files /dev/null and b/dist/assets/learn/color/hsb.png differ
            diff --git a/dist/assets/learn/color/rgb.jpg b/dist/assets/learn/color/rgb.jpg
            new file mode 100644
            index 0000000000..692491a293
            Binary files /dev/null and b/dist/assets/learn/color/rgb.jpg differ
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-01.png b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-01.png
            new file mode 100644
            index 0000000000..28779fc275
            Binary files /dev/null and b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-01.png differ
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-02.png b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-02.png
            new file mode 100644
            index 0000000000..abaa5164e9
            Binary files /dev/null and b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-02.png differ
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-03.svg b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-03.svg
            new file mode 100644
            index 0000000000..2507b84658
            --- /dev/null
            +++ b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-03.svg
            @@ -0,0 +1,300 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 width="1046px" height="600px" viewBox="-259.5 0 1046 600" enable-background="new -259.5 0 1046 600" xml:space="preserve">
            +<rect x="387.954" y="117.272" opacity="0.5" fill="#FFFF00" enable-background="new    " width="388.562" height="390.228"/>
            +<rect x="-54.773" y="118.712" opacity="0.5" fill="#FFFF00" enable-background="new    " width="195.228" height="195.228"/>
            +<g>
            +	<rect x="-248.106" y="118.864" fill="none" stroke="#999999" stroke-width="1.3" width="388.561" height="388.56"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-248.106" y1="442.728" x2="140.53" y2="442.728"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-248.106" y1="377.727" x2="140.53" y2="377.727"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-248.106" y1="313.182" x2="140.53" y2="313.182"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-248.106" y1="248.409" x2="140.53" y2="248.409"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-248.106" y1="183.636" x2="140.53" y2="183.636"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="75.53" y1="118.864" x2="75.53" y2="507.576"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="11.136" y1="118.864" x2="11.136" y2="507.576"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-53.788" y1="118.864" x2="-53.788" y2="507.576"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-118.485" y1="118.864" x2="-118.485" y2="507.576"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-183.182" y1="118.864" x2="-183.182" y2="507.576"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M175.184,320.606l-3.485-5.833l-3.485,5.833h-4.773v-1.667c0.909-0.227,1.818-0.379,2.728-0.379l3.788-5.605l-3.712-5.605
            +		c-0.909,0-1.818-0.229-2.576-0.379v-1.667h4.772l3.258,5.606l3.485-5.606h4.545v1.667c-0.909,0.227-1.818,0.379-2.728,0.379
            +		l-3.485,5.529l3.788,5.834c0.909,0,1.667,0.227,2.576,0.379v1.666h-4.772L175.184,320.606L175.184,320.606z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-48.75,81.364l-5.531,15.227c-1.667,4.773-3.257,6.363-6.667,6.363c-0.606,0-1.439,0-2.121-0.227l0.227-2.576
            +		c0.682,0.228,1.364,0.379,2.045,0.379c1.667,0,2.728-0.909,3.788-3.788l0.682-1.817h-0.682l-4.773-13.561
            +		c-0.682,0-1.439-0.229-2.045-0.379v-1.667h7.197v1.667c-0.606,0.227-1.364,0.379-2.045,0.379l2.348,6.666
            +		c0.606,1.439,0.909,2.576,1.364,3.788l0,0c0.228-1.137,0.909-2.879,1.439-4.546l2.045-5.984c-0.682,0-1.439-0.228-2.045-0.379
            +		v-1.667h7.045v1.667C-47.159,81.212-47.917,81.364-48.75,81.364z"/>
            +</g>
            +<polyline fill="none" stroke="#000000" stroke-width="1.3" points="-61.591,127.121 -53.863,119.47 -46.061,127.121 "/>
            +<polyline fill="none" stroke="#000000" stroke-width="1.3" points="130.455,305.455 138.106,313.182 130.455,320.909 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="138.106" y1="313.182" x2="-248.106" y2="313.182"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-53.788" y1="120.151" x2="-53.788" y2="506.212"/>
            +<polyline fill="none" stroke="#000000" stroke-width="1.3" points="-46.212,500.984 -53.939,508.409 -61.742,500.984 "/>
            +<polyline fill="none" stroke="#000000" stroke-width="1.3" points="-240.455,320.909 -248.106,313.182 -240.455,305.455 "/>
            +<g enable-background="new    ">
            +	<path d="M-130.227,583.409v-1.667c0.682-0.227,1.818-0.379,2.727-0.379v-17.045c-0.909,0-1.818-0.228-2.727-0.379v-1.667h13.636
            +		v4.925h-2.045c-0.228-0.909-0.379-1.818-0.379-2.576h-5.606v6.97h4.545c0.227-0.682,0.227-1.439,0.379-2.121h1.818v6.363h-1.818
            +		c-0.228-0.682-0.379-1.439-0.379-2.121h-4.545v7.576h5.606c0.227-0.682,0.227-1.818,0.379-2.728h2.045v4.924h-13.636V583.409z"/>
            +	<path d="M-113.561,583.409v-1.667c0.682-0.227,1.818-0.379,2.727-0.379V570c-0.682-0.228-1.818-0.228-2.727-0.379v-1.515
            +		c1.667-0.228,3.712-0.379,5.53-0.228v13.561c0.909,0,1.818,0.228,2.576,0.379v1.666h-8.106V583.409z M-109.394,564.697
            +		c-1.136,0-1.818-0.682-1.818-1.818s0.909-1.818,1.818-1.818s1.818,0.682,1.818,1.818S-108.409,564.697-109.394,564.697z"/>
            +	<path d="M-96.894,591.363c-4.091,0-6.591-1.666-6.591-4.772c0-1.818,1.364-3.258,2.576-4.167c-0.909-0.379-1.439-1.363-1.439-2.348
            +		c0-1.137,0.682-2.122,1.667-2.576c-1.439-0.909-2.349-2.121-2.349-4.167c0-3.105,2.349-5.833,6.591-5.833
            +		c0.909,0,1.439,0.228,2.121,0.379h5.228V570h-2.576c0.682,0.606,1.363,1.667,1.363,2.879c0,3.105-2.121,5.605-6.591,5.605
            +		c-0.606,0-1.136,0-1.667-0.227c-0.682,0.379-0.909,0.682-0.909,1.363c0,0.909,0.682,1.137,2.728,1.363l2.878,0.228
            +		c3.258,0.228,5.228,1.667,5.228,4.546C-88.712,588.939-91.97,591.363-96.894,591.363z M-94.773,583.409l-2.878-0.228
            +		c-0.379,0-0.682,0-0.909,0c-1.364,0.909-2.045,1.818-2.045,3.106c0,1.818,1.818,2.879,4.167,2.879c3.106,0,4.924-1.439,4.924-3.258
            +		C-91.667,584.242-92.5,583.409-94.773,583.409z M-96.591,569.621c-2.349,0-3.712,1.439-3.712,3.485
            +		c0,2.121,1.364,3.484,3.712,3.484c2.121,0,3.712-1.363,3.712-3.484C-93.106,570.909-94.167,569.621-96.591,569.621z"/>
            +	<path d="M-74.621,583.409v-10.076c0-2.121-0.606-3.484-2.728-3.484c-2.576,0-4.394,2.575-4.394,5.984v5.228
            +		c0.909,0,1.818,0.228,2.576,0.379v1.667h-7.879v-1.667c0.682-0.228,1.667-0.379,2.576-0.379v-18.712
            +		c-0.682-0.228-1.818-0.228-2.727-0.379v-1.667c1.667-0.227,3.712-0.379,5.53-0.227v7.272c0,0.909,0,2.121-0.379,3.105l0,0
            +		c0.909-2.121,2.727-3.484,5.53-3.484c3.485,0,4.773,2.121,4.773,4.924v8.713c0.909,0,1.818,0.227,2.576,0.378v1.667h-5.152
            +		C-74.621,582.803-74.621,583.409-74.621,583.409z"/>
            +	<path d="M-61.742,583.712c-3.106,0-4.167-1.363-4.167-4.772v-9.016h-3.106v-2.121h3.106v-5.151l2.728-0.682v5.833h4.394v2.121
            +		h-4.394v8.03c0,2.576,0.606,3.258,2.121,3.258c0.682,0,1.439-0.228,2.045-0.228l0.379,2.349
            +		C-59.318,583.484-60.53,583.712-61.742,583.712z"/>
            +	<path d="M-44.394,583.409v-10.076c0-2.121-0.606-3.484-2.727-3.484c-2.576,0-4.394,2.575-4.394,5.984v5.228
            +		c0.909,0,1.818,0.228,2.576,0.379v1.667h-8.03v-1.667c0.682-0.228,1.667-0.379,2.576-0.379v-18.712
            +		c-0.682-0.228-1.818-0.228-2.727-0.379v-1.667c1.667-0.227,3.712-0.379,5.53-0.227v7.272c0,0.909,0,2.121-0.379,3.105l0,0
            +		c0.909-2.121,2.727-3.484,5.53-3.484c3.485,0,4.773,2.121,4.773,4.924v8.713c0.909,0,1.818,0.227,2.576,0.378v1.667h-5.152v0.758
            +		H-44.394L-44.394,583.409z"/>
            +	<path d="M-12.727,574.772v7.651c-2.046,0.683-4.773,1.364-6.97,1.364c-6.364,0-10.455-3.788-10.455-10.455
            +		c0-6.666,4.091-11.363,11.363-11.363c2.046,0,3.788,0.379,5.833,0.682v4.925H-15c-0.227-1.137-0.379-2.046-0.379-2.728
            +		c-1.136-0.379-2.348-0.606-3.712-0.606c-4.545,0-8.03,2.728-8.03,8.409c0,5.228,3.106,8.258,7.879,8.258
            +		c1.439,0,2.576-0.228,3.712-0.606v-5.833c-0.909,0-1.818-0.228-2.728-0.379v-1.667h7.652v1.667
            +		C-11.136,574.394-11.894,574.621-12.727,574.772z"/>
            +	<path d="M1.894,570.379c-3.712-0.606-5.152,1.818-5.152,6.667v4.166c0.909,0,1.818,0.228,2.728,0.379v1.667h-8.409v-1.667
            +		c0.682-0.228,1.818-0.379,2.728-0.379v-11.363c-0.682-0.228-1.818-0.228-2.728-0.379v-1.439c1.667-0.228,3.712-0.379,5.53-0.228
            +		c0,0.909-0.227,2.349-0.379,3.713l0,0c0.682-2.122,2.122-4.395,5.606-4.092C1.894,567.5,1.894,570.379,1.894,570.379z"/>
            +	<path d="M12.955,583.409c0-1.137,0-2.121,0.227-3.106l0,0c-0.682,1.818-2.727,3.485-5.227,3.485s-4.394-1.667-4.394-4.091
            +		c0-3.258,3.485-5.228,9.318-5.228v-1.137c0-2.121-0.682-3.484-3.258-3.484c-0.909,0-2.045,0.228-2.879,0.379
            +		c0,0.682-0.227,1.666-0.378,2.575H4.545v-4.394c1.667-0.606,3.485-0.909,5.228-0.909c4.545,0,5.833,2.045,5.833,5.151v8.258
            +		c0.682,0.228,1.818,0.228,2.576,0.379v1.666C16.97,583.409,14.697,583.484,12.955,583.409z M12.955,576.212
            +		c-4.924,0-6.591,1.364-6.591,2.879c0,1.363,0.909,2.349,2.348,2.349c2.576,0,4.167-2.576,4.167-4.925
            +		C12.955,576.516,12.955,576.212,12.955,576.212z"/>
            +	<path d="M30.985,583.409c0-0.909,0-2.121,0.227-3.106l0,0c-0.909,2.046-2.727,3.485-5.227,3.485c-3.788,0-5.606-2.728-5.606-7.272
            +		c0-5.531,3.106-8.713,8.03-8.713c0.909,0,1.667,0,2.576,0.228v-4.924c-0.682-0.228-1.818-0.228-2.727-0.379v-1.818
            +		c1.667-0.228,3.712-0.379,5.53-0.228v20.53c0.682,0.228,1.818,0.228,2.576,0.379v1.667
            +		C34.849,583.409,32.651,583.484,30.985,583.409z M30.909,570.151c-0.909-0.228-1.818-0.379-2.728-0.379
            +		c-2.878,0-4.924,1.818-4.924,6.212c0,3.258,1.136,5.228,3.484,5.228c2.728,0,4.167-3.258,4.167-5.984
            +		C30.909,575.379,30.909,570.151,30.909,570.151z"/>
            +	<path d="M51.136,575.454H40.985c-0.227,4.092,1.439,5.834,4.924,5.834c1.439,0,3.106-0.379,4.394-0.909l0.378,2.121
            +		c-1.667,0.606-3.485,0.909-5.53,0.909c-4.772,0-7.272-2.576-7.272-8.03c0-4.546,2.576-8.258,6.97-8.258
            +		c4.394,0,6.212,2.879,6.212,6.363C51.136,574.242,51.136,575,51.136,575.454z M44.924,569.621c-2.045,0-3.485,1.439-3.788,3.788
            +		h7.273C48.409,571.137,47.045,569.621,44.924,569.621z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M500.076,584.47c-6.364,0-9.697-4.091-9.697-10.454c0-6.364,3.484-11.364,10.151-11.364c1.667,0,3.485,0.228,5.151,0.606
            +		v5.151h-2.045c-0.228-1.137-0.379-2.046-0.379-2.879c-1.137-0.379-2.046-0.379-3.106-0.379c-4.545,0-6.667,3.712-6.667,8.409
            +		c0,5.151,2.349,8.258,7.197,8.258c1.667,0,3.712-0.379,4.925-1.137l0.605,2.349C504.318,583.863,502.272,584.47,500.076,584.47z"/>
            +	<path d="M514.772,584.47c-4.166,0-6.97-2.349-6.97-7.879c0-4.772,2.879-8.258,7.651-8.258c4.091,0,6.97,2.121,6.97,7.879
            +		C522.349,580.758,519.621,584.47,514.772,584.47z M515.151,570.53c-2.349,0-4.394,1.667-4.394,5.606
            +		c0,3.712,1.439,5.605,4.394,5.605c2.349,0,4.394-1.818,4.394-5.605C519.394,572.728,517.954,570.53,515.151,570.53z"/>
            +	<path d="M546.667,584.091v-10.075c0-2.122-0.606-3.485-2.576-3.485c-2.121,0-4.394,2.349-4.394,6.212v5.228
            +		c0.909,0,1.818,0.228,2.575,0.379v1.667h-5.228v-10.076c0-2.046-0.378-3.484-2.575-3.484c-2.349,0-4.394,2.575-4.394,6.212v5.228
            +		c0.908,0,1.817,0.227,2.575,0.378v1.667h-8.03v-1.667c0.682-0.227,1.818-0.378,2.728-0.378V570.53
            +		c-0.682-0.228-1.818-0.228-2.728-0.379v-1.666c1.667-0.228,3.788-0.379,5.53-0.228c0,0.909-0.228,2.349-0.228,3.258l0,0
            +		c0.909-2.121,2.879-3.713,5.228-3.713c3.258,0,4.167,2.121,4.395,3.485c0.605-1.439,2.348-3.485,5.227-3.485
            +		s4.546,1.667,4.546,5.152v8.636c0.909,0,1.818,0.228,2.575,0.379v1.667L546.667,584.091L546.667,584.091z"/>
            +	<path d="M561.061,584.242c-0.909,0-1.667,0-2.728-0.227v5.605c0.909,0,1.818,0.228,2.728,0.379v1.667h-8.258V590
            +		c0.682-0.228,1.667-0.379,2.576-0.379V570.53c-0.682-0.228-1.667-0.228-2.576-0.379v-1.667c1.439-0.227,3.713-0.378,5.228-0.227
            +		c0,0.909-0.228,2.349-0.228,3.105l0,0c0.909-2.121,2.728-3.484,5.151-3.484c3.713,0,5.606,2.576,5.606,7.272
            +		C569.091,581.137,566.212,584.242,561.061,584.242z M562.728,570.53c-2.728,0-4.167,3.258-4.167,5.985v5.151
            +		c0.909,0.227,1.667,0.378,2.728,0.378c2.879,0,4.924-1.817,4.924-6.212C566.212,572.576,565.151,570.53,562.728,570.53z"/>
            +	<path d="M583.561,584.091c0-0.909,0-2.349,0.228-3.258l0,0c-0.909,2.121-2.728,3.713-5.53,3.713c-3.713,0-4.773-2.122-4.773-4.925
            +		v-8.637c-0.682-0.227-1.817-0.227-2.575-0.378v-1.667c1.439-0.228,3.712-0.379,5.53-0.228v10.076c0,2.121,0.605,3.484,2.728,3.484
            +		c2.575,0,4.394-2.575,4.394-5.984v-5.228c-0.682-0.228-1.667-0.228-2.576-0.379v-1.667c1.439-0.227,3.713-0.378,5.228-0.227v13.333
            +		c0.682,0.228,1.818,0.228,2.576,0.379v1.667C587.424,584.091,585.228,584.242,583.561,584.091z"/>
            +	<path d="M596.742,584.47c-3.105,0-4.166-1.363-4.166-4.772v-9.016h-3.106v-2.121h3.106v-5.151l2.727-0.682v5.833h4.395v2.121
            +		h-4.395v8.03c0,2.576,0.606,3.258,2.121,3.258c0.683,0,1.439-0.228,2.046-0.228l0.379,2.349
            +		C598.863,584.242,597.651,584.47,596.742,584.47z"/>
            +	<path d="M615.228,576.212h-10.151c-0.228,4.091,1.439,5.833,4.924,5.833c1.439,0,3.106-0.378,4.394-0.908l0.379,2.121
            +		c-1.666,0.605-3.484,0.909-5.53,0.909c-4.772,0-7.272-2.576-7.272-8.03c0-4.546,2.576-8.258,6.97-8.258s6.212,2.879,6.212,6.363
            +		C615.455,575,615.455,575.682,615.228,576.212z M608.939,570.379c-2.046,0-3.485,1.439-3.788,3.788h7.272
            +		C612.424,571.894,611.137,570.379,608.939,570.379z"/>
            +	<path d="M628.333,571.137c-3.712-0.606-5.151,1.818-5.151,6.666v4.167c0.909,0,1.818,0.228,2.728,0.379v1.667h-8.258v-1.667
            +		c0.682-0.228,1.818-0.379,2.728-0.379v-11.363c-0.682-0.228-1.818-0.228-2.728-0.379v-1.667c1.667-0.228,3.712-0.379,5.53-0.228
            +		c0,0.909-0.228,2.349-0.379,3.713l0,0c0.682-2.122,2.121-4.395,5.606-4.092L628.333,571.137z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-193.561,340.834v-2.729h9.849v2.576L-193.561,340.834L-193.561,340.834z"/>
            +	<path d="M-176.591,348.863v-2.348l4.545-4.092c4.091-3.258,4.924-4.772,4.924-6.666c0-2.046-1.364-3.484-3.788-3.484
            +		c-1.818,0-3.485,0.908-4.545,1.666l-0.606-2.576c1.667-0.908,3.485-1.666,5.606-1.666c4.167,0,6.364,2.348,6.364,5.605
            +		c0,2.728-1.439,4.773-4.924,7.652l-3.788,3.257h-0.227c1.439-0.228,4.924-0.228,9.47-0.228v2.728L-176.591,348.863
            +		L-176.591,348.863z"/>
            +</g>
            +<text transform="matrix(1 0 0 1 -150.7744 348.9209)" font-family="'TheSerif-HP5Plain'" font-size="31.3586" letter-spacing="17"> </text>
            +<g enable-background="new    ">
            +	<path d="M-126.364,340.834v-2.729h9.849v2.576L-126.364,340.834L-126.364,340.834z"/>
            +	<path d="M-108.788,348.863v-2.575h5.606v-13.183l-5.53,3.485l-0.909-2.349l6.97-4.166h2.348v16.287h4.924v2.576L-108.788,348.863
            +		L-108.788,348.863z"/>
            +</g>
            +<text transform="matrix(1 0 0 1 -74.4688 348.9209)" font-family="'TheSerif-HP5Plain'" font-size="31.3586" letter-spacing="3"> </text>
            +<g enable-background="new    ">
            +	<path d="M-36.97,349.166c-4.167,0-7.651-2.348-7.651-9.696c0-6.212,3.788-9.696,8.257-9.696c4.091,0,7.652,2.348,7.652,9.469
            +		C-28.788,345.682-32.576,349.166-36.97,349.166z M-36.818,332.197c-2.576,0-4.924,2.121-4.924,7.272
            +		c0,5.228,2.045,7.575,4.924,7.575c2.576,0,4.924-2.121,4.924-7.196C-31.894,334.395-33.939,332.197-36.818,332.197z"/>
            +	<path d="M13.485,348.863v-2.575h5.606v-13.183l-5.53,3.485l-0.909-2.349l6.97-4.166h2.349v16.287h4.924v2.576L13.485,348.863
            +		L13.485,348.863z"/>
            +</g>
            +<text transform="matrix(1 0 0 1 42.9512 348.9209)" font-family="'TheSerif-HP5Plain'" font-size="31.3586" letter-spacing="11"> </text>
            +<g enable-background="new    ">
            +	<path d="M75.076,348.863v-2.348l4.545-4.092c4.091-3.258,4.924-4.772,4.924-6.666c0-2.046-1.364-3.484-3.788-3.484
            +		c-1.818,0-3.485,0.908-4.546,1.666l-0.606-2.576c1.667-0.908,3.485-1.666,5.606-1.666c4.167,0,6.364,2.348,6.364,5.605
            +		c0,2.728-1.439,4.773-4.924,7.652l-3.788,3.257h-0.228c1.439-0.228,4.924-0.228,9.47-0.228v2.728L75.076,348.863L75.076,348.863z"
            +		/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-43.333,195.682v-2.348l4.545-4.091c4.091-3.257,4.924-4.772,4.924-6.667c0-2.045-1.363-3.485-3.788-3.485
            +		c-1.818,0-3.485,0.909-4.545,1.667l-0.606-2.576c1.667-0.909,3.485-1.667,5.606-1.667c4.167,0,6.363,2.349,6.363,5.606
            +		c0,2.728-1.439,4.773-4.924,7.651l-3.788,3.258h-0.228c1.439-0.227,4.924-0.227,9.47-0.227v2.727L-43.333,195.682L-43.333,195.682
            +		L-43.333,195.682z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-42.651,261.894v-2.576h5.606v-13.106l-5.53,3.485l-0.909-2.348l6.97-4.167h2.349v16.288h4.924v2.576L-42.651,261.894
            +		L-42.651,261.894z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-41.288,385.984v-2.575h9.849v2.575H-41.288z"/>
            +	<path d="M-23.864,394.091v-2.575h5.606v-13.182l-5.53,3.484l-0.909-2.349l6.97-4.167h2.348v16.288h4.924v2.575L-23.864,394.091
            +		L-23.864,394.091z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-41.288,452.349v-2.728h9.849v2.576L-41.288,452.349L-41.288,452.349z"/>
            +	<path d="M-24.545,460.379v-2.349l4.545-4.091c4.091-3.258,4.924-4.772,4.924-6.667c0-2.045-1.364-3.484-3.788-3.484
            +		c-1.818,0-3.485,0.909-4.545,1.667l-0.606-2.576c1.667-0.909,3.485-1.667,5.606-1.667c4.167,0,6.364,2.349,6.364,5.606
            +		c0,2.728-1.439,4.772-4.924,7.651l-3.788,3.258h-0.227c1.439-0.228,4.924-0.228,9.47-0.228v2.728L-24.545,460.379L-24.545,460.379z
            +		"/>
            +</g>
            +<text transform="matrix(1 0 0 1 39.0288 157.1514)" font-family="'TheSerif-HP5Plain'" font-size="47.1917" letter-spacing="6"> </text>
            +<text transform="matrix(1 0 0 1 215.7344 157.1514)" font-family="'TheSerif-HP5Plain'" font-size="47.1917" letter-spacing="18"> </text>
            +<g>
            +	<rect x="387.954" y="118.864" fill="none" stroke="#999999" stroke-width="1.3" width="388.562" height="388.56"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="387.954" y1="442.728" x2="776.439" y2="442.728"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="387.954" y1="377.727" x2="776.439" y2="377.727"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="387.954" y1="313.182" x2="776.439" y2="313.182"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="387.954" y1="248.409" x2="776.439" y2="248.409"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="387.954" y1="183.636" x2="776.439" y2="183.636"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="711.742" y1="118.864" x2="711.742" y2="507.576"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="647.045" y1="118.864" x2="647.045" y2="507.576"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="582.121" y1="118.864" x2="582.121" y2="507.576"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="517.197" y1="118.864" x2="517.197" y2="507.576"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="452.651" y1="118.864" x2="452.651" y2="507.576"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M395.606,25.53l-3.485-5.833l-3.484,5.833h-4.773v-1.818c0.909-0.227,1.818-0.378,2.728-0.378l3.788-5.606l-3.712-5.606
            +		c-0.909,0-1.818-0.227-2.576-0.379v-1.667h4.772l3.258,5.606l3.485-5.606h4.545v1.667c-0.909,0.228-1.818,0.379-2.728,0.379
            +		l-3.484,5.53l3.788,5.833c0.909,0,1.666,0.227,2.575,0.379v1.667H395.606L395.606,25.53L395.606,25.53z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M299.697,110.151l-5.53,15.228c-1.667,4.772-3.257,6.363-6.667,6.363c-0.606,0-1.439,0-2.121-0.227l0.227-2.576
            +		c0.682,0.227,1.364,0.379,2.045,0.379c1.667,0,2.728-0.909,3.788-3.788l0.682-1.818h-0.682l-4.773-13.561
            +		c-0.682,0-1.439-0.227-2.045-0.379v-1.667h7.197v1.667c-0.606,0.228-1.364,0.379-2.045,0.379l2.348,6.667
            +		c0.606,1.439,0.909,2.576,1.364,3.788l0,0c0.227-1.136,0.909-2.878,1.439-4.545l2.045-5.985c-0.682,0-1.439-0.227-2.045-0.379
            +		v-1.667h6.97v1.667C301.137,110,300.455,110,299.697,110.151z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M393.484,79.242c-4.166,0-7.651-2.348-7.651-9.697c0-6.212,3.788-9.697,8.258-9.697c4.091,0,7.651,2.348,7.651,9.47
            +		C401.742,75.758,398.03,79.242,393.484,79.242z M393.788,62.121c-2.576,0-4.925,2.121-4.925,7.273c0,5.227,2.046,7.576,4.925,7.576
            +		c2.575,0,4.924-2.121,4.924-7.197C398.712,64.47,396.818,62.121,393.788,62.121z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M450.379,78.864v-2.576h5.605V63.182l-5.53,3.485l-0.908-2.348l6.97-4.167h2.348v16.288h4.925v2.576L450.379,78.864
            +		L450.379,78.864z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M512.424,78.864v-2.349l4.546-4.091c4.091-3.258,4.924-4.773,4.924-6.667c0-1.97-1.363-3.485-3.787-3.485
            +		c-1.818,0-3.485,0.909-4.546,1.667l-0.53-2.576c1.667-0.909,3.485-1.667,5.606-1.667c4.166,0,6.363,2.349,6.363,5.606
            +		c0,2.727-1.439,4.772-4.924,7.651l-3.788,3.257h-0.228c1.439-0.227,4.924-0.227,9.47-0.227v2.727L512.424,78.864L512.424,78.864
            +		L512.424,78.864z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M579.394,81.818c-1.363,0-2.727-0.228-3.787-0.606l0.605-2.576c1.137,0.379,2.349,0.606,3.788,0.606
            +		c3.258,0,5.53-1.818,5.53-4.167c0-2.348-1.818-3.788-5.151-3.788c-1.137,0-1.818,0-2.728,0.227v-2.349h0.682
            +		c4.546,0,6.667-1.363,6.667-3.788c0-2.045-1.439-3.106-3.788-3.106c-1.667,0-3.105,0.606-4.394,1.364l-0.606-2.348
            +		c1.667-0.682,3.258-1.137,5.53-1.137c4.167,0,6.213,2.045,6.213,4.924c0,2.349-1.439,4.167-3.788,4.924l0,0
            +		c2.575,0.379,4.545,2.576,4.545,5.151C588.333,78.864,584.621,81.818,579.394,81.818z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M648.939,76.061v5.228h-2.728v-5.228h-9.696l-0.228-2.349L645,59.849h4.091v13.561h3.712v2.576h-3.787v0.076H648.939z
            +		 M646.212,62.5L646.212,62.5l-7.196,11.136c1.817,0,5.833,0,7.196,0V62.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M704.546,81.818c-0.909,0-2.349-0.228-3.485-0.379l0.228-2.576c1.136,0.378,2.575,0.378,3.484,0.378
            +		c3.788,0,5.834-2.121,5.834-4.772c0-2.728-2.122-4.091-5.606-4.091c-1.363,0-2.349,0.227-3.258,0.227V59.849h10.985v2.727h-8.409
            +		v5.53c0.605,0,1.136,0,1.439,0c5.151,0,7.879,2.728,7.879,5.985C713.863,78.485,710.076,81.818,704.546,81.818z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M770.228,79.242c-4.395,0-7.197-3.257-7.197-9.015c0-9.016,4.394-12.803,10.454-12.803c0.606,0,1.439,0,1.818,0.227v2.576
            +		C774.621,60,773.939,60,773.258,60c-4.091,0-6.212,2.349-7.197,6.667c-0.228,0.379-0.228,0.909-0.379,1.667l0,0
            +		c1.137-1.818,2.879-2.728,4.925-2.728c4.166,0,6.363,2.728,6.363,6.212C777.424,76.061,774.394,79.242,770.228,79.242z
            +		 M770.228,67.955c-2.576,0-4.091,2.121-4.091,4.091c0,2.576,1.439,4.773,4.166,4.773c2.576,0,4.091-1.818,4.091-4.546
            +		C774.394,69.47,772.954,67.955,770.228,67.955z"/>
            +</g>
            +<circle cx="387.954" cy="118.864" r="10.076"/>
            +<circle cx="-54.773" cy="312.349" r="10.075"/>
            +<g enable-background="new    ">
            +	<path d="M344.849,133.106c-4.167,0-7.651-2.348-7.651-9.697c0-6.212,3.787-9.697,8.257-9.697c4.092,0,7.652,2.349,7.652,9.47
            +		C353.106,129.621,349.242,133.106,344.849,133.106z M345.076,116.288c-2.576,0-4.925,2.121-4.925,7.272
            +		c0,5.228,2.046,7.576,4.925,7.576c2.575,0,4.924-2.121,4.924-7.197C350,118.409,347.954,116.288,345.076,116.288z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M338.863,195.682v-2.576h5.606v-13.182l-5.53,3.485l-0.909-2.349l6.97-4.167h2.349v16.288h4.924v2.576L338.863,195.682
            +		L338.863,195.682z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M338.258,258.409v-2.349l4.545-4.091c4.091-3.258,4.925-4.773,4.925-6.667c0-2.045-1.364-3.485-3.788-3.485
            +		c-1.818,0-3.485,0.909-4.546,1.667l-0.605-2.576c1.666-0.909,3.484-1.667,5.605-1.667c4.167,0,6.364,2.349,6.364,5.606
            +		c0,2.727-1.439,4.772-4.925,7.651l-3.787,3.258h-0.228c1.439-0.228,4.924-0.228,9.47-0.228v2.728L338.258,258.409L338.258,258.409
            +		L338.258,258.409z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M342.424,324.016c-1.363,0-2.727-0.228-3.787-0.606l0.605-2.575c1.137,0.378,2.349,0.605,3.788,0.605
            +		c3.258,0,5.53-1.818,5.53-4.166c0-2.35-1.818-3.789-5.151-3.789c-1.137,0-1.818,0-2.728,0.228v-2.349h0.682
            +		c4.546,0,6.667-1.363,6.667-3.787c0-2.046-1.439-3.106-3.788-3.106c-1.666,0-3.105,0.606-4.394,1.364l-0.606-2.35
            +		c1.667-0.682,3.258-1.136,5.53-1.136c4.167,0,6.212,2.046,6.212,4.924c0,2.349-1.438,4.167-3.787,4.925l0,0
            +		c2.575,0.379,4.545,2.575,4.545,5.151C351.288,321.061,347.651,324.016,342.424,324.016z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M349.394,381.061v5.228h-2.727v-5.228h-9.697l-0.228-2.349l8.712-13.863h4.092v13.561h3.712v2.575L349.394,381.061
            +		L349.394,381.061z M346.591,367.5L346.591,367.5l-7.197,11.137c1.818,0,5.834,0,7.197,0V367.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M342.349,449.318c-0.909,0-2.349-0.228-3.485-0.379l0.228-2.576c1.137,0.379,2.576,0.379,3.485,0.379
            +		c3.787,0,5.833-2.121,5.833-4.772c0-2.728-2.121-4.091-5.606-4.091c-1.363,0-2.349,0.228-3.257,0.228v-10.683h10.984v2.728h-8.409
            +		v5.53c0.606,0,1.137,0,1.439,0c5.151,0,7.879,2.728,7.879,5.985C351.439,446.137,347.879,449.318,342.349,449.318z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M345.076,509.47c-4.395,0-7.197-3.258-7.197-9.016c0-9.015,4.394-12.803,10.454-12.803c0.606,0,1.439,0,1.818,0.228v2.575
            +		c-0.682-0.227-1.363-0.227-2.045-0.227c-4.091,0-6.213,2.349-7.197,6.666c-0.228,0.379-0.228,0.909-0.379,1.667l0,0
            +		c1.137-1.818,2.879-2.728,4.924-2.728c4.167,0,6.592,2.728,6.592,6.213C352.121,506.591,349.242,509.47,345.076,509.47z
            +		 M345.151,498.258c-2.575,0-4.091,2.121-4.091,4.091c0,2.575,1.439,4.772,4.167,4.772c2.575,0,4.091-1.818,4.091-4.545
            +		C349.242,500,347.879,498.258,345.151,498.258z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="389.394" y1="118.864" x2="377.197" y2="118.864"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="389.394" y1="184.015" x2="377.197" y2="184.015"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="389.394" y1="248.409" x2="377.197" y2="248.409"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="389.394" y1="313.03" x2="377.197" y2="313.03"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="389.394" y1="378.105" x2="377.197" y2="378.105"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="389.394" y1="443.484" x2="377.197" y2="443.484"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="389.394" y1="506.97" x2="377.197" y2="506.97"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="775.758" y1="118.712" x2="775.758" y2="106.515"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="710.833" y1="118.712" x2="710.833" y2="106.515"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="646.212" y1="118.712" x2="646.212" y2="106.515"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="581.742" y1="118.712" x2="581.742" y2="106.515"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="516.818" y1="118.712" x2="516.818" y2="106.515"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="451.061" y1="118.712" x2="451.061" y2="106.515"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="387.954" y1="118.712" x2="387.954" y2="106.515"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="300.455,237.651 292.727,245.228 285.076,237.651 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="292.727" y1="245.228" x2="292.727" y2="154.318"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="506.742,8.333 514.318,15.985 506.742,23.636 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="516.137" y1="15.985" x2="425.303" y2="15.985"/>
            +<g id="Layer_2">
            +</g>
            +</svg>
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-04.png b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-04.png
            new file mode 100644
            index 0000000000..911a8cb9fc
            Binary files /dev/null and b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-04.png differ
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-05.svg b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-05.svg
            new file mode 100644
            index 0000000000..d51c9cecf7
            --- /dev/null
            +++ b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-05.svg
            @@ -0,0 +1,166 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 612 792" enable-background="new 0 0 612 792" xml:space="preserve">
            +<g>
            +	<rect x="89.9" y="165.3" fill="none" stroke="#999999" stroke-width="1.3" width="488.1" height="488.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="89.9" y1="572.3" x2="578.1" y2="572.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="89.9" y1="490.7" x2="578.1" y2="490.7"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="89.9" y1="409.5" x2="578.1" y2="409.5"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="89.9" y1="328.3" x2="578.1" y2="328.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="89.9" y1="246.6" x2="578.1" y2="246.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="496.5" y1="165.3" x2="496.5" y2="653.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="415.4" y1="165.3" x2="415.4" y2="653.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="334.1" y1="165.3" x2="334.1" y2="653.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="252.6" y1="165.3" x2="252.6" y2="653.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="171.3" y1="165.3" x2="171.3" y2="653.6"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M99.6,48l-4.4-7.4L90.9,48H85v-2.2c1.2-0.2,2.4-0.5,3.4-0.5l4.9-7.1l-4.5-7.1c-1,0-2.2-0.3-3.4-0.5v-2.2h6.1l4.2,7.2
            +		l4.2-7.2h5.7v2.2c-1.2,0.2-2.4,0.5-3.4,0.5l-4.4,6.9l4.7,7.2c1,0,2.2,0.3,3.4,0.5V48L99.6,48L99.6,48z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-20.7,154.2l-6.9,19c-2.2,6.1-4.2,7.9-8.6,7.9c-0.7,0-1.9,0-2.7-0.2l0.3-3.2c0.8,0.3,1.7,0.5,2.5,0.5c2.2,0,3.4-1,4.7-4.9
            +		l0.8-2.2h-0.8l-6.1-17c-0.8,0-1.9-0.2-2.5-0.5v-2.2h8.9v2.2c-0.7,0.2-1.7,0.3-2.5,0.5l3,8.4c0.7,1.9,1,3.2,1.5,4.9l0,0
            +		c0.3-1.3,1-3.5,1.9-5.9l2.7-7.6c-1,0-1.9-0.2-2.5-0.5v-2.2h8.8v2.2C-19,154.1-19.9,154.2-20.7,154.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M97.1,115.5c-5.2,0-9.8-3-9.8-12.1c0-7.9,4.7-12.3,10.3-12.3c5,0,9.8,3,9.8,12.1C107.4,111.1,102.7,115.5,97.1,115.5z
            +		 M97.4,94c-3.2,0-6.2,2.9-6.2,9.1c0,6.6,2.5,9.4,6.2,9.4c3.2,0,6.2-2.7,6.2-9.1C103.7,96.8,101.1,94,97.4,94z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M168.5,115v-3.2h7.2V95.1l-6.7,4.4l-1.2-3l8.8-5.4h3v20.5h5.9v3.2h-17V115z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M246.4,115v-2.9l5.6-5c5-4.2,6.2-5.9,6.2-8.6c0-2.5-1.5-4.4-4.9-4.4c-2.4,0-4.4,1-5.7,2l-0.8-3.2c2-1.2,4.4-2,7.2-2
            +		c5.2,0,8.1,3,8.1,7.1c0,3.4-1.7,5.9-6.1,9.6l-4.7,4h-0.2c1.9-0.2,6.2-0.2,12-0.2v3.4h-16.7V115z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M330.6,118.7c-1.7,0-3.5-0.2-4.9-0.7l0.7-3.2c1.3,0.5,3,0.8,4.7,0.8c4.2,0,6.9-2.4,6.9-5.2c0-3-2.4-4.9-6.6-4.9
            +		c-1.3,0-2.4,0-3.5,0.2v-3h0.8c5.6,0,8.4-1.7,8.4-4.9c0-2.5-1.9-3.9-4.9-3.9c-2.2,0-4,0.7-5.6,1.5l-0.7-3c2-0.8,4.2-1.3,6.7-1.3
            +		c5.2,0,7.9,2.5,7.9,6.2c0,3-1.9,5.2-4.9,6.2l0,0c3.2,0.3,5.7,3.2,5.7,6.4C341.7,115,337.1,118.7,330.6,118.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M418.1,111.8v6.6h-3.5v-6.6h-12.1l-0.3-2.9L413,91.6h5v17.2h4.5v3.2h-4.5V111.8z M414.5,94.6L414.5,94.6l-8.9,14
            +		c2.4,0,7.2,0,8.9,0V94.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M487.9,118.7c-1.2,0-3-0.2-4.4-0.3l0.3-3c1.3,0.3,3,0.5,4.4,0.5c4.7,0,7.4-2.7,7.4-5.9c0-3.4-2.7-5.2-7.1-5.2
            +		c-1.5,0-3,0.2-4,0.3V91.6h13.8V95h-10.6v6.9c0.7,0,1.3,0,1.9,0c6.6,0,9.8,3.4,9.8,7.6C499.5,114.7,494.8,118.7,487.9,118.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M570.2,115.5c-5.6,0-8.9-4.2-8.9-11.3c0-11.3,5.6-16,13.1-16c0.8,0,1.7,0,2.4,0.2v3.2c-0.8-0.2-1.7-0.2-2.7-0.2
            +		c-5,0-7.9,3-8.9,8.4c-0.2,0.5-0.2,1.2-0.3,2l0,0c1.3-2.2,3.7-3.4,6.2-3.4c5.2,0,8.1,3.4,8.1,7.7
            +		C579.1,111.6,575.6,115.5,570.2,115.5z M570.4,101.2c-3.2,0-5.2,2.9-5.2,5c0,3.2,1.9,6.1,5.4,6.1c3.2,0,5-2.4,5-5.9
            +		C575.6,103.4,573.8,101.2,570.4,101.2z"/>
            +</g>
            +<circle cx="415.4" cy="570.3" r="12.6"/>
            +<g enable-background="new    ">
            +	<path d="M35.8,183.3c-5.2,0-9.8-3-9.8-12.1c0-7.9,4.7-12.3,10.3-12.3c5,0,9.8,3,9.8,12.1C46.1,179,41.4,183.3,35.8,183.3z
            +		 M36,161.8c-3.2,0-6.2,2.9-6.2,9.1c0,6.6,2.5,9.4,6.2,9.4c3.2,0,6.2-2.7,6.2-9.1C42.4,164.7,39.9,161.8,36,161.8z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M28.4,261.8v-3.2h7.2v-16.7l-6.7,4.4l-1.2-3l8.8-5.4h3v20.5h6.2v3.2H28.4V261.8z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M27.6,340.5v-2.9l5.6-5c5-4.2,6.2-5.9,6.2-8.6c0-2.5-1.5-4.4-4.9-4.4c-2.4,0-4.4,1-5.7,2l-0.8-3.2c2-1.2,4.4-2,7.2-2
            +		c5.2,0,8.1,3,8.1,7.1c0,3.4-1.7,5.9-6.1,9.6l-4.7,4h-0.2c1.9-0.2,6.2-0.2,12-0.2v3.4H27.6V340.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M32.8,423c-1.7,0-3.5-0.2-4.9-0.7l0.7-3.2c1.3,0.5,3,0.8,4.7,0.8c4.2,0,6.9-2.4,6.9-5.2c0-3-2.4-4.9-6.6-4.9
            +		c-1.3,0-2.4,0-3.5,0.2v-3H31c5.6,0,8.4-1.7,8.4-4.9c0-2.5-1.9-3.9-4.9-3.9c-2.2,0-4,0.7-5.6,1.5l-0.7-3c2-0.8,4.2-1.3,6.7-1.3
            +		c5.2,0,7.9,2.5,7.9,6.2c0,3-1.9,5.2-4.9,6.2l0,0c3.2,0.3,5.7,3.2,5.7,6.4C44.1,419.3,39.4,423,32.8,423z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M41.6,494.7v6.6H38v-6.6H25.9l-0.3-2.9l10.9-17.3h5v17.2h4.5v3.2h-4.5V494.7z M38.2,477.7L38.2,477.7l-8.9,14
            +		c2.4,0,7.2,0,8.9,0V477.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M32.6,580.6c-1.2,0-3-0.2-4.4-0.3l0.3-3c1.3,0.3,3,0.5,4.4,0.5c4.7,0,7.4-2.7,7.4-5.9c0-3.4-2.7-5.2-7.1-5.2
            +		c-1.5,0-3,0.2-4,0.3v-13.5h13.8v3.4H32.5v6.9c0.7,0,1.3,0,1.9,0c6.6,0,9.8,3.4,9.8,7.6C44.3,576.5,39.5,580.6,32.6,580.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M36.2,656.1c-5.6,0-8.9-4.2-8.9-11.3c0-11.3,5.6-16,13.1-16c0.8,0,1.7,0,2.4,0.2v3.2c-0.8-0.2-1.7-0.2-2.7-0.2
            +		c-5,0-7.9,3-8.9,8.4c-0.2,0.5-0.2,1.2-0.3,2l0,0c1.3-2.2,3.7-3.4,6.2-3.4c5.2,0,8.1,3.4,8.1,7.7C45.1,652.4,41.4,656.1,36.2,656.1z
            +		 M36.3,642c-3.2,0-5.2,2.9-5.2,5c0,3.2,1.9,6.1,5.4,6.1c3.2,0,5-2.4,5-5.9C41.4,644.2,39.7,642,36.3,642z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="91.9" y1="165.3" x2="76.4" y2="165.3"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="91.9" y1="247" x2="76.4" y2="247"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="91.9" y1="328.1" x2="76.4" y2="328.1"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="91.9" y1="409.2" x2="76.4" y2="409.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="91.9" y1="490.8" x2="76.4" y2="490.8"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="91.9" y1="573.3" x2="76.4" y2="573.3"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="91.9" y1="652.9" x2="76.4" y2="652.9"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="577.5" y1="165.2" x2="577.5" y2="149.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="495.5" y1="165.2" x2="495.5" y2="149.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="414.7" y1="165.2" x2="414.7" y2="149.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="333.2" y1="165.2" x2="333.2" y2="149.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="252" y1="165.2" x2="252" y2="149.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="169.5" y1="165.2" x2="169.5" y2="149.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="90.7" y1="165.2" x2="90.7" y2="149.7"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="-20,314.5 -29.6,324 -39.2,314.5 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-29.6" y1="324" x2="-29.6" y2="209.9"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="239.3,26.5 248.9,36.1 239.3,45.7 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="251.1" y1="36.1" x2="136.8" y2="36.1"/>
            +<g enable-background="new    ">
            +	<path d="M716,419.3c-1.2,0-2.2,0-3.4-0.2v7.1c1.2,0,2.4,0.3,3.4,0.5v2.2h-10.3v-2.2c1-0.2,2-0.5,3.2-0.5v-23.9
            +		c-1-0.2-2.2-0.3-3.2-0.3v-2.2c1.9-0.2,4.5-0.3,6.7-0.3c0,1.2-0.2,2.9-0.3,4l0,0c1.2-2.7,3.5-4.4,6.6-4.4c4.5,0,7.2,3.2,7.2,9.3
            +		C726.1,415.3,722.4,419.3,716,419.3z M718,402c-3.5,0-5.4,4.2-5.4,7.6v6.4c1,0.3,2.2,0.5,3.5,0.5c3.7,0,6.2-2.2,6.2-7.9
            +		C722.4,404.5,721,402,718,402z"/>
            +	<path d="M738.2,419.5c-5.4,0-8.8-3-8.8-9.9c0-5.9,3.7-10.4,9.6-10.4c4.9,0,8.8,2.7,8.8,9.9C747.6,414.8,744.1,419.5,738.2,419.5z
            +		 M738.5,402.1c-2.9,0-5.6,2.2-5.6,7.2c0,4.5,1.9,7.1,5.6,7.1c2.9,0,5.6-2.4,5.6-7.2C744.1,404.7,742.1,402.1,738.5,402.1z"/>
            +	<path d="M750.5,419v-2.2c1-0.2,2.2-0.5,3.4-0.5v-14.1c-1-0.2-2.4-0.3-3.4-0.3v-2.2c2-0.2,4.7-0.3,6.9-0.3v17c1.2,0,2.4,0.3,3.4,0.5
            +		v2.2L750.5,419L750.5,419z M755.7,395.6c-1.3,0-2.4-1-2.4-2.4c0-1.3,1-2.4,2.4-2.4c1.2,0,2.4,1,2.4,2.4
            +		C758.1,394.6,757.1,395.6,755.7,395.6z"/>
            +	<path d="M778.4,419v-12.6c0-2.7-0.7-4.4-3.4-4.4c-3.2,0-5.6,3.4-5.6,7.6v6.7c1,0,2.2,0.2,3.2,0.5v2.2h-10.1v-2.2
            +		c1-0.2,2.2-0.5,3.4-0.5v-14.1c-1-0.2-2.4-0.3-3.4-0.3v-2.2c2-0.2,4.7-0.3,6.9-0.3c0,1.2,0,3-0.3,4.2l0,0c1.2-2.7,3.5-4.5,6.9-4.5
            +		c4.4,0,5.9,2.9,5.9,6.2v11.1c1.2,0,2.4,0.3,3.2,0.5v2.2L778.4,419L778.4,419z"/>
            +	<path d="M794.9,419.3c-4,0-5.2-1.7-5.2-5.9v-11.3h-4v-2.7h4v-6.4l3.5-1v7.4h5.6v2.7h-5.6v9.9c0,3.2,0.7,4,2.9,4
            +		c0.8,0,1.9-0.2,2.5-0.3l0.3,2.9C797.8,419.1,796.3,419.3,794.9,419.3z"/>
            +	<path d="M824.9,427.9c-6.6-6.1-9.8-12.3-9.8-19.9c0-8.1,3.9-14.6,9.8-20l2,2c-5.4,5.2-8.2,11.3-8.2,17.7c0,6.6,2.7,12.6,8.2,18
            +		L824.9,427.9z"/>
            +	<path d="M850,419l-5.9-7.6l-5.7,7.6H834l8.1-9.9l-7.6-9.8h4.4l5.7,7.4l5.7-7.4h4l-7.6,9.8l7.9,9.9H850z"/>
            +	<path d="M861.4,424.2c4-1.2,5.2-3,5.2-4.4c0-2.5-2-2.5-2-4.7c0-1.7,1.2-2.9,2.9-2.9c2.5,0,3.7,2.4,3.7,4.9c0,4.9-3.4,7.7-9.1,9.1
            +		L861.4,424.2z"/>
            +	<path d="M893.2,419c-3,7.2-5.4,9.4-10.1,10.1l-0.7-3.2c3.7-0.5,5-1.5,7.4-6.9l-7.9-19.5h4l4.2,10.9c0.5,1.3,1.2,3.2,1.5,4.5l0,0
            +		c0.3-1.3,1.2-3.4,2-5.6l3.7-9.8h3.9L893.2,419z"/>
            +	<path d="M911.1,388c6.6,6.1,9.8,12.3,9.8,19.9c0,8.1-3.9,14.6-9.8,20l-2-2c5.4-5.2,8.2-11.4,8.2-17.7c0-6.6-2.7-12.6-8.2-18
            +		L911.1,388z"/>
            +	<path d="M931.3,425.2l-1.5-1.3c2.5-2.7,2.5-4.5,1.7-5.7c-1.2-1.3-0.2-3.5,1.7-3.5C936.1,414.6,937.5,419.6,931.3,425.2z
            +		 M933.3,407.9c-1.3,0-2.5-1-2.5-2.5c0-1.3,1.2-2.5,2.5-2.5c1.3,0,2.5,1.2,2.5,2.5C935.6,406.9,934.6,407.9,933.3,407.9z"/>
            +</g>
            +<text transform="matrix(1 0 0 1 175.3309 762.707)" fill="#808080" font-family="'TheSerif-HP5Plain'" font-size="39.4">Example:  </text>
            +<g enable-background="new    ">
            +	<path d="M375.5,762.7v-2.2c1-0.2,2-0.3,3-0.5l-1.5-4.4h-11.1l-1.5,4.4c1,0,2.2,0.3,3,0.5v2.2h-9.3v-2.2c0.7-0.2,1.7-0.3,2.4-0.5
            +		l8.8-24.1h4.4l8.8,24.1c0.7,0,1.7,0.2,2.4,0.5v2.2H375.5z M372.8,743.5c-0.5-1.3-0.8-2.5-1.2-3.9l0,0c-0.3,1.2-0.7,2.5-1.2,3.9
            +		l-3.4,9.4h9.3L372.8,743.5z"/>
            +	<path d="M410,771.6c-6.6-6.1-9.8-12.3-9.8-19.9c0-8.1,3.9-14.6,9.8-20l2,2c-5.4,5.2-8.2,11.3-8.2,17.7c0,6.6,2.7,12.6,8.2,18
            +		L410,771.6z"/>
            +	<path d="M434.9,759.3v6.6h-3.5v-6.6h-12.1l-0.3-2.9l10.9-17.3h5v17.2h4.5v3.2h-4.5V759.3z M431.4,742.3L431.4,742.3l-8.9,14
            +		c2.4,0,7.2,0,8.9,0V742.3z"/>
            +	<path d="M446.5,767.9c4-1.2,5.2-3,5.2-4.4c0-2.5-2-2.5-2-4.7c0-1.7,1.2-2.9,2.9-2.9c2.5,0,3.7,2.4,3.7,4.9c0,4.9-3.4,7.7-9.1,9.1
            +		L446.5,767.9z"/>
            +	<path d="M473.1,766.4c-1.2,0-3-0.2-4.4-0.3l0.3-3c1.3,0.3,3,0.5,4.4,0.5c4.7,0,7.4-2.7,7.4-5.9c0-3.4-2.7-5.2-7.1-5.2
            +		c-1.5,0-3,0.2-4,0.3v-13.5h13.8v3.4h-10.6v6.9c0.7,0,1.3,0,1.9,0c6.6,0,9.8,3.4,9.8,7.6C484.7,762.2,480,766.4,473.1,766.4z"/>
            +	<path d="M496.2,731.7c6.6,6.1,9.8,12.3,9.8,19.9c0,8.1-3.9,14.6-9.8,20l-2-2c5.4-5.2,8.2-11.4,8.2-17.7c0-6.6-2.7-12.6-8.2-18
            +		L496.2,731.7z"/>
            +	<path d="M525,768.7l-1.5-1.3c2.5-2.7,2.5-4.5,1.7-5.7c-1.2-1.3-0.2-3.5,1.7-3.5C529.8,758.3,531.2,763.2,525,768.7z M527,751.6
            +		c-1.3,0-2.5-1-2.5-2.5c0-1.3,1.2-2.5,2.5-2.5c1.3,0,2.5,1.2,2.5,2.5C529.3,750.4,528.3,751.6,527,751.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M470.8,581.1v-2.2c1-0.2,2-0.3,3-0.5l-1.5-4.4h-11.1l-1.5,4.4c1,0,2.2,0.3,3,0.5v2.2h-9.3v-2.2c0.7-0.2,1.7-0.3,2.4-0.5
            +		l8.8-24.1h4.4l8.8,24.1c0.7,0,1.7,0.2,2.4,0.5v2.2H470.8z M468.1,561.7c-0.5-1.3-0.8-2.5-1.2-3.9l0,0c-0.3,1.2-0.7,2.5-1.2,3.9
            +		l-3.4,9.4h9.3L468.1,561.7z"/>
            +	<path d="M505.3,589.8c-6.6-6.1-9.8-12.3-9.8-19.9c0-8.1,3.9-14.6,9.8-20l2,2c-5.4,5.2-8.2,11.3-8.2,17.7c0,6.6,2.7,12.6,8.2,18
            +		L505.3,589.8z"/>
            +	<path d="M530,577.7v6.6h-3.5v-6.6h-12.1l-0.3-2.9l10.9-17.3h5v17h4.5v3.2H530z M526.6,560.7L526.6,560.7l-8.9,14c2.4,0,7.2,0,8.9,0
            +		V560.7z"/>
            +	<path d="M541.8,586.3c4-1.2,5.2-3,5.2-4.4c0-2.5-2-2.5-2-4.7c0-1.7,1.2-2.9,2.9-2.9c2.5,0,3.7,2.4,3.7,4.9c0,4.9-3.4,7.7-9.1,9.1
            +		L541.8,586.3z"/>
            +	<path d="M568.4,584.8c-1.2,0-3-0.2-4.4-0.3l0.3-3c1.3,0.3,3,0.5,4.4,0.5c4.7,0,7.4-2.7,7.4-5.9c0-3.4-2.7-5.2-7.1-5.2
            +		c-1.5,0-3,0.2-4,0.3v-13.5h13.8v3.4h-10.6v6.9c0.7,0,1.3,0,1.9,0c6.6,0,9.8,3.4,9.8,7.6C580,580.6,575.3,584.8,568.4,584.8z"/>
            +	<path d="M591.4,549.9c6.6,6.1,9.8,12.3,9.8,19.9c0,8.1-3.9,14.6-9.8,20l-2-2c5.4-5.2,8.2-11.4,8.2-17.7c0-6.6-2.7-12.6-8.2-18
            +		L591.4,549.9z"/>
            +</g>
            +</svg>
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-06.svg b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-06.svg
            new file mode 100644
            index 0000000000..a735b785c5
            --- /dev/null
            +++ b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-06.svg
            @@ -0,0 +1,274 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 612 792" enable-background="new 0 0 612 792" xml:space="preserve">
            +<g>
            +	<rect x="77.5" y="148" fill="none" stroke="#999999" stroke-width="1.3" width="486" height="486"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="77.5" y1="553.3" x2="563.6" y2="553.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="77.5" y1="472.1" x2="563.6" y2="472.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="77.5" y1="391" x2="563.6" y2="391"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="77.5" y1="310.2" x2="563.6" y2="310.2"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="77.5" y1="229" x2="563.6" y2="229"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="482.5" y1="148" x2="482.5" y2="634.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="401.5" y1="148" x2="401.5" y2="634.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="320.6" y1="148" x2="320.6" y2="634.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="239.5" y1="148" x2="239.5" y2="634.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="158.6" y1="148" x2="158.6" y2="634.1"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M87.2,31.2l-4.4-7.3l-4.2,7.3h-5.9V29c1.1-0.2,2.2-0.6,3.3-0.6l4.8-7l-4.6-7c-1.1,0-2.2-0.4-3.3-0.6v-2.2h5.9l4,7.2
            +		l4.2-7.2h6.1v2.2c-1.1,0.2-2.2,0.6-3.3,0.6l-4.4,6.8l4.8,7.2c1.1,0,2.2,0.4,3.3,0.6v2.2L87.2,31.2L87.2,31.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-32.8,137l-7,18.9c-2.2,5.9-4,7.9-8.4,7.9c-0.7,0-1.8,0-2.8-0.2l0.2-3.1c0.9,0.2,1.7,0.4,2.6,0.4c2.2,0,3.3-1.1,4.8-4.8
            +		l0.7-2.2h-0.9l-6.1-16.9c-0.9,0-1.8-0.2-2.6-0.6v-2.2h9v2.2c-0.7,0.2-1.7,0.4-2.6,0.6l2.9,8.4c0.6,1.8,1.1,3.3,1.5,5l0,0
            +		c0.4-1.3,1.1-3.5,1.8-5.9l2.6-7.5c-0.9,0-1.8-0.2-2.6-0.6v-2.2h8.6v2.2C-30.9,136.7-31.8,136.9-32.8,137z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M84.7,98.3c-5.1,0-9.7-3.1-9.7-12.1c0-7.9,4.8-12.1,10.3-12.1c5,0,9.7,2.9,9.7,11.9C94.9,93.9,90.2,98.3,84.7,98.3z
            +		 M84.9,77c-3.1,0-6.2,2.8-6.2,9c0,6.6,2.4,9.4,6.2,9.4c3.1,0,6.2-2.8,6.2-9C91.1,79.8,88.7,77,84.9,77z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M155.7,98v-3.1h7.2V78.3l-6.8,4.4l-1.3-2.9l8.6-5.3h3.1v20.4h6.1V98H155.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M233.3,98V95l5.7-5.1c5-4.2,6.2-5.9,6.2-8.4s-1.5-4.4-4.8-4.4c-2.2,0-4.4,1.1-5.7,2l-0.7-3.1c2-1.3,4.2-2,7.2-2
            +		c5.3,0,8.1,2.9,8.1,7c0,3.3-1.7,5.9-6.1,9.5l-4.8,4h-0.2c1.8-0.2,6.1-0.2,11.9-0.2v3.3h-16.9V98z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M317.1,101.6c-1.7,0-3.5-0.2-5-0.6l0.6-3.1c1.3,0.6,2.9,0.7,4.8,0.7c4.2,0,6.8-2.4,6.8-5.3c0-2.9-2.4-4.8-6.4-4.8
            +		c-1.3,0-2.4,0-3.5,0.2v-2.9h0.7c5.7,0,8.4-1.7,8.4-4.8c0-2.4-1.8-3.9-4.8-3.9c-2.2,0-4,0.6-5.5,1.5l-0.6-3.1c2-0.9,4.2-1.3,6.8-1.3
            +		c5.3,0,7.9,2.6,7.9,6.2c0,3.1-1.8,5.3-4.8,6.1l0,0c3.3,0.4,5.7,3.1,5.7,6.2C328.1,98,323.6,101.6,317.1,101.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M404.3,94.7v6.6h-3.5v-6.6h-12.1l-0.2-2.9l10.8-17.2h5v17.1h4.6v3.1H404.3z M400.8,77.6L400.8,77.6L392,91.5
            +		c2.4,0,7.3,0,8.8,0V77.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M473.8,101.6c-1.3,0-2.9-0.2-4.4-0.4l0.2-3.1c1.3,0.4,3.1,0.6,4.4,0.6c4.8,0,7.3-2.8,7.3-5.9c0-3.3-2.8-5.1-7-5.1
            +		c-1.7,0-3.1,0.2-4,0.2V74.5h13.8v3.3h-10.5v7c0.7,0,1.5,0,1.8,0c6.4,0,9.7,3.3,9.7,7.5C485.2,97.4,480.6,101.6,473.8,101.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M555.7,98.3c-5.5,0-8.8-4-8.8-11.2c0-11.4,5.5-16,13-16c0.7,0,1.7,0,2.4,0.2v3.1c-0.7-0.2-1.7-0.2-2.6-0.2
            +		c-5,0-7.9,2.9-9,8.4c-0.2,0.4-0.2,1.1-0.4,2l0,0c1.3-2.2,3.7-3.5,6.2-3.5c5.1,0,8.1,3.3,8.1,7.7C564.7,94.7,561,98.3,555.7,98.3z
            +		 M555.8,84.2c-3.3,0-5.1,2.8-5.1,5.1c0,3.3,1.8,6.1,5.3,6.1c3.1,0,5-2.4,5-5.9C561,86.4,559.1,84.2,555.8,84.2z"/>
            +</g>
            +<circle fill="#808080" cx="158.6" cy="310.2" r="12.7"/>
            +<circle fill="#808080" cx="481.2" cy="310.2" r="12.7"/>
            +<g enable-background="new    ">
            +	<path d="M23.6,165.8c-5.1,0-9.7-3.1-9.7-12.1c0-7.9,4.8-12.1,10.3-12.1c5,0,9.7,2.9,9.7,11.9C33.9,161.6,29.1,165.8,23.6,165.8z
            +		 M23.9,144.6c-3.1,0-6.2,2.8-6.2,9c0,6.6,2.4,9.4,6.2,9.4c3.1,0,6.2-2.8,6.2-9C30.2,147.5,27.6,144.6,23.9,144.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M16.2,244v-3.1h7.2v-16.5l-6.8,4.4l-1.3-2.9l8.6-5.3h3.1v20.4h6.1v3.1H16.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M15.3,322.5v-2.9l5.7-5.1c5-4.2,6.2-5.9,6.2-8.4c0-2.6-1.5-4.4-4.8-4.4c-2.2,0-4.4,1.1-5.7,2l-0.7-3.1c2-1.3,4.2-2,7.2-2
            +		c5.3,0,8.1,2.9,8.1,7c0,3.3-1.7,5.9-6.1,9.5l-4.8,4h-0.2c1.8-0.2,6.1-0.2,11.9-0.2v3.3H15.3V322.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M20.6,404.5c-1.7,0-3.5-0.2-5-0.6l0.6-3.1c1.3,0.6,2.9,0.7,4.8,0.7c4.2,0,6.8-2.4,6.8-5.3c0-2.9-2.4-4.8-6.4-4.8
            +		c-1.3,0-2.4,0-3.5,0.2v-2.9h0.7c5.7,0,8.4-1.7,8.4-4.8c0-2.4-1.8-3.9-4.8-3.9c-2.2,0-4,0.6-5.5,1.5l-0.6-3.1c2-0.9,4.2-1.3,6.8-1.3
            +		c5.3,0,7.9,2.6,7.9,6.2c0,3.1-1.8,5.3-4.8,6.1l0,0c3.3,0.4,5.7,3.1,5.7,6.2C31.8,400.9,27.2,404.5,20.6,404.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M29.4,476.1v6.6H26v-6.6H13.9l-0.2-2.9l10.8-17.2h5V473H34v3.1H29.4z M26,459L26,459L17.2,473c2.4,0,7.3,0,8.8,0V459z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M20.5,561.4c-1.3,0-2.9-0.2-4.4-0.4l0.2-3.1c1.3,0.4,3.1,0.6,4.4,0.6c4.8,0,7.3-2.8,7.3-5.9c0-3.3-2.8-5.1-7-5.1
            +		c-1.7,0-3.1,0.2-4,0.2v-13.4h13.8v3.3H20.3v7c0.7,0,1.5,0,1.8,0c6.4,0,9.7,3.3,9.7,7.5C32,557.4,27.2,561.4,20.5,561.4z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M23.9,636.6c-5.5,0-8.8-4-8.8-11.2c0-11.4,5.5-16,13-16c0.7,0,1.7,0,2.4,0.2v3.1c-0.7-0.2-1.7-0.2-2.6-0.2
            +		c-5,0-7.9,2.9-9,8.4c-0.2,0.4-0.2,1.1-0.4,2l0,0c1.3-2.2,3.7-3.5,6.2-3.5c5.1,0,8.1,3.3,8.1,7.7C32.8,633,29.3,636.6,23.9,636.6z
            +		 M24.1,622.5c-3.3,0-5.1,2.8-5.1,5.1c0,3.3,1.8,6.1,5.3,6.1c3.1,0,5-2.4,5-5.9C29.3,624.7,27.4,622.5,24.1,622.5z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="79.5" y1="148" x2="63.9" y2="148"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="79.5" y1="229.3" x2="63.9" y2="229.3"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="79.5" y1="310.1" x2="63.9" y2="310.1"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="79.5" y1="391" x2="63.9" y2="391"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="79.5" y1="472.2" x2="63.9" y2="472.2"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="79.5" y1="554.1" x2="63.9" y2="554.1"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="79.5" y1="633.3" x2="63.9" y2="633.3"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="563" y1="147.9" x2="563" y2="132.4"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="481.4" y1="147.9" x2="481.4" y2="132.4"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="400.6" y1="147.9" x2="400.6" y2="132.4"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="319.9" y1="147.9" x2="319.9" y2="132.4"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="238.8" y1="147.9" x2="238.8" y2="132.4"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="156.6" y1="147.9" x2="156.6" y2="132.4"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="78.3" y1="147.9" x2="78.3" y2="132.4"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="-31.8,296.5 -41.6,306 -51.1,296.5 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-41.6" y1="306" x2="-41.6" y2="192.3"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="226.1,9.7 235.9,19.2 226.1,28.8 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="237.9" y1="19.2" x2="124.1" y2="19.2"/>
            +<g enable-background="new    ">
            +	<path d="M647,396.3v-2.2c0.9-0.2,2.2-0.4,3.3-0.6v-23.3c-0.9-0.2-2.2-0.4-3.3-0.4v-2.2c2-0.2,4.6-0.4,7-0.2v26.2
            +		c1.1,0,2.4,0.4,3.3,0.6v2.2H647V396.3z"/>
            +	<path d="M659,396.3v-2.2c1.1-0.2,2.2-0.4,3.5-0.6v-14.1c-0.9-0.2-2.2-0.4-3.5-0.4v-2.2c2-0.2,4.6-0.4,7-0.4v16.9
            +		c1.1,0,2.4,0.4,3.3,0.6v2.2H659V396.3z M664.3,372.8c-1.3,0-2.4-0.9-2.4-2.2s1.1-2.4,2.4-2.4c1.3,0,2.4,1.1,2.4,2.4
            +		C666.5,371.9,665.6,372.8,664.3,372.8z"/>
            +	<path d="M686.8,396.3v-12.5c0-2.8-0.7-4.4-3.3-4.4c-3.3,0-5.5,3.3-5.5,7.5v6.8c1.1,0,2.2,0.2,3.1,0.6v2.2h-10.1v-2.2
            +		c1.1-0.2,2.2-0.4,3.5-0.6v-14.1c-0.9-0.2-2.2-0.4-3.5-0.4V377c2-0.2,4.6-0.4,6.8-0.4c0,1.1,0,2.9-0.2,4l0,0c1.1-2.8,3.5-4.4,7-4.4
            +		c4.4,0,5.9,2.8,5.9,6.2v11c1.1,0,2.4,0.4,3.3,0.6v2.2L686.8,396.3L686.8,396.3z"/>
            +	<path d="M712.4,386.4h-12.7c-0.2,5.1,1.8,7.3,6.2,7.3c1.8,0,3.9-0.4,5.5-1.1l0.6,2.8c-2,0.7-4.4,1.3-6.8,1.3
            +		c-5.9,0-9.2-3.1-9.2-10.1c0-5.9,3.3-10.3,8.8-10.3s7.7,3.7,7.7,8.1C712.5,384.9,712.5,385.6,712.4,386.4z M704.6,379
            +		c-2.6,0-4.4,1.8-4.8,5h9.2C709,380.9,707.4,379,704.6,379z"/>
            +	<path d="M731.4,404.5c-4.6-7.3-5.7-13.6-5.7-19.3s1.3-12.5,5.7-19.4l2.6,1.3c-3.1,5.5-5,11.7-5,18.2c0,6.8,1.7,12.7,5,18.2
            +		L731.4,404.5z"/>
            +	<path d="M758.2,396.3l-4.4-7.3l-4.2,7.3h-5.9v-2.2c1.1-0.2,2.2-0.6,3.3-0.6l4.8-7l-4.6-7c-1.1,0-2.2-0.4-3.3-0.6v-2.2h5.9l4,7.2
            +		l4.2-7.2h5.7v2.2c-1.1,0.2-2.2,0.6-3.3,0.6l-4.4,6.8l4.8,7.2c1.1,0,2.2,0.4,3.3,0.6v2.2L758.2,396.3L758.2,396.3z"/>
            +	<path d="M768.7,396.3v-3.1h7.2v-16.5l-6.8,4.4l-1.3-2.9l8.6-5.3h2.9v20.4h6.1v3.1H768.7z"/>
            +	<path d="M799.3,402.3l-1.5-1.3c2.6-2.8,2.6-4.6,1.7-5.7c-1.1-1.3-0.2-3.5,1.7-3.5C804.1,391.9,805.4,396.8,799.3,402.3z"/>
            +	<path d="M831.8,379.4l-7,18.9c-2.2,5.9-4,7.9-8.4,7.9c-0.7,0-1.8,0-2.8-0.2l0.2-3.1c0.9,0.2,1.7,0.4,2.6,0.4c2.2,0,3.3-1.1,4.8-4.8
            +		l0.7-2.2H821l-6.1-16.9c-0.9,0-1.8-0.2-2.6-0.6v-2.2h9v2.2c-0.7,0.2-1.7,0.4-2.6,0.6l2.9,8.4c0.6,1.8,1.1,3.3,1.5,5l0,0
            +		c0.4-1.3,1.1-3.5,1.8-5.9l2.6-7.5c-0.9,0-1.8-0.2-2.6-0.6v-2.2h8.6v2.2C833.4,379,832.7,379.2,831.8,379.4z"/>
            +	<path d="M838.6,396.3v-3.1h7.2v-16.5l-6.8,4.4l-1.3-2.9l8.6-5.3h2.9v20.4h6.1v3.1H838.6z"/>
            +	<path d="M869.2,402.3l-1.5-1.3c2.6-2.8,2.6-4.6,1.7-5.7c-1.1-1.3-0.2-3.5,1.7-3.5C874,391.9,875.3,396.8,869.2,402.3z"/>
            +	<path d="M897.3,396.3l-4.4-7.3l-4.2,7.3h-5.9v-2.2c1.1-0.2,2.2-0.6,3.3-0.6l4.8-7l-4.6-7c-1.1,0-2.2-0.4-3.3-0.6v-2.2h5.9l4,7.2
            +		l4.2-7.2h5.7v2.2c-1.1,0.2-2.2,0.6-3.3,0.6l-4.4,6.8l4.8,7.2c1.1,0,2.2,0.4,3.3,0.6v2.2L897.3,396.3L897.3,396.3z"/>
            +	<path d="M907,396.3v-2.9l5.7-5.1c5-4.2,6.2-5.9,6.2-8.4c0-2.6-1.5-4.4-4.8-4.4c-2.2,0-4.4,1.1-5.7,2l-0.7-3.1c2-1.3,4.2-2,7.2-2
            +		c5.3,0,8.1,2.9,8.1,7c0,3.3-1.7,5.9-6.1,9.5l-4.8,4H912c1.8-0.2,6.1-0.2,11.9-0.2v3.3H907V396.3z"/>
            +	<path d="M938.4,402.3l-1.5-1.3c2.6-2.8,2.6-4.6,1.7-5.7c-1.1-1.3-0.2-3.5,1.7-3.5C943.2,391.9,944.5,396.8,938.4,402.3z"/>
            +	<path d="M970.9,379.4l-7,18.9c-2.2,5.9-4,7.9-8.4,7.9c-0.7,0-1.8,0-2.8-0.2l0.2-3.1c0.9,0.2,1.7,0.4,2.6,0.4c2.2,0,3.3-1.1,4.8-4.8
            +		l0.7-2.2H960l-6.1-16.9c-0.9,0-1.8-0.2-2.6-0.6v-2.2h9v2.2c-0.7,0.2-1.7,0.4-2.6,0.6l2.9,8.4c0.6,1.8,1.1,3.3,1.5,5l0,0
            +		c0.4-1.3,1.1-3.5,1.8-5.9l2.6-7.5c-0.9,0-1.8-0.2-2.6-0.6v-2.2h8.6v2.2C972.7,379,971.8,379.2,970.9,379.4z"/>
            +	<path d="M976.9,396.3v-2.9l5.7-5.1c5-4.2,6.2-5.9,6.2-8.4c0-2.6-1.5-4.4-4.8-4.4c-2.2,0-4.4,1.1-5.7,2l-0.7-3.1c2-1.3,4.2-2,7.2-2
            +		c5.3,0,8.1,2.9,8.1,7c0,3.3-1.7,5.9-6.1,9.5l-4.8,4h-0.2c1.8-0.2,6.1-0.2,11.9-0.2v3.3h-16.9V396.3z"/>
            +	<path d="M1009.4,404.5l-2.6-1.3c3.3-5.5,5-11.7,5-18c0-6.8-1.7-12.7-5-18.3l2.8-1.3c4.6,7.3,5.7,13.6,5.7,19.3
            +		C1015.1,390.6,1013.8,397.4,1009.4,404.5z"/>
            +	<path d="M1030.5,402.3l-1.5-1.3c2.6-2.8,2.6-4.6,1.7-5.7c-1.1-1.3-0.2-3.5,1.7-3.5C1035.3,391.9,1036.6,396.8,1030.5,402.3z
            +		 M1032.3,385.1c-1.3,0-2.4-1.1-2.4-2.4s1.1-2.4,2.4-2.4c1.3,0,2.4,1.1,2.4,2.4C1034.9,384,1033.8,385.1,1032.3,385.1z"/>
            +</g>
            +<text transform="matrix(1 0 0 1 646.3711 479.9532)" fill="#999999" font-family="'TheSerif-HP5Plain'" font-size="30.5127" letter-spacing="67"> </text>
            +<g enable-background="new    ">
            +	<path fill="#999999" d="M753.3,472.8c-0.9,0-1.7,0-2.2-0.2v5.1c0.9,0,1.8,0.2,2.6,0.4v1.7h-8.1v-1.7c0.7-0.2,1.7-0.4,2.6-0.4v-16.5
            +		c-0.9,0-1.8-0.2-2.6-0.4v-1.7h2.6c0.9,0,3.5-0.2,5.3-0.2c5.5,0,7.9,2.9,7.9,6.4C761.5,469.9,758.2,472.8,753.3,472.8z M753.3,461.6
            +		c-0.7,0-1.7,0-2.2,0v8.8c0.6,0,1.5,0.2,2.4,0.2c3.5,0,5.1-2,5.1-4.6C758.6,463.8,757.3,461.6,753.3,461.6z"/>
            +	<path fill="#999999" d="M770.3,480.1c-4.2,0-6.8-2.4-6.8-7.7c0-4.6,2.8-8.1,7.3-8.1c3.9,0,6.8,2,6.8,7.7
            +		C777.7,476.7,774.9,480.1,770.3,480.1z M770.5,466.7c-2.2,0-4.2,1.7-4.2,5.5c0,3.5,1.5,5.5,4.2,5.5c2.2,0,4.2-1.8,4.2-5.5
            +		C774.7,468.8,773.3,466.7,770.5,466.7z"/>
            +	<path fill="#999999" d="M779.9,480v-1.7c0.7-0.2,1.7-0.4,2.6-0.4v-11c-0.7-0.2-1.8-0.2-2.6-0.4v-1.7c1.5-0.2,3.7-0.4,5.3-0.2v13.2
            +		c0.9,0,1.8,0.2,2.6,0.4v1.7H779.9z M783.9,461.8c-0.9,0-1.8-0.7-1.8-1.8s0.7-1.8,1.8-1.8c0.9,0,1.8,0.7,1.8,1.8
            +		C785.6,461.1,784.8,461.8,783.9,461.8z"/>
            +	<path fill="#999999" d="M801.5,480v-9.7c0-2.2-0.6-3.5-2.6-3.5c-2.6,0-4.4,2.6-4.4,5.9v5.1c0.7,0,1.7,0.2,2.4,0.4v1.7H789v-1.7
            +		c0.7-0.2,1.7-0.4,2.6-0.4v-11c-0.7-0.2-1.8-0.2-2.6-0.4v-1.7c1.5-0.2,3.7-0.4,5.3-0.2c0,0.9,0,2.2-0.2,3.1l0,0
            +		c0.9-2,2.8-3.5,5.3-3.5c3.5,0,4.6,2.2,4.6,4.8v8.6c0.9,0,1.8,0.2,2.6,0.4v1.7h-5.1V480z"/>
            +	<path fill="#999999" d="M814.2,480.1c-3.1,0-4-1.3-4-4.6v-8.8H807v-2.2h3.1v-5l2.8-0.7v5.7h4.2v2.2h-4.2v7.7c0,2.6,0.6,3.1,2.2,3.1
            +		c0.7,0,1.3,0,1.8-0.2l0.4,2.2C816.4,480.1,815.3,480.1,814.2,480.1z"/>
            +	<path fill="#999999" d="M838.4,480v-1.7c0.7-0.2,1.7-0.4,2.4-0.4l-1.1-3.3h-8.6l-1.1,3.3c0.7,0,1.7,0.2,2.4,0.4v1.7h-7.2v-1.7
            +		c0.6-0.2,1.3-0.4,1.8-0.4l6.8-18.5h3.5l6.8,18.5c0.6,0,1.3,0.2,1.8,0.4v1.7H838.4z M836.4,465.1c-0.4-1.1-0.7-2-0.9-2.9l0,0
            +		c-0.2,0.9-0.6,1.8-0.9,2.9l-2.6,7.3h7.2L836.4,465.1z"/>
            +	<path fill="#999999" d="M881.2,472.8c-0.9,0-1.7,0-2.2-0.2v5.1c0.9,0,1.8,0.2,2.6,0.4v1.7h-8.1v-1.7c0.7-0.2,1.7-0.4,2.6-0.4v-16.5
            +		c-0.9,0-1.8-0.2-2.6-0.4v-1.7h2.6c0.9,0,3.5-0.2,5.3-0.2c5.5,0,7.9,2.9,7.9,6.4C889.4,469.9,886.1,472.8,881.2,472.8z M881.2,461.6
            +		c-0.7,0-1.7,0-2.2,0v8.8c0.6,0,1.5,0.2,2.4,0.2c3.5,0,5.1-2,5.1-4.6C886.5,463.8,885.2,461.6,881.2,461.6z"/>
            +	<path fill="#999999" d="M898.2,480.1c-4.2,0-6.8-2.4-6.8-7.7c0-4.6,2.8-8.1,7.3-8.1c3.9,0,6.8,2,6.8,7.7
            +		C905.6,476.7,902.8,480.1,898.2,480.1z M898.4,466.7c-2.2,0-4.2,1.7-4.2,5.5c0,3.5,1.5,5.5,4.2,5.5c2.2,0,4.2-1.8,4.2-5.5
            +		C902.6,468.8,901.2,466.7,898.4,466.7z"/>
            +	<path fill="#999999" d="M907.6,480v-1.7c0.7-0.2,1.7-0.4,2.6-0.4v-11c-0.7-0.2-1.8-0.2-2.6-0.4v-1.7c1.5-0.2,3.7-0.4,5.3-0.2v13.2
            +		c0.9,0,1.8,0.2,2.6,0.4v1.7H907.6z M911.8,461.8c-0.9,0-1.8-0.7-1.8-1.8s0.7-1.8,1.8-1.8c0.9,0,1.8,0.7,1.8,1.8
            +		C913.4,461.1,912.7,461.8,911.8,461.8z"/>
            +	<path fill="#999999" d="M929.4,480v-9.7c0-2.2-0.6-3.5-2.6-3.5c-2.6,0-4.4,2.6-4.4,5.9v5.1c0.7,0,1.7,0.2,2.4,0.4v1.7h-7.9v-1.7
            +		c0.7-0.2,1.7-0.4,2.6-0.4v-11c-0.7-0.2-1.8-0.2-2.6-0.4v-1.7c1.5-0.2,3.7-0.4,5.3-0.2c0,0.9,0,2.2-0.2,3.1l0,0
            +		c0.9-2,2.8-3.5,5.3-3.5c3.5,0,4.6,2.2,4.6,4.8v8.6c0.9,0,1.8,0.2,2.6,0.4v1.7h-5.1V480z"/>
            +	<path fill="#999999" d="M942.1,480.1c-3.1,0-4-1.3-4-4.6v-8.8h-3.1v-2.2h3.1v-5l2.8-0.7v5.7h4.2v2.2h-4.2v7.7
            +		c0,2.6,0.6,3.1,2.2,3.1c0.7,0,1.3,0,1.8-0.2l0.4,2.2C944.3,480.1,943.2,480.1,942.1,480.1z"/>
            +	<path fill="#999999" d="M961.7,480c-1.1,0-3.1,0-5.3,0h-2.8v-1.7c0.7-0.2,1.7-0.4,2.6-0.4v-16.5c-0.9,0-1.8-0.2-2.6-0.4v-1.7h2.6
            +		c1.5,0,3.5,0,5.9,0c4.4,0,6.6,1.8,6.6,5c0,2.2-1.1,4-3.3,4.8l0,0c2.9,0.6,4.2,2.6,4.2,4.8C969.6,476.3,968.1,480,961.7,480z
            +		 M961.7,461.6c-0.9,0-1.7,0-2.6,0v6.6c0.6,0,1.1,0,1.8,0c3.3,0,4.8-1.3,4.8-3.7C965.9,462.9,965,461.6,961.7,461.6z M961.1,470.4
            +		c-0.4,0-1.5,0-2,0v7.2c0.6,0,1.5,0.2,2.8,0.2c3.3,0,4.8-1.7,4.8-3.9C966.7,471.1,964.3,470.4,961.1,470.4z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M184.3,287.3v-2.2c0.9-0.2,2-0.4,3.1-0.6l-1.5-4.4h-11l-1.5,4.4c1.1,0,2.2,0.2,3.1,0.6v2.2h-9.2v-2.2
            +		c0.7-0.2,1.7-0.4,2.4-0.4l8.6-23.9h4.4l8.8,23.9c0.7,0,1.7,0.2,2.4,0.4v2.2H184.3z M181.6,268c-0.6-1.3-0.9-2.6-1.3-3.9l0,0
            +		c-0.4,1.3-0.7,2.4-1.1,3.9l-3.5,9.4h9.2L181.6,268z"/>
            +	<path d="M218.6,296.1c-6.6-6.1-9.7-12.1-9.7-19.8c0-8.1,3.9-14.7,9.7-20l2,2c-5.3,5.1-8.3,11.4-8.3,17.6c0,6.6,2.8,12.5,8.3,17.8
            +		L218.6,296.1z"/>
            +	<path d="M230.2,287.3v-3.1h7.2v-16.5l-6.8,4.4l-1.3-2.9l8.6-5.3h2.9v20.4h6.1v3.1H230.2z"/>
            +	<path d="M254.9,292.4c4-1.1,5.3-2.9,5.3-4.4c0-2.4-2-2.6-2-4.6c0-1.7,1.1-2.9,2.8-2.9c2.4,0,3.7,2.4,3.7,5c0,4.8-3.3,7.7-9,9.2
            +		L254.9,292.4z"/>
            +	<path d="M276.4,287.3v-2.9l5.7-5.1c5-4.2,6.2-5.9,6.2-8.4c0-2.6-1.5-4.4-4.8-4.4c-2.2,0-4.4,1.1-5.7,2l-0.7-3.1c2-1.3,4.2-2,7.2-2
            +		c5.3,0,8.1,2.9,8.1,7c0,3.3-1.7,5.9-6.1,9.5l-4.8,4h-0.2c1.8-0.2,6.1-0.2,11.9-0.2v3.3h-16.9V287.3z"/>
            +	<path d="M304.5,256.3c6.6,6.1,9.7,12.1,9.7,19.8c0,8.1-3.9,14.7-9.7,20l-2-2c5.3-5.1,8.3-11.4,8.3-17.6c0-6.6-2.8-12.7-8.3-17.8
            +		L304.5,256.3z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M500.8,287.5c-1.5,0-4-0.2-6.8-0.2h-3.5v-2.2c1.1-0.2,2.2-0.4,3.5-0.6v-21.1c-1.1,0-2.4-0.4-3.5-0.6v-2.2h3.3
            +		c1.8,0,4.4-0.2,7.5-0.2c5.7,0,8.4,2.4,8.4,6.4c0,2.8-1.5,5.1-4.4,6.2l0,0c3.7,0.6,5.3,3.3,5.3,6.1
            +		C510.9,282.5,509.1,287.5,500.8,287.5z M500.8,263.6c-1.3,0-2.2,0-3.3,0v8.6c0.7,0,1.5,0,2.4,0c4.4,0,6.2-1.7,6.2-4.6
            +		C506.1,265.3,505,263.6,500.8,263.6z M500.1,275c-0.6,0-1.8,0-2.6,0v9.2c0.7,0.2,1.8,0.2,3.5,0.2c4.4,0,6.2-2.2,6.2-5
            +		C507.2,276.1,504.1,275,500.1,275z"/>
            +	<path d="M537.5,296.1c-6.6-6.1-9.7-12.1-9.7-19.8c0-8.1,3.9-14.7,9.7-20l2,2c-5.3,5.1-8.3,11.4-8.3,17.6c0,6.6,2.8,12.5,8.3,17.8
            +		L537.5,296.1z"/>
            +	<path d="M553.3,291c-1.3,0-2.9-0.2-4.4-0.4l0.2-3.1c1.3,0.4,3.1,0.6,4.4,0.6c4.8,0,7.3-2.8,7.3-5.9c0-3.3-2.8-5.1-7-5.1
            +		c-1.7,0-3.1,0.2-4,0.2v-13.4h13.8v3.3h-10.5v7c0.7,0,1.5,0,1.8,0c6.4,0,9.7,3.3,9.7,7.5C564.8,286.8,560.2,291,553.3,291z"/>
            +	<path d="M573.8,292.4c4-1.1,5.3-2.9,5.3-4.4c0-2.4-2-2.6-2-4.6c0-1.7,1.1-2.9,2.8-2.9c2.4,0,3.7,2.4,3.7,5c0,4.8-3.3,7.7-9,9.2
            +		L573.8,292.4z"/>
            +	<path d="M595.3,287.3v-2.9l5.7-5.1c5-4.2,6.2-5.9,6.2-8.4c0-2.6-1.5-4.4-4.8-4.4c-2.2,0-4.4,1.1-5.7,2l-0.7-3.1c2-1.3,4.2-2,7.2-2
            +		c5.3,0,8.1,2.9,8.1,7c0,3.3-1.7,5.9-6.1,9.5l-4.8,4h-0.2c1.8-0.2,6.1-0.2,11.9-0.2v3.3h-16.9V287.3z"/>
            +	<path d="M623.4,256.3c6.6,6.1,9.7,12.1,9.7,19.8c0,8.1-3.9,14.7-9.7,20l-2-2c5.3-5.1,8.3-11.4,8.3-17.6c0-6.6-2.8-12.7-8.3-17.8
            +		L623.4,256.3z"/>
            +</g>
            +<line fill="none" stroke="#999999" stroke-width="5" x1="744.5" y1="424.9" x2="841.5" y2="424.9"/>
            +<line fill="none" stroke="#999999" stroke-width="5" x1="864.3" y1="424.9" x2="974" y2="424.9"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="156" y1="311.5" x2="482.5" y2="311.5"/>
            +<g enable-background="new    ">
            +	<path fill="#808080" d="M91.1,740.7v-2.2c1.1-0.2,2.2-0.4,3.5-0.6v-21.3c-1.1,0-2.4-0.4-3.5-0.6v-2.2h17.1v6.1h-2.6
            +		c-0.2-1.3-0.4-2.4-0.6-3.3h-7.2v8.6h5.7c0.2-0.9,0.4-1.8,0.6-2.8h2.2v8.1h-2.2c-0.2-0.7-0.4-1.8-0.6-2.8h-5.7v9.4h7.2
            +		c0.2-1.1,0.4-2.2,0.6-3.3h2.6v6.2H91.1V740.7z"/>
            +	<path fill="#808080" d="M125.6,740.7l-4.4-7.3l-4.2,7.3h-5.9v-2.2c1.1-0.2,2.2-0.6,3.3-0.6l4.8-7l-4.6-7c-1.1,0-2.2-0.4-3.3-0.6
            +		v-2.2h5.9l4,7.2l4.2-7.2h5.7v2.2c-1.1,0.2-2.2,0.6-3.3,0.6l-4.4,6.8l4.8,7.2c1.1,0,2.2,0.4,3.3,0.6v2.2L125.6,740.7L125.6,740.7z"
            +		/>
            +	<path fill="#808080" d="M145.6,740.7c0-1.3,0-2.8,0.2-3.9l0,0c-0.9,2.4-3.5,4.2-6.6,4.2c-3.1,0-5.5-2-5.5-5.1
            +		c0-4.2,4.4-6.6,11.7-6.6v-1.7c0-2.8-0.9-4.2-4-4.2c-1.1,0-2.6,0.2-3.7,0.6c0,0.9-0.2,2-0.6,3.1h-2.2v-5.3c2-0.6,4.4-1.1,6.6-1.1
            +		c5.7,0,7.3,2.6,7.3,6.4v10.6c0.9,0.2,2.2,0.4,3.3,0.4v2.2C150.5,740.5,147.8,740.7,145.6,740.7z M145.4,731.7
            +		c-6.1,0-8.3,1.5-8.3,3.7c0,1.7,1.1,2.9,2.9,2.9c3.1,0,5.3-3.1,5.3-6.2V731.7z"/>
            +	<path fill="#808080" d="M181.9,740.7v-12.5c0-2.8-0.6-4.4-3.1-4.4c-2.8,0-5.5,2.9-5.5,7.7v6.6c1.1,0,2.2,0.2,3.1,0.6v2.2h-6.6
            +		v-12.5c0-2.4-0.6-4.4-3.1-4.4c-2.9,0-5.5,3.3-5.5,7.7v6.6c1.1,0,2.2,0.2,3.1,0.6v2.2h-10.1v-2.2c1.1-0.2,2.2-0.4,3.5-0.6V724
            +		c-0.9-0.2-2.2-0.4-3.5-0.4v-2.2c2-0.2,4.8-0.4,6.8-0.4c0,1.1-0.2,2.9-0.4,4l0,0c1.1-2.8,3.7-4.6,6.8-4.6c4,0,5.1,2.8,5.5,4.4
            +		c0.7-1.8,2.9-4.4,6.6-4.4s5.7,2,5.7,6.4v10.8c1.1,0,2.4,0.4,3.3,0.6v2.2h-6.6V740.7z"/>
            +	<path fill="#808080" d="M199.9,740.9c-1.3,0-2.2,0-3.3-0.2v7c1.1,0,2.4,0.4,3.5,0.6v2.2h-10.3v-2.2c1.1-0.2,2-0.4,3.3-0.6v-23.9
            +		c-0.9-0.2-2.2-0.4-3.3-0.4v-2.2c1.8-0.2,4.6-0.4,6.8-0.4c0,1.1-0.2,2.9-0.4,4l0,0c1.1-2.8,3.5-4.4,6.4-4.4c4.6,0,7.2,3.3,7.2,9.2
            +		C210,736.8,206.1,740.9,199.9,740.9z M201.9,723.6c-3.5,0-5.3,4-5.3,7.5v6.4c1.1,0.4,2.2,0.6,3.5,0.6c3.7,0,6.2-2.2,6.2-7.9
            +		C206.1,726,204.9,723.6,201.9,723.6z"/>
            +	<path fill="#808080" d="M212.4,740.7v-2.2c0.9-0.2,2.2-0.4,3.3-0.6v-23.1c-0.9-0.2-2.2-0.4-3.3-0.4v-2.2c2-0.2,4.6-0.4,7-0.2v26.1
            +		c1.1,0,2.4,0.4,3.3,0.6v2.2h-10.3V740.7z"/>
            +	<path fill="#808080" d="M241,730.8h-12.7c-0.2,5.1,1.8,7.3,6.2,7.3c1.8,0,3.9-0.4,5.5-1.1l0.6,2.8c-2,0.7-4.4,1.3-6.8,1.3
            +		c-5.9,0-9.2-3.1-9.2-10.1c0-5.9,3.3-10.3,8.8-10.3s7.7,3.7,7.7,8.1C241,729.3,241,730,241,730.8z M233.1,723.4
            +		c-2.6,0-4.4,1.8-4.8,5h9.2C237.5,725.3,235.9,723.4,233.1,723.4z"/>
            +	<path fill="#808080" d="M249.1,729.5c-1.3,0-2.4-1.1-2.4-2.4s1.1-2.4,2.4-2.4s2.4,1.1,2.4,2.4S250.4,729.5,249.1,729.5z M249.1,741
            +		c-1.3,0-2.4-1.1-2.4-2.4s1.1-2.4,2.4-2.4s2.4,1.1,2.4,2.4S250.4,741,249.1,741z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M272.6,740.7v-2.2c0.9-0.2,2.2-0.4,3.3-0.6v-23.1c-0.9-0.2-2.2-0.4-3.3-0.4v-2.2c2-0.2,4.6-0.4,7-0.2v26.1
            +		c1.1,0,2.4,0.4,3.3,0.6v2.2h-10.3V740.7z"/>
            +	<path d="M284.7,740.7v-2.2c1.1-0.2,2.2-0.4,3.5-0.6V724c-0.9-0.2-2.2-0.4-3.5-0.4v-2.2c2-0.2,4.6-0.4,7-0.4v16.9
            +		c1.1,0,2.4,0.4,3.3,0.6v2.2H284.7z M289.8,717.2c-1.3,0-2.4-0.9-2.4-2.2s1.1-2.4,2.4-2.4c1.3,0,2.4,1.1,2.4,2.4
            +		S291.1,717.2,289.8,717.2z"/>
            +	<path d="M312.6,740.7v-12.5c0-2.8-0.7-4.4-3.3-4.4c-3.3,0-5.5,3.3-5.5,7.5v6.8c1.1,0,2.2,0.2,3.1,0.6v2.2h-10.1v-2.2
            +		c1.1-0.2,2.2-0.4,3.5-0.6V724c-0.9-0.2-2.2-0.4-3.5-0.4v-2.2c2-0.2,4.6-0.4,6.8-0.4c0,1.1,0,2.9-0.2,4l0,0c1.1-2.8,3.5-4.4,7-4.4
            +		c4.4,0,5.9,2.8,5.9,6.2v11c1.1,0,2.4,0.4,3.3,0.6v2.2H312.6z"/>
            +	<path d="M337.9,730.8h-12.7c-0.2,5.1,1.8,7.3,6.2,7.3c1.8,0,3.9-0.4,5.5-1.1l0.6,2.8c-2,0.7-4.4,1.3-6.8,1.3
            +		c-5.9,0-9.2-3.1-9.2-10.1c0-5.9,3.3-10.3,8.8-10.3c5.5,0,7.7,3.7,7.7,8.1C338.1,729.3,338.1,730,337.9,730.8z M330.2,723.4
            +		c-2.6,0-4.4,1.8-4.8,5h9.2C334.6,725.3,332.9,723.4,330.2,723.4z"/>
            +	<path d="M364.5,749.5c-6.6-6.1-9.7-12.1-9.7-19.8c0-8.1,3.9-14.7,9.7-20l2,2c-5.3,5.1-8.3,11.4-8.3,17.6c0,6.6,2.8,12.5,8.3,17.8
            +		L364.5,749.5z"/>
            +	<path d="M376,740.7v-3.1h7.2V721l-6.8,4.4l-1.3-2.9l8.6-5.3h2.9v20.4h6.1v3.1H376z"/>
            +	<path d="M400.8,745.8c4-1.1,5.3-2.9,5.3-4.4c0-2.4-2-2.6-2-4.6c0-1.7,1.1-2.9,2.8-2.9c2.4,0,3.7,2.4,3.7,5c0,4.8-3.3,7.7-9,9.2
            +		L400.8,745.8z"/>
            +	<path d="M422.3,740.7v-2.9l5.7-5.1c5-4.2,6.2-5.9,6.2-8.4c0-2.6-1.5-4.4-4.8-4.4c-2.2,0-4.4,1.1-5.7,2l-0.7-3.1c2-1.3,4.2-2,7.2-2
            +		c5.3,0,8.1,2.9,8.1,7c0,3.3-1.7,5.9-6.1,9.5l-4.8,4h-0.2c1.8-0.2,6.1-0.2,11.9-0.2v3.3h-16.9V740.7z"/>
            +	<path d="M448,745.8c4-1.1,5.3-2.9,5.3-4.4c0-2.4-2-2.6-2-4.6c0-1.7,1.1-2.9,2.8-2.9c2.4,0,3.7,2.4,3.7,5c0,4.8-3.3,7.7-9,9.2
            +		L448,745.8z"/>
            +	<path d="M474.4,744.3c-1.3,0-2.9-0.2-4.4-0.4l0.2-3.1c1.3,0.4,3.1,0.6,4.4,0.6c4.8,0,7.3-2.8,7.3-5.9c0-3.3-2.8-5.1-7-5.1
            +		c-1.7,0-3.1,0.2-4,0.2v-13.4h13.8v3.3h-10.5v7c0.7,0,1.5,0,1.8,0c6.4,0,9.7,3.3,9.7,7.5C485.9,740.1,481.4,744.3,474.4,744.3z"/>
            +	<path d="M494.9,745.8c4-1.1,5.3-2.9,5.3-4.4c0-2.4-2-2.6-2-4.6c0-1.7,1.1-2.9,2.8-2.9c2.4,0,3.7,2.4,3.7,5c0,4.8-3.3,7.7-9,9.2
            +		L494.9,745.8z"/>
            +	<path d="M516.4,740.7v-2.9l5.7-5.1c5-4.2,6.2-5.9,6.2-8.4c0-2.6-1.5-4.4-4.8-4.4c-2.2,0-4.4,1.1-5.7,2l-0.7-3.1c2-1.3,4.2-2,7.2-2
            +		c5.3,0,8.1,2.9,8.1,7c0,3.3-1.7,5.9-6.1,9.5l-4.8,4h-0.2c1.8-0.2,6.1-0.2,11.9-0.2v3.3h-16.9V740.7z"/>
            +	<path d="M544.5,709.7c6.6,6.1,9.7,12.1,9.7,19.8c0,8.1-3.9,14.7-9.7,20l-2-2c5.3-5.1,8.3-11.4,8.3-17.6c0-6.6-2.8-12.7-8.3-17.8
            +		L544.5,709.7z"/>
            +	<path d="M588.1,746.7l-1.5-1.3c2.6-2.8,2.6-4.6,1.7-5.7c-1.1-1.3-0.2-3.5,1.7-3.5C592.9,736.3,594.2,741,588.1,746.7z M590,729.5
            +		c-1.3,0-2.4-1.1-2.4-2.4s1.1-2.4,2.4-2.4c1.3,0,2.4,1.1,2.4,2.4C592.4,728.4,591.4,729.5,590,729.5z"/>
            +</g>
            +</svg>
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-07.svg b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-07.svg
            new file mode 100644
            index 0000000000..6ae80e3d41
            --- /dev/null
            +++ b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-07.svg
            @@ -0,0 +1,292 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 612 792" enable-background="new 0 0 612 792" xml:space="preserve">
            +<g>
            +	<rect x="-29.6" y="177.1" fill="none" stroke="#999999" stroke-width="1.3" width="444.1" height="444.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-29.6" y1="547.3" x2="414.3" y2="547.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-29.6" y1="473" x2="414.3" y2="473"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-29.6" y1="399.2" x2="414.3" y2="399.2"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-29.6" y1="325.3" x2="414.3" y2="325.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="-29.6" y1="251" x2="414.3" y2="251"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="340.4" y1="177.1" x2="340.4" y2="621.2"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="266.5" y1="177.1" x2="266.5" y2="621.2"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="192.4" y1="177.1" x2="192.4" y2="621.2"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="118.4" y1="177.1" x2="118.4" y2="621.2"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="44.3" y1="177.1" x2="44.3" y2="621.2"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-20.8,70.3l-4-6.7l-3.9,6.7h-5.4v-2.1c1.1-0.2,2.1-0.4,3-0.6l4.3-6.5l-4.1-6.3c-0.9,0-2.1-0.4-3-0.6v-2.1h5.4l3.7,6.5
            +		l3.9-6.5h5.2v2.1c-1.1,0.2-2.1,0.4-3,0.6l-3.9,6.3l4.3,6.5c0.9,0,2.1,0.4,3,0.6v2.1H-20.8z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-130.4,167l-6.3,17.4c-1.9,5.4-3.7,7.3-7.7,7.3c-0.7,0-1.7,0-2.4-0.2l0.2-3c0.7,0.2,1.5,0.4,2.4,0.4c1.9,0,3-0.9,4.3-4.5
            +		l0.7-2.1h-0.7l-5.4-15.5c-0.7,0-1.7-0.2-2.2-0.4v-1.8h8.2v1.9c-0.7,0.2-1.5,0.4-2.2,0.4l2.6,7.7c0.6,1.7,0.9,3,1.3,4.5l0,0
            +		c0.4-1.3,0.9-3.2,1.7-5.2l2.4-6.9c-0.9,0-1.7-0.2-2.2-0.4v-2h8v1.9C-128.7,166.8-129.5,167-130.4,167z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-23.1,131.7c-4.9,0-8.8-2.8-8.8-11c0-7.1,4.3-11.2,9.3-11.2c4.7,0,8.8,2.6,8.8,11C-13.7,127.8-18,131.7-23.1,131.7z
            +		 M-22.9,112.1c-3,0-5.6,2.6-5.6,8.2c0,6,2.2,8.6,5.8,8.6c3,0,5.6-2.4,5.6-8.2C-17.1,114.7-19.5,112.1-22.9,112.1z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M41.9,131.3v-3h6.5v-15.1l-6.2,4.1l-1.1-2.8l7.8-4.9h2.8v18.7h5.6v3H41.9z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M112.6,131.3v-2.6l5-4.7c4.5-3.9,5.6-5.4,5.6-7.8s-1.3-3.9-4.5-3.9c-2.1,0-4.1,0.9-5.2,1.9l-0.7-2.8
            +		c1.9-1.1,3.9-1.9,6.5-1.9c4.9,0,7.3,2.8,7.3,6.3c0,3-1.5,5.4-5.6,8.8l-4.3,3.7h-0.2c1.7-0.2,5.6-0.2,11-0.2v3.2H112.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M189.2,134.7c-1.5,0-3.2-0.2-4.5-0.6l0.6-3c1.3,0.4,2.8,0.7,4.3,0.7c3.7,0,6.3-2.2,6.3-4.9c0-2.6-2.1-4.5-6-4.5
            +		c-1.3,0-2.2,0-3.2,0.2V120h0.7c5,0,7.7-1.5,7.7-4.5c0-2.2-1.7-3.5-4.3-3.5c-2.1,0-3.5,0.6-5,1.3l-0.6-2.8c1.9-0.7,3.9-1.3,6.2-1.3
            +		c4.9,0,7.3,2.4,7.3,5.8c0,2.8-1.7,4.9-4.3,5.6l0,0c3,0.4,5.2,2.8,5.2,5.8C199.4,131.3,195.2,134.7,189.2,134.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M268.9,128.3v6h-3.2v-6h-11l-0.2-2.6l9.9-15.9h4.5v15.5h4.1v3H268.9z M265.7,112.7L265.7,112.7l-8,12.7c2.1,0,6.7,0,8,0
            +		V112.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M332.4,134.7c-1.1,0-2.6-0.2-3.9-0.4l0.2-2.8c1.1,0.4,2.8,0.4,4.1,0.4c4.3,0,6.7-2.4,6.7-5.4s-2.4-4.7-6.5-4.7
            +		c-1.5,0-2.8,0.2-3.7,0.2v-12.3H342v3.2h-9.5v6.3c0.6,0,1.3,0,1.7,0c6,0,9,3,9,6.9C342.8,131,338.7,134.7,332.4,134.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M407.2,131.7c-5,0-8-3.7-8-10.3c0-10.3,5-14.6,11.9-14.6c0.7,0,1.5,0,2.1,0.2v2.8c-0.7-0.2-1.5-0.2-2.4-0.2
            +		c-4.7,0-7.3,2.8-8.2,7.7c-0.2,0.4-0.2,1.1-0.4,1.9l0,0c1.1-2.1,3.4-3.2,5.6-3.2c4.9,0,7.5,3.2,7.5,7.1
            +		C415.4,128.2,412.1,131.7,407.2,131.7z M407.4,118.8c-3,0-4.7,2.6-4.7,4.7c0,3,1.7,5.6,4.9,5.6c2.8,0,4.7-2.2,4.7-5.2
            +		C412.1,120.7,410.4,118.8,407.4,118.8z"/>
            +</g>
            +<circle fill="#808080" cx="44.3" cy="325.3" r="11.6"/>
            +<g enable-background="new    ">
            +	<path d="M-78.9,193.3c-4.9,0-8.8-2.8-8.8-11c0-7.1,4.3-11.2,9.3-11.2c4.7,0,8.8,2.6,8.8,11C-69.6,189.4-73.9,193.3-78.9,193.3z
            +		 M-78.7,173.9c-3,0-5.6,2.6-5.6,8.2c0,6,2.2,8.6,5.8,8.6c3,0,5.6-2.4,5.6-8.2C-72.9,176.5-75.2,173.9-78.7,173.9z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-85.6,264.8v-3h6.5v-15.1l-6.2,4.1l-1.1-2.8l7.8-4.9h2.8v18.7h5.6v3H-85.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-86.4,336.5v-2.6l5-4.7c4.5-3.9,5.6-5.4,5.6-7.8s-1.3-3.9-4.5-3.9c-2.1,0-4.1,0.9-5.2,1.9l-0.7-2.8
            +		c1.9-1.1,3.9-1.9,6.5-1.9c4.9,0,7.3,2.8,7.3,6.3c0,3-1.5,5.4-5.6,8.8l-4.3,3.7h-0.2c1.7-0.2,5.6-0.2,11-0.2v3.2H-86.4z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-81.5,411.4c-1.5,0-3.2-0.2-4.5-0.6l0.6-3c1.3,0.4,2.8,0.7,4.3,0.7c3.7,0,6.3-2.2,6.3-4.9c0-2.6-2.1-4.5-6-4.5
            +		c-1.3,0-2.2,0-3.2,0.2v-2.6h0.7c5,0,7.7-1.5,7.7-4.5c0-2.2-1.7-3.5-4.3-3.5c-2.1,0-3.5,0.6-5,1.3l-0.6-2.8c1.9-0.7,3.9-1.3,6.2-1.3
            +		c4.9,0,7.3,2.4,7.3,5.8c0,2.8-1.7,4.9-4.3,5.6l0,0c3,0.4,5.2,2.8,5.2,5.8C-71.4,408-75.5,411.4-81.5,411.4z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-73.7,476.7v6h-3.2v-6h-11l-0.2-2.6l9.9-15.9h4.5v15.5h4.1v3H-73.7L-73.7,476.7z M-76.8,461.2L-76.8,461.2l-8,12.7
            +		c2.1,0,6.7,0,8,0V461.2z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-81.7,554.7c-1.1,0-2.6-0.2-3.9-0.4l0.2-2.8c1.1,0.4,2.8,0.4,4.1,0.4c4.3,0,6.7-2.4,6.7-5.4s-2.4-4.7-6.5-4.7
            +		c-1.5,0-2.8,0.2-3.7,0.2v-12.3h12.5v3.2h-9.5v6.3c0.6,0,1.3,0,1.7,0c6,0,9,3,9,6.9C-71.2,551-75.5,554.7-81.7,554.7z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M-78.5,623.4c-5,0-8-3.7-8-10.3c0-10.3,5-14.6,11.9-14.6c0.7,0,1.5,0,2.1,0.2v2.8c-0.7-0.2-1.5-0.2-2.4-0.2
            +		c-4.7,0-7.3,2.8-8.2,7.7c-0.2,0.4-0.2,1.1-0.4,1.9l0,0c1.1-2.1,3.4-3.2,5.6-3.2c4.9,0,7.5,3.2,7.5,7.1
            +		C-70.5,620.1-73.7,623.4-78.5,623.4z M-78.5,610.5c-3,0-4.7,2.6-4.7,4.7c0,3,1.7,5.6,4.9,5.6c2.8,0,4.7-2.2,4.7-5.2
            +		S-75.4,610.5-78.5,610.5z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-27.7" y1="177.1" x2="-41.9" y2="177.1"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-27.7" y1="251.4" x2="-41.9" y2="251.4"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-27.7" y1="325.1" x2="-41.9" y2="325.1"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-27.7" y1="398.8" x2="-41.9" y2="398.8"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-27.7" y1="473.1" x2="-41.9" y2="473.1"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-27.7" y1="548" x2="-41.9" y2="548"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-27.7" y1="620.6" x2="-41.9" y2="620.6"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="413.8" y1="176.9" x2="413.8" y2="162.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="339.5" y1="176.9" x2="339.5" y2="162.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="265.7" y1="176.9" x2="265.7" y2="162.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="191.8" y1="176.9" x2="191.8" y2="162.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="117.7" y1="176.9" x2="117.7" y2="162.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="42.6" y1="176.9" x2="42.6" y2="162.7"/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-29.1" y1="176.9" x2="-29.1" y2="162.7"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="-129.5,312.8 -138.3,321.4 -147,312.8 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="-138.3" y1="321.4" x2="-138.3" y2="217.4"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="385.8,523.4 377,532.1 368.2,523.4 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="377" y1="532.1" x2="377" y2="481"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="368.2,348.4 377,339.7 385.8,348.4 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="377" y1="339.7" x2="377" y2="390.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="106.1,50.7 114.9,59.5 106.1,68.2 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="116.9" y1="59.5" x2="12.9" y2="59.5"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="311.3,572.7 320,581.4 311.3,590 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="322.1" y1="581.4" x2="251.2" y2="581.4"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="70.8,590 62,581.4 70.8,572.7 "/>
            +<line fill="none" stroke="#000000" stroke-width="1.3" x1="60" y1="581.4" x2="130.9" y2="581.4"/>
            +<g enable-background="new    ">
            +	<path d="M543.1,389c-4.1-0.7-6,2.1-6,7.8v4.9c1.1,0,2.2,0.2,3.2,0.4v1.9h-9.5v-1.9c0.9-0.2,2.1-0.4,3.2-0.4v-12.9
            +		c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.2-0.2c0,1.1-0.2,2.8-0.4,4.3l0,0c0.7-2.4,2.6-4.9,6.5-4.5V389z"/>
            +	<path d="M560.5,394.9h-11.6c-0.2,4.7,1.7,6.7,5.6,6.7c1.7,0,3.5-0.4,5-1.1l0.4,2.6c-1.9,0.7-3.9,1.1-6.2,1.1
            +		c-5.4,0-8.4-2.8-8.4-9.1c0-5.2,3-9.3,8-9.3s7.1,3.4,7.1,7.3C560.5,393.4,560.5,394.2,560.5,394.9z M553.2,388.2
            +		c-2.2,0-3.9,1.7-4.3,4.5h8.4C557.3,389.9,555.8,388.2,553.2,388.2z"/>
            +	<path d="M571.7,404.1c-4.5,0-8-2.1-8-8.6c0-5.8,3-9.7,8.8-9.7c1.5,0,3.2,0.2,4.3,0.6v5.2h-2.1c-0.2-1.1-0.4-2.1-0.4-3
            +		c-0.6-0.2-1.5-0.4-2.4-0.4c-3.2,0-5,2.6-5,6.5c0,3.5,1.1,6.3,5.4,6.3c1.5,0,3-0.4,4.3-0.9l0.6,2.6
            +		C575.8,403.7,573.9,404.1,571.7,404.1z"/>
            +	<path d="M586.6,404.1c-3.7,0-4.9-1.5-4.9-5.4v-10.3H578V386h3.7v-5.8l3.2-0.9v6.7h5v2.4h-5v9.1c0,3,0.6,3.7,2.6,3.7
            +		c0.7,0,1.7-0.2,2.2-0.4l0.4,2.6C589.2,404.1,587.7,404.1,586.6,404.1z"/>
            +	<path d="M599.1,411.4c-4.3-6.7-5.2-12.3-5.2-17.7c0-5.2,1.3-11.4,5.2-17.7l2.2,1.1c-3,5-4.5,10.6-4.5,16.4c0,6.2,1.5,11.6,4.5,16.6
            +		L599.1,411.4z"/>
            +	<path d="M623.6,403.9l-3.9-6.7l-3.9,6.7h-5.4v-2.1c1.1-0.2,2.1-0.4,3-0.6l4.3-6.5l-4.1-6.3c-0.9,0-2.1-0.4-3-0.6v-2.1h5.4l3.7,6.5
            +		l3.9-6.5h5.2v2.1c-1.1,0.2-2.1,0.4-3,0.6l-3.9,6.3l4.3,6.5c0.9,0,2.1,0.4,3,0.6v2.1H623.6z"/>
            +	<path d="M639.6,409.3l-1.3-1.3c2.2-2.4,2.4-4.1,1.5-5.2c-0.9-1.3-0.2-3.2,1.5-3.2C644.1,399.8,645.2,404.3,639.6,409.3z"/>
            +	<path d="M669.5,388.4l-6.3,17.4c-1.9,5.4-3.7,7.3-7.7,7.3c-0.7,0-1.7,0-2.4-0.2l0.2-3c0.7,0.2,1.5,0.4,2.4,0.4c1.9,0,3-0.9,4.3-4.5
            +		l0.7-2.1H660l-5.4-15.5c-0.7,0-1.7-0.2-2.2-0.4v-1.9h8.2v1.9c-0.7,0.2-1.5,0.4-2.2,0.4l2.6,7.7c0.6,1.7,0.9,3,1.3,4.5l0,0
            +		c0.4-1.3,0.9-3.2,1.7-5.2l2.4-6.9c-0.9,0-1.7-0.2-2.2-0.4V386h8v1.9C671,388.2,670.3,388.4,669.5,388.4z"/>
            +	<path d="M682,409.3l-1.3-1.3c2.2-2.4,2.4-4.1,1.5-5.2c-0.9-1.3-0.2-3.2,1.5-3.2C686.5,399.8,687.6,404.3,682,409.3z"/>
            +	<path d="M722.3,388.4l-4.9,15.5h-3.7l-3.5-10.5c-0.4-1.1-0.7-2.2-0.9-3.5l0,0c-0.4,1.5-0.7,3-1.3,4.5l-3,9.5h-3.7l-4.7-15.5
            +		c-0.7,0-1.5-0.2-2.2-0.4v-1.9h8.2v1.9c-0.7,0.2-1.5,0.4-2.4,0.4l2.2,8c0.4,1.5,0.7,3,1.1,4.1l0,0c0.4-1.5,0.7-3,1.3-4.3l3.2-10.1
            +		h3.4l3.2,10.1c0.6,2.1,0.9,3.2,1.3,4.3l0,0c0.4-1.3,0.6-2.2,1.1-3.9l2.2-8c-0.7,0-1.7-0.2-2.4-0.4v-1.9h8v1.9
            +		C724,388.2,723.3,388.4,722.3,388.4z"/>
            +	<path d="M725.9,403.9V402c0.9-0.2,2.1-0.4,3.2-0.4v-12.9c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v15.5
            +		c1.1,0,2.1,0.2,3,0.4v1.9h-9.3V403.9z M730.7,382.4c-1.1,0-2.2-0.9-2.2-2.1c0-1.1,0.9-2.1,2.2-2.1c1.1,0,2.1,0.9,2.1,2.1
            +		S731.9,382.4,730.7,382.4z"/>
            +	<path d="M749.8,403.9c0-0.9,0-2.6,0.4-3.5l0,0c-0.9,2.4-3.2,3.9-6,3.9c-4.3,0-6.5-3.2-6.5-8.4c0-6.2,3.5-10.1,9.1-10.1
            +		c0.9,0,1.9,0,3,0.2v-5.8c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v23.5c0.9,0.2,2.1,0.4,3,0.4v1.9
            +		C754.3,403.9,751.7,403.9,749.8,403.9z M749.6,388.8c-1.1-0.2-2.2-0.4-3.2-0.4c-3.4,0-5.6,2.1-5.6,7.1c0,3.9,1.3,6,3.9,6
            +		c3.2,0,4.9-3.7,4.9-6.9L749.6,388.8L749.6,388.8z"/>
            +	<path d="M764.5,404.1c-3.7,0-4.9-1.5-4.9-5.4v-10.3h-3.7V386h3.7v-5.8l3.2-0.9v6.7h5v2.4h-5v9.1c0,3,0.6,3.7,2.6,3.7
            +		c0.7,0,1.7-0.2,2.2-0.4l0.4,2.6C767,404.1,765.7,404.1,764.5,404.1z"/>
            +	<path d="M784.1,403.9v-11.4c0-2.4-0.7-3.9-3-3.9c-3,0-5,3-5,6.9v6.2c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.1v-1.9c0.9-0.2,2.1-0.4,3-0.4
            +		v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v8.4c0,1.1,0,2.6-0.4,3.5l0,0c1.1-2.4,3.2-3.9,6.2-3.9
            +		c4.1,0,5.4,2.6,5.4,5.8v10.1c0.9,0,2.1,0.2,3,0.4v1.9h-6V403.9z"/>
            +	<path d="M801.1,409.3l-1.3-1.3c2.2-2.4,2.4-4.1,1.5-5.2c-0.9-1.3-0.2-3.2,1.5-3.2C805.6,399.8,806.7,404.3,801.1,409.3z"/>
            +	<path d="M828.2,403.9v-11.4c0-2.4-0.7-3.9-3-3.9c-3,0-5,3-5,6.9v6.2c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.1v-1.9c0.9-0.2,2.1-0.4,3-0.4
            +		v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v8.4c0,1.1,0,2.6-0.4,3.5l0,0c1.1-2.4,3.2-3.9,6.2-3.9
            +		c4.1,0,5.4,2.6,5.4,5.8v10.1c0.9,0,2.1,0.2,3,0.4v1.9h-6V403.9z"/>
            +	<path d="M851.5,394.9h-11.6c-0.2,4.7,1.7,6.7,5.6,6.7c1.7,0,3.5-0.4,5-1.1l0.4,2.6c-1.9,0.7-3.9,1.1-6.2,1.1
            +		c-5.4,0-8.4-2.8-8.4-9.1c0-5.2,3-9.3,8-9.3s7.1,3.4,7.1,7.3C851.7,393.4,851.7,394.2,851.5,394.9z M844.4,388.2
            +		c-2.2,0-3.9,1.7-4.3,4.5h8.4C848.5,389.9,846.9,388.2,844.4,388.2z"/>
            +	<path d="M854.3,403.9V402c0.9-0.2,2.1-0.4,3.2-0.4v-12.9c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v15.5
            +		c1.1,0,2.1,0.2,3,0.4v1.9h-9.3V403.9z M859.2,382.4c-1.1,0-2.2-0.9-2.2-2.1c0-1.1,0.9-2.1,2.2-2.1c1.1,0,2.1,0.9,2.1,2.1
            +		C861.2,381.5,860.3,382.4,859.2,382.4z"/>
            +	<path d="M873.4,413c-4.7,0-7.5-1.9-7.5-5.4c0-2.1,1.3-3.9,3-4.7c-1.1-0.4-1.7-1.5-1.7-2.6c0-1.3,0.7-2.4,2.1-3
            +		c-1.7-0.9-2.6-2.6-2.6-4.9c0-3.5,2.6-6.7,7.5-6.7c0.9,0,1.7,0.2,2.4,0.4h6v2.6h-3c0.9,0.7,1.5,1.9,1.5,3.4c0,3.7-2.4,6.5-7.5,6.5
            +		c-0.7,0-1.3,0-1.9-0.2c-0.7,0.4-1.1,0.9-1.1,1.5c0,0.9,0.9,1.3,3,1.3l3.2,0.2c3.9,0.2,6,1.9,6,5.2C882.7,410.1,879,413,873.4,413z
            +		 M875.8,403.7l-3.4-0.2c-0.4,0-0.7,0-1.1,0c-1.3,0.9-2.2,2.2-2.2,3.5c0,2.1,2.1,3.4,4.9,3.4c3.5,0,5.6-1.7,5.6-3.9
            +		C879.5,405,878.2,403.9,875.8,403.7z M873.7,388.2c-2.6,0-4.3,1.7-4.3,3.9c0,2.4,1.5,3.9,4.1,3.9s4.1-1.5,4.1-3.9
            +		C877.9,389.7,876.4,388.2,873.7,388.2z"/>
            +	<path d="M898.8,403.9v-11.4c0-2.4-0.7-3.9-3-3.9c-3,0-5,3-5,6.9v6.2c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.1v-1.9c0.9-0.2,2.1-0.4,3-0.4
            +		v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v8.4c0,1.1,0,2.6-0.4,3.5l0,0c1.1-2.4,3.2-3.9,6.2-3.9
            +		c4.1,0,5.4,2.6,5.4,5.8v10.1c0.9,0,2.1,0.2,3,0.4v1.9h-6V403.9z"/>
            +	<path d="M913.7,404.1c-3.7,0-4.9-1.5-4.9-5.4v-10.3h-3.7V386h3.7v-5.8l3.2-0.9v6.7h5v2.4h-5v9.1c0,3,0.6,3.7,2.6,3.7
            +		c0.7,0,1.7-0.2,2.2-0.4l0.4,2.6C916.3,404.1,914.8,404.1,913.7,404.1z"/>
            +	<path d="M929.6,411.4l-2.2-1.1c3-5,4.5-10.6,4.5-16.4c0-6.2-1.5-11.6-4.5-16.6l2.4-1.1c4.1,6.7,5.2,12.3,5.2,17.5
            +		C934.8,398.7,933.7,404.8,929.6,411.4z"/>
            +	<path d="M949,409.3l-1.3-1.3c2.2-2.4,2.4-4.1,1.5-5.2c-0.9-1.3-0.2-3.2,1.5-3.2C953.3,399.8,954.4,404.3,949,409.3z M950.7,393.6
            +		c-1.3,0-2.2-0.9-2.2-2.2c0-1.3,0.9-2.2,2.2-2.2c1.3,0,2.2,0.9,2.2,2.2S952,393.6,950.7,393.6z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M66.7,312.4c-6-5.4-8.8-11.2-8.8-18.1c0-7.3,3.5-13.4,9-18.3l1.9,1.9c-4.9,4.7-7.5,10.3-7.5,16.1c0,6,2.4,11.4,7.5,16.4
            +		L66.7,312.4z"/>
            +	<path d="M77.2,304.2v-2.8h6.5v-15.1l-6.2,4.1l-1.1-2.8l8-4.9h2.8v18.7h5.6v3H77.1L77.2,304.2L77.2,304.2z"/>
            +	<path d="M99.9,309.1c3.7-0.9,4.9-2.6,4.9-3.9c0-2.2-1.9-2.2-1.9-4.3c0-1.5,1.1-2.6,2.6-2.6c2.2,0,3.4,2.2,3.4,4.5
            +		c0,4.5-3,7.1-8.2,8.4L99.9,309.1z"/>
            +	<path d="M119.5,304.2v-2.6l5-4.7c4.5-3.9,5.6-5.4,5.6-7.8s-1.3-3.9-4.5-3.9c-2.1,0-4.1,0.9-5.2,1.9l-0.7-2.8
            +		c1.9-1.1,3.9-1.9,6.5-1.9c4.9,0,7.3,2.8,7.3,6.3c0,3-1.5,5.4-5.6,8.8l-4.3,3.7h-0.2c1.7-0.2,5.6-0.2,11-0.2v3.2H119.5z"/>
            +	<path d="M145.1,276c6,5.6,8.8,11.2,8.8,18.1c0,7.3-3.5,13.4-9,18.3l-1.9-1.9c4.9-4.7,7.5-10.3,7.5-16.1c0-6-2.4-11.6-7.5-16.4
            +		L145.1,276z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="42.1" y1="326.4" x2="340.4" y2="326.4"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="42.1" y1="545.6" x2="340.4" y2="545.6"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="338.5" y1="547.3" x2="338.5" y2="325.3"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="43.8" y1="547.3" x2="43.8" y2="325.3"/>
            +<g enable-background="new    ">
            +	<path fill="#808080" d="M-16.5,721.6v-1.9c0.9-0.2,2.1-0.4,3.2-0.4v-19.4c-1.1,0-2.2-0.2-3.2-0.4v-1.9h15.7v5.6H-3
            +		c-0.2-1.1-0.4-2.2-0.4-3h-6.5v8h5.2c0.2-0.9,0.4-1.7,0.6-2.4H-2v7.3h-2.1c-0.2-0.7-0.4-1.7-0.6-2.4h-5.2v8.6h6.5
            +		c0.2-0.9,0.4-2.1,0.6-3.2h2.2v5.8h-15.9V721.6z"/>
            +	<path fill="#808080" d="M15,721.6l-3.9-6.7l-3.9,6.7H1.7v-2c1.1-0.2,2.1-0.4,3-0.6l4.3-6.5l-4.1-6.3c-0.9,0-2.1-0.4-3-0.6v-2.1h5.4
            +		l3.7,6.5l3.9-6.5h5.2v2.1c-1.1,0.2-2.1,0.4-3,0.6l-3.9,6.3l4.3,6.5c0.9,0,2.1,0.4,3,0.6v2.1L15,721.6L15,721.6z"/>
            +	<path fill="#808080" d="M33.5,721.6c0-1.3,0-2.6,0.2-3.5l0,0c-0.9,2.2-3.2,3.9-6,3.9c-3,0-4.9-1.9-4.9-4.7c0-3.9,3.9-6.2,10.6-6.2
            +		v-1.3c0-2.4-0.9-3.9-3.7-3.9c-1.1,0-2.2,0.2-3.4,0.6c0,0.9-0.2,1.9-0.4,3h-2.1v-4.9c1.9-0.6,3.9-0.9,6-0.9c5.2,0,6.7,2.4,6.7,6v9.7
            +		c0.9,0.2,2.1,0.4,3,0.4v1.9C37.8,721.6,35.3,721.8,33.5,721.6z M33.3,713.4c-5.6,0-7.5,1.3-7.5,3.4c0,1.5,1.1,2.6,2.8,2.6
            +		c2.8,0,4.9-2.8,4.9-5.6v-0.4H33.3z"/>
            +	<path fill="#808080" d="M66.5,721.6v-11.4c0-2.4-0.6-4.1-2.8-4.1c-2.6,0-5,2.6-5,7.1v6c0.9,0,2.1,0.2,3,0.4v1.9h-6.2v-11.2
            +		c0-2.2-0.4-4.1-3-4.1s-5,3-5,7.1v6c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.1v-2c0.9-0.2,2.1-0.4,3.2-0.4v-12.9c-0.9-0.2-2.1-0.4-3.2-0.4V704
            +		c1.9-0.2,4.3-0.4,6.3-0.2c0,1.1-0.2,2.6-0.4,3.7l0,0c0.9-2.4,3.4-4.1,6.2-4.1c3.7,0,4.9,2.6,4.9,4.1c0.7-1.7,2.6-4.1,6.2-4.1
            +		c3.4,0,5.2,1.9,5.2,5.8v9.9c1.1,0,2.1,0.2,3,0.4v1.9h-6L66.5,721.6L66.5,721.6z"/>
            +	<path fill="#808080" d="M83,721.8c-1.1,0-2.1,0-3-0.2v6.5c1.1,0,2.2,0.2,3.2,0.4v1.9h-9.3v-1.9c0.9-0.2,1.9-0.4,3-0.4v-21.7
            +		c-0.9-0.2-2.1-0.4-3-0.4v-1.9c1.7-0.2,4.1-0.4,6.2-0.2c0,0.9-0.2,2.6-0.4,3.5l0,0c0.9-2.4,3.2-3.9,6-3.9c4.1,0,6.5,3,6.5,8.4
            +		C92.1,718.3,88.7,721.8,83,721.8z M84.8,706.1c-3.2,0-4.9,3.7-4.9,6.9v5.8c0.9,0.4,2.1,0.4,3.2,0.4c3.4,0,5.6-2.1,5.6-7.1
            +		C88.7,708.4,87.4,706.1,84.8,706.1z"/>
            +	<path fill="#808080" d="M94.3,721.6v-1.9c0.9-0.2,2.1-0.4,3-0.4V698c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v23.7
            +		c1.1,0,2.1,0.2,3,0.4v1.9h-9.1V721.6z"/>
            +	<path fill="#808080" d="M120.5,712.7h-11.8c-0.2,4.7,1.7,6.7,5.6,6.7c1.7,0,3.5-0.4,5-1.1l0.4,2.6c-1.9,0.7-3.9,1.1-6.2,1.1
            +		c-5.4,0-8.4-2.8-8.4-9.1c0-5.2,3-9.3,8-9.3s7.1,3.4,7.1,7.3C120.5,711.2,120.5,711.9,120.5,712.7z M113.2,705.9
            +		c-2.2,0-3.9,1.7-4.3,4.5h8.4C117.3,707.6,115.8,705.9,113.2,705.9z"/>
            +	<path fill="#808080" d="M127.9,711.5c-1.3,0-2.2-0.9-2.2-2.2s0.9-2.2,2.2-2.2s2.2,0.9,2.2,2.2C130.2,710.4,129.1,711.5,127.9,711.5
            +		z M127.9,722c-1.3,0-2.2-0.9-2.2-2.2s0.9-2.2,2.2-2.2s2.2,0.9,2.2,2.2C130.2,720.9,129.1,722,127.9,722z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M162.1,706.7c-4.1-0.7-6,2.1-6,7.8v4.9c1.1,0,2.2,0.2,3.2,0.4v1.9h-9.5v-1.9c0.9-0.2,2.1-0.4,3.2-0.4v-12.9
            +		c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.2-0.2c0,1.1-0.2,2.8-0.4,4.3l0,0c0.7-2.4,2.6-4.9,6.5-4.5L162.1,706.7
            +		L162.1,706.7z"/>
            +	<path d="M179.3,712.7h-11.6c-0.2,4.7,1.7,6.7,5.6,6.7c1.7,0,3.5-0.4,5-1.1l0.4,2.6c-1.9,0.7-3.9,1.1-6.2,1.1
            +		c-5.4,0-8.4-2.8-8.4-9.1c0-5.2,3-9.3,8-9.3s7.1,3.4,7.1,7.3C179.3,711.2,179.3,711.9,179.3,712.7z M172.2,705.9
            +		c-2.2,0-3.9,1.7-4.3,4.5h8.4C176.1,707.6,174.6,705.9,172.2,705.9z"/>
            +	<path d="M190.5,722c-4.5,0-8-2.1-8-8.6c0-5.8,3-9.7,8.8-9.7c1.5,0,3.2,0.2,4.3,0.6v5.2h-2.1c-0.2-1.1-0.4-2.1-0.4-3
            +		c-0.6-0.2-1.5-0.4-2.4-0.4c-3.2,0-5,2.6-5,6.5c0,3.5,1.1,6.3,5.4,6.3c1.5,0,3-0.4,4.3-0.9l0.6,2.6C194.6,721.4,192.7,722,190.5,722
            +		z"/>
            +	<path d="M205.6,722c-3.7,0-4.9-1.5-4.9-5.4v-10.3H197v-2.4h3.7v-5.8l3.2-0.9v6.7h5v2.4h-5v9.1c0,3,0.6,3.7,2.6,3.7
            +		c0.7,0,1.7-0.2,2.2-0.4l0.4,2.6C208,721.8,206.7,722,205.6,722z"/>
            +	<path d="M232.7,729.7c-6-5.4-8.8-11.2-8.8-18.1c0-7.3,3.5-13.4,9-18.3l1.9,1.9c-4.9,4.7-7.5,10.3-7.5,16.1c0,6,2.4,11.4,7.5,16.4
            +		L232.7,729.7z"/>
            +	<path d="M243.3,721.6v-3h6.5v-15.1l-6.1,4.1l-1.1-2.8l7.8-4.9h2.8v18.7h5.6v3H243.3L243.3,721.6z"/>
            +	<path d="M266.1,726.3c3.7-0.9,4.9-2.6,4.9-3.9c0-2.2-1.9-2.2-1.9-4.3c0-1.5,1.1-2.6,2.6-2.6c2.2,0,3.4,2.2,3.4,4.5
            +		c0,4.5-3,7.1-8.2,8.4L266.1,726.3z"/>
            +	<path d="M285.5,721.6V719l5-4.7c4.5-3.9,5.6-5.4,5.6-7.8c0-2.4-1.3-3.9-4.5-3.9c-2.1,0-4.1,0.9-5.2,1.9l-0.7-2.8
            +		c1.9-1.1,3.9-1.9,6.5-1.9c4.9,0,7.3,2.8,7.3,6.3c0,3-1.5,5.4-5.6,8.8l-4.3,3.7h-0.2c1.7-0.2,5.6-0.2,11-0.2v3.2H285.5L285.5,721.6z
            +		"/>
            +	<path d="M309,726.3c3.7-0.9,4.9-2.6,4.9-3.9c0-2.2-1.9-2.2-1.9-4.3c0-1.5,1.1-2.6,2.6-2.6c2.2,0,3.4,2.2,3.4,4.5
            +		c0,4.5-3,7.1-8.2,8.4L309,726.3z"/>
            +	<path d="M341.3,718.6v6h-3.2v-6h-11l-0.2-2.6l9.9-15.9h4.5v15.5h4.1v3H341.3L341.3,718.6z M338.2,703.1L338.2,703.1l-8,12.7
            +		c2.1,0,6.7,0,8,0V703.1z"/>
            +	<path d="M352,726.3c3.7-0.9,4.9-2.6,4.9-3.9c0-2.2-1.9-2.2-1.9-4.3c0-1.5,1.1-2.6,2.6-2.6c2.2,0,3.4,2.2,3.4,4.5
            +		c0,4.5-3,7.1-8.2,8.4L352,726.3z"/>
            +	<path d="M376.4,725c-1.5,0-3.2-0.2-4.5-0.6l0.6-3c1.3,0.4,2.8,0.7,4.3,0.7c3.7,0,6.3-2.2,6.3-4.9c0-2.6-2.1-4.5-6-4.5
            +		c-1.3,0-2.2,0-3.2,0.2v-2.6h0.7c5,0,7.7-1.5,7.7-4.5c0-2.2-1.7-3.5-4.3-3.5c-2.1,0-3.5,0.6-5,1.3l-0.6-2.8c1.9-0.7,3.9-1.3,6.2-1.3
            +		c4.9,0,7.3,2.4,7.3,5.8c0,2.8-1.7,4.9-4.3,5.6l0,0c3,0.4,5.2,2.8,5.2,5.8C386.7,721.6,382.4,725,376.4,725z"/>
            +	<path d="M397.1,693.4c6,5.6,8.8,11.2,8.8,18.1c0,7.3-3.5,13.4-9,18.3l-1.9-1.9c4.9-4.7,7.5-10.3,7.5-16.1c0-6-2.4-11.6-7.5-16.4
            +		L397.1,693.4z"/>
            +	<path d="M423.5,727.2l-1.3-1.3c2.2-2.4,2.4-4.1,1.5-5.2c-0.9-1.3-0.2-3.2,1.5-3.2C427.8,717.5,428.9,722.2,423.5,727.2z
            +		 M425.1,711.5c-1.3,0-2.2-0.9-2.2-2.2s0.9-2.2,2.2-2.2s2.2,0.9,2.2,2.2C427.4,710.4,426.3,711.5,425.1,711.5z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M164.9,573.8l-4.9,15.5h-3.7l-3.5-10.5c-0.4-1.1-0.7-2.2-0.9-3.5l0,0c-0.4,1.5-0.7,3-1.3,4.5l-3,9.5h-3.7l-4.7-15.5
            +		c-0.7,0-1.5-0.2-2.2-0.4v-1.9h8.2v1.9c-0.7,0.2-1.5,0.4-2.4,0.4l2.2,8c0.4,1.5,0.7,3,1.1,4.1l0,0c0.4-1.5,0.7-3,1.3-4.3l3.2-10.1
            +		h3.4l3.2,10.1c0.6,2.1,0.9,3.2,1.3,4.3l0,0c0.4-1.3,0.6-2.2,1.1-3.9l2.2-8c-0.7,0-1.7-0.2-2.4-0.4v-1.9h8v1.9
            +		C166.4,573.6,165.7,573.8,164.9,573.8z"/>
            +	<path d="M168.5,589.3v-1.9c0.9-0.2,2.1-0.4,3.2-0.4v-13.1c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v15.5
            +		c1.1,0,2.1,0.2,3,0.4v1.9h-9.3V589.3z M173.1,568c-1.1,0-2.2-0.9-2.2-2.1s0.9-2.1,2.2-2.1c1.1,0,2.1,0.9,2.1,2.1
            +		C175.4,567.1,174.2,568,173.1,568z"/>
            +	<path d="M192.2,589.3c0-0.9,0-2.6,0.4-3.5l0,0c-0.9,2.4-3.2,3.9-6,3.9c-4.3,0-6.5-3.2-6.5-8.4c0-6.2,3.5-10.1,9.1-10.1
            +		c0.9,0,1.9,0,3,0.2v-5.8c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v23.5c0.9,0.2,2.1,0.4,3,0.4v1.9
            +		C196.6,589.3,194.2,589.5,192.2,589.3z M192.2,574.1c-1.1-0.2-2.2-0.4-3.2-0.4c-3.4,0-5.6,2.1-5.6,7.1c0,3.9,1.3,6,3.9,6
            +		c3.2,0,4.9-3.7,4.9-6.9L192.2,574.1L192.2,574.1z"/>
            +	<path d="M206.9,589.6c-3.7,0-4.9-1.5-4.9-5.4v-10.3h-3.7v-2.4h3.7v-5.8l3.2-0.9v6.7h5v2.4h-5v9.1c0,3,0.6,3.7,2.6,3.7
            +		c0.7,0,1.7-0.2,2.2-0.4l0.4,2.6C209.3,589.5,208,589.6,206.9,589.6z"/>
            +	<path d="M226.7,589.3v-11.4c0-2.4-0.7-4.1-3-4.1c-3,0-5,3-5,6.9v6.2c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.1v-1.9c0.9-0.2,2.1-0.4,3-0.4
            +		v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4v-1.9c1.9-0.2,4.3-0.4,6.3-0.2v8.4c0,1.1,0,2.6-0.4,3.5l0,0c1.1-2.4,3.2-3.9,6.2-3.9
            +		c4.1,0,5.4,2.6,5.4,5.8V587c0.9,0,2.1,0.2,3,0.4v1.9L226.7,589.3L226.7,589.3z"/>
            +</g>
            +<g enable-background="new    ">
            +	<path d="M369.7,447.9v-11.3c0-2.4-0.7-4.1-3-4.1c-3,0-5,3-5,6.9v6.2c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.1V446c0.9-0.2,2.1-0.4,3-0.4
            +		v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4V422c1.9-0.2,4.3-0.4,6.3-0.2v8.4c0,1.1,0,2.6-0.4,3.5l0,0c1.1-2.4,3.2-3.9,6.2-3.9
            +		c4.1,0,5.4,2.6,5.4,5.8v10.1c0.9,0,2.1,0.2,3,0.4v1.9L369.7,447.9L369.7,447.9z"/>
            +	<path d="M393,439h-11.8c-0.2,4.7,1.7,6.7,5.6,6.7c1.7,0,3.5-0.4,5-1.1l0.4,2.6c-1.9,0.7-3.9,1.1-6.2,1.1c-5.4,0-8.4-2.8-8.4-9.1
            +		c0-5.2,3-9.3,8-9.3s7.1,3.4,7.1,7.3C393,437.5,393,438.2,393,439z M385.8,432.3c-2.2,0-3.9,1.7-4.3,4.5h8.4
            +		C389.9,433.9,388.4,432.3,385.8,432.3z"/>
            +	<path d="M395.8,447.9V446c0.9-0.2,2.1-0.4,3.2-0.4v-12.9c-0.9-0.2-2.1-0.4-3.2-0.4v-1.7c1.9-0.2,4.3-0.4,6.3-0.2v15.5
            +		c1.1,0,2.1,0.2,3,0.4v1.9h-9.3L395.8,447.9L395.8,447.9z M400.5,426.5c-1.1,0-2.2-0.9-2.2-2.1s0.9-2.1,2.2-2.1
            +		c1.1,0,2.1,0.9,2.1,2.1C402.6,425.5,401.6,426.5,400.5,426.5z"/>
            +	<path d="M414.7,457.1c-4.7,0-7.5-1.9-7.5-5.4c0-2.1,1.3-3.9,3-4.7c-1.1-0.4-1.7-1.5-1.7-2.6c0-1.3,0.7-2.4,2.1-3
            +		c-1.7-0.9-2.6-2.6-2.6-4.9c0-3.5,2.6-6.7,7.5-6.7c0.9,0,1.7,0.2,2.4,0.4h6v2.6h-3c0.9,0.7,1.5,1.9,1.5,3.4c0,3.7-2.4,6.5-7.5,6.5
            +		c-0.7,0-1.3,0-1.9-0.2c-0.7,0.4-1.1,0.9-1.1,1.5c0,0.9,0.9,1.3,3,1.3l3.2,0.2c3.9,0.2,6,1.9,6,5.2
            +		C424,454.1,420.3,457.1,414.7,457.1z M417.1,447.8l-3.4-0.2c-0.4,0-0.7,0-1.1,0c-1.3,0.9-2.2,2.2-2.2,3.5c0,2.1,2.1,3.4,4.9,3.4
            +		c3.5,0,5.6-1.7,5.6-3.9C420.9,449.1,419.7,447.9,417.1,447.8z M415.3,432.3c-2.6,0-4.3,1.7-4.3,3.9c0,2.4,1.5,3.9,4.1,3.9
            +		s4.1-1.5,4.1-3.9C419.2,433.8,417.7,432.3,415.3,432.3z"/>
            +	<path d="M440.1,447.9v-11.3c0-2.4-0.7-4.1-3-4.1c-3,0-5,3-5,6.9v6.2c0.9,0,2.1,0.2,2.8,0.4v1.9h-9.2V446c0.9-0.2,2.1-0.4,3-0.4
            +		v-21.3c-0.9-0.2-2.1-0.4-3.2-0.4V422c1.9-0.2,4.3-0.4,6.3-0.2v8.4c0,1.1,0,2.6-0.4,3.5l0,0c1.1-2.4,3.2-3.9,6.2-3.9
            +		c4.1,0,5.4,2.6,5.4,5.8v10.1c0.9,0,2.1,0.2,3,0.4v1.9L440.1,447.9L440.1,447.9z"/>
            +	<path d="M455.2,448.1c-3.7,0-4.9-1.5-4.9-5.4v-10.3h-3.7V430h3.7v-5.8l3.2-0.9v6.7h5v2.4h-5v9.1c0,3,0.6,3.7,2.6,3.7
            +		c0.7,0,1.7-0.2,2.2-0.4l0.4,2.6C457.6,448.1,456.3,448.1,455.2,448.1z"/>
            +</g>
            +</svg>
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-08.svg b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-08.svg
            new file mode 100644
            index 0000000000..68f140e7d1
            --- /dev/null
            +++ b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-08.svg
            @@ -0,0 +1,297 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 640 480" enable-background="new 0 0 640 480" xml:space="preserve">
            +<g>
            +	<rect x="74.3" y="101.5" fill="none" stroke="#999999" stroke-width="1.3" width="267.6" height="267.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="74.3" y1="324.6" x2="341.9" y2="324.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="74.3" y1="279.9" x2="341.9" y2="279.9"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="74.3" y1="235.3" x2="341.9" y2="235.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="74.3" y1="190.8" x2="341.9" y2="190.8"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="74.3" y1="146.1" x2="341.9" y2="146.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="297.3" y1="101.5" x2="297.3" y2="369.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="252.8" y1="101.5" x2="252.8" y2="369.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="208.1" y1="101.5" x2="208.1" y2="369.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="163.5" y1="101.5" x2="163.5" y2="369.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="119" y1="101.5" x2="119" y2="369.1"/>
            +</g>
            +<g>
            +	<path d="M79.7,37.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H79.7z"/>
            +</g>
            +<g>
            +	<path d="M13.6,95.4l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2c1.2,0,1.8-0.6,2.6-2.7
            +		l0.5-1.2H7.9l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3V94h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6c0.3,1,0.6,1.8,0.8,2.7h0
            +		c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3V94H15v1.2C14.6,95.3,14.1,95.4,13.6,95.4z"/>
            +</g>
            +<g>
            +	<path d="M78.3,74.1c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C83.9,71.7,81.3,74.1,78.3,74.1z
            +		 M78.4,62.3c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C81.8,63.9,80.5,62.3,78.4,62.3z"/>
            +	<path d="M117.4,73.9v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H117.4z"/>
            +	<path d="M160.1,73.9v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H160.1z"/>
            +	<path d="M206.2,75.9c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C212.4,73.9,209.8,75.9,206.2,75.9z"/>
            +	<path d="M254.2,72.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.6h2.7v9.4h2.5v1.8H254.2z M252.3,62.7L252.3,62.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V62.7z"/>
            +	<path d="M292.5,75.9c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C298.9,73.6,296.3,75.9,292.5,75.9z"/>
            +	<path d="M337.6,74.1c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C342.5,72.1,340.6,74.1,337.6,74.1z M337.7,66.3c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C340.6,67.5,339.6,66.3,337.7,66.3z"/>
            +</g>
            +<circle fill="#808080" cx="209" cy="189.6" r="7"/>
            +<g>
            +	<path d="M44.7,111.3c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C50.3,108.9,47.7,111.3,44.7,111.3z
            +		 M44.8,99.5c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C48.2,101.1,46.9,99.5,44.8,99.5z"/>
            +	<path d="M40.6,154.3v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H40.6z"/>
            +	<path d="M40.1,197.5v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H40.1z"/>
            +	<path d="M43,242.7c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C49.2,240.7,46.6,242.7,43,242.7z"/>
            +	<path d="M47.8,282.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H47.8z M45.9,272.7L45.9,272.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V272.7z"/>
            +	<path d="M42.9,329.1c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C49.3,326.8,46.7,329.1,42.9,329.1z"/>
            +	<path d="M44.8,370.5c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C49.7,368.5,47.8,370.5,44.8,370.5z M44.9,362.7c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C47.8,363.9,46.8,362.7,44.9,362.7z"/>
            +</g>
            +<line stroke="#000000" stroke-width="1.3" x1="75.4" y1="101.5" x2="66.9" y2="101.5"/>
            +<line stroke="#000000" stroke-width="1.3" x1="75.4" y1="146.3" x2="66.9" y2="146.3"/>
            +<line stroke="#000000" stroke-width="1.3" x1="75.4" y1="190.7" x2="66.9" y2="190.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="75.4" y1="235.2" x2="66.9" y2="235.2"/>
            +<line stroke="#000000" stroke-width="1.3" x1="75.4" y1="279.9" x2="66.9" y2="279.9"/>
            +<line stroke="#000000" stroke-width="1.3" x1="75.4" y1="325.1" x2="66.9" y2="325.1"/>
            +<line stroke="#000000" stroke-width="1.3" x1="75.4" y1="368.7" x2="66.9" y2="368.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="341.5" y1="101.4" x2="341.5" y2="92.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="296.7" y1="101.4" x2="296.7" y2="92.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="252.3" y1="101.4" x2="252.3" y2="92.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="207.8" y1="101.4" x2="207.8" y2="92.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="163.1" y1="101.4" x2="163.1" y2="92.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="117.9" y1="101.4" x2="117.9" y2="92.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="74.7" y1="101.4" x2="74.7" y2="92.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="14.1,183.2 8.8,188.5 3.5,183.2 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="8.8" y1="188.5" x2="8.8" y2="125.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="156.2,25.3 161.5,30.6 156.2,35.9 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="162.7" y1="30.6" x2="100" y2="30.6"/>
            +<g>
            +	<path d="M419.6,229.1c-2.5-0.4-3.6,1.3-3.6,4.7v2.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7V237c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.7-0.1,1.7-0.2,2.5h0c0.5-1.5,1.6-3,3.9-2.7L419.6,229.1z"/>
            +	<path d="M429.9,232.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C430,231.9,430,232.3,429.9,232.8z M425.6,228.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C428,229.7,427.1,228.7,425.6,228.7z"/>
            +	<path d="M436.7,238.3c-2.7,0-4.9-1.2-4.9-5.2c0-3.5,1.8-5.9,5.3-5.9c0.9,0,1.9,0.2,2.6,0.4v3.1h-1.2c-0.1-0.6-0.2-1.2-0.3-1.8
            +		c-0.4-0.1-0.9-0.2-1.4-0.2c-1.9,0-3,1.6-3,4c0,2.2,0.7,3.8,3.2,3.8c0.9,0,1.8-0.2,2.6-0.5l0.3,1.6C439.2,238,438,238.3,436.7,238.3
            +		z"/>
            +	<path d="M445.8,238.3c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C447.3,238.2,446.5,238.3,445.8,238.3z"/>
            +	<path d="M463.5,238.2V237c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10h-1.8
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5V237c0.4-0.1,1-0.2,1.3-0.2
            +		L452,225c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H463.5z"/>
            +	<path d="M474.6,238.3c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C479.8,235.8,477.8,238.3,474.6,238.3z
            +		 M474.8,228.8c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C477.8,230.3,476.8,228.8,474.8,228.8z"/>
            +	<path d="M489,238.2c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2C491.7,238.1,490.2,238.2,489,238.2
            +		z M488.9,229c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6c1.9,0,2.9-2.3,2.9-4.1V229z"/>
            +	<path d="M502.9,232.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C503,231.9,502.9,232.3,502.9,232.8z M498.6,228.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C501,229.7,500.1,228.7,498.6,228.7z"/>
            +	<path d="M513.3,242.7c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L513.3,242.7z"/>
            +	<path d="M527.5,238.3c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6H530c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C530.5,238,529,238.3,527.5,238.3z"/>
            +	<path d="M533,238.2V237c0.6-0.1,1.2-0.2,1.9-0.3V225c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4H541c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9v4.8
            +		h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H533z"/>
            +	<path d="M558.1,225v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2h-5.5V237
            +		c0.6-0.1,1.2-0.3,1.9-0.3V225c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C559.1,224.9,558.6,225,558.1,225z"/>
            +	<path d="M570.5,227.2c-0.1-0.8-0.3-1.5-0.3-2h-3v11.5c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7V237c0.6-0.1,1.2-0.2,1.9-0.3v-11.5h-3
            +		c0,0.5-0.2,1.2-0.3,2h-1.4v-3.6h11.3v3.6H570.5z"/>
            +	<path d="M572.9,238.2V237c0.6-0.1,1.2-0.2,1.9-0.3V225c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H572.9z"/>
            +	<path d="M593.2,238.2l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5V237c0.6-0.1,1.2-0.2,1.9-0.3V225c-0.6,0-1.3-0.2-1.9-0.3
            +		v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2
            +		H593.2z M589.7,225.1c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C593.1,225.8,592,225.1,589.7,225.1z"/>
            +	<path d="M603.5,242.7l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C606.7,235.1,606,238.8,603.5,242.7z"/>
            +	<path d="M615.2,241.5l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C617.8,235.7,618.5,238.4,615.2,241.5z M616.2,232
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C617.6,231.4,617,232,616.2,232z"/>
            +	<path d="M419.6,255.1c-2.5-0.4-3.6,1.3-3.6,4.7v2.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.7-0.1,1.7-0.2,2.5h0c0.5-1.5,1.6-3,3.9-2.7L419.6,255.1z"/>
            +	<path d="M429.9,258.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C430,257.8,430,258.2,429.9,258.7z M425.6,254.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C428,255.6,427.1,254.6,425.6,254.6z"/>
            +	<path d="M436.7,264.2c-2.7,0-4.9-1.2-4.9-5.2c0-3.5,1.8-5.9,5.3-5.9c0.9,0,1.9,0.2,2.6,0.4v3.1h-1.2c-0.1-0.6-0.2-1.2-0.3-1.8
            +		c-0.4-0.1-0.9-0.2-1.4-0.2c-1.9,0-3,1.6-3,4c0,2.2,0.7,3.8,3.2,3.8c0.9,0,1.8-0.2,2.6-0.5l0.3,1.6C439.2,264,438,264.2,436.7,264.2
            +		z"/>
            +	<path d="M445.8,264.2c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C447.3,264.2,446.5,264.2,445.8,264.2z"/>
            +	<path d="M453.3,268.6c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L453.3,268.6z"/>
            +	<path d="M468,264.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H468z"/>
            +	<path d="M477.7,267.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C480.3,261.6,481.1,264.4,477.7,267.4z"/>
            +	<path d="M495.6,254.8l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2
            +		c1.2,0,1.8-0.6,2.6-2.7l0.5-1.2h-0.5l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6
            +		c0.3,1,0.6,1.8,0.8,2.7h0c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.8v1.2C496.6,254.6,496.1,254.7,495.6,254.8z"/>
            +	<path d="M503.2,267.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C505.9,261.6,506.6,264.4,503.2,267.4z"/>
            +	<path d="M527.6,254.8l-2.9,9.3h-2.2l-2.1-6.3c-0.2-0.7-0.4-1.4-0.6-2.1h0c-0.2,1-0.5,1.8-0.8,2.7l-1.8,5.8h-2.2l-2.8-9.3
            +		c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.5,0.1-1,0.2-1.5,0.3l1.3,4.8c0.2,0.9,0.5,1.8,0.7,2.4h0c0.2-0.9,0.5-1.8,0.7-2.6l1.9-6h2
            +		l1.9,6c0.4,1.3,0.6,1.9,0.8,2.6h0c0.2-0.8,0.4-1.4,0.7-2.4l1.4-4.9c-0.5,0-1-0.1-1.5-0.3v-1.2h4.8v1.2
            +		C528.5,254.6,528,254.7,527.6,254.8z"/>
            +	<path d="M529.7,264.1v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H529.7z M532.6,251.2c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C533.8,250.6,533.3,251.2,532.6,251.2z"/>
            +	<path d="M544,264.1c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2C546.7,264.1,545.2,264.1,544,264.1
            +		z M544,255c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6c1.9,0,2.9-2.3,2.9-4.1V255z"/>
            +	<path d="M552.9,264.2c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C554.4,264.2,553.6,264.2,552.9,264.2z"/>
            +	<path d="M564.8,264.1v-6.9c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v5.1c0,0.7,0,1.6-0.2,2.1l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2H564.8z"/>
            +	<path d="M575,267.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C577.6,261.6,578.4,264.4,575,267.4z"/>
            +	<path d="M591.4,264.1v-6.9c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v5.1c0,0.7,0,1.6-0.2,2.1l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2H591.4z"/>
            +	<path d="M605.4,258.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C605.5,257.8,605.4,258.2,605.4,258.7z M601.1,254.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C603.5,255.6,602.6,254.6,601.1,254.6z"/>
            +	<path d="M607.1,264.1v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H607.1z M610,251.2c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C611.2,250.6,610.6,251.2,610,251.2z"/>
            +	<path d="M618.5,269.6c-2.8,0-4.5-1.1-4.5-3.2c0-1.3,0.8-2.3,1.8-2.9c-0.6-0.3-1.1-0.9-1.1-1.6c0-0.8,0.5-1.5,1.2-1.8
            +		c-1-0.6-1.6-1.6-1.6-3c0-2.2,1.6-4,4.6-4c0.6,0,1,0.1,1.5,0.2h3.7v1.5h-1.8c0.5,0.4,0.9,1.1,0.9,2c0,2.2-1.5,3.9-4.5,3.9
            +		c-0.4,0-0.8,0-1.1-0.2c-0.5,0.2-0.7,0.6-0.7,0.9c0,0.6,0.5,0.8,1.8,0.8l2,0.1c2.3,0.1,3.6,1.2,3.6,3.1
            +		C624.2,267.8,621.9,269.6,618.5,269.6z M620,264l-2.1-0.1c-0.2,0-0.5,0-0.6,0c-0.8,0.6-1.4,1.3-1.4,2.1c0,1.3,1.2,2,2.9,2
            +		c2.2,0,3.4-1,3.4-2.3C622.2,264.7,621.5,264.1,620,264z M618.8,254.6c-1.6,0-2.5,1-2.5,2.4c0,1.5,0.9,2.4,2.5,2.4
            +		c1.5,0,2.5-0.9,2.5-2.4C621.2,255.5,620.3,254.6,618.8,254.6z"/>
            +	<path d="M633.8,264.1v-6.9c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v5.1c0,0.7,0,1.6-0.2,2.1l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2H633.8z"/>
            +	<path d="M642.9,264.2c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C644.4,264.2,643.6,264.2,642.9,264.2z"/>
            +	<path d="M652.4,268.6l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C655.6,261,654.9,264.7,652.4,268.6z"/>
            +	<path d="M664.1,267.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C666.7,261.6,667.4,264.4,664.1,267.4z
            +		 M665.1,257.9c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C666.5,257.4,665.9,257.9,665.1,257.9z"/>
            +</g>
            +<text transform="matrix(1 0 0 1 218.5635 179.9517)" font-family="'TheSansMono-W5Regular'" font-size="21.6">(3,2)</text>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="118.7" y1="145.9" x2="298.5" y2="145.9"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="117.5" y1="235.9" x2="297.3" y2="235.9"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="297.4" y1="235.3" x2="297.4" y2="145.2"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="118.6" y1="235.9" x2="118.6" y2="146.4"/>
            +<g>
            +	<path fill="#808080" d="M60.7,429.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4
            +		c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9
            +		c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H60.7z"/>
            +	<path fill="#808080" d="M79.7,429.7l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3
            +		v-1.2h3.3l2.3,3.9l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H79.7z"/>
            +	<path fill="#808080" d="M90.7,429.7c0-0.8,0-1.5,0.1-2.1h0c-0.5,1.3-1.9,2.3-3.7,2.3c-1.8,0-3-1.1-3-2.8c0-2.3,2.4-3.7,6.4-3.7
            +		v-0.8c0-1.5-0.5-2.4-2.2-2.4c-0.6,0-1.4,0.1-2,0.3c0,0.5-0.2,1.1-0.3,1.8h-1.2v-2.9c1.1-0.3,2.4-0.6,3.7-0.6c3.2,0,4,1.4,4,3.6v5.8
            +		c0.5,0.1,1.2,0.2,1.8,0.2v1.2C93.4,429.6,91.9,429.7,90.7,429.7z M90.6,424.7c-3.4,0-4.5,0.8-4.5,2c0,0.9,0.6,1.6,1.6,1.6
            +		c1.7,0,2.9-1.7,2.9-3.4V424.7z"/>
            +	<path fill="#808080" d="M110.7,429.7v-6.9c0-1.5-0.3-2.4-1.7-2.4c-1.5,0-3,1.6-3,4.2v3.7c0.6,0,1.2,0.1,1.8,0.3v1.2H104v-6.9
            +		c0-1.4-0.3-2.4-1.8-2.4c-1.6,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.6-0.1,1.6-0.2,2.3l0,0c0.6-1.5,2-2.5,3.7-2.5c2.3,0,2.9,1.6,3,2.4
            +		c0.4-1,1.6-2.4,3.7-2.4c2,0,3.2,1.1,3.2,3.5v6c0.6,0,1.3,0.2,1.8,0.3v1.2H110.7z"/>
            +	<path fill="#808080" d="M120.6,429.8c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H115v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C126.1,427.6,124.1,429.8,120.6,429.8z M121.7,420.3c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C124.1,421.6,123.3,420.3,121.7,420.3z"/>
            +	<path fill="#808080" d="M127.4,429.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V414c1.1-0.1,2.5-0.2,3.8-0.2
            +		v14.3c0.6,0,1.3,0.2,1.8,0.3v1.2H127.4z"/>
            +	<path fill="#808080" d="M143.2,424.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7
            +		c-3.3,0-5-1.7-5-5.5c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C143.3,423.4,143.2,423.8,143.2,424.3z M138.9,420.2
            +		c-1.4,0-2.4,1-2.6,2.7h5C141.3,421.2,140.4,420.2,138.9,420.2z"/>
            +	<path fill="#808080" d="M147.7,423.5c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C149,422.9,148.4,423.5,147.7,423.5z M147.7,429.9c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C149,429.3,148.4,429.9,147.7,429.9z"/>
            +	<path d="M166.8,420.7c-2.5-0.4-3.6,1.3-3.6,4.7v2.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.7-0.1,1.7-0.2,2.5h0c0.5-1.5,1.6-3,3.9-2.7L166.8,420.7z"/>
            +	<path d="M177.2,424.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C177.3,423.4,177.3,423.8,177.2,424.3z M172.9,420.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C175.3,421.2,174.4,420.2,172.9,420.2z"/>
            +	<path d="M184,429.8c-2.7,0-4.9-1.2-4.9-5.2c0-3.5,1.8-5.9,5.3-5.9c0.9,0,1.9,0.2,2.6,0.4v3.1h-1.2c-0.1-0.6-0.2-1.2-0.3-1.8
            +		c-0.4-0.1-0.9-0.2-1.4-0.2c-1.9,0-3,1.6-3,4c0,2.2,0.7,3.8,3.2,3.8c0.9,0,1.8-0.2,2.6-0.5l0.3,1.6
            +		C186.5,429.6,185.3,429.8,184,429.8z"/>
            +	<path d="M193,429.8c-2.2,0-2.9-0.9-2.9-3.2v-6.2H188v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C194.6,429.7,193.7,429.8,193,429.8z"/>
            +	<path d="M210.8,429.7v-1.2c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10H205
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5v-1.2c0.4-0.1,1-0.2,1.3-0.2
            +		l1.7-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H210.8z"/>
            +	<path d="M221.9,429.9c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C227.1,427.4,225.1,429.9,221.9,429.9z
            +		 M222.1,420.3c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C225.1,421.8,224,420.3,222.1,420.3z"/>
            +	<path d="M236.3,429.7c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2V414c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2C239,429.6,237.5,429.7,236.3,429.7z
            +		 M236.2,420.5c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6c1.9,0,2.9-2.3,2.9-4.1V420.5z"/>
            +	<path d="M250.2,424.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C250.2,423.4,250.2,423.8,250.2,424.3z M245.9,420.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C248.3,421.2,247.4,420.2,245.9,420.2z"/>
            +	<path d="M260.6,434.2c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L260.6,434.2z"/>
            +	<path d="M274.8,429.9c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6h-1.4c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C277.8,429.5,276.3,429.9,274.8,429.9z"/>
            +	<path d="M280.3,429.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H280.3z"/>
            +	<path d="M305.4,416.5v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2h-5.5v-1.2
            +		c0.6-0.1,1.2-0.3,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C306.4,416.4,305.9,416.5,305.4,416.5z"/>
            +	<path d="M317.8,418.7c-0.1-0.8-0.3-1.5-0.3-2h-3v11.5c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.5h-3
            +		c0,0.5-0.2,1.2-0.3,2h-1.4v-3.6h11.3v3.6H317.8z"/>
            +	<path d="M320.2,429.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8H324
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5H324v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H320.2z"/>
            +	<path d="M340.5,429.7l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7
            +		c-0.6,0-1.3-0.2-1.9-0.3v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4
            +		c0.5,0.1,1.1,0.2,1.7,0.3v1.2H340.5z M337,416.6c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6
            +		C340.4,417.3,339.3,416.6,337,416.6z"/>
            +	<path d="M350.8,434.2l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C354,426.6,353.3,430.3,350.8,434.2z"/>
            +	<path d="M362.4,433l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C365.1,427.2,365.8,429.9,362.4,433z M363.5,423.5
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C364.8,422.9,364.2,423.5,363.5,423.5z"/>
            +	<path d="M168.6,446.6c-2.5-0.4-3.6,1.3-3.6,4.7v2.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2V445c1.1-0.1,2.6-0.2,3.8-0.2c0,0.7-0.1,1.7-0.2,2.5h0c0.5-1.5,1.6-3,3.9-2.7L168.6,446.6z"/>
            +	<path d="M179,450.2h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C179,449.3,179,449.7,179,450.2z M174.6,446.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C177.1,447.2,176.2,446.1,174.6,446.1z"/>
            +	<path d="M185.8,455.8c-2.7,0-4.9-1.2-4.9-5.2c0-3.5,1.8-5.9,5.3-5.9c0.9,0,1.9,0.2,2.6,0.4v3.1h-1.2c-0.1-0.6-0.2-1.2-0.3-1.8
            +		c-0.4-0.1-0.9-0.2-1.4-0.2c-1.9,0-3,1.6-3,4c0,2.2,0.7,3.8,3.2,3.8c0.9,0,1.8-0.2,2.6-0.5l0.3,1.6
            +		C188.3,455.5,187.1,455.8,185.8,455.8z"/>
            +	<path d="M194.8,455.8c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C196.3,455.7,195.5,455.8,194.8,455.8z"/>
            +	<path d="M211.2,460.4c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L211.2,460.4z"/>
            +	<path d="M220,457.6c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C226.2,455.5,223.6,457.6,220,457.6z"/>
            +	<path d="M231.2,458.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L231.2,458.4z"/>
            +	<path d="M243,455.6V454l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H243z"/>
            +	<path d="M257.2,458.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L257.2,458.4z"/>
            +	<path d="M276.7,453.7v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H276.7z M274.8,444.4L274.8,444.4l-4.9,7.6
            +		c1.3,0,4,0,4.9,0V444.4z"/>
            +	<path d="M283.1,458.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L283.1,458.4z"/>
            +	<path d="M294.9,455.6V454l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H294.9z"/>
            +	<path d="M310.3,438.6c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L310.3,438.6z"/>
            +	<path d="M326.1,458.9l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C328.7,453.1,329.4,455.9,326.1,458.9z
            +		 M327.1,449.4c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C328.5,448.9,327.9,449.4,327.1,449.4z"/>
            +</g>
            +</svg>
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-09.svg b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-09.svg
            new file mode 100644
            index 0000000000..10dcfb0920
            --- /dev/null
            +++ b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-09.svg
            @@ -0,0 +1,305 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 640 480" enable-background="new 0 0 640 480" xml:space="preserve">
            +<g>
            +	<rect x="75.3" y="99.5" fill="none" stroke="#999999" stroke-width="1.3" width="267.6" height="267.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="75.3" y1="322.6" x2="342.9" y2="322.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="75.3" y1="277.9" x2="342.9" y2="277.9"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="75.3" y1="233.3" x2="342.9" y2="233.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="75.3" y1="188.8" x2="342.9" y2="188.8"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="75.3" y1="144.1" x2="342.9" y2="144.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="298.3" y1="99.5" x2="298.3" y2="367.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="253.8" y1="99.5" x2="253.8" y2="367.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="209.1" y1="99.5" x2="209.1" y2="367.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="164.5" y1="99.5" x2="164.5" y2="367.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="120" y1="99.5" x2="120" y2="367.1"/>
            +</g>
            +<g>
            +	<path d="M80.7,35.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H80.7z"/>
            +</g>
            +<g>
            +	<path d="M14.6,93.4l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2c1.2,0,1.8-0.6,2.6-2.7
            +		l0.5-1.2H8.9l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3V92h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3L9.3,98c0.3,1,0.6,1.8,0.8,2.7h0
            +		c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3V92H16v1.2C15.6,93.3,15.1,93.4,14.6,93.4z"/>
            +</g>
            +<g>
            +	<path d="M79.3,72.1c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C84.9,69.7,82.3,72.1,79.3,72.1z
            +		 M79.4,60.3c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C82.8,61.9,81.5,60.3,79.4,60.3z"/>
            +	<path d="M118.4,71.9v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H118.4z"/>
            +	<path d="M161.1,71.9v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H161.1z"/>
            +	<path d="M207.2,73.9c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C213.4,71.9,210.8,73.9,207.2,73.9z"/>
            +	<path d="M255.2,70.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.6h2.7v9.4h2.5v1.8H255.2z M253.3,60.7L253.3,60.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V60.7z"/>
            +	<path d="M293.5,73.9c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C299.9,71.6,297.3,73.9,293.5,73.9z"/>
            +	<path d="M338.6,72.1c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C343.5,70.1,341.6,72.1,338.6,72.1z M338.7,64.3c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C341.6,65.5,340.6,64.3,338.7,64.3z"/>
            +</g>
            +<circle fill="#808080" cx="120.1" cy="143.9" r="7"/>
            +<circle fill="#808080" cx="298.9" cy="233.9" r="7"/>
            +<g>
            +	<path d="M45.7,109.3c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C51.3,106.9,48.7,109.3,45.7,109.3z
            +		 M45.8,97.5c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C49.2,99.1,47.9,97.5,45.8,97.5z"/>
            +	<path d="M41.6,152.3v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H41.6z"/>
            +	<path d="M41.1,195.5v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H41.1z"/>
            +	<path d="M44,240.7c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C50.2,238.7,47.6,240.7,44,240.7z"/>
            +	<path d="M48.8,280.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H48.8z M46.9,270.7L46.9,270.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V270.7z"/>
            +	<path d="M43.9,327.1c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C50.3,324.8,47.7,327.1,43.9,327.1z"/>
            +	<path d="M45.8,368.5c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C50.7,366.5,48.8,368.5,45.8,368.5z M45.9,360.7c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C48.8,361.9,47.8,360.7,45.9,360.7z"/>
            +</g>
            +<line stroke="#000000" stroke-width="1.3" x1="76.4" y1="99.5" x2="67.9" y2="99.5"/>
            +<line stroke="#000000" stroke-width="1.3" x1="76.4" y1="144.3" x2="67.9" y2="144.3"/>
            +<line stroke="#000000" stroke-width="1.3" x1="76.4" y1="188.7" x2="67.9" y2="188.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="76.4" y1="233.2" x2="67.9" y2="233.2"/>
            +<line stroke="#000000" stroke-width="1.3" x1="76.4" y1="277.9" x2="67.9" y2="277.9"/>
            +<line stroke="#000000" stroke-width="1.3" x1="76.4" y1="323.1" x2="67.9" y2="323.1"/>
            +<line stroke="#000000" stroke-width="1.3" x1="76.4" y1="366.7" x2="67.9" y2="366.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="342.5" y1="99.4" x2="342.5" y2="90.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="297.7" y1="99.4" x2="297.7" y2="90.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="253.3" y1="99.4" x2="253.3" y2="90.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="208.8" y1="99.4" x2="208.8" y2="90.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="164.1" y1="99.4" x2="164.1" y2="90.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="118.9" y1="99.4" x2="118.9" y2="90.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="75.7" y1="99.4" x2="75.7" y2="90.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="15.1,181.2 9.8,186.5 4.5,181.2 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="9.8" y1="186.5" x2="9.8" y2="123.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="157.2,23.3 162.5,28.6 157.2,33.9 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="163.7" y1="28.6" x2="101" y2="28.6"/>
            +<g>
            +	<path d="M420.6,227.1c-2.5-0.4-3.6,1.3-3.6,4.7v2.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7V235c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.7-0.1,1.7-0.2,2.5h0c0.5-1.5,1.6-3,3.9-2.7L420.6,227.1z"/>
            +	<path d="M430.9,230.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C431,229.9,431,230.3,430.9,230.8z M426.6,226.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C429,227.7,428.1,226.7,426.6,226.7z"/>
            +	<path d="M437.7,236.3c-2.7,0-4.9-1.2-4.9-5.2c0-3.5,1.8-5.9,5.3-5.9c0.9,0,1.9,0.2,2.6,0.4v3.1h-1.2c-0.1-0.6-0.2-1.2-0.3-1.8
            +		c-0.4-0.1-0.9-0.2-1.4-0.2c-1.9,0-3,1.6-3,4c0,2.2,0.7,3.8,3.2,3.8c0.9,0,1.8-0.2,2.6-0.5l0.3,1.6C440.2,236,439,236.3,437.7,236.3
            +		z"/>
            +	<path d="M446.8,236.3c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C448.3,236.2,447.4,236.3,446.8,236.3z"/>
            +	<path d="M464.5,236.2V235c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10h-1.8
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5V235c0.4-0.1,1-0.2,1.3-0.2
            +		L453,223c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H464.5z"/>
            +	<path d="M475.6,236.3c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C480.8,233.8,478.8,236.3,475.6,236.3z
            +		 M475.8,226.8c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C478.8,228.3,477.8,226.8,475.8,226.8z"/>
            +	<path d="M490,236.2c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2C492.7,236.1,491.2,236.2,490,236.2
            +		z M489.9,227c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6c1.9,0,2.9-2.3,2.9-4.1V227z"/>
            +	<path d="M503.9,230.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C504,229.9,503.9,230.3,503.9,230.8z M499.6,226.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C502,227.7,501.1,226.7,499.6,226.7z"/>
            +	<path d="M514.3,240.7c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L514.3,240.7z"/>
            +	<path d="M528.5,236.3c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6H531c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C531.5,236,530,236.3,528.5,236.3z"/>
            +	<path d="M540.6,236.4c-4.3,0-6.5-2.9-6.5-7.3c0-4.9,3.1-7.7,6.9-7.7c4.3,0,6.5,2.9,6.5,7.3C547.5,233.6,544.4,236.4,540.6,236.4z
            +		 M540.8,223.1c-2.6,0-4.6,2-4.6,5.6c0,3.5,1.5,5.9,4.6,5.9c2.6,0,4.6-2,4.6-5.6C545.4,225.5,543.9,223.1,540.8,223.1z"/>
            +	<path d="M557.9,236.2l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2H549V235c0.6-0.1,1.2-0.2,1.9-0.3V223c-0.6,0-1.3-0.2-1.9-0.3
            +		v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2
            +		H557.9z M554.4,223.1c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C557.8,223.8,556.7,223.1,554.4,223.1z"/>
            +	<path d="M575.7,223v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2h-5.5V235
            +		c0.6-0.1,1.2-0.3,1.9-0.3V223c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C576.8,222.9,576.3,223,575.7,223z"/>
            +	<path d="M578.8,236.2V235c0.6-0.1,1.2-0.2,1.9-0.3V223c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H578.8z"/>
            +	<path d="M599.1,236.2l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5V235c0.6-0.1,1.2-0.2,1.9-0.3V223c-0.6,0-1.3-0.2-1.9-0.3
            +		v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2
            +		H599.1z M595.6,223.1c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C599.1,223.8,598,223.1,595.6,223.1z"/>
            +	<path d="M607.2,236.3c-1.1,0-2.2-0.1-3.1-0.4v-3.5h1.4c0.1,0.7,0.2,1.4,0.3,1.9c0.5,0.1,1,0.2,1.6,0.2c1.7,0,3.1-0.7,3.1-2.5
            +		c0-3.3-6.7-2-6.7-6.7c0-2.4,1.9-4.1,5.2-4.1c1,0,1.9,0.1,2.8,0.3v3.3h-1.4c-0.1-0.7-0.2-1.4-0.3-1.9c-0.3-0.1-0.8-0.1-1.3-0.1
            +		c-1.9,0-2.9,0.9-2.9,2.3c0,3.2,6.7,2,6.7,6.6C612.6,234.5,610.5,236.3,607.2,236.3z"/>
            +	<path d="M620.4,240.7l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C623.5,233.1,622.8,236.8,620.4,240.7z"/>
            +	<path d="M632,239.5l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C634.6,233.7,635.3,236.4,632,239.5z M633.1,230
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C634.4,229.4,633.8,230,633.1,230z"/>
            +	<path d="M420.6,253.1c-2.5-0.4-3.6,1.3-3.6,4.7v2.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.7-0.1,1.7-0.2,2.5h0c0.5-1.5,1.6-3,3.9-2.7L420.6,253.1z"/>
            +	<path d="M430.9,256.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C431,255.8,431,256.2,430.9,256.7z M426.6,252.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C429,253.6,428.1,252.6,426.6,252.6z"/>
            +	<path d="M437.7,262.2c-2.7,0-4.9-1.2-4.9-5.2c0-3.5,1.8-5.9,5.3-5.9c0.9,0,1.9,0.2,2.6,0.4v3.1h-1.2c-0.1-0.6-0.2-1.2-0.3-1.8
            +		c-0.4-0.1-0.9-0.2-1.4-0.2c-1.9,0-3,1.6-3,4c0,2.2,0.7,3.8,3.2,3.8c0.9,0,1.8-0.2,2.6-0.5l0.3,1.6C440.2,262,439,262.2,437.7,262.2
            +		z"/>
            +	<path d="M446.8,262.2c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C448.3,262.2,447.4,262.2,446.8,262.2z"/>
            +	<path d="M454.3,266.6c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L454.3,266.6z"/>
            +	<path d="M469,262.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H469z"/>
            +	<path d="M474.9,262.1v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H474.9z"/>
            +	<path d="M491.7,265.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C494.3,259.6,495,262.4,491.7,265.4z"/>
            +	<path d="M509.6,252.8l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2
            +		c1.2,0,1.8-0.6,2.6-2.7l0.5-1.2h-0.5l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6
            +		c0.3,1,0.6,1.8,0.8,2.7h0c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.8v1.2C510.5,252.6,510.1,252.7,509.6,252.8z"/>
            +	<path d="M513.3,262.1v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H513.3z"/>
            +	<path d="M530.2,265.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C532.8,259.6,533.5,262.4,530.2,265.4z"/>
            +	<path d="M545.6,262.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H545.6z"/>
            +	<path d="M551,262.1v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H551z"/>
            +	<path d="M568.3,265.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C570.9,259.6,571.6,262.4,568.3,265.4z"/>
            +	<path d="M586.2,252.8l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2
            +		c1.2,0,1.8-0.6,2.6-2.7l0.5-1.2h-0.5l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6
            +		c0.3,1,0.6,1.8,0.8,2.7h0c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.8v1.2C587.1,252.6,586.7,252.7,586.2,252.8z"/>
            +	<path d="M589.5,262.1v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H589.5z"/>
            +	<path d="M607.3,266.6l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C610.5,259,609.8,262.7,607.3,266.6z"/>
            +	<path d="M619,265.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C621.6,259.6,622.3,262.4,619,265.4z M620,255.9
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C621.4,255.4,620.8,255.9,620,255.9z"/>
            +</g>
            +<g>
            +	<path d="M136,139.6c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L136,139.6z"/>
            +	<path d="M142.4,134.8V133h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7V133h3.4v1.8H142.4z"/>
            +	<path d="M156,137.6c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L156,137.6z"/>
            +	<path d="M168.3,134.8V133h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7V133h3.4v1.8H168.3z"/>
            +	<path d="M183.3,117.7c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L183.3,117.7z"/>
            +</g>
            +<g>
            +	<path d="M310,265.6c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L310,265.6z"/>
            +	<path d="M318.7,262.8c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C325,260.5,322.5,262.8,318.7,262.8z"/>
            +	<path d="M330,263.6c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L330,263.6z"/>
            +	<path d="M344.7,262.8c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1V254h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C350.9,260.7,348.3,262.8,344.7,262.8z"/>
            +	<path d="M357.3,243.7c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L357.3,243.7z"/>
            +</g>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="119.7" y1="143.9" x2="299.5" y2="143.9"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="118.5" y1="233.9" x2="298.3" y2="233.9"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="298.4" y1="233.3" x2="298.4" y2="143.2"/>
            +<line fill="none" stroke="#000000" stroke-width="2" x1="119.6" y1="233.9" x2="119.6" y2="144.4"/>
            +<g>
            +	<path fill="#808080" d="M61.7,427.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4
            +		c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9
            +		c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H61.7z"/>
            +	<path fill="#808080" d="M80.7,427.7l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3
            +		v-1.2h3.3l2.3,3.9l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H80.7z"/>
            +	<path fill="#808080" d="M91.7,427.7c0-0.8,0-1.5,0.1-2.1h0c-0.5,1.3-1.9,2.3-3.7,2.3c-1.8,0-3-1.1-3-2.8c0-2.3,2.4-3.7,6.4-3.7
            +		v-0.8c0-1.5-0.5-2.4-2.2-2.4c-0.6,0-1.4,0.1-2,0.3c0,0.5-0.2,1.1-0.3,1.8h-1.2v-2.9c1.1-0.3,2.4-0.6,3.7-0.6c3.2,0,4,1.4,4,3.6v5.8
            +		c0.5,0.1,1.2,0.2,1.8,0.2v1.2C94.4,427.6,92.9,427.7,91.7,427.7z M91.6,422.7c-3.4,0-4.5,0.8-4.5,2c0,0.9,0.6,1.6,1.6,1.6
            +		c1.7,0,2.9-1.7,2.9-3.4V422.7z"/>
            +	<path fill="#808080" d="M111.7,427.7v-6.9c0-1.5-0.3-2.4-1.7-2.4c-1.5,0-3,1.6-3,4.2v3.7c0.6,0,1.2,0.1,1.8,0.3v1.2H105v-6.9
            +		c0-1.4-0.3-2.4-1.8-2.4c-1.6,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.6-0.1,1.6-0.2,2.3l0,0c0.6-1.5,2-2.5,3.7-2.5c2.3,0,2.9,1.6,3,2.4
            +		c0.4-1,1.6-2.4,3.7-2.4c2,0,3.2,1.1,3.2,3.5v6c0.6,0,1.3,0.2,1.8,0.3v1.2H111.7z"/>
            +	<path fill="#808080" d="M121.6,427.8c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H116v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C127.1,425.6,125.1,427.8,121.6,427.8z M122.7,418.3c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C125.1,419.6,124.3,418.3,122.7,418.3z"/>
            +	<path fill="#808080" d="M128.4,427.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V412c1.1-0.1,2.5-0.2,3.8-0.2
            +		v14.3c0.6,0,1.3,0.2,1.8,0.3v1.2H128.4z"/>
            +	<path fill="#808080" d="M144.2,422.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7
            +		c-3.3,0-5-1.7-5-5.5c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C144.3,421.4,144.2,421.8,144.2,422.3z M139.9,418.2
            +		c-1.4,0-2.4,1-2.6,2.7h5C142.3,419.2,141.4,418.2,139.9,418.2z"/>
            +	<path fill="#808080" d="M148.7,421.5c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C150,420.9,149.4,421.5,148.7,421.5z M148.7,427.9c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C150,427.3,149.4,427.9,148.7,427.9z"/>
            +	<path d="M167.8,418.7c-2.5-0.4-3.6,1.3-3.6,4.7v2.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.7-0.1,1.7-0.2,2.5h0c0.5-1.5,1.6-3,3.9-2.7L167.8,418.7z"/>
            +	<path d="M178.2,422.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C178.3,421.4,178.3,421.8,178.2,422.3z M173.9,418.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C176.3,419.2,175.4,418.2,173.9,418.2z"/>
            +	<path d="M185,427.8c-2.7,0-4.9-1.2-4.9-5.2c0-3.5,1.8-5.9,5.3-5.9c0.9,0,1.9,0.2,2.6,0.4v3.1h-1.2c-0.1-0.6-0.2-1.2-0.3-1.8
            +		c-0.4-0.1-0.9-0.2-1.4-0.2c-1.9,0-3,1.6-3,4c0,2.2,0.7,3.8,3.2,3.8c0.9,0,1.8-0.2,2.6-0.5l0.3,1.6
            +		C187.5,427.6,186.3,427.8,185,427.8z"/>
            +	<path d="M194,427.8c-2.2,0-2.9-0.9-2.9-3.2v-6.2H189v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C195.6,427.7,194.7,427.8,194,427.8z"/>
            +	<path d="M211.8,427.7v-1.2c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10H206
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5v-1.2c0.4-0.1,1-0.2,1.3-0.2
            +		l1.7-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H211.8z"/>
            +	<path d="M222.9,427.9c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C228.1,425.4,226.1,427.9,222.9,427.9z
            +		 M223.1,418.3c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C226.1,419.8,225,418.3,223.1,418.3z"/>
            +	<path d="M237.3,427.7c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2V412c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2C240,427.6,238.5,427.7,237.3,427.7z
            +		 M237.2,418.5c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6c1.9,0,2.9-2.3,2.9-4.1V418.5z"/>
            +	<path d="M251.2,422.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C251.2,421.4,251.2,421.8,251.2,422.3z M246.9,418.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C249.3,419.2,248.4,418.2,246.9,418.2z"/>
            +	<path d="M261.6,432.2c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L261.6,432.2z"/>
            +	<path d="M275.8,427.9c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6h-1.4c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C278.8,427.5,277.3,427.9,275.8,427.9z"/>
            +	<path d="M287.9,427.9c-4.3,0-6.5-2.9-6.5-7.3c0-4.9,3.1-7.7,6.9-7.7c4.3,0,6.5,2.9,6.5,7.3C294.8,425.1,291.7,427.9,287.9,427.9z
            +		 M288.1,414.6c-2.6,0-4.6,2-4.6,5.6c0,3.5,1.5,5.9,4.6,5.9c2.6,0,4.6-2,4.6-5.6C292.7,417,291.2,414.6,288.1,414.6z"/>
            +	<path d="M305.2,427.7l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7
            +		c-0.6,0-1.3-0.2-1.9-0.3v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4
            +		c0.5,0.1,1.1,0.2,1.7,0.3v1.2H305.2z M301.7,414.6c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6
            +		C305.1,415.3,304,414.6,301.7,414.6z"/>
            +	<path d="M323,414.5v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2h-5.5v-1.2
            +		c0.6-0.1,1.2-0.3,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C324.1,414.4,323.5,414.5,323,414.5z"/>
            +	<path d="M326.1,427.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H326.1z"/>
            +	<path d="M346.4,427.7l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7
            +		c-0.6,0-1.3-0.2-1.9-0.3v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4
            +		c0.5,0.1,1.1,0.2,1.7,0.3v1.2H346.4z M342.9,414.6c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6
            +		C346.3,415.3,345.2,414.6,342.9,414.6z"/>
            +	<path d="M354.5,427.9c-1.1,0-2.2-0.1-3.1-0.4V424h1.4c0.1,0.7,0.2,1.4,0.3,1.9c0.5,0.1,1,0.2,1.6,0.2c1.7,0,3.1-0.7,3.1-2.5
            +		c0-3.3-6.7-2-6.7-6.7c0-2.4,1.9-4.1,5.2-4.1c1,0,1.9,0.1,2.8,0.3v3.3h-1.4c-0.1-0.7-0.2-1.4-0.3-1.9c-0.3-0.1-0.8-0.1-1.3-0.1
            +		c-1.9,0-2.9,0.9-2.9,2.3c0,3.2,6.7,2,6.7,6.6C359.9,426,357.8,427.9,354.5,427.9z"/>
            +	<path d="M367.6,432.2l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C370.8,424.6,370.1,428.3,367.6,432.2z"/>
            +	<path d="M379.3,431l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C381.9,425.2,382.6,427.9,379.3,431z M380.3,421.5
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C381.7,420.9,381.1,421.5,380.3,421.5z"/>
            +	<path d="M169.6,444.6c-2.5-0.4-3.6,1.3-3.6,4.7v2.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2V443c1.1-0.1,2.6-0.2,3.8-0.2c0,0.7-0.1,1.7-0.2,2.5h0c0.5-1.5,1.6-3,3.9-2.7L169.6,444.6z"/>
            +	<path d="M180,448.2h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C180,447.3,180,447.7,180,448.2z M175.6,444.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C178.1,445.2,177.2,444.1,175.6,444.1z"/>
            +	<path d="M186.8,453.8c-2.7,0-4.9-1.2-4.9-5.2c0-3.5,1.8-5.9,5.3-5.9c0.9,0,1.9,0.2,2.6,0.4v3.1h-1.2c-0.1-0.6-0.2-1.2-0.3-1.8
            +		c-0.4-0.1-0.9-0.2-1.4-0.2c-1.9,0-3,1.6-3,4c0,2.2,0.7,3.8,3.2,3.8c0.9,0,1.8-0.2,2.6-0.5l0.3,1.6
            +		C189.2,453.5,188.1,453.8,186.8,453.8z"/>
            +	<path d="M195.8,453.8c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C197.3,453.7,196.5,453.8,195.8,453.8z"/>
            +	<path d="M212.2,458.4c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L212.2,458.4z"/>
            +	<path d="M218.6,453.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H218.6z"/>
            +	<path d="M232.2,456.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L232.2,456.4z"/>
            +	<path d="M244.5,453.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H244.5z"/>
            +	<path d="M258.2,456.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L258.2,456.4z"/>
            +	<path d="M272.8,455.6c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C279.1,453.3,276.5,455.6,272.8,455.6z"
            +		/>
            +	<path d="M284.1,456.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L284.1,456.4z"/>
            +	<path d="M298.8,455.6c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C304.9,453.5,302.4,455.6,298.8,455.6z"/>
            +	<path d="M311.3,436.6c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L311.3,436.6z"/>
            +	<path d="M335.3,456.9l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C338,451.1,338.7,453.9,335.3,456.9z M336.4,447.4
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C337.7,446.9,337.1,447.4,336.4,447.4z"/>
            +</g>
            +</svg>
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-10.svg b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-10.svg
            new file mode 100644
            index 0000000000..4e7b774ed3
            --- /dev/null
            +++ b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-10.svg
            @@ -0,0 +1,355 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 640 480" enable-background="new 0 0 640 480" xml:space="preserve">
            +<g>
            +	<rect x="85.3" y="96.5" fill="none" stroke="#999999" stroke-width="1.3" width="267.6" height="267.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="85.3" y1="319.6" x2="352.9" y2="319.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="85.3" y1="274.9" x2="352.9" y2="274.9"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="85.3" y1="230.3" x2="352.9" y2="230.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="85.3" y1="185.8" x2="352.9" y2="185.8"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="85.3" y1="141.1" x2="352.9" y2="141.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="308.3" y1="96.5" x2="308.3" y2="364.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="263.8" y1="96.5" x2="263.8" y2="364.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="219.1" y1="96.5" x2="219.1" y2="364.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="174.5" y1="96.5" x2="174.5" y2="364.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="130" y1="96.5" x2="130" y2="364.1"/>
            +</g>
            +<g>
            +	<path d="M90.7,32.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H90.7z"/>
            +</g>
            +<g>
            +	<path d="M24.6,90.4l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2c1.2,0,1.8-0.6,2.6-2.7
            +		l0.5-1.2h-0.5l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3V89h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6c0.3,1,0.6,1.8,0.8,2.7h0
            +		c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3V89H26v1.2C25.6,90.3,25.1,90.4,24.6,90.4z"/>
            +</g>
            +<g>
            +	<path d="M89.3,69.1c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C94.9,66.7,92.3,69.1,89.3,69.1z
            +		 M89.4,57.3c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C92.8,58.9,91.5,57.3,89.4,57.3z"/>
            +	<path d="M128.4,68.9v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H128.4z"/>
            +	<path d="M171.1,68.9v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H171.1z"/>
            +	<path d="M217.2,70.9c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C223.4,68.9,220.8,70.9,217.2,70.9z"/>
            +	<path d="M265.2,67.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.6h2.7v9.4h2.5v1.8H265.2z M263.3,57.7L263.3,57.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V57.7z"/>
            +	<path d="M303.5,70.9c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C309.9,68.6,307.3,70.9,303.5,70.9z"/>
            +	<path d="M348.6,69.1c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C353.5,67.1,351.6,69.1,348.6,69.1z M348.7,61.3c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C351.6,62.5,350.6,61.3,348.7,61.3z"/>
            +</g>
            +<circle fill="#808080" cx="220" cy="232.6" r="7"/>
            +<g>
            +	<path d="M55.7,106.3c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C61.3,103.9,58.7,106.3,55.7,106.3z
            +		 M55.8,94.5c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C59.2,96.1,57.9,94.5,55.8,94.5z"/>
            +	<path d="M51.6,149.3v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H51.6z"/>
            +	<path d="M51.1,192.5v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H51.1z"/>
            +	<path d="M54,237.7c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C60.2,235.7,57.6,237.7,54,237.7z"/>
            +	<path d="M58.8,277.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H58.8z M56.9,267.7L56.9,267.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V267.7z"/>
            +	<path d="M53.9,324.1c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C60.3,321.8,57.7,324.1,53.9,324.1z"/>
            +	<path d="M55.8,365.5c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C60.7,363.5,58.8,365.5,55.8,365.5z M55.9,357.7c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C58.8,358.9,57.8,357.7,55.9,357.7z"/>
            +</g>
            +<line stroke="#000000" stroke-width="1.3" x1="86.4" y1="96.5" x2="77.9" y2="96.5"/>
            +<line stroke="#000000" stroke-width="1.3" x1="86.4" y1="141.3" x2="77.9" y2="141.3"/>
            +<line stroke="#000000" stroke-width="1.3" x1="86.4" y1="185.7" x2="77.9" y2="185.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="86.4" y1="230.2" x2="77.9" y2="230.2"/>
            +<line stroke="#000000" stroke-width="1.3" x1="86.4" y1="274.9" x2="77.9" y2="274.9"/>
            +<line stroke="#000000" stroke-width="1.3" x1="86.4" y1="320.1" x2="77.9" y2="320.1"/>
            +<line stroke="#000000" stroke-width="1.3" x1="86.4" y1="363.7" x2="77.9" y2="363.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="352.5" y1="96.4" x2="352.5" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="307.7" y1="96.4" x2="307.7" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="263.3" y1="96.4" x2="263.3" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="218.8" y1="96.4" x2="218.8" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="174.1" y1="96.4" x2="174.1" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="128.9" y1="96.4" x2="128.9" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="85.7" y1="96.4" x2="85.7" y2="87.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="25.1,178.2 19.8,183.5 14.5,178.2 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="19.8" y1="183.5" x2="19.8" y2="120.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="167.2,20.3 172.5,25.6 167.2,30.9 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="173.7" y1="25.6" x2="111" y2="25.6"/>
            +<g>
            +	<path d="M432.5,227.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C432.5,226.9,432.5,227.3,432.5,227.8z M428.1,223.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C430.6,224.7,429.7,223.7,428.1,223.7z"/>
            +	<path d="M433.9,233.2V232c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H433.9z"/>
            +	<path d="M440.3,233.2V232c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H440.3z"/>
            +	<path d="M446.8,233.2V232c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H446.8z M449.7,220.3c-0.7,0-1.3-0.5-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C451,219.7,450.4,220.3,449.7,220.3z"/>
            +	<path d="M458.6,233.3c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H453v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C464.1,231.1,462.1,233.3,458.6,233.3z M459.7,223.8c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C462.1,225.1,461.4,223.8,459.7,223.8z"/>
            +	<path d="M468.9,233.3c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9h-1.2c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C473.4,231.8,471.7,233.3,468.9,233.3z"/>
            +	<path d="M484.4,227.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C484.5,226.9,484.5,227.3,484.4,227.8z M480.1,223.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C482.5,224.7,481.6,223.7,480.1,223.7z"/>
            +	<path d="M500.3,233.2V232c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10h-1.8
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5V232c0.4-0.1,1-0.2,1.3-0.2
            +		l1.7-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H500.3z"/>
            +	<path d="M511.4,233.3c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C516.6,230.8,514.6,233.3,511.4,233.3z
            +		 M511.6,223.8c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C514.6,225.3,513.6,223.8,511.6,223.8z"/>
            +	<path d="M525.8,233.2c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2C528.5,233.1,527,233.2,525.8,233.2
            +		z M525.8,224c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6c1.9,0,2.9-2.3,2.9-4.1V224z"/>
            +	<path d="M539.7,227.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C539.8,226.9,539.8,227.3,539.7,227.8z M535.4,223.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C537.8,224.7,536.9,223.7,535.4,223.7z"/>
            +	<path d="M550.2,237.7c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L550.2,237.7z"/>
            +	<path d="M564.4,233.3c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6h-1.4c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C567.4,233,565.9,233.3,564.4,233.3z"/>
            +	<path d="M569.8,233.2V232c0.6-0.1,1.2-0.2,1.9-0.3V220c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H569.8z"/>
            +	<path d="M594.9,220v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2h-5.5V232
            +		c0.6-0.1,1.2-0.3,1.9-0.3V220c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C596,219.9,595.4,220,594.9,220z"/>
            +	<path d="M607.4,222.2c-0.1-0.8-0.3-1.5-0.3-2h-3v11.5c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7V232c0.6-0.1,1.2-0.2,1.9-0.3v-11.5h-3
            +		c0,0.5-0.2,1.2-0.3,2h-1.4v-3.6h11.3v3.6H607.4z"/>
            +	<path d="M609.7,233.2V232c0.6-0.1,1.2-0.2,1.9-0.3V220c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4H617c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H609.7z"/>
            +	<path d="M630.1,233.2l-3.9-6.5H625v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5V232c0.6-0.1,1.2-0.2,1.9-0.3V220c-0.6,0-1.3-0.2-1.9-0.3
            +		v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2
            +		H630.1z M626.6,220.1c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C630,220.8,628.9,220.1,626.6,220.1z"/>
            +	<path d="M640.4,237.7L639,237c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C643.5,230.1,642.8,233.8,640.4,237.7z"/>
            +	<path d="M652,236.5l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C654.6,230.7,655.3,233.4,652,236.5z M653.1,227
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C654.4,226.4,653.8,227,653.1,227z"/>
            +	<path d="M432.5,253.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C432.5,252.8,432.5,253.2,432.5,253.7z M428.1,249.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C430.6,250.6,429.7,249.6,428.1,249.6z"/>
            +	<path d="M433.9,259.1v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H433.9z"/>
            +	<path d="M440.3,259.1v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H440.3z"/>
            +	<path d="M446.8,259.1v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H446.8z M449.7,246.2c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C451,245.6,450.4,246.2,449.7,246.2z"/>
            +	<path d="M458.6,259.2c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H453v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C464.1,257,462.1,259.2,458.6,259.2z M459.7,249.7c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C462.1,251.1,461.4,249.7,459.7,249.7z"/>
            +	<path d="M468.9,259.3c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9h-1.2c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C473.4,257.7,471.7,259.3,468.9,259.3z"/>
            +	<path d="M484.4,253.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C484.5,252.8,484.5,253.2,484.4,253.7z M480.1,249.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C482.5,250.6,481.6,249.6,480.1,249.6z"/>
            +	<path d="M494.8,263.6c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L494.8,263.6z"/>
            +	<path d="M509.6,259.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H509.6z"/>
            +	<path d="M519.2,262.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C521.9,256.6,522.6,259.4,519.2,262.4z"/>
            +	<path d="M537.2,249.8l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2
            +		c1.2,0,1.8-0.6,2.6-2.7l0.5-1.2h-0.5l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6
            +		c0.3,1,0.6,1.8,0.8,2.7h0c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.8v1.2C538.1,249.6,537.7,249.7,537.2,249.8z"/>
            +	<path d="M544.8,262.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C547.4,256.6,548.1,259.4,544.8,262.4z"/>
            +	<path d="M569.1,249.8l-2.9,9.3h-2.2l-2.1-6.3c-0.2-0.7-0.4-1.4-0.6-2.1h0c-0.2,1-0.5,1.8-0.8,2.7l-1.8,5.8h-2.2l-2.8-9.3
            +		c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.5,0.1-1,0.2-1.5,0.3l1.3,4.8c0.2,0.9,0.5,1.8,0.7,2.4h0c0.2-0.9,0.5-1.8,0.7-2.6l1.9-6h2
            +		l1.9,6c0.4,1.3,0.6,1.9,0.8,2.6h0c0.2-0.8,0.4-1.4,0.7-2.4l1.4-4.9c-0.5,0-1-0.1-1.5-0.3v-1.2h4.8v1.2
            +		C570.1,249.6,569.6,249.7,569.1,249.8z"/>
            +	<path d="M571.2,259.1v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H571.2z M574.1,246.2c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C575.4,245.6,574.8,246.2,574.1,246.2z"/>
            +	<path d="M585.6,259.1c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2
            +		C588.3,259.1,586.8,259.1,585.6,259.1z M585.5,250c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6
            +		c1.9,0,2.9-2.3,2.9-4.1V250z"/>
            +	<path d="M594.4,259.2c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C596,259.2,595.1,259.2,594.4,259.2z"/>
            +	<path d="M606.3,259.1v-6.9c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v5.1c0,0.7,0,1.6-0.2,2.1l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2H606.3z"/>
            +	<path d="M616.6,262.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C619.2,256.6,619.9,259.4,616.6,262.4z"/>
            +	<path d="M632.9,259.1v-6.9c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v5.1c0,0.7,0,1.6-0.2,2.1l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2H632.9z"/>
            +	<path d="M646.9,253.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C647,252.8,647,253.2,646.9,253.7z M642.6,249.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C645.1,250.6,644.1,249.6,642.6,249.6z"/>
            +	<path d="M648.6,259.1v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H648.6z M651.5,246.2c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C652.8,245.6,652.2,246.2,651.5,246.2z"/>
            +	<path d="M660,264.6c-2.8,0-4.5-1.1-4.5-3.2c0-1.3,0.8-2.3,1.8-2.9c-0.6-0.3-1.1-0.9-1.1-1.6c0-0.8,0.5-1.5,1.2-1.8
            +		c-1-0.6-1.6-1.6-1.6-3c0-2.2,1.6-4,4.6-4c0.6,0,1,0.1,1.5,0.2h3.7v1.5h-1.8c0.5,0.4,0.9,1.1,0.9,2c0,2.2-1.5,3.9-4.5,3.9
            +		c-0.4,0-0.8,0-1.1-0.2c-0.5,0.2-0.7,0.6-0.7,0.9c0,0.6,0.5,0.8,1.8,0.8l2,0.1c2.3,0.1,3.6,1.2,3.6,3.1
            +		C665.7,262.8,663.4,264.6,660,264.6z M661.5,259l-2.1-0.1c-0.2,0-0.5,0-0.6,0c-0.8,0.6-1.4,1.3-1.4,2.1c0,1.3,1.2,2,2.9,2
            +		c2.2,0,3.4-1,3.4-2.3C663.8,259.7,663.1,259.1,661.5,259z M660.3,249.6c-1.6,0-2.5,1-2.5,2.4c0,1.5,0.9,2.4,2.5,2.4
            +		c1.5,0,2.5-0.9,2.5-2.4C662.8,250.5,661.9,249.6,660.3,249.6z"/>
            +	<path d="M675.4,259.1v-6.9c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v5.1c0,0.7,0,1.6-0.2,2.1l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2H675.4z"/>
            +	<path d="M684.4,259.2c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C686,259.2,685.1,259.2,684.4,259.2z"/>
            +	<path d="M694,263.6l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C697.1,256,696.4,259.7,694,263.6z"/>
            +	<path d="M705.6,262.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C708.2,256.6,709,259.4,705.6,262.4z M706.7,252.9
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C708,252.4,707.4,252.9,706.7,252.9z"/>
            +</g>
            +<g>
            +	<path d="M231.2,223c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L231.2,223z"/>
            +	<path d="M240,220.2c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C246.1,218.1,243.6,220.2,240,220.2z"/>
            +	<path d="M251.2,221c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L251.2,221z"/>
            +	<path d="M265.9,220.2c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C272.1,218.1,269.5,220.2,265.9,220.2z"/>
            +	<path d="M278.5,201.1c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L278.5,201.1z"/>
            +</g>
            +<g>
            +	<path fill="#808080" d="M71.7,424.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4
            +		c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9
            +		c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H71.7z"/>
            +	<path fill="#808080" d="M90.7,424.7l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3
            +		v-1.2h3.3l2.3,3.9l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H90.7z"/>
            +	<path fill="#808080" d="M101.7,424.7c0-0.8,0-1.5,0.1-2.1h0c-0.5,1.3-1.9,2.3-3.7,2.3c-1.8,0-3-1.1-3-2.8c0-2.3,2.4-3.7,6.4-3.7
            +		v-0.8c0-1.5-0.5-2.4-2.2-2.4c-0.6,0-1.4,0.1-2,0.3c0,0.5-0.2,1.1-0.3,1.8h-1.2v-2.9c1.1-0.3,2.4-0.6,3.7-0.6c3.2,0,4,1.4,4,3.6v5.8
            +		c0.5,0.1,1.2,0.2,1.8,0.2v1.2C104.4,424.6,102.9,424.7,101.7,424.7z M101.6,419.7c-3.4,0-4.5,0.8-4.5,2c0,0.9,0.6,1.6,1.6,1.6
            +		c1.7,0,2.9-1.7,2.9-3.4V419.7z"/>
            +	<path fill="#808080" d="M121.7,424.7v-6.9c0-1.5-0.3-2.4-1.7-2.4c-1.5,0-3,1.6-3,4.2v3.7c0.6,0,1.2,0.1,1.8,0.3v1.2H115v-6.9
            +		c0-1.4-0.3-2.4-1.8-2.4c-1.6,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.6-0.1,1.6-0.2,2.3l0,0c0.6-1.5,2-2.5,3.7-2.5c2.3,0,2.9,1.6,3,2.4
            +		c0.4-1,1.6-2.4,3.7-2.4c2,0,3.2,1.1,3.2,3.5v6c0.6,0,1.3,0.2,1.8,0.3v1.2H121.7z"/>
            +	<path fill="#808080" d="M131.6,424.8c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H126v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C137.1,422.6,135.1,424.8,131.6,424.8z M132.7,415.3c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C135.1,416.6,134.3,415.3,132.7,415.3z"/>
            +	<path fill="#808080" d="M138.4,424.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V409c1.1-0.1,2.5-0.2,3.8-0.2
            +		v14.3c0.6,0,1.3,0.2,1.8,0.3v1.2H138.4z"/>
            +	<path fill="#808080" d="M154.2,419.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7
            +		c-3.3,0-5-1.7-5-5.5c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C154.3,418.4,154.2,418.8,154.2,419.3z M149.9,415.2
            +		c-1.4,0-2.4,1-2.6,2.7h5C152.3,416.2,151.4,415.2,149.9,415.2z"/>
            +	<path fill="#808080" d="M158.7,418.5c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C160,417.9,159.4,418.5,158.7,418.5z M158.7,424.9c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C160,424.3,159.4,424.9,158.7,424.9z"/>
            +	<path d="M179.7,419.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C179.8,418.4,179.8,418.8,179.7,419.3z M175.4,415.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C177.9,416.2,176.9,415.2,175.4,415.2z"/>
            +	<path d="M181.2,424.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V409c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H181.2z"/>
            +	<path d="M187.5,424.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V409c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H187.5z"/>
            +	<path d="M194.1,424.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H194.1z M197,411.8c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C198.3,411.2,197.7,411.8,197,411.8z"/>
            +	<path d="M205.9,424.8c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.6v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C211.4,422.6,209.4,424.8,205.9,424.8z M207,415.3c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C209.4,416.6,208.6,415.3,207,415.3z"/>
            +	<path d="M216.1,424.9c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9H219c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C220.7,423.3,219,424.9,216.1,424.9z"/>
            +	<path d="M231.7,419.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C231.8,418.4,231.7,418.8,231.7,419.3z M227.4,415.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C229.8,416.2,228.9,415.2,227.4,415.2z"/>
            +	<path d="M247.6,424.7v-1.2c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10h-1.8
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5v-1.2c0.4-0.1,1-0.2,1.3-0.2
            +		l1.7-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H247.6z"/>
            +	<path d="M258.7,424.9c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C263.9,422.4,261.9,424.9,258.7,424.9z
            +		 M258.9,415.3c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C261.9,416.8,260.9,415.3,258.9,415.3z"/>
            +	<path d="M273.1,424.7c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2V409c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2
            +		C275.8,424.6,274.3,424.7,273.1,424.7z M273.1,415.5c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6
            +		c1.9,0,2.9-2.3,2.9-4.1V415.5z"/>
            +	<path d="M287,419.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C287.1,418.4,287.1,418.8,287,419.3z M282.7,415.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C285.1,416.2,284.2,415.2,282.7,415.2z"/>
            +	<path d="M297.4,429.2c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L297.4,429.2z"/>
            +	<path d="M311.7,424.9c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6h-1.4c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C314.6,424.5,313.1,424.9,311.7,424.9z"/>
            +	<path d="M317.1,424.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8H321
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5H321v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H317.1z"/>
            +	<path d="M342.2,411.5v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2h-5.5v-1.2
            +		c0.6-0.1,1.2-0.3,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C343.2,411.4,342.7,411.5,342.2,411.5z"/>
            +	<path d="M354.6,413.7c-0.1-0.8-0.3-1.5-0.3-2h-3v11.5c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.5h-3
            +		c0,0.5-0.2,1.2-0.3,2h-1.4v-3.6H356v3.6H354.6z"/>
            +	<path d="M357,424.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4H365c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H357z"/>
            +	<path d="M377.3,424.7l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7
            +		c-0.6,0-1.3-0.2-1.9-0.3v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4
            +		c0.5,0.1,1.1,0.2,1.7,0.3v1.2H377.3z M373.8,411.6c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6
            +		C377.3,412.3,376.2,411.6,373.8,411.6z"/>
            +	<path d="M387.6,429.2l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C390.8,421.6,390.1,425.3,387.6,429.2z"/>
            +	<path d="M399.3,428l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C401.9,422.2,402.6,424.9,399.3,428z M400.3,418.5
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C401.7,417.9,401.1,418.5,400.3,418.5z"/>
            +	<path d="M181.5,445.2h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C181.6,444.3,181.5,444.7,181.5,445.2z M177.2,441.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C179.6,442.2,178.7,441.1,177.2,441.1z"/>
            +	<path d="M182.9,450.6v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V435c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H182.9z"/>
            +	<path d="M189.3,450.6v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V435c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H189.3z"/>
            +	<path d="M195.9,450.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2V440c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H195.9z M198.8,437.7c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C200,437.1,199.4,437.7,198.8,437.7z"/>
            +	<path d="M207.7,450.7c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.6v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2V440c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C213.2,448.5,211.1,450.7,207.7,450.7z M208.8,441.2c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C211.1,442.6,210.4,441.2,208.8,441.2z"/>
            +	<path d="M217.9,450.8c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9h-1.2c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C222.5,449.2,220.7,450.8,217.9,450.8z"/>
            +	<path d="M233.4,445.2h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C233.5,444.3,233.5,444.7,233.4,445.2z M229.1,441.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C231.6,442.2,230.6,441.1,229.1,441.1z"/>
            +	<path d="M248,455.4c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L248,455.4z"/>
            +	<path d="M256.9,452.6c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C263,450.5,260.5,452.6,256.9,452.6z"/>
            +	<path d="M268.1,453.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L268.1,453.4z"/>
            +	<path d="M282.8,452.6c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C288.9,450.5,286.4,452.6,282.8,452.6z"/>
            +	<path d="M294,453.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L294,453.4z"/>
            +	<path d="M313.5,448.7v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H313.5z M311.6,439.4L311.6,439.4l-4.9,7.6
            +		c1.3,0,4,0,4.9,0V439.4z"/>
            +	<path d="M319.9,453.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L319.9,453.4z"/>
            +	<path d="M336.4,450.8c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C341.3,448.7,339.3,450.8,336.4,450.8z M336.5,443c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C339.3,444.2,338.4,443,336.5,443z"/>
            +	<path d="M347.1,433.6c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L347.1,433.6z"/>
            +	<path d="M362.9,453.9l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C365.5,448.1,366.3,450.9,362.9,453.9z M364,444.4
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C365.3,443.9,364.7,444.4,364,444.4z"/>
            +</g>
            +<ellipse fill="none" stroke="#000000" stroke-width="2" cx="219.1" cy="230.3" rx="89.2" ry="133.8"/>
            +</svg>
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-11.svg b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-11.svg
            new file mode 100644
            index 0000000000..f451fe0a4f
            --- /dev/null
            +++ b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-11.svg
            @@ -0,0 +1,345 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 640 480" enable-background="new 0 0 640 480" xml:space="preserve">
            +<g>
            +	<rect x="66.3" y="112.5" fill="none" stroke="#999999" stroke-width="1.3" width="267.6" height="267.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="66.3" y1="335.6" x2="333.9" y2="335.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="66.3" y1="290.9" x2="333.9" y2="290.9"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="66.3" y1="246.3" x2="333.9" y2="246.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="66.3" y1="201.8" x2="333.9" y2="201.8"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="66.3" y1="157.1" x2="333.9" y2="157.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="289.3" y1="112.5" x2="289.3" y2="380.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="244.8" y1="112.5" x2="244.8" y2="380.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="200.1" y1="112.5" x2="200.1" y2="380.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="155.5" y1="112.5" x2="155.5" y2="380.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="111" y1="112.5" x2="111" y2="380.1"/>
            +</g>
            +<g>
            +	<path d="M71.7,48.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H71.7z"/>
            +</g>
            +<g>
            +	<path d="M5.6,106.4l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2c1.2,0,1.8-0.6,2.6-2.7
            +		l0.5-1.2h-0.5l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3V105h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6c0.3,1,0.6,1.8,0.8,2.7h0
            +		c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3V105H7v1.2C6.6,106.3,6.1,106.4,5.6,106.4z"/>
            +</g>
            +<g>
            +	<path d="M70.3,85.1c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C75.9,82.7,73.3,85.1,70.3,85.1z
            +		 M70.4,73.3c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C73.8,74.9,72.5,73.3,70.4,73.3z"/>
            +	<path d="M109.4,84.9v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H109.4z"/>
            +	<path d="M152.1,84.9v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H152.1z"/>
            +	<path d="M198.2,86.9c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C204.4,84.9,201.8,86.9,198.2,86.9z"/>
            +	<path d="M246.2,83.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H246.2z M244.3,73.7L244.3,73.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V73.7z"/>
            +	<path d="M284.5,86.9c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C290.9,84.6,288.3,86.9,284.5,86.9z"/>
            +	<path d="M329.6,85.1c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C334.5,83.1,332.6,85.1,329.6,85.1z M329.7,77.3c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C332.6,78.5,331.6,77.3,329.7,77.3z"/>
            +</g>
            +<circle fill="#808080" cx="111" cy="158.6" r="7"/>
            +<g>
            +	<path d="M36.7,122.3c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C42.3,119.9,39.7,122.3,36.7,122.3z
            +		 M36.8,110.5c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C40.2,112.1,38.9,110.5,36.8,110.5z"/>
            +	<path d="M32.6,165.3v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H32.6z"/>
            +	<path d="M32.1,208.5v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H32.1z"/>
            +	<path d="M35,253.7c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C41.2,251.7,38.6,253.7,35,253.7z"/>
            +	<path d="M39.8,293.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H39.8z M37.9,283.7L37.9,283.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V283.7z"/>
            +	<path d="M34.9,340.1c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C41.3,337.8,38.7,340.1,34.9,340.1z"/>
            +	<path d="M36.8,381.5c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C41.7,379.5,39.8,381.5,36.8,381.5z M36.9,373.7c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C39.8,374.9,38.8,373.7,36.9,373.7z"/>
            +</g>
            +<line stroke="#000000" stroke-width="1.3" x1="67.4" y1="112.5" x2="58.9" y2="112.5"/>
            +<line stroke="#000000" stroke-width="1.3" x1="67.4" y1="157.3" x2="58.9" y2="157.3"/>
            +<line stroke="#000000" stroke-width="1.3" x1="67.4" y1="201.7" x2="58.9" y2="201.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="67.4" y1="246.2" x2="58.9" y2="246.2"/>
            +<line stroke="#000000" stroke-width="1.3" x1="67.4" y1="290.9" x2="58.9" y2="290.9"/>
            +<line stroke="#000000" stroke-width="1.3" x1="67.4" y1="336.1" x2="58.9" y2="336.1"/>
            +<line stroke="#000000" stroke-width="1.3" x1="67.4" y1="379.7" x2="58.9" y2="379.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="333.5" y1="112.4" x2="333.5" y2="103.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="288.7" y1="112.4" x2="288.7" y2="103.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="244.3" y1="112.4" x2="244.3" y2="103.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="199.8" y1="112.4" x2="199.8" y2="103.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="155.1" y1="112.4" x2="155.1" y2="103.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="109.9" y1="112.4" x2="109.9" y2="103.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="66.7" y1="112.4" x2="66.7" y2="103.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="6.1,194.2 0.8,199.5 -4.5,194.2 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="0.8" y1="199.5" x2="0.8" y2="136.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="148.2,36.3 153.5,41.6 148.2,46.9 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="154.7" y1="41.6" x2="92" y2="41.6"/>
            +<g>
            +	<path d="M413.5,243.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C413.5,242.9,413.5,243.3,413.5,243.8z M409.1,239.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C411.6,240.7,410.7,239.7,409.1,239.7z"/>
            +	<path d="M414.9,249.2V248c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H414.9z"/>
            +	<path d="M421.3,249.2V248c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H421.3z"/>
            +	<path d="M427.8,249.2V248c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H427.8z M430.7,236.3c-0.7,0-1.3-0.5-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C432,235.7,431.4,236.3,430.7,236.3z"/>
            +	<path d="M439.6,249.3c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H434v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C445.1,247.1,443.1,249.3,439.6,249.3z M440.7,239.8c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C443.1,241.1,442.4,239.8,440.7,239.8z"/>
            +	<path d="M449.9,249.3c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9h-1.2c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C454.4,247.8,452.7,249.3,449.9,249.3z"/>
            +	<path d="M465.4,243.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C465.5,242.9,465.5,243.3,465.4,243.8z M461.1,239.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C463.5,240.7,462.6,239.7,461.1,239.7z"/>
            +	<path d="M481.3,249.2V248c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10h-1.8
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5V248c0.4-0.1,1-0.2,1.3-0.2
            +		l1.7-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H481.3z"/>
            +	<path d="M492.4,249.3c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C497.6,246.8,495.6,249.3,492.4,249.3z
            +		 M492.6,239.8c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C495.6,241.3,494.6,239.8,492.6,239.8z"/>
            +	<path d="M506.8,249.2c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2C509.5,249.1,508,249.2,506.8,249.2
            +		z M506.8,240c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6c1.9,0,2.9-2.3,2.9-4.1V240z"/>
            +	<path d="M520.7,243.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C520.8,242.9,520.8,243.3,520.7,243.8z M516.4,239.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C518.8,240.7,517.9,239.7,516.4,239.7z"/>
            +	<path d="M531.2,253.7c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L531.2,253.7z"/>
            +	<path d="M545.4,249.3c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6h-1.4c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C548.4,249,546.9,249.3,545.4,249.3z"/>
            +	<path d="M557.4,249.4c-4.3,0-6.5-2.9-6.5-7.3c0-4.9,3.1-7.7,6.9-7.7c4.3,0,6.5,2.9,6.5,7.3C564.4,246.6,561.2,249.4,557.4,249.4z
            +		 M557.7,236.1c-2.6,0-4.6,2-4.6,5.6c0,3.5,1.5,5.9,4.6,5.9c2.6,0,4.6-2,4.6-5.6C562.3,238.5,560.7,236.1,557.7,236.1z"/>
            +	<path d="M574.7,249.2l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5V248c0.6-0.1,1.2-0.2,1.9-0.3V236c-0.6,0-1.3-0.2-1.9-0.3
            +		v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2
            +		H574.7z M571.2,236.1c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C574.6,236.7,573.5,236.1,571.2,236.1z"/>
            +	<path d="M592.6,236v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2H579V248
            +		c0.6-0.1,1.2-0.3,1.9-0.3V236c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C593.6,235.9,593.1,236,592.6,236z"/>
            +	<path d="M595.7,249.2V248c0.6-0.1,1.2-0.2,1.9-0.3V236c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H595.7z"/>
            +	<path d="M616,249.2l-3.9-6.5H611v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5V248c0.6-0.1,1.2-0.2,1.9-0.3V236c-0.6,0-1.3-0.2-1.9-0.3v-1.2
            +		h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2H616z
            +		 M612.5,236.1c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C615.9,236.7,614.8,236.1,612.5,236.1z"/>
            +	<path d="M626.3,253.7l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C629.5,246.1,628.7,249.8,626.3,253.7z"/>
            +	<path d="M637.9,252.5l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C640.6,246.7,641.3,249.4,637.9,252.5z M639,243
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C640.3,242.4,639.7,243,639,243z"/>
            +	<path d="M413.5,269.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C413.5,268.8,413.5,269.2,413.5,269.7z M409.1,265.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C411.6,266.6,410.7,265.6,409.1,265.6z"/>
            +	<path d="M414.9,275.1v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H414.9z"/>
            +	<path d="M421.3,275.1v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H421.3z"/>
            +	<path d="M427.8,275.1v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H427.8z M430.7,262.2c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C432,261.6,431.4,262.2,430.7,262.2z"/>
            +	<path d="M439.6,275.2c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H434v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C445.1,273,443.1,275.2,439.6,275.2z M440.7,265.7c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C443.1,267.1,442.4,265.7,440.7,265.7z"/>
            +	<path d="M449.9,275.3c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9h-1.2c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C454.4,273.7,452.7,275.3,449.9,275.3z"/>
            +	<path d="M465.4,269.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C465.5,268.8,465.5,269.2,465.4,269.7z M461.1,265.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C463.5,266.6,462.6,265.6,461.1,265.6z"/>
            +	<path d="M475.8,279.6c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L475.8,279.6z"/>
            +	<path d="M490.6,275.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H490.6z"/>
            +	<path d="M500.2,278.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C502.9,272.6,503.6,275.4,500.2,278.4z"/>
            +	<path d="M518.2,265.8l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2
            +		c1.2,0,1.8-0.6,2.6-2.7l0.5-1.2h-0.5l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6
            +		c0.3,1,0.6,1.8,0.8,2.7h0c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.8v1.2C519.1,265.6,518.7,265.7,518.2,265.8z"/>
            +	<path d="M525.8,278.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C528.4,272.6,529.1,275.4,525.8,278.4z"/>
            +	<path d="M550.1,265.8l-2.9,9.3h-2.2l-2.1-6.3c-0.2-0.7-0.4-1.4-0.6-2.1h0c-0.2,1-0.5,1.8-0.8,2.7l-1.8,5.8h-2.2l-2.8-9.3
            +		c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.5,0.1-1,0.2-1.5,0.3l1.3,4.8c0.2,0.9,0.5,1.8,0.7,2.4h0c0.2-0.9,0.5-1.8,0.7-2.6l1.9-6h2
            +		l1.9,6c0.4,1.3,0.6,1.9,0.8,2.6h0c0.2-0.8,0.4-1.4,0.7-2.4l1.4-4.9c-0.5,0-1-0.1-1.5-0.3v-1.2h4.8v1.2
            +		C551.1,265.6,550.6,265.7,550.1,265.8z"/>
            +	<path d="M552.2,275.1v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H552.2z M555.1,262.2c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C556.4,261.6,555.8,262.2,555.1,262.2z"/>
            +	<path d="M566.6,275.1c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2C569.3,275,567.8,275.1,566.6,275.1
            +		z M566.5,266c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6c1.9,0,2.9-2.3,2.9-4.1V266z"/>
            +	<path d="M575.4,275.2c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C577,275.2,576.1,275.2,575.4,275.2z"/>
            +	<path d="M587.3,275.1v-6.9c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v5.1c0,0.7,0,1.6-0.2,2.1l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2H587.3z"/>
            +	<path d="M597.6,278.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C600.2,272.6,600.9,275.4,597.6,278.4z"/>
            +	<path d="M613.9,275.1v-6.9c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v5.1c0,0.7,0,1.6-0.2,2.1l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2H613.9z"/>
            +	<path d="M627.9,269.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C628,268.8,628,269.2,627.9,269.7z M623.6,265.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C626.1,266.6,625.1,265.6,623.6,265.6z"/>
            +	<path d="M629.6,275.1v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H629.6z M632.5,262.2c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C633.8,261.6,633.2,262.2,632.5,262.2z"/>
            +	<path d="M641,280.6c-2.8,0-4.5-1.1-4.5-3.2c0-1.3,0.8-2.3,1.8-2.9c-0.6-0.3-1.1-0.9-1.1-1.6c0-0.8,0.5-1.5,1.2-1.8
            +		c-1-0.6-1.6-1.6-1.6-3c0-2.2,1.6-4,4.6-4c0.6,0,1,0.1,1.5,0.2h3.7v1.5h-1.8c0.5,0.4,0.9,1.1,0.9,2c0,2.2-1.5,3.9-4.5,3.9
            +		c-0.4,0-0.8,0-1.1-0.2c-0.5,0.2-0.7,0.6-0.7,0.9c0,0.6,0.5,0.8,1.8,0.8l2,0.1c2.3,0.1,3.6,1.2,3.6,3.1
            +		C646.7,278.8,644.4,280.6,641,280.6z M642.5,275l-2.1-0.1c-0.2,0-0.5,0-0.6,0c-0.8,0.6-1.4,1.3-1.4,2.1c0,1.3,1.2,2,2.9,2
            +		c2.2,0,3.4-1,3.4-2.3C644.8,275.7,644.1,275.1,642.5,275z M641.3,265.6c-1.6,0-2.5,1-2.5,2.4c0,1.5,0.9,2.4,2.5,2.4
            +		c1.5,0,2.5-0.9,2.5-2.4C643.8,266.5,642.9,265.6,641.3,265.6z"/>
            +	<path d="M656.4,275.1v-6.9c0-1.5-0.4-2.4-1.8-2.4c-1.8,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.5v-1.2
            +		c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v5.1c0,0.7,0,1.6-0.2,2.1l0,0
            +		c0.6-1.5,1.9-2.4,3.8-2.4c2.4,0,3.2,1.5,3.2,3.4v6c0.6,0,1.3,0.2,1.8,0.3v1.2H656.4z"/>
            +	<path d="M665.4,275.2c-2.2,0-2.9-0.9-2.9-3.2v-6.2h-2.2v-1.5h2.2v-3.5l1.9-0.5v4h3v1.5h-3v5.5c0,1.8,0.3,2.2,1.5,2.2
            +		c0.5,0,1-0.1,1.4-0.2l0.2,1.6C667,275.2,666.1,275.2,665.4,275.2z"/>
            +	<path d="M675,279.6l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C678.1,272,677.4,275.7,675,279.6z"/>
            +	<path d="M686.6,278.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C689.2,272.6,690,275.4,686.6,278.4z M687.7,268.9
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C689,268.4,688.4,268.9,687.7,268.9z"/>
            +</g>
            +<g>
            +	<path d="M124.6,151.4c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L124.6,151.4z"/>
            +	<path d="M131,146.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H131z"/>
            +	<path d="M144.6,149.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L144.6,149.4z"/>
            +	<path d="M156.9,146.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H156.9z"/>
            +	<path d="M171.9,129.5c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L171.9,129.5z"/>
            +</g>
            +<g>
            +	<path fill="#808080" d="M52.7,440.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4
            +		c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9
            +		c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H52.7z"/>
            +	<path fill="#808080" d="M71.7,440.7l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3
            +		v-1.2h3.3l2.3,3.9l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H71.7z"/>
            +	<path fill="#808080" d="M82.7,440.7c0-0.8,0-1.5,0.1-2.1h0c-0.5,1.3-1.9,2.3-3.7,2.3c-1.8,0-3-1.1-3-2.8c0-2.3,2.4-3.7,6.4-3.7
            +		v-0.8c0-1.5-0.5-2.4-2.2-2.4c-0.6,0-1.4,0.1-2,0.3c0,0.5-0.2,1.1-0.3,1.8h-1.2v-2.9c1.1-0.3,2.4-0.6,3.7-0.6c3.2,0,4,1.4,4,3.6v5.8
            +		c0.5,0.1,1.2,0.2,1.8,0.2v1.2C85.4,440.6,83.9,440.7,82.7,440.7z M82.6,435.7c-3.4,0-4.5,0.8-4.5,2c0,0.9,0.6,1.6,1.6,1.6
            +		c1.7,0,2.9-1.7,2.9-3.4V435.7z"/>
            +	<path fill="#808080" d="M102.7,440.7v-6.9c0-1.5-0.3-2.4-1.7-2.4c-1.5,0-3,1.6-3,4.2v3.7c0.6,0,1.2,0.1,1.8,0.3v1.2H96v-6.9
            +		c0-1.4-0.3-2.4-1.8-2.4c-1.6,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.6-0.1,1.6-0.2,2.3l0,0c0.6-1.5,2-2.5,3.7-2.5c2.3,0,2.9,1.6,3,2.4
            +		c0.4-1,1.6-2.4,3.7-2.4c2,0,3.2,1.1,3.2,3.5v6c0.6,0,1.3,0.2,1.8,0.3v1.2H102.7z"/>
            +	<path fill="#808080" d="M112.6,440.8c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H107v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C118.1,438.6,116.1,440.8,112.6,440.8z M113.7,431.3c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C116.1,432.6,115.3,431.3,113.7,431.3z"/>
            +	<path fill="#808080" d="M119.4,440.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V425c1.1-0.1,2.5-0.2,3.8-0.2
            +		v14.3c0.6,0,1.3,0.2,1.8,0.3v1.2H119.4z"/>
            +	<path fill="#808080" d="M135.2,435.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7
            +		c-3.3,0-5-1.7-5-5.5c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C135.3,434.4,135.2,434.8,135.2,435.3z M130.9,431.2
            +		c-1.4,0-2.4,1-2.6,2.7h5C133.3,432.2,132.4,431.2,130.9,431.2z"/>
            +	<path fill="#808080" d="M139.7,434.5c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C141,433.9,140.4,434.5,139.7,434.5z M139.7,440.9c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C141,440.3,140.4,440.9,139.7,440.9z"/>
            +	<path d="M160.7,435.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C160.8,434.4,160.8,434.8,160.7,435.3z M156.4,431.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C158.9,432.2,157.9,431.2,156.4,431.2z"/>
            +	<path d="M162.2,440.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V425c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H162.2z"/>
            +	<path d="M168.5,440.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V425c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H168.5z"/>
            +	<path d="M175.1,440.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H175.1z M178,427.8c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C179.3,427.2,178.7,427.8,178,427.8z"/>
            +	<path d="M186.9,440.8c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.6v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C192.4,438.6,190.4,440.8,186.9,440.8z M188,431.3c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C190.4,432.6,189.6,431.3,188,431.3z"/>
            +	<path d="M197.1,440.9c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9H200c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C201.7,439.3,200,440.9,197.1,440.9z"/>
            +	<path d="M212.7,435.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C212.8,434.4,212.7,434.8,212.7,435.3z M208.4,431.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C210.8,432.2,209.9,431.2,208.4,431.2z"/>
            +	<path d="M228.6,440.7v-1.2c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10h-1.8
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5v-1.2c0.4-0.1,1-0.2,1.3-0.2
            +		l1.7-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H228.6z"/>
            +	<path d="M239.7,440.9c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C244.9,438.4,242.9,440.9,239.7,440.9z
            +		 M239.9,431.3c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C242.9,432.8,241.9,431.3,239.9,431.3z"/>
            +	<path d="M254.1,440.7c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2V425c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2
            +		C256.8,440.6,255.3,440.7,254.1,440.7z M254.1,431.5c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6
            +		c1.9,0,2.9-2.3,2.9-4.1V431.5z"/>
            +	<path d="M268,435.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C268.1,434.4,268.1,434.8,268,435.3z M263.7,431.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C266.1,432.2,265.2,431.2,263.7,431.2z"/>
            +	<path d="M278.4,445.2c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L278.4,445.2z"/>
            +	<path d="M292.7,440.9c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6h-1.4c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C295.6,440.5,294.1,440.9,292.7,440.9z"/>
            +	<path d="M304.7,440.9c-4.3,0-6.5-2.9-6.5-7.3c0-4.9,3.1-7.7,6.9-7.7c4.3,0,6.5,2.9,6.5,7.3C311.6,438.1,308.5,440.9,304.7,440.9z
            +		 M304.9,427.6c-2.6,0-4.6,2-4.6,5.6c0,3.5,1.5,5.9,4.6,5.9c2.6,0,4.6-2,4.6-5.6C309.5,430,308,427.6,304.9,427.6z"/>
            +	<path d="M322,440.7l-3.9-6.5H317v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3
            +		v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2
            +		H322z M318.5,427.6c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C321.9,428.3,320.8,427.6,318.5,427.6z"/>
            +	<path d="M339.9,427.5v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2h-5.5v-1.2
            +		c0.6-0.1,1.2-0.3,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C340.9,427.4,340.4,427.5,339.9,427.5z"/>
            +	<path d="M342.9,440.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4H351c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H342.9z"/>
            +	<path d="M363.3,440.7l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7
            +		c-0.6,0-1.3-0.2-1.9-0.3v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4
            +		c0.5,0.1,1.1,0.2,1.7,0.3v1.2H363.3z M359.8,427.6c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6
            +		C363.2,428.3,362.1,427.6,359.8,427.6z"/>
            +	<path d="M373.6,445.2l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C376.7,437.6,376,441.3,373.6,445.2z"/>
            +	<path d="M385.2,444l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C387.8,438.2,388.6,440.9,385.2,444z M386.3,434.5
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C387.6,433.9,387,434.5,386.3,434.5z"/>
            +	<path d="M162.5,461.2h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C162.6,460.3,162.5,460.7,162.5,461.2z M158.2,457.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C160.6,458.2,159.7,457.1,158.2,457.1z"/>
            +	<path d="M163.9,466.6v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V451c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H163.9z"/>
            +	<path d="M170.3,466.6v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V451c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H170.3z"/>
            +	<path d="M176.9,466.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2V456c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H176.9z M179.8,453.7c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C181,453.1,180.4,453.7,179.8,453.7z"/>
            +	<path d="M188.7,466.7c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.6v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2V456c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C194.2,464.5,192.1,466.7,188.7,466.7z M189.8,457.2c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C192.1,458.6,191.4,457.2,189.8,457.2z"/>
            +	<path d="M198.9,466.8c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9h-1.2c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C203.5,465.2,201.7,466.8,198.9,466.8z"/>
            +	<path d="M214.4,461.2h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C214.5,460.3,214.5,460.7,214.4,461.2z M210.1,457.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C212.6,458.2,211.6,457.1,210.1,457.1z"/>
            +	<path d="M229,471.4c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L229,471.4z"/>
            +	<path d="M235.4,466.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H235.4z"/>
            +	<path d="M249.1,469.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L249.1,469.4z"/>
            +	<path d="M261.3,466.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H261.3z"/>
            +	<path d="M275,469.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L275,469.4z"/>
            +	<path d="M289.7,468.6c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C295.8,466.5,293.3,468.6,289.7,468.6z"/>
            +	<path d="M300.9,469.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L300.9,469.4z"/>
            +	<path d="M315.5,468.6c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C321.8,466.3,319.3,468.6,315.5,468.6z"
            +		/>
            +	<path d="M328.1,449.6c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L328.1,449.6z"/>
            +	<path d="M343.9,469.9l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C346.5,464.1,347.3,466.9,343.9,469.9z M345,460.4
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C346.3,459.9,345.7,460.4,345,460.4z"/>
            +</g>
            +<ellipse fill="none" stroke="#000000" stroke-width="2" cx="177.9" cy="268.6" rx="66.9" ry="111.5"/>
            +</svg>
            diff --git a/dist/assets/learn/coordinate-system-and-shapes/images/drawing-12.svg b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-12.svg
            new file mode 100644
            index 0000000000..175276f7a3
            --- /dev/null
            +++ b/dist/assets/learn/coordinate-system-and-shapes/images/drawing-12.svg
            @@ -0,0 +1,337 @@
            +<?xml version="1.0" encoding="utf-8"?>
            +<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
            +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
            +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            +	 viewBox="0 0 640 480" enable-background="new 0 0 640 480" xml:space="preserve">
            +<g>
            +	<rect x="69.3" y="96.5" fill="none" stroke="#999999" stroke-width="1.3" width="267.6" height="267.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="69.3" y1="319.6" x2="336.9" y2="319.6"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="69.3" y1="274.9" x2="336.9" y2="274.9"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="69.3" y1="230.3" x2="336.9" y2="230.3"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="69.3" y1="185.8" x2="336.9" y2="185.8"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="69.3" y1="141.1" x2="336.9" y2="141.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="292.3" y1="96.5" x2="292.3" y2="364.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="247.8" y1="96.5" x2="247.8" y2="364.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="203.1" y1="96.5" x2="203.1" y2="364.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="158.5" y1="96.5" x2="158.5" y2="364.1"/>
            +	<line fill="none" stroke="#999999" stroke-width="1.3" x1="114" y1="96.5" x2="114" y2="364.1"/>
            +</g>
            +<g>
            +	<path d="M74.7,32.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H74.7z"/>
            +</g>
            +<g>
            +	<path d="M8.6,90.4l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2c1.2,0,1.8-0.6,2.6-2.7
            +		l0.5-1.2H2.9l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3V89h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3L3.3,95c0.3,1,0.6,1.8,0.8,2.7h0
            +		c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3V89H10v1.2C9.6,90.3,9.1,90.4,8.6,90.4z"/>
            +</g>
            +<g>
            +	<path d="M73.3,69.1c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C78.9,66.7,76.3,69.1,73.3,69.1z
            +		 M73.4,57.3c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C76.8,58.9,75.5,57.3,73.4,57.3z"/>
            +	<path d="M112.4,68.9v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H112.4z"/>
            +	<path d="M155.1,68.9v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H155.1z"/>
            +	<path d="M201.2,70.9c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C207.4,68.9,204.8,70.9,201.2,70.9z"/>
            +	<path d="M249.2,67.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.6h2.7v9.4h2.5v1.8H249.2z M247.3,57.7L247.3,57.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V57.7z"/>
            +	<path d="M287.5,70.9c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C293.9,68.6,291.3,70.9,287.5,70.9z"/>
            +	<path d="M332.6,69.1c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C337.5,67.1,335.6,69.1,332.6,69.1z M332.7,61.3c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C335.6,62.5,334.6,61.3,332.7,61.3z"/>
            +</g>
            +<circle fill="#808080" cx="114" cy="142.6" r="7"/>
            +<circle fill="#808080" cx="249.6" cy="320.2" r="7"/>
            +<g>
            +	<path d="M39.7,106.3c-2.9,0-5.3-1.7-5.3-6.7c0-4.3,2.6-6.7,5.7-6.7c2.8,0,5.3,1.6,5.3,6.6C45.3,103.9,42.7,106.3,39.7,106.3z
            +		 M39.8,94.5c-1.8,0-3.4,1.6-3.4,5c0,3.6,1.4,5.1,3.4,5.1c1.8,0,3.4-1.5,3.4-5C43.2,96.1,41.9,94.5,39.8,94.5z"/>
            +	<path d="M35.6,149.3v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H35.6z"/>
            +	<path d="M35.1,192.5v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H35.1z"/>
            +	<path d="M38,237.7c-0.9,0-1.9-0.1-2.7-0.3l0.3-1.8c0.7,0.3,1.7,0.4,2.6,0.4c2.3,0,3.8-1.3,3.8-2.9c0-1.6-1.3-2.7-3.6-2.7
            +		c-0.7,0-1.3,0-1.9,0.1v-1.6h0.5c3.1,0,4.6-0.9,4.6-2.7c0-1.4-1.1-2.1-2.6-2.1c-1.2,0-2.2,0.3-3.1,0.8l-0.3-1.7
            +		c1.1-0.5,2.3-0.8,3.7-0.8c2.9,0,4.3,1.4,4.3,3.5c0,1.7-1.1,2.9-2.6,3.4l0,0c1.8,0.2,3.1,1.7,3.1,3.5
            +		C44.2,235.7,41.6,237.7,38,237.7z"/>
            +	<path d="M42.8,277.1v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H42.8z M40.9,267.7L40.9,267.7l-4.9,7.6c1.3,0,4,0,4.9,0
            +		V267.7z"/>
            +	<path d="M37.9,324.1c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C44.3,321.8,41.7,324.1,37.9,324.1z"/>
            +	<path d="M39.8,365.5c-3,0-4.9-2.3-4.9-6.2c0-6.2,3.1-8.8,7.2-8.8c0.4,0,1,0,1.3,0.1v1.7c-0.5-0.1-0.9-0.1-1.4-0.1
            +		c-2.8,0-4.3,1.6-4.9,4.6c-0.1,0.2-0.1,0.6-0.2,1.1h0c0.7-1.2,2-1.9,3.4-1.9c2.9,0,4.5,1.9,4.5,4.2
            +		C44.7,363.5,42.8,365.5,39.8,365.5z M39.9,357.7c-1.8,0-2.8,1.6-2.8,2.8c0,1.8,1,3.3,2.9,3.3c1.7,0,2.8-1.3,2.8-3.2
            +		C42.8,358.9,41.8,357.7,39.9,357.7z"/>
            +</g>
            +<line stroke="#000000" stroke-width="1.3" x1="70.4" y1="96.5" x2="61.9" y2="96.5"/>
            +<line stroke="#000000" stroke-width="1.3" x1="70.4" y1="141.3" x2="61.9" y2="141.3"/>
            +<line stroke="#000000" stroke-width="1.3" x1="70.4" y1="185.7" x2="61.9" y2="185.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="70.4" y1="230.2" x2="61.9" y2="230.2"/>
            +<line stroke="#000000" stroke-width="1.3" x1="70.4" y1="274.9" x2="61.9" y2="274.9"/>
            +<line stroke="#000000" stroke-width="1.3" x1="70.4" y1="320.1" x2="61.9" y2="320.1"/>
            +<line stroke="#000000" stroke-width="1.3" x1="70.4" y1="363.7" x2="61.9" y2="363.7"/>
            +<line stroke="#000000" stroke-width="1.3" x1="336.5" y1="96.4" x2="336.5" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="291.7" y1="96.4" x2="291.7" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="247.3" y1="96.4" x2="247.3" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="202.8" y1="96.4" x2="202.8" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="158.1" y1="96.4" x2="158.1" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="112.9" y1="96.4" x2="112.9" y2="87.8"/>
            +<line stroke="#000000" stroke-width="1.3" x1="69.7" y1="96.4" x2="69.7" y2="87.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="9.1,178.2 3.8,183.5 -1.5,178.2 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="3.8" y1="183.5" x2="3.8" y2="120.8"/>
            +<polyline fill="#FFFFFF" stroke="#000000" stroke-width="1.3" points="151.2,20.3 156.5,25.6 151.2,30.9 "/>
            +<line fill="#FFFFFF" stroke="#000000" stroke-width="1.3" x1="157.7" y1="25.6" x2="95" y2="25.6"/>
            +<g>
            +	<path d="M416.5,227.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C416.5,226.9,416.5,227.3,416.5,227.8z M412.1,223.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C414.6,224.7,413.7,223.7,412.1,223.7z"/>
            +	<path d="M417.9,233.2V232c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H417.9z"/>
            +	<path d="M424.3,233.2V232c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H424.3z"/>
            +	<path d="M430.8,233.2V232c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H430.8z M433.7,220.3c-0.7,0-1.3-0.5-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C435,219.7,434.4,220.3,433.7,220.3z"/>
            +	<path d="M442.6,233.3c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H437v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C448.1,231.1,446.1,233.3,442.6,233.3z M443.7,223.8c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C446.1,225.1,445.4,223.8,443.7,223.8z"/>
            +	<path d="M452.9,233.3c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9h-1.2c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C457.4,231.8,455.7,233.3,452.9,233.3z"/>
            +	<path d="M468.4,227.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C468.5,226.9,468.5,227.3,468.4,227.8z M464.1,223.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C466.5,224.7,465.6,223.7,464.1,223.7z"/>
            +	<path d="M484.3,233.2V232c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10h-1.8
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5V232c0.4-0.1,1-0.2,1.3-0.2
            +		l1.7-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H484.3z"/>
            +	<path d="M495.4,233.3c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C500.6,230.8,498.6,233.3,495.4,233.3z
            +		 M495.6,223.8c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C498.6,225.3,497.6,223.8,495.6,223.8z"/>
            +	<path d="M509.8,233.2c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2C512.5,233.1,511,233.2,509.8,233.2
            +		z M509.8,224c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6c1.9,0,2.9-2.3,2.9-4.1V224z"/>
            +	<path d="M523.7,227.8h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C523.8,226.9,523.8,227.3,523.7,227.8z M519.4,223.7c-1.4,0-2.4,1-2.6,2.7h5
            +		C521.8,224.7,520.9,223.7,519.4,223.7z"/>
            +	<path d="M534.2,237.7c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L534.2,237.7z"/>
            +	<path d="M548.4,233.3c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6h-1.4c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C551.3,233,549.9,233.3,548.4,233.3z"/>
            +	<path d="M560.4,233.4c-4.3,0-6.5-2.9-6.5-7.3c0-4.9,3.1-7.7,6.9-7.7c4.3,0,6.5,2.9,6.5,7.3C567.4,230.6,564.2,233.4,560.4,233.4z
            +		 M560.7,220.1c-2.6,0-4.6,2-4.6,5.6c0,3.5,1.5,5.9,4.6,5.9c2.6,0,4.6-2,4.6-5.6C565.3,222.5,563.7,220.1,560.7,220.1z"/>
            +	<path d="M577.7,233.2l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5V232c0.6-0.1,1.2-0.2,1.9-0.3V220c-0.6,0-1.3-0.2-1.9-0.3
            +		v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2
            +		H577.7z M574.2,220.1c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C577.6,220.8,576.5,220.1,574.2,220.1z"/>
            +	<path d="M595.6,220v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2H582V232
            +		c0.6-0.1,1.2-0.3,1.9-0.3V220c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C596.6,219.9,596.1,220,595.6,220z"/>
            +	<path d="M598.7,233.2V232c0.6-0.1,1.2-0.2,1.9-0.3V220c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H598.7z"/>
            +	<path d="M619,233.2l-3.9-6.5H614v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5V232c0.6-0.1,1.2-0.2,1.9-0.3V220c-0.6,0-1.3-0.2-1.9-0.3v-1.2
            +		h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2H619z
            +		 M615.5,220.1c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C618.9,220.8,617.8,220.1,615.5,220.1z"/>
            +	<path d="M627,233.3c-1.1,0-2.2-0.1-3.1-0.4v-3.5h1.4c0.1,0.7,0.2,1.4,0.3,1.9c0.5,0.1,1,0.2,1.6,0.2c1.7,0,3.1-0.7,3.1-2.5
            +		c0-3.3-6.7-2-6.7-6.7c0-2.4,1.9-4.1,5.2-4.1c1,0,1.9,0.1,2.8,0.3v3.3h-1.4c-0.1-0.7-0.2-1.4-0.3-1.9c-0.3-0.1-0.8-0.1-1.3-0.1
            +		c-1.9,0-2.9,0.9-2.9,2.3c0,3.2,6.7,2,6.7,6.6C632.4,231.5,630.4,233.3,627,233.3z"/>
            +	<path d="M640.2,237.7l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C643.4,230.1,642.6,233.8,640.2,237.7z"/>
            +	<path d="M651.8,236.5l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C654.5,230.7,655.2,233.4,651.8,236.5z M652.9,227
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C654.2,226.4,653.6,227,652.9,227z"/>
            +	<path d="M416.5,253.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C416.5,252.8,416.5,253.2,416.5,253.7z M412.1,249.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C414.6,250.6,413.7,249.6,412.1,249.6z"/>
            +	<path d="M417.9,259.1v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H417.9z"/>
            +	<path d="M424.3,259.1v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2v-1.2c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H424.3z"/>
            +	<path d="M430.8,259.1v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H430.8z M433.7,246.2c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C435,245.6,434.4,246.2,433.7,246.2z"/>
            +	<path d="M442.6,259.2c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H437v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C448.1,257,446.1,259.2,442.6,259.2z M443.7,249.7c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C446.1,251.1,445.4,249.7,443.7,249.7z"/>
            +	<path d="M452.9,259.3c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9h-1.2c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C457.4,257.7,455.7,259.3,452.9,259.3z"/>
            +	<path d="M468.4,253.7h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C468.5,252.8,468.5,253.2,468.4,253.7z M464.1,249.6c-1.4,0-2.4,1-2.6,2.7h5
            +		C466.5,250.6,465.6,249.6,464.1,249.6z"/>
            +	<path d="M478.8,263.6c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L478.8,263.6z"/>
            +	<path d="M493.6,259.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H493.6z"/>
            +	<path d="M499.4,259.1v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H499.4z"/>
            +	<path d="M516.2,262.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C518.8,256.6,519.6,259.4,516.2,262.4z"/>
            +	<path d="M534.1,249.8l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2
            +		c1.2,0,1.8-0.6,2.6-2.7l0.5-1.2h-0.5l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6
            +		c0.3,1,0.6,1.8,0.8,2.7h0c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.8v1.2C535.1,249.6,534.6,249.7,534.1,249.8z"/>
            +	<path d="M537.9,259.1v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H537.9z"/>
            +	<path d="M554.7,262.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C557.3,256.6,558,259.4,554.7,262.4z"/>
            +	<path d="M570.2,259.1l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3v-1.2h3.3l2.3,3.9
            +		l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H570.2z"/>
            +	<path d="M575.5,259.1v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H575.5z"/>
            +	<path d="M592.8,262.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C595.4,256.6,596.1,259.4,592.8,262.4z"/>
            +	<path d="M610.7,249.8l-3.8,10.5c-1.2,3.3-2.3,4.4-4.7,4.4c-0.4,0-1,0-1.5-0.1l0.2-1.8c0.5,0.2,0.9,0.2,1.4,0.2
            +		c1.2,0,1.8-0.6,2.6-2.7l0.5-1.2h-0.5l-3.3-9.3c-0.5,0-1-0.1-1.4-0.3v-1.2h4.9v1.2c-0.4,0.1-0.9,0.2-1.4,0.3l1.6,4.6
            +		c0.3,1,0.6,1.8,0.8,2.7h0c0.2-0.7,0.6-2,1-3.2l1.4-4.1c-0.5,0-1-0.1-1.4-0.3v-1.2h4.8v1.2C611.7,249.6,611.2,249.7,610.7,249.8z"/>
            +	<path d="M614,259.1v-1.6l3.1-2.8c2.7-2.3,3.4-3.2,3.4-4.7c0-1.4-0.8-2.4-2.7-2.4c-1.3,0-2.4,0.6-3.1,1.1l-0.4-1.7
            +		c1.1-0.7,2.4-1.1,4-1.1c2.9,0,4.4,1.6,4.4,3.8c0,1.8-1,3.2-3.3,5.3l-2.6,2.2l-0.1,0c1-0.1,3.4-0.1,6.6-0.1v1.9H614z"/>
            +	<path d="M631.9,263.6l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C635,256,634.3,259.7,631.9,263.6z"/>
            +	<path d="M643.5,262.4l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C646.1,256.6,646.9,259.4,643.5,262.4z
            +		 M644.6,252.9c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3s1.3,0.6,1.3,1.3C645.9,252.4,645.3,252.9,644.6,252.9z"/>
            +</g>
            +<g>
            +	<path d="M127.6,135.4c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L127.6,135.4z"/>
            +	<path d="M134,130.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H134z"/>
            +	<path d="M147.6,133.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L147.6,133.4z"/>
            +	<path d="M159.9,130.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H159.9z"/>
            +	<path d="M174.9,113.5c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L174.9,113.5z"/>
            +</g>
            +<g>
            +	<path d="M265.4,313c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L265.4,313z"/>
            +	<path d="M279,306.3v3.6H277v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H279z M277.1,297L277.1,297l-4.9,7.6c1.3,0,4,0,4.9,0V297z"/>
            +	<path d="M285.4,311c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L285.4,311z"/>
            +	<path d="M300,310.2c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C306.3,307.9,303.8,310.2,300,310.2z"/>
            +	<path d="M312.6,291.1c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L312.6,291.1z"/>
            +</g>
            +<g>
            +	<path fill="#808080" d="M55.7,424.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4h-1.4
            +		c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9
            +		c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H55.7z"/>
            +	<path fill="#808080" d="M74.7,424.7l-2.4-4l-2.4,4h-3.2v-1.2c0.6-0.1,1.3-0.3,1.8-0.3l2.6-3.9l-2.5-3.9c-0.6,0-1.2-0.2-1.8-0.3
            +		v-1.2h3.3l2.3,3.9l2.3-3.9h3.1v1.2c-0.6,0.1-1.3,0.3-1.8,0.3l-2.4,3.8l2.6,4c0.6,0,1.2,0.2,1.8,0.3v1.2H74.7z"/>
            +	<path fill="#808080" d="M85.7,424.7c0-0.8,0-1.5,0.1-2.1h0c-0.5,1.3-1.9,2.3-3.7,2.3c-1.8,0-3-1.1-3-2.8c0-2.3,2.4-3.7,6.4-3.7
            +		v-0.8c0-1.5-0.5-2.4-2.2-2.4c-0.6,0-1.4,0.1-2,0.3c0,0.5-0.2,1.1-0.3,1.8h-1.2v-2.9c1.1-0.3,2.4-0.6,3.7-0.6c3.2,0,4,1.4,4,3.6v5.8
            +		c0.5,0.1,1.2,0.2,1.8,0.2v1.2C88.4,424.6,86.9,424.7,85.7,424.7z M85.6,419.7c-3.4,0-4.5,0.8-4.5,2c0,0.9,0.6,1.6,1.6,1.6
            +		c1.7,0,2.9-1.7,2.9-3.4V419.7z"/>
            +	<path fill="#808080" d="M105.7,424.7v-6.9c0-1.5-0.3-2.4-1.7-2.4c-1.5,0-3,1.6-3,4.2v3.7c0.6,0,1.2,0.1,1.8,0.3v1.2H99v-6.9
            +		c0-1.4-0.3-2.4-1.8-2.4c-1.6,0-3,1.8-3,4.2v3.7c0.6,0,1.2,0.1,1.7,0.3v1.2h-5.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8
            +		c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2c0,0.6-0.1,1.6-0.2,2.3l0,0c0.6-1.5,2-2.5,3.7-2.5c2.3,0,2.9,1.6,3,2.4
            +		c0.4-1,1.6-2.4,3.7-2.4c2,0,3.2,1.1,3.2,3.5v6c0.6,0,1.3,0.2,1.8,0.3v1.2H105.7z"/>
            +	<path fill="#808080" d="M115.6,424.8c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2H110v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C121.1,422.6,119.1,424.8,115.6,424.8z M116.7,415.3c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C119.1,416.6,118.3,415.3,116.7,415.3z"/>
            +	<path fill="#808080" d="M122.4,424.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V409c1.1-0.1,2.5-0.2,3.8-0.2
            +		v14.3c0.6,0,1.3,0.2,1.8,0.3v1.2H122.4z"/>
            +	<path fill="#808080" d="M138.2,419.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7
            +		c-3.3,0-5-1.7-5-5.5c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C138.3,418.4,138.2,418.8,138.2,419.3z M133.9,415.2
            +		c-1.4,0-2.4,1-2.6,2.7h5C136.3,416.2,135.4,415.2,133.9,415.2z"/>
            +	<path fill="#808080" d="M142.7,418.5c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C144,417.9,143.4,418.5,142.7,418.5z M142.7,424.9c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C144,424.3,143.4,424.9,142.7,424.9z"/>
            +	<path d="M163.7,419.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C163.8,418.4,163.8,418.8,163.7,419.3z M159.4,415.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C161.9,416.2,160.9,415.2,159.4,415.2z"/>
            +	<path d="M165.2,424.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V409c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H165.2z"/>
            +	<path d="M171.5,424.7v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V409c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H171.5z"/>
            +	<path d="M178.1,424.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2v-1.2c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H178.1z M181,411.8c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C182.3,411.2,181.7,411.8,181,411.8z"/>
            +	<path d="M189.9,424.8c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.6v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2v-1.2c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C195.4,422.6,193.4,424.8,189.9,424.8z M191,415.3c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C193.4,416.6,192.6,415.3,191,415.3z"/>
            +	<path d="M200.1,424.9c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9H203c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C204.7,423.3,203,424.9,200.1,424.9z"/>
            +	<path d="M215.7,419.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C215.8,418.4,215.7,418.8,215.7,419.3z M211.4,415.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C213.8,416.2,212.9,415.2,211.4,415.2z"/>
            +	<path d="M231.6,424.7v-1.2c0.5-0.1,1.1-0.2,1.7-0.3l-1-7.5c-0.2-1.6-0.4-2.8-0.4-3.7h0c-0.2,0.7-0.3,1.6-0.7,2.5l-3.5,10h-1.8
            +		l-3.3-9.5c-0.4-1.1-0.6-2.2-0.8-3h0c0,1.1-0.2,2.4-0.3,3.7l-0.9,7.4c0.6,0,1.2,0.2,1.7,0.3v1.2h-5v-1.2c0.4-0.1,1-0.2,1.3-0.2
            +		l1.7-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l3.1,8.9c0.3,0.8,0.6,2,0.8,2.9h0c0.2-1,0.5-1.8,0.8-2.8l3.1-9h4.7v1.2
            +		c-0.6,0.1-1.2,0.2-1.9,0.3l1.8,11.7c0.4,0,1,0.2,1.3,0.2v1.2H231.6z"/>
            +	<path d="M242.7,424.9c-2.9,0-4.8-1.7-4.8-5.4c0-3.2,2-5.7,5.2-5.7c2.7,0,4.8,1.5,4.8,5.4C247.9,422.4,245.9,424.9,242.7,424.9z
            +		 M242.9,415.3c-1.6,0-3,1.2-3,4c0,2.5,1,3.9,3,3.9c1.6,0,3-1.3,3-3.9C245.9,416.8,244.9,415.3,242.9,415.3z"/>
            +	<path d="M257.1,424.7c0-0.6,0-1.6,0.2-2.2l0,0c-0.6,1.4-1.9,2.4-3.6,2.4c-2.6,0-4-1.9-4-5.1c0-3.8,2.2-6,5.6-6c0.6,0,1.2,0,1.8,0.1
            +		v-3.5c-0.5-0.1-1.3-0.2-1.9-0.2V409c1.1-0.1,2.6-0.2,3.8-0.2v14.2c0.5,0.1,1.2,0.2,1.8,0.2v1.2
            +		C259.8,424.6,258.3,424.7,257.1,424.7z M257.1,415.5c-0.6-0.2-1.3-0.2-1.9-0.2c-2.1,0-3.4,1.2-3.4,4.3c0,2.3,0.8,3.6,2.4,3.6
            +		c1.9,0,2.9-2.3,2.9-4.1V415.5z"/>
            +	<path d="M271,419.3h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C271.1,418.4,271.1,418.8,271,419.3z M266.7,415.2c-1.4,0-2.4,1-2.6,2.7h5
            +		C269.1,416.2,268.2,415.2,266.7,415.2z"/>
            +	<path d="M281.4,429.2c-2.5-4-3.2-7.5-3.2-10.7c0-3.2,0.7-6.9,3.2-10.7l1.4,0.7c-1.8,3-2.7,6.4-2.7,10c0,3.7,0.9,7,2.7,10
            +		L281.4,429.2z"/>
            +	<path d="M295.7,424.9c-4.4,0-6.7-2.7-6.7-7.1c0-4.5,2.3-7.8,7.1-7.8c1.2,0,2.4,0.2,3.5,0.4v3.6h-1.4c-0.2-0.7-0.2-1.4-0.3-2
            +		c-0.8-0.2-1.4-0.3-2.1-0.3c-3.1,0-4.6,2.5-4.6,5.7c0,3.5,1.6,5.7,5,5.7c1.2,0,2.5-0.3,3.4-0.7l0.3,1.7
            +		C298.6,424.5,297.1,424.9,295.7,424.9z"/>
            +	<path d="M307.7,424.9c-4.3,0-6.5-2.9-6.5-7.3c0-4.9,3.1-7.7,6.9-7.7c4.3,0,6.5,2.9,6.5,7.3C314.6,422.1,311.5,424.9,307.7,424.9z
            +		 M307.9,411.6c-2.6,0-4.6,2-4.6,5.6c0,3.5,1.5,5.9,4.6,5.9c2.6,0,4.6-2,4.6-5.6C312.5,414,311,411.6,307.9,411.6z"/>
            +	<path d="M325,424.7l-3.9-6.5H320v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3
            +		v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4c0.5,0.1,1.1,0.2,1.7,0.3v1.2
            +		H325z M321.5,411.6c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6C324.9,412.3,323.8,411.6,321.5,411.6z"/>
            +	<path d="M342.9,411.5v13.1h-2.7l-5.6-9.2c-0.6-1.1-1.2-2.2-1.7-3.2c0.2,2.5,0.2,6.3,0.2,10.9c0.6,0,1.2,0.2,1.7,0.3v1.2h-5.5v-1.2
            +		c0.6-0.1,1.2-0.3,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h4.6l5.6,9.1c0.6,1,1.2,2.2,1.7,3.2c-0.2-2.5-0.2-6.3-0.2-10.8
            +		c-0.6,0-1.2-0.2-1.7-0.3v-1.2h5.1v1.2C343.9,411.4,343.4,411.5,342.9,411.5z"/>
            +	<path d="M345.9,424.7v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7c-0.6,0-1.3-0.2-1.9-0.3v-1.2h9.4v3.4H354c-0.1-0.7-0.2-1.3-0.3-1.8h-3.9
            +		v4.8h3.1c0.1-0.5,0.2-1,0.3-1.5h1.2v4.4h-1.2c-0.1-0.5-0.2-1-0.3-1.5h-3.1v5.2h3.9c0.1-0.6,0.2-1.2,0.3-1.9h1.4v3.5H345.9z"/>
            +	<path d="M366.3,424.7l-3.9-6.5h-1.1v5.1c0.5,0,1.1,0.1,1.6,0.3v1.2h-5.5v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-11.7
            +		c-0.6,0-1.3-0.2-1.9-0.3v-1.2h1.7c0.6,0,2.4-0.1,4-0.1c3.1,0,5.1,1,5.1,3.9c0,2.3-1.6,3.6-3.9,4c0.3,0.4,0.7,0.9,1,1.3l2.5,4
            +		c0.5,0.1,1.1,0.2,1.7,0.3v1.2H366.3z M362.8,411.6c-0.4,0-1.1,0-1.5,0.1v5h1.7c2.1,0,3.3-1,3.3-2.6
            +		C366.2,412.3,365.1,411.6,362.8,411.6z"/>
            +	<path d="M374.3,424.9c-1.1,0-2.2-0.1-3.1-0.4V421h1.4c0.1,0.7,0.2,1.4,0.3,1.9c0.5,0.1,1,0.2,1.6,0.2c1.7,0,3.1-0.7,3.1-2.5
            +		c0-3.3-6.7-2-6.7-6.7c0-2.4,1.9-4.1,5.2-4.1c1,0,1.9,0.1,2.8,0.3v3.3h-1.4c-0.1-0.7-0.2-1.4-0.3-1.9c-0.3-0.1-0.8-0.1-1.3-0.1
            +		c-1.9,0-2.9,0.9-2.9,2.3c0,3.2,6.7,2,6.7,6.6C379.7,423,377.7,424.9,374.3,424.9z"/>
            +	<path d="M387.5,429.2l-1.4-0.7c1.8-3,2.7-6.4,2.7-9.9c0-3.7-0.9-7-2.7-10.1l1.5-0.7c2.5,4,3.1,7.5,3.1,10.6
            +		C390.6,421.6,389.9,425.3,387.5,429.2z"/>
            +	<path d="M399.1,428l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C401.8,422.2,402.5,424.9,399.1,428z M400.2,418.5
            +		c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C401.5,417.9,400.9,418.5,400.2,418.5z"/>
            +	<path d="M165.5,445.2h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C165.6,444.3,165.5,444.7,165.5,445.2z M161.2,441.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C163.6,442.2,162.7,441.1,161.2,441.1z"/>
            +	<path d="M166.9,450.6v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V435c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H166.9z"/>
            +	<path d="M173.3,450.6v-1.2c0.5-0.1,1.2-0.2,1.8-0.3v-12.8c-0.5-0.1-1.2-0.2-1.9-0.2V435c1.1-0.1,2.5-0.2,3.8-0.2v14.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H173.3z"/>
            +	<path d="M179.9,450.6v-1.2c0.6-0.1,1.2-0.2,1.9-0.3v-7.8c-0.5-0.1-1.3-0.2-1.9-0.2V440c1.1-0.1,2.6-0.2,3.8-0.2v9.3
            +		c0.6,0,1.3,0.2,1.8,0.3v1.2H179.9z M182.8,437.7c-0.7,0-1.3-0.5-1.3-1.3s0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3
            +		C184,437.1,183.4,437.7,182.8,437.7z"/>
            +	<path d="M191.7,450.7c-0.7,0-1.2,0-1.8-0.1v3.9c0.6,0,1.3,0.2,1.9,0.3v1.2h-5.6v-1.2c0.6-0.1,1.1-0.2,1.8-0.3v-13.1
            +		c-0.5-0.1-1.2-0.2-1.8-0.2V440c1.1-0.1,2.5-0.2,3.7-0.2c0,0.6-0.1,1.6-0.2,2.2l0,0c0.6-1.5,1.9-2.4,3.6-2.4c2.5,0,4,1.8,4,5.1
            +		C197.2,448.5,195.1,450.7,191.7,450.7z M192.8,441.2c-1.9,0-2.9,2.3-2.9,4.1v3.5c0.6,0.2,1.2,0.3,1.9,0.3c2,0,3.4-1.2,3.4-4.3
            +		C195.1,442.6,194.4,441.2,192.8,441.2z"/>
            +	<path d="M201.9,450.8c-0.8,0-1.8-0.1-2.5-0.3v-3h1.2c0.1,0.5,0.2,1.1,0.3,1.7c0.4,0.1,0.8,0.1,1.3,0.1c1.4,0,2.4-0.6,2.4-1.7
            +		c0-2.4-5.4-1-5.4-4.7c0-1.8,1.5-3.2,4.3-3.2c0.8,0,1.7,0.1,2.5,0.3v2.9h-1.2c-0.1-0.5-0.2-1.1-0.3-1.7c-0.4-0.1-0.8-0.1-1.2-0.1
            +		c-1.4,0-2.2,0.6-2.2,1.6c0,2.4,5.4,1.1,5.4,4.6C206.5,449.2,204.7,450.8,201.9,450.8z"/>
            +	<path d="M217.4,445.2h-7c-0.1,2.8,1.1,4,3.4,4c1,0,2.1-0.2,3.1-0.6l0.3,1.5c-1.1,0.4-2.4,0.7-3.7,0.7c-3.3,0-5-1.7-5-5.5
            +		c0-3.2,1.8-5.6,4.8-5.6c3,0,4.3,2,4.3,4.4C217.5,444.3,217.5,444.7,217.4,445.2z M213.1,441.1c-1.4,0-2.4,1-2.6,2.7h5
            +		C215.6,442.2,214.6,441.1,213.1,441.1z"/>
            +	<path d="M232,455.4c-3.6-3.3-5.3-6.7-5.3-10.9c0-4.4,2.1-8.1,5.4-11l1.1,1.1c-2.9,2.9-4.5,6.2-4.5,9.7c0,3.6,1.5,6.9,4.5,9.9
            +		L232,455.4z"/>
            +	<path d="M238.4,450.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H238.4z"/>
            +	<path d="M252.1,453.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L252.1,453.4z"/>
            +	<path d="M264.3,450.6v-1.8h4v-9.1l-3.7,2.4l-0.7-1.7l4.8-2.9h1.7v11.3h3.4v1.8H264.3z"/>
            +	<path d="M278,453.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L278,453.4z"/>
            +	<path d="M297.5,448.7v3.6h-1.9v-3.6h-6.6l-0.2-1.6l6-9.5h2.7v9.4h2.5v1.8H297.5z M295.6,439.4L295.6,439.4l-4.9,7.6
            +		c1.3,0,4,0,4.9,0V439.4z"/>
            +	<path d="M303.9,453.4c2.2-0.6,2.9-1.6,2.9-2.4c0-1.4-1.1-1.4-1.1-2.5c0-0.9,0.6-1.6,1.5-1.6c1.4,0,2,1.3,2,2.7c0,2.7-1.8,4.3-5,5
            +		L303.9,453.4z"/>
            +	<path d="M318.5,452.6c-0.7,0-1.6-0.1-2.4-0.2l0.2-1.7c0.7,0.2,1.7,0.3,2.4,0.3c2.6,0,4-1.5,4-3.2c0-1.8-1.5-2.8-3.9-2.8
            +		c-0.9,0-1.7,0.1-2.2,0.2v-7.4h7.6v1.9l-5.8,0v3.8c0.4,0,0.8,0,1.1,0c3.6,0,5.4,1.8,5.4,4.1C324.8,450.3,322.3,452.6,318.5,452.6z"
            +		/>
            +	<path d="M331.1,433.6c3.6,3.3,5.3,6.7,5.3,10.9c0,4.4-2.1,8.1-5.4,11l-1.1-1.1c2.9-2.9,4.5-6.2,4.5-9.7c0-3.6-1.5-6.9-4.5-9.9
            +		L331.1,433.6z"/>
            +	<path d="M355.2,453.9l-0.8-0.7c1.4-1.5,1.4-2.5,0.9-3.1c-0.6-0.8-0.1-1.9,0.9-1.9C357.8,448.1,358.5,450.9,355.2,453.9z
            +		 M356.2,444.4c-0.7,0-1.3-0.6-1.3-1.3c0-0.7,0.6-1.3,1.3-1.3c0.7,0,1.3,0.6,1.3,1.3C357.6,443.9,357,444.4,356.2,444.4z"/>
            +</g>
            +<ellipse fill="none" stroke="#000000" stroke-width="2" cx="180.9" cy="230.3" rx="66.9" ry="89.2"/>
            +</svg>
            diff --git a/dist/assets/learn/curves/bezier/embed.html b/dist/assets/learn/curves/bezier/embed.html
            new file mode 100644
            index 0000000000..e1c1a0c007
            --- /dev/null
            +++ b/dist/assets/learn/curves/bezier/embed.html
            @@ -0,0 +1,19 @@
            +<!DOCTYPE html>
            +<head>
            +  <title>Curves Example</title>
            +  <script src="../../../js/p5.min.js"></script>
            +  <!-- uncomment lines below to include extra p5 libraries -->
            +  <!--<script src="../addons/p5.sound.js"></script>-->
            +  <script src="sketch.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +  <style>
            +    body {
            +      padding: 0;
            +      margin: 0;
            +    }
            +  </style>
            +</head>
            +
            +<body>
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/curves/bezier/sketch.js b/dist/assets/learn/curves/bezier/sketch.js
            new file mode 100644
            index 0000000000..bdb92c80d6
            --- /dev/null
            +++ b/dist/assets/learn/curves/bezier/sketch.js
            @@ -0,0 +1,75 @@
            +let x1 = 100;
            +let y1 = 150;
            +let x2 = 200;
            +let y2 = 150;
            +let x3 = 50;
            +let y3 = 50;
            +let x4 = 250;
            +let y4 = 50;
            +let d1 = false;
            +let d2 = false;
            +let d4 = false;
            +let d3 = false;
            +
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(255);
            +  ellipse(x1, y1, 10, 10); // endpoints of curve
            +  ellipse(x2, y2, 10, 10);
            +  fill(255, 0, 0);
            +  ellipse(x3, y3, 10, 10); // control points
            +  ellipse(x4, y4, 10, 10);
            +  noFill();
            +  stroke(0);
            +  bezier(x1, y1, x3, y3, x4, y4, x2, y2);
            +
            +  noStroke();
            +
            +  fill(0, 0, 255, 100);
            +  text('(' + x1 + ',' + y1 + ')', x1, y1);
            +  text('(' + x2 + ',' + y2 + ')', x2, y2);
            +  text('(' + x3 + ',' + y3 + ')', x3, y3);
            +  text('(' + x4 + ',' + y4 + ')', x4, y4);
            +
            +  if (d1) {
            +    x1 = mouseX;
            +    y1 = mouseY;
            +  }
            +  if (d2) {
            +    x2 = mouseX;
            +    y2 = mouseY;
            +  }
            +  if (d3) {
            +    x3 = mouseX;
            +    y3 = mouseY;
            +  }
            +  if (d4) {
            +    x4 = mouseX;
            +    y4 = mouseY;
            +  }
            +}
            +
            +function mouseDragged() {
            +  if (dist(mouseX, mouseY, x1, y1) < 10) {
            +    d1 = true;
            +  }
            +  if (dist(mouseX, mouseY, x2, y2) < 10) {
            +    d2 = true;
            +  }
            +  if (dist(mouseX, mouseY, x3, y3) < 10) {
            +    d3 = true;
            +  }
            +  if (dist(mouseX, mouseY, x4, y4) < 10) {
            +    d4 = true;
            +  }
            +}
            +
            +function mouseReleased() {
            +  d1 = false;
            +  d2 = false;
            +  d3 = false;
            +  d4 = false;
            +}
            diff --git a/dist/assets/learn/curves/bezier_with_lines/bezier_with_lines.png b/dist/assets/learn/curves/bezier_with_lines/bezier_with_lines.png
            new file mode 100644
            index 0000000000..5ae9533148
            Binary files /dev/null and b/dist/assets/learn/curves/bezier_with_lines/bezier_with_lines.png differ
            diff --git a/dist/assets/learn/curves/curve_ex/embed.html b/dist/assets/learn/curves/curve_ex/embed.html
            new file mode 100644
            index 0000000000..e1c1a0c007
            --- /dev/null
            +++ b/dist/assets/learn/curves/curve_ex/embed.html
            @@ -0,0 +1,19 @@
            +<!DOCTYPE html>
            +<head>
            +  <title>Curves Example</title>
            +  <script src="../../../js/p5.min.js"></script>
            +  <!-- uncomment lines below to include extra p5 libraries -->
            +  <!--<script src="../addons/p5.sound.js"></script>-->
            +  <script src="sketch.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +  <style>
            +    body {
            +      padding: 0;
            +      margin: 0;
            +    }
            +  </style>
            +</head>
            +
            +<body>
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/curves/curve_ex/sketch.js b/dist/assets/learn/curves/curve_ex/sketch.js
            new file mode 100644
            index 0000000000..bf71e0655a
            --- /dev/null
            +++ b/dist/assets/learn/curves/curve_ex/sketch.js
            @@ -0,0 +1,80 @@
            +let x1 = 80;
            +let y1 = 80;
            +let x2 = 160;
            +let y2 = 120;
            +let x3 = 200;
            +let y3 = 200;
            +let x4 = 120;
            +let y4 = 240;
            +let d1 = false;
            +let d2 = false;
            +let d4 = false;
            +let d3 = false;
            +let d5 = false;
            +
            +function setup() {
            +  createCanvas(300, 300);
            +}
            +
            +function draw() {
            +  background(255);
            +  stroke(0);
            +  curve(x1, y1, x2, y2, x3, y3, x4, y4);
            +  noStroke();
            +  fill(255, 0, 0);
            +  ellipse(x1, y1, 10, 10);
            +  fill(0, 0, 255, 192);
            +  ellipse(x3, y3, 10, 10);
            +  ellipse(x2, y2, 10, 10);
            +  fill(255, 0, 0);
            +  ellipse(x4, y4, 10, 10);
            +
            +  noStroke();
            +  text('(' + x1 + ',' + y1 + ')', x1, y1);
            +  text('(' + x2 + ',' + y2 + ')', x2, y2);
            +  text('(' + x3 + ',' + y3 + ')', x3, y3);
            +  text('(' + x4 + ',' + y4 + ')', x4, y4);
            +
            +  if (d1) {
            +    x1 = mouseX;
            +    y1 = mouseY;
            +  }
            +  if (d2) {
            +    x2 = mouseX;
            +    y2 = mouseY;
            +  }
            +  if (d3) {
            +    x3 = mouseX;
            +    y3 = mouseY;
            +  }
            +  if (d4) {
            +    x4 = mouseX;
            +    y4 = mouseY;
            +  }
            +}
            +
            +function mouseDragged() {
            +  if (dist(mouseX, mouseY, x1, y1) < 10) {
            +    d1 = true;
            +  }
            +  if (dist(mouseX, mouseY, x2, y2) < 10) {
            +    d2 = true;
            +  }
            +  if (dist(mouseX, mouseY, x3, y3) < 10) {
            +    d3 = true;
            +  }
            +  if (dist(mouseX, mouseY, x4, y4) < 10) {
            +    d4 = true;
            +  }
            +  if (dist(mouseX, mouseY, x5, y5) < 10) {
            +    d5 = true;
            +  }
            +}
            +
            +function mouseReleased() {
            +  d1 = false;
            +  d2 = false;
            +  d3 = false;
            +  d4 = false;
            +  d5 = false;
            +}
            diff --git a/dist/assets/learn/debugging/0-0.jpg b/dist/assets/learn/debugging/0-0.jpg
            new file mode 100644
            index 0000000000..e633635c19
            Binary files /dev/null and b/dist/assets/learn/debugging/0-0.jpg differ
            diff --git a/dist/assets/learn/debugging/0-1.jpg b/dist/assets/learn/debugging/0-1.jpg
            new file mode 100644
            index 0000000000..41da05dd3f
            Binary files /dev/null and b/dist/assets/learn/debugging/0-1.jpg differ
            diff --git a/dist/assets/learn/debugging/0-3.png b/dist/assets/learn/debugging/0-3.png
            new file mode 100644
            index 0000000000..0d8b245a57
            Binary files /dev/null and b/dist/assets/learn/debugging/0-3.png differ
            diff --git a/dist/assets/learn/debugging/0-4.png b/dist/assets/learn/debugging/0-4.png
            new file mode 100644
            index 0000000000..3592c7b299
            Binary files /dev/null and b/dist/assets/learn/debugging/0-4.png differ
            diff --git a/dist/assets/learn/debugging/0-5.png b/dist/assets/learn/debugging/0-5.png
            new file mode 100644
            index 0000000000..1e40dcfc1e
            Binary files /dev/null and b/dist/assets/learn/debugging/0-5.png differ
            diff --git a/dist/assets/learn/debugging/0-6.png b/dist/assets/learn/debugging/0-6.png
            new file mode 100644
            index 0000000000..05efed3b54
            Binary files /dev/null and b/dist/assets/learn/debugging/0-6.png differ
            diff --git a/dist/assets/learn/debugging/1-0.jpg b/dist/assets/learn/debugging/1-0.jpg
            new file mode 100644
            index 0000000000..6e319385f0
            Binary files /dev/null and b/dist/assets/learn/debugging/1-0.jpg differ
            diff --git a/dist/assets/learn/debugging/2-1.png b/dist/assets/learn/debugging/2-1.png
            new file mode 100644
            index 0000000000..8a4a333c3e
            Binary files /dev/null and b/dist/assets/learn/debugging/2-1.png differ
            diff --git a/dist/assets/learn/debugging/2-2.png b/dist/assets/learn/debugging/2-2.png
            new file mode 100644
            index 0000000000..8d39e11404
            Binary files /dev/null and b/dist/assets/learn/debugging/2-2.png differ
            diff --git a/dist/assets/learn/debugging/2-3.jpg b/dist/assets/learn/debugging/2-3.jpg
            new file mode 100644
            index 0000000000..753841082c
            Binary files /dev/null and b/dist/assets/learn/debugging/2-3.jpg differ
            diff --git a/dist/assets/learn/debugging/3-1.png b/dist/assets/learn/debugging/3-1.png
            new file mode 100644
            index 0000000000..1f4c5ae0d4
            Binary files /dev/null and b/dist/assets/learn/debugging/3-1.png differ
            diff --git a/dist/assets/learn/debugging/3-2.png b/dist/assets/learn/debugging/3-2.png
            new file mode 100644
            index 0000000000..d3091dc2a6
            Binary files /dev/null and b/dist/assets/learn/debugging/3-2.png differ
            diff --git a/dist/assets/learn/debugging/3-3.jpg b/dist/assets/learn/debugging/3-3.jpg
            new file mode 100644
            index 0000000000..1a96c97764
            Binary files /dev/null and b/dist/assets/learn/debugging/3-3.jpg differ
            diff --git a/dist/assets/learn/debugging/3-4.png b/dist/assets/learn/debugging/3-4.png
            new file mode 100644
            index 0000000000..817422ac1f
            Binary files /dev/null and b/dist/assets/learn/debugging/3-4.png differ
            diff --git a/dist/assets/learn/debugging/3-5.jpg b/dist/assets/learn/debugging/3-5.jpg
            new file mode 100644
            index 0000000000..a9de487d8c
            Binary files /dev/null and b/dist/assets/learn/debugging/3-5.jpg differ
            diff --git a/dist/assets/learn/debugging/4-1.png b/dist/assets/learn/debugging/4-1.png
            new file mode 100644
            index 0000000000..805047f03f
            Binary files /dev/null and b/dist/assets/learn/debugging/4-1.png differ
            diff --git a/dist/assets/learn/debugging/4-2.png b/dist/assets/learn/debugging/4-2.png
            new file mode 100644
            index 0000000000..ae3a5c92db
            Binary files /dev/null and b/dist/assets/learn/debugging/4-2.png differ
            diff --git a/dist/assets/learn/debugging/4-3.png b/dist/assets/learn/debugging/4-3.png
            new file mode 100644
            index 0000000000..91797bf456
            Binary files /dev/null and b/dist/assets/learn/debugging/4-3.png differ
            diff --git a/dist/assets/learn/debugging/5-1.jpg b/dist/assets/learn/debugging/5-1.jpg
            new file mode 100644
            index 0000000000..1198e7bad6
            Binary files /dev/null and b/dist/assets/learn/debugging/5-1.jpg differ
            diff --git a/dist/assets/learn/debugging/5-2.png b/dist/assets/learn/debugging/5-2.png
            new file mode 100644
            index 0000000000..c0b81c5df4
            Binary files /dev/null and b/dist/assets/learn/debugging/5-2.png differ
            diff --git a/dist/assets/learn/debugging/6-1.png b/dist/assets/learn/debugging/6-1.png
            new file mode 100644
            index 0000000000..13361d77e8
            Binary files /dev/null and b/dist/assets/learn/debugging/6-1.png differ
            diff --git a/dist/assets/learn/debugging/6-2.png b/dist/assets/learn/debugging/6-2.png
            new file mode 100644
            index 0000000000..76b1fd6861
            Binary files /dev/null and b/dist/assets/learn/debugging/6-2.png differ
            diff --git a/dist/assets/learn/debugging/6-3.jpg b/dist/assets/learn/debugging/6-3.jpg
            new file mode 100644
            index 0000000000..61aa849022
            Binary files /dev/null and b/dist/assets/learn/debugging/6-3.jpg differ
            diff --git a/dist/assets/learn/debugging/7-1.jpg b/dist/assets/learn/debugging/7-1.jpg
            new file mode 100644
            index 0000000000..1f7c0bad16
            Binary files /dev/null and b/dist/assets/learn/debugging/7-1.jpg differ
            diff --git a/dist/assets/learn/debugging/8-0.jpg b/dist/assets/learn/debugging/8-0.jpg
            new file mode 100644
            index 0000000000..489f211891
            Binary files /dev/null and b/dist/assets/learn/debugging/8-0.jpg differ
            diff --git a/dist/assets/learn/debugging/9-1.jpg b/dist/assets/learn/debugging/9-1.jpg
            new file mode 100644
            index 0000000000..8442d645b3
            Binary files /dev/null and b/dist/assets/learn/debugging/9-1.jpg differ
            diff --git a/dist/assets/learn/interactivity/and.js b/dist/assets/learn/interactivity/and.js
            new file mode 100644
            index 0000000000..7daa97f3c9
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/and.js
            @@ -0,0 +1,22 @@
            +var and_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +    p.fill(0);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if ((p.mouseX > 40) && (p.mouseX < 80) &&
            +      (p.mouseY > 20) && (p.mouseY < 80)) {
            +      p.fill(255);
            +    } else {
            +      p.fill(0);
            +    }
            +    p.rect(40, 20, 40, 60);
            +  }
            +
            +};
            +
            +var and = new p5(and_s, 'and');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/coded_keys.js b/dist/assets/learn/interactivity/coded_keys.js
            new file mode 100644
            index 0000000000..5e4239be14
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/coded_keys.js
            @@ -0,0 +1,25 @@
            +var coded_keys_s = function( p ) {
            +
            +  var y = 35;
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.stroke(0);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    p.line(10, 50, 90, 50);
            +    if (p.keyCode == p.UP_ARROW) {
            +      y = 20;
            +    } else if (p.keyCode == p.DOWN_ARROW) {
            +      y = 50;
            +    } else {
            +      y = 35;
            +    }
            +    p.rect(25, y, 50, 30);
            +  }
            +
            +};
            +
            +var coded_keys = new p5(coded_keys_s, 'coded_keys');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/corners.js b/dist/assets/learn/interactivity/corners.js
            new file mode 100644
            index 0000000000..dfe87f3774
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/corners.js
            @@ -0,0 +1,24 @@
            +var corners_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +    p.fill(0);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if ((p.mouseX <= 50) && (p.mouseY <= 50)) {
            +      p.rect(0, 0, 50, 50); // Upper-left
            +    } else if ((p.mouseX <= 50) && (p.mouseY > 50)) {
            +      p.rect(0, 50, 50, 50); // Lower-left
            +    } else if ((p.mouseX > 50) && (p.mouseY <= 50)) {
            +      p.rect(50, 0, 50, 50); // Upper-right
            +    } else {
            +      p.rect(50, 50, 50, 50); // Lower-right
            +    }
            +  }
            +
            +};
            +
            +var corners = new p5(corners_s, 'corners');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/cursor_1.js b/dist/assets/learn/interactivity/cursor_1.js
            new file mode 100644
            index 0000000000..ec388a7097
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/cursor_1.js
            @@ -0,0 +1,16 @@
            +var cursor_1_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.strokeWeight(7);
            +    p.noCursor();
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    p.ellipse(p.mouseX, p.mouseY, 10, 10);
            +  }
            +
            +};
            +
            +var cursor_1 = new p5(cursor_1_s, 'cursor_1');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/cursor_2.js b/dist/assets/learn/interactivity/cursor_2.js
            new file mode 100644
            index 0000000000..9f5af53304
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/cursor_2.js
            @@ -0,0 +1,18 @@
            +var cursor_2_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.mouseIsPressed == true) {
            +      p.cursor();
            +    } else {
            +      p.noCursor();
            +    }
            +  }
            +
            +};
            +
            +var cursor_2 = new p5(cursor_2_s, 'cursor_2');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/cursor_3.js b/dist/assets/learn/interactivity/cursor_3.js
            new file mode 100644
            index 0000000000..63a1f2202b
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/cursor_3.js
            @@ -0,0 +1,21 @@
            +var cursor_3_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noCursor();
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.mousePressed == true) {
            +      p.cursor(p.HAND);  // Draw cursor as hand
            +    } else {
            +      p.cursor(p.CROSS); // Draw cursor as cross
            +    }
            +    p.line(p.mouseX, 0, p.mouseX, p.height);
            +    p.line(0, p.mouseY, p.height, p.mouseY);
            +  }
            +
            +};
            +
            +var cursor_3 = new p5(cursor_3_s, 'cursor_3');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/draw_t.js b/dist/assets/learn/interactivity/draw_t.js
            new file mode 100644
            index 0000000000..2525597561
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/draw_t.js
            @@ -0,0 +1,26 @@
            +var draw_t_s = function( p ) {
            +
            +  var drawT = false;
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (drawT == true) {
            +      p.rect(20, 20, 60, 20);
            +      p.rect(39, 40, 22, 45);
            +    }
            +  }
            +
            +  p.keyPressed = function() {
            +    if ((p.key == 'T') || (p.key == 't')) {
            +      drawT = true;
            +    }
            +  }
            +
            +};
            +
            +var draw_t = new p5(draw_t_s, 'draw_t');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/draw_t_2.js b/dist/assets/learn/interactivity/draw_t_2.js
            new file mode 100644
            index 0000000000..dc3bf74de7
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/draw_t_2.js
            @@ -0,0 +1,30 @@
            +var draw_t_2_s = function( p ) {
            +
            +  var drawT = false;
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (drawT == true) {
            +      p.rect(20, 20, 60, 20);
            +      p.rect(39, 40, 22, 45);
            +    }
            +  }
            +
            +  p.keyPressed = function() {
            +    if ((p.key == 'T') || (p.key == 't')) {
            +      drawT = true;
            +    }
            +  }
            +
            +  p.keyReleased = function() {
            +    drawT = false;
            +  }
            +
            +};
            +
            +var draw_t_2 = new p5(draw_t_2_s, 'draw_t_2');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/event_1.js b/dist/assets/learn/interactivity/event_1.js
            new file mode 100644
            index 0000000000..6a52d6d95d
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/event_1.js
            @@ -0,0 +1,28 @@
            +var event_1_s = function( p ) {
            +
            +  var frame = false;
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +  }
            +
            +  p.draw = function() {
            +    if (frame > 120) { // If 120 frames since the mouse
            +      p.noLoop(); // was pressed, stop the program
            +      p.background(0); // and turn the background black.
            +    } else { // Otherwise, set the background
            +      p.background(204); // to light gray and draw lines
            +      p.line(p.mouseX, 0, p.mouseX, 100); // at the mouse position
            +      p.line(0, p.mouseY, 100, p.mouseY);
            +      frame++;
            +    }
            +  }
            +
            +  p.mousePressed = function() {
            +    frame = 0;
            +    p.loop();
            +  }
            +
            +};
            +
            +var event_1 = new p5(event_1_s, 'event_1');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/event_2.js b/dist/assets/learn/interactivity/event_2.js
            new file mode 100644
            index 0000000000..2108dad7d9
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/event_2.js
            @@ -0,0 +1,20 @@
            +var event_2_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noLoop();
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    p.line(p.mouseX, 0, p.mouseX, 100);
            +    p.line(0, p.mouseY, 100, p.mouseY);
            +  }
            +
            +  p.mousePressed = function() {
            +    p.redraw(); // Run the code in draw one time
            +  }
            +
            +};
            +
            +var event_2 = new p5(event_2_s, 'event_2');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/invert_mouse.js b/dist/assets/learn/interactivity/invert_mouse.js
            new file mode 100644
            index 0000000000..24cd88ae8f
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/invert_mouse.js
            @@ -0,0 +1,22 @@
            +var invert_mouse_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +  }
            +
            +  p.draw = function() {
            +    var x = p.mouseX;
            +    var y = p.mouseY;
            +    var ix = p.width - p.mouseX; // Inverse X
            +    var iy = p.height - p.mouseY; // Inverse Y
            +    p.background(126);
            +    p.fill(255, 150);
            +    p.ellipse(x, p.height/2, y, y);
            +    p.fill(0, 159);
            +    p.ellipse(ix, p.height/2, iy, iy);
            +  }
            +
            +};
            +
            +var invert_mouse = new p5(invert_mouse_s, 'invert_mouse');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/key_1.js b/dist/assets/learn/interactivity/key_1.js
            new file mode 100644
            index 0000000000..a04f840209
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/key_1.js
            @@ -0,0 +1,19 @@
            +var key_1_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.strokeWeight(4);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.keyIsPressed === true) { // If the key is pressed,
            +      p.line(20, 20, 80, 80); // draw a line
            +    } else { // Otherwise,
            +      p.rect(40, 40, 20, 20); // draw a rectangle
            +    }
            +  }
            +
            +};
            +
            +var key_1 = new p5(key_1_s, 'key_1');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/key_2.js b/dist/assets/learn/interactivity/key_2.js
            new file mode 100644
            index 0000000000..d852efc19d
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/key_2.js
            @@ -0,0 +1,19 @@
            +var key_2_s = function( p ) {
            +
            +  var x = 20;
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.strokeWeight(4);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.keyIsPressed == true) { // If the key is pressed
            +      x++; // add 1 to x
            +    }
            +    p.line(x, 20, x-60, 80);
            +  }
            +
            +};
            +
            +var key_2 = new p5(key_2_s, 'key_2');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/key_code_1.js b/dist/assets/learn/interactivity/key_code_1.js
            new file mode 100644
            index 0000000000..c27021b71a
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/key_code_1.js
            @@ -0,0 +1,17 @@
            +var key_code_1_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.stroke(0);
            +  }
            +
            +  p.draw = function() {
            +    if (p.keyIsPressed === true) {
            +      var x = p.keyCode - 32;
            +      p.line(x, 0, x, p.height);
            +    }
            +  }
            +
            +};
            +
            +var key_code_1 = new p5(key_code_1_s, 'key_code_1');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/key_code_2.js b/dist/assets/learn/interactivity/key_code_2.js
            new file mode 100644
            index 0000000000..d59646b2f4
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/key_code_2.js
            @@ -0,0 +1,23 @@
            +var key_code_2_s = function( p ) {
            +
            +  var angle = 20;
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.stroke(0);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.keyIsPressed === true) {
            +      if ((p.keyCode >= 32) && (p.keyCode <= 126)) {
            +        // If the key is alphanumeric, // use its value as an angle
            +        angle = (p.keyCode - 32) * 3;
            +      }
            +    }
            +    p.arc(50, 50, 66, 66, 0, p.radians(angle));
            +  }
            +
            +};
            +
            +var key_code_2 = new p5(key_code_2_s, 'key_code_2');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/key_eq_a.js b/dist/assets/learn/interactivity/key_eq_a.js
            new file mode 100644
            index 0000000000..cc6ea6eb27
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/key_eq_a.js
            @@ -0,0 +1,23 @@
            +var key_eq_a_s = function( p ) {
            +
            +  var x = 20;
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.strokeWeight(4);
            +    p.stroke(255);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    p.background(0);
            +    // If the 'A' key is pressed draw a line
            +    if ((p.keyIsPressed === true) && (p.key == 'A')) {
            +      p.line(50, 25, 50, 75);
            +    } else { // Otherwise, draw an ellipse
            +      p.ellipse(50, 50, 50, 50);
            +    }
            +  }
            +
            +};
            +
            +var key_eq_a = new p5(key_eq_a_s, 'key_eq_a');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/key_var.js b/dist/assets/learn/interactivity/key_var.js
            new file mode 100644
            index 0000000000..1c023e2785
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/key_var.js
            @@ -0,0 +1,16 @@
            +var key_var_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.textSize(60);
            +    p.fill(255);
            +  }
            +
            +  p.draw = function() {
            +    p.background(0);
            +    p.text(p.key, 20, 75); // Draw at coordinate (20,75)
            +  }
            +
            +};
            +
            +var key_var = new p5(key_var_s, 'key_var');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/mouse_1.js b/dist/assets/learn/interactivity/mouse_1.js
            new file mode 100644
            index 0000000000..54ba2ac88d
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/mouse_1.js
            @@ -0,0 +1,15 @@
            +var mouse_1_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +  }
            +
            +  p.draw = function() {
            +    p.background(126);
            +    p.ellipse(p.mouseX, p.mouseY, 33, 33);
            +  }
            +
            +};
            +
            +var mouse_1 = new p5(mouse_1_s, 'mouse_1');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/mouse_2.js b/dist/assets/learn/interactivity/mouse_2.js
            new file mode 100644
            index 0000000000..f384a5de93
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/mouse_2.js
            @@ -0,0 +1,17 @@
            +var mouse_2_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +  }
            +
            +  p.draw = function() {
            +    p.background(126);
            +    p.ellipse(p.mouseX, 16, 33, 33); // Top circle
            +    p.ellipse(p.mouseX+20, 50, 33, 33); // Middle circle
            +    p.ellipse(p.mouseX-20, 84, 33, 33); // Bottom circle
            +  }
            +
            +};
            +
            +var mouse_2 = new p5(mouse_2_s, 'mouse_2');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/mouse_3.js b/dist/assets/learn/interactivity/mouse_3.js
            new file mode 100644
            index 0000000000..c1bba5237c
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/mouse_3.js
            @@ -0,0 +1,17 @@
            +var mouse_3_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +  }
            +
            +  p.draw = function() {
            +    p.background(126);
            +    p.ellipse(p.mouseX, 16, 33, 33); // Top circle
            +    p.ellipse(p.mouseX/2, 50, 33, 33); // Middle circle
            +    p.ellipse(p.mouseX*2, 84, 33, 33); // Bottom circle
            +  }
            +
            +};
            +
            +var mouse3 = new p5(mouse_3_s, 'mouse_3');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/mouse_boxes.js b/dist/assets/learn/interactivity/mouse_boxes.js
            new file mode 100644
            index 0000000000..a94c991dcc
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/mouse_boxes.js
            @@ -0,0 +1,19 @@
            +var mouse_boxes_s = function( p ) {
            +
            +  var gray = 0;
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.fill(0, 102);
            +    p.background(204);
            +  }
            +
            +  p.draw = function() {}
            +
            +  p.mouseReleased = function() {
            +    p.rect(p.mouseX, p.mouseY, 33, 33);
            +  }
            +
            +};
            +
            +var mouse_boxes = new p5(mouse_boxes_s, 'mouse_boxes');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/mouse_pressed.js b/dist/assets/learn/interactivity/mouse_pressed.js
            new file mode 100644
            index 0000000000..f453bd6eba
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/mouse_pressed.js
            @@ -0,0 +1,19 @@
            +var mouse_pressed_s = function( p ) {
            +
            +  var gray = 0;
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +  }
            +
            +  p.draw = function() {
            +    p.background(gray);
            +  }
            +
            +  p.mousePressed = function() {
            +    gray += 20;
            +  }
            +
            +};
            +
            +var mouse_pressed = new p5(mouse_pressed_s, 'mouse_pressed');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/mouse_released.js b/dist/assets/learn/interactivity/mouse_released.js
            new file mode 100644
            index 0000000000..73e9390d84
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/mouse_released.js
            @@ -0,0 +1,19 @@
            +var mouse_released_s = function( p ) {
            +
            +  var gray = 0;
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +  }
            +
            +  p.draw = function() {
            +    p.background(gray);
            +  }
            +
            +  p.mouseReleased = function() {
            +    gray += 20;
            +  }
            +
            +};
            +
            +var mouse_released = new p5(mouse_released_s, 'mouse_released');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/moved_dragged.js b/dist/assets/learn/interactivity/moved_dragged.js
            new file mode 100644
            index 0000000000..b0059fee22
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/moved_dragged.js
            @@ -0,0 +1,30 @@
            +var moved_dragged_s = function( p ) {
            +
            +  var dragX, dragY, moveX, moveY;
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    p.fill(0);
            +    p.ellipse(dragX, dragY, 33, 33); // Black circle
            +    p.fill(153);
            +    p.ellipse(moveX, moveY, 33, 33); // Gray circle
            +  }
            +
            +  p.mouseMoved = function() { // Move gray circle
            +    moveX = p.mouseX;
            +    moveY = p.mouseY;
            +  }
            +
            +  p.mouseDragged = function() { // Move black circle
            +    dragX = p.mouseX;
            +    dragY = p.mouseY;
            +  }
            +
            +};
            +
            +var moved_dragged = new p5(moved_dragged_s, 'moved_dragged');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/pressed_1.js b/dist/assets/learn/interactivity/pressed_1.js
            new file mode 100644
            index 0000000000..4ed4f4d028
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/pressed_1.js
            @@ -0,0 +1,21 @@
            +var pressed_1_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +    p.fill(0);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.mouseIsPressed == true) {
            +      p.fill(255); // White
            +    } else {
            +      p.fill(0); // Black
            +    }
            +    p.rect(25, 25, 50, 50);
            +  }
            +
            +};
            +
            +var pressed_1 = new p5(pressed_1_s, 'pressed_1');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/pressed_2.js b/dist/assets/learn/interactivity/pressed_2.js
            new file mode 100644
            index 0000000000..cd4a5c0e7a
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/pressed_2.js
            @@ -0,0 +1,23 @@
            +var pressed_2_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +    p.fill(0);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.mouseButton == p.LEFT) {
            +      p.fill(0); // Black
            +    } else if (p.mouseButton == p.RIGHT) {
            +      p.fill(255); // White
            +    } else {
            +      p.fill(126); // Gray
            +    }
            +    p.rect(25, 25, 50, 50);
            +  }
            +
            +};
            +
            +var pressed_2 = new p5(pressed_2_s, 'pressed_2');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/pressed_3.js b/dist/assets/learn/interactivity/pressed_3.js
            new file mode 100644
            index 0000000000..9659e40587
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/pressed_3.js
            @@ -0,0 +1,25 @@
            +var pressed_3_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +    p.fill(0);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.mouseIsPressed === true) {
            +      if (p.mouseButton == p.LEFT) {
            +        p.fill(0); // Black
            +      } else if (p.mouseButton == p.RIGHT) {
            +        p.fill(255); // White
            +      }
            +    } else {
            +      p.fill(126); // Gray
            +    }
            +    p.rect(25, 25, 50, 50);
            +  }
            +
            +};
            +
            +var pressed_3 = new p5(pressed_3_s, 'pressed_3');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/prev_mouse.js b/dist/assets/learn/interactivity/prev_mouse.js
            new file mode 100644
            index 0000000000..325fa76075
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/prev_mouse.js
            @@ -0,0 +1,15 @@
            +var prev_mouse_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.strokeWeight(8);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    p.line(p.mouseX, p.mouseY, p.pmouseX, p.pmouseY);
            +  }
            +
            +};
            +
            +var prev_mouse = new p5(prev_mouse_s, 'prev_mouse');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/region_1.js b/dist/assets/learn/interactivity/region_1.js
            new file mode 100644
            index 0000000000..2eb0ca9651
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/region_1.js
            @@ -0,0 +1,20 @@
            +var region_1_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +    p.fill(0);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.mouseX < 50) {
            +      p.rect(0, 0, 50, 100); // Left
            +    } else {
            +      p.rect(50, 0, 50, 100); // Right
            +    }
            +  }
            +
            +};
            +
            +var region_1 = new p5(region_1_s, 'region_1');
            \ No newline at end of file
            diff --git a/dist/assets/learn/interactivity/region_2.js b/dist/assets/learn/interactivity/region_2.js
            new file mode 100644
            index 0000000000..5d1d76637d
            --- /dev/null
            +++ b/dist/assets/learn/interactivity/region_2.js
            @@ -0,0 +1,22 @@
            +var region_2_s = function( p ) {
            +
            +  p.setup = function() {
            +    p.createCanvas(100, 100);
            +    p.noStroke();
            +    p.fill(0);
            +  }
            +
            +  p.draw = function() {
            +    p.background(204);
            +    if (p.mouseX < 33) {
            +      p.rect(0, 0, 33, 100); // Left
            +    } else if (p.mouseX < 66) {
            +      p.rect(33, 0, 33, 100); // Middle
            +    } else {
            +      p.rect(66, 0, 33, 100); // Right
            +    }
            +  }
            +
            +};
            +
            +var region_2 = new p5(region_2_s, 'region_2');
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/cache-dom-lookups/index.html b/dist/assets/learn/performance/code/cache-dom-lookups/index.html
            new file mode 100644
            index 0000000000..0c1fb34e31
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/cache-dom-lookups/index.html
            @@ -0,0 +1,38 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>p5 Performance Test</title>
            +    <style>
            +      html, body, canvas {
            +        padding: 0; 
            +        margin: 0;
            +      }
            +      body {
            +        overflow: hidden;
            +      }
            +      button {
            +        font-size: 3em;
            +        background-color: #ff00d5;
            +        border: none;
            +        outline: none;
            +        color: white;
            +        box-shadow: 0 6px #D102AF;
            +        border-radius: 3px;
            +        padding: 10px 30px;
            +        cursor: pointer;
            +      }
            +      button:hover {
            +        box-shadow: 0 4px #D102AF;
            +        margin-top: 2px;
            +      }
            +    </style>
            +  </head>
            +  <body>
            +    <button id="button-1">button 1</button>
            +    <button id="button-2">button 2</button>
            +
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/addons/p5.dom.min.js"></script>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/cache-dom-lookups/sketch.js b/dist/assets/learn/performance/code/cache-dom-lookups/sketch.js
            new file mode 100644
            index 0000000000..e3c62ffab1
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/cache-dom-lookups/sketch.js
            @@ -0,0 +1,32 @@
            +// Results in Chrome:
            +// 
            +//  Cached button took:     573.42ms.
            +//  Non-cached button took: 5925.31ms.
            +
            +p5.disableFriendlyErrors = true;
            +
            +var iterations = 100000;
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  
            +  // -- REPOSITION BUTTON - CACHED LOOKUP --------------------------------------
            +  
            +  var start = millis();
            +  var button1 = select("#button-1");
            +  for (var i = 0; i < iterations; i++) {
            +    button1.position(random(0, width), random(0, height));
            +  }
            +  var elapsed = millis() - start;
            +  console.log("Cached button took: " + elapsed.toFixed(2) + "ms.")
            +
            +  // -- REPOSITION BUTTON - NON-CACHED LOOKUP ----------------------------------
            +  
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    var button2 = select("#button-2");
            +    button2.position(random(0, width), random(0, height));
            +  }
            +  var elapsed = millis() - start;
            +  console.log("Non-cached button took: " + elapsed.toFixed(2) + "ms.")
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/cpu-profiler-demo/index.html b/dist/assets/learn/performance/code/cpu-profiler-demo/index.html
            new file mode 100644
            index 0000000000..489736223b
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/cpu-profiler-demo/index.html
            @@ -0,0 +1,20 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>p5 Performance Test</title>
            +    <style>
            +      html, body, canvas {
            +        padding: 0; 
            +        margin: 0;
            +      }
            +      body {
            +        overflow: hidden;
            +      }
            +    </style>
            +  </head>
            +  <body>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/addons/p5.dom.min.js"></script>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/cpu-profiler-demo/sketch.js b/dist/assets/learn/performance/code/cpu-profiler-demo/sketch.js
            new file mode 100644
            index 0000000000..40de9dae34
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/cpu-profiler-demo/sketch.js
            @@ -0,0 +1,75 @@
            +p5.disableFriendlyErrors = true;
            +
            +var capture;
            +var videoWidth = null;
            +var videoHeigh = null;
            +var sampledPixels = [];
            +var stepSize = 2;
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  
            +  // Set up a video capture
            +  capture = createCapture(VIDEO);
            +  capture.size(640, 480);
            +  capture.hide();
            +
            +  // Wait until the stream has loaded a frame before doing any processing
            +  capture.elt.addEventListener("loadeddata", function () {
            +    videoWidth = this.videoWidth;
            +    videoHeight = this.videoHeight;
            +    samplePixels();
            +    sortPixels();
            +    drawPixels();
            +  });
            +}
            +
            +function samplePixels() {
            +  // Make the camera pixels available
            +  capture.loadPixels();
            +  // Sample the pixels from the camera and store the colors in an array
            +  sampledPixels = [];
            +  for (y = 0; y < videoHeight; y += stepSize) {
            +    for (x = 0; x < videoWidth; x += stepSize) {
            +      var i = 4 * (y * videoWidth + x);
            +      var c = color(
            +        capture.pixels[i],
            +        capture.pixels[i + 1],
            +        capture.pixels[i + 2]
            +      );
            +      sampledPixels.push(c);
            +    }
            +  }
            +}
            +
            +function sortPixels() {
            +  // Use the native array sort method to do the grunt work of sorting
            +  sampledPixels.sort(sortHue);
            +}
            +
            +function sortHue(color1, color2) {
            +  // Given two p5 colors, determine which has the greater hue value
            +  var hue1 = hue(color1);
            +  var hue2 = hue(color2);
            +  if (hue1 < hue2) return -1;
            +  else if (hue1 > hue2) return 1;
            +  return 0;  
            +}
            +
            +function drawPixels() {
            +  // Calculated dimensions of sampled video 
            +  var sampledWidth = Math.ceil(videoWidth / stepSize);
            +  var sampledHeight = Math.ceil(videoHeight / stepSize);
            +  // We are going to draw rectangles for each sampled color, so scale up the
            +  // rectangles so they fit the canvas
            +  var w = width / sampledWidth;
            +  var h = height / sampledHeight;
            +  for (var i = 0; i < sampledPixels.length; i++) {
            +    var x = i % sampledWidth;
            +    var y = Math.floor(i / sampledWidth);
            +    fill(sampledPixels[i]);
            +    noStroke();
            +    // Draw rectangle slightly larger than needed to deal with rounding errors
            +    rect(x * w, y * h, w + 1, h + 1);
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/distance-squared/index.html b/dist/assets/learn/performance/code/distance-squared/index.html
            new file mode 100644
            index 0000000000..b104074ca8
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/distance-squared/index.html
            @@ -0,0 +1,16 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>p5 Performance Test</title>
            +    <style>
            +      html, body, canvas {
            +        padding: 0; 
            +        margin: 0; 
            +      }
            +    </style>
            +  </head>
            +  <body>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/distance-squared/sketch.js b/dist/assets/learn/performance/code/distance-squared/sketch.js
            new file mode 100644
            index 0000000000..ddf2c61c5d
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/distance-squared/sketch.js
            @@ -0,0 +1,56 @@
            +// Results in Chrome:
            +// 
            +//  p5 dist took:                 3205.14ms.
            +//  Distance squared squred took: 2921.55ms.
            +//  
            +// Results in p5 Editor:
            +// 
            +//  p5 dist took:                 5381.38ms.
            +//  Distance squared squred took: 2450.13ms.
            +
            +p5.disableFriendlyErrors = true;
            +
            +var iterations = 10000000;
            +
            +function setup() {
            +  createCanvas(800, 600);
            +
            +  // Setup random points that will be checked
            +  var points = [];
            +  for (var i = 0; i < iterations; i += 1) {
            +    points.push(random(-100, 100), random(-100, 100));
            +  }
            +  var maxDistance = 50;
            +
            +  // -- DISTANCE ---------------------------------------------------------------
            +  
            +  var lastPoint = points[0];
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    var d = dist(lastPoint.x, lastPoint.y, points[i].x, points[i].y);
            +    // Do something, e.g. collision detection, creating particles inside an area
            +    lastPoint = points[i];
            +  }
            +  var elapsed = millis() - start;
            +  console.log("p5 dist took: " + elapsed.toFixed(2) + "ms.")
            +
            +
            +  // -- DISTANCE SQUARED -------------------------------------------------------
            +
            +  var maxDistanceSquared = maxDistance * maxDistance;
            +  var distSquared = function (x1, y1, x2, y2) {
            +    var dx = x2 - x1;
            +    var dy = y2 - y1;
            +    return dx * dx + dy * dy;
            +  }
            +  var lastPoint = points[0];
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    var d = distSquared(lastPoint.x, lastPoint.y, points[i].x, points[i].y);
            +    // Do something, e.g. collision detection, creating particles inside an area
            +    lastPoint = points[i];
            +  }
            +  var elapsed = millis() - start;
            +  console.log("Distance squared squred took: " + elapsed.toFixed(2) + "ms.")
            +
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/fps-demo/index.html b/dist/assets/learn/performance/code/fps-demo/index.html
            new file mode 100644
            index 0000000000..b104074ca8
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/fps-demo/index.html
            @@ -0,0 +1,16 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>p5 Performance Test</title>
            +    <style>
            +      html, body, canvas {
            +        padding: 0; 
            +        margin: 0; 
            +      }
            +    </style>
            +  </head>
            +  <body>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/fps-demo/sketch.js b/dist/assets/learn/performance/code/fps-demo/sketch.js
            new file mode 100644
            index 0000000000..6c69d847dd
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/fps-demo/sketch.js
            @@ -0,0 +1,19 @@
            +function setup() {
            +  createCanvas(300, 300);
            +}
            +
            +function draw() {
            +  var seconds = millis() / 1000;
            +  var radius = map(sin(3 * seconds), -1, 1, 50, min(width, height));
            +
            +  background("#191716");
            +  fill("#E6AF2E");
            +  ellipse(width / 2, height / 2, radius, radius);
            +
            +  // Draw FPS (rounded to 2 decimal places) at the bottom left of the 
            +  // screen
            +  // var fps = frameRate();
            +  // fill(255);
            +  // stroke(0);
            +  // text("FPS: " + fps.toFixed(2), 10, height - 10);
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/friendly-error-system/index.html b/dist/assets/learn/performance/code/friendly-error-system/index.html
            new file mode 100644
            index 0000000000..b104074ca8
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/friendly-error-system/index.html
            @@ -0,0 +1,16 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>p5 Performance Test</title>
            +    <style>
            +      html, body, canvas {
            +        padding: 0; 
            +        margin: 0; 
            +      }
            +    </style>
            +  </head>
            +  <body>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/friendly-error-system/sketch.js b/dist/assets/learn/performance/code/friendly-error-system/sketch.js
            new file mode 100644
            index 0000000000..4e79b0da4a
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/friendly-error-system/sketch.js
            @@ -0,0 +1,30 @@
            +// Results in Chrome:
            +// 
            +//  Friendly Errors Disabled:
            +//    "Random took: 271.43ms."
            +//  
            +//  Friendly Errors Enabled:
            +//    "Random took: 1534.10ms."
            +//  
            +// Results in p5 Editor:
            +// 
            +//  Friendly Errors Disabled:
            +//    "Random took: 1885.23ms."
            +//  
            +//  Friendly Errors Enabled:
            +//    "Random took: 3147.38ms."
            +
            +p5.disableFriendlyErrors = false;
            +
            +var iterations = 10000000;
            +
            +function setup() {
            +  createCanvas(800, 600);
            +
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    random();
            +  }
            +  var elapsed = millis() - start;
            +  console.log("Random took: " + elapsed.toFixed(2) + "ms.")
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/native-vs-p5/index.html b/dist/assets/learn/performance/code/native-vs-p5/index.html
            new file mode 100644
            index 0000000000..b104074ca8
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/native-vs-p5/index.html
            @@ -0,0 +1,16 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>p5 Performance Test</title>
            +    <style>
            +      html, body, canvas {
            +        padding: 0; 
            +        margin: 0; 
            +      }
            +    </style>
            +  </head>
            +  <body>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/native-vs-p5/sketch.js b/dist/assets/learn/performance/code/native-vs-p5/sketch.js
            new file mode 100644
            index 0000000000..ad0bfb71a1
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/native-vs-p5/sketch.js
            @@ -0,0 +1,80 @@
            +// Results in Chrome:
            +// 
            +//  p5 random took:     283.88ms.
            +//  Native random took: 190.01ms.
            +//  
            +//  p5 sin took:        481.14ms.
            +//  Native sin took:    338.33ms.
            +//  
            +//  p5 min took:        781.41ms.
            +//  Native min took:    538.15ms.
            +//  
            +// Results in p5 Editor:
            +// 
            +//  p5 random took:     2430.28ms.
            +//  Native random took: 85.56ms.
            +//  
            +//  p5 sin took:        2337.90ms.
            +//  Native sin took:    265.94ms.
            +//  
            +//  p5 min took:        8335.63ms.
            +//  Native min took:    5308.00ms.
            +
            +p5.disableFriendlyErrors = true;
            +
            +var iterations = 10000000;
            +
            +function setup() {
            +  createCanvas(800, 600);
            +
            +  // -- RANDOM -----------------------------------------------------------
            +  
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    random(0, 100);
            +  }
            +  var elapsed = millis() - start;
            +  console.log("p5 random took: " + elapsed.toFixed(2) + "ms.")
            +
            +
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    Math.random() * 100;
            +  }
            +  var elapsed = millis() - start;
            +  console.log("Native random took: " + elapsed.toFixed(2) + "ms.")
            +
            +  // -- SIN -----------------------------------------------------------
            +  
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    sin(i / iterations * (10 * TWO_PI));
            +  }
            +  var elapsed = millis() - start;
            +  console.log("p5 sin took: " + elapsed.toFixed(2) + "ms.")
            +
            +
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    Math.sin(i / iterations * (10 * TWO_PI));
            +  }
            +  var elapsed = millis() - start;
            +  console.log("Native sin took: " + elapsed.toFixed(2) + "ms.")
            +
            +  // -- MIN -----------------------------------------------------------
            +  
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    min(random(0, 100), random(0, 100));
            +  }
            +  var elapsed = millis() - start;
            +  console.log("p5 min took: " + elapsed.toFixed(2) + "ms.")
            +
            +
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    Math.min(random(0, 100), random(0, 100));
            +  }
            +  var elapsed = millis() - start;
            +  console.log("Native min took: " + elapsed.toFixed(2) + "ms.")
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/platforms-test/index.html b/dist/assets/learn/performance/code/platforms-test/index.html
            new file mode 100644
            index 0000000000..b104074ca8
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/platforms-test/index.html
            @@ -0,0 +1,16 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>p5 Performance Test</title>
            +    <style>
            +      html, body, canvas {
            +        padding: 0; 
            +        margin: 0; 
            +      }
            +    </style>
            +  </head>
            +  <body>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/platforms-test/sketch.js b/dist/assets/learn/performance/code/platforms-test/sketch.js
            new file mode 100644
            index 0000000000..fa993f2a44
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/platforms-test/sketch.js
            @@ -0,0 +1,71 @@
            +// Particle system performance test
            +// 
            +// Chrome Results:
            +//  "Drawing 200x times took: 1708.16ms."
            +// 
            +// Firefox Results:
            +//  "Drawing 200x times took: 3761.27ms."
            +//  
            +// Edge Results:
            +//  "Drawing 200x times took: 8362.05ms."
            +// 
            +// IE11 Results:
            +//  "Drawing 200x times took: 8665.79ms."
            +// 
            +// Editor results:
            +//  "Drawing 200x times took: 4480.28ms."
            +
            +p5.disableFriendlyErrors = true;
            +
            +var iterations = 200;
            +var numParticles = 1000;
            +var particles = [];
            +
            +function setup() {
            +  createCanvas(800, 600);
            +  colorMode(HSB, 100);
            +
            +  for (var i = 0; i < numParticles; i++) {
            +    particles.push({
            +      x: random(0, width),
            +      y: random(0, height),
            +      heading: random(0, TWO_PI),
            +      radius: random(5, 10),
            +      color: color(random(70, 90), 100, 100)
            +    })
            +  }
            +
            +  var start = millis();
            +  for (var i = 0; i < iterations; i++) {
            +    draw();
            +  }
            +  var elapsed = millis() - start;
            +  console.log("Drawing " + iterations + "x times took: " + elapsed.toFixed(2) + 
            +    "ms.");
            +}
            +
            +function draw() {
            +  // Clear with an alpha for trail effect
            +  background(0, 20);
            +
            +  for (var i = 0; i < particles.length; i++) {
            +    var particle = particles[i];
            +
            +    // Randomly adjust the heading
            +    particle.heading += random(-PI / 12, PI / 12);
            +
            +    // Move the particle
            +    particle.x += 5 * cos(particle.heading);
            +    particle.y += 5 * sin(particle.heading);
            +
            +    // Wrap particles around the edges of the screen
            +    if (particle.x > width) particle.x = particle.x - width;
            +    else if (particle.x < 0) particle.x = width + particle.x;
            +    if (particle.y > height) particle.y = particle.y - height;
            +    else if (particle.y < 0) particle.y = height + particle.y;
            +
            +    // Draw particle
            +    fill(particle.color);
            +    ellipse(particle.x, particle.y, particle.radius, particle.radius);
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/reflow-dom-manipulation/index.html b/dist/assets/learn/performance/code/reflow-dom-manipulation/index.html
            new file mode 100644
            index 0000000000..489736223b
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/reflow-dom-manipulation/index.html
            @@ -0,0 +1,20 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>p5 Performance Test</title>
            +    <style>
            +      html, body, canvas {
            +        padding: 0; 
            +        margin: 0;
            +      }
            +      body {
            +        overflow: hidden;
            +      }
            +    </style>
            +  </head>
            +  <body>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/addons/p5.dom.min.js"></script>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/reflow-dom-manipulation/sketch.js b/dist/assets/learn/performance/code/reflow-dom-manipulation/sketch.js
            new file mode 100644
            index 0000000000..db7a2aeebb
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/reflow-dom-manipulation/sketch.js
            @@ -0,0 +1,48 @@
            +// Results in Chrome:
            +// 
            +//  Creating divs in native JS took:  1.19ms.
            +//  Creating divs in p5 took:         479.57ms.
            +//  
            +// Note: tests are in functions so that the timeline in Chrome dev tools can
            +// provide useful debugging information. 
            +
            +p5.disableFriendlyErrors = true;
            +
            +var iterations = 1000;
            +
            +function setup() {
            +  createCanvas(0, 0);
            +
            +  nativeAddDivs();
            +  p5AddDivs();
            +}
            +
            +function nativeAddDivs() {
            +  // Test
            +  var start = millis();
            +  var containerDiv = document.createElement("div");
            +  for (var i = 0; i < iterations; i++) {
            +    var childDiv = document.createElement("div");
            +    childDiv.textContent = i;
            +    containerDiv.appendChild(childDiv);
            +  }
            +  document.body.appendChild(containerDiv);
            +  var elapsed = millis() - start;
            +  console.log("Creating divs in native JS took: " + elapsed.toFixed(2) + "ms.")
            +  // Cleanup
            +  document.body.removeChild(containerDiv);
            +}
            +
            +function p5AddDivs() {
            +  // Test
            +  var start = millis();
            +  var containerDiv = createDiv();
            +  for (var i = 0; i < iterations; i++) {
            +    var childDiv = createDiv(i);
            +    containerDiv.child(childDiv);
            +  }
            +  var elapsed = millis() - start;
            +  console.log("Creating divs in p5 took: " + elapsed.toFixed(2) + "ms.")
            +  // Cleanup
            +  containerDiv.remove();
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/resizing-images/blackberry-original.jpg b/dist/assets/learn/performance/code/resizing-images/blackberry-original.jpg
            new file mode 100644
            index 0000000000..6a1c157155
            Binary files /dev/null and b/dist/assets/learn/performance/code/resizing-images/blackberry-original.jpg differ
            diff --git a/dist/assets/learn/performance/code/resizing-images/blackberry-tiny-sharpened.jpg b/dist/assets/learn/performance/code/resizing-images/blackberry-tiny-sharpened.jpg
            new file mode 100644
            index 0000000000..aaaa843ba5
            Binary files /dev/null and b/dist/assets/learn/performance/code/resizing-images/blackberry-tiny-sharpened.jpg differ
            diff --git a/dist/assets/learn/performance/code/resizing-images/floral-original.jpg b/dist/assets/learn/performance/code/resizing-images/floral-original.jpg
            new file mode 100644
            index 0000000000..e2d9b3e90b
            Binary files /dev/null and b/dist/assets/learn/performance/code/resizing-images/floral-original.jpg differ
            diff --git a/dist/assets/learn/performance/code/resizing-images/floral-tiny-sharpened.jpg b/dist/assets/learn/performance/code/resizing-images/floral-tiny-sharpened.jpg
            new file mode 100644
            index 0000000000..023ec5181a
            Binary files /dev/null and b/dist/assets/learn/performance/code/resizing-images/floral-tiny-sharpened.jpg differ
            diff --git a/dist/assets/learn/performance/code/resizing-images/index.html b/dist/assets/learn/performance/code/resizing-images/index.html
            new file mode 100644
            index 0000000000..90f056b99a
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/resizing-images/index.html
            @@ -0,0 +1,16 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>p5 Performance Test</title>
            +    <style>
            +      html, body, canvas {
            +        padding: 0; 
            +        margin: 0;
            +      }
            +    </style>
            +  </head>
            +  <body>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/code/resizing-images/sketch.js b/dist/assets/learn/performance/code/resizing-images/sketch.js
            new file mode 100644
            index 0000000000..bccf4fc899
            --- /dev/null
            +++ b/dist/assets/learn/performance/code/resizing-images/sketch.js
            @@ -0,0 +1,213 @@
            +// Chrome, 100x iterations
            +//  resizeBeforeRuntime took:     7282.69ms.
            +//  sampleImage took:             8371.29ms.
            +//  imageResize took:             7530.42ms.
            +//  iterativeImageResize took:    7680.36ms.
            +
            +// NOTE: this code disregards pixel density
            +
            +// Image sources: 
            +//  - steve lodefink, blackberry
            +//    https://flic.kr/p/2sGVow
            +//    Creative Commons Attribution License (Share, Adapt, Commercial)
            +//  - floral pattern
            +//    http://www.publicdomainpictures.net/view-image.php?image=51731&picture=vintage-floral-wallpaper-pattern
            +//    Creative Commons Public Domain 
            +
            +
            +p5.disableFriendlyErrors = true;
            +
            +var originalImage;
            +var preshrunkImage;
            +
            +var scale;
            +var stepSize;
            +
            +var iterations = 1;
            +
            +function preload() {
            +  originalImage = loadImage("floral-original.jpg");
            +  preshrunkImage = loadImage("floral-tiny-sharpened.jpg");
            +}
            +
            +function setup() {
            +  createCanvas(originalImage.width * 4 , originalImage.height);
            +  background(255);
            +
            +  stepSize = originalImage.width / preshrunkImage.width;
            +  scale = 1 / stepSize;
            +
            +  resizeBeforeRuntime();
            +  translate(originalImage.width, 0);
            +  sampleImage();
            +  translate(originalImage.width, 0);
            +  imageResize();
            +  translate(originalImage.width, 0);
            +  iterativeImageResize();
            +
            +}
            +
            +function resizeBeforeRuntime() {
            +  var start = millis();
            +
            +  var w = preshrunkImage.width;
            +  var h = preshrunkImage.height;
            +
            +  // Iterations
            +  for (var i = 0; i < iterations; i++) {
            +
            +    // Get the pixel data
            +    preshrunkImage.loadPixels();
            +
            +    // Iterate through pixels
            +    for (var x = 0; x < w; x++) {
            +      for (var y = 0; y < h; y++) {
            +        var index = 4 * (y * w + x);
            +        var r = preshrunkImage.pixels[index];
            +        var g = preshrunkImage.pixels[index+1];
            +        var b = preshrunkImage.pixels[index+2];
            +        var a = preshrunkImage.pixels[index+3];  
            +        fill(r, g, b, a);
            +        noStroke();
            +        rect(x * stepSize, y * stepSize, stepSize, stepSize);  
            +      }
            +    }
            +
            +  }
            +
            +  var elapsed = millis() - start;
            +  console.log("resizeBeforeRuntime took: " + elapsed.toFixed(2) + "ms.")
            +}
            +
            +function sampleImage() {
            +  var start = millis();
            +
            +  var w = originalImage.width;
            +  var h = originalImage.height;
            +
            +  // Iterations
            +  for (var i = 0; i < iterations; i++) {
            +
            +    // Get the pixel data
            +    originalImage.loadPixels();
            +
            +    // Iterate through pixels
            +    for (var x = 0; x < w; x += stepSize) {
            +      for (var y = 0; y < h; y += stepSize) {
            +        var index = 4 * (y * w + x);
            +        var r = originalImage.pixels[index];
            +        var g = originalImage.pixels[index+1];
            +        var b = originalImage.pixels[index+2];
            +        var a = originalImage.pixels[index+3];  
            +        fill(r, g, b, a);
            +        noStroke();
            +        rect(x, y, stepSize, stepSize);  
            +      }
            +    }
            +
            +  }
            +
            +  var elapsed = millis() - start;
            +  console.log("sampleImage took: " + elapsed.toFixed(2) + "ms.")
            +}
            +
            +function imageResize() {
            +  // Make a copy of the image so that it can be destructively resized.  Don't
            +  // time this since a normal application wouldn't need it.
            +  var originalWidth = originalImage.width;
            +  var originalHeight = originalImage.height;
            +  var img = new p5.Image(originalWidth, originalHeight);
            +  img.copy(originalImage, 0, 0, originalWidth, originalHeight, 0, 0, 
            +    originalWidth, originalHeight);
            +
            +  // Setup work, only needs to be done once
            +  var w = preshrunkImage.width;
            +  var h = preshrunkImage.height;
            +
            +  var start = millis();
            +
            +  // Resize the image
            +  img.resize(w, h);
            +    
            +  // Iterations
            +  for (var i = 0; i < iterations; i++) {
            +
            +
            +    // Get the pixel data
            +    img.loadPixels();
            +
            +    // Iterate through pixels
            +    for (var x = 0; x < w; x++) {
            +      for (var y = 0; y < h; y++) {
            +        var index = 4 * (y * w + x);
            +        var r = img.pixels[index];
            +        var g = img.pixels[index+1];
            +        var b = img.pixels[index+2];
            +        var a = img.pixels[index+3];  
            +        fill(r, g, b, a);
            +        noStroke();
            +        rect(x * stepSize, y * stepSize, stepSize, stepSize);  
            +      }
            +    }
            +
            +  }
            +
            +  var elapsed = millis() - start;
            +  console.log("imageResize took: " + elapsed.toFixed(2) + "ms.")
            +}
            +
            +function iterativeImageResize() {
            +  // Make a copy of the image so that it can be destructively resized.  Don't
            +  // time this since a normal application wouldn't need it.
            +  var originalWidth = originalImage.width;
            +  var originalHeight = originalImage.height;
            +  var img = new p5.Image(originalWidth, originalHeight);
            +  img.copy(originalImage, 0, 0, originalWidth, originalHeight, 0, 0, 
            +    originalWidth, originalHeight);
            +
            +  var start = millis();
            +
            +  // Interatively resize the image by halfing as many times as possible. In an
            +  // application, you would want to choose a number of times to half (1x - 2x
            +  // times). The resizing here is extremely drastic for demonstration purposes, 
            +  // so this is going to do 3x half resizes.
            +  // Source: http://stackoverflow.com/a/19262385
            +  var targetWidth = preshrunkImage.width;
            +  var targetHeight = preshrunkImage.height;
            +  while (img.width > (2 * targetWidth) && img.height > (2 * targetHeight)) {
            +    img.resize(img.width / 2, img.height / 2);
            +  }
            +  // Final resize to get to the exact dimensions
            +  if (img.width !== targetWidth || img.height !== targetHeight) {
            +    img.resize(targetWidth, targetHeight)
            +  }
            +
            +  // Setup work, only needs to be done once
            +  var w = img.width;
            +  var h = img.height;
            +
            +  // Iterations
            +  for (var i = 0; i < iterations; i++) {
            +
            +    // Get the pixels
            +    img.loadPixels();
            +
            +    // Iterate through pixels
            +    for (var x = 0; x < w; x++) {
            +      for (var y = 0; y < h; y++) {
            +        var index = 4 * (y * w + x);
            +        var r = img.pixels[index];
            +        var g = img.pixels[index+1];
            +        var b = img.pixels[index+2];
            +        var a = img.pixels[index+3];  
            +        fill(r, g, b, a);
            +        noStroke();
            +        rect(x * stepSize, y * stepSize, stepSize, stepSize);  
            +      }
            +    }
            +
            +  }
            +
            +  var elapsed = millis() - start;
            +  console.log("iterativeImageResize took: " + elapsed.toFixed(2) + "ms.")
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/performance/images/chrome-cpu-flame.gif b/dist/assets/learn/performance/images/chrome-cpu-flame.gif
            new file mode 100644
            index 0000000000..6a4cd10bb5
            Binary files /dev/null and b/dist/assets/learn/performance/images/chrome-cpu-flame.gif differ
            diff --git a/dist/assets/learn/performance/images/chrome-cpu-profile.jpg b/dist/assets/learn/performance/images/chrome-cpu-profile.jpg
            new file mode 100644
            index 0000000000..f30503ec5f
            Binary files /dev/null and b/dist/assets/learn/performance/images/chrome-cpu-profile.jpg differ
            diff --git a/dist/assets/learn/performance/images/chrome-fps.jpg b/dist/assets/learn/performance/images/chrome-fps.jpg
            new file mode 100644
            index 0000000000..c7f0e2f7f3
            Binary files /dev/null and b/dist/assets/learn/performance/images/chrome-fps.jpg differ
            diff --git a/dist/assets/learn/performance/images/chrome-show-fps.gif b/dist/assets/learn/performance/images/chrome-show-fps.gif
            new file mode 100644
            index 0000000000..296938b18e
            Binary files /dev/null and b/dist/assets/learn/performance/images/chrome-show-fps.gif differ
            diff --git a/dist/assets/learn/performance/images/drastic-resizing-comparison.png b/dist/assets/learn/performance/images/drastic-resizing-comparison.png
            new file mode 100644
            index 0000000000..f270c12d6f
            Binary files /dev/null and b/dist/assets/learn/performance/images/drastic-resizing-comparison.png differ
            diff --git a/dist/assets/learn/performance/images/editor-show-fps.gif b/dist/assets/learn/performance/images/editor-show-fps.gif
            new file mode 100644
            index 0000000000..296bdc8b3a
            Binary files /dev/null and b/dist/assets/learn/performance/images/editor-show-fps.gif differ
            diff --git a/dist/assets/learn/performance/images/resizing-comparison.png b/dist/assets/learn/performance/images/resizing-comparison.png
            new file mode 100644
            index 0000000000..5a31036dfc
            Binary files /dev/null and b/dist/assets/learn/performance/images/resizing-comparison.png differ
            diff --git a/dist/assets/learn/performance/images/timeline.png b/dist/assets/learn/performance/images/timeline.png
            new file mode 100644
            index 0000000000..b7a9901f1c
            Binary files /dev/null and b/dist/assets/learn/performance/images/timeline.png differ
            diff --git a/dist/assets/learn/program-flow/images/clouds.jpg b/dist/assets/learn/program-flow/images/clouds.jpg
            new file mode 100644
            index 0000000000..8b308be288
            Binary files /dev/null and b/dist/assets/learn/program-flow/images/clouds.jpg differ
            diff --git a/dist/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.html b/dist/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.html
            new file mode 100644
            index 0000000000..84925bd2ae
            --- /dev/null
            +++ b/dist/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.html
            @@ -0,0 +1,10 @@
            +<!DOCTYPE html>
            +<head>
            +	<title>loadImage example</title>
            +	<script src="../../../js/p5.min.js"></script>
            +  	<script src="loadImage-example-1.js"></script>
            +</head>
            +<body>
            +
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.js b/dist/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.js
            new file mode 100644
            index 0000000000..39e0f67f48
            --- /dev/null
            +++ b/dist/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.js
            @@ -0,0 +1,11 @@
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.html b/dist/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.html
            new file mode 100644
            index 0000000000..853ff78469
            --- /dev/null
            +++ b/dist/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.html
            @@ -0,0 +1,10 @@
            +<!DOCTYPE html>
            +<head>
            +  <title>loadImage example</title>
            +	<script src="../../../js/p5.min.js"></script>
            +  	<script src="loadImage-example-2.js"></script>
            +</head>
            +<body>
            +
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.js b/dist/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.js
            new file mode 100644
            index 0000000000..68fb8bacad
            --- /dev/null
            +++ b/dist/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.js
            @@ -0,0 +1,14 @@
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.html b/dist/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.html
            new file mode 100644
            index 0000000000..35bc79feb3
            --- /dev/null
            +++ b/dist/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.html
            @@ -0,0 +1,10 @@
            +<!DOCTYPE html>
            +<head>
            +  <title>loadImage example</title>
            +	<script src="../../../js/p5.min.js"></script>
            +  	<script src="loadImage-example-3.js"></script>
            +</head>
            +<body>
            +
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.js b/dist/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.js
            new file mode 100644
            index 0000000000..a9e9f79cd4
            --- /dev/null
            +++ b/dist/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.js
            @@ -0,0 +1,13 @@
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            \ No newline at end of file
            diff --git a/dist/assets/learn/test-tutorial/embed.html b/dist/assets/learn/test-tutorial/embed.html
            new file mode 100644
            index 0000000000..61c562d6aa
            --- /dev/null
            +++ b/dist/assets/learn/test-tutorial/embed.html
            @@ -0,0 +1,15 @@
            +<!DOCTYPE html>
            +<head>
            +  <title>embedded example</title>
            +  <script src="../../js/p5.min.js"></script>
            +  <!-- uncomment lines below to include extra p5 libraries -->
            +  <!--<script src="../addons/p5.sound.js"></script>-->
            +  <script src="sketch.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +  <style> body {padding: 0; margin: 0;} </style>
            +</head>
            +
            +<body>
            +
            +</body>
            +</html>
            diff --git a/dist/assets/learn/test-tutorial/sketch.js b/dist/assets/learn/test-tutorial/sketch.js
            new file mode 100644
            index 0000000000..4550217a07
            --- /dev/null
            +++ b/dist/assets/learn/test-tutorial/sketch.js
            @@ -0,0 +1,204 @@
            +var angle = 360.0;
            +var x1 =200;
            +var y1 =350;
            +var d = 300;
            +
            +var x2 =350;
            +var y2 =200;
            +
            +var xx=0;
            +var yy=0;
            +var cx=380;
            +var cy=200;
            +
            +var tx = 20;
            +
            +var ty = 20;
            +
            +var aSlider;
            +
            +
            +function setup() {
            +  createCanvas(600, 400);
            +  smooth();
            +  noFill();
            +  aSlider= createSlider(0,360,60);
            +  aSlider.position(tx-5, ty+10);
            +  //put in the css width for the slider
            +  textFont("Georgia");
            +  smooth();
            +
            +}
            +
            +function draw(){
            +  background(255);
            +  stroke(200);
            +  strokeWeight(1);
            +  noFill();
            +  rect(10,105,170,275);
            +  axes();
            +  circle();
            +  x1y1();
            +  x2y2();
            +  arcCalc();
            +  calculations();
            +  trigCalcs();
            +
            +}
            +
            +function labels(){
            +  console.log("angle="+angle);
            +  if(angle==90||angle==0||angle==180||angle==270){
            +
            +  }else{
            +    stroke(0);
            +    fill(0);
            +    text("r",(x1+cx)/2+5,(cy+y1)/2+7);
            +    text("x",(x1+cx)/2,cy-5);
            +    text("y",x1-10,(y1+cy)/2);
            +  }
            +
            +}
            +
            +function calculations(){
            +  stroke(237,34,93);
            +  fill(237,34,93);
            +  //axis lables
            +  text("90",cx-5,85);
            +  text("\u03C0"+" / 2",cx-10,65);
            +  text("0",cx+d/2-10,cy-3);
            +  text("0",cx+d/2-25,cy-3);
            +  text("270",cx-10,cy+d/2-30);
            +  text("3 / 2 "+"\u03C0",cx-15,cy+d/2-10);
            +  text("180",cx-d/2+25,cy-3);
            +  text("\u03C0",cx-d/2+10,cy-3);
            +  //cartesian
            +  stroke(0);
            +  fill(0);
            +  text("(0,1)",cx-10,40);
            +  text("(1,0)",cx+d/2+10,cy-3);
            +  text("(-1,0)",cx-d/2-30,cy-3);
            +  text("(0,-1)",cx-10,cy+d/2+20);
            +  stroke(237,34,93);
            +  fill(237,34,93);
            +  textSize(13);
            +
            +  //key
            +  text("Change the angle:",tx,ty);
            +  text("angle = "+round(360-angle) + " degrees",tx,ty+50);
            +  text("angle = "+(radians(360-angle)/PI).toFixed(2) + " \u03C0 radians",tx,ty+70);
            +  stroke(0);
            +  fill(0);
            +  textSize(12);
            +  text("To calculate the coordinates",tx,ty+105);
            +  text("of the point:",tx,ty+120);
            +
            +
            +}
            +
            +function x1y1(){
            +  //calculate x1
            +  x1=d/2*cos(radians(angle))+cx;
            +  //calculate y1
            +  y1=d/2*sin(radians(angle))+cy;
            +
            +}
            +
            +function x2y2(){
            +  //curve
            +  noFill();
            +  //calculate x1
            +  x2=d/2*cos(radians(angle))+20;
            +  //calculate y1
            +  y2=d/2*sin(radians(angle))+20;
            +  stroke(200);
            +
            +}
            +
            +function arcCalc(){
            +  stroke(237,34,93);
            +  arc(cx, cy, 60, 60, radians(angle), 0+2*PI );
            +
            +}
            +
            +function trigCalcs(){
            +  var l =18;
            +  //lables for trig calculations
            +  text("r = 1",tx,ty+140);
            +
            +  text("C = A / H",tx,ty+170);
            +  text("A / H = C",tx,ty+170+l);
            +  text("x/r = cos(angle)",tx,ty+170+2*l);
            +  text("x/1 = cos("+(radians(360-angle)/PI).toFixed(2) +" \u03C0)",tx,ty+170+3*l);
            +  xx =(cos(radians(angle)).toFixed(2));
            +  text("x = "+xx,tx,ty+170+4*l);
            +  text("S = O / A",tx,ty+170+6*l);
            +  text("O / A = S",tx,ty+170+7*l);
            +  text("y/r = sin(angle)",tx,ty+170+8*l);
            +  text("y/1 = sin("+(radians(360-angle)/PI).toFixed(2) +" \u03C0)",tx,ty+170+9*l);
            +  yy = (-1*sin(radians(angle)).toFixed(2));
            +
            +
            +  text("y = "+yy,tx,ty+170+10*l);
            +}
            +
            +function circle(){
            +  //draw circle and triangle stuff
            +  stroke(0);
            +  angle=(360-aSlider.value());
            +  noFill();
            +  //big circle
            +  ellipse(cx,cy,d,d);
            +
            +  strokeWeight(3);
            +  stroke(0);
            +  fill(237,34,93);
            +  line(x1,y1,x1,cy); //opposite
            +  line(x1,cy,cx,cy); //x
            +  line(cx,cy,x1,y1);
            +  strokeWeight(1);
            +  stroke(0);
            +  fill(237,34,93);
            +  ellipse(x1,y1,7,7);
            +  ellipseMode();
            +  var a;
            +  var b=0;
            +  var f=0;
            +  if(xx>0){
            +    textAlign(LEFT);
            +    a=1;
            +  }else{
            +    textAlign(RIGHT);
            +    a=-1;
            +  }
            +
            +  if(yy<-0.9){
            +    b=2;
            +  }
            +  else if(yy>0.9){
            +    b=-1;
            +  }
            +  if(xx==0||yy==0){
            +    f=0;
            +  }else{
            +    f=255
            +  }
            +
            +  stroke(0,f);
            +  fill(0,f);
            +  text("("+xx+","+yy+")",x1+5*a,y1+5*b);
            +  textAlign(LEFT);
            +  strokeWeight(1)
            +  labels();
            +  noFill();
            +
            +}
            +
            +function axes(){
            +  //axis
            +  stroke(0);
            +  //y
            +  line(cx,cy-d/2-20,cx,cy+d/2+20);
            +  //x
            +  line(cx-d/2-20,cy,cx+d/2+20,cy);
            +}
            diff --git a/dist/assets/learn/transformations/angles.png b/dist/assets/learn/transformations/angles.png
            new file mode 100644
            index 0000000000..d8b488bd7d
            Binary files /dev/null and b/dist/assets/learn/transformations/angles.png differ
            diff --git a/dist/assets/learn/trigonometry/images/hypotenuse.jpg b/dist/assets/learn/trigonometry/images/hypotenuse.jpg
            new file mode 100644
            index 0000000000..1d9deda1df
            Binary files /dev/null and b/dist/assets/learn/trigonometry/images/hypotenuse.jpg differ
            diff --git a/dist/assets/learn/trigonometry/images/polar.jpg b/dist/assets/learn/trigonometry/images/polar.jpg
            new file mode 100644
            index 0000000000..c9c723e523
            Binary files /dev/null and b/dist/assets/learn/trigonometry/images/polar.jpg differ
            diff --git a/dist/assets/learn/trigonometry/images/pythagoras.jpg b/dist/assets/learn/trigonometry/images/pythagoras.jpg
            new file mode 100644
            index 0000000000..331ac6c7fd
            Binary files /dev/null and b/dist/assets/learn/trigonometry/images/pythagoras.jpg differ
            diff --git a/dist/assets/learn/trigonometry/images/pythagoras1.jpg b/dist/assets/learn/trigonometry/images/pythagoras1.jpg
            new file mode 100644
            index 0000000000..c49d346ebb
            Binary files /dev/null and b/dist/assets/learn/trigonometry/images/pythagoras1.jpg differ
            diff --git a/dist/assets/learn/trigonometry/images/screen_coordinates.jpg b/dist/assets/learn/trigonometry/images/screen_coordinates.jpg
            new file mode 100644
            index 0000000000..fa93746620
            Binary files /dev/null and b/dist/assets/learn/trigonometry/images/screen_coordinates.jpg differ
            diff --git a/dist/assets/learn/trigonometry/images/sohcahtoa.jpg b/dist/assets/learn/trigonometry/images/sohcahtoa.jpg
            new file mode 100644
            index 0000000000..9ec544979a
            Binary files /dev/null and b/dist/assets/learn/trigonometry/images/sohcahtoa.jpg differ
            diff --git a/dist/assets/learn/trigonometry/sincoscurves/embed.html b/dist/assets/learn/trigonometry/sincoscurves/embed.html
            new file mode 100644
            index 0000000000..ce926f1f8b
            --- /dev/null
            +++ b/dist/assets/learn/trigonometry/sincoscurves/embed.html
            @@ -0,0 +1,14 @@
            +<!DOCTYPE html>
            +<head>
            +  <title>sin cos curves</title>
            +  <script src="http://www.courses.tegabrain.com/PVA15/wp-content/uploads/2015/10/p5.min_.js"></script>
            +  <!-- uncomment lines below to include extra p5 libraries -->
            +  <!--<script src="../addons/p5.sound.js"></script>-->
            +  <script src="http://www.courses.tegabrain.com/PVA15/wp-content/uploads/2015/10/sketch.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +  <style> body {padding: 0; margin: 0;} </style>
            +</head>
            +
            +<body>
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/learn/trigonometry/sincoscurves/embed1.html b/dist/assets/learn/trigonometry/sincoscurves/embed1.html
            new file mode 100644
            index 0000000000..ccd4be44c3
            --- /dev/null
            +++ b/dist/assets/learn/trigonometry/sincoscurves/embed1.html
            @@ -0,0 +1,14 @@
            +<!DOCTYPE html>
            +<head>
            +  <title>sin cos curves</title>
            +  <script src="http://www.courses.tegabrain.com/PVA15/wp-content/uploads/2015/10/p5min.js"></script>
            +  <!-- uncomment lines below to include extra p5 libraries -->
            +  <!--<script src="../addons/p5.sound.js"></script>-->
            +  <script src="http://www.courses.tegabrain.com/PVA15/wp-content/uploads/2015/10/sketch.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +  <style> body {padding: 0; margin: 0;} </style>
            +</head>
            +
            +<body>
            +</body>
            +</html>
            diff --git a/dist/assets/learn/trigonometry/sincoscurves/sin_curve.js b/dist/assets/learn/trigonometry/sincoscurves/sin_curve.js
            new file mode 100644
            index 0000000000..299eee0316
            --- /dev/null
            +++ b/dist/assets/learn/trigonometry/sincoscurves/sin_curve.js
            @@ -0,0 +1,240 @@
            +var angle = 360.0;
            +var x1 =200;
            +var y1 =350;
            +var d = 180;
            +
            +var x2 =350;
            +var y2 =200;
            +
            +var cx=200;
            +var cy=200;
            +
            +var f=1;
            +var f2 = 2;
            +
            +var p=0;
            +//axis margins
            +var ax = 80;
            +var ay = 80;
            +
            +var play = 1;
            +
            +var ex =465;
            +var ey =480;
            +
            +
            +function setup() {
            +
            +  createCanvas(800, 750);
            +  textFont("Georgia");
            +  smooth();
            +  noFill();
            +  rect(0, 0, width-1, height-1);
            +}
            +
            +function draw() {
            +  background(255);
            +  buttons();
            +  greyGuides();
            +  circle();
            +  pointCalcs();
            +  track();
            +  circleEllipses();
            +  waves();
            +  circleLabels();
            +
            +  bgLabels();
            +  pLabels();
            +  console.log("p="+p);
            +  console.log("angle="+angle);
            +
            +}
            +
            +function buttons(){
            +  stroke(0);
            +  //labels
            +
            +  //button
            +  fill(237,34,93);
            +  ellipse(ex,ey,30,30);
            +
            +  stroke(255);
            +  fill(255);
            +
            +
            +
            +  if(play===1){
            +    angle=angle-f;
            +    text("II",ex-4,ey+4);
            +  }else{
            +    text(">",ex-4,ey+4);
            +    stroke(255);
            +
            +  }
            +
            +}
            +
            +
            +function waves(){
            +  stroke(237,34,93);
            +  fill(237,34,93);
            +
            +  //bouncing ellipses
            +
            +  ellipse(cx + d/2+p, y1, 5,5); // sin ball
            +  ellipse(x1,cy+p+d/2, 5,5); // cos ball
            +
            +
            +  angle2=0;
            +  stroke(237,34,93);
            +  for(var i=0;i<p;i++){
            +
            +
            +    px2 = cx + cos(radians(angle2))*(d/2);
            +    py2 = cy + sin(radians(angle2))*(d/2);
            +    //sin
            +    point(cx+d/2+i, py2);
            +    //cos
            +    point(px2,cy+i+d/2);
            +    angle2 =angle2- f2;
            +
            +
            +  }
            +
            +
            +  p=180-(angle/2);
            +
            +  if(angle<-360){
            +
            +    angle=360.0;
            +  }
            +
            +}
            +
            +function circleEllipses(){
            +  fill(237,34,93);
            +  stroke(0);
            +  //circle ellipse
            +  ellipse(cx,cy,5,5);
            +  ellipse(x1,y1,5,5);
            +}
            +
            +function circleLabels(){
            +
            +  stroke(0);
            +  fill(0);
            +
            +  //labels
            +  text("90",cx-5,cy-d/2-20);
            +  text("\u03C0"+" / 2",cx-10,cy-d/2-40);
            +  text("0",cx+d/2+20,cy+5);
            +  text("0",cx+d/2+5,cy+5);
            +  text("270",cx-10,cy+d/2+20);
            +  text("3 / 2 "+"\u03C0",cx-15,cy+d/2+40);
            +  text("180",cx-d/2-30,cy+5);
            +  text("\u03C0",cx-d/2-45,cy+5);
            +
            +}
            +function pointCalcs(){
            +
            +  //calculate x1
            +  x1=d/2*cos(radians(angle))+cx;
            +  //calculate y1
            +  y1=d/2*sin(radians(angle))+cy;
            +
            +
            +}
            +
            +function greyGuides(){
            +  stroke(220);
            +  //guide lines
            +  line(cx-d/2,cy,cx-d/2,cy+2.5*d);
            +  line(cx+d/2,cy,cx+d/2,cy+2.5*d);
            +
            +  line(cx,cy,cx,cy+2.5*d);
            +  line(cx,cy-d/2,cx+450,cy-d/2);
            +  line(cx,cy+d/2,cx+450,cy+d/2);
            +  line(cx,cy,cx+450,cy);
            +
            +  //angle lines
            +  //cos
            +  line(cx-d/2,cy+d/2,cx+d/2,cy+d/2);
            +  line(cx-d/2,cy+3*d/2,cx+d/2,cy+3*d/2);
            +  line(cx-d/2,cy+2.5*d,cx+d/2,cy+2.5*d);
            +  //sin
            +  line(cx+d*0.5,cy-d/2,cx+d*0.5,cy+d/2);
            +  line(cx+d*1.5,cy-d/2,cx+d*1.5,cy+d/2);
            +  line(cx+d*2.5,cy-d/2,cx+d*2.5,cy+d/2);
            +
            +}
            +function circle(){
            +
            +  //axis
            +  stroke(0);
            +  line(cx-d/2,cy,cx+d/2,cy);
            +  line(cx,cy-d/2,cx,cy+d/2);
            +  noFill();
            +  //big circle
            +  ellipse(cx,cy,d,d);
            +}
            +
            +function pLabels(){
            +  stroke(237,34,93);
            +  fill(237,34,93);
            +  textSize(14);
            +  //key
            +  text("angle = "+round(360-angle) + " degrees",width-350,height-210);
            +  text("angle = "+radians(360-angle).toFixed(2) + " radians",width-350,height-180);
            +  text("cos(angle) = "+((x1-cx)/(d/2)).toFixed(2),width-350,height-150);
            +  text("sin(angle) = "+(-(y1-cy)/(d/2)).toFixed(2) ,width-350,height-120);
            +
            +}
            +
            +function track(){
            +
            +  fill(0);
            +  stroke(200);
            +  line(cx,cy,x1,y1)
            +  line(x1,y1,cx + d/2+p, y1);//sin tracker
            +  line(x1,y1,x1,cy+p+d/2);//cos tracker
            +
            +}
            +
            +function bgLabels(){
            +  stroke(200);
            +  fill(200);
            +  //1 and -1 for cos
            +  text("1",cx+d/2-3,cy+2.5*d+15);
            +  text("0",cx-3,cy+2.5*d+15);
            +  text("-1",cx-d/2-3,cy+2.5*d+15);
            +
            +  //1 and -1 for sin
            +  text("-1",cx+450+15,cy+d/2-3);
            +  text("0",cx+450+15,cy-3);
            +  text("1",cx+450+15,cy-d/2+5);
            +
            +
            +  //axis labels sine
            +  stroke(200);
            +  text("angle",d/2+370,80);
            +  text("0",d/2+200,100);
            +  text("\u03C0",d/2+380,100);
            +  text("2"+"\u03C0",d/2+550,100);
            +
            +  //axis labels cos
            +  text("angle",30,300+d);
            +  text("0",90,300);
            +  text("\u03C0",90,d+300);
            +  text("2"+"\u03C0",90,cy+2.5*d);
            +
            +
            +  text("cos(angle)",170,cy+2.5*d+30);
            +  text("sin(angle)",cy+360+130,200);
            +}
            +
            +function mousePressed() {
            +  if(dist(mouseX,mouseY,ex,ey)<30){
            +    play=play*-1;
            +  }
            +
            +}
            diff --git a/dist/assets/learn/trigonometry/unitCircle/embed.html b/dist/assets/learn/trigonometry/unitCircle/embed.html
            new file mode 100644
            index 0000000000..432db33ba7
            --- /dev/null
            +++ b/dist/assets/learn/trigonometry/unitCircle/embed.html
            @@ -0,0 +1,14 @@
            +<!DOCTYPE html>
            +<head>
            +  <title>sin cos curves</title>
            +  <script src="../../../js/p5.min.js"></script>
            +  <!-- uncomment lines below to include extra p5 libraries -->
            +  <!--<script src="../addons/p5.sound.js"></script>-->
            +  <script src="sketch.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +  <style> body {padding: 0; margin: 0;} </style>
            +</head>
            +
            +<body>
            +</body>
            +</html>
            diff --git a/dist/assets/learn/trigonometry/unitCircle/sketch.js b/dist/assets/learn/trigonometry/unitCircle/sketch.js
            new file mode 100644
            index 0000000000..4550217a07
            --- /dev/null
            +++ b/dist/assets/learn/trigonometry/unitCircle/sketch.js
            @@ -0,0 +1,204 @@
            +var angle = 360.0;
            +var x1 =200;
            +var y1 =350;
            +var d = 300;
            +
            +var x2 =350;
            +var y2 =200;
            +
            +var xx=0;
            +var yy=0;
            +var cx=380;
            +var cy=200;
            +
            +var tx = 20;
            +
            +var ty = 20;
            +
            +var aSlider;
            +
            +
            +function setup() {
            +  createCanvas(600, 400);
            +  smooth();
            +  noFill();
            +  aSlider= createSlider(0,360,60);
            +  aSlider.position(tx-5, ty+10);
            +  //put in the css width for the slider
            +  textFont("Georgia");
            +  smooth();
            +
            +}
            +
            +function draw(){
            +  background(255);
            +  stroke(200);
            +  strokeWeight(1);
            +  noFill();
            +  rect(10,105,170,275);
            +  axes();
            +  circle();
            +  x1y1();
            +  x2y2();
            +  arcCalc();
            +  calculations();
            +  trigCalcs();
            +
            +}
            +
            +function labels(){
            +  console.log("angle="+angle);
            +  if(angle==90||angle==0||angle==180||angle==270){
            +
            +  }else{
            +    stroke(0);
            +    fill(0);
            +    text("r",(x1+cx)/2+5,(cy+y1)/2+7);
            +    text("x",(x1+cx)/2,cy-5);
            +    text("y",x1-10,(y1+cy)/2);
            +  }
            +
            +}
            +
            +function calculations(){
            +  stroke(237,34,93);
            +  fill(237,34,93);
            +  //axis lables
            +  text("90",cx-5,85);
            +  text("\u03C0"+" / 2",cx-10,65);
            +  text("0",cx+d/2-10,cy-3);
            +  text("0",cx+d/2-25,cy-3);
            +  text("270",cx-10,cy+d/2-30);
            +  text("3 / 2 "+"\u03C0",cx-15,cy+d/2-10);
            +  text("180",cx-d/2+25,cy-3);
            +  text("\u03C0",cx-d/2+10,cy-3);
            +  //cartesian
            +  stroke(0);
            +  fill(0);
            +  text("(0,1)",cx-10,40);
            +  text("(1,0)",cx+d/2+10,cy-3);
            +  text("(-1,0)",cx-d/2-30,cy-3);
            +  text("(0,-1)",cx-10,cy+d/2+20);
            +  stroke(237,34,93);
            +  fill(237,34,93);
            +  textSize(13);
            +
            +  //key
            +  text("Change the angle:",tx,ty);
            +  text("angle = "+round(360-angle) + " degrees",tx,ty+50);
            +  text("angle = "+(radians(360-angle)/PI).toFixed(2) + " \u03C0 radians",tx,ty+70);
            +  stroke(0);
            +  fill(0);
            +  textSize(12);
            +  text("To calculate the coordinates",tx,ty+105);
            +  text("of the point:",tx,ty+120);
            +
            +
            +}
            +
            +function x1y1(){
            +  //calculate x1
            +  x1=d/2*cos(radians(angle))+cx;
            +  //calculate y1
            +  y1=d/2*sin(radians(angle))+cy;
            +
            +}
            +
            +function x2y2(){
            +  //curve
            +  noFill();
            +  //calculate x1
            +  x2=d/2*cos(radians(angle))+20;
            +  //calculate y1
            +  y2=d/2*sin(radians(angle))+20;
            +  stroke(200);
            +
            +}
            +
            +function arcCalc(){
            +  stroke(237,34,93);
            +  arc(cx, cy, 60, 60, radians(angle), 0+2*PI );
            +
            +}
            +
            +function trigCalcs(){
            +  var l =18;
            +  //lables for trig calculations
            +  text("r = 1",tx,ty+140);
            +
            +  text("C = A / H",tx,ty+170);
            +  text("A / H = C",tx,ty+170+l);
            +  text("x/r = cos(angle)",tx,ty+170+2*l);
            +  text("x/1 = cos("+(radians(360-angle)/PI).toFixed(2) +" \u03C0)",tx,ty+170+3*l);
            +  xx =(cos(radians(angle)).toFixed(2));
            +  text("x = "+xx,tx,ty+170+4*l);
            +  text("S = O / A",tx,ty+170+6*l);
            +  text("O / A = S",tx,ty+170+7*l);
            +  text("y/r = sin(angle)",tx,ty+170+8*l);
            +  text("y/1 = sin("+(radians(360-angle)/PI).toFixed(2) +" \u03C0)",tx,ty+170+9*l);
            +  yy = (-1*sin(radians(angle)).toFixed(2));
            +
            +
            +  text("y = "+yy,tx,ty+170+10*l);
            +}
            +
            +function circle(){
            +  //draw circle and triangle stuff
            +  stroke(0);
            +  angle=(360-aSlider.value());
            +  noFill();
            +  //big circle
            +  ellipse(cx,cy,d,d);
            +
            +  strokeWeight(3);
            +  stroke(0);
            +  fill(237,34,93);
            +  line(x1,y1,x1,cy); //opposite
            +  line(x1,cy,cx,cy); //x
            +  line(cx,cy,x1,y1);
            +  strokeWeight(1);
            +  stroke(0);
            +  fill(237,34,93);
            +  ellipse(x1,y1,7,7);
            +  ellipseMode();
            +  var a;
            +  var b=0;
            +  var f=0;
            +  if(xx>0){
            +    textAlign(LEFT);
            +    a=1;
            +  }else{
            +    textAlign(RIGHT);
            +    a=-1;
            +  }
            +
            +  if(yy<-0.9){
            +    b=2;
            +  }
            +  else if(yy>0.9){
            +    b=-1;
            +  }
            +  if(xx==0||yy==0){
            +    f=0;
            +  }else{
            +    f=255
            +  }
            +
            +  stroke(0,f);
            +  fill(0,f);
            +  text("("+xx+","+yy+")",x1+5*a,y1+5*b);
            +  textAlign(LEFT);
            +  strokeWeight(1)
            +  labels();
            +  noFill();
            +
            +}
            +
            +function axes(){
            +  //axis
            +  stroke(0);
            +  //y
            +  line(cx,cy-d/2-20,cx,cy+d/2+20);
            +  //x
            +  line(cx-d/2-20,cy,cx+d/2+20,cy);
            +}
            diff --git a/dist/assets/learn/tutorial-guide/images/screenshot-1.png b/dist/assets/learn/tutorial-guide/images/screenshot-1.png
            new file mode 100644
            index 0000000000..22f20077b0
            Binary files /dev/null and b/dist/assets/learn/tutorial-guide/images/screenshot-1.png differ
            diff --git a/dist/assets/learn/tutorial-guide/images/screenshot-2.png b/dist/assets/learn/tutorial-guide/images/screenshot-2.png
            new file mode 100644
            index 0000000000..f717e2984b
            Binary files /dev/null and b/dist/assets/learn/tutorial-guide/images/screenshot-2.png differ
            diff --git a/dist/assets/learn/tutorial-guide/images/screenshot-3.png b/dist/assets/learn/tutorial-guide/images/screenshot-3.png
            new file mode 100644
            index 0000000000..f26e40cb14
            Binary files /dev/null and b/dist/assets/learn/tutorial-guide/images/screenshot-3.png differ
            diff --git a/dist/assets/learn/tutorial-guide/images/screenshot-4.png b/dist/assets/learn/tutorial-guide/images/screenshot-4.png
            new file mode 100644
            index 0000000000..46c27ab50e
            Binary files /dev/null and b/dist/assets/learn/tutorial-guide/images/screenshot-4.png differ
            diff --git a/dist/assets/p5_featured/15May_AV/image/droplet.png b/dist/assets/p5_featured/15May_AV/image/droplet.png
            new file mode 100644
            index 0000000000..a82de59c08
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/image/droplet.png differ
            diff --git a/dist/assets/p5_featured/15May_AV/image/logo.png b/dist/assets/p5_featured/15May_AV/image/logo.png
            new file mode 100644
            index 0000000000..debddfa152
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/image/logo.png differ
            diff --git a/dist/assets/p5_featured/15May_AV/index.html b/dist/assets/p5_featured/15May_AV/index.html
            new file mode 100644
            index 0000000000..11ca8a31d3
            --- /dev/null
            +++ b/dist/assets/p5_featured/15May_AV/index.html
            @@ -0,0 +1,184 @@
            +<!DOCTYPE html>
            +	<head>
            +		<title></title>
            +		<script src="src/Tone.js"></script>
            +        <script src="src/Player.js"></script>
            +        <script src="src/Player02.js"></script>
            +        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.2/p5.min.js"></script>
            +        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.2/addons/p5.dom.min.js"></script>
            +        <script src="src/Splash.js"></script>
            +        <script src="src/SplashSystem.js"></script>
            +        <script src="src/Visualizer.js"></script>
            +        
            +        <!-- to load font -->
            +        <link type="text/css" rel="stylesheet" href="http://fonts.googleapis.com/css?family=Abel|Inconsolata:400,700&amp;nftmvh" media="all"> 
            +        
            +        <style type="text/css">
            +            body{
            +                margin: 0px;
            +                background-color: #fafafa;
            +                font-family: 'Inconsolata', "Courier New", Courier, monospace, "Times New Roman", Times, serif;
            +                font-size : 10px;
            +            }
            +            
            +            #textarea{
            +                font-family: 'Inconsolata', "Courier New", Courier, monospace, "Times New Roman", Times, serif;
            +                vertical-align: text-top;
            +                position: fixed;
            +                border : 0px;
            +                opacity: 0.7;
            +                width : 400px;
            +                height: 400px;
            +                top: 160px;
            +                left: 280px;
            +                z-index: 1;
            +            }
            +            #textarea:focus { 
            +                outline: none !important;
            +            }
            +            
            +            #p5Canvas {
            +                margin: 0px;
            +                position: absolute;
            +                top : 0px;
            +                left : 0px;
            +                z-index: -1;
            +            }
            +            #logo {
            +                position: fixed; 
            +                top: 20px;
            +                left: 383px;
            +                z-index: 1;
            +               
            +            }
            +            #footer {
            +                color: #aaa;
            +                position:fixed;
            +                text-align: center;
            +                left: 255px;
            +                bottom: 10px; 
            +               
            +            }
            +            #footer a {
            +                color: #aaa;
            +            }
            +            #footer a:hover {
            +                color: #aaa;
            +                text-decoration: line-through;
            +            }
            +        </style>
            +	</head>
            +	<body>
            +		<script>
            +            //get visualizer object
            +            var mVisualizers = [];
            +            var maxNumVisualizers = 7;
            +            
            +            for(var i = 0; i < maxNumVisualizers; i ++){
            +                mVisualizers[i] = new Visualizer();
            +            }
            +            
            +            function setup(){
            +                var VisualizerWidth = mVisualizers[0].returnWindowWidth();
            +                var VisualizerHeight = mVisualizers[0].returnWindowHeight();
            +                canvas = createCanvas(VisualizerWidth, VisualizerHeight);
            +                canvas.id("p5Canvas");
            +                frameRate(60);
            +                angleMode(DEGREES);
            +                
            +                for(var i = 0; i < maxNumVisualizers; i ++){
            +                    mVisualizers[i].setup();
            +                }
            +            };
            +
            +            function draw(){
            +                clear();
            +                for(var i = 0; i < maxNumVisualizers; i ++){
            +                    mVisualizers[i].update();
            +                    mVisualizers[i].draw();
            +                    
            +                    if( mVisualizers[i].returnTrigger() ){
            +                        // console.log("mVisualizers[i].returnTrigger() : " + mVisualizers[i].returnTrigger());
            +                        
            +                        var note = mPlayer.playRain();
            +                        note.start();
            +                    }
            +                }
            +            }; 
            +            
            +            
            +            
            +            
            +            //create class object
            +            var mPlayer = new Player02();
            +            mPlayer.whiteNoise();
            +            mPlayer.preSetting();
            +            
            +            Tone.Buffer.onload = function(){};
            +
            +            //when you type something then excute keyIncreas()
            +            document.onkeyup = keyIncrease;
            +
            +            var keyCount  = 0;
            +            var newInterval = 1;
            +
            +            function keyIncrease(event){
            +                //when you type something then this function will be excuted and then make keyCount increase
            +                keyCount += 3;
            +
            +                //set maximum of keyCount
            +                if(keyCount > 100){
            +                    keyCount = 100;
            +                }
            +
            +                //typewritter
            +                var key = event.keyCode;
            +
            +                if( key == 32 && Tone.Buffer.allLoaded){
            +                    var note = mPlayer.playKeyReturn();
            +                    note.start();
            +                } else if (key == 13 && Tone.Buffer.allLoaded){
            +                    var note = mPlayer.playKeySpace();
            +                    note.start();
            +                } else if (Tone.Buffer.allLoaded){
            +                    var note = mPlayer.playKeyStroke();
            +                    note.start();
            +                }
            +            }
            +
            +            //it will excute keyDecrease() every 50ms
            +            setInterval(keyDecrease, 50);
            +
            +            function keyDecrease(){
            +                //every 50ms, keyCount decreased
            +                keyCount -= 1;
            +
            +                //set minimun of keyCount
            +                if(keyCount < 0){
            +                    keyCount = 0;
            +                }
            +
            +                //remap keyCount to newInterval, this variable will have range of values between 0.15 to 1.00	
            +                newInterval = Math.abs(0.85 - keyCount * 0.01 + 0.15);
            +                if(newInterval < 0.15){
            +                    //just in case..
            +                    newInterval = 0.15;
            +                }
            +                
            +                for(var i = 0; i < maxNumVisualizers; i ++){
            +                    mVisualizers[i].getNewInterval(newInterval);
            +                }
            +            }
            +            
            +            
            +            //html
            +            function resetTextarea(){
            +                document.getElementById('textarea').value = ' ';
            +            }
            +		</script>
            +        
            +        <!-- <div id="logo"><img src="../image/logo.png"></div>
            +        <textarea id="textarea" onfocus="resetTextarea()" >Type what you feel with Interactive rainy sound. </textarea>
            +        <div id="footer">Interactive Music @ITP 2015 Spring / Javascript/HTML/CSS/TONE.js/P5.js / <a href =" http://kimsehyun.kr" target="_blank">http://kimsehyun.kr</a></div> -->
            +	</body>
            +</html>
            diff --git a/dist/assets/p5_featured/15May_AV/samples/keyReturn.wav b/dist/assets/p5_featured/15May_AV/samples/keyReturn.wav
            new file mode 100644
            index 0000000000..bdca905da7
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/samples/keyReturn.wav differ
            diff --git a/dist/assets/p5_featured/15May_AV/samples/keySpace.wav b/dist/assets/p5_featured/15May_AV/samples/keySpace.wav
            new file mode 100644
            index 0000000000..132b8d1a74
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/samples/keySpace.wav differ
            diff --git a/dist/assets/p5_featured/15May_AV/samples/keyStroke.wav b/dist/assets/p5_featured/15May_AV/samples/keyStroke.wav
            new file mode 100644
            index 0000000000..3f4d03ac7f
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/samples/keyStroke.wav differ
            diff --git a/dist/assets/p5_featured/15May_AV/samples/rain01.wav b/dist/assets/p5_featured/15May_AV/samples/rain01.wav
            new file mode 100644
            index 0000000000..4642dc04c3
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/samples/rain01.wav differ
            diff --git a/dist/assets/p5_featured/15May_AV/samples/rain02.wav b/dist/assets/p5_featured/15May_AV/samples/rain02.wav
            new file mode 100644
            index 0000000000..bdd0556dc7
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/samples/rain02.wav differ
            diff --git a/dist/assets/p5_featured/15May_AV/samples/rain03.wav b/dist/assets/p5_featured/15May_AV/samples/rain03.wav
            new file mode 100644
            index 0000000000..a8406a092b
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/samples/rain03.wav differ
            diff --git a/dist/assets/p5_featured/15May_AV/samples/rain04.wav b/dist/assets/p5_featured/15May_AV/samples/rain04.wav
            new file mode 100644
            index 0000000000..3f9a313a1f
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/samples/rain04.wav differ
            diff --git a/dist/assets/p5_featured/15May_AV/samples/rain05.wav b/dist/assets/p5_featured/15May_AV/samples/rain05.wav
            new file mode 100644
            index 0000000000..ea4c1e17a8
            Binary files /dev/null and b/dist/assets/p5_featured/15May_AV/samples/rain05.wav differ
            diff --git a/dist/assets/p5_featured/15May_AV/src/Player.js b/dist/assets/p5_featured/15May_AV/src/Player.js
            new file mode 100644
            index 0000000000..86e87a0124
            --- /dev/null
            +++ b/dist/assets/p5_featured/15May_AV/src/Player.js
            @@ -0,0 +1,126 @@
            +
            +var Player = function(){
            +    this.noise;
            +    this.feedbackDelay;
            +    
            +    this.obj = {};
            +
            +    this.newInterval = 1.0;
            +
            +    //load players
            +    this.rain01 = new Tone.Player("samples/rain01.wav").toMaster();
            +    this.rain02 = new Tone.Player("samples/rain02.wav").toMaster();
            +    this.rain03 = new Tone.Player("samples/rain03.wav").toMaster();
            +    this.rain04 = new Tone.Player("samples/rain04.wav").toMaster();
            +    this.rain05 = new Tone.Player("samples/rain05.wav").toMaster();
            +    
            +    //get players to array
            +    this.rains = [this.rain01, this.rain02, this.rain03, this.rain04, this.rain05];
            +    
            +    //keystroke
            +    this.keyReturn = new Tone.Player("samples/keyReturn.wav").toMaster();
            +    this.keySpace = new Tone.Player("samples/keySpace.wav").toMaster();
            +    this.keyStroke = new Tone.Player("samples/keyStroke.wav").toMaster();
            +    
            +    //delay
            +    this.feedbackDelay = new Tone.PingPongDelay("16n");
            +};
            +
            +Player.prototype.whiteNoise = function()
            +{
            +    //declare white noise 
            +    this.noise = new Tone.Noise("white");
            +    this.noise.volume.value = -35;
            +
            +    //excute noise
            +    this.noise.toMaster();
            +    this.noise.start();
            +};
            +
            +Player.prototype.preSetting = function()
            +{
            +    //set retrigger 
            +    this.rain01.retrigger = true;
            +    this.rain02.retrigger = true;
            +    this.rain03.retrigger = true;
            +    this.rain04.retrigger = true;
            +    this.rain05.retrigger = true;
            +
            +    this.keyReturn.retrigger = true;
            +    this.keySpace.retrigger = true;
            +    this.keyStroke.retrigger = true;
            +
            +    //set master 'volume' and 'fadetime'
            +    // Tone.Master.setVolume(0, 0);
            +    this.keyReturn.volume.value = -15;
            +    this.keySpace.volume.value = -5;
            +    this.keyStroke.volume.value = -15;
            +    
            +    //set delay
            +    this.feedbackDelay.toMaster();	
            +    //60% feedback
            +    this.feedbackDelay.feedback.value = 0.3;
            +    this.feedbackDelay.wet.value = 0.03;
            +    //player
            +    this.rain01.connect(this.feedbackDelay);
            +    this.rain02.connect(this.feedbackDelay);
            +    this.rain03.connect(this.feedbackDelay);
            +    this.rain04.connect(this.feedbackDelay);
            +    this.rain05.connect(this.feedbackDelay);
            +    //noise
            +    this.noise.connect(this.feedbackDelay);
            +};
            +
            +Player.prototype.calInterval = function(time){
            +    this.t = time;
            +//    console.log("newInterval : " + newInterval + ", time : " + this.t);
            +    
            +    this.randRain = Math.floor(Math.random() * this.rains.length);
            +    this.note = this.rains[this.randRain];
            +
            +    //connections
            +    this.note.start(this.t);
            +//    console.log("cIntv");
            +    Tone.Transport.setTimeout(this.calInterval.bind(this), this.newInterval);  
            +};
            +
            +Player.prototype.play = function()
            +{   
            +    // plays with interval	
            +    // newInterval range would be from 0.15 to 1.00
            +    Tone.Transport.start();
            +    Tone.Transport.setTimeout(this.calInterval.bind(this), this.newInterval); 
            +
            +};
            +
            +Player.prototype.getNewInterval = function(newInterval){
            +    this.newInterval = newInterval; 
            +}
            +
            +Player.prototype.playKeyReturn = function()
            +{   
            +    return this.keyReturn;
            +};
            +
            +Player.prototype.playKeySpace = function()
            +{   
            +    return this.keySpace;
            +};
            +
            +Player.prototype.playKeyStroke = function()
            +{   
            +    return this.keyStroke;
            +};
            +
            +
            +
            +
            +
            +			
            +			
            +			
            +
            +
            +			
            +
            +			
            diff --git a/dist/assets/p5_featured/15May_AV/src/Player02.js b/dist/assets/p5_featured/15May_AV/src/Player02.js
            new file mode 100644
            index 0000000000..e538c4245f
            --- /dev/null
            +++ b/dist/assets/p5_featured/15May_AV/src/Player02.js
            @@ -0,0 +1,114 @@
            +/**
            + * @class  this class is supposed to playing rainy&typewriting sounds samples
            + *
            + * @constructor
            + * @param {number} [keys=88] the number of keys the piano has
            + * @param {string} [type="grand"] the type of piano that it is. 
            + */
            +var Player02 = function(){
            +    /**
            +	 * the number of keys the piano has
            +	 * @type {number}
            +	 */
            +    this.noise;
            +    this.feedbackDelay;
            +
            +    //load players
            +    this.rain01 = new Tone.Player("samples/rain01.wav").toMaster();
            +    this.rain02 = new Tone.Player("samples/rain02.wav").toMaster();
            +    this.rain03 = new Tone.Player("samples/rain03.wav").toMaster();
            +    this.rain04 = new Tone.Player("samples/rain04.wav").toMaster();
            +    this.rain05 = new Tone.Player("samples/rain05.wav").toMaster();
            +    
            +    //get players to array
            +    this.rains = [this.rain01, this.rain02, this.rain03, this.rain04, this.rain05];
            +    
            +    //keystroke
            +    this.keyReturn = new Tone.Player("samples/keyReturn.wav").toMaster();
            +    this.keySpace = new Tone.Player("samples/keySpace.wav").toMaster();
            +    this.keyStroke = new Tone.Player("samples/keyStroke.wav").toMaster();
            +    
            +    //delay
            +    this.feedbackDelay = new Tone.PingPongDelay("16n");
            +};
            +
            +Player02.prototype.whiteNoise = function()
            +{
            +    //declare white noise 
            +    this.noise = new Tone.Noise("white");
            +    this.noise.volume.value = -35;
            +
            +    //excute noise
            +    this.noise.toMaster();
            +    this.noise.start();
            +};
            +
            +Player02.prototype.preSetting = function()
            +{
            +    //set retrigger 
            +    this.rain01.retrigger = true;
            +    this.rain02.retrigger = true;
            +    this.rain03.retrigger = true;
            +    this.rain04.retrigger = true;
            +    this.rain05.retrigger = true;
            +
            +    this.keyReturn.retrigger = true;
            +    this.keySpace.retrigger = true;
            +    this.keyStroke.retrigger = true;
            +
            +    //set master 'volume' and 'fadetime'
            +    // Tone.Master.setVolume(0, 0);
            +    this.keyReturn.volume.value = -15;
            +    this.keySpace.volume.value = -5;
            +    this.keyStroke.volume.value = -15;
            +    
            +    //set delay
            +    this.feedbackDelay.toMaster();	
            +    //60% feedback
            +    this.feedbackDelay.feedback.value = 0.3;
            +    this.feedbackDelay.wet.value = 0.03;
            +    //player
            +    this.rain01.connect(this.feedbackDelay);
            +    this.rain02.connect(this.feedbackDelay);
            +    this.rain03.connect(this.feedbackDelay);
            +    this.rain04.connect(this.feedbackDelay);
            +    this.rain05.connect(this.feedbackDelay);
            +    //noise
            +    this.noise.connect(this.feedbackDelay);
            +};
            +
            +Player02.prototype.playRain = function()
            +{   
            +    this.randRain = Math.floor(Math.random() * this.rains.length);
            +    this.note = this.rains[this.randRain];
            +
            +    return this.note;
            +};
            +
            +Player02.prototype.playKeyReturn = function()
            +{   
            +    return this.keyReturn;
            +};
            +
            +Player02.prototype.playKeySpace = function()
            +{   
            +    return this.keySpace;
            +};
            +
            +Player02.prototype.playKeyStroke = function()
            +{   
            +    return this.keyStroke;
            +};
            +
            +
            +
            +
            +
            +			
            +			
            +			
            +
            +
            +			
            +
            +			
            diff --git a/dist/assets/p5_featured/15May_AV/src/Splash.js b/dist/assets/p5_featured/15May_AV/src/Splash.js
            new file mode 100644
            index 0000000000..ae035e96ec
            --- /dev/null
            +++ b/dist/assets/p5_featured/15May_AV/src/Splash.js
            @@ -0,0 +1,109 @@
            +/**
            + * @class  this class is supposed to make a splash object
            + *
            + * @constructor
            + * @param {float} [_x = 0]                                  from SplashSystem's constructor
            + * @param {float} [_y = 0]                                  from SplashSystem's constructor
            + * @param {float} [_force = random value between -1 to 1]   from SplashSystem's constructor
            + */
            +var Splash = function(_x, _y, _force){
            +    /**
            +	 * to remember the original location when it generates
            +	 * @type {p5.Vector}
            +	 */
            +    this.rootLoc = new p5.Vector(_x, _y);
            +    
            +    /**
            +	 * location of splash object
            +	 * @type {p5.Vector}
            +	 */
            +    this.loc = new p5.Vector(_x, _y);
            +    
            +    /**
            +	 * velocity of splash object, initial y value would be -5 to -10. 
            +     * x value will be coming from this.force
            +	 * @type {p5.Vector}
            +	 */
            +    this.vel = new p5.Vector(0, Math.random() * -5 - 5);
            +    
            +    /**
            +	 * force for splash object, it will give x value to velocity
            +	 * @type {p5.Vector}
            +	 */
            +    this.force = new p5.Vector(_force, 1);
            +    
            +    /**
            +	 * size for splash object, 1 to 5 
            +	 * @type {float}
            +	 */
            +    this.size = Math.random() * 4 + 1;
            +    
            +    /**
            +	 * if the boolean is true then splash object start to disappear in this.display function
            +	 * @type {boolean}
            +     * @type {float} variable for alpha 
            +	 */
            +    this.isDead = false;
            +    this.alpha = 255;
            +};
            +
            +/**
            + * excute this.update() and this.display()
            + */
            +Splash.prototype.render = function(){
            +    this.update();
            +    this.display();
            +};
            +
            +/**
            + * once splash object is disappeared and droplet hit the ground again then reset every variable to restart 
            + * @param {float} for loc.x 
            + * @param {float} for loc.y
            + * @param {float} for force.x 
            + */
            +Splash.prototype.reset = function(_x, _y, _force){
            +    this.rootLoc = new p5.Vector(_x, _y);
            +    this.loc = new p5.Vector(_x, _y);
            +    this.vel = new p5.Vector(0, Math.random() * -5 -5);
            +    this.force = new p5.Vector(_force, 1);
            +    this.size = Math.random() * 4;
            +    this.isDead = false;
            +    this.alpha = 255;
            +};
            +
            +/**
            + * update this object
            + * detect this object is dead or not 
            + */
            +Splash.prototype.update = function(){
            +    this.vel.add(this.force);
            +    this.loc.add(this.vel);
            +    
            +    this.force.x = 0;
            +    
            +    if(this.loc.y > this.rootLoc.y){
            +        this.isDead = true;
            +    }
            +     
            +};
            +
            +/**
            + * display this object
            + * when this object is dead, this object starts to disappear
            + */
            +Splash.prototype.display = function(){
            +    noStroke();
            +    
            +    if(!this.isDead){
            +        fill(51, 51, 51);
            +    } else {
            +        fill(51, 51, 51, this.alpha);
            +        this.alpha -= 60;
            +        
            +        if(this.alpha < 0){
            +            this.alpha = 0;
            +        }
            +    }
            +    
            +    ellipse(this.loc.x, this.loc.y, this.size, this.size);
            +};
            diff --git a/dist/assets/p5_featured/15May_AV/src/SplashSystem.js b/dist/assets/p5_featured/15May_AV/src/SplashSystem.js
            new file mode 100644
            index 0000000000..fb60cd85e7
            --- /dev/null
            +++ b/dist/assets/p5_featured/15May_AV/src/SplashSystem.js
            @@ -0,0 +1,23 @@
            +var SplashSystem = function(){
            +    this.mSplashes = [];
            +    
            +    this.randomForce = Math.random() * 2 - 1;
            +    
            +    this.mSplashesNum = 2;
            +    for(var i = 0; i < this.mSplashesNum; i++){
            +        this.mSplashes[i] = new Splash(0, 0, this.randomForce );
            +    }
            +};
            +
            +SplashSystem.prototype.reset = function(_x, _y){
            +    for(var i = 0; i < this.mSplashesNum; i++){
            +        this.randomForce = Math.random() * 2 - 1;
            +        this.mSplashes[i].reset(_x, _y, this.randomForce);
            +    }
            +};
            +
            +SplashSystem.prototype.render = function(){
            +    for(var i = 0; i < this.mSplashesNum; i++){
            +        this.mSplashes[i].render();
            +    }
            +};
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/15May_AV/src/Tone.js b/dist/assets/p5_featured/15May_AV/src/Tone.js
            new file mode 100644
            index 0000000000..1a1c102650
            --- /dev/null
            +++ b/dist/assets/p5_featured/15May_AV/src/Tone.js
            @@ -0,0 +1,14134 @@
            +(function (root) {
            +	"use strict";
            +	var Tone;
            +	//constructs the main Tone object
            +	function mainModule(func){
            +		Tone = func();
            +	}
            +	//invokes each of the modules with the main Tone object as the argument
            +	function toneModule(func){
            +		func(Tone);
            +	}
            +	
            +	/**
            +	 *  Tone.js
            +	 *  @author Yotam Mann
            +	 *  @license http://opensource.org/licenses/MIT MIT License
            +	 *  @copyright 2014-2015 Yotam Mann
            +	 */
            +	mainModule(function(){
            +
            +		
            +
            +		//////////////////////////////////////////////////////////////////////////
            +		//	WEB AUDIO CONTEXT
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		//borrowed from underscore.js
            +		function isUndef(val){
            +			return val === void 0;
            +		}
            +
            +		//borrowed from underscore.js
            +		function isFunction(val){
            +			return typeof val === "function";
            +		}
            +
            +		var audioContext;
            +
            +		//polyfill for AudioContext and OfflineAudioContext
            +		if (isUndef(window.AudioContext)){
            +			window.AudioContext = window.webkitAudioContext;
            +		} 
            +		if (isUndef(window.OfflineAudioContext)){
            +			window.OfflineAudioContext = window.webkitOfflineAudioContext;
            +		} 
            +
            +		if (!isUndef(AudioContext)){
            +			audioContext = new AudioContext();
            +		} else {
            +			throw new Error("Web Audio is not supported in this browser");
            +		}
            +
            +		//SHIMS////////////////////////////////////////////////////////////////////
            +
            +		if (!isFunction(AudioContext.prototype.createGain)){
            +			AudioContext.prototype.createGain = AudioContext.prototype.createGainNode;
            +		}
            +		if (!isFunction(AudioContext.prototype.createDelay)){
            +			AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode;
            +		}
            +		if (!isFunction(AudioContext.prototype.createPeriodicWave)){
            +			AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable;
            +		}
            +		if (!isFunction(AudioBufferSourceNode.prototype.start)){
            +			AudioBufferSourceNode.prototype.start = AudioBufferSourceNode.prototype.noteGrainOn;
            +		}
            +		if (!isFunction(AudioBufferSourceNode.prototype.stop)){
            +			AudioBufferSourceNode.prototype.stop = AudioBufferSourceNode.prototype.noteOff;
            +		}
            +		if (!isFunction(OscillatorNode.prototype.start)){
            +			OscillatorNode.prototype.start = OscillatorNode.prototype.noteOn;
            +		}
            +		if (!isFunction(OscillatorNode.prototype.stop)){
            +			OscillatorNode.prototype.stop = OscillatorNode.prototype.noteOff;	
            +		}
            +		if (!isFunction(OscillatorNode.prototype.setPeriodicWave)){
            +			OscillatorNode.prototype.setPeriodicWave = OscillatorNode.prototype.setWaveTable;	
            +		}
            +		//extend the connect function to include Tones
            +		AudioNode.prototype._nativeConnect = AudioNode.prototype.connect;
            +		AudioNode.prototype.connect = function(B, outNum, inNum){
            +			if (B.input){
            +				if (Array.isArray(B.input)){
            +					if (isUndef(inNum)){
            +						inNum = 0;
            +					}
            +					this.connect(B.input[inNum]);
            +				} else {
            +					this.connect(B.input, outNum, inNum);
            +				}
            +			} else {
            +				try {
            +					if (B instanceof AudioNode){
            +						this._nativeConnect(B, outNum, inNum);
            +					} else {
            +						this._nativeConnect(B, outNum);
            +					}
            +				} catch (e) {
            +					throw new Error("error connecting to node: "+B);
            +				}
            +			}
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	TONE
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  @class  Tone is the baseclass of all Tone Modules. 
            +		 *  @constructor
            +		 *  @alias Tone
            +		 *  @param {number} [inputs=1] the number of input nodes
            +		 *  @param {number} [outputs=1] the number of output nodes
            +		 */
            +		var Tone = function(inputs, outputs){
            +
            +			/**
            +			 *  the input node(s)
            +			 *  @type {GainNode|Array}
            +			 */
            +			if (isUndef(inputs) || inputs === 1){
            +				this.input = this.context.createGain();
            +			} else if (inputs > 1){
            +				this.input = new Array(inputs);
            +			}
            +
            +			/**
            +			 *  the output node(s)
            +			 *  @type {GainNode|Array}
            +			 */
            +			if (isUndef(outputs) || outputs === 1){
            +				this.output = this.context.createGain();
            +			} else if (outputs > 1){
            +				this.output = new Array(inputs);
            +			}
            +		};
            +
            +		/**
            +		 *  set the parameters at once
            +		 *  @param {Object} params
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.set = function(params){
            +			for (var attr in params){
            +				var param = this[attr];
            +				var value = params[attr];
            +				if (param instanceof Tone.Signal){
            +					param.value = value;
            +				} else if (param instanceof AudioParam){
            +					param.value = value;
            +				} else if (param instanceof Tone){
            +					param.set(value);
            +				} else {
            +					this[attr] = value;
            +				}
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  get a group of parameters
            +		 *  @param {Array=} params the parameters to get, otherwise will return 
            +		 *  					   all available.
            +		 */
            +		Tone.prototype.get = function(params){
            +			if (isUndef(params)){
            +				params = this._collectDefaults(this.constructor);
            +			}
            +			var ret = {};
            +			for (var i = 0; i < params.length; i++){
            +				var attr = params[i];
            +				var param = this[attr];
            +				if (param instanceof Tone.Signal){
            +					ret[attr] = param.value;
            +				} else if (param instanceof AudioParam){
            +					ret[attr] = param.value;
            +				} else if (param instanceof Tone){
            +					ret[attr] = param.get();
            +				} else if (!isFunction(param) && !isUndef(param)){
            +					ret[attr] = param;
            +				} 
            +			}
            +			return ret;
            +		};
            +
            +		/**
            +		 *  collect all of the default attributes in one
            +		 *  @private
            +		 *  @param {function} constr the constructor to find the defaults from
            +		 *  @return {Array} all of the attributes which belong to the class
            +		 */
            +		Tone.prototype._collectDefaults = function(constr){
            +			var ret = [];
            +			if (!isUndef(constr.defaults)){
            +				ret = Object.keys(constr.defaults);
            +			}
            +			if (!isUndef(constr._super)){
            +				ret = ret.concat(this._collectDefaults(constr._super));
            +			}
            +			return ret;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	CLASS VARS
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  A static pointer to the audio context
            +		 *  @type {AudioContext}
            +		 */
            +		Tone.context = audioContext;
            +
            +		/**
            +		 *  A static pointer to the audio context
            +		 *  @type {AudioContext}
            +		 */
            +		Tone.prototype.context = Tone.context;
            +
            +		/**
            +		 *  the default buffer size
            +		 *  @type {number}
            +		 *  @static
            +		 *  @const
            +		 */
            +		Tone.prototype.bufferSize = 2048;
            +
            +		/**
            +		 *  the delay time of a single buffer frame
            +		 *  @type {number}
            +		 *  @static
            +		 *  @const
            +		 */
            +		Tone.prototype.bufferTime = Tone.prototype.bufferSize / Tone.context.sampleRate;
            +		
            +		///////////////////////////////////////////////////////////////////////////
            +		//	CONNECTIONS
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  disconnect and dispose
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.dispose = function(){
            +			if (!this.isUndef(this.input)){
            +				if (this.input instanceof AudioNode){
            +					this.input.disconnect();
            +				} 
            +				this.input = null;
            +			}
            +			if (!this.isUndef(this.output)){
            +				if (this.output instanceof AudioNode){
            +					this.output.disconnect();
            +				} 
            +				this.output = null;
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  a silent connection to the DesinationNode
            +		 *  which will ensure that anything connected to it
            +		 *  will not be garbage collected
            +		 *  
            +		 *  @private
            +		 */
            +		var _silentNode = null;
            +
            +		/**
            +		 *  makes a connection to ensure that the node will not be garbage collected
            +		 *  until 'dispose' is explicitly called
            +		 *
            +		 *  use carefully. circumvents JS and WebAudio's normal Garbage Collection behavior
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.noGC = function(){
            +			this.output.connect(_silentNode);
            +			return this;
            +		};
            +
            +		AudioNode.prototype.noGC = function(){
            +			this.connect(_silentNode);
            +			return this;
            +		};
            +
            +		/**
            +		 *  connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode
            +		 *  @param  {Tone | AudioParam | AudioNode} unit 
            +		 *  @param {number} [outputNum=0] optionally which output to connect from
            +		 *  @param {number} [inputNum=0] optionally which input to connect to
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.connect = function(unit, outputNum, inputNum){
            +			if (Array.isArray(this.output)){
            +				outputNum = this.defaultArg(outputNum, 0);
            +				this.output[outputNum].connect(unit, 0, inputNum);
            +			} else {
            +				this.output.connect(unit, outputNum, inputNum);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  disconnect the output
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.disconnect = function(outputNum){
            +			if (Array.isArray(this.output)){
            +				outputNum = this.defaultArg(outputNum, 0);
            +				this.output[outputNum].disconnect();
            +			} else {
            +				this.output.disconnect();
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  connect together all of the arguments in series
            +		 *  @param {...AudioParam|Tone|AudioNode}
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.connectSeries = function(){
            +			if (arguments.length > 1){
            +				var currentUnit = arguments[0];
            +				for (var i = 1; i < arguments.length; i++){
            +					var toUnit = arguments[i];
            +					currentUnit.connect(toUnit);
            +					currentUnit = toUnit;
            +				}
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  fan out the connection from the first argument to the rest of the arguments
            +		 *  @param {...AudioParam|Tone|AudioNode}
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.connectParallel = function(){
            +			var connectFrom = arguments[0];
            +			if (arguments.length > 1){
            +				for (var i = 1; i < arguments.length; i++){
            +					var connectTo = arguments[i];
            +					connectFrom.connect(connectTo);
            +				}
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  connect the output of this node to the rest of the nodes in series.
            +		 *  @param {...AudioParam|Tone|AudioNode}
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.chain = function(){
            +			if (arguments.length > 0){
            +				var currentUnit = this;
            +				for (var i = 0; i < arguments.length; i++){
            +					var toUnit = arguments[i];
            +					currentUnit.connect(toUnit);
            +					currentUnit = toUnit;
            +				}
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  connect the output of this node to the rest of the nodes in parallel.
            +		 *  @param {...AudioParam|Tone|AudioNode}
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.fan = function(){
            +			if (arguments.length > 0){
            +				for (var i = 1; i < arguments.length; i++){
            +					this.connect(arguments[i]);
            +				}
            +			}
            +			return this;
            +		};
            +
            +		//give native nodes chain and fan methods
            +		AudioNode.prototype.chain = Tone.prototype.chain;
            +		AudioNode.prototype.fan = Tone.prototype.fan;
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	UTILITIES / HELPERS / MATHS
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  if a the given is undefined, use the fallback. 
            +		 *  if both given and fallback are objects, given
            +		 *  will be augmented with whatever properties it's
            +		 *  missing which are in fallback
            +		 *
            +		 *  warning: if object is self referential, it will go into an an 
            +		 *  infinite recursive loop. 
            +		 *  
            +		 *  @param  {*} given    
            +		 *  @param  {*} fallback 
            +		 *  @return {*}          
            +		 */
            +		Tone.prototype.defaultArg = function(given, fallback){
            +			if (typeof given === "object" && typeof fallback === "object"){
            +				var ret = {};
            +				//make a deep copy of the given object
            +				for (var givenProp in given) {
            +					ret[givenProp] = this.defaultArg(given[givenProp], given[givenProp]);
            +				}
            +				for (var prop in fallback) {
            +					ret[prop] = this.defaultArg(given[prop], fallback[prop]);
            +				}
            +				return ret;
            +			} else {
            +				return isUndef(given) ? fallback : given;
            +			}
            +		};
            +
            +		/**
            +		 *  returns the args as an options object with given arguments
            +		 *  mapped to the names provided. 
            +		 *
            +		 *  if the args given is an array containing an object, it is assumed
            +		 *  that that's already the options object and will just return it. 
            +		 *  
            +		 *  @param  {Array} values  the 'arguments' object of the function
            +		 *  @param  {Array.<string>} keys the names of the arguments as they
            +		 *                                 should appear in the options object
            +		 *  @param {Object=} defaults optional defaults to mixin to the returned 
            +		 *                            options object                              
            +		 *  @return {Object}       the options object with the names mapped to the arguments
            +		 */
            +		Tone.prototype.optionsObject = function(values, keys, defaults){
            +			var options = {};
            +			if (values.length === 1 && typeof values[0] === "object"){
            +				options = values[0];
            +			} else {
            +				for (var i = 0; i < keys.length; i++){
            +					options[keys[i]] = values[i];
            +				}
            +			}
            +			if (!this.isUndef(defaults)){
            +				return this.defaultArg(options, defaults);
            +			} else {
            +				return options;
            +			}
            +		};
            +
            +		/**
            +		 *  test if the arg is undefined
            +		 *  @param {*} arg the argument to test
            +		 *  @returns {boolean} true if the arg is undefined
            +		 *  @function
            +		 */
            +		Tone.prototype.isUndef = isUndef;
            +
            +		/**
            +		 *  test if the arg is a function
            +		 *  @param {*} arg the argument to test
            +		 *  @returns {boolean} true if the arg is a function
            +		 *  @function
            +		 */
            +		Tone.prototype.isFunction = isFunction;
            +
            +		/**
            +		 *  interpolate the input value (0-1) to be between outputMin and outputMax
            +		 *  @param  {number} input     
            +		 *  @param  {number} outputMin 
            +		 *  @param  {number} outputMax 
            +		 *  @return {number}           
            +		 */
            +		Tone.prototype.interpolate = function(input, outputMin, outputMax){
            +			return input*(outputMax - outputMin) + outputMin;
            +		};
            +
            +		/**
            +		 *  normalize the input to 0-1 from between inputMin to inputMax
            +		 *  @param  {number} input    
            +		 *  @param  {number} inputMin 
            +		 *  @param  {number} inputMax 
            +		 *  @return {number}          
            +		 */
            +		Tone.prototype.normalize = function(input, inputMin, inputMax){
            +			//make sure that min < max
            +			if (inputMin > inputMax){
            +				var tmp = inputMax;
            +				inputMax = inputMin;
            +				inputMin = tmp;
            +			} else if (inputMin == inputMax){
            +				return 0;
            +			}
            +			return (input - inputMin) / (inputMax - inputMin);
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		// GAIN CONVERSIONS
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  equal power gain scale
            +		 *  good for cross-fading
            +		 *  @param  {number} percent (0-1)
            +		 *  @return {number}         output gain (0-1)
            +		 */
            +		Tone.prototype.equalPowerScale = function(percent){
            +			var piFactor = 0.5 * Math.PI;
            +			return Math.sin(percent * piFactor);
            +		};
            +
            +		/**
            +		 *  @param  {number} gain (0-1)
            +		 *  @return {number}      gain (decibel scale but betwee 0-1)
            +		 */
            +		Tone.prototype.logScale = function(gain) {
            +			return  Math.max(this.normalize(this.gainToDb(gain), -100, 0), 0);
            +		};
            +
            +		/**
            +		 *  @param  {number} gain (0-1)
            +		 *  @return {number}      gain (decibel scale but betwee 0-1)
            +		 */
            +		Tone.prototype.expScale = function(gain) {
            +			return this.dbToGain(this.interpolate(gain, -100, 0));
            +		};
            +
            +		/**
            +		 *  convert db scale to gain scale (0-1)
            +		 *  @param  {number} db
            +		 *  @return {number}   
            +		 */
            +		Tone.prototype.dbToGain = function(db) {
            +			return Math.pow(2, db / 6);
            +		};
            +
            +		/**
            +		 *  convert gain scale to decibels
            +		 *  @param  {number} gain (0-1)
            +		 *  @return {number}   
            +		 */
            +		Tone.prototype.gainToDb = function(gain) {
            +			return  20 * (Math.log(gain) / Math.LN10);
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	TIMING
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  @return {number} the currentTime from the AudioContext
            +		 */
            +		Tone.prototype.now = function(){
            +			return this.context.currentTime;
            +		};
            +
            +		/**
            +		 *  convert a sample count to seconds
            +		 *  @param  {number} samples 
            +		 *  @return {number}         
            +		 */
            +		Tone.prototype.samplesToSeconds = function(samples){
            +			return samples / this.context.sampleRate;
            +		};
            +
            +		/**
            +		 *  convert a time into samples
            +		 *  
            +		 *  @param  {Tone.time} time
            +		 *  @return {number}         
            +		 */
            +		Tone.prototype.toSamples = function(time){
            +			var seconds = this.toSeconds(time);
            +			return Math.round(seconds * this.context.sampleRate);
            +		};
            +
            +		/**
            +		 *  convert time to seconds
            +		 *
            +		 *  this is a simplified version which only handles numbers and 
            +		 *  'now' relative numbers. If the Transport is included this 
            +		 *  method is overridden to include many other features including 
            +		 *  notationTime, Frequency, and transportTime
            +		 *  
            +		 *  @param  {number=} time 
            +		 *  @param {number=} now if passed in, this number will be 
            +		 *                       used for all 'now' relative timings
            +		 *  @return {number}   	seconds in the same timescale as the AudioContext
            +		 */
            +		Tone.prototype.toSeconds = function(time, now){
            +			now = this.defaultArg(now, this.now());
            +			if (typeof time === "number"){
            +				return time; //assuming that it's seconds
            +			} else if (typeof time === "string"){
            +				var plusTime = 0;
            +				if(time.charAt(0) === "+") {
            +					time = time.slice(1);	
            +					plusTime = now;			
            +				} 
            +				return parseFloat(time) + plusTime;
            +			} else {
            +				return now;
            +			}
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		// FREQUENCY CONVERSION
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  true if the input is in the format number+hz
            +		 *  i.e.: 10hz
            +		 *
            +		 *  @param {number} freq 
            +		 *  @return {boolean} 
            +		 *  @function
            +		 */
            +		Tone.prototype.isFrequency = (function(){
            +			var freqFormat = new RegExp(/\d*\.?\d+hz$/i);
            +			return function(freq){
            +				return freqFormat.test(freq);
            +			};
            +		})();
            +
            +		/**
            +		 *  convert a time to a frequency
            +		 *  defined in "Tone/core/Transport"
            +		 *  	
            +		 *  @param  {Tone.Frequency} time 
            +		 *  @return {number}      the time in hertz
            +		 */
            +		Tone.prototype.toFrequency = function(time){
            +			if (this.isFrequency(time)){
            +				return parseFloat(time);
            +			} else {
            +				return parseFloat(time);
            +			}
            +		};
            +
            +		/**
            +		 *  convert a frequency into seconds
            +		 *  accepts both numbers and strings 
            +		 *  	i.e. 10hz or 10 both equal .1
            +		 *  
            +		 *  @param  {number|string} freq 
            +		 *  @return {number}      
            +		 */
            +		Tone.prototype.frequencyToSeconds = function(freq){
            +			return 1 / parseFloat(freq);
            +		};
            +
            +		/**
            +		 *  convert a number in seconds to a frequency
            +		 *  @param  {number} seconds 
            +		 *  @return {number}         
            +		 */
            +		Tone.prototype.secondsToFrequency = function(seconds){
            +			return 1/seconds;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	INTERNAL STATIC METHODS
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 * 	Adds an ES5 getter setter to the prototype of the constructor. 
            +		 * 	The prototype is expected to have a camelCase function of the 
            +		 * 	property with the names getProperty and setProperty
            +		 *  @internal
            +		 *  @static
            +		 *  @param {Object} constr the constructor
            +		 *  @param {string} property the property
            +		 */
            +		Tone._defineGetterSetter = function(constr, property){
            +			var proto = constr.prototype;
            +			function capitalize(string){
            +			    return string.charAt(0).toUpperCase() + string.slice(1);
            +			}
            +			var getterName = "get"+capitalize(property);
            +			var setterName = "set"+capitalize(property);
            +			if (proto.hasOwnProperty(getterName) && 
            +				isFunction(proto[getterName]) && 
            +				proto.hasOwnProperty(setterName) && 
            +				isFunction(proto[setterName])){
            +				Object.defineProperty(constr.prototype, property, {
            +					get : function(){
            +						return this[getterName]();
            +					},
            +					set : function(val){
            +						return this[setterName](val);
            +					}
            +				});
            +			} 
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	INHERITANCE
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  have a child inherit all of Tone's (or a parent's) prototype
            +		 *  to inherit the parent's properties, make sure to call 
            +		 *  Parent.call(this) in the child's constructor
            +		 *
            +		 *  based on closure library's inherit function
            +		 *
            +		 *  @static
            +		 *  @param  {function} 	child  
            +		 *  @param  {function=} parent (optional) parent to inherit from
            +		 *                             if no parent is supplied, the child
            +		 *                             will inherit from Tone
            +		 */
            +		Tone.extend = function(child, parent){
            +			if (isUndef(parent)){
            +				parent = Tone;
            +			}
            +			function TempConstructor(){}
            +			TempConstructor.prototype = parent.prototype;
            +			child.prototype = new TempConstructor();
            +			/** @override */
            +			child.prototype.constructor = child;
            +			child._super = parent;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	CONTEXT
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  array of callbacks to be invoked when a new context is added
            +		 *  @internal 
            +		 *  @private
            +		 */
            +		var newContextCallbacks = [];
            +
            +		/**
            +		 *  invoke this callback when a new context is added
            +		 *  will be invoked initially with the first context
            +		 *  @internal 
            +		 *  @static
            +		 *  @param {function(AudioContext)} callback the callback to be invoked
            +		 *                                           with the audio context
            +		 */
            +		Tone._initAudioContext = function(callback){
            +			//invoke the callback with the existing AudioContext
            +			callback(Tone.context);
            +			//add it to the array
            +			newContextCallbacks.push(callback);
            +		};
            +
            +		/**
            +		 *  @static
            +		 */
            +		Tone.setContext = function(ctx){
            +			//set the prototypes
            +			Tone.prototype.context = ctx;
            +			Tone.context = ctx;
            +			//invoke all the callbacks
            +			for (var i = 0; i < newContextCallbacks.length; i++){
            +				newContextCallbacks[i](ctx);
            +			}
            +		};
            +
            +		/**
            +		 *  bind this to a touchstart event to start the audio
            +		 *
            +		 *  http://stackoverflow.com/questions/12517000/no-sound-on-ios-6-web-audio-api/12569290#12569290
            +		 *  
            +		 *  @static
            +		 */
            +		Tone.startMobile = function(){
            +			var osc = Tone.context.createOscillator();
            +			var silent = Tone.context.createGain();
            +			silent.gain.value = 0;
            +			osc.connect(silent);
            +			silent.connect(Tone.context.destination);
            +			var now = Tone.context.currentTime;
            +			osc.start(now);
            +			osc.stop(now+1);
            +		};
            +
            +		//setup the context
            +		Tone._initAudioContext(function(audioContext){
            +			//set the bufferTime
            +			Tone.prototype.bufferTime = Tone.prototype.bufferSize / audioContext.sampleRate;
            +			_silentNode = audioContext.createGain();
            +			_silentNode.gain.value = 0;
            +			_silentNode.connect(audioContext.destination);
            +		});
            +
            +		console.log("%c * Tone.js r4-dev * ", "background: #000; color: #fff");
            +
            +		return Tone;
            +	});
            +
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Base class for all Signals
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 */
            +		Tone.SignalBase = function(){
            +
            +		};
            +
            +		Tone.extend(Tone.SignalBase);
            +
            +		/**
            +		 *  Signals can connect to other Signals
            +		 *
            +		 *  @override
            +		 *  @param {AudioParam|AudioNode|Tone.Signal|Tone} node 
            +		 *  @param {number} [outputNumber=0] 
            +		 *  @param {number} [inputNumber=0] 
            +		 *  @returns {Tone.SignalBase} `this`
            +		 */
            +		Tone.SignalBase.prototype.connect = function(node, outputNumber, inputNumber){
            +			//zero it out so that the signal can have full control
            +			if (node instanceof Tone.Signal || node instanceof AudioParam){
            +				node.value = 0;
            +			} 
            +			Tone.prototype.connect.call(this, node, outputNumber, inputNumber);
            +			return this;
            +		};
            +
            +		return Tone.SignalBase;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Wraps the WaveShaperNode
            +		 *
            +		 *  ```javascript
            +		 *  var timesTwo = new Tone.WaveShaper(function(val){
            +		 *  	return val * 2;
            +		 *  }, 2048);
            +		 *  ```
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 *  @param {function(number, number)|Array|number} mapping the function used to define the values. 
            +		 *                                    The mapping function should take two arguments: 
            +		 *                                    the first is the value at the current position 
            +		 *                                    and the second is the array position. 
            +		 *                                    If the argument is an array, that array will be
            +		 *                                    set as the wave shapping function
            +		 *  @param {number} [bufferLen=1024] the length of the WaveShaperNode buffer.
            +		 */
            +		Tone.WaveShaper = function(mapping, bufferLen){
            +
            +			/**
            +			 *  the waveshaper
            +			 *  @type {WaveShaperNode}
            +			 *  @private
            +			 */
            +			this._shaper = this.input = this.output = this.context.createWaveShaper();
            +
            +			/**
            +			 *  the waveshapers curve
            +			 *  @type {Float32Array}
            +			 *  @private
            +			 */
            +			this._curve = null;
            +
            +			if (Array.isArray(mapping)){
            +				this.curve = mapping;
            +			} else if (isFinite(mapping) || this.isUndef(mapping)){
            +				this._curve = new Float32Array(this.defaultArg(mapping, 1024));
            +			} else if (this.isFunction(mapping)){
            +				this._curve = new Float32Array(this.defaultArg(bufferLen, 1024));
            +				this.setMap(mapping);
            +			} 
            +		};
            +
            +		Tone.extend(Tone.WaveShaper, Tone.SignalBase);
            +
            +		/**
            +		 *  uses a mapping function to set the value of the curve
            +		 *  @param {function(number, number)} mapping the function used to define the values. 
            +		 *                                    The mapping function should take two arguments: 
            +		 *                                    the first is the value at the current position 
            +		 *                                    and the second is the array position
            +		 *  @returns {Tone.WaveShaper} `this`
            +		 */
            +		Tone.WaveShaper.prototype.setMap = function(mapping){
            +			for (var i = 0, len = this._curve.length; i < len; i++){
            +				var normalized = (i / (len)) * 2 - 1;
            +				var normOffOne = (i / (len - 1)) * 2 - 1;
            +				this._curve[i] = mapping(normalized, i, normOffOne);
            +			}
            +			this._shaper.curve = this._curve;
            +			return this;
            +		};
            +
            +		/**
            +		 * The array to set as the waveshaper curve
            +		 * @memberOf Tone.WaveShaper#
            +		 * @type {Array}
            +		 * @name curve
            +		 */
            +		Object.defineProperty(Tone.WaveShaper.prototype, "curve", {
            +			get : function(){
            +				return this._shaper.curve;
            +			},
            +			set : function(mapping){
            +				//fixes safari WaveShaperNode bug
            +				if (this._isSafari()){
            +					var first = mapping[0];
            +					mapping.unshift(first);	
            +				}
            +				this._curve = new Float32Array(mapping);
            +				this._shaper.curve = this._curve;
            +			}
            +		});
            +
            +		/**
            +		 * The oversampling. Can either be "none", "2x" or "4x"
            +		 * @memberOf Tone.WaveShaper#
            +		 * @type {string}
            +		 * @name curve
            +		 */
            +		Object.defineProperty(Tone.WaveShaper.prototype, "oversample", {
            +			get : function(){
            +				return this._shaper.oversample;
            +			},
            +			set : function(oversampling){
            +				this._shaper.oversample = oversampling;
            +			}
            +		});
            +
            +		/**
            +		 *  returns true if the browser is safari
            +		 *  @return  {boolean} 
            +		 *  @private
            +		 */
            +		Tone.WaveShaper.prototype._isSafari = function(){
            +			var ua = navigator.userAgent.toLowerCase(); 
            +			return ua.indexOf("safari") !== -1 && ua.indexOf("chrome") === -1;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.WaveShaper} `this`
            +		 */
            +		Tone.WaveShaper.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._shaper.disconnect();
            +			this._shaper = null;
            +			this._curve = null;
            +			return this;
            +		};
            +
            +		return Tone.WaveShaper;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Constant audio-rate signal.
            +		 *          Tone.Signal is a core component which allows for sample-accurate 
            +		 *          synchronization of many components. Tone.Signal can be scheduled 
            +		 *          with all of the functions available to AudioParams
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number|AudioParam} [value=0] initial value or the AudioParam to control
            +		 *                                       note that the signal has no output
            +		 *                                       if an AudioParam is passed in.
            +		 *  @param {Tone.Signal.Unit} [units=Number] unit the units the signal is in
            +		 */
            +		Tone.Signal = function(value, units){
            +
            +			/**
            +			 *  scales the constant output to the desired output
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._scalar = this.context.createGain();
            +
            +			/**
            +			 *  the ratio of the this value to the control signal value
            +			 *
            +			 *  @private
            +			 *  @type {number}
            +			 */
            +			this._syncRatio = 1;
            +
            +			/**
            +			 * the units the signal is in
            +			 * @type {Tone.Signal.Type}
            +			 */
            +			this.units = this.defaultArg(units, Tone.Signal.Units.Number);
            +
            +			var destination;
            +			if (value instanceof AudioParam){
            +				destination = value;
            +				destination.value = 0;
            +			} else {
            +				destination = this.context.createGain();
            +				this.value = this.defaultArg(value, 0);
            +			}
            +
            +			/**
            +			 *  @type {GainNode|AudioParam}
            +			 */
            +			this.input = this.output = destination;
            +
            +			//connect the constant 1 output to the node output
            +			Tone.Signal._constant.chain(this._scalar, this.output);
            +		};
            +
            +		Tone.extend(Tone.Signal, Tone.SignalBase);
            +
            +		/**
            +		 * The value of the signal. 
            +		 * @memberOf Tone.Signal#
            +		 * @type {Tone.Time|Tone.Frequency|number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.Signal.prototype, "value", {
            +			get : function(){
            +				return this._toUnits(this._scalar.gain.value);
            +			},
            +			set : function(value){
            +				var convertedVal = this._fromUnits(value);
            +				convertedVal *= this._syncRatio;
            +				this._scalar.gain.value = convertedVal;
            +			}
            +		});
            +
            +		/**
            +		 * @private
            +		 * @param  {Tone.Time|Tone.Volume|Tone.Frequency|number|undefined} val the value to convert
            +		 * @return {number}     the number which the value should be set to
            +		 */
            +		Tone.Signal.prototype._fromUnits = function(val){
            +			switch(this.units){
            +				case Tone.Signal.Units.Time: 
            +					return this.toSeconds(val);
            +				case Tone.Signal.Units.Frequency: 
            +					return this.toFrequency(val);
            +				case Tone.Signal.Units.Decibels: 
            +					return this.dbToGain(val);
            +				case Tone.Signal.Units.Normal: 
            +					return Math.min(Math.max(val, 0), 1);
            +				case Tone.Signal.Units.Audio: 
            +					return Math.min(Math.max(val, -1), 1);
            +				default:
            +					return val;
            +			}
            +		};
            +
            +		/**
            +		 * convert to the desired units
            +		 * @private
            +		 * @param  {number} val the value to convert
            +		 * @return {number}
            +		 */
            +		Tone.Signal.prototype._toUnits = function(val){
            +			switch(this.units){
            +				case Tone.Signal.Units.Decibels: 
            +					return this.gainToDb(val);
            +				default:
            +					return val;
            +			}
            +		};
            +
            +		/**
            +		 *  Schedules a parameter value change at the given time.
            +		 *  
            +		 *  @param {number}		value 
            +		 *  @param {Tone.Time}  time 
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.setValueAtTime = function(value, time){
            +			value = this._fromUnits(value);
            +			value *= this._syncRatio;
            +			this._scalar.gain.setValueAtTime(value, this.toSeconds(time));
            +			return this;
            +		};
            +
            +		/**
            +		 *  creates a schedule point with the current value at the current time
            +		 *
            +		 *  @param {number=} now (optionally) pass the now value in
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.setCurrentValueNow = function(now){
            +			now = this.defaultArg(now, this.now());
            +			var currentVal = this.value;
            +			this.cancelScheduledValues(now);
            +			this._scalar.gain.setValueAtTime(currentVal, now);
            +			return this;
            +		};
            +
            +		/**
            +		 *  Schedules a linear continuous change in parameter value from the 
            +		 *  previous scheduled parameter value to the given value.
            +		 *  
            +		 *  @param  {number} value   
            +		 *  @param  {Tone.Time} endTime 
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.linearRampToValueAtTime = function(value, endTime){
            +			value = this._fromUnits(value);
            +			value *= this._syncRatio;
            +			this._scalar.gain.linearRampToValueAtTime(value, this.toSeconds(endTime));
            +			return this;
            +		};
            +
            +		/**
            +		 *  Schedules an exponential continuous change in parameter value from 
            +		 *  the previous scheduled parameter value to the given value.
            +		 *  
            +		 *  @param  {number} value   
            +		 *  @param  {Tone.Time} endTime 
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.exponentialRampToValueAtTime = function(value, endTime){
            +			value = this._fromUnits(value);
            +			value *= this._syncRatio;
            +			//can't go below a certain value
            +			value = Math.max(0.00001, value);
            +			this._scalar.gain.exponentialRampToValueAtTime(value, this.toSeconds(endTime));
            +			return this;
            +		};
            +
            +		/**
            +		 *  Schedules an exponential continuous change in parameter value from 
            +		 *  the current time and current value to the given value.
            +		 *  
            +		 *  @param  {number} value   
            +		 *  @param  {Tone.Time} rampTime the time that it takes the 
            +		 *                               value to ramp from it's current value
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.exponentialRampToValueNow = function(value, rampTime ){
            +			var now = this.now();
            +			this.setCurrentValueNow(now);
            +			this.exponentialRampToValueAtTime(value, now + this.toSeconds(rampTime ));
            +			return this;
            +		};
            +
            +		/**
            +		 *  Schedules an linear continuous change in parameter value from 
            +		 *  the current time and current value to the given value at the given time.
            +		 *  
            +		 *  @param  {number} value   
            +		 *  @param  {Tone.Time} rampTime the time that it takes the 
            +		 *                               value to ramp from it's current value
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.linearRampToValueNow = function(value, rampTime){
            +			value = this._fromUnits(value);
            +			var now = this.now();
            +			this.setCurrentValueNow(now);
            +			value *= this._syncRatio;
            +			this._scalar.gain.linearRampToValueAtTime(value, now + this.toSeconds(rampTime));
            +			return this;
            +		};
            +
            +		/**
            +		 *  Start exponentially approaching the target value at the given time with
            +		 *  a rate having the given time constant.
            +		 *  	
            +		 *  @param {number} value        
            +		 *  @param {Tone.Time} startTime    
            +		 *  @param {number} timeConstant 
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.setTargetAtTime = function(value, startTime, timeConstant){
            +			value = this._fromUnits(value);
            +			value *= this._syncRatio;
            +			this._scalar.gain.setTargetAtTime(value, this.toSeconds(startTime), timeConstant);
            +			return this;
            +		};
            +
            +		/**
            +		 *  Sets an array of arbitrary parameter values starting at the given time
            +		 *  for the given duration.
            +		 *  	
            +		 *  @param {Array<number>} values    
            +		 *  @param {Tone.Time} startTime 
            +		 *  @param {Tone.Time} duration  
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.setValueCurveAtTime = function(values, startTime, duration){
            +			for (var i = 0; i < values.length; i++){
            +				values[i] = this._fromUnits(values[i]);
            +				values[i] *= this._syncRatio;
            +			}
            +			this._scalar.gain.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration));
            +			return this;
            +		};
            +
            +		/**
            +		 *  Cancels all scheduled parameter changes with times greater than or 
            +		 *  equal to startTime.
            +		 *  
            +		 *  @param  {Tone.Time} startTime
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.cancelScheduledValues = function(startTime){
            +			this._scalar.gain.cancelScheduledValues(this.toSeconds(startTime));
            +			return this;
            +		};
            +
            +		/**
            +		 *  Ramps to the given value over the duration of the rampTime. 
            +		 *  Automatically selects the best ramp type (exponential or linear)
            +		 *  depending on the `units` of the signal
            +		 *  
            +		 *  @param  {number} value   
            +		 *  @param  {Tone.Time} rampTime the time that it takes the 
            +		 *                               value to ramp from it's current value
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.rampTo = function(value, rampTime){
            +			rampTime = this.defaultArg(rampTime, 0);
            +			if (this.units === Tone.Signal.Units.Frequency){
            +				this.exponentialRampToValueNow(value, rampTime);
            +			} else {
            +				this.linearRampToValueNow(value, rampTime);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  Sync this to another signal and it will always maintain the 
            +		 *  ratio between the two signals until it is unsynced
            +		 *
            +		 *  Signals can only be synced to one other signal. while syncing, 
            +		 *  if a signal's value is changed, the new ratio between the signals
            +		 *  is maintained as the syncing signal is changed. 
            +		 *  
            +		 *  @param  {Tone.Signal} signal to sync to
            +		 *  @param {number=} ratio optionally pass in the ratio between 
            +		 *                         the two signals, otherwise it will be computed
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.sync = function(signal, ratio){
            +			if (ratio){
            +				this._syncRatio = ratio;
            +			} else {
            +				//get the sync ratio
            +				if (signal.value !== 0){
            +					this._syncRatio = this.value / signal.value;
            +				} else {
            +					this._syncRatio = 0;
            +				}
            +			}
            +			//make a new scalar which is not connected to the constant signal
            +			this._scalar.disconnect();
            +			this._scalar = this.context.createGain();
            +			this.connectSeries(signal, this._scalar, this.output);
            +			//set it ot the sync ratio
            +			this._scalar.gain.value = this._syncRatio;
            +			return this;
            +		};
            +
            +		/**
            +		 *  unbind the signal control
            +		 *
            +		 *  will leave the signal value as it was without the influence of the control signal
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.unsync = function(){
            +			//make a new scalar so that it's disconnected from the control signal
            +			//get the current gain
            +			var currentGain = this.value;
            +			this._scalar.disconnect();
            +			this._scalar = this.context.createGain();
            +			this._scalar.gain.value = currentGain / this._syncRatio;
            +			this._syncRatio = 1;
            +			//reconnect things up
            +			Tone.Signal._constant.chain(this._scalar, this.output);
            +			return this;
            +		};
            +
            +		/**
            +		 *  dispose and disconnect
            +		 *  @returns {Tone.Signal} `this`
            +		 */
            +		Tone.Signal.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._scalar.disconnect();
            +			this._scalar = null;
            +			return this;
            +		};
            +
            +		/**
            +		 * The units the Signal is in
            +		 * @enum {string}
            +		 */
            +		Tone.Signal.Units = {
            +			/** The default type. */
            +			Number : "number",
            +			/** Tone.Time will be converted into seconds. */
            +			Time : "time",
            +			/** Tone.Frequency will be converted into hertz. */
            +			Frequency : "frequency",
            +			/** A Gain value. */
            +			Gain : "gain",
            +			/** Within normal range [0,1]. */
            +			Normal : "normal",
            +			/** Within normal range [-1,1]. */
            +			Audio : "audio",
            +			/** In decibels. */
            +			Decibels : "db",
            +			/** In half-step increments, i.e. 12 is an octave above the root. */
            +			Interval : "interval"
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	STATIC
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  the constant signal generator
            +		 *  @static
            +		 *  @private
            +		 *  @const
            +		 *  @type {OscillatorNode}
            +		 */
            +		Tone.Signal._generator = null;
            +
            +		/**
            +		 *  the signal generator waveshaper. makes the incoming signal
            +		 *  only output 1 for all inputs.
            +		 *  @static
            +		 *  @private
            +		 *  @const
            +		 *  @type {Tone.WaveShaper}
            +		 */
            +		Tone.Signal._constant = null;
            +
            +		/**
            +		 *  initializer function
            +		 */
            +		Tone._initAudioContext(function(audioContext){
            +			Tone.Signal._generator = audioContext.createOscillator();
            +			Tone.Signal._constant = new Tone.WaveShaper([1,1]);
            +			Tone.Signal._generator.connect(Tone.Signal._constant);
            +			Tone.Signal._generator.start(0);
            +			Tone.Signal._generator.noGC();
            +		});
            +
            +		return Tone.Signal;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Pow applies an exponent to the incoming signal. The incoming signal
            +		 *         must be in the range -1,1
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 *  @param {number} exp the exponent to apply to the incoming signal, must be at least 2. 
            +		 */
            +		Tone.Pow = function(exp){
            +
            +			/**
            +			 * the exponent
            +			 * @private
            +			 * @type {number}
            +			 */
            +			this._exp = this.defaultArg(exp, 1);
            +
            +			/**
            +			 *  @type {WaveShaperNode}
            +			 *  @private
            +			 */
            +			this._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192);
            +		};
            +
            +		Tone.extend(Tone.Pow, Tone.SignalBase);
            +
            +		/**
            +		 * The value of the exponent
            +		 * @memberOf Tone.Pow#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.Pow.prototype, "value", {
            +			get : function(){
            +				return this._exp;
            +			},
            +			set : function(exp){
            +				this._exp = exp;
            +				this._expScaler.setMap(this._expFunc(this._exp));
            +			}
            +		});
            +
            +
            +		/**
            +		 *  the function which maps the waveshaper
            +		 *  @param   {number} exp
            +		 *  @return {function}
            +		 *  @private
            +		 */
            +		Tone.Pow.prototype._expFunc = function(exp){
            +			return function(val){
            +				return Math.pow(Math.abs(val), exp);
            +			};
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Pow} `this`
            +		 */
            +		Tone.Pow.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._expScaler.dispose();
            +			this._expScaler = null;
            +			return this;
            +		};
            +
            +		/**
            +		 * the exponent to raise the funciton to
            +		 * @memberOf Tone.Pow#
            +		 * @type {number}
            +		 * @name exponent
            +		 */
            +		Tone._defineGetterSetter(Tone.Pow, "exponent");
            +
            +		return Tone.Pow;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  ADSR envelope generator attaches to an AudioParam or Signal. 
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @param {Tone.Time|Object} [attack=0.01]	the attack time in seconds
            +		 *  @param {Tone.Time} [decay=0.1]	the decay time in seconds
            +		 *  @param {number} [sustain=0.5] 	a percentage (0-1) of the full amplitude
            +		 *  @param {Tone.Time} [release=1]	the release time in seconds
            +		 */
            +		Tone.Envelope = function(){
            +
            +			//get all of the defaults
            +			var options = this.optionsObject(arguments, ["attack", "decay", "sustain", "release"], Tone.Envelope.defaults);
            +
            +			/** 
            +			 *  The attack time
            +			 *  @type {Tone.Time}
            +			 */
            +			this.attack = options.attack;
            +
            +			/**
            +			 *  The decay time
            +			 *  @type {Tone.Time}
            +			 */
            +			this.decay = options.decay;
            +			
            +			/**
            +			 *  the sustain is a value between 0-1
            +			 *  @type {number}
            +			 */
            +			this.sustain = options.sustain;
            +
            +			/**
            +			 *  The release time
            +			 *  @type {Tone.Time}
            +			 */
            +			this.release = options.release;
            +
            +			/**
            +			 *  the signal
            +			 *  @type {Tone.Signal}
            +			 *  @private
            +			 */
            +			this._sig = this.output = new Tone.Signal(0);
            +		};
            +
            +		Tone.extend(Tone.Envelope);
            +
            +		/**
            +		 *  the default parameters
            +		 *  @static
            +		 *  @const
            +		 */
            +		Tone.Envelope.defaults = {
            +			"attack" : 0.01,
            +			"decay" : 0.1,
            +			"sustain" : 0.5,
            +			"release" : 1,
            +		};
            +
            +		/**
            +		 *  the envelope time multipler
            +		 *  @type {number}
            +		 *  @private
            +		 */
            +		Tone.Envelope.prototype._timeMult = 0.25;
            +
            +		/**
            +		 *  attack->decay->sustain linear ramp
            +		 *  @param  {Tone.Time} [time=now]
            +		 *  @param {number} [velocity=1] the velocity of the envelope scales the vales.
            +		 *                               number between 0-1
            +		 *  @returns {Tone.Envelope} `this`
            +		 */
            +		Tone.Envelope.prototype.triggerAttack = function(time, velocity){
            +			velocity = this.defaultArg(velocity, 1);
            +			var attack = this.toSeconds(this.attack);
            +			var decay = this.toSeconds(this.decay);
            +			var scaledMax = velocity;
            +			var sustainVal = this.sustain * scaledMax;
            +			time = this.toSeconds(time);
            +			this._sig.cancelScheduledValues(time);
            +			this._sig.setTargetAtTime(scaledMax, time, attack * this._timeMult);
            +			this._sig.setTargetAtTime(sustainVal, time + attack, decay * this._timeMult);	
            +			return this;
            +		};
            +		
            +		/**
            +		 *  triggers the release of the envelope with a linear ramp
            +		 *  @param  {Tone.Time} [time=now]
            +		 *  @returns {Tone.Envelope} `this`
            +		 */
            +		Tone.Envelope.prototype.triggerRelease = function(time){
            +			time = this.toSeconds(time);
            +			this._sig.cancelScheduledValues(time);
            +			var release = this.toSeconds(this.release);
            +			this._sig.setTargetAtTime(0, time, release * this._timeMult);
            +			return this;
            +		};
            +
            +		/**
            +		 *  trigger the attack and release after a sustain time
            +		 *  @param {Tone.Time} duration the duration of the note
            +		 *  @param {Tone.Time} [time=now] the time of the attack
            +		 *  @param {number} [velocity=1] the velocity of the note
            +		 *  @returns {Tone.Envelope} `this`
            +		 */
            +		Tone.Envelope.prototype.triggerAttackRelease = function(duration, time, velocity) {
            +			time = this.toSeconds(time);
            +			this.triggerAttack(time, velocity);
            +			this.triggerRelease(time + this.toSeconds(duration));
            +			return this;
            +		};
            +
            +		/**
            +		 *  borrows the connect method from {@link Tone.Signal}
            +		 *  
            +		 *  @function
            +		 */
            +		Tone.Envelope.prototype.connect = Tone.Signal.prototype.connect;
            +
            +		/**
            +		 *  disconnect and dispose
            +		 *  @returns {Tone.Envelope} `this`
            +		 */
            +		Tone.Envelope.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._sig.dispose();
            +			this._sig = null;
            +			return this;
            +		};
            +
            +		return Tone.Envelope;
            +	});
            +
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  An Envelope connected to a gain node which can be used as an amplitude envelope.
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.Envelope}
            +		 *  @param {Tone.Time|Object} [attack=0.01]	the attack time in seconds
            +		 *  @param {Tone.Time} [decay=0.1]	the decay time in seconds
            +		 *  @param {number} [sustain=0.5] 	a percentage (0-1) of the full amplitude
            +		 *  @param {Tone.Time} [release=1]	the release time in seconds
            +		 */
            +		Tone.AmplitudeEnvelope = function(){
            +
            +			Tone.Envelope.apply(this, arguments);
            +
            +			/**
            +			 *  the input node
            +			 *  @type {GainNode}
            +			 */
            +			this.input = this.output = this.context.createGain();
            +
            +			this._sig.connect(this.output.gain);
            +		};
            +
            +		Tone.extend(Tone.AmplitudeEnvelope, Tone.Envelope);
            +
            +		return Tone.AmplitudeEnvelope;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A thin wrapper around the DynamicsCompressorNode
            +		 *
            +		 *  @extends {Tone}
            +		 *  @constructor
            +		 *  @param {number} [threshold=-24] threshold in decibels
            +		 *  @param {number} [ratio=12] gain reduction ratio
            +		 */
            +		Tone.Compressor = function(){
            +
            +			var options = this.optionsObject(arguments, ["threshold", "ratio"], Tone.Compressor.defaults);
            +
            +			/**
            +			 *  the compressor node
            +			 *  @type {DynamicsCompressorNode}
            +			 *  @private
            +			 */
            +			this._compressor = this.context.createDynamicsCompressor();
            +
            +			/**
            +			 *  the input and output
            +			 */
            +			this.input = this.output = this._compressor;
            +
            +			/**
            +			 *  the threshold vaue
            +			 *  @type {AudioParam}
            +			 */
            +			this.threshold = this._compressor.threshold;
            +
            +			/**
            +			 *  The attack parameter
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.attack = new Tone.Signal(this._compressor.attack, Tone.Signal.Units.Time);
            +
            +			/**
            +			 *  The release parameter
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.release = new Tone.Signal(this._compressor.release, Tone.Signal.Units.Time);
            +
            +			/**
            +			 *  The knee parameter
            +			 *  @type {AudioParam}
            +			 */
            +			this.knee = this._compressor.knee;
            +
            +			/**
            +			 *  The ratio value
            +			 *  @type {AudioParam}
            +			 */
            +			this.ratio = this._compressor.ratio;
            +
            +			//set the defaults
            +			this.set(options);
            +		};
            +
            +		Tone.extend(Tone.Compressor);
            +
            +		/**
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.Compressor.defaults = {
            +			"ratio" : 12,
            +			"threshold" : -24,
            +			"release" : 0.25,
            +			"attack" : 0.003,
            +			"knee" : 30
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Compressor} `this`
            +		 */
            +		Tone.Compressor.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._compressor.disconnect();
            +			this._compressor = null;
            +			this.attack.dispose();
            +			this.attack = null;
            +			this.release.dispose();
            +			this.release = null;
            +			this.threshold = null;
            +			this.ratio = null;
            +			this.knee = null;
            +			return this;
            +		};
            +
            +		return Tone.Compressor;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Add a signal and a number or two signals. 
            +		 *         input 0: augend. input 1: addend. 
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number=} value if no value is provided, Tone.Add will sum the first
            +		 *                         and second inputs. 
            +		 */
            +		Tone.Add = function(value){
            +
            +			Tone.call(this, 2, 0);
            +
            +			/**
            +			 *  the summing node
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._sum = this.input[0] = this.input[1] = this.output = this.context.createGain();
            +
            +			/**
            +			 *  @private
            +			 *  @type {Tone.Signal}
            +			 */
            +			this._addend = null;
            +
            +			if (isFinite(value)){
            +				this._addend = new Tone.Signal(value);
            +				this._addend.connect(this._sum);
            +			} 
            +		};
            +
            +		Tone.extend(Tone.Add, Tone.SignalBase);
            +
            +		/**
            +		 * The value being added to the incoming signal. Note, that
            +		 * if Add was constructed without any arguments, it expects
            +		 * that the signals to add will be connected to input 0 and input 1
            +		 * and therefore will throw an error when trying to set the value. 
            +		 * 
            +		 * @memberOf Tone.Add#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.Add.prototype, "value", {
            +			get : function(){
            +				if (this._addend !== null){
            +					return this._addend.value;
            +				} else {
            +					throw new Error("cannot switch from signal to number");
            +				}
            +			},
            +			set : function(value){
            +				if (this._addend !== null){
            +					this._addend.value = value;
            +				} else {
            +					throw new Error("cannot switch from signal to number");
            +				}
            +			}
            +		});
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.Add} `this`
            +		 */
            +		Tone.Add.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._sum = null;
            +			if (this._addend){
            +				this._addend.dispose();
            +				this._addend = null;
            +			}
            +			return this;
            +		}; 
            +
            +		return Tone.Add;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Multiply the incoming signal by a number or Multiply two signals.
            +		 *          input 0: multiplicand.
            +		 *          input 1: multiplier.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number=} value constant value to multiple. if no value is provided
            +		 *                         it will be multiplied by the value of input 1.
            +		 */
            +		Tone.Multiply = function(value){
            +
            +			Tone.call(this, 2, 0);
            +
            +			/**
            +			 *  the input node is the same as the output node
            +			 *  it is also the GainNode which handles the scaling of incoming signal
            +			 *  
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._mult = this.input[0] = this.output = this.context.createGain();
            +
            +			/**
            +			 *  the scaling parameter
            +			 *  @type {AudioParam}
            +			 *  @private
            +			 */
            +			this._factor = this.input[1] = this.output.gain;
            +			
            +			this._factor.value = this.defaultArg(value, 0);
            +		};
            +
            +		Tone.extend(Tone.Multiply, Tone.SignalBase);
            +
            +		/**
            +		 * The value being multiplied to the incoming signal.
            +		 * @memberOf Tone.Multiply#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.Multiply.prototype, "value", {
            +			get : function(){
            +				return this._factor.value;
            +			},
            +			set : function(value){
            +				this._factor.value = value;	
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Multiply} `this`
            +		 */
            +		Tone.Multiply.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._mult = null;
            +			this._factor = null;
            +			return this;
            +		}; 
            +
            +		return Tone.Multiply;
            +	});
            +
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Negate the incoming signal. i.e. an input signal of 10 will output -10
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 */
            +		Tone.Negate = function(){
            +			/**
            +			 *  negation is done by multiplying by -1
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._multiply = this.input = this.output= new Tone.Multiply(-1);
            +		};
            +
            +		Tone.extend(Tone.Negate, Tone.SignalBase);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Negate} `this`
            +		 */
            +		Tone.Negate.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._multiply.dispose();
            +			this._multiply = null;
            +			return this;
            +		}; 
            +
            +		return Tone.Negate;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Subtract a signal and a number or two signals. 
            +		 *         input 0 : minuend.
            +		 *         input 1 : subtrahend
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 *  @param {number=} value value to subtract from the incoming signal. If the value
            +		 *                         is omitted, it will subtract the second signal from the first
            +		 */
            +		Tone.Subtract = function(value){
            +
            +			Tone.call(this, 2, 0);
            +
            +			/**
            +			 *  the adder node
            +			 *  @type {Tone.Add}
            +			 *  @private
            +			 */
            +			this._adder = this.input[0] = this.output = new Tone.Add(-value);
            +
            +			/**
            +			 *  the negate node
            +			 *  @type {Tone.Negate}
            +			 *  @private
            +			 */
            +			this._neg = this.input[1] = new Tone.Negate();
            +
            +			//connect it up
            +			this._neg.connect(this._adder, 0, 1);
            +		};
            +
            +		Tone.extend(Tone.Subtract, Tone.SignalBase);
            +
            +		/**
            +		 * The value being subtracted from the incoming signal. 
            +		 * @memberOf Tone.Subtract#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.Subtract.prototype, "value", {
            +			get : function(){
            +				return -this._adder.value;
            +			},
            +			set : function(value){
            +				this._adder.value = -value;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.SignalBase} `this`
            +		 */
            +		Tone.Subtract.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._neg.dispose();
            +			this._neg = null;
            +			this._adder.dispose();
            +			this._adder = null;
            +			return this;
            +		};
            +
            +		return Tone.Subtract;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  GreaterThanZero outputs 1 when the input is strictly greater than zero
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 */
            +		Tone.GreaterThanZero = function(){
            +			
            +			/**
            +			 *  @type {Tone.WaveShaper}
            +			 *  @private
            +			 */
            +			this._thresh = this.output = new Tone.WaveShaper(function(val){
            +				if (val <= 0){
            +					return 0;
            +				} else {
            +					return 1;
            +				}
            +			});
            +
            +			/**
            +			 *  scale the first thresholded signal by a large value.
            +			 *  this will help with values which are very close to 0
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._scale = this.input = new Tone.Multiply(10000);
            +
            +			//connections
            +			this._scale.connect(this._thresh);
            +		};
            +
            +		Tone.extend(Tone.GreaterThanZero, Tone.SignalBase);
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.GreaterThanZero} `this`
            +		 */
            +		Tone.GreaterThanZero.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._scale.dispose();
            +			this._scale = null;
            +			this._thresh.dispose();
            +			this._thresh = null;
            +			return this;
            +		};
            +
            +		return Tone.GreaterThanZero;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  EqualZero outputs 1 when the input is strictly greater than zero
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 */
            +		Tone.EqualZero = function(){
            +
            +			/**
            +			 *  scale the incoming signal by a large factor
            +			 *  @private
            +			 *  @type {Tone.Multiply}
            +			 */
            +			this._scale = this.input = new Tone.Multiply(10000);
            +			
            +			/**
            +			 *  @type {Tone.WaveShaper}
            +			 *  @private
            +			 */
            +			this._thresh = new Tone.WaveShaper(function(val){
            +				if (val === 0){
            +					return 1;
            +				} else {
            +					return 0;
            +				}
            +			}, 128);
            +
            +			/**
            +			 *  threshold the output so that it's 0 or 1
            +			 *  @type {Tone.GreaterThanZero}
            +			 *  @private
            +			 */
            +			this._gtz = this.output = new Tone.GreaterThanZero();
            +
            +			//connections
            +			this._scale.chain(this._thresh, this._gtz);
            +		};
            +
            +		Tone.extend(Tone.EqualZero, Tone.SignalBase);
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.EqualZero} `this`
            +		 */
            +		Tone.EqualZero.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._gtz.dispose();
            +			this._gtz = null;
            +			this._scale.dispose();
            +			this._scale = null;
            +			this._thresh.dispose();
            +			this._thresh = null;
            +			return this;
            +		};
            +
            +		return Tone.EqualZero;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Output 1 if the signal is equal to the value, otherwise outputs 0. 
            +		 *          Can accept two signals if connected to inputs 0 and 1.
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} value the number to compare the incoming signal to
            +		 */
            +		Tone.Equal = function(value){
            +
            +			Tone.call(this, 2, 0);
            +
            +			/**
            +			 *  subtract the value from the incoming signal
            +			 *  
            +			 *  @type {Tone.Add}
            +			 *  @private
            +			 */
            +			this._sub = this.input[0] = new Tone.Subtract(value);
            +
            +			/**
            +			 *  @type {Tone.EqualZero}
            +			 *  @private
            +			 */
            +			this._equals = this.output = new Tone.EqualZero();
            +
            +			this._sub.connect(this._equals);
            +			this.input[1] = this._sub.input[1];
            +		};
            +
            +		Tone.extend(Tone.Equal, Tone.SignalBase);
            +
            +		/**
            +		 * The value to compare to the incoming signal.
            +		 * 
            +		 * @memberOf Tone.Equal#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.Equal.prototype, "value", {
            +			get : function(){
            +				return this._sub.value;
            +			},
            +			set : function(value){
            +				this._sub.value = value;
            +			}
            +		});
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.Equal} `this`
            +		 */
            +		Tone.Equal.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._equals.disconnect();
            +			this._equals = null;
            +			this._sub.dispose();
            +			this._sub = null;
            +			return this;
            +		};
            +
            +		return Tone.Equal;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Select between any number of inputs, sending the one 
            +		 *         selected by the gate signal to the output
            +		 *
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} [sourceCount=2] the number of inputs the switch accepts
            +		 */
            +		Tone.Select = function(sourceCount){
            +
            +			sourceCount = this.defaultArg(sourceCount, 2);
            +
            +			Tone.call(this, sourceCount, 1);
            +
            +			/**
            +			 *  the control signal
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.gate = new Tone.Signal(0);
            +
            +			//make all the inputs and connect them
            +			for (var i = 0; i < sourceCount; i++){
            +				var switchGate = new SelectGate(i);
            +				this.input[i] = switchGate;
            +				this.gate.connect(switchGate.selecter);
            +				switchGate.connect(this.output);
            +			}
            +		};
            +
            +		Tone.extend(Tone.Select, Tone.SignalBase);
            +
            +		/**
            +		 *  open one of the inputs and close the other
            +		 *  @param {number} [which=0] open one of the gates (closes the other)
            +		 *  @param {Tone.Time} time the time when the switch will open
            +		 *  @returns {Tone.Select} `this`
            +		 */
            +		Tone.Select.prototype.select = function(which, time){
            +			//make sure it's an integer
            +			which = Math.floor(which);
            +			this.gate.setValueAtTime(which, this.toSeconds(time));
            +			return this;
            +		};
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.Select} `this`
            +		 */
            +		Tone.Select.prototype.dispose = function(){
            +			this.gate.dispose();
            +			for (var i = 0; i < this.input.length; i++){
            +				this.input[i].dispose();
            +				this.input[i] = null;
            +			}
            +			Tone.prototype.dispose.call(this);
            +			this.gate = null;
            +			return this;
            +		}; 
            +
            +		////////////START HELPER////////////
            +
            +		/**
            +		 *  helper class for Tone.Select representing a single gate
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @internal only used by Tone.Select
            +		 */
            +		var SelectGate = function(num){
            +
            +			/**
            +			 *  the selector
            +			 *  @type {Tone.Equal}
            +			 */
            +			this.selecter = new Tone.Equal(num);
            +
            +			/**
            +			 *  the gate
            +			 *  @type {GainNode}
            +			 */
            +			this.gate = this.input = this.output = this.context.createGain();
            +
            +			//connect the selecter to the gate gain
            +			this.selecter.connect(this.gate.gain);
            +		};
            +
            +		Tone.extend(SelectGate);
            +
            +		/**
            +		 *  clean up
            +		 *  @private
            +		 */
            +		SelectGate.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.selecter.dispose();
            +			this.gate.disconnect();
            +			this.selecter = null;
            +			this.gate = null;
            +		};
            +
            +		////////////END HELPER////////////
            +
            +		//return Tone.Select
            +		return Tone.Select;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class IfThenElse has three inputs. When the first input (if) is true (i.e. === 1), 
            +		 *         then it will pass the second input (then) through to the output, otherwise, 
            +		 *         if it's not true (i.e. === 0) then it will pass the third input (else) 
            +		 *         through to the output. 
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 */
            +		Tone.IfThenElse = function(){
            +
            +			Tone.call(this, 3, 0);
            +
            +			/**
            +			 *  the selector node which is responsible for the routing
            +			 *  @type {Tone.Select}
            +			 *  @private
            +			 */
            +			this._selector = this.output = new Tone.Select(2);
            +
            +			//the input mapping
            +			this.if = this.input[0] = this._selector.gate;
            +			this.then = this.input[1] = this._selector.input[1];
            +			this.else = this.input[2] = this._selector.input[0];
            +		};
            +
            +		Tone.extend(Tone.IfThenElse, Tone.SignalBase);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.IfThenElse} `this`
            +		 */
            +		Tone.IfThenElse.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._selector.dispose();
            +			this._selector = null;
            +			this.if = null;
            +			this.then = null;
            +			this.else = null;
            +			return this;
            +		};
            +
            +		return Tone.IfThenElse;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class OR the inputs together. True if at least one of the inputs is true. 
            +		 *         Simply an alias for Tone.GreaterThanZero
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 */
            +		Tone.OR = function(inputCount){
            +
            +			inputCount = this.defaultArg(inputCount, 2);
            +			Tone.call(this, inputCount, 0);
            +
            +			/**
            +			 *  a private summing node
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._sum = this.context.createGain();
            +
            +			/**
            +			 *  @type {Tone.Equal}
            +			 *  @private
            +			 */
            +			this._gtz = new Tone.GreaterThanZero();
            +
            +			/**
            +			 *  the output
            +			 *  @type {Tone.Equal}
            +			 */
            +			this.output = this._gtz;
            +
            +			//make each of the inputs an alias
            +			for (var i = 0; i < inputCount; i++){
            +				this.input[i] = this._sum;
            +			}
            +			this._sum.connect(this._gtz);
            +		};
            +
            +		Tone.extend(Tone.OR, Tone.SignalBase);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.OR} `this`
            +		 */
            +		Tone.OR.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._gtz.dispose();
            +			this._gtz = null;
            +			this._sum.disconnect();
            +			this._sum = null;
            +			return this;
            +		};
            +
            +		return Tone.OR;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class and returns 1 when all the inputs are equal to 1
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 *  @param {number} [inputCount=2] the number of inputs. NOTE: all inputs are
            +		 *                                 connected to the single AND input node
            +		 */
            +		Tone.AND = function(inputCount){
            +
            +			inputCount = this.defaultArg(inputCount, 2);
            +
            +			Tone.call(this, inputCount, 0);
            +
            +			/**
            +			 *  @type {Tone.Equal}
            +			 *  @private
            +			 */
            +			this._equals = this.output = new Tone.Equal(inputCount);
            +
            +			//make each of the inputs an alias
            +			for (var i = 0; i < inputCount; i++){
            +				this.input[i] = this._equals;
            +			}
            +		};
            +
            +		Tone.extend(Tone.AND, Tone.SignalBase);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.AND} `this`
            +		 */
            +		Tone.AND.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._equals.dispose();
            +			this._equals = null;
            +			return this;
            +		};
            +
            +		return Tone.AND;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Just an alias for EqualZero. but has the same effect as a NOT operator. 
            +		 *          Outputs 1 when input equals 0. 
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 */
            +		Tone.NOT = Tone.EqualZero;
            +
            +		return Tone.NOT;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Output 1 if the signal is greater than the value, otherwise outputs 0.
            +		 *          can compare two signals or a signal and a number. 
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} [value=0] the value to compare to the incoming signal
            +		 */
            +		Tone.GreaterThan = function(value){
            +
            +			Tone.call(this, 2, 0);
            +			
            +			/**
            +			 *  subtract the amount from the incoming signal
            +			 *  @type {Tone.Subtract}
            +			 *  @private
            +			 */
            +			this._sub = this.input[0] = new Tone.Subtract(value);
            +			this.input[1] = this._sub.input[1];
            +
            +			/**
            +			 *  compare that amount to zero
            +			 *  @type {Tone.GreaterThanZero}
            +			 *  @private
            +			 */
            +			this._gtz = this.output = new Tone.GreaterThanZero();
            +
            +			//connect
            +			this._sub.connect(this._gtz);
            +		};
            +
            +		Tone.extend(Tone.GreaterThan, Tone.SignalBase);
            +
            +		/**
            +		 * The value to compare to the incoming signal.
            +		 * 
            +		 * @memberOf Tone.GreaterThan#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.GreaterThan.prototype, "value", {
            +			get : function(){
            +				return this._sub.value;
            +			},
            +			set : function(value){
            +				this._sub.value = value;
            +			}
            +		});
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.GreaterThan} `this`
            +		 */
            +		Tone.GreaterThan.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._sub.dispose();
            +			this._gtz.dispose();
            +			this._sub = null;
            +			this._gtz = null;
            +			return this;
            +		};
            +
            +		return Tone.GreaterThan;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Output 1 if the signal is less than the value, otherwise outputs 0.
            +		 *          can compare two signals or a signal and a number. 
            +		 *          input 0: left hand side of comparison.
            +		 *          input 1: right hand side of comparison.
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} [value=0] the value to compare to the incoming signal
            +		 */
            +		Tone.LessThan = function(value){
            +
            +			Tone.call(this, 2, 0);
            +
            +			/**
            +			 *  negate the incoming signal
            +			 *  @type {Tone.Negate}
            +			 *  @private
            +			 */
            +			this._neg = this.input[0] = new Tone.Negate();
            +
            +			/**
            +			 *  input < value === -input > -value
            +			 *  @type {Tone.GreaterThan}
            +			 *  @private
            +			 */
            +			this._gt = this.output = new Tone.GreaterThan(-value);
            +
            +			/**
            +			 *  negate the signal coming from the second input
            +			 *  @private
            +			 *  @type {Tone.Negate}
            +			 */
            +			this._lhNeg = this.input[1] = new Tone.Negate();
            +
            +			//connect
            +			this._neg.connect(this._gt);
            +			this._lhNeg.connect(this._gt, 0, 1);
            +		};
            +
            +		Tone.extend(Tone.LessThan, Tone.SignalBase);
            +
            +		/**
            +		 * The value to compare to the incoming signal.
            +		 * 
            +		 * @memberOf Tone.LessThan#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.LessThan.prototype, "value", {
            +			get : function(){
            +				return -this._gt.value;
            +			},
            +			set : function(value){
            +				this._gt.value = -value;
            +			}
            +		});
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.LessThan} `this`
            +		 */
            +		Tone.LessThan.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._neg.dispose();
            +			this._neg = null;
            +			this._gt.dispose();
            +			this._gt = null;
            +			this._lhNeg.dispose();
            +			this._lhNeg = null;
            +			return this;
            +		};
            +
            +		return Tone.LessThan;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class return the absolute value of an incoming signal
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 */
            +		Tone.Abs = function(){
            +			Tone.call(this, 1, 0);
            +
            +			/**
            +			 *  @type {Tone.LessThan}
            +			 *  @private
            +			 */
            +			this._ltz = new Tone.LessThan(0);
            +
            +			/**
            +			 *  @type {Tone.Select}
            +			 *  @private
            +			 */
            +			this._switch = this.output = new Tone.Select(2);
            +			
            +			/**
            +			 *  @type {Tone.Negate}
            +			 *  @private
            +			 */
            +			this._negate = new Tone.Negate();
            +
            +			//two signal paths, positive and negative
            +			this.input.connect(this._switch, 0, 0);
            +			this.input.connect(this._negate);
            +			this._negate.connect(this._switch, 0, 1);
            +			
            +			//the control signal
            +			this.input.chain(this._ltz, this._switch.gate);
            +		};
            +
            +		Tone.extend(Tone.Abs, Tone.SignalBase);
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.Abs} `this`
            +		 */
            +		Tone.Abs.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._switch.dispose();
            +			this._switch = null;
            +			this._ltz.dispose();
            +			this._ltz = null;
            +			this._negate.dispose();
            +			this._negate = null;
            +			return this;
            +		}; 
            +
            +		return Tone.Abs;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 * 	@class  outputs the greater of two signals. If a number is provided in the constructor
            +		 * 	        it will use that instead of the signal. 
            +		 * 	
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number=} max max value if provided. if not provided, it will use the
            +		 *                       signal value from input 1. 
            +		 */
            +		Tone.Max = function(max){
            +
            +			Tone.call(this, 2, 0);
            +			this.input[0] = this.context.createGain();
            +
            +			/**
            +			 *  the max signal
            +			 *  @type {Tone.Signal}
            +			 *  @private
            +			 */
            +			this._maxSignal = this.input[1] = new Tone.Signal(max);
            +
            +			/**
            +			 *  @type {Tone.Select}
            +			 *  @private
            +			 */
            +			this._ifThenElse = this.output = new Tone.IfThenElse();
            +
            +			/**
            +			 *  @type {Tone.Select}
            +			 *  @private
            +			 */
            +			this._gt = new Tone.GreaterThan();
            +
            +			//connections
            +			this.input[0].chain(this._gt, this._ifThenElse.if);
            +			this.input[0].connect(this._ifThenElse.then);
            +			this._maxSignal.connect(this._ifThenElse.else);
            +			this._maxSignal.connect(this._gt, 0, 1);
            +		};
            +
            +		Tone.extend(Tone.Max, Tone.SignalBase);
            +
            +		/**
            +		 * Will output the maximum between the incoming signal
            +		 * and `value`.
            +		 * @memberOf Tone.Max#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.Max.prototype, "value", {
            +			get : function(){
            +				return this._maxSignal.value;
            +			},
            +			set : function(max){
            +				this._maxSignal.value = max;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Max} `this`
            +		 */
            +		Tone.Max.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._maxSignal.dispose();
            +			this._ifThenElse.dispose();
            +			this._gt.dispose();
            +			this._maxSignal = null;
            +			this._ifThenElse = null;
            +			this._gt = null;
            +			return this;
            +		};
            +
            +		return Tone.Max;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 * 	@class  outputs the lesser of two signals. If a number is given 
            +		 * 	        in the constructor, it will use a signal and a number. 
            +		 * 	
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} min the minimum to compare to the incoming signal
            +		 */
            +		Tone.Min = function(min){
            +
            +			Tone.call(this, 2, 0);
            +			this.input[0] = this.context.createGain();
            +
            +			/**
            +			 *  @type {Tone.Select}
            +			 *  @private
            +			 */
            +			this._ifThenElse = this.output = new Tone.IfThenElse();
            +
            +			/**
            +			 *  @type {Tone.Select}
            +			 *  @private
            +			 */
            +			this._lt = new Tone.LessThan();
            +
            +			/**
            +			 *  the min signal
            +			 *  @type {Tone.Signal}
            +			 *  @private
            +			 */
            +			this._minSignal = this.input[1] = new Tone.Signal(min);
            +
            +			//connections
            +			this.input[0].chain(this._lt, this._ifThenElse.if);
            +			this.input[0].connect(this._ifThenElse.then);
            +			this._minSignal.connect(this._ifThenElse.else);
            +			this._minSignal.connect(this._lt, 0, 1);
            +		};
            +
            +		Tone.extend(Tone.Min, Tone.SignalBase);
            +
            +		/**
            +		 * Will output the minimum between the incoming signal
            +		 * and `value`.
            +		 * @memberOf Tone.Min#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.Min.prototype, "value", {
            +			get : function(){
            +				return this._minSignal.value;
            +			},
            +			set : function(max){
            +				this._minSignal.value = max;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Min} `this`
            +		 */
            +		Tone.Min.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._minSignal.dispose();
            +			this._ifThenElse.dispose();
            +			this._lt.dispose();
            +			this._minSignal = null;
            +			this._ifThenElse = null;
            +			this._lt = null;
            +			return this;
            +		};
            +
            +		return Tone.Min;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Signal-rate modulo operator. Specify the modulus and the 
            +		 *         number of bits of the incoming signal. Because the operator is composed of many components, 
            +		 *         fewer bits will improve performance. 
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} modulus the modulus to apply
            +		 *  @param {number} [bits=8]	optionally set the maximum bits the incoming signal can have. 
            +		 *                           	defaults to 8 meaning that incoming values must be in the range
            +		 *                            	[-255,255].
            +		 */
            +		Tone.Modulo = function(modulus, bits){
            +
            +			Tone.call(this);
            +
            +			bits = this.defaultArg(bits, 8);
            +
            +			/**
            +			 *  the array of Modulus Subroutine objects
            +			 *  @type {Array.<ModulusSubroutine>}
            +			 *  @private
            +			 */
            +			this._modChain = [];
            +
            +			//create all of the subroutines
            +			for (var i = bits - 1; i >= 0; i--){
            +				var mod = new ModuloSubroutine(modulus, Math.pow(2, i));
            +				this._modChain.push(mod);
            +			}
            +			this.connectSeries.apply(this, this._modChain);
            +			this.input.connect(this._modChain[0]);
            +			this._modChain[this._modChain.length - 1].connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.Modulo, Tone.SignalBase);
            +
            +		/**
            +		 * clean up
            +		 *  @returns {Tone.Modulo} `this`
            +		 */
            +		Tone.Modulo.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			for (var i = 0; i < this._modChain.length; i++) {
            +				this._modChain[i].dispose();
            +				this._modChain[i] = null;
            +			}
            +			this._modChain = null;
            +			return this;
            +		};
            +
            +		/**
            +		 *  @class applies a modolus at a single bit depth. 
            +		 *         uses this operation: http://stackoverflow.com/a/14842954
            +		 *
            +		 *  
            +		 *  @internal helper class for modulo
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 */
            +		var ModuloSubroutine = function(modulus, multiple){
            +
            +			var val = modulus * multiple;
            +			var arrayLength = 1024;
            +
            +			/**
            +			 *  the input node
            +			 */
            +			this.input = this.context.createGain();
            +
            +			/**
            +			 *  divide the incoming signal so it's on a 0 to 1 scale
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._div = new Tone.Multiply(1 / val);
            +
            +			/**
            +			 *  the curve that the waveshaper uses
            +			 *  @type {Float32Array}
            +			 *  @private
            +			 */
            +			this._curve = new Float32Array(1024);
            +
            +			/**
            +			 *  apply the equation logic
            +			 *  @type {WaveShaperNode}
            +			 *  @private
            +			 */
            +			this._operator = new Tone.WaveShaper(function(norm, pos){
            +				if (pos === arrayLength - 1){
            +					return -val;
            +				} else if (pos === 0){
            +					return val;
            +				} else {
            +					return 0;
            +				}
            +			}, arrayLength);
            +
            +			//connect it up
            +			this.input.chain(this._div, this._operator);
            +		};
            +
            +		Tone.extend(ModuloSubroutine);
            +
            +		/**
            +		 *  @override the default connection to connect the operator and the input to the next node
            +		 *  @private
            +		 */
            +		ModuloSubroutine.prototype.connect = function(node){
            +			this._operator.connect(node);
            +			this.input.connect(node);
            +		};
            +
            +		 /**
            +		  *  internal class clean up
            +		  */
            +		ModuloSubroutine.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._div.dispose();
            +			this._div = null;
            +			this._operator.disconnect();
            +			this._operator = null;
            +			this._curve = null;
            +		};
            +
            +		return Tone.Modulo;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  this is the maximum value that the divide can handle	
            +		 *  @type {number}
            +		 *  @const
            +		 */
            +		var MAX_VALUE = Math.pow(2, 13);
            +
            +		/**
            +		 *  @private
            +		 *  @static
            +		 *  @type {Array}
            +		 */
            +		var guessCurve = new Array(MAX_VALUE);
            +		//set the value
            +		for (var i = 0; i < guessCurve.length; i++){
            +			var normalized = (i / (guessCurve.length - 1)) * 2 - 1;
            +			if (normalized === 0){
            +				guessCurve[i] = 0;
            +			} else {
            +				guessCurve[i] = 1 / (normalized * MAX_VALUE);
            +			}
            +		}
            +
            +		/**
            +		 *  @class Compute the inverse of the input.
            +		 *         Uses this approximation algorithm: 
            +		 *         http://en.wikipedia.org/wiki/Multiplicative_inverse#Algorithms
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 *  @param {number} [precision=3] the precision of the calculation
            +		 */
            +		Tone.Inverse = function(precision){
            +
            +			Tone.call(this);
            +
            +			precision = this.defaultArg(precision, 3);
            +
            +			/**
            +			 *  a constant generator of the value 2
            +			 *  @private
            +			 *  @type {Tone.Signal}
            +			 */
            +			this._two = new Tone.Signal(2);
            +
            +			/**
            +			 *  starting guess is 0.1 times the input
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._guessMult = new Tone.Multiply(1/MAX_VALUE);
            +
            +			/**
            +			 *  produces a starting guess based on the input
            +			 *  @type {WaveShaperNode}
            +			 *  @private
            +			 */
            +			this._guess = new Tone.WaveShaper(guessCurve);
            +			this.input.chain(this._guessMult, this._guess);
            +
            +			/**
            +			 *  the array of inverse helpers
            +			 *  @type {Array}
            +			 *  @private
            +			 */
            +			this._inverses = new Array(precision);
            +
            +			//create the helpers
            +			for (var i = 0; i < precision; i++){
            +				var guess;
            +				if (i === 0){
            +					guess = this._guess;
            +				} else {
            +					guess = this._inverses[i-1];
            +				}
            +				var inv = new InverseHelper(guess, this._two);
            +				this.input.connect(inv);
            +				this._inverses[i] = inv;
            +			}
            +			this._inverses[precision-1].connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.Inverse, Tone.SignalBase);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Inverse} `this`
            +		 */
            +		Tone.Inverse.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			for (var i = 0; i < this._inverses.length; i++){
            +				this._inverses[i].dispose();
            +				this._inverses[i] = null;
            +			}
            +			this._inverses = null;
            +			this._two.dispose();
            +			this._two = null;
            +			this._guessMult.dispose();
            +			this._guessMult = null;
            +			this._guess.disconnect();
            +			this._guess = null;
            +			return this;
            +		};
            +
            +		// BEGIN INVERSE HELPER ///////////////////////////////////////////////////
            +
            +		/**
            +		 *  internal helper function for computing the inverse of a signal
            +		 *  @extends {Tone}
            +		 *  @constructor
            +		 *  @internal
            +		 */
            +		var InverseHelper = function(guess, two){
            +			this._outerMultiply = new Tone.Multiply();
            +			this._innerMultiply = new Tone.Multiply();
            +			this._subtract = new Tone.Subtract();
            +			//connections
            +			guess.connect(this._innerMultiply, 0, 1);
            +			two.connect(this._subtract, 0, 0);
            +			this._innerMultiply.connect(this._subtract, 0, 1);
            +			this._subtract.connect(this._outerMultiply, 0, 1);
            +			guess.connect(this._outerMultiply, 0, 0);
            +			this.output = this._outerMultiply;
            +			this.input = this._innerMultiply;
            +		};
            +
            +		Tone.extend(InverseHelper);
            +
            +		InverseHelper.prototype.dispose = function(){
            +			this._outerMultiply.dispose();
            +			this._outerMultiply = null;
            +			this._innerMultiply.dispose();
            +			this._innerMultiply = null;
            +			this._subtract.dispose();
            +			this._subtract = null;
            +		};
            +		
            +		// END INVERSE HELPER /////////////////////////////////////////////////////
            +
            +		return Tone.Inverse;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Divide by a value or signal. 
            +		 *         input 0: numerator. input 1: divisor. 
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 *  @param {number=} divisor if no value is provided, Tone.Divide will divide the first
            +		 *                         and second inputs. 
            +		 *  @param {number} [precision=3] the precision of the calculation
            +		 */
            +		Tone.Divide = function(divisor, precision){
            +
            +			Tone.call(this, 2, 0);
            +
            +			/**
            +			 *  the denominator value
            +			 *  @type {Tone.Signal}
            +			 *  @private
            +			 */
            +			this._denominator = null;
            +
            +			/**
            +			 *  the inverse
            +			 *  @type {Tone}
            +			 */
            +			this._inverse = new Tone.Inverse(precision);
            +
            +			/**
            +			 *  multiply input 0 by the inverse
            +			 *  @type {Tone.Multiply}
            +			 */
            +			this._mult = new Tone.Multiply();
            +
            +			if (isFinite(divisor)){
            +				this._denominator = new Tone.Signal(divisor);
            +				this._denominator.connect(this._inverse);
            +			}
            +			this.input[1] = this._inverse;
            +			this._inverse.connect(this._mult, 0, 1);
            +			this.input[0] = this.output = this._mult.input[0];
            +		};
            +
            +		Tone.extend(Tone.Divide, Tone.SignalBase);
            +
            +		/**
            +		 * The value being divided from the incoming signal. Note, that
            +		 * if Divide was constructed without a divisor, it expects
            +		 * that the signals to numberator will be connected to input 0 and 
            +		 * the denominator to input 1 and therefore will throw an error when 
            +		 * trying to set/get the value. 
            +		 * 
            +		 * @memberOf Tone.Divide#
            +		 * @type {number}
            +		 * @name value
            +		 */
            +		Object.defineProperty(Tone.Divide.prototype, "value", {
            +			get : function(){
            +				if (this._denominator !== null){
            +					return this._denominator.value;
            +				} else {
            +					throw new Error("cannot switch from signal to number");
            +				}
            +			},
            +			set : function(value){
            +				if (this._denominator !== null){
            +					this._denominator.value = value;
            +				} else {
            +					throw new Error("cannot switch from signal to number");
            +				}
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Divide} `this`
            +		 */
            +		Tone.Divide.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			if (this._denominator){
            +				this._denominator.dispose();
            +				this._denominator = null;
            +			}
            +			this._inverse.dispose();
            +			this._inverse = null;
            +			this._mult.dispose();
            +			this._mult = null;
            +			return this;
            +		};
            +
            +		return Tone.Divide;
            +	});
            +	toneModule( 
            +		function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class evaluate an expression at audio rate. 
            +		 *         parsing code modified from https://code.google.com/p/tapdigit/
            +		 *         Copyright 2011 2012 Ariya Hidayat, New BSD License
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 *  @param {string} expr the expression to generate
            +		 */
            +		Tone.Expr = function(){
            +
            +			var expr = this._replacements(Array.prototype.slice.call(arguments));
            +			var inputCount = this._parseInputs(expr);
            +
            +			/**
            +			 *  hold onto all of the nodes for disposal
            +			 *  @type {Array}
            +			 *  @private
            +			 */
            +			this._nodes = [];
            +
            +			/**
            +			 *  the inputs
            +			 *  @type {Array}
            +			 */
            +			this.input = new Array(inputCount);
            +
            +			//create a gain for each input
            +			for (var i = 0; i < inputCount; i++){
            +				this.input[i] = this.context.createGain();
            +			}
            +
            +			//parse the syntax tree
            +			var tree = this._parseTree(expr);
            +			//evaluate the results
            +			var result;
            +			try {
            +				result = this._eval(tree);
            +			} catch (e){
            +				this._disposeNodes();
            +				throw new Error("Could evaluate expression: "+expr);
            +			}
            +
            +			/**
            +			 *  the output node is the result of the expression
            +			 *  @type {*}
            +			 */
            +			this.output = result;
            +		};
            +
            +		Tone.extend(Tone.Expr, Tone.SignalBase);
            +
            +		//some helpers to cut down the amount of code
            +		function applyBinary(Constructor, args, self){
            +			var op = new Constructor();
            +			self._eval(args[0]).connect(op, 0, 0);
            +			self._eval(args[1]).connect(op, 0, 1);
            +			return op;
            +		}
            +		function applyUnary(Constructor, args, self){
            +			var op = new Constructor();
            +			self._eval(args[0]).connect(op, 0, 0);
            +			return op;
            +		}
            +		function getNumber(arg){
            +			return arg ? parseFloat(arg) : undefined;
            +		}
            +		function literalNumber(arg){
            +			return arg && arg.args ? parseFloat(arg.args) : undefined;
            +		}
            +
            +		/*
            +		 *  the Expressions that Tone.Expr can parse.
            +		 *
            +		 *  each expression belongs to a group and contains a regexp 
            +		 *  for selecting the operator as well as that operators method
            +		 *  
            +		 *  @type {Object}
            +		 *  @private
            +		 */
            +		Tone.Expr._Expressions = {
            +			//values
            +			"value" : {
            +				"signal" : {
            +					regexp : /^\d+\.\d+|^\d+/,
            +					method : function(arg){
            +						var sig = new Tone.Signal(getNumber(arg));
            +						return sig;
            +					}
            +				},
            +				"input" : {
            +					regexp : /^\$\d/,
            +					method : function(arg, self){
            +						return self.input[getNumber(arg.substr(1))];
            +					}
            +				}
            +			},
            +			//syntactic glue
            +			"glue" : {
            +				"(" : {
            +					regexp : /^\(/,
            +				},
            +				")" : {
            +					regexp : /^\)/,
            +				},
            +				"," : {
            +					regexp : /^,/,
            +				}
            +			},
            +			//functions
            +			"func" : {
            +				"abs" :  {
            +					regexp : /^abs/,
            +					method : applyUnary.bind(this, Tone.Abs)
            +				},
            +				"min" : {
            +					regexp : /^min/,
            +					method : applyBinary.bind(this, Tone.Min)
            +				},
            +				"max" : {
            +					regexp : /^max/,
            +					method : applyBinary.bind(this, Tone.Max)
            +				},
            +				"if" :  {
            +					regexp : /^if/,
            +					method : function(args, self){
            +						var op = new Tone.IfThenElse();
            +						self._eval(args[0]).connect(op.if);
            +						self._eval(args[1]).connect(op.then);
            +						self._eval(args[2]).connect(op.else);
            +						return op;
            +					}
            +				},
            +				"gt0" : {
            +					regexp : /^gt0/,
            +					method : applyUnary.bind(this, Tone.GreaterThanZero)
            +				},
            +				"eq0" : {
            +					regexp : /^eq0/,
            +					method : applyUnary.bind(this, Tone.EqualZero)
            +				},
            +				"inv" : {
            +					regexp : /^inv/,
            +					method : function(args, self){
            +						var precision = literalNumber(args[1]);
            +						var op = new Tone.Inverse(precision);
            +						self._eval(args[0]).connect(op);
            +						return op;
            +					}
            +				},
            +				"mod" : {
            +					regexp : /^mod/,
            +					method : function(args, self){
            +						var modulus = literalNumber(args[1]);
            +						var bits = literalNumber(args[2]);
            +						var op = new Tone.Modulo(modulus, bits);
            +						self._eval(args[0]).connect(op);
            +						return op;
            +					}
            +				},
            +				"pow" : {
            +					regexp : /^pow/,
            +					method : function(args, self){
            +						var exp = literalNumber(args[1]);
            +						var op = new Tone.Pow(exp);
            +						self._eval(args[0]).connect(op);
            +						return op;
            +					}
            +				},
            +			},
            +			//binary expressions
            +			"binary" : {
            +				"+" : {
            +					regexp : /^\+/,
            +					precedence : 1,
            +					method : applyBinary.bind(this, Tone.Add)
            +				},
            +				"-" : {
            +					regexp : /^\-/,
            +					precedence : 1,
            +					method : function(args, self){
            +						//both unary and binary op
            +						if (args.length === 1){
            +							return applyUnary(Tone.Negate, args, self);
            +						} else {
            +							return applyBinary(Tone.Subtract, args, self);
            +						}
            +					}
            +				},
            +				"*" : {
            +					regexp : /^\*/,
            +					precedence : 0,
            +					method : applyBinary.bind(this, Tone.Multiply)
            +				},
            +				"/" : {
            +					regexp : /^\//,
            +					precedence : 0,
            +					method : applyBinary.bind(this, Tone.Divide)
            +				},
            +				">" : {
            +					regexp : /^\>/,
            +					precedence : 2,
            +					method : applyBinary.bind(this, Tone.GreaterThan)
            +				},
            +				"<" : {
            +					regexp : /^</,
            +					precedence : 2,
            +					method : applyBinary.bind(this, Tone.LessThan)
            +				},
            +				"==" : {
            +					regexp : /^==/,
            +					precedence : 3,
            +					method : applyBinary.bind(this, Tone.Equal)
            +				},
            +				"&&" : {
            +					regexp : /^&&/,
            +					precedence : 4,
            +					method : applyBinary.bind(this, Tone.AND)
            +				},
            +				"||" : {
            +					regexp : /^\|\|/,
            +					precedence : 5,
            +					method : applyBinary.bind(this, Tone.OR)
            +				},
            +			},
            +			//unary expressions
            +			"unary" : {
            +				"-" : {
            +					regexp : /^\-/,
            +					method : applyUnary.bind(this, Tone.Negate)
            +				},
            +				"!" : {
            +					regexp : /^\!/,
            +					method : applyUnary.bind(this, Tone.NOT)
            +				},
            +			},
            +		};
            +			
            +		/**
            +		 *  @param   {string} expr the expression string
            +		 *  @return  {number}      the input count
            +		 *  @private
            +		 */
            +		Tone.Expr.prototype._parseInputs = function(expr){
            +			var inputArray = expr.match(/\$\d/g);
            +			var inputMax = 0;
            +			if (inputArray !== null){
            +				for (var i = 0; i < inputArray.length; i++){
            +					var inputNum = parseInt(inputArray[i].substr(1)) + 1;
            +					inputMax = Math.max(inputMax, inputNum);
            +				}
            +			}
            +			return inputMax;
            +		};
            +
            +		/**
            +		 *  @param   {Array} args 	an array of arguments
            +		 *  @return  {string} the results of the replacements being replaced
            +		 *  @private
            +		 */
            +		Tone.Expr.prototype._replacements = function(args){
            +			var expr = args.shift();
            +			for (var i = 0; i < args.length; i++){
            +				expr = expr.replace(/\%/i, args[i]);
            +			}
            +			return expr;
            +		};
            +
            +		/**
            +		 *  tokenize the expression based on the Expressions object
            +		 *  @param   {string} expr 
            +		 *  @return  {Object}      returns two methods on the tokenized list, next and peek
            +		 *  @private
            +		 */
            +		Tone.Expr.prototype._tokenize = function(expr){
            +			var position = -1;
            +			var tokens = [];
            +
            +			while(expr.length > 0){
            +				expr = expr.trim();
            +				var token =  getNextToken(expr);
            +				tokens.push(token);
            +				expr = expr.substr(token.value.length);
            +			}
            +
            +			function getNextToken(expr){
            +				for (var type in Tone.Expr._Expressions){
            +					var group = Tone.Expr._Expressions[type];
            +					for (var opName in group){
            +						var op = group[opName];
            +						var reg = op.regexp;
            +						var match = expr.match(reg);
            +						if (match !== null){
            +							return {
            +								type : type,
            +								value : match[0],
            +								method : op.method
            +							};
            +						}
            +					}
            +				}
            +				throw new SyntaxError("Unexpected token "+expr);
            +			}
            +
            +			return {
            +				next : function(){
            +					return tokens[++position];
            +				},
            +				peek : function(){
            +					return tokens[position + 1];
            +				}
            +			};
            +		};
            +
            +		/**
            +		 *  recursively parse the string expression into a syntax tree
            +		 *  
            +		 *  @param   {string} expr 
            +		 *  @return  {Object}
            +		 *  @private
            +		 */
            +		Tone.Expr.prototype._parseTree = function(expr){
            +			var lexer = this._tokenize(expr);
            +			var isUndef = this.isUndef.bind(this);
            +
            +			function matchSyntax(token, syn) {
            +				return !isUndef(token) && 
            +					token.type === "glue" &&
            +					token.value === syn;
            +			}
            +
            +			function matchGroup(token, groupName, prec) {
            +				var ret = false;
            +				var group = Tone.Expr._Expressions[groupName];
            +				if (!isUndef(token)){
            +					for (var opName in group){
            +						var op = group[opName];
            +						if (op.regexp.test(token.value)){
            +							if (!isUndef(prec)){
            +								if(op.precedence === prec){	
            +									return true;
            +								}
            +							} else {
            +								return true;
            +							}
            +						}
            +					}
            +				}
            +				return ret;
            +			}
            +
            +			function parseExpression(precedence) {
            +				if (isUndef(precedence)){
            +					precedence = 5;
            +				}
            +				var expr;
            +				if (precedence < 0){
            +					expr = parseUnary();
            +				} else {
            +					expr = parseExpression(precedence-1);
            +				}
            +				var token = lexer.peek();
            +				while (matchGroup(token, "binary", precedence)) {
            +					token = lexer.next();
            +					expr = {
            +						operator: token.value,
            +						method : token.method,
            +						args : [
            +							expr,
            +							parseExpression(precedence)
            +						]
            +					};
            +					token = lexer.peek();
            +				}
            +				return expr;
            +			}
            +
            +			function parseUnary() {
            +				var token, expr;
            +				token = lexer.peek();
            +				if (matchGroup(token, "unary")) {
            +					token = lexer.next();
            +					expr = parseUnary();
            +					return {
            +						operator: token.value,
            +						method : token.method,
            +						args : [expr]
            +					};
            +				}
            +				return parsePrimary();
            +			}
            +
            +			function parsePrimary() {
            +				var token, expr;
            +				token = lexer.peek();
            +				if (isUndef(token)) {
            +					throw new SyntaxError("Unexpected termination of expression");
            +				}
            +				if (token.type === "func") {
            +					token = lexer.next();
            +					return parseFunctionCall(token);
            +				}
            +				if (token.type === "value") {
            +					token = lexer.next();
            +					return {
            +						method : token.method,
            +						args : token.value
            +					};
            +				}
            +				if (matchSyntax(token, "(")) {
            +					lexer.next();
            +					expr = parseExpression();
            +					token = lexer.next();
            +					if (!matchSyntax(token, ")")) {
            +						throw new SyntaxError("Expected )");
            +					}
            +					return expr;
            +				}
            +				throw new SyntaxError("Parse error, cannot process token " + token.value);
            +			}
            +
            +			function parseFunctionCall(func) {
            +				var token, args = [];
            +				token = lexer.next();
            +				if (!matchSyntax(token, "(")) {
            +					throw new SyntaxError("Expected ( in a function call \"" + func.value + "\"");
            +				}
            +				token = lexer.peek();
            +				if (!matchSyntax(token, ")")) {
            +					args = parseArgumentList();
            +				}
            +				token = lexer.next();
            +				if (!matchSyntax(token, ")")) {
            +					throw new SyntaxError("Expected ) in a function call \"" + func.value + "\"");
            +				}
            +				return {
            +					method : func.method,
            +					args : args,
            +					name : name
            +				};
            +			}
            +
            +			function parseArgumentList() {
            +				var token, expr, args = [];
            +				while (true) {
            +					expr = parseExpression();
            +					if (isUndef(expr)) {
            +						// TODO maybe throw exception?
            +						break;
            +					}
            +					args.push(expr);
            +					token = lexer.peek();
            +					if (!matchSyntax(token, ",")) {
            +						break;
            +					}
            +					lexer.next();
            +				}
            +				return args;
            +			}
            +
            +			return parseExpression();
            +		};
            +
            +		/**
            +		 *  recursively evaluate the expression tree
            +		 *  @param   {Object} tree 
            +		 *  @return  {AudioNode}      the resulting audio node from the expression
            +		 *  @private
            +		 */
            +		Tone.Expr.prototype._eval = function(tree){
            +			if (!this.isUndef(tree)){
            +				var node = tree.method(tree.args, this);
            +				this._nodes.push(node);
            +				return node;
            +			} 
            +		};
            +
            +		/**
            +		 *  dispose all the nodes
            +		 *  @private
            +		 */
            +		Tone.Expr.prototype._disposeNodes = function(){
            +			for (var i = 0; i < this._nodes.length; i++){
            +				var node = this._nodes[i];
            +				if (this.isFunction(node.dispose)) {
            +					node.dispose();
            +				} else if (this.isFunction(node.disconnect)) {
            +					node.disconnect();
            +				}
            +				node = null;
            +				this._nodes[i] = null;
            +			}
            +			this._nodes = null;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 */
            +		Tone.Expr.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._disposeNodes();
            +		};
            +
            +		return Tone.Expr;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Convert an incoming signal between 0,1 to an equal power gain scale.
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 */
            +		Tone.EqualPowerGain = function(){
            +
            +			/**
            +			 *  @type {Tone.WaveShaper}
            +			 *  @private
            +			 */
            +			this._eqPower = this.input = this.output = new Tone.WaveShaper(function(val){
            +				if (Math.abs(val) < 0.001){
            +					//should output 0 when input is 0
            +					return 0;
            +				} else {
            +					return this.equalPowerScale(val);
            +				}
            +			}.bind(this), 4096);
            +		};
            +
            +		Tone.extend(Tone.EqualPowerGain, Tone.SignalBase);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.EqualPowerGain} `this`
            +		 */
            +		Tone.EqualPowerGain.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._eqPower.dispose();
            +			this._eqPower = null;
            +			return this;
            +		};
            +
            +		return Tone.EqualPowerGain;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 * @class  Equal power fading control values:
            +		 * 	       0 = 100% input 0
            +		 * 	       1 = 100% input 1
            +		 *
            +		 * @constructor
            +		 * @extends {Tone}
            +		 * @param {number} [initialFade=0.5]
            +		 */		
            +		Tone.CrossFade = function(initialFade){
            +
            +			Tone.call(this, 2, 1);
            +
            +			/**
            +			 *  the first input. input "a".
            +			 *  @type {GainNode}
            +			 */
            +			this.a = this.input[0] = this.context.createGain();
            +
            +			/**
            +			 *  the second input. input "b"
            +			 *  @type {GainNode}
            +			 */
            +			this.b = this.input[1] = this.context.createGain();
            +
            +			/**
            +			 *  Controls the amount of wet signal 
            +			 *  which is mixed into the dry signal. 
            +			 *  Values between 0-1.
            +			 *  
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Signal.Units.Normal);
            +
            +			/**
            +			 *  equal power gain cross fade
            +			 *  @private
            +			 *  @type {Tone.EqualPowerGain}
            +			 */
            +			this._equalPowerA = new Tone.EqualPowerGain();
            +
            +			/**
            +			 *  equal power gain cross fade
            +			 *  @private
            +			 *  @type {Tone.EqualPowerGain}
            +			 */
            +			this._equalPowerB = new Tone.EqualPowerGain();
            +			
            +			/**
            +			 *  invert the incoming signal
            +			 *  @private
            +			 *  @type {Tone}
            +			 */
            +			this._invert = new Tone.Expr("1 - $0");
            +
            +			//connections
            +			this.a.connect(this.output);
            +			this.b.connect(this.output);
            +			this.fade.chain(this._equalPowerB, this.b.gain);
            +			this.fade.chain(this._invert, this._equalPowerA, this.a.gain);
            +		};
            +
            +		Tone.extend(Tone.CrossFade);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.CrossFade} `this`
            +		 */
            +		Tone.CrossFade.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._equalPowerA.dispose();
            +			this._equalPowerA = null;
            +			this._equalPowerB.dispose();
            +			this._equalPowerB = null;
            +			this.fade.dispose();
            +			this.fade = null;
            +			this._invert.dispose();
            +			this._invert = null;
            +			this.a.disconnect();
            +			this.a = null;
            +			this.b.disconnect();
            +			this.b = null;
            +			return this;
            +		};
            +
            +		return Tone.CrossFade;
            +	});
            +
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Filter object which allows for all of the same native methods
            +		 *          as the BiquadFilter (with AudioParams implemented as Tone.Signals)
            +		 *          but adds the ability to set the filter rolloff at -12 (default), 
            +		 *          -24 and -48. 
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @param {number|Object} [freq=350] the frequency
            +		 *  @param {string} [type=lowpass] the type of filter
            +		 *  @param {number} [rolloff=-12] the rolloff which is the drop per octave. 
            +		 *                                 3 choices: -12, -24, and -48
            +		 */
            +		Tone.Filter = function(){
            +			Tone.call(this);
            +
            +			var options = this.optionsObject(arguments, ["frequency", "type", "rolloff"], Tone.Filter.defaults);
            +
            +			/**
            +			 *  the filter(s)
            +			 *  @type {Array.<BiquadFilterNode>}
            +			 *  @private
            +			 */
            +			this._filters = [];
            +
            +			/**
            +			 *  the frequency of the filter
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = new Tone.Signal(options.frequency, Tone.Signal.Units.Frequency);
            +
            +			/**
            +			 *  the detune parameter
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.detune = new Tone.Signal(0);
            +
            +			/**
            +			 *  the gain of the filter, only used in certain filter types
            +			 *  @type {AudioParam}
            +			 */
            +			this.gain = new Tone.Signal(options.gain, Tone.Signal.Units.Decibels);
            +
            +			/**
            +			 *  the Q or Quality of the filter
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.Q = new Tone.Signal(options.Q);
            +
            +			/**
            +			 *  the type of the filter
            +			 *  @type {string}
            +			 *  @private
            +			 */
            +			this._type = options.type;
            +
            +			/**
            +			 *  the rolloff value of the filter
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._rolloff = options.rolloff;
            +
            +			//set the rolloff;
            +			this.rolloff = options.rolloff;
            +		};
            +
            +		Tone.extend(Tone.Filter);
            +
            +		/**
            +		 *  the default parameters
            +		 *
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.Filter.defaults = {
            +			"type" : "lowpass",
            +			"frequency" : 350,
            +			"rolloff" : -12,
            +			"Q" : 1,
            +			"gain" : 0,
            +		};
            +
            +		/**
            +		 * The type of the filter
            +		 * @memberOf Tone.Filter#
            +		 * @type {string}
            +		 * @name type
            +		 */
            +		Object.defineProperty(Tone.Filter.prototype, "type", {
            +			get : function(){
            +				return this._type;
            +			},
            +			set : function(type){
            +				this._type = type;
            +				for (var i = 0; i < this._filters.length; i++){
            +					this._filters[i].type = type;
            +				}
            +			}
            +		});
            +
            +		/**
            +		 * The rolloff of the filter which is the drop in db
            +		 * per octave. Implemented internally by cascading filters.
            +		 * Only accepts the values -12, -24, and -48.
            +		 * @memberOf Tone.Filter#
            +		 * @type {number}
            +		 * @name rolloff
            +		 */
            +		Object.defineProperty(Tone.Filter.prototype, "rolloff", {
            +			get : function(){
            +				return this._rolloff;
            +			},
            +			set : function(rolloff){
            +				var cascadingCount = Math.log(rolloff / -12) / Math.LN2 + 1;
            +				//check the rolloff is valid
            +				if (cascadingCount % 1 !== 0){
            +					throw new RangeError("Filter rolloff can only be -12, -24, or -48");
            +				}
            +				this._rolloff = rolloff;
            +				//first disconnect the filters and throw them away
            +				this.input.disconnect();
            +				for (var i = 0; i < this._filters.length; i++) {
            +					this._filters[i].disconnect();
            +					this._filters[i] = null;
            +				}
            +				this._filters = new Array(cascadingCount);
            +				for (var count = 0; count < cascadingCount; count++){
            +					var filter = this.context.createBiquadFilter();
            +					filter.type = this._type;
            +					this.frequency.connect(filter.frequency);
            +					this.detune.connect(filter.detune);
            +					this.Q.connect(filter.Q);
            +					this.gain.connect(filter.gain);
            +					this._filters[count] = filter;
            +				}
            +				//connect them up
            +				var connectionChain = [this.input].concat(this._filters).concat([this.output]);
            +				this.connectSeries.apply(this, connectionChain);
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @return {Tone.Filter} `this`
            +		 */
            +		Tone.Filter.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			for (var i = 0; i < this._filters.length; i++) {
            +				this._filters[i].disconnect();
            +				this._filters[i] = null;
            +			}
            +			this._filters = null;
            +			this.frequency.dispose();
            +			this.Q.dispose();
            +			this.frequency = null;
            +			this.Q = null;
            +			this.detune.dispose();
            +			this.detune = null;
            +			this.gain.dispose();
            +			this.gain = null;
            +			return this;
            +		};
            +
            +		return Tone.Filter;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Split the incoming signal into three bands (low, mid, high)
            +		 *         with two crossover frequency controls. 
            +		 *
            +		 *  @extends {Tone}
            +		 *  @constructor
            +		 *  @param {number} lowFrequency the low/mid crossover frequency
            +		 *  @param {number} highFrequency the mid/high crossover frequency
            +		 */
            +		Tone.MultibandSplit = function(){
            +			var options = this.optionsObject(arguments, ["lowFrequency", "highFrequency"], Tone.MultibandSplit.defaults);
            +
            +			/**
            +			 *  the input
            +			 *  @type {GainNode}
            +			 */
            +			this.input = this.context.createGain();
            +
            +			/**
            +			 *  the outputs
            +			 *  @type {Array}
            +			 */
            +			this.output = new Array(3);
            +
            +			/**
            +			 *  the low band
            +			 *  @type {Tone.Filter}
            +			 */
            +			this.low = this.output[0] = new Tone.Filter(0, "lowpass");
            +
            +			/**
            +			 *  the lower filter of the mid band
            +			 *  @type {Tone.Filter}
            +			 *  @private
            +			 */
            +			this._lowMidFilter = new Tone.Filter(0, "highpass");
            +
            +			/**
            +			 *  the mid band
            +			 *  @type {Tone.Filter}
            +			 */
            +			this.mid = this.output[1] = new Tone.Filter(0, "lowpass");
            +
            +			/**
            +			 *  the high band
            +			 *  @type {Tone.Filter}
            +			 */
            +			this.high = this.output[2] = new Tone.Filter(0, "highpass");
            +
            +			/**
            +			 *  the low/mid crossover frequency
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.lowFrequency = new Tone.Signal(options.lowFrequency);
            +
            +			/**
            +			 *  the mid/high crossover frequency
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.highFrequency = new Tone.Signal(options.highFrequency);
            +
            +			this.input.fan(this.low, this.high);
            +			this.input.chain(this._lowMidFilter, this.mid);
            +			//the frequency control signal
            +			this.lowFrequency.connect(this.low.frequency);
            +			this.lowFrequency.connect(this._lowMidFilter.frequency);
            +			this.highFrequency.connect(this.mid.frequency);
            +			this.highFrequency.connect(this.high.frequency);
            +		};
            +
            +		Tone.extend(Tone.MultibandSplit);
            +
            +		/**
            +		 *  @private
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.MultibandSplit.defaults = {
            +			"lowFrequency" : 400,
            +			"highFrequency" : 2500
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.MultibandSplit} `this`
            +		 */
            +		Tone.MultibandSplit.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.low.dispose();
            +			this._lowMidFilter.dispose();
            +			this.mid.dispose();
            +			this.high.dispose();
            +			this.lowFrequency.dispose();
            +			this.highFrequency.dispose();
            +			this.low = null;
            +			this._lowMidFilter = null;
            +			this.mid = null;
            +			this.high = null;
            +			this.lowFrequency = null;
            +			this.highFrequency = null;
            +			return this;
            +		};
            +
            +		return Tone.MultibandSplit;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A 3 band EQ with control over low, mid, and high gain as
            +		 *         well as the low and high crossover frequencies. 
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  
            +		 *  @param {number|object} [lowLevel=0] the gain applied to the lows (in db)
            +		 *  @param {number} [midLevel=0] the gain applied to the mid (in db)
            +		 *  @param {number} [highLevel=0] the gain applied to the high (in db)
            +		 */
            +		Tone.EQ = function(){
            +
            +			var options = this.optionsObject(arguments, ["low", "mid", "high"], Tone.EQ.defaults);
            +
            +			/**
            +			 *  the output node
            +			 *  @type {GainNode}
            +			 */
            +			this.output = this.context.createGain();
            +
            +			/**
            +			 *  the multiband split
            +			 *  @type {Tone.MultibandSplit}
            +			 *  @private
            +			 */
            +			this._multibandSplit = new Tone.MultibandSplit({
            +				"lowFrequency" : options.lowFrequency,
            +				"highFrequency" : options.highFrequency
            +			});
            +
            +			/**
            +			 *  input node
            +			 */
            +			this.input = this._multibandSplit;
            +
            +			/**
            +			 *  the low gain
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._lowGain = this.context.createGain();
            +
            +			/**
            +			 *  the mid gain
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._midGain = this.context.createGain();
            +
            +			/**
            +			 *  the high gain
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._highGain = this.context.createGain();
            +
            +			/**
            +			 *  the low/mid crossover frequency
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.lowFrequency = this._multibandSplit.lowFrequency;
            +
            +			/**
            +			 *  the mid/high crossover frequency
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.highFrequency = this._multibandSplit.highFrequency;
            +
            +			//the frequency bands
            +			this._multibandSplit.low.chain(this._lowGain, this.output);
            +			this._multibandSplit.mid.chain(this._midGain, this.output);
            +			this._multibandSplit.high.chain(this._highGain, this.output);
            +			//set the gains
            +			this.high = options.low;
            +			this.mid = options.mid;
            +			this.low = options.high;
            +		};
            +
            +		Tone.extend(Tone.EQ);
            +
            +		/**
            +		 *  the default values
            +		 *  @type {Object}
            +		 *  @static
            +		 */
            +		Tone.EQ.defaults = {
            +			"low" : 0,
            +			"mid" : 0,
            +			"high" : 0,
            +			"lowFrequency" : 400,
            +			"highFrequency" : 2500
            +		};
            +
            +		/**
            +		 * The gain in decibels of the low part
            +		 * @memberOf Tone.EQ#
            +		 * @type {number}
            +		 * @name low
            +		 */
            +		Object.defineProperty(Tone.EQ.prototype, "low", {
            +			get : function(){
            +				return this.gainToDb(this._lowGain.gain.value);
            +			},
            +			set : function(db){
            +				this._lowGain.gain.value = this.dbToGain(db);
            +			}
            +		});
            +
            +		/**
            +		 * the gain in decibels of the mid
            +		 * @memberOf Tone.EQ#
            +		 * @type {number}
            +		 * @name mid
            +		 */
            +		Object.defineProperty(Tone.EQ.prototype, "mid", {
            +			get : function(){
            +				return this.gainToDb(this._midGain.gain.value);
            +			},
            +			set : function(db){
            +				this._midGain.gain.value = this.dbToGain(db);
            +			}
            +		});
            +
            +		/**
            +		 * the gain in decibels of the high
            +		 * @memberOf Tone.EQ#
            +		 * @type {number}
            +		 * @name high
            +		 */
            +		Object.defineProperty(Tone.EQ.prototype, "high", {
            +			get : function(){
            +				return this.gainToDb(this._highGain.gain.value);
            +			},
            +			set : function(db){
            +				this._highGain.gain.value = this.dbToGain(db);
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.EQ} `this`
            +		 */
            +		Tone.EQ.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._multibandSplit.dispose();
            +			this._lowGain.disconnect();
            +			this._midGain.disconnect();
            +			this._highGain.disconnect();
            +			this._multibandSplit = null;
            +			this.lowFrequency = null;
            +			this.highFrequency = null;
            +			this._lowGain = null;
            +			this._midGain = null;
            +			this._highGain = null;
            +			return this;
            +		};
            +
            +		return Tone.EQ;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +		
            +		/**
            +		 *  @class  performs a linear scaling on an input signal.
            +		 *          Scales a normal gain input range [0,1] to between
            +		 *          outputMin and outputMax
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} [outputMin=0]
            +		 *  @param {number} [outputMax=1]
            +		 */
            +		Tone.Scale = function(outputMin, outputMax){
            +
            +			/** 
            +			 *  @private
            +			 *  @type {number}
            +			 */
            +			this._outputMin = this.defaultArg(outputMin, 0);
            +
            +			/** 
            +			 *  @private
            +			 *  @type {number}
            +			 */
            +			this._outputMax = this.defaultArg(outputMax, 1);
            +
            +
            +			/** 
            +			 *  @private
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._scale = this.input = new Tone.Multiply(1);
            +			
            +			/** 
            +			 *  @private
            +			 *  @type {Tone.Add}
            +			 *  @private
            +			 */
            +			this._add = this.output = new Tone.Add(0);
            +
            +			this._scale.connect(this._add);
            +			this._setRange();
            +		};
            +
            +		Tone.extend(Tone.Scale, Tone.SignalBase);
            +
            +		/**
            +		 * The minimum output value.
            +		 * @memberOf Tone.Scale#
            +		 * @type {number}
            +		 * @name min
            +		 */
            +		Object.defineProperty(Tone.Scale.prototype, "min", {
            +			get : function(){
            +				return this._outputMin;
            +			},
            +			set : function(min){
            +				this._outputMin = min;
            +				this._setRange();
            +			}
            +		});
            +
            +		/**
            +		 * The maximum output value.
            +		 * @memberOf Tone.Scale#
            +		 * @type {number}
            +		 * @name max
            +		 */
            +		Object.defineProperty(Tone.Scale.prototype, "max", {
            +			get : function(){
            +				return this._outputMax;
            +			},
            +			set : function(max){
            +				this._outputMax = max;
            +				this._setRange();
            +			}
            +		});
            +
            +		/**
            +		 *  set the values
            +		 *  @private
            +		 */
            +		Tone.Scale.prototype._setRange = function() {
            +			this._add.value = this._outputMin;
            +			this._scale.value = this._outputMax - this._outputMin;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Scale} `this`
            +		 */
            +		Tone.Scale.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._add.dispose();
            +			this._add = null;
            +			this._scale.dispose();
            +			this._scale = null;
            +			return this;
            +		}; 
            +
            +		return Tone.Scale;
            +	});
            +
            +	toneModule( 
            +	function(Tone){
            +		
            +		/**
            +		 *  @class  performs an exponential scaling on an input signal.
            +		 *          Scales a normal gain range [0,1] exponentially
            +		 *          to the output range of outputMin to outputMax.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} [outputMin=0]
            +		 *  @param {number} [outputMax=1]
            +		 *  @param {number} [exponent=2] the exponent which scales the incoming signal
            +		 */
            +		Tone.ScaleExp = function(outputMin, outputMax, exponent){
            +
            +			/**
            +			 *  scale the input to the output range
            +			 *  @type {Tone.Scale}
            +			 *  @private
            +			 */
            +			this._scale = this.output = new Tone.Scale(outputMin, outputMax);
            +
            +			/**
            +			 *  @private
            +			 *  @type {Tone.Pow}
            +			 *  @private
            +			 */
            +			this._exp = this.input = new Tone.Pow(this.defaultArg(exponent, 2));
            +
            +			this._exp.connect(this._scale);
            +		};
            +
            +		Tone.extend(Tone.ScaleExp, Tone.SignalBase);
            +
            +		/**
            +		 * The minimum output value.
            +		 * @memberOf Tone.ScaleExp#
            +		 * @type {number}
            +		 * @name exponent
            +		 */
            +		Object.defineProperty(Tone.ScaleExp.prototype, "exponent", {
            +			get : function(){
            +				return this._exp.value;
            +			},
            +			set : function(exp){
            +				this._exp.value = exp;
            +			}
            +		});
            +
            +		/**
            +		 * The minimum output value.
            +		 * @memberOf Tone.ScaleExp#
            +		 * @type {number}
            +		 * @name min
            +		 */
            +		Object.defineProperty(Tone.ScaleExp.prototype, "min", {
            +			get : function(){
            +				return this._scale.min;
            +			},
            +			set : function(min){
            +				this._scale.min = min;
            +			}
            +		});
            +
            +		/**
            +		 * The maximum output value.
            +		 * @memberOf Tone.ScaleExp#
            +		 * @type {number}
            +		 * @name max
            +		 */
            +		Object.defineProperty(Tone.ScaleExp.prototype, "max", {
            +			get : function(){
            +				return this._scale.max;
            +			},
            +			set : function(max){
            +				this._scale.max = max;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.ScaleExp} `this`
            +		 */
            +		Tone.ScaleExp.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._scale.dispose();
            +			this._scale = null;
            +			this._exp.dispose();
            +			this._exp = null;
            +			return this;
            +		}; 
            +
            +
            +		return Tone.ScaleExp;
            +	});
            +
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A comb filter with feedback
            +		 *
            +		 *  @extends {Tone}
            +		 *  @constructor
            +		 *  @param {number} [minDelay=0.01] the minimum delay time which the filter can have
            +		 *  @param {number} [maxDelay=1] the maximum delay time which the filter can have
            +		 */
            +		Tone.FeedbackCombFilter = function(){
            +
            +			Tone.call(this);
            +			var options = this.optionsObject(arguments, ["minDelay", "maxDelay"], Tone.FeedbackCombFilter.defaults);
            +
            +			var minDelay = options.minDelay;
            +			var maxDelay = options.maxDelay;
            +			//the delay * samplerate = number of samples. 
            +			// buffersize / number of samples = number of delays needed per buffer frame
            +			var delayCount = Math.ceil(this.bufferSize / (minDelay * this.context.sampleRate));
            +			//set some ranges
            +			delayCount = Math.min(delayCount, 10);
            +			delayCount = Math.max(delayCount, 1);
            +
            +			/**
            +			 *  the number of filter delays
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._delayCount = delayCount;
            +
            +			/**
            +			 *  @type {Array.<FilterDelay>}
            +			 *  @private
            +			 */
            +			this._delays = new Array(this._delayCount);
            +
            +			/**
            +			 *  the resonance control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.resonance = new Tone.Signal(options.resonance, Tone.Signal.Units.Normal);
            +
            +			/**
            +			 *  scale the resonance value to the normal range
            +			 *  @type {Tone.Scale}
            +			 *  @private
            +			 */
            +			this._resScale = new Tone.ScaleExp(0.01, 1 / this._delayCount - 0.001, 0.5);
            +
            +			/**
            +			 *  internal flag for keeping track of when frequency
            +			 *  correction has been used
            +			 *  @type {boolean}
            +			 *  @private
            +			 */
            +			this._highFrequencies = false;
            +
            +			/**
            +			 *  internal counter of delayTime
            +			 *  @type {Tone.TIme}
            +			 *  @private
            +			 */
            +			this._delayTime = options.delayTime;
            +
            +			/**
            +			 *  the feedback node
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._feedback = this.context.createGain();
            +
            +			//make the filters
            +			for (var i = 0; i < this._delayCount; i++) {
            +				var delay = this.context.createDelay(maxDelay);
            +				delay.delayTime.value = minDelay;
            +				delay.connect(this._feedback);
            +				this._delays[i] = delay;
            +			}
            +
            +			//connections
            +			this.connectSeries.apply(this, this._delays);
            +			this.input.connect(this._delays[0]);
            +			//set the delay to the min value initially
            +			this._feedback.connect(this._delays[0]);
            +			//resonance control
            +			this.resonance.chain(this._resScale, this._feedback.gain);
            +			this._feedback.connect(this.output);
            +			this.delayTime = options.delayTime;
            +		};
            +
            +		Tone.extend(Tone.FeedbackCombFilter);
            +
            +		/**
            +		 *  the default parameters
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.FeedbackCombFilter.defaults = {
            +			"resonance" : 0.5,
            +			"minDelay" : 0.1,
            +			"maxDelay" : 1,
            +			"delayTime" : 0.1
            +		};
            +
            +		/**
            +		 * the delay time of the FeedbackCombFilter
            +		 * @memberOf Tone.FeedbackCombFilter#
            +		 * @type {Tone.Time}
            +		 * @name delayTime
            +		 */
            +		Object.defineProperty(Tone.FeedbackCombFilter.prototype, "delayTime", {
            +			get : function(){
            +				return this._delayTime;
            +			},
            +			set : function(delayAmount){
            +				this._delayTime = delayAmount;
            +				delayAmount = this.toSeconds(delayAmount);
            +				//the number of samples to delay by
            +				var sampleRate = this.context.sampleRate;
            +				var delaySamples = sampleRate * delayAmount;
            +				// delayTime corection when frequencies get high
            +				var now = this.now() + this.bufferTime;
            +				var cutoff = 100;
            +				if (delaySamples < cutoff){
            +					this._highFrequencies = true;
            +					var changeNumber = Math.round((delaySamples / cutoff) * this._delayCount);
            +					for (var i = 0; i < changeNumber; i++) {
            +						this._delays[i].delayTime.setValueAtTime(1 / sampleRate + delayAmount, now);
            +					}
            +					delayAmount = Math.floor(delaySamples) / sampleRate;
            +				} else if (this._highFrequencies){
            +					this._highFrequencies = false;
            +					for (var j = 0; j < this._delays.length; j++) {
            +						this._delays[j].delayTime.setValueAtTime(delayAmount, now);
            +					}
            +				}
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.FeedbackCombFilter} `this`
            +		 */
            +		Tone.FeedbackCombFilter.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			//dispose the filter delays
            +			for (var i = 0; i < this._delays.length; i++) {
            +				this._delays[i].disconnect();
            +				this._delays[i] = null;
            +			}
            +			this._delays = null;
            +			this.resonance.dispose();
            +			this.resonance = null;
            +			this._resScale.dispose();
            +			this._resScale = null;
            +			this._feedback.disconnect();
            +			this._feedback = null;
            +			return this;
            +		};
            +
            +		return Tone.FeedbackCombFilter;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Follow the envelope of the incoming signal. 
            +		 *          Careful with small (< 0.02) attack or decay values. 
            +		 *          The follower has some ripple which gets exaggerated
            +		 *          by small values. 
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @param {Tone.Time} [attack = 0.05] 
            +		 *  @param {Tone.Time} [release = 0.5] 
            +		 */
            +		Tone.Follower = function(){
            +
            +			Tone.call(this);
            +			var options = this.optionsObject(arguments, ["attack", "release"], Tone.Follower.defaults);
            +
            +			/**
            +			 *  @type {Tone.Abs}
            +			 *  @private
            +			 */
            +			this._abs = new Tone.Abs();
            +
            +			/**
            +			 *  the lowpass filter which smooths the input
            +			 *  @type {BiquadFilterNode}
            +			 *  @private
            +			 */
            +			this._filter = this.context.createBiquadFilter();
            +			this._filter.type = "lowpass";
            +			this._filter.frequency.value = 0;
            +			this._filter.Q.value = -100;
            +
            +			/**
            +			 *  @type {WaveShaperNode}
            +			 *  @private
            +			 */
            +			this._frequencyValues = new Tone.WaveShaper();
            +			
            +			/**
            +			 *  @type {Tone.Subtract}
            +			 *  @private
            +			 */
            +			this._sub = new Tone.Subtract();
            +
            +			/**
            +			 *  @type {DelayNode}
            +			 *  @private
            +			 */
            +			this._delay = this.context.createDelay();
            +			this._delay.delayTime.value = this.bufferTime;
            +
            +			/**
            +			 *  this keeps it far from 0, even for very small differences
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._mult = new Tone.Multiply(10000);
            +
            +			/**
            +			 *  @private
            +			 *  @type {number}
            +			 */
            +			this._attack = options.attack;
            +
            +			/**
            +			 *  @private
            +			 *  @type {number}
            +			 */
            +			this._release = options.release;
            +
            +			//the smoothed signal to get the values
            +			this.input.chain(this._abs, this._filter, this.output);
            +			//the difference path
            +			this._abs.connect(this._sub, 0, 1);
            +			this._filter.chain(this._delay, this._sub);
            +			//threshold the difference and use the thresh to set the frequency
            +			this._sub.chain(this._mult, this._frequencyValues, this._filter.frequency);
            +			//set the attack and release values in the table
            +			this._setAttackRelease(this._attack, this._release);
            +		};
            +
            +		Tone.extend(Tone.Follower);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.Follower.defaults = {
            +			"attack" : 0.05, 
            +			"release" : 0.5
            +		};
            +
            +		/**
            +		 *  sets the attack and release times in the wave shaper
            +		 *  @param   {Tone.Time} attack  
            +		 *  @param   {Tone.Time} release 
            +		 *  @private
            +		 */
            +		Tone.Follower.prototype._setAttackRelease = function(attack, release){
            +			var minTime = this.bufferTime;
            +			attack = this.secondsToFrequency(this.toSeconds(attack));
            +			release = this.secondsToFrequency(this.toSeconds(release));
            +			attack = Math.max(attack, minTime);
            +			release = Math.max(release, minTime);
            +			this._frequencyValues.setMap(function(val){
            +				if (val <= 0){
            +					return attack;
            +				} else {
            +					return release;
            +				} 
            +			});
            +		};
            +
            +		/**
            +		 * The attack time.
            +		 * @memberOf Tone.Follower#
            +		 * @type {Tone.Time}
            +		 * @name attack
            +		 */
            +		Object.defineProperty(Tone.Follower.prototype, "attack", {
            +			get : function(){
            +				return this._attack;
            +			},
            +			set : function(attack){
            +				this._attack = attack;
            +				this._setAttackRelease(this._attack, this._release);	
            +			}
            +		});
            +
            +		/**
            +		 * The release time.
            +		 * @memberOf Tone.Follower#
            +		 * @type {Tone.Time}
            +		 * @name release
            +		 */
            +		Object.defineProperty(Tone.Follower.prototype, "release", {
            +			get : function(){
            +				return this._release;
            +			},
            +			set : function(release){
            +				this._release = release;
            +				this._setAttackRelease(this._attack, this._release);	
            +			}
            +		});
            +
            +		/**
            +		 *  borrows the connect method from Signal so that the output can be used
            +		 *  as a control signal {@link Tone.Signal}
            +		 */
            +		Tone.Follower.prototype.connect = Tone.Signal.prototype.connect;
            +
            +		/**
            +		 *  dispose
            +		 *  @returns {Tone.Follower} `this`
            +		 */
            +		Tone.Follower.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._filter.disconnect();
            +			this._filter = null;
            +			this._frequencyValues.disconnect();
            +			this._frequencyValues = null;
            +			this._delay.disconnect();
            +			this._delay = null;
            +			this._sub.disconnect();
            +			this._sub = null;
            +			this._abs.dispose();
            +			this._abs = null;
            +			this._mult.dispose();
            +			this._mult = null;
            +			this._curve = null;
            +			return this;
            +		};
            +
            +		return Tone.Follower;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Only pass signal through when it's signal exceeds the
            +		 *          specified threshold.
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @param {number} [threshold = -40] the threshold in Decibels
            +		 *  @param {number} [attack = 0.1] the follower's attack time
            +		 *  @param {number} [release = 0.1] the follower's release time
            +		 */
            +		Tone.Gate = function(){
            +			
            +			Tone.call(this);
            +			var options = this.optionsObject(arguments, ["threshold", "attack", "release"], Tone.Gate.defaults);
            +
            +			/**
            +			 *  @type {Tone.Follower}
            +			 *  @private
            +			 */
            +			this._follower = new Tone.Follower(options.attack, options.release);
            +
            +			/**
            +			 *  @type {Tone.GreaterThan}
            +			 *  @private
            +			 */
            +			this._gt = new Tone.GreaterThan(this.dbToGain(options.threshold));
            +
            +			//the connections
            +			this.input.connect(this.output);
            +			//the control signal
            +			this.input.chain(this._gt, this._follower, this.output.gain);
            +		};
            +
            +		Tone.extend(Tone.Gate);
            +
            +		/**
            +		 *  @const
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.Gate.defaults = {
            +			"attack" : 0.1, 
            +			"release" : 0.1,
            +			"threshold" : -40
            +		};
            +
            +		/**
            +		 * The threshold of the gate in decibels
            +		 * @memberOf Tone.Gate#
            +		 * @type {number}
            +		 * @name threshold
            +		 */
            +		Object.defineProperty(Tone.Gate.prototype, "threshold", {
            +			get : function(){
            +				return this.gainToDb(this._gt.value);
            +			}, 
            +			set : function(thresh){
            +				this._gt.value = this.dbToGain(thresh);
            +			}
            +		});
            +
            +		/**
            +		 * The attack speed of the gate
            +		 * @memberOf Tone.Gate#
            +		 * @type {Tone.Time}
            +		 * @name attack
            +		 */
            +		Object.defineProperty(Tone.Gate.prototype, "attack", {
            +			get : function(){
            +				return this._follower.attack;
            +			}, 
            +			set : function(attackTime){
            +				this._follower.attack = attackTime;
            +			}
            +		});
            +
            +		/**
            +		 * The release speed of the gate
            +		 * @memberOf Tone.Gate#
            +		 * @type {Tone.Time}
            +		 * @name release
            +		 */
            +		Object.defineProperty(Tone.Gate.prototype, "release", {
            +			get : function(){
            +				return this._follower.release;
            +			}, 
            +			set : function(releaseTime){
            +				this._follower.release = releaseTime;
            +			}
            +		});
            +
            +		/**
            +		 *  dispose
            +		 *  @returns {Tone.Gate} `this`
            +		 */
            +		Tone.Gate.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._follower.dispose();
            +			this._gt.dispose();
            +			this._follower = null;
            +			this._gt = null;
            +			return this;
            +		};
            +
            +		return Tone.Gate;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +		
            +		/**
            +		 *  @class  a sample accurate clock built on an oscillator.
            +		 *          Invokes the tick method at the set rate
            +		 *
            +		 * 	@internal
            +		 * 	@constructor
            +		 * 	@extends {Tone}
            +		 * 	@param {Tone.Frequency} frequency the rate of the callback
            +		 * 	@param {function} callback the callback to be invoked with the time of the audio event
            +		 */
            +		Tone.Clock = function(frequency, callback){
            +
            +			/**
            +			 *  the oscillator
            +			 *  @type {OscillatorNode}
            +			 *  @private
            +			 */
            +			this._oscillator = null;
            +
            +			/**
            +			 *  the script processor which listens to the oscillator
            +			 *  @type {ScriptProcessorNode}
            +			 *  @private
            +			 */
            +			this._jsNode = this.context.createScriptProcessor(this.bufferSize, 1, 1);
            +			this._jsNode.onaudioprocess = this._processBuffer.bind(this);
            +
            +			/**
            +			 *  the rate control signal
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = new Tone.Signal(frequency);
            +
            +			/**
            +			 *  whether the tick is on the up or down
            +			 *  @type {boolean}
            +			 *  @private
            +			 */
            +			this._upTick = false;
            +
            +			/**
            +			 *  the callback which is invoked on every tick
            +			 *  with the time of that tick as the argument
            +			 *  @type {function(number)}
            +			 */
            +			this.tick = callback;
            +
            +			//setup
            +			this._jsNode.noGC();
            +		};
            +
            +		Tone.extend(Tone.Clock);
            +
            +		/**
            +		 *  start the clock
            +		 *  @param {Tone.Time} time the time when the clock should start
            +		 *  @returns {Tone.Clock} `this`
            +		 */
            +		Tone.Clock.prototype.start = function(time){
            +			if (!this._oscillator){
            +				this._oscillator = this.context.createOscillator();
            +				this._oscillator.type = "square";
            +				this._oscillator.connect(this._jsNode);
            +				//connect it up
            +				this.frequency.connect(this._oscillator.frequency);
            +				this._upTick = false;
            +				var startTime = this.toSeconds(time);
            +				this._oscillator.start(startTime);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  stop the clock
            +		 *  @param {Tone.Time} time the time when the clock should stop
            +		 *  @param {function} onend called when the oscilator stops
            +		 *  @returns {Tone.Clock} `this`
            +		 */
            +		Tone.Clock.prototype.stop = function(time, onend){
            +			if (this._oscillator){
            +				var now = this.now();
            +				var stopTime = this.toSeconds(time, now);
            +				this._oscillator.stop(stopTime);
            +				this._oscillator = null;
            +				//set a timeout for when it stops
            +				if (time){
            +					setTimeout(onend, (stopTime - now) * 1000);
            +				} else {
            +					onend();
            +				}
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  @private
            +		 *  @param  {AudioProcessingEvent} event
            +		 */
            +		Tone.Clock.prototype._processBuffer = function(event){
            +			var now = this.defaultArg(event.playbackTime, this.now());
            +			var bufferSize = this._jsNode.bufferSize;
            +			var incomingBuffer = event.inputBuffer.getChannelData(0);
            +			var upTick = this._upTick;
            +			var self = this;
            +			for (var i = 0; i < bufferSize; i++){
            +				var sample = incomingBuffer[i];
            +				if (sample > 0 && !upTick){
            +					upTick = true;	
            +					//get the callback out of audio thread
            +					setTimeout(function(){
            +						//to account for the double buffering
            +						var tickTime = now + self.samplesToSeconds(i + bufferSize * 2);
            +						return function(){
            +							if (self.tick){
            +								self.tick(tickTime);
            +							}
            +						};
            +					}(), 0); // jshint ignore:line
            +				} else if (sample < 0 && upTick){
            +					upTick = false;
            +				}
            +			}
            +			this._upTick = upTick;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Clock} `this`
            +		 */
            +		Tone.Clock.prototype.dispose = function(){
            +			this._jsNode.disconnect();
            +			this.frequency.dispose();
            +			this.frequency = null;
            +			if (this._oscillator){
            +				this._oscillator.disconnect();
            +				this._oscillator = null;
            +			}
            +			this._jsNode.onaudioprocess = function(){};
            +			this._jsNode = null;
            +			this.tick = null;
            +			return this;
            +		};
            +
            +		return Tone.Clock;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  Time can be descibed in a number of ways. 
            +		 *  Any Method which accepts Tone.Time as a parameter will accept: 
            +		 *  
            +		 *  Numbers, which will be taken literally as the time (in seconds). 
            +		 *  
            +		 *  Notation, ("4n", "8t") describes time in BPM and time signature relative values. 
            +		 *  
            +		 *  Transport Time, ("4:3:2") will also provide tempo and time signature relative times 
            +		 *  in the form BARS:QUARTERS:SIXTEENTHS.
            +		 *  
            +		 *  Frequency, ("8hz") is converted to the length of the cycle in seconds.
            +		 *  
            +		 *  Now-Relative, ("+1") prefix any of the above with "+" and it will be interpreted as 
            +		 *  "the current time plus whatever expression follows".
            +		 *  
            +		 *  Expressions, ("3:0 + 2 - (1m / 7)") any of the above can also be combined 
            +		 *  into a mathematical expression which will be evaluated to compute the desired time.
            +		 *  
            +		 *  No Argument, for methods which accept time, no argument will be interpreted as 
            +		 *  "now" (i.e. the currentTime).
            +		 *
            +		 *  [Tone.Time Wiki](https://github.com/TONEnoTONE/Tone.js/wiki/Time)
            +		 *  
            +		 *  @typedef {number|string|undefined} Tone.Time 
            +		 */
            +		
            +		/**
            +		 *  Frequency can be described similar to time, except ultimately the
            +		 *  values are converted to frequency instead of seconds. A number
            +		 *  is taken literally as the value in hertz, or any of the Tone.Time
            +		 *  encodings can be used. 
            +		 *  
            +		 *  @typedef {number|Tone.Time} Tone.Frequency
            +		 */
            +
            +		/**
            +		 *  @class  oscillator-based transport allows for simple musical timing
            +		 *          supports tempo curves and time changes
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 */
            +		Tone.Transport = function(){
            +
            +			/**
            +			 *  watches the main oscillator for timing ticks
            +			 *  initially starts at 120bpm
            +			 *  
            +			 *  @private
            +			 *  @type {Tone.Clock}
            +			 */
            +			this._clock = new Tone.Clock(1, this._processTick.bind(this));
            +
            +			/** 
            +			 *  @type {boolean}
            +			 */
            +			this.loop = false;
            +
            +			/**
            +			 *  @type {TransportState}
            +			 */
            +			this.state = TransportState.STOPPED;
            +		};
            +
            +		Tone.extend(Tone.Transport);
            +
            +		/** 
            +		 * @private 
            +		 * @type {number} 
            +		 */
            +		var timelineTicks = 0;
            +
            +		/** 
            +		 * @private 
            +		 * @type {number} 
            +		 */
            +		var transportTicks = 0;
            +
            +		/** 
            +		 * @private
            +		 * @type {number}
            +		 */
            +		var tatum = 12;
            +
            +		/**
            +		 *  controls which beat the swing is applied to
            +		 *  defaults to an 16th note
            +		 *  @private
            +		 *  @type {number}
            +		 */
            +		var swingTatum = 3;
            +
            +		/**
            +		 *  controls which beat the swing is applied to
            +		 *  @private
            +		 *  @type {number}
            +		 */
            +		var swingAmount = 0;
            +
            +		/** 
            +		 * @private
            +		 * @type {number}
            +		 */
            +		var transportTimeSignature = 4;
            +
            +		/** 
            +		 * @private
            +		 * @type {number}
            +		 */
            +		var loopStart = 0;
            +
            +		/** 
            +		 * @private
            +		 * @type {number}
            +		 */
            +		var loopEnd = tatum * 4;
            +
            +		/** 
            +		 * @private
            +		 * @type {Array}
            +		 */
            +		var intervals = [];
            +		
            +		/** 
            +		 * @private
            +		 * @type {Array}
            +		 */
            +		var timeouts = [];
            +		
            +		/** 
            +		 * @private
            +		 * @type {Array}
            +		 */
            +		var transportTimeline = [];
            +		
            +		/** 
            +		 * @private
            +		 * @type {number}
            +		 */
            +		var timelineProgress = 0;
            +
            +		/** 
            +		 *  All of the synced components
            +		 *  @private 
            +		 *  @type {Array<Tone>}
            +		 */
            +		var SyncedSources = [];
            +
            +		/**
            +		 *  @enum
            +		 */
            +		 var TransportState = {
            +		 	STARTED : "started",
            +		 	PAUSED : "paused",
            +		 	STOPPED : "stopped"
            +		 };
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	TICKS
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  called on every tick
            +		 *  @param   {number} tickTime clock relative tick time
            +		 *  @private
            +		 */
            +		Tone.Transport.prototype._processTick = function(tickTime){
            +			if (this.state === TransportState.STARTED){
            +				if (swingAmount > 0 && timelineTicks % tatum !== 0 && timelineTicks % swingTatum === 0){
            +					//add some swing
            +					tickTime += Tone.Transport.ticksToSeconds(swingTatum) * swingAmount;
            +				}
            +				processIntervals(tickTime);
            +				processTimeouts(tickTime);
            +				processTimeline(tickTime);
            +				transportTicks += 1;
            +				timelineTicks += 1;
            +				if (this.loop){
            +					if (timelineTicks === loopEnd){
            +						this._setTicks(loopStart);
            +					}
            +				}
            +			}
            +		};
            +
            +		/**
            +		 *  jump to a specific tick in the timeline
            +		 *  updates the timeline callbacks
            +		 *  
            +		 *  @param   {number} ticks the tick to jump to
            +		 *  @private
            +		 */
            +		Tone.Transport.prototype._setTicks = function(ticks){
            +			timelineTicks = ticks;
            +			for (var i = 0; i < transportTimeline.length; i++){
            +				var timeout = transportTimeline[i];
            +				if (timeout.callbackTick() >= ticks){
            +					timelineProgress = i;
            +					break;
            +				}
            +			}
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	EVENT PROCESSING
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  process the intervals
            +		 *  @param  {number} time 
            +		 */
            +		var processIntervals = function(time){
            +			for (var i = 0, len = intervals.length; i<len; i++){
            +				var interval = intervals[i];
            +				if (interval.testInterval(transportTicks)){
            +					interval.doCallback(time);
            +				}
            +			}
            +		};
            +
            +		/**
            +		 *  process the timeouts
            +		 *  @param  {number} time 
            +		 */
            +		var processTimeouts = function(time){
            +			var removeTimeouts = 0;
            +			for (var i = 0, len = timeouts.length; i<len; i++){
            +				var timeout = timeouts[i];
            +				var callbackTick = timeout.callbackTick();
            +				if (callbackTick <= transportTicks){
            +					timeout.doCallback(time);
            +					removeTimeouts++;
            +				} else if (callbackTick > transportTicks){
            +					break;
            +				} 
            +			}
            +			//remove the timeouts off the front of the array after they've been called
            +			timeouts.splice(0, removeTimeouts);
            +		};
            +
            +		/**
            +		 *  process the transportTimeline events
            +		 *  @param  {number} time 
            +		 */
            +		var processTimeline = function(time){
            +			for (var i = timelineProgress, len = transportTimeline.length; i<len; i++){
            +				var evnt = transportTimeline[i];
            +				var callbackTick = evnt.callbackTick();
            +				if (callbackTick === timelineTicks){
            +					timelineProgress = i;
            +					evnt.doCallback(time);
            +				} else if (callbackTick > timelineTicks){
            +					break;
            +				} 
            +			}
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	INTERVAL
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  intervals are recurring events 
            +		 *
            +		 *  ```javascript
            +		 *  //triggers a callback every 8th note with the exact time of the event
            +		 *  Tone.Transport.setInterval(function(time){
            +		 *  	envelope.triggerAttack(time);
            +		 *  }, "8n");
            +		 *  ```
            +		 *  
            +		 *  @param {function} callback
            +		 *  @param {Tone.Time}   interval 
            +		 *  @param {Object}   ctx  the context the function is invoked in
            +		 *  @return {number} the id of the interval
            +		 */
            +		Tone.Transport.prototype.setInterval = function(callback, interval, ctx){
            +			var tickTime = this.toTicks(interval);
            +			var timeout = new TimelineEvent(callback, ctx, tickTime, transportTicks);
            +			intervals.push(timeout);
            +			return timeout.id;
            +		};
            +
            +		/**
            +		 *  clear an interval from the processing array
            +		 *  @param  {number} rmInterval 	the interval to remove
            +		 *  @return {boolean}            	true if the event was removed
            +		 */
            +		Tone.Transport.prototype.clearInterval = function(rmInterval){
            +			for (var i = 0; i < intervals.length; i++){
            +				var interval = intervals[i];
            +				if (interval.id === rmInterval){
            +					intervals.splice(i, 1);
            +					return true;
            +				}
            +			}
            +			return false;
            +		};
            +
            +		/**
            +		 *  removes all of the intervals that are currently set
            +		 *  @return {boolean}            	true if the event was removed
            +		 */
            +		Tone.Transport.prototype.clearIntervals = function(){
            +			var willRemove = intervals.length > 0;
            +			intervals = [];
            +			return willRemove;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	TIMEOUT
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  set a timeout to occur after time from now. NB: the transport must be 
            +		 *  running for this to be triggered. All timeout events are cleared when the 
            +		 *  transport is stopped. 
            +		 *
            +		 *  ```javascript
            +		 *  //trigger an event to happen 1 second from now
            +		 *  Tone.Transport.setTimeout(function(time){
            +		 *  	player.start(time);
            +		 *  }, 1)
            +		 *  ```
            +		 *  
            +		 *  @param {function} callback 
            +		 *  @param {Tone.Time}   time     
            +		 *  @param {Object}   ctx      the context to invoke the callback in
            +		 *  @return {number} the id of the timeout for clearing timeouts
            +		 */
            +		Tone.Transport.prototype.setTimeout = function(callback, time, ctx){
            +			var ticks = this.toTicks(time);
            +			var timeout = new TimelineEvent(callback, ctx, ticks + transportTicks, 0);
            +			//put it in the right spot
            +			for (var i = 0, len = timeouts.length; i<len; i++){
            +				var testEvnt = timeouts[i];
            +				if (testEvnt.callbackTick() > timeout.callbackTick()){
            +					timeouts.splice(i, 0, timeout);
            +					return timeout.id;
            +				}
            +			}
            +			//otherwise push it on the end
            +			timeouts.push(timeout);
            +			return timeout.id;
            +		};
            +
            +		/**
            +		 *  clear the timeout based on it's ID
            +		 *  @param  {number} timeoutID 
            +		 *  @return {boolean}           true if the timeout was removed
            +		 */
            +		Tone.Transport.prototype.clearTimeout = function(timeoutID){
            +			for (var i = 0; i < timeouts.length; i++){
            +				var testTimeout = timeouts[i];
            +				if (testTimeout.id === timeoutID){
            +					timeouts.splice(i, 1);
            +					return true;
            +				}
            +			}
            +			return false;
            +		};
            +
            +		/**
            +		 *  removes all of the timeouts that are currently set
            +		 *  @return {boolean}            	true if the event was removed
            +		 */
            +		Tone.Transport.prototype.clearTimeouts = function(){
            +			var willRemove = timeouts.length > 0;
            +			timeouts = [];
            +			return willRemove;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	TIMELINE
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  Timeline events are synced to the transportTimeline of the Tone.Transport
            +		 *  Unlike Timeout, Timeline events will restart after the 
            +		 *  Tone.Transport has been stopped and restarted. 
            +		 *
            +		 *  ```javascript
            +		 *  //trigger the start of a part on the 16th measure
            +		 *  Tone.Transport.setTimeline(function(time){
            +		 *  	part.start(time);
            +		 *  }, "16m");
            +		 *  ```
            +		 *
            +		 *  
            +		 *  @param {function} 	callback 	
            +		 *  @param {Tome.Time}  timeout  
            +		 *  @param {Object}   	ctx      	the context in which the funtion is called
            +		 *  @return {number} 				the id for clearing the transportTimeline event
            +		 */
            +		Tone.Transport.prototype.setTimeline = function(callback, timeout, ctx){
            +			var ticks = this.toTicks(timeout);
            +			var timelineEvnt = new TimelineEvent(callback, ctx, ticks, 0);
            +			//put it in the right spot
            +			for (var i = timelineProgress, len = transportTimeline.length; i<len; i++){
            +				var testEvnt = transportTimeline[i];
            +				if (testEvnt.callbackTick() > timelineEvnt.callbackTick()){
            +					transportTimeline.splice(i, 0, timelineEvnt);
            +					return timelineEvnt.id;
            +				}
            +			}
            +			//otherwise push it on the end
            +			transportTimeline.push(timelineEvnt);
            +			return timelineEvnt.id;
            +		};
            +
            +		/**
            +		 *  clear the transportTimeline event from the 
            +		 *  @param  {number} timelineID 
            +		 *  @return {boolean} true if it was removed
            +		 */
            +		Tone.Transport.prototype.clearTimeline = function(timelineID){
            +			for (var i = 0; i < transportTimeline.length; i++){
            +				var testTimeline = transportTimeline[i];
            +				if (testTimeline.id === timelineID){
            +					transportTimeline.splice(i, 1);
            +					return true;
            +				}
            +			}
            +			return false;
            +		};
            +
            +		/**
            +		 *  remove all events from the timeline
            +		 *  @returns {boolean} true if the events were removed
            +		 */
            +		Tone.Transport.prototype.clearTimelines = function(){
            +			timelineProgress = 0;
            +			var willRemove = transportTimeline.length > 0;
            +			transportTimeline = [];
            +			return willRemove;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	TIME CONVERSIONS
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  turns the time into
            +		 *  @param  {Tone.Time} time
            +		 *  @return {number}      
            +		 */
            +		Tone.Transport.prototype.toTicks = function(time){
            +			//get the seconds
            +			var seconds = this.toSeconds(time);
            +			var quarter = this.notationToSeconds("4n");
            +			var quarters = seconds / quarter;
            +			var tickNum = quarters * tatum;
            +			//quantize to tick value
            +			return Math.round(tickNum);
            +		};
            +
            +		/**
            +		 *  get the transport time
            +		 *  @return {string} in transportTime format (measures:beats:sixteenths)
            +		 */
            +		Tone.Transport.prototype.getTransportTime = function(){
            +			var quarters = timelineTicks / tatum;
            +			var measures = Math.floor(quarters / transportTimeSignature);
            +			var sixteenths = Math.floor((quarters % 1) * 4);
            +			quarters = Math.floor(quarters) % transportTimeSignature;
            +			var progress = [measures, quarters, sixteenths];
            +			return progress.join(":");
            +		};
            +
            +		/**
            +		 *  set the transport time, jump to the position right away
            +		 *  	
            +		 *  @param {Tone.Time} progress 
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.setTransportTime = function(progress){
            +			var ticks = this.toTicks(progress);
            +			this._setTicks(ticks);
            +			return this;
            +		};
            +
            +		/**
            +		 *  returns the time of the next beat
            +		 *  @param  {string} [subdivision="4n"]
            +		 *  @return {number} 	the time in seconds of the next subdivision
            +		 */
            +		Tone.Transport.prototype.nextBeat = function(subdivision){
            +			subdivision = this.defaultArg(subdivision, "4n");
            +			var tickNum = this.toTicks(subdivision);
            +			var remainingTicks = (transportTicks % tickNum);
            +			var nextTick = remainingTicks;
            +			if (remainingTicks > 0){
            +				nextTick = tickNum - remainingTicks;
            +			}
            +			return this.ticksToSeconds(nextTick);
            +		};
            +
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	START/STOP/PAUSE
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  start the transport and all sources synced to the transport
            +		 *  
            +		 *  @param  {Tone.Time} time
            +		 *  @param  {Tone.Time=} offset the offset position to start
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.start = function(time, offset){
            +			if (this.state === TransportState.STOPPED || this.state === TransportState.PAUSED){
            +				if (!this.isUndef(offset)){
            +					this._setTicks(this.toTicks(offset));
            +				}
            +				this.state = TransportState.STARTED;
            +				var startTime = this.toSeconds(time);
            +				this._clock.start(startTime);
            +				//call start on each of the synced sources
            +				for (var i = 0; i < SyncedSources.length; i++){
            +					var source = SyncedSources[i].source;
            +					var delay = SyncedSources[i].delay;
            +					source.start(startTime + delay);
            +				}
            +			}
            +			return this;
            +		};
            +
            +
            +		/**
            +		 *  stop the transport and all sources synced to the transport
            +		 *  
            +		 *  @param  {Tone.Time} time
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.stop = function(time){
            +			if (this.state === TransportState.STARTED || this.state === TransportState.PAUSED){
            +				var stopTime = this.toSeconds(time);
            +				this._clock.stop(stopTime, this._onended.bind(this));
            +				//call start on each of the synced sources
            +				for (var i = 0; i < SyncedSources.length; i++){
            +					var source = SyncedSources[i].source;
            +					source.stop(stopTime);
            +				}
            +			} else {
            +				this._onended();
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  invoked when the transport is stopped
            +		 *  @private
            +		 */
            +		Tone.Transport.prototype._onended = function(){
            +			transportTicks = 0;
            +			this._setTicks(0);
            +			this.clearTimeouts();
            +			this.state = TransportState.STOPPED;
            +		};
            +
            +		/**
            +		 *  pause the transport and all sources synced to the transport
            +		 *  
            +		 *  @param  {Tone.Time} time
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.pause = function(time){
            +			if (this.state === TransportState.STARTED){
            +				this.state = TransportState.PAUSED;
            +				var stopTime = this.toSeconds(time);
            +				this._clock.stop(stopTime);
            +				//call pause on each of the synced sources
            +				for (var i = 0; i < SyncedSources.length; i++){
            +					var source = SyncedSources[i].source;
            +					source.pause(stopTime);
            +				}
            +			}
            +			return this;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	SETTERS/GETTERS
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  set the BPM
            +		 *  optionally ramp to the bpm over some time
            +		 *  @param {number} bpm   
            +		 *  @param {Tone.Time=} rampTime 
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.setBpm = function(bpm, rampTime){
            +			var quarterTime = this.notationToSeconds(tatum.toString() + "n", bpm, transportTimeSignature) / 4;
            +			quarterTime = this.secondsToFrequency(quarterTime);
            +			if (this.isUndef(rampTime)){
            +				this._clock.frequency.value = quarterTime;
            +			} else {
            +				this._clock.frequency.rampTo(quarterTime, rampTime);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  return the current BPM
            +		 *  
            +		 *  @return {number} 
            +		 */
            +		Tone.Transport.prototype.getBpm = function(){
            +			//convert the current frequency of the oscillator to bpm
            +			var freq = this._clock.frequency.value;
            +			return 60 * (freq / tatum);
            +		};
            +
            +		/**
            +		 *  set the time signature
            +		 *  
            +		 *  ```javascript
            +		 *  this.setTimeSignature(3, 8); // 3/8
            +		 *  this.setTimeSignature(4); // 4/4
            +		 *  ```
            +		 *  
            +		 *  @param {number} numerator  the numerator of the time signature
            +		 *  @param {number} [denominator=4] the denominator of the time signature. this should
            +		 *                                   be a multiple of 2. 
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.setTimeSignature = function(numerator, denominator){
            +			denominator = this.defaultArg(denominator, 4);
            +			transportTimeSignature = numerator / (denominator / 4);
            +			return this;
            +		};
            +
            +		/**
            +		 *  return the time signature as just the numerator over 4. 
            +		 *  for example 4/4 would return 4 and 6/8 would return 3
            +		 *  
            +		 *  @return {number} 
            +		 */
            +		Tone.Transport.prototype.getTimeSignature = function(){
            +			return transportTimeSignature;
            +		};
            +
            +		/**
            +		 *  set the loop start position
            +		 *  
            +		 *  @param {Tone.Time} startPosition
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.setLoopStart = function(startPosition){
            +			loopStart = this.toTicks(startPosition);
            +			return this;
            +		};
            +
            +		/**
            +		 *  set the loop start position
            +		 *  
            +		 *  @param {Tone.Time} endPosition
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.setLoopEnd = function(endPosition){
            +			loopEnd = this.toTicks(endPosition);
            +			return this;
            +		};
            +
            +		/**
            +		 *  shorthand loop setting
            +		 *  @param {Tone.Time} startPosition 
            +		 *  @param {Tone.Time} endPosition   
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.setLoopPoints = function(startPosition, endPosition){
            +			this.setLoopStart(startPosition);
            +			this.setLoopEnd(endPosition);
            +			return this;
            +		};
            +
            +		/**
            +		 *  set the amount of swing which is applied to the subdivision (defaults to 16th notes)
            +		 *  @param {number} amount a value between 0-1 where 1 equal to the note + half the subdivision
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.setSwing = function(amount){
            +			//scale the values to a normal range
            +			swingAmount = amount * 0.5;
            +			return this;
            +		};
            +
            +		/**
            +		 *  set the subdivision which the swing will be applied to. the starting values is a 16th note. 
            +		 *  
            +		 *  ```javascript
            +		 *  Tone.Transport.setSwingSubdivision("8n"); //the eight note will be swing by the "swing amount"
            +		 *  ```
            +		 *  
            +		 *  @param {string} subdivision the subdivision in notation (i.e. 8n, 16n, 8t).
            +		 *                              value must be less than a quarter note.
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.setSwingSubdivision = function(subdivision){
            +			swingTatum = this.toTicks(subdivision);
            +			return this;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	SYNCING
            +		///////////////////////////////////////////////////////////////////////////////
            +		
            +
            +		/**
            +		 *  Sync a source to the transport so that 
            +		 *  @param  {Tone.Source} source the source to sync to the transport
            +		 *  @param {Tone.Time} delay (optionally) start the source with a delay from the transport
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.syncSource = function(source, startDelay){
            +			SyncedSources.push({
            +				source : source,
            +				delay : this.toSeconds(this.defaultArg(startDelay, 0))
            +			});
            +			return this;
            +		};
            +
            +		/**
            +		 *  remove the source from the list of Synced Sources
            +		 *  
            +		 *  @param  {Tone.Source} source [description]
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.unsyncSource = function(source){
            +			for (var i = 0; i < SyncedSources.length; i++){
            +				if (SyncedSources[i].source === source){
            +					SyncedSources.splice(i, 1);
            +				}
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  attaches the signal to the tempo control signal so that 
            +		 *  any changes in the tempo will change the signal in the same
            +		 *  ratio
            +		 *  
            +		 *  @param  {Tone.Signal} signal 
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.syncSignal = function(signal){
            +			//overreaching. fix this. 
            +			signal.sync(this._clock.frequency);
            +			return this;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Transport} `this`
            +		 */
            +		Tone.Transport.prototype.dispose = function(){
            +			this._clock.dispose();
            +			this._clock = null;
            +			return this;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	TIMELINE EVENT
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  @static
            +		 *  @type {number}
            +		 */
            +		var TimelineEventIDCounter = 0;
            +
            +		/**
            +		 *  A Timeline event
            +		 *
            +		 *  @constructor
            +		 *  @internal
            +		 *  @param {function(number)} callback   
            +		 *  @param {Object}   context    
            +		 *  @param {number}   tickTime
            +	 	 *  @param {number}   startTicks
            +		 */
            +		var TimelineEvent = function(callback, context, tickTime, startTicks){
            +			this.startTicks = startTicks;
            +			this.tickTime = tickTime;
            +			this.callback = callback;
            +			this.context = context;
            +			this.id = TimelineEventIDCounter++;
            +		};
            +		
            +		/**
            +		 *  invoke the callback in the correct context
            +		 *  passes in the playback time
            +		 *  
            +		 *  @param  {number} playbackTime 
            +		 */
            +		TimelineEvent.prototype.doCallback = function(playbackTime){
            +			this.callback.call(this.context, playbackTime); 
            +		};
            +
            +		/**
            +		 *  get the tick which the callback is supposed to occur on
            +		 *  
            +		 *  @return {number} 
            +		 */
            +		TimelineEvent.prototype.callbackTick = function(){
            +			return this.startTicks + this.tickTime;
            +		};
            +
            +		/**
            +		 *  test if the tick occurs on the interval
            +		 *  
            +		 *  @param  {number} tick 
            +		 *  @return {boolean}      
            +		 */
            +		TimelineEvent.prototype.testInterval = function(tick){
            +			return (tick - this.startTicks) % this.tickTime === 0;
            +		};
            +
            +
            +		///////////////////////////////////////////////////////////////////////////////
            +		//	AUGMENT TONE'S PROTOTYPE TO INCLUDE TRANSPORT TIMING
            +		///////////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  tests if a string is musical notation
            +		 *  i.e.:
            +		 *  	4n = quarter note
            +		 *   	2m = two measures
            +		 *    	8t = eighth-note triplet
            +		 *  defined in "Tone/core/Transport"
            +		 *  
            +		 *  @return {boolean} 
            +		 *  @method isNotation
            +		 *  @lends Tone.prototype.isNotation
            +		 */
            +		Tone.prototype.isNotation = (function(){
            +			var notationFormat = new RegExp(/[0-9]+[mnt]$/i);
            +			return function(note){
            +				return notationFormat.test(note);
            +			};
            +		})();
            +
            +		/**
            +		 *  tests if a string is in Tick notation
            +		 *  defined in "Tone/core/Transport"
            +		 *  @return {boolean} 
            +		 *  @method isTicks
            +		 *  @lends Tone.prototype.isNotation
            +		 */
            +		Tone.prototype.isTicks = (function(){
            +			var tickFormat = new RegExp(/[0-9]+[i]$/i);
            +			return function(tick){
            +				return tickFormat.test(tick);
            +			};
            +		})();
            +
            +		/**
            +		 *  tests if a string is transportTime
            +		 *  i.e. :
            +		 *  	1:2:0 = 1 measure + two quarter notes + 0 sixteenth notes
            +		 *  defined in "Tone/core/Transport"
            +		 *  	
            +		 *  @return {boolean} 
            +		 *
            +		 *  @method isTransportTime
            +		 *  @lends Tone.prototype.isTransportTime
            +		 */
            +		Tone.prototype.isTransportTime = (function(){
            +			var transportTimeFormat = new RegExp(/^\d+(\.\d+)?:\d+(\.\d+)?(:\d+(\.\d+)?)?$/i);
            +			return function(transportTime){
            +				return transportTimeFormat.test(transportTime);
            +			};
            +		})();
            +
            +		/**
            +		 *
            +		 *  convert notation format strings to seconds
            +		 *  defined in "Tone/core/Transport"
            +		 *  
            +		 *  @param  {string} notation     
            +		 *  @param {number=} bpm 
            +		 *  @param {number=} timeSignature 
            +		 *  @return {number} 
            +		 *                
            +		 */
            +		Tone.prototype.notationToSeconds = function(notation, bpm, timeSignature){
            +			bpm = this.defaultArg(bpm, Tone.Transport.getBpm());
            +			timeSignature = this.defaultArg(timeSignature, transportTimeSignature);
            +			var beatTime = (60 / bpm);
            +			var subdivision = parseInt(notation, 10);
            +			var beats = 0;
            +			if (subdivision === 0){
            +				beats = 0;
            +			}
            +			var lastLetter = notation.slice(-1);
            +			if (lastLetter === "t"){
            +				beats = (4 / subdivision) * 2/3;
            +			} else if (lastLetter === "n"){
            +				beats = 4 / subdivision;
            +			} else if (lastLetter === "m"){
            +				beats = subdivision * timeSignature;
            +			} else {
            +				beats = 0;
            +			}
            +			return beatTime * beats;
            +		};
            +
            +		/**
            +		 *  convert transportTime into seconds
            +		 *  defined in "Tone/core/Transport"
            +		 *  
            +		 *  ie: 4:2:3 == 4 measures + 2 quarters + 3 sixteenths
            +		 *
            +		 *  @param  {string} transportTime 
            +		 *  @param {number=} bpm 
            +		 *  @param {number=} timeSignature
            +		 *  @return {number}               seconds
            +		 *
            +		 *  @lends Tone.prototype.transportTimeToSeconds
            +		 */
            +		Tone.prototype.transportTimeToSeconds = function(transportTime, bpm, timeSignature){
            +			bpm = this.defaultArg(bpm, Tone.Transport.getBpm());
            +			timeSignature = this.defaultArg(timeSignature, transportTimeSignature);
            +			var measures = 0;
            +			var quarters = 0;
            +			var sixteenths = 0;
            +			var split = transportTime.split(":");
            +			if (split.length === 2){
            +				measures = parseFloat(split[0]);
            +				quarters = parseFloat(split[1]);
            +			} else if (split.length === 1){
            +				quarters = parseFloat(split[0]);
            +			} else if (split.length === 3){
            +				measures = parseFloat(split[0]);
            +				quarters = parseFloat(split[1]);
            +				sixteenths = parseFloat(split[2]);
            +			}
            +			var beats = (measures * timeSignature + quarters + sixteenths / 4);
            +			return beats * this.notationToSeconds("4n");
            +		};
            +
            +		/**
            +		 *  convert ticks into seconds
            +		 *  defined in "Tone/core/Transport"
            +		 *  
            +		 *  @param  {number} ticks 
            +		 *  @param {number=} bpm 
            +		 *  @param {number=} timeSignature
            +		 *  @return {number}               seconds
            +		 */
            +		Tone.prototype.ticksToSeconds = function(ticks, bpm, timeSignature){
            +			ticks = Math.floor(ticks);
            +			var quater = this.notationToSeconds("4n", bpm, timeSignature);
            +			return (quater * ticks) / (tatum);
            +		};
            +
            +		/**
            +		 *  Convert seconds to the closest transportTime in the form 
            +		 *  	measures:quarters:sixteenths
            +		 *  defined in "Tone/core/Transport"
            +		 *
            +		 *  @method toTransportTime
            +		 *  
            +		 *  @param {Tone.Time} seconds 
            +		 *  @param {number=} bpm 
            +		 *  @param {number=} timeSignature
            +		 *  @return {string}  
            +		 *  
            +		 *  @lends Tone.prototype.toTransportTime
            +		 */
            +		Tone.prototype.toTransportTime = function(time, bpm, timeSignature){
            +			var seconds = this.toSeconds(time, bpm, timeSignature);
            +			bpm = this.defaultArg(bpm, Tone.Transport.getBpm());
            +			timeSignature = this.defaultArg(timeSignature, transportTimeSignature);
            +			var quarterTime = this.notationToSeconds("4n");
            +			var quarters = seconds / quarterTime;
            +			var measures = Math.floor(quarters / timeSignature);
            +			var sixteenths = Math.floor((quarters % 1) * 4);
            +			quarters = Math.floor(quarters) % timeSignature;
            +			var progress = [measures, quarters, sixteenths];
            +			return progress.join(":");
            +		};
            +
            +		/**
            +		 *  convert a time to a frequency
            +		 *  defined in "Tone/core/Transport"
            +		 *  	
            +		 *  @param  {Tone.Time} time 
            +		 *  @return {number}      the time in hertz
            +		 */
            +		Tone.prototype.toFrequency = function(time, now){
            +			if (this.isFrequency(time)){
            +				return parseFloat(time);
            +			} else if (this.isNotation(time) || this.isTransportTime(time)) {
            +				return this.secondsToFrequency(this.toSeconds(time, now));
            +			} else {
            +				return time;
            +			}
            +		};
            +
            +		/**
            +		 *  convert Tone.Time into seconds.
            +		 *  defined in "Tone/core/Transport"
            +		 *  
            +		 *  unlike the method which it overrides, this takes into account 
            +		 *  transporttime and musical notation
            +		 *
            +		 *  Time : 1.40
            +		 *  Notation: 4n|1m|2t
            +		 *  TransportTime: 2:4:1 (measure:quarters:sixteens)
            +		 *  Now Relative: +3n
            +		 *  Math: 3n+16n or even very complicated expressions ((3n*2)/6 + 1)
            +		 *
            +		 *  @override
            +		 *  @param  {Tone.Time} time       
            +		 *  @param {number=} 	now 	if passed in, this number will be 
            +		 *                        		used for all 'now' relative timings
            +		 *  @return {number} 
            +		 */
            +		Tone.prototype.toSeconds = function(time, now){
            +			now = this.defaultArg(now, this.now());
            +			if (typeof time === "number"){
            +				return time; //assuming that it's seconds
            +			} else if (typeof time === "string"){
            +				var plusTime = 0;
            +				if(time.charAt(0) === "+") {
            +					plusTime = now;
            +					time = time.slice(1);
            +				} 
            +				var components = time.split(/[\(\)\-\+\/\*]/);
            +				if (components.length > 1){
            +					var originalTime = time;
            +					for(var i = 0; i < components.length; i++){
            +						var symb = components[i].trim();
            +						if (symb !== ""){
            +							var val = this.toSeconds(symb);
            +							time = time.replace(symb, val);
            +						}
            +					}
            +					try {
            +						//i know eval is evil, but i think it's safe here
            +						time = eval(time); // jshint ignore:line
            +					} catch (e){
            +						throw new EvalError("problem evaluating Tone.Time: "+originalTime);
            +					}
            +				} else if (this.isNotation(time)){
            +					time = this.notationToSeconds(time);
            +				} else if (this.isTransportTime(time)){
            +					time = this.transportTimeToSeconds(time);
            +				} else if (this.isFrequency(time)){
            +					time = this.frequencyToSeconds(time);
            +				} else {
            +					time = parseFloat(time);
            +				}
            +				return time + plusTime;
            +			} else {
            +				return now;
            +			}
            +		};
            +
            +		var TransportConstructor = Tone.Transport;
            +
            +		Tone._initAudioContext(function(){
            +			if (typeof Tone.Transport === "function"){
            +				//a single transport object
            +				Tone.Transport = new Tone.Transport();
            +				Tone.Transport.setBpm(120);
            +			} else {
            +				//stop the clock
            +				Tone.Transport.stop();
            +				//get the previous bpm
            +				var bpm = Tone.Transport.getBpm();
            +				//destory the old clock
            +				Tone.Transport._clock.dispose();
            +				//make new Transport insides
            +				TransportConstructor.call(Tone.Transport);
            +				//set the bpm
            +				Tone.Transport.setBpm(bpm);
            +			}
            +		});
            +
            +		return Tone.Transport;
            +	});
            +
            +	toneModule( function(Tone){
            +
            +		
            +		
            +		/**
            +		 *  @class  A single master output. 
            +		 *          adds toMaster to Tone
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 */
            +		Tone.Master = function(){
            +			Tone.call(this);
            +			
            +			//connections
            +			this.input.chain(this.output, this.context.destination);
            +		};
            +
            +		Tone.extend(Tone.Master);
            +
            +		/**
            +		 *  mute the output
            +		 *  @param {boolean} muted
            +		 *  @returns {Tone.Master} `this`
            +		 */
            +		Tone.Master.prototype.mute = function(muted){
            +			muted = this.defaultArg(muted, true);
            +			if (muted){
            +				this.output.gain.value = 0;
            +			} else {
            +				this.output.gain.value = 1;
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  @param {number} db the volume of the output in decibels
            +		 *  @param {Tone.Time=} fadeTime time it takes to reach the value
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.Master.prototype.setVolume = function(db, fadeTime){
            +			var now = this.now();
            +			var gain = this.dbToGain(db);
            +			if (fadeTime){
            +				var currentVolume = this.output.gain.value;
            +				this.output.gain.cancelScheduledValues(now);
            +				this.output.gain.setValueAtTime(currentVolume, now);
            +				this.output.gain.linearRampToValueAtTime(gain, now + this.toSeconds(fadeTime));
            +			} else {
            +				this.output.gain.setValueAtTime(gain, now);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 * get the volume in decibels
            +		 * @return {Tone.Volume}
            +		 */
            +		Tone.Master.prototype.getVolume = function(){
            +			return this.gainToDb(this.output.gain.value);
            +		};
            +
            +		/**
            +		 *  route the master signal to the node's input. 
            +		 *  NOTE: this will disconnect the previously connected node
            +		 *  @param {AudioNode|Tone} node the node to use as the entry
            +		 *                               point to the master chain
            +		 *  @returns {Tone.Master} `this`
            +		 */
            +		Tone.Master.prototype.send = function(node){
            +			//disconnect the previous node
            +			this.input.disconnect();
            +			this.input.connect(node);
            +			return this;
            +		};
            +
            +		/**
            +		 *  the master effects chain return point
            +		 *  @param {AudioNode|Tone} node the node to connect 
            +		 *  @returns {Tone.Master} `this`
            +		 */
            +		Tone.Master.prototype.receive = function(node){
            +			node.connect(this.output);
            +			return this;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	AUGMENT TONE's PROTOTYPE
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *  connect 'this' to the master output
            +		 *  defined in "Tone/core/Master"
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.toMaster = function(){
            +			this.connect(Tone.Master);
            +			return this;
            +		};
            +
            +		/**
            +		 *  Also augment AudioNode's prototype to include toMaster
            +		 *  as a convenience
            +		 *  @returns {AudioNode} `this`
            +		 */
            +		AudioNode.prototype.toMaster = function(){
            +			this.connect(Tone.Master);
            +			return this;
            +		};
            +
            +		var MasterConstructor = Tone.Master;
            +
            +		/**
            +		 *  initialize the module and listen for new audio contexts
            +		 */
            +		Tone._initAudioContext(function(){
            +			//a single master output
            +			if (!Tone.prototype.isUndef(Tone.Master)){
            +				Tone.Master = new MasterConstructor();
            +			} else {
            +				MasterConstructor.prototype.dispose.call(Tone.Master);
            +				MasterConstructor.call(Tone.Master);
            +			}
            +		});
            +
            +		return Tone.Master;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +		
            +		/**
            +		 *  @class  Base class for sources.
            +		 *          Sources have start/stop/pause and 
            +		 *          the ability to be synced to the 
            +		 *          start/stop/pause of Tone.Transport.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 */	
            +		Tone.Source = function(options){
            +			//unlike most ToneNodes, Sources only have an output and no input
            +			Tone.call(this, 0, 1);
            +			options = this.defaultArg(options, Tone.Source.defaults);
            +
            +			/**
            +			 *  @type {Tone.Source.State}
            +			 *  @readOnly
            +			 */
            +			this.state = Tone.Source.State.STOPPED;
            +
            +			/**
            +			 * the onended callback when the source is done playing
            +			 * @type {function}
            +			 */
            +			this.onended = options.onended;
            +
            +			/**
            +			 * the volume of the output in decibels
            +			 * @type {Tone.Signal}
            +			 */
            +			this.volume = new Tone.Signal(this.output.gain, Tone.Signal.Units.Decibels);
            +
            +			/**
            +			 * 	keeps track of the timeout for chaning the state
            +			 * 	and calling the onended
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._timeout = -1;
            +		};
            +
            +		Tone.extend(Tone.Source);
            +
            +		/**
            +		 *  the default parameters
            +		 *
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.Source.defaults = {
            +			"onended" : function(){},
            +			"volume" : 0,
            +		};
            +
            +		/**
            +		 *  star thte source
            +		 *  @param  {Tone.Time} time 
            +		 *  @returns {Tone.Source} `this`
            +		 */
            +		Tone.Source.prototype.start = function(time){
            +			if (this.state !== Tone.Source.State.STARTED || this.retrigger){
            +				var now = this.now();
            +				time = this.toSeconds(time, now);
            +				var diff = now - time;
            +				if (diff !== 0){
            +					this._timeout = setTimeout(function(){
            +						this.state = Tone.Source.State.STARTED;
            +					}.bind(this), diff * 1000);
            +				} else {
            +					this.state = Tone.Source.State.STARTED;
            +				}
            +				this._start.apply(this, arguments);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 * 	stop the source
            +		 *  @param  {Tone.Time} time 
            +		 *  @returns {Tone.Source} `this`
            +		 */
            +		Tone.Source.prototype.stop = function(time){
            +			if (this.state !== Tone.Source.State.STOPPED){
            +				clearTimeout(this._timeout);
            +				var now = this.now();
            +				time = this.toSeconds(time, now);
            +				var diff = now - time;
            +				if (diff !== 0){
            +					this._timeout = setTimeout(function(){
            +						this.state = Tone.Source.State.STOPPED;
            +						this.onended();
            +					}.bind(this), diff * 1000);
            +				} else {
            +					this.state = Tone.Source.State.STOPPED;
            +					this.onended();
            +				}
            +				this._stop.apply(this, arguments);
            +			}
            +			return this;
            +		};
            +
            +
            +		/**
            +	 	 *  @abstract
            +		 *  @param  {Tone.Time} time 
            +		 */
            +		Tone.Source.prototype.pause = function(time){
            +			//if there is no pause, just stop it
            +			this.stop(time);
            +		};
            +
            +		/**
            +		 *  sync the source to the Transport
            +		 *
            +		 *  @param {Tone.Time} [delay=0] delay time before starting the source
            +		 */
            +		Tone.Source.prototype.sync = function(delay){
            +			Tone.Transport.syncSource(this, delay);
            +		};
            +
            +		/**
            +		 *  unsync the source to the Transport
            +		 */
            +		Tone.Source.prototype.unsync = function(){
            +			Tone.Transport.unsyncSource(this);
            +		};
            +
            +		/**
            +		 *	clean up
            +		 *  @return {Tone.Source} `this`
            +		 */
            +		Tone.Source.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.stop();
            +			this.state = null;
            +			clearTimeout(this._timeout);
            +			this.onended = function(){};
            +			this.volume.dispose();
            +			this.volume = null;
            +		};
            +
            +		/**
            +		 *  internal onended callback
            +		 *  @private
            +		 */
            +		Tone.Source.prototype._onended = function(){
            +			this.state = Tone.Source.State.STOPPED;
            +			this.onended();
            +		};
            +
            +		/**
            +		 *  @enum {string}
            +		 */
            +		Tone.Source.State = {
            +			STARTED : "started",
            +			PAUSED : "paused",
            +			STOPPED : "stopped",
            +			WAITING : "waiting"
            +	 	};
            +
            +		return Tone.Source;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Oscilator with start, pause, stop and sync to Transport methods
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Source}
            +		 *  @param {number|string} [frequency=440] starting frequency
            +		 *  @param {string} [type="sine"] type of oscillator (sine|square|triangle|sawtooth)
            +		 */
            +		Tone.Oscillator = function(){
            +			
            +			var options = this.optionsObject(arguments, ["frequency", "type"], Tone.Oscillator.defaults);
            +			Tone.Source.call(this, options);
            +
            +			/**
            +			 *  the main oscillator
            +			 *  @type {OscillatorNode}
            +			 *  @private
            +			 */
            +			this._oscillator = null;
            +			
            +			/**
            +			 *  the frequency control signal
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = new Tone.Signal(options.frequency, Tone.Signal.Units.Frequency);
            +
            +			/**
            +			 *  the detune control signal
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.detune = new Tone.Signal(options.detune);
            +
            +			/**
            +			 *  the periodic wave
            +			 *  @type {PeriodicWave}
            +			 *  @private
            +			 */
            +			this._wave = null;
            +
            +			/**
            +			 *  the phase of the oscillator
            +			 *  between 0 - 360
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._phase = options.phase;
            +
            +			/**
            +			 *  the type of the oscillator
            +			 *  @type {string}
            +			 *  @private
            +			 */
            +			this._type = options.type;
            +			
            +			//setup
            +			this.phase = this._phase;
            +		};
            +
            +		Tone.extend(Tone.Oscillator, Tone.Source);
            +
            +		/**
            +		 *  the default parameters
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.Oscillator.defaults = {
            +			"type" : "sine",
            +			"frequency" : 440,
            +			"detune" : 0,
            +			"phase" : 0
            +		};
            +
            +		/**
            +		 *  start the oscillator
            +		 *  @param  {Tone.Time} [time=now] 
            +		 *  @private
            +		 */
            +		Tone.Oscillator.prototype._start = function(time){
            +			//new oscillator with previous values
            +			this._oscillator = this.context.createOscillator();
            +			this._oscillator.setPeriodicWave(this._wave);
            +			//connect the control signal to the oscillator frequency & detune
            +			this._oscillator.connect(this.output);
            +			this.frequency.connect(this._oscillator.frequency);
            +			this.detune.connect(this._oscillator.detune);
            +			//start the oscillator
            +			this._oscillator.onended = this._onended.bind(this);
            +			this._oscillator.start(this.toSeconds(time));
            +		};
            +
            +		/**
            +		 *  stop the oscillator
            +		 *  @param  {Tone.Time} [time=now] (optional) timing parameter
            +		 *  @returns {Tone.Oscillator} `this`
            +		 */
            +		Tone.Oscillator.prototype._stop = function(time){
            +			this._oscillator.stop(this.toSeconds(time));
            +			return this;
            +		};
            +
            +		/**
            +		 *  sync the signal to the Transport's bpm
            +		 *  @returns {Tone.Oscillator} `this`
            +		 */
            +		Tone.Oscillator.prototype.syncFrequency = function(){
            +			Tone.Transport.syncSignal(this.frequency);
            +			return this;
            +		};
            +
            +		/**
            +		 *  unsync the oscillator's frequency from teh transprot
            +		 *  @returns {Tone.Oscillator} `this`
            +		 */
            +		Tone.Oscillator.prototype.unsyncFrequency = function(){
            +			this.frequency.unsync();
            +			return this;
            +		};
            +
            +		/**
            +		 * The type of the oscillator. sine, square, triangle, sawtooth
            +		 *
            +		 * uses PeriodicWave even for native types so that it can set the phase
            +		 *
            +		 * the the PeriodicWave equations are from the Web Audio Source code
            +		 * here: https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/modules/webaudio/PeriodicWave.cpp&sq=package:chromium
            +		 *  
            +		 * @memberOf Tone.Oscillator#
            +		 * @type {string}
            +		 * @name type
            +		 */
            +		Object.defineProperty(Tone.Oscillator.prototype, "type", {
            +			get : function(){
            +				return this._type;
            +			},
            +			set : function(type){
            +				var fftSize = 4096;
            +				var halfSize = fftSize / 2;
            +
            +				var real = new Float32Array(halfSize);
            +				var imag = new Float32Array(halfSize);
            +				
            +				// Clear DC and Nyquist.
            +				real[0] = 0;
            +				imag[0] = 0;
            +
            +				var shift = this._phase;	
            +				for (var n = 1; n < halfSize; ++n) {
            +					var piFactor = 2 / (n * Math.PI);
            +					var b; 
            +					switch (type) {
            +						case "sine": 
            +							b = (n === 1) ? 1 : 0;
            +							break;
            +						case "square":
            +							b = (n & 1) ? 2 * piFactor : 0;
            +							break;
            +						case "sawtooth":
            +							b = piFactor * ((n & 1) ? 1 : -1);
            +							break;
            +						case "triangle":
            +							if (n & 1) {
            +								b = 2 * (piFactor * piFactor) * ((((n - 1) >> 1) & 1) ? -1 : 1);
            +							} else {
            +								b = 0;
            +							}
            +							break;
            +						default:
            +							throw new TypeError("invalid oscillator type: "+type);
            +					}
            +					if (b !== 0){
            +						real[n] = -b * Math.sin(shift);
            +						imag[n] = b * Math.cos(shift);
            +					} else {
            +						real[n] = 0;
            +						imag[n] = 0;
            +					}
            +				}
            +				var periodicWave = this.context.createPeriodicWave(real, imag);
            +				this._wave = periodicWave;
            +				if (this._oscillator !== null){
            +					this._oscillator.setPeriodicWave(this._wave);
            +				}
            +				this._type = type;
            +			}
            +		});
            +
            +		/**
            +		 * the phase of the oscillator in degrees
            +		 * @memberOf Tone.Oscillator#
            +		 * @type {number}
            +		 * @name phase
            +		 */
            +		Object.defineProperty(Tone.Oscillator.prototype, "phase", {
            +			get : function(){
            +				return this._phase * (180 / Math.PI);
            +			}, 
            +			set : function(phase){
            +				this._phase = phase * Math.PI / 180;
            +				//reset the type
            +				this.type = this._type;
            +			}
            +		});
            +
            +		/**
            +		 *  dispose and disconnect
            +		 *  @return {Tone.Oscillator} `this`
            +		 */
            +		Tone.Oscillator.prototype.dispose = function(){
            +			Tone.Source.prototype.dispose.call(this);
            +			if (this._oscillator !== null){
            +				this._oscillator.disconnect();
            +				this._oscillator = null;
            +			}
            +			this.frequency.dispose();
            +			this.frequency = null;
            +			this.detune.dispose();
            +			this.detune = null;
            +			this._wave = null;
            +			return this;
            +		};
            +
            +		return Tone.Oscillator;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class AudioToGain converts an input range of -1,1 to 0,1
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 */
            +		Tone.AudioToGain = function(){
            +
            +			/**
            +			 *  @type {WaveShaperNode}
            +			 *  @private
            +			 */
            +			this._norm = this.input = this.output = new Tone.WaveShaper([0,1]);
            +		};
            +
            +		Tone.extend(Tone.AudioToGain, Tone.SignalBase);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.AND} `this`
            +		 */
            +		Tone.AudioToGain.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._norm.disconnect();
            +			this._norm = null;
            +			return this;
            +		};
            +
            +		return Tone.AudioToGain;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  The Low Frequency Oscillator produces an output signal 
            +		 *          which can be attached to an AudioParam or Tone.Signal 
            +		 *          for constant control over that parameter. the LFO can 
            +		 *          also be synced to the transport to start/stop/pause
            +		 *          and change when the tempo changes.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Oscillator}
            +		 *  @param {Tone.Time} [frequency="4n"]
            +		 *  @param {number} [outputMin=0]
            +		 *  @param {number} [outputMax=1]
            +		 */
            +		Tone.LFO = function(){
            +
            +			var options = this.optionsObject(arguments, ["frequency", "min", "max"], Tone.LFO.defaults);
            +
            +			/** 
            +			 *  the oscillator
            +			 *  @type {Tone.Oscillator}
            +			 */
            +			this.oscillator = new Tone.Oscillator({
            +				"frequency" : options.frequency, 
            +				"type" : options.type, 
            +				"phase" : options.phase
            +			});
            +
            +			/**
            +			 *  the lfo's frequency
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = this.oscillator.frequency;
            +
            +			/**
            +			 * The amplitude of the LFO, which controls the output range between
            +			 * the min and max output. For example if the min is -10 and the max 
            +			 * is 10, setting the amplitude to 0.5 would make the LFO modulate
            +			 * between -5 and 5. 
            +			 * @type {Tone.Signal}
            +			 */
            +			this.amplitude = this.oscillator.volume;
            +			this.amplitude.units = Tone.Signal.Units.Normal;
            +			this.amplitude.value = options.amplitude;
            +
            +			/**
            +			 *  @type {Tone.AudioToGain} 
            +			 *  @private
            +			 */
            +			this._a2g = new Tone.AudioToGain();
            +
            +			/**
            +			 *  @type {Tone.Scale} 
            +			 *  @private
            +			 */
            +			this._scaler = this.output = new Tone.Scale(options.min, options.max);
            +
            +			//connect it up
            +			this.oscillator.chain(this._a2g, this._scaler);
            +		};
            +
            +		Tone.extend(Tone.LFO, Tone.Oscillator);
            +
            +		/**
            +		 *  the default parameters
            +		 *
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.LFO.defaults = {
            +			"type" : "sine",
            +			"min" : 0,
            +			"max" : 1,
            +			"phase" : 0,
            +			"frequency" : "4n",
            +			"amplitude" : 1
            +		};
            +
            +		/**
            +		 *  start the LFO
            +		 *  @param  {Tone.Time} [time=now] the time the LFO will start
            +		 *  @returns {Tone.LFO} `this`
            +		 */
            +		Tone.LFO.prototype.start = function(time){
            +			this.oscillator.start(time);
            +			return this;
            +		};
            +
            +		/**
            +		 *  stop the LFO
            +		 *  @param  {Tone.Time} [time=now] the time the LFO will stop
            +		 *  @returns {Tone.LFO} `this`
            +		 */
            +		Tone.LFO.prototype.stop = function(time){
            +			this.oscillator.stop(time);
            +			return this;
            +		};
            +
            +		/**
            +		 *  Sync the start/stop/pause to the transport 
            +		 *  and the frequency to the bpm of the transport
            +		 *
            +		 *  @param {Tone.Time} [delay=0] the time to delay the start of the
            +		 *                                LFO from the start of the transport
            +		 *  @returns {Tone.LFO} `this`
            +		 */
            +		Tone.LFO.prototype.sync = function(delay){
            +			this.oscillator.sync(delay);
            +			this.oscillator.syncFrequency();
            +			return this;
            +		};
            +
            +		/**
            +		 *  unsync the LFO from transport control
            +		 *  @returns {Tone.LFO} `this`
            +		 */
            +		Tone.LFO.prototype.unsync = function(){
            +			this.oscillator.unsync();
            +			this.oscillator.unsyncFrequency();
            +			return this;
            +		};
            +
            +		/**
            +		 * the miniumum output of the scale
            +		 * @memberOf Tone.LFO#
            +		 * @type {number}
            +		 * @name min
            +		 */
            +		Object.defineProperty(Tone.LFO.prototype, "min", {
            +			get : function(){
            +				return this._scaler.min;
            +			},
            +			set : function(min){
            +				this._scaler.min = min;
            +			}
            +		});
            +
            +		/**
            +		 * the maximum output of the scale
            +		 * @memberOf Tone.LFO#
            +		 * @type {number}
            +		 * @name max
            +		 */
            +		Object.defineProperty(Tone.LFO.prototype, "max", {
            +			get : function(){
            +				return this._scaler.max;
            +			},
            +			set : function(max){
            +				this._scaler.max = max;
            +			}
            +		});
            +
            +		/**
            +		 * the type of the oscillator
            +		 * @memberOf Tone.LFO#
            +		 * @type {string}
            +		 * @name type
            +		 */
            +		 Object.defineProperty(Tone.LFO.prototype, "type", {
            +			get : function(){
            +				return this.oscillator.type;
            +			},
            +			set : function(type){
            +				this.oscillator.type = type;
            +			}
            +		});
            +
            +		 /**
            +		 * the phase of the LFO
            +		 * @memberOf Tone.LFO#
            +		 * @type {string}
            +		 * @name phase
            +		 */
            +		 Object.defineProperty(Tone.LFO.prototype, "phase", {
            +			get : function(){
            +				return this.oscillator.phase;
            +			},
            +			set : function(phase){
            +				this.oscillator.phase = phase;
            +			}
            +		});
            +
            +		/**
            +		 *	Override the connect method so that it 0's out the value 
            +		 *	if attached to an AudioParam or Tone.Signal. 
            +		 *	
            +		 *	Borrowed from {@link Tone.Signal}
            +		 *	
            +		 *  @function
            +		 */
            +		Tone.LFO.prototype.connect = Tone.Signal.prototype.connect;
            +
            +		/**
            +		 *  disconnect and dispose
            +		 *  @returns {Tone.LFO} `this`
            +		 */
            +		Tone.LFO.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.oscillator.dispose();
            +			this.oscillator = null;
            +			this._scaler.dispose();
            +			this._scaler = null;
            +			this._a2g.dispose();
            +			this._a2g = null;
            +			this.frequency = null;
            +			this.amplitude = null;
            +			return this;
            +		};
            +
            +		return Tone.LFO;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A limiter on the incoming signal. Composed of a Tone.Compressor
            +		 *         with a fast attack and decay value. 
            +		 *
            +		 *  @extends {Tone}
            +		 *  @constructor
            +		 *  @param {number} threshold the threshold in decibels
            +		 */
            +		Tone.Limiter = function(threshold){
            +
            +			/**
            +			 *  the compressor
            +			 *  @private
            +			 *  @type {Tone.Compressor}
            +			 */
            +			this._compressor = this.input = this.output = new Tone.Compressor({
            +				"attack" : 0.001,
            +				"decay" : 0.001,
            +				"threshold" : threshold
            +			});
            +
            +			/**
            +			 * The threshold of of the limiter
            +			 * @type {AudioParam}
            +			 */
            +			this.threshold = this._compressor.threshold;
            +		};
            +
            +		Tone.extend(Tone.Limiter);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Limiter} `this`
            +		 */
            +		Tone.Limiter.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._compressor.dispose();
            +			this._compressor = null;
            +			this.threshold = null;
            +			return this;
            +		};
            +
            +		return Tone.Limiter;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A lowpass feedback comb filter. 
            +		 *         DelayNode -> Lowpass Filter -> feedback
            +		 *
            +		 *  @extends {Tone}
            +		 *  @constructor
            +		 *  @param {number} [minDelay=0.1] the minimum delay time which the filter can have
            +		 *  @param {number} [maxDelay=1] the maximum delay time which the filter can have
            +		 */
            +		Tone.LowpassCombFilter = function(){
            +
            +			Tone.call(this);
            +
            +			var options = this.optionsObject(arguments, ["minDelay", "maxDelay"], Tone.LowpassCombFilter.defaults);
            +
            +			//the delay * samplerate = number of samples. 
            +			// buffersize / number of samples = number of delays needed per buffer frame
            +			var delayCount = Math.ceil(this.bufferSize / (options.minDelay * this.context.sampleRate));
            +			//set some ranges
            +			delayCount = Math.min(delayCount, 10);
            +			delayCount = Math.max(delayCount, 1);
            +
            +			/**
            +			 *  the number of filter delays
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._filterDelayCount = delayCount;
            +
            +			/**
            +			 *  @type {Array.<FilterDelay>}
            +			 *  @private
            +			 */
            +			this._filterDelays = new Array(this._filterDelayCount);
            +
            +			/**
            +			 *  the dampening control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.dampening = new Tone.Signal(options.dampening, Tone.Signal.Units.Frequency);
            +
            +			/**
            +			 *  the resonance control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.resonance = new Tone.Signal(options.resonance, Tone.Signal.Units.Normal);
            +
            +			/**
            +			 *  scale the resonance value to the normal range
            +			 *  @type {Tone.Scale}
            +			 *  @private
            +			 */
            +			this._resScale = new Tone.ScaleExp(0.01, 1 / this._filterDelayCount - 0.001, 0.5);
            +
            +			/**
            +			 *  internal flag for keeping track of when frequency
            +			 *  correction has been used
            +			 *  @type {boolean}
            +			 *  @private
            +			 */
            +			this._highFrequencies = false;
            +
            +			/**
            +			 *  internal counter of delayTime
            +			 *  @type {Tone.Time}
            +			 *  @private
            +			 */
            +			this._delayTime = options.delayTime;
            +
            +			/**
            +			 *  the feedback node
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._feedback = this.context.createGain();
            +
            +			//make the filters
            +			for (var i = 0; i < this._filterDelayCount; i++) {
            +				var filterDelay = new FilterDelay(options.minDelay, this.dampening);
            +				filterDelay.connect(this._feedback);
            +				this._filterDelays[i] = filterDelay;
            +			}
            +
            +			//connections
            +			this.input.connect(this._filterDelays[0]);
            +			this._feedback.connect(this._filterDelays[0]);
            +			this.connectSeries.apply(this, this._filterDelays);
            +			//resonance control
            +			this.resonance.chain(this._resScale, this._feedback.gain);
            +			this._feedback.connect(this.output);
            +			//set the delay to the min value initially
            +			this.delayTime = options.delayTime;
            +		};
            +
            +		Tone.extend(Tone.LowpassCombFilter);
            +
            +		/**
            +		 *  the default parameters
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.LowpassCombFilter.defaults = {
            +			"resonance" : 0.5,
            +			"dampening" : 3000,
            +			"minDelay" : 0.1,
            +			"maxDelay" : 1,
            +			"delayTime" : 0.1
            +		};
            +
            +		/**
            +		 * The delay time of the LowpassCombFilter. Auto corrects
            +		 * for sample offsets for small delay amounts.
            +		 * @memberOf Tone.LowpassCombFilter#
            +		 * @type {Tone.Time}
            +		 * @name delayTime
            +		 */
            +		Object.defineProperty(Tone.LowpassCombFilter.prototype, "delayTime", {
            +			get : function(){
            +				return this._delayTime;
            +			},
            +			set : function(delayAmount){
            +				this.setDelayTimeAtTime(delayAmount);
            +			}
            +		});
            +
            +		/**
            +		 * set the delay time for the comb filter at a specific time. 
            +		 * @param {Tone.Time} delayAmount the amount of delay time
            +		 * @param {Tone.Time} [time=now] when the delay time should be set
            +		 */
            +		Tone.LowpassCombFilter.prototype.setDelayTimeAtTime = function(delayAmount, time){
            +			this._delayTime = this.toSeconds(delayAmount);
            +			//the number of samples to delay by
            +			var sampleRate = this.context.sampleRate;
            +			var delaySamples = sampleRate * this._delayTime;
            +			// delayTime corection when frequencies get high
            +			time = this.toSeconds(time);
            +			var cutoff = 100;
            +			if (delaySamples < cutoff){
            +				this._highFrequencies = true;
            +				var changeNumber = Math.round((delaySamples / cutoff) * this._filterDelayCount);
            +				for (var i = 0; i < changeNumber; i++) {
            +					this._filterDelays[i].setDelay(1 / sampleRate + this._delayTime, time);
            +				}
            +				this._delayTime = Math.floor(delaySamples) / sampleRate;
            +			} else if (this._highFrequencies){
            +				this._highFrequencies = false;
            +				for (var j = 0; j < this._filterDelays.length; j++) {
            +					this._filterDelays[j].setDelay(this._delayTime, time);
            +				}
            +			}
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.LowpassCombFilter} `this`
            +		 */
            +		Tone.LowpassCombFilter.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			//dispose the filter delays
            +			for (var i = 0; i < this._filterDelays.length; i++) {
            +				this._filterDelays[i].dispose();
            +				this._filterDelays[i] = null;
            +			}
            +			this._filterDelays = null;
            +			this.dampening.dispose();
            +			this.dampening = null;
            +			this.resonance.dispose();
            +			this.resonance = null;
            +			this._resScale.dispose();
            +			this._resScale = null;
            +			this._feedback.disconnect();
            +			this._feedback = null;
            +			return this;
            +		};
            +
            +		// BEGIN HELPER CLASS //
            +
            +		/**
            +		 *  FilterDelay
            +		 *  @internal
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 */
            +		var FilterDelay = function(maxDelay, filterFreq){
            +			this.delay = this.input = this.context.createDelay(maxDelay);
            +			this.delay.delayTime.value = maxDelay;
            +
            +			this.filter = this.output = this.context.createBiquadFilter();
            +			filterFreq.connect(this.filter.frequency);
            +
            +			this.filter.type = "lowpass";
            +			this.filter.Q.value = 0;
            +
            +			this.delay.connect(this.filter);
            +		};
            +
            +		Tone.extend(FilterDelay);
            +
            +		FilterDelay.prototype.setDelay = function(amount, time) {
            +			this.delay.delayTime.setValueAtTime(amount, time);
            +		};
            +
            +		/**
            +		 *  clean up
            +		 */
            +		FilterDelay.prototype.dispose = function(){
            +			this.delay.disconnect();
            +			this.delay = null;
            +			this.filter.disconnect();
            +			this.filter = null;
            +		};
            +
            +		// END HELPER CLASS //
            +
            +		return Tone.LowpassCombFilter;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  merge a left and a right channel into a single stereo channel
            +		 *          instead of connecting to the input, connect to either the left, or right input.
            +		 *          default input for connect is left input.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 */
            +		Tone.Merge = function(){
            +
            +			Tone.call(this, 2, 1);
            +
            +			/**
            +			 *  the left input channel
            +			 *  alias for input 0
            +			 *  @type {GainNode}
            +			 */
            +			this.left = this.input[0] = this.context.createGain();
            +
            +			/**
            +			 *  the right input channel
            +			 *  alias for input 1
            +			 *  @type {GainNode}
            +			 */
            +			this.right = this.input[1] = this.context.createGain();
            +
            +			/**
            +			 *  the merger node for the two channels
            +			 *  @type {ChannelMergerNode}
            +			 *  @private
            +			 */
            +			this._merger = this.context.createChannelMerger(2);
            +
            +			//connections
            +			this.left.connect(this._merger, 0, 0);
            +			this.right.connect(this._merger, 0, 1);
            +			this._merger.connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.Merge);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Merge} `this`
            +		 */
            +		Tone.Merge.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.left.disconnect();
            +			this.right.disconnect();
            +			this._merger.disconnect();
            +			this.left = null;
            +			this.right = null;
            +			this._merger = null;
            +			return this;
            +		}; 
            +
            +		return Tone.Merge;
            +	});
            +
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Get the rms of the input signal with some averaging.
            +		 *          can also just get the value of the signal
            +		 *          or the value in dB. inspired by https://github.com/cwilso/volume-meter/blob/master/volume-meter.js
            +		 *          Note that for signal processing, it's better to use {@link Tone.Follower} which will produce
            +		 *          an audio-rate envelope follower instead of needing to poll the Meter to get the output.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @param {number} [channels=1] number of channels being metered
            +		 *  @param {number} [smoothing=0.8] amount of smoothing applied to the volume
            +		 *  @param {number} [clipMemory=500] number in ms that a "clip" should be remembered
            +		 */
            +		Tone.Meter = function(channels, smoothing, clipMemory){
            +			//extends Unit
            +			Tone.call(this);
            +
            +			/** @type {number} */
            +			this.channels = this.defaultArg(channels, 1);
            +
            +			/** @type {number} */
            +			this.smoothing = this.defaultArg(smoothing, 0.8);
            +
            +			/** @type {number} */
            +			this.clipMemory = this.defaultArg(clipMemory, 500);
            +
            +			/** 
            +			 *  the rms for each of the channels
            +			 *  @private
            +			 *  @type {Array<number>}
            +			 */
            +			this._volume = new Array(this.channels);
            +
            +			/** 
            +			 *  the raw values for each of the channels
            +			 *  @private
            +			 *  @type {Array<number>}
            +			 */
            +			this._values = new Array(this.channels);
            +
            +			//zero out the volume array
            +			for (var i = 0; i < this.channels; i++){
            +				this._volume[i] = 0;
            +				this._values[i] = 0;
            +			}
            +
            +			/** 
            +			 *  last time the values clipped
            +			 *  @private
            +			 *  @type {number}
            +			 */
            +			this._lastClip = 0;
            +			
            +			/** 
            +			 *  @private
            +			 *  @type {ScriptProcessorNode}
            +			 */
            +			this._jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, 1);
            +			this._jsNode.onaudioprocess = this._onprocess.bind(this);
            +			//so it doesn't get garbage collected
            +			this._jsNode.noGC();
            +
            +			//signal just passes
            +			this.input.connect(this.output);
            +			this.input.connect(this._jsNode);
            +		};
            +
            +		Tone.extend(Tone.Meter);
            +
            +		/**
            +		 *  called on each processing frame
            +		 *  @private
            +		 *  @param  {AudioProcessingEvent} event 
            +		 */
            +		Tone.Meter.prototype._onprocess = function(event){
            +			var bufferSize = this._jsNode.bufferSize;
            +			var smoothing = this.smoothing;
            +			for (var channel = 0; channel < this.channels; channel++){
            +				var input = event.inputBuffer.getChannelData(channel);
            +				var sum = 0;
            +				var total = 0;
            +				var x;
            +				var clipped = false;
            +				for (var i = 0; i < bufferSize; i++){
            +					x = input[i];
            +					if (!clipped && x > 0.95){
            +						clipped = true;
            +						this._lastClip = Date.now();
            +					}
            +					total += x;
            +			    	sum += x * x;
            +				}
            +				var average = total / bufferSize;
            +				var rms = Math.sqrt(sum / bufferSize);
            +				this._volume[channel] = Math.max(rms, this._volume[channel] * smoothing);
            +				this._values[channel] = average;
            +			}
            +		};
            +
            +		/**
            +		 *  get the rms of the signal
            +		 *  	
            +		 *  @param  {number} [channel=0] which channel
            +		 *  @return {number}         the value
            +		 */
            +		Tone.Meter.prototype.getLevel = function(channel){
            +			channel = this.defaultArg(channel, 0);
            +			var vol = this._volume[channel];
            +			if (vol < 0.00001){
            +				return 0;
            +			} else {
            +				return vol;
            +			}
            +		};
            +
            +		/**
            +		 *  get the value of the signal
            +		 *  @param  {number=} channel 
            +		 *  @return {number}         
            +		 */
            +		Tone.Meter.prototype.getValue = function(channel){
            +			channel = this.defaultArg(channel, 0);
            +			return this._values[channel];
            +		};
            +
            +		/**
            +		 *  get the volume of the signal in dB
            +		 *  @param  {number=} channel 
            +		 *  @return {number}         
            +		 */
            +		Tone.Meter.prototype.getDb = function(channel){
            +			return this.gainToDb(this.getLevel(channel));
            +		};
            +
            +		/**
            +		 * @returns {boolean} if the audio has clipped in the last 500ms
            +		 */
            +		Tone.Meter.prototype.isClipped = function(){
            +			return Date.now() - this._lastClip < this.clipMemory;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Meter} `this`
            +		 */
            +		Tone.Meter.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._jsNode.disconnect();
            +			this._jsNode.onaudioprocess = null;
            +			this._volume = null;
            +			this._values = null;
            +			return this;
            +		};
            +
            +		return Tone.Meter;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Transform the incoming mono or stereo signal into mono
            +		 *
            +		 *  @extends {Tone}
            +		 *  @constructor
            +		 */
            +		Tone.Mono = function(){
            +			Tone.call(this);
            +
            +			/**
            +			 *  merge the signal
            +			 *  @type {Tone.Merge}
            +			 *  @private
            +			 */
            +			this._merge = new Tone.Merge();
            +
            +			this.input.connect(this._merge, 0, 0);
            +			this.input.connect(this._merge, 0, 1);
            +			this.input.gain.value = this.dbToGain(-10);
            +			this._merge.connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.Mono);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Mono} `this`
            +		 */
            +		Tone.Mono.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._merge.dispose();
            +			this._merge = null;
            +			return this;
            +		};
            +
            +		return Tone.Mono;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A compressor with seperate controls over low/mid/high dynamics
            +		 *
            +		 *  @extends {Tone}
            +		 *  @constructor
            +		 *  @param {Object} options the low/mid/high compressor settings in a single object
            +		 */
            +		Tone.MultibandCompressor = function(options){
            +
            +			options = this.defaultArg(arguments, Tone.MultibandCompressor.defaults);
            +
            +			/**
            +			 *  split the incoming signal into high/mid/low
            +			 *  @type {Tone.MultibandSplit}
            +			 *  @private
            +			 */
            +			this._splitter = new Tone.MultibandSplit({
            +				"lowFrequency" : options.lowFrequency,
            +				"highFrequency" : options.highFrequency
            +			});
            +
            +			/**
            +			 *  low/mid crossover frequency
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.lowFrequency = this._splitter.lowFrequency;
            +
            +			/**
            +			 *  mid/high crossover frequency
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.highFrequency = this._splitter.highFrequency;
            +
            +			/**
            +			 *  the input
            +			 */
            +			this.input = this._splitter;
            +
            +			/**
            +			 *  the output
            +			 *  @type {GainNode}
            +			 */
            +			this.output = this.context.createGain();
            +
            +			/**
            +			 *  the low compressor
            +			 *  @type {Tone.Compressor}
            +			 */
            +			this.low = new Tone.Compressor(options.low);
            +
            +			/**
            +			 *  the mid compressor
            +			 *  @type {Tone.Compressor}
            +			 */
            +			this.mid = new Tone.Compressor(options.mid);
            +
            +			/**
            +			 *  the high compressor
            +			 *  @type {Tone.Compressor}
            +			 */
            +			this.high = new Tone.Compressor(options.high);
            +
            +			//connect the compressor
            +			this._splitter.low.chain(this.low, this.output);
            +			this._splitter.mid.chain(this.mid, this.output);
            +			this._splitter.high.chain(this.high, this.output);
            +		};
            +
            +		Tone.extend(Tone.MultibandCompressor);
            +
            +		/**
            +		 *  @const
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.MultibandCompressor.defaults = {
            +			"low" : Tone.Compressor.defaults,
            +			"mid" : Tone.Compressor.defaults,
            +			"high" : Tone.Compressor.defaults,
            +			"lowFrequency" : 250,
            +			"highFrequency" : 2000
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.MultibandCompressor} `this`
            +		 */
            +		Tone.MultibandCompressor.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._splitter.dispose();
            +			this.low.dispose();
            +			this.mid.dispose();
            +			this.high.dispose();
            +			this._splitter = null;
            +			this.low = null;
            +			this.mid = null;
            +			this.high = null;
            +			this.lowFrequency = null;
            +			this.highFrequency = null;
            +			return this;
            +		};
            +
            +		return Tone.MultibandCompressor;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *	@class  Split the incoming signal into left and right channels
            +		 *	
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 */
            +		Tone.Split = function(){
            +
            +			Tone.call(this, 1, 2);
            +
            +			/** 
            +			 *  @type {ChannelSplitterNode}
            +			 *  @private
            +			 */
            +			this._splitter = this.context.createChannelSplitter(2);
            +
            +			/** 
            +			 *  left channel output
            +			 *  alais for the first output
            +			 *  @type {GainNode}
            +			 */
            +			this.left = this.output[0] = this.context.createGain();
            +
            +			/**
            +			 *  the right channel output
            +			 *  alais for the second output
            +			 *  @type {GainNode}
            +			 */
            +			this.right = this.output[1] = this.context.createGain();
            +			
            +			//connections
            +			this.input.connect(this._splitter);
            +			this._splitter.connect(this.left, 0, 0);
            +			this._splitter.connect(this.right, 1, 0);
            +		};
            +
            +		Tone.extend(Tone.Split);
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.Split} `this`
            +		 */
            +		Tone.Split.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._splitter.disconnect();
            +			this.left.disconnect();
            +			this.right.disconnect();
            +			this.left = null;
            +			this.right = null;
            +			this._splitter = null;
            +			return this;
            +		}; 
            +
            +		return Tone.Split;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  Panner. 
            +		 *  
            +		 *  @class  Equal Power Gain L/R Panner. Not 3D. 
            +		 *          0 = 100% Left
            +		 *          1 = 100% Right
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @param {number} [initialPan=0.5] the initail panner value (defaults to 0.5 = center)
            +		 */
            +		Tone.Panner = function(initialPan){
            +
            +			Tone.call(this, 1, 0);
            +			
            +			/**
            +			 *  the dry/wet knob
            +			 *  @type {Tone.CrossFade}
            +			 *  @private
            +			 */
            +			this._crossFade = new Tone.CrossFade();
            +			
            +			/**
            +			 *  @type {Tone.Merge}
            +			 *  @private
            +			 */
            +			this._merger = this.output = new Tone.Merge();
            +			
            +			/**
            +			 *  @type {Tone.Split}
            +			 *  @private
            +			 */
            +			this._splitter = new Tone.Split();
            +			
            +			/**
            +			 *  the pan control
            +			 *  @type {Tone.Signal}
            +			 */	
            +			this.pan = this._crossFade.fade;
            +
            +			//CONNECTIONS:
            +			this.input.connect(this._splitter.left);
            +			this.input.connect(this._splitter.right);
            +			//left channel is dry, right channel is wet
            +			this._splitter.connect(this._crossFade, 0, 0);
            +			this._splitter.connect(this._crossFade, 1, 1);
            +			//merge it back together
            +			this._crossFade.a.connect(this._merger.left);
            +			this._crossFade.b.connect(this._merger.right);
            +
            +			//initial value
            +			this.pan.value = this.defaultArg(initialPan, 0.5);
            +		};
            +
            +		Tone.extend(Tone.Panner);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Panner} `this`
            +		 */
            +		Tone.Panner.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._crossFade.dispose();
            +			this._crossFade = null;
            +			this._splitter.dispose();
            +			this._splitter = null;
            +			this._merger.dispose();
            +			this._merger = null;
            +			this.pan = null;
            +			return this;
            +		};
            +
            +		return Tone.Panner;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A Panner and volume in one
            +		 *
            +		 *  @extends {Tone}
            +		 *  @constructor
            +		 */
            +		Tone.PanVol = function(pan, volume){
            +			/**
            +			 *  the panning node
            +			 *  @type {Tone.Panner}
            +			 *  @private
            +			 */
            +			this._panner = this.input = new Tone.Panner(pan);
            +
            +			/**
            +			 * the output node
            +			 * @type {GainNode}
            +			 */
            +			this.output = this.context.createGain();
            +
            +			/**
            +			 *  The volume control in decibels. 
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.volume = new Tone.Signal(this.output.gain, Tone.Signal.Units.Decibels);
            +			this.volume.value = this.defaultArg(volume, 0);
            +
            +			/**
            +			 *  the panning control
            +			 *  @type {Tone.Panner}
            +			 *  @private
            +			 */
            +			this.pan = this._panner.pan;
            +
            +			//connections
            +			this._panner.connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.PanVol);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.PanVol} `this`
            +		 */
            +		Tone.PanVol.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._panner.dispose();
            +			this._panner = null;
            +			this.volume.dispose();
            +			this.volume = null;
            +			this.pan = null;
            +			return this;
            +		};
            +
            +		return Tone.PanVol;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @deprecated
            +		 *  @class  Record an input into an array or AudioBuffer. 
            +		 *          it is limited in that the recording length needs to be known beforehand. 
            +		 *          Mostly used internally for testing. 
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @param {number} channels 
            +		 */
            +		Tone.Recorder = function(channels){
            +
            +			console.warn("Tone.Recorder is deprecated. It will be removed in next version");
            +
            +			Tone.call(this);
            +
            +			/**
            +			 *  the number of channels in the recording
            +			 *  @type {number}
            +			 */
            +			this.channels = this.defaultArg(channels, 1);
            +
            +			/**
            +			 *  @private
            +			 *  @type {ScriptProcessorNode}
            +			 */
            +			this._jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, 1);
            +			this._jsNode.onaudioprocess = this._audioprocess.bind(this);
            +
            +			/**
            +			 *  Float32Array for each channel
            +			 *  @private
            +			 *  @type {Array<Float32Array>}
            +			 */
            +			this._recordBuffers = new Array(this.channels);
            +
            +			/**
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._recordStartSample = 0;
            +
            +			/**
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._recordEndSample = 0;
            +
            +			/**
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._recordDuration = 0;
            +
            +			/**
            +			 *  @type {RecordState}
            +			 */
            +			this.state = RecordState.STOPPED;
            +
            +			/** 
            +			 *  @private
            +			 *  @type {number}
            +			 */
            +			this._recordBufferOffset = 0;
            +
            +			/** 
            +			 *  callback invoked when the recording is over
            +			 *  @private
            +			 *  @type {function(Float32Array)}
            +			 */
            +			this._callback = function(){};
            +
            +			//connect it up
            +			this.input.connect(this._jsNode);
            +			//pass thru audio
            +			this.input.connect(this.output);
            +			//so it doesn't get garbage collected
            +			this._jsNode.noGC();
            +			//clear it to start
            +			this.clear();
            +		};
            +
            +		Tone.extend(Tone.Recorder);
            +
            +		/**
            +		 *  internal method called on audio process
            +		 *  
            +		 *  @private
            +		 *  @param   {AudioProcessorEvent} event 
            +		 */
            +		Tone.Recorder.prototype._audioprocess = function(event){
            +			if (this.state === RecordState.STOPPED){
            +				return;
            +			} else if (this.state === RecordState.RECORDING){
            +				//check if it's time yet
            +				var now = this.defaultArg(event.playbackTime, this.now());
            +				var processPeriodStart = this.toSamples(now);
            +				var bufferSize = this._jsNode.bufferSize;
            +				var processPeriodEnd = processPeriodStart + bufferSize;
            +				var bufferOffset, len;
            +				if (processPeriodStart > this._recordEndSample){
            +					this.state = RecordState.STOPPED;
            +					this._callback(this._recordBuffers);
            +				} else if (processPeriodStart > this._recordStartSample) {
            +					bufferOffset = 0;
            +					len = Math.min(this._recordEndSample - processPeriodStart, bufferSize);
            +					this._recordChannels(event.inputBuffer, bufferOffset, len, bufferSize);
            +				} else if (processPeriodEnd > this._recordStartSample) {
            +					len = processPeriodEnd - this._recordStartSample;
            +					bufferOffset = bufferSize - len;
            +					this._recordChannels(event.inputBuffer, bufferOffset, len, bufferSize);
            +				} 
            +
            +			}
            +		};
            +
            +		/**
            +		 *  record an input channel
            +		 *  @param   {AudioBuffer} inputBuffer        
            +		 *  @param   {number} from  
            +		 *  @param   {number} to  
            +		 *  @private
            +		 */
            +		Tone.Recorder.prototype._recordChannels = function(inputBuffer, from, to, bufferSize){
            +			var offset = this._recordBufferOffset;
            +			var buffers = this._recordBuffers;
            +			for (var channelNum = 0; channelNum < inputBuffer.numberOfChannels; channelNum++){
            +				var channel = inputBuffer.getChannelData(channelNum);
            +				if ((from === 0) && (to === bufferSize)){
            +					//set the whole thing
            +					this._recordBuffers[channelNum].set(channel, offset);
            +				} else {
            +					for (var i = from; i < from + to; i++){
            +						var zeroed = i - from; 
            +						buffers[channelNum][zeroed + offset] = channel[i];				
            +					}
            +				}
            +			}
            +			this._recordBufferOffset += to;
            +		};	
            +
            +		/**
            +		 *  Record for a certain period of time
            +		 *  
            +		 *  will clear the internal buffer before starting
            +		 *  
            +		 *  @param  {Tone.Time} duration 
            +		 *  @param  {Tone.Time} wait the wait time before recording
            +		 *  @param {function(Float32Array)} callback the callback to be invoked when the buffer is done recording
            +		 *  @returns {Tone.Recorder} `this`
            +		 */
            +		Tone.Recorder.prototype.record = function(duration, startTime, callback){
            +			if (this.state === RecordState.STOPPED){
            +				this.clear();
            +				this._recordBufferOffset = 0;
            +				startTime = this.defaultArg(startTime, 0);
            +				this._recordDuration = this.toSamples(duration);
            +				this._recordStartSample = this.toSamples("+"+startTime);
            +				this._recordEndSample = this._recordStartSample + this._recordDuration;
            +				for (var i = 0; i < this.channels; i++){
            +					this._recordBuffers[i] = new Float32Array(this._recordDuration);
            +				}
            +				this.state = RecordState.RECORDING;
            +				this._callback = this.defaultArg(callback, function(){});
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  clears the recording buffer
            +		 *  @returns {Tone.PanVol} `this`
            +		 */
            +		Tone.Recorder.prototype.clear = function(){
            +			for (var i = 0; i < this.channels; i++){
            +				this._recordBuffers[i] = null;
            +			}
            +			this._recordBufferOffset = 0;
            +			return this;
            +		};
            +
            +
            +		/**
            +		 *  true if there is nothing in the buffers
            +		 *  @return {boolean} 
            +		 */
            +		Tone.Recorder.prototype.isEmpty = function(){
            +			return this._recordBuffers[0] === null;
            +		};
            +
            +		/**
            +		 *  @return {Array<Float32Array>}
            +		 */
            +		Tone.Recorder.prototype.getFloat32Array = function(){
            +			if (this.isEmpty()){
            +				return null;
            +			} else {
            +				return this._recordBuffers;
            +			}
            +		};
            +
            +		/**
            +		 *  @return {AudioBuffer}
            +		 */
            +		Tone.Recorder.prototype.getAudioBuffer = function(){
            +			if (this.isEmpty()){
            +				return null;
            +			} else {
            +				var audioBuffer = this.context.createBuffer(this.channels, this._recordBuffers[0].length, this.context.sampleRate);
            +				for (var channelNum = 0; channelNum < audioBuffer.numberOfChannels; channelNum++){
            +					var channel = audioBuffer.getChannelData(channelNum);
            +					channel.set(this._recordBuffers[channelNum]);
            +				}
            +				return audioBuffer;
            +			}
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.PanVol} `this`
            +		 */
            +		Tone.Recorder.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._jsNode.disconnect();
            +			this._jsNode.onaudioprocess = undefined;
            +			this._jsNode = null;
            +			this._recordBuffers = null;
            +			return this;
            +		};
            +
            +		/**
            +		 *  @enum {string}
            +		 */
            +		var RecordState = {
            +			STOPPED : "stopped",
            +			SCHEDULED : "scheduled",
            +			RECORDING : "recording"
            +		};
            +
            +		return Tone.Recorder;
            +	});
            +	toneModule( 
            +		function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class An envelope which can be scaled to any range. 
            +		 *         Useful for applying an envelope to a filter
            +		 *
            +		 *  @extends {Tone.Envelope}
            +		 *  @constructor
            +		 *  @param {Tone.Time|Object} [attack=0.01]	the attack time in seconds
            +		 *  @param {Tone.Time} [decay=0.1]	the decay time in seconds
            +		 *  @param {number} [sustain=0.5] 	a percentage (0-1) of the full amplitude
            +		 *  @param {Tone.Time} [release=1]	the release time in seconds
            +		 */
            +		Tone.ScaledEnvelope = function(){
            +
            +			//get all of the defaults
            +			var options = this.optionsObject(arguments, ["attack", "decay", "sustain", "release"], Tone.Envelope.defaults);
            +			Tone.Envelope.call(this, options);
            +			options = this.defaultArg(options, Tone.ScaledEnvelope.defaults);
            +
            +			/** 
            +			 *  scale the incoming signal by an exponent
            +			 *  @type {Tone.Pow}
            +			 *  @private
            +			 */
            +			this._exp = this.output = new Tone.Pow(options.exponent);
            +
            +			/**
            +			 *  scale the signal to the desired range
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._scale = this.output = new Tone.Scale(options.min, options.max);
            +
            +			this._sig.chain(this._exp, this._scale);
            +		};
            +
            +		Tone.extend(Tone.ScaledEnvelope, Tone.Envelope);
            +
            +		/**
            +		 *  the default parameters
            +		 *  @static
            +		 */
            +		Tone.ScaledEnvelope.defaults = {
            +			"min" : 0,
            +			"max" : 1,
            +			"exponent" : 1
            +		};
            +
            +		/**
            +		 * The envelope's min output value.
            +		 * @memberOf Tone.ScaledEnvelope#
            +		 * @type {number}
            +		 * @name min
            +		 */
            +		Object.defineProperty(Tone.ScaledEnvelope.prototype, "min", {
            +			get : function(){
            +				return this._scale.min;
            +			},
            +			set : function(min){
            +				this._scale.min = min;
            +			}
            +		});
            +
            +		/**
            +		 * The envelope's max output value. 
            +		 * @memberOf Tone.ScaledEnvelope#
            +		 * @type {number}
            +		 * @name max
            +		 */
            +		Object.defineProperty(Tone.ScaledEnvelope.prototype, "max", {
            +			get : function(){
            +				return this._scale.max;
            +			},
            +			set : function(max){
            +				this._scale.max = max;
            +			}
            +		});
            +
            +		/**
            +		 * the envelope's exponent
            +		 * @memberOf Tone.ScaledEnvelope#
            +		 * @type {number}
            +		 * @name exponent
            +		 */
            +		Object.defineProperty(Tone.ScaledEnvelope.prototype, "exponent", {
            +			get : function(){
            +				return this._exp.value;
            +			},
            +			set : function(exp){
            +				this._exp.value = exp;
            +			}
            +		});
            +		
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.ScaledEnvelope} `this`
            +		 */
            +		Tone.ScaledEnvelope.prototype.dispose = function(){
            +			Tone.Envelope.prototype.dispose.call(this);
            +			this._scale.dispose();
            +			this._scale = null;
            +			this._exp.dispose();
            +			this._exp = null;
            +			return this;
            +		};
            +
            +		return Tone.ScaledEnvelope;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Buffer loading and storage. Tone.Buffer will load and store the buffers
            +		 *          in the same data structure they were given in the argument. If given
            +		 *          a string, this._buffer will equal an AudioBuffer. If constructed
            +		 *          with an array, the samples will be placed in an array in the same
            +		 *          order. 
            +		 *  
            +		 *  @constructor 
            +		 *  @param {AudioBuffer|string} url the url to load, or the audio buffer to set
            +		 */
            +		Tone.Buffer = function(){
            +
            +			var options = this.optionsObject(arguments, ["url", "onload"], Tone.Buffer.defaults);
            +
            +			/**
            +			 *  stores the loaded AudioBuffer
            +			 *  @type {AudioBuffer}
            +			 *  @private
            +			 */
            +			this._buffer = null;
            +
            +			/**
            +			 *  the url of the buffer. `undefined` if it was 
            +			 *  constructed with a buffer
            +			 *  @type {string}
            +			 *  @readOnly
            +			 */
            +			this.url = undefined;
            +
            +			/**
            +			 *  indicates if the buffer is loaded or not
            +			 *  @type {boolean}
            +			 *  @readOnly
            +			 */
            +			this.loaded = false;
            +
            +			/**
            +			 *  the callback to invoke when everything is loaded
            +			 *  @type {function}
            +			 */
            +			this.onload = options.onload.bind(this, this);
            +
            +			if (options.url instanceof AudioBuffer){
            +				this._buffer.set(options.url);
            +				this.onload(this);
            +			} else if (typeof options.url === "string"){
            +				this.url = options.url;
            +				Tone.Buffer._addToQueue(options.url, this);
            +			}
            +		};
            +
            +		Tone.extend(Tone.Buffer);
            +
            +		/**
            +		 *  the default parameters
            +		 *
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.Buffer.defaults = {
            +			"url" : undefined,
            +			"onload" : function(){},
            +		};
            +
            +		/**
            +		 *  set the buffer
            +		 *  @param {AudioBuffer|Tone.Buffer} buffer the buffer
            +		 *  @returns {Tone.Buffer} `this`
            +		 */
            +		Tone.Buffer.prototype.set = function(buffer){
            +			if (buffer instanceof Tone.Buffer){
            +				this._buffer = buffer.get();
            +			} else {
            +				this._buffer = buffer;
            +			}
            +			this.loaded = true;
            +			return this;
            +		};
            +
            +		/**
            +		 *  @return {AudioBuffer} the audio buffer
            +		 */
            +		Tone.Buffer.prototype.get = function(){
            +			return this._buffer;
            +		};
            +
            +		/**
            +		 *  @param {string} url the url to load
            +		 *  @param {function=} callback the callback to invoke on load. 
            +		 *                              don't need to set if `onload` is
            +		 *                              already set.
            +		 *  @returns {Tone.Buffer} `this`
            +		 */
            +		Tone.Buffer.prototype.load = function(url, callback){
            +			this.url = url;
            +			this.onload = this.defaultArg(callback, this.onload);
            +			Tone.Buffer._addToQueue(url, this);
            +			return this;
            +		};
            +
            +		/**
            +		 *  dispose and disconnect
            +		 *  @returns {Tone.Buffer} `this`
            +		 */
            +		Tone.Buffer.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			Tone.Buffer._removeFromQueue(this);
            +			this._buffer = null;
            +			this.onload = null;
            +			return this;
            +		};
            +
            +		/**
            +		 * the duration of the buffer
            +		 * @memberOf Tone.Buffer#
            +		 * @type {number}
            +		 * @name duration
            +		 * @readOnly
            +		 */
            +		Object.defineProperty(Tone.Buffer.prototype, "duration", {
            +			get : function(){
            +				if (this._buffer){
            +					return this._buffer.duration;
            +				} else {
            +					return 0;
            +				}
            +			},
            +		});
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		// STATIC METHODS
            +		///////////////////////////////////////////////////////////////////////////
            +		 
            +		/**
            +		 *  the static queue for all of the xhr requests
            +		 *  @type {Array}
            +		 *  @private
            +		 */
            +		Tone.Buffer._queue = [];
            +
            +		/**
            +		 *  the array of current downloads
            +		 *  @type {Array}
            +		 *  @private
            +		 */
            +		Tone.Buffer._currentDownloads = [];
            +
            +		/**
            +		 *  the total number of downloads
            +		 *  @type {number}
            +		 *  @private
            +		 */
            +		Tone.Buffer._totalDownloads = 0;
            +
            +		/**
            +		 *  the maximum number of simultaneous downloads
            +		 *  @static
            +		 *  @type {number}
            +		 */
            +		Tone.Buffer.MAX_SIMULTANEOUS_DOWNLOADS = 6;
            +
            +		/**
            +		 *  Flag if everything was loaded.
            +		 *  @static
            +		 *  @readOnly
            +		 *  @type {boolean}
            +		 */
            +		Tone.Buffer.allLoaded = false;
            +		
            +		/**
            +		 *  Adds a file to be loaded to the loading queue
            +		 *  @param   {string}   url      the url to load
            +		 *  @param   {function} callback the callback to invoke once it's loaded
            +		 *  @private
            +		 */
            +		Tone.Buffer._addToQueue = function(url, buffer){
            +			Tone.Buffer._queue.push({
            +				url : url,
            +				Buffer : buffer,
            +				progress : 0,
            +				xhr : null
            +			});
            +			this._totalDownloads++;
            +			Tone.Buffer._next();
            +		};
            +
            +		/**
            +		 *  Remove an object from the queue's (if it's still there)
            +		 *  Abort the XHR if it's in progress
            +		 *  @param {Tone.Buffer} buffer the buffer to remove
            +		 *  @private
            +		 */
            +		Tone.Buffer._removeFromQueue = function(buffer){
            +			var i;
            +			for (i = 0; i < Tone.Buffer._queue.length; i++){
            +				var q = Tone.Buffer._queue[i];
            +				if (q.Buffer === buffer){
            +					Tone.Buffer._queue.splice(i, 1);
            +				}
            +			}
            +			for (i = 0; i < Tone.Buffer._currentDownloads.length; i++){
            +				var dl = Tone.Buffer._currentDownloads[i];
            +				if (dl.Buffer === buffer){
            +					Tone.Buffer._currentDownloads.splice(i, 1);
            +					dl.xhr.abort();
            +					dl.xhr.onprogress = null;
            +					dl.xhr.onload = null;
            +					dl.xhr.onerror = null;
            +				}
            +			}
            +		};
            +
            +		/**
            +		 *  load the next buffer in the queue
            +		 *  @private
            +		 */
            +		Tone.Buffer._next = function(){
            +			if (Tone.Buffer._queue.length > 0){
            +				if (Tone.Buffer._currentDownloads.length < Tone.Buffer.MAX_SIMULTANEOUS_DOWNLOADS){
            +					var next = Tone.Buffer._queue.shift();
            +					Tone.Buffer._currentDownloads.push(next);
            +					next.xhr = Tone.Buffer.load(next.url, function(buffer){
            +						//remove this one from the queue
            +						var index = Tone.Buffer._currentDownloads.indexOf(next);
            +						Tone.Buffer._currentDownloads.splice(index, 1);
            +						next.Buffer.set(buffer);
            +						next.Buffer.onload(next.Buffer);
            +						Tone.Buffer._onprogress();
            +						Tone.Buffer._next();
            +					});
            +					next.xhr.onprogress = function(event){
            +						next.progress = event.loaded / event.total;
            +						Tone.Buffer._onprogress();
            +					};
            +					next.xhr.onerror = Tone.Buffer.onerror;
            +				} 
            +			} else if (Tone.Buffer._currentDownloads.length === 0){
            +				Tone.Buffer.allLoaded = true;
            +				Tone.Buffer.onload();
            +				//reset the downloads
            +				Tone.Buffer._totalDownloads = 0;
            +			}
            +		};
            +
            +		/**
            +		 *  internal progress event handler
            +		 *  @private
            +		 */
            +		Tone.Buffer._onprogress = function(){
            +			var curretDownloadsProgress = 0;
            +			var currentDLLen = Tone.Buffer._currentDownloads.length;
            +			var inprogress = 0;
            +			if (currentDLLen > 0){
            +				for (var i = 0; i < currentDLLen; i++){
            +					var dl = Tone.Buffer._currentDownloads[i];
            +					curretDownloadsProgress += dl.progress;
            +				}
            +				inprogress = curretDownloadsProgress;
            +			}
            +			var currentDownloadProgress = currentDLLen - inprogress;
            +			var completed = Tone.Buffer._totalDownloads - Tone.Buffer._queue.length - currentDownloadProgress;
            +			Tone.Buffer.onprogress(completed / Tone.Buffer._totalDownloads);
            +		};
            +
            +		/**
            +		 *  makes an xhr reqest for the selected url
            +		 *  Load the audio file as an audio buffer.
            +		 *  Decodes the audio asynchronously and invokes
            +		 *  the callback once the audio buffer loads.
            +		 *  @param {string} url the url of the buffer to load.
            +		 *                      filetype support depends on the
            +		 *                      browser.
            +		 *  @param {function} callback function
            +		 *  @returns {XMLHttpRequest} returns the XHR
            +		 */
            +		Tone.Buffer.load = function(url, callback){
            +			var request = new XMLHttpRequest();
            +			request.open("GET", url, true);
            +			request.responseType = "arraybuffer";
            +			// decode asynchronously
            +			request.onload = function() {
            +				Tone.context.decodeAudioData(request.response, function(buff) {
            +					if(!buff){
            +						throw new Error("could not decode audio data:" + url);
            +					}
            +					callback(buff);
            +				});
            +			};
            +			//send the request
            +			request.send();
            +			return request;
            +		};
            +
            +		/**
            +		 *  callback when all of the buffers in the queue have loaded
            +		 *  @static
            +		 *  @type {function}
            +		 */
            +		Tone.Buffer.onload = function(){};
            +
            +		/**
            +		 *  callback with the progress of all of the loads in the queue
            +		 *  @static
            +		 *  @type {function}
            +		 */
            +		Tone.Buffer.onprogress = function(){};
            +
            +		/**
            +		 *  callback if one of the buffers in the queue encounters an error
            +		 *  @static
            +		 *  @type {function}
            +		 */
            +		Tone.Buffer.onerror = function(){};
            +
            +		return Tone.Buffer;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  buses are another way of routing audio
            +		 *
            +		 *  augments Tone.prototype to include send and recieve
            +		 */
            +
            +		 /**
            +		  *  All of the routes
            +		  *  
            +		  *  @type {Object}
            +		  *  @static
            +		  *  @private
            +		  */
            +		var Buses = {};
            +
            +		/**
            +		 *  send signal to a channel name
            +		 *  defined in "Tone/core/Bus"
            +		 *
            +		 *  @param  {string} channelName 
            +		 *  @param  {number} amount      
            +		 *  @return {GainNode}             
            +		 */
            +		Tone.prototype.send = function(channelName, amount){
            +			if (!Buses.hasOwnProperty(channelName)){
            +				Buses[channelName] = this.context.createGain();
            +			}
            +			var sendKnob = this.context.createGain();
            +			sendKnob.gain.value = this.defaultArg(amount, 1);
            +			this.output.chain(sendKnob, Buses[channelName]);
            +			return sendKnob;		
            +		};
            +
            +		/**
            +		 *  recieve the input from the desired channelName to the input
            +		 *  defined in "Tone/core/Bus"
            +		 *
            +		 *  @param  {string} channelName 
            +		 *  @param {AudioNode} [input=this.input] if no input is selected, the
            +		 *                                         input of the current node is
            +		 *                                         chosen. 
            +		 *  @returns {Tone} `this`
            +		 */
            +		Tone.prototype.receive = function(channelName, input){
            +			if (!Buses.hasOwnProperty(channelName)){
            +				Buses[channelName] = this.context.createGain();	
            +			}
            +			if (this.isUndef(input)){
            +				input = this.input;
            +			}
            +			Buses[channelName].connect(input);
            +			return this;
            +		};
            +
            +		return Tone;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  A timed note. Creating a note will register a callback 
            +		 *          which will be invoked on the channel at the time with
            +		 *          whatever value was specified. 
            +		 *
            +		 *  @constructor
            +		 *  @param {number|string} channel the channel name of the note
            +		 *  @param {Tone.Time} time the time when the note will occur
            +		 *  @param {string|number|Object|Array} value the value of the note
            +		 */
            +		Tone.Note = function(channel, time, value){
            +
            +			/**
            +			 *  the value of the note. This value is returned
            +			 *  when the channel callback is invoked.
            +			 *  
            +			 *  @type {string|number|Object}
            +			 */
            +			this.value = value;
            +
            +			/**
            +			 *  the channel name or number
            +			 *  
            +			 *  @type {string|number}
            +			 *  @private
            +			 */
            +			this._channel = channel;
            +
            +			/**
            +			 *  an internal reference to the id of the timeline
            +			 *  callback which is set. 
            +			 *  
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._timelineID = Tone.Transport.setTimeline(this._trigger.bind(this), time);
            +		};
            +
            +		/**
            +		 *  invoked by the timeline
            +		 *  @private
            +		 *  @param {number} time the time at which the note should play
            +		 */
            +		Tone.Note.prototype._trigger = function(time){
            +			//invoke the callback
            +			channelCallbacks(this._channel, time, this.value);
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Note} `this`
            +		 */
            +		Tone.Note.prototype.dispose = function(){ 
            +			Tone.Tranport.clearTimeline(this._timelineID);
            +			this.value = null;
            +			return this;
            +		};
            +
            +		/**
            +		 *  @private
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		var NoteChannels = {};
            +
            +		/**
            +		 *  invoke all of the callbacks on a specific channel
            +		 *  @private
            +		 */
            +		function channelCallbacks(channel, time, value){
            +			if (NoteChannels.hasOwnProperty(channel)){
            +				var callbacks = NoteChannels[channel];
            +				for (var i = 0, len = callbacks.length; i < len; i++){
            +					var callback = callbacks[i];
            +					if (Array.isArray(value)){
            +						callback.apply(window, [time].concat(value));
            +					} else {
            +						callback(time, value);
            +					}
            +				}
            +			}
            +		}
            +
            +		/**
            +		 *  listen to a specific channel, get all of the note callbacks
            +		 *  @static
            +		 *  @param {string|number} channel the channel to route note events from
            +		 *  @param {function(*)} callback callback to be invoked when a note will occur
            +		 *                                        on the specified channel
            +		 */
            +		Tone.Note.route = function(channel, callback){
            +			if (NoteChannels.hasOwnProperty(channel)){
            +				NoteChannels[channel].push(callback);
            +			} else {
            +				NoteChannels[channel] = [callback];
            +			}
            +		};
            +
            +		/**
            +		 *  remove a callback from a channel
            +		 *  @static
            +		 */
            +		Tone.Note.unroute = function(channel, callback){
            +			if (NoteChannels.hasOwnProperty(channel)){
            +				var channelCallback = NoteChannels[channel];
            +				var index = channelCallback.indexOf(callback);
            +				if (index !== -1){
            +					NoteChannels[channel].splice(index, 1);
            +				}
            +			}
            +		};
            +
            +		/**
            +		 *  Parses a score and registers all of the notes along the timeline. 
            +		 *
            +		 *  Scores are a JSON object with instruments at the top level
            +		 *  and an array of time and values. The value of a note can be 0 or more 
            +		 *  parameters. 
            +		 *
            +		 *  The only requirement for the score format is that the time is the first (or only)
            +		 *  value in the array. All other values are optional and will be passed into the callback
            +		 *  function registered using ""
            +		 *
            +		 *  ```javascript
            +		 *  var score = { 
            +		 *  	"synth"  : [["0", "C3"], ["0:1", "D3"], ["0:2", "E3"], ... ],
            +		 *  	"bass"  : [["0", "C2"], ["1:0", "A2"], ["2:0", "C2"], ["3:0", "A2"], ... ],
            +		 *  	"kick"  : ["0", "0:2", "1:0", "1:2", "2:0", ... ],
            +		 *  	//...
            +		 *  };
            +		 *  ```
            +		 *  
            +		 *  To convert MIDI files to score notation, take a look at utils/MidiToScore.js
            +		 *
            +		 *  @static
            +		 *  @param {Object} score
            +		 *  @return {Array<Tone.Note>} an array of all of the notes that were created
            +		 */
            +		Tone.Note.parseScore = function(score){
            +			var notes = [];
            +			for (var inst in score){
            +				var part = score[inst];
            +				if (inst === "tempo"){
            +					Tone.Transport.setBpm(part);
            +				} else if (inst === "timeSignature"){
            +					Tone.Transport.setTimeSignature(part[0], part[1]);
            +				} else if (Array.isArray(part)){
            +					for (var i = 0; i < part.length; i++){
            +						var noteDescription = part[i];
            +						var note;
            +						if (Array.isArray(noteDescription)){
            +							var time = noteDescription[0];
            +							var value = noteDescription.slice(1);
            +							note = new Tone.Note(inst, time, value);
            +						} else {
            +							note = new Tone.Note(inst, noteDescription);
            +						}
            +						notes.push(note);
            +					}
            +				} else {
            +					throw new TypeError("score parts must be Arrays");
            +				}
            +			}
            +			return notes;
            +		};
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		//	MUSIC NOTES
            +		//	
            +		//	Augments Tone.prototype to include note methods
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		var noteToIndex = { "c" : 0, "c#" : 1, "db" : 1, "d" : 2, "d#" : 3, "eb" : 3, 
            +			"e" : 4, "f" : 5, "f#" : 6, "gb" : 6, "g" : 7, "g#" : 8, "ab" : 8, 
            +			"a" : 9, "a#" : 10, "bb" : 10, "b" : 11
            +		};
            +
            +		var noteIndexToNote = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
            +
            +		var middleC = 261.6255653005986;
            +
            +		/**
            +		 *  convert a note name to frequency (i.e. A4 to 440)
            +		 *  defined in "Tone/core/Note"
            +		 *  
            +		 *  @param  {string} note
            +		 *  @return {number}         
            +		 */
            +		Tone.prototype.noteToFrequency = function(note){
            +			//break apart the note by frequency and octave
            +			var parts = note.split(/(\d+)/);
            +			if (parts.length === 3){
            +				var index = noteToIndex[parts[0].toLowerCase()];
            +				var octave = parts[1];
            +				var noteNumber = index + parseInt(octave, 10) * 12;
            +				return Math.pow(2, (noteNumber - 48) / 12) * middleC;
            +			} else {
            +				return 0;
            +			}
            +		};
            +
            +		/**
            +		 *  test if a string is in note format: i.e. "C4"
            +		 *  @param  {string|number}  note the note to test
            +		 *  @return {boolean}      true if it's in the form of a note
            +		 *  @method isNotation
            +		 *  @lends Tone.prototype.isNotation
            +		 */
            +		Tone.prototype.isNote = ( function(){
            +			var noteFormat = new RegExp(/[a-g]{1}([b#]{1}|[b#]{0})[0-9]+$/i);
            +			return function(note){
            +				if (typeof note === "string"){
            +					note = note.toLowerCase();
            +				} 
            +				return noteFormat.test(note);
            +			};
            +		})();
            +
            +		/**
            +		 *  a pointer to the previous toFrequency method
            +		 *  @private
            +		 *  @function
            +		 */
            +		Tone.prototype._overwrittenToFrequency = Tone.prototype.toFrequency;
            +
            +		/**
            +		 *  a to frequency method which accepts frequencies in the form
            +		 *  of notes ("C#4"), frequencies as strings ("49hz"), frequency numbers,
            +		 *  or notation ("4n")
            +		 *  @param  {string|number} note the note name or notation
            +		 *  @return {number}      the frequency as a number
            +		 */
            +		Tone.prototype.toFrequency = function(note){
            +			if (this.isNote(note)){
            +				note = this.noteToFrequency(note);
            +			} 
            +			return this._overwrittenToFrequency(note);
            +		};
            +
            +		/**
            +		 *  convert a note name (i.e. A4, C#5, etc to a frequency)
            +		 *  defined in "Tone/core/Note"
            +		 *  
            +		 *  @param  {number} freq
            +		 *  @return {string}         
            +		 */
            +		Tone.prototype.frequencyToNote = function(freq){
            +			var log = Math.log(freq / middleC) / Math.LN2;
            +			var noteNumber = Math.round(12 * log) + 48;
            +			var octave = Math.floor(noteNumber/12);
            +			var noteName = noteIndexToNote[noteNumber % 12];
            +			return noteName + octave.toString();
            +		};
            +
            +		/**
            +		 *  convert an interval (in semitones) to a frequency ratio
            +		 *  defined in "Tone/core/Note"
            +		 *
            +		 *  ```javascript
            +		 *  tone.intervalToFrequencyRatio(0); // returns 1
            +		 *  tone.intervalToFrequencyRatio(12); // returns 2
            +		 *  ```
            +		 *  
            +		 *  @param  {number} interval the number of semitones above the base note
            +		 *  @return {number}          the frequency ratio
            +		 */
            +		Tone.prototype.intervalToFrequencyRatio = function(interval){
            +			return Math.pow(2,(interval/12));
            +		};
            +
            +		/**
            +		 *  convert a midi note number into a note name
            +		 *  defined in "Tone/core/Note"
            +		 *
            +		 *  ```javascript
            +		 *  tone.midiToNote(60); // returns "C3"
            +		 *  ```
            +		 *  
            +		 *  @param  {number} midiNumber the midi note number
            +		 *  @return {string}            the note's name and octave
            +		 */
            +		Tone.prototype.midiToNote = function(midiNumber){
            +			var octave = Math.floor(midiNumber / 12) - 2;
            +			var note = midiNumber % 12;
            +			return noteIndexToNote[note] + octave;
            +		};
            +
            +		/**
            +		 *  convert a note to it's midi value
            +		 *  defined in "Tone/core/Note"
            +		 *
            +		 *  ```javascript
            +		 *  tone.noteToMidi("C3"); // returns 60
            +		 *  ```
            +		 *  
            +		 *  @param  {string} note the note name (i.e. "C3")
            +		 *  @return {number} the midi value of that note
            +		 */
            +		Tone.prototype.noteToMidi = function(note){
            +			//break apart the note by frequency and octave
            +			var parts = note.split(/(\d+)/);
            +			if (parts.length === 3){
            +				var index = noteToIndex[parts[0].toLowerCase()];
            +				var octave = parts[1];
            +				return index + (parseInt(octave, 10) + 2) * 12;
            +			} else {
            +				return 0;
            +			}
            +		};
            +
            +		return Tone.Note;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +		
            +		/**
            +		 * 	@class  Effect is the base class for effects. connect the effect between
            +		 * 	        the effectSend and effectReturn GainNodes. then control the amount of
            +		 * 	        effect which goes to the output using the dry/wet control.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @param {number} [initialWet=0] the starting wet value
            +		 *                                 defaults to 100% wet
            +		 */
            +		Tone.Effect = function(){
            +
            +			Tone.call(this);
            +
            +			//get all of the defaults
            +			var options = this.optionsObject(arguments, ["wet"], Tone.Effect.defaults);
            +
            +			/**
            +			 *  the drywet knob to control the amount of effect
            +			 *  @type {Tone.CrossFade}
            +			 */
            +			this.dryWet = new Tone.CrossFade(options.wet);
            +
            +			/**
            +			 *  The wet control, i.e. how much of the effected
            +			 *  will pass through to the output. 
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.wet = this.dryWet.fade;
            +
            +			/**
            +			 *  connect the effectSend to the input of hte effect
            +			 *  
            +			 *  @type {GainNode}
            +			 */
            +			this.effectSend = this.context.createGain();
            +
            +			/**
            +			 *  connect the output of the effect to the effectReturn
            +			 *  
            +			 *  @type {GainNode}
            +			 */
            +			this.effectReturn = this.context.createGain();
            +
            +			//connections
            +			this.input.connect(this.dryWet.a);
            +			this.input.connect(this.effectSend);
            +			this.effectReturn.connect(this.dryWet.b);
            +			this.dryWet.connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.Effect);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.Effect.defaults = {
            +			"wet" : 1
            +		};
            +
            +		/**
            +		 *  bypass the effect
            +		 *  @returns {Tone.Effect} `this`
            +		 */
            +		Tone.Effect.prototype.bypass = function(){
            +			this.setWet(0);
            +			return this;
            +		};
            +
            +		/**
            +		 *  chains the effect in between the effectSend and effectReturn
            +		 *  @param  {Tone} effect
            +		 *  @internal
            +		 *  @returns {Tone.Effect} `this`
            +		 */
            +		Tone.Effect.prototype.connectEffect = function(effect){
            +			this.effectSend.chain(effect, this.effectReturn);
            +			return this;
            +		};
            +
            +		/**
            +		 *  set the preset if it exists
            +		 *  @param {string} presetName the name of the preset
            +		 *  @returns {Tone.Effect} `this`
            +		 */
            +		Tone.Effect.prototype.setPreset = function(presetName){
            +			if (!this.isUndef(this.preset) && this.preset.hasOwnProperty(presetName)){
            +				this.set(this.preset[presetName]);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  tear down
            +		 *  @returns {Tone.Effect} `this`
            +		 */
            +		Tone.Effect.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.dryWet.dispose();
            +			this.dryWet = null;
            +			this.effectSend.disconnect();
            +			this.effectSend = null;
            +			this.effectReturn.disconnect();
            +			this.effectReturn = null;
            +			this.wet = null;
            +			return this;
            +		};
            +
            +		return Tone.Effect;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class AutoPanner is a Tone.Panner with an LFO connected to the pan amount
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Effect}
            +		 *  @param {number} [frequency=1] (optional) rate in HZ of the left-right pan
            +		 */
            +		Tone.AutoPanner = function(){
            +
            +			var options = this.optionsObject(arguments, ["frequency"], Tone.AutoPanner.defaults);
            +			Tone.Effect.call(this, options);
            +
            +			/**
            +			 *  the lfo which drives the panning
            +			 *  @type {Tone.LFO}
            +			 *  @private
            +			 */
            +			this._lfo = new Tone.LFO(options.frequency, 0, 1);
            +
            +			/**
            +			 * The amount of panning between left and right. 
            +			 * 0 = always center. 1 = full range between left and right. 
            +			 * @type {Tone.Signal}
            +			 */
            +			this.amount = this._lfo.amplitude;
            +
            +			/**
            +			 *  the panner node which does the panning
            +			 *  @type {Tone.Panner}
            +			 *  @private
            +			 */
            +			this._panner = new Tone.Panner();
            +
            +			/**
            +			 * How fast the panner modulates
            +			 * @type {Tone.Signal}
            +			 */
            +			this.frequency = this._lfo.frequency;
            +
            +			//connections
            +			this.connectEffect(this._panner);
            +			this._lfo.connect(this._panner.pan);
            +			this.type = options.type;
            +		};
            +
            +		//extend Effect
            +		Tone.extend(Tone.AutoPanner, Tone.Effect);
            +
            +		/**
            +		 *  defaults
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.AutoPanner.defaults = {
            +			"frequency" : 1,
            +			"type" : "sine",
            +			"amount" : 1
            +		};
            +		
            +		/**
            +		 * Start the panner
            +		 * 
            +		 * @param {Tone.Time} [time=now] the panner begins.
            +		 * @returns {Tone.AutoPanner} `this`
            +		 */
            +		Tone.AutoPanner.prototype.start = function(time){
            +			this._lfo.start(time);
            +			return this;
            +		};
            +
            +		/**
            +		 * Stop the panner
            +		 * 
            +		 * @param {Tone.Time} [time=now] the panner stops.
            +		 * @returns {Tone.AutoPanner} `this`
            +		 */
            +		Tone.AutoPanner.prototype.stop = function(time){
            +			this._lfo.stop(time);
            +			return this;
            +		};
            +
            +		/**
            +		 * sync the panner to the transport
            +		 * @returns {Tone.AutoPanner} `this`
            +		 */
            +		Tone.AutoPanner.prototype.sync = function(){
            +			this._lfo.sync();
            +			return this;
            +		};
            +
            +		/**
            +		 * unsync the panner from the transport
            +		 * @returns {Tone.AutoPanner} `this`
            +		 */
            +		Tone.AutoPanner.prototype.unsync = function(){
            +			this._lfo.unsync();
            +			return this;
            +		};
            +
            +		/**
            +		 * Type of oscillator attached to the AutoPanner.
            +		 * @memberOf Tone.AutoPanner#
            +		 * @type {string}
            +		 * @name type
            +		 */
            +		Object.defineProperty(Tone.AutoPanner.prototype, "type", {
            +			get : function(){
            +				return this._lfo.type;
            +			},
            +			set : function(type){
            +				this._lfo.type = type;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.AutoPanner} `this`
            +		 */
            +		Tone.AutoPanner.prototype.dispose = function(){
            +			Tone.Effect.prototype.dispose.call(this);
            +			this._lfo.dispose();
            +			this._lfo = null;
            +			this._panner.dispose();
            +			this._panner = null;
            +			this.frequency = null;
            +			this.amount = null;
            +			return this;
            +		};
            +
            +		return Tone.AutoPanner;
            +	});
            +
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  AutoWah connects an envelope follower to a bandpass filter.
            +		 *          Some inspiration from Tuna.js https://github.com/Dinahmoe/tuna
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Effect}
            +		 *  @param {number} [baseFrequency=100] the frequency the filter is set 
            +		 *                                       to at the low point of the wah
            +		 *  @param {number} [octaves=5] the number of octaves above the baseFrequency
            +		 *                               the filter will sweep to when fully open
            +		 *  @param {number} [sensitivity=0] the decibel threshold sensitivity for 
            +		 *                                   the incoming signal. Normal range of -40 to 0. 
            +		 */
            +		Tone.AutoWah = function(){
            +
            +			var options = this.optionsObject(arguments, ["baseFrequency", "octaves", "sensitivity"], Tone.AutoWah.defaults);
            +			Tone.Effect.call(this, options);
            +
            +			/**
            +			 *  the envelope follower
            +			 *  @type {Tone.Follower}
            +			 *  @private
            +			 */
            +			this.follower = new Tone.Follower(options.follower);
            +
            +			/**
            +			 *  scales the follower value to the frequency domain
            +			 *  @type {Tone}
            +			 *  @private
            +			 */
            +			this._sweepRange = new Tone.ScaleExp(0, 1, 0.5);
            +
            +			/**
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._baseFrequency = options.baseFrequency;
            +
            +			/**
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._octaves = options.octaves;
            +
            +			/**
            +			 *  @type {BiquadFilterNode}
            +			 *  @private
            +			 */
            +			this._bandpass = new Tone.Filter({
            +				"rolloff" : -48,
            +				"frequency" : 0,
            +				"Q" : options.Q,
            +			});
            +		
            +			/**
            +			 *  @type {Tone.Filter}
            +			 *  @private
            +			 */
            +			this._peaking = new Tone.Filter(0, "peaking");
            +			this._peaking.gain.value = options.gain;
            +
            +			/**
            +			 * the gain of the filter.
            +			 * @type {Tone.Signal}
            +			 */
            +			this.gain = this._peaking.gain;
            +
            +			/**
            +			 * The quality of the filter.
            +			 * @type {Tone.Signal}
            +			 */
            +			this.Q = this._bandpass.Q;
            +
            +			//the control signal path
            +			this.effectSend.chain(this.follower, this._sweepRange);
            +			this._sweepRange.connect(this._bandpass.frequency);
            +			this._sweepRange.connect(this._peaking.frequency);
            +			//the filtered path
            +			this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn);
            +			//set the initial value
            +			this._setSweepRange();
            +			this.sensitivity = options.sensitivity;
            +		};
            +
            +		Tone.extend(Tone.AutoWah, Tone.Effect);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.AutoWah.defaults = {
            +			"baseFrequency" : 100,
            +			"octaves" : 6,
            +			"sensitivity" : 0,
            +			"Q" : 2,
            +			"gain" : 2,
            +			"follower" : {
            +				"attack" : 0.3,
            +				"release" : 0.5
            +			}
            +		};
            +
            +		/**
            +		 * The number of octaves that the filter will sweep.
            +		 * @memberOf Tone.AutoWah#
            +		 * @type {number}
            +		 * @name octaves
            +		 */
            +		Object.defineProperty(Tone.AutoWah.prototype, "octaves", {
            +			get : function(){
            +				return this._octaves;
            +			}, 
            +			set : function(octaves){
            +				this._octaves = octaves;
            +				this._setSweepRange();
            +			}
            +		});
            +
            +		/**
            +		 * The base frequency from which the sweep will start from.
            +		 * @memberOf Tone.AutoWah#
            +		 * @type {Tone.Frequency}
            +		 * @name baseFrequency
            +		 */
            +		Object.defineProperty(Tone.AutoWah.prototype, "baseFrequency", {
            +			get : function(){
            +				return this._baseFrequency;
            +			}, 
            +			set : function(baseFreq){
            +				this._baseFrequency = baseFreq;
            +				this._setSweepRange();
            +			}
            +		});
            +
            +		/**
            +		 * The sensitivity to control how responsive to the input signal the filter is. 
            +		 * in Decibels. 
            +		 * @memberOf Tone.AutoWah#
            +		 * @type {number}
            +		 * @name sensitivity
            +		 */
            +		Object.defineProperty(Tone.AutoWah.prototype, "sensitivity", {
            +			get : function(){
            +				return this.gainToDb(this._sweepRange.max);
            +			}, 
            +			set : function(sensitivy){
            +				this._sweepRange.max = this.dbToGain(sensitivy);
            +			}
            +		});
            +
            +		/**
            +		 *  sets the sweep range of the scaler
            +		 *  @private
            +		 */
            +		Tone.AutoWah.prototype._setSweepRange = function(){
            +			this._sweepRange.min = this._baseFrequency;
            +			this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2);
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.AutoWah} `this`
            +		 */
            +		Tone.AutoWah.prototype.dispose = function(){
            +			Tone.Effect.prototype.dispose.call(this);
            +			this.follower.dispose();
            +			this.follower = null;
            +			this._sweepRange.dispose();
            +			this._sweepRange = null;
            +			this._bandpass.dispose();
            +			this._bandpass = null;
            +			this._peaking.dispose();
            +			this._peaking = null;
            +			this.gain = null;
            +			this.Q = null;
            +			return this;
            +		};
            +
            +		return Tone.AutoWah;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class downsample incoming signal. 
            +		 *
            +		 *  The algorithm to downsample the incoming signal is to scale the input
            +		 *  to between [0, 2^bits) and then apply a Floor function to the scaled value, 
            +		 *  then scale it back to audio range [-1, 1]
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Effect}
            +		 *  @param {number} bits 1-8. 
            +		 */
            +		Tone.BitCrusher = function(){
            +
            +			var options = this.optionsObject(arguments, ["bits"], Tone.BitCrusher.defaults);
            +			Tone.Effect.call(this, options);
            +
            +			var invStepSize = 1 / Math.pow(2, options.bits - 1);
            +			/**
            +			 *  floor function
            +			 *  @type {Tone.Expr}
            +			 *  @private
            +			 */
            +			this._floor = new Tone.Expr("$0 - mod($0, %, %)", invStepSize, options.bits);
            +
            +			//connect it up
            +			this.connectEffect(this._floor);
            +		};
            +
            +		Tone.extend(Tone.BitCrusher, Tone.Effect);
            +
            +		/**
            +		 *  the default values
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.BitCrusher.defaults = {
            +			"bits" : 4
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.BitCrusher} `this`
            +		 */
            +		Tone.BitCrusher.prototype.dispose = function(){
            +			Tone.Effect.prototype.dispose.call(this);
            +			this._floor.dispose();
            +			this._floor = null;
            +			return this;
            +		}; 
            +
            +		return Tone.BitCrusher;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A Chebyshev waveshaper. Good for making different types of distortion sounds.
            +		 *         Note that odd orders sound very different from even ones. order = 1 is no change. 
            +		 *         http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php
            +		 *
            +		 *  @extends {Tone.Effect}
            +		 *  @constructor
            +		 *  @param {number} order the order of the chebyshev polynomial
            +		 */
            +		Tone.Chebyshev = function(){
            +
            +			var options = this.optionsObject(arguments, ["order"], Tone.Chebyshev.defaults);
            +			Tone.Effect.call(this);
            +
            +			/**
            +			 *  @type {WaveShaperNode}
            +			 *  @private
            +			 */
            +			this._shaper = new Tone.WaveShaper(4096);
            +
            +			/**
            +			 * holds onto the order of the filter
            +			 * @type {number}
            +			 * @private
            +			 */
            +			this._order = options.order;
            +
            +			this.connectEffect(this._shaper);
            +			this.order = options.order;
            +			this.oversample = options.oversample;
            +		};
            +
            +		Tone.extend(Tone.Chebyshev, Tone.Effect);
            +
            +		/**
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.Chebyshev.defaults = {
            +			"order" : 1,
            +			"oversample" : "none"
            +		};
            +		
            +		/**
            +		 *  get the coefficient for that degree
            +		 *  @param {number} x the x value
            +		 *  @param   {number} degree 
            +		 *  @param {Object} memo memoize the computed value. 
            +		 *                       this speeds up computation greatly. 
            +		 *  @return  {number}       the coefficient 
            +		 *  @private
            +		 */
            +		Tone.Chebyshev.prototype._getCoefficient = function(x, degree, memo){
            +			if (memo.hasOwnProperty(degree)){
            +				return memo[degree];
            +			} else if (degree === 0){
            +				memo[degree] = 0;
            +			} else if (degree === 1){
            +				memo[degree] = x;
            +			} else {
            +				memo[degree] = 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo);
            +			}
            +			return memo[degree];
            +		};
            +
            +		/**
            +		 * The order of the Chebyshev polynomial i.e.
            +		 * order = 2 -> 2x^2 + 1. order = 3 -> 4x^3 + 3x. 
            +		 * @memberOf Tone.Chebyshev#
            +		 * @type {number}
            +		 * @name order
            +		 */
            +		Object.defineProperty(Tone.Chebyshev.prototype, "order", {
            +			get : function(){
            +				return this._order;
            +			},
            +			set : function(order){
            +				this._order = order;
            +				var curve = new Array(4096);
            +				var len = curve.length;
            +				for (var i = 0; i < len; ++i) {
            +					var x = i * 2 / len - 1;
            +					if (x === 0){
            +						//should output 0 when input is 0
            +						curve[i] = 0;
            +					} else {
            +						curve[i] = this._getCoefficient(x, order, {});
            +					}
            +				}
            +				this._shaper.curve = curve;
            +			} 
            +		});
            +
            +		/**
            +		 * The oversampling of the effect. Can either be "none", "2x" or "4x".
            +		 * @memberOf Tone.Chebyshev#
            +		 * @type {string}
            +		 * @name oversample
            +		 */
            +		Object.defineProperty(Tone.Chebyshev.prototype, "oversample", {
            +			get : function(){
            +				return this._shaper.oversample;
            +			},
            +			set : function(oversampling){
            +				this._shaper.oversample = oversampling;
            +			} 
            +		});
            +
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Chebyshev} `this`
            +		 */
            +		Tone.Chebyshev.prototype.dispose = function(){
            +			Tone.Effect.prototype.dispose.call(this);
            +			this._shaper.dispose();
            +			this._shaper = null;
            +			return this;
            +		};
            +
            +		return Tone.Chebyshev;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Creates an effect with an effectSendL/R and effectReturnL/R
            +		 *
            +		 *	@constructor
            +		 *	@extends {Tone.Effect}
            +		 */
            +		Tone.StereoEffect = function(){
            +
            +			Tone.call(this);
            +			//get the defaults
            +			var options = this.optionsObject(arguments, ["wet"], Tone.Effect.defaults);
            +
            +			/**
            +			 *  the drywet knob to control the amount of effect
            +			 *  @type {Tone.CrossFade}
            +			 */
            +			this.dryWet = new Tone.CrossFade(options.wet);
            +
            +			/**
            +			 *  The wet control, i.e. how much of the effected
            +			 *  will pass through to the output. 
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.wet = this.dryWet.fade;
            +
            +			/**
            +			 *  then split it
            +			 *  @type {Tone.Split}
            +			 *  @private
            +			 */
            +			this._split = new Tone.Split();
            +
            +			/**
            +			 *  the effects send LEFT
            +			 *  @type {GainNode}
            +			 */
            +			this.effectSendL = this._split.left;
            +
            +			/**
            +			 *  the effects send RIGHT
            +			 *  @type {GainNode}
            +			 */
            +			this.effectSendR = this._split.right;
            +
            +			/**
            +			 *  the stereo effect merger
            +			 *  @type {Tone.Merge}
            +			 *  @private
            +			 */
            +			this._merge = new Tone.Merge();
            +
            +			/**
            +			 *  the effect return LEFT
            +			 *  @type {GainNode}
            +			 */
            +			this.effectReturnL = this._merge.left;
            +
            +			/**
            +			 *  the effect return RIGHT
            +			 *  @type {GainNode}
            +			 */
            +			this.effectReturnR = this._merge.right;
            +
            +			//connections
            +			this.input.connect(this._split);
            +			//dry wet connections
            +			this.input.connect(this.dryWet, 0, 0);
            +			this._merge.connect(this.dryWet, 0, 1);
            +			this.dryWet.connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.StereoEffect, Tone.Effect);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.StereoEffect} `this`
            +		 */
            +		Tone.StereoEffect.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.dryWet.dispose();
            +			this.dryWet = null;
            +			this._split.dispose();
            +			this._split = null;
            +			this._merge.dispose();
            +			this._merge = null;
            +			this.effectSendL = null;
            +			this.effectSendR = null;
            +			this.effectReturnL = null;
            +			this.effectReturnR = null;
            +			this.wet = null;
            +			return this;
            +		};
            +
            +		return Tone.StereoEffect;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +		
            +		/**
            +		 * 	@class  Feedback Effect (a sound loop between an audio source and its own output)
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Effect}
            +		 *  @param {number|Object} [initialFeedback=0.125] the initial feedback value
            +		 */
            +		Tone.FeedbackEffect = function(){
            +
            +			var options = this.optionsObject(arguments, ["feedback"]);
            +			options = this.defaultArg(options, Tone.FeedbackEffect.defaults);
            +
            +			Tone.Effect.call(this, options);
            +
            +			/**
            +			 *  controls the amount of feedback
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.feedback = new Tone.Signal(options.feedback, Tone.Signal.Units.Normal);
            +			
            +			/**
            +			 *  the gain which controls the feedback
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._feedbackGain = this.context.createGain();
            +
            +			//the feedback loop
            +			this.effectReturn.chain(this._feedbackGain, this.effectSend);
            +			this.feedback.connect(this._feedbackGain.gain);
            +		};
            +
            +		Tone.extend(Tone.FeedbackEffect, Tone.Effect);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.FeedbackEffect.defaults = {
            +			"feedback" : 0.125
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.FeedbackEffect} `this`
            +		 */
            +		Tone.FeedbackEffect.prototype.dispose = function(){
            +			Tone.Effect.prototype.dispose.call(this);
            +			this.feedback.dispose();
            +			this.feedback = null;
            +			this._feedbackGain.disconnect();
            +			this._feedbackGain = null;
            +			return this;
            +		};
            +
            +		return Tone.FeedbackEffect;
            +	});
            +
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Just like a stereo feedback effect, but the feedback is routed from left to right
            +		 *         and right to left instead of on the same channel.
            +		 *
            +		 *	@constructor
            +		 *	@extends {Tone.FeedbackEffect}
            +		 */
            +		Tone.StereoXFeedbackEffect = function(){
            +
            +			var options = this.optionsObject(arguments, ["feedback"], Tone.FeedbackEffect.defaults);
            +			Tone.StereoEffect.call(this, options);
            +
            +			/**
            +			 *  controls the amount of feedback
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.feedback = new Tone.Signal(options.feedback);
            +
            +			/**
            +			 *  the left side feeback
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._feedbackLR = this.context.createGain();
            +
            +			/**
            +			 *  the right side feeback
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._feedbackRL = this.context.createGain();
            +
            +			//connect it up
            +			this.effectReturnL.chain(this._feedbackLR, this.effectSendR);
            +			this.effectReturnR.chain(this._feedbackRL, this.effectSendL);
            +			this.feedback.fan(this._feedbackLR.gain, this._feedbackRL.gain);
            +		};
            +
            +		Tone.extend(Tone.StereoXFeedbackEffect, Tone.FeedbackEffect);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.StereoXFeedbackEffect} `this`
            +		 */
            +		Tone.StereoXFeedbackEffect.prototype.dispose = function(){
            +			Tone.StereoEffect.prototype.dispose.call(this);
            +			this.feedback.dispose();
            +			this.feedback = null;
            +			this._feedbackLR.disconnect();
            +			this._feedbackLR = null;
            +			this._feedbackRL.disconnect();
            +			this._feedbackRL = null;
            +			return this;
            +		};
            +
            +		return Tone.StereoXFeedbackEffect;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A Chorus effect with feedback. inspiration from https://github.com/Dinahmoe/tuna/blob/master/tuna.js
            +		 *
            +		 *	@constructor
            +		 *	@extends {Tone.StereoXFeedbackEffect}
            +		 *	@param {number|Object} [frequency=2] the frequency of the effect
            +		 *	@param {number} [delayTime=3.5] the delay of the chorus effect in ms
            +		 *	@param {number} [depth=0.7] the depth of the chorus
            +		 */
            +		Tone.Chorus = function(){
            +
            +			var options = this.optionsObject(arguments, ["frequency", "delayTime", "depth"], Tone.Chorus.defaults);
            +			Tone.StereoXFeedbackEffect.call(this, options);
            +
            +			/**
            +			 *  the depth of the chorus
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._depth = options.depth;
            +
            +			/**
            +			 *  the delayTime
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._delayTime = options.delayTime / 1000;
            +
            +			/**
            +			 *  the lfo which controls the delayTime
            +			 *  @type {Tone.LFO}
            +			 *  @private
            +			 */
            +			this._lfoL = new Tone.LFO(options.rate, 0, 1);
            +
            +			/**
            +			 *  another LFO for the right side with a 180 degree phase diff
            +			 *  @type {Tone.LFO}
            +			 *  @private
            +			 */
            +			this._lfoR = new Tone.LFO(options.rate, 0, 1);
            +			this._lfoR.phase = 180;
            +
            +			/**
            +			 *  delay for left
            +			 *  @type {DelayNode}
            +			 *  @private
            +			 */
            +			this._delayNodeL = this.context.createDelay();
            +
            +			/**
            +			 *  delay for right
            +			 *  @type {DelayNode}
            +			 *  @private
            +			 */
            +			this._delayNodeR = this.context.createDelay();
            +
            +			/**
            +			 * The frequency the chorus will modulate at. 
            +			 * @type {Tone.Signal}
            +			 */
            +			this.frequency = this._lfoL.frequency;
            +
            +			//connections
            +			this.connectSeries(this.effectSendL, this._delayNodeL, this.effectReturnL);
            +			this.connectSeries(this.effectSendR, this._delayNodeR, this.effectReturnR);
            +			//and pass through
            +			this.effectSendL.connect(this.effectReturnL);
            +			this.effectSendR.connect(this.effectReturnR);
            +			//lfo setup
            +			this._lfoL.connect(this._delayNodeL.delayTime);
            +			this._lfoR.connect(this._delayNodeR.delayTime);
            +			//start the lfo
            +			this._lfoL.start();
            +			this._lfoR.start();
            +			//have one LFO frequency control the other
            +			this._lfoL.frequency.connect(this._lfoR.frequency);
            +			//set the initial values
            +			this.depth = this._depth;
            +			this.frequency.value = options.frequency;
            +			this.type = options.type;
            +		};
            +
            +		Tone.extend(Tone.Chorus, Tone.StereoXFeedbackEffect);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.Chorus.defaults = {
            +			"frequency" : 1.5, 
            +			"delayTime" : 3.5,
            +			"depth" : 0.7,
            +			"feedback" : 0.1,
            +			"type" : "sine"
            +		};
            +
            +		/**
            +		 * The depth of the effect. 
            +		 * @memberOf Tone.Chorus#
            +		 * @type {number}
            +		 * @name depth
            +		 */
            +		Object.defineProperty(Tone.Chorus.prototype, "depth", {
            +			get : function(){
            +				return this._depth;
            +			},
            +			set : function(depth){
            +				this._depth = depth;
            +				var deviation = this._delayTime * depth;
            +				this._lfoL.min = this._delayTime - deviation;
            +				this._lfoL.max = this._delayTime + deviation;
            +				this._lfoR.min = this._delayTime - deviation;
            +				this._lfoR.max = this._delayTime + deviation;
            +			}
            +		});
            +
            +		/**
            +		 * The delayTime in milliseconds
            +		 * @memberOf Tone.Chorus#
            +		 * @type {number}
            +		 * @name delayTime
            +		 */
            +		Object.defineProperty(Tone.Chorus.prototype, "delayTime", {
            +			get : function(){
            +				return this._delayTime * 1000;
            +			},
            +			set : function(delayTime){
            +				this._delayTime = delayTime / 1000;
            +				this.depth = this._depth;
            +			}
            +		});
            +
            +		/**
            +		 * The lfo type for the chorus. 
            +		 * @memberOf Tone.Chorus#
            +		 * @type {string}
            +		 * @name type
            +		 */
            +		Object.defineProperty(Tone.Chorus.prototype, "type", {
            +			get : function(){
            +				return this._lfoL.type;
            +			},
            +			set : function(type){
            +				this._lfoL.type = type;
            +				this._lfoR.type = type;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Chorus} `this`
            +		 */
            +		Tone.Chorus.prototype.dispose = function(){
            +			Tone.StereoXFeedbackEffect.prototype.dispose.call(this);
            +			this._lfoL.dispose();
            +			this._lfoL = null;
            +			this._lfoR.dispose();
            +			this._lfoR = null;
            +			this._delayNodeL.disconnect();
            +			this._delayNodeL = null;
            +			this._delayNodeR.disconnect();
            +			this._delayNodeR = null;
            +			this.frequency = null;
            +			return this;
            +		};
            +
            +		return Tone.Chorus;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Convolver wrapper for reverb and emulation.
            +		 *          NB: currently, this class only supports 1 buffer member.
            +		 *          Future iterations will include a this.buffers collection for multi buffer mode.
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.Effect}
            +		 *  @param {string|Object|AudioBuffer=} url
            +		 *  @param {function=} callback function
            +		 */
            +		Tone.Convolver = function(url){
            +
            +			Tone.Effect.apply(this, arguments);
            +
            +		  	/**
            +			 *  convolver node
            +			 *  @type {ConvolverNode}
            +			 *  @private
            +			 */
            +			this._convolver = this.context.createConvolver();
            +
            +			/**
            +			 *  the convolution buffer
            +			 *  @type {Tone.Buffer}
            +			 *  @private
            +			 */
            +			this._buffer = new Tone.Buffer(url, this.setBuffer.bind(this));
            +
            +			this.connectEffect(this._convolver);
            +		};
            +
            +		Tone.extend(Tone.Convolver, Tone.Effect);
            +
            +		/**
            +		 *  Load the impulse response url as an audio buffer.
            +		 *  Decodes the audio asynchronously and invokes
            +		 *  the callback once the audio buffer loads.
            +		 *  @param {string} url the url of the buffer to load.
            +		 *                      filetype support depends on the
            +		 *                      browser.
            +		 *  @param  {function(Tone.Convolver)=} callback
            +		 *  @returns {Tone.Convolver} `this`
            +		 */
            +		Tone.Convolver.prototype.load = function(url, callback){
            +			var self = this;
            +			this._buffer.load(url, function(buff){
            +				self.setBuffer(buff);
            +				if (callback){
            +					callback(this);
            +				}
            +			});
            +			return this;
            +		};
            +
            +		/**
            +		 *  set the buffer
            +		 *  @param {AudioBuffer} buffer the impulse response
            +		 *  @returns {Tone.Convolver} `this`
            +		 */
            +		Tone.Convolver.prototype.setBuffer = function(buffer){
            +			this._buffer.set(buffer);
            +			this._convolver.buffer = this._buffer.get();
            +			return this;
            +		};
            +
            +		/**
            +		 *  dispose and disconnect
            +		 *  @returns {Tone.Convolver} `this`
            +		 */
            +		Tone.Convolver.prototype.dispose = function(){
            +			Tone.Effect.prototype.dispose.call(this);
            +			this._convolver.disconnect();
            +			this._convolver = null;
            +			this._buffer.dispose();
            +			this._buffer = null;
            +			return this;
            +		}; 
            +
            +		return Tone.Convolver;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A simple distortion effect using the waveshaper node
            +		 *         algorithm from http://stackoverflow.com/a/22313408
            +		 *
            +		 *  @extends {Tone.Effect}
            +		 *  @constructor
            +		 *  @param {number} distortion the amount of distortion (nominal range of 0-1)
            +		 */
            +		Tone.Distortion = function(){
            +
            +			var options = this.optionsObject(arguments, ["distortion"], Tone.Distortion.defaults);
            +
            +			Tone.Effect.call(this);
            +
            +			/**
            +			 *  @type {Tone.WaveShaper}
            +			 *  @private
            +			 */
            +			this._shaper = new Tone.WaveShaper(4096);
            +
            +			/**
            +			 * holds the distortion amount
            +			 * @type {number}
            +			 * @private
            +			 */
            +			this._distortion = options.distortion;
            +
            +			this.connectEffect(this._shaper);
            +			this.distortion = options.distortion;
            +			this.oversample = options.oversample;
            +		};
            +
            +		Tone.extend(Tone.Distortion, Tone.Effect);
            +
            +		/**
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.Distortion.defaults = {
            +			"distortion" : 0.4,
            +			"oversample" : "none"
            +		};
            +
            +		/**
            +		 * The amount of distortion. Range between 0-1. 
            +		 * @memberOf Tone.Distortion#
            +		 * @type {number}
            +		 * @name distortion
            +		 */
            +		Object.defineProperty(Tone.Distortion.prototype, "distortion", {
            +			get : function(){
            +				return this._distortion;
            +			},
            +			set : function(amount){
            +				this._distortion = amount;
            +				var k = amount * 100;
            +				var deg = Math.PI / 180;
            +				this._shaper.setMap(function(x){
            +					if (Math.abs(x) < 0.001){
            +						//should output 0 when input is 0
            +						return 0;
            +					} else {
            +						return ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );
            +					}
            +				});
            +			} 
            +		});
            +
            +		/**
            +		 * The oversampling of the effect. Can either be "none", "2x" or "4x".
            +		 * @memberOf Tone.Distortion#
            +		 * @type {string}
            +		 * @name oversample
            +		 */
            +		Object.defineProperty(Tone.Distortion.prototype, "oversample", {
            +			get : function(){
            +				return this._shaper.oversample;
            +			},
            +			set : function(oversampling){
            +				this._shaper.oversample = oversampling;
            +			} 
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Distortion} `this`
            +		 */
            +		Tone.Distortion.prototype.dispose = function(){
            +			Tone.Effect.prototype.dispose.call(this);
            +			this._shaper.dispose();
            +			this._shaper = null;
            +			return this;
            +		};
            +
            +		return Tone.Distortion;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +		
            +		/**
            +		 *  @class  A feedback delay
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.FeedbackEffect}
            +		 *  @param {Tone.Time|Object} [delayTime=0.25]
            +		 */
            +		Tone.FeedbackDelay = function(){
            +			
            +			var options = this.optionsObject(arguments, ["delayTime"], Tone.FeedbackDelay.defaults);
            +			Tone.FeedbackEffect.call(this, options);
            +
            +			/**
            +			 *  Tone.Signal to control the delay amount
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.delayTime = new Tone.Signal(options.delayTime, Tone.Signal.Units.Time);
            +
            +			/**
            +			 *  the delay node
            +			 *  @type {DelayNode}
            +			 *  @private
            +			 */
            +			this._delayNode = this.context.createDelay(4);
            +
            +			// connect it up
            +			this.connectEffect(this._delayNode);
            +			this.delayTime.connect(this._delayNode.delayTime);
            +		};
            +
            +		Tone.extend(Tone.FeedbackDelay, Tone.FeedbackEffect);
            +
            +		/**
            +		 *  [defaults description]
            +		 *  @type {Object}
            +		 */
            +		Tone.FeedbackDelay.defaults = {
            +			"delayTime" : 0.25
            +		};
            +		
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.FeedbackDelay} `this`
            +		 */
            +		Tone.FeedbackDelay.prototype.dispose = function(){
            +			Tone.FeedbackEffect.prototype.dispose.call(this);
            +			this.delayTime.dispose();
            +			this._delayNode.disconnect();
            +			this._delayNode = null;
            +			this.delayTime = null;
            +			return this;
            +		};
            +
            +		return Tone.FeedbackDelay;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  an array of comb filter delay values from Freeverb implementation
            +		 *  @static
            +		 *  @private
            +		 *  @type {Array}
            +		 */
            +		var combFilterTunings = [1557 / 44100, 1617 / 44100, 1491 / 44100, 1422 / 44100, 1277 / 44100, 1356 / 44100, 1188 / 44100, 1116 / 44100];
            +
            +		/**
            +		 *  an array of allpass filter frequency values from Freeverb implementation
            +		 *  @private
            +		 *  @static
            +		 *  @type {Array}
            +		 */
            +		var allpassFilterFrequencies = [225, 556, 441, 341];
            +
            +		/**
            +		 *  @class Reverb based on the Freeverb
            +		 *
            +		 *  @extends {Tone.Effect}
            +		 *  @constructor
            +		 *  @param {number} [roomSize=0.7] correlated to the decay time. 
            +		 *                                 value between (0,1)
            +		 *  @param {number} [dampening=0.5] filtering which is applied to the reverb. 
            +		 *                                  value between [0,1]
            +		 */
            +		Tone.Freeverb = function(){
            +
            +			var options = this.optionsObject(arguments, ["roomSize", "dampening"], Tone.Freeverb.defaults);
            +			Tone.StereoEffect.call(this, options);
            +
            +			/**
            +			 *  the roomSize value between (0,1)
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.roomSize = new Tone.Signal(options.roomSize);
            +
            +			/**
            +			 *  the amount of dampening
            +			 *  value between [0,1]
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.dampening = new Tone.Signal(options.dampening);
            +
            +			/**
            +			 *  scale the dampening
            +			 *  @type {Tone.ScaleExp}
            +			 *  @private
            +			 */
            +			this._dampeningScale = new Tone.ScaleExp(100, 8000, 0.5);
            +
            +			/**
            +			 *  the comb filters
            +			 *  @type {Array.<Tone.LowpassCombFilter>}
            +			 *  @private
            +			 */
            +			this._combFilters = [];
            +
            +			/**
            +			 *  the allpass filters on the left
            +			 *  @type {Array.<BiqaudFilterNode>}
            +			 *  @private
            +			 */
            +			this._allpassFiltersL = [];
            +
            +			/**
            +			 *  the allpass filters on the right
            +			 *  @type {Array.<BiqaudFilterNode>}
            +			 *  @private
            +			 */
            +			this._allpassFiltersR = [];
            +
            +			//make the allpass filters on teh right
            +			for (var l = 0; l < allpassFilterFrequencies.length; l++){
            +				var allpassL = this.context.createBiquadFilter();
            +				allpassL.type = "allpass";
            +				allpassL.frequency.value = allpassFilterFrequencies[l];
            +				this._allpassFiltersL.push(allpassL);
            +			}
            +
            +			//make the allpass filters on the left
            +			for (var r = 0; r < allpassFilterFrequencies.length; r++){
            +				var allpassR = this.context.createBiquadFilter();
            +				allpassR.type = "allpass";
            +				allpassR.frequency.value = allpassFilterFrequencies[r];
            +				this._allpassFiltersR.push(allpassR);
            +			}
            +
            +			//make the comb filters
            +			for (var c = 0; c < combFilterTunings.length; c++){
            +				var lfpf = new Tone.LowpassCombFilter(combFilterTunings[c]);
            +				if (c < combFilterTunings.length / 2){
            +					this.effectSendL.chain(lfpf, this._allpassFiltersL[0]);
            +				} else {
            +					this.effectSendR.chain(lfpf, this._allpassFiltersR[0]);
            +				}
            +				this.roomSize.connect(lfpf.resonance);
            +				this._dampeningScale.connect(lfpf.dampening);
            +				this._combFilters.push(lfpf);
            +			}
            +
            +			//chain the allpass filters togetehr
            +			this.connectSeries.apply(this, this._allpassFiltersL);
            +			this.connectSeries.apply(this, this._allpassFiltersR);
            +			this._allpassFiltersL[this._allpassFiltersL.length - 1].connect(this.effectReturnL);
            +			this._allpassFiltersR[this._allpassFiltersR.length - 1].connect(this.effectReturnR);
            +			this.dampening.connect(this._dampeningScale);
            +		};
            +
            +		Tone.extend(Tone.Freeverb, Tone.StereoEffect);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.Freeverb.defaults = {
            +			"roomSize" : 0.7, 
            +			"dampening" : 0.5
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Freeverb} `this`
            +		 */
            +		Tone.Freeverb.prototype.dispose = function(){
            +			Tone.StereoEffect.prototype.dispose.call(this);
            +			for (var al = 0; al < this._allpassFiltersL.length; al++) {
            +				this._allpassFiltersL[al].disconnect();
            +				this._allpassFiltersL[al] = null;
            +			}
            +			this._allpassFiltersL = null;
            +			for (var ar = 0; ar < this._allpassFiltersR.length; ar++) {
            +				this._allpassFiltersR[ar].disconnect();
            +				this._allpassFiltersR[ar] = null;
            +			}
            +			this._allpassFiltersR = null;
            +			for (var cf = 0; cf < this._combFilters.length; cf++) {
            +				this._combFilters[cf].dispose();
            +				this._combFilters[cf] = null;
            +			}
            +			this._combFilters = null;
            +			this.roomSize.dispose();
            +			this.dampening.dispose();
            +			this._dampeningScale.dispose();
            +			this.roomSize = null;
            +			this.dampening = null;
            +			this._dampeningScale = null;
            +			return this;
            +		};
            +
            +		return Tone.Freeverb;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  an array of the comb filter delay time values
            +		 *  @private
            +		 *  @static
            +		 *  @type {Array}
            +		 */
            +		var combFilterDelayTimes = [1687 / 25000, 1601 / 25000, 2053 / 25000, 2251 / 25000];
            +
            +		/**
            +		 *  the resonances of each of the comb filters
            +		 *  @private
            +		 *  @static
            +		 *  @type {Array}
            +		 */
            +		var combFilterResonances = [0.773, 0.802, 0.753, 0.733];
            +
            +		/**
            +		 *  the allpass filter frequencies
            +		 *  @private
            +		 *  @static
            +		 *  @type {Array}
            +		 */
            +		var allpassFilterFreqs = [347, 113, 37];
            +
            +		/**
            +		 *  @class a simple Schroeder Reverberators tuned by John Chowning in 1970
            +		 *         made up of 3 allpass filters and 4 feedback comb filters. 
            +		 *         https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html
            +		 *
            +		 *  @extends {Tone.Effect}
            +		 *  @constructor
            +		 *  @param {number} roomSize coorelates to the decay time
            +		 */
            +		Tone.JCReverb = function(){
            +
            +			var options = this.optionsObject(arguments, ["roomSize"], Tone.JCReverb.defaults);
            +			Tone.StereoEffect.call(this, options);
            +
            +			/**
            +			 *  room size control values between [0,1]
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.roomSize = new Tone.Signal(options.roomSize, Tone.Signal.Units.Normal);
            +
            +			/**
            +			 *  scale the room size
            +			 *  @type {Tone.Scale}
            +			 *  @private
            +			 */
            +			this._scaleRoomSize = new Tone.Scale(-0.733, 0.197);
            +
            +			/**
            +			 *  a series of allpass filters
            +			 *  @type {Array.<BiquadFilterNode>}
            +			 *  @private
            +			 */
            +			this._allpassFilters = [];
            +
            +			/**
            +			 *  parallel feedback comb filters
            +			 *  @type {Array.<Tone.FeedbackCombFilter>}
            +			 *  @private
            +			 */
            +			this._feedbackCombFilters = [];
            +
            +			//make the allpass filters
            +			for (var af = 0; af < allpassFilterFreqs.length; af++) {
            +				var allpass = this.context.createBiquadFilter();
            +				allpass.type = "allpass";
            +				allpass.frequency.value = allpassFilterFreqs[af];
            +				this._allpassFilters.push(allpass);
            +			}
            +
            +			//and the comb filters
            +			for (var cf = 0; cf < combFilterDelayTimes.length; cf++) {
            +				var fbcf = new Tone.FeedbackCombFilter(combFilterDelayTimes[cf], 0.1);
            +				this._scaleRoomSize.connect(fbcf.resonance);
            +				fbcf.resonance.value = combFilterResonances[cf];
            +				this._allpassFilters[this._allpassFilters.length - 1].connect(fbcf);
            +				if (cf < combFilterDelayTimes.length / 2){
            +					fbcf.connect(this.effectReturnL);
            +				} else {
            +					fbcf.connect(this.effectReturnR);
            +				}
            +				this._feedbackCombFilters.push(fbcf);
            +			}
            +
            +			//chain the allpass filters together
            +			this.roomSize.connect(this._scaleRoomSize);
            +			this.connectSeries.apply(this, this._allpassFilters);
            +			this.effectSendL.connect(this._allpassFilters[0]);
            +			this.effectSendR.connect(this._allpassFilters[0]);
            +		};
            +
            +		Tone.extend(Tone.JCReverb, Tone.StereoEffect);
            +
            +		/**
            +		 *  the default values
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.JCReverb.defaults = {
            +			"roomSize" : 0.5
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.JCReverb} `this`
            +		 */
            +		Tone.JCReverb.prototype.dispose = function(){
            +			Tone.StereoEffect.prototype.dispose.call(this);
            +			for (var apf = 0; apf < this._allpassFilters.length; apf++) {
            +				this._allpassFilters[apf].disconnect();
            +				this._allpassFilters[apf] = null;
            +			}
            +			this._allpassFilters = null;
            +			for (var fbcf = 0; fbcf < this._feedbackCombFilters.length; fbcf++) {
            +				this._feedbackCombFilters[fbcf].dispose();
            +				this._feedbackCombFilters[fbcf] = null;
            +			}
            +			this._feedbackCombFilters = null;
            +			this.roomSize.dispose();
            +			this.roomSize = null;
            +			this._scaleRoomSize.dispose();
            +			this._scaleRoomSize = null;
            +			return this;
            +		};
            +
            +		return Tone.JCReverb;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Applies a Mid/Side seperation and recombination
            +		 *         http://musicdsp.org/showArchiveComment.php?ArchiveID=173
            +		 *         http://www.kvraudio.com/forum/viewtopic.php?t=212587
            +		 *         M = (L+R)/sqrt(2);   // obtain mid-signal from left and right
            +		 *         S = (L-R)/sqrt(2);   // obtain side-signal from left and righ
            +		 *         // amplify mid and side signal seperately:
            +		 *         M/S send/return
            +		 *         L = (M+S)/sqrt(2);   // obtain left signal from mid and side
            +		 *         R = (M-S)/sqrt(2);   // obtain right signal from mid and side
            +		 *
            +		 *  @extends {Tone.StereoEffect}
            +		 *  @constructor
            +		 */
            +		Tone.MidSideEffect = function(){
            +			Tone.StereoEffect.call(this);
            +
            +			/**
            +			 *  a constant signal equal to 1 / sqrt(2)
            +			 *  @type {Tone.Signal}
            +			 *  @private
            +			 */
            +			this._sqrtTwo = new Tone.Signal(1 / Math.sqrt(2));
            +
            +			/**
            +			 *  the mid send.
            +			 *  connect to mid processing
            +			 *  @type {Tone.Expr}
            +			 */
            +			this.midSend = new Tone.Expr("($0 + $1) * $2");
            +
            +			/**
            +			 *  the side send.
            +			 *  connect to side processing
            +			 *  @type {Tone.Expr}
            +			 */
            +			this.sideSend = new Tone.Expr("($0 - $1) * $2");
            +
            +			/**
            +			 *  recombine the mid/side into Left
            +			 *  @type {Tone.Expr}
            +			 *  @private
            +			 */
            +			this._left = new Tone.Expr("($0 + $1) * $2");
            +
            +			/**
            +			 *  recombine the mid/side into Right
            +			 *  @type {Tone.Expr}
            +			 *  @private
            +			 */
            +			this._right = new Tone.Expr("($0 - $1) * $2");
            +
            +			/**
            +			 *  the mid return connection
            +			 *  @type {GainNode}
            +			 */
            +			this.midReturn = this.context.createGain();
            +
            +			/**
            +			 *  the side return connection
            +			 *  @type {GainNode}
            +			 */
            +			this.sideReturn = this.context.createGain();
            +
            +			//connections
            +			this.effectSendL.connect(this.midSend, 0, 0);
            +			this.effectSendR.connect(this.midSend, 0, 1);
            +			this.effectSendL.connect(this.sideSend, 0, 0);
            +			this.effectSendR.connect(this.sideSend, 0, 1);
            +			this._left.connect(this.effectReturnL);
            +			this._right.connect(this.effectReturnR);
            +			this.midReturn.connect(this._left, 0, 0);
            +			this.sideReturn.connect(this._left, 0, 1);
            +			this.midReturn.connect(this._right, 0, 0);
            +			this.sideReturn.connect(this._right, 0, 1);
            +			this._sqrtTwo.connect(this.midSend, 0, 2);
            +			this._sqrtTwo.connect(this.sideSend, 0, 2);
            +			this._sqrtTwo.connect(this._left, 0, 2);
            +			this._sqrtTwo.connect(this._right, 0, 2);
            +		};
            +
            +		Tone.extend(Tone.MidSideEffect, Tone.StereoEffect);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.MidSideEffect} `this`
            +		 */
            +		Tone.MidSideEffect.prototype.dispose = function(){
            +			Tone.StereoEffect.prototype.dispose.call(this);
            +			this._sqrtTwo.dispose();
            +			this._sqrtTwo = null;
            +			this.midSend.dispose();
            +			this.midSend = null;
            +			this.sideSend.dispose();
            +			this.sideSend = null;
            +			this._left.dispose();
            +			this._left = null;
            +			this._right.dispose();
            +			this._right = null;
            +			this.midReturn.disconnect();
            +			this.midReturn = null;
            +			this.sideReturn.disconnect();
            +			this.sideReturn = null;
            +			return this;
            +		};
            +
            +		return Tone.MidSideEffect;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A Phaser effect. inspiration from https://github.com/Dinahmoe/tuna/
            +		 *
            +		 *	@extends {Tone.StereoEffect}
            +		 *	@constructor
            +		 *	@param {number|Object} [frequency=0.5] the speed of the phasing
            +		 *	@param {number} [depth=10] the depth of the effect
            +		 *	@param {number} [baseFrequency=400] the base frequency of the filters
            +		 */
            +		Tone.Phaser = function(){
            +
            +			//set the defaults
            +			var options = this.optionsObject(arguments, ["frequency", "depth", "baseFrequency"], Tone.Phaser.defaults);
            +			Tone.StereoEffect.call(this, options);
            +
            +			/**
            +			 *  the lfo which controls the frequency on the left side
            +			 *  @type {Tone.LFO}
            +			 *  @private
            +			 */
            +			this._lfoL = new Tone.LFO(options.frequency, 0, 1);
            +
            +			/**
            +			 *  the lfo which controls the frequency on the right side
            +			 *  @type {Tone.LFO}
            +			 *  @private
            +			 */
            +			this._lfoR = new Tone.LFO(options.frequency, 0, 1);
            +			this._lfoR.phase = 180;
            +
            +			/**
            +			 *  the base modulation frequency
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._baseFrequency = options.baseFrequency;
            +
            +			/**
            +			 *  the depth of the phasing
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._depth = options.depth;
            +			
            +			/**
            +			 *  the array of filters for the left side
            +			 *  @type {Array.<Tone.Filter>}
            +			 *  @private
            +			 */
            +			this._filtersL = this._makeFilters(options.stages, this._lfoL, options.Q);
            +
            +			/**
            +			 *  the array of filters for the left side
            +			 *  @type {Array.<Tone.Filter>}
            +			 *  @private
            +			 */
            +			this._filtersR = this._makeFilters(options.stages, this._lfoR, options.Q);
            +
            +			/**
            +			 * the frequency of the effect
            +			 * @type {Tone.Signal}
            +			 */
            +			this.frequency = this._lfoL.frequency;
            +			this.frequency.value = options.frequency;
            +			
            +			//connect them up
            +			this.effectSendL.connect(this._filtersL[0]);
            +			this.effectSendR.connect(this._filtersR[0]);
            +			this._filtersL[options.stages - 1].connect(this.effectReturnL);
            +			this._filtersR[options.stages - 1].connect(this.effectReturnR);
            +			this.effectSendL.connect(this.effectReturnL);
            +			this.effectSendR.connect(this.effectReturnR);
            +			//control the frequency with one LFO
            +			this._lfoL.frequency.connect(this._lfoR.frequency);
            +			//set the options
            +			this.baseFrequency = options.baseFrequency;
            +			this.depth = options.depth;
            +			//start the lfo
            +			this._lfoL.start();
            +			this._lfoR.start();
            +		};
            +
            +		Tone.extend(Tone.Phaser, Tone.StereoEffect);
            +
            +		/**
            +		 *  defaults
            +		 *  @static
            +		 *  @type {object}
            +		 */
            +		Tone.Phaser.defaults = {
            +			"frequency" : 0.5,
            +			"depth" : 10,
            +			"stages" : 4,
            +			"Q" : 100,
            +			"baseFrequency" : 400,
            +		};
            +
            +		/**
            +		 *  @param {number} stages
            +		 *  @returns {Array} the number of filters all connected together
            +		 *  @private
            +		 */
            +		Tone.Phaser.prototype._makeFilters = function(stages, connectToFreq, Q){
            +			var filters = new Array(stages);
            +			//make all the filters
            +			for (var i = 0; i < stages; i++){
            +				var filter = this.context.createBiquadFilter();
            +				filter.type = "allpass";
            +				filter.Q.value = Q;
            +				connectToFreq.connect(filter.frequency);
            +				filters[i] = filter;
            +			}
            +			this.connectSeries.apply(this, filters);
            +			return filters;
            +		};
            +
            +		/**
            +		 * The depth of the effect. 
            +		 * @memberOf Tone.Phaser#
            +		 * @type {number}
            +		 * @name depth
            +		 */
            +		Object.defineProperty(Tone.Phaser.prototype, "depth", {
            +			get : function(){
            +				return this._depth;
            +			},
            +			set : function(depth){
            +				this._depth = depth;
            +				var max = this._baseFrequency + this._baseFrequency * depth;
            +				this._lfoL.max = max;
            +				this._lfoR.max = max;
            +			}
            +		});
            +
            +		/**
            +		 * The the base frequency of the filters. 
            +		 * @memberOf Tone.Phaser#
            +		 * @type {string}
            +		 * @name baseFrequency
            +		 */
            +		Object.defineProperty(Tone.Phaser.prototype, "baseFrequency", {
            +			get : function(){
            +				return this._baseFrequency;
            +			},
            +			set : function(freq){
            +				this._baseFrequency = freq;	
            +				this._lfoL.min = freq;
            +				this._lfoR.min = freq;
            +				this.depth = this._depth;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Phaser} `this`
            +		 */
            +		Tone.Phaser.prototype.dispose = function(){
            +			Tone.StereoEffect.prototype.dispose.call(this);
            +			this._lfoL.dispose();
            +			this._lfoL = null;
            +			this._lfoR.dispose();
            +			this._lfoR = null;
            +			for (var i = 0; i < this._filtersL.length; i++){
            +				this._filtersL[i].disconnect();
            +				this._filtersL[i] = null;
            +			}
            +			this._filtersL = null;
            +			for (var j = 0; j < this._filtersR.length; j++){
            +				this._filtersR[j].disconnect();
            +				this._filtersR[j] = null;
            +			}
            +			this._filtersR = null;
            +			this.frequency = null;
            +			return this;
            +		};
            +
            +		return Tone.Phaser;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  PingPongDelay is a dual delay effect where the echo is heard
            +		 *          first in one channel and next in the opposite channel
            +		 *
            +		 * 	@constructor
            +		 * 	@extends {Tone.StereoXFeedbackEffect}
            +		 *  @param {Tone.Time|Object} [delayTime=0.25] is the interval between consecutive echos
            +		 */
            +		Tone.PingPongDelay = function(){
            +			
            +			var options = this.optionsObject(arguments, ["delayTime"], Tone.PingPongDelay.defaults);
            +			Tone.StereoXFeedbackEffect.call(this, options);
            +
            +			/**
            +			 *  the delay node on the left side
            +			 *  @type {DelayNode}
            +			 *  @private
            +			 */
            +			this._leftDelay = this.context.createDelay(options.maxDelayTime);
            +
            +			/**
            +			 *  the delay node on the right side
            +			 *  @type {DelayNode}
            +			 *  @private
            +			 */
            +			this._rightDelay = this.context.createDelay(options.maxDelayTime);
            +
            +			/**
            +			 *  the predelay on the left side
            +			 *  @private
            +			 *  @type {DelayNode}
            +			 */
            +			this._leftPreDelay = this.context.createDelay(options.maxDelayTime);
            +
            +			/**
            +			 *  the delay time signal
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.delayTime = new Tone.Signal(options.delayTime, Tone.Signal.Units.Time);
            +
            +			//connect it up
            +			this.effectSendL.chain(this._leftPreDelay, this._leftDelay, this.effectReturnL);
            +			this.effectSendR.chain(this._rightDelay, this.effectReturnR);
            +			this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._leftPreDelay.delayTime);
            +			//rearranged the feedback to be after the leftPreDelay
            +			this._feedbackRL.disconnect();
            +			this._feedbackRL.connect(this._leftDelay);
            +		};
            +
            +		Tone.extend(Tone.PingPongDelay, Tone.StereoXFeedbackEffect);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.PingPongDelay.defaults = {
            +			"delayTime" : 0.25,
            +			"maxDelayTime" : 1
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.PingPongDelay} `this`
            +		 */
            +		Tone.PingPongDelay.prototype.dispose = function(){
            +			Tone.StereoXFeedbackEffect.prototype.dispose.call(this);
            +			this._leftDelay.disconnect();
            +			this._rightDelay.disconnect();
            +			this._leftPreDelay.disconnect();
            +			this.delayTime.dispose();
            +			this._leftDelay = null;
            +			this._rightDelay = null;
            +			this._leftPreDelay = null;
            +			this.delayTime = null;
            +			return this;
            +		};
            +
            +		return Tone.PingPongDelay;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A stereo feedback effect where the feedback is on the same channel
            +		 *
            +		 *	@constructor
            +		 *	@extends {Tone.FeedbackEffect}
            +		 */
            +		Tone.StereoFeedbackEffect = function(){
            +
            +			var options = this.optionsObject(arguments, ["feedback"], Tone.FeedbackEffect.defaults);
            +			Tone.StereoEffect.call(this, options);
            +
            +			/**
            +			 *  controls the amount of feedback
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.feedback = new Tone.Signal(options.feedback);
            +
            +			/**
            +			 *  the left side feeback
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._feedbackL = this.context.createGain();
            +
            +			/**
            +			 *  the right side feeback
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._feedbackR = this.context.createGain();
            +
            +			//connect it up
            +			this.effectReturnL.chain(this._feedbackL, this.effectSendL);
            +			this.effectReturnR.chain(this._feedbackR, this.effectSendR);
            +			this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain);
            +		};
            +
            +		Tone.extend(Tone.StereoFeedbackEffect, Tone.FeedbackEffect);
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.StereoFeedbackEffect} `this`
            +		 */
            +		Tone.StereoFeedbackEffect.prototype.dispose = function(){
            +			Tone.StereoEffect.prototype.dispose.call(this);
            +			this.feedback.dispose();
            +			this.feedback = null;
            +			this._feedbackL.disconnect();
            +			this._feedbackL = null;
            +			this._feedbackR.disconnect();
            +			this._feedbackR = null;
            +			return this;
            +		};
            +
            +		return Tone.StereoFeedbackEffect;
            +	});
            +	toneModule( 
            +		function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Applies a width factor (0-1) to the mid/side seperation. 
            +		 *         0 is all mid and 1 is all side. 
            +		 *         http://musicdsp.org/showArchiveComment.php?ArchiveID=173
            +		 *         http://www.kvraudio.com/forum/viewtopic.php?t=212587
            +		 *         M *= 2*(1-width);
            +		 *         S *= 2*width
            +		 *
            +		 *  @extends {Tone.MidSideEffect}
            +		 *  @constructor
            +		 *  @param {number|Object} [width=0.5] the stereo width. A width of 0 is mono and 1 is stereo. 0.5 is no change.
            +		 */
            +		Tone.StereoWidener = function(){
            +
            +			var options = this.optionsObject(arguments, ["width"], Tone.StereoWidener.defaults);
            +			Tone.MidSideEffect.call(this, options);
            +
            +			/**
            +			 *  The width control. 0 = 100% mid. 1 = 100% side. 
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.width = new Tone.Signal(0.5, Tone.Signal.Units.Normal);
            +
            +			/**
            +			 *  Mid multiplier
            +			 *  @type {Tone.Expr}
            +			 *  @private
            +			 */
            +			this._midMult = new Tone.Expr("$0 * ($1 * (1 - $2))");
            +
            +			/**
            +			 *  Side multiplier
            +			 *  @type {Tone.Expr}
            +			 *  @private
            +			 */
            +			this._sideMult = new Tone.Expr("$0 * ($1 * $2)");
            +
            +			/**
            +			 *  constant output of 2
            +			 *  @type {Tone}
            +			 *  @private
            +			 */
            +			this._two = new Tone.Signal(2);
            +
            +			//the mid chain
            +			this._two.connect(this._midMult, 0, 1);
            +			this.width.connect(this._midMult, 0, 2);
            +			//the side chain
            +			this._two.connect(this._sideMult, 0, 1);
            +			this.width.connect(this._sideMult, 0, 2);
            +			//connect it to the effect send/return
            +			this.midSend.chain(this._midMult, this.midReturn);
            +			this.sideSend.chain(this._sideMult, this.sideReturn);
            +		};
            +
            +		Tone.extend(Tone.StereoWidener, Tone.MidSideEffect);
            +
            +		/**
            +		 *  the default values
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.StereoWidener.defaults = {
            +			"width" : 0.5
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.StereoWidener} `this`
            +		 */
            +		Tone.StereoWidener.prototype.dispose = function(){
            +			Tone.MidSideEffect.prototype.dispose.call(this);
            +			this.width.dispose();
            +			this.width = null;
            +			this._midMult.dispose();
            +			this._midMult = null;
            +			this._sideMult.dispose();
            +			this._sideMult = null;
            +			this._two.dispose();
            +			this._two = null;
            +			return this;
            +		};
            +
            +		return Tone.StereoWidener;
            +	});
            +	toneModule(
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Pulse Oscillator with control over width
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Oscillator}
            +		 *  @param {number} [frequency=440] the frequency of the oscillator
            +		 *  @param {number} [width = 0.5] the width of the pulse
            +		 */
            +		Tone.PulseOscillator = function(){
            +
            +			var options = this.optionsObject(arguments, ["frequency", "width"], Tone.Oscillator.defaults);
            +			Tone.Source.call(this, options);
            +
            +			/**
            +			 *  the width of the pulse
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.width = new Tone.Signal(options.width);
            +
            +			/**
            +			 *  the sawtooth oscillator
            +			 *  @type {Tone.Oscillator}
            +			 *  @private
            +			 */
            +			this._sawtooth = new Tone.Oscillator({
            +				frequency : options.frequency,
            +				detune : options.detune,
            +				type : "sawtooth",
            +				phase : options.phase
            +			});
            +
            +			/**
            +			 *  the oscillators frequency
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = this._sawtooth.frequency;
            +
            +			/**
            +			 *  the oscillators detune
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.detune = this._sawtooth.detune;
            +
            +			/**
            +			 *  threshold the signal to turn it into a square
            +			 *  
            +			 *  @type {Tone.WaveShaper}
            +			 *  @private
            +			 */
            +			this._thresh = new Tone.WaveShaper(function(val){
            +				if (val < 0){
            +					return -1;
            +				} else {
            +					return 1;
            +				}
            +			});
            +
            +			//connections
            +			this._sawtooth.chain(this._thresh, this.output);
            +			this.width.connect(this._thresh);
            +			this._sawtooth.onended = this._onended.bind(this);
            +		};
            +
            +		Tone.extend(Tone.PulseOscillator, Tone.Oscillator);
            +
            +		/**
            +		 *  the default parameters
            +		 *
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.PulseOscillator.defaults = {
            +			"frequency" : 440,
            +			"detune" : 0,
            +			"phase" : 0,
            +			"width" : 0.2,
            +		};
            +
            +		/**
            +		 *  start the oscillator
            +		 *  @param  {Tone.Time} time 
            +		 *  @private
            +		 */
            +		Tone.PulseOscillator.prototype._start = function(time){
            +			time = this.toSeconds(time);
            +			this._sawtooth.start(time);
            +			this.width.output.gain.setValueAtTime(1, time);
            +		};
            +
            +		/**
            +		 *  stop the oscillator
            +		 *  @param  {Tone.Time} time 
            +		 *  @returns {Tone.PulseOscillator} `this`
            +		 */
            +		Tone.PulseOscillator.prototype._stop = function(time){
            +			time = this.toSeconds(time);
            +			this._sawtooth.stop(time);
            +			//the width is still connected to the output. 
            +			//that needs to be stopped also
            +			this.width.output.gain.setValueAtTime(0, time);
            +		};
            +
            +		/**
            +		 * the phase of the oscillator in degrees
            +		 * @memberOf Tone.PulseOscillator#
            +		 * @type {number}
            +		 * @name phase
            +		 */
            +		Object.defineProperty(Tone.PulseOscillator.prototype, "phase", {
            +			get : function(){
            +				return this._sawtooth.phase;
            +			}, 
            +			set : function(phase){
            +				this._sawtooth.phase = phase;
            +			}
            +		});
            +
            +		/**
            +		 * The type of the oscillator.
            +		 * @memberOf Tone.PulseOscillator#
            +		 * @type {string}
            +		 * @name type
            +		 */
            +		Object.defineProperty(Tone.PulseOscillator.prototype, "type", {
            +			get : function(){
            +				return "pulse";
            +			}
            +		});
            +
            +		/**
            +		 *  clean up method
            +		 *  @return {Tone.PulseOscillator} `this`
            +		 */
            +		Tone.PulseOscillator.prototype.dispose = function(){
            +			Tone.Source.prototype.dispose.call(this);
            +			this._sawtooth.dispose();
            +			this._sawtooth = null;
            +			this.width.dispose();
            +			this.width = null;
            +			this._thresh.disconnect();
            +			this._thresh = null;
            +			this.frequency = null;
            +			this.detune = null;
            +			return this;
            +		};
            +
            +		return Tone.PulseOscillator;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class takes an array of Oscillator descriptions and mixes them together
            +		 *         with the same detune and frequency controls. 
            +		 *
            +		 *  @extends {Tone.Oscillator}
            +		 *  @constructor
            +		 *  @param {frequency} frequency frequency of the oscillator (meaningless for noise types)
            +		 *  @param {string} type the type of the oscillator
            +		 */
            +		Tone.PWMOscillator = function(){
            +			var options = this.optionsObject(arguments, ["frequency", "modulationFrequency"], Tone.PWMOscillator.defaults);
            +			Tone.Source.call(this, options);
            +
            +			/**
            +			 *  the pulse oscillator
            +			 */
            +			this._pulse = new Tone.PulseOscillator(options.modulationFrequency);
            +			//change the pulse oscillator type
            +			this._pulse._sawtooth.type = "sine";
            +
            +			/**
            +			 *  the modulator
            +			 */
            +			this._modulator = new Tone.Oscillator({
            +				"frequency" : options.frequency,
            +				"detune" : options.detune
            +			});
            +
            +			/**
            +			 *  the frequency control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = this._modulator.frequency;
            +
            +			/**
            +			 *  the detune control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.detune = this._modulator.detune;
            +
            +			/**
            +			 *  the modulation rate of the oscillator
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.modulationFrequency = this._pulse.frequency;	
            +
            +			//connections
            +			this._modulator.connect(this._pulse.width);
            +			this._pulse.connect(this.output);
            +			this._pulse.onended = this._onended.bind(this);
            +		};
            +
            +		Tone.extend(Tone.PWMOscillator, Tone.Oscillator);
            +
            +		/**
            +		 *  default values
            +		 *  @static
            +		 *  @type {Object}
            +		 *  @const
            +		 */
            +		Tone.PWMOscillator.defaults = {
            +			"frequency" : 440,
            +			"detune" : 0,
            +			"modulationFrequency" : 0.4,
            +		};
            +
            +		/**
            +		 *  start the oscillator
            +		 *  @param  {Tone.Time} [time=now]
            +		 *  @private
            +		 */
            +		Tone.PWMOscillator.prototype._start = function(time){
            +			time = this.toSeconds(time);
            +			this._modulator.start(time);
            +			this._pulse.start(time);
            +		};
            +
            +		/**
            +		 *  stop the oscillator
            +		 *  @param  {Tone.Time} time (optional) timing parameter
            +		 *  @private
            +		 */
            +		Tone.PWMOscillator.prototype._stop = function(time){
            +			time = this.toSeconds(time);
            +			this._modulator.stop(time);
            +			this._pulse.stop(time);
            +		};
            +
            +		/**
            +		 * The type of the oscillator.
            +		 *  
            +		 * @memberOf Tone.PWMOscillator#
            +		 * @type {string}
            +		 * @name type
            +		 */
            +		Object.defineProperty(Tone.PWMOscillator.prototype, "type", {
            +			get : function(){
            +				return "pwm";
            +			}
            +		});
            +
            +		/**
            +		 * the phase of the oscillator in degrees
            +		 * @memberOf Tone.PWMOscillator#
            +		 * @type {number}
            +		 * @name phase
            +		 */
            +		Object.defineProperty(Tone.PWMOscillator.prototype, "phase", {
            +			get : function(){
            +				return this._modulator.phase;
            +			}, 
            +			set : function(phase){
            +				this._modulator.phase = phase;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @return {Tone.PWMOscillator} `this`
            +		 */
            +		Tone.PWMOscillator.prototype.dispose = function(){
            +			Tone.Source.prototype.dispose.call(this);
            +			this._pulse.dispose();
            +			this._pulse = null;
            +			this._modulator.dispose();
            +			this._modulator = null;
            +			this.frequency = null;
            +			this.detune = null;
            +			this.modulationFrequency = null;
            +			return this;
            +		};
            +
            +		return Tone.PWMOscillator;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class OmniOscillator aggregates Tone.Oscillator, Tone.PulseOscillator,
            +		 *         and Tone.PWMOscillator which allows it to have the types: 
            +		 *         sine, square, triangle, sawtooth, pulse or pwm. 
            +		 *
            +		 *  @extends {Tone.Oscillator}
            +		 *  @constructor
            +		 *  @param {frequency} frequency frequency of the oscillator (meaningless for noise types)
            +		 *  @param {string} type the type of the oscillator
            +		 */
            +		Tone.OmniOscillator = function(){
            +			var options = this.optionsObject(arguments, ["frequency", "type"], Tone.OmniOscillator.defaults);
            +			Tone.Source.call(this, options);
            +
            +			/**
            +			 *  the frequency control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = new Tone.Signal(options.frequency, Tone.Signal.Units.Frequency);
            +
            +			/**
            +			 *  the detune control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.detune = new Tone.Signal(options.detune);
            +
            +			/**
            +			 *  the type of the oscillator source
            +			 *  @type {string}
            +			 *  @private
            +			 */
            +			this._sourceType = undefined;
            +
            +			/**
            +			 *  the oscillator
            +			 *  @type {Tone.Oscillator|Tone.PWMOscillator|Tone.PulseOscillator}
            +			 *  @private
            +			 */
            +			this._oscillator = null;
            +
            +			//set the oscillator
            +			this.type = options.type;
            +		};
            +
            +		Tone.extend(Tone.OmniOscillator, Tone.Oscillator);
            +
            +		/**
            +		 *  default values
            +		 *  @static
            +		 *  @type {Object}
            +		 *  @const
            +		 */
            +		Tone.OmniOscillator.defaults = {
            +			"frequency" : 440,
            +			"detune" : 0,
            +			"type" : "sine",
            +			"width" : 0.4, //only applies if the oscillator is set to "pulse",
            +			"modulationFrequency" : 0.4, //only applies if the oscillator is set to "pwm",
            +		};
            +
            +		/**
            +		 *  start the oscillator
            +		 *  @param {Tone.Time} [time=now] the time to start the oscillator
            +		 *  @private
            +		 */
            +		Tone.OmniOscillator.prototype._start = function(time){
            +			this._oscillator.start(time);
            +		};
            +
            +		/**
            +		 *  start the oscillator
            +		 *  @param {Tone.Time} [time=now] the time to start the oscillator
            +		 *  @private
            +		 */
            +		Tone.OmniOscillator.prototype._stop = function(time){
            +			this._oscillator.stop(time);
            +		};
            +
            +		/**
            +		 * The type of the oscillator. sine, square, triangle, sawtooth, pwm, or pulse. 
            +		 *  
            +		 * @memberOf Tone.OmniOscillator#
            +		 * @type {string}
            +		 * @name type
            +		 */
            +		Object.defineProperty(Tone.OmniOscillator.prototype, "type", {
            +			get : function(){
            +				return this._oscillator.type;
            +			}, 
            +			set : function(type){
            +				if (type === "sine" || type === "square" || type === "triangle" || type === "sawtooth"){
            +					if (this._sourceType !== OmniOscType.Oscillator){
            +						this._sourceType = OmniOscType.Oscillator;
            +						this._createNewOscillator(Tone.Oscillator);
            +					}
            +					this._oscillator.type = type;
            +				} else if (type === "pwm"){
            +					if (this._sourceType !== OmniOscType.PWMOscillator){
            +						this._sourceType = OmniOscType.PWMOscillator;
            +						this._createNewOscillator(Tone.PWMOscillator);
            +					}
            +				} else if (type === "pulse"){
            +					if (this._sourceType !== OmniOscType.PulseOscillator){
            +						this._sourceType = OmniOscType.PulseOscillator;
            +						this._createNewOscillator(Tone.PulseOscillator);
            +					}
            +				} else {
            +					throw new TypeError("Tone.OmniOscillator does not support type "+type);
            +				}
            +			}
            +		});
            +
            +		/**
            +		 *  connect the oscillator to the frequency and detune signals
            +		 *  @private
            +		 */
            +		Tone.OmniOscillator.prototype._createNewOscillator = function(OscillatorConstructor){
            +			//short delay to avoid clicks on the change
            +			var now = this.now() + this.bufferTime;
            +			if (this._oscillator !== null){
            +				var oldOsc = this._oscillator;
            +				oldOsc.stop(now);
            +				oldOsc.onended = function(){
            +					oldOsc.dispose();
            +					oldOsc = null;
            +				};
            +			}
            +			this._oscillator = new OscillatorConstructor();
            +			this.frequency.connect(this._oscillator.frequency);
            +			this.detune.connect(this._oscillator.detune);
            +			this._oscillator.connect(this.output);
            +			if (this.state === Tone.Source.State.STARTED){
            +				this._oscillator.start(now);
            +			}
            +			this._oscillator.onended = this._onended.bind(this);
            +		};
            +
            +		/**
            +		 * the phase of the oscillator in degrees
            +		 * @memberOf Tone.OmniOscillator#
            +		 * @type {number}
            +		 * @name phase
            +		 */
            +		Object.defineProperty(Tone.OmniOscillator.prototype, "phase", {
            +			get : function(){
            +				return this._oscillator.phase;
            +			}, 
            +			set : function(phase){
            +				this._oscillator.phase = phase;
            +			}
            +		});
            +
            +		/**
            +		 * The width Signal of the oscillator (only if the oscillator is set to pulse)
            +		 * @memberOf Tone.PulseOscillator#
            +		 * @type {Tone.Signal}
            +		 * @name width
            +		 */
            +		Object.defineProperty(Tone.OmniOscillator.prototype, "width", {
            +			get : function(){
            +				if (this._sourceType === OmniOscType.PulseOscillator){
            +					return this._oscillator.width;
            +				} 
            +			}
            +		});
            +
            +		/**
            +		 * The modulationFrequency Signal of the oscillator 
            +		 * (only if the oscillator type is set to pwm)
            +		 * @memberOf Tone.PulseOscillator#
            +		 * @type {Tone.Signal}
            +		 * @name width
            +		 */
            +		Object.defineProperty(Tone.OmniOscillator.prototype, "modulationFrequency", {
            +			get : function(){
            +				if (this._sourceType === OmniOscType.PWMOscillator){
            +					return this._oscillator.modulationFrequency;
            +				} 
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @private
            +		 *  @return {Tone.OmniOscillator} `this`
            +		 */
            +		Tone.OmniOscillator.prototype.dispose = function(){
            +			Tone.Source.prototype.dispose.call(this);
            +			this.detune.dispose();
            +			this.detune = null;
            +			this.frequency.dispose();
            +			this.frequency = null;
            +			this._oscillator.dispose();
            +			this._oscillator = null;
            +			this._sourceType = null;
            +			return this;
            +		};
            +
            +		/**
            +		 *  @enum {string}
            +		 */
            +		var OmniOscType = {
            +			PulseOscillator : "PulseOscillator",
            +			PWMOscillator : "PWMOscillator",
            +			Oscillator : "Oscillator"
            +		};
            +
            +		return Tone.OmniOscillator;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Base-class for all instruments
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 */
            +		Tone.Instrument = function(){
            +
            +			/**
            +			 *  the output
            +			 *  @type {GainNode}
            +			 */
            +			this.output = this.context.createGain();
            +
            +			/**
            +			 * the volume of the output in decibels
            +			 * @type {Tone.Signal}
            +			 */
            +			this.volume = new Tone.Signal(this.output.gain, Tone.Signal.Units.Decibels);
            +		};
            +
            +		Tone.extend(Tone.Instrument);
            +
            +		/**
            +		 *  @abstract
            +		 *  @param {string|number} note the note to trigger
            +		 *  @param {Tone.Time} [time=now] the time to trigger the ntoe
            +		 *  @param {number} [velocity=1] the velocity to trigger the note
            +		 */
            +		Tone.Instrument.prototype.triggerAttack = function(){};
            +
            +		/**
            +		 *  @abstract
            +		 *  @param {Tone.Time} [time=now] when to trigger the release
            +		 */
            +		Tone.Instrument.prototype.triggerRelease = function(){};
            +
            +		/**
            +		 *  trigger the attack and then the release
            +		 *  @param  {string|number} note     the note to trigger
            +		 *  @param  {Tone.Time} duration the duration of the note
            +		 *  @param {Tone.Time} [time=now]     the time of the attack
            +		 *  @param  {number} velocity the velocity
            +		 *  @returns {Tone.Instrument} `this`
            +		 */
            +		Tone.Instrument.prototype.triggerAttackRelease = function(note, duration, time, velocity){
            +			time = this.toSeconds(time);
            +			duration = this.toSeconds(duration);
            +			this.triggerAttack(note, time, velocity);
            +			this.triggerRelease(time + duration);
            +			return this;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Instrument} `this`
            +		 */
            +		Tone.Instrument.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.volume.dispose();
            +			this.volume = null;
            +			return this;
            +		};
            +
            +		return Tone.Instrument;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  this is a base class for monophonic instruments. 
            +		 *          it defines their interfaces
            +		 *
            +		 *  @constructor
            +		 *  @abstract
            +		 *  @extends {Tone.Instrument}
            +		 */
            +		Tone.Monophonic = function(options){
            +
            +			Tone.Instrument.call(this);
            +
            +			//get the defaults
            +			options = this.defaultArg(options, Tone.Monophonic.defaults);
            +
            +			/**
            +			 *  The glide time between notes. 
            +			 *  @type {Tone.Time}
            +			 */
            +			this.portamento = options.portamento;
            +		};
            +
            +		Tone.extend(Tone.Monophonic, Tone.Instrument);
            +
            +		/**
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.Monophonic.defaults = {
            +			"portamento" : 0
            +		};
            +
            +		/**
            +		 *  trigger the attack. start the note, at the time with the velocity
            +		 *  
            +		 *  @param  {string|string} note     the note
            +		 *  @param  {Tone.Time} [time=now]     the time, if not given is now
            +		 *  @param  {number} [velocity=1] velocity defaults to 1
            +		 *  @returns {Tone.Monophonic} `this`
            +		 */
            +		Tone.Monophonic.prototype.triggerAttack = function(note, time, velocity) {
            +			time = this.toSeconds(time);
            +			this.triggerEnvelopeAttack(time, velocity);
            +			this.setNote(note, time);
            +			return this;
            +		};
            +
            +		/**
            +		 *  trigger the release portion of the envelope
            +		 *  @param  {Tone.Time} [time=now] if no time is given, the release happens immediatly
            +		 *  @returns {Tone.Monophonic} `this`
            +		 */
            +		Tone.Monophonic.prototype.triggerRelease = function(time){
            +			this.triggerEnvelopeRelease(time);
            +			return this;
            +		};
            +
            +		/**
            +		 *  override this method with the actual method
            +		 *  @abstract
            +		 *  @param {Tone.Time} [time=now] the time the attack should happen
            +		 *  @param {number} [velocity=1] the velocity of the envelope
            +		 *  @returns {Tone.Monophonic} `this`
            +		 */	
            +		Tone.Monophonic.prototype.triggerEnvelopeAttack = function() {};
            +
            +		/**
            +		 *  override this method with the actual method
            +		 *  @abstract
            +		 *  @param {Tone.Time} [time=now] the time the attack should happen
            +		 *  @param {number} [velocity=1] the velocity of the envelope
            +		 *  @returns {Tone.Monophonic} `this`
            +		 */	
            +		Tone.Monophonic.prototype.triggerEnvelopeRelease = function() {};
            +
            +		/**
            +		 *  set the note to happen at a specific time
            +		 *  @param {number|string} note if the note is a string, it will be 
            +		 *                              parsed as (NoteName)(Octave) i.e. A4, C#3, etc
            +		 *                              otherwise it will be considered as the frequency
            +		 *  @returns {Tone.Monophonic} `this`
            +		 */
            +		Tone.Monophonic.prototype.setNote = function(note, time){
            +			time = this.toSeconds(time);
            +			if (this.portamento > 0){
            +				var currentNote = this.frequency.value;
            +				this.frequency.setValueAtTime(currentNote, time);
            +				var portTime = this.toSeconds(this.portamento);
            +				this.frequency.exponentialRampToValueAtTime(note, time + portTime);
            +			} else {
            +				this.frequency.setValueAtTime(note, time);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  set the preset if it exists
            +		 *  @param {string} presetName the name of the preset
            +		 *  @returns {Tone.Monophonic} `this`
            +		 */
            +		Tone.Monophonic.prototype.setPreset = function(presetName){
            +			if (!this.isUndef(this.preset) && this.preset.hasOwnProperty(presetName)){
            +				this.set(this.preset[presetName]);
            +			}
            +			return this;
            +		};
            +
            +		return Tone.Monophonic;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  the MonoSynth is a single oscillator, monophonic synthesizer
            +		 *          with a filter, and two envelopes (on the filter and the amplitude). 
            +		 *
            +		 * Flow: 
            +		 * 
            +		 * <pre>
            +		 * OmniOscillator+-->AmplitudeEnvelope+-->Filter 
            +		 *                                          ^    
            +		 *                                          |    
            +		 *                         ScaledEnvelope+--+
            +		 * </pre>
            +		 *  
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Monophonic}
            +		 *  @param {Object} options the options available for the synth 
            +		 *                          see defaults below
            +		 */
            +		Tone.MonoSynth = function(options){
            +
            +			//get the defaults
            +			options = this.defaultArg(options, Tone.MonoSynth.defaults);
            +			Tone.Monophonic.call(this, options);
            +
            +			/**
            +			 *  the first oscillator
            +			 *  @type {Tone.OmniOscillator}
            +			 */
            +			this.oscillator = new Tone.OmniOscillator(options.oscillator);
            +
            +			/**
            +			 *  the frequency control signal
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = this.oscillator.frequency;
            +
            +			/**
            +			 *  the detune control signal
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.detune = this.oscillator.detune;
            +
            +			/**
            +			 *  the filter
            +			 *  @type {Tone.Filter}
            +			 */
            +			this.filter = new Tone.Filter(options.filter);
            +
            +			/**
            +			 *  the filter envelope
            +			 *  @type {Tone.Envelope}
            +			 */
            +			this.filterEnvelope = new Tone.ScaledEnvelope(options.filterEnvelope);
            +
            +			/**
            +			 *  the amplitude envelope
            +			 *  @type {Tone.Envelope}
            +			 */
            +			this.envelope = new Tone.AmplitudeEnvelope(options.envelope);
            +
            +			//connect the oscillators to the output
            +			this.oscillator.chain(this.filter, this.envelope, this.output);
            +			//start the oscillators
            +			this.oscillator.start();
            +			//connect the filter envelope
            +			this.filterEnvelope.connect(this.filter.frequency);
            +		};
            +
            +		Tone.extend(Tone.MonoSynth, Tone.Monophonic);
            +
            +		/**
            +		 *  @const
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.MonoSynth.defaults = {
            +			"oscillator" : {
            +				"type" : "square"
            +			},
            +			"filter" : {
            +				"Q" : 6,
            +				"type" : "lowpass",
            +				"rolloff" : -24
            +			},
            +			"envelope" : {
            +				"attack" : 0.005,
            +				"decay" : 0.1,
            +				"sustain" : 0.9,
            +				"release" : 1
            +			},
            +			"filterEnvelope" : {
            +				"attack" : 0.06,
            +				"decay" : 0.2,
            +				"sustain" : 0.5,
            +				"release" : 2,
            +				"min" : 20,
            +				"max" : 4000,
            +				"exponent" : 2
            +			}
            +		};
            +
            +		/**
            +		 *  start the attack portion of the envelope
            +		 *  @param {Tone.Time} [time=now] the time the attack should start
            +		 *  @param {number} [velocity=1] the velocity of the note (0-1)
            +		 *  @returns {Tone.MonoSynth} `this`
            +		 */
            +		Tone.MonoSynth.prototype.triggerEnvelopeAttack = function(time, velocity){
            +			//the envelopes
            +			this.envelope.triggerAttack(time, velocity);
            +			this.filterEnvelope.triggerAttack(time);	
            +			return this;	
            +		};
            +
            +		/**
            +		 *  start the release portion of the envelope
            +		 *  @param {Tone.Time} [time=now] the time the release should start
            +		 *  @returns {Tone.MonoSynth} `this`
            +		 */
            +		Tone.MonoSynth.prototype.triggerEnvelopeRelease = function(time){
            +			this.envelope.triggerRelease(time);
            +			this.filterEnvelope.triggerRelease(time);
            +			return this;
            +		};
            +
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.MonoSynth} `this`
            +		 */
            +		Tone.MonoSynth.prototype.dispose = function(){
            +			Tone.Monophonic.prototype.dispose.call(this);
            +			this.oscillator.dispose();
            +			this.oscillator = null;
            +			this.envelope.dispose();
            +			this.envelope = null;
            +			this.filterEnvelope.dispose();
            +			this.filterEnvelope = null;
            +			this.filter.dispose();
            +			this.filter = null;
            +			this.frequency = null;
            +			this.detune = null;
            +			return this;
            +		};
            +
            +		return Tone.MonoSynth;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  the AMSynth is an amplitude modulation synthesizer
            +		 *          composed of two MonoSynths where one MonoSynth is the 
            +		 *          carrier and the second is the modulator.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Monophonic}
            +		 *  @param {Object} options the options available for the synth 
            +		 *                          see defaults below
            +		 */
            +		Tone.AMSynth = function(options){
            +
            +			options = this.defaultArg(options, Tone.AMSynth.defaults);
            +			Tone.Monophonic.call(this, options);
            +
            +			/**
            +			 *  the first voice
            +			 *  @type {Tone.MonoSynth}
            +			 */
            +			this.carrier = new Tone.MonoSynth(options.carrier);
            +			this.carrier.volume.value = -10;
            +
            +			/**
            +			 *  the second voice
            +			 *  @type {Tone.MonoSynth}
            +			 */
            +			this.modulator = new Tone.MonoSynth(options.modulator);
            +			this.modulator.volume.value = -10;
            +
            +			/**
            +			 *  the frequency control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = new Tone.Signal(440, Tone.Signal.Units.Frequency);
            +
            +			/**
            +			 *  the ratio between the two voices
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._harmonicity = new Tone.Multiply(options.harmonicity);
            +
            +			/**
            +			 *  convert the -1,1 output to 0,1
            +			 *  @type {Tone.AudioToGain}
            +			 *  @private
            +			 */
            +			this._modulationScale = new Tone.AudioToGain();
            +
            +			/**
            +			 *  the node where the modulation happens
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._modulationNode = this.context.createGain();
            +
            +			//control the two voices frequency
            +			this.frequency.connect(this.carrier.frequency);
            +			this.frequency.chain(this._harmonicity, this.modulator.frequency);
            +			this.modulator.chain(this._modulationScale, this._modulationNode.gain);
            +			this.carrier.chain(this._modulationNode, this.output);
            +		};
            +
            +		Tone.extend(Tone.AMSynth, Tone.Monophonic);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.AMSynth.defaults = {
            +			"harmonicity" : 3,
            +			"carrier" : {
            +				"volume" : -10,
            +				"portamento" : 0,
            +				"oscillator" : {
            +					"type" : "sine"
            +				},
            +				"envelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.01,
            +					"sustain" : 1,
            +					"release" : 0.5
            +				},
            +				"filterEnvelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5,
            +					"min" : 20000,
            +					"max" : 20000
            +				}
            +			},
            +			"modulator" : {
            +				"volume" : -10,
            +				"portamento" : 0,
            +				"oscillator" : {
            +					"type" : "square"
            +				},
            +				"envelope" : {
            +					"attack" : 2,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5
            +				},
            +				"filterEnvelope" : {
            +					"attack" : 4,
            +					"decay" : 0.2,
            +					"sustain" : 0.5,
            +					"release" : 0.5,
            +					"min" : 20,
            +					"max" : 1500
            +				}
            +			}
            +		};
            +
            +		/**
            +		 *  trigger the attack portion of the note
            +		 *  
            +		 *  @param  {Tone.Time} [time=now] the time the note will occur
            +		 *  @param {number} [velocity=1] the velocity of the note
            +		 *  @returns {Tone.AMSynth} `this`
            +		 */
            +		Tone.AMSynth.prototype.triggerEnvelopeAttack = function(time, velocity){
            +			//the port glide
            +			time = this.toSeconds(time);
            +			//the envelopes
            +			this.carrier.envelope.triggerAttack(time, velocity);
            +			this.modulator.envelope.triggerAttack(time);
            +			this.carrier.filterEnvelope.triggerAttack(time);
            +			this.modulator.filterEnvelope.triggerAttack(time);
            +			return this;
            +		};
            +
            +		/**
            +		 *  trigger the release portion of the note
            +		 *  
            +		 *  @param  {Tone.Time} [time=now] the time the note will release
            +		 *  @returns {Tone.AMSynth} `this`
            +		 */
            +		Tone.AMSynth.prototype.triggerEnvelopeRelease = function(time){
            +			this.carrier.triggerRelease(time);
            +			this.modulator.triggerRelease(time);
            +			return this;
            +		};
            +
            +		/**
            +		 * The ratio between the two carrier and the modulator. 
            +		 * @memberOf Tone.AMSynth#
            +		 * @type {number}
            +		 * @name harmonicity
            +		 */
            +		Object.defineProperty(Tone.AMSynth.prototype, "harmonicity", {
            +			get : function(){
            +				return this._harmonicity.value;
            +			},
            +			set : function(harm){
            +				this._harmonicity.value = harm;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.AMSynth} `this`
            +		 */
            +		Tone.AMSynth.prototype.dispose = function(){
            +			Tone.Monophonic.prototype.dispose.call(this);
            +			this.carrier.dispose();
            +			this.carrier = null;
            +			this.modulator.dispose();
            +			this.modulator = null;
            +			this.frequency.dispose();
            +			this.frequency = null;
            +			this._harmonicity.dispose();
            +			this._harmonicity = null;
            +			this._modulationScale.dispose();
            +			this._modulationScale = null;
            +			this._modulationNode.disconnect();
            +			this._modulationNode = null;
            +			return this;
            +		};
            +
            +		return Tone.AMSynth;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  the DuoSynth is a monophonic synth composed of two 
            +		 *          MonoSynths run in parallel with control over the 
            +		 *          frequency ratio between the two voices and vibrato effect.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Monophonic}
            +		 *  @param {Object} options the options available for the synth 
            +		 *                          see defaults below
            +		 */
            +		Tone.DuoSynth = function(options){
            +
            +			options = this.defaultArg(options, Tone.DuoSynth.defaults);
            +			Tone.Monophonic.call(this, options);
            +
            +			/**
            +			 *  the first voice
            +			 *  @type {Tone.MonoSynth}
            +			 */
            +			this.voice0 = new Tone.MonoSynth(options.voice0);
            +			this.voice0.volume.value = -10;
            +
            +			/**
            +			 *  the second voice
            +			 *  @type {Tone.MonoSynth}
            +			 */
            +			this.voice1 = new Tone.MonoSynth(options.voice1);
            +			this.voice1.volume.value = -10;
            +
            +			/**
            +			 *  The vibrato LFO. 
            +			 *  @type {Tone.LFO}
            +			 *  @private
            +			 */
            +			this._vibrato = new Tone.LFO(options.vibratoRate, -50, 50);
            +			this._vibrato.start();
            +
            +			/**
            +			 * the vibrato frequency
            +			 * @type {Tone.Signal}
            +			 */
            +			this.vibratoRate = this._vibrato.frequency;
            +
            +			/**
            +			 *  the vibrato gain
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._vibratoGain = this.context.createGain();
            +
            +			/**
            +			 * The amount of vibrato
            +			 * @type {Tone.Signal}
            +			 */
            +			this.vibratoAmount = new Tone.Signal(this._vibratoGain.gain, Tone.Signal.Units.Gain);
            +			this.vibratoAmount.value = options.vibratoAmount;
            +
            +			/**
            +			 *  the delay before the vibrato starts
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._vibratoDelay = this.toSeconds(options.vibratoDelay);
            +
            +			/**
            +			 *  the frequency control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = new Tone.Signal(440, Tone.Signal.Units.Frequency);
            +
            +			/**
            +			 *  the ratio between the two voices
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._harmonicity = new Tone.Multiply(options.harmonicity);
            +
            +			//control the two voices frequency
            +			this.frequency.connect(this.voice0.frequency);
            +			this.frequency.chain(this._harmonicity, this.voice1.frequency);
            +			this._vibrato.connect(this._vibratoGain);
            +			this._vibratoGain.fan(this.voice0.detune, this.voice1.detune);
            +			this.voice0.connect(this.output);
            +			this.voice1.connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.DuoSynth, Tone.Monophonic);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.DuoSynth.defaults = {
            +			"vibratoAmount" : 0.5,
            +			"vibratoRate" : 5,
            +			"vibratoDelay" : 1,
            +			"harmonicity" : 1.5,
            +			"voice0" : {
            +				"volume" : -10,
            +				"portamento" : 0,
            +				"oscillator" : {
            +					"type" : "sine"
            +				},
            +				"filterEnvelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5
            +				},
            +				"envelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5
            +				}
            +			},
            +			"voice1" : {
            +				"volume" : -10,
            +				"portamento" : 0,
            +				"oscillator" : {
            +					"type" : "sine"
            +				},
            +				"filterEnvelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5
            +				},
            +				"envelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5
            +				}
            +			}
            +		};
            +
            +		/**
            +		 *  start the attack portion of the envelopes
            +		 *  
            +		 *  @param {Tone.Time} [time=now] the time the attack should start
            +		 *  @param {number} [velocity=1] the velocity of the note (0-1)
            +		 *  @returns {Tone.DuoSynth} `this`
            +		 */
            +		Tone.DuoSynth.prototype.triggerEnvelopeAttack = function(time, velocity){
            +			time = this.toSeconds(time);
            +			this.voice0.envelope.triggerAttack(time, velocity);
            +			this.voice1.envelope.triggerAttack(time, velocity);
            +			this.voice0.filterEnvelope.triggerAttack(time);
            +			this.voice1.filterEnvelope.triggerAttack(time);
            +			return this;
            +		};
            +
            +		/**
            +		 *  start the release portion of the envelopes
            +		 *  
            +		 *  @param {Tone.Time} [time=now] the time the release should start
            +		 *  @returns {Tone.DuoSynth} `this`
            +		 */
            +		Tone.DuoSynth.prototype.triggerEnvelopeRelease = function(time){
            +			this.voice0.triggerRelease(time);
            +			this.voice1.triggerRelease(time);
            +			return this;
            +		};
            +
            +		/**
            +		 * The ratio between the two carrier and the modulator. 
            +		 * @memberOf Tone.DuoSynth#
            +		 * @type {number}
            +		 * @name harmonicity
            +		 */
            +		Object.defineProperty(Tone.DuoSynth.prototype, "harmonicity", {
            +			get : function(){
            +				return this._harmonicity.value;
            +			},
            +			set : function(harm){
            +				this._harmonicity.value = harm;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.DuoSynth} `this`
            +		 */
            +		Tone.DuoSynth.prototype.dispose = function(){
            +			Tone.Monophonic.prototype.dispose.call(this);
            +			this.voice0.dispose();
            +			this.voice0 = null;
            +			this.voice1.dispose();
            +			this.voice1 = null;
            +			this.frequency.dispose();
            +			this.frequency = null;
            +			this._vibrato.dispose();
            +			this._vibrato = null;
            +			this._vibratoGain.disconnect();
            +			this._vibratoGain = null;
            +			this._harmonicity.dispose();
            +			this._harmonicity = null;
            +			this.vibratoAmount.dispose();
            +			this.vibratoAmount = null;
            +			this.vibratoRate = null;
            +			return this;
            +		};
            +
            +		return Tone.DuoSynth;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  the FMSynth is composed of two MonoSynths where one MonoSynth is the 
            +		 *          carrier and the second is the modulator.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Monophonic}
            +		 *  @param {Object} options the options available for the synth 
            +		 *                          see defaults below
            +		 */
            +		Tone.FMSynth = function(options){
            +
            +			options = this.defaultArg(options, Tone.FMSynth.defaults);
            +			Tone.Monophonic.call(this, options);
            +
            +			/**
            +			 *  the first voice
            +			 *  @type {Tone.MonoSynth}
            +			 */
            +			this.carrier = new Tone.MonoSynth(options.carrier);
            +			this.carrier.volume.value = -10;
            +
            +			/**
            +			 *  the second voice
            +			 *  @type {Tone.MonoSynth}
            +			 */
            +			this.modulator = new Tone.MonoSynth(options.modulator);
            +			this.modulator.volume.value = -10;
            +
            +			/**
            +			 *  the frequency control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.frequency = new Tone.Signal(440, Tone.Signal.Units.Frequency);
            +
            +			/**
            +			 *  the ratio between the two voices
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._harmonicity = new Tone.Multiply(options.harmonicity);
            +
            +			/**
            +			 *  
            +			 *
            +			 *	@type {Tone.Multiply}
            +			 *	@private
            +			 */
            +			this._modulationIndex = new Tone.Multiply(options.modulationIndex);
            +
            +			/**
            +			 *  the node where the modulation happens
            +			 *  @type {GainNode}
            +			 *  @private
            +			 */
            +			this._modulationNode = this.context.createGain();
            +
            +			//control the two voices frequency
            +			this.frequency.connect(this.carrier.frequency);
            +			this.frequency.chain(this._harmonicity, this.modulator.frequency);
            +			this.frequency.chain(this._modulationIndex, this._modulationNode);
            +			this.modulator.connect(this._modulationNode.gain);
            +			this._modulationNode.gain.value = 0;
            +			this._modulationNode.connect(this.carrier.frequency);
            +			this.carrier.connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.FMSynth, Tone.Monophonic);
            +
            +		/**
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.FMSynth.defaults = {
            +			"harmonicity" : 3,
            +			"modulationIndex" : 10,
            +			"carrier" : {
            +				"volume" : -10,
            +				"portamento" : 0,
            +				"oscillator" : {
            +					"type" : "sine"
            +				},
            +				"envelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5
            +				},
            +				"filterEnvelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5,
            +					"min" : 20000,
            +					"max" : 20000
            +				}
            +			},
            +			"modulator" : {
            +				"volume" : -10,
            +				"portamento" : 0,
            +				"oscillator" : {
            +					"type" : "triangle"
            +				},
            +				"envelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5
            +				},
            +				"filterEnvelope" : {
            +					"attack" : 0.01,
            +					"decay" : 0.0,
            +					"sustain" : 1,
            +					"release" : 0.5,
            +					"min" : 20000,
            +					"max" : 20000
            +				}
            +			}
            +		};
            +
            +		/**
            +		 *  trigger the attack portion of the note
            +		 *  
            +		 *  @param  {Tone.Time} [time=now] the time the note will occur
            +		 *  @param {number} [velocity=1] the velocity of the note
            +		 *  @returns {Tone.FMSynth} `this`
            +		 */
            +		Tone.FMSynth.prototype.triggerEnvelopeAttack = function(time, velocity){
            +			//the port glide
            +			time = this.toSeconds(time);
            +			//the envelopes
            +			this.carrier.envelope.triggerAttack(time, velocity);
            +			this.modulator.envelope.triggerAttack(time);
            +			this.carrier.filterEnvelope.triggerAttack(time);
            +			this.modulator.filterEnvelope.triggerAttack(time);
            +			return this;
            +		};
            +
            +		/**
            +		 *  trigger the release portion of the note
            +		 *  
            +		 *  @param  {Tone.Time} [time=now] the time the note will release
            +		 *  @returns {Tone.FMSynth} `this`
            +		 */
            +		Tone.FMSynth.prototype.triggerEnvelopeRelease = function(time){
            +			this.carrier.triggerRelease(time);
            +			this.modulator.triggerRelease(time);
            +			return this;
            +		};
            +
            +		/**
            +		 * The ratio between the two carrier and the modulator. 
            +		 * @memberOf Tone.FMSynth#
            +		 * @type {number}
            +		 * @name harmonicity
            +		 */
            +		Object.defineProperty(Tone.FMSynth.prototype, "harmonicity", {
            +			get : function(){
            +				return this._harmonicity.value;
            +			},
            +			set : function(harm){
            +				this._harmonicity.value = harm;
            +			}
            +		});
            +
            +		/**
            +		 * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the 
            +		 *  ratio of the frequency of the modulating signal (mf) to the amplitude of the 
            +		 *  modulating signal (ma) -- as in ma/mf. 
            +		 * @memberOf Tone.FMSynth#
            +		 * @type {number}
            +		 * @name modulationIndex
            +		 */
            +		Object.defineProperty(Tone.FMSynth.prototype, "modulationIndex", {
            +			get : function(){
            +				return this._modulationIndex.value;
            +			},
            +			set : function(mod){
            +				this._modulationIndex.value = mod;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.FMSynth} `this`
            +		 */
            +		Tone.FMSynth.prototype.dispose = function(){
            +			Tone.Monophonic.prototype.dispose.call(this);
            +			this.carrier.dispose();
            +			this.carrier = null;
            +			this.modulator.dispose();
            +			this.modulator = null;
            +			this.frequency.dispose();
            +			this.frequency = null;
            +			this._modulationIndex.dispose();
            +			this._modulationIndex = null;
            +			this._harmonicity.dispose();
            +			this._harmonicity = null;
            +			this._modulationNode.disconnect();
            +			this._modulationNode = null;
            +			return this;
            +		};
            +
            +		return Tone.FMSynth;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +		
            +		/**
            +		 *  @class  Audio file player with start, loop, stop.
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.Source} 
            +		 *  @param {string|AudioBuffer} url either the AudioBuffer or the url from
            +		 *                                  which to load the AudioBuffer
            +		 */
            +		Tone.Player = function(){
            +			
            +			var options = this.optionsObject(arguments, ["url", "onload"], Tone.Player.defaults);
            +			Tone.Source.call(this, options);
            +
            +			/**
            +			 *  @private
            +			 *  @type {AudioBufferSourceNode}
            +			 */
            +			this._source = null;
            +			
            +			/**
            +			 *  the buffer
            +			 *  @private
            +			 *  @type {Tone.Buffer}
            +			 */
            +			this._buffer = new Tone.Buffer(options.url, options.onload.bind(null, this));
            +
            +			/**
            +			 *  if the buffer should loop once it's over
            +			 *  @type {boolean}
            +			 *  @private
            +			 */
            +			this._loop = options.loop;
            +
            +			/**
            +			 *  if 'loop' is true, the loop will start at this position
            +			 *  @type {Tone.Time}
            +			 */
            +			this._loopStart = options.loopStart;
            +
            +			/**
            +			 *  if 'loop' is true, the loop will end at this position
            +			 *  @type {Tone.Time}
            +			 */
            +			this._loopEnd = options.loopEnd;
            +
            +			/**
            +			 *  the playback rate
            +			 *  @private
            +			 *  @type {number}
            +			 */
            +			this._playbackRate = options.playbackRate;
            +
            +			/**
            +			 *  enabling retrigger will allow a player to be restarted
            +			 *  before the the previous 'start' is done playing
            +			 *  
            +			 *  @type {boolean}
            +			 */
            +			this.retrigger = options.retrigger;
            +		};
            +
            +		Tone.extend(Tone.Player, Tone.Source);
            +		
            +		/**
            +		 *  the default parameters
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.Player.defaults = {
            +			"onload" : function(){},
            +			"playbackRate" : 1,
            +			"loop" : false,
            +			"loopStart" : 0,
            +			"loopEnd" : 0,
            +			"retrigger" : false
            +		};
            +
            +		/**
            +		 *  Load the audio file as an audio buffer.
            +		 *  Decodes the audio asynchronously and invokes
            +		 *  the callback once the audio buffer loads.
            +		 * @param {string} url the url of the buffer to load.
            +		 *        filetype support depends on the
            +		 *        browser.
            +		 * @param  {function(Tone.Player)=} callback
            +		 *  @returns {Tone.Player} `this`
            +		 */
            +		Tone.Player.prototype.load = function(url, callback){
            +			this._buffer.load(url, callback.bind(this, this));
            +			return this;
            +		};
            +
            +		/**
            +		 *  play the buffer between the desired positions
            +		 *  
            +		 *  @private
            +		 *  @param  {Tone.Time} [startTime=now] when the player should start.
            +		 *  @param  {Tone.Time} [offset=0] the offset from the beginning of the sample
            +		 *                                 to start at. 
            +		 *  @param  {Tone.Time=} duration how long the sample should play. If no duration
            +		 *                                is given, it will default to the full length 
            +		 *                                of the sample (minus any offset)
            +		 *  @returns {Tone.Player} `this`
            +		 */
            +		Tone.Player.prototype._start = function(startTime, offset, duration){
            +			if (this._buffer.loaded){
            +				//if it's a loop the default offset is the loopstart point
            +				if (this._loop){
            +					offset = this.defaultArg(offset, this._loopStart);
            +				} else {
            +					//otherwise the default offset is 0
            +					offset = this.defaultArg(offset, 0);
            +				}
            +				duration = this.defaultArg(duration, this._buffer.duration - offset);
            +				//make the source
            +				this._source = this.context.createBufferSource();
            +				this._source.buffer = this._buffer.get();
            +				//set the looping properties
            +				if (this._loop){
            +					this._source.loop = this._loop;
            +					this._source.loopStart = this.toSeconds(this._loopStart);
            +					this._source.loopEnd = this.toSeconds(this._loopEnd);
            +				}
            +				//and other properties
            +				this._source.playbackRate.value = this._playbackRate;
            +				this._source.onended = this._onended.bind(this);
            +				this._source.connect(this.output);
            +				//start it
            +				this._source.start(this.toSeconds(startTime), this.toSeconds(offset), this.toSeconds(duration));
            +			} else {
            +				throw Error("tried to start Player before the buffer was loaded");
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  Stop playback.
            +		 *  @private
            +		 *  @param  {Tone.Time} [time=now]
            +		 *  @returns {Tone.Player} `this`
            +		 */
            +		Tone.Player.prototype._stop = function(time){
            +			if (this._source){
            +				this._source.stop(this.toSeconds(time));
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  set the loop start and end
            +		 *  @param {Tone.Time} loopStart the loop end time
            +		 *  @param {Tone.Time} loopEnd the loop end time
            +		 *  @returns {Tone.Player} `this`
            +		 */
            +		Tone.Player.prototype.setLoopPoints = function(loopStart, loopEnd){
            +			this.loopStart = loopStart;
            +			this.loopEnd = loopEnd;
            +			return this;
            +		};
            +
            +		/**
            +		 * if 'loop' is true, the loop will start at this position
            +		 * @memberOf Tone.Player#
            +		 * @type {Tone.Time}
            +		 * @name loopStart
            +		 */
            +		Object.defineProperty(Tone.Player.prototype, "loopStart", {
            +			get : function(){
            +				return this._loopStart;
            +			}, 
            +			set : function(loopStart){
            +				this._loopStart = loopStart;
            +				if (this._source){
            +					this._source.loopStart = this.toSeconds(loopStart);
            +				}
            +			}
            +		});
            +
            +		/**
            +		 * if 'loop' is true, the loop will end at this position
            +		 * @memberOf Tone.Player#
            +		 * @type {Tone.Time}
            +		 * @name loopEnd
            +		 */
            +		Object.defineProperty(Tone.Player.prototype, "loopEnd", {
            +			get : function(){
            +				return this._loopEnd;
            +			}, 
            +			set : function(loopEnd){
            +				this._loopEnd = loopEnd;
            +				if (this._source){
            +					this._source.loopEnd = this.toSeconds(loopEnd);
            +				}
            +			}
            +		});
            +
            +		/**
            +		 * The audio buffer belonging to the player. 
            +		 * @memberOf Tone.Player#
            +		 * @type {AudioBuffer}
            +		 * @name buffer
            +		 */
            +		Object.defineProperty(Tone.Player.prototype, "buffer", {
            +			get : function(){
            +				return this._buffer;
            +			}, 
            +			set : function(buffer){
            +				this._buffer.set(buffer);
            +			}
            +		});
            +
            +		/**
            +		 * if the buffer should loop once it's over
            +		 * @memberOf Tone.Player#
            +		 * @type {boolean}
            +		 * @name loop
            +		 */
            +		Object.defineProperty(Tone.Player.prototype, "loop", {
            +			get : function(){
            +				return this._loop;
            +			}, 
            +			set : function(loop){
            +				this._loop = loop;
            +				if (this._source){
            +					this._source.loop = loop;
            +				}
            +			}
            +		});
            +
            +		/**
            +		 * The playback speed. 1 is normal speed. 
            +		 * Note that this is not a Tone.Signal because of a bug in Blink. 
            +		 * Please star this issue if this an important thing to you: 
            +		 * https://code.google.com/p/chromium/issues/detail?id=311284
            +		 * 
            +		 * @memberOf Tone.Player#
            +		 * @type {number}
            +		 * @name playbackRate
            +		 */
            +		Object.defineProperty(Tone.Player.prototype, "playbackRate", {
            +			get : function(){
            +				return this._playbackRate;
            +			}, 
            +			set : function(rate){
            +				this._playbackRate = rate;
            +				if (this._source) {
            +					this._source.playbackRate.value = rate;
            +				}
            +			}
            +		});
            +
            +		/**
            +		 *  dispose and disconnect
            +		 *  @return {Tone.Player} `this`
            +		 */
            +		Tone.Player.prototype.dispose = function(){
            +			Tone.Source.prototype.dispose.call(this);
            +			if (this._source !== null){
            +				this._source.disconnect();
            +				this._source = null;
            +			}
            +			this._buffer.dispose();
            +			this._buffer = null;
            +			return this;
            +		};
            +
            +		return Tone.Player;
            +	});
            +
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class A simple sampler instrument which plays an audio buffer 
            +		 *         through an amplitude envelope and a filter envelope. Nested
            +		 *         lists will be flattened like so: 
            +		 *         ```javascript
            +		 *         var sampler = new Sampler({
            +		 *         	A : {
            +		 *         		1 : {"./audio/casio/A1.mp3",
            +		 *         		2 : "./audio/casio/A2.mp3",
            +		 *         	},
            +		 *         	"B.1" : "./audio/casio/B1.mp3",
            +		 *         });
            +		 *         //...once samples have loaded
            +		 *         sampler.triggerAttack("A.1", time, velocity);
            +		 *         ```
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Instrument}
            +		 *  @param {Object|string} urls the urls of the audio file
            +		 *  @param {Object} options the options object for the synth
            +		 */
            +		Tone.Sampler = function(urls, options){
            +
            +			Tone.Instrument.call(this);
            +			options = this.defaultArg(options, Tone.Sampler.defaults);
            +
            +			/**
            +			 *  the sample player
            +			 *  @type {Tone.Player}
            +			 */
            +			this.player = new Tone.Player(options.player);
            +			this.player.retrigger = true;
            +
            +			/**
            +			 *  the buffers
            +			 *  @type {Object<Tone.Buffer>}
            +			 *  @private
            +			 */
            +			this._buffers = {};
            +
            +			/**
            +			 *  The amplitude envelope. 
            +			 *  @type {Tone.Envelope}
            +			 */
            +			this.envelope = new Tone.AmplitudeEnvelope(options.envelope);
            +
            +			/**
            +			 *  The filter envelope. 
            +			 *  @type {Tone.Envelope}
            +			 */
            +			this.filterEnvelope = new Tone.ScaledEnvelope(options.filterEnvelope);
            +
            +			/**
            +			 *  The name of the current sample. 
            +			 *  @type {string}
            +			 */
            +			this._sample = options.sample;
            +
            +			/**
            +			 * the private reference to the pitch
            +			 * @type {number}
            +			 * @private
            +			 */
            +			this._pitch = options.pitch;
            +
            +			/**
            +			 *  The filter.
            +			 *  @type {BiquadFilterNode}
            +			 */
            +			this.filter = new Tone.Filter(options.filter);
            +
            +			//connections / setup
            +			this._loadBuffers(urls);
            +			this.pitch = options.pitch;
            +			this.player.chain(this.filter, this.envelope, this.output);
            +			this.filterEnvelope.connect(this.filter.frequency);
            +		};
            +
            +		Tone.extend(Tone.Sampler, Tone.Instrument);
            +
            +		/**
            +		 *  the default parameters
            +		 *  @static
            +		 */
            +		Tone.Sampler.defaults = {
            +			"sample" : 0,
            +			"pitch" : 0,
            +			"player" : {
            +				"loop" : false,
            +			},
            +			"envelope" : {
            +				"attack" : 0.001,
            +				"decay" : 0,
            +				"sustain" : 1,
            +				"release" : 0.1
            +			},
            +			"filterEnvelope" : {
            +				"attack" : 0.001,
            +				"decay" : 0.001,
            +				"sustain" : 1,
            +				"release" : 0.5,
            +				"min" : 20,
            +				"max" : 20000,
            +				"exponent" : 2,
            +			},
            +			"filter" : {
            +				"type" : "lowpass"
            +			}
            +		};
            +
            +		/**
            +		 *  load the buffers
            +		 *  @param   {Object} urls   the urls
            +		 *  @private
            +		 */
            +		Tone.Sampler.prototype._loadBuffers = function(urls){
            +			if (typeof urls === "string"){
            +				this._buffers["0"] = new Tone.Buffer(urls, this.setSample.bind(this, "0"));
            +			} else {
            +				urls = this._flattenUrls(urls);
            +				for (var buffName in urls){
            +					this._sample = buffName;
            +					var urlString = urls[buffName];
            +					this._buffers[buffName] = new Tone.Buffer(urlString);
            +				}
            +			}
            +		};
            +
            +		/**
            +		 *  flatten an object into a single depth object
            +		 *  https://gist.github.com/penguinboy/762197
            +		 *  @param   {Object} ob 	
            +		 *  @return  {Object}    
            +		 *  @private
            +		 */
            +		Tone.Sampler.prototype._flattenUrls = function(ob) {
            +			var toReturn = {};
            +			for (var i in ob) {
            +				if (!ob.hasOwnProperty(i)) continue;
            +				if ((typeof ob[i]) == "object") {
            +					var flatObject = this._flattenUrls(ob[i]);
            +					for (var x in flatObject) {
            +						if (!flatObject.hasOwnProperty(x)) continue;
            +						toReturn[i + "." + x] = flatObject[x];
            +					}
            +				} else {
            +					toReturn[i] = ob[i];
            +				}
            +			}
            +			return toReturn;
            +		};
            +
            +		/**
            +		 *  start the sample.
            +		 *  @param {string=} sample the name of the samle to trigger, defaults to
            +		 *                          the last sample used
            +		 *  @param {Tone.Time} [time=now] the time when the note should start
            +		 *  @param {number} [velocity=1] the velocity of the note
            +		 *  @returns {Tone.Sampler} `this`
            +		 */
            +		Tone.Sampler.prototype.triggerAttack = function(name, time, velocity){
            +			time = this.toSeconds(time);
            +			if (name){
            +				this.setSample(name);
            +			}
            +			this.player.start(time, 0);
            +			this.envelope.triggerAttack(time, velocity);
            +			this.filterEnvelope.triggerAttack(time);
            +			return this;
            +		};
            +
            +		/**
            +		 *  start the release portion of the sample
            +		 *  
            +		 *  @param {Tone.Time} [time=now] the time when the note should release
            +		 *  @returns {Tone.Sampler} `this`
            +		 */
            +		Tone.Sampler.prototype.triggerRelease = function(time){
            +			time = this.toSeconds(time);
            +			this.filterEnvelope.triggerRelease(time);
            +			this.envelope.triggerRelease(time);
            +			this.player.stop(this.toSeconds(this.envelope.release) + time);
            +			return this;
            +		};
            +
            +		/**
            +		 * The name of the sample to trigger.
            +		 * @memberOf Tone.Sampler#
            +		 * @type {number|string}
            +		 * @name sample
            +		 */
            +		Object.defineProperty(Tone.Sampler.prototype, "sample", {
            +			get : function(){
            +				return this._sample;
            +			},
            +			set : function(name){
            +				if (this._buffers.hasOwnProperty(name)){
            +					this._sample = name;
            +					this.player.buffer = this._buffers[name];
            +				} else {
            +					throw new Error("Sampler does not have a sample named "+name);
            +				}
            +			}
            +		});
            +
            +		/**
            +		 * Repitch the sampled note by some interval (measured
            +		 * in semi-tones). 
            +		 * ```javascript
            +		 * sampler.pitch = -12; //down one octave
            +		 * sampler.pitch = 7; //up a fifth
            +		 * ```
            +		 * @memberOf Tone.Sampler#
            +		 * @type {number}
            +		 * @name pitch
            +		 */
            +		Object.defineProperty(Tone.Sampler.prototype, "pitch", {
            +			get : function(){
            +				return this._pitch;
            +			},
            +			set : function(interval){
            +				this._pitch = interval;
            +				this.player.playbackRate = this.intervalToFrequencyRatio(interval);
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Sampler} `this`
            +		 */
            +		Tone.Sampler.prototype.dispose = function(){
            +			Tone.Instrument.prototype.dispose.call(this);
            +			this.player.dispose();
            +			this.filterEnvelope.dispose();
            +			this.envelope.dispose();
            +			this.filter.dispose();
            +			this.player = null;
            +			this.filterEnvelope = null;
            +			this.envelope = null;
            +			this.filter = null;
            +			for (var sample in this._buffers){
            +				this._buffers[sample].dispose();
            +				this._buffers[sample] = null;
            +			}
            +			this._buffers = null;
            +			return this;
            +		};
            +
            +		return Tone.Sampler;
            +	});
            +
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Aggregates multiple Tone.Samplers into a single instrument.
            +		 *         Pass in a mapping of names to sample urls and an optional 
            +		 *         callback to invoke when all of the samples are loaded. 
            +		 *
            +		 *  ```javascript
            +		 *  var sampler = new Tone.MultiSampler({
            +		 *  	"kick" : "../audio/BD.mp3",
            +		 *  	"snare" : "../audio/SD.mp3",
            +		 *  	"hat" : "../audio/hh.mp3"
            +		 *  }, onload);
            +		 *  //once loaded...
            +		 *  sampler.triggerAttack("kick");
            +		 *  ```
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Instrument}
            +		 *  @param {Object} samples the samples used in this
            +		 *  @param {function} onload the callback to invoke when all 
            +		 *                           of the samples have been loaded
            +		 */
            +		Tone.MultiSampler = function(samples, onload){
            +
            +			console.warn("Tone.MultiSampler is deprecated - use Tone.PolySynth with Tone.Sampler as the voice");
            +		 	Tone.Instrument.call(this);
            +
            +		 	/**
            +		 	 *  the array of voices
            +		 	 *  @type {Tone.Sampler}
            +		 	 */
            +			this.samples = {};
            +
            +			//make the samples
            +			this._createSamples(samples, onload);
            +		};
            +
            +		Tone.extend(Tone.MultiSampler, Tone.Instrument);
            +
            +		/**
            +		 *  creates all of the samples and tracks their loading
            +		 *  
            +		 *  @param   {Object} samples the samples
            +		 *  @param   {function} onload  the onload callback
            +		 *  @private
            +		 */
            +		Tone.MultiSampler.prototype._createSamples = function(samples, onload){
            +			//object which tracks the number of loaded samples
            +			var loadCounter = {
            +				total : 0,
            +				loaded : 0
            +			};
            +			//get the count
            +			for (var s in samples){ //jshint ignore:line
            +				loadCounter.total++;
            +			}
            +			//the function to invoke when a sample is loaded
            +			var onSampleLoad = function(){
            +				loadCounter.loaded++;
            +				if (loadCounter.loaded === loadCounter.total){
            +					if (onload){
            +						onload();
            +					}
            +				}
            +			};
            +			for (var samp in samples){
            +				var url = samples[samp];
            +				var sampler = new Tone.Sampler(url, onSampleLoad);
            +				sampler.connect(this.output);
            +				this.samples[samp] = sampler;
            +			}
            +		};
            +
            +		/**
            +		 *  start a sample
            +		 *  
            +		 *  @param  {string} sample the note name to start
            +		 *  @param {Tone.Time} [time=now] the time when the note should start
            +		 *  @param {number} [velocity=1] the velocity of the note
            +		 */
            +		Tone.MultiSampler.prototype.triggerAttack = function(sample, time, velocity){
            +			if (this.samples.hasOwnProperty(sample)){
            +				this.samples[sample].triggerAttack(0, time, velocity);
            +			}
            +		};
            +
            +		/**
            +		 *  start the release portion of the note
            +		 *  
            +		 *  @param  {string} sample the note name to release
            +		 *  @param {Tone.Time} [time=now] the time when the note should release
            +		 */
            +		Tone.MultiSampler.prototype.triggerRelease = function(sample, time){
            +			if (this.samples.hasOwnProperty(sample)){
            +				this.samples[sample].triggerRelease(time);
            +			}
            +		};
            +
            +		/**
            +		  *  start the release portion of the note
            +		  *  
            +		  *  @param  {string} sample the note name to release
            +		  *  @param {Tone.Time} duration the duration of the note
            +		  *  @param {Tone.Time} [time=now] the time when the note should start
            +		  *  @param {number} [velocity=1] the velocity of the note
            +		  */
            +		Tone.MultiSampler.prototype.triggerAttackRelease = function(sample, duration, time, velocity){
            +			if (this.samples.hasOwnProperty(sample)){
            +				time = this.toSeconds(time);
            +				duration = this.toSeconds(duration);
            +				var samp = this.samples[sample];
            +				samp.triggerAttack(0, time, velocity);
            +				samp.triggerRelease(time + duration);
            +			}
            +		};
            +
            +		/**
            +		 *  sets all the samplers with these settings
            +		 *  @param {object} params the parameters to be applied 
            +		 *                         to all internal samplers
            +		 */
            +		Tone.MultiSampler.prototype.set = function(params){
            +			for (var samp in this.samples){
            +				this.samples[samp].set(params);
            +			}
            +		};
            +
            +		/**
            +		 *  clean up
            +		 */
            +		Tone.MultiSampler.prototype.dispose = function(){
            +			Tone.Instrument.prototype.dispose.call(this);
            +			for (var samp in this.samples){
            +				this.samples[samp].dispose();
            +				this.samples[samp] = null;
            +			}
            +			this.samples = null;
            +		};
            +
            +		return Tone.MultiSampler;
            +	});
            +
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Noise generator. 
            +		 *          Uses looped noise buffers to save on performance. 
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Source}
            +		 *  @param {string} type the noise type (white|pink|brown)
            +		 */
            +		Tone.Noise = function(){
            +
            +			var options = this.optionsObject(arguments, ["type"], Tone.Noise.defaults);
            +			Tone.Source.call(this, options);
            +
            +			/**
            +			 *  @private
            +			 *  @type {AudioBufferSourceNode}
            +			 */
            +			this._source = null;
            +			
            +			/**
            +			 *  the buffer
            +			 *  @private
            +			 *  @type {AudioBuffer}
            +			 */
            +			this._buffer = null;
            +
            +			this.type = options.type;
            +		};
            +
            +		Tone.extend(Tone.Noise, Tone.Source);
            +
            +		/**
            +		 *  the default parameters
            +		 *
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.Noise.defaults = {
            +			"type" : "white",
            +		};
            +
            +		/**
            +		 * The type of the noise. Can be "white", "brown", or "pink". 
            +		 * @memberOf Tone.Noise#
            +		 * @type {string}
            +		 * @name type
            +		 */
            +		Object.defineProperty(Tone.Noise.prototype, "type", {
            +			get : function(){
            +				if (this._buffer === _whiteNoise){
            +					return "white";
            +				} else if (this._buffer === _brownNoise){
            +					return "brown";
            +				} else if (this._buffer === _pinkNoise){
            +					return "pink";
            +				}
            +			}, 
            +			set : function(type){
            +				switch (type){
            +					case "white" : 
            +						this._buffer = _whiteNoise;
            +						break;
            +					case "pink" : 
            +						this._buffer = _pinkNoise;
            +						break;
            +					case "brown" : 
            +						this._buffer = _brownNoise;
            +						break;
            +					default : 
            +						this._buffer = _whiteNoise;
            +				}
            +				//if it's playing, stop and restart it
            +				if (this.state === Tone.Source.State.STARTED){
            +					var now = this.now() + this.bufferTime;
            +					//remove the listener
            +					this._source.onended = undefined;
            +					this._stop(now);
            +					this._start(now);
            +				}
            +			}
            +		});
            +
            +		/**
            +		 *  internal start method
            +		 *  
            +		 *  @param {Tone.Time} time
            +		 *  @private
            +		 */
            +		Tone.Noise.prototype._start = function(time){		
            +			this._source = this.context.createBufferSource();
            +			this._source.buffer = this._buffer;
            +			this._source.loop = true;
            +			this.connectSeries(this._source, this.output);
            +			this._source.start(this.toSeconds(time));
            +			this._source.onended = this.onended;
            +		};
            +
            +		/**
            +		 *  internal stop method
            +		 *  
            +		 *  @param {Tone.Time} time
            +		 *  @private
            +		 */
            +		Tone.Noise.prototype._stop = function(time){
            +			if (this._source){
            +				this._source.stop(this.toSeconds(time));
            +			}
            +		};
            +
            +		/**
            +		 *  dispose all the components
            +		 *  @returns {Tone.Noise} `this`
            +		 */
            +		Tone.Noise.prototype.dispose = function(){
            +			Tone.Source.prototype.dispose.call(this);
            +			if (this._source !== null){
            +				this._source.disconnect();
            +				this._source = null;
            +			}
            +			this._buffer = null;
            +			return this;
            +		};
            +
            +
            +		///////////////////////////////////////////////////////////////////////////
            +		// THE BUFFERS
            +		// borred heavily from http://noisehack.com/generate-noise-web-audio-api/
            +		///////////////////////////////////////////////////////////////////////////
            +
            +		/**
            +		 *	static noise buffers
            +		 *  
            +		 *  @static
            +		 *  @private
            +		 *  @type {AudioBuffer}
            +		 */
            +		var _pinkNoise = null, _brownNoise = null, _whiteNoise = null;
            +
            +		Tone._initAudioContext(function(audioContext){
            +
            +			var sampleRate = audioContext.sampleRate;
            +			
            +			//four seconds per buffer
            +			var bufferLength = sampleRate * 4;
            +
            +			//fill the buffers
            +			_pinkNoise = (function() {
            +				var buffer = audioContext.createBuffer(2, bufferLength, sampleRate);
            +				for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++){
            +					var channel = buffer.getChannelData(channelNum);
            +					var b0, b1, b2, b3, b4, b5, b6;
            +					b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;
            +					for (var i = 0; i < bufferLength; i++) {
            +						var white = Math.random() * 2 - 1;
            +						b0 = 0.99886 * b0 + white * 0.0555179;
            +						b1 = 0.99332 * b1 + white * 0.0750759;
            +						b2 = 0.96900 * b2 + white * 0.1538520;
            +						b3 = 0.86650 * b3 + white * 0.3104856;
            +						b4 = 0.55000 * b4 + white * 0.5329522;
            +						b5 = -0.7616 * b5 - white * 0.0168980;
            +						channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;
            +						channel[i] *= 0.11; // (roughly) compensate for gain
            +						b6 = white * 0.115926;
            +					}
            +				}
            +				return buffer;
            +			}());
            +
            +			_brownNoise = (function() {
            +				var buffer = audioContext.createBuffer(2, bufferLength, sampleRate);
            +				for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++){
            +					var channel = buffer.getChannelData(channelNum);
            +					var lastOut = 0.0;
            +					for (var i = 0; i < bufferLength; i++) {
            +						var white = Math.random() * 2 - 1;
            +						channel[i] = (lastOut + (0.02 * white)) / 1.02;
            +						lastOut = channel[i];
            +						channel[i] *= 3.5; // (roughly) compensate for gain
            +					}
            +				}
            +				return buffer;
            +			})();
            +
            +			_whiteNoise = (function(){
            +				var buffer = audioContext.createBuffer(2, bufferLength, sampleRate);
            +				for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++){
            +					var channel = buffer.getChannelData(channelNum);
            +					for (var i = 0; i < bufferLength; i++){
            +						channel[i] =  Math.random() * 2 - 1;
            +					}
            +				}
            +				return buffer;
            +			}());
            +		});
            +
            +		return Tone.Noise;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  the NoiseSynth is a single oscillator, monophonic synthesizer
            +		 *          with a filter, and two envelopes (on the filter and the amplitude)
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Instrument}
            +		 *  @param {Object} options the options available for the synth 
            +		 *                          see defaults below
            +		 */
            +		Tone.NoiseSynth = function(options){
            +
            +			//get the defaults
            +			options = this.defaultArg(options, Tone.NoiseSynth.defaults);
            +			Tone.Instrument.call(this);
            +
            +			/**
            +			 *  The noise source. Set the type by setting
            +			 *  `noiseSynth.noise.type`. 
            +			 *  @type {Tone.Noise}
            +			 */
            +			this.noise = new Tone.Noise();
            +
            +			/**
            +			 *  The filter .
            +			 *  @type {Tone.Filter}
            +			 */
            +			this.filter = new Tone.Filter(options.filter);
            +
            +			/**
            +			 *  The filter envelope. 
            +			 *  @type {Tone.Envelope}
            +			 */
            +			this.filterEnvelope = new Tone.ScaledEnvelope(options.filterEnvelope);
            +
            +			/**
            +			 *  The amplitude envelope. 
            +			 *  @type {Tone.Envelope}
            +			 */
            +			this.envelope = new Tone.AmplitudeEnvelope(options.envelope);
            +
            +			//connect the noise to the output
            +			this.noise.chain(this.filter, this.envelope, this.output);
            +			//start the noise
            +			this.noise.start();
            +			//connect the filter envelope
            +			this.filterEnvelope.connect(this.filter.frequency);
            +		};
            +
            +		Tone.extend(Tone.NoiseSynth, Tone.Instrument);
            +
            +		/**
            +		 *  @const
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.NoiseSynth.defaults = {
            +			"noise" : {
            +				"type" : "white"
            +			},
            +			"filter" : {
            +				"Q" : 6,
            +				"type" : "highpass",
            +				"rolloff" : -24
            +			},
            +			"envelope" : {
            +				"attack" : 0.005,
            +				"decay" : 0.1,
            +				"sustain" : 0.0,
            +			},
            +			"filterEnvelope" : {
            +				"attack" : 0.06,
            +				"decay" : 0.2,
            +				"sustain" : 0,
            +				"release" : 2,
            +				"min" : 20,
            +				"max" : 4000,
            +				"exponent" : 2
            +			}
            +		};
            +
            +		/**
            +		 *  start the attack portion of the envelope
            +		 *  @param {Tone.Time} [time=now] the time the attack should start
            +		 *  @param {number} [velocity=1] the velocity of the note (0-1)
            +		 *  @returns {Tone.NoiseSynth} `this`
            +		 */
            +		Tone.NoiseSynth.prototype.triggerAttack = function(time, velocity){
            +			//the envelopes
            +			this.envelope.triggerAttack(time, velocity);
            +			this.filterEnvelope.triggerAttack(time);	
            +			return this;	
            +		};
            +
            +		/**
            +		 *  start the release portion of the envelope
            +		 *  @param {Tone.Time} [time=now] the time the release should start
            +		 *  @returns {Tone.NoiseSynth} `this`
            +		 */
            +		Tone.NoiseSynth.prototype.triggerRelease = function(time){
            +			this.envelope.triggerRelease(time);
            +			this.filterEnvelope.triggerRelease(time);
            +			return this;
            +		};
            +
            +		/**
            +		 *  trigger the attack and then the release
            +		 *  @param  {Tone.Time} duration the duration of the note
            +		 *  @param  {Tone.Time} [time=now]     the time of the attack
            +		 *  @param  {number} [velocity=1] the velocity
            +		 *  @returns {Tone.NoiseSynth} `this`
            +		 */
            +		Tone.NoiseSynth.prototype.triggerAttackRelease = function(duration, time, velocity){
            +			time = this.toSeconds(time);
            +			duration = this.toSeconds(duration);
            +			this.triggerAttack(time, velocity);
            +			console.log(time + duration);
            +			this.triggerRelease(time + duration);
            +			return this;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.NoiseSynth} `this`
            +		 */
            +		Tone.NoiseSynth.prototype.dispose = function(){
            +			Tone.Instrument.prototype.dispose.call(this);
            +			this.noise.dispose();
            +			this.noise = null;
            +			this.envelope.dispose();
            +			this.envelope = null;
            +			this.filterEnvelope.dispose();
            +			this.filterEnvelope = null;
            +			this.filter.dispose();
            +			this.filter = null;
            +			return this;
            +		};
            +
            +		return Tone.NoiseSynth;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Karplus-String string synthesis. 
            +		 *  
            +		 *  @constructor
            +		 *  @extends {Tone.Instrument}
            +		 *  @param {Object} options see the defaults
            +		 */
            +		Tone.PluckSynth = function(options){
            +
            +			options = this.defaultArg(options, Tone.PluckSynth.defaults);
            +			Tone.Instrument.call(this);
            +
            +			/**
            +			 *  @type {Tone.Noise}
            +			 *  @private
            +			 */
            +			this._noise = new Tone.Noise("pink");
            +
            +			/**
            +			 *  The amount of noise at the attack. 
            +			 *  Nominal range of [0.1, 20]
            +			 *  @type {number}
            +			 */
            +			this.attackNoise = 1;
            +
            +			/**
            +			 *  the LFCF
            +			 *  @type {Tone.LowpassCombFilter}
            +			 *  @private
            +			 */
            +			this._lfcf = new Tone.LowpassCombFilter(1 / 440);
            +
            +			/**
            +			 *  the resonance control
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.resonance = this._lfcf.resonance;
            +
            +			/**
            +			 *  the dampening control. i.e. the lowpass filter frequency of the comb filter
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.dampening = this._lfcf.dampening;
            +
            +			//connections
            +			this._noise.connect(this._lfcf);
            +			this._lfcf.connect(this.output);
            +		};
            +
            +		Tone.extend(Tone.PluckSynth, Tone.Instrument);
            +
            +		/**
            +		 *  @static
            +		 *  @const
            +		 *  @type {Object}
            +		 */
            +		Tone.PluckSynth.defaults = {
            +			"attackNoise" : 1,
            +			"dampening" : 4000,
            +			"resonance" : 0.5
            +		};
            +
            +		/**
            +		 *  trigger the attack portion
            +		 *  @param {string|number} note the note name or frequency
            +		 *  @param {Tone.Time} [time=now] the time of the note
            +		 *  @returns {Tone.PluckSynth} `this`
            +		 */
            +		Tone.PluckSynth.prototype.triggerAttack = function(note, time) {
            +			note = this.toFrequency(note);
            +			time = this.toSeconds(time);
            +			var delayAmount = 1 / note;
            +			this._lfcf.setDelayTimeAtTime(delayAmount, time);		
            +			this._noise.start(time);
            +			this._noise.stop(time + delayAmount * this.attackNoise);
            +			return this;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.PluckSynth} `this`
            +		 */
            +		Tone.PluckSynth.prototype.dispose = function(){
            +			Tone.Instrument.prototype.dispose.call(this);
            +			this._noise.dispose();
            +			this._lfcf.dispose();
            +			this._noise = null;
            +			this._lfcf = null;
            +			this.dampening = null;
            +			this.resonance = null;
            +			return this;
            +		};
            +
            +		return Tone.PluckSynth;
            +	});
            +	toneModule( 
            +	function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  Creates a polyphonic synthesizer out of 
            +		 *          the monophonic voice which is passed in. 
            +		 *
            +		 *  ```javascript
            +		 *  //a polysynth composed of 6 Voices of MonoSynth
            +		 *  var synth = new Tone.PolySynth(6, Tone.MonoSynth);
            +		 *  //set a MonoSynth preset
            +		 *  synth.setPreset("Pianoetta");
            +		 *  ```
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Instrument}
            +		 *  @param {number|Object} [polyphony=4] the number of voices to create
            +		 *  @param {function} [voice=Tone.MonoSynth] the constructor of the voices
            +		 *                                            uses Tone.MonoSynth by default
            +		 *  @param {Object} voiceOptions the options to pass to the voice                                          
            +		 */
            +		Tone.PolySynth = function(){
            +
            +			Tone.Instrument.call(this);
            +
            +			var options = this.optionsObject(arguments, ["polyphony", "voice", "voiceOptions"], Tone.PolySynth.defaults);
            +
            +			/**
            +			 *  the array of voices
            +			 *  @type {Array}
            +			 */
            +			this.voices = new Array(options.polyphony);
            +
            +			/**
            +			 *  the queue of free voices
            +			 *  @private
            +			 *  @type {Array}
            +			 */
            +			this._freeVoices = [];
            +
            +			/**
            +			 *  keeps track of which notes are down
            +			 *  @private
            +			 *  @type {Object}
            +			 */
            +			this._activeVoices = {};
            +
            +			//create the voices
            +			for (var i = 0; i < options.polyphony; i++){
            +				var v = new options.voice(options.voiceOptions);
            +				this.voices[i] = v;
            +				v.connect(this.output);
            +			}
            +
            +			//make a copy of the voices
            +			this._freeVoices = this.voices.slice(0);
            +		};
            +
            +		Tone.extend(Tone.PolySynth, Tone.Instrument);
            +
            +		/**
            +		 *  the defaults
            +		 *  @const
            +		 *  @static
            +		 *  @type {Object}
            +		 */
            +		Tone.PolySynth.defaults = {
            +			"polyphony" : 4,
            +			"voice" : Tone.MonoSynth,
            +			"voiceOptions" : {
            +				"portamento" : 0
            +			}
            +		};
            +
            +		/**
            +		 *  trigger the attack
            +		 *  @param  {string|number|Object|Array} value the value of the note(s) to start.
            +		 *                                             if the value is an array, it will iterate
            +		 *                                             over the array to play each of the notes
            +		 *  @param  {Tone.Time} [time=now]  the start time of the note
            +		 *  @param {number} [velocity=1] the velocity of the note
            +		 *  @returns {Tone.PolySynth} `this`
            +		 */
            +		Tone.PolySynth.prototype.triggerAttack = function(value, time, velocity){
            +			if (!Array.isArray(value)){
            +				value = [value];
            +			}
            +			for (var i = 0; i < value.length; i++){
            +				var val = value[i];
            +				var stringified = JSON.stringify(val);
            +				if (this._activeVoices[stringified]){
            +					this._activeVoices[stringified].triggerAttack(val, time, velocity);
            +				} else if (this._freeVoices.length > 0){
            +					var voice = this._freeVoices.shift();
            +					voice.triggerAttack(val, time, velocity);
            +					this._activeVoices[stringified] = voice;
            +				}
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  trigger the attack and release after the specified duration
            +		 *  
            +		 *  @param  {string|number|Object|Array} value the note(s).
            +		 *                                             if the value is an array, it will iterate
            +		 *                                             over the array to play each of the notes
            +		 *  @param  {Tone.Time} duration the duration of the note
            +		 *  @param  {Tone.Time} [time=now]     if no time is given, defaults to now
            +		 *  @param  {number} [velocity=1] the velocity of the attack (0-1)
            +		 *  @returns {Tone.PolySynth} `this`
            +		 */
            +		Tone.PolySynth.prototype.triggerAttackRelease = function(value, duration, time, velocity){
            +			time = this.toSeconds(time);
            +			this.triggerAttack(value, time, velocity);
            +			this.triggerRelease(value, time + this.toSeconds(duration));
            +			return this;
            +		};
            +
            +		/**
            +		 *  trigger the release of a note
            +		 *  @param  {string|number|Object|Array} value the value of the note(s) to release.
            +		 *                                             if the value is an array, it will iterate
            +		 *                                             over the array to play each of the notes
            +		 *  @param  {Tone.Time} [time=now]  the release time of the note
            +		 *  @returns {Tone.PolySynth} `this`
            +		 */
            +		Tone.PolySynth.prototype.triggerRelease = function(value, time){
            +			if (!Array.isArray(value)){
            +				value = [value];
            +			}
            +			for (var i = 0; i < value.length; i++){
            +				//get the voice
            +				var stringified = JSON.stringify(value[i]);
            +				var voice = this._activeVoices[stringified];
            +				if (voice){
            +					voice.triggerRelease(time);
            +					this._freeVoices.push(voice);
            +					this._activeVoices[stringified] = null;
            +				}
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  set the options on all of the voices
            +		 *  @param {Object} params 
            +		 *  @returns {Tone.PolySynth} `this`
            +		 */
            +		Tone.PolySynth.prototype.set = function(params){
            +			for (var i = 0; i < this.voices.length; i++){
            +				this.voices[i].set(params);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  @param {string} presetName the preset name
            +		 *  @returns {Tone.PolySynth} `this`
            +		 */
            +		Tone.PolySynth.prototype.setPreset = function(presetName){
            +			for (var i = 0; i < this.voices.length; i++){
            +				this.voices[i].setPreset(presetName);
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.PolySynth} `this`
            +		 */
            +		Tone.PolySynth.prototype.dispose = function(){
            +			Tone.Instrument.prototype.dispose.call(this);
            +			for (var i = 0; i < this.voices.length; i++){
            +				this.voices[i].dispose();
            +				this.voices[i] = null;
            +			}
            +			this.voices = null;
            +			this._activeVoices = null;
            +			this._freeVoices = null;
            +			return this;
            +		};
            +
            +		return Tone.PolySynth;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 * 	@class  Clip the incoming signal so that the output is always between min and max
            +		 * 	
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} min the minimum value of the outgoing signal
            +		 *  @param {number} max the maximum value of the outgoing signal
            +		 */
            +		Tone.Clip = function(min, max){
            +			//make sure the args are in the right order
            +			if (min > max){
            +				var tmp = min;
            +				min = max;
            +				max = tmp;
            +			}
            +			
            +			/**
            +			 *  the min clipper
            +			 *  @type {Tone.Min}
            +			 *  @private
            +			 */
            +			this._min = this.input = new Tone.Min(max);
            +
            +			/**
            +			 *  the max clipper
            +			 *  @type {Tone.Max}
            +			 *  @private
            +			 */
            +			this._max = this.output = new Tone.Max(min);
            +
            +			this._min.connect(this._max);
            +		};
            +
            +		Tone.extend(Tone.Clip, Tone.SignalBase);
            +
            +		/**
            +		 * The minimum value which Clip will output.
            +		 * @memberOf Tone.Clip#
            +		 * @type {number}
            +		 * @name min
            +		 */
            +		Object.defineProperty(Tone.Clip.prototype, "min", {
            +			get : function(){
            +				return this._min.value;
            +			},
            +			set : function(min){
            +				this._min.value = min;
            +			}
            +		});
            +
            +		/**
            +		 * The maximum value which Clip will output.
            +		 * @memberOf Tone.Clip#
            +		 * @type {number}
            +		 * @name max
            +		 */
            +		Object.defineProperty(Tone.Clip.prototype, "max", {
            +			get : function(){
            +				return this._max.value;
            +			},
            +			set : function(max){
            +				this._max.value = max;
            +			}
            +		});
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Clip} `this`
            +		 */
            +		Tone.Clip.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._min.dispose();
            +			this._min = null;
            +			this._max.dispose();
            +			this._max = null;
            +			return this;
            +		};
            +
            +		return Tone.Clip;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Normalize takes an input min and max and maps it linearly to [0,1]
            +		 *
            +		 *  @extends {Tone.SignalBase}
            +		 *  @constructor
            +		 */
            +		Tone.Normalize = function(inputMin, inputMax){
            +
            +			/**
            +			 *  the min input value
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._inputMin = this.defaultArg(inputMin, 0);
            +
            +			/**
            +			 *  the max input value
            +			 *  @type {number}
            +			 *  @private
            +			 */
            +			this._inputMax = this.defaultArg(inputMax, 1);
            +
            +			/**
            +			 *  subtract the min from the input
            +			 *  @type {Tone.Add}
            +			 *  @private
            +			 */
            +			this._sub = this.input = new Tone.Add(0);
            +
            +			/**
            +			 *  divide by the difference between the input and output
            +			 *  @type {Tone.Multiply}
            +			 *  @private
            +			 */
            +			this._div = this.output = new Tone.Multiply(1);
            +
            +			this._sub.connect(this._div);
            +			this._setRange();
            +		};
            +
            +		Tone.extend(Tone.Normalize, Tone.SignalBase);
            +
            +		/**
            +		 * The minimum value the input signal will reach.
            +		 * @memberOf Tone.Normalize#
            +		 * @type {number}
            +		 * @name min
            +		 */
            +		Object.defineProperty(Tone.Normalize.prototype, "min", {
            +			get : function(){
            +				return this._inputMin;
            +			},
            +			set : function(min){
            +				this._inputMin = min;
            +				this._setRange();
            +			}
            +		});
            +
            +		/**
            +		 * The maximum value the input signal will reach.
            +		 * @memberOf Tone.Normalize#
            +		 * @type {number}
            +		 * @name max
            +		 */
            +		Object.defineProperty(Tone.Normalize.prototype, "max", {
            +			get : function(){
            +				return this._inputMax;
            +			},
            +			set : function(max){
            +				this._inputMax = max;
            +				this._setRange();
            +			}
            +		});
            +
            +		/**
            +		 *  set the values
            +		 *  @private
            +		 */
            +		Tone.Normalize.prototype._setRange = function() {
            +			this._sub.value = -this._inputMin;
            +			this._div.value = 1 / (this._inputMax - this._inputMin);
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Normalize} `this`
            +		 */
            +		Tone.Normalize.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this._sub.dispose();
            +			this._sub = null;
            +			this._div.dispose();
            +			this._div = null;
            +			return this;
            +		};
            +
            +		return Tone.Normalize;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class Route a single input to the specified output
            +		 *
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 *  @param {number} [outputCount=2] the number of inputs the switch accepts
            +		 */
            +		Tone.Route = function(outputCount){
            +
            +			outputCount = this.defaultArg(outputCount, 2);
            +			Tone.call(this, 1, outputCount);
            +
            +			/**
            +			 *  the control signal
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.gate = new Tone.Signal(0);
            +
            +			//make all the inputs and connect them
            +			for (var i = 0; i < outputCount; i++){
            +				var routeGate = new RouteGate(i);
            +				this.output[i] = routeGate;
            +				this.gate.connect(routeGate.selecter);
            +				this.input.connect(routeGate);
            +			}
            +		};
            +
            +		Tone.extend(Tone.Route, Tone.SignalBase);
            +
            +		/**
            +		 *  routes the signal to one of the outputs and close the others
            +		 *  @param {number} [which=0] open one of the gates (closes the other)
            +		 *  @param {Tone.Time} time the time when the switch will open
            +		 *  @returns {Tone.Route} `this`
            +		 */
            +		Tone.Route.prototype.select = function(which, time){
            +			//make sure it's an integer
            +			which = Math.floor(which);
            +			this.gate.setValueAtTime(which, this.toSeconds(time));
            +			return this;
            +		};
            +
            +		/**
            +		 *  dispose method
            +		 *  @returns {Tone.Route} `this`
            +		 */
            +		Tone.Route.prototype.dispose = function(){
            +			this.gate.dispose();
            +			for (var i = 0; i < this.output.length; i++){
            +				this.output[i].dispose();
            +				this.output[i] = null;
            +			}
            +			Tone.prototype.dispose.call(this);
            +			this.gate = null;
            +			return this;
            +		}; 
            +
            +		////////////START HELPER////////////
            +
            +		/**
            +		 *  helper class for Tone.Route representing a single gate
            +		 *  @constructor
            +		 *  @extends {Tone}
            +		 *  @internal only used by Tone.Route
            +		 */
            +		var RouteGate = function(num){
            +
            +			/**
            +			 *  the selector
            +			 *  @type {Tone.Equal}
            +			 */
            +			this.selecter = new Tone.Equal(num);
            +
            +			/**
            +			 *  the gate
            +			 *  @type {GainNode}
            +			 */
            +			this.gate = this.input = this.output = this.context.createGain();
            +
            +			//connect the selecter to the gate gain
            +			this.selecter.connect(this.gate.gain);
            +		};
            +
            +		Tone.extend(RouteGate);
            +
            +		/**
            +		 *  clean up
            +		 *  @private
            +		 */
            +		RouteGate.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.selecter.dispose();
            +			this.gate.disconnect();
            +			this.selecter = null;
            +			this.gate = null;
            +		};
            +
            +		////////////END HELPER////////////
            +
            +		//return Tone.Route
            +		return Tone.Route;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  When the gate is set to 0, the input signal does not pass through to the output. 
            +		 *          If the gate is set to 1, the input signal passes through.
            +		 *          the gate is initially closed.
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.SignalBase}
            +		 */
            +		Tone.Switch = function(){
            +			Tone.call(this);
            +
            +			/**
            +			 *  the control signal for the switch
            +			 *  when this value is 0, the input signal will not pass through,
            +			 *  when it is high (1), the input signal will pass through.
            +			 *  
            +			 *  @type {Tone.Signal}
            +			 */
            +			this.gate = new Tone.Signal(0);
            +
            +			/**
            +			 *  thresh the control signal to either 0 or 1
            +			 *  @type {Tone.GreaterThan}
            +			 *  @private
            +			 */
            +			this._thresh = new Tone.GreaterThan(0.5);
            +
            +			this.input.connect(this.output);
            +			this.gate.chain(this._thresh, this.output.gain);
            +		};
            +
            +		Tone.extend(Tone.Switch, Tone.SignalBase);
            +
            +		/**
            +		 *  open the switch at a specific time
            +		 *
            +		 *  @param {Tone.Time} time the time when the switch will be open
            +		 *  @returns {Tone.Switch} `this`
            +		 */
            +		Tone.Switch.prototype.open = function(time){
            +			this.gate.setValueAtTime(1, this.toSeconds(time));
            +			return this;
            +		}; 
            +
            +		/**
            +		 *  close the switch at a specific time
            +		 *
            +		 *  @param {Tone.Time} time the time when the switch will be open
            +		 *  @returns {Tone.Switch} `this`
            +		 */
            +		Tone.Switch.prototype.close = function(time){
            +			this.gate.setValueAtTime(0, this.toSeconds(time));
            +			return this;
            +		}; 
            +
            +		/**
            +		 *  clean up
            +		 *  @returns {Tone.Switch} `this`
            +		 */
            +		Tone.Switch.prototype.dispose = function(){
            +			Tone.prototype.dispose.call(this);
            +			this.gate.dispose();
            +			this._thresh.dispose();
            +			this.gate = null;
            +			this._thresh = null;
            +			return this;
            +		}; 
            +
            +		return Tone.Switch;
            +	});
            +	toneModule( function(Tone){
            +
            +		
            +
            +		/**
            +		 *  @class  WebRTC Microphone. 
            +		 *          CHROME ONLY (for now) because of the 
            +		 *          use of the MediaStreamAudioSourceNode
            +		 *
            +		 *  @constructor
            +		 *  @extends {Tone.Source}
            +		 *  @param {number=} inputNum 
            +		 */
            +		Tone.Microphone = function(inputNum){
            +			Tone.Source.call(this);
            +
            +			/**
            +			 *  @type {MediaStreamAudioSourceNode}
            +			 *  @private
            +			 */
            +			this._mediaStream = null;
            +			
            +			/**
            +			 *  @type {LocalMediaStream}
            +			 *  @private
            +			 */
            +			this._stream = null;
            +			
            +			/**
            +			 *  @type {Object}
            +			 *  @private
            +			 */
            +			this._constraints = {"audio" : true};
            +
            +			//get the option
            +			var self = this;
            +			MediaStreamTrack.getSources(function (media_sources) {
            +				if (inputNum < media_sources.length){
            +					self.constraints.audio = {
            +						optional : [{ sourceId: media_sources[inputNum].id}]
            +					};
            +				}
            +			});		
            +		};
            +
            +		Tone.extend(Tone.Microphone, Tone.Source);
            +
            +		/**
            +		 *  start the stream. 
            +		 *  @returns {Tone.Microphone} `this`
            +		 */
            +		Tone.Microphone.prototype.start = function(){
            +			if (this.state === Tone.Source.State.STOPPED){
            +				this.state = Tone.Source.State.STARTED;
            +					navigator.getUserMedia(this._constraints, 
            +						this._onStream.bind(this), this._onStreamError.bind(this));
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  stop the stream. 
            +		 *  @returns {Tone.Microphone} `this`
            +		 */
            +		Tone.Microphone.prototype.stop = function(){
            +			if (this._stream && this.state === Tone.Source.State.STARTED){
            +				this.state = Tone.Source.State.STOPPED;
            +				this._stream.stop();
            +			}
            +			return this;
            +		};
            +
            +		/**
            +		 *  called when the stream is successfully setup
            +		 *  @param   {LocalMediaStream} stream 
            +		 *  @private
            +		 */
            +		Tone.Microphone.prototype._onStream = function(stream) {
            +			this._stream = stream;
            +			// Wrap a MediaStreamSourceNode around the live input stream.
            +			this._mediaStream = this.context.createMediaStreamSource(stream);
            +			this._mediaStream.connect(this.output);
            +		};
            +
            +		/**
            +		 *  called on error
            +		 *  @param   {Error} e 
            +		 *  @private
            +		 */
            +		Tone.Microphone.prototype._onStreamError = function(e) {
            +			console.error(e);
            +		};
            +
            +		/**
            +		 *  clean up
            +		 *  @return {Tone.Microphone} `this`
            +		 */
            +		Tone.Microphone.prototype.dispose = function() {
            +			Tone.Source.prototype.dispose.call(this);
            +			if (this._mediaStream){
            +				this._mediaStream.disconnect();
            +				this._mediaStream = null;
            +			}
            +			this._stream = null;
            +			this._constraints = null;
            +			return this;
            +		};
            +
            +		//polyfill
            +		navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || 
            +			navigator.mozGetUserMedia || navigator.msGetUserMedia;
            +
            +		return Tone.Microphone;
            +	});
            +
            +	//requirejs compatibility
            +	if ( typeof define === "function" && define.amd ) {
            +		define( "Tone", [], function() {
            +			return Tone;
            +		});
            +	} else {
            +		root.Tone = Tone;
            +	}
            +} (this));
            diff --git a/dist/assets/p5_featured/15May_AV/src/Visualizer.js b/dist/assets/p5_featured/15May_AV/src/Visualizer.js
            new file mode 100644
            index 0000000000..55b5f109a6
            --- /dev/null
            +++ b/dist/assets/p5_featured/15May_AV/src/Visualizer.js
            @@ -0,0 +1,142 @@
            +var Visualizer = function(){
            +    this.mSplashSystem = new SplashSystem();
            +    
            +    this.windowWidth = window.innerWidth;
            +    this.windowHeight = window.innerHeight;
            +    
            +    this.defaultYpos = Math.random() * -60 - 30;
            +    
            +    this.newInterval;
            +    
            +    this.droplet;
            +    this.loc = new p5.Vector(Math.random() * this.windowWidth, this.defaultYpos);
            +    this.vel = new p5.Vector(0, 0);
            +    this.rotation = 0;
            +    this.gravity = new p5.Vector(0, 1);
            +    this.wind = new p5.Vector(0, 0);  
            +    this.sizeOffset;
            +    this.defaultSizeX;
            +    this.defaultSizeY;
            +    this.sizeX;
            +    this.sizeY;
            +    
            +    this.isDead = false;
            +};
            +    
            +Visualizer.prototype.setup = function(){
            +    this.droplet = loadImage("image/droplet.png");
            +    this.getNewSize();
            +    this.getGravity();
            +};
            +
            +Visualizer.prototype.returnWindowWidth = function(){
            +    return this.windowWidth;
            +};
            +
            +Visualizer.prototype.returnWindowHeight = function(){
            +    return this.windowHeight;
            +};
            +
            +Visualizer.prototype.getNewSize = function(){
            +    this.sizeOffset = Math.random();
            +    this.defaultSizeX = this.sizeOffset * 79 / 3 + 5;
            +    this.defaultSizeY = this.sizeOffset * 116 / 3 + 5;
            +    this.sizeX = this.defaultSizeX;
            +    this.sizeY = this.defaultSizeY;
            +//    this.isDead = false;
            +};
            +
            +Visualizer.prototype.getGravity = function(){
            +    this.gravity.y = 1 * this.sizeX * 0.02 + 0.5;
            +};
            +
            +Visualizer.prototype.getNewInterval = function(newInterval){
            +    this.newInterval = newInterval;
            +    
            +    this.setDynamicValues();
            +}
            +
            +Visualizer.prototype.setDynamicValues = function(){
            +//    this.gravity.y = Math.abs(3 - (1 - this.newInterval)) * this.sizeX * 0.02 + 0.5;
            +    this.gravity.y = Math.abs(1/(this.newInterval*3)) * this.sizeX * 0.02 + 0.5;
            +    this.wind.x = Math.abs(this.newInterval - 1.0);
            +}
            +
            +Visualizer.prototype.detectCol = function(){
            +    //make droplet drop on certain section of window (from 40% of height to 90% of height)
            +    if(this.loc.y > Math.random() * this.windowHeight * 0.5 + this.windowHeight * 0.7){
            +        this.isDead = true;
            +        
            +        this.mSplashSystem.reset(this.loc.x, this.loc.y);
            +        
            +        this.loc.x = Math.random() * this.windowWidth;
            +        this.loc.y = this.defaultYpos;
            +        
            +        this.vel.y = 0;
            +        
            +        this.getNewSize();
            +    }    
            +};
            +
            +Visualizer.prototype.returnTrigger = function(){
            +    if( this.isDead ){
            +        this.isDead = false;
            +        return true; 
            +    } else {
            +        return false;
            +    }
            +};
            +
            +Visualizer.prototype.update = function(){
            +    this.vel.add(this.gravity);
            +    this.vel.add(this.wind);
            +    
            +    this.loc.add(this.vel);
            +    this.mSplashSystem.render();
            +    
            +    this.reCalDynamicValues();
            +    this.detectCol();
            +};
            +
            +Visualizer.prototype.reCalDynamicValues = function(){
            +    //reset vel's wind
            +    if(this.vel.x > 0 ){
            +        this.vel.x -= 0.8;
            +    } else if(this.vel.x < 0){
            +        this.vel.x = 0;
            +    } else if(this.vel.x > 1){
            +        this.vel.x = 1; //restrict value
            +    }
            +    
            +    //set rotation
            +    if(this.vel.x > 0.1){
            +        this.rotation -= 0.5;
            +        if(this.rotation < -45){
            +            this.rotation = -45;   
            +        }
            +    } else if (this.vel.x < 0.1) {
            +        this.rotation += 4;
            +        if(this.rotation > 0){
            +            this.rotation = 0;   
            +        }
            +    }
            +    
            +    //reset vel's gravity
            +    if(this.vel.y > 3){
            +        this.vel.y -= 0.5;
            +    } else if (this.vel.y < 0.5){
            +        this.vel.y = 0.5;
            +    }
            +};
            +    
            +Visualizer.prototype.draw = function(){
            +    push();
            +    {
            +        translate(this.loc.x, this.loc.y);
            +        rotate(this.rotation);
            +        image(this.droplet, 0, 0, this.sizeX, this.sizeY);
            +    }
            +    pop();
            +};
            +    
            +    
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book1.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book1.png
            new file mode 100644
            index 0000000000..be2022623f
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book1.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book2.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book2.png
            new file mode 100644
            index 0000000000..de4cf902ea
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book2.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book3.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book3.png
            new file mode 100644
            index 0000000000..a8ae415793
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book3.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book4.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book4.png
            new file mode 100644
            index 0000000000..19c16759e8
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book4.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book5.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book5.png
            new file mode 100644
            index 0000000000..27cf1a2f01
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/book5.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/handone.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/handone.png
            new file mode 100644
            index 0000000000..ebe4852ca4
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/handone.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/handtwo.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/handtwo.png
            new file mode 100644
            index 0000000000..bbe3396d67
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/handtwo.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/index.html b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/index.html
            new file mode 100644
            index 0000000000..6f62b43a26
            --- /dev/null
            +++ b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/index.html
            @@ -0,0 +1,11 @@
            +<!DOCTYPE html>
            +  <head>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.dom.min.js"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.sound.min.js"></script>
            +    <link rel="stylesheet" type="text/css" href="style.css">
            +  </head>
            +  <body>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/malala.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/malala.png
            new file mode 100644
            index 0000000000..b25019393c
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/malala.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/mouth1.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/mouth1.png
            new file mode 100644
            index 0000000000..90d5adb13e
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/mouth1.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/mouth2.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/mouth2.png
            new file mode 100644
            index 0000000000..d891f263f6
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/mouth2.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/mouth3.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/mouth3.png
            new file mode 100644
            index 0000000000..c5fea62ef4
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/mouth3.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen.png
            new file mode 100644
            index 0000000000..67254e975c
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen1.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen1.png
            new file mode 100644
            index 0000000000..a316a217cf
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen1.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen2.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen2.png
            new file mode 100644
            index 0000000000..77e5fe7858
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen2.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen3.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen3.png
            new file mode 100644
            index 0000000000..0c0ae90fa3
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen3.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen4.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen4.png
            new file mode 100644
            index 0000000000..ce01a7b0dc
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen4.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen5.png b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen5.png
            new file mode 100644
            index 0000000000..5246389e6f
            Binary files /dev/null and b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/pen5.png differ
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/sketch.js b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/sketch.js
            new file mode 100644
            index 0000000000..ae7a2c9e79
            --- /dev/null
            +++ b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/sketch.js
            @@ -0,0 +1,121 @@
            +var malala;
            +var book = [];
            +var pen = [];
            +var child = [];
            +var teacher = [];
            +
            +var scene = 1;
            +var font;
            +
            +function preload() {
            +  font = loadFont("Inconsolata.otf");
            +  malala = loadImage("malala.png");
            +quote = "Let us remember:   One book, one pen, one child, and one teacher can change the world - Malala Yousafzai";
            +
            +  
            +  book[0] = loadImage("book1.png");
            +  book[1] = loadImage("book2.png");
            +  book[2] = loadImage("book3.png");
            +  book[3] = loadImage("book4.png");
            +  book[4] = loadImage("book5.png");
            +
            +  pen[0] = loadImage("pen.png");
            +  pen[1] = loadImage("pen1.png");
            +  pen[2] = loadImage("pen2.png");
            +  pen[3] = loadImage("pen3.png");
            +  pen[4] = loadImage("pen4.png");
            +  pen[5] = loadImage("pen5.png");
            +  
            +  
            +  child[0] = loadImage("handone.png");
            +  child[1] = loadImage("handtwo.png");
            +
            +  teacher[0] = loadImage("mouth1.png");
            +  teacher[1] = loadImage("mouth2.png");
            +  teacher[2] = loadImage("mouth3.png");
            +
            +
            +}
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  imageMode(CENTER);
            +  noCursor();
            +}
            +
            +function draw() {
            +  clear();
            +  noStroke();  
            +    
            +  if (scene == 1) {
            +    textSize(25);
            +    textFont(font);
            +    fill('#68c7b7');
            +    text("Click the screen to change image.", windowWidth*0.5, 100);
            +  }
            +  
            +  // Opening book
            +  if (scene == 2) {
            +    frame = int(map(mouseX, 0, width, 0, book.length));
            +    frame = int(constrain(frame, 0, book.length));
            +    for (var c = 0; c < windowWidth - 50; c += 100) {
            +      for (var d = 0; d < windowHeight; d += 100)
            +        image(book[frame], c + 15, d + 50, 50, 50);
            +    }
            +  }
            +
            +  // Flowing pen
            +  if (scene == 3) {
            +    frame = int(map(mouseX, 0, width, 0, pen.length));
            +    frame = int(constrain(frame, 0, pen.length));
            +    for (var x = 0; x < windowWidth - 50; x += 100) {
            +      for (var y = 0; y < windowHeight; y += 100)
            +        image(pen[frame], x + 15, y + 50, 50, 50);
            +    }
            +  }
            +
            +  // Child's hand
            +  if (scene == 4) {
            +    frame = int(map(mouseX, 0, width, 0, child.length));
            +    frame = int(constrain(frame, 0, child.length));
            +    for (var a = 0; a < windowWidth - 50; a += 100) {
            +      for (var b = 0; b < windowHeight; b += 100)
            +        image(child[frame], a + 15, b + 50, 50, 50);
            +    }
            +  }
            +
            +  // Teacher's voice
            +  if (scene == 5) {
            +    frame = int(map(mouseX, 0, width, 0, teacher.length));
            +    frame = int(constrain(frame, 0, teacher.length));
            +    for (var i = 0; i < windowWidth - 50; i += 100) {
            +      for (var j = 0; j < windowHeight; j += 100)
            +        image(teacher[frame], i + 15, j + 50, 50, 50);
            +    }
            +  }
            +    image(malala, 175, windowHeight * 0.70, 1000, 1000);
            +    fill(246,144,101);
            +    textSize(20);
            +    text(quote, windowWidth-200, windowHeight/2-50, 150, 500);
            +    fill(255,255,153,50);
            +  ellipse(mouseX,mouseY,80,80);
            +	fill(255,255,153,150);
            +  ellipse(mouseX,mouseY,50,50);
            +  ellipse(mouseX,mouseY,15,15);
            +  fill("#ffff32");
            +  ellipse(mouseX,mouseY,10,10);
            +}
            +
            +function mousePressed() {
            +  if (scene == 1) {
            +    scene = 2;
            +  } else if (scene == 2) {
            +    scene = 3;
            +  } else if (scene == 3) {
            +    scene = 4;
            +  } else if (scene == 4) {
            +    scene = 5;
            +  }	else if (scene == 5) {
            +    scene = 2;
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/style.css b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/style.css
            new file mode 100644
            index 0000000000..57c14ee231
            --- /dev/null
            +++ b/dist/assets/p5_featured/ChellyJin_HaolinFang_MalalaWomensDay/style.css
            @@ -0,0 +1,4 @@
            +html, body {
            +  margin: 0;
            +  padding: 0;
            +}
            diff --git a/dist/assets/p5_featured/ChirsMill_AuroraII/AuroraII-p5front.js b/dist/assets/p5_featured/ChirsMill_AuroraII/AuroraII-p5front.js
            new file mode 100644
            index 0000000000..eb21315683
            --- /dev/null
            +++ b/dist/assets/p5_featured/ChirsMill_AuroraII/AuroraII-p5front.js
            @@ -0,0 +1,260 @@
            +/*
            +  Aurora II - modified for p5.js homepage June 25th,2015
            +  (2015, digital/live sculpture, pixel accumulation)
            +  Christopher Eugene Mills
            +
            +  License at bottom.
            + */
            +
            +//Switches
            +var genCoord = false;
            +var controlAmp = false;
            +
            +var motion = true;
            +var randir = true;
            +
            +var blur = true;
            +var timed = true;
            +
            +//NoiseField
            +var p = []; //4
            +var s1 = []; //numlines
            +var s2 = []; //numlines
            +var lines = []; //numlines
            +
            +var numlines = 80;
            +var reslines = 20;
            +var amplitude = 0;
            +var maxAmp = 280;
            +var minAmp = 35;
            +var safeAmp = 3;
            +var edgeCalm = 0; //1.4
            +
            +var lineRes = 0.15;
            +var stepRes = 0.041;
            +
            +//Appearance
            +var strWei = 1;
            +var strAlpha = 0.55;
            +var bgAlpha = 1/20;
            +
            +//Motion
            +var m, mAcc;
            +var maxVel = 0.010;
            +
            +//Timer
            +var start, end;
            +var trigger = 12; //seconds
            +
            +
            +function setup() {
            +  //devicePixelScaling(false);
            +  createCanvas(windowWidth, windowHeight);
            +  //noSmooth();
            +  frameRate(30);
            +
            +  //Set Appearance
            +  strokeWeight(strWei);
            +  colorMode(HSB, 360, 100, 100, 1);
            +  curveTightness(0);
            +  noFill();
            +
            +  //Resettable
            +  init2();
            +}
            +
            +function init2() {
            +  noiseSeed(random(10000000));
            +
            +  //Timer Start
            +  if (timed) {
            +    start = millis();
            +    end = start + (trigger*1000);
            +  }
            +
            +  //Colors
            +    var h = random(360);
            +    if (blur) {bg = color(0,0,100,bgAlpha);}
            +    else {bg = color(0,0,100);}
            +    str = color(h,80,75, strAlpha);
            +
            +  //Corners
            +  var x = new Array();
            +  var y = new Array();
            +  if (genCoord) {
            +    x[0] = (width/2)-random(height/2);
            +    y[0] = (height/2)-random(height/2);
            +    x[1] = (width/2)-random(height/2);
            +    y[1] = (height/2)+random(height/2);
            +    x[2] = (width/2)+random(height/2);
            +    y[2] = (height/2)-random(height/2);
            +    x[3] = (width/2)+random(height/2);
            +    y[3] = (height/2)+random(height/2);
            +  }
            +  else {
            +    for (var i = 0; i < 4; i++) {
            +      x[i] = random(width);
            +      y[i] = random(height);
            +    }
            +  }
            +  p[0] = createVector(x[0], y[0]);
            +  p[1] = createVector(x[1], y[1]);
            +  p[2] = createVector(x[2], y[2]);
            +  p[3] = createVector(x[3], y[3]);
            +
            +  //Stepping Lines
            +  for (var i = 0; i < numlines; ++i) {
            +    s1[i] = p5.Vector.lerp(p[0], p[1], i/(numlines-1));
            +  }
            +  for (var i = 0; i < numlines; ++i) {
            +    s2[i] = p5.Vector.lerp(p[2], p[3], i/(numlines-1));
            +  }
            +
            +  //Motion
            +  var xvel, yvel;
            +  if (randir) {
            +    xvel = random(-maxVel, maxVel);
            +    yvel = random(-maxVel, maxVel);
            +  }
            +  else{
            +    xvel = 0;
            +    yvel = random(0, -maxVel);
            +  }
            +  m = createVector(xvel, yvel);
            +  mAcc = createVector(0,0);
            +
            +  //Amplitude
            +  if (!controlAmp) {
            +    amplitude = minAmp+abs(randomGaussian())*(maxAmp-minAmp);
            +  }
            +
            +  //Generate Lines
            +  for (var i = 0; i < numlines; ++i) {
            +    lines[i] = new Line2(s1[i], s2[i], reslines, i);
            +  }
            +}
            +
            +function draw() {
            +  background(bg);
            +  stroke(str);
            +
            +  //Draw
            +  for (var i = 0; i < numlines; ++i) {
            +    lines[i].draw();
            +    lines[i].update();
            +  }
            +
            +  //Motion
            +  if (motion) {
            +    mAcc.add(m);
            +  }
            +
            +  //Timer
            +  if (timed && millis() > end) {
            +    init2();
            +  }
            +}
            +
            +function windowResized() {
            +  resizeCanvas(windowWidth, windowHeight);
            +  background(bg);
            +  init2();
            +}
            +
            +function mousePressed() {
            +  if (mouseButton == LEFT) {
            +    if (controlAmp) {
            +      amplitude = map(mouseY, 0, windowHeight, minAmp-safeAmp, maxAmp+safeAmp)
            +      amplitude = constrain(amplitude, minAmp, maxAmp);
            +    }
            +    init2();
            +  }
            +  // prevent default
            +  //return false;
            +}
            +
            +function touchStarted() {
            +    if (controlAmp) {
            +      amplitude = map(touchY, 0, windowHeight, minAmp-safeAmp, maxAmp+safeAmp)
            +      amplitude = constrain(amplitude, minAmp, maxAmp);
            +    }
            +    init2();
            +  // prevent default
            +  //return false;
            +}
            +
            +
            +function coin() {
            +  if (random(1)>0.5) return true;
            +  else return false;
            +}
            +
            +
            +function Line2 (p1_, p2_, divs_, step_) {
            +  this.p1 = p1_;
            +  this.p2 = p2_;
            +  this.divs = divs_;
            +  this.step = step_;
            +
            +  //Calc
            +  this.p = p5.Vector.sub(this.p1, this.p2);
            +  this.pPerp = this.p.copy();
            +  this.pPerp.rotate(HALF_PI);
            +
            +  this.a = this.p.heading();
            +  this.aPerp = this.pPerp.heading();
            +
            +  this.vPerp = p5.Vector.fromAngle(this.aPerp);
            +
            +  //Generate
            +  this.points = new Array(); //divs
            +  this.generateVectors();
            +}
            +
            +Line2.prototype.generateVectors = function() {
            +  for (var i = 0; i < this.divs; ++i) {
            +    var n = (noise((i * lineRes) + mAcc.x, (this.step * stepRes) + mAcc.y) - 0.5) * 2;
            +    // var mod = pow( sin(i*PI/(this.divs-1)), edgeCalm);
            +    // var mod2 = pow( sin(this.step*PI/(numlines-1)), edgeCalm);
            +    // var sizedamp = width/1920;
            +
            +    this.points[i] = p5.Vector.lerp(this.p1, this.p2, i/(this.divs-1));
            +    this.points[i].add(p5.Vector.mult(this.vPerp, n*amplitude));
            +  }
            +}
            +
            +Line2.prototype.draw = function() {
            +  beginShape();
            +  for (var i = 0; i < this.divs; ++i) {
            +    curveVertex(this.points[i].x, this.points[i].y);
            +  }
            +  endShape();
            +}
            +
            +Line2.prototype.update = function() {
            +  this.generateVectors();
            +}
            +
            +/*
            +  The MIT License (MIT)
            +
            +  Copyright (c) 2015 CHRISTOPHER MILLS
            +
            +  Permission is hereby granted, free of charge, to any person obtaining a copy
            +  of this software and associated documentation files (the "Software"), to deal
            +  in the Software without restriction, including without limitation the rights
            +  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
            +  copies of the Software, and to permit persons to whom the Software is
            +  furnished to do so, subject to the following conditions:
            +
            +  The above copyright notice and this permission notice shall be included in all
            +  copies or substantial portions of the Software.
            +
            +  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
            +  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
            +  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
            +  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
            +  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
            +  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
            +  SOFTWARE.
            +*/
            diff --git a/dist/assets/p5_featured/ChirsMill_AuroraII/index.html b/dist/assets/p5_featured/ChirsMill_AuroraII/index.html
            new file mode 100644
            index 0000000000..87c22dd511
            --- /dev/null
            +++ b/dist/assets/p5_featured/ChirsMill_AuroraII/index.html
            @@ -0,0 +1,31 @@
            +<!DOCTYPE html>
            +<html lang="en-us">
            +  <head>
            +
            +    <link href="http://gmpg.org/xfn/11" rel="profile">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta http-equiv="content-type" content="text/html; charset=utf-8">
            +
            +    <!-- Enable responsiveness on mobile devices-->
            +    <meta name="viewport" content="width=device-width, initial-scale=1.0">
            +
            +    <title>
            +        p5.js Front &middot; Christopher Eugene Mills
            +    </title>
            +
            +    <!-- JavaScript -->
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.5/p5.min.js"></script>
            +
            +    <script src="AuroraII-p5front.js"></script>
            +
            +    <style type="text/css">
            +      body {margin:0; padding:0;}
            +      canvas {display:block;}
            +      canvas:focus {outline:0;}
            +    </style>
            +  </head>
            +
            +  <body>
            +  </body>
            +
            +</html>
            diff --git a/dist/assets/p5_featured/Christine_Social_June/Bob.js b/dist/assets/p5_featured/Christine_Social_June/Bob.js
            new file mode 100644
            index 0000000000..933fec9f75
            --- /dev/null
            +++ b/dist/assets/p5_featured/Christine_Social_June/Bob.js
            @@ -0,0 +1,399 @@
            +//Bob
            +function Bob() {
            +
            +  //Internal Properties
            +  var bobView = this,
            +    //Booleans
            +      doRunInterference = true,
            +      doRunBob = true,
            +      doDisplayBob = true,
            +      activeBobMode = false,
            +      isPassThrough = false,
            +      isPairing = true,
            +      diversityValue = 255,
            +
            +    //Scalars
            +      fieldPulseRate = 0,
            +      size = 20,
            +      hue = Math.floor(Math.random() * 256),
            +      fieldPulseFrame = 0,
            +      pushForce,
            +      driveForce = createVector(0, 0),
            +      radius = size/2,
            +      tempXPos = Math.floor(Math.random() * (width-size) + size/2),
            +      tempYPos = Math.floor(Math.random() * (height-size) + size/2);
            +
            +  //External Properties
            +  bobView.isActiveBob = false;
            +  bobView.size = 20;
            +  bobView.radius = radius;
            +  bobView.hue = hue;
            +  bobView.fieldRings = Math.floor(Math.random() * 12 + 3);
            +  bobView.fieldSize = 464;
            +  bobView.fieldRadius = bobView.fieldSize/2;
            +  bobView.fieldIncrement = bobView.fieldRadius/bobView.fieldRings;
            +  bobView.fieldIncrementMultiplier = Math.random() * 2 + 1;
            +
            +    //Vectors
            +  bobView.position = createVector(tempXPos, tempYPos);
            +  bobView.velocity = p5.Vector.random2D().mult(4);
            +  bobView.acceleration = createVector(0, 0);
            +
            +    //Arrays
            +  bobView.forces = [];
            +  
            +  //bobView.run(bills)
            +  //Operates the Bob, passing it the list of other Bobs (as bills)
            +  bobView.run = function(bills) {
            +
            +    if(doRunInterference) {
            +      bills.forEach(bobView.runInterference, this);
            +    }
            +
            +    if(bobView.isActiveBob) {
            +      bobView.driveBob();
            +    }
            +
            +    if(doRunBob) {
            +      bobView.update(bills);
            +    }
            +
            +    bobView.display();
            +    bobView.reset();
            +  }
            +  
            +  //bobView.update()
            +  //Updates the position vectors of the Bob, no params
            +  bobView.update = function(bills) {
            +    bobView.forces.forEach(bobView.addForce);
            +    bobView.velocity.add(bobView.acceleration.x, bobView.acceleration.y);
            +    bobView.velocity.limit(7);
            +    bobView.position.add(bobView.velocity.x, bobView.velocity.y);
            +    if(isPassThrough){
            +      bobView.passThrough();
            +    } else {
            +      bobView.checkForWalls();
            +    }
            +  }
            +
            +  bobView.checkForWalls = function() {
            +    if((bobView.position.x - radius) <= 0){  
            +      bobView.position.x = radius;
            +      if(bobView.velocity.x < 0){
            +        bobView.velocity.x *= -1; 
            +      }
            +    }
            +    if((bobView.position.x + radius) >= width){  
            +      bobView.position.x = width - radius; 
            +      if(bobView.velocity.x > 0){
            +        bobView.velocity.x *= -1; 
            +      }
            +    }
            +    if((bobView.position.y - radius) <= 0){ 
            +      bobView.position.y = radius; 
            +      if(bobView.velocity.y < 0){
            +        bobView.velocity.y *= -1; 
            +      }
            +    }
            +    if((bobView.position.y + radius) >= height){ 
            +      bobView.position.y = height - radius; 
            +      if(bobView.velocity.y > 0){
            +        bobView.velocity.y *= -1; 
            +      }
            +    }
            +  }
            +
            +  bobView.passThrough = function() {
            +    if((bobView.position.x + radius) <= 0){  
            +      bobView.position.x = width;
            +    }
            +    if((bobView.position.x - radius) >= width){  
            +      bobView.position.x = 0 - radius;
            +    }
            +    if((bobView.position.y + radius) <= 0){ 
            +      bobView.position.y = height;
            +    }
            +    if((bobView.position.y - radius) >= height){ 
            +      bobView.position.y = 0 - radius;
            +    }
            +  }
            +
            +  bobView.addForce = function(force, index, forces) {
            +    bobView.acceleration.add(force.x, force.y);
            +  }
            +  
            +  //bobView.display()
            +  //Runs the functions that create the visual appearance of the Bob, no params
            +  bobView.display = function() {
            +    if(activeBobMode && bobView.isActiveBob){
            +      bobView.renderField();
            +    }
            +    bobView.renderBob();
            +  }
            +  
            +  bobView.runInterference = function(bill, index, bills) {
            +  	var thisBob = bobView,
            +  		  otherBob = bill,
            +        distance = p5.Vector.dist(thisBob.position, otherBob.position),
            +        dVector = p5.Vector.sub(otherBob.position, thisBob.position),
            +        dNormal = dVector.normalize();
            +
            +    fieldPulseFrame = fieldPulseFrame % bobView.fieldIncrement;
            +    
            +    //if otherBob is not thisBob
            +    if(distance > 0) {
            +      //for each ring of thisBob's field
            +      for(var i = fieldPulseFrame; i < thisBob.fieldRadius; i+=thisBob.fieldIncrement) {
            +        //for each ring of otherBob's field
            +        for(var j = fieldPulseFrame; j < otherBob.fieldRadius; j+=otherBob.fieldIncrement) {
            +          //check if the two rings intersect
            +          var areIntersecting = checkIntersect(
            +                                thisBob.position.x, 
            +                                thisBob.position.y, 
            +                                i, 
            +                                otherBob.position.x, 
            +                                otherBob.position.y, 
            +                                j
            +                              );
            +                                              
            +          switch(areIntersecting) {
            +          //fields intersect and have intersection points
            +            case 1:
            +              bobView.handleIntersection(thisBob, otherBob, distance, i, j);
            +              break;
            +
            +          //If one of the fields is contained in the other
            +            case -1:
            +              // renderOverlapShape(i);
            +              break;
            +
            +            default:
            +              break;
            +          }
            +        }
            +      }
            +    }
            +  }
            +
            +  bobView.handleIntersection = function(thisBob, otherBob, distance, i, j) {
            +    var intersections,
            +        firstIntersectionPoint,
            +        secondIntersectionPoint,
            +        pushForceFactor,
            +        pushVector1,
            +        pushVector2,
            +        hueDifference;
            +
            +    intersections = getIntersections(
            +                      thisBob.position.x, 
            +                      thisBob.position.y, 
            +                      i, 
            +                      otherBob.position.x, 
            +                      otherBob.position.y, 
            +                      j
            +                    );
            +
            +    firstIntersectionPoint = createVector(intersections[0], intersections[1]);
            +    secondIntersectionPoint = createVector(intersections[2], intersections[3]);
            +
            +    if(!activeBobMode || (activeBobMode && bobView.isActiveBob)) {
            +      bobView.renderIntersectShape(intersections, distance, otherBob.hue, i);
            +    }
            +
            +    hueDifference = bobView.getHueGap(thisBob.hue, otherBob.hue);
            +
            +    if(isPairing) {
            +      pushForce = (43.75 - hueDifference)/63.75;
            +    } else {
            +      pushForce = (hueDifference - 20)/63.75;
            +    }
            +
            +    diversityFactor = map(diversityValue, 0, 255, 0, 63.75);
            +
            +    pushForce *= diversityFactor;
            +
            +    pushForceFactor = pushForce / (i * j);
            +
            +    pushVector1 = p5.Vector.sub(thisBob.position, firstIntersectionPoint)
            +      .normalize()
            +      .mult(pushForceFactor);
            +
            +    pushVector2 = p5.Vector.sub(thisBob.position, secondIntersectionPoint)
            +      .normalize()
            +      .mult(pushForceFactor);
            +
            +    bobView.forces.push(pushVector1);
            +    bobView.forces.push(pushVector2);
            +  }
            +  
            +  bobView.renderBob = function() {
            +    noStroke();
            +
            +    if(bobView.isActiveBob) {
            +      strokeWeight(4);
            +      stroke(0, 0, 255, 100);
            +    }
            +
            +    if(bobView.isActiveBob || !activeBobMode){
            +      fill(hue, diversityValue, 200);
            +    } else {
            +      fill(hue, diversityValue, 200, 150);
            +    }
            +    ellipse(bobView.position.x, bobView.position.y, size, size);
            +  }
            +  
            +  bobView.renderIntersectShape = function(intersections, distance, otherHue, i) {
            +    var circleNormal = createVector(radius, 0),
            +        distIntA = createVector(intersections[0], intersections[1]),
            +        distIntB = createVector(intersections[2], intersections[3]),
            +        angle1, angle2, newHue, opacity;
            +
            +    newHue = bobView.averageHues(bobView.hue, otherHue);
            +
            +    if(activeBobMode && bobView.isActiveBob) {
            +      opacity = map(i, 0, bobView.fieldSize, 0, 255);
            +      opacity = (255-opacity);
            +    } else {
            +      opacity = 200;
            +    }
            +        
            +    
            +    //Dots
            +    var dotSize =4;
            +    noStroke();
            +
            +    for (var i = dotSize; i > 0; i--){
            +      fill(newHue, diversityValue, 200, (opacity/3));
            +      ellipse(distIntA.x, distIntA.y, dotSize, dotSize);
            +      if(activeBobMode && bobView.isActiveBob) {
            +        ellipse(distIntB.x, distIntB.y, dotSize, dotSize);
            +      }
            +    }
            +    //Arcs
            +    /*
            +    distIntA.sub(position);
            +    distIntB.sub(position);
            +    
            +    if(distance.x > 0){
            +      if(distIntA.y < distance.y){
            +        angle1 = getArcAngle(circleNormal, distIntA);
            +        angle2 = getArcAngle(circleNormal, distIntB);
            +      } else {
            +        angle1 = getArcAngle(circleNormal, distIntB);
            +        angle2 = getArcAngle(circleNormal, distIntA);
            +      }
            +      
            +      if((angle1 - PI) >  angle2){
            +        angle2 += TWO_PI;
            +      }
            +    } else {
            +      if(distIntA.y > distance.y){
            +        angle1 = getArcAngle(circleNormal, distIntA);
            +        angle2 = getArcAngle(circleNormal, distIntB);
            +      } else {
            +        angle1 = getArcAngle(circleNormal, distIntB);
            +        angle2 = getArcAngle(circleNormal, distIntA);
            +      }
            +      
            +      if((angle1 - PI) >  angle2){
            +        angle2 += TWO_PI;
            +      }
            +    }
            +    fill(100, 1);
            +    noStroke();
            +    arc(position.x, position.y, 2*tempSize, 2*tempSize, angle1, angle2, OPEN);
            +    */
            +  }
            +
            +  bobView.getHueGap = function(hue1, hue2) {
            +    var hueDifference, hueGap;
            +    hueDifference = Math.abs(hue1 - hue2);
            +
            +    if(hueDifference > 128){
            +      hueGap = (255 - hueDifference)/2;
            +    } else {
            +      hueGap = hueDifference/2;
            +    }
            +
            +    return hueGap;
            +  }
            +
            +  bobView.averageHues = function(hue1, hue2) {
            +    var baseHue, newHue, hueGap, hueDifference,
            +        maxHue = 255;
            +    hueDifference = Math.abs(hue1 - hue2);
            +    
            +    if(hueDifference > (maxHue/2)){
            +      if(hue1 > hue2) {
            +        baseHue = hue1;
            +      } else {
            +        baseHue = hue2;
            +      }
            +
            +      hueGap = (maxHue - hueDifference)/2;
            +    } else {
            +      if(hue1 < hue2) {
            +        baseHue = hue1;
            +      } else {
            +        baseHue = hue2;
            +      }
            +
            +      hueGap = hueDifference/2;
            +    }
            +
            +    newHue = (baseHue + hueGap) % maxHue;
            +    return newHue;
            +  }
            +  
            +  bobView.renderOverlapShape = function(shapeSize){
            +    noFill();
            +    strokeWeight(2);
            +    stroke(0, 0, 0);
            +    ellipse(bobView.position.x, bobView.position.y, 2*shapeSize, 2*shapeSize);
            +  }
            +  
            +  bobView.renderField = function() {
            +    strokeWeight(1);
            +    noFill();
            +    for(var i = fieldPulseFrame; i < bobView.fieldRadius; i+=bobView.fieldIncrement){
            +      var opacity = map(i, 0, bobView.fieldRadius, 255, 0);
            +      stroke(hue, 200, 200, opacity);
            +      ellipse(bobView.position.x, bobView.position.y, 2*i, 2*i);
            +    }
            +  }
            +
            +  bobView.driveBob = function() {
            +    var driveForceMag,
            +        driveForceIncrement = 0.1;
            +
            +    if (keyIsDown(LEFT_ARROW))
            +      driveForce.add(-1 * driveForceIncrement, 0);
            +
            +    if (keyIsDown(RIGHT_ARROW))
            +      driveForce.add(driveForceIncrement, 0);
            +
            +    if (keyIsDown(UP_ARROW))
            +      driveForce.add(0, -1 * driveForceIncrement);
            +
            +    if (keyIsDown(DOWN_ARROW))
            +      driveForce.add(0, driveForceIncrement);
            +
            +    bobView.forces.push(driveForce);
            +
            +    driveForceMag = driveForce.mag();
            +
            +    
            +    if(driveForceMag > 0.01){
            +      driveForce.mult(0.9);
            +    } else if(driveForceMag > 0){
            +      driveForce.mult(0);
            +    }
            +  }
            +
            +  bobView.reset = function() {
            +    bobView.acceleration.mult(0);
            +    bobView.velocity.mult(0.99999);
            +    bobView.forces = [];
            +    fieldPulseFrame += fieldPulseRate;
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Christine_Social_June/BobSystem.js b/dist/assets/p5_featured/Christine_Social_June/BobSystem.js
            new file mode 100644
            index 0000000000..f0b63f3735
            --- /dev/null
            +++ b/dist/assets/p5_featured/Christine_Social_June/BobSystem.js
            @@ -0,0 +1,22 @@
            +//Bob System
            +function BobSystem(options) {
            +  var bobs = [],
            +      bobAmount = 5;
            +
            +  this.addBob = function(){
            +    var newBob = new Bob();
            +    bobs.push(newBob);
            +  }
            +  
            +  this.runBobs = function(){
            +  	bobs.forEach(this.runBob);
            +  }
            +
            +  this.runBob = function(bob, index, bobs) {
            +  	bob.run(bobs);
            +  }
            +
            +  for(var i = bobs.length; i < bobAmount; i++){
            +    this.addBob();
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Christine_Social_June/equations.js b/dist/assets/p5_featured/Christine_Social_June/equations.js
            new file mode 100644
            index 0000000000..2c52134d4a
            --- /dev/null
            +++ b/dist/assets/p5_featured/Christine_Social_June/equations.js
            @@ -0,0 +1,77 @@
            +//Equations
            +function checkIntersect(x0, y0, r0, x1, y1, r1) {
            +  var doTheyIntersect,
            +      dx, 
            +      dy, 
            +      d;
            +  
            +  //Calculating distance between centerpoints
            +  dx = x1 - x0;
            +  dy = y1 - y0;
            +  d = sqrt(sq(dy)+sq(dx)); 
            +  
            +  //Using distance to determine if they intersect
            +  if(d > (r0 + r1)) {
            +    //No intersection
            +    doTheyIntersect = 0;
            +  } else if (d < abs(r0 - r1)){
            +    //One is contained within the other
            +    doTheyIntersect = -1;
            +  } else {
            +    
            +    //They intersect
            +    doTheyIntersect = 1;
            +  }
            +  
            +  return doTheyIntersect;
            +}
            +
            +function getIntersections(x0, y0, r0, x1, y1, r1) {
            +  var dx, dy, d, a, x2, y2, h, rx, ry, xi1, xi2, yi1, yi2,
            +      intersectionPoints = [];
            +  
            +  dx = x1 - x0;
            +  dy = y1 - y0;
            +  d = sqrt(sq(dy)+sq(dx));
            +
            +  a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d);
            +  x2 = x0 + (dx * a/d);
            +  y2 = y0 + (dy * a/d);
            +  h = sqrt(sq(r0) - sq(a));
            +  rx = (0-dy) * (h/d);
            +  ry = dx * (h/d);
            +  xi1 = x2 + rx;
            +  xi2 = x2 - rx;
            +  yi1 = y2 + ry;
            +  yi2 = y2 - ry;
            +  
            +  intersectionPoints[0] = xi1;
            +  intersectionPoints[1] = yi1;
            +  intersectionPoints[2] = xi2;
            +  intersectionPoints[3] = yi2;
            +  
            +  return intersectionPoints;
            +}
            +
            +function getArcAngle(normal, intersection) {
            +  var angle;
            +  
            +  angle = p5.Vector.angleBetween(normal, intersection);
            +  
            +  if(intersection.y < 0){
            +    angle = TWO_PI - angle;
            +  }
            +  
            +  return angle;
            +}
            +
            +function debounce(fn, delay) {
            +  var timer = null;
            +  return function () {
            +    var context = this, args = arguments;
            +    clearTimeout(timer);
            +    timer = setTimeout(function () {
            +      fn.apply(context, args);
            +    }, delay);
            +  };
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Christine_Social_June/index.html b/dist/assets/p5_featured/Christine_Social_June/index.html
            new file mode 100644
            index 0000000000..06040a84fe
            --- /dev/null
            +++ b/dist/assets/p5_featured/Christine_Social_June/index.html
            @@ -0,0 +1,13 @@
            +<!DOCTYPE html>
            +	<head>
            +		<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.0/p5.min.js"></script>
            +		<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.0/addons/p5.min.js"></script>
            +		<script src="equations.js"></script>
            +		<script src="Bob.js"></script>
            +		<script src="BobSystem.js"></script>
            +		<script src="sketch.js"></script>
            +	</head>
            +	<body style="margin: 0; padding: 0;">
            +		<div id="sketch-container" class="sketch-container"></div>
            +	</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Christine_Social_June/sketch.js b/dist/assets/p5_featured/Christine_Social_June/sketch.js
            new file mode 100644
            index 0000000000..3ee7e46b96
            --- /dev/null
            +++ b/dist/assets/p5_featured/Christine_Social_June/sketch.js
            @@ -0,0 +1,30 @@
            +var BobsUno, options, sliderValue, sketch, slider,
            +    isActiveBobMode = false;
            +
            +function setup() {
            +
            +  sketch = createCanvas(windowWidth, windowHeight)
            +  sketch.id("p5Canvas");
            +
            +  colorMode(HSB);
            +  frameRate(30);
            +
            +  options = {
            +    doRunBobs: true,
            +    doDisplayBob: true,
            +    bobSize: 20,
            +    doRunInterference: true,
            +    fieldPulseRate: 1
            +  };
            +  BobsUno = new BobSystem();
            +}
            +
            +function draw() {
            +  background(255);
            +
            +  BobsUno.runBobs();
            +}
            +
            +function windowResized() {
            +  resizeCanvas(windowWidth, windowHeight);
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Grace_Obergfell/index.html b/dist/assets/p5_featured/Grace_Obergfell/index.html
            new file mode 100644
            index 0000000000..244cdd96ab
            --- /dev/null
            +++ b/dist/assets/p5_featured/Grace_Obergfell/index.html
            @@ -0,0 +1,11 @@
            +<!DOCTYPE html><head>
            +    <script src="../../js/p5.min.js"></script>
            +    <link rel="stylesheet" type="text/css" href="style.css">
            +    <meta charset="utf-8">
            +
            +  </head>
            +  <body>
            +    <script src="sketch.js"></script>
            +  
            +
            +</body></html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Grace_Obergfell/sketch.js b/dist/assets/p5_featured/Grace_Obergfell/sketch.js
            new file mode 100644
            index 0000000000..86d1c323e1
            --- /dev/null
            +++ b/dist/assets/p5_featured/Grace_Obergfell/sketch.js
            @@ -0,0 +1,40 @@
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  background(255);
            +  colorMode(HSB);
            +  //for loop that creates prints all the shapes
            +  for (var x = 0; x < 100; x++) {
            +
            +    for (var y = 0; y < 100; y++) {
            +      //changes color for specific regions
            +   
            +        fill(170+x, 10, 255, 100);   
            +//       if (x%10 >= 4 && x%10 <= 5) {
            +//         fill(200, 10, 255, 100);
            +//       }
            +  
            +//      else if( x%10 >= 2 && x%10 <=7){
            +//         fill(255, 255, 255, 100);
            +//       }
            +    
            +//       else{
            +//         fill(255, 255, 255, 100);
            +//       }
            +      //actually prints the moons
            +      moon(x, y);
            +      
            +    }
            +  
            +  }
            +}
            +
            +//makes the moons and colors
            +function moon(x, y) {
            +  noStroke();
            +//location and repeat of the moon
            +  ellipse(x * 40 + 20, y * 40 + 20, 40, 40);
            +  fill(255);
            +  ellipse(x * 40 + 30, y * 41 + 25, 40, 40);
            +
            +
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Grace_Obergfell/style.css b/dist/assets/p5_featured/Grace_Obergfell/style.css
            new file mode 100644
            index 0000000000..9386f1c2e3
            --- /dev/null
            +++ b/dist/assets/p5_featured/Grace_Obergfell/style.css
            @@ -0,0 +1,7 @@
            +html, body {
            +  margin: 0;
            +  padding: 0;
            +}
            +canvas {
            +  display: block;
            +}
            diff --git a/dist/assets/p5_featured/HarverMoon_Perlin/index.html b/dist/assets/p5_featured/HarverMoon_Perlin/index.html
            new file mode 100644
            index 0000000000..9620eef9cf
            --- /dev/null
            +++ b/dist/assets/p5_featured/HarverMoon_Perlin/index.html
            @@ -0,0 +1,15 @@
            +<!DOCTYPE html>
            +<head>
            +  <!-- <script src="../p5.js"></script> -->
            +  <script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.5/p5.js"></script>
            +  <!-- uncomment lines below to include extra p5 libraries -->
            +	<!--<script src="../addons/p5.dom.js"></script>-->
            +  <!--<script src="../addons/p5.sound.js"></script>-->
            +  <script src="sketch.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +  <style> body {padding: 0; margin: 0;} </style>
            +</head>
            +
            +<body>
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/HarverMoon_Perlin/sketch.js b/dist/assets/p5_featured/HarverMoon_Perlin/sketch.js
            new file mode 100644
            index 0000000000..695119d884
            --- /dev/null
            +++ b/dist/assets/p5_featured/HarverMoon_Perlin/sketch.js
            @@ -0,0 +1,71 @@
            +var particles = [];
            +var mouse;
            +
            +var colorA;
            +var colorB;
            +var colorC;
            +var colorD;
            +
            +function setup() {
            +	mouse = createVector(mouseX,mouseY);
            +	createCanvas(windowWidth,windowHeight);
            +	MnowPos = createVector(500,500);
            +	Macc = createVector(2,-2);
            +	noStroke();
            +	fill(0);
            +	rectMode(CENTER);
            +	background(255);
            +	colorA = color(48,222,179);
            +	colorB = color(221,166,232);
            +	colorC = color(145,162,  0);
            +	colorD = color(196,195,195);
            +}
            +function draw() {
            +	mouse.set(mouseX,mouseY)
            +	for(var i = 0; i < particles.length; i++){
            +		particles[i].update();
            +		particles[i].draw();
            +		var noiseRot = map(noise(particles[i].nowPos.x * .006 ,particles[i].nowPos.y * .006), .2, .8, 0, PI*2 );
            +		particles[i].acc.set(cos(noiseRot)*3,sin(noiseRot)*3);
            +	}
            +	if(particles.length < 500){
            +		MnowPos.set(mouse);
            +		MnowPos.add(random(-10,10), random(-10,10) );
            +		var mLoc = int(map(mouseX,0,width,0,4));
            +		if(mLoc == 0){
            +			particles[i] = new Particle(MnowPos,Macc,colorA);
            +		}
            +		else if(mLoc == 1){
            +			particles[i] = new Particle(MnowPos,Macc,colorB);
            +		}
            +		else if(mLoc == 2){
            +			particles[i] = new Particle(MnowPos,Macc,colorC);
            +		}
            +		else if(mLoc == 3){
            +			particles[i] = new Particle(MnowPos,Macc,colorD);
            +		}
            +	}
            +	for(var j = 0; j < particles.length; j++){
            +		if(particles[j].nowPos.x>=width-10 || particles[j].nowPos.x <= 10 || particles[j].nowPos.y>=height-10 || particles[j].nowPos.y <= 10  || particles[j].lifeCount <= 0){
            +			particles.splice(j,1);
            +			//println("kill : " + j);
            +		}
            +	}
            +}
            +
            +function Particle ( posN, accN, colorIn){
            +	this.nowPos=createVector(posN.x,posN.y);
            +	this.acc = createVector(accN.x, accN.y);
            +	this.lifeCount = random(100,400);
            +	this.colorN = colorIn;
            +}
            +
            +Particle.prototype.update = function(){
            +	this.lifeCount--;
            +	this.nowPos.add(this.acc);
            +}
            +
            +Particle.prototype.draw = function(){
            +	fill(this.colorN);
            +	ellipse(this.nowPos.x,this.nowPos.y,2,2);
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Hindi-animate/assets/bg.jpg b/dist/assets/p5_featured/Hindi-animate/assets/bg.jpg
            new file mode 100644
            index 0000000000..8e0fc694a5
            Binary files /dev/null and b/dist/assets/p5_featured/Hindi-animate/assets/bg.jpg differ
            diff --git a/dist/assets/p5_featured/Hindi-animate/index.html b/dist/assets/p5_featured/Hindi-animate/index.html
            new file mode 100644
            index 0000000000..a79b9e8d2f
            --- /dev/null
            +++ b/dist/assets/p5_featured/Hindi-animate/index.html
            @@ -0,0 +1,10 @@
            +
            +<!-- saved from url=(0043)http://www.qianqian-ye.com/p5js-superwoman/ -->
            +<!DOCTYPE html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>
            +  <script src="sketch.js"></script>
            +  <style> body {padding: 0; margin: 0;} canvas { opacity: 0.8 }</style>
            +</head>
            +
            +<body></body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Hindi-animate/sketch.js b/dist/assets/p5_featured/Hindi-animate/sketch.js
            new file mode 100644
            index 0000000000..8cfd4b6446
            --- /dev/null
            +++ b/dist/assets/p5_featured/Hindi-animate/sketch.js
            @@ -0,0 +1,16 @@
            +let img;
            +let offset = 0;
            +let easing = 0.05;
            +
            +function setup() {
            +  createCanvas(1000,1000);
            +  img = loadImage('assets/bg.jpg'); // Load an image into the program
            +}
            +
            +function draw() {
            +  image(img, 0, 0); // Display at full opacity
            +  let dx = mouseX - img.width / 2 - offset;
            +  offset += dx * easing;
            +  tint(255, 127); // Display at half opacity
            +  image(img, offset, 0);
            +}
            diff --git a/dist/assets/p5_featured/KD_2020_08_08_22_21_27/index.html b/dist/assets/p5_featured/KD_2020_08_08_22_21_27/index.html
            new file mode 100644
            index 0000000000..55f0aecbbe
            --- /dev/null
            +++ b/dist/assets/p5_featured/KD_2020_08_08_22_21_27/index.html
            @@ -0,0 +1,24 @@
            +<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" name="viewport" content="width=device-width, height=device-height, initial-scale=1.0">
            +  <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@900&amp;display=swap" rel="stylesheet">
            +	<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.min.js"></script>
            +  <meta charset="utf-8">
            +  <style>
            +    html, body {
            +      margin: 0;
            +      padding: 0;
            +    }
            +    canvas {
            +      display: block;
            +    }
            +
            +    .hidden {
            +      height:100%; 
            +      min-height:100%; 
            +      overflow:hidden !important; 
            +      touch-action:none;
            +    }
            +  </style>
            +</head>
            +<body>
            +  <script src="sketch.js"></script>
            +</body></html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/KD_2020_08_08_22_21_27/sketch.js b/dist/assets/p5_featured/KD_2020_08_08_22_21_27/sketch.js
            new file mode 100644
            index 0000000000..d7e61bfb58
            --- /dev/null
            +++ b/dist/assets/p5_featured/KD_2020_08_08_22_21_27/sketch.js
            @@ -0,0 +1,329 @@
            +//Javascript
            +function scrollDisable(){
            +    $('html, body').addClass('hidden');
            +}
            +function scrollAble(){
            +    $('html, body').removeClass('hidden');
            +}
            +function scrollDisable(){
            +    $('body').addClass('scrollDisable').on('scroll touchmove mousewheel', function(e){
            +        e.preventDefault();
            +    });
            +}
            +
            +
            +var sentence = "나라의 말이 중국과 달라 문자로 서로 통하지 아니하여서 이런 까닭으로 어리석은 백성이 말하고자 하는 바가 있어도 마침내 제 뜻을 능히 펴지 못하는 사람이 많다 내가 이를 위하여 가엾이 여겨 새로 스물여덟 자를 만드니 사람마다 하여금 쉬이 익혀 날마다 씀에 편안하게 하고자 할 따름이다";
            +
            +var kdtree;
            +var particles = [];
            +var isMobile;
            +
            +function isMobileDevice() {
            +  return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
            +}
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  isMobile = isMobileDevice();
            +  sentence = sentence.replace(/ /g, "");
            +  textFont("Noto Sans KR");
            +  print(sentence.length);
            +  let sentenceLength = isMobile ? sentence.length / 3 : sentence.length;
            +
            +  for (let i = 0; i < sentenceLength; i++) {
            +    particles.push(new Particle(createVector(random(width), random(height)),
            +      sentence[(i * 2) % sentence.length], sentence[(i * 2 + 1) % sentence.length], i
            +    ));
            +  }
            +}
            +
            +
            +
            +function draw() {
            +
            +  background(color(250, 247, 247));
            +  kdtree = new KDTree(createVector(width * 0.5, height * 0.5), 0);
            +  for (let i = 0; i < particles.length; i++) {
            +    kdtree.insert(particles[i]);
            +  }
            +
            +
            +
            +  for (let i = 0; i < particles.length; i++) {
            +    let currentPosition = particles[i].position;
            +    let desiredPosition = particles[i].desiredPosition;
            +    let velocity = particles[i].velocity;
            +
            +    let textColor = particles[i].textColor;
            +    let desiredColor = particles[i].desiredColor;
            +
            +    for (let j = 0; j < 3; j++) {
            +      textColor[j] += (desiredColor[j] - textColor[j]) * 0.03;
            +    }
            +
            +    let newDirection = createVector();
            +    let newDPDirection = createVector();
            +    for (let j = 0; j < particles.length; j++) {
            +      let subDirection = p5.Vector.sub(currentPosition, particles[j].position);
            +      subDirection.mult(exp(-subDirection.mag() * 0.5))
            +      newDirection.add(subDirection);
            +    }
            +    velocity.add(newDirection);
            +
            +
            +    let mouseAttraction = p5.Vector.sub(particles[i].position, createVector(mouseX, mouseY));
            +    velocity.add(mouseAttraction.normalize().mult(exp(-mouseAttraction.mag())));
            +    
            +    if(currentPosition.x > width || currentPosition.x < 0){
            +      desiredPosition.x += currentPosition.x > width ? -1 : 1;
            +    }
            +    if(currentPosition.y > height || currentPosition.y < 0){
            +      desiredPosition.y += currentPosition.y > height ? -1 : 1;
            +    }
            +
            +    velocity.add(p5.Vector.sub(desiredPosition, currentPosition).mult(0.01));
            +
            +    velocity.mult(0.9);
            +    currentPosition.add(velocity);
            +  }
            +  kdtree.draw();
            +}
            +
            +function mousePressed() {
            +  for (let i = 0; i < particles.length; i++) {
            +    let desiredPosition = particles[i].desiredPosition;
            +    desiredPosition.x = random(width);
            +    desiredPosition.y = random(height);
            +  }
            +}
            +
            +function touchStarted() {
            +  for (let i = 0; i < particles.length; i++) {
            +    let desiredPosition = particles[i].desiredPosition;
            +    desiredPosition.x = random(width);
            +    desiredPosition.y = random(height);
            +  }
            +}
            +
            +function touchMoved() {
            +  let test = kdtree.search(createVector(mouseX, mouseY));
            +  if (test != null) {
            +    test.particle.textColor = [250, 247, 247];
            +  }
            +}
            +
            +function mouseMoved() {
            +  let test = kdtree.search(createVector(mouseX, mouseY));
            +  if (test != null) {
            +    test.particle.textColor = [250, 247, 247];
            +  }
            +}
            +
            +function keyPressed() {
            +  for (let i = 0; i < particles.length; i++) {
            +    let desiredPosition = particles[i].desiredPosition;
            +    desiredPosition.x = random(width);
            +    desiredPosition.y = random(height);
            +  }
            +}
            +
            +let KDTree = function() {
            +  this.root = null;
            +  this.size = 100;
            +};
            +
            +KDTree.prototype.insert = function(particle) {
            +  this.root = KDNode.prototype.insert(this.root, particle, 0, 0, width, height, 1);
            +};
            +
            +KDTree.prototype.search = function(position) {
            +  return this.root.search(this.root, position, 1);
            +}
            +
            +KDTree.prototype.draw = function() {
            +  if (this.root) {
            +    this.root.draw(this.root, true);
            +  }
            +};
            +
            +
            +let Particle = function(position, leftTextContent, rightTextContent, index) {
            +  this.position = position;
            +  this.desiredPosition = createVector(random(width), random(height));
            +  this.velocity = createVector();
            +  this.leftTextContent = leftTextContent;
            +  this.rightTextContent = rightTextContent;
            +  // this.leftColor = colorList[parseInt(random(colorList.length))];
            +  // this.rightColor = colorList[parseInt(random(colorList.length))];
            +  this.textColor = [250, 247, 247];
            +  this.desiredColor = [225, 222, 222];
            +
            +  this.index = index;
            +}
            +
            +
            +
            +
            +let KDNode = function( /*PVector*/ p, /*PVector*/ minP, /*PVector*/ maxP) {
            +  this.particle = p;
            +  this.minP = minP
            +  this.maxP = maxP;
            +  this.left_down = null;
            +  this.right_up = null;
            +};
            +
            +KDNode.prototype.draw = function(node, drawVert) {
            +  if (!node) {
            +    return;
            +  }
            +  let round = 0;
            +  let textSizeValue = 30;
            +  let textColor = color(50, 46, 47);
            +  textSize(textSizeValue);
            +  noStroke();
            +  let rectWidth, rectHeight, rectX, rectY = null;
            +  if (drawVert == true) {
            +    // rectMode(CENTER)
            +    textAlign(CENTER, CENTER);
            +    if (node.right_up == null) {
            +      rectWidth = node.maxP.x - node.particle.position.x;
            +      rectHeight = node.maxP.y - node.minP.y;
            +      rectX = node.particle.position.x + rectWidth * 0.5;
            +      rectY = node.minP.y + rectHeight * 0.5;
            +      // rect(rectX, rectY, rectWidth, rectHeight, round);
            +
            +      push();
            +      translate(rectX, rectY);
            +      scale((rectWidth) / (textWidth(node.particle.leftTextContent) + 10), (rectHeight - 5) / textSizeValue);
            +      fill(node.particle.textColor);
            +      text(node.particle.leftTextContent, 0, 0);
            +      pop();
            +    }
            +    if (node.left_down == null) {
            +      rectWidth = node.particle.position.x - node.minP.x;
            +      rectHeight = node.maxP.y - node.minP.y;
            +      rectX = node.minP.x + rectWidth * 0.5;
            +      rectY = node.minP.y + rectHeight * 0.5;
            +      // rect(rectX, rectY, rectWidth, rectHeight, round);
            +
            +      push();
            +      translate(rectX, rectY);
            +      scale((rectWidth) / (textWidth(node.particle.rightTextContent) + 10), (rectHeight - 5) / textSizeValue);
            +      fill(node.particle.textColor);
            +      text(node.particle.rightTextContent, 0, 0);
            +      pop();
            +    }
            +  } else {
            +    if (node.right_up == null) {
            +      rectWidth = node.maxP.x - node.minP.x;
            +      rectHeight = node.maxP.y - node.particle.position.y;
            +      rectX = node.minP.x + rectWidth * 0.5;
            +      rectY = node.particle.position.y + rectHeight * 0.5;
            +      // rect(rectX, rectY, rectWidth, rectHeight, round);
            +
            +      push();
            +      translate(rectX, rectY);
            +      scale((rectWidth) / (textWidth(node.particle.leftTextContent) + 10), (rectHeight - 5) / textSizeValue);
            +      fill(node.particle.textColor);
            +      text(node.particle.leftTextContent, 0, 0);
            +      pop();
            +    }
            +    if (node.left_down == null) {
            +      rectWidth = node.maxP.x - node.minP.x;
            +      rectHeight = node.particle.position.y - node.minP.y;
            +      rectX = node.minP.x + rectWidth * 0.5;
            +      rectY = node.minP.y + rectHeight * 0.5;
            +      // rect(rectX, rectY, rectWidth, rectHeight, round);
            +
            +      push();
            +      translate(rectX, rectY);
            +      scale((rectWidth) / (textWidth(node.particle.rightTextContent) + 10), (rectHeight - 5) / textSizeValue);
            +      fill(node.particle.textColor);
            +      text(node.particle.rightTextContent, 0, 0);
            +      pop();
            +    }
            +  }
            +  KDNode.prototype.draw(node.left_down, !drawVert)
            +  KDNode.prototype.draw(node.right_up, !drawVert)
            +}
            +
            +KDNode.prototype.search = function( /*KDNode*/ node, /*Vector*/ p, /*boolean*/ isHorizontal) {
            +  if (node == null) {
            +    return node;
            +  } else if (node.particle.position.x == p.x && node.particle.position.y == p.y) {
            +    print("same!")
            +    return node;
            +  }
            +  // The current node is vertical: compare x-coordinates
            +  let searched = null;
            +
            +  if (isHorizontal) {
            +    isHorizontal = !isHorizontal;
            +    if (p.x - node.particle.position.x < 0) {
            +      if (node.left_down != null) {
            +        searched = node.search(node.left_down, p, isHorizontal);
            +      } else {
            +        return node;
            +      }
            +    } else {
            +      if (node.right_up != null) {
            +        searched = node.search(node.right_up, p, isHorizontal);
            +      } else {
            +        return node;
            +      }
            +    }
            +  }
            +  // The current node is horizontal: compare y-coordinates
            +  else {
            +    isHorizontal = !isHorizontal;
            +    if (p.y - node.particle.position.y < 0) {
            +      if (node.left_down != null) {
            +        searched = node.search(node.left_down, p, isHorizontal);
            +      } else {
            +        return node;
            +      }
            +    } else {
            +      if (node.right_up != null) {
            +        searched = node.search(node.right_up, p, isHorizontal);
            +      } else {
            +        return node;
            +      }
            +    }
            +  }
            +
            +  return searched;
            +}
            +
            +KDNode.prototype.insert = function( /*KDNode*/ node, /*Particle*/ p, /*float*/ x0, /*float*/ y0, /*float*/ x1, /*float*/ y1, /*int*/ xcmp) {
            +  if (node == null) {
            +    return new KDNode(p, createVector(x0, y0), createVector(x1, y1));
            +  } else if (node.particle.position.x == p.position.x && node.particle.position.y == p.position.y) return node;
            +  // The current node is vertical: compare x-coordinates
            +  if (xcmp == 1) {
            +    xcmp = 0;
            +    let cmp = p.position.x - node.particle.position.x;
            +    if (cmp < 0)
            +      node.left_down = node.insert(node.left_down, p, x0, y0, node.particle.position.x, y1, xcmp);
            +    else
            +      node.right_up = node.insert(node.right_up, p, node.particle.position.x, y0, x1, y1, xcmp);
            +  }
            +  // The current node is horizontal: compare y-coordinates
            +  else {
            +    xcmp = 1;
            +    let cmp = p.position.y - node.particle.position.y;
            +    if (cmp < 0)
            +      node.left_down = node.insert(node.left_down, p, x0, y0, x1, node.particle.position.y, xcmp);
            +    else
            +      node.right_up = node.insert(node.right_up, p, x0, node.particle.position.y, x1, y1, xcmp);
            +  }
            +  return node;
            +}
            +
            +function windowResized() {
            +  resizeCanvas(windowWidth, windowHeight);
            +  for (let i = 0; i < particles.length; i++) {
            +    let desiredPosition = particles[i].desiredPosition;
            +    desiredPosition.x = random(width);
            +    desiredPosition.y = random(height);
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/LeslieRuckman_RainbowPixelGrow/index.html b/dist/assets/p5_featured/LeslieRuckman_RainbowPixelGrow/index.html
            new file mode 100644
            index 0000000000..8ba6c3940e
            --- /dev/null
            +++ b/dist/assets/p5_featured/LeslieRuckman_RainbowPixelGrow/index.html
            @@ -0,0 +1,13 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>RainbowPixelGrow </title>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.13/p5.min.js" type="text/javascript"></script>
            +
            +    <script src="sketch.js" type="text/javascript"></script>
            +
            +    <style> body {padding: 0; margin: 0;} canvas {vertical-align: top;} </style>
            +  </head>
            +  <body>
            +  </body>
            +</html>
            diff --git a/dist/assets/p5_featured/LeslieRuckman_RainbowPixelGrow/sketch.js b/dist/assets/p5_featured/LeslieRuckman_RainbowPixelGrow/sketch.js
            new file mode 100644
            index 0000000000..afe1bb6c62
            --- /dev/null
            +++ b/dist/assets/p5_featured/LeslieRuckman_RainbowPixelGrow/sketch.js
            @@ -0,0 +1,87 @@
            +var lines = [];
            +var x;
            +var y;
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +
            +  var gap = 10;
            +  for (var y = 0; y < height - gap; y += gap * 2) {
            +    for (var x = 0; x < width; x += gap * 2) {
            +      lines.push(new Shape(x, y));
            +    }
            +  }
            +
            +  // println(width);
            +  // println(height);
            +  // println(lines.length);
            +
            +
            +}
            +
            +function draw() {
            +  background(255);
            +
            +  for (var i = 0; i < lines.length; i++) {
            +    // update
            +
            +    // check
            +    lines[i].intersects(); // rollover
            +
            +    // display
            +    lines[i].display();
            +
            +  }
            +
            +  // println(lines.length);
            +
            +}
            +
            +
            +function Shape(x, y) {
            +
            +  this.x = x;
            +  this.y = y;
            +  this.r = 200;
            +  this.scale = 1.0;
            +
            +  var r = map(this.y, 0, height, 10, 255);
            +  var g = map(this.x, 0, width, 10, 255);
            +  var b = random(50, 100);
            +  this.col = color(r, g, b, 10);
            +
            +  this.state = false;
            +  this.grow = 0;
            +  this.turn = 0;
            +
            +  this.display = function(x, y) {
            +    noStroke();
            +    fill(this.col);
            +    rect(this.x, this.y, (5 * this.scale) + this.grow, (5 * this.scale) + this.grow);
            +  }
            +
            +  this.intersects = function() {
            +    var d = dist(this.x, this.y, mouseX, mouseY);
            +    if (d < this.r) {
            +      this.grow = 1.5 * this.scale;
            +      this.state = true;
            +      this.col = this.col;
            +      this.scale = lerp(this.scale, 15, 0.2);
            +      return true;
            +    } else {
            +      this.state = false;
            +      this.col = this.col;
            +      this.scale = lerp(this.scale, 1.5, 0.05);
            +      return false;
            +    }
            +  }
            +}
            +
            +
            +// function mousePressed() {
            +//   for (var i = lines.length - 1; i >= 0; i--) {
            +//     if (lines[i].intersects()) {
            +//       lines.splice(i, 1);
            +//     }
            +//   }
            +// }
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Sarah_voronoi/index.html b/dist/assets/p5_featured/Sarah_voronoi/index.html
            new file mode 100644
            index 0000000000..f2449f72cd
            --- /dev/null
            +++ b/dist/assets/p5_featured/Sarah_voronoi/index.html
            @@ -0,0 +1,15 @@
            +
            +<head>
            +   <!-- <script src="./lib/p5.js"></script> -->
            +   <!-- <script src="./lib/p5.min.js"></script> -->
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
            +   <!-- <script src="./lib/d3.js"></script> -->
            +   <!-- <script src="./lib/d3.min.js"></script> -->
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.7/p5.min.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +  <style> body {padding: 0; margin: 0;} </style>
            +</head>
            +
            +<body>
            +  <script src="sgp_background_sketch.js"></script>
            +</body>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Sarah_voronoi/sgp_background_sketch.js b/dist/assets/p5_featured/Sarah_voronoi/sgp_background_sketch.js
            new file mode 100644
            index 0000000000..048dfee140
            --- /dev/null
            +++ b/dist/assets/p5_featured/Sarah_voronoi/sgp_background_sketch.js
            @@ -0,0 +1,96 @@
            +// Ported by Sarah Groff-Palermo (github: @sarahgp)
            +// With help from http://bl.ocks.org/mbostock/4060366 & the p5/D3
            +// cookbook (http://sciutoalex.github.io/p5-D3-cookbook/recipes-beginner/voronoi/)
            +
            +var c, width, height, polydraw, colorArr, vertices, voronoi, polygons;
            +
            +var iOS = (navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false),
            +    body = document.body,
            +    html = document.documentElement;
            +
            +function getWidth() {
            +  return body.clientWidth;
            +}
            +
            +function getHeight() {
            +  return Math.max(body.scrollHeight, body.offsetHeight, 
            +                    html.clientHeight, html.scrollHeight, html.offsetHeight);
            +}
            +
            +function setup() {
            +
            +  width = getWidth();
            +  height = getHeight();
            +
            +  colorMode(HSL);
            +  c = createCanvas(width, height);
            +  c.parent('home-sketch-frame');
            +
            +  colorArr = [color(240, 5, 29, .05),
            +              color(240, 5, 29, .1),
            +              color(240, 5, 29, .15),
            +              color(240, 5, 39, .05),
            +              color(240, 5, 39, .1),
            +              color(240, 5, 39, .15),
            +              color(240, 5, 49, .05),
            +              color(240, 5, 49, .1),
            +              color(240, 5, 49, .05)];
            +
            +  vertices = d3.range(140).map(function(d) {
            +      return [Math.random() * width, Math.random() * height];
            +    });
            +
            +  voronoi = d3.geom.voronoi()
            +      .clipExtent([[0, 0], [width, height]]);
            +
            +  polygons = voronoi(vertices);
            +
            +  polydraw = function() {
            +    
            +    stroke(255);
            +
            +    for (var j = 0, jL = polygons.length; j < jL; j++) {
            +      
            +      var singlegon = polygons[j];
            +
            +      j === 0 ? fill(color(60, 100, 50, 1)) : 
            +                fill(colorArr[j % colorArr.length]);
            +
            +      beginShape();
            +
            +      for (var k = 0, kL = singlegon.length; k < kL; k++){
            +        vertex(singlegon[k][0], singlegon[k][1]);
            +      }
            +
            +      endShape(CLOSE);
            +
            +    }
            +  }
            +
            +  polydraw();
            +
            +}
            +
            +// on iOS links become unclickable with movement
            +if (!iOS) { 
            +  function mouseMoved() {
            +    c.clear();
            +    vertices[0] = [mouseX, mouseY];
            +    polygons = voronoi(vertices);
            +    polydraw();
            +  }
            +}
            +
            +function windowResized(){  
            +  console.log("resize")
            +  width = getWidth();
            +  height = getHeight();
            +  resizeCanvas(width, height);
            +  voronoi = d3.geom.voronoi()
            +      .clipExtent([[0, 0], [width, height]]);
            +  vertices = d3.range(140).map(function(d) {
            +        return [Math.random() * width, Math.random() * height];
            +      });
            +  polygons = voronoi(vertices);
            +  polydraw();
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/Tai_PursuingRelief/finger01.png b/dist/assets/p5_featured/Tai_PursuingRelief/finger01.png
            new file mode 100644
            index 0000000000..0712fed0de
            Binary files /dev/null and b/dist/assets/p5_featured/Tai_PursuingRelief/finger01.png differ
            diff --git a/dist/assets/p5_featured/Tai_PursuingRelief/index.html b/dist/assets/p5_featured/Tai_PursuingRelief/index.html
            new file mode 100644
            index 0000000000..6f62b43a26
            --- /dev/null
            +++ b/dist/assets/p5_featured/Tai_PursuingRelief/index.html
            @@ -0,0 +1,11 @@
            +<!DOCTYPE html>
            +  <head>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.dom.min.js"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.sound.min.js"></script>
            +    <link rel="stylesheet" type="text/css" href="style.css">
            +  </head>
            +  <body>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            diff --git a/dist/assets/p5_featured/Tai_PursuingRelief/sketch.js b/dist/assets/p5_featured/Tai_PursuingRelief/sketch.js
            new file mode 100644
            index 0000000000..6d96847551
            --- /dev/null
            +++ b/dist/assets/p5_featured/Tai_PursuingRelief/sketch.js
            @@ -0,0 +1,575 @@
            +var img;
            +var finger1 = 0;
            +var finger2 = 0;
            +var finger3 = 0;
            +var finger4 = 0;
            +var finger5 = 0;
            +var finger6 = 0;
            +var finger7 = 0;
            +
            +// MOZZIE #1 : RGB declaration
            +var r, g, b;
            +// MOZZIE #2 : RGB declaration
            +var r2, g2, b2;
            +// MOZZIE #3 : RGB declaration
            +var r3, g3, b3;
            +// MOZZIE #4 : RGB declaration
            +var r4, g4, b4;
            +// MOZZIE #5 : RGB declaration
            +var r5, g5, b5;
            +// MOZZIE #6 : RGB declaration
            +var r6, g6, b6;
            +// MOZZIE #7 : RGB declaration
            +var r7, g7, b7;
            +// MOZZIE #8 : RGB declaration
            +var r8, g8, b8;
            +// MOZZIE #9 : RGB declaration
            +var r9, g9, b9;
            +
            +// Declared MOZZIE #1
            +var mozzie;
            +// Declared MOZZIE #2
            +var mozzie2;
            +// Declared MOZZIE #3
            +var mozzie3;
            +// Declared MOZZIE #4
            +var mozzie4;
            +// Declared MOZZIE #5
            +var mozzie5;
            +// Declared MOZZIE #6
            +var mozzie6;
            +// Declared MOZZIE #7
            +var mozzie7;
            +// Declared MOZZIE #8
            +var mozzie8;
            +// Declared MOZZIE #9
            +var mozzie9;
            +
            +function preload() {
            +  //can only see 'loadImage' in Firefox 
            +  img = loadImage("finger01.png");
            +}
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  imageMode(CORNER);
            +  // MOZZIE #1 :red, green, and blue color values
            +  r = 255;
            +  g = 255;
            +  b = 255;
            +  // MOZZIE #2 :red, green, and blue color values
            +  r2 = 255;
            +  g2 = 255;
            +  b2 = 255;
            +  // MOZZIE #3 :red, green, and blue color values
            +  r3 = 255;
            +  g3 = 255;
            +  b3 = 255;
            +  // MOZZIE #4 :red, green, and blue color values
            +  r4 = 255;
            +  g4 = 255;
            +  b4 = 255;
            +  // MOZZIE #5 :red, green, and blue color values
            +  r5 = 255;
            +  g5 = 255;
            +  b5 = 255;
            +  // MOZZIE #6 :red, green, and blue color values
            +  r6 = 255;
            +  g6 = 255;
            +  b6 = 255;
            +  // MOZZIE #7 :red, green, and blue color values
            +  r7 = 255;
            +  g7 = 255;
            +  b7 = 255;
            +  // MOZZIE #8 :red, green, and blue color values
            +  r8 = 255;
            +  g8 = 255;
            +  b8 = 255;
            +  // MOZZIE #9 :red, green, and blue color values
            +  r9 = 255;
            +  g9 = 255;
            +  b9 = 255;
            +
            +  // MOZZIE #1 
            +  mozzie = {
            +    x: (windowWidth/1200)*80,
            +    y: (windowHeight/640)*300,
            +    show: function() {
            +      noStroke();
            +      strokeWeight(2);
            +      stroke(r, g - 20, b - 20);
            +      fill(r, g - 20, b - 20);
            +      ellipse(this.x, this.y, 50, 50);
            +    },
            +    mousePressed: function() {
            +      var d = dist(mouseX, mouseY, this.x, this.y);
            +      if (d < 28) {
            +        r = 255;
            +        g = g - 20;
            +        b = b - 20;
            +      }
            +    }
            +  }
            +
            +  // MOZZIE #2 - with the new set of variables 
            +  mozzie2 = {
            +    x: (windowWidth/1200)*100,
            +    y: (windowHeight/640)*600,
            +    show: function() {
            +      noStroke();
            +      strokeWeight(2);
            +      stroke(r2, g2 - 20, b2 - 20);
            +      fill(r2, g2 - 20, b2 - 20);
            +      ellipse(this.x, this.y, 50, 50);
            +    },
            +    mousePressed: function() {
            +      var d2 = dist(mouseX, mouseY, this.x, this.y);
            +      if (d2 < 28) {
            +        r2 = 255;
            +        g2 = g2 - 20;
            +        b2 = b2 - 20;
            +      }
            +    }
            +  }
            +
            +  // MOZZIE #3 - with the new set of variables 
            +  mozzie3 = {
            +    x: (windowWidth/1200)*360,
            +    y: (windowHeight/640)*50,
            +    show: function() {
            +      noStroke();
            +      strokeWeight(2);
            +      stroke(r3, g3 - 20, b3 - 20);
            +      fill(r3, g3 - 20, b3 - 20);
            +      ellipse(this.x, this.y, 50, 50);
            +    },
            +    mousePressed: function() {
            +      var d3 = dist(mouseX, mouseY, this.x, this.y);
            +      if (d3 < 28) {
            +        r3 = 255;
            +        g3 = g3 - 20;
            +        b3 = b3 - 20;
            +      }
            +    }
            +  }
            +
            +  // MOZZIE #4 - with the new set of variables 
            +  mozzie4 = {
            +    x: (windowWidth/1200)*800,
            +    y: (windowHeight/640)*400,
            +    show: function() {
            +      noStroke();
            +      strokeWeight(2);
            +      stroke(r4, g4 - 20, b4 - 20);
            +      fill(r4, g4 - 20, b4 - 20);
            +      ellipse(this.x, this.y, 50, 50);
            +    },
            +    mousePressed: function() {
            +      var d4 = dist(mouseX, mouseY, this.x, this.y);
            +      if (d4 < 28) {
            +        r4 = 255;
            +        g4 = g4 - 20;
            +        b4 = b4 - 20;
            +      }
            +    }
            +  }
            +
            +  // MOZZIE #5 - with the new set of variables 
            +  mozzie5 = {
            +    x: (windowWidth/1200)*400,
            +    y: (windowHeight/640)*350,
            +    show: function() {
            +      noStroke();
            +      strokeWeight(2);
            +      stroke(r5, g5 - 20, b5 - 20);
            +      fill(r5, g5 - 20, b5 - 20);
            +      ellipse(this.x, this.y, 50, 50);
            +    },
            +    mousePressed: function() {
            +      var d5 = dist(mouseX, mouseY, this.x, this.y);
            +      if (d5 < 28) {
            +        r5 = 255;
            +        g5 = g5 - 20;
            +        b5 = b5 - 20;
            +      }
            +    }
            +  }
            +
            +  // MOZZIE #6 - with the new set of variables 
            +  mozzie6 = {
            +    x: (windowWidth/1200)*1150,
            +    y: (windowHeight/640)*300,
            +    show: function() {
            +      noStroke();
            +      strokeWeight(2);
            +      stroke(r6, g6 - 20, b6 - 20);
            +      fill(r6, g6 - 20, b6 - 20);
            +      ellipse(this.x, this.y, 50, 50);
            +    },
            +    mousePressed: function() {
            +      var d6 = dist(mouseX, mouseY, this.x, this.y);
            +      if (d6 < 28) {
            +        r6 = 255;
            +        g6 = g6 - 20;
            +        b6 = b6 - 20;
            +      }
            +    }
            +  }
            +
            +  // MOZZIE #7 - with the new set of variables 
            +  mozzie7 = {
            +    x: (windowWidth/1200)*900,
            +    y: (windowHeight/640)*350,
            +    show: function() {
            +      noStroke();
            +      strokeWeight(2);
            +      stroke(r7, g7 - 20, b7 - 20);
            +      fill(r7, g7 - 20, b7 - 20);
            +      ellipse(this.x, this.y, 50, 50);
            +    },
            +    mousePressed: function() {
            +      var d7 = dist(mouseX, mouseY, this.x, this.y);
            +      if (d7 < 28) {
            +        r7 = 255;
            +        g7 = g7 - 20;
            +        b7 = b7 - 20;
            +      }
            +    }
            +  }
            +
            +  // MOZZIE #8 - with the new set of variables 
            +  mozzie8 = {
            +    x: (windowWidth/1200)*890,
            +    y: (windowHeight/640)*610,
            +    show: function() {
            +      noStroke();
            +      strokeWeight(2);
            +      stroke(r8, g8 - 20, b8 - 20);
            +      fill(r8, g8 - 20, b8 - 20);
            +      ellipse(this.x, this.y, 50, 50);
            +    },
            +    mousePressed: function() {
            +      var d8 = dist(mouseX, mouseY, this.x, this.y);
            +      if (d8 < 28) {
            +        r8 = 255;
            +        g8 = g8 - 20;
            +        b8 = b8 - 20;
            +      }
            +    }
            +  }
            +
            +  // MOZZIE #9 - with the new set of variables 
            +  mozzie9 = {
            +    x: (windowWidth/1200)*880,
            +    y: (windowHeight/640)*100,
            +    show: function() {
            +      noStroke();
            +      strokeWeight(2);
            +      stroke(r9, g9 - 20, b9 - 20);
            +      fill(r9, g9 - 20, b9 - 20);
            +      ellipse(this.x, this.y, 50, 50);
            +    },
            +    mousePressed: function() {
            +      var d9 = dist(mouseX, mouseY, this.x, this.y);
            +      if (d9 < 28) {
            +        r9 = 255;
            +        g9 = g9 - 20;
            +        b9 = b9 - 20;
            +      }
            +    }
            +  }
            +
            +}
            +
            +function draw() {
            +  //FINGER
            +  // 'aspect' to keep ratio of image
            +  var aspect = img.height / img.width;
            +  var imageWidth = 150;
            +  var imageHeight = imageWidth * aspect;
            +
            +  background(255, 249, 249);
            +
            +  fingerTopLeft = {
            +    x: (windowWidth/1200)*200,
            +    y: (windowHeight/640)*110,
            +    aspect: img.height / img.width,
            +    imageWidth: 150,
            +    imageHeight: imageWidth * aspect,
            +
            +    show: function() {
            +      push();
            +      translate(this.x, this.y);
            +      scale(-1, 1);
            +      //rotate(radians(frameCount*finger1)
            +      rotate(radians(finger1));
            +      image(img, 0, 0, imageWidth, imageHeight);
            +      pop();
            +
            +    },
            +    mousePressed: function() {
            +      var dfinger1 = dist(mouseX, mouseY, this.x, this.y);
            +      if (dfinger1 < 300) {
            +        finger1 = finger1 + 45;
            +      }
            +    }
            +  }
            +
            +  /*
            +  //fingerTopLeft
            +  //'push' or 'pop'for isolated behaviours
            +  push ();
            +  // 'imageMode' set pivot point to center of image
            +  '
            +  // 'translate': placing pivot point on X-Y grid
            +  translate(200, 110);
            +  // 'scale' to flip
            +  scale(-1,1);
            +  rotate(radians(frameCount * 1.1));
            +  image(img, 0, 0, imageWidth, imageHeight);
            +  pop ();
            +  */
            +
            +  fingerBottomLeft = {
            +    x: (windowWidth/1200)*200,
            +    y: (windowHeight/640)*420,
            +    aspect: img.height / img.width,
            +    imageWidth: 150,
            +    imageHeight: imageWidth * aspect,
            +
            +    show: function() {
            +      push();
            +      translate(this.x, this.y);
            +      scale(-1, 1);
            +      rotate(radians(finger2));
            +      image(img, 0, 0, imageWidth, imageHeight);
            +      pop();
            +
            +    },
            +    mousePressed: function() {
            +      var dfinger2 = dist(mouseX, mouseY, this.x, this.y);
            +      if (dfinger2 < 300) {
            +        finger2 = finger2 + 45;
            +      }
            +    }
            +  }
            +  /*
            +  //fingerBottomLeft
            +  push ();
            +  '
            +  translate(200, 420);
            +  //scale(-1,1);
            +  rotate(radians(frameCount * 2));
            +  image(img, 0, 0, imageWidth, imageHeight);
            +  pop ();
            +  */
            +
            +  fingerTopMid = {
            +    x: (windowWidth/1200)*580,
            +    y: (windowHeight/640)*50,
            +    aspect: img.height / img.width,
            +    imageWidth: 150,
            +    imageHeight: imageWidth * aspect,
            +
            +    show: function() {
            +      push();
            +      translate(this.x, this.y);
            +      scale(-1, 1);
            +      rotate(radians(finger3));
            +      image(img, 0, 0, imageWidth, imageHeight);
            +      pop();
            +
            +    },
            +    mousePressed: function() {
            +      var dfinger3 = dist(mouseX, mouseY, this.x, this.y);
            +      if (dfinger3 < 200) {
            +        finger3 = finger3 + 45;
            +      }
            +    }
            +  }
            +  /*
            +  //fingerTopMid
            +  push ();
            +  '
            +  translate(580, 150);
            +  scale(-1,1);
            +  rotate(radians(frameCount));
            +  image(img, 0, 0, imageWidth, imageHeight);
            +  pop ();
            +  */
            +
            +  fingerMidMid = {
            +    x: (windowWidth/1200)*700,
            +    y: (windowHeight/640)*320,
            +    aspect: img.height / img.width,
            +    imageWidth: 150,
            +    imageHeight: imageWidth * aspect,
            +
            +    show: function() {
            +      push();
            +      translate(this.x, this.y);
            +      scale(-1, 1);
            +      rotate(radians(finger4));
            +      image(img, 0, 0, imageWidth, imageHeight);
            +      pop();
            +
            +    },
            +    mousePressed: function() {
            +      var dfinger4 = dist(mouseX, mouseY, this.x, this.y);
            +      if (dfinger4 < 200) {
            +        finger4 = finger4 + 45;
            +      }
            +    }
            +  }
            +
            +  /*
            +  //fingerMidMid
            +  push ();
            +  '
            +  translate(680, 350);
            +  scale(-1,1);
            +  rotate(radians(frameCount * 2.5));
            +  image(img, 0, 0, imageWidth, imageHeight);
            +  pop ();
            +  */
            +
            +  fingerBottomMid = {
            +    x: (windowWidth/1200)*550,
            +    y: (windowHeight/640)*480,
            +    aspect: img.height / img.width,
            +    imageWidth: 150,
            +    imageHeight: imageWidth * aspect,
            +
            +    show: function() {
            +      push();
            +      translate(this.x, this.y);
            +      scale(-1, 1);
            +      rotate(radians(finger5));
            +      image(img, 0, 0, imageWidth, imageHeight);
            +      pop();
            +
            +    },
            +    mousePressed: function() {
            +      var dfinger5 = dist(mouseX, mouseY, this.x, this.y);
            +      if (dfinger5 < 200) {
            +        finger5 = finger5 + 45;
            +      }
            +    }
            +  }
            +
            +  /*
            +  //fingerBottomMid
            +  push ();
            +  '
            +  translate(500, 550);
            +  rotate(radians(frameCount * 3));
            +  image(img, 0, 0, imageWidth, imageHeight);
            +  pop ();
            +  */
            +
            +  fingerTopRight = {
            +    x: (windowWidth/1200)*1100,
            +    y: (windowHeight/640)*105,
            +    aspect: img.height / img.width,
            +    imageWidth: 150,
            +    imageHeight: imageWidth * aspect,
            +
            +    show: function() {
            +      push();
            +      translate(this.x, this.y);
            +      scale(-1, 1);
            +      rotate(radians(finger6));
            +      image(img, 0, 0, imageWidth, imageHeight);
            +      pop();
            +
            +    },
            +    mousePressed: function() {
            +      var dfinger6 = dist(mouseX, mouseY, this.x, this.y);
            +      if (dfinger6 < 200) {
            +        finger6 = finger6 + 45;
            +      }
            +    }
            +  }
            +
            +  /*
            +  //fingerTopRight
            +  push ();
            +  '
            +  translate(900, 105);
            +  scale(-1,1);
            +  rotate(radians(frameCount * 2));
            +  image(img, 0, 0, imageWidth, imageHeight);
            +  pop ();
            +  */
            +
            +  fingerBottomRight = {
            +    x: (windowWidth/1200)*1000,
            +    y: (windowHeight/640)*450,
            +    aspect: img.height / img.width,
            +    imageWidth: 150,
            +    imageHeight: imageWidth * aspect,
            +
            +    show: function() {
            +      push();
            +      translate(this.x, this.y);
            +      scale(-1, 1);
            +      rotate(radians(finger7));
            +      image(img, 0, 0, imageWidth, imageHeight);
            +      pop();
            +
            +    },
            +    mousePressed: function() {
            +      var dfinger7 = dist(mouseX, mouseY, this.x, this.y);
            +      if (dfinger7 < 200) {
            +        finger7 = finger7 + 45;
            +      }
            +    }
            +  }
            +  /*
            +  //fingerBottomRight
            +  push ();
            +  '
            +  translate(1000, 450);
            +  rotate(radians(frameCount * 1.2));
            +  image(img, 0, 0, imageWidth, imageHeight);
            +  pop ();
            +  */
            +
            +  mozzie.show();
            +  mozzie2.show();
            +  mozzie3.show();
            +  mozzie4.show();
            +  mozzie5.show();
            +  mozzie6.show();
            +  mozzie7.show();
            +  mozzie8.show();
            +  mozzie9.show();
            +
            +  fingerTopLeft.show();
            +  fingerBottomLeft.show();
            +  fingerTopMid.show();
            +  fingerMidMid.show();
            +  fingerBottomMid.show();
            +  fingerTopRight.show();
            +  fingerBottomRight.show();
            +}
            +
            +function mousePressed() {
            +  mozzie.mousePressed();
            +  mozzie2.mousePressed();
            +  mozzie3.mousePressed();
            +  mozzie4.mousePressed();
            +  mozzie5.mousePressed();
            +  mozzie6.mousePressed();
            +  mozzie7.mousePressed();
            +  mozzie8.mousePressed();
            +  mozzie9.mousePressed();
            +
            +  fingerTopLeft.mousePressed();
            +  fingerBottomLeft.mousePressed();
            +  fingerTopMid.mousePressed();
            +  fingerMidMid.mousePressed();
            +  fingerBottomMid.mousePressed();
            +  fingerTopRight.mousePressed();
            +  fingerBottomRight.mousePressed();
            +}
            diff --git a/dist/assets/p5_featured/Tai_PursuingRelief/style.css b/dist/assets/p5_featured/Tai_PursuingRelief/style.css
            new file mode 100644
            index 0000000000..57c14ee231
            --- /dev/null
            +++ b/dist/assets/p5_featured/Tai_PursuingRelief/style.css
            @@ -0,0 +1,4 @@
            +html, body {
            +  margin: 0;
            +  padding: 0;
            +}
            diff --git a/dist/assets/p5_featured/browning/bubble.js b/dist/assets/p5_featured/browning/bubble.js
            new file mode 100644
            index 0000000000..1cb3866dae
            --- /dev/null
            +++ b/dist/assets/p5_featured/browning/bubble.js
            @@ -0,0 +1,53 @@
            +function Bubble(x, y) {
            +	this.x = x;
            +  this.col = color(141, 115, 243);
            +  
            +  this.history = []; /* history */
            +  
            +  this.y = y; 
            +	this.r = 20;
            +	this.display = function() {
            +  	fill(this.col);
            +  	ellipse(this.x, this.y, this.r * 2, this.r * 2);
            +
            +	}
            +  this.changeColor = function() {
            +    this.col = color(random(255));
            +  }
            +  this.intersects = function(other) {
            +  	var d = dist(this.x, this.y, other.x, other.y);
            +    if (d < this.r + other.r) {     
            +      return true;
            +    }else {
            +      return false; 
            +    }   
            +  }
            +  this.update = function() {
            +    this.x += random(-5, 5);
            +    this.y += random(-5, 5);
            +    
            +    for (var i = 0; i < this.history.length; i++) {
            +      this.history[i].x += random(-3, 3);
            +      this.history[i].y += random(-3, 3);
            +    }
            +
            +    var v = createVector(this.x, this.y);
            +    this.history.push(v); 
            +    if (this.history.length > 80) {
            +      this.history.splice(0, 1);
            +    }
            +  }
            +  
            +  this.show = function() {
            +   //ellipse(this.x, this.y, 24, 24);
            +    
            +    noFill();
            +    for (var i = 0; i < this.history.length; i++) {
            +      var pos = this.history[i];
            +      //fill(255);
            +      ellipse(pos.x, pos.y, i*1.2, i*1.2);
            +    	//vertex(pos.x, pos.y);
            +    }
            +  	
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/browning/index.html b/dist/assets/p5_featured/browning/index.html
            new file mode 100644
            index 0000000000..7b0c3e709b
            --- /dev/null
            +++ b/dist/assets/p5_featured/browning/index.html
            @@ -0,0 +1,11 @@
            +<!DOCTYPE html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
            +    <script src="../../js/p5.min.js"></script>
            +    <script src="../../js/p5.dom.min.js"></script>
            +    <script src="../../js/p5.sound.min.js"></script>
            +    <script src="bubble.js"></script>
            +    <script src="sketch.js"></script>
            +  </head>
            +  <body>
            +    
            +  </body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/browning/sketch.js b/dist/assets/p5_featured/browning/sketch.js
            new file mode 100644
            index 0000000000..39c038c1f0
            --- /dev/null
            +++ b/dist/assets/p5_featured/browning/sketch.js
            @@ -0,0 +1,35 @@
            +var bubbles = [];
            +
            +function setup() { 
            +  createCanvas(windowWidth, windowHeight);
            +  for (var i = 0; i < 1; i++) { 
            +    bubbles[i] = new Bubble(random(width), random(height)); 
            +  } 
            +
            +  stroke(141, 115, 243);
            +}
            +
            +function mousePressed() {
            +  bubbles.push(new Bubble(mouseX, mouseY)); 
            +}
            +
            +function keyPressed() {
            +  bubbles.splice(0,1);    
            +}
            +
            +function draw() {
            +  background(255);
            +  for (var i = 0;i < bubbles.length; i++) {
            +    bubbles[i].update();
            +    bubbles[i].display();
            +    bubbles[i].show();
            +      
            +  
            +    for (var j = 0; j < bubbles.length; j++) {
            +      if (i != j && bubbles[i].intersects(bubbles[j])) {
            +        bubbles[i].changeColor();
            +        bubbles[j].changeColor();
            +      } 
            +    }
            +  }
            +}   
            diff --git a/dist/assets/p5_featured/browning/style.css b/dist/assets/p5_featured/browning/style.css
            new file mode 100644
            index 0000000000..57c14ee231
            --- /dev/null
            +++ b/dist/assets/p5_featured/browning/style.css
            @@ -0,0 +1,4 @@
            +html, body {
            +  margin: 0;
            +  padding: 0;
            +}
            diff --git a/dist/assets/p5_featured/fengyizhu_points/index.html b/dist/assets/p5_featured/fengyizhu_points/index.html
            new file mode 100644
            index 0000000000..54fe30ba83
            --- /dev/null
            +++ b/dist/assets/p5_featured/fengyizhu_points/index.html
            @@ -0,0 +1,14 @@
            +<!DOCTYPE html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            +    <meta charset="UTF-8">
            +    <title>points</title>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.4/p5.min.js" type="text/javascript"></script><style type="text/css"></style>
            +
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.4/addons/p5.dom.min.js" type="text/javascript"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.4/addons/p5.sound.min.js" type="text/javascript"></script>
            +
            +    <script src="sketch.js" type="text/javascript"></script>
            +
            +    <style> body {padding: 0; margin: 0;} canvas {vertical-align: top;} </style>
            +  </head>
            +  <body></body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/fengyizhu_points/sketch.js b/dist/assets/p5_featured/fengyizhu_points/sketch.js
            new file mode 100644
            index 0000000000..c3b20c016c
            --- /dev/null
            +++ b/dist/assets/p5_featured/fengyizhu_points/sketch.js
            @@ -0,0 +1,157 @@
            +var BEI = 0;
            +var DONGBEI = 1;
            +var DONG = 2;
            +var DONGNAN = 3;
            +var NAN = 4;
            +var XINAN = 5;
            +var XI = 6;
            +var XIBEI = 7;
            +
            +var stepSize = 1;
            +var spacing = 10;
            +
            +var d;
            +var counter = 0;
            +
            +
            +points = [];
            +
            +function windowResized() {
            +  resizeCanvas(windowWidth, windowHeight);
            +}
            +
            +function setup() {
            +  var c = createCanvas(windowWidth, windowHeight);
            +  c.parent('home-sketch-frame');
            +  background(0);
            +  for (var i = 0; i < 300; i++) {
            +    points.push(new Point(int(800 / (spacing * 2)), int(800 / (spacing * 2))));
            +  }
            +}
            +
            +function mousePressed() {
            +  background(255);
            +}
            +
            +function draw() {
            +  counter++;
            +  // print(counter);
            +  //Behavior 6
            +  if (counter < 200) {
            +    var alp = map(counter, 0, 700, 10, 0.8);
            +  } else {
            +    alp = 0.8;
            +  }
            +  background(255,alp);
            +
            +  //Behavoir 5
            +  if (counter > 8100) {
            +    var z = map(counter, 8100, 15200, 0.8, 255);
            +  } else {
            +    z = 0.8;
            +  }
            +  
            +  background(255, z);
            +  
            +  push();
            +  translate(windowWidth / 2 - 600, windowHeight / 2 - 600);
            +  scale(1.5);
            +
            +  for (var i = 0; i < points.length; i++) {
            +    points[i].update();
            +    points[i].display();
            +    points[i].setPrevPosition();
            +  }
            +  pop();
            +}
            +
            +////////////////////////////////////////// Point ////////////////////////////////////////////
            +
            +function Point(_x, _y) {
            +  this.x = _x;
            +  this.y = _y;
            +  this.px;
            +  this.py;
            +  //this.color = color(13, 86, 97);
            +  this.color = color(random(150,255), 195, 205);
            +
            +  this.display = function() {
            +    push();
            +    //Behavior 3
            +    if (counter > 3700) {
            +      var r = map(counter, 3700, 5200, random(150,255), 242);
            +      var g = map(counter, 3700, 5200, 195, 21);
            +      var b = map(counter, 3700, 5200, 205, 91);
            +      stroke(r, g, b);
            +    } else {
            +      stroke(this.color);
            +    }
            +    //Behavior 1
            +    if (counter > 1200) {
            +      strokeWeight(1.9);
            +    } else {
            +      var l = map(counter, 0, 1200, 0.01, 1.899);
            +      strokeWeight(l);
            +    }
            +    line(this.x * spacing, this.y * spacing, this.px * spacing, this.py * spacing);
            +    pop();
            +
            +    noStroke(0);
            +    //Behavior 2
            +    var d;
            +    if (counter <= 1200) {
            +      d = 0.1;
            +    } else {
            +      d = map(counter, 1200, 3200, 0.1, 7.999);
            +    }
            +    if (counter > 3200) {
            +      d = 8;
            +    }
            +    fill(255);
            +    smooth();
            +    ellipse(this.x * spacing, this.y * spacing, d, d);
            +  }
            +
            +  this.setPrevPosition = function() {
            +    this.px = this.x;
            +    this.py = this.y;
            +  }
            +  this.update = function() {
            +    //Behavior 0 
            +    var direction = int(random(0, 8));
            +
            +    if (direction == BEI) {
            +      this.y -= stepSize;
            +    } else if (direction == DONGBEI) {
            +      this.x += stepSize;
            +      this.y -= stepSize;
            +    } else if (direction == DONG) {
            +      this.x += stepSize;
            +    } else if (direction == DONGNAN) {
            +      this.x += stepSize;
            +      this.y += stepSize;
            +    } else if (direction == NAN) {
            +      this.y += stepSize;
            +    } else if (direction == XINAN) {
            +      this.x -= stepSize;
            +      this.y += stepSize;
            +    } else if (direction == XI) {
            +      this.x -= stepSize;
            +    } else if (direction == XIBEI) {
            +      this.x -= stepSize;
            +      this.y -= stepSize;
            +    }
            +    if (this.x > 1500 / spacing - 1) {
            +      this.x = 1500 / spacing - 2;
            +    }
            +    if (this.x < -700) {
            +      this.x = -700;
            +    }
            +    if (this.y < -100) {
            +      this.y = -100;
            +    }
            +    if (this.y > 900 / spacing - 1) {
            +      this.y = 900 / spacing - 2;
            +    }
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/hsinyu_lin/index.html b/dist/assets/p5_featured/hsinyu_lin/index.html
            new file mode 100644
            index 0000000000..a4e83dec04
            --- /dev/null
            +++ b/dist/assets/p5_featured/hsinyu_lin/index.html
            @@ -0,0 +1,24 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>Untitled</title>
            +    <script src="//cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.8/p5.min.js" type="text/javascript"></script>
            +    <script src="//cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.8/addons/p5.dom.min.js" type="text/javascript"></script>
            +    <script src="sketch.js" type="text/javascript"></script>
            +    
            +    <style> 
            +    
            +    body {padding: 0; margin: 0;} 
            +    canvas {vertical-align: top;} 
            +    #sketchA {position: absolute; top: 0px; left:0px; z-index:4;}
            +    #sketchB {position: absolute; top: 0px; left:0px; z-index:-1;}
            +    </style>
            +  </head>
            + 
            +  <body>
            +   <div id="sketchA">
            +   </div>
            +   <div id="sketchB">
            +   </div>
            +  </body>
            +</html>
            diff --git a/dist/assets/p5_featured/hsinyu_lin/sketch.js b/dist/assets/p5_featured/hsinyu_lin/sketch.js
            new file mode 100644
            index 0000000000..ac8d223334
            --- /dev/null
            +++ b/dist/assets/p5_featured/hsinyu_lin/sketch.js
            @@ -0,0 +1,44 @@
            +/* The Sound of an Effect (p5js version) by Hsinyu Lin, 2017 */
            +
            +var f, f1;
            +var pos = 0.00003;
            +var capture;
            +var button;
            +
            +function setup() {
            + createCanvas(windowWidth, windowHeight);
            + capture = createCapture(VIDEO);
            + capture.hide();
            + imageMode(CENTER);
            + button = createButton('hide sketch');
            + button.position(10, 44);
            + button.mousePressed(toggleSketch);
            +}
            +
            +function draw() {
            + // background(255);
            + translate(width / 2, height / 2);
            + for (f = 0; f < windowWidth; f += 85) {
            +  for (f1 = 0; f1 < windowHeight; f1 += 85) {
            +   rotate(PI / pos);
            +   image(capture, f + random(1, 10), f1 + random(1, 10), 65, 65, f + random(0.5, 1), f1, [80 + random(1, 3)], [80]);
            +  }
            + }
            +}
            +
            +function mouseWheel(event) {
            + print(event.delta);
            + pos += event.delta;
            + console.log(pos);
            +}
            +
            +function toggleSketch() {
            +  console.log(canvas.style.display)
            +  if (canvas.style.display === 'none') {
            +    canvas.style.display = 'block';
            +    button.html('hide sketch');
            +  } else {
            +    canvas.style.display = 'none';
            +    button.html('show sketch');
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/karenpeng_homepagesketch/index.html b/dist/assets/p5_featured/karenpeng_homepagesketch/index.html
            new file mode 100644
            index 0000000000..325f490e25
            --- /dev/null
            +++ b/dist/assets/p5_featured/karenpeng_homepagesketch/index.html
            @@ -0,0 +1,11 @@
            +<!DOCTYPE html>
            +  <head>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.10/p5.min.js"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.10/addons/p5.dom.min.js"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.10/addons/p5.sound.min.js"></script>
            +    <link rel="stylesheet" type="text/css" href="style.css">
            +  </head>
            +  <body>
            +    <script src="sketch.js"></script>
            +  </body>
            +</html>
            diff --git a/dist/assets/p5_featured/karenpeng_homepagesketch/sketch.js b/dist/assets/p5_featured/karenpeng_homepagesketch/sketch.js
            new file mode 100644
            index 0000000000..d897d46fa0
            --- /dev/null
            +++ b/dist/assets/p5_featured/karenpeng_homepagesketch/sketch.js
            @@ -0,0 +1,98 @@
            +var FRAME_RATE = 50;
            +var MY_RADIUS = 10;
            +var MAX_SPEED = 10;
            +var walkerManagers = [];
            +
            +function Walker(x, y, radius, index) {
            +  this.x = x;
            +  this.y = y;
            +  this.radius = radius;
            +  this.index = index;
            +}
            +
            +Walker.prototype.update = function(time) {
            +  this.x += (sin(this.index + time) + map(noise(time, this.index), 0, 1, -2, 2));
            +  this.y += (cos(this.index + time) + map(noise(time, this.index), 0, 1, -2, 2));
            +  this.radius -= 0.08;
            +}
            +
            +Walker.prototype.render = function() {
            +  noStroke();
            +  fill(206, 33, 89, 90);
            +  ellipse(this.x, this.y, this.radius + 2, this.radius + 2);
            +  fill(206, 33, 89);
            +  ellipse(this.x, this.y, this.radius, this.radius);
            +}
            +
            +function WalkerManager(x, y) {
            +  this.x = x;
            +  this.y = y;
            +  this.loc = createVector(random(x), random(y));
            +  this.loc.x = constrain(this.loc.x, MY_RADIUS, width - MY_RADIUS);
            +  this.loc.y = constrain(this.loc.y, MY_RADIUS, height - MY_RADIUS);
            +  this.noff = createVector(random(10), random(10));
            +  this.counter = 0;
            +  this.history = [];
            +}
            +
            +WalkerManager.prototype.walk = function (time) {
            +
            +  if (isMousePressed) {
            +    var easing = createVector(mouseX, mouseY).sub(this.loc).mult(0.06);
            +    this.loc.add(easing);
            +  } else {
            +    var lerpX = map(noise(this.noff.y, this.noff.x), 0, 1, MAX_SPEED * -1, MAX_SPEED);
            +    var lerpY = map(noise(this.noff.x, this.noff.y), 0, 1, MAX_SPEED * -1, MAX_SPEED);
            +
            +    this.loc.add(createVector(lerpX, lerpY));
            +    this.loc.x = constrain(this.loc.x, MY_RADIUS, width - MY_RADIUS);
            +    this.loc.y = constrain(this.loc.y, MY_RADIUS, height - MY_RADIUS);
            +
            +    var nLerp = map(noise(this.counter), 0, 1, 0, 0.01);
            +    this.noff.add(nLerp, nLerp);
            +  }
            +
            +  this.radius = noise(time) * 40;
            +  this.history.push(new Walker(this.loc.x, this.loc.y, this.radius, this.counter));
            +  this.counter++;
            +};
            +
            +WalkerManager.prototype.update = function(time) {
            +  this.history.forEach(function(walker, index) {
            +    if (index === this.history.length - 1) {
            +      return;
            +    }
            +    walker.update(time);
            +    if (walker.radius <= 0) {
            +      this.history.splice(index, 1);
            +    }
            +  }.bind(this));
            +}
            +
            +WalkerManager.prototype.render = function () {
            +  this.history.forEach(function(walker, index) {
            +    walker.render();
            +  });
            +  var lastWalker = this.history[this.history.length - 1];
            +  var radius = Math.min(lastWalker.radius + 6, MY_RADIUS * 2);
            +  fill(206, 33, 89, 90);
            +  ellipse(lastWalker.x, lastWalker.y, radius, radius);
            +};
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  frameRate(FRAME_RATE);
            +  background(255);
            +  for(var i = 0; i < 1; i++) {
            +    walkerManagers.push(new WalkerManager(width, height));
            +  }
            +}
            +
            +function draw() {
            +  background(255);
            +  walkerManagers.forEach(function(walkerManager) {
            +    walkerManager.walk(frameCount * 0.1);
            +    walkerManager.render();
            +    walkerManager.update(frameCount * 0.1);
            +  });
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/karenpeng_homepagesketch/style.css b/dist/assets/p5_featured/karenpeng_homepagesketch/style.css
            new file mode 100644
            index 0000000000..57c14ee231
            --- /dev/null
            +++ b/dist/assets/p5_featured/karenpeng_homepagesketch/style.css
            @@ -0,0 +1,4 @@
            +html, body {
            +  margin: 0;
            +  padding: 0;
            +}
            diff --git a/dist/assets/p5_featured/kay/images/bread.png b/dist/assets/p5_featured/kay/images/bread.png
            new file mode 100644
            index 0000000000..349cf163cd
            Binary files /dev/null and b/dist/assets/p5_featured/kay/images/bread.png differ
            diff --git a/dist/assets/p5_featured/kay/images/peach.png b/dist/assets/p5_featured/kay/images/peach.png
            new file mode 100644
            index 0000000000..4e90fdaa84
            Binary files /dev/null and b/dist/assets/p5_featured/kay/images/peach.png differ
            diff --git a/dist/assets/p5_featured/kay/images/ray.png b/dist/assets/p5_featured/kay/images/ray.png
            new file mode 100644
            index 0000000000..ca22993c60
            Binary files /dev/null and b/dist/assets/p5_featured/kay/images/ray.png differ
            diff --git a/dist/assets/p5_featured/kay/images/sir-left.png b/dist/assets/p5_featured/kay/images/sir-left.png
            new file mode 100644
            index 0000000000..70cedf1cfc
            Binary files /dev/null and b/dist/assets/p5_featured/kay/images/sir-left.png differ
            diff --git a/dist/assets/p5_featured/kay/images/sir-right.png b/dist/assets/p5_featured/kay/images/sir-right.png
            new file mode 100644
            index 0000000000..d1d1e02430
            Binary files /dev/null and b/dist/assets/p5_featured/kay/images/sir-right.png differ
            diff --git a/dist/assets/p5_featured/kay/images/sun.png b/dist/assets/p5_featured/kay/images/sun.png
            new file mode 100644
            index 0000000000..ad581a46c1
            Binary files /dev/null and b/dist/assets/p5_featured/kay/images/sun.png differ
            diff --git a/dist/assets/p5_featured/kay/images/tomato.png b/dist/assets/p5_featured/kay/images/tomato.png
            new file mode 100644
            index 0000000000..41a1c32377
            Binary files /dev/null and b/dist/assets/p5_featured/kay/images/tomato.png differ
            diff --git a/dist/assets/p5_featured/kay/images/tree-over.png b/dist/assets/p5_featured/kay/images/tree-over.png
            new file mode 100644
            index 0000000000..8f6fe8b434
            Binary files /dev/null and b/dist/assets/p5_featured/kay/images/tree-over.png differ
            diff --git a/dist/assets/p5_featured/kay/images/tree.png b/dist/assets/p5_featured/kay/images/tree.png
            new file mode 100644
            index 0000000000..a2b856f5fb
            Binary files /dev/null and b/dist/assets/p5_featured/kay/images/tree.png differ
            diff --git a/dist/assets/p5_featured/kay/index.html b/dist/assets/p5_featured/kay/index.html
            new file mode 100644
            index 0000000000..4bcea19f07
            --- /dev/null
            +++ b/dist/assets/p5_featured/kay/index.html
            @@ -0,0 +1,18 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>Untitled</title>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js" type="text/javascript"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/addons/p5.dom.js" type="text/javascript"></script>
            +    <script src="libraries/p5.play.js" type="text/javascript"></script>
            +    <script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
            +    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js" integrity="sha256-T0Vest3yCU7pafRw9r+settMBX6JkKN06dqBnpQ8d30=" crossorigin="anonymous"></script>
            +
            +    <script src="sketch.js" type="text/javascript"></script>
            +    <script src="scripts/tree.js" type="text/javascript"></script>
            +    <style> body {padding: 0; margin: 0; overflow: hidden;} canvas {vertical-align: top;} </style>
            +  </head>
            +  <body>
            +    <div id="p5_loading" class="loadingclass"></div>
            +  </body>
            +</html>
            diff --git a/dist/assets/p5_featured/kay/libraries/p5.play.js b/dist/assets/p5_featured/kay/libraries/p5.play.js
            new file mode 100644
            index 0000000000..5143cbaff1
            --- /dev/null
            +++ b/dist/assets/p5_featured/kay/libraries/p5.play.js
            @@ -0,0 +1,4349 @@
            +/*
            +p5.play
            +by Paolo Pedercini/molleindustria, 2015
            +http://molleindustria.org/
            +*/
            +
            +(function(root, factory) {
            +if (typeof define === 'function' && define.amd)
            +define('p5.play', ['p5'], function(p5) { (factory(p5)); });
            +else if (typeof exports === 'object')
            +factory(require('../p5'));
            +else
            +factory(root.p5);
            +}(this, function(p5) {
            +/**
            + * p5.play is a library for p5.js to facilitate the creation of games and gamelike
            + * projects.
            + *
            + * It provides a flexible Sprite class to manage visual objects in 2D space
            + * and features such as animation support, basic collision detection
            + * and resolution, mouse and keyboard interactions, and a virtual camera.
            + *
            + * p5.play is not a box2D-derived physics engine, it doesn't use events, and it's
            + * designed to be understood and possibly modified by intermediate programmers.
            + *
            + * See the examples folder for more info on how to use this library.
            + *
            + * @module p5.play
            + * @submodule p5.play
            + * @for p5.play
            + * @main
            + */
            +
            +// =============================================================================
            +//                         initialization
            +// =============================================================================
            +
            +// This is the new way to initialize custom p5 properties for any p5 instance.
            +// The goal is to migrate lazy P5 properties over to this method.
            +// @see https://github.com/molleindustria/p5.play/issues/46
            +p5.prototype.registerMethod('init', function p5PlayInit() {
            +  /**
            +   * The sketch camera automatically created at the beginning of a sketch.
            +   * A camera facilitates scrolling and zooming for scenes extending beyond
            +   * the canvas. A camera has a position, a zoom factor, and the mouse
            +   * coordinates relative to the view.
            +   *
            +   * In p5.js terms the camera wraps the whole drawing cycle in a
            +   * transformation matrix but it can be disabled anytime during the draw
            +   * cycle, for example to draw interface elements in an absolute position.
            +   *
            +   * @property camera
            +   * @type {camera}
            +   */
            +  this.camera = new Camera(this, 0, 0, 1);
            +  this.camera.init = false;
            +});
            +
            +// This provides a way for us to lazily define properties that
            +// are global to p5 instances.
            +//
            +// Note that this isn't just an optimization: p5 currently provides no
            +// way for add-ons to be notified when new p5 instances are created, so
            +// lazily creating these properties is the *only* mechanism available
            +// to us. For more information, see:
            +//
            +// https://github.com/processing/p5.js/issues/1263
            +function defineLazyP5Property(name, getter) {
            +  Object.defineProperty(p5.prototype, name, {
            +    configurable: true,
            +    enumerable: true,
            +    get: function() {
            +      var context = (this instanceof p5 && !this._isGlobal) ? this : window;
            +
            +      if (typeof(context._p5PlayProperties) === 'undefined') {
            +        context._p5PlayProperties = {};
            +      }
            +      if (!(name in context._p5PlayProperties)) {
            +        context._p5PlayProperties[name] = getter.call(context);
            +      }
            +      return context._p5PlayProperties[name];
            +    }
            +  });
            +}
            +
            +// This returns a factory function, suitable for passing to
            +// defineLazyP5Property, that returns a subclass of the given
            +// constructor that is always bound to a particular p5 instance.
            +function boundConstructorFactory(constructor) {
            +  if (typeof(constructor) !== 'function')
            +    throw new Error('constructor must be a function');
            +
            +  return function createBoundConstructor() {
            +    var pInst = this;
            +
            +    function F() {
            +      var args = Array.prototype.slice.call(arguments);
            +
            +      return constructor.apply(this, [pInst].concat(args));
            +    }
            +    F.prototype = constructor.prototype;
            +
            +    return F;
            +  };
            +}
            +
            +// This is a utility that makes it easy to define convenient aliases to
            +// pre-bound p5 instance methods.
            +//
            +// For example:
            +//
            +//   var pInstBind = createPInstBinder(pInst);
            +//
            +//   var createVector = pInstBind('createVector');
            +//   var loadImage = pInstBind('loadImage');
            +//
            +// The above will create functions createVector and loadImage, which can be
            +// used similar to p5 global mode--however, they're bound to specific p5
            +// instances, and can thus be used outside of global mode.
            +function createPInstBinder(pInst) {
            +  return function pInstBind(methodName) {
            +    var method = pInst[methodName];
            +
            +    if (typeof(method) !== 'function')
            +      throw new Error('"' + methodName + '" is not a p5 method');
            +    return method.bind(pInst);
            +  };
            +}
            +
            +// These are utility p5 functions that don't depend on p5 instance state in
            +// order to work properly, so we'll go ahead and make them easy to
            +// access without needing to bind them to a p5 instance.
            +var abs = p5.prototype.abs;
            +var radians = p5.prototype.radians;
            +var dist = p5.prototype.dist;
            +var degrees = p5.prototype.degrees;
            +var pow = p5.prototype.pow;
            +var round = p5.prototype.round;
            +
            +
            +// =============================================================================
            +//                         p5 additions
            +// =============================================================================
            +
            +/**
            +* A Group containing all the sprites in the sketch.
            +*
            +* @property allSprites
            +* @type {Group}
            +*/
            +
            +defineLazyP5Property('allSprites', function() {
            +  return new p5.prototype.Group();
            +});
            +
            +p5.prototype.spriteUpdate = true;
            +
            +/**
            +   * A Sprite is the main building block of p5.play:
            +   * an element able to store images or animations with a set of
            +   * properties such as position and visibility.
            +   * A Sprite can have a collider that defines the active area to detect
            +   * collisions or overlappings with other sprites and mouse interactions.
            +   *
            +   * Sprites created using createSprite (the preferred way) are added to the
            +   * allSprites group and given a depth value that puts it in front of all
            +   * other sprites.
            +   *
            +   * @method createSprite
            +   * @param {Number} x Initial x coordinate
            +   * @param {Number} y Initial y coordinate
            +   * @param {Number} width Width of the placeholder rectangle and of the
            +   *                       collider until an image or new collider are set
            +   * @param {Number} height Height of the placeholder rectangle and of the
            +   *                       collider until an image or new collider are set
            +   * @return {Object} The new sprite instance
            +   */
            +
            +p5.prototype.createSprite = function(x, y, width, height) {
            +  var s = new Sprite(this, x, y, width, height);
            +  s.depth = this.allSprites.maxDepth()+1;
            +  this.allSprites.add(s);
            +  return s;
            +};
            +
            +
            +/**
            +   * Removes a Sprite from the sketch.
            +   * The removed Sprite won't be drawn or updated anymore.
            +   * Equivalent to Sprite.remove()
            +   *
            +   * @method removeSprite
            +   * @param {Object} sprite Sprite to be removed
            +*/
            +p5.prototype.removeSprite = function(sprite) {
            +  sprite.remove();
            +};
            +
            +/**
            +* Updates all the sprites in the sketch (position, animation...)
            +* it's called automatically at every draw().
            +* It can be paused by passing a parameter true or false;
            +* Note: it does not render the sprites.
            +*
            +* @method updateSprites
            +* @param {Boolean} updating false to pause the update, true to resume
            +*/
            +p5.prototype.updateSprites = function(upd) {
            +
            +  if(upd === false)
            +    this.spriteUpdate = false;
            +  if(upd === true)
            +    this.spriteUpdate = true;
            +
            +  if(this.spriteUpdate)
            +  for(var i = 0; i<this.allSprites.size(); i++)
            +  {
            +    this.allSprites.get(i).update();
            +  }
            +};
            +
            +/**
            +* Returns all the sprites in the sketch as an array
            +*
            +* @method getSprites
            +* @return {Array} Array of Sprites
            +*/
            +p5.prototype.getSprites = function() {
            +
            +  //draw everything
            +  if(arguments.length===0)
            +  {
            +    return this.allSprites.toArray();
            +  }
            +  else
            +  {
            +    var arr = [];
            +    //for every tag
            +    for(var j=0; j<arguments.length; j++)
            +    {
            +      for(var i = 0; i<this.allSprites.size(); i++)
            +      {
            +        if(this.allSprites.get(i).isTagged(arguments[j]))
            +          arr.push(this.allSprites.get(i));
            +      }
            +    }
            +
            +    return arr;
            +  }
            +
            +};
            +
            +/**
            +* Displays a Group of sprites.
            +* If no parameter is specified, draws all sprites in the
            +* sketch.
            +* The drawing order is determined by the Sprite property "depth"
            +*
            +* @method drawSprites
            +* @param {Group} [group] Group of Sprites to be displayed
            +*/
            +p5.prototype.drawSprites = function(group) {
            +  // If no group is provided, draw the allSprites group.
            +  group = group || this.allSprites;
            +
            +  if (typeof group.draw !== 'function')
            +  {
            +    throw('Error: with drawSprites you can only draw all sprites or a group');
            +  }
            +
            +  group.draw();
            +};
            +
            +/**
            +* Displays a Sprite.
            +* To be typically used in the main draw function.
            +*
            +* @method drawSprite
            +* @param {Sprite} sprite Sprite to be displayed
            +*/
            +p5.prototype.drawSprite = function(sprite) {
            +  if(sprite)
            +  sprite.display();
            +};
            +
            +/**
            +* Loads an animation.
            +* To be typically used in the preload() function of the sketch.
            +*
            +* @method loadAnimation
            +* @param {Sprite} sprite Sprite to be displayed
            +*/
            +p5.prototype.loadAnimation = function() {
            +  return construct(this.Animation, arguments);
            +};
            +
            +/**
            + * Loads a Sprite Sheet.
            + * To be typically used in the preload() function of the sketch.
            + *
            + * @method loadSpriteSheet
            + */
            +p5.prototype.loadSpriteSheet = function() {
            +  return construct(this.SpriteSheet, arguments);
            +};
            +
            +/**
            +* Displays an animation.
            +*
            +* @method animation
            +* @param {Animation} anim Animation to be displayed
            +* @param {Number} x X coordinate
            +* @param {Number} y Y coordinate
            +*
            +*/
            +p5.prototype.animation = function(anim, x, y) {
            +  anim.draw(x, y);
            +};
            +
            +//variable to detect instant presses
            +defineLazyP5Property('_p5play', function() {
            +  return {
            +    keyStates: {},
            +    mouseStates: {}
            +  };
            +});
            +
            +var KEY_IS_UP = 0;
            +var KEY_WENT_DOWN = 1;
            +var KEY_IS_DOWN = 2;
            +var KEY_WENT_UP = 3;
            +
            +/**
            +* Detects if a key was pressed during the last cycle.
            +* It can be used to trigger events once, when a key is pressed or released.
            +* Example: Super Mario jumping.
            +*
            +* @method keyWentDown
            +* @param {Number|String} key Key code or character
            +* @return {Boolean} True if the key was pressed
            +*/
            +p5.prototype.keyWentDown = function(key) {
            +  return this._isKeyInState(key, KEY_WENT_DOWN);
            +};
            +
            +
            +/**
            +* Detects if a key was released during the last cycle.
            +* It can be used to trigger events once, when a key is pressed or released.
            +* Example: Spaceship shooting.
            +*
            +* @method keyWentUp
            +* @param {Number|String} key Key code or character
            +* @return {Boolean} True if the key was released
            +*/
            +p5.prototype.keyWentUp = function(key) {
            +  return this._isKeyInState(key, KEY_WENT_UP);
            +};
            +
            +/**
            +* Detects if a key is currently pressed
            +* Like p5 keyIsDown but accepts strings and codes
            +*
            +* @method keyDown
            +* @param {Number|String} key Key code or character
            +* @return {Boolean} True if the key is down
            +*/
            +p5.prototype.keyDown = function(key) {
            +  return this._isKeyInState(key, KEY_IS_DOWN);
            +};
            +
            +/**
            + * Detects if a key is in the given state during the last cycle.
            + * Helper method encapsulating common key state logic; it may be preferable
            + * to call keyDown or other methods directly.
            + *
            + * @private
            + * @method _isKeyInState
            + * @param {Number|String} key Key code or character
            + * @param {Number} state Key state to check against
            + * @return {Boolean} True if the key is in the given state
            + */
            +p5.prototype._isKeyInState = function(key, state) {
            +  var keyCode;
            +  var keyStates = this._p5play.keyStates;
            +
            +  if(typeof key === 'string')
            +  {
            +    keyCode = this._keyCodeFromAlias(key);
            +  }
            +  else
            +  {
            +    keyCode = key;
            +  }
            +
            +  //if undefined start checking it
            +  if(keyStates[keyCode]===undefined)
            +  {
            +    if(this.keyIsDown(keyCode))
            +      keyStates[keyCode] = KEY_IS_DOWN;
            +    else
            +      keyStates[keyCode] = KEY_IS_UP;
            +  }
            +
            +  return (keyStates[keyCode] === state);
            +};
            +
            +/**
            +* Detects if a mouse button is currently down
            +* Combines mouseIsPressed and mouseButton of p5
            +*
            +* @method mouseDown
            +* @param {Number} [buttonCode] Mouse button constant LEFT, RIGHT or CENTER
            +* @return {Boolean} True if the button is down
            +*/
            +p5.prototype.mouseDown = function(buttonCode) {
            +  return this._isMouseButtonInState(buttonCode, KEY_IS_DOWN);
            +};
            +
            +/**
            +* Detects if a mouse button is currently up
            +* Combines mouseIsPressed and mouseButton of p5
            +*
            +* @method mouseUp
            +* @param {Number} [buttonCode] Mouse button constant LEFT, RIGHT or CENTER
            +* @return {Boolean} True if the button is up
            +*/
            +p5.prototype.mouseUp = function(buttonCode) {
            +  return this._isMouseButtonInState(buttonCode, KEY_IS_UP);
            +};
            +
            +/**
            + * Detects if a mouse button was released during the last cycle.
            + * It can be used to trigger events once, to be checked in the draw cycle
            + *
            + * @method mouseWentUp
            + * @param {Number} [buttonCode] Mouse button constant LEFT, RIGHT or CENTER
            + * @return {Boolean} True if the button was just released
            + */
            +p5.prototype.mouseWentUp = function(buttonCode) {
            +  return this._isMouseButtonInState(buttonCode, KEY_WENT_UP);
            +};
            +
            +
            +/**
            + * Detects if a mouse button was pressed during the last cycle.
            + * It can be used to trigger events once, to be checked in the draw cycle
            + *
            + * @method mouseWentDown
            + * @param {Number} [buttonCode] Mouse button constant LEFT, RIGHT or CENTER
            + * @return {Boolean} True if the button was just pressed
            + */
            +p5.prototype.mouseWentDown = function(buttonCode) {
            +  return this._isMouseButtonInState(buttonCode, KEY_WENT_DOWN);
            +};
            +
            +/**
            + * Detects if a mouse button is in the given state during the last cycle.
            + * Helper method encapsulating common mouse button state logic; it may be
            + * preferable to call mouseWentUp, etc, directly.
            + *
            + * @private
            + * @method _isMouseButtonInState
            + * @param {Number} [buttonCode] Mouse button constant LEFT, RIGHT or CENTER
            + * @param {Number} state
            + * @return {boolean} True if the button was in the given state
            + */
            +p5.prototype._isMouseButtonInState = function(buttonCode, state) {
            +  var mouseStates = this._p5play.mouseStates;
            +
            +  if(buttonCode === undefined)
            +    buttonCode = this.LEFT;
            +
            +  //undefined = not tracked yet, start tracking
            +  if(mouseStates[buttonCode]===undefined)
            +  {
            +  if(this.mouseIsPressed && this.mouseButton === buttonCode)
            +    mouseStates[buttonCode] = KEY_IS_DOWN;
            +  else
            +    mouseStates[buttonCode] = KEY_IS_UP;
            +  }
            +
            +  return (mouseStates[buttonCode] === state);
            +};
            +
            +
            +/**
            + * An object storing all useful keys for easy access
            + * Key.tab = 9
            + *
            + * @private
            + * @property KEY
            + * @type {Object}
            + */
            +p5.prototype.KEY = {
            +    'BACKSPACE': 8,
            +    'TAB': 9,
            +    'ENTER': 13,
            +    'SHIFT': 16,
            +    'CTRL': 17,
            +    'ALT': 18,
            +    'PAUSE': 19,
            +    'CAPS_LOCK': 20,
            +    'ESC': 27,
            +    'SPACE': 32,
            +    ' ': 32,
            +    'PAGE_UP': 33,
            +    'PAGE_DOWN': 34,
            +    'END': 35,
            +    'HOME': 36,
            +    'LEFT_ARROW': 37,
            +    'LEFT': 37,
            +    'UP_ARROW': 38,
            +    'UP': 38,
            +    'RIGHT_ARROW': 39,
            +    'RIGHT': 39,
            +    'DOWN_ARROW': 40,
            +    'DOWN': 40,
            +    'INSERT': 45,
            +    'DELETE': 46,
            +    '0': 48,
            +    '1': 49,
            +    '2': 50,
            +    '3': 51,
            +    '4': 52,
            +    '5': 53,
            +    '6': 54,
            +    '7': 55,
            +    '8': 56,
            +    '9': 57,
            +    'A': 65,
            +    'B': 66,
            +    'C': 67,
            +    'D': 68,
            +    'E': 69,
            +    'F': 70,
            +    'G': 71,
            +    'H': 72,
            +    'I': 73,
            +    'J': 74,
            +    'K': 75,
            +    'L': 76,
            +    'M': 77,
            +    'N': 78,
            +    'O': 79,
            +    'P': 80,
            +    'Q': 81,
            +    'R': 82,
            +    'S': 83,
            +    'T': 84,
            +    'U': 85,
            +    'V': 86,
            +    'W': 87,
            +    'X': 88,
            +    'Y': 89,
            +    'Z': 90,
            +    '0NUMPAD': 96,
            +    '1NUMPAD': 97,
            +    '2NUMPAD': 98,
            +    '3NUMPAD': 99,
            +    '4NUMPAD': 100,
            +    '5NUMPAD': 101,
            +    '6NUMPAD': 102,
            +    '7NUMPAD': 103,
            +    '8NUMPAD': 104,
            +    '9NUMPAD': 105,
            +    'MULTIPLY': 106,
            +    'PLUS': 107,
            +    'MINUS': 109,
            +    'DOT': 110,
            +    'SLASH1': 111,
            +    'F1': 112,
            +    'F2': 113,
            +    'F3': 114,
            +    'F4': 115,
            +    'F5': 116,
            +    'F6': 117,
            +    'F7': 118,
            +    'F8': 119,
            +    'F9': 120,
            +    'F10': 121,
            +    'F11': 122,
            +    'F12': 123,
            +    'EQUAL': 187,
            +    'COMMA': 188,
            +    'SLASH': 191,
            +    'BACKSLASH': 220
            +};
            +
            +/**
            + * An object storing deprecated key aliases, which we still support but
            + * should be mapped to valid aliases and generate warnings.
            + *
            + * @private
            + * @property KEY_DEPRECATIONS
            + * @type {Object}
            + */
            +p5.prototype.KEY_DEPRECATIONS = {
            +  'MINUT': 'MINUS',
            +  'COMA': 'COMMA'
            +};
            +
            +/**
            + * Given a string key alias (as defined in the KEY property above), look up
            + * and return the numeric JavaScript key code for that key.  If a deprecated
            + * alias is passed (as defined in the KEY_DEPRECATIONS property) it will be
            + * mapped to a valid key code, but will also generate a warning about use
            + * of the deprecated alias.
            + *
            + * @private
            + * @method _keyCodeFromAlias
            + * @param {!string} alias - a case-insensitive key alias
            + * @return {number|undefined} a numeric JavaScript key code, or undefined
            + *          if no key code matching the given alias is found.
            + */
            +p5.prototype._keyCodeFromAlias = function(alias) {
            +  alias = alias.toUpperCase();
            +  if (this.KEY_DEPRECATIONS[alias]) {
            +    this._warn('Key literal "' + alias + '" is deprecated and may be removed ' +
            +      'in a future version of p5.play. ' +
            +      'Please use "' + this.KEY_DEPRECATIONS[alias] + '" instead.');
            +    alias = this.KEY_DEPRECATIONS[alias];
            +  }
            +  return this.KEY[alias];
            +};
            +
            +//pre draw: detect keyStates
            +p5.prototype.readPresses = function() {
            +  var keyStates = this._p5play.keyStates;
            +  var mouseStates = this._p5play.mouseStates;
            +
            +  for (var key in keyStates) {
            +    if(this.keyIsDown(key)) //if is down
            +    {
            +      if(keyStates[key] === KEY_IS_UP)//and was up
            +        keyStates[key] = KEY_WENT_DOWN;
            +      else
            +        keyStates[key] = KEY_IS_DOWN; //now is simply down
            +    }
            +    else //if it's up
            +    {
            +      if(keyStates[key] === KEY_IS_DOWN)//and was up
            +        keyStates[key] = KEY_WENT_UP;
            +      else
            +        keyStates[key] = KEY_IS_UP; //now is simply down
            +    }
            +  }
            +
            +  //mouse
            +  for (var btn in mouseStates) {
            +
            +    if(this.mouseIsPressed && this.mouseButton === btn) //if is down
            +    {
            +      if(mouseStates[btn] === KEY_IS_UP)//and was up
            +        mouseStates[btn] = KEY_WENT_DOWN;
            +      else
            +        mouseStates[btn] = KEY_IS_DOWN; //now is simply down
            +    }
            +    else //if it's up
            +    {
            +      if(mouseStates[btn] === KEY_IS_DOWN)//and was up
            +        mouseStates[btn] = KEY_WENT_UP;
            +      else
            +        mouseStates[btn] = KEY_IS_UP; //now is simply down
            +    }
            +  }
            +
            +};
            +
            +/**
            +* Turns the quadTree on or off.
            +* A quadtree is a data structure used to optimize collision detection.
            +* It can improve performance when there is a large number of Sprites to be
            +* checked continuously for overlapping.
            +*
            +* p5.play will create and update a quadtree automatically.
            +*
            +* @method useQuadTree
            +* @param {Boolean} use Pass true to enable, false to disable
            +*/
            +p5.prototype.useQuadTree = function(use) {
            +
            +  if(this.quadTree !== undefined)
            +  {
            +    if(use === undefined)
            +      return this.quadTree.active;
            +    else if(use)
            +      this.quadTree.active = true;
            +    else
            +      this.quadTree.active = false;
            +  }
            +  else
            +    return false;
            +};
            +
            +//the actual quadTree
            +defineLazyP5Property('quadTree', function() {
            +  return new Quadtree({
            +    x: 0,
            +    y: 0,
            +    width: 0,
            +    height: 0
            +  }, 4);
            +});
            +
            +/*
            +//framerate independent delta, doesn't really work
            +p5.prototype.deltaTime = 1;
            +
            +var now = Date.now();
            +var then = Date.now();
            +var INTERVAL_60 = 0.0166666; //60 fps
            +
            +function updateDelta() {
            +then = now;
            +now = Date.now();
            +deltaTime = ((now - then) / 1000)/INTERVAL_60; // seconds since last frame
            +}
            +*/
            +
            +/**
            +   * A Sprite is the main building block of p5.play:
            +   * an element able to store images or animations with a set of
            +   * properties such as position and visibility.
            +   * A Sprite can have a collider that defines the active area to detect
            +   * collisions or overlappings with other sprites and mouse interactions.
            +   *
            +   * To create a Sprite, use
            +   * {{#crossLink "p5.play/createSprite:method"}}{{/crossLink}}.
            +   *
            +   * @class Sprite
            +   */
            +
            +// For details on why these docs aren't in a YUIDoc comment block, see:
            +//
            +// https://github.com/molleindustria/p5.play/pull/67
            +//
            +// @param {Number} x Initial x coordinate
            +// @param {Number} y Initial y coordinate
            +// @param {Number} width Width of the placeholder rectangle and of the
            +//                       collider until an image or new collider are set
            +// @param {Number} height Height of the placeholder rectangle and of the
            +//                        collider until an image or new collider are set
            +function Sprite(pInst, _x, _y, _w, _h) {
            +  var pInstBind = createPInstBinder(pInst);
            +
            +  var createVector = pInstBind('createVector');
            +  var color = pInstBind('color');
            +  var random = pInstBind('random');
            +  var print = pInstBind('print');
            +  var push = pInstBind('push');
            +  var pop = pInstBind('pop');
            +  var colorMode = pInstBind('colorMode');
            +  var noStroke = pInstBind('noStroke');
            +  var rectMode = pInstBind('rectMode');
            +  var ellipseMode = pInstBind('ellipseMode');
            +  var imageMode = pInstBind('imageMode');
            +  var translate = pInstBind('translate');
            +  var scale = pInstBind('scale');
            +  var rotate = pInstBind('rotate');
            +  var stroke = pInstBind('stroke');
            +  var strokeWeight = pInstBind('strokeWeight');
            +  var line = pInstBind('line');
            +  var noFill = pInstBind('noFill');
            +  var fill = pInstBind('fill');
            +  var textAlign = pInstBind('textAlign');
            +  var textSize = pInstBind('textSize');
            +  var text = pInstBind('text');
            +  var rect = pInstBind('rect');
            +  var cos = pInstBind('cos');
            +  var sin = pInstBind('sin');
            +  var atan2 = pInstBind('atan2');
            +
            +  var quadTree = pInst.quadTree;
            +  var camera = pInst.camera;
            +
            +
            +  // These are p5 constants that we'd like easy access to.
            +  var RGB = p5.prototype.RGB;
            +  var CENTER = p5.prototype.CENTER;
            +  var LEFT = p5.prototype.LEFT;
            +  var BOTTOM = p5.prototype.BOTTOM;
            +
            +  /**
            +  * The sprite's position of the sprite as a vector (x,y).
            +  * @property position
            +  * @type {p5.Vector}
            +  */
            +  this.position = createVector(_x, _y);
            +
            +  /**
            +  * The sprite's position at the beginning of the last update as a vector (x,y).
            +  * @property previousPosition
            +  * @type {p5.Vector}
            +  */
            +  this.previousPosition = createVector(_x, _y);
            +
            +  /*
            +  The sprite's position at the end of the last update as a vector (x,y).
            +  Note: this will differ from position whenever the position is changed
            +  directly by assignment.
            +  */
            +  this.newPosition = createVector(_x, _y);
            +
            +  //Position displacement on the x coordinate since the last update
            +  this.deltaX = 0;
            +  this.deltaY = 0;
            +
            +  /**
            +  * The sprite's velocity as a vector (x,y)
            +  * Velocity is speed broken down to its vertical and horizontal components.
            +  *
            +  * @property velocity
            +  * @type {p5.Vector}
            +  */
            +  this.velocity = createVector(0, 0);
            +
            +  /**
            +  * Set a limit to the sprite's scalar speed regardless of the direction.
            +  * The value can only be positive. If set to -1, there's no limit.
            +  *
            +  * @property maxSpeed
            +  * @type {Number}
            +  * @default -1
            +  */
            +  this.maxSpeed = -1;
            +
            +  /**
            +  * Friction factor, reduces the sprite's velocity.
            +  * The friction should be close to 0 (eg. 0.01)
            +  * 0: no friction
            +  * 1: full friction
            +  *
            +  * @property friction
            +  * @type {Number}
            +  * @default 0
            +  */
            +  this.friction = 0;
            +
            +  /**
            +  * The sprite's current collider.
            +  * It can either be an Axis Aligned Bounding Box (a non-rotated rectangle)
            +  * or a circular collider.
            +  * If the sprite is checked for collision, bounce, overlapping or mouse events the
            +  * collider is automatically created from the width and height
            +  * of the sprite or from the image dimension in case of animate sprites
            +  *
            +  * You can set a custom collider with Sprite.setCollider
            +  *
            +  * @property collider
            +  * @type {Object}
            +  */
            +  this.collider = undefined;
            +
            +  //internal use
            +  //"default" - no image or custom collider is specified, use the shape width / height
            +  //"custom" - specified with setCollider
            +  //"image" - no collider is set with setCollider and an image is added
            +  this.colliderType = 'none';
            +
            +  /**
            +  * Object containing information about the most recent collision/overlapping
            +  * To be typically used in combination with Sprite.overlap or Sprite.collide
            +  * functions.
            +  * The properties are touching.left, touching.right, touching.top,
            +  * touching.bottom and are either true or false depending on the side of the
            +  * collider.
            +  *
            +  * @property touching
            +  * @type {Object}
            +  */
            +  this.touching = {};
            +  this.touching.left = false;
            +  this.touching.right = false;
            +  this.touching.top = false;
            +  this.touching.bottom = false;
            +
            +  /**
            +  * The mass determines the velocity transfer when sprites bounce
            +  * against each other. See Sprite.bounce
            +  * The higher the mass the least the sprite will be affected by collisions.
            +  *
            +  * @property mass
            +  * @type {Number}
            +  * @default 1
            +  */
            +  this.mass = 1;
            +
            +  /**
            +  * If set to true the sprite won't bounce or be displaced by collisions
            +  * Simulates an infinite mass or an anchored object.
            +  *
            +  * @property immovable
            +  * @type {Boolean}
            +  * @default false
            +  */
            +  this.immovable = false;
            +
            +  //Coefficient of restitution - velocity lost in the bouncing
            +  //0 perfectly inelastic , 1 elastic, > 1 hyper elastic
            +
            +  /**
            +  * Coefficient of restitution. The velocity lost after bouncing.
            +  * 1: perfectly elastic, no energy is lost
            +  * 0: perfectly inelastic, no bouncing
            +  * less than 1: inelastic, this is the most common in nature
            +  * greater than 1: hyper elastic, energy is increased like in a pinball bumper
            +  *
            +  * @property restitution
            +  * @type {Number}
            +  * @default 1
            +  */
            +  this.restitution = 1;
            +
            +  /**
            +  * Rotation in degrees of the visual element (image or animation)
            +  * Note: this is not the movement's direction, see getDirection.
            +  *
            +  * @property rotation
            +  * @type {Number}
            +  * @default 0
            +  */
            +  Object.defineProperty(this, 'rotation', {
            +    enumerable: true,
            +    get: function() {
            +      return this._rotation;
            +    },
            +    set: function(value) {
            +      this._rotation = value;
            +      if (this.rotateToDirection) {
            +        this.setSpeed(this.getSpeed(), value);
            +      }
            +    }
            +  });
            +
            +  /**
            +  * Internal rotation variable (expressed in degrees).
            +  * Note: external callers access this through the rotation property above.
            +  *
            +  * @private
            +  * @property _rotation
            +  * @type {Number}
            +  * @default 0
            +  */
            +  this._rotation = 0;
            +
            +  /**
            +  * Rotation change in degrees per frame of thevisual element (image or animation)
            +  * Note: this is not the movement's direction, see getDirection.
            +  *
            +  * @property rotationSpeed
            +  * @type {Number}
            +  * @default 0
            +  */
            +  this.rotationSpeed = 0;
            +
            +
            +  /**
            +  * Automatically lock the rotation property of the visual element
            +  * (image or animation) to the sprite's movement direction and vice versa.
            +  *
            +  * @property rotateToDirection
            +  * @type {Boolean}
            +  * @default false
            +  */
            +  this.rotateToDirection = false;
            +
            +
            +  /**
            +  * Determines the rendering order within a group: a sprite with
            +  * lower depth will appear below the ones with higher depth.
            +  *
            +  * Note: drawing a group before another with drawSprites will make
            +  * its members appear below the second one, like in normal p5 canvas
            +  * drawing.
            +  *
            +  * @property depth
            +  * @type {Number}
            +  * @default One more than the greatest existing sprite depth, when calling
            +  *          createSprite().  When calling new Sprite() directly, depth will
            +  *          initialize to 0 (not recommended).
            +  */
            +  this.depth = 0;
            +
            +  /**
            +  * Determines the sprite's scale.
            +  * Example: 2 will be twice the native size of the visuals,
            +  * 0.5 will be half. Scaling up may make images blurry.
            +  *
            +  * @property scale
            +  * @type {Number}
            +  * @default 1
            +  */
            +  this.scale = 1;
            +
            +  var dirX = 1;
            +  var dirY = 1;
            +
            +  /**
            +  * The sprite's visibility.
            +  *
            +  * @property visible
            +  * @type {Boolean}
            +  * @default true
            +  */
            +  this.visible = true;
            +
            +  /**
            +  * If set to true sprite will track its mouse state.
            +  * the properties mouseIsPressed and mouseIsOver will be updated.
            +  * Note: automatically set to true if the functions
            +  * onMouseReleased or onMousePressed are set.
            +  *
            +  * @property mouseActive
            +  * @type {Boolean}
            +  * @default false
            +  */
            +  this.mouseActive = false;
            +
            +  /**
            +  * True if mouse is on the sprite's collider.
            +  * Read only.
            +  *
            +  * @property mouseIsOver
            +  * @type {Boolean}
            +  */
            +  this.mouseIsOver = false;
            +
            +  /**
            +  * True if mouse is pressed on the sprite's collider.
            +  * Read only.
            +  *
            +  * @property mouseIsPressed
            +  * @type {Boolean}
            +  */
            +  this.mouseIsPressed = false;
            +
            +  /*
            +  * Width of the sprite's current image.
            +  * If no images or animations are set it's the width of the
            +  * placeholder rectangle.
            +  * Used internally to make calculations and draw the sprite.
            +  *
            +  * @private
            +  * @property _internalWidth
            +  * @type {Number}
            +  * @default 100
            +  */
            +  this._internalWidth = _w;
            +
            +  /*
            +  * Height of the sprite's current image.
            +  * If no images or animations are set it's the height of the
            +  * placeholder rectangle.
            +  * Used internally to make calculations and draw the sprite.
            +  *
            +  * @private
            +  * @property _internalHeight
            +  * @type {Number}
            +  * @default 100
            +  */
            +  this._internalHeight = _h;
            +
            +  /*
            +   * _internalWidth and _internalHeight are used for all p5.play
            +   * calculations, but width and height can be extended. For example,
            +   * you may want users to always get and set a scaled width:
            +      Object.defineProperty(this, 'width', {
            +        enumerable: true,
            +        configurable: true,
            +        get: function() {
            +          return this._internalWidth * this.scale;
            +        },
            +        set: function(value) {
            +          this._internalWidth = value / this.scale;
            +        }
            +      });
            +   */
            +
            +  /**
            +  * Width of the sprite's current image.
            +  * If no images or animations are set it's the width of the
            +  * placeholder rectangle.
            +  *
            +  * @property width
            +  * @type {Number}
            +  * @default 100
            +  */
            +  Object.defineProperty(this, 'width', {
            +    enumerable: true,
            +    configurable: true,
            +    get: function() {
            +      return this._internalWidth;
            +    },
            +    set: function(value) {
            +      this._internalWidth = value;
            +    }
            +  });
            +
            +  if(_w === undefined)
            +    this.width = 100;
            +  else
            +    this.width = _w;
            +
            +  /**
            +  * Height of the sprite's current image.
            +  * If no images or animations are set it's the height of the
            +  * placeholder rectangle.
            +  *
            +  * @property height
            +  * @type {Number}
            +  * @default 100
            +  */
            +  Object.defineProperty(this, 'height', {
            +    enumerable: true,
            +    configurable: true,
            +    get: function() {
            +      return this._internalHeight;
            +    },
            +    set: function(value) {
            +      this._internalHeight = value;
            +    }
            +  });
            +
            +  if(_h === undefined)
            +    this.height = 100;
            +  else
            +    this.height = _h;
            +
            +  /**
            +  * Unscaled width of the sprite
            +  * If no images or animations are set it's the width of the
            +  * placeholder rectangle.
            +  *
            +  * @property originalWidth
            +  * @type {Number}
            +  * @default 100
            +  */
            +  this.originalWidth = this._internalWidth;
            +
            +  /**
            +  * Unscaled height of the sprite
            +  * If no images or animations are set it's the height of the
            +  * placeholder rectangle.
            +  *
            +  * @property originalHeight
            +  * @type {Number}
            +  * @default 100
            +  */
            +  this.originalHeight = this._internalHeight;
            +
            +  /**
            +  * True if the sprite has been removed.
            +  *
            +  * @property removed
            +  * @type {Boolean}
            +  */
            +  this.removed = false;
            +
            +  /**
            +  * Cycles before self removal.
            +  * Set it to initiate a countdown, every draw cycle the property is
            +  * reduced by 1 unit. At 0 it will call a sprite.remove()
            +  * Disabled if set to -1.
            +  *
            +  * @property life
            +  * @type {Number}
            +  * @default -1
            +  */
            +  this.life = -1;
            +
            +  /**
            +  * If set to true, draws an outline of the collider, the depth, and center.
            +  *
            +  * @property debug
            +  * @type {Boolean}
            +  * @default false
            +  */
            +  this.debug = false;
            +
            +  /**
            +  * If no image or animations are set this is color of the
            +  * placeholder rectangle
            +  *
            +  * @property shapeColor
            +  * @type {color}
            +  */
            +  this.shapeColor = color(random(255), random(255), random(255));
            +
            +  /**
            +  * Groups the sprite belongs to, including allSprites
            +  *
            +  * @property groups
            +  * @type {Array}
            +  */
            +  this.groups = [];
            +
            +  var animations = {};
            +
            +  //The current animation's label.
            +  var currentAnimation = '';
            +
            +  /**
            +  * Reference to the current animation.
            +  *
            +  * @property animation
            +  * @type {Animation}
            +  */
            +  this.animation = undefined;
            +
            +  /*
            +   * @private
            +   * Keep animation properties in sync with how the animation changes.
            +   */
            +  this._syncAnimationSizes = function() {
            +    //has an animation but the collider is still default
            +    //the animation wasn't loaded. if the animation is not a 1x1 image
            +    //it means it just finished loading
            +    if(this.colliderType === 'default' &&
            +      animations[currentAnimation].getWidth() !== 1 && animations[currentAnimation].getHeight() !== 1)
            +    {
            +      this.collider = this.getBoundingBox();
            +      this.colliderType = 'image';
            +      this._internalWidth = animations[currentAnimation].getWidth()*abs(this._getScaleX());
            +      this._internalHeight = animations[currentAnimation].getHeight()*abs(this._getScaleY());
            +      //quadTree.insert(this);
            +    }
            +
            +    //update size and collider
            +    if(animations[currentAnimation].frameChanged || this.width === undefined || this.height === undefined)
            +    {
            +      //this.collider = this.getBoundingBox();
            +      this._internalWidth = animations[currentAnimation].getWidth()*abs(this._getScaleX());
            +      this._internalHeight = animations[currentAnimation].getHeight()*abs(this._getScaleY());
            +    }
            +  };
            +
            +  /**
            +  * Updates the sprite.
            +  * Called automatically at the beginning of the draw cycle.
            +  *
            +  * @method update
            +  */
            +  this.update = function() {
            +
            +    if(!this.removed)
            +    {
            +      //if there has been a change somewhere after the last update
            +      //the old position is the last position registered in the update
            +      if(this.newPosition !== this.position)
            +        this.previousPosition = createVector(this.newPosition.x, this.newPosition.y);
            +      else
            +        this.previousPosition = createVector(this.position.x, this.position.y);
            +
            +      this.velocity.x *= 1 - this.friction;
            +      this.velocity.y *= 1 - this.friction;
            +
            +      if(this.maxSpeed !== -1)
            +        this.limitSpeed(this.maxSpeed);
            +
            +      if(this.rotateToDirection && this.velocity.mag() > 0)
            +        this._rotation = this.getDirection();
            +
            +      this.rotation += this.rotationSpeed;
            +
            +      this.position.x += this.velocity.x;
            +      this.position.y += this.velocity.y;
            +
            +      this.newPosition = createVector(this.position.x, this.position.y);
            +
            +      this.deltaX = this.position.x - this.previousPosition.x;
            +      this.deltaY = this.position.y - this.previousPosition.y;
            +
            +      //if there is an animation
            +      if(animations[currentAnimation])
            +      {
            +        //update it
            +        animations[currentAnimation].update();
            +
            +        this._syncAnimationSizes();
            +      }
            +
            +      //a collider is created either manually with setCollider or
            +      //when I check this sprite for collisions or overlaps
            +      if(this.collider)
            +      {
            +        if(this.collider instanceof AABB)
            +        {
            +        //scale / rotate collider
            +        var t;
            +        if (pInst._angleMode === pInst.RADIANS) {
            +          t = radians(this.rotation);
            +        } else {
            +          t = this.rotation;
            +        }
            +
            +        if(this.colliderType === 'custom')
            +          {
            +          this.collider.extents.x = this.collider.originalExtents.x * abs(this._getScaleX()) * abs(cos(t)) +
            +          this.collider.originalExtents.y * abs(this._getScaleY()) * abs(sin(t));
            +
            +          this.collider.extents.y = this.collider.originalExtents.x * abs(this._getScaleX()) * abs(sin(t)) +
            +          this.collider.originalExtents.y * abs(this._getScaleY()) * abs(cos(t));
            +          }
            +        else if(this.colliderType === 'default')
            +          {
            +          this.collider.extents.x = this._internalWidth * abs(this._getScaleX()) * abs(cos(t)) +
            +          this._internalHeight * abs(this._getScaleY()) * abs(sin(t));
            +          this.collider.extents.y = this._internalWidth * abs(this._getScaleX()) * abs(sin(t)) +
            +          this._internalHeight * abs(this._getScaleY()) * abs(cos(t));
            +          }
            +        else if(this.colliderType === 'image')
            +          {
            +          this.collider.extents.x = this._internalWidth * abs(cos(t)) +
            +          this._internalHeight * abs(sin(t));
            +
            +          this.collider.extents.y = this._internalWidth * abs(sin(t)) +
            +          this._internalHeight * abs(cos(t));
            +          }
            +        }
            +
            +        if(this.collider instanceof CircleCollider)
            +        {
            +        //print(this.scale);
            +        this.collider.radius = this.collider.originalRadius * abs(this.scale);
            +        }
            +
            +      }//end collider != null
            +
            +      //mouse actions
            +      if (this.mouseActive)
            +      {
            +        //if no collider set it
            +          if(!this.collider)
            +            this.setDefaultCollider();
            +
            +        this.mouseUpdate();
            +      }
            +      else
            +      {
            +        if (typeof(this.onMouseOver) === 'function' ||
            +            typeof(this.onMouseOut) === 'function' ||
            +            typeof(this.onMousePressed) === 'function' ||
            +            typeof(this.onMouseReleased) === 'function')
            +        {
            +          //if a mouse function is set
            +          //it's implied we want to have it mouse active so
            +          //we do this automatically
            +          this.mouseActive = true;
            +
            +          //if no collider set it
            +          if(!this.collider)
            +            this.setDefaultCollider();
            +
            +          this.mouseUpdate();
            +        }
            +      }
            +
            +      //self destruction countdown
            +      if (this.life>0)
            +        this.life--;
            +      if (this.life === 0)
            +        this.remove();
            +    }
            +  };//end update
            +
            +  /**
            +   * Creates a default collider matching the size of the
            +   * placeholder rectangle or the bounding box of the image.
            +   *
            +   * @method setDefaultCollider
            +   */
            +  this.setDefaultCollider = function() {
            +
            +    //if has animation get the animation bounding box
            +    //working only for preloaded images
            +    if(animations[currentAnimation] && (animations[currentAnimation].getWidth() !== 1 && animations[currentAnimation].getHeight() !== 1))
            +    {
            +      this.collider = this.getBoundingBox();
            +      this._internalWidth = animations[currentAnimation].getWidth()*abs(this._getScaleX());
            +      this._internalHeight = animations[currentAnimation].getHeight()*abs(this._getScaleY());
            +      //quadTree.insert(this);
            +      this.colliderType = 'image';
            +      //print("IMAGE COLLIDER ADDED");
            +    }
            +    else if(animations[currentAnimation] && animations[currentAnimation].getWidth() === 1 && animations[currentAnimation].getHeight() === 1)
            +    {
            +    //animation is still loading
            +    //print("wait");
            +    }
            +    else //get the with and height defined at the creation
            +    {
            +      this.collider = new AABB(pInst, this.position, createVector(this._internalWidth, this._internalHeight));
            +      //quadTree.insert(this);
            +      this.colliderType = 'default';
            +    }
            +
            +    pInst.quadTree.insert(this);
            +  };
            +
            +  /**
            +   * Updates the sprite mouse states and triggers the mouse events:
            +   * onMouseOver, onMouseOut, onMousePressed, onMouseReleased
            +   *
            +   * @method mouseUpdate
            +   */
            +  this.mouseUpdate = function() {
            +
            +    var mouseWasOver = this.mouseIsOver;
            +    var mouseWasPressed = this.mouseIsPressed;
            +
            +    this.mouseIsOver = false;
            +    this.mouseIsPressed = false;
            +
            +    var mousePosition;
            +
            +    if(camera.active)
            +      mousePosition = createVector(camera.mouseX, camera.mouseY);
            +    else
            +      mousePosition = createVector(pInst.mouseX, pInst.mouseY);
            +
            +      //rollover
            +      if(this.collider)
            +      {
            +
            +        if (this.collider instanceof CircleCollider)
            +        {
            +          if (dist(mousePosition.x, mousePosition.y, this.collider.center.x, this.collider.center.y) < this.collider.radius)
            +            this.mouseIsOver = true;
            +        } else if (this.collider instanceof AABB)
            +        {
            +          if (mousePosition.x > this.collider.left() &&
            +              mousePosition.y > this.collider.top() &&
            +              mousePosition.x < this.collider.right() &&
            +              mousePosition.y < this.collider.bottom())
            +          {
            +            this.mouseIsOver = true;
            +          }
            +        }
            +
            +        //global p5 var
            +        if(this.mouseIsOver && pInst.mouseIsPressed)
            +          this.mouseIsPressed = true;
            +
            +        //event change - call functions
            +        if(!mouseWasOver && this.mouseIsOver && this.onMouseOver !== undefined)
            +          if(typeof(this.onMouseOver) === 'function')
            +            this.onMouseOver.call(this, this);
            +          else
            +            print('Warning: onMouseOver should be a function');
            +
            +        if(mouseWasOver && !this.mouseIsOver && this.onMouseOut !== undefined)
            +          if(typeof(this.onMouseOut) === 'function')
            +            this.onMouseOut.call(this, this);
            +          else
            +            print('Warning: onMouseOut should be a function');
            +
            +        if(!mouseWasPressed && this.mouseIsPressed && this.onMousePressed !== undefined)
            +          if(typeof(this.onMousePressed) === 'function')
            +            this.onMousePressed.call(this, this);
            +          else
            +            print('Warning: onMousePressed should be a function');
            +
            +        if(mouseWasPressed && !pInst.mouseIsPressed && !this.mouseIsPressed && this.onMouseReleased !== undefined)
            +          if(typeof(this.onMouseReleased) === 'function')
            +            this.onMouseReleased.call(this, this);
            +          else
            +            print('Warning: onMouseReleased should be a function');
            +
            +      }
            +
            +  };
            +
            +  /**
            +  * Sets a collider for the sprite.
            +  *
            +  * In p5.play a Collider is an invisible circle or rectangle
            +  * that can have any size or position relative to the sprite and which
            +  * will be used to detect collisions and overlapping with other sprites,
            +  * or the mouse cursor.
            +  *
            +  * If the sprite is checked for collision, bounce, overlapping or mouse events
            +  * a collider is automatically created from the width and height parameter
            +  * passed at the creation of the sprite or the from the image dimension in case
            +  * of animated sprites.
            +  *
            +  * Often the image bounding box is not appropriate as the active area for
            +  * collision detection so you can set a circular or rectangular sprite with
            +  * different dimensions and offset from the sprite's center.
            +  *
            +  * There are four ways to call this method:
            +  *
            +  * 1. setCollider("rectangle")
            +  * 2. setCollider("rectangle", offsetX, offsetY, width, height)
            +  * 3. setCollider("circle")
            +  * 4. setCollider("circle", offsetX, offsetY, radius)
            +  *
            +  * @method setCollider
            +  * @param {String} type Either "rectangle" or "circle"
            +  * @param {Number} offsetX Collider x position from the center of the sprite
            +  * @param {Number} offsetY Collider y position from the center of the sprite
            +  * @param {Number} width Collider width or radius
            +  * @param {Number} height Collider height
            +  * @throws {TypeError} if given invalid parameters.
            +  */
            +  this.setCollider = function(type, offsetX, offsetY, width, height) {
            +    if (!(type === 'rectangle' || type === 'circle')) {
            +      throw new TypeError('setCollider expects the first argument to be either "circle" or "rectangle"');
            +    } else if (type === 'circle' && arguments.length > 1 && arguments.length < 4) {
            +      throw new TypeError('Usage: setCollider("circle") or setCollider("circle", offsetX, offsetY, radius)');
            +    } else if (type === 'circle' && arguments.length > 4) {
            +      pInst._warn('Extra parameters to setCollider were ignored. Usage: setCollider("circle") or setCollider("circle", offsetX, offsetY, radius)');
            +    } else if (type === 'rectangle' && arguments.length > 1 && arguments.length < 5) {
            +      throw new TypeError('Usage: setCollider("rectangle") or setCollider("rectangle", offsetX, offsetY, width, height)');
            +    } else if (type === 'rectangle' && arguments.length > 5) {
            +      pInst._warn('Extra parameters to setCollider were ignored. Usage: setCollider("rectangle") or setCollider("rectangle", offsetX, offsetY, width, height)');
            +    }
            +
            +    this.colliderType = 'custom';
            +
            +    var v = createVector(offsetX, offsetY);
            +    if (type === 'rectangle' && arguments.length === 1) {
            +      this.collider = new AABB(pInst, this.position, createVector(this.width, this.height));
            +    } else if (type === 'rectangle' && arguments.length >= 5) {
            +      this.collider = new AABB(pInst, this.position, createVector(width, height), v);
            +    } else if (type === 'circle' && arguments.length === 1) {
            +      this.collider = new CircleCollider(pInst, this.position, Math.floor(Math.max(this.width, this.height) / 2));
            +    } else if (type === 'circle' && arguments.length >= 4) {
            +      this.collider = new CircleCollider(pInst, this.position, width, v);
            +    }
            +
            +    quadTree.insert(this);
            +  };
            +
            +  /**
            +   * Returns a the bounding box of the current image
            +   * @method getBoundingBox
            +   */
            +  this.getBoundingBox = function() {
            +
            +    var w = animations[currentAnimation].getWidth()*abs(this._getScaleX());
            +    var h = animations[currentAnimation].getHeight()*abs(this._getScaleY());
            +
            +    //if the bounding box is 1x1 the image is not loaded
            +    //potential issue with actual 1x1 images
            +    if(w === 1 && h === 1) {
            +      //not loaded yet
            +      return new AABB(pInst, this.position, createVector(w, h));
            +    }
            +    else {
            +      return new AABB(pInst, this.position, createVector(w, h));
            +    }
            +  };
            +
            +  /**
            +  * Sets the sprite's horizontal mirroring.
            +  * If 1 the images displayed normally
            +  * If -1 the images are flipped horizontally
            +  * If no argument returns the current x mirroring
            +  *
            +  * @method mirrorX
            +  * @param {Number} dir Either 1 or -1
            +  * @return {Number} Current mirroring if no parameter is specified
            +  */
            +  this.mirrorX = function(dir) {
            +    if(dir === 1 || dir === -1)
            +      dirX = dir;
            +    else
            +      return dirX;
            +  };
            +
            +  /**
            +  * Sets the sprite's vertical mirroring.
            +  * If 1 the images displayed normally
            +  * If -1 the images are flipped vertically
            +  * If no argument returns the current y mirroring
            +  *
            +  * @method mirrorY
            +  * @param {Number} dir Either 1 or -1
            +  * @return {Number} Current mirroring if no parameter is specified
            +  */
            +  this.mirrorY = function(dir) {
            +    if(dir === 1 || dir === -1)
            +      dirY = dir;
            +    else
            +      return dirY;
            +  };
            +
            +  /*
            +   * Returns the value the sprite should be scaled in the X direction.
            +   * Used to calculate rendering and collisions.
            +   * @private
            +   */
            +  this._getScaleX = function()
            +  {
            +    return this.scale;
            +  };
            +
            +  /*
            +   * Returns the value the sprite should be scaled in the Y direction.
            +   * Used to calculate rendering and collisions.
            +   * @private
            +   */
            +  this._getScaleY = function()
            +  {
            +    return this.scale;
            +  };
            +
            +  /**
            +   * Manages the positioning, scale and rotation of the sprite
            +   * Called automatically, it should not be overridden
            +   * @private
            +   * @final
            +   * @method display
            +   */
            +  this.display = function()
            +  {
            +    if (this.visible && !this.removed)
            +    {
            +      push();
            +      colorMode(RGB);
            +
            +      noStroke();
            +      rectMode(CENTER);
            +      ellipseMode(CENTER);
            +      imageMode(CENTER);
            +
            +      translate(this.position.x, this.position.y);
            +      scale(this._getScaleX()*dirX, this._getScaleY()*dirY);
            +      if (pInst._angleMode === pInst.RADIANS) {
            +        rotate(radians(this.rotation));
            +      } else {
            +        rotate(this.rotation);
            +      }
            +      this.draw();
            +      //draw debug info
            +      pop();
            +
            +
            +      if(this.debug)
            +      {
            +        push();
            +        //draw the anchor point
            +        stroke(0, 255, 0);
            +        strokeWeight(1);
            +        line(this.position.x-10, this.position.y, this.position.x+10, this.position.y);
            +        line(this.position.x, this.position.y-10, this.position.x, this.position.y+10);
            +        noFill();
            +
            +        //depth number
            +        noStroke();
            +        fill(0, 255, 0);
            +        textAlign(LEFT, BOTTOM);
            +        textSize(16);
            +        text(this.depth+'', this.position.x+4, this.position.y-2);
            +
            +        noFill();
            +        stroke(0, 255, 0);
            +
            +        //bounding box
            +        if(this.collider !== undefined)
            +        {
            +          this.collider.draw();
            +        }
            +        pop();
            +      }
            +
            +    }
            +  };
            +
            +
            +  /**
            +  * Manages the visuals of the sprite.
            +  * It can be overridden with a custom drawing function.
            +  * The 0,0 point will be the center of the sprite.
            +  * Example:
            +  * sprite.draw = function() { ellipse(0,0,10,10) }
            +  * Will display the sprite as circle.
            +  *
            +  * @method draw
            +  */
            +  this.draw = function()
            +  {
            +    if(currentAnimation !== '' && animations)
            +    {
            +      if(animations[currentAnimation])
            +        animations[currentAnimation].draw(0, 0, 0);
            +    }
            +    else
            +    {
            +      noStroke();
            +      fill(this.shapeColor);
            +      rect(0, 0, this._internalWidth, this._internalHeight);
            +    }
            +  };
            +
            +  /**
            +   * Removes the Sprite from the sketch.
            +   * The removed Sprite won't be drawn or updated anymore.
            +   *
            +   * @method remove
            +   */
            +  this.remove = function() {
            +    this.removed = true;
            +
            +    quadTree.removeObject(this);
            +
            +    //when removed from the "scene" also remove all the references in all the groups
            +    while (this.groups.length > 0) {
            +      this.groups[0].remove(this);
            +    }
            +  };
            +
            +  /**
            +  * Sets the velocity vector.
            +  *
            +  * @method setVelocity
            +  * @param {Number} x X component
            +  * @param {Number} y Y component
            +  */
            +  this.setVelocity = function(x, y) {
            +    this.velocity.x = x;
            +    this.velocity.y = y;
            +  };
            +
            +  /**
            +  * Calculates the scalar speed.
            +  *
            +  * @method getSpeed
            +  * @return {Number} Scalar speed
            +  */
            +  this.getSpeed = function() {
            +    return this.velocity.mag();
            +  };
            +
            +  /**
            +  * Calculates the movement's direction in degrees.
            +  *
            +  * @method getDirection
            +  * @return {Number} Angle in degrees
            +  */
            +  this.getDirection = function() {
            +
            +    var direction = atan2(this.velocity.y, this.velocity.x);
            +
            +    if(isNaN(direction))
            +      direction = 0;
            +
            +    // Unlike Math.atan2, the atan2 method above will return degrees if
            +    // the current p5 angleMode is DEGREES, and radians if the p5 angleMode is
            +    // RADIANS.  This method should always return degrees (for now).
            +    // See https://github.com/molleindustria/p5.play/issues/94
            +    if (pInst._angleMode === pInst.RADIANS) {
            +      direction = degrees(direction);
            +    }
            +
            +    return direction;
            +  };
            +
            +  /**
            +  * Adds the sprite to an existing group
            +  *
            +  * @method addToGroup
            +  * @param {Object} group
            +  */
            +  this.addToGroup = function(group) {
            +    if(group instanceof Array)
            +      group.add(this);
            +    else
            +      print('addToGroup error: '+group+' is not a group');
            +  };
            +
            +  /**
            +  * Limits the scalar speed.
            +  *
            +  * @method limitSpeed
            +  * @param {Number} max Max speed: positive number
            +  */
            +  this.limitSpeed = function(max) {
            +
            +    //update linear speed
            +    var speed = this.getSpeed();
            +
            +    if(abs(speed)>max)
            +    {
            +      //find reduction factor
            +      var k = max/abs(speed);
            +      this.velocity.x *= k;
            +      this.velocity.y *= k;
            +    }
            +  };
            +
            +  /**
            +  * Set the speed and direction of the sprite.
            +  * The action overwrites the current velocity.
            +  * If direction is not supplied, the current direction is maintained.
            +  * If direction is not supplied and there is no current velocity, the current
            +  * rotation angle used for the direction.
            +  *
            +  * @method setSpeed
            +  * @param {Number}  speed Scalar speed
            +  * @param {Number}  [angle] Direction in degrees
            +  */
            +  this.setSpeed = function(speed, angle) {
            +    var a;
            +    if (typeof angle === 'undefined') {
            +      if (this.velocity.x !== 0 || this.velocity.y !== 0) {
            +        a = pInst.atan2(this.velocity.y, this.velocity.x);
            +      } else {
            +        if (pInst._angleMode === pInst.RADIANS) {
            +          a = radians(this._rotation);
            +        } else {
            +          a = this._rotation;
            +        }
            +      }
            +    } else {
            +      if (pInst._angleMode === pInst.RADIANS) {
            +        a = radians(angle);
            +      } else {
            +        a = angle;
            +      }
            +    }
            +    this.velocity.x = cos(a)*speed;
            +    this.velocity.y = sin(a)*speed;
            +  };
            +
            +  /**
            +  * Pushes the sprite in a direction defined by an angle.
            +  * The force is added to the current velocity.
            +  *
            +  * @method addSpeed
            +  * @param {Number}  speed Scalar speed to add
            +  * @param {Number}  angle Direction in degrees
            +  */
            +  this.addSpeed = function(speed, angle) {
            +    var a;
            +    if (pInst._angleMode === pInst.RADIANS) {
            +      a = radians(angle);
            +    } else {
            +      a = angle;
            +    }
            +    this.velocity.x += cos(a) * speed;
            +    this.velocity.y += sin(a) * speed;
            +  };
            +
            +  /**
            +  * Pushes the sprite toward a point.
            +  * The force is added to the current velocity.
            +  *
            +  * @method attractionPoint
            +  * @param {Number}  magnitude Scalar speed to add
            +  * @param {Number}  pointX Direction x coordinate
            +  * @param {Number}  pointY Direction y coordinate
            +  */
            +  this.attractionPoint = function(magnitude, pointX, pointY) {
            +    var angle = atan2(pointY-this.position.y, pointX-this.position.x);
            +    this.velocity.x += cos(angle) * magnitude;
            +    this.velocity.y += sin(angle) * magnitude;
            +  };
            +
            +
            +  /**
            +  * Adds an image to the sprite.
            +  * An image will be considered a one-frame animation.
            +  * The image should be preloaded in the preload() function using p5 loadImage.
            +  * Animations require a identifying label (string) to change them.
            +  * The image is stored in the sprite but not necessarily displayed
            +  * until Sprite.changeAnimation(label) is called
            +  *
            +  * Usages:
            +  * - sprite.addImage(label, image);
            +  * - sprite.addImage(image);
            +  *
            +  * If only an image is passed no label is specified
            +  *
            +  * @method addImage
            +  * @param {String|p5.Image} label Label or image
            +  * @param {p5.Image} [img] Image
            +  */
            +  this.addImage = function()
            +  {
            +    if(typeof arguments[0] === 'string' && arguments[1] instanceof p5.Image)
            +      this.addAnimation(arguments[0], arguments[1]);
            +    else if(arguments[0] instanceof p5.Image)
            +      this.addAnimation('normal', arguments[0]);
            +    else
            +      throw('addImage error: allowed usages are <image> or <label>, <image>');
            +  };
            +
            +  /**
            +  * Adds an animation to the sprite.
            +  * The animation should be preloaded in the preload() function
            +  * using loadAnimation.
            +  * Animations require a identifying label (string) to change them.
            +  * Animations are stored in the sprite but not necessarily displayed
            +  * until Sprite.changeAnimation(label) is called.
            +  *
            +  * Usage:
            +  * - sprite.addAnimation(label, animation);
            +  *
            +  * Alternative usages. See Animation for more information on file sequences:
            +  * - sprite.addAnimation(label, firstFrame, lastFrame);
            +  * - sprite.addAnimation(label, frame1, frame2, frame3...);
            +  *
            +  * @method addAnimation
            +  * @param {String} label Animation identifier
            +  * @param {Animation} animation The preloaded animation
            +  */
            +  this.addAnimation = function(label)
            +  {
            +    var anim;
            +
            +    if(typeof label !== 'string')
            +    {
            +      print('Sprite.addAnimation error: the first argument must be a label (String)');
            +      return -1;
            +    }
            +    else if(arguments.length < 2)
            +    {
            +      print('addAnimation error: you must specify a label and n frame images');
            +      return -1;
            +    }
            +    else if(arguments[1] instanceof Animation)
            +    {
            +
            +      var sourceAnimation = arguments[1];
            +
            +      var newAnimation = sourceAnimation.clone();
            +
            +      animations[label] = newAnimation;
            +
            +      if(currentAnimation === '')
            +      {
            +        currentAnimation = label;
            +        this.animation = newAnimation;
            +      }
            +
            +      newAnimation.isSpriteAnimation = true;
            +
            +      this._internalWidth = newAnimation.getWidth()*abs(this._getScaleX());
            +      this._internalHeight = newAnimation.getHeight()*abs(this._getScaleY());
            +
            +      return newAnimation;
            +    }
            +    else
            +    {
            +      var animFrames = [];
            +      for(var i=1; i<arguments.length; i++)
            +        animFrames.push(arguments[i]);
            +
            +      anim = construct(pInst.Animation, animFrames);
            +      animations[label] = anim;
            +
            +      if(currentAnimation === '')
            +      {
            +        currentAnimation = label;
            +        this.animation = anim;
            +      }
            +      anim.isSpriteAnimation = true;
            +
            +      this._internalWidth = anim.getWidth()*abs(this._getScaleX());
            +      this._internalHeight = anim.getHeight()*abs(this._getScaleY());
            +
            +      return anim;
            +    }
            +
            +  };
            +
            +  /**
            +  * Changes the displayed image/animation.
            +  * Equivalent to changeAnimation
            +  *
            +  * @method changeImage
            +  * @param {String} label Image/Animation identifier
            +  */
            +  this.changeImage = function(label) {
            +    this.changeAnimation(label);
            +  };
            +
            +   /**
            +  * Returns the label of the current animation
            +  *
            +  * @method getAnimationLabel
            +  * @return {String} label Image/Animation identifier
            +  */
            +  this.getAnimationLabel = function() {
            +    return currentAnimation;
            +  };
            +
            +  /**
            +  * Changes the displayed animation.
            +  * See Animation for more control over the sequence.
            +  *
            +  * @method changeAnimation
            +  * @param {String} label Animation identifier
            +  */
            +  this.changeAnimation = function(label) {
            +    if(!animations[label])
            +      print('changeAnimation error: no animation labeled '+label);
            +    else
            +    {
            +      currentAnimation = label;
            +      this.animation = animations[label];
            +    }
            +  };
            +
            +  /**
            +  * Checks if the given point corresponds to a transparent pixel
            +  * in the sprite's current image. It can be used to check a point collision
            +  * against only the visible part of the sprite.
            +  *
            +  * @method overlapPixel
            +  * @param {Number} pointX x coordinate of the point to check
            +  * @param {Number} pointY y coordinate of the point to check
            +  * @return {Boolean} result True if non-transparent
            +  */
            +  this.overlapPixel = function(pointX, pointY) {
            +    var point = createVector(pointX, pointY);
            +
            +    var img = this.animation.getFrameImage();
            +
            +    //convert point to img relative position
            +    point.x -= this.position.x-img.width/2;
            +    point.y -= this.position.y-img.height/2;
            +
            +    //out of the image entirely
            +    if(point.x<0 || point.x>img.width || point.y<0 || point.y>img.height)
            +      return false;
            +    else if(this.rotation === 0 && this.scale === 1)
            +    {
            +      //true if full opacity
            +      var values = img.get(point.x, point.y);
            +      return values[3] === 255;
            +    }
            +    else
            +    {
            +      print('Error: overlapPixel doesn\'t work with scaled or rotated sprites yet');
            +      //offscreen printing to be implemented bleurch
            +      return false;
            +    }
            +  };
            +
            +  /**
            +  * Checks if the given point is inside the sprite's collider.
            +  *
            +  * @method overlapPoint
            +  * @param {Number} pointX x coordinate of the point to check
            +  * @param {Number} pointY y coordinate of the point to check
            +  * @return {Boolean} result True if inside
            +  */
            +  this.overlapPoint = function(pointX, pointY) {
            +    var point = createVector(pointX, pointY);
            +
            +    if(!this.collider)
            +      this.setDefaultCollider();
            +
            +    if(this.collider !== undefined)
            +    {
            +      if(this.collider instanceof AABB)
            +        return (point.x > this.collider.left() && point.x < this.collider.right() && point.y > this.collider.top() && point.y < this.collider.bottom());
            +      if(this.collider instanceof CircleCollider)
            +      {
            +        var sqRadius = this.collider.radius * this.collider.radius;
            +        var sqDist = pow(this.collider.center.x - point.x, 2) + pow(this.collider.center.y - point.y, 2);
            +        return sqDist<sqRadius;
            +      }
            +      else
            +        return false;
            +    }
            +    else
            +      return false;
            +
            +  };
            +
            +
            +  /**
            +  * Checks if the the sprite is overlapping another sprite or a group.
            +  * The check is performed using the colliders. If colliders are not set
            +  * they will be created automatically from the image/animation bounding box.
            +  *
            +  * A callback function can be specified to perform additional operations
            +  * when the overlap occours.
            +  * If the target is a group the function will be called for each single
            +  * sprite overlapping. The parameter of the function are respectively the
            +  * current sprite and the colliding sprite.
            +  *
            +  * @example
            +  *     sprite.overlap(otherSprite, explosion);
            +  *
            +  *     function explosion(spriteA, spriteB) {
            +  *       spriteA.remove();
            +  *       spriteB.score++;
            +  *     }
            +  *
            +  * @method overlap
            +  * @param {Object} target Sprite or group to check against the current one
            +  * @param {Function} [callback] The function to be called if overlap is positive
            +  * @return {Boolean} True if overlapping
            +  */
            +  this.overlap = function(target, callback) {
            +    //if(this.collider instanceof AABB && target.collider instanceof AABB)
            +    return this.AABBops('overlap', target, callback);
            +  };
            +
            +  /**
            +  * Checks if the the sprite is overlapping another sprite or a group.
            +  * If the overlap is positive the current sprite will be displace by
            +  * the colliding one in the closest non-overlapping position.
            +  *
            +  * The check is performed using the colliders. If colliders are not set
            +  * they will be created automatically from the image/animation bounding box.
            +  *
            +  * A callback function can be specified to perform additional operations
            +  * when the collision occours.
            +  * If the target is a group the function will be called for each single
            +  * sprite colliding. The parameter of the function are respectively the
            +  * current sprite and the colliding sprite.
            +  *
            +  * @example
            +  *     sprite.collide(otherSprite, explosion);
            +  *
            +  *     function explosion(spriteA, spriteB) {
            +  *       spriteA.remove();
            +  *       spriteB.score++;
            +  *     }
            +  *
            +  * @method collide
            +  * @param {Object} target Sprite or group to check against the current one
            +  * @param {Function} [callback] The function to be called if overlap is positive
            +  * @return {Boolean} True if overlapping
            +  */
            +  this.collide = function(target, callback) {
            +    //if(this.collider instanceof AABB && target.collider instanceof AABB)
            +    return this.AABBops('collide', target, callback);
            +  };
            +
            +  /**
            +  * Checks if the the sprite is overlapping another sprite or a group.
            +  * If the overlap is positive the current sprite will displace
            +  * the colliding one to the closest non-overlapping position.
            +  *
            +  * The check is performed using the colliders. If colliders are not set
            +  * they will be created automatically from the image/animation bounding box.
            +  *
            +  * A callback function can be specified to perform additional operations
            +  * when the collision occours.
            +  * If the target is a group the function will be called for each single
            +  * sprite colliding. The parameter of the function are respectively the
            +  * current sprite and the colliding sprite.
            +  *
            +  * @example
            +  *     sprite.displace(otherSprite, explosion);
            +  *
            +  *     function explosion(spriteA, spriteB) {
            +  *       spriteA.remove();
            +  *       spriteB.score++;
            +  *     }
            +  *
            +  * @method displace
            +  * @param {Object} target Sprite or group to check against the current one
            +  * @param {Function} [callback] The function to be called if overlap is positive
            +  * @return {Boolean} True if overlapping
            +  */
            +  this.displace = function(target, callback) {
            +    return this.AABBops('displace', target, callback);
            +  };
            +
            +  /**
            +  * Checks if the the sprite is overlapping another sprite or a group.
            +  * If the overlap is positive the sprites will bounce affecting each
            +  * other's trajectories depending on their .velocity, .mass and .restitution
            +  *
            +  * The check is performed using the colliders. If colliders are not set
            +  * they will be created automatically from the image/animation bounding box.
            +  *
            +  * A callback function can be specified to perform additional operations
            +  * when the collision occours.
            +  * If the target is a group the function will be called for each single
            +  * sprite colliding. The parameter of the function are respectively the
            +  * current sprite and the colliding sprite.
            +  *
            +  * @example
            +  *     sprite.bounce(otherSprite, explosion);
            +  *
            +  *     function explosion(spriteA, spriteB) {
            +  *       spriteA.remove();
            +  *       spriteB.score++;
            +  *     }
            +  *
            +  * @method bounce
            +  * @param {Object} target Sprite or group to check against the current one
            +  * @param {Function} [callback] The function to be called if overlap is positive
            +  * @return {Boolean} True if overlapping
            +  */
            +  this.bounce = function(target, callback) {
            +    return this.AABBops('bounce', target, callback);
            +  };
            +
            +  // Internal collision detection function. Do not use directly.
            +  this.AABBops = function(type, target, callback) {
            +
            +    this.touching.left = false;
            +    this.touching.right = false;
            +    this.touching.top = false;
            +    this.touching.bottom = false;
            +
            +    var result = false;
            +
            +    //if single sprite turn into array anyway
            +    var others = [];
            +
            +    if(target instanceof Sprite)
            +      others.push(target);
            +    else if(target instanceof Array)
            +    {
            +      if(quadTree !== undefined && quadTree.active)
            +        others = quadTree.retrieveFromGroup( this, target);
            +
            +      if(others.length === 0)
            +        others = target;
            +
            +    }
            +    else
            +      throw('Error: overlap can only be checked between sprites or groups');
            +
            +    for(var i=0; i<others.length; i++)
            +      if(this !== others[i] && !this.removed) //you can check collisions within the same group but not on itself
            +      {
            +        var displacement;
            +        var other = others[i];
            +
            +        if(this.collider === undefined)
            +          this.setDefaultCollider();
            +
            +        if(other.collider === undefined)
            +          other.setDefaultCollider();
            +
            +        /*
            +        if(this.colliderType=="default" && animations[currentAnimation]!=null)
            +        {
            +          print("busted");
            +          return false;
            +        }*/
            +        if(this.collider !== undefined && other.collider !== undefined)
            +        {
            +        if(type === 'overlap') {
            +            var over;
            +
            +            //if the other is a circle I calculate the displacement from here
            +            if(this.collider instanceof CircleCollider)
            +                over = other.collider.overlap(this.collider);
            +            else
            +                over = this.collider.overlap(other.collider);
            +
            +            if(over)
            +            {
            +
            +              result = true;
            +
            +              if(callback !== undefined && typeof callback === 'function')
            +                callback.call(this, this, other);
            +            }
            +          }
            +        else if(type === 'collide' || type === 'displace' || type === 'bounce')
            +          {
            +            displacement = createVector(0, 0);
            +
            +            //if the sum of the speed is more than the collider i may
            +            //have a tunnelling problem
            +            var tunnelX = abs(this.velocity.x-other.velocity.x) >= other.collider.extents.x/2 && round(this.deltaX - this.velocity.x) === 0;
            +
            +            var tunnelY = abs(this.velocity.y-other.velocity.y) >= other.collider.size().y/2 && round(this.deltaY - this.velocity.y) === 0;
            +
            +
            +            if(tunnelX || tunnelY)
            +            {
            +              //instead of using the colliders I use the bounding box
            +              //around the previous position and current position
            +              //this is regardless of the collider type
            +
            +              //the center is the average of the coll centers
            +              var c = createVector(
            +                (this.position.x+this.previousPosition.x)/2,
            +                (this.position.y+this.previousPosition.y)/2);
            +
            +              //the extents are the distance between the coll centers
            +              //plus the extents of both
            +              var e = createVector(
            +                abs(this.position.x -this.previousPosition.x) + this.collider.extents.x,
            +                abs(this.position.y -this.previousPosition.y) + this.collider.extents.y);
            +
            +              var bbox = new AABB(pInst, c, e, this.collider.offset);
            +
            +              //bbox.draw();
            +
            +              if(bbox.overlap(other.collider))
            +              {
            +                if(tunnelX) {
            +
            +                  //entering from the right
            +                  if(this.velocity.x < 0)
            +                    displacement.x = other.collider.right() - this.collider.left() + 1;
            +                  else if(this.velocity.x > 0 )
            +                    displacement.x = other.collider.left() - this.collider.right() -1;
            +                  }
            +
            +                if(tunnelY) {
            +                  //from top
            +                  if(this.velocity.y > 0)
            +                    displacement.y = other.collider.top() - this.collider.bottom() - 1;
            +                  else if(this.velocity.y < 0 )
            +                    displacement.y = other.collider.bottom() - this.collider.top() + 1;
            +
            +                  }
            +
            +              }//end overlap
            +
            +            }
            +            else //non tunnel overlap
            +            {
            +
            +              //if the other is a circle I calculate the displacement from here
            +              //and reverse it
            +              if(this.collider instanceof CircleCollider)
            +                {
            +                displacement = other.collider.collide(this.collider).mult(-1);
            +                }
            +              else
            +                displacement = this.collider.collide(other.collider);
            +
            +            }
            +
            +            if(displacement.x !== 0 || displacement.y !== 0)
            +            {
            +              var newVelX1, newVelY1, newVelX2, newVelY2;
            +
            +              if (type === 'displace' && !other.immovable) {
            +                other.position.sub(displacement);
            +              } else if ((type === 'collide' || type === 'bounce') && !this.immovable) {
            +                this.position.add(displacement);
            +                this.previousPosition = createVector(this.position.x, this.position.y);
            +                this.newPosition = createVector(this.position.x, this.position.y);
            +              }
            +
            +              if(displacement.x > 0)
            +                this.touching.left = true;
            +              if(displacement.x < 0)
            +                this.touching.right = true;
            +              if(displacement.y < 0)
            +                this.touching.bottom = true;
            +              if(displacement.y > 0)
            +                this.touching.top = true;
            +
            +              if(type === 'bounce')
            +              {
            +                if (this.collider instanceof CircleCollider && other.collider instanceof CircleCollider) {
            +                  var dx1 = p5.Vector.sub(this.position, other.position);
            +                  var dx2 = p5.Vector.sub(other.position, this.position);
            +                  var magnitude = dx1.magSq();
            +                  var totalMass = this.mass + other.mass;
            +                  var m1 = 0, m2 = 0;
            +                  if (this.immovable) {
            +                    m2 = 2;
            +                  } else if (other.immovable) {
            +                    m1 = 2;
            +                  } else {
            +                    m1 = 2 * other.mass / totalMass;
            +                    m2 = 2 * this.mass / totalMass;
            +                  }
            +                  var newVel1 = dx1.mult(m1 * p5.Vector.sub(this.velocity, other.velocity).dot(dx1) / magnitude);
            +                  var newVel2 = dx2.mult(m2 * p5.Vector.sub(other.velocity, this.velocity).dot(dx2) / magnitude);
            +
            +                  this.velocity.sub(newVel1.mult(this.restitution));
            +                  other.velocity.sub(newVel2.mult(other.restitution));
            +                }
            +                else {
            +                if(other.immovable)
            +                {
            +                  newVelX1 = -this.velocity.x+other.velocity.x;
            +                  newVelY1 = -this.velocity.y+other.velocity.y;
            +                }
            +                else
            +                {
            +                  newVelX1 = (this.velocity.x * (this.mass - other.mass) + (2 * other.mass * other.velocity.x)) / (this.mass + other.mass);
            +                  newVelY1 = (this.velocity.y * (this.mass - other.mass) + (2 * other.mass * other.velocity.y)) / (this.mass + other.mass);
            +                  newVelX2 = (other.velocity.x * (other.mass - this.mass) + (2 * this.mass * this.velocity.x)) / (this.mass + other.mass);
            +                  newVelY2 = (other.velocity.y * (other.mass - this.mass) + (2 * this.mass * this.velocity.y)) / (this.mass + other.mass);
            +                }
            +
            +                //var bothCircles = (this.collider instanceof CircleCollider &&
            +                //                   other.collider  instanceof CircleCollider);
            +
            +                //if(this.touching.left || this.touching.right || this.collider instanceof CircleCollider)
            +
            +                //print(displacement);
            +
            +                if(abs(displacement.x)>abs(displacement.y))
            +                {
            +
            +
            +                  if(!this.immovable)
            +                  {
            +                    this.velocity.x = newVelX1*this.restitution;
            +
            +                  }
            +
            +                  if(!other.immovable)
            +                    other.velocity.x = newVelX2*other.restitution;
            +
            +                }
            +                //if(this.touching.top || this.touching.bottom || this.collider instanceof CircleCollider)
            +                if(abs(displacement.x)<abs(displacement.y))
            +                {
            +
            +                  if(!this.immovable)
            +                    this.velocity.y = newVelY1*this.restitution;
            +
            +                  if(!other.immovable)
            +                    other.velocity.y = newVelY2*other.restitution;
            +                }
            +                }
            +              }
            +              //else if(type == "collide")
            +                //this.velocity = createVector(0,0);
            +
            +              if(callback !== undefined && typeof callback === 'function')
            +                callback.call(this, this, other);
            +
            +              result = true;
            +            }
            +          }
            +        }//end collider exists
            +      }
            +
            +    return result;
            +  };
            +} //end Sprite class
            +
            +defineLazyP5Property('Sprite', boundConstructorFactory(Sprite));
            +
            +/**
            +   * A camera facilitates scrolling and zooming for scenes extending beyond
            +   * the canvas. A camera has a position, a zoom factor, and the mouse
            +   * coordinates relative to the view.
            +   * The camera is automatically created on the first draw cycle.
            +   *
            +   * In p5.js terms the camera wraps the whole drawing cycle in a
            +   * transformation matrix but it can be disable anytime during the draw
            +   * cycle for example to draw interface elements in an absolute position.
            +   *
            +   * @class Camera
            +   * @constructor
            +   * @param {Number} x Initial x coordinate
            +   * @param {Number} y Initial y coordinate
            +   * @param {Number} zoom magnification
            +   **/
            +function Camera(pInst, x, y, zoom) {
            +  /**
            +  * Camera position. Defines the global offset of the sketch.
            +  *
            +  * @property position
            +  * @type {p5.Vector}
            +  */
            +  this.position = pInst.createVector(x, y);
            +
            +  /**
            +  * Camera zoom. Defines the global scale of the sketch.
            +  * A scale of 1 will be the normal size. Setting it to 2 will make everything
            +  * twice the size. .5 will make everything half size.
            +  *
            +  * @property zoom
            +  * @type {Number}
            +  */
            +  this.zoom = zoom;
            +
            +  /**
            +  * MouseX translated to the camera view.
            +  * Offsetting and scaling the canvas will not change the sprites' position
            +  * nor the mouseX and mouseY variables. Use this property to read the mouse
            +  * position if the camera moved or zoomed.
            +  *
            +  * @property mouseX
            +  * @type {Number}
            +  */
            +  this.mouseX = pInst.mouseX;
            +
            +  /**
            +  * MouseY translated to the camera view.
            +  * Offsetting and scaling the canvas will not change the sprites' position
            +  * nor the mouseX and mouseY variables. Use this property to read the mouse
            +  * position if the camera moved or zoomed.
            +  *
            +  * @property mouseY
            +  * @type {Number}
            +  */
            +  this.mouseY = pInst.mouseY;
            +
            +  /**
            +  * True if the camera is active.
            +  * Read only property. Use the methods Camera.on() and Camera.off()
            +  * to enable or disable the camera.
            +  *
            +  * @property active
            +  * @type {Boolean}
            +  */
            +  this.active = false;
            +
            +  /**
            +  * Activates the camera.
            +  * The canvas will be drawn according to the camera position and scale until
            +  * Camera.off() is called
            +  *
            +  * @method on
            +  */
            +  this.on = function() {
            +    if(!this.active)
            +    {
            +      cameraPush.call(pInst);
            +      this.active = true;
            +    }
            +  };
            +
            +  /**
            +  * Deactivates the camera.
            +  * The canvas will be drawn normally, ignoring the camera's position
            +  * and scale until Camera.on() is called
            +  *
            +  * @method off
            +  */
            +  this.off = function() {
            +    if(this.active)
            +    {
            +      cameraPop.call(pInst);
            +      this.active = false;
            +    }
            +  };
            +} //end camera class
            +
            +defineLazyP5Property('Camera', boundConstructorFactory(Camera));
            +
            +//called pre draw by default
            +function cameraPush() {
            +  var pInst = this;
            +  var camera = pInst.camera;
            +
            +  //awkward but necessary in order to have the camera at the center
            +  //of the canvas by default
            +  if(!camera.init && camera.position.x === 0 && camera.position.y === 0)
            +    {
            +    camera.position.x=pInst.width/2;
            +    camera.position.y=pInst.height/2;
            +    camera.init = true;
            +    }
            +
            +  camera.mouseX = pInst.mouseX+camera.position.x-pInst.width/2;
            +  camera.mouseY = pInst.mouseY+camera.position.y-pInst.height/2;
            +
            +  if(!camera.active)
            +  {
            +    camera.active = true;
            +    pInst.push();
            +    pInst.scale(camera.zoom);
            +    pInst.translate(-camera.position.x+pInst.width/2/camera.zoom, -camera.position.y+pInst.height/2/camera.zoom);
            +  }
            +}
            +
            +//called postdraw by default
            +function cameraPop() {
            +  var pInst = this;
            +
            +  if(pInst.camera.active)
            +  {
            +    pInst.pop();
            +    pInst.camera.active = false;
            +  }
            +}
            +
            +
            +
            +
            +/**
            +   * In p5.play groups are collections of sprites with similar behavior.
            +   * For example a group may contain all the sprites in the background
            +   * or all the sprites that "kill" the player.
            +   *
            +   * Groups are "extended" arrays and inherit all their properties
            +   * e.g. group.length
            +   *
            +   * Since groups contain only references, a sprite can be in multiple
            +   * groups and deleting a group doesn't affect the sprites themselves.
            +   *
            +   * Sprite.remove() will also remove the sprite from all the groups
            +   * it belongs to.
            +   *
            +   * @class Group
            +   * @constructor
            +   */
            +function Group() {
            +
            +  //basically extending the array
            +  var array = [];
            +
            +  /**
            +  * Gets the member at index i.
            +  *
            +  * @method get
            +  * @param {Number} i The index of the object to retrieve
            +  */
            +  array.get = function(i) {
            +    return array[i];
            +  };
            +
            +  /**
            +  * Checks if the group contains a sprite.
            +  *
            +  * @method contains
            +  * @param {Sprite} sprite The sprite to search
            +  * @return {Number} Index or -1 if not found
            +  */
            +  array.contains = function(sprite) {
            +    return this.indexOf(sprite)>-1;
            +  };
            +
            +  /**
            +   * Same as Group.contains
            +   * @method indexOf
            +   */
            +  array.indexOf = function(item) {
            +    for (var i = 0, len = array.length; i < len; ++i) {
            +      if (virtEquals(item, array[i])) {
            +        return i;
            +      }
            +    }
            +    return -1;
            +  };
            +
            +  /**
            +  * Adds a sprite to the group.
            +  *
            +  * @method add
            +  * @param {Sprite} s The sprite to be added
            +  */
            +  array.add = function(s) {
            +    if(!(s instanceof Sprite)) {
            +      throw('Error: you can only add sprites to a group');
            +    }
            +
            +    if (-1 === this.indexOf(s)) {
            +      array.push(s);
            +      s.groups.push(this);
            +    }
            +  };
            +
            +  /**
            +   * Same as group.length
            +   * @method size
            +   */
            +  array.size = function() {
            +    return array.length;
            +  };
            +
            +  /**
            +  * Removes all the sprites in the group
            +  * from the scene.
            +  *
            +  * @method removeSprites
            +  */
            +  array.removeSprites = function() {
            +    while (array.length > 0) {
            +      array[0].remove();
            +    }
            +  };
            +
            +  /**
            +  * Removes all references to the group.
            +  * Does not remove the actual sprites.
            +  *
            +  * @method clear
            +  */
            +  array.clear = function() {
            +    array.length = 0;
            +  };
            +
            +  /**
            +  * Removes a sprite from the group.
            +  * Does not remove the actual sprite, only the affiliation (reference).
            +  *
            +  * @method remove
            +  * @param {Sprite} item The sprite to be removed
            +  * @return {Boolean} True if sprite was found and removed
            +  */
            +  array.remove = function(item) {
            +    if(!(item instanceof Sprite)) {
            +      throw('Error: you can only remove sprites from a group');
            +    }
            +
            +    var i, removed = false;
            +    for (i = array.length - 1; i >= 0; i--) {
            +      if (array[i] === item) {
            +        array.splice(i, 1);
            +        removed = true;
            +      }
            +    }
            +
            +    if (removed) {
            +      for (i = item.groups.length - 1; i >= 0; i--) {
            +        if (item.groups[i] === this) {
            +          item.groups.splice(i, 1);
            +        }
            +      }
            +    }
            +
            +    return removed;
            +  };
            +
            +  /**
            +   * Returns a copy of the group as standard array.
            +   * @method toArray
            +   */
            +  array.toArray = function() {
            +    return array.slice(0);
            +  };
            +
            +  /**
            +  * Returns the highest depth in a group
            +  *
            +  * @method maxDepth
            +  * @return {Number} The depth of the sprite drawn on the top
            +  */
            +  array.maxDepth = function() {
            +    if (array.length === 0) {
            +      return 0;
            +    }
            +
            +    return array.reduce(function(maxDepth, sprite) {
            +      return Math.max(maxDepth, sprite.depth);
            +    }, -Infinity);
            +  };
            +
            +  /**
            +  * Returns the lowest depth in a group
            +  *
            +  * @method minDepth
            +  * @return {Number} The depth of the sprite drawn on the bottom
            +  */
            +  array.minDepth = function() {
            +    if (array.length === 0) {
            +      return 99999;
            +    }
            +
            +    return array.reduce(function(minDepth, sprite) {
            +      return Math.min(minDepth, sprite.depth);
            +    }, Infinity);
            +  };
            +
            +  /**
            +  * Draws all the sprites in the group.
            +  *
            +  * @method draw
            +  */
            +  array.draw = function() {
            +
            +    //sort by depth
            +    this.sort(function(a, b) {
            +      return a.depth - b.depth;
            +    });
            +
            +    for(var i = 0; i<this.size(); i++)
            +    {
            +      this.get(i).display();
            +    }
            +  };
            +
            +  //internal use
            +  function virtEquals(obj, other) {
            +    if (obj === null || other === null) {
            +      return (obj === null) && (other === null);
            +    }
            +    if (typeof (obj) === 'string') {
            +      return obj === other;
            +    }
            +    if (typeof(obj) !== 'object') {
            +      return obj === other;
            +    }
            +    if (obj.equals instanceof Function) {
            +      return obj.equals(other);
            +    }
            +    return obj === other;
            +  }
            +
            +  /**
            +   * Collide each member of group against the target using the given collision
            +   * type.  Return true if any collision occurred.
            +   * Internal use
            +   *
            +   * @private
            +   * @method _groupCollide
            +   * @param {!string} type one of 'overlap', 'collide', 'displace', 'bounce'
            +   * @param {Object} target Group or Sprite
            +   * @param {Function} [callback] on collision.
            +   * @return {boolean} True if any collision/overlap occurred
            +   */
            +  function _groupCollide(type, target, callback) {
            +    var didCollide = false;
            +    for(var i = 0; i<this.size(); i++)
            +      didCollide = this.get(i).AABBops(type, target, callback) || didCollide;
            +    return didCollide;
            +  }
            +
            +  /**
            +  * Checks if the the group is overlapping another group or sprite.
            +  * The check is performed using the colliders. If colliders are not set
            +  * they will be created automatically from the image/animation bounding box.
            +  *
            +  * A callback function can be specified to perform additional operations
            +  * when the overlap occurs.
            +  * The function will be called for each single sprite overlapping.
            +  * The parameter of the function are respectively the
            +  * member of the current group and the other sprite passed as parameter.
            +  *
            +  * @example
            +  *     group.overlap(otherSprite, explosion);
            +  *
            +  *     function explosion(spriteA, spriteB) {
            +  *       spriteA.remove();
            +  *       spriteB.score++;
            +  *     }
            +  *
            +  * @method overlap
            +  * @param {Object} target Group or Sprite to check against the current one
            +  * @param {Function} [callback] The function to be called if overlap is positive
            +  * @return {Boolean} True if overlapping
            +  */
            +  array.overlap = _groupCollide.bind(array, 'overlap');
            +
            +
            +  /**
            +  * Checks if the the group is overlapping another group or sprite.
            +  * If the overlap is positive the sprites in the group will be displaced
            +  * by the colliding one to the closest non-overlapping positions.
            +  *
            +  * The check is performed using the colliders. If colliders are not set
            +  * they will be created automatically from the image/animation bounding box.
            +  *
            +  * A callback function can be specified to perform additional operations
            +  * when the overlap occours.
            +  * The function will be called for each single sprite overlapping.
            +  * The parameter of the function are respectively the
            +  * member of the current group and the other sprite passed as parameter.
            +  *
            +  * @example
            +  *     group.collide(otherSprite, explosion);
            +  *
            +  *     function explosion(spriteA, spriteB) {
            +  *       spriteA.remove();
            +  *       spriteB.score++;
            +  *     }
            +  *
            +  * @method collide
            +  * @param {Object} target Group or Sprite to check against the current one
            +  * @param {Function} [callback] The function to be called if overlap is positive
            +  * @return {Boolean} True if overlapping
            +  */
            +  array.collide = _groupCollide.bind(array, 'collide');
            +
            +  /**
            +  * Checks if the the group is overlapping another group or sprite.
            +  * If the overlap is positive the sprites in the group will displace
            +  * the colliding ones to the closest non-overlapping positions.
            +  *
            +  * The check is performed using the colliders. If colliders are not set
            +  * they will be created automatically from the image/animation bounding box.
            +  *
            +  * A callback function can be specified to perform additional operations
            +  * when the overlap occurs.
            +  * The function will be called for each single sprite overlapping.
            +  * The parameter of the function are respectively the
            +  * member of the current group and the other sprite passed as parameter.
            +  *
            +  * @example
            +  *     group.displace(otherSprite, explosion);
            +  *
            +  *     function explosion(spriteA, spriteB) {
            +  *       spriteA.remove();
            +  *       spriteB.score++;
            +  *     }
            +  *
            +  * @method displace
            +  * @param {Object} target Group or Sprite to check against the current one
            +  * @param {Function} [callback] The function to be called if overlap is positive
            +  * @return {Boolean} True if overlapping
            +  */
            +  array.displace = _groupCollide.bind(array, 'displace');
            +
            +  /**
            +  * Checks if the the group is overlapping another group or sprite.
            +  * If the overlap is positive the sprites will bounce affecting each
            +  * other's trajectories depending on their .velocity, .mass and .restitution.
            +  *
            +  * The check is performed using the colliders. If colliders are not set
            +  * they will be created automatically from the image/animation bounding box.
            +  *
            +  * A callback function can be specified to perform additional operations
            +  * when the overlap occours.
            +  * The function will be called for each single sprite overlapping.
            +  * The parameter of the function are respectively the
            +  * member of the current group and the other sprite passed as parameter.
            +  *
            +  * @example
            +  *     group.bounce(otherSprite, explosion);
            +  *
            +  *     function explosion(spriteA, spriteB) {
            +  *       spriteA.remove();
            +  *       spriteB.score++;
            +  *     }
            +  *
            +  * @method bounce
            +  * @param {Object} target Group or Sprite to check against the current one
            +  * @param {Function} [callback] The function to be called if overlap is positive
            +  * @return {Boolean} True if overlapping
            +  */
            +  array.bounce = _groupCollide.bind(array, 'bounce');
            +
            +  return array;
            +}
            +
            +p5.prototype.Group = Group;
            +
            +//circle collider - used internally
            +function CircleCollider(pInst, _center, _radius, _offset) {
            +  var pInstBind = createPInstBinder(pInst);
            +
            +  var createVector = pInstBind('createVector');
            +
            +  var CENTER = p5.prototype.CENTER;
            +
            +  this.center = _center;
            +  this.radius = _radius;
            +  this.originalRadius = _radius;
            +
            +  if(_offset === undefined)
            +    this.offset = createVector(0, 0);
            +  else
            +    this.offset = _offset;
            +  this.extents = createVector(_radius*2, _radius*2);
            +
            +  this.draw = function()
            +  {
            +    pInst.noFill();
            +    pInst.stroke(0, 255, 0);
            +    pInst.rectMode(CENTER);
            +    pInst.ellipse(this.center.x+this.offset.x, this.center.y+this.offset.y, this.radius*2, this.radius*2);
            +  };
            +
            +  //should be called only for circle vs circle
            +  this.overlap = function(other)
            +  {
            +    //square dist
            +    var r = this.radius + other.radius;
            +    r *= r;
            +    var thisCenterX = this.center.x + this.offset.x;
            +    var thisCenterY = this.center.y + this.offset.y;
            +    var otherCenterX = other.center.x + other.offset.x;
            +    var otherCenterY = other.center.y + other.offset.y;
            +    var sqDist = pow(thisCenterX - otherCenterX, 2) + pow(thisCenterY - otherCenterY, 2);
            +    return r > sqDist;
            +  };
            +
            +  //should be called only for circle vs circle
            +  this.collide = function(other)
            +  {
            +    if(this.overlap(other)) {
            +      var thisCenterX = this.center.x + this.offset.x;
            +      var thisCenterY = this.center.y + this.offset.y;
            +      var otherCenterX = other.center.x + other.offset.x;
            +      var otherCenterY = other.center.y + other.offset.y;
            +      var a = pInst.atan2(thisCenterY-otherCenterY, thisCenterX-otherCenterX);
            +      var radii = this.radius+other.radius;
            +      var intersection = abs(radii - dist(thisCenterX, thisCenterY, otherCenterX, otherCenterY));
            +
            +      var displacement = createVector(pInst.cos(a)*intersection, pInst.sin(a)*intersection);
            +
            +      return displacement;
            +    } else {
            +      return createVector(0, 0);
            +    }
            +  };
            +
            +  this.size = function()
            +  {
            +    return createVector(this.radius*2, this.radius*2);
            +  };
            +
            +  this.left = function()
            +  {
            +    return this.center.x+this.offset.x - this.radius;
            +  };
            +
            +  this.right = function()
            +  {
            +    return this.center.x+this.offset.x + this.radius;
            +  };
            +
            +  this.top = function()
            +  {
            +    return this.center.y+this.offset.y - this.radius;
            +  };
            +
            +  this.bottom = function()
            +  {
            +    return this.center.y+this.offset.y + this.radius;
            +  };
            +
            +
            +
            +}
            +defineLazyP5Property('CircleCollider', boundConstructorFactory(CircleCollider));
            +
            +//axis aligned bounding box - extents are the half sizes - used internally
            +function AABB(pInst, _center, _extents, _offset) {
            +  var pInstBind = createPInstBinder(pInst);
            +
            +  var createVector = pInstBind('createVector');
            +
            +  var CENTER = p5.prototype.CENTER;
            +  var PI = p5.prototype.PI;
            +
            +  this.center = _center;
            +  this.extents = _extents;
            +  this.originalExtents = _extents.copy();
            +
            +  if(_offset === undefined)
            +    this.offset = createVector(0, 0);
            +  else
            +    this.offset = _offset;
            +
            +  this.min = function()
            +  {
            +    return createVector(this.center.x+this.offset.x - this.extents.x, this.center.y+this.offset.y - this.extents.y);
            +  };
            +
            +  this.max = function()
            +  {
            +    return createVector(this.center.x+this.offset.x + this.extents.x, this.center.y+this.offset.y + this.extents.y);
            +  };
            +
            +  this.right = function()
            +  {
            +    return this.center.x+this.offset.x + this.extents.x/2;
            +  };
            +
            +  this.left = function()
            +  {
            +    return this.center.x+this.offset.x - this.extents.x/2;
            +  };
            +
            +  this.top = function()
            +  {
            +    return this.center.y+this.offset.y - this.extents.y/2;
            +  };
            +
            +  this.bottom = function()
            +  {
            +    return this.center.y+this.offset.y + this.extents.y/2;
            +  };
            +
            +  this.size = function()
            +  {
            +    return createVector(this.extents.x * 2, this.extents.y * 2);
            +  };
            +
            +  this.rotate = function(r)
            +  {
            +    //rotate the bbox
            +    var t;
            +    if (pInst._angleMode === pInst.RADIANS) {
            +      t = radians(r);
            +    } else {
            +      t = r;
            +    }
            +
            +    var w2 = this.extents.x * abs(pInst.cos(t)) + this.extents.y * abs(pInst.sin(t));
            +    var h2 = this.extents.x * abs(pInst.sin(t)) + this.extents.y * abs(pInst.cos(t));
            +
            +    this.extents.x = w2;
            +    this.extents.y = h2;
            +
            +  };
            +
            +  this.draw = function()
            +  {
            +    //fill(col);
            +    pInst.noFill();
            +    pInst.stroke(0, 255, 0);
            +    pInst.rectMode(CENTER);
            +    pInst.rect(this.center.x+this.offset.x, this.center.y+this.offset.y, this.size().x/2, this.size().y/2);
            +  };
            +
            +  this.overlap = function(other)
            +  {
            +    //box vs box
            +    if(other instanceof AABB)
            +    {
            +      var md = other.minkowskiDifference(this);
            +
            +      if (md.min().x <= 0 &&
            +          md.max().x >= 0 &&
            +          md.min().y <= 0 &&
            +          md.max().y >= 0)
            +      {
            +        return true;
            +      }
            +      else
            +        return false;
            +    }
            +    //box vs circle
            +    else if(other instanceof CircleCollider)
            +    {
            +
            +      //find closest point to the circle on the box
            +      var pt = createVector(other.center.x, other.center.y);
            +
            +      //I don't know what's going o try to trace a line from centers to see
            +      if( other.center.x < this.left() )
            +        pt.x = this.left();
            +      else if( other.center.x > this.right())
            +        pt.x = this.right();
            +
            +      if( other.center.y < this.top() )
            +        pt.y = this.top();
            +      else if( other.center.y > this.bottom())
            +        pt.y = this.bottom();
            +
            +      var distance = pt.dist(other.center);
            +
            +      return distance<other.radius;
            +    }
            +  };
            +
            +  this.collide = function(other)
            +  {
            +
            +    if(other instanceof AABB)
            +    {
            +      var md = other.minkowskiDifference(this);
            +
            +      if (md.min().x <= 0 &&
            +          md.max().x >= 0 &&
            +          md.min().y <= 0 &&
            +          md.max().y >= 0)
            +      {
            +        var boundsPoint = md.closestPointOnBoundsToPoint(createVector(0, 0));
            +
            +        return boundsPoint;
            +      }
            +      else
            +        return createVector(0, 0);
            +    }
            +    //box vs circle
            +    else if(other instanceof CircleCollider)
            +    {
            +
            +      //find closest point to the circle on the box
            +      var pt = createVector(other.center.x, other.center.y);
            +
            +      //I don't know what's going o try to trace a line from centers to see
            +      if( other.center.x < this.left() )
            +        pt.x = this.left();
            +      else if( other.center.x > this.right())
            +        pt.x = this.right();
            +
            +      if( other.center.y < this.top() )
            +        pt.y = this.top();
            +      else if( other.center.y > this.bottom())
            +        pt.y = this.bottom();
            +
            +
            +      var distance = pt.dist(other.center);
            +      var a;
            +
            +      if(distance<other.radius)
            +      {
            +        //reclamp point
            +        if(pt.x === other.center.x && pt.y === other.center.y)
            +        {
            +          var xOverlap = pt.x - this.center.x;
            +          var yOverlap = pt.y - this.center.y;
            +
            +
            +          if(abs(xOverlap) < abs(yOverlap))
            +          {
            +            if(xOverlap > 0 )
            +              pt.x = this.right();
            +            else
            +              pt.x = this.left();
            +          }
            +          else
            +          {
            +            if(yOverlap < 0 )
            +              pt.y = this.top();
            +            else
            +              pt.y = this.bottom();
            +          }
            +
            +          a = pInst.atan2(other.center.y-pt.y, other.center.x-pt.x);
            +
            +          //fix exceptions
            +          if(a === 0)
            +          {
            +            if(pt.x === this.right()) a = PI;
            +            if(pt.y === this.top()) a = PI/2;
            +            if(pt.y === this.bottom()) a = -PI/2;
            +          }
            +        }
            +        else
            +        {
            +          //angle bw point and center
            +          a = pInst.atan2(pt.y-other.center.y, pt.x-other.center.x);
            +          //project the normal (line between pt and center) onto the circle
            +        }
            +
            +        var d = createVector(pt.x-other.center.x, pt.y-other.center.y);
            +        var displacement = createVector(pInst.cos(a)*other.radius-d.x, pInst.sin(a)*other.radius-d.y);
            +
            +        //if(pt.x === other.center.x && pt.y === other.center.y)
            +        //displacement = displacement.mult(-1);
            +
            +        return displacement;
            +        //return createVector(0,0);
            +      }
            +      else
            +        return createVector(0, 0);
            +    }
            +  };
            +
            +  this.minkowskiDifference = function(other)
            +  {
            +    var topLeft = this.min().sub(other.max());
            +    var fullSize = this.size().add(other.size());
            +    return new AABB(pInst, topLeft.add(fullSize.div(2)), fullSize.div(2));
            +  };
            +
            +
            +  this.closestPointOnBoundsToPoint = function(point)
            +  {
            +    // test x first
            +    var minDist = abs(point.x - this.min().x);
            +    var boundsPoint = createVector(this.min().x, point.y);
            +
            +    if (abs(this.max().x - point.x) < minDist)
            +    {
            +      minDist = abs(this.max().x - point.x);
            +      boundsPoint = createVector(this.max().x, point.y);
            +    }
            +
            +    if (abs(this.max().y - point.y) < minDist)
            +    {
            +      minDist = abs(this.max().y - point.y);
            +      boundsPoint = createVector(point.x, this.max().y);
            +    }
            +
            +    if (abs(this.min().y - point.y) < minDist)
            +    {
            +      minDist = abs(this.min.y - point.y);
            +      boundsPoint = createVector(point.x, this.min().y);
            +    }
            +
            +    return boundsPoint;
            +  };
            +
            +
            +}//end AABB
            +defineLazyP5Property('AABB', boundConstructorFactory(AABB));
            +
            +
            +
            +/**
            + * An Animation object contains a series of images (p5.Image) that
            + * can be displayed sequentially.
            + *
            + * All files must be png images. You must include the directory from the sketch root,
            + * and the extension .png
            + *
            + * A sprite can have multiple labeled animations, see Sprite.addAnimation
            + * and Sprite.changeAnimation, however an animation can be used independently.
            + *
            + * An animation can be created either by passing a series of file names,
            + * no matter how many or by passing the first and the last file name
            + * of a numbered sequence.
            + * p5.play will try to detect the sequence pattern.
            + *
            + * For example if the given filenames are
            + * "data/file0001.png" and "data/file0005.png" the images
            + * "data/file0003.png" and "data/file0004.png" will be loaded as well.
            + *
            + * @example
            + *     var sequenceAnimation;
            + *     var glitch;
            + *
            + *     function preload() {
            + *       sequenceAnimation = loadAnimation("data/walking0001.png", "data/walking0005.png");
            + *       glitch = loadAnimation("data/dog.png", "data/horse.png", "data/cat.png", "data/snake.png");
            + *     }
            + *
            + *     function setup() {
            + *       createCanvas(800, 600);
            + *     }
            + *
            + *     function draw() {
            + *       background(0);
            + *       animation(sequenceAnimation, 100, 100);
            + *       animation(glitch, 200, 100);
            + *     }
            + *
            + * @class Animation
            + * @constructor
            + * @param {String} fileName1 First file in a sequence OR first image file
            + * @param {String} fileName2 Last file in a sequence OR second image file
            + * @param {String} [...fileNameN] Any number of image files after the first two
            + */
            +function Animation(pInst) {
            +  var frameArguments = Array.prototype.slice.call(arguments, 1);
            +  var i;
            +
            +  var CENTER = p5.prototype.CENTER;
            +
            +  /**
            +  * Array of frames (p5.Image)
            +  *
            +  * @property images
            +  * @type {Array}
            +  */
            +  this.images = [];
            +
            +  var frame = 0;
            +  var cycles = 0;
            +  var targetFrame = -1;
            +
            +  this.offX = 0;
            +  this.offY = 0;
            +
            +  /**
            +  * Delay between frames in number of draw cycles.
            +  * If set to 4 the framerate of the animation would be the
            +  * sketch framerate divided by 4 (60fps = 15fps)
            +  *
            +  * @property frameDelay
            +  * @type {Number}
            +  * @default 4
            +  */
            +  this.frameDelay = 4;
            +
            +  /**
            +  * True if the animation is currently playing.
            +  *
            +  * @property playing
            +  * @type {Boolean}
            +  * @default true
            +  */
            +  this.playing = true;
            +
            +  /**
            +  * Animation visibility.
            +  *
            +  * @property visible
            +  * @type {Boolean}
            +  * @default true
            +  */
            +  this.visible = true;
            +
            +  /**
            +  * If set to false the animation will stop after reaching the last frame
            +  *
            +  * @property looping
            +  * @type {Boolean}
            +  * @default true
            +  */
            +  this.looping = true;
            +
            +  /**
            +  * True if frame changed during the last draw cycle
            +  *
            +  * @property frameChanged
            +  * @type {Boolean}
            +  */
            +  this.frameChanged = false;
            +
            +  //is the collider defined manually or defined
            +  //by the current frame size
            +  this.imageCollider = false;
            +
            +
            +  //sequence mode
            +  if(frameArguments.length === 2 && typeof frameArguments[0] === 'string' && typeof frameArguments[1] === 'string')
            +  {
            +    var from = frameArguments[0];
            +    var to = frameArguments[1];
            +
            +    //print("sequence mode "+from+" -> "+to);
            +
            +    //make sure the extensions are fine
            +    var ext1 = from.substring(from.length-4, from.length);
            +    if(ext1 !== '.png')
            +    {
            +      pInst.print('Animation error: you need to use .png files (filename '+from+')');
            +      from = -1;
            +    }
            +
            +    var ext2 = to.substring(to.length-4, to.length);
            +    if(ext2 !== '.png')
            +    {
            +      pInst.print('Animation error: you need to use .png files (filename '+to+')');
            +      to = -1;
            +    }
            +
            +    //extensions are fine
            +    if(from !== -1 && to !== -1)
            +    {
            +      var digits1 = 0;
            +      var digits2 = 0;
            +
            +      //skip extension work backwards to find the numbers
            +      for (i = from.length-5; i >= 0; i--) {
            +        if(from.charAt(i) >= '0' && from.charAt(i) <= '9')
            +          digits1++;
            +      }
            +
            +      for (i = to.length-5; i >= 0; i--) {
            +        if(to.charAt(i) >= '0' && to.charAt(i) <= '9')
            +          digits2++;
            +      }
            +
            +      var prefix1 = from.substring(0, from.length-(4+digits1));
            +      var prefix2 = to.substring(0, to.length-(4+digits2) );
            +
            +      // Our numbers likely have leading zeroes, which means that some
            +      // browsers (e.g., PhantomJS) will interpret them as base 8 (octal)
            +      // instead of decimal. To fix this, we'll explicity tell parseInt to
            +      // use a base of 10 (decimal). For more details on this issue, see
            +      // http://stackoverflow.com/a/8763427/2422398.
            +      var number1 = parseInt(from.substring(from.length-(4+digits1), from.length-4), 10);
            +      var number2 = parseInt(to.substring(to.length-(4+digits2), to.length-4), 10);
            +
            +      //swap if inverted
            +      if(number2<number1)
            +      {
            +        var t = number2;
            +        number2 = number1;
            +        number1 = t;
            +      }
            +
            +      //two different frames
            +      if(prefix1 !== prefix2 )
            +      {
            +        //print("2 separate images");
            +        this.images.push(pInst.loadImage(from));
            +        this.images.push(pInst.loadImage(to));
            +      }
            +      //same digits: case img0001, img0002
            +      else
            +      {
            +        var fileName;
            +        if(digits1 === digits2)
            +        {
            +
            +          //load all images
            +          for (i = number1; i <= number2; i++) {
            +            // Use nf() to number format 'i' into four digits
            +            fileName = prefix1 + pInst.nf(i, digits1) + '.png';
            +            this.images.push(pInst.loadImage(fileName));
            +
            +          }
            +
            +        }
            +        else //case: case img1, img2
            +        {
            +          //print("from "+prefix1+" "+number1 +" to "+number2);
            +          for (i = number1; i <= number2; i++) {
            +            // Use nf() to number format 'i' into four digits
            +            fileName = prefix1 + i + '.png';
            +            this.images.push(pInst.loadImage(fileName));
            +
            +          }
            +
            +        }
            +      }
            +
            +    }//end no ext error
            +
            +  }//end sequence mode
            +  // Sprite sheet mode
            +  else if (frameArguments.length === 1 && (frameArguments[0] instanceof SpriteSheet))
            +  {
            +    this.spriteSheet = frameArguments[0];
            +    this.images = this.spriteSheet.frames;
            +  }
            +  else if(frameArguments.length !== 0)//arbitrary list of images
            +  {
            +    //print("Animation arbitrary mode");
            +    for (i = 0; i < frameArguments.length; i++) {
            +      //print("loading "+fileNames[i]);
            +      if(frameArguments[i] instanceof p5.Image)
            +        this.images.push(frameArguments[i]);
            +      else
            +        this.images.push(pInst.loadImage(frameArguments[i]));
            +    }
            +  }
            +
            +  /**
            +  * Objects are passed by reference so to have different sprites
            +  * using the same animation you need to clone it.
            +  *
            +  * @method clone
            +  * @return {Animation} A clone of the current animation
            +  */
            +  this.clone = function() {
            +    var myClone = new Animation(pInst); //empty
            +    myClone.images = [];
            +
            +    if (this.spriteSheet) {
            +      myClone.spriteSheet = this.spriteSheet.clone();
            +    }
            +    myClone.images = this.images.slice();
            +
            +    myClone.offX = this.offX;
            +    myClone.offY = this.offY;
            +    myClone.frameDelay = this.frameDelay;
            +    myClone.playing = this.playing;
            +    myClone.looping = this.looping;
            +
            +    return myClone;
            +  };
            +
            +  /**
            +   * Draws the animation at coordinate x and y.
            +   * Updates the frames automatically.
            +   *
            +   * @method draw
            +   * @param {Number} x x coordinate
            +   * @param {Number} y y coordinate
            +   * @param {Number} [r=0] rotation
            +   */
            +  this.draw = function(x, y, r) {
            +    this.xpos = x;
            +    this.ypos = y;
            +    this.rotation = r || 0;
            +
            +    if (this.visible)
            +    {
            +
            +      //only connection with the sprite class
            +      //if animation is used independently draw and update are the sam
            +      if(!this.isSpriteAnimation)
            +        this.update();
            +
            +      //this.currentImageMode = g.imageMode;
            +      pInst.push();
            +      pInst.imageMode(CENTER);
            +
            +      pInst.translate(this.xpos, this.ypos);
            +      if (pInst._angleMode === pInst.RADIANS) {
            +        pInst.rotate(radians(this.rotation));
            +      } else {
            +        pInst.rotate(this.rotation);
            +      }
            +
            +      if(this.images[frame] !== undefined)
            +      {
            +        if (this.spriteSheet) {
            +          var frame_info = this.images[frame].frame;
            +          pInst.image(this.spriteSheet.image, frame_info.x, frame_info.y, frame_info.width,
            +            frame_info.height, this.offX, this.offY, frame_info.width, frame_info.height);
            +        } else {
            +          pInst.image(this.images[frame], this.offX, this.offY);
            +        }
            +      }
            +      else
            +      {
            +        pInst.print('Warning undefined frame '+frame);
            +        //this.isActive = false;
            +      }
            +
            +      pInst.pop();
            +    }
            +  };
            +
            +  //called by draw
            +  this.update = function() {
            +    cycles++;
            +    var previousFrame = frame;
            +    this.frameChanged = false;
            +
            +
            +    //go to frame
            +    if(this.images.length === 1)
            +    {
            +      this.playing = false;
            +      frame = 0;
            +    }
            +
            +    if ( this.playing && cycles%this.frameDelay === 0)
            +    {
            +      //going to target frame up
            +      if(targetFrame>frame && targetFrame !== -1)
            +      {
            +        frame++;
            +      }
            +      //going to taget frame down
            +      else if(targetFrame<frame && targetFrame !== -1)
            +      {
            +        frame--;
            +      }
            +      else if(targetFrame === frame && targetFrame !== -1)
            +      {
            +        this.playing=false;
            +      }
            +      else if (this.looping) //advance frame
            +      {
            +        //if next frame is too high
            +        if (frame>=this.images.length-1)
            +          frame = 0;
            +        else
            +          frame++;
            +      } else
            +      {
            +        //if next frame is too high
            +        if (frame<this.images.length-1)
            +          frame++;
            +      }
            +    }
            +
            +    if(previousFrame !== frame)
            +      this.frameChanged = true;
            +
            +  };//end update
            +
            +  /**
            +  * Plays the animation.
            +  *
            +  * @method play
            +  */
            +  this.play = function() {
            +    this.playing = true;
            +    targetFrame = -1;
            +  };
            +
            +  /**
            +  * Stops the animation.
            +  *
            +  * @method stop
            +  */
            +  this.stop = function(){
            +    this.playing = false;
            +  };
            +
            +  /**
            +  * Rewinds the animation to the first frame.
            +  *
            +  * @method rewind
            +  */
            +  this.rewind = function() {
            +    frame = 0;
            +  };
            +
            +  /**
            +  * Changes the current frame.
            +  *
            +  * @method changeFrame
            +  * @param {Number} frame Frame number (starts from 0).
            +  */
            +  this.changeFrame = function(f) {
            +    if (f<this.images.length)
            +      frame = f;
            +    else
            +      frame = this.images.length - 1;
            +
            +    targetFrame = -1;
            +    //this.playing = false;
            +  };
            +
            +   /**
            +  * Goes to the next frame and stops.
            +  *
            +  * @method nextFrame
            +  */
            +  this.nextFrame = function() {
            +
            +    if (frame<this.images.length-1)
            +      frame = frame+1;
            +    else if(this.looping)
            +      frame = 0;
            +
            +    targetFrame = -1;
            +    this.playing = false;
            +  };
            +
            +   /**
            +  * Goes to the previous frame and stops.
            +  *
            +  * @method previousFrame
            +  */
            +  this.previousFrame = function() {
            +
            +    if (frame>0)
            +      frame = frame-1;
            +    else if(this.looping)
            +      frame = this.images.length-1;
            +
            +    targetFrame = -1;
            +    this.playing = false;
            +  };
            +
            +  /**
            +  * Plays the animation forward or backward toward a target frame.
            +  *
            +  * @method goToFrame
            +  * @param {Number} toFrame Frame number destination (starts from 0)
            +  */
            +  this.goToFrame = function(toFrame) {
            +    if(toFrame < 0 || toFrame >= this.images.length) {
            +      return;
            +    }
            +
            +    // targetFrame gets used by the update() method to decide what frame to
            +    // select next.  When it's not being used it gets set to -1.
            +    targetFrame = toFrame;
            +
            +    if(targetFrame !== frame) {
            +      this.playing = true;
            +    }
            +  };
            +
            +  /**
            +  * Returns the current frame number.
            +  *
            +  * @method getFrame
            +  * @return {Number} Current frame (starts from 0)
            +  */
            +  this.getFrame = function() {
            +    return frame;
            +  };
            +
            +  /**
            +  * Returns the last frame number.
            +  *
            +  * @method getLastFrame
            +  * @return {Number} Last frame number (starts from 0)
            +  */
            +  this.getLastFrame = function() {
            +    return this.images.length-1;
            +  };
            +
            +  /**
            +  * Returns the current frame image as p5.Image.
            +  *
            +  * @method getFrameImage
            +  * @return {p5.Image} Current frame image
            +  */
            +  this.getFrameImage = function() {
            +    return this.images[frame];
            +  };
            +
            +  /**
            +  * Returns the frame image at the specified frame number.
            +  *
            +  * @method getImageAt
            +  * @param {Number} frame Frame number
            +  * @return {p5.Image} Frame image
            +  */
            +  this.getImageAt = function(f) {
            +    return this.images[f];
            +  };
            +
            +  /**
            +  * Returns the current frame width in pixels.
            +  * If there is no image loaded, returns 1.
            +  *
            +  * @method getWidth
            +  * @return {Number} Frame width
            +  */
            +  this.getWidth = function() {
            +    if (this.images[frame] instanceof p5.Image) {
            +      return this.images[frame].width;
            +    } else if (this.images[frame]) {
            +      // Special case: Animation-from-spritesheet treats its images array differently.
            +      return this.images[frame].frame.width;
            +    } else {
            +      return 1;
            +    }
            +  };
            +
            +  /**
            +  * Returns the current frame height in pixels.
            +  * If there is no image loaded, returns 1.
            +  *
            +  * @method getHeight
            +  * @return {Number} Frame height
            +  */
            +  this.getHeight = function() {
            +    if (this.images[frame] instanceof p5.Image) {
            +      return this.images[frame].height;
            +    } else if (this.images[frame]) {
            +      // Special case: Animation-from-spritesheet treats its images array differently.
            +      return this.images[frame].frame.height;
            +    } else {
            +      return 1;
            +    }
            +  };
            +
            +}
            +
            +defineLazyP5Property('Animation', boundConstructorFactory(Animation));
            +
            +/**
            + * Represents a sprite sheet and all it's frames.  To be used with Animation,
            + * or static drawing single frames.
            + *
            + *  There are two different ways to load a SpriteSheet
            + *
            + * 1. Given width, height that will be used for every frame and the
            + *    number of frames to cycle through. The sprite sheet must have a
            + *    uniform grid with consistent rows and columns.
            + *
            + * 2. Given an array of frame objects that define the position and
            + *    dimensions of each frame.  This is Flexible because you can use
            + *    sprite sheets that don't have uniform rows and columns.
            + *
            + * @example
            + *     // Method 1 - Using width, height for each frame and number of frames
            + *     explode_sprite_sheet = loadSpriteSheet('assets/explode_sprite_sheet.png', 171, 158, 11);
            + *
            + *     // Method 2 - Using an array of objects that define each frame
            + *     var player_frames = loadJSON('assets/tiles.json');
            + *     player_sprite_sheet = loadSpriteSheet('assets/player_spritesheet.png', player_frames);
            + *
            + * @class SpriteSheet
            + * @constructor
            + * @param image String image path or p5.Image object
            + */
            +function SpriteSheet(pInst) {
            +  var spriteSheetArgs = Array.prototype.slice.call(arguments, 1);
            +
            +  this.image = null;
            +  this.frames = [];
            +  this.frame_width = 0;
            +  this.frame_height = 0;
            +  this.num_frames = 0;
            +
            +  /**
            +   * Generate the frames data for this sprite sheet baesd on user params
            +   * @private
            +   * @method _generateSheetFrames
            +   */
            +  this._generateSheetFrames = function() {
            +    var sX = 0, sY = 0;
            +    for (var i = 0; i < this.num_frames; i++) {
            +      this.frames.push(
            +        {
            +          'name': i,
            +          'frame': {
            +            'x': sX,
            +            'y': sY,
            +            'width': this.frame_width,
            +            'height': this.frame_height
            +          }
            +        });
            +      sX += this.frame_width;
            +      if (sX >= this.image.width) {
            +        sX = 0;
            +        sY += this.frame_height;
            +        if (sY >= this.image.height) {
            +          sY = 0;
            +        }
            +      }
            +    }
            +  };
            +
            +  if (spriteSheetArgs.length === 2 && Array.isArray(spriteSheetArgs[1])) {
            +    this.frames = spriteSheetArgs[1];
            +    this.num_frames = this.frames.length;
            +  } else if (spriteSheetArgs.length === 4 &&
            +    (typeof spriteSheetArgs[1] === 'number') &&
            +    (typeof spriteSheetArgs[2] === 'number') &&
            +    (typeof spriteSheetArgs[3] === 'number')) {
            +    this.frame_width = spriteSheetArgs[1];
            +    this.frame_height = spriteSheetArgs[2];
            +    this.num_frames = spriteSheetArgs[3];
            +  }
            +
            +  if(spriteSheetArgs[0] instanceof p5.Image) {
            +    this.image = spriteSheetArgs[0];
            +    if (spriteSheetArgs.length === 4) {
            +      this._generateSheetFrames();
            +    }
            +  } else {
            +    if (spriteSheetArgs.length === 2) {
            +      this.image = pInst.loadImage(spriteSheetArgs[0]);
            +    } else if (spriteSheetArgs.length === 4) {
            +      this.image = pInst.loadImage(spriteSheetArgs[0], this._generateSheetFrames.bind(this));
            +    }
            +  }
            +
            +  /**
            +   * Draws a specific frame to the canvas.
            +   * @param frame_name  Can either be a string name, or a numeric index.
            +   * @param x   x position to draw the frame at
            +   * @param y   y position to draw the frame at
            +   * @param [width]   optional width to draw the frame
            +   * @param [height]  optional height to draw the frame
            +   * @method drawFrame
            +   */
            +  this.drawFrame = function(frame_name, x, y, width, height) {
            +    var frameToDraw;
            +    if (typeof frame_name === 'number') {
            +      frameToDraw = this.frames[frame_name].frame;
            +    } else {
            +      for (var i = 0; i < this.frames.length; i++) {
            +        if (this.frames[i].name === frame_name) {
            +          frameToDraw = this.frames[i].frame;
            +          break;
            +        }
            +      }
            +    }
            +    var dWidth = width || frameToDraw.width;
            +    var dHeight = height || frameToDraw.height;
            +    pInst.image(this.image, frameToDraw.x, frameToDraw.y,
            +      frameToDraw.width, frameToDraw.height, x, y, dWidth, dHeight);
            +  };
            +
            +  /**
            +   * Objects are passed by reference so to have different sprites
            +   * using the same animation you need to clone it.
            +   *
            +   * @method clone
            +   * @return {SpriteSheet} A clone of the current SpriteSheet
            +   */
            +  this.clone = function() {
            +    var myClone = new SpriteSheet(pInst); //empty
            +
            +    // Deep clone the frames by value not reference
            +    for(var i = 0; i < this.frames.length; i++) {
            +      var frame = this.frames[i].frame;
            +      var cloneFrame = {
            +        'name':frame.name,
            +        'frame': {
            +          'x':frame.x,
            +          'y':frame.y,
            +          'width':frame.width,
            +          'height':frame.height
            +        }
            +      };
            +      myClone.frames.push(cloneFrame);
            +    }
            +
            +    // clone other fields
            +    myClone.image = this.image;
            +    myClone.frame_width = this.frame_width;
            +    myClone.frame_height = this.frame_height;
            +    myClone.num_frames = this.num_frames;
            +
            +    return myClone;
            +  };
            +}
            +
            +defineLazyP5Property('SpriteSheet', boundConstructorFactory(SpriteSheet));
            +
            +//general constructor to be able to feed arguments as array
            +function construct(constructor, args) {
            +  function F() {
            +    return constructor.apply(this, args);
            +  }
            +  F.prototype = constructor.prototype;
            +  return new F();
            +}
            +
            +
            +
            +
            +
            +/*
            + * Javascript Quadtree
            + * based on
            + * https://github.com/timohausmann/quadtree-js/
            + * Copyright © 2012 Timo Hausmann
            +*/
            +
            +function Quadtree( bounds, max_objects, max_levels, level ) {
            +
            +  this.active = true;
            +  this.max_objects	= max_objects || 10;
            +  this.max_levels		= max_levels || 4;
            +
            +  this.level 			= level || 0;
            +  this.bounds 		= bounds;
            +
            +  this.objects 		= [];
            +  this.object_refs	= [];
            +  this.nodes 			= [];
            +}
            +
            +Quadtree.prototype.updateBounds = function() {
            +
            +  //find maximum area
            +  var objects = this.getAll();
            +  var x = 10000;
            +  var y = 10000;
            +  var w = -10000;
            +  var h = -10000;
            +
            +  for( var i=0; i < objects.length; i++ )
            +    {
            +      if(objects[i].position.x < x)
            +        x = objects[i].position.x;
            +      if(objects[i].position.y < y)
            +        y = objects[i].position.y;
            +      if(objects[i].position.x > w)
            +        w = objects[i].position.x;
            +      if(objects[i].position.y > h)
            +        h = objects[i].position.y;
            +    }
            +
            +
            +  this.bounds = {
            +    x:x,
            +    y:y,
            +    width:w,
            +    height:h
            +  };
            +  //print(this.bounds);
            +};
            +
            +/*
            +	 * Split the node into 4 subnodes
            +	 */
            +Quadtree.prototype.split = function() {
            +
            +  var nextLevel	= this.level + 1,
            +      subWidth	= Math.round( this.bounds.width / 2 ),
            +      subHeight 	= Math.round( this.bounds.height / 2 ),
            +      x 			= Math.round( this.bounds.x ),
            +      y 			= Math.round( this.bounds.y );
            +
            +  //top right node
            +  this.nodes[0] = new Quadtree({
            +    x	: x + subWidth,
            +    y	: y,
            +    width	: subWidth,
            +    height	: subHeight
            +  }, this.max_objects, this.max_levels, nextLevel);
            +
            +  //top left node
            +  this.nodes[1] = new Quadtree({
            +    x	: x,
            +    y	: y,
            +    width	: subWidth,
            +    height	: subHeight
            +  }, this.max_objects, this.max_levels, nextLevel);
            +
            +  //bottom left node
            +  this.nodes[2] = new Quadtree({
            +    x	: x,
            +    y	: y + subHeight,
            +    width	: subWidth,
            +    height	: subHeight
            +  }, this.max_objects, this.max_levels, nextLevel);
            +
            +  //bottom right node
            +  this.nodes[3] = new Quadtree({
            +    x	: x + subWidth,
            +    y	: y + subHeight,
            +    width	: subWidth,
            +    height	: subHeight
            +  }, this.max_objects, this.max_levels, nextLevel);
            +};
            +
            +
            +/*
            +	 * Determine the quadtrant for an area in this node
            +	 */
            +Quadtree.prototype.getIndex = function( pRect ) {
            +  if(!pRect.collider)
            +    return -1;
            +  else
            +  {
            +    var index 				= -1,
            +        verticalMidpoint 	= this.bounds.x + (this.bounds.width / 2),
            +        horizontalMidpoint 	= this.bounds.y + (this.bounds.height / 2),
            +
            +        //pRect can completely fit within the top quadrants
            +        topQuadrant = (pRect.collider.top() < horizontalMidpoint && pRect.collider.top() + pRect.collider.size().y < horizontalMidpoint),
            +
            +        //pRect can completely fit within the bottom quadrants
            +        bottomQuadrant = (pRect.collider.top() > horizontalMidpoint);
            +
            +    //pRect can completely fit within the left quadrants
            +    if( pRect.collider.left() < verticalMidpoint && pRect.collider.left() + pRect.collider.size().x < verticalMidpoint ) {
            +      if( topQuadrant ) {
            +        index = 1;
            +      } else if( bottomQuadrant ) {
            +        index = 2;
            +      }
            +
            +      //pRect can completely fit within the right quadrants
            +    } else if( pRect.collider.left() > verticalMidpoint ) {
            +      if( topQuadrant ) {
            +        index = 0;
            +      } else if( bottomQuadrant ) {
            +        index = 3;
            +      }
            +    }
            +
            +    return index;
            +  }
            +};
            +
            +
            +/*
            +	 * Insert an object into the node. If the node
            +	 * exceeds the capacity, it will split and add all
            +	 * objects to their corresponding subnodes.
            +	 */
            +Quadtree.prototype.insert = function( obj ) {
            +  //avoid double insertion
            +  if(this.objects.indexOf(obj) === -1)
            +  {
            +
            +    var i = 0,
            +        index;
            +
            +    //if we have subnodes ...
            +    if( typeof this.nodes[0] !== 'undefined' ) {
            +      index = this.getIndex( obj );
            +
            +      if( index !== -1 ) {
            +        this.nodes[index].insert( obj );
            +        return;
            +      }
            +    }
            +
            +    this.objects.push( obj );
            +
            +    if( this.objects.length > this.max_objects && this.level < this.max_levels ) {
            +
            +      //split if we don't already have subnodes
            +      if( typeof this.nodes[0] === 'undefined' ) {
            +        this.split();
            +      }
            +
            +      //add all objects to there corresponding subnodes
            +      while( i < this.objects.length ) {
            +
            +        index = this.getIndex( this.objects[i] );
            +
            +        if( index !== -1 ) {
            +          this.nodes[index].insert( this.objects.splice(i, 1)[0] );
            +        } else {
            +          i = i + 1;
            +        }
            +      }
            +    }
            +  }
            +};
            +
            +
            +/*
            +	 * Return all objects that could collide with a given area
            +	 */
            +Quadtree.prototype.retrieve = function( pRect ) {
            +
            +
            +  var index = this.getIndex( pRect ),
            +      returnObjects = this.objects;
            +
            +  //if we have subnodes ...
            +  if( typeof this.nodes[0] !== 'undefined' ) {
            +
            +    //if pRect fits into a subnode ..
            +    if( index !== -1 ) {
            +      returnObjects = returnObjects.concat( this.nodes[index].retrieve( pRect ) );
            +
            +      //if pRect does not fit into a subnode, check it against all subnodes
            +    } else {
            +      for( var i=0; i < this.nodes.length; i=i+1 ) {
            +        returnObjects = returnObjects.concat( this.nodes[i].retrieve( pRect ) );
            +      }
            +    }
            +  }
            +
            +  return returnObjects;
            +};
            +
            +Quadtree.prototype.retrieveFromGroup = function( pRect, group ) {
            +
            +  var results = [];
            +  var candidates = this.retrieve(pRect);
            +
            +  for(var i=0; i<candidates.length; i++)
            +    if(group.contains(candidates[i]))
            +    results.push(candidates[i]);
            +
            +  return results;
            +};
            +
            +/*
            +	 * Get all objects stored in the quadtree
            +	 */
            +Quadtree.prototype.getAll = function() {
            +
            +  var objects = this.objects;
            +
            +  for( var i=0; i < this.nodes.length; i=i+1 ) {
            +    objects = objects.concat( this.nodes[i].getAll() );
            +  }
            +
            +  return objects;
            +};
            +
            +
            +/*
            +	 * Get the node in which a certain object is stored
            +	 */
            +Quadtree.prototype.getObjectNode = function( obj ) {
            +
            +  var index;
            +
            +  //if there are no subnodes, object must be here
            +  if( !this.nodes.length ) {
            +
            +    return this;
            +
            +  } else {
            +
            +    index = this.getIndex( obj );
            +
            +    //if the object does not fit into a subnode, it must be here
            +    if( index === -1 ) {
            +
            +      return this;
            +
            +      //if it fits into a subnode, continue deeper search there
            +    } else {
            +      var node = this.nodes[index].getObjectNode( obj );
            +      if( node ) return node;
            +    }
            +  }
            +
            +  return false;
            +};
            +
            +
            +/*
            +	 * Removes a specific object from the quadtree
            +	 * Does not delete empty subnodes. See cleanup-function
            +	 */
            +Quadtree.prototype.removeObject = function( obj ) {
            +
            +  var node = this.getObjectNode( obj ),
            +      index = node.objects.indexOf( obj );
            +
            +  if( index === -1 ) return false;
            +
            +  node.objects.splice( index, 1);
            +};
            +
            +
            +/*
            +	 * Clear the quadtree and delete all objects
            +	 */
            +Quadtree.prototype.clear = function() {
            +
            +  this.objects = [];
            +
            +  if( !this.nodes.length ) return;
            +
            +  for( var i=0; i < this.nodes.length; i=i+1 ) {
            +
            +    this.nodes[i].clear();
            +  }
            +
            +  this.nodes = [];
            +};
            +
            +
            +/*
            +	 * Clean up the quadtree
            +	 * Like clear, but objects won't be deleted but re-inserted
            +	 */
            +Quadtree.prototype.cleanup = function() {
            +
            +  var objects = this.getAll();
            +
            +  this.clear();
            +
            +  for( var i=0; i < objects.length; i++ ) {
            +    this.insert( objects[i] );
            +  }
            +};
            +
            +
            +
            +function updateTree() {
            +  if(this.quadTree.active)
            +  {
            +    this.quadTree.updateBounds();
            +    this.quadTree.cleanup();
            +  }
            +}
            +
            +//keyboard input
            +p5.prototype.registerMethod('pre', p5.prototype.readPresses);
            +
            +//automatic sprite update
            +p5.prototype.registerMethod('pre', p5.prototype.updateSprites);
            +
            +//quadtree update
            +p5.prototype.registerMethod('post', updateTree);
            +
            +//camera push and pop
            +p5.prototype.registerMethod('pre', cameraPush);
            +p5.prototype.registerMethod('post', cameraPop);
            +
            +//deltaTime
            +//p5.prototype.registerMethod('pre', updateDelta);
            +
            +/**
            + * Log a warning message to the host console, using native `console.warn`
            + * if it is available but falling back on `console.log` if not.  If no
            + * console is available, this method will fail silently.
            + * @method _warn
            + * @param {!string} message
            + * @private
            + */
            +p5.prototype._warn = function(message) {
            +  var console = window.console;
            +
            +  if(console)
            +  {
            +    if('function' === typeof console.warn)
            +    {
            +      console.warn(message);
            +    }
            +    else if('function' === typeof console.log)
            +    {
            +      console.log('Warning: ' + message);
            +    }
            +  }
            +};
            +
            +}));
            diff --git a/dist/assets/p5_featured/kay/scripts/tree.js b/dist/assets/p5_featured/kay/scripts/tree.js
            new file mode 100644
            index 0000000000..9b8f807306
            --- /dev/null
            +++ b/dist/assets/p5_featured/kay/scripts/tree.js
            @@ -0,0 +1,64 @@
            +var twirling, twirlingOver;
            +
            +function Tree() {
            +	var twirling = loadAnimation(loadSpriteSheet("images/tree.png", 186, 179.7, 12));
            +	var twirlingOver = loadAnimation(loadSpriteSheet("images/tree-over.png", 186, 179.7, 12));
            +	var foodImgs = ["bread", "peach", "ray", "tomato"];
            +	
            +	this.load = function(i, vh) {
            +		this.sprite = createSprite(i * 230, 4 * vh / 5);
            +		this.sprite.addAnimation("twirling", twirling);
            +		this.sprite.addAnimation("twirling over", twirlingOver);
            +	}
            +
            +	this.update = function(vw) {
            +		this.sprite.onMouseOver = function() {
            +			this.changeAnimation("twirling over");
            +		}
            +		this.sprite.onMouseOut = function() {
            +			this.changeAnimation("twirling");
            +		}
            +		this.sprite.onMouseReleased = function(){
            +			var foodBox = document.createElement("div");
            +			foodBox.className = "draggable";
            +			foodBox.style.position = "absolute";
            +			foodBox.style.bottom = "20px";
            +			foodBox.style.left = getRandomInt(vw) + "px";
            +
            +			var food = document.createElement("img");
            +			var foodNum = getRandomInt(foodImgs.length);
            +			var foodImg = foodImgs[foodNum];
            +			food.src = "images/" + foodImg + ".png";
            +			food.style.position = "relative";
            +			food.style.transformOrigin = "bottom";
            +			food.style.transform = "rotate(" + getRandomInt(180) +"deg) scale(" + random(0.1,0.3) + ")";
            +			foodBox.appendChild(food);
            +			document.body.appendChild(foodBox);
            +
            +			$(function() {
            +    			$(".draggable").draggable({scroll:false});
            +			});
            +
            +		}
            +
            +		function getRandomInt(cap){
            +			return Math.floor(Math.random() * cap);
            +		}
            +	}
            +
            +	this.move = function(direction, vw) {
            +		if (direction == "right") {
            +			this.sprite.position.x--;
            +			if (this.sprite.position.x < 0) {
            +				this.sprite.position.x = vw;
            +			}
            +		}
            +
            +		if (direction == "left") {
            +			this.sprite.position.x++;
            +			if (this.sprite.position.x > vw) {
            +				this.sprite.position.x = 0;
            +			}
            +		}
            +	}
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/kay/sketch.js b/dist/assets/p5_featured/kay/sketch.js
            new file mode 100644
            index 0000000000..33674cbc78
            --- /dev/null
            +++ b/dist/assets/p5_featured/kay/sketch.js
            @@ -0,0 +1,54 @@
            +var glowing, walkingLeft, walkingRight;
            +var sun, sir;
            +var trees = [];
            +
            +function preload() {
            +	glowing = loadAnimation(loadSpriteSheet("images/sun.png", 255.5, 269.5, 6));
            +	walkingLeft = loadAnimation(loadSpriteSheet("images/sir-left.png", 232.5, 236, 11));
            +	walkingRight = loadAnimation(loadSpriteSheet("images/sir-right.png", 232.5, 236, 11));
            +	for (var i = 0; i < 8; i++) {
            +		trees[i] = new Tree();
            +	}
            +}
            +
            +function setup() {
            +	var cnv = createCanvas(windowWidth, windowHeight);
            +	cnv.style('position', 'absolute');
            +	sun = createSprite(width / 4, 200);
            +	sun.addAnimation("glowing", glowing);
            +	sun.animation.frameDelay = 7;
            +	sun.scale=0.5;
            +	for (var i = 0; i < trees.length; i++) {
            +		trees[i].load(i, windowHeight);
            +		trees[i].sprite.scale = 0.6;
            +	}
            +	sir = createSprite(width / 3, height - 120);
            +	sir.addAnimation("walking left", walkingLeft);
            +	sir.addAnimation("walking right", walkingRight);
            +	sir.animation.frameDelay = 5;
            +	sir.scale=0.8;
            +}
            +
            +function draw() {
            +	background(255);
            +	drawSprites();
            +	trees.forEach(function(tree){
            +		tree.update(windowWidth);
            +	});
            +	if (mouseX > width / 2) {
            +		sir.changeAnimation("walking right");
            +		sir.rotation = 10;
            +		trees.forEach(function(tree){
            +			tree.move("right", windowWidth);
            +		});
            +	} else {
            +		sir.changeAnimation("walking left");
            +		sir.rotation = -10;
            +		trees.forEach(function(tree){
            +			tree.move("left", windowWidth);
            +		});
            +	}
            +}
            +function windowResized(){
            +	resizeCanvas(windowWidth, windowHeight);
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/kevin_3d/index.html b/dist/assets/p5_featured/kevin_3d/index.html
            new file mode 100644
            index 0000000000..3e03d1e9fe
            --- /dev/null
            +++ b/dist/assets/p5_featured/kevin_3d/index.html
            @@ -0,0 +1,10 @@
            +<!DOCTYPE html>
            +  <head>
            +    <script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.13/p5.min.js'></script>
            +    <script src='sketch.js'></script>
            +    <!-- <style>body{margin: 0; padding: 0}</style> -->
            +  </head>
            +  <body>
            +  </body>
            +</html>
            +
            diff --git a/dist/assets/p5_featured/kevin_3d/sketch.js b/dist/assets/p5_featured/kevin_3d/sketch.js
            new file mode 100644
            index 0000000000..9307f26d74
            --- /dev/null
            +++ b/dist/assets/p5_featured/kevin_3d/sketch.js
            @@ -0,0 +1,106 @@
            +var x = 0;
            +var boxWidth = 50;
            +var boxSpacing = 850;
            +var period = 400;
            +var pos;
            +var bricks = [];
            +var brickRows = 10, brickCols = 10;
            +var radialDistance = 350;
            +var targetzs = [];
            +var zs = [];
            +
            +function Brick(){
            +  var position = null;
            +  Object.defineProperty(this, 'position', {
            +    get : function(){
            +      return position;
            +    },
            +    set : function(value){
            +      position = value;
            +    }
            +  });
            +}
            +
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight, WEBGL);
            +  colorMode(HSB);
            +
            +  for (var i = 0; i < (brickRows * brickCols); i++) {
            +    bricks.push(new Brick());
            +  }
            +  for (var i=0; i<brickRows*brickCols; i++) {
            +    zs[i] = 0;
            +    targetzs[i] = 0;
            +  }
            +
            +}
            +
            +function draw() {
            +  background(0,0,0);
            +  translate(-width/2,-height/2,0);
            +  var brickIter = 0;
            +
            +  push();
            +    translate(width/2,height/2,-2000.0);
            +    var dirX = (mouseX / width - 0.5) *2;
            +    var dirY = (mouseY / height - 0.5) *(-2);
            +  
            +    basicMaterial(45, 40, 255, 10);
            +    sphere(width);
            +    pointLight(45, 40, 255, 0, 0, -400);
            +  pop();
            +
            +
            +  pointLight(255, 100,255, 0, 0, 1.0);
            +  pointLight(0,0,255, 0,0,2.5);
            +  
            +  var theta = asin(random(-width, width) / width);
            +  for (var i = 0; i < brickRows; i++) {
            +    for (var j = 0; j < brickCols; j++) {
            +      var _x = width * cos(theta) * cos(random(TWO_PI));
            +      var _y = width * cos(theta) * sin(random(TWO_PI));
            +      var _z = width * sin(theta);
            +
            +      push();
            +      
            +      pos = createVector((i*(width / 10)),
            +        (j * (width / 10)),
            +        map(cos(TWO_PI * frameCount / period), -1,1, 0,-100) );
            +      var distFromMouse = p5.Vector.dist(pos, createVector(mouseX, mouseY, 100));
            +      distFromMouse /= radialDistance;
            +      if (distFromMouse < 1.0){
            +          pos.z -= (distFromMouse * radialDistance * 0.75);
            +      }
            +      var ind = i*brickCols+j;
            +      targetzs[ind] = pos.z;
            +      zs[ind] += (targetzs[ind] - zs[ind])*0.08;
            +
            +      translate( pos.x,
            +        pos.y, //0);
            +        zs[ind]);
            +      
            +      var rotAngle = gaze(mouseY, mouseX, createVector(pos.x, pos.y, zs[ind]));
            +      
            +      //rotateX(rotAngle.x);
            +      //rotateY(rotAngle.y);
            +      //rotate(radians(gaze(mouseX, mouseY, pos)), [1,1,1]);
            +      // ambientMaterial(255,0,255);
            +      specularMaterial(0,0,255);
            +      box(boxWidth, boxWidth,  400);
            +      pop();
            +
            +      brickIter++;
            +    }
            +  }
            +}
            +
            +function gaze(targetX, targetY, pos){
            +  var desired = p5.Vector.sub(createVector(targetX, targetY, 1000), pos);
            +  desired.normalize();
            +  var pitch = atan2(desired.x,desired.z);
            +  var yaw = atan2(desired.y, sqrt(desired.x*desired.x + desired.z*desired.z));
            +  var azimuth = atan2(-desired.x, -desired.z);
            +  var gazeAngle = createVector(pitch, yaw, azimuth);
            +  return gazeAngle;
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/kylemcdonald_magnify/index.html b/dist/assets/p5_featured/kylemcdonald_magnify/index.html
            new file mode 100644
            index 0000000000..f665529ce7
            --- /dev/null
            +++ b/dist/assets/p5_featured/kylemcdonald_magnify/index.html
            @@ -0,0 +1,11 @@
            +<!DOCTYPE html>
            +<head>
            +<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.js"></script>
            +<script src="sketch.js"></script>
            +
            +<style>body{padding:0; margin:0;}</style>
            +</head>
            +<body>
            +<div class="boop"></div>
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/kylemcdonald_magnify/sketch.js b/dist/assets/p5_featured/kylemcdonald_magnify/sketch.js
            new file mode 100644
            index 0000000000..ebf1efd93b
            --- /dev/null
            +++ b/dist/assets/p5_featured/kylemcdonald_magnify/sketch.js
            @@ -0,0 +1,47 @@
            +var speed = .0001;
            +var n = 30; 
            +var grid = [];
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  var spacing = min(width, height) / n;
            +  for(var y = 0; y < height; y += spacing) {
            +    for(var x = 0; x < width; x += spacing) {
            +      grid.push(createVector(x, y));
            +    }
            +  }
            +}
            +
            +function draw() {
            +  var a = map(cos(millis() * speed * 10), -1, 1, 0, 255);
            +  background(255, a);
            +  
            +  var control = [];
            +  for(var i = 0; i < 8; i++) {
            +    var x = width * noise(i*2 + 0, millis() * speed);
            +    var y = height * noise(i*2 + 1, millis() * speed);
            +    var v = createVector(x, y);
            +    control.push(v);
            +    // ellipse(v.x, v.y, 10, 10); // draw centers
            +  }
            +  
            +  noStroke();
            +  fill(112,128,132, 150);
            +  
            +  var range = min(width, height) / 3;
            +  var zoom = range / 4;
            +  
            +  grid.forEach(function (v) {
            +    var vv = v.copy();
            +    control.forEach(function (c) {
            +      var difference = p5.Vector.sub(v, c);
            +      var length = difference.mag();
            +      difference.div(length);
            +      if(length < range) {
            +        var amt = map(cos(map(length, 0, range, 0, TWO_PI)), 1, -1, 0, zoom);
            +        vv.add(difference.mult(amt));
            +      }
            +    })
            +    ellipse(vv.x, vv.y, 2, 2);
            +  });
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/love1/index.html b/dist/assets/p5_featured/love1/index.html
            new file mode 100644
            index 0000000000..26928c2a5d
            --- /dev/null
            +++ b/dist/assets/p5_featured/love1/index.html
            @@ -0,0 +1,11 @@
            +<!DOCTYPE html>
            +<head>
            +<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.6/p5.min.js"></script>
            +<script src="sketch.js"></script>
            +
            +<style>body{padding:0; margin:0;}</style>
            +</head>
            +<body>
            +<div class="boop"></div>
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/love1/sketch.js b/dist/assets/p5_featured/love1/sketch.js
            new file mode 100644
            index 0000000000..e42d50741d
            --- /dev/null
            +++ b/dist/assets/p5_featured/love1/sketch.js
            @@ -0,0 +1,128 @@
            +var numBalls = 24;
            +var spring = 0.05;
            +var gravity = -0.00005;
            +var friction = -0.5;
            +var balls = [];
            +var colors;
            +var partners = {
            +  0: 13,
            +  1: 15,
            +  2: 17,
            +  3: 19,
            +  4: 21,
            +  5: 23,
            +  6: 14,
            +  7: 18,
            +  8: 22,
            +  9: 16,
            +  10: 20,
            +  11: 12
            +}
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  var a = 255;  // change this to lighten
            +  colors = [
            +    color(228, 3, 3, a),
            +    color(255, 140, 0, a),
            +    color(255, 237, 0, a),
            +    color(0, 128, 38, a),
            +    color(0, 77, 255, a),
            +    color(117, 7, 135, a)
            +  ];
            +  for (var i = 0; i < numBalls; i++) {
            +    balls[i] = new Ball(width/2, (i%6)*height*0.133+height*0.15, 60, i, balls);
            +  }
            +  for (var i = 0; i < numBalls/2; i++) {
            +    balls[i].p = partners[i];
            +    balls[partners[i]].p = i;
            +    console.log('partners '+partners[i]+" "+i)
            +  }
            +  noStroke();
            +  noFill();
            +  fill(255, 204);
            +}
            +
            +function draw() {
            +  background(255, 100);
            +  for (var i = 0; i < balls.length; i++) {
            +    var ball = balls[i];
            +    ball.collide();
            +    ball.move();
            +    ball.display();  
            +  }
            +}
            +
            + 
            +function Ball(xin, yin, din, idin, oin) {
            +  this.x = xin;
            +  this.y = yin;
            +  this.diameter = din;
            +  this.id = idin;
            +  this.others = oin;
            +  this.vx = 0;
            +  this.vy = 0;
            +  this.collided = false;
            +
            +  this.collide = function() {
            +    for (var i = this.id + 1; i < numBalls; i++) {
            +      if (this.others[i].id !== this.p) {
            +        var dx = this.others[i].x - this.x;
            +        var dy = this.others[i].y - this.y;
            +        var distance = sqrt(dx*dx + dy*dy);
            +        var minDist = this.others[i].diameter/2 + this.diameter/2;
            +        if (distance < minDist) {
            +          var angle = atan2(dy, dx);
            +          var targetX = this.x + cos(angle) * minDist;
            +          var targetY = this.y + sin(angle) * minDist;
            +          var ax = (targetX - this.others[i].x) * spring;
            +          var ay = (targetY - this.others[i].y) * spring + random(-0.01, 0.01);
            +          this.vx -= ax;
            +          this.vy -= ay;
            +          this.others[i].vx += ax;
            +          this.others[i].vy += ay;
            +        }
            +      }
            +    }   
            +  }
            +  
            +  this.move = function() {
            +    this.vy += gravity;
            +    this.x += this.vx;
            +    this.y += this.vy;
            +    if (this.x + this.diameter/2 > width) {
            +      this.x = width - this.diameter/2;
            +      this.vx *= friction; 
            +    }
            +    else if (this.x - this.diameter/2 < 0) {
            +      this.x = this.diameter/2;
            +      this.vx *= friction;
            +    }
            +    if (this.y + this.diameter/2 > height) {
            +      this.y = height - this.diameter/2;
            +      this.vy *= friction; 
            +    } 
            +    else if (this.y - this.diameter/2 < 0) {
            +      this.y = this.diameter/2;
            +      this.vy *= friction;
            +    }
            +    this.vx += (balls[this.p].x - this.x) * 0.0001;
            +    this.vy += (balls[this.p].y - this.y) * 0.0001;
            +  }
            +   
            +  this.display = function() {
            +    push();  
            +    fill(colors[this.id%6]);
            +    stroke(colors[this.id%6]);
            +    //ellipse(this.x, this.y, this.diameter, this.diameter);
            +    translate(this.x-50, this.y-this.diameter/2);
            +    scale(1.5)
            +    beginShape();
            +    vertex(50, 15); 
            +    bezierVertex(50, -5, 90, 5, 50, 40); 
            +    vertex(50, 15); 
            +    bezierVertex(50, -5, 10, 5, 50, 40); 
            +    endShape();
            +    pop(); 
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/march/index.html b/dist/assets/p5_featured/march/index.html
            new file mode 100644
            index 0000000000..2d77bf32c2
            --- /dev/null
            +++ b/dist/assets/p5_featured/march/index.html
            @@ -0,0 +1,27 @@
            +
            +<!DOCTYPE html>
            +<head>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.6/p5.min.js"></script>
            +  <script src="sketch.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +<meta name="viewport" content="user-scalable=yes,initial-scale=.3,maximum-scale=.3,minimum-scale=.3,width=device-width">
            +<link href="https://fonts.googleapis.com/css?family=Open+Sans:800" rel="stylesheet">
            +
            +<style>
            +
            +canvas {
            +
            +  position: absolute;
            +  top: 0;
            +  left: 0;
            +  z-index: -1;
            +}
            +</style>
            +
            +</head>
            +
            +<!DOCTYPE html>
            +
            +<body>
            +</body>
            +</html>
            diff --git a/dist/assets/p5_featured/march/sketch.js b/dist/assets/p5_featured/march/sketch.js
            new file mode 100644
            index 0000000000..5f95271d34
            --- /dev/null
            +++ b/dist/assets/p5_featured/march/sketch.js
            @@ -0,0 +1,64 @@
            +var texts = ['UNITE WITH LOVE, RESIST WITH LOVE',
            +  'TOGETHER, WE RISE',
            +  'WOMEN\'S RIGHTS ARE HUMAN RIGHTS',
            +  'EXPECT US',
            +  'LOVE',
            +  'RESPECT',
            +  'RISE UP',
            +  'EQUALITY',
            +  'HUMAN RIGHTS FOR ALL',
            +  'SOLIDARITY',
            +  'WE ARE ALL EQUAL',
            +  'LOVE WINS',
            +  'TOGETHER',
            +  'STAY WOKE',
            +  'I LOVE YOU',
            +  'NASTY ARTIST CODER WOMEN',
            +  'WE ARE THE FUTURE',
            +  'STAND TOGETHER',
            +  'CELEBRATE DIFFERENCES',
            +  'INDIVISIBLE',
            +  'WE GO HIGH',
            +  'HOPE NOT FEAR',
            +  'REACH OUT',
            +  'LET\'S LISTEN TO EACH OTHER'];
            +
            +var i;
            +var dir = 0;
            +var a = 0;
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  textAlign(CENTER);
            +  textFont('Open Sans');
            +  noStroke();
            +  setInterval(startFadeOut, 10000);
            +}
            +
            +function draw() {
            +  a += dir;
            +  if (a <= 0) {
            +    dir = 3;
            +    switchText();
            +  } if (a >= 255) {
            +    dir = 0;
            +  }
            +  background(255);
            +  fill(220, a);
            +  textSize(1);
            +  var w = textWidth(texts[i]);
            +  var s = 0.9*windowWidth/w;
            +  textSize(s);
            +  text(texts[i], width/2, height/2+s*0.33);
            +}
            +
            +function switchText() {
            +  var lasti = i;
            +  while (i == lasti) {
            +    i = Math.floor(Math.random()*texts.length);
            +  }
            +}
            +
            +function startFadeOut() {
            +  dir = -3;
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/matthew_kaney_teatime/crockery_pot.obj b/dist/assets/p5_featured/matthew_kaney_teatime/crockery_pot.obj
            new file mode 100644
            index 0000000000..a02c0ffa17
            --- /dev/null
            +++ b/dist/assets/p5_featured/matthew_kaney_teatime/crockery_pot.obj
            @@ -0,0 +1,12297 @@
            +# This file uses centimeters as units for non-parametric coordinates.
            +
            +v -0.449913 0.429545 0.064337
            +v -0.449783 0.440337 0.084763
            +v -0.453041 0.440436 0.087901
            +v -0.448283 0.429493 0.062043
            +v -0.446820 0.429449 0.055575
            +v -0.445579 0.429412 0.045535
            +v -0.444620 0.429382 0.032540
            +v -0.444874 0.426010 -0.011900
            +v -0.444620 0.429382 -0.032306
            +v -0.440300 0.450843 -0.052282
            +v -0.445579 0.429412 -0.045301
            +v -0.446820 0.429449 -0.055341
            +v -0.446857 0.440246 -0.075685
            +v -0.448283 0.429493 -0.061811
            +v -0.449913 0.429545 -0.064106
            +v -0.449783 0.440337 -0.084531
            +v -0.450834 0.429572 -0.063385
            +v -0.451709 0.429599 -0.061301
            +v -0.452536 0.429624 -0.057951
            +v -0.458286 0.440596 -0.079254
            +v -0.453986 0.429668 -0.047876
            +v -0.453295 0.429646 -0.053441
            +v -0.454593 0.429688 -0.041361
            +v -0.455654 0.429717 -0.022357
            +v -0.455368 0.429710 -0.029153
            +v -0.464946 0.440798 -0.020793
            +v -0.455997 0.429730 -0.007669
            +v -0.465208 0.440806 -0.010528
            +v -0.465297 0.440811 0.000116
            +v -0.455821 0.429727 0.017196
            +v -0.464857 0.440796 0.023460
            +v -0.447402 0.419468 0.001665
            +v -0.472046 0.451810 0.052511
            +v -0.454245 0.429675 0.045535
            +v -0.453007 0.429636 0.055575
            +v -0.459228 0.440623 0.075919
            +v -0.451541 0.429594 0.062043
            +v -0.456172 0.451327 0.103905
            +v -0.446894 0.451043 0.089741
            +v -0.441973 0.461690 0.081832
            +v -0.438142 0.461572 0.058452
            +v -0.441973 0.461690 -0.081600
            +v -0.458935 0.451411 -0.102512
            +v -0.462398 0.440722 -0.056579
            +v -0.455012 0.429700 -0.035505
            +v -0.476639 0.462748 0.081832
            +v -0.452787 0.462021 0.111540
            +v -0.423785 0.507354 0.037165
            +v -0.446970 0.472640 -0.107295
            +v -0.454290 0.472862 -0.119829
            +v -0.459305 0.462218 -0.115431
            +v -0.469794 0.462539 -0.104362
            +v -0.478023 0.462788 -0.074513
            +v -0.497311 0.484972 0.066247
            +v -0.477902 0.473583 0.107524
            +v -0.470583 0.473361 0.120056
            +v -0.459305 0.462218 0.115665
            +v -0.446970 0.472640 0.107524
            +v -0.438448 0.450784 -0.027488
            +v -0.439572 0.483208 -0.092526
            +v -0.471089 0.484170 -0.129413
            +v -0.476353 0.484333 -0.125160
            +v -0.491566 0.484794 0.092758
            +v -0.455792 0.483704 0.126433
            +v -0.430124 0.501389 0.069533
            +v -0.431358 0.495271 -0.068312
            +v -0.447010 0.483435 -0.113003
            +v -0.455792 0.483704 -0.126201
            +v -0.465568 0.484003 -0.130880
            +v -0.481299 0.484481 -0.118329
            +v -0.490002 0.484747 -0.097783
            +v -0.530377 0.522922 -0.049788
            +v -0.532360 0.522983 -0.033850
            +v -0.531945 0.522969 0.038036
            +v -0.484126 0.484570 0.113233
            +v -0.475344 0.484299 0.126433
            +v -0.447049 0.495750 0.117160
            +v -0.438196 0.495481 0.095972
            +v -0.517105 0.522517 0.100958
            +v -0.460930 0.520800 0.137617
            +v -0.465568 0.484003 0.131110
            +v -0.493216 0.521787 -0.136251
            +v -0.500982 0.522026 -0.128816
            +v -0.508158 0.522243 -0.118803
            +v -0.514651 0.522441 -0.106449
            +v -0.534005 0.523033 0.000116
            +v -0.526129 0.522791 0.072103
            +v -0.505425 0.522159 0.123248
            +v -0.427663 0.513627 -0.071077
            +v -0.436139 0.513886 -0.099613
            +v -0.447116 0.514224 -0.121657
            +v -0.460930 0.520800 -0.137385
            +v -0.476281 0.521269 -0.142477
            +v -0.484950 0.521535 -0.140883
            +v -0.491632 0.521740 0.137617
            +v -0.447141 0.520378 0.123248
            +v -0.435455 0.520021 0.100958
            +v -0.520364 0.522616 -0.091981
            +v -0.476281 0.521269 0.142709
            +v -0.422196 0.513462 -0.037387
            +v -0.462048 0.571003 0.146698
            +v -0.482848 0.571639 0.152125
            +v -0.443359 0.570435 0.131381
            +v -0.427532 0.569949 0.107618
            +v -0.415304 0.569577 0.076854
            +v -0.407422 0.569335 0.040540
            +v -0.415304 0.569577 -0.076627
            +v -0.407422 0.569335 -0.040313
            +v -0.427532 0.569949 -0.107391
            +v -0.443359 0.570435 -0.131149
            +v -0.462048 0.571003 -0.146471
            +v -0.482848 0.571639 -0.151895
            +v -0.494595 0.571999 -0.150196
            +v -0.505795 0.572342 -0.145257
            +v -0.516318 0.572663 -0.137331
            +v -0.526042 0.572959 -0.126660
            +v -0.534839 0.573228 -0.113489
            +v -0.542580 0.573465 -0.098064
            +v -0.552499 0.573768 -0.069163
            +v -0.558836 0.573961 -0.036092
            +v -0.561064 0.574030 0.000116
            +v -0.558274 0.573943 0.040540
            +v -0.550392 0.573704 0.076857
            +v -0.538164 0.573329 0.107618
            +v -0.522335 0.572846 0.131381
            +v -0.503648 0.572276 0.146698
            +v -0.460400 0.621121 0.151029
            +v -0.485648 0.621894 0.156617
            +v -0.437717 0.620431 0.135259
            +v -0.418506 0.619841 0.110795
            +v -0.403663 0.619390 0.079126
            +v -0.403663 0.619390 -0.078894
            +v -0.418506 0.619841 -0.110566
            +v -0.437717 0.620431 -0.135030
            +v -0.460400 0.621121 -0.150798
            +v -0.485648 0.621894 -0.156387
            +v -0.499906 0.622330 -0.154636
            +v -0.513501 0.622745 -0.149552
            +v -0.526274 0.623137 -0.141391
            +v -0.538078 0.623497 -0.130402
            +v -0.548752 0.623823 -0.116844
            +v -0.558151 0.624109 -0.100967
            +v -0.564673 0.624309 -0.086689
            +v -0.570189 0.624479 -0.071210
            +v -0.574619 0.624612 -0.054655
            +v -0.577880 0.624713 -0.037163
            +v -0.579898 0.624772 -0.018864
            +v -0.580586 0.624795 0.000116
            +v -0.577197 0.624691 0.041734
            +v -0.567631 0.624400 0.079126
            +v -0.552790 0.623948 0.110795
            +v -0.533578 0.623359 0.135259
            +v -0.510896 0.622666 0.151029
            +v -0.456362 0.671169 0.151446
            +v -0.485189 0.672049 0.157048
            +v -0.430462 0.670379 0.135634
            +v -0.408525 0.669708 0.111099
            +v -0.391580 0.669193 0.079343
            +v -0.408525 0.669708 -0.110872
            +v -0.391580 0.669193 -0.079114
            +v -0.430462 0.670379 -0.135402
            +v -0.456362 0.671169 -0.151214
            +v -0.485189 0.672049 -0.156817
            +v -0.501470 0.672547 -0.155063
            +v -0.516992 0.673021 -0.149966
            +v -0.531578 0.673468 -0.141784
            +v -0.545054 0.673877 -0.130764
            +v -0.557245 0.674252 -0.117167
            +v -0.567974 0.674578 -0.101246
            +v -0.575421 0.674807 -0.086931
            +v -0.581719 0.675000 -0.071405
            +v -0.586778 0.675155 -0.054808
            +v -0.590503 0.675266 -0.037269
            +v -0.592805 0.675338 -0.018913
            +v -0.593594 0.675362 0.000116
            +v -0.589724 0.675244 0.041850
            +v -0.578800 0.674908 0.079343
            +v -0.561853 0.674393 0.111104
            +v -0.539918 0.673722 0.135634
            +v -0.514019 0.672932 0.151446
            +v -0.450478 0.721159 0.148390
            +v -0.482219 0.722131 0.153876
            +v -0.421964 0.720286 0.132893
            +v -0.397811 0.719551 0.108859
            +v -0.379155 0.718978 0.077742
            +v -0.397811 0.719551 -0.108629
            +v -0.379155 0.718978 -0.077515
            +v -0.421964 0.720286 -0.132666
            +v -0.450478 0.721159 -0.148160
            +v -0.482219 0.722131 -0.153649
            +v -0.500146 0.722674 -0.151930
            +v -0.517233 0.723199 -0.146934
            +v -0.533292 0.723690 -0.138917
            +v -0.548130 0.724144 -0.128122
            +v -0.561552 0.724553 -0.114799
            +v -0.573364 0.724913 -0.099199
            +v -0.581566 0.725165 -0.085172
            +v -0.588500 0.725375 -0.069962
            +v -0.594068 0.725545 -0.053698
            +v -0.598170 0.725671 -0.036512
            +v -0.600703 0.725747 -0.018533
            +v -0.601572 0.725774 0.000113
            +v -0.597312 0.725646 0.041006
            +v -0.585283 0.725279 0.077742
            +v -0.566627 0.724706 0.108859
            +v -0.542474 0.723971 0.132893
            +v -0.513960 0.723100 0.148390
            +v -0.443334 0.771110 0.142139
            +v -0.477530 0.772156 0.147398
            +v -0.412612 0.770172 0.127298
            +v -0.386592 0.769376 0.104278
            +v -0.366492 0.768764 0.074471
            +v -0.386592 0.769376 -0.104046
            +v -0.366492 0.768764 -0.074239
            +v -0.412612 0.770172 -0.127067
            +v -0.443334 0.771110 -0.141907
            +v -0.477530 0.772156 -0.147166
            +v -0.496842 0.772745 -0.145518
            +v -0.515252 0.773308 -0.140735
            +v -0.532555 0.773836 -0.133056
            +v -0.548540 0.774324 -0.122715
            +v -0.562998 0.774766 -0.109954
            +v -0.575727 0.775155 -0.095013
            +v -0.584561 0.775427 -0.081576
            +v -0.592033 0.775654 -0.067007
            +v -0.598032 0.775836 -0.051431
            +v -0.602450 0.775970 -0.034967
            +v -0.605181 0.776056 -0.017744
            +v -0.606113 0.776085 0.000116
            +v -0.601525 0.775942 0.039284
            +v -0.588569 0.775548 0.074471
            +v -0.568469 0.774933 0.104278
            +v -0.542447 0.774139 0.127298
            +v -0.511725 0.773199 0.142139
            +v -0.441590 0.821226 0.132888
            +v -0.410064 0.820264 0.119017
            +v -0.383358 0.819450 0.097492
            +v -0.362731 0.818816 0.069626
            +v -0.349434 0.818411 0.036734
            +v -0.383358 0.819450 -0.097262
            +v -0.362731 0.818816 -0.069399
            +v -0.410064 0.820264 -0.118785
            +v -0.441590 0.821226 -0.132661
            +v -0.476686 0.822299 -0.137575
            +v -0.505323 0.850806 -0.129561
            +v -0.518918 0.834100 -0.129284
            +v -0.535725 0.834614 -0.122227
            +v -0.551248 0.835090 -0.112729
            +v -0.564402 0.824978 -0.102786
            +v -0.577646 0.829100 -0.088283
            +v -0.586527 0.825657 -0.076255
            +v -0.594196 0.825888 -0.062638
            +v -0.600351 0.826076 -0.048074
            +v -0.604887 0.826216 -0.032683
            +v -0.607690 0.826300 -0.016582
            +v -0.608649 0.826330 0.000116
            +v -0.603937 0.826187 0.036734
            +v -0.590641 0.825780 0.069626
            +v -0.570606 0.835679 0.095807
            +v -0.543308 0.824332 0.119017
            +v -0.511779 0.823372 0.132888
            +v -0.349434 0.818411 -0.036502
            +v -0.350996 0.819388 -0.036450
            +v -0.352370 0.820358 -0.036393
            +v -0.361847 0.829302 0.036097
            +v -0.393956 0.830284 -0.095575
            +v -0.419228 0.831056 -0.116726
            +v -0.449065 0.831967 0.130589
            +v -0.374433 0.829685 0.068425
            +v -0.419228 0.831056 0.116958
            +v -0.393956 0.830284 0.095807
            +v -0.374433 0.829685 -0.068193
            +v -0.449065 0.831967 -0.130362
            +v -0.565529 0.852646 -0.097891
            +v -0.361847 0.829302 -0.035870
            +v -0.518869 0.851223 0.126576
            +v -0.476683 0.822299 0.137805
            +v -0.357387 0.829167 0.000116
            +v -0.585150 0.853248 -0.072624
            +v -0.591949 0.853453 -0.059655
            +v -0.435877 0.865807 0.109476
            +v -0.404995 0.847740 0.092861
            +v -0.386706 0.847182 0.066321
            +v -0.374914 0.846824 0.034992
            +v -0.370738 0.846696 0.000116
            +v -0.374914 0.846824 -0.034763
            +v -0.386706 0.847182 -0.066094
            +v -0.404995 0.847740 -0.092632
            +v -0.576213 0.870094 -0.081682
            +v -0.587259 0.870432 0.064051
            +v -0.569967 0.869904 0.089679
            +v -0.546825 0.852076 0.113361
            +v -0.487750 0.850271 0.131258
            +v -0.385046 0.864255 0.033793
            +v -0.381096 0.864134 0.000116
            +v -0.385046 0.864255 -0.033566
            +v -0.396193 0.864595 -0.063819
            +v -0.413488 0.865123 -0.089450
            +v -0.435877 0.865807 -0.109246
            +v -0.497311 0.901928 -0.116541
            +v -0.512364 0.902390 -0.115236
            +v -0.526716 0.902826 -0.111447
            +v -0.540202 0.903238 -0.105363
            +v -0.552664 0.903621 -0.097173
            +v -0.591241 0.904800 -0.040710
            +v -0.591712 0.921934 0.029681
            +v -0.522791 0.885583 0.117579
            +v -0.466885 0.883876 0.117579
            +v -0.420504 0.882460 0.086263
            +v -0.404075 0.881957 0.061612
            +v -0.393482 0.881634 0.032510
            +v -0.547913 0.903475 0.100849
            +v -0.494839 0.884732 0.121926
            +v -0.456120 0.944992 0.088123
            +v -0.397079 0.898867 0.000116
            +v -0.400658 0.898976 -0.030907
            +v -0.410757 0.899284 -0.058780
            +v -0.426424 0.899763 -0.082385
            +v -0.456120 0.944992 -0.087896
            +v -0.477581 0.945648 -0.098165
            +v -0.563935 0.903964 -0.087067
            +v -0.573854 0.904267 -0.075231
            +v -0.580742 0.904477 -0.064589
            +v -0.592728 0.939089 0.000116
            +v -0.582052 0.921641 0.056241
            +v -0.567066 0.921182 0.078739
            +v -0.477581 0.945648 0.098392
            +v -0.431464 0.917038 0.078739
            +v -0.421367 0.933852 0.053311
            +v -0.412102 0.933571 0.028137
            +v -0.583579 0.999282 -0.010336
            +v -0.525403 0.957188 0.095161
            +v -0.414186 0.953789 0.000116
            +v -0.417322 0.953885 -0.026097
            +v -0.423896 0.944008 -0.051340
            +v -0.435739 0.934293 -0.074407
            +v -0.501473 0.946378 -0.101804
            +v -0.515233 0.956877 -0.097346
            +v -0.527814 0.957262 -0.094144
            +v -0.539635 0.957622 -0.089003
            +v -0.550555 0.957958 -0.082084
            +v -0.565006 0.998712 -0.055553
            +v -0.570578 0.998882 -0.047691
            +v -0.579069 0.999141 -0.030048
            +v -0.581854 0.999225 -0.020416
            +v -0.439908 0.954576 0.069821
            +v -0.426175 0.954156 0.049874
            +v -0.421569 0.974172 0.024626
            +v -0.443228 0.974833 -0.065068
            +v -0.544733 0.988014 0.077081
            +v -0.480406 0.975973 0.088993
            +v -0.462166 0.995570 0.074543
            +v -0.460277 0.975356 -0.079474
            +v -0.480406 0.975973 -0.088762
            +v -0.502040 0.956475 0.098676
            +v -0.433085 0.994684 0.043628
            +v -0.422021 0.994343 0.000116
            +v -0.424917 0.994432 -0.022806
            +v -0.581272 0.999208 0.023035
            +v -0.573105 0.998959 0.043628
            +v -0.560430 0.998574 0.061069
            +v -0.445759 0.995071 0.061069
            +v -0.433085 0.994684 -0.043397
            +v -0.503093 0.996820 -0.086075
            +v -0.584168 0.999299 0.000116
            +v -0.522695 1.030993 0.074488
            +v -0.424917 0.994432 0.023035
            +v -0.447284 1.011905 -0.057536
            +v -0.513903 1.030724 -0.076149
            +v -0.524777 1.031057 -0.073647
            +v -0.552975 1.031918 -0.057527
            +v -0.482305 1.029760 0.074488
            +v -0.464164 1.029205 -0.066489
            +v -0.482305 1.029760 -0.074259
            +v -0.534994 1.031368 -0.069624
            +v -0.544435 1.031657 -0.064209
            +v -0.540836 1.031546 0.066716
            +v -0.466059 1.062838 0.059875
            +v -0.501700 1.063925 -0.069089
            +v -0.561740 1.082545 -0.029814
            +v -0.483218 1.080147 0.063442
            +v -0.435648 1.095479 0.000116
            +v -0.454768 1.096066 -0.044031
            +v -0.466059 1.062838 -0.059646
            +v -0.482925 1.063351 -0.066619
            +v -0.562164 1.099349 -0.021730
            +v -0.502499 1.030374 0.077244
            +v -0.454768 1.096066 0.044257
            +v -0.444560 1.095752 0.031627
            +v -0.437979 1.095550 0.016713
            +v -0.437979 1.095550 -0.016486
            +v -0.444560 1.095752 -0.031395
            +v -0.510768 1.097778 -0.061604
            +v -0.520119 1.098061 -0.059579
            +v -0.528906 1.098330 -0.056323
            +v -0.537027 1.098580 -0.051942
            +v -0.550834 1.099001 -0.040200
            +v -0.566271 1.099472 0.000116
            +v -0.547149 1.098888 0.044257
            +v -0.561392 1.118896 0.015803
            +v -0.555161 1.118706 0.029898
            +v -0.533931 1.098481 0.054016
            +v -0.518329 1.098007 0.060307
            +v -0.472936 1.135767 0.048431
            +v -0.502790 1.136677 -0.055839
            +v -0.487066 1.136199 0.054071
            +v -0.500960 1.097474 0.062534
            +v -0.460972 1.135402 0.039689
            +v -0.451729 1.135121 -0.028137
            +v -0.470536 1.116119 -0.050824
            +v -0.487066 1.136199 -0.053841
            +v -0.556826 1.118758 -0.026770
            +v -0.560235 1.138434 -0.013212
            +v -0.545493 1.118410 0.041833
            +v -0.452390 1.174287 -0.013469
            +v -0.466535 1.174721 -0.036008
            +v -0.528349 1.157036 -0.048088
            +v -0.542096 1.137881 -0.041702
            +v -0.552008 1.138185 -0.030919
            +v -0.560988 1.158033 0.000116
            +v -0.532641 1.137592 0.048431
            +v -0.457936 1.174459 0.025902
            +v -0.452390 1.174287 0.013698
            +v -0.450426 1.174230 0.000116
            +v -0.481738 1.194761 -0.042417
            +v -0.558950 1.157971 0.014293
            +v -0.553202 1.157796 0.027029
            +v -0.544368 1.177099 0.036238
            +v -0.520085 1.176356 0.049369
            +v -0.481738 1.194761 0.042649
            +v -0.471185 1.194436 0.034948
            +v -0.457936 1.174459 -0.025672
            +v -0.508062 1.195561 -0.049139
            +v -0.512504 1.156550 -0.052600
            +v -0.528998 1.176628 -0.046068
            +v -0.542027 1.177027 -0.038056
            +v -0.554453 1.177407 -0.023164
            +v -0.534385 1.196367 0.042649
            +v -0.506697 1.240005 0.045175
            +v -0.505452 1.175907 0.051192
            +v -0.463034 1.194189 0.024979
            +v -0.457780 1.194029 0.013215
            +v -0.471185 1.194436 -0.034721
            +v -0.505042 1.235804 -0.045076
            +v -0.560062 1.216726 0.000116
            +v -0.558543 1.224985 0.012721
            +v -0.553459 1.216526 0.024276
            +v -0.545895 1.216292 0.033961
            +v -0.485253 1.235198 0.033260
            +v -0.463279 1.213771 0.000116
            +v -0.465005 1.213823 -0.012613
            +v -0.469882 1.213971 -0.024047
            +v -0.516969 1.236170 -0.046751
            +v -0.525867 1.215683 -0.045654
            +v -0.541731 1.236924 -0.038969
            +v -0.548626 1.216376 -0.030798
            +v -0.558683 1.216684 -0.011286
            +v -0.505037 1.280040 -0.032831
            +v -0.494329 1.235476 -0.040355
            +v -0.530414 1.240733 0.045175
            +v -0.497439 1.279805 0.023635
            +v -0.496322 1.287820 0.012571
            +v -0.563141 1.241730 0.000116
            +v -0.527814 1.245990 -0.045950
            +v -0.555694 1.237354 0.023773
            +v -0.552751 1.246752 0.033060
            +v -0.543690 1.246476 0.040345
            +v -0.561547 1.241683 0.012544
            +v -0.497439 1.279805 -0.023403
            +v -0.508772 1.266763 0.040167
            +v -0.545814 1.246540 -0.038737
            +v -0.555279 1.246829 -0.029974
            +v -0.558257 1.241582 -0.021183
            +v -0.561871 1.241695 -0.011014
            +v -0.570588 1.263315 0.023529
            +v -0.518553 1.240371 0.046845
            +v -0.509103 1.288212 0.033238
            +v -0.576997 1.263510 0.000116
            +v -0.552341 1.281483 0.045037
            +v -0.565899 1.263171 -0.029839
            +v -0.575322 1.263458 0.012448
            +v -0.531045 1.288881 0.045284
            +v -0.490806 1.279601 0.000116
            +v -0.492540 1.279655 -0.012275
            +v -0.531045 1.288881 -0.045052
            +v -0.514875 1.280338 -0.040113
            +v -0.550156 1.297517 -0.047089
            +v -0.553676 1.281522 -0.044438
            +v -0.584968 1.282479 -0.016187
            +v -0.579430 1.290358 0.033238
            +v -0.563955 1.281838 0.040345
            +v -0.566259 1.281907 -0.038737
            +v -0.589090 1.298706 -0.030374
            +v -0.593624 1.290795 -0.005563
            +v -0.592210 1.290751 0.012571
            +v -0.587200 1.290598 0.023761
            +v -0.506130 1.296170 0.023946
            +v -0.499171 1.295958 0.000116
            +v -0.560943 1.321996 0.047543
            +v -0.531183 1.304987 0.041300
            +v -0.520679 1.304666 0.033845
            +v -0.507339 1.304257 0.012798
            +v -0.507339 1.304257 -0.012569
            +v -0.512568 1.304417 -0.023965
            +v -0.520679 1.304666 -0.033616
            +v -0.531183 1.304987 -0.041073
            +v -0.588179 1.322827 -0.046924
            +v -0.611723 1.315498 -0.021913
            +v -0.598481 1.323143 0.042587
            +v -0.586845 1.322788 0.047543
            +v -0.550156 1.297517 0.047319
            +v -0.512568 1.304417 0.024192
            +v -0.615532 1.315611 0.012968
            +v -0.610334 1.315456 0.024515
            +v -0.608336 1.323444 0.034898
            +v -0.549310 1.321640 0.042587
            +v -0.539454 1.321337 0.034898
            +v -0.529064 1.322462 0.014717
            +v -0.514179 1.312516 0.000116
            +v -0.516022 1.312572 -0.012739
            +v -0.560943 1.321996 -0.047316
            +v -0.600072 1.315140 -0.036006
            +v -0.617374 1.315668 0.000116
            +v -0.573894 1.322390 0.049300
            +v -0.533877 1.322610 0.027596
            +v -0.531842 1.321107 -0.024718
            +v -0.539454 1.321337 -0.034671
            +v -0.573894 1.322390 -0.049070
            +v -0.600787 1.323214 -0.040907
            +v -0.617670 1.325168 -0.024187
            +v -0.621205 1.323838 -0.011602
            +v -0.622967 1.326771 0.000296
            +v -0.621299 1.326722 0.015016
            +v -0.616592 1.326579 0.028233
            +v -0.563851 1.324963 0.053656
            +v -0.552694 1.324623 0.048084
            +v -0.554339 1.326115 -0.047551
            +v -0.563851 1.324963 -0.053062
            +v -0.607307 1.326293 -0.041058
            +v -0.599845 1.326066 0.048084
            +v -0.588688 1.325723 0.053656
            +v -0.576270 1.325343 -0.055035
            +v -0.576270 1.325343 0.055632
            +v -0.538806 1.329961 0.000116
            +v -0.544386 1.330134 -0.025238
            +v -0.550777 1.330326 -0.035404
            +v -0.559053 1.330580 0.043483
            +v -0.544386 1.330134 0.025470
            +v -0.578213 1.328284 -0.054154
            +v -0.597193 1.331745 -0.045296
            +v -0.616109 1.332322 -0.022774
            +v -0.619424 1.332423 -0.011851
            +v -0.619128 1.332416 0.013471
            +v -0.608617 1.332092 0.035633
            +v -0.579696 1.331209 0.050338
            +v -0.568822 1.330879 -0.048315
            +v -0.600341 1.331841 0.043483
            +v -0.569306 1.330891 0.027584
            +v -0.560659 1.330630 0.024333
            +v -0.578717 1.331180 0.028951
            +v -0.588253 1.331471 0.028344
            +v -0.597272 1.331745 0.025806
            +v -0.605149 1.331989 0.021511
            +v -0.553375 1.330408 0.019424
            +v -0.611353 1.332179 0.015746
            +v -0.615458 1.332302 0.008908
            +v -0.547943 1.330240 0.013195
            +v -0.617187 1.332354 0.001463
            +v -0.616422 1.332332 -0.006083
            +v -0.544733 1.330139 0.006063
            +v -0.543969 1.330119 -0.001483
            +v -0.549805 1.330297 -0.015766
            +v -0.545698 1.330171 -0.008927
            +v -0.556007 1.330486 -0.021528
            +v -0.613213 1.332235 -0.013212
            +v -0.563886 1.330726 -0.025825
            +v -0.607781 1.332068 -0.019446
            +v -0.572900 1.331002 -0.028364
            +v -0.600494 1.331846 -0.024355
            +v -0.582439 1.331293 -0.028970
            +v -0.591850 1.331582 -0.027601
            +v -0.515992 1.219879 0.025806
            +v -0.492565 1.236902 0.024333
            +v -0.487900 1.240289 0.019424
            +v -0.498096 1.232881 0.027584
            +v -0.504120 1.228508 0.028951
            +v -0.510223 1.224075 0.028344
            +v -0.521035 1.216215 0.021511
            +v -0.525004 1.213332 0.015746
            +v -0.527633 1.211422 0.008908
            +v -0.528739 1.210618 0.001463
            +v -0.528250 1.210973 -0.006083
            +v -0.526195 1.212466 -0.013212
            +v -0.522719 1.214992 -0.019446
            +v -0.518057 1.218379 -0.024355
            +v -0.512524 1.222400 -0.027601
            +v -0.506500 1.226773 -0.028970
            +v -0.500397 1.231211 -0.028364
            +v -0.494627 1.235402 -0.025825
            +v -0.489585 1.239063 -0.021528
            +v -0.485616 1.241947 -0.015766
            +v -0.482989 1.243859 -0.008927
            +v -0.481881 1.244660 -0.001483
            +v -0.482372 1.244305 0.006063
            +v -0.484424 1.242815 0.013195
            +v -0.446926 0.419714 0.005351
            +v -0.446785 0.420018 0.006342
            +v -0.446566 0.420588 0.007541
            +v -0.446132 0.421878 0.009221
            +v -0.446230 0.421389 -0.008836
            +v -0.446600 0.420267 -0.007472
            +v -0.446785 0.419783 -0.006510
            +v -0.446901 0.419527 -0.005711
            +v -0.446988 0.419372 -0.004983
            +v -0.447027 0.419315 -0.004603
            +v -0.447062 0.419275 -0.004238
            +v -0.447091 0.419246 -0.003888
            +v -0.447121 0.419223 -0.003537
            +v -0.447148 0.419211 -0.003185
            +v -0.447170 0.419204 -0.002827
            +v -0.447294 0.419268 -0.000745
            +v -0.447345 0.419342 0.000326
            +v -0.447471 0.419672 0.003491
            +v -0.447565 0.420038 0.006313
            +v -0.447720 0.420812 0.011611
            +v -0.448108 0.423267 0.026802
            +v -0.447032 0.419529 0.004448
            +v -0.444691 0.426713 0.012741
            +v -0.420255 0.519557 0.031346
            +v -0.421819 0.513447 -0.030044
            +v -0.395216 0.616484 0.043586
            +v -0.370723 0.711348 0.046640
            +v -0.394535 0.619111 -0.043216
            +v -0.356213 0.768451 0.046557
            +v -0.368841 0.718665 -0.046004
            +v -0.352451 0.788545 0.039797
            +v -0.346639 0.818325 0.015011
            +v -0.352232 0.789431 -0.039023
            +v -0.356147 0.768446 -0.046145
            +v -0.346950 0.819142 -0.006438
            +v -0.347046 0.819408 -0.003954
            +v -0.347222 0.819850 0.000372
            +v -0.076237 0.012909 0.164854
            +v -0.032207 0.017344 0.168687
            +v -0.054478 0.017344 0.170155
            +v -0.032140 0.066632 0.169190
            +v -0.054478 0.066632 0.170663
            +v -0.030981 0.080964 0.177952
            +v -0.054478 0.080964 0.179502
            +v -0.029863 0.089400 0.186396
            +v -0.054478 0.089400 0.188020
            +v -0.027537 0.100373 0.203980
            +v -0.054478 0.100373 0.205756
            +v -0.026220 0.108807 0.213934
            +v -0.054478 0.108807 0.215796
            +v -0.018437 0.184457 0.272763
            +v -0.054478 0.184457 0.275136
            +v -0.012877 0.225284 0.314788
            +v -0.054478 0.225281 0.317528
            +v -0.008276 0.256711 0.349565
            +v -0.054478 0.256711 0.352607
            +v -0.004860 0.289848 0.375378
            +v -0.054478 0.289848 0.378647
            +v -0.002859 0.335790 0.390512
            +v -0.054478 0.335790 0.393911
            +v -0.002496 0.405641 0.393245
            +v -0.054478 0.405641 0.396669
            +v -0.032140 1.309667 0.169190
            +v -0.054478 1.309667 0.170663
            +v -0.028420 1.315944 0.197307
            +v -0.054478 1.315944 0.199022
            +v -0.028137 1.326273 0.199461
            +v -0.054478 1.326273 0.201195
            +v -0.027071 1.345813 0.207512
            +v -0.054478 1.345813 0.209318
            +v -0.027202 1.351820 0.206523
            +v -0.054478 1.351820 0.208319
            +v -0.027853 1.359222 0.201595
            +v -0.054478 1.359222 0.203348
            +v -0.045826 1.489050 0.065746
            +v -0.054475 1.489050 0.066316
            +v -0.047267 1.500903 0.054860
            +v -0.054475 1.500903 0.055336
            +v -0.054475 1.527125 0.040542
            +v -0.049233 1.553962 0.040007
            +v -0.054475 1.657823 0.074567
            +v -0.054475 1.666013 0.073398
            +v -0.054475 1.672168 0.068726
            +v -0.054475 1.676879 0.061525
            +v -0.049990 1.688121 0.034279
            +v -0.054475 1.688121 0.034575
            +v -0.054586 1.692447 -0.000464
            +v -0.054475 1.692447 -0.000471
            +v -0.054478 0.010459 0.159056
            +v -0.011436 0.012909 0.160606
            +v -0.010432 0.017344 0.164340
            +v -0.010299 0.066632 0.164831
            +v -0.008007 0.080964 0.173367
            +v -0.005797 0.089400 0.181596
            +v -0.001196 0.100373 0.198723
            +v 0.001409 0.108807 0.208420
            +v 0.016802 0.184457 0.265727
            +v 0.027799 0.225284 0.306669
            +v 0.036899 0.256711 0.340549
            +v 0.043656 0.289848 0.365696
            +v 0.047615 0.335790 0.380437
            +v 0.048330 0.405641 0.383102
            +v -0.010299 1.309667 0.164831
            +v -0.002943 1.315944 0.192221
            +v -0.000274 1.345813 0.202164
            +v -0.000530 1.351820 0.201197
            +v -0.001821 1.359222 0.196402
            +v -0.037370 1.489050 0.064059
            +v -0.040219 1.500903 0.053454
            +v -0.044055 1.527125 0.039166
            +v -0.045604 1.688121 0.033403
            +v -0.054695 1.692447 -0.000444
            +v 0.009016 0.012909 0.153657
            +v 0.010496 0.017344 0.157231
            +v 0.010691 0.066632 0.157702
            +v 0.014073 0.080964 0.165865
            +v 0.017332 0.089400 0.173737
            +v 0.024121 0.100373 0.190121
            +v 0.027964 0.108807 0.199397
            +v 0.050671 0.184457 0.254222
            +v 0.066893 0.225284 0.293385
            +v 0.080318 0.256711 0.325795
            +v 0.090284 0.289848 0.349851
            +v 0.096125 0.335790 0.363954
            +v 0.097181 0.405641 0.366502
            +v 0.010691 1.309667 0.157702
            +v 0.021543 1.315944 0.183900
            +v 0.025482 1.345813 0.193415
            +v 0.025102 1.351820 0.192492
            +v 0.023201 1.359222 0.187899
            +v -0.029242 1.489050 0.061296
            +v -0.033443 1.500903 0.051152
            +v -0.039178 1.553962 0.037308
            +v -0.035229 1.657823 0.072029
            +v -0.035532 1.666013 0.070899
            +v -0.041389 1.688121 0.031970
            +v -0.054801 1.692447 -0.000409
            +v -0.054085 0.010129 0.001053
            +v -0.046416 0.010129 0.061296
            +v 0.022428 0.010129 0.133766
            +v 0.030325 0.017344 0.147460
            +v 0.030579 0.066632 0.147901
            +v 0.034992 0.080964 0.155556
            +v 0.039247 0.089400 0.162937
            +v 0.043549 0.094887 0.170401
            +v 0.048106 0.100373 0.178303
            +v 0.053121 0.108807 0.187003
            +v 0.082757 0.184457 0.238407
            +v 0.103930 0.225284 0.275133
            +v 0.121452 0.256711 0.305525
            +v 0.134457 0.289848 0.328084
            +v 0.142082 0.335790 0.341309
            +v 0.143459 0.405641 0.343699
            +v 0.030579 1.309667 0.147901
            +v 0.044743 1.315944 0.172469
            +v 0.045829 1.326273 0.174353
            +v 0.049884 1.345813 0.181389
            +v 0.049386 1.351820 0.180523
            +v 0.046904 1.359222 0.176218
            +v -0.034415 1.527125 0.035172
            +v -0.037395 1.688121 0.030002
            +v -0.054897 1.692447 -0.000360
            +v 0.046441 0.012909 0.132064
            +v 0.048794 0.017344 0.135138
            +v 0.049102 0.066632 0.135538
            +v 0.054478 0.080964 0.142556
            +v 0.059660 0.089400 0.149315
            +v 0.070448 0.100373 0.163396
            +v 0.076556 0.108807 0.171363
            +v 0.112648 0.184457 0.218465
            +v 0.138431 0.225284 0.252110
            +v 0.159772 0.256711 0.279956
            +v 0.175609 0.289848 0.300628
            +v 0.184894 0.335790 0.312743
            +v 0.186572 0.405641 0.314931
            +v 0.049102 1.309667 0.135538
            +v 0.066350 1.315944 0.158048
            +v 0.067675 1.326273 0.159774
            +v 0.072616 1.345813 0.166220
            +v 0.072007 1.351820 0.165431
            +v 0.068985 1.359222 0.161486
            +v -0.021538 1.489050 0.057502
            +v -0.033189 1.518227 0.037296
            +v -0.017418 1.657823 0.064651
            +v -0.018003 1.666013 0.063639
            +v -0.020337 1.672168 0.059589
            +v -0.023933 1.676879 0.053353
            +v -0.033672 1.688121 0.027520
            +v -0.054991 1.692447 -0.000296
            +v 0.057731 0.010459 0.112576
            +v 0.065578 0.017344 0.120428
            +v 0.065936 0.066632 0.120786
            +v 0.072184 0.080964 0.127035
            +v 0.078211 0.089400 0.133059
            +v 0.090752 0.100373 0.145602
            +v 0.097852 0.108807 0.152699
            +v 0.139810 0.184457 0.194658
            +v 0.169785 0.225281 0.224635
            +v 0.194591 0.256711 0.249441
            +v 0.213004 0.289848 0.267851
            +v 0.223799 0.335790 0.278644
            +v 0.225747 0.405641 0.280597
            +v 0.065936 1.309667 0.120786
            +v 0.085991 1.315944 0.140839
            +v 0.087528 1.326273 0.142378
            +v 0.093271 1.345813 0.148119
            +v 0.092563 1.351820 0.147413
            +v 0.089050 1.359222 0.143900
            +v -0.020980 1.510057 0.033870
            +v -0.026072 1.527125 0.028776
            +v -0.030160 1.553962 0.032103
            +v -0.030293 1.688121 0.024557
            +v -0.055075 1.692447 -0.000224
            +v 0.080288 0.017344 0.103642
            +v 0.080693 0.066632 0.103952
            +v 0.087703 0.080964 0.109328
            +v 0.094467 0.089400 0.114508
            +v 0.108546 0.100373 0.125298
            +v 0.116516 0.108807 0.131403
            +v 0.163615 0.184457 0.167498
            +v 0.197263 0.225281 0.193281
            +v 0.225108 0.256711 0.214617
            +v 0.245778 0.289848 0.230459
            +v 0.257893 0.335790 0.239742
            +v 0.260083 0.405641 0.241419
            +v 0.080690 1.309667 0.103952
            +v 0.103200 1.315944 0.121200
            +v 0.104927 1.326273 0.122523
            +v 0.111373 1.345813 0.127464
            +v 0.110581 1.351820 0.126854
            +v 0.106636 1.359222 0.123833
            +v -0.007847 1.489050 0.047003
            +v -0.002010 1.657823 0.052835
            +v -0.011234 1.676879 0.043614
            +v -0.027330 1.688121 0.021175
            +v -0.055146 1.692447 -0.000141
            +v 0.089260 0.012909 0.083241
            +v 0.092612 0.017344 0.085172
            +v 0.093051 0.066632 0.085424
            +v 0.100706 0.080964 0.089840
            +v 0.108089 0.089400 0.094095
            +v 0.123455 0.100373 0.102953
            +v 0.132151 0.108807 0.107968
            +v 0.183560 0.184457 0.137607
            +v 0.220286 0.225284 0.158780
            +v 0.250677 0.256711 0.176302
            +v 0.273234 0.289848 0.189307
            +v 0.286459 0.335790 0.196930
            +v 0.288849 0.405641 0.198309
            +v 0.093051 1.309667 0.085424
            +v 0.117621 1.315944 0.099593
            +v 0.119503 1.326273 0.100676
            +v 0.126539 1.345813 0.104734
            +v 0.125675 1.351820 0.104236
            +v 0.121371 1.359222 0.101754
            +v -0.013437 1.510057 0.024032
            +v -0.019675 1.527125 0.020435
            +v -0.019843 1.553962 0.020342
            +v 0.003488 1.666013 0.044790
            +v -0.000222 1.672168 0.041946
            +v -0.024846 1.688121 0.017453
            +v -0.055208 1.692447 -0.000049
            +v 0.102381 0.017344 0.065344
            +v 0.102852 0.066632 0.065541
            +v 0.111015 0.080964 0.068921
            +v 0.118887 0.089400 0.072184
            +v 0.135274 0.100373 0.078968
            +v 0.144549 0.108807 0.082812
            +v 0.199372 0.184453 0.105519
            +v 0.238535 0.225284 0.121743
            +v 0.270947 0.256711 0.135168
            +v 0.295004 0.289848 0.145131
            +v 0.309107 0.335790 0.150973
            +v 0.311655 0.405641 0.152028
            +v 0.102852 1.309667 0.065541
            +v 0.129052 1.315944 0.076393
            +v 0.138564 1.345813 0.080332
            +v 0.137642 1.351820 0.079950
            +v 0.133051 1.359222 0.078048
            +v 0.002654 1.489050 0.033307
            +v 0.009803 1.657823 0.037429
            +v -0.001497 1.676879 0.030917
            +v -0.022877 1.688121 0.013459
            +v -0.055257 1.692447 0.000049
            +v -0.053691 0.010129 0.000372
            +v 0.078919 0.010129 0.077278
            +v 0.105756 0.012909 0.043414
            +v 0.109493 0.017344 0.044415
            +v 0.109986 0.066632 0.044549
            +v 0.118519 0.080964 0.046840
            +v 0.126746 0.089400 0.049051
            +v 0.143876 0.100373 0.053651
            +v 0.153573 0.108807 0.056256
            +v 0.210880 0.184457 0.071649
            +v 0.251819 0.225284 0.082646
            +v 0.285701 0.256711 0.091746
            +v 0.310848 0.289848 0.098503
            +v 0.325590 0.335790 0.102460
            +v 0.328254 0.405641 0.103178
            +v 0.109984 1.309667 0.044549
            +v 0.137371 1.315944 0.051905
            +v 0.147314 1.345813 0.054576
            +v 0.146352 1.351820 0.054315
            +v 0.141552 1.359222 0.053027
            +v -0.008728 1.510057 0.012660
            +v -0.015682 1.527125 0.010795
            +v -0.015867 1.553962 0.010743
            +v 0.012993 1.666013 0.028317
            +v 0.008673 1.672168 0.026531
            +v -0.021447 1.688121 0.009246
            +v -0.055292 1.692447 0.000153
            +v 0.113839 0.017344 0.022641
            +v 0.114343 0.066632 0.022707
            +v 0.123102 0.080964 0.023867
            +v 0.131549 0.089400 0.024984
            +v 0.149132 0.100373 0.027310
            +v 0.159086 0.108807 0.028628
            +v 0.217913 0.184457 0.036413
            +v 0.259938 0.225284 0.041971
            +v 0.294715 0.256711 0.046574
            +v 0.320530 0.289848 0.049988
            +v 0.335662 0.335790 0.051991
            +v 0.338398 0.405641 0.052351
            +v 0.114343 1.309667 0.022707
            +v 0.142457 1.315944 0.026430
            +v 0.144611 1.326273 0.026713
            +v 0.152662 1.345813 0.027777
            +v 0.151673 1.351820 0.027646
            +v 0.146747 1.359222 0.026995
            +v 0.009211 1.489050 0.017480
            +v 0.017179 1.657823 0.019619
            +v 0.004583 1.676879 0.016237
            +v -0.020571 1.688121 0.004857
            +v -0.055314 1.692447 0.000261
            +v 0.111437 0.012909 0.000372
            +v 0.115305 0.017344 0.000372
            +v 0.115813 0.066632 0.000372
            +v 0.124652 0.080964 0.000372
            +v 0.133170 0.089400 0.000372
            +v 0.150906 0.100373 0.000372
            +v 0.160949 0.108807 0.000372
            +v 0.220286 0.184457 0.000372
            +v 0.262678 0.225284 0.000372
            +v 0.297759 0.256711 0.000372
            +v 0.323796 0.289848 0.000372
            +v 0.339061 0.335790 0.000372
            +v 0.341819 0.405641 0.000372
            +v 0.115813 1.309667 0.000372
            +v 0.144174 1.315944 0.000372
            +v 0.146347 1.326273 0.000372
            +v 0.154468 1.345813 0.000372
            +v 0.153472 1.351820 0.000372
            +v 0.148501 1.359222 0.000372
            +v -0.007104 1.510057 0.000372
            +v -0.014308 1.527125 0.000372
            +v -0.014498 1.553962 0.000372
            +v 0.017919 1.666013 0.009949
            +v -0.020275 1.688121 0.000372
            +v -0.055321 1.692447 0.000372
            +v -0.049889 0.010129 0.008328
            +v 0.113839 0.017344 -0.021898
            +v 0.114343 0.066632 -0.021967
            +v 0.123102 0.080964 -0.023124
            +v 0.131549 0.089400 -0.024239
            +v 0.149132 0.100373 -0.026568
            +v 0.159086 0.108807 -0.027883
            +v 0.217913 0.184457 -0.035668
            +v 0.259938 0.225284 -0.041228
            +v 0.294715 0.256711 -0.045831
            +v 0.320530 0.289848 -0.049243
            +v 0.335662 0.335790 -0.051246
            +v 0.338395 0.405641 -0.051609
            +v 0.114343 1.309667 -0.021967
            +v 0.142457 1.315944 -0.025685
            +v 0.144611 1.326273 -0.025968
            +v 0.152662 1.345813 -0.027034
            +v 0.151673 1.351820 -0.026906
            +v 0.146747 1.359222 -0.026252
            +v 0.011466 1.489050 0.000372
            +v 0.019720 1.657823 0.000372
            +v 0.013876 1.672168 0.000372
            +v -0.020571 1.688121 -0.004115
            +v -0.055314 1.692447 0.000483
            +v -0.053750 0.010129 0.000072
            +v 0.104209 0.010459 0.000372
            +v 0.098807 0.012909 -0.063121
            +v 0.109493 0.017344 -0.043670
            +v 0.109984 0.066632 -0.043804
            +v 0.118519 0.080964 -0.046098
            +v 0.126746 0.089400 -0.048308
            +v 0.143876 0.100373 -0.052911
            +v 0.153573 0.108807 -0.055514
            +v 0.210880 0.184457 -0.070904
            +v 0.251819 0.225284 -0.081904
            +v 0.285701 0.256711 -0.091006
            +v 0.310848 0.289848 -0.097761
            +v 0.325590 0.335790 -0.101720
            +v 0.328254 0.405641 -0.102433
            +v 0.109984 1.309667 -0.043804
            +v 0.137371 1.315944 -0.051160
            +v 0.147314 1.345813 -0.053831
            +v 0.146352 1.351820 -0.053572
            +v 0.141552 1.359222 -0.052285
            +v -0.017552 1.518227 -0.020916
            +v -0.011856 1.518227 0.000372
            +v -0.015682 1.527125 -0.010050
            +v -0.015867 1.553962 -0.009998
            +v 0.017919 1.666013 -0.009206
            +v 0.006147 1.676879 -0.007650
            +v -0.021447 1.688121 -0.008498
            +v -0.055292 1.692447 0.000592
            +v -0.045607 0.010129 -0.002010
            +v 0.102381 0.017344 -0.064601
            +v 0.102852 0.066632 -0.064796
            +v 0.111015 0.080964 -0.068178
            +v 0.118887 0.089400 -0.071437
            +v 0.135274 0.100373 -0.078226
            +v 0.144549 0.108807 -0.082067
            +v 0.199372 0.184453 -0.104776
            +v 0.238535 0.225284 -0.120998
            +v 0.270947 0.256711 -0.134423
            +v 0.295004 0.289848 -0.144389
            +v 0.309104 0.335790 -0.150228
            +v 0.311655 0.405641 -0.151286
            +v 0.102852 1.309667 -0.064796
            +v 0.129050 1.315944 -0.075648
            +v 0.138564 1.345813 -0.079587
            +v 0.137642 1.351820 -0.079205
            +v 0.133051 1.359222 -0.077303
            +v 0.009211 1.489050 -0.016735
            +v 0.017179 1.657823 -0.018876
            +v -0.022877 1.688121 -0.012717
            +v -0.055257 1.692447 0.000696
            +v 0.092612 0.017344 -0.084430
            +v 0.093051 0.066632 -0.084684
            +v 0.100706 0.080964 -0.089095
            +v 0.108089 0.089400 -0.093350
            +v 0.123455 0.100373 -0.102211
            +v 0.132151 0.108807 -0.107226
            +v 0.183560 0.184457 -0.136862
            +v 0.220283 0.225284 -0.158035
            +v 0.250677 0.256711 -0.175557
            +v 0.273234 0.289848 -0.188562
            +v 0.286459 0.335790 -0.196187
            +v 0.288849 0.405641 -0.197564
            +v 0.093051 1.309667 -0.084684
            +v 0.117621 1.315944 -0.098846
            +v 0.119503 1.326273 -0.099931
            +v 0.126539 1.345813 -0.103989
            +v 0.125675 1.351820 -0.103489
            +v 0.121371 1.359222 -0.101007
            +v -0.013437 1.510057 -0.023289
            +v -0.019843 1.553962 -0.019597
            +v 0.012993 1.666013 -0.027574
            +v -0.005935 1.676879 -0.036825
            +v -0.024846 1.688121 -0.016710
            +v -0.055208 1.692447 0.000794
            +v -0.054083 0.010129 -0.000308
            +v -0.023682 0.010129 -0.003703
            +v 0.077217 0.012909 -0.100543
            +v 0.080288 0.017344 -0.102897
            +v 0.080693 0.066632 -0.103207
            +v 0.087703 0.080964 -0.108583
            +v 0.094467 0.089400 -0.113765
            +v 0.108546 0.100373 -0.124553
            +v 0.116516 0.108807 -0.130658
            +v 0.163615 0.184457 -0.166753
            +v 0.197263 0.225281 -0.192536
            +v 0.225108 0.256711 -0.213877
            +v 0.245776 0.289848 -0.229714
            +v 0.257893 0.335790 -0.238999
            +v 0.260083 0.405641 -0.240674
            +v 0.080690 1.309667 -0.103207
            +v 0.103200 1.315944 -0.120455
            +v 0.104927 1.326273 -0.121780
            +v 0.111373 1.345813 -0.126721
            +v 0.110581 1.351820 -0.126112
            +v 0.106636 1.359222 -0.123088
            +v 0.002654 1.489050 -0.032565
            +v -0.019675 1.527125 -0.019693
            +v 0.009803 1.657823 -0.036684
            +v 0.004739 1.672168 -0.033768
            +v -0.027330 1.688121 -0.020430
            +v -0.055146 1.692447 0.000886
            +v -0.046520 0.010129 -0.004216
            +v 0.092129 0.010459 -0.060354
            +v 0.064530 0.014907 -0.118635
            +v 0.065936 0.020154 -0.120041
            +v 0.065936 0.066632 -0.120041
            +v 0.072184 0.080964 -0.126290
            +v 0.078211 0.089400 -0.132316
            +v 0.090752 0.100373 -0.144857
            +v 0.097852 0.108807 -0.151954
            +v 0.139810 0.184457 -0.193915
            +v 0.169785 0.225281 -0.223890
            +v 0.194591 0.256711 -0.248696
            +v 0.213004 0.289848 -0.267109
            +v 0.223796 0.335790 -0.277904
            +v 0.225747 0.405641 -0.279852
            +v 0.065936 1.309667 -0.120041
            +v 0.085989 1.315944 -0.140094
            +v 0.087528 1.326273 -0.141633
            +v 0.093271 1.345813 -0.147376
            +v 0.092563 1.351820 -0.146668
            +v 0.089050 1.359222 -0.143153
            +v -0.020980 1.510057 -0.033125
            +v -0.030293 1.688121 -0.023812
            +v -0.055075 1.692447 0.000969
            +v 0.028391 0.012909 -0.143365
            +v 0.048794 0.017344 -0.134391
            +v 0.049102 0.066632 -0.134798
            +v 0.054478 0.080964 -0.141811
            +v 0.059660 0.089400 -0.148572
            +v 0.070448 0.100373 -0.162651
            +v 0.076553 0.108807 -0.170619
            +v 0.112648 0.184457 -0.217720
            +v 0.138431 0.225284 -0.251368
            +v 0.159772 0.256711 -0.279213
            +v 0.175609 0.289848 -0.299881
            +v 0.184892 0.335790 -0.311998
            +v 0.186572 0.405641 -0.314186
            +v 0.049102 1.309667 -0.134798
            +v 0.066350 1.315944 -0.157305
            +v 0.067675 1.326273 -0.159032
            +v 0.072614 1.345813 -0.165478
            +v 0.072007 1.351820 -0.164686
            +v 0.068983 1.359222 -0.160741
            +v -0.007847 1.489050 -0.046258
            +v -0.026208 1.553962 -0.027897
            +v -0.002013 1.657823 -0.052095
            +v -0.002839 1.666013 -0.051268
            +v -0.006142 1.672168 -0.047960
            +v -0.033672 1.688121 -0.026775
            +v -0.054991 1.692447 0.001043
            +v 0.060561 0.011404 -0.114663
            +v 0.030325 0.017344 -0.146717
            +v 0.030579 0.066632 -0.147156
            +v 0.034992 0.080964 -0.154814
            +v 0.039247 0.089400 -0.162194
            +v 0.048106 0.100373 -0.177558
            +v 0.053121 0.108807 -0.186256
            +v 0.082757 0.184457 -0.237665
            +v 0.103930 0.225284 -0.274391
            +v 0.121452 0.256711 -0.304780
            +v 0.134457 0.289848 -0.327341
            +v 0.142082 0.335790 -0.340564
            +v 0.143459 0.405641 -0.342954
            +v 0.030576 1.309667 -0.147156
            +v 0.044743 1.315944 -0.171724
            +v 0.049884 1.345813 -0.180646
            +v 0.049386 1.351820 -0.179778
            +v 0.046904 1.359222 -0.175476
            +v -0.030816 1.510057 -0.040668
            +v -0.030044 1.527125 -0.031514
            +v -0.037395 1.688121 -0.029259
            +v -0.054897 1.692447 0.001105
            +v 0.009016 0.012909 -0.152914
            +v 0.010496 0.017344 -0.156486
            +v 0.010691 0.066632 -0.156955
            +v 0.014073 0.080964 -0.165120
            +v 0.017332 0.089400 -0.172992
            +v 0.024121 0.100373 -0.189376
            +v 0.027964 0.108807 -0.198654
            +v 0.050671 0.184457 -0.253477
            +v 0.066893 0.225284 -0.292640
            +v 0.080318 0.256711 -0.325052
            +v 0.090284 0.289848 -0.349109
            +v 0.096125 0.335790 -0.363209
            +v 0.097181 0.405641 -0.365757
            +v 0.010691 1.309667 -0.156955
            +v 0.021543 1.315944 -0.183155
            +v 0.025482 1.345813 -0.192667
            +v 0.025100 1.351820 -0.191747
            +v 0.023201 1.359222 -0.187154
            +v -0.021538 1.489050 -0.056757
            +v -0.028551 1.518227 -0.033458
            +v -0.039178 1.553962 -0.036563
            +v -0.017418 1.657823 -0.063906
            +v -0.018003 1.666013 -0.062894
            +v -0.023933 1.676879 -0.052608
            +v -0.041389 1.688121 -0.031225
            +v -0.054801 1.692447 0.001152
            +v -0.054475 0.010129 -0.000414
            +v -0.010432 0.017344 -0.163598
            +v -0.010299 0.066632 -0.164089
            +v -0.008007 0.080964 -0.172622
            +v -0.005797 0.089400 -0.180848
            +v -0.001196 0.100373 -0.197983
            +v 0.001409 0.108807 -0.207675
            +v 0.016802 0.184457 -0.264985
            +v 0.027799 0.225284 -0.305924
            +v 0.036899 0.256711 -0.339804
            +v 0.043653 0.289848 -0.364953
            +v 0.047615 0.335790 -0.379695
            +v 0.048328 0.405641 -0.382359
            +v -0.010299 1.309667 -0.164089
            +v -0.002945 1.315944 -0.191476
            +v -0.000274 1.345813 -0.201419
            +v -0.000533 1.351820 -0.200457
            +v -0.001821 1.359222 -0.195657
            +v -0.042188 1.510057 -0.045377
            +v -0.045604 1.688121 -0.032656
            +v -0.054695 1.692447 0.001187
            +v -0.032715 0.012909 -0.164109
            +v -0.032207 0.017344 -0.167944
            +v -0.032140 0.066632 -0.168448
            +v -0.030981 0.080964 -0.177207
            +v -0.029863 0.089400 -0.185654
            +v -0.027537 0.100373 -0.203235
            +v -0.026222 0.108807 -0.213189
            +v -0.018437 0.184457 -0.272015
            +v -0.012877 0.225284 -0.314043
            +v -0.008276 0.256711 -0.348820
            +v -0.004860 0.289848 -0.374633
            +v -0.002859 0.335790 -0.389765
            +v -0.002496 0.405641 -0.392500
            +v -0.032140 1.309667 -0.168448
            +v -0.028420 1.315944 -0.196560
            +v -0.028137 1.326273 -0.198718
            +v -0.027071 1.345813 -0.206768
            +v -0.027202 1.351820 -0.205778
            +v -0.027853 1.359222 -0.200850
            +v -0.037370 1.489050 -0.063314
            +v -0.049233 1.553962 -0.039262
            +v -0.035229 1.657823 -0.071284
            +v -0.035532 1.666013 -0.070154
            +v -0.036746 1.672168 -0.065640
            +v -0.054589 1.692447 0.001209
            +v -0.014532 0.010129 -0.148333
            +v -0.054475 0.017344 -0.169410
            +v -0.054475 0.066632 -0.169918
            +v -0.054475 0.080964 -0.178757
            +v -0.054475 0.089400 -0.187275
            +v -0.054475 0.100373 -0.205011
            +v -0.054475 0.108807 -0.215051
            +v -0.054475 0.184457 -0.274391
            +v -0.054475 0.225281 -0.316781
            +v -0.054478 0.256711 -0.351864
            +v -0.054478 0.289848 -0.377904
            +v -0.054478 0.335790 -0.393166
            +v -0.054478 0.405641 -0.395924
            +v -0.054478 1.309667 -0.169918
            +v -0.054478 1.315944 -0.198277
            +v -0.054478 1.326273 -0.200452
            +v -0.054478 1.345813 -0.208571
            +v -0.054478 1.351820 -0.207574
            +v -0.054478 1.359222 -0.202606
            +v -0.054478 1.489050 -0.065573
            +v -0.054478 1.510057 -0.047001
            +v -0.044055 1.527125 -0.038423
            +v -0.049990 1.688121 -0.033534
            +v -0.054478 1.688121 -0.033830
            +v -0.054478 1.692447 0.001216
            +v -0.052095 0.010129 -0.008498
            +v -0.076746 0.017344 -0.167944
            +v -0.076812 0.066632 -0.168448
            +v -0.077972 0.080964 -0.177207
            +v -0.079089 0.089400 -0.185654
            +v -0.081415 0.100373 -0.203235
            +v -0.082733 0.108807 -0.213189
            +v -0.090516 0.184457 -0.272015
            +v -0.096076 0.225284 -0.314043
            +v -0.100676 0.256711 -0.348820
            +v -0.104093 0.289848 -0.374633
            +v -0.106096 0.335790 -0.389765
            +v -0.106459 0.405641 -0.392500
            +v -0.076812 1.309667 -0.168448
            +v -0.080532 1.315944 -0.196560
            +v -0.080818 1.326273 -0.198716
            +v -0.081882 1.345813 -0.206768
            +v -0.081751 1.351820 -0.205778
            +v -0.081100 1.359222 -0.200850
            +v -0.059720 1.553962 -0.039260
            +v -0.054478 1.657823 -0.073825
            +v -0.054478 1.666013 -0.072656
            +v -0.054478 1.672168 -0.067981
            +v -0.054478 1.676879 -0.060780
            +v -0.058962 1.688121 -0.033532
            +v -0.054367 1.692447 0.001209
            +v -0.054776 0.010129 -0.000355
            +v -0.054475 0.010459 -0.158311
            +v -0.076237 0.012909 -0.164109
            +v -0.098520 0.017344 -0.163598
            +v -0.098654 0.066632 -0.164089
            +v -0.100945 0.080964 -0.172622
            +v -0.103156 0.089400 -0.180848
            +v -0.107756 0.100373 -0.197983
            +v -0.110361 0.108807 -0.207675
            +v -0.125754 0.184457 -0.264985
            +v -0.136751 0.225284 -0.305924
            +v -0.145851 0.256711 -0.339804
            +v -0.152608 0.289848 -0.364953
            +v -0.156567 0.335790 -0.379695
            +v -0.157283 0.405641 -0.382359
            +v -0.098654 1.309667 -0.164089
            +v -0.106010 1.315944 -0.191476
            +v -0.108681 1.345813 -0.201419
            +v -0.108422 1.351820 -0.200457
            +v -0.107132 1.359222 -0.195657
            +v -0.063126 1.489050 -0.065004
            +v -0.066765 1.510057 -0.045377
            +v -0.063348 1.688121 -0.032656
            +v -0.054258 1.692447 0.001187
            +v -0.056858 0.010129 -0.008498
            +v -0.119449 0.017344 -0.156486
            +v -0.119644 0.066632 -0.156955
            +v -0.123026 0.080964 -0.165120
            +v -0.126287 0.089400 -0.172992
            +v -0.133073 0.100373 -0.189376
            +v -0.136917 0.108807 -0.198654
            +v -0.159624 0.184457 -0.253475
            +v -0.175846 0.225281 -0.292640
            +v -0.189270 0.256711 -0.325052
            +v -0.199236 0.289848 -0.349109
            +v -0.205078 0.335790 -0.363209
            +v -0.206134 0.405641 -0.365757
            +v -0.119644 1.309667 -0.156955
            +v -0.130498 1.315944 -0.183155
            +v -0.134435 1.345813 -0.192667
            +v -0.134055 1.351820 -0.191747
            +v -0.132153 1.359222 -0.187154
            +v -0.069777 1.553962 -0.036563
            +v -0.073724 1.657823 -0.071284
            +v -0.073420 1.666013 -0.070154
            +v -0.070342 1.676879 -0.058688
            +v -0.067564 1.688121 -0.031225
            +v -0.054154 1.692447 0.001152
            +v -0.131381 0.010129 -0.133022
            +v -0.137343 0.012909 -0.143365
            +v -0.139277 0.017344 -0.146717
            +v -0.139529 0.066632 -0.147156
            +v -0.143945 0.080964 -0.154814
            +v -0.148200 0.089400 -0.162194
            +v -0.157058 0.100373 -0.177558
            +v -0.162073 0.108807 -0.186256
            +v -0.191710 0.184457 -0.237665
            +v -0.212883 0.225281 -0.274391
            +v -0.230405 0.256711 -0.304780
            +v -0.243410 0.289848 -0.327341
            +v -0.251035 0.335790 -0.340564
            +v -0.252414 0.405641 -0.342954
            +v -0.139531 1.309667 -0.147156
            +v -0.153696 1.315944 -0.171724
            +v -0.154781 1.326273 -0.173608
            +v -0.158837 1.345813 -0.180644
            +v -0.158339 1.351820 -0.179778
            +v -0.155857 1.359222 -0.175473
            +v -0.079711 1.489050 -0.060553
            +v -0.078137 1.510057 -0.040668
            +v -0.064897 1.527125 -0.038423
            +v -0.091672 1.676879 -0.048167
            +v -0.071558 1.688121 -0.029257
            +v -0.054056 1.692447 0.001105
            +v -0.054954 0.010129 -0.000252
            +v -0.157747 0.017344 -0.134391
            +v -0.158057 0.066632 -0.134798
            +v -0.163430 0.080964 -0.141811
            +v -0.168613 0.089400 -0.148572
            +v -0.179400 0.100373 -0.162651
            +v -0.185508 0.108807 -0.170619
            +v -0.221601 0.184457 -0.217718
            +v -0.247386 0.225281 -0.251365
            +v -0.268724 0.256711 -0.279213
            +v -0.284562 0.289848 -0.299881
            +v -0.293847 0.335790 -0.311998
            +v -0.295524 0.405641 -0.314186
            +v -0.158057 1.309667 -0.134798
            +v -0.175306 1.315944 -0.157305
            +v -0.176628 1.326273 -0.159032
            +v -0.181569 1.345813 -0.165478
            +v -0.180959 1.351820 -0.164686
            +v -0.177938 1.359222 -0.160741
            +v -0.094588 1.489050 -0.051969
            +v -0.078793 1.553962 -0.031361
            +v -0.091534 1.657823 -0.063906
            +v -0.090952 1.666013 -0.062894
            +v -0.088616 1.672168 -0.058844
            +v -0.075280 1.688121 -0.026775
            +v -0.053964 1.692447 0.001043
            +v -0.060062 0.010129 -0.006917
            +v -0.174531 0.017344 -0.119681
            +v -0.174891 0.066632 -0.120041
            +v -0.181137 0.080964 -0.126290
            +v -0.187164 0.089400 -0.132316
            +v -0.199705 0.100373 -0.144857
            +v -0.206804 0.108807 -0.151954
            +v -0.248763 0.184457 -0.193913
            +v -0.278740 0.225281 -0.223890
            +v -0.303546 0.256711 -0.248696
            +v -0.321956 0.289848 -0.267109
            +v -0.332751 0.335790 -0.277901
            +v -0.334702 0.405641 -0.279850
            +v -0.174891 1.309667 -0.120041
            +v -0.194944 1.315944 -0.140094
            +v -0.196481 1.326273 -0.141633
            +v -0.202224 1.345813 -0.147376
            +v -0.201518 1.351820 -0.146668
            +v -0.198003 1.359222 -0.143153
            +v -0.087972 1.510057 -0.033125
            +v -0.082881 1.527125 -0.028031
            +v -0.106942 1.657823 -0.052095
            +v -0.078660 1.688121 -0.023812
            +v -0.053881 1.692447 0.000969
            +v -0.073371 0.010129 -0.024286
            +v -0.171795 0.012909 -0.116945
            +v -0.189241 0.017344 -0.102897
            +v -0.189643 0.066632 -0.103207
            +v -0.196658 0.080964 -0.108580
            +v -0.203420 0.089400 -0.113763
            +v -0.217498 0.100373 -0.124553
            +v -0.225469 0.108807 -0.130658
            +v -0.272568 0.184457 -0.166753
            +v -0.306218 0.225281 -0.192536
            +v -0.334061 0.256711 -0.213877
            +v -0.354731 0.289848 -0.229714
            +v -0.366845 0.335790 -0.238997
            +v -0.369036 0.405641 -0.240674
            +v -0.189645 1.309667 -0.103207
            +v -0.212153 1.315944 -0.120455
            +v -0.213879 1.326273 -0.121780
            +v -0.220325 1.345813 -0.126721
            +v -0.219533 1.351820 -0.126109
            +v -0.215589 1.359222 -0.123088
            +v -0.101106 1.489050 -0.046258
            +v -0.086208 1.553962 -0.023946
            +v -0.102810 1.672168 -0.047960
            +v -0.097719 1.676879 -0.042871
            +v -0.081623 1.688121 -0.020430
            +v -0.053807 1.692447 0.000886
            +v -0.055235 0.010129 0.000168
            +v -0.166684 0.010459 -0.111836
            +v -0.201565 0.017344 -0.084430
            +v -0.202007 0.066632 -0.084684
            +v -0.209661 0.080964 -0.089095
            +v -0.217042 0.089400 -0.093350
            +v -0.232408 0.100373 -0.102211
            +v -0.241106 0.108807 -0.107226
            +v -0.292515 0.184457 -0.136862
            +v -0.329238 0.225281 -0.158035
            +v -0.359630 0.256711 -0.175557
            +v -0.382189 0.289848 -0.188562
            +v -0.395411 0.335790 -0.196187
            +v -0.397804 0.405641 -0.197564
            +v -0.202004 1.309667 -0.084684
            +v -0.226574 1.315944 -0.098846
            +v -0.235491 1.345813 -0.103987
            +v -0.234628 1.351820 -0.103489
            +v -0.230323 1.359222 -0.101007
            +v -0.095516 1.510057 -0.023289
            +v -0.084615 1.518227 -0.029765
            +v -0.089277 1.527125 -0.019690
            +v -0.113368 1.657823 -0.044758
            +v -0.112441 1.666013 -0.044045
            +v -0.084107 1.688121 -0.016710
            +v -0.053745 1.692447 0.000794
            +v -0.061767 0.010129 -0.005215
            +v -0.207762 0.012909 -0.063119
            +v -0.211336 0.017344 -0.064601
            +v -0.211805 0.066632 -0.064796
            +v -0.219970 0.080964 -0.068176
            +v -0.227839 0.089400 -0.071437
            +v -0.244226 0.100373 -0.078223
            +v -0.253502 0.108807 -0.082067
            +v -0.308325 0.184457 -0.104776
            +v -0.347490 0.225281 -0.120998
            +v -0.379900 0.256711 -0.134420
            +v -0.403956 0.289848 -0.144386
            +v -0.418059 0.335790 -0.150228
            +v -0.420607 0.405641 -0.151283
            +v -0.211805 1.309667 -0.064796
            +v -0.238005 1.315944 -0.075648
            +v -0.240013 1.326273 -0.076479
            +v -0.247517 1.345813 -0.079587
            +v -0.246595 1.351820 -0.079205
            +v -0.242004 1.359222 -0.077303
            +v -0.111607 1.489050 -0.032565
            +v -0.091413 1.553962 -0.014927
            +v -0.113536 1.676879 -0.015492
            +v -0.086075 1.688121 -0.012717
            +v -0.053696 1.692447 0.000696
            +v -0.218448 0.017344 -0.043670
            +v -0.218936 0.066632 -0.043804
            +v -0.227472 0.080964 -0.046095
            +v -0.235701 0.089400 -0.048308
            +v -0.252828 0.100373 -0.052909
            +v -0.262525 0.108807 -0.055511
            +v -0.319835 0.184457 -0.070904
            +v -0.360772 0.225284 -0.081901
            +v -0.394654 0.256711 -0.091004
            +v -0.419801 0.289848 -0.097758
            +v -0.434543 0.335790 -0.101717
            +v -0.437207 0.405641 -0.102433
            +v -0.218936 1.309667 -0.043804
            +v -0.246326 1.315944 -0.051160
            +v -0.248425 1.326273 -0.051725
            +v -0.256269 1.345813 -0.053831
            +v -0.255305 1.351820 -0.053572
            +v -0.250504 1.359222 -0.052285
            +v -0.100227 1.510057 -0.011915
            +v -0.093271 1.527125 -0.010050
            +v -0.123026 1.657823 -0.028021
            +v -0.121945 1.666013 -0.027574
            +v -0.087506 1.688121 -0.008498
            +v -0.053661 1.692447 0.000592
            +v -0.218956 0.012909 -0.021392
            +v -0.222792 0.017344 -0.021898
            +v -0.223295 0.066632 -0.021965
            +v -0.232055 0.080964 -0.023124
            +v -0.240504 0.089400 -0.024239
            +v -0.258085 0.100373 -0.026565
            +v -0.268039 0.108807 -0.027883
            +v -0.326865 0.184457 -0.035665
            +v -0.368890 0.225284 -0.041228
            +v -0.403668 0.256711 -0.045829
            +v -0.429483 0.289848 -0.049243
            +v -0.444615 0.335790 -0.051246
            +v -0.447350 0.405641 -0.051609
            +v -0.223295 1.309667 -0.021965
            +v -0.251410 1.315944 -0.025685
            +v -0.253566 1.326273 -0.025968
            +v -0.261618 1.345813 -0.027034
            +v -0.260628 1.351820 -0.026903
            +v -0.255700 1.359222 -0.026252
            +v -0.118164 1.489050 -0.016735
            +v -0.128034 1.657823 -0.009359
            +v -0.120490 1.672168 -0.017362
            +v -0.088382 1.688121 -0.004115
            +v -0.053639 1.692447 0.000483
            +v -0.203181 0.010129 -0.039573
            +v -0.218956 0.012909 0.022135
            +v -0.224260 0.017344 0.000372
            +v -0.224768 0.066632 0.000372
            +v -0.233602 0.080964 0.000372
            +v -0.242125 0.089400 0.000372
            +v -0.259861 0.100373 0.000372
            +v -0.269901 0.108807 0.000372
            +v -0.329238 0.184457 0.000372
            +v -0.371631 0.225284 0.000372
            +v -0.406712 0.256711 0.000372
            +v -0.432752 0.289848 0.000372
            +v -0.448016 0.335790 0.000372
            +v -0.253127 1.315944 0.000372
            +v -0.224768 1.309667 0.000372
            +v -0.255300 1.326273 0.000372
            +v -0.263423 1.345813 0.000372
            +v -0.262424 1.351820 0.000372
            +v -0.257454 1.359222 0.000372
            +v -0.101848 1.510057 0.000372
            +v -0.094647 1.527125 0.000372
            +v -0.094110 1.553962 -0.004872
            +v -0.088678 1.688121 0.000372
            +v -0.053634 1.692447 0.000372
            +v -0.222792 0.017344 0.022641
            +v -0.223295 0.066632 0.022707
            +v -0.232055 0.080964 0.023867
            +v -0.240504 0.089400 0.024984
            +v -0.258085 0.100373 0.027310
            +v -0.268039 0.108807 0.028628
            +v -0.326865 0.184457 0.036413
            +v -0.368890 0.225284 0.041971
            +v -0.403668 0.256711 0.046574
            +v -0.429483 0.289848 0.049988
            +v -0.444615 0.335790 0.051991
            +v -0.447350 0.405641 0.052354
            +v -0.251410 1.315944 0.026430
            +v -0.223295 1.309667 0.022707
            +v -0.253566 1.326273 0.026713
            +v -0.261618 1.345813 0.027779
            +v -0.260628 1.351820 0.027648
            +v -0.255700 1.359222 0.026995
            +v -0.120421 1.489050 0.000372
            +v -0.128672 1.657823 0.000372
            +v -0.127503 1.666013 0.000372
            +v -0.122829 1.672168 0.000372
            +v -0.113536 1.676879 0.016237
            +v -0.088382 1.688121 0.004857
            +v -0.053639 1.692447 0.000264
            +v -0.213162 0.010459 0.000372
            +v -0.214708 0.012909 0.043414
            +v -0.218448 0.017344 0.044415
            +v -0.218936 0.066632 0.044549
            +v -0.227472 0.080964 0.046840
            +v -0.235701 0.089400 0.049051
            +v -0.252828 0.100373 0.053651
            +v -0.262525 0.108807 0.056256
            +v -0.319835 0.184457 0.071649
            +v -0.360772 0.225284 0.082649
            +v -0.394654 0.256711 0.091746
            +v -0.419801 0.289848 0.098503
            +v -0.434543 0.335790 0.102465
            +v -0.437207 0.405641 0.103178
            +v -0.218936 1.309667 0.044549
            +v -0.246326 1.315944 0.051905
            +v -0.248425 1.326273 0.052470
            +v -0.256269 1.345813 0.054579
            +v -0.255305 1.351820 0.054317
            +v -0.250504 1.359222 0.053030
            +v -0.100225 1.510057 0.012660
            +v -0.097097 1.518227 0.000372
            +v -0.093271 1.527125 0.010795
            +v -0.093086 1.553962 0.010743
            +v -0.087506 1.688121 0.009246
            +v -0.053661 1.692447 0.000153
            +v -0.198213 0.012909 0.083241
            +v -0.211334 0.017344 0.065344
            +v -0.211805 0.066632 0.065541
            +v -0.219970 0.080964 0.068921
            +v -0.227839 0.089400 0.072184
            +v -0.244226 0.100373 0.078968
            +v -0.253502 0.108807 0.082812
            +v -0.308325 0.184457 0.105519
            +v -0.347488 0.225281 0.121743
            +v -0.379900 0.256711 0.135168
            +v -0.403956 0.289848 0.145131
            +v -0.418059 0.335790 0.150973
            +v -0.420607 0.405641 0.152031
            +v -0.211805 1.309667 0.065541
            +v -0.238005 1.315944 0.076393
            +v -0.240013 1.326273 0.077224
            +v -0.247517 1.345813 0.080332
            +v -0.246595 1.351820 0.079950
            +v -0.242004 1.359222 0.078048
            +v -0.118164 1.489050 0.017480
            +v -0.126132 1.657823 0.019621
            +v -0.125002 1.666013 0.019315
            +v -0.086075 1.688121 0.013459
            +v -0.053696 1.692447 0.000049
            +v -0.054870 0.010129 0.001053
            +v -0.187872 0.010129 0.077278
            +v -0.201565 0.017344 0.085172
            +v -0.202007 0.066632 0.085424
            +v -0.209661 0.080964 0.089840
            +v -0.217042 0.089400 0.094095
            +v -0.232408 0.100373 0.102953
            +v -0.241106 0.108807 0.107968
            +v -0.292515 0.184457 0.137607
            +v -0.329238 0.225281 0.158780
            +v -0.359630 0.256711 0.176302
            +v -0.382189 0.289848 0.189307
            +v -0.395411 0.335790 0.196930
            +v -0.397804 0.405641 0.198309
            +v -0.202004 1.309667 0.085426
            +v -0.226574 1.315944 0.099593
            +v -0.228458 1.326273 0.100676
            +v -0.235491 1.345813 0.104734
            +v -0.234628 1.351820 0.104236
            +v -0.230323 1.359222 0.101754
            +v -0.095516 1.510057 0.024032
            +v -0.089277 1.527125 0.020438
            +v -0.089112 1.553962 0.020342
            +v -0.103017 1.676879 0.037570
            +v -0.084107 1.688121 0.017455
            +v -0.053745 1.692447 -0.000049
            +v -0.189241 0.017344 0.103644
            +v -0.189643 0.066632 0.103952
            +v -0.196658 0.080964 0.109328
            +v -0.203420 0.089400 0.114508
            +v -0.217498 0.100373 0.125298
            +v -0.225469 0.108807 0.131403
            +v -0.234492 0.123132 0.138318
            +v -0.272568 0.184457 0.167498
            +v -0.306218 0.225281 0.193281
            +v -0.334061 0.256711 0.214619
            +v -0.354731 0.289848 0.230459
            +v -0.366845 0.335790 0.239742
            +v -0.369036 0.405641 0.241422
            +v -0.189643 1.309667 0.103952
            +v -0.212153 1.315944 0.121200
            +v -0.213879 1.326273 0.122523
            +v -0.220325 1.345813 0.127464
            +v -0.219533 1.351820 0.126857
            +v -0.215589 1.359222 0.123833
            +v -0.111607 1.489050 0.033307
            +v -0.118756 1.657823 0.037429
            +v -0.117742 1.666013 0.036847
            +v -0.113691 1.672168 0.034511
            +v -0.081623 1.688121 0.021175
            +v -0.053807 1.692447 -0.000141
            +v -0.171795 0.012909 0.117693
            +v -0.174531 0.017344 0.120428
            +v -0.174891 0.066632 0.120786
            +v -0.181137 0.080964 0.127035
            +v -0.187164 0.089400 0.133059
            +v -0.199705 0.100373 0.145602
            +v -0.206802 0.108807 0.152699
            +v -0.214844 0.123132 0.160739
            +v -0.248763 0.184457 0.194658
            +v -0.278740 0.225281 0.224635
            +v -0.303544 0.256711 0.249441
            +v -0.321956 0.289848 0.267851
            +v -0.332749 0.335790 0.278644
            +v -0.334700 0.405641 0.280597
            +v -0.174889 1.309667 0.120786
            +v -0.194944 1.315944 0.140839
            +v -0.196481 1.326273 0.142378
            +v -0.202224 1.345813 0.148119
            +v -0.201518 1.351820 0.147413
            +v -0.198003 1.359222 0.143900
            +v -0.101106 1.489050 0.047003
            +v -0.087972 1.510057 0.033870
            +v -0.082881 1.527125 0.028776
            +v -0.082745 1.553962 0.028640
            +v -0.078660 1.688121 0.024557
            +v -0.053881 1.692447 -0.000222
            +v -0.062961 0.010129 0.003888
            +v -0.083177 0.010129 0.012258
            +v -0.157747 0.017344 0.135138
            +v -0.158057 0.066632 0.135538
            +v -0.163430 0.080964 0.142556
            +v -0.168613 0.089400 0.149315
            +v -0.179400 0.100373 0.163396
            +v -0.185508 0.108807 0.171363
            +v -0.192423 0.123132 0.180387
            +v -0.221601 0.184457 0.218465
            +v -0.247386 0.225281 0.252110
            +v -0.268722 0.256711 0.279956
            +v -0.284562 0.289848 0.300628
            +v -0.293847 0.335790 0.312743
            +v -0.295524 0.405641 0.314931
            +v -0.158057 1.309667 0.135538
            +v -0.175306 1.315944 0.158050
            +v -0.176628 1.326273 0.159774
            +v -0.180533 1.340213 0.164871
            +v -0.181566 1.345813 0.166220
            +v -0.180959 1.351820 0.165431
            +v -0.177938 1.359222 0.161486
            +v -0.106940 1.657823 0.052837
            +v -0.106113 1.666013 0.052008
            +v -0.102810 1.672168 0.048705
            +v -0.097719 1.676879 0.043614
            +v -0.075280 1.688121 0.027520
            +v -0.053964 1.692447 -0.000296
            +v -0.166684 0.010459 0.112576
            +v -0.137343 0.012909 0.144110
            +v -0.139277 0.017344 0.147460
            +v -0.139529 0.066632 0.147901
            +v -0.143945 0.080964 0.155556
            +v -0.148200 0.089401 0.162937
            +v -0.152502 0.094887 0.170401
            +v -0.157058 0.100373 0.178303
            +v -0.162073 0.108807 0.187003
            +v -0.167752 0.123132 0.196848
            +v -0.191710 0.184457 0.238407
            +v -0.212883 0.225281 0.275133
            +v -0.230405 0.256711 0.305525
            +v -0.243410 0.289848 0.328084
            +v -0.251035 0.335790 0.341309
            +v -0.252414 0.405641 0.343699
            +v -0.139529 1.309667 0.147901
            +v -0.153694 1.315944 0.172469
            +v -0.154781 1.326273 0.174353
            +v -0.156424 1.334031 0.177202
            +v -0.157986 1.340213 0.179914
            +v -0.158837 1.345813 0.181391
            +v -0.158339 1.351820 0.180523
            +v -0.155857 1.359223 0.176218
            +v -0.094586 1.489050 0.052716
            +v -0.078137 1.510057 0.041413
            +v -0.084615 1.518227 0.030510
            +v -0.074540 1.527125 0.035172
            +v -0.074444 1.553962 0.035007
            +v -0.071558 1.688121 0.030002
            +v -0.054056 1.692447 -0.000360
            +v -0.117969 0.012909 0.153657
            +v -0.119449 0.017344 0.157231
            +v -0.119644 0.066632 0.157702
            +v -0.123026 0.080964 0.165865
            +v -0.126287 0.089400 0.173737
            +v -0.129583 0.094887 0.181695
            +v -0.133073 0.100373 0.190121
            +v -0.136917 0.108807 0.199397
            +v -0.159624 0.184457 0.254222
            +v -0.175846 0.225281 0.293385
            +v -0.189270 0.256711 0.325795
            +v -0.199236 0.289848 0.349851
            +v -0.205078 0.335790 0.363954
            +v -0.206134 0.405641 0.366502
            +v -0.119644 1.309667 0.157702
            +v -0.130495 1.315944 0.183900
            +v -0.131329 1.326273 0.185910
            +v -0.132587 1.334031 0.188945
            +v -0.133786 1.340213 0.191841
            +v -0.134435 1.345813 0.193415
            +v -0.134055 1.351820 0.192492
            +v -0.132153 1.359222 0.187899
            +v -0.079711 1.489050 0.061296
            +v -0.091534 1.657823 0.064651
            +v -0.090952 1.666013 0.063639
            +v -0.070342 1.676879 0.059433
            +v -0.067564 1.688121 0.031970
            +v -0.054152 1.692447 -0.000409
            +v -0.094421 0.010129 0.149076
            +v -0.098520 0.017344 0.164340
            +v -0.098654 0.066632 0.164831
            +v -0.100945 0.080964 0.173367
            +v -0.103156 0.089400 0.181596
            +v -0.105391 0.094887 0.189917
            +v -0.107756 0.100373 0.198723
            +v -0.110361 0.108807 0.208420
            +v -0.125754 0.184457 0.265727
            +v -0.136751 0.225284 0.306669
            +v -0.145851 0.256711 0.340549
            +v -0.152606 0.289848 0.365696
            +v -0.156565 0.335790 0.380437
            +v -0.157283 0.405641 0.383102
            +v -0.098654 1.309667 0.164831
            +v -0.106010 1.315944 0.192221
            +v -0.108679 1.345813 0.202164
            +v -0.108420 1.351820 0.201200
            +v -0.107132 1.359222 0.196402
            +v -0.071583 1.489050 0.064059
            +v -0.064897 1.527125 0.039166
            +v -0.063348 1.688121 0.033403
            +v -0.054258 1.692447 -0.000444
            +v -0.056858 0.010129 0.009243
            +v -0.054374 0.010129 0.001152
            +v -0.076746 0.017344 0.168687
            +v -0.076812 0.066632 0.169190
            +v -0.077972 0.080964 0.177952
            +v -0.079089 0.089400 0.186396
            +v -0.081415 0.100373 0.203980
            +v -0.082733 0.108807 0.213934
            +v -0.090516 0.184457 0.272763
            +v -0.096076 0.225284 0.314788
            +v -0.100676 0.256711 0.349565
            +v -0.104093 0.289848 0.375378
            +v -0.106096 0.335790 0.390512
            +v -0.106456 0.405641 0.393245
            +v -0.076812 1.309667 0.169190
            +v -0.080532 1.315944 0.197307
            +v -0.080816 1.326273 0.199461
            +v -0.081882 1.345813 0.207512
            +v -0.081751 1.351820 0.206523
            +v -0.081100 1.359222 0.201595
            +v -0.063126 1.489050 0.065746
            +v -0.061686 1.500903 0.054860
            +v -0.054475 1.518227 0.042994
            +v -0.064848 1.553962 0.038983
            +v -0.073724 1.657823 0.072029
            +v -0.073420 1.666013 0.070899
            +v -0.072209 1.672168 0.066385
            +v -0.058962 1.688121 0.034279
            +v -0.054364 1.692447 -0.000464
            +v 0.211918 1.014939 -0.054105
            +v 0.212984 1.014860 0.032715
            +v 0.218399 1.016806 0.039117
            +v 0.234685 1.022742 0.044065
            +v 0.250840 1.028687 0.038658
            +v 0.256097 1.030645 0.032108
            +v 0.255034 1.030722 -0.054714
            +v 0.249619 1.028776 -0.061113
            +v 0.242014 1.026015 -0.064888
            +v 0.224687 1.019668 -0.064643
            +v 0.217178 1.016898 -0.060657
            +v 0.200164 1.044948 -0.053910
            +v 0.201355 1.044872 0.032908
            +v 0.206254 1.047292 0.039311
            +v 0.213120 1.050723 0.043093
            +v 0.228740 1.058602 0.042861
            +v 0.235496 1.062043 0.038877
            +v 0.240218 1.064475 0.032330
            +v 0.239026 1.064552 -0.054490
            +v 0.234127 1.062130 -0.060891
            +v 0.227262 1.058698 -0.064675
            +v 0.219435 1.054759 -0.065852
            +v 0.211642 1.050817 -0.064441
            +v 0.204885 1.047378 -0.060455
            +v 0.189332 1.110211 0.044768
            +v 0.204251 1.097356 0.043236
            +v 0.202137 1.114777 0.039361
            +v 0.225666 1.087365 0.032542
            +v 0.224358 1.087402 -0.054273
            +v 0.200398 1.114681 -0.060400
            +v 0.187413 1.110100 -0.065349
            +v 0.180548 1.107660 -0.063933
            +v 0.174610 1.105536 -0.059942
            +v 0.179045 1.083924 -0.053540
            +v 0.180454 1.083951 0.033275
            +v 0.176347 1.105632 0.039820
            +v 0.182420 1.107768 0.043596
            +v 0.214163 1.103067 0.032708
            +v 0.212754 1.103042 -0.054108
            +v 0.194325 1.112544 -0.064177
            +v 0.170478 1.104034 -0.053392
            +v 0.171993 1.104118 0.033421
            +v 0.191683 1.132461 0.043093
            +v 0.206267 1.116276 0.032811
            +v 0.204752 1.116188 -0.054001
            +v 0.164841 1.129279 -0.053062
            +v 0.166346 1.129366 0.033238
            +v 0.170900 1.129913 0.039598
            +v 0.183816 1.162549 0.044164
            +v 0.197904 1.133226 0.039124
            +v 0.202233 1.133766 0.032609
            +v 0.200729 1.133683 -0.053693
            +v 0.196175 1.133130 -0.060050
            +v 0.182583 1.131467 -0.064959
            +v 0.175394 1.130584 -0.063548
            +v 0.169173 1.129820 -0.059576
            +v 0.164150 1.162831 -0.052830
            +v 0.165645 1.162914 0.032962
            +v 0.170207 1.162828 0.039282
            +v 0.176571 1.162700 0.043009
            +v 0.201587 1.162155 0.032335
            +v 0.200092 1.162071 -0.053454
            +v 0.195531 1.162157 -0.059774
            +v 0.189167 1.162288 -0.063501
            +v 0.176665 1.192285 -0.062996
            +v 0.168487 1.162730 -0.059303
            +v 0.166218 1.193464 -0.052637
            +v 0.167703 1.193550 0.032639
            +v 0.189164 1.213953 0.043369
            +v 0.202019 1.210603 0.038090
            +v 0.203233 1.189635 0.032022
            +v 0.201745 1.189554 -0.053254
            +v 0.187289 1.213845 -0.064150
            +v 0.174435 1.217197 -0.058871
            +v 0.170285 1.218302 -0.052477
            +v 0.171763 1.218389 0.032288
            +v 0.176132 1.217293 0.038537
            +v 0.182227 1.215739 0.042225
            +v 0.206168 1.209496 0.031699
            +v 0.204690 1.209407 -0.053069
            +v 0.205638 1.225424 -0.059128
            +v 0.194226 1.212059 -0.063003
            +v 0.187514 1.234894 -0.062593
            +v 0.178335 1.239816 -0.052383
            +v 0.179803 1.239897 0.031871
            +v 0.183786 1.237874 0.038088
            +v 0.189334 1.234998 0.041763
            +v 0.206439 1.246959 0.042385
            +v 0.211696 1.242272 0.041048
            +v 0.196056 1.212162 0.041988
            +v 0.211087 1.223480 0.031341
            +v 0.209619 1.223399 -0.052914
            +v 0.193780 1.231594 -0.063958
            +v 0.182099 1.237778 -0.058728
            +v 0.191651 1.258524 -0.052376
            +v 0.193109 1.258608 0.031363
            +v 0.196471 1.255727 0.037555
            +v 0.216235 1.238183 0.037227
            +v 0.219378 1.235289 0.030929
            +v 0.217918 1.235207 -0.052810
            +v 0.214558 1.238086 -0.059004
            +v 0.209888 1.242169 -0.062672
            +v 0.216684 1.267215 -0.062497
            +v 0.194793 1.255633 -0.058676
            +v 0.210327 1.275367 -0.052462
            +v 0.211778 1.275451 0.030766
            +v 0.218480 1.267313 0.040589
            +v 0.250285 1.272716 0.039714
            +v 0.231019 1.251585 0.036662
            +v 0.233614 1.248208 0.030414
            +v 0.232164 1.248124 -0.052815
            +v 0.221053 1.261733 -0.063810
            +v 0.212922 1.271993 -0.058713
            +v 0.236256 1.292709 0.030066
            +v 0.238809 1.289179 0.036193
            +v 0.274608 1.297621 0.040172
            +v 0.256023 1.264176 0.029750
            +v 0.254582 1.264092 -0.052965
            +v 0.252026 1.267619 -0.059095
            +v 0.248499 1.272614 -0.062741
            +v 0.268974 1.303292 -0.062811
            +v 0.263431 1.311896 -0.052914
            +v 0.288938 1.322398 0.034698
            +v 0.291979 1.317183 0.038307
            +v 0.301726 1.299984 0.034499
            +v 0.293610 1.311095 -0.064148
            +v 0.287300 1.322304 -0.059177
            +v 0.285304 1.325997 -0.053052
            +v 0.286725 1.326078 0.028640
            +v 0.332421 1.324830 0.038164
            +v 0.303721 1.296291 0.028374
            +v 0.302298 1.296210 -0.053318
            +v 0.300088 1.299893 -0.059377
            +v 0.297046 1.305105 -0.062983
            +v 0.309065 1.326322 -0.062899
            +v 0.305712 1.335896 -0.053163
            +v 0.307126 1.335978 0.028021
            +v 0.308690 1.332026 0.034050
            +v 0.333464 1.318101 0.036948
            +v 0.298810 1.305206 0.038201
            +v 0.318902 1.303988 0.027846
            +v 0.317489 1.303906 -0.053335
            +v 0.307064 1.331932 -0.059234
            +v 0.328183 1.341471 -0.053301
            +v 0.329589 1.341550 0.027367
            +v 0.330348 1.337416 0.033374
            +v 0.331338 1.331555 0.036973
            +v 0.334327 1.312234 0.033329
            +v 0.334878 1.308085 0.027308
            +v 0.333471 1.308004 -0.053360
            +v 0.332712 1.312141 -0.059367
            +v 0.331722 1.318002 -0.062966
            +v 0.330639 1.324729 -0.064157
            +v 0.329599 1.331456 -0.062946
            +v 0.328733 1.337322 -0.059325
            +v 0.355520 1.343255 -0.053523
            +v 0.356916 1.343336 0.026632
            +v 0.392925 1.325859 0.036457
            +v 0.391750 1.319233 0.035298
            +v 0.357733 1.309671 0.026652
            +v 0.356337 1.309592 -0.053506
            +v 0.392338 1.332388 -0.063403
            +v 0.393403 1.338171 -0.059863
            +v 0.394215 1.342258 -0.053942
            +v 0.395604 1.342335 0.025704
            +v 0.394997 1.338262 0.031657
            +v 0.394054 1.332485 0.035244
            +v 0.390685 1.313453 0.031758
            +v 0.389873 1.309363 0.025835
            +v 0.388484 1.309284 -0.053809
            +v 0.389091 1.313359 -0.059764
            +v 0.390031 1.319134 -0.063348
            +v 0.391163 1.325763 -0.064562
            +v 0.436592 1.327995 -0.054408
            +v 0.437971 1.328072 0.024723
            +v 0.436491 1.324277 0.030655
            +v 0.434313 1.318902 0.034237
            +v 0.455725 1.293346 0.033574
            +v 0.426868 1.301176 0.030843
            +v 0.425181 1.297369 0.024974
            +v 0.423802 1.297290 -0.054157
            +v 0.425282 1.301087 -0.060087
            +v 0.461244 1.304407 -0.063943
            +v 0.434908 1.324186 -0.060280
            +v 0.466774 1.312716 -0.054665
            +v 0.468146 1.312792 0.023955
            +v 0.466024 1.309363 0.029859
            +v 0.462941 1.304503 0.033438
            +v 0.452518 1.288481 0.030115
            +v 0.450195 1.285040 0.024296
            +v 0.448826 1.284964 -0.054325
            +v 0.450945 1.288392 -0.060230
            +v 0.457615 1.298827 -0.065045
            +v 0.464450 1.309274 -0.060484
            +v 0.489990 1.293644 -0.054791
            +v 0.491351 1.293723 0.023314
            +v 0.488566 1.290869 0.029190
            +v 0.484540 1.286819 0.032760
            +v 0.479873 1.282171 0.034013
            +v 0.459354 1.298926 0.034679
            +v 0.471017 1.273466 0.029516
            +v 0.468027 1.270597 0.023743
            +v 0.466666 1.270523 -0.054364
            +v 0.469451 1.273379 -0.060240
            +v 0.473479 1.277427 -0.063810
            +v 0.478146 1.282072 -0.065060
            +v 0.482853 1.286722 -0.063982
            +v 0.487002 1.290778 -0.060566
            +v 0.509206 1.269622 -0.054848
            +v 0.510558 1.269701 0.022747
            +v 0.507378 1.267350 0.028593
            +v 0.516370 1.230710 0.032777
            +v 0.510837 1.227232 0.031726
            +v 0.487434 1.253023 0.028953
            +v 0.484052 1.250660 0.023228
            +v 0.482700 1.250583 -0.054367
            +v 0.520201 1.234090 -0.063948
            +v 0.505824 1.267262 -0.060576
            +v 0.528563 1.239268 -0.054899
            +v 0.529905 1.239342 0.022182
            +v 0.526612 1.237211 0.027991
            +v 0.525840 1.184793 0.022051
            +v 0.528038 1.186357 -0.060292
            +v 0.509174 1.227138 -0.063748
            +v 0.514665 1.230614 -0.064996
            +v 0.550119 1.196370 -0.060687
            +v 0.555186 1.198096 0.021528
            +v 0.551651 1.196456 0.027303
            +v 0.546569 1.194127 0.030818
            +v 0.521863 1.234181 0.031526
            +v 0.534775 1.188779 0.031030
            +v 0.529572 1.186443 0.027695
            +v 0.524505 1.184719 -0.054517
            +v 0.533122 1.188683 -0.063810
            +v 0.539001 1.191357 -0.065058
            +v 0.544916 1.194034 -0.064022
            +v 0.553851 1.198022 -0.055042
            +v 0.565546 1.164264 0.021123
            +v 0.556550 1.161474 0.030359
            +v 0.550417 1.159599 0.031603
            +v 0.538821 1.156074 0.027271
            +v 0.533606 1.154836 -0.054391
            +v 0.542602 1.157621 -0.063627
            +v 0.558471 1.127644 -0.064685
            +v 0.560331 1.163025 -0.060539
            +v 0.554581 1.091255 0.020874
            +v 0.556915 1.092319 -0.059821
            +v 0.604053 1.036711 0.019555
            +v 0.581156 1.099349 0.026000
            +v 0.569866 1.095881 0.030678
            +v 0.563773 1.094023 0.029669
            +v 0.568208 1.095785 -0.064495
            +v 0.574301 1.097642 -0.063484
            +v 0.583492 1.100412 -0.054695
            +v 0.595289 1.033993 0.028541
            +v 0.583302 1.030332 0.028756
            +v 0.578019 1.028734 0.025537
            +v 0.572939 1.027525 -0.053927
            +v 0.581704 1.030241 -0.062914
            +v 0.598974 1.035505 -0.059910
            +v 0.610393 1.002580 0.024705
            +v 0.599038 1.000306 0.029289
            +v 0.583677 0.997272 0.019693
            +v 0.586063 0.997940 -0.059352
            +v 0.597415 1.000214 -0.063938
            +v 0.593693 1.033904 -0.063126
            +v 0.614056 1.003323 0.019157
            +v 0.605127 1.001522 0.028087
            +v 0.592916 0.999090 0.028300
            +v 0.587533 0.998026 0.025105
            +v 0.582397 0.997198 -0.053807
            +v 0.591329 0.998998 -0.062734
            +v 0.603538 1.001431 -0.062951
            +v 0.608921 1.002496 -0.059754
            +v 0.612776 1.003249 -0.054339
            +v 0.618798 0.954223 0.018866
            +v 0.609794 0.953293 0.027735
            +v 0.603664 0.952661 0.028931
            +v 0.597492 0.952030 0.027949
            +v 0.592070 0.951475 0.024779
            +v 0.590609 0.951393 -0.059091
            +v 0.602048 0.952570 -0.063647
            +v 0.608220 0.953202 -0.062665
            +v 0.613640 0.953757 -0.059495
            +v 0.621134 0.919667 -0.053890
            +v 0.622397 0.919739 0.018583
            +v 0.619311 0.891277 0.023773
            +v 0.601890 0.892505 0.027298
            +v 0.596527 0.892873 0.024170
            +v 0.591904 0.917706 0.019115
            +v 0.590639 0.917637 -0.053358
            +v 0.599608 0.918237 -0.062162
            +v 0.612507 0.891563 -0.062046
            +v 0.617870 0.891193 -0.058918
            +v 0.621711 0.890936 -0.053617
            +v 0.622967 0.891008 0.018346
            +v 0.614061 0.891652 0.027088
            +v 0.592686 0.893129 0.018871
            +v 0.591431 0.893060 -0.053091
            +v 0.595087 0.892794 -0.058521
            +v 0.606402 0.891990 -0.063010
            +v 0.616844 0.862363 -0.053247
            +v 0.618090 0.862432 0.018203
            +v 0.614572 0.863384 0.023590
            +v 0.592341 0.834826 0.027944
            +v 0.607995 0.892079 0.028265
            +v 0.592627 0.869122 0.023968
            +v 0.588922 0.870062 0.018704
            +v 0.587679 0.869990 -0.052746
            +v 0.591196 0.869041 -0.058136
            +v 0.596352 0.832438 -0.061069
            +v 0.613141 0.863300 -0.058513
            +v 0.604774 0.829029 -0.052748
            +v 0.606010 0.829098 0.018188
            +v 0.602679 0.830519 0.023536
            +v 0.597884 0.832527 0.026792
            +v 0.586763 0.837125 0.026982
            +v 0.581857 0.839123 0.023891
            +v 0.578342 0.840536 0.018662
            +v 0.577106 0.840465 -0.052277
            +v 0.580438 0.839042 -0.057625
            +v 0.585231 0.837036 -0.060881
            +v 0.590774 0.834737 -0.062031
            +v 0.601259 0.830440 -0.057978
            +v 0.584408 0.783427 0.018353
            +v 0.581383 0.785390 0.023659
            +v 0.577027 0.788163 0.026881
            +v 0.571985 0.791345 0.028018
            +v 0.566905 0.794523 0.027054
            +v 0.562438 0.797293 0.023978
            +v 0.559231 0.799244 0.018780
            +v 0.558005 0.799175 -0.051646
            +v 0.561029 0.797214 -0.056949
            +v 0.565386 0.794436 -0.060173
            +v 0.570428 0.791256 -0.061311
            +v 0.575507 0.788079 -0.060346
            +v 0.579975 0.785309 -0.057270
            +v 0.555018 0.761164 0.026975
            +v 0.524303 0.742203 0.027212
            +v 0.541754 0.771929 0.024069
            +v 0.553508 0.761075 -0.059618
            +v 0.583182 0.783358 -0.052067
            +v 0.540086 0.729208 0.018667
            +v 0.537365 0.731507 0.023891
            +v 0.528887 0.738484 0.028171
            +v 0.516155 0.747668 -0.050355
            +v 0.518876 0.745369 -0.055575
            +v 0.527355 0.738395 -0.059858
            +v 0.535974 0.731428 -0.055859
            +v 0.494149 0.678742 0.024106
            +v 0.511856 0.708351 0.027145
            +v 0.502787 0.715747 0.027298
            +v 0.498779 0.718966 0.024279
            +v 0.495895 0.721240 0.019189
            +v 0.475921 0.692408 -0.054186
            +v 0.501300 0.715663 -0.058027
            +v 0.510368 0.708267 -0.058180
            +v 0.495641 0.676411 -0.049413
            +v 0.453651 0.623835 0.019254
            +v 0.468693 0.655541 0.027313
            +v 0.485791 0.685619 0.028327
            +v 0.477290 0.692487 0.024387
            +v 0.430248 0.641591 -0.047728
            +v 0.458288 0.662747 -0.056592
            +v 0.484279 0.685533 -0.058402
            +v 0.492780 0.678665 -0.054468
            +v 0.450986 0.626045 0.024323
            +v 0.442693 0.632755 0.028477
            +v 0.459754 0.662831 0.027463
            +v 0.417475 0.619659 -0.052213
            +v 0.425761 0.613067 -0.056338
            +v 0.467228 0.655460 -0.056740
            +v 0.447143 0.629176 0.027399
            +v 0.438208 0.636337 0.027547
            +v 0.434261 0.639457 0.024599
            +v 0.431422 0.641655 0.019624
            +v 0.445690 0.629089 -0.056022
            +v 0.449637 0.625971 -0.053074
            +v 0.420010 0.587005 0.024313
            +v 0.411784 0.593550 0.028408
            +v 0.403421 0.600084 0.024587
            +v 0.390492 0.577330 -0.054058
            +v 0.452476 0.623771 -0.048096
            +v 0.376491 0.557783 0.027431
            +v 0.385231 0.582562 0.019720
            +v 0.384086 0.582498 -0.046095
            +v 0.399289 0.570398 -0.054201
            +v 0.418681 0.586931 -0.051905
            +v 0.391583 0.545770 0.019389
            +v 0.400710 0.570475 0.027313
            +v 0.357239 0.541127 0.024567
            +v 0.355942 0.541055 -0.049884
            +v 0.379429 0.554260 -0.054497
            +v 0.405969 0.565243 -0.046458
            +v 0.373461 0.528339 0.024298
            +v 0.380874 0.554342 0.028334
            +v 0.336979 0.522019 -0.044447
            +v 0.372164 0.528267 -0.050153
            +v 0.354654 0.512339 0.027222
            +v 0.338099 0.522083 0.019831
            +v 0.360404 0.508106 -0.044842
            +v 0.361524 0.508170 0.019436
            +v 0.349962 0.515136 0.028260
            +v 0.345238 0.517931 0.027382
            +v 0.339794 0.520295 -0.049290
            +v 0.343852 0.517850 -0.052233
            +v 0.353265 0.512258 -0.052391
            +v 0.355236 0.493500 0.019303
            +v 0.332376 0.473368 0.026699
            +v 0.328713 0.486758 0.024237
            +v 0.329821 0.502723 0.019740
            +v 0.328710 0.502659 -0.044026
            +v 0.342611 0.483788 -0.051542
            +v 0.350623 0.482298 -0.044132
            +v 0.351726 0.482362 0.019120
            +v 0.325368 0.487372 0.019574
            +v 0.324268 0.487311 -0.043678
            +v 0.327445 0.486684 -0.048451
            +v 0.332016 0.485803 -0.051359
            +v 0.349802 0.474004 -0.043853
            +v 0.339532 0.462383 0.027197
            +v 0.327665 0.473188 0.023973
            +v 0.324290 0.473060 0.019355
            +v 0.323197 0.472998 -0.043389
            +v 0.336353 0.473494 -0.052040
            +v 0.351132 0.465449 -0.043614
            +v 0.352217 0.465514 0.018617
            +v 0.349121 0.464742 0.023314
            +v 0.326557 0.459236 0.019069
            +v 0.325471 0.459176 -0.043157
            +v 0.328567 0.459948 -0.047854
            +v 0.341116 0.429426 0.022900
            +v 0.338045 0.428232 0.018388
            +v 0.361139 0.437781 -0.043246
            +v 0.362205 0.437843 0.017959
            +v 0.355108 0.434977 0.025389
            +v 0.336979 0.428173 -0.042814
            +v 0.339890 0.429357 -0.047432
            +v 0.348916 0.432971 -0.051246
            +v 0.336997 0.428260 -0.039869
            +v 0.344627 0.431343 -0.050062
            +v 0.354220 0.435216 -0.050062
            +v 0.361847 0.438302 -0.039869
            +v 0.361847 0.438302 0.015035
            +v 0.354220 0.435216 0.025228
            +v 0.344627 0.431343 0.025228
            +v 0.336997 0.428260 0.015035
            +v 0.341242 0.422051 -0.039223
            +v 0.347915 0.424747 -0.048103
            +v 0.357188 0.423205 -0.044156
            +v 0.363110 0.430884 0.014389
            +v 0.356435 0.428186 0.023272
            +v 0.350835 0.420639 0.019323
            +v 0.361934 0.425124 -0.037923
            +v 0.346089 0.418723 0.013089
            +v 0.361934 0.425124 0.013089
            +v 0.357967 0.420879 0.010982
            +v 0.346089 0.418723 -0.037923
            +v 0.357967 0.420879 -0.035813
            +v 0.211844 1.015117 -0.049951
            +v 0.217767 1.017243 -0.059295
            +v 0.242571 1.026148 -0.064439
            +v 0.250263 1.028911 -0.059295
            +v 0.256186 1.031038 -0.049951
            +v 0.256186 1.031038 0.028070
            +v 0.250263 1.028911 0.037414
            +v 0.225456 1.020003 0.042555
            +v 0.217767 1.017243 0.037414
            +v 0.211844 1.015117 0.028070
            +v 0.218872 1.003912 -0.049038
            +v 0.223996 1.005755 -0.057124
            +v 0.230780 1.008190 -0.061658
            +v 0.238380 1.010918 -0.063136
            +v 0.245980 1.013649 -0.061658
            +v 0.257890 1.017921 0.027155
            +v 0.252764 1.016081 0.035244
            +v 0.245980 1.013649 0.039778
            +v 0.238380 1.010918 0.041255
            +v 0.230780 1.008190 0.039778
            +v 0.252784 1.011515 -0.055454
            +v 0.257298 1.013136 -0.048333
            +v 0.226885 1.002215 0.033571
            +v 0.222373 1.000597 0.026452
            +v 0.227153 0.997735 0.025307
            +v 0.227153 0.997735 -0.047188
            +v 0.235625 1.000779 -0.056049
            +v 0.255428 1.007889 -0.047188
            +v 0.255428 1.007889 0.025307
            +v 0.246957 1.004847 0.034168
            +v 0.237324 0.996815 0.022308
            +v 0.237324 0.996815 -0.044191
            +v 0.248166 1.000705 -0.044191
            +v 0.248166 1.000705 0.022308
            +v -0.455997 0.429730 -0.007669
            +v -0.447170 0.419204 -0.002827
            +v -0.447170 0.419204 -0.002827
            +v -0.447170 0.419204 -0.002827
            +v -0.447170 0.419204 -0.002827
            +v -0.447294 0.419268 -0.000745
            +v -0.447294 0.419268 -0.000745
            +v -0.455654 0.429717 -0.022357
            +v -0.455866 0.429727 -0.015181
            +v -0.464946 0.440798 -0.020793
            +v -0.455866 0.429727 -0.015181
            +v -0.455997 0.429730 -0.007669
            +v -0.465208 0.440806 -0.010528
            +v -0.455866 0.429727 -0.015181
            +v -0.465208 0.440806 -0.010528
            +v -0.464946 0.440798 -0.020793
            +v -0.455997 0.429730 -0.007669
            +v -0.456041 0.429730 0.000116
            +v -0.465297 0.440811 0.000116
            +v -0.456041 0.429730 0.000116
            +v -0.455821 0.429727 0.017196
            +v -0.464857 0.440796 0.023460
            +v -0.456041 0.429730 0.000116
            +v -0.464857 0.440796 0.023460
            +v -0.465297 0.440811 0.000116
            +v -0.455654 0.429717 -0.022357
            +v -0.447170 0.419204 -0.002827
            +v -0.455866 0.429727 -0.015181
            +v -0.455866 0.429727 -0.015181
            +v -0.447170 0.419204 -0.002827
            +v -0.455997 0.429730 -0.007669
            +v -0.455997 0.429730 -0.007669
            +v -0.447170 0.419204 -0.002827
            +v -0.456041 0.429730 0.000116
            +v -0.456041 0.429730 0.000116
            +v -0.447294 0.419268 -0.000745
            +v -0.455821 0.429727 0.017196
            +v -0.447294 0.419268 -0.000745
            +v -0.456041 0.429730 0.000116
            +v -0.447170 0.419204 -0.002827
            +v -0.450774 0.405641 0.000372
            +v -0.447350 0.405641 -0.051609
            +v -0.444615 0.335790 -0.051246
            +v -0.448016 0.335790 0.000372
            +v -0.450774 0.405641 0.000372
            +v -0.444615 0.335790 -0.051246
            +v -0.447350 0.405641 0.052354
            +v -0.450774 0.405641 0.000372
            +v -0.448016 0.335790 0.000372
            +v -0.450774 0.405641 0.000372
            +v -0.447350 0.405641 0.052354
            +v -0.446926 0.419714 0.005351
            +v -0.450774 0.405641 0.000372
            +v -0.446926 0.419714 0.005351
            +v -0.447032 0.419529 0.004448
            +v -0.444874 0.426010 -0.011900
            +v -0.447350 0.405641 -0.051609
            +v -0.450774 0.405641 0.000372
            +v -0.450774 0.405641 0.000372
            +v -0.446230 0.421389 -0.008836
            +v -0.444874 0.426010 -0.011900
            +v -0.446600 0.420267 -0.007472
            +v -0.446230 0.421389 -0.008836
            +v -0.450774 0.405641 0.000372
            +v -0.446785 0.419783 -0.006510
            +v -0.446600 0.420267 -0.007472
            +v -0.450774 0.405641 0.000372
            +v -0.446901 0.419527 -0.005711
            +v -0.446785 0.419783 -0.006510
            +v -0.450774 0.405641 0.000372
            +v -0.446988 0.419372 -0.004983
            +v -0.446901 0.419527 -0.005711
            +v -0.450774 0.405641 0.000372
            +v -0.447027 0.419315 -0.004603
            +v -0.446988 0.419372 -0.004983
            +v -0.450774 0.405641 0.000372
            +v -0.447062 0.419275 -0.004238
            +v -0.447027 0.419315 -0.004603
            +v -0.450774 0.405641 0.000372
            +v -0.447062 0.419275 -0.004238
            +v -0.450774 0.405641 0.000372
            +v -0.447091 0.419246 -0.003888
            +v -0.447121 0.419223 -0.003537
            +v -0.447091 0.419246 -0.003888
            +v -0.450774 0.405641 0.000372
            +v -0.447121 0.419223 -0.003537
            +v -0.450774 0.405641 0.000372
            +v -0.447148 0.419211 -0.003185
            +v -0.447170 0.419204 -0.002827
            +v -0.447148 0.419211 -0.003185
            +v -0.450774 0.405641 0.000372
            +v -0.450774 0.405641 0.000372
            +v -0.447294 0.419268 -0.000745
            +v -0.447170 0.419204 -0.002827
            +v -0.447294 0.419268 -0.000745
            +v -0.450774 0.405641 0.000372
            +v -0.447345 0.419342 0.000326
            +v -0.450774 0.405641 0.000372
            +v -0.447348 0.419347 0.000372
            +v -0.447345 0.419342 0.000326
            +v -0.450774 0.405641 0.000372
            +v -0.447294 0.419327 0.001238
            +v -0.447348 0.419347 0.000372
            +v -0.447294 0.419327 0.001238
            +v -0.450774 0.405641 0.000372
            +v -0.447239 0.419332 0.002055
            +v -0.447239 0.419332 0.002055
            +v -0.450774 0.405641 0.000372
            +v -0.447183 0.419359 0.002834
            +v -0.450774 0.405641 0.000372
            +v -0.447032 0.419529 0.004448
            +v -0.447116 0.419421 0.003616
            +v -0.447183 0.419359 0.002834
            +v -0.450774 0.405641 0.000372
            +v -0.447116 0.419421 0.003616
            +vt 0.962593 0.249558
            +vt 0.968968 0.255967
            +vt 0.970168 0.256025
            +vt 0.961750 0.249528
            +vt 0.959625 0.249502
            +vt 0.956424 0.249479
            +vt 0.952373 0.249462
            +vt 0.939330 0.247459
            +vt 0.933561 0.249462
            +vt 0.927504 0.262205
            +vt 0.930132 0.249479
            +vt 0.927608 0.249502
            +vt 0.922291 0.255913
            +vt 0.926105 0.249528
            +vt 0.925735 0.249558
            +vt 0.920472 0.255967
            +vt 0.926054 0.249574
            +vt 0.926723 0.249590
            +vt 0.927716 0.249606
            +vt 0.923043 0.256121
            +vt 0.930581 0.249631
            +vt 0.929010 0.249619
            +vt 0.932407 0.249643
            +vt 0.937724 0.249662
            +vt 0.935820 0.249656
            +vt 0.939275 0.256241
            +vt 0.941865 0.249668
            +vt 0.942127 0.256246
            +vt 0.945101 0.256248
            +vt 0.948971 0.249665
            +vt 0.951699 0.256240
            +vt 0.943532 0.243574
            +vt 0.960798 0.262781
            +vt 0.957215 0.249636
            +vt 0.960153 0.249614
            +vt 0.966864 0.256138
            +vt 0.962016 0.249587
            +vt 0.975388 0.262493
            +vt 0.970353 0.262325
            +vt 0.967495 0.268646
            +vt 0.959765 0.268577
            +vt 0.920042 0.268646
            +vt 0.917393 0.262543
            +vt 0.929416 0.256195
            +vt 0.934044 0.249650
            +vt 0.969801 0.269275
            +vt 0.977637 0.268843
            +vt 0.951639 0.295763
            +vt 0.914403 0.275148
            +vt 0.912546 0.275281
            +vt 0.914358 0.268961
            +vt 0.918545 0.269151
            +vt 0.926942 0.269299
            +vt 0.966587 0.282472
            +vt 0.977583 0.275708
            +vt 0.981096 0.275577
            +vt 0.979250 0.268961
            +vt 0.976055 0.275148
            +vt 0.934085 0.262171
            +vt 0.916897 0.281425
            +vt 0.912894 0.281996
            +vt 0.914646 0.282092
            +vt 0.973873 0.282368
            +vt 0.982521 0.281719
            +vt 0.962618 0.292221
            +vt 0.921887 0.288588
            +vt 0.913028 0.281560
            +vt 0.911287 0.281719
            +vt 0.911722 0.281896
            +vt 0.916929 0.282181
            +vt 0.922916 0.282339
            +vt 0.939124 0.305008
            +vt 0.943165 0.305044
            +vt 0.961265 0.305037
            +vt 0.979574 0.282233
            +vt 0.983235 0.282073
            +vt 0.979172 0.288872
            +vt 0.971804 0.288712
            +vt 0.977427 0.304767
            +vt 0.986255 0.303748
            +vt 0.984350 0.281896
            +vt 0.914588 0.304334
            +vt 0.917315 0.304475
            +vt 0.920506 0.304605
            +vt 0.924119 0.304723
            +vt 0.951711 0.305074
            +vt 0.969946 0.304931
            +vt 0.983307 0.304556
            +vt 0.920580 0.299489
            +vt 0.914577 0.299643
            +vt 0.910980 0.299842
            +vt 0.909521 0.303748
            +vt 0.910737 0.304026
            +vt 0.912376 0.304184
            +vt 0.987110 0.304306
            +vt 0.981151 0.303498
            +vt 0.973267 0.303286
            +vt 0.928115 0.304826
            +vt 0.988261 0.304026
            +vt 0.929007 0.299389
            +vt 0.989167 0.333560
            +vt 0.991282 0.333938
            +vt 0.983661 0.333221
            +vt 0.975015 0.332934
            +vt 0.963791 0.332712
            +vt 0.950926 0.332570
            +vt 0.917114 0.332712
            +vt 0.925929 0.332570
            +vt 0.911233 0.332934
            +vt 0.908139 0.333221
            +vt 0.907653 0.333560
            +vt 0.909655 0.333938
            +vt 0.911746 0.334151
            +vt 0.914390 0.334354
            +vt 0.917521 0.334545
            +vt 0.921087 0.334721
            +vt 0.925041 0.334881
            +vt 0.929342 0.335021
            +vt 0.936896 0.335202
            +vt 0.945124 0.335316
            +vt 0.953909 0.335357
            +vt 0.963652 0.335306
            +vt 0.972475 0.335164
            +vt 0.980091 0.334942
            +vt 0.986118 0.334654
            +vt 0.990059 0.334315
            +vt 0.990508 0.363322
            +vt 0.992691 0.363780
            +vt 0.984744 0.362911
            +vt 0.975576 0.362561
            +vt 0.963569 0.362292
            +vt 0.914535 0.362292
            +vt 0.908908 0.362561
            +vt 0.906299 0.362911
            +vt 0.906430 0.363322
            +vt 0.909104 0.363780
            +vt 0.911557 0.364039
            +vt 0.914532 0.364285
            +vt 0.917960 0.364517
            +vt 0.921785 0.364732
            +vt 0.925960 0.364925
            +vt 0.930443 0.365095
            +vt 0.934247 0.365214
            +vt 0.938210 0.365314
            +vt 0.942318 0.365394
            +vt 0.946556 0.365453
            +vt 0.950912 0.365490
            +vt 0.955378 0.365503
            +vt 0.965095 0.365441
            +vt 0.973868 0.365268
            +vt 0.981447 0.364999
            +vt 0.987472 0.364650
            +vt 0.991444 0.364238
            +vt 0.990559 0.393041
            +vt 0.992815 0.393564
            +vt 0.984615 0.392571
            +vt 0.975096 0.392173
            +vt 0.962563 0.391866
            +vt 0.907074 0.392173
            +vt 0.912334 0.391866
            +vt 0.904979 0.392571
            +vt 0.905689 0.393041
            +vt 0.908943 0.393564
            +vt 0.911690 0.393859
            +vt 0.914918 0.394141
            +vt 0.918560 0.394406
            +vt 0.922559 0.394650
            +vt 0.926866 0.394871
            +vt 0.931442 0.395066
            +vt 0.935291 0.395200
            +vt 0.939276 0.395315
            +vt 0.943380 0.395407
            +vt 0.947593 0.395474
            +vt 0.951905 0.395516
            +vt 0.956306 0.395530
            +vt 0.965841 0.395460
            +vt 0.974417 0.395262
            +vt 0.981823 0.394955
            +vt 0.987720 0.394556
            +vt 0.991616 0.394087
            +vt 0.989440 0.422726
            +vt 0.991804 0.423302
            +vt 0.983361 0.422208
            +vt 0.973629 0.421770
            +vt 0.960797 0.421432
            +vt 0.905689 0.421770
            +vt 0.910473 0.421432
            +vt 0.904145 0.422208
            +vt 0.905414 0.422726
            +vt 0.909181 0.423302
            +vt 0.912168 0.423627
            +vt 0.915592 0.423937
            +vt 0.919383 0.424229
            +vt 0.923486 0.424498
            +vt 0.927854 0.424741
            +vt 0.932447 0.424955
            +vt 0.936280 0.425104
            +vt 0.940223 0.425230
            +vt 0.944261 0.425331
            +vt 0.948385 0.425405
            +vt 0.952586 0.425452
            +vt 0.956857 0.425467
            +vt 0.966063 0.425390
            +vt 0.974303 0.425172
            +vt 0.981400 0.424833
            +vt 0.987039 0.424395
            +vt 0.990741 0.423877
            +vt 0.987204 0.452388
            +vt 0.989732 0.453008
            +vt 0.981014 0.451831
            +vt 0.971186 0.451358
            +vt 0.958271 0.450994
            +vt 0.904754 0.451358
            +vt 0.908944 0.450994
            +vt 0.903819 0.451831
            +vt 0.905650 0.452388
            +vt 0.909889 0.453008
            +vt 0.913077 0.453359
            +vt 0.916648 0.453693
            +vt 0.920534 0.454007
            +vt 0.924681 0.454297
            +vt 0.929044 0.454559
            +vt 0.933585 0.454790
            +vt 0.937345 0.454951
            +vt 0.941186 0.455086
            +vt 0.945096 0.455195
            +vt 0.949068 0.455275
            +vt 0.953092 0.455325
            +vt 0.957166 0.455341
            +vt 0.965890 0.455258
            +vt 0.973647 0.455024
            +vt 0.980289 0.454659
            +vt 0.985530 0.454186
            +vt 0.988909 0.453629
            +vt 0.984094 0.482149
            +vt 0.977971 0.481577
            +vt 0.968434 0.481092
            +vt 0.956031 0.480717
            +vt 0.942003 0.480476
            +vt 0.905915 0.481092
            +vt 0.909583 0.480717
            +vt 0.905381 0.481577
            +vt 0.907495 0.482149
            +vt 0.911888 0.482785
            +vt 0.917741 0.499714
            +vt 0.919604 0.489793
            +vt 0.923249 0.490098
            +vt 0.927132 0.490380
            +vt 0.930729 0.484377
            +vt 0.935223 0.486825
            +vt 0.938678 0.484778
            +vt 0.942326 0.484917
            +vt 0.946023 0.485028
            +vt 0.949761 0.485111
            +vt 0.953533 0.485161
            +vt 0.957335 0.485179
            +vt 0.965429 0.485094
            +vt 0.972564 0.484853
            +vt 0.978212 0.490731
            +vt 0.983328 0.483993
            +vt 0.986263 0.483422
            +vt 0.916895 0.480476
            +vt 0.917218 0.481057
            +vt 0.917503 0.481633
            +vt 0.943601 0.486944
            +vt 0.908355 0.487526
            +vt 0.907511 0.487985
            +vt 0.983610 0.488526
            +vt 0.956900 0.487172
            +vt 0.977737 0.487985
            +vt 0.968655 0.487526
            +vt 0.912203 0.487172
            +vt 0.909251 0.488526
            +vt 0.931903 0.500807
            +vt 0.919472 0.486944
            +vt 0.984672 0.499960
            +vt 0.986765 0.482785
            +vt 0.930362 0.486863
            +vt 0.939334 0.501163
            +vt 0.942775 0.501286
            +vt 0.976099 0.508622
            +vt 0.968457 0.497894
            +vt 0.957458 0.497562
            +vt 0.945029 0.497348
            +vt 0.932575 0.497272
            +vt 0.922181 0.497348
            +vt 0.915069 0.497562
            +vt 0.911120 0.497894
            +vt 0.936506 0.511168
            +vt 0.971054 0.511369
            +vt 0.976636 0.511054
            +vt 0.981929 0.500467
            +vt 0.985102 0.499395
            +vt 0.945959 0.507699
            +vt 0.934204 0.507628
            +vt 0.924290 0.507699
            +vt 0.917385 0.507902
            +vt 0.913426 0.508216
            +vt 0.912153 0.508622
            +vt 0.919566 0.530072
            +vt 0.921852 0.530345
            +vt 0.924503 0.530605
            +vt 0.927458 0.530850
            +vt 0.930667 0.531075
            +vt 0.946887 0.531776
            +vt 0.963071 0.541951
            +vt 0.982279 0.520366
            +vt 0.980178 0.519352
            +vt 0.967369 0.518511
            +vt 0.957604 0.518212
            +vt 0.946605 0.518020
            +vt 0.978651 0.530989
            +vt 0.982564 0.519860
            +vt 0.970435 0.555644
            +vt 0.936576 0.528253
            +vt 0.927622 0.528318
            +vt 0.921230 0.528501
            +vt 0.917409 0.528785
            +vt 0.920564 0.555644
            +vt 0.921129 0.556033
            +vt 0.934088 0.531280
            +vt 0.937683 0.531460
            +vt 0.940678 0.531585
            +vt 0.956246 0.552137
            +vt 0.968894 0.541776
            +vt 0.973745 0.541505
            +vt 0.974814 0.556033
            +vt 0.965717 0.539044
            +vt 0.956563 0.549029
            +vt 0.947448 0.548861
            +vt 0.953167 0.587881
            +vt 0.976187 0.562886
            +vt 0.938941 0.560868
            +vt 0.931546 0.560925
            +vt 0.925350 0.555059
            +vt 0.920952 0.549290
            +vt 0.923493 0.556467
            +vt 0.926262 0.562701
            +vt 0.928509 0.562930
            +vt 0.931031 0.563144
            +vt 0.933780 0.563342
            +vt 0.941219 0.587544
            +vt 0.943519 0.587645
            +vt 0.948278 0.587799
            +vt 0.950711 0.587849
            +vt 0.963511 0.561335
            +vt 0.955929 0.561085
            +vt 0.947446 0.572972
            +vt 0.924520 0.573365
            +vt 0.972254 0.581192
            +vt 0.972156 0.574040
            +vt 0.966649 0.585678
            +vt 0.923271 0.573674
            +vt 0.923775 0.574040
            +vt 0.976104 0.562462
            +vt 0.954633 0.585150
            +vt 0.939969 0.584950
            +vt 0.933579 0.585002
            +vt 0.960843 0.587839
            +vt 0.965317 0.587691
            +vt 0.968946 0.587461
            +vt 0.961239 0.585381
            +vt 0.928901 0.585150
            +vt 0.927372 0.586420
            +vt 0.955637 0.587892
            +vt 0.970402 0.606713
            +vt 0.947337 0.585002
            +vt 0.927091 0.595377
            +vt 0.931029 0.606554
            +vt 0.932874 0.606751
            +vt 0.939602 0.607263
            +vt 0.967987 0.605980
            +vt 0.927101 0.605651
            +vt 0.927567 0.605980
            +vt 0.934944 0.606936
            +vt 0.937197 0.607107
            +vt 0.969329 0.607042
            +vt 0.962508 0.625622
            +vt 0.931261 0.626269
            +vt 0.946851 0.637327
            +vt 0.964827 0.635902
            +vt 0.941681 0.645007
            +vt 0.931714 0.645354
            +vt 0.929110 0.625622
            +vt 0.929539 0.625928
            +vt 0.948788 0.647303
            +vt 0.970021 0.606346
            +vt 0.956878 0.645354
            +vt 0.952091 0.645169
            +vt 0.946894 0.645050
            +vt 0.937149 0.645050
            +vt 0.933806 0.645169
            +vt 0.934139 0.646371
            +vt 0.935681 0.646540
            +vt 0.937411 0.646699
            +vt 0.939298 0.646847
            +vt 0.943423 0.647098
            +vt 0.954310 0.647377
            +vt 0.963888 0.647031
            +vt 0.957742 0.658912
            +vt 0.960788 0.658799
            +vt 0.965584 0.646790
            +vt 0.966287 0.646507
            +vt 0.959675 0.668931
            +vt 0.934627 0.669472
            +vt 0.962406 0.669188
            +vt 0.965779 0.646192
            +vt 0.956075 0.668714
            +vt 0.935638 0.668546
            +vt 0.931972 0.657264
            +vt 0.933259 0.669188
            +vt 0.947135 0.658830
            +vt 0.950646 0.670515
            +vt 0.963161 0.658624
            +vt 0.939804 0.691805
            +vt 0.935364 0.692062
            +vt 0.939320 0.681560
            +vt 0.942230 0.670185
            +vt 0.945722 0.670366
            +vt 0.953903 0.682152
            +vt 0.964034 0.670014
            +vt 0.951728 0.691906
            +vt 0.947587 0.691805
            +vt 0.943435 0.691770
            +vt 0.935533 0.703961
            +vt 0.957196 0.682115
            +vt 0.959937 0.682011
            +vt 0.961656 0.693474
            +vt 0.963448 0.693034
            +vt 0.958724 0.703961
            +vt 0.955608 0.703769
            +vt 0.937094 0.691906
            +vt 0.936878 0.704439
            +vt 0.936524 0.681273
            +vt 0.939873 0.693195
            +vt 0.943091 0.693431
            +vt 0.947783 0.693657
            +vt 0.962636 0.704916
            +vt 0.961366 0.730831
            +vt 0.962930 0.692767
            +vt 0.951960 0.703622
            +vt 0.948022 0.703527
            +vt 0.936276 0.703769
            +vt 0.937548 0.728335
            +vt 0.953831 0.717006
            +vt 0.956781 0.721909
            +vt 0.959269 0.716886
            +vt 0.961180 0.716749
            +vt 0.956357 0.727976
            +vt 0.944880 0.715250
            +vt 0.941528 0.715281
            +vt 0.938975 0.715369
            +vt 0.938440 0.728552
            +vt 0.939648 0.716385
            +vt 0.942845 0.729001
            +vt 0.945442 0.716798
            +vt 0.950979 0.716981
            +vt 0.940622 0.754602
            +vt 0.937531 0.728141
            +vt 0.963030 0.731262
            +vt 0.954736 0.754464
            +vt 0.951633 0.759224
            +vt 0.954069 0.731855
            +vt 0.939779 0.734384
            +vt 0.959300 0.729254
            +vt 0.961417 0.734837
            +vt 0.962661 0.734672
            +vt 0.956958 0.731826
            +vt 0.942224 0.754464
            +vt 0.960153 0.746719
            +vt 0.943292 0.734710
            +vt 0.946241 0.734882
            +vt 0.948583 0.731766
            +vt 0.951304 0.731832
            +vt 0.960260 0.744671
            +vt 0.962664 0.731046
            +vt 0.958302 0.759456
            +vt 0.955114 0.744787
            +vt 0.964413 0.755460
            +vt 0.947208 0.744585
            +vt 0.957918 0.744756
            +vt 0.963101 0.759854
            +vt 0.947749 0.754343
            +vt 0.944621 0.754375
            +vt 0.940327 0.759854
            +vt 0.939848 0.754780
            +vt 0.941744 0.764981
            +vt 0.942699 0.755484
            +vt 0.951925 0.756052
            +vt 0.963172 0.760731
            +vt 0.963957 0.755670
            +vt 0.945179 0.755712
            +vt 0.949025 0.765687
            +vt 0.955006 0.760989
            +vt 0.959094 0.760964
            +vt 0.961394 0.760873
            +vt 0.955557 0.764182
            +vt 0.948564 0.764056
            +vt 0.965569 0.779518
            +vt 0.962065 0.769417
            +vt 0.959348 0.769226
            +vt 0.952682 0.768984
            +vt 0.946038 0.768984
            +vt 0.943647 0.769079
            +vt 0.942057 0.769226
            +vt 0.941299 0.769417
            +vt 0.945247 0.780011
            +vt 0.952647 0.775659
            +vt 0.966499 0.780198
            +vt 0.967045 0.779987
            +vt 0.964858 0.764981
            +vt 0.956153 0.769079
            +vt 0.960669 0.775727
            +vt 0.962976 0.775633
            +vt 0.965248 0.780377
            +vt 0.963600 0.779306
            +vt 0.960976 0.779127
            +vt 0.955011 0.779794
            +vt 0.949967 0.773888
            +vt 0.946836 0.773922
            +vt 0.942717 0.779518
            +vt 0.948650 0.775447
            +vt 0.957911 0.775760
            +vt 0.966754 0.779752
            +vt 0.958697 0.779881
            +vt 0.945346 0.778989
            +vt 0.943654 0.779127
            +vt 0.943508 0.779752
            +vt 0.947628 0.780240
            +vt 0.952580 0.781401
            +vt 0.955579 0.780611
            +vt 0.958311 0.782354
            +vt 0.961477 0.782323
            +vt 0.964182 0.782238
            +vt 0.967269 0.781281
            +vt 0.965208 0.781078
            +vt 0.942038 0.781963
            +vt 0.941675 0.781281
            +vt 0.948118 0.782069
            +vt 0.967866 0.781934
            +vt 0.968613 0.781731
            +vt 0.942384 0.781506
            +vt 0.968440 0.781506
            +vt 0.952116 0.784248
            +vt 0.946386 0.784349
            +vt 0.944548 0.784464
            +vt 0.964437 0.784615
            +vt 0.958921 0.784349
            +vt 0.942758 0.783252
            +vt 0.946369 0.785306
            +vt 0.952776 0.785650
            +vt 0.955403 0.785710
            +vt 0.961001 0.785705
            +vt 0.965433 0.785514
            +vt 0.967330 0.784989
            +vt 0.943218 0.784792
            +vt 0.966810 0.785364
            +vt 0.961160 0.784801
            +vt 0.959783 0.784644
            +vt 0.962096 0.784972
            +vt 0.962544 0.785144
            +vt 0.962497 0.785308
            +vt 0.961979 0.785451
            +vt 0.958056 0.784512
            +vt 0.961040 0.785563
            +vt 0.959752 0.785638
            +vt 0.956104 0.784414
            +vt 0.958198 0.785669
            +vt 0.956472 0.785655
            +vt 0.954081 0.784355
            +vt 0.952149 0.784341
            +vt 0.949153 0.784447
            +vt 0.950463 0.784372
            +vt 0.948307 0.784560
            +vt 0.954673 0.785598
            +vt 0.947971 0.784703
            +vt 0.952904 0.785499
            +vt 0.948148 0.784866
            +vt 0.951269 0.785366
            +vt 0.948802 0.785039
            +vt 0.949870 0.785210
            +vt 0.956857 0.718878
            +vt 0.954505 0.728986
            +vt 0.952735 0.730998
            +vt 0.955871 0.726599
            +vt 0.956743 0.724001
            +vt 0.957073 0.721368
            +vt 0.956128 0.716702
            +vt 0.954947 0.714990
            +vt 0.953404 0.713857
            +vt 0.951601 0.713379
            +vt 0.949651 0.713591
            +vt 0.947672 0.714476
            +vt 0.945783 0.715976
            +vt 0.944098 0.717987
            +vt 0.942725 0.720374
            +vt 0.941755 0.722973
            +vt 0.941262 0.725607
            +vt 0.941295 0.728096
            +vt 0.941870 0.730271
            +vt 0.942964 0.731983
            +vt 0.944514 0.733118
            +vt 0.946415 0.733595
            +vt 0.948528 0.733384
            +vt 0.950691 0.732498
            +vt 0.944549 0.243720
            +vt 0.944822 0.243901
            +vt 0.944549 0.243720
            +vt 0.945146 0.244240
            +vt 0.944822 0.243901
            +vt 0.945589 0.245005
            +vt 0.945146 0.244240
            +vt 0.945589 0.245005
            +vt 0.946463 0.247876
            +vt 0.940372 0.244716
            +vt 0.940372 0.244716
            +vt 0.940807 0.244049
            +vt 0.940807 0.244049
            +vt 0.941105 0.243762
            +vt 0.941105 0.243762
            +vt 0.941348 0.243609
            +vt 0.941348 0.243609
            +vt 0.941567 0.243518
            +vt 0.941567 0.243518
            +vt 0.941681 0.243484
            +vt 0.941681 0.243484
            +vt 0.941790 0.243460
            +vt 0.941790 0.243460
            +vt 0.941894 0.243442
            +vt 0.941894 0.243442
            +vt 0.941999 0.243430
            +vt 0.941999 0.243430
            +vt 0.942103 0.243422
            +vt 0.942103 0.243422
            +vt 0.942209 0.243418
            +vt 0.942824 0.243454
            +vt 0.943139 0.243500
            +vt 0.943139 0.243500
            +vt 0.944070 0.243695
            +vt 0.944070 0.243695
            +vt 0.944901 0.243912
            +vt 0.944901 0.243912
            +vt 0.946468 0.244373
            +vt 0.946468 0.244373
            +vt 0.951004 0.245830
            +vt 0.944298 0.243611
            +vt 0.951004 0.245830
            +vt 0.949410 0.303010
            +vt 0.931051 0.299382
            +vt 0.950536 0.360568
            +vt 0.948582 0.416900
            +vt 0.923006 0.362127
            +vt 0.946608 0.450808
            +vt 0.917666 0.421245
            +vt 0.943581 0.462742
            +vt 0.933693 0.480425
            +vt 0.916649 0.463268
            +vt 0.915205 0.450806
            +vt 0.928671 0.481332
            +vt 0.926291 0.480911
            +vt 0.927155 0.481069
            +vt 0.926291 0.480911
            +vt 0.927155 0.481069
            +vt 0.969697 0.002150
            +vt 0.946984 0.004784
            +vt 0.971713 0.004784
            +vt 0.948950 0.034051
            +vt 0.973047 0.034051
            +vt 0.986837 0.042562
            +vt 0.996686 0.042562
            +vt 0.027693 0.047571
            +vt -0.003314 0.042562
            +vt -0.003314 0.042562
            +vt -0.013163 0.042562
            +vt 0.019624 0.047571
            +vt 0.105594 0.054088
            +vt 0.063998 0.054088
            +vt 0.137600 0.059096
            +vt 0.085527 0.059096
            +vt 0.216080 0.104019
            +vt 0.161282 0.104019
            +vt 0.233544 0.128263
            +vt 0.185340 0.128262
            +vt 0.241580 0.146926
            +vt 0.197496 0.146926
            +vt 0.245708 0.166602
            +vt 0.204000 0.166602
            +vt 0.247658 0.193884
            +vt 0.207131 0.193884
            +vt 0.247981 0.235363
            +vt 0.207653 0.235363
            +vt -0.051050 0.772196
            +vt -0.026953 0.772196
            +vt 0.078807 0.775926
            +vt 0.047968 0.775926
            +vt 0.087911 0.782057
            +vt 0.053272 0.782057
            +vt 0.118021 0.793661
            +vt 0.071976 0.793661
            +vt 0.114663 0.797226
            +vt 0.069775 0.797227
            +vt 0.096509 0.801623
            +vt 0.058408 0.801624
            +vt -0.185290 0.878718
            +vt -0.174387 0.878718
            +vt 0.811340 0.885757
            +vt 0.825613 0.878718
            +vt 0.825613 0.878718
            +vt 0.814710 0.878718
            +vt 0.819840 0.885757
            +vt 0.813259 0.901329
            +vt 0.807512 0.917266
            +vt 0.830563 0.978941
            +vt 0.829826 0.983802
            +vt 0.826999 0.987459
            +vt 0.822989 0.990257
            +vt 0.806230 0.996931
            +vt 0.810925 0.996931
            +vt 0.800078 0.999500
            +vt 0.799981 0.999500
            +vt 0.943851 0.000695
            +vt 0.837639 0.002150
            +vt 0.845894 0.004784
            +vt 0.847211 0.034051
            +vt 0.887807 0.042562
            +vt 0.021960 0.047571
            +vt -0.013163 0.042562
            +vt -0.013163 0.042562
            +vt -0.112193 0.042562
            +vt 0.238594 0.054088
            +vt 0.258733 0.059096
            +vt 0.283482 0.104019
            +vt 0.287255 0.128263
            +vt 0.288903 0.146926
            +vt 0.289733 0.166602
            +vt 0.290121 0.193884
            +vt 0.290185 0.235363
            +vt -0.152790 0.772196
            +vt 0.207052 0.775926
            +vt 0.247812 0.793661
            +vt 0.245542 0.797227
            +vt 0.230139 0.801624
            +vt -0.196980 0.878718
            +vt 0.802358 0.885757
            +vt 0.814710 0.878718
            +vt 0.814710 0.878718
            +vt 0.803020 0.878718
            +vt 0.801620 0.901329
            +vt 0.801363 0.996931
            +vt 0.800177 0.999500
            +vt 0.695033 0.002150
            +vt 0.678432 0.004784
            +vt 0.675999 0.034051
            +vt 0.623194 0.042562
            +vt -0.443131 0.047571
            +vt -0.112193 0.042562
            +vt 0.556869 0.047571
            +vt 0.444931 0.054088
            +vt 0.411891 0.059096
            +vt 0.351888 0.104019
            +vt 0.340774 0.128263
            +vt 0.335790 0.146926
            +vt 0.333256 0.166602
            +vt 0.332063 0.193884
            +vt 0.331865 0.235363
            +vt 0.675999 0.772196
            +vt 0.478431 0.775926
            +vt 0.847210 0.772196
            +vt 0.431270 0.793661
            +vt 0.434856 0.797227
            +vt 0.455645 0.801624
            +vt -0.208846 0.878718
            +vt 0.793276 0.885757
            +vt 0.803020 0.878718
            +vt 0.803020 0.878718
            +vt 0.791154 0.878718
            +vt 0.795672 0.917266
            +vt 0.803601 0.978941
            +vt 0.803514 0.983802
            +vt 0.796470 0.996931
            +vt 0.800276 0.999500
            +vt 0.800039 0.000499
            +vt 0.813265 0.000499
            +vt 0.674187 0.000499
            +vt 0.626220 0.004784
            +vt 0.624497 0.034051
            +vt 0.593495 0.042562
            +vt 0.563225 0.047571
            +vt 0.556869 0.047571
            +vt 0.534383 0.050830
            +vt 0.556869 0.047571
            +vt 0.556869 0.047571
            +vt 0.507417 0.054088
            +vt 0.482662 0.059096
            +vt 0.408808 0.104019
            +vt 0.388728 0.128263
            +vt 0.378983 0.146926
            +vt 0.373857 0.166602
            +vt 0.371408 0.193884
            +vt 0.371001 0.235363
            +vt 0.624496 0.772196
            +vt 0.526929 0.775926
            +vt 0.520375 0.782057
            +vt 0.498047 0.793661
            +vt 0.500607 0.797227
            +vt 0.514125 0.801624
            +vt 0.791154 0.878718
            +vt 0.791154 0.878718
            +vt 0.789800 0.901329
            +vt 0.791677 0.996931
            +vt 0.800372 0.999500
            +vt 0.622570 0.002150
            +vt 0.613487 0.004784
            +vt 0.612294 0.034051
            +vt 0.591574 0.042562
            +vt 0.572176 0.047571
            +vt 0.535635 0.054088
            +vt 0.517943 0.059096
            +vt 0.452141 0.104019
            +vt 0.429122 0.128263
            +vt 0.416959 0.146926
            +vt 0.410297 0.166602
            +vt 0.407051 0.193884
            +vt 0.406507 0.235363
            +vt 0.612294 0.772196
            +vt 0.548769 0.775926
            +vt 0.544420 0.782057
            +vt 0.529100 0.793661
            +vt 0.530901 0.797227
            +vt 0.540212 0.801624
            +vt 0.779704 0.878718
            +vt 0.788986 0.896045
            +vt 0.775578 0.978941
            +vt 0.776195 0.983802
            +vt 0.778554 0.987459
            +vt 0.781872 0.990257
            +vt 0.787103 0.996931
            +vt 0.800467 0.999500
            +vt 0.632046 0.000695
            +vt 0.612228 0.004784
            +vt 0.611332 0.034051
            +vt 0.595966 0.042562
            +vt 0.581751 0.047571
            +vt 0.554752 0.054088
            +vt 0.541248 0.059096
            +vt 0.485362 0.104019
            +vt 0.462604 0.128262
            +vt 0.449720 0.146926
            +vt 0.442395 0.166602
            +vt 0.438756 0.193884
            +vt 0.438140 0.235363
            +vt 0.611332 0.772196
            +vt 0.564549 0.775926
            +vt 0.561322 0.782057
            +vt 0.549811 0.793661
            +vt 0.551181 0.797227
            +vt 0.558186 0.801624
            +vt 0.774370 0.891193
            +vt 0.779170 0.901329
            +vt 0.784347 0.917266
            +vt 0.782875 0.996931
            +vt 0.800558 0.999500
            +vt 0.615635 0.004784
            +vt 0.614920 0.034051
            +vt 0.602779 0.042562
            +vt 0.591605 0.047571
            +vt 0.570276 0.054088
            +vt 0.559438 0.059096
            +vt 0.511890 0.104019
            +vt 0.490634 0.128262
            +vt 0.477962 0.146926
            +vt 0.470531 0.166602
            +vt 0.466779 0.193884
            +vt 0.466141 0.235363
            +vt 0.614921 0.772196
            +vt 0.578051 0.775926
            +vt 0.575496 0.782057
            +vt 0.566327 0.793661
            +vt 0.567426 0.797227
            +vt 0.573008 0.801624
            +vt 0.760076 0.878718
            +vt 0.752703 0.978941
            +vt 0.764051 0.990257
            +vt 0.779122 0.996931
            +vt 0.800642 0.999500
            +vt 0.625868 0.002150
            +vt 0.621341 0.004784
            +vt 0.620755 0.034051
            +vt 0.610764 0.042562
            +vt 0.601589 0.047571
            +vt 0.584021 0.054088
            +vt 0.575012 0.059096
            +vt 0.534077 0.104019
            +vt 0.514636 0.128263
            +vt 0.502600 0.146926
            +vt 0.495375 0.166602
            +vt 0.491674 0.193884
            +vt 0.491042 0.235363
            +vt 0.620755 0.772196
            +vt 0.590441 0.775926
            +vt 0.588337 0.782057
            +vt 0.580748 0.793661
            +vt 0.581656 0.797227
            +vt 0.586279 0.801624
            +vt 0.764702 0.891193
            +vt 0.770983 0.901329
            +vt 0.771145 0.917266
            +vt 0.745589 0.983802
            +vt 0.750275 0.987459
            +vt 0.775933 0.996931
            +vt 0.800719 0.999500
            +vt 0.628363 0.004784
            +vt 0.627864 0.034051
            +vt 0.619421 0.042562
            +vt 0.611672 0.047571
            +vt 0.596806 0.054088
            +vt 0.589136 0.059096
            +vt 0.553468 0.104017
            +vt 0.535812 0.128263
            +vt 0.524575 0.146926
            +vt 0.517703 0.166602
            +vt 0.514144 0.193884
            +vt 0.513533 0.235363
            +vt 0.627864 0.772196
            +vt 0.602249 0.775926
            +vt 0.594025 0.793661
            +vt 0.594797 0.797227
            +vt 0.598723 0.801624
            +vt 0.746906 0.878718
            +vt 0.738259 0.978941
            +vt 0.751718 0.990257
            +vt 0.773348 0.996931
            +vt 0.800786 0.999500
            +vt 0.799522 0.000499
            +vt 0.640294 0.000499
            +vt 0.639550 0.002150
            +vt 0.636248 0.004784
            +vt 0.635818 0.034051
            +vt 0.628554 0.042562
            +vt 0.621888 0.047571
            +vt 0.609078 0.054088
            +vt 0.602441 0.059096
            +vt 0.571069 0.104019
            +vt 0.555072 0.128263
            +vt 0.544671 0.146926
            +vt 0.538216 0.166602
            +vt 0.534846 0.193884
            +vt 0.534265 0.235363
            +vt 0.635819 0.772196
            +vt 0.613776 0.775926
            +vt 0.606674 0.793661
            +vt 0.607343 0.797227
            +vt 0.610734 0.801624
            +vt 0.758919 0.891193
            +vt 0.765815 0.901329
            +vt 0.765995 0.917266
            +vt 0.735385 0.983802
            +vt 0.740341 0.987459
            +vt 0.771374 0.996931
            +vt 0.800844 0.999500
            +vt 0.644774 0.004784
            +vt 0.644401 0.034051
            +vt 0.638077 0.042562
            +vt 0.632276 0.047571
            +vt 0.621107 0.054088
            +vt 0.615302 0.059096
            +vt 0.587525 0.104019
            +vt 0.573041 0.128263
            +vt 0.563467 0.146926
            +vt 0.557457 0.166602
            +vt 0.554293 0.193884
            +vt 0.553747 0.235363
            +vt 0.644401 0.772196
            +vt 0.625206 0.775926
            +vt 0.623864 0.782057
            +vt 0.619007 0.793661
            +vt 0.619591 0.797227
            +vt 0.622552 0.801624
            +vt 0.740311 0.878718
            +vt 0.731745 0.978941
            +vt 0.745211 0.990257
            +vt 0.770004 0.996931
            +vt 0.800891 0.999500
            +vt 0.656324 0.002150
            +vt 0.653800 0.004784
            +vt 0.653472 0.034051
            +vt 0.647924 0.042562
            +vt 0.642836 0.047571
            +vt 0.633024 0.054088
            +vt 0.627911 0.059096
            +vt 0.603214 0.104019
            +vt 0.590106 0.128263
            +vt 0.581328 0.146926
            +vt 0.575764 0.166602
            +vt 0.572818 0.193884
            +vt 0.572308 0.235363
            +vt 0.653472 0.772196
            +vt 0.636629 0.775926
            +vt 0.635449 0.782057
            +vt 0.631175 0.793661
            +vt 0.631689 0.797227
            +vt 0.634296 0.801624
            +vt 0.756769 0.891193
            +vt 0.763606 0.901329
            +vt 0.763786 0.917266
            +vt 0.732036 0.983802
            +vt 0.769235 0.996931
            +vt 0.800927 0.999500
            +vt 0.798224 0.000499
            +vt 0.663179 0.004784
            +vt 0.662891 0.034051
            +vt 0.658000 0.042562
            +vt 0.653511 0.047571
            +vt 0.644847 0.054088
            +vt 0.640324 0.059096
            +vt 0.618304 0.104019
            +vt 0.606452 0.128263
            +vt 0.598430 0.146926
            +vt 0.593303 0.166602
            +vt 0.590576 0.193884
            +vt 0.590103 0.235363
            +vt 0.662891 0.772196
            +vt 0.648033 0.775926
            +vt 0.646991 0.782057
            +vt 0.643213 0.793661
            +vt 0.643668 0.797227
            +vt 0.645972 0.801624
            +vt 0.739085 0.878718
            +vt 0.731287 0.978941
            +vt 0.736802 0.987459
            +vt 0.769043 0.996931
            +vt 0.800950 0.999500
            +vt 0.799496 0.000499
            +vt 0.661188 0.000695
            +vt 0.684330 0.002150
            +vt 0.672791 0.004784
            +vt 0.672536 0.034051
            +vt 0.668211 0.042562
            +vt 0.664242 0.047571
            +vt 0.656570 0.054088
            +vt 0.652557 0.059096
            +vt 0.632899 0.104019
            +vt 0.622198 0.128263
            +vt 0.614891 0.146926
            +vt 0.610190 0.166602
            +vt 0.607679 0.193884
            +vt 0.607242 0.235363
            +vt 0.672536 0.772196
            +vt 0.659392 0.775926
            +vt 0.655120 0.793661
            +vt 0.655523 0.797227
            +vt 0.657566 0.801624
            +vt 0.764922 0.896045
            +vt 0.761283 0.896045
            +vt 0.764097 0.901329
            +vt 0.764266 0.917266
            +vt 0.733834 0.983802
            +vt 0.744390 0.990257
            +vt 0.769391 0.996931
            +vt 0.800960 0.999500
            +vt 0.791915 0.000499
            +vt 0.682589 0.004784
            +vt 0.682363 0.034051
            +vt 0.678537 0.042562
            +vt 0.675024 0.047571
            +vt 0.668228 0.054088
            +vt 0.664667 0.059096
            +vt 0.647136 0.104017
            +vt 0.637501 0.128263
            +vt 0.630873 0.146926
            +vt 0.626586 0.166602
            +vt 0.624287 0.193884
            +vt 0.623888 0.235363
            +vt 0.682362 0.772196
            +vt 0.670730 0.775926
            +vt 0.666942 0.793661
            +vt 0.667300 0.797227
            +vt 0.669111 0.801624
            +vt 0.741987 0.878718
            +vt 0.735243 0.978941
            +vt 0.770225 0.996931
            +vt 0.800957 0.999500
            +vt 0.692576 0.004784
            +vt 0.692376 0.034051
            +vt 0.689000 0.042562
            +vt 0.685899 0.047571
            +vt 0.679894 0.054088
            +vt 0.676744 0.059096
            +vt 0.661164 0.104019
            +vt 0.652534 0.128263
            +vt 0.646560 0.146926
            +vt 0.642677 0.166602
            +vt 0.640589 0.193884
            +vt 0.640225 0.235363
            +vt 0.692376 0.772196
            +vt 0.682105 0.775926
            +vt 0.681382 0.782057
            +vt 0.678757 0.793661
            +vt 0.679073 0.797227
            +vt 0.680675 0.801624
            +vt 0.761305 0.891193
            +vt 0.766966 0.917266
            +vt 0.739292 0.983802
            +vt 0.754690 0.990257
            +vt 0.771506 0.996931
            +vt 0.800941 0.999500
            +vt 0.799685 0.000499
            +vt 0.771937 0.000499
            +vt 0.704113 0.002150
            +vt 0.702766 0.004784
            +vt 0.702590 0.034051
            +vt 0.699629 0.042562
            +vt 0.696907 0.047571
            +vt 0.691631 0.054088
            +vt 0.688860 0.059096
            +vt 0.675107 0.104019
            +vt 0.667435 0.128262
            +vt 0.662097 0.146926
            +vt 0.658614 0.166602
            +vt 0.656735 0.193884
            +vt 0.656407 0.235363
            +vt 0.702591 0.772196
            +vt 0.693575 0.775926
            +vt 0.692939 0.782057
            +vt 0.690631 0.793661
            +vt 0.690909 0.797227
            +vt 0.692318 0.801624
            +vt 0.747861 0.878718
            +vt 0.766817 0.901329
            +vt 0.742254 0.978941
            +vt 0.746201 0.987459
            +vt 0.773194 0.996931
            +vt 0.800913 0.999500
            +vt 0.792229 0.000499
            +vt 0.687686 0.000695
            +vt 0.713586 0.003337
            +vt 0.712988 0.006453
            +vt 0.712988 0.034051
            +vt 0.710411 0.042562
            +vt 0.708043 0.047571
            +vt 0.703449 0.054088
            +vt 0.701034 0.059096
            +vt 0.689008 0.104019
            +vt 0.682261 0.128262
            +vt 0.677545 0.146926
            +vt 0.674457 0.166602
            +vt 0.672788 0.193884
            +vt 0.672496 0.235363
            +vt 0.712988 0.772196
            +vt 0.705142 0.775926
            +vt 0.704589 0.782057
            +vt 0.702578 0.793661
            +vt 0.702820 0.797227
            +vt 0.704047 0.801624
            +vt 0.766805 0.891193
            +vt 0.775250 0.996931
            +vt 0.800871 0.999500
            +vt 0.734982 0.002150
            +vt 0.723620 0.004784
            +vt 0.723490 0.034051
            +vt 0.721275 0.042562
            +vt 0.719239 0.047571
            +vt 0.715286 0.054088
            +vt 0.713206 0.059096
            +vt 0.702822 0.104019
            +vt 0.696969 0.128263
            +vt 0.692861 0.146926
            +vt 0.690164 0.166602
            +vt 0.688703 0.193884
            +vt 0.688447 0.235363
            +vt 0.723490 0.772196
            +vt 0.716743 0.775926
            +vt 0.716267 0.782057
            +vt 0.714536 0.793661
            +vt 0.714745 0.797227
            +vt 0.715801 0.801624
            +vt 0.755941 0.878718
            +vt 0.771467 0.917266
            +vt 0.751486 0.978941
            +vt 0.752104 0.983802
            +vt 0.754618 0.987459
            +vt 0.777621 0.996931
            +vt 0.800820 0.999500
            +vt 0.715310 0.001257
            +vt 0.734130 0.004784
            +vt 0.734019 0.034051
            +vt 0.732145 0.042562
            +vt 0.730421 0.047571
            +vt 0.727075 0.054088
            +vt 0.725312 0.059096
            +vt 0.716495 0.104019
            +vt 0.711505 0.128263
            +vt 0.707992 0.146926
            +vt 0.705680 0.166602
            +vt 0.704425 0.193884
            +vt 0.704206 0.235363
            +vt 0.734020 0.772196
            +vt 0.728309 0.775926
            +vt 0.726439 0.793661
            +vt 0.726616 0.797227
            +vt 0.727511 0.801624
            +vt 0.773754 0.891193
            +vt 0.774151 0.901329
            +vt 0.780249 0.996931
            +vt 0.800756 0.999500
            +vt 0.745355 0.002150
            +vt 0.744650 0.004784
            +vt 0.744558 0.034051
            +vt 0.743008 0.042562
            +vt 0.741583 0.047571
            +vt 0.738813 0.054088
            +vt 0.737354 0.059096
            +vt 0.730040 0.104019
            +vt 0.725889 0.128263
            +vt 0.722959 0.146926
            +vt 0.721026 0.166602
            +vt 0.719976 0.193884
            +vt 0.719793 0.235363
            +vt 0.744558 0.772196
            +vt 0.739835 0.775926
            +vt 0.738287 0.793661
            +vt 0.738434 0.797227
            +vt 0.739174 0.801624
            +vt 0.765545 0.878718
            +vt 0.772763 0.896045
            +vt 0.780617 0.917266
            +vt 0.762218 0.978941
            +vt 0.762678 0.983802
            +vt 0.767563 0.990257
            +vt 0.783089 0.996931
            +vt 0.800684 0.999500
            +vt 0.799996 0.000499
            +vt 0.755208 0.004784
            +vt 0.755134 0.034051
            +vt 0.753896 0.042562
            +vt 0.752757 0.047571
            +vt 0.750543 0.054088
            +vt 0.749377 0.059096
            +vt 0.743522 0.104019
            +vt 0.740191 0.128263
            +vt 0.737835 0.146926
            +vt 0.736279 0.166602
            +vt 0.735433 0.193884
            +vt 0.735285 0.235363
            +vt 0.755134 0.772196
            +vt 0.751360 0.775926
            +vt 0.750123 0.793661
            +vt 0.750240 0.797227
            +vt 0.750832 0.801624
            +vt 0.781657 0.891193
            +vt 0.786114 0.996931
            +vt 0.800602 0.999500
            +vt 0.766255 0.002150
            +vt 0.765830 0.004784
            +vt 0.765774 0.034051
            +vt 0.764839 0.042562
            +vt 0.763979 0.047571
            +vt 0.762306 0.054088
            +vt 0.761425 0.059096
            +vt 0.756997 0.104019
            +vt 0.754474 0.128263
            +vt 0.752687 0.146926
            +vt 0.751505 0.166602
            +vt 0.750861 0.193884
            +vt 0.750749 0.235363
            +vt 0.765774 0.772196
            +vt 0.762923 0.775926
            +vt 0.762722 0.782057
            +vt 0.761989 0.793661
            +vt 0.762077 0.797226
            +vt 0.762525 0.801623
            +vt 0.776092 0.878718
            +vt 0.787755 0.917266
            +vt 0.773855 0.978941
            +vt 0.774164 0.983802
            +vt 0.775426 0.987459
            +vt 0.800515 0.999500
            +vt 0.757587 0.000499
            +vt 0.776503 0.004784
            +vt 0.776466 0.034051
            +vt 0.775826 0.042562
            +vt 0.775238 0.047571
            +vt 0.774096 0.054088
            +vt 0.773494 0.059096
            +vt 0.770467 0.104019
            +vt 0.768740 0.128262
            +vt 0.767516 0.146926
            +vt 0.766706 0.166602
            +vt 0.766264 0.193884
            +vt 0.766187 0.235363
            +vt 0.776466 0.772196
            +vt 0.774518 0.775926
            +vt 0.774380 0.782057
            +vt 0.773880 0.793661
            +vt 0.773940 0.797227
            +vt 0.774246 0.801624
            +vt 0.787330 0.878718
            +vt 0.790250 0.891193
            +vt 0.784036 0.901329
            +vt 0.789298 0.996931
            +vt 0.792608 0.996931
            +vt 0.800421 0.999500
            +vt 0.796009 0.000499
            +vt 0.787155 0.004784
            +vt 0.787135 0.034051
            +vt 0.786785 0.042562
            +vt 0.786464 0.047571
            +vt 0.785839 0.054088
            +vt 0.785510 0.059096
            +vt 0.783855 0.104019
            +vt 0.782910 0.128263
            +vt 0.782240 0.146926
            +vt 0.781797 0.166602
            +vt 0.781555 0.193884
            +vt 0.781513 0.235363
            +vt 0.787135 0.772196
            +vt 0.786070 0.775926
            +vt 0.785995 0.782057
            +vt 0.785720 0.793661
            +vt 0.785753 0.797227
            +vt 0.785921 0.801624
            +vt 0.795404 0.917266
            +vt 0.786161 0.978941
            +vt 0.786323 0.983802
            +vt 0.786981 0.987459
            +vt 0.788043 0.990257
            +vt 0.795992 0.996931
            +vt 0.800324 0.999500
            +vt 0.800270 0.000499
            +vt 0.777354 0.000695
            +vt 0.787314 0.002150
            +vt 0.797713 0.004784
            +vt 0.797710 0.034051
            +vt 0.797643 0.042562
            +vt 0.797582 0.047571
            +vt 0.797464 0.054088
            +vt 0.797401 0.059096
            +vt 0.797087 0.104019
            +vt 0.796908 0.128263
            +vt 0.796781 0.146926
            +vt 0.796697 0.166602
            +vt 0.796651 0.193884
            +vt 0.796643 0.235363
            +vt 0.797710 0.772196
            +vt 0.797508 0.775926
            +vt 0.797442 0.793661
            +vt 0.797448 0.797227
            +vt 0.797479 0.801624
            +vt 0.793085 0.878718
            +vt 0.799146 0.891193
            +vt 0.799395 0.996931
            +vt 0.800223 0.999500
            +vt 0.799956 0.000499
            +vt 0.808168 0.004784
            +vt 0.808181 0.034051
            +vt 0.808393 0.042562
            +vt 0.808588 0.047571
            +vt 0.808966 0.054088
            +vt 0.809166 0.059096
            +vt 0.810169 0.104019
            +vt 0.810740 0.128262
            +vt 0.811145 0.146926
            +vt 0.811413 0.166602
            +vt 0.811559 0.193884
            +vt 0.811585 0.235363
            +vt 0.808181 0.772196
            +vt 0.808827 0.775926
            +vt 0.809038 0.793661
            +vt 0.809018 0.797227
            +vt 0.808917 0.801624
            +vt 0.803145 0.917266
            +vt 0.798718 0.978941
            +vt 0.798735 0.983802
            +vt 0.798915 0.990257
            +vt 0.802785 0.996931
            +vt 0.800125 0.999500
            +vt 0.817614 0.000499
            +vt 0.818331 0.002150
            +vt 0.818553 0.004784
            +vt 0.818582 0.034051
            +vt 0.819070 0.042562
            +vt 0.819519 0.047571
            +vt 0.820391 0.054088
            +vt 0.820850 0.059095
            +vt 0.823156 0.104019
            +vt 0.824468 0.128262
            +vt 0.825398 0.146926
            +vt 0.826013 0.166602
            +vt 0.826348 0.193884
            +vt 0.826407 0.235363
            +vt 0.818582 0.772196
            +vt 0.820069 0.775926
            +vt 0.820174 0.782057
            +vt 0.820557 0.793661
            +vt 0.820511 0.797227
            +vt 0.820278 0.801624
            +vt 0.804561 0.878718
            +vt 0.807974 0.891193
            +vt 0.799279 0.901329
            +vt 0.814991 0.990257
            +vt 0.806143 0.996931
            +vt 0.800027 0.999500
            +vt 0.800449 0.000499
            +vt 0.828902 0.004784
            +vt 0.828947 0.034051
            +vt 0.829712 0.042562
            +vt 0.830415 0.047571
            +vt 0.831782 0.054088
            +vt 0.832501 0.059095
            +vt 0.836108 0.104019
            +vt 0.838159 0.128262
            +vt 0.839610 0.146925
            +vt 0.840569 0.166602
            +vt 0.841090 0.193884
            +vt 0.841182 0.235363
            +vt 0.828947 0.772196
            +vt 0.831278 0.775926
            +vt 0.831442 0.782057
            +vt 0.832041 0.793661
            +vt 0.831969 0.797227
            +vt 0.831604 0.801624
            +vt 0.815855 0.878718
            +vt 0.810745 0.917266
            +vt 0.811138 0.978941
            +vt 0.811014 0.983802
            +vt 0.810506 0.987459
            +vt 0.809449 0.996931
            +vt 0.799932 0.999500
            +vt 0.802987 0.000499
            +vt 0.839206 0.004784
            +vt 0.839267 0.034051
            +vt 0.840313 0.042562
            +vt 0.841274 0.047571
            +vt 0.843139 0.054088
            +vt 0.844121 0.059095
            +vt 0.849037 0.104019
            +vt 0.851826 0.128262
            +vt 0.853797 0.146926
            +vt 0.855097 0.166602
            +vt 0.855805 0.193884
            +vt 0.855928 0.235363
            +vt 0.839267 0.772196
            +vt 0.842452 0.775926
            +vt 0.842676 0.782057
            +vt 0.843493 0.793661
            +vt 0.843395 0.797227
            +vt 0.842896 0.801624
            +vt 0.816558 0.891193
            +vt 0.814485 0.901329
            +vt 0.823310 0.978941
            +vt 0.812669 0.996931
            +vt 0.799840 0.999500
            +vt 0.808717 0.000499
            +vt 0.838730 0.002150
            +vt 0.849402 0.004784
            +vt 0.849480 0.034051
            +vt 0.850810 0.042562
            +vt 0.852032 0.047571
            +vt 0.854402 0.054088
            +vt 0.855649 0.059095
            +vt 0.861885 0.104019
            +vt 0.865415 0.128262
            +vt 0.867903 0.146926
            +vt 0.869543 0.166602
            +vt 0.870435 0.193884
            +vt 0.870591 0.235363
            +vt 0.849480 0.772196
            +vt 0.853528 0.775926
            +vt 0.853814 0.782057
            +vt 0.854852 0.793661
            +vt 0.854727 0.797227
            +vt 0.854094 0.801624
            +vt 0.821382 0.878718
            +vt 0.817965 0.917266
            +vt 0.821957 0.987459
            +vt 0.820204 0.990257
            +vt 0.815752 0.996931
            +vt 0.799755 0.999500
            +vt 0.800799 0.000499
            +vt 0.837812 0.000695
            +vt 0.859427 0.004784
            +vt 0.859523 0.034051
            +vt 0.861143 0.042562
            +vt 0.862631 0.047571
            +vt 0.865515 0.054088
            +vt 0.867031 0.059095
            +vt 0.874603 0.104019
            +vt 0.878877 0.128262
            +vt 0.881883 0.146926
            +vt 0.883861 0.166602
            +vt 0.884935 0.193884
            +vt 0.885122 0.235363
            +vt 0.859523 0.772196
            +vt 0.864452 0.775926
            +vt 0.866062 0.793661
            +vt 0.865910 0.797227
            +vt 0.865140 0.801624
            +vt 0.824526 0.891193
            +vt 0.815205 0.896045
            +vt 0.821384 0.901329
            +vt 0.829192 0.978941
            +vt 0.828855 0.983802
            +vt 0.818645 0.996931
            +vt 0.799678 0.999500
            +vt 0.804837 0.000499
            +vt 0.868411 0.002150
            +vt 0.869284 0.004784
            +vt 0.869397 0.034051
            +vt 0.871315 0.042562
            +vt 0.873076 0.047571
            +vt 0.876489 0.054088
            +vt 0.878282 0.059095
            +vt 0.887219 0.104019
            +vt 0.892249 0.128262
            +vt 0.895778 0.146926
            +vt 0.898095 0.166602
            +vt 0.899351 0.193884
            +vt 0.899571 0.235363
            +vt 0.869397 0.772196
            +vt 0.875231 0.775926
            +vt 0.875643 0.782057
            +vt 0.877136 0.793661
            +vt 0.876956 0.797227
            +vt 0.876045 0.801624
            +vt 0.831885 0.878718
            +vt 0.824394 0.917266
            +vt 0.838915 0.990257
            +vt 0.821315 0.996931
            +vt 0.799610 0.999500
            +vt 0.879007 0.004784
            +vt 0.879139 0.034051
            +vt 0.881369 0.042562
            +vt 0.883415 0.047571
            +vt 0.887381 0.054088
            +vt 0.889463 0.059095
            +vt 0.899821 0.104019
            +vt 0.905629 0.128263
            +vt 0.909692 0.146926
            +vt 0.912355 0.166602
            +vt 0.913796 0.193884
            +vt 0.914047 0.235363
            +vt 0.879139 0.772196
            +vt 0.885920 0.775926
            +vt 0.886397 0.782057
            +vt 0.888132 0.793661
            +vt 0.887923 0.797227
            +vt 0.886864 0.801624
            +vt 0.831496 0.891193
            +vt 0.827337 0.901329
            +vt 0.840234 0.978941
            +vt 0.839753 0.983802
            +vt 0.823739 0.996931
            +vt 0.799553 0.999500
            +vt 0.887464 0.002150
            +vt 0.888632 0.004784
            +vt 0.888783 0.034051
            +vt 0.891344 0.042562
            +vt 0.893697 0.047571
            +vt 0.898250 0.054088
            +vt 0.900639 0.059095
            +vt 0.912500 0.104019
            +vt 0.919124 0.128263
            +vt 0.923743 0.146926
            +vt 0.926763 0.166602
            +vt 0.928394 0.193884
            +vt 0.928679 0.235363
            +vt 0.888783 0.772196
            +vt 0.896572 0.775926
            +vt 0.897121 0.782057
            +vt 0.899112 0.793661
            +vt 0.898872 0.797227
            +vt 0.897657 0.801624
            +vt 0.841338 0.878718
            +vt 0.850115 0.978941
            +vt 0.842526 0.987459
            +vt 0.825886 0.996931
            +vt 0.799506 0.999500
            +vt 0.874711 0.000499
            +vt 0.906000 0.002150
            +vt 0.898152 0.004784
            +vt 0.898325 0.034051
            +vt 0.901245 0.042562
            +vt 0.903926 0.047571
            +vt 0.909115 0.054088
            +vt 0.911837 0.059095
            +vt 0.925311 0.104019
            +vt 0.932803 0.128263
            +vt 0.938008 0.146926
            +vt 0.941401 0.166602
            +vt 0.943230 0.193884
            +vt 0.907205 0.775926
            +vt 0.898325 0.772196
            +vt 0.907829 0.782057
            +vt 0.910098 0.793661
            +vt 0.909824 0.797227
            +vt 0.908440 0.801624
            +vt 0.837183 0.891193
            +vt 0.832083 0.901329
            +vt 0.829759 0.917266
            +vt 0.827711 0.996931
            +vt 0.799472 0.999500
            +vt 0.907507 0.004784
            +vt 0.907703 0.034051
            +vt 0.911016 0.042562
            +vt 0.914057 0.047571
            +vt 0.919940 0.054088
            +vt 0.923024 0.059095
            +vt 0.938252 0.104019
            +vt 0.946675 0.128263
            +vt 0.952502 0.146926
            +vt 0.956287 0.166602
            +vt 0.958323 0.193884
            +vt 0.958678 0.235363
            +vt 0.917775 0.775926
            +vt 0.907703 0.772196
            +vt 0.918483 0.782057
            +vt 0.921054 0.793661
            +vt 0.920745 0.797227
            +vt 0.919176 0.801624
            +vt 0.849454 0.878718
            +vt 0.854509 0.978941
            +vt 0.853807 0.983802
            +vt 0.850954 0.987459
            +vt 0.851974 0.990257
            +vt 0.829161 0.996931
            +vt 0.799450 0.999500
            +vt 0.894256 0.000695
            +vt 0.914931 0.002150
            +vt 0.916636 0.004784
            +vt 0.916857 0.034051
            +vt 0.920603 0.042562
            +vt 0.924043 0.047571
            +vt 0.930695 0.054088
            +vt 0.934179 0.059095
            +vt 0.951332 0.104019
            +vt 0.960764 0.128263
            +vt 0.967254 0.146926
            +vt 0.971455 0.166602
            +vt 0.973708 0.193884
            +vt 0.974100 0.235363
            +vt 0.916857 0.772196
            +vt 0.928246 0.775926
            +vt 0.929047 0.782057
            +vt 0.931954 0.793661
            +vt 0.931603 0.797227
            +vt 0.929831 0.801624
            +vt 0.841087 0.891193
            +vt 0.833841 0.896045
            +vt 0.835183 0.901329
            +vt 0.835024 0.917266
            +vt 0.830186 0.996931
            +vt 0.799440 0.999500
            +vt 0.932006 0.002150
            +vt 0.925525 0.004784
            +vt 0.925776 0.034051
            +vt 0.930009 0.042562
            +vt 0.933898 0.047571
            +vt 0.941415 0.054088
            +vt 0.945350 0.059095
            +vt 0.964657 0.104019
            +vt 0.975196 0.128262
            +vt 0.982404 0.146926
            +vt 0.987047 0.166602
            +vt 0.989530 0.193884
            +vt 0.989962 0.235363
            +vt 0.925776 0.772196
            +vt 0.938649 0.775926
            +vt 0.939554 0.782057
            +vt 0.942836 0.793661
            +vt 0.942441 0.797227
            +vt 0.940439 0.801624
            +vt 0.855623 0.878718
            +vt 0.861735 0.978941
            +vt 0.860881 0.983802
            +vt 0.830752 0.996931
            +vt 0.799444 0.999500
            +vt 0.800717 0.000499
            +vt 0.924979 0.000499
            +vt 0.934187 0.004784
            +vt 0.934469 0.034051
            +vt 0.939267 0.042562
            +vt 0.943672 0.047571
            +vt 0.952192 0.054088
            +vt 0.956648 0.059095
            +vt 0.978416 0.104019
            +vt 0.990192 0.128262
            +vt 0.998187 0.146926
            +vt -0.017596 0.146926
            +vt -0.012953 0.166602
            +vt 0.003307 0.166602
            +vt -0.017596 0.146926
            +vt -0.001813 0.146926
            +vt -0.012953 0.166602
            +vt -0.010470 0.193884
            +vt 0.006035 0.193884
            +vt -0.012953 0.166602
            +vt -0.010470 0.193884
            +vt -0.010038 0.235363
            +vt 0.006508 0.235363
            +vt -0.010470 0.193884
            +vt 0.934471 0.772196
            +vt -0.010038 0.235363
            +vt -0.065529 0.772196
            +vt 0.949059 0.775926
            +vt 0.950082 0.782057
            +vt 0.953803 0.793661
            +vt 0.953355 0.797227
            +vt 0.951087 0.801624
            +vt 0.842683 0.891193
            +vt 0.836210 0.901329
            +vt 0.836037 0.917266
            +vt 0.855171 0.990257
            +vt 0.830823 0.996931
            +vt 0.799461 0.999500
            +vt 0.942615 0.004784
            +vt 0.942936 0.034051
            +vt 0.948400 0.042562
            +vt 0.953420 0.047571
            +vt 0.963130 0.054088
            +vt 0.968202 0.059095
            +vt 0.973601 0.067603
            +vt 0.992854 0.104019
            +vt -0.021584 0.104019
            +vt -0.009808 0.128262
            +vt 0.006037 0.128262
            +vt -0.021584 0.104019
            +vt -0.007146 0.104019
            +vt -0.009808 0.128262
            +vt -0.001813 0.146926
            +vt 0.014904 0.146926
            +vt -0.009808 0.128262
            +vt 0.020539 0.166602
            +vt -0.001813 0.146926
            +vt -0.001813 0.146926
            +vt 0.023527 0.193884
            +vt 0.024046 0.235363
            +vt -0.057064 0.772196
            +vt -0.065529 0.772196
            +vt 0.959558 0.775926
            +vt 0.942936 0.772196
            +vt 0.960726 0.782057
            +vt 0.964963 0.793661
            +vt 0.964453 0.797227
            +vt 0.961868 0.801624
            +vt 0.859107 0.878718
            +vt 0.866217 0.978941
            +vt 0.865219 0.983802
            +vt 0.861196 0.987459
            +vt 0.830355 0.996931
            +vt 0.799490 0.999500
            +vt 0.947890 0.002150
            +vt 0.950737 0.004784
            +vt 0.951107 0.034051
            +vt 0.957380 0.042562
            +vt 0.963152 0.047571
            +vt 0.974314 0.054088
            +vt 0.980138 0.059095
            +vt 0.986327 0.067603
            +vt -0.026399 0.067603
            +vt -0.007146 0.104019
            +vt 0.008243 0.104019
            +vt -0.026399 0.067603
            +vt -0.013673 0.067603
            +vt 0.023045 0.128262
            +vt -0.007146 0.104019
            +vt -0.007146 0.104019
            +vt 0.032874 0.146926
            +vt 0.039063 0.166602
            +vt 0.042326 0.193884
            +vt 0.042890 0.235363
            +vt -0.048893 0.772196
            +vt 0.970209 0.775926
            +vt 0.942936 0.772196
            +vt 0.942936 0.772196
            +vt 0.951107 0.772196
            +vt 0.971552 0.782057
            +vt 0.976419 0.793661
            +vt 0.975833 0.797227
            +vt 0.972866 0.801624
            +vt 0.859005 0.878718
            +vt 0.841414 0.891193
            +vt 0.834747 0.901329
            +vt 0.834572 0.917266
            +vt 0.829312 0.996931
            +vt 0.799532 0.999500
            +vt 0.808440 0.000499
            +vt 0.827984 0.000499
            +vt 0.958397 0.004784
            +vt 0.958825 0.034051
            +vt 0.966112 0.042562
            +vt 0.972822 0.047571
            +vt 0.985806 0.054088
            +vt 0.992569 0.059095
            +vt 0.999741 0.067603
            +vt 0.024885 0.104019
            +vt -0.013673 0.067603
            +vt -0.013673 0.067603
            +vt -0.000259 0.067603
            +vt 0.041541 0.128262
            +vt 0.052420 0.146925
            +vt 0.059186 0.166602
            +vt 0.062725 0.193884
            +vt 0.063334 0.235363
            +vt -0.041175 0.772196
            +vt 0.981033 0.775926
            +vt 0.951107 0.772196
            +vt 0.951107 0.772196
            +vt 0.958825 0.772196
            +vt 0.982594 0.782057
            +vt 0.987089 0.790336
            +vt 0.988252 0.793661
            +vt 0.987572 0.797227
            +vt 0.984122 0.801624
            +vt 0.866926 0.978941
            +vt 0.865801 0.983802
            +vt 0.861315 0.987459
            +vt 0.854427 0.990257
            +vt 0.827667 0.996931
            +vt 0.799586 0.999500
            +vt 0.942418 0.000695
            +vt 0.961492 0.002150
            +vt 0.965370 0.004784
            +vt 0.965874 0.034051
            +vt 0.974459 0.042562
            +vt 0.982389 0.047571
            +vt 0.990039 0.050830
            +vt 0.997727 0.054088
            +vt -0.014194 0.054088
            +vt -0.007431 0.059095
            +vt 0.005703 0.059095
            +vt -0.014194 0.054088
            +vt -0.002273 0.054088
            +vt -0.007431 0.059095
            +vt -0.000259 0.067603
            +vt 0.014122 0.067603
            +vt -0.007431 0.059095
            +vt 0.043231 0.104019
            +vt -0.000259 0.067603
            +vt -0.000259 0.067603
            +vt 0.061994 0.128262
            +vt 0.073967 0.146926
            +vt 0.081293 0.166602
            +vt 0.085085 0.193884
            +vt 0.085736 0.235363
            +vt -0.034126 0.772196
            +vt 0.992091 0.775926
            +vt 0.958825 0.772196
            +vt 0.958825 0.772196
            +vt 0.965874 0.772196
            +vt 0.993937 0.782057
            +vt 0.996681 0.786664
            +vt 0.999241 0.790336
            +vt -0.012911 0.790336
            +vt -0.011748 0.793661
            +vt 0.000616 0.793661
            +vt -0.012911 0.790336
            +vt -0.000759 0.790336
            +vt 0.999811 0.797227
            +vt -0.011748 0.793661
            +vt -0.000189 0.797227
            +vt 0.995739 0.801624
            +vt 0.857217 0.878718
            +vt 0.836700 0.891193
            +vt 0.837005 0.896045
            +vt 0.830425 0.901329
            +vt 0.830262 0.917266
            +vt 0.825425 0.996931
            +vt 0.799648 0.999500
            +vt 0.966688 0.002150
            +vt 0.971336 0.004784
            +vt 0.971943 0.034051
            +vt 0.982277 0.042562
            +vt 0.991852 0.047571
            +vt -0.017611 0.047571
            +vt -0.009961 0.050830
            +vt 0.001101 0.050830
            +vt -0.017611 0.047571
            +vt -0.008148 0.047571
            +vt -0.009961 0.050830
            +vt -0.002273 0.054088
            +vt 0.010385 0.054088
            +vt -0.009961 0.050830
            +vt 0.019985 0.059096
            +vt -0.002273 0.054088
            +vt -0.002273 0.054088
            +vt 0.064120 0.104019
            +vt 0.085192 0.128262
            +vt 0.098208 0.146926
            +vt 0.105996 0.166602
            +vt 0.109977 0.193884
            +vt 0.110656 0.235363
            +vt -0.028057 0.772196
            +vt 0.003582 0.775926
            +vt -0.007909 0.775926
            +vt -0.007909 0.775926
            +vt -0.006063 0.782057
            +vt 0.005811 0.782057
            +vt -0.007909 0.775926
            +vt -0.006063 0.782057
            +vt -0.003319 0.786664
            +vt 0.009123 0.786664
            +vt -0.006063 0.782057
            +vt -0.003319 0.786664
            +vt -0.000759 0.790336
            +vt 0.012214 0.790336
            +vt -0.003319 0.786664
            +vt 0.013868 0.793661
            +vt -0.000759 0.790336
            +vt -0.000759 0.790336
            +vt 0.012900 0.797227
            +vt -0.000189 0.797227
            +vt -0.000189 0.797227
            +vt -0.004261 0.801624
            +vt 0.007988 0.801624
            +vt -0.000189 0.797227
            +vt 0.849425 0.878718
            +vt -0.004261 0.801624
            +vt -0.150575 0.878718
            +vt 0.862300 0.978941
            +vt 0.861117 0.983802
            +vt 0.839075 0.990257
            +vt 0.822600 0.996931
            +vt 0.799720 0.999500
            +vt 0.952114 0.000499
            +vt 0.975689 0.004784
            +vt 0.976438 0.034051
            +vt 0.989275 0.042562
            +vt -0.017723 0.042562
            +vt -0.008148 0.047571
            +vt 0.001242 0.047571
            +vt -0.017723 0.042562
            +vt -0.010725 0.042562
            +vt 0.012820 0.050830
            +vt -0.008148 0.047571
            +vt -0.008148 0.047571
            +vt 0.024412 0.054088
            +vt 0.036325 0.059096
            +vt 0.088982 0.104019
            +vt 0.112354 0.128263
            +vt 0.126131 0.146926
            +vt 0.134137 0.166602
            +vt 0.138161 0.193884
            +vt 0.138842 0.235363
            +vt -0.023562 0.772196
            +vt 0.015921 0.775926
            +vt 0.028744 0.793661
            +vt 0.027542 0.797227
            +vt 0.021426 0.801624
            +vt -0.156839 0.878718
            +vt -0.150575 0.878718
            +vt 0.823188 0.901329
            +vt 0.819212 0.996931
            +vt 0.799800 0.999500
            +vt 0.804743 0.000499
            +vt 0.800315 0.000499
            +vt 0.977050 0.004784
            +vt 0.978017 0.034051
            +vt 0.994760 0.042562
            +vt 0.010548 0.047571
            +vt -0.010725 0.042562
            +vt -0.010725 0.042562
            +vt -0.005240 0.042562
            +vt 0.041137 0.054088
            +vt 0.056617 0.059096
            +vt 0.120181 0.104019
            +vt 0.145145 0.128263
            +vt 0.158920 0.146926
            +vt 0.166623 0.166602
            +vt 0.170417 0.193884
            +vt 0.171054 0.235363
            +vt -0.021983 0.772196
            +vt 0.029973 0.775926
            +vt 0.033642 0.782057
            +vt 0.046797 0.793661
            +vt 0.045230 0.797227
            +vt 0.037215 0.801624
            +vt -0.164798 0.878718
            +vt 0.827497 0.885757
            +vt 0.843161 0.878718
            +vt 0.843161 0.878718
            +vt 0.835202 0.878718
            +vt 0.814267 0.896045
            +vt 0.823057 0.917266
            +vt 0.850642 0.978941
            +vt 0.849546 0.983802
            +vt 0.845287 0.987459
            +vt 0.815296 0.996931
            +vt 0.799888 0.999500
            +vt -0.005240 0.042562
            +vt -0.005240 0.042562
            +vt -0.003314 0.042562
            +vt 0.835202 0.878718
            +vt 0.835202 0.878718
            +vt 0.825613 0.878718
            +vt 0.586033 0.598289
            +vt 0.590978 0.597133
            +vt 0.627022 0.597179
            +vt 0.578683 0.601813
            +vt 0.576851 0.605343
            +vt 0.578455 0.606507
            +vt 0.612542 0.606553
            +vt 0.627261 0.598343
            +vt 0.625860 0.599987
            +vt 0.620031 0.603756
            +vt 0.616351 0.605396
            +vt 0.594993 0.614954
            +vt 0.631490 0.614999
            +vt 0.590004 0.616392
            +vt 0.585752 0.618430
            +vt 0.580993 0.623109
            +vt 0.580951 0.625150
            +vt 0.582672 0.626595
            +vt 0.617584 0.626640
            +vt 0.621359 0.625202
            +vt 0.624963 0.623164
            +vt 0.628132 0.620826
            +vt 0.630549 0.618485
            +vt 0.631823 0.616443
            +vt 0.593367 0.653754
            +vt 0.588686 0.646120
            +vt 0.591438 0.656467
            +vt 0.586924 0.640188
            +vt 0.622541 0.640211
            +vt 0.633559 0.656408
            +vt 0.640425 0.653689
            +vt 0.642881 0.652240
            +vt 0.644197 0.650977
            +vt 0.603063 0.638161
            +vt 0.640152 0.638145
            +vt 0.601354 0.651036
            +vt 0.596754 0.652303
            +vt 0.590583 0.649513
            +vt 0.626710 0.649497
            +vt 0.637213 0.655141
            +vt 0.606686 0.650138
            +vt 0.643915 0.650087
            +vt 0.593361 0.666967
            +vt 0.593266 0.657357
            +vt 0.629721 0.657305
            +vt 0.609379 0.665128
            +vt 0.646397 0.665077
            +vt 0.603874 0.665455
            +vt 0.595878 0.684833
            +vt 0.593103 0.667423
            +vt 0.594821 0.667743
            +vt 0.631193 0.667692
            +vt 0.635127 0.667365
            +vt 0.642336 0.666378
            +vt 0.644999 0.665853
            +vt 0.646515 0.665398
            +vt 0.609854 0.685051
            +vt 0.646642 0.685001
            +vt 0.604358 0.684999
            +vt 0.599522 0.684923
            +vt 0.595194 0.684600
            +vt 0.631364 0.684550
            +vt 0.635296 0.684602
            +vt 0.639108 0.684679
            +vt 0.644267 0.702492
            +vt 0.646739 0.684942
            +vt 0.609061 0.703242
            +vt 0.645618 0.703192
            +vt 0.594185 0.715359
            +vt 0.592130 0.713369
            +vt 0.594749 0.700919
            +vt 0.630643 0.700870
            +vt 0.640095 0.715295
            +vt 0.643930 0.717286
            +vt 0.607384 0.717992
            +vt 0.643700 0.717943
            +vt 0.602138 0.717342
            +vt 0.597577 0.716419
            +vt 0.593852 0.712711
            +vt 0.629429 0.712661
            +vt 0.631095 0.722171
            +vt 0.636875 0.714235
            +vt 0.639503 0.727796
            +vt 0.604067 0.730766
            +vt 0.640076 0.730716
            +vt 0.599150 0.729563
            +vt 0.594978 0.727856
            +vt 0.588365 0.734960
            +vt 0.587262 0.732176
            +vt 0.592296 0.714296
            +vt 0.592300 0.721017
            +vt 0.627485 0.720968
            +vt 0.637363 0.725835
            +vt 0.640542 0.729506
            +vt 0.598891 0.741876
            +vt 0.634412 0.741827
            +vt 0.594448 0.740166
            +vt 0.587672 0.729747
            +vt 0.589710 0.728029
            +vt 0.624361 0.727980
            +vt 0.627679 0.729691
            +vt 0.630635 0.732115
            +vt 0.628046 0.746986
            +vt 0.635233 0.740109
            +vt 0.592341 0.751879
            +vt 0.627063 0.751830
            +vt 0.585275 0.747046
            +vt 0.576509 0.750254
            +vt 0.583320 0.737706
            +vt 0.585493 0.735700
            +vt 0.619328 0.735650
            +vt 0.626887 0.743734
            +vt 0.628192 0.749824
            +vt 0.584870 0.762125
            +vt 0.581274 0.760031
            +vt 0.570419 0.765043
            +vt 0.579523 0.745182
            +vt 0.612096 0.745134
            +vt 0.614929 0.747227
            +vt 0.617237 0.750194
            +vt 0.611019 0.768412
            +vt 0.609402 0.773519
            +vt 0.569643 0.779757
            +vt 0.567499 0.776659
            +vt 0.567115 0.766446
            +vt 0.604634 0.773043
            +vt 0.604728 0.779701
            +vt 0.572640 0.781943
            +vt 0.603277 0.781895
            +vt 0.560144 0.781200
            +vt 0.569185 0.764253
            +vt 0.598965 0.764205
            +vt 0.601457 0.766391
            +vt 0.603374 0.769488
            +vt 0.600325 0.782087
            +vt 0.568650 0.787821
            +vt 0.598071 0.787773
            +vt 0.565948 0.785473
            +vt 0.560437 0.777205
            +vt 0.566173 0.769548
            +vt 0.566471 0.768824
            +vt 0.595306 0.768777
            +vt 0.599669 0.785418
            +vt 0.564728 0.791131
            +vt 0.592856 0.791083
            +vt 0.562320 0.788674
            +vt 0.560780 0.785193
            +vt 0.561667 0.773720
            +vt 0.563835 0.771256
            +vt 0.591709 0.771208
            +vt 0.593728 0.773665
            +vt 0.595045 0.777146
            +vt 0.595649 0.781139
            +vt 0.595515 0.785134
            +vt 0.594601 0.788619
            +vt 0.560510 0.792189
            +vt 0.587165 0.792142
            +vt 0.552142 0.781813
            +vt 0.552678 0.777877
            +vt 0.560378 0.772198
            +vt 0.586997 0.772151
            +vt 0.583170 0.785689
            +vt 0.581983 0.789123
            +vt 0.555381 0.791597
            +vt 0.580155 0.791550
            +vt 0.553489 0.789176
            +vt 0.552410 0.785747
            +vt 0.554002 0.774443
            +vt 0.556086 0.772016
            +vt 0.581105 0.771970
            +vt 0.582709 0.774389
            +vt 0.583561 0.777819
            +vt 0.583703 0.781754
            +vt 0.550689 0.783125
            +vt 0.573604 0.783079
            +vt 0.549038 0.780873
            +vt 0.548164 0.777680
            +vt 0.546225 0.762505
            +vt 0.550014 0.767154
            +vt 0.552031 0.764894
            +vt 0.575441 0.764847
            +vt 0.576836 0.767101
            +vt 0.572644 0.769072
            +vt 0.575433 0.780819
            +vt 0.547840 0.774053
            +vt 0.569509 0.774006
            +vt 0.546338 0.772016
            +vt 0.545583 0.769130
            +vt 0.547564 0.759616
            +vt 0.549528 0.757572
            +vt 0.571840 0.757526
            +vt 0.573104 0.759562
            +vt 0.573428 0.765760
            +vt 0.571320 0.771963
            +vt 0.545883 0.762728
            +vt 0.566626 0.762682
            +vt 0.544497 0.761032
            +vt 0.543845 0.758628
            +vt 0.543894 0.755869
            +vt 0.545554 0.765818
            +vt 0.545972 0.750700
            +vt 0.547912 0.748997
            +vt 0.569445 0.748951
            +vt 0.570594 0.750647
            +vt 0.570975 0.753051
            +vt 0.570684 0.755810
            +vt 0.569812 0.758571
            +vt 0.568437 0.760979
            +vt 0.544397 0.748463
            +vt 0.564395 0.748417
            +vt 0.543089 0.747067
            +vt 0.541261 0.725309
            +vt 0.541970 0.723245
            +vt 0.544661 0.738560
            +vt 0.546560 0.737157
            +vt 0.567409 0.737111
            +vt 0.565353 0.727316
            +vt 0.566181 0.747014
            +vt 0.543000 0.730437
            +vt 0.562286 0.730393
            +vt 0.541744 0.729170
            +vt 0.543350 0.698042
            +vt 0.563623 0.698972
            +vt 0.566562 0.723189
            +vt 0.566230 0.725252
            +vt 0.561410 0.704917
            +vt 0.541292 0.705944
            +vt 0.540102 0.704969
            +vt 0.539570 0.703586
            +vt 0.541175 0.727372
            +vt 0.540351 0.700410
            +vt 0.541598 0.699024
            +vt 0.562629 0.697998
            +vt 0.563904 0.700354
            +vt 0.563568 0.701942
            +vt 0.562709 0.703531
            +vt 0.540667 0.685852
            +vt 0.559740 0.705899
            +vt 0.539003 0.684196
            +vt 0.539107 0.683081
            +vt 0.541024 0.680989
            +vt 0.561635 0.680254
            +vt 0.562859 0.681908
            +vt 0.561485 0.664106
            +vt 0.560362 0.685117
            +vt 0.541498 0.642498
            +vt 0.560534 0.643129
            +vt 0.538537 0.610108
            +vt 0.538456 0.647304
            +vt 0.538049 0.645244
            +vt 0.538693 0.644142
            +vt 0.560489 0.645189
            +vt 0.559682 0.646291
            +vt 0.556887 0.647936
            +vt 0.536982 0.608495
            +vt 0.537664 0.606320
            +vt 0.538769 0.605371
            +vt 0.557673 0.604654
            +vt 0.558865 0.606267
            +vt 0.556664 0.609392
            +vt 0.536977 0.589840
            +vt 0.536585 0.588490
            +vt 0.539795 0.586687
            +vt 0.557684 0.587086
            +vt 0.557670 0.588436
            +vt 0.557825 0.608441
            +vt 0.538023 0.590282
            +vt 0.536507 0.589213
            +vt 0.537182 0.587767
            +vt 0.538266 0.587136
            +vt 0.556788 0.586645
            +vt 0.557951 0.587714
            +vt 0.556923 0.589159
            +vt 0.555780 0.589791
            +vt 0.537808 0.561124
            +vt 0.554304 0.590239
            +vt 0.536318 0.560572
            +vt 0.536397 0.560198
            +vt 0.536989 0.559822
            +vt 0.538061 0.559494
            +vt 0.557220 0.559444
            +vt 0.557201 0.560143
            +vt 0.556460 0.560519
            +vt 0.555330 0.560847
            +vt 0.537661 0.540648
            +vt 0.553532 0.540605
            +vt 0.536673 0.523745
            +vt 0.536879 0.524476
            +vt 0.537929 0.524695
            +vt 0.539400 0.539441
            +vt 0.555961 0.539398
            +vt 0.557095 0.539754
            +vt 0.555965 0.523916
            +vt 0.554859 0.523696
            +vt 0.537680 0.523586
            +vt 0.553429 0.523543
            +vt 0.536222 0.523968
            +vt 0.539407 0.524847
            +vt 0.555833 0.524805
            +vt 0.556702 0.524646
            +vt 0.556689 0.524168
            +vt 0.537999 0.506618
            +vt 0.553740 0.506576
            +vt 0.536987 0.507182
            +vt 0.537300 0.490224
            +vt 0.536300 0.524222
            +vt 0.538217 0.510590
            +vt 0.539688 0.511148
            +vt 0.556085 0.511106
            +vt 0.556960 0.510542
            +vt 0.557144 0.488807
            +vt 0.555163 0.507134
            +vt 0.538730 0.486823
            +vt 0.554623 0.486781
            +vt 0.537703 0.487667
            +vt 0.537236 0.488859
            +vt 0.537870 0.491589
            +vt 0.538915 0.492777
            +vt 0.540393 0.493615
            +vt 0.556923 0.493573
            +vt 0.557812 0.492729
            +vt 0.558095 0.491537
            +vt 0.557848 0.490171
            +vt 0.556050 0.487619
            +vt 0.540064 0.459702
            +vt 0.539001 0.460868
            +vt 0.538509 0.462515
            +vt 0.538560 0.464404
            +vt 0.539127 0.466291
            +vt 0.540182 0.467935
            +vt 0.541683 0.469095
            +vt 0.558557 0.469054
            +vt 0.559479 0.467888
            +vt 0.559790 0.466240
            +vt 0.559564 0.464351
            +vt 0.558871 0.462465
            +vt 0.557775 0.460820
            +vt 0.539951 0.446481
            +vt 0.542124 0.435223
            +vt 0.541625 0.452874
            +vt 0.560825 0.446430
            +vt 0.543119 0.427506
            +vt 0.556332 0.459661
            +vt 0.541995 0.428871
            +vt 0.541526 0.433013
            +vt 0.562527 0.438467
            +vt 0.563494 0.437102
            +vt 0.563594 0.432961
            +vt 0.561735 0.428824
            +vt 0.545419 0.397538
            +vt 0.543117 0.415121
            +vt 0.543815 0.419512
            +vt 0.544973 0.421424
            +vt 0.546610 0.422773
            +vt 0.568210 0.405653
            +vt 0.566085 0.419462
            +vt 0.565076 0.415070
            +vt 0.550655 0.364933
            +vt 0.564607 0.396152
            +vt 0.546822 0.383761
            +vt 0.544980 0.401621
            +vt 0.546854 0.405699
            +vt 0.572707 0.375476
            +vt 0.571139 0.388039
            +vt 0.568233 0.401570
            +vt 0.566210 0.397492
            +vt 0.549438 0.366246
            +vt 0.549052 0.370230
            +vt 0.547636 0.388089
            +vt 0.575878 0.362453
            +vt 0.575741 0.358539
            +vt 0.569986 0.383711
            +vt 0.548916 0.368103
            +vt 0.549805 0.372356
            +vt 0.551131 0.374208
            +vt 0.552967 0.375516
            +vt 0.572732 0.368053
            +vt 0.571395 0.366200
            +vt 0.552833 0.343062
            +vt 0.552504 0.346948
            +vt 0.554752 0.350829
            +vt 0.580828 0.337317
            +vt 0.569680 0.364894
            +vt 0.557365 0.325709
            +vt 0.558751 0.340424
            +vt 0.579619 0.340386
            +vt 0.579372 0.333199
            +vt 0.575605 0.343017
            +vt 0.557989 0.318576
            +vt 0.554205 0.333247
            +vt 0.561194 0.315820
            +vt 0.585978 0.315776
            +vt 0.582915 0.323617
            +vt 0.576068 0.330140
            +vt 0.558868 0.308225
            +vt 0.556453 0.323666
            +vt 0.588161 0.304472
            +vt 0.582963 0.308182
            +vt 0.560649 0.298722
            +vt 0.566038 0.304510
            +vt 0.583571 0.296209
            +vt 0.562331 0.296247
            +vt 0.561009 0.300384
            +vt 0.562083 0.302044
            +vt 0.589087 0.303446
            +vt 0.589148 0.301997
            +vt 0.587272 0.298675
            +vt 0.563369 0.287537
            +vt 0.564493 0.275581
            +vt 0.566061 0.283533
            +vt 0.567539 0.293013
            +vt 0.589805 0.292976
            +vt 0.589193 0.281770
            +vt 0.564001 0.280922
            +vt 0.585263 0.280885
            +vt 0.568416 0.283898
            +vt 0.590675 0.283860
            +vt 0.591494 0.283489
            +vt 0.591402 0.282966
            +vt 0.585340 0.275959
            +vt 0.563090 0.269059
            +vt 0.566348 0.275476
            +vt 0.568700 0.275399
            +vt 0.590821 0.275362
            +vt 0.590675 0.275656
            +vt 0.564100 0.270917
            +vt 0.585001 0.270880
            +vt 0.562927 0.270458
            +vt 0.568386 0.267191
            +vt 0.590240 0.267154
            +vt 0.591056 0.267614
            +vt 0.564402 0.249488
            +vt 0.566573 0.248780
            +vt 0.582942 0.254449
            +vt 0.562739 0.254485
            +vt 0.561233 0.252783
            +vt 0.587644 0.248743
            +vt 0.588487 0.249447
            +vt 0.587802 0.251592
            +vt 0.586702 0.248796
            +vt 0.562968 0.250626
            +vt 0.561429 0.252927
            +vt 0.563806 0.254758
            +vt 0.581768 0.254758
            +vt 0.588318 0.250626
            +vt 0.586373 0.252927
            +vt 0.567975 0.248796
            +vt 0.585616 0.245108
            +vt 0.587038 0.246708
            +vt 0.583981 0.245794
            +vt 0.563829 0.250354
            +vt 0.561777 0.248752
            +vt 0.564075 0.244270
            +vt 0.581149 0.246933
            +vt 0.567082 0.243132
            +vt 0.564462 0.246933
            +vt 0.565829 0.244412
            +vt 0.584219 0.243132
            +vt 0.581240 0.244412
            +vt 0.625630 0.597286
            +vt 0.587079 0.598549
            +vt 0.582126 0.600187
            +vt 0.577575 0.605476
            +vt 0.580223 0.606739
            +vt 0.610585 0.606739
            +vt 0.615550 0.605476
            +vt 0.626595 0.598549
            +vt 0.619702 0.603837
            +vt 0.622717 0.590632
            +vt 0.593624 0.597286
            +vt 0.623628 0.591726
            +vt 0.622757 0.593172
            +vt 0.620664 0.594792
            +vt 0.617690 0.596413
            +vt 0.580179 0.598952
            +vt 0.577911 0.597859
            +vt 0.577616 0.596413
            +vt 0.578998 0.594792
            +vt 0.581893 0.593172
            +vt 0.613486 0.595146
            +vt 0.609696 0.596109
            +vt 0.586053 0.589624
            +vt 0.590856 0.588662
            +vt 0.589854 0.586965
            +vt 0.619124 0.586965
            +vt 0.619245 0.588770
            +vt 0.609875 0.592993
            +vt 0.581638 0.592993
            +vt 0.579949 0.591188
            +vt 0.588087 0.586417
            +vt 0.614609 0.586417
            +vt 0.611096 0.588728
            +vt 0.584941 0.588728
            +vt 0.941865 0.249668
            +vt 0.942209 0.243418
            +vt 0.942209 0.243418
            +vt 0.942209 0.243418
            +vt 0.942209 0.243418
            +vt 0.942824 0.243454
            +vt 0.942824 0.243454
            +vt 0.937724 0.249662
            +vt 0.939743 0.249666
            +vt 0.939275 0.256241
            +vt 0.939743 0.249666
            +vt 0.941865 0.249668
            +vt 0.942127 0.256246
            +vt 0.939743 0.249666
            +vt 0.942127 0.256246
            +vt 0.939275 0.256241
            +vt 0.941865 0.249668
            +vt 0.944075 0.249669
            +vt 0.945101 0.256248
            +vt 0.944075 0.249669
            +vt 0.948971 0.249665
            +vt 0.951699 0.256240
            +vt 0.944075 0.249669
            +vt 0.951699 0.256240
            +vt 0.945101 0.256248
            +vt 0.937724 0.249662
            +vt 0.942209 0.243418
            +vt 0.939743 0.249666
            +vt 0.939743 0.249666
            +vt 0.942209 0.243418
            +vt 0.941865 0.249668
            +vt 0.941865 0.249668
            +vt 0.942209 0.243418
            +vt 0.944075 0.249669
            +vt 0.944075 0.249669
            +vt 0.942824 0.243454
            +vt 0.948971 0.249665
            +vt 0.942824 0.243454
            +vt 0.944075 0.249669
            +vt 0.942209 0.243418
            +vt 0.943549 0.235363
            +vt 0.928679 0.235363
            +vt 0.928394 0.193884
            +vt 0.943230 0.193884
            +vt 0.943549 0.235363
            +vt 0.928394 0.193884
            +vt 0.958678 0.235363
            +vt 0.943549 0.235363
            +vt 0.943230 0.193884
            +vt 0.943549 0.235363
            +vt 0.958678 0.235363
            +vt 0.944549 0.243720
            +vt 0.943549 0.235363
            +vt 0.944549 0.243720
            +vt 0.944298 0.243611
            +vt 0.939330 0.247459
            +vt 0.928679 0.235363
            +vt 0.943549 0.235363
            +vt 0.943549 0.235363
            +vt 0.940372 0.244716
            +vt 0.939330 0.247459
            +vt 0.940807 0.244049
            +vt 0.940372 0.244716
            +vt 0.943549 0.235363
            +vt 0.941105 0.243762
            +vt 0.940807 0.244049
            +vt 0.943549 0.235363
            +vt 0.941348 0.243609
            +vt 0.941105 0.243762
            +vt 0.943549 0.235363
            +vt 0.941567 0.243518
            +vt 0.941348 0.243609
            +vt 0.943549 0.235363
            +vt 0.941681 0.243484
            +vt 0.941567 0.243518
            +vt 0.943549 0.235363
            +vt 0.941790 0.243460
            +vt 0.941681 0.243484
            +vt 0.943549 0.235363
            +vt 0.941790 0.243460
            +vt 0.943549 0.235363
            +vt 0.941894 0.243442
            +vt 0.941999 0.243430
            +vt 0.941894 0.243442
            +vt 0.943549 0.235363
            +vt 0.941999 0.243430
            +vt 0.943549 0.235363
            +vt 0.942103 0.243422
            +vt 0.942209 0.243418
            +vt 0.942103 0.243422
            +vt 0.943549 0.235363
            +vt 0.943549 0.235363
            +vt 0.942824 0.243454
            +vt 0.942209 0.243418
            +vt 0.942824 0.243454
            +vt 0.943549 0.235363
            +vt 0.943139 0.243500
            +vt 0.943549 0.235363
            +vt 0.943152 0.243503
            +vt 0.943139 0.243500
            +vt 0.943549 0.235363
            +vt 0.943397 0.243491
            +vt 0.943152 0.243503
            +vt 0.943397 0.243491
            +vt 0.943549 0.235363
            +vt 0.943627 0.243493
            +vt 0.943627 0.243493
            +vt 0.943549 0.235363
            +vt 0.943846 0.243510
            +vt 0.943549 0.235363
            +vt 0.944298 0.243611
            +vt 0.944066 0.243546
            +vt 0.943846 0.243510
            +vt 0.943549 0.235363
            +vt 0.944066 0.243546
            +vn -0.009519 -0.945491 0.325509
            +vn 0.812261 -0.539436 0.221905
            +vn 0.789654 -0.507356 0.345016
            +vn -0.402735 -0.812863 0.420782
            +vn -0.968229 0.237156 -0.079311
            +vn 0.960794 -0.270757 -0.059711
            +vn 0.960367 -0.255844 -0.110634
            +vn 0.963331 -0.261899 -0.058338
            +vn 0.952304 -0.291264 -0.091007
            +vn 0.925985 -0.313715 -0.210081
            +vn 0.855832 -0.495783 -0.147481
            +vn 0.615580 -0.754477 -0.227653
            +vn 0.546400 -0.677088 -0.492950
            +vn 0.054240 -0.927915 -0.368824
            +vn -0.348976 -0.910862 -0.220332
            +vn -0.690029 -0.690641 -0.216506
            +vn -0.522764 -0.837308 -0.160107
            +vn -0.628111 -0.768203 -0.123859
            +vn -0.713196 -0.684553 -0.150793
            +vn -0.711019 -0.699019 -0.076313
            +vn -0.733990 -0.676509 -0.059957
            +vn -0.767576 -0.636126 -0.078555
            +vn -0.766429 -0.640014 -0.054480
            +vn -0.767563 -0.640602 -0.021804
            +vn -0.767563 -0.640602 -0.021804
            +vn -0.767563 -0.640602 -0.021804
            +vn -0.756976 -0.652699 -0.031169
            +vn -0.769280 -0.638011 -0.033905
            +vn -0.754917 -0.654684 -0.038596
            +vn -0.767131 -0.641356 -0.013137
            +vn -0.767131 -0.641356 -0.013137
            +vn -0.767131 -0.641356 -0.013137
            +vn -0.768284 -0.639824 -0.019114
            +vn -0.768284 -0.639824 -0.019114
            +vn -0.768284 -0.639824 -0.019114
            +vn -0.767484 -0.641053 -0.004370
            +vn -0.767484 -0.641053 -0.004370
            +vn -0.767484 -0.641053 -0.004370
            +vn -0.768078 -0.640327 -0.006115
            +vn -0.770189 -0.637668 0.013721
            +vn -0.767739 -0.640640 -0.012549
            +vn -0.771878 -0.635695 0.009831
            +vn -0.771878 -0.635695 0.009831
            +vn -0.771878 -0.635695 0.009831
            +vn -0.767416 -0.640996 0.014027
            +vn -0.767416 -0.640996 0.014027
            +vn -0.767416 -0.640996 0.014027
            +vn -0.584710 -0.780946 0.219632
            +vn -0.736655 -0.672370 0.072513
            +vn -0.757913 -0.648214 0.073397
            +vn -0.770649 -0.636133 0.037886
            +vn -0.901840 -0.430627 -0.035298
            +vn -0.709292 -0.686305 0.160905
            +vn -0.655491 -0.745515 0.120580
            +vn -0.554565 -0.811691 0.183346
            +vn -0.420675 -0.779647 0.463878
            +vn 0.904373 -0.315675 0.287156
            +vn 0.913867 -0.376369 0.152294
            +vn 0.947877 -0.242765 0.206381
            +vn 0.943955 -0.317211 0.091248
            +vn 0.959628 -0.255810 0.116938
            +vn 0.961851 -0.268786 0.050962
            +vn 0.949625 -0.236304 -0.205849
            +vn -0.381284 -0.787610 -0.484038
            +vn -0.713956 -0.643652 -0.275641
            +vn -0.760655 -0.631643 -0.149769
            +vn -0.757509 -0.630782 0.168211
            +vn 0.736918 -0.395514 0.548197
            +vn -0.020155 -0.664228 0.747258
            +vn 0.960894 -0.256614 0.104073
            +vn 0.850375 -0.339819 -0.401728
            +vn 0.645656 -0.424372 -0.634852
            +vn 0.169668 -0.693920 -0.699777
            +vn -0.822270 -0.547339 -0.155857
            +vn -0.814733 -0.576935 -0.057931
            +vn -0.771627 -0.626654 0.109072
            +vn -0.695269 -0.649225 0.308396
            +vn -0.567723 -0.657130 0.495853
            +vn 0.898881 -0.227317 0.374620
            +vn 0.943656 -0.204215 -0.260403
            +vn -0.416496 -0.522302 -0.744132
            +vn -0.605522 -0.565077 -0.560384
            +vn -0.724346 -0.573569 -0.382546
            +vn -0.769947 -0.595335 -0.229693
            +vn -0.815916 -0.578125 0.007198
            +vn -0.780193 -0.589487 0.209293
            +vn 0.655100 -0.236417 0.717601
            +vn 0.050960 -0.379217 0.923903
            +vn 0.951219 -0.232277 0.203049
            +vn 0.955373 -0.244047 -0.166441
            +vn 0.958207 -0.252263 -0.134916
            +vn 0.883539 -0.129133 -0.450204
            +vn 0.683171 -0.154810 -0.713660
            +vn 0.178938 -0.330812 -0.926577
            +vn -0.821584 -0.564381 0.080459
            +vn -0.741550 -0.559614 0.370049
            +vn -0.574321 -0.493277 0.653324
            +vn 0.847794 -0.140641 0.511337
            +vn 0.937767 -0.186920 0.292667
            +vn -0.819215 -0.528390 -0.222914
            +vn -0.820297 -0.470575 0.325073
            +vn 0.530060 -0.167912 0.831169
            +vn -0.567390 -0.358722 -0.741207
            +vn -0.699035 -0.403447 -0.590407
            +vn -0.769258 -0.439506 -0.463763
            +vn -0.803951 -0.474059 -0.359070
            +vn -0.834993 -0.512400 0.200581
            +vn -0.751118 -0.407415 0.519455
            +vn -0.011889 -0.247376 0.968847
            +vn 0.949289 -0.218699 -0.225880
            +vn 0.912799 -0.179363 -0.366916
            +vn 0.814239 -0.152925 -0.560026
            +vn 0.538081 -0.155932 -0.828344
            +vn 0.128518 -0.212277 -0.968722
            +vn -0.338021 -0.302534 -0.891187
            +vn -0.522581 -0.338227 0.782631
            +vn 0.800821 -0.165718 0.575521
            +vn 0.911334 -0.203180 0.358034
            +vn 0.452890 -0.123228 0.883009
            +vn -0.008753 -0.144177 0.989513
            +vn 0.736689 -0.147683 0.659908
            +vn 0.871321 -0.190077 0.452405
            +vn 0.933559 -0.228798 0.275896
            +vn 0.953102 -0.246684 0.175339
            +vn 0.930245 -0.231687 -0.284543
            +vn 0.950206 -0.252135 -0.183128
            +vn 0.869312 -0.192955 -0.455044
            +vn 0.734545 -0.151641 -0.661399
            +vn 0.454918 -0.126192 -0.881547
            +vn 0.104258 -0.130112 -0.986003
            +vn -0.280475 -0.171184 -0.944473
            +vn -0.503227 -0.211294 -0.837924
            +vn -0.658640 -0.252004 -0.709004
            +vn -0.759002 -0.289649 -0.583111
            +vn -0.821687 -0.322828 -0.469694
            +vn -0.868088 -0.358651 -0.343210
            +vn -0.890885 -0.393161 -0.227481
            +vn -0.905718 -0.409599 -0.109104
            +vn -0.909667 -0.415181 0.011445
            +vn -0.906059 -0.403558 0.127273
            +vn -0.887125 -0.377500 0.265525
            +vn -0.838703 -0.334894 0.429446
            +vn -0.722386 -0.276690 0.633720
            +vn -0.459539 -0.206680 0.863775
            +vn 0.400128 -0.068098 0.913926
            +vn -0.005634 -0.053921 0.998529
            +vn 0.683734 -0.118437 0.720056
            +vn 0.839645 -0.176244 0.513745
            +vn 0.920947 -0.228968 0.315326
            +vn 0.916298 -0.224602 -0.331590
            +vn 0.837989 -0.177066 -0.516161
            +vn 0.682135 -0.119830 -0.721341
            +vn 0.398703 -0.069308 -0.914457
            +vn 0.091991 -0.049819 -0.994513
            +vn -0.241436 -0.064365 -0.968280
            +vn -0.450030 -0.092003 -0.888262
            +vn -0.612385 -0.127027 -0.780287
            +vn -0.729949 -0.163921 -0.663554
            +vn -0.811676 -0.199084 -0.549133
            +vn -0.863153 -0.228089 -0.450491
            +vn -0.898055 -0.261650 -0.353604
            +vn -0.918905 -0.273267 -0.284496
            +vn -0.933802 -0.293360 -0.204824
            +vn -0.944606 -0.297421 -0.138782
            +vn -0.948611 -0.309353 -0.066621
            +vn -0.951998 -0.302980 0.043613
            +vn -0.943763 -0.291635 0.155759
            +vn -0.910363 -0.260944 0.321165
            +vn -0.836387 -0.212435 0.505301
            +vn -0.686658 -0.150878 0.711152
            +vn -0.408751 -0.088858 0.908310
            +vn 0.360552 -0.013054 0.932648
            +vn -0.002657 0.023464 0.999721
            +vn 0.638924 -0.082739 0.764808
            +vn 0.810435 -0.156241 0.564610
            +vn 0.899638 -0.211125 0.382200
            +vn 0.809346 -0.155975 -0.566243
            +vn 0.909261 -0.224699 -0.350365
            +vn 0.638102 -0.083241 -0.765439
            +vn 0.360314 -0.013934 -0.932727
            +vn 0.084015 0.021174 -0.996239
            +vn -0.210864 0.024705 -0.977203
            +vn -0.403848 0.008029 -0.914791
            +vn -0.565192 -0.019575 -0.824727
            +vn -0.692121 -0.052887 -0.719841
            +vn -0.787904 -0.087492 -0.609551
            +vn -0.852700 -0.117687 -0.508973
            +vn -0.899659 -0.143988 -0.412166
            +vn -0.930648 -0.164238 -0.326987
            +vn -0.952943 -0.180592 -0.243487
            +vn -0.967940 -0.192682 -0.161138
            +vn -0.976530 -0.200062 -0.079779
            +vn -0.978291 -0.200875 0.050958
            +vn -0.965270 -0.188153 0.181252
            +vn -0.916765 -0.153313 0.368832
            +vn -0.818984 -0.100940 0.564869
            +vn -0.644832 -0.040462 0.763253
            +vn -0.365444 0.009868 0.930781
            +vn 0.326708 0.043210 0.944137
            +vn 0.000036 0.092303 0.995731
            +vn 0.596852 -0.040403 0.801333
            +vn 0.780832 -0.129512 0.611170
            +vn 0.888746 -0.202077 0.411456
            +vn 0.780273 -0.128350 -0.612128
            +vn 0.886141 -0.195581 -0.420123
            +vn 0.596836 -0.040252 -0.801353
            +vn 0.327650 0.042544 -0.943841
            +vn 0.077670 0.086498 -0.993220
            +vn -0.184715 0.100284 -0.977662
            +vn -0.361456 0.090570 -0.927980
            +vn -0.517091 0.068349 -0.853197
            +vn -0.647800 0.037991 -0.760863
            +vn -0.753322 0.003834 -0.657640
            +vn -0.829171 -0.027723 -0.558307
            +vn -0.887001 -0.056043 -0.458354
            +vn -0.926842 -0.078672 -0.367118
            +vn -0.956385 -0.097270 -0.275439
            +vn -0.976734 -0.111145 -0.183405
            +vn -0.988615 -0.119734 -0.091122
            +vn -0.990980 -0.120888 0.057830
            +vn -0.972934 -0.106008 0.205332
            +vn -0.908885 -0.066228 0.411755
            +vn -0.789429 -0.009622 0.613766
            +vn -0.598480 0.049972 0.799577
            +vn -0.326141 0.091602 0.940872
            +vn 0.300062 0.117337 0.946676
            +vn 0.006832 0.154524 0.987965
            +vn 0.558405 0.047132 0.828228
            +vn 0.754698 -0.034682 0.655155
            +vn 0.882295 -0.102982 0.459293
            +vn 0.755237 -0.037428 -0.654382
            +vn 0.880538 -0.106104 -0.461946
            +vn 0.560115 0.043822 -0.827255
            +vn 0.302674 0.114858 -0.946148
            +vn 0.061177 0.155097 -0.986003
            +vn -0.150122 0.163814 -0.975002
            +vn -0.319372 0.145209 -0.936438
            +vn -0.468026 0.123009 -0.875111
            +vn -0.597460 0.096181 -0.796110
            +vn -0.711858 0.064364 -0.699368
            +vn -0.795489 0.032845 -0.605077
            +vn -0.864331 0.002850 -0.502916
            +vn -0.913060 -0.021144 -0.407276
            +vn -0.950439 -0.041282 -0.308159
            +vn -0.976811 -0.056564 -0.206495
            +vn -0.992473 -0.066176 -0.103043
            +vn -0.995573 -0.068171 0.064708
            +vn -0.971907 -0.052461 0.229446
            +vn -0.889491 -0.007976 0.456883
            +vn -0.753238 0.048772 0.655937
            +vn -0.549455 0.107669 0.828557
            +vn -0.287291 0.149182 0.946155
            +vn 0.285028 0.209005 0.935455
            +vn 0.012699 0.203871 0.978915
            +vn 0.530384 0.201475 0.823469
            +vn 0.727882 0.181427 0.661265
            +vn 0.871897 0.157829 0.463556
            +vn 0.935621 0.231288 0.266681
            +vn 0.730402 0.164928 -0.662806
            +vn 0.860052 0.174537 -0.479425
            +vn 0.533052 0.188007 -0.824929
            +vn 0.288558 0.200858 -0.936157
            +vn 0.060538 0.226713 -0.972078
            +vn -0.131469 0.229243 -0.964450
            +vn -0.308471 0.176492 -0.934717
            +vn -0.445356 0.164289 -0.880152
            +vn -0.566548 0.140972 -0.811880
            +vn -0.685405 0.089640 -0.722624
            +vn -0.772530 0.081679 -0.629702
            +vn -0.843884 0.056805 -0.533509
            +vn -0.898362 0.044964 -0.436949
            +vn -0.944883 0.065123 -0.320868
            +vn -0.973127 0.093203 -0.210565
            +vn -0.988071 0.093347 -0.122484
            +vn -0.995088 0.075387 0.064158
            +vn -0.971442 0.067417 0.227496
            +vn -0.878615 0.050737 0.474828
            +vn -0.731313 0.086989 0.676472
            +vn -0.530992 0.111141 0.840056
            +vn -0.261910 0.163209 0.951192
            +vn 0.972320 -0.024965 -0.232314
            +vn 0.542805 0.828231 -0.139271
            +vn 0.660155 0.734370 -0.157784
            +vn 0.725097 0.665663 0.176427
            +vn -0.944297 0.327010 0.036986
            +vn 0.614296 0.564185 -0.551666
            +vn 0.488783 0.443297 -0.751385
            +vn 0.277856 0.335963 0.899958
            +vn 0.688238 0.629159 0.361230
            +vn 0.490621 0.445199 0.749058
            +vn 0.615525 0.565975 0.548453
            +vn 0.691673 0.627440 -0.357643
            +vn 0.261163 0.326405 -0.908435
            +vn -0.671052 0.148097 -0.726469
            +vn 0.741264 0.647506 -0.176814
            +vn -0.277932 0.182919 0.943024
            +vn 0.025023 0.252141 0.967367
            +vn 0.749227 0.662313 0.000798
            +vn -0.847718 0.130697 -0.514093
            +vn -0.909763 0.139624 -0.390943
            +vn 0.514150 0.367296 0.775076
            +vn 0.669325 0.452264 0.589458
            +vn 0.767415 0.497614 0.404295
            +vn 0.810255 0.552684 0.195005
            +vn 0.826358 0.563142 0.001956
            +vn 0.810512 0.553666 -0.191113
            +vn 0.758476 0.524118 -0.387317
            +vn 0.655144 0.467125 -0.593785
            +vn -0.783527 0.156112 -0.601427
            +vn -0.894639 0.144698 0.422709
            +vn -0.739225 0.158289 0.654593
            +vn -0.542200 0.152613 0.826274
            +vn 0.862552 0.468143 0.191955
            +vn 0.889871 0.456210 -0.001289
            +vn 0.871695 0.447105 -0.200614
            +vn 0.807806 0.430855 -0.402261
            +vn 0.682573 0.387659 -0.619528
            +vn 0.511750 0.358319 -0.780845
            +vn 0.109912 0.297723 -0.948304
            +vn -0.144244 0.266503 -0.952980
            +vn -0.325661 0.239166 -0.914737
            +vn -0.465028 0.214079 -0.859022
            +vn -0.586130 0.202681 -0.784457
            +vn -0.945825 0.152118 -0.286837
            +vn -0.966832 0.146012 0.209562
            +vn -0.280847 0.251123 0.926317
            +vn 0.301535 0.325852 0.896045
            +vn 0.001574 0.291287 0.956634
            +vn 0.696363 0.372279 0.613586
            +vn 0.821814 0.391651 0.413801
            +vn 0.897139 0.388338 0.210561
            +vn -0.529280 0.227550 0.817364
            +vn 0.516922 0.314113 0.796319
            +vn 0.935864 0.352356 0.001764
            +vn 0.912231 0.353675 -0.206759
            +vn 0.836317 0.362593 -0.411218
            +vn 0.741974 0.369818 -0.559204
            +vn 0.510381 0.322773 -0.797075
            +vn 0.289326 0.322976 -0.901098
            +vn -0.706982 0.194586 -0.679935
            +vn -0.780601 0.184737 -0.597105
            +vn -0.877833 0.166968 -0.448922
            +vn -0.978783 0.161258 -0.126414
            +vn -0.989355 0.140950 0.036200
            +vn -0.878485 0.170490 0.446315
            +vn -0.729615 0.204717 0.652497
            +vn 0.277144 0.318139 0.906630
            +vn -0.013304 0.294602 0.955527
            +vn 0.717543 0.344121 0.605568
            +vn 0.850595 0.316245 0.420092
            +vn 0.928711 0.300471 0.217287
            +vn -0.279876 0.274024 0.920098
            +vn 0.967472 0.252966 0.002471
            +vn 0.941980 0.253185 -0.220389
            +vn 0.854533 0.280923 -0.436871
            +vn 0.723684 0.311008 -0.616082
            +vn 0.065650 0.311841 -0.947864
            +vn -0.159572 0.288166 -0.944191
            +vn -0.304387 0.273895 -0.912321
            +vn -0.445668 0.257570 -0.857343
            +vn -0.590295 0.233656 -0.772630
            +vn -0.742607 0.209294 -0.636185
            +vn -0.859155 0.185456 -0.476926
            +vn -0.911673 0.174116 -0.372203
            +vn -0.962194 0.164559 -0.217033
            +vn 0.713974 0.273136 0.644700
            +vn 0.850192 0.245435 0.465763
            +vn 0.951014 0.210427 0.226481
            +vn 0.724387 0.244483 -0.644587
            +vn -0.512990 0.246142 0.822348
            +vn 0.248585 0.283327 0.926246
            +vn 0.524460 0.240747 0.816690
            +vn 0.512487 0.261797 -0.817813
            +vn 0.274480 0.282806 -0.919065
            +vn 0.863337 0.171104 0.474734
            +vn 0.988919 0.148444 -0.002060
            +vn 0.956044 0.161849 -0.244510
            +vn -0.953480 0.166183 0.251513
            +vn -0.865175 0.182333 0.467147
            +vn -0.725542 0.208728 0.655760
            +vn -0.006766 0.247057 0.968977
            +vn 0.721610 0.200581 0.662606
            +vn 0.871162 0.183674 -0.455348
            +vn 0.071823 0.271223 -0.959833
            +vn -0.984384 0.162242 0.068312
            +vn -0.246321 0.241736 0.938557
            +vn 0.958465 0.144969 0.245620
            +vn 0.726117 0.189948 -0.660813
            +vn -0.152500 0.247282 -0.956867
            +vn -0.282270 0.242650 -0.928140
            +vn -0.648869 0.215159 -0.729846
            +vn 0.269542 0.232081 0.934604
            +vn 0.501371 0.219702 -0.836874
            +vn 0.257388 0.239600 -0.936132
            +vn -0.415391 0.235231 -0.878702
            +vn -0.544026 0.228835 -0.807261
            +vn -0.505153 0.218989 0.834784
            +vn 0.502779 0.191732 0.842883
            +vn 0.074060 0.206007 -0.975744
            +vn -0.843309 0.190802 -0.502419
            +vn 0.262406 0.194017 0.945252
            +vn 0.987698 0.156374 0.000499
            +vn 0.687417 0.174369 -0.705020
            +vn 0.499408 0.184882 -0.846410
            +vn 0.261144 0.193097 -0.945789
            +vn -0.960203 0.161441 -0.227917
            +vn 0.673671 0.180508 0.716648
            +vn 0.849616 0.169364 0.499469
            +vn 0.950461 0.160099 0.266443
            +vn 0.953860 0.157936 -0.255357
            +vn 0.847305 0.164240 -0.505074
            +vn -0.168626 0.182480 -0.968642
            +vn -0.265817 0.185793 -0.945951
            +vn -0.405001 0.172411 -0.897913
            +vn -0.565418 0.172273 -0.806613
            +vn -0.721581 0.174598 -0.669952
            +vn -0.986620 0.161476 -0.022487
            +vn -0.687841 0.189504 0.700688
            +vn -0.001461 0.178115 0.984008
            +vn -0.949221 0.136783 0.283318
            +vn -0.850220 0.145103 0.506035
            +vn -0.467732 0.189148 0.863394
            +vn -0.229852 0.177233 0.956952
            +vn 0.477024 0.168932 0.862502
            +vn 0.073886 0.152195 -0.985585
            +vn -0.881345 0.105146 -0.460624
            +vn 0.256462 0.154478 0.954130
            +vn 0.680797 0.175084 0.711239
            +vn 0.838634 0.179302 -0.514339
            +vn 0.486061 0.172243 -0.856783
            +vn 0.254202 0.155782 -0.954523
            +vn -0.743978 0.092078 -0.661830
            +vn -0.762240 0.095200 -0.640255
            +vn -0.971498 0.053817 -0.230858
            +vn -0.682870 0.108168 0.722488
            +vn -0.019807 0.101007 0.994689
            +vn 0.941753 0.223758 -0.251066
            +vn 0.633523 0.173894 -0.753929
            +vn -0.202858 0.113050 -0.972660
            +vn -0.381675 0.124942 -0.915813
            +vn -0.654860 0.029052 -0.755191
            +vn -0.999128 0.033597 0.024795
            +vn -0.481506 0.106296 0.869973
            +vn 0.814612 0.189825 0.548064
            +vn 0.940991 0.199015 0.273731
            +vn 0.975873 0.218098 -0.010303
            +vn 0.427537 0.162467 -0.889278
            +vn -0.961329 0.034684 0.273209
            +vn -0.864093 0.052947 0.500540
            +vn -0.668815 0.045182 0.742054
            +vn -0.228313 0.083761 0.969978
            +vn 0.434217 0.165625 0.885451
            +vn 0.660003 0.214943 0.719858
            +vn 0.839896 0.211757 -0.499733
            +vn -0.002548 0.093771 -0.995591
            +vn -0.414292 0.029606 -0.909662
            +vn -0.817369 0.046220 -0.574258
            +vn -0.952757 -0.015594 -0.303333
            +vn -0.999925 -0.010542 0.006213
            +vn -0.493165 0.010738 0.869870
            +vn 0.295618 0.142845 0.944566
            +vn 0.833734 0.318044 0.451371
            +vn 0.905897 0.335488 0.258454
            +vn 0.697577 0.252258 -0.670635
            +vn 0.280760 0.137953 -0.949812
            +vn -0.962366 -0.043064 0.268324
            +vn -0.867223 -0.014220 0.497717
            +vn -0.732251 -0.056417 0.678694
            +vn 0.016681 0.049217 0.998649
            +vn 0.682898 0.285465 0.672429
            +vn 0.928017 0.367631 0.060267
            +vn 0.905958 0.347612 -0.241673
            +vn 0.790840 0.315876 -0.524208
            +vn 0.083734 0.063895 -0.994438
            +vn -0.281829 0.017821 -0.959299
            +vn -0.592008 -0.086064 -0.801323
            +vn -0.816607 -0.020745 -0.576822
            +vn 0.668923 0.327070 -0.667508
            +vn 0.562960 0.240888 -0.790601
            +vn -0.272581 -0.092147 -0.957710
            +vn -0.250632 -0.035215 0.967442
            +vn 0.818722 0.352762 0.453050
            +vn 0.876312 0.407511 0.256929
            +vn -0.896541 -0.363461 -0.253201
            +vn -0.931983 -0.362212 0.014532
            +vn -0.447106 -0.217178 -0.867715
            +vn -0.872205 -0.257610 0.415806
            +vn -0.665965 -0.300771 0.682662
            +vn -0.491775 -0.174683 0.853020
            +vn -0.721276 -0.303978 -0.622381
            +vn -0.858966 -0.353661 -0.370271
            +vn -0.888794 -0.401686 0.220667
            +vn 0.792806 0.373832 -0.481361
            +vn 0.495810 0.233231 0.836526
            +vn -0.749689 -0.458314 0.477404
            +vn 0.614691 0.330688 0.716101
            +vn -0.021177 -0.062529 -0.997818
            +vn -0.847518 -0.530757 -0.003263
            +vn -0.247818 -0.176540 0.952586
            +vn -0.001850 -0.047379 0.998875
            +vn -0.700080 -0.421661 -0.576273
            +vn -0.827171 -0.515297 0.224179
            +vn 0.251815 0.134401 0.958397
            +vn 0.918159 0.395429 0.024898
            +vn 0.878989 0.401302 -0.257555
            +vn 0.230153 0.125431 -0.965037
            +vn -0.289754 -0.202928 -0.935341
            +vn 0.467440 0.239142 -0.851065
            +vn -0.484703 -0.342350 -0.804897
            +vn -0.782075 -0.532768 -0.323291
            +vn -0.617898 -0.488172 0.616352
            +vn -0.461985 -0.343399 0.817708
            +vn -0.648703 -0.567136 -0.507485
            +vn -0.787673 -0.612844 -0.063189
            +vn -0.777464 -0.604841 0.172386
            +vn -0.706503 -0.553012 0.441623
            +vn 0.751318 0.474791 0.458362
            +vn 0.832529 0.552265 -0.043577
            +vn 0.206136 -0.067944 0.976162
            +vn 0.437338 0.320542 0.840231
            +vn 0.580932 0.449561 0.678537
            +vn 0.721082 0.667172 0.186876
            +vn 0.782023 0.577820 -0.233589
            +vn 0.706499 0.545773 -0.450546
            +vn 0.603408 0.474339 -0.641016
            +vn 0.421848 0.346901 -0.837678
            +vn -0.377707 -0.439275 -0.815092
            +vn -0.543116 -0.489908 -0.681920
            +vn -0.714195 -0.622124 -0.320758
            +vn -0.470691 -0.535319 0.701344
            +vn -0.299916 -0.433280 0.849894
            +vn 0.655955 0.655501 0.374222
            +vn -0.069719 -0.333623 -0.940125
            +vn -0.766437 -0.640641 -0.046395
            +vn -0.752271 -0.632295 0.185181
            +vn -0.668299 -0.605778 0.431752
            +vn -0.591470 -0.555866 0.584103
            +vn -0.063385 -0.350327 0.934480
            +vn 0.466435 0.228840 0.854442
            +vn 0.578765 0.523590 0.625208
            +vn 0.589341 0.796675 0.134110
            +vn 0.643123 0.765675 -0.011598
            +vn 0.619309 0.768701 -0.159861
            +vn 0.252776 -0.030966 -0.967029
            +vn -0.495327 -0.586790 -0.640569
            +vn 0.586444 0.723566 0.364055
            +vn 0.595833 0.727233 -0.340757
            +vn 0.525137 0.585059 -0.618011
            +vn -0.859746 -0.224666 -0.458652
            +vn -0.908830 -0.364433 -0.203019
            +vn -0.999054 -0.032799 0.028544
            +vn -0.956478 -0.115488 0.267979
            +vn -0.884369 -0.060571 0.462842
            +vn 0.279057 0.434672 0.856264
            +vn 0.018151 -0.097744 0.995046
            +vn 0.538549 0.585720 0.605720
            +vn 0.327037 -0.018187 -0.944836
            +vn 0.518820 0.551457 -0.653239
            +vn -0.127239 -0.557834 -0.820141
            +vn -0.712663 0.112075 -0.692496
            +vn -0.560830 -0.164563 0.811412
            +vn -0.288356 0.172328 0.941888
            +vn 0.517925 0.853928 -0.050603
            +vn 0.455411 0.877899 -0.147966
            +vn 0.265570 0.944866 -0.191575
            +vn 0.014766 0.955863 0.293442
            +vn 0.111660 0.987603 0.110330
            +vn 0.295089 0.943443 0.151122
            +vn 0.080873 0.982592 -0.167247
            +vn -0.068737 0.787209 -0.612843
            +vn -0.141574 0.936761 -0.320056
            +vn -0.435756 0.872402 -0.221431
            +vn -0.775715 0.611591 -0.155633
            +vn -0.630479 0.754325 0.183002
            +vn -0.302953 0.917355 0.258225
            +vn -0.101307 0.974967 0.197929
            +vn 0.749484 0.660323 -0.047410
            +vn -0.206921 -0.022654 -0.978095
            +vn -0.412195 -0.220369 -0.884043
            +vn 0.006080 0.034312 -0.999393
            +vn 0.212610 0.247000 -0.945404
            +vn 0.391818 0.404572 -0.826317
            +vn 0.527213 0.546519 -0.650664
            +vn -0.599155 -0.324296 -0.732014
            +vn 0.682759 0.529722 -0.503224
            +vn 0.757970 0.588960 -0.280369
            +vn -0.741736 -0.444514 -0.502230
            +vn -0.842480 -0.482633 -0.239358
            +vn -0.858858 -0.508906 0.058111
            +vn -0.789035 -0.514462 0.335787
            +vn -0.693062 -0.398644 0.600623
            +vn 0.779282 0.596581 0.191860
            +vn -0.530267 -0.285079 0.798465
            +vn 0.718059 0.554910 0.420078
            +vn -0.335118 -0.094788 0.937396
            +vn 0.602890 0.508025 0.615170
            +vn -0.124563 0.007446 0.992184
            +vn 0.427336 0.547931 0.719135
            +vn 0.092404 0.307197 0.947149
            +vn 0.285341 0.320087 0.903396
            +vn 0.243485 0.426571 -0.871064
            +vn -0.513373 -0.206106 -0.833048
            +vn -0.702248 -0.272308 -0.657797
            +vn -0.291060 -0.111796 -0.950150
            +vn -0.061954 0.004033 -0.998071
            +vn 0.163703 0.135459 -0.977165
            +vn 0.658837 0.521640 -0.542057
            +vn 0.535845 0.404793 -0.740954
            +vn 0.729892 0.611012 -0.306467
            +vn 0.743407 0.666913 -0.050738
            +vn 0.697587 0.686119 0.206428
            +vn 0.595217 0.668556 0.445813
            +vn 0.444138 0.617309 0.649362
            +vn 0.255225 0.537948 0.803413
            +vn 0.043567 0.438298 0.897773
            +vn -0.173583 0.319450 0.931569
            +vn -0.381171 0.205253 0.901432
            +vn -0.578644 0.096292 0.809876
            +vn -0.739794 -0.011011 0.672743
            +vn -0.862088 -0.112441 0.494127
            +vn -0.938657 -0.194923 0.284479
            +vn -0.965696 -0.255371 0.047086
            +vn -0.935403 -0.292384 -0.198828
            +vn -0.844659 -0.300341 -0.443110
            +vn -0.766831 -0.602364 0.221648
            +vn -0.980988 -0.091229 0.171288
            +vn -0.984932 0.045515 0.166844
            +vn -0.976006 0.182708 0.118445
            +vn -0.967518 0.233700 0.096405
            +vn 0.932499 -0.356568 -0.057479
            +vn 0.860156 -0.500573 -0.097767
            +vn 0.670753 -0.727479 -0.144447
            +vn 0.267707 -0.947388 -0.175467
            +vn -0.111222 -0.980305 -0.163193
            +vn -0.366194 -0.920483 -0.136428
            +vn -0.491723 -0.862997 -0.115952
            +vn -0.568507 -0.816579 -0.099998
            +vn -0.647525 -0.758031 -0.078100
            +vn -0.695645 -0.715813 -0.060737
            +vn -0.719124 -0.693077 -0.050037
            +vn -0.701214 -0.710546 -0.058501
            +vn -0.736523 -0.675221 -0.040133
            +vn -0.749123 -0.661714 -0.030830
            +vn -0.758154 -0.651720 -0.021514
            +vn -0.758154 -0.651720 -0.021514
            +vn -0.758154 -0.651720 -0.021514
            +vn -0.763218 -0.646009 -0.013076
            +vn -0.763218 -0.646009 -0.013076
            +vn -0.763218 -0.646009 -0.013076
            +vn -0.765264 -0.643701 -0.004366
            +vn -0.765264 -0.643701 -0.004366
            +vn -0.765264 -0.643701 -0.004366
            +vn 0.760323 0.649062 0.025043
            +vn 0.760323 0.649062 0.025043
            +vn 0.760323 0.649062 0.025043
            +vn -0.766737 -0.641887 0.009762
            +vn -0.766737 -0.641887 0.009762
            +vn -0.766737 -0.641887 0.009762
            +vn -0.767956 -0.639985 -0.025741
            +vn -0.767956 -0.639985 -0.025741
            +vn -0.767956 -0.639985 -0.025741
            +vn -0.765059 -0.643849 0.011978
            +vn -0.769186 -0.638988 0.006915
            +vn -0.698139 -0.713664 0.057326
            +vn -0.628742 -0.773353 0.081298
            +vn -0.494583 -0.861799 0.112654
            +vn -0.100080 -0.982118 0.159460
            +vn 0.218620 -0.960683 0.171155
            +vn -0.967646 0.239584 -0.079119
            +vn -0.967639 0.239232 0.080267
            +vn 0.715760 -0.200276 0.669012
            +vn 0.550520 -0.161842 -0.818984
            +vn 0.897790 -0.225013 0.378606
            +vn -0.759822 0.198474 -0.619094
            +vn -0.717075 0.276981 0.639597
            +vn -0.942462 0.246831 -0.225479
            +vn -0.956483 0.248968 0.152169
            +vn -0.966411 0.248181 0.066750
            +vn -0.944107 0.268427 -0.191334
            +vn -0.967078 0.245704 -0.066258
            +vn -0.959987 0.272006 -0.066619
            +vn 0.000542 -1.000000 -0.000382
            +vn -0.007906 -0.999814 0.017617
            +vn 0.000000 -1.000000 -0.000000
            +vn 0.008751 -0.999803 0.017810
            +vn 0.007994 -0.993938 0.109655
            +vn 0.089327 -0.925938 0.366960
            +vn -0.059144 -0.917421 0.393497
            +vn 0.114821 -0.276124 0.954239
            +vn 0.004341 -0.125700 0.992059
            +vn 0.000234 -0.149346 0.988785
            +vn 0.129633 -0.149235 0.980268
            +vn 0.104488 -0.610077 0.785422
            +vn 0.000812 -0.610086 0.792335
            +vn 0.078047 -0.807434 0.584772
            +vn 0.000872 -0.807454 0.589929
            +vn 0.076149 -0.817570 0.570772
            +vn 0.000802 -0.817559 0.575844
            +vn 0.102565 -0.634745 0.765885
            +vn 0.001468 -0.634738 0.772726
            +vn 0.099415 -0.660462 0.744249
            +vn 0.001176 -0.660473 0.750849
            +vn 0.090284 -0.731994 0.675303
            +vn 0.001131 -0.731986 0.681319
            +vn 0.096435 -0.684263 0.722831
            +vn 0.001037 -0.684254 0.729243
            +vn 0.117120 -0.457738 0.881339
            +vn 0.000802 -0.457734 0.889089
            +vn 0.129626 -0.152027 0.979839
            +vn 0.000309 -0.152022 0.988377
            +vn 0.127283 0.223237 0.966418
            +vn -0.000256 0.223235 0.974765
            +vn 0.125511 0.242535 0.961989
            +vn -0.001459 0.242537 0.970141
            +vn 0.028719 -0.976365 0.214212
            +vn 0.000434 -0.976363 0.216136
            +vn 0.000524 -0.976364 0.216133
            +vn 0.028809 -0.976367 0.214193
            +vn 0.118196 -0.323738 0.938735
            +vn 0.000581 -0.327470 0.944861
            +vn 0.000279 -0.205892 0.978575
            +vn 0.128040 -0.205803 0.970181
            +vn 0.126607 -0.266889 0.955375
            +vn 0.000516 -0.266885 0.963728
            +vn 0.119402 0.402636 0.907539
            +vn -0.000370 0.402684 0.915339
            +vn 0.090498 0.718590 0.689520
            +vn -0.000468 0.718587 0.695437
            +vn 0.086845 0.722899 0.685474
            +vn -0.003585 0.722900 0.690943
            +vn 0.084591 0.678825 0.729411
            +vn 0.059622 0.630336 0.774030
            +vn 0.274663 0.033381 0.960961
            +vn -0.022501 0.115869 0.993010
            +vn -0.000673 0.515351 0.856979
            +vn 0.034910 0.967940 0.248745
            +vn -0.009993 0.962044 0.272711
            +vn 0.047369 0.895698 0.442133
            +vn 0.122409 0.014258 0.992377
            +vn -0.000268 0.014299 0.999898
            +vn 0.000005 -0.027978 -0.999609
            +vn 0.000000 -1.000000 0.000000
            +vn 0.258273 -0.078784 0.962854
            +vn 0.256409 -0.149257 0.954975
            +vn 0.206082 -0.610105 0.765050
            +vn 0.153686 -0.807436 0.569585
            +vn 0.149973 -0.817564 0.555965
            +vn 0.201623 -0.634749 0.745950
            +vn 0.195686 -0.660444 0.724928
            +vn 0.177639 -0.731990 0.657750
            +vn 0.189962 -0.684288 0.704035
            +vn 0.231157 -0.457752 0.858505
            +vn 0.256422 -0.152033 0.954533
            +vn 0.252349 0.223235 0.941534
            +vn 0.249930 0.242536 0.937396
            +vn 0.056432 -0.976363 0.208638
            +vn 0.056506 -0.976362 0.208624
            +vn 0.230961 -0.320794 0.918558
            +vn 0.243158 -0.252704 0.936491
            +vn 0.236863 0.402560 0.884218
            +vn 0.179752 0.718584 0.671808
            +vn 0.175636 0.722900 0.668257
            +vn 0.187677 0.651395 0.735161
            +vn 0.430700 0.504630 0.748229
            +vn 0.369460 -0.264359 0.890850
            +vn 0.069782 -0.266601 0.961278
            +vn 0.248174 -0.279610 0.927484
            +vn -0.000453 -0.281248 0.959635
            +vn 0.183346 0.552123 0.813354
            +vn 0.046464 0.423332 0.904782
            +vn 0.317918 0.737735 0.595545
            +vn 0.086311 0.718704 0.689938
            +vn 0.172789 0.898806 0.402855
            +vn 0.113714 0.943546 0.311110
            +vn 0.070927 0.965988 0.248668
            +vn 0.244927 0.014033 0.969440
            +vn 0.092194 -0.963994 0.249432
            +vn 0.381444 -0.079441 0.920972
            +vn 0.378566 -0.149289 0.913455
            +vn 0.303950 -0.610041 0.731755
            +vn 0.226384 -0.804058 0.549765
            +vn 0.221079 -0.817567 0.531703
            +vn 0.297028 -0.634745 0.713354
            +vn 0.288416 -0.660442 0.693277
            +vn 0.261765 -0.731982 0.629033
            +vn 0.280006 -0.684293 0.673305
            +vn 0.340965 -0.457773 0.821089
            +vn 0.378510 -0.152039 0.913025
            +vn 0.372788 0.223234 0.900664
            +vn 0.369894 0.242537 0.896858
            +vn 0.083110 -0.976358 0.199545
            +vn 0.083189 -0.976358 0.199510
            +vn 0.371055 -0.249914 0.894350
            +vn 0.361983 -0.327770 0.872660
            +vn 0.349928 0.402663 0.845821
            +vn 0.265714 0.718594 0.642665
            +vn 0.270731 0.719679 0.639348
            +vn 0.114476 0.639803 0.759966
            +vn 0.456181 0.095012 0.884800
            +vn 0.309520 -0.020552 0.950671
            +vn 0.454675 0.049690 0.889270
            +vn -0.751971 -0.006964 -0.659159
            +vn 0.233827 -0.918591 0.318614
            +vn 0.493010 -0.163348 0.854552
            +vn 0.494386 -0.149232 0.856336
            +vn 0.396659 -0.610027 0.685951
            +vn 0.313812 -0.778800 0.543132
            +vn 0.267671 -0.851366 0.451141
            +vn 0.292072 -0.809863 0.508740
            +vn 0.387397 -0.634738 0.668604
            +vn 0.376240 -0.660434 0.649823
            +vn 0.341456 -0.731990 0.589574
            +vn 0.365286 -0.684295 0.631115
            +vn 0.444959 -0.457769 0.769714
            +vn 0.494171 -0.152039 0.855967
            +vn 0.486891 0.223235 0.844454
            +vn 0.483629 0.242533 0.841000
            +vn 0.108398 -0.976359 0.187012
            +vn 0.108484 -0.976361 0.186948
            +vn 0.489244 -0.206070 0.847452
            +vn 0.495242 -0.336041 0.801131
            +vn 0.486974 -0.260815 0.833566
            +vn 0.457124 0.402590 0.793070
            +vn 0.347450 0.718657 0.602337
            +vn 0.376990 0.723476 0.578326
            +vn 0.631652 -0.260900 0.730032
            +vn 0.485332 -0.272626 0.830739
            +vn 0.516098 0.362350 0.776109
            +vn 0.318266 0.889935 0.326684
            +vn 0.125689 0.965996 0.225951
            +vn 0.512534 0.013763 0.858557
            +vn 0.013780 -0.999897 0.003881
            +vn 0.139285 -0.982051 0.127184
            +vn 0.606565 -0.079376 0.791062
            +vn 0.601908 -0.149340 0.784477
            +vn 0.482803 -0.610087 0.628247
            +vn 0.360669 -0.805870 0.469564
            +vn 0.351856 -0.816685 0.457409
            +vn 0.471411 -0.634732 0.612280
            +vn 0.457832 -0.660448 0.595146
            +vn 0.415466 -0.731987 0.539984
            +vn 0.444555 -0.684294 0.578024
            +vn 0.541657 -0.457746 0.705036
            +vn 0.601691 -0.152023 0.784128
            +vn 0.592954 0.223236 0.773674
            +vn 0.589228 0.242534 0.770706
            +vn 0.131873 -0.976360 0.171261
            +vn 0.131951 -0.976363 0.171188
            +vn 0.575408 -0.327505 0.749430
            +vn 0.595658 -0.206174 0.776327
            +vn 0.586860 -0.266897 0.764435
            +vn 0.556762 0.402480 0.726654
            +vn 0.423137 0.718610 0.551864
            +vn 0.566066 0.586763 0.579033
            +vn 0.723980 0.011166 0.689730
            +vn 0.151214 0.967934 0.200594
            +vn 0.606766 0.013559 0.794765
            +vn 0.700046 -0.186005 0.689447
            +vn 0.699309 -0.149186 0.699078
            +vn 0.560828 -0.610121 0.559664
            +vn 0.417732 -0.807493 0.416480
            +vn 0.407750 -0.817557 0.406621
            +vn 0.547449 -0.634721 0.545371
            +vn 0.531764 -0.660467 0.530104
            +vn 0.482550 -0.731988 0.480978
            +vn 0.516377 -0.684265 0.514914
            +vn 0.629254 -0.457715 0.628121
            +vn 0.699121 -0.152030 0.698653
            +vn 0.689082 0.223234 0.689444
            +vn 0.684935 0.242537 0.687051
            +vn 0.153138 -0.976363 0.152523
            +vn 0.153202 -0.976364 0.152453
            +vn 0.668506 -0.327449 0.667740
            +vn 0.692104 -0.206075 0.691755
            +vn 0.681831 -0.266767 0.681133
            +vn 0.647034 0.402548 0.647535
            +vn 0.491698 0.718652 0.491703
            +vn 0.488377 0.722800 0.488926
            +vn 0.677351 -0.270629 0.684073
            +vn 0.703714 0.387211 0.595696
            +vn 0.532231 0.710499 0.460349
            +vn 0.175958 0.968559 0.175874
            +vn 0.706820 0.014740 0.707240
            +vn 0.327539 -0.925602 0.189683
            +vn 0.762363 -0.246864 0.598214
            +vn 0.784831 -0.149243 0.601471
            +vn 0.629259 -0.610041 0.481542
            +vn 0.468645 -0.807473 0.358273
            +vn 0.457444 -0.817571 0.349747
            +vn 0.614094 -0.634740 0.469035
            +vn 0.596548 -0.660457 0.455989
            +vn 0.541344 -0.731987 0.413693
            +vn 0.579304 -0.684276 0.442914
            +vn 0.706017 -0.457734 0.540388
            +vn 0.784508 -0.152018 0.601197
            +vn 0.773363 0.223235 0.593359
            +vn 0.768976 0.242536 0.591483
            +vn 0.171779 -0.976361 0.131191
            +vn 0.171830 -0.976363 0.131107
            +vn 0.750156 -0.327481 0.574476
            +vn 0.776696 -0.206009 0.595234
            +vn 0.765088 -0.266832 0.586038
            +vn 0.726147 0.402610 0.557329
            +vn 0.551819 0.718609 0.423198
            +vn 0.687519 0.602492 0.405366
            +vn 0.849221 0.136568 0.510071
            +vn 0.805104 -0.258752 0.533719
            +vn 0.216960 0.961904 0.166338
            +vn 0.376400 0.900289 0.218640
            +vn 0.795677 0.014440 0.605549
            +vn 0.863470 -0.079372 0.498116
            +vn 0.856606 -0.149301 0.493899
            +vn 0.686712 -0.610092 0.395239
            +vn 0.511403 -0.807464 0.294056
            +vn 0.499188 -0.817556 0.287078
            +vn 0.670039 -0.634750 0.384891
            +vn 0.650961 -0.660442 0.374254
            +vn 0.590709 -0.731994 0.339482
            +vn 0.632149 -0.684276 0.363530
            +vn 0.770506 -0.457751 0.443604
            +vn 0.856269 -0.152033 0.493648
            +vn 0.844201 0.223235 0.487331
            +vn 0.839584 0.242535 0.486081
            +vn 0.187420 -0.976366 0.107630
            +vn 0.187464 -0.976367 0.107540
            +vn 0.816645 -0.323712 0.477808
            +vn 0.847634 -0.205743 0.489067
            +vn 0.835009 -0.266920 0.481159
            +vn 0.792753 0.402479 0.457769
            +vn 0.602295 0.718661 0.347514
            +vn 0.598199 0.722767 0.346072
            +vn 0.829975 -0.281783 0.481394
            +vn 0.215447 0.968569 0.124325
            +vn 0.863154 0.014204 0.504741
            +vn 0.229225 -0.972123 0.049315
            +vn 0.911504 -0.163149 0.377549
            +vn 0.913595 -0.149213 0.378259
            +vn 0.732339 -0.610055 0.302511
            +vn 0.545355 -0.807454 0.224958
            +vn 0.532301 -0.817571 0.219618
            +vn 0.714443 -0.634755 0.294376
            +vn 0.694165 -0.660435 0.286286
            +vn 0.629893 -0.731978 0.259697
            +vn 0.674087 -0.684298 0.278107
            +vn 0.821698 -0.457757 0.339514
            +vn 0.913252 -0.152042 0.377960
            +vn 0.900466 0.223235 0.373265
            +vn 0.895737 0.242538 0.372599
            +vn 0.199852 -0.976363 0.082306
            +vn 0.199891 -0.976361 0.082232
            +vn 0.869239 -0.320767 0.376209
            +vn 0.890885 -0.252746 0.377418
            +vn 0.845560 0.402601 0.350630
            +vn 0.642476 0.718612 0.266122
            +vn 0.721375 0.659369 0.211781
            +vn 0.960067 0.117553 0.253877
            +vn 0.932776 -0.255346 0.254416
            +vn 0.857790 0.391398 0.333171
            +vn 0.662853 0.711223 0.234068
            +vn 0.438256 0.893693 0.096147
            +vn 0.260680 0.962090 0.080174
            +vn 0.232788 0.967951 0.094236
            +vn 0.923584 0.014112 0.383137
            +vn -0.945437 -0.042135 -0.323068
            +vn 0.002285 -0.999997 0.000349
            +vn 0.962796 -0.079418 0.258297
            +vn 0.955094 -0.149280 0.255950
            +vn 0.765536 -0.610008 0.204560
            +vn 0.570015 -0.807447 0.152031
            +vn 0.556352 -0.817582 0.148430
            +vn 0.746707 -0.634741 0.198827
            +vn 0.725535 -0.660445 0.193418
            +vn 0.658341 -0.731985 0.175457
            +vn 0.704560 -0.684301 0.187956
            +vn 0.858915 -0.457751 0.229627
            +vn 0.954695 -0.152038 0.255816
            +vn 0.941403 0.223235 0.252838
            +vn 0.936642 0.242535 0.252744
            +vn 0.208878 -0.976360 0.055595
            +vn 0.208901 -0.976361 0.055500
            +vn 0.935350 -0.249911 0.250332
            +vn 0.912624 -0.327745 0.244337
            +vn 0.884043 0.402558 0.237518
            +vn 0.671610 0.718657 0.180199
            +vn 0.667480 0.722777 0.179062
            +vn 0.926415 -0.281778 0.249713
            +vn 0.965886 0.013881 0.258594
            +vn 0.027946 -0.999609 0.000331
            +vn 0.410485 -0.911590 0.022501
            +vn 0.978001 -0.163882 0.129062
            +vn 0.980325 -0.149328 0.129086
            +vn 0.785653 -0.610056 0.102859
            +vn 0.584956 -0.807467 0.076309
            +vn 0.570979 -0.817573 0.074544
            +vn 0.766281 -0.634732 0.099646
            +vn 0.744564 -0.660454 0.097083
            +vn 0.675605 -0.731989 0.088031
            +vn 0.723082 -0.684285 0.094373
            +vn 0.881551 -0.457738 0.115516
            +vn 0.979922 -0.152029 0.128998
            +vn 0.966354 0.223234 0.127771
            +vn 0.961615 0.242537 0.128346
            +vn 0.214337 -0.976362 0.027858
            +vn 0.214343 -0.976364 0.027750
            +vn 0.970204 -0.205815 0.127844
            +vn 0.937074 -0.335969 0.094963
            +vn 0.957745 -0.260867 0.121131
            +vn 0.907488 0.402532 0.120140
            +vn 0.689431 0.718610 0.091017
            +vn 0.769864 0.636456 -0.047269
            +vn 0.924004 0.381435 -0.026920
            +vn 0.995143 0.096178 0.020985
            +vn 0.966831 -0.255374 0.004619
            +vn 0.892459 0.427214 0.144934
            +vn 0.661330 0.749798 -0.021090
            +vn 0.249312 0.967931 0.030874
            +vn 0.990902 0.014056 0.133848
            +vn 0.996849 -0.079323 -0.000000
            +vn 0.988799 -0.149251 -0.000242
            +vn 0.792339 -0.610081 -0.000815
            +vn 0.589927 -0.807456 -0.000863
            +vn 0.575810 -0.817583 -0.000811
            +vn 0.772729 -0.634735 -0.001471
            +vn 0.750861 -0.660459 -0.001172
            +vn 0.681309 -0.731995 -0.001137
            +vn 0.729233 -0.684265 -0.001034
            +vn 0.889096 -0.457719 -0.000800
            +vn 0.988378 -0.152018 -0.000314
            +vn 0.974765 0.223233 0.000235
            +vn 0.970141 0.242535 0.001458
            +vn 0.216128 -0.976365 -0.000441
            +vn 0.216129 -0.976365 -0.000538
            +vn 0.944880 -0.327416 -0.000564
            +vn 0.978574 -0.205897 -0.000280
            +vn 0.963725 -0.266896 -0.000506
            +vn 0.915406 0.402533 0.000371
            +vn 0.695358 0.718663 0.000026
            +vn 0.692180 0.721721 -0.002176
            +vn 0.959513 -0.281660 0.001703
            +vn 0.452815 0.887802 -0.082253
            +vn 0.258696 0.965950 -0.004059
            +vn 0.999898 0.014267 0.000269
            +vn 0.915243 -0.382408 -0.126862
            +vn 0.980264 -0.149306 -0.129579
            +vn 0.785438 -0.610063 -0.104454
            +vn 0.584734 -0.807463 -0.078036
            +vn 0.570778 -0.817568 -0.076124
            +vn 0.765892 -0.634737 -0.102557
            +vn 0.744260 -0.660452 -0.099398
            +vn 0.675305 -0.731995 -0.090261
            +vn 0.722815 -0.684281 -0.096430
            +vn 0.881346 -0.457731 -0.117098
            +vn 0.979845 -0.152013 -0.129601
            +vn 0.966421 0.223235 -0.127264
            +vn 0.961995 0.242535 -0.125468
            +vn 0.214219 -0.976363 -0.028725
            +vn 0.214215 -0.976362 -0.028803
            +vn 0.938728 -0.323743 -0.118237
            +vn 0.970174 -0.205804 -0.128092
            +vn 0.955372 -0.266900 -0.126607
            +vn 0.907578 0.402543 -0.119419
            +vn 0.689438 0.718611 -0.090964
            +vn 0.798360 0.497867 -0.338747
            +vn 0.961086 0.010828 -0.276036
            +vn 0.935142 -0.255371 -0.245552
            +vn 0.850598 0.502471 -0.154940
            +vn 0.296739 0.954904 -0.010221
            +vn 0.990973 0.014393 -0.133290
            +vn 0.000000 -1.000000 -0.000000
            +vn -0.866459 -0.009248 0.499163
            +vn 0.017171 -0.999835 -0.005935
            +vn 0.429514 -0.890018 -0.152922
            +vn 0.959362 -0.125029 -0.252966
            +vn 0.954968 -0.149224 -0.256452
            +vn 0.765079 -0.610062 -0.206103
            +vn 0.569564 -0.807450 -0.153690
            +vn 0.555940 -0.817580 -0.149978
            +vn 0.745952 -0.634749 -0.201614
            +vn 0.724949 -0.660431 -0.195650
            +vn 0.657741 -0.731999 -0.177636
            +vn 0.704029 -0.684297 -0.189950
            +vn 0.858510 -0.457742 -0.231156
            +vn 0.954533 -0.152033 -0.256423
            +vn 0.941539 0.223236 -0.252327
            +vn 0.937380 0.242534 -0.249991
            +vn 0.208651 -0.976360 -0.056442
            +vn 0.208635 -0.976359 -0.056513
            +vn 0.918555 -0.320804 -0.230956
            +vn 0.936456 -0.252816 -0.243174
            +vn 0.884243 0.402510 -0.236853
            +vn 0.671620 0.718659 -0.180158
            +vn 0.669944 0.721526 -0.174861
            +vn 0.927284 -0.281793 -0.246448
            +vn 0.596864 0.740292 -0.309388
            +vn 0.242006 0.967961 -0.066971
            +vn 0.979507 -0.020753 -0.200336
            +vn 0.947875 0.049223 -0.314819
            +vn 0.920980 -0.079443 -0.381424
            +vn 0.913449 -0.149269 -0.378588
            +vn 0.731734 -0.610048 -0.303984
            +vn 0.544698 -0.807452 -0.226550
            +vn 0.531685 -0.817575 -0.221094
            +vn 0.713321 -0.634760 -0.297075
            +vn 0.693291 -0.660430 -0.288410
            +vn 0.629041 -0.731975 -0.261763
            +vn 0.673291 -0.684305 -0.280012
            +vn 0.821096 -0.457747 -0.340983
            +vn 0.913016 -0.152039 -0.378531
            +vn 0.900659 0.223234 -0.372800
            +vn 0.896848 0.242537 -0.369919
            +vn 0.199543 -0.976358 -0.083108
            +vn 0.199505 -0.976359 -0.083188
            +vn 0.894357 -0.249902 -0.371046
            +vn 0.872667 -0.327768 -0.361969
            +vn 0.845837 0.402595 -0.349966
            +vn 0.642488 0.718611 -0.266097
            +vn 0.638531 0.597310 -0.485283
            +vn 0.852897 0.077190 -0.516342
            +vn 0.839456 -0.255335 -0.479705
            +vn 0.835156 0.423149 -0.351369
            +vn 0.355627 0.903245 -0.240163
            +vn 0.295884 0.945155 -0.138330
            +vn 0.237336 0.965996 -0.102582
            +vn 0.923760 0.014189 -0.382710
            +vn 0.000000 -1.000000 -0.000000
            +vn 0.318839 -0.921491 -0.221800
            +vn 0.854548 -0.163403 -0.492998
            +vn 0.856383 -0.149171 -0.494324
            +vn 0.685921 -0.610059 -0.396662
            +vn 0.510531 -0.807475 -0.295536
            +vn 0.498381 -0.817567 -0.288446
            +vn 0.668602 -0.634732 -0.387410
            +vn 0.649793 -0.660448 -0.376266
            +vn 0.589596 -0.731981 -0.341439
            +vn 0.631117 -0.684291 -0.365291
            +vn 0.769703 -0.457760 -0.444986
            +vn 0.855971 -0.152035 -0.494165
            +vn 0.844449 0.223233 -0.486901
            +vn 0.841022 0.242535 -0.483590
            +vn 0.187006 -0.976361 -0.108388
            +vn 0.186951 -0.976362 -0.108475
            +vn 0.847523 -0.205895 -0.489196
            +vn 0.801150 -0.336022 -0.495226
            +vn 0.833559 -0.260861 -0.486962
            +vn 0.793088 0.402548 -0.457129
            +vn 0.602325 0.718656 -0.347474
            +vn 0.598614 0.722771 -0.345346
            +vn 0.833989 -0.265132 -0.483908
            +vn 0.863492 0.013926 -0.504170
            +vn -0.556464 -0.025770 0.830472
            +vn 0.798360 -0.081396 -0.596654
            +vn 0.786597 -0.148779 -0.599274
            +vn 0.628278 -0.610070 -0.482784
            +vn 0.467596 -0.807475 -0.359636
            +vn 0.456467 -0.817562 -0.351041
            +vn 0.612301 -0.634733 -0.471382
            +vn 0.595134 -0.660461 -0.457829
            +vn 0.539980 -0.731989 -0.415468
            +vn 0.578045 -0.684271 -0.444563
            +vn 0.705051 -0.457732 -0.541650
            +vn 0.784132 -0.152032 -0.601683
            +vn 0.773674 0.223235 -0.592954
            +vn 0.770705 0.242534 -0.589229
            +vn 0.171253 -0.976361 -0.131877
            +vn 0.171192 -0.976361 -0.131957
            +vn 0.749450 -0.327508 -0.575381
            +vn 0.776315 -0.206191 -0.595667
            +vn 0.764477 -0.266840 -0.586832
            +vn 0.726593 0.402670 -0.556704
            +vn 0.551851 0.718610 -0.423156
            +vn 0.554232 0.637681 -0.534966
            +vn 0.645455 -0.256534 -0.719429
            +vn 0.620054 0.419720 -0.662849
            +vn 0.197374 0.968568 -0.151390
            +vn 0.796000 0.014086 -0.605132
            +vn 0.000000 -1.000000 0.000000
            +vn 0.062982 -0.995502 -0.070771
            +vn 0.490441 -0.697234 -0.522812
            +vn 0.706581 -0.038553 -0.706581
            +vn 0.699161 -0.147853 -0.699509
            +vn 0.559672 -0.610127 -0.560814
            +vn 0.416484 -0.807494 -0.417725
            +vn 0.406633 -0.817538 -0.407777
            +vn 0.545349 -0.634731 -0.547458
            +vn 0.530104 -0.660464 -0.531768
            +vn 0.480945 -0.731996 -0.482570
            +vn 0.514909 -0.684264 -0.516383
            +vn 0.628115 -0.457722 -0.629255
            +vn 0.698660 -0.152023 -0.699116
            +vn 0.689445 0.223234 -0.689081
            +vn 0.687054 0.242535 -0.684934
            +vn 0.152523 -0.976362 -0.153148
            +vn 0.152465 -0.976361 -0.153213
            +vn 0.667696 -0.327523 -0.668513
            +vn 0.691715 -0.206230 -0.692098
            +vn 0.681110 -0.266768 -0.681853
            +vn 0.647481 0.402752 -0.646961
            +vn 0.491718 0.718653 -0.491682
            +vn 0.488953 0.722795 -0.488357
            +vn 0.556413 0.391817 -0.732724
            +vn 0.608388 0.064101 -0.791047
            +vn 0.678311 -0.282654 -0.678234
            +vn 0.432733 0.722662 -0.538983
            +vn 0.176223 0.967930 -0.179043
            +vn 0.712728 0.014394 -0.701293
            +vn 0.006267 -0.999888 -0.013594
            +vn 0.194516 -0.921392 -0.336452
            +vn 0.593465 -0.143888 -0.791893
            +vn 0.598879 -0.148783 -0.786898
            +vn 0.481560 -0.610062 -0.629225
            +vn 0.358298 -0.807451 -0.468663
            +vn 0.349778 -0.817541 -0.457473
            +vn 0.469053 -0.634734 -0.614086
            +vn 0.455980 -0.660457 -0.596556
            +vn 0.413677 -0.731995 -0.541346
            +vn 0.442912 -0.684277 -0.579304
            +vn 0.540400 -0.457721 -0.706017
            +vn 0.601190 -0.152024 -0.784512
            +vn 0.593359 0.223234 -0.773364
            +vn 0.591507 0.242536 -0.768957
            +vn 0.131191 -0.976359 -0.171792
            +vn 0.131122 -0.976360 -0.171839
            +vn 0.580192 -0.323805 -0.747347
            +vn 0.595457 -0.206188 -0.776478
            +vn 0.586040 -0.266842 -0.765083
            +vn 0.557317 0.402584 -0.726171
            +vn 0.423215 0.718611 -0.551803
            +vn 0.382028 0.637618 -0.668953
            +vn 0.225009 0.880529 -0.417180
            +vn 0.190915 0.953693 -0.232425
            +vn 0.607187 0.014084 -0.794434
            +vn 0.498137 -0.079393 -0.863456
            +vn 0.493870 -0.149267 -0.856628
            +vn 0.395232 -0.610077 -0.686729
            +vn 0.294068 -0.807427 -0.511454
            +vn 0.287071 -0.817560 -0.499185
            +vn 0.384923 -0.634743 -0.670026
            +vn 0.374232 -0.660446 -0.650970
            +vn 0.339506 -0.731983 -0.590708
            +vn 0.363509 -0.684298 -0.632137
            +vn 0.443609 -0.457756 -0.770500
            +vn 0.493651 -0.152026 -0.856269
            +vn 0.487329 0.223236 -0.844201
            +vn 0.486003 0.242533 -0.839630
            +vn 0.107629 -0.976360 -0.187448
            +vn 0.107543 -0.976363 -0.187482
            +vn 0.486154 -0.320819 -0.812853
            +vn 0.490178 -0.252709 -0.834185
            +vn 0.457748 0.402601 -0.792703
            +vn 0.347504 0.718656 -0.602308
            +vn 0.346037 0.722768 -0.598217
            +vn 0.423222 -0.257413 -0.868690
            +vn 0.480401 -0.281289 -0.830717
            +vn 0.445407 0.552057 -0.704873
            +vn 0.180147 0.793410 -0.581419
            +vn 0.124276 0.968563 -0.215503
            +vn 0.496351 0.014439 -0.868002
            +vn 0.112417 -0.964444 -0.239189
            +vn 0.381423 -0.078770 -0.921038
            +vn 0.378171 -0.149291 -0.913619
            +vn 0.302438 -0.610069 -0.732357
            +vn 0.224946 -0.807447 -0.545370
            +vn 0.219634 -0.817580 -0.532282
            +vn 0.294362 -0.634758 -0.714446
            +vn 0.286291 -0.660435 -0.694163
            +vn 0.259690 -0.731988 -0.629885
            +vn 0.278110 -0.684299 -0.674084
            +vn 0.339512 -0.457763 -0.821696
            +vn 0.377968 -0.152020 -0.913253
            +vn 0.373264 0.223235 -0.900467
            +vn 0.372603 0.242536 -0.895736
            +vn 0.082310 -0.976361 -0.199859
            +vn 0.082234 -0.976361 -0.199890
            +vn 0.370003 -0.249924 -0.894783
            +vn 0.361115 -0.325887 -0.873724
            +vn 0.350642 0.402572 -0.845568
            +vn 0.266132 0.718616 -0.642467
            +vn 0.211835 0.572537 -0.792040
            +vn 0.207449 0.157176 -0.965536
            +vn 0.094164 0.967948 -0.232829
            +vn 0.063180 0.966003 -0.250692
            +vn 0.373668 0.014297 -0.927452
            +vn -0.067443 -0.017958 0.997562
            +vn 0.064069 -0.918019 -0.391328
            +vn 0.255673 -0.163311 -0.952870
            +vn 0.256042 -0.149202 -0.955082
            +vn 0.204576 -0.610018 -0.765524
            +vn 0.152005 -0.807475 -0.569981
            +vn 0.148430 -0.817567 -0.556375
            +vn 0.198790 -0.634732 -0.746725
            +vn 0.193429 -0.660448 -0.725530
            +vn 0.175472 -0.731983 -0.658340
            +vn 0.187954 -0.684299 -0.704563
            +vn 0.229594 -0.457767 -0.858916
            +vn 0.255811 -0.152035 -0.954697
            +vn 0.252837 0.223235 -0.941403
            +vn 0.252809 0.242537 -0.936623
            +vn 0.055596 -0.976358 -0.208886
            +vn 0.055512 -0.976359 -0.208908
            +vn 0.250381 -0.249925 -0.935333
            +vn 0.244399 -0.327753 -0.912605
            +vn 0.237534 0.402520 -0.884056
            +vn 0.180197 0.718664 -0.671603
            +vn 0.179124 0.722766 -0.667476
            +vn 0.122680 -0.261919 -0.957261
            +vn 0.248325 -0.279613 -0.927444
            +vn 0.242173 0.366141 -0.898495
            +vn 0.037692 0.906848 -0.419769
            +vn 0.056952 0.943627 -0.326074
            +vn 0.258587 0.013833 -0.965889
            +vn -0.001224 -0.999999 -0.000014
            +vn -0.005610 -0.996109 -0.087955
            +vn 0.130412 -0.079399 -0.988275
            +vn 0.129129 -0.149317 -0.980321
            +vn 0.102900 -0.610058 -0.785647
            +vn 0.076351 -0.807448 -0.584978
            +vn 0.074538 -0.817562 -0.570995
            +vn 0.099648 -0.634731 -0.766281
            +vn 0.097081 -0.660462 -0.744557
            +vn 0.088027 -0.731995 -0.675599
            +vn 0.094396 -0.684273 -0.723091
            +vn 0.115543 -0.457726 -0.881554
            +vn 0.128992 -0.152028 -0.979923
            +vn 0.127770 0.223232 -0.966355
            +vn 0.128339 0.242535 -0.961616
            +vn 0.027851 -0.976359 -0.214354
            +vn 0.027752 -0.976361 -0.214358
            +vn 0.127753 -0.206233 -0.970127
            +vn 0.094951 -0.336016 -0.937058
            +vn 0.121115 -0.260818 -0.957761
            +vn 0.120123 0.402639 -0.907443
            +vn 0.091018 0.718613 -0.689428
            +vn 0.018255 0.594016 -0.804246
            +vn 0.135347 0.014436 -0.990693
            +vn -0.070147 -0.951051 -0.300967
            +vn 0.000000 -0.163943 -0.986470
            +vn -0.000242 -0.149255 -0.988799
            +vn -0.000816 -0.610083 -0.792337
            +vn -0.000873 -0.807449 -0.589937
            +vn -0.000810 -0.817554 -0.575852
            +vn -0.001475 -0.634733 -0.772730
            +vn -0.001172 -0.660469 -0.750853
            +vn -0.001131 -0.731998 -0.681306
            +vn -0.001046 -0.684274 -0.729224
            +vn -0.000803 -0.457710 -0.889101
            +vn -0.000304 -0.152008 -0.988379
            +vn 0.000257 0.223233 -0.974765
            +vn 0.001460 0.242534 -0.970142
            +vn -0.000443 -0.976361 -0.216148
            +vn -0.000535 -0.976361 -0.216145
            +vn -0.000580 -0.327433 -0.944874
            +vn -0.000280 -0.206119 -0.978527
            +vn -0.000506 -0.266814 -0.963748
            +vn 0.000336 0.402430 -0.915451
            +vn 0.000467 0.718579 -0.695445
            +vn 0.042685 0.720730 -0.691900
            +vn -0.117898 -0.252783 -0.960313
            +vn 0.000050 -0.279605 -0.960115
            +vn -0.046442 0.423444 -0.904731
            +vn -0.072335 0.694084 -0.716251
            +vn -0.145364 0.874191 -0.463314
            +vn 0.004005 0.965946 -0.258711
            +vn 0.000271 0.014305 -0.999898
            +vn -0.010651 -0.999764 -0.018921
            +vn -0.130405 -0.079399 -0.988276
            +vn -0.129579 -0.149292 -0.980266
            +vn -0.104497 -0.610076 -0.785422
            +vn -0.078042 -0.807455 -0.584745
            +vn -0.076110 -0.817547 -0.570810
            +vn -0.102552 -0.634741 -0.765890
            +vn -0.099394 -0.660458 -0.744256
            +vn -0.090271 -0.731998 -0.675300
            +vn -0.096440 -0.684275 -0.722819
            +vn -0.117117 -0.457726 -0.881346
            +vn -0.129614 -0.152023 -0.979841
            +vn -0.127265 0.223234 -0.966421
            +vn -0.125468 0.242535 -0.961995
            +vn -0.028715 -0.976359 -0.214239
            +vn -0.028798 -0.976360 -0.214224
            +vn -0.118228 -0.323797 -0.938711
            +vn -0.128031 -0.206057 -0.970128
            +vn -0.126580 -0.266860 -0.955386
            +vn -0.119345 0.402660 -0.907536
            +vn -0.090958 0.718654 -0.689393
            +vn -0.128936 0.722766 -0.678959
            +vn -0.257815 0.549728 -0.794563
            +vn -0.262346 0.156587 -0.952184
            +vn -0.030972 0.967938 -0.249271
            +vn -0.133311 0.014361 -0.990970
            +vn 0.000000 -1.000000 0.000000
            +vn 0.322039 -0.015344 0.946602
            +vn -0.261282 -0.124842 -0.957155
            +vn -0.256477 -0.149198 -0.954966
            +vn -0.206087 -0.610010 -0.765124
            +vn -0.153709 -0.807476 -0.569523
            +vn -0.149975 -0.817569 -0.555957
            +vn -0.201610 -0.634727 -0.745973
            +vn -0.195680 -0.660449 -0.724926
            +vn -0.177613 -0.731986 -0.657761
            +vn -0.189945 -0.684299 -0.704028
            +vn -0.231146 -0.457761 -0.858503
            +vn -0.256409 -0.152030 -0.954537
            +vn -0.252354 0.223236 -0.941532
            +vn -0.250028 0.242535 -0.937370
            +vn -0.056430 -0.976359 -0.208659
            +vn -0.056518 -0.976361 -0.208625
            +vn -0.230978 -0.320788 -0.918556
            +vn -0.243216 -0.252816 -0.936445
            +vn -0.236842 0.402563 -0.884222
            +vn -0.180166 0.718613 -0.671667
            +vn -0.372027 -0.261816 -0.890533
            +vn -0.248223 -0.279619 -0.927469
            +vn -0.183416 0.552054 -0.813385
            +vn -0.294864 0.752949 -0.588323
            +vn -0.064420 0.968573 -0.240242
            +vn -0.124157 0.953774 -0.273680
            +vn -0.200350 -0.020751 -0.979505
            +vn -0.314833 0.049292 -0.947866
            +vn -0.150658 -0.940908 -0.303305
            +vn -0.357732 -0.275099 -0.892383
            +vn -0.378643 -0.149266 -0.913427
            +vn -0.303929 -0.610081 -0.731729
            +vn -0.226532 -0.807428 -0.544742
            +vn -0.221101 -0.817593 -0.531654
            +vn -0.297039 -0.634746 -0.713348
            +vn -0.288410 -0.660446 -0.693275
            +vn -0.261744 -0.731985 -0.629037
            +vn -0.279999 -0.684296 -0.673305
            +vn -0.340964 -0.457757 -0.821098
            +vn -0.378525 -0.152028 -0.913020
            +vn -0.372799 0.223236 -0.900659
            +vn -0.369937 0.242535 -0.896841
            +vn -0.083115 -0.976362 -0.199523
            +vn -0.083199 -0.976362 -0.199485
            +vn -0.371050 -0.249915 -0.894351
            +vn -0.361960 -0.327693 -0.872698
            +vn -0.350012 0.402537 -0.845846
            +vn -0.266091 0.718664 -0.642431
            +vn -0.262815 0.724597 -0.637093
            +vn -0.365629 0.643312 -0.672655
            +vn -0.225438 0.902709 -0.366461
            +vn -0.373084 0.014164 -0.927689
            +vn 0.000000 -1.000000 -0.000000
            +vn -0.498158 -0.079392 -0.863444
            +vn -0.494272 -0.149326 -0.856386
            +vn -0.396628 -0.610105 -0.685900
            +vn -0.295559 -0.807431 -0.510588
            +vn -0.288446 -0.817553 -0.498404
            +vn -0.387434 -0.634741 -0.668580
            +vn -0.376236 -0.660453 -0.649806
            +vn -0.341442 -0.731986 -0.589588
            +vn -0.365299 -0.684281 -0.631123
            +vn -0.444984 -0.457772 -0.769697
            +vn -0.494174 -0.152029 -0.855967
            +vn -0.486892 0.223233 -0.844454
            +vn -0.483485 0.242537 -0.841082
            +vn -0.108382 -0.976361 -0.187007
            +vn -0.108459 -0.976361 -0.186967
            +vn -0.489220 -0.206048 -0.847472
            +vn -0.495231 -0.336038 -0.801140
            +vn -0.486935 -0.260779 -0.833600
            +vn -0.457113 0.402584 -0.793079
            +vn -0.347472 0.718612 -0.602378
            +vn -0.582679 -0.252787 -0.772389
            +vn -0.485248 -0.272626 -0.830789
            +vn -0.509059 0.334835 -0.792934
            +vn -0.123717 0.967959 -0.218516
            +vn -0.428923 -0.020524 -0.903108
            +vn -0.558300 0.048290 -0.828232
            +vn 0.751668 -0.009410 0.659474
            +vn -0.019212 -0.999675 -0.016756
            +vn -0.322105 -0.895645 -0.306705
            +vn -0.600322 -0.163763 -0.782812
            +vn -0.601863 -0.149265 -0.784526
            +vn -0.482803 -0.610055 -0.628278
            +vn -0.359668 -0.807455 -0.467606
            +vn -0.351043 -0.817549 -0.456489
            +vn -0.471391 -0.634724 -0.612304
            +vn -0.457839 -0.660464 -0.595122
            +vn -0.415479 -0.732001 -0.539955
            +vn -0.444558 -0.684262 -0.578060
            +vn -0.541655 -0.457740 -0.705041
            +vn -0.601686 -0.152025 -0.784131
            +vn -0.592969 0.223232 -0.773664
            +vn -0.589207 0.242535 -0.770722
            +vn -0.131876 -0.976358 -0.171271
            +vn -0.131951 -0.976360 -0.171204
            +vn -0.575396 -0.327478 -0.749451
            +vn -0.595659 -0.206053 -0.776358
            +vn -0.586838 -0.266830 -0.764476
            +vn -0.556718 0.402603 -0.726620
            +vn -0.422823 0.718586 -0.552136
            +vn -0.384762 0.721991 -0.575054
            +vn -0.540253 0.626443 -0.561867
            +vn -0.636187 0.403449 -0.657643
            +vn -0.617561 0.099966 -0.780144
            +vn -0.151369 0.968555 -0.197454
            +vn -0.612115 0.014017 -0.790644
            +vn -0.000575 -1.000000 -0.000447
            +vn -0.704873 -0.079417 -0.704874
            +vn -0.699385 -0.149327 -0.698972
            +vn -0.560862 -0.610099 -0.559655
            +vn -0.417738 -0.807495 -0.416470
            +vn -0.407767 -0.817540 -0.406637
            +vn -0.547449 -0.634721 -0.545371
            +vn -0.531749 -0.660472 -0.530113
            +vn -0.482548 -0.732002 -0.480958
            +vn -0.516383 -0.684257 -0.514919
            +vn -0.629250 -0.457708 -0.628131
            +vn -0.699115 -0.152023 -0.698660
            +vn -0.689082 0.223233 -0.689444
            +vn -0.684987 0.242532 -0.687002
            +vn -0.153158 -0.976361 -0.152521
            +vn -0.153224 -0.976362 -0.152449
            +vn -0.668515 -0.327485 -0.667713
            +vn -0.692129 -0.206093 -0.691724
            +vn -0.681835 -0.266815 -0.681110
            +vn -0.646975 0.402728 -0.647483
            +vn -0.491694 0.718656 -0.491701
            +vn -0.516697 0.721220 -0.461373
            +vn -0.769040 -0.258209 -0.584727
            +vn -0.635559 -0.259656 -0.727079
            +vn -0.693589 0.524086 -0.494235
            +vn -0.527626 0.707605 -0.470006
            +vn -0.368568 0.890246 -0.267618
            +vn -0.178389 0.967464 -0.179419
            +vn -0.706832 0.014019 -0.707243
            +vn 0.000000 -1.000000 -0.000000
            +vn -0.789891 -0.125257 -0.600318
            +vn -0.784778 -0.149206 -0.601549
            +vn -0.629252 -0.610064 -0.481524
            +vn -0.468648 -0.807472 -0.358272
            +vn -0.457433 -0.817571 -0.349762
            +vn -0.614071 -0.634736 -0.469071
            +vn -0.596534 -0.660461 -0.456003
            +vn -0.541338 -0.731996 -0.413685
            +vn -0.579312 -0.684268 -0.442917
            +vn -0.706022 -0.457714 -0.540399
            +vn -0.784507 -0.152019 -0.601198
            +vn -0.773356 0.223233 -0.593370
            +vn -0.768962 0.242534 -0.591501
            +vn -0.171794 -0.976359 -0.131190
            +vn -0.171846 -0.976359 -0.131118
            +vn -0.747381 -0.323799 -0.580152
            +vn -0.776500 -0.206187 -0.595428
            +vn -0.765115 -0.266796 -0.586020
            +vn -0.726148 0.402685 -0.557273
            +vn -0.551823 0.718607 -0.423197
            +vn -0.687524 0.601896 -0.406241
            +vn -0.873643 0.033396 -0.485421
            +vn -0.796874 -0.281705 -0.534447
            +vn -0.200512 0.967950 -0.151220
            +vn -0.790281 0.014317 -0.612578
            +vn 0.997546 -0.028099 -0.064129
            +vn -0.277753 -0.952568 -0.124371
            +vn -0.826951 -0.275952 -0.489901
            +vn -0.856575 -0.149266 -0.493962
            +vn -0.686742 -0.610015 -0.395306
            +vn -0.511413 -0.807460 -0.294049
            +vn -0.499159 -0.817583 -0.287051
            +vn -0.670043 -0.634748 -0.384886
            +vn -0.650964 -0.660451 -0.374233
            +vn -0.590711 -0.731981 -0.339505
            +vn -0.632159 -0.684279 -0.363507
            +vn -0.770510 -0.457752 -0.443596
            +vn -0.856268 -0.152034 -0.493650
            +vn -0.844201 0.223235 -0.487330
            +vn -0.839607 0.242535 -0.486043
            +vn -0.187440 -0.976361 -0.107640
            +vn -0.187482 -0.976362 -0.107552
            +vn -0.811034 -0.321901 -0.488470
            +vn -0.834153 -0.252736 -0.490218
            +vn -0.792755 0.402484 -0.457762
            +vn -0.602301 0.718655 -0.347516
            +vn -0.598198 0.722767 -0.346074
            +vn -0.890267 -0.260747 -0.373412
            +vn -0.654481 0.732814 -0.186111
            +vn -0.432288 0.893434 -0.122072
            +vn -0.290024 0.945085 -0.150667
            +vn -0.225935 0.965994 -0.125737
            +vn -0.863148 0.014219 -0.504750
            +vn -0.013129 -0.999893 -0.006386
            +vn -0.920973 -0.107776 -0.374424
            +vn -0.913652 -0.149198 -0.378127
            +vn -0.732371 -0.610028 -0.302487
            +vn -0.545382 -0.807424 -0.224998
            +vn -0.532293 -0.817579 -0.219612
            +vn -0.714456 -0.634752 -0.294351
            +vn -0.694164 -0.660444 -0.286269
            +vn -0.629894 -0.731986 -0.259673
            +vn -0.674104 -0.684274 -0.278123
            +vn -0.821697 -0.457772 -0.339498
            +vn -0.913255 -0.152036 -0.377956
            +vn -0.900475 0.223235 -0.373245
            +vn -0.895753 0.242537 -0.372563
            +vn -0.199855 -0.976362 -0.082315
            +vn -0.199889 -0.976362 -0.082226
            +vn -0.904178 -0.205915 -0.374248
            +vn -0.880733 -0.336069 -0.333716
            +vn -0.893906 -0.260807 -0.364570
            +vn -0.845550 0.402598 -0.350657
            +vn -0.642469 0.718611 -0.266143
            +vn -0.721369 0.659383 -0.211754
            +vn -0.948525 0.146020 -0.281030
            +vn -0.889309 -0.275215 -0.365221
            +vn -0.856930 0.397120 -0.328583
            +vn -0.894211 -0.020626 -0.447170
            +vn -0.947184 0.048857 -0.316946
            +vn -0.388169 -0.919413 -0.063289
            +vn -0.957169 -0.124873 -0.261216
            +vn -0.955096 -0.149239 -0.255968
            +vn -0.765459 -0.610125 -0.204500
            +vn -0.570016 -0.807442 -0.152048
            +vn -0.556377 -0.817561 -0.148452
            +vn -0.746706 -0.634745 -0.198819
            +vn -0.725530 -0.660441 -0.193450
            +vn -0.658339 -0.731992 -0.175435
            +vn -0.704568 -0.684292 -0.187956
            +vn -0.858916 -0.457751 -0.229626
            +vn -0.954694 -0.152041 -0.255819
            +vn -0.935748 0.214795 -0.279714
            +vn -0.936637 0.242535 -0.252760
            +vn -0.208867 -0.976363 -0.055588
            +vn -0.208890 -0.976363 -0.055492
            +vn -0.912732 -0.327463 -0.244312
            +vn -0.945200 -0.205977 -0.253318
            +vn -0.930934 -0.266892 -0.249260
            +vn -0.883984 0.402663 -0.237560
            +vn -0.671607 0.718658 -0.180207
            +vn -0.667479 0.722771 -0.179095
            +vn -0.962863 -0.259574 -0.074272
            +vn -0.240229 0.968577 -0.064411
            +vn -0.965886 0.013966 -0.258591
            +vn -0.084391 -0.996426 0.003781
            +vn -0.988276 -0.079396 -0.130411
            +vn -0.980323 -0.149286 -0.129157
            +vn -0.785603 -0.610124 -0.102841
            +vn -0.584951 -0.807470 -0.076314
            +vn -0.571013 -0.817548 -0.074563
            +vn -0.766281 -0.634731 -0.099648
            +vn -0.744563 -0.660459 -0.097058
            +vn -0.675609 -0.731986 -0.088029
            +vn -0.723079 -0.684288 -0.094377
            +vn -0.881548 -0.457738 -0.115537
            +vn -0.967334 -0.200011 -0.155758
            +vn -0.963967 0.198531 -0.177067
            +vn -0.959423 0.242503 -0.143875
            +vn -0.214335 -0.976363 -0.027852
            +vn -0.214350 -0.976362 -0.027759
            +vn -0.936808 -0.327487 -0.123059
            +vn -0.970174 -0.206009 -0.127761
            +vn -0.955504 -0.266903 -0.125599
            +vn -0.907433 0.402659 -0.120128
            +vn -0.689428 0.718613 -0.091016
            +vn -0.777469 0.628903 -0.004832
            +vn -0.914933 0.403324 -0.015082
            +vn -0.995661 0.092058 -0.013586
            +vn -0.946003 -0.261896 -0.191019
            +vn -0.896589 0.441071 0.039804
            +vn -0.249334 0.967924 -0.030902
            +vn -0.992314 0.014178 -0.122929
            +vn -0.468789 -0.881186 0.061224
            +vn -0.986458 -0.164015 0.000000
            +vn -0.988808 -0.149196 0.000227
            +vn -0.792324 -0.610101 0.000797
            +vn -0.589876 -0.807493 0.000882
            +vn -0.575852 -0.817553 0.000810
            +vn -0.772737 -0.634724 0.001468
            +vn -0.750862 -0.660458 0.001172
            +vn -0.681308 -0.731996 0.001137
            +vn -0.729221 -0.684277 0.001040
            +vn -0.889089 -0.457733 0.000804
            +vn -0.972226 -0.233130 0.020678
            +vn -0.997063 -0.039391 -0.065677
            +vn -0.997063 -0.039391 -0.065677
            +vn -0.997063 -0.039391 -0.065677
            +vn -0.997062 -0.039367 -0.065709
            +vn -0.997062 -0.039367 -0.065709
            +vn -0.997062 -0.039367 -0.065709
            +vn -0.216141 -0.976362 0.000440
            +vn -0.216141 -0.976362 0.000531
            +vn -0.944859 -0.327477 0.000569
            +vn -0.978568 -0.205922 0.000245
            +vn -0.963728 -0.266885 0.000516
            +vn -0.915339 0.402683 -0.000369
            +vn -0.695364 0.718658 -0.000025
            +vn -0.691062 0.722796 -0.000421
            +vn -0.957331 -0.282471 0.061055
            +vn -0.638914 0.767693 0.049353
            +vn -0.462231 0.880276 0.107039
            +vn -0.329885 0.944021 0.000002
            +vn -0.999896 0.014408 -0.000280
            +vn 0.000000 -1.000000 0.000000
            +vn -0.019438 -0.999750 0.011058
            +vn -0.988274 -0.079360 0.130445
            +vn -0.980263 -0.149248 0.129649
            +vn -0.785402 -0.610111 0.104447
            +vn -0.584731 -0.807465 0.078035
            +vn -0.570797 -0.817552 0.076147
            +vn -0.765888 -0.634742 0.102557
            +vn -0.744267 -0.660448 0.099377
            +vn -0.675308 -0.731992 0.090262
            +vn -0.722812 -0.684283 0.096434
            +vn -0.881339 -0.457738 0.117118
            +vn -0.979839 -0.152028 0.129630
            +vn -0.997064 -0.039367 0.065677
            +vn -0.997064 -0.039367 0.065677
            +vn -0.997064 -0.039367 0.065677
            +vn -0.959210 0.216873 0.181332
            +vn -0.214221 -0.976363 0.028722
            +vn -0.214207 -0.976363 0.028807
            +vn -0.936664 -0.327477 0.124173
            +vn -0.970099 -0.206019 0.128315
            +vn -0.955373 -0.266900 0.126594
            +vn -0.907518 0.402685 0.119400
            +vn -0.689435 0.718613 0.090963
            +vn -0.773413 0.601887 0.198909
            +vn -0.961064 0.010787 0.276114
            +vn -0.946695 -0.258741 0.191890
            +vn -0.249311 0.967930 0.030902
            +vn -0.992377 0.014469 0.122387
            +vn -0.239269 -0.967522 0.081560
            +vn -0.962817 -0.078816 0.258401
            +vn -0.954962 -0.149301 0.256430
            +vn -0.765062 -0.610097 0.206063
            +vn -0.569570 -0.807443 0.153704
            +vn -0.555970 -0.817559 0.149982
            +vn -0.745944 -0.634753 0.201634
            +vn -0.724930 -0.660442 0.195687
            +vn -0.657763 -0.731984 0.177616
            +vn -0.704033 -0.684295 0.189944
            +vn -0.858502 -0.457759 0.231153
            +vn -0.954537 -0.152031 0.256408
            +vn -0.941534 0.223236 0.252348
            +vn -0.933229 0.242513 0.265088
            +vn -0.208639 -0.976363 0.056427
            +vn -0.208620 -0.976363 0.056505
            +vn -0.912432 -0.327485 0.245400
            +vn -0.945065 -0.205967 0.253830
            +vn -0.930675 -0.266875 0.250245
            +vn -0.884171 0.402675 0.236842
            +vn -0.671621 0.718659 0.180151
            +vn -0.667693 0.722771 0.178294
            +vn -0.927183 -0.282221 0.246340
            +vn -0.813377 0.552073 0.183392
            +vn -0.588371 0.752925 0.294827
            +vn -0.240250 0.968571 0.064427
            +vn -0.273687 0.953774 0.124140
            +vn -0.966761 0.013850 0.255304
            +vn -0.292205 -0.944509 0.150061
            +vn -0.911502 -0.163138 0.377558
            +vn -0.913451 -0.149256 0.378589
            +vn -0.731750 -0.610048 0.303946
            +vn -0.544711 -0.807439 0.226567
            +vn -0.531702 -0.817567 0.221084
            +vn -0.713347 -0.634749 0.297036
            +vn -0.693280 -0.660443 0.288406
            +vn -0.629041 -0.731982 0.261742
            +vn -0.673312 -0.684290 0.279996
            +vn -0.821095 -0.457762 0.340965
            +vn -0.913013 -0.152056 0.378531
            +vn -0.900667 0.223237 0.372780
            +vn -0.896840 0.242537 0.369937
            +vn -0.199526 -0.976362 0.083107
            +vn -0.199487 -0.976363 0.083188
            +vn -0.872740 -0.327429 0.362099
            +vn -0.903993 -0.205912 0.374696
            +vn -0.890160 -0.266900 0.369297
            +vn -0.845831 0.402611 0.349962
            +vn -0.642491 0.718613 0.266086
            +vn -0.659834 0.659379 0.360331
            +vn -0.866016 0.136849 0.480925
            +vn -0.839424 -0.255344 0.479757
            +vn -0.366495 0.902685 0.225482
            +vn -0.923749 0.014040 0.382741
            +vn 0.752479 -0.024059 -0.658176
            +vn -0.863467 -0.079376 0.498121
            +vn -0.856348 -0.149272 0.494355
            +vn -0.685923 -0.610057 0.396661
            +vn -0.510554 -0.807450 0.295565
            +vn -0.498375 -0.817572 0.288440
            +vn -0.671370 -0.637900 0.377287
            +vn -0.649815 -0.660454 0.376220
            +vn -0.589600 -0.731981 0.341432
            +vn -0.631121 -0.684283 0.365298
            +vn -0.769725 -0.457739 0.444971
            +vn -0.855959 -0.152047 0.494182
            +vn -0.844454 0.223234 0.486893
            +vn -0.841023 0.242536 0.483587
            +vn -0.186985 -0.976364 0.108393
            +vn -0.186938 -0.976365 0.108471
            +vn -0.818179 -0.327389 0.472651
            +vn -0.847473 -0.205952 0.489258
            +vn -0.834519 -0.266876 0.482033
            +vn -0.793106 0.402483 0.457155
            +vn -0.602320 0.718662 0.347470
            +vn -0.598616 0.722770 0.345345
            +vn -0.831537 -0.282233 0.478426
            +vn -0.806555 0.366164 0.464104
            +vn -0.218528 0.967949 0.123777
            +vn -0.863421 0.013914 0.504293
            +vn -0.014597 -0.999786 0.014659
            +vn -0.333138 -0.885630 0.323541
            +vn -0.782831 -0.163802 0.600287
            +vn -0.784508 -0.149275 0.601884
            +vn -0.628263 -0.610070 0.482805
            +vn -0.467608 -0.807458 0.359659
            +vn -0.456461 -0.817566 0.351039
            +vn -0.579929 -0.681909 0.445739
            +vn -0.627475 -0.616846 0.475160
            +vn -0.594934 -0.663166 0.454163
            +vn -0.539973 -0.731984 0.415486
            +vn -0.578042 -0.684266 0.444576
            +vn -0.705034 -0.457730 0.541674
            +vn -0.784125 -0.152029 0.601694
            +vn -0.773664 0.223233 0.592968
            +vn -0.770722 0.242538 0.589205
            +vn -0.171252 -0.976362 0.131873
            +vn -0.171196 -0.976362 0.131943
            +vn -0.749443 -0.327464 0.575416
            +vn -0.776339 -0.206053 0.595685
            +vn -0.764448 -0.266886 0.586848
            +vn -0.726618 0.402589 0.556731
            +vn -0.551849 0.718613 0.423152
            +vn -0.553269 0.628894 0.546247
            +vn -0.657654 0.403469 0.636163
            +vn -0.718488 0.096205 0.688854
            +vn -0.686880 -0.255361 0.680431
            +vn -0.197380 0.968570 0.151371
            +vn -0.786414 0.014364 0.617533
            +vn -0.704874 -0.079385 0.704877
            +vn -0.699026 -0.149283 0.699341
            +vn -0.559699 -0.610075 0.560843
            +vn -0.416483 -0.807493 0.417729
            +vn -0.406638 -0.817542 0.407763
            +vn -0.516635 -0.681891 0.517796
            +vn -0.555458 -0.617102 0.557362
            +vn -0.527037 -0.665329 0.528744
            +vn -0.480944 -0.731995 0.482573
            +vn -0.514918 -0.684248 0.516394
            +vn -0.628130 -0.457709 0.629250
            +vn -0.698674 -0.152023 0.699102
            +vn -0.689433 0.223232 0.689093
            +vn -0.687025 0.242536 0.684962
            +vn -0.152520 -0.976363 0.153142
            +vn -0.152449 -0.976365 0.153201
            +vn -0.672469 -0.328544 0.663208
            +vn -0.691750 -0.206053 0.692116
            +vn -0.689646 -0.260076 0.675831
            +vn -0.647556 0.402539 0.647019
            +vn -0.492094 0.718587 0.491402
            +vn -0.519403 0.720733 0.459090
            +vn -0.679604 -0.282227 0.677116
            +vn -0.606957 0.423350 0.672590
            +vn -0.426857 0.718676 0.548905
            +vn -0.267603 0.890262 0.368540
            +vn -0.179474 0.967462 0.178340
            +vn -0.701648 0.014234 0.712381
            +vn -0.183054 -0.930077 0.318510
            +vn -0.600279 -0.163802 0.782837
            +vn -0.601505 -0.149262 0.784801
            +vn -0.481515 -0.610063 0.629259
            +vn -0.362742 -0.804101 0.470998
            +vn -0.349748 -0.817575 0.457436
            +vn -0.444485 -0.681879 0.580925
            +vn -0.477750 -0.617099 0.625255
            +vn -0.453333 -0.665321 0.593159
            +vn -0.413689 -0.731984 0.541350
            +vn -0.442903 -0.684279 0.579310
            +vn -0.540383 -0.457749 0.706011
            +vn -0.601226 -0.152012 0.784487
            +vn -0.593371 0.223235 0.773354
            +vn -0.591509 0.242536 0.768956
            +vn -0.131163 -0.976364 0.171785
            +vn -0.131103 -0.976363 0.171833
            +vn -0.572919 -0.332477 0.749149
            +vn -0.595271 -0.205909 0.776694
            +vn -0.570108 -0.380077 0.728366
            +vn -0.607468 -0.060141 0.792064
            +vn -0.557326 0.402406 0.726263
            +vn -0.423151 0.718657 0.551793
            +vn -0.386927 0.722437 0.573038
            +vn -0.359496 0.583800 0.727970
            +vn -0.484364 0.010792 0.874800
            +vn -0.487780 -0.255378 0.834777
            +vn -0.151208 0.967930 0.200619
            +vn -0.619398 0.013948 0.784954
            +vn -0.498205 -0.078745 0.863476
            +vn -0.493971 -0.149206 0.856581
            +vn -0.395266 -0.610067 0.686719
            +vn -0.312530 -0.779371 0.543052
            +vn -0.258171 -0.851504 0.456387
            +vn -0.294188 -0.809875 0.507500
            +vn -0.364983 -0.682489 0.633242
            +vn -0.383207 -0.617284 0.687105
            +vn -0.372054 -0.665307 0.647258
            +vn -0.339504 -0.731985 0.590707
            +vn -0.363523 -0.684279 0.632150
            +vn -0.443585 -0.457774 0.770503
            +vn -0.493630 -0.152043 0.856278
            +vn -0.487330 0.223235 0.844201
            +vn -0.486097 0.242537 0.839574
            +vn -0.107631 -0.976361 0.187442
            +vn -0.107570 -0.976360 0.187483
            +vn -0.477833 -0.290824 0.828913
            +vn -0.461157 0.492680 0.737971
            +vn -0.461157 0.492680 0.737971
            +vn -0.462505 -0.378181 0.801915
            +vn -0.498818 -0.059741 0.864645
            +vn -0.457756 0.402703 0.792647
            +vn -0.347513 0.718612 0.602355
            +vn -0.481437 -0.282246 0.829792
            +vn -0.445466 0.552158 0.704757
            +vn -0.225165 0.751816 0.619737
            +vn -0.171502 0.895095 0.411574
            +vn -0.150725 0.945093 0.289967
            +vn -0.125681 0.966002 0.225928
            +vn -0.517916 0.014403 0.855310
            +vn -0.111177 -0.963997 0.241556
            +vn -0.381444 -0.079441 0.920972
            +vn -0.378160 -0.149293 0.913623
            +vn -0.302487 -0.610059 0.732346
            +vn -0.239177 -0.779354 0.579139
            +vn -0.200597 -0.850745 0.485791
            +vn -0.225520 -0.806718 0.546211
            +vn -0.286638 -0.636975 0.715612
            +vn -0.283216 -0.662223 0.693722
            +vn -0.259699 -0.731982 0.629888
            +vn -0.278120 -0.684278 0.674101
            +vn -0.339499 -0.457771 0.821697
            +vn -0.377941 -0.152044 0.913260
            +vn -0.373245 0.223235 0.900475
            +vn -0.372554 0.242536 0.895756
            +vn -0.082325 -0.976358 0.199869
            +vn -0.082236 -0.976360 0.199896
            +vn -0.366438 -0.301587 0.880210
            +vn -0.374468 -0.206199 0.904022
            +vn -0.203635 0.642892 0.738392
            +vn -0.275724 0.691414 0.667775
            +vn -0.381914 -0.059807 0.922261
            +vn -0.350633 0.402667 0.845527
            +vn -0.266565 0.718598 0.642309
            +vn -0.307082 0.721677 0.620389
            +vn -0.256861 0.138275 0.956505
            +vn -0.194819 -0.260258 0.945680
            +vn -0.383212 0.014267 0.923550
            +vn -0.255647 -0.163360 0.952868
            +vn -0.255958 -0.149274 0.955093
            +vn -0.204512 -0.610088 0.765485
            +vn -0.162124 -0.778822 0.605930
            +vn -0.133379 -0.850688 0.508468
            +vn -0.152489 -0.806699 0.570949
            +vn -0.198831 -0.634745 0.746703
            +vn -0.193453 -0.660446 0.725525
            +vn -0.175448 -0.731993 0.658335
            +vn -0.187974 -0.684279 0.704576
            +vn -0.229632 -0.457756 0.858911
            +vn -0.255833 -0.152036 0.954691
            +vn -0.252838 0.223235 0.941403
            +vn -0.252711 0.242533 0.936651
            +vn -0.055594 -0.976362 0.208872
            +vn -0.055486 -0.976365 0.208885
            +vn -0.262398 -0.321975 0.909659
            +vn -0.253397 -0.239945 0.937132
            +vn -0.237515 0.402547 0.884049
            +vn -0.180639 0.718587 0.671567
            +vn -0.185858 0.718498 0.670236
            +vn -0.248019 -0.282637 0.926608
            +vn -0.242116 0.366093 0.898530
            +vn -0.064482 0.968569 0.240241
            +vn -0.248145 0.014090 0.968620
            +vn -0.130467 -0.079315 0.988275
            +vn -0.129175 -0.149252 0.980325
            +vn -0.102910 -0.610062 0.785642
            +vn -0.077000 -0.805857 0.587083
            +vn -0.074629 -0.816683 0.572240
            +vn -0.099646 -0.634744 0.766271
            +vn -0.097107 -0.660464 0.744552
            +vn -0.088048 -0.731986 0.675607
            +vn -0.094380 -0.684272 0.723093
            +vn -0.115537 -0.457743 0.881545
            +vn -0.129023 -0.152029 0.979919
            +vn -0.127792 0.223235 0.966351
            +vn -0.128400 0.242537 0.961608
            +vn -0.027843 -0.976365 0.214325
            +vn -0.027751 -0.976366 0.214336
            +vn -0.127797 -0.205814 0.970210
            +vn -0.094928 -0.335991 0.937069
            +vn -0.121126 -0.260865 0.957746
            +vn -0.120134 0.402660 0.907432
            +vn -0.091428 0.718588 0.689400
            +vn -0.093903 0.722899 0.684543
            +vn 0.032931 0.590460 0.806395
            +vn -0.030880 0.967926 0.249329
            +vn -0.124321 0.014355 0.992138
            +vn -0.968136 0.242169 0.063771
            +vn -0.968136 0.242169 0.063771
            +vn -0.968136 0.242169 0.063771
            +vn -0.968144 0.242039 0.064139
            +vn -0.968144 0.242039 0.064139
            +vn -0.968144 0.242039 0.064139
            +vn -0.968165 0.242052 -0.063773
            +vn -0.968165 0.242052 -0.063773
            +vn -0.968165 0.242052 -0.063773
            +vn -0.968140 0.242314 -0.063158
            +vn -0.968140 0.242314 -0.063158
            +vn -0.968140 0.242314 -0.063158
            +vn -0.968121 0.242398 -0.063125
            +vn -0.968121 0.242398 -0.063125
            +vn -0.968121 0.242398 -0.063125
            +vn -0.968213 0.241576 -0.064844
            +vn -0.968213 0.241576 -0.064844
            +vn -0.968213 0.241576 -0.064844
            +vn -0.968110 0.242586 -0.062574
            +vn -0.968110 0.242586 -0.062574
            +vn -0.968110 0.242586 -0.062574
            +vn -0.968129 0.242388 -0.063044
            +vn -0.968129 0.242388 -0.063044
            +vn -0.968129 0.242388 -0.063044
            +vn -0.968168 0.241835 -0.064548
            +vn -0.968168 0.241835 -0.064548
            +vn -0.968168 0.241835 -0.064548
            +vn -0.968169 0.241579 -0.065481
            +vn -0.968170 0.241579 -0.065481
            +vn -0.968169 0.241579 -0.065481
            +vn -0.968125 0.242868 -0.061233
            +vn -0.968125 0.242868 -0.061233
            +vn -0.968125 0.242868 -0.061233
            +vn -0.968190 0.241206 -0.066541
            +vn -0.968190 0.241206 -0.066541
            +vn -0.968190 0.241206 -0.066541
            +vn -0.968158 0.241501 -0.065939
            +vn -0.968158 0.241501 -0.065939
            +vn -0.968158 0.241501 -0.065939
            +vn -0.968150 0.244224 -0.055130
            +vn -0.968150 0.244224 -0.055130
            +vn -0.968151 0.244224 -0.055131
            +vn -0.968115 0.241979 -0.064809
            +vn -0.968115 0.241979 -0.064809
            +vn -0.968115 0.241979 -0.064809
            +vn -0.968170 0.242079 -0.063601
            +vn -0.968170 0.242079 -0.063601
            +vn -0.968170 0.242079 -0.063601
            +vn -0.967386 0.241849 -0.075318
            +vn -0.967386 0.241850 -0.075318
            +vn -0.967386 0.241850 -0.075318
            +vn -0.968016 0.242005 0.066166
            +vn -0.968016 0.242005 0.066167
            +vn -0.968016 0.242005 0.066166
            +vn -0.968174 0.242259 0.062852
            +vn -0.968174 0.242259 0.062852
            +vn -0.968174 0.242259 0.062852
            +vn -0.968202 0.242358 0.062023
            +vn -0.968202 0.242358 0.062023
            +vn -0.968202 0.242358 0.062023
            +vn -0.968155 0.241459 0.066127
            +vn -0.968155 0.241459 0.066127
            +vn -0.968155 0.241459 0.066127
            +vn -0.968172 0.242106 0.063458
            +vn -0.968172 0.242106 0.063458
            +vn -0.968172 0.242106 0.063458
            +vn -0.961529 0.242535 0.128989
            +vn -0.968163 0.242045 -0.063827
            +vn -0.968172 0.242042 0.063705
            +vn 0.968153 -0.242038 0.064016
            +vn 0.968153 -0.242038 0.064016
            +vn 0.968153 -0.242038 0.064016
            +vn 0.172684 -0.935364 0.308665
            +vn -0.813647 -0.577261 0.068903
            +vn -0.362392 -0.931317 -0.036334
            +vn 0.328601 -0.860566 0.389163
            +vn 0.488873 -0.816293 0.307684
            +vn 0.987906 -0.150215 0.038442
            +vn 0.887797 -0.457485 -0.050233
            +vn -0.204167 -0.774518 -0.598696
            +vn -0.006015 -0.421526 -0.906796
            +vn 0.256741 -0.262033 -0.930281
            +vn 0.576091 0.177455 -0.797890
            +vn -0.900701 -0.425959 0.085423
            +vn -0.901810 -0.429511 -0.047539
            +vn -0.549424 -0.268557 0.791208
            +vn -0.255497 -0.138858 0.956786
            +vn 0.234460 0.120989 0.964567
            +vn 0.537849 0.290293 0.791485
            +vn 0.880459 0.472072 0.044046
            +vn 0.874504 0.476185 -0.092145
            +vn 0.534486 0.313636 -0.784829
            +vn 0.255566 0.151728 -0.954811
            +vn -0.009118 0.000207 -0.999958
            +vn -0.282761 -0.131090 -0.950190
            +vn -0.551669 -0.259796 -0.792570
            +vn -0.889865 -0.446491 -0.093735
            +vn -0.016796 -0.000733 0.999859
            +vn 0.249622 0.133219 0.959136
            +vn 0.656230 0.274398 0.702899
            +vn 0.826519 0.552186 0.109349
            +vn 0.824651 0.560726 -0.074407
            +vn 0.543526 0.270754 -0.794526
            +vn -0.037545 -0.005368 -0.999280
            +vn -0.353994 -0.151529 -0.922891
            +vn -0.617832 -0.238107 -0.749392
            +vn -0.890411 -0.444517 0.097841
            +vn -0.593268 -0.230461 0.771311
            +vn -0.309395 -0.118233 0.943555
            +vn 0.828779 0.559162 0.021529
            +vn 0.824273 0.564073 -0.048953
            +vn 0.275846 0.141534 -0.950724
            +vn -0.952900 -0.296741 0.062656
            +vn -0.953790 -0.298960 -0.030118
            +vn 0.390441 0.028495 0.920187
            +vn 0.931072 0.363196 0.034551
            +vn 0.928338 0.365441 -0.068134
            +vn -0.992192 -0.107348 0.063492
            +vn -0.993816 -0.107265 -0.028714
            +vn -0.550027 -0.051350 0.833567
            +vn 0.038337 0.008125 0.999232
            +vn 0.651425 0.034014 0.757950
            +vn 0.994151 0.102734 0.033299
            +vn 0.992435 0.102425 -0.067687
            +vn 0.728220 0.084586 -0.680103
            +vn -0.026267 0.015091 -0.999541
            +vn -0.351350 -0.016516 -0.936098
            +vn -0.708004 -0.067228 -0.703001
            +vn -0.997670 0.021407 0.064778
            +vn -0.999326 0.021377 -0.029845
            +vn -0.656997 0.035744 0.753045
            +vn -0.326940 0.022712 0.944772
            +vn 0.999776 -0.019909 0.007181
            +vn 0.997658 -0.017322 -0.066162
            +vn 0.648920 -0.024611 -0.760458
            +vn 0.337066 -0.006693 -0.941457
            +vn -0.312785 0.039491 -0.949003
            +vn -0.615349 0.023511 -0.787904
            +vn -0.986912 0.109974 0.117940
            +vn -0.990391 0.109771 -0.084122
            +vn -0.002132 0.022838 0.999737
            +vn 0.371207 -0.044776 0.927470
            +vn 0.648312 -0.040766 0.760283
            +vn 0.994689 -0.087932 0.053489
            +vn 0.992617 -0.104354 -0.061822
            +vn -0.057698 0.025607 -0.998006
            +vn -0.588967 0.148059 -0.794479
            +vn -0.965673 0.252164 0.062366
            +vn -0.967217 0.252156 -0.030149
            +vn -0.634376 0.146037 0.759105
            +vn -0.324019 0.079731 0.942685
            +vn 0.973956 -0.224296 0.033177
            +vn 0.974670 -0.220557 -0.037068
            +vn 0.610470 -0.248540 -0.752033
            +vn 0.301138 -0.044994 -0.952519
            +vn -0.310373 0.179921 -0.933433
            +vn -0.881738 0.467889 0.060144
            +vn -0.883164 0.468063 -0.030624
            +vn -0.601946 0.335523 0.724627
            +vn -0.240603 0.160433 0.957273
            +vn 0.005703 0.033684 0.999416
            +vn 0.264508 -0.177956 0.947822
            +vn 0.886371 -0.460243 0.050229
            +vn 0.888818 -0.453400 -0.066560
            +vn -0.017162 0.030735 -0.999380
            +vn -0.625839 0.335869 -0.703930
            +vn -0.741963 0.667870 0.058652
            +vn -0.743468 0.667928 -0.033568
            +vn -0.408868 0.411270 0.814668
            +vn 0.569009 -0.406160 0.715026
            +vn 0.743869 -0.665734 0.058796
            +vn 0.738464 -0.671423 -0.062142
            +vn 0.446877 -0.462926 -0.765507
            +vn 0.246764 -0.241124 -0.938598
            +vn -0.222505 0.279325 -0.934061
            +vn -0.436380 0.394868 -0.808487
            +vn -0.613988 0.780733 0.116078
            +vn -0.599854 0.798908 -0.043819
            +vn -0.165723 0.250967 0.953704
            +vn 0.241899 -0.303269 0.921690
            +vn 0.446839 -0.546508 0.708282
            +vn 0.619806 -0.783740 0.039896
            +vn 0.617673 -0.783260 -0.070593
            +vn -0.019168 0.017825 -0.999657
            +vn -0.420706 0.561941 -0.712200
            +vn -0.560209 0.826628 0.053410
            +vn -0.556010 0.827311 -0.080052
            +vn -0.330930 0.518982 0.788126
            +vn 0.003442 0.042634 0.999085
            +vn 0.565752 -0.821816 0.067397
            +vn 0.564315 -0.823537 -0.057754
            +vn 0.383507 -0.549408 -0.742343
            +vn 0.178624 -0.257905 -0.949515
            +vn -0.208206 0.302465 -0.930142
            +vn -0.343677 0.596574 0.725249
            +vn -0.101817 0.239338 0.965583
            +vn 0.238057 -0.367132 0.899190
            +vn 0.403221 -0.551857 0.729977
            +vn -0.012411 0.013962 -0.999825
            +vn -0.316357 0.532555 -0.785050
            +vn -0.516163 0.854340 0.060660
            +vn -0.493869 0.868631 -0.039682
            +vn 0.023706 0.030735 0.999246
            +vn 0.535722 -0.843411 0.040730
            +vn 0.531966 -0.844057 -0.067679
            +vn 0.338893 -0.592308 -0.730974
            +vn 0.157376 -0.293268 -0.942988
            +vn -0.111095 0.290099 -0.950527
            +vn -0.338688 0.939526 0.050800
            +vn -0.340171 0.939459 -0.041235
            +vn -0.173159 0.549041 0.817661
            +vn 0.078948 -0.330092 0.940642
            +vn 0.349670 -0.934700 0.063780
            +vn 0.360533 -0.929823 -0.073787
            +vn 0.035292 -0.337990 -0.940488
            +vn -0.240726 0.658112 -0.713400
            +vn -0.145440 0.988188 0.048293
            +vn -0.146953 0.988126 -0.044858
            +vn -0.047076 0.657096 0.752335
            +vn -0.011031 0.352968 0.935570
            +vn 0.129253 -0.647003 0.751453
            +vn 0.151479 -0.986110 0.068126
            +vn 0.145296 -0.988061 -0.051225
            +vn 0.023856 -0.639706 -0.768249
            +vn -0.008099 0.021920 -0.999727
            +vn -0.035568 0.349951 -0.936092
            +vn -0.071343 0.654266 -0.752892
            +vn -0.009514 0.994387 0.105375
            +vn -0.013220 0.994129 -0.107393
            +vn 0.032549 0.024184 0.999178
            +vn -0.021215 -0.307742 0.951233
            +vn 0.022175 -0.999205 0.033118
            +vn 0.022929 -0.997659 -0.064422
            +vn 0.045602 0.344110 -0.937821
            +vn 0.098433 0.670224 -0.735602
            +vn 0.184945 0.981885 0.041186
            +vn 0.183392 0.981760 -0.050140
            +vn 0.122355 0.670845 0.731434
            +vn 0.072760 0.345770 0.935494
            +vn -0.059675 -0.671971 0.738169
            +vn -0.170672 -0.982902 0.069098
            +vn -0.178696 -0.982767 -0.047287
            +vn -0.112935 -0.631072 -0.767460
            +vn -0.067243 -0.333525 -0.940340
            +vn -0.002222 0.021945 -0.999757
            +vn 0.377267 0.925274 0.039220
            +vn 0.375750 0.925130 -0.054274
            +vn 0.278738 0.643045 0.713301
            +vn 0.121157 0.247810 0.961203
            +vn 0.008270 -0.044948 0.998955
            +vn -0.097729 -0.268660 0.958265
            +vn -0.262120 -0.693422 0.671162
            +vn -0.371596 -0.926613 0.057482
            +vn -0.373480 -0.926674 -0.042295
            +vn -0.229297 -0.575790 -0.784786
            +vn -0.059554 -0.055772 -0.996666
            +vn 0.154795 0.277993 -0.948029
            +vn 0.198471 0.504270 -0.840429
            +vn 0.540746 0.840428 0.035707
            +vn 0.539272 0.840233 -0.056519
            +vn 0.394162 0.585221 0.708627
            +vn 0.221705 0.305586 0.925994
            +vn -0.340724 -0.579987 0.739947
            +vn -0.526833 -0.847783 0.060917
            +vn -0.528739 -0.847811 -0.040632
            +vn -0.348692 -0.597634 -0.721975
            +vn -0.015190 -0.011428 -0.999819
            +vn 0.369736 0.581948 -0.724314
            +vn 0.712221 0.701177 0.033040
            +vn 0.710714 0.700974 -0.059343
            +vn 0.513196 0.485001 0.708099
            +vn 0.267939 0.218160 0.938411
            +vn 0.055998 0.011461 0.998365
            +vn -0.479110 -0.463300 0.745524
            +vn -0.709348 -0.701946 0.064014
            +vn -0.713848 -0.697091 -0.066974
            +vn -0.524248 -0.456174 -0.719075
            +vn -0.275792 -0.204831 -0.939139
            +vn 0.234413 0.214396 -0.948201
            +vn 0.490027 0.483233 -0.725506
            +vn 0.815461 0.577902 0.032457
            +vn 0.813827 0.577789 -0.062014
            +vn 0.490937 0.329949 0.806297
            +vn 0.037941 -0.009823 0.999232
            +vn -0.292352 -0.207851 0.933450
            +vn -0.599479 -0.438797 0.669390
            +vn -0.826865 -0.558674 0.064637
            +vn -0.826573 -0.561805 -0.033933
            +vn -0.438822 -0.263636 -0.859029
            +vn 0.319801 0.204179 -0.925223
            +vn 0.469061 0.329904 -0.819234
            +vn 0.848423 0.528318 0.032533
            +vn 0.843496 0.526331 -0.107193
            +vn 0.600172 0.362001 0.713267
            +vn 0.290772 0.158417 0.943587
            +vn -0.906131 -0.419379 0.055213
            +vn -0.634860 -0.316675 -0.704748
            +vn -0.008197 -0.005432 -0.999952
            +vn 0.618389 0.297696 -0.727305
            +vn 0.902842 0.428917 0.030113
            +vn 0.923301 0.380791 -0.050130
            +vn 0.647998 0.287364 0.705351
            +vn 0.215435 0.093383 0.972043
            +vn -0.256583 -0.120466 0.958985
            +vn -0.609283 -0.326868 0.722448
            +vn -0.882221 -0.469564 -0.034577
            +vn -0.294099 -0.138024 -0.945756
            +vn -0.000203 -0.003083 -0.999995
            +vn 0.299710 0.133023 -0.944711
            +vn 0.956407 0.289497 0.038434
            +vn 0.409117 0.111918 0.905592
            +vn -0.026264 -0.021094 0.999432
            +vn -0.643626 -0.207515 0.736670
            +vn -0.954998 -0.294040 -0.038991
            +vn -0.426887 -0.135721 -0.894062
            +vn 0.064758 0.014033 -0.997802
            +vn 0.650366 0.194295 -0.734352
            +vn 0.954834 0.288422 -0.071445
            +vn -0.952801 -0.294894 0.072170
            +vn -0.667897 -0.209272 -0.714226
            +vn 0.956953 0.287797 0.037592
            +vn 0.672543 0.193948 0.714191
            +vn 0.073636 0.007995 0.997253
            +vn -0.370718 -0.126821 0.920046
            +vn -0.087285 -0.032503 -0.995653
            +vn 0.391593 0.114016 -0.913047
            +vn 0.357194 0.095210 0.929165
            +vn -0.263981 -0.094843 0.959854
            +vn -0.687993 -0.221851 0.690976
            +vn -0.954489 -0.295800 -0.038110
            +vn -0.350653 -0.113049 -0.929657
            +vn 0.692571 0.206033 -0.691300
            +vn 0.977050 0.207343 -0.048799
            +vn 0.697421 0.120954 0.706380
            +vn 0.030390 -0.004926 0.999526
            +vn -0.978330 -0.201788 0.046398
            +vn -0.679563 -0.136063 -0.720889
            +vn -0.004437 -0.006861 -0.999967
            +vn 0.271180 0.077042 -0.959440
            +vn 0.983952 0.175972 0.029541
            +vn 0.374527 0.058125 0.925393
            +vn -0.317982 -0.067474 0.945693
            +vn -0.654878 -0.126626 0.745051
            +vn -0.986858 -0.160386 -0.019693
            +vn -0.351024 -0.068477 -0.933859
            +vn 0.342191 0.056282 -0.937943
            +vn 0.672264 0.116900 -0.731024
            +vn 0.987462 0.095586 0.125627
            +vn 0.466122 0.029818 0.884218
            +vn 0.021151 -0.007772 0.999746
            +vn -0.330923 -0.036933 0.942935
            +vn -0.713835 -0.075162 0.696268
            +vn -0.694145 -0.075448 -0.715870
            +vn -0.051956 -0.014265 -0.998547
            +vn 0.338013 0.019686 -0.940935
            +vn 0.693126 0.059867 -0.718326
            +vn 0.996254 0.075894 0.041444
            +vn 0.993330 0.077732 -0.085172
            +vn 0.674021 -0.026658 0.738231
            +vn 0.043943 -0.021124 0.998811
            +vn -0.315871 -0.029141 0.948355
            +vn -0.636685 0.004516 0.771111
            +vn -0.994700 -0.086048 0.056289
            +vn -0.996058 -0.086138 -0.021195
            +vn -0.364618 -0.039214 -0.930331
            +vn 0.322388 -0.026124 -0.946247
            +vn 0.647174 -0.031784 -0.761680
            +vn 0.996808 -0.074341 0.029103
            +vn 0.995141 -0.074503 -0.064375
            +vn 0.356020 -0.023995 0.934170
            +vn -0.995856 0.060899 0.067542
            +vn -0.997598 0.060807 -0.033193
            +vn -0.555529 0.002494 -0.831493
            +vn -0.063785 -0.015219 -0.997848
            +vn 0.964193 -0.263485 0.030109
            +vn 0.962535 -0.263662 -0.063317
            +vn 0.532928 -0.149154 0.832911
            +vn 0.025738 -0.011116 0.999607
            +vn -0.622131 0.186236 0.760440
            +vn -0.962847 0.261548 0.067225
            +vn -0.964612 0.261503 -0.033752
            +vn -0.606295 0.175650 -0.775599
            +vn 0.293220 -0.132406 -0.946832
            +vn 0.503101 -0.151107 -0.850915
            +vn 0.919569 -0.391647 0.031692
            +vn 0.917876 -0.391792 -0.063261
            +vn 0.647057 -0.274304 0.711389
            +vn 0.324904 -0.129563 0.936830
            +vn -0.311380 0.119112 0.942791
            +vn -0.601319 0.246488 0.760039
            +vn -0.920344 0.385616 0.065329
            +vn -0.922053 0.385583 -0.033830
            +vn -0.644113 0.259019 -0.719741
            +vn -0.324563 0.112987 -0.939091
            +vn -0.010696 -0.012724 -0.999862
            +vn 0.620924 -0.275925 -0.733702
            +vn 0.834629 -0.549858 0.032426
            +vn 0.821391 -0.567977 -0.052143
            +vn 0.612378 -0.392123 0.686464
            +vn 0.325427 -0.192767 0.925710
            +vn 0.005575 0.002566 0.999981
            +vn -0.251581 0.158994 0.954687
            +vn -0.571744 0.342871 0.745351
            +vn -0.828853 0.557314 0.049022
            +vn -0.836004 0.547490 -0.036768
            +vn -0.582153 0.366772 -0.725655
            +vn -0.302214 0.178465 -0.936385
            +vn -0.030326 0.001240 -0.999539
            +vn 0.292843 -0.194866 -0.936093
            +vn 0.588175 -0.394120 -0.706200
            +vn 0.285636 -0.229939 0.930344
            +vn -0.279353 0.230136 0.932201
            +vn -0.547866 0.448145 0.706406
            +vn 0.253165 -0.231905 -0.939217
            +vn 0.773571 -0.633502 0.016239
            +vn 0.541000 -0.439626 0.716971
            +vn 0.028480 -0.020292 0.999388
            +vn -0.776783 0.629451 -0.019999
            +vn -0.526702 0.408072 -0.745696
            +vn -0.048350 0.011969 -0.998759
            +vn 0.555749 -0.472356 -0.684121
            +vn 0.772224 -0.633938 -0.042331
            +vn 0.575456 -0.468572 0.670292
            +vn 0.282748 -0.228074 0.931684
            +vn -0.220850 0.182682 0.958046
            +vn -0.544797 0.444954 0.710783
            +vn -0.776163 0.629438 0.037136
            +vn -0.584421 0.456255 -0.671032
            +vn -0.294282 0.213920 -0.931470
            +vn 0.250069 -0.229893 -0.940539
            +vn 0.777743 -0.628321 0.018138
            +vn 0.282515 -0.227915 0.931794
            +vn 0.011529 -0.006524 0.999912
            +vn -0.546641 0.446396 0.708459
            +vn -0.781253 0.623046 -0.038183
            +vn -0.296116 0.212212 -0.931279
            +vn -0.023785 -0.008184 -0.999684
            +vn 0.514210 -0.440437 -0.735937
            +vn 0.777020 -0.627429 -0.050730
            +vn 0.558419 -0.449312 0.697343
            +vn 0.009483 -0.007340 0.999928
            +vn -0.261618 0.215706 0.940759
            +vn -0.524530 0.391445 -0.756068
            +vn -0.055627 0.014156 -0.998351
            +vn 0.230198 -0.214030 -0.949316
            +vn 0.282589 -0.226066 0.932222
            +vn -0.265460 0.211729 0.940586
            +vn -0.546141 0.437253 0.714521
            +vn -0.780622 0.623209 0.047322
            +vn 0.264158 -0.238960 -0.934408
            +vn 0.533957 -0.450868 -0.715268
            +vn 0.560179 -0.444622 0.698935
            +vn -0.010406 0.006366 0.999926
            +vn -0.515710 0.403727 0.755677
            +vn -0.317329 0.220892 -0.922230
            +vn -0.290611 0.226963 0.929534
            +vn -0.786749 0.614202 0.061491
            +vn -0.788179 0.613556 -0.048190
            +vn 0.251420 -0.227907 -0.940663
            +vn 0.519152 -0.433674 -0.736484
            +vn 0.781606 -0.622676 0.036966
            +vn 0.780142 -0.622455 -0.062680
            +vn 0.306512 -0.243825 0.920108
            +vn -0.557119 0.432081 0.709171
            +vn -0.560022 0.416346 -0.716262
            +vn -0.026601 -0.011532 -0.999580
            +vn 0.519957 -0.417958 0.744954
            +vn 0.033821 -0.028664 0.999017
            +vn -0.822172 0.569098 -0.012688
            +vn -0.193140 0.070918 -0.978605
            +vn 0.199441 -0.157455 -0.967177
            +vn 0.517749 -0.436932 -0.735545
            +vn 0.830146 -0.551004 -0.085164
            +vn 0.387438 -0.217774 0.895805
            +vn -0.393509 0.209097 0.895226
            +vn -0.821661 0.565783 0.069006
            +vn 0.818994 -0.570469 0.061762
            +vn -0.008305 -0.004358 0.999956
            +vn -0.605194 0.323084 -0.727570
            +vn 0.923341 -0.331145 0.194385
            +vn 0.945267 -0.295004 -0.139435
            +vn -0.230087 -0.036329 0.972492
            +vn -0.478649 0.116015 0.870308
            +vn -0.925711 0.344638 0.155831
            +vn -0.936109 0.341424 -0.084439
            +vn 0.376518 -0.139184 -0.915894
            +vn 0.056314 -0.044917 -0.997402
            +vn 0.990848 -0.124641 -0.051818
            +vn 0.065137 -0.042717 0.996962
            +vn -0.980942 0.183417 0.064118
            +vn -0.982590 0.183354 -0.029982
            +vn -0.645258 0.101559 -0.757184
            +vn -0.306442 0.038070 -0.951128
            +vn 0.993947 0.030190 -0.105626
            +vn 0.497143 0.119983 0.859333
            +vn -0.615862 -0.117674 0.779016
            +vn -0.997097 -0.041816 0.063629
            +vn -0.995319 -0.042866 -0.086620
            +vn 0.972835 0.229621 0.029429
            +vn 0.933978 0.283874 -0.217027
            +vn -0.947440 -0.296515 0.120153
            +vn -0.955738 -0.292660 -0.030239
            +vn -0.467979 -0.149078 -0.871075
            +vn 0.946197 -0.253080 -0.201647
            +vn -0.298601 -0.441178 0.846286
            +vn -0.595333 -0.800654 0.067316
            +vn 0.405316 -0.691939 -0.597445
            +vn 0.944878 -0.320838 0.065338
            +vn 0.303977 -0.222849 0.926249
            +vn -0.877311 -0.478881 -0.031596
            +vn 0.061641 -0.904906 -0.421123
            +vn -0.662039 0.748258 -0.042587
            +vn -0.974919 0.189193 0.117217
            +vn -0.491508 0.845786 0.207522
            +vn -0.311177 0.941858 0.126775
            +vn -0.035810 0.998405 0.043637
            +vn 0.087382 0.994129 -0.063815
            +vn -0.515257 0.772337 -0.371490
            +vn 0.391469 0.458295 -0.797946
            +vn -0.702129 -0.702051 -0.118909
            +vn -0.080328 -0.676884 -0.731694
            +vn 0.531910 -0.547010 -0.646415
            +vn 0.992762 -0.017076 0.118880
            +vn 0.527834 -0.431312 0.731683
            +vn -0.034238 -0.778866 0.626254
            +vn -0.375051 -0.924187 0.072213
            +vn 0.979480 -0.179749 -0.091157
            +vn -0.124024 -0.987605 -0.096196
            +vn 0.889781 -0.434482 0.139697
            +vn 0.395424 -0.917833 0.034972
            +vn 0.383554 -0.922922 -0.033166
            +vn -0.638821 0.768997 -0.023473
            +vn -0.995024 -0.056577 0.082010
            +vn -0.513845 0.837228 0.187119
            +vn -0.345648 0.930323 0.122582
            +vn -0.277439 0.955626 0.099029
            +vn 0.105396 0.993980 0.029927
            +vn 0.019036 0.999353 -0.030520
            +vn 0.017124 0.949255 -0.314042
            +vn -0.567338 0.653039 -0.501665
            +vn -0.125048 0.563333 -0.816712
            +vn -0.758358 -0.649125 -0.059421
            +vn -0.475120 -0.596021 -0.647318
            +vn -0.198188 -0.363939 -0.910093
            +vn 0.045610 -0.273931 -0.960667
            +vn 0.491869 -0.227079 -0.840536
            +vn 0.998062 -0.018503 0.059416
            +vn 0.745749 -0.157701 0.647293
            +vn 0.384365 -0.154690 0.910129
            +vn 0.138963 -0.240347 0.960689
            +vn -0.235072 -0.488115 0.840527
            +vn -0.750351 -0.657666 0.066706
            +vn 0.657259 -0.410558 -0.632023
            +vn 0.997314 -0.030204 -0.066731
            +vn -0.246010 -0.734930 0.631947
            +vn -0.378427 -0.923093 -0.068504
            +vn -0.259939 -0.963640 0.061878
            +vn 0.193973 -0.789866 -0.581795
            +vn 0.813519 -0.578237 -0.061879
            +vn 0.879171 -0.471557 0.068499
            +vn 0.352715 -0.732919 0.581741
            +vn 0.125412 -0.991168 -0.043099
            +vn 0.127988 -0.988173 0.084454
            +vn 0.529774 -0.843922 -0.084472
            +vn 0.533684 -0.844585 0.043102
            +f 1/1/1 4/4/2 2/2/3
            +f 1/1/1 2/2/3 3/3/4
            +f 8/8/5 9/9/6 10/10/7
            +f 8/8/5 10/10/7 59/59/8
            +f 9/9/6 11/11/9 13/13/10
            +f 9/9/6 13/13/10 10/10/7
            +f 11/11/9 12/12/11 13/13/10
            +f 12/12/11 14/14/12 16/16/13
            +f 12/12/11 16/16/13 13/13/10
            +f 14/14/12 15/15/14 16/16/13
            +f 15/15/14 17/17/15 20/20/16
            +f 15/15/14 20/20/16 16/16/13
            +f 17/17/15 18/18/17 20/20/16
            +f 18/18/17 19/19/18 20/20/16
            +f 19/19/18 22/22/19 20/20/16
            +f 21/21/20 23/23/21 44/44/22
            +f 21/21/20 44/44/22 22/22/19
            +f 23/23/21 45/45/23 44/44/22
            +f 2349/2495/24 2350/2496/25 2351/2497/26
            +f 24/24/27 26/26/28 25/25/29
            +f 2352/2498/30 2353/2499/31 2354/2500/32
            +f 2355/2501/33 2356/2502/34 2357/2503/35
            +f 2358/2504/36 2359/2505/37 2360/2506/38
            +f 2342/2488/39 29/29/40 28/28/41
            +f 2361/2507/42 2362/2508/43 2363/2509/44
            +f 2364/2510/45 2365/2511/46 2366/2512/47
            +f 30/30/48 32/32/49 33/33/50
            +f 30/30/48 33/33/50 31/31/51
            +f 32/32/49 34/34/52 36/36/53
            +f 32/32/49 36/36/53 33/33/50
            +f 34/34/52 35/35/54 36/36/53
            +f 35/35/54 37/37/55 3/3/4
            +f 35/35/54 3/3/4 36/36/53
            +f 37/37/55 1/1/1 3/3/4
            +f 3/3/4 2/2/3 38/38/56
            +f 2/2/3 4/4/2 39/39/57
            +f 4/4/2 5/5/58 40/40/59
            +f 4/4/2 40/40/59 39/39/57
            +f 5/5/58 6/6/60 41/41/61
            +f 5/5/58 41/41/61 40/40/59
            +f 6/6/60 7/7/62 41/41/61
            +f 10/10/7 13/13/10 42/42/63
            +f 16/16/13 20/20/16 43/43/64
            +f 20/20/16 52/52/65 43/43/64
            +f 20/20/16 22/22/19 52/52/65
            +f 22/22/19 53/53/66 52/52/65
            +f 22/22/19 44/44/22 53/53/66
            +f 25/25/29 26/26/28 45/45/23
            +f 33/33/50 36/36/53 46/46/67
            +f 36/36/53 3/3/4 38/38/56
            +f 38/38/56 2/2/3 47/47/68
            +f 38/38/56 47/47/68 57/57/69
            +f 2/2/3 39/39/57 47/47/68
            +f 41/41/61 7/7/62 48/48/70
            +f 42/42/63 13/13/10 49/49/71
            +f 13/13/10 16/16/13 50/50/72
            +f 13/13/10 50/50/72 49/49/71
            +f 16/16/13 43/43/64 51/51/73
            +f 16/16/13 51/51/73 50/50/72
            +f 44/44/22 72/72/74 53/53/66
            +f 44/44/22 45/45/23 73/73/75
            +f 44/44/22 73/73/75 72/72/74
            +f 45/45/23 26/26/28 73/73/75
            +f 31/31/51 33/33/50 54/54/76
            +f 33/33/50 46/46/67 54/54/76
            +f 46/46/67 36/36/53 55/55/77
            +f 36/36/53 38/38/56 56/56/78
            +f 36/36/53 56/56/78 55/55/77
            +f 38/38/56 57/57/69 56/56/78
            +f 47/47/68 39/39/57 58/58/79
            +f 39/39/57 40/40/59 58/58/79
            +f 10/10/7 42/42/63 60/60/80
            +f 42/42/63 49/49/71 60/60/80
            +f 51/51/73 43/43/64 61/61/81
            +f 43/43/64 62/62/82 61/61/81
            +f 43/43/64 52/52/65 70/70/83
            +f 43/43/64 70/70/83 62/62/82
            +f 52/52/65 53/53/66 71/71/84
            +f 26/26/28 28/28/41 86/86/85
            +f 28/28/41 29/29/40 86/86/85
            +f 54/54/76 46/46/67 63/63/86
            +f 46/46/67 55/55/77 63/63/86
            +f 57/57/69 47/47/68 64/64/87
            +f 57/57/69 64/64/87 81/81/88
            +f 47/47/68 58/58/79 64/64/87
            +f 40/40/59 41/41/61 65/65/89
            +f 41/41/61 48/48/70 65/65/89
            +f 59/59/8 10/10/7 66/66/90
            +f 59/59/8 66/66/90 100/100/91
            +f 10/10/7 60/60/80 66/66/90
            +f 60/60/80 49/49/71 67/67/92
            +f 49/49/71 50/50/72 68/68/93
            +f 49/49/71 68/68/93 67/67/92
            +f 50/50/72 51/51/73 69/69/94
            +f 50/50/72 69/69/94 68/68/93
            +f 51/51/73 61/61/81 69/69/94
            +f 52/52/65 71/71/84 70/70/83
            +f 26/26/28 86/86/85 73/73/75
            +f 29/29/40 31/31/51 74/74/95
            +f 31/31/51 54/54/76 74/74/95
            +f 63/63/86 55/55/77 75/75/96
            +f 55/55/77 56/56/78 76/76/97
            +f 55/55/77 76/76/97 75/75/96
            +f 56/56/78 57/57/69 81/81/88
            +f 56/56/78 81/81/88 76/76/97
            +f 64/64/87 58/58/79 77/77/98
            +f 58/58/79 40/40/59 78/78/99
            +f 58/58/79 78/78/99 77/77/98
            +f 40/40/59 65/65/89 78/78/99
            +f 71/71/84 53/53/66 98/98/100
            +f 54/54/76 63/63/86 79/79/101
            +f 63/63/86 75/75/96 79/79/101
            +f 81/81/88 64/64/87 80/80/102
            +f 64/64/87 77/77/98 80/80/102
            +f 61/61/81 62/62/82 82/82/103
            +f 62/62/82 70/70/83 83/83/104
            +f 62/62/82 83/83/104 82/82/103
            +f 70/70/83 84/84/105 83/83/104
            +f 70/70/83 71/71/84 85/85/106
            +f 70/70/83 85/85/106 84/84/105
            +f 71/71/84 98/98/100 85/85/106
            +f 29/29/40 74/74/95 86/86/85
            +f 74/74/95 54/54/76 87/87/107
            +f 54/54/76 79/79/101 87/87/107
            +f 79/79/101 75/75/96 88/88/108
            +f 75/75/96 76/76/97 88/88/108
            +f 81/81/88 80/80/102 99/99/109
            +f 100/100/91 66/66/90 89/89/110
            +f 66/66/90 60/60/80 90/90/111
            +f 66/66/90 90/90/111 89/89/110
            +f 60/60/80 67/67/92 91/91/112
            +f 60/60/80 91/91/112 90/90/111
            +f 67/67/92 68/68/93 92/92/113
            +f 67/67/92 92/92/113 91/91/112
            +f 68/68/93 69/69/94 93/93/114
            +f 68/68/93 93/93/114 92/92/113
            +f 69/69/94 61/61/81 94/94/115
            +f 69/69/94 94/94/115 93/93/114
            +f 61/61/81 82/82/103 94/94/115
            +f 88/88/108 76/76/97 95/95/116
            +f 76/76/97 81/81/88 99/99/109
            +f 76/76/97 99/99/109 95/95/116
            +f 80/80/102 77/77/98 96/96/117
            +f 77/77/98 78/78/99 97/97/118
            +f 77/77/98 97/97/118 96/96/117
            +f 78/78/99 65/65/89 97/97/118
            +f 53/53/66 72/72/74 98/98/100
            +f 99/99/109 80/80/102 101/101/119
            +f 99/99/109 101/101/119 102/102/120
            +f 80/80/102 96/96/117 103/103/121
            +f 80/80/102 103/103/121 101/101/119
            +f 96/96/117 97/97/118 104/104/122
            +f 96/96/117 104/104/122 103/103/121
            +f 97/97/118 65/65/89 105/105/123
            +f 97/97/118 105/105/123 104/104/122
            +f 65/65/89 48/48/70 106/106/124
            +f 65/65/89 106/106/124 105/105/123
            +f 100/100/91 89/89/110 107/107/125
            +f 100/100/91 107/107/125 108/108/126
            +f 89/89/110 90/90/111 109/109/127
            +f 89/89/110 109/109/127 107/107/125
            +f 90/90/111 91/91/112 110/110/128
            +f 90/90/111 110/110/128 109/109/127
            +f 91/91/112 92/92/113 111/111/129
            +f 91/91/112 111/111/129 110/110/128
            +f 92/92/113 93/93/114 112/112/130
            +f 92/92/113 112/112/130 111/111/129
            +f 93/93/114 94/94/115 113/113/131
            +f 93/93/114 113/113/131 112/112/130
            +f 94/94/115 82/82/103 114/114/132
            +f 94/94/115 114/114/132 113/113/131
            +f 82/82/103 83/83/104 115/115/133
            +f 82/82/103 115/115/133 114/114/132
            +f 83/83/104 84/84/105 116/116/134
            +f 83/83/104 116/116/134 115/115/133
            +f 84/84/105 85/85/106 117/117/135
            +f 84/84/105 117/117/135 116/116/134
            +f 85/85/106 98/98/100 118/118/136
            +f 85/85/106 118/118/136 117/117/135
            +f 98/98/100 119/119/137 118/118/136
            +f 98/98/100 72/72/74 119/119/137
            +f 72/72/74 120/120/138 119/119/137
            +f 72/72/74 73/73/75 120/120/138
            +f 73/73/75 86/86/85 121/121/139
            +f 73/73/75 121/121/139 120/120/138
            +f 86/86/85 74/74/95 122/122/140
            +f 86/86/85 122/122/140 121/121/139
            +f 74/74/95 87/87/107 123/123/141
            +f 74/74/95 123/123/141 122/122/140
            +f 87/87/107 79/79/101 124/124/142
            +f 87/87/107 124/124/142 123/123/141
            +f 79/79/101 88/88/108 125/125/143
            +f 79/79/101 125/125/143 124/124/142
            +f 88/88/108 95/95/116 126/126/144
            +f 88/88/108 126/126/144 125/125/143
            +f 95/95/116 99/99/109 102/102/120
            +f 95/95/116 102/102/120 126/126/144
            +f 102/102/120 101/101/119 127/127/145
            +f 102/102/120 127/127/145 128/128/146
            +f 101/101/119 103/103/121 129/129/147
            +f 101/101/119 129/129/147 127/127/145
            +f 103/103/121 104/104/122 130/130/148
            +f 103/103/121 130/130/148 129/129/147
            +f 104/104/122 105/105/123 131/131/149
            +f 104/104/122 131/131/149 130/130/148
            +f 108/108/126 107/107/125 132/132/150
            +f 107/107/125 109/109/127 133/133/151
            +f 107/107/125 133/133/151 132/132/150
            +f 109/109/127 110/110/128 134/134/152
            +f 109/109/127 134/134/152 133/133/151
            +f 110/110/128 111/111/129 135/135/153
            +f 110/110/128 135/135/153 134/134/152
            +f 111/111/129 112/112/130 136/136/154
            +f 111/111/129 136/136/154 135/135/153
            +f 112/112/130 113/113/131 137/137/155
            +f 112/112/130 137/137/155 136/136/154
            +f 113/113/131 114/114/132 138/138/156
            +f 113/113/131 138/138/156 137/137/155
            +f 114/114/132 115/115/133 139/139/157
            +f 114/114/132 139/139/157 138/138/156
            +f 115/115/133 116/116/134 140/140/158
            +f 115/115/133 140/140/158 139/139/157
            +f 116/116/134 117/117/135 141/141/159
            +f 116/116/134 141/141/159 140/140/158
            +f 117/117/135 118/118/136 142/142/160
            +f 117/117/135 142/142/160 141/141/159
            +f 118/118/136 119/119/137 143/143/161
            +f 118/118/136 143/143/161 142/142/160
            +f 119/119/137 144/144/162 143/143/161
            +f 119/119/137 120/120/138 145/145/163
            +f 119/119/137 145/145/163 144/144/162
            +f 120/120/138 146/146/164 145/145/163
            +f 120/120/138 121/121/139 147/147/165
            +f 120/120/138 147/147/165 146/146/164
            +f 121/121/139 148/148/166 147/147/165
            +f 121/121/139 122/122/140 149/149/167
            +f 121/121/139 149/149/167 148/148/166
            +f 122/122/140 123/123/141 150/150/168
            +f 122/122/140 150/150/168 149/149/167
            +f 123/123/141 124/124/142 151/151/169
            +f 123/123/141 151/151/169 150/150/168
            +f 124/124/142 125/125/143 152/152/170
            +f 124/124/142 152/152/170 151/151/169
            +f 125/125/143 126/126/144 153/153/171
            +f 125/125/143 153/153/171 152/152/170
            +f 126/126/144 102/102/120 128/128/146
            +f 126/126/144 128/128/146 153/153/171
            +f 128/128/146 127/127/145 154/154/172
            +f 128/128/146 154/154/172 155/155/173
            +f 127/127/145 129/129/147 156/156/174
            +f 127/127/145 156/156/174 154/154/172
            +f 129/129/147 130/130/148 157/157/175
            +f 129/129/147 157/157/175 156/156/174
            +f 130/130/148 131/131/149 158/158/176
            +f 130/130/148 158/158/176 157/157/175
            +f 132/132/150 133/133/151 159/159/177
            +f 132/132/150 159/159/177 160/160/178
            +f 133/133/151 134/134/152 161/161/179
            +f 133/133/151 161/161/179 159/159/177
            +f 134/134/152 135/135/153 162/162/180
            +f 134/134/152 162/162/180 161/161/179
            +f 135/135/153 136/136/154 163/163/181
            +f 135/135/153 163/163/181 162/162/180
            +f 136/136/154 137/137/155 164/164/182
            +f 136/136/154 164/164/182 163/163/181
            +f 137/137/155 138/138/156 165/165/183
            +f 137/137/155 165/165/183 164/164/182
            +f 138/138/156 139/139/157 166/166/184
            +f 138/138/156 166/166/184 165/165/183
            +f 139/139/157 140/140/158 167/167/185
            +f 139/139/157 167/167/185 166/166/184
            +f 140/140/158 141/141/159 168/168/186
            +f 140/140/158 168/168/186 167/167/185
            +f 141/141/159 142/142/160 169/169/187
            +f 141/141/159 169/169/187 168/168/186
            +f 142/142/160 143/143/161 170/170/188
            +f 142/142/160 170/170/188 169/169/187
            +f 143/143/161 144/144/162 171/171/189
            +f 143/143/161 171/171/189 170/170/188
            +f 144/144/162 145/145/163 172/172/190
            +f 144/144/162 172/172/190 171/171/189
            +f 145/145/163 146/146/164 173/173/191
            +f 145/145/163 173/173/191 172/172/190
            +f 146/146/164 147/147/165 174/174/192
            +f 146/146/164 174/174/192 173/173/191
            +f 147/147/165 148/148/166 175/175/193
            +f 147/147/165 175/175/193 174/174/192
            +f 148/148/166 149/149/167 176/176/194
            +f 148/148/166 176/176/194 175/175/193
            +f 149/149/167 150/150/168 177/177/195
            +f 149/149/167 177/177/195 176/176/194
            +f 150/150/168 151/151/169 178/178/196
            +f 150/150/168 178/178/196 177/177/195
            +f 151/151/169 152/152/170 179/179/197
            +f 151/151/169 179/179/197 178/178/196
            +f 152/152/170 153/153/171 180/180/198
            +f 152/152/170 180/180/198 179/179/197
            +f 153/153/171 128/128/146 155/155/173
            +f 153/153/171 155/155/173 180/180/198
            +f 155/155/173 154/154/172 181/181/199
            +f 155/155/173 181/181/199 182/182/200
            +f 154/154/172 156/156/174 183/183/201
            +f 154/154/172 183/183/201 181/181/199
            +f 156/156/174 157/157/175 184/184/202
            +f 156/156/174 184/184/202 183/183/201
            +f 157/157/175 158/158/176 185/185/203
            +f 157/157/175 185/185/203 184/184/202
            +f 160/160/178 159/159/177 186/186/204
            +f 160/160/178 186/186/204 187/187/205
            +f 159/159/177 161/161/179 188/188/206
            +f 159/159/177 188/188/206 186/186/204
            +f 161/161/179 162/162/180 189/189/207
            +f 161/161/179 189/189/207 188/188/206
            +f 162/162/180 163/163/181 190/190/208
            +f 162/162/180 190/190/208 189/189/207
            +f 163/163/181 164/164/182 191/191/209
            +f 163/163/181 191/191/209 190/190/208
            +f 164/164/182 165/165/183 192/192/210
            +f 164/164/182 192/192/210 191/191/209
            +f 165/165/183 166/166/184 193/193/211
            +f 165/165/183 193/193/211 192/192/210
            +f 166/166/184 167/167/185 194/194/212
            +f 166/166/184 194/194/212 193/193/211
            +f 167/167/185 168/168/186 195/195/213
            +f 167/167/185 195/195/213 194/194/212
            +f 168/168/186 169/169/187 196/196/214
            +f 168/168/186 196/196/214 195/195/213
            +f 169/169/187 170/170/188 197/197/215
            +f 169/169/187 197/197/215 196/196/214
            +f 170/170/188 171/171/189 198/198/216
            +f 170/170/188 198/198/216 197/197/215
            +f 171/171/189 172/172/190 199/199/217
            +f 171/171/189 199/199/217 198/198/216
            +f 172/172/190 173/173/191 200/200/218
            +f 172/172/190 200/200/218 199/199/217
            +f 173/173/191 174/174/192 201/201/219
            +f 173/173/191 201/201/219 200/200/218
            +f 174/174/192 175/175/193 202/202/220
            +f 174/174/192 202/202/220 201/201/219
            +f 175/175/193 176/176/194 203/203/221
            +f 175/175/193 203/203/221 202/202/220
            +f 176/176/194 177/177/195 204/204/222
            +f 176/176/194 204/204/222 203/203/221
            +f 177/177/195 178/178/196 205/205/223
            +f 177/177/195 205/205/223 204/204/222
            +f 178/178/196 179/179/197 206/206/224
            +f 178/178/196 206/206/224 205/205/223
            +f 179/179/197 180/180/198 207/207/225
            +f 179/179/197 207/207/225 206/206/224
            +f 180/180/198 155/155/173 182/182/200
            +f 180/180/198 182/182/200 207/207/225
            +f 182/182/200 181/181/199 208/208/226
            +f 182/182/200 208/208/226 209/209/227
            +f 181/181/199 183/183/201 210/210/228
            +f 181/181/199 210/210/228 208/208/226
            +f 183/183/201 184/184/202 211/211/229
            +f 183/183/201 211/211/229 210/210/228
            +f 184/184/202 185/185/203 212/212/230
            +f 184/184/202 212/212/230 211/211/229
            +f 187/187/205 186/186/204 213/213/231
            +f 187/187/205 213/213/231 214/214/232
            +f 186/186/204 188/188/206 215/215/233
            +f 186/186/204 215/215/233 213/213/231
            +f 188/188/206 189/189/207 216/216/234
            +f 188/188/206 216/216/234 215/215/233
            +f 189/189/207 190/190/208 217/217/235
            +f 189/189/207 217/217/235 216/216/234
            +f 190/190/208 191/191/209 218/218/236
            +f 190/190/208 218/218/236 217/217/235
            +f 191/191/209 192/192/210 219/219/237
            +f 191/191/209 219/219/237 218/218/236
            +f 192/192/210 193/193/211 220/220/238
            +f 192/192/210 220/220/238 219/219/237
            +f 193/193/211 194/194/212 221/221/239
            +f 193/193/211 221/221/239 220/220/238
            +f 194/194/212 195/195/213 222/222/240
            +f 194/194/212 222/222/240 221/221/239
            +f 195/195/213 196/196/214 223/223/241
            +f 195/195/213 223/223/241 222/222/240
            +f 196/196/214 197/197/215 224/224/242
            +f 196/196/214 224/224/242 223/223/241
            +f 197/197/215 198/198/216 225/225/243
            +f 197/197/215 225/225/243 224/224/242
            +f 198/198/216 199/199/217 226/226/244
            +f 198/198/216 226/226/244 225/225/243
            +f 199/199/217 200/200/218 227/227/245
            +f 199/199/217 227/227/245 226/226/244
            +f 200/200/218 201/201/219 228/228/246
            +f 200/200/218 228/228/246 227/227/245
            +f 201/201/219 202/202/220 229/229/247
            +f 201/201/219 229/229/247 228/228/246
            +f 202/202/220 203/203/221 230/230/248
            +f 202/202/220 230/230/248 229/229/247
            +f 203/203/221 204/204/222 231/231/249
            +f 203/203/221 231/231/249 230/230/248
            +f 204/204/222 205/205/223 232/232/250
            +f 204/204/222 232/232/250 231/231/249
            +f 205/205/223 206/206/224 233/233/251
            +f 205/205/223 233/233/251 232/232/250
            +f 206/206/224 207/207/225 234/234/252
            +f 206/206/224 234/234/252 233/233/251
            +f 207/207/225 182/182/200 209/209/227
            +f 207/207/225 209/209/227 234/234/252
            +f 209/209/227 208/208/226 235/235/253
            +f 209/209/227 235/235/253 277/277/254
            +f 208/208/226 210/210/228 236/236/255
            +f 208/208/226 236/236/255 235/235/253
            +f 210/210/228 211/211/229 237/237/256
            +f 210/210/228 237/237/256 236/236/255
            +f 211/211/229 212/212/230 238/238/257
            +f 211/211/229 238/238/257 237/237/256
            +f 212/212/230 239/239/258 238/238/257
            +f 214/214/232 213/213/231 240/240/259
            +f 214/214/232 240/240/259 241/241/260
            +f 213/213/231 215/215/233 242/242/261
            +f 213/213/231 242/242/261 240/240/259
            +f 215/215/233 216/216/234 243/243/262
            +f 215/215/233 243/243/262 242/242/261
            +f 216/216/234 217/217/235 244/244/263
            +f 216/216/234 244/244/263 243/243/262
            +f 217/217/235 218/218/236 245/245/264
            +f 217/217/235 245/245/264 244/244/263
            +f 218/218/236 219/219/237 246/246/265
            +f 218/218/236 246/246/265 245/245/264
            +f 219/219/237 220/220/238 247/247/266
            +f 219/219/237 247/247/266 246/246/265
            +f 220/220/238 221/221/239 248/248/267
            +f 220/220/238 248/248/267 247/247/266
            +f 221/221/239 222/222/240 249/249/268
            +f 221/221/239 249/249/268 248/248/267
            +f 222/222/240 223/223/241 250/250/269
            +f 222/222/240 250/250/269 249/249/268
            +f 223/223/241 224/224/242 251/251/270
            +f 223/223/241 251/251/270 250/250/269
            +f 224/224/242 225/225/243 252/252/271
            +f 224/224/242 252/252/271 251/251/270
            +f 225/225/243 226/226/244 253/253/272
            +f 225/225/243 253/253/272 252/252/271
            +f 226/226/244 227/227/245 254/254/273
            +f 226/226/244 254/254/273 253/253/272
            +f 227/227/245 228/228/246 255/255/274
            +f 227/227/245 255/255/274 254/254/273
            +f 228/228/246 229/229/247 256/256/275
            +f 228/228/246 256/256/275 255/255/274
            +f 229/229/247 230/230/248 257/257/276
            +f 229/229/247 257/257/276 256/256/275
            +f 230/230/248 231/231/249 258/258/277
            +f 230/230/248 258/258/277 257/257/276
            +f 231/231/249 232/232/250 259/259/278
            +f 231/231/249 259/259/278 258/258/277
            +f 232/232/250 233/233/251 260/260/279
            +f 232/232/250 260/260/279 259/259/278
            +f 233/233/251 234/234/252 261/261/280
            +f 233/233/251 261/261/280 260/260/279
            +f 234/234/252 209/209/227 277/277/254
            +f 234/234/252 277/277/254 261/261/280
            +f 262/262/281 241/241/260 263/263/282
            +f 263/263/282 241/241/260 264/264/283
            +f 238/238/257 239/239/258 265/265/284
            +f 239/239/258 642/659/285 265/265/284
            +f 241/241/260 240/240/259 266/266/286
            +f 240/240/259 242/242/261 267/267/287
            +f 240/240/259 267/267/287 266/266/286
            +f 242/242/261 243/243/262 267/267/287
            +f 277/277/254 235/235/253 268/268/288
            +f 235/235/253 236/236/255 268/268/288
            +f 237/237/256 238/238/257 269/269/289
            +f 238/238/257 265/265/284 269/269/289
            +f 268/268/288 236/236/255 270/270/290
            +f 236/236/255 237/237/256 270/270/290
            +f 270/270/290 237/237/256 271/271/291
            +f 237/237/256 269/269/289 271/271/291
            +f 264/264/283 241/241/260 272/272/292
            +f 241/241/260 266/266/286 272/272/292
            +f 267/267/287 243/243/262 273/273/293
            +f 243/243/262 244/244/263 273/273/293
            +f 248/248/267 249/249/268 274/274/294
            +f 249/249/268 250/250/269 274/274/294
            +f 642/659/285 264/264/283 275/275/295
            +f 264/264/283 272/272/292 275/275/295
            +f 260/260/279 261/261/280 276/276/296
            +f 261/261/280 277/277/254 276/276/296
            +f 277/277/254 268/268/288 293/293/297
            +f 265/265/284 642/659/285 278/278/298
            +f 642/659/285 275/275/295 278/278/298
            +f 250/250/269 251/251/270 279/279/299
            +f 251/251/270 252/252/271 280/280/300
            +f 251/251/270 280/280/300 279/279/299
            +f 252/252/271 253/253/272 280/280/300
            +f 276/276/296 277/277/254 293/293/297
            +f 268/268/288 270/270/290 281/281/301
            +f 270/270/290 271/271/291 282/282/302
            +f 270/270/290 282/282/302 281/281/301
            +f 271/271/291 269/269/289 283/283/303
            +f 271/271/291 283/283/303 282/282/302
            +f 269/269/289 265/265/284 284/284/304
            +f 269/269/289 284/284/304 283/283/303
            +f 265/265/284 278/278/298 285/285/305
            +f 265/265/284 285/285/305 284/284/304
            +f 278/278/298 275/275/295 286/286/306
            +f 278/278/298 286/286/306 285/285/305
            +f 275/275/295 272/272/292 287/287/307
            +f 275/275/295 287/287/307 286/286/306
            +f 272/272/292 266/266/286 288/288/308
            +f 272/272/292 288/288/308 287/287/307
            +f 266/266/286 267/267/287 288/288/308
            +f 274/274/294 250/250/269 289/289/309
            +f 250/250/269 279/279/299 289/289/309
            +f 257/257/276 258/258/277 290/290/310
            +f 258/258/277 259/259/278 291/291/311
            +f 258/258/277 291/291/311 290/290/310
            +f 259/259/278 260/260/279 292/292/312
            +f 259/259/278 292/292/312 291/291/311
            +f 260/260/279 276/276/296 292/292/312
            +f 283/283/303 284/284/304 294/294/313
            +f 284/284/304 285/285/305 295/295/314
            +f 284/284/304 295/295/314 294/294/313
            +f 285/285/305 286/286/306 296/296/315
            +f 285/285/305 296/296/315 295/295/314
            +f 286/286/306 287/287/307 297/297/316
            +f 286/286/306 297/297/316 296/296/315
            +f 287/287/307 288/288/308 298/298/317
            +f 287/287/307 298/298/317 297/297/316
            +f 288/288/308 267/267/287 299/299/318
            +f 288/288/308 299/299/318 298/298/317
            +f 267/267/287 273/273/293 299/299/318
            +f 273/273/293 244/244/263 300/300/319
            +f 244/244/263 245/245/264 301/301/320
            +f 244/244/263 301/301/320 300/300/319
            +f 245/245/264 246/246/265 302/302/321
            +f 245/245/264 302/302/321 301/301/320
            +f 246/246/265 247/247/266 303/303/322
            +f 246/246/265 303/303/322 302/302/321
            +f 247/247/266 248/248/267 304/304/323
            +f 247/247/266 304/304/323 303/303/322
            +f 248/248/267 274/274/294 304/304/323
            +f 280/280/300 253/253/272 305/305/324
            +f 253/253/272 254/254/273 305/305/324
            +f 256/256/275 257/257/276 306/306/325
            +f 257/257/276 290/290/310 306/306/325
            +f 292/292/312 276/276/296 307/307/326
            +f 276/276/296 293/293/297 307/307/326
            +f 293/293/297 268/268/288 308/308/327
            +f 293/293/297 308/308/327 313/313/328
            +f 268/268/288 281/281/301 308/308/327
            +f 281/281/301 282/282/302 309/309/329
            +f 282/282/302 283/283/303 310/310/330
            +f 282/282/302 310/310/330 309/309/329
            +f 283/283/303 294/294/313 311/311/331
            +f 283/283/303 311/311/331 310/310/330
            +f 294/294/313 295/295/314 311/311/331
            +f 291/291/311 292/292/312 312/312/332
            +f 292/292/312 307/307/326 312/312/332
            +f 307/307/326 293/293/297 313/313/328
            +f 308/308/327 281/281/301 314/314/333
            +f 281/281/301 309/309/329 314/314/333
            +f 311/311/331 295/295/314 315/315/334
            +f 295/295/314 296/296/315 316/316/335
            +f 295/295/314 316/316/335 315/315/334
            +f 296/296/315 297/297/316 317/317/336
            +f 296/296/315 317/317/336 316/316/335
            +f 297/297/316 298/298/317 318/318/337
            +f 297/297/316 318/318/337 317/317/336
            +f 298/298/317 299/299/318 319/319/338
            +f 298/298/317 319/319/338 318/318/337
            +f 299/299/318 273/273/293 320/320/339
            +f 299/299/318 320/320/339 319/319/338
            +f 273/273/293 300/300/319 320/320/339
            +f 304/304/323 274/274/294 321/321/340
            +f 274/274/294 289/289/309 322/322/341
            +f 274/274/294 322/322/341 321/321/340
            +f 289/289/309 279/279/299 323/323/342
            +f 289/289/309 323/323/342 322/322/341
            +f 279/279/299 280/280/300 323/323/342
            +f 280/280/300 305/305/324 323/323/342
            +f 305/305/324 254/254/273 331/331/343
            +f 254/254/273 255/255/274 331/331/343
            +f 255/255/274 256/256/275 324/324/344
            +f 256/256/275 306/306/325 324/324/344
            +f 306/306/325 290/290/310 325/325/345
            +f 290/290/310 291/291/311 326/326/346
            +f 290/290/310 326/326/346 325/325/345
            +f 291/291/311 312/312/332 326/326/346
            +f 313/313/328 308/308/327 327/327/347
            +f 313/313/328 327/327/347 355/355/348
            +f 308/308/327 314/314/333 327/327/347
            +f 314/314/333 309/309/329 328/328/349
            +f 309/309/329 310/310/330 329/329/350
            +f 309/309/329 329/329/350 328/328/349
            +f 310/310/330 311/311/331 330/330/351
            +f 310/310/330 330/330/351 329/329/350
            +f 311/311/331 315/315/334 330/330/351
            +f 255/255/274 324/324/344 331/331/343
            +f 312/312/332 307/307/326 332/332/352
            +f 307/307/326 313/313/328 355/355/348
            +f 307/307/326 355/355/348 332/332/352
            +f 330/330/351 315/315/334 333/333/353
            +f 315/315/334 316/316/335 334/334/354
            +f 315/315/334 334/334/354 333/333/353
            +f 316/316/335 317/317/336 335/335/355
            +f 316/316/335 335/335/355 334/334/354
            +f 317/317/336 318/318/337 336/336/356
            +f 317/317/336 336/336/356 335/335/355
            +f 318/318/337 319/319/338 336/336/356
            +f 320/320/339 300/300/319 337/337/357
            +f 300/300/319 301/301/320 338/338/358
            +f 300/300/319 338/338/358 337/337/357
            +f 301/301/320 302/302/321 339/339/359
            +f 301/301/320 339/339/359 338/338/358
            +f 302/302/321 303/303/322 340/340/360
            +f 302/302/321 340/340/360 339/339/359
            +f 303/303/322 304/304/323 341/341/361
            +f 303/303/322 341/341/361 340/340/360
            +f 304/304/323 321/321/340 341/341/361
            +f 321/321/340 322/322/341 342/342/362
            +f 322/322/341 323/323/342 343/343/363
            +f 322/322/341 343/343/363 342/342/362
            +f 323/323/342 344/344/364 343/343/363
            +f 323/323/342 305/305/324 344/344/364
            +f 305/305/324 331/331/343 345/345/365
            +f 305/305/324 345/345/365 344/344/364
            +f 314/314/333 328/328/349 346/346/366
            +f 328/328/349 329/329/350 346/346/366
            +f 346/346/366 329/329/350 347/347/367
            +f 329/329/350 330/330/351 348/348/368
            +f 329/329/350 348/348/368 347/347/367
            +f 330/330/351 333/333/353 348/348/368
            +f 335/335/355 336/336/356 349/349/369
            +f 336/336/356 319/319/338 349/349/369
            +f 326/326/346 312/312/332 350/350/370
            +f 312/312/332 332/332/352 350/350/370
            +f 355/355/348 327/327/347 351/351/371
            +f 327/327/347 314/314/333 352/352/372
            +f 327/327/347 352/352/372 351/351/371
            +f 314/314/333 346/346/366 352/352/372
            +f 349/349/369 319/319/338 353/353/373
            +f 319/319/338 320/320/339 354/354/374
            +f 319/319/338 354/354/374 353/353/373
            +f 320/320/339 337/337/357 354/354/374
            +f 346/346/366 347/347/367 356/356/375
            +f 347/347/367 348/348/368 356/356/375
            +f 348/348/368 333/333/353 357/357/376
            +f 333/333/353 334/334/354 358/358/377
            +f 333/333/353 358/358/377 357/357/376
            +f 334/334/354 335/335/355 358/358/377
            +f 324/324/344 306/306/325 359/359/378
            +f 306/306/325 325/325/345 360/360/379
            +f 306/306/325 360/360/379 359/359/378
            +f 325/325/345 326/326/346 361/361/380
            +f 325/325/345 361/361/380 360/360/379
            +f 326/326/346 350/350/370 361/361/380
            +f 355/355/348 351/351/371 387/387/381
            +f 352/352/372 346/346/366 362/362/382
            +f 346/346/366 356/356/375 362/362/382
            +f 358/358/377 335/335/355 363/363/383
            +f 335/335/355 349/349/369 363/363/383
            +f 354/354/374 337/337/357 364/364/384
            +f 337/337/357 338/338/358 364/364/384
            +f 331/331/343 324/324/344 365/365/385
            +f 324/324/344 359/359/378 365/365/385
            +f 350/350/370 332/332/352 366/366/386
            +f 332/332/352 355/355/348 387/387/381
            +f 332/332/352 387/387/381 366/366/386
            +f 356/356/375 348/348/368 367/367/387
            +f 348/348/368 357/357/376 367/367/387
            +f 363/363/383 349/349/369 368/368/388
            +f 349/349/369 353/353/373 368/368/388
            +f 364/364/384 338/338/358 369/369/389
            +f 338/338/358 339/339/359 370/370/390
            +f 338/338/358 370/370/390 369/369/389
            +f 339/339/359 340/340/360 370/370/390
            +f 341/341/361 321/321/340 371/371/391
            +f 321/321/340 342/342/362 371/371/391
            +f 387/387/381 351/351/371 372/372/392
            +f 351/351/371 352/352/372 372/372/392
            +f 368/368/388 353/353/373 373/373/393
            +f 353/353/373 354/354/374 374/374/394
            +f 353/353/373 374/374/394 373/373/393
            +f 354/354/374 364/364/384 374/374/394
            +f 370/370/390 340/340/360 375/375/395
            +f 340/340/360 341/341/361 376/376/396
            +f 340/340/360 376/376/396 375/375/395
            +f 341/341/361 371/371/391 376/376/396
            +f 361/361/380 350/350/370 377/377/397
            +f 350/350/370 366/366/386 377/377/397
            +f 372/372/392 352/352/372 378/378/398
            +f 352/352/372 362/362/382 378/378/398
            +f 374/374/394 364/364/384 379/379/399
            +f 364/364/384 369/369/389 379/379/399
            +f 343/343/363 344/344/364 380/380/400
            +f 387/387/381 372/372/392 381/381/401
            +f 372/372/392 378/378/398 381/381/401
            +f 367/367/387 357/357/376 382/382/402
            +f 357/357/376 358/358/377 382/382/402
            +f 363/363/383 368/368/388 383/383/403
            +f 368/368/388 373/373/393 384/384/404
            +f 368/368/388 384/384/404 383/383/403
            +f 373/373/393 374/374/394 385/385/405
            +f 373/373/393 385/385/405 384/384/404
            +f 374/374/394 379/379/399 385/385/405
            +f 380/380/400 344/344/364 386/386/406
            +f 344/344/364 345/345/365 386/386/406
            +f 345/345/365 331/331/343 386/386/406
            +f 378/378/398 362/362/382 388/388/407
            +f 362/362/382 356/356/375 389/389/408
            +f 362/362/382 389/389/408 388/388/407
            +f 356/356/375 367/367/387 390/390/409
            +f 356/356/375 390/390/409 389/389/408
            +f 367/367/387 382/382/402 390/390/409
            +f 382/382/402 358/358/377 391/391/410
            +f 358/358/377 363/363/383 392/392/411
            +f 358/358/377 392/392/411 391/391/410
            +f 363/363/383 383/383/403 392/392/411
            +f 379/379/399 369/369/389 393/393/412
            +f 369/369/389 370/370/390 394/394/413
            +f 369/369/389 394/394/413 393/393/412
            +f 370/370/390 375/375/395 395/395/414
            +f 370/370/390 395/395/414 394/394/413
            +f 375/375/395 376/376/396 396/396/415
            +f 375/375/395 396/396/415 395/395/414
            +f 376/376/396 371/371/391 397/397/416
            +f 376/376/396 397/397/416 396/396/415
            +f 371/371/391 342/342/362 397/397/416
            +f 342/342/362 343/343/363 380/380/400
            +f 342/342/362 380/380/400 397/397/416
            +f 331/331/343 365/365/385 398/398/417
            +f 365/365/385 359/359/378 398/398/417
            +f 360/360/379 361/361/380 399/399/418
            +f 361/361/380 377/377/397 399/399/418
            +f 387/387/381 381/381/401 407/407/419
            +f 386/386/406 331/331/343 398/398/417
            +f 398/398/417 359/359/378 400/400/420
            +f 359/359/378 360/360/379 401/401/421
            +f 359/359/378 401/401/421 400/400/420
            +f 360/360/379 399/399/418 401/401/421
            +f 399/399/418 377/377/397 402/402/422
            +f 377/377/397 366/366/386 403/403/423
            +f 377/377/397 403/403/423 402/402/422
            +f 366/366/386 387/387/381 407/407/419
            +f 366/366/386 407/407/419 403/403/423
            +f 381/381/401 378/378/398 404/404/424
            +f 378/378/398 388/388/407 404/404/424
            +f 385/385/405 379/379/399 405/405/425
            +f 379/379/399 393/393/412 405/405/425
            +f 397/397/416 380/380/400 412/412/426
            +f 380/380/400 386/386/406 412/412/426
            +f 407/407/419 381/381/401 406/406/427
            +f 381/381/401 404/404/424 406/406/427
            +f 404/404/424 388/388/407 408/408/428
            +f 388/388/407 389/389/408 408/408/428
            +f 391/391/410 392/392/411 409/409/429
            +f 392/392/411 383/383/403 409/409/429
            +f 383/383/403 384/384/404 410/410/430
            +f 384/384/404 385/385/405 411/411/431
            +f 384/384/404 411/411/431 410/410/430
            +f 385/385/405 405/405/425 411/411/431
            +f 396/396/415 397/397/416 418/418/432
            +f 397/397/416 419/419/433 418/418/432
            +f 386/386/406 413/413/434 412/412/426
            +f 386/386/406 398/398/417 413/413/434
            +f 401/401/421 399/399/418 414/414/435
            +f 399/399/418 402/402/422 414/414/435
            +f 407/407/419 406/406/427 440/440/436
            +f 382/382/402 391/391/410 415/415/437
            +f 391/391/410 409/409/429 415/415/437
            +f 409/409/429 383/383/403 416/416/438
            +f 383/383/403 410/410/430 416/416/438
            +f 405/405/425 393/393/412 434/434/439
            +f 393/393/412 394/394/413 417/417/440
            +f 393/393/412 417/417/440 434/434/439
            +f 394/394/413 395/395/414 417/417/440
            +f 395/395/414 396/396/415 436/436/441
            +f 395/395/414 436/436/441 417/417/440
            +f 396/396/415 418/418/432 436/436/441
            +f 397/397/416 412/412/426 419/419/433
            +f 413/413/434 398/398/417 420/420/442
            +f 398/398/417 400/400/420 420/420/442
            +f 414/414/435 402/402/422 421/421/443
            +f 402/402/422 403/403/423 421/421/443
            +f 403/403/423 407/407/419 440/440/436
            +f 408/408/428 389/389/408 422/422/444
            +f 389/389/408 390/390/409 423/423/445
            +f 389/389/408 423/423/445 422/422/444
            +f 390/390/409 382/382/402 424/424/446
            +f 390/390/409 424/424/446 423/423/445
            +f 382/382/402 415/415/437 424/424/446
            +f 416/416/438 410/410/430 425/425/447
            +f 410/410/430 411/411/431 425/425/447
            +f 420/420/442 400/400/420 426/426/448
            +f 400/400/420 401/401/421 427/427/449
            +f 400/400/420 427/427/449 426/426/448
            +f 401/401/421 414/414/435 428/428/450
            +f 401/401/421 428/428/450 427/427/449
            +f 414/414/435 421/421/443 428/428/450
            +f 421/421/443 403/403/423 429/429/451
            +f 403/403/423 440/440/436 429/429/451
            +f 406/406/427 404/404/424 430/430/452
            +f 404/404/424 408/408/428 431/431/453
            +f 404/404/424 431/431/453 430/430/452
            +f 408/408/428 422/422/444 431/431/453
            +f 415/415/437 409/409/429 432/432/454
            +f 409/409/429 416/416/438 432/432/454
            +f 411/411/431 405/405/425 433/433/455
            +f 405/405/425 434/434/439 433/433/455
            +f 417/417/440 435/435/456 434/434/439
            +f 417/417/440 436/436/441 435/435/456
            +f 418/418/432 419/419/433 437/437/457
            +f 418/418/432 437/437/457 436/436/441
            +f 419/419/433 412/412/426 437/437/457
            +f 412/412/426 457/457/458 437/437/457
            +f 412/412/426 413/413/434 457/457/458
            +f 413/413/434 445/445/459 457/457/458
            +f 413/413/434 420/420/442 445/445/459
            +f 428/428/450 421/421/443 438/438/460
            +f 421/421/443 429/429/451 438/438/460
            +f 440/440/436 406/406/427 439/439/461
            +f 406/406/427 430/430/452 439/439/461
            +f 431/431/453 422/422/444 441/441/462
            +f 422/422/444 423/423/445 442/442/463
            +f 422/422/444 442/442/463 441/441/462
            +f 423/423/445 424/424/446 442/442/463
            +f 432/432/454 416/416/438 443/443/464
            +f 416/416/438 425/425/447 443/443/464
            +f 425/425/447 411/411/431 444/444/465
            +f 411/411/431 433/433/455 444/444/465
            +f 420/420/442 426/426/448 446/446/466
            +f 420/420/442 446/446/466 445/445/459
            +f 426/426/448 427/427/449 447/447/467
            +f 426/426/448 447/447/467 446/446/466
            +f 427/427/449 428/428/450 448/448/468
            +f 427/427/449 448/448/468 447/447/467
            +f 428/428/450 438/438/460 448/448/468
            +f 440/440/436 439/439/461 476/476/469
            +f 430/430/452 431/431/453 449/449/470
            +f 431/431/453 441/441/462 449/449/470
            +f 442/442/463 424/424/446 450/450/471
            +f 424/424/446 415/415/437 451/451/472
            +f 424/424/446 451/451/472 450/450/471
            +f 415/415/437 432/432/454 452/452/473
            +f 415/415/437 452/452/473 451/451/472
            +f 432/432/454 443/443/464 452/452/473
            +f 444/444/465 433/433/455 453/453/474
            +f 433/433/455 434/434/439 454/454/475
            +f 434/434/439 435/435/456 454/454/475
            +f 435/435/456 455/455/476 454/454/475
            +f 435/435/456 436/436/441 455/455/476
            +f 436/436/441 456/456/477 455/455/476
            +f 436/436/441 437/437/457 456/456/477
            +f 437/437/457 457/457/458 456/456/477
            +f 429/429/451 440/440/436 476/476/469
            +f 452/452/473 443/443/464 458/458/478
            +f 443/443/464 425/425/447 459/459/479
            +f 443/443/464 459/459/479 458/458/478
            +f 425/425/447 444/444/465 459/459/479
            +f 453/453/474 433/433/455 464/464/480
            +f 433/433/455 454/454/475 464/464/480
            +f 438/438/460 429/429/451 460/460/481
            +f 429/429/451 476/476/469 460/460/481
            +f 449/449/470 441/441/462 461/461/482
            +f 441/441/462 442/442/463 462/462/483
            +f 441/441/462 462/462/483 461/461/482
            +f 442/442/463 450/450/471 462/462/483
            +f 456/456/477 457/457/458 474/474/484
            +f 457/457/458 463/463/485 474/474/484
            +f 457/457/458 445/445/459 463/463/485
            +f 445/445/459 446/446/466 463/463/485
            +f 454/454/475 471/471/486 464/464/480
            +f 454/454/475 455/455/476 471/471/486
            +f 446/446/466 447/447/467 465/465/487
            +f 447/447/467 448/448/468 466/466/488
            +f 447/447/467 466/466/488 465/465/487
            +f 448/448/468 438/438/460 467/467/489
            +f 448/448/468 467/467/489 466/466/488
            +f 438/438/460 460/460/481 467/467/489
            +f 455/455/476 456/456/477 472/472/490
            +f 456/456/477 473/473/491 472/472/490
            +f 456/456/477 474/474/484 473/473/491
            +f 463/463/485 446/446/466 468/468/492
            +f 446/446/466 465/465/487 468/468/492
            +f 451/451/472 452/452/473 469/469/493
            +f 452/452/473 458/458/478 469/469/493
            +f 439/439/461 430/430/452 470/470/494
            +f 430/430/452 449/449/470 470/470/494
            +f 455/455/476 472/472/490 471/471/486
            +f 468/468/492 465/465/487 475/475/495
            +f 465/465/487 466/466/488 475/475/495
            +f 470/470/494 449/449/470 477/477/496
            +f 449/449/470 461/461/482 477/477/496
            +f 444/444/465 453/453/474 487/487/497
            +f 453/453/474 464/464/480 487/487/497
            +f 474/474/484 463/463/485 478/478/498
            +f 463/463/485 468/468/492 478/478/498
            +f 467/467/489 460/460/481 479/479/499
            +f 460/460/481 476/476/469 479/479/499
            +f 476/476/469 439/439/461 511/511/500
            +f 471/471/486 472/472/490 480/480/501
            +f 472/472/490 473/473/491 480/480/501
            +f 478/478/498 468/468/492 481/481/502
            +f 468/468/492 475/475/495 481/481/502
            +f 479/479/499 476/476/469 511/511/500
            +f 511/511/500 439/439/461 482/482/503
            +f 439/439/461 470/470/494 482/482/503
            +f 462/462/483 450/450/471 483/483/504
            +f 450/450/471 451/451/472 484/484/505
            +f 450/450/471 484/484/505 483/483/504
            +f 451/451/472 469/469/493 484/484/505
            +f 459/459/479 444/444/465 485/485/506
            +f 444/444/465 487/487/497 485/485/506
            +f 464/464/480 471/471/486 488/488/507
            +f 458/458/478 459/459/479 486/486/508
            +f 459/459/479 485/485/506 486/486/508
            +f 464/464/480 488/488/507 487/487/497
            +f 471/471/486 492/492/509 488/488/507
            +f 471/471/486 480/480/501 492/492/509
            +f 473/473/491 474/474/484 489/489/510
            +f 475/475/495 466/466/488 490/490/511
            +f 466/466/488 467/467/489 491/491/512
            +f 466/466/488 491/491/512 490/490/511
            +f 467/467/489 479/479/499 491/491/512
            +f 480/480/501 493/493/513 492/492/509
            +f 480/480/501 473/473/491 489/489/510
            +f 480/480/501 489/489/510 493/493/513
            +f 489/489/510 474/474/484 494/494/514
            +f 474/474/484 478/478/498 494/494/514
            +f 478/478/498 481/481/502 495/495/515
            +f 478/478/498 495/495/515 494/494/514
            +f 481/481/502 475/475/495 496/496/516
            +f 481/481/502 496/496/516 495/495/515
            +f 475/475/495 490/490/511 496/496/516
            +f 477/477/496 461/461/482 497/497/517
            +f 461/461/482 462/462/483 497/497/517
            +f 462/462/483 483/483/504 498/498/518
            +f 483/483/504 484/484/505 498/498/518
            +f 511/511/500 482/482/503 499/499/519
            +f 482/482/503 470/470/494 500/500/520
            +f 482/482/503 500/500/520 499/499/519
            +f 470/470/494 477/477/496 501/501/521
            +f 470/470/494 501/501/521 500/500/520
            +f 477/477/496 497/497/517 501/501/521
            +f 497/497/517 462/462/483 502/502/522
            +f 462/462/483 498/498/518 502/502/522
            +f 498/498/518 484/484/505 503/503/523
            +f 484/484/505 469/469/493 504/504/524
            +f 484/484/505 504/504/524 503/503/523
            +f 469/469/493 458/458/478 505/505/525
            +f 469/469/493 505/505/525 504/504/524
            +f 458/458/478 486/486/508 506/506/526
            +f 458/458/478 506/506/526 505/505/525
            +f 486/486/508 485/485/506 506/506/526
            +f 487/487/497 488/488/507 507/507/527
            +f 488/488/507 492/492/509 522/522/528
            +f 488/488/507 522/522/528 507/507/527
            +f 492/492/509 493/493/513 522/522/528
            +f 493/493/513 489/489/510 508/508/529
            +f 489/489/510 494/494/514 508/508/529
            +f 490/490/511 491/491/512 509/509/530
            +f 491/491/512 479/479/499 510/510/531
            +f 491/491/512 510/510/531 509/509/530
            +f 479/479/499 511/511/500 510/510/531
            +f 501/501/521 497/497/517 512/512/532
            +f 497/497/517 502/502/522 512/512/532
            +f 485/485/506 487/487/497 528/528/533
            +f 508/508/529 494/494/514 523/523/534
            +f 494/494/514 495/495/515 513/513/535
            +f 495/495/515 496/496/516 514/514/536
            +f 495/495/515 514/514/536 513/513/535
            +f 496/496/516 490/490/511 515/515/537
            +f 496/496/516 515/515/537 514/514/536
            +f 490/490/511 509/509/530 515/515/537
            +f 511/511/500 499/499/519 524/524/538
            +f 499/499/519 500/500/520 516/516/539
            +f 500/500/520 501/501/521 517/517/540
            +f 500/500/520 517/517/540 516/516/539
            +f 501/501/521 512/512/532 517/517/540
            +f 512/512/532 502/502/522 518/518/541
            +f 502/502/522 498/498/518 519/519/542
            +f 502/502/522 519/519/542 518/518/541
            +f 498/498/518 503/503/523 520/520/543
            +f 498/498/518 520/520/543 519/519/542
            +f 503/503/523 504/504/524 520/520/543
            +f 506/506/526 485/485/506 521/521/544
            +f 485/485/506 528/528/533 521/521/544
            +f 507/507/527 522/522/528 529/529/545
            +f 493/493/513 508/508/529 522/522/528
            +f 494/494/514 513/513/535 523/523/534
            +f 510/510/531 511/511/500 524/524/538
            +f 517/517/540 512/512/532 525/525/546
            +f 512/512/532 518/518/541 525/525/546
            +f 520/520/543 504/504/524 526/526/547
            +f 504/504/524 505/505/525 527/527/548
            +f 504/504/524 527/527/548 526/526/547
            +f 505/505/525 506/506/526 527/527/548
            +f 506/506/526 521/521/544 527/527/548
            +f 487/487/497 507/507/527 528/528/533
            +f 522/522/528 508/508/529 530/530/549
            +f 522/522/528 530/530/549 529/529/545
            +f 508/508/529 531/531/550 530/530/549
            +f 508/508/529 523/523/534 531/531/550
            +f 523/523/534 532/532/551 531/531/550
            +f 523/523/534 513/513/535 533/533/552
            +f 523/523/534 533/533/552 532/532/551
            +f 513/513/535 514/514/536 534/534/553
            +f 513/513/535 534/534/553 533/533/552
            +f 514/514/536 515/515/537 534/534/553
            +f 524/524/538 499/499/519 535/535/554
            +f 524/524/538 535/535/554 543/543/555
            +f 499/499/519 516/516/539 536/536/556
            +f 499/499/519 536/536/556 535/535/554
            +f 516/516/539 517/517/540 536/536/556
            +f 517/517/540 525/525/546 536/536/556
            +f 527/527/548 521/521/544 538/538/557
            +f 527/527/548 538/538/557 537/537/558
            +f 521/521/544 528/528/533 542/542/559
            +f 521/521/544 542/542/559 538/538/557
            +f 528/528/533 507/507/527 542/542/559
            +f 507/507/527 529/529/545 539/539/560
            +f 529/529/545 530/530/549 539/539/560
            +f 534/534/553 515/515/537 540/540/561
            +f 515/515/537 509/509/530 540/540/561
            +f 509/509/530 510/510/531 541/541/562
            +f 509/509/530 541/541/562 540/540/561
            +f 510/510/531 524/524/538 543/543/555
            +f 510/510/531 543/543/555 541/541/562
            +f 507/507/527 539/539/560 542/542/559
            +f 518/518/541 519/519/542 544/544/563
            +f 519/519/542 520/520/543 545/545/564
            +f 519/519/542 545/545/564 544/544/563
            +f 520/520/543 526/526/547 545/545/564
            +f 526/526/547 527/527/548 546/546/565
            +f 526/526/547 546/546/565 545/545/564
            +f 527/527/548 537/537/558 546/546/565
            +f 543/543/555 535/535/554 555/555/566
            +f 535/535/554 536/536/556 547/547/567
            +f 536/536/556 525/525/546 548/548/568
            +f 536/536/556 548/548/568 547/547/567
            +f 525/525/546 518/518/541 548/548/568
            +f 518/518/541 544/544/563 548/548/568
            +f 537/537/558 538/538/557 556/556/569
            +f 538/538/557 542/542/559 549/549/570
            +f 538/538/557 549/549/570 556/556/569
            +f 542/542/559 550/550/571 549/549/570
            +f 542/542/559 539/539/560 550/550/571
            +f 539/539/560 551/551/572 550/550/571
            +f 539/539/560 530/530/549 551/551/572
            +f 530/530/549 531/531/550 551/551/572
            +f 531/531/550 552/552/573 551/551/572
            +f 531/531/550 532/532/551 552/552/573
            +f 532/532/551 533/533/552 553/553/574
            +f 533/533/552 534/534/553 554/554/575
            +f 533/533/552 554/554/575 553/553/574
            +f 534/534/553 540/540/561 554/554/575
            +f 540/540/561 557/557/576 554/554/575
            +f 540/540/561 541/541/562 557/557/576
            +f 541/541/562 543/543/555 555/555/566
            +f 546/546/565 537/537/558 556/556/569
            +f 552/552/573 532/532/551 568/568/577
            +f 532/532/551 553/553/574 568/568/577
            +f 535/535/554 547/547/567 555/555/566
            +f 549/549/570 550/550/571 556/556/569
            +f 541/541/562 555/555/566 557/557/576
            +f 557/557/576 555/555/566 547/547/567
            +f 554/554/575 557/557/576 547/547/567
            +f 554/554/575 547/547/567 548/548/568
            +f 550/550/571 551/551/572 556/556/569
            +f 554/554/575 548/548/568 558/558/578
            +f 548/548/568 559/559/579 558/558/578
            +f 560/560/580 554/554/575 558/558/578
            +f 554/554/575 560/560/580 561/561/581
            +f 562/562/582 554/554/575 561/561/581
            +f 563/563/583 554/554/575 562/562/582
            +f 548/548/568 564/564/584 559/559/579
            +f 553/553/574 554/554/575 563/563/583
            +f 565/565/585 553/553/574 563/563/583
            +f 566/566/586 553/553/574 565/565/585
            +f 564/564/584 548/548/568 567/567/587
            +f 568/568/577 553/553/574 566/566/586
            +f 570/570/588 548/548/568 544/544/563
            +f 567/567/587 548/548/568 570/570/588
            +f 571/571/589 544/544/563 545/545/564
            +f 570/570/588 544/544/563 571/571/589
            +f 573/573/590 545/545/564 572/572/591
            +f 545/545/564 573/573/590 571/571/589
            +f 568/568/577 569/569/592 552/552/573
            +f 572/572/591 545/545/564 574/574/593
            +f 575/575/594 552/552/573 569/569/592
            +f 576/576/595 545/545/564 546/546/565
            +f 574/574/593 545/545/564 576/576/595
            +f 577/577/596 552/552/573 575/575/594
            +f 552/552/573 577/577/596 551/551/572
            +f 576/576/595 546/546/565 578/578/597
            +f 579/579/598 551/551/572 577/577/596
            +f 580/580/599 546/546/565 556/556/569
            +f 578/578/597 546/546/565 580/580/599
            +f 556/556/569 551/551/572 579/579/598
            +f 581/581/600 556/556/569 579/579/598
            +f 580/580/599 556/556/569 581/581/600
            +f 582/582/601 583/583/602 584/584/603
            +f 582/582/601 585/585/604 583/583/602
            +f 582/582/601 586/586/605 585/585/604
            +f 582/582/601 587/587/606 586/586/605
            +f 582/582/601 589/589/607 588/588/608
            +f 582/582/601 590/590/609 589/589/607
            +f 582/582/601 591/591/610 590/590/609
            +f 582/582/601 592/592/611 591/591/610
            +f 582/582/601 593/593/612 592/592/611
            +f 582/582/601 594/594/613 593/593/612
            +f 582/582/601 595/595/614 594/594/613
            +f 582/582/601 596/596/615 595/595/614
            +f 582/582/601 597/597/616 596/596/615
            +f 582/582/601 598/598/617 597/597/616
            +f 582/582/601 599/599/618 598/598/617
            +f 582/582/601 600/600/619 599/599/618
            +f 582/582/601 601/601/620 600/600/619
            +f 582/582/601 602/602/621 601/601/620
            +f 582/582/601 603/603/622 602/602/621
            +f 582/582/601 604/604/623 603/603/622
            +f 582/582/601 605/605/624 604/604/623
            +f 582/582/601 584/584/603 605/605/624
            +f 559/559/579 583/583/602 585/585/604
            +f 585/585/604 558/558/578 559/559/579
            +f 585/585/604 586/586/605 560/560/580
            +f 558/558/578 585/585/604 560/560/580
            +f 561/561/581 586/586/605 587/587/606
            +f 586/586/605 561/561/581 560/560/580
            +f 562/562/582 587/587/606 582/582/601
            +f 562/562/582 561/561/581 587/587/606
            +f 562/562/582 582/582/601 563/563/583
            +f 584/584/603 583/583/602 564/564/584
            +f 583/583/602 559/559/579 564/564/584
            +f 563/563/583 582/582/601 588/588/608
            +f 565/565/585 588/588/608 589/589/607
            +f 565/565/585 563/563/583 588/588/608
            +f 565/565/585 589/589/607 566/566/586
            +f 584/584/603 564/564/584 605/605/624
            +f 564/564/584 567/567/587 605/605/624
            +f 566/566/586 589/589/607 590/590/609
            +f 568/568/577 590/590/609 591/591/610
            +f 568/568/577 566/566/586 590/590/609
            +f 568/568/577 591/591/610 569/569/592
            +f 604/604/623 605/605/624 570/570/588
            +f 570/570/588 605/605/624 567/567/587
            +f 570/570/588 603/603/622 604/604/623
            +f 570/570/588 571/571/589 603/603/622
            +f 601/601/620 602/602/621 572/572/591
            +f 572/572/591 602/602/621 573/573/590
            +f 571/571/589 602/602/621 603/603/622
            +f 602/602/621 571/571/589 573/573/590
            +f 572/572/591 600/600/619 601/601/620
            +f 572/572/591 574/574/593 600/600/619
            +f 569/569/592 591/591/610 592/592/611
            +f 599/599/618 600/600/619 574/574/593
            +f 592/592/611 593/593/612 575/575/594
            +f 569/569/592 592/592/611 575/575/594
            +f 574/574/593 576/576/595 599/599/618
            +f 575/575/594 593/593/612 577/577/596
            +f 576/576/595 598/598/617 599/599/618
            +f 576/576/595 578/578/597 598/598/617
            +f 577/577/596 593/593/612 594/594/613
            +f 577/577/596 594/594/613 579/579/598
            +f 597/597/616 598/598/617 580/580/599
            +f 580/580/599 598/598/617 578/578/597
            +f 579/579/598 594/594/613 595/595/614
            +f 581/581/600 595/595/614 596/596/615
            +f 581/581/600 579/579/598 595/595/614
            +f 580/580/599 596/596/615 597/597/616
            +f 580/580/599 581/581/600 596/596/615
            +f 606/606/625 4/4/2 1/1/1
            +f 607/607/626 5/5/58 4/4/2
            +f 4/4/2 606/608/625 607/607/626
            +f 608/609/627 6/6/60 5/5/58
            +f 5/5/58 607/610/626 608/609/627
            +f 609/611/628 7/7/62 6/6/60
            +f 6/6/60 608/612/627 609/611/628
            +f 7/7/62 609/613/628 628/614/629
            +f 610/615/630 9/9/6 8/8/5
            +f 9/9/6 610/616/630 11/11/9
            +f 611/617/631 11/11/9 610/616/630
            +f 11/11/9 611/618/631 12/12/11
            +f 12/12/11 612/619/632 14/14/12
            +f 612/620/632 12/12/11 611/618/631
            +f 14/14/12 613/621/633 15/15/14
            +f 613/622/633 14/14/12 612/619/632
            +f 15/15/14 614/623/634 17/17/15
            +f 614/624/634 15/15/14 613/621/633
            +f 17/17/15 615/625/635 18/18/17
            +f 615/626/635 17/17/15 614/623/634
            +f 18/18/17 616/627/636 19/19/18
            +f 616/628/636 18/18/17 615/625/635
            +f 19/19/18 617/629/637 22/22/19
            +f 617/630/637 19/19/18 616/627/636
            +f 22/22/19 618/631/638 21/21/20
            +f 618/632/638 22/22/19 617/629/637
            +f 21/21/20 619/633/639 23/23/21
            +f 619/634/639 21/21/20 618/631/638
            +f 23/23/21 2346/2492/640 45/45/23
            +f 620/635/641 23/23/21 619/633/639
            +f 45/45/23 2345/2491/642 25/25/29
            +f 25/25/29 2344/2490/643 24/24/27
            +f 2367/2513/644 2368/2514/645 2369/2515/646
            +f 2370/2516/647 2371/2517/648 2372/2518/649
            +f 2373/2519/650 2374/2520/651 2375/2521/652
            +f 27/27/653 2348/2494/654 2343/2489/655
            +f 2376/2522/656 2377/2523/657 2378/2524/658
            +f 2379/2525/659 2380/2526/660 2381/2527/661
            +f 30/30/48 622/637/662 32/32/49
            +f 622/638/662 30/30/48 2347/2493/663
            +f 34/34/52 623/639/664 35/35/54
            +f 623/640/664 34/34/52 32/32/49
            +f 35/35/54 624/641/665 37/37/55
            +f 624/642/665 35/35/54 623/639/664
            +f 37/37/55 625/643/666 1/1/1
            +f 625/644/666 37/37/55 624/641/665
            +f 1/1/1 626/645/667 606/606/625
            +f 626/645/667 627/646/668 606/606/625
            +f 626/647/667 1/1/1 625/643/666
            +f 59/59/8 630/649/669 8/8/5
            +f 7/7/62 628/614/629 48/48/70
            +f 630/649/669 59/59/8 100/100/91
            +f 629/648/670 48/48/70 628/614/629
            +f 630/649/669 100/100/91 108/108/126
            +f 48/48/70 629/648/670 106/106/124
            +f 631/650/671 106/106/124 629/648/670
            +f 108/108/126 633/652/672 630/649/669
            +f 631/650/671 105/105/123 106/106/124
            +f 105/105/123 631/650/671 131/131/149
            +f 633/652/672 108/108/126 132/132/150
            +f 633/652/672 132/132/150 160/160/178
            +f 632/651/673 131/131/149 631/650/671
            +f 131/131/149 632/651/673 158/158/176
            +f 160/160/178 635/654/674 633/652/672
            +f 635/654/674 160/160/178 187/187/205
            +f 158/158/176 632/651/673 185/185/203
            +f 635/654/674 187/187/205 214/214/232
            +f 634/653/675 185/185/203 632/651/673
            +f 185/185/203 634/653/675 212/212/230
            +f 212/212/230 634/653/675 239/239/258
            +f 635/654/674 214/214/232 639/658/676
            +f 639/658/676 214/214/232 241/241/260
            +f 634/653/675 636/655/677 239/239/258
            +f 637/656/678 239/239/258 636/655/677
            +f 262/262/281 638/657/679 241/241/260
            +f 262/262/281 640/660/680 638/657/679
            +f 640/660/680 262/262/281 263/263/282
            +f 639/658/676 241/241/260 638/657/679
            +f 637/656/678 642/659/285 239/239/258
            +f 263/263/282 641/661/681 640/662/680
            +f 641/661/681 263/263/282 264/264/283
            +f 642/659/285 641/663/681 264/264/283
            +f 744/783/682 1797/1924/683 1820/1954/684
            +f 744/783/682 745/784/685 1797/1924/683
            +f 745/784/685 694/721/686 1797/1924/683
            +f 695/722/687 643/664/688 694/721/686
            +f 644/665/689 645/666/690 643/664/688
            +f 695/722/687 644/665/689 643/664/688
            +f 644/665/689 647/668/691 645/666/690
            +f 644/665/689 646/667/692 647/668/691
            +f 648/669/693 649/670/694 647/668/691
            +f 646/667/692 648/669/693 647/668/691
            +f 650/671/695 651/675/696 649/672/694
            +f 649/673/694 648/674/693 650/671/695
            +f 652/676/697 653/677/698 651/675/696
            +f 650/671/695 652/676/697 651/675/696
            +f 654/678/699 655/679/700 653/677/698
            +f 652/676/697 654/678/699 653/677/698
            +f 656/680/701 657/681/702 655/679/700
            +f 654/678/699 656/680/701 655/679/700
            +f 658/682/703 659/683/704 657/681/702
            +f 656/680/701 658/682/703 657/681/702
            +f 660/684/705 661/685/706 659/683/704
            +f 658/682/703 660/684/705 659/683/704
            +f 662/686/707 663/687/708 661/685/706
            +f 660/684/705 662/686/707 661/685/706
            +f 664/688/709 665/689/710 663/687/708
            +f 662/686/707 664/688/709 663/687/708
            +f 666/690/711 667/691/712 665/689/710
            +f 664/688/709 666/690/711 665/689/710
            +f 668/692/713 669/693/714 667/691/712
            +f 666/690/711 668/692/713 667/691/712
            +f 670/694/715 671/695/716 669/693/717
            +f 668/692/718 670/694/715 669/693/717
            +f 672/696/719 673/697/720 671/695/721
            +f 670/694/722 672/696/719 671/695/721
            +f 674/698/723 675/699/724 673/697/720
            +f 672/696/719 674/698/723 673/697/720
            +f 676/700/725 677/701/726 675/699/724
            +f 674/698/723 676/700/725 675/699/724
            +f 678/702/727 679/703/728 677/701/726
            +f 676/700/725 678/702/727 677/701/726
            +f 680/704/729 681/705/730 679/703/728
            +f 678/702/727 680/704/729 679/703/728
            +f 682/706/731 683/710/732 681/707/730
            +f 681/708/730 680/709/729 682/706/731
            +f 715/748/733 684/711/734 1842/1982/735
            +f 690/717/736 691/718/737 689/716/738
            +f 692/719/739 693/720/740 691/718/737
            +f 690/717/736 692/719/739 691/718/737
            +f 692/719/739 1821/1955/741 693/720/740
            +f 744/783/682 1820/1954/684 965/1009/742
            +f 696/723/743 644/665/689 695/722/687
            +f 697/724/744 646/667/692 644/665/689
            +f 696/723/743 697/724/744 644/665/689
            +f 698/725/745 648/669/693 646/667/692
            +f 697/724/744 698/725/745 646/667/692
            +f 699/726/746 650/671/695 648/727/693
            +f 648/728/693 698/729/745 699/726/746
            +f 700/730/747 652/676/697 650/671/695
            +f 699/726/746 700/730/747 650/671/695
            +f 701/731/748 654/678/699 652/676/697
            +f 700/730/747 701/731/748 652/676/697
            +f 702/732/749 656/680/701 654/678/699
            +f 701/731/748 702/732/749 654/678/699
            +f 703/733/750 658/682/703 656/680/701
            +f 702/732/749 703/733/750 656/680/701
            +f 704/734/751 660/684/705 658/682/703
            +f 703/733/750 704/734/751 658/682/703
            +f 705/735/752 662/686/707 660/684/705
            +f 704/734/751 705/735/752 660/684/705
            +f 706/736/753 664/688/709 662/686/707
            +f 705/735/752 706/736/753 662/686/707
            +f 707/737/754 666/690/711 664/688/709
            +f 706/736/753 707/737/754 664/688/709
            +f 708/738/755 668/692/713 666/690/711
            +f 707/737/754 708/738/755 666/690/711
            +f 709/739/756 670/694/715 668/692/718
            +f 708/738/757 709/739/756 668/692/718
            +f 709/739/758 672/696/719 670/694/722
            +f 710/740/759 674/698/723 672/696/719
            +f 709/739/758 710/740/759 672/696/719
            +f 711/741/760 676/700/725 674/698/723
            +f 710/740/759 711/741/760 674/698/723
            +f 712/742/761 678/702/727 676/700/725
            +f 711/741/760 712/742/761 676/700/725
            +f 713/743/762 680/704/729 678/702/727
            +f 712/742/761 713/743/762 678/702/727
            +f 714/744/763 682/706/731 680/745/729
            +f 680/746/729 713/747/762 714/744/763
            +f 788/832/764 683/710/732 682/706/731
            +f 714/744/763 788/832/764 682/706/731
            +f 788/832/764 1842/1982/735 683/710/732
            +f 738/777/765 685/712/766 684/711/734
            +f 715/748/733 738/777/765 684/711/734
            +f 739/778/767 686/713/768 685/712/766
            +f 738/777/765 739/778/767 685/712/766
            +f 740/779/769 687/714/770 686/713/768
            +f 739/778/767 740/779/769 686/713/768
            +f 791/835/771 688/715/772 687/714/770
            +f 740/779/769 791/835/771 687/714/770
            +f 792/836/773 689/716/738 688/715/772
            +f 791/835/771 792/836/773 688/715/772
            +f 792/836/773 741/780/774 689/716/738
            +f 716/749/775 690/717/736 689/716/738
            +f 741/780/774 716/749/775 689/716/738
            +f 717/750/776 692/719/739 690/717/736
            +f 716/749/775 717/750/776 690/717/736
            +f 717/750/776 1821/1955/741 692/719/739
            +f 718/751/777 695/722/687 694/721/686
            +f 745/784/685 718/751/777 694/721/686
            +f 718/751/777 696/723/743 695/722/687
            +f 718/751/777 719/752/778 696/723/743
            +f 719/752/778 720/753/779 696/723/743
            +f 720/753/779 697/724/744 696/723/743
            +f 721/754/780 698/725/745 697/724/744
            +f 720/753/779 721/754/780 697/724/744
            +f 722/755/781 699/726/746 698/756/745
            +f 721/754/780 722/757/781 698/725/745
            +f 723/758/782 700/730/747 699/726/746
            +f 722/791/781 723/758/782 699/726/746
            +f 724/759/783 701/731/748 700/730/747
            +f 723/758/782 724/759/783 700/730/747
            +f 725/760/784 702/732/749 701/731/748
            +f 724/759/783 725/760/784 701/731/748
            +f 726/761/785 703/733/750 702/732/749
            +f 725/760/784 726/761/785 702/732/749
            +f 727/762/786 704/734/751 703/733/750
            +f 726/761/785 727/762/786 703/733/750
            +f 728/763/787 705/735/752 704/734/751
            +f 727/762/786 728/763/787 704/734/751
            +f 729/764/788 706/736/753 705/735/752
            +f 728/763/787 729/764/788 705/735/752
            +f 730/765/789 707/737/754 706/736/753
            +f 729/764/788 730/765/789 706/736/753
            +f 731/766/790 708/738/755 707/737/754
            +f 730/765/789 731/766/790 707/737/754
            +f 732/767/791 709/739/756 708/738/757
            +f 731/766/792 732/767/791 708/768/757
            +f 733/769/793 710/740/759 709/739/758
            +f 732/767/794 733/769/793 709/739/758
            +f 734/770/795 711/741/760 710/740/759
            +f 733/769/793 734/770/795 710/740/759
            +f 735/771/796 712/742/761 711/741/760
            +f 734/770/795 735/771/796 711/741/760
            +f 736/772/797 713/743/762 712/742/761
            +f 735/771/796 736/772/797 712/742/761
            +f 737/773/798 714/744/763 713/774/762
            +f 713/775/762 736/776/797 737/773/798
            +f 737/773/798 788/832/764 714/744/763
            +f 765/809/799 715/748/733 1842/1982/735
            +f 788/832/764 765/809/799 1842/1982/735
            +f 742/781/800 717/750/776 716/749/775
            +f 741/780/774 742/781/801 716/749/775
            +f 742/781/800 1821/1955/741 717/750/776
            +f 743/782/802 965/1009/742 1821/1955/741
            +f 768/812/803 718/751/777 745/784/685
            +f 768/812/803 746/785/804 718/751/777
            +f 746/785/804 719/752/778 718/751/777
            +f 746/785/804 720/753/779 719/752/778
            +f 746/785/804 747/786/805 720/753/779
            +f 748/787/806 721/754/780 720/753/779
            +f 747/786/805 748/787/806 720/753/779
            +f 749/788/807 722/789/781 721/754/780
            +f 748/787/806 749/788/807 721/754/780
            +f 749/788/807 750/790/808 722/792/781
            +f 751/793/809 723/758/782 722/791/781
            +f 750/790/808 751/793/809 722/791/781
            +f 752/794/810 724/759/783 723/758/782
            +f 751/793/809 752/794/810 723/758/782
            +f 753/795/811 725/760/784 724/759/783
            +f 752/794/810 753/795/811 724/759/783
            +f 754/796/812 726/761/785 725/760/784
            +f 753/795/811 754/796/812 725/760/784
            +f 755/797/813 727/762/786 726/761/785
            +f 754/796/812 755/797/813 726/761/785
            +f 756/798/814 728/763/787 727/762/786
            +f 755/797/813 756/798/814 727/762/786
            +f 757/799/815 729/764/788 728/763/787
            +f 756/798/814 757/799/815 728/763/787
            +f 758/800/816 730/765/789 729/764/788
            +f 757/799/815 758/800/816 729/764/788
            +f 759/801/817 731/766/790 730/765/789
            +f 758/800/816 759/801/817 730/765/789
            +f 760/802/818 732/767/791 731/766/792
            +f 759/801/819 760/802/818 731/766/792
            +f 760/802/820 761/803/821 732/767/794
            +f 762/804/822 733/769/793 732/767/794
            +f 761/803/821 762/804/822 732/767/794
            +f 763/805/823 734/770/795 733/769/793
            +f 762/804/822 763/805/823 733/769/793
            +f 764/806/824 735/771/796 734/770/795
            +f 763/805/823 764/806/824 734/770/795
            +f 787/831/825 736/807/797 735/771/796
            +f 764/806/824 787/831/825 735/771/796
            +f 736/808/797 788/832/764 737/773/798
            +f 816/860/826 738/777/765 715/748/733
            +f 765/809/799 816/860/826 715/748/733
            +f 789/833/827 739/778/767 738/777/765
            +f 816/860/826 789/833/827 738/777/765
            +f 790/834/828 740/779/769 739/778/767
            +f 789/833/827 790/834/828 739/778/767
            +f 790/834/828 791/835/771 740/779/769
            +f 839/883/829 741/780/774 792/836/773
            +f 839/883/829 766/810/830 741/780/774
            +f 767/811/831 742/781/801 741/780/774
            +f 766/810/830 767/811/831 741/780/774
            +f 743/782/802 1821/1955/741 742/781/800
            +f 767/811/831 743/782/802 742/781/801
            +f 891/935/832 745/784/685 744/783/682
            +f 891/935/832 795/839/833 745/784/685
            +f 795/839/833 768/812/803 745/784/685
            +f 769/813/834 746/785/804 768/812/803
            +f 770/814/835 747/786/805 746/785/804
            +f 769/813/834 770/814/835 746/785/804
            +f 771/815/836 748/787/806 747/786/805
            +f 770/814/835 771/815/836 747/786/805
            +f 772/816/837 749/788/807 748/787/806
            +f 771/815/836 772/816/837 748/787/806
            +f 772/816/837 750/790/808 749/788/807
            +f 773/817/838 751/793/809 750/790/808
            +f 772/816/837 773/817/838 750/790/808
            +f 774/818/839 752/794/810 751/793/809
            +f 773/817/838 774/818/839 751/793/809
            +f 775/819/840 753/795/811 752/794/810
            +f 774/818/839 775/819/840 752/794/810
            +f 776/820/841 754/796/812 753/795/811
            +f 775/819/840 776/820/841 753/795/811
            +f 777/821/842 755/797/813 754/796/812
            +f 776/820/841 777/821/842 754/796/812
            +f 778/822/843 756/798/814 755/797/813
            +f 777/821/842 778/822/843 755/797/813
            +f 779/823/844 757/799/815 756/798/814
            +f 778/822/843 779/823/844 756/798/814
            +f 780/824/845 758/800/816 757/799/815
            +f 779/823/844 780/824/845 757/799/815
            +f 781/825/846 759/801/817 758/800/816
            +f 780/824/845 781/825/846 758/800/816
            +f 782/826/847 760/802/818 759/801/819
            +f 781/825/848 782/826/847 759/801/819
            +f 783/827/849 761/803/821 760/802/820
            +f 782/826/850 783/827/849 760/802/820
            +f 784/828/851 762/804/822 761/803/821
            +f 783/827/849 784/828/851 761/803/821
            +f 785/829/852 763/805/823 762/804/822
            +f 784/828/851 785/829/852 762/804/822
            +f 786/830/853 764/806/824 763/805/823
            +f 785/829/852 786/830/853 763/805/823
            +f 786/830/853 787/831/825 764/806/824
            +f 814/858/854 736/808/797 787/831/825
            +f 814/858/854 788/832/764 736/808/797
            +f 815/859/855 765/809/799 788/832/764
            +f 793/837/856 766/810/830 839/883/829
            +f 794/838/857 767/811/831 766/810/830
            +f 793/837/856 794/838/857 766/810/830
            +f 794/838/857 743/782/802 767/811/831
            +f 796/840/858 769/813/834 768/812/803
            +f 795/839/833 796/840/858 768/812/803
            +f 796/840/858 770/814/835 769/813/834
            +f 796/840/858 797/841/859 770/814/835
            +f 798/842/860 771/815/836 770/814/835
            +f 797/841/859 798/842/860 770/814/835
            +f 799/843/861 772/816/837 771/815/836
            +f 798/842/860 799/843/861 771/815/836
            +f 800/844/862 773/817/838 772/816/837
            +f 799/843/861 800/844/862 772/816/837
            +f 801/845/863 774/818/839 773/817/838
            +f 800/844/862 801/845/863 773/817/838
            +f 802/846/864 775/819/840 774/818/839
            +f 801/845/863 802/846/864 774/818/839
            +f 803/847/865 776/820/841 775/819/840
            +f 802/846/864 803/847/865 775/819/840
            +f 804/848/866 777/821/842 776/820/841
            +f 803/847/865 804/848/866 776/820/841
            +f 805/849/867 778/822/843 777/821/842
            +f 804/848/866 805/849/867 777/821/842
            +f 806/850/868 779/823/844 778/822/843
            +f 805/849/867 806/850/868 778/822/843
            +f 807/851/869 780/824/845 779/823/844
            +f 806/850/868 807/851/869 779/823/844
            +f 808/852/870 781/825/846 780/824/845
            +f 807/851/869 808/852/870 780/824/845
            +f 809/853/871 782/826/847 781/825/848
            +f 808/852/872 809/853/871 781/825/848
            +f 810/854/873 783/827/849 782/826/850
            +f 809/853/874 810/854/873 782/826/850
            +f 811/855/875 784/828/851 783/827/849
            +f 810/854/873 811/855/875 783/827/849
            +f 812/856/876 785/829/852 784/828/851
            +f 811/855/875 812/856/876 784/828/851
            +f 813/857/877 786/830/853 785/829/852
            +f 812/856/876 813/857/877 785/829/852
            +f 837/881/878 787/831/825 786/830/853
            +f 813/857/877 837/881/878 786/830/853
            +f 837/881/878 814/858/854 787/831/825
            +f 815/859/855 816/860/826 765/809/799
            +f 838/882/879 789/833/827 816/860/826
            +f 864/908/880 790/834/828 789/833/827
            +f 838/882/879 864/908/880 789/833/827
            +f 865/909/881 791/835/771 790/834/828
            +f 864/908/880 865/909/881 790/834/828
            +f 839/883/829 792/836/773 791/835/771
            +f 865/909/881 839/883/829 791/835/771
            +f 817/861/882 793/837/856 839/883/829
            +f 818/862/883 794/838/857 793/837/856
            +f 817/861/882 818/862/883 793/837/856
            +f 818/862/883 743/782/802 794/838/857
            +f 891/935/832 842/886/884 795/839/833
            +f 819/863/885 796/840/858 795/839/833
            +f 842/886/884 819/863/885 795/839/833
            +f 819/863/885 820/864/886 796/840/858
            +f 820/864/886 797/841/859 796/840/858
            +f 821/865/887 798/842/860 797/841/859
            +f 820/864/886 821/865/887 797/841/859
            +f 822/866/888 799/843/861 798/842/860
            +f 821/865/887 822/866/888 798/842/860
            +f 823/867/889 800/844/862 799/843/861
            +f 822/866/888 823/867/889 799/843/861
            +f 824/868/890 801/845/863 800/844/862
            +f 823/867/889 824/868/890 800/844/862
            +f 825/869/891 802/846/864 801/845/863
            +f 824/868/890 825/869/891 801/845/863
            +f 826/870/892 803/847/865 802/846/864
            +f 825/869/891 826/870/892 802/846/864
            +f 827/871/893 804/848/866 803/847/865
            +f 826/870/892 827/871/893 803/847/865
            +f 828/872/894 805/849/867 804/848/866
            +f 827/871/893 828/872/894 804/848/866
            +f 829/873/895 806/850/868 805/849/867
            +f 828/872/894 829/873/895 805/849/867
            +f 830/874/896 807/851/869 806/850/868
            +f 829/873/895 830/874/896 806/850/868
            +f 831/875/897 808/852/870 807/851/869
            +f 830/874/896 831/875/897 807/851/869
            +f 832/876/898 809/853/871 808/852/872
            +f 831/875/899 832/876/898 808/852/872
            +f 833/877/900 810/854/873 809/853/874
            +f 832/876/901 833/877/900 809/853/874
            +f 834/878/902 811/855/875 810/854/873
            +f 833/877/900 834/878/902 810/854/873
            +f 835/879/903 812/856/876 811/855/875
            +f 834/878/902 835/879/903 811/855/875
            +f 836/880/904 813/857/877 812/856/876
            +f 835/879/903 836/880/904 812/856/876
            +f 836/880/904 837/881/878 813/857/877
            +f 861/905/905 814/858/854 837/881/878
            +f 862/906/906 815/859/855 788/832/764
            +f 814/858/854 862/906/906 788/832/764
            +f 863/907/907 816/860/826 815/859/855
            +f 863/907/907 838/882/879 816/860/826
            +f 840/884/908 817/861/882 839/883/829
            +f 887/931/909 840/884/908 839/883/829
            +f 841/885/910 818/862/883 817/861/882
            +f 840/884/908 841/885/910 817/861/882
            +f 841/885/910 743/782/802 818/862/883
            +f 843/887/911 819/863/885 842/886/884
            +f 844/888/912 820/864/886 819/863/885
            +f 843/887/911 844/888/912 819/863/885
            +f 845/889/913 821/865/887 820/864/886
            +f 844/888/912 845/889/913 820/864/886
            +f 846/890/914 822/866/888 821/865/887
            +f 845/889/913 846/890/914 821/865/887
            +f 847/891/915 823/867/889 822/866/888
            +f 846/890/914 847/891/915 822/866/888
            +f 848/892/916 824/868/890 823/867/889
            +f 847/891/915 848/892/916 823/867/889
            +f 849/893/917 825/869/891 824/868/890
            +f 848/892/916 849/893/917 824/868/890
            +f 850/894/918 826/870/892 825/869/891
            +f 849/893/917 850/894/918 825/869/891
            +f 851/895/919 827/871/893 826/870/892
            +f 850/894/918 851/895/919 826/870/892
            +f 852/896/920 828/872/894 827/871/893
            +f 851/895/919 852/896/920 827/871/893
            +f 853/897/921 829/873/895 828/872/894
            +f 852/896/920 853/897/921 828/872/894
            +f 854/898/922 830/874/896 829/873/895
            +f 853/897/921 854/898/922 829/873/895
            +f 855/899/923 831/875/897 830/874/896
            +f 854/898/922 855/899/923 830/874/896
            +f 856/900/924 832/876/898 831/875/899
            +f 855/899/925 856/900/924 831/875/899
            +f 857/901/926 833/877/900 832/876/901
            +f 856/900/927 857/901/926 832/876/901
            +f 858/902/928 834/878/902 833/877/900
            +f 857/901/926 858/902/928 833/877/900
            +f 859/903/929 835/879/903 834/878/902
            +f 858/902/928 859/903/929 834/878/902
            +f 860/904/930 836/880/904 835/879/903
            +f 859/903/929 860/904/930 835/879/903
            +f 885/929/931 837/881/878 836/880/904
            +f 860/904/930 885/929/931 836/880/904
            +f 885/929/931 861/905/905 837/881/878
            +f 862/906/906 863/907/907 815/859/855
            +f 886/930/932 838/882/879 863/907/907
            +f 886/930/932 864/908/880 838/882/879
            +f 887/931/909 839/883/829 865/909/881
            +f 866/910/933 840/884/908 887/931/909
            +f 867/911/934 841/885/910 840/884/908
            +f 866/910/933 867/911/934 840/884/908
            +f 867/911/934 743/782/802 841/885/910
            +f 892/936/935 842/886/884 891/935/832
            +f 868/912/936 843/887/911 842/886/884
            +f 892/936/935 868/912/936 842/886/884
            +f 868/912/936 844/888/912 843/887/911
            +f 868/912/936 869/913/937 844/888/912
            +f 870/914/938 845/889/913 844/888/912
            +f 869/913/937 870/914/938 844/888/912
            +f 871/915/939 846/890/914 845/889/913
            +f 870/914/938 871/915/939 845/889/913
            +f 872/916/940 847/891/915 846/890/914
            +f 871/915/939 872/916/940 846/890/914
            +f 873/917/941 848/892/916 847/891/915
            +f 872/916/940 873/917/941 847/891/915
            +f 874/918/942 849/893/917 848/892/916
            +f 873/917/941 874/918/942 848/892/916
            +f 875/919/943 850/894/918 849/893/917
            +f 874/918/942 875/919/943 849/893/917
            +f 876/920/944 851/895/919 850/894/918
            +f 875/919/943 876/920/944 850/894/918
            +f 877/921/945 852/896/920 851/895/919
            +f 876/920/944 877/921/945 851/895/919
            +f 878/922/946 853/897/921 852/896/920
            +f 877/921/945 878/922/946 852/896/920
            +f 879/923/947 854/898/922 853/897/921
            +f 878/922/946 879/923/947 853/897/921
            +f 880/924/948 855/899/923 854/898/922
            +f 879/923/947 880/924/948 854/898/922
            +f 881/925/949 856/900/924 855/899/925
            +f 880/924/950 881/925/949 855/899/925
            +f 881/925/951 857/901/926 856/900/927
            +f 882/926/952 858/902/928 857/901/926
            +f 881/925/951 882/926/952 857/901/926
            +f 883/927/953 859/903/929 858/902/928
            +f 882/926/952 883/927/953 858/902/928
            +f 884/928/954 860/904/930 859/903/929
            +f 883/927/953 884/928/954 859/903/929
            +f 884/928/954 885/929/931 860/904/930
            +f 910/954/955 861/905/905 885/929/931
            +f 911/955/956 862/906/906 814/858/854
            +f 861/905/905 911/955/956 814/858/854
            +f 912/956/957 863/907/907 862/906/906
            +f 912/956/957 886/930/932 863/907/907
            +f 913/957/958 864/908/880 886/930/932
            +f 914/958/959 865/909/881 864/908/880
            +f 913/957/958 914/958/959 864/908/880
            +f 914/958/959 887/931/909 865/909/881
            +f 937/981/960 915/959/961 887/931/909
            +f 888/932/962 866/910/933 887/931/909
            +f 915/959/961 888/932/962 887/931/909
            +f 889/933/963 867/911/934 866/910/933
            +f 888/932/962 889/933/963 866/910/933
            +f 889/933/963 743/782/802 867/911/934
            +f 890/934/964 965/1009/742 743/782/802
            +f 1064/1108/965 744/783/682 965/1009/742
            +f 893/937/966 868/912/936 892/936/935
            +f 894/938/967 869/913/937 868/912/936
            +f 893/937/966 894/938/967 868/912/936
            +f 895/939/968 870/914/938 869/913/937
            +f 894/938/967 895/939/968 869/913/937
            +f 896/940/969 871/915/939 870/914/938
            +f 895/939/968 896/940/969 870/914/938
            +f 897/941/970 872/916/940 871/915/939
            +f 896/940/969 897/941/970 871/915/939
            +f 898/942/971 873/917/941 872/916/940
            +f 897/941/970 898/942/971 872/916/940
            +f 899/943/972 874/918/942 873/917/941
            +f 898/942/971 899/943/972 873/917/941
            +f 900/944/973 875/919/943 874/918/942
            +f 899/943/972 900/944/973 874/918/942
            +f 901/945/974 876/920/944 875/919/943
            +f 900/944/973 901/945/974 875/919/943
            +f 902/946/975 877/921/945 876/920/944
            +f 901/945/974 902/946/975 876/920/944
            +f 903/947/976 878/922/946 877/921/945
            +f 902/946/975 903/947/976 877/921/945
            +f 904/948/977 879/923/947 878/922/946
            +f 903/947/976 904/948/977 878/922/946
            +f 905/949/978 880/924/948 879/923/947
            +f 904/948/977 905/949/978 879/923/947
            +f 906/950/979 881/925/949 880/924/950
            +f 905/949/980 906/950/979 880/924/950
            +f 907/951/981 882/926/952 881/925/951
            +f 906/950/982 907/951/981 881/925/951
            +f 908/952/983 883/927/953 882/926/952
            +f 907/951/981 908/952/983 882/926/952
            +f 909/953/984 884/928/954 883/927/953
            +f 908/952/983 909/953/984 883/927/953
            +f 935/979/985 885/929/931 884/928/954
            +f 909/953/984 935/979/985 884/928/954
            +f 935/979/985 910/954/955 885/929/931
            +f 911/955/956 912/956/957 862/906/906
            +f 936/980/986 886/930/932 912/956/957
            +f 936/980/986 913/957/958 886/930/932
            +f 937/981/960 887/931/909 914/958/959
            +f 916/960/987 889/933/963 888/932/962
            +f 915/959/961 916/960/987 888/932/962
            +f 890/934/964 743/782/802 889/933/963
            +f 916/960/987 890/934/964 889/933/963
            +f 990/1034/988 891/935/832 744/783/682
            +f 940/984/989 892/936/935 891/935/832
            +f 990/1034/988 940/984/989 891/935/832
            +f 917/961/990 893/937/966 892/936/935
            +f 940/984/989 917/961/990 892/936/935
            +f 917/961/990 918/962/991 893/937/966
            +f 918/962/991 894/938/967 893/937/966
            +f 919/963/992 895/939/968 894/938/967
            +f 918/962/991 919/963/992 894/938/967
            +f 920/964/993 896/940/969 895/939/968
            +f 919/963/992 920/964/993 895/939/968
            +f 921/965/994 897/941/970 896/940/969
            +f 920/964/993 921/965/994 896/940/969
            +f 922/966/995 898/942/971 897/941/970
            +f 921/965/994 922/966/995 897/941/970
            +f 923/967/996 899/943/972 898/942/971
            +f 922/966/995 923/967/996 898/942/971
            +f 924/968/997 900/944/973 899/943/972
            +f 923/967/996 924/968/997 899/943/972
            +f 925/969/998 901/945/974 900/944/973
            +f 924/968/997 925/969/998 900/944/973
            +f 926/970/999 902/946/975 901/945/974
            +f 925/969/998 926/970/999 901/945/974
            +f 927/971/1000 903/947/976 902/946/975
            +f 926/970/999 927/971/1000 902/946/975
            +f 928/972/1001 904/948/977 903/947/976
            +f 927/971/1000 928/972/1001 903/947/976
            +f 929/973/1002 905/949/978 904/948/977
            +f 928/972/1001 929/973/1002 904/948/977
            +f 930/974/1003 906/950/979 905/949/980
            +f 929/973/1004 930/974/1003 905/949/980
            +f 930/974/1005 931/975/1006 906/950/982
            +f 932/976/1007 907/951/981 906/950/982
            +f 931/975/1006 932/976/1007 906/950/982
            +f 933/977/1008 908/952/983 907/951/981
            +f 932/976/1007 933/977/1008 907/951/981
            +f 934/978/1009 909/953/984 908/952/983
            +f 933/977/1008 934/978/1009 908/952/983
            +f 934/978/1009 935/979/985 909/953/984
            +f 959/1003/1010 910/954/955 935/979/985
            +f 1010/1054/1011 861/905/905 910/954/955
            +f 960/1004/1012 911/955/956 861/905/905
            +f 1010/1054/1011 960/1004/1012 861/905/905
            +f 961/1005/1013 912/956/957 911/955/956
            +f 961/1005/1013 936/980/986 912/956/957
            +f 962/1006/1014 913/957/958 936/980/986
            +f 986/1030/1015 914/958/959 913/957/958
            +f 962/1006/1014 986/1030/1015 913/957/958
            +f 986/1030/1015 937/981/960 914/958/959
            +f 937/981/960 938/982/1016 915/959/961
            +f 939/983/1017 916/960/987 915/959/961
            +f 938/982/1016 939/983/1017 915/959/961
            +f 939/983/1017 890/934/964 916/960/987
            +f 941/985/1018 917/961/990 940/984/989
            +f 941/985/1018 918/962/991 917/961/990
            +f 941/985/1018 942/986/1019 918/962/991
            +f 943/987/1020 919/963/992 918/962/991
            +f 942/986/1019 943/987/1020 918/962/991
            +f 944/988/1021 920/964/993 919/963/992
            +f 943/987/1020 944/988/1021 919/963/992
            +f 945/989/1022 921/965/994 920/964/993
            +f 944/988/1021 945/989/1022 920/964/993
            +f 946/990/1023 922/966/995 921/965/994
            +f 945/989/1022 946/990/1023 921/965/994
            +f 947/991/1024 923/967/996 922/966/995
            +f 946/990/1023 947/991/1024 922/966/995
            +f 948/992/1025 924/968/997 923/967/996
            +f 947/991/1024 948/992/1025 923/967/996
            +f 949/993/1026 925/969/998 924/968/997
            +f 948/992/1025 949/993/1026 924/968/997
            +f 950/994/1027 926/970/999 925/969/998
            +f 949/993/1026 950/994/1027 925/969/998
            +f 951/995/1028 927/971/1000 926/970/999
            +f 950/994/1027 951/995/1028 926/970/999
            +f 952/996/1029 928/972/1001 927/971/1000
            +f 951/995/1028 952/996/1029 927/971/1000
            +f 953/997/1030 929/973/1002 928/972/1001
            +f 952/996/1029 953/997/1030 928/972/1001
            +f 954/998/1031 930/974/1003 929/973/1004
            +f 953/997/1032 954/998/1031 929/973/1004
            +f 955/999/1033 931/975/1006 930/974/1005
            +f 954/998/1034 955/999/1033 930/974/1005
            +f 956/1000/1035 932/976/1007 931/975/1006
            +f 955/999/1033 956/1000/1035 931/975/1006
            +f 957/1001/1036 933/977/1008 932/976/1007
            +f 956/1000/1035 957/1001/1036 932/976/1007
            +f 958/1002/1037 934/978/1009 933/977/1008
            +f 957/1001/1036 958/1002/1037 933/977/1008
            +f 984/1028/1038 935/979/985 934/978/1009
            +f 958/1002/1037 984/1028/1038 934/978/1009
            +f 984/1028/1038 959/1003/1010 935/979/985
            +f 959/1003/1010 1010/1054/1011 910/954/955
            +f 960/1004/1012 961/1005/1013 911/955/956
            +f 985/1029/1039 936/980/986 961/1005/1013
            +f 985/1029/1039 962/1006/1014 936/980/986
            +f 1014/1058/1040 937/981/960 986/1030/1015
            +f 963/1007/1041 938/982/1016 937/981/960
            +f 964/1008/1042 939/983/1017 938/982/1016
            +f 963/1007/1041 964/1008/1042 938/982/1016
            +f 964/1008/1042 890/934/964 939/983/1017
            +f 1064/1108/965 990/1034/988 744/783/682
            +f 990/1034/988 966/1010/1043 940/984/989
            +f 966/1010/1043 941/985/1018 940/984/989
            +f 966/1010/1043 967/1011/1044 941/985/1018
            +f 967/1011/1044 942/986/1019 941/985/1018
            +f 968/1012/1045 943/987/1020 942/986/1019
            +f 967/1011/1044 968/1012/1045 942/986/1019
            +f 969/1013/1046 944/988/1021 943/987/1020
            +f 968/1012/1045 969/1013/1046 943/987/1020
            +f 970/1014/1047 945/989/1022 944/988/1021
            +f 969/1013/1046 970/1014/1047 944/988/1021
            +f 971/1015/1048 946/990/1023 945/989/1022
            +f 970/1014/1047 971/1015/1048 945/989/1022
            +f 972/1016/1049 947/991/1024 946/990/1023
            +f 971/1015/1048 972/1016/1049 946/990/1023
            +f 973/1017/1050 948/992/1025 947/991/1024
            +f 972/1016/1049 973/1017/1050 947/991/1024
            +f 974/1018/1051 949/993/1026 948/992/1025
            +f 973/1017/1050 974/1018/1051 948/992/1025
            +f 975/1019/1052 950/994/1027 949/993/1026
            +f 974/1018/1051 975/1019/1052 949/993/1026
            +f 976/1020/1053 951/995/1028 950/994/1027
            +f 975/1019/1052 976/1020/1053 950/994/1027
            +f 977/1021/1054 952/996/1029 951/995/1028
            +f 976/1020/1053 977/1021/1054 951/995/1028
            +f 978/1022/1055 953/997/1030 952/996/1029
            +f 977/1021/1054 978/1022/1055 952/996/1029
            +f 979/1023/1056 954/998/1031 953/997/1032
            +f 978/1022/1057 979/1023/1056 953/997/1032
            +f 980/1024/1058 955/999/1033 954/998/1034
            +f 979/1023/1059 980/1024/1058 954/998/1034
            +f 981/1025/1060 956/1000/1035 955/999/1033
            +f 980/1024/1058 981/1025/1060 955/999/1033
            +f 982/1026/1061 957/1001/1036 956/1000/1035
            +f 981/1025/1060 982/1026/1061 956/1000/1035
            +f 983/1027/1062 958/1002/1037 957/1001/1036
            +f 982/1026/1061 983/1027/1062 957/1001/1036
            +f 983/1027/1062 984/1028/1038 958/1002/1037
            +f 1009/1053/1063 959/1003/1010 984/1028/1038
            +f 1011/1055/1064 960/1004/1012 1010/1054/1011
            +f 1012/1056/1065 961/1005/1013 960/1004/1012
            +f 1012/1056/1065 985/1029/1039 961/1005/1013
            +f 1013/1057/1066 962/1006/1014 985/1029/1039
            +f 1013/1057/1066 986/1030/1015 962/1006/1014
            +f 987/1031/1067 963/1007/1041 937/981/960
            +f 1014/1058/1040 987/1031/1067 937/981/960
            +f 988/1032/1068 964/1008/1042 963/1007/1041
            +f 987/1031/1067 988/1032/1068 963/1007/1041
            +f 988/1032/1068 890/934/964 964/1008/1042
            +f 1017/1061/1069 965/1009/742 890/934/964
            +f 989/1033/1070 1017/1061/1069 890/934/964
            +f 1017/1061/1069 1064/1108/965 965/1009/742
            +f 1091/1135/1071 991/1035/1072 990/1034/988
            +f 991/1035/1072 966/1010/1043 990/1034/988
            +f 991/1035/1072 992/1036/1073 966/1010/1043
            +f 992/1036/1073 967/1011/1044 966/1010/1043
            +f 992/1036/1073 993/1037/1074 967/1011/1044
            +f 994/1038/1075 968/1012/1045 967/1011/1044
            +f 993/1037/1074 994/1038/1075 967/1011/1044
            +f 995/1039/1076 969/1013/1046 968/1012/1045
            +f 994/1038/1075 995/1039/1076 968/1012/1045
            +f 996/1040/1077 970/1014/1047 969/1013/1046
            +f 995/1039/1076 996/1040/1077 969/1013/1046
            +f 997/1041/1078 971/1015/1048 970/1014/1047
            +f 996/1040/1077 997/1041/1078 970/1014/1047
            +f 998/1042/1079 972/1016/1049 971/1015/1048
            +f 997/1041/1078 998/1042/1079 971/1015/1048
            +f 999/1043/1080 973/1017/1050 972/1016/1049
            +f 998/1042/1079 999/1043/1080 972/1016/1049
            +f 1000/1044/1081 974/1018/1051 973/1017/1050
            +f 999/1043/1080 1000/1044/1081 973/1017/1050
            +f 1001/1045/1082 975/1019/1052 974/1018/1051
            +f 1000/1044/1081 1001/1045/1082 974/1018/1051
            +f 1002/1046/1083 976/1020/1053 975/1019/1052
            +f 1001/1045/1082 1002/1046/1083 975/1019/1052
            +f 1003/1047/1084 977/1021/1054 976/1020/1053
            +f 1002/1046/1083 1003/1047/1084 976/1020/1053
            +f 1004/1048/1085 978/1022/1055 977/1021/1054
            +f 1003/1047/1084 1004/1048/1085 977/1021/1054
            +f 1005/1049/1086 979/1023/1056 978/1022/1057
            +f 1004/1048/1087 1005/1049/1086 978/1022/1057
            +f 1005/1049/1088 980/1024/1058 979/1023/1059
            +f 1006/1050/1089 981/1025/1060 980/1024/1058
            +f 1005/1049/1088 1006/1050/1089 980/1024/1058
            +f 1007/1051/1090 982/1026/1061 981/1025/1060
            +f 1006/1050/1089 1007/1051/1090 981/1025/1060
            +f 1008/1052/1091 983/1027/1062 982/1026/1061
            +f 1007/1051/1090 1008/1052/1091 982/1026/1061
            +f 1035/1079/1092 984/1028/1038 983/1027/1062
            +f 1008/1052/1091 1035/1079/1092 983/1027/1062
            +f 1035/1079/1092 1009/1053/1063 984/1028/1038
            +f 1009/1053/1063 1010/1054/1011 959/1003/1010
            +f 1011/1055/1064 1012/1056/1065 960/1004/1012
            +f 1036/1080/1093 985/1029/1039 1012/1056/1065
            +f 1036/1080/1093 1013/1057/1066 985/1029/1039
            +f 1087/1131/1094 986/1030/1015 1013/1057/1066
            +f 1087/1131/1094 1014/1058/1040 986/1030/1015
            +f 1015/1059/1095 987/1031/1067 1014/1058/1040
            +f 1016/1060/1096 988/1032/1068 987/1031/1067
            +f 1015/1059/1095 1016/1060/1097 987/1031/1067
            +f 989/1033/1070 890/934/964 988/1032/1068
            +f 1016/1060/1096 989/1033/1070 988/1032/1068
            +f 1091/1135/1071 990/1034/988 1064/1108/965
            +f 991/1035/1072 1018/1062/1098 992/1036/1073
            +f 1018/1062/1098 1019/1063/1099 992/1036/1073
            +f 1019/1063/1099 993/1037/1074 992/1036/1073
            +f 1020/1064/1100 994/1038/1075 993/1037/1074
            +f 1019/1063/1099 1020/1064/1100 993/1037/1074
            +f 1021/1065/1101 995/1039/1076 994/1038/1075
            +f 1020/1064/1100 1021/1065/1101 994/1038/1075
            +f 1022/1066/1102 996/1040/1077 995/1039/1076
            +f 1021/1065/1101 1022/1066/1102 995/1039/1076
            +f 1023/1067/1103 997/1041/1078 996/1040/1077
            +f 1022/1066/1102 1023/1067/1103 996/1040/1077
            +f 1024/1068/1104 998/1042/1079 997/1041/1078
            +f 1023/1067/1103 1024/1068/1104 997/1041/1078
            +f 1025/1069/1105 999/1043/1080 998/1042/1079
            +f 1024/1068/1104 1025/1069/1105 998/1042/1079
            +f 1026/1070/1106 1000/1044/1081 999/1043/1080
            +f 1025/1069/1105 1026/1070/1106 999/1043/1080
            +f 1027/1071/1107 1001/1045/1082 1000/1044/1081
            +f 1026/1070/1106 1027/1071/1107 1000/1044/1081
            +f 1028/1072/1108 1002/1046/1083 1001/1045/1082
            +f 1027/1071/1107 1028/1072/1108 1001/1045/1082
            +f 1029/1073/1109 1003/1047/1084 1002/1046/1083
            +f 1028/1072/1108 1029/1073/1109 1002/1046/1083
            +f 1030/1074/1110 1004/1048/1085 1003/1047/1084
            +f 1029/1073/1109 1030/1074/1110 1003/1047/1084
            +f 1031/1075/1111 1005/1049/1086 1004/1048/1087
            +f 1030/1074/1112 1031/1075/1111 1004/1048/1087
            +f 1032/1076/1113 1006/1050/1089 1005/1049/1088
            +f 1031/1075/1114 1032/1076/1113 1005/1049/1088
            +f 1033/1077/1115 1007/1051/1090 1006/1050/1089
            +f 1032/1076/1113 1033/1077/1115 1006/1050/1089
            +f 1034/1078/1116 1008/1052/1091 1007/1051/1090
            +f 1033/1077/1115 1034/1078/1116 1007/1051/1090
            +f 1034/1078/1116 1035/1079/1092 1008/1052/1091
            +f 1057/1101/1117 1009/1053/1063 1035/1079/1092
            +f 1085/1129/1118 1011/1055/1064 1010/1054/1011
            +f 1009/1053/1063 1085/1129/1118 1010/1054/1011
            +f 1058/1102/1119 1012/1056/1065 1011/1055/1064
            +f 1058/1102/1119 1036/1080/1093 1012/1056/1065
            +f 1059/1103/1120 1013/1057/1066 1036/1080/1093
            +f 1059/1103/1120 1087/1131/1094 1013/1057/1066
            +f 1060/1104/1121 1014/1058/1040 1087/1131/1094
            +f 1060/1104/1121 1061/1105/1122 1014/1058/1040
            +f 1037/1081/1123 1015/1059/1095 1014/1058/1040
            +f 1061/1105/1122 1037/1081/1123 1014/1058/1040
            +f 1038/1082/1124 1016/1060/1097 1015/1059/1095
            +f 1037/1081/1123 1038/1082/1124 1015/1059/1095
            +f 1038/1082/1124 989/1033/1070 1016/1060/1097
            +f 1090/1134/1125 1017/1061/1069 989/1033/1070
            +f 1090/1134/1125 1064/1108/965 1017/1061/1069
            +f 1065/1109/1126 991/1035/1072 1091/1135/1071
            +f 1065/1109/1126 1039/1083/1127 991/1035/1072
            +f 1039/1083/1127 1018/1062/1098 991/1035/1072
            +f 1039/1083/1127 1019/1063/1099 1018/1062/1098
            +f 1039/1083/1127 1040/1084/1128 1019/1063/1099
            +f 1041/1085/1129 1020/1064/1100 1019/1063/1099
            +f 1040/1084/1128 1041/1085/1129 1019/1063/1099
            +f 1042/1086/1130 1021/1065/1101 1020/1064/1100
            +f 1041/1085/1129 1042/1086/1130 1020/1064/1100
            +f 1043/1087/1131 1022/1066/1102 1021/1065/1101
            +f 1042/1086/1130 1043/1087/1131 1021/1065/1101
            +f 1044/1088/1132 1023/1067/1103 1022/1066/1102
            +f 1043/1087/1131 1044/1088/1132 1022/1066/1102
            +f 1045/1089/1133 1024/1068/1104 1023/1067/1103
            +f 1044/1088/1132 1045/1089/1133 1023/1067/1103
            +f 1046/1090/1134 1025/1069/1105 1024/1068/1104
            +f 1045/1089/1133 1046/1090/1134 1024/1068/1104
            +f 1047/1091/1135 1026/1070/1106 1025/1069/1105
            +f 1046/1090/1134 1047/1091/1135 1025/1069/1105
            +f 1048/1092/1136 1027/1071/1107 1026/1070/1106
            +f 1047/1091/1135 1048/1092/1136 1026/1070/1106
            +f 1049/1093/1137 1028/1072/1108 1027/1071/1107
            +f 1048/1092/1136 1049/1093/1137 1027/1071/1107
            +f 1050/1094/1138 1029/1073/1109 1028/1072/1108
            +f 1049/1093/1137 1050/1094/1138 1028/1072/1108
            +f 1051/1095/1139 1030/1074/1110 1029/1073/1109
            +f 1050/1094/1138 1051/1095/1139 1029/1073/1109
            +f 1052/1096/1140 1031/1075/1111 1030/1074/1112
            +f 1051/1095/1141 1052/1096/1140 1030/1074/1112
            +f 1052/1096/1142 1053/1097/1143 1031/1075/1114
            +f 1054/1098/1144 1032/1076/1113 1031/1075/1114
            +f 1053/1097/1143 1054/1098/1144 1031/1075/1114
            +f 1055/1099/1145 1033/1077/1115 1032/1076/1113
            +f 1054/1098/1144 1055/1099/1145 1032/1076/1113
            +f 1056/1100/1146 1034/1078/1116 1033/1077/1115
            +f 1055/1099/1145 1056/1100/1146 1033/1077/1115
            +f 1084/1128/1147 1035/1079/1092 1034/1078/1116
            +f 1056/1100/1146 1084/1128/1147 1034/1078/1116
            +f 1084/1128/1147 1057/1101/1117 1035/1079/1092
            +f 1085/1129/1118 1058/1102/1119 1011/1055/1064
            +f 1086/1130/1148 1036/1080/1093 1058/1102/1119
            +f 1086/1130/1148 1059/1103/1120 1036/1080/1093
            +f 1062/1106/1149 1038/1082/1124 1037/1081/1123
            +f 1061/1105/1122 1062/1106/1149 1037/1081/1123
            +f 1062/1106/1149 989/1033/1070 1038/1082/1124
            +f 1063/1107/1150 1090/1134/1125 989/1033/1070
            +f 1066/1110/1151 1039/1083/1127 1065/1109/1126
            +f 1066/1110/1151 1067/1111/1152 1039/1083/1127
            +f 1067/1111/1152 1040/1084/1128 1039/1083/1127
            +f 1068/1112/1153 1041/1085/1129 1040/1084/1128
            +f 1067/1111/1152 1068/1112/1153 1040/1084/1128
            +f 1069/1113/1154 1042/1086/1130 1041/1085/1129
            +f 1068/1112/1153 1069/1113/1154 1041/1085/1129
            +f 1070/1114/1155 1043/1087/1131 1042/1086/1130
            +f 1069/1113/1154 1070/1114/1155 1042/1086/1130
            +f 1071/1115/1156 1044/1088/1132 1043/1087/1131
            +f 1070/1114/1155 1071/1115/1156 1043/1087/1131
            +f 1072/1116/1157 1045/1089/1133 1044/1088/1132
            +f 1071/1115/1156 1072/1116/1157 1044/1088/1132
            +f 1073/1117/1158 1046/1090/1134 1045/1089/1133
            +f 1072/1116/1157 1073/1117/1158 1045/1089/1133
            +f 1074/1118/1159 1047/1091/1135 1046/1090/1134
            +f 1073/1117/1158 1074/1118/1159 1046/1090/1134
            +f 1075/1119/1160 1048/1092/1136 1047/1091/1135
            +f 1074/1118/1159 1075/1119/1160 1047/1091/1135
            +f 1076/1120/1161 1049/1093/1137 1048/1092/1136
            +f 1075/1119/1160 1076/1120/1161 1048/1092/1136
            +f 1077/1121/1162 1050/1094/1138 1049/1093/1137
            +f 1076/1120/1161 1077/1121/1162 1049/1093/1137
            +f 1078/1122/1163 1051/1095/1139 1050/1094/1138
            +f 1077/1121/1162 1078/1122/1163 1050/1094/1138
            +f 1079/1123/1164 1052/1096/1140 1051/1095/1141
            +f 1078/1122/1165 1079/1123/1164 1051/1095/1141
            +f 1080/1124/1166 1053/1097/1143 1052/1096/1142
            +f 1079/1123/1167 1080/1124/1166 1052/1096/1142
            +f 1081/1125/1168 1054/1098/1144 1053/1097/1143
            +f 1080/1124/1166 1081/1125/1168 1053/1097/1143
            +f 1082/1126/1169 1055/1099/1145 1054/1098/1144
            +f 1081/1125/1168 1082/1126/1169 1054/1098/1144
            +f 1083/1127/1170 1056/1100/1146 1055/1099/1145
            +f 1082/1126/1169 1083/1127/1170 1055/1099/1145
            +f 1083/1127/1170 1084/1128/1147 1056/1100/1146
            +f 1111/1155/1171 1057/1101/1117 1084/1128/1147
            +f 1134/1178/1172 1058/1102/1119 1085/1129/1118
            +f 1134/1178/1172 1086/1130/1148 1058/1102/1119
            +f 1136/1180/1173 1059/1103/1120 1086/1130/1148
            +f 1136/1180/1173 1087/1131/1094 1059/1103/1120
            +f 1060/1104/1121 1088/1132/1174 1061/1105/1122
            +f 1089/1133/1175 1062/1106/1149 1061/1105/1122
            +f 1088/1132/1174 1089/1133/1175 1061/1105/1122
            +f 1063/1107/1150 989/1033/1070 1062/1106/1149
            +f 1089/1133/1175 1063/1107/1150 1062/1106/1149
            +f 1259/1303/1176 1064/1108/965 1090/1134/1125
            +f 1140/1184/1177 1065/1109/1126 1091/1135/1071
            +f 1140/1184/1177 1092/1136/1178 1065/1109/1126
            +f 1092/1136/1178 1066/1110/1151 1065/1109/1126
            +f 1092/1136/1178 1093/1137/1179 1066/1110/1151
            +f 1093/1137/1179 1067/1111/1152 1066/1110/1151
            +f 1093/1137/1179 1094/1138/1180 1067/1111/1152
            +f 1095/1139/1181 1068/1112/1153 1067/1111/1152
            +f 1094/1138/1180 1095/1139/1181 1067/1111/1152
            +f 1096/1140/1182 1069/1113/1154 1068/1112/1153
            +f 1095/1139/1181 1096/1140/1182 1068/1112/1153
            +f 1097/1141/1183 1070/1114/1155 1069/1113/1154
            +f 1096/1140/1182 1097/1141/1183 1069/1113/1154
            +f 1098/1142/1184 1071/1115/1156 1070/1114/1155
            +f 1097/1141/1183 1098/1142/1184 1070/1114/1155
            +f 1099/1143/1185 1072/1116/1157 1071/1115/1156
            +f 1098/1142/1184 1099/1143/1185 1071/1115/1156
            +f 1100/1144/1186 1073/1117/1158 1072/1116/1157
            +f 1099/1143/1185 1100/1144/1186 1072/1116/1157
            +f 1101/1145/1187 1074/1118/1159 1073/1117/1158
            +f 1100/1144/1186 1101/1145/1187 1073/1117/1158
            +f 1102/1146/1188 1075/1119/1160 1074/1118/1159
            +f 1101/1145/1187 1102/1146/1188 1074/1118/1159
            +f 1103/1147/1189 1076/1120/1161 1075/1119/1160
            +f 1102/1146/1188 1103/1147/1189 1075/1119/1160
            +f 1104/1148/1190 1077/1121/1162 1076/1120/1161
            +f 1103/1147/1189 1104/1148/1190 1076/1120/1161
            +f 1105/1149/1191 1078/1122/1163 1077/1121/1162
            +f 1104/1148/1190 1105/1149/1191 1077/1121/1162
            +f 1106/1150/1192 1079/1123/1164 1078/1122/1165
            +f 1105/1149/1193 1106/1150/1192 1078/1122/1165
            +f 1107/1151/1194 1080/1124/1166 1079/1123/1167
            +f 1106/1150/1195 1107/1151/1194 1079/1123/1167
            +f 1108/1152/1196 1081/1125/1168 1080/1124/1166
            +f 1107/1151/1194 1108/1152/1196 1080/1124/1166
            +f 1109/1153/1197 1082/1126/1169 1081/1125/1168
            +f 1108/1152/1196 1109/1153/1197 1081/1125/1168
            +f 1110/1154/1198 1083/1127/1170 1082/1126/1169
            +f 1109/1153/1197 1110/1154/1198 1082/1126/1169
            +f 1133/1177/1199 1084/1128/1147 1083/1127/1170
            +f 1110/1154/1198 1133/1177/1199 1083/1127/1170
            +f 1133/1177/1199 1111/1155/1171 1084/1128/1147
            +f 1181/1225/1200 1009/1053/1063 1057/1101/1117
            +f 1111/1155/1171 1181/1225/1200 1057/1101/1117
            +f 1159/1203/1201 1085/1129/1118 1009/1053/1063
            +f 1181/1225/1200 1159/1203/1201 1009/1053/1063
            +f 1135/1179/1202 1086/1130/1148 1134/1178/1172
            +f 1135/1179/1202 1136/1180/1173 1086/1130/1148
            +f 1137/1181/1203 1087/1131/1094 1136/1180/1173
            +f 1137/1181/1203 1060/1104/1121 1087/1131/1094
            +f 1112/1156/1204 1088/1132/1174 1060/1104/1121
            +f 1113/1157/1205 1089/1133/1175 1088/1132/1174
            +f 1112/1156/1204 1113/1157/1205 1088/1132/1174
            +f 1113/1157/1205 1063/1107/1150 1089/1133/1175
            +f 1259/1303/1176 1090/1134/1125 1063/1107/1150
            +f 1234/1278/1206 1091/1135/1071 1064/1108/965
            +f 1234/1278/1206 1140/1184/1177 1091/1135/1071
            +f 1114/1158/1207 1092/1136/1178 1140/1184/1177
            +f 1114/1158/1207 1115/1159/1208 1092/1136/1178
            +f 1115/1159/1208 1093/1137/1179 1092/1136/1178
            +f 1116/1160/1209 1094/1138/1180 1093/1137/1179
            +f 1115/1159/1208 1116/1160/1209 1093/1137/1179
            +f 1117/1161/1210 1095/1139/1181 1094/1138/1180
            +f 1116/1160/1209 1117/1161/1210 1094/1138/1180
            +f 1118/1162/1211 1096/1140/1182 1095/1139/1181
            +f 1117/1161/1210 1118/1162/1211 1095/1139/1181
            +f 1119/1163/1212 1097/1141/1183 1096/1140/1182
            +f 1118/1162/1211 1119/1163/1212 1096/1140/1182
            +f 1120/1164/1213 1098/1142/1184 1097/1141/1183
            +f 1119/1163/1212 1120/1164/1213 1097/1141/1183
            +f 1121/1165/1214 1099/1143/1185 1098/1142/1184
            +f 1120/1164/1213 1121/1165/1214 1098/1142/1184
            +f 1122/1166/1215 1100/1144/1186 1099/1143/1185
            +f 1121/1165/1214 1122/1166/1215 1099/1143/1185
            +f 1123/1167/1216 1101/1145/1187 1100/1144/1186
            +f 1122/1166/1215 1123/1167/1216 1100/1144/1186
            +f 1124/1168/1217 1102/1146/1188 1101/1145/1187
            +f 1123/1167/1216 1124/1168/1217 1101/1145/1187
            +f 1125/1169/1218 1103/1147/1189 1102/1146/1188
            +f 1124/1168/1217 1125/1169/1218 1102/1146/1188
            +f 1126/1170/1219 1104/1148/1190 1103/1147/1189
            +f 1125/1169/1218 1126/1170/1219 1103/1147/1189
            +f 1127/1171/1220 1105/1149/1191 1104/1148/1190
            +f 1126/1170/1219 1127/1171/1220 1104/1148/1190
            +f 1128/1172/1221 1106/1150/1192 1105/1149/1193
            +f 1127/1171/1222 1128/1172/1221 1105/1149/1193
            +f 1129/1173/1223 1107/1151/1194 1106/1150/1195
            +f 1128/1172/1224 1129/1173/1223 1106/1150/1195
            +f 1130/1174/1225 1108/1152/1196 1107/1151/1194
            +f 1129/1173/1223 1130/1174/1225 1107/1151/1194
            +f 1131/1175/1226 1109/1153/1197 1108/1152/1196
            +f 1130/1174/1225 1131/1175/1226 1108/1152/1196
            +f 1132/1176/1227 1110/1154/1198 1109/1153/1197
            +f 1131/1175/1226 1132/1176/1227 1109/1153/1197
            +f 1132/1176/1227 1133/1177/1199 1110/1154/1198
            +f 1158/1202/1228 1111/1155/1171 1133/1177/1199
            +f 1159/1203/1201 1134/1178/1172 1085/1129/1118
            +f 1185/1229/1229 1060/1104/1121 1137/1181/1203
            +f 1138/1182/1230 1112/1156/1204 1060/1104/1121
            +f 1185/1229/1229 1138/1182/1230 1060/1104/1121
            +f 1139/1183/1231 1113/1157/1205 1112/1156/1204
            +f 1138/1182/1230 1139/1183/1231 1112/1156/1204
            +f 1139/1183/1231 1063/1107/1150 1113/1157/1205
            +f 1114/1158/1207 1141/1185/1232 1115/1159/1208
            +f 1141/1185/1232 1142/1186/1233 1115/1159/1208
            +f 1142/1186/1233 1116/1160/1209 1115/1159/1208
            +f 1143/1187/1234 1117/1161/1210 1116/1160/1209
            +f 1142/1186/1233 1143/1187/1234 1116/1160/1209
            +f 1144/1188/1235 1118/1162/1211 1117/1161/1210
            +f 1143/1187/1234 1144/1188/1235 1117/1161/1210
            +f 1145/1189/1236 1119/1163/1212 1118/1162/1211
            +f 1144/1188/1235 1145/1189/1236 1118/1162/1211
            +f 1146/1190/1237 1120/1164/1213 1119/1163/1212
            +f 1145/1189/1236 1146/1190/1237 1119/1163/1212
            +f 1147/1191/1238 1121/1165/1214 1120/1164/1213
            +f 1146/1190/1237 1147/1191/1238 1120/1164/1213
            +f 1148/1192/1239 1122/1166/1215 1121/1165/1214
            +f 1147/1191/1238 1148/1192/1239 1121/1165/1214
            +f 1149/1193/1240 1123/1167/1216 1122/1166/1215
            +f 1148/1192/1239 1149/1193/1240 1122/1166/1215
            +f 1150/1194/1241 1124/1168/1217 1123/1167/1216
            +f 1149/1193/1240 1150/1194/1241 1123/1167/1216
            +f 1151/1195/1242 1125/1169/1218 1124/1168/1217
            +f 1150/1194/1241 1151/1195/1242 1124/1168/1217
            +f 1152/1196/1243 1126/1170/1219 1125/1169/1218
            +f 1151/1195/1242 1152/1196/1243 1125/1169/1218
            +f 1153/1197/1244 1127/1171/1220 1126/1170/1219
            +f 1152/1196/1243 1153/1197/1244 1126/1170/1219
            +f 1154/1198/1245 1128/1172/1221 1127/1171/1222
            +f 1153/1197/1246 1154/1198/1245 1127/1171/1222
            +f 1154/1198/1247 1129/1173/1223 1128/1172/1224
            +f 1155/1199/1248 1130/1174/1225 1129/1173/1223
            +f 1154/1198/1247 1155/1199/1248 1129/1173/1223
            +f 1156/1200/1249 1131/1175/1226 1130/1174/1225
            +f 1155/1199/1248 1156/1200/1249 1130/1174/1225
            +f 1157/1201/1250 1132/1176/1227 1131/1175/1226
            +f 1156/1200/1249 1157/1201/1250 1131/1175/1226
            +f 1180/1224/1251 1133/1177/1199 1132/1176/1227
            +f 1157/1201/1250 1180/1224/1251 1132/1176/1227
            +f 1180/1224/1251 1158/1202/1228 1133/1177/1199
            +f 1158/1202/1228 1181/1225/1200 1111/1155/1171
            +f 1182/1226/1252 1134/1178/1172 1159/1203/1201
            +f 1183/1227/1253 1135/1179/1202 1134/1178/1172
            +f 1182/1226/1252 1183/1227/1253 1134/1178/1172
            +f 1184/1228/1254 1136/1180/1173 1135/1179/1202
            +f 1183/1227/1253 1184/1228/1254 1135/1179/1202
            +f 1232/1276/1255 1137/1181/1203 1136/1180/1173
            +f 1184/1228/1254 1232/1276/1255 1136/1180/1173
            +f 1232/1276/1255 1185/1229/1229 1137/1181/1203
            +f 1160/1204/1256 1138/1182/1230 1185/1229/1229
            +f 1161/1205/1257 1139/1183/1231 1138/1182/1230
            +f 1160/1204/1256 1161/1205/1257 1138/1182/1230
            +f 1161/1205/1257 1063/1107/1150 1139/1183/1231
            +f 1234/1278/1206 1064/1108/965 1259/1303/1176
            +f 1162/1206/1258 1114/1158/1207 1140/1184/1177
            +f 1234/1278/1206 1162/1206/1258 1140/1184/1177
            +f 1163/1207/1259 1141/1185/1232 1114/1158/1207
            +f 1162/1206/1258 1163/1207/1259 1114/1158/1207
            +f 1164/1208/1260 1142/1186/1233 1141/1185/1232
            +f 1163/1207/1259 1164/1208/1260 1141/1185/1232
            +f 1165/1209/1261 1143/1187/1234 1142/1186/1233
            +f 1164/1208/1260 1165/1209/1261 1142/1186/1233
            +f 1166/1210/1262 1144/1188/1235 1143/1187/1234
            +f 1165/1209/1261 1166/1210/1262 1143/1187/1234
            +f 1167/1211/1263 1145/1189/1236 1144/1188/1235
            +f 1166/1210/1262 1167/1211/1263 1144/1188/1235
            +f 1168/1212/1264 1146/1190/1237 1145/1189/1236
            +f 1167/1211/1263 1168/1212/1264 1145/1189/1236
            +f 1169/1213/1265 1147/1191/1238 1146/1190/1237
            +f 1168/1212/1264 1169/1213/1265 1146/1190/1237
            +f 1170/1214/1266 1148/1192/1239 1147/1191/1238
            +f 1169/1213/1265 1170/1214/1266 1147/1191/1238
            +f 1171/1215/1267 1149/1193/1240 1148/1192/1239
            +f 1170/1214/1266 1171/1215/1267 1148/1192/1239
            +f 1172/1216/1268 1150/1194/1241 1149/1193/1240
            +f 1171/1215/1267 1172/1216/1268 1149/1193/1240
            +f 1173/1217/1269 1151/1195/1242 1150/1194/1241
            +f 1172/1216/1268 1173/1217/1269 1150/1194/1241
            +f 1174/1218/1270 1152/1196/1243 1151/1195/1242
            +f 1173/1217/1269 1174/1218/1270 1151/1195/1242
            +f 1175/1219/1271 1153/1197/1244 1152/1196/1243
            +f 1174/1218/1270 1175/1219/1271 1152/1196/1243
            +f 1176/1220/1272 1154/1198/1245 1153/1197/1246
            +f 1175/1219/1273 1176/1220/1272 1153/1197/1246
            +f 1177/1221/1274 1155/1199/1248 1154/1198/1247
            +f 1176/1220/1275 1177/1221/1274 1154/1198/1247
            +f 1178/1222/1276 1156/1200/1249 1155/1199/1248
            +f 1177/1221/1274 1178/1222/1276 1155/1199/1248
            +f 1179/1223/1277 1157/1201/1250 1156/1200/1249
            +f 1178/1222/1276 1179/1223/1277 1156/1200/1249
            +f 1179/1223/1277 1180/1224/1251 1157/1201/1250
            +f 1206/1250/1278 1158/1202/1228 1180/1224/1251
            +f 1255/1299/1279 1159/1203/1201 1181/1225/1200
            +f 1255/1299/1279 1182/1226/1252 1159/1203/1201
            +f 1186/1230/1280 1160/1204/1256 1185/1229/1229
            +f 1207/1251/1281 1186/1230/1280 1185/1229/1229
            +f 1187/1231/1282 1161/1205/1257 1160/1204/1256
            +f 1186/1230/1280 1187/1231/1282 1160/1204/1256
            +f 1187/1231/1282 1063/1107/1150 1161/1205/1257
            +f 1188/1232/1283 1259/1303/1176 1063/1107/1150
            +f 1209/1253/1284 1162/1206/1258 1234/1278/1206
            +f 1209/1253/1284 1189/1233/1285 1162/1206/1258
            +f 1189/1233/1285 1163/1207/1259 1162/1206/1258
            +f 1189/1233/1285 1164/1208/1260 1163/1207/1259
            +f 1189/1233/1285 1190/1234/1286 1164/1208/1260
            +f 1191/1235/1287 1165/1209/1261 1164/1208/1260
            +f 1190/1234/1286 1191/1235/1287 1164/1208/1260
            +f 1192/1236/1288 1166/1210/1262 1165/1209/1261
            +f 1191/1235/1287 1192/1236/1288 1165/1209/1261
            +f 1193/1237/1289 1167/1211/1263 1166/1210/1262
            +f 1192/1236/1288 1193/1237/1289 1166/1210/1262
            +f 1194/1238/1290 1168/1212/1264 1167/1211/1263
            +f 1193/1237/1289 1194/1238/1290 1167/1211/1263
            +f 1195/1239/1291 1169/1213/1265 1168/1212/1264
            +f 1194/1238/1290 1195/1239/1291 1168/1212/1264
            +f 1196/1240/1292 1170/1214/1266 1169/1213/1265
            +f 1195/1239/1291 1196/1240/1292 1169/1213/1265
            +f 1197/1241/1293 1171/1215/1267 1170/1214/1266
            +f 1196/1240/1292 1197/1241/1293 1170/1214/1266
            +f 1198/1242/1294 1172/1216/1268 1171/1215/1267
            +f 1197/1241/1293 1198/1242/1294 1171/1215/1267
            +f 1199/1243/1295 1173/1217/1269 1172/1216/1268
            +f 1198/1242/1294 1199/1243/1295 1172/1216/1268
            +f 1200/1244/1296 1174/1218/1270 1173/1217/1269
            +f 1199/1243/1295 1200/1244/1296 1173/1217/1269
            +f 1201/1245/1297 1175/1219/1271 1174/1218/1270
            +f 1200/1244/1296 1201/1245/1297 1174/1218/1270
            +f 1202/1246/1298 1176/1220/1272 1175/1219/1273
            +f 1201/1245/1299 1202/1246/1298 1175/1219/1273
            +f 1203/1247/1300 1177/1221/1274 1176/1220/1275
            +f 1202/1246/1301 1203/1247/1300 1176/1220/1275
            +f 1204/1248/1302 1178/1222/1276 1177/1221/1274
            +f 1203/1247/1300 1204/1248/1302 1177/1221/1274
            +f 1205/1249/1303 1179/1223/1277 1178/1222/1276
            +f 1204/1248/1302 1205/1249/1303 1178/1222/1276
            +f 1228/1272/1304 1180/1224/1251 1179/1223/1277
            +f 1205/1249/1303 1228/1272/1304 1179/1223/1277
            +f 1228/1272/1304 1206/1250/1278 1180/1224/1251
            +f 1206/1250/1278 1181/1225/1200 1158/1202/1228
            +f 1206/1250/1278 1255/1299/1279 1181/1225/1200
            +f 1229/1273/1305 1182/1226/1252 1255/1299/1279
            +f 1230/1274/1306 1183/1227/1253 1182/1226/1252
            +f 1229/1273/1305 1230/1274/1306 1182/1226/1252
            +f 1231/1275/1307 1184/1228/1254 1183/1227/1253
            +f 1230/1274/1306 1231/1275/1307 1183/1227/1253
            +f 1231/1275/1307 1232/1276/1255 1184/1228/1254
            +f 1282/1326/1308 1185/1229/1229 1232/1276/1255
            +f 1282/1326/1308 1256/1300/1309 1185/1229/1229
            +f 1256/1300/1309 1207/1251/1281 1185/1229/1229
            +f 1208/1252/1310 1187/1231/1282 1186/1230/1280
            +f 1207/1251/1281 1208/1252/1310 1186/1230/1280
            +f 1188/1232/1283 1063/1107/1150 1187/1231/1282
            +f 1208/1252/1310 1188/1232/1283 1187/1231/1282
            +f 1259/1303/1176 1409/1453/1311 1234/1278/1206
            +f 1286/1330/1312 1209/1253/1284 1234/1278/1206
            +f 1210/1254/1313 1189/1233/1285 1209/1253/1284
            +f 1211/1255/1314 1190/1234/1286 1189/1233/1285
            +f 1210/1254/1313 1211/1255/1314 1189/1233/1285
            +f 1212/1256/1315 1191/1235/1287 1190/1234/1286
            +f 1211/1255/1314 1212/1256/1315 1190/1234/1286
            +f 1213/1257/1316 1192/1236/1288 1191/1235/1287
            +f 1212/1256/1315 1213/1257/1316 1191/1235/1287
            +f 1214/1258/1317 1193/1237/1289 1192/1236/1288
            +f 1213/1257/1316 1214/1258/1317 1192/1236/1288
            +f 1215/1259/1318 1194/1238/1290 1193/1237/1289
            +f 1214/1258/1317 1215/1259/1318 1193/1237/1289
            +f 1216/1260/1319 1195/1239/1291 1194/1238/1290
            +f 1215/1259/1318 1216/1260/1319 1194/1238/1290
            +f 1217/1261/1320 1196/1240/1292 1195/1239/1291
            +f 1216/1260/1319 1217/1261/1320 1195/1239/1291
            +f 1218/1262/1321 1197/1241/1293 1196/1240/1292
            +f 1217/1261/1320 1218/1262/1321 1196/1240/1292
            +f 1219/1263/1322 1198/1242/1294 1197/1241/1293
            +f 1218/1262/1321 1219/1263/1322 1197/1241/1293
            +f 1220/1264/1323 1199/1243/1295 1198/1242/1294
            +f 1219/1263/1322 1220/1264/1323 1198/1242/1294
            +f 1221/1265/1324 1200/1244/1296 1199/1243/1295
            +f 1220/1264/1323 1221/1265/1324 1199/1243/1295
            +f 1222/1266/1325 1201/1245/1297 1200/1244/1296
            +f 1221/1265/1324 1222/1266/1325 1200/1244/1296
            +f 1223/1267/1326 1202/1246/1298 1201/1245/1299
            +f 1222/1266/1327 1223/1267/1326 1201/1245/1299
            +f 1223/1267/1328 1224/1268/1329 1202/1246/1301
            +f 1225/1269/1330 1203/1247/1300 1202/1246/1301
            +f 1224/1268/1329 1225/1269/1330 1202/1246/1301
            +f 1226/1270/1331 1204/1248/1302 1203/1247/1300
            +f 1225/1269/1330 1226/1270/1331 1203/1247/1300
            +f 1227/1271/1332 1205/1249/1303 1204/1248/1302
            +f 1226/1270/1331 1227/1271/1332 1204/1248/1302
            +f 1227/1271/1332 1228/1272/1304 1205/1249/1303
            +f 1254/1298/1333 1206/1250/1278 1228/1272/1304
            +f 1233/1277/1334 1208/1252/1310 1207/1251/1281
            +f 1256/1300/1309 1233/1277/1334 1207/1251/1281
            +f 1233/1277/1334 1188/1232/1283 1208/1252/1310
            +f 1287/1331/1335 1209/1253/1284 1286/1330/1312
            +f 1235/1279/1336 1210/1254/1313 1209/1253/1284
            +f 1287/1331/1335 1235/1279/1336 1209/1253/1284
            +f 1235/1279/1336 1211/1255/1314 1210/1254/1313
            +f 1235/1279/1336 1236/1280/1337 1211/1255/1314
            +f 1237/1281/1338 1212/1256/1315 1211/1255/1314
            +f 1236/1280/1337 1237/1281/1338 1211/1255/1314
            +f 1238/1282/1339 1213/1257/1316 1212/1256/1315
            +f 1237/1281/1338 1238/1282/1339 1212/1256/1315
            +f 1239/1283/1340 1214/1258/1317 1213/1257/1316
            +f 1238/1282/1339 1239/1283/1340 1213/1257/1316
            +f 1240/1284/1341 1215/1259/1318 1214/1258/1317
            +f 1239/1283/1340 1240/1284/1341 1214/1258/1317
            +f 1241/1285/1342 1216/1260/1319 1215/1259/1318
            +f 1240/1284/1341 1241/1285/1342 1215/1259/1318
            +f 1242/1286/1343 1217/1261/1320 1216/1260/1319
            +f 1241/1285/1342 1242/1286/1343 1216/1260/1319
            +f 1243/1287/1344 1218/1262/1321 1217/1261/1320
            +f 1242/1286/1343 1243/1287/1344 1217/1261/1320
            +f 1244/1288/1345 1219/1263/1322 1218/1262/1321
            +f 1243/1287/1344 1244/1288/1345 1218/1262/1321
            +f 1245/1289/1346 1220/1264/1323 1219/1263/1322
            +f 1244/1288/1345 1245/1289/1346 1219/1263/1322
            +f 1246/1290/1347 1221/1265/1324 1220/1264/1323
            +f 1245/1289/1346 1246/1290/1347 1220/1264/1323
            +f 1247/1291/1348 1222/1266/1325 1221/1265/1324
            +f 1246/1290/1347 1247/1291/1348 1221/1265/1324
            +f 1248/1292/1349 1223/1267/1326 1222/1266/1327
            +f 1247/1291/1350 1248/1292/1349 1222/1266/1327
            +f 1249/1293/1351 1224/1268/1329 1223/1267/1328
            +f 1248/1292/1352 1249/1293/1351 1223/1267/1328
            +f 1250/1294/1353 1225/1269/1330 1224/1268/1329
            +f 1249/1293/1351 1250/1294/1353 1224/1268/1329
            +f 1251/1295/1354 1226/1270/1331 1225/1269/1330
            +f 1250/1294/1353 1251/1295/1354 1225/1269/1330
            +f 1252/1296/1355 1227/1271/1332 1226/1270/1331
            +f 1251/1295/1354 1252/1296/1355 1226/1270/1331
            +f 1253/1297/1356 1228/1272/1304 1227/1271/1332
            +f 1252/1296/1355 1253/1297/1356 1227/1271/1332
            +f 1253/1297/1356 1254/1298/1333 1228/1272/1304
            +f 1278/1322/1357 1229/1273/1305 1255/1299/1279
            +f 1279/1323/1358 1230/1274/1306 1229/1273/1305
            +f 1278/1322/1357 1279/1323/1358 1229/1273/1305
            +f 1280/1324/1359 1231/1275/1307 1230/1274/1306
            +f 1279/1323/1358 1280/1324/1359 1230/1274/1306
            +f 1281/1325/1360 1232/1276/1255 1231/1275/1307
            +f 1280/1324/1359 1281/1325/1360 1231/1275/1307
            +f 1281/1325/1360 1282/1326/1308 1232/1276/1255
            +f 1330/1374/1361 1257/1301/1362 1256/1300/1309
            +f 1258/1302/1363 1233/1277/1334 1256/1300/1309
            +f 1257/1301/1362 1258/1302/1363 1256/1300/1309
            +f 1258/1302/1363 1188/1232/1283 1233/1277/1334
            +f 1333/1377/1364 1234/1278/1206 1409/1453/1311
            +f 1333/1377/1364 1286/1330/1312 1234/1278/1206
            +f 1287/1331/1335 1260/1304/1365 1235/1279/1336
            +f 1260/1304/1365 1261/1305/1366 1235/1279/1336
            +f 1261/1305/1366 1236/1280/1337 1235/1279/1336
            +f 1262/1306/1367 1237/1281/1338 1236/1280/1337
            +f 1261/1305/1366 1262/1306/1367 1236/1280/1337
            +f 1263/1307/1368 1238/1282/1339 1237/1281/1338
            +f 1262/1306/1367 1263/1307/1368 1237/1281/1338
            +f 1264/1308/1369 1239/1283/1340 1238/1282/1339
            +f 1263/1307/1368 1264/1308/1369 1238/1282/1339
            +f 1265/1309/1370 1240/1284/1341 1239/1283/1340
            +f 1264/1308/1369 1265/1309/1370 1239/1283/1340
            +f 1266/1310/1371 1241/1285/1342 1240/1284/1341
            +f 1265/1309/1370 1266/1310/1371 1240/1284/1341
            +f 1267/1311/1372 1242/1286/1343 1241/1285/1342
            +f 1266/1310/1371 1267/1311/1372 1241/1285/1342
            +f 1268/1312/1373 1243/1287/1344 1242/1286/1343
            +f 1267/1311/1372 1268/1312/1373 1242/1286/1343
            +f 1269/1313/1374 1244/1288/1345 1243/1287/1344
            +f 1268/1312/1373 1269/1313/1374 1243/1287/1344
            +f 1270/1314/1375 1245/1289/1346 1244/1288/1345
            +f 1269/1313/1374 1270/1314/1375 1244/1288/1345
            +f 1271/1315/1376 1246/1290/1347 1245/1289/1346
            +f 1270/1314/1375 1271/1315/1376 1245/1289/1346
            +f 1272/1316/1377 1247/1291/1348 1246/1290/1347
            +f 1271/1315/1376 1272/1316/1377 1246/1290/1347
            +f 1273/1317/1378 1248/1292/1349 1247/1291/1350
            +f 1272/1316/1379 1273/1317/1378 1247/1291/1350
            +f 1274/1318/1380 1249/1293/1351 1248/1292/1352
            +f 1273/1317/1381 1274/1318/1380 1248/1292/1352
            +f 1275/1319/1382 1250/1294/1353 1249/1293/1351
            +f 1274/1318/1380 1275/1319/1382 1249/1293/1351
            +f 1276/1320/1383 1251/1295/1354 1250/1294/1353
            +f 1275/1319/1382 1276/1320/1383 1250/1294/1353
            +f 1277/1321/1384 1252/1296/1355 1251/1295/1354
            +f 1276/1320/1383 1277/1321/1384 1251/1295/1354
            +f 1305/1349/1385 1253/1297/1356 1252/1296/1355
            +f 1277/1321/1384 1305/1349/1385 1252/1296/1355
            +f 1306/1350/1386 1254/1298/1333 1253/1297/1356
            +f 1305/1349/1385 1306/1350/1386 1253/1297/1356
            +f 1355/1399/1387 1255/1299/1279 1206/1250/1278
            +f 1254/1298/1333 1355/1399/1387 1206/1250/1278
            +f 1355/1399/1387 1278/1322/1357 1255/1299/1279
            +f 1330/1374/1361 1256/1300/1309 1282/1326/1308
            +f 1283/1327/1388 1257/1301/1362 1330/1374/1361
            +f 1284/1328/1389 1258/1302/1363 1257/1301/1362
            +f 1283/1327/1388 1284/1328/1389 1257/1301/1362
            +f 1284/1328/1389 1188/1232/1283 1258/1302/1363
            +f 1309/1353/1390 1259/1303/1176 1188/1232/1283
            +f 1285/1329/1391 1309/1353/1390 1188/1232/1283
            +f 1309/1353/1390 1409/1453/1311 1259/1303/1176
            +f 1288/1332/1392 1260/1304/1365 1287/1331/1335
            +f 1288/1332/1392 1261/1305/1366 1260/1304/1365
            +f 1288/1332/1392 1289/1333/1393 1261/1305/1366
            +f 1290/1334/1394 1262/1306/1367 1261/1305/1366
            +f 1289/1333/1393 1290/1334/1394 1261/1305/1366
            +f 1291/1335/1395 1263/1307/1368 1262/1306/1367
            +f 1290/1334/1394 1291/1335/1395 1262/1306/1367
            +f 1292/1336/1396 1264/1308/1369 1263/1307/1368
            +f 1291/1335/1395 1292/1336/1396 1263/1307/1368
            +f 1293/1337/1397 1265/1309/1370 1264/1308/1369
            +f 1292/1336/1396 1293/1337/1397 1264/1308/1369
            +f 1294/1338/1398 1266/1310/1371 1265/1309/1370
            +f 1293/1337/1397 1294/1338/1398 1265/1309/1370
            +f 1295/1339/1399 1267/1311/1372 1266/1310/1371
            +f 1294/1338/1398 1295/1339/1399 1266/1310/1371
            +f 1296/1340/1400 1268/1312/1373 1267/1311/1372
            +f 1295/1339/1399 1296/1340/1400 1267/1311/1372
            +f 1297/1341/1401 1269/1313/1374 1268/1312/1373
            +f 1296/1340/1400 1297/1341/1401 1268/1312/1373
            +f 1298/1342/1402 1270/1314/1375 1269/1313/1374
            +f 1297/1341/1401 1298/1342/1402 1269/1313/1374
            +f 1299/1343/1403 1271/1315/1376 1270/1314/1375
            +f 1298/1342/1402 1299/1343/1403 1270/1314/1375
            +f 1300/1344/1404 1272/1316/1377 1271/1315/1376
            +f 1299/1343/1403 1300/1344/1404 1271/1315/1376
            +f 1301/1345/1405 1273/1317/1378 1272/1316/1379
            +f 1300/1344/1406 1301/1345/1405 1272/1316/1379
            +f 1301/1345/1407 1274/1318/1380 1273/1317/1381
            +f 1302/1346/1408 1275/1319/1382 1274/1318/1380
            +f 1301/1345/1407 1302/1346/1408 1274/1318/1380
            +f 1303/1347/1409 1276/1320/1383 1275/1319/1382
            +f 1302/1346/1408 1303/1347/1409 1275/1319/1382
            +f 1304/1348/1410 1277/1321/1384 1276/1320/1383
            +f 1303/1347/1409 1304/1348/1410 1276/1320/1383
            +f 1304/1348/1410 1305/1349/1385 1277/1321/1384
            +f 1327/1371/1411 1278/1322/1357 1355/1399/1387
            +f 1328/1372/1412 1279/1323/1358 1278/1322/1357
            +f 1327/1371/1411 1328/1372/1412 1278/1322/1357
            +f 1329/1373/1413 1280/1324/1359 1279/1323/1358
            +f 1328/1372/1412 1329/1373/1413 1279/1323/1358
            +f 1382/1426/1414 1281/1325/1360 1280/1324/1359
            +f 1329/1373/1413 1382/1426/1414 1280/1324/1359
            +f 1330/1374/1361 1282/1326/1308 1281/1325/1360
            +f 1382/1426/1414 1330/1374/1361 1281/1325/1360
            +f 1307/1351/1415 1283/1327/1388 1330/1374/1361
            +f 1331/1375/1416 1307/1351/1415 1330/1374/1361
            +f 1308/1352/1417 1284/1328/1389 1283/1327/1388
            +f 1307/1351/1415 1308/1352/1418 1283/1327/1388
            +f 1285/1329/1391 1188/1232/1283 1284/1328/1389
            +f 1308/1352/1417 1285/1329/1391 1284/1328/1389
            +f 1334/1378/1419 1287/1331/1335 1286/1330/1312
            +f 1333/1377/1364 1334/1378/1419 1286/1330/1312
            +f 1310/1354/1420 1288/1332/1392 1287/1331/1335
            +f 1334/1378/1419 1310/1354/1420 1287/1331/1335
            +f 1311/1355/1421 1289/1333/1393 1288/1332/1392
            +f 1310/1354/1420 1311/1355/1421 1288/1332/1392
            +f 1312/1356/1422 1290/1334/1394 1289/1333/1393
            +f 1311/1355/1421 1312/1356/1422 1289/1333/1393
            +f 1313/1357/1423 1291/1335/1395 1290/1334/1394
            +f 1312/1356/1422 1313/1357/1423 1290/1334/1394
            +f 1314/1358/1424 1292/1336/1396 1291/1335/1395
            +f 1313/1357/1423 1314/1358/1424 1291/1335/1395
            +f 1315/1359/1425 1293/1337/1397 1292/1336/1396
            +f 1314/1358/1424 1315/1359/1425 1292/1336/1396
            +f 1316/1360/1426 1294/1338/1398 1293/1337/1397
            +f 1315/1359/1425 1316/1360/1426 1293/1337/1397
            +f 1317/1361/1427 1295/1339/1399 1294/1338/1398
            +f 1316/1360/1426 1317/1361/1427 1294/1338/1398
            +f 1318/1362/1428 1296/1340/1400 1295/1339/1399
            +f 1317/1361/1427 1318/1362/1428 1295/1339/1399
            +f 1319/1363/1429 1297/1341/1401 1296/1340/1400
            +f 1318/1362/1428 1319/1363/1429 1296/1340/1400
            +f 1320/1364/1430 1298/1342/1402 1297/1341/1401
            +f 1319/1363/1429 1320/1364/1430 1297/1341/1401
            +f 1321/1365/1431 1299/1343/1403 1298/1342/1402
            +f 1320/1364/1430 1321/1365/1431 1298/1342/1402
            +f 1322/1366/1432 1300/1344/1404 1299/1343/1403
            +f 1321/1365/1431 1322/1366/1432 1299/1343/1403
            +f 1323/1367/1433 1301/1345/1405 1300/1344/1406
            +f 1322/1366/1434 1323/1367/1433 1300/1344/1406
            +f 1324/1368/1435 1302/1346/1408 1301/1345/1407
            +f 1323/1367/1436 1324/1368/1435 1301/1345/1407
            +f 1325/1369/1437 1303/1347/1409 1302/1346/1408
            +f 1324/1368/1435 1325/1369/1437 1302/1346/1408
            +f 1326/1370/1438 1304/1348/1410 1303/1347/1409
            +f 1325/1369/1437 1326/1370/1438 1303/1347/1409
            +f 1353/1397/1439 1305/1349/1385 1304/1348/1410
            +f 1326/1370/1438 1353/1397/1439 1304/1348/1410
            +f 1354/1398/1440 1306/1350/1386 1305/1349/1385
            +f 1353/1397/1439 1354/1398/1440 1305/1349/1385
            +f 1306/1350/1386 1355/1399/1387 1254/1298/1333
            +f 1356/1400/1441 1331/1375/1416 1330/1374/1361
            +f 1332/1376/1442 1308/1352/1418 1307/1351/1415
            +f 1331/1375/1416 1332/1376/1442 1307/1351/1415
            +f 1332/1376/1442 1285/1329/1391 1308/1352/1418
            +f 1385/1429/1443 1309/1353/1390 1285/1329/1391
            +f 1385/1429/1443 1409/1453/1311 1309/1353/1390
            +f 1335/1379/1444 1310/1354/1420 1334/1378/1419
            +f 1335/1379/1444 1336/1380/1445 1310/1354/1420
            +f 1336/1380/1445 1311/1355/1421 1310/1354/1420
            +f 1337/1381/1446 1312/1356/1422 1311/1355/1421
            +f 1336/1380/1445 1337/1381/1446 1311/1355/1421
            +f 1338/1382/1447 1313/1357/1423 1312/1356/1422
            +f 1337/1381/1446 1338/1382/1447 1312/1356/1422
            +f 1339/1383/1448 1314/1358/1424 1313/1357/1423
            +f 1338/1382/1447 1339/1383/1448 1313/1357/1423
            +f 1340/1384/1449 1315/1359/1425 1314/1358/1424
            +f 1339/1383/1448 1340/1384/1449 1314/1358/1424
            +f 1341/1385/1450 1316/1360/1426 1315/1359/1425
            +f 1340/1384/1449 1341/1385/1450 1315/1359/1425
            +f 1342/1386/1451 1317/1361/1427 1316/1360/1426
            +f 1341/1385/1450 1342/1386/1451 1316/1360/1426
            +f 1343/1387/1452 1318/1362/1428 1317/1361/1427
            +f 1342/1386/1451 1343/1387/1452 1317/1361/1427
            +f 1344/1388/1453 1319/1363/1429 1318/1362/1428
            +f 1343/1387/1452 1344/1388/1453 1318/1362/1428
            +f 1345/1389/1454 1320/1364/1430 1319/1363/1429
            +f 1344/1388/1453 1345/1389/1454 1319/1363/1429
            +f 1346/1390/1455 1321/1365/1431 1320/1364/1430
            +f 1345/1389/1454 1346/1390/1455 1320/1364/1430
            +f 1347/1391/1456 1322/1366/1432 1321/1365/1431
            +f 1346/1390/1455 1347/1391/1456 1321/1365/1431
            +f 1348/1392/1457 1323/1367/1433 1322/1366/1434
            +f 1347/1391/1458 1348/1392/1457 1322/1366/1434
            +f 1348/1392/1459 1349/1393/1460 1323/1367/1436
            +f 1350/1394/1461 1324/1368/1435 1323/1367/1436
            +f 1349/1393/1460 1350/1394/1461 1323/1367/1436
            +f 1351/1395/1462 1325/1369/1437 1324/1368/1435
            +f 1350/1394/1461 1351/1395/1462 1324/1368/1435
            +f 1352/1396/1463 1326/1370/1438 1325/1369/1437
            +f 1351/1395/1462 1352/1396/1463 1325/1369/1437
            +f 1352/1396/1463 1353/1397/1439 1326/1370/1438
            +f 1379/1423/1464 1327/1371/1411 1355/1399/1387
            +f 1380/1424/1465 1328/1372/1412 1327/1371/1411
            +f 1379/1423/1464 1380/1424/1465 1327/1371/1411
            +f 1381/1425/1466 1329/1373/1413 1328/1372/1412
            +f 1380/1424/1465 1381/1425/1466 1328/1372/1412
            +f 1381/1425/1466 1382/1426/1414 1329/1373/1413
            +f 1356/1400/1441 1330/1374/1361 1382/1426/1414
            +f 1356/1400/1441 1357/1401/1467 1331/1375/1416
            +f 1358/1402/1468 1332/1376/1442 1331/1375/1416
            +f 1357/1401/1467 1358/1402/1469 1331/1375/1416
            +f 1358/1402/1468 1285/1329/1391 1332/1376/1442
            +f 1359/1403/1470 1385/1429/1443 1285/1329/1391
            +f 1436/1480/1471 1333/1377/1364 1409/1453/1311
            +f 1410/1454/1472 1334/1378/1419 1333/1377/1364
            +f 1436/1480/1471 1410/1454/1472 1333/1377/1364
            +f 1360/1404/1473 1335/1379/1444 1334/1378/1419
            +f 1410/1454/1472 1360/1404/1473 1334/1378/1419
            +f 1360/1404/1473 1336/1380/1445 1335/1379/1444
            +f 1360/1404/1473 1361/1405/1474 1336/1380/1445
            +f 1362/1406/1475 1337/1381/1446 1336/1380/1445
            +f 1361/1405/1474 1362/1406/1475 1336/1380/1445
            +f 1363/1407/1476 1338/1382/1447 1337/1381/1446
            +f 1362/1406/1475 1363/1407/1476 1337/1381/1446
            +f 1364/1408/1477 1339/1383/1448 1338/1382/1447
            +f 1363/1407/1476 1364/1408/1477 1338/1382/1447
            +f 1365/1409/1478 1340/1384/1449 1339/1383/1448
            +f 1364/1408/1477 1365/1409/1478 1339/1383/1448
            +f 1366/1410/1479 1341/1385/1450 1340/1384/1449
            +f 1365/1409/1478 1366/1410/1479 1340/1384/1449
            +f 1367/1411/1480 1342/1386/1451 1341/1385/1450
            +f 1366/1410/1479 1367/1411/1480 1341/1385/1450
            +f 1368/1412/1481 1343/1387/1452 1342/1386/1451
            +f 1367/1411/1480 1368/1412/1481 1342/1386/1451
            +f 1369/1413/1482 1344/1388/1453 1343/1387/1452
            +f 1368/1412/1481 1369/1413/1482 1343/1387/1452
            +f 1370/1414/1483 1345/1389/1454 1344/1388/1453
            +f 1369/1413/1482 1370/1414/1483 1344/1388/1453
            +f 1371/1415/1484 1346/1390/1455 1345/1389/1454
            +f 1370/1414/1483 1371/1415/1484 1345/1389/1454
            +f 1372/1416/1485 1347/1391/1456 1346/1390/1455
            +f 1371/1415/1484 1372/1416/1485 1346/1390/1455
            +f 1373/1417/1486 1348/1392/1457 1347/1391/1458
            +f 1372/1416/1487 1373/1417/1486 1347/1391/1458
            +f 1374/1418/1488 1349/1393/1460 1348/1392/1459
            +f 1373/1417/1489 1374/1418/1488 1348/1392/1459
            +f 1375/1419/1490 1350/1394/1461 1349/1393/1460
            +f 1374/1418/1488 1375/1419/1490 1349/1393/1460
            +f 1376/1420/1491 1351/1395/1462 1350/1394/1461
            +f 1375/1419/1490 1376/1420/1491 1350/1394/1461
            +f 1377/1421/1492 1352/1396/1463 1351/1395/1462
            +f 1376/1420/1491 1377/1421/1492 1351/1395/1462
            +f 1378/1422/1493 1353/1397/1439 1352/1396/1463
            +f 1377/1421/1492 1378/1422/1493 1352/1396/1463
            +f 1404/1448/1494 1354/1398/1440 1353/1397/1439
            +f 1378/1422/1493 1404/1448/1494 1353/1397/1439
            +f 1455/1499/1495 1306/1350/1386 1354/1398/1440
            +f 1405/1449/1496 1355/1399/1387 1306/1350/1386
            +f 1455/1499/1495 1405/1449/1496 1306/1350/1386
            +f 1405/1449/1496 1379/1423/1464 1355/1399/1387
            +f 1383/1427/1497 1357/1401/1467 1356/1400/1441
            +f 1384/1428/1498 1358/1402/1469 1357/1401/1467
            +f 1383/1427/1497 1384/1428/1498 1357/1401/1467
            +f 1359/1403/1470 1285/1329/1391 1358/1402/1468
            +f 1384/1428/1498 1359/1403/1470 1358/1402/1469
            +f 1711/1787/1499 1436/1480/1471 1409/1453/1311
            +f 1386/1430/1500 1360/1404/1473 1410/1454/1472
            +f 1386/1430/1500 1387/1431/1501 1360/1404/1473
            +f 1387/1431/1501 1361/1405/1474 1360/1404/1473
            +f 1388/1432/1502 1362/1406/1475 1361/1405/1474
            +f 1387/1431/1501 1388/1432/1502 1361/1405/1474
            +f 1389/1433/1503 1363/1407/1476 1362/1406/1475
            +f 1388/1432/1502 1389/1433/1503 1362/1406/1475
            +f 1390/1434/1504 1364/1408/1477 1363/1407/1476
            +f 1389/1433/1503 1390/1434/1504 1363/1407/1476
            +f 1391/1435/1505 1365/1409/1478 1364/1408/1477
            +f 1390/1434/1504 1391/1435/1505 1364/1408/1477
            +f 1392/1436/1506 1366/1410/1479 1365/1409/1478
            +f 1391/1435/1505 1392/1436/1506 1365/1409/1478
            +f 1393/1437/1507 1367/1411/1480 1366/1410/1479
            +f 1392/1436/1506 1393/1437/1507 1366/1410/1479
            +f 1394/1438/1508 1368/1412/1481 1367/1411/1480
            +f 1393/1437/1507 1394/1438/1508 1367/1411/1480
            +f 1395/1439/1509 1369/1413/1482 1368/1412/1481
            +f 1394/1438/1508 1395/1439/1509 1368/1412/1481
            +f 1396/1440/1510 1370/1414/1483 1369/1413/1482
            +f 1395/1439/1509 1396/1440/1510 1369/1413/1482
            +f 1397/1441/1511 1371/1415/1484 1370/1414/1483
            +f 1396/1440/1510 1397/1441/1511 1370/1414/1483
            +f 1398/1442/1512 1372/1416/1485 1371/1415/1484
            +f 1397/1441/1511 1398/1442/1512 1371/1415/1484
            +f 1399/1443/1513 1373/1417/1486 1372/1416/1487
            +f 1398/1442/1514 1399/1443/1513 1372/1416/1487
            +f 1400/1444/1515 1374/1418/1488 1373/1417/1489
            +f 1399/1443/1516 1400/1444/1515 1373/1417/1489
            +f 1401/1445/1517 1375/1419/1490 1374/1418/1488
            +f 1400/1444/1515 1401/1445/1517 1374/1418/1488
            +f 1402/1446/1518 1376/1420/1491 1375/1419/1490
            +f 1401/1445/1517 1402/1446/1518 1375/1419/1490
            +f 1403/1447/1519 1377/1421/1492 1376/1420/1491
            +f 1402/1446/1518 1403/1447/1519 1376/1420/1491
            +f 1429/1473/1520 1378/1422/1493 1377/1421/1492
            +f 1403/1447/1519 1429/1473/1520 1377/1421/1492
            +f 1429/1473/1520 1404/1448/1494 1378/1422/1493
            +f 1404/1448/1494 1455/1499/1495 1354/1398/1440
            +f 1430/1474/1521 1379/1423/1464 1405/1449/1496
            +f 1406/1450/1522 1380/1424/1465 1379/1423/1464
            +f 1430/1474/1521 1406/1450/1522 1379/1423/1464
            +f 1458/1502/1523 1381/1425/1466 1380/1424/1465
            +f 1406/1450/1522 1458/1502/1523 1380/1424/1465
            +f 1431/1475/1524 1382/1426/1414 1381/1425/1466
            +f 1458/1502/1523 1431/1475/1524 1381/1425/1466
            +f 1432/1476/1525 1356/1400/1441 1382/1426/1414
            +f 1431/1475/1524 1432/1476/1525 1382/1426/1414
            +f 1407/1451/1526 1383/1427/1497 1356/1400/1441
            +f 1432/1476/1525 1407/1451/1526 1356/1400/1441
            +f 1408/1452/1527 1384/1428/1498 1383/1427/1497
            +f 1407/1451/1526 1408/1452/1527 1383/1427/1497
            +f 1408/1452/1527 1359/1403/1470 1384/1428/1498
            +f 1461/1505/1528 1385/1429/1443 1359/1403/1470
            +f 1461/1505/1528 1409/1453/1311 1385/1429/1443
            +f 1411/1455/1529 1386/1430/1500 1410/1454/1472
            +f 1411/1455/1529 1387/1431/1501 1386/1430/1500
            +f 1411/1455/1529 1412/1456/1530 1387/1431/1501
            +f 1413/1457/1531 1388/1432/1502 1387/1431/1501
            +f 1412/1456/1530 1413/1457/1531 1387/1431/1501
            +f 1414/1458/1532 1389/1433/1503 1388/1432/1502
            +f 1413/1457/1531 1414/1458/1532 1388/1432/1502
            +f 1415/1459/1533 1390/1434/1504 1389/1433/1503
            +f 1414/1458/1532 1415/1459/1533 1389/1433/1503
            +f 1416/1460/1534 1391/1435/1505 1390/1434/1504
            +f 1415/1459/1533 1416/1460/1534 1390/1434/1504
            +f 1417/1461/1535 1392/1436/1506 1391/1435/1505
            +f 1416/1460/1534 1417/1461/1535 1391/1435/1505
            +f 1418/1462/1536 1393/1437/1507 1392/1436/1506
            +f 1417/1461/1535 1418/1462/1536 1392/1436/1506
            +f 1419/1463/1537 1394/1438/1508 1393/1437/1507
            +f 1418/1462/1536 1419/1463/1537 1393/1437/1507
            +f 1420/1464/1538 1395/1439/1509 1394/1438/1508
            +f 1419/1463/1537 1420/1464/1538 1394/1438/1508
            +f 1421/1465/1539 1396/1440/1510 1395/1439/1509
            +f 1420/1464/1538 1421/1465/1539 1395/1439/1509
            +f 1422/1466/1540 1397/1441/1511 1396/1440/1510
            +f 1421/1465/1539 1422/1466/1540 1396/1440/1510
            +f 1423/1467/1541 1398/1442/1512 1397/1441/1511
            +f 1422/1466/1540 1423/1467/1541 1397/1441/1511
            +f 1424/1468/1542 1399/1443/1513 1398/1442/1514
            +f 1423/1467/1543 1424/1468/1542 1398/1442/1514
            +f 1425/1469/1544 1400/1444/1515 1399/1443/1516
            +f 1424/1468/1545 1425/1469/1544 1399/1443/1516
            +f 1426/1470/1546 1401/1445/1517 1400/1444/1515
            +f 1425/1469/1544 1426/1470/1546 1400/1444/1515
            +f 1427/1471/1547 1402/1446/1518 1401/1445/1517
            +f 1426/1470/1546 1427/1471/1547 1401/1445/1517
            +f 1428/1472/1548 1403/1447/1519 1402/1446/1518
            +f 1427/1471/1547 1428/1472/1548 1402/1446/1518
            +f 1428/1472/1548 1429/1473/1520 1403/1447/1519
            +f 1454/1498/1549 1404/1448/1494 1429/1473/1520
            +f 1456/1500/1550 1405/1449/1496 1455/1499/1495
            +f 1457/1501/1551 1406/1450/1522 1430/1474/1521
            +f 1457/1501/1551 1458/1502/1523 1406/1450/1522
            +f 1433/1477/1552 1407/1451/1526 1432/1476/1525
            +f 1434/1478/1553 1408/1452/1527 1407/1451/1526
            +f 1433/1477/1552 1434/1478/1553 1407/1451/1526
            +f 1434/1478/1553 1359/1403/1470 1408/1452/1527
            +f 1435/1479/1554 1461/1505/1528 1359/1403/1470
            +f 1461/1505/1528 1711/1787/1499 1409/1453/1311
            +f 1462/1506/1555 1410/1454/1472 1436/1480/1471
            +f 1437/1481/1556 1411/1455/1529 1410/1454/1472
            +f 1462/1506/1555 1437/1481/1556 1410/1454/1472
            +f 1437/1481/1556 1438/1482/1557 1411/1455/1529
            +f 1438/1482/1557 1412/1456/1530 1411/1455/1529
            +f 1439/1483/1558 1413/1457/1531 1412/1456/1530
            +f 1438/1482/1557 1439/1483/1558 1412/1456/1530
            +f 1440/1484/1559 1414/1458/1532 1413/1457/1531
            +f 1439/1483/1558 1440/1484/1559 1413/1457/1531
            +f 1441/1485/1560 1415/1459/1533 1414/1458/1532
            +f 1440/1484/1559 1441/1485/1560 1414/1458/1532
            +f 1442/1486/1561 1416/1460/1534 1415/1459/1533
            +f 1441/1485/1560 1442/1486/1561 1415/1459/1533
            +f 1443/1487/1562 1417/1461/1535 1416/1460/1534
            +f 1442/1486/1561 1443/1487/1562 1416/1460/1534
            +f 1444/1488/1563 1418/1462/1536 1417/1461/1535
            +f 1443/1487/1562 1444/1488/1563 1417/1461/1535
            +f 1445/1489/1564 1419/1463/1537 1418/1462/1536
            +f 1444/1488/1563 1445/1489/1564 1418/1462/1536
            +f 1446/1490/1565 1420/1464/1538 1419/1463/1537
            +f 1445/1489/1564 1446/1490/1565 1419/1463/1537
            +f 1447/1491/1566 1421/1465/1539 1420/1464/1538
            +f 1446/1490/1565 1447/1491/1566 1420/1464/1538
            +f 1448/1492/1567 1422/1466/1540 1421/1465/1539
            +f 1447/1491/1566 1448/1492/1567 1421/1465/1539
            +f 1449/1493/1568 1423/1467/1541 1422/1466/1540
            +f 1448/1492/1567 1449/1493/1568 1422/1466/1540
            +f 1450/1494/1569 1424/1468/1542 1423/1467/1543
            +f 1449/1493/1570 1450/1494/1569 1423/1467/1543
            +f 1450/1494/1571 1425/1469/1544 1424/1468/1545
            +f 1451/1495/1572 1426/1470/1546 1425/1469/1544
            +f 1450/1494/1571 1451/1495/1572 1425/1469/1544
            +f 1452/1496/1573 1427/1471/1547 1426/1470/1546
            +f 1451/1495/1572 1452/1496/1573 1426/1470/1546
            +f 1453/1497/1574 1428/1472/1548 1427/1471/1547
            +f 1452/1496/1573 1453/1497/1574 1427/1471/1547
            +f 1481/1525/1575 1429/1473/1520 1428/1472/1548
            +f 1453/1497/1574 1481/1525/1575 1428/1472/1548
            +f 1481/1525/1575 1454/1498/1549 1429/1473/1520
            +f 1454/1498/1549 1455/1499/1495 1404/1448/1494
            +f 1482/1526/1576 1430/1474/1521 1405/1449/1496
            +f 1456/1500/1550 1482/1526/1576 1405/1449/1496
            +f 1482/1526/1576 1457/1501/1551 1430/1474/1521
            +f 1531/1575/1577 1431/1475/1524 1458/1502/1523
            +f 1483/1527/1578 1432/1476/1525 1431/1475/1524
            +f 1531/1575/1577 1483/1527/1578 1431/1475/1524
            +f 1483/1527/1578 1484/1528/1579 1432/1476/1525
            +f 1459/1503/1580 1433/1477/1552 1432/1476/1525
            +f 1484/1528/1579 1459/1503/1580 1432/1476/1525
            +f 1460/1504/1581 1434/1478/1553 1433/1477/1552
            +f 1459/1503/1580 1460/1504/1581 1433/1477/1552
            +f 1435/1479/1554 1359/1403/1470 1434/1478/1553
            +f 1460/1504/1581 1435/1479/1554 1434/1478/1553
            +f 1534/1578/1582 1436/1480/1471 1711/1787/1499
            +f 1534/1578/1582 1462/1506/1555 1436/1480/1471
            +f 1463/1507/1583 1437/1481/1556 1462/1506/1555
            +f 1463/1507/1583 1438/1482/1557 1437/1481/1556
            +f 1463/1507/1583 1464/1508/1584 1438/1482/1557
            +f 1465/1509/1585 1439/1483/1558 1438/1482/1557
            +f 1464/1508/1584 1465/1509/1585 1438/1482/1557
            +f 1466/1510/1586 1440/1484/1559 1439/1483/1558
            +f 1465/1509/1585 1466/1510/1586 1439/1483/1558
            +f 1467/1511/1587 1441/1485/1560 1440/1484/1559
            +f 1466/1510/1586 1467/1511/1587 1440/1484/1559
            +f 1468/1512/1588 1442/1486/1561 1441/1485/1560
            +f 1467/1511/1587 1468/1512/1588 1441/1485/1560
            +f 1469/1513/1589 1443/1487/1562 1442/1486/1561
            +f 1468/1512/1588 1469/1513/1589 1442/1486/1561
            +f 1470/1514/1590 1444/1488/1563 1443/1487/1562
            +f 1469/1513/1589 1470/1514/1590 1443/1487/1562
            +f 1471/1515/1591 1445/1489/1564 1444/1488/1563
            +f 1470/1514/1590 1471/1515/1591 1444/1488/1563
            +f 1472/1516/1592 1446/1490/1565 1445/1489/1564
            +f 1471/1515/1591 1472/1516/1592 1445/1489/1564
            +f 1473/1517/1593 1447/1491/1566 1446/1490/1565
            +f 1472/1516/1592 1473/1517/1593 1446/1490/1565
            +f 1474/1518/1594 1448/1492/1567 1447/1491/1566
            +f 1473/1517/1593 1474/1518/1594 1447/1491/1566
            +f 1475/1519/1595 1449/1493/1568 1448/1492/1567
            +f 1474/1518/1594 1475/1519/1595 1448/1492/1567
            +f 1476/1520/1596 1450/1494/1569 1449/1493/1570
            +f 1475/1519/1597 1476/1520/1596 1449/1493/1570
            +f 1476/1520/1598 1477/1521/1599 1450/1494/1571
            +f 1478/1522/1600 1451/1495/1572 1450/1494/1571
            +f 1477/1521/1599 1478/1522/1600 1450/1494/1571
            +f 1479/1523/1601 1452/1496/1573 1451/1495/1572
            +f 1478/1522/1600 1479/1523/1601 1451/1495/1572
            +f 1480/1524/1602 1453/1497/1574 1452/1496/1573
            +f 1479/1523/1601 1480/1524/1602 1452/1496/1573
            +f 1480/1524/1602 1481/1525/1575 1453/1497/1574
            +f 1504/1548/1603 1454/1498/1549 1481/1525/1575
            +f 1505/1549/1604 1456/1500/1550 1455/1499/1495
            +f 1454/1498/1549 1505/1549/1604 1455/1499/1495
            +f 1506/1550/1605 1457/1501/1551 1482/1526/1576
            +f 1507/1551/1606 1458/1502/1523 1457/1501/1551
            +f 1506/1550/1605 1507/1551/1606 1457/1501/1551
            +f 1507/1551/1606 1531/1575/1577 1458/1502/1523
            +f 1485/1529/1607 1460/1504/1581 1459/1503/1580
            +f 1484/1528/1579 1485/1529/1608 1459/1503/1580
            +f 1485/1529/1607 1435/1479/1554 1460/1504/1581
            +f 1510/1554/1609 1462/1506/1555 1534/1578/1582
            +f 1510/1554/1609 1463/1507/1583 1462/1506/1555
            +f 1510/1554/1609 1486/1530/1610 1463/1507/1583
            +f 1486/1530/1610 1487/1531/1611 1463/1507/1583
            +f 1487/1531/1611 1464/1508/1584 1463/1507/1583
            +f 1488/1532/1612 1465/1509/1585 1464/1508/1584
            +f 1487/1531/1611 1488/1532/1612 1464/1508/1584
            +f 1489/1533/1613 1466/1510/1586 1465/1509/1585
            +f 1488/1532/1612 1489/1533/1613 1465/1509/1585
            +f 1490/1534/1614 1467/1511/1587 1466/1510/1586
            +f 1489/1533/1613 1490/1534/1614 1466/1510/1586
            +f 1491/1535/1615 1468/1512/1588 1467/1511/1587
            +f 1490/1534/1614 1491/1535/1615 1467/1511/1587
            +f 1492/1536/1616 1469/1513/1589 1468/1512/1588
            +f 1491/1535/1615 1492/1536/1616 1468/1512/1588
            +f 1493/1537/1617 1470/1514/1590 1469/1513/1589
            +f 1492/1536/1616 1493/1537/1617 1469/1513/1589
            +f 1494/1538/1618 1471/1515/1591 1470/1514/1590
            +f 1493/1537/1617 1494/1538/1618 1470/1514/1590
            +f 1495/1539/1619 1472/1516/1592 1471/1515/1591
            +f 1494/1538/1618 1495/1539/1619 1471/1515/1591
            +f 1496/1540/1620 1473/1517/1593 1472/1516/1592
            +f 1495/1539/1619 1496/1540/1620 1472/1516/1592
            +f 1497/1541/1621 1474/1518/1594 1473/1517/1593
            +f 1496/1540/1620 1497/1541/1621 1473/1517/1593
            +f 1498/1542/1622 1475/1519/1595 1474/1518/1594
            +f 1497/1541/1621 1498/1542/1622 1474/1518/1594
            +f 1499/1543/1623 1476/1520/1596 1475/1519/1597
            +f 1498/1542/1624 1499/1543/1623 1475/1519/1597
            +f 1500/1544/1625 1477/1521/1599 1476/1520/1598
            +f 1499/1543/1626 1500/1544/1625 1476/1520/1598
            +f 1501/1545/1627 1478/1522/1600 1477/1521/1599
            +f 1500/1544/1625 1501/1545/1627 1477/1521/1599
            +f 1502/1546/1628 1479/1523/1601 1478/1522/1600
            +f 1501/1545/1627 1502/1546/1628 1478/1522/1600
            +f 1503/1547/1629 1480/1524/1602 1479/1523/1601
            +f 1502/1546/1628 1503/1547/1629 1479/1523/1601
            +f 1529/1573/1630 1481/1525/1575 1480/1524/1602
            +f 1503/1547/1629 1529/1573/1630 1480/1524/1602
            +f 1529/1573/1630 1504/1548/1603 1481/1525/1575
            +f 1555/1599/1631 1482/1526/1576 1456/1500/1550
            +f 1505/1549/1604 1555/1599/1631 1456/1500/1550
            +f 1555/1599/1631 1506/1550/1605 1482/1526/1576
            +f 1483/1527/1578 1508/1552/1632 1484/1528/1579
            +f 1509/1553/1633 1485/1529/1608 1484/1528/1579
            +f 1508/1552/1632 1509/1553/1633 1484/1528/1579
            +f 1509/1553/1633 1435/1479/1554 1485/1529/1608
            +f 1583/1627/1634 1510/1554/1609 1534/1578/1582
            +f 1511/1555/1635 1486/1530/1610 1510/1554/1609
            +f 1512/1556/1636 1487/1531/1611 1486/1530/1610
            +f 1511/1555/1635 1512/1556/1636 1486/1530/1610
            +f 1513/1557/1637 1488/1532/1612 1487/1531/1611
            +f 1512/1556/1636 1513/1557/1637 1487/1531/1611
            +f 1514/1558/1638 1489/1533/1613 1488/1532/1612
            +f 1513/1557/1637 1514/1558/1638 1488/1532/1612
            +f 1515/1559/1639 1490/1534/1614 1489/1533/1613
            +f 1514/1558/1638 1515/1559/1639 1489/1533/1613
            +f 1516/1560/1640 1491/1535/1615 1490/1534/1614
            +f 1515/1559/1639 1516/1560/1640 1490/1534/1614
            +f 1517/1561/1641 1492/1536/1616 1491/1535/1615
            +f 1516/1560/1640 1517/1561/1641 1491/1535/1615
            +f 1518/1562/1642 1493/1537/1617 1492/1536/1616
            +f 1517/1561/1641 1518/1562/1642 1492/1536/1616
            +f 1519/1563/1643 1494/1538/1618 1493/1537/1617
            +f 1518/1562/1642 1519/1563/1643 1493/1537/1617
            +f 1520/1564/1644 1495/1539/1619 1494/1538/1618
            +f 1519/1563/1643 1520/1564/1644 1494/1538/1618
            +f 1521/1565/1645 1496/1540/1620 1495/1539/1619
            +f 1520/1564/1644 1521/1565/1645 1495/1539/1619
            +f 1522/1566/1646 1497/1541/1621 1496/1540/1620
            +f 1521/1565/1645 1522/1566/1646 1496/1540/1620
            +f 1523/1567/1647 1498/1542/1622 1497/1541/1621
            +f 1524/1568/1648 1499/1543/1623 1498/1542/1624
            +f 1523/1567/1649 1524/1568/1648 1498/1542/1624
            +f 1525/1569/1650 1500/1544/1625 1499/1543/1626
            +f 1524/1568/1651 1525/1569/1650 1499/1543/1626
            +f 1526/1570/1652 1501/1545/1627 1500/1544/1625
            +f 1525/1569/1650 1526/1570/1652 1500/1544/1625
            +f 1527/1571/1653 1502/1546/1628 1501/1545/1627
            +f 1526/1570/1652 1527/1571/1653 1501/1545/1627
            +f 1528/1572/1654 1503/1547/1629 1502/1546/1628
            +f 1527/1571/1653 1528/1572/1654 1502/1546/1628
            +f 1528/1572/1654 1529/1573/1630 1503/1547/1629
            +f 1553/1597/1655 1504/1548/1603 1529/1573/1630
            +f 1604/1648/1656 1454/1498/1549 1504/1548/1603
            +f 1554/1598/1657 1505/1549/1604 1454/1498/1549
            +f 1604/1648/1656 1554/1598/1657 1454/1498/1549
            +f 1530/1574/1658 1506/1550/1605 1555/1599/1631
            +f 1578/1622/1659 1507/1551/1606 1506/1550/1605
            +f 1530/1574/1658 1578/1622/1659 1506/1550/1605
            +f 1578/1622/1659 1531/1575/1577 1507/1551/1606
            +f 1532/1576/1660 1508/1552/1632 1483/1527/1578
            +f 1533/1577/1661 1509/1553/1633 1508/1552/1632
            +f 1532/1576/1660 1533/1577/1661 1508/1552/1632
            +f 1533/1577/1661 1435/1479/1554 1509/1553/1633
            +f 1535/1579/1662 1510/1554/1609 1583/1627/1634
            +f 1535/1579/1662 1536/1580/1663 1510/1554/1609
            +f 1536/1580/1663 1511/1555/1635 1510/1554/1609
            +f 1536/1580/1663 1512/1556/1636 1511/1555/1635
            +f 1536/1580/1663 1537/1581/1664 1512/1556/1636
            +f 1538/1582/1665 1513/1557/1637 1512/1556/1636
            +f 1537/1581/1664 1538/1582/1665 1512/1556/1636
            +f 1539/1583/1666 1514/1558/1638 1513/1557/1637
            +f 1538/1582/1665 1539/1583/1666 1513/1557/1637
            +f 1540/1584/1667 1515/1559/1639 1514/1558/1638
            +f 1539/1583/1666 1540/1584/1667 1514/1558/1638
            +f 1541/1585/1668 1516/1560/1640 1515/1559/1639
            +f 1540/1584/1667 1541/1585/1668 1515/1559/1639
            +f 1542/1586/1669 1517/1561/1641 1516/1560/1640
            +f 1541/1585/1668 1542/1586/1669 1516/1560/1640
            +f 1543/1587/1670 1518/1562/1642 1517/1561/1641
            +f 1542/1586/1669 1543/1587/1670 1517/1561/1641
            +f 1544/1588/1671 1519/1563/1643 1518/1562/1642
            +f 1543/1587/1670 1544/1588/1671 1518/1562/1642
            +f 1545/1589/1672 1520/1564/1644 1519/1563/1643
            +f 1544/1588/1671 1545/1589/1672 1519/1563/1643
            +f 1546/1590/1673 1521/1565/1645 1520/1564/1644
            +f 1545/1589/1672 1546/1590/1673 1520/1564/1644
            +f 2382/2528/1674 2383/2529/1675 2384/2530/1676
            +f 2385/2531/1677 2386/2532/1678 2387/2533/1679
            +f 1547/1591/1680 1524/1568/1648 1523/1567/1649
            +f 1548/1592/1681 1547/1591/1680 1523/1567/1649
            +f 1549/1593/1682 1525/1569/1650 1524/1568/1651
            +f 1547/1591/1683 1549/1593/1682 1524/1568/1651
            +f 1550/1594/1684 1526/1570/1652 1525/1569/1650
            +f 1549/1593/1682 1550/1594/1684 1525/1569/1650
            +f 1551/1595/1685 1527/1571/1653 1526/1570/1652
            +f 1550/1594/1684 1551/1595/1685 1526/1570/1652
            +f 1552/1596/1686 1528/1572/1654 1527/1571/1653
            +f 1551/1595/1685 1552/1596/1686 1527/1571/1653
            +f 1576/1620/1687 1529/1573/1630 1528/1572/1654
            +f 1552/1596/1686 1576/1620/1687 1528/1572/1654
            +f 1576/1620/1687 1553/1597/1655 1529/1573/1630
            +f 1553/1597/1655 1604/1648/1656 1504/1548/1603
            +f 1554/1598/1657 1555/1599/1631 1505/1549/1604
            +f 1577/1621/1688 1530/1574/1658 1555/1599/1631
            +f 1577/1621/1688 1578/1622/1659 1530/1574/1658
            +f 1579/1623/1689 1531/1575/1577 1578/1622/1659
            +f 1580/1624/1690 1483/1527/1578 1531/1575/1577
            +f 1579/1623/1689 1580/1624/1690 1531/1575/1577
            +f 1556/1600/1691 1532/1576/1660 1483/1527/1578
            +f 1580/1624/1690 1556/1600/1691 1483/1527/1578
            +f 1557/1601/1692 1533/1577/1661 1532/1576/1660
            +f 1556/1600/1691 1557/1601/1692 1532/1576/1660
            +f 1557/1601/1692 1435/1479/1554 1533/1577/1661
            +f 1710/1786/1693 1461/1505/1528 1435/1479/1554
            +f 1710/1786/1693 1711/1787/1499 1461/1505/1528
            +f 1634/1678/1694 1534/1578/1582 1711/1787/1499
            +f 1634/1678/1694 1583/1627/1634 1534/1578/1582
            +f 1535/1579/1662 1558/1602/1695 1536/1580/1663
            +f 1558/1602/1695 1559/1603/1696 1536/1580/1663
            +f 1559/1603/1696 1537/1581/1664 1536/1580/1663
            +f 1560/1604/1697 1538/1582/1665 1537/1581/1664
            +f 1559/1603/1696 1560/1604/1697 1537/1581/1664
            +f 1561/1605/1698 1539/1583/1666 1538/1582/1665
            +f 1560/1604/1697 1561/1605/1698 1538/1582/1665
            +f 1562/1606/1699 1540/1584/1667 1539/1583/1666
            +f 1561/1605/1698 1562/1606/1699 1539/1583/1666
            +f 1563/1607/1700 1541/1585/1668 1540/1584/1667
            +f 1562/1606/1699 1563/1607/1700 1540/1584/1667
            +f 1564/1608/1701 1542/1586/1669 1541/1585/1668
            +f 1563/1607/1700 1564/1608/1701 1541/1585/1668
            +f 1565/1609/1702 1543/1587/1670 1542/1586/1669
            +f 1564/1608/1701 1565/1609/1702 1542/1586/1669
            +f 1566/1610/1703 1544/1588/1671 1543/1587/1670
            +f 1565/1609/1702 1566/1610/1703 1543/1587/1670
            +f 1567/1611/1704 1545/1589/1672 1544/1588/1671
            +f 1566/1610/1703 1567/1611/1704 1544/1588/1671
            +f 1568/1612/1705 1546/1590/1673 1545/1589/1672
            +f 1567/1611/1704 1568/1612/1705 1545/1589/1672
            +f 2388/2534/1706 2389/2535/1707 2390/2536/1708
            +f 1568/1612/1705 1569/1613/1709 1546/1590/1673
            +f 1570/1614/1710 1547/1591/1680 1548/1592/1681
            +f 1571/1615/1711 1570/1614/1710 1548/1592/1681
            +f 1572/1616/1712 1549/1593/1682 1547/1591/1683
            +f 1570/1614/1713 1572/1616/1712 1547/1591/1683
            +f 1573/1617/1714 1550/1594/1684 1549/1593/1682
            +f 1572/1616/1712 1573/1617/1714 1549/1593/1682
            +f 1574/1618/1715 1551/1595/1685 1550/1594/1684
            +f 1573/1617/1714 1574/1618/1715 1550/1594/1684
            +f 1575/1619/1716 1552/1596/1686 1551/1595/1685
            +f 1574/1618/1715 1575/1619/1716 1551/1595/1685
            +f 1575/1619/1716 1576/1620/1687 1552/1596/1686
            +f 1603/1647/1717 1553/1597/1655 1576/1620/1687
            +f 1605/1649/1718 1554/1598/1657 1604/1648/1656
            +f 1606/1650/1719 1555/1599/1631 1554/1598/1657
            +f 1606/1650/1719 1577/1621/1688 1555/1599/1631
            +f 1581/1625/1720 1556/1600/1691 1580/1624/1690
            +f 1582/1626/1721 1557/1601/1692 1556/1600/1691
            +f 1581/1625/1720 1582/1626/1721 1556/1600/1691
            +f 1582/1626/1721 1435/1479/1554 1557/1601/1692
            +f 1584/1628/1722 1535/1579/1662 1583/1627/1634
            +f 1585/1629/1723 1558/1602/1695 1535/1579/1662
            +f 1584/1628/1722 1585/1629/1723 1535/1579/1662
            +f 1586/1630/1724 1559/1603/1696 1558/1602/1695
            +f 1585/1629/1723 1586/1630/1724 1558/1602/1695
            +f 1587/1631/1725 1560/1604/1697 1559/1603/1696
            +f 1586/1630/1724 1587/1631/1725 1559/1603/1696
            +f 1588/1632/1726 1561/1605/1698 1560/1604/1697
            +f 1587/1631/1725 1588/1632/1726 1560/1604/1697
            +f 1589/1633/1727 1562/1606/1699 1561/1605/1698
            +f 1588/1632/1726 1589/1633/1727 1561/1605/1698
            +f 1590/1634/1728 1563/1607/1700 1562/1606/1699
            +f 1589/1633/1727 1590/1634/1728 1562/1606/1699
            +f 1591/1635/1729 1564/1608/1701 1563/1607/1700
            +f 1590/1634/1728 1591/1635/1729 1563/1607/1700
            +f 1592/1636/1730 1565/1609/1702 1564/1608/1701
            +f 1591/1635/1729 1592/1636/1730 1564/1608/1701
            +f 1593/1637/1731 1566/1610/1703 1565/1609/1702
            +f 1592/1636/1730 1593/1637/1731 1565/1609/1702
            +f 1594/1638/1732 1567/1611/1704 1566/1610/1703
            +f 1593/1637/1731 1594/1638/1732 1566/1610/1703
            +f 1595/1639/1733 1568/1612/1705 1567/1611/1704
            +f 1594/1638/1732 1595/1639/1733 1567/1611/1704
            +f 1596/1640/1734 1569/1613/1709 1568/1612/1705
            +f 1595/1639/1733 1596/1640/1734 1568/1612/1705
            +f 1596/1640/1734 1597/1641/1735 1569/1613/1709
            +f 1598/1642/1736 1570/1614/1710 1571/1615/1711
            +f 1597/1641/1737 1598/1642/1736 1571/1615/1711
            +f 1599/1643/1738 1572/1616/1712 1570/1614/1713
            +f 1598/1642/1739 1599/1643/1738 1570/1614/1713
            +f 1600/1644/1740 1573/1617/1714 1572/1616/1712
            +f 1599/1643/1738 1600/1644/1740 1572/1616/1712
            +f 1601/1645/1741 1574/1618/1715 1573/1617/1714
            +f 1600/1644/1740 1601/1645/1741 1573/1617/1714
            +f 1602/1646/1742 1575/1619/1716 1574/1618/1715
            +f 1601/1645/1741 1602/1646/1742 1574/1618/1715
            +f 1628/1672/1743 1576/1620/1687 1575/1619/1716
            +f 1602/1646/1742 1628/1672/1743 1575/1619/1716
            +f 1628/1672/1743 1603/1647/1717 1576/1620/1687
            +f 1603/1647/1717 1604/1648/1656 1553/1597/1655
            +f 1605/1649/1718 1606/1650/1719 1554/1598/1657
            +f 1629/1673/1744 1577/1621/1688 1606/1650/1719
            +f 1630/1674/1745 1578/1622/1659 1577/1621/1688
            +f 1629/1673/1744 1630/1674/1745 1577/1621/1688
            +f 1681/1748/1746 1579/1623/1689 1578/1622/1659
            +f 1630/1674/1745 1681/1748/1746 1578/1622/1659
            +f 1681/1748/1746 1580/1624/1690 1579/1623/1689
            +f 1607/1651/1747 1581/1625/1720 1580/1624/1690
            +f 1631/1675/1748 1607/1651/1747 1580/1624/1690
            +f 1608/1652/1749 1582/1626/1721 1581/1625/1720
            +f 1607/1651/1747 1608/1652/1749 1581/1625/1720
            +f 1608/1652/1749 1435/1479/1554 1582/1626/1721
            +f 1609/1653/1750 1584/1628/1722 1583/1627/1634
            +f 1634/1678/1694 1609/1653/1750 1583/1627/1634
            +f 1609/1653/1750 1610/1654/1751 1584/1628/1722
            +f 1610/1654/1751 1585/1629/1723 1584/1628/1722
            +f 1610/1654/1751 1586/1630/1724 1585/1629/1723
            +f 1610/1654/1751 1611/1655/1752 1586/1630/1724
            +f 1612/1656/1753 1587/1631/1725 1586/1630/1724
            +f 1611/1655/1752 1612/1656/1753 1586/1630/1724
            +f 1613/1657/1754 1588/1632/1726 1587/1631/1725
            +f 1612/1656/1753 1613/1657/1754 1587/1631/1725
            +f 1614/1658/1755 1589/1633/1727 1588/1632/1726
            +f 1613/1657/1754 1614/1658/1755 1588/1632/1726
            +f 1615/1659/1756 1590/1634/1728 1589/1633/1727
            +f 1614/1658/1755 1615/1659/1756 1589/1633/1727
            +f 1616/1660/1757 1591/1635/1729 1590/1634/1728
            +f 1615/1659/1756 1616/1660/1757 1590/1634/1728
            +f 1617/1661/1758 1592/1636/1730 1591/1635/1729
            +f 1616/1660/1757 1617/1661/1758 1591/1635/1729
            +f 1618/1662/1759 1593/1637/1731 1592/1636/1730
            +f 1617/1661/1758 1618/1662/1759 1592/1636/1730
            +f 1619/1663/1760 1594/1638/1732 1593/1637/1731
            +f 1618/1662/1759 1619/1663/1760 1593/1637/1731
            +f 1620/1664/1761 1595/1639/1733 1594/1638/1732
            +f 1619/1663/1760 1620/1664/1761 1594/1638/1732
            +f 1621/1665/1762 1596/1640/1734 1595/1639/1733
            +f 1620/1664/1761 1621/1665/1762 1595/1639/1733
            +f 1622/1666/1763 1597/1641/1735 1596/1640/1734
            +f 1621/1665/1762 1622/1666/1763 1596/1640/1734
            +f 1623/1667/1764 1598/1642/1736 1597/1641/1737
            +f 1622/1666/1765 1623/1667/1764 1597/1641/1737
            +f 1624/1668/1766 1599/1643/1738 1598/1642/1739
            +f 1623/1667/1767 1624/1668/1766 1598/1642/1739
            +f 1625/1669/1768 1600/1644/1740 1599/1643/1738
            +f 1624/1668/1766 1625/1669/1768 1599/1643/1738
            +f 1626/1670/1769 1601/1645/1741 1600/1644/1740
            +f 1625/1669/1768 1626/1670/1769 1600/1644/1740
            +f 1627/1671/1770 1602/1646/1742 1601/1645/1741
            +f 1626/1670/1769 1627/1671/1770 1601/1645/1741
            +f 1627/1671/1770 1628/1672/1743 1602/1646/1742
            +f 1653/1709/1771 1603/1647/1717 1628/1672/1743
            +f 1654/1710/1772 1605/1649/1718 1604/1648/1656
            +f 1603/1647/1717 1654/1710/1772 1604/1648/1656
            +f 1655/1711/1773 1606/1650/1719 1605/1649/1718
            +f 1655/1711/1773 1629/1673/1744 1606/1650/1719
            +f 1656/1712/1774 1631/1675/1748 1580/1624/1690
            +f 1632/1676/1775 1608/1652/1749 1607/1651/1747
            +f 1631/1675/1748 1632/1676/1775 1607/1651/1747
            +f 1632/1676/1775 1435/1479/1554 1608/1652/1749
            +f 1633/1677/1776 1710/1786/1693 1435/1479/1554
            +f 1609/1653/1750 1635/1679/1777 1610/1654/1751
            +f 1635/1679/1777 1636/1680/1778 1610/1654/1751
            +f 1636/1680/1778 1611/1655/1752 1610/1654/1751
            +f 1637/1681/1779 1612/1656/1753 1611/1655/1752
            +f 1636/1680/1778 1637/1681/1779 1611/1655/1752
            +f 1638/1682/1780 1613/1657/1754 1612/1656/1753
            +f 1637/1681/1779 1638/1682/1780 1612/1656/1753
            +f 1639/1683/1781 1614/1658/1755 1613/1657/1754
            +f 1638/1682/1780 1639/1683/1781 1613/1657/1754
            +f 1640/1684/1782 1615/1659/1756 1614/1658/1755
            +f 1639/1683/1781 1640/1684/1782 1614/1658/1755
            +f 1641/1685/1783 1616/1660/1757 1615/1659/1756
            +f 1640/1684/1782 1641/1685/1783 1615/1659/1756
            +f 1642/1686/1784 1617/1661/1758 1616/1660/1757
            +f 1641/1685/1783 1642/1686/1784 1616/1660/1757
            +f 1643/1687/1785 1618/1662/1759 1617/1661/1758
            +f 1642/1686/1784 1643/1687/1785 1617/1661/1758
            +f 1618/1688/1759 1644/1690/1786 1619/1689/1760
            +f 1618/1691/1759 1643/1692/1785 1644/1690/1786
            +f 1619/1693/1760 1645/1695/1787 1620/1694/1761
            +f 1644/1690/1786 1645/1695/1787 1619/1696/1760
            +f 1620/1697/1761 1646/1699/1788 1621/1698/1762
            +f 1645/1695/1787 1646/1699/1788 1620/1700/1761
            +f 1647/1701/1789 1622/1666/1763 1621/1665/1762
            +f 1621/1702/1762 1646/1699/1788 1647/1703/1789
            +f 1648/1704/1790 1623/1667/1764 1622/1666/1765
            +f 1647/1701/1791 1648/1704/1790 1622/1666/1765
            +f 1649/1705/1792 1624/1668/1766 1623/1667/1767
            +f 1648/1704/1793 1649/1705/1792 1623/1667/1767
            +f 1650/1706/1794 1625/1669/1768 1624/1668/1766
            +f 1649/1705/1792 1650/1706/1794 1624/1668/1766
            +f 1651/1707/1795 1626/1670/1769 1625/1669/1768
            +f 1650/1706/1794 1651/1707/1795 1625/1669/1768
            +f 1652/1708/1796 1627/1671/1770 1626/1670/1769
            +f 1651/1707/1795 1652/1708/1796 1626/1670/1769
            +f 1678/1745/1797 1628/1672/1743 1627/1671/1770
            +f 1652/1708/1796 1678/1745/1797 1627/1671/1770
            +f 1678/1745/1797 1653/1709/1771 1628/1672/1743
            +f 1654/1710/1772 1655/1711/1773 1605/1649/1718
            +f 1679/1746/1798 1629/1673/1744 1655/1711/1773
            +f 1680/1747/1799 1630/1674/1745 1629/1673/1744
            +f 1679/1746/1798 1680/1747/1799 1629/1673/1744
            +f 1680/1747/1799 1681/1748/1746 1630/1674/1745
            +f 1656/1712/1774 1580/1624/1690 1681/1748/1746
            +f 1656/1712/1774 1657/1713/1800 1631/1675/1748
            +f 1658/1714/1801 1632/1676/1775 1631/1675/1748
            +f 1657/1713/1800 1658/1714/1801 1631/1675/1748
            +f 1633/1677/1776 1435/1479/1554 1632/1676/1775
            +f 1658/1714/1801 1633/1677/1776 1632/1676/1775
            +f 1738/1820/1802 1634/1678/1694 1711/1787/1499
            +f 1684/1751/1803 1609/1653/1750 1634/1678/1694
            +f 1738/1820/1802 1684/1751/1803 1634/1678/1694
            +f 1659/1715/1804 1635/1679/1777 1609/1653/1750
            +f 1684/1751/1803 1659/1715/1804 1609/1653/1750
            +f 1660/1716/1805 1636/1680/1778 1635/1679/1777
            +f 1659/1715/1804 1660/1716/1805 1635/1679/1777
            +f 1661/1717/1806 1637/1681/1779 1636/1680/1778
            +f 1660/1716/1805 1661/1717/1806 1636/1680/1778
            +f 1662/1718/1807 1638/1682/1780 1637/1681/1779
            +f 1661/1717/1806 1662/1718/1807 1637/1681/1779
            +f 1663/1719/1808 1639/1683/1781 1638/1682/1780
            +f 1662/1718/1807 1663/1719/1808 1638/1682/1780
            +f 1664/1720/1809 1640/1684/1782 1639/1683/1781
            +f 1663/1719/1808 1664/1720/1809 1639/1683/1781
            +f 1664/1720/1809 1665/1721/1810 1640/1684/1782
            +f 1666/1722/1811 1641/1685/1783 1640/1684/1782
            +f 1665/1721/1810 1666/1722/1811 1640/1684/1782
            +f 1641/1723/1783 1667/1725/1812 1642/1724/1784
            +f 1641/1726/1783 1666/1727/1811 1667/1725/1812
            +f 1642/1728/1784 1668/1730/1813 1643/1729/1785
            +f 1667/1725/1812 1668/1730/1813 1642/1731/1784
            +f 1669/1732/1814 1644/1690/1786 1643/1733/1785
            +f 1668/1730/1813 1669/1732/1814 1643/1734/1785
            +f 1670/1735/1815 1645/1695/1787 1644/1690/1786
            +f 1669/1732/1814 1670/1735/1815 1644/1690/1786
            +f 1671/1736/1816 1646/1699/1788 1645/1695/1787
            +f 1670/1735/1815 1671/1736/1816 1645/1695/1787
            +f 1672/1737/1817 1647/1738/1789 1646/1699/1788
            +f 1671/1736/1816 1672/1737/1817 1646/1699/1788
            +f 1673/1739/1818 1648/1704/1790 1647/1701/1791
            +f 1672/1740/1819 1673/1739/1818 1647/1701/1791
            +f 1674/1741/1820 1649/1705/1792 1648/1704/1793
            +f 1673/1739/1821 1674/1741/1820 1648/1704/1793
            +f 1675/1742/1822 1650/1706/1794 1649/1705/1792
            +f 1674/1741/1820 1675/1742/1822 1649/1705/1792
            +f 1676/1743/1823 1651/1707/1795 1650/1706/1794
            +f 1675/1742/1822 1676/1743/1823 1650/1706/1794
            +f 1677/1744/1824 1652/1708/1796 1651/1707/1795
            +f 1676/1743/1823 1677/1744/1824 1651/1707/1795
            +f 1677/1744/1824 1678/1745/1797 1652/1708/1796
            +f 1705/1781/1825 1653/1709/1771 1678/1745/1797
            +f 1764/1864/1826 1603/1647/1717 1653/1709/1771
            +f 1706/1782/1827 1654/1710/1772 1603/1647/1717
            +f 1764/1864/1826 1706/1782/1827 1603/1647/1717
            +f 1707/1783/1828 1655/1711/1773 1654/1710/1772
            +f 1707/1783/1828 1679/1746/1798 1655/1711/1773
            +f 1682/1749/1829 1657/1713/1800 1656/1712/1774
            +f 1683/1750/1830 1658/1714/1801 1657/1713/1800
            +f 1682/1749/1829 1683/1750/1830 1657/1713/1800
            +f 1683/1750/1830 1633/1677/1776 1658/1714/1801
            +f 1685/1752/1831 1659/1715/1804 1684/1751/1803
            +f 1686/1753/1832 1660/1716/1805 1659/1715/1804
            +f 1685/1752/1831 1686/1753/1832 1659/1715/1804
            +f 1687/1754/1833 1661/1717/1806 1660/1716/1805
            +f 1686/1753/1832 1687/1754/1833 1660/1716/1805
            +f 1688/1755/1834 1662/1718/1807 1661/1717/1806
            +f 1687/1754/1833 1688/1755/1834 1661/1717/1806
            +f 1689/1756/1835 1663/1719/1808 1662/1718/1807
            +f 1688/1755/1834 1689/1756/1835 1662/1718/1807
            +f 1690/1757/1836 1664/1720/1809 1663/1719/1808
            +f 1689/1756/1835 1690/1757/1836 1663/1719/1808
            +f 1691/1758/1837 1665/1721/1810 1664/1720/1809
            +f 1690/1757/1836 1691/1758/1837 1664/1720/1809
            +f 1665/1759/1810 1692/1761/1838 1666/1760/1811
            +f 1665/1762/1810 1691/1763/1837 1692/1761/1838
            +f 1693/1764/1839 1667/1725/1812 1666/1765/1811
            +f 1692/1761/1838 1693/1764/1839 1666/1766/1811
            +f 1694/1767/1840 1668/1730/1813 1667/1725/1812
            +f 1693/1764/1839 1694/1767/1840 1667/1725/1812
            +f 1695/1768/1841 1669/1732/1814 1668/1730/1813
            +f 1694/1767/1840 1695/1768/1841 1668/1730/1813
            +f 1696/1769/1842 1670/1735/1815 1669/1732/1814
            +f 1695/1768/1841 1696/1769/1842 1669/1732/1814
            +f 1697/1770/1843 1671/1736/1816 1670/1735/1815
            +f 1696/1769/1842 1697/1770/1843 1670/1735/1815
            +f 1698/1771/1844 1672/1737/1817 1671/1736/1816
            +f 1697/1770/1843 1698/1771/1844 1671/1736/1816
            +f 1699/1772/1845 1673/1739/1818 1672/1773/1819
            +f 1672/1774/1819 1698/1775/1846 1699/1772/1845
            +f 1700/1776/1847 1674/1741/1820 1673/1739/1821
            +f 1699/1772/1848 1700/1776/1847 1673/1739/1821
            +f 1701/1777/1849 1675/1742/1822 1674/1741/1820
            +f 1700/1776/1847 1701/1777/1849 1674/1741/1820
            +f 1702/1778/1850 1676/1743/1823 1675/1742/1822
            +f 1701/1777/1849 1702/1778/1850 1675/1742/1822
            +f 1703/1779/1851 1677/1744/1824 1676/1743/1823
            +f 1702/1778/1850 1703/1779/1851 1676/1743/1823
            +f 1704/1780/1852 1678/1745/1797 1677/1744/1824
            +f 1703/1779/1851 1704/1780/1852 1677/1744/1824
            +f 1704/1780/1852 1705/1781/1825 1678/1745/1797
            +f 1705/1781/1825 1764/1864/1826 1653/1709/1771
            +f 1706/1782/1827 1707/1783/1828 1654/1710/1772
            +f 1732/1814/1853 1679/1746/1798 1707/1783/1828
            +f 1733/1815/1854 1680/1747/1799 1679/1746/1798
            +f 1732/1814/1853 1733/1815/1854 1679/1746/1798
            +f 1734/1816/1855 1681/1748/1746 1680/1747/1799
            +f 1733/1815/1854 1734/1816/1855 1680/1747/1799
            +f 1735/1817/1856 1656/1712/1774 1681/1748/1746
            +f 1734/1816/1855 1735/1817/1856 1681/1748/1746
            +f 1708/1784/1857 1682/1749/1829 1656/1712/1774
            +f 1735/1817/1856 1708/1784/1857 1656/1712/1774
            +f 1709/1785/1858 1683/1750/1830 1682/1749/1829
            +f 1708/1784/1857 1709/1785/1858 1682/1749/1829
            +f 1709/1785/1858 1633/1677/1776 1683/1750/1830
            +f 1739/1821/1859 1684/1751/1803 1738/1820/1802
            +f 1739/1821/1859 1712/1788/1860 1684/1751/1803
            +f 1712/1788/1860 1685/1752/1831 1684/1751/1803
            +f 1712/1788/1860 1686/1753/1832 1685/1752/1831
            +f 1712/1788/1860 1713/1789/1861 1686/1753/1832
            +f 1714/1790/1862 1687/1754/1833 1686/1753/1832
            +f 1713/1789/1861 1714/1790/1862 1686/1753/1832
            +f 1715/1791/1863 1688/1755/1834 1687/1754/1833
            +f 1714/1790/1862 1715/1791/1863 1687/1754/1833
            +f 1716/1792/1864 1689/1756/1835 1688/1755/1834
            +f 1715/1791/1863 1716/1792/1864 1688/1755/1834
            +f 1717/1793/1865 1690/1757/1836 1689/1756/1835
            +f 1716/1792/1864 1717/1793/1865 1689/1756/1835
            +f 1718/1794/1866 1691/1758/1837 1690/1757/1836
            +f 1717/1793/1865 1718/1794/1866 1690/1757/1836
            +f 1719/1795/1867 1692/1761/1838 1691/1796/1837
            +f 1691/1797/1837 1718/1798/1866 1719/1795/1867
            +f 1720/1799/1868 1693/1764/1839 1692/1761/1838
            +f 1719/1795/1867 1720/1799/1868 1692/1761/1838
            +f 1721/1800/1869 1694/1767/1840 1693/1764/1839
            +f 1720/1799/1868 1721/1800/1869 1693/1764/1839
            +f 1722/1801/1870 1695/1768/1841 1694/1767/1840
            +f 1721/1800/1869 1722/1801/1870 1694/1767/1840
            +f 1723/1802/1871 1696/1769/1842 1695/1768/1841
            +f 1722/1801/1870 1723/1802/1871 1695/1768/1841
            +f 1724/1803/1872 1697/1770/1843 1696/1769/1842
            +f 1723/1802/1871 1724/1803/1872 1696/1769/1842
            +f 1725/1804/1873 1698/1771/1844 1697/1770/1843
            +f 1724/1803/1872 1725/1804/1873 1697/1770/1843
            +f 1726/1805/1874 1699/1772/1845 1698/1806/1846
            +f 1698/1807/1846 1725/1808/1875 1726/1805/1874
            +f 1727/1809/1876 1700/1776/1847 1699/1772/1848
            +f 1726/1805/1877 1727/1809/1876 1699/1772/1848
            +f 1728/1810/1878 1701/1777/1849 1700/1776/1847
            +f 1727/1809/1876 1728/1810/1878 1700/1776/1847
            +f 1728/1810/1878 1729/1811/1879 1701/1777/1849
            +f 1730/1812/1880 1702/1778/1850 1701/1777/1849
            +f 1729/1811/1879 1730/1812/1880 1701/1777/1849
            +f 1731/1813/1881 1703/1779/1851 1702/1778/1850
            +f 1730/1812/1880 1731/1813/1881 1702/1778/1850
            +f 1762/1862/1882 1704/1780/1852 1703/1779/1851
            +f 1731/1813/1881 1762/1862/1882 1703/1779/1851
            +f 1763/1863/1883 1705/1781/1825 1704/1780/1852
            +f 1762/1862/1882 1763/1863/1883 1704/1780/1852
            +f 1765/1865/1884 1706/1782/1827 1764/1864/1826
            +f 1766/1866/1885 1707/1783/1828 1706/1782/1827
            +f 1766/1866/1885 1732/1814/1853 1707/1783/1828
            +f 1736/1818/1886 1708/1784/1857 1735/1817/1856
            +f 1737/1819/1887 1709/1785/1858 1708/1784/1857
            +f 1736/1818/1886 1737/1819/1887 1708/1784/1857
            +f 1737/1819/1887 1633/1677/1776 1709/1785/1858
            +f 1820/1954/684 1710/1786/1693 1633/1677/1776
            +f 1820/1954/684 1711/1787/1499 1710/1786/1693
            +f 1740/1822/1888 1712/1788/1860 1739/1821/1859
            +f 1740/1822/1888 1713/1789/1861 1712/1788/1860
            +f 1740/1822/1888 1741/1823/1889 1713/1789/1861
            +f 1742/1824/1890 1714/1790/1862 1713/1789/1861
            +f 1741/1823/1889 1742/1824/1890 1713/1789/1861
            +f 1743/1825/1891 1715/1791/1863 1714/1790/1862
            +f 1742/1824/1890 1743/1825/1891 1714/1790/1862
            +f 1743/1825/1891 1744/1826/1892 1715/1791/1863
            +f 1745/1827/1893 1716/1792/1864 1715/1791/1863
            +f 1744/1826/1892 1745/1827/1893 1715/1791/1863
            +f 1716/1828/1864 1746/1830/1894 1717/1829/1865
            +f 1716/1831/1864 1745/1832/1893 1746/1830/1894
            +f 1717/1833/1865 1747/1835/1895 1718/1834/1866
            +f 1746/1830/1894 1747/1835/1895 1717/1836/1865
            +f 1748/1837/1896 1719/1795/1867 1718/1838/1866
            +f 1747/1835/1895 1748/1837/1896 1718/1839/1866
            +f 1749/1840/1897 1720/1799/1868 1719/1795/1867
            +f 1748/1837/1896 1749/1840/1897 1719/1795/1867
            +f 1750/1841/1898 1721/1800/1869 1720/1799/1868
            +f 1749/1840/1897 1750/1841/1898 1720/1799/1868
            +f 1751/1842/1899 1722/1801/1870 1721/1800/1869
            +f 1750/1841/1898 1751/1842/1899 1721/1800/1869
            +f 1752/1843/1900 1723/1802/1871 1722/1801/1870
            +f 1751/1842/1899 1752/1843/1900 1722/1801/1870
            +f 1753/1844/1901 1724/1803/1872 1723/1802/1871
            +f 1752/1843/1900 1753/1844/1901 1723/1802/1871
            +f 1754/1845/1902 1725/1804/1873 1724/1803/1872
            +f 1753/1844/1901 1754/1845/1902 1724/1803/1872
            +f 1755/1846/1903 1726/1805/1874 1725/1847/1875
            +f 1725/1848/1875 1754/1849/1904 1755/1846/1903
            +f 1756/1850/1905 1727/1809/1876 1726/1805/1877
            +f 1755/1846/1906 1756/1850/1905 1726/1805/1877
            +f 1757/1851/1907 1728/1810/1878 1727/1809/1876
            +f 1756/1850/1905 1757/1851/1907 1727/1809/1876
            +f 1757/1851/1907 1758/1852/1908 1728/1810/1878
            +f 1728/1853/1878 1759/1855/1909 1729/1854/1879
            +f 1728/1856/1878 1758/1857/1908 1759/1855/1909
            +f 1760/1858/1910 1730/1812/1880 1729/1811/1879
            +f 1729/1859/1879 1759/1855/1909 1760/1860/1910
            +f 1761/1861/1911 1731/1813/1881 1730/1812/1880
            +f 1760/1858/1910 1761/1861/1911 1730/1812/1880
            +f 1761/1861/1911 1762/1862/1882 1731/1813/1881
            +f 1763/1863/1883 1764/1864/1826 1705/1781/1825
            +f 1765/1865/1884 1766/1866/1885 1706/1782/1827
            +f 1792/1919/1912 1732/1814/1853 1766/1866/1885
            +f 1793/1920/1913 1733/1815/1854 1732/1814/1853
            +f 1792/1919/1912 1793/1920/1913 1732/1814/1853
            +f 1846/1986/1914 1734/1816/1855 1733/1815/1854
            +f 1793/1920/1913 1846/1986/1914 1733/1815/1854
            +f 1794/1921/1915 1735/1817/1856 1734/1816/1855
            +f 1846/1986/1914 1794/1921/1915 1734/1816/1855
            +f 1794/1921/1915 1795/1922/1916 1735/1817/1856
            +f 1767/1867/1917 1736/1818/1886 1735/1817/1856
            +f 1795/1922/1916 1767/1867/1917 1735/1817/1856
            +f 1768/1868/1918 1737/1819/1887 1736/1818/1886
            +f 1767/1867/1917 1768/1868/1918 1736/1818/1886
            +f 1768/1868/1918 1633/1677/1776 1737/1819/1887
            +f 1711/1787/1499 1797/1924/683 1738/1820/1802
            +f 1769/1869/1919 1739/1821/1859 1738/1820/1802
            +f 1797/1924/683 1769/1869/1919 1738/1820/1802
            +f 1769/1869/1919 1740/1822/1888 1739/1821/1859
            +f 1769/1869/1919 1770/1870/1920 1740/1822/1888
            +f 1770/1870/1920 1771/1871/1921 1740/1822/1888
            +f 1771/1871/1921 1741/1823/1889 1740/1822/1888
            +f 1772/1872/1922 1742/1824/1890 1741/1823/1889
            +f 1771/1871/1921 1772/1872/1922 1741/1823/1889
            +f 1773/1873/1923 1743/1825/1891 1742/1824/1890
            +f 1772/1872/1922 1773/1873/1923 1742/1824/1890
            +f 1743/1874/1891 1774/1876/1924 1744/1875/1892
            +f 1743/1877/1891 1773/1878/1923 1774/1876/1924
            +f 1744/1879/1892 1775/1881/1925 1745/1880/1893
            +f 1774/1876/1924 1775/1881/1925 1744/1882/1892
            +f 1776/1883/1926 1746/1830/1894 1745/1884/1893
            +f 1775/1881/1925 1776/1883/1926 1745/1885/1893
            +f 1776/1883/1926 1747/1835/1895 1746/1830/1894
            +f 1777/1886/1927 1748/1837/1896 1747/1835/1895
            +f 1776/1883/1926 1777/1886/1927 1747/1835/1895
            +f 1778/1887/1928 1749/1840/1897 1748/1837/1896
            +f 1777/1886/1927 1778/1887/1928 1748/1837/1896
            +f 1779/1888/1929 1750/1841/1898 1749/1840/1897
            +f 1778/1887/1928 1779/1888/1929 1749/1840/1897
            +f 1780/1889/1930 1751/1842/1899 1750/1841/1898
            +f 1779/1888/1929 1780/1889/1930 1750/1841/1898
            +f 1781/1890/1931 1752/1843/1900 1751/1842/1899
            +f 1780/1889/1930 1781/1890/1931 1751/1842/1899
            +f 1782/1891/1932 1753/1844/1901 1752/1843/1900
            +f 1781/1890/1931 1782/1891/1932 1752/1843/1900
            +f 1783/1892/1933 1754/1845/1902 1753/1844/1901
            +f 1782/1891/1932 1783/1892/1933 1753/1844/1901
            +f 1784/1893/1934 1755/1894/1903 1754/1845/1904
            +f 1783/1892/1935 1784/1893/1934 1754/1845/1904
            +f 1755/1895/1906 1785/1897/1936 1756/1896/1905
            +f 1784/1893/1937 1785/1897/1936 1755/1898/1906
            +f 1756/1899/1905 1786/1901/1938 1757/1900/1907
            +f 1785/1897/1936 1786/1901/1938 1756/1902/1905
            +f 1757/1903/1907 1787/1905/1939 1758/1904/1908
            +f 1786/1901/1938 1787/1905/1939 1757/1906/1907
            +f 1788/1907/1940 1759/1855/1909 1758/1908/1908
            +f 1787/1905/1939 1788/1907/1940 1758/1909/1908
            +f 1789/1910/1941 1760/1911/1910 1759/1855/1909
            +f 1788/1907/1940 1789/1910/1941 1759/1855/1909
            +f 1760/1912/1910 1790/1914/1942 1761/1913/1911
            +f 1789/1910/1941 1790/1914/1942 1760/1915/1910
            +f 1791/1916/1943 1762/1862/1882 1761/1861/1911
            +f 1761/1917/1911 1790/1914/1942 1791/1918/1943
            +f 1842/1982/735 1763/1863/1883 1762/1862/1882
            +f 1791/1916/1943 1842/1982/735 1762/1862/1882
            +f 1817/1951/1944 1765/1865/1884 1764/1864/1826
            +f 1763/1863/1883 1817/1951/1944 1764/1864/1826
            +f 1843/1983/1945 1766/1866/1885 1765/1865/1884
            +f 1843/1983/1945 1792/1919/1912 1766/1866/1885
            +f 1796/1923/1946 1768/1868/1918 1767/1867/1917
            +f 1795/1922/1916 1796/1923/1946 1767/1867/1917
            +f 1796/1923/1946 1633/1677/1776 1768/1868/1918
            +f 1820/1954/684 1797/1924/683 1711/1787/1499
            +f 643/664/688 1769/1869/1919 1797/1924/683
            +f 643/664/688 1798/1925/1947 1769/1869/1919
            +f 1798/1925/1947 1770/1870/1920 1769/1869/1919
            +f 1798/1925/1947 1771/1871/1921 1770/1870/1920
            +f 1798/1925/1947 1799/1926/1948 1771/1871/1921
            +f 1800/1927/1949 1772/1872/1922 1771/1871/1921
            +f 1799/1926/1948 1800/1927/1949 1771/1871/1921
            +f 1772/1928/1922 1801/1930/1950 1773/1929/1923
            +f 1772/1931/1922 1800/1932/1949 1801/1930/1950
            +f 1802/1933/1951 1774/1876/1924 1773/1934/1923
            +f 1801/1930/1950 1802/1933/1951 1773/1935/1923
            +f 1803/1936/1952 1775/1881/1925 1774/1876/1924
            +f 1802/1933/1951 1803/1936/1952 1774/1876/1924
            +f 1804/1937/1953 1776/1883/1926 1775/1881/1925
            +f 1803/1936/1952 1804/1937/1953 1775/1881/1925
            +f 1805/1938/1954 1777/1886/1927 1776/1883/1926
            +f 1804/1937/1953 1805/1938/1954 1776/1883/1926
            +f 1806/1939/1955 1778/1887/1928 1777/1886/1927
            +f 1805/1938/1954 1806/1939/1955 1777/1886/1927
            +f 1807/1940/1956 1779/1888/1929 1778/1887/1928
            +f 1806/1939/1955 1807/1940/1956 1778/1887/1928
            +f 1808/1941/1957 1780/1889/1930 1779/1888/1929
            +f 1807/1940/1956 1808/1941/1957 1779/1888/1929
            +f 1809/1942/1958 1781/1890/1931 1780/1889/1930
            +f 1808/1941/1957 1809/1942/1958 1780/1889/1930
            +f 1810/1943/1959 1782/1891/1932 1781/1890/1931
            +f 1809/1942/1958 1810/1943/1959 1781/1890/1931
            +f 1811/1944/1960 1783/1892/1933 1782/1891/1932
            +f 1810/1943/1959 1811/1944/1960 1782/1891/1932
            +f 1812/1945/1961 1784/1893/1934 1783/1892/1935
            +f 1811/1944/1962 1812/1945/1961 1783/1892/1935
            +f 1812/1945/1963 1785/1897/1936 1784/1893/1937
            +f 1813/1946/1964 1786/1901/1938 1785/1897/1936
            +f 1812/1945/1963 1813/1946/1964 1785/1897/1936
            +f 1813/1946/1964 1787/1905/1939 1786/1901/1938
            +f 1813/1946/1964 1788/1907/1940 1787/1905/1939
            +f 1814/1947/1965 1789/1910/1941 1788/1907/1940
            +f 1813/1946/1964 1814/1947/1965 1788/1907/1940
            +f 1815/1948/1966 1790/1914/1942 1789/1910/1941
            +f 1814/1947/1965 1815/1948/1966 1789/1910/1941
            +f 1816/1949/1967 1791/1950/1943 1790/1914/1942
            +f 1815/1948/1966 1816/1949/1967 1790/1914/1942
            +f 1816/1979/1967 1842/1982/735 1791/1916/1943
            +f 1817/1951/1944 1843/1983/1945 1765/1865/1884
            +f 1844/1984/1968 1792/1919/1912 1843/1983/1945
            +f 1845/1985/1969 1793/1920/1913 1792/1919/1912
            +f 1844/1984/1968 1845/1985/1969 1792/1919/1912
            +f 1845/1985/1969 1846/1986/1914 1793/1920/1913
            +f 1794/1921/1915 1818/1952/1970 1795/1922/1916
            +f 1819/1953/1971 1796/1923/1946 1795/1922/1916
            +f 1818/1952/1970 1819/1953/1971 1795/1922/1916
            +f 1819/1953/1971 1633/1677/1776 1796/1923/1946
            +f 1821/1955/741 1820/1954/684 1633/1677/1776
            +f 694/721/686 643/664/688 1797/1924/683
            +f 1822/1956/1972 1798/1925/1947 643/664/688
            +f 1822/1956/1972 1799/1926/1948 1798/1925/1947
            +f 1822/1956/1972 1823/1957/1973 1799/1926/1948
            +f 1824/1958/1974 1800/1927/1949 1799/1926/1948
            +f 1823/1957/1973 1824/1958/1974 1799/1926/1948
            +f 1825/1959/1975 1801/1930/1950 1800/1960/1949
            +f 1800/1961/1949 1824/1962/1974 1825/1959/1975
            +f 1825/1959/1975 1802/1933/1951 1801/1930/1950
            +f 1826/1963/1976 1803/1936/1952 1802/1933/1951
            +f 1825/1959/1975 1826/1963/1976 1802/1933/1951
            +f 1827/1964/1977 1804/1937/1953 1803/1936/1952
            +f 1826/1963/1976 1827/1964/1977 1803/1936/1952
            +f 1828/1965/1978 1805/1938/1954 1804/1937/1953
            +f 1827/1964/1977 1828/1965/1978 1804/1937/1953
            +f 1829/1966/1979 1806/1939/1955 1805/1938/1954
            +f 1828/1965/1978 1829/1966/1979 1805/1938/1954
            +f 1830/1967/1980 1807/1940/1956 1806/1939/1955
            +f 1829/1966/1979 1830/1967/1980 1806/1939/1955
            +f 1831/1968/1981 1808/1941/1957 1807/1940/1956
            +f 1830/1967/1980 1831/1968/1981 1807/1940/1956
            +f 1832/1969/1982 1809/1942/1958 1808/1941/1957
            +f 1831/1968/1981 1832/1969/1982 1808/1941/1957
            +f 1833/1970/1983 1810/1943/1959 1809/1942/1958
            +f 1832/1969/1982 1833/1970/1983 1809/1942/1958
            +f 1834/1971/1984 1811/1944/1960 1810/1943/1959
            +f 1833/1970/1983 1834/1971/1984 1810/1943/1959
            +f 1835/1972/1985 1812/1945/1961 1811/1944/1962
            +f 1834/1971/1986 1835/1972/1985 1811/1944/1962
            +f 1835/1972/1987 1836/1973/1988 1812/1945/1963
            +f 1837/1974/1989 1813/1946/1964 1812/1945/1963
            +f 1836/1973/1988 1837/1974/1989 1812/1945/1963
            +f 1838/1975/1990 1814/1947/1965 1813/1946/1964
            +f 1837/1974/1989 1838/1975/1990 1813/1946/1964
            +f 1839/1976/1991 1815/1948/1966 1814/1947/1965
            +f 1838/1975/1990 1839/1976/1991 1814/1947/1965
            +f 1840/1977/1992 1816/1949/1967 1815/1948/1966
            +f 1839/1976/1991 1840/1977/1992 1815/1948/1966
            +f 1816/1980/1967 1840/1981/1992 1841/1978/1993
            +f 1841/1978/1993 1842/1982/735 1816/1979/1967
            +f 684/711/734 1817/1951/1944 1763/1863/1883
            +f 1842/1982/735 684/711/734 1763/1863/1883
            +f 1847/1987/1994 1818/1952/1970 1794/1921/1915
            +f 1848/1988/1995 1819/1953/1971 1818/1952/1970
            +f 1847/1987/1994 1848/1988/1995 1818/1952/1970
            +f 1821/1955/741 1633/1677/1776 1819/1953/1971
            +f 1848/1988/1995 1821/1955/741 1819/1953/1971
            +f 965/1009/742 1820/1954/684 1821/1955/741
            +f 645/666/690 1822/1956/1972 643/664/688
            +f 645/666/690 647/668/691 1822/1956/1972
            +f 647/668/691 1823/1957/1973 1822/1956/1972
            +f 649/670/694 1824/1958/1974 1823/1957/1973
            +f 647/668/691 649/670/694 1823/1957/1973
            +f 651/675/696 1825/1959/1975 1824/1989/1974
            +f 1824/1990/1974 649/1991/694 651/675/696
            +f 653/677/698 1826/1963/1976 1825/1959/1975
            +f 651/675/696 653/677/698 1825/1959/1975
            +f 655/679/700 1827/1964/1977 1826/1963/1976
            +f 653/677/698 655/679/700 1826/1963/1976
            +f 657/681/702 1828/1965/1978 1827/1964/1977
            +f 655/679/700 657/681/702 1827/1964/1977
            +f 659/683/704 1829/1966/1979 1828/1965/1978
            +f 657/681/702 659/683/704 1828/1965/1978
            +f 661/685/706 1830/1967/1980 1829/1966/1979
            +f 659/683/704 661/685/706 1829/1966/1979
            +f 663/687/708 1831/1968/1981 1830/1967/1980
            +f 661/685/706 663/687/708 1830/1967/1980
            +f 665/689/710 1832/1969/1982 1831/1968/1981
            +f 663/687/708 665/689/710 1831/1968/1981
            +f 667/691/712 1833/1970/1983 1832/1969/1982
            +f 665/689/710 667/691/712 1832/1969/1982
            +f 669/693/714 1834/1971/1984 1833/1970/1983
            +f 667/691/712 669/693/714 1833/1970/1983
            +f 671/695/716 1835/1972/1985 1834/1971/1986
            +f 669/693/717 671/695/716 1834/1971/1986
            +f 673/697/720 1836/1973/1988 1835/1972/1987
            +f 671/695/721 673/697/720 1835/1972/1987
            +f 675/699/724 1837/1974/1989 1836/1973/1988
            +f 673/697/720 675/699/724 1836/1973/1988
            +f 677/701/726 1838/1975/1990 1837/1974/1989
            +f 675/699/724 677/701/726 1837/1974/1989
            +f 679/703/728 1839/1976/1991 1838/1975/1990
            +f 677/701/726 679/703/728 1838/1975/1990
            +f 681/705/730 1840/1977/1992 1839/1976/1991
            +f 679/703/728 681/705/730 1839/1976/1991
            +f 683/710/732 1841/1978/1993 1840/1992/1992
            +f 1840/1993/1992 681/1994/730 683/710/732
            +f 683/710/732 1842/1982/735 1841/1978/1993
            +f 685/712/766 1843/1983/1945 1817/1951/1944
            +f 684/711/734 685/712/766 1817/1951/1944
            +f 686/713/768 1844/1984/1968 1843/1983/1945
            +f 685/712/766 686/713/768 1843/1983/1945
            +f 687/714/770 1845/1985/1969 1844/1984/1968
            +f 686/713/768 687/714/770 1844/1984/1968
            +f 688/715/772 1846/1986/1914 1845/1985/1969
            +f 687/714/770 688/715/772 1845/1985/1969
            +f 689/716/738 1794/1921/1915 1846/1986/1914
            +f 688/715/772 689/716/738 1846/1986/1914
            +f 691/718/737 1847/1987/1994 1794/1921/1915
            +f 689/716/738 691/718/737 1794/1921/1915
            +f 693/720/740 1848/1988/1995 1847/1987/1994
            +f 691/718/737 693/720/740 1847/1987/1994
            +f 693/720/740 1821/1955/741 1848/1988/1995
            +f 2391/2537/1996 2392/2538/1997 2393/2539/1998
            +f 2394/2540/1999 2395/2541/2000 2396/2542/2001
            +f 606/608/625 1569/1613/1709 607/607/626
            +f 607/607/626 1569/1613/1709 608/609/627
            +f 608/609/627 1569/1613/1709 609/611/628
            +f 609/611/628 1569/1613/1709 628/614/629
            +f 2397/2543/2002 2398/2544/2003 2399/2545/2004
            +f 2400/2546/2005 2401/2547/2006 2402/2548/2007
            +f 2403/2549/2008 2404/2550/2009 2405/2551/2010
            +f 2406/2552/2011 2407/2553/2012 2408/2554/2013
            +f 2409/2555/2014 2410/2556/2015 2411/2557/2016
            +f 2412/2558/2017 2413/2559/2018 2414/2560/2019
            +f 2415/2561/2020 2416/2562/2021 2417/2563/2022
            +f 2418/2564/2023 2419/2565/2024 2420/2566/2025
            +f 2421/2567/2026 2422/2568/2027 2423/2569/2028
            +f 2424/2570/2029 2425/2571/2030 2426/2572/2031
            +f 2427/2573/2032 2428/2574/2033 2429/2575/2034
            +f 2430/2576/2035 2431/2577/2036 2432/2578/2037
            +f 2433/2579/2038 2434/2580/2039 2435/2581/2040
            +f 2436/2582/2041 2437/2583/2042 2438/2584/2043
            +f 2439/2585/2044 2440/2586/2045 2441/2587/2046
            +f 2442/2588/2047 2443/2589/2048 2444/2590/2049
            +f 2445/2591/2050 2446/2592/2051 2447/2593/2052
            +f 2448/2594/2053 2449/2595/2054 2450/2596/2055
            +f 2451/2597/2056 2452/2598/2057 2453/2599/2058
            +f 2454/2600/2059 2455/2601/2060 2456/2602/2061
            +f 1522/1566/1646 8/8/5 630/649/669
            +f 628/614/629 1569/1613/1709 629/648/670
            +f 629/648/670 1569/1613/1709 631/650/671
            +f 1522/1566/1646 630/649/669 633/652/672
            +f 631/650/671 1569/1613/1709 632/651/673
            +f 1497/1541/1621 1522/1566/1646 635/654/674
            +f 1522/1566/1646 633/652/672 635/654/674
            +f 1569/1613/1709 1597/1641/1735 634/653/675
            +f 632/651/673 1569/1613/1709 634/653/675
            +f 635/654/674 639/658/676 1497/1541/1621
            +f 1523/1567/1647 1497/1541/1621 639/658/676
            +f 1571/1615/2062 636/655/677 1597/1641/1735
            +f 1597/1641/1735 636/655/677 634/653/675
            +f 636/655/677 1571/1615/2062 637/656/678
            +f 638/657/679 1548/1592/2063 1523/1567/1647
            +f 1548/1592/2063 638/657/679 640/660/680
            +f 638/657/679 1523/1567/1647 639/658/676
            +f 642/659/285 1571/1615/2062 1548/1592/2064
            +f 637/656/678 1571/1615/2062 642/659/285
            +f 642/659/285 1548/1592/2064 641/663/681
            +f 641/663/2065 1548/1592/2066 621/636/2067
            +f 1851/1995/2068 1850/1996/2069 1849/1997/2070
            +f 1852/1998/2071 1851/1995/2068 1849/1997/2070
            +f 1853/1999/2072 1852/1998/2071 1849/1997/2070
            +f 1854/2000/2073 1853/1999/2072 1849/1997/2070
            +f 1855/2001/2074 1854/2000/2073 1849/1997/2070
            +f 1855/2001/2074 1849/1997/2070 1859/2002/2075
            +f 1855/2001/2074 1859/2002/2075 1858/2003/2076
            +f 1855/2001/2074 1858/2003/2076 1857/2004/2077
            +f 1855/2001/2074 1857/2004/2077 1856/2005/2078
            +f 1849/1997/2070 1850/1996/2069 1861/2006/2079
            +f 1849/1997/2070 1861/2006/2079 1860/2007/2080
            +f 1850/1996/2069 1851/1995/2068 1862/2008/2081
            +f 1850/1996/2069 1862/2008/2081 1861/2006/2079
            +f 1851/1995/2068 1852/1998/2071 1863/2009/2082
            +f 1851/1995/2068 1863/2009/2082 1862/2008/2081
            +f 1852/1998/2071 1853/1999/2072 1864/2010/2083
            +f 1853/1999/2072 1865/2011/2084 1864/2010/2083
            +f 1853/1999/2072 1854/2000/2073 1866/2012/2085
            +f 1853/1999/2072 1866/2012/2085 1865/2011/2084
            +f 1854/2000/2073 1855/2001/2074 1867/2013/2086
            +f 1854/2000/2073 1867/2013/2086 1866/2012/2085
            +f 1855/2001/2074 1856/2005/2078 1868/2014/2087
            +f 1855/2001/2074 1868/2014/2087 1867/2013/2086
            +f 1856/2005/2078 1857/2004/2077 1869/2015/2088
            +f 1856/2005/2078 1869/2015/2088 1868/2014/2087
            +f 1857/2004/2077 1858/2003/2076 1870/2016/2089
            +f 1857/2004/2077 1870/2016/2089 1869/2015/2088
            +f 1858/2003/2076 1871/2017/2090 1870/2016/2089
            +f 1858/2003/2076 1859/2002/2075 1872/2018/2091
            +f 1858/2003/2076 1872/2018/2091 1871/2017/2090
            +f 1859/2002/2075 1849/1997/2070 1860/2007/2080
            +f 1859/2002/2075 1860/2007/2080 1872/2018/2091
            +f 1860/2007/2080 1861/2006/2079 1882/2029/2092
            +f 1863/2009/2082 1852/1998/2071 1873/2019/2093
            +f 1852/1998/2071 1864/2010/2083 1874/2020/2094
            +f 1852/1998/2071 1874/2020/2094 1873/2019/2093
            +f 1864/2010/2083 1865/2011/2084 1875/2021/2095
            +f 1864/2010/2083 1875/2021/2095 1874/2020/2094
            +f 1865/2011/2084 1866/2012/2085 1876/2022/2096
            +f 1865/2011/2084 1876/2022/2096 1875/2021/2095
            +f 1866/2012/2085 1867/2013/2086 1877/2023/2097
            +f 1866/2012/2085 1877/2023/2097 1876/2022/2096
            +f 1867/2013/2086 1868/2014/2087 1878/2024/2098
            +f 1867/2013/2086 1878/2024/2098 1877/2023/2097
            +f 1868/2014/2087 1869/2015/2088 1878/2024/2098
            +f 1869/2015/2088 1870/2016/2089 1879/2025/2099
            +f 1870/2016/2089 1871/2017/2090 1880/2026/2100
            +f 1870/2016/2089 1880/2026/2100 1879/2025/2099
            +f 1871/2017/2090 1872/2018/2091 1881/2027/2101
            +f 1871/2017/2090 1881/2027/2101 1880/2026/2100
            +f 1872/2018/2091 1860/2007/2080 1882/2029/2092
            +f 1872/2018/2091 1882/2029/2092 1881/2027/2101
            +f 1882/2029/2092 1861/2006/2079 1883/2028/2102
            +f 1861/2006/2079 1862/2008/2081 1884/2030/2103
            +f 1861/2006/2079 1884/2030/2103 1883/2028/2102
            +f 1862/2008/2081 1863/2009/2082 1885/2031/2104
            +f 1862/2008/2081 1885/2031/2104 1884/2030/2103
            +f 1863/2009/2082 1873/2019/2093 1885/2031/2104
            +f 1875/2021/2095 1876/2022/2096 1886/2032/2105
            +f 1876/2022/2096 1877/2023/2097 1887/2033/2106
            +f 1876/2022/2096 1887/2033/2106 1886/2032/2105
            +f 1877/2023/2097 1878/2024/2098 1887/2033/2106
            +f 1878/2024/2098 1869/2015/2088 1888/2034/2107
            +f 1869/2015/2088 1879/2025/2099 1888/2034/2107
            +f 1882/2029/2092 1883/2028/2102 1890/2035/2108
            +f 1882/2029/2092 1890/2035/2108 1889/2036/2109
            +f 1883/2028/2102 1884/2030/2103 1890/2035/2108
            +f 1873/2019/2093 1874/2020/2094 1891/2037/2110
            +f 1874/2020/2094 1875/2021/2095 1891/2037/2110
            +f 1875/2021/2095 1886/2032/2105 1892/2038/2111
            +f 1886/2032/2105 1887/2033/2106 1893/2039/2112
            +f 1886/2032/2105 1893/2039/2112 1892/2038/2111
            +f 1887/2033/2106 1878/2024/2098 1893/2039/2112
            +f 1881/2027/2101 1882/2029/2092 1889/2036/2109
            +f 1889/2036/2109 1890/2035/2108 1895/2040/2113
            +f 1889/2036/2109 1895/2040/2113 1894/2041/2114
            +f 1890/2035/2108 1884/2030/2103 1896/2042/2115
            +f 1890/2035/2108 1896/2042/2115 1895/2040/2113
            +f 1884/2030/2103 1885/2031/2104 1896/2042/2115
            +f 1885/2031/2104 1873/2019/2093 1897/2043/2116
            +f 1873/2019/2093 1891/2037/2110 1897/2043/2116
            +f 1891/2037/2110 1875/2021/2095 1898/2044/2117
            +f 1875/2021/2095 1892/2038/2111 1899/2045/2118
            +f 1875/2021/2095 1899/2045/2118 1898/2044/2117
            +f 1892/2038/2111 1893/2039/2112 1900/2046/2119
            +f 1892/2038/2111 1900/2046/2119 1899/2045/2118
            +f 1893/2039/2112 1878/2024/2098 1901/2047/2120
            +f 1893/2039/2112 1901/2047/2120 1900/2046/2119
            +f 1878/2024/2098 1888/2034/2107 1901/2047/2120
            +f 1888/2034/2107 1879/2025/2099 1902/2048/2121
            +f 1879/2025/2099 1880/2026/2100 1903/2049/2122
            +f 1879/2025/2099 1903/2049/2122 1902/2048/2121
            +f 1880/2026/2100 1881/2027/2101 1904/2050/2123
            +f 1880/2026/2100 1904/2050/2123 1903/2049/2122
            +f 1881/2027/2101 1889/2036/2109 1894/2041/2114
            +f 1881/2027/2101 1894/2041/2114 1904/2050/2123
            +f 1894/2041/2114 1895/2040/2113 1906/2051/2124
            +f 1894/2041/2114 1906/2051/2124 1905/2052/2125
            +f 1895/2040/2113 1896/2042/2115 1907/2053/2126
            +f 1895/2040/2113 1907/2053/2126 1906/2051/2124
            +f 1896/2042/2115 1885/2031/2104 1908/2054/2127
            +f 1896/2042/2115 1908/2054/2127 1907/2053/2126
            +f 1885/2031/2104 1897/2043/2116 1908/2054/2127
            +f 1898/2044/2117 1899/2045/2118 1909/2055/2128
            +f 1899/2045/2118 1900/2046/2119 1910/2056/2129
            +f 1899/2045/2118 1910/2056/2129 1909/2055/2128
            +f 1900/2046/2119 1901/2047/2120 1911/2057/2130
            +f 1900/2046/2119 1911/2057/2130 1910/2056/2129
            +f 1901/2047/2120 1888/2034/2107 1912/2058/2131
            +f 1901/2047/2120 1912/2058/2131 1911/2057/2130
            +f 1888/2034/2107 1902/2048/2121 1912/2058/2131
            +f 1902/2048/2121 1903/2049/2122 1913/2059/2132
            +f 1903/2049/2122 1904/2050/2123 1914/2060/2133
            +f 1903/2049/2122 1914/2060/2133 1913/2059/2132
            +f 1904/2050/2123 1894/2041/2114 1905/2052/2125
            +f 1904/2050/2123 1905/2052/2125 1914/2060/2133
            +f 1905/2052/2125 1906/2051/2124 1916/2061/2134
            +f 1905/2052/2125 1916/2061/2134 1915/2062/2135
            +f 1906/2051/2124 1907/2053/2126 1916/2061/2134
            +f 1908/2054/2127 1897/2043/2116 1917/2063/2136
            +f 1897/2043/2116 1891/2037/2110 1938/2084/2137
            +f 1897/2043/2116 1938/2084/2137 1917/2063/2136
            +f 1891/2037/2110 1898/2044/2117 1918/2064/2138
            +f 1891/2037/2110 1918/2064/2138 1938/2084/2137
            +f 1898/2044/2117 1909/2055/2128 1919/2065/2139
            +f 1898/2044/2117 1919/2065/2139 1918/2064/2138
            +f 1909/2055/2128 1910/2056/2129 1920/2066/2140
            +f 1909/2055/2128 1920/2066/2140 1919/2065/2139
            +f 1910/2056/2129 1911/2057/2130 1920/2066/2140
            +f 1912/2058/2131 1902/2048/2121 1921/2067/2141
            +f 1902/2048/2121 1913/2059/2132 1921/2067/2141
            +f 1913/2059/2132 1914/2060/2133 1922/2068/2142
            +f 1914/2060/2133 1905/2052/2125 1915/2062/2135
            +f 1914/2060/2133 1915/2062/2135 1922/2068/2142
            +f 1915/2062/2135 1916/2061/2134 1924/2069/2143
            +f 1915/2062/2135 1924/2069/2143 1923/2070/2144
            +f 1916/2061/2134 1907/2053/2126 1925/2071/2145
            +f 1916/2061/2134 1925/2071/2145 1924/2069/2143
            +f 1907/2053/2126 1908/2054/2127 1926/2072/2146
            +f 1907/2053/2126 1926/2072/2146 1925/2071/2145
            +f 1908/2054/2127 1917/2063/2136 1926/2072/2146
            +f 1918/2064/2138 1919/2065/2139 1927/2073/2147
            +f 1919/2065/2139 1920/2066/2140 1928/2074/2148
            +f 1919/2065/2139 1928/2074/2148 1927/2073/2147
            +f 1920/2066/2140 1911/2057/2130 1929/2075/2149
            +f 1920/2066/2140 1929/2075/2149 1928/2074/2148
            +f 1911/2057/2130 1912/2058/2131 1930/2076/2150
            +f 1911/2057/2130 1930/2076/2150 1929/2075/2149
            +f 1912/2058/2131 1921/2067/2141 1930/2076/2150
            +f 1921/2067/2141 1913/2059/2132 1931/2077/2151
            +f 1913/2059/2132 1922/2068/2142 1931/2077/2151
            +f 1922/2068/2142 1915/2062/2135 1923/2070/2144
            +f 1923/2070/2144 1924/2069/2143 1933/2078/2152
            +f 1923/2070/2144 1933/2078/2152 1932/2079/2153
            +f 1924/2069/2143 1925/2071/2145 1934/2080/2154
            +f 1924/2069/2143 1934/2080/2154 1933/2078/2152
            +f 1925/2071/2145 1926/2072/2146 1935/2081/2155
            +f 1925/2071/2145 1935/2081/2155 1934/2080/2154
            +f 1926/2072/2146 1917/2063/2136 1936/2082/2156
            +f 1926/2072/2146 1936/2082/2156 1935/2081/2155
            +f 1917/2063/2136 1938/2084/2137 1937/2083/2157
            +f 1917/2063/2136 1937/2083/2157 1936/2082/2156
            +f 1918/2064/2138 1927/2073/2147 1939/2085/2158
            +f 1918/2064/2138 1939/2085/2158 1938/2084/2137
            +f 1927/2073/2147 1928/2074/2148 1940/2086/2159
            +f 1927/2073/2147 1940/2086/2159 1939/2085/2158
            +f 1928/2074/2148 1929/2075/2149 1940/2086/2159
            +f 1930/2076/2150 1921/2067/2141 1941/2087/2160
            +f 1921/2067/2141 1931/2077/2151 1941/2087/2160
            +f 1931/2077/2151 1922/2068/2142 1942/2088/2161
            +f 1922/2068/2142 1923/2070/2144 1932/2079/2153
            +f 1922/2068/2142 1932/2079/2153 1942/2088/2161
            +f 1932/2079/2153 1933/2078/2152 1944/2089/2162
            +f 1932/2079/2153 1944/2089/2162 1943/2090/2163
            +f 1933/2078/2152 1934/2080/2154 1945/2091/2164
            +f 1933/2078/2152 1945/2091/2164 1944/2089/2162
            +f 1934/2080/2154 1935/2081/2155 1945/2091/2164
            +f 1937/2083/2157 1938/2084/2137 1946/2092/2165
            +f 1938/2084/2137 1939/2085/2158 1947/2093/2166
            +f 1938/2084/2137 1947/2093/2166 1946/2092/2165
            +f 1939/2085/2158 1940/2086/2159 1948/2094/2167
            +f 1939/2085/2158 1948/2094/2167 1947/2093/2166
            +f 1940/2086/2159 1929/2075/2149 1949/2095/2168
            +f 1940/2086/2159 1949/2095/2168 1948/2094/2167
            +f 1929/2075/2149 1930/2076/2150 1950/2096/2169
            +f 1929/2075/2149 1950/2096/2169 1949/2095/2168
            +f 1930/2076/2150 1941/2087/2160 1950/2096/2169
            +f 1941/2087/2160 1931/2077/2151 1951/2097/2170
            +f 1931/2077/2151 1942/2088/2161 1952/2098/2171
            +f 1931/2077/2151 1952/2098/2171 1951/2097/2170
            +f 1942/2088/2161 1932/2079/2153 1943/2090/2163
            +f 1942/2088/2161 1943/2090/2163 1952/2098/2171
            +f 1943/2090/2163 1944/2089/2162 1954/2099/2172
            +f 1943/2090/2163 1954/2099/2172 1953/2100/2173
            +f 1944/2089/2162 1945/2091/2164 1954/2099/2172
            +f 1945/2091/2164 1935/2081/2155 1955/2101/2174
            +f 1935/2081/2155 1936/2082/2156 1955/2101/2174
            +f 1936/2082/2156 1937/2083/2157 1956/2102/2175
            +f 1937/2083/2157 1946/2092/2165 1957/2103/2176
            +f 1937/2083/2157 1957/2103/2176 1956/2102/2175
            +f 1946/2092/2165 1947/2093/2166 1958/2104/2177
            +f 1946/2092/2165 1958/2104/2177 1957/2103/2176
            +f 1947/2093/2166 1948/2094/2167 1959/2105/2178
            +f 1947/2093/2166 1959/2105/2178 1958/2104/2177
            +f 1948/2094/2167 1949/2095/2168 1959/2105/2178
            +f 1950/2096/2169 1941/2087/2160 1960/2106/2179
            +f 1941/2087/2160 1951/2097/2170 1960/2106/2179
            +f 1951/2097/2170 1952/2098/2171 1961/2107/2180
            +f 1952/2098/2171 1943/2090/2163 1953/2100/2173
            +f 1952/2098/2171 1953/2100/2173 1961/2107/2180
            +f 1953/2100/2173 1954/2099/2172 1962/2108/2181
            +f 1953/2100/2173 1962/2108/2181 1970/2116/2182
            +f 1954/2099/2172 1945/2091/2164 1963/2109/2183
            +f 1954/2099/2172 1963/2109/2183 1962/2108/2181
            +f 1945/2091/2164 1955/2101/2174 1963/2109/2183
            +f 1955/2101/2174 1936/2082/2156 1964/2110/2184
            +f 1936/2082/2156 1956/2102/2175 1964/2110/2184
            +f 1957/2103/2176 1958/2104/2177 1965/2111/2185
            +f 1958/2104/2177 1959/2105/2178 1966/2112/2186
            +f 1958/2104/2177 1966/2112/2186 1965/2111/2185
            +f 1959/2105/2178 1949/2095/2168 1967/2113/2187
            +f 1959/2105/2178 1967/2113/2187 1966/2112/2186
            +f 1949/2095/2168 1950/2096/2169 1968/2114/2188
            +f 1949/2095/2168 1968/2114/2188 1967/2113/2187
            +f 1950/2096/2169 1960/2106/2179 1968/2114/2188
            +f 1960/2106/2179 1951/2097/2170 1969/2115/2189
            +f 1951/2097/2170 1961/2107/2180 1969/2115/2189
            +f 1961/2107/2180 1953/2100/2173 1970/2116/2182
            +f 1962/2108/2181 1963/2109/2183 1971/2117/2190
            +f 1963/2109/2183 1955/2101/2174 1972/2118/2191
            +f 1963/2109/2183 1972/2118/2191 1971/2117/2190
            +f 1955/2101/2174 1964/2110/2184 1972/2118/2191
            +f 1964/2110/2184 1956/2102/2175 1988/2134/2192
            +f 1956/2102/2175 1957/2103/2176 1973/2119/2193
            +f 1956/2102/2175 1973/2119/2193 1988/2134/2192
            +f 1957/2103/2176 1965/2111/2185 1973/2119/2193
            +f 1968/2114/2188 1960/2106/2179 1974/2120/2194
            +f 1960/2106/2179 1969/2115/2189 1974/2120/2194
            +f 1969/2115/2189 1961/2107/2180 1975/2121/2195
            +f 1961/2107/2180 1970/2116/2182 1975/2121/2195
            +f 1970/2116/2182 1962/2108/2181 1977/2122/2196
            +f 1970/2116/2182 1977/2122/2196 1976/2123/2197
            +f 1962/2108/2181 1971/2117/2190 1977/2122/2196
            +f 1972/2118/2191 1964/2110/2184 1978/2124/2198
            +f 1964/2110/2184 1988/2134/2192 1978/2124/2198
            +f 1973/2119/2193 1965/2111/2185 1979/2125/2199
            +f 1965/2111/2185 1966/2112/2186 1980/2126/2200
            +f 1965/2111/2185 1980/2126/2200 1979/2125/2199
            +f 1966/2112/2186 1967/2113/2187 1981/2127/2201
            +f 1966/2112/2186 1981/2127/2201 1980/2126/2200
            +f 1967/2113/2187 1968/2114/2188 1982/2128/2202
            +f 1967/2113/2187 1982/2128/2202 1981/2127/2201
            +f 1968/2114/2188 1974/2120/2194 1982/2128/2202
            +f 1974/2120/2194 1969/2115/2189 1983/2129/2203
            +f 1969/2115/2189 1975/2121/2195 1983/2129/2203
            +f 1975/2121/2195 1970/2116/2182 1976/2123/2197
            +f 1976/2123/2197 1977/2122/2196 1985/2130/2204
            +f 1976/2123/2197 1985/2130/2204 1984/2131/2205
            +f 1977/2122/2196 1971/2117/2190 1986/2132/2206
            +f 1977/2122/2196 1986/2132/2206 1985/2130/2204
            +f 1971/2117/2190 1972/2118/2191 1986/2132/2206
            +f 1978/2124/2198 1988/2134/2192 1987/2133/2207
            +f 1973/2119/2193 1979/2125/2199 1989/2135/2208
            +f 1973/2119/2193 1989/2135/2208 1988/2134/2192
            +f 1979/2125/2199 1980/2126/2200 1990/2136/2209
            +f 1979/2125/2199 1990/2136/2209 1989/2135/2208
            +f 1980/2126/2200 1981/2127/2201 2000/2146/2210
            +f 1980/2126/2200 2000/2146/2210 1990/2136/2209
            +f 1981/2127/2201 1982/2128/2202 2000/2146/2210
            +f 1983/2129/2203 1975/2121/2195 1991/2137/2211
            +f 1975/2121/2195 1976/2123/2197 1984/2131/2205
            +f 1975/2121/2195 1984/2131/2205 1991/2137/2211
            +f 1984/2131/2205 1985/2130/2204 1993/2138/2212
            +f 1984/2131/2205 1993/2138/2212 1992/2139/2213
            +f 1985/2130/2204 1986/2132/2206 1994/2140/2214
            +f 1985/2130/2204 1994/2140/2214 1993/2138/2212
            +f 1986/2132/2206 1972/2118/2191 1995/2141/2215
            +f 1986/2132/2206 1995/2141/2215 1994/2140/2214
            +f 1972/2118/2191 1978/2124/2198 1995/2141/2215
            +f 1987/2133/2207 1988/2134/2192 1996/2142/2216
            +f 1988/2134/2192 1989/2135/2208 1997/2143/2217
            +f 1988/2134/2192 1997/2143/2217 1996/2142/2216
            +f 1989/2135/2208 1990/2136/2209 1998/2144/2218
            +f 1989/2135/2208 1998/2144/2218 1997/2143/2217
            +f 1990/2136/2209 2000/2146/2210 1999/2145/2219
            +f 1990/2136/2209 1999/2145/2219 1998/2144/2218
            +f 1982/2128/2202 1974/2120/2194 2001/2147/2220
            +f 1982/2128/2202 2001/2147/2220 2000/2146/2210
            +f 1974/2120/2194 1983/2129/2203 2002/2148/2221
            +f 1974/2120/2194 2002/2148/2221 2001/2147/2220
            +f 1983/2129/2203 1991/2137/2211 2003/2149/2222
            +f 1983/2129/2203 2003/2149/2222 2002/2148/2221
            +f 1991/2137/2211 1984/2131/2205 1992/2139/2213
            +f 1991/2137/2211 1992/2139/2213 2003/2149/2222
            +f 1992/2139/2213 1993/2138/2212 2005/2150/2223
            +f 1992/2139/2213 2005/2150/2223 2004/2151/2224
            +f 1993/2138/2212 1994/2140/2214 2005/2150/2223
            +f 1995/2141/2215 1978/2124/2198 2006/2152/2225
            +f 1978/2124/2198 1987/2133/2207 2007/2153/2226
            +f 1978/2124/2198 2007/2153/2226 2006/2152/2225
            +f 1987/2133/2207 1996/2142/2216 2007/2153/2226
            +f 1996/2142/2216 1997/2143/2217 2008/2154/2227
            +f 1997/2143/2217 1998/2144/2218 2009/2155/2228
            +f 1997/2143/2217 2009/2155/2228 2008/2154/2227
            +f 1998/2144/2218 1999/2145/2219 2009/2155/2228
            +f 2001/2147/2220 2002/2148/2221 2010/2156/2229
            +f 2002/2148/2221 2003/2149/2222 2011/2157/2230
            +f 2002/2148/2221 2011/2157/2230 2010/2156/2229
            +f 2003/2149/2222 1992/2139/2213 2004/2151/2224
            +f 2003/2149/2222 2004/2151/2224 2011/2157/2230
            +f 2004/2151/2224 2005/2150/2223 2013/2158/2231
            +f 2004/2151/2224 2013/2158/2231 2012/2159/2232
            +f 2005/2150/2223 1994/2140/2214 2014/2160/2233
            +f 2005/2150/2223 2014/2160/2233 2013/2158/2231
            +f 1994/2140/2214 1995/2141/2215 2015/2161/2234
            +f 1994/2140/2214 2015/2161/2234 2014/2160/2233
            +f 1995/2141/2215 2006/2152/2225 2015/2161/2234
            +f 2007/2153/2226 1996/2142/2216 2016/2162/2235
            +f 1996/2142/2216 2008/2154/2227 2017/2163/2236
            +f 1996/2142/2216 2017/2163/2236 2016/2162/2235
            +f 2008/2154/2227 2009/2155/2228 2018/2164/2237
            +f 2008/2154/2227 2018/2164/2237 2017/2163/2236
            +f 2009/2155/2228 1999/2145/2219 2019/2165/2238
            +f 2009/2155/2228 2019/2165/2238 2018/2164/2237
            +f 1999/2145/2219 2000/2146/2210 2020/2166/2239
            +f 1999/2145/2219 2020/2166/2239 2019/2165/2238
            +f 2000/2146/2210 2001/2147/2220 2021/2167/2240
            +f 2000/2146/2210 2021/2167/2240 2020/2166/2239
            +f 2001/2147/2220 2010/2156/2229 2021/2167/2240
            +f 2011/2157/2230 2004/2151/2224 2012/2159/2232
            +f 2012/2159/2232 2013/2158/2231 2023/2168/2241
            +f 2012/2159/2232 2023/2168/2241 2022/2169/2242
            +f 2013/2158/2231 2014/2160/2233 2024/2170/2243
            +f 2013/2158/2231 2024/2170/2243 2023/2168/2241
            +f 2014/2160/2233 2015/2161/2234 2025/2171/2244
            +f 2014/2160/2233 2025/2171/2244 2024/2170/2243
            +f 2015/2161/2234 2006/2152/2225 2048/2194/2245
            +f 2015/2161/2234 2048/2194/2245 2025/2171/2244
            +f 2006/2152/2225 2007/2153/2226 2026/2172/2246
            +f 2006/2152/2225 2026/2172/2246 2048/2194/2245
            +f 2007/2153/2226 2016/2162/2235 2027/2173/2247
            +f 2007/2153/2226 2027/2173/2247 2026/2172/2246
            +f 2016/2162/2235 2017/2163/2236 2028/2174/2248
            +f 2016/2162/2235 2028/2174/2248 2027/2173/2247
            +f 2017/2163/2236 2018/2164/2237 2029/2175/2249
            +f 2017/2163/2236 2029/2175/2249 2028/2174/2248
            +f 2018/2164/2237 2019/2165/2238 2030/2176/2250
            +f 2018/2164/2237 2030/2176/2250 2029/2175/2249
            +f 2019/2165/2238 2020/2166/2239 2041/2187/2251
            +f 2019/2165/2238 2041/2187/2251 2030/2176/2250
            +f 2020/2166/2239 2021/2167/2240 2041/2187/2251
            +f 2021/2167/2240 2010/2156/2229 2031/2177/2252
            +f 2010/2156/2229 2011/2157/2230 2032/2178/2253
            +f 2010/2156/2229 2032/2178/2253 2031/2177/2252
            +f 2011/2157/2230 2012/2159/2232 2022/2169/2242
            +f 2011/2157/2230 2022/2169/2242 2032/2178/2253
            +f 2022/2169/2242 2023/2168/2241 2034/2179/2254
            +f 2022/2169/2242 2034/2179/2254 2033/2180/2255
            +f 2023/2168/2241 2024/2170/2243 2035/2181/2256
            +f 2023/2168/2241 2035/2181/2256 2034/2179/2254
            +f 2024/2170/2243 2025/2171/2244 2036/2182/2257
            +f 2024/2170/2243 2036/2182/2257 2035/2181/2256
            +f 2025/2171/2244 2048/2194/2245 2036/2182/2257
            +f 2026/2172/2246 2027/2173/2247 2037/2183/2258
            +f 2027/2173/2247 2028/2174/2248 2038/2184/2259
            +f 2027/2173/2247 2038/2184/2259 2037/2183/2258
            +f 2028/2174/2248 2029/2175/2249 2039/2185/2260
            +f 2028/2174/2248 2039/2185/2260 2038/2184/2259
            +f 2029/2175/2249 2030/2176/2250 2040/2186/2261
            +f 2029/2175/2249 2040/2186/2261 2039/2185/2260
            +f 2030/2176/2250 2041/2187/2251 2054/2200/2262
            +f 2030/2176/2250 2054/2200/2262 2040/2186/2261
            +f 2021/2167/2240 2031/2177/2252 2041/2187/2251
            +f 2031/2177/2252 2032/2178/2253 2042/2188/2263
            +f 2032/2178/2253 2022/2169/2242 2033/2180/2255
            +f 2032/2178/2253 2033/2180/2255 2042/2188/2263
            +f 2033/2180/2255 2034/2179/2254 2044/2189/2264
            +f 2033/2180/2255 2044/2189/2264 2043/2190/2265
            +f 2034/2179/2254 2035/2181/2256 2045/2191/2266
            +f 2034/2179/2254 2045/2191/2266 2044/2189/2264
            +f 2035/2181/2256 2036/2182/2257 2046/2192/2267
            +f 2035/2181/2256 2046/2192/2267 2045/2191/2266
            +f 2036/2182/2257 2048/2194/2245 2047/2193/2268
            +f 2036/2182/2257 2047/2193/2268 2046/2192/2267
            +f 2026/2172/2246 2037/2183/2258 2049/2195/2269
            +f 2026/2172/2246 2049/2195/2269 2048/2194/2245
            +f 2037/2183/2258 2038/2184/2259 2050/2196/2270
            +f 2037/2183/2258 2050/2196/2270 2049/2195/2269
            +f 2038/2184/2259 2039/2185/2260 2051/2197/2271
            +f 2038/2184/2259 2051/2197/2271 2050/2196/2270
            +f 2039/2185/2260 2040/2186/2261 2052/2198/2272
            +f 2039/2185/2260 2052/2198/2272 2051/2197/2271
            +f 2040/2186/2261 2054/2200/2262 2053/2199/2273
            +f 2040/2186/2261 2053/2199/2273 2052/2198/2272
            +f 2041/2187/2251 2031/2177/2252 2055/2201/2274
            +f 2041/2187/2251 2055/2201/2274 2054/2200/2262
            +f 2031/2177/2252 2042/2188/2263 2056/2202/2275
            +f 2031/2177/2252 2056/2202/2275 2055/2201/2274
            +f 2042/2188/2263 2033/2180/2255 2043/2190/2265
            +f 2042/2188/2263 2043/2190/2265 2056/2202/2275
            +f 2043/2190/2265 2044/2189/2264 2058/2203/2276
            +f 2043/2190/2265 2058/2203/2276 2057/2204/2277
            +f 2044/2189/2264 2045/2191/2266 2059/2205/2278
            +f 2044/2189/2264 2059/2205/2278 2058/2203/2276
            +f 2045/2191/2266 2046/2192/2267 2059/2205/2278
            +f 2046/2192/2267 2047/2193/2268 2060/2206/2279
            +f 2047/2193/2268 2048/2194/2245 2061/2207/2280
            +f 2047/2193/2268 2061/2207/2280 2060/2206/2279
            +f 2048/2194/2245 2049/2195/2269 2062/2208/2281
            +f 2048/2194/2245 2062/2208/2281 2061/2207/2280
            +f 2049/2195/2269 2050/2196/2270 2063/2209/2282
            +f 2049/2195/2269 2063/2209/2282 2062/2208/2281
            +f 2050/2196/2270 2051/2197/2271 2064/2210/2283
            +f 2050/2196/2270 2064/2210/2283 2063/2209/2282
            +f 2051/2197/2271 2052/2198/2272 2072/2218/2284
            +f 2051/2197/2271 2072/2218/2284 2064/2210/2283
            +f 2052/2198/2272 2053/2199/2273 2072/2218/2284
            +f 2054/2200/2262 2055/2201/2274 2065/2211/2285
            +f 2055/2201/2274 2056/2202/2275 2066/2212/2286
            +f 2055/2201/2274 2066/2212/2286 2065/2211/2285
            +f 2056/2202/2275 2043/2190/2265 2057/2204/2277
            +f 2056/2202/2275 2057/2204/2277 2066/2212/2286
            +f 2057/2204/2277 2058/2203/2276 2068/2213/2287
            +f 2057/2204/2277 2068/2213/2287 2067/2214/2288
            +f 2058/2203/2276 2059/2205/2278 2069/2215/2289
            +f 2058/2203/2276 2069/2215/2289 2068/2213/2287
            +f 2059/2205/2278 2046/2192/2267 2078/2224/2290
            +f 2059/2205/2278 2078/2224/2290 2069/2215/2289
            +f 2046/2192/2267 2060/2206/2279 2078/2224/2290
            +f 2062/2208/2281 2063/2209/2282 2070/2216/2291
            +f 2063/2209/2282 2064/2210/2283 2070/2216/2291
            +f 2064/2210/2283 2072/2218/2284 2071/2217/2292
            +f 2053/2199/2273 2054/2200/2262 2073/2219/2293
            +f 2053/2199/2273 2073/2219/2293 2072/2218/2284
            +f 2054/2200/2262 2065/2211/2285 2073/2219/2293
            +f 2065/2211/2285 2066/2212/2286 2074/2220/2294
            +f 2066/2212/2286 2057/2204/2277 2067/2214/2288
            +f 2066/2212/2286 2067/2214/2288 2074/2220/2294
            +f 2067/2214/2288 2068/2213/2287 2075/2221/2295
            +f 2067/2214/2288 2075/2221/2295 2085/2232/2296
            +f 2068/2213/2287 2069/2215/2289 2076/2222/2297
            +f 2068/2213/2287 2076/2222/2297 2075/2221/2295
            +f 2069/2215/2289 2078/2224/2290 2077/2223/2298
            +f 2069/2215/2289 2077/2223/2298 2076/2222/2297
            +f 2060/2206/2279 2061/2207/2280 2079/2225/2299
            +f 2060/2206/2279 2079/2225/2299 2078/2224/2290
            +f 2061/2207/2280 2062/2208/2281 2080/2226/2300
            +f 2061/2207/2280 2080/2226/2300 2079/2225/2299
            +f 2062/2208/2281 2070/2216/2291 2080/2226/2300
            +f 2070/2216/2291 2064/2210/2283 2081/2227/2301
            +f 2064/2210/2283 2071/2217/2292 2081/2227/2301
            +f 2071/2217/2292 2072/2218/2284 2082/2228/2302
            +f 2072/2218/2284 2073/2219/2293 2083/2229/2303
            +f 2072/2218/2284 2083/2229/2303 2082/2228/2302
            +f 2073/2219/2293 2065/2211/2285 2084/2230/2304
            +f 2073/2219/2293 2084/2230/2304 2083/2229/2303
            +f 2065/2211/2285 2074/2220/2294 2084/2230/2304
            +f 2074/2220/2294 2067/2214/2288 2085/2232/2296
            +f 2085/2232/2296 2075/2221/2295 2086/2231/2305
            +f 2075/2221/2295 2076/2222/2297 2086/2231/2305
            +f 2076/2222/2297 2077/2223/2298 2087/2233/2306
            +f 2077/2223/2298 2078/2224/2290 2088/2234/2307
            +f 2077/2223/2298 2088/2234/2307 2087/2233/2306
            +f 2078/2224/2290 2079/2225/2299 2088/2234/2307
            +f 2079/2225/2299 2080/2226/2300 2089/2235/2308
            +f 2080/2226/2300 2070/2216/2291 2089/2235/2308
            +f 2070/2216/2291 2081/2227/2301 2090/2236/2309
            +f 2081/2227/2301 2071/2217/2292 2090/2236/2309
            +f 2071/2217/2292 2082/2228/2302 2091/2237/2310
            +f 2082/2228/2302 2083/2229/2303 2092/2238/2311
            +f 2082/2228/2302 2092/2238/2311 2091/2237/2310
            +f 2083/2229/2303 2084/2230/2304 2092/2238/2311
            +f 2084/2230/2304 2074/2220/2294 2093/2239/2312
            +f 2074/2220/2294 2085/2232/2296 2093/2239/2312
            +f 2085/2232/2296 2086/2231/2305 2102/2248/2313
            +f 2089/2235/2308 2070/2216/2291 2094/2240/2314
            +f 2070/2216/2291 2090/2236/2309 2094/2240/2314
            +f 2090/2236/2309 2071/2217/2292 2095/2241/2315
            +f 2071/2217/2292 2091/2237/2310 2095/2241/2315
            +f 2093/2239/2312 2085/2232/2296 2102/2248/2313
            +f 2102/2248/2313 2086/2231/2305 2096/2242/2316
            +f 2086/2231/2305 2076/2222/2297 2097/2243/2317
            +f 2086/2231/2305 2097/2243/2317 2096/2242/2316
            +f 2076/2222/2297 2087/2233/2306 2097/2243/2317
            +f 2087/2233/2306 2088/2234/2307 2098/2244/2318
            +f 2088/2234/2307 2079/2225/2299 2099/2245/2319
            +f 2088/2234/2307 2099/2245/2319 2098/2244/2318
            +f 2079/2225/2299 2089/2235/2308 2099/2245/2319
            +f 2091/2237/2310 2092/2238/2311 2100/2246/2320
            +f 2092/2238/2311 2084/2230/2304 2101/2247/2321
            +f 2092/2238/2311 2101/2247/2321 2100/2246/2320
            +f 2084/2230/2304 2093/2239/2312 2101/2247/2321
            +f 2097/2243/2317 2087/2233/2306 2103/2249/2322
            +f 2087/2233/2306 2098/2244/2318 2103/2249/2322
            +f 2098/2244/2318 2099/2245/2319 2104/2250/2323
            +f 2099/2245/2319 2089/2235/2308 2105/2251/2324
            +f 2099/2245/2319 2105/2251/2324 2104/2250/2323
            +f 2089/2235/2308 2094/2240/2314 2105/2251/2324
            +f 2094/2240/2314 2090/2236/2309 2106/2252/2325
            +f 2090/2236/2309 2095/2241/2315 2106/2252/2325
            +f 2095/2241/2315 2091/2237/2310 2107/2253/2326
            +f 2091/2237/2310 2100/2246/2320 2107/2253/2326
            +f 2101/2247/2321 2093/2239/2312 2108/2254/2327
            +f 2093/2239/2312 2102/2248/2313 2108/2254/2327
            +f 2102/2248/2313 2096/2242/2316 2123/2270/2328
            +f 2096/2242/2316 2097/2243/2317 2109/2255/2329
            +f 2097/2243/2317 2103/2249/2322 2109/2255/2329
            +f 2103/2249/2322 2098/2244/2318 2110/2256/2330
            +f 2098/2244/2318 2104/2250/2323 2110/2256/2330
            +f 2105/2251/2324 2094/2240/2314 2111/2257/2331
            +f 2094/2240/2314 2106/2252/2325 2111/2257/2331
            +f 2106/2252/2325 2095/2241/2315 2112/2258/2332
            +f 2095/2241/2315 2107/2253/2326 2112/2258/2332
            +f 2107/2253/2326 2100/2246/2320 2113/2259/2333
            +f 2100/2246/2320 2101/2247/2321 2114/2260/2334
            +f 2100/2246/2320 2114/2260/2334 2113/2259/2333
            +f 2101/2247/2321 2108/2254/2327 2114/2260/2334
            +f 2108/2254/2327 2102/2248/2313 2123/2270/2328
            +f 2123/2270/2328 2096/2242/2316 2115/2261/2335
            +f 2096/2242/2316 2109/2255/2329 2115/2261/2335
            +f 2109/2255/2329 2103/2249/2322 2116/2262/2336
            +f 2103/2249/2322 2110/2256/2330 2116/2262/2336
            +f 2110/2256/2330 2104/2250/2323 2117/2263/2337
            +f 2104/2250/2323 2105/2251/2324 2118/2264/2338
            +f 2104/2250/2323 2118/2264/2338 2117/2263/2337
            +f 2105/2251/2324 2111/2257/2331 2118/2264/2338
            +f 2111/2257/2331 2106/2252/2325 2119/2265/2339
            +f 2106/2252/2325 2112/2258/2332 2119/2265/2339
            +f 2112/2258/2332 2107/2253/2326 2120/2266/2340
            +f 2107/2253/2326 2113/2259/2333 2120/2266/2340
            +f 2113/2259/2333 2114/2260/2334 2121/2267/2341
            +f 2114/2260/2334 2108/2254/2327 2122/2268/2342
            +f 2114/2260/2334 2122/2268/2342 2121/2267/2341
            +f 2108/2254/2327 2123/2270/2328 2122/2268/2342
            +f 2123/2270/2328 2115/2261/2335 2124/2269/2343
            +f 2115/2261/2335 2109/2255/2329 2124/2269/2343
            +f 2109/2255/2329 2116/2262/2336 2125/2271/2344
            +f 2116/2262/2336 2110/2256/2330 2126/2272/2345
            +f 2116/2262/2336 2126/2272/2345 2125/2271/2344
            +f 2110/2256/2330 2117/2263/2337 2127/2273/2346
            +f 2110/2256/2330 2127/2273/2346 2126/2272/2345
            +f 2117/2263/2337 2118/2264/2338 2128/2274/2347
            +f 2117/2263/2337 2128/2274/2347 2127/2273/2346
            +f 2118/2264/2338 2111/2257/2331 2128/2274/2347
            +f 2119/2265/2339 2112/2258/2332 2129/2275/2348
            +f 2112/2258/2332 2120/2266/2340 2129/2275/2348
            +f 2120/2266/2340 2113/2259/2333 2130/2276/2349
            +f 2113/2259/2333 2121/2267/2341 2131/2277/2350
            +f 2113/2259/2333 2131/2277/2350 2130/2276/2349
            +f 2121/2267/2341 2122/2268/2342 2132/2278/2351
            +f 2121/2267/2341 2132/2278/2351 2131/2277/2350
            +f 2122/2268/2342 2123/2270/2328 2132/2278/2351
            +f 2123/2270/2328 2124/2269/2343 2134/2279/2352
            +f 2123/2270/2328 2134/2279/2352 2133/2280/2353
            +f 2124/2269/2343 2109/2255/2329 2135/2281/2354
            +f 2124/2269/2343 2135/2281/2354 2134/2279/2352
            +f 2109/2255/2329 2125/2271/2344 2135/2281/2354
            +f 2125/2271/2344 2126/2272/2345 2154/2300/2355
            +f 2126/2272/2345 2127/2273/2346 2136/2282/2356
            +f 2126/2272/2345 2136/2282/2356 2154/2300/2355
            +f 2127/2273/2346 2128/2274/2347 2137/2283/2357
            +f 2127/2273/2346 2137/2283/2357 2136/2282/2356
            +f 2128/2274/2347 2111/2257/2331 2138/2284/2358
            +f 2128/2274/2347 2138/2284/2358 2137/2283/2357
            +f 2111/2257/2331 2119/2265/2339 2139/2285/2359
            +f 2111/2257/2331 2139/2285/2359 2138/2284/2358
            +f 2119/2265/2339 2129/2275/2348 2139/2285/2359
            +f 2129/2275/2348 2120/2266/2340 2140/2286/2360
            +f 2120/2266/2340 2130/2276/2349 2140/2286/2360
            +f 2130/2276/2349 2131/2277/2350 2141/2287/2361
            +f 2131/2277/2350 2132/2278/2351 2142/2288/2362
            +f 2131/2277/2350 2142/2288/2362 2141/2287/2361
            +f 2132/2278/2351 2123/2270/2328 2133/2280/2353
            +f 2132/2278/2351 2133/2280/2353 2142/2288/2362
            +f 2133/2280/2353 2134/2279/2352 2144/2289/2363
            +f 2133/2280/2353 2144/2289/2363 2143/2290/2364
            +f 2134/2279/2352 2135/2281/2354 2144/2289/2363
            +f 2135/2281/2354 2125/2271/2344 2145/2291/2365
            +f 2125/2271/2344 2154/2300/2355 2145/2291/2365
            +f 2137/2283/2357 2138/2284/2358 2146/2292/2366
            +f 2138/2284/2358 2139/2285/2359 2147/2293/2367
            +f 2138/2284/2358 2147/2293/2367 2146/2292/2366
            +f 2139/2285/2359 2129/2275/2348 2148/2294/2368
            +f 2139/2285/2359 2148/2294/2368 2147/2293/2367
            +f 2129/2275/2348 2140/2286/2360 2148/2294/2368
            +f 2140/2286/2360 2130/2276/2349 2149/2295/2369
            +f 2130/2276/2349 2141/2287/2361 2149/2295/2369
            +f 2142/2288/2362 2133/2280/2353 2143/2290/2364
            +f 2143/2290/2364 2144/2289/2363 2151/2296/2370
            +f 2143/2290/2364 2151/2296/2370 2150/2297/2371
            +f 2144/2289/2363 2135/2281/2354 2152/2298/2372
            +f 2144/2289/2363 2152/2298/2372 2151/2296/2370
            +f 2135/2281/2354 2145/2291/2365 2152/2298/2372
            +f 2145/2291/2365 2154/2300/2355 2153/2299/2373
            +f 2136/2282/2356 2137/2283/2357 2155/2301/2374
            +f 2136/2282/2356 2155/2301/2374 2154/2300/2355
            +f 2137/2283/2357 2146/2292/2366 2156/2302/2375
            +f 2137/2283/2357 2156/2302/2375 2155/2301/2374
            +f 2146/2292/2366 2147/2293/2367 2157/2303/2376
            +f 2146/2292/2366 2157/2303/2376 2156/2302/2375
            +f 2147/2293/2367 2148/2294/2368 2158/2304/2377
            +f 2147/2293/2367 2158/2304/2377 2157/2303/2376
            +f 2148/2294/2368 2140/2286/2360 2149/2295/2369
            +f 2148/2294/2368 2149/2295/2369 2158/2304/2377
            +f 2149/2295/2369 2141/2287/2361 2159/2305/2378
            +f 2141/2287/2361 2142/2288/2362 2160/2306/2379
            +f 2141/2287/2361 2160/2306/2379 2159/2305/2378
            +f 2142/2288/2362 2143/2290/2364 2150/2297/2371
            +f 2142/2288/2362 2150/2297/2371 2160/2306/2379
            +f 2150/2297/2371 2151/2296/2370 2162/2307/2380
            +f 2150/2297/2371 2162/2307/2380 2161/2308/2381
            +f 2151/2296/2370 2152/2298/2372 2163/2309/2382
            +f 2151/2296/2370 2163/2309/2382 2162/2307/2380
            +f 2152/2298/2372 2145/2291/2365 2164/2310/2383
            +f 2152/2298/2372 2164/2310/2383 2163/2309/2382
            +f 2145/2291/2365 2153/2299/2373 2164/2310/2383
            +f 2153/2299/2373 2154/2300/2355 2165/2311/2384
            +f 2154/2300/2355 2155/2301/2374 2166/2312/2385
            +f 2154/2300/2355 2166/2312/2385 2165/2311/2384
            +f 2155/2301/2374 2156/2302/2375 2167/2313/2386
            +f 2155/2301/2374 2167/2313/2386 2166/2312/2385
            +f 2156/2302/2375 2157/2303/2376 2168/2314/2387
            +f 2156/2302/2375 2168/2314/2387 2167/2313/2386
            +f 2157/2303/2376 2158/2304/2377 2169/2315/2388
            +f 2157/2303/2376 2169/2315/2388 2168/2314/2387
            +f 2158/2304/2377 2149/2295/2369 2170/2316/2389
            +f 2158/2304/2377 2170/2316/2389 2169/2315/2388
            +f 2149/2295/2369 2171/2317/2390 2170/2316/2389
            +f 2149/2295/2369 2159/2305/2378 2171/2317/2390
            +f 2159/2305/2378 2160/2306/2379 2172/2318/2391
            +f 2160/2306/2379 2150/2297/2371 2161/2308/2381
            +f 2160/2306/2379 2161/2308/2381 2172/2318/2391
            +f 2161/2308/2381 2162/2307/2380 2173/2319/2392
            +f 2161/2308/2381 2173/2319/2392 2190/2337/2393
            +f 2162/2307/2380 2163/2309/2382 2174/2320/2394
            +f 2162/2307/2380 2174/2320/2394 2173/2319/2392
            +f 2163/2309/2382 2164/2310/2383 2175/2321/2395
            +f 2163/2309/2382 2175/2321/2395 2174/2320/2394
            +f 2164/2310/2383 2153/2299/2373 2176/2322/2396
            +f 2164/2310/2383 2176/2322/2396 2175/2321/2395
            +f 2153/2299/2373 2165/2311/2384 2177/2323/2397
            +f 2153/2299/2373 2177/2323/2397 2176/2322/2396
            +f 2165/2311/2384 2166/2312/2385 2178/2324/2398
            +f 2165/2311/2384 2178/2324/2398 2177/2323/2397
            +f 2166/2312/2385 2167/2313/2386 2179/2325/2399
            +f 2166/2312/2385 2179/2325/2399 2178/2324/2398
            +f 2167/2313/2386 2168/2314/2387 2180/2326/2400
            +f 2167/2313/2386 2180/2326/2400 2179/2325/2399
            +f 2168/2314/2387 2169/2315/2388 2181/2327/2401
            +f 2168/2314/2387 2181/2327/2401 2180/2326/2400
            +f 2169/2315/2388 2170/2316/2389 2182/2328/2402
            +f 2169/2315/2388 2182/2328/2402 2181/2327/2401
            +f 2170/2316/2389 2171/2317/2390 2183/2329/2403
            +f 2170/2316/2389 2183/2329/2403 2182/2328/2402
            +f 2171/2317/2390 2159/2305/2378 2184/2330/2404
            +f 2171/2317/2390 2184/2330/2404 2183/2329/2403
            +f 2159/2305/2378 2172/2318/2391 2185/2331/2405
            +f 2159/2305/2378 2185/2331/2405 2184/2330/2404
            +f 2172/2318/2391 2161/2308/2381 2190/2337/2393
            +f 2172/2318/2391 2190/2337/2393 2185/2331/2405
            +f 2174/2320/2394 2175/2321/2395 2186/2332/2406
            +f 2175/2321/2395 2176/2322/2396 2186/2332/2406
            +f 2176/2322/2396 2177/2323/2397 2187/2333/2407
            +f 2177/2323/2397 2178/2324/2398 2188/2334/2408
            +f 2177/2323/2397 2188/2334/2408 2187/2333/2407
            +f 2178/2324/2398 2179/2325/2399 2188/2334/2408
            +f 2183/2329/2403 2184/2330/2404 2189/2335/2409
            +f 2184/2330/2404 2185/2331/2405 2189/2335/2409
            +f 2190/2337/2393 2173/2319/2392 2191/2336/2410
            +f 2173/2319/2392 2174/2320/2394 2192/2338/2411
            +f 2173/2319/2392 2192/2338/2411 2191/2336/2410
            +f 2174/2320/2394 2186/2332/2406 2192/2338/2411
            +f 2186/2332/2406 2176/2322/2396 2193/2339/2412
            +f 2176/2322/2396 2187/2333/2407 2193/2339/2412
            +f 2179/2325/2399 2180/2326/2400 2194/2340/2413
            +f 2180/2326/2400 2181/2327/2401 2195/2341/2414
            +f 2180/2326/2400 2195/2341/2414 2194/2340/2413
            +f 2181/2327/2401 2182/2328/2402 2195/2341/2414
            +f 2182/2328/2402 2183/2329/2403 2196/2342/2415
            +f 2183/2329/2403 2189/2335/2409 2196/2342/2415
            +f 2189/2335/2409 2185/2331/2405 2197/2343/2416
            +f 2185/2331/2405 2190/2337/2393 2197/2343/2416
            +f 2190/2337/2393 2191/2336/2410 2206/2353/2417
            +f 2191/2336/2410 2192/2338/2411 2198/2344/2418
            +f 2192/2338/2411 2186/2332/2406 2199/2345/2419
            +f 2192/2338/2411 2199/2345/2419 2198/2344/2418
            +f 2186/2332/2406 2193/2339/2412 2199/2345/2419
            +f 2193/2339/2412 2187/2333/2407 2200/2346/2420
            +f 2187/2333/2407 2188/2334/2408 2201/2347/2421
            +f 2187/2333/2407 2201/2347/2421 2200/2346/2420
            +f 2188/2334/2408 2179/2325/2399 2202/2348/2422
            +f 2188/2334/2408 2202/2348/2422 2201/2347/2421
            +f 2179/2325/2399 2194/2340/2413 2202/2348/2422
            +f 2194/2340/2413 2195/2341/2414 2203/2349/2423
            +f 2195/2341/2414 2182/2328/2402 2204/2350/2424
            +f 2195/2341/2414 2204/2350/2424 2203/2349/2423
            +f 2182/2328/2402 2196/2342/2415 2204/2350/2424
            +f 2196/2342/2415 2189/2335/2409 2205/2351/2425
            +f 2189/2335/2409 2197/2343/2416 2205/2351/2425
            +f 2197/2343/2416 2190/2337/2393 2206/2353/2417
            +f 2206/2353/2417 2191/2336/2410 2207/2352/2426
            +f 2191/2336/2410 2198/2344/2418 2207/2352/2426
            +f 2198/2344/2418 2199/2345/2419 2208/2354/2427
            +f 2199/2345/2419 2193/2339/2412 2209/2355/2428
            +f 2199/2345/2419 2209/2355/2428 2208/2354/2427
            +f 2193/2339/2412 2200/2346/2420 2209/2355/2428
            +f 2200/2346/2420 2201/2347/2421 2210/2356/2429
            +f 2201/2347/2421 2202/2348/2422 2210/2356/2429
            +f 2202/2348/2422 2194/2340/2413 2211/2357/2430
            +f 2194/2340/2413 2203/2349/2423 2211/2357/2430
            +f 2203/2349/2423 2204/2350/2424 2212/2358/2431
            +f 2204/2350/2424 2196/2342/2415 2213/2359/2432
            +f 2204/2350/2424 2213/2359/2432 2212/2358/2431
            +f 2196/2342/2415 2205/2351/2425 2213/2359/2432
            +f 2205/2351/2425 2197/2343/2416 2214/2360/2433
            +f 2197/2343/2416 2206/2353/2417 2214/2360/2433
            +f 2206/2353/2417 2207/2352/2426 2231/2377/2434
            +f 2207/2352/2426 2198/2344/2418 2215/2361/2435
            +f 2198/2344/2418 2208/2354/2427 2215/2361/2435
            +f 2208/2354/2427 2209/2355/2428 2216/2362/2436
            +f 2209/2355/2428 2200/2346/2420 2217/2363/2437
            +f 2209/2355/2428 2217/2363/2437 2216/2362/2436
            +f 2200/2346/2420 2210/2356/2429 2217/2363/2437
            +f 2211/2357/2430 2203/2349/2423 2218/2364/2438
            +f 2203/2349/2423 2212/2358/2431 2218/2364/2438
            +f 2212/2358/2431 2213/2359/2432 2219/2365/2439
            +f 2213/2359/2432 2205/2351/2425 2220/2366/2440
            +f 2213/2359/2432 2220/2366/2440 2219/2365/2439
            +f 2205/2351/2425 2214/2360/2433 2220/2366/2440
            +f 2214/2360/2433 2206/2353/2417 2231/2377/2434
            +f 2215/2361/2435 2208/2354/2427 2221/2367/2441
            +f 2208/2354/2427 2216/2362/2436 2221/2367/2441
            +f 2216/2362/2436 2217/2363/2437 2222/2368/2442
            +f 2217/2363/2437 2210/2356/2429 2223/2369/2443
            +f 2217/2363/2437 2223/2369/2443 2222/2368/2442
            +f 2210/2356/2429 2202/2348/2422 2224/2370/2444
            +f 2210/2356/2429 2224/2370/2444 2223/2369/2443
            +f 2202/2348/2422 2211/2357/2430 2224/2370/2444
            +f 2219/2365/2439 2220/2366/2440 2225/2371/2445
            +f 2220/2366/2440 2214/2360/2433 2226/2372/2446
            +f 2220/2366/2440 2226/2372/2446 2225/2371/2445
            +f 2214/2360/2433 2231/2377/2434 2226/2372/2446
            +f 2207/2352/2426 2215/2361/2435 2227/2373/2447
            +f 2215/2361/2435 2221/2367/2441 2227/2373/2447
            +f 2221/2367/2441 2216/2362/2436 2228/2374/2448
            +f 2216/2362/2436 2222/2368/2442 2228/2374/2448
            +f 2222/2368/2442 2223/2369/2443 2229/2375/2449
            +f 2223/2369/2443 2224/2370/2444 2229/2375/2449
            +f 2218/2364/2438 2212/2358/2431 2230/2376/2450
            +f 2212/2358/2431 2219/2365/2439 2230/2376/2450
            +f 2228/2374/2448 2222/2368/2442 2232/2378/2451
            +f 2222/2368/2442 2229/2375/2449 2232/2378/2451
            +f 2229/2375/2449 2224/2370/2444 2233/2379/2452
            +f 2224/2370/2444 2211/2357/2430 2234/2380/2453
            +f 2224/2370/2444 2234/2380/2453 2233/2379/2452
            +f 2211/2357/2430 2218/2364/2438 2234/2380/2453
            +f 2219/2365/2439 2225/2371/2445 2235/2381/2454
            +f 2225/2371/2445 2226/2372/2446 2236/2382/2455
            +f 2225/2371/2445 2236/2382/2455 2235/2381/2454
            +f 2226/2372/2446 2231/2377/2434 2236/2382/2455
            +f 2231/2377/2434 2207/2352/2426 2237/2383/2456
            +f 2231/2377/2434 2237/2383/2456 2242/2388/2457
            +f 2207/2352/2426 2227/2373/2447 2237/2383/2456
            +f 2227/2373/2447 2221/2367/2441 2238/2384/2458
            +f 2221/2367/2441 2228/2374/2448 2238/2384/2458
            +f 2232/2378/2451 2229/2375/2449 2239/2385/2459
            +f 2229/2375/2449 2233/2379/2452 2239/2385/2459
            +f 2234/2380/2453 2218/2364/2438 2240/2386/2460
            +f 2218/2364/2438 2230/2376/2450 2240/2386/2460
            +f 2230/2376/2450 2219/2365/2439 2241/2387/2461
            +f 2219/2365/2439 2235/2381/2454 2241/2387/2461
            +f 2236/2382/2455 2231/2377/2434 2242/2388/2457
            +f 2237/2383/2456 2227/2373/2447 2243/2389/2462
            +f 2227/2373/2447 2238/2384/2458 2243/2389/2462
            +f 2238/2384/2458 2228/2374/2448 2244/2390/2463
            +f 2228/2374/2448 2232/2378/2451 2244/2390/2463
            +f 2233/2379/2452 2234/2380/2453 2245/2391/2464
            +f 2234/2380/2453 2240/2386/2460 2245/2391/2464
            +f 2240/2386/2460 2230/2376/2450 2254/2400/2465
            +f 2230/2376/2450 2241/2387/2461 2254/2400/2465
            +f 2241/2387/2461 2235/2381/2454 2255/2401/2466
            +f 2235/2381/2454 2236/2382/2455 2246/2392/2467
            +f 2235/2381/2454 2246/2392/2467 2255/2401/2466
            +f 2236/2382/2455 2242/2388/2457 2246/2392/2467
            +f 2242/2388/2457 2237/2383/2456 2249/2395/2468
            +f 2243/2389/2462 2238/2384/2458 2247/2393/2469
            +f 2238/2384/2458 2244/2390/2463 2247/2393/2469
            +f 2244/2390/2463 2232/2378/2451 2252/2398/2470
            +f 2232/2378/2451 2239/2385/2459 2252/2398/2470
            +f 2239/2385/2459 2233/2379/2452 2248/2394/2471
            +f 2233/2379/2452 2245/2391/2464 2248/2394/2471
            +f 2246/2392/2467 2242/2388/2457 2249/2395/2468
            +f 2249/2395/2468 2237/2383/2456 2250/2396/2472
            +f 2237/2383/2456 2243/2389/2462 2250/2396/2472
            +f 2243/2389/2462 2247/2393/2469 2250/2396/2472
            +f 2247/2393/2469 2244/2390/2463 2251/2397/2473
            +f 2244/2390/2463 2252/2398/2470 2251/2397/2473
            +f 2239/2385/2459 2248/2394/2471 2252/2398/2470
            +f 2245/2391/2464 2240/2386/2460 2253/2399/2474
            +f 2240/2386/2460 2254/2400/2465 2253/2399/2474
            +f 2241/2387/2461 2255/2401/2466 2254/2400/2465
            +f 2246/2392/2467 2249/2395/2468 2255/2401/2466
            +f 2249/2395/2468 2250/2396/2472 2256/2402/2475
            +f 2249/2395/2468 2256/2402/2475 2262/2409/2476
            +f 2250/2396/2472 2247/2393/2469 2256/2402/2475
            +f 2251/2397/2473 2252/2398/2470 2257/2403/2477
            +f 2252/2398/2470 2258/2404/2478 2257/2403/2477
            +f 2252/2398/2470 2248/2394/2471 2259/2405/2479
            +f 2252/2398/2470 2259/2405/2479 2258/2404/2478
            +f 2248/2394/2471 2245/2391/2464 2260/2406/2480
            +f 2248/2394/2471 2260/2406/2480 2259/2405/2479
            +f 2245/2391/2464 2253/2399/2474 2260/2406/2480
            +f 2254/2400/2465 2255/2401/2466 2261/2407/2481
            +f 2254/2400/2465 2261/2407/2481 2273/2419/2482
            +f 2255/2401/2466 2249/2395/2468 2262/2409/2476
            +f 2255/2401/2466 2262/2409/2476 2261/2407/2481
            +f 2262/2409/2476 2256/2402/2475 2263/2408/2483
            +f 2256/2402/2475 2247/2393/2469 2269/2415/2484
            +f 2247/2393/2469 2251/2397/2473 2269/2415/2484
            +f 2258/2404/2478 2259/2405/2479 2264/2410/2485
            +f 2259/2405/2479 2260/2406/2480 2265/2411/2486
            +f 2259/2405/2479 2265/2411/2486 2264/2410/2485
            +f 2260/2406/2480 2253/2399/2474 2266/2412/2487
            +f 2260/2406/2480 2266/2412/2487 2265/2411/2486
            +f 2253/2399/2474 2254/2400/2465 2267/2413/2488
            +f 2253/2399/2474 2267/2413/2488 2266/2412/2487
            +f 2254/2400/2465 2273/2419/2482 2267/2413/2488
            +f 2262/2409/2476 2263/2408/2483 2268/2414/2489
            +f 2263/2408/2483 2256/2402/2475 2276/2422/2490
            +f 2256/2402/2475 2269/2415/2484 2276/2422/2490
            +f 2251/2397/2473 2257/2403/2477 2269/2415/2484
            +f 2257/2403/2477 2258/2404/2478 2270/2416/2491
            +f 2258/2404/2478 2264/2410/2485 2271/2417/2492
            +f 2258/2404/2478 2271/2417/2492 2270/2416/2491
            +f 2264/2410/2485 2265/2411/2486 2272/2418/2493
            +f 2264/2410/2485 2272/2418/2493 2271/2417/2492
            +f 2265/2411/2486 2266/2412/2487 2272/2418/2493
            +f 2261/2407/2481 2262/2409/2476 2268/2414/2489
            +f 2268/2414/2489 2263/2408/2483 2275/2420/2494
            +f 2268/2414/2489 2275/2420/2494 2274/2421/2495
            +f 2263/2408/2483 2276/2422/2490 2275/2420/2494
            +f 2270/2416/2491 2271/2417/2492 2277/2423/2496
            +f 2271/2417/2492 2272/2418/2493 2278/2424/2497
            +f 2271/2417/2492 2278/2424/2497 2277/2423/2496
            +f 2272/2418/2493 2266/2412/2487 2279/2425/2498
            +f 2272/2418/2493 2279/2425/2498 2278/2424/2497
            +f 2266/2412/2487 2267/2413/2488 2279/2425/2498
            +f 2267/2413/2488 2273/2419/2482 2279/2425/2498
            +f 2273/2419/2482 2261/2407/2481 2274/2421/2495
            +f 2261/2407/2481 2268/2414/2489 2274/2421/2495
            +f 2274/2421/2495 2275/2420/2494 2282/2428/2499
            +f 2269/2415/2484 2257/2403/2477 2280/2426/2500
            +f 2257/2403/2477 2270/2416/2491 2280/2426/2500
            +f 2270/2416/2491 2277/2423/2496 2281/2427/2501
            +f 2270/2416/2491 2281/2427/2501 2280/2426/2500
            +f 2277/2423/2496 2278/2424/2497 2281/2427/2501
            +f 2279/2425/2498 2273/2419/2482 2287/2433/2502
            +f 2282/2428/2499 2275/2420/2494 2283/2429/2503
            +f 2275/2420/2494 2276/2422/2490 2283/2429/2503
            +f 2276/2422/2490 2284/2430/2504 2283/2429/2503
            +f 2276/2422/2490 2269/2415/2484 2284/2430/2504
            +f 2269/2415/2484 2280/2426/2500 2284/2430/2504
            +f 2281/2427/2501 2278/2424/2497 2285/2431/2505
            +f 2278/2424/2497 2279/2425/2498 2286/2432/2506
            +f 2278/2424/2497 2286/2432/2506 2285/2431/2505
            +f 2279/2425/2498 2287/2433/2502 2286/2432/2506
            +f 2273/2419/2482 2274/2421/2495 2282/2428/2499
            +f 2273/2419/2482 2282/2428/2499 2287/2433/2502
            +f 2281/2427/2501 2285/2431/2505 2286/2432/2506
            +f 2281/2427/2501 2286/2432/2506 2287/2433/2502
            +f 2281/2427/2501 2287/2433/2502 2282/2428/2499
            +f 2281/2427/2501 2282/2428/2499 2283/2429/2503
            +f 2280/2426/2500 2281/2427/2501 2283/2429/2503
            +f 2284/2430/2504 2280/2426/2500 2283/2429/2503
            +f 2288/2434/2507 2295/2441/2508 2294/2435/2509
            +f 2288/2434/2507 2294/2435/2509 2293/2436/2510
            +f 2288/2434/2507 2293/2436/2510 2292/2437/2511
            +f 2288/2434/2507 2292/2437/2511 2291/2438/2512
            +f 2289/2439/2513 2288/2434/2507 2291/2438/2512
            +f 2289/2439/2513 2291/2438/2512 2290/2440/2514
            +f 2295/2441/2508 2288/2434/2507 2296/2442/2515
            +f 2288/2434/2507 2289/2439/2513 2296/2442/2515
            +f 2289/2439/2513 2297/2443/2516 2296/2442/2515
            +f 2289/2439/2513 2290/2440/2514 2297/2443/2516
            +f 2290/2440/2514 2298/2444/2517 2297/2443/2516
            +f 2290/2440/2514 2291/2438/2512 2298/2444/2517
            +f 2291/2438/2512 2292/2437/2511 2299/2445/2518
            +f 2292/2437/2511 2293/2436/2510 2299/2445/2518
            +f 2293/2436/2510 2300/2446/2519 2299/2445/2518
            +f 2293/2436/2510 2294/2435/2509 2300/2446/2519
            +f 2294/2435/2509 2301/2447/2520 2300/2446/2519
            +f 2294/2435/2509 2295/2441/2508 2301/2447/2520
            +f 2295/2441/2508 2296/2442/2515 2303/2449/2521
            +f 2298/2444/2517 2291/2438/2512 2302/2448/2522
            +f 2291/2438/2512 2299/2445/2518 2302/2448/2522
            +f 2301/2447/2520 2295/2441/2508 2303/2449/2521
            +f 2303/2449/2521 2296/2442/2515 2306/2452/2523
            +f 2296/2442/2515 2297/2443/2516 2298/2444/2517
            +f 2296/2442/2515 2298/2444/2517 2306/2452/2523
            +f 2302/2448/2522 2299/2445/2518 2304/2450/2524
            +f 2299/2445/2518 2300/2446/2519 2301/2447/2520
            +f 2299/2445/2518 2301/2447/2520 2304/2450/2524
            +f 2303/2449/2521 2306/2452/2523 2305/2451/2525
            +f 2298/2444/2517 2307/2453/2526 2306/2452/2523
            +f 2298/2444/2517 2302/2448/2522 2307/2453/2526
            +f 2302/2448/2522 2304/2450/2524 2305/2451/2525
            +f 2302/2448/2522 2305/2451/2525 2307/2453/2526
            +f 2304/2450/2524 2301/2447/2520 2305/2451/2525
            +f 2301/2447/2520 2303/2449/2521 2305/2451/2525
            +f 2307/2453/2526 2305/2451/2525 2306/2452/2523
            +f 2308/2454/2527 2317/2464/2528 2316/2455/2529
            +f 2308/2454/2527 2316/2455/2529 2315/2456/2530
            +f 2308/2454/2527 2315/2456/2530 2314/2457/2531
            +f 2308/2454/2527 2314/2457/2531 2313/2458/2532
            +f 2308/2454/2527 2313/2458/2532 2312/2459/2533
            +f 2308/2454/2527 2312/2459/2533 2311/2460/2534
            +f 2309/2461/2535 2308/2454/2527 2311/2460/2534
            +f 2309/2461/2535 2311/2460/2534 2310/2462/2536
            +f 2317/2464/2528 2308/2454/2527 2318/2463/2537
            +f 2308/2454/2527 2309/2461/2535 2319/2465/2538
            +f 2308/2454/2527 2319/2465/2538 2318/2463/2537
            +f 2309/2461/2535 2320/2466/2539 2319/2465/2538
            +f 2309/2461/2535 2310/2462/2536 2321/2467/2540
            +f 2309/2461/2535 2321/2467/2540 2320/2466/2539
            +f 2310/2462/2536 2322/2468/2541 2321/2467/2540
            +f 2310/2462/2536 2311/2460/2534 2322/2468/2541
            +f 2312/2459/2533 2313/2458/2532 2323/2469/2542
            +f 2313/2458/2532 2314/2457/2531 2324/2470/2543
            +f 2313/2458/2532 2324/2470/2543 2323/2469/2542
            +f 2314/2457/2531 2325/2471/2544 2324/2470/2543
            +f 2314/2457/2531 2315/2456/2530 2326/2472/2545
            +f 2314/2457/2531 2326/2472/2545 2325/2471/2544
            +f 2315/2456/2530 2327/2473/2546 2326/2472/2545
            +f 2315/2456/2530 2316/2455/2529 2327/2473/2546
            +f 2317/2464/2528 2318/2463/2537 2331/2477/2547
            +f 2322/2468/2541 2311/2460/2534 2328/2474/2548
            +f 2311/2460/2534 2312/2459/2533 2329/2475/2549
            +f 2311/2460/2534 2329/2475/2549 2328/2474/2548
            +f 2312/2459/2533 2323/2469/2542 2329/2475/2549
            +f 2327/2473/2546 2316/2455/2529 2330/2476/2550
            +f 2316/2455/2529 2317/2464/2528 2331/2477/2547
            +f 2316/2455/2529 2331/2477/2547 2330/2476/2550
            +f 2331/2477/2547 2318/2463/2537 2333/2479/2551
            +f 2331/2477/2547 2333/2479/2551 2332/2478/2552
            +f 2318/2463/2537 2319/2465/2538 2333/2479/2551
            +f 2319/2465/2538 2320/2466/2539 2334/2480/2553
            +f 2319/2465/2538 2334/2480/2553 2333/2479/2551
            +f 2320/2466/2539 2321/2467/2540 2334/2480/2553
            +f 2321/2467/2540 2322/2468/2541 2328/2474/2548
            +f 2321/2467/2540 2328/2474/2548 2334/2480/2553
            +f 2328/2474/2548 2329/2475/2549 2335/2481/2554
            +f 2329/2475/2549 2323/2469/2542 2336/2482/2555
            +f 2329/2475/2549 2336/2482/2555 2335/2481/2554
            +f 2323/2469/2542 2324/2470/2543 2336/2482/2555
            +f 2324/2470/2543 2325/2471/2544 2337/2483/2556
            +f 2324/2470/2543 2337/2483/2556 2336/2482/2555
            +f 2325/2471/2544 2326/2472/2545 2337/2483/2556
            +f 2326/2472/2545 2327/2473/2546 2330/2476/2550
            +f 2326/2472/2545 2330/2476/2550 2337/2483/2556
            +f 2330/2476/2550 2331/2477/2547 2332/2478/2552
            +f 2332/2478/2552 2333/2479/2551 2339/2485/2557
            +f 2332/2478/2552 2339/2485/2557 2338/2484/2558
            +f 2333/2479/2551 2334/2480/2553 2339/2485/2557
            +f 2334/2480/2553 2328/2474/2548 2340/2486/2559
            +f 2334/2480/2553 2340/2486/2559 2339/2485/2557
            +f 2328/2474/2548 2335/2481/2554 2340/2486/2559
            +f 2335/2481/2554 2336/2482/2555 2341/2487/2560
            +f 2335/2481/2554 2341/2487/2560 2340/2486/2559
            +f 2336/2482/2555 2337/2483/2556 2341/2487/2560
            +f 2337/2483/2556 2330/2476/2550 2338/2484/2558
            +f 2337/2483/2556 2338/2484/2558 2341/2487/2560
            +f 2330/2476/2550 2332/2478/2552 2338/2484/2558
            +f 2340/2486/2559 2341/2487/2560 2338/2484/2558
            +f 2340/2486/2559 2338/2484/2558 2339/2485/2557
            diff --git a/dist/assets/p5_featured/matthew_kaney_teatime/index.html b/dist/assets/p5_featured/matthew_kaney_teatime/index.html
            new file mode 100644
            index 0000000000..6a7579f263
            --- /dev/null
            +++ b/dist/assets/p5_featured/matthew_kaney_teatime/index.html
            @@ -0,0 +1,16 @@
            +<!DOCTYPE html>
            +<!-- saved from url=(0041)http://content.mindofmatthew.com/teatime/ -->
            +<!DOCTYPE html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            +  
            +  <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +  <title></title>
            +  <link rel="stylesheet" href="http://content.mindofmatthew.com/teatime/">
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.24/p5.min.js"></script><style type="text/css"></style>
            +  <script src="sketch.js"></script>
            +  <style>
            +    html, body {margin:0; padding:0; font-size: 0;}
            +  </style> 
            +</head>
            +<body> 
            +</body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/matthew_kaney_teatime/koffie.obj b/dist/assets/p5_featured/matthew_kaney_teatime/koffie.obj
            new file mode 100644
            index 0000000000..d9612c3af4
            --- /dev/null
            +++ b/dist/assets/p5_featured/matthew_kaney_teatime/koffie.obj
            @@ -0,0 +1,3159 @@
            +# This file uses centimeters as units for non-parametric coordinates.
            +
            +v 0.007783 0.554414 0.017154
            +v 0.393444 0.551211 0.017154
            +v 0.179209 0.552846 0.017154
            +v 0.387588 0.553771 -0.049818
            +v 0.176602 0.554678 -0.012601
            +v 0.370207 0.550843 -0.114750
            +v 0.168857 0.552959 -0.041468
            +v 0.341794 0.554688 -0.175677
            +v 0.156237 0.550456 -0.068559
            +v 0.303216 0.551098 -0.230747
            +v 0.139083 0.552619 -0.093024
            +v 0.255684 0.552402 -0.278260
            +v 0.117962 0.554650 -0.114145
            +v 0.200633 0.554121 -0.316819
            +v 0.093478 0.551835 -0.131280
            +v 0.139687 0.550493 -0.345270
            +v 0.066424 0.550626 -0.143919
            +v 0.074774 0.554688 -0.362650
            +v 0.037557 0.553308 -0.151646
            +v 0.007783 0.550493 -0.368507
            +v 0.007783 0.554678 -0.154253
            +v -0.059207 0.553856 -0.362650
            +v -0.021990 0.553242 -0.151646
            +v -0.124120 0.553771 -0.345270
            +v -0.050857 0.551438 -0.143919
            +v -0.185066 0.551221 -0.316819
            +v -0.077911 0.550607 -0.131280
            +v -0.240117 0.550493 -0.278260
            +v -0.102395 0.550446 -0.114145
            +v -0.287649 0.550475 -0.230747
            +v -0.123516 0.550437 -0.093024
            +v -0.326227 0.551051 -0.175677
            +v -0.140670 0.550522 -0.068559
            +v -0.354640 0.553403 -0.114750
            +v -0.153290 0.551107 -0.041468
            +v -0.372021 0.554329 -0.049818
            +v -0.161035 0.552666 -0.012601
            +v -0.377877 0.550512 0.017154
            +v -0.163642 0.554451 0.017154
            +v -0.372021 0.554225 0.084145
            +v -0.161035 0.554092 0.046928
            +v -0.354640 0.550928 0.149058
            +v -0.153290 0.551306 0.075795
            +v -0.326227 0.554517 0.210003
            +v -0.140670 0.550843 0.102867
            +v -0.287649 0.550446 0.265073
            +v -0.123516 0.553970 0.127332
            +v -0.240117 0.554159 0.312606
            +v -0.102395 0.553960 0.148472
            +v -0.185066 0.552137 0.351164
            +v -0.077911 0.550796 0.165607
            +v -0.124120 0.551825 0.379578
            +v -0.050857 0.551514 0.178246
            +v -0.059207 0.553941 0.396977
            +v -0.021990 0.554385 0.185973
            +v 0.007783 0.551117 0.402834
            +v 0.007783 0.553988 0.188580
            +v 0.074774 0.553327 0.396977
            +v 0.037557 0.551627 0.185973
            +v 0.139687 0.553639 0.379578
            +v 0.066424 0.550465 0.178246
            +v 0.200633 0.550663 0.351164
            +v 0.093478 0.550711 0.165607
            +v 0.255684 0.550692 0.312606
            +v 0.117962 0.551249 0.148472
            +v 0.303216 0.551004 0.265073
            +v 0.139083 0.551381 0.127332
            +v 0.341794 0.550503 0.210003
            +v 0.156237 0.551013 0.102867
            +v 0.370207 0.551353 0.149058
            +v 0.168857 0.550484 0.075795
            +v 0.387588 0.554612 0.084145
            +v 0.176602 0.550824 0.046928
            +v 0.297209 0.037340 0.041997
            +v 0.298720 0.037340 -0.022614
            +v 0.286440 0.037340 -0.083956
            +v 0.261767 0.037340 -0.140292
            +v 0.225948 0.037340 -0.189883
            +v 0.180381 0.037340 -0.230973
            +v 0.126350 0.037340 -0.261824
            +v 0.065177 0.037340 -0.280697
            +v 0.000264 0.037340 -0.285817
            +v -0.062079 0.037340 -0.276881
            +v -0.119813 0.037340 -0.255174
            +v -0.171275 0.037340 -0.222019
            +v -0.214651 0.037340 -0.178775
            +v -0.248203 0.037340 -0.126727
            +v -0.270231 0.037340 -0.067237
            +v -0.278959 0.037340 -0.002513
            +v -0.273405 0.037340 0.060700
            +v -0.254777 0.037340 0.119756
            +v -0.224323 0.037340 0.172918
            +v -0.183479 0.037340 0.218486
            +v -0.133529 0.037340 0.254683
            +v -0.075757 0.037340 0.279771
            +v -0.011789 0.037340 0.291976
            +v 0.052180 0.037340 0.289916
            +v 0.112445 0.037340 0.274425
            +v 0.167232 0.037340 0.246824
            +v 0.214877 0.037340 0.208454
            +v 0.253568 0.037340 0.160639
            +v 0.281604 0.037340 0.104718
            +v 0.375799 0.055363 0.057224
            +v 0.377764 0.055363 -0.025561
            +v 0.362046 0.055363 -0.104170
            +v 0.330421 0.055363 -0.176338
            +v 0.284513 0.055363 -0.239872
            +v 0.226137 0.055363 -0.292523
            +v 0.156917 0.055363 -0.332045
            +v 0.078553 0.055363 -0.356227
            +v -0.004610 0.055363 -0.362802
            +v -0.084485 0.055363 -0.351353
            +v -0.158504 0.055363 -0.323506
            +v -0.224399 0.055363 -0.281037
            +v -0.279979 0.055363 -0.225627
            +v -0.323015 0.055363 -0.158957
            +v -0.351240 0.055363 -0.082728
            +v -0.362386 0.055363 0.000208
            +v -0.355283 0.055363 0.081179
            +v -0.331403 0.055363 0.156841
            +v -0.292410 0.055363 0.224985
            +v -0.240079 0.055363 0.283342
            +v -0.176035 0.055363 0.329722
            +v -0.102054 0.055363 0.361857
            +v -0.020063 0.055363 0.377518
            +v 0.061890 0.055363 0.374874
            +v 0.139083 0.055363 0.355018
            +v 0.209323 0.055363 0.319671
            +v 0.270344 0.055363 0.270495
            +v 0.319917 0.055363 0.209248
            +v 0.355812 0.055363 0.137571
            +v 0.428130 0.056615 0.069674
            +v 0.430322 0.056615 -0.025447
            +v 0.412299 0.056615 -0.115732
            +v 0.375950 0.056615 -0.198668
            +v 0.323242 0.056615 -0.271629
            +v 0.256175 0.056615 -0.332121
            +v 0.176640 0.056615 -0.377537
            +v 0.086639 0.056615 -0.405346
            +v -0.008955 0.056615 -0.412865
            +v -0.100694 0.056615 -0.399679
            +v -0.185708 0.056615 -0.367751
            +v -0.261389 0.056615 -0.318934
            +v -0.325244 0.056615 -0.255287
            +v -0.374666 0.056615 -0.178680
            +v -0.407122 0.056615 -0.091116
            +v -0.419931 0.056615 0.004156
            +v -0.411770 0.056615 0.097180
            +v -0.384338 0.056615 0.184121
            +v -0.339565 0.056615 0.262391
            +v -0.279412 0.056615 0.329438
            +v -0.205885 0.056615 0.382714
            +v -0.120871 0.056615 0.419648
            +v -0.026675 0.056615 0.437633
            +v 0.067444 0.056615 0.434591
            +v 0.156161 0.056615 0.411789
            +v 0.236830 0.056615 0.371171
            +v 0.306919 0.056615 0.314684
            +v 0.363897 0.056615 0.244311
            +v 0.405157 0.056615 0.161980
            +v 0.322637 0.006896 0.054730
            +v 0.324300 0.006896 -0.016530
            +v 0.310773 0.006896 -0.084202
            +v 0.283531 0.006896 -0.146337
            +v 0.244047 0.006896 -0.201011
            +v 0.193794 0.006896 -0.246351
            +v 0.134209 0.006896 -0.280376
            +v 0.066764 0.006896 -0.301214
            +v -0.004874 0.006896 -0.306844
            +v -0.073603 0.006896 -0.296982
            +v -0.137307 0.006896 -0.273008
            +v -0.194058 0.006896 -0.236471
            +v -0.241893 0.006896 -0.188769
            +v -0.278921 0.006896 -0.131356
            +v -0.303254 0.006896 -0.065744
            +v -0.312851 0.006896 0.005649
            +v -0.306730 0.006896 0.075341
            +v -0.286138 0.006896 0.140481
            +v -0.252586 0.006896 0.199140
            +v -0.207547 0.006896 0.249374
            +v -0.152458 0.006896 0.289293
            +v -0.088755 0.006896 0.316970
            +v -0.018174 0.006896 0.330440
            +v 0.052369 0.006896 0.328173
            +v 0.118831 0.006896 0.311075
            +v 0.179285 0.006896 0.280640
            +v 0.231842 0.006896 0.238322
            +v 0.274500 0.006896 0.185595
            +v 0.305408 0.006896 0.123913
            +v 0.297209 0.037340 0.041997
            +v 0.298720 0.037340 -0.022614
            +v 0.286440 0.037340 -0.083956
            +v 0.261767 0.037340 -0.140292
            +v 0.225948 0.037340 -0.189883
            +v 0.180381 0.037340 -0.230973
            +v 0.126350 0.037340 -0.261824
            +v 0.065177 0.037340 -0.280697
            +v 0.000264 0.037340 -0.285817
            +v -0.062079 0.037340 -0.276881
            +v -0.119813 0.037340 -0.255174
            +v -0.171275 0.037340 -0.222019
            +v -0.214651 0.037340 -0.178775
            +v -0.248203 0.037340 -0.126727
            +v -0.270231 0.037340 -0.067237
            +v -0.278959 0.037340 -0.002513
            +v -0.273405 0.037340 0.060700
            +v -0.254777 0.037340 0.119756
            +v -0.224323 0.037340 0.172918
            +v -0.183479 0.037340 0.218486
            +v -0.133529 0.037340 0.254683
            +v -0.075757 0.037340 0.279771
            +v -0.011789 0.037340 0.291976
            +v 0.052180 0.037340 0.289916
            +v 0.112445 0.037340 0.274425
            +v 0.167232 0.037340 0.246824
            +v 0.214877 0.037340 0.208454
            +v 0.253568 0.037340 0.160639
            +v 0.281604 0.037340 0.104718
            +v 0.322637 0.006896 0.054730
            +v 0.324300 0.006896 -0.016530
            +v 0.310773 0.006896 -0.084202
            +v 0.283531 0.006896 -0.146337
            +v 0.244047 0.006896 -0.201011
            +v 0.193794 0.006896 -0.246351
            +v 0.134209 0.006896 -0.280376
            +v 0.066764 0.006896 -0.301214
            +v -0.004874 0.006896 -0.306844
            +v -0.073603 0.006896 -0.296982
            +v -0.137307 0.006896 -0.273008
            +v -0.194058 0.006896 -0.236471
            +v -0.241893 0.006896 -0.188769
            +v -0.278921 0.006896 -0.131356
            +v -0.303254 0.006896 -0.065744
            +v -0.312851 0.006896 0.005649
            +v -0.306730 0.006896 0.075341
            +v -0.286138 0.006896 0.140481
            +v -0.252586 0.006896 0.199140
            +v -0.207547 0.006896 0.249374
            +v -0.152458 0.006896 0.289293
            +v -0.088755 0.006896 0.316970
            +v -0.018174 0.006896 0.330440
            +v 0.052369 0.006896 0.328173
            +v 0.118831 0.006896 0.311075
            +v 0.179285 0.006896 0.280640
            +v 0.231842 0.006896 0.238322
            +v 0.274500 0.006896 0.185595
            +v 0.305408 0.006896 0.123913
            +v -0.245369 0.047962 0.587862
            +v -0.244198 0.069206 0.588013
            +v -0.180796 0.062873 0.593794
            +v -0.117508 0.057328 0.600349
            +v -0.054371 0.053993 0.609115
            +v 0.008615 0.052874 0.620110
            +v 0.071638 0.051136 0.630482
            +v 0.386265 0.011822 0.672781
            +v 0.387437 0.033066 0.672932
            +v 0.389099 0.011822 0.651698
            +v 0.073263 0.029892 0.609229
            +v 0.009975 0.035385 0.602616
            +v -0.053389 0.041492 0.596628
            +v -0.116564 0.045388 0.588410
            +v -0.179587 0.047065 0.577981
            +v -0.242535 0.047962 0.566778
            +v -0.241364 0.069206 0.566948
            +v -0.178718 0.062873 0.578114
            +v -0.115883 0.057328 0.588504
            +v -0.052709 0.053993 0.596722
            +v 0.010957 0.052874 0.602749
            +v 0.074472 0.051136 0.609399
            +v 0.390308 0.033066 0.651849
            +v -0.181703 0.047065 0.593681
            +v -0.118150 0.045388 0.600274
            +v -0.055051 0.041492 0.609021
            +v 0.007632 0.035385 0.619978
            +v 0.070429 0.029892 0.630331
            +v -0.396429 0.033170 0.556822
            +v -0.234601 0.075058 0.578586
            +v -0.243631 0.075370 0.604600
            +v -0.262825 0.076276 0.627384
            +v -0.290974 0.077722 0.645388
            +v -0.326113 0.079606 0.657384
            +v -0.365824 0.081802 0.662561
            +v -0.407462 0.084154 0.660539
            +v -0.448118 0.086506 0.651490
            +v -0.485071 0.088703 0.636017
            +v -0.515789 0.090587 0.615161
            +v -0.538157 0.092032 0.590374
            +v -0.550701 0.092939 0.563302
            +v -0.552515 0.093251 0.535852
            +v -0.543522 0.092939 0.509819
            +v -0.524290 0.092032 0.487035
            +v -0.496141 0.090587 0.469031
            +v -0.461002 0.088703 0.457035
            +v -0.421291 0.086506 0.451877
            +v -0.379653 0.084154 0.453880
            +v -0.338998 0.081802 0.462929
            +v -0.302045 0.079606 0.478402
            +v -0.271327 0.077722 0.499258
            +v -0.248959 0.076276 0.524045
            +v -0.236414 0.075370 0.551098
            +v -0.249450 0.062471 0.602881
            +v -0.268039 0.063350 0.624890
            +v -0.295206 0.064748 0.642290
            +v -0.329136 0.066566 0.653870
            +v -0.367525 0.068682 0.658858
            +v -0.407727 0.070958 0.656912
            +v -0.446984 0.073230 0.648184
            +v -0.482690 0.075351 0.633221
            +v -0.512351 0.077169 0.613083
            +v -0.534001 0.078567 0.589146
            +v -0.546092 0.079446 0.563000
            +v -0.547867 0.079743 0.536476
            +v -0.539139 0.079446 0.511330
            +v -0.520550 0.078567 0.489340
            +v -0.493383 0.077169 0.471941
            +v -0.459453 0.075351 0.460360
            +v -0.421064 0.073230 0.455353
            +v -0.380862 0.070958 0.457299
            +v -0.341605 0.068682 0.466046
            +v -0.305899 0.066566 0.480990
            +v -0.276239 0.064748 0.501129
            +v -0.254626 0.063350 0.525084
            +v -0.242535 0.062471 0.551211
            +v -0.240759 0.062174 0.577755
            +v -0.289576 0.041893 0.590450
            +v -0.303141 0.042535 0.606546
            +v -0.323053 0.043555 0.619298
            +v -0.347877 0.044887 0.627762
            +v -0.375988 0.046436 0.631427
            +v -0.405422 0.048104 0.630010
            +v -0.434176 0.049766 0.623605
            +v -0.460322 0.051320 0.612667
            +v -0.482010 0.052652 0.597912
            +v -0.497842 0.053672 0.580381
            +v -0.506683 0.054314 0.561262
            +v -0.508005 0.054536 0.541822
            +v -0.501620 0.054314 0.523440
            +v -0.488018 0.053672 0.507325
            +v -0.468106 0.052652 0.494592
            +v -0.443281 0.051320 0.486110
            +v -0.415208 0.049766 0.482445
            +v -0.385774 0.048104 0.483880
            +v -0.357021 0.046436 0.490266
            +v -0.330874 0.044887 0.501204
            +v -0.309148 0.043555 0.515959
            +v -0.293355 0.042535 0.533491
            +v -0.284475 0.041893 0.552628
            +v -0.283191 0.041671 0.572049
            +v 0.442904 0.602002 0.103094
            +v 0.489756 0.581816 0.109403
            +v 0.525915 0.533207 0.114259
            +v 0.531734 0.433864 0.115033
            +v 0.500297 0.364814 0.110820
            +v 0.418495 0.247183 0.099825
            +v 0.316819 0.174855 0.086147
            +v 0.195305 0.065376 0.069825
            +v 0.221263 0.117362 0.073301
            +v 0.277032 0.197771 0.080801
            +v 0.340509 0.227497 0.089340
            +v 0.402248 0.277108 0.097634
            +v 0.492816 0.441893 0.109800
            +v 0.490511 0.511822 0.109498
            +v 0.464478 0.557030 0.106003
            +v 0.385888 0.569159 0.095442
            +v 0.388533 0.582770 0.095782
            +v 0.448193 0.602002 0.071620
            +v 0.493421 0.581816 0.077684
            +v 0.529958 0.533207 0.082596
            +v 0.536041 0.433864 0.083408
            +v 0.504529 0.364823 0.079176
            +v 0.422765 0.247173 0.068181
            +v 0.321353 0.174968 0.054560
            +v 0.199046 0.065173 0.038105
            +v 0.230142 0.119114 0.042299
            +v 0.290219 0.201162 0.050385
            +v 0.345874 0.227922 0.057847
            +v 0.405649 0.276786 0.065895
            +v 0.497010 0.441883 0.078175
            +v 0.494705 0.511803 0.077854
            +v 0.468937 0.557040 0.074397
            +v 0.392764 0.569159 0.064157
            +v 0.397412 0.582770 0.064781
            +v 0.393936 0.587238 0.096519
            +v 0.410069 0.595891 0.098692
            +v 0.431228 0.601426 0.101544
            +v 0.442904 0.602002 0.103094
            +v 0.454881 0.600567 0.104718
            +v 0.466859 0.596732 0.106324
            +v 0.478534 0.590365 0.107892
            +v 0.489756 0.581816 0.109403
            +v 0.500335 0.571454 0.110820
            +v 0.510008 0.559647 0.112124
            +v 0.518585 0.546772 0.113276
            +v 0.525915 0.533207 0.114259
            +v 0.531772 0.519312 0.115052
            +v 0.535928 0.505446 0.115619
            +v 0.538422 0.491645 0.115940
            +v 0.539177 0.477759 0.116053
            +v 0.538346 0.463600 0.115940
            +v 0.535814 0.449025 0.115600
            +v 0.531734 0.433864 0.115033
            +v 0.518849 0.401133 0.113314
            +v 0.489453 0.345988 0.109366
            +v 0.465838 0.308884 0.106192
            +v 0.441543 0.275011 0.102924
            +v 0.429793 0.260228 0.101337
            +v 0.407689 0.235725 0.098371
            +v 0.386983 0.216922 0.095575
            +v 0.367147 0.202465 0.092911
            +v 0.316819 0.174855 0.086147
            +v 0.294262 0.160464 0.083125
            +v 0.269022 0.139659 0.079724
            +v 0.255268 0.126184 0.077873
            +v 0.206074 0.073551 0.071261
            +v 0.195268 0.067794 0.069806
            +v 0.201086 0.081420 0.070599
            +v 0.221263 0.117362 0.073301
            +v 0.248883 0.160450 0.077023
            +v 0.263316 0.180636 0.078968
            +v 0.277032 0.197771 0.080801
            +v 0.289161 0.210367 0.082426
            +v 0.299665 0.218467 0.083843
            +v 0.317196 0.225259 0.086185
            +v 0.340509 0.227497 0.089340
            +v 0.358494 0.235517 0.091739
            +v 0.379540 0.252898 0.094592
            +v 0.402248 0.277108 0.097634
            +v 0.424994 0.305446 0.100694
            +v 0.446229 0.335276 0.103547
            +v 0.472640 0.380740 0.107099
            +v 0.485222 0.411297 0.108799
            +v 0.489718 0.426609 0.109385
            +v 0.492816 0.441893 0.109800
            +v 0.494517 0.457035 0.110046
            +v 0.494479 0.486015 0.110027
            +v 0.490511 0.511822 0.109498
            +v 0.483635 0.532763 0.108572
            +v 0.474793 0.547603 0.107382
            +v 0.464478 0.557030 0.106003
            +v 0.441506 0.564266 0.102924
            +v 0.407273 0.563151 0.098314
            +v 0.388759 0.566948 0.095839
            +v 0.385208 0.578671 0.095348
            +v 0.402664 0.587238 0.065499
            +v 0.417740 0.595891 0.067520
            +v 0.437312 0.601426 0.070146
            +v 0.448193 0.602002 0.071620
            +v 0.459491 0.600567 0.073131
            +v 0.470939 0.596732 0.074661
            +v 0.482350 0.590365 0.076191
            +v 0.493421 0.581816 0.077684
            +v 0.503963 0.571454 0.079101
            +v 0.513711 0.559647 0.080423
            +v 0.522439 0.546772 0.081594
            +v 0.529958 0.533207 0.082596
            +v 0.535966 0.519312 0.083408
            +v 0.540273 0.505446 0.083975
            +v 0.542804 0.491645 0.084334
            +v 0.543636 0.477759 0.084428
            +v 0.542729 0.463600 0.084315
            +v 0.540197 0.449025 0.083975
            +v 0.536041 0.433864 0.083408
            +v 0.530336 0.417947 0.082652
            +v 0.514429 0.383328 0.080518
            +v 0.493647 0.345997 0.077722
            +v 0.457904 0.291362 0.072923
            +v 0.422765 0.247173 0.068181
            +v 0.401417 0.225665 0.065328
            +v 0.381165 0.209200 0.062608
            +v 0.361555 0.196444 0.059963
            +v 0.321353 0.174968 0.054560
            +v 0.298796 0.160577 0.051537
            +v 0.273291 0.139659 0.048099
            +v 0.259236 0.126071 0.046210
            +v 0.209096 0.073088 0.039465
            +v 0.199499 0.067794 0.038181
            +v 0.206905 0.082015 0.039182
            +v 0.230142 0.119114 0.042299
            +v 0.260596 0.163274 0.046380
            +v 0.276050 0.183838 0.048458
            +v 0.290219 0.201162 0.050385
            +v 0.302272 0.213716 0.051991
            +v 0.312096 0.221556 0.053313
            +v 0.327058 0.227403 0.055316
            +v 0.345874 0.227922 0.057847
            +v 0.361970 0.235243 0.060020
            +v 0.382563 0.252435 0.062797
            +v 0.417475 0.290738 0.067482
            +v 0.440221 0.320323 0.070524
            +v 0.460435 0.350484 0.073263
            +v 0.477174 0.380843 0.075492
            +v 0.489605 0.411345 0.077174
            +v 0.493988 0.426619 0.077759
            +v 0.497010 0.441883 0.078175
            +v 0.498711 0.457006 0.078402
            +v 0.498597 0.485977 0.078383
            +v 0.494705 0.511803 0.077854
            +v 0.487904 0.532763 0.076947
            +v 0.479138 0.547612 0.075776
            +v 0.468937 0.557040 0.074397
            +v 0.445700 0.564266 0.071279
            +v 0.411052 0.563151 0.066613
            +v 0.394880 0.566948 0.064441
            +v 0.393936 0.578671 0.064308
            +v 0.242497 0.103448 0.043962
            +v 0.243744 0.103448 -0.009257
            +v 0.233618 0.103448 -0.059774
            +v 0.213290 0.103448 -0.106173
            +v 0.183819 0.103448 -0.146999
            +v 0.146300 0.103448 -0.180834
            +v 0.101790 0.103448 -0.206263
            +v 0.051424 0.103448 -0.221811
            +v -0.002040 0.103448 -0.226024
            +v -0.053389 0.103448 -0.218656
            +v -0.100921 0.103448 -0.200765
            +v -0.143277 0.103448 -0.173466
            +v -0.179020 0.103448 -0.137855
            +v -0.206678 0.103448 -0.094989
            +v -0.224815 0.103448 -0.046002
            +v -0.231956 0.103448 0.007292
            +v -0.227422 0.103448 0.059359
            +v -0.212081 0.103448 0.107987
            +v -0.187031 0.103448 0.151778
            +v -0.153365 0.103448 0.189298
            +v -0.112218 0.103448 0.219109
            +v -0.064648 0.103448 0.239758
            +v -0.011978 0.103448 0.249828
            +v 0.040693 0.103448 0.248127
            +v 0.090341 0.103448 0.235356
            +v 0.135456 0.103448 0.212629
            +v 0.174675 0.103448 0.181042
            +v 0.206565 0.103448 0.141671
            +v 0.229651 0.103448 0.095612
            +v 0.322033 0.256090 0.054655
            +v 0.323695 0.256090 -0.016493
            +v 0.310169 0.256090 -0.084013
            +v 0.283002 0.256090 -0.146035
            +v 0.243593 0.256090 -0.200614
            +v 0.193416 0.256090 -0.245860
            +v 0.133944 0.256090 -0.279828
            +v 0.066651 0.256090 -0.300609
            +v -0.004836 0.256090 -0.306239
            +v -0.073452 0.256090 -0.296377
            +v -0.137042 0.256090 -0.272479
            +v -0.193681 0.256090 -0.235999
            +v -0.241402 0.256090 -0.188372
            +v -0.278392 0.256090 -0.131091
            +v -0.302650 0.256090 -0.065612
            +v -0.312209 0.256090 0.005649
            +v -0.306126 0.256090 0.075228
            +v -0.285571 0.256090 0.140235
            +v -0.252132 0.256090 0.198781
            +v -0.207132 0.256090 0.248940
            +v -0.152118 0.256090 0.288783
            +v -0.088566 0.256090 0.316403
            +v -0.018136 0.256090 0.329854
            +v 0.052293 0.256090 0.327568
            +v 0.118642 0.256090 0.310509
            +v 0.178983 0.256090 0.280130
            +v 0.231389 0.256090 0.237907
            +v 0.273972 0.256090 0.185255
            +v 0.304841 0.256090 0.123686
            +v 0.367449 0.374203 0.060757
            +v 0.369338 0.374203 -0.020611
            +v 0.353922 0.374203 -0.097860
            +v 0.322826 0.374203 -0.168800
            +v 0.277750 0.374203 -0.231238
            +v 0.220356 0.374203 -0.282983
            +v 0.152307 0.374203 -0.321844
            +v 0.075303 0.374203 -0.345610
            +v -0.006461 0.374203 -0.352033
            +v -0.084938 0.374203 -0.340774
            +v -0.157672 0.374203 -0.313418
            +v -0.222434 0.374203 -0.271704
            +v -0.277070 0.374203 -0.217239
            +v -0.319350 0.374203 -0.151703
            +v -0.347121 0.374203 -0.076796
            +v -0.358041 0.374203 0.004704
            +v -0.351089 0.374203 0.084296
            +v -0.327587 0.374203 0.158655
            +v -0.289274 0.374203 0.225627
            +v -0.237850 0.374203 0.282983
            +v -0.174902 0.374203 0.328569
            +v -0.102206 0.374203 0.360157
            +v -0.021650 0.374203 0.375535
            +v 0.058905 0.374203 0.372947
            +v 0.134775 0.374203 0.353431
            +v 0.203807 0.374203 0.318689
            +v 0.263770 0.374203 0.270363
            +v 0.312511 0.374203 0.210154
            +v 0.347801 0.374203 0.139725
            +v 0.394351 0.479479 0.064365
            +v 0.396392 0.479479 -0.023048
            +v 0.379804 0.479479 -0.106060
            +v 0.346366 0.479479 -0.182270
            +v 0.297964 0.479479 -0.249374
            +v 0.236301 0.479479 -0.304954
            +v 0.163189 0.479479 -0.346706
            +v 0.080442 0.479479 -0.372248
            +v -0.007406 0.479479 -0.379162
            +v -0.091739 0.479479 -0.367071
            +v -0.169877 0.479479 -0.337675
            +v -0.239475 0.479479 -0.292864
            +v -0.298153 0.479479 -0.234336
            +v -0.343570 0.479479 -0.163926
            +v -0.373419 0.479479 -0.083427
            +v -0.385208 0.479479 0.004156
            +v -0.377688 0.479479 0.089661
            +v -0.352487 0.479479 0.169574
            +v -0.311302 0.479479 0.241515
            +v -0.256024 0.479479 0.303160
            +v -0.188429 0.479479 0.352128
            +v -0.110291 0.479479 0.386058
            +v -0.023728 0.479479 0.402607
            +v 0.062835 0.479479 0.399811
            +v 0.144373 0.479479 0.378841
            +v 0.218505 0.479479 0.341510
            +v 0.282964 0.479479 0.289595
            +v 0.335333 0.479479 0.224909
            +v 0.373230 0.479479 0.149228
            +v 0.415775 0.625183 0.067255
            +v 0.417928 0.625183 -0.024994
            +v 0.400434 0.625183 -0.112577
            +v 0.365144 0.625183 -0.193019
            +v 0.314060 0.625183 -0.263808
            +v 0.248996 0.625183 -0.322448
            +v 0.171841 0.625183 -0.366504
            +v 0.084561 0.625183 -0.393482
            +v -0.008161 0.625183 -0.400775
            +v -0.097143 0.625183 -0.388004
            +v -0.179625 0.625183 -0.357021
            +v -0.253039 0.625183 -0.309677
            +v -0.314967 0.625183 -0.247938
            +v -0.362915 0.625183 -0.173636
            +v -0.394389 0.625183 -0.088698
            +v -0.406820 0.625183 0.003703
            +v -0.398885 0.625183 0.093931
            +v -0.372285 0.625183 0.178265
            +v -0.328834 0.625183 0.254192
            +v -0.270533 0.625183 0.319218
            +v -0.199197 0.625183 0.370906
            +v -0.116715 0.625183 0.406707
            +v -0.025391 0.625183 0.424163
            +v 0.065933 0.625183 0.421216
            +v 0.151967 0.625183 0.399093
            +v 0.230218 0.625183 0.359684
            +v 0.298229 0.625183 0.304917
            +v 0.353469 0.625183 0.236641
            +v 0.393482 0.625183 0.156785
            +v 0.413810 0.634261 0.066991
            +v 0.415926 0.634261 -0.024824
            +v 0.398507 0.634261 -0.111973
            +v 0.363444 0.634261 -0.192018
            +v 0.312549 0.634261 -0.262466
            +v 0.247825 0.634261 -0.320824
            +v 0.171048 0.634261 -0.364691
            +v 0.084183 0.634261 -0.391517
            +v -0.008086 0.634261 -0.398772
            +v -0.096651 0.634261 -0.386077
            +v -0.178718 0.634261 -0.355245
            +v -0.251792 0.634261 -0.308128
            +v -0.313418 0.634261 -0.246673
            +v -0.361139 0.634261 -0.172748
            +v -0.392424 0.634261 -0.088226
            +v -0.404817 0.634261 0.003760
            +v -0.396921 0.634261 0.093553
            +v -0.370434 0.634261 0.177452
            +v -0.327209 0.634261 0.253001
            +v -0.269173 0.634261 0.317725
            +v -0.198177 0.634261 0.369168
            +v -0.116148 0.634261 0.404799
            +v -0.025202 0.634261 0.422160
            +v 0.065631 0.634261 0.419232
            +v 0.151249 0.634261 0.397204
            +v 0.229160 0.634261 0.358022
            +v 0.296831 0.634261 0.303500
            +v 0.351806 0.634261 0.235564
            +v 0.391593 0.634261 0.156086
            +v 0.315118 0.357228 0.053729
            +v 0.316743 0.357228 -0.015850
            +v 0.303556 0.357228 -0.081916
            +v 0.276956 0.357228 -0.142578
            +v 0.238417 0.357228 -0.195967
            +v 0.189298 0.357228 -0.240212
            +v 0.131148 0.357228 -0.273405
            +v 0.065328 0.357228 -0.293770
            +v -0.004610 0.357228 -0.299249
            +v -0.071714 0.357228 -0.289614
            +v -0.133906 0.357228 -0.266245
            +v -0.189298 0.357228 -0.230558
            +v -0.235999 0.357228 -0.183989
            +v -0.272158 0.357228 -0.127955
            +v -0.295886 0.357228 -0.063893
            +v -0.305257 0.357228 0.005800
            +v -0.299287 0.357228 0.073849
            +v -0.279224 0.357228 0.137439
            +v -0.246465 0.357228 0.194701
            +v -0.202446 0.357228 0.243744
            +v -0.148642 0.357228 0.282719
            +v -0.086487 0.357228 0.309734
            +v -0.017570 0.357228 0.322883
            +v 0.051311 0.357228 0.320673
            +v 0.116148 0.357228 0.303991
            +v 0.175204 0.357228 0.274274
            +v 0.226477 0.357228 0.232957
            +v 0.268115 0.357228 0.181476
            +v 0.298304 0.357228 0.121249
            +v 0.217220 0.056138 0.040561
            +v 0.218278 0.056138 -0.006952
            +v 0.209285 0.056138 -0.052066
            +v 0.191111 0.056138 -0.093478
            +v 0.164814 0.056138 -0.129958
            +v 0.131299 0.056138 -0.160166
            +v 0.091551 0.056138 -0.182855
            +v 0.046588 0.056138 -0.196722
            +v -0.001171 0.056138 -0.200501
            +v -0.046965 0.056138 -0.193907
            +v -0.089435 0.056138 -0.177962
            +v -0.127256 0.056138 -0.153573
            +v -0.159184 0.056138 -0.121778
            +v -0.183857 0.056138 -0.083521
            +v -0.200066 0.056138 -0.039768
            +v -0.206452 0.056138 0.007821
            +v -0.202371 0.056138 0.054296
            +v -0.188655 0.056138 0.097728
            +v -0.166287 0.056138 0.136835
            +v -0.136249 0.056138 0.170330
            +v -0.099523 0.056138 0.196930
            +v -0.057054 0.056138 0.215387
            +v -0.010013 0.056138 0.224361
            +v 0.037028 0.056138 0.222850
            +v 0.081311 0.056138 0.211458
            +v 0.121627 0.056138 0.191168
            +v 0.156652 0.056138 0.162943
            +v 0.185104 0.056138 0.127785
            +v 0.205696 0.056138 0.086676
            +v 0.242497 0.103448 0.043962
            +v 0.243744 0.103448 -0.009257
            +v 0.233618 0.103448 -0.059774
            +v 0.213290 0.103448 -0.106173
            +v 0.183819 0.103448 -0.146999
            +v 0.146300 0.103448 -0.180834
            +v 0.101790 0.103448 -0.206263
            +v 0.051424 0.103448 -0.221811
            +v -0.002040 0.103448 -0.226024
            +v -0.053389 0.103448 -0.218656
            +v -0.100921 0.103448 -0.200765
            +v -0.143277 0.103448 -0.173466
            +v -0.179020 0.103448 -0.137855
            +v -0.206678 0.103448 -0.094989
            +v -0.224815 0.103448 -0.046002
            +v -0.231956 0.103448 0.007292
            +v -0.227422 0.103448 0.059359
            +v -0.212081 0.103448 0.107987
            +v -0.187031 0.103448 0.151778
            +v -0.153365 0.103448 0.189298
            +v -0.112218 0.103448 0.219109
            +v -0.064648 0.103448 0.239758
            +v -0.011978 0.103448 0.249828
            +v 0.040693 0.103448 0.248127
            +v 0.090341 0.103448 0.235356
            +v 0.135456 0.103448 0.212629
            +v 0.174675 0.103448 0.181042
            +v 0.206565 0.103448 0.141671
            +v 0.229651 0.103448 0.095612
            +v 0.217220 0.056138 0.040561
            +v 0.218278 0.056138 -0.006952
            +v 0.209285 0.056138 -0.052066
            +v 0.191111 0.056138 -0.093478
            +v 0.164814 0.056138 -0.129958
            +v 0.131299 0.056138 -0.160166
            +v 0.091551 0.056138 -0.182855
            +v 0.046588 0.056138 -0.196722
            +v -0.001171 0.056138 -0.200501
            +v -0.046965 0.056138 -0.193907
            +v -0.089435 0.056138 -0.177962
            +v -0.127256 0.056138 -0.153573
            +v -0.159184 0.056138 -0.121778
            +v -0.183857 0.056138 -0.083521
            +v -0.200066 0.056138 -0.039768
            +v -0.206452 0.056138 0.007821
            +v -0.202371 0.056138 0.054296
            +v -0.188655 0.056138 0.097728
            +v -0.166287 0.056138 0.136835
            +v -0.136249 0.056138 0.170330
            +v -0.099523 0.056138 0.196930
            +v -0.057054 0.056138 0.215387
            +v -0.010013 0.056138 0.224361
            +v 0.037028 0.056138 0.222850
            +v 0.081311 0.056138 0.211458
            +v 0.121627 0.056138 0.191168
            +v 0.156652 0.056138 0.162943
            +v 0.185104 0.056138 0.127785
            +v 0.205696 0.056138 0.086676
            +vt 0.500000 0.500000
            +vt 1.000000 0.500000
            +vt 0.722222 0.500000
            +vt 0.992404 0.586824
            +vt 0.718846 0.538589
            +vt 0.969846 0.671010
            +vt 0.708821 0.576005
            +vt 0.933013 0.750000
            +vt 0.692450 0.611111
            +vt 0.883022 0.821394
            +vt 0.670232 0.642842
            +vt 0.821394 0.883022
            +vt 0.642842 0.670232
            +vt 0.750000 0.933013
            +vt 0.611111 0.692450
            +vt 0.671010 0.969846
            +vt 0.576005 0.708821
            +vt 0.586824 0.992404
            +vt 0.538588 0.718846
            +vt 0.500000 1.000000
            +vt 0.500000 0.722222
            +vt 0.413176 0.992404
            +vt 0.461412 0.718846
            +vt 0.328990 0.969846
            +vt 0.423996 0.708821
            +vt 0.250000 0.933013
            +vt 0.388889 0.692450
            +vt 0.178606 0.883022
            +vt 0.357158 0.670232
            +vt 0.116978 0.821394
            +vt 0.329768 0.642842
            +vt 0.066987 0.750000
            +vt 0.307550 0.611111
            +vt 0.030154 0.671010
            +vt 0.291179 0.576005
            +vt 0.007596 0.586824
            +vt 0.281154 0.538589
            +vt 0.000000 0.500000
            +vt 0.277778 0.500000
            +vt 0.007596 0.413176
            +vt 0.281154 0.461412
            +vt 0.030154 0.328990
            +vt 0.291179 0.423995
            +vt 0.066987 0.250000
            +vt 0.307550 0.388889
            +vt 0.116978 0.178606
            +vt 0.329768 0.357158
            +vt 0.178606 0.116978
            +vt 0.357158 0.329768
            +vt 0.250000 0.066987
            +vt 0.388889 0.307550
            +vt 0.328990 0.030154
            +vt 0.423996 0.291179
            +vt 0.413176 0.007596
            +vt 0.461412 0.281154
            +vt 0.500000 0.000000
            +vt 0.500000 0.277778
            +vt 0.586824 0.007596
            +vt 0.538588 0.281154
            +vt 0.671010 0.030154
            +vt 0.576005 0.291179
            +vt 0.750000 0.066987
            +vt 0.611111 0.307550
            +vt 0.821394 0.116978
            +vt 0.642842 0.329768
            +vt 0.883022 0.178606
            +vt 0.670232 0.357158
            +vt 0.933013 0.250000
            +vt 0.692450 0.388889
            +vt 0.969846 0.328990
            +vt 0.708821 0.423995
            +vt 0.992404 0.413176
            +vt 0.718846 0.461412
            +vt 1.000000 0.000000
            +vt 0.000000 0.000000
            +vt 0.035601 0.000000
            +vt 0.070060 0.000000
            +vt 0.103942 0.000000
            +vt 0.137630 0.000000
            +vt 0.171432 0.000000
            +vt 0.205703 0.000000
            +vt 0.240953 0.000000
            +vt 0.276835 0.000000
            +vt 0.311518 0.000000
            +vt 0.345503 0.000000
            +vt 0.379209 0.000000
            +vt 0.412954 0.000000
            +vt 0.447067 0.000000
            +vt 0.482012 0.000000
            +vt 0.517988 0.000000
            +vt 0.552933 0.000000
            +vt 0.587046 0.000000
            +vt 0.620791 0.000000
            +vt 0.654497 0.000000
            +vt 0.688482 0.000000
            +vt 0.723165 0.000000
            +vt 0.759048 0.000000
            +vt 0.794297 0.000000
            +vt 0.828568 0.000000
            +vt 0.862370 0.000000
            +vt 0.896058 0.000000
            +vt 0.929940 0.000000
            +vt 0.964399 0.000000
            +vt 1.000000 0.219800
            +vt 0.000000 0.219800
            +vt 0.035601 0.219800
            +vt 0.070060 0.219800
            +vt 0.103942 0.219800
            +vt 0.137630 0.219800
            +vt 0.171432 0.219800
            +vt 0.205703 0.219800
            +vt 0.240953 0.219800
            +vt 0.276835 0.219800
            +vt 0.311518 0.219800
            +vt 0.345503 0.219800
            +vt 0.379209 0.219800
            +vt 0.412954 0.219800
            +vt 0.447067 0.219800
            +vt 0.482012 0.219800
            +vt 0.517988 0.219800
            +vt 0.552933 0.219800
            +vt 0.587046 0.219800
            +vt 0.620791 0.219800
            +vt 0.654497 0.219800
            +vt 0.688482 0.219800
            +vt 0.723165 0.219800
            +vt 0.759048 0.219800
            +vt 0.794297 0.219800
            +vt 0.828568 0.219800
            +vt 0.862370 0.219800
            +vt 0.896058 0.219800
            +vt 0.929940 0.219800
            +vt 0.964399 0.219800
            +vt 1.000000 0.386960
            +vt 0.000000 0.386960
            +vt 0.035601 0.386960
            +vt 0.070060 0.386960
            +vt 0.103942 0.386960
            +vt 0.137630 0.386960
            +vt 0.171432 0.386960
            +vt 0.205703 0.386960
            +vt 0.240953 0.386960
            +vt 0.276835 0.386960
            +vt 0.311518 0.386960
            +vt 0.345503 0.386960
            +vt 0.379209 0.386960
            +vt 0.412954 0.386960
            +vt 0.447067 0.386960
            +vt 0.482012 0.386960
            +vt 0.517988 0.386960
            +vt 0.552933 0.386960
            +vt 0.587046 0.386960
            +vt 0.620791 0.386960
            +vt 0.654497 0.386960
            +vt 0.688482 0.386960
            +vt 0.723165 0.386960
            +vt 0.759048 0.386960
            +vt 0.794297 0.386960
            +vt 0.828568 0.386960
            +vt 0.862370 0.386960
            +vt 0.896058 0.386960
            +vt 0.929940 0.386960
            +vt 0.964399 0.386960
            +vt 1.000000 1.000000
            +vt 0.000000 1.000000
            +vt 0.035601 1.000000
            +vt 0.070060 1.000000
            +vt 0.103942 1.000000
            +vt 0.137630 1.000000
            +vt 0.171432 1.000000
            +vt 0.205703 1.000000
            +vt 0.240953 1.000000
            +vt 0.276835 1.000000
            +vt 0.311518 1.000000
            +vt 0.345503 1.000000
            +vt 0.379209 1.000000
            +vt 0.412954 1.000000
            +vt 0.447067 1.000000
            +vt 0.482012 1.000000
            +vt 0.517988 1.000000
            +vt 0.552933 1.000000
            +vt 0.587046 1.000000
            +vt 0.620791 1.000000
            +vt 0.654497 1.000000
            +vt 0.688482 1.000000
            +vt 0.723165 1.000000
            +vt 0.759048 1.000000
            +vt 0.794297 1.000000
            +vt 0.828568 1.000000
            +vt 0.862370 1.000000
            +vt 0.896058 1.000000
            +vt 0.929940 1.000000
            +vt 0.964399 1.000000
            +vt 0.998446 0.500000
            +vt 0.986126 0.611168
            +vt 0.950953 0.713558
            +vt 0.895608 0.804488
            +vt 0.822771 0.881279
            +vt 0.735125 0.941248
            +vt 0.635348 0.981715
            +vt 0.526124 1.000000
            +vt 0.413561 0.993798
            +vt 0.308725 0.964087
            +vt 0.214678 0.913534
            +vt 0.134102 0.844819
            +vt 0.069676 0.760623
            +vt 0.024082 0.663628
            +vt 0.000000 0.556514
            +vt 0.000000 0.443486
            +vt 0.024082 0.336372
            +vt 0.069676 0.239377
            +vt 0.134102 0.155181
            +vt 0.214678 0.086467
            +vt 0.308725 0.035913
            +vt 0.413561 0.006202
            +vt 0.526124 0.000000
            +vt 0.635348 0.018285
            +vt 0.735125 0.058752
            +vt 0.822771 0.118721
            +vt 0.895608 0.195512
            +vt 0.950953 0.286442
            +vt 0.986126 0.388832
            +vt 0.998446 0.500000
            +vt 0.986126 0.611168
            +vt 0.950953 0.713558
            +vt 0.895608 0.804488
            +vt 0.822771 0.881279
            +vt 0.735125 0.941248
            +vt 0.635348 0.981715
            +vt 0.526124 1.000000
            +vt 0.413561 0.993798
            +vt 0.308725 0.964087
            +vt 0.214678 0.913534
            +vt 0.134102 0.844819
            +vt 0.069676 0.760623
            +vt 0.024082 0.663628
            +vt 0.000000 0.556514
            +vt 0.000000 0.443486
            +vt 0.024082 0.336372
            +vt 0.069676 0.239377
            +vt 0.134102 0.155181
            +vt 0.214678 0.086467
            +vt 0.308725 0.035913
            +vt 0.413561 0.006202
            +vt 0.526124 0.000000
            +vt 0.635348 0.018285
            +vt 0.735125 0.058752
            +vt 0.822771 0.118721
            +vt 0.895608 0.195512
            +vt 0.950953 0.286442
            +vt 0.986126 0.388832
            +vt 0.000000 1.000000
            +vt 1.000000 0.000000
            +vt 0.000000 0.000000
            +vt 0.000000 0.000000
            +vt 1.000000 1.000000
            +vt 0.000000 1.000000
            +vt 0.100000 0.000000
            +vt 0.100000 1.000000
            +vt 0.100000 0.000000
            +vt 0.200000 0.000000
            +vt 0.200000 1.000000
            +vt 0.200000 0.000000
            +vt 0.300000 0.000000
            +vt 0.300000 1.000000
            +vt 0.300000 0.000000
            +vt 0.400000 0.000000
            +vt 0.400000 1.000000
            +vt 0.400000 0.000000
            +vt 0.500000 0.000000
            +vt 0.500000 1.000000
            +vt 0.500000 0.000000
            +vt 1.000000 0.000000
            +vt 1.000000 1.000000
            +vt 1.000000 1.000000
            +vt 0.000000 0.000000
            +vt 0.000000 1.000000
            +vt 1.000000 0.000000
            +vt 1.000000 0.000000
            +vt 0.000000 0.000000
            +vt 0.000000 1.000000
            +vt 0.500000 0.000000
            +vt 0.400000 0.000000
            +vt 0.600000 0.000000
            +vt 0.600000 1.000000
            +vt 0.300000 0.000000
            +vt 0.700000 0.000000
            +vt 0.700000 1.000000
            +vt 0.200000 0.000000
            +vt 0.800000 0.000000
            +vt 0.800000 1.000000
            +vt 0.100000 0.000000
            +vt 0.900000 0.000000
            +vt 0.900000 1.000000
            +vt 1.000000 0.000000
            +vt 1.000000 1.000000
            +vt 0.000000 0.000000
            +vt 0.000000 0.000000
            +vt 0.000000 1.000000
            +vt 0.000000 1.000000
            +vt 0.100000 1.000000
            +vt 0.200000 1.000000
            +vt 0.300000 1.000000
            +vt 0.400000 1.000000
            +vt 0.500000 1.000000
            +vt 1.000000 1.000000
            +vt 0.100000 1.000000
            +vt 0.200000 1.000000
            +vt 0.300000 1.000000
            +vt 0.400000 1.000000
            +vt 0.500000 1.000000
            +vt 0.958333 1.000000
            +vt 0.916667 1.000000
            +vt 0.875000 1.000000
            +vt 0.833333 1.000000
            +vt 0.791667 1.000000
            +vt 0.750000 1.000000
            +vt 0.708333 1.000000
            +vt 0.666667 1.000000
            +vt 0.625000 1.000000
            +vt 0.583333 1.000000
            +vt 0.541667 1.000000
            +vt 0.500000 1.000000
            +vt 0.458333 1.000000
            +vt 0.416667 1.000000
            +vt 0.375000 1.000000
            +vt 0.333333 1.000000
            +vt 0.291667 1.000000
            +vt 0.250000 1.000000
            +vt 0.208333 1.000000
            +vt 0.166667 1.000000
            +vt 0.125000 1.000000
            +vt 0.083333 1.000000
            +vt 0.041667 1.000000
            +vt 0.000000 1.000000
            +vt 1.000000 0.500000
            +vt 0.000000 0.500000
            +vt 0.041667 0.500000
            +vt 0.083333 0.500000
            +vt 0.125000 0.500000
            +vt 0.166667 0.500000
            +vt 0.208333 0.500000
            +vt 0.250000 0.500000
            +vt 0.291667 0.500000
            +vt 0.333333 0.500000
            +vt 0.375000 0.500000
            +vt 0.416667 0.500000
            +vt 0.458333 0.500000
            +vt 0.500000 0.500000
            +vt 0.541667 0.500000
            +vt 0.583333 0.500000
            +vt 0.625000 0.500000
            +vt 0.666667 0.500000
            +vt 0.708333 0.500000
            +vt 0.750000 0.500000
            +vt 0.791667 0.500000
            +vt 0.833333 0.500000
            +vt 0.875000 0.500000
            +vt 0.916667 0.500000
            +vt 0.958333 0.500000
            +vt 0.041667 0.583333
            +vt 0.083333 0.583333
            +vt 0.125000 0.583333
            +vt 0.166667 0.583333
            +vt 0.208333 0.583333
            +vt 0.250000 0.583333
            +vt 0.291667 0.583333
            +vt 0.333333 0.583333
            +vt 0.375000 0.583333
            +vt 0.416667 0.583333
            +vt 0.458333 0.583333
            +vt 0.500000 0.583333
            +vt 0.541667 0.583333
            +vt 0.583333 0.583333
            +vt 0.625000 0.583333
            +vt 0.666667 0.583333
            +vt 0.708333 0.583333
            +vt 0.750000 0.583333
            +vt 0.791667 0.583333
            +vt 0.833333 0.583333
            +vt 0.875000 0.583333
            +vt 0.916667 0.583333
            +vt 0.958333 0.583333
            +vt 1.000000 0.583333
            +vt 0.000000 0.583333
            +vt 0.041667 0.750000
            +vt 0.083333 0.750000
            +vt 0.125000 0.750000
            +vt 0.166667 0.750000
            +vt 0.208333 0.750000
            +vt 0.250000 0.750000
            +vt 0.291667 0.750000
            +vt 0.333333 0.750000
            +vt 0.375000 0.750000
            +vt 0.416667 0.750000
            +vt 0.458333 0.750000
            +vt 0.500000 0.750000
            +vt 0.541667 0.750000
            +vt 0.583333 0.750000
            +vt 0.625000 0.750000
            +vt 0.666667 0.750000
            +vt 0.708333 0.750000
            +vt 0.750000 0.750000
            +vt 0.791667 0.750000
            +vt 0.833333 0.750000
            +vt 0.875000 0.750000
            +vt 0.916667 0.750000
            +vt 0.958333 0.750000
            +vt 1.000000 0.750000
            +vt 0.000000 0.750000
            +vt 0.000000 0.000000
            +vt 0.039341 0.000000
            +vt 0.074071 0.000000
            +vt 0.114555 0.000000
            +vt 0.182236 0.000000
            +vt 0.232619 0.000000
            +vt 0.327936 0.000000
            +vt 0.411683 0.000000
            +vt 0.521108 0.000000
            +vt 0.559887 0.000000
            +vt 0.624933 0.000000
            +vt 0.673665 0.000000
            +vt 0.727131 0.000000
            +vt 0.853330 0.000000
            +vt 0.899923 0.000000
            +vt 0.935365 0.000000
            +vt 0.989674 0.000000
            +vt 1.000000 0.000000
            +vt 0.000000 1.000000
            +vt 0.037296 1.000000
            +vt 0.071155 1.000000
            +vt 0.112005 1.000000
            +vt 0.180141 1.000000
            +vt 0.230821 1.000000
            +vt 0.326658 1.000000
            +vt 0.410629 1.000000
            +vt 0.521156 1.000000
            +vt 0.562831 1.000000
            +vt 0.630790 1.000000
            +vt 0.674365 1.000000
            +vt 0.726689 1.000000
            +vt 0.854123 1.000000
            +vt 0.900957 1.000000
            +vt 0.936514 1.000000
            +vt 0.989659 1.000000
            +vt 1.000000 1.000000
            +vt 0.115120 0.047990
            +vt 0.138580 0.026760
            +vt 0.171745 0.008598
            +vt 0.191081 0.002698
            +vt 0.211779 0.000000
            +vt 0.233485 0.001309
            +vt 0.255793 0.006928
            +vt 0.278219 0.016387
            +vt 0.300271 0.029151
            +vt 0.321458 0.044683
            +vt 0.341290 0.062447
            +vt 0.359275 0.081906
            +vt 0.374922 0.102525
            +vt 0.387770 0.123805
            +vt 0.397711 0.145707
            +vt 0.404859 0.168484
            +vt 0.409335 0.192393
            +vt 0.411260 0.217694
            +vt 0.410754 0.244645
            +vt 0.402929 0.304528
            +vt 0.376715 0.408696
            +vt 0.352711 0.480406
            +vt 0.326163 0.547028
            +vt 0.312649 0.576589
            +vt 0.285861 0.626705
            +vt 0.259064 0.666747
            +vt 0.231809 0.699204
            +vt 0.158952 0.766450
            +vt 0.127185 0.799940
            +vt 0.093584 0.845233
            +vt 0.076150 0.873479
            +vt 0.015691 0.981863
            +vt 0.000000 0.996007
            +vt 0.004068 0.970879
            +vt 0.022793 0.902560
            +vt 0.051071 0.819195
            +vt 0.066824 0.779502
            +vt 0.082604 0.745205
            +vt 0.097673 0.719113
            +vt 0.111861 0.701201
            +vt 0.138392 0.682473
            +vt 0.176625 0.668870
            +vt 0.203380 0.647909
            +vt 0.231454 0.610081
            +vt 0.259383 0.560183
            +vt 0.285635 0.503434
            +vt 0.308680 0.444825
            +vt 0.333891 0.358039
            +vt 0.342235 0.301868
            +vt 0.343294 0.274522
            +vt 0.342049 0.247783
            +vt 0.338613 0.221868
            +vt 0.326345 0.173714
            +vt 0.308864 0.132475
            +vt 0.288549 0.100562
            +vt 0.267434 0.079635
            +vt 0.246186 0.068322
            +vt 0.204589 0.066033
            +vt 0.147622 0.082399
            +vt 0.115001 0.083922
            +vt 0.104069 0.065946
            +vt 0.122556 0.046213
            +vt 0.144208 0.025450
            +vt 0.174718 0.007966
            +vt 0.192720 0.002404
            +vt 0.212246 0.000000
            +vt 0.233065 0.001528
            +vt 0.254824 0.007277
            +vt 0.276989 0.016791
            +vt 0.299007 0.029550
            +vt 0.320326 0.045033
            +vt 0.340395 0.062721
            +vt 0.358662 0.082092
            +vt 0.374574 0.102627
            +vt 0.387614 0.123842
            +vt 0.397659 0.145701
            +vt 0.404843 0.168452
            +vt 0.409303 0.192348
            +vt 0.411175 0.217644
            +vt 0.410597 0.244593
            +vt 0.407706 0.273449
            +vt 0.395556 0.337730
            +vt 0.376394 0.408557
            +vt 0.339364 0.514495
            +vt 0.298983 0.602810
            +vt 0.272202 0.647592
            +vt 0.245228 0.683518
            +vt 0.217682 0.713028
            +vt 0.159285 0.765741
            +vt 0.127548 0.799202
            +vt 0.093516 0.844779
            +vt 0.075645 0.873319
            +vt 0.013829 0.982597
            +vt 0.000000 0.995444
            +vt 0.006458 0.968673
            +vt 0.029786 0.897198
            +vt 0.062348 0.810905
            +vt 0.079583 0.770204
            +vt 0.096116 0.735401
            +vt 0.111015 0.709439
            +vt 0.124162 0.692255
            +vt 0.146859 0.676190
            +vt 0.178214 0.667353
            +vt 0.202108 0.648378
            +vt 0.229421 0.611091
            +vt 0.271816 0.532665
            +vt 0.297559 0.473849
            +vt 0.318788 0.415180
            +vt 0.334093 0.357638
            +vt 0.342169 0.301687
            +vt 0.343088 0.274454
            +vt 0.341732 0.247804
            +vt 0.338223 0.221950
            +vt 0.325912 0.173851
            +vt 0.308502 0.132601
            +vt 0.288341 0.100646
            +vt 0.267422 0.079674
            +vt 0.246313 0.068338
            +vt 0.204361 0.066164
            +vt 0.146727 0.082696
            +vt 0.118018 0.083234
            +vt 0.111514 0.064155
            +vt 1.000000 0.000000
            +vt 0.000000 0.000000
            +vt 0.035601 0.000000
            +vt 0.070060 0.000000
            +vt 0.103942 0.000000
            +vt 0.137630 0.000000
            +vt 0.171432 0.000000
            +vt 0.205703 0.000000
            +vt 0.240953 0.000000
            +vt 0.276835 0.000000
            +vt 0.311518 0.000000
            +vt 0.345503 0.000000
            +vt 0.379209 0.000000
            +vt 0.412954 0.000000
            +vt 0.447067 0.000000
            +vt 0.482012 0.000000
            +vt 0.517988 0.000000
            +vt 0.552933 0.000000
            +vt 0.587046 0.000000
            +vt 0.620791 0.000000
            +vt 0.654497 0.000000
            +vt 0.688482 0.000000
            +vt 0.723165 0.000000
            +vt 0.759048 0.000000
            +vt 0.794297 0.000000
            +vt 0.828568 0.000000
            +vt 0.862370 0.000000
            +vt 0.896058 0.000000
            +vt 0.929940 0.000000
            +vt 0.964399 0.000000
            +vt 1.000000 0.137727
            +vt 0.000000 0.137727
            +vt 0.035601 0.137727
            +vt 0.070060 0.137727
            +vt 0.103942 0.137727
            +vt 0.137630 0.137727
            +vt 0.171432 0.137727
            +vt 0.205703 0.137727
            +vt 0.240953 0.137727
            +vt 0.276835 0.137727
            +vt 0.311518 0.137727
            +vt 0.345503 0.137727
            +vt 0.379209 0.137727
            +vt 0.412954 0.137727
            +vt 0.447067 0.137727
            +vt 0.482012 0.137727
            +vt 0.517988 0.137727
            +vt 0.552933 0.137727
            +vt 0.587046 0.137727
            +vt 0.620791 0.137727
            +vt 0.654497 0.137727
            +vt 0.688482 0.137727
            +vt 0.723165 0.137727
            +vt 0.759048 0.137727
            +vt 0.794297 0.137727
            +vt 0.828568 0.137727
            +vt 0.862370 0.137727
            +vt 0.896058 0.137727
            +vt 0.929940 0.137727
            +vt 0.964399 0.137727
            +vt 1.000000 0.244060
            +vt 0.000000 0.244060
            +vt 0.035601 0.244060
            +vt 0.070060 0.244060
            +vt 0.103942 0.244060
            +vt 0.137630 0.244060
            +vt 0.171432 0.244060
            +vt 0.205703 0.244060
            +vt 0.240953 0.244060
            +vt 0.276835 0.244060
            +vt 0.311518 0.244060
            +vt 0.345503 0.244060
            +vt 0.379209 0.244060
            +vt 0.412954 0.244060
            +vt 0.447067 0.244060
            +vt 0.482012 0.244060
            +vt 0.517988 0.244060
            +vt 0.552933 0.244060
            +vt 0.587046 0.244060
            +vt 0.620791 0.244060
            +vt 0.654497 0.244060
            +vt 0.688482 0.244060
            +vt 0.723165 0.244060
            +vt 0.759048 0.244060
            +vt 0.794297 0.244060
            +vt 0.828568 0.244060
            +vt 0.862370 0.244060
            +vt 0.896058 0.244060
            +vt 0.929940 0.244060
            +vt 0.964399 0.244060
            +vt 1.000000 0.338912
            +vt 0.000000 0.338912
            +vt 0.035601 0.338912
            +vt 0.070060 0.338912
            +vt 0.103942 0.338912
            +vt 0.137630 0.338912
            +vt 0.171432 0.338912
            +vt 0.205703 0.338912
            +vt 0.240953 0.338912
            +vt 0.276835 0.338912
            +vt 0.311518 0.338912
            +vt 0.345503 0.338912
            +vt 0.379209 0.338912
            +vt 0.412954 0.338912
            +vt 0.447067 0.338912
            +vt 0.482012 0.338912
            +vt 0.517988 0.338912
            +vt 0.552933 0.338912
            +vt 0.587046 0.338912
            +vt 0.620791 0.338912
            +vt 0.654497 0.338912
            +vt 0.688482 0.338912
            +vt 0.723165 0.338912
            +vt 0.759048 0.338912
            +vt 0.794297 0.338912
            +vt 0.828568 0.338912
            +vt 0.862370 0.338912
            +vt 0.896058 0.338912
            +vt 0.929940 0.338912
            +vt 0.964399 0.338912
            +vt 1.000000 0.471097
            +vt 0.000000 0.471097
            +vt 0.035601 0.471097
            +vt 0.070060 0.471097
            +vt 0.103942 0.471097
            +vt 0.137630 0.471097
            +vt 0.171432 0.471097
            +vt 0.205703 0.471097
            +vt 0.240953 0.471097
            +vt 0.276835 0.471097
            +vt 0.311518 0.471097
            +vt 0.345503 0.471097
            +vt 0.379209 0.471097
            +vt 0.412954 0.471097
            +vt 0.447067 0.471097
            +vt 0.482012 0.471097
            +vt 0.517988 0.471097
            +vt 0.552933 0.471097
            +vt 0.587046 0.471097
            +vt 0.620791 0.471097
            +vt 0.654497 0.471097
            +vt 0.688482 0.471097
            +vt 0.723165 0.471097
            +vt 0.759048 0.471097
            +vt 0.794297 0.471097
            +vt 0.828568 0.471097
            +vt 0.862370 0.471097
            +vt 0.896058 0.471097
            +vt 0.929940 0.471097
            +vt 0.964399 0.471097
            +vt 1.000000 0.478701
            +vt 0.000000 0.478701
            +vt 0.035601 0.478701
            +vt 0.070060 0.478701
            +vt 0.103942 0.478701
            +vt 0.137630 0.478701
            +vt 0.171432 0.478701
            +vt 0.205703 0.478701
            +vt 0.240953 0.478701
            +vt 0.276835 0.478701
            +vt 0.311518 0.478701
            +vt 0.345503 0.478701
            +vt 0.379209 0.478701
            +vt 0.412954 0.478701
            +vt 0.447067 0.478701
            +vt 0.482012 0.478701
            +vt 0.517988 0.478701
            +vt 0.552933 0.478701
            +vt 0.587046 0.478701
            +vt 0.620791 0.478701
            +vt 0.654497 0.478701
            +vt 0.688482 0.478701
            +vt 0.723165 0.478701
            +vt 0.759048 0.478701
            +vt 0.794297 0.478701
            +vt 0.828568 0.478701
            +vt 0.862370 0.478701
            +vt 0.896058 0.478701
            +vt 0.929940 0.478701
            +vt 0.964399 0.478701
            +vt 1.000000 0.728844
            +vt 0.000000 0.728844
            +vt 0.035601 0.728844
            +vt 0.070060 0.728844
            +vt 0.103942 0.728844
            +vt 0.137630 0.728844
            +vt 0.171432 0.728844
            +vt 0.205703 0.728844
            +vt 0.240953 0.728844
            +vt 0.276835 0.728844
            +vt 0.311518 0.728844
            +vt 0.345503 0.728844
            +vt 0.379209 0.728844
            +vt 0.412954 0.728844
            +vt 0.447067 0.728844
            +vt 0.482012 0.728844
            +vt 0.517988 0.728844
            +vt 0.552933 0.728844
            +vt 0.587046 0.728844
            +vt 0.620791 0.728844
            +vt 0.654497 0.728844
            +vt 0.688482 0.728844
            +vt 0.723165 0.728844
            +vt 0.759048 0.728844
            +vt 0.794297 0.728844
            +vt 0.828568 0.728844
            +vt 0.862370 0.728844
            +vt 0.896058 0.728844
            +vt 0.929940 0.728844
            +vt 0.964399 0.728844
            +vt 1.000000 1.000000
            +vt 0.000000 1.000000
            +vt 0.035601 1.000000
            +vt 0.070060 1.000000
            +vt 0.103942 1.000000
            +vt 0.137630 1.000000
            +vt 0.171432 1.000000
            +vt 0.205703 1.000000
            +vt 0.240953 1.000000
            +vt 0.276835 1.000000
            +vt 0.311518 1.000000
            +vt 0.345503 1.000000
            +vt 0.379209 1.000000
            +vt 0.412954 1.000000
            +vt 0.447067 1.000000
            +vt 0.482012 1.000000
            +vt 0.517988 1.000000
            +vt 0.552933 1.000000
            +vt 0.587046 1.000000
            +vt 0.620791 1.000000
            +vt 0.654497 1.000000
            +vt 0.688482 1.000000
            +vt 0.723165 1.000000
            +vt 0.759048 1.000000
            +vt 0.794297 1.000000
            +vt 0.828568 1.000000
            +vt 0.862370 1.000000
            +vt 0.896058 1.000000
            +vt 0.929940 1.000000
            +vt 0.964399 1.000000
            +vt 0.998446 0.500000
            +vt 0.986126 0.611168
            +vt 0.950953 0.713558
            +vt 0.895608 0.804488
            +vt 0.822771 0.881279
            +vt 0.735125 0.941248
            +vt 0.635348 0.981715
            +vt 0.526124 1.000000
            +vt 0.413561 0.993798
            +vt 0.308725 0.964087
            +vt 0.214678 0.913534
            +vt 0.134102 0.844819
            +vt 0.069676 0.760623
            +vt 0.024082 0.663628
            +vt 0.000000 0.556514
            +vt 0.000000 0.443486
            +vt 0.024082 0.336372
            +vt 0.069676 0.239377
            +vt 0.134102 0.155181
            +vt 0.214678 0.086467
            +vt 0.308725 0.035913
            +vt 0.413561 0.006202
            +vt 0.526124 0.000000
            +vt 0.635348 0.018285
            +vt 0.735125 0.058752
            +vt 0.822771 0.118721
            +vt 0.895608 0.195512
            +vt 0.950953 0.286442
            +vt 0.986126 0.388832
            +vt 0.998446 0.500000
            +vt 0.986126 0.611168
            +vt 0.950953 0.713558
            +vt 0.895608 0.804488
            +vt 0.822771 0.881279
            +vt 0.735125 0.941248
            +vt 0.635348 0.981715
            +vt 0.526124 1.000000
            +vt 0.413561 0.993798
            +vt 0.308725 0.964087
            +vt 0.214678 0.913534
            +vt 0.134102 0.844819
            +vt 0.069676 0.760623
            +vt 0.024082 0.663628
            +vt 0.000000 0.556514
            +vt 0.000000 0.443486
            +vt 0.024082 0.336372
            +vt 0.069676 0.239377
            +vt 0.134102 0.155181
            +vt 0.214678 0.086467
            +vt 0.308725 0.035913
            +vt 0.413561 0.006202
            +vt 0.526124 0.000000
            +vt 0.635348 0.018285
            +vt 0.735125 0.058752
            +vt 0.822771 0.118721
            +vt 0.895608 0.195512
            +vt 0.950953 0.286442
            +vt 0.986126 0.388832
            +vn 0.002161 0.999996 -0.001769
            +vn 0.001557 0.999998 -0.001058
            +vn 0.004144 0.999704 0.023960
            +vn 0.003041 0.999883 0.014974
            +vn 0.000544 1.000000 0.000423
            +vn -0.002102 0.999858 -0.016718
            +vn -0.004663 0.999644 -0.026267
            +vn -0.006139 0.999976 0.003114
            +vn -0.001942 0.999998 -0.000426
            +vn 0.008445 0.999953 0.004825
            +vn 0.016555 0.999785 0.012490
            +vn 0.010619 0.999927 0.005823
            +vn 0.006717 0.999972 0.003432
            +vn -0.028270 0.999535 -0.011434
            +vn -0.032372 0.999317 -0.017818
            +vn 0.010198 0.999945 0.002338
            +vn 0.013893 0.999903 -0.000306
            +vn 0.019625 0.999789 0.006032
            +vn 0.028379 0.999580 0.005930
            +vn -0.004678 0.999943 -0.009572
            +vn -0.004035 0.999963 -0.007565
            +vn 0.001014 0.999999 0.000820
            +vn -0.009058 0.999958 0.001163
            +vn -0.022814 0.999606 0.016332
            +vn -0.027274 0.999541 0.013178
            +vn -0.017618 0.999750 0.013742
            +vn -0.019046 0.999775 0.009292
            +vn -0.003334 0.999989 0.003431
            +vn -0.005812 0.999983 -0.000057
            +vn 0.002464 0.999994 -0.002234
            +vn -0.001042 0.999988 -0.004700
            +vn 0.011885 0.999821 -0.014718
            +vn 0.007210 0.999848 -0.015868
            +vn 0.017172 0.999577 -0.023457
            +vn 0.013021 0.999564 -0.026519
            +vn 0.004224 0.999991 -0.000977
            +vn 0.003411 0.999932 -0.011110
            +vn -0.009515 0.999933 -0.006626
            +vn -0.007758 0.999922 -0.009762
            +vn 0.001882 0.999907 0.013524
            +vn 0.002864 0.999785 0.020526
            +vn 0.004525 0.999890 0.014104
            +vn 0.004000 0.999752 0.021923
            +vn -0.000369 0.999924 -0.012339
            +vn -0.007591 0.999855 -0.015225
            +vn -0.013299 0.999888 -0.006844
            +vn -0.017346 0.999771 -0.012562
            +vn 0.006672 0.999973 0.003113
            +vn 0.012527 0.999880 0.009099
            +vn 0.021828 0.999699 0.011201
            +vn 0.022392 0.999618 0.016176
            +vn -0.025917 0.999622 -0.009133
            +vn -0.032488 0.999437 -0.008336
            +vn -0.008661 0.999962 -0.001181
            +vn -0.014487 0.999893 -0.002240
            +vn 0.017070 0.999832 0.006611
            +vn 0.022355 0.999733 0.005866
            +vn 0.003646 0.999979 -0.005348
            +vn 0.014016 0.999896 -0.003348
            +vn 0.013939 0.999776 -0.015904
            +vn 0.015459 0.999830 -0.010083
            +vn 0.009206 0.999933 -0.007005
            +vn 0.007435 0.999972 -0.001173
            +vn -0.002827 0.999985 0.004645
            +vn -0.001732 0.999969 0.007665
            +vn 0.002577 0.999996 -0.000679
            +vn 0.005019 0.999987 0.000949
            +vn 0.002339 0.999996 -0.001748
            +vn 0.006376 0.999978 -0.001999
            +vn -0.011142 0.999779 0.017808
            +vn -0.005046 0.999868 0.015469
            +vn -0.011958 0.999886 0.009197
            +vn -0.007323 0.999857 0.015250
            +vn 0.218162 -0.975496 0.028520
            +vn 0.221573 -0.974946 -0.019626
            +vn 0.128850 -0.991607 -0.010629
            +vn 0.126015 -0.991876 0.017371
            +vn 0.214157 -0.974437 -0.067897
            +vn 0.125339 -0.991346 -0.039022
            +vn 0.196466 -0.974000 -0.112805
            +vn 0.115524 -0.991130 -0.065690
            +vn 0.169425 -0.973668 -0.152532
            +vn 0.099922 -0.990967 -0.089441
            +vn 0.133821 -0.973475 -0.185576
            +vn 0.078932 -0.990892 -0.109105
            +vn 0.090758 -0.973410 -0.210323
            +vn 0.053412 -0.990880 -0.123707
            +vn 0.042974 -0.973486 -0.224675
            +vn 0.025034 -0.990924 -0.132071
            +vn -0.006352 -0.973741 -0.227571
            +vn -0.004236 -0.991054 -0.133392
            +vn -0.055325 -0.974130 -0.219114
            +vn -0.033001 -0.991220 -0.128042
            +vn -0.099960 -0.974591 -0.200450
            +vn -0.059009 -0.991419 -0.116644
            +vn -0.138500 -0.975117 -0.173101
            +vn -0.081164 -0.991659 -0.100122
            +vn -0.169972 -0.975699 -0.138280
            +vn -0.098878 -0.991932 -0.079329
            +vn -0.193333 -0.976301 -0.097256
            +vn -0.111605 -0.992219 -0.055188
            +vn -0.207391 -0.976869 -0.052110
            +vn -0.118875 -0.992485 -0.029018
            +vn -0.211317 -0.977399 -0.005988
            +vn -0.120263 -0.992739 -0.002584
            +vn -0.205276 -0.977889 0.039943
            +vn -0.116304 -0.992939 0.023340
            +vn -0.190099 -0.978285 0.082589
            +vn -0.107407 -0.993092 0.047239
            +vn -0.167124 -0.978577 0.120238
            +vn -0.094244 -0.993206 0.068265
            +vn -0.137283 -0.978771 0.152190
            +vn -0.077277 -0.993294 0.085994
            +vn -0.101176 -0.978857 0.177772
            +vn -0.056929 -0.993347 0.100108
            +vn -0.059823 -0.978829 0.195742
            +vn -0.033793 -0.993353 0.110039
            +vn -0.015998 -0.978701 0.204667
            +vn -0.009267 -0.993294 0.115243
            +vn 0.029242 -0.978485 0.204238
            +vn 0.016116 -0.993192 0.115369
            +vn 0.073380 -0.978161 0.194464
            +vn 0.041067 -0.993036 0.110418
            +vn 0.114099 -0.977753 0.176015
            +vn 0.064363 -0.992850 0.100533
            +vn 0.150285 -0.977272 0.149510
            +vn 0.085305 -0.992640 0.085964
            +vn 0.180849 -0.976724 0.115340
            +vn 0.103152 -0.992418 0.066831
            +vn 0.204218 -0.976112 0.074159
            +vn 0.117067 -0.992170 0.043527
            +vn -0.687881 0.723444 0.058720
            +vn -0.691415 0.716432 -0.093116
            +vn -0.652125 0.729962 0.204668
            +vn -0.588983 0.734830 0.336339
            +vn -0.502071 0.738255 0.450449
            +vn -0.393716 0.740388 0.544806
            +vn -0.266440 0.740818 0.616602
            +vn -0.125829 0.739719 0.661047
            +vn 0.020617 0.737519 0.675012
            +vn 0.168375 0.733506 0.658497
            +vn 0.307863 0.728152 0.612384
            +vn 0.434488 0.721619 0.538968
            +vn 0.544551 0.714345 0.439518
            +vn 0.633601 0.706225 0.315904
            +vn 0.695590 0.697512 0.172138
            +vn 0.723681 0.689912 0.017522
            +vn 0.717145 0.682251 -0.142256
            +vn 0.675581 0.675454 -0.295554
            +vn 0.601863 0.669981 -0.434610
            +vn 0.498933 0.666185 -0.554314
            +vn 0.369632 0.664490 -0.649481
            +vn 0.219017 0.664891 -0.714109
            +vn 0.058950 0.666990 -0.742731
            +vn -0.103742 0.671328 -0.733864
            +vn -0.257893 0.677323 -0.689003
            +vn -0.394612 0.684364 -0.613129
            +vn -0.509742 0.692182 -0.510928
            +vn -0.600041 0.700538 -0.386262
            +vn -0.661701 0.709034 -0.243767
            +vn -0.421780 0.905980 0.036095
            +vn -0.419144 0.906183 -0.056141
            +vn -0.404167 0.905825 0.127002
            +vn -0.368111 0.905663 0.210400
            +vn -0.315744 0.905520 0.283442
            +vn -0.248530 0.905445 0.344095
            +vn -0.168289 0.905389 0.389806
            +vn -0.079402 0.905376 0.417121
            +vn 0.012650 0.905494 0.424170
            +vn 0.104718 0.905701 0.410780
            +vn 0.189980 0.905905 0.378477
            +vn 0.265328 0.906089 0.329551
            +vn 0.328670 0.906328 0.265603
            +vn 0.377634 0.906569 0.188483
            +vn 0.409246 0.906766 0.101458
            +vn 0.420984 0.907006 0.010613
            +vn 0.412497 0.907312 -0.081436
            +vn 0.384838 0.907547 -0.168102
            +vn 0.340305 0.907684 -0.245564
            +vn 0.280692 0.907763 -0.311735
            +vn 0.207390 0.907803 -0.364530
            +vn 0.122817 0.907751 -0.401129
            +vn 0.033183 0.907663 -0.418387
            +vn -0.058786 0.907610 -0.415679
            +vn -0.147412 0.907482 -0.393378
            +vn -0.227812 0.907271 -0.353499
            +vn -0.297615 0.907028 -0.297869
            +vn -0.354685 0.906793 -0.227870
            +vn -0.396329 0.906506 -0.145500
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000001
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000001
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn -0.081308 -0.707876 0.701642
            +vn -0.002140 0.701878 0.712294
            +vn -0.263716 0.701794 0.661769
            +vn -0.340889 -0.677585 0.651670
            +vn -0.113935 -0.706907 0.698070
            +vn -0.034581 0.704604 0.708758
            +vn -0.167086 -0.703530 0.690744
            +vn -0.087757 0.707360 0.701384
            +vn -0.180777 -0.702390 0.688453
            +vn -0.101491 0.707841 0.699043
            +vn -0.140142 -0.705665 0.694549
            +vn -0.060787 0.706304 0.705294
            +vn -0.087112 -0.708030 0.700789
            +vn -0.007872 0.702743 0.711401
            +vn 0.101068 -0.707826 -0.699119
            +vn 0.180375 0.702204 -0.688749
            +vn 0.048249 -0.705777 -0.706789
            +vn 0.127658 0.706137 -0.696472
            +vn 0.007535 -0.702375 -0.711767
            +vn 0.086798 0.707861 -0.700998
            +vn 0.021257 -0.703454 -0.710423
            +vn 0.100565 0.707398 -0.699625
            +vn 0.074475 -0.706890 -0.703392
            +vn 0.153738 0.704525 -0.692827
            +vn 0.106880 -0.707835 -0.698245
            +vn 0.186045 0.701974 -0.687474
            +vn -0.156699 -0.677540 -0.718599
            +vn -0.079587 0.701970 -0.707746
            +vn 0.786684 -0.416840 0.455382
            +vn 0.527812 -0.787717 0.317673
            +vn 0.592662 -0.801507 0.079609
            +vn 0.892741 -0.434313 0.119943
            +vn 0.602512 -0.377623 0.703122
            +vn 0.415184 -0.752329 0.511491
            +vn 0.398377 -0.334315 0.854125
            +vn 0.279754 -0.708254 0.648162
            +vn 0.204136 -0.298743 0.932245
            +vn 0.137932 -0.667809 0.731441
            +vn 0.025202 -0.274220 0.961337
            +vn -0.002375 -0.638383 0.769715
            +vn -0.143231 -0.259551 0.955049
            +vn -0.139097 -0.622973 0.769777
            +vn -0.308043 -0.254925 0.916582
            +vn -0.271871 -0.622792 0.733632
            +vn -0.474620 -0.260490 0.840762
            +vn -0.399724 -0.636981 0.659148
            +vn -0.643922 -0.274895 0.714001
            +vn -0.517932 -0.662576 0.541055
            +vn -0.804702 -0.296373 0.514410
            +vn -0.616877 -0.693123 0.372885
            +vn -0.920545 -0.318667 0.225941
            +vn -0.677630 -0.718692 0.155884
            +vn -0.935915 -0.329004 -0.125773
            +vn -0.678754 -0.728686 -0.091157
            +vn -0.827822 -0.320095 -0.460705
            +vn -0.612286 -0.718745 -0.329410
            +vn -0.639980 -0.298252 -0.708147
            +vn -0.496224 -0.693356 -0.522512
            +vn -0.432544 -0.275505 -0.858488
            +vn -0.356734 -0.662695 -0.658465
            +vn -0.235595 -0.260111 -0.936396
            +vn -0.211396 -0.637064 -0.741257
            +vn -0.055076 -0.254344 -0.965544
            +vn -0.068512 -0.622812 -0.779366
            +vn 0.114121 -0.258903 -0.959138
            +vn 0.069157 -0.622978 -0.779176
            +vn 0.278278 -0.273803 -0.920648
            +vn 0.200952 -0.638314 -0.743084
            +vn 0.443134 -0.298816 -0.845187
            +vn 0.326282 -0.667779 -0.669038
            +vn 0.609883 -0.334521 -0.718428
            +vn 0.441051 -0.708290 -0.551180
            +vn 0.766525 -0.378122 -0.519099
            +vn 0.535515 -0.752377 -0.383605
            +vn 0.878454 -0.418110 -0.231307
            +vn 0.592780 -0.787820 -0.167185
            +vn 0.241962 -0.955581 0.168284
            +vn 0.274969 -0.960743 0.036946
            +vn 0.186384 -0.941976 0.279182
            +vn 0.117448 -0.924453 0.362756
            +vn 0.042288 -0.907349 0.418247
            +vn -0.034756 -0.894122 0.446473
            +vn -0.111080 -0.886585 0.449031
            +vn -0.184362 -0.885555 0.426385
            +vn -0.252478 -0.890425 0.378679
            +vn -0.311654 -0.899884 0.305093
            +vn -0.357553 -0.910849 0.206181
            +vn -0.383158 -0.919831 0.084270
            +vn -0.380965 -0.923175 -0.051118
            +vn -0.347391 -0.919758 -0.182659
            +vn -0.290399 -0.910842 -0.293319
            +vn -0.219950 -0.899892 -0.376585
            +vn -0.143506 -0.890477 -0.431808
            +vn -0.065251 -0.885521 -0.459995
            +vn 0.011419 -0.886635 -0.462329
            +vn 0.084250 -0.894109 -0.439854
            +vn 0.151275 -0.907348 -0.392220
            +vn 0.209225 -0.924429 -0.318835
            +vn 0.253362 -0.942036 -0.219945
            +vn 0.277954 -0.955528 -0.098524
            +vn -0.056109 -0.998396 -0.007541
            +vn -0.503754 0.855464 -0.120053
            +vn 0.004089 0.999867 -0.015811
            +vn 0.019256 0.999729 -0.013076
            +vn -0.475391 0.872536 -0.112622
            +vn 0.634292 0.768857 0.080820
            +vn 0.630708 0.771838 0.080457
            +vn 0.953083 0.276809 0.122517
            +vn 0.952872 0.277550 0.122478
            +vn 0.979849 -0.151244 0.130469
            +vn 0.979864 -0.151140 0.130470
            +vn 0.845276 -0.522088 0.113722
            +vn 0.845275 -0.522090 0.113722
            +vn 0.709883 -0.697740 0.096046
            +vn 0.709904 -0.697719 0.096049
            +vn 0.622597 -0.778076 0.083497
            +vn 0.622090 -0.778486 0.083445
            +vn 0.514767 -0.856300 0.042011
            +vn 0.513874 -0.856850 0.041744
            +vn -0.817440 0.538730 -0.203869
            +vn -0.811208 0.546140 -0.208980
            +vn -0.686394 0.703017 -0.186091
            +vn -0.628463 0.761302 -0.159542
            +vn -0.529925 0.844417 -0.078358
            +vn -0.534574 0.841450 -0.078698
            +vn -0.808617 0.579464 -0.101782
            +vn -0.805687 0.583574 -0.101536
            +vn -0.927259 0.355819 -0.116550
            +vn -0.927196 0.355986 -0.116539
            +vn -0.962152 -0.239988 -0.129112
            +vn -0.962159 -0.239958 -0.129113
            +vn -0.475876 -0.876759 -0.069537
            +vn -0.478271 -0.875431 -0.069844
            +vn -0.327418 -0.942136 -0.071952
            +vn -0.314813 -0.946660 -0.068753
            +vn 0.132551 -0.000592 -0.991176
            +vn 0.133192 -0.000174 -0.991090
            +vn 0.133307 -0.000003 -0.991075
            +vn 0.133921 -0.000948 -0.990992
            +vn 0.133557 0.000031 -0.991041
            +vn 0.132970 -0.000042 -0.991120
            +vn 0.133187 0.000046 -0.991091
            +vn 0.132980 -0.000461 -0.991119
            +vn 0.133528 -0.000202 -0.991045
            +vn 0.132961 0.000041 -0.991121
            +vn 0.132947 0.000160 -0.991123
            +vn 0.133256 -0.000019 -0.991082
            +vn 0.133214 0.000162 -0.991087
            +vn 0.133210 0.000183 -0.991088
            +vn 0.133294 0.000152 -0.991077
            +vn 0.133403 0.000005 -0.991062
            +vn 0.133434 0.000032 -0.991058
            +vn 0.133286 0.000117 -0.991078
            +vn 0.133374 0.000097 -0.991066
            +vn 0.133307 -0.000058 -0.991075
            +vn 0.133584 -0.000206 -0.991037
            +vn 0.133483 -0.000195 -0.991051
            +vn 0.133606 0.000208 -0.991035
            +vn 0.133350 0.000102 -0.991069
            +vn 0.133431 -0.000430 -0.991058
            +vn 0.133486 0.000125 -0.991051
            +vn 0.133275 0.000053 -0.991079
            +vn 0.133389 0.000532 -0.991064
            +vn 0.133381 0.000538 -0.991065
            +vn 0.133381 0.000222 -0.991065
            +vn 0.133155 -0.000482 -0.991095
            +vn 0.133144 -0.000180 -0.991097
            +vn 0.133085 -0.000219 -0.991105
            +vn 0.133376 -0.000067 -0.991066
            +vn 0.133619 -0.000002 -0.991033
            +vn 0.133433 -0.000150 -0.991058
            +vn 0.133425 -0.000140 -0.991059
            +vn 0.133406 -0.000088 -0.991062
            +vn 0.133408 0.000016 -0.991061
            +vn 0.133210 -0.000151 -0.991088
            +vn 0.133201 0.000045 -0.991089
            +vn 0.133327 0.000412 -0.991072
            +vn 0.133232 0.000185 -0.991085
            +vn 0.133101 0.000040 -0.991102
            +vn 0.133468 0.000088 -0.991053
            +vn 0.133051 0.000046 -0.991109
            +vn 0.133249 -0.000025 -0.991083
            +vn 0.133142 -0.000099 -0.991097
            +vn 0.133577 -0.000258 -0.991038
            +vn 0.132908 -0.000103 -0.991128
            +vn 0.133253 -0.000097 -0.991082
            +vn 0.133111 -0.000059 -0.991101
            +vn 0.132985 -0.000316 -0.991118
            +vn 0.133102 -0.000002 -0.991102
            +vn 0.133248 0.000263 -0.991083
            +vn 0.133210 0.000252 -0.991088
            +vn 0.133204 0.000167 -0.991089
            +vn 0.133222 0.000027 -0.991086
            +vn 0.132841 0.000246 -0.991137
            +vn 0.132150 0.000468 -0.991230
            +vn 0.132911 0.000958 -0.991128
            +vn -0.133343 -0.000060 0.991070
            +vn -0.133949 -0.000557 0.990988
            +vn -0.133042 0.000461 0.991110
            +vn -0.133159 -0.000509 0.991095
            +vn -0.132848 -0.000315 0.991136
            +vn -0.133556 -0.000026 0.991041
            +vn -0.133241 0.000073 0.991084
            +vn -0.133369 -0.000117 0.991067
            +vn -0.132580 -0.000183 0.991172
            +vn -0.132776 -0.000001 0.991146
            +vn -0.133152 0.000237 0.991096
            +vn -0.133088 0.000191 0.991104
            +vn -0.133232 0.000300 0.991085
            +vn -0.133270 0.000094 0.991080
            +vn -0.133240 0.000513 0.991084
            +vn -0.133335 0.000136 0.991071
            +vn -0.133191 -0.000350 0.991090
            +vn -0.133158 -0.000369 0.991095
            +vn -0.133354 -0.000008 0.991069
            +vn -0.133202 -0.000184 0.991089
            +vn -0.133178 -0.000101 0.991092
            +vn -0.133174 0.000090 0.991093
            +vn -0.133050 0.000136 0.991109
            +vn -0.133416 0.000029 0.991060
            +vn -0.133163 -0.000228 0.991094
            +vn -0.133071 0.000140 0.991107
            +vn -0.133190 0.000350 0.991090
            +vn -0.133087 -0.000206 0.991104
            +vn -0.133198 -0.000127 0.991090
            +vn -0.132896 -0.000047 0.991130
            +vn -0.133167 0.000230 0.991094
            +vn -0.133443 -0.000132 0.991057
            +vn -0.133465 0.000057 0.991054
            +vn -0.133543 0.000087 0.991043
            +vn -0.133493 0.000177 0.991050
            +vn -0.133213 0.000180 0.991087
            +vn -0.133199 0.000149 0.991089
            +vn -0.133447 0.000086 0.991056
            +vn -0.133983 0.000292 0.990984
            +vn -0.133201 -0.000074 0.991089
            +vn -0.132944 -0.000148 0.991123
            +vn -0.132990 -0.000131 0.991117
            +vn -0.133045 0.000136 0.991110
            +vn -0.133531 -0.000062 0.991045
            +vn -0.133492 0.000127 0.991050
            +vn -0.133434 0.000148 0.991058
            +vn -0.133429 0.000151 0.991058
            +vn -0.133031 0.000165 0.991112
            +vn -0.133137 0.000203 0.991098
            +vn -0.132933 0.000112 0.991125
            +vn -0.132996 0.000227 0.991117
            +vn -0.133142 0.000148 0.991097
            +vn -0.133539 0.000139 0.991044
            +vn -0.134107 0.000021 0.990967
            +vn -0.133689 0.000324 0.991023
            +vn -0.133540 0.000315 0.991043
            +vn -0.133306 0.000241 0.991075
            +vn -0.133197 -0.000023 0.991090
            +vn -0.132551 -0.000503 0.991176
            +vn -0.131679 -0.000858 0.991292
            +vn -0.132147 -0.000975 0.991230
            +vn 0.877247 -0.465324 0.117948
            +vn 0.881844 -0.465479 -0.075377
            +vn 0.906275 -0.415524 -0.077494
            +vn 0.901536 -0.415386 0.121194
            +vn 0.844342 -0.465552 -0.265233
            +vn 0.867708 -0.415699 -0.272539
            +vn 0.768564 -0.465577 -0.438802
            +vn 0.789798 -0.415741 -0.450975
            +vn 0.658691 -0.465563 -0.591082
            +vn 0.676897 -0.415719 -0.607444
            +vn 0.518259 -0.465576 -0.717389
            +vn 0.532590 -0.415694 -0.737256
            +vn 0.350842 -0.465518 -0.812528
            +vn 0.360619 -0.415578 -0.835014
            +vn 0.165429 -0.465363 -0.869524
            +vn 0.170042 -0.415397 -0.893605
            +vn -0.026602 -0.465394 -0.884704
            +vn -0.027441 -0.415434 -0.909210
            +vn -0.218973 -0.465482 -0.857541
            +vn -0.225061 -0.415568 -0.881278
            +vn -0.397321 -0.465547 -0.790824
            +vn -0.408285 -0.415626 -0.812748
            +vn -0.555268 -0.465575 -0.689143
            +vn -0.570649 -0.415671 -0.708221
            +vn -0.688524 -0.465524 -0.556077
            +vn -0.707571 -0.415677 -0.571451
            +vn -0.792030 -0.465508 -0.394958
            +vn -0.813899 -0.415618 -0.405993
            +vn -0.859241 -0.465418 -0.212349
            +vn -0.882992 -0.415499 -0.218369
            +vn -0.884829 -0.465400 -0.021938
            +vn -0.909321 -0.415490 -0.022431
            +vn -0.868262 -0.465496 0.171567
            +vn -0.892252 -0.415624 0.176475
            +vn -0.811019 -0.465453 0.354403
            +vn -0.833397 -0.415618 0.364295
            +vn -0.717620 -0.465517 0.517992
            +vn -0.737515 -0.415613 0.532295
            +vn -0.592015 -0.465555 0.657858
            +vn -0.608427 -0.415633 0.676066
            +vn -0.437580 -0.465566 0.769267
            +vn -0.449778 -0.415609 0.790550
            +vn -0.259275 -0.465480 0.846230
            +vn -0.266569 -0.415478 0.869666
            +vn -0.070049 -0.465405 0.882321
            +vn -0.071936 -0.415415 0.906783
            +vn 0.123860 -0.465512 0.876332
            +vn 0.127360 -0.415572 0.900599
            +vn 0.310362 -0.465602 0.828789
            +vn 0.318970 -0.415680 0.851745
            +vn 0.479143 -0.465626 0.744053
            +vn 0.492430 -0.415692 0.764665
            +vn 0.625289 -0.465592 0.626289
            +vn 0.642637 -0.415686 0.643602
            +vn 0.744369 -0.465491 0.478784
            +vn 0.764943 -0.415653 0.492032
            +vn 0.830700 -0.465401 0.305516
            +vn 0.853648 -0.415523 0.314048
            +vn 0.948396 -0.306575 -0.080972
            +vn 0.943401 -0.306462 0.126791
            +vn 0.908096 -0.306671 -0.285159
            +vn 0.826543 -0.306663 -0.472001
            +vn 0.708412 -0.306688 -0.635685
            +vn 0.557320 -0.306668 -0.771589
            +vn 0.377334 -0.306533 -0.873874
            +vn 0.177874 -0.306398 -0.935137
            +vn -0.028710 -0.306476 -0.951446
            +vn -0.235513 -0.306623 -0.922234
            +vn -0.427236 -0.306650 -0.850550
            +vn -0.597141 -0.306675 -0.741197
            +vn -0.740527 -0.306664 -0.597977
            +vn -0.851768 -0.306560 -0.424869
            +vn -0.924006 -0.306483 -0.228649
            +vn -0.951567 -0.306546 -0.023451
            +vn -0.933710 -0.306690 0.184733
            +vn -0.872079 -0.306732 0.381305
            +vn -0.771760 -0.306669 0.557083
            +vn -0.636769 -0.306646 0.707456
            +vn -0.470678 -0.306613 0.827316
            +vn -0.278941 -0.306468 0.910093
            +vn -0.075312 -0.306443 0.948905
            +vn 0.133229 -0.306592 0.942471
            +vn 0.333775 -0.306666 0.891376
            +vn 0.515323 -0.306655 0.800253
            +vn 0.672494 -0.306708 0.673559
            +vn 0.800515 -0.306753 0.514858
            +vn 0.893337 -0.306605 0.328546
            +vn 0.978513 -0.188527 -0.083493
            +vn 0.973328 -0.188448 0.130843
            +vn 0.936927 -0.188547 -0.294309
            +vn 0.852801 -0.188512 -0.487026
            +vn 0.730958 -0.188518 -0.655867
            +vn 0.574973 -0.188486 -0.796165
            +vn 0.389347 -0.188439 -0.901610
            +vn 0.183569 -0.188420 -0.964780
            +vn -0.029562 -0.188476 -0.981633
            +vn -0.242933 -0.188576 -0.951537
            +vn -0.440830 -0.188611 -0.877551
            +vn -0.616140 -0.188560 -0.764733
            +vn -0.764063 -0.188527 -0.616981
            +vn -0.878823 -0.188493 -0.438338
            +vn -0.953293 -0.188444 -0.236053
            +vn -0.981782 -0.188467 -0.024188
            +vn -0.963396 -0.188538 0.190581
            +vn -0.899818 -0.188600 0.393392
            +vn -0.796226 -0.188620 0.574845
            +vn -0.657037 -0.188635 0.729876
            +vn -0.485573 -0.188604 0.853609
            +vn -0.287767 -0.188491 0.938968
            +vn -0.077757 -0.188463 0.978997
            +vn 0.137467 -0.188536 0.972398
            +vn 0.344444 -0.188556 0.919676
            +vn 0.531685 -0.188552 0.825687
            +vn 0.693803 -0.188567 0.695040
            +vn 0.826005 -0.188540 0.531195
            +vn 0.921739 -0.188469 0.338935
            +vn 0.988515 -0.125370 -0.084383
            +vn 0.983262 -0.125352 0.132220
            +vn 0.946492 -0.125431 -0.297354
            +vn 0.861496 -0.125452 -0.492022
            +vn 0.738433 -0.125358 -0.662572
            +vn 0.580845 -0.125326 -0.804308
            +vn 0.393382 -0.125398 -0.910783
            +vn 0.185514 -0.125396 -0.974608
            +vn -0.029892 -0.125392 -0.991657
            +vn -0.245383 -0.125482 -0.961271
            +vn -0.445366 -0.125522 -0.886506
            +vn -0.622495 -0.125425 -0.772508
            +vn -0.771860 -0.125444 -0.623294
            +vn -0.887796 -0.125485 -0.442800
            +vn -0.963020 -0.125355 -0.238494
            +vn -0.991817 -0.125306 -0.024428
            +vn -0.973250 -0.125336 0.192549
            +vn -0.909051 -0.125318 0.397394
            +vn -0.804369 -0.125337 0.580759
            +vn -0.663808 -0.125392 0.737316
            +vn -0.490548 -0.125443 0.862338
            +vn -0.290699 -0.125398 0.948562
            +vn -0.078566 -0.125346 0.988998
            +vn 0.138896 -0.125356 0.982341
            +vn 0.347964 -0.125376 0.929087
            +vn 0.537104 -0.125455 0.834134
            +vn 0.700879 -0.125471 0.702158
            +vn 0.834461 -0.125368 0.536616
            +vn 0.931141 -0.125337 0.342442
            +vn -0.930475 0.357620 0.079525
            +vn -0.925570 0.357525 -0.124484
            +vn -0.890972 0.357661 0.279728
            +vn -0.810913 0.357617 0.463174
            +vn -0.694925 0.357635 0.623840
            +vn -0.546778 0.357673 0.757037
            +vn -0.370422 0.357620 0.857260
            +vn -0.174629 0.357517 0.917435
            +vn 0.028258 0.357580 0.933455
            +vn 0.230933 0.357694 0.904834
            +vn 0.419207 0.357693 0.834459
            +vn 0.585979 0.357638 0.727134
            +vn 0.726491 0.357645 0.586772
            +vn 0.835692 0.357656 0.416776
            +vn 0.906531 0.357566 0.224387
            +vn 0.933598 0.357582 0.023016
            +vn 0.916080 0.357661 -0.181318
            +vn 0.855652 0.357680 -0.374066
            +vn 0.757112 0.357675 -0.546672
            +vn 0.624725 0.357740 -0.694075
            +vn 0.461890 0.357749 -0.811587
            +vn 0.273641 0.357615 -0.892879
            +vn 0.073885 0.357547 -0.930968
            +vn -0.130775 0.357666 -0.924648
            +vn -0.327459 0.357660 -0.874557
            +vn -0.505482 0.357626 -0.785233
            +vn -0.659870 0.357646 -0.660804
            +vn -0.785492 0.357690 -0.505034
            +vn -0.876420 0.357618 -0.322487
            +vn -0.941582 0.327048 0.080397
            +vn -0.936606 0.326964 -0.125952
            +vn -0.901595 0.327130 0.283042
            +vn -0.820585 0.327114 0.468655
            +vn -0.703246 0.327095 0.631233
            +vn -0.553208 0.327098 0.766138
            +vn -0.374711 0.327071 0.867535
            +vn -0.176685 0.326974 0.928370
            +vn 0.028524 0.327011 0.944590
            +vn 0.233684 0.327117 0.915635
            +vn 0.424178 0.327140 0.844424
            +vn 0.592919 0.327105 0.735833
            +vn 0.735145 0.327108 0.593770
            +vn 0.845698 0.327085 0.421674
            +vn 0.917370 0.326974 0.226983
            +vn 0.944740 0.326992 0.023316
            +vn 0.927021 0.327100 -0.183407
            +vn 0.865872 0.327116 -0.378499
            +vn 0.766148 0.327094 -0.553196
            +vn 0.632159 0.327111 -0.702406
            +vn 0.467350 0.327123 -0.821325
            +vn 0.276846 0.327033 -0.903552
            +vn 0.074782 0.326966 -0.942073
            +vn -0.132244 0.327077 -0.935699
            +vn -0.331368 0.327109 -0.884983
            +vn -0.511533 0.327134 -0.794555
            +vn -0.667738 0.327152 -0.668653
            +vn -0.794859 0.327147 -0.511052
            +vn -0.886882 0.327050 -0.326311
            +vn -0.946669 0.311914 0.080796
            +vn -0.941674 0.311803 -0.126603
            +vn -0.906452 0.312044 0.284560
            +vn -0.825032 0.312017 0.471135
            +vn -0.707092 0.311985 0.634575
            +vn -0.556127 0.311934 0.770338
            +vn -0.376607 0.311900 0.872288
            +vn -0.177627 0.311831 0.933386
            +vn 0.028653 0.311851 0.949699
            +vn 0.234984 0.311912 0.920594
            +vn 0.426440 0.311954 0.849019
            +vn 0.596054 0.311949 0.739870
            +vn 0.739108 0.311953 0.596997
            +vn 0.850303 0.311913 0.423905
            +vn 0.922341 0.311825 0.228151
            +vn 0.949844 0.311846 0.023428
            +vn 0.932033 0.311984 -0.184340
            +vn 0.870542 0.312031 -0.380518
            +vn 0.770268 0.311994 -0.556190
            +vn 0.635540 0.311950 -0.706241
            +vn 0.469856 0.311939 -0.825790
            +vn 0.278318 0.311868 -0.908448
            +vn 0.075195 0.311814 -0.947163
            +vn -0.132855 0.311948 -0.940765
            +vn -0.333189 0.311996 -0.889744
            +vn -0.514332 0.312007 -0.798820
            +vn -0.671366 0.312003 -0.672251
            +vn -0.799156 0.311978 -0.513828
            +vn -0.891666 0.311882 -0.328117
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000001
            +vn 0.000000 1.000000 0.000001
            +vn 0.000000 1.000000 0.000001
            +vn 0.000000 1.000000 0.000002
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000001
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000002
            +vn 0.000000 1.000000 0.000001
            +vn 0.000000 1.000000 0.000002
            +vn 0.000000 1.000000 0.000001
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000001
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000001
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000000
            +vn 0.000000 1.000000 -0.000002
            +vn 0.000000 1.000000 0.000000
            +vn 0.000000 1.000000 0.000002
            +vn 0.000000 1.000000 0.000001
            +f 4/4/1 5/5/2 3/3/3 2/2/4
            +f 5/5/2 1/1/5 3/3/3
            +f 6/6/6 7/7/7 5/5/2 4/4/1
            +f 7/7/7 1/1/5 5/5/2
            +f 8/8/8 9/9/9 7/7/7 6/6/6
            +f 9/9/9 1/1/5 7/7/7
            +f 10/10/10 11/11/11 9/9/9 8/8/8
            +f 11/11/11 1/1/5 9/9/9
            +f 12/12/12 13/13/13 11/11/11 10/10/10
            +f 13/13/13 1/1/5 11/11/11
            +f 14/14/14 15/15/15 13/13/13 12/12/12
            +f 15/15/15 1/1/5 13/13/13
            +f 16/16/16 17/17/17 15/15/15 14/14/14
            +f 17/17/17 1/1/5 15/15/15
            +f 18/18/18 19/19/19 17/17/17 16/16/16
            +f 19/19/19 1/1/5 17/17/17
            +f 20/20/20 21/21/21 19/19/19 18/18/18
            +f 21/21/21 1/1/5 19/19/19
            +f 22/22/22 23/23/23 21/21/21 20/20/20
            +f 23/23/23 1/1/5 21/21/21
            +f 24/24/24 25/25/25 23/23/23 22/22/22
            +f 25/25/25 1/1/5 23/23/23
            +f 26/26/26 27/27/27 25/25/25 24/24/24
            +f 27/27/27 1/1/5 25/25/25
            +f 28/28/28 29/29/29 27/27/27 26/26/26
            +f 29/29/29 1/1/5 27/27/27
            +f 30/30/30 31/31/31 29/29/29 28/28/28
            +f 31/31/31 1/1/5 29/29/29
            +f 32/32/32 33/33/33 31/31/31 30/30/30
            +f 33/33/33 1/1/5 31/31/31
            +f 34/34/34 35/35/35 33/33/33 32/32/32
            +f 35/35/35 1/1/5 33/33/33
            +f 36/36/36 37/37/37 35/35/35 34/34/34
            +f 37/37/37 1/1/5 35/35/35
            +f 38/38/38 39/39/39 37/37/37 36/36/36
            +f 39/39/39 1/1/5 37/37/37
            +f 40/40/40 41/41/41 39/39/39 38/38/38
            +f 41/41/41 1/1/5 39/39/39
            +f 42/42/42 43/43/43 41/41/41 40/40/40
            +f 43/43/43 1/1/5 41/41/41
            +f 44/44/44 45/45/45 43/43/43 42/42/42
            +f 45/45/45 1/1/5 43/43/43
            +f 46/46/46 47/47/47 45/45/45 44/44/44
            +f 47/47/47 1/1/5 45/45/45
            +f 48/48/48 49/49/49 47/47/47 46/46/46
            +f 49/49/49 1/1/5 47/47/47
            +f 50/50/50 51/51/51 49/49/49 48/48/48
            +f 51/51/51 1/1/5 49/49/49
            +f 52/52/52 53/53/53 51/51/51 50/50/50
            +f 53/53/53 1/1/5 51/51/51
            +f 54/54/54 55/55/55 53/53/53 52/52/52
            +f 55/55/55 1/1/5 53/53/53
            +f 56/56/56 57/57/57 55/55/55 54/54/54
            +f 57/57/57 1/1/5 55/55/55
            +f 58/58/58 59/59/59 57/57/57 56/56/56
            +f 59/59/59 1/1/5 57/57/57
            +f 60/60/60 61/61/61 59/59/59 58/58/58
            +f 61/61/61 1/1/5 59/59/59
            +f 62/62/62 63/63/63 61/61/61 60/60/60
            +f 63/63/63 1/1/5 61/61/61
            +f 64/64/64 65/65/65 63/63/63 62/62/62
            +f 65/65/65 1/1/5 63/63/63
            +f 66/66/66 67/67/67 65/65/65 64/64/64
            +f 67/67/67 1/1/5 65/65/65
            +f 68/68/68 69/69/69 67/67/67 66/66/66
            +f 69/69/69 1/1/5 67/67/67
            +f 70/70/70 71/71/71 69/69/69 68/68/68
            +f 71/71/71 1/1/5 69/69/69
            +f 72/72/72 73/73/73 71/71/71 70/70/70
            +f 73/73/73 1/1/5 71/71/71
            +f 2/2/4 3/3/3 73/73/73 72/72/72
            +f 3/3/3 1/1/5 73/73/73
            +f 74/75/74 75/76/75 104/106/76 103/105/77
            +f 75/76/75 76/77/78 105/107/79 104/106/76
            +f 76/77/78 77/78/80 106/108/81 105/107/79
            +f 77/78/80 78/79/82 107/109/83 106/108/81
            +f 78/79/82 79/80/84 108/110/85 107/109/83
            +f 79/80/84 80/81/86 109/111/87 108/110/85
            +f 80/81/86 81/82/88 110/112/89 109/111/87
            +f 81/82/88 82/83/90 111/113/91 110/112/89
            +f 82/83/90 83/84/92 112/114/93 111/113/91
            +f 83/84/92 84/85/94 113/115/95 112/114/93
            +f 84/85/94 85/86/96 114/116/97 113/115/95
            +f 85/86/96 86/87/98 115/117/99 114/116/97
            +f 86/87/98 87/88/100 116/118/101 115/117/99
            +f 87/88/100 88/89/102 117/119/103 116/118/101
            +f 88/89/102 89/90/104 118/120/105 117/119/103
            +f 89/90/104 90/91/106 119/121/107 118/120/105
            +f 90/91/106 91/92/108 120/122/109 119/121/107
            +f 91/92/108 92/93/110 121/123/111 120/122/109
            +f 92/93/110 93/94/112 122/124/113 121/123/111
            +f 93/94/112 94/95/114 123/125/115 122/124/113
            +f 94/95/114 95/96/116 124/126/117 123/125/115
            +f 95/96/116 96/97/118 125/127/119 124/126/117
            +f 96/97/118 97/98/120 126/128/121 125/127/119
            +f 97/98/120 98/99/122 127/129/123 126/128/121
            +f 98/99/122 99/100/124 128/130/125 127/129/123
            +f 99/100/124 100/101/126 129/131/127 128/130/125
            +f 100/101/126 101/102/128 130/132/129 129/131/127
            +f 101/102/128 102/103/130 131/133/131 130/132/129
            +f 102/103/130 74/74/74 103/104/77 131/133/131
            +f 103/105/77 104/106/76 133/136/132 132/135/133
            +f 104/106/76 105/107/79 134/137/134 133/136/132
            +f 105/107/79 106/108/81 135/138/135 134/137/134
            +f 106/108/81 107/109/83 136/139/136 135/138/135
            +f 107/109/83 108/110/85 137/140/137 136/139/136
            +f 108/110/85 109/111/87 138/141/138 137/140/137
            +f 109/111/87 110/112/89 139/142/139 138/141/138
            +f 110/112/89 111/113/91 140/143/140 139/142/139
            +f 111/113/91 112/114/93 141/144/141 140/143/140
            +f 112/114/93 113/115/95 142/145/142 141/144/141
            +f 113/115/95 114/116/97 143/146/143 142/145/142
            +f 114/116/97 115/117/99 144/147/144 143/146/143
            +f 115/117/99 116/118/101 145/148/145 144/147/144
            +f 116/118/101 117/119/103 146/149/146 145/148/145
            +f 117/119/103 118/120/105 147/150/147 146/149/146
            +f 118/120/105 119/121/107 148/151/148 147/150/147
            +f 119/121/107 120/122/109 149/152/149 148/151/148
            +f 120/122/109 121/123/111 150/153/150 149/152/149
            +f 121/123/111 122/124/113 151/154/151 150/153/150
            +f 122/124/113 123/125/115 152/155/152 151/154/151
            +f 123/125/115 124/126/117 153/156/153 152/155/152
            +f 124/126/117 125/127/119 154/157/154 153/156/153
            +f 125/127/119 126/128/121 155/158/155 154/157/154
            +f 126/128/121 127/129/123 156/159/156 155/158/155
            +f 127/129/123 128/130/125 157/160/157 156/159/156
            +f 128/130/125 129/131/127 158/161/158 157/160/157
            +f 129/131/127 130/132/129 159/162/159 158/161/158
            +f 130/132/129 131/133/131 160/163/160 159/162/159
            +f 131/133/131 103/104/77 132/134/133 160/163/160
            +f 132/135/133 133/136/132 162/166/161 161/165/162
            +f 133/136/132 134/137/134 163/167/163 162/166/161
            +f 134/137/134 135/138/135 164/168/164 163/167/163
            +f 135/138/135 136/139/136 165/169/165 164/168/164
            +f 136/139/136 137/140/137 166/170/166 165/169/165
            +f 137/140/137 138/141/138 167/171/167 166/170/166
            +f 138/141/138 139/142/139 168/172/168 167/171/167
            +f 139/142/139 140/143/140 169/173/169 168/172/168
            +f 140/143/140 141/144/141 170/174/170 169/173/169
            +f 141/144/141 142/145/142 171/175/171 170/174/170
            +f 142/145/142 143/146/143 172/176/172 171/175/171
            +f 143/146/143 144/147/144 173/177/173 172/176/172
            +f 144/147/144 145/148/145 174/178/174 173/177/173
            +f 145/148/145 146/149/146 175/179/175 174/178/174
            +f 146/149/146 147/150/147 176/180/176 175/179/175
            +f 147/150/147 148/151/148 177/181/177 176/180/176
            +f 148/151/148 149/152/149 178/182/178 177/181/177
            +f 149/152/149 150/153/150 179/183/179 178/182/178
            +f 150/153/150 151/154/151 180/184/180 179/183/179
            +f 151/154/151 152/155/152 181/185/181 180/184/180
            +f 152/155/152 153/156/153 182/186/182 181/185/181
            +f 153/156/153 154/157/154 183/187/183 182/186/182
            +f 154/157/154 155/158/155 184/188/184 183/187/183
            +f 155/158/155 156/159/156 185/189/185 184/188/184
            +f 156/159/156 157/160/157 186/190/186 185/189/185
            +f 157/160/157 158/161/158 187/191/187 186/190/186
            +f 158/161/158 159/162/159 188/192/188 187/191/187
            +f 159/162/159 160/163/160 189/193/189 188/192/188
            +f 160/163/160 132/134/133 161/164/162 189/193/189
            +f 193/197/190 190/194/191 191/195/192
            +f 194/198/193 190/194/191 193/197/190
            +f 197/201/194 190/194/191 194/198/193
            +f 212/216/195 190/194/191 197/201/194
            +f 215/219/196 190/194/191 212/216/195
            +f 216/220/197 190/194/191 215/219/196
            +f 218/222/198 190/194/191 216/220/197
            +f 193/197/190 191/195/192 192/196/199
            +f 197/201/194 194/198/193 195/199/200
            +f 197/201/194 195/199/200 196/200/201
            +f 204/208/202 197/201/194 198/202/203
            +f 212/216/195 197/201/194 204/208/202
            +f 200/204/204 198/202/203 199/203/205
            +f 201/205/206 198/202/203 200/204/204
            +f 204/208/202 198/202/203 201/205/206
            +f 204/208/202 201/205/206 202/206/207
            +f 204/208/202 202/206/207 203/207/208
            +f 212/216/195 204/208/202 205/209/209
            +f 207/211/210 205/209/209 206/210/211
            +f 208/212/212 205/209/209 207/211/210
            +f 211/215/213 205/209/209 208/212/212
            +f 212/216/195 205/209/209 211/215/213
            +f 211/215/213 208/212/212 209/213/214
            +f 211/215/213 209/213/214 210/214/215
            +f 214/218/216 212/216/195 213/217/217
            +f 215/219/196 212/216/195 214/218/216
            +f 218/222/198 216/220/197 217/221/218
            +f 222/226/219 219/223/220 220/224/221
            +f 223/227/222 219/223/220 222/226/219
            +f 226/230/223 219/223/220 223/227/222
            +f 241/245/224 219/223/220 226/230/223
            +f 244/248/225 219/223/220 241/245/224
            +f 245/249/226 219/223/220 244/248/225
            +f 247/251/227 219/223/220 245/249/226
            +f 222/226/219 220/224/221 221/225/228
            +f 226/230/223 223/227/222 224/228/229
            +f 226/230/223 224/228/229 225/229/230
            +f 233/237/231 226/230/223 227/231/232
            +f 241/245/224 226/230/223 233/237/231
            +f 229/233/233 227/231/232 228/232/234
            +f 230/234/235 227/231/232 229/233/233
            +f 233/237/231 227/231/232 230/234/235
            +f 233/237/231 230/234/235 231/235/236
            +f 233/237/231 231/235/236 232/236/237
            +f 241/245/224 233/237/231 234/238/238
            +f 236/240/239 234/238/238 235/239/240
            +f 237/241/241 234/238/238 236/240/239
            +f 240/244/242 234/238/238 237/241/241
            +f 241/245/224 234/238/238 240/244/242
            +f 240/244/242 237/241/241 238/242/243
            +f 240/244/242 238/242/243 239/243/244
            +f 243/247/245 241/245/224 242/246/246
            +f 244/248/225 241/245/224 243/247/245
            +f 247/251/227 245/249/226 246/250/247
            +f 271/258/248 250/259/249 249/257/250 248/254/251
            +f 272/261/252 251/262/253 250/259/249 271/258/248
            +f 273/264/254 252/265/255 251/262/253 272/261/252
            +f 274/267/256 253/268/257 252/265/255 273/264/254
            +f 275/270/258 254/271/259 253/268/257 274/267/256
            +f 255/273/260 256/274/261 254/271/259 275/270/258
            +f 257/279/262 270/306/263 256/277/261 255/276/260
            +f 258/282/264 269/305/265 270/281/263 257/280/262
            +f 259/284/266 268/285/267 269/305/265 258/282/264
            +f 260/287/268 267/288/269 268/285/267 259/284/266
            +f 261/290/270 266/291/271 267/288/269 260/287/268
            +f 262/293/272 265/294/273 266/291/271 261/290/270
            +f 263/295/274 264/296/275 265/294/273 262/293/272
            +f 248/253/251 249/256/250 264/299/275 263/298/274
            +f 250/260/249 265/301/273 264/300/275 249/255/250
            +f 251/263/253 266/302/271 265/301/273 250/260/249
            +f 252/266/255 267/303/269 266/302/271 251/263/253
            +f 253/269/257 268/304/267 267/303/269 252/266/255
            +f 254/272/259 269/305/265 268/304/267 253/269/257
            +f 256/278/261 270/306/263 269/305/265 254/272/259
            +f 262/292/272 271/307/248 248/252/251 263/297/274
            +f 261/289/270 272/308/252 271/307/248 262/292/272
            +f 260/286/268 273/309/254 272/308/252 261/289/270
            +f 259/283/266 274/310/256 273/309/254 260/286/268
            +f 258/282/264 275/311/258 274/310/256 259/283/266
            +f 257/279/262 255/275/260 275/311/258 258/282/264
            +f 278/338/276 301/361/277 324/385/278 277/337/279
            +f 279/339/280 302/362/281 301/361/277 278/338/276
            +f 280/340/282 303/363/283 302/362/281 279/339/280
            +f 281/341/284 304/364/285 303/363/283 280/340/282
            +f 282/342/286 305/365/287 304/364/285 281/341/284
            +f 283/343/288 306/366/289 305/365/287 282/342/286
            +f 284/344/290 307/367/291 306/366/289 283/343/288
            +f 285/345/292 308/368/293 307/367/291 284/344/290
            +f 286/346/294 309/369/295 308/368/293 285/345/292
            +f 287/347/296 310/370/297 309/369/295 286/346/294
            +f 288/348/298 311/371/299 310/370/297 287/347/296
            +f 289/349/300 312/372/301 311/371/299 288/348/298
            +f 290/350/302 313/373/303 312/372/301 289/349/300
            +f 291/351/304 314/374/305 313/373/303 290/350/302
            +f 292/352/306 315/375/307 314/374/305 291/351/304
            +f 293/353/308 316/376/309 315/375/307 292/352/306
            +f 294/354/310 317/377/311 316/376/309 293/353/308
            +f 295/355/312 318/378/313 317/377/311 294/354/310
            +f 296/356/314 319/379/315 318/378/313 295/355/312
            +f 297/357/316 320/380/317 319/379/315 296/356/314
            +f 298/358/318 321/381/319 320/380/317 297/357/316
            +f 299/359/320 322/382/321 321/381/319 298/358/318
            +f 300/360/322 323/383/323 322/382/321 299/359/320
            +f 277/336/279 324/384/278 323/383/323 300/360/322
            +f 301/361/277 325/386/324 348/410/325 324/385/278
            +f 302/362/281 326/387/326 325/386/324 301/361/277
            +f 303/363/283 327/388/327 326/387/326 302/362/281
            +f 304/364/285 328/389/328 327/388/327 303/363/283
            +f 305/365/287 329/390/329 328/389/328 304/364/285
            +f 306/366/289 330/391/330 329/390/329 305/365/287
            +f 307/367/291 331/392/331 330/391/330 306/366/289
            +f 308/368/293 332/393/332 331/392/331 307/367/291
            +f 309/369/295 333/394/333 332/393/332 308/368/293
            +f 310/370/297 334/395/334 333/394/333 309/369/295
            +f 311/371/299 335/396/335 334/395/334 310/370/297
            +f 312/372/301 336/397/336 335/396/335 311/371/299
            +f 313/373/303 337/398/337 336/397/336 312/372/301
            +f 314/374/305 338/399/338 337/398/337 313/373/303
            +f 315/375/307 339/400/339 338/399/338 314/374/305
            +f 316/376/309 340/401/340 339/400/339 315/375/307
            +f 317/377/311 341/402/341 340/401/340 316/376/309
            +f 318/378/313 342/403/342 341/402/341 317/377/311
            +f 319/379/315 343/404/343 342/403/342 318/378/313
            +f 320/380/317 344/405/344 343/404/343 319/379/315
            +f 321/381/319 345/406/345 344/405/344 320/380/317
            +f 322/382/321 346/407/346 345/406/345 321/381/319
            +f 323/383/323 347/408/347 346/407/346 322/382/321
            +f 324/384/278 348/409/325 347/408/347 323/383/323
            +f 276/335/348 348/410/325 325/386/324
            +f 276/334/348 325/386/324 326/387/326
            +f 276/333/348 326/387/326 327/388/327
            +f 276/332/348 327/388/327 328/389/328
            +f 276/331/348 328/389/328 329/390/329
            +f 276/330/348 329/390/329 330/391/330
            +f 276/329/348 330/391/330 331/392/331
            +f 276/328/348 331/392/331 332/393/332
            +f 276/327/348 332/393/332 333/394/333
            +f 276/326/348 333/394/333 334/395/334
            +f 276/325/348 334/395/334 335/396/335
            +f 276/324/348 335/396/335 336/397/336
            +f 276/323/348 336/397/336 337/398/337
            +f 276/322/348 337/398/337 338/399/338
            +f 276/321/348 338/399/338 339/400/339
            +f 276/320/348 339/400/339 340/401/340
            +f 276/319/348 340/401/340 341/402/341
            +f 276/318/348 341/402/341 342/403/342
            +f 276/317/348 342/403/342 343/404/343
            +f 276/316/348 343/404/343 344/405/344
            +f 276/315/348 344/405/344 345/406/345
            +f 276/314/348 345/406/345 346/407/346
            +f 276/313/348 346/407/346 347/408/347
            +f 276/312/348 347/408/347 348/409/325
            +f 365/411/349 349/412/350 366/430/351 382/429/352
            +f 349/412/350 350/413/353 367/431/354 366/430/351
            +f 350/413/353 351/414/355 368/432/356 367/431/354
            +f 351/414/355 352/415/357 369/433/358 368/432/356
            +f 352/415/357 353/416/359 370/434/360 369/433/358
            +f 353/416/359 354/417/361 371/435/362 370/434/360
            +f 354/417/361 355/418/363 372/436/364 371/435/362
            +f 355/418/363 356/419/365 373/437/366 372/436/364
            +f 356/419/365 357/420/367 374/438/368 373/437/366
            +f 357/420/367 358/421/369 375/439/370 374/438/368
            +f 358/421/369 359/422/371 376/440/372 375/439/370
            +f 359/422/371 360/423/373 377/441/374 376/440/372
            +f 360/423/373 361/424/375 378/442/376 377/441/374
            +f 361/424/375 362/425/377 379/443/378 378/442/376
            +f 362/425/377 363/426/379 380/444/380 379/443/378
            +f 363/426/379 364/427/381 381/445/382 380/444/380
            +f 364/427/381 365/428/349 382/446/352 381/445/382
            +f 442/506/383 383/447/384 441/505/385
            +f 443/507/386 383/447/384 442/506/383
            +f 441/505/385 383/447/384 384/448/387
            +f 441/505/385 384/448/387 385/449/388
            +f 440/504/389 385/449/388 386/450/390
            +f 441/505/385 385/449/388 440/504/389
            +f 440/504/389 386/450/390 387/451/391
            +f 440/504/389 387/451/391 388/452/392
            +f 439/503/393 388/452/392 389/453/394
            +f 440/504/389 388/452/392 439/503/393
            +f 439/503/393 389/453/394 390/454/395
            +f 438/502/396 390/454/395 391/455/397
            +f 439/503/393 390/454/395 438/502/396
            +f 437/501/398 391/455/397 392/456/399
            +f 438/502/396 391/455/397 437/501/398
            +f 437/501/398 392/456/399 393/457/400
            +f 436/500/401 393/457/400 394/458/402
            +f 437/501/398 393/457/400 436/500/401
            +f 436/500/401 394/458/402 395/459/403
            +f 435/499/404 395/459/403 396/460/405
            +f 436/500/401 395/459/403 435/499/404
            +f 435/499/404 396/460/405 397/461/406
            +f 435/499/404 397/461/406 398/462/407
            +f 434/498/408 398/462/407 399/463/409
            +f 435/499/404 398/462/407 434/498/408
            +f 434/498/408 399/463/409 400/464/410
            +f 433/497/411 400/464/410 401/465/412
            +f 434/498/408 400/464/410 433/497/411
            +f 432/496/413 401/465/412 402/466/414
            +f 433/497/411 401/465/412 432/496/413
            +f 432/496/413 402/466/414 431/495/415
            +f 431/495/415 402/466/414 403/467/416
            +f 431/495/415 403/467/416 430/494/417
            +f 429/493/418 403/467/416 404/468/419
            +f 430/494/417 403/467/416 429/493/418
            +f 429/493/418 404/468/419 428/492/420
            +f 428/492/420 404/468/419 405/469/421
            +f 428/492/420 405/469/421 427/491/422
            +f 427/491/422 405/469/421 406/470/423
            +f 427/491/422 406/470/423 426/490/424
            +f 426/490/424 406/470/423 407/471/425
            +f 426/490/424 407/471/425 425/489/426
            +f 425/489/426 407/471/425 408/472/427
            +f 425/489/426 408/472/427 409/473/428
            +f 425/489/426 409/473/428 424/488/429
            +f 424/488/429 409/473/428 410/474/430
            +f 424/488/429 410/474/430 423/487/431
            +f 423/487/431 410/474/430 422/486/432
            +f 422/486/432 410/474/430 421/485/433
            +f 421/485/433 410/474/430 411/475/434
            +f 421/485/433 411/475/434 420/484/435
            +f 420/484/435 411/475/434 419/483/436
            +f 419/483/436 411/475/434 412/476/437
            +f 419/483/436 412/476/437 418/482/438
            +f 418/482/438 412/476/437 413/477/439
            +f 418/482/438 413/477/439 417/481/440
            +f 417/481/440 413/477/439 414/478/441
            +f 417/481/440 414/478/441 416/480/442
            +f 416/480/442 414/478/441 415/479/443
            +f 502/566/444 504/568/445 503/567/446
            +f 444/508/447 504/568/445 502/566/444
            +f 444/508/447 502/566/444 445/509/448
            +f 445/509/448 502/566/444 446/510/449
            +f 446/510/449 502/566/444 501/565/450
            +f 446/510/449 501/565/450 447/511/451
            +f 447/511/451 501/565/450 448/512/452
            +f 448/512/452 501/565/450 449/513/453
            +f 449/513/453 501/565/450 500/564/454
            +f 449/513/453 500/564/454 450/514/455
            +f 450/514/455 500/564/454 451/515/456
            +f 451/515/456 500/564/454 499/563/457
            +f 451/515/456 499/563/457 452/516/458
            +f 452/516/458 499/563/457 453/517/459
            +f 453/517/459 499/563/457 498/562/460
            +f 453/517/459 498/562/460 454/518/461
            +f 454/518/461 498/562/460 497/561/462
            +f 454/518/461 497/561/462 455/519/463
            +f 455/519/463 497/561/462 456/520/464
            +f 456/520/464 497/561/462 496/560/465
            +f 456/520/464 496/560/465 457/521/466
            +f 458/522/467 496/560/465 459/523/468
            +f 457/521/466 496/560/465 458/522/467
            +f 459/523/468 496/560/465 495/559/469
            +f 459/523/468 495/559/469 460/524/470
            +f 460/524/470 495/559/469 461/525/471
            +f 461/525/471 495/559/469 494/558/472
            +f 461/525/471 494/558/472 462/526/473
            +f 463/527/474 494/558/472 493/557/475
            +f 462/526/473 494/558/472 463/527/474
            +f 463/527/474 493/557/475 492/556/476
            +f 463/527/474 492/556/476 464/528/477
            +f 464/528/477 492/556/476 491/555/478
            +f 465/529/479 491/555/478 490/554/480
            +f 464/528/477 491/555/478 465/529/479
            +f 466/530/481 490/554/480 489/553/482
            +f 465/529/479 490/554/480 466/530/481
            +f 466/530/481 489/553/482 488/552/483
            +f 466/530/481 488/552/483 467/531/484
            +f 467/531/484 488/552/483 487/551/485
            +f 468/532/486 487/551/485 486/550/487
            +f 467/531/484 487/551/485 468/532/486
            +f 469/533/488 486/550/487 485/549/489
            +f 468/532/486 486/550/487 469/533/488
            +f 469/533/488 485/549/489 470/534/490
            +f 471/535/491 485/549/489 484/548/492
            +f 470/534/490 485/549/489 471/535/491
            +f 471/535/491 484/548/492 483/547/493
            +f 471/535/491 483/547/493 482/546/494
            +f 471/535/491 482/546/494 481/545/495
            +f 472/536/496 481/545/495 480/544/497
            +f 471/535/491 481/545/495 472/536/496
            +f 473/537/498 480/544/497 479/543/499
            +f 472/536/496 480/544/497 473/537/498
            +f 474/538/500 479/543/499 478/542/501
            +f 473/537/498 479/543/499 474/538/500
            +f 474/538/500 478/542/501 475/539/502
            +f 475/539/502 478/542/501 477/541/503
            +f 475/539/502 477/541/503 476/540/504
            +f 505/570/505 506/571/506 535/601/507 534/600/508
            +f 506/571/506 507/572/509 536/602/510 535/601/507
            +f 507/572/509 508/573/511 537/603/512 536/602/510
            +f 508/573/511 509/574/513 538/604/514 537/603/512
            +f 509/574/513 510/575/515 539/605/516 538/604/514
            +f 510/575/515 511/576/517 540/606/518 539/605/516
            +f 511/576/517 512/577/519 541/607/520 540/606/518
            +f 512/577/519 513/578/521 542/608/522 541/607/520
            +f 513/578/521 514/579/523 543/609/524 542/608/522
            +f 514/579/523 515/580/525 544/610/526 543/609/524
            +f 515/580/525 516/581/527 545/611/528 544/610/526
            +f 516/581/527 517/582/529 546/612/530 545/611/528
            +f 517/582/529 518/583/531 547/613/532 546/612/530
            +f 518/583/531 519/584/533 548/614/534 547/613/532
            +f 519/584/533 520/585/535 549/615/536 548/614/534
            +f 520/585/535 521/586/537 550/616/538 549/615/536
            +f 521/586/537 522/587/539 551/617/540 550/616/538
            +f 522/587/539 523/588/541 552/618/542 551/617/540
            +f 523/588/541 524/589/543 553/619/544 552/618/542
            +f 524/589/543 525/590/545 554/620/546 553/619/544
            +f 525/590/545 526/591/547 555/621/548 554/620/546
            +f 526/591/547 527/592/549 556/622/550 555/621/548
            +f 527/592/549 528/593/551 557/623/552 556/622/550
            +f 528/593/551 529/594/553 558/624/554 557/623/552
            +f 529/594/553 530/595/555 559/625/556 558/624/554
            +f 530/595/555 531/596/557 560/626/558 559/625/556
            +f 531/596/557 532/597/559 561/627/560 560/626/558
            +f 532/597/559 533/598/561 562/628/562 561/627/560
            +f 533/598/561 505/569/505 534/599/508 562/628/562
            +f 534/600/508 535/601/507 564/631/563 563/630/564
            +f 535/601/507 536/602/510 565/632/565 564/631/563
            +f 536/602/510 537/603/512 566/633/566 565/632/565
            +f 537/603/512 538/604/514 567/634/567 566/633/566
            +f 538/604/514 539/605/516 568/635/568 567/634/567
            +f 539/605/516 540/606/518 569/636/569 568/635/568
            +f 540/606/518 541/607/520 570/637/570 569/636/569
            +f 541/607/520 542/608/522 571/638/571 570/637/570
            +f 542/608/522 543/609/524 572/639/572 571/638/571
            +f 543/609/524 544/610/526 573/640/573 572/639/572
            +f 544/610/526 545/611/528 574/641/574 573/640/573
            +f 545/611/528 546/612/530 575/642/575 574/641/574
            +f 546/612/530 547/613/532 576/643/576 575/642/575
            +f 547/613/532 548/614/534 577/644/577 576/643/576
            +f 548/614/534 549/615/536 578/645/578 577/644/577
            +f 549/615/536 550/616/538 579/646/579 578/645/578
            +f 550/616/538 551/617/540 580/647/580 579/646/579
            +f 551/617/540 552/618/542 581/648/581 580/647/580
            +f 552/618/542 553/619/544 582/649/582 581/648/581
            +f 553/619/544 554/620/546 583/650/583 582/649/582
            +f 554/620/546 555/621/548 584/651/584 583/650/583
            +f 555/621/548 556/622/550 585/652/585 584/651/584
            +f 556/622/550 557/623/552 586/653/586 585/652/585
            +f 557/623/552 558/624/554 587/654/587 586/653/586
            +f 558/624/554 559/625/556 588/655/588 587/654/587
            +f 559/625/556 560/626/558 589/656/589 588/655/588
            +f 560/626/558 561/627/560 590/657/590 589/656/589
            +f 561/627/560 562/628/562 591/658/591 590/657/590
            +f 562/628/562 534/599/508 563/629/564 591/658/591
            +f 563/630/564 564/631/563 593/661/592 592/660/593
            +f 564/631/563 565/632/565 594/662/594 593/661/592
            +f 565/632/565 566/633/566 595/663/595 594/662/594
            +f 566/633/566 567/634/567 596/664/596 595/663/595
            +f 567/634/567 568/635/568 597/665/597 596/664/596
            +f 568/635/568 569/636/569 598/666/598 597/665/597
            +f 569/636/569 570/637/570 599/667/599 598/666/598
            +f 570/637/570 571/638/571 600/668/600 599/667/599
            +f 571/638/571 572/639/572 601/669/601 600/668/600
            +f 572/639/572 573/640/573 602/670/602 601/669/601
            +f 573/640/573 574/641/574 603/671/603 602/670/602
            +f 574/641/574 575/642/575 604/672/604 603/671/603
            +f 575/642/575 576/643/576 605/673/605 604/672/604
            +f 576/643/576 577/644/577 606/674/606 605/673/605
            +f 577/644/577 578/645/578 607/675/607 606/674/606
            +f 578/645/578 579/646/579 608/676/608 607/675/607
            +f 579/646/579 580/647/580 609/677/609 608/676/608
            +f 580/647/580 581/648/581 610/678/610 609/677/609
            +f 581/648/581 582/649/582 611/679/611 610/678/610
            +f 582/649/582 583/650/583 612/680/612 611/679/611
            +f 583/650/583 584/651/584 613/681/613 612/680/612
            +f 584/651/584 585/652/585 614/682/614 613/681/613
            +f 585/652/585 586/653/586 615/683/615 614/682/614
            +f 586/653/586 587/654/587 616/684/616 615/683/615
            +f 587/654/587 588/655/588 617/685/617 616/684/616
            +f 588/655/588 589/656/589 618/686/618 617/685/617
            +f 589/656/589 590/657/590 619/687/619 618/686/618
            +f 590/657/590 591/658/591 620/688/620 619/687/619
            +f 591/658/591 563/629/564 592/659/593 620/688/620
            +f 592/660/593 593/661/592 622/691/621 621/690/622
            +f 593/661/592 594/662/594 623/692/623 622/691/621
            +f 594/662/594 595/663/595 624/693/624 623/692/623
            +f 595/663/595 596/664/596 625/694/625 624/693/624
            +f 596/664/596 597/665/597 626/695/626 625/694/625
            +f 597/665/597 598/666/598 627/696/627 626/695/626
            +f 598/666/598 599/667/599 628/697/628 627/696/627
            +f 599/667/599 600/668/600 629/698/629 628/697/628
            +f 600/668/600 601/669/601 630/699/630 629/698/629
            +f 601/669/601 602/670/602 631/700/631 630/699/630
            +f 602/670/602 603/671/603 632/701/632 631/700/631
            +f 603/671/603 604/672/604 633/702/633 632/701/632
            +f 604/672/604 605/673/605 634/703/634 633/702/633
            +f 605/673/605 606/674/606 635/704/635 634/703/634
            +f 606/674/606 607/675/607 636/705/636 635/704/635
            +f 607/675/607 608/676/608 637/706/637 636/705/636
            +f 608/676/608 609/677/609 638/707/638 637/706/637
            +f 609/677/609 610/678/610 639/708/639 638/707/638
            +f 610/678/610 611/679/611 640/709/640 639/708/639
            +f 611/679/611 612/680/612 641/710/641 640/709/640
            +f 612/680/612 613/681/613 642/711/642 641/710/641
            +f 613/681/613 614/682/614 643/712/643 642/711/642
            +f 614/682/614 615/683/615 644/713/644 643/712/643
            +f 615/683/615 616/684/616 645/714/645 644/713/644
            +f 616/684/616 617/685/617 646/715/646 645/714/645
            +f 617/685/617 618/686/618 647/716/647 646/715/646
            +f 618/686/618 619/687/619 648/717/648 647/716/647
            +f 619/687/619 620/688/620 649/718/649 648/717/648
            +f 620/688/620 592/659/593 621/689/622 649/718/649
            +f 621/690/622 622/691/621 651/721/650 650/720/651
            +f 622/691/621 623/692/623 652/722/652 651/721/650
            +f 623/692/623 624/693/624 653/723/653 652/722/652
            +f 624/693/624 625/694/625 654/724/654 653/723/653
            +f 625/694/625 626/695/626 655/725/655 654/724/654
            +f 626/695/626 627/696/627 656/726/656 655/725/655
            +f 627/696/627 628/697/628 657/727/657 656/726/656
            +f 628/697/628 629/698/629 658/728/658 657/727/657
            +f 629/698/629 630/699/630 659/729/659 658/728/658
            +f 630/699/630 631/700/631 660/730/660 659/729/659
            +f 631/700/631 632/701/632 661/731/661 660/730/660
            +f 632/701/632 633/702/633 662/732/662 661/731/661
            +f 633/702/633 634/703/634 663/733/663 662/732/662
            +f 634/703/634 635/704/635 664/734/664 663/733/663
            +f 635/704/635 636/705/636 665/735/665 664/734/664
            +f 636/705/636 637/706/637 666/736/666 665/735/665
            +f 637/706/637 638/707/638 667/737/667 666/736/666
            +f 638/707/638 639/708/639 668/738/668 667/737/667
            +f 639/708/639 640/709/640 669/739/669 668/738/668
            +f 640/709/640 641/710/641 670/740/670 669/739/669
            +f 641/710/641 642/711/642 671/741/671 670/740/670
            +f 642/711/642 643/712/643 672/742/672 671/741/671
            +f 643/712/643 644/713/644 673/743/673 672/742/672
            +f 644/713/644 645/714/645 674/744/674 673/743/673
            +f 645/714/645 646/715/646 675/745/675 674/744/674
            +f 646/715/646 647/716/647 676/746/676 675/745/675
            +f 647/716/647 648/717/648 677/747/677 676/746/676
            +f 648/717/648 649/718/649 678/748/678 677/747/677
            +f 649/718/649 621/689/622 650/719/651 678/748/678
            +f 650/720/651 651/721/650 680/751/679 679/750/680
            +f 651/721/650 652/722/652 681/752/681 680/751/679
            +f 652/722/652 653/723/653 682/753/682 681/752/681
            +f 653/723/653 654/724/654 683/754/683 682/753/682
            +f 654/724/654 655/725/655 684/755/684 683/754/683
            +f 655/725/655 656/726/656 685/756/685 684/755/684
            +f 656/726/656 657/727/657 686/757/686 685/756/685
            +f 657/727/657 658/728/658 687/758/687 686/757/686
            +f 658/728/658 659/729/659 688/759/688 687/758/687
            +f 659/729/659 660/730/660 689/760/689 688/759/688
            +f 660/730/660 661/731/661 690/761/690 689/760/689
            +f 661/731/661 662/732/662 691/762/691 690/761/690
            +f 662/732/662 663/733/663 692/763/692 691/762/691
            +f 663/733/663 664/734/664 693/764/693 692/763/692
            +f 664/734/664 665/735/665 694/765/694 693/764/693
            +f 665/735/665 666/736/666 695/766/695 694/765/694
            +f 666/736/666 667/737/667 696/767/696 695/766/695
            +f 667/737/667 668/738/668 697/768/697 696/767/696
            +f 668/738/668 669/739/669 698/769/698 697/768/697
            +f 669/739/669 670/740/670 699/770/699 698/769/698
            +f 670/740/670 671/741/671 700/771/700 699/770/699
            +f 671/741/671 672/742/672 701/772/701 700/771/700
            +f 672/742/672 673/743/673 702/773/702 701/772/701
            +f 673/743/673 674/744/674 703/774/703 702/773/702
            +f 674/744/674 675/745/675 704/775/704 703/774/703
            +f 675/745/675 676/746/676 705/776/705 704/775/704
            +f 676/746/676 677/747/677 706/777/706 705/776/705
            +f 677/747/677 678/748/678 707/778/707 706/777/706
            +f 678/748/678 650/719/651 679/749/680 707/778/707
            +f 679/750/680 680/751/679 709/781/708 708/780/709
            +f 680/751/679 681/752/681 710/782/710 709/781/708
            +f 681/752/681 682/753/682 711/783/711 710/782/710
            +f 682/753/682 683/754/683 712/784/712 711/783/711
            +f 683/754/683 684/755/684 713/785/713 712/784/712
            +f 684/755/684 685/756/685 714/786/714 713/785/713
            +f 685/756/685 686/757/686 715/787/715 714/786/714
            +f 686/757/686 687/758/687 716/788/716 715/787/715
            +f 687/758/687 688/759/688 717/789/717 716/788/716
            +f 688/759/688 689/760/689 718/790/718 717/789/717
            +f 689/760/689 690/761/690 719/791/719 718/790/718
            +f 690/761/690 691/762/691 720/792/720 719/791/719
            +f 691/762/691 692/763/692 721/793/721 720/792/720
            +f 692/763/692 693/764/693 722/794/722 721/793/721
            +f 693/764/693 694/765/694 723/795/723 722/794/722
            +f 694/765/694 695/766/695 724/796/724 723/795/723
            +f 695/766/695 696/767/696 725/797/725 724/796/724
            +f 696/767/696 697/768/697 726/798/726 725/797/725
            +f 697/768/697 698/769/698 727/799/727 726/798/726
            +f 698/769/698 699/770/699 728/800/728 727/799/727
            +f 699/770/699 700/771/700 729/801/729 728/800/728
            +f 700/771/700 701/772/701 730/802/730 729/801/729
            +f 701/772/701 702/773/702 731/803/731 730/802/730
            +f 702/773/702 703/774/703 732/804/732 731/803/731
            +f 703/774/703 704/775/704 733/805/733 732/804/732
            +f 704/775/704 705/776/705 734/806/734 733/805/733
            +f 705/776/705 706/777/706 735/807/735 734/806/734
            +f 706/777/706 707/778/707 736/808/736 735/807/735
            +f 707/778/707 679/749/680 708/779/709 736/808/736
            +f 740/812/737 737/809/738 738/810/739
            +f 741/813/740 737/809/738 740/812/737
            +f 744/816/741 737/809/738 741/813/740
            +f 759/831/742 737/809/738 744/816/741
            +f 762/834/743 737/809/738 759/831/742
            +f 763/835/744 737/809/738 762/834/743
            +f 765/837/745 737/809/738 763/835/744
            +f 740/812/737 738/810/739 739/811/746
            +f 744/816/741 741/813/740 742/814/747
            +f 744/816/741 742/814/747 743/815/748
            +f 751/823/749 744/816/741 745/817/750
            +f 759/831/742 744/816/741 751/823/749
            +f 747/819/751 745/817/750 746/818/752
            +f 748/820/753 745/817/750 747/819/751
            +f 751/823/749 745/817/750 748/820/753
            +f 751/823/749 748/820/753 749/821/754
            +f 751/823/749 749/821/754 750/822/755
            +f 759/831/742 751/823/749 752/824/756
            +f 754/826/757 752/824/756 753/825/758
            +f 755/827/759 752/824/756 754/826/757
            +f 758/830/760 752/824/756 755/827/759
            +f 759/831/742 752/824/756 758/830/760
            +f 758/830/760 755/827/759 756/828/761
            +f 758/830/760 756/828/761 757/829/762
            +f 761/833/763 759/831/742 760/832/764
            +f 762/834/743 759/831/742 761/833/763
            +f 765/837/745 763/835/744 764/836/765
            +f 769/841/766 766/838/767 767/839/768
            +f 770/842/769 766/838/767 769/841/766
            +f 773/845/770 766/838/767 770/842/769
            +f 788/860/771 766/838/767 773/845/770
            +f 791/863/772 766/838/767 788/860/771
            +f 792/864/773 766/838/767 791/863/772
            +f 794/866/774 766/838/767 792/864/773
            +f 769/841/766 767/839/768 768/840/775
            +f 773/845/770 770/842/769 771/843/776
            +f 773/845/770 771/843/776 772/844/777
            +f 780/852/778 773/845/770 774/846/779
            +f 781/853/780 773/845/770 780/852/778
            +f 788/860/771 773/845/770 781/853/780
            +f 776/848/781 774/846/779 775/847/782
            +f 777/849/783 774/846/779 776/848/781
            +f 780/852/778 774/846/779 777/849/783
            +f 780/852/778 777/849/783 778/850/784
            +f 780/852/778 778/850/784 779/851/785
            +f 783/855/786 781/853/780 782/854/787
            +f 784/856/788 781/853/780 783/855/786
            +f 787/859/789 781/853/780 784/856/788
            +f 788/860/771 781/853/780 787/859/789
            +f 787/859/789 784/856/788 785/857/790
            +f 787/859/789 785/857/790 786/858/791
            +f 790/862/792 788/860/771 789/861/793
            +f 791/863/772 788/860/771 790/862/792
            +f 794/866/774 792/864/773 793/865/794
            diff --git a/dist/assets/p5_featured/matthew_kaney_teatime/sketch.js b/dist/assets/p5_featured/matthew_kaney_teatime/sketch.js
            new file mode 100644
            index 0000000000..909262f6ff
            --- /dev/null
            +++ b/dist/assets/p5_featured/matthew_kaney_teatime/sketch.js
            @@ -0,0 +1,106 @@
            +var teapot1;
            +var teapot2;
            +var cup;
            +
            +var teapotLayers = [];
            +
            +var lastPosition;
            +var stillCount;
            +
            +var colorWidth = 40;
            +var colorOffset = 0;
            +
            +function setup(){
            +  createCanvas(windowWidth, windowHeight, WEBGL);
            +  
            +  lastPosition = new p5.Vector(mouseX, mouseY);
            +  
            +  teapot1 = loadModel('teapot.obj');
            +  teapot2 = loadModel('crockery_pot.obj');
            +  cup = loadModel('koffie.obj');
            +  
            +  directionalLight(125, 125, 125, -1, 1, 0.5);
            +  ambientLight(125);
            +  
            +  colorMode(HSB, 255);
            +}
            +
            +function draw(){
            +  if(dist(lastPosition.x, lastPosition.y, mouseX, mouseY) > 0) {
            +    stillCount = 0;
            +    colorOffset = floor(random(255));
            +  } else {
            +    if(stillCount >= 10) {
            +      if((stillCount - 10) % 60 == 0) {
            +        var newWidth = width / height * 900 * 0.5;
            +        var newX = map(mouseX, 0, width, -newWidth, newWidth);
            +        var newY = map(mouseY, 0, height, -450, 450);
            +        
            +        var layer = {};
            +        layer.center = new p5.Vector(newX, newY);
            +        layer.startFrame = frameCount;
            +        layer.axis = (random(1) < 0.5) ? 'x' : 'y';
            +        layer.rotation = random(0.1);
            +        layer.orbit = random(0.05) - 0.025;
            +        layer.number = floor(random(5, 30));
            +        layer.color = color((floor(random(colorWidth)) + colorOffset) % 255, 255, 255);
            +        layer.direction = floor(random(2));
            +        
            +        layer.model = (random(1) < 0.35) ? teapot1 : (random(1) < 0.5) ? cup : teapot2;
            +        
            +        teapotLayers.push(layer);
            +      }
            +    }
            +    
            +    stillCount++;
            +  }
            +  
            +  lastPosition = new p5.Vector(mouseX, mouseY);
            +  
            +  for(var i = 0; i < teapotLayers.length; ++i) {
            +    var frameOffset = frameCount - teapotLayers[i].startFrame;
            +    var radius = frameOffset;
            +    var cx = teapotLayers[i].center.x;
            +    var cy = teapotLayers[i].center.y;
            +    
            +    specularMaterial(teapotLayers[i].color);
            +    
            +    var modelScale = constrain(frameOffset / 2, 0, 50);
            +    if(frameOffset > 300) {
            +      modelScale = map(frameOffset, 300, 350, 50, 0);
            +      
            +      if(frameOffset >= 350) {
            +        teapotLayers[i].cull = true;
            +      }
            +    }
            +    
            +    for(var j = 0; j < teapotLayers[i].number; ++j) {
            +      var angle = j * PI * 2 / teapotLayers[i].number + teapotLayers[i].orbit * frameOffset;
            +      
            +      push();
            +      
            +      translate(cos(angle) * radius + cx, -sin(angle) * radius + cy, -frameOffset * 0.2);
            +      rotateZ(angle + PI * teapotLayers[i].direction);
            +      
            +      if(teapotLayers[i].axis == 'x') {
            +        rotateX(teapotLayers[i].rotation * frameOffset);
            +      } else {
            +        rotateY(teapotLayers[i].rotation * frameOffset);
            +      }
            +      
            +      scale(modelScale);
            +      model(teapotLayers[i].model);
            +      
            +      pop();
            +    }
            +  }
            +  
            +  if(teapotLayers.length > 0 && teapotLayers[0].cull) {
            +    teapotLayers.shift();
            +  }
            +}
            +
            +function windowResized() {
            +  resizeCanvas(windowWidth, windowHeight);
            +  perspective(60 / 180 * PI, width/height, 0.1, 100);
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/matthew_kaney_teatime/teapot.obj b/dist/assets/p5_featured/matthew_kaney_teatime/teapot.obj
            new file mode 100644
            index 0000000000..6fed4538c6
            --- /dev/null
            +++ b/dist/assets/p5_featured/matthew_kaney_teatime/teapot.obj
            @@ -0,0 +1,5049 @@
            +# Blender v2.65 (sub 0) OBJ File
            +# www.blender.org
            +o teapot.005
            +v -0.498530 0.712498 -0.039883
            +v -0.501666 0.699221 -0.063813
            +v -0.501255 0.717792 0.000000
            +v -0.624036 0.711938 -0.039883
            +v -0.526706 0.651362 -0.039883
            +v -0.508714 0.682112 -0.071712
            +v -0.622039 0.698704 -0.063813
            +v -0.624834 0.717232 0.000000
            +v -0.498530 0.712498 0.039883
            +v -0.638129 0.287158 0.000000
            +v -0.517593 0.664661 -0.063813
            +v -0.534329 0.646030 0.000000
            +v -0.614850 0.651067 -0.039883
            +v -0.616848 0.664299 -0.063813
            +v -0.619445 0.681503 -0.071790
            +v -0.741245 0.707456 -0.039883
            +v -0.744483 0.712577 0.000000
            +v -0.624036 0.711938 0.039883
            +v -0.501667 0.699221 0.063813
            +v -0.622039 0.698704 0.063813
            +v -0.712095 0.661370 -0.063813
            +v -0.733150 0.694655 -0.063813
            +v -0.741245 0.707456 0.039883
            +v -0.733150 0.694655 0.063813
            +v -0.631184 0.277569 -0.039883
            +v -0.526706 0.651362 0.039883
            +v -0.614053 0.645774 0.000000
            +v -0.704000 0.648569 -0.039883
            +v -0.722621 0.678012 -0.071790
            +v -0.832523 0.695296 -0.039883
            +v -0.837545 0.699948 0.000000
            +v -0.832523 0.695296 0.039883
            +v -0.619445 0.681503 0.071790
            +v -0.508714 0.682112 0.071712
            +v -0.722621 0.678012 0.071790
            +v -0.517593 0.664661 0.063813
            +v -0.619922 0.238069 -0.071790
            +v -0.624826 0.259599 -0.063813
            +v -0.710066 0.328372 0.000000
            +v -0.614850 0.651067 0.039883
            +v -0.787321 0.653419 -0.063813
            +v -0.803644 0.668539 -0.071790
            +v -0.819967 0.683663 -0.063813
            +v -0.819967 0.683663 0.063813
            +v -0.803644 0.668539 0.071790
            +v -0.711425 0.307332 -0.063813
            +v -0.615553 0.216807 -0.063813
            +v -0.712688 0.287795 -0.071790
            +v -0.631184 0.277569 0.039883
            +v -0.710455 0.322361 -0.039883
            +v -0.710455 0.322361 0.039883
            +v -0.700762 0.643448 0.000000
            +v -0.774766 0.641786 -0.039883
            +v -0.897800 0.671612 -0.039883
            +v -0.904015 0.675354 0.000000
            +v -0.897800 0.671612 0.039883
            +v -0.882265 0.662257 0.063813
            +v -0.712095 0.661370 0.063813
            +v -0.787321 0.653419 0.063813
            +v -0.608884 0.198682 -0.039883
            +v -0.624828 0.259599 0.063813
            +v -0.766936 0.377559 0.000000
            +v -0.769651 0.372307 0.039883
            +v -0.616848 0.664299 0.063813
            +v -0.704000 0.648569 0.039883
            +v -0.841868 0.637931 -0.063813
            +v -0.862065 0.650094 -0.071790
            +v -0.882265 0.662257 -0.063813
            +v -0.862065 0.650094 0.071790
            +v -0.841868 0.637931 0.063813
            +v -0.611709 0.194244 0.000000
            +v -0.776434 0.359177 -0.063813
            +v -0.769651 0.372307 -0.039883
            +v -0.713952 0.268259 -0.063813
            +v -0.711425 0.307332 0.063813
            +v -0.776434 0.359177 0.063813
            +v -0.769743 0.637131 0.000000
            +v -0.826329 0.628576 -0.039883
            +v -0.937016 0.632565 -0.039883
            +v -0.943899 0.634805 0.000000
            +v -0.937016 0.632565 0.039883
            +v -0.919812 0.626965 0.063813
            +v -0.897443 0.619684 0.071790
            +v -0.774766 0.641786 0.039883
            +v -0.826329 0.628576 0.039883
            +v -0.714922 0.253231 -0.039883
            +v -0.608883 0.198681 0.039883
            +v -0.715311 0.247220 0.000000
            +v -0.785253 0.342107 -0.071790
            +v -0.619922 0.238069 0.071790
            +v -0.712688 0.287795 0.071790
            +v -0.809626 0.430737 0.000000
            +v -0.814205 0.426194 0.039883
            +v -0.825653 0.414838 0.063813
            +v -0.875076 0.612403 -0.063813
            +v -0.897443 0.619684 -0.071790
            +v -0.919812 0.626965 -0.063813
            +v -0.875076 0.612403 0.063813
            +v -0.857869 0.606800 0.039883
            +v -0.794072 0.325038 -0.063813
            +v -0.800855 0.311909 -0.039883
            +v -0.825653 0.414838 -0.063813
            +v -0.814205 0.426194 -0.039883
            +v -0.615480 0.216617 0.063578
            +v -0.785253 0.342107 0.071790
            +v -0.840534 0.400078 0.071790
            +v -0.820114 0.624834 0.000000
            +v -0.857869 0.606800 -0.039883
            +v -0.950104 0.574316 -0.039883
            +v -0.957194 0.574316 0.000000
            +v -0.950104 0.574316 0.039883
            +v -0.932377 0.574316 0.063813
            +v -0.909334 0.574316 0.071790
            +v -0.886292 0.574316 0.063813
            +v -0.850987 0.604560 0.000000
            +v -0.714922 0.253231 0.039883
            +v -0.803571 0.306656 0.000000
            +v -0.840534 0.400078 -0.071790
            +v -0.713952 0.268259 0.063813
            +v -0.794072 0.325038 0.063813
            +v -0.839022 0.483916 0.000000
            +v -0.844976 0.480304 0.039883
            +v -0.859854 0.471278 0.063813
            +v -0.879202 0.459542 0.071790
            +v -0.886292 0.574316 -0.063813
            +v -0.909334 0.574316 -0.071790
            +v -0.932377 0.574316 -0.063813
            +v -0.868564 0.574316 0.039883
            +v -0.861474 0.574316 0.000000
            +v -0.855419 0.385315 -0.063813
            +v -0.866867 0.373960 -0.039883
            +v -0.859854 0.471278 -0.063813
            +v -0.844976 0.480304 -0.039883
            +v -0.855419 0.385315 0.063813
            +v -0.898547 0.447807 0.063813
            +v -0.868564 0.574316 -0.039883
            +v -0.941014 0.505765 -0.039883
            +v -0.947813 0.503580 0.000000
            +v -0.941014 0.505765 0.039883
            +v -0.924011 0.511234 0.063813
            +v -0.901913 0.518343 0.071790
            +v -0.879811 0.525448 0.063813
            +v -0.862808 0.530917 0.039883
            +v -0.800855 0.311909 0.039883
            +v -0.871445 0.369416 0.000000
            +v -0.879202 0.459542 -0.071790
            +v -0.866867 0.373960 0.039883
            +v -0.856009 0.533103 0.000000
            +v -0.879811 0.525448 -0.063813
            +v -0.901913 0.518343 -0.071790
            +v -0.924011 0.511234 -0.063813
            +v -0.862808 0.530917 -0.039883
            +v -0.898547 0.447807 -0.063813
            +v -0.913428 0.438781 -0.039883
            +v -0.913428 0.438781 0.039883
            +v -0.919378 0.435169 0.000000
            +v 0.600960 0.444810 0.085753
            +v 0.605956 0.463769 0.000000
            +v 0.600959 0.444810 -0.085753
            +v 0.656890 0.471064 0.000000
            +v 0.661223 0.454734 -0.083705
            +v 0.730696 0.501576 -0.073611
            +v 0.661223 0.454734 0.083705
            +v 0.605101 0.399712 -0.137265
            +v 0.746455 0.470391 -0.117778
            +v 0.724395 0.514048 0.000000
            +v 0.605100 0.399712 0.137265
            +v 0.672055 0.413907 -0.133928
            +v 0.613258 0.341675 -0.154354
            +v 0.786583 0.544847 -0.096783
            +v 0.768856 0.565896 -0.060489
            +v 0.672055 0.413907 0.133928
            +v 0.730696 0.501576 0.073611
            +v 0.686135 0.360830 -0.150669
            +v 0.809626 0.517481 -0.108881
            +v 0.766935 0.429850 -0.132501
            +v 0.761767 0.574316 0.000000
            +v 0.613258 0.341675 0.154354
            +v 0.813417 0.626247 -0.075788
            +v 0.839021 0.611098 -0.085261
            +v 0.793721 0.637899 -0.047367
            +v 0.686135 0.360830 0.150669
            +v 0.768856 0.565896 0.060489
            +v 0.746455 0.470391 0.117778
            +v 0.619427 0.283145 -0.137236
            +v 0.864627 0.595949 -0.075788
            +v 0.832669 0.490118 -0.096783
            +v 0.787419 0.389310 -0.117778
            +v 0.785843 0.642561 0.000000
            +v 0.619427 0.283145 0.137236
            +v 0.700219 0.307756 -0.133928
            +v 0.847933 0.703560 -0.059638
            +v 0.879938 0.698065 -0.067092
            +v 0.911944 0.692571 -0.059638
            +v 0.823314 0.707784 -0.037273
            +v 0.766935 0.429850 0.132501
            +v 0.793721 0.637899 0.047367
            +v 0.786583 0.544847 0.096783
            +v 0.700219 0.307756 0.133928
            +v 0.617684 0.235930 -0.085941
            +v 0.936563 0.688344 -0.037273
            +v 0.884319 0.584297 -0.047367
            +v 0.850396 0.469070 -0.060489
            +v 0.803175 0.358128 -0.073611
            +v 0.813468 0.709475 0.000000
            +v 0.617684 0.235930 0.085941
            +v 0.625577 0.219883 0.000000
            +v 0.711051 0.266929 -0.083705
            +v 0.911107 0.765755 -0.053178
            +v 0.957193 0.765755 -0.059825
            +v 1.003279 0.765755 -0.053178
            +v 1.038733 0.765755 -0.033236
            +v 0.875654 0.765755 -0.033236
            +v 0.809626 0.517481 0.108881
            +v 0.787419 0.389310 0.117778
            +v 0.823314 0.707784 0.037273
            +v 0.813417 0.626247 0.075788
            +v 0.711051 0.266929 0.083705
            +v 0.715384 0.250599 0.000000
            +v 1.052913 0.765755 0.000000
            +v 0.946409 0.686653 0.000000
            +v 0.892200 0.579635 0.000000
            +v 0.857486 0.460650 0.000000
            +v 0.809479 0.345652 0.000000
            +v 0.861474 0.765755 0.000000
            +v 0.929990 0.776479 -0.051602
            +v 0.979075 0.777181 -0.058052
            +v 1.028157 0.777879 -0.051602
            +v 1.065915 0.778419 -0.032251
            +v 1.081016 0.778632 0.000000
            +v 0.892235 0.775943 -0.032251
            +v 0.839021 0.611098 0.085261
            +v 0.832669 0.490118 0.096783
            +v 0.803175 0.358128 0.073611
            +v 0.875654 0.765755 0.033236
            +v 0.847933 0.703560 0.059638
            +v 1.065915 0.778419 0.032174
            +v 1.038733 0.765755 0.033236
            +v 0.936563 0.688344 0.037273
            +v 0.884319 0.584297 0.047367
            +v 0.850396 0.469070 0.060489
            +v 0.877131 0.775726 0.000000
            +v 0.943713 0.783087 -0.047663
            +v 0.992645 0.784366 -0.053621
            +v 1.041577 0.785649 -0.047663
            +v 1.079216 0.786631 -0.029789
            +v 1.094273 0.787027 0.000000
            +v 1.079216 0.786631 0.029174
            +v 0.906073 0.782101 -0.029789
            +v 0.879938 0.698065 0.067092
            +v 0.864627 0.595949 0.075788
            +v 0.892235 0.775943 0.032236
            +v 0.911107 0.765755 0.053178
            +v 1.041577 0.785649 0.046875
            +v 1.028157 0.777879 0.051503
            +v 1.003279 0.765755 0.053178
            +v 0.911944 0.692571 0.059638
            +v 0.891016 0.781708 0.000000
            +v 0.951249 0.785448 -0.042542
            +v 0.997575 0.787068 -0.047860
            +v 1.043903 0.788686 -0.042542
            +v 1.079539 0.789934 -0.026589
            +v 1.093795 0.790431 0.000000
            +v 1.079539 0.789934 0.024511
            +v 1.043903 0.788686 0.039883
            +v 0.915613 0.784200 -0.026589
            +v 0.957193 0.765755 0.059825
            +v 0.906073 0.782101 0.029666
            +v 0.929990 0.776479 0.051553
            +v 0.997575 0.787068 0.045616
            +v 0.992645 0.784366 0.052956
            +v 0.979075 0.777181 0.057969
            +v 0.901357 0.783702 0.000000
            +v 0.951569 0.783431 -0.037421
            +v 0.993532 0.785033 -0.042099
            +v 1.035492 0.786631 -0.037421
            +v 1.067772 0.787863 -0.023388
            +v 1.080684 0.788354 0.000000
            +v 1.067772 0.787863 0.018464
            +v 1.035492 0.786631 0.031119
            +v 0.993532 0.785033 0.036781
            +v 0.919292 0.782200 -0.023388
            +v 0.915613 0.784200 0.026173
            +v 0.943713 0.783087 0.047269
            +v 0.951569 0.783431 0.034270
            +v 0.951249 0.785448 0.041213
            +v 0.906379 0.781708 0.000000
            +v 0.943653 0.776909 -0.033482
            +v 0.980182 0.778010 -0.037667
            +v 1.016712 0.779111 -0.033482
            +v 1.044812 0.779957 -0.020926
            +v 1.056052 0.780295 0.000000
            +v 1.044812 0.779957 0.011310
            +v 1.016712 0.779111 0.021172
            +v 0.980182 0.778010 0.027281
            +v 0.943653 0.776909 0.027327
            +v 0.915553 0.776064 -0.020926
            +v 0.919292 0.782200 0.022403
            +v 0.915553 0.776064 0.019003
            +v 0.904312 0.775726 0.000000
            +v 0.926468 0.765755 -0.031906
            +v 0.957193 0.765755 -0.035895
            +v 0.987920 0.765755 -0.031906
            +v 1.011552 0.765755 -0.019942
            +v 1.021006 0.765755 0.000000
            +v 1.011552 0.765755 0.003324
            +v 0.987920 0.765755 0.010635
            +v 0.957193 0.765755 0.017947
            +v 0.926468 0.765755 0.021271
            +v 0.902834 0.765755 0.016618
            +v 0.902834 0.765755 -0.019942
            +v 0.893380 0.765755 0.000000
            +v 0.886428 0.750924 -0.019014
            +v 0.908324 0.750924 -0.030099
            +v 0.936793 0.750924 -0.033795
            +v 0.965261 0.750924 -0.030099
            +v 0.987158 0.750924 -0.019014
            +v 0.995918 0.750924 -0.000537
            +v 0.987158 0.750924 0.002542
            +v 0.965261 0.750924 0.009317
            +v 0.936793 0.750924 0.016092
            +v 0.908324 0.750924 0.019171
            +v 0.886428 0.750924 0.014860
            +v 0.877668 0.750924 -0.000537
            +v 0.936793 0.750924 -0.007312
            +v 0.440746 0.783205 0.000000
            +v 0.446690 0.765755 0.000000
            +v 0.430973 0.765755 0.119945
            +v 0.425236 0.783205 0.118348
            +v 0.425236 0.783205 -0.118348
            +v 0.453011 0.750009 0.000000
            +v 0.437073 0.750009 0.121642
            +v 0.441668 0.793673 0.000000
            +v 0.386470 0.765755 0.226985
            +v 0.430973 0.765755 -0.119945
            +v 0.426127 0.793673 -0.118596
            +v 0.437073 0.750009 -0.121642
            +v 0.426127 0.793673 0.118596
            +v 0.381327 0.783205 0.223964
            +v 0.381327 0.783205 -0.223964
            +v 0.382124 0.793673 -0.224433
            +v 0.317150 0.765755 0.317150
            +v 0.391939 0.750009 0.230197
            +v 0.321638 0.750009 0.321639
            +v 0.386470 0.765755 -0.226985
            +v 0.391939 0.750009 -0.230197
            +v 0.447686 0.797164 0.000000
            +v 0.431936 0.797164 -0.120212
            +v 0.387332 0.797164 -0.227491
            +v 0.230197 0.750009 0.391940
            +v 0.226984 0.765755 0.386470
            +v 0.317150 0.765755 -0.317150
            +v 0.321638 0.750009 -0.321639
            +v 0.431936 0.797164 0.120212
            +v 0.382124 0.793673 0.224433
            +v 0.312929 0.783205 0.312929
            +v 0.313584 0.793673 -0.313584
            +v 0.312929 0.783205 -0.312929
            +v 0.317858 0.797164 -0.317858
            +v 0.121642 0.750009 0.437072
            +v 0.119944 0.765755 0.430973
            +v 0.226984 0.765755 -0.386470
            +v 0.230197 0.750009 -0.391940
            +v 0.457031 0.793673 0.000000
            +v 0.440950 0.793673 -0.122721
            +v 0.395416 0.793673 -0.232239
            +v 0.324491 0.793673 -0.324492
            +v -0.000000 0.750009 0.453012
            +v -0.000000 0.765755 0.446690
            +v 0.223963 0.783205 0.381327
            +v 0.223963 0.783205 -0.381327
            +v 0.119944 0.765755 -0.430973
            +v 0.121642 0.750009 -0.437072
            +v 0.440950 0.793673 0.122721
            +v 0.387332 0.797164 0.227491
            +v 0.313584 0.793673 0.313584
            +v 0.227491 0.797164 -0.387332
            +v 0.224433 0.793673 -0.382125
            +v 0.232239 0.793673 -0.395417
            +v -0.119945 0.765755 0.430973
            +v -0.121642 0.750009 0.437072
            +v 0.118348 0.783205 0.425237
            +v 0.118348 0.783205 -0.425237
            +v -0.000000 0.750009 -0.453012
            +v -0.000000 0.765755 -0.446690
            +v 0.467924 0.783205 0.000000
            +v 0.451460 0.783205 -0.125646
            +v 0.404842 0.783205 -0.237775
            +v 0.332226 0.783205 -0.332226
            +v 0.237775 0.783205 -0.404842
            +v -0.226985 0.765755 0.386470
            +v -0.000000 0.783205 0.440746
            +v 0.224433 0.793673 0.382125
            +v 0.118596 0.793673 -0.426127
            +v -0.000000 0.783205 -0.440746
            +v -0.119945 0.765755 -0.430973
            +v -0.121642 0.750009 -0.437072
            +v 0.451460 0.783205 0.125646
            +v 0.395416 0.793673 0.232239
            +v 0.317858 0.797164 0.317858
            +v 0.122721 0.793673 -0.440950
            +v 0.120212 0.797164 -0.431937
            +v 0.125646 0.783205 -0.451460
            +v -0.317150 0.765755 0.317150
            +v -0.230198 0.750009 0.391939
            +v -0.321639 0.750009 0.321639
            +v -0.118348 0.783205 0.425237
            +v 0.118596 0.793673 0.426127
            +v -0.000000 0.793673 -0.441668
            +v -0.118348 0.783205 -0.425237
            +v -0.226985 0.765755 -0.386470
            +v 0.478596 0.765755 0.000000
            +v 0.461756 0.765755 -0.128512
            +v 0.414076 0.765755 -0.243198
            +v 0.339803 0.765755 -0.339804
            +v 0.243198 0.765755 -0.414076
            +v 0.128512 0.765755 -0.461757
            +v -0.391940 0.750009 0.230197
            +v -0.386470 0.765755 0.226985
            +v -0.223964 0.783205 0.381327
            +v -0.000000 0.793673 0.441668
            +v 0.227491 0.797164 0.387332
            +v -0.000000 0.797164 -0.447686
            +v -0.118596 0.793673 -0.426127
            +v -0.223964 0.783205 -0.381327
            +v -0.317150 0.765755 -0.317150
            +v -0.230198 0.750009 -0.391939
            +v -0.321639 0.750009 -0.321639
            +v 0.461756 0.765755 0.128512
            +v 0.404842 0.783205 0.237775
            +v 0.324491 0.793673 0.324492
            +v -0.000000 0.783205 -0.467924
            +v -0.000000 0.793673 -0.457031
            +v -0.000000 0.765755 -0.478597
            +v -0.437073 0.750009 0.121642
            +v -0.430974 0.765755 0.119945
            +v -0.312929 0.783205 0.312929
            +v -0.118596 0.793673 0.426127
            +v 0.120212 0.797164 0.431937
            +v -0.120212 0.797164 -0.431937
            +v -0.224433 0.793673 -0.382125
            +v -0.312929 0.783205 -0.312929
            +v -0.386470 0.765755 -0.226985
            +v -0.391940 0.750009 -0.230197
            +v 0.518110 0.682112 0.000000
            +v 0.499881 0.682112 -0.139122
            +v 0.448260 0.682112 -0.263277
            +v 0.367859 0.682112 -0.367859
            +v 0.263277 0.682112 -0.448260
            +v 0.139122 0.682112 -0.499882
            +v -0.000000 0.682112 -0.518110
            +v -0.453012 0.750009 0.000000
            +v -0.446690 0.765755 0.000000
            +v -0.381327 0.783205 0.223964
            +v -0.224433 0.793673 0.382125
            +v -0.000000 0.797164 0.447686
            +v 0.232239 0.793673 0.395417
            +v -0.122721 0.793673 -0.440950
            +v -0.227491 0.797164 -0.387332
            +v -0.313584 0.793673 -0.313584
            +v -0.381327 0.783205 -0.223964
            +v -0.430974 0.765755 -0.119945
            +v 0.499881 0.682112 0.139122
            +v 0.414076 0.765755 0.243198
            +v 0.332226 0.783205 0.332226
            +v -0.128513 0.765755 -0.461757
            +v -0.125646 0.783205 -0.451460
            +v -0.139123 0.682112 -0.499882
            +v -0.437073 0.750009 -0.121642
            +v -0.425237 0.783205 0.118348
            +v -0.313584 0.793673 0.313584
            +v -0.120212 0.797164 0.431937
            +v 0.122721 0.793673 0.440950
            +v -0.232240 0.793673 -0.395417
            +v -0.317859 0.797164 -0.317858
            +v -0.382125 0.793673 -0.224433
            +v -0.425237 0.783205 -0.118348
            +v 0.555408 0.599133 0.000000
            +v 0.535865 0.599133 -0.149137
            +v 0.480530 0.599133 -0.282230
            +v 0.394341 0.599133 -0.394341
            +v 0.282230 0.599133 -0.480530
            +v 0.149137 0.599133 -0.535866
            +v -0.000000 0.599133 -0.555408
            +v -0.149138 0.599133 -0.535866
            +v -0.440746 0.783205 0.000000
            +v -0.382125 0.793673 0.224433
            +v -0.227491 0.797164 0.387332
            +v -0.000000 0.793673 0.457031
            +v 0.237775 0.783205 0.404842
            +v -0.237775 0.783205 -0.404842
            +v -0.324492 0.793673 -0.324492
            +v -0.387332 0.797164 -0.227491
            +v -0.426127 0.793673 -0.118596
            +v 0.535865 0.599133 0.149137
            +v 0.448260 0.682112 0.263277
            +v 0.339803 0.765755 0.339804
            +v -0.263278 0.682112 -0.448260
            +v -0.243198 0.765755 -0.414076
            +v -0.282230 0.599133 -0.480530
            +v -0.426127 0.793673 0.118596
            +v -0.317859 0.797164 0.317858
            +v -0.122721 0.793673 0.440950
            +v 0.125646 0.783205 0.451460
            +v -0.332226 0.783205 -0.332226
            +v -0.395417 0.793673 -0.232239
            +v -0.431937 0.797164 -0.120212
            +v -0.441668 0.793673 0.000000
            +v 0.588275 0.517481 0.000000
            +v 0.567578 0.517481 -0.157963
            +v 0.508969 0.517485 -0.298931
            +v 0.417675 0.517481 -0.417675
            +v 0.298931 0.517485 -0.508969
            +v 0.157963 0.517485 -0.567578
            +v -0.000000 0.517481 -0.588275
            +v -0.157963 0.517481 -0.567578
            +v -0.298931 0.517485 -0.508969
            +v -0.387332 0.797164 0.227491
            +v -0.232240 0.793673 0.395417
            +v -0.000000 0.783205 0.467924
            +v 0.243198 0.765755 0.414076
            +v -0.339804 0.765755 -0.339804
            +v -0.404842 0.783205 -0.237775
            +v -0.440950 0.793673 -0.122721
            +v -0.447686 0.797164 0.000000
            +v 0.567578 0.517485 0.157963
            +v 0.480530 0.599133 0.282230
            +v 0.367859 0.682112 0.367859
            +v -0.394341 0.599133 -0.394341
            +v -0.367859 0.682112 -0.367859
            +v -0.417675 0.517481 -0.417675
            +v -0.431937 0.797164 0.120212
            +v -0.324492 0.793673 0.324492
            +v -0.125646 0.783205 0.451460
            +v 0.128512 0.765755 0.461757
            +v -0.414076 0.765755 -0.243198
            +v -0.451461 0.783205 -0.125646
            +v -0.457031 0.793673 0.000000
            +v 0.592873 0.437827 -0.165003
            +v 0.531651 0.437827 -0.312254
            +v 0.436292 0.437827 -0.436292
            +v 0.312254 0.437827 -0.531651
            +v 0.165003 0.437827 -0.592873
            +v -0.000000 0.437827 -0.614496
            +v -0.165004 0.437827 -0.592873
            +v -0.312255 0.437827 -0.531651
            +v -0.436292 0.437827 -0.436292
            +v -0.395417 0.793673 0.232239
            +v -0.237775 0.783205 0.404842
            +v -0.000000 0.765755 0.478597
            +v 0.263277 0.682112 0.448260
            +v -0.448260 0.682112 -0.263277
            +v -0.461757 0.765755 -0.128512
            +v -0.467924 0.783205 0.000000
            +v -0.440950 0.793673 0.122721
            +v 0.592873 0.437827 0.165003
            +v 0.508969 0.517485 0.298931
            +v 0.394341 0.599133 0.394341
            +v -0.508969 0.517485 -0.298931
            +v -0.480530 0.599133 -0.282230
            +v -0.531651 0.437827 -0.312254
            +v -0.332226 0.783205 0.332226
            +v -0.128513 0.765755 0.461757
            +v 0.139122 0.682112 0.499882
            +v -0.499882 0.682112 -0.139122
            +v -0.478597 0.765755 0.000000
            +v -0.451461 0.783205 0.125646
            +v 0.546669 0.360830 -0.321075
            +v 0.448614 0.360830 -0.448614
            +v 0.321074 0.360830 -0.546669
            +v 0.169664 0.360830 -0.609621
            +v -0.000000 0.360830 -0.631850
            +v -0.169664 0.360830 -0.609621
            +v -0.321075 0.360830 -0.546669
            +v -0.448615 0.360830 -0.448614
            +v -0.546669 0.360830 -0.321075
            +v -0.404842 0.783205 0.237775
            +v -0.243198 0.765755 0.414076
            +v -0.000000 0.682112 0.518110
            +v 0.282230 0.599133 0.480530
            +v -0.535866 0.599133 -0.149137
            +v -0.461757 0.765755 0.128512
            +v 0.531651 0.437827 0.312254
            +v 0.417675 0.517481 0.417675
            +v 0.609621 0.360830 -0.169664
            +v -0.592873 0.437827 -0.165003
            +v -0.567578 0.517485 -0.157963
            +v -0.609621 0.360830 -0.169664
            +v -0.339804 0.765755 0.339804
            +v -0.139123 0.682112 0.499882
            +v 0.149137 0.599133 0.535866
            +v -0.555408 0.599133 0.000000
            +v -0.499882 0.682112 0.139122
            +v -0.414076 0.765755 0.243198
            +v 0.609621 0.360830 0.169664
            +v 0.552100 0.287158 -0.324265
            +v 0.453072 0.287158 -0.453072
            +v 0.324265 0.287158 -0.552100
            +v 0.171349 0.287158 -0.615677
            +v -0.000000 0.287158 -0.638129
            +v -0.171350 0.287158 -0.615677
            +v -0.324265 0.287158 -0.552100
            +v -0.453072 0.287158 -0.453072
            +v -0.552100 0.287158 -0.324265
            +v -0.615677 0.287158 -0.171349
            +v -0.263278 0.682112 0.448260
            +v -0.000000 0.599133 0.555408
            +v 0.298931 0.517485 0.508969
            +v -0.588275 0.517481 0.000000
            +v -0.448260 0.682112 0.263277
            +v 0.546669 0.360830 0.321075
            +v 0.436292 0.437827 0.436292
            +v 0.615677 0.287158 -0.171349
            +v -0.631850 0.360830 0.000000
            +v -0.614496 0.437827 0.000000
            +v -0.367859 0.682112 0.367859
            +v -0.149138 0.599133 0.535866
            +v 0.157963 0.517481 0.567578
            +v -0.567578 0.517481 0.157963
            +v -0.480530 0.599133 0.282230
            +v 0.615677 0.287158 0.171349
            +v 0.541877 0.221240 -0.318259
            +v 0.444680 0.221240 -0.444680
            +v 0.318259 0.221240 -0.541877
            +v 0.168176 0.221240 -0.604276
            +v -0.000000 0.221240 -0.626311
            +v -0.168177 0.221240 -0.604276
            +v -0.318259 0.221240 -0.541877
            +v -0.444680 0.221240 -0.444680
            +v -0.541877 0.221240 -0.318259
            +v -0.604277 0.221240 -0.168176
            +v -0.282230 0.599133 0.480530
            +v -0.000000 0.517481 0.588275
            +v 0.312254 0.437827 0.531651
            +v -0.592873 0.437827 0.165003
            +v -0.535866 0.599133 0.149137
            +v -0.394341 0.599133 0.394341
            +v 0.552100 0.287158 0.324265
            +v 0.448614 0.360830 0.448614
            +v 0.604276 0.221240 -0.168176
            +v -0.615677 0.287158 0.171349
            +v -0.609621 0.360830 0.169664
            +v -0.157963 0.517485 0.567578
            +v 0.165003 0.437827 0.592873
            +v -0.531651 0.437827 0.312254
            +v -0.508969 0.517485 0.298931
            +v -0.417675 0.517481 0.417675
            +v 0.604276 0.221240 0.168176
            +v 0.516317 0.166623 -0.303247
            +v 0.423705 0.166623 -0.423705
            +v 0.303247 0.166623 -0.516317
            +v 0.160243 0.166623 -0.575771
            +v -0.000000 0.166623 -0.596769
            +v -0.160244 0.166623 -0.575771
            +v -0.303247 0.166623 -0.516317
            +v -0.423705 0.166623 -0.423705
            +v -0.516317 0.166623 -0.303247
            +v -0.575771 0.166623 -0.160243
            +v -0.298931 0.517485 0.508969
            +v -0.000000 0.437827 0.614496
            +v 0.321074 0.360830 0.546669
            +v -0.546669 0.360830 0.321075
            +v 0.541877 0.221240 0.318259
            +v 0.453072 0.287158 0.453072
            +v 0.575771 0.166623 -0.160243
            +v -0.596769 0.166623 0.000000
            +v -0.604277 0.221240 0.168176
            +v -0.552100 0.287158 0.324265
            +v -0.165004 0.437827 0.592873
            +v 0.169664 0.360830 0.609621
            +v -0.448615 0.360830 0.448614
            +v -0.436292 0.437827 0.436292
            +v -0.312255 0.437827 0.531651
            +v 0.575771 0.166623 0.160243
            +v 0.483086 0.122640 -0.283731
            +v 0.396438 0.122640 -0.396438
            +v 0.283731 0.122640 -0.483086
            +v 0.149931 0.122640 -0.538718
            +v -0.000000 0.122640 -0.558363
            +v -0.149931 0.122640 -0.538718
            +v -0.283731 0.122640 -0.483086
            +v -0.396438 0.122640 -0.396438
            +v -0.483087 0.122640 -0.283731
            +v -0.538718 0.122640 -0.149931
            +v -0.558363 0.122640 0.000000
            +v -0.541877 0.221240 0.318259
            +v -0.000000 0.360830 0.631850
            +v 0.324265 0.287158 0.552100
            +v -0.453072 0.287158 0.453072
            +v 0.516317 0.166623 0.303247
            +v 0.596768 0.166623 0.000000
            +v 0.444680 0.221240 0.444680
            +v 0.538718 0.122640 -0.149931
            +v -0.538718 0.122640 0.149931
            +v -0.516317 0.166623 0.303247
            +v -0.444680 0.221240 0.444680
            +v -0.169664 0.360830 0.609621
            +v 0.171349 0.287158 0.615677
            +v -0.324265 0.287158 0.552100
            +v -0.321075 0.360830 0.546669
            +v 0.538718 0.122640 0.149931
            +v 0.558363 0.122640 0.000000
            +v 0.449858 0.088629 -0.264215
            +v 0.369171 0.088629 -0.369171
            +v 0.264215 0.088629 -0.449859
            +v 0.139618 0.088629 -0.501662
            +v -0.000000 0.088629 -0.519957
            +v -0.139618 0.088629 -0.501662
            +v -0.264215 0.088629 -0.449859
            +v -0.369171 0.088629 -0.369171
            +v -0.449859 0.088629 -0.264215
            +v -0.501662 0.088629 -0.139618
            +v -0.519957 0.088629 0.000000
            +v -0.501662 0.088629 0.139618
            +v -0.575771 0.166623 0.160243
            +v -0.423705 0.166623 0.423705
            +v -0.000000 0.287158 0.638129
            +v 0.318259 0.221240 0.541877
            +v -0.318259 0.221240 0.541877
            +v 0.483086 0.122640 0.283731
            +v 0.423705 0.166623 0.423705
            +v 0.501662 0.088629 -0.139618
            +v -0.449859 0.088629 0.264215
            +v -0.483087 0.122640 0.283731
            +v -0.396438 0.122640 0.396438
            +v -0.303247 0.166623 0.516317
            +v -0.171350 0.287158 0.615677
            +v 0.168176 0.221240 0.604276
            +v -0.168177 0.221240 0.604276
            +v 0.501662 0.088629 0.139618
            +v 0.519957 0.088629 0.000000
            +v 0.424299 0.063924 -0.249203
            +v 0.348195 0.063924 -0.348195
            +v 0.249203 0.063924 -0.424298
            +v 0.131685 0.063924 -0.473160
            +v -0.000000 0.063924 -0.490415
            +v -0.131686 0.063924 -0.473160
            +v -0.249203 0.063924 -0.424298
            +v -0.348196 0.063924 -0.348195
            +v -0.424299 0.063924 -0.249203
            +v -0.473160 0.063924 -0.131685
            +v -0.490415 0.063924 0.000000
            +v -0.473160 0.063924 0.131685
            +v -0.424299 0.063924 0.249203
            +v -0.283731 0.122640 0.483086
            +v -0.000000 0.221240 0.626311
            +v 0.303247 0.166623 0.516317
            +v -0.160244 0.166623 0.575771
            +v 0.449858 0.088629 0.264215
            +v 0.396438 0.122640 0.396438
            +v 0.473160 0.063924 -0.131685
            +v -0.348196 0.063924 0.348195
            +v -0.369171 0.088629 0.369171
            +v -0.264215 0.088629 0.449859
            +v -0.149931 0.122640 0.538718
            +v 0.160243 0.166623 0.575771
            +v -0.000000 0.166623 0.596769
            +v 0.473160 0.063924 0.131685
            +v 0.490415 0.063924 0.000000
            +v 0.414076 0.047860 -0.243198
            +v 0.339803 0.047860 -0.339804
            +v 0.243198 0.047860 -0.414076
            +v 0.128512 0.047860 -0.461757
            +v -0.000000 0.047860 -0.478597
            +v -0.128513 0.047860 -0.461757
            +v -0.243198 0.047860 -0.414076
            +v -0.339804 0.047860 -0.339804
            +v -0.414076 0.047860 -0.243198
            +v -0.461757 0.047860 -0.128512
            +v -0.478597 0.047860 0.000000
            +v -0.461757 0.047860 0.128512
            +v -0.414076 0.047860 0.243198
            +v -0.339804 0.047860 0.339804
            +v -0.139618 0.088629 0.501662
            +v 0.283731 0.122640 0.483086
            +v -0.000000 0.122640 0.558363
            +v 0.424299 0.063924 0.249203
            +v 0.369171 0.088629 0.369171
            +v 0.461756 0.047860 -0.128512
            +v -0.243198 0.047860 0.414076
            +v -0.249203 0.063924 0.424298
            +v -0.131686 0.063924 0.473160
            +v -0.000000 0.088629 0.519957
            +v 0.149931 0.122640 0.538718
            +v 0.461756 0.047860 0.128512
            +v 0.478596 0.047860 0.000000
            +v 0.410719 0.036005 -0.241228
            +v 0.337050 0.036005 -0.337050
            +v 0.241227 0.036005 -0.410719
            +v 0.127471 0.036005 -0.458017
            +v -0.000000 0.036005 -0.474720
            +v -0.127471 0.036005 -0.458017
            +v -0.241228 0.036005 -0.410719
            +v -0.337051 0.036005 -0.337050
            +v -0.410719 0.036005 -0.241228
            +v -0.458017 0.036005 -0.127471
            +v -0.474721 0.036005 0.000000
            +v -0.458017 0.036005 0.127471
            +v -0.410719 0.036005 0.241228
            +v -0.337051 0.036005 0.337050
            +v -0.241228 0.036005 0.410719
            +v -0.000000 0.063924 0.490415
            +v 0.264215 0.088629 0.449859
            +v 0.139618 0.088629 0.501662
            +v 0.414076 0.047860 0.243198
            +v 0.348195 0.063924 0.348195
            +v 0.458017 0.036005 -0.127471
            +v -0.127471 0.036005 0.458017
            +v -0.128513 0.047860 0.461757
            +v -0.000000 0.047860 0.478597
            +v 0.131685 0.063924 0.473160
            +v 0.458017 0.036005 0.127471
            +v 0.474720 0.036005 0.000000
            +v 0.394137 0.024816 -0.231489
            +v 0.323442 0.024816 -0.323442
            +v 0.231489 0.024816 -0.394137
            +v 0.122324 0.024816 -0.439524
            +v -0.000000 0.024816 -0.455554
            +v -0.122325 0.024816 -0.439524
            +v -0.231489 0.024816 -0.394137
            +v -0.323442 0.024816 -0.323442
            +v -0.394137 0.024816 -0.231489
            +v -0.439524 0.024816 -0.122325
            +v -0.455554 0.024816 0.000000
            +v -0.439524 0.024816 0.122325
            +v -0.394137 0.024816 0.231489
            +v -0.323442 0.024816 0.323442
            +v -0.231489 0.024816 0.394137
            +v -0.122325 0.024816 0.439524
            +v 0.128512 0.047860 0.461757
            +v 0.249203 0.063924 0.424298
            +v 0.410719 0.036005 0.241228
            +v 0.339803 0.047860 0.339804
            +v 0.439524 0.024816 -0.122325
            +v -0.000000 0.036005 0.474720
            +v -0.000000 0.024816 0.455554
            +v 0.127471 0.036005 0.458017
            +v 0.243198 0.047860 0.414076
            +v 0.439524 0.024816 0.122325
            +v 0.455554 0.024816 0.000000
            +v 0.354551 0.014956 -0.208238
            +v 0.290957 0.014956 -0.290957
            +v 0.208238 0.014956 -0.354551
            +v 0.110038 0.014956 -0.395378
            +v -0.000000 0.014956 -0.409797
            +v -0.110038 0.014956 -0.395378
            +v -0.208239 0.014956 -0.354551
            +v -0.290957 0.014956 -0.290957
            +v -0.354551 0.014956 -0.208238
            +v -0.395378 0.014956 -0.110038
            +v -0.409797 0.014956 0.000000
            +v -0.395378 0.014956 0.110038
            +v -0.354551 0.014956 0.208238
            +v -0.290957 0.014956 0.290957
            +v -0.208239 0.014956 0.354551
            +v -0.110038 0.014956 0.395378
            +v -0.000000 0.014956 0.409797
            +v 0.241227 0.036005 0.410719
            +v 0.337050 0.036005 0.337050
            +v 0.394137 0.024816 0.231489
            +v 0.395378 0.014956 -0.110038
            +v 0.122324 0.024816 0.439524
            +v 0.110038 0.014956 0.395378
            +v 0.231489 0.024816 0.394137
            +v 0.395378 0.014956 0.110038
            +v 0.409797 0.014956 0.000000
            +v 0.282184 0.007090 -0.165735
            +v 0.231570 0.007090 -0.231570
            +v 0.165735 0.007090 -0.282185
            +v 0.087579 0.007090 -0.314679
            +v -0.000000 0.007090 -0.326154
            +v -0.087579 0.007090 -0.314679
            +v -0.165735 0.007090 -0.282185
            +v -0.231570 0.007090 -0.231570
            +v -0.282184 0.007090 -0.165735
            +v -0.314679 0.007090 -0.087579
            +v -0.326155 0.007090 0.000000
            +v -0.314679 0.007090 0.087579
            +v -0.282184 0.007090 0.165735
            +v -0.231570 0.007090 0.231570
            +v -0.165735 0.007090 0.282185
            +v -0.087579 0.007090 0.314679
            +v -0.000000 0.007090 0.326154
            +v 0.087579 0.007090 0.314679
            +v 0.323442 0.024816 0.323442
            +v 0.354551 0.014956 0.208238
            +v 0.314679 0.007090 -0.087579
            +v 0.208238 0.014956 0.354551
            +v 0.165735 0.007090 0.282185
            +v 0.290957 0.014956 0.290957
            +v 0.314679 0.007090 0.087579
            +v 0.326154 0.007090 0.000000
            +v 0.167259 0.001883 -0.098236
            +v 0.137258 0.001883 -0.137259
            +v 0.098236 0.001883 -0.167259
            +v 0.051910 0.001883 -0.186520
            +v -0.000000 0.001883 -0.193322
            +v -0.051911 0.001883 -0.186520
            +v -0.098237 0.001883 -0.167259
            +v -0.137259 0.001883 -0.137259
            +v -0.167259 0.001883 -0.098236
            +v -0.186520 0.001883 -0.051911
            +v -0.193323 0.001883 0.000000
            +v -0.186520 0.001883 0.051911
            +v -0.167259 0.001883 0.098236
            +v -0.137259 0.001883 0.137259
            +v -0.098237 0.001883 0.167259
            +v -0.051911 0.001883 0.186520
            +v -0.000000 0.001883 0.193322
            +v 0.051910 0.001883 0.186520
            +v 0.098236 0.001883 0.167259
            +v 0.282184 0.007090 0.165735
            +v 0.186520 0.001883 -0.051911
            +v 0.231570 0.007090 0.231570
            +v 0.137258 0.001883 0.137259
            +v 0.186520 0.001883 0.051911
            +v 0.193322 0.001883 0.000000
            +v -0.000000 0.000000 0.000000
            +v 0.167259 0.001883 0.098236
            +v 0.063813 0.861474 0.000000
            +v 0.054654 0.888729 0.000000
            +v 0.052734 0.888729 0.014691
            +v 0.061568 0.861474 0.017135
            +v 0.061568 0.861474 -0.017135
            +v 0.072979 0.919969 0.020357
            +v 0.111968 0.841089 0.000000
            +v 0.047296 0.888729 0.027792
            +v 0.052734 0.888729 -0.014691
            +v 0.108028 0.841089 -0.030065
            +v 0.075630 0.919969 0.000000
            +v 0.065466 0.919969 0.038494
            +v 0.108028 0.841089 0.030065
            +v 0.055210 0.861474 0.032427
            +v 0.055210 0.861474 -0.032427
            +v 0.096873 0.841089 -0.056896
            +v 0.100064 0.951211 0.027927
            +v 0.089769 0.951211 0.052799
            +v 0.183167 0.826023 0.000000
            +v 0.176722 0.826023 -0.049184
            +v 0.038821 0.888729 0.038821
            +v 0.053751 0.919969 0.053751
            +v 0.047296 0.888729 -0.027792
            +v 0.072979 0.919969 -0.020357
            +v 0.158473 0.826023 -0.093076
            +v 0.103696 0.951211 0.000000
            +v 0.073714 0.951211 0.073714
            +v 0.176722 0.826023 0.049184
            +v 0.096873 0.841089 0.056896
            +v 0.045307 0.861474 0.045307
            +v 0.079497 0.841089 -0.079497
            +v 0.045307 0.861474 -0.045307
            +v 0.130048 0.826023 -0.130048
            +v 0.111754 0.978466 0.031195
            +v 0.100259 0.978466 0.058974
            +v 0.082330 0.978466 0.082330
            +v 0.263228 0.813615 0.000000
            +v 0.253966 0.813615 -0.070682
            +v 0.227741 0.813615 -0.133759
            +v 0.027792 0.888729 0.047296
            +v 0.038494 0.919969 0.065466
            +v 0.052799 0.951211 0.089769
            +v 0.038821 0.888729 -0.038821
            +v 0.065466 0.919969 -0.038494
            +v 0.100064 0.951211 -0.027927
            +v 0.186892 0.813615 -0.186892
            +v 0.115809 0.978466 0.000000
            +v 0.058974 0.978466 0.100259
            +v 0.253966 0.813615 0.070682
            +v 0.158473 0.826023 0.093076
            +v 0.079497 0.841089 0.079497
            +v 0.032426 0.861474 0.055210
            +v 0.093076 0.826023 -0.158473
            +v 0.056896 0.841089 -0.096873
            +v 0.032426 0.861474 -0.055210
            +v 0.133759 0.813615 -0.227741
            +v 0.085811 0.997741 0.023955
            +v 0.076985 0.997741 0.045285
            +v 0.063219 0.997741 0.063219
            +v 0.045285 0.997741 0.076986
            +v 0.337972 0.801206 0.000000
            +v 0.326081 0.801206 -0.090752
            +v 0.292408 0.801206 -0.171740
            +v 0.239960 0.801206 -0.239960
            +v 0.014691 0.888729 0.052735
            +v 0.020357 0.919969 0.072979
            +v 0.027927 0.951211 0.100064
            +v 0.031195 0.978466 0.111754
            +v 0.027792 0.888729 -0.047296
            +v 0.053751 0.919969 -0.053751
            +v 0.089769 0.951211 -0.052799
            +v 0.111754 0.978466 -0.031195
            +v 0.171740 0.801206 -0.292408
            +v 0.088924 0.997741 0.000000
            +v 0.023955 0.997741 0.085811
            +v 0.326081 0.801206 0.090752
            +v 0.227741 0.813615 0.133759
            +v 0.130048 0.826023 0.130048
            +v 0.056896 0.841089 0.096873
            +v 0.017135 0.861474 0.061568
            +v 0.070682 0.813615 -0.253966
            +v 0.049184 0.826023 -0.176722
            +v 0.030065 0.841089 -0.108029
            +v 0.017135 0.861474 -0.061568
            +v 0.090752 0.801206 -0.326081
            +v -0.000000 1.005054 0.000000
            +v 0.393218 0.786140 0.000000
            +v 0.379380 0.786140 -0.105586
            +v 0.340206 0.786140 -0.199813
            +v 0.279184 0.786140 -0.279184
            +v 0.199813 0.786140 -0.340206
            +v -0.000000 0.888729 0.054654
            +v -0.000000 0.919969 0.075630
            +v -0.000000 0.951211 0.103696
            +v -0.000000 0.978466 0.115809
            +v -0.000000 0.997741 0.088925
            +v 0.014691 0.888729 -0.052735
            +v 0.038494 0.919969 -0.065466
            +v 0.073714 0.951211 -0.073714
            +v 0.100259 0.978466 -0.058974
            +v 0.085811 0.997741 -0.023955
            +v 0.105586 0.786140 -0.379381
            +v 0.379380 0.786140 0.105586
            +v 0.292408 0.801206 0.171740
            +v 0.186892 0.813615 0.186892
            +v 0.093076 0.826023 0.158473
            +v 0.030065 0.841089 0.108029
            +v -0.000000 0.861474 0.063813
            +v -0.000000 0.801206 -0.337972
            +v -0.000000 0.813615 -0.263228
            +v -0.000000 0.826023 -0.183167
            +v -0.000000 0.841089 -0.111968
            +v -0.000000 0.861474 -0.063813
            +v -0.000000 0.786140 -0.393218
            +v 0.076985 0.997741 -0.045285
            +v -0.023955 0.997741 0.085811
            +v 0.414784 0.765755 0.000000
            +v 0.400190 0.765755 -0.111377
            +v 0.358865 0.765755 -0.210772
            +v 0.294497 0.765755 -0.294497
            +v 0.210772 0.765755 -0.358865
            +v 0.111377 0.765755 -0.400190
            +v -0.014691 0.888729 0.052735
            +v -0.020357 0.919969 0.072979
            +v -0.027927 0.951211 0.100064
            +v -0.031195 0.978466 0.111754
            +v -0.000000 0.888729 -0.054654
            +v 0.020357 0.919969 -0.072979
            +v 0.052799 0.951211 -0.089769
            +v 0.082330 0.978466 -0.082330
            +v -0.000000 0.765755 -0.414784
            +v 0.063219 0.997741 -0.063219
            +v -0.045285 0.997741 0.076986
            +v 0.400190 0.765755 0.111377
            +v 0.340206 0.786140 0.199813
            +v 0.239960 0.801206 0.239960
            +v 0.133759 0.813615 0.227741
            +v 0.049184 0.826023 0.176722
            +v -0.000000 0.841089 0.111968
            +v -0.017135 0.861474 0.061568
            +v -0.105586 0.786140 -0.379381
            +v -0.090752 0.801206 -0.326081
            +v -0.070682 0.813615 -0.253966
            +v -0.049184 0.826023 -0.176722
            +v -0.030066 0.841089 -0.108029
            +v -0.017135 0.861474 -0.061568
            +v -0.111377 0.765755 -0.400190
            +v 0.045285 0.997741 -0.076986
            +v -0.063220 0.997741 0.063219
            +v 0.414952 0.750806 0.115486
            +v 0.430085 0.750806 0.000000
            +v 0.414952 0.750806 -0.115486
            +v 0.372103 0.750806 -0.218547
            +v 0.305360 0.750806 -0.305360
            +v 0.218547 0.750806 -0.372103
            +v 0.115486 0.750806 -0.414952
            +v -0.000000 0.750806 -0.430085
            +v -0.027793 0.888729 0.047296
            +v -0.038494 0.919969 0.065466
            +v -0.052799 0.951211 0.089769
            +v -0.058974 0.978466 0.100259
            +v -0.014691 0.888729 -0.052735
            +v -0.000000 0.919969 -0.075630
            +v 0.027927 0.951211 -0.100064
            +v 0.058974 0.978466 -0.100259
            +v -0.115486 0.750806 -0.414952
            +v 0.023955 0.997741 -0.085811
            +v -0.076986 0.997741 0.045285
            +v 0.372103 0.750806 0.218547
            +v 0.358865 0.765755 0.210772
            +v 0.279184 0.786140 0.279184
            +v 0.171740 0.801206 0.292408
            +v 0.070682 0.813615 0.253966
            +v -0.000000 0.826023 0.183167
            +v -0.030066 0.841089 0.108029
            +v -0.032427 0.861474 0.055210
            +v -0.210772 0.765755 -0.358865
            +v -0.199813 0.786140 -0.340206
            +v -0.171740 0.801206 -0.292408
            +v -0.133759 0.813615 -0.227741
            +v -0.093076 0.826023 -0.158473
            +v -0.056896 0.841089 -0.096873
            +v -0.032427 0.861474 -0.055210
            +v -0.218547 0.750806 -0.372103
            +v 0.031195 0.978466 -0.111754
            +v -0.000000 0.997741 -0.088925
            +v -0.082331 0.978466 0.082330
            +v -0.085811 0.997741 0.023955
            +v 0.305360 0.750806 0.305360
            +v 0.294497 0.765755 0.294497
            +v -0.038821 0.888729 0.038821
            +v -0.053751 0.919969 0.053751
            +v -0.073714 0.951211 0.073714
            +v -0.027793 0.888729 -0.047296
            +v -0.020357 0.919969 -0.072979
            +v -0.000000 0.951211 -0.103696
            +v -0.305360 0.750806 -0.305360
            +v -0.294497 0.765755 -0.294497
            +v -0.000000 0.978466 -0.115809
            +v -0.023955 0.997741 -0.085811
            +v -0.100259 0.978466 0.058974
            +v -0.088925 0.997741 0.000000
            +v 0.210772 0.765755 0.358865
            +v 0.218547 0.750806 0.372103
            +v 0.199813 0.786140 0.340206
            +v 0.090752 0.801206 0.326081
            +v -0.000000 0.813615 0.263228
            +v -0.049184 0.826023 0.176722
            +v -0.056896 0.841089 0.096873
            +v -0.045307 0.861474 0.045307
            +v -0.279185 0.786140 -0.279184
            +v -0.239960 0.801206 -0.239960
            +v -0.186892 0.813615 -0.186892
            +v -0.130049 0.826023 -0.130048
            +v -0.079497 0.841089 -0.079497
            +v -0.045307 0.861474 -0.045307
            +v -0.372103 0.750806 -0.218547
            +v -0.358865 0.765755 -0.210772
            +v -0.031195 0.978466 -0.111754
            +v -0.045285 0.997741 -0.076986
            +v -0.111754 0.978466 0.031195
            +v -0.085811 0.997741 -0.023955
            +v 0.111377 0.765755 0.400190
            +v 0.115486 0.750806 0.414952
            +v -0.047296 0.888729 0.027792
            +v -0.065466 0.919969 0.038494
            +v -0.089770 0.951211 0.052799
            +v -0.038821 0.888729 -0.038821
            +v -0.038494 0.919969 -0.065466
            +v -0.027927 0.951211 -0.100064
            +v -0.414952 0.750806 -0.115486
            +v -0.400190 0.765755 -0.111377
            +v -0.058974 0.978466 -0.100259
            +v -0.063220 0.997741 -0.063219
            +v -0.115809 0.978466 0.000000
            +v -0.076986 0.997741 -0.045285
            +v 0.105586 0.786140 0.379381
            +v -0.000000 0.765755 0.414784
            +v -0.000000 0.750806 0.430085
            +v -0.000000 0.801206 0.337972
            +v -0.070682 0.813615 0.253966
            +v -0.093076 0.826023 0.158473
            +v -0.079497 0.841089 0.079497
            +v -0.055210 0.861474 0.032427
            +v -0.340206 0.786140 -0.199813
            +v -0.292408 0.801206 -0.171740
            +v -0.227741 0.813615 -0.133759
            +v -0.158473 0.826023 -0.093076
            +v -0.096873 0.841089 -0.056896
            +v -0.055210 0.861474 -0.032427
            +v -0.430085 0.750806 0.000000
            +v -0.414784 0.765755 0.000000
            +v -0.052799 0.951211 -0.089769
            +v -0.082331 0.978466 -0.082330
            +v -0.100064 0.951211 0.027927
            +v -0.111754 0.978466 -0.031195
            +v -0.000000 0.786140 0.393218
            +v -0.115486 0.750806 0.414952
            +v -0.111377 0.765755 0.400190
            +v -0.052735 0.888729 0.014691
            +v -0.072979 0.919969 0.020357
            +v -0.047296 0.888729 -0.027792
            +v -0.053751 0.919969 -0.053751
            +v -0.414952 0.750806 0.115486
            +v -0.400190 0.765755 0.111377
            +v -0.379381 0.786140 -0.105586
            +v -0.073714 0.951211 -0.073714
            +v -0.100259 0.978466 -0.058974
            +v -0.103696 0.951211 0.000000
            +v -0.105586 0.786140 0.379381
            +v -0.218547 0.750806 0.372103
            +v -0.210772 0.765755 0.358865
            +v -0.090752 0.801206 0.326081
            +v -0.133759 0.813615 0.227741
            +v -0.130049 0.826023 0.130048
            +v -0.096873 0.841089 0.056896
            +v -0.061568 0.861474 0.017135
            +v -0.326081 0.801206 -0.090752
            +v -0.253966 0.813615 -0.070682
            +v -0.176722 0.826023 -0.049184
            +v -0.108029 0.841089 -0.030065
            +v -0.061568 0.861474 -0.017135
            +v -0.372103 0.750806 0.218547
            +v -0.358865 0.765755 0.210772
            +v -0.393219 0.786140 0.000000
            +v -0.089770 0.951211 -0.052799
            +v -0.100064 0.951211 -0.027927
            +v -0.199813 0.786140 0.340206
            +v -0.305360 0.750806 0.305360
            +v -0.294497 0.765755 0.294497
            +v -0.054655 0.888729 0.000000
            +v -0.075630 0.919969 0.000000
            +v -0.052735 0.888729 -0.014691
            +v -0.065466 0.919969 -0.038494
            +v -0.379381 0.786140 0.105586
            +v -0.171740 0.801206 0.292408
            +v -0.279185 0.786140 0.279184
            +v -0.186892 0.813615 0.186892
            +v -0.158473 0.826023 0.093076
            +v -0.108029 0.841089 0.030065
            +v -0.063813 0.861474 0.000000
            +v -0.337972 0.801206 0.000000
            +v -0.263228 0.813615 0.000000
            +v -0.183167 0.826023 0.000000
            +v -0.111968 0.841089 0.000000
            +v -0.340206 0.786140 0.199813
            +v -0.072979 0.919969 -0.020357
            +v -0.239960 0.801206 0.239960
            +v -0.326081 0.801206 0.090752
            +v -0.292408 0.801206 0.171740
            +v -0.227741 0.813615 0.133759
            +v -0.176722 0.826023 0.049184
            +v -0.253966 0.813615 0.070682
            +v -0.526706 0.651362 -0.039883
            +v -0.534329 0.646030 0.000000
            +v -0.619922 0.238069 -0.071790
            +v -0.624826 0.259599 -0.063813
            +v -0.638129 0.287158 0.000000
            +v -0.631184 0.277569 0.039883
            +v -0.501666 0.699221 -0.063813
            +v -0.508714 0.682112 -0.071712
            +v -0.611709 0.194244 0.000000
            +v -0.608883 0.198681 0.039883
            +v -0.517593 0.664661 0.063813
            +v -0.508714 0.682112 0.071712
            +v -0.631184 0.277569 -0.039883
            +v -0.624828 0.259599 0.063813
            +v -0.615480 0.216617 0.063578
            +v -0.615553 0.216807 -0.063813
            +v -0.517593 0.664661 -0.063813
            +v -0.498530 0.712498 -0.039883
            +v -0.619922 0.238069 0.071790
            +v -0.526706 0.651362 0.039883
            +v -0.608884 0.198682 -0.039883
            +v 0.605100 0.399712 0.137265
            +v 0.613258 0.341675 0.154354
            +v 0.605956 0.463769 0.000000
            +v 0.600959 0.444810 -0.085753
            +v 0.613258 0.341675 -0.154354
            +v 0.605101 0.399712 -0.137265
            +v 0.600960 0.444810 0.085753
            +v 0.121642 0.750009 -0.437072
            +v -0.000000 0.750009 -0.453012
            +v 0.453011 0.750009 0.000000
            +v 0.437073 0.750009 -0.121642
            +v -0.453012 0.750009 0.000000
            +v -0.437073 0.750009 -0.121642
            +v -0.230198 0.750009 0.391939
            +v -0.321639 0.750009 0.321639
            +v -0.391940 0.750009 0.230197
            +v -0.437073 0.750009 0.121642
            +v 0.121642 0.750009 0.437072
            +v -0.000000 0.750009 0.453012
            +v -0.121642 0.750009 0.437072
            +v 0.437073 0.750009 0.121642
            +v 0.391939 0.750009 0.230197
            +v 0.321638 0.750009 -0.321639
            +v 0.230197 0.750009 -0.391940
            +v -0.121642 0.750009 -0.437072
            +v 0.391939 0.750009 -0.230197
            +v 0.321638 0.750009 0.321639
            +v 0.230197 0.750009 0.391940
            +v -0.230198 0.750009 -0.391939
            +v -0.501255 0.717792 0.000000
            +v 0.617684 0.235930 0.085941
            +v 0.625577 0.219883 0.000000
            +v -0.321639 0.750009 -0.321639
            +v -0.391940 0.750009 -0.230197
            +v -0.498530 0.712498 0.039883
            +v -0.501667 0.699221 0.063813
            +v 0.617684 0.235930 -0.085941
            +v 0.619427 0.283145 -0.137236
            +v 0.619427 0.283145 0.137236
            +vn -0.901883 0.415418 0.118168
            +vn -0.905637 0.407056 0.118656
            +vn -0.877041 0.418744 0.235298
            +vn 0.058443 -0.998260 0.000732
            +vn 0.015107 -0.999878 0.000183
            +vn 0.014557 -0.949278 0.314035
            +vn 0.056703 -0.947539 0.314524
            +vn 0.162053 -0.986755 0.002014
            +vn 0.157933 -0.933592 0.321604
            +vn 0.392376 -0.919767 0.004334
            +vn 0.378307 -0.856655 0.350688
            +vn 0.783776 -0.620991 0.005249
            +vn 0.726829 -0.553880 0.406079
            +vn 0.994812 -0.101627 0.001984
            +vn 0.908139 -0.082766 0.410321
            +vn 0.003082 -0.939787 0.341685
            +vn 0.002167 -0.619495 0.784967
            +vn 0.011536 -0.679403 0.733634
            +vn 0.044679 -0.675588 0.735923
            +vn 0.123325 -0.652272 0.747856
            +vn 0.275399 -0.556871 0.783593
            +vn 0.460067 -0.316263 0.829615
            +vn 0.563036 -0.041200 0.825373
            +vn -0.000427 0.122166 0.992492
            +vn 0.000397 0.003632 0.999969
            +vn 0.002869 0.011841 0.999908
            +vn 0.004852 0.029298 0.999542
            +vn -0.008179 0.053499 0.998505
            +vn -0.046510 0.041536 0.998047
            +vn -0.039155 0.003113 0.999207
            +vn -0.850551 0.473769 -0.228217
            +vn -0.897885 0.424177 -0.117649
            +vn -0.880886 0.473281 0.000000
            +vn -0.013611 0.682394 0.730827
            +vn -0.053896 0.680441 0.730796
            +vn -0.147557 0.656789 0.739464
            +vn -0.325968 0.560564 0.761223
            +vn -0.537645 0.315806 0.781762
            +vn -0.611530 0.029939 0.790613
            +vn -0.904172 0.427137 0.000000
            +vn -0.897885 0.424146 0.117618
            +vn -0.020112 0.949461 0.313150
            +vn -0.081820 0.945433 0.315287
            +vn -0.227699 0.916379 0.329173
            +vn -0.504196 0.785302 0.359203
            +vn -0.810633 0.443220 0.382611
            +vn -0.921232 0.039705 0.386944
            +vn -0.020569 0.949400 -0.313334
            +vn -0.021729 0.999756 -0.000092
            +vn -0.004242 0.950468 -0.310770
            +vn -0.088260 0.996094 -0.000488
            +vn -0.246895 0.969024 -0.001343
            +vn -0.549730 0.835322 -0.002350
            +vn -0.880673 0.473647 -0.001984
            +vn -0.999084 0.042146 -0.000610
            +vn -0.877041 0.418744 -0.235298
            +vn -0.920286 0.391156 0.000000
            +vn -0.905637 0.407056 -0.118656
            +vn -0.083132 0.945006 -0.316202
            +vn -0.230201 0.914823 -0.331797
            +vn -0.505570 0.782800 -0.362743
            +vn -0.808710 0.444960 -0.384625
            +vn -0.920835 0.042055 -0.387646
            +vn -0.897885 0.424146 -0.117618
            +vn -0.901883 0.415448 -0.118168
            +vn -0.014161 0.682394 -0.730796
            +vn -0.055361 0.680074 -0.731010
            +vn -0.150029 0.655660 -0.739982
            +vn -0.327616 0.560594 -0.760491
            +vn -0.537431 0.320933 -0.779809
            +vn -0.611988 0.033387 -0.790155
            +vn 0.015168 -0.949339 -0.313852
            +vn 0.011902 -0.679403 -0.733634
            +vn 0.003265 -0.939817 -0.341594
            +vn 0.000183 0.004212 -0.999969
            +vn 0.003510 0.014008 -0.999878
            +vn 0.005921 0.035951 -0.999329
            +vn -0.010132 0.064333 -0.997864
            +vn -0.051576 0.048463 -0.997467
            +vn -0.041597 0.003998 -0.999115
            +vn 0.003082 -0.620106 -0.784478
            +vn -0.000031 0.122440 -0.992462
            +vn -0.897885 0.424177 0.117649
            +vn 0.046449 -0.674398 -0.736869
            +vn 0.125980 -0.648946 -0.750298
            +vn 0.275430 -0.552477 -0.786676
            +vn 0.455519 -0.320536 -0.830500
            +vn 0.561693 -0.046480 -0.826014
            +vn -0.888668 0.391644 0.238441
            +vn 0.058046 -0.947630 -0.314005
            +vn 0.159948 -0.933836 -0.319865
            +vn 0.380169 -0.857753 -0.345927
            +vn 0.725547 -0.560930 -0.398602
            +vn 0.908597 -0.089236 -0.407971
            +vn 0.003235 -0.999969 0.000031
            +vn 0.973144 0.230110 0.000824
            +vn 0.890896 0.211737 0.401776
            +vn 0.912900 0.408094 0.002533
            +vn 0.836970 0.380932 0.392834
            +vn 0.829035 0.559160 0.003784
            +vn 0.764519 0.528550 0.368969
            +vn 0.718650 0.695334 0.003937
            +vn 0.668294 0.663717 0.335917
            +vn 0.579577 0.814905 0.002838
            +vn 0.542650 0.779687 0.312357
            +vn 0.495163 0.868770 0.002258
            +vn 0.458052 0.820643 0.341624
            +vn 0.561205 0.137028 0.816218
            +vn 0.532029 0.253456 0.807886
            +vn 0.497543 0.363445 0.787591
            +vn 0.449538 0.472060 0.758293
            +vn 0.373669 0.563555 0.736686
            +vn 0.289041 0.531114 0.796442
            +vn -0.023225 -0.005249 0.999695
            +vn -0.016785 -0.010254 0.999786
            +vn -0.011444 -0.012940 0.999847
            +vn -0.009796 -0.013276 0.999847
            +vn -0.014801 -0.013916 0.999786
            +vn -0.089755 -0.176122 0.980255
            +vn -0.585772 -0.152379 0.795984
            +vn -0.538896 -0.288766 0.791314
            +vn -0.484146 -0.407910 0.774071
            +vn -0.424635 -0.509781 0.748161
            +vn -0.355907 -0.584765 0.728935
            +vn -0.889828 -0.237159 0.389782
            +vn -0.808740 -0.446852 0.382366
            +vn -0.702475 -0.613269 0.361095
            +vn -0.590625 -0.734855 0.333293
            +vn -0.483291 -0.816767 0.315104
            +vn -0.912076 0.409955 0.000000
            +vn -0.965606 -0.259987 -0.000458
            +vn -0.872433 -0.488693 -0.001465
            +vn -0.748436 -0.663167 -0.002197
            +vn -0.621601 -0.783288 -0.002136
            +vn -0.507065 -0.861873 -0.001251
            +vn -0.438215 -0.854366 0.279183
            +vn -0.456130 -0.889889 -0.000732
            +vn -0.889126 -0.238868 -0.390332
            +vn -0.807001 -0.448531 -0.384075
            +vn -0.700980 -0.613392 -0.363750
            +vn -0.590442 -0.733757 -0.336039
            +vn -0.484787 -0.815332 -0.316477
            +vn -0.440962 -0.852931 -0.279305
            +vn -0.359691 -0.584185 -0.727531
            +vn -0.358074 -0.682241 -0.637410
            +vn -0.585467 -0.154668 -0.795770
            +vn -0.538499 -0.291696 -0.790490
            +vn -0.484512 -0.409772 -0.772851
            +vn -0.426496 -0.510056 -0.746910
            +vn -0.909543 -0.399274 -0.115207
            +vn -0.971191 -0.204688 -0.121891
            +vn -0.912931 -0.326609 -0.244606
            +vn -0.020478 -0.017853 -0.999603
            +vn -0.024537 -0.005737 -0.999664
            +vn -0.020844 -0.012207 -0.999695
            +vn -0.017548 -0.016846 -0.999695
            +vn -0.016724 -0.018097 -0.999695
            +vn -0.909116 -0.400311 0.115055
            +vn -0.873775 -0.472610 0.114475
            +vn -0.795892 -0.566485 0.213538
            +vn -0.353069 -0.684103 0.638203
            +vn 0.559679 0.139714 -0.816828
            +vn 0.528581 0.255501 -0.809473
            +vn 0.494217 0.362987 -0.789911
            +vn 0.449049 0.469283 -0.760308
            +vn 0.378246 0.560869 -0.736412
            +vn -0.091983 -0.174383 -0.980346
            +vn 0.295267 0.530625 -0.794488
            +vn 0.890500 0.214759 -0.401044
            +vn 0.836634 0.384075 -0.390515
            +vn 0.765191 0.530198 -0.365123
            +vn 0.671041 0.663228 -0.331339
            +vn 0.547929 0.777642 -0.308206
            +vn 0.464522 0.818842 -0.337199
            +vn 0.931486 0.265572 -0.248543
            +vn 0.939543 0.342357 0.000000
            +vn 0.947539 0.295114 -0.122684
            +vn -0.351421 0.936186 0.001953
            +vn -0.144444 0.989502 0.003174
            +vn -0.126743 0.878811 0.459975
            +vn -0.716758 0.697287 -0.000946
            +vn -0.299997 0.838313 0.455214
            +vn -0.621876 0.660207 0.421155
            +vn -0.901822 0.432081 -0.004517
            +vn -0.807031 0.443434 0.389904
            +vn -0.930204 0.366863 -0.008484
            +vn -0.824549 0.383312 0.416059
            +vn -0.850673 0.525529 -0.011628
            +vn -0.722465 0.508988 0.467910
            +vn -0.668447 0.743645 -0.011139
            +vn -0.531449 0.686514 0.496170
            +vn -0.116459 0.505448 0.854946
            +vn -0.258400 0.470656 0.843593
            +vn -0.407605 0.396985 0.822321
            +vn -0.450270 0.352367 0.820399
            +vn -0.385876 0.395734 0.833338
            +vn -0.270669 0.487838 0.829890
            +vn 0.141606 -0.001190 0.989898
            +vn -0.067690 0.525346 0.848170
            +vn 0.989593 0.100253 0.103122
            +vn 0.970244 0.213324 0.114475
            +vn 0.960418 0.152654 0.232917
            +vn 0.241829 0.092502 0.965880
            +vn 0.209296 0.170660 0.962828
            +vn 0.096194 0.178625 0.979186
            +vn 0.009552 0.154332 0.987945
            +vn -0.000122 0.151952 0.988372
            +vn 0.361248 -0.477279 0.801019
            +vn 0.607929 -0.282540 0.741997
            +vn 0.679220 -0.106754 0.726096
            +vn 0.583911 -0.078524 0.807978
            +vn 0.402722 -0.205237 0.891995
            +vn 0.279519 -0.338694 0.898404
            +vn 0.488601 -0.768700 0.412671
            +vn 0.784570 -0.501511 0.364544
            +vn 0.893918 -0.279611 0.350291
            +vn 0.861415 -0.285287 0.420179
            +vn 0.679373 -0.540452 0.496323
            +vn 0.458327 -0.754540 0.469588
            +vn 0.524155 -0.851588 -0.000153
            +vn 0.827143 -0.561968 0.001679
            +vn 0.943205 -0.332133 0.003479
            +vn 0.933256 -0.359081 0.005737
            +vn 0.756859 -0.653493 0.006470
            +vn 0.492843 -0.870083 0.004120
            +vn 0.322489 -0.946562 -0.001129
            +vn 0.912839 -0.326609 0.244942
            +vn 0.824396 -0.565996 0.000000
            +vn 0.894162 -0.447676 0.000000
            +vn 0.486557 -0.770501 -0.411756
            +vn 0.783990 -0.504074 -0.362285
            +vn 0.895199 -0.281899 -0.345134
            +vn 0.863735 -0.289010 -0.412824
            +vn 0.682119 -0.544267 -0.488296
            +vn 0.461928 -0.758202 -0.460128
            +vn 0.357463 -0.479141 -0.801599
            +vn 0.605884 -0.285867 -0.742393
            +vn 0.679739 -0.108646 -0.725333
            +vn 0.583636 -0.077883 -0.808222
            +vn 0.401440 -0.199225 -0.893918
            +vn 0.281961 -0.330638 -0.900632
            +vn 0.135228 -0.002380 -0.990783
            +vn 0.235755 0.091128 -0.967498
            +vn 0.200720 0.170629 -0.964660
            +vn 0.086123 0.184576 -0.979003
            +vn 0.000671 0.174322 -0.984680
            +vn -0.007141 0.169012 -0.985565
            +vn 0.966613 -0.042848 -0.252602
            +vn 0.960418 0.152654 -0.232917
            +vn 0.989593 0.100223 -0.103092
            +vn -0.119297 0.503342 -0.855770
            +vn -0.261269 0.472793 -0.841517
            +vn -0.414075 0.399792 -0.817713
            +vn -0.459700 0.357036 -0.813105
            +vn -0.394024 0.408490 -0.823298
            +vn -0.277871 0.487381 -0.827754
            +vn -0.072207 0.520127 -0.851009
            +vn -0.298654 0.840297 -0.452376
            +vn -0.617512 0.663961 -0.421613
            +vn -0.801324 0.450209 -0.393872
            +vn -0.819422 0.389691 -0.420270
            +vn -0.721274 0.506912 -0.471969
            +vn -0.538347 0.670644 -0.510239
            +vn -0.482009 0.876125 -0.005127
            +vn -0.394635 0.815363 0.423536
            +vn -0.321909 0.946745 -0.002594
            +vn -0.255287 0.921995 0.291086
            +vn 0.004242 0.999969 0.000397
            +vn -0.002960 0.999939 -0.010102
            +vn 0.853450 0.521073 -0.007050
            +vn 0.392041 0.688986 -0.609546
            +vn 0.805170 -0.592517 -0.023621
            +vn 0.588763 -0.206122 -0.781579
            +vn 0.681478 -0.731040 -0.033296
            +vn 0.485031 -0.441237 -0.754967
            +vn -0.206824 0.638203 0.741539
            +vn -0.129490 0.862056 0.489944
            +vn -0.033418 0.999176 0.022340
            +vn 0.047700 0.864040 -0.501114
            +vn 0.099307 0.538743 -0.836573
            +vn 0.053560 0.251839 -0.966277
            +vn 0.020112 0.322611 0.946287
            +vn 0.021943 0.748894 0.662282
            +vn -0.025941 0.995605 0.089908
            +vn -0.059175 0.930876 -0.360424
            +vn -0.080172 0.784448 -0.614948
            +vn -0.142582 0.557604 -0.817743
            +vn 0.281747 -0.174993 0.943388
            +vn 0.303903 0.444136 0.842830
            +vn 0.034333 0.983764 0.175970
            +vn -0.113865 0.956420 -0.268777
            +vn -0.155339 0.858852 -0.488021
            +vn -0.207404 0.641865 -0.738182
            +vn 0.467238 -0.683187 0.561144
            +vn 0.699515 0.004364 0.714560
            +vn 0.355296 0.891934 0.279641
            +vn -0.170354 0.971465 -0.164861
            +vn -0.245552 0.901181 -0.357097
            +vn -0.248726 0.651082 -0.717063
            +vn 0.494430 -0.869167 0.006317
            +vn 0.933134 -0.358898 0.019868
            +vn 0.703146 0.710685 0.021790
            +vn -0.203650 0.978942 -0.012574
            +vn -0.326456 0.942869 -0.066073
            +vn -0.397595 0.857082 -0.327525
            +vn 0.460616 -0.712546 -0.529221
            +vn 0.695486 -0.098544 -0.711722
            +vn 0.397534 0.853816 -0.336070
            +vn -0.198248 0.963439 0.180151
            +vn -0.306833 0.888516 0.341075
            +vn -0.393689 0.807672 0.438887
            +vn 0.276559 -0.211951 -0.937315
            +vn 0.294626 0.366161 -0.882656
            +vn 0.046632 0.973235 -0.224982
            +vn -0.146733 0.912168 0.382611
            +vn -0.202643 0.700797 0.683950
            +vn -0.232673 0.506485 0.830226
            +vn 0.011689 0.309397 -0.950835
            +vn 0.013245 0.708640 -0.705435
            +vn -0.027589 0.995758 -0.087680
            +vn -0.047395 0.829371 0.556658
            +vn -0.015259 0.386608 0.922086
            +vn 0.004639 0.119510 0.992798
            +vn -0.211035 0.631001 -0.746513
            +vn -0.138768 0.848781 -0.510147
            +vn -0.024995 0.999664 -0.001190
            +vn 0.120426 0.724570 0.678579
            +vn 0.260750 0.006531 0.965361
            +vn 0.272500 -0.255898 0.927488
            +vn -0.395581 0.809961 -0.432905
            +vn -0.258827 0.918851 -0.297800
            +vn 0.004730 0.999878 0.013031
            +vn 0.466628 0.599780 0.649983
            +vn 0.621937 -0.400861 0.672628
            +vn 0.551042 -0.592181 0.587878
            +vn 0.649068 0.384991 -0.656087
            +vn 0.055971 0.691214 0.720450
            +vn -0.115940 0.804590 0.582354
            +vn -0.262185 0.897946 0.353435
            +vn -0.341655 0.885006 -0.316263
            +vn -0.081423 0.793085 -0.603626
            +vn -0.155675 0.857753 -0.489883
            +vn 0.728690 0.365978 0.578784
            +vn 0.318674 0.539384 0.779382
            +vn 0.953551 0.300150 -0.024415
            +vn -0.133976 0.836818 -0.530808
            +vn 0.095401 0.667959 -0.738029
            +vn 0.000000 0.999969 0.000000
            +vn -0.992523 -0.122013 0.000000
            +vn -0.937346 -0.348338 0.000000
            +vn -0.905148 -0.348827 -0.242836
            +vn -0.958617 -0.122227 -0.257057
            +vn -0.832057 0.554674 0.000000
            +vn -0.803217 0.555376 -0.215339
            +vn -0.048616 0.998810 0.000000
            +vn -0.046236 0.998840 -0.012726
            +vn 0.544267 0.838893 0.000000
            +vn 0.525376 0.839106 0.140843
            +vn 0.783471 0.621387 0.000000
            +vn 0.756371 0.621845 0.202918
            +vn 0.880886 0.473281 0.000000
            +vn 0.850551 0.473769 0.228217
            +vn -0.810907 -0.349376 -0.469375
            +vn -0.859004 -0.122410 -0.497085
            +vn -0.719657 0.555559 -0.416425
            +vn -0.041749 0.998810 -0.024415
            +vn 0.470077 0.839625 0.272011
            +vn 0.677236 0.622608 0.391980
            +vn 0.761803 0.474471 0.440962
            +vn -0.662465 -0.349620 -0.662465
            +vn -0.701773 -0.122440 -0.701773
            +vn -0.587878 0.555650 -0.587878
            +vn -0.034272 0.998810 -0.034272
            +vn 0.383831 0.839808 0.383831
            +vn 0.553148 0.622913 0.553148
            +vn 0.622303 0.474776 0.622303
            +vn -0.469375 -0.349376 -0.810907
            +vn -0.497085 -0.122379 -0.859004
            +vn -0.416425 0.555559 -0.719657
            +vn -0.024415 0.998810 -0.041749
            +vn 0.272011 0.839625 0.470077
            +vn 0.391980 0.622608 0.677236
            +vn 0.440962 0.474471 0.761834
            +vn -0.242836 -0.348827 -0.905148
            +vn -0.257057 -0.122227 -0.958617
            +vn -0.215339 0.555376 -0.803217
            +vn -0.012726 0.998840 -0.046205
            +vn 0.140843 0.839106 0.525376
            +vn 0.202918 0.621845 0.756371
            +vn 0.228217 0.473769 0.850551
            +vn 0.000000 -0.348338 -0.937346
            +vn 0.000000 -0.122013 -0.992523
            +vn 0.000000 0.554674 -0.832057
            +vn 0.000000 0.998810 -0.048616
            +vn 0.000000 0.838893 0.544267
            +vn 0.000000 0.621387 0.783471
            +vn 0.000000 0.473281 0.880886
            +vn 0.242836 -0.348827 -0.905148
            +vn 0.257057 -0.122227 -0.958617
            +vn 0.215308 0.555376 -0.803217
            +vn 0.012726 0.998840 -0.046205
            +vn -0.140843 0.839106 0.525376
            +vn -0.202918 0.621845 0.756340
            +vn -0.228217 0.473769 0.850551
            +vn 0.469375 -0.349376 -0.810907
            +vn 0.497085 -0.122379 -0.859004
            +vn 0.416425 0.555559 -0.719657
            +vn 0.024415 0.998810 -0.041749
            +vn -0.272011 0.839625 0.470077
            +vn -0.391980 0.622608 0.677236
            +vn -0.440962 0.474502 0.761803
            +vn 0.662465 -0.349620 -0.662465
            +vn 0.701773 -0.122471 -0.701773
            +vn 0.587878 0.555650 -0.587878
            +vn 0.034272 0.998810 -0.034272
            +vn -0.383831 0.839808 0.383831
            +vn -0.553148 0.622913 0.553148
            +vn -0.622303 0.474776 0.622303
            +vn 0.810907 -0.349406 -0.469375
            +vn 0.859004 -0.122379 -0.497085
            +vn 0.719657 0.555559 -0.416425
            +vn 0.041749 0.998810 -0.024415
            +vn -0.470077 0.839625 0.272011
            +vn -0.677236 0.622608 0.391980
            +vn -0.761803 0.474471 0.440962
            +vn 0.905148 -0.348827 -0.242836
            +vn 0.958617 -0.122227 -0.257057
            +vn 0.803217 0.555376 -0.215339
            +vn 0.046205 0.998840 -0.012726
            +vn -0.525376 0.839106 0.140843
            +vn -0.756340 0.621876 0.202918
            +vn -0.850551 0.473769 0.228217
            +vn 0.937346 -0.348338 0.000000
            +vn 0.992523 -0.122013 0.000000
            +vn 0.832026 0.554674 0.000000
            +vn 0.048616 0.998810 0.000000
            +vn -0.544267 0.838893 0.000000
            +vn -0.783471 0.621387 0.000000
            +vn 0.905148 -0.348827 0.242836
            +vn 0.958617 -0.122227 0.257057
            +vn 0.803217 0.555376 0.215308
            +vn 0.046205 0.998840 0.012726
            +vn -0.525376 0.839106 -0.140843
            +vn -0.756340 0.621876 -0.202918
            +vn 0.810907 -0.349406 0.469375
            +vn 0.859004 -0.122379 0.497085
            +vn 0.719657 0.555559 0.416425
            +vn 0.041749 0.998810 0.024415
            +vn -0.470077 0.839625 -0.272011
            +vn -0.677236 0.622608 -0.391980
            +vn -0.761803 0.474471 -0.440962
            +vn 0.662465 -0.349620 0.662465
            +vn 0.701773 -0.122471 0.701773
            +vn 0.587878 0.555650 0.587878
            +vn 0.034272 0.998810 0.034272
            +vn -0.383831 0.839808 -0.383831
            +vn -0.553148 0.622913 -0.553148
            +vn -0.622303 0.474776 -0.622303
            +vn 0.469375 -0.349376 0.810907
            +vn 0.497085 -0.122379 0.859004
            +vn 0.416425 0.555559 0.719657
            +vn 0.024415 0.998810 0.041749
            +vn -0.272011 0.839625 -0.470077
            +vn -0.391980 0.622608 -0.677236
            +vn -0.440962 0.474471 -0.761803
            +vn 0.242836 -0.348827 0.905148
            +vn 0.257057 -0.122227 0.958617
            +vn 0.215339 0.555376 0.803217
            +vn 0.012726 0.998840 0.046205
            +vn -0.140843 0.839106 -0.525376
            +vn -0.202918 0.621845 -0.756371
            +vn -0.228217 0.473769 -0.850551
            +vn 0.000000 -0.348338 0.937346
            +vn 0.000000 -0.122013 0.992523
            +vn 0.000000 0.554674 0.832057
            +vn 0.000000 0.998810 0.048616
            +vn 0.000000 0.838893 -0.544267
            +vn 0.000000 0.621387 -0.783471
            +vn 0.000000 0.473281 -0.880886
            +vn -0.242836 -0.348827 0.905148
            +vn -0.257057 -0.122227 0.958617
            +vn -0.215308 0.555376 0.803217
            +vn -0.012726 0.998840 0.046205
            +vn 0.140843 0.839106 -0.525376
            +vn 0.202918 0.621845 -0.756371
            +vn 0.228217 0.473769 -0.850551
            +vn -0.469375 -0.349376 0.810907
            +vn -0.497085 -0.122379 0.859004
            +vn -0.416425 0.555559 0.719657
            +vn -0.024415 0.998810 0.041749
            +vn 0.272011 0.839625 -0.470077
            +vn 0.391980 0.622608 -0.677236
            +vn 0.440962 0.474471 -0.761803
            +vn -0.662465 -0.349620 0.662465
            +vn -0.701773 -0.122440 0.701773
            +vn -0.587878 0.555650 0.587878
            +vn -0.034272 0.998810 0.034272
            +vn 0.383831 0.839808 -0.383831
            +vn 0.553148 0.622913 -0.553148
            +vn 0.622303 0.474776 -0.622303
            +vn -0.810907 -0.349376 0.469375
            +vn -0.859004 -0.122410 0.497085
            +vn -0.719657 0.555528 0.416425
            +vn -0.041749 0.998810 0.024415
            +vn 0.470077 0.839625 -0.272011
            +vn 0.677236 0.622639 -0.391980
            +vn 0.761803 0.474471 -0.440962
            +vn -0.905148 -0.348827 0.242836
            +vn -0.958617 -0.122227 0.257057
            +vn -0.803217 0.555376 0.215339
            +vn -0.046236 0.998840 0.012726
            +vn 0.525376 0.839106 -0.140843
            +vn 0.756371 0.621845 -0.202918
            +vn 0.850551 0.473769 -0.228217
            +vn 0.908292 0.418256 0.000000
            +vn 0.877041 0.418744 0.235298
            +vn 0.920286 0.391156 0.000000
            +vn 0.888668 0.391644 0.238441
            +vn 0.907315 0.342753 0.243446
            +vn 0.785638 0.419416 0.454756
            +vn 0.796075 0.392285 0.460799
            +vn 0.812830 0.343333 0.470504
            +vn 0.931486 0.265542 0.248543
            +vn 0.834162 0.266366 0.482864
            +vn 0.855312 0.152379 0.495132
            +vn 0.966613 -0.042848 0.252602
            +vn 0.864498 -0.045808 0.500504
            +vn 0.641804 0.419691 0.641804
            +vn 0.650349 0.392499 0.650349
            +vn 0.664052 0.343577 0.664052
            +vn 0.681509 0.266579 0.681509
            +vn 0.698813 0.152501 0.698813
            +vn 0.706351 -0.045869 0.706351
            +vn 0.454756 0.419416 0.785638
            +vn 0.460799 0.392285 0.796075
            +vn 0.470504 0.343333 0.812830
            +vn 0.482864 0.266366 0.834162
            +vn 0.495132 0.152409 0.855312
            +vn 0.500504 -0.045808 0.864498
            +vn 0.235298 0.418744 0.877041
            +vn 0.238441 0.391644 0.888668
            +vn 0.243446 0.342753 0.907315
            +vn 0.249855 0.265908 0.931028
            +vn 0.256172 0.152104 0.954558
            +vn 0.258980 -0.045717 0.964782
            +vn 0.000000 0.418256 0.908292
            +vn 0.000000 0.391156 0.920286
            +vn 0.000000 0.342357 0.939543
            +vn 0.000000 0.265542 0.964080
            +vn 0.000000 0.151891 0.988372
            +vn 0.000000 -0.045656 0.998932
            +vn -0.235298 0.418744 0.877041
            +vn -0.238441 0.391644 0.888668
            +vn -0.243446 0.342753 0.907315
            +vn -0.249855 0.265877 0.931028
            +vn -0.256172 0.152104 0.954558
            +vn -0.258980 -0.045717 0.964782
            +vn -0.454756 0.419416 0.785638
            +vn -0.460799 0.392285 0.796075
            +vn -0.470504 0.343333 0.812830
            +vn -0.482864 0.266366 0.834162
            +vn -0.495132 0.152379 0.855312
            +vn -0.500504 -0.045808 0.864498
            +vn -0.641804 0.419691 0.641804
            +vn -0.650349 0.392499 0.650349
            +vn -0.664052 0.343577 0.664052
            +vn -0.681509 0.266579 0.681509
            +vn -0.698813 0.152501 0.698813
            +vn -0.706351 -0.045869 0.706351
            +vn -0.785638 0.419416 0.454756
            +vn -0.796075 0.392285 0.460799
            +vn -0.812830 0.343364 0.470504
            +vn -0.834162 0.266366 0.482864
            +vn -0.855312 0.152379 0.495132
            +vn -0.864498 -0.045808 0.500504
            +vn -0.907315 0.342753 0.243446
            +vn -0.931028 0.265908 0.249855
            +vn -0.954558 0.152104 0.256172
            +vn -0.964782 -0.045717 0.258980
            +vn -0.939543 0.342357 0.000000
            +vn -0.964080 0.265542 0.000000
            +vn -0.988372 0.151891 0.000000
            +vn -0.888668 0.391644 -0.238441
            +vn -0.907315 0.342753 -0.243446
            +vn -0.931028 0.265877 -0.249855
            +vn -0.954558 0.152104 -0.256172
            +vn -0.785638 0.419416 -0.454756
            +vn -0.796075 0.392285 -0.460799
            +vn -0.812830 0.343333 -0.470504
            +vn -0.834162 0.266366 -0.482864
            +vn -0.855312 0.152379 -0.495132
            +vn -0.964782 -0.045717 -0.258980
            +vn -0.864498 -0.045808 -0.500504
            +vn -0.641804 0.419691 -0.641804
            +vn -0.650349 0.392499 -0.650349
            +vn -0.664052 0.343577 -0.664052
            +vn -0.681509 0.266579 -0.681509
            +vn -0.698813 0.152501 -0.698813
            +vn -0.706351 -0.045869 -0.706351
            +vn -0.454756 0.419416 -0.785638
            +vn -0.460799 0.392285 -0.796075
            +vn -0.470504 0.343333 -0.812830
            +vn -0.482864 0.266366 -0.834162
            +vn -0.495132 0.152379 -0.855312
            +vn -0.500504 -0.045808 -0.864498
            +vn -0.235298 0.418744 -0.877041
            +vn -0.238441 0.391644 -0.888668
            +vn -0.243446 0.342753 -0.907315
            +vn -0.249855 0.265908 -0.931028
            +vn -0.256172 0.152104 -0.954558
            +vn -0.258980 -0.045717 -0.964782
            +vn 0.000000 0.418256 -0.908292
            +vn 0.000000 0.391156 -0.920286
            +vn 0.000000 0.342357 -0.939543
            +vn 0.000000 0.265542 -0.964080
            +vn 0.000000 0.151891 -0.988372
            +vn 0.000000 -0.045656 -0.998932
            +vn 0.235298 0.418744 -0.877041
            +vn 0.238441 0.391644 -0.888668
            +vn 0.243446 0.342753 -0.907315
            +vn 0.249855 0.265877 -0.931028
            +vn 0.256172 0.152104 -0.954558
            +vn 0.258980 -0.045717 -0.964782
            +vn 0.454756 0.419416 -0.785638
            +vn 0.460799 0.392285 -0.796075
            +vn 0.470504 0.343333 -0.812830
            +vn 0.482864 0.266366 -0.834162
            +vn 0.495132 0.152379 -0.855312
            +vn 0.500504 -0.045808 -0.864498
            +vn 0.641804 0.419691 -0.641804
            +vn 0.650349 0.392499 -0.650349
            +vn 0.664052 0.343577 -0.664052
            +vn 0.681509 0.266579 -0.681509
            +vn 0.698813 0.152501 -0.698813
            +vn 0.706351 -0.045869 -0.706351
            +vn 0.785638 0.419416 -0.454756
            +vn 0.796075 0.392285 -0.460799
            +vn 0.812830 0.343364 -0.470504
            +vn 0.834162 0.266366 -0.482864
            +vn 0.855312 0.152379 -0.495132
            +vn 0.864498 -0.045808 -0.500504
            +vn 0.877041 0.418744 -0.235298
            +vn 0.888668 0.391644 -0.238441
            +vn 0.907315 0.342753 -0.243446
            +vn 0.795892 -0.566485 0.213538
            +vn 0.712180 -0.701987 0.000000
            +vn 0.687399 -0.702445 0.184393
            +vn 0.652974 -0.757347 0.000000
            +vn 0.630146 -0.757805 0.169012
            +vn 0.724021 -0.689749 0.000000
            +vn 0.698752 -0.690329 0.187414
            +vn 0.886410 -0.462874 0.000000
            +vn 0.855861 -0.463454 0.229530
            +vn 0.817774 -0.327158 0.473434
            +vn 0.712729 -0.567248 0.412549
            +vn 0.615345 -0.703146 0.356151
            +vn 0.564043 -0.758446 0.326456
            +vn 0.625660 -0.690939 0.362102
            +vn 0.766625 -0.464125 0.443678
            +vn 0.668111 -0.327403 0.668111
            +vn 0.582171 -0.567522 0.582171
            +vn 0.502579 -0.703421 0.502579
            +vn 0.460646 -0.758660 0.460646
            +vn 0.510971 -0.691183 0.510971
            +vn 0.626209 -0.464370 0.626240
            +vn 0.473434 -0.327158 0.817774
            +vn 0.412549 -0.567248 0.712729
            +vn 0.356151 -0.703146 0.615375
            +vn 0.326456 -0.758446 0.564043
            +vn 0.362102 -0.690939 0.625660
            +vn 0.443678 -0.464125 0.766625
            +vn 0.245003 -0.326609 0.912839
            +vn 0.213538 -0.566485 0.795892
            +vn 0.184393 -0.702445 0.687399
            +vn 0.169012 -0.757805 0.630146
            +vn 0.187414 -0.690329 0.698752
            +vn 0.229530 -0.463454 0.855831
            +vn 0.000000 -0.326243 0.945250
            +vn 0.000000 -0.565996 0.824396
            +vn 0.000000 -0.701987 0.712180
            +vn 0.000000 -0.757347 0.652974
            +vn 0.000000 -0.689749 0.724021
            +vn 0.000000 -0.462905 0.886380
            +vn -0.245003 -0.326609 0.912839
            +vn -0.213538 -0.566485 0.795892
            +vn -0.184393 -0.702445 0.687399
            +vn -0.169012 -0.757805 0.630146
            +vn -0.187414 -0.690329 0.698752
            +vn -0.229530 -0.463454 0.855861
            +vn -0.473434 -0.327158 0.817774
            +vn -0.412549 -0.567248 0.712729
            +vn -0.356151 -0.703146 0.615375
            +vn -0.326456 -0.758446 0.564043
            +vn -0.362102 -0.690939 0.625660
            +vn -0.443678 -0.464125 0.766625
            +vn -0.668111 -0.327403 0.668111
            +vn -0.582171 -0.567522 0.582171
            +vn -0.502579 -0.703421 0.502579
            +vn -0.460646 -0.758660 0.460646
            +vn -0.510971 -0.691183 0.510971
            +vn -0.626209 -0.464370 0.626209
            +vn -0.817774 -0.327158 0.473434
            +vn -0.712729 -0.567248 0.412549
            +vn -0.615375 -0.703146 0.356151
            +vn -0.564043 -0.758446 0.326456
            +vn -0.625660 -0.690939 0.362102
            +vn -0.766625 -0.464125 0.443678
            +vn -0.912931 -0.326609 0.244575
            +vn -0.687399 -0.702445 0.184393
            +vn -0.630146 -0.757805 0.169012
            +vn -0.698752 -0.690329 0.187414
            +vn -0.855831 -0.463485 0.229530
            +vn -0.824396 -0.565996 0.000000
            +vn -0.712180 -0.701987 0.000000
            +vn -0.652974 -0.757347 0.000000
            +vn -0.724021 -0.689749 0.000000
            +vn -0.886410 -0.462874 0.000000
            +vn -0.795892 -0.566485 -0.213538
            +vn -0.687399 -0.702445 -0.184393
            +vn -0.630146 -0.757805 -0.169012
            +vn -0.698752 -0.690329 -0.187414
            +vn -0.855831 -0.463454 -0.229530
            +vn -0.817774 -0.327158 -0.473434
            +vn -0.712729 -0.567217 -0.412549
            +vn -0.615375 -0.703146 -0.356151
            +vn -0.564043 -0.758446 -0.326456
            +vn -0.625660 -0.690939 -0.362102
            +vn -0.766625 -0.464125 -0.443678
            +vn -0.668111 -0.327403 -0.668111
            +vn -0.582171 -0.567522 -0.582171
            +vn -0.502579 -0.703421 -0.502579
            +vn -0.460646 -0.758660 -0.460646
            +vn -0.510971 -0.691183 -0.510971
            +vn -0.626209 -0.464370 -0.626209
            +vn -0.473434 -0.327158 -0.817774
            +vn -0.412549 -0.567248 -0.712729
            +vn -0.356151 -0.703146 -0.615375
            +vn -0.326456 -0.758446 -0.564043
            +vn -0.362102 -0.690939 -0.625660
            +vn -0.443678 -0.464125 -0.766625
            +vn -0.245003 -0.326609 -0.912839
            +vn -0.213538 -0.566485 -0.795892
            +vn -0.184393 -0.702445 -0.687399
            +vn -0.169012 -0.757805 -0.630146
            +vn -0.187414 -0.690329 -0.698752
            +vn -0.229530 -0.463454 -0.855831
            +vn 0.000000 -0.326243 -0.945250
            +vn 0.000000 -0.565996 -0.824396
            +vn 0.000000 -0.701987 -0.712180
            +vn 0.000000 -0.757347 -0.652974
            +vn 0.000000 -0.689749 -0.724021
            +vn 0.000000 -0.462905 -0.886380
            +vn 0.245003 -0.326609 -0.912839
            +vn 0.213538 -0.566485 -0.795892
            +vn 0.184393 -0.702445 -0.687399
            +vn 0.169012 -0.757805 -0.630146
            +vn 0.187445 -0.690329 -0.698752
            +vn 0.229530 -0.463454 -0.855861
            +vn 0.473434 -0.327158 -0.817774
            +vn 0.412549 -0.567248 -0.712729
            +vn 0.356151 -0.703146 -0.615375
            +vn 0.326456 -0.758446 -0.564043
            +vn 0.362102 -0.690939 -0.625660
            +vn 0.443678 -0.464125 -0.766625
            +vn 0.668111 -0.327403 -0.668111
            +vn 0.582171 -0.567522 -0.582171
            +vn 0.502579 -0.703421 -0.502579
            +vn 0.460646 -0.758660 -0.460646
            +vn 0.510971 -0.691183 -0.510971
            +vn 0.626209 -0.464370 -0.626209
            +vn 0.817774 -0.327158 -0.473434
            +vn 0.712729 -0.567248 -0.412549
            +vn 0.615375 -0.703146 -0.356151
            +vn 0.564043 -0.758446 -0.326456
            +vn 0.625660 -0.690939 -0.362102
            +vn 0.766625 -0.464125 -0.443678
            +vn 0.912839 -0.326609 -0.244942
            +vn 0.795892 -0.566485 -0.213538
            +vn 0.687399 -0.702445 -0.184393
            +vn 0.630146 -0.757805 -0.169012
            +vn 0.698752 -0.690329 -0.187414
            +vn 0.855861 -0.463454 -0.229530
            +vn 0.025666 -0.999664 0.000000
            +vn 0.000000 -1.000000 0.000000
            +vn 0.024781 -0.999664 -0.006623
            +vn 0.068667 -0.997620 0.000000
            +vn 0.066256 -0.997620 -0.017731
            +vn 0.157170 -0.987548 0.000000
            +vn 0.151677 -0.987579 -0.040620
            +vn 0.373150 -0.927763 0.000000
            +vn 0.360118 -0.927885 -0.096469
            +vn 0.789148 -0.614154 0.000000
            +vn 0.762017 -0.614399 -0.204505
            +vn 0.022156 -0.999664 -0.012787
            +vn 0.059236 -0.997650 -0.034272
            +vn 0.135624 -0.987640 -0.078463
            +vn 0.322153 -0.928129 -0.186377
            +vn 0.682333 -0.615131 -0.394971
            +vn 0.018067 -0.999664 -0.018067
            +vn 0.048341 -0.997650 -0.048341
            +vn 0.110691 -0.987640 -0.110691
            +vn 0.262947 -0.928251 -0.262947
            +vn 0.557329 -0.615375 -0.557329
            +vn 0.012787 -0.999664 -0.022156
            +vn 0.034272 -0.997650 -0.059236
            +vn 0.078463 -0.987640 -0.135624
            +vn 0.186377 -0.928129 -0.322153
            +vn 0.394971 -0.615131 -0.682302
            +vn 0.006623 -0.999664 -0.024781
            +vn 0.017731 -0.997620 -0.066256
            +vn 0.040620 -0.987579 -0.151677
            +vn 0.096469 -0.927885 -0.360118
            +vn 0.204474 -0.614399 -0.762017
            +vn 0.000000 -0.999664 -0.025666
            +vn 0.000000 -0.997620 -0.068667
            +vn 0.000000 -0.987548 -0.157170
            +vn 0.000000 -0.927763 -0.373150
            +vn 0.000000 -0.614154 -0.789148
            +vn -0.006623 -0.999664 -0.024781
            +vn -0.017731 -0.997620 -0.066256
            +vn -0.040620 -0.987579 -0.151677
            +vn -0.096469 -0.927885 -0.360118
            +vn -0.204474 -0.614399 -0.762017
            +vn -0.012787 -0.999664 -0.022156
            +vn -0.034272 -0.997650 -0.059236
            +vn -0.078463 -0.987640 -0.135624
            +vn -0.186377 -0.928129 -0.322153
            +vn -0.394971 -0.615131 -0.682333
            +vn -0.018067 -0.999664 -0.018067
            +vn -0.048341 -0.997650 -0.048341
            +vn -0.110691 -0.987640 -0.110691
            +vn -0.262947 -0.928251 -0.262947
            +vn -0.557329 -0.615375 -0.557329
            +vn -0.022156 -0.999664 -0.012787
            +vn -0.059236 -0.997650 -0.034272
            +vn -0.135624 -0.987640 -0.078463
            +vn -0.322153 -0.928129 -0.186377
            +vn -0.682302 -0.615131 -0.394971
            +vn -0.024781 -0.999664 -0.006623
            +vn -0.066256 -0.997620 -0.017731
            +vn -0.151677 -0.987579 -0.040620
            +vn -0.360118 -0.927885 -0.096469
            +vn -0.762017 -0.614399 -0.204474
            +vn -0.025666 -0.999664 0.000000
            +vn -0.068667 -0.997620 0.000000
            +vn -0.157170 -0.987548 0.000000
            +vn -0.373150 -0.927763 0.000000
            +vn -0.789148 -0.614154 0.000000
            +vn -0.024781 -0.999664 0.006623
            +vn -0.066256 -0.997620 0.017731
            +vn -0.151677 -0.987579 0.040620
            +vn -0.360149 -0.927885 0.096469
            +vn -0.762017 -0.614399 0.204474
            +vn -0.022156 -0.999664 0.012787
            +vn -0.059236 -0.997650 0.034272
            +vn -0.135624 -0.987640 0.078463
            +vn -0.322153 -0.928129 0.186377
            +vn -0.682333 -0.615131 0.394971
            +vn -0.018067 -0.999664 0.018067
            +vn -0.048341 -0.997650 0.048341
            +vn -0.110691 -0.987640 0.110691
            +vn -0.262947 -0.928251 0.262947
            +vn -0.557329 -0.615375 0.557329
            +vn -0.012787 -0.999664 0.022156
            +vn -0.034272 -0.997650 0.059236
            +vn -0.078463 -0.987640 0.135624
            +vn -0.186377 -0.928129 0.322153
            +vn -0.394971 -0.615131 0.682302
            +vn -0.006623 -0.999664 0.024781
            +vn -0.017731 -0.997620 0.066256
            +vn -0.040620 -0.987579 0.151677
            +vn -0.096469 -0.927885 0.360118
            +vn -0.204474 -0.614399 0.762017
            +vn 0.000000 -0.999664 0.025666
            +vn 0.000000 -0.997620 0.068667
            +vn 0.000000 -0.987548 0.157170
            +vn 0.000000 -0.927763 0.373150
            +vn 0.000000 -0.614154 0.789148
            +vn 0.006623 -0.999664 0.024781
            +vn 0.017731 -0.997620 0.066256
            +vn 0.040620 -0.987579 0.151677
            +vn 0.096469 -0.927885 0.360149
            +vn 0.204474 -0.614399 0.762017
            +vn 0.012787 -0.999664 0.022156
            +vn 0.034272 -0.997650 0.059236
            +vn 0.078463 -0.987640 0.135624
            +vn 0.186377 -0.928129 0.322153
            +vn 0.394971 -0.615131 0.682333
            +vn 0.018067 -0.999664 0.018067
            +vn 0.048341 -0.997650 0.048341
            +vn 0.110691 -0.987640 0.110691
            +vn 0.262947 -0.928251 0.262947
            +vn 0.557329 -0.615375 0.557329
            +vn 0.022156 -0.999664 0.012787
            +vn 0.059236 -0.997650 0.034272
            +vn 0.135624 -0.987640 0.078463
            +vn 0.322153 -0.928129 0.186346
            +vn 0.682302 -0.615131 0.394971
            +vn 0.024781 -0.999664 0.006623
            +vn 0.066256 -0.997620 0.017731
            +vn 0.151677 -0.987579 0.040620
            +vn 0.360118 -0.927885 0.096469
            +vn 0.762017 -0.614399 0.204474
            +vn 0.464827 -0.373638 -0.802667
            +vn 0.655812 -0.373882 -0.655812
            +vn 0.000000 -0.372539 0.927976
            +vn -0.240699 -0.373028 0.896023
            +vn -0.802667 -0.373608 0.464827
            +vn 0.896023 -0.372997 -0.240699
            +vn -0.927976 -0.372539 0.000000
            +vn 0.927976 -0.372539 0.000000
            +vn 0.717063 0.696982 0.000000
            +vn 0.990387 -0.138310 -0.000061
            +vn 0.956694 -0.138737 0.255806
            +vn 0.692129 0.697470 0.185583
            +vn 0.857326 -0.139317 0.495529
            +vn 0.620045 0.697653 0.358837
            +vn 0.700125 -0.139531 0.700217
            +vn 0.506516 0.697714 0.506546
            +vn 0.495468 -0.139286 0.857356
            +vn 0.358776 0.697714 0.620014
            +vn 0.255867 -0.138737 0.956694
            +vn 0.185583 0.697531 0.692068
            +vn 0.000061 -0.138310 0.990387
            +vn 0.000000 0.696982 0.717063
            +vn -0.255806 -0.138737 0.956694
            +vn -0.185583 0.697470 0.692129
            +vn -0.495529 -0.139317 0.857326
            +vn -0.358837 0.697653 0.620045
            +vn -0.700217 -0.139531 0.700156
            +vn -0.506546 0.697714 0.506516
            +vn -0.857356 -0.139286 0.495468
            +vn -0.620014 0.697714 0.358776
            +vn -0.956694 -0.138737 0.255867
            +vn -0.692068 0.697531 0.185583
            +vn -0.990387 -0.138310 0.000061
            +vn -0.717063 0.696982 0.000000
            +vn -0.956694 -0.138737 -0.255806
            +vn -0.692129 0.697470 -0.185583
            +vn -0.857326 -0.139317 -0.495529
            +vn -0.620045 0.697653 -0.358837
            +vn -0.700125 -0.139531 -0.700217
            +vn -0.506516 0.697714 -0.506546
            +vn -0.495468 -0.139286 -0.857356
            +vn -0.358776 0.697714 -0.620014
            +vn -0.255867 -0.138737 -0.956694
            +vn -0.185583 0.697531 -0.692068
            +vn -0.000061 -0.138310 -0.990387
            +vn 0.000000 0.696982 -0.717063
            +vn 0.255806 -0.138737 -0.956694
            +vn 0.185583 0.697470 -0.692129
            +vn 0.495529 -0.139317 -0.857326
            +vn 0.358837 0.697653 -0.620045
            +vn 0.700217 -0.139531 -0.700156
            +vn 0.506546 0.697714 -0.506516
            +vn 0.857356 -0.139286 -0.495468
            +vn 0.620014 0.697714 -0.358776
            +vn 0.956694 -0.138737 -0.255867
            +vn 0.692068 0.697531 -0.185583
            +vn 0.292520 0.956236 0.000000
            +vn 0.282083 0.956389 0.075686
            +vn 0.177953 0.984008 0.000000
            +vn 0.171606 0.984069 0.046022
            +vn 0.158879 0.987274 0.000000
            +vn 0.153264 0.987304 0.041078
            +vn 0.217719 0.975982 0.000000
            +vn 0.210059 0.976043 0.056276
            +vn 0.504715 0.863277 0.000000
            +vn 0.487197 0.863460 0.130558
            +vn 0.693258 0.720664 0.000000
            +vn 0.669057 0.721183 0.179449
            +vn 0.252388 0.956511 0.146092
            +vn 0.153508 0.984130 0.088839
            +vn 0.137059 0.987365 0.079318
            +vn 0.187872 0.976135 0.108676
            +vn 0.435926 0.863887 0.252205
            +vn 0.598956 0.721824 0.346660
            +vn 0.206091 0.956572 0.206091
            +vn 0.125340 0.984161 0.125340
            +vn 0.111911 0.987396 0.111911
            +vn 0.153356 0.976196 0.153356
            +vn 0.355907 0.864071 0.355907
            +vn 0.489151 0.722098 0.489151
            +vn 0.146092 0.956511 0.252388
            +vn 0.088839 0.984130 0.153508
            +vn 0.079318 0.987365 0.137059
            +vn 0.108676 0.976135 0.187872
            +vn 0.252205 0.863887 0.435926
            +vn 0.346660 0.721824 0.598956
            +vn 0.075686 0.956389 0.282083
            +vn 0.046022 0.984069 0.171606
            +vn 0.041078 0.987304 0.153264
            +vn 0.056276 0.976043 0.210059
            +vn 0.130558 0.863460 0.487197
            +vn 0.179449 0.721183 0.669057
            +vn 0.000000 0.956236 0.292520
            +vn 0.000000 0.984008 0.177953
            +vn 0.000000 0.987274 0.158879
            +vn 0.000000 0.975982 0.217719
            +vn 0.000000 0.863277 0.504715
            +vn 0.000000 0.720664 0.693258
            +vn -0.075686 0.956389 0.282083
            +vn -0.046022 0.984069 0.171606
            +vn -0.041078 0.987304 0.153264
            +vn -0.056276 0.976043 0.210059
            +vn -0.130558 0.863460 0.487197
            +vn -0.179449 0.721183 0.669057
            +vn -0.146092 0.956511 0.252388
            +vn -0.088839 0.984130 0.153508
            +vn -0.079318 0.987365 0.137059
            +vn -0.108676 0.976135 0.187872
            +vn -0.252205 0.863887 0.435926
            +vn -0.346660 0.721824 0.598956
            +vn -0.206091 0.956572 0.206091
            +vn -0.125340 0.984161 0.125340
            +vn -0.111911 0.987396 0.111911
            +vn -0.153356 0.976196 0.153356
            +vn -0.355907 0.864071 0.355907
            +vn -0.489151 0.722098 0.489151
            +vn -0.252388 0.956511 0.146092
            +vn -0.153508 0.984130 0.088839
            +vn -0.137059 0.987365 0.079318
            +vn -0.187872 0.976135 0.108676
            +vn -0.435926 0.863887 0.252205
            +vn -0.598956 0.721824 0.346660
            +vn -0.282083 0.956389 0.075686
            +vn -0.171606 0.984069 0.046022
            +vn -0.153264 0.987304 0.041078
            +vn -0.210059 0.976043 0.056276
            +vn -0.487197 0.863460 0.130558
            +vn -0.669057 0.721183 0.179449
            +vn -0.292520 0.956236 0.000000
            +vn -0.177953 0.984008 0.000000
            +vn -0.158879 0.987274 0.000000
            +vn -0.217719 0.975982 0.000000
            +vn -0.504715 0.863277 0.000000
            +vn -0.693258 0.720664 0.000000
            +vn -0.282083 0.956389 -0.075686
            +vn -0.171606 0.984069 -0.046022
            +vn -0.153264 0.987304 -0.041078
            +vn -0.210059 0.976043 -0.056276
            +vn -0.487197 0.863460 -0.130558
            +vn -0.669057 0.721183 -0.179449
            +vn -0.252388 0.956511 -0.146092
            +vn -0.153508 0.984130 -0.088839
            +vn -0.137059 0.987365 -0.079318
            +vn -0.187872 0.976135 -0.108676
            +vn -0.435926 0.863887 -0.252205
            +vn -0.598956 0.721824 -0.346660
            +vn -0.206091 0.956572 -0.206091
            +vn -0.125340 0.984161 -0.125340
            +vn -0.111911 0.987396 -0.111911
            +vn -0.153356 0.976196 -0.153356
            +vn -0.355907 0.864071 -0.355907
            +vn -0.489151 0.722098 -0.489151
            +vn -0.146092 0.956511 -0.252388
            +vn -0.088839 0.984130 -0.153508
            +vn -0.079318 0.987365 -0.137059
            +vn -0.108676 0.976135 -0.187872
            +vn -0.252205 0.863887 -0.435926
            +vn -0.346660 0.721824 -0.598956
            +vn -0.075686 0.956389 -0.282083
            +vn -0.046022 0.984069 -0.171606
            +vn -0.041078 0.987304 -0.153264
            +vn -0.056276 0.976043 -0.210059
            +vn -0.130558 0.863460 -0.487197
            +vn -0.179449 0.721183 -0.669057
            +vn 0.000000 0.956236 -0.292520
            +vn 0.000000 0.984008 -0.177953
            +vn 0.000000 0.987274 -0.158879
            +vn 0.000000 0.975982 -0.217719
            +vn 0.000000 0.863277 -0.504715
            +vn 0.000000 0.720664 -0.693258
            +vn 0.075686 0.956389 -0.282083
            +vn 0.046022 0.984069 -0.171606
            +vn 0.041078 0.987304 -0.153264
            +vn 0.056276 0.976043 -0.210059
            +vn 0.130558 0.863460 -0.487197
            +vn 0.179449 0.721183 -0.669057
            +vn 0.146092 0.956511 -0.252388
            +vn 0.088839 0.984130 -0.153508
            +vn 0.079318 0.987365 -0.137059
            +vn 0.108676 0.976135 -0.187872
            +vn 0.252205 0.863887 -0.435926
            +vn 0.346660 0.721824 -0.598956
            +vn 0.206091 0.956572 -0.206091
            +vn 0.125340 0.984161 -0.125340
            +vn 0.111911 0.987396 -0.111911
            +vn 0.153356 0.976196 -0.153356
            +vn 0.355907 0.864071 -0.355907
            +vn 0.489151 0.722098 -0.489151
            +vn 0.252388 0.956511 -0.146092
            +vn 0.153508 0.984130 -0.088839
            +vn 0.137059 0.987365 -0.079318
            +vn 0.187872 0.976135 -0.108676
            +vn 0.435926 0.863887 -0.252205
            +vn 0.598956 0.721824 -0.346660
            +vn 0.282083 0.956389 -0.075686
            +vn 0.171606 0.984069 -0.046022
            +vn 0.153264 0.987304 -0.041078
            +vn 0.210059 0.976043 -0.056276
            +vn 0.487197 0.863460 -0.130558
            +vn 0.669057 0.721183 -0.179449
            +vn 0.363842 0.931455 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.351451 0.931516 0.093509
            +vn 0.968261 0.249916 0.000000
            +vn 0.935423 0.249763 0.250130
            +vn 0.842860 -0.538102 0.000000
            +vn 0.813959 -0.538713 0.217292
            +vn 0.786767 -0.617206 -0.000031
            +vn 0.759514 -0.618000 0.202857
            +vn 0.314432 0.931791 0.181280
            +vn 0.838404 0.249855 0.484359
            +vn 0.729026 -0.539720 0.420911
            +vn 0.680013 -0.619068 0.392743
            +vn 0.256386 0.931913 0.256417
            +vn 0.684652 0.249886 0.684652
            +vn 0.595050 -0.540147 0.595050
            +vn 0.555010 -0.619526 0.555040
            +vn 0.181280 0.931791 0.314432
            +vn 0.484359 0.249825 0.838404
            +vn 0.420881 -0.539720 0.729026
            +vn 0.392712 -0.619098 0.680013
            +vn 0.093509 0.931516 0.351451
            +vn 0.250160 0.249763 0.935423
            +vn 0.217322 -0.538713 0.813959
            +vn 0.202887 -0.618030 0.759484
            +vn 0.000000 0.931455 0.363842
            +vn 0.000000 0.249916 0.968261
            +vn 0.000000 -0.538102 0.842860
            +vn 0.000031 -0.617206 0.786767
            +vn -0.093509 0.931516 0.351451
            +vn -0.250130 0.249763 0.935423
            +vn -0.217292 -0.538682 0.813959
            +vn -0.202857 -0.618000 0.759514
            +vn -0.181280 0.931791 0.314432
            +vn -0.484359 0.249855 0.838404
            +vn -0.420911 -0.539720 0.729026
            +vn -0.392743 -0.619068 0.680013
            +vn -0.256417 0.931913 0.256386
            +vn -0.684652 0.249886 0.684652
            +vn -0.595050 -0.540147 0.595050
            +vn -0.555040 -0.619526 0.555010
            +vn -0.314432 0.931791 0.181280
            +vn -0.838404 0.249825 0.484359
            +vn -0.729026 -0.539720 0.420881
            +vn -0.680013 -0.619098 0.392712
            +vn -0.351451 0.931516 0.093509
            +vn -0.935423 0.249763 0.250160
            +vn -0.813959 -0.538713 0.217292
            +vn -0.759484 -0.618030 0.202887
            +vn -0.363842 0.931455 0.000000
            +vn -0.968261 0.249916 0.000000
            +vn -0.842860 -0.538102 0.000000
            +vn -0.786767 -0.617206 0.000031
            +vn -0.351451 0.931516 -0.093509
            +vn -0.935423 0.249763 -0.250130
            +vn -0.813959 -0.538713 -0.217292
            +vn -0.759514 -0.618000 -0.202857
            +vn -0.314432 0.931791 -0.181280
            +vn -0.838404 0.249855 -0.484359
            +vn -0.729026 -0.539720 -0.420911
            +vn -0.680013 -0.619068 -0.392743
            +vn -0.256386 0.931913 -0.256417
            +vn -0.684652 0.249886 -0.684652
            +vn -0.595050 -0.540147 -0.595050
            +vn -0.555010 -0.619526 -0.555040
            +vn -0.181280 0.931791 -0.314432
            +vn -0.484359 0.249825 -0.838404
            +vn -0.420881 -0.539720 -0.729026
            +vn -0.392712 -0.619098 -0.680013
            +vn -0.093509 0.931516 -0.351451
            +vn -0.250160 0.249763 -0.935423
            +vn -0.217322 -0.538713 -0.813959
            +vn -0.202887 -0.618030 -0.759484
            +vn 0.000000 0.931455 -0.363842
            +vn 0.000000 0.249916 -0.968261
            +vn 0.000000 -0.538102 -0.842860
            +vn -0.000031 -0.617206 -0.786767
            +vn 0.093509 0.931516 -0.351451
            +vn 0.250130 0.249763 -0.935423
            +vn 0.217292 -0.538682 -0.813959
            +vn 0.202857 -0.618000 -0.759514
            +vn 0.181280 0.931791 -0.314432
            +vn 0.484359 0.249855 -0.838404
            +vn 0.420911 -0.539720 -0.729026
            +vn 0.392743 -0.619068 -0.680013
            +vn 0.256417 0.931913 -0.256386
            +vn 0.684652 0.249886 -0.684652
            +vn 0.595050 -0.540147 -0.595050
            +vn 0.555040 -0.619526 -0.555010
            +vn 0.314432 0.931791 -0.181280
            +vn 0.838404 0.249825 -0.484359
            +vn 0.729026 -0.539720 -0.420881
            +vn 0.680013 -0.619098 -0.392712
            +vn 0.351451 0.931516 -0.093509
            +vn 0.935423 0.249763 -0.250160
            +vn 0.813959 -0.538713 -0.217292
            +vn 0.759484 -0.618030 -0.202887
            +vn -0.354198 0.930296 -0.095187
            +vn 0.095187 0.930296 0.354198
            +vn 0.354198 0.930296 0.095187
            +vn 0.183721 0.930387 0.317179
            +vn -0.183721 0.930387 -0.317179
            +vn -0.367443 0.930021 0.000000
            +vn -0.183721 0.930387 0.317179
            +vn 0.367412 0.930021 0.000000
            +vn -0.317179 0.930387 0.183721
            +vn -0.095187 0.930296 -0.354198
            +vn 0.000000 0.930021 -0.367443
            +vn -0.354198 0.930296 0.095187
            +vn 0.095187 0.930296 -0.354198
            +vn 0.000000 0.930021 0.367443
            +vn -0.317179 0.930387 -0.183721
            +vn 0.317179 0.930387 -0.183721
            +vn -0.095187 0.930296 0.354198
            +vn 0.317179 0.930387 0.183721
            +vn 0.354198 0.930296 -0.095187
            +vn 0.183721 0.930387 -0.317179
            +vn -0.034730 0.999390 0.000000
            +vn 0.033479 0.999390 -0.009003
            +vn 0.034730 0.999390 0.000000
            +vn 0.009003 0.999390 -0.033479
            +vn 0.000000 0.999390 -0.034730
            +vn -0.259163 0.930387 0.259163
            +vn -0.017335 0.999390 0.029939
            +vn 0.947539 0.295083 0.122654
            +vn -0.004486 0.999969 0.000000
            +vn -0.004151 0.950468 0.310739
            +vn -0.003021 0.719291 0.694662
            +vn -0.998688 0.050722 0.000000
            +vn -0.003143 0.719321 -0.694632
            +vn 0.970214 0.213324 -0.114505
            +vn -0.136235 0.879482 -0.455947
            +vn 0.949858 0.312662 0.000000
            +vn 0.055757 -0.017579 -0.998260
            +vn 0.201300 -0.540880 -0.816645
            +vn 0.974456 -0.186071 -0.125645
            +vn 0.988098 -0.096286 0.119938
            +vn 0.974456 -0.186041 0.125614
            +vn -0.879574 -0.475723 0.000000
            +vn -0.873775 -0.472610 -0.114475
            +vn 0.988067 -0.096286 -0.119938
            +vn 0.295480 -0.855464 -0.425214
            +vn -0.976196 -0.174993 -0.127903
            +vn -0.971007 -0.205725 0.121677
            +vn -0.976196 -0.174963 0.127903
            +vn -0.976196 -0.174993 0.127903
            +vn 0.896054 -0.372997 0.240699
            +vn -0.802667 -0.373638 -0.464827
            +vn -0.655812 -0.373852 -0.655812
            +vn -0.240699 -0.373028 -0.896023
            +vn -0.464827 -0.373638 -0.802667
            +vn -0.896023 -0.373028 0.240699
            +vn 0.000000 -0.372539 -0.927976
            +vn -0.655812 -0.373852 0.655812
            +vn 0.240699 -0.373028 0.896023
            +vn -0.896023 -0.373028 -0.240699
            +vn 0.802667 -0.373638 -0.464827
            +vn 0.655812 -0.373882 0.655812
            +vn 0.464827 -0.373638 0.802667
            +vn -0.464827 -0.373638 0.802667
            +vn 0.240699 -0.373028 -0.896023
            +vn 0.802667 -0.373638 0.464827
            +vn -0.033479 0.999390 0.009003
            +vn -0.259163 0.930387 -0.259163
            +vn -0.024445 0.999390 -0.024445
            +vn -0.029939 0.999390 -0.017335
            +vn 0.259163 0.930387 -0.259163
            +vn 0.024445 0.999390 -0.024445
            +vn 0.017335 0.999390 -0.029939
            +vn 0.029939 0.999390 -0.017335
            +vn 0.033479 0.999390 0.009003
            +vn -0.009003 0.999390 0.033479
            +vn 0.000000 0.999390 0.034730
            +vn -0.017335 0.999390 -0.029939
            +vn 0.259163 0.930387 0.259163
            +vn 0.029939 0.999390 0.017335
            +vn -0.009003 0.999390 -0.033479
            +vn 0.024445 0.999390 0.024445
            +vn 0.017335 0.999390 0.029939
            +vn 0.009003 0.999390 0.033479
            +vn -0.033479 0.999390 -0.009003
            +vn -0.024445 0.999390 0.024445
            +vn -0.029939 0.999390 0.017335
            +vn 0.055757 -0.017579 0.998260
            +vn 0.294198 -0.855403 0.426252
            +vn 0.201300 -0.540880 0.816614
            +s 1
            +f 34//1 1243//2 593//3
            +f 52//4 27//5 40//6
            +f 52//4 40//6 65//7
            +f 77//8 52//4 65//7
            +f 77//8 65//7 84//9
            +f 107//10 77//8 84//9
            +f 107//10 84//9 85//11
            +f 115//12 107//10 85//11
            +f 115//12 85//11 99//13
            +f 129//14 115//12 99//13
            +f 129//14 99//13 128//15
            +f 1252//16 36//17 40//6
            +f 65//7 40//6 64//18
            +f 65//7 64//18 58//19
            +f 84//9 65//7 58//19
            +f 84//9 58//19 59//20
            +f 85//11 84//9 59//20
            +f 85//11 59//20 70//21
            +f 99//13 85//11 70//21
            +f 99//13 70//21 98//22
            +f 128//15 99//13 98//22
            +f 128//15 98//22 114//23
            +f 1244//24 33//25 64//18
            +f 58//19 64//18 33//25
            +f 58//19 33//25 35//26
            +f 59//20 58//19 35//26
            +f 59//20 35//26 45//27
            +f 70//21 59//20 45//27
            +f 70//21 45//27 69//28
            +f 98//22 70//21 69//28
            +f 98//22 69//28 83//29
            +f 114//23 98//22 83//29
            +f 114//23 83//29 113//30
            +f 553//31 1//32 566//33
            +f 35//26 33//25 20//34
            +f 35//26 20//34 24//35
            +f 45//27 35//26 24//35
            +f 45//27 24//35 44//36
            +f 69//28 45//27 44//36
            +f 69//28 44//36 57//37
            +f 83//29 69//28 57//37
            +f 83//29 57//37 82//38
            +f 113//30 83//29 82//38
            +f 113//30 82//38 112//39
            +f 566//33 1283//40 9//41
            +f 24//35 20//34 18//42
            +f 24//35 18//42 23//43
            +f 44//36 24//35 23//43
            +f 44//36 23//43 32//44
            +f 57//37 44//36 32//44
            +f 57//37 32//44 56//45
            +f 82//38 57//37 56//45
            +f 82//38 56//45 81//46
            +f 112//39 82//38 81//46
            +f 112//39 81//46 111//47
            +f 4//48 8//49 1250//50
            +f 23//43 18//42 8//49
            +f 23//43 8//49 17//51
            +f 32//44 23//43 17//51
            +f 32//44 17//51 31//52
            +f 56//45 32//44 31//52
            +f 56//45 31//52 55//53
            +f 81//46 56//45 55//53
            +f 81//46 55//53 80//54
            +f 111//47 81//46 80//54
            +f 111//47 80//54 110//55
            +f 565//56 592//57 1233//58
            +f 17//51 8//49 4//48
            +f 17//51 4//48 16//59
            +f 31//52 17//51 16//59
            +f 31//52 16//59 30//60
            +f 55//53 31//52 30//60
            +f 55//53 30//60 54//61
            +f 80//54 55//53 54//61
            +f 80//54 54//61 79//62
            +f 110//55 80//54 79//62
            +f 110//55 79//62 109//63
            +f 1//32 565//56 2//64
            +f 6//65 2//64 565//56
            +f 16//59 4//48 7//66
            +f 16//59 7//66 22//67
            +f 30//60 16//59 22//67
            +f 30//60 22//67 43//68
            +f 54//61 30//60 43//68
            +f 54//61 43//68 68//69
            +f 79//62 54//61 68//69
            +f 79//62 68//69 97//70
            +f 109//63 79//62 97//70
            +f 109//63 97//70 127//71
            +f 565//56 1233//58 1249//58
            +f 13//72 14//73 5//74
            +f 22//67 7//66 15//75
            +f 22//67 15//75 29//76
            +f 43//68 22//67 29//76
            +f 43//68 29//76 42//77
            +f 68//69 43//68 42//77
            +f 68//69 42//77 67//78
            +f 97//70 68//69 67//78
            +f 97//70 67//78 96//79
            +f 127//71 97//70 96//79
            +f 127//71 96//79 126//80
            +f 11//81 15//75 1240//82
            +f 1289//83 34//1 593//3
            +f 29//76 15//75 14//73
            +f 29//76 14//73 21//84
            +f 42//77 29//76 21//84
            +f 42//77 21//84 41//85
            +f 67//78 42//77 41//85
            +f 67//78 41//85 66//86
            +f 96//79 67//78 66//86
            +f 96//79 66//86 95//87
            +f 126//80 96//79 95//87
            +f 126//80 95//87 125//88
            +f 636//89 1243//2 26//2
            +f 636//89 26//2 592//57
            +f 21//84 14//73 13//72
            +f 21//84 13//72 28//90
            +f 41//85 21//84 28//90
            +f 41//85 28//90 53//91
            +f 66//86 41//85 53//91
            +f 66//86 53//91 78//92
            +f 95//87 66//86 78//92
            +f 95//87 78//92 108//93
            +f 125//88 95//87 108//93
            +f 125//88 108//93 136//94
            +f 12//95 13//72 5//74
            +f 28//90 13//72 27//5
            +f 28//90 27//5 52//4
            +f 53//91 28//90 52//4
            +f 53//91 52//4 77//8
            +f 78//92 53//91 77//8
            +f 78//92 77//8 107//10
            +f 108//93 78//92 107//10
            +f 108//93 107//10 115//12
            +f 136//94 108//93 115//12
            +f 136//94 115//12 129//14
            +f 148//96 129//14 128//15
            +f 148//96 128//15 143//97
            +f 121//98 148//96 143//97
            +f 121//98 143//97 122//99
            +f 92//100 121//98 122//99
            +f 92//100 122//99 93//101
            +f 62//102 92//100 93//101
            +f 62//102 93//101 63//103
            +f 39//104 62//102 63//103
            +f 39//104 63//103 51//105
            +f 10//106 39//104 51//105
            +f 10//106 51//105 49//107
            +f 143//97 128//15 114//23
            +f 143//97 114//23 142//108
            +f 122//99 143//97 142//108
            +f 122//99 142//108 123//109
            +f 93//101 122//99 123//109
            +f 93//101 123//109 94//110
            +f 63//103 93//101 94//110
            +f 63//103 94//110 76//111
            +f 51//105 63//103 76//111
            +f 51//105 76//111 75//112
            +f 49//107 51//105 75//112
            +f 49//107 75//112 61//113
            +f 142//108 114//23 113//30
            +f 142//108 113//30 141//114
            +f 123//109 142//108 141//114
            +f 123//109 141//114 124//115
            +f 94//110 123//109 124//115
            +f 94//110 124//115 106//116
            +f 76//111 94//110 106//116
            +f 76//111 106//116 105//117
            +f 75//112 76//111 105//117
            +f 75//112 105//117 91//118
            +f 61//113 75//112 91//118
            +f 61//113 91//118 90//119
            +f 141//114 113//30 112//39
            +f 141//114 112//39 140//120
            +f 124//115 141//114 140//120
            +f 124//115 140//120 135//121
            +f 106//116 124//115 135//121
            +f 106//116 135//121 134//122
            +f 105//117 106//116 134//122
            +f 105//117 134//122 120//123
            +f 91//118 105//117 120//123
            +f 91//118 120//123 119//124
            +f 90//119 91//118 119//124
            +f 140//120 112//39 111//47
            +f 140//120 111//47 139//125
            +f 135//121 140//120 139//125
            +f 135//121 139//125 155//126
            +f 134//122 135//121 155//126
            +f 134//122 155//126 147//127
            +f 120//123 134//122 147//127
            +f 120//123 147//127 144//128
            +f 119//124 120//123 144//128
            +f 119//124 144//128 116//129
            +f 26//2 1234//130 592//57
            +f 139//125 111//47 110//55
            +f 139//125 110//55 138//131
            +f 155//126 139//125 138//131
            +f 155//126 138//131 156//132
            +f 147//127 155//126 156//132
            +f 147//127 156//132 145//133
            +f 144//128 147//127 145//133
            +f 144//128 145//133 117//134
            +f 116//129 144//128 117//134
            +f 116//129 117//134 88//135
            +f 27//5 13//72 12//95
            +f 1242//136 88//135 71//137
            +f 138//131 110//55 109//63
            +f 138//131 109//63 137//138
            +f 156//132 138//131 137//138
            +f 156//132 137//138 154//139
            +f 145//133 156//132 154//139
            +f 145//133 154//139 131//140
            +f 117//134 145//133 131//140
            +f 117//134 131//140 101//141
            +f 88//135 117//134 101//141
            +f 88//135 101//141 86//142
            +f 60//143 74//144 1248//145
            +f 137//138 109//63 127//71
            +f 137//138 127//71 151//146
            +f 154//139 137//138 151//146
            +f 154//139 151//146 153//147
            +f 131//140 154//139 153//147
            +f 131//140 153//147 130//148
            +f 101//141 131//140 130//148
            +f 101//141 130//148 100//149
            +f 86//142 101//141 100//149
            +f 86//142 100//149 74//144
            +f 47//150 1235//151 631//152
            +f 74//144 48//153 1248//145
            +f 151//146 127//71 126//80
            +f 151//146 126//80 150//154
            +f 153//147 151//146 150//154
            +f 153//147 150//154 146//155
            +f 130//148 153//147 146//155
            +f 130//148 146//155 118//156
            +f 100//149 130//148 118//156
            +f 100//149 118//156 89//157
            +f 74//144 100//149 89//157
            +f 74//144 89//157 48//153
            +f 1247//158 87//159 715//160
            +f 104//161 116//129 1242//136
            +f 150//154 126//80 125//88
            +f 150//154 125//88 149//162
            +f 146//155 150//154 149//162
            +f 146//155 149//162 132//163
            +f 118//156 146//155 132//163
            +f 118//156 132//163 102//164
            +f 89//157 118//156 102//164
            +f 89//157 102//164 72//165
            +f 48//153 89//157 72//165
            +f 48//153 72//165 46//166
            +f 37//167 48//153 46//166
            +f 37//167 46//166 38//168
            +f 149//162 125//88 136//94
            +f 149//162 136//94 152//169
            +f 132//163 149//162 152//169
            +f 132//163 152//169 133//170
            +f 102//164 132//163 133//170
            +f 102//164 133//170 103//171
            +f 72//165 102//164 103//171
            +f 72//165 103//171 73//172
            +f 46//166 72//165 73//172
            +f 46//166 73//172 50//173
            +f 38//168 46//166 50//173
            +f 38//168 50//173 25//174
            +f 152//169 136//94 129//14
            +f 152//169 129//14 148//96
            +f 133//170 152//169 148//96
            +f 133//170 148//96 121//98
            +f 103//171 133//170 121//98
            +f 103//171 121//98 92//100
            +f 73//172 103//171 92//100
            +f 73//172 92//100 62//102
            +f 50//173 73//172 62//102
            +f 50//173 62//102 39//104
            +f 25//174 50//173 39//104
            +f 39//104 10//106 25//174
            +f 539//175 509//176 159//177
            +f 160//178 158//179 157//180
            +f 166//181 160//178 163//182
            +f 166//181 163//182 173//183
            +f 177//184 166//181 173//183
            +f 177//184 173//183 183//185
            +f 189//186 177//184 183//185
            +f 189//186 183//185 197//187
            +f 205//188 189//186 197//187
            +f 205//188 197//187 216//189
            +f 225//190 205//188 216//189
            +f 225//190 216//189 235//191
            +f 173//183 163//182 172//192
            +f 173//183 172//192 184//193
            +f 183//185 173//183 184//193
            +f 183//185 184//193 198//194
            +f 197//187 183//185 198//194
            +f 197//187 198//194 217//195
            +f 216//189 197//187 217//195
            +f 216//189 217//195 236//196
            +f 235//191 216//189 236//196
            +f 235//191 236//196 253//197
            +f 182//198 172//192 1254//199
            +f 1255//200 167//201 595//202
            +f 184//193 172//192 182//198
            +f 184//193 182//198 196//203
            +f 198//194 184//193 196//203
            +f 198//194 196//203 214//204
            +f 217//195 198//194 214//204
            +f 217//195 214//204 232//205
            +f 236//196 217//195 232//205
            +f 236//196 232//205 250//206
            +f 253//197 236//196 250//206
            +f 253//197 250//206 267//207
            +f 196//203 182//198 199//208
            +f 196//203 199//208 215//209
            +f 214//204 196//203 215//209
            +f 214//204 215//209 233//210
            +f 232//205 214//204 233//210
            +f 232//205 233//210 251//211
            +f 250//206 232//205 251//211
            +f 250//206 251//211 257//212
            +f 267//207 250//206 257//212
            +f 267//207 257//212 256//213
            +f 215//209 199//208 218//214
            +f 215//209 218//214 234//215
            +f 233//210 215//209 234//215
            +f 233//210 234//215 241//216
            +f 251//211 233//210 241//216
            +f 251//211 241//216 240//217
            +f 257//212 251//211 240//217
            +f 257//212 240//217 239//218
            +f 256//213 257//212 239//218
            +f 256//213 239//218 238//219
            +f 234//215 218//214 219//220
            +f 234//215 219//220 224//221
            +f 241//216 234//215 224//221
            +f 241//216 224//221 223//222
            +f 240//217 241//216 223//222
            +f 240//217 223//222 222//223
            +f 239//218 240//217 222//223
            +f 239//218 222//223 221//224
            +f 238//219 239//218 221//224
            +f 238//219 221//224 220//225
            +f 219//220 218//214 1285//226
            +f 648//227 691//228 207//229
            +f 224//221 219//220 208//230
            +f 224//221 208//230 204//231
            +f 223//222 224//221 204//231
            +f 223//222 204//231 203//232
            +f 222//223 223//222 203//232
            +f 222//223 203//232 202//233
            +f 221//224 222//223 202//233
            +f 221//224 202//233 201//234
            +f 220//225 221//224 201//234
            +f 220//225 201//234 212//235
            +f 204//231 208//230 191//236
            +f 204//231 191//236 188//237
            +f 203//232 204//231 188//237
            +f 203//232 188//237 187//238
            +f 202//233 203//232 187//238
            +f 202//233 187//238 186//239
            +f 201//234 202//233 186//239
            +f 201//234 186//239 194//240
            +f 212//235 201//234 194//240
            +f 212//235 194//240 211//241
            +f 188//237 191//236 174//242
            +f 188//237 174//242 176//243
            +f 187//238 188//237 176//243
            +f 187//238 176//243 175//244
            +f 186//239 187//238 175//244
            +f 186//239 175//244 180//245
            +f 194//240 186//239 180//245
            +f 194//240 180//245 193//246
            +f 211//241 194//240 193//246
            +f 211//241 193//246 210//247
            +f 613//248 585//249 1258//250
            +f 176//243 174//242 168//251
            +f 176//243 168//251 165//252
            +f 175//244 176//243 165//252
            +f 175//244 165//252 170//253
            +f 180//245 175//244 170//253
            +f 180//245 170//253 179//254
            +f 193//246 180//245 179//254
            +f 193//246 179//254 192//255
            +f 210//247 193//246 192//255
            +f 210//247 192//255 209//256
            +f 168//251 174//242 164//257
            +f 165//252 168//251 161//258
            +f 165//252 161//258 162//259
            +f 170//253 165//252 162//259
            +f 170//253 162//259 171//260
            +f 179//254 170//253 171//260
            +f 179//254 171//260 181//261
            +f 192//255 179//254 181//261
            +f 192//255 181//261 195//262
            +f 209//256 192//255 195//262
            +f 209//256 195//262 213//263
            +f 160//178 161//258 158//179
            +f 161//258 160//178 162//259
            +f 162//259 160//178 166//181
            +f 171//260 162//259 166//181
            +f 171//260 166//181 177//184
            +f 181//261 171//260 177//184
            +f 181//261 177//184 189//186
            +f 195//262 181//261 189//186
            +f 195//262 189//186 205//188
            +f 213//263 195//262 205//188
            +f 213//263 205//188 225//190
            +f 242//264 225//190 235//191
            +f 242//264 235//191 252//265
            +f 258//266 242//264 252//265
            +f 258//266 252//265 268//267
            +f 273//268 258//266 268//267
            +f 273//268 268//267 283//269
            +f 287//270 273//268 283//269
            +f 287//270 283//269 298//271
            +f 300//272 287//270 298//271
            +f 300//272 298//271 299//273
            +f 312//274 300//272 299//273
            +f 312//274 299//273 310//275
            +f 252//265 235//191 253//197
            +f 252//265 253//197 269//276
            +f 268//267 252//265 269//276
            +f 268//267 269//276 284//277
            +f 283//269 268//267 284//277
            +f 283//269 284//277 286//278
            +f 298//271 283//269 286//278
            +f 298//271 286//278 285//279
            +f 299//273 298//271 285//279
            +f 299//273 285//279 296//280
            +f 310//275 299//273 296//280
            +f 310//275 296//280 309//281
            +f 269//276 253//197 267//207
            +f 269//276 267//207 272//282
            +f 284//277 269//276 272//282
            +f 284//277 272//282 271//283
            +f 286//278 284//277 271//283
            +f 286//278 271//283 270//284
            +f 285//279 286//278 270//284
            +f 285//279 270//284 281//285
            +f 296//280 285//279 281//285
            +f 296//280 281//285 295//286
            +f 309//281 296//280 295//286
            +f 309//281 295//286 308//287
            +f 272//282 267//207 256//213
            +f 272//282 256//213 255//288
            +f 271//283 272//282 255//288
            +f 271//283 255//288 254//289
            +f 270//284 271//283 254//289
            +f 270//284 254//289 265//290
            +f 281//285 270//284 265//290
            +f 281//285 265//290 280//291
            +f 295//286 281//285 280//291
            +f 295//286 280//291 294//292
            +f 308//287 295//286 294//292
            +f 308//287 294//292 307//293
            +f 255//288 256//213 238//219
            +f 255//288 238//219 237//294
            +f 254//289 255//288 237//294
            +f 254//289 237//294 248//295
            +f 265//290 254//289 248//295
            +f 265//290 248//295 264//296
            +f 280//291 265//290 264//296
            +f 280//291 264//296 279//297
            +f 294//292 280//291 279//297
            +f 294//292 279//297 293//298
            +f 307//293 294//292 293//298
            +f 307//293 293//298 306//299
            +f 237//294 238//219 220//225
            +f 237//294 220//225 230//300
            +f 248//295 237//294 230//300
            +f 248//295 230//300 247//301
            +f 264//296 248//295 247//301
            +f 264//296 247//301 263//302
            +f 279//297 264//296 263//302
            +f 279//297 263//302 278//303
            +f 293//298 279//297 278//303
            +f 293//298 278//303 292//304
            +f 306//299 293//298 292//304
            +f 306//299 292//304 305//305
            +f 230//300 220//225 212//235
            +f 230//300 212//235 229//306
            +f 247//301 230//300 229//306
            +f 247//301 229//306 246//307
            +f 263//302 247//301 246//307
            +f 263//302 246//307 262//308
            +f 278//303 263//302 262//308
            +f 278//303 262//308 277//309
            +f 292//304 278//303 277//309
            +f 292//304 277//309 291//310
            +f 305//305 292//304 291//310
            +f 305//305 291//310 304//311
            +f 229//306 212//235 211//241
            +f 229//306 211//241 228//312
            +f 246//307 229//306 228//312
            +f 246//307 228//312 245//313
            +f 262//308 246//307 245//313
            +f 262//308 245//313 261//314
            +f 277//309 262//308 261//314
            +f 277//309 261//314 276//315
            +f 291//310 277//309 276//315
            +f 291//310 276//315 290//316
            +f 304//311 291//310 290//316
            +f 304//311 290//316 303//317
            +f 228//312 211//241 210//247
            +f 228//312 210//247 227//318
            +f 245//313 228//312 227//318
            +f 245//313 227//318 244//319
            +f 261//314 245//313 244//319
            +f 261//314 244//319 260//320
            +f 276//315 261//314 260//320
            +f 276//315 260//320 275//321
            +f 290//316 276//315 275//321
            +f 290//316 275//321 289//322
            +f 303//317 290//316 289//322
            +f 303//317 289//322 302//323
            +f 227//318 210//247 209//256
            +f 227//318 209//256 226//324
            +f 244//319 227//318 226//324
            +f 244//319 226//324 243//325
            +f 260//320 244//319 243//325
            +f 260//320 243//325 259//326
            +f 275//321 260//320 259//326
            +f 275//321 259//326 274//327
            +f 289//322 275//321 274//327
            +f 289//322 274//327 288//328
            +f 302//323 289//322 288//328
            +f 302//323 288//328 301//329
            +f 226//324 209//256 213//263
            +f 226//324 213//263 231//330
            +f 243//325 226//324 231//330
            +f 243//325 231//330 249//331
            +f 259//326 243//325 249//331
            +f 259//326 249//331 266//332
            +f 274//327 259//326 266//332
            +f 274//327 266//332 282//333
            +f 288//328 274//327 282//333
            +f 288//328 282//333 297//334
            +f 301//329 288//328 297//334
            +f 301//329 297//334 311//335
            +f 231//330 213//263 225//190
            +f 231//330 225//190 242//264
            +f 249//331 231//330 242//264
            +f 249//331 242//264 258//266
            +f 266//332 249//331 258//266
            +f 266//332 258//266 273//268
            +f 282//333 266//332 273//268
            +f 282//333 273//268 287//270
            +f 297//334 282//333 287//270
            +f 297//334 287//270 300//272
            +f 311//335 297//334 300//272
            +f 311//335 300//272 312//274
            +f 312//274 310//275 323//336
            +f 302//323 315//337 316//338
            +f 304//311 317//339 318//340
            +f 303//317 316//338 317//339
            +f 309//281 308//287 321//341
            +f 307//293 306//299 319//342
            +f 311//335 313//343 314//344
            +f 301//329 314//344 315//337
            +f 312//274 324//345 313//343
            +f 306//299 305//305 318//340
            +f 308//287 307//293 320//346
            +f 310//275 309//281 322//347
            +f 322//347 321//341 325//348
            +f 314//344 313//343 325//348
            +f 323//336 322//347 325//348
            +f 319//342 318//340 325//348
            +f 315//337 314//344 325//348
            +f 321//341 320//346 325//348
            +f 324//345 323//336 325//348
            +f 320//346 319//342 325//348
            +f 317//339 316//338 325//348
            +f 316//338 315//337 325//348
            +f 313//343 324//345 325//348
            +f 318//340 317//339 325//348
            +f 326//349 327//350 328//351
            +f 326//349 328//351 329//352
            +f 333//353 326//349 329//352
            +f 333//353 329//352 338//354
            +f 347//355 333//353 338//354
            +f 347//355 338//354 354//356
            +f 364//357 347//355 354//356
            +f 364//357 354//356 374//358
            +f 386//359 364//357 374//358
            +f 386//359 374//358 398//360
            +f 412//361 386//359 398//360
            +f 412//361 398//360 429//362
            +f 329//352 328//351 334//363
            +f 329//352 334//363 339//364
            +f 338//354 329//352 339//364
            +f 338//354 339//364 355//365
            +f 354//356 338//354 355//365
            +f 354//356 355//365 375//366
            +f 374//358 354//356 375//366
            +f 374//358 375//366 399//367
            +f 398//360 374//358 399//367
            +f 398//360 399//367 430//368
            +f 429//362 398//360 430//368
            +f 429//362 430//368 464//369
            +f 339//364 334//363 342//370
            +f 339//364 342//370 356//371
            +f 355//365 339//364 356//371
            +f 355//365 356//371 376//372
            +f 375//366 355//365 376//372
            +f 375//366 376//372 400//373
            +f 399//367 375//366 400//373
            +f 399//367 400//373 431//374
            +f 430//368 399//367 431//374
            +f 430//368 431//374 465//375
            +f 464//369 430//368 465//375
            +f 464//369 465//375 497//376
            +f 356//371 342//370 351//377
            +f 356//371 351//377 370//378
            +f 376//372 356//371 370//378
            +f 376//372 370//378 393//379
            +f 400//373 376//372 393//379
            +f 400//373 393//379 422//380
            +f 431//374 400//373 422//380
            +f 431//374 422//380 457//381
            +f 465//375 431//374 457//381
            +f 465//375 457//381 490//382
            +f 497//376 465//375 490//382
            +f 497//376 490//382 521//383
            +f 370//378 351//377 361//384
            +f 370//378 361//384 382//385
            +f 393//379 370//378 382//385
            +f 393//379 382//385 408//386
            +f 422//380 393//379 408//386
            +f 422//380 408//386 439//387
            +f 457//381 422//380 439//387
            +f 457//381 439//387 473//388
            +f 490//382 457//381 473//388
            +f 490//382 473//388 504//389
            +f 521//383 490//382 504//389
            +f 521//383 504//389 535//390
            +f 382//385 361//384 369//391
            +f 382//385 369//391 392//392
            +f 408//386 382//385 392//392
            +f 408//386 392//392 421//393
            +f 439//387 408//386 421//393
            +f 439//387 421//393 456//394
            +f 473//388 439//387 456//394
            +f 473//388 456//394 489//395
            +f 504//389 473//388 489//395
            +f 504//389 489//395 520//396
            +f 535//390 504//389 520//396
            +f 535//390 520//396 550//397
            +f 392//392 369//391 380//398
            +f 392//392 380//398 407//399
            +f 421//393 392//392 407//399
            +f 421//393 407//399 438//400
            +f 456//394 421//393 438//400
            +f 456//394 438//400 472//401
            +f 489//395 456//394 472//401
            +f 489//395 472//401 503//402
            +f 520//396 489//395 503//402
            +f 520//396 503//402 534//403
            +f 550//397 520//396 534//403
            +f 550//397 534//403 563//404
            +f 407//399 380//398 391//405
            +f 407//399 391//405 420//406
            +f 438//400 407//399 420//406
            +f 438//400 420//406 455//407
            +f 472//401 438//400 455//407
            +f 472//401 455//407 488//408
            +f 503//402 472//401 488//408
            +f 503//402 488//408 519//409
            +f 534//403 503//402 519//409
            +f 534//403 519//409 549//410
            +f 563//404 534//403 549//410
            +f 563//404 549//410 578//411
            +f 420//406 391//405 404//412
            +f 420//406 404//412 437//413
            +f 455//407 420//406 437//413
            +f 455//407 437//413 471//414
            +f 488//408 455//407 471//414
            +f 488//408 471//414 502//415
            +f 519//409 488//408 502//415
            +f 519//409 502//415 533//416
            +f 549//410 519//409 533//416
            +f 549//410 533//416 562//417
            +f 578//411 549//410 562//417
            +f 578//411 562//417 589//418
            +f 437//413 404//412 419//419
            +f 437//413 419//419 454//420
            +f 471//414 437//413 454//420
            +f 471//414 454//420 487//421
            +f 502//415 471//414 487//421
            +f 502//415 487//421 518//422
            +f 533//416 502//415 518//422
            +f 533//416 518//422 548//423
            +f 562//417 533//416 548//423
            +f 562//417 548//423 577//424
            +f 589//418 562//417 577//424
            +f 589//418 577//424 594//425
            +f 454//420 419//419 436//426
            +f 454//420 436//426 470//427
            +f 487//421 454//420 470//427
            +f 487//421 470//427 501//428
            +f 518//422 487//421 501//428
            +f 518//422 501//428 532//429
            +f 548//423 518//422 532//429
            +f 548//423 532//429 555//430
            +f 577//424 548//423 555//430
            +f 577//424 555//430 567//431
            +f 594//425 577//424 567//431
            +f 594//425 567//431 582//432
            +f 470//427 436//426 453//433
            +f 470//427 453//433 486//434
            +f 501//428 470//427 486//434
            +f 501//428 486//434 508//435
            +f 532//429 501//428 508//435
            +f 532//429 508//435 525//436
            +f 555//430 532//429 525//436
            +f 555//430 525//436 538//437
            +f 567//431 555//430 538//437
            +f 567//431 538//437 554//438
            +f 582//432 567//431 554//438
            +f 582//432 554//438 566//33
            +f 486//434 453//433 462//439
            +f 486//434 462//439 477//440
            +f 508//435 486//434 477//440
            +f 508//435 477//440 494//441
            +f 525//436 508//435 494//441
            +f 525//436 494//441 507//442
            +f 538//437 525//436 507//442
            +f 538//437 507//442 524//443
            +f 554//438 538//437 524//443
            +f 554//438 524//443 537//444
            +f 566//33 554//438 537//444
            +f 566//33 537//444 553//31
            +f 477//440 462//439 443//445
            +f 477//440 443//445 461//446
            +f 494//441 477//440 461//446
            +f 494//441 461//446 476//447
            +f 507//442 494//441 476//447
            +f 507//442 476//447 493//448
            +f 524//443 507//442 493//448
            +f 524//443 493//448 506//449
            +f 537//444 524//443 506//449
            +f 537//444 506//449 523//450
            +f 553//31 537//444 523//450
            +f 553//31 523//450 536//451
            +f 461//446 443//445 426//452
            +f 461//446 426//452 442//453
            +f 476//447 461//446 442//453
            +f 476//447 442//453 460//454
            +f 493//448 476//447 460//454
            +f 493//448 460//454 475//455
            +f 506//449 493//448 475//455
            +f 506//449 475//455 492//456
            +f 523//450 506//449 492//456
            +f 523//450 492//456 505//457
            +f 536//451 523//450 505//457
            +f 536//451 505//457 522//458
            +f 442//453 426//452 411//459
            +f 442//453 411//459 425//460
            +f 460//454 442//453 425//460
            +f 460//454 425//460 441//461
            +f 475//455 460//454 441//461
            +f 475//455 441//461 459//462
            +f 492//456 475//455 459//462
            +f 492//456 459//462 474//463
            +f 505//457 492//456 474//463
            +f 505//457 474//463 491//464
            +f 522//458 505//457 491//464
            +f 522//458 491//464 499//465
            +f 425//460 411//459 396//466
            +f 425//460 396//466 410//467
            +f 441//461 425//460 410//467
            +f 441//461 410//467 424//468
            +f 459//462 441//461 424//468
            +f 459//462 424//468 440//469
            +f 474//463 459//462 440//469
            +f 474//463 440//469 458//470
            +f 491//464 474//463 458//470
            +f 491//464 458//470 467//471
            +f 499//465 491//464 467//471
            +f 499//465 467//471 466//472
            +f 410//467 396//466 385//473
            +f 410//467 385//473 395//474
            +f 424//468 410//467 395//474
            +f 424//468 395//474 409//475
            +f 440//469 424//468 409//475
            +f 440//469 409//475 423//476
            +f 458//470 440//469 423//476
            +f 458//470 423//476 433//477
            +f 467//471 458//470 433//477
            +f 467//471 433//477 432//478
            +f 466//472 467//471 432//478
            +f 466//472 432//478 434//479
            +f 395//474 385//473 372//480
            +f 395//474 372//480 383//481
            +f 409//475 395//474 383//481
            +f 409//475 383//481 394//482
            +f 423//476 409//475 394//482
            +f 423//476 394//482 402//483
            +f 433//477 423//476 402//483
            +f 433//477 402//483 401//484
            +f 432//478 433//477 401//484
            +f 432//478 401//484 403//485
            +f 434//479 432//478 403//485
            +f 434//479 403//485 417//486
            +f 383//481 372//480 362//487
            +f 383//481 362//487 371//488
            +f 394//482 383//481 371//488
            +f 394//482 371//488 378//489
            +f 402//483 394//482 378//489
            +f 402//483 378//489 377//490
            +f 401//484 402//483 377//490
            +f 401//484 377//490 379//491
            +f 403//485 401//484 379//491
            +f 403//485 379//491 390//492
            +f 417//486 403//485 390//492
            +f 417//486 390//492 416//493
            +f 371//488 362//487 352//494
            +f 371//488 352//494 358//495
            +f 378//489 371//488 358//495
            +f 378//489 358//495 357//496
            +f 377//490 378//489 357//496
            +f 377//490 357//496 359//497
            +f 379//491 377//490 359//497
            +f 379//491 359//497 367//498
            +f 390//492 379//491 367//498
            +f 390//492 367//498 389//499
            +f 416//493 390//492 389//499
            +f 416//493 389//499 415//500
            +f 358//495 352//494 345//501
            +f 358//495 345//501 340//502
            +f 357//496 358//495 340//502
            +f 357//496 340//502 341//503
            +f 359//497 357//496 341//503
            +f 359//497 341//503 349//504
            +f 367//498 359//497 349//504
            +f 367//498 349//504 366//505
            +f 389//499 367//498 366//505
            +f 389//499 366//505 388//506
            +f 415//500 389//499 388//506
            +f 415//500 388//506 414//507
            +f 340//502 345//501 335//508
            +f 340//502 335//508 330//509
            +f 341//503 340//502 330//509
            +f 341//503 330//509 336//510
            +f 349//504 341//503 336//510
            +f 349//504 336//510 348//511
            +f 366//505 349//504 348//511
            +f 366//505 348//511 365//512
            +f 388//506 366//505 365//512
            +f 388//506 365//512 387//513
            +f 414//507 388//506 387//513
            +f 414//507 387//513 413//514
            +f 330//509 335//508 327//350
            +f 327//350 326//349 330//509
            +f 330//509 326//349 336//510
            +f 336//510 326//349 333//353
            +f 348//511 336//510 333//353
            +f 348//511 333//353 347//355
            +f 365//512 348//511 347//355
            +f 365//512 347//355 364//357
            +f 387//513 365//512 364//357
            +f 387//513 364//357 386//359
            +f 413//514 387//513 386//359
            +f 413//514 386//359 412//361
            +f 445//515 412//361 429//362
            +f 445//515 429//362 463//516
            +f 478//517 445//515 463//516
            +f 478//517 463//516 495//518
            +f 509//176 478//517 495//518
            +f 509//176 495//518 526//519
            +f 463//516 429//362 464//369
            +f 463//516 464//369 496//520
            +f 495//518 463//516 496//520
            +f 495//518 496//520 527//521
            +f 526//519 495//518 527//521
            +f 526//519 527//521 557//522
            +f 556//523 526//519 557//522
            +f 556//523 557//522 583//524
            +f 595//202 556//523 583//524
            +f 595//202 583//524 611//525
            +f 621//526 595//202 611//525
            +f 621//526 611//525 638//527
            +f 496//520 464//369 497//376
            +f 496//520 497//376 528//528
            +f 527//521 496//520 528//528
            +f 527//521 528//528 558//529
            +f 557//522 527//521 558//529
            +f 557//522 558//529 584//530
            +f 583//524 557//522 584//530
            +f 583//524 584//530 612//531
            +f 611//525 583//524 612//531
            +f 611//525 612//531 639//532
            +f 638//527 611//525 639//532
            +f 638//527 639//532 664//533
            +f 528//528 497//376 521//383
            +f 528//528 521//383 551//534
            +f 558//529 528//528 551//534
            +f 558//529 551//534 580//535
            +f 584//530 558//529 580//535
            +f 584//530 580//535 608//536
            +f 612//531 584//530 608//536
            +f 612//531 608//536 634//537
            +f 639//532 612//531 634//537
            +f 639//532 634//537 661//538
            +f 664//533 639//532 661//538
            +f 664//533 661//538 688//539
            +f 551//534 521//383 535//390
            +f 551//534 535//390 564//540
            +f 580//535 551//534 564//540
            +f 580//535 564//540 591//541
            +f 608//536 580//535 591//541
            +f 608//536 591//541 618//542
            +f 634//537 608//536 618//542
            +f 634//537 618//542 644//543
            +f 661//538 634//537 644//543
            +f 661//538 644//543 670//544
            +f 688//539 661//538 670//544
            +f 688//539 670//544 698//545
            +f 564//540 535//390 550//397
            +f 564//540 550//397 579//546
            +f 591//541 564//540 579//546
            +f 591//541 579//546 607//547
            +f 618//542 591//541 607//547
            +f 618//542 607//547 633//548
            +f 644//543 618//542 633//548
            +f 644//543 633//548 660//549
            +f 670//544 644//543 660//549
            +f 670//544 660//549 687//550
            +f 698//545 670//544 687//550
            +f 698//545 687//550 717//551
            +f 579//546 550//397 563//404
            +f 579//546 563//404 590//552
            +f 607//547 579//546 590//552
            +f 607//547 590//552 617//553
            +f 633//548 607//547 617//553
            +f 633//548 617//553 643//554
            +f 660//549 633//548 643//554
            +f 660//549 643//554 669//555
            +f 687//550 660//549 669//555
            +f 687//550 669//555 697//556
            +f 717//551 687//550 697//556
            +f 717//551 697//556 727//557
            +f 590//552 563//404 578//411
            +f 590//552 578//411 606//558
            +f 617//553 590//552 606//558
            +f 617//553 606//558 632//559
            +f 643//554 617//553 632//559
            +f 643//554 632//559 659//560
            +f 669//555 643//554 659//560
            +f 669//555 659//560 673//561
            +f 697//556 669//555 673//561
            +f 697//556 673//561 700//562
            +f 727//557 697//556 700//562
            +f 727//557 700//562 699//563
            +f 606//558 578//411 589//418
            +f 606//558 589//418 616//564
            +f 632//559 606//558 616//564
            +f 632//559 616//564 637//565
            +f 659//560 632//559 637//565
            +f 659//560 637//565 647//566
            +f 673//561 659//560 647//566
            +f 673//561 647//566 672//567
            +f 700//562 673//561 672//567
            +f 700//562 672//567 671//568
            +f 699//563 700//562 671//568
            +f 699//563 671//568 689//569
            +f 616//564 589//418 594//425
            +f 616//564 594//425 610//570
            +f 637//565 616//564 610//570
            +f 637//565 610//570 620//571
            +f 647//566 637//565 620//571
            +f 647//566 620//571 646//572
            +f 672//567 647//566 646//572
            +f 672//567 646//572 645//573
            +f 671//568 672//567 645//573
            +f 671//568 645//573 662//574
            +f 689//569 671//568 662//574
            +f 689//569 662//574 668//575
            +f 610//570 594//425 582//432
            +f 610//570 582//432 593//3
            +f 620//571 610//570 593//3
            +f 620//571 593//3 636//89
            +f 646//572 620//571 636//89
            +f 646//572 636//89 619//576
            +f 645//573 646//572 619//576
            +f 645//573 619//576 635//577
            +f 662//574 645//573 635//577
            +f 662//574 635//577 642//578
            +f 668//575 662//574 642//578
            +f 668//575 642//578 641//579
            +f 593//3 582//432 566//33
            +f 619//576 636//89 592//57
            +f 619//576 592//57 609//580
            +f 635//577 619//576 609//580
            +f 635//577 609//580 615//581
            +f 642//578 635//577 615//581
            +f 642//578 615//581 614//582
            +f 641//579 642//578 614//582
            +f 592//57 565//56 581//583
            +f 609//580 592//57 581//583
            +f 609//580 581//583 587//584
            +f 615//581 609//580 587//584
            +f 615//581 587//584 586//585
            +f 614//582 615//581 586//585
            +f 614//582 586//585 588//586
            +f 565//56 553//31 536//451
            +f 565//56 536//451 552//587
            +f 581//583 565//56 552//587
            +f 581//583 552//587 560//588
            +f 587//584 581//583 560//588
            +f 587//584 560//588 559//589
            +f 586//585 587//584 559//589
            +f 586//585 559//589 561//590
            +f 588//586 586//585 561//590
            +f 588//586 561//590 576//591
            +f 605//592 588//586 576//591
            +f 605//592 576//591 604//593
            +f 552//587 536//451 522//458
            +f 552//587 522//458 530//594
            +f 560//588 552//587 530//594
            +f 560//588 530//594 529//595
            +f 559//589 560//588 529//595
            +f 559//589 529//595 531//596
            +f 561//590 559//589 531//596
            +f 561//590 531//596 547//597
            +f 576//591 561//590 547//597
            +f 576//591 547//597 575//598
            +f 604//593 576//591 575//598
            +f 604//593 575//598 603//599
            +f 530//594 522//458 499//465
            +f 530//594 499//465 498//600
            +f 529//595 530//594 498//600
            +f 529//595 498//600 500//601
            +f 531//596 529//595 500//601
            +f 531//596 500//601 517//602
            +f 547//597 531//596 517//602
            +f 547//597 517//602 546//603
            +f 575//598 547//597 546//603
            +f 575//598 546//603 574//604
            +f 603//599 575//598 574//604
            +f 603//599 574//604 602//605
            +f 498//600 499//465 466//472
            +f 498//600 466//472 468//606
            +f 500//601 498//600 468//606
            +f 500//601 468//606 485//607
            +f 517//602 500//601 485//607
            +f 517//602 485//607 516//608
            +f 546//603 517//602 516//608
            +f 546//603 516//608 545//609
            +f 574//604 546//603 545//609
            +f 574//604 545//609 573//610
            +f 602//605 574//604 573//610
            +f 602//605 573//610 601//611
            +f 468//606 466//472 434//479
            +f 468//606 434//479 451//612
            +f 485//607 468//606 451//612
            +f 485//607 451//612 484//613
            +f 516//608 485//607 484//613
            +f 516//608 484//613 515//614
            +f 545//609 516//608 515//614
            +f 545//609 515//614 544//615
            +f 573//610 545//609 544//615
            +f 573//610 544//615 572//616
            +f 601//611 573//610 572//616
            +f 601//611 572//616 600//617
            +f 451//612 434//479 417//486
            +f 451//612 417//486 450//618
            +f 484//613 451//612 450//618
            +f 484//613 450//618 483//619
            +f 515//614 484//613 483//619
            +f 515//614 483//619 514//620
            +f 544//615 515//614 514//620
            +f 544//615 514//620 543//621
            +f 572//616 544//615 543//621
            +f 572//616 543//621 571//622
            +f 600//617 572//616 571//622
            +f 600//617 571//622 599//623
            +f 450//618 417//486 416//493
            +f 450//618 416//493 449//624
            +f 483//619 450//618 449//624
            +f 483//619 449//624 482//625
            +f 514//620 483//619 482//625
            +f 514//620 482//625 513//626
            +f 543//621 514//620 513//626
            +f 543//621 513//626 542//627
            +f 571//622 543//621 542//627
            +f 571//622 542//627 570//628
            +f 599//623 571//622 570//628
            +f 599//623 570//628 598//629
            +f 449//624 416//493 415//500
            +f 449//624 415//500 448//630
            +f 482//625 449//624 448//630
            +f 482//625 448//630 481//631
            +f 513//626 482//625 481//631
            +f 513//626 481//631 512//632
            +f 542//627 513//626 512//632
            +f 542//627 512//632 541//633
            +f 570//628 542//627 541//633
            +f 570//628 541//633 569//634
            +f 598//629 570//628 569//634
            +f 598//629 569//634 597//635
            +f 448//630 415//500 414//507
            +f 448//630 414//507 447//636
            +f 481//631 448//630 447//636
            +f 481//631 447//636 480//637
            +f 512//632 481//631 480//637
            +f 512//632 480//637 511//638
            +f 541//633 512//632 511//638
            +f 541//633 511//638 540//639
            +f 569//634 541//633 540//639
            +f 569//634 540//639 568//640
            +f 597//635 569//634 568//640
            +f 597//635 568//640 596//641
            +f 447//636 414//507 413//514
            +f 447//636 413//514 446//642
            +f 480//637 447//636 446//642
            +f 480//637 446//642 479//643
            +f 511//638 480//637 479//643
            +f 511//638 479//643 510//644
            +f 540//639 511//638 510//644
            +f 540//639 510//644 539//175
            +f 568//640 540//639 539//175
            +f 568//640 539//175 585//249
            +f 596//641 568//640 585//249
            +f 596//641 585//249 613//248
            +f 446//642 413//514 412//361
            +f 446//642 412//361 445//515
            +f 479//643 446//642 445//515
            +f 479//643 445//515 478//517
            +f 510//644 479//643 478//517
            +f 510//644 478//517 509//176
            +f 539//175 510//644 509//176
            +f 691//228 648//227 674//645
            +f 702//646 691//228 674//645
            +f 702//646 674//645 701//647
            +f 731//648 702//646 701//647
            +f 731//648 701//647 730//649
            +f 759//650 731//648 730//649
            +f 759//650 730//649 758//651
            +f 786//652 759//650 758//651
            +f 786//652 758//651 785//653
            +f 648//227 621//526 638//527
            +f 648//227 638//527 663//654
            +f 674//645 648//227 663//654
            +f 674//645 663//654 690//655
            +f 701//647 674//645 690//655
            +f 701//647 690//655 720//656
            +f 730//649 701//647 720//656
            +f 730//649 720//656 749//657
            +f 758//651 730//649 749//657
            +f 758//651 749//657 777//658
            +f 785//653 758//651 777//658
            +f 785//653 777//658 805//659
            +f 663//654 638//527 664//533
            +f 663//654 664//533 692//660
            +f 690//655 663//654 692//660
            +f 690//655 692//660 721//661
            +f 720//656 690//655 721//661
            +f 720//656 721//661 750//662
            +f 749//657 720//656 750//662
            +f 749//657 750//662 778//663
            +f 777//658 749//657 778//663
            +f 777//658 778//663 806//664
            +f 805//659 777//658 806//664
            +f 805//659 806//664 833//665
            +f 692//660 664//533 688//539
            +f 692//660 688//539 718//666
            +f 721//661 692//660 718//666
            +f 721//661 718//666 747//667
            +f 750//662 721//661 747//667
            +f 750//662 747//667 775//668
            +f 778//663 750//662 775//668
            +f 778//663 775//668 803//669
            +f 806//664 778//663 803//669
            +f 806//664 803//669 831//670
            +f 833//665 806//664 831//670
            +f 833//665 831//670 838//671
            +f 718//666 688//539 698//545
            +f 718//666 698//545 728//672
            +f 747//667 718//666 728//672
            +f 747//667 728//672 756//673
            +f 775//668 747//667 756//673
            +f 775//668 756//673 784//674
            +f 803//669 775//668 784//674
            +f 803//669 784//674 804//675
            +f 831//670 803//669 804//675
            +f 831//670 804//675 811//676
            +f 838//671 831//670 811//676
            +f 838//671 811//676 830//677
            +f 728//672 698//545 717//551
            +f 728//672 717//551 746//678
            +f 756//673 728//672 746//678
            +f 756//673 746//678 757//679
            +f 784//674 756//673 757//679
            +f 784//674 757//679 776//680
            +f 804//675 784//674 776//680
            +f 804//675 776//680 783//681
            +f 811//676 804//675 783//681
            +f 811//676 783//681 802//682
            +f 830//677 811//676 802//682
            +f 830//677 802//682 810//683
            +f 746//678 717//551 727//557
            +f 746//678 727//557 729//684
            +f 757//679 746//678 729//684
            +f 757//679 729//684 748//685
            +f 776//680 757//679 748//685
            +f 776//680 748//685 755//686
            +f 783//681 776//680 755//686
            +f 783//681 755//686 774//687
            +f 802//682 783//681 774//687
            +f 802//682 774//687 782//688
            +f 810//683 802//682 782//688
            +f 810//683 782//688 809//689
            +f 729//684 727//557 699//563
            +f 729//684 699//563 719//690
            +f 748//685 729//684 719//690
            +f 748//685 719//690 726//691
            +f 755//686 748//685 726//691
            +f 755//686 726//691 745//692
            +f 774//687 755//686 745//692
            +f 774//687 745//692 754//693
            +f 782//688 774//687 754//693
            +f 782//688 754//693 781//694
            +f 809//689 782//688 781//694
            +f 809//689 781//694 780//695
            +f 719//690 699//563 689//569
            +f 719//690 689//569 696//696
            +f 726//691 719//690 696//696
            +f 726//691 696//696 716//697
            +f 745//692 726//691 716//697
            +f 745//692 716//697 725//698
            +f 754//693 745//692 725//698
            +f 754//693 725//698 753//699
            +f 781//694 754//693 753//699
            +f 781//694 753//699 752//700
            +f 780//695 781//694 752//700
            +f 780//695 752//700 773//701
            +f 696//696 689//569 668//575
            +f 696//696 668//575 686//702
            +f 716//697 696//696 686//702
            +f 716//697 686//702 695//703
            +f 725//698 716//697 695//703
            +f 725//698 695//703 724//704
            +f 753//699 725//698 724//704
            +f 753//699 724//704 723//705
            +f 752//700 753//699 723//705
            +f 752//700 723//705 744//706
            +f 773//701 752//700 744//706
            +f 773//701 744//706 772//707
            +f 686//702 668//575 641//579
            +f 686//702 641//579 667//708
            +f 695//703 686//702 667//708
            +f 695//703 667//708 715//160
            +f 724//704 695//703 715//160
            +f 724//704 715//160 694//709
            +f 723//705 724//704 694//709
            +f 723//705 694//709 714//710
            +f 744//706 723//705 714//710
            +f 744//706 714//710 743//711
            +f 772//707 744//706 743//711
            +f 772//707 743//711 771//712
            +f 694//709 715//160 666//713
            +f 694//709 666//713 685//714
            +f 714//710 694//709 685//714
            +f 714//710 685//714 713//715
            +f 743//711 714//710 713//715
            +f 743//711 713//715 742//716
            +f 771//712 743//711 742//716
            +f 771//712 742//716 770//717
            +f 666//713 631//152 658//718
            +f 685//714 666//713 658//718
            +f 685//714 658//718 684//719
            +f 713//715 685//714 684//719
            +f 713//715 684//719 712//720
            +f 742//716 713//715 712//720
            +f 742//716 712//720 741//721
            +f 770//717 742//716 741//721
            +f 770//717 741//721 769//722
            +f 631//152 605//592 604//593
            +f 631//152 604//593 630//723
            +f 658//718 631//152 630//723
            +f 658//718 630//723 657//724
            +f 684//719 658//718 657//724
            +f 684//719 657//724 683//725
            +f 712//720 684//719 683//725
            +f 712//720 683//725 711//726
            +f 741//721 712//720 711//726
            +f 741//721 711//726 740//727
            +f 769//722 741//721 740//727
            +f 769//722 740//727 768//728
            +f 630//723 604//593 603//599
            +f 630//723 603//599 629//729
            +f 657//724 630//723 629//729
            +f 657//724 629//729 656//730
            +f 683//725 657//724 656//730
            +f 683//725 656//730 682//731
            +f 711//726 683//725 682//731
            +f 711//726 682//731 710//732
            +f 740//727 711//726 710//732
            +f 740//727 710//732 739//733
            +f 768//728 740//727 739//733
            +f 768//728 739//733 767//734
            +f 629//729 603//599 602//605
            +f 629//729 602//605 628//735
            +f 656//730 629//729 628//735
            +f 656//730 628//735 655//736
            +f 682//731 656//730 655//736
            +f 682//731 655//736 681//737
            +f 710//732 682//731 681//737
            +f 710//732 681//737 709//738
            +f 739//733 710//732 709//738
            +f 739//733 709//738 738//739
            +f 767//734 739//733 738//739
            +f 767//734 738//739 766//740
            +f 628//735 602//605 601//611
            +f 628//735 601//611 627//741
            +f 655//736 628//735 627//741
            +f 655//736 627//741 654//742
            +f 681//737 655//736 654//742
            +f 681//737 654//742 680//743
            +f 709//738 681//737 680//743
            +f 709//738 680//743 708//744
            +f 738//739 709//738 708//744
            +f 738//739 708//744 737//745
            +f 766//740 738//739 737//745
            +f 766//740 737//745 765//746
            +f 627//741 601//611 600//617
            +f 627//741 600//617 626//747
            +f 654//742 627//741 626//747
            +f 654//742 626//747 653//748
            +f 680//743 654//742 653//748
            +f 680//743 653//748 679//749
            +f 708//744 680//743 679//749
            +f 708//744 679//749 707//750
            +f 737//745 708//744 707//750
            +f 737//745 707//750 736//751
            +f 765//746 737//745 736//751
            +f 765//746 736//751 764//752
            +f 626//747 600//617 599//623
            +f 626//747 599//623 625//753
            +f 653//748 626//747 625//753
            +f 653//748 625//753 652//754
            +f 679//749 653//748 652//754
            +f 679//749 652//754 678//755
            +f 707//750 679//749 678//755
            +f 707//750 678//755 706//756
            +f 736//751 707//750 706//756
            +f 736//751 706//756 735//757
            +f 764//752 736//751 735//757
            +f 764//752 735//757 763//758
            +f 625//753 599//623 598//629
            +f 625//753 598//629 624//759
            +f 652//754 625//753 624//759
            +f 652//754 624//759 651//760
            +f 678//755 652//754 651//760
            +f 678//755 651//760 677//761
            +f 706//756 678//755 677//761
            +f 706//756 677//761 705//762
            +f 735//757 706//756 705//762
            +f 735//757 705//762 734//763
            +f 763//758 735//757 734//763
            +f 763//758 734//763 762//764
            +f 624//759 598//629 597//635
            +f 624//759 597//635 623//765
            +f 651//760 624//759 623//765
            +f 651//760 623//765 650//766
            +f 677//761 651//760 650//766
            +f 677//761 650//766 676//767
            +f 705//762 677//761 676//767
            +f 705//762 676//767 704//768
            +f 734//763 705//762 704//768
            +f 734//763 704//768 733//769
            +f 762//764 734//763 733//769
            +f 762//764 733//769 761//770
            +f 623//765 597//635 596//641
            +f 623//765 596//641 622//771
            +f 650//766 623//765 622//771
            +f 650//766 622//771 649//772
            +f 676//767 650//766 649//772
            +f 676//767 649//772 675//773
            +f 704//768 676//767 675//773
            +f 704//768 675//773 703//774
            +f 733//769 704//768 703//774
            +f 733//769 703//774 732//775
            +f 761//770 733//769 732//775
            +f 761//770 732//775 760//776
            +f 622//771 596//641 613//248
            +f 622//771 613//248 640//777
            +f 649//772 622//771 640//777
            +f 649//772 640//777 665//778
            +f 675//773 649//772 665//778
            +f 675//773 665//778 693//779
            +f 703//774 675//773 693//779
            +f 703//774 693//779 722//780
            +f 732//775 703//774 722//780
            +f 732//775 722//780 751//781
            +f 760//776 732//775 751//781
            +f 760//776 751//781 779//782
            +f 693//779 665//778 691//228
            +f 693//779 691//228 702//646
            +f 722//780 693//779 702//646
            +f 722//780 702//646 731//648
            +f 751//781 722//780 731//648
            +f 751//781 731//648 759//650
            +f 779//782 751//781 759//650
            +f 779//782 759//650 786//652
            +f 917//783 918//784 913//785
            +f 892//786 917//783 913//785
            +f 892//786 913//785 887//787
            +f 866//788 892//786 887//787
            +f 866//788 887//787 861//789
            +f 840//790 866//788 861//789
            +f 840//790 861//789 834//791
            +f 813//792 840//790 834//791
            +f 813//792 834//791 807//793
            +f 786//652 813//792 807//793
            +f 786//652 807//793 779//782
            +f 913//785 918//784 893//794
            +f 887//787 913//785 893//794
            +f 887//787 893//794 867//795
            +f 861//789 887//787 867//795
            +f 861//789 867//795 841//796
            +f 834//791 861//789 841//796
            +f 834//791 841//796 814//797
            +f 807//793 834//791 814//797
            +f 807//793 814//797 787//798
            +f 779//782 807//793 787//798
            +f 779//782 787//798 760//776
            +f 893//794 918//784 894//799
            +f 867//795 893//794 894//799
            +f 867//795 894//799 868//800
            +f 841//796 867//795 868//800
            +f 841//796 868//800 842//801
            +f 814//797 841//796 842//801
            +f 814//797 842//801 815//802
            +f 787//798 814//797 815//802
            +f 787//798 815//802 788//803
            +f 760//776 787//798 788//803
            +f 760//776 788//803 761//770
            +f 894//799 918//784 895//804
            +f 868//800 894//799 895//804
            +f 868//800 895//804 869//805
            +f 842//801 868//800 869//805
            +f 842//801 869//805 843//806
            +f 815//802 842//801 843//806
            +f 815//802 843//806 816//807
            +f 788//803 815//802 816//807
            +f 788//803 816//807 789//808
            +f 761//770 788//803 789//808
            +f 761//770 789//808 762//764
            +f 895//804 918//784 896//809
            +f 869//805 895//804 896//809
            +f 869//805 896//809 870//810
            +f 843//806 869//805 870//810
            +f 843//806 870//810 844//811
            +f 816//807 843//806 844//811
            +f 816//807 844//811 817//812
            +f 789//808 816//807 817//812
            +f 789//808 817//812 790//813
            +f 762//764 789//808 790//813
            +f 762//764 790//813 763//758
            +f 896//809 918//784 897//814
            +f 870//810 896//809 897//814
            +f 870//810 897//814 871//815
            +f 844//811 870//810 871//815
            +f 844//811 871//815 845//816
            +f 817//812 844//811 845//816
            +f 817//812 845//816 818//817
            +f 790//813 817//812 818//817
            +f 790//813 818//817 791//818
            +f 763//758 790//813 791//818
            +f 763//758 791//818 764//752
            +f 897//814 918//784 898//819
            +f 871//815 897//814 898//819
            +f 871//815 898//819 872//820
            +f 845//816 871//815 872//820
            +f 845//816 872//820 846//821
            +f 818//817 845//816 846//821
            +f 818//817 846//821 819//822
            +f 791//818 818//817 819//822
            +f 791//818 819//822 792//823
            +f 764//752 791//818 792//823
            +f 764//752 792//823 765//746
            +f 898//819 918//784 899//824
            +f 872//820 898//819 899//824
            +f 872//820 899//824 873//825
            +f 846//821 872//820 873//825
            +f 846//821 873//825 847//826
            +f 819//822 846//821 847//826
            +f 819//822 847//826 820//827
            +f 792//823 819//822 820//827
            +f 792//823 820//827 793//828
            +f 765//746 792//823 793//828
            +f 765//746 793//828 766//740
            +f 899//824 918//784 900//829
            +f 873//825 899//824 900//829
            +f 873//825 900//829 874//830
            +f 847//826 873//825 874//830
            +f 847//826 874//830 848//831
            +f 820//827 847//826 848//831
            +f 820//827 848//831 821//832
            +f 793//828 820//827 821//832
            +f 793//828 821//832 794//833
            +f 766//740 793//828 794//833
            +f 766//740 794//833 767//734
            +f 900//829 918//784 901//834
            +f 874//830 900//829 901//834
            +f 874//830 901//834 875//835
            +f 848//831 874//830 875//835
            +f 848//831 875//835 849//836
            +f 821//832 848//831 849//836
            +f 821//832 849//836 822//837
            +f 794//833 821//832 822//837
            +f 794//833 822//837 795//838
            +f 767//734 794//833 795//838
            +f 767//734 795//838 768//728
            +f 901//834 918//784 902//839
            +f 875//835 901//834 902//839
            +f 875//835 902//839 876//840
            +f 849//836 875//835 876//840
            +f 849//836 876//840 850//841
            +f 822//837 849//836 850//841
            +f 822//837 850//841 823//842
            +f 795//838 822//837 823//842
            +f 795//838 823//842 796//843
            +f 768//728 795//838 796//843
            +f 768//728 796//843 769//722
            +f 902//839 918//784 903//844
            +f 876//840 902//839 903//844
            +f 876//840 903//844 877//845
            +f 850//841 876//840 877//845
            +f 850//841 877//845 851//846
            +f 823//842 850//841 851//846
            +f 823//842 851//846 824//847
            +f 796//843 823//842 824//847
            +f 796//843 824//847 797//848
            +f 769//722 796//843 797//848
            +f 769//722 797//848 770//717
            +f 903//844 918//784 904//849
            +f 877//845 903//844 904//849
            +f 877//845 904//849 878//850
            +f 851//846 877//845 878//850
            +f 851//846 878//850 852//851
            +f 824//847 851//846 852//851
            +f 824//847 852//851 825//852
            +f 797//848 824//847 825//852
            +f 797//848 825//852 798//853
            +f 770//717 797//848 798//853
            +f 770//717 798//853 771//712
            +f 904//849 918//784 905//854
            +f 878//850 904//849 905//854
            +f 878//850 905//854 879//855
            +f 852//851 878//850 879//855
            +f 852//851 879//855 853//856
            +f 825//852 852//851 853//856
            +f 825//852 853//856 826//857
            +f 798//853 825//852 826//857
            +f 798//853 826//857 799//858
            +f 771//712 798//853 799//858
            +f 771//712 799//858 772//707
            +f 905//854 918//784 906//859
            +f 879//855 905//854 906//859
            +f 879//855 906//859 880//860
            +f 853//856 879//855 880//860
            +f 853//856 880//860 854//861
            +f 826//857 853//856 854//861
            +f 826//857 854//861 827//862
            +f 799//858 826//857 827//862
            +f 799//858 827//862 800//863
            +f 772//707 799//858 800//863
            +f 772//707 800//863 773//701
            +f 906//859 918//784 907//864
            +f 880//860 906//859 907//864
            +f 880//860 907//864 881//865
            +f 854//861 880//860 881//865
            +f 854//861 881//865 855//866
            +f 827//862 854//861 855//866
            +f 827//862 855//866 828//867
            +f 800//863 827//862 828//867
            +f 800//863 828//867 801//868
            +f 773//701 800//863 801//868
            +f 773//701 801//868 780//695
            +f 907//864 918//784 908//869
            +f 881//865 907//864 908//869
            +f 881//865 908//869 882//870
            +f 855//866 881//865 882//870
            +f 855//866 882//870 856//871
            +f 828//867 855//866 856//871
            +f 828//867 856//871 829//872
            +f 801//868 828//867 829//872
            +f 801//868 829//872 808//873
            +f 780//695 801//868 808//873
            +f 780//695 808//873 809//689
            +f 908//869 918//784 909//874
            +f 882//870 908//869 909//874
            +f 882//870 909//874 883//875
            +f 856//871 882//870 883//875
            +f 856//871 883//875 857//876
            +f 829//872 856//871 857//876
            +f 829//872 857//876 836//877
            +f 808//873 829//872 836//877
            +f 808//873 836//877 835//878
            +f 809//689 808//873 835//878
            +f 809//689 835//878 810//683
            +f 909//874 918//784 910//879
            +f 883//875 909//874 910//879
            +f 883//875 910//879 884//880
            +f 857//876 883//875 884//880
            +f 857//876 884//880 863//881
            +f 836//877 857//876 863//881
            +f 836//877 863//881 862//882
            +f 835//878 836//877 862//882
            +f 835//878 862//882 837//883
            +f 810//683 835//878 837//883
            +f 810//683 837//883 830//677
            +f 910//879 918//784 911//884
            +f 884//880 910//879 911//884
            +f 884//880 911//884 889//885
            +f 863//881 884//880 889//885
            +f 863//881 889//885 888//886
            +f 862//882 863//881 888//886
            +f 862//882 888//886 864//887
            +f 837//883 862//882 864//887
            +f 837//883 864//887 858//888
            +f 830//677 837//883 858//888
            +f 830//677 858//888 838//671
            +f 911//884 918//784 915//889
            +f 889//885 911//884 915//889
            +f 889//885 915//889 914//890
            +f 888//886 889//885 914//890
            +f 888//886 914//890 890//891
            +f 864//887 888//886 890//891
            +f 864//887 890//891 885//892
            +f 858//888 864//887 885//892
            +f 858//888 885//892 859//893
            +f 838//671 858//888 859//893
            +f 838//671 859//893 833//665
            +f 915//889 918//784 919//894
            +f 914//890 915//889 919//894
            +f 914//890 919//894 912//895
            +f 890//891 914//890 912//895
            +f 890//891 912//895 886//896
            +f 885//892 890//891 886//896
            +f 885//892 886//896 860//897
            +f 859//893 885//892 860//897
            +f 859//893 860//897 832//898
            +f 833//665 859//893 832//898
            +f 833//665 832//898 805//659
            +f 919//894 918//784 916//899
            +f 912//895 919//894 916//899
            +f 912//895 916//899 891//900
            +f 886//896 912//895 891//900
            +f 886//896 891//900 865//901
            +f 860//897 886//896 865//901
            +f 860//897 865//901 839//902
            +f 832//898 860//897 839//902
            +f 832//898 839//902 812//903
            +f 805//659 832//898 812//903
            +f 805//659 812//903 785//653
            +f 916//899 918//784 917//783
            +f 891//900 916//899 917//783
            +f 891//900 917//783 892//786
            +f 865//901 891//900 892//786
            +f 865//901 892//786 866//788
            +f 839//902 865//901 866//788
            +f 839//902 866//788 840//790
            +f 812//903 839//902 840//790
            +f 812//903 840//790 813//792
            +f 785//653 812//903 813//792
            +f 785//653 813//792 786//652
            +f 404//412 1267//904 1268//905
            +f 384//906 373//907 372//480
            +f 346//908 345//501 352//494
            +f 435//909 436//426 419//419
            +f 331//910 327//350 335//508
            +f 462//439 453//433 1265//911
            +f 920//912 921//913 922//914
            +f 920//912 922//914 923//915
            +f 923//915 922//914 927//916
            +f 923//915 927//916 933//917
            +f 933//917 927//916 940//918
            +f 933//917 940//918 949//919
            +f 949//919 940//918 959//920
            +f 949//919 959//920 971//921
            +f 971//921 959//920 984//922
            +f 971//921 984//922 999//923
            +f 999//923 984//922 1011//924
            +f 999//923 1011//924 1027//925
            +f 1027//925 1011//924 1042//926
            +f 1027//925 1042//926 1059//927
            +f 1059//927 1042//926 1077//928
            +f 1059//927 1077//928 1095//929
            +f 1095//929 1077//928 1110//930
            +f 1095//929 1110//930 1129//931
            +f 1129//931 1110//930 1144//932
            +f 1129//931 1144//932 1163//933
            +f 1163//933 1144//932 1179//934
            +f 1163//933 1179//934 1196//935
            +f 1196//935 1179//934 1210//936
            +f 1196//935 1210//936 1220//937
            +f 1220//937 1210//936 1212//938
            +f 1220//937 1212//938 1201//939
            +f 1201//939 1212//938 1181//940
            +f 1201//939 1181//940 1169//941
            +f 1169//941 1181//940 1147//942
            +f 1169//941 1147//942 1135//943
            +f 1135//943 1147//942 1113//944
            +f 1135//943 1113//944 1102//945
            +f 1102//945 1113//944 1081//946
            +f 1102//945 1081//946 1065//947
            +f 1065//947 1081//946 1046//948
            +f 1065//947 1046//948 1032//949
            +f 1032//949 1046//948 1016//950
            +f 1032//949 1016//950 1003//951
            +f 1003//951 1016//950 988//952
            +f 1003//951 988//952 974//953
            +f 974//953 988//952 962//954
            +f 974//953 962//954 951//955
            +f 951//955 962//954 942//956
            +f 951//955 942//956 934//957
            +f 934//957 942//956 928//958
            +f 934//957 928//958 924//959
            +f 924//959 928//958 921//913
            +f 921//913 920//912 924//959
            +f 926//960 920//912 923//915
            +f 926//960 923//915 932//961
            +f 938//962 926//960 932//961
            +f 938//962 932//961 947//963
            +f 956//964 938//962 947//963
            +f 956//964 947//963 968//965
            +f 980//966 956//964 968//965
            +f 980//966 968//965 995//967
            +f 1006//968 980//966 995//967
            +f 1006//968 995//967 1022//969
            +f 1036//970 1006//968 1022//969
            +f 1036//970 1022//969 1053//971
            +f 932//961 923//915 933//917
            +f 932//961 933//917 948//972
            +f 947//963 932//961 948//972
            +f 947//963 948//972 969//973
            +f 968//965 947//963 969//973
            +f 968//965 969//973 996//974
            +f 995//967 968//965 996//974
            +f 995//967 996//974 1023//975
            +f 1022//969 995//967 1023//975
            +f 1022//969 1023//975 1054//976
            +f 1053//971 1022//969 1054//976
            +f 1053//971 1054//976 1089//977
            +f 948//972 933//917 949//919
            +f 948//972 949//919 970//978
            +f 969//973 948//972 970//978
            +f 969//973 970//978 997//979
            +f 996//974 969//973 997//979
            +f 996//974 997//979 1024//980
            +f 1023//975 996//974 1024//980
            +f 1023//975 1024//980 1055//981
            +f 1054//976 1023//975 1055//981
            +f 1054//976 1055//981 1090//982
            +f 1089//977 1054//976 1090//982
            +f 1089//977 1090//982 1109//983
            +f 970//978 949//919 971//921
            +f 970//978 971//921 998//984
            +f 997//979 970//978 998//984
            +f 997//979 998//984 1025//985
            +f 1024//980 997//979 1025//985
            +f 1024//980 1025//985 1056//986
            +f 1055//981 1024//980 1056//986
            +f 1055//981 1056//986 1091//987
            +f 1090//982 1055//981 1091//987
            +f 1090//982 1091//987 1124//988
            +f 1109//983 1090//982 1124//988
            +f 1109//983 1124//988 1122//989
            +f 998//984 971//921 999//923
            +f 998//984 999//923 1026//990
            +f 1025//985 998//984 1026//990
            +f 1025//985 1026//990 1057//991
            +f 1056//986 1025//985 1057//991
            +f 1056//986 1057//991 1092//992
            +f 1091//987 1056//986 1092//992
            +f 1091//987 1092//992 1125//993
            +f 1124//988 1091//987 1125//993
            +f 1124//988 1125//993 1156//994
            +f 1122//989 1124//988 1156//994
            +f 1122//989 1156//994 1142//995
            +f 1026//990 999//923 1027//925
            +f 1026//990 1027//925 1058//996
            +f 1057//991 1026//990 1058//996
            +f 1057//991 1058//996 1093//997
            +f 1092//992 1057//991 1093//997
            +f 1092//992 1093//997 1126//998
            +f 1125//993 1092//992 1126//998
            +f 1125//993 1126//998 1159//999
            +f 1156//994 1125//993 1159//999
            +f 1156//994 1159//999 1176//1000
            +f 1142//995 1156//994 1176//1000
            +f 1142//995 1176//1000 1157//1001
            +f 1058//996 1027//925 1059//927
            +f 1058//996 1059//927 1094//1002
            +f 1093//997 1058//996 1094//1002
            +f 1093//997 1094//1002 1127//1003
            +f 1126//998 1093//997 1127//1003
            +f 1126//998 1127//1003 1160//1004
            +f 1159//999 1126//998 1160//1004
            +f 1159//999 1160//1004 1192//1005
            +f 1176//1000 1159//999 1192//1005
            +f 1176//1000 1192//1005 1189//1006
            +f 1157//1001 1176//1000 1189//1006
            +f 1157//1001 1189//1006 1178//1007
            +f 1094//1002 1059//927 1095//929
            +f 1094//1002 1095//929 1128//1008
            +f 1127//1003 1094//1002 1128//1008
            +f 1127//1003 1128//1008 1161//1009
            +f 1160//1004 1127//1003 1161//1009
            +f 1160//1004 1161//1009 1193//1010
            +f 1192//1005 1160//1004 1193//1010
            +f 1192//1005 1193//1010 1215//1011
            +f 1189//1006 1192//1005 1215//1011
            +f 1189//1006 1215//1011 1207//1012
            +f 1178//1007 1189//1006 1207//1012
            +f 1178//1007 1207//1012 1191//1013
            +f 1128//1008 1095//929 1129//931
            +f 1128//1008 1129//931 1162//1014
            +f 1161//1009 1128//1008 1162//1014
            +f 1161//1009 1162//1014 1194//1015
            +f 1193//1010 1161//1009 1194//1015
            +f 1193//1010 1194//1015 1217//1016
            +f 1215//1011 1193//1010 1217//1016
            +f 1215//1011 1217//1016 1227//1017
            +f 1207//1012 1215//1011 1227//1017
            +f 1207//1012 1227//1017 1216//1018
            +f 1191//1013 1207//1012 1216//1018
            +f 1191//1013 1216//1018 1209//1019
            +f 1162//1014 1129//931 1163//933
            +f 1162//1014 1163//933 1195//1020
            +f 1194//1015 1162//1014 1195//1020
            +f 1194//1015 1195//1020 1218//1021
            +f 1217//1016 1194//1015 1218//1021
            +f 1217//1016 1218//1021 1230//1022
            +f 1227//1017 1217//1016 1230//1022
            +f 1227//1017 1230//1022 1229//1023
            +f 1216//1018 1227//1017 1229//1023
            +f 1216//1018 1229//1023 1225//1024
            +f 1209//1019 1216//1018 1225//1024
            +f 1209//1019 1225//1024 1203//1025
            +f 1195//1020 1163//933 1196//935
            +f 1195//1020 1196//935 1219//1026
            +f 1218//1021 1195//1020 1219//1026
            +f 1218//1021 1219//1026 1231//1027
            +f 1230//1022 1218//1021 1231//1027
            +f 1230//1022 1231//1027 1232//1028
            +f 1229//1023 1230//1022 1232//1028
            +f 1229//1023 1232//1028 1228//1029
            +f 1225//1024 1229//1023 1228//1029
            +f 1225//1024 1228//1029 1214//1030
            +f 1203//1025 1225//1024 1214//1030
            +f 1203//1025 1214//1030 1184//1031
            +f 1219//1026 1196//935 1220//937
            +f 1219//1026 1220//937 1224//1032
            +f 1231//1027 1219//1026 1224//1032
            +f 1231//1027 1224//1032 1223//1033
            +f 1232//1028 1231//1027 1223//1033
            +f 1232//1028 1223//1033 1222//1034
            +f 1228//1029 1232//1028 1222//1034
            +f 1228//1029 1222//1034 1221//1035
            +f 1214//1030 1228//1029 1221//1035
            +f 1214//1030 1221//1035 1204//1036
            +f 1184//1031 1214//1030 1204//1036
            +f 1184//1031 1204//1036 1171//1037
            +f 1224//1032 1220//937 1201//939
            +f 1224//1032 1201//939 1200//1038
            +f 1223//1033 1224//1032 1200//1038
            +f 1223//1033 1200//1038 1199//1039
            +f 1222//1034 1223//1033 1199//1039
            +f 1222//1034 1199//1039 1198//1040
            +f 1221//1035 1222//1034 1198//1040
            +f 1221//1035 1198//1040 1197//1041
            +f 1204//1036 1221//1035 1197//1041
            +f 1204//1036 1197//1041 1185//1042
            +f 1171//1037 1204//1036 1185//1042
            +f 1171//1037 1185//1042 1151//1043
            +f 1200//1038 1201//939 1169//941
            +f 1200//1038 1169//941 1168//1044
            +f 1199//1039 1200//1038 1168//1044
            +f 1199//1039 1168//1044 1167//1045
            +f 1198//1040 1199//1039 1167//1045
            +f 1198//1040 1167//1045 1166//1046
            +f 1197//1041 1198//1040 1166//1046
            +f 1197//1041 1166//1046 1165//1047
            +f 1185//1042 1197//1041 1165//1047
            +f 1185//1042 1165//1047 1164//1048
            +f 1151//1043 1185//1042 1164//1048
            +f 1151//1043 1164//1048 1137//1049
            +f 1168//1044 1169//941 1135//943
            +f 1168//1044 1135//943 1134//1050
            +f 1167//1045 1168//1044 1134//1050
            +f 1167//1045 1134//1050 1133//1051
            +f 1166//1046 1167//1045 1133//1051
            +f 1166//1046 1133//1051 1132//1052
            +f 1165//1047 1166//1046 1132//1052
            +f 1165//1047 1132//1052 1131//1053
            +f 1164//1048 1165//1047 1131//1053
            +f 1164//1048 1131//1053 1130//1054
            +f 1137//1049 1164//1048 1130//1054
            +f 1137//1049 1130//1054 1117//1055
            +f 1134//1050 1135//943 1102//945
            +f 1134//1050 1102//945 1101//1056
            +f 1133//1051 1134//1050 1101//1056
            +f 1133//1051 1101//1056 1100//1057
            +f 1132//1052 1133//1051 1100//1057
            +f 1132//1052 1100//1057 1099//1058
            +f 1131//1053 1132//1052 1099//1058
            +f 1131//1053 1099//1058 1098//1059
            +f 1130//1054 1131//1053 1098//1059
            +f 1130//1054 1098//1059 1097//1060
            +f 1117//1055 1130//1054 1097//1060
            +f 1117//1055 1097//1060 1096//1061
            +f 1101//1056 1102//945 1065//947
            +f 1101//1056 1065//947 1064//1062
            +f 1100//1057 1101//1056 1064//1062
            +f 1100//1057 1064//1062 1063//1063
            +f 1099//1058 1100//1057 1063//1063
            +f 1099//1058 1063//1063 1062//1064
            +f 1098//1059 1099//1058 1062//1064
            +f 1098//1059 1062//1064 1061//1065
            +f 1097//1060 1098//1059 1061//1065
            +f 1097//1060 1061//1065 1060//1066
            +f 1096//1061 1097//1060 1060//1066
            +f 1096//1061 1060//1066 1066//1067
            +f 1064//1062 1065//947 1032//949
            +f 1064//1062 1032//949 1031//1068
            +f 1063//1063 1064//1062 1031//1068
            +f 1063//1063 1031//1068 1030//1069
            +f 1062//1064 1063//1063 1030//1069
            +f 1062//1064 1030//1069 1029//1070
            +f 1061//1065 1062//1064 1029//1070
            +f 1061//1065 1029//1070 1028//1071
            +f 1060//1066 1061//1065 1028//1071
            +f 1060//1066 1028//1071 1033//1072
            +f 1066//1067 1060//1066 1033//1072
            +f 1066//1067 1033//1072 1050//1073
            +f 1031//1068 1032//949 1003//951
            +f 1031//1068 1003//951 1002//1074
            +f 1030//1069 1031//1068 1002//1074
            +f 1030//1069 1002//1074 1001//1075
            +f 1029//1070 1030//1069 1001//1075
            +f 1029//1070 1001//1075 1000//1076
            +f 1028//1071 1029//1070 1000//1076
            +f 1028//1071 1000//1076 1004//1077
            +f 1033//1072 1028//1071 1004//1077
            +f 1033//1072 1004//1077 1021//1078
            +f 1050//1073 1033//1072 1021//1078
            +f 1050//1073 1021//1078 1041//1079
            +f 1002//1074 1003//951 974//953
            +f 1002//1074 974//953 973//1080
            +f 1001//1075 1002//1074 973//1080
            +f 1001//1075 973//1080 972//1081
            +f 1000//1076 1001//1075 972//1081
            +f 1000//1076 972//1081 975//1082
            +f 1004//1077 1000//1076 975//1082
            +f 1004//1077 975//1082 992//1083
            +f 1021//1078 1004//1077 992//1083
            +f 1021//1078 992//1083 1010//1084
            +f 1041//1079 1021//1078 1010//1084
            +f 1041//1079 1010//1084 1040//1085
            +f 973//1080 974//953 951//955
            +f 973//1080 951//955 950//1086
            +f 972//1081 973//1080 950//1086
            +f 972//1081 950//1086 952//1087
            +f 975//1082 972//1081 952//1087
            +f 975//1082 952//1087 965//1088
            +f 992//1083 975//1082 965//1088
            +f 992//1083 965//1088 983//1089
            +f 1010//1084 992//1083 983//1089
            +f 1010//1084 983//1089 1009//1090
            +f 1040//1085 1010//1084 1009//1090
            +f 1040//1085 1009//1090 1039//1091
            +f 950//1086 951//955 934//957
            +f 950//1086 934//957 935//1092
            +f 952//1087 950//1086 935//1092
            +f 952//1087 935//1092 944//1093
            +f 965//1088 952//1087 944//1093
            +f 965//1088 944//1093 958//1094
            +f 983//1089 965//1088 958//1094
            +f 983//1089 958//1094 982//1095
            +f 1009//1090 983//1089 982//1095
            +f 1009//1090 982//1095 1008//1096
            +f 1039//1091 1009//1090 1008//1096
            +f 1039//1091 1008//1096 1038//1097
            +f 935//1092 934//957 924//959
            +f 935//1092 924//959 929//1098
            +f 944//1093 935//1092 929//1098
            +f 944//1093 929//1098 939//1099
            +f 958//1094 944//1093 939//1099
            +f 958//1094 939//1099 957//1100
            +f 982//1095 958//1094 957//1100
            +f 982//1095 957//1100 981//1101
            +f 1008//1096 982//1095 981//1101
            +f 1008//1096 981//1101 1007//1102
            +f 1038//1097 1008//1096 1007//1102
            +f 1038//1097 1007//1102 1037//1103
            +f 924//959 920//912 929//1098
            +f 929//1098 920//912 926//960
            +f 939//1099 929//1098 926//960
            +f 939//1099 926//960 938//962
            +f 957//1100 939//1099 938//962
            +f 957//1100 938//962 956//964
            +f 981//1101 957//1100 956//964
            +f 981//1101 956//964 980//966
            +f 1007//1102 981//1101 980//966
            +f 1007//1102 980//966 1006//968
            +f 1037//1103 1007//1102 1006//968
            +f 1037//1103 1006//968 1036//970
            +f 993//1104 1005//1105 976//1106
            +f 966//1107 993//1104 976//1106
            +f 966//1107 976//1106 953//1108
            +f 945//1109 966//1107 953//1108
            +f 945//1109 953//1108 936//1110
            +f 930//1111 945//1109 936//1110
            +f 930//1111 936//1110 925//1112
            +f 921//913 930//1111 925//1112
            +f 921//913 925//1112 922//914
            +f 976//1106 1005//1105 977//1113
            +f 953//1108 976//1106 977//1113
            +f 953//1108 977//1113 954//1114
            +f 936//1110 953//1108 954//1114
            +f 936//1110 954//1114 937//1115
            +f 925//1112 936//1110 937//1115
            +f 925//1112 937//1115 931//1116
            +f 922//914 925//1112 931//1116
            +f 922//914 931//1116 927//916
            +f 977//1113 1005//1105 978//1117
            +f 954//1114 977//1113 978//1117
            +f 954//1114 978//1117 955//1118
            +f 937//1115 954//1114 955//1118
            +f 937//1115 955//1118 946//1119
            +f 931//1116 937//1115 946//1119
            +f 931//1116 946//1119 941//1120
            +f 927//916 931//1116 941//1120
            +f 927//916 941//1120 940//918
            +f 978//1117 1005//1105 979//1121
            +f 955//1118 978//1117 979//1121
            +f 955//1118 979//1121 967//1122
            +f 946//1119 955//1118 967//1122
            +f 946//1119 967//1122 961//1123
            +f 941//1120 946//1119 961//1123
            +f 941//1120 961//1123 960//1124
            +f 940//918 941//1120 960//1124
            +f 940//918 960//1124 959//920
            +f 979//1121 1005//1105 994//1125
            +f 967//1122 979//1121 994//1125
            +f 967//1122 994//1125 987//1126
            +f 961//1123 967//1122 987//1126
            +f 961//1123 987//1126 986//1127
            +f 960//1124 961//1123 986//1127
            +f 960//1124 986//1127 985//1128
            +f 959//920 960//1124 985//1128
            +f 959//920 985//1128 984//922
            +f 994//1125 1005//1105 1015//1129
            +f 987//1126 994//1125 1015//1129
            +f 987//1126 1015//1129 1014//1130
            +f 986//1127 987//1126 1014//1130
            +f 986//1127 1014//1130 1013//1131
            +f 985//1128 986//1127 1013//1131
            +f 985//1128 1013//1131 1012//1132
            +f 984//922 985//1128 1012//1132
            +f 984//922 1012//1132 1011//924
            +f 1015//1129 1005//1105 1035//1133
            +f 1014//1130 1015//1129 1035//1133
            +f 1014//1130 1035//1133 1045//1134
            +f 1013//1131 1014//1130 1045//1134
            +f 1013//1131 1045//1134 1044//1135
            +f 1012//1132 1013//1131 1044//1135
            +f 1012//1132 1044//1135 1043//1136
            +f 1011//924 1012//1132 1043//1136
            +f 1011//924 1043//1136 1042//926
            +f 1035//1133 1005//1105 1052//1137
            +f 1045//1134 1035//1133 1052//1137
            +f 1045//1134 1052//1137 1080//1138
            +f 1044//1135 1045//1134 1080//1138
            +f 1044//1135 1080//1138 1079//1139
            +f 1043//1136 1044//1135 1079//1139
            +f 1043//1136 1079//1139 1078//1140
            +f 1042//926 1043//1136 1078//1140
            +f 1042//926 1078//1140 1077//928
            +f 1052//1137 1005//1105 1068//1141
            +f 1080//1138 1052//1137 1068//1141
            +f 1080//1138 1068//1141 1106//1142
            +f 1079//1139 1080//1138 1106//1142
            +f 1079//1139 1106//1142 1112//1143
            +f 1078//1140 1079//1139 1112//1143
            +f 1078//1140 1112//1143 1111//1144
            +f 1077//928 1078//1140 1111//1144
            +f 1077//928 1111//1144 1110//930
            +f 1068//1141 1005//1105 1087//1145
            +f 1106//1142 1068//1141 1087//1145
            +f 1106//1142 1087//1145 1120//1146
            +f 1112//1143 1106//1142 1120//1146
            +f 1112//1143 1120//1146 1146//1147
            +f 1111//1144 1112//1143 1146//1147
            +f 1111//1144 1146//1147 1145//1148
            +f 1110//930 1111//1144 1145//1148
            +f 1110//930 1145//1148 1144//932
            +f 1087//1145 1005//1105 1107//1149
            +f 1120//1146 1087//1145 1107//1149
            +f 1120//1146 1107//1149 1140//1150
            +f 1146//1147 1120//1146 1140//1150
            +f 1146//1147 1140//1150 1174//1151
            +f 1145//1148 1146//1147 1174//1151
            +f 1145//1148 1174//1151 1180//1152
            +f 1144//932 1145//1148 1180//1152
            +f 1144//932 1180//1152 1179//934
            +f 1107//1149 1005//1105 1121//1153
            +f 1140//1150 1107//1149 1121//1153
            +f 1140//1150 1121//1153 1154//1154
            +f 1174//1151 1140//1150 1154//1154
            +f 1174//1151 1154//1154 1188//1155
            +f 1180//1152 1174//1151 1188//1155
            +f 1180//1152 1188//1155 1211//1156
            +f 1179//934 1180//1152 1211//1156
            +f 1179//934 1211//1156 1210//936
            +f 1121//1153 1005//1105 1141//1157
            +f 1154//1154 1121//1153 1141//1157
            +f 1154//1154 1141//1157 1175//1158
            +f 1188//1155 1154//1154 1175//1158
            +f 1188//1155 1175//1158 1206//1159
            +f 1211//1156 1188//1155 1206//1159
            +f 1211//1156 1206//1159 1226//1160
            +f 1210//936 1211//1156 1226//1160
            +f 1210//936 1226//1160 1212//938
            +f 1141//1157 1005//1105 1155//1161
            +f 1175//1158 1141//1157 1155//1161
            +f 1175//1158 1155//1161 1187//1162
            +f 1206//1159 1175//1158 1187//1162
            +f 1206//1159 1187//1162 1205//1163
            +f 1226//1160 1206//1159 1205//1163
            +f 1226//1160 1205//1163 1213//1164
            +f 1212//938 1226//1160 1213//1164
            +f 1212//938 1213//1164 1181//940
            +f 1155//1161 1005//1105 1153//1165
            +f 1187//1162 1155//1161 1153//1165
            +f 1187//1162 1153//1165 1173//1166
            +f 1205//1163 1187//1162 1173//1166
            +f 1205//1163 1173//1166 1186//1167
            +f 1213//1164 1205//1163 1186//1167
            +f 1213//1164 1186//1167 1182//1168
            +f 1181//940 1213//1164 1182//1168
            +f 1181//940 1182//1168 1147//942
            +f 1153//1165 1005//1105 1139//1169
            +f 1173//1166 1153//1165 1139//1169
            +f 1173//1166 1139//1169 1152//1170
            +f 1186//1167 1173//1166 1152//1170
            +f 1186//1167 1152//1170 1172//1171
            +f 1182//1168 1186//1167 1172//1171
            +f 1182//1168 1172//1171 1148//1172
            +f 1147//942 1182//1168 1148//1172
            +f 1147//942 1148//1172 1113//944
            +f 1139//1169 1005//1105 1119//1173
            +f 1152//1170 1139//1169 1119//1173
            +f 1152//1170 1119//1173 1138//1174
            +f 1172//1171 1152//1170 1138//1174
            +f 1172//1171 1138//1174 1149//1175
            +f 1148//1172 1172//1171 1149//1175
            +f 1148//1172 1149//1175 1114//1176
            +f 1113//944 1148//1172 1114//1176
            +f 1113//944 1114//1176 1081//946
            +f 1119//1173 1005//1105 1105//1177
            +f 1138//1174 1119//1173 1105//1177
            +f 1138//1174 1105//1177 1118//1178
            +f 1149//1175 1138//1174 1118//1178
            +f 1149//1175 1118//1178 1115//1179
            +f 1114//1176 1149//1175 1115//1179
            +f 1114//1176 1115//1179 1082//1180
            +f 1081//946 1114//1176 1082//1180
            +f 1081//946 1082//1180 1046//948
            +f 1105//1177 1005//1105 1086//1181
            +f 1118//1178 1105//1177 1086//1181
            +f 1118//1178 1086//1181 1104//1182
            +f 1115//1179 1118//1178 1104//1182
            +f 1115//1179 1104//1182 1083//1183
            +f 1082//1180 1115//1179 1083//1183
            +f 1082//1180 1083//1183 1047//1184
            +f 1046//948 1082//1180 1047//1184
            +f 1046//948 1047//1184 1016//950
            +f 1086//1181 1005//1105 1067//1185
            +f 1104//1182 1086//1181 1067//1185
            +f 1104//1182 1067//1185 1084//1186
            +f 1083//1183 1104//1182 1084//1186
            +f 1083//1183 1084//1186 1048//1187
            +f 1047//1184 1083//1183 1048//1187
            +f 1047//1184 1048//1187 1017//1188
            +f 1016//950 1047//1184 1017//1188
            +f 1016//950 1017//1188 988//952
            +f 1067//1185 1005//1105 1051//1189
            +f 1084//1186 1067//1185 1051//1189
            +f 1084//1186 1051//1189 1049//1190
            +f 1048//1187 1084//1186 1049//1190
            +f 1048//1187 1049//1190 1018//1191
            +f 1017//1188 1048//1187 1018//1191
            +f 1017//1188 1018//1191 989//1192
            +f 988//952 1017//1188 989//1192
            +f 988//952 989//1192 962//954
            +f 1051//1189 1005//1105 1034//1193
            +f 1049//1190 1051//1189 1034//1193
            +f 1049//1190 1034//1193 1019//1194
            +f 1018//1191 1049//1190 1019//1194
            +f 1018//1191 1019//1194 990//1195
            +f 989//1192 1018//1191 990//1195
            +f 989//1192 990//1195 963//1196
            +f 962//954 989//1192 963//1196
            +f 962//954 963//1196 942//956
            +f 1034//1193 1005//1105 1020//1197
            +f 1019//1194 1034//1193 1020//1197
            +f 1019//1194 1020//1197 991//1198
            +f 990//1195 1019//1194 991//1198
            +f 990//1195 991//1198 964//1199
            +f 963//1196 990//1195 964//1199
            +f 963//1196 964//1199 943//1200
            +f 942//956 963//1196 943//1200
            +f 942//956 943//1200 928//958
            +f 1020//1197 1005//1105 993//1104
            +f 991//1198 1020//1197 993//1104
            +f 991//1198 993//1104 966//1107
            +f 964//1199 991//1198 966//1107
            +f 964//1199 966//1107 945//1109
            +f 943//1200 964//1199 945//1109
            +f 943//1200 945//1109 930//1111
            +f 928//958 943//1200 930//1111
            +f 928//958 930//1111 921//913
            +f 1151//1043 1137//1049 1150//1201
            +f 1142//995 1143//1202 1122//989
            +f 1053//971 1089//977 1069//1203
            +f 1122//989 1123//1204 1109//983
            +f 1096//1061 1103//1205 1117//1055
            +f 1171//1037 1170//1206 1184//1031
            +f 1191//1013 1209//1019 1190//1207
            +f 1036//970 1053//971 1070//1208
            +f 1036//970 1070//1208 1037//1103
            +f 1203//1025 1202//1209 1209//1019
            +f 1066//1067 1085//1210 1096//1061
            +f 1050//1073 1076//1211 1066//1067
            +f 1184//1031 1183//1212 1203//1025
            +f 1041//1079 1040//1085 1075//1213
            +f 1171//1037 1151//1043 1170//1206
            +f 1157//1001 1158//1214 1142//995
            +f 1137//1049 1117//1055 1136//1215
            +f 1038//1097 1072//1216 1039//1091
            +f 1178//1007 1191//1013 1177//1217
            +f 1089//977 1109//983 1088//1218
            +f 1037//1103 1071//1219 1038//1097
            +f 1050//1073 1041//1079 1076//1211
            +f 1157//1001 1178//1007 1158//1214
            +f 1040//1085 1039//1091 1074//1220
            +f 1170//1206 1150//1201 452//1221
            +f 1264//1222 1071//1219 1263//1223
            +f 1261//1224 1262//1225 1076//1211
            +f 1085//1210 1076//1211 1262//1225
            +f 1190//1207 1208//1226 405//1227
            +f 509//176 526//519 1260//1228
            +f 1260//1228 526//519 556//523
            +f 167//201 556//523 595//202
            +f 595//202 621//526 1255//200
            +f 172//192 163//182 1254//199
            +f 8//49 18//42 3//1229
            +f 3//1229 18//42 1288//1230
            +f 15//75 7//66 1240//82
            +f 1250//50 8//49 3//1229
            +f 1//32 1283//40 566//33
            +f 593//3 566//33 9//41
            +f 19//1231 20//34 33//25
            +f 1243//2 636//89 593//3
            +f 64//18 40//6 36//17
            +f 1244//24 64//18 36//17
            +f 641//579 614//582 1237//1232
            +f 1250//50 1239//1233 4//48
            +f 7//66 4//48 1239//1233
            +f 5//74 14//73 11//81
            +f 1240//82 7//66 1239//1233
            +f 1//32 553//31 565//56
            +f 593//3 9//41 1289//83
            +f 18//42 20//34 1288//1230
            +f 40//6 27//5 1252//16
            +f 1249//58 6//65 565//56
            +f 14//73 15//75 11//81
            +f 592//57 1234//130 1233//58
            +f 1237//1232 614//582 588//586
            +f 1237//1232 588//586 605//592
            +f 539//175 159//177 1259//1234
            +f 164//257 1257//1235 168//251
            +f 509//176 1256//1236 159//177
            +f 1258//250 585//249 1259//1234
            +f 169//1237 164//257 174//242
            +f 191//236 208//230 185//1238
            +f 1290//1239 207//229 640//777
            +f 621//526 1292//1240 1255//200
            +f 163//182 160//178 157//180
            +f 1284//1241 1292//1240 648//227
            +f 1252//16 27//5 12//95
            +f 119//124 116//129 104//161
            +f 116//129 88//135 1242//136
            +f 87//159 666//713 715//160
            +f 87//159 1241//1242 666//713
            +f 1253//1243 47//150 631//152
            +f 631//152 666//713 1253//1243
            +f 86//142 74//144 60//143
            +f 640//777 1291//1244 1290//1239
            +f 1291//1244 640//777 613//248
            +f 208//230 219//220 200//1245
            +f 665//778 640//777 207//229
            +f 1285//226 200//1245 219//220
            +f 648//227 207//229 1284//1241
            +f 691//228 665//778 207//229
            +f 605//592 1236//1246 1245//1246
            +f 1235//151 605//592 631//152
            +f 1248//145 48//153 37//167
            +f 667//708 1251//1247 1247//158
            +f 605//592 1235//151 1236//1246
            +f 641//579 1238//1248 1246//1249
            +f 641//579 1237//1232 1238//1248
            +f 404//412 391//405 1267//904
            +f 1265//911 453//433 436//426
            +f 328//351 327//350 331//910
            +f 443//445 462//439 469//1250
            +f 342//370 1275//1251 344//1252
            +f 342//370 334//363 1275//1251
            +f 372//480 385//473 384//906
            +f 351//377 1271//1253 361//384
            +f 351//377 350//1254 1271//1253
            +f 337//1255 335//508 345//501
            +f 384//906 385//473 396//466
            +f 361//384 368//1256 369//391
            +f 361//384 1271//1253 368//1256
            +f 352//494 1276//1257 346//908
            +f 397//1258 396//466 411//459
            +f 342//370 350//1254 351//377
            +f 342//370 344//1252 350//1254
            +f 380//398 369//391 368//1256
            +f 334//363 328//351 332//1259
            +f 404//412 418//1260 419//419
            +f 404//412 1268//905 418//1260
            +f 426//452 1286//1261 1282//1262
            +f 1282//1262 411//459 426//452
            +f 352//494 362//487 1277//1263
            +f 1277//1263 1276//1257 352//494
            +f 391//405 380//398 381//1264
            +f 426//452 443//445 444//1265
            +f 444//1265 1286//1261 426//452
            +f 362//487 372//480 373//907
            +f 373//907 1277//1263 362//487
            +f 1202//1209 1183//1212 1270//1266
            +f 1116//1267 428//1268 1136//1215
            +f 428//1268 1287//1269 1136//1215
            +f 1073//1270 353//1271 1074//1220
            +f 353//1271 363//1272 1074//1220
            +f 353//1271 1073//1270 1279//1273
            +f 1070//1208 1069//1203 1263//1223
            +f 1274//1274 1069//1203 1088//1218
            +f 1177//1217 1273//1275 1272//1276
            +f 1272//1276 1158//1214 1177//1217
            +f 428//1268 1116//1267 427//1277
            +f 1088//1218 1108//1278 343//1279
            +f 1103//1205 1085//1210 1278//1280
            +f 1108//1278 1123//1204 1280//1281
            +f 1123//1204 1281//1282 1280//1281
            +f 1143//1202 1158//1214 360//1283
            +f 1158//1214 1272//1276 360//1283
            +f 1075//1213 1261//1224 1076//1211
            +f 1085//1210 1262//1225 1278//1280
            +f 1123//1204 1143//1202 1281//1282
            +f 1143//1202 360//1283 1281//1282
            +f 1074//1220 363//1272 1075//1213
            +f 363//1272 1261//1224 1075//1213
            +f 1270//1266 1183//1212 452//1221
            +f 1266//1284 1150//1201 1136//1215
            +f 1273//1275 1177//1217 1190//1207
            +f 1208//1226 1202//1209 406//1285
            +f 1202//1209 1269//1286 406//1285
            +f 1072//1216 1071//1219 1264//1222
            +f 1241//1242 1253//1243 666//713
            +f 71//137 86//142 60//143
            +f 88//135 86//142 71//137
            +f 1245//1246 1237//1232 605//592
            +f 119//124 104//161 90//119
            +f 667//708 1246//1249 1251//1247
            +f 621//526 648//227 1292//1240
            +f 208//230 200//1245 185//1238
            +f 174//242 191//236 169//1237
            +f 1258//250 1291//1244 613//248
            +f 1244//24 19//1231 33//25
            +f 1288//1230 20//34 19//1231
            +f 199//208 182//198 178//1287
            +f 206//1288 218//214 190//1289
            +f 1260//1228 556//523 167//201
            +f 157//180 1254//199 163//182
            +f 178//1287 182//198 1254//199
            +f 218//214 206//1288 1285//226
            +f 161//258 1257//1235 158//179
            +f 324//345 312//274 323//336
            +f 303//317 302//323 316//338
            +f 305//305 304//311 318//340
            +f 304//311 303//317 317//339
            +f 322//347 309//281 321//341
            +f 320//346 307//293 319//342
            +f 301//329 311//335 314//344
            +f 302//323 301//329 315//337
            +f 311//335 312//274 313//343
            +f 319//342 306//299 318//340
            +f 321//341 308//287 320//346
            +f 323//336 310//275 322//347
            +f 418//1260 435//909 419//419
            +f 337//1255 331//910 335//508
            +f 469//1250 462//439 1265//911
            +f 1137//1049 1136//1215 1150//1201
            +f 1143//1202 1123//1204 1122//989
            +f 1089//977 1088//1218 1069//1203
            +f 1123//1204 1108//1278 1109//983
            +f 1103//1205 1116//1267 1117//1055
            +f 1170//1206 1183//1212 1184//1031
            +f 1209//1019 1208//1226 1190//1207
            +f 1053//971 1069//1203 1070//1208
            +f 1070//1208 1071//1219 1037//1103
            +f 1202//1209 1208//1226 1209//1019
            +f 1085//1210 1103//1205 1096//1061
            +f 1076//1211 1085//1210 1066//1067
            +f 1183//1212 1202//1209 1203//1025
            +f 1040//1085 1074//1220 1075//1213
            +f 1151//1043 1150//1201 1170//1206
            +f 1158//1214 1143//1202 1142//995
            +f 1117//1055 1116//1267 1136//1215
            +f 1072//1216 1073//1270 1039//1091
            +f 1191//1013 1190//1207 1177//1217
            +f 1109//983 1108//1278 1088//1218
            +f 1071//1219 1072//1216 1038//1097
            +f 1041//1079 1075//1213 1076//1211
            +f 1178//1007 1177//1217 1158//1214
            +f 1039//1091 1073//1270 1074//1220
            +f 1150//1201 1266//1284 452//1221
            +f 1071//1219 1070//1208 1263//1223
            +f 1208//1226 406//1285 405//1227
            +f 1256//1236 509//176 1260//1228
            +f 1257//1235 161//258 168//251
            +f 585//249 539//175 1259//1234
            +f 715//160 667//708 1247//158
            +f 667//708 641//579 1246//1249
            +f 435//909 1265//911 436//426
            +f 332//1259 328//351 331//910
            +f 444//1265 443//445 469//1250
            +f 346//908 337//1255 345//501
            +f 397//1258 384//906 396//466
            +f 1282//1262 397//1258 411//459
            +f 381//1264 380//398 368//1256
            +f 1275//1251 334//363 332//1259
            +f 1267//904 391//405 381//1264
            +f 1269//1286 1202//1209 1270//1266
            +f 1073//1270 1072//1216 1279//1273
            +f 1069//1203 1274//1274 1263//1223
            +f 343//1279 1274//1274 1088//1218
            +f 1116//1267 1103//1205 427//1277
            +f 1108//1278 1280//1281 343//1279
            +f 427//1277 1103//1205 1278//1280
            +f 1183//1212 1170//1206 452//1221
            +f 1287//1269 1266//1284 1136//1215
            +f 405//1227 1273//1275 1190//1207
            +f 1279//1273 1072//1216 1264//1222
            +f 191//236 185//1238 169//1237
            +f 190//1289 199//208 178//1287
            +f 218//214 199//208 190//1289
            diff --git a/dist/assets/p5_featured/maya-dulynoted/index.html b/dist/assets/p5_featured/maya-dulynoted/index.html
            new file mode 100644
            index 0000000000..02f9f5a94d
            --- /dev/null
            +++ b/dist/assets/p5_featured/maya-dulynoted/index.html
            @@ -0,0 +1,16 @@
            +<!DOCTYPE html>
            +<head>
            +  <meta charset="UTF-8">
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/0.9.0/Tone.min.js"></script>
            +  <!-- uncomment lines below to include extra p5 libraries -->
            +  <!--<script src="libraries/p5.dom.js"></script>-->
            +  <!--<script src="libraries/p5.sound.js"></script>-->
            +  <script src="sketch.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +  <style> body {padding: 0; margin: 0;} </style>
            +</head>
            +
            +<body>
            +</body>
            +</html>
            diff --git a/dist/assets/p5_featured/maya-dulynoted/sketch.js b/dist/assets/p5_featured/maya-dulynoted/sketch.js
            new file mode 100644
            index 0000000000..019c01ded5
            --- /dev/null
            +++ b/dist/assets/p5_featured/maya-dulynoted/sketch.js
            @@ -0,0 +1,132 @@
            +/**
            + * p5 Home Page Sketch
            + * Notes displayed on the screen
            + * Each note falls and plays when touched by the mouse
            + * Music staff follows behind cursor
            +*/
            +
            +var twinkleNotes = ['C4', 'C4', 'G4', 'G4', 'A4', 'A4', 'G4', 'F4', 'F4', 'E4', 'E4', 'D4', 'D4', 'C4',
            +'G4', 'G4', 'F4', 'F4', 'E4', 'E4', 'D4', 'G4', 'G4', 'F4', 'F4', 'E4', 'E4', 'D4', 'C4', 'C4', 'G4', 'G4', 'A4', 'A4',
            +'G4', 'F4', 'F4', 'E4', 'E4', 'D4', 'D4', 'C4'];
            +
            +var notes = [];
            +var staffPath = [];
            +var synth;
            +var currentNote = 0;
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  background(255);
            +
            +  // Create a synth and connect it to the master output (your speakers)
            +  synth = new Tone.Synth().toMaster();
            +
            +  // Create and display all of the notes
            +  for(var i = 0; i < width/6; i++) {
            +    notes[i] = new Note();
            +    notes[i].twinkle();
            +    notes[i].display();
            +  }
            +}
            +
            +function draw() {
            +  background(255);
            +
            +  if (pmouseX != 0 && pmouseY != 0) {
            +    staffPath[staffPath.length] = new Staff(pmouseX, pmouseY, mouseX, mouseY);
            +  }
            +
            +  for(var j = 0; j < notes.length; j++) {
            +    notes[j].twinkle();
            +    notes[j].display();
            +  }
            +
            +  // Loop through backwards
            +  for (var i = 0; i <= this.staffPath.length - 1; i++) {
            +    if (this.staffPath[i].shade >= 255) {
            +      this.staffPath.splice(i, 1);
            +    } else {
            +      this.staffPath[i].display();
            +    }
            +  }
            +}
            +
            +// Note class
            +function Note() {
            +  this.rad = 5;
            +  this.currentWidth = width;
            +  this.currentHeight = height;
            +  this.x = random(0, width);
            +  this.y = random(0, height);
            +  this.c = color(random(100, 255), random(100, 255), random(100, 255));
            +  this.f = 100;
            +  this.rotation = random(10);
            +  this.detectRad = 25;
            +  this.spin = false;
            +
            +
            +  this.twinkle = function() {
            +    if (mouseX + this.detectRad > this.x && mouseX - this.detectRad < this.x && mouseY + this.detectRad > this.y && mouseY - this.detectRad < this.y && !this.spin) {
            +      this.f = this.c;
            +      this.spin = true;
            +      currentNote = int(random(twinkleNotes.length));
            +      synth.triggerAttackRelease(twinkleNotes[currentNote], "8n");
            +    }
            +    else {
            +      this.f = this.c;
            +    }
            +  }
            +
            +  this.display = function() {
            +    fill(this.f);
            +    push();
            +    translate(this.x, this.y);
            +    if (this.spin) {
            +    rotate(this.rotation);
            +    this.y = this.y + 20;
            +    }
            +    strokeWeight(2);
            +    strokeJoin(ROUND);
            +    smooth();
            +    stroke(0);
            +    scale(0.75);
            +    ellipse(0, 0, 25, 10);
            +    line(13, 0, 13, -40);
            +    pop();
            +  }
            +
            +  this.updatePosition = function(newWidth, newHeight) {
            +    this.x = map(this.x, 0, this.currentWidth, 0, newWidth);
            +    this.y = map(this.y, 0, this.currentHeight, 0, newHeight);
            +    this.currentWidth = newWidth;
            +    this.currentHeight = newHeight;
            +  }
            +}
            +
            +// Class for the staff lines drawn following the path of the mouse
            +function Staff(prevX, prevY, newX, newY) {
            +  this.faded = false;
            +  this.shade = 0;
            +  this.interval = 8;
            +
            +  this.display = function() {
            +    strokeWeight(2);
            +    stroke(this.shade);
            +    strokeJoin(ROUND);
            +    smooth();
            +    line(prevX, prevY - this.interval, newX, newY - this.interval);
            +    line(prevX, prevY - 2*this.interval, newX, newY - 2*this.interval);
            +    line(prevX, prevY, newX, newY);
            +    line(prevX, prevY + this.interval, newX, newY + this.interval);
            +    line(prevX, prevY + 2*this.interval, newX, newY + 2*this.interval);
            +    line(prevX, prevY + 3*this.interval, newX, newY + 3*this.interval);
            +    this.shade+=8;
            +  }
            +}
            +
            +function windowResized() {
            +  resizeCanvas(windowWidth, windowHeight);
            +  for(var j = 0; j < notes.length; j++) {
            +    notes[j].updatePosition(windowWidth, windowHeight);
            +  }
            +}
            diff --git a/dist/assets/p5_featured/naomichan/index.html b/dist/assets/p5_featured/naomichan/index.html
            new file mode 100644
            index 0000000000..a12cd6b58b
            --- /dev/null
            +++ b/dist/assets/p5_featured/naomichan/index.html
            @@ -0,0 +1,12 @@
            +<!DOCTYPE html>
            +<head>
            +  <meta charset="UTF-8">
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
            +  <script src="sketch.js"></script>
            +
            +  <style> body {padding: 0; margin: 0;} </style>
            +</head>
            +
            +<body>
            +</body>
            +</html>
            diff --git a/dist/assets/p5_featured/naomichan/sketch.js b/dist/assets/p5_featured/naomichan/sketch.js
            new file mode 100644
            index 0000000000..0e5a670a67
            --- /dev/null
            +++ b/dist/assets/p5_featured/naomichan/sketch.js
            @@ -0,0 +1,138 @@
            +var inc = .1;
            +var scl = 10;
            +var cols, rows;
            +
            +var zoff = 0;
            +
            +var particle = []
            +
            +var flowfield;
            +
            +function setup() {
            +	createCanvas(windowWidth, windowHeight);
            +	cols = floor(width/scl)
            +	rows = floor(height/scl)
            +
            +	flowfield = new Array(cols * rows)
            +
            +for (var i = 0; i < 150; i++) {
            +		particle[i] = new Particle();
            +	}
            +
            +	background('#FFCCC3')
            +
            +}
            +
            +function draw() {
            +
            +	var yoff = 0
            +for (var y = 0; y < rows; y++) {
            +	var xoff = 0
            +for (var x = 0; x < cols; x++) {
            +		var index =  x + y * cols
            +		var angle = noise(xoff, yoff, zoff) * TWO_PI * 4;
            +		var v = p5.Vector.fromAngle(angle)
            +		v.setMag(1);
            +		flowfield[index] = v
            +		xoff += inc
            +		// stroke(0,50);
            +		// strokeWeight(1)
            +
            +	}
            +	yoff += inc
            +
            +
            +	zoff += 0.0003
            +}
            +
            +for (var i = 0; i < particle.length; i++) {
            +	particle[i].follow(flowfield)
            +	particle[i].update()
            +	particle[i].edges()
            +	particle[i].show()
            +
            +	}
            +}
            +
            +function resizeWindow(){
            +	resizeWindow(windowWidth, windowHeight)
            +}
            +
            +
            +function Particle(){
            +	this.pos = createVector(random(width),random(height));
            +	this.vel = createVector(0,0);
            +	this.acc = createVector(0,0);
            +	this.maxspeed = 1;
            +
            +	this.prevPos = this.pos.copy()
            +
            +	this.update = function(){
            +		this.vel.add(this.acc);
            +		this.vel.limit(this.maxspeed)
            +		this.pos.add(this.vel);
            +		this.acc.mult(0)
            +	}
            +
            +	this.follow = function(vectors) {
            +		var x = floor(this.pos.x / scl);
            +		var y = floor(this.pos.y / scl);
            +		var index = x + y * cols;
            +		var force = vectors[index];
            +		this.applyForce(force);
            +	}
            +
            +this.applyForce = function(force) {
            +	this.acc.add(force);
            +	}
            +
            +this.show = function(){
            +	line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y)
            +
            +
            +	if (mouseX < width*.25){
            +		stroke(249,226,149, 30)
            +
            +	}else if (mouseX < width*.5){
            +		stroke(128,150,229, 30)
            +
            +	}else if (mouseX < width*.75){
            +		stroke(255,149,197, 30)
            +
            +	} else if (mouseX < width){
            +		stroke(128,239,255, 30)
            +
            +	}
            +
            +	// this.updatePrev()
            +	}
            +
            +this.updatePrev = function() {
            +	this.prevPos.x = this.pos.x
            +	this.prevPos.y = this.pos.y
            +
            +}
            +
            +this.edges = function() {
            +	if(this.pos.x > width) {
            +		this.pos.x = 0;
            +		this.updatePrev()
            +	}
            +	if(this.pos.x < 0) {
            +		this.pos.x = width;
            +		this.updatePrev()
            +
            +	}
            +	if(this.pos.y > height) {
            +		this.pos.y = 0
            +		this.updatePrev()
            +
            +	}
            +	if(this.pos.y < 0) {
            +		this.pos.y = height
            +		this.updatePrev()
            +
            +	}
            +
            +	}
            +}
            diff --git a/dist/assets/p5_featured/nea-p5js/assets/Museo_Slab_500_2.otf b/dist/assets/p5_featured/nea-p5js/assets/Museo_Slab_500_2.otf
            new file mode 100644
            index 0000000000..f7c3e27caa
            Binary files /dev/null and b/dist/assets/p5_featured/nea-p5js/assets/Museo_Slab_500_2.otf differ
            diff --git a/dist/assets/p5_featured/nea-p5js/assets/Museo_Slab_500italic-webfont.ttf b/dist/assets/p5_featured/nea-p5js/assets/Museo_Slab_500italic-webfont.ttf
            new file mode 100644
            index 0000000000..7aa6e912ff
            Binary files /dev/null and b/dist/assets/p5_featured/nea-p5js/assets/Museo_Slab_500italic-webfont.ttf differ
            diff --git a/dist/assets/p5_featured/nea-p5js/bubble.js b/dist/assets/p5_featured/nea-p5js/bubble.js
            new file mode 100644
            index 0000000000..146a5bd3b3
            --- /dev/null
            +++ b/dist/assets/p5_featured/nea-p5js/bubble.js
            @@ -0,0 +1,113 @@
            +function Bubble(d, xp,yp, xs, ys, eText, textw, texth, txx, tyy) {
            +
            +  this.mass = d;
            +  this.position = createVector(xp,yp);
            +  this.velocity = createVector(xs,ys);
            +  this.acceleration = createVector(0,0);
            +  this.eText = eText;
            +  this.tw = textw;
            +  this.th=texth;
            +  this.tx=txx;
            +  this.ty=tyy;
            +  this.c=color(int(random(255)),int(random(255)),int(random(255)));
            +  this.tc=255;
            +  this.dragOffset = createVector(0, 0);
            +  this.dragging = false;
            +  this.rollover = false;
            +
            +
            +  this.applyForce = function(force) {  //**********
            +    var f = p5.Vector.div(force, this.mass);
            +    this.acceleration.add(f); //add to force.
            +  };
            +
            +  this.update = function() {
            +    this.velocity.add(this.acceleration);
            +    this.position.add(this.velocity);
            +    this.acceleration.mult(0); // set our acceleration back to zero *************
            +  };
            +
            +
            +  this.checkEdges = function() {
            +    if (this.position.x > width-this.mass/2) {
            +      this.position.x = width-this.mass/2;
            +      this.velocity.x *= -1;
            +    } else if (this.position.x < 0+this.mass/2) {
            +      this.velocity.x *= -1;
            +      this.position.x = 0+this.mass/2;
            +    }
            +    if (this.position.y > height-this.mass/2) {
            +      this.velocity.y *= -1;
            +      this.position.y = height-this.mass/2;
            +    } else if (this.position.y < 0+this.mass/2) {
            +      this.velocity.y *= -1;
            +      this.position.y = 0+this.mass/2;
            +    }
            +  };
            +
            +
            +
            +
            +  this.display = function() {
            +    noStroke()
            +    textSize(15);
            +    ellipseMode(CENTER);
            +    fill(this.c);
            +    ellipse(this.position.x, this.position.y, this.mass, this.mass);
            +    fill(this.tc);
            +    textAlign(CENTER);
            +    rectMode(CENTER);
            +    text(this.eText,this.position.x-this.tx,this.position.y-this.ty,this.tw, this.th);
            +
            +  };
            +
            +
            +  this.collide = function(m, n){ //m is each of the mover objects
            +    //if dist between centers of movers is less than both their radius added -> colliding!
            +    if(dist(m.position.x,m.position.y,this.position.x,this.position.y)<(m.mass/2+this.mass/2)||dist(n.position.x,n.position.y,this.position.x,this.position.y)<(n.mass/2+this.mass/2)){
            +      if(this.bang==false){
            +
            +        var r1=int(random(255));
            +        var g1=int(random(255));
            +        var b1=int(random(255));
            +        this.c=color(r1,g1,b1);
            +        this.bang =true;
            +        console.log("colliding");
            +
            +      }
            +    }else {
            +      this.bang =false;
            +    }
            +  }
            +
            +  // The methods below are for mouse interaction
            +  this.handlePress = function(mx, my) {
            +    var d = dist(mx, my, this.position.x, this.position.y);
            +    if (d < this.mass/2) {
            +      this.dragging = true;
            +      this.dragOffset.x = this.position.x - mx;
            +      this.dragOffset.y = this.position.y - my;
            +    }
            +  };
            +
            +  this.handleHover = function(mx, my) {
            +    var d = dist(mx, my, this.position.x, this.position.y);
            +    if (d < this.mass/2) {
            +      this.rollover = true;
            +    } else {
            +      this.rollover = false;
            +    }
            +  };
            +
            +  this.stopDragging = function() {
            +    this.dragging = false;
            +  };
            +
            +  this.handleDrag = function(mx, my) {
            +    if (this.dragging) {
            +      this.position.x = mx + this.dragOffset.x;
            +      this.position.y = my + this.dragOffset.y;
            +    }
            +
            +  };
            +}
            diff --git a/dist/assets/p5_featured/nea-p5js/index.html b/dist/assets/p5_featured/nea-p5js/index.html
            new file mode 100644
            index 0000000000..21b3c2f7c9
            --- /dev/null
            +++ b/dist/assets/p5_featured/nea-p5js/index.html
            @@ -0,0 +1,62 @@
            +
            +<!DOCTYPE html>
            +<head>
            +	<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.21/p5.min.js"></script>
            +  <script src="sketch.js"></script>
            +	<script src="bubble.js"></script>
            +	<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.21/addons/p5.dom.min.js"></script>
            +  <!-- this line removes any default padding and style. you might only need one of these values set. -->
            +<meta name="viewport" content="user-scalable=yes,initial-scale=.3,maximum-scale=.3,minimum-scale=.3,width=device-width">
            +<style type="text/css">
            +
            +@font-face {
            +    font-family: myFirstFont;
            +    src: url(assets/Museo_Slab_500_2.otf);
            +}
            +body {
            +		font-family: myFirstFont;
            +		margin: 0;
            +	}
            +
            +	#items {
            +		font-size: 30px;
            +	}
            +
            +	a {
            +		color: white;
            +	}
            +
            +	#main {
            +		padding: 20px;
            +	}
            +
            +	h1 {
            +		margin-top: 0;
            +		border-bottom: 5px dotted #ccc;
            +		padding-bottom: 20px;
            +	}
            +
            +#main2 {
            +font-family: myFirstFont;
            +color:black;
            +font-size:80px;
            +
            +}
            +
            +
            +
            +</style>
            +
            +</head>
            +
            +<!DOCTYPE html>
            +
            +<body>
            +
            +
            +
            +
            +
            +
            +</body>
            +</html>
            diff --git a/dist/assets/p5_featured/nea-p5js/sketch.js b/dist/assets/p5_featured/nea-p5js/sketch.js
            new file mode 100644
            index 0000000000..30480232ea
            --- /dev/null
            +++ b/dist/assets/p5_featured/nea-p5js/sketch.js
            @@ -0,0 +1,107 @@
            +var t;
            +var data;
            +var entries = [];
            +var n;
            +var fontRegular;
            +
            +var attractor;
            +
            +var b1;
            +var b2;
            +var b3;
            +
            +var bs = [];
            +
            +var startText1="The National Endowment for the Arts supports art practices (like ALL of these) across the USA. NEA funds partly supported the last p5.js Contributors Conference.";
            +var startText2="The current US government wants to dismantle the NEA. Yet the NEA's modest budget amounts to less than 0.025% of the public funds spent on the US military.";
            +var startText3="In the United States Census in 2000, more people identified their primary occupation as artist, than as lawyer, doctor, or police officer combined.*";
            +
            +
            +function preload() {
            +  fontRegular = loadFont("assets/Museo_Slab_500_2.otf");
            +};
            +
            +function setup(){
            +  textFont(fontRegular);
            +  textSize(30);
            +
            +  createCanvas(windowWidth, windowHeight);
            +  //  createCanvas(window.innerWidth, window.innerHeight);
            +
            +  bs[0] = new Bubble(220,200,200,0.5,-0.5,startText2, 180,180,0,-10);
            +  bs[2] = new Bubble(220,100,100,0.2,-0.2,startText1, 180,190,0,-10);
            +  bs[1] = new Bubble(210,220,250,-0.1,0.1,startText3, 170,230,0,-45);
            +
            +  
            +  //diamter, xposition,yposition, xspeed, yspeed, eText, text width, text hieght, move text x, move text y
            +};
            +
            +function draw(){
            +  background(255);
            +
            +  for (var i = 0; i < bs.length; i++) {
            +    //FRICTION
            +    var c = 0.01;
            +    var normal = 1;
            +    var frictionMag = c * normal;
            +    var friction = bs[i].velocity.copy();
            +    friction.mult(-1);
            +    friction.normalize();
            +    friction.mult(frictionMag);
            +
            +
            +
            +    bs[i].checkEdges();
            +    bs[i].update();
            +
            +
            +
            +    bs[i].display();
            +    // bs[i].interact();
            +    stroke(255);
            +    strokeWeight(1);
            +  line(bs[2].position.x-3, bs[2].position.y-7,bs[2].position.x+74, bs[2].position.y-7);
            +  line(bs[2].position.x-44, bs[2].position.y+11,bs[2].position.x-82, bs[2].position.y+11);
            +
            +
            +  }
            +
            +
            +  bs[0].collide(bs[1],bs[2]);
            +  bs[1].collide(bs[0],bs[2]);
            +  bs[2].collide(bs[1],bs[0]);
            +
            +
            +};
            +
            +function mouseMoved() {
            +  for (var i = 0; i < bs.length; i++) {
            +    bs[i].handleHover(mouseX, mouseY);
            +  }
            +};
            +
            +function mousePressed() {
            +
            +  for (var i = 0; i < bs.length; i++) {
            +    bs[i].handlePress(mouseX, mouseY);
            +  }
            +  if(mouseX<bs[2].position.x+74&&mouseX>bs[2].position.x-82&&mouseY<bs[2].position.y+11&&mouseY>bs[2].position.y-25){
            +    console.log("clicked");
            +    //location.assign("http://www.neafunded.us/");
            +    top.window.location.href='http://www.neafunded.us/';
            +
            +  }
            +};
            +
            +function mouseDragged() {
            +  for (var i = 0; i < bs.length; i++) {
            +    bs[i].handleHover(mouseX, mouseY);
            +    bs[i].handleDrag(mouseX, mouseY);
            +  }
            +};
            +
            +function mouseReleased() {
            +  for (var i = 0; i < bs.length; i++) {
            +    bs[i].stopDragging();
            +  }
            +};
            diff --git a/dist/assets/p5_featured/paom/gifs/processing01.gif b/dist/assets/p5_featured/paom/gifs/processing01.gif
            new file mode 100644
            index 0000000000..8e47e38851
            Binary files /dev/null and b/dist/assets/p5_featured/paom/gifs/processing01.gif differ
            diff --git a/dist/assets/p5_featured/paom/gifs/processing02.gif b/dist/assets/p5_featured/paom/gifs/processing02.gif
            new file mode 100644
            index 0000000000..3a77eeb761
            Binary files /dev/null and b/dist/assets/p5_featured/paom/gifs/processing02.gif differ
            diff --git a/dist/assets/p5_featured/paom/gifs/processing03.gif b/dist/assets/p5_featured/paom/gifs/processing03.gif
            new file mode 100644
            index 0000000000..6c618e11bf
            Binary files /dev/null and b/dist/assets/p5_featured/paom/gifs/processing03.gif differ
            diff --git a/dist/assets/p5_featured/paom/gifs/processing04.gif b/dist/assets/p5_featured/paom/gifs/processing04.gif
            new file mode 100644
            index 0000000000..8074b2a1fe
            Binary files /dev/null and b/dist/assets/p5_featured/paom/gifs/processing04.gif differ
            diff --git a/dist/assets/p5_featured/paom/gifs/processing05.gif b/dist/assets/p5_featured/paom/gifs/processing05.gif
            new file mode 100644
            index 0000000000..c64de56d50
            Binary files /dev/null and b/dist/assets/p5_featured/paom/gifs/processing05.gif differ
            diff --git a/dist/assets/p5_featured/paom/gifs/processing06.gif b/dist/assets/p5_featured/paom/gifs/processing06.gif
            new file mode 100644
            index 0000000000..b2d347e4d2
            Binary files /dev/null and b/dist/assets/p5_featured/paom/gifs/processing06.gif differ
            diff --git a/dist/assets/p5_featured/paom/index.html b/dist/assets/p5_featured/paom/index.html
            new file mode 100644
            index 0000000000..1f84da20c4
            --- /dev/null
            +++ b/dist/assets/p5_featured/paom/index.html
            @@ -0,0 +1,52 @@
            +<!DOCTYPE html>
            +  <head>
            +    <script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.4/p5.min.js'></script>
            +    <script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.4/addons/p5.dom.js'></script>
            +    <script type='text/javascript' language='javascript'>
            +    
            +    var gifs = [];
            +    function setup() {
            +      var s = windowHeight/1400;
            +      gifs[0] = createImg('gifs/processing01.gif'); // lower left
            +      gifs[0].size(395*s, 538*s);
            +      gifs[0].position(0, windowHeight-gifs[0].height);
            +
            +      gifs[1] = createImg('gifs/processing04.gif'); // mid left
            +      gifs[1].size(468*s, 468*s);
            +      gifs[1].position(150*s, windowHeight*0.5 - 0.65*gifs[1].height);
            +
            +      gifs[2] = createImg('gifs/processing02.gif'); // upper left
            +      gifs[2].size(306*s, 500*s);
            +      gifs[2].position(0, 110*s);
            +
            +      gifs[3] = createImg('gifs/processing06.gif'); // upper right
            +      gifs[3].size(324*s, 528*s);
            +      gifs[3].position(windowWidth-gifs[3].width-10*s, 110*s);
            +
            +      gifs[4] = createImg('gifs/processing05.gif'); // mid right
            +      gifs[4].size(398*s, 534*s);
            +      gifs[4].position(windowWidth-gifs[4].width-200*s, windowHeight*0.5 - 0.5*gifs[4].height);
            +
            +      gifs[5] = createImg('gifs/processing03.gif'); // lower right
            +      gifs[5].size(299*s, 450*s);
            +      gifs[5].position(windowWidth-gifs[5].width-40*s, windowHeight-gifs[5].height);
            +
            +      // if (windowHeight < 500) {
            +      // }
            +
            +      if (windowWidth < 720) {
            +        gifs[1].hide();
            +        gifs[4].hide();
            +        gifs[2].hide();
            +        gifs[3].hide();
            +      }
            +      console.log(windowHeight, window.innerHeight)
            +    }
            +
            +    </script>
            +    <style>body{margin: 0; padding: 0}</style>
            +  </head>
            +  <body oncontextmenu="return false;">
            +  </body>
            +</html>
            +
            diff --git a/dist/assets/p5_featured/qianqianye-shanshui_ii/index.html b/dist/assets/p5_featured/qianqianye-shanshui_ii/index.html
            new file mode 100644
            index 0000000000..b07b8ab5f6
            --- /dev/null
            +++ b/dist/assets/p5_featured/qianqianye-shanshui_ii/index.html
            @@ -0,0 +1,8 @@
            +<!DOCTYPE html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.min.js"></script>
            +  <script src="sketch.js"></script>
            +  <style> body {padding: 0; margin: 0;}</style>
            +</head>
            +
            +<body></body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/qianqianye-shanshui_ii/sketch.js b/dist/assets/p5_featured/qianqianye-shanshui_ii/sketch.js
            new file mode 100644
            index 0000000000..f083e4fd62
            --- /dev/null
            +++ b/dist/assets/p5_featured/qianqianye-shanshui_ii/sketch.js
            @@ -0,0 +1,62 @@
            +var num = 5;
            +var mountains = [];
            +
            +function setup() {
            +	createCanvas(windowWidth, windowHeight);
            +	shanShui();
            +}
            +
            +function draw() {
            +	background(255);
            +	noStroke();
            +	ellipse(100, 100, 80, 80); //sun
            +
            +	for (var i = 0; i < mountains.length; i++) {
            +		mountains[i].show();
            +	}
            +}
            +
            +function shanShui() {
            +	for (var i = 0; i < num; i++) {
            +		mountains.push(new curveLine(i));
            +	 }
            +}
            +
            +function curveLine(_index) {
            +	var index = _index;
            +	var screen = 2000;
            +	var screenHeight = 800;
            +	var base = random (screen/4, screen/2); 
            +	var start = random (-screen/2, screen/2); 
            +
            +	this.show = function (){
            +			var ink = 20;
            +
            +			var c = color(0, 0, 0,ink);
            +			fill(c);
            +    		stroke(c);
            +
            +			var xoffset = map(mouseX, 0,screen, -100,100) * (index+1) ;
            +
            +				 for (var x = start; x < base + start; x++) {
            +				 	var mapLoc = map(x, start, base+start, 0, 1);
            +				 	var edgePercent = .2;
            +
            +				 	if(mapLoc< edgePercent){
            +				 		stroke(0,0,0,(mapLoc*(1/edgePercent))*ink);
            +				 	}else if(mapLoc> abs(1-edgePercent)){
            +				 		var inverseLoc = abs(1-mapLoc);
            +				 		stroke(0,0,0,(inverseLoc*1/edgePercent)*ink);
            +				 	}
            +
            +					var nx = map(x, 0, screen, 0, 10);
            +					var y = screenHeight * (noise(nx+index*10)*.7);
            +					var xPos = x+ xoffset
            +
            +					line (xPos, y, xPos, y+(screenHeight-y)/2);
            +					line (xPos, y, xPos, y+(screenHeight-y)/4);
            +					line (xPos, y, xPos, y+(screenHeight-y)/8);
            +					line (xPos, y, xPos, y+(screenHeight-y)/16);	
            +				 }
            +	}
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/qianqianye-superwoman/index.html b/dist/assets/p5_featured/qianqianye-superwoman/index.html
            new file mode 100644
            index 0000000000..5a8b5ab196
            --- /dev/null
            +++ b/dist/assets/p5_featured/qianqianye-superwoman/index.html
            @@ -0,0 +1,10 @@
            +
            +<!-- saved from url=(0043)http://www.qianqian-ye.com/p5js-superwoman/ -->
            +<!DOCTYPE html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.8/p5.min.js"></script>
            +  <script src="superwoman.js"></script>
            +  <style> body {padding: 0; margin: 0;} canvas { opacity: 0.8 }</style>
            +</head>
            +
            +<body></body>
            +</html>
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/qianqianye-superwoman/superwoman.js b/dist/assets/p5_featured/qianqianye-superwoman/superwoman.js
            new file mode 100644
            index 0000000000..4990d3a8b2
            --- /dev/null
            +++ b/dist/assets/p5_featured/qianqianye-superwoman/superwoman.js
            @@ -0,0 +1,149 @@
            +var women;
            +
            +function setup(){
            +	createCanvas(windowWidth, windowHeight);
            +	rectMode(CENTER);
            +	womanShow();
            +	}
            +
            +function womanShow(){
            +	women = new Array ();
            +	var womenDist = 110;
            +
            +	for (var wx = 0; wx <= width; wx+=womenDist) {
            +		for (var wy = 0; wy <=height; wy+=womenDist) {
            +			if (((wx+wy)/womenDist)%2==0) {
            +				var xLoc =wx+40;
            +				var yLoc = wy+110;
            +				var randomColor = color (random(100,200),random(255),random(255)); // for the diversity theme!
            +				var womenN = new SuperWoman(createVector(xLoc,yLoc),randomColor);
            +				womenN.superwomanStart();
            +				append(women, womenN);
            +			}
            +		}
            +	}
            +}
            +
            +function draw(){
            +	background(255);
            +	for (var i = 0; i < women.length; i++) {
            +	women[i].superwomanDraw();
            +	}
            +}
            +
            +function SuperWoman(startPos,inColor){
            +	this.pos = startPos;
            +	this.bodyColor = inColor;
            +	this.posWait = startPos;
            +	this.posFlyto;
            +	this.transform;
            +	this.upDown;
            +	this.state;
            +	this.flyTime;
            +	this.a;
            +
            +	this.superwomanStart = function(){
            +		this.pos = createVector(this.posWait.x,	this.posWait.y);
            +		this.transform = 0;
            +		this.flyTime = 0;
            +		this.upDown = false;
            +		this.state = 0;
            +		this.posFlyto = new Array(this.posWait);
            +		var upV = createVector(this.posWait.x, this.posWait.y-100);
            +		append (this.posFlyto, upV);
            +		for (var i = 0; i < 3; i++) {
            +			var randomPosition = createVector(3*random(0, width), 3*random (0, this.posWait.y-300)); //FLY PATH
            +			append (this.posFlyto, randomPosition);
            +		}
            +	}
            +
            +	this.superwomanDraw = function(){
            +		this.stateMachine();
            +		noStroke();
            +		push();		
            +		translate(this.pos.x,this.pos.y);
            +		scale(.5);
            +		rotate(this.a);
            +	
            +		capeColor = color(237,34,93); //P5 COLOR!!!
            +		currentColor = lerpColor(this.bodyColor, capeColor, this.transform/100);
            +		fill(currentColor);
            +		quad(-20,0-50,   20,0-50,   50,0+50,   -50,0+50); //CAPE
            +		fill(this.bodyColor);
            +		rect(0, 0, 50,100); //BODY
            +		ellipse(0,-90, 50,50); //HEAD
            +		triangle(0,-10,-50,0+50, 50,50); //SKIRT
            +		strokeWeight(15);
            +		strokeCap(ROUND);
            +		strokeJoin(ROUND);
            +		stroke(this.bodyColor);
            +		noFill()
            +		line(0-15,0+120,0-15,0); //LEFT LEG
            +		line(0+15,0+120,0+15,0); //RIGHT LEG
            +		
            +		var armHeight = map (this.transform,0,100, 10, -110);
            +		var armHover = map (this.transform,0,100,PI, 0);
            +		var armAddition = sin(armHover)*40;
            +		beginShape();   //ARMS
            +		vertex(0-50,0+10);
            +		vertex(0-30,0-50);
            +		vertex(0+30,0-50);
            +		vertex(0+50+armAddition,0+armHeight);
            +		endShape();
            +		pop();
            +	}
            +
            +	this.stateMachine = function(){
            +		if (this.state == 0) {   //waiting state
            +			var mouseNow = createVector(mouseX, mouseY);
            +			var distMouse = this.pos.dist(mouseNow);
            +			var hover = distMouse <=110;
            +			if (hover == true) { //transform trigger
            +				this.state = 1;
            +			}
            +		}else if (this.state == 1) {	//transform state
            +			if (this.upDown == true) {
            +				this.transform = this.transform +5;
            +				if (this.transform >= 100) { 
            +					this.state = 2;
            +					this.transform = 100;
            +				}
            +			}else if (this.upDown == false) {
            +				this.transform = this.transform -5; 
            +				if (this.transform <=0) {
            +					this.upDown = true;
            +					this.state = 0;
            +					this.transform = 0;
            +				}
            +			}
            +		}else if (this.state == 2) { //fly state
            +			this.flyTime = this.flyTime +.01;
            +			if (this.flyTime >= 1) {
            +				this.state = 1;
            +				this.upDown = false;
            +				this.flyTime = 0;
            +			}
            +			
            +			var x = bezierPoint(this.posFlyto[0].x,this.posFlyto[1].x,this.posFlyto[2].x,this.posFlyto[0].x,this.flyTime);
            +			var y = bezierPoint(this.posFlyto[0].y,this.posFlyto[1].y,this.posFlyto[2].y,this.posFlyto[0].y,this.flyTime);
            +			this.pos.x =x;
            +			this.pos.y =y;
            +			var tx = bezierTangent(this.posFlyto[0].x,this.posFlyto[1].x,this.posFlyto[2].x,this.posFlyto[0].x,this.flyTime);
            +	  		var ty = bezierTangent(this.posFlyto[0].y,this.posFlyto[1].y,this.posFlyto[2].y,this.posFlyto[0].y,this.flyTime);
            +	  		this.a = atan2(ty, tx);
            +	  		this.a += PI/2;
            +
            +	  		for (var i = 0; i <= this.flyTime; i+=.01) { // FLYTRACE
            +	  			var traceX = bezierPoint(this.posFlyto[0].x,this.posFlyto[1].x,this.posFlyto[2].x,this.posFlyto[0].x,i);
            +				var traceY = bezierPoint(this.posFlyto[0].y,this.posFlyto[1].y,this.posFlyto[2].y,this.posFlyto[0].y,i);
            +	  			fill(255-(i/this.flyTime)*35); // Trace color changes by flytime
            +	  			ellipse(traceX,traceY,(i/this.flyTime)*10, (i/this.flyTime)*10); // Trace weight changes by flytime
            +  			}
            +		}
            +	}
            +}
            +
            +function windowResized() {
            +  resizeCanvas(windowWidth, windowHeight);
            +  womanShow();
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/yiningshi/README.md b/dist/assets/p5_featured/yiningshi/README.md
            new file mode 100644
            index 0000000000..4a4dceb094
            --- /dev/null
            +++ b/dist/assets/p5_featured/yiningshi/README.md
            @@ -0,0 +1,10 @@
            +# Brick Breaker
            +This is a Brick Breaker game using p5.js. It's featured on [p5js homwpage](http://www.p5js.org) from June 14 to June 28 in 2017. Read more about this project on [p5 diversity page](https://diversity.p5js.org/feature/yiningshi.html).
            +
            +# Demo
            +[https://yining1023.github.io/brickBreaker](https://yining1023.github.io/brickBreaker)
            +
            +# Video tutorial about how to make this game
            +coming soon!
            +
            +This is inspired by Danial Shiffman's [Asteroids Coding Challenge](https://www.youtube.com/watch?v=hacZU523FyM)
            diff --git a/dist/assets/p5_featured/yiningshi/ball.js b/dist/assets/p5_featured/yiningshi/ball.js
            new file mode 100644
            index 0000000000..aa0af9e9ad
            --- /dev/null
            +++ b/dist/assets/p5_featured/yiningshi/ball.js
            @@ -0,0 +1,67 @@
            +function Ball(pos) {
            +  if (pos) {
            +    this.pos = pos.copy();
            +  } else {
            +    this.pos = createVector(width / 2, height - 500);
            +  }
            +
            +  this.r = 30;
            +  this.vel = createVector(1, random(1, 2)).mult(4);
            +  this.direction = createVector(1, 1);
            +  this.shadows = [];
            +  this.colors = ['#6CD9CC', '#FB6578', '#FE5A8F', '#FC9574', '#9A8DF2'];
            +
            +  this.update = function() {
            +    var shadow = this.pos.copy();
            +    this.shadows.push(shadow);
            +
            +    if (this.shadows.length > 5) {
            +      this.shadows.splice(0, 1);
            +    }
            +
            +    this.pos.x += this.vel.x * this.direction.x;
            +    this.pos.y += this.vel.y * this.direction.y;
            +  }
            +
            +  this.display = function() {
            +    for (var i = this.shadows.length - 1; i >= 0; i--) {
            +      var rgbsC = 'rgba(194, 186, 247, ' + i / this.shadows.length + ')';
            +      fill(rgbsC);
            +      ellipse(this.shadows[i].x, this.shadows[i].y, (this.r + i) * 2, (this.r + i) * 2);
            +    }
            +
            +    stroke('#9A8DF2');
            +    strokeWeight(2);
            +    fill(255);
            +    ellipse(this.pos.x, this.pos.y, this.r * 2, this.r * 2);
            +    noFill();
            +    stroke(0);
            +    strokeWeight(1);
            +  }
            +
            +  this.checkEdges = function() {
            +    if (this.pos.x > width - this.r || this.pos.x < this.r) {
            +      this.direction.x *= -1;
            +    }
            +    if (this.pos.y < this.r) {
            +      if (ball.direction.y < 0) this.direction.y *= -1;
            +    }
            +  }
            +
            +  this.meets = function(board) {
            +    if (board.pos.y - this.pos.y > 0 && board.pos.y - this.pos.y < this.r && ball.pos.x > board.pos.x - ball.r && ball.pos.x < board.pos.x + board.r + ball.r) {
            +      return true;
            +    } else {
            +      return false;
            +    }
            +  }
            +
            +  this.hits = function(brick) {
            +    var d = dist(this.pos.x, this.pos.y, brick.pos.x, brick.pos.y);
            +    if (d < brick.r + this.r) {
            +      return true;
            +    } else {
            +      return false;
            +    }
            +  }
            +}
            diff --git a/dist/assets/p5_featured/yiningshi/board.js b/dist/assets/p5_featured/yiningshi/board.js
            new file mode 100644
            index 0000000000..c642800a0c
            --- /dev/null
            +++ b/dist/assets/p5_featured/yiningshi/board.js
            @@ -0,0 +1,35 @@
            +function Board() {
            +  this.r = 160;
            +  this.h = 20;
            +  this.pos = createVector(width / 2 - this.r / 2, height - 40);
            +  this.isMovingLeft = false;
            +  this.isMovingRight = false;
            +
            +  this.display = function() {
            +    strokeWeight(2);
            +    stroke('#9A8DF2');
            +    rect(this.pos.x, this.pos.y, this.r, this.h);
            +    for (var i = 0; i < this.r; i += this.h) {
            +      line(this.pos.x + i, this.pos.y, this.pos.x + this.h + i, this.pos.y + this.h);
            +    }
            +    stroke(0);
            +    strokeWeight(0);
            +  }
            +
            +  this.update = function() {
            +    if (this.isMovingLeft) {
            +      this.move(-20);
            +    } else if (this.isMovingRight) {
            +      this.move(20);
            +    }
            +  }
            +
            +  this.move = function(step) {
            +    this.pos.x += step;
            +  }
            +
            +  this.checkEdges = function() {
            +    if (this.pos.x <= 0) this.pos.x = 0;
            +    else if (this.pos.x + this.r >= width) this.pos.x = width - this.r;
            +  }
            +}
            diff --git a/dist/assets/p5_featured/yiningshi/brick.js b/dist/assets/p5_featured/yiningshi/brick.js
            new file mode 100644
            index 0000000000..97c9a61c7f
            --- /dev/null
            +++ b/dist/assets/p5_featured/yiningshi/brick.js
            @@ -0,0 +1,46 @@
            +function Brick(pos, r) {
            +  if (pos) {
            +    this.pos = pos.copy();
            +  } else {
            +    this.pos = createVector(random(width), random(height - 400));
            +  }
            +  if (r) {
            +    this.r = r * 0.5;
            +  } else {
            +    this.r = random(20, 80);
            +  }
            +
            +  this.total = 6;
            +  this.offset = [];
            +  this.index = Math.floor(random(5));
            +  this.colors = ['#6CD9CC', '#FB6578', '#FE5A8F', '#FC9574', '#9A8DF2'];
            +  this.miniDrops = [];
            +
            +  this.display = function() {
            +    push();
            +    stroke(this.colors[this.index]);
            +    strokeWeight(2);
            +    translate(this.pos.x, this.pos.y);
            +    beginShape();
            +    for (var i = 0; i < this.total; i++) {
            +      var angle = map(i, 0, this.total, 0, TWO_PI);
            +      var r = this.r;
            +      var x = r * cos(angle);
            +      var y = r * sin(angle);
            +      vertex(x, y);
            +    }
            +    endShape(CLOSE);
            +    stroke(0);
            +    strokeWeight(1);
            +    pop();
            +
            +  }
            +
            +  this.shrink = function() {
            +    var newB = [];
            +    newB[0] = new Brick(this.pos, this.r);
            +    // newB[1] = new Brick(this.pos, this.r);
            +    return newB;
            +  }
            +
            +}
            diff --git a/dist/assets/p5_featured/yiningshi/drop.js b/dist/assets/p5_featured/yiningshi/drop.js
            new file mode 100644
            index 0000000000..8811a8fecb
            --- /dev/null
            +++ b/dist/assets/p5_featured/yiningshi/drop.js
            @@ -0,0 +1,28 @@
            +function Drop(index) {
            +  this.x = random(width);
            +  this.y = random(-500, -50);
            +  this.z = random(0, 20);
            +  this.len = 20;
            +  this.yspeed = random(5, 15);
            +
            +  this.colors = ['#6CD9CC', '#FB6578', '#FE5A8F', '#FC9574', '#9A8DF2'];
            +  this.index = index;
            +
            +  this.fall = function() {
            +    this.y = this.y + this.yspeed;
            +
            +    if (this.y > height) {
            +      this.y = random(-200, -100);
            +      this.yspeed = random(5, 15);
            +    }
            +  }
            +
            +  this.show = function() {
            +    strokeWeight(2);
            +    stroke(this.colors[this.index]);
            +    line(this.x, this.y, this.x - this.len / 3, this.y + this.len);
            +    stroke(0);
            +    strokeWeight(1);
            +  }
            +
            +}
            \ No newline at end of file
            diff --git a/dist/assets/p5_featured/yiningshi/index.html b/dist/assets/p5_featured/yiningshi/index.html
            new file mode 100644
            index 0000000000..b56bbc2cdd
            --- /dev/null
            +++ b/dist/assets/p5_featured/yiningshi/index.html
            @@ -0,0 +1,32 @@
            +<!DOCTYPE html>
            +  <head>
            +    <meta charset="UTF-8">
            +    <title>Untitled</title>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.12/p5.min.js" type="text/javascript"></script>
            +
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.12/addons/p5.dom.min.js" type="text/javascript"></script>
            +    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.12/addons/p5.sound.min.js" type="text/javascript"></script>
            +    <script src="brick.js" type="text/javascript"></script>
            +    <script src="board.js" type="text/javascript"></script>
            +    <script src="ball.js" type="text/javascript"></script>
            +    <script src="drop.js" type="text/javascript"></script>
            +
            +    <script src="sketch.js" type="text/javascript"></script>
            +
            +    <style>
            +      body {
            +        padding: 0; margin: 0;
            +      }
            +      canvas {
            +        vertical-align: top;
            +      }
            +      html {
            +        font-family: monospace;
            +        color: #333;
            +        font-size: 20px;
            +      }
            +    </style>
            +  </head>
            +  <body>
            +  </body>
            +</html>
            diff --git a/dist/assets/p5_featured/yiningshi/sketch.js b/dist/assets/p5_featured/yiningshi/sketch.js
            new file mode 100644
            index 0000000000..d5bd61575e
            --- /dev/null
            +++ b/dist/assets/p5_featured/yiningshi/sketch.js
            @@ -0,0 +1,117 @@
            +var board;
            +var ball;
            +var bricks = [];
            +var gameOver = true;
            +var youWin = false;
            +var winText;
            +var instructionText;
            +var drops = [];
            +
            +function setup() {
            +  createCanvas(windowWidth, windowHeight);
            +  ellipseMode(CENTER);
            +  textAlign(CENTER);
            +  noFill();
            +  stroke(0);
            +
            +  board = new Board();
            +  ball = new Ball();
            +
            +  for (var i = 0; i < 100; i++) {
            +    drops[i] = new Drop(Math.floor(random(5)));
            +  }
            +
            +  createBricks(20);
            +  createText();
            +}
            +
            +function draw() {
            +  background(255);
            +
            +  // bricks
            +  for (var i = bricks.length - 1; i >= 0; i--) {
            +    if (ball.hits(bricks[i])) {
            +      if (bricks[i].r >= 40) {
            +        var newBricks = bricks[i].shrink();
            +        bricks = bricks.concat(newBricks);
            +      }
            +      bricks.splice(i, 1);
            +      ball.direction.y *= -1;
            +      break;
            +    }
            +    bricks[i].display();
            +  }
            +
            +  // board
            +  board.display();
            +  if (!gameOver) board.checkEdges();
            +  if (!gameOver) board.update();
            +
            +  // ball
            +  if (ball.meets(board)) {
            +    if (ball.direction.y > 0) ball.direction.y *= -1;
            +  }
            +  ball.display();
            +  if (!gameOver) ball.checkEdges();
            +  if (!gameOver) ball.update();
            +
            +  if (ball.pos.y > height) {
            +    ball.pos = createVector(board.pos.x + board.r, height - 500);
            +    gameOver = true;
            +    ball.shadows = [];
            +  }
            +
            +  if (bricks.length === 0) {
            +    youWin = true;
            +    gameOver = true;
            +  }
            +
            +  if (youWin) {
            +    winText.style('display', 'block');
            +    for (var i = 0; i < drops.length; i++) {
            +      drops[i].fall();
            +      drops[i].show();
            +    }
            +  } else {
            +    winText.style('display', 'none');
            +  }
            +
            +  if (gameOver) {
            +    instructionText.style('display', 'block');
            +  } else {
            +    instructionText.style('display', 'none');
            +  }
            +}
            +
            +function keyReleased() {
            +  board.isMovingRight = false;
            +  board.isMovingLeft = false;
            +}
            +
            +function keyPressed() {
            +  if (key === 'a' || key === 'A') {
            +    board.isMovingLeft = true;
            +  } else if (key === 'd' || key === 'D') {
            +    board.isMovingRight = true;
            +  } else if (key === 's' || key === 'S') {
            +    if (bricks.length === 0) createBricks(20);
            +    gameOver = false;
            +    youWin = false;
            +  }
            +}
            +
            +function createBricks(n) {
            +  for (var i = 0; i < n; i++) {
            +    bricks.push(new Brick());
            +  }
            +}
            +
            +function createText() {
            +  winText = createP('🎉🎉🎉 YOU WIN! 🎉🎉🎉');
            +  winText.style('display', 'none');
            +  winText.position(width / 2 - 130, 80);
            +
            +  instructionText = createP("Press 'S' to Start, 'A'/'D' to move Right/Left");
            +  instructionText.style('display', 'none');
            +  instructionText.position(width / 2 - 240, 100);
            +}
            diff --git a/dist/assets/reference/en.json b/dist/assets/reference/en.json
            new file mode 100644
            index 0000000000..73ee8da6ef
            --- /dev/null
            +++ b/dist/assets/reference/en.json
            @@ -0,0 +1,7610 @@
            +{
            +  "h1": "Reference",
            +  "reference-search": "Search reference",
            +  "reference-description1": "Can't find what you're looking for? You may want to check out",
            +  "reference-description3": "You can also download an offline version of the reference.",
            +  "reference-contribute2": "Please let us know.",
            +  "reference-error1": "Notice any errors or typos?",
            +  "reference-error3": "Please feel free to edit",
            +  "reference-error5": "and issue a pull request!",
            +  "reference-example": "Example",
            +  "reference-description": "Description",
            +  "reference-extends": "Extends",
            +  "reference-parameters": "Parameters",
            +  "reference-syntax": "Syntax",
            +  "reference-returns": "Returns",
            +  "Environment": "Environment",
            +  "Color": "Color",
            +  "Color Conversion": "Color Conversion",
            +  "Creating & Reading": "Creating & Reading",
            +  "Setting": "Setting",
            +  "Shape": "Shape",
            +  "2D Primitives": "2D Primitives",
            +  "Attributes": "Attributes",
            +  "Curves": "Curves",
            +  "Vertex": "Vertex",
            +  "Constants": "Constants",
            +  "Structure": "Structure",
            +  "DOM": "DOM",
            +  "Rendering": "Rendering",
            +  "Foundation": "Foundation",
            +  "Transform": "Transform",
            +  "Data": "Data",
            +  "LocalStorage": "LocalStorage",
            +  "Dictionary": "Dictionary",
            +  "Events": "Events",
            +  "Acceleration": "Acceleration",
            +  "Keyboard": "Keyboard",
            +  "Mouse": "Mouse",
            +  "Touch": "Touch",
            +  "Image": "Image",
            +  "Loading & Displaying": "Loading & Displaying",
            +  "Pixels": "Pixels",
            +  "IO": "IO",
            +  "Input": "Input",
            +  "Output": "Output",
            +  "Table": "Table",
            +  "Math": "Math",
            +  "Calculation": "Calculation",
            +  "Vector": "Vector",
            +  "Noise": "Noise",
            +  "Random": "Random",
            +  "Trigonometry": "Trigonometry",
            +  "Typography": "Typography",
            +  "Array Functions": "Array Functions",
            +  "Conversion": "Conversion",
            +  "String Functions": "String Functions",
            +  "Time & Date": "Time & Date",
            +  "3D Primitives": "3D Primitives",
            +  "3D": "3D",
            +  "Interaction": "Interaction",
            +  "Lights": "Lights",
            +  "3D Models": "3D Models",
            +  "Material": "Material",
            +  "Camera": "Camera",
            +  "p5": {
            +    "description": [
            +      "This is the p5 instance constructor.",
            +      "A p5 instance holds all the properties and methods related to a p5 sketch. It expects an incoming sketch closure and it can also take an optional node parameter for attaching the generated p5 canvas to a node. The sketch closure takes the newly created p5 instance as its sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>, <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.",
            +      "A p5 sketch can run in \"global\" or \"instance\" mode: \"global\" - all properties and methods are attached to the window \"instance\" - all properties and methods are bound to this p5 object"
            +    ],
            +    "returns": "P5: a p5 instance",
            +    "params": {
            +      "sketch": "Function: a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,  <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the  given p5 instance",
            +      "node": "HTMLElement: (Optional) element to attach canvas to"
            +    },
            +    "describe": {
            +      "description": [
            +        "Creates a screen reader accessible description for the canvas. The first parameter should be a string with a description of the canvas. The second parameter is optional. If specified, it determines how the description is displayed.",
            +        "<code class=\"language-javascript\">describe(text, LABEL)</code> displays the description to all users as a <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\"> tombstone or exhibit label/caption</a> in a div adjacent to the canvas. You can style it as you wish in your CSS.",
            +        "<code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the description accessible to screen-reader users only, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a>. If a second parameter is not specified, by default, the description will only be available to screen-reader users."
            +      ],
            +      "params": {
            +        "text": "String: description of the canvas",
            +        "display": "Constant: (Optional) either LABEL or FALLBACK"
            +      }
            +    },
            +    "describeElement": {
            +      "description": [
            +        "This function creates a screen-reader accessible description for elements —shapes or groups of shapes that create meaning together— in the canvas. The first paramater should be the name of the element. The second parameter should be a string with a description of the element. The third parameter is optional. If specified, it determines how the element description is displayed.",
            +        "<code class=\"language-javascript\">describeElement(name, text, LABEL)</code> displays the element description to all users as a <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\"> tombstone or exhibit label/caption</a> in a div adjacent to the canvas. You can style it as you wish in your CSS.",
            +        "<code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code> makes the element description accessible to screen-reader users only, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a>. If a second parameter is not specified, by default, the element description will only be available to screen-reader users."
            +      ],
            +      "params": {
            +        "name": "String: name of the element",
            +        "text": "String: description of the element",
            +        "display": "Constant: (Optional) either LABEL or FALLBACK"
            +      }
            +    },
            +    "textOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">textOutput()</code> creates a screenreader accessible output that describes the shapes present on the canvas. The general description of the canvas includes canvas size, canvas color, and number of elements in the canvas (example: 'Your output is a, 400 by 400 pixels, lavender blue canvas containing the following 4 shapes:'). This description is followed by a list of shapes where the color, position, and area of each shape are described (example: \"orange ellipse at top left covering 1% of the canvas\"). Each element can be selected to get more details. A table of elements is also provided. In this table, shape, color, location, coordinates and area are described (example: \"orange ellipse location=top left area=2\").",
            +        "<code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code> make the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a> which is accessible to screen readers. <code class=\"language-javascript\">textOutput(LABEL)</code> creates an additional div with the output adjacent to the canvas, this is useful for non-screen reader users that might want to display the output outside of the canvas' sub DOM as they code. However, using LABEL will create unnecessary redundancy for screen reader users. We recommend using LABEL only as part of the development process of a sketch and removing it before publishing or sharing with screen reader users."
            +      ],
            +      "params": {
            +        "display": "Constant: (Optional) either FALLBACK or LABEL"
            +      }
            +    },
            +    "gridOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">gridOutput()</code> lays out the content of the canvas in the form of a grid (html table) based on the spatial location of each shape. A brief description of the canvas is available before the table output. This description includes: color of the background, size of the canvas, number of objects, and object types (example: \"lavender blue canvas is 200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid describes the content spatially, each element is placed on a cell of the table depending on its position. Within each cell an element the color and type of shape of that element are available (example: \"orange ellipse\"). These descriptions can be selected individually to get more details. A list of elements where shape, color, location, and area are described (example: \"orange ellipse location=top left area=1%\") is also available.",
            +        "<code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code> make the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a> which is accessible to screen readers. <code class=\"language-javascript\">gridOutput(LABEL)</code> creates an additional div with the output adjacent to the canvas, this is useful for non-screen reader users that might want to display the output outside of the canvas' sub DOM as they code. However, using LABEL will create unnecessary redundancy for screen reader users. We recommend using LABEL only as part of the development process of a sketch and removing it before publishing or sharing with screen reader users."
            +      ],
            +      "params": {
            +        "display": "Constant: (Optional) either FALLBACK or LABEL"
            +      }
            +    },
            +    "alpha": {
            +      "description": [
            +        "Extracts the alpha value from a color or pixel array."
            +      ],
            +      "returns": "Number: the alpha value",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "blue": {
            +      "description": [
            +        "Extracts the blue value from a color or pixel array."
            +      ],
            +      "returns": "Number: the blue value",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "brightness": {
            +      "description": [
            +        "Extracts the HSB brightness value from a color or pixel array."
            +      ],
            +      "returns": "Number: the brightness value",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "color": {
            +      "description": [
            +        "Creates colors for storing in variables of the color datatype. The parameters are interpreted as RGB or HSB values depending on the current <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255 and, therefore, the function call color(255, 204, 0) will return a bright yellow color.",
            +        "Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted as a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either RGB or HSB values. Adding a fourth value applies alpha transparency.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used."
            +      ],
            +      "returns": "p5.Color: resulting color",
            +      "params": {
            +        "gray": "Number: number specifying value between white and black.",
            +        "alpha": "Number: (Optional) alpha value relative to current color range  (default is 0-255)",
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "value": "String: a color string",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color"
            +      }
            +    },
            +    "green": {
            +      "description": [
            +        "Extracts the green value from a color or pixel array."
            +      ],
            +      "returns": "Number: the green value",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "hue": {
            +      "description": [
            +        "Extracts the hue value from a color or pixel array.",
            +        "Hue exists in both HSB and HSL. This function will return the HSB-normalized hue when supplied with an HSB color object (or when supplied with a pixel array while the color mode is HSB), but will default to the HSL-normalized hue otherwise. (The values will only be different if the maximum hue setting for each system is different.)"
            +      ],
            +      "returns": "Number: the hue",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "lerpColor": {
            +      "description": [
            +        "Blends two colors to find a third color somewhere between them. The amt parameter is the amount to interpolate between the two values where 0.0 is equal to the first color, 0.1 is very near the first color, 0.5 is halfway in between, etc. An amount below 0 will be treated as 0. Likewise, amounts above 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>, but necessary because otherwise numbers outside the range will produce strange and unexpected colors.",
            +        "The way that colors are interpolated depends on the current color mode."
            +      ],
            +      "returns": "p5.Color: interpolated color",
            +      "params": {
            +        "c1": "p5.Color: interpolate from this color",
            +        "c2": "p5.Color: interpolate to this color",
            +        "amt": "Number: number between 0 and 1"
            +      }
            +    },
            +    "lightness": {
            +      "description": [
            +        "Extracts the HSL lightness value from a color or pixel array."
            +      ],
            +      "returns": "Number: the lightness",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "red": {
            +      "description": [
            +        "Extracts the red value from a color or pixel array."
            +      ],
            +      "returns": "Number: the red value",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "saturation": {
            +      "description": [
            +        "Extracts the saturation value from a color or pixel array.",
            +        "Saturation is scaled differently in HSB and HSL. This function will return the HSB saturation when supplied with an HSB color object (or when supplied with a pixel array while the color mode is HSB), but will default to the HSL saturation otherwise."
            +      ],
            +      "returns": "Number: the saturation value",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "background": {
            +      "description": [
            +        "The <a href=\"#/p5/background\">background()</a> function sets the color used for the background of the p5.js canvas. The default background is transparent. This function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear the display window at the beginning of each frame, but it can be used inside <a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of animation or if the background need only be set once.",
            +        "The color is either specified in terms of the RGB, HSB, or HSL color depending on the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space is RGB, with each value in the range from 0 to 255). The alpha range by default is also 0 to 255.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used.",
            +        "A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.",
            +        "A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image."
            +      ],
            +      "params": {
            +        "color": "p5.Color: any value created by the <a href=\"#/p5/color\">color()</a> function",
            +        "colorstring": "String: color string, possible formats include: integer  rgb() or rgba(), percentage rgb() or rgba(),  3-digit hex, 6-digit hex",
            +        "a": "Number: (Optional) opacity of the background relative to current  color range (default is 0-255)",
            +        "gray": "Number: specifies a value between white and black",
            +        "v1": "Number: red or hue value (depending on the current color  mode)",
            +        "v2": "Number: green or saturation value (depending on the current  color mode)",
            +        "v3": "Number: blue or brightness value (depending on the current  color mode)",
            +        "values": "Number[]: an array containing the red, green, blue  and alpha components of the color",
            +        "image": "p5.Image: image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,  to set as background  (must be same size as the sketch window)"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Clears the pixels within a buffer. This function only clears the canvas. It will not clear objects created by createX() methods such as <a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>. Unlike the main graphics context, pixels in additional graphics areas created with <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely or partially transparent. This function clears everything to make all of the pixels 100% transparent.",
            +        "Note: In WebGL mode, this function can be passed normalized RGBA color values in order to clear the screen to a specific color. In addition to color, it will also clear the depth buffer. If you are not using the webGL renderer these color values will have no effect."
            +      ],
            +      "params": {
            +        "r": "Number: normalized red val.",
            +        "g": "Number: normalized green val.",
            +        "b": "Number: normalized blue val.",
            +        "a": "Number: normalized alpha val."
            +      }
            +    },
            +    "colorMode": {
            +      "description": [
            +        "<a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets color data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>, and <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255 using the RGB color model. This is equivalent to setting colorMode(RGB, 255). Setting colorMode(HSB) lets you use the HSB system instead. By default, this is colorMode(HSB, 360, 100, 100, 1). You can also use HSL.",
            +        "Note: existing color objects remember the mode that they were created in, so you can change modes as you like without affecting their appearance."
            +      ],
            +      "params": {
            +        "mode": "Constant: either RGB, HSB or HSL, corresponding to  Red/Green/Blue and Hue/Saturation/Brightness  (or Lightness)",
            +        "max": "Number: (Optional) range for all values",
            +        "max1": "Number: range for the red or hue depending on the  current color mode",
            +        "max2": "Number: range for the green or saturation depending  on the current color mode",
            +        "max3": "Number: range for the blue or brightness/lightness  depending on the current color mode",
            +        "maxA": "Number: (Optional) range for the alpha"
            +      }
            +    },
            +    "fill": {
            +      "description": [
            +        "Sets the color used to fill shapes. For example, if you run fill(204, 102, 0), all shapes drawn after the fill command will be filled with the color orange. This color is either specified in terms of the RGB or HSB color depending on the current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space is RGB, with each value in the range from 0 to 255). The alpha range by default is also 0 to 255.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used.",
            +        "A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "alpha": "Number (Optional)",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the fill color"
            +      }
            +    },
            +    "noFill": {
            +      "description": [
            +        "Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called, nothing will be drawn to the screen."
            +      ]
            +    },
            +    "noStroke": {
            +      "description": [
            +        "Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called, nothing will be drawn to the screen."
            +      ]
            +    },
            +    "stroke": {
            +      "description": [
            +        "Sets the color used to draw lines and borders around shapes. This color is either specified in terms of the RGB or HSB color depending on the current <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space is RGB, with each value in the range from 0 to 255). The alpha range by default is also 0 to 255.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used.",
            +        "A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "alpha": "Number (Optional)",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the stroke color"
            +      }
            +    },
            +    "erase": {
            +      "description": [
            +        "All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from the canvas.Erased areas will reveal the web page underneath the canvas.Erasing can be canceled with <a href=\"#/p5/noErase\">noErase()</a>.",
            +        "Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\"> background()</a> in between <a href=\"#/p5/erase\">erase()</a> and <a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual."
            +      ],
            +      "params": {
            +        "strengthFill": "Number: (Optional) A number (0-255) for the strength of erasing for a shape's fill.  This will default to 255 when no argument is given, which  is full strength.",
            +        "strengthStroke": "Number: (Optional) A number (0-255) for the strength of erasing for a shape's stroke.  This will default to 255 when no argument is given, which  is full strength."
            +      }
            +    },
            +    "noErase": {
            +      "description": [
            +        "Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>. The <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and <a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were prior to calling <a href=\"#/p5/erase\">erase()</a>."
            +      ]
            +    },
            +    "arc": {
            +      "description": [
            +        "Draw an arc to the screen. If called with only x, y, w, h, start and stop, the arc will be drawn and filled as an open pie segment. If a mode parameter is provided, the arc will be filled like an open semi-circle (OPEN), a closed semi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed with the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.",
            +        "The arc is always drawn clockwise from wherever start falls to wherever stop falls on the ellipse. Adding or subtracting TWO_PI to either angle does not change where they fall. If both start and stop fall at the same place, a full ellipse will be drawn. Be aware that the y-axis increases in the downward direction, therefore angles are measured clockwise from the positive x-direction (\"3 o'clock\")."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the arc's ellipse",
            +        "y": "Number: y-coordinate of the arc's ellipse",
            +        "w": "Number: width of the arc's ellipse by default",
            +        "h": "Number: height of the arc's ellipse by default",
            +        "start": "Number: angle to start the arc, specified in radians",
            +        "stop": "Number: angle to stop the arc, specified in radians",
            +        "mode": "Constant: (Optional) optional parameter to determine the way of drawing  the arc. either CHORD, PIE or OPEN",
            +        "detail": "Integer: (Optional) optional parameter for WebGL mode only. This is to  specify the number of vertices that makes up the  perimeter of the arc. Default value is 25. Won't  draw a stroke for a detail of more than 50."
            +      }
            +    },
            +    "ellipse": {
            +      "description": [
            +        "Draws an ellipse (oval) to the screen. By default, the first two parameters set the location of the center of the ellipse, and the third and fourth parameters set the shape's width and height. If no height is specified, the value of width is used for both the width and height. If a negative height or width is specified, the absolute value is taken.",
            +        "An ellipse with equal width and height is a circle. The origin may be changed with the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the center of ellipse.",
            +        "y": "Number: y-coordinate of the center of ellipse.",
            +        "w": "Number: width of the ellipse.",
            +        "h": "Number: (Optional) height of the ellipse.",
            +        "detail": "Integer: (Optional) optional parameter for WebGL mode only. This is to  specify the number of vertices that makes up the  perimeter of the ellipse. Default value is 25. Won't  draw a stroke for a detail of more than 50."
            +      }
            +    },
            +    "circle": {
            +      "description": [
            +        "Draws a circle to the screen. A circle is a simple closed shape. It is the set of all points in a plane that are at a given distance from a given point, the centre. This function is a special case of the ellipse() function, where the width and height of the ellipse are the same. Height and width of the ellipse correspond to the diameter of the circle. By default, the first two parameters set the location of the centre of the circle, the third sets the diameter of the circle."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the centre of the circle.",
            +        "y": "Number: y-coordinate of the centre of the circle.",
            +        "d": "Number: diameter of the circle."
            +      }
            +    },
            +    "line": {
            +      "description": [
            +        "Draws a line (a direct path between two points) to the screen. If called with only 4 parameters, it will draw a line in 2D with a default width of 1 pixel. This width can be modified by using the <a href=\"#/p5/strokeWeight\"> strokeWeight()</a> function. A line cannot be filled, therefore the <a href=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to color a line, use the <a href=\"#/p5/stroke\">stroke()</a> function."
            +      ],
            +      "params": {
            +        "x1": "Number: the x-coordinate of the first point",
            +        "y1": "Number: the y-coordinate of the first point",
            +        "x2": "Number: the x-coordinate of the second point",
            +        "y2": "Number: the y-coordinate of the second point",
            +        "z1": "Number: the z-coordinate of the first point",
            +        "z2": "Number: the z-coordinate of the second point"
            +      }
            +    },
            +    "point": {
            +      "description": [
            +        "Draws a point, a coordinate in space at the dimension of one pixel. The first parameter is the horizontal value for the point, the second param is the vertical value for the point. The color of the point is changed with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point can be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function."
            +      ],
            +      "params": {
            +        "x": "Number: the x-coordinate",
            +        "y": "Number: the y-coordinate",
            +        "z": "Number: (Optional) the z-coordinate (for WebGL mode)",
            +        "coordinate_vector": "p5.Vector: the coordinate vector"
            +      }
            +    },
            +    "quad": {
            +      "description": [
            +        "Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is similar to a rectangle, but the angles between its edges are not constrained to ninety degrees. The first pair of parameters (x1,y1) sets the first vertex and the subsequent pairs should proceed clockwise or counter-clockwise around the defined shape. z-arguments only work when quad() is used in WEBGL mode."
            +      ],
            +      "params": {
            +        "x1": "Number: the x-coordinate of the first point",
            +        "y1": "Number: the y-coordinate of the first point",
            +        "x2": "Number: the x-coordinate of the second point",
            +        "y2": "Number: the y-coordinate of the second point",
            +        "x3": "Number: the x-coordinate of the third point",
            +        "y3": "Number: the y-coordinate of the third point",
            +        "x4": "Number: the x-coordinate of the fourth point",
            +        "y4": "Number: the y-coordinate of the fourth point",
            +        "detailX": "Integer: (Optional) number of segments in the x-direction",
            +        "detailY": "Integer: (Optional) number of segments in the y-direction",
            +        "z1": "Number: the z-coordinate of the first point",
            +        "z2": "Number: the z-coordinate of the second point",
            +        "z3": "Number: the z-coordinate of the third point",
            +        "z4": "Number: the z-coordinate of the fourth point"
            +      }
            +    },
            +    "rect": {
            +      "description": [
            +        "Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with every angle at ninety degrees. By default, the first two parameters set the location of the upper-left corner, the third sets the width, and the fourth sets the height. The way these parameters are interpreted, may be changed with the <a href=\"#/p5/rectMode\">rectMode()</a> function.",
            +        "The fifth, sixth, seventh and eighth parameters, if specified, determine corner radius for the top-left, top-right, lower-right and lower-left corners, respectively. An omitted corner radius parameter is set to the value of the previously specified radius value in the parameter list."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the rectangle.",
            +        "y": "Number: y-coordinate of the rectangle.",
            +        "w": "Number: width of the rectangle.",
            +        "h": "Number: (Optional) height of the rectangle.",
            +        "tl": "Number: (Optional) optional radius of top-left corner.",
            +        "tr": "Number: (Optional) optional radius of top-right corner.",
            +        "br": "Number: (Optional) optional radius of bottom-right corner.",
            +        "bl": "Number: (Optional) optional radius of bottom-left corner.",
            +        "detailX": "Integer: (Optional) number of segments in the x-direction (for WebGL mode)",
            +        "detailY": "Integer: (Optional) number of segments in the y-direction (for WebGL mode)"
            +      }
            +    },
            +    "square": {
            +      "description": [
            +        "Draws a square to the screen. A square is a four-sided shape with every angle at ninety degrees, and equal side size. This function is a special case of the rect() function, where the width and height are the same, and the parameter is called \"s\" for side size. By default, the first two parameters set the location of the upper-left corner, the third sets the side size of the square. The way these parameters are interpreted, may be changed with the <a href=\"#/p5/rectMode\">rectMode()</a> function.",
            +        "The fourth, fifth, sixth and seventh parameters, if specified, determine corner radius for the top-left, top-right, lower-right and lower-left corners, respectively. An omitted corner radius parameter is set to the value of the previously specified radius value in the parameter list."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the square.",
            +        "y": "Number: y-coordinate of the square.",
            +        "s": "Number: side size of the square.",
            +        "tl": "Number: (Optional) optional radius of top-left corner.",
            +        "tr": "Number: (Optional) optional radius of top-right corner.",
            +        "br": "Number: (Optional) optional radius of bottom-right corner.",
            +        "bl": "Number: (Optional) optional radius of bottom-left corner."
            +      }
            +    },
            +    "triangle": {
            +      "description": [
            +        "Draws a triangle to the canvas. A triangle is a plane created by connecting three points. The first two arguments specify the first point, the middle two arguments specify the second point, and the last two arguments specify the third point."
            +      ],
            +      "params": {
            +        "x1": "Number: x-coordinate of the first point",
            +        "y1": "Number: y-coordinate of the first point",
            +        "x2": "Number: x-coordinate of the second point",
            +        "y2": "Number: y-coordinate of the second point",
            +        "x3": "Number: x-coordinate of the third point",
            +        "y3": "Number: y-coordinate of the third point"
            +      }
            +    },
            +    "ellipseMode": {
            +      "description": [
            +        "Modifies the location from which ellipses are drawn by changing the way in which parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>, <a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.",
            +        "The default mode is CENTER, in which the first two parameters are interpreted as the shape's center point's x and y coordinates respectively, while the third and fourth parameters are its width and height.",
            +        "ellipseMode(RADIUS) also uses the first two parameters as the shape's center point's x and y coordinates, but uses the third and fourth parameters to specify half of the shapes's width and height.",
            +        "ellipseMode(CORNER) interprets the first two parameters as the upper-left corner of the shape, while the third and fourth parameters are its width and height.",
            +        "ellipseMode(CORNERS) interprets the first two parameters as the location of one corner of the ellipse's bounding box, and the third and fourth parameters as the location of the opposite corner.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "mode": "Constant: either CENTER, RADIUS, CORNER, or CORNERS"
            +      }
            +    },
            +    "noSmooth": {
            +      "description": [
            +        "Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable smoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled by default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like smooth (antialiased) edges on your geometry."
            +      ]
            +    },
            +    "rectMode": {
            +      "description": [
            +        "Modifies the location from which rectangles are drawn by changing the way in which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.",
            +        "The default mode is CORNER, which interprets the first two parameters as the upper-left corner of the shape, while the third and fourth parameters are its width and height.",
            +        "rectMode(CORNERS) interprets the first two parameters as the location of one of the corners, and the third and fourth parameters as the location of the diagonally opposite corner. Note, the rectangle is drawn between the coordinates, so it is not neccesary that the first corner be the upper left corner.",
            +        "rectMode(CENTER) interprets the first two parameters as the shape's center point, while the third and fourth parameters are its width and height.",
            +        "rectMode(RADIUS) also uses the first two parameters as the shape's center point, but uses the third and fourth parameters to specify half of the shape's width and height respectively.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "mode": "Constant: either CORNER, CORNERS, CENTER, or RADIUS"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also improve image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by default in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled by default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like smooth (antialiased) edges on your geometry."
            +      ]
            +    },
            +    "strokeCap": {
            +      "description": [
            +        "Sets the style for rendering line endings. These ends are either rounded, squared or extended, each of which specified with the corresponding parameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "cap": "Constant: either ROUND, SQUARE or PROJECT"
            +      }
            +    },
            +    "strokeJoin": {
            +      "description": [
            +        "Sets the style of the joints which connect line segments. These joints are either mitered, beveled or rounded and specified with the corresponding parameters MITER, BEVEL and ROUND. The default joint is MITER.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "join": "Constant: either MITER, BEVEL, ROUND"
            +      }
            +    },
            +    "strokeWeight": {
            +      "description": [
            +        "Sets the width of the stroke used for lines, points and the border around shapes. All widths are set in units of pixels.",
            +        "Note that it is affected by any transformation or scaling that has been applied previously."
            +      ],
            +      "params": {
            +        "weight": "Number: the weight of the stroke (in pixels)"
            +      }
            +    },
            +    "bezier": {
            +      "description": [
            +        "Draws a cubic Bezier curve on the screen. These curves are defined by a series of anchor and control points. The first two parameters specify the first anchor point and the last two parameters specify the other anchor point, which become the first and last points on the curve. The middle parameters specify the two control points which define the shape of the curve. Approximately speaking, control points \"pull\" the curve towards them.",
            +        "Bezier curves were developed by French automotive engineer Pierre Bezier, and are commonly used in computer graphics to define gently sloping curves. See also <a href=\"#/p5/curve\">curve()</a>."
            +      ],
            +      "params": {
            +        "x1": "Number: x-coordinate for the first anchor point",
            +        "y1": "Number: y-coordinate for the first anchor point",
            +        "x2": "Number: x-coordinate for the first control point",
            +        "y2": "Number: y-coordinate for the first control point",
            +        "x3": "Number: x-coordinate for the second control point",
            +        "y3": "Number: y-coordinate for the second control point",
            +        "x4": "Number: x-coordinate for the second anchor point",
            +        "y4": "Number: y-coordinate for the second anchor point",
            +        "z1": "Number: z-coordinate for the first anchor point",
            +        "z2": "Number: z-coordinate for the first control point",
            +        "z3": "Number: z-coordinate for the second control point",
            +        "z4": "Number: z-coordinate for the second anchor point"
            +      }
            +    },
            +    "bezierDetail": {
            +      "description": [
            +        "Sets the resolution at which Bezier's curve is displayed. The default value is 20.",
            +        "Note, This function is only useful when using the WEBGL renderer as the default canvas renderer does not use this information."
            +      ],
            +      "params": {
            +        "detail": "Number: resolution of the curves"
            +      }
            +    },
            +    "bezierPoint": {
            +      "description": [
            +        "Given the x or y co-ordinate values of control and anchor points of a bezier curve, it evaluates the x or y coordinate of the bezier at position t. The parameters a and d are the x or y coordinates of first and last points on the curve while b and c are of the control points.The final parameter t is the position of the resultant point which is given between 0 and 1. This can be done once with the x coordinates and a second time with the y coordinates to get the location of a bezier curve at t."
            +      ],
            +      "returns": "Number: the value of the Bezier at position t",
            +      "params": {
            +        "a": "Number: coordinate of first point on the curve",
            +        "b": "Number: coordinate of first control point",
            +        "c": "Number: coordinate of second control point",
            +        "d": "Number: coordinate of second point on the curve",
            +        "t": "Number: value between 0 and 1"
            +      }
            +    },
            +    "bezierTangent": {
            +      "description": [
            +        "Evaluates the tangent to the Bezier at position t for points a, b, c, d. The parameters a and d are the first and last points on the curve, and b and c are the control points. The final parameter t varies between 0 and 1."
            +      ],
            +      "returns": "Number: the tangent at position t",
            +      "params": {
            +        "a": "Number: coordinate of first point on the curve",
            +        "b": "Number: coordinate of first control point",
            +        "c": "Number: coordinate of second control point",
            +        "d": "Number: coordinate of second point on the curve",
            +        "t": "Number: value between 0 and 1"
            +      }
            +    },
            +    "curve": {
            +      "description": [
            +        "Draws a curved line on the screen between two points, given as the middle four parameters. The first two parameters are a control point, as if the curve came from this point even though it's not drawn. The last two parameters similarly describe the other control point. <br /><br /> Longer curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions together or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called <a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve. The <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines."
            +      ],
            +      "params": {
            +        "x1": "Number: x-coordinate for the beginning control point",
            +        "y1": "Number: y-coordinate for the beginning control point",
            +        "x2": "Number: x-coordinate for the first point",
            +        "y2": "Number: y-coordinate for the first point",
            +        "x3": "Number: x-coordinate for the second point",
            +        "y3": "Number: y-coordinate for the second point",
            +        "x4": "Number: x-coordinate for the ending control point",
            +        "y4": "Number: y-coordinate for the ending control point",
            +        "z1": "Number: z-coordinate for the beginning control point",
            +        "z2": "Number: z-coordinate for the first point",
            +        "z3": "Number: z-coordinate for the second point",
            +        "z4": "Number: z-coordinate for the ending control point"
            +      }
            +    },
            +    "curveDetail": {
            +      "description": [
            +        "Sets the resolution at which curves display. The default value is 20 while the minimum value is 3.",
            +        "This function is only useful when using the WEBGL renderer as the default canvas renderer does not use this information."
            +      ],
            +      "params": {
            +        "resolution": "Number: resolution of the curves"
            +      }
            +    },
            +    "curveTightness": {
            +      "description": [
            +        "Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a> and <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness determines how the curve fits to the vertex points. The value 0.0 is the default value for tightness (this value defines the curves to be Catmull-Rom splines) and the value 1.0 connects all the points with straight lines. Values within the range -5.0 and 5.0 will deform the curves but will leave them recognizable and as values increase in magnitude, they will continue to deform."
            +      ],
            +      "params": {
            +        "amount": "Number: amount of deformation from the original vertices"
            +      }
            +    },
            +    "curvePoint": {
            +      "description": [
            +        "Evaluates the curve at position t for points a, b, c, d. The parameter t varies between 0 and 1, a and d are control points of the curve, and b and c are the start and end points of the curve. This can be done once with the x coordinates and a second time with the y coordinates to get the location of a curve at t."
            +      ],
            +      "returns": "Number: bezier value at position t",
            +      "params": {
            +        "a": "Number: coordinate of first control point of the curve",
            +        "b": "Number: coordinate of first point",
            +        "c": "Number: coordinate of second point",
            +        "d": "Number: coordinate of second control point",
            +        "t": "Number: value between 0 and 1"
            +      }
            +    },
            +    "curveTangent": {
            +      "description": [
            +        "Evaluates the tangent to the curve at position t for points a, b, c, d. The parameter t varies between 0 and 1, a and d are points on the curve, and b and c are the control points."
            +      ],
            +      "returns": "Number: the tangent at position t",
            +      "params": {
            +        "a": "Number: coordinate of first control point",
            +        "b": "Number: coordinate of first point on the curve",
            +        "c": "Number: coordinate of second point on the curve",
            +        "d": "Number: coordinate of second conrol point",
            +        "t": "Number: value between 0 and 1"
            +      }
            +    },
            +    "beginContour": {
            +      "description": [
            +        "Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a> begins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording. The vertices that define a negative shape must \"wind\" in the opposite direction from the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices shape in counter-clockwise.",
            +        "These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within."
            +      ]
            +    },
            +    "beginShape": {
            +      "description": [
            +        "Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more complex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and <a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which types of shapes to create from the provided vertices. With no mode specified, the shape can be any irregular polygon.",
            +        "The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:",
            +        "POINTS Draw a series of points",
            +        "LINES Draw a series of unconnected line segments (individual lines)",
            +        "TRIANGLES Draw a series of separate triangles",
            +        "TRIANGLE_FAN Draw a series of connected triangles sharing the first vertex in a fan-like fashion",
            +        "TRIANGLE_STRIP Draw a series of connected triangles in strip fashion",
            +        "QUADS Draw a series of separate quad",
            +        "QUAD_STRIP Draw quad strip using adjacent edges to form the next quad",
            +        "TESS (WebGl only) Handle irregular polygon for filling curve by explicit tessellation",
            +        "After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop drawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the current stroke color and filled with the fill color.",
            +        "Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "kind": "Constant: (Optional) either POINTS, LINES, TRIANGLES, TRIANGLE_FAN  TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS"
            +      }
            +    },
            +    "bezierVertex": {
            +      "description": [
            +        "Specifies vertex coordinates for Bezier curves. Each call to bezierVertex() defines the position of two control points and one anchor point of a Bezier curve, adding a new segment to a line or shape. For WebGL mode bezierVertex() can be used in 2D as well as 3D mode. 2D mode expects 6 parameters, while 3D mode expects 9 parameters (including z coordinates).",
            +        "The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there is no MODE or POINTS parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "x2": "Number: x-coordinate for the first control point",
            +        "y2": "Number: y-coordinate for the first control point",
            +        "x3": "Number: x-coordinate for the second control point",
            +        "y3": "Number: y-coordinate for the second control point",
            +        "x4": "Number: x-coordinate for the anchor point",
            +        "y4": "Number: y-coordinate for the anchor point",
            +        "z2": "Number: z-coordinate for the first control point (for WebGL mode)",
            +        "z3": "Number: z-coordinate for the second control point (for WebGL mode)",
            +        "z4": "Number: z-coordinate for the anchor point (for WebGL mode)"
            +      }
            +    },
            +    "curveVertex": {
            +      "description": [
            +        "Specifies vertex coordinates for curves. This function may only be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there is no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>. For WebGL mode curveVertex() can be used in 2D as well as 3D mode. 2D mode expects 2 parameters, while 3D mode expects 3 parameters.",
            +        "The first and last points in a series of curveVertex() lines will be used to guide the beginning and end of the curve. A minimum of four points is required to draw a tiny curve between the second and third points. Adding a fifth point with curveVertex() will draw the curve between the second, third, and fourth points. The curveVertex() function is an implementation of Catmull-Rom splines."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the vertex",
            +        "y": "Number: y-coordinate of the vertex",
            +        "z": "Number: (Optional) z-coordinate of the vertex (for WebGL mode)"
            +      }
            +    },
            +    "endContour": {
            +      "description": [
            +        "Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a> begins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording. The vertices that define a negative shape must \"wind\" in the opposite direction from the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices shape in counter-clockwise.",
            +        "These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within."
            +      ]
            +    },
            +    "endShape": {
            +      "description": [
            +        "The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be called after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data defined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image buffer. The constant CLOSE as the value for the MODE parameter to close the shape (to connect the beginning and the end)."
            +      ],
            +      "params": {
            +        "mode": "Constant: (Optional) use CLOSE to close the shape"
            +      }
            +    },
            +    "quadraticVertex": {
            +      "description": [
            +        "Specifies vertex coordinates for quadratic Bezier curves. Each call to quadraticVertex() defines the position of one control points and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point. For WebGL mode quadraticVertex() can be used in 2D as well as 3D mode. 2D mode expects 4 parameters, while 3D mode expects 6 parameters (including z coordinates).",
            +        "This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there is no MODE or POINTS parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "cx": "Number: x-coordinate for the control point",
            +        "cy": "Number: y-coordinate for the control point",
            +        "x3": "Number: x-coordinate for the anchor point",
            +        "y3": "Number: y-coordinate for the anchor point",
            +        "cz": "Number: z-coordinate for the control point (for WebGL mode)",
            +        "z3": "Number: z-coordinate for the anchor point (for WebGL mode)"
            +      }
            +    },
            +    "vertex": {
            +      "description": [
            +        "All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a> is used to specify the vertex coordinates for points, lines, triangles, quads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the vertex",
            +        "y": "Number: y-coordinate of the vertex",
            +        "z": "Number: z-coordinate of the vertex.  Defaults to 0 if not specified.",
            +        "u": "Number: the vertex's texture u-coordinate",
            +        "v": "Number: the vertex's texture v-coordinate"
            +      }
            +    },
            +    "normal": {
            +      "description": [
            +        "Sets the 3d vertex normal to use for subsequent vertices drawn with <a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally nearly perpendicular to a shape's surface which controls how much light will be reflected from that part of the surface."
            +      ],
            +      "params": {
            +        "vector": "Vector: A p5.Vector representing the vertex normal.",
            +        "x": "Number: The x component of the vertex normal.",
            +        "y": "Number: The y component of the vertex normal.",
            +        "z": "Number: The z component of the vertex normal."
            +      }
            +    },
            +    "VERSION": {
            +      "description": [
            +        "Version of this p5.js."
            +      ]
            +    },
            +    "P2D": {
            +      "description": [
            +        "The default, two-dimensional renderer."
            +      ]
            +    },
            +    "WEBGL": {
            +      "description": [
            +        "One of the two render modes in p5.js: P2D (default renderer) and WEBGL Enables 3D render by introducing the third dimension: Z"
            +      ]
            +    },
            +    "ARROW": {},
            +    "CROSS": {},
            +    "HAND": {},
            +    "MOVE": {},
            +    "TEXT": {},
            +    "WAIT": {},
            +    "HALF_PI": {
            +      "description": [
            +        "HALF_PI is a mathematical constant with the value 1.57079632679489661923. It is half the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "PI": {
            +      "description": [
            +        "PI is a mathematical constant with the value 3.14159265358979323846. It is the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "QUARTER_PI": {
            +      "description": [
            +        "QUARTER_PI is a mathematical constant with the value 0.7853982. It is one quarter the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "TAU": {
            +      "description": [
            +        "TAU is an alias for TWO_PI, a mathematical constant with the value 6.28318530717958647693. It is twice the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "TWO_PI": {
            +      "description": [
            +        "TWO_PI is a mathematical constant with the value 6.28318530717958647693. It is twice the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "DEGREES": {
            +      "description": [
            +        "Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which p5.js interprets and calculates angles (either DEGREES or RADIANS)."
            +      ]
            +    },
            +    "RADIANS": {
            +      "description": [
            +        "Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which p5.js interprets and calculates angles (either RADIANS or DEGREES)."
            +      ]
            +    },
            +    "CORNER": {},
            +    "CORNERS": {},
            +    "RADIUS": {},
            +    "RIGHT": {},
            +    "LEFT": {},
            +    "CENTER": {},
            +    "TOP": {},
            +    "BOTTOM": {},
            +    "BASELINE": {},
            +    "POINTS": {},
            +    "LINES": {},
            +    "LINE_STRIP": {},
            +    "LINE_LOOP": {},
            +    "TRIANGLES": {},
            +    "TRIANGLE_FAN": {},
            +    "TRIANGLE_STRIP": {},
            +    "QUADS": {},
            +    "QUAD_STRIP": {},
            +    "TESS": {},
            +    "CLOSE": {},
            +    "OPEN": {},
            +    "CHORD": {},
            +    "PIE": {},
            +    "PROJECT": {},
            +    "SQUARE": {},
            +    "ROUND": {},
            +    "BEVEL": {},
            +    "MITER": {},
            +    "RGB": {},
            +    "HSB": {
            +      "description": [
            +        "HSB (hue, saturation, brightness) is a type of color model. You can learn more about it at <a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>."
            +      ]
            +    },
            +    "HSL": {},
            +    "AUTO": {
            +      "description": [
            +        "AUTO allows us to automatically set the width or height of an element (but not both), based on the current height and width of the element. Only one parameter can be passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time."
            +      ]
            +    },
            +    "ALT": {},
            +    "BACKSPACE": {},
            +    "CONTROL": {},
            +    "DELETE": {},
            +    "DOWN_ARROW": {},
            +    "ENTER": {},
            +    "ESCAPE": {},
            +    "LEFT_ARROW": {},
            +    "OPTION": {},
            +    "RETURN": {},
            +    "RIGHT_ARROW": {},
            +    "SHIFT": {},
            +    "TAB": {},
            +    "UP_ARROW": {},
            +    "BLEND": {},
            +    "REMOVE": {},
            +    "ADD": {},
            +    "DARKEST": {},
            +    "LIGHTEST": {},
            +    "DIFFERENCE": {},
            +    "SUBTRACT": {},
            +    "EXCLUSION": {},
            +    "MULTIPLY": {},
            +    "SCREEN": {},
            +    "REPLACE": {},
            +    "OVERLAY": {},
            +    "HARD_LIGHT": {},
            +    "SOFT_LIGHT": {},
            +    "DODGE": {},
            +    "BURN": {},
            +    "THRESHOLD": {},
            +    "GRAY": {},
            +    "OPAQUE": {},
            +    "INVERT": {},
            +    "POSTERIZE": {},
            +    "DILATE": {},
            +    "ERODE": {},
            +    "BLUR": {},
            +    "NORMAL": {},
            +    "ITALIC": {},
            +    "BOLD": {},
            +    "BOLDITALIC": {},
            +    "CHAR": {},
            +    "WORD": {},
            +    "LINEAR": {},
            +    "QUADRATIC": {},
            +    "BEZIER": {},
            +    "CURVE": {},
            +    "STROKE": {},
            +    "FILL": {},
            +    "TEXTURE": {},
            +    "IMMEDIATE": {},
            +    "IMAGE": {},
            +    "NEAREST": {},
            +    "REPEAT": {},
            +    "CLAMP": {},
            +    "MIRROR": {},
            +    "LANDSCAPE": {},
            +    "PORTRAIT": {},
            +    "GRID": {},
            +    "AXES": {},
            +    "LABEL": {},
            +    "FALLBACK": {},
            +    "print": {
            +      "description": [
            +        "The <a href=\"#/p5/print\">print()</a> function writes to the console area of your browser. This function is often helpful for looking at the data a program is producing. This function creates a new line of text for each call to the function. Individual elements can be separated with quotes (\"\") and joined with the addition operator (+).",
            +        "Note that calling print() without any arguments invokes the window.print() function which opens the browser's print dialog. To print a blank line to console you can write print('\\n')."
            +      ],
            +      "params": {
            +        "contents": "Any: any combination of Number, String, Object, Boolean,  Array to print"
            +      }
            +    },
            +    "frameCount": {
            +      "description": [
            +        "The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the number of frames that have been displayed since the program started. Inside <a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration of draw it is 1, etc."
            +      ]
            +    },
            +    "deltaTime": {
            +      "description": [
            +        "The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time difference between the beginning of the previous frame and the beginning of the current frame in milliseconds.",
            +        "This variable is useful for creating time sensitive animation or physics calculation that should stay constant regardless of frame rate."
            +      ]
            +    },
            +    "focused": {
            +      "description": [
            +        "Confirms if the window a p5.js program is in is \"focused,\" meaning that the sketch will accept mouse or keyboard input. This variable is \"true\" if the window is focused and \"false\" if not."
            +      ]
            +    },
            +    "cursor": {
            +      "description": [
            +        "Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended size is 16×16 or 32×32 pixels. The values for parameters x and y must be less than the dimensions of the image."
            +      ],
            +      "params": {
            +        "type": "String|Constant: Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT  Native CSS properties: 'grab', 'progress', 'cell' etc.  External: path for cursor's images  (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)  For more information on Native CSS cursors and url visit:  <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a>",
            +        "x": "Number: (Optional) the horizontal active spot of the cursor (must be less than 32)",
            +        "y": "Number: (Optional) the vertical active spot of the cursor (must be less than 32)"
            +      }
            +    },
            +    "frameRate": {
            +      "description": [
            +        "Specifies the number of frames to be displayed every second. For example, the function call frameRate(30) will attempt to refresh 30 times a second. If the processor is not fast enough to maintain the specified rate, the frame rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is based on the frame rate of the display (here also called \"refresh rate\"), which is set to 60 frames per second on most computers. A frame rate of 24 frames per second (usual for movies) or above will be enough for smooth animations. This is the same as setFrameRate(val).",
            +        "Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate. The draw function must run at least once before it will return a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.",
            +        "Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not of the type numbers or are non positive also returns current framerate."
            +      ],
            +      "params": {
            +        "fps": "Number: number of frames to be displayed every second"
            +      }
            +    },
            +    "noCursor": {
            +      "description": [
            +        "Hides the cursor from view."
            +      ]
            +    },
            +    "displayWidth": {
            +      "description": [
            +        "System variable that stores the width of the screen display according to The default <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a full-screen program on any display size. To return actual screen size, multiply this by pixelDensity."
            +      ]
            +    },
            +    "displayHeight": {
            +      "description": [
            +        "System variable that stores the height of the screen display according to The default <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a full-screen program on any display size. To return actual screen size, multiply this by pixelDensity."
            +      ]
            +    },
            +    "windowWidth": {
            +      "description": [
            +        "System variable that stores the width of the inner window, it maps to window.innerWidth."
            +      ]
            +    },
            +    "windowHeight": {
            +      "description": [
            +        "System variable that stores the height of the inner window, it maps to window.innerHeight."
            +      ]
            +    },
            +    "windowResized": {
            +      "description": [
            +        "The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once every time the browser window is resized. This is a good place to resize the canvas or do any other adjustments to accommodate the new window size."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional Event callback argument."
            +      }
            +    },
            +    "width": {
            +      "description": [
            +        "System variable that stores the width of the drawing canvas. This value is set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For example, the function call createCanvas(320, 240) sets the width variable to the value 320. The value of width defaults to 100 if <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "System variable that stores the height of the drawing canvas. This value is set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For example, the function call createCanvas(320, 240) sets the height variable to the value 240. The value of height defaults to 100 if <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program."
            +      ]
            +    },
            +    "fullscreen": {
            +      "description": [
            +        "If argument is given, sets the sketch to fullscreen or not based on the value of the argument. If no argument is given, returns the current fullscreen state. Note that due to browser restrictions this can only be called on user input, for example, on mouse press like the example below."
            +      ],
            +      "returns": "Boolean: current fullscreen state",
            +      "params": {
            +        "val": "Boolean: (Optional) whether the sketch should be in fullscreen mode or not"
            +      }
            +    },
            +    "pixelDensity": {
            +      "description": [
            +        "Sets the pixel scaling for high pixel density displays. By default pixel density is set to match display density, call pixelDensity(1) to turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns the current pixel density of the sketch."
            +      ],
            +      "params": {
            +        "val": "Number: whether or how much the sketch should scale"
            +      }
            +    },
            +    "displayDensity": {
            +      "description": [
            +        "Returns the pixel density of the current display the sketch is running on."
            +      ],
            +      "returns": "Number: current pixel density of the display"
            +    },
            +    "getURL": {
            +      "description": [
            +        "Gets the current URL. Note: when using the p5 Editor, this will return an empty object because the sketch is embedded in an iframe. It will work correctly if you view the sketch using the editor's present or share URLs."
            +      ],
            +      "returns": "String: url"
            +    },
            +    "getURLPath": {
            +      "description": [
            +        "Gets the current URL path as an array. Note: when using the p5 Editor, this will return an empty object because the sketch is embedded in an iframe. It will work correctly if you view the sketch using the editor's present or share URLs."
            +      ],
            +      "returns": "String[]: path components"
            +    },
            +    "getURLParams": {
            +      "description": [
            +        "Gets the current URL params as an Object. Note: when using the p5 Editor, this will return an empty object because the sketch is embedded in an iframe. It will work correctly if you view the sketch using the editor's present or share URLs."
            +      ],
            +      "returns": "Object: URL params"
            +    },
            +    "preload": {
            +      "description": [
            +        "Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle asynchronous loading of external files in a blocking way. If a preload function is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have finished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>, <a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous loading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a> or anywhere else with the use of a callback parameter.",
            +        "By default the text \"loading...\" will be displayed. To make your own loading page, include an HTML element with id \"p5_loading\" in your page. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>."
            +      ]
            +    },
            +    "setup": {
            +      "description": [
            +        "The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to define initial environment properties such as screen size and background color and to load media such as images and fonts as the program starts. There can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't be called again after its initial execution.",
            +        "Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other functions, including <a href=\"#/p5/draw\">draw()</a>."
            +      ]
            +    },
            +    "draw": {
            +      "description": [
            +        "Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes the lines of code contained inside its block until the program is stopped or <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will still be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and should never be called explicitly.",
            +        "It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After <a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the code inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code inside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.",
            +        "The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with the <a href=\"#/p5/frameRate\">frameRate()</a> function.",
            +        "There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must exist if you want the code to run continuously, or to process events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in your program, as shown in the above example.",
            +        "It is important to note that the drawing coordinate system will be reset at the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed within <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be undone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate over time. On the other hand, styling applied (ex: fill, stroke, etc) will remain in effect."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the entire p5 sketch. This will remove the canvas and any elements created by p5.js. It will also stop the draw loop and unbind any properties or methods from the window global scope. It will leave a variable p5 in case you wanted to create a new p5 sketch. If you like, you can set p5 = null to erase it. While all functions and variables and objects created by the p5 library will be removed, any other global variables created by your code will remain."
            +      ]
            +    },
            +    "disableFriendlyErrors": {
            +      "description": [
            +        "Turn off some features of the friendly error system (FES), which can give a significant boost to performance when needed.",
            +        "Note that this will disable the parts of the FES that cause performance slowdown (like argument checking). Friendly errors that have no performance cost (like giving an descriptive error if a file load fails, or warning you if you try to override p5.js functions in the global space), will remain in place.",
            +        "See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'> disabling the friendly error system</a>."
            +      ]
            +    },
            +    "let": {
            +      "description": [
            +        "Creates and names a new variable. A variable is a container for a value.",
            +        "Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope. This means that the variable only exists within the <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> block</a> that it is created within.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>: Declares a block scope local variable, optionally initializing it to a value."
            +      ]
            +    },
            +    "const": {
            +      "description": [
            +        "Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>, a constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value, however constants cannot be reassigned once they are declared. Although it is noteworthy that for non-primitive data types like objects & arrays, their elements can still be changeable. So if a variable is assigned an array, you can still add or remove elements from the array but cannot reassign another array to it. Also unlike <code>let</code>, you cannot declare variables without value using const.",
            +        "Constants have block-scope. This means that the constant only exists within the <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> block</a> that it is created within. A constant cannot be redeclared within a scope in which it already exists.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>: Declares a read-only named constant. Constants are block-scoped, much like variables defined using the 'let' statement. The value of a constant can't be changed through reassignment, and it can't be redeclared."
            +      ]
            +    },
            +    "===": {
            +      "description": [
            +        "The strict equality operator <a href=\"#/p5/===\">===</a> checks to see if two values are equal and of the same type.",
            +        "A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>: The non-identity operator returns true if the operands are not equal and/or not of the same type.",
            +        "Note: In some examples around the web you may see a double-equals-sign <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>, used for comparison instead. This is the non-strict equality operator in Javascript. This will convert the two values being compared to the same type before comparing them."
            +      ]
            +    },
            +    ">": {
            +      "description": [
            +        "The greater than operator <a href=\"#/p5/>\">></a> evaluates to true if the left value is greater than the right value. <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\"> There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    ">=": {
            +      "description": [
            +        "The greater than or equal to operator <a href=\"#/p5/>=\">>=</a> evaluates to true if the left value is greater than or equal to the right value.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "<": {
            +      "description": [
            +        "The less than operator <a href=\"#/p5/<\"><</a> evaluates to true if the left value is less than the right value.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "<=": {
            +      "description": [
            +        "The less than or equal to operator <a href=\"#/p5/<=\"><=</a> evaluates to true if the left value is less than or equal to the right value.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "if-else": {
            +      "description": [
            +        "The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.",
            +        "A condition is placed between the parenthesis following 'if', when that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>, the code between the following curly braces is run. Alternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>, the code between the curly braces of 'else' block is run instead. Writing an else block is optional.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>: The 'if' statement executes a statement if a specified condition is truthy. If the condition is falsy, another statement can be executed"
            +      ]
            +    },
            +    "function": {
            +      "description": [
            +        "Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>. A <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.",
            +        "Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a> are variables that are scoped to the function, that can be assigned a value when calling the function.Multiple parameters can be given by seperating them with commmas.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>: Declares a function with the specified parameters."
            +      ]
            +    },
            +    "return": {
            +      "description": [
            +        "Specifies the value to be returned by a function. For more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\"> the MDN entry for return</a>."
            +      ]
            +    },
            +    "boolean": {
            +      "description": [
            +        "Converts a number or string to its boolean representation. For a number, any non-zero value (positive or negative) evaluates to true, while zero evaluates to false. For a string, the value \"true\" evaluates to true, while any other value evaluates to false. When an array of number or string values is passed in, then a array of booleans of the same length is returned."
            +      ],
            +      "returns": "Boolean: boolean representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number|Array: value to parse"
            +      }
            +    },
            +    "string": {
            +      "description": [
            +        "A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript. A string is a series of text characters. In Javascript, a string value must be surrounded by either single-quotation marks(') or double-quotation marks(\").",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>: A string is a sequence of characters used to represent text."
            +      ]
            +    },
            +    "number": {
            +      "description": [
            +        "A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript. A number can be a whole number or a decimal number.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a>"
            +      ]
            +    },
            +    "object": {
            +      "description": [
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:  An <a href=\"#/p5/object\">object</a> is a collection of related data and/or  functionality (which usually consists of several variables and functions —  which are called properties and methods when they are inside objects.)"
            +      ]
            +    },
            +    "class": {
            +      "description": [
            +        "Creates and names a <a href=\"#/p5/class\">class</a> which is a template for the creation of <a href=\"#/p5/object\">objects</a>.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>: The class declaration creates a new Class with a given name using prototype-based inheritance."
            +      ]
            +    },
            +    "for": {
            +      "description": [
            +        "<a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one section of code multiple times.",
            +        "A 'for loop' consists of three different expressions inside of a parenthesis, all of which are optional.These expressions are used to control the number of times the loop is run.The first expression is a statement that is used to set the initial state for the loop.The second expression is a condition that you would like to check before each loop. If this expression returns false then the loop will exit.The third expression is executed at the end of each loop. These expression are separated by ; (semi-colon).In case of an empty expression, only a semi-colon is written.",
            +        "The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second and third expression.",
            +        "As with any loop, it is important to ensure that the loop can 'exit', or that the test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop is the second expression detailed above. Ensuring that this expression can eventually become false ensures that your loop doesn't attempt to run an infinite amount of times, which can crash your browser.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>: Creates a loop that executes a specified statement until the test condition evaluates to false. The condition is evaluated after executing the statement, resulting in the specified statement executing at least once."
            +      ]
            +    },
            +    "while": {
            +      "description": [
            +        "<a href=\"#/p5/while\">while</a> creates a loop that is useful for executing one section of code multiple times.",
            +        "With a 'while loop', the code inside of the loop body (between the curly braces) is run repeatedly until the test condition (inside of the parenthesis) evaluates to false. The condition is tested before executing the code body with <a href=\"#/p5/while\">while</a>, so if the condition is initially false the loop body, or statement, will never execute.",
            +        "As with any loop, it is important to ensure that the loop can 'exit', or that the test condition will eventually evaluate to false. This is to keep your loop from trying to run an infinite amount of times, which can crash your browser.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>: The while statement creates a loop that executes a specified statement as long as the test condition evaluates to true.The condition is evaluated before executing the statement."
            +      ]
            +    },
            +    "createCanvas": {
            +      "description": [
            +        "Creates a canvas element in the document, and sets the dimensions of it in pixels. This method should be called only once at the start of setup. Calling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a sketch will result in very unpredictable behavior. If you want more than one drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a> (hidden by default but it can be shown).",
            +        "Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0) is positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code> is set to <code>WEBGL</code>), the origin is positioned at the center of the canvas. See <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.",
            +        "The system variables width and height are set by the parameters passed to this function. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the window will be given a default size of 100×100 pixels.",
            +        "For more ways to position the canvas, see the <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'> positioning the canvas</a> wiki page."
            +      ],
            +      "returns": "p5.Renderer:",
            +      "params": {
            +        "w": "Number: width of the canvas",
            +        "h": "Number: height of the canvas",
            +        "renderer": "Constant: (Optional) either P2D or WEBGL"
            +      }
            +    },
            +    "resizeCanvas": {
            +      "description": [
            +        "Resizes the canvas to given width and height. The canvas will be cleared and draw will be called immediately, allowing the sketch to re-render itself in the resized canvas."
            +      ],
            +      "params": {
            +        "w": "Number: width of the canvas",
            +        "h": "Number: height of the canvas",
            +        "noRedraw": "Boolean: (Optional) don't redraw the canvas immediately"
            +      }
            +    },
            +    "noCanvas": {
            +      "description": [
            +        "Removes the default canvas for a p5 sketch that doesn't require a canvas"
            +      ]
            +    },
            +    "createGraphics": {
            +      "description": [
            +        "Creates and returns a new p5.Renderer object. Use this class if you need to draw into an off-screen graphics buffer. The two parameters define the width and height in pixels."
            +      ],
            +      "returns": "p5.Graphics: offscreen graphics buffer",
            +      "params": {
            +        "w": "Number: width of the offscreen graphics buffer",
            +        "h": "Number: height of the offscreen graphics buffer",
            +        "renderer": "Constant: (Optional) either P2D or WEBGL  undefined defaults to p2d"
            +      }
            +    },
            +    "blendMode": {
            +      "description": [
            +        "Blends the pixels in the display window according to the defined mode. There is a choice of the following modes to blend the source pixels (A) with the ones of pixels already in the display window (B): <ul> <li><code>BLEND</code> - linear interpolation of colours: C = A*factor + B. <b>This is the default blending mode.</b></li> <li><code>ADD</code> - sum of A and B</li> <li><code>DARKEST</code> - only the darkest colour succeeds: C = min(A*factor, B).</li> <li><code>LIGHTEST</code> - only the lightest colour succeeds: C = max(A*factor, B).</li> <li><code>DIFFERENCE</code> - subtract colors from underlying image.</li> <li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less extreme.</li> <li><code>MULTIPLY</code> - multiply the colors, result will always be darker.</li> <li><code>SCREEN</code> - opposite multiply, uses inverse values of the colors.</li> <li><code>REPLACE</code> - the pixels entirely replace the others and don't utilize alpha (transparency) values.</li> <li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li> <li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN </code>. Multiplies dark values, and screens light values. <em>(2D)</em></li> <li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50% gray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li> <li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and <code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em> </li> <li><code>DODGE</code> - lightens light tones and increases contrast, ignores darks. <em>(2D)</em></li> <li><code>BURN</code> - darker areas are applied, increasing contrast, ignores lights. <em>(2D)</em></li> <li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li> </ul>",
            +        "<em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer. <em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer."
            +      ],
            +      "params": {
            +        "mode": "Constant: blend mode to set for canvas.  either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,  EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT"
            +      }
            +    },
            +    "drawingContext": {
            +      "description": [
            +        "The p5.js API provides a lot of functionality for creating graphics, but there is some native HTML5 Canvas functionality that is not exposed by p5. You can still call it directly using the variable <code>drawingContext</code>, as in the example shown. This is the equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>. See this <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\"> reference for the native canvas API</a> for possible drawing functions you can call."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>. If <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a> begins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a> in <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.",
            +        "When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate or access the screen inside event handling functions such as <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to call <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>, which will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen properly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been called, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a> or <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.",
            +        "Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will be called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a> has been specified. Otherwise, the sketch would enter an odd state until <a href=\"#/p5/loop\">loop()</a> was called.",
            +        "Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop()."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "By default, p5.js loops through draw() continuously, executing the code within it. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling <a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a> loop can be resumed with loop().",
            +        "Avoid calling loop() from inside setup().",
            +        "Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop()."
            +      ]
            +    },
            +    "isLooping": {
            +      "description": [
            +        "By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously, executing the code within it. If the sketch is stopped with <a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>, isLooping() returns the current state for use within custom event handlers."
            +      ]
            +    },
            +    "push": {
            +      "description": [
            +        "The <a href=\"#/p5/push\">push()</a> function saves the current drawing style settings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these settings. Note that these functions are always used together. They allow you to change the style and transformation settings and later return to what you had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on the current style and transform information. The <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more control. (See the second example for a demonstration.)",
            +        "<a href=\"#/p5/push\">push()</a> stores information related to the current transformation state and style settings controlled by the following functions: <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"#/p5/strokeCap\">strokeCap()</a>, <a href=\"#/p5/strokeJoin\">strokeJoin()</a>, <a href=\"#/p5/imageMode\">imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href=\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5/textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/noiseSeed\">noiseSeed()</a>.",
            +        "In WEBGL mode additional style settings are stored. These are controlled by the following functions: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ambientLight\">ambientLight()</a>, <a href=\"#/p5/directionalLight\">directionalLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">shininess()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> and <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "pop": {
            +      "description": [
            +        "The <a href=\"#/p5/push\">push()</a> function saves the current drawing style settings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these settings. Note that these functions are always used together. They allow you to change the style and transformation settings and later return to what you had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on the current style and transform information. The <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more control. (See the second example for a demonstration.)",
            +        "<a href=\"#/p5/push\">push()</a> stores information related to the current transformation state and style settings controlled by the following functions: <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"#/p5/strokeCap\">strokeCap()</a>, <a href=\"#/p5/strokeJoin\">strokeJoin()</a>, <a href=\"#/p5/imageMode\">imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href=\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5/textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/noiseSeed\">noiseSeed()</a>.",
            +        "In WEBGL mode additional style settings are stored. These are controlled by the following functions: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ambientLight\">ambientLight()</a>, <a href=\"#/p5/directionalLight\">directionalLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">shininess()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> and <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "redraw": {
            +      "description": [
            +        "Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This function allows the program to update the display window only when necessary, for example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.",
            +        "In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a> within events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This is because <a href=\"#/p5/redraw\">redraw()</a> does not run <a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates an update is needed).",
            +        "The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when called inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations, use <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.",
            +        "In addition you can set the number of redraws per method call. Just add an integer as single parameter for the number of redraws."
            +      ],
            +      "params": {
            +        "n": "Integer: (Optional) Redraw for n-times. The default value is 1."
            +      }
            +    },
            +    "p5": {
            +      "description": [
            +        "The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal \"global mode\". This is an advanced topic. A short description and example is included below. Please see <a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\"> Dan Shiffman's Coding Train video tutorial</a> or this <a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a> for more info.",
            +        "By default, all p5.js functions are in the global namespace (i.e. bound to the window object), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this might be inconvenient if you are mixing with other JS libraries (synchronously or asynchronously) or writing long programs of your own. p5.js currently supports a way around this problem called \"instance mode\". In instance mode, all p5 functions are bound up in a single variable instead of polluting your global namespace.",
            +        "Optionally, you can specify a default container for the canvas and any other elements to append to with a second argument. You can give the ID of an element in your html, or an html node itself.",
            +        "Note that creating instances like this also allows you to have more than one p5 sketch on a single web page, as they will each be wrapped up with their own set up variables. Of course, you could also use iframes to have multiple sketches in global mode."
            +      ],
            +      "params": {
            +        "sketch": "Object: a function containing a p5.js sketch",
            +        "node": "String|Object: ID or pointer to HTML DOM node to contain sketch in"
            +      }
            +    },
            +    "applyMatrix": {
            +      "description": [
            +        "Multiplies the current matrix by the one specified through the parameters. This is a powerful operation that can perform the equivalent of translate, scale, shear and rotate all at once. You can learn more about transformation matrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\"> Wikipedia</a>.",
            +        "The naming of the arguments here follows the naming of the <a href= \"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\"> WHATWG specification</a> and corresponds to a transformation matrix of the form: <blockquote>",
            +        "<img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\" alt=\"The transformation matrix used when applyMatrix is called\"/> </blockquote>"
            +      ],
            +      "params": {
            +        "a": "Number|Array: numbers which define the 2×3 matrix to be multiplied, or an array of numbers",
            +        "b": "Number: numbers which define the 2×3 matrix to be multiplied",
            +        "c": "Number: numbers which define the 2×3 matrix to be multiplied",
            +        "d": "Number: numbers which define the 2×3 matrix to be multiplied",
            +        "e": "Number: numbers which define the 2×3 matrix to be multiplied",
            +        "f": "Number: numbers which define the 2×3 matrix to be multiplied"
            +      }
            +    },
            +    "resetMatrix": {
            +      "description": [
            +        "Replaces the current matrix with the identity matrix."
            +      ]
            +    },
            +    "rotate": {
            +      "description": [
            +        "Rotates a shape by the amount specified by the angle parameter. This function accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles can be entered in either RADIANS or DEGREES.",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling rotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI). All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.",
            +        "Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation, specified in radians  or degrees, depending on current angleMode",
            +        "axis": "p5.Vector|Number[]: (Optional) (in 3d) the axis to rotate around"
            +      }
            +    },
            +    "rotateX": {
            +      "description": [
            +        "Rotates a shape around X axis by the amount specified in angle parameter. The angles can be entered in either RADIANS or DEGREES.",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation, specified in radians  or degrees, depending on current angleMode"
            +      }
            +    },
            +    "rotateY": {
            +      "description": [
            +        "Rotates a shape around Y axis by the amount specified in angle parameter. The angles can be entered in either RADIANS or DEGREES.",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation, specified in radians  or degrees, depending on current angleMode"
            +      }
            +    },
            +    "rotateZ": {
            +      "description": [
            +        "Rotates a shape around Z axis by the amount specified in angle parameter. The angles can be entered in either RADIANS or DEGREES.",
            +        "This method works in WEBGL mode only.",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation, specified in radians  or degrees, depending on current angleMode"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Increases or decreases the size of a shape by expanding or contracting vertices. Objects always scale from their relative origin to the coordinate system. Scale values are specified as decimal percentages. For example, the function call scale(2.0) increases the dimension of a shape by 200%.",
            +        "Transformations apply to everything that happens after and subsequent calls to the function multiply the effect. For example, calling scale(2.0) and then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.",
            +        "Using this function with the z parameter is only available in WEBGL mode. This function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "s": "Number|p5.Vector|Number[]: percent to scale the object, or percentage to  scale the object in the x-axis if multiple arguments  are given",
            +        "y": "Number: (Optional) percent to scale the object in the y-axis",
            +        "z": "Number: (Optional) percent to scale the object in the z-axis (webgl only)",
            +        "scales": "p5.Vector|Number[]: per-axis percents to scale the object"
            +      }
            +    },
            +    "shearX": {
            +      "description": [
            +        "Shears a shape around the x-axis by the amount specified by the angle parameter. Angles should be specified in the current angleMode. Objects are always sheared around their relative position to the origin and positive numbers shear objects in a clockwise direction.",
            +        "Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling shearX(PI/2) and then shearX(PI/2) is the same as shearX(PI). If <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.",
            +        "Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions."
            +      ],
            +      "params": {
            +        "angle": "Number: angle of shear specified in radians or degrees,  depending on current angleMode"
            +      }
            +    },
            +    "shearY": {
            +      "description": [
            +        "Shears a shape around the y-axis the amount specified by the angle parameter. Angles should be specified in the current angleMode. Objects are always sheared around their relative position to the origin and positive numbers shear objects in a clockwise direction.",
            +        "Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling shearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If <a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.",
            +        "Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions."
            +      ],
            +      "params": {
            +        "angle": "Number: angle of shear specified in radians or degrees,  depending on current angleMode"
            +      }
            +    },
            +    "translate": {
            +      "description": [
            +        "Specifies an amount to displace objects within the display window. The x parameter specifies left/right translation, the y parameter specifies up/down translation.",
            +        "Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling translate(50, 0) and then translate(20, 0) is the same as translate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again. This function can be further controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "x": "Number: left/right translation",
            +        "y": "Number: up/down translation",
            +        "z": "Number: (Optional) forward/backward translation (webgl only)",
            +        "vector": "p5.Vector: the vector to translate by"
            +      }
            +    },
            +    "storeItem": {
            +      "description": [
            +        "Stores a value in local storage under the key name.  Local storage is saved in the browser and persists  between browsing sessions and page reloads.  The key can be the name of the variable but doesn't  have to be. To retrieve stored items  see <a href=\"#/p5/getItem\">getItem</a>. Sensitive data such as passwords or personal information  should not be stored in local storage."
            +      ],
            +      "params": {
            +        "key": "String",
            +        "value": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +      }
            +    },
            +    "getItem": {
            +      "description": [
            +        "Returns the value of an item that was stored in local storage  using storeItem()"
            +      ],
            +      "returns": "Number|Object|String|Boolean|p5.Color|p5.Vector: Value of stored item",
            +      "params": {
            +        "key": "String: name that you wish to use to store in local storage"
            +      }
            +    },
            +    "clearStorage": {
            +      "description": [
            +        "Clears all local storage items set with storeItem()  for the current domain."
            +      ]
            +    },
            +    "removeItem": {
            +      "description": [
            +        "Removes an item that was stored with storeItem()"
            +      ],
            +      "params": {
            +        "key": "String"
            +      }
            +    },
            +    "createStringDict": {
            +      "description": [
            +        "Creates a new instance of p5.StringDict using the key-value pair  or the object you provide."
            +      ],
            +      "returns": "p5.StringDict:",
            +      "params": {
            +        "key": "String",
            +        "value": "String",
            +        "object": "Object: object"
            +      }
            +    },
            +    "createNumberDict": {
            +      "description": [
            +        "Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair  or object you provide."
            +      ],
            +      "returns": "p5.NumberDict:",
            +      "params": {
            +        "key": "Number",
            +        "value": "Number",
            +        "object": "Object: object"
            +      }
            +    },
            +    "select": {
            +      "description": [
            +        "Searches the page for the first element that matches the given CSS selector string (can be an ID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>. The DOM node itself can be accessed with .elt. Returns null if none found. You can also specify a container to search within."
            +      ],
            +      "returns": "p5.Element|null: <a href=\"#/p5.Element\">p5.Element</a> containing node found",
            +      "params": {
            +        "selectors": "String: CSS selector string of element to search for",
            +        "container": "String|p5.Element|HTMLElement: (Optional) CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or  HTML element to search within"
            +      }
            +    },
            +    "selectAll": {
            +      "description": [
            +        "Searches the page for elements that match the given CSS selector string (can be an ID a class, tag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in an array. The DOM node itself can be accessed with .elt. Returns an empty array if none found. You can also specify a container to search within."
            +      ],
            +      "returns": "p5.Element[]: Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found",
            +      "params": {
            +        "selectors": "String: CSS selector string of elements to search for",
            +        "container": "String|p5.Element|HTMLElement: (Optional) CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>  , or HTML element to search within"
            +      }
            +    },
            +    "removeElements": {
            +      "description": [
            +        "Removes all elements created by p5, except any canvas / graphics elements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>. Event handlers are removed, and element is removed from the DOM."
            +      ]
            +    },
            +    "changed": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an element changes. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when the value of  an element changes.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "input": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is detected with an element. The input event is often used to detect keystrokes in a input element, or changes on a slider element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when any user input is  detected within the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "createDiv": {
            +      "description": [
            +        "Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createP": {
            +      "description": [
            +        "Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used for paragraph length text."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createSpan": {
            +      "description": [
            +        "Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createImg": {
            +      "description": [
            +        "Creates an <code>&lt;img&gt;</code> element in the DOM with given src and alternate text."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "src": "String: src path or url for image",
            +        "alt": "String: <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.",
            +        "crossOrigin": "String: <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used",
            +        "successCallback": "Function: (Optional) callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument"
            +      }
            +    },
            +    "createA": {
            +      "description": [
            +        "Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "href": "String: url of page to link to",
            +        "html": "String: inner html of link element to display",
            +        "target": "String: (Optional) target where new link should open,  could be _blank, _self, _parent, _top."
            +      }
            +    },
            +    "createSlider": {
            +      "description": [
            +        "Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM. Use .size() to set the display length of the slider."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "min": "Number: minimum value of the slider",
            +        "max": "Number: maximum value of the slider",
            +        "value": "Number: (Optional) default value of the slider",
            +        "step": "Number: (Optional) step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)"
            +      }
            +    },
            +    "createButton": {
            +      "description": [
            +        "Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM. Use .size() to set the display size of the button. Use .mousePressed() to specify behavior on press."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "label": "String: label displayed on the button",
            +        "value": "String: (Optional) value of the button"
            +      }
            +    },
            +    "createCheckbox": {
            +      "description": [
            +        "Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM. Calling .checked() on a checkbox returns if it is checked or not"
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "label": "String: (Optional) label displayed after checkbox",
            +        "value": "Boolean: (Optional) value of the checkbox; checked is true, unchecked is false"
            +      }
            +    },
            +    "createSelect": {
            +      "description": [
            +        "Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM. It also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box. <ul> <li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li> <li><code>.value()</code> will return the currently selected option.</li> <li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li> <li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li> <li><code>.disable()</code> marks whole of dropdown element as disabled.</li> <li><code>.disable(value)</code> marks given option as disabled</li> </ul>"
            +      ],
            +      "returns": "p5.Element:",
            +      "params": {
            +        "multiple": "Boolean: (Optional) true if dropdown should support multiple selections",
            +        "existing": "Object: DOM select element"
            +      }
            +    },
            +    "createRadio": {
            +      "description": [
            +        "Creates a radio button element in the DOM.It also helps existing radio buttons assign methods of <a href=\"#/p5.Element/\">p5.Element</a>. <ul> <li><code>.option(value, [label])</code> can be used to create a new option for the element. If an option with a value already exists, it will be returned. It is recommended to use string values as input for <code>value</code>. Optionally, a label can be provided as second argument for the option.</li> <li><code>.remove(value)</code> can be used to remove an option for the element. String values recommended as input for <code>value</code>.</li> <li><code>.value()</code> method will return the currently selected value.</li> <li><code>.selected()</code> method will return the currently selected input element.</li> <li><code>.selected(value)</code> method will select the option and return it. String values recommended as input for <code>value</code>.</li> <li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li> </ul>"
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "containerElement": "Object: An container HTML Element either a div or span inside which all existing radio inputs will be considered as options.",
            +        "name": "String: (Optional) A name parameter for each Input Element."
            +      }
            +    },
            +    "createColorPicker": {
            +      "description": [
            +        "Creates a colorPicker element in the DOM for color input. The .value() method will return a hex string (#rrggbb) of the color. The .color() method will return a p5.Color object with the current chosen color."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "value": "String|p5.Color: (Optional) default color of element"
            +      }
            +    },
            +    "createInput": {
            +      "description": [
            +        "Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input. Use .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "value": "String: default value of the input box",
            +        "type": "String: (Optional) type of text, ie text, password etc. Defaults to text.  Needs a value to be specified first."
            +      }
            +    },
            +    "createFileInput": {
            +      "description": [
            +        "Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'. This allows users to select local files for use in a sketch."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element",
            +      "params": {
            +        "callback": "Function: callback function for when a file is loaded",
            +        "multiple": "Boolean: (Optional) optional, to allow multiple files to be selected"
            +      }
            +    },
            +    "createVideo": {
            +      "description": [
            +        "Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback of audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a> and drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter can be either a single string path to a video file, or an array of string paths to different formats of the same video. This is useful for ensuring that your video can play across different browsers, as each supports different formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this page</a> for further information about supported formats."
            +      ],
            +      "returns": "p5.MediaElement: pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +      "params": {
            +        "src": "String|String[]: path to a video file, or array of paths for  supporting different browsers",
            +        "callback": "Function: (Optional) callback function to be called upon  'canplaythrough' event fire, that is, when the  browser can play the media, and estimates that  enough data has been loaded to play the media  up to its end without having to stop for  further buffering of content"
            +      }
            +    },
            +    "createAudio": {
            +      "description": [
            +        "Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio playback. The first parameter can be either a single string path to a audio file, or an array of string paths to different formats of the same audio. This is useful for ensuring that your audio can play across different browsers, as each supports different formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this page for further information about supported formats</a>."
            +      ],
            +      "returns": "p5.MediaElement: pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +      "params": {
            +        "src": "String|String[]: (Optional) path to an audio file, or array of paths  for supporting different browsers",
            +        "callback": "Function: (Optional) callback function to be called upon  'canplaythrough' event fire, that is, when the  browser can play the media, and estimates that  enough data has been loaded to play the media  up to its end without having to stop for  further buffering of content"
            +      }
            +    },
            +    "VIDEO": {},
            +    "AUDIO": {},
            +    "createCapture": {
            +      "description": [
            +        "Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed from a webcam. The element is separate from the canvas and is displayed by default. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>. The feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>. The loadedmetadata property can be used to detect when the element has fully loaded (see second example).",
            +        "More specific properties of the feed can be passing in a Constraints object. See the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'> W3C spec</a> for possible properties. Note that not all of these are supported by all browsers.",
            +        "<em>Security note</em>: A new browser security specification requires that getUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>, only works when you're running the code locally, or on HTTPS. Learn more <a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a> and <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>."
            +      ],
            +      "returns": "p5.Element: capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "type": "String|Constant|Object: type of capture, either VIDEO or  AUDIO if none specified, default both,  or a Constraints object",
            +        "callback": "Function: (Optional) function to be called once  stream has loaded"
            +      }
            +    },
            +    "createElement": {
            +      "description": [
            +        "Creates element with given tag in the DOM with given content."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "tag": "String: tag for the new element",
            +        "content": "String: (Optional) html content to be inserted into the element"
            +      }
            +    },
            +    "deviceOrientation": {
            +      "description": [
            +        "The system variable deviceOrientation always contains the orientation of the device. The value of this variable will either be set 'landscape' or 'portrait'. If no data is available it will be set to 'undefined'. either LANDSCAPE or PORTRAIT."
            +      ]
            +    },
            +    "accelerationX": {
            +      "description": [
            +        "The system variable accelerationX always contains the acceleration of the device along the x axis. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "accelerationY": {
            +      "description": [
            +        "The system variable accelerationY always contains the acceleration of the device along the y axis. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "accelerationZ": {
            +      "description": [
            +        "The system variable accelerationZ always contains the acceleration of the device along the z axis. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "pAccelerationX": {
            +      "description": [
            +        "The system variable pAccelerationX always contains the acceleration of the device along the x axis in the frame previous to the current frame. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "pAccelerationY": {
            +      "description": [
            +        "The system variable pAccelerationY always contains the acceleration of the device along the y axis in the frame previous to the current frame. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "pAccelerationZ": {
            +      "description": [
            +        "The system variable pAccelerationZ always contains the acceleration of the device along the z axis in the frame previous to the current frame. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "rotationX": {
            +      "description": [
            +        "The system variable rotationX always contains the rotation of the device along the x axis. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be -180 to 180. If it is set to RADIANS, the value will be -PI to PI.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "rotationY": {
            +      "description": [
            +        "The system variable rotationY always contains the rotation of the device along the y axis. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be -90 to 90. If it is set to RADIANS, the value will be -PI/2 to PI/2.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "rotationZ": {
            +      "description": [
            +        "The system variable rotationZ always contains the rotation of the device along the z axis. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be 0 to 360. If it is set to RADIANS, the value will be 0 to 2*PI.",
            +        "Unlike rotationX and rotationY, this variable is available for devices with a built-in compass only.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "pRotationX": {
            +      "description": [
            +        "The system variable pRotationX always contains the rotation of the device along the x axis in the frame previous to the current frame. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be -180 to 180. If it is set to RADIANS, the value will be -PI to PI.",
            +        "pRotationX can also be used with rotationX to determine the rotate direction of the device along the X-axis."
            +      ]
            +    },
            +    "pRotationY": {
            +      "description": [
            +        "The system variable pRotationY always contains the rotation of the device along the y axis in the frame previous to the current frame. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be -90 to 90. If it is set to RADIANS, the value will be -PI/2 to PI/2.",
            +        "pRotationY can also be used with rotationY to determine the rotate direction of the device along the Y-axis."
            +      ]
            +    },
            +    "pRotationZ": {
            +      "description": [
            +        "The system variable pRotationZ always contains the rotation of the device along the z axis in the frame previous to the current frame. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be 0 to 360. If it is set to RADIANS, the value will be 0 to 2*PI.",
            +        "pRotationZ can also be used with rotationZ to determine the rotate direction of the device along the Z-axis."
            +      ]
            +    },
            +    "turnAxis": {
            +      "description": [
            +        "When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis variable. The turnAxis variable is only defined within the scope of deviceTurned()."
            +      ]
            +    },
            +    "setMoveThreshold": {
            +      "description": [
            +        "The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for the <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5."
            +      ],
            +      "params": {
            +        "value": "Number: The threshold value"
            +      }
            +    },
            +    "setShakeThreshold": {
            +      "description": [
            +        "The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for the <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30."
            +      ],
            +      "params": {
            +        "value": "Number: The threshold value"
            +      }
            +    },
            +    "deviceMoved": {
            +      "description": [
            +        "The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than the threshold value along X, Y or Z axis. The default threshold is set to 0.5. The threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>."
            +      ]
            +    },
            +    "deviceTurned": {
            +      "description": [
            +        "The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by more than 90 degrees continuously.",
            +        "The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis variable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis: X, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'."
            +      ]
            +    },
            +    "deviceShaken": {
            +      "description": [
            +        "The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration changes of accelerationX and accelerationY values is more than the threshold value. The default threshold is set to 30. The threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>."
            +      ]
            +    },
            +    "keyIsPressed": {
            +      "description": [
            +        "The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed and false if no keys are pressed."
            +      ]
            +    },
            +    "key": {
            +      "description": [
            +        "The system variable key always contains the value of the most recent key on the keyboard that was typed. To get the proper capitalization, it is best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a> variable."
            +      ]
            +    },
            +    "keyCode": {
            +      "description": [
            +        "The variable keyCode is used to detect special keys such as BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. You can also check for custom keys by looking up the keyCode of any key on a site like this: <a href=\"http://keycode.info/\">keycode.info</a>."
            +      ]
            +    },
            +    "keyPressed": {
            +      "description": [
            +        "The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The keyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.",
            +        "For non-ASCII keys, use the keyCode variable. You can check if the keyCode equals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.",
            +        "For ASCII keys, the key that was pressed is stored in the key variable. However, it does not distinguish between uppercase and lowercase. For this reason, it is recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the case of the variable will be distinguished.",
            +        "Because of how operating systems handle key repeats, holding down a key may cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The rate of repeat is set by the operating system and how each computer is configured. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyReleased": {
            +      "description": [
            +        "The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released. See <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyTyped": {
            +      "description": [
            +        "The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but action keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect a keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead. The most recent key typed will be stored in the key variable.",
            +        "Because of how operating systems handle key repeats, holding down a key will cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The rate of repeat is set by the operating system and how each computer is configured. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyIsDown": {
            +      "description": [
            +        "The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed. It can be used if you have an object that moves, and you want several keys to be able to affect its behaviour simultaneously, such as moving a sprite diagonally. You can put in any number representing the keyCode of the key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed <a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>."
            +      ],
            +      "returns": "Boolean: whether key is down or not",
            +      "params": {
            +        "code": "Number: The key to check for."
            +      }
            +    },
            +    "movedX": {
            +      "description": [
            +        "The variable movedX contains the horizontal movement of the mouse since the last frame"
            +      ]
            +    },
            +    "movedY": {
            +      "description": [
            +        "The variable movedY contains the vertical movement of the mouse since the last frame"
            +      ]
            +    },
            +    "mouseX": {
            +      "description": [
            +        "The system variable mouseX always contains the current horizontal position of the mouse, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. If touch is used instead of mouse input, mouseX will hold the x value of the most recent touch point."
            +      ]
            +    },
            +    "mouseY": {
            +      "description": [
            +        "The system variable mouseY always contains the current vertical position of the mouse, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. If touch is used instead of mouse input, mouseY will hold the y value of the most recent touch point."
            +      ]
            +    },
            +    "pmouseX": {
            +      "description": [
            +        "The system variable pmouseX always contains the horizontal position of the mouse or finger in the frame previous to the current frame, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX value at the start of each touch event."
            +      ]
            +    },
            +    "pmouseY": {
            +      "description": [
            +        "The system variable pmouseY always contains the vertical position of the mouse or finger in the frame previous to the current frame, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY value at the start of each touch event."
            +      ]
            +    },
            +    "winMouseX": {
            +      "description": [
            +        "The system variable winMouseX always contains the current horizontal position of the mouse, relative to (0, 0) of the window."
            +      ]
            +    },
            +    "winMouseY": {
            +      "description": [
            +        "The system variable winMouseY always contains the current vertical position of the mouse, relative to (0, 0) of the window."
            +      ]
            +    },
            +    "pwinMouseX": {
            +      "description": [
            +        "The system variable pwinMouseX always contains the horizontal position of the mouse in the frame previous to the current frame, relative to (0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX value at the start of each touch event."
            +      ]
            +    },
            +    "pwinMouseY": {
            +      "description": [
            +        "The system variable pwinMouseY always contains the vertical position of the mouse in the frame previous to the current frame, relative to (0, 0) of the window. Note: pwinMouseY will be reset to the current winMouseY value at the start of each touch event."
            +      ]
            +    },
            +    "mouseButton": {
            +      "description": [
            +        "p5 automatically tracks if the mouse button is pressed and which button is pressed. The value of the system variable mouseButton is either LEFT, RIGHT, or CENTER depending on which button was pressed last. Warning: different browsers may track mouseButton differently."
            +      ]
            +    },
            +    "mouseIsPressed": {
            +      "description": [
            +        "The boolean system variable mouseIsPressed is true if the mouse is pressed and false if not."
            +      ]
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse button is not pressed. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseDragged": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and a mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the <a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button is pressed. The mouseButton variable (see the related reference entry) can be used to determine which button has been pressed. If no <a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is released. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been pressed and then released. Browsers handle clicks differently, so this function is only guaranteed to be run when the left mouse button is clicked. To handle other mouse buttons being pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event listener has detected a dblclick event which is a part of the DOM L3 specification. The doubleClicked event is fired when a pointing device button (usually a mouse's primary button) is clicked twice on a single element. For more info on the dblclick event refer to mozilla's documentation here: <a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a>"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel event is detected either triggered by an actual mouse wheel or by a touchpad. The event.delta property returns the amount the mouse wheel have scrolled. The values can be positive or negative depending on the scroll direction (on OS X with \"natural\" scrolling enabled, the signs are inverted). Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method. Due to the current support of the \"wheel\" event on Safari, the function may only work as expected if \"return false\" is included while using Safari."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional WheelEvent callback argument."
            +      }
            +    },
            +    "requestPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a> locks the pointer to its current position and makes it invisible. Use <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since the last call of draw. Note that not all browsers support this feature. This enables you to create experiences that aren't limited by the mouse moving out of the screen even if it is repeatedly moved into one direction. For example, a first person perspective experience."
            +      ]
            +    },
            +    "exitPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a> exits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a> for example to make ui elements usable etc"
            +      ]
            +    },
            +    "touches": {
            +      "description": [
            +        "The system variable touches[] contains an array of the positions of all current touch points, relative to (0, 0) of the canvas, and IDs identifying a unique touch as it moves. Each element in the array is an object with x, y, and id properties.",
            +        "The touches[] array is not supported on Safari and IE on touch-based desktops (laptops)."
            +      ]
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "The touchStarted() function is called once after every time a touch is registered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various touch events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered. If no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various touch events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no <a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various touch events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "createImage": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a fresh buffer of pixels to play with. Set the size of the buffer with the width and height parameters.",
            +        ".<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels in the display window. These values are numbers. This array is the size (including an appropriate factor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for more info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.",
            +        "Before accessing the pixels of an image, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes."
            +      ],
            +      "returns": "p5.Image: the <a href=\"#/p5.Image\">p5.Image</a> object",
            +      "params": {
            +        "width": "Integer: width in pixels",
            +        "height": "Integer: height in pixels"
            +      }
            +    },
            +    "saveCanvas": {
            +      "description": [
            +        "Save the current canvas as an image. The browser will either save the file immediately, or prompt the user with a dialogue window."
            +      ],
            +      "params": {
            +        "selectedCanvas": "p5.Element|HTMLCanvasElement: a variable  representing a specific html5 canvas (optional)",
            +        "filename": "String (Optional)",
            +        "extension": "String: (Optional) 'jpg' or 'png'"
            +      }
            +    },
            +    "saveFrames": {
            +      "description": [
            +        "Capture a sequence of frames that can be used to create a movie. Accepts a callback. For example, you may wish to send the frames to a server where they can be stored or converted into a movie. If no callback is provided, the browser will pop up save dialogues in an attempt to download all of the images that have just been created. With the callback provided the image data isn't saved by default but instead passed as an argument to the callback function as an array of objects, with the size of array equal to the total number of frames.",
            +        "Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation. To export longer animations, you might look into a library like <a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>."
            +      ],
            +      "params": {
            +        "filename": "String",
            +        "extension": "String: 'jpg' or 'png'",
            +        "duration": "Number: Duration in seconds to save the frames for.",
            +        "framerate": "Number: Framerate to save the frames in.",
            +        "callback": "Function(Array): (Optional) A callback function that will be executed  to handle the image data. This function  should accept an array as argument. The  array will contain the specified number of  frames of objects. Each object has three  properties: imageData - an  image/octet-stream, filename and extension."
            +      }
            +    },
            +    "loadImage": {
            +      "description": [
            +        "Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.",
            +        "The image may not be immediately available for rendering. If you want to ensure that the image is ready before doing anything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>. You may also supply a callback function to handle the image when it's ready.",
            +        "The path to the image should be relative to the HTML file that links in your sketch. Loading an image from a URL or other remote location may be blocked due to your browser's built-in security.",
            +        "You can also pass in a string of a base64 encoded image as an alternative to the file path. Remember to add \"data:image/png;base64,\" in front of the string."
            +      ],
            +      "returns": "p5.Image: the <a href=\"#/p5.Image\">p5.Image</a> object",
            +      "params": {
            +        "path": "String: Path of the image to be loaded",
            +        "successCallback": "function(p5.Image): (Optional) Function to be called once  the image is loaded. Will be passed the  <a href=\"#/p5.Image\">p5.Image</a>.",
            +        "failureCallback": "Function(Event): (Optional) called with event error if  the image fails to load."
            +      }
            +    },
            +    "image": {
            +      "description": [
            +        "Draw an image to the p5.js canvas.",
            +        "This function can be used with different numbers of parameters. The simplest use requires only three parameters: img, x, and y—where (x, y) is the position of the image. Two more parameters can optionally be added to specify the width and height of the image.",
            +        "This function can also be used with all eight Number parameters. To differentiate between all these parameters, p5.js uses the language of \"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source image\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the \"source image\" dimensions can be useful when you want to display a subsection of the source image instead of the whole thing. Here's a diagram to explain further: <img src=\"assets/drawImage.png\"></img>"
            +      ],
            +      "params": {
            +        "img": "p5.Image|p5.Element|p5.Texture: the image to display",
            +        "x": "Number: the x-coordinate of the top-left corner of the image",
            +        "y": "Number: the y-coordinate of the top-left corner of the image",
            +        "width": "Number: (Optional) the width to draw the image",
            +        "height": "Number: (Optional) the height to draw the image",
            +        "dx": "Number: the x-coordinate of the destination  rectangle in which to draw the source image",
            +        "dy": "Number: the y-coordinate of the destination  rectangle in which to draw the source image",
            +        "dWidth": "Number: the width of the destination rectangle",
            +        "dHeight": "Number: the height of the destination rectangle",
            +        "sx": "Number: the x-coordinate of the subsection of the source image to draw into the destination rectangle",
            +        "sy": "Number: the y-coordinate of the subsection of the source image to draw into the destination rectangle",
            +        "sWidth": "Number: (Optional) the width of the subsection of the  source image to draw into the destination  rectangle",
            +        "sHeight": "Number: (Optional) the height of the subsection of the  source image to draw into the destination rectangle"
            +      }
            +    },
            +    "tint": {
            +      "description": [
            +        "Sets the fill value for displaying images. Images can be tinted to specified colors or made transparent by including an alpha value.",
            +        "To apply transparency to an image without affecting its color, use white as the tint color and specify an alpha value. For instance, tint(255, 128) will make an image 50% transparent (assuming the default alpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).",
            +        "The value for the gray parameter must be less than or equal to the current maximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is 255."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "alpha": "Number (Optional)",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the tint color"
            +      }
            +    },
            +    "noTint": {
            +      "description": [
            +        "Removes the current fill value for displaying images and reverts to displaying images with their original hues."
            +      ]
            +    },
            +    "imageMode": {
            +      "description": [
            +        "Set image mode. Modifies the location from which images are drawn by changing the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted. The default mode is imageMode(CORNER), which interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If two additional parameters are specified, they are used to set the image's width and height.",
            +        "imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the location of one corner, and the fourth and fifth parameters as the opposite corner.",
            +        "imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the image's center point. If two additional parameters are specified, they are used to set the image's width and height."
            +      ],
            +      "params": {
            +        "mode": "Constant: either CORNER, CORNERS, or CENTER"
            +      }
            +    },
            +    "pixels": {
            +      "description": [
            +        "<a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a> containing the values for all the pixels in the display window. These values are numbers. This array is the size (include an appropriate factor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. Retina and other high density displays will have more pixels[] (by a factor of pixelDensity^2). For example, if the image is 100×100 pixels, there will be 40,000. On a retina display, there will be 160,000.",
            +        "The first four values (indices 0-3) in the array will be the R, G, B, A values of the pixel at (0, 0). The second four values (indices 4-7) will contain the R, G, B, A values of the pixel at (1, 0). More generally, to set values for a pixel at (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre>",
            +        "While the above method is complex, it is flexible enough to work with any pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of setting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at any pixelDensity, but the performance may not be as fast when lots of modifications are made to the pixel array.",
            +        "Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a> function must be run to update the changes.",
            +        "Note that this is not a standard javascript array. This means that standard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or <a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not work."
            +      ]
            +    },
            +    "blend": {
            +      "description": [
            +        "Copies a region of pixels from one image to another, using a specified blend mode to do the operation."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height",
            +        "blendMode": "Constant: the blend mode. either  BLEND, DARKEST, LIGHTEST, DIFFERENCE,  MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD or NORMAL."
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Copies a region of the canvas to another region of the canvas and copies a region of pixels from an image used as the srcImg parameter into the canvas srcImage is specified this is used as the source. If the source and destination regions aren't the same size, it will automatically resize source pixels to fit the specified target region."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5.Element: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Applies a filter to the canvas. The presets options are:",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used.",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used.",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used.",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges.",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur.",
            +        "ERODE Reduces the light areas. No parameter is used.",
            +        "DILATE Increases the light areas. No parameter is used.",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "Constant: either THRESHOLD, GRAY, OPAQUE, INVERT,  POSTERIZE, BLUR, ERODE, DILATE or BLUR.  See Filters.js for docs on  each available filter",
            +        "filterParam": "Number: (Optional) an optional parameter unique  to each filter, see above"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Get a region of pixels, or a single pixel, from the canvas.",
            +        "Returns an array of [R,G,B,A] values for any pixel or grabs a section of an image. If no parameters are specified, the entire image is returned. Use the x and y parameters to get the value of one pixel. Get a section of the display window by specifying additional w and h parameters. When getting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.",
            +        "Getting the color of a single pixel with get(x, y) is easy, but not as fast as grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to get(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is <pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates let off = (y * width + x) * d * 4; let components = [  pixels[off],  pixels[off + 1],  pixels[off + 2],  pixels[off + 3] ]; print(components);</code></pre>",
            +        "See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.",
            +        "If you want to extract an array of colors or a subimage from an p5.Image object, take a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a>"
            +      ],
            +      "returns": "p5.Image: the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "w": "Number: width",
            +        "h": "Number: height"
            +      }
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This function must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>. Note that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a> will occur."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Changes the color of any pixel, or writes an image directly to the display window. The x and y parameters specify the pixel to change and the c parameter specifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A] pixel array. It can also be a single grayscale value. When setting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.",
            +        "After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear. This should be called once all pixels have been set, and must be called before calling .<a href=\"#/p5/get\">get()</a> or drawing the image.",
            +        "Setting the color of a single pixel with set(x, y) is easy, but not as fast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a> values directly may be complicated when working with a retina display, but will perform better when lots of pixels need to be set directly on every loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "c": "Number|Number[]|Object: insert a grayscale value | a pixel array |  a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy"
            +      }
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array. Use in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from the array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only necessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the pixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with <a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur."
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) x-coordinate of the upper-left corner of region  to update",
            +        "y": "Number: (Optional) y-coordinate of the upper-left corner of region  to update",
            +        "w": "Number: (Optional) width of region to update",
            +        "h": "Number: (Optional) height of region to update"
            +      }
            +    },
            +    "loadJSON": {
            +      "description": [
            +        "Loads a JSON file from a file or a URL, and returns an Object. Note that even if the JSON file contains an Array, an Object will be returned with index numbers as keys.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. JSONP is supported via a polyfill and you can pass in as the second argument an object with definitions of the json callback following the syntax specified <a href=\"https://github.com/camsong/ fetch-jsonp\">here</a>.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object|Array: JSON data",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "jsonpOptions": "Object: (Optional) options object for jsonp related settings",
            +        "datatype": "String: (Optional) \"json\" or \"jsonp\"",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed  in as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadStrings": {
            +      "description": [
            +        "Reads the contents of a file and creates a String array of its individual lines. If the name of the file is used as the parameter, as in the above example, the file must be located in the sketch directory/folder.",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "String[]: Array of Strings",
            +      "params": {
            +        "filename": "String: name of the file or url to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>  completes, Array is passed in as first  argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadTable": {
            +      "description": [
            +        "Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with its values. If a file is specified, it must be located in the sketch's \"data\" folder. The filename parameter can also be a URL to a file found online. By default, the file is assumed to be comma-separated (in CSV format). Table only looks for a header row if the 'header' option is included.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called. Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object:",
            +        "All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: <a href=\"#/p5.Table\">Table</a> object containing data",
            +      "params": {
            +        "filename": "String: name of the file or URL to load",
            +        "extension": "String: (Optional) parse the table by comma-separated values \"csv\", semicolon-separated  values \"ssv\", or tab-separated values \"tsv\"",
            +        "header": "String: (Optional) \"header\" to indicate table has header row",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the  <a href=\"#/p5.Table\">Table</a> object is passed in as the  first argument.",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadXML": {
            +      "description": [
            +        "Reads the contents of a file and creates an XML object with its values. If the name of the file is used as the parameter, as in the above example, the file must be located in the sketch directory/folder.",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.",
            +        "Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: XML object containing data",
            +      "params": {
            +        "filename": "String: name of the file or URL to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>  completes, XML object is passed in as  first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadBytes": {
            +      "description": [
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: an object whose 'bytes' property will be the loaded buffer",
            +      "params": {
            +        "file": "String: name of the file or URL to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>  completes",
            +        "errorCallback": "Function: (Optional) function to be executed if there  is an error"
            +      }
            +    },
            +    "httpGet": {
            +      "description": [
            +        "Method for executing an HTTP GET request. If data type is not specified, p5 will try to guess based on the URL, defaulting to text. This is equivalent to calling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return a Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer which can be used to initialize typed arrays (such as Uint8Array)."
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "datatype": "String: (Optional) \"json\", \"jsonp\", \"binary\", \"arrayBuffer\",  \"xml\", or \"text\"",
            +        "data": "Object|Boolean: (Optional) param data passed sent with request",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in  as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "httpPost": {
            +      "description": [
            +        "Method for executing an HTTP POST request. If data type is not specified, p5 will try to guess based on the URL, defaulting to text. This is equivalent to calling <code>httpDo(path, 'POST')</code>."
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "datatype": "String: (Optional) \"json\", \"jsonp\", \"xml\", or \"text\".  If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.",
            +        "data": "Object|Boolean: (Optional) param data passed sent with request",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in  as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "httpDo": {
            +      "description": [
            +        "Method for executing an HTTP request. If data type is not specified, p5 will try to guess based on the URL, defaulting to text. For more advanced use, you may also pass in the path as the first argument and a object as the second argument, the signature follows the one specified in the Fetch API specification. This method is suitable for fetching files up to size of 64MB when \"GET\" is used."
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "method": "String: (Optional) either \"GET\", \"POST\", or \"PUT\",  defaults to \"GET\"",
            +        "datatype": "String: (Optional) \"json\", \"jsonp\", \"xml\", or \"text\"",
            +        "data": "Object: (Optional) param data passed sent with request",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in  as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument",
            +        "options": "Object: Request object options as documented in the  \"fetch\" API <a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a>"
            +      }
            +    },
            +    "createWriter": {
            +      "returns": "p5.PrintWriter:",
            +      "params": {
            +        "name": "String: name of the file to be created",
            +        "extension": "String (Optional)"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "Saves a given element(image, text, json, csv, wav, or html) to the client's computer. The first parameter can be a pointer to element we want to save. The element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of Strings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table </a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires p5.sound). The second parameter is a filename (including extension).The third parameter is for options specific to this type of object. This method will save a file that fits the given parameters. If it is called without specifying an element, by default it will save the whole canvas as an image file. You can optionally specify a filename as the first parameter in such a case. <strong>Note that it is not recommended to call this method within draw, as it will open a new save dialog on every render.</strong>"
            +      ],
            +      "params": {
            +        "objectOrFilename": "Object|String: (Optional) If filename is provided, will  save canvas as an image with  either png or jpg extension  depending on the filename.  If object is provided, will  save depending on the object  and filename (see examples  above).",
            +        "filename": "String: (Optional) If an object is provided as the first  parameter, then the second parameter  indicates the filename,  and should include an appropriate  file extension (see examples above).",
            +        "options": "Boolean|String: (Optional) Additional options depend on  filetype. For example, when saving JSON,  <code>true</code> indicates that the  output will be optimized for filesize,  rather than readability."
            +      }
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "Writes the contents of an Array or a JSON object to a .json file. The file saving process and location of the saved file will vary between web browsers."
            +      ],
            +      "params": {
            +        "json": "Array|Object",
            +        "filename": "String",
            +        "optimize": "Boolean: (Optional) If true, removes line breaks  and spaces from the output  file to optimize filesize  (but not readability)."
            +      }
            +    },
            +    "saveStrings": {
            +      "description": [
            +        "Writes an array of Strings to a text file, one line per String. The file saving process and location of the saved file will vary between web browsers."
            +      ],
            +      "params": {
            +        "list": "String[]: string array to be written",
            +        "filename": "String: filename for output",
            +        "extension": "String: (Optional) the filename's extension",
            +        "isCRLF": "Boolean: (Optional) if true, change line-break to CRLF"
            +      }
            +    },
            +    "saveTable": {
            +      "description": [
            +        "Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a text file with comma-separated-values ('csv') but can also use tab separation ('tsv'), or generate an HTML table ('html'). The file saving process and location of the saved file will vary between web browsers."
            +      ],
            +      "params": {
            +        "Table": "p5.Table: the <a href=\"#/p5.Table\">Table</a> object to save to a file",
            +        "filename": "String: the filename to which the Table should be saved",
            +        "options": "String: (Optional) can be one of \"tsv\", \"csv\", or \"html\""
            +      }
            +    },
            +    "abs": {
            +      "description": [
            +        "Calculates the absolute value (magnitude) of a number. Maps to Math.abs(). The absolute value of a number is always positive."
            +      ],
            +      "returns": "Number: absolute value of given number",
            +      "params": {
            +        "n": "Number: number to compute"
            +      }
            +    },
            +    "ceil": {
            +      "description": [
            +        "Calculates the closest int value that is greater than or equal to the value of the parameter. Maps to Math.ceil(). For example, ceil(9.03) returns the value 10."
            +      ],
            +      "returns": "Integer: rounded up number",
            +      "params": {
            +        "n": "Number: number to round up"
            +      }
            +    },
            +    "constrain": {
            +      "description": [
            +        "Constrains a value between a minimum and maximum value."
            +      ],
            +      "returns": "Number: constrained number",
            +      "params": {
            +        "n": "Number: number to constrain",
            +        "low": "Number: minimum limit",
            +        "high": "Number: maximum limit"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "Calculates the distance between two points, in either two or three dimensions. If you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a>"
            +      ],
            +      "returns": "Number: distance between the two points",
            +      "params": {
            +        "x1": "Number: x-coordinate of the first point",
            +        "y1": "Number: y-coordinate of the first point",
            +        "x2": "Number: x-coordinate of the second point",
            +        "y2": "Number: y-coordinate of the second point",
            +        "z1": "Number: z-coordinate of the first point",
            +        "z2": "Number: z-coordinate of the second point"
            +      }
            +    },
            +    "exp": {
            +      "description": [
            +        "Returns Euler's number e (2.71828...) raised to the power of the n parameter. Maps to Math.exp()."
            +      ],
            +      "returns": "Number: e^n",
            +      "params": {
            +        "n": "Number: exponent to raise"
            +      }
            +    },
            +    "floor": {
            +      "description": [
            +        "Calculates the closest int value that is less than or equal to the value of the parameter. Maps to Math.floor()."
            +      ],
            +      "returns": "Integer: rounded down number",
            +      "params": {
            +        "n": "Number: number to round down"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "Calculates a number between two numbers at a specific increment. The amt parameter is the amount to interpolate between the two values where 0.0 equal to the first point, 0.1 is very near the first point, 0.5 is half-way in between, and 1.0 is equal to the second point. If the value of amt is more than 1.0 or less than 0.0, the number will be calculated accordingly in the ratio of the two given numbers. The lerp function is convenient for creating motion along a straight path and for drawing dotted lines."
            +      ],
            +      "returns": "Number: lerped value",
            +      "params": {
            +        "start": "Number: first value",
            +        "stop": "Number: second value",
            +        "amt": "Number: number"
            +      }
            +    },
            +    "log": {
            +      "description": [
            +        "Calculates the natural logarithm (the base-e logarithm) of a number. This function expects the n parameter to be a value greater than 0.0. Maps to Math.log()."
            +      ],
            +      "returns": "Number: natural logarithm of n",
            +      "params": {
            +        "n": "Number: number greater than 0"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "Calculates the magnitude (or length) of a vector. A vector is a direction in space commonly used in computer graphics and linear algebra. Because it has no \"start\" position, the magnitude of a vector can be thought of as the distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is a shortcut for writing dist(0, 0, x, y)."
            +      ],
            +      "returns": "Number: magnitude of vector from (0,0) to (a,b)",
            +      "params": {
            +        "a": "Number: first value",
            +        "b": "Number: second value"
            +      }
            +    },
            +    "map": {
            +      "description": [
            +        "Re-maps a number from one range to another.",
            +        "In the first example above, the number 25 is converted from a value in the range of 0 to 100 into a value that ranges from the left edge of the window (0) to the right edge (width)."
            +      ],
            +      "returns": "Number: remapped number",
            +      "params": {
            +        "value": "Number: the incoming value to be converted",
            +        "start1": "Number: lower bound of the value's current range",
            +        "stop1": "Number: upper bound of the value's current range",
            +        "start2": "Number: lower bound of the value's target range",
            +        "stop2": "Number: upper bound of the value's target range",
            +        "withinBounds": "Boolean: (Optional) constrain the value to the newly mapped range"
            +      }
            +    },
            +    "max": {
            +      "description": [
            +        "Determines the largest value in a sequence of numbers, and then returns that value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array of any length."
            +      ],
            +      "returns": "Number: maximum Number",
            +      "params": {
            +        "n0": "Number: Number to compare",
            +        "n1": "Number: Number to compare",
            +        "nums": "Number[]: Numbers to compare"
            +      }
            +    },
            +    "min": {
            +      "description": [
            +        "Determines the smallest value in a sequence of numbers, and then returns that value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array of any length."
            +      ],
            +      "returns": "Number: minimum Number",
            +      "params": {
            +        "n0": "Number: Number to compare",
            +        "n1": "Number: Number to compare",
            +        "nums": "Number[]: Numbers to compare"
            +      }
            +    },
            +    "norm": {
            +      "description": [
            +        "Normalizes a number from another range into a value between 0 and 1. Identical to map(value, low, high, 0, 1). Numbers outside of the range are not clamped to 0 and 1, because out-of-range values are often intentional and useful. (See the example above.)"
            +      ],
            +      "returns": "Number: normalized number",
            +      "params": {
            +        "value": "Number: incoming value to be normalized",
            +        "start": "Number: lower bound of the value's current range",
            +        "stop": "Number: upper bound of the value's current range"
            +      }
            +    },
            +    "pow": {
            +      "description": [
            +        "Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient way of multiplying numbers by themselves (or their reciprocals) in large quantities. For example, pow(3, 5) is equivalent to the expression 3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 / 3 × 3 × 3 × 3 × 3. Maps to Math.pow()."
            +      ],
            +      "returns": "Number: n^e",
            +      "params": {
            +        "n": "Number: base of the exponential expression",
            +        "e": "Number: power by which to raise the base"
            +      }
            +    },
            +    "round": {
            +      "description": [
            +        "Calculates the integer closest to the n parameter. For example, round(133.8) returns the value 134. Maps to Math.round()."
            +      ],
            +      "returns": "Integer: rounded number",
            +      "params": {
            +        "n": "Number: number to round",
            +        "decimals": "Number: (Optional) number of decimal places to round to, default is 0"
            +      }
            +    },
            +    "sq": {
            +      "description": [
            +        "Squares a number (multiplies a number by itself). The result is always a positive number, as multiplying two negative numbers always yields a positive result. For example, -1 * -1 = 1."
            +      ],
            +      "returns": "Number: squared number",
            +      "params": {
            +        "n": "Number: number to square"
            +      }
            +    },
            +    "sqrt": {
            +      "description": [
            +        "Calculates the square root of a number. The square root of a number is always positive, even though there may be a valid negative root. The square root s of number a is such that s*s = a. It is the opposite of squaring. Maps to Math.sqrt()."
            +      ],
            +      "returns": "Number: square root of number",
            +      "params": {
            +        "n": "Number: non-negative number to square root"
            +      }
            +    },
            +    "fract": {
            +      "description": [
            +        "Calculates the fractional part of a number."
            +      ],
            +      "returns": "Number: fractional part of x, i.e, {x}",
            +      "params": {
            +        "num": "Number: Number whose fractional part needs to be found out"
            +      }
            +    },
            +    "createVector": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector. A vector is an entity that has both magnitude and direction."
            +      ],
            +      "returns": "p5.Vector:",
            +      "params": {
            +        "x": "Number: (Optional) x component of the vector",
            +        "y": "Number: (Optional) y component of the vector",
            +        "z": "Number: (Optional) z component of the vector"
            +      }
            +    },
            +    "noise": {
            +      "description": [
            +        "Returns the Perlin noise value at specified coordinates. Perlin noise is a random sequence generator producing a more naturally ordered, harmonic succession of numbers compared to the standard <b>random()</b> function. It was invented by Ken Perlin in the 1980s and been used since in graphical applications to produce procedural textures, natural motion, shapes, terrains etc.<br /><br /> The main difference to the <b>random()</b> function is that Perlin noise is defined in an infinite n-dimensional space where each pair of coordinates corresponds to a fixed semi-random value (fixed only for the lifespan of the program; see the <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise, depending on the number of coordinates given. The resulting value will always be between 0.0 and 1.0. The noise value can be animated by moving through the noise space as demonstrated in the example above. The 2nd and 3rd dimension can also be interpreted as time.<br /><br />The actual noise is structured similar to an audio signal, in respect to the function's use of frequencies. Similar to the concept of harmonics in physics, perlin noise is computed over several octaves which are added together for the final result. <br /><br />Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the function works within an infinite space the value of the coordinates doesn't matter as such, only the distance between successive coordinates does (eg. when using <b>noise()</b> within a loop). As a general rule the smaller the difference between coordinates, the smoother the resulting noise sequence will be. Steps of 0.005-0.03 work best for most applications, but this will differ depending on use."
            +      ],
            +      "returns": "Number: Perlin noise value (between 0 and 1) at specified  coordinates",
            +      "params": {
            +        "x": "Number: x-coordinate in noise space",
            +        "y": "Number: (Optional) y-coordinate in noise space",
            +        "z": "Number: (Optional) z-coordinate in noise space"
            +      }
            +    },
            +    "noiseDetail": {
            +      "description": [
            +        "Adjusts the character and level of detail produced by the Perlin noise  function. Similar to harmonics in physics, noise is computed over  several octaves. Lower octaves contribute more to the output signal and  as such define the overall intensity of the noise, whereas higher octaves  create finer grained details in the noise sequence. By default, noise is computed over 4 octaves with each octave contributing  exactly half than its predecessor, starting at 50% strength for the 1st  octave. This falloff amount can be changed by adding an additional function  parameter. Eg. a falloff factor of 0.75 means each octave will now have  75% impact (25% less) of the previous lower octave. Any value between  0.0 and 1.0 is valid, however note that values greater than 0.5 might  result in greater than 1.0 values returned by <b>noise()</b>. By changing these parameters, the signal created by the <b>noise()</b>  function can be adapted to fit very specific needs and characteristics."
            +      ],
            +      "params": {
            +        "lod": "Number: number of octaves to be used by the noise",
            +        "falloff": "Number: falloff factor for each octave"
            +      }
            +    },
            +    "noiseSeed": {
            +      "description": [
            +        "Sets the seed value for <b>noise()</b>. By default, <b>noise()</b> produces different results each time the program is run. Set the <b>value</b> parameter to a constant to return the same pseudo-random numbers each time the software is run."
            +      ],
            +      "params": {
            +        "seed": "Number: the seed value"
            +      }
            +    },
            +    "randomSeed": {
            +      "description": [
            +        "Sets the seed value for <a href=\"#/p5/random\">random()</a>.",
            +        "By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program is run. Set the seed parameter to a constant to return the same pseudo-random numbers each time the software is run."
            +      ],
            +      "params": {
            +        "seed": "Number: the seed value"
            +      }
            +    },
            +    "random": {
            +      "description": [
            +        "Return a random floating-point number.",
            +        "Takes either 0, 1 or 2 arguments.",
            +        "If no argument is given, returns a random number from 0 up to (but not including) 1.",
            +        "If one argument is given and it is a number, returns a random number from 0 up to (but not including) the number.",
            +        "If one argument is given and it is an array, returns a random element from that array.",
            +        "If two arguments are given, returns a random number from the first argument up to (but not including) the second argument."
            +      ],
            +      "returns": "Number: the random number",
            +      "params": {
            +        "min": "Number: (Optional) the lower bound (inclusive)",
            +        "max": "Number: (Optional) the upper bound (exclusive)",
            +        "choices": "Array: the array to choose from"
            +      }
            +    },
            +    "randomGaussian": {
            +      "description": [
            +        "Returns a random number fitting a Gaussian, or  normal, distribution. There is theoretically no minimum or maximum  value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is  just a very low probability that values far from the mean will be  returned; and a higher probability that numbers near the mean will  be returned. Takes either 0, 1 or 2 arguments.  If no args, returns a mean of 0 and standard deviation of 1.  If one arg, that arg is the mean (standard deviation is 1).  If two args, first is mean, second is standard deviation."
            +      ],
            +      "returns": "Number: the random number",
            +      "params": {
            +        "mean": "Number: (Optional) the mean",
            +        "sd": "Number: (Optional) the standard deviation"
            +      }
            +    },
            +    "acos": {
            +      "description": [
            +        "The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value. This function expects the values in the range of -1 to 1 and values are returned in the range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the angle mode is DEGREES."
            +      ],
            +      "returns": "Number: the arc cosine of the given value",
            +      "params": {
            +        "value": "Number: the value whose arc cosine is to be returned"
            +      }
            +    },
            +    "asin": {
            +      "description": [
            +        "The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value. This function expects the values in the range of -1 to 1 and values are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle mode is DEGREES."
            +      ],
            +      "returns": "Number: the arc sine of the given value",
            +      "params": {
            +        "value": "Number: the value whose arc sine is to be returned"
            +      }
            +    },
            +    "atan": {
            +      "description": [
            +        "The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value. This function expects the values in the range of -Infinity to Infinity (exclusive) and values are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle mode is DEGREES."
            +      ],
            +      "returns": "Number: the arc tangent of the given value",
            +      "params": {
            +        "value": "Number: the value whose arc tangent is to be returned"
            +      }
            +    },
            +    "atan2": {
            +      "description": [
            +        "Calculates the angle (in radians) from a specified point to the coordinate origin as measured from the positive x-axis. Values are returned as a float in the range from PI to -PI if the angleMode is RADIANS or 180 to -180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is most often used for orienting geometry to the position of the cursor.",
            +        "Note: The y-coordinate of the point is the first parameter, and the x-coordinate is the second parameter, due the the structure of calculating the tangent."
            +      ],
            +      "returns": "Number: the arc tangent of the given point",
            +      "params": {
            +        "y": "Number: y-coordinate of the point",
            +        "x": "Number: x-coordinate of the point"
            +      }
            +    },
            +    "cos": {
            +      "description": [
            +        "Calculates the cosine of an angle. This function takes into account the current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1."
            +      ],
            +      "returns": "Number: the cosine of the angle",
            +      "params": {
            +        "angle": "Number: the angle"
            +      }
            +    },
            +    "sin": {
            +      "description": [
            +        "Calculates the sine of an angle. This function takes into account the current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1."
            +      ],
            +      "returns": "Number: the sine of the angle",
            +      "params": {
            +        "angle": "Number: the angle"
            +      }
            +    },
            +    "tan": {
            +      "description": [
            +        "Calculates the tangent of an angle. This function takes into account the current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers."
            +      ],
            +      "returns": "Number: the tangent of the angle",
            +      "params": {
            +        "angle": "Number: the angle"
            +      }
            +    },
            +    "degrees": {
            +      "description": [
            +        "Converts a radian measurement to its corresponding value in degrees. Radians and degrees are two ways of measuring the same thing. There are 360 degrees in a circle and 2*PI radians in a circle. For example, 90° = PI/2 = 1.5707964. This function does not take into account the current <a href=\"#/p5/angleMode\">angleMode</a>."
            +      ],
            +      "returns": "Number: the converted angle",
            +      "params": {
            +        "radians": "Number: the radians value to convert to degrees"
            +      }
            +    },
            +    "radians": {
            +      "description": [
            +        "Converts a degree measurement to its corresponding value in radians. Radians and degrees are two ways of measuring the same thing. There are 360 degrees in a circle and 2*PI radians in a circle. For example, 90° = PI/2 = 1.5707964. This function does not take into account the current <a href=\"#/p5/angleMode\">angleMode</a>."
            +      ],
            +      "returns": "Number: the converted angle",
            +      "params": {
            +        "degrees": "Number: the degree value to convert to radians"
            +      }
            +    },
            +    "angleMode": {
            +      "description": [
            +        "Sets the current mode of p5 to given mode. Default mode is RADIANS."
            +      ],
            +      "params": {
            +        "mode": "Constant: either RADIANS or DEGREES"
            +      }
            +    },
            +    "textAlign": {
            +      "description": [
            +        "Sets the current alignment for drawing text. Accepts two arguments: horizAlign (LEFT, CENTER, or RIGHT) and vertAlign (TOP, BOTTOM, CENTER, or BASELINE).",
            +        "The horizAlign parameter is in reference to the x value of the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter is in reference to the y value.",
            +        "So if you write textAlign(LEFT), you are aligning the left edge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>. If you write textAlign(RIGHT, TOP), you are aligning the right edge of your text to the x value and the top of edge of the text to the y value."
            +      ],
            +      "params": {
            +        "horizAlign": "Constant: horizontal alignment, either LEFT,  CENTER, or RIGHT",
            +        "vertAlign": "Constant: (Optional) vertical alignment, either TOP,  BOTTOM, CENTER, or BASELINE"
            +      }
            +    },
            +    "textLeading": {
            +      "description": [
            +        "Sets/gets the spacing, in pixels, between lines of text. This setting will be used in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function."
            +      ],
            +      "params": {
            +        "leading": "Number: the size in pixels for spacing between lines"
            +      }
            +    },
            +    "textSize": {
            +      "description": [
            +        "Sets/gets the current font size. This size will be used in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels."
            +      ],
            +      "params": {
            +        "theSize": "Number: the size of the letters in units of pixels"
            +      }
            +    },
            +    "textStyle": {
            +      "description": [
            +        "Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC. Note: this may be is overridden by CSS styling. For non-system fonts (opentype, truetype, etc.) please load styled fonts instead."
            +      ],
            +      "params": {
            +        "theStyle": "Constant: styling for text, either NORMAL,  ITALIC, BOLD or BOLDITALIC"
            +      }
            +    },
            +    "textWidth": {
            +      "description": [
            +        "Calculates and returns the width of any character or text string."
            +      ],
            +      "returns": "Number: the calculated width",
            +      "params": {
            +        "theText": "String: the String of characters to measure"
            +      }
            +    },
            +    "textAscent": {
            +      "description": [
            +        "Returns the ascent of the current font at its current size. The ascent represents the distance, in pixels, of the tallest character above the baseline."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "textDescent": {
            +      "description": [
            +        "Returns the descent of the current font at its current size. The descent represents the distance, in pixels, of the character with the longest descender below the baseline."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "textWrap": {
            +      "description": [
            +        "Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.",
            +        "WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.",
            +        "CHAR wrap style breaks lines wherever needed to stay within the text box.",
            +        "WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen."
            +      ],
            +      "returns": "String: wrapStyle",
            +      "params": {
            +        "wrapStyle": "Constant: text wrapping style, either WORD or CHAR"
            +      }
            +    },
            +    "loadFont": {
            +      "description": [
            +        "Loads an opentype font file (.otf, .ttf) from a file or a URL, and returns a PFont Object. This method is asynchronous, meaning it may not finish before the next line in your sketch is executed.",
            +        "The path to the font should be relative to the HTML file that links in your sketch. Loading fonts from a URL or other remote location may be blocked due to your browser's built-in security."
            +      ],
            +      "returns": "p5.Font: <a href=\"#/p5.Font\">p5.Font</a> object",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/loadFont\">loadFont()</a> completes",
            +        "onError": "Function: (Optional) function to be executed if  an error occurs"
            +      }
            +    },
            +    "text": {
            +      "description": [
            +        "Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. A default font will be used unless a font is set with the <a href=\"#/p5/textFont\">textFont()</a> function and a default size will be used unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change the color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change the outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and <a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.",
            +        "The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a> function, which gives the option to draw to the left, right, and center of the coordinates.",
            +        "The x2 and y2 parameters define a rectangular area to display within and may only be used with string data. When these parameters are specified, they are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a> setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. If x2 and y2 are not specified, the baseline alignment is the default, which means that the text will be drawn upwards from x and y.",
            +        "<b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font using the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above). <a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode. Learn more about working with text in webgl mode on the <a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>."
            +      ],
            +      "params": {
            +        "str": "String|Object|Array|Number|Boolean: the alphanumeric  symbols to be displayed",
            +        "x": "Number: x-coordinate of text",
            +        "y": "Number: y-coordinate of text",
            +        "x2": "Number: (Optional) by default, the width of the text box,  see <a href=\"#/p5/rectMode\">rectMode()</a> for more info",
            +        "y2": "Number: (Optional) by default, the height of the text box,  see <a href=\"#/p5/rectMode\">rectMode()</a> for more info"
            +      }
            +    },
            +    "textFont": {
            +      "description": [
            +        "Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function. If textFont() is called without any argument, it will return the current font if one has been set already. If not, it will return the name of the default font as a string. If textFont() is called with a font to use, it will return the p5 object.",
            +        "<b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported."
            +      ],
            +      "returns": "Object: the current font / p5 Object",
            +      "params": {
            +        "font": "Object|String: a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>, or a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a> (a font that is generally available across all systems)",
            +        "size": "Number: (Optional) the font size to use"
            +      }
            +    },
            +    "append": {
            +      "description": [
            +        "Adds a value to the end of an array. Extends the length of the array by one. Maps to Array.push()."
            +      ],
            +      "returns": "Array: the array that was appended to",
            +      "params": {
            +        "array": "Array: Array to append",
            +        "value": "Any: to be added to the Array"
            +      }
            +    },
            +    "arrayCopy": {
            +      "description": [
            +        "Copies an array (or part of an array) to another array. The src array is copied to the dst array, beginning at the position specified by srcPosition and into the position specified by dstPosition. The number of elements to copy is determined by length. Note that copying values overwrites existing values in the destination array. To append values instead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.",
            +        "The simplified version with only two arguments, arrayCopy(src, dst), copies an entire array to another of the same size. It is equivalent to arrayCopy(src, 0, dst, 0, src.length).",
            +        "Using this function is far more efficient for copying array data than iterating through a for() loop and copying each element individually."
            +      ],
            +      "params": {
            +        "src": "Array: the source Array",
            +        "srcPosition": "Integer: starting position in the source Array",
            +        "dst": "Array: the destination Array",
            +        "dstPosition": "Integer: starting position in the destination Array",
            +        "length": "Integer: number of Array elements to be copied"
            +      }
            +    },
            +    "concat": {
            +      "description": [
            +        "Concatenates two arrays, maps to Array.concat(). Does not modify the input arrays."
            +      ],
            +      "returns": "Array: concatenated array",
            +      "params": {
            +        "a": "Array: first Array to concatenate",
            +        "b": "Array: second Array to concatenate"
            +      }
            +    },
            +    "reverse": {
            +      "description": [
            +        "Reverses the order of an array, maps to Array.reverse()"
            +      ],
            +      "returns": "Array: the reversed list",
            +      "params": {
            +        "list": "Array: Array to reverse"
            +      }
            +    },
            +    "shorten": {
            +      "description": [
            +        "Decreases an array by one element and returns the shortened array, maps to Array.pop()."
            +      ],
            +      "returns": "Array: shortened Array",
            +      "params": {
            +        "list": "Array: Array to shorten"
            +      }
            +    },
            +    "shuffle": {
            +      "description": [
            +        "Randomizes the order of the elements of an array. Implements <a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank> Fisher-Yates Shuffle Algorithm</a>."
            +      ],
            +      "returns": "Array: shuffled Array",
            +      "params": {
            +        "array": "Array: Array to shuffle",
            +        "bool": "Boolean: (Optional) modify passed array"
            +      }
            +    },
            +    "sort": {
            +      "description": [
            +        "Sorts an array of numbers from smallest to largest, or puts an array of words in alphabetical order. The original array is not modified; a re-ordered array is returned. The count parameter states the number of elements to sort. For example, if there are 12 elements in an array and count is set to 5, only the first 5 elements in the array will be sorted."
            +      ],
            +      "returns": "Array: the sorted list",
            +      "params": {
            +        "list": "Array: Array to sort",
            +        "count": "Integer: (Optional) number of elements to sort, starting from 0"
            +      }
            +    },
            +    "splice": {
            +      "description": [
            +        "Inserts a value or an array of values into an existing array. The first parameter specifies the initial array to be modified, and the second parameter defines the data to be inserted. The third parameter is an index value which specifies the array position from which to insert data. (Remember that array index numbering starts at zero, so the first position is 0, the second position is 1, and so on.)"
            +      ],
            +      "returns": "Array: the list",
            +      "params": {
            +        "list": "Array: Array to splice into",
            +        "value": "Any: value to be spliced in",
            +        "position": "Integer: in the array from which to insert data"
            +      }
            +    },
            +    "subset": {
            +      "description": [
            +        "Extracts an array of elements from an existing array. The list parameter defines the array from which the elements will be copied, and the start and count parameters specify which elements to extract. If no count is given, elements will be extracted from the start to the end of the array. When specifying the start, remember that the first array element is 0. This function does not change the source array."
            +      ],
            +      "returns": "Array: Array of extracted elements",
            +      "params": {
            +        "list": "Array: Array to extract from",
            +        "start": "Integer: position to begin",
            +        "count": "Integer: (Optional) number of values to extract"
            +      }
            +    },
            +    "float": {
            +      "description": [
            +        "Converts a string to its floating point representation. The contents of a string must resemble a number, or NaN (not a number) will be returned. For example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\") will return NaN.",
            +        "When an array of values is passed in, then an array of floats of the same length is returned."
            +      ],
            +      "returns": "Number: floating point representation of string",
            +      "params": {
            +        "str": "String: float string to parse"
            +      }
            +    },
            +    "int": {
            +      "description": [
            +        "Converts a boolean, string, or float to its integer representation. When an array of values is passed in, then an int array of the same length is returned."
            +      ],
            +      "returns": "Number: integer representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number: value to parse",
            +        "radix": "Integer: (Optional) the radix to convert to (default: 10)",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "str": {
            +      "description": [
            +        "Converts a boolean, string or number to its string representation. When an array of values is passed in, then an array of strings of the same length is returned."
            +      ],
            +      "returns": "String: string representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number|Array: value to parse"
            +      }
            +    },
            +    "byte": {
            +      "description": [
            +        "Converts a number, string representation of a number, or boolean to its byte representation. A byte can be only a whole number between -128 and 127, so when a value outside of this range is converted, it wraps around to the corresponding byte representation. When an array of number, string or boolean values is passed in, then an array of bytes the same length is returned."
            +      ],
            +      "returns": "Number: byte representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "char": {
            +      "description": [
            +        "Converts a number or string to its corresponding single-character string representation. If a string parameter is provided, it is first parsed as an integer and then translated into a single-character string. When an array of number or string values is passed in, then an array of single-character strings of the same length is returned."
            +      ],
            +      "returns": "String: string representation of value",
            +      "params": {
            +        "n": "String|Number: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "unchar": {
            +      "description": [
            +        "Converts a single-character string to its corresponding integer representation. When an array of single-character string values is passed in, then an array of integers of the same length is returned."
            +      ],
            +      "returns": "Number: integer representation of value",
            +      "params": {
            +        "n": "String: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "hex": {
            +      "description": [
            +        "Converts a number to a string in its equivalent hexadecimal notation. If a second parameter is passed, it is used to set the number of characters to generate in the hexadecimal notation. When an array is passed in, an array of strings in hexadecimal notation of the same length is returned."
            +      ],
            +      "returns": "String: hexadecimal string representation of value",
            +      "params": {
            +        "n": "Number: value to parse",
            +        "digits": "Number (Optional)",
            +        "ns": "Number[]: array of values to parse"
            +      }
            +    },
            +    "unhex": {
            +      "description": [
            +        "Converts a string representation of a hexadecimal number to its equivalent integer value. When an array of strings in hexadecimal notation is passed in, an array of integers of the same length is returned."
            +      ],
            +      "returns": "Number: integer representation of hexadecimal value",
            +      "params": {
            +        "n": "String: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "join": {
            +      "description": [
            +        "Combines an array of Strings into one String, each separated by the character(s) used for the separator parameter. To join arrays of ints or floats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or nfs()."
            +      ],
            +      "returns": "String: joined String",
            +      "params": {
            +        "list": "Array: array of Strings to be joined",
            +        "separator": "String: String to be placed between each item"
            +      }
            +    },
            +    "match": {
            +      "description": [
            +        "This function is used to apply a regular expression to a piece of text, and return matching groups (elements found inside parentheses) as a String array. If there are no matches, a null value will be returned. If no groups are specified in the regular expression, but the sequence matches, an array of length 1 (with the matched text as the first element of the array) will be returned.",
            +        "To use the function, first check to see if the result is null. If the result is null, then the sequence did not match at all. If the sequence did match, an array is returned.",
            +        "If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Element [0] of a regular expression match returns the entire matching string, and the match groups start at element [1] (the first group is [1], the second [2], and so on)."
            +      ],
            +      "returns": "String[]: Array of Strings found",
            +      "params": {
            +        "str": "String: the String to be searched",
            +        "regexp": "String: the regexp to be used for matching"
            +      }
            +    },
            +    "matchAll": {
            +      "description": [
            +        "This function is used to apply a regular expression to a piece of text, and return a list of matching groups (elements found inside parentheses) as a two-dimensional String array. If there are no matches, a null value will be returned. If no groups are specified in the regular expression, but the sequence matches, a two dimensional array is still returned, but the second dimension is only of length one.",
            +        "To use the function, first check to see if the result is null. If the result is null, then the sequence did not match at all. If the sequence did match, a 2D array is returned.",
            +        "If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Assuming a loop with counter variable i, element [i][0] of a regular expression match returns the entire matching string, and the match groups start at element [i][1] (the first group is [i][1], the second [i][2], and so on)."
            +      ],
            +      "returns": "String[]: 2d Array of Strings found",
            +      "params": {
            +        "str": "String: the String to be searched",
            +        "regexp": "String: the regexp to be used for matching"
            +      }
            +    },
            +    "nf": {
            +      "description": [
            +        "Utility function for formatting numbers into strings. There are two versions: one for formatting floats, and one for formatting ints.",
            +        "The values for the digits, left, and right parameters should always be positive integers.",
            +        "(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter if greater than the current length of the number.",
            +        "For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123 (integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than the result will be 123.200."
            +      ],
            +      "returns": "String: formatted String",
            +      "params": {
            +        "num": "Number|String: the Number to format",
            +        "left": "Integer|String: (Optional) number of digits to the left of the  decimal point",
            +        "right": "Integer|String: (Optional) number of digits to the right of the  decimal point",
            +        "nums": "Array: the Numbers to format"
            +      }
            +    },
            +    "nfc": {
            +      "description": [
            +        "Utility function for formatting numbers into strings and placing appropriate commas to mark units of 1000. There are two versions: one for formatting ints, and one for formatting an array of ints. The value for the right parameter should always be a positive integer."
            +      ],
            +      "returns": "String: formatted String",
            +      "params": {
            +        "num": "Number|String: the Number to format",
            +        "right": "Integer|String: (Optional) number of digits to the right of the  decimal point",
            +        "nums": "Array: the Numbers to format"
            +      }
            +    },
            +    "nfp": {
            +      "description": [
            +        "Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but puts a \"+\" in front of positive numbers and a \"-\" in front of negative numbers. There are two versions: one for formatting floats, and one for formatting ints. The values for left, and right parameters should always be positive integers."
            +      ],
            +      "returns": "String: formatted String",
            +      "params": {
            +        "num": "Number: the Number to format",
            +        "left": "Integer: (Optional) number of digits to the left of the decimal  point",
            +        "right": "Integer: (Optional) number of digits to the right of the  decimal point",
            +        "nums": "Number[]: the Numbers to format"
            +      }
            +    },
            +    "nfs": {
            +      "description": [
            +        "Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but puts an additional \"_\" (space) in front of positive numbers just in case to align it with negative numbers which includes \"-\" (minus) sign.",
            +        "The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative number with some negative number (See the example to get a clear picture). There are two versions: one for formatting float, and one for formatting int.",
            +        "The values for the digits, left, and right parameters should always be positive integers.",
            +        "(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.",
            +        "(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter if greater than the current length of the number.",
            +        "For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123 (integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than the result will be 123.200."
            +      ],
            +      "returns": "String: formatted String",
            +      "params": {
            +        "num": "Number: the Number to format",
            +        "left": "Integer: (Optional) number of digits to the left of the decimal  point",
            +        "right": "Integer: (Optional) number of digits to the right of the  decimal point",
            +        "nums": "Array: the Numbers to format"
            +      }
            +    },
            +    "split": {
            +      "description": [
            +        "The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into pieces using a character or string as the delimiter. The delim parameter specifies the character or characters that mark the boundaries between each piece. A String[] array is returned that contains each of the pieces.",
            +        "The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it splits using a range of characters instead of a specific character or sequence."
            +      ],
            +      "returns": "String[]: Array of Strings",
            +      "params": {
            +        "value": "String: the String to be split",
            +        "delim": "String: the String used to separate the data"
            +      }
            +    },
            +    "splitTokens": {
            +      "description": [
            +        "The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character delimiters or \"tokens.\" The delim parameter specifies the character or characters to be used as a boundary.",
            +        "If no delim characters are specified, any whitespace character is used to split. Whitespace characters include tab (\\t), line feed (\\n), carriage return (\\r), form feed (\\f), and space."
            +      ],
            +      "returns": "String[]: Array of Strings",
            +      "params": {
            +        "value": "String: the String to be split",
            +        "delim": "String: (Optional) list of individual Strings that will be used as  separators"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "Removes whitespace characters from the beginning and end of a String. In addition to standard whitespace characters such as space, carriage return, and tab, this function also removes the Unicode \"nbsp\" character."
            +      ],
            +      "returns": "String: a trimmed String",
            +      "params": {
            +        "str": "String: a String to be trimmed",
            +        "strs": "Array: an Array of Strings to be trimmed"
            +      }
            +    },
            +    "day": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function returns the current day as a value from 1 - 31."
            +      ],
            +      "returns": "Integer: the current day"
            +    },
            +    "hour": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function returns the current hour as a value from 0 - 23."
            +      ],
            +      "returns": "Integer: the current hour"
            +    },
            +    "minute": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function returns the current minute as a value from 0 - 59."
            +      ],
            +      "returns": "Integer: the current minute"
            +    },
            +    "millis": {
            +      "description": [
            +        "Returns the number of milliseconds (thousandths of a second) since starting the sketch (when <code>setup()</code> is called). This information is often used for timing events and animation sequences."
            +      ],
            +      "returns": "Number: the number of milliseconds since starting the sketch"
            +    },
            +    "month": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function returns the current month as a value from 1 - 12."
            +      ],
            +      "returns": "Integer: the current month"
            +    },
            +    "second": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function returns the current second as a value from 0 - 59."
            +      ],
            +      "returns": "Integer: the current second"
            +    },
            +    "year": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function returns the current year as an integer (2014, 2015, 2016, etc)."
            +      ],
            +      "returns": "Integer: the current year"
            +    },
            +    "plane": {
            +      "description": [
            +        "Draw a plane with given a width and height"
            +      ],
            +      "params": {
            +        "width": "Number: (Optional) width of the plane",
            +        "height": "Number: (Optional) height of the plane",
            +        "detailX": "Integer: (Optional) Optional number of triangle  subdivisions in x-dimension",
            +        "detailY": "Integer: (Optional) Optional number of triangle  subdivisions in y-dimension"
            +      }
            +    },
            +    "box": {
            +      "description": [
            +        "Draw a box with given width, height and depth"
            +      ],
            +      "params": {
            +        "width": "Number: (Optional) width of the box",
            +        "Height": "Number: (Optional) height of the box",
            +        "depth": "Number: (Optional) depth of the box",
            +        "detailX": "Integer: (Optional) Optional number of triangle  subdivisions in x-dimension",
            +        "detailY": "Integer: (Optional) Optional number of triangle  subdivisions in y-dimension"
            +      }
            +    },
            +    "sphere": {
            +      "description": [
            +        "Draw a sphere with given radius.",
            +        "DetailX and detailY determines the number of subdivisions in the x-dimension and the y-dimension of a sphere. More subdivisions make the sphere seem smoother. The recommended maximum values are both 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "Number: (Optional) radius of circle",
            +        "detailX": "Integer: (Optional) optional number of subdivisions in x-dimension",
            +        "detailY": "Integer: (Optional) optional number of subdivisions in y-dimension"
            +      }
            +    },
            +    "cylinder": {
            +      "description": [
            +        "Draw a cylinder with given radius and height",
            +        "DetailX and detailY determines the number of subdivisions in the x-dimension and the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother. The recommended maximum value for detailX is 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "Number: (Optional) radius of the surface",
            +        "height": "Number: (Optional) height of the cylinder",
            +        "detailX": "Integer: (Optional) number of subdivisions in x-dimension;  default is 24",
            +        "detailY": "Integer: (Optional) number of subdivisions in y-dimension;  default is 1",
            +        "bottomCap": "Boolean: (Optional) whether to draw the bottom of the cylinder",
            +        "topCap": "Boolean: (Optional) whether to draw the top of the cylinder"
            +      }
            +    },
            +    "cone": {
            +      "description": [
            +        "Draw a cone with given radius and height",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a cone. More subdivisions make the cone seem smoother. The recommended maximum value for detailX is 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "Number: (Optional) radius of the bottom surface",
            +        "height": "Number: (Optional) height of the cone",
            +        "detailX": "Integer: (Optional) number of segments,  the more segments the smoother geometry  default is 24",
            +        "detailY": "Integer: (Optional) number of segments,  the more segments the smoother geometry  default is 1",
            +        "cap": "Boolean: (Optional) whether to draw the base of the cone"
            +      }
            +    },
            +    "ellipsoid": {
            +      "description": [
            +        "Draw an ellipsoid with given radius",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother. Avoid detail number above 150, it may crash the browser."
            +      ],
            +      "params": {
            +        "radiusx": "Number: (Optional) x-radius of ellipsoid",
            +        "radiusy": "Number: (Optional) y-radius of ellipsoid",
            +        "radiusz": "Number: (Optional) z-radius of ellipsoid",
            +        "detailX": "Integer: (Optional) number of segments,  the more segments the smoother geometry  default is 24. Avoid detail number above  150, it may crash the browser.",
            +        "detailY": "Integer: (Optional) number of segments,  the more segments the smoother geometry  default is 16. Avoid detail number above  150, it may crash the browser."
            +      }
            +    },
            +    "torus": {
            +      "description": [
            +        "Draw a torus with given radius and tube radius",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a torus. More subdivisions make the torus appear to be smoother. The default and maximum values for detailX and detailY are 24 and 16, respectively. Setting them to relatively small values like 4 and 6 allows you to create new shapes other than a torus."
            +      ],
            +      "params": {
            +        "radius": "Number: (Optional) radius of the whole ring",
            +        "tubeRadius": "Number: (Optional) radius of the tube",
            +        "detailX": "Integer: (Optional) number of segments in x-dimension,  the more segments the smoother geometry  default is 24",
            +        "detailY": "Integer: (Optional) number of segments in y-dimension,  the more segments the smoother geometry  default is 16"
            +      }
            +    },
            +    "orbitControl": {
            +      "description": [
            +        "Allows movement around a 3D sketch using a mouse or trackpad. Left-clicking and dragging will rotate the camera position about the center of the sketch, right-clicking and dragging will pan the camera position without rotation, and using the mouse wheel (scrolling) will move the camera closer or further from the center of the sketch. This function can be called with parameters dictating sensitivity to mouse movement along the X and Y axes. Calling this function without parameters is equivalent to calling orbitControl(1,1). To reverse direction of movement in either axis, enter a negative number for sensitivity."
            +      ],
            +      "params": {
            +        "sensitivityX": "Number: (Optional) sensitivity to mouse movement along X axis",
            +        "sensitivityY": "Number: (Optional) sensitivity to mouse movement along Y axis",
            +        "sensitivityZ": "Number: (Optional) sensitivity to scroll movement along Z axis"
            +      }
            +    },
            +    "debugMode": {
            +      "description": [
            +        "debugMode() helps visualize 3D space by adding a grid to indicate where the ‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z directions. This function can be called without parameters to create a default grid and axes icon, or it can be called according to the examples above to customize the size and position of the grid and/or axes icon. The grid is drawn using the most recently set stroke color and weight. To specify these parameters, add a call to stroke() and strokeWeight() just before the end of the draw() loop.",
            +        "By default, the grid will run through the origin (0,0,0) of the sketch along the XZ plane and the axes icon will be offset from the origin. Both the grid and axes icon will be sized according to the current canvas size. Note that because the grid runs parallel to the default camera view, it is often helpful to use debugMode along with orbitControl to allow full view of the grid."
            +      ],
            +      "params": {
            +        "mode": "Constant: either GRID or AXES",
            +        "gridSize": "Number: (Optional) size of one side of the grid",
            +        "gridDivisions": "Number: (Optional) number of divisions in the grid",
            +        "xOff": "Number: (Optional) X axis offset from origin (0,0,0)",
            +        "yOff": "Number: (Optional) Y axis offset from origin (0,0,0)",
            +        "zOff": "Number: (Optional) Z axis offset from origin (0,0,0)",
            +        "axesSize": "Number: (Optional) size of axes icon",
            +        "gridXOff": "Number (Optional)",
            +        "gridYOff": "Number (Optional)",
            +        "gridZOff": "Number (Optional)",
            +        "axesXOff": "Number (Optional)",
            +        "axesYOff": "Number (Optional)",
            +        "axesZOff": "Number (Optional)"
            +      }
            +    },
            +    "noDebugMode": {
            +      "description": [
            +        "Turns off debugMode() in a 3D sketch."
            +      ]
            +    },
            +    "ambientLight": {
            +      "description": [
            +        "Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas. It has no particular source."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "alpha": "Number: (Optional) the alpha value",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the ambient light color"
            +      }
            +    },
            +    "specularColor": {
            +      "description": [
            +        "Set's the color of the specular highlight when using a specular material and specular light.",
            +        "This method can be combined with specularMaterial() and shininess() functions to set specular highlights. The default color is white, ie (255, 255, 255), which is used if this method is not called before specularMaterial(). If this method is called without specularMaterial(), There will be no effect.",
            +        "Note: specularColor is equivalent to the processing function <a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the ambient light color"
            +      }
            +    },
            +    "directionalLight": {
            +      "description": [
            +        "Creates a directional light with a color and a direction",
            +        "A maximum of 5 directionalLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value (depending on the current color mode),",
            +        "v2": "Number: green or saturation value",
            +        "v3": "Number: blue or brightness value",
            +        "position": "p5.Vector: the direction of the light",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string,  or <a href=\"#/p5.Color\">p5.Color</a> value",
            +        "x": "Number: x axis direction",
            +        "y": "Number: y axis direction",
            +        "z": "Number: z axis direction"
            +      }
            +    },
            +    "pointLight": {
            +      "description": [
            +        "Creates a point light with a color and a light position",
            +        "A maximum of 5 pointLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value (depending on the current color mode),",
            +        "v2": "Number: green or saturation value",
            +        "v3": "Number: blue or brightness value",
            +        "x": "Number: x axis position",
            +        "y": "Number: y axis position",
            +        "z": "Number: z axis position",
            +        "position": "p5.Vector: the position of the light",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string, or <a href=\"#/p5.Color\">p5.Color</a> value"
            +      }
            +    },
            +    "lights": {
            +      "description": [
            +        "Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop."
            +      ]
            +    },
            +    "lightFalloff": {
            +      "description": [
            +        "Sets the falloff rates for point lights. It affects only the elements which are created after it in the code. The default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:",
            +        "d = distance from light position to vertex position",
            +        "falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)"
            +      ],
            +      "params": {
            +        "constant": "Number: constant value for determining falloff",
            +        "linear": "Number: linear value for determining falloff",
            +        "quadratic": "Number: quadratic value for determining falloff"
            +      }
            +    },
            +    "spotLight": {
            +      "description": [
            +        "Creates a spotlight with a given color, position, direction of light, angle and concentration. Here, angle refers to the opening or aperture of the cone of the spotlight, and concentration is used to focus the light towards the center. Both angle and concentration are optional, but if you want to provide concentration, you will also have to specify the angle.",
            +        "A maximum of 5 spotLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value (depending on the current color mode),",
            +        "v2": "Number: green or saturation value",
            +        "v3": "Number: blue or brightness value",
            +        "x": "Number: x axis position",
            +        "y": "Number: y axis position",
            +        "z": "Number: z axis position",
            +        "rx": "Number: x axis direction of light",
            +        "ry": "Number: y axis direction of light",
            +        "rz": "Number: z axis direction of light",
            +        "angle": "Number: (Optional) optional parameter for angle. Defaults to PI/3",
            +        "conc": "Number: (Optional) optional parameter for concentration. Defaults to 100",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string, or <a href=\"#/p5.Color\">p5.Color</a> value",
            +        "position": "p5.Vector: the position of the light",
            +        "direction": "p5.Vector: the direction of the light"
            +      }
            +    },
            +    "noLights": {
            +      "description": [
            +        "This function will remove all the lights from the sketch for the subsequent materials rendered. It affects all the subsequent methods. Calls to lighting methods made after noLights() will re-enable lights in the sketch."
            +      ]
            +    },
            +    "loadModel": {
            +      "description": [
            +        "Load a 3d model from an OBJ or STL file.",
            +        "<a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>. This allows the model to load fully before the rest of your code is run.",
            +        "One of the limitations of the OBJ and STL format is that it doesn't have a built-in sense of scale. This means that models exported from different programs might be very different sizes. If your model isn't displaying, try calling <a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the model to a scale appropriate for p5. You can also make additional changes to the final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.",
            +        "Also, the support for colored STL files is not present. STL files with color will be rendered without color properties."
            +      ],
            +      "returns": "p5.Geometry: the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +      "params": {
            +        "path": "String: Path of the model to be loaded",
            +        "normalize": "Boolean: If true, scale the model to a  standardized size when loading",
            +        "successCallback": "function(p5.Geometry): (Optional) Function to be called  once the model is loaded. Will be passed  the 3D model object.",
            +        "failureCallback": "Function(Event): (Optional) called with event error if  the model fails to load.",
            +        "fileType": "String: (Optional) The file extension of the model  (<code>.stl</code>, <code>.obj</code>)."
            +      }
            +    },
            +    "model": {
            +      "description": [
            +        "Render a 3d model to the screen."
            +      ],
            +      "params": {
            +        "model": "p5.Geometry: Loaded 3d model to be rendered"
            +      }
            +    },
            +    "loadShader": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object from the provided vertex and fragment shader files.",
            +        "The shader files are loaded asynchronously in the background, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.",
            +        "Note, shaders can only be used in WEBGL mode."
            +      ],
            +      "returns": "p5.Shader: a shader object created from the provided vertex and fragment shader files.",
            +      "params": {
            +        "vertFilename": "String: path to file containing vertex shader source code",
            +        "fragFilename": "String: path to file containing fragment shader source code",
            +        "callback": "Function: (Optional) callback to be executed after loadShader completes. On success, the p5.Shader object is passed as the first argument.",
            +        "errorCallback": "Function: (Optional) callback to be executed when an error occurs inside loadShader. On error, the error is passed as the first argument."
            +      }
            +    },
            +    "createShader": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object from the provided vertex and fragment shader code.",
            +        "Note, shaders can only be used in WEBGL mode."
            +      ],
            +      "returns": "p5.Shader: a shader object created from the provided vertex and fragment shaders.",
            +      "params": {
            +        "vertSrc": "String: source code for the vertex shader",
            +        "fragSrc": "String: source code for the fragment shader"
            +      }
            +    },
            +    "shader": {
            +      "description": [
            +        "Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to be used to render subsequent shapes.",
            +        "Custom shaders can be created using the <a href=\"#/p5/createShader\">createShader()</a> and <a href=\"#/p5/loadShader\">loadShader()</a> functions.",
            +        "Use <a href=\"#/p5/resetShader\">resetShader()</a> to restore the default shaders.",
            +        "Note, shaders can only be used in WEBGL mode."
            +      ],
            +      "params": {
            +        "s": "p5.Shader: the <a href=\"#/p5.Shader\">p5.Shader</a> object to use for rendering shapes."
            +      }
            +    },
            +    "resetShader": {
            +      "description": [
            +        "Restores the default shaders. Code that runs after resetShader() will not be affected by the shader previously set by <a href=\"#/p5/shader\">shader()</a>"
            +      ]
            +    },
            +    "texture": {
            +      "description": [
            +        "Sets the texture that will be used to render subsequent shapes.",
            +        "A texture is like a \"skin\" that wraps around a 3D geometry. Currently supported textures are images, video, and offscreen renders.",
            +        "To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>, you will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.",
            +        "Note, texture() can only be used in WEBGL mode.",
            +        "You can view more materials in this <a href=\"https://p5js.org/examples/3d-materials.html\">example</a>."
            +      ],
            +      "params": {
            +        "tex": "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture: image to use as texture"
            +      }
            +    },
            +    "textureMode": {
            +      "description": [
            +        "Sets the coordinate space for texture mapping. The default mode is IMAGE which refers to the actual coordinates of the image. NORMAL refers to a normalized space of values ranging from 0 to 1.",
            +        "With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire size of a quad would require the points (0,0) (100, 0) (100,200) (0,200). The same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1)."
            +      ],
            +      "params": {
            +        "mode": "Constant: either IMAGE or NORMAL"
            +      }
            +    },
            +    "textureWrap": {
            +      "description": [
            +        "Sets the global texture wrapping mode. This controls how textures behave when their uv's go outside of the 0 to 1 range. There are three options: CLAMP, REPEAT, and MIRROR.",
            +        "CLAMP causes the pixels at the edge of the texture to extend to the bounds. REPEAT causes the texture to tile repeatedly until reaching the bounds. MIRROR works similarly to REPEAT but it flips the texture with every new tile.",
            +        "REPEAT & MIRROR are only available if the texture is a power of two size (128, 256, 512, 1024, etc.).",
            +        "This method will affect all textures in your sketch until a subsequent textureWrap() call is made.",
            +        "If only one argument is provided, it will be applied to both the horizontal and vertical axes."
            +      ],
            +      "params": {
            +        "wrapX": "Constant: either CLAMP, REPEAT, or MIRROR",
            +        "wrapY": "Constant: (Optional) either CLAMP, REPEAT, or MIRROR"
            +      }
            +    },
            +    "normalMaterial": {
            +      "description": [
            +        "Normal material for geometry is a material that is not affected by light. It is not reflective and is a placeholder material often used for debugging. Surfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue. You can view all possible materials in this <a href=\"https://p5js.org/examples/3d-materials.html\">example</a>."
            +      ]
            +    },
            +    "ambientMaterial": {
            +      "description": [
            +        "Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting. For example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light. Here's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>."
            +      ],
            +      "params": {
            +        "v1": "Number: gray value, red or hue value  (depending on the current color mode),",
            +        "v2": "Number: (Optional) green or saturation value",
            +        "v3": "Number: (Optional) blue or brightness value",
            +        "color": "Number[]|String|p5.Color: color, color Array, or CSS color string"
            +      }
            +    },
            +    "emissiveMaterial": {
            +      "description": [
            +        "Sets the emissive color of the material used for geometry drawn to the screen. This is a misnomer in the sense that the material does not actually emit light that effects surrounding polygons. Instead, it gives the appearance that the object is glowing. An emissive material will display at full strength even if there is no light for it to reflect."
            +      ],
            +      "params": {
            +        "v1": "Number: gray value, red or hue value  (depending on the current color mode),",
            +        "v2": "Number: (Optional) green or saturation value",
            +        "v3": "Number: (Optional) blue or brightness value",
            +        "a": "Number: (Optional) opacity",
            +        "color": "Number[]|String|p5.Color: color, color Array, or CSS color string"
            +      }
            +    },
            +    "specularMaterial": {
            +      "description": [
            +        "Specular material for geometry with a given color. Specular material is a shiny reflective material. Like ambient material it also defines the color the object reflects under ambient lighting. For example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light. For all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer. Here's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>."
            +      ],
            +      "params": {
            +        "gray": "Number: number specifying value between white and black.",
            +        "alpha": "Number: (Optional) alpha value relative to current color range  (default is 0-255)",
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "color": "Number[]|String|p5.Color: color Array, or CSS color string"
            +      }
            +    },
            +    "shininess": {
            +      "description": [
            +        "Sets the amount of gloss in the surface of shapes. Used in combination with specularMaterial() in setting the material properties of shapes. The default and minimum value is 1."
            +      ],
            +      "params": {
            +        "shine": "Number: Degree of Shininess.  Defaults to 1."
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "Sets the position of the current camera in a 3D sketch. Parameters for this function define the camera's position, the center of the sketch (where the camera is pointing), and an up direction (the orientation of the camera).",
            +        "This function simulates the movements of the camera, allowing objects to be viewed from various angles. Remember, it does not move the objects themselves but the camera instead. For example when the centerX value is positive, and the camera is rotating to the right side of the sketch, the object will seem like it's moving to the left.",
            +        "See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a> to view the position of your camera.",
            +        "If no parameters are given, the following default is used: camera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)"
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) camera position value on x axis",
            +        "y": "Number: (Optional) camera position value on y axis",
            +        "z": "Number: (Optional) camera position value on z axis",
            +        "centerX": "Number: (Optional) x coordinate representing center of the sketch",
            +        "centerY": "Number: (Optional) y coordinate representing center of the sketch",
            +        "centerZ": "Number: (Optional) z coordinate representing center of the sketch",
            +        "upX": "Number: (Optional) x component of direction 'up' from camera",
            +        "upY": "Number: (Optional) y component of direction 'up' from camera",
            +        "upZ": "Number: (Optional) z component of direction 'up' from camera"
            +      }
            +    },
            +    "perspective": {
            +      "description": [
            +        "Sets a perspective projection for the current camera in a 3D sketch. This projection represents depth through foreshortening: objects that are close to the camera appear their actual size while those that are further away from the camera appear smaller.",
            +        "The parameters to this function define the viewing frustum (the truncated pyramid within which objects are seen by the camera) through vertical field of view, aspect ratio (usually width/height), and near and far clipping planes.",
            +        "If no parameters are given, the following default is used: perspective(PI/3, width/height, eyeZ/10, eyeZ*10), where eyeZ is equal to ((height/2) / tan(PI/6))."
            +      ],
            +      "params": {
            +        "fovy": "Number: (Optional) camera frustum vertical field of view,  from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units",
            +        "aspect": "Number: (Optional) camera frustum aspect ratio",
            +        "near": "Number: (Optional) frustum near plane length",
            +        "far": "Number: (Optional) frustum far plane length"
            +      }
            +    },
            +    "ortho": {
            +      "description": [
            +        "Sets an orthographic projection for the current camera in a 3D sketch and defines a box-shaped viewing frustum within which objects are seen. In this projection, all objects with the same dimension appear the same size, regardless of whether they are near or far from the camera.",
            +        "The parameters to this function specify the viewing frustum where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values.",
            +        "If no parameters are given, the following default is used: ortho(-width/2, width/2, -height/2, height/2)."
            +      ],
            +      "params": {
            +        "left": "Number: (Optional) camera frustum left plane",
            +        "right": "Number: (Optional) camera frustum right plane",
            +        "bottom": "Number: (Optional) camera frustum bottom plane",
            +        "top": "Number: (Optional) camera frustum top plane",
            +        "near": "Number: (Optional) camera frustum near plane",
            +        "far": "Number: (Optional) camera frustum far plane"
            +      }
            +    },
            +    "frustum": {
            +      "description": [
            +        "Sets the frustum of the current camera as defined by the parameters.",
            +        "A frustum is a geometric form: a pyramid with its top cut off. With the viewer's eye at the imaginary top of the pyramid, the six planes of the frustum act as clipping planes when rendering a 3D view. Thus, any form inside the clipping planes is visible; anything outside those planes is not visible.",
            +        "Setting the frustum changes the perspective of the scene being rendered. This can be achieved more simply in many cases by using <a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.",
            +        "If no parameters are given, the following default is used: frustum(-width/2, width/2, -height/2, height/2, 0, max(width, height))."
            +      ],
            +      "params": {
            +        "left": "Number: (Optional) camera frustum left plane",
            +        "right": "Number: (Optional) camera frustum right plane",
            +        "bottom": "Number: (Optional) camera frustum bottom plane",
            +        "top": "Number: (Optional) camera frustum top plane",
            +        "near": "Number: (Optional) camera frustum near plane",
            +        "far": "Number: (Optional) camera frustum far plane"
            +      }
            +    },
            +    "createCamera": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it as the current (active) camera.",
            +        "The new camera is initialized with a default position (see <a href=\"#/p5.Camera/camera\">camera()</a>) and a default perspective projection (see <a href=\"#/p5.Camera/perspective\">perspective()</a>). Its properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a> methods.",
            +        "Note: Every 3D sketch starts with a default camera initialized. This camera can be controlled with the global methods <a href=\"#/p5/camera\">camera()</a>, <a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>, and <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera in the scene."
            +      ],
            +      "returns": "p5.Camera: The newly created camera object."
            +    },
            +    "setCamera": {
            +      "description": [
            +        "Sets the current (active) camera of a 3D sketch. Allows for switching between multiple cameras."
            +      ],
            +      "params": {
            +        "cam": "p5.Camera: p5.Camera object"
            +      }
            +    },
            +    "setAttributes": {
            +      "description": [
            +        "Set attributes for the WebGL Drawing context. This is a way of adjusting how the WebGL renderer works to fine-tune the display and performance.",
            +        "Note that this will reinitialize the drawing context if called after the WebGL canvas is made.",
            +        "If an object is passed as the parameter, all attributes not declared in the object will be set to defaults.",
            +        "The available attributes are:  alpha - indicates if the canvas contains an alpha buffer default is false",
            +        "depth - indicates whether the drawing buffer has a depth buffer of at least 16 bits - default is true",
            +        "stencil - indicates whether the drawing buffer has a stencil buffer of at least 8 bits",
            +        "antialias - indicates whether or not to perform anti-aliasing default is false (true in Safari)",
            +        "premultipliedAlpha - indicates that the page compositor will assume the drawing buffer contains colors with pre-multiplied alpha default is false",
            +        "preserveDrawingBuffer - if true the buffers will not be cleared and and will preserve their values until cleared or overwritten by author (note that p5 clears automatically on draw loop) default is true",
            +        "perPixelLighting - if true, per-pixel lighting will be used in the lighting shader otherwise per-vertex lighting is used. default is true."
            +      ],
            +      "params": {
            +        "key": "String: Name of attribute",
            +        "value": "Boolean: New value of named attribute",
            +        "obj": "Object: object with key-value pairs"
            +      }
            +    },
            +    "getAudioContext": {
            +      "description": [
            +        "Returns the Audio Context for this sketch. Useful for users who would like to dig deeper into the <a target='_blank' href= 'http://webaudio.github.io/web-audio-api/'>Web Audio API </a>.",
            +        "Some browsers require users to startAudioContext with a user gesture, such as touchStarted in the example below."
            +      ],
            +      "returns": "Object: AudioContext for this sketch"
            +    },
            +    "userStartAudio": {
            +      "description": [
            +        "It is not only a good practice to give users control over starting audio. This policy is enforced by many web browsers, including iOS and <a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay policy\">Google Chrome</a>, which create the Web Audio API's <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\" title=\"Audio Context @ MDN\">Audio Context</a> in a suspended state.",
            +        "In these browser-specific policies, sound will not play until a user interaction event (i.e. <code>mousePressed()</code>) explicitly resumes the AudioContext, or starts an audio node. This can be accomplished by calling <code>start()</code> on a <code>p5.Oscillator</code>, <code> play()</code> on a <code>p5.SoundFile</code>, or simply <code>userStartAudio()</code>.",
            +        "<code>userStartAudio()</code> starts the AudioContext on a user gesture. The default behavior will enable audio on any mouseUp or touchEnd event. It can also be placed in a specific interaction function, such as <code>mousePressed()</code> as in the example below. This method utilizes <a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext </a>, a library by Yotam Mann (MIT Licence, 2016)."
            +      ],
            +      "returns": "Promise: Returns a Promise that resolves when  the AudioContext state is 'running'",
            +      "params": {
            +        "element(s)": "Element|Array: (Optional) This argument can be an Element,  Selector String, NodeList, p5.Element,  jQuery Element, or an Array of any of those.",
            +        "callback": "Function: (Optional) Callback to invoke when the AudioContext  has started"
            +      }
            +    },
            +    "getOutputVolume": {
            +      "description": [
            +        "Returns a number representing the output volume for sound in this sketch."
            +      ],
            +      "returns": "Number: Output volume for sound in this sketch.  Should be between 0.0 (silence) and 1.0."
            +    },
            +    "outputVolume": {
            +      "description": [
            +        "Scale the output of all sound in this sketch Scaled between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal.",
            +        "<b>How This Works</b>: When you load the p5.sound module, it creates a single instance of p5sound. All sound objects in this module output to p5sound before reaching your computer's output. So if you change the amplitude of p5sound, it impacts all of the sound in this module.",
            +        "If no value is provided, returns a Web Audio API Gain Node"
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "soundOut": {
            +      "description": [
            +        "<code>p5.soundOut</code> is the p5.sound final output bus. It sends output to the destination of this window's web audio context. It contains Web Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>), and Gain Nodes for <code>.input</code> and <code>.output</code>."
            +      ]
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Returns a number representing the sample rate, in samples per second, of all sound objects in this audio context. It is determined by the sampling rate of your operating system's sound card, and it is not currently possile to change. It is often 44100, or twice the range of human hearing."
            +      ],
            +      "returns": "Number: samplerate samples per second"
            +    },
            +    "freqToMidi": {
            +      "description": [
            +        "Returns the closest MIDI note value for a given frequency."
            +      ],
            +      "returns": "Number: MIDI note value",
            +      "params": {
            +        "frequency": "Number: A freqeuncy, for example, the \"A\"  above Middle C is 440Hz"
            +      }
            +    },
            +    "midiToFreq": {
            +      "description": [
            +        "Returns the frequency value of a MIDI note value. General MIDI treats notes as integers where middle C is 60, C# is 61, D is 62 etc. Useful for generating musical frequencies with oscillators."
            +      ],
            +      "returns": "Number: Frequency value of the given MIDI note",
            +      "params": {
            +        "midiNote": "Number: The number of a MIDI note"
            +      }
            +    },
            +    "soundFormats": {
            +      "description": [
            +        "List the SoundFile formats that you will include. LoadSound will search your directory for these extensions, and will pick a format that is compatable with the client's web browser. <a href=\"http://media.io/\">Here</a> is a free online file converter."
            +      ],
            +      "params": {
            +        "formats": "String: (Optional) i.e. 'mp3', 'wav', 'ogg'"
            +      }
            +    },
            +    "saveSound": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. For uploading audio to a server, use <a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile that you wish to save",
            +        "fileName": "String: name of the resulting .wav file."
            +      }
            +    },
            +    "loadSound": {
            +      "description": [
            +        "loadSound() returns a new p5.SoundFile from a specified path. If called during preload(), the p5.SoundFile will be ready to play in time for setup() and draw(). If called outside of preload, the p5.SoundFile will not be ready immediately, so loadSound accepts a callback as the second parameter. Using a <a href=\"https://github.com/processing/p5.js/wiki/Local-server\"> local server</a> is recommended when loading external files."
            +      ],
            +      "returns": "SoundFile: Returns a p5.SoundFile",
            +      "params": {
            +        "path": "String|Array: Path to the sound file, or an array with  paths to soundfiles in multiple formats  i.e. ['sound.ogg', 'sound.mp3'].  Alternately, accepts an object: either  from the HTML5 File API, or a p5.File.",
            +        "successCallback": "Function: (Optional) Name of a function to call once file loads",
            +        "errorCallback": "Function: (Optional) Name of a function to call if there is  an error loading the file.",
            +        "whileLoading": "Function: (Optional) Name of a function to call while file is loading.  This function will receive the percentage loaded  so far, from 0.0 to 1.0."
            +      }
            +    },
            +    "createConvolver": {
            +      "description": [
            +        "Create a p5.Convolver. Accepts a path to a soundfile that will be used to generate an impulse response."
            +      ],
            +      "returns": "p5.Convolver:",
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: (Optional) function to call if loading is successful.  The object will be passed in as the argument  to the callback function.",
            +        "errorCallback": "Function: (Optional) function to call if loading is not successful.  A custom error will be passed in as the argument  to the callback function."
            +      }
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the global tempo, in beats per minute, for all p5.Parts. This method will impact all active p5.Parts."
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.Color": {
            +    "description": [
            +      "Each color stores the color mode and level maxes that was applied at the time of its construction. These are used to interpret the input arguments (at construction and later for that instance of color) and to format the output e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.",
            +      "Internally, we store an array representing the ideal RGBA values in floating point form, normalized from 0 to 1. From this we calculate the closest screen color (RGBA levels from 0 to 255) and expose this to the renderer.",
            +      "We also cache normalized, floating point components of the color in various representations as they are calculated. This is done to prevent repeating a conversion that has already been performed."
            +    ],
            +    "toString": {
            +      "description": [
            +        "This function returns the color formatted as a string. This can be useful for debugging, or for using p5.js with other libraries."
            +      ],
            +      "returns": "String: the formatted string",
            +      "params": {
            +        "format": "String: (Optional) How the color string will be formatted. Leaving this empty formats the string as rgba(r, g, b, a). '#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes. 'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode. 'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels. 'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages."
            +      }
            +    },
            +    "setRed": {
            +      "description": [
            +        "The setRed function sets the red component of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "red": "Number: the new red value"
            +      }
            +    },
            +    "setGreen": {
            +      "description": [
            +        "The setGreen function sets the green component of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "green": "Number: the new green value"
            +      }
            +    },
            +    "setBlue": {
            +      "description": [
            +        "The setBlue function sets the blue component of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "blue": "Number: the new blue value"
            +      }
            +    },
            +    "setAlpha": {
            +      "description": [
            +        "The setAlpha function sets the transparency (alpha) value of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "alpha": "Number: the new alpha value"
            +      }
            +    }
            +  },
            +  "p5.Element": {
            +    "description": [
            +      "Base class for all elements added to a sketch, including canvas, graphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a> objects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>, <a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped",
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "elt": {
            +      "description": [
            +        "Underlying HTML element. All normal HTML methods can be called on this."
            +      ]
            +    },
            +    "parent": {
            +      "description": [
            +        "Attaches the element to the parent specified. A way of setting  the container for the element. Accepts either a string ID, DOM  node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.  For more ways to position the canvas, see the  <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>  positioning the canvas</a> wiki page."
            +      ],
            +      "params": {
            +        "parent": "String|p5.Element|Object: the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>  of desired parent element"
            +      }
            +    },
            +    "id": {
            +      "description": [
            +        "Sets the ID of the element. If no ID argument is passed in, it instead  returns the current ID of the element.  Note that only one element can have a particular id in a page.  The <a href=\"#/p5.Element/class\">.class()</a> function can be used  to identify multiple elements with the same class name."
            +      ],
            +      "params": {
            +        "id": "String: ID of the element"
            +      }
            +    },
            +    "class": {
            +      "description": [
            +        "Adds given class to the element. If no class argument is passed in, it  instead returns a string containing the current class(es) of the element."
            +      ],
            +      "params": {
            +        "class": "String: class to add"
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called once after every time a mouse button is pressed over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  pressed over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a mouse button is pressed twice over the element. This can be used to attach element and action specific event listeners."
            +      ],
            +      "returns": "p5.Element:",
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  double clicked over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners.",
            +        "The function accepts a callback function as argument which will be executed when the <code>wheel</code> event is triggered on the element, the callback function is passed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code> except it reads the horizontal wheel scroll of the mouse wheel.",
            +        "On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are reversed."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  scrolled over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is called once after every time a mouse button is released over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  released over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is called once after a mouse button is pressed and released over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap.This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  clicked over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a mouse moves over the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse moves  over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseOver": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a mouse moves onto the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse moves  onto the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseOut": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a mouse moves off the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse  moves off of an element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch  starts over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch moves over  the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch ends  over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "dragOver": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a file is dragged over the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a file is  dragged over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "dragLeave": {
            +      "description": [
            +        "The .dragLeave() function is called once after every time a dragged file leaves the element area. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a file is  dragged off the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "addClass": {
            +      "description": [
            +        "Adds specified class to the element."
            +      ],
            +      "params": {
            +        "class": "String: name of class to add"
            +      }
            +    },
            +    "removeClass": {
            +      "description": [
            +        "Removes specified class from the element."
            +      ],
            +      "params": {
            +        "class": "String: name of class to remove"
            +      }
            +    },
            +    "hasClass": {
            +      "description": [
            +        "Checks if specified class already set to element"
            +      ],
            +      "returns": "Boolean: a boolean value if element has specified class",
            +      "params": {
            +        "c": "String: class name of class to check"
            +      }
            +    },
            +    "toggleClass": {
            +      "description": [
            +        "Toggles element class"
            +      ],
            +      "params": {
            +        "c": "String: class name to toggle"
            +      }
            +    },
            +    "child": {
            +      "description": [
            +        "Attaches the element as a child to the parent specified.  Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.  If no argument is specified, an array of children DOM nodes is returned."
            +      ],
            +      "returns": "Node[]: an array of child nodes",
            +      "params": {
            +        "child": "String|p5.Element: (Optional) the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>  to add to the current element"
            +      }
            +    },
            +    "center": {
            +      "description": [
            +        "Centers a p5 Element either vertically, horizontally, or both, relative to its parent or according to the body if the Element has no parent. If no argument is passed the Element is aligned both vertically and horizontally."
            +      ],
            +      "params": {
            +        "align": "String: (Optional) passing 'vertical', 'horizontal' aligns element accordingly"
            +      }
            +    },
            +    "html": {
            +      "description": [
            +        "If an argument is given, sets the inner HTML of the element,  replacing any existing html. If true is included as a second  argument, html is appended instead of replacing existing html.  If no arguments are given, returns  the inner HTML of the element."
            +      ],
            +      "returns": "String: the inner HTML of the element",
            +      "params": {
            +        "html": "String: (Optional) the HTML to be placed inside the element",
            +        "append": "Boolean: (Optional) whether to append HTML to existing"
            +      }
            +    },
            +    "position": {
            +      "description": [
            +        "Sets the position of the element. If no position type argument is given, the  position will be relative to (0, 0) of the window.  Essentially, this sets position:absolute and left and top  properties of style. If an optional third argument specifying position type is given,  the x and y coordinates will be interpreted based on the <a target=\"_blank\"  href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.  If no arguments given, the function returns the x and y position of the element. found documentation on how to be more specific with object type  <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a>"
            +      ],
            +      "returns": "Object: object of form { x: 0, y: 0 } containing the position of the element in an object",
            +      "params": {
            +        "x": "Number: (Optional) x-position relative to upper left of window (optional)",
            +        "y": "Number: (Optional) y-position relative to upper left of window (optional)",
            +        "positionType": "String: (Optional) it can be static, fixed, relative, sticky, initial or inherit (optional)"
            +      }
            +    },
            +    "style": {
            +      "description": [
            +        "Sets the given style (css) property (1st arg) of the element with the given value (2nd arg). If a single argument is given, .style() returns the value of the given property; however, if the single argument is given in css syntax ('text-align:center'), .style() sets the css appropriately."
            +      ],
            +      "returns": "String: value of property",
            +      "params": {
            +        "property": "String: property to be set",
            +        "value": "String|p5.Color: value to assign to property"
            +      }
            +    },
            +    "attribute": {
            +      "description": [
            +        "Adds a new attribute or changes the value of an existing attribute  on the specified element. If no value is specified, returns the  value of the given attribute, or null if attribute is not set."
            +      ],
            +      "returns": "String: value of attribute",
            +      "params": {
            +        "attr": "String: attribute to set",
            +        "value": "String: value to assign to attribute"
            +      }
            +    },
            +    "removeAttribute": {
            +      "description": [
            +        "Removes an attribute on the specified element."
            +      ],
            +      "params": {
            +        "attr": "String: attribute to remove"
            +      }
            +    },
            +    "value": {
            +      "description": [
            +        "Either returns the value of the element if no arguments given, or sets the value of the element."
            +      ],
            +      "returns": "String|Number: value of the element",
            +      "params": {
            +        "value": "String|Number"
            +      }
            +    },
            +    "show": {
            +      "description": [
            +        "Shows the current element. Essentially, setting display:block for the style."
            +      ]
            +    },
            +    "hide": {
            +      "description": [
            +        "Hides the current element. Essentially, setting display:none for the style."
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "Sets the width and height of the element. AUTO can be used to  only adjust one dimension at a time. If no arguments are given, it  returns the width and height of the element in an object. In case of  elements which need to be loaded, such as images, it is recommended  to call the function after the element has finished loading."
            +      ],
            +      "returns": "Object: the width and height of the element in an object",
            +      "params": {
            +        "w": "Number|Constant: width of the element, either AUTO, or a number",
            +        "h": "Number|Constant: (Optional) height of the element, either AUTO, or a number"
            +      }
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the element, stops all media streams, and deregisters all listeners."
            +      ]
            +    },
            +    "drop": {
            +      "description": [
            +        "Registers a callback that gets called every time a file that is dropped on the element has been loaded. p5 will load every dropped file into memory and pass it as a p5.File object to the callback. Multiple files dropped at the same time will result in multiple calls to the callback.",
            +        "You can optionally pass a second callback which will be registered to the raw <a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event. The callback will thus be provided the original <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>. Dropping multiple files at the same time will trigger the second callback once per drop, whereas the first callback will trigger for each loaded file."
            +      ],
            +      "params": {
            +        "callback": "Function: callback to receive loaded file, called for each file dropped.",
            +        "fxn": "Function: (Optional) callback triggered once when files are dropped with the drop event."
            +      }
            +    }
            +  },
            +  "p5.Graphics": {
            +    "description": [
            +      "Thin wrapper around a renderer, to be used for creating a graphics buffer object. Use this class if you need to draw into an off-screen graphics buffer. The two parameters define the width and height in pixels. The fields and methods for this class are extensive, but mirror the normal drawing API for p5."
            +    ],
            +    "params": {
            +      "w": "Number: width",
            +      "h": "Number: height",
            +      "renderer": "Constant: the renderer to use, either P2D or WEBGL",
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "reset": {
            +      "description": [
            +        "Resets certain values such as those modified by functions in the Transform category and in the Lights category that are not automatically reset with graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior of the standard canvas."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes a Graphics object from the page and frees any resources associated with it."
            +      ]
            +    }
            +  },
            +  "p5.Renderer": {
            +    "description": [
            +      "Main graphics and rendering context, as well as the base API implementation for p5.js \"core\". To be used as the superclass for Renderer2D and Renderer3D classes, respectively."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped",
            +      "pInst": "P5: (Optional) pointer to p5 instance",
            +      "isMainCanvas": "Boolean: (Optional) whether we're using it as main canvas"
            +    }
            +  },
            +  "JSON": {
            +    "stringify": {
            +      "description": [
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>: The JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>."
            +      ],
            +      "params": {
            +        "object": "Object: :Javascript object that you would like to convert to JSON"
            +      }
            +    }
            +  },
            +  "console": {
            +    "log": {
            +      "description": [
            +        "Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a> and <a href=\"#/p5/console/log\">console.log</a> interchangeably.",
            +        "The console is opened differently depending on which browser you are using. Here are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a> , <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>, and <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>. With the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console is embedded directly in the page underneath the code editor.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>: The Console method log() outputs a message to the web console. The message may be a single <a href=\"#/p5/string\">string</a> (with optional substitution values), or it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>."
            +      ],
            +      "params": {
            +        "message": "String|Expression|Object: :Message that you would like to print to the console"
            +      }
            +    }
            +  },
            +  "p5.TypedDict": {
            +    "description": [
            +      "Base class for all p5.Dictionary types. Specifically  typed Dictionary classes inherit from this class."
            +    ],
            +    "size": {
            +      "description": [
            +        "Returns the number of key-value pairs currently stored in the Dictionary."
            +      ],
            +      "returns": "Integer: the number of key-value pairs in the Dictionary"
            +    },
            +    "hasKey": {
            +      "description": [
            +        "Returns true if the given key exists in the Dictionary, otherwise returns false."
            +      ],
            +      "returns": "Boolean: whether that key exists in Dictionary",
            +      "params": {
            +        "key": "Number|String: that you want to look up"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Returns the value stored at the given key."
            +      ],
            +      "returns": "Number|String: the value stored at that key",
            +      "params": {
            +        "the": "Number|String: key you want to access"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Updates the value associated with the given key in case it already exists in the Dictionary. Otherwise a new key-value pair is added."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String"
            +      }
            +    },
            +    "create": {
            +      "description": [
            +        "Creates a new key-value pair in the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String",
            +        "obj": "Object: key/value pair"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Removes all previously stored key-value pairs from the Dictionary."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the key-value pair stored at the given key from the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String: for the pair to remove"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Logs the set of items currently stored in the Dictionary to the console."
            +      ]
            +    },
            +    "saveTable": {
            +      "description": [
            +        "Converts the Dictionary into a CSV file for local download."
            +      ]
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "Converts the Dictionary into a JSON file for local download."
            +      ]
            +    }
            +  },
            +  "p5.StringDict": {
            +    "description": [
            +      "A simple Dictionary class for Strings."
            +    ]
            +  },
            +  "p5.NumberDict": {
            +    "description": [
            +      "A simple Dictionary class for Numbers."
            +    ],
            +    "add": {
            +      "description": [
            +        "Add the given number to the value currently stored at the given key. The sum then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to add to",
            +        "Number": "Number: to add to the value"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtract the given number from the value currently stored at the given key. The difference then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to subtract from",
            +        "Number": "Number: to subtract from the value"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the given number with the value currently stored at the given key. The product then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to multiply",
            +        "Amount": "Number: to multiply the value by"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Divide the given number with the value currently stored at the given key. The quotient then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to divide",
            +        "Amount": "Number: to divide the value by"
            +      }
            +    },
            +    "minValue": {
            +      "description": [
            +        "Return the lowest number currently stored in the Dictionary."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "maxValue": {
            +      "description": [
            +        "Return the highest number currently stored in the Dictionary."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "minKey": {
            +      "description": [
            +        "Return the lowest key currently used in the Dictionary."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "maxKey": {
            +      "description": [
            +        "Return the highest key currently used in the Dictionary."
            +      ],
            +      "returns": "Number:"
            +    }
            +  },
            +  "p5.MediaElement": {
            +    "description": [
            +      "Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods of <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not called directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>, <a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped"
            +    },
            +    "src": {
            +      "description": [
            +        "Path to the media element source."
            +      ],
            +      "returns": "String: src"
            +    },
            +    "play": {
            +      "description": [
            +        "Play an HTML5 media element."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stops an HTML5 media element (sets current time to zero)."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses an HTML5 media element."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Set 'loop' to true for an HTML5 media element, and starts playing."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Set 'loop' to false for an HTML5 media element. Element will stop when it reaches the end."
            +      ]
            +    },
            +    "autoplay": {
            +      "description": [
            +        "Set HTML5 media element to autoplay or not. If no argument is specified, by default it will autoplay."
            +      ],
            +      "params": {
            +        "shouldAutoplay": "Boolean: whether the element should autoplay"
            +      }
            +    },
            +    "volume": {
            +      "description": [
            +        "Sets volume for this HTML5 media element. If no argument is given, returns the current volume."
            +      ],
            +      "returns": "Number: current volume",
            +      "params": {
            +        "val": "Number: volume between 0.0 and 1.0"
            +      }
            +    },
            +    "speed": {
            +      "description": [
            +        "If no arguments are given, returns the current playback speed of the element. The speed parameter sets the speed where 2.0 will play the element twice as fast, 0.5 will play at half the speed, and -1 will play the element in normal speed in reverse.(Note that not all browsers support backward playback and even if they do, playback might not be smooth.)"
            +      ],
            +      "returns": "Number: current playback speed of the element",
            +      "params": {
            +        "speed": "Number: speed multiplier for element playback"
            +      }
            +    },
            +    "time": {
            +      "description": [
            +        "If no arguments are given, returns the current time of the element. If an argument is given the current time of the element is set to it."
            +      ],
            +      "returns": "Number: current time (in seconds)",
            +      "params": {
            +        "time": "Number: time to jump to (in seconds)"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of the HTML5 media element."
            +      ],
            +      "returns": "Number: duration"
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the audio or video element reaches the end. If the element is looping, this will not be called. The element is passed in as the argument to the onended callback."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended. The  media element will be passed  in as the argument to the  callback."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send the audio output of this element to a specified audioNode or p5.sound object. If no element is provided, connects to p5's main output. That connection is established when this method is first called. All connections are removed by the .disconnect() method.",
            +        "This method is meant to be used with the p5.sound.js addon library."
            +      ],
            +      "params": {
            +        "audioNode": "AudioNode|Object: AudioNode from the Web Audio API, or an object from the p5.sound library"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all Web Audio routing, including to main output. This is useful if you want to re-route the output through audio effects, for example."
            +      ]
            +    },
            +    "showControls": {
            +      "description": [
            +        "Show the default MediaElement controls, as determined by the web browser."
            +      ]
            +    },
            +    "hideControls": {
            +      "description": [
            +        "Hide the default mediaElement controls."
            +      ]
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point.",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback.",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    }
            +  },
            +  "p5.File": {
            +    "description": [
            +      "Base class for a file. Used for Element.drop and createFileInput."
            +    ],
            +    "params": {
            +      "file": "File: File that is wrapped"
            +    },
            +    "file": {
            +      "description": [
            +        "Underlying File object. All normal File methods can be called on this."
            +      ]
            +    },
            +    "type": {
            +      "description": [
            +        "File type (image, text, etc.)"
            +      ]
            +    },
            +    "subtype": {
            +      "description": [
            +        "File subtype (usually the file extension jpg, png, xml, etc.)"
            +      ]
            +    },
            +    "name": {
            +      "description": [
            +        "File name"
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "File size"
            +      ]
            +    },
            +    "data": {
            +      "description": [
            +        "URL string containing either image data, the text contents of the file or a parsed object if file is JSON and p5.XML if XML"
            +      ]
            +    }
            +  },
            +  "p5.Image": {
            +    "description": [
            +      "Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an image.",
            +      "p5 can display .gif, .jpg and .png images. Images may be displayed in 2D and 3D space. Before an image is used, it must be loaded with the <a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and height of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the values for every pixel in the image.",
            +      "The methods described below allow easy access to the image's pixels and alpha channel and simplify the process of compositing.",
            +      "Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on the image to make sure that the pixel data is properly loaded."
            +    ],
            +    "params": {
            +      "width": "Number",
            +      "height": "Number"
            +    },
            +    "width": {
            +      "description": [
            +        "Image width."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "Image height."
            +      ]
            +    },
            +    "pixels": {
            +      "description": [
            +        "Array containing the values for all the pixels in the display window. These values are numbers. This array is the size (include an appropriate factor for pixelDensity) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. Retina and other high density displays may have more pixels (by a factor of pixelDensity^2). For example, if the image is 100×100 pixels, there will be 40,000. With pixelDensity = 2, there will be 160,000. The first four values (indices 0-3) in the array will be the R, G, B, A values of the pixel at (0, 0). The second four values (indices 4-7) will contain the R, G, B, A values of the pixel at (1, 0). More generally, to set values for a pixel at (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre>",
            +        "Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes."
            +      ]
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "Loads the pixels data for this image into the [pixels] attribute."
            +      ]
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "Updates the backing canvas for this image with the contents of the [pixels] array.",
            +        "If this image is an animated GIF then the pixels will be updated in the frame that is currently displayed."
            +      ],
            +      "params": {
            +        "x": "Integer: x-offset of the target update area for the  underlying canvas",
            +        "y": "Integer: y-offset of the target update area for the  underlying canvas",
            +        "w": "Integer: height of the target update area for the  underlying canvas",
            +        "h": "Integer: height of the target update area for the  underlying canvas"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Get a region of pixels from an image.",
            +        "If no params are passed, the whole image is returned. If x and y are the only params passed a single pixel is extracted. If all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a> is returned."
            +      ],
            +      "returns": "p5.Image: the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "w": "Number: width",
            +        "h": "Number: height"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the color of a single pixel or write an image into this <a href=\"#/p5.Image\">p5.Image</a>.",
            +        "Note that for a large number of pixels this will be slower than directly manipulating the pixels array and then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "a": "Number|Number[]|Object: grayscale value | pixel array |  a <a href=\"#/p5.Color\">p5.Color</a> | image to copy"
            +      }
            +    },
            +    "resize": {
            +      "description": [
            +        "Resize the image to a new width and height. To make the image scale proportionally, use 0 as the value for the wide or high parameter. For instance, to make the width of an image 150 pixels, and change the height using the same proportion, use resize(150, 0)."
            +      ],
            +      "params": {
            +        "width": "Number: the resized image width",
            +        "height": "Number: the resized image height"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Copies a region of pixels from one image to another. If no srcImage is specified this is used as the source. If the source and destination regions aren't the same size, it will automatically resize source pixels to fit the specified target region."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5.Element: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height"
            +      }
            +    },
            +    "mask": {
            +      "description": [
            +        "Masks part of an image from displaying by loading another image and using its alpha channel as an alpha channel for this image. Masks are cumulative, one applied to an image object, they cannot be removed."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a>",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used.",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used.",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used.",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges.",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur.",
            +        "ERODE Reduces the light areas. No parameter is used.",
            +        "DILATE Increases the light areas. No parameter is used.",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "Constant: either THRESHOLD, GRAY, OPAQUE, INVERT,  POSTERIZE, ERODE, DILATE or BLUR.  See Filters.js for docs on  each available filter",
            +        "filterParam": "Number: (Optional) an optional parameter unique  to each filter, see above"
            +      }
            +    },
            +    "blend": {
            +      "description": [
            +        "Copies a region of pixels from one image to another, using a specified blend mode to do the operation."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height",
            +        "blendMode": "Constant: the blend mode. either  BLEND, DARKEST, LIGHTEST, DIFFERENCE,  MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD or NORMAL. Available blend modes are: normal | multiply | screen | overlay |  darken | lighten | color-dodge | color-burn | hard-light |  soft-light | difference | exclusion | hue | saturation |  color | luminosity <a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a>"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "Saves the image to a file and force the browser to download it. Accepts two strings for filename and file extension Supports png (default), jpg, and gif  Note that the file will only be downloaded as an animated GIF if the p5.Image was loaded from a GIF file."
            +      ],
            +      "params": {
            +        "filename": "String: give your file a name",
            +        "extension": "String: 'png' or 'jpg'"
            +      }
            +    },
            +    "reset": {
            +      "description": [
            +        "Starts an animated GIF over at the beginning state."
            +      ]
            +    },
            +    "getCurrentFrame": {
            +      "description": [
            +        "Gets the index for the frame that is currently visible in an animated GIF."
            +      ],
            +      "returns": "Number: The index for the currently displaying frame in animated GIF"
            +    },
            +    "setFrame": {
            +      "description": [
            +        "Sets the index of the frame that is currently visible in an animated GIF"
            +      ],
            +      "params": {
            +        "index": "Number: the index for the frame that should be displayed"
            +      }
            +    },
            +    "numFrames": {
            +      "description": [
            +        "Returns the number of frames in an animated GIF"
            +      ],
            +      "returns": "Number:"
            +    },
            +    "play": {
            +      "description": [
            +        "Plays an animated GIF that was paused with <a href=\"#/p5.Image/pause\">pause()</a>"
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses an animated GIF."
            +      ]
            +    },
            +    "delay": {
            +      "description": [
            +        "Changes the delay between frames in an animated GIF. There is an optional second parameter that indicates an index for a specific frame that should have its delay modified. If no index is given, all frames will have the new delay."
            +      ],
            +      "params": {
            +        "d": "Number: the amount in milliseconds to delay between switching frames",
            +        "index": "Number: (Optional) the index of the frame that should have the new delay value {optional}"
            +      }
            +    }
            +  },
            +  "p5.PrintWriter": {
            +    "params": {
            +      "filename": "String",
            +      "extension": "String (Optional)"
            +    },
            +    "write": {
            +      "description": [
            +        "Writes data to the PrintWriter stream"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be written by the PrintWriter"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Writes data to the PrintWriter stream, and adds a new line at the end"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be printed by the PrintWriter"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Clears the data already written to the PrintWriter object"
            +      ]
            +    },
            +    "close": {
            +      "description": [
            +        "Closes the PrintWriter"
            +      ]
            +    }
            +  },
            +  "p5.Table": {
            +    "description": [
            +      "<a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much like in a traditional spreadsheet. Tables can be generated from scratch, dynamically, or using data from an existing file."
            +    ],
            +    "params": {
            +      "rows": "p5.TableRow[]: (Optional) An array of p5.TableRow objects"
            +    },
            +    "columns": {
            +      "description": [
            +        "An array containing the names of the columns in the table, if the \"header\" the table is loaded with the \"header\" parameter."
            +      ]
            +    },
            +    "rows": {
            +      "description": [
            +        "An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the rows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a>"
            +      ]
            +    },
            +    "addRow": {
            +      "description": [
            +        "Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default, an empty row is created. Typically, you would store a reference to the new row in a TableRow object (see newRow in the example above), and then set individual values using <a href=\"#/p5/set\">set()</a>.",
            +        "If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is duplicated and added to the table."
            +      ],
            +      "returns": "p5.TableRow: the row that was added",
            +      "params": {
            +        "row": "p5.TableRow: (Optional) row to be added to the table"
            +      }
            +    },
            +    "removeRow": {
            +      "description": [
            +        "Removes a row from the table object."
            +      ],
            +      "params": {
            +        "id": "Integer: ID number of the row to remove"
            +      }
            +    },
            +    "getRow": {
            +      "description": [
            +        "Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference can then be used to get and set values of the selected row."
            +      ],
            +      "returns": "p5.TableRow: <a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +      "params": {
            +        "rowID": "Integer: ID number of the row to get"
            +      }
            +    },
            +    "getRows": {
            +      "description": [
            +        "Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s."
            +      ],
            +      "returns": "p5.TableRow[]: Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s"
            +    },
            +    "findRow": {
            +      "description": [
            +        "Finds the first row in the Table that contains the value provided, and returns a reference to that row. Even if multiple rows are possible matches, only the first matching row is returned. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow:",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "findRows": {
            +      "description": [
            +        "Finds the rows in the Table that contain the value provided, and returns references to those rows. Returns an Array, so for must be used to iterate through all the rows, as shown in the example above. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "matchRow": {
            +      "description": [
            +        "Finds the first row in the Table that matches the regular expression provided, and returns a reference to that row. Even if multiple rows are possible matches, only the first matching row is returned. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow: TableRow object",
            +      "params": {
            +        "regexp": "String|RegExp: The regular expression to match",
            +        "column": "String|Integer: The column ID (number) or  title (string)"
            +      }
            +    },
            +    "matchRows": {
            +      "description": [
            +        "Finds the rows in the Table that match the regular expression provided, and returns references to those rows. Returns an array, so for must be used to iterate through all the rows, as shown in the example. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "regexp": "String: The regular expression to match",
            +        "column": "String|Integer: (Optional) The column ID (number) or  title (string)"
            +      }
            +    },
            +    "getColumn": {
            +      "description": [
            +        "Retrieves all values in the specified column, and returns them as an array. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "Array: Array of column values",
            +      "params": {
            +        "column": "String|Number: String or Number of the column to return"
            +      }
            +    },
            +    "clearRows": {
            +      "description": [
            +        "Removes all rows from a Table. While all rows are removed, columns and column titles are maintained."
            +      ]
            +    },
            +    "addColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object. Typically, you will want to specify a title, so the column may be easily referenced later by name. (If no title is specified, the new column's title will be null.)"
            +      ],
            +      "params": {
            +        "title": "String: (Optional) title of the given column"
            +      }
            +    },
            +    "getColumnCount": {
            +      "description": [
            +        "Returns the total number of columns in a Table."
            +      ],
            +      "returns": "Integer: Number of columns in this table"
            +    },
            +    "getRowCount": {
            +      "description": [
            +        "Returns the total number of rows in a Table."
            +      ],
            +      "returns": "Integer: Number of rows in this table"
            +    },
            +    "removeTokens": {
            +      "description": [
            +        "Removes any of the specified characters (or \"tokens\").",
            +        "If no column is specified, then the values in all columns and rows are processed. A specific column may be referenced by either its ID or title."
            +      ],
            +      "params": {
            +        "chars": "String: String listing characters to be removed",
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "Trims leading and trailing whitespace, such as spaces and tabs, from String table values. If no column is specified, then the values in all columns and rows are trimmed. A specific column may be referenced by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "removeColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table object. The column to be removed may be identified by either its title (a String) or its index value (an int). removeColumn(0) would remove the first column, removeColumn(1) would remove the second column, and so on."
            +      ],
            +      "params": {
            +        "column": "String|Integer: columnName (string) or ID (number)"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Stores a value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String|Number: value to assign"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Stores a Float value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "Number: value to assign"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Stores a String value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String: value to assign"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retrieves a value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "String|Number:",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Retrieves a Float value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "Number:",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Retrieves a String value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "String:",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getObject": {
            +      "description": [
            +        "Retrieves all table data and returns as an object. If a column name is passed in, each row object will be stored with that attribute as its title."
            +      ],
            +      "returns": "Object:",
            +      "params": {
            +        "headerColumn": "String: (Optional) Name of the column which should be used to  title each row object (optional)"
            +      }
            +    },
            +    "getArray": {
            +      "description": [
            +        "Retrieves all table data and returns it as a multidimensional array."
            +      ],
            +      "returns": "Array:"
            +    }
            +  },
            +  "p5.TableRow": {
            +    "description": [
            +      "A TableRow object represents a single row of data values, stored in columns, from a table.",
            +      "A Table Row contains both an ordered array, and an unordered JSON object."
            +    ],
            +    "params": {
            +      "str": "String: (Optional) optional: populate the row with a  string of values, separated by the  separator",
            +      "separator": "String: (Optional) comma separated values (csv) by default"
            +    },
            +    "set": {
            +      "description": [
            +        "Stores a value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number: The value to be stored"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Stores a Float value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "Number|String: The value to be stored  as a Float"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Stores a String value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number|Boolean|Object: The value to be stored  as a String"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retrieves a value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String|Number:",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Retrieves a Float value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "Number: Float Floating point number",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Retrieves an String value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String: String",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    }
            +  },
            +  "p5.XML": {
            +    "description": [
            +      "XML is a representation of an XML object, able to parse XML code. Use <a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects."
            +    ],
            +    "getParent": {
            +      "description": [
            +        "Gets a copy of the element's parent. Returns the parent as another <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "returns": "p5.XML: element parent"
            +    },
            +    "getName": {
            +      "description": [
            +        "Gets the element's full name, which is returned as a String."
            +      ],
            +      "returns": "String: the name of the node"
            +    },
            +    "setName": {
            +      "description": [
            +        "Sets the element's name, which is specified as a String."
            +      ],
            +      "params": {
            +        "the": "String: new name of the node"
            +      }
            +    },
            +    "hasChildren": {
            +      "description": [
            +        "Checks whether or not the element has any children, and returns the result as a boolean."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "listChildren": {
            +      "description": [
            +        "Get the names of all of the element's children, and returns the names as an array of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a> on each child element individually."
            +      ],
            +      "returns": "String[]: names of the children of the element"
            +    },
            +    "getChildren": {
            +      "description": [
            +        "Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When the name parameter is specified, then it will return all children that match that name."
            +      ],
            +      "returns": "p5.XML[]: children of the element",
            +      "params": {
            +        "name": "String: (Optional) element name"
            +      }
            +    },
            +    "getChild": {
            +      "description": [
            +        "Returns the first of the element's children that matches the name parameter or the child of the given index.It returns undefined if no matching child is found."
            +      ],
            +      "returns": "p5.XML:",
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "addChild": {
            +      "description": [
            +        "Appends a new child to the element. The child can be specified with either a String, which will be used as the new tag's name, or as a reference to an existing <a href=\"#/p5.XML\">p5.XML</a> object. A reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "params": {
            +        "node": "p5.XML: a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added"
            +      }
            +    },
            +    "removeChild": {
            +      "description": [
            +        "Removes the element specified by name or index."
            +      ],
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "getAttributeCount": {
            +      "description": [
            +        "Counts the specified element's number of attributes, returned as an Number."
            +      ],
            +      "returns": "Integer:"
            +    },
            +    "listAttributes": {
            +      "description": [
            +        "Gets all of the specified element's attributes, and returns them as an array of Strings."
            +      ],
            +      "returns": "String[]: an array of strings containing the names of attributes"
            +    },
            +    "hasAttribute": {
            +      "description": [
            +        "Checks whether or not an element has the specified attribute."
            +      ],
            +      "returns": "Boolean: true if attribute found else false",
            +      "params": {
            +        "the": "String: attribute to be checked"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Returns an attribute value of the element as an Number. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, the value 0 is returned."
            +      ],
            +      "returns": "Number:",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Returns an attribute value of the element as an String. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, null is returned."
            +      ],
            +      "returns": "String:",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "setAttribute": {
            +      "description": [
            +        "Sets the content of an element's attribute. The first parameter specifies the attribute name, while the second specifies the new content."
            +      ],
            +      "params": {
            +        "name": "String: the full name of the attribute",
            +        "value": "Number|String|Boolean: the value of the attribute"
            +      }
            +    },
            +    "getContent": {
            +      "description": [
            +        "Returns the content of an element. If there is no such content, defaultValue is returned if specified, otherwise null is returned."
            +      ],
            +      "returns": "String:",
            +      "params": {
            +        "defaultValue": "String: (Optional) value returned if no content is found"
            +      }
            +    },
            +    "setContent": {
            +      "description": [
            +        "Sets the element's content."
            +      ],
            +      "params": {
            +        "text": "String: the new content"
            +      }
            +    },
            +    "serialize": {
            +      "description": [
            +        "Serializes the element into a string. This function is useful for preparing the content to be sent over a http request or saved to file."
            +      ],
            +      "returns": "String: Serialized string of the element"
            +    }
            +  },
            +  "p5.Vector": {
            +    "description": [
            +      "A class to describe a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector. A vector is an entity that has both magnitude and direction. The datatype, however, stores the components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude and direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.",
            +      "In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a position, velocity, or acceleration. For example, if you consider a rectangle moving across the screen, at any given instant it has a position (a vector that points from the origin to its location), a velocity (the rate at which the object's position changes per time unit, expressed as a vector), and acceleration (the rate at which the object's velocity changes per time unit, expressed as a vector).",
            +      "Since vectors represent groupings of values, we cannot simply use traditional addition/multiplication/etc. Instead, we'll need to do some \"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class."
            +    ],
            +    "params": {
            +      "x": "Number: (Optional) x component of the vector",
            +      "y": "Number: (Optional) y component of the vector",
            +      "z": "Number: (Optional) z component of the vector"
            +    },
            +    "x": {
            +      "description": [
            +        "The x component of the vector"
            +      ]
            +    },
            +    "y": {
            +      "description": [
            +        "The y component of the vector"
            +      ]
            +    },
            +    "z": {
            +      "description": [
            +        "The z component of the vector"
            +      ]
            +    },
            +    "toString": {
            +      "description": [
            +        "Returns a string representation of a vector v by calling String(v) or v.toString(). This method is useful for logging vectors in the console."
            +      ],
            +      "returns": "String:"
            +    },
            +    "set": {
            +      "description": [
            +        "Sets the x, y, and z component of the vector using two or three separate variables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array."
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) the x component of the vector",
            +        "y": "Number: (Optional) the y component of the vector",
            +        "z": "Number: (Optional) the z component of the vector",
            +        "value": "p5.Vector|Number[]: the vector to set"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object."
            +      ],
            +      "returns": "p5.Vector: the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    },
            +    "add": {
            +      "description": [
            +        "Adds x, y, and z components to a vector, adds one vector to another, or adds two independent vectors together. The version of the method that adds two vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to be added",
            +        "y": "Number: (Optional) the y component of the vector to be added",
            +        "z": "Number: (Optional) the z component of the vector to be added",
            +        "value": "p5.Vector|Number[]: the vector to add",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "rem": {
            +      "description": [
            +        "Gives remainder of a vector when it is divided by another vector. See examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of divisor vector",
            +        "y": "Number: the y component of divisor vector",
            +        "z": "Number: the z component of divisor vector",
            +        "value": "p5.Vector | Number[]: divisor vector",
            +        "v1": "p5.Vector: dividend <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: divisor <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtracts x, y, and z components from a vector, subtracts one vector from another, or subtracts two independent vectors. The version of the method that subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the other acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to subtract",
            +        "y": "Number: (Optional) the y component of the vector to subtract",
            +        "z": "Number: (Optional) the z component of the vector to subtract",
            +        "value": "p5.Vector|Number[]: the vector to subtract",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies the x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y, and z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector, the x, y, z components of both vectors are multiplied by each other (for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method creates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "n": "Number: The number to multiply with the vector",
            +        "x": "Number: The number to multiply with the x component of the vector",
            +        "y": "Number: The number to multiply with the y component of the vector",
            +        "z": "Number: (Optional) The number to multiply with the z component of the vector",
            +        "arr": "Number[]: The array to multiply with the components of the vector",
            +        "v": "p5.Vector: The vector to multiply with the components of the original vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and z components of two vectors against each other. When dividing a vector by a scalar, the x, y, and z components of the vector are all divided by the scalar. When dividing a vector by a vector, the x, y, z components of the source vector are treated as the dividend, and the x, y, z components of the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z). The static version of this method creates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "n": "Number: The number to divide the vector by",
            +        "x": "Number: The number to divide with the x component of the vector",
            +        "y": "Number: The number to divide with the y component of the vector",
            +        "z": "Number: (Optional) The number to divide with the z component of the vector",
            +        "arr": "Number[]: The array to divide the components of the vector by",
            +        "v": "p5.Vector: The vector to divide the components of the original vector by",
            +        "target": "p5.Vector: (Optional) the vector to receive the result",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "Calculates the magnitude (length) of the vector and returns the result as a float (this is simply the equation sqrt(x*x + y*y + z*z).)"
            +      ],
            +      "returns": "Number: magnitude of the vector",
            +      "params": {
            +        "vecT": "p5.Vector: the vector to return the magnitude of"
            +      }
            +    },
            +    "magSq": {
            +      "description": [
            +        "Calculates the squared magnitude of the vector and returns the result as a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.) Faster if the real length is not required in the case of comparing vectors, etc."
            +      ],
            +      "returns": "Number: squared magnitude of the vector"
            +    },
            +    "dot": {
            +      "description": [
            +        "Calculates the dot product of two vectors. The version of the method that computes the dot product of two independent vectors is a static method. See the examples for more context."
            +      ],
            +      "returns": "Number: the dot product",
            +      "params": {
            +        "x": "Number: x component of the vector",
            +        "y": "Number: (Optional) y component of the vector",
            +        "z": "Number: (Optional) z component of the vector",
            +        "value": "p5.Vector: value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "cross": {
            +      "description": [
            +        "Calculates and returns a vector composed of the cross product between two vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>. See the examples for more context."
            +      ],
            +      "returns": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +      "params": {
            +        "v": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> to be crossed",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "Calculates the Euclidean distance between two points (considering a point as a vector object). If you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a>"
            +      ],
            +      "returns": "Number: the distance",
            +      "params": {
            +        "v": "p5.Vector: the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "normalize": {
            +      "description": [
            +        "Normalize the vector to length 1 (make it a unit vector)."
            +      ],
            +      "returns": "p5.Vector: normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +      "params": {
            +        "v": "p5.Vector: the vector to normalize",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "limit": {
            +      "description": [
            +        "Limit the magnitude of this vector to the value used for the <b>max</b> parameter."
            +      ],
            +      "params": {
            +        "max": "Number: the maximum magnitude for the vector"
            +      }
            +    },
            +    "setMag": {
            +      "description": [
            +        "Set the magnitude of this vector to the value used for the <b>len</b> parameter."
            +      ],
            +      "params": {
            +        "len": "Number: the new length for this vector"
            +      }
            +    },
            +    "heading": {
            +      "description": [
            +        "Calculate the angle of rotation for this vector(only 2D vectors). p5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a> will take the current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and give the angle in radians or degree accordingly."
            +      ],
            +      "returns": "Number: the angle of rotation"
            +    },
            +    "setHeading": {
            +      "description": [
            +        "Rotate the vector to a specific angle (only 2D vectors), magnitude remains the same"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation"
            +      }
            +    },
            +    "rotate": {
            +      "description": [
            +        "Rotate the vector by an angle (only 2D vectors), magnitude remains the same"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation",
            +        "v": "p5.Vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "angleBetween": {
            +      "description": [
            +        "Calculates and returns the angle between two vectors. This function will take the current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and give the angle in radians or degree accordingly."
            +      ],
            +      "returns": "Number: the angle between (in radians)",
            +      "params": {
            +        "value": "p5.Vector: the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "Linear interpolate the vector to another vector"
            +      ],
            +      "params": {
            +        "x": "Number: the x component",
            +        "y": "Number: the y component",
            +        "z": "Number: the z component",
            +        "amt": "Number: the amount of interpolation; some value between 0.0  (old vector) and 1.0 (new vector). 0.9 is very near  the new vector. 0.5 is halfway in between.",
            +        "v": "p5.Vector: the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to",
            +        "v1": "p5.Vector",
            +        "v2": "p5.Vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "reflect": {
            +      "description": [
            +        "Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D This method acts on the vector directly"
            +      ],
            +      "params": {
            +        "surfaceNormal": "p5.Vector: the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method"
            +      }
            +    },
            +    "array": {
            +      "description": [
            +        "Return a representation of this vector as a float array. This is only for temporary use. If used in any other fashion, the contents should be copied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own array."
            +      ],
            +      "returns": "Number[]: an Array with the 3 values"
            +    },
            +    "equals": {
            +      "description": [
            +        "Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      ],
            +      "returns": "Boolean: whether the vectors are equals",
            +      "params": {
            +        "x": "Number: (Optional) the x component of the vector",
            +        "y": "Number: (Optional) the y component of the vector",
            +        "z": "Number: (Optional) the z component of the vector",
            +        "value": "p5.Vector|Array: the vector to compare"
            +      }
            +    },
            +    "fromAngle": {
            +      "description": [
            +        "Make a new 2D vector from an angle"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +      "params": {
            +        "angle": "Number: the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)",
            +        "length": "Number: (Optional) the length of the new vector (defaults to 1)"
            +      }
            +    },
            +    "fromAngles": {
            +      "description": [
            +        "Make a new 3D vector from a pair of ISO spherical angles"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +      "params": {
            +        "theta": "Number: the polar angle, in radians (zero is up)",
            +        "phi": "Number: the azimuthal angle, in radians  (zero is out of the screen)",
            +        "length": "Number: (Optional) the length of the new vector (defaults to 1)"
            +      }
            +    },
            +    "random2D": {
            +      "description": [
            +        "Make a new 2D unit vector from a random angle"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    },
            +    "random3D": {
            +      "description": [
            +        "Make a new random 3D unit vector."
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    }
            +  },
            +  "p5.Font": {
            +    "description": [
            +      "Base class for font handling"
            +    ],
            +    "params": {
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "font": {
            +      "description": [
            +        "Underlying opentype font implementation"
            +      ]
            +    },
            +    "textBounds": {
            +      "description": [
            +        "Returns a tight bounding box for the given text string using this font"
            +      ],
            +      "returns": "Object: a rectangle object with properties: x, y, w, h",
            +      "params": {
            +        "line": "String: a line of text",
            +        "x": "Number: x-position",
            +        "y": "Number: y-position",
            +        "fontSize": "Number: (Optional) font size to use (optional) Default is 12.",
            +        "options": "Object: (Optional) opentype options (optional)  opentype fonts contains alignment and baseline options.  Default is 'LEFT' and 'alphabetic'"
            +      }
            +    },
            +    "textToPoints": {
            +      "description": [
            +        "Computes an array of points following the path for specified text"
            +      ],
            +      "returns": "Array: an array of points, each with x, y, alpha (the path angle)",
            +      "params": {
            +        "txt": "String: a line of text",
            +        "x": "Number: x-position",
            +        "y": "Number: y-position",
            +        "fontSize": "Number: font size to use (optional)",
            +        "options": "Object: (Optional) an (optional) object that can contain: sampleFactor - the ratio of path-length to number of samples (default=.1); higher values yield more points and are therefore more precise simplifyThreshold - if set to a non-zero value, collinear points will be be removed from the polygon; the value represents the threshold angle to use when determining whether two edges are collinear"
            +      }
            +    }
            +  },
            +  "p5.Camera": {
            +    "description": [
            +      "This class describes a camera for use in p5's <a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\"> WebGL mode</a>. It contains camera position, orientation, and projection information necessary for rendering a 3D scene.",
            +      "New p5.Camera objects can be made through the <a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through the methods described below. A camera created in this way will use a default position in the scene and a default perspective projection until these properties are changed through the various methods available. It is possible to create multiple cameras, in which case the current camera can be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.",
            +      "Note: The methods below operate in two coordinate systems: the 'world' coordinate system describe positions in terms of their relationship to the origin along the X, Y and Z axes whereas the camera's 'local' coordinate system describes positions from the camera's point of view: left-right, up-down, and forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method, for instance, moves the camera along its own axes, whereas the <a href=\"#/p5.Camera/setPosition\">setPosition()</a> method sets the camera's position in world-space.",
            +      "The camera object propreties <code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code> which describes camera position, orientation, and projection are also accessible via the camera object generated using <a href=\"#/p5/createCamera\">createCamera()</a>"
            +    ],
            +    "params": {
            +      "rendererGL": "RendererGL: instance of WebGL renderer"
            +    },
            +    "eyeX": {
            +      "description": [
            +        "camera position value on x axis"
            +      ]
            +    },
            +    "eyeY": {
            +      "description": [
            +        "camera position value on y axis"
            +      ]
            +    },
            +    "eyeZ": {
            +      "description": [
            +        "camera position value on z axis"
            +      ]
            +    },
            +    "centerX": {
            +      "description": [
            +        "x coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerY": {
            +      "description": [
            +        "y coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerZ": {
            +      "description": [
            +        "z coordinate representing center of the sketch"
            +      ]
            +    },
            +    "upX": {
            +      "description": [
            +        "x component of direction 'up' from camera"
            +      ]
            +    },
            +    "upY": {
            +      "description": [
            +        "y component of direction 'up' from camera"
            +      ]
            +    },
            +    "upZ": {
            +      "description": [
            +        "z component of direction 'up' from camera"
            +      ]
            +    },
            +    "perspective": {
            +      "description": [
            +        "Sets a perspective projection. Accepts the same parameters as the global <a href=\"#/p5/perspective\">perspective()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "ortho": {
            +      "description": [
            +        "Sets an orthographic projection. Accepts the same parameters as the global <a href=\"#/p5/ortho\">ortho()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "frustum": {
            +      "description": [
            +        "Sets the camera's frustum. Accepts the same parameters as the global <a href=\"#/p5/frustum\">frustum()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Panning rotates the camera view to the left and right."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "tilt": {
            +      "description": [
            +        "Tilting rotates the camera view up and down."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "lookAt": {
            +      "description": [
            +        "Reorients the camera to look at a position in world space."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "Sets the camera's position and orientation. Accepts the same parameters as the global <a href=\"#/p5/camera\">camera()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "move": {
            +      "description": [
            +        "Move camera along its local axes while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: amount to move along camera's left-right axis",
            +        "y": "Number: amount to move along camera's up-down axis",
            +        "z": "Number: amount to move along camera's forward-backward axis"
            +      }
            +    },
            +    "setPosition": {
            +      "description": [
            +        "Set camera position in world-space while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    }
            +  },
            +  "p5.Geometry": {
            +    "description": [
            +      "p5 Geometry class"
            +    ],
            +    "params": {
            +      "detailX": "Integer: (Optional) number of vertices along the x-axis.",
            +      "detailY": "Integer: (Optional) number of vertices along the y-axis.",
            +      "callback": "Function: (Optional) function to call upon object instantiation."
            +    },
            +    "computeFaces": {
            +      "description": [
            +        "computes faces for geometry objects based on the vertices."
            +      ]
            +    },
            +    "computeNormals": {
            +      "description": [
            +        "computes smooth normals per vertex as an average of each face."
            +      ]
            +    },
            +    "averageNormals": {
            +      "description": [
            +        "Averages the vertex normals. Used in curved surfaces"
            +      ]
            +    },
            +    "averagePoleNormals": {
            +      "description": [
            +        "Averages pole normals. Used in spherical primitives"
            +      ]
            +    },
            +    "normalize": {
            +      "description": [
            +        "Modifies all vertices to be centered within the range -100 to 100."
            +      ]
            +    }
            +  },
            +  "p5.Shader": {
            +    "description": [
            +      "Shader class for WEBGL Mode"
            +    ],
            +    "params": {
            +      "renderer": "p5.RendererGL: an instance of p5.RendererGL that will provide the GL context for this new p5.Shader",
            +      "vertSrc": "String: source code for the vertex shader (as a string)",
            +      "fragSrc": "String: source code for the fragment shader (as a string)"
            +    },
            +    "setUniform": {
            +      "description": [
            +        "Used to set the uniforms of a <a href=\"#/p5.Shader\">p5.Shader</a> object.",
            +        "Uniforms are used as a way to provide shader programs (which run on the GPU) with values from a sketch (which runs on the CPU)."
            +      ],
            +      "params": {
            +        "uniformName": "String: the name of the uniform. Must correspond to the name used in the vertex and fragment shaders",
            +        "data": "Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture: the data to associate with the uniform. The type can be a boolean (true/false), a number, an array of numbers, or an image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)"
            +      }
            +    }
            +  },
            +  "p5.sound": {},
            +  "p5.SoundFile": {
            +    "description": [
            +      "SoundFile object with a path to a file.",
            +      "The p5.SoundFile may not be available immediately because it loads the file information asynchronously.",
            +      "To do something with the sound as soon as it loads pass the name of a function as the second parameter.",
            +      "Only one file path is required. However, audio file formats (i.e. mp3, ogg, wav and m4a/aac) are not supported by all web browsers. If you want to ensure compatability, instead of a single file path, you may include an Array of filepaths, and the browser will choose a format that works."
            +    ],
            +    "params": {
            +      "path": "String|Array: path to a sound file (String). Optionally,  you may include multiple file formats in  an array. Alternately, accepts an object  from the HTML5 File API, or a p5.File.",
            +      "successCallback": "Function: (Optional) Name of a function to call once file loads",
            +      "errorCallback": "Function: (Optional) Name of a function to call if file fails to  load. This function will receive an error or  XMLHttpRequest object with information  about what went wrong.",
            +      "whileLoadingCallback": "Function: (Optional) Name of a function to call while file  is loading. That function will  receive progress of the request to  load the sound file  (between 0 and 1) as its first  parameter. This progress  does not account for the additional  time needed to decode the audio data."
            +    },
            +    "isLoaded": {
            +      "description": [
            +        "Returns true if the sound file finished loading successfully."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "play": {
            +      "description": [
            +        "Play the p5.SoundFile"
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule playback to start (in seconds from now).",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) amplitude (volume)  of playback",
            +        "cueStart": "Number: (Optional) (optional) cue start time in seconds",
            +        "duration": "Number: (Optional) (optional) duration of playback in seconds"
            +      }
            +    },
            +    "playMode": {
            +      "description": [
            +        "p5.SoundFile has two play modes: <code>restart</code> and <code>sustain</code>. Play Mode determines what happens to a p5.SoundFile if it is triggered while in the middle of playback. In sustain mode, playback will continue simultaneous to the new playback. In restart mode, play() will stop playback and start over. With untilDone, a sound will play only if it's not already playing. Sustain is the default mode."
            +      ],
            +      "params": {
            +        "str": "String: 'restart' or 'sustain' or 'untilDone'"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses a file that is currently playing. If the file is not playing, then nothing will happen.",
            +        "After pausing, .play() will resume from the paused position. If p5.SoundFile had been set to loop before it was paused, it will continue to loop after it is unpaused with .play()."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop the p5.SoundFile. Accepts optional parameters to set the playback rate, playback volume, loopStart, loopEnd."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) playback volume",
            +        "cueLoopStart": "Number: (Optional) (optional) startTime in seconds",
            +        "duration": "Number: (Optional) (optional) loop duration in seconds"
            +      }
            +    },
            +    "setLoop": {
            +      "description": [
            +        "Set a p5.SoundFile's looping flag to true or false. If the sound is currently playing, this change will take effect when it reaches the end of the current playback."
            +      ],
            +      "params": {
            +        "Boolean": "Boolean: set looping to true or false"
            +      }
            +    },
            +    "isLooping": {
            +      "description": [
            +        "Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "isPlaying": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is playing, false if not (i.e. paused or stopped)."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "isPaused": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is paused, false if not (i.e. playing or stopped)."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop soundfile playback."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  in seconds from now"
            +      }
            +    },
            +    "pan": {
            +      "description": [
            +        "Set the stereo panning of a p5.sound object to a floating point number between -1.0 (left) and 1.0 (right). Default is 0.0 (center)."
            +      ],
            +      "params": {
            +        "panValue": "Number: (Optional) Set the stereo panner",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current stereo pan position (-1.0 to 1.0)"
            +      ],
            +      "returns": "Number: Returns the stereo pan setting of the Oscillator  as a number between -1.0 (left) and 1.0 (right).  0.0 is center and default."
            +    },
            +    "rate": {
            +      "description": [
            +        "Set the playback rate of a sound file. Will change the speed and the pitch. Values less than zero will reverse the audio buffer."
            +      ],
            +      "params": {
            +        "playbackRate": "Number: (Optional) Set the playback rate. 1.0 is normal,  .5 is half-speed, 2.0 is twice as fast.  Values less than zero play backwards."
            +      }
            +    },
            +    "setVolume": {
            +      "description": [
            +        "Multiply the output volume (amplitude) of a sound file between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal."
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of a sound file in seconds."
            +      ],
            +      "returns": "Number: The duration of the soundFile in seconds."
            +    },
            +    "currentTime": {
            +      "description": [
            +        "Return the current position of the p5.SoundFile playhead, in seconds. Time is relative to the normal buffer direction, so if <code>reverseBuffer</code> has been called, currentTime will count backwards."
            +      ],
            +      "returns": "Number: currentTime of the soundFile in seconds."
            +    },
            +    "jump": {
            +      "description": [
            +        "Move the playhead of a soundfile that is currently playing to a new position and a new duration, in seconds. If none are given, will reset the file to play entire duration from start to finish. To set the position of a soundfile that is not currently playing, use the <code>play</code> or <code>loop</code> methods."
            +      ],
            +      "params": {
            +        "cueTime": "Number: cueTime of the soundFile in seconds.",
            +        "duration": "Number: duration in seconds."
            +      }
            +    },
            +    "channels": {
            +      "description": [
            +        "Return the number of channels in a sound file. For example, Mono = 1, Stereo = 2."
            +      ],
            +      "returns": "Number: [channels]"
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Return the sample rate of the sound file."
            +      ],
            +      "returns": "Number: [sampleRate]"
            +    },
            +    "frames": {
            +      "description": [
            +        "Return the number of samples in a sound file. Equal to sampleRate * duration."
            +      ],
            +      "returns": "Number: [sampleCount]"
            +    },
            +    "getPeaks": {
            +      "description": [
            +        "Returns an array of amplitude peaks in a p5.SoundFile that can be used to draw a static waveform. Scans through the p5.SoundFile's audio buffer to find the greatest amplitudes. Accepts one parameter, 'length', which determines size of the array. Larger arrays result in more precise waveform visualizations.",
            +        "Inspired by Wavesurfer.js."
            +      ],
            +      "returns": "Float32Array: Array of peaks.",
            +      "params": {
            +        "length": "Number: (Optional) length is the size of the returned array.  Larger length results in more precision.  Defaults to 5*width of the browser window."
            +      }
            +    },
            +    "reverseBuffer": {
            +      "description": [
            +        "Reverses the p5.SoundFile's buffer source. Playback must be handled separately (see example)."
            +      ]
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the soundfile reaches the end of a buffer. If the soundfile is playing through once, this will be called when it ends. If it is looping, it will be called when stop is called."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connects the output of a p5sound object to input of another p5.sound object. For example, you may connect a p5.SoundFile to an FFT or an Effect. If no parameter is given, it will connect to the main output. Most p5sound objects connect to the master output when they are created."
            +      ],
            +      "params": {
            +        "object": "Object: (Optional) Audio object that accepts an input"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnects the output of this p5sound object."
            +      ]
            +    },
            +    "setPath": {
            +      "description": [
            +        "Reset the source for this SoundFile to a new path (URL)."
            +      ],
            +      "params": {
            +        "path": "String: path to audio file",
            +        "callback": "Function: Callback"
            +      }
            +    },
            +    "setBuffer": {
            +      "description": [
            +        "Replace the current Audio Buffer with a new Buffer."
            +      ],
            +      "params": {
            +        "buf": "Array: Array of Float32 Array(s). 2 Float32 Arrays  will create a stereo source. 1 will create  a mono source."
            +      }
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point.",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback.",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ]
            +    },
            +    "save": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. To upload a file to a server, see <a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a>"
            +      ],
            +      "params": {
            +        "fileName": "String: (Optional) name of the resulting .wav file."
            +      }
            +    },
            +    "getBlob": {
            +      "description": [
            +        "This method is useful for sending a SoundFile to a server. It returns the .wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at MDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\". A Blob is a file-like data object that can be uploaded to a server with an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll use the <code>httpDo</code> options object to send a POST request with some specific options: we encode the request as <code>multipart/form-data</code>, and attach the blob as one of the form values using <code>FormData</code>."
            +      ],
            +      "returns": "Blob: A file-like data object"
            +    }
            +  },
            +  "p5.Amplitude": {
            +    "description": [
            +      "Amplitude measures volume between 0.0 and 1.0. Listens to all p5sound by default, or use setInput() to listen to a specific sound source. Accepts an optional smoothing value, which defaults to 0."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) between 0.0 and .999 to smooth  amplitude readings (defaults to 0)"
            +    },
            +    "setInput": {
            +      "description": [
            +        "Connects to the p5sound instance (main output) by default. Optionally, you can pass in a specific source (i.e. a soundfile)."
            +      ],
            +      "params": {
            +        "snd": "SoundObject|undefined: (Optional) set the sound source  (optional, defaults to  main output)",
            +        "smoothing": "Number|undefined: (Optional) a range between 0.0 and 1.0  to smooth amplitude readings"
            +      }
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Returns a single Amplitude reading at the moment it is called. For continuous readings, run in the draw loop."
            +      ],
            +      "returns": "Number: Amplitude as a number between 0.0 and 1.0",
            +      "params": {
            +        "channel": "Number: (Optional) Optionally return only channel 0 (left) or 1 (right)"
            +      }
            +    },
            +    "toggleNormalize": {
            +      "description": [
            +        "Determines whether the results of Amplitude.process() will be Normalized. To normalize, Amplitude finds the difference the loudest reading it has processed and the maximum amplitude of 1.0. Amplitude adds this difference to all values to produce results that will reliably map between 0.0 and 1.0. However, if a louder moment occurs, the amount that Normalize adds to all the values will change. Accepts an optional boolean parameter (true or false). Normalizing is off by default."
            +      ],
            +      "params": {
            +        "boolean": "Boolean: (Optional) set normalize to true (1) or false (0)"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth Amplitude analysis by averaging with the last analysis frame. Off by default."
            +      ],
            +      "params": {
            +        "set": "Number: smoothing from 0.0 <= 1"
            +      }
            +    }
            +  },
            +  "p5.FFT": {
            +    "description": [
            +      "FFT (Fast Fourier Transform) is an analysis algorithm that isolates individual <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\"> audio frequencies</a> within a waveform.",
            +      "Once instantiated, a p5.FFT object can return an array based on two types of analyses: • <code>FFT.waveform()</code> computes amplitude values along the time domain. The array indices correspond to samples across a brief moment in time. Each value represents amplitude of the waveform at that sample of time. • <code>FFT.analyze() </code> computes amplitude values along the frequency domain. The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Use with <code>getEnergy()</code> to measure amplitude at specific frequencies, or within a range of frequencies.",
            +      "FFT analyzes a very short snapshot of sound called a sample buffer. It returns an array of amplitude measurements, referred to as <code>bins</code>. The array is 1024 bins long by default. You can change the bin array length, but it must be a power of 2 between 16 and 1024 in order for the FFT algorithm to function correctly. The actual size of the FFT buffer is twice the number of bins, so given a standard sample rate, the buffer is 2048/44100 seconds long."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) Smooth results of Freq Spectrum.  0.0 < smoothing < 1.0.  Defaults to 0.8.",
            +      "bins": "Number: (Optional) Length of resulting array.  Must be a power of two between  16 and 1024. Defaults to 1024."
            +    },
            +    "setInput": {
            +      "description": [
            +        "Set the input source for the FFT analysis. If no source is provided, FFT will analyze all sound in the sketch."
            +      ],
            +      "params": {
            +        "source": "Object: (Optional) p5.sound object (or web audio API source node)"
            +      }
            +    },
            +    "waveform": {
            +      "description": [
            +        "Returns an array of amplitude values (between -1.0 and +1.0) that represent a snapshot of amplitude readings in a single buffer. Length will be equal to bins (defaults to 1024). Can be used to draw the waveform of a sound."
            +      ],
            +      "returns": "Array: Array Array of amplitude values (-1 to 1)  over time. Array length = bins.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "precision": "String: (Optional) If any value is provided, will return results  in a Float32 Array which is more precise  than a regular array."
            +      }
            +    },
            +    "analyze": {
            +      "description": [
            +        "Returns an array of amplitude values (between 0 and 255) across the frequency spectrum. Length is equal to FFT bins (1024 by default). The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Must be called prior to using <code>getEnergy()</code>."
            +      ],
            +      "returns": "Array: spectrum Array of energy (amplitude/volume)  values across the frequency spectrum.  Lowest energy (silence) = 0, highest  possible is 255.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "scale": "Number: (Optional) If \"dB,\" returns decibel  float measurements between  -140 and 0 (max).  Otherwise returns integers from 0-255."
            +      }
            +    },
            +    "getEnergy": {
            +      "description": [
            +        "Returns the amount of energy (volume) at a specific <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\"> frequency</a>, or the average amount of energy between two frequencies. Accepts Number(s) corresponding to frequency (in Hz), or a \"string\" corresponding to predefined frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\"). Returns a range between 0 (no energy/volume at that frequency) and 255 (maximum energy). <em>NOTE: analyze() must be called prior to getEnergy(). analyze() tells the FFT to analyze frequency data, and getEnergy() uses the results to determine the value at a specific frequency or range of frequencies.</em>"
            +      ],
            +      "returns": "Number: Energy Energy (volume/amplitude) from  0 and 255.",
            +      "params": {
            +        "frequency1": "Number|String: Will return a value representing  energy at this frequency. Alternately,  the strings \"bass\", \"lowMid\" \"mid\",  \"highMid\", and \"treble\" will return  predefined frequency ranges.",
            +        "frequency2": "Number: (Optional) If a second frequency is given,  will return average amount of  energy that exists between the  two frequencies."
            +      }
            +    },
            +    "getCentroid": {
            +      "description": [
            +        "Returns the <a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\"> spectral centroid</a> of the input signal. <em>NOTE: analyze() must be called prior to getCentroid(). Analyze() tells the FFT to analyze frequency data, and getCentroid() uses the results determine the spectral centroid.</em>"
            +      ],
            +      "returns": "Number: Spectral Centroid Frequency of the spectral centroid in Hz."
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth FFT analysis by averaging with the last analysis frame."
            +      ],
            +      "params": {
            +        "smoothing": "Number: 0.0 < smoothing < 1.0.  Defaults to 0.8."
            +      }
            +    },
            +    "linAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values for a given number of frequency bands split equally. N defaults to 16. <em>NOTE: analyze() must be called prior to linAverages(). Analyze() tells the FFT to analyze frequency data, and linAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: linearAverages Array of average amplitude values for each group",
            +      "params": {
            +        "N": "Number: Number of returned frequency groups"
            +      }
            +    },
            +    "logAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values of the spectrum, for a given set of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\"> Octave Bands</a> <em>NOTE: analyze() must be called prior to logAverages(). Analyze() tells the FFT to analyze frequency data, and logAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: logAverages Array of average amplitude values for each group",
            +      "params": {
            +        "octaveBands": "Array: Array of Octave Bands objects for grouping"
            +      }
            +    },
            +    "getOctaveBands": {
            +      "description": [
            +        "Calculates and Returns the 1/N <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a> N defaults to 3 and minimum central frequency to 15.625Hz. (1/3 Octave Bands ~= 31 Frequency Bands) Setting fCtr0 to a central value of a higher octave will ignore the lower bands and produce less frequency groups."
            +      ],
            +      "returns": "Array: octaveBands Array of octave band objects with their bounds",
            +      "params": {
            +        "N": "Number: Specifies the 1/N type of generated octave bands",
            +        "fCtr0": "Number: Minimum central frequency for the lowest band"
            +      }
            +    }
            +  },
            +  "p5.Oscillator": {
            +    "description": [
            +      "Creates a signal that oscillates between -1.0 and 1.0. By default, the oscillation takes the form of a sinusoidal shape ('sine'). Additional types include 'triangle', 'sawtooth' and 'square'. The frequency defaults to 440 oscillations per second (440Hz, equal to the pitch of an 'A' note).",
            +      "Set the type of oscillation with setType(), or by instantiating a specific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a href=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a href=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a href=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) frequency defaults to 440Hz",
            +      "type": "String: (Optional) type of oscillator. Options:  'sine' (default), 'triangle',  'sawtooth', 'square'"
            +    },
            +    "start": {
            +      "description": [
            +        "Start an oscillator.",
            +        "Starting an oscillator on a user gesture will enable audio in browsers that have a strict autoplay policy, including Chrome and most mobile devices. See also: <code>userStartAudio()</code>."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) startTime in seconds from now.",
            +        "frequency": "Number: (Optional) frequency in Hz."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop an oscillator. Accepts an optional parameter to determine how long (in seconds from now) until the oscillator stops."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: Time, in seconds from now."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the amplitude between 0 and 1.0. Or, pass in an object such as an oscillator to modulate amplitude with an audio signal."
            +      ],
            +      "returns": "AudioParam: gain If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's  gain/amplitude/volume)",
            +      "params": {
            +        "vol": "Number|Object: between 0 and 1.0  or a modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getAmp": {
            +      "description": [
            +        "Returns the value of output gain"
            +      ],
            +      "returns": "Number: Amplitude value between 0.0 and 1.0"
            +    },
            +    "freq": {
            +      "description": [
            +        "Set frequency of an oscillator to a value. Or, pass in an object such as an oscillator to modulate the frequency with an audio signal."
            +      ],
            +      "returns": "AudioParam: Frequency If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's frequency",
            +      "params": {
            +        "Frequency": "Number|Object: Frequency in Hz  or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Ramp time (in seconds)",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen  at x seconds from now"
            +      }
            +    },
            +    "getFreq": {
            +      "description": [
            +        "Returns the value of frequency of oscillator"
            +      ],
            +      "returns": "Number: Frequency of oscillator in Hertz"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type to 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "params": {
            +        "type": "String: 'sine', 'triangle', 'sawtooth' or 'square'."
            +      }
            +    },
            +    "getType": {
            +      "description": [
            +        "Returns current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "returns": "String: type of oscillator eg . 'sine', 'triangle', 'sawtooth' or 'square'."
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Pan between Left (-1) and Right (1)"
            +      ],
            +      "params": {
            +        "panning": "Number: Number between -1 and 1",
            +        "timeFromNow": "Number: schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current value of panPosition , between Left (-1) and Right (1)"
            +      ],
            +      "returns": "Number: panPosition of oscillator , between Left (-1) and Right (1)"
            +    },
            +    "phase": {
            +      "description": [
            +        "Set the phase of an oscillator between 0.0 and 1.0. In this implementation, phase is a delay time based on the oscillator's current frequency."
            +      ],
            +      "params": {
            +        "phase": "Number: float between 0.0 and 1.0"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Oscillator's output amplitude by a fixed value (i.e. turn it up!). Calling this method again will override the initial mult() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with multiplied output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this oscillator's amplitude values to a given range, and return the oscillator. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.SinOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SinOsc()</code>. This creates a Sine Wave Oscillator and is equivalent to <code> new p5.Oscillator('sine') </code> or creating a p5.Oscillator and then calling its method <code>setType('sine')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.TriOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.TriOsc()</code>. This creates a Triangle Wave Oscillator and is equivalent to <code>new p5.Oscillator('triangle') </code> or creating a p5.Oscillator and then calling its method <code>setType('triangle')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SawOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SawOsc()</code>. This creates a SawTooth Wave Oscillator and is equivalent to <code> new p5.Oscillator('sawtooth') </code> or creating a p5.Oscillator and then calling its method <code>setType('sawtooth')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SqrOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SqrOsc()</code>. This creates a Square Wave Oscillator and is equivalent to <code> new p5.Oscillator('square') </code> or creating a p5.Oscillator and then calling its method <code>setType('square')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.Envelope": {
            +    "description": [
            +      "Envelopes are pre-defined amplitude distribution over time. Typically, envelopes are used to control the output volume of an object, a series of fades referred to as Attack, Decay, Sustain and Release ( <a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a> ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can control an Oscillator's frequency like this: <code>osc.freq(env)</code>.",
            +      "Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level. Use <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.",
            +      "Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope, the <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger, or <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/ <code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff."
            +    ],
            +    "attackTime": {
            +      "description": [
            +        "Time until envelope reaches attackLevel"
            +      ]
            +    },
            +    "attackLevel": {
            +      "description": [
            +        "Level once attack is complete."
            +      ]
            +    },
            +    "decayTime": {
            +      "description": [
            +        "Time until envelope reaches decayLevel."
            +      ]
            +    },
            +    "decayLevel": {
            +      "description": [
            +        "Level after decay. The envelope will sustain here until it is released."
            +      ]
            +    },
            +    "releaseTime": {
            +      "description": [
            +        "Duration of the release portion of the envelope."
            +      ]
            +    },
            +    "releaseLevel": {
            +      "description": [
            +        "Level at the end of the release."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Reset the envelope with a series of time/value pairs."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds) before level  reaches attackLevel",
            +        "attackLevel": "Number: Typically an amplitude between  0.0 and 1.0",
            +        "decayTime": "Number: Time",
            +        "decayLevel": "Number: Amplitude (In a standard ADSR envelope,  decayLevel = sustainLevel)",
            +        "releaseTime": "Number: Release Time (in seconds)",
            +        "releaseLevel": "Number: Amplitude"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setRange": {
            +      "description": [
            +        "Set max (attackLevel) and min (releaseLevel) of envelope."
            +      ],
            +      "params": {
            +        "aLevel": "Number: attack level (defaults to 1)",
            +        "rLevel": "Number: release level (defaults to 0)"
            +      }
            +    },
            +    "setInput": {
            +      "description": [
            +        "Assign a parameter to be controlled by this envelope. If a p5.Sound object is given, then the p5.Envelope will control its output gain. If multiple inputs are provided, the env will control all of them."
            +      ],
            +      "params": {
            +        "inputs": "Object: (Optional) A p5.sound object or  Web Audio Param."
            +      }
            +    },
            +    "setExp": {
            +      "description": [
            +        "Set whether the envelope ramp is linear (default) or exponential. Exponential ramps can be useful because we perceive amplitude and frequency logarithmically."
            +      ],
            +      "params": {
            +        "isExp": "Boolean: true is exponential, false is linear"
            +      }
            +    },
            +    "play": {
            +      "description": [
            +        "Play tells the envelope to start acting on a given input. If the input is a p5.sound object (i.e. AudioIn, Oscillator, SoundFile), then Envelope will control its output volume. Envelopes can also be used to control any <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Audio Param.</a>"
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound object or  Web Audio Param.",
            +        "startTime": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go. Input can be any p5.sound object, or a <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Param</a>."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time from now (in seconds)"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the Release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "ramp": {
            +      "description": [
            +        "Exponentially ramp to a value using the first two values from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code> as <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\"> time constants</a> for simple exponential ramps. If the value is higher than current value, it uses attackTime, while a decrease uses decayTime."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: When to trigger the ramp",
            +        "v": "Number: Target value",
            +        "v2": "Number: (Optional) Second target value"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Envelope's output amplitude by a fixed value. Calling this method again will override the initial mult() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this envelope's amplitude values to a given range, and return the envelope. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.Noise": {
            +    "description": [
            +      "Noise is a type of oscillator that generates a buffer with random values."
            +    ],
            +    "params": {
            +      "type": "String: Type of noise can be 'white' (default),  'brown' or 'pink'."
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type of noise to 'white', 'pink' or 'brown'. White is the default."
            +      ],
            +      "params": {
            +        "type": "String: (Optional) 'white', 'pink' or 'brown'"
            +      }
            +    }
            +  },
            +  "p5.Pulse": {
            +    "description": [
            +      "Creates a Pulse object, an oscillator that implements Pulse Width Modulation. The pulse is created with two oscillators. Accepts a parameter for frequency, and to set the width between the pulses. See <a href=\" http://p5js.org/reference/#/p5.Oscillator\"> <code>p5.Oscillator</code> for a full list of methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Frequency in oscillations per second (Hz)",
            +      "w": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +    },
            +    "width": {
            +      "description": [
            +        "Set the width of a Pulse object (an oscillator that implements Pulse Width Modulation)."
            +      ],
            +      "params": {
            +        "width": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +      }
            +    }
            +  },
            +  "p5.AudioIn": {
            +    "description": [
            +      "Get audio from an input, i.e. your computer's microphone.",
            +      "Turn the mic on/off with the start() and stop() methods. When the mic is on, its volume can be measured with getLevel or by connecting an FFT object.",
            +      "If you want to hear the AudioIn, use the .connect() method. AudioIn does not connect to p5.sound output by default to prevent feedback.",
            +      "<em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/ Stream</a> API, which is not supported by certain browsers. Access in Chrome browser is limited to localhost and https, but access over http may be limited.</em>"
            +    ],
            +    "params": {
            +      "errorCallback": "Function: (Optional) A function to call if there is an error  accessing the AudioIn. For example,  Safari and iOS devices do not  currently allow microphone access."
            +    },
            +    "input": {},
            +    "output": {},
            +    "stream": {},
            +    "mediaStream": {},
            +    "currentSource": {},
            +    "enabled": {
            +      "description": [
            +        "Client must allow browser to access their microphone / audioin source. Default: false. Will become true when the client enables access."
            +      ]
            +    },
            +    "amplitude": {
            +      "description": [
            +        "Input amplitude, connect to it by default but not to master out"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start processing audio input. This enables the use of other AudioIn methods like getLevel(). Note that by default, AudioIn is not connected to p5.sound's output. So you won't hear anything unless you use the connect() method.<br/>",
            +        "Certain browsers limit access to the user's microphone. For example, Chrome only allows access from localhost and over https. For this reason, you may want to include an errorCallback—a function that is called in case the browser won't provide mic access."
            +      ],
            +      "params": {
            +        "successCallback": "Function: (Optional) Name of a function to call on  success.",
            +        "errorCallback": "Function: (Optional) Name of a function to call if  there was an error. For example,  some browsers do not support  getUserMedia."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel(). If re-starting, the user may be prompted for permission access."
            +      ]
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to an audio unit. If no parameter is provided, will connect to the main output (i.e. your speakers).<br/>"
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) An object that accepts audio input,  such as an FFT"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect the AudioIn from all audio units. For example, if connect() had been called, disconnect() will stop sending signal to your speakers.<br/>"
            +      ]
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Read the Amplitude (volume level) of an AudioIn. The AudioIn class contains its own instance of the Amplitude class to help make it easy to get a microphone's volume level. Accepts an optional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must .start() before using .getLevel().</em><br/>"
            +      ],
            +      "returns": "Number: Volume level (between 0.0 and 1.0)",
            +      "params": {
            +        "smoothing": "Number: (Optional) Smoothing is 0.0 by default.  Smooths values based on previous values."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set amplitude (volume) of a mic input between 0 and 1.0. <br/>"
            +      ],
            +      "params": {
            +        "vol": "Number: between 0 and 1.0",
            +        "time": "Number: (Optional) ramp time (optional)"
            +      }
            +    },
            +    "getSources": {
            +      "description": [
            +        "Returns a list of available input sources. This is a wrapper for <a href=\"https://developer.mozilla.org/ en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\"> MediaDevices.enumerateDevices() - Web APIs | MDN</a> and it returns a Promise."
            +      ],
            +      "returns": "Promise: Returns a Promise that can be used in place of the callbacks, similar  to the enumerateDevices() method",
            +      "params": {
            +        "successCallback": "Function: (Optional) This callback function handles the sources when they  have been enumerated. The callback function  receives the deviceList array as its only argument",
            +        "errorCallback": "Function: (Optional) This optional callback receives the error  message as its argument."
            +      }
            +    },
            +    "setSource": {
            +      "description": [
            +        "Set the input source. Accepts a number representing a position in the array returned by getSources(). This is only available in browsers that support  <a href=\"https://developer.mozilla.org/  en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">  navigator.mediaDevices.enumerateDevices()</a>"
            +      ],
            +      "params": {
            +        "num": "Number: position of input source in the array"
            +      }
            +    }
            +  },
            +  "p5.Effect": {
            +    "description": [
            +      "Effect is a base class for audio effects in p5. This module handles the nodes and methods that are common and useful for current and future effects.",
            +      "This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>, <a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>, <a href=\"/reference/#/p5.Delay\">p5.Delay</a>, <a href=\"/reference/#/p5.Filter\">p5.Filter</a>, <a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>."
            +    ],
            +    "params": {
            +      "ac": "Object: (Optional) Reference to the audio context of the p5 object",
            +      "input": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "output": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "_drywet": "Object: (Optional) Tone.JS CrossFade node (defaults to value: 1)",
            +      "wet": "AudioNode: (Optional) Effects that extend this class should connect  to the wet signal to this gain node, so that dry and wet  signals are mixed properly."
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output volume of the filter."
            +      ],
            +      "params": {
            +        "vol": "Number: (Optional) amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts until rampTime",
            +        "tFromNow": "Number: (Optional) schedule this event to happen in tFromNow seconds"
            +      }
            +    },
            +    "chain": {
            +      "description": [
            +        "Link effects together in a chain Example usage: filter.chain(reverb, delay, panner); May be used with an open-ended number of arguments"
            +      ],
            +      "params": {
            +        "arguments": "Object: (Optional) Chain together multiple sound objects"
            +      }
            +    },
            +    "drywet": {
            +      "description": [
            +        "Adjust the dry/wet value."
            +      ],
            +      "params": {
            +        "fade": "Number: (Optional) The desired drywet value (0 - 1.0)"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.js-sound, Web Audio Node, or use signal to control an AudioParam"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Filter": {
            +    "description": [
            +      "A p5.Filter uses a Web Audio Biquad Filter to filter the frequency response of an input source. Subclasses include: <a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>: Allows frequencies below the cutoff frequency to pass through, and attenuates frequencies above the cutoff.<br/> <a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>: The opposite of a lowpass filter. <br/> <a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>: Allows a range of frequencies to pass through and attenuates the frequencies below and above this frequency range.<br/>",
            +      "The <code>.res()</code> method controls either width of the bandpass, or resonance of the low/highpass cutoff frequency.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "type": "String: (Optional) 'lowpass' (default), 'highpass', 'bandpass'"
            +    },
            +    "biquadFilter": {
            +      "description": [
            +        "The p5.Filter is built with a <a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\"> Web Audio BiquadFilter Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Filter an audio signal according to a set of filter parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance/Width of the filter frequency  from 0.001 to 1000"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the frequency and the resonance of the filter."
            +      ],
            +      "params": {
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance (Q) from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "freq": {
            +      "description": [
            +        "Set the filter frequency, in Hz, from 10 to 22050 (the range of human hearing, although in reality most people hear in a narrower range)."
            +      ],
            +      "returns": "Number: value Returns the current frequency value",
            +      "params": {
            +        "freq": "Number: Filter Frequency",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "res": {
            +      "description": [
            +        "Controls either width of a bandpass frequency, or the resonance of a low/highpass cutoff frequency."
            +      ],
            +      "returns": "Number: value Returns the current res value",
            +      "params": {
            +        "res": "Number: Resonance/Width of filter freq  from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "gain": {
            +      "description": [
            +        "Controls the gain attribute of a Biquad Filter. This is distinctly different from .amp() which is inherited from p5.Effect .amp() controls the volume via the output gain node p5.Filter.gain() controls the gain parameter of a Biquad Filter node."
            +      ],
            +      "returns": "Number: Returns the current or updated gain value",
            +      "params": {
            +        "gain": "Number"
            +      }
            +    },
            +    "toggle": {
            +      "description": [
            +        "Toggle function. Switches between the specified type and allpass"
            +      ],
            +      "returns": "Boolean: [Toggle value]"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set the type of a p5.Filter. Possible types include: \"lowpass\" (default), \"highpass\", \"bandpass\", \"lowshelf\", \"highshelf\", \"peaking\", \"notch\", \"allpass\"."
            +      ],
            +      "params": {
            +        "t": "String"
            +      }
            +    }
            +  },
            +  "p5.LowPass": {
            +    "description": [
            +      "Constructor: <code>new p5.LowPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('lowpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.HighPass": {
            +    "description": [
            +      "Constructor: <code>new p5.HighPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('highpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.BandPass": {
            +    "description": [
            +      "Constructor: <code>new p5.BandPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('bandpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.EQ": {
            +    "description": [
            +      "p5.EQ is an audio effect that performs the function of a multiband audio equalizer. Equalization is used to adjust the balance of frequency compoenents of an audio signal. This process is commonly used in sound production and recording to change the waveform before it reaches a sound output device. EQ can also be used as an audio effect to create interesting distortions by filtering out parts of the spectrum. p5.EQ is built using a chain of Web Audio Biquad Filter Nodes and can be instantiated with 3 or 8 bands. Bands can be added or removed from the EQ by directly modifying p5.EQ.bands (the array that stores filters).",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "returns": "Object: p5.EQ object",
            +    "params": {
            +      "_eqsize": "Number: (Optional) Constructor will accept 3 or 8, defaults to 3"
            +    },
            +    "bands": {
            +      "description": [
            +        "The p5.EQ is built with abstracted p5.Filter objects. To modify any bands, use methods of the <a href=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\"> p5.Filter</a> API, especially <code>gain</code> and <code>freq</code>. Bands are stored in an array, with indices 0 - 3, or 0 - 7"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process an input by connecting it to the EQ"
            +      ],
            +      "params": {
            +        "src": "Object: Audio source"
            +      }
            +    }
            +  },
            +  "p5.Panner3D": {
            +    "description": [
            +      "Panner3D is based on the <a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>. This panner is a spatial processing node that allows audio to be positioned and oriented in 3D space.",
            +      "The position is relative to an <a title=\"Web Audio Listener docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\"> Audio Context Listener</a>, which can be accessed by <code>p5.soundOut.audiocontext.listener</code>"
            +    ],
            +    "panner": {
            +      "description": [
            +        "<a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>",
            +        "Properties include  <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>  : \"equal power\" or \"HRTF\"  <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a> : \"linear\", \"inverse\", or \"exponential\""
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect an audio sorce"
            +      ],
            +      "params": {
            +        "src": "Object: Input source"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "positionX": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionY": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionZ": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orient": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "orientX": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientY": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientZ": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "setFalloff": {
            +      "description": [
            +        "Set the rolloff factor and max distance"
            +      ],
            +      "params": {
            +        "maxDistance": "Number (Optional)",
            +        "rolloffFactor": "Number (Optional)"
            +      }
            +    },
            +    "maxDist": {
            +      "description": [
            +        "Maxium distance between the source and the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "maxDistance": "Number"
            +      }
            +    },
            +    "rollof": {
            +      "description": [
            +        "How quickly the volume is reduced as the source moves away from the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "rolloffFactor": "Number"
            +      }
            +    }
            +  },
            +  "p5.Delay": {
            +    "description": [
            +      "Delay is an echo effect. It processes an existing sound source, and outputs a delayed version of that sound. The p5.Delay can produce different effects depending on the delayTime, feedback, filter, and type. In the example below, a feedback of 0.5 (the default value) will produce a looping delay that decreases in volume by 50% each repeat. A filter will cut out the high frequencies so that the delay does not sound as piercing as the original source.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "leftDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "rightDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Add delay to an audio signal according to a set of delay parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "delayTime": "Number: (Optional) Time (in seconds) of the delay/echo.  Some browsers limit delayTime to  1 second.",
            +        "feedback": "Number: (Optional) sends the delay back through itself  in a loop that decreases in volume  each time.",
            +        "lowPass": "Number: (Optional) Cutoff frequency. Only frequencies  below the lowPass will be part of the  delay."
            +      }
            +    },
            +    "delayTime": {
            +      "description": [
            +        "Set the delay (echo) time, in seconds. Usually this value will be a floating point number between 0.0 and 1.0."
            +      ],
            +      "params": {
            +        "delayTime": "Number: Time (in seconds) of the delay"
            +      }
            +    },
            +    "feedback": {
            +      "description": [
            +        "Feedback occurs when Delay sends its signal back through its input in a loop. The feedback amount determines how much signal to send each time through the loop. A feedback greater than 1.0 is not desirable because it will increase the overall output each time through the loop, creating an infinite feedback loop. The default value is 0.5"
            +      ],
            +      "returns": "Number: Feedback value",
            +      "params": {
            +        "feedback": "Number|Object: 0.0 to 1.0, or an object such as an  Oscillator that can be used to  modulate this param"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Set a lowpass filter frequency for the delay. A lowpass filter will cut off any frequencies higher than the filter frequency."
            +      ],
            +      "params": {
            +        "cutoffFreq": "Number|Object: A lowpass filter will cut off any  frequencies higher than the filter frequency.",
            +        "res": "Number|Object: Resonance of the filter frequency  cutoff, or an object (i.e. a p5.Oscillator)  that can be used to modulate this parameter.  High numbers (i.e. 15) will produce a resonance,  low numbers (i.e. .2) will produce a slope."
            +      }
            +    },
            +    "setType": {
            +      "description": [
            +        "Choose a preset type of delay. 'pingPong' bounces the signal from the left to the right channel to produce a stereo effect. Any other parameter will revert to the default delay setting."
            +      ],
            +      "params": {
            +        "type": "String|Number: 'pingPong' (1) or 'default' (0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the delay effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Reverb": {
            +    "description": [
            +      "Reverb adds depth to a sound through a large number of decaying echoes. It creates the perception that sound is occurring in a physical space. The p5.Reverb has paramters for Time (how long does the reverb last) and decayRate (how much the sound decays with each echo) that can be set with the .set() or .process() methods. The p5.Convolver extends p5.Reverb allowing you to recreate the sound of actual physical spaces through convolution.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "process": {
            +      "description": [
            +        "Connect a source to the reverb, and assign reverb parameters."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output.",
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the reverb settings. Similar to .process(), but without assigning a new input."
            +      ],
            +      "params": {
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the reverb effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Convolver": {
            +    "description": [
            +      "p5.Convolver extends p5.Reverb. It can emulate the sound of real physical spaces through a process called <a href=\" https://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\"> convolution</a>.",
            +      "Convolution multiplies any audio input by an \"impulse response\" to simulate the dispersion of sound over time. The impulse response is generated from an audio file that you provide. One way to generate an impulse response is to pop a balloon in a reverberant space and record the echo. Convolution can also be used to experiment with sound.",
            +      "Use the method <code>createConvolution(path)</code> to instantiate a p5.Convolver with a path to your impulse response audio file."
            +    ],
            +    "params": {
            +      "path": "String: path to a sound file",
            +      "callback": "Function: (Optional) function to call when loading succeeds",
            +      "errorCallback": "Function: (Optional) function to call if loading fails.  This function will receive an error or  XMLHttpRequest object with information  about what went wrong."
            +    },
            +    "convolverNode": {
            +      "description": [
            +        "Internally, the p5.Convolver uses the a <a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\"> Web Audio Convolver Node</a>."
            +      ]
            +    },
            +    "impulses": {
            +      "description": [
            +        "If you load multiple impulse files using the .addImpulse method, they will be stored as Objects in this Array. Toggle between them with the <code>toggleImpulse(id)</code> method."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect a source to the convolver."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "addImpulse": {
            +      "description": [
            +        "Load and assign a new Impulse Response to the p5.Convolver. The impulse is added to the <code>.impulses</code> array. Previous impulses can be accessed with the <code>.toggleImpulse(id)</code> method."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "resetImpulse": {
            +      "description": [
            +        "Similar to .addImpulse, except that the <code>.impulses</code> Array is reset to save memory. A new <code>.impulses</code> array is created with this impulse as the only item."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "toggleImpulse": {
            +      "description": [
            +        "If you have used <code>.addImpulse()</code> to add multiple impulses to a p5.Convolver, then you can use this method to toggle between the items in the <code>.impulses</code> Array. Accepts a parameter to identify which impulse you wish to use, identified either by its original filename (String) or by its position in the <code>.impulses </code> Array (Number).<br/> You can access the objects in the .impulses Array directly. Each Object has two attributes: an <code>.audioBuffer</code> (type: Web Audio <a href=\" http://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\"> AudioBuffer)</a> and a <code>.name</code>, a String that corresponds with the original filename."
            +      ],
            +      "params": {
            +        "id": "String|Number: Identify the impulse by its original filename  (String), or by its position in the  <code>.impulses</code> Array (Number)."
            +      }
            +    }
            +  },
            +  "p5.Phrase": {
            +    "description": [
            +      "A phrase is a pattern of musical events over time, i.e. a series of notes and rests.",
            +      "Phrases must be added to a p5.Part for playback, and each part can play multiple phrases at the same time. For example, one Phrase might be a kick drum, another could be a snare, and another could be the bassline.",
            +      "The first parameter is a name so that the phrase can be modified or deleted later. The callback is a a function that this phrase will call at every step—for example it might be called <code>playNote(value){}</code>. The array determines which value is passed into the callback at each step of the phrase. It can be numbers, an object with multiple numbers, or a zero (0) indicates a rest so the callback won't be called)."
            +    ],
            +    "params": {
            +      "name": "String: Name so that you can access the Phrase.",
            +      "callback": "Function: The name of a function that this phrase  will call. Typically it will play a sound,  and accept two parameters: a time at which  to play the sound (in seconds from now),  and a value from the sequence array. The  time should be passed into the play() or  start() method to ensure precision.",
            +      "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +    },
            +    "sequence": {
            +      "description": [
            +        "Array of values to pass into the callback at each step of the phrase. Depending on the callback function's requirements, these values may be numbers, strings, or an object with multiple parameters. Zero (0) indicates a rest."
            +      ]
            +    }
            +  },
            +  "p5.Part": {
            +    "description": [
            +      "A p5.Part plays back one or more p5.Phrases. Instantiate a part with steps and tatums. By default, each step represents a 1/16th note.",
            +      "See p5.Phrase for more about musical timing."
            +    ],
            +    "params": {
            +      "steps": "Number: (Optional) Steps in the part",
            +      "tatums": "Number: (Optional) Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)"
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo of this part, in Beats Per Minute."
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: (Optional) Seconds from now"
            +      }
            +    },
            +    "getBPM": {
            +      "description": [
            +        "Returns the tempo, in Beats Per Minute, of this part."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of this part. It will play through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of this part. It will begin looping through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Tell the part to stop looping."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the part. Playback will resume from the current step."
            +      ],
            +      "params": {
            +        "time": "Number: seconds from now"
            +      }
            +    },
            +    "addPhrase": {
            +      "description": [
            +        "Add a p5.Phrase to this Part."
            +      ],
            +      "params": {
            +        "phrase": "p5.Phrase: reference to a p5.Phrase"
            +      }
            +    },
            +    "removePhrase": {
            +      "description": [
            +        "Remove a phrase from this part, based on the name it was given when it was created."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "getPhrase": {
            +      "description": [
            +        "Get a phrase from this part, based on the name it was given when it was created. Now you can modify its array."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "replaceSequence": {
            +      "description": [
            +        "Find all sequences with the specified name, and replace their patterns with the specified array."
            +      ],
            +      "params": {
            +        "phraseName": "String",
            +        "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +      }
            +    },
            +    "onStep": {
            +      "description": [
            +        "Set the function that will be called at every step. This will clear the previous function."
            +      ],
            +      "params": {
            +        "callback": "Function: The name of the callback  you want to fire  on every beat/tatum."
            +      }
            +    }
            +  },
            +  "p5.Score": {
            +    "description": [
            +      "A Score consists of a series of Parts. The parts will be played back in order. For example, you could have an A part, a B part, and a C part, and play them back in this order <code>new p5.Score(a, a, b, a, c)</code>"
            +    ],
            +    "params": {
            +      "parts": "p5.Part: (Optional) One or multiple parts, to be played in sequence."
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of the score."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop playback of the score."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause playback of the score."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of the score."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Stop looping playback of the score. If it is currently playing, this will go into effect after the current round of playback completes."
            +      ]
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo for all parts in the score"
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.SoundLoop": {
            +    "description": [
            +      "SoundLoop"
            +    ],
            +    "params": {
            +      "callback": "Function: this function will be called on each iteration of theloop",
            +      "interval": "Number|String: (Optional) amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second."
            +    },
            +    "bpm": {
            +      "description": [
            +        "Getters and Setters, setting any paramter will result in a change in the clock's frequency, that will be reflected after the next callback beats per minute (defaults to 60)"
            +      ]
            +    },
            +    "timeSignature": {
            +      "description": [
            +        "number of quarter notes in a measure (defaults to 4)"
            +      ]
            +    },
            +    "interval": {
            +      "description": [
            +        "length of the loops interval"
            +      ]
            +    },
            +    "iterations": {
            +      "description": [
            +        "how many times the callback has been called so far"
            +      ]
            +    },
            +    "musicalTimeMode": {
            +      "description": [
            +        "musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention true if string, false if number"
            +      ]
            +    },
            +    "maxIterations": {
            +      "description": [
            +        "Set a limit to the number of loops to play. defaults to Infinity"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a starting time"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a stopping time"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a pausing time"
            +      }
            +    },
            +    "syncedStart": {
            +      "description": [
            +        "Synchronize loops. Use this method to start two or more loops in synchronization or to start a loop in synchronization with a loop that is already playing This method will schedule the implicit loop in sync with the explicit master loop i.e. loopToStart.syncedStart(loopToSyncWith)"
            +      ],
            +      "params": {
            +        "otherLoop": "Object: a p5.SoundLoop to sync with",
            +        "timeFromNow": "Number: (Optional) Start the loops in sync after timeFromNow seconds"
            +      }
            +    }
            +  },
            +  "p5.Compressor": {
            +    "description": [
            +      "Compressor is an audio effect class that performs dynamics compression on an audio input source. This is a very commonly used technique in music and sound production. Compression creates an overall louder, richer, and fuller sound by lowering the volume of louds and raising that of softs. Compression can be used to avoid clipping (sound distortion due to peaks in volume) and is especially useful when many sounds are played at once. Compression can be used on indivudal sound sources in addition to the main output.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "compressor": {
            +      "description": [
            +        "The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"  target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node  </a>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Performs the same function as .connect, but also accepts optional parameters to set compressor's audioParams"
            +      ],
            +      "params": {
            +        "src": "Object: Sound source to be connected",
            +        "attack": "Number: (Optional) The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: (Optional) The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: (Optional) The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the paramters of a compressor."
            +      ],
            +      "params": {
            +        "attack": "Number: The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "attack": {
            +      "description": [
            +        "Get current attack or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "attack": "Number: (Optional) Attack is the amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "knee": {
            +      "description": [
            +        "Get current knee or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "ratio": {
            +      "description": [
            +        "Get current ratio or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "threshold": {
            +      "description": [
            +        "Get current threshold or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "release": {
            +      "description": [
            +        "Get current release or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "reduction": {
            +      "description": [
            +        "Return the current reduction value"
            +      ],
            +      "returns": "Number: Value of the amount of gain reduction that is applied to the signal"
            +    }
            +  },
            +  "p5.PeakDetect": {
            +    "description": [
            +      "PeakDetect works in conjunction with p5.FFT to look for onsets in some or all of the frequency spectrum.",
            +      "To use p5.PeakDetect, call <code>update</code> in the draw loop and pass in a p5.FFT object.",
            +      "You can listen for a specific part of the frequency spectrum by setting the range between <code>freq1</code> and <code>freq2</code>.",
            +      "<code>threshold</code> is the threshold for detecting a peak, scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud as 1.0.",
            +      "The update method is meant to be run in the draw loop, and <b>frames</b> determines how many loops must pass before another peak can be detected. For example, if the frameRate() = 60, you could detect the beat of a 120 beat-per-minute song with this equation: <code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>",
            +      "Based on example contribtued by @b2renger, and a simple beat detection explanation by <a href=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\" target=\"_blank\">Felix Turner</a>."
            +    ],
            +    "params": {
            +      "freq1": "Number: (Optional) lowFrequency - defaults to 20Hz",
            +      "freq2": "Number: (Optional) highFrequency - defaults to 20000 Hz",
            +      "threshold": "Number: (Optional) Threshold for detecting a beat between 0 and 1  scaled logarithmically where 0.1 is 1/2 the loudness  of 1.0. Defaults to 0.35.",
            +      "framesPerPeak": "Number: (Optional) Defaults to 20."
            +    },
            +    "isDetected": {
            +      "description": [
            +        "isDetected is set to true when a peak is detected."
            +      ]
            +    },
            +    "update": {
            +      "description": [
            +        "The update method is run in the draw loop.",
            +        "Accepts an FFT object. You must call .analyze() on the FFT object prior to updating the peakDetect because it relies on a completed FFT analysis."
            +      ],
            +      "params": {
            +        "fftObject": "p5.FFT: A p5.FFT object"
            +      }
            +    },
            +    "onPeak": {
            +      "description": [
            +        "onPeak accepts two arguments: a function to call when a peak is detected. The value of the peak, between 0.0 and 1.0, is passed to the callback."
            +      ],
            +      "params": {
            +        "callback": "Function: Name of a function that will  be called when a peak is  detected.",
            +        "val": "Object: (Optional) Optional value to pass  into the function when  a peak is detected."
            +      }
            +    }
            +  },
            +  "p5.SoundRecorder": {
            +    "description": [
            +      "Record sounds for playback and/or to save as a .wav file. The p5.SoundRecorder records all sound output from your sketch, or can be assigned a specific source with setInput().",
            +      "The record() method accepts a p5.SoundFile as a parameter. When playback is stopped (either after the given amount of time, or with the stop() method), the p5.SoundRecorder will send its recording to that p5.SoundFile for playback."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a specific device to the p5.SoundRecorder. If no parameter is given, p5.SoundRecorer will record all audible p5.sound from your sketch."
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) p5.sound object or a web audio unit  that outputs sound"
            +      }
            +    },
            +    "record": {
            +      "description": [
            +        "Start recording. To access the recording, provide a p5.SoundFile as the first parameter. The p5.SoundRecorder will send its recording to that p5.SoundFile for playback once recording is complete. Optional parameters include duration (in seconds) of the recording, and a callback function that will be called once the complete recording has been transfered to the p5.SoundFile."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile",
            +        "duration": "Number: (Optional) Time (in seconds)",
            +        "callback": "Function: (Optional) The name of a function that will be  called once the recording completes"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the recording. Once the recording is stopped, the results will be sent to the p5.SoundFile that was given on .record(), and if a callback function was provided on record, that function will be called."
            +      ]
            +    }
            +  },
            +  "p5.Distortion": {
            +    "description": [
            +      "A Distortion effect created with a Waveshaper Node, with an approach adapted from <a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a>",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +      "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +    },
            +    "WaveShaperNode": {
            +      "description": [
            +        "The p5.Distortion is built with a <a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\"> Web Audio WaveShaper Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process a sound source, optionally specify amount and oversample values."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the amount and oversample of the waveshaper distortion."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "getAmount": {
            +      "description": [
            +        "Return the distortion amount, typically between 0-1."
            +      ],
            +      "returns": "Number: Unbounded distortion amount.  Normal values range from 0-1."
            +    },
            +    "getOversample": {
            +      "description": [
            +        "Return the oversampling."
            +      ],
            +      "returns": "String: Oversample can either be 'none', '2x', or '4x'."
            +    }
            +  },
            +  "p5.Gain": {
            +    "description": [
            +      "A gain node is usefull to set the relative volume of sound. It's typically used to build mixers."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a source to the gain node."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the gain node."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    }
            +  },
            +  "p5.AudioVoice": {
            +    "description": [
            +      "Base class for monophonic synthesizers. Any extensions of this class should follow the API and implement the methods below in order to remain compatible with p5.PolySynth();"
            +    ],
            +    "connect": {
            +      "description": [
            +        "Connect to p5 objects or Web Audio Nodes"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect from soundOut"
            +      ]
            +    }
            +  },
            +  "p5.MonoSynth": {
            +    "description": [
            +      "A MonoSynth is used as a single voice for sound synthesis. This is a class to be used in conjunction with the PolySynth class. Custom synthetisers should be built inheriting from this class."
            +    ],
            +    "attack": {
            +      "description": [
            +        "Getters and Setters"
            +      ]
            +    },
            +    "decay": {},
            +    "sustain": {},
            +    "release": {},
            +    "play": {
            +      "description": [
            +        "Play tells the MonoSynth to start playing a note. This method schedules the calling of .triggerAttack and .triggerRelease."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope. Defaults to 0.15 seconds."
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "MonoSynth amp"
            +      ],
            +      "returns": "Number: new volume value",
            +      "params": {
            +        "vol": "Number: desired volume",
            +        "rampTime": "Number: (Optional) Time to reach new volume"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  },
            +  "p5.OnsetDetect": {
            +    "description": [
            +      "Listen for onsets (a sharp increase in volume) within a given frequency range."
            +    ],
            +    "params": {
            +      "freqLow": "Number: Low frequency",
            +      "freqHigh": "Number: High frequency",
            +      "threshold": "Number: Amplitude threshold between 0 (no energy) and 1 (maximum)",
            +      "callback": "Function: Function to call when an onset is detected"
            +    }
            +  },
            +  "p5.PolySynth": {
            +    "description": [
            +      "An AudioVoice is used as a single voice for sound synthesis. The PolySynth class holds an array of AudioVoice, and deals with voices allocations, with setting notes to be played, and parameters to be set."
            +    ],
            +    "params": {
            +      "synthVoice": "Number: (Optional) A monophonic synth voice inheriting  the AudioVoice class. Defaults to p5.MonoSynth",
            +      "maxVoices": "Number: (Optional) Number of voices, defaults to 8;"
            +    },
            +    "notes": {
            +      "description": [
            +        "An object that holds information about which notes have been played and which notes are currently being played. New notes are added as keys on the fly. While a note has been attacked, but not released, the value of the key is the audiovoice which is generating that note. When notes are released, the value of the key becomes undefined."
            +      ]
            +    },
            +    "polyvalue": {
            +      "description": [
            +        "A PolySynth must have at least 1 voice, defaults to 8"
            +      ]
            +    },
            +    "AudioVoice": {
            +      "description": [
            +        "Monosynth that generates the sound for each note that is triggered. The p5.PolySynth defaults to using the p5.MonoSynth as its voice."
            +      ]
            +    },
            +    "play": {
            +      "description": [
            +        "Play a note by triggering noteAttack and noteRelease with sustain time"
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note to play (ranging from 0 to 127 - 60 being a middle C)",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "noteADSR": {
            +      "description": [
            +        "noteADSR sets the envelope for a specific note that has just been triggered. Using this method modifies the envelope of whichever audiovoice is being used to play the desired note. The envelope should be reset before noteRelease is called in order to prevent the modified envelope from being used on other notes."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) Midi note on which ADSR should be set.",
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set the PolySynths global envelope. This method modifies the envelopes of each monosynth so that all notes are played with this envelope."
            +      ],
            +      "params": {
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "noteAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of a MonoSynth. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)/",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds)"
            +      }
            +    },
            +    "noteRelease": {
            +      "description": [
            +        "Trigger the Release of an AudioVoice note. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.  If no value is provided, all notes will be released.",
            +        "secondsFromNow": "Number: (Optional) time to trigger the release"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/reference/es.json b/dist/assets/reference/es.json
            new file mode 100644
            index 0000000000..ce29be9802
            --- /dev/null
            +++ b/dist/assets/reference/es.json
            @@ -0,0 +1,7564 @@
            +{
            +  "h1": "Referencia",
            +  "reference-search": "Busca en la API",
            +  "reference-description1": "¿No encuentras lo que buscas? Quizás debas revisar en",
            +  "reference-description3": "Puedes descargar una versión de la referencia.",
            +  "reference-contribute2": "por favor dinos",
            +  "reference-error1": "¿Encontraste algún error?",
            +  "reference-error3": "Por favor siéntete libre de",
            +  "reference-error5": "y de indicar un pull request.",
            +  "reference-example": "Ejemplo",
            +  "reference-description": "Descripción",
            +  "reference-extends": "Extiende",
            +  "reference-parameters": "Parámetros",
            +  "reference-syntax": "Sintaxis",
            +  "reference-returns": "Retorna",
            +  "Environment": "Ambiente",
            +  "Color": "Color",
            +  "Color Conversion": "Color Conversion",
            +  "Creating & Reading": "Creación y lectura",
            +  "Setting": "Configuración",
            +  "Shape": "Forma",
            +  "2D Primitives": "Primitivas 2D",
            +  "Attributes": "Atributos",
            +  "Curves": "Curvas",
            +  "Vertex": "Vértices",
            +  "Constants": "Constantes",
            +  "Structure": "Estructura",
            +  "DOM": "DOM",
            +  "Rendering": "Render",
            +  "Foundation": "Foundation",
            +  "Transform": "Transformar",
            +  "Data": "Datos",
            +  "LocalStorage": "LocalStorage",
            +  "Dictionary": "Diccionario",
            +  "Events": "Eventos",
            +  "Acceleration": "Aceleración",
            +  "Keyboard": "Teclado",
            +  "Mouse": "Ratón",
            +  "Touch": "Tacto",
            +  "Image": "Imagen",
            +  "Loading & Displaying": "Cargar & Mostrar",
            +  "Pixels": "Pixeles",
            +  "IO": "Entrada y salida",
            +  "Input": "Entrada",
            +  "Output": "Salida",
            +  "Table": "Tabla",
            +  "Math": "Matemáticas",
            +  "Calculation": "Cálculo",
            +  "Vector": "Vector",
            +  "Noise": "Ruido",
            +  "Random": "Random",
            +  "Trigonometry": "Trigonometría",
            +  "Typography": "Tipografía",
            +  "Array Functions": "Funciones de arreglo",
            +  "Conversion": "Conversión",
            +  "String Functions": "Funciones de String",
            +  "Time & Date": "Tiempo & Fecha",
            +  "3D Primitives": "Primitivas 3D",
            +  "Lights, Camera": "Luces, cámara",
            +  "Interaction": "Interaction",
            +  "Lights": "Luces",
            +  "3D Models": "Modelos 3D",
            +  "Material": "Materiales",
            +  "Camera": "Cámara",
            +  "p5": {
            +    "description": [
            +      "This is the p5 instance constructor.",
            +      "A p5 instance holds all the properties and methods related to a p5 sketch. It expects an incoming sketch closure and it can also take an optional node parameter for attaching the generated p5 canvas to a node. The sketch closure takes the newly created p5 instance as its sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>, <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.",
            +      "A p5 sketch can run in \"global\" or \"instance\" mode: \"global\" - all properties and methods are attached to the window \"instance\" - all properties and methods are bound to this p5 object"
            +    ],
            +    "returns": "P5: a p5 instance",
            +    "params": {
            +      "sketch": "Function: a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,  <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the  given p5 instance",
            +      "node": "HTMLElement: (Optional) element to attach canvas to"
            +    },
            +    "describe": {
            +      "description": [
            +        "Creates a screen reader accessible description for the canvas. The first parameter should be a string with a description of the canvas. The second parameter is optional. If specified, it determines how the description is displayed.",
            +        "<code class=\"language-javascript\">describe(text, LABEL)</code> displays the description to all users as a <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\"> tombstone or exhibit label/caption</a> in a <code class=\"language-javascript\"><div class=\"p5Label\"></div></code> adjacent to the canvas. You can style it as you wish in your CSS.",
            +        "<code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the description accessible to screen-reader users only, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a>. If a second parameter is not specified, by default, the description will only be available to screen-reader users."
            +      ],
            +      "params": {
            +        "text": "String: description of the canvas",
            +        "display": "Constant: (Optional) either LABEL or FALLBACK (Optional)"
            +      }
            +    },
            +    "describeElement": {
            +      "description": [
            +        "This function creates a screen-reader accessible description for elements —shapes or groups of shapes that create meaning together— in the canvas. The first paramater should be the name of the element. The second parameter should be a string with a description of the element. The third parameter is optional. If specified, it determines how the element description is displayed.",
            +        "<code class=\"language-javascript\">describeElement(name, text, LABEL)</code> displays the element description to all users as a <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\"> tombstone or exhibit label/caption</a> in a <code class=\"language-javascript\"><div class=\"p5Label\"></div></code> adjacent to the canvas. You can style it as you wish in your CSS.",
            +        "<code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code> makes the element description accessible to screen-reader users only, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a>. If a second parameter is not specified, by default, the element description will only be available to screen-reader users."
            +      ],
            +      "params": {
            +        "name": "String: name of the element",
            +        "text": "String: description of the element",
            +        "display": "Constant: (Optional) either LABEL or FALLBACK (Optional)"
            +      }
            +    },
            +    "textOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">textOutput()</code> creates a screenreader accessible output that describes the shapes present on the canvas. The general description of the canvas includes canvas size, canvas color, and number of elements in the canvas (example: 'Your output is a, 400 by 400 pixels, lavender blue canvas containing the following 4 shapes:'). This description is followed by a list of shapes where the color, position, and area of each shape are described (example: \"orange ellipse at top left covering 1% of the canvas\"). Each element can be selected to get more details. A table of elements is also provided. In this table, shape, color, location, coordinates and area are described (example: \"orange ellipse location=top left area=2\").",
            +        "<code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">texOutput(FALLBACK)</code> make the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a> which is accessible to screen readers. <code class=\"language-javascript\">textOutput(LABEL)</code> creates an additional div with the output adjacent to the canvas, this is useful for non-screen reader users that might want to display the output outside of the canvas' sub DOM as they code. However, using LABEL will create unnecessary redundancy for screen reader users. We recommend using LABEL only as part of the development process of a sketch and removing it before publishing or sharing with screen reader users."
            +      ],
            +      "params": {
            +        "display": "Constant: (Optional) either FALLBACK or LABEL (Optional)"
            +      }
            +    },
            +    "gridOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">gridOutput()</code> lays out the content of the canvas in the form of a grid (html table) based on the spatial location of each shape. A brief description of the canvas is available before the table output. This description includes: color of the background, size of the canvas, number of objects, and object types (example: \"lavender blue canvas is 200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid describes the content spatially, each element is placed on a cell of the table depending on its position. Within each cell an element the color and type of shape of that element are available (example: \"orange ellipse\"). These descriptions can be selected individually to get more details. A list of elements where shape, color, location, and area are described (example: \"orange ellipse location=top left area=1%\") is also available.",
            +        "<code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code> make the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a> which is accessible to screen readers. <code class=\"language-javascript\">gridOutput(LABEL)</code> creates an additional div with the output adjacent to the canvas, this is useful for non-screen reader users that might want to display the output outside of the canvas' sub DOM as they code. However, using LABEL will create unnecessary redundancy for screen reader users. We recommend using LABEL only as part of the development process of a sketch and removing it before publishing or sharing with screen reader users."
            +      ],
            +      "params": {
            +        "display": "Constant: (Optional) either FALLBACK or LABEL (Optional)"
            +      }
            +    },
            +    "alpha": {
            +      "description": [
            +        "Extrae el valor de alpha de un color o de un arreglo de pixeles."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "color": "Objeto: objeto p5.Color o arreglo de pixeles"
            +      }
            +    },
            +    "blue": {
            +      "description": [
            +        "Extrae el valor de azul de un color o de un arreglo de pixeles."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "color": "Objeto: objeto p5.Color o arreglo de pixeles"
            +      }
            +    },
            +    "brightness": {
            +      "description": [
            +        "Extrae el valor de brillo HSB de un color o de un arreglo de pixeles."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "color": "Objeto: objeto p5.Color o arreglo de pixeles"
            +      }
            +    },
            +    "color": {
            +      "description": [
            +        "Crea colores para ser almacenados en variables del tipo color. Los parámetros son interpretados como valores RGB o HSB, dependiendo del modo actual de color según colorMode)(). El modo por defecto es RGB con valores entre 0 y 255 y, por lo tanto, la función color(255, 204, 0) retorna un color amarillo brillante. Nota que si solo se provee un valor a la función color(), será interpretado como un valor en escala de grises. Añade un segundo valor, y será usado como transparencia alpha. Cuando se especifican tres valores, son interpretados como valores RGB o HSB. Al añadir un cuarto valor se aplica transparencia alpha. Si se provee solo un parámetro de tipo string, será interpretado como un string de color compatible con CSS.Los colores son almacenados como números o arreglos.",
            +        "Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted as a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either RGB or HSB values. Adding a fourth value applies alpha transparency.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used."
            +      ],
            +      "returns": "Arreglo: color resultante",
            +      "params": {
            +        "gray": "Número|String: número especificando el valor entre blanco y negro.",
            +        "alpha": "Número: valor de alpha relativo al rango de color actual (por defecto es 0-255)",
            +        "v1": "Número|String: valor de rojo o tinte relativo al rango de color actual, o un string de color",
            +        "v2": "Número: valor de verde o saturación relativo al rango de color actual",
            +        "v3": "Número: valor de azul o brillo relativo al rango de color actual",
            +        "value": "String: a color string",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color"
            +      }
            +    },
            +    "green": {
            +      "description": [
            +        "Extrae el valor de verde de un color o de un arreglo de pixeles."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "color": "Objeto: objeto p5.Color o arreglo de pixeles"
            +      }
            +    },
            +    "hue": {
            +      "description": [
            +        "Extrae el valor de tinte de un color o de un arreglo de pixeles. El tinte (hue) existe en HSB y HSL. Esta función retorna el tinte normalizado HSB que cuando se le provee un objeto de color HSB (o cuando se le provee un arreglo de pixeles mientras el modo de color es HSB), pero por defecto retornará el tinte normalizado según HSB en otro caso. (Estos valores solo son diferentes si la configuración de valor de tinte máximo de cada sistema es diferente.)",
            +        "Hue exists in both HSB and HSL. This function will return the HSB-normalized hue when supplied with an HSB color object (or when supplied with a pixel array while the color mode is HSB), but will default to the HSL-normalized hue otherwise. (The values will only be different if the maximum hue setting for each system is different.)"
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "color": "Objeto: objeto p5.Color o arreglo de pixeles"
            +      }
            +    },
            +    "lerpColor": {
            +      "description": [
            +        "Mezcla dos colores para encontrar un tercer color según la combinación de ambos. El parámetro amt es la cantidad a interpolar entre los dos valores, donde 0.0 es igual al primer color, 0.1 es muy cercano al primer color, 0.5 está a medio camino entre ambos, etc. Un valor menor que 0 será tratado como 0. Del mismo modo, valores sobre 1 serán tratados como 1. Esto es distinto al comportamiento de lerp(), pero necesario porque de otra manera los números fuera de rango producirían colores no esperados y extraños. La manera en que los colores son interpolados depende del modo de color actual.",
            +        "The way that colors are interpolated depends on the current color mode."
            +      ],
            +      "returns": "Arreglo/Número: color interpolado",
            +      "params": {
            +        "c1": "Arreglo/Número: interpola desde este color",
            +        "c2": "Arreglo/Número: interpola hacia este color",
            +        "amt": "Número: número entre 0 y 1"
            +      }
            +    },
            +    "lightness": {
            +      "description": [
            +        "Extrae el valor de luminosidad HSL de un color o de un arreglo de pixeles."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "color": "Objeto: objeto p5.Color o arreglo de pixeles"
            +      }
            +    },
            +    "red": {
            +      "description": [
            +        "Extrae el valor de rojo de un color o de un arreglo de pixeles."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "color": "Objeto: objeto p5.Color o arreglo de pixeles"
            +      }
            +    },
            +    "saturation": {
            +      "description": [
            +        "Extrae el valor de saturación de un color o de un arreglo de pixeles. La saturación es escalada en HSB y HSL de forma distinta. Esta función retornará la saturación HSB cuando le sea provisto un objeto de color HSB (o cuando le sea provisto un arreglo de pixeles mientras el modo de color es HSB), pero por defecto retornará saturación HSL.",
            +        "Saturation is scaled differently in HSB and HSL. This function will return the HSB saturation when supplied with an HSB color object (or when supplied with a pixel array while the color mode is HSB), but will default to the HSL saturation otherwise."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "color": "Objeto: objeto p5.Color o arreglo de pixeles"
            +      }
            +    },
            +    "background": {
            +      "description": [
            +        "La función background() define el color usado como fondo del lienzo p5.js. El fondo por defecto es gris claro. Esta función es típicamente usada dentro de draw() para despejar o borrar la ventana mostrada al inicio de cada cuadro, pero puede ser usada dentro de setup() para definir el fondo en el primer cuadro de la animación o si el fondo solo necesita ser definido una vez.",
            +        "The color is either specified in terms of the RGB, HSB, or HSL color depending on the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space is RGB, with each value in the range from 0 to 255). The alpha range by default is also 0 to 255.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used.",
            +        "A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.",
            +        "A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image."
            +      ],
            +      "params": {
            +        "color": "Color: cualquier valor creado con la función color()",
            +        "colorstring": "colorstring: string de color, formatos posibles: enteros rgb() o rgba(), porcentajes rgb() o rgba(), hex 3 dígitos, hex 6 dígitos",
            +        "a": "Número: opacidad del fondo relativo al rango de color actual (por defecto es 0-255)",
            +        "gray": "Número: especifica un valor entre blanco y negro",
            +        "v1": "Número: valor de rojo o hue (dependiendo del modo de color actual)",
            +        "v2": "Número: valor de verde o saturación (dependiendo del modo de color actual)",
            +        "v3": "Número: valor de azul o brillo (dependiendo del modo de color actual)",
            +        "values": "Number[]: an array containing the red, green, blue  and alpha components of the color",
            +        "image": "p5.Image: imagen creada con loadImage() o createImage(), para ser definida como fondo (debe ser del mismo tamaño que la ventana del bosquejo)"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Borra los pixeles del buffer. Esta función solo funciona en objetos p5.Canvas creados con la función createCanvas(); no funcionará con la ventana principal. A diferencia del contexto principal de gráficas, los pixeles en las áreas gráficas adicionales creadas con createGraphics() pueden ser entera o parcialmente transparentes. Esta función borra todo para hacer los pixeles 100% transparentes."
            +      ]
            +    },
            +    "colorMode": {
            +      "description": [
            +        "colorMode() cambia la manera en que p5.js interpreta los datos de color. Por defecto, los parámetros de fill(), stroke(), background() y color() son definidos por valores entre 0 y 255 en modo RGB. Esto es equivalente a definir el modo de color según colorMode(RGB, 255). Definir el modo de color en colorMode(HSB) permite usar el sistema HSB. Por defecto, este modo de color es colorMode(HSB, 360, 100, 100, 1). También se puede usar HSL. Nota: los objetos de color existentes recuerdan el modo en que fueron creados, por lo que puedes cambiar el modo como quieras, sin afectar su apariencia.",
            +        "Note: existing color objects remember the mode that they were created in, so you can change modes as you like without affecting their appearance."
            +      ],
            +      "params": {
            +        "mode": "Constante: RGB o HSB, correspondiente a Rojo/Verde/Azul o tinte/saturación/brillo (o luminosidad)",
            +        "max": "Number: (Optional) range for all values",
            +        "max1": "Número: rango de rojo o tinte, dependiendo del modo de color actual, o rango para todos los valores",
            +        "max2": "Número: rango de verde o saturación, dependiendo del modo de color actual.",
            +        "max3": "Número: rango de azul o brillo/luminosidad, dependiendo del modo de color actual.",
            +        "maxA": "Número: rango de transparencia alpha"
            +      }
            +    },
            +    "fill": {
            +      "description": [
            +        "Define el color usado para el relleno de figuras geométricas. Por ejemplo, si ejecutas fill(204, 102, 0), todas las figuras a continuación tendrán relleno naranja. Este color es especificado en términos de color RGB o HSB, dependiendo del modo de color según colorMode() (el dominio de color por defecto es RGB, con cada valor en el rango entre 0 y 255). Si se provee un argumento tipo string, los tipos RGB, RGBA y CSS hexadecimal están soportados. Un objeto Color p5 puede ser provisto para definir el color del relleno.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used.",
            +        "A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color."
            +      ],
            +      "params": {
            +        "v1": "Número|Arreglo|String|p5.Color: valor de gris, rojo, tinte (dependiendo del modo de color actual), o arreglo de color, o string de color CSS.",
            +        "v2": "Número: valor de verde o saturación (dependiendo del modo de color actual)",
            +        "v3": "Número: valor de azul o brillo (dependiendo del modo de color actual)",
            +        "alpha": "Número: opacidad del fondo",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the fill color"
            +      }
            +    },
            +    "noFill": {
            +      "description": [
            +        "Deshabilita el relleno de figuras geométricas. Si tanto noStroke() como noFill() son ejecutados, nada será dibujado en pantalla."
            +      ]
            +    },
            +    "noStroke": {
            +      "description": [
            +        "Deshabilita el dibujo de los trazos (bordes). Si tanto noStroke() como noFill() son ejecutados, nada será dibujado en pantalla."
            +      ]
            +    },
            +    "stroke": {
            +      "description": [
            +        "Define el color usado para dibujar líneas y bordes de figuras. Este color especificado en términos de color RGB o HSB, dependiendo del modo de color actual según colorMode() (el dominio de color por defecto es RGB, con cada valor en el rango entre 0 y 255). Si se provee un argumento tipo string, los tipos RGB, RGBA y CSS hexadecimal están soportados. Un objeto Color p5 puede ser provisto para definir el color del trazado.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used.",
            +        "A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color."
            +      ],
            +      "params": {
            +        "v1": "Número|Arreglo|String|p5.Color: valor de gris, rojo, tinte (dependiendo del modo de color actual), o arreglo de color, o string de color CSS.",
            +        "v2": "Número: valor de verde o saturación (dependiendo del modo de color actual)",
            +        "v3": "Número: valor de azul o brillo (dependiendo del modo de color actual)",
            +        "alpha": "Número: opacidad del fondo",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the stroke color"
            +      }
            +    },
            +    "erase": {
            +      "description": [
            +        "All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from the canvas.Erased areas will reveal the web page underneath the canvas.Erasing can be canceled with <a href=\"#/p5/noErase\">noErase()</a>.",
            +        "Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\"> background()</a> in between <a href=\"#/p5/erase\">erase()</a> and <a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual."
            +      ],
            +      "params": {
            +        "strengthFill": "Number: (Optional) A number (0-255) for the strength of erasing for a shape's fill.  This will default to 255 when no argument is given, which  is full strength.",
            +        "strengthStroke": "Number: (Optional) A number (0-255) for the strength of erasing for a shape's stroke.  This will default to 255 when no argument is given, which  is full strength."
            +      }
            +    },
            +    "noErase": {
            +      "description": [
            +        "Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>. The <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and <a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were prior to calling <a href=\"#/p5/erase\">erase()</a>."
            +      ]
            +    },
            +    "arc": {
            +      "description": [
            +        "Dibuja un arco en la pantalla. Si se llama con solo a, b, c, d, start y stop, el arco se dibuja como un pastel abierto. Si el modo se provee, el arco será dibujado abierto, o como acorde, o como pastel, según lo especificado. El origen puede ser cambiado con la función ellipseMode(). Nota que si dibujas un círculo completo (ej: 0 a TWO_PI) aparecerá en blanco, porque 0 y TWO_PI son la misma posición en el círculo unitario. La mejor manera de manejar esto es usar la función ellipse() para una elipse cerrada, y la función arc() para generar solo secciones de una elipse.",
            +        "The arc is always drawn clockwise from wherever start falls to wherever stop falls on the ellipse. Adding or subtracting TWO_PI to either angle does not change where they fall. If both start and stop fall at the same place, a full ellipse will be drawn. Be aware that the y-axis increases in the downward direction, therefore angles are measured clockwise from the positive x-direction (\"3 o'clock\")."
            +      ],
            +      "params": {
            +        "x": "Número: coordenada x del arco de elipse.",
            +        "y": "Número: coordenada y del arco de elipse.",
            +        "w": "Número: ancho del arco de elipse.",
            +        "h": "Número: altura del arco de elipse.",
            +        "start": "Número: ángulo inicial del arco de elipse.",
            +        "stop": "Número: ángulo final del arco de elipse.",
            +        "mode": "Constante: parámetro opcional para determinar la manera de dibujar el arco.",
            +        "detail": "Number: (Optional) optional parameter for WebGL mode only. This is to  specify the number of vertices that makes up the  perimeter of the arc. Default value is 25."
            +      }
            +    },
            +    "ellipse": {
            +      "description": [
            +        "Dibuja una elipse (óvalo)  en la pantalla. Una elipse con igual ancho y altura es un círculo. Por defecto, los primeros dos parámetros definen la ubicación, y el tercero y cuarto definen el ancho y altura de la figura. Si no especifica una altura, el valor del ancho es usado como ancho y altura. El origen puede ser cambiado con la función ellipseMode().",
            +        "An ellipse with equal width and height is a circle. The origin may be changed with the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function."
            +      ],
            +      "params": {
            +        "x": "Número: coordenada x de la elipse.",
            +        "y": "Número: coordenada y de la elipse.",
            +        "w": "Número: ancho de la elipse.",
            +        "h": "Número: altura de la elipse.",
            +        "detail": "Integer: number of radial sectors to draw (for WebGL mode)"
            +      }
            +    },
            +    "circle": {
            +      "description": [
            +        "Draws a circle to the screen. A circle is a simple closed shape.It is the set of all points in a plane that are at a given distance from a given point, the centre.This function is a special case of the ellipse() function, where the width and height of the ellipse are the same. Height and width of the ellipse correspond to the diameter of the circle. By default, the first two parameters set the location of the centre of the circle, the third sets the diameter of the circle."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the centre of the circle.",
            +        "y": "Number: y-coordinate of the centre of the circle.",
            +        "d": "Number: diameter of the circle."
            +      }
            +    },
            +    "line": {
            +      "description": [
            +        "Dibuja una línea (un camino directo entre dos puntos) en la pantalla. La versión de line() con cuatro parámetros dibuja la línea en 2D. Para darle color a una línea, usa la función stroke(). Una línea no puede ser rellenada, por lo que la función fill() no afectará el color de una línea. Las líneas 2D son dibujadas con una ancho de un pixel por defecto, pero esto puede ser cambiado con la función strokeWeight()."
            +      ],
            +      "params": {
            +        "x1": "Número: coordenada x del primer punto.",
            +        "y1": "Número: coordenada y del primer punto.",
            +        "x2": "Número: coordenada x del segundo punto.",
            +        "y2": "Número: coordenada y del segundo punto.",
            +        "z1": "Number: the z-coordinate of the first point",
            +        "z2": "Number: the z-coordinate of the second point"
            +      }
            +    },
            +    "point": {
            +      "description": [
            +        "Dibuja un punto, una coordenada en el espacio de un pixel de dimensión. El primer parámetro es la coordenada horizontal del punto, el segundo valor es la coordenada vertical del punto. El color del punto es determinado por el trazado actual con la función stroke()."
            +      ],
            +      "params": {
            +        "x": "Número: coordenada x.",
            +        "y": "Número: coordenada y .",
            +        "z": "Number: (Optional) the z-coordinate (for WebGL mode)",
            +        "coordinate_vector": "p5.Vector: the coordinate vector"
            +      }
            +    },
            +    "quad": {
            +      "description": [
            +        "Dibuja un cuadrilátero, un polígono de cuatro lados. Es similar a un rectángulo, pero los ángulos entre sus bordes no están limitados a noventa grados. El primer par de parámetros (x1, y1) corresponde a las coordenadas del primer vértice y los pares siguientes deben seguir en el mismo orden, según las manecillas del reloj o en contra, alrededor de la figura a definir."
            +      ],
            +      "params": {
            +        "x1": "Número: coordenada x del primer punto.",
            +        "y1": "Número: coordenada y del primer punto.",
            +        "x2": "Número: coordenada x del segundo punto.",
            +        "y2": "Número: coordenada y del segundo punto.",
            +        "x3": "Número: coordenada x del tercer punto.",
            +        "y3": "Número: coordenada y del tercer punto.",
            +        "x4": "Número: coordenada x del cuarto punto.",
            +        "y4": "Número: coordenada y del cuarto punto.",
            +        "detailX": "Integer: (Optional) number of segments in the x-direction",
            +        "detailY": "Integer: (Optional) number of segments in the y-direction",
            +        "z1": "Number: the z-coordinate of the first point",
            +        "z2": "Number: the z-coordinate of the second point",
            +        "z3": "Number: the z-coordinate of the third point",
            +        "z4": "Number: the z-coordinate of the fourth point"
            +      }
            +    },
            +    "rect": {
            +      "description": [
            +        "Dibuja un rectángulo en la pantalla. Un rectángulo es una figura de cuatro lados con cada ángulo interior de noventa grados. Por defecto, los dos primeros parámetros definen la ubicación de la esquina superior izquierda, el tercero el ancho y el cuarto la altura. La manera en que estos parámetros son interpretados, sin embargo, puede ser cambiado con la función rectMode(). Los parámetros quinto, sexto, séptimo y octavo, si son especificados, determinan el radio de la esquina superior derecha, superior izquierda, inferior derecha e inferior izquierda, respectivamente. Si se omite un parámetro de radio de esquina, se usa el radio especificado por el valor anterior en la lista.",
            +        "The fifth, sixth, seventh and eighth parameters, if specified, determine corner radius for the top-left, top-right, lower-right and lower-left corners, respectively. An omitted corner radius parameter is set to the value of the previously specified radius value in the parameter list."
            +      ],
            +      "params": {
            +        "x": "Número: coordenada x del rectángulo.",
            +        "y": "Número: coordenada y del rectángulo.",
            +        "w": "Número: ancho del rectángulo.",
            +        "h": "Número: altura del rectángulo.",
            +        "tl": "Número: radio opcional de la esquina superior izquierda.",
            +        "tr": "Número: radio opcional de la esquina superior derecha.",
            +        "br": "Número: radio opcional de la esquina inferior derecha.",
            +        "bl": "Número: radio opcional de la esquina inferior izquierda.",
            +        "detailX": "Número:",
            +        "detailY": "Número:"
            +      }
            +    },
            +    "square": {
            +      "description": [
            +        "Draws a square to the screen. A square is a four-sided shape with every angle at ninety degrees, and equal side size. This function is a special case of the rect() function, where the width and height are the same, and the parameter is called \"s\" for side size. By default, the first two parameters set the location of the upper-left corner, the third sets the side size of the square. The way these parameters are interpreted, may be changed with the <a href=\"#/p5/rectMode\">rectMode()</a> function.",
            +        "The fourth, fifth, sixth and seventh parameters, if specified, determine corner radius for the top-left, top-right, lower-right and lower-left corners, respectively. An omitted corner radius parameter is set to the value of the previously specified radius value in the parameter list."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the square.",
            +        "y": "Number: y-coordinate of the square.",
            +        "s": "Number: side size of the square.",
            +        "tl": "Number: (Optional) optional radius of top-left corner.",
            +        "tr": "Number: (Optional) optional radius of top-right corner.",
            +        "br": "Number: (Optional) optional radius of bottom-right corner.",
            +        "bl": "Number: (Optional) optional radius of bottom-left corner."
            +      }
            +    },
            +    "triangle": {
            +      "description": [
            +        "Un triángulo es un plano creado por la conexión de tres puntos. Los primeros dos argumentos especifican el primer punto, los parámetros centrales especifican el segundo punto, y los dos últimos parámetros especifican el tercer punto."
            +      ],
            +      "params": {
            +        "x1": "Número: coordenada x del primer punto.",
            +        "y1": "Número: coordenada y del primer punto.",
            +        "x2": "Número: coordenada x del segundo punto.",
            +        "y2": "Número: coordenada y del segundo punto.",
            +        "x3": "Número: coordenada x del tercer punto.",
            +        "y3": "Número: coordenada y del tercer punto."
            +      }
            +    },
            +    "ellipseMode": {
            +      "description": [
            +        "Modifica la ubicación de donde las elipses son dibujadas, cambiando la manera en que los parámetros dados a ellipse() son interpretados. El modo por defecto es ellipseMode(CENTER), que interpreta los dos primeros parámetros de ellipse() como el centro de la figura, mientras que los parámetros tercero y cuarto son el ancho y la altura. ellipseMode(RADIUS) también usa los dos primeros parámetros de ellipse() como el punto central de la figura, pero usa los parámetros tercero y cuarto para especificar la mitad del ancho y la altura de la figura. ellipseMode(CORNER) interpreta los dos primeros parámetros de ellipse() como la esquina superior izquierda de la figura, mientras que los parámetros tercero y cuarto son el ancho y la altura. ellipseMode(CORNERS) interpreta los dos primeros parámetros de ellipse() como la ubicación de una esquina del rectángulo contenedor de la elipse, y los parámetros tercero y cuarto como la ubicación de la esquina opuesta. El parámetro debe ser escrito en MAYÚSCULAS porque Javascript es una lenguaje de programación que distingue entre mayúsculas y minúsculas.",
            +        "The default mode is CENTER, in which the first two parameters are interpreted as the shape's center point's x and y coordinates respectively, while the third and fourth parameters are its width and height.",
            +        "ellipseMode(RADIUS) also uses the first two parameters as the shape's center point's x and y coordinates, but uses the third and fourth parameters to specify half of the shapes's width and height.",
            +        "ellipseMode(CORNER) interprets the first two parameters as the upper-left corner of the shape, while the third and fourth parameters are its width and height.",
            +        "ellipseMode(CORNERS) interprets the first two parameters as the location of one corner of the ellipse's bounding box, and the third and fourth parameters as the location of the opposite corner.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "mode": "Constante: puede ser CENTER, RADIUS, CORNER, o CORNERS."
            +      }
            +    },
            +    "noSmooth": {
            +      "description": [
            +        "Dibuja las figuras geométricas con bordes no suaves (aliasing). Notar que smooth() está activo por defecto, así que es necesario ejectuar noSmooth() para deshabilitar el suavizado de las figuras geométricas, imágenes y tipografías."
            +      ]
            +    },
            +    "rectMode": {
            +      "description": [
            +        "Modifica la ubicación en que los rectángulos son dibujados, cambiando la manera en que los parámetros dados a rect() son interpretados. El modo por defecto es rectMode(CORNER), que interpreta los primeros dos parámetros de rect() como la esquina superior izquierda de la figura, mientras que los parámetros tercero y cuarto son su ancho y altura. rectMode(CORNERS) interpreta los dos primeros parámetros de rect() como la ubicación de una esquina, y los parámetros tercero y cuarto como la ubicación de la esquina opuesta. rectMode(CENTER) interpreta los dos primeros parámetros de rect() como el punto central de la figura, mientas que los parámetros tercero y cuarto son su ancho y altura. rectMode(RADIUS) también usa los dos primeros parámetros de rect()= como el punto central de la figura, pero usa los parámetros tercero y cuarto para especificar la mitad del ancho y la altura de la figura. Los parámetros deben ser escritos en MAYÚSCULAS porque Javascript es un lenguaje que distingue entre mayúsculas y minúsculas.",
            +        "The default mode is CORNER, which interprets the first two parameters as the upper-left corner of the shape, while the third and fourth parameters are its width and height.",
            +        "rectMode(CORNERS) interprets the first two parameters as the location of one of the corners, and the third and fourth parameters as the location of the diagonally opposite corner. Note, the rectangle is drawn between the coordinates, so it is not neccesary that the first corner be the upper left corner.",
            +        "rectMode(CENTER) interprets the first two parameters as the shape's center point, while the third and fourth parameters are its width and height.",
            +        "rectMode(RADIUS) also uses the first two parameters as the shape's center point, but uses the third and fourth parameters to specify half of the shape's width and height respectively.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "mode": "Constante: puede ser CORNER, CORNERS, CENTER, o RADIUS."
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "Dibuja todas las figuras geométricas con bordes suaves (sin aliasing). smooth() también mejorará la calidad de las imágenes cuyo tamaño ha sido modificado. Notar que smooth() está activo por defecto; noSmooth() puede ser usado para deshabilitar el suavizado de las figuras geométricas, imágenes y tipografía."
            +      ]
            +    },
            +    "strokeCap": {
            +      "description": [
            +        "Define el estilo de rendering de los extremos de las líneas. Estos extremos pueden ser cuadrados, extendidos o redondeados, cada uno de estos especifados con los parámetros correspondientes: SQUARE, PROJECT, y ROUND. El extremo por defecto es redonedeado (ROUND).",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "cap": "Constante: puede ser SQUARE, PROJECT, o ROUND."
            +      }
            +    },
            +    "strokeJoin": {
            +      "description": [
            +        "Define el estilo de las uniones que conectan segmentos de líneas. Estas uniones pueden ser tipo inglete, biseladas o redondeadas, y especificadas con los parámetros correspondientes: MITER, BEVEL, y ROUND. La unión por defecto es MITER.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "join": "Constante: puede ser MITER, BEVEL, o ROUND."
            +      }
            +    },
            +    "strokeWeight": {
            +      "description": [
            +        "Define el ancho del trazo usado para dibujar líneas, puntos y los bordes de las figuras geométricas. Todos los anchos son medidos en pixeles."
            +      ],
            +      "params": {
            +        "weight": "Número: el peso (en pixeles) del trazado"
            +      }
            +    },
            +    "bezier": {
            +      "description": [
            +        "Dibuja una curva Bezier cúbica en la pantalla. Estas curvas están definidas por una serie de puntos ancla y de control. Los primeros dos parámetros especifican el primer punto ancla y los dos últimos especifican el otro punto ancla, que se convierten en los puntos primero y último de la curva. Los parámetros en el medio especifican los dos puntos de control que definen la forma de la curva. De forma aproximada, los puntos de control atraen la curva hacia ellos. Las curvas Bezier fueron desarrolladas por el ingeniero automotriz Pierre Bezier, y son comúnmente usadas en gráficas computacionales para definir curvas de pendiente suave. Ver también curve().",
            +        "Bezier curves were developed by French automotive engineer Pierre Bezier, and are commonly used in computer graphics to define gently sloping curves. See also <a href=\"#/p5/curve\">curve()</a>."
            +      ],
            +      "params": {
            +        "x1": "Número: coordenada x del primer punto ancla",
            +        "y1": "Número: coordenada y del primer punto ancla",
            +        "x2": "Número: coordenada y del primer punto de control",
            +        "y2": "Número: coordenada x del segundo punto de control",
            +        "x3": "Número: coordenada x del segundo punto ancla",
            +        "y3": "Número: coordenada y del segundo punto ancla",
            +        "x4": "Número: coordenada z del primer punto de control",
            +        "y4": "Número: coordenada z del segundo punto ancla",
            +        "z1": "Número: coordenada x del primer punto de control",
            +        "z2": "Número: coordenada y del segundo punto de control",
            +        "z3": "Número: coordenada z del primer punto ancla",
            +        "z4": "Número: coordenada z del segundo punto de control"
            +      }
            +    },
            +    "bezierDetail": {
            +      "description": [
            +        "Sets the resolution at which Bezier's curve is displayed. The default value is 20.",
            +        "Note, This function is only useful when using the WEBGL renderer as the default canvas renderer does not use this information."
            +      ],
            +      "params": {
            +        "detail": "Number: resolution of the curves"
            +      }
            +    },
            +    "bezierPoint": {
            +      "description": [
            +        "Evalua la curva Bezier en la posición t para los puntos a, b, c, d. Los parámetros a y d son los puntos primero y último de la curva, mientras que b y c son los puntos de control. El parámetro final t varía entre 0 y 1. Esto puede ser realizado una vez con las coordenadas x y una segunda vez con las coordenadas y para obtener la ubicación de la curva Bezier en t."
            +      ],
            +      "returns": "el valor de la curva Bezier en la posición t",
            +      "params": {
            +        "a": "Número: coordenada del primer punto de la curva",
            +        "b": "Número: coordenada del primer punto de control de la curva",
            +        "c": "Número: coordenada del segundo punto de control de la curva",
            +        "d": "Número: coordenada del segundo punto de la curva",
            +        "t": "Número: valor entre 0 y 1"
            +      }
            +    },
            +    "bezierTangent": {
            +      "description": [
            +        "Evalua la tangente de la curva Bezier en la posición t para los puntos a, b, c, d. Los parámetros a y d son los puntos primero y último de la curva, mientras que b y c son los puntos de control. El parámetro final t varía entre 0  1."
            +      ],
            +      "returns": "la tangente en la posición t",
            +      "params": {
            +        "a": "Número: coordenada del primer punto de la curva",
            +        "b": "Número: coordenada del primer punto de control de la curva",
            +        "c": "Número: coordenada del segundo punto de control de la curva",
            +        "d": "Número: coordenada del segundo punto de la curva",
            +        "t": "Número: valor entre 0 y 1"
            +      }
            +    },
            +    "curve": {
            +      "description": [
            +        "Dibuja una línea curva en la pantalla entre dos puntos, dados como los cuatro parámetros centrales. Los dos primeros puntos son un punto de control, como si la curva viniera desde este punto, aunque no sea dibujado. Los dos últimos parámetros de forma similar describen el otro punto de control. SE pueden cerar curvas más largas, por medio del posicionamiento de varias funciones curve() juntas o usando curveVertex(). Una función adicional llamada curveTightness() provee control de la calidad visual de la curva. La función curve() es una implementación de la Catmull-Rom spline."
            +      ],
            +      "params": {
            +        "x1": "Número: coordenada x del punto de control inicial",
            +        "y1": "Número: coordenada y del punto de control inicial",
            +        "x2": "Número: coordenada y del primer punto",
            +        "y2": "Número: coordenada x del segundo punto",
            +        "x3": "Número: coordenada x del punto de control final",
            +        "y3": "Número: coordenada y del punto de control final",
            +        "x4": "Número: coordenada z del primer punto",
            +        "y4": "Número: coordenada z del segundo punto",
            +        "z1": "Número: coordenada x del primer punto",
            +        "z2": "Número: coordenada y del segundo punto",
            +        "z3": "Número: coordenada z del punto de control inicial",
            +        "z4": "Número: coordenada z del punto de control final"
            +      }
            +    },
            +    "curveDetail": {
            +      "description": [
            +        "Sets the resolution at which curves display. The default value is 20 while the minimum value is 3.",
            +        "This function is only useful when using the WEBGL renderer as the default canvas renderer does not use this information."
            +      ],
            +      "params": {
            +        "resolution": "Number: resolution of the curves"
            +      }
            +    },
            +    "curveTightness": {
            +      "description": [
            +        "Modifica la calidad de las formas creadas con curve() y curveVertex(). El parámetro tightness (tirantez) determina cómo la curva calza con los vértices. El valor 0.0 es el valor por defecto (este valor define las curvas Spline Catmull-Rom) y el valor 1.0 conecta todos los puntos con líneas rectas. Valores en el rango entre -5.0 y 5.0 deformarán las curvas pero las dejarán reconocibles, y a medida que los valores crecen en magnitud, se continuarán deformando."
            +      ],
            +      "params": {
            +        "amount": "Número: deformación de los vértices originales"
            +      }
            +    },
            +    "curvePoint": {
            +      "description": [
            +        "Evalua la curva en la posición t para los puntos a, b, c, d. El parámetro t varía entre 0 y 1, los puntos a y d son puntos en la cruva, y b y c son los puntos de control. Esto puede ser hecho una vez con las coordenadas x y una segunda vez con las coordenadas y para obtener la ubicación de la curva en t."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "a": "Número: coordenada del primer punto de la curva",
            +        "b": "Número: coordenada del primer punto de control de la curva",
            +        "c": "Número: coordenada del segundo punto de control de la curva",
            +        "d": "Número: coordenada del segundo punto de la curva",
            +        "t": "Número: valor entre 0 y 1"
            +      }
            +    },
            +    "curveTangent": {
            +      "description": [
            +        "Evalua la tangente de la curva en la posición t para los puntos a, b, c, d. El parámetro t varía entre 0 y 1, a y d son los puntos de la curva, b y c son los puntos de control."
            +      ],
            +      "returns": "la tangente en la posición t",
            +      "params": {
            +        "a": "Número: coordenada del primer punto de la curva",
            +        "b": "Número: coordenada del primer punto de control de la curva",
            +        "c": "Número: coordenada del segundo punto de control de la curva",
            +        "d": "Número: coordenada del segundo punto de la curva",
            +        "t": "Número: valor entre 0 y 1"
            +      }
            +    },
            +    "beginContour": {
            +      "description": [
            +        "Usa las funciones beginContour() y endContour() para crear figuras negativas dentro de figuras como el centro de la letra 'O'. beginContour() empieza la grabación de los vértices para la figura y endContour() finaliza la grabación. Los vértices que definen una figura negativa deben ser definidos en la dirección opuesta a la figura exterior. Primero dibuja los vértices de la figura exterior en el orden de las manecillas del reloj, y luego para figuras internas, dibuja vértices en el sentido contrario a las manecillas del reloj. Estas funciones solo pueden ser usadas dentro de un par beginShape()/endShape() y transformaciones como translate(), rotate(), y scale() no funcionan dentro de un par beginContour()/endContour(). Tampoco es posible usar otras figuras, como elupse() o rect() dentro.",
            +        "These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within."
            +      ]
            +    },
            +    "beginShape": {
            +      "description": [
            +        "El uso de las funciones beginShape() y endShape() permiten la creación de figuras más complejas. beginShape() empieza la grabación de vértices para una figura, mientras que endShape() termina la grabación. El valor del parámetro kind (tipo) define qué tipo de figuras serán creadas a partir de los vértices. Si no se especifica un modo, la figura puede ser cualquier polígono irregular. Los parámetros disponibles para beginShape() son POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, y QUAD_STRIP. Después de llamar a la función beginShape(), debe ser seguida por una serie de comandos vertex(). Para detener el dibujo de la figura, ejecuta endShape(). Cada figura será dibujada con el color de trazo y el color de relleno actual. Transformaciones como translate(), rotate(), y scale() no funcionan dentro de beginShape(). Tampoco es posible usar otras figuras como ellipse() o rect() dentro de beginShape().",
            +        "The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:",
            +        "POINTS Draw a series of points",
            +        "LINES Draw a series of unconnected line segments (individual lines)",
            +        "TRIANGLES Draw a series of separate triangles",
            +        "TRIANGLE_FAN Draw a series of connected triangles sharing the first vertex in a fan-like fashion",
            +        "TRIANGLE_STRIP Draw a series of connected triangles in strip fashion",
            +        "QUADS Draw a series of seperate quad",
            +        "QUAD_STRIP Draw quad strip using adjacent edges to form the next quad",
            +        "TESS (WebGl only) Handle irregular polygon for filling curve by explicit tessellation",
            +        "After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop drawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the current stroke color and filled with the fill color.",
            +        "Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "kind": "Constante: puede ser POINTS, LINES, TRIANGLES, TRIANGLE_FAN TRIANGLE_STRIP, QUADS, o QUAD_STRIP"
            +      }
            +    },
            +    "bezierVertex": {
            +      "description": [
            +        "Especifica las coordenadas de un vértice para una curva Bezier. Cada llamada a la función bezierVertex() define la posición de dos puntos de control y un punto ancla de una curva Bezier, añadiendo un nuevo segmento a la línea o figura. La primera vez que bezierVertex() es usada dentro de una llamada a beginShape(), debe ser antecedida por una llamada a la función vertex() para definir el primer punto ancla. Esta función debe ser usada entre beginShape() y endShape() y solo cuando no se ha especificado el parámetro MODE (modo) a beginShape().",
            +        "The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there is no MODE or POINTS parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "x2": "Número: coordenada x del primer punto de control la curva",
            +        "y2": "Número: coordenada y del primer punto de control la curva",
            +        "x3": "Número: coordenada x del segundo punto de control la curva",
            +        "y3": "Número: coordenada y del segundo punto de control la curva",
            +        "x4": "Número: coordenada x del primer punto ancla",
            +        "y4": "Número: coordenada y del primer punto ancla",
            +        "z2": "Number: z-coordinate for the first control point (for WebGL mode)",
            +        "z3": "Number: z-coordinate for the second control point (for WebGL mode)",
            +        "z4": "Number: z-coordinate for the anchor point (for WebGL mode)"
            +      }
            +    },
            +    "curveVertex": {
            +      "description": [
            +        "Especifica las coordenadas de un vértice para una curva. Esta función solo puede ser usada entre beginShape() y endShape() y cuando no se ha especificado el parámetro MODE en la función beginShape(). Los puntos primero y último en una serie de líneas curveVertex() serán usados para guiar el inicio y final de una curva. Un mínimo de cuatro puntos es requerido para dibujar una pequeña curva entre los puntos segundo y tercero, Añadir un quinto punto con curveVertex() dibujará la curva entre los puntos segundo, tercero y cuarto. La función curveVertex() es una implementación de las splines de Catmull-Rom.",
            +        "The first and last points in a series of curveVertex() lines will be used to guide the beginning and end of a the curve. A minimum of four points is required to draw a tiny curve between the second and third points. Adding a fifth point with curveVertex() will draw the curve between the second, third, and fourth points. The curveVertex() function is an implementation of Catmull-Rom splines."
            +      ],
            +      "params": {
            +        "x": "Número: coordenada x del vértice",
            +        "y": "Número: coordenada y del vértice",
            +        "z": "Number: (Optional) z-coordinate of the vertex (for WebGL mode)"
            +      }
            +    },
            +    "endContour": {
            +      "description": [
            +        "Usa las funciones beginContour() y endContour() para crear figuras negativas dentro de figuras como el centro de la letra 'O'. beginContour() empieza la grabación de los vértices para la figura y endContour() finaliza la grabación. Los vértices que definen una figura negativa deben ser definidos en la dirección opuesta a la figura exterior. Primero dibuja los vértices de la figura exterior en el orden de las manecillas del reloj, y luego para figuras internas, dibuja vértices en el sentido contrario a las manecillas del reloj. Estas funciones solo pueden ser usadas dentro de un par beginShape()/endShape() y transformaciones como translate(), rotate(), y scale() no funcionan dentro de un par beginContour()/endContour(). Tampoco es posible usar otras figuras, como elupse() o rect() dentro.",
            +        "These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within."
            +      ]
            +    },
            +    "endShape": {
            +      "description": [
            +        "La función endShape() es compañera de la función beginShape() y solo puede ser ejecutada tras la ejecución de beginShape(). Cuando endshape() es ejecutada, todos los datos de imagen definidos desde la llamada anterior a beginShape() son escritos en el buffer de imagen. La constante CLOSE se usa como valor para el parámetro MODE para cerrar la figura (para conectar el comienzo con el final)."
            +      ],
            +      "params": {
            +        "mode": "Constante: usa CLOSE para cerrar la figura."
            +      }
            +    },
            +    "quadraticVertex": {
            +      "description": [
            +        "Especifica las coordenadas de vértices par curvas Bezier cuadráticas. Cada llamada a quadraticVertex() define la posición de uno de los puntos de control y ancla de una curva Bezier, añadiendo un nuevo segmento a la línea o figura. La primera vez que quadraticVertex() es usada dentro de una llamada a beginShape(), debe ser precedida por una llamada a la función vertex() para definir el primer punto ancla. Esta función debe ser usada entre un par beginShape() y endShape() y solo cuando no se ha especificado el parámetro MODE de beginShape().",
            +        "This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there is no MODE or POINTS parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "cx": "Número: coordenada x del punto de control",
            +        "cy": "Número: coordenada y del punto de control",
            +        "x3": "Número: coordenada x del punto ancla",
            +        "y3": "Número: coordenada y del punto ancla",
            +        "cz": "Number: z-coordinate for the control point (for WebGL mode)",
            +        "z3": "Number: z-coordinate for the anchor point (for WebGL mode)"
            +      }
            +    },
            +    "vertex": {
            +      "description": [
            +        "Todas las figuras son construidas mediante la conexión de una serie de vértices. vertex() es usado para especificar las coordenadas de los vértices para puntos, líneas, triángulos, cuadriláteros y polígonos. Es usada exclusivamente dentro de un par de funciones beginShape() y endShape()."
            +      ],
            +      "params": {
            +        "x": "Número: coordenada x del vértice",
            +        "y": "Número: coordenada y del vértice",
            +        "z": "Number: z-coordinate of the vertex",
            +        "u": "Number: (Optional) the vertex's texture u-coordinate",
            +        "v": "Number: (Optional) the vertex's texture v-coordinate"
            +      }
            +    },
            +    "normal": {
            +      "description": [
            +        "Sets the 3d vertex normal to use for subsequent vertices drawn with <a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally nearly perpendicular to a shape's surface which controls how much light will be reflected from that part of the surface."
            +      ],
            +      "params": {
            +        "vector": "Vector: A p5.Vector representing the vertex normal.",
            +        "x": "Number: The x component of the vertex normal.",
            +        "y": "Number: The y component of the vertex normal.",
            +        "z": "Number: The z component of the vertex normal."
            +      }
            +    },
            +    "VERSION": {
            +      "description": [
            +        "Version of this p5.js."
            +      ]
            +    },
            +    "P2D": {
            +      "description": [
            +        "The default, two-dimensional renderer."
            +      ]
            +    },
            +    "WEBGL": {
            +      "description": [
            +        "One of the two render modes in p5.js: P2D (default renderer) and WEBGL Enables 3D render by introducing the third dimension: Z"
            +      ]
            +    },
            +    "ARROW": {},
            +    "CROSS": {},
            +    "HAND": {},
            +    "MOVE": {},
            +    "TEXT": {},
            +    "WAIT": {},
            +    "HALF_PI": {
            +      "description": [
            +        "HALF_PI es una constante matemática de valor 1.57079632679489661923. Es la mitad de la razón entre la circunferencia de un círculo y su diámetro. Es útil en combinación con las funciones trigonométricas sin() y cos()."
            +      ]
            +    },
            +    "PI": {
            +      "description": [
            +        "PI es una constante matemática de valor 3.14159265358979323846. Es la razón entre la circunferencia de un círculo y su diámetro. Es útil en combinación con las funciones trigonométricas sin() y cos()."
            +      ]
            +    },
            +    "QUARTER_PI": {
            +      "description": [
            +        "QUARTER_PI es una constante matemática de valor 0.7853982. Es un cuarto de la razón entre la circunferencia de un círculo y su diámetro. Es útil en combinación con las funciones trigonométricas sin() y cos()."
            +      ]
            +    },
            +    "TAU": {
            +      "description": [
            +        "TAU es un alias de TWO_PI, una constante matemática de valor 6.28318530717958647693. Es el doble de la razón entre la circunferencia de un círculo y su diámetro. Es útil en combinación con las funciones trigonométricas sin() y cos()."
            +      ]
            +    },
            +    "TWO_PI": {
            +      "description": [
            +        "TWO_PI es una constante matemática de valor 6.28318530717958647693. Es el doble de la razón entre la circunferencia de un círculo y su diámetro. Es útil en combinación con las funciones trigonométricas sin() y cos()."
            +      ]
            +    },
            +    "DEGREES": {
            +      "description": [
            +        "Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which p5.js interprets and calculates angles (either DEGREES or RADIANS)."
            +      ]
            +    },
            +    "RADIANS": {
            +      "description": [
            +        "Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which p5.js interprets and calculates angles (either RADIANS or DEGREES)."
            +      ]
            +    },
            +    "CORNER": {},
            +    "CORNERS": {},
            +    "RADIUS": {},
            +    "RIGHT": {},
            +    "LEFT": {},
            +    "CENTER": {},
            +    "TOP": {},
            +    "BOTTOM": {},
            +    "BASELINE": {},
            +    "POINTS": {},
            +    "LINES": {},
            +    "LINE_STRIP": {},
            +    "LINE_LOOP": {},
            +    "TRIANGLES": {},
            +    "TRIANGLE_FAN": {},
            +    "TRIANGLE_STRIP": {},
            +    "QUADS": {},
            +    "QUAD_STRIP": {},
            +    "TESS": {},
            +    "CLOSE": {},
            +    "OPEN": {},
            +    "CHORD": {},
            +    "PIE": {},
            +    "PROJECT": {},
            +    "SQUARE": {},
            +    "ROUND": {},
            +    "BEVEL": {},
            +    "MITER": {},
            +    "RGB": {},
            +    "HSB": {
            +      "description": [
            +        "HSB (hue, saturation, brightness) is a type of color model. You can learn more about it at <a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>."
            +      ]
            +    },
            +    "HSL": {},
            +    "AUTO": {
            +      "description": [
            +        "AUTO allows us to automatically set the width or height of an element (but not both), based on the current height and width of the element. Only one parameter can be passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time."
            +      ]
            +    },
            +    "ALT": {},
            +    "BACKSPACE": {},
            +    "CONTROL": {},
            +    "DELETE": {},
            +    "DOWN_ARROW": {},
            +    "ENTER": {},
            +    "ESCAPE": {},
            +    "LEFT_ARROW": {},
            +    "OPTION": {},
            +    "RETURN": {},
            +    "RIGHT_ARROW": {},
            +    "SHIFT": {},
            +    "TAB": {},
            +    "UP_ARROW": {},
            +    "BLEND": {},
            +    "REMOVE": {},
            +    "ADD": {},
            +    "DARKEST": {},
            +    "LIGHTEST": {},
            +    "DIFFERENCE": {},
            +    "SUBTRACT": {},
            +    "EXCLUSION": {},
            +    "MULTIPLY": {},
            +    "SCREEN": {},
            +    "REPLACE": {},
            +    "OVERLAY": {},
            +    "HARD_LIGHT": {},
            +    "SOFT_LIGHT": {},
            +    "DODGE": {},
            +    "BURN": {},
            +    "THRESHOLD": {},
            +    "GRAY": {},
            +    "OPAQUE": {},
            +    "INVERT": {},
            +    "POSTERIZE": {},
            +    "DILATE": {},
            +    "ERODE": {},
            +    "BLUR": {},
            +    "NORMAL": {},
            +    "ITALIC": {},
            +    "BOLD": {},
            +    "BOLDITALIC": {},
            +    "CHAR": {},
            +    "WORD": {},
            +    "LINEAR": {},
            +    "QUADRATIC": {},
            +    "BEZIER": {},
            +    "CURVE": {},
            +    "STROKE": {},
            +    "FILL": {},
            +    "TEXTURE": {},
            +    "IMMEDIATE": {},
            +    "IMAGE": {},
            +    "NEAREST": {},
            +    "REPEAT": {},
            +    "CLAMP": {},
            +    "MIRROR": {},
            +    "LANDSCAPE": {},
            +    "PORTRAIT": {},
            +    "GRID": {},
            +    "AXES": {},
            +    "LABEL": {},
            +    "FALLBACK": {},
            +    "print": {
            +      "description": [
            +        "La función print() escribe en la consola del navegador. Esta función es a menudo de ayuda para observar los datos que un programa está produciendo. Esta función crea una nueva línea de texto por cada ejecución de la función. Elementos individuales pueden ser separados por comillas ('') y unidos con el operador de adición (+). Aunque print() es similar a console.log(), no llama a console.log() directamente, para simular una manera más simple de entender el comportamiento del programa. Por esto mismo, es más lento. Para resultados más rápidos, usar directamente console.log().",
            +        "Note that calling print() without any arguments invokes the window.print() function which opens the browser's print dialog. To print a blank line to console you can write print('\\n')."
            +      ],
            +      "params": {
            +        "contents": "Cualquiera: cualquier combinación de número, string, objeto, boolean o arreglo a imprimir"
            +      }
            +    },
            +    "frameCount": {
            +      "description": [
            +        "La variable de sistema frameCount contiene el número de cuadros (frames) que se han mostrado desde que el programa empezó a ejecutarse. Dentro de setup() el valor es 0, después de la primera iteración de draw() es 1, etc."
            +      ]
            +    },
            +    "deltaTime": {
            +      "description": [
            +        "The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time difference between the beginning of the previous frame and the beginning of the current frame in milliseconds.",
            +        "This variable is useful for creating time sensitive animation or physics calculation that should stay constant regardless of frame rate."
            +      ]
            +    },
            +    "focused": {
            +      "description": [
            +        "Confirma si la ventana de un programa de p5.js está en foco, lo que significa que el bosquejo aceptará entradas desde el ratón o teclado. Esta variable es verdadera (true) si la ventana está en foco y falsa (false) si no."
            +      ]
            +    },
            +    "cursor": {
            +      "description": [
            +        "Define el cursor como un símbolo predeterminado o una imagen, o hace el cursor visible si es que estaba escondido. Si estás tratando de asignar una imagen al cursor, el tamaño recomendado es 16x16 o 32x32 pixeles. No es posible cargar una imagen al cursor si estás exportando tu programa a la Web, y no todos los modos funcionan con todos los navegadores. Los valores de los parámetros x e y deben ser menores a la dimensión de la imagen."
            +      ],
            +      "params": {
            +        "type": "Número|Constante: puede ser ARROW, CROSS, HAND, MOVE, TEXT, o WAIT, o la dirección de una imagen",
            +        "x": "Número: el punto activo horizontal del cursor",
            +        "y": "Número: el punto activo vertical del cursor"
            +      }
            +    },
            +    "frameRate": {
            +      "description": [
            +        "Especifica el número de cuadros mostrados por segundo. Por ejemplo, la llamada a la función frameRate(30), tratará de refrescar 30 veces por segundo. Si el procesador no es lo suficientemente rápido para mantener la tasa especificada, la tasa de cuadros por segundo no será lograda. Definir la tasa de cuadros por segundo dentro de setup() es lo recomendable. La tasa por defecto es de 60 veces por segundo. Esto es lo mismo que setFrameRate(val). Llamar a la función frameRate() sin argumentos retorna la tasa actual. Esto es lo mismo que getFrameRate(). Llamar a la función frameRate() con arugmentos que no son de tipo número o no son positivos también retornarán la tasa actual.",
            +        "Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate. The draw function must run at least once before it will return a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.",
            +        "Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not of the type numbers or are non positive also returns current framerate."
            +      ],
            +      "params": {
            +        "fps": "Número: número de cuadros a ser mostrados cada segundo."
            +      }
            +    },
            +    "noCursor": {
            +      "description": [
            +        "Esconde el cursor."
            +      ]
            +    },
            +    "displayWidth": {
            +      "description": [
            +        "Variable de sistema que almacena el ancho de la pantalla mostrada. Esto es usado para correr un programa a pantalla completa en cualquier dimensión de pantalla."
            +      ]
            +    },
            +    "displayHeight": {
            +      "description": [
            +        "Variable de sistema que almacena la altura de la pantalla mostrada. Esto es usado para correr un programa a pantalla completa en cualquier dimensión de pantalla."
            +      ]
            +    },
            +    "windowWidth": {
            +      "description": [
            +        "Variable de sistema que almacena el ancho interior de la ventana del navegador, equivale a window.innerWidth."
            +      ]
            +    },
            +    "windowHeight": {
            +      "description": [
            +        "Variable de sistema que almacena la altura interior de la ventana del navegador, equivale a window.innerHeight."
            +      ]
            +    },
            +    "windowResized": {
            +      "description": [
            +        "La función windowResized() es llamada cada vez que la ventana del navegador cambia de tamaño. Es un buen lugar para cambiar las dimensiones del lienzo o hacer cualquier otro ajuste necesario para acomodar las nuevas dimensiones de la ventana."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional Event callback argument."
            +      }
            +    },
            +    "width": {
            +      "description": [
            +        "Variable de sistema que almacena el ancho del lienzo dibujado. Este valor es definido por el primer parámetro de la función createCanvas(). Por ejemplo, la llamada a la función (320, 240) define la variable width al valor 320. El valor por defecto de ancho es de 100 si es que createCanvas() no ha sido usado en el programa."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "ariable de sistema que almacena la altura del lienzo dibujado. Este valor es definido por el primer parámetro de la función createCanvas(). Por ejemplo, la llamada a la función (320, 240) define la variable width al valor 240. El valor por defecto de ancho es de 100 si es que createCanvas() no ha sido usado en el programa."
            +      ]
            +    },
            +    "fullscreen": {
            +      "description": [
            +        "Si se da un argumento, define que el bosquejo esté a pantalla completa basado en el valor del argumento. Si no se da un argumento, retorna el estado actual de pantalla completa. Notar que debido a restricciones del navegador esto solo puede ser llamado con una entrada de parte del usuario, por ejemplo, cuando se presiona el ratón como en el ejemplo."
            +      ],
            +      "returns": "Boolean: estado de pantalla completa actual",
            +      "params": {
            +        "val": "Boolean: define si el bosquejo debe estar a pantalla completa o no."
            +      }
            +    },
            +    "pixelDensity": {
            +      "description": [
            +        "Define el escalamiento de pixeles para monitores de alta densidad de pixeles. Por defecto, la densidad de pixeles es definida para calzar con la densidad del monitor, ejecuta pixelDensity() para que no sea así. Llamar a pixelDensity() sin argumentos retorna la densidad de pixeles actual del bosquejo."
            +      ],
            +      "params": {
            +        "val": "Número: si es que el bosquejo debe ser escalado y cuánto."
            +      }
            +    },
            +    "displayDensity": {
            +      "description": [
            +        "Retorna la densidad de pixeles del monitor actual en que el bosquejo está corriendo."
            +      ],
            +      "returns": "Número: la densidad de pixeles actual del monitor"
            +    },
            +    "getURL": {
            +      "description": [
            +        "Retorna la URL actual."
            +      ],
            +      "returns": "String: URL"
            +    },
            +    "getURLPath": {
            +      "description": [
            +        "Retorna la dirección URL como un arreglo"
            +      ],
            +      "returns": "Arreglo: los componentes de la dirección"
            +    },
            +    "getURLParams": {
            +      "description": [
            +        "Retorna los parámetros de la URL actual como un objeto."
            +      ],
            +      "returns": "Objeto: parámetros de la URL"
            +    },
            +    "preload": {
            +      "description": [
            +        "La función preload() es ejecutada antes de setup(), es usada para manejar la carga asíncrona de archivos externos. Si se define una función preload(), setup() esperará hasta que las llamadas a funciones load hayan terminado. Solo se deben incluir instrucciones de carga dentro de preload() (loadImage, loadJSON, loadFont, loadStrings, etc).",
            +        "By default the text \"loading...\" will be displayed. To make your own loading page, include an HTML element with id \"p5_loading\" in your page. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>."
            +      ]
            +    },
            +    "setup": {
            +      "description": [
            +        "La función setup() es ejecutada una vez, cuando el programa empieza. Es usada para definir propiedades iniciales como amaño de la pantalla y color de fondo y para cargar medios como imágenes y tipografías cuando el programa empieza. Solo puede haber una función setup() en cada programa y no debe ser llamada después de su ejecución inicial. Nota: las variables declaradas dentro de setup() no son accesibles dentro de otras funciones, como draw().",
            +        "Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other functions, including <a href=\"#/p5/draw\">draw()</a>."
            +      ]
            +    },
            +    "draw": {
            +      "description": [
            +        "La función draw() es ejecutada después de setup(), y ejecuta contínuamente las líneas de código dentro de su bloque hasta que el programa es detenido o se ejecuta la función noLoop(). Notar que si noLoop() es ejecutada dentro de setup(), draw() igualmente será ejecutado una vez antes de parar. La función draw() es ejecutada automáticamente y nunca debiera ser ejecutada explícitamente. Siempre debería ser controlada con noLoop(), redraw() y loop(). Después de que noLoop() detiene la ejecución del código dentro de draw(), redraw() causa que el código dentro de draw() se ejecute una vez, y loop() causa que el código dentro de draw() siga ejecutándose de forma continua. El número de veces que draw() se ejecuta por segundo puede ser controlado con la función frameRate(). Solo puede haber una función draw() en cada bosquejo, y draw() solo debe existir si quieres que el código corra de forma continua, o para procesar eventos como mousePressed(). Algunas veces, podrías querer ejecutar una función draw() vacía, como se mostró en el ejemplo más arriba. Es importante notar que el sistema de coordenadas de dibujo será reiniciado al principio de cada ejecución de la función draw(). Si cualquier transformación es hecha dentro de draw() (por ejemplo: escalar, rotar, trasladar), sus efectos serán anulados al principio de cada ejecución de draw(), así que las transformaciones no se acumulan en el tiempo. Por el otro lado, el estilo aplicado (color de relleno, color de trazado) sí se mantendrá en efecto.",
            +        "It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After <a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the code inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code inside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.",
            +        "The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with the <a href=\"#/p5/frameRate\">frameRate()</a> function.",
            +        "There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must exist if you want the code to run continuously, or to process events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in your program, as shown in the above example.",
            +        "It is important to note that the drawing coordinate system will be reset at the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed within <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be undone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate over time. On the other hand, styling applied (ex: fill, stroke, etc) will remain in effect."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Remueve el bosquejo de p5 completamente. Esto removerá el lienzo y cualquier otro elemento creado por p5.js. También detendrá el bucle de dibujo y desvinculará cualquier propiedad o método global de la ventana. Dejará una variable p5 en caso que quieras crear un nuevo bosquejo p5. Si quieres, puedes definir p5 = null para borrar esta variable."
            +      ]
            +    },
            +    "disableFriendlyErrors": {
            +      "description": [
            +        "Allows for the friendly error system (FES) to be turned off when creating a sketch, which can give a significant boost to performance when needed. See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'> disabling the friendly error system</a>."
            +      ]
            +    },
            +    "let": {
            +      "description": [
            +        "Creates and names a new variable. A variable is a container for a value.",
            +        "Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope. This means that the variable only exists within the <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> block</a> that it is created within.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>: Declares a block scope local variable, optionally initializing it to a value."
            +      ]
            +    },
            +    "const": {
            +      "description": [
            +        "Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>, a constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value, however constants cannot be reassigned once they are declared. Although it is noteworthy that for non-primitive data types like objects & arrays, their elements can still be changeable. So if a variable is assigned an array, you can still add or remove elements from the array but cannot reassign another array to it. Also unlike <code>let</code>, you cannot declare variables without value using const.",
            +        "Constants have block-scope. This means that the constant only exists within the <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> block</a> that it is created within. A constant cannot be redeclared within a scope in which it already exists.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>: Declares a read-only named constant. Constants are block-scoped, much like variables defined using the 'let' statement. The value of a constant can't be changed through reassignment, and it can't be redeclared."
            +      ]
            +    },
            +    "===": {
            +      "description": [
            +        "The strict equality operator <a href=\"#/p5/===\">===</a> checks to see if two values are equal and of the same type.",
            +        "A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>: The non-identity operator returns true if the operands are not equal and/or not of the same type.",
            +        "Note: In some examples around the web you may see a double-equals-sign <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>, used for comparison instead. This is the non-strict equality operator in Javascript. This will convert the two values being compared to the same type before comparing them."
            +      ]
            +    },
            +    ">": {
            +      "description": [
            +        "The greater than operator <a href=\"#/p5/>\">></a> evaluates to true if the left value is greater than the right value. <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\"> There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    ">=": {
            +      "description": [
            +        "The greater than or equal to operator <a href=\"#/p5/>=\">>=</a> evaluates to true if the left value is greater than or equal to the right value.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "<": {
            +      "description": [
            +        "The less than operator <a href=\"#/p5/<\"><</a> evaluates to true if the left value is less than the right value.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "<=": {
            +      "description": [
            +        "The less than or equal to operator <a href=\"#/p5/<=\"><=</a> evaluates to true if the left value is less than or equal to the right value.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "if-else": {
            +      "description": [
            +        "The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.",
            +        "A condition is placed between the parenthesis following 'if', when that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>, the code between the following curly braces is run. Alternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>, the code between the curly braces of 'else' block is run instead. Writing an else block is optional.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>: The 'if' statement executes a statement if a specified condition is truthy. If the condition is falsy, another statement can be executed"
            +      ]
            +    },
            +    "function": {
            +      "description": [
            +        "Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>. A <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.",
            +        "Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a> are variables that are scoped to the function, that can be assigned a value when calling the function.Multiple parameters can be given by seperating them with commas.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>: Declares a function with the specified parameters."
            +      ]
            +    },
            +    "return": {
            +      "description": [
            +        "Specifies the value to be returned by a function. For more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\"> the MDN entry for return</a>."
            +      ]
            +    },
            +    "boolean": {
            +      "description": [
            +        "Convierte un número o string a su representación en boolean. Para números, cualquier valor distinto de cero (positivo o ne gativo), evalua a true, mientras que cero evalua a falso. Para un string, el valor true evalua a true, mientras que cualquier otro valor evalua a falso. Cuando un arreglo de números o strings es introducido, entonces un arreglo de booleans de la misma longitud es retornado."
            +      ],
            +      "returns": "Boolean: representación en formato boolean del valor",
            +      "params": {
            +        "n": "String|Boolean|Número|Arreglo: valor a procesar"
            +      }
            +    },
            +    "string": {
            +      "description": [
            +        "A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript. A string is a series of text characters. In Javascript, a string value must be surrounded by either single-quotation marks(') or double-quotation marks(\").",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>: A string is a sequence of characters used to represent text."
            +      ]
            +    },
            +    "number": {
            +      "description": [
            +        "A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript. A number can be a whole number or a decimal number.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a>"
            +      ]
            +    },
            +    "object": {
            +      "description": [
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:  An <a href=\"#/p5/object\">object</a> is a collection of related data and/or  functionality (which usually consists of several variables and functions —  which are called properties and methods when they are inside objects.)"
            +      ]
            +    },
            +    "class": {
            +      "description": [
            +        "Creates and names a <a href=\"#/p5/class\">class</a> which is a template for the creation of <a href=\"#/p5/objects\">objects</a>.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>: The class declaration creates a new Class with a given name using prototype-based inheritance."
            +      ]
            +    },
            +    "for": {
            +      "description": [
            +        "<a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one section of code multiple times.",
            +        "A 'for loop' consists of three different expressions inside of a parenthesis, all of which are optional.These expressions are used to control the number of times the loop is run.The first expression is a statement that is used to set the initial state for the loop.The second expression is a condition that you would like to check before each loop. If this expression returns false then the loop will exit.The third expression is executed at the end of each loop. These expression are separated by ; (semi-colon).In case of an empty expression, only a semi-colon is written.",
            +        "The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second and third expression.",
            +        "As with any loop, it is important to ensure that the loop can 'exit', or that the test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop is the second expression detailed above. Ensuring that this expression can eventually become false ensures that your loop doesn't attempt to run an infinite amount of times, which can crash your browser.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>: Creates a loop that executes a specified statement until the test condition evaluates to false. The condition is evaluated after executing the statement, resulting in the specified statement executing at least once."
            +      ]
            +    },
            +    "while": {
            +      "description": [
            +        "<a href=\"#/p5/while\">while</a> creates a loop that is useful for executing one section of code multiple times.",
            +        "With a 'while loop', the code inside of the loop body (between the curly braces) is run repeatedly until the test condition (inside of the parenthesis) evaluates to false. The condition is tested before executing the code body with <a href=\"#/p5/while\">while</a>, so if the condition is initially false the loop body, or statement, will never execute.",
            +        "As with any loop, it is important to ensure that the loop can 'exit', or that the test condition will eventually evaluate to false. This is to keep your loop from trying to run an infinite amount of times, which can crash your browser.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>: The while statement creates a loop that executes a specified statement as long as the test condition evaluates to true.The condition is evaluated before executing the statement."
            +      ]
            +    },
            +    "createCanvas": {
            +      "description": [
            +        "Crea un elemento canvas en el documento, y define sus dimensiones medidas en pixeles. Este método debe ser llamado solo una vez al comienzo de la función setup(). Llamar a la función createCanvas() más de una vez en un bosquejo puede resultar en comportamientos impredecibles. Si quieres más de un lienzo donde dibujar, debes usar la función createGraphics() (escondido por defecto, pero puede ser mostrado), Las variables de sistema width (ancho) y height (altura) son definidas por los parámetros pasados a la función. Si createCanvas() no es usado, la ventana tendrá un tamaño por defecto de 100 x 100 pixeles. Para más maneras de posicionar el lienzo, ver la sección de posición del lienzo.",
            +        "Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0) is positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code> is set to <code>WEBGL</code>), the origin is positioned at the center of the canvas. See <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.",
            +        "The system variables width and height are set by the parameters passed to this function. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the window will be given a default size of 100x100 pixels.",
            +        "For more ways to position the canvas, see the <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'> positioning the canvas</a> wiki page."
            +      ],
            +      "returns": "Objeto: lienzo generado",
            +      "params": {
            +        "w": "Número: ancho del lienzo",
            +        "h": "Número: altura del lienzo",
            +        "renderer": "Constante: P2D o WEBGL"
            +      }
            +    },
            +    "resizeCanvas": {
            +      "description": [
            +        "Redimensiona el linezo al ancho y la altura dados. El lienzo será borrado y la función draw() será llamada inmediatamente, permitiendo que el bosquejo se ajuste al nuevo lienzo"
            +      ],
            +      "params": {
            +        "w": "Number: width of the canvas",
            +        "h": "Number: height of the canvas",
            +        "noRedraw": "Boolean: (Optional) don't redraw the canvas immediately"
            +      }
            +    },
            +    "noCanvas": {
            +      "description": [
            +        "Remueve el lienzo por defecto para un bosquejo de p5 que no requiere un lienzo."
            +      ]
            +    },
            +    "createGraphics": {
            +      "description": [
            +        "Crea y retorna un nuevo objeto p5.Renderer. Usa esta clase si necesitas dibujar fuera de pantalla en un buffer gráfico. Los dos parámetros definen el ancho y la altura en pixeles."
            +      ],
            +      "returns": "buffer gráfico fuera de pantalla",
            +      "params": {
            +        "w": "Número: ancho del buffer gráfico fuera de pantalla",
            +        "h": "Número: altura del buffer gráfico fuera de pantalla",
            +        "renderer": "Constante: P2D o WEBGL, si no se define es P2D por defecto"
            +      }
            +    },
            +    "blendMode": {
            +      "description": [
            +        "Combina los pixeles en la ventana según el modo definido. Existen distintas maneras de combinar los pixeles de la fuente (A) con los ya existentes en la pantalla mostrada (B). TODO",
            +        "<em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer. <em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer."
            +      ],
            +      "params": {
            +        "mode": "Constante: modo de combinar del lienzo"
            +      }
            +    },
            +    "drawingContext": {
            +      "description": [
            +        "The p5.js API provides a lot of functionality for creating graphics, but there is some native HTML5 Canvas functionality that is not exposed by p5. You can still call it directly using the variable <code>drawingContext</code>, as in the example shown. This is the equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>. See this <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\"> reference for the native canvas API</a> for possible drawing functions you can call."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Detiene la ejecución continua del código de draw() de p5.js. Si se llama a la función loop(), el código dentro de draw() empieza a correr de forma continua nuevamente. Si se usa noLoop() dentro de setup(), debe ser la última línea de código dentro del bloque. Cuando se usa noLoop(), no es posible manipular o acceder a la pantalla dentro de las funciones que manejan eventos como mousePressed() o keyPressed(). En vez de eso, usa estas funciones para llamar a redraw() o loop(), que permitirán la ejecución de draw(), lo que permite el refresco correcto de la pantalla. Esto significa que cuando noLoop() ha sido ejecutado, no se sigue dibujando, y funciones como saveFrame() o loadPixels() no se pueden usar. Notar que si el bosquejo es escalado, redraw() será llamado para actualizar el bosquejo, incluso si noLoop() ha sido ejecutada. Por otro lado, el bosquejo entrará a un estado singular, hasta que loop() sea ejecutado.",
            +        "When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate or access the screen inside event handling functions such as <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to call <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>, which will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen properly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been called, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a> or <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.",
            +        "Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will be called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a> has been specified. Otherwise, the sketch would enter an odd state until <a href=\"#/p5/loop\">loop()</a> was called.",
            +        "Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop()."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Por defecto, p5.js repite de forma continua la función draw(), ejecutado el código dentro de su bloque. Sin embargo, el bucle de dibujo puede ser detenido llamando a la función noLoop(). En ese caso, el bucle de draw() puede ser retomado con loop().",
            +        "Avoid calling loop() from inside setup().",
            +        "Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop()."
            +      ]
            +    },
            +    "isLooping": {
            +      "description": [
            +        "By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously, executing the code within it. If the sketch is stopped with <a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>, isLooping() returns the current state for use within custom event handlers."
            +      ]
            +    },
            +    "push": {
            +      "description": [
            +        "La función push() graba la configuración actual de estilo de dibujo, y pop() restaura esta configuración. Notar que estas funciones siempre son usadas en conjunto. Permiten cambiar las configuraciones de estilo y transformaciones y luego volver a lo que tenías. Cuando un nuevo estado es iniciado con push(), construye encima de la información actual de estilo y transformación. Las funciones push() y pop() pueden ser embebidas para proveer más control (ver el segundo ejemplo para una demostración). push() almacena información relacionada a la configuración de estado de transformación y de estulo actual, controlada por las siguientes funciones: fill(), stroke(), tint(), strokeWeight(), strokeCap(), strokeJoin(), imageMode(), rectMode(), ellipseMode(), colorMode(), textAlign(), textFont(), textMode(), textSize(), textLeading().",
            +        "<a href=\"#/p5/push\">push()</a> stores information related to the current transformation state and style settings controlled by the following functions: <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"#/p5/strokeCap\">strokeCap()</a>, <a href=\"#/p5/strokeJoin\">strokeJoin()</a>, <a href=\"#/p5/imageMode\">imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href=\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5/textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/noiseSeed\">noiseSeed()</a>.",
            +        "In WEBGL mode additional style settings are stored. These are controlled by the following functions: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ambientLight\">ambientLight()</a>, <a href=\"#/p5/directionalLight\">directionalLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">shininess()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> and <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "pop": {
            +      "description": [
            +        "La función push() graba la configuración actual de estilo de dibujo, y pop() restaura esta configuración. Notar que estas funciones siempre son usadas en conjunto. Permiten cambiar las configuraciones de estilo y transformaciones y luego volver a lo que tenías. Cuando un nuevo estado es iniciado con push(), construye encima de la información actual de estilo y transformación. Las funciones push() y pop() pueden ser embebidas para proveer más control (ver el segundo ejemplo para una demostración). push() almacena información relacionada a la configuración de estado de transformación y de estulo actual, controlada por las siguientes funciones: fill(), stroke(), tint(), strokeWeight(), strokeCap(), strokeJoin(), imageMode(), rectMode(), ellipseMode(), colorMode(), textAlign(), textFont(), textMode(), textSize(), textLeading().",
            +        "<a href=\"#/p5/push\">push()</a> stores information related to the current transformation state and style settings controlled by the following functions: <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"#/p5/strokeCap\">strokeCap()</a>, <a href=\"#/p5/strokeJoin\">strokeJoin()</a>, <a href=\"#/p5/imageMode\">imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href=\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5/textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/noiseSeed\">noiseSeed()</a>.",
            +        "In WEBGL mode additional style settings are stored. These are controlled by the following functions: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ambientLight\">ambientLight()</a>, <a href=\"#/p5/directionalLight\">directionalLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">shininess()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> and <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "redraw": {
            +      "description": [
            +        "Ejecuta una vez el código dentro de la función draw(). Esta función permite al programa actualizar la ventana mostrada solamente cuando es necesario, por ejemplo, cuando un evento registrado por mousePressed() o keyPressed() ocurre. En la estructura de un programa, solo hace sentido llamar a redraw() dentro de eventos como mousePressed(). Esto es porque redraw() no hace que draw() se ejecute de forma inmediata (solo define una indicación de que se necesita un refresco). La función redraw() no funciona de forma correcta cuando se llama dentro de la función draw(). Para habilitar y deshabilitar animaciones, usa las funcioens loop() y noLoop(). Adicionalmente, puedes definir el número de veces que se dibuja por cada llamada a este método. Para esto, añade un entero como parámetro único a la función, que señale cuántas veces se requiere dibujar.",
            +        "In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a> within events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This is because <a href=\"#/p5/redraw\">redraw()</a> does not run <a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates an update is needed).",
            +        "The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when called inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations, use <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.",
            +        "In addition you can set the number of redraws per method call. Just add an integer as single parameter for the number of redraws."
            +      ],
            +      "params": {
            +        "n": "Entero: redibuja n-veces. Por defecto el valor es 1"
            +      }
            +    },
            +    "p5": {
            +      "description": [
            +        "The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal \"global mode\". This is an advanced topic. A short description and example is included below. Please see <a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\"> Dan Shiffman's Coding Train video tutorial</a> or this <a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a> for more info.",
            +        "By default, all p5.js functions are in the global namespace (i.e. bound to the window object), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this might be inconvenient if you are mixing with other JS libraries (synchronously or asynchronously) or writing long programs of your own. p5.js currently supports a way around this problem called \"instance mode\". In instance mode, all p5 functions are bound up in a single variable instead of polluting your global namespace.",
            +        "Optionally, you can specify a default container for the canvas and any other elements to append to with a second argument. You can give the ID of an element in your html, or an html node itself.",
            +        "Note that creating instances like this also allows you to have more than one p5 sketch on a single web page, as they will each be wrapped up with their own set up variables. Of course, you could also use iframes to have multiple sketches in global mode."
            +      ],
            +      "params": {
            +        "sketch": "Object: a function containing a p5.js sketch",
            +        "node": "String|Object: ID or pointer to HTML DOM node to contain sketch in"
            +      }
            +    },
            +    "applyMatrix": {
            +      "description": [
            +        "Multiplica la matriz actual por la especificada según los parámetros. Esto es muy lento porque tratará de calcular el inverso de la transformada, así que evítalo cuando sea posible",
            +        "The naming of the arguments here follows the naming of the <a href= \"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\"> WHATWG specification</a> and corresponds to a transformation matrix of the form: <blockquote>",
            +        "<img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\" alt=\"The transformation matrix used when applyMatrix is called\"/> </blockquote>"
            +      ],
            +      "params": {
            +        "a": "Número: números que definen la matriz 3x2 a multiplicar",
            +        "b": "Número: números que definen la matriz 3x2 a multiplicar",
            +        "c": "Número: números que definen la matriz 3x2 a multiplicar",
            +        "d": "Número: números que definen la matriz 3x2 a multiplicar",
            +        "e": "Número: números que definen la matriz 3x2 a multiplicar",
            +        "f": "Número: números que definen la matriz 3x2 a multiplicar"
            +      }
            +    },
            +    "resetMatrix": {
            +      "description": [
            +        "Reemplaza la matriz actual con la matriz identidad"
            +      ]
            +    },
            +    "rotate": {
            +      "description": [
            +        "Rota una figura según el monto especificado por el parámetro ángulo. Esta función toma en cuenta el modo de ángulo definido por angleMode(), así que los ángulos pueden ser ingresados en radianes o grados. Los objetos son siempre rotados según su posición relativa al origen y los números positivos rotan en la dirección de las manecillas del reloj. Las transformaciones se aplican a todo lo que ocurre de forma posterior y las subsecuentes llamadas a la función acumulan el efecto. Por ejemplo, llamar a la función rotate(HALF_PI) y luego rotate(HALF_PI) equivale a una llamada a rotate(PI). Todas las transformaciones son anuladas cuando la función draw() comienza nuevamente. Técnicamente, rotate() multiplica la matriz de transformación actual por una matriz de rotación. Esta función puede ser controlada además con las funciones push() y pop().",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling rotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI). All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.",
            +        "Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "angle": "Ángulo: el ángulo de rotación, especificado en radianes o grados, dependiendo de angleMode()",
            +        "axis": "p5.Vector|Arreglo: eje sobre el que se rota"
            +      }
            +    },
            +    "rotateX": {
            +      "description": [
            +        "Rota en torno al eje X",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "Número: ángulo en radianes"
            +      }
            +    },
            +    "rotateY": {
            +      "description": [
            +        "Rota en torno al eje Y",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "Número: ángulo en radianes"
            +      }
            +    },
            +    "rotateZ": {
            +      "description": [
            +        "Rota en torno al eje Z,. Sólo disponible en el modo WEBGL.",
            +        "This method works in WEBGL mode only.",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "Número: ángulo en radianes"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Aumenta o decrementa el tamaño de una figura por medio de expandir o contraer sus vértices. Los objetos siempre escalan desde su origen relativo al sistema de coordenadas. Los valores de escalamiento son porcentajes decimales. Por ejemplo, la llamada a la función scale(2.0) aumenta la dimensión de una figura en un 200%. Las transformaciones se aplican a todo lo que ocurre después y llamadas subsecuentes a la función multiplican el efecto. Por ejemplo, llamar a scale(2.0) y luego a scale(1.5) equivale a llamar a scale(3.0). Si la función scale() es llamad dentro de draw(), la transformación es anulada cuando el bucle empieza nuevamente. El uso de esta función con el parámetro z está solo disponible en el modo WEBGL. Esta función puede también ser controlada con las funciones push() y pop().",
            +        "Transformations apply to everything that happens after and subsequent calls to the function multiply the effect. For example, calling scale(2.0) and then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.",
            +        "Using this function with the z parameter is only available in WEBGL mode. This function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "s": "Número | p5.Vector| Arreglo: porcentaje a escalar del objeto, o porcentaje a esacalar del objeto en el eje x si se dan múltiples argumentos",
            +        "y": "Número: porcentaje a escalar el objeto en el eje y",
            +        "z": "Número: porcentaje a escalar el objeto en el eje z (sólo en modo WEBGL)",
            +        "scales": "p5.Vector|Number[]: per-axis percents to scale the object"
            +      }
            +    },
            +    "shearX": {
            +      "description": [
            +        "Corta la figura en torno al eje x según el monto especificado por el parámetro ángulo. Los ángulos deben ser especificados según el modo actual de ángulo angleMode(). Los objetos son siempre cortados según su posición relativa al origen y los números positivos cortan los objetos en la dirección de las manecillas del reloj. Las transformaciones aplican a todo lo que ocurre después y llamadas posteriores a la misma función acumulan el efecto. Por ejemplo, llamar a shearX(PI/2) y luego a shearX(PI/2) equivale a llamar a shearX(PI). Si shearX() es llamado dentro de draw(), la transformación es anulada cuando el bucle empieza nuevamente. Técnicamente, shearX() multiplica la matriz de transformación actual por una matriz de rotación. La función puede ser controlada con las funciones push() y pop().",
            +        "Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling shearX(PI/2) and then shearX(PI/2) is the same as shearX(PI). If <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.",
            +        "Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions."
            +      ],
            +      "params": {
            +        "angle": "Número: ángulo de corte especificado en radianes o grados, dependiendo del modo de ángulo actual angleMode()"
            +      }
            +    },
            +    "shearY": {
            +      "description": [
            +        "Corta la figura en torno al eje y según el monto especificado por el parámetro ángulo. Los ángulos deben ser especificados según el modo actual de ángulo angleMode(). Los objetos son siempre cortados según su posición relativa al origen y los números positivos cortan los objetos en la dirección de las manecillas del reloj. Las transformaciones aplican a todo lo que ocurre después y llamadas posteriores a la misma función acumulan el efecto. Por ejemplo, llamar a shearY(PI/2) y luego a shearY(PI/2) equivale a llamar a shearY(PI). Si shearY() es llamado dentro de draw(), la transformación es anulada cuando el bucle empieza nuevamente. Técnicamente, shearY() multiplica la matriz de transformación actual por una matriz de rotación. La función puede ser controlada con las funciones push() y pop().",
            +        "Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling shearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If <a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.",
            +        "Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions."
            +      ],
            +      "params": {
            +        "angle": "Número: ángulo de corte especificado en radianes o grados, dependiendo del modo de ángulo actual angleMode()"
            +      }
            +    },
            +    "translate": {
            +      "description": [
            +        "Especifica una cantidad a desplazar los objetos dentro de la ventana mostrada. El parámetro x especifica la traslación de izquierda a derecha, el parámetro y especifica la traslación de arriba a abajo. Las transformaciones son acumulativas y aplican a todo lo que ocurre después y llamadas posteriores a la misma función acumulan el efecto. Por ejemplo, llamar a translate(50, 0) y luego a translate(20, 0) equivale a llamar a translate(70, 0). Si translate() es llamado dentro de draw(), la transformación es anulada cada vez que el bucle empieza nuevamente. Esta función peude ser controlada con las funciones push() y pop().",
            +        "Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling translate(50, 0) and then translate(20, 0) is the same as translate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again. This function can be further controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "x": "Número: traslación izquierda-derecha",
            +        "y": "Número: traslación arriba-abajo",
            +        "z": "Número: traslación adelante-atrás (solo en modo WEBGL)",
            +        "vector": "p5.Vector: the vector to translate by"
            +      }
            +    },
            +    "storeItem": {
            +      "description": [
            +        "Stores a value in local storage under the key name.  Local storage is saved in the browser and persists  between browsing sessions and page reloads.  The key can be the name of the variable but doesn't  have to be. To retrieve stored items  see <a href=\"#/p5/getItem\">getItem</a>. Sensitive data such as passwords or personal information  should not be stored in local storage."
            +      ],
            +      "params": {
            +        "key": "String",
            +        "value": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +      }
            +    },
            +    "getItem": {
            +      "description": [
            +        "Returns the value of an item that was stored in local storage  using storeItem()"
            +      ],
            +      "returns": "Number|Object|String|Boolean|p5.Color|p5.Vector: Value of stored item",
            +      "params": {
            +        "key": "String: name that you wish to use to store in local storage"
            +      }
            +    },
            +    "clearStorage": {
            +      "description": [
            +        "Clears all local storage items set with storeItem()  for the current domain."
            +      ]
            +    },
            +    "removeItem": {
            +      "description": [
            +        "Removes an item that was stored with storeItem()"
            +      ],
            +      "params": {
            +        "key": "String"
            +      }
            +    },
            +    "createStringDict": {
            +      "description": [
            +        "Creates a new instance of p5.StringDict using the key-value pair  or the object you provide."
            +      ],
            +      "returns": "p5.StringDict:",
            +      "params": {
            +        "key": "String",
            +        "value": "String",
            +        "object": "Object: object"
            +      }
            +    },
            +    "createNumberDict": {
            +      "description": [
            +        "Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair  or object you provide."
            +      ],
            +      "returns": "p5.NumberDict:",
            +      "params": {
            +        "key": "Number",
            +        "value": "Number",
            +        "object": "Object: object"
            +      }
            +    },
            +    "select": {
            +      "description": [
            +        "Searches the page for the first element that matches the given CSS selector string (can be an ID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>. The DOM node itself can be accessed with .elt. Returns null if none found. You can also specify a container to search within."
            +      ],
            +      "returns": "p5.Element|null: <a href=\"#/p5.Element\">p5.Element</a> containing node found",
            +      "params": {
            +        "selectors": "String: CSS selector string of element to search for",
            +        "container": "String|p5.Element|HTMLElement: (Optional) CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or  HTML element to search within"
            +      }
            +    },
            +    "selectAll": {
            +      "description": [
            +        "Searches the page for elements that match the given CSS selector string (can be an ID a class, tag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in an array. The DOM node itself can be accessed with .elt. Returns an empty array if none found. You can also specify a container to search within."
            +      ],
            +      "returns": "p5.Element[]: Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found",
            +      "params": {
            +        "selectors": "String: CSS selector string of elements to search for",
            +        "container": "String|p5.Element|HTMLElement: (Optional) CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>  , or HTML element to search within"
            +      }
            +    },
            +    "removeElements": {
            +      "description": [
            +        "Removes all elements created by p5, except any canvas / graphics elements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>. Event handlers are removed, and element is removed from the DOM."
            +      ]
            +    },
            +    "changed": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an element changes. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when the value of  an element changes.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "input": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is detected with an element. The input event is often used to detect keystrokes in a input element, or changes on a slider element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when any user input is  detected within the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "createDiv": {
            +      "description": [
            +        "Creates a <div></div> element in the DOM with given inner HTML."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createP": {
            +      "description": [
            +        "Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used for paragraph length text."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createSpan": {
            +      "description": [
            +        "Creates a <span></span> element in the DOM with given inner HTML."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createImg": {
            +      "description": [
            +        "Creates an <img> element in the DOM with given src and alternate text."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "src": "String: src path or url for image",
            +        "alt": "String: <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.",
            +        "crossOrigin": "String: <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used",
            +        "successCallback": "Function: (Optional) callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument"
            +      }
            +    },
            +    "createA": {
            +      "description": [
            +        "Creates an <a></a> element in the DOM for including a hyperlink."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "href": "String: url of page to link to",
            +        "html": "String: inner html of link element to display",
            +        "target": "String: (Optional) target where new link should open,  could be _blank, _self, _parent, _top."
            +      }
            +    },
            +    "createSlider": {
            +      "description": [
            +        "Creates a slider <input></input> element in the DOM. Use .size() to set the display length of the slider."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "min": "Number: minimum value of the slider",
            +        "max": "Number: maximum value of the slider",
            +        "value": "Number: (Optional) default value of the slider",
            +        "step": "Number: (Optional) step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)"
            +      }
            +    },
            +    "createButton": {
            +      "description": [
            +        "Creates a <button></button> element in the DOM. Use .size() to set the display size of the button. Use .mousePressed() to specify behavior on press."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "label": "String: label displayed on the button",
            +        "value": "String: (Optional) value of the button"
            +      }
            +    },
            +    "createCheckbox": {
            +      "description": [
            +        "Creates a checkbox <input></input> element in the DOM. Calling .checked() on a checkbox returns if it is checked or not"
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "label": "String: (Optional) label displayed after checkbox",
            +        "value": "Boolean: (Optional) value of the checkbox; checked is true, unchecked is false"
            +      }
            +    },
            +    "createSelect": {
            +      "description": [
            +        "Creates a dropdown menu <select></select> element in the DOM. It also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box. <ul> <li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li> <li><code>.value()</code> will return the currently selected option.</li> <li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li> <li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li> <li><code>.disable()</code> marks whole of dropdown element as disabled.</li> <li><code>.disable(value)</code> marks given option as disabled</li> </ul>"
            +      ],
            +      "returns": "p5.Element:",
            +      "params": {
            +        "multiple": "Boolean: (Optional) true if dropdown should support multiple selections",
            +        "existing": "Object: DOM select element"
            +      }
            +    },
            +    "createRadio": {
            +      "description": [
            +        "Creates a radio button element in the DOM.It also helps existing radio buttons assign methods of <a href=\"#/p5.Element/\">p5.Element</a>. <ul> <li><code>.option(value, [label])</code> can be used to create a new option for the element. If an option with a value already exists, it will be returned. Optionally, a label can be provided as second argument for the option.</li> <li><code>.remove(value)</code> can be used to remove an option for the element.</li> <li><code>.value()</code> method will return the currently selected value.</li> <li><code>.selected()</code> method will return the currently selected input element.</li> <li><code>.selected(value)</code> method will select the option and return it.</li> <li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li> </ul>"
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "containerElement": "Object: An container HTML Element either a div or span inside which all existing radio inputs will be considered as options.",
            +        "name": "String: (Optional) A name parameter for each Input Element."
            +      }
            +    },
            +    "createColorPicker": {
            +      "description": [
            +        "Creates a colorPicker element in the DOM for color input. The .value() method will return a hex string (#rrggbb) of the color. The .color() method will return a p5.Color object with the current chosen color."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "value": "String|p5.Color: (Optional) default color of element"
            +      }
            +    },
            +    "createInput": {
            +      "description": [
            +        "Creates an <input></input> element in the DOM for text input. Use .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "value": "String: default value of the input box",
            +        "type": "String: (Optional) type of text, ie text, password etc. Defaults to text.  Needs a value to be specified first."
            +      }
            +    },
            +    "createFileInput": {
            +      "description": [
            +        "Creates an <input></input> element in the DOM of type 'file'. This allows users to select local files for use in a sketch."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element",
            +      "params": {
            +        "callback": "Function: callback function for when a file is loaded",
            +        "multiple": "Boolean: (Optional) optional, to allow multiple files to be selected"
            +      }
            +    },
            +    "createVideo": {
            +      "description": [
            +        "Creates an HTML5 <video> element in the DOM for simple playback of audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a> and drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter can be either a single string path to a video file, or an array of string paths to different formats of the same video. This is useful for ensuring that your video can play across different browsers, as each supports different formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this page</a> for further information about supported formats."
            +      ],
            +      "returns": "p5.MediaElement: pointer to video <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "src": "String|String[]: path to a video file, or array of paths for  supporting different browsers",
            +        "callback": "Function: (Optional) callback function to be called upon  'canplaythrough' event fire, that is, when the  browser can play the media, and estimates that  enough data has been loaded to play the media  up to its end without having to stop for  further buffering of content"
            +      }
            +    },
            +    "createAudio": {
            +      "description": [
            +        "Creates a hidden HTML5 <audio> element in the DOM for simple audio playback. The first parameter can be either a single string path to a audio file, or an array of string paths to different formats of the same audio. This is useful for ensuring that your audio can play across different browsers, as each supports different formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this page for further information about supported formats</a>."
            +      ],
            +      "returns": "p5.MediaElement: pointer to audio <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "src": "String|String[]: (Optional) path to an audio file, or array of paths  for supporting different browsers",
            +        "callback": "Function: (Optional) callback function to be called upon  'canplaythrough' event fire, that is, when the  browser can play the media, and estimates that  enough data has been loaded to play the media  up to its end without having to stop for  further buffering of content"
            +      }
            +    },
            +    "VIDEO": {},
            +    "AUDIO": {},
            +    "createCapture": {
            +      "description": [
            +        "Creates a new HTML5 <video> element that contains the audio/video feed from a webcam. The element is separate from the canvas and is displayed by default. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>. The feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>. The loadedmetadata property can be used to detect when the element has fully loaded (see second example).",
            +        "More specific properties of the feed can be passing in a Constraints object. See the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'> W3C spec</a> for possible properties. Note that not all of these are supported by all browsers.",
            +        "<em>Security note</em>: A new browser security specification requires that getUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>, only works when you're running the code locally, or on HTTPS. Learn more <a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a> and <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>."
            +      ],
            +      "returns": "p5.Element: capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "type": "String|Constant|Object: type of capture, either VIDEO or  AUDIO if none specified, default both,  or a Constraints object",
            +        "callback": "Function: (Optional) function to be called once  stream has loaded"
            +      }
            +    },
            +    "createElement": {
            +      "description": [
            +        "Creates element with given tag in the DOM with given content."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "tag": "String: tag for the new element",
            +        "content": "String: (Optional) html content to be inserted into the element"
            +      }
            +    },
            +    "deviceOrientation": {
            +      "description": [
            +        "La variable de sistema deviceOrientation siempre contiene la orientación del dispositivo. El valor de esta variable será o landscape (paisaje) o portrait (retrato). Si la información no está disponible, su valor será undefined."
            +      ]
            +    },
            +    "accelerationX": {
            +      "description": [
            +        "La variable de sistema accelerationX siempré contiene la aceleración del dispositivo en el eje X. El valor es representado en unidades de metros por segundo al cuadrado."
            +      ]
            +    },
            +    "accelerationY": {
            +      "description": [
            +        "La variable de sistema accelerationX siempré contiene la aceleración del dispositivo en el eje Y. El valor es representado en unidades de metros por segundo al cuadrado."
            +      ]
            +    },
            +    "accelerationZ": {
            +      "description": [
            +        "La variable de sistema accelerationX siempré contiene la aceleración del dispositivo en el eje Z. El valor es representado en unidades de metros por segundo al cuadrado."
            +      ]
            +    },
            +    "pAccelerationX": {
            +      "description": [
            +        "La variable de sistema pAccelerationX siempré contiene la aceleración del dispositivo en el eje X, del cuadro anterior al cuadro actual. El valor es representado en unidades de metros por segundo al cuadrado."
            +      ]
            +    },
            +    "pAccelerationY": {
            +      "description": [
            +        "La variable de sistema pAccelerationY siempré contiene la aceleración del dispositivo en el eje Y, del cuadro anterior al cuadro actual. El valor es representado en unidades de metros por segundo al cuadrado."
            +      ]
            +    },
            +    "pAccelerationZ": {
            +      "description": [
            +        "La variable de sistema pAccelerationZ siempré contiene la aceleración del dispositivo en el eje Z, del cuadro anterior al cuadro actual. El valor es representado en unidades de metros por segundo al cuadrado."
            +      ]
            +    },
            +    "rotationX": {
            +      "description": [
            +        "La variable de sistema rotationX siempre contiene la rotación del dispositivo en el eje x. El valor está representado entre 0 y  +/-180 grados. Nota: el orden en que las rotaciones son llamadas es importante, por ejemplo, si se usan juntas, deben ser llamadas en el orden Z-X-Y, en caso contrario podría haber un comportamiento errado.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "rotationY": {
            +      "description": [
            +        "La variable de sistema rotationX siempre contiene la rotación del dispositivo en el eje x. El valor está representado entre 0 y  +/-180 grados. Nota: el orden en que las rotaciones son llamadas es importante, por ejemplo, si se usan juntas, deben ser llamadas en el orden Z-X-Y, en caso contrario podría haber un comportamiento errado.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "rotationZ": {
            +      "description": [
            +        "La variable de sistema rotationX siempre contiene la rotación del dispositivo en el eje y. El valor está representado entre 0 y  360 grados. A diferencia de rotationX y rotationY, esta variable está solo disponible en dispositivos equipados con una brújula interna. Nota: el orden en que las rotaciones son llamadas es importante, por ejemplo, si se usan juntas, deben ser llamadas en el orden Z-X-Y, en caso contrario podría haber un comportamiento errado.",
            +        "Unlike rotationX and rotationY, this variable is available for devices with a built-in compass only.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "pRotationX": {
            +      "description": [
            +        "La variable de sistema pRotationX siempre contiene la rotación del dispositivo en el eje x, en el cuadro anterior al actual. El valor está representado entre 0 y  +/-180 grados. pRotationX puede ser usado en conjunto con rotationX para determinar la dirección de rotación del dispositivo a lo largo del eje x.",
            +        "pRotationX can also be used with rotationX to determine the rotate direction of the device along the X-axis."
            +      ]
            +    },
            +    "pRotationY": {
            +      "description": [
            +        "La variable de sistema pRotationY siempre contiene la rotación del dispositivo en el eje x, en el cuadro anterior al actual. El valor está representado entre 0 y  +/-90 grados. pRotationY puede ser usado en conjunto con rotationY para determinar la dirección de rotación del dispositivo a lo largo del eje y.",
            +        "pRotationY can also be used with rotationY to determine the rotate direction of the device along the Y-axis."
            +      ]
            +    },
            +    "pRotationZ": {
            +      "description": [
            +        "La variable de sistema pRotationZ siempre contiene la rotación del dispositivo en el eje z, en el cuadro anterior al actual. El valor está representado entre 0 y 359 grados. pRotationZ puede ser usado en conjunto con rotationZ para determinar la dirección de rotación del dispositivo a lo largo del eje z.",
            +        "pRotationZ can also be used with rotationZ to determine the rotate direction of the device along the Z-axis."
            +      ]
            +    },
            +    "turnAxis": {
            +      "description": [
            +        "When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis variable. The turnAxis variable is only defined within the scope of deviceTurned()."
            +      ]
            +    },
            +    "setMoveThreshold": {
            +      "description": [
            +        "La función setMoveThreshold() es usada para definir el umbral para detectar movimiento de la función deviceMoved(). El valor umbral por defecto es 0.5"
            +      ],
            +      "params": {
            +        "value": "Número: el valor umbral"
            +      }
            +    },
            +    "setShakeThreshold": {
            +      "description": [
            +        "La función setShakeThreshold() es usada para definir el umbral para detectar agitamiento de la función deviceShaken(). El valor umbral por defecto es 30."
            +      ],
            +      "params": {
            +        "value": "Número: el valor umbral"
            +      }
            +    },
            +    "deviceMoved": {
            +      "description": [
            +        "La función deviceMoved() es llamada cuando el dispositivo es movido en una cantidad mayor al valor umbral en el eje X, Y o Z. El valor umbral por defecto es 0.5"
            +      ]
            +    },
            +    "deviceTurned": {
            +      "description": [
            +        "La función deviceTurned() es llamada cuando el dispositivo es girado en más de 90 grados de modo continuo. El eje que gatilla la función deviceTurned() es almacenado en la variable turnAxis. El método deviceTurned() puede ser restringido para gatillar en cualquier eje: X, Y o Z, comparando la variable turnAxis con X, Y o Z.",
            +        "The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis variable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis: X, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'."
            +      ]
            +    },
            +    "deviceShaken": {
            +      "description": [
            +        "La función deviceShaken() es llamada cuando la aceleración total de los cambios de accelerationX y accelerationY son mayores al valor umbral. El valor umbral por defecto es 30"
            +      ]
            +    },
            +    "keyIsPressed": {
            +      "description": [
            +        "La variable boolean de sistema keyIsPressed es verdadera (true) cuando cualquier tecla es presionada y falsa (false) si no hay ninguna tecla presionada"
            +      ]
            +    },
            +    "key": {
            +      "description": [
            +        "La variable de sistema key siempre contiene el valor más reciente de la tecla del teclado presionada. Para tener los mejores resultados, es mejor usarla dentro de la función keyTyped(). Para teclas sin valor ASCII, usa la variable keyCode"
            +      ]
            +    },
            +    "keyCode": {
            +      "description": [
            +        "La variable keyCode es usada para detectar teclas especiales, como BACKSPACE, DELETE, ENTER, RETURN, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. También puedes revisar las teclas especiales buscando el código keyCode de cualquier tecla en internet."
            +      ]
            +    },
            +    "keyPressed": {
            +      "description": [
            +        "La función keyPressed() es llamada una vez cada vez que una tecla es presionada. El código keyCode de la tecla presionada es almacenado en la variable keyCode. Para las teclas sin valor ASCII, usa la variable keyCode.  Puedes comprobar si la variable keyCode es igual a BACKSPACE, DELETE, ENTER, RETURN, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. Para las teclas con valor ASCII que son presionadas, el valor es almacenado en la variable key. Sin embargo, no distingue entre letras mayúsculas y minúsculas. Por esta razón, es recomendable usar la función keyTyped() para leer la variable key, que sí distingue entre mayúsculas y minúsculas. Por la forma en que los sistemas operativos manejan la repetición de teclas, mantener presionada una tecla puede causar múltiples llamadas a keyTyped() (y también keyReleased()). La tasa de repetición es definida por el sistema operativo y según cómo cada computador está configurado. Los navegadores tienen distintos comportamientos por defecto asociados a distintos eventos gatillados por teclas. Para prevenir cualquier comportamiento por defecto para este evento, añade return false al final de este método.",
            +        "For non-ASCII keys, use the keyCode variable. You can check if the keyCode equals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.",
            +        "For ASCII keys, the key that was pressed is stored in the key variable. However, it does not distinguish between uppercase and lowercase. For this reason, it is recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the case of the variable will be distinguished.",
            +        "Because of how operating systems handle key repeats, holding down a key may cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The rate of repeat is set by the operating system and how each computer is configured. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyReleased": {
            +      "description": [
            +        "La función keyReleased() es llamada una vez cada vez que una tecla es soltada. Ver key y keyCode para más información. Los navegadores tienen distintos comportamientos por defecto asociados a distintos eventos gatillados por teclas. Para prevenir cualquier comportamiento por defecto para este evento, añade return false al final de este método."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyTyped": {
            +      "description": [
            +        "la función keyTyped es llamada cava vez que una tecla es presionada, excepto cuando son presionadas la steclas de acción como Ctrl, Shift y Alt, que son ignoradas. La tecla presionada más reciente será almacenada en la variable key. Por la forma en que los sistemas operativos manejan la repetición de teclas, mantener presionada una tecla puede causar múltiples llamadas a keyTyped() (y también keyReleased()). La tasa de repetición es definida por el sistema operativo y según cómo cada computador está configurado. Los navegadores tienen distintos comportamientos por defecto asociados a distintos eventos gatillados por teclas. Para prevenir cualquier comportamiento por defecto para este evento, añade return false al final de este método.",
            +        "Because of how operating systems handle key repeats, holding down a key will cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The rate of repeat is set by the operating system and how each computer is configured. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyIsDown": {
            +      "description": [
            +        "La función keyIsDown() comprueba si la tecla está presionada. Puede ser usada si tienes un objeto que se mueve, y quieres que varias teclas sean capaces de afectar este comportamiento de manera simultánea, como cuando mueves una imagen de forma diagonal. Puedes ingresar cualquier número representando el código de tecla keyCode de la tecla, o usar cualquier de los nombres de la variable keyCode."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "code": "Número: la tecla a buscar"
            +      }
            +    },
            +    "movedX": {
            +      "description": [
            +        "The variable movedX contains the horizontal movement of the mouse since the last frame"
            +      ]
            +    },
            +    "movedY": {
            +      "description": [
            +        "The variable movedY contains the vertical movement of the mouse since the last frame"
            +      ]
            +    },
            +    "mouseX": {
            +      "description": [
            +        "La variable de sistema mouseX siempre contiene la posición horizontal actual del ratón, relativa al origen (0, 0) del lienzo."
            +      ]
            +    },
            +    "mouseY": {
            +      "description": [
            +        "La variable de sistema mouseY siempre contiene la posición vertical actual del ratón, relativa al origen (0, 0) del lienzo."
            +      ]
            +    },
            +    "pmouseX": {
            +      "description": [
            +        "La variable de sistema pmouseX siempre contiene la posición horizontal actual del ratón, en el cuadro anterior al actual, relativa al origen (0, 0) del lienzo."
            +      ]
            +    },
            +    "pmouseY": {
            +      "description": [
            +        "La variable de sistema pmouseY siempre contiene la posición vertical actual del ratón, en el cuadro anterior al actual, relativa al origen (0, 0) del lienzo."
            +      ]
            +    },
            +    "winMouseX": {
            +      "description": [
            +        "La variable de sistema winMouseX siempre contiene la posición horizontal actual del ratón, relativa al origen (0, 0) de la ventana del navegador."
            +      ]
            +    },
            +    "winMouseY": {
            +      "description": [
            +        "La variable de sistema winMouseY siempre contiene la posición vertical actual del ratón, relativa al origen (0, 0) de la ventana del navegador."
            +      ]
            +    },
            +    "pwinMouseX": {
            +      "description": [
            +        "La variable de sistema pwinMouseX siempre contiene la posición horizontal actual del ratón, en el cuadro anterior al actual, relativa al origen (0, 0) de la ventana del navegador."
            +      ]
            +    },
            +    "pwinMouseY": {
            +      "description": [
            +        "La variable de sistema pwinMouseY siempre contiene la posición vertical actual del ratón, en el cuadro anterior al actual, relativa al origen (0, 0) de la ventana del navegador."
            +      ]
            +    },
            +    "mouseButton": {
            +      "description": [
            +        "P5.js automáticamente rastrea si el botón del ratón está presionado y cuál botón está presionado. El valor de la variable de sistema mouseButton es o LEFT, RIGHT o CENTER dependiendo de cual fue el último botón presionado. Advertencia: diferentes navegadores pueden diferir."
            +      ]
            +    },
            +    "mouseIsPressed": {
            +      "description": [
            +        "La variable boolean de sistema mouseIsPressed es verdadera (true) si el ratón está siendo presionado, y falsa (false) en caso contrario."
            +      ]
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "La función mouseMoved() es llamada cada vez que el ratón se mueve y un botón del ratón no está siendo presionado. Los navegadores pueden tener comportamientos por defecto asociados a distintos eventos del ratón. Para prevenir cualquier comportamiento por defecto, añade return false como última línea de este método."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseDragged": {
            +      "description": [
            +        "La función mouseDragged() es llamada cada vez que el ratón se mueve y un botón del ratón está siendo presionado. Los navegadores pueden tener comportamientos por defecto asociados a distintos eventos del ratón. Para prevenir cualquier comportamiento por defecto, añade return false como última línea de este método."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "La función mousePressed() es llamada cada vez que un botón del ratón está siendo presionado. La variable mouseButton (ver la referencia) puede ser usada para determinar cual botón está siendo presionado. Si no se define una función mousePressed(), la función touchStarted() será llamada en su reemplazo, si es que está definida. Los navegadores pueden tener comportamientos por defecto asociados a distintos eventos del ratón. Para prevenir cualquier comportamiento por defecto, añade return false como última línea de este método."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "La función mouseReleased() es llamada cada vez que un botón del ratón es soltado. Si no se define una función mouseReleased(), la función touchEnded() será llamada en su reemplazo, si es que está definida. Los navegadores pueden tener comportamientos por defecto asociados a distintos eventos del ratón. Para prevenir cualquier comportamiento por defecto, añade return false como última línea de este método."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "La función mouseClicked() es llamada cada vez que un botón del ratón es presionado y luego soltado. Los navegadores pueden tener comportamientos por defecto asociados a distintos eventos del ratón. Para prevenir cualquier comportamiento por defecto, añade return false como última línea de este método."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event listener has detected a dblclick event which is a part of the DOM L3 specification. The doubleClicked event is fired when a pointing device button (usually a mouse's primary button) is clicked twice on a single element. For more info on the dblclick event refer to mozilla's documentation here: <a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a>"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "La función mouseWheel() es llamada cada vez que se detecta un evento de rueda de ratón vertical, ya sea gatillado por un ratón o por un touchpad. La propiedad event.delta retorna el monto que el ratón ha avanzado. Estos valores pueden ser positivos o negativos, dependiendo de la dirección de navegación (en OS X con natural scrolling, los signos son invertidos).  Los navegadores pueden tener comportamientos por defecto asociados a distintos eventos del ratón. Para prevenir cualquier comportamiento por defecto, añade return false como última línea de este método. Debido al soporte actual del evento wheel en Safari, la función podría solo funcionar si return false es incluido cuando se usa Safari."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional WheelEvent callback argument."
            +      }
            +    },
            +    "requestPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a> locks the pointer to its current position and makes it invisible. Use <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since the last call of draw. Note that not all browsers support this feature. This enables you to create experiences that aren't limited by the mouse moving out of the screen even if it is repeatedly moved into one direction. For example, a first person perspective experience."
            +      ]
            +    },
            +    "exitPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a> exits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a> for example to make ui elements usable etc"
            +      ]
            +    },
            +    "touches": {
            +      "description": [
            +        "The system variable touches[] contains an array of the positions of all current touch points, relative to (0, 0) of the canvas, and IDs identifying a unique touch as it moves. Each element in the array is an object with x, y, and id properties.",
            +        "The touches[] array is not supported on Safari and IE on touch-based desktops (laptops)."
            +      ]
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "La función touchStarted() es llamada una vez, cada vez que un toque nuevo es registrado. Si la función touchStarted() no ha sido definida, la función mouseIsPressed() será llamada en su lugar, si es que está definida. Los navegadores tienen distintos comportamientos por defecto asociados a distintos eventos gatillados por toque. Para prevenir cualquier comportamiento por defecto para este evento, añade return false al final de este método."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "La función touchStarted() es llamada una vez, cada vez que es registrado el movimiento de un toque. Si la función touchMoved() no ha sido definida, la función mouseDragged() será llamada en su lugar, si es que está definida. Los navegadores tienen distintos comportamientos por defecto asociados a distintos eventos gatillados por toque. Para prevenir cualquier comportamiento por defecto para este evento, añade return false al final de este método."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "La función touchEnded() es llamada una vez, cada vez que un toque finaliza. Si la función touchEnded() no ha sido definida, la función mouseReleased() será llamada en su lugar, si es que está definida. Los navegadores tienen distintos comportamientos por defecto asociados a distintos eventos gatillados por toque. Para prevenir cualquier comportamiento por defecto para este evento, añade return false al final de este método."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "createImage": {
            +      "description": [
            +        "Crea una nueva p5.Image (el tipo de datos para almacenar imágenes). Esto provee un nuevo buffer de pixeles para jugar. Define el tamaño del buffer con los parámetros de ancho y altuar. .pixels da acceso a un arreglo conteniendo los valores de todos los pixeles en la ventana mostrada. Estos valores son números. Este arreglo es del tamaño (incluyendo un factor apropiado de pixelDensity) de la ventana mostrada x4, representando los valroes R, G, B, A en orden para cada pixel., moviendo de izquierda a derecha en cada fila, y luego bajando de columna. Ver .pixels para mayor información. Podría ser más simple usar set() y get(). Antes de acceder a los pixeles de una imagen, los datos deben ser cargados con la función loadPixels(). Después de que el arreglo de datos ha sido modificado, la función updatePixels() debe ejecutarse para actualizar los cambios.",
            +        ".<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels in the display window. These values are numbers. This array is the size (including an appropriate factor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for more info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.",
            +        "Before accessing the pixels of an image, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "width": "Entero: ancho en pixeles",
            +        "height": "Entero: altura en pixeles"
            +      }
            +    },
            +    "saveCanvas": {
            +      "description": [
            +        "Graba el lienzo actual como una imagen. En Safari, esto abrirá la imagen en la ventana y el usuario deberá proveer su propio nombre de archivo. Otros navegadores o grabarán el archivo de inmediato, o abrirán una ventana de diálogo."
            +      ],
            +      "params": {
            +        "selectedCanvas": "Canvas seleccionado: una variable representando un canvas HTML5 específico (opcional)",
            +        "filename": "String",
            +        "extension": "String: jpg o png"
            +      }
            +    },
            +    "saveFrames": {
            +      "description": [
            +        "Captura una secuencia de cuadros que pueden ser usados para crear una película. Acepta una función callback. Por ejemplo, puedes querer mandar los cuadros a un servidor donde pueden ser almacenados o convertidos en una película. Si no se provee una función callback, el navegador abrirá varios diálogos tratando de descargar todas las imágenes que han sido creadas. Con una función callback provista, los datos de imagen no son grabados por defecto, sino que son pasados como argumento a la función callback como un arreglo de objetos, con el tamaño del arreglo siendo igual al número total de cuadros.",
            +        "Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation. To export longer animations, you might look into a library like <a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>."
            +      ],
            +      "params": {
            +        "filename": "String:",
            +        "extension": "String: jpg o png",
            +        "duration": "Número: duración en segundos para grabar los cuadros",
            +        "framerate": "Número: tasa de cuadros por segundo a grabar",
            +        "callback": "Función: una función callback que será ejecutada para manejar los datos de imagen. Esta función deberá aceptar un arreglo como argumento. El arreglo contendrá el número especificado de cuadros como objetos. Cada objeto tiene tres propiedades: datos de imagen imageData, nombre del archivo y extensión"
            +      }
            +    },
            +    "loadImage": {
            +      "description": [
            +        "Carga una imagen desde una ruta de archivo y crea un objeto p5.Image. La imagen puede no estar inmediatamente disponible para render. Si quieres asegurarte que esté lista antes de hacer algo con ella, ubica la función loadImage() dentro de preload(). También puedes proveer una función callback para manejar la imagen cuando esté lista. La ruta a la imagen debe ser relativa al archivo HTML de tu bosquejo. Cargar desde una URL u otra ubicación remota podría estar bloqueado por las opciones de seguridad del navegador.",
            +        "The image may not be immediately available for rendering. If you want to ensure that the image is ready before doing anything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>. You may also supply a callback function to handle the image when it's ready.",
            +        "The path to the image should be relative to the HTML file that links in your sketch. Loading an image from a URL or other remote location may be blocked due to your browser's built-in security.",
            +        "You can also pass in a string of a base64 encoded image as an alternative to the file path. Remember to add \"data:image/png;base64,\" in front of the string."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "path": "String: ruta de la imagen a cargar",
            +        "successCallback": "Función(p5.Image): función a ser llamada una vez que la imagen sea cargada. Le será pasado el objeto p5.Image",
            +        "failureCallback": "Función(evento): llamada con el evento error si es que la carga de la imagen falla."
            +      }
            +    },
            +    "image": {
            +      "description": [
            +        "Dibuja una imagen en el lienzo principal del bosquejo p5.js.",
            +        "This function can be used with different numbers of parameters. The simplest use requires only three parameters: img, x, and y—where (x, y) is the position of the image. Two more parameters can optionally be added to specify the width and height of the image.",
            +        "This function can also be used with all eight Number parameters. To differentiate between all these parameters, p5.js uses the language of \"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source image\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the \"source image\" dimensions can be useful when you want to display a subsection of the source image instead of the whole thing. Here's a diagram to explain further: <img src=\"assets/drawImage.png\"></img>"
            +      ],
            +      "params": {
            +        "img": "p5.Image: la imagen a mostrar",
            +        "x": "Número: la coordenada x donde se ubicará la esquina superior de la imagen",
            +        "y": "Número: la coordenada y donde se ubicará la esquina superior de la imagen",
            +        "width": "Número: ancho de la imagen a dibujar",
            +        "height": "Número: altura de la imagen a dibujar",
            +        "dx": "Número: la coordenada x en el lienzo de destino donde se ubicará la esquina superior izquierda de la imagen",
            +        "dy": "Número: la coordenada y en el lienzo de destino donde se ubicará la esquina superior izquierda de la imagen",
            +        "dWidth": "Número: ancho de la imagen a dibujar en el lienzo de destino",
            +        "dHeight": "Número: altura de la imagen a dibujar en el lienzo de destino",
            +        "sx": "Número: la coordenada x de la esquina superior izquierda del subrectángulo de la imagen original a dibujar en el lienzo de destino",
            +        "sy": "Número: la coordenada y de la esquina superior izquierda del subrectángulo de la imagen original a dibujar en el lienzo de destino",
            +        "sWidth": "Número: el ancho del subrectángulo de la imagen original a dibujar en el lienzo de destino",
            +        "sHeight": "Número: la altura del subrectángulo de la imagen original a dibujar en el lienzo de destino"
            +      }
            +    },
            +    "tint": {
            +      "description": [
            +        "Define el valor de relleno para mostrar imágenes. Las imágenes pueden ser teñidas en colores específicos o hacerse transparentes al incluir un valor alpha. Para aplicar transparencia a una imagen sin afectar su color, usa blanco como color de teñido y especifica un valor alpha. Por ejemplo, tint(255, 128) hará una imagen 50% transparente (asumiendo el rango alpha por defecto entre 0 y 255, el que puede ser modificado con la función colorMode()). El valor del parámetro gris debe ser menor o igual al actual valor máximo según lo especificado por colorMode(). El valor máximo por defecto es 255.",
            +        "To apply transparency to an image without affecting its color, use white as the tint color and specify an alpha value. For instance, tint(255, 128) will make an image 50% transparent (assuming the default alpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).",
            +        "The value for the gray parameter must be less than or equal to the current maximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is 255."
            +      ],
            +      "params": {
            +        "v1": "Número|Arreglo: valor de gris, rojo o tinte (dependiendo del modo de color actual), o un arreglo de colores",
            +        "v2": "Número|Arreglo: valor de verde o saturación (dependiendo del modo de color actual)",
            +        "v3": "Número|Arreglo: valor de azul o brillo (dependiendo del modo de color actual)",
            +        "alpha": "Número|Arreglo: opacidad del fondo",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the tint color"
            +      }
            +    },
            +    "noTint": {
            +      "description": [
            +        "Remueve el valor actual de relleno para mostrar imágenes y revierte a mostrar las imágenes con sus colores originales."
            +      ]
            +    },
            +    "imageMode": {
            +      "description": [
            +        "Define el modo de imagen. Modifica la ubicación desde la que las imágenes son dibujadas, por medio de cambiar la manera en que los parámetros dados a image() son interpretados. El modo por defecto es imageMode(CORNER), que interpreta los paráemtros segundo y tercero de image() como la posición de la esquina superior izquierda de la imagen. Si se dan dos parámetros adicionales, son usados para definir el ancho y la altura la imagen. imageMode(CORNERS) interpreta los paráemtros segundo y tercero de image() como la ubicación de una esquina, y los parámetros cuarto y quinto como la ubicación de la esquina opuesta. imageMode(CENTER) interpreta los parámetros segundo y tercero de image() como el punto central de la imagen. Si dos parámetros adicionales son especificados, son usados para definir el ancho y la altura de la imagen.",
            +        "imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the location of one corner, and the fourth and fifth parameters as the opposite corner.",
            +        "imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the image's center point. If two additional parameters are specified, they are used to set the image's width and height."
            +      ],
            +      "params": {
            +        "mode": "Constante: puede ser CORNER, CORNERS, o CENTER"
            +      }
            +    },
            +    "pixels": {
            +      "description": [
            +        "<a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a> containing the values for all the pixels in the display window. These values are numbers. This array is the size (include an appropriate factor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. Retina and other high density displays will have more pixels[] (by a factor of pixelDensity^2). For example, if the image is 100x100 pixels, there will be 40,000. On a retina display, there will be 160,000.",
            +        "The first four values (indices 0-3) in the array will be the R, G, B, A values of the pixel at (0, 0). The second four values (indices 4-7) will contain the R, G, B, A values of the pixel at (1, 0). More generally, to set values for a pixel at (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre>",
            +        "While the above method is complex, it is flexible enough to work with any pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of setting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at any pixelDensity, but the performance may not be as fast when lots of modifications are made to the pixel array.",
            +        "Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a> function must be run to update the changes.",
            +        "Note that this is not a standard javascript array. This means that standard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or <a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not work."
            +      ]
            +    },
            +    "blend": {
            +      "description": [
            +        "Copia una región de pixeles de una imagen a otra, usando un modo específico de mezcla para hacer la operación. Los modos disponibles de mezcla son: BLEND | DARKEST | LIGHTEST | DIFFERENCE | MULTIPLY| EXCLUSION | SCREEN | REPLACE | OVERLAY | HARD_LIGHT | SOFT_LIGHT | DODGE | BURN | ADD | NORMAL"
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: imagen fuente",
            +        "sx": "Entero: coordenada x de la esquina superior izquierda de la fuente",
            +        "sy": "Entero: coordenada y de la esquina superior izquierda de la fuente",
            +        "sw": "Entero: ancho de la imagen fuente",
            +        "sh": "Entero: altura de la imagen fuente",
            +        "dx": "Entero: coordenada x de la esquina superior izquierda del destino",
            +        "dy": "Entero: coordenada y de la esquina superior izquierda del destino",
            +        "dw": "Entero: ancho de la imagen destino",
            +        "dh": "Entero: altura de la imagen destino",
            +        "blendMode": "Constante: el modo de mezcla"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Copia una región del lienzo a otra región del lienzo desde una imagen usada como el parámetro srcImage en el lienzo. Si la fuente y el destino no son del mismo tamaño, automáticamente redimensionará los pixeles de la fuente para calzar con la región especificada como destino."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: imagen fuente",
            +        "sx": "Entero: coordenada x de la esquina superior izquierda de la fuente",
            +        "sy": "Entero: coordenada y de la esquina superior izquierda de la fuente",
            +        "sw": "Entero: ancho de la imagen fuente",
            +        "sh": "Entero: altura de la imagen fuente",
            +        "dx": "Entero: coordenada x de la esquina superior izquierda de destino",
            +        "dy": "Entero: coordenada y de la esquina superior izquierda de destino",
            +        "dw": "Entero: ancho de la imagen de destino",
            +        "dh": "Entero: altura de la imagen de destino"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Aplica un filtro al lienzo. Las opciones posibles son: THRESHOLD, que convierte la imagen a pixeles blancos y negros dependiendo de si están arriba o abajo del umbral definido por el parámetro. El parámetro debe estar entre 0.0 (negro) y 1.0 (blanco). Si no se especifica ningún valor, el valor por defecto es 0.5. GRAY, convierte cualquier color en la imagen a un equivalente en la escala de grises, no tiene parámetros. OPAQUE, hace que el canal alpha sea totalmente opaco, no tiene parámetros. INVERT, hace que cada pixel tenga su valor inverso, no tiene parámetros. POSTERIZE, limita cada canal de la imagen a un número de colores especificado como parámetro. El parámetro puede definir entre 2 y 255 valores, pero los resultados más notorios se dan con valores bajos. BLUR, hace que la imagen sea borrosa con un proceso Gaussiano, siendo el parámetro el nivel de cuán borroso es el resultado, si no se usa ningún parámetro, el parámetro por defecto es 1, a mayores valores es más borroso el resultado. ERODE, reduce las áreas claras, no tiene parámetros. DILATE, aumenta las áreas claras, no tiene parámetros.",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used.",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used.",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used.",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges.",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur.",
            +        "ERODE Reduces the light areas. No parameter is used.",
            +        "DILATE Increases the light areas. No parameter is used.",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "Constante:",
            +        "filterParam": "Número: un parámetro opcional único a cada filtro, ver más arriba"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retorna un arreglo de valores RGBA por cada pixel o toma una sección de una imagen. Si no especifican parámetros, se retorna la imagen entera. Usa los parámetros x e y para obtener el valor de un pixel. Toma una sección de la ventana mostrada si especificas los parámetros adicionales w y h. Cuando se obtiene una imagen, los parámetros x e y definen las coordenadas de la esquina superior izquierda de la imagen, sin importar el actual mode imagen definido por imageMode(). Si el pixel solicitado está fuera de la imagen, se retorna el valor [0, 0, 0, 255]. Para obtener los números escalados según los rangoes de color actuales y tomar en cuenta el modo de color según colorMode(), usa getColor() en vez de get(). Tomar el valor de un pixel con get(x, y) es fácil, pero no tan rápido como tomar los datos directamente desde pixels[]. La instrucción equivalente a get(x, y) usando pixels[] con densidad de pixeles d es  var off = (y width + x) d * 4; [pixels[off], pixels[off+1], pixels[off+2], pixels[off+3]]. Ver la referencia de pixels[] para mayor información.",
            +        "Returns an array of [R,G,B,A] values for any pixel or grabs a section of an image. If no parameters are specified, the entire image is returned. Use the x and y parameters to get the value of one pixel. Get a section of the display window by specifying additional w and h parameters. When getting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.",
            +        "Getting the color of a single pixel with get(x, y) is easy, but not as fast as grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to get(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is <pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates let off = (y * width + x) * d * 4; let components = [  pixels[off],  pixels[off + 1],  pixels[off + 2],  pixels[off + 3] ]; print(components);</code></pre>",
            +        "See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.",
            +        "If you want to extract an array of colors or a subimage from an p5.Image object, take a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a>"
            +      ],
            +      "returns": "Arreglo|p5.Image: valores de pixel en la posición (x, y) en formato arreglo RGBAs o p5.Image",
            +      "params": {
            +        "x": "Número: coordenada x del pixel",
            +        "y": "Número: coordenada y del pixel",
            +        "w": "Número: ancho",
            +        "h": "Número: altura"
            +      }
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "Carga los datos de los pixeles en pantalla al arreglo pixels[]. Esta función siempre debe ser llamada antes de leer o escribir en el arreglo pixels[]"
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Cambia el color de cualquier pixel, o pone una imagen directamente en la ventana. Los parámetros x e y especifican el pixel a cambiar y c especifica el valor del color. Puede ser un objeto p5.Color o un arreglo de pixeles RGBA. También puede ser un valor único en escala de grises. Cuando se define una imagen, los parámetros x e y definen las coordenadas de la esquina superior izquierda de la imagen, sin importar el modo actual de imagen según imageMode(). Después de usar set(), debes llamar a updatePixels()' para que tus cambios aparezcan. Esta función debería ser llamada una vez que todos los pixeles han sido definidos. Definir el color de un solo pixel con set(x, y) es fácil, pero es tan rápido como poner los datos directamente en el arreglo pixels[]. Definir los valores de pixels[] directamente puede ser complicado cuando se trabaja con un monitor retina, pero tendrá un mejor desempeño cuando muchos pixeles necesiten ser definidos directamente en cada iteración. Ver la referencia de pixels[] para mayor información.",
            +        "After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear. This should be called once all pixels have been set, and must be called before calling .<a href=\"#/p5/get\">get()</a> or drawing the image.",
            +        "Setting the color of a single pixel with set(x, y) is easy, but not as fast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a> values directly may be complicated when working with a retina display, but will perform better when lots of pixels need to be set directly on every loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information."
            +      ],
            +      "params": {
            +        "x": "Número: coordenada x del pixel",
            +        "y": "Número: coordenada y del pixel",
            +        "c": "Número|Arreglo|Objeto: inserta un valor en escala de grises | un arreglo de pixeles | un objeto p5.Color | un objeto p5.Image a copiar"
            +      }
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "Actualiza la ventana mostrada con los datos del arreglo pixels[]. Se usa en conjunto con loadPixels(). Si solo estás leyendo pixeles desde el arreglo, no hay necesidad de llamar a updatePixels() - actualizar es solo necesario para aplicar cambios. updatePixels() debe ser llamada cada vez que el arreglo de pixeles es manipulado o si se llama a la función set()."
            +      ],
            +      "params": {
            +        "x": "Número: coordenada x de la esquina superior izquierda de la región a actualizar",
            +        "y": "Número: coordenada y de la esquina superior izquierda de la región a actualizar",
            +        "w": "Número: ancho de la región a actualizar",
            +        "h": "Número: altura de la región a actualizar"
            +      }
            +    },
            +    "loadJSON": {
            +      "description": [
            +        "Carga un archivo JSON desde un archivo o una URL, y retorna un objeto o un arreglo. Este método es asíncrono, lo que significa que puede que no termine antes que se ejecute la siguiente línea en tu bosquejo.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. JSONP is supported via a polyfill and you can pass in as the second argument an object with definitions of the json callback following the syntax specified <a href=\"https://github.com/camsong/ fetch-jsonp\">here</a>.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Objeto|Arreglo: datos JSON",
            +      "params": {
            +        "path": "String: nombre de archivo o URL a cargar",
            +        "jsonpOptions": "Object: (Optional) options object for jsonp related settings",
            +        "datatype": "Función: función a ser ejecutada después de que loadJSON() finalice, los datos son pasados como primer argumento",
            +        "callback": "Función: función a ser ejecutada si es que hay un error, la respuesta es pasada como primer argumento",
            +        "errorCallback": "String: json o jsonp"
            +      }
            +    },
            +    "loadStrings": {
            +      "description": [
            +        "Lee los contenidos de un archivo y crea un arreglo de Strings de sus líneas individuales. Si el nombre del archivo es usado como parámetro, como en el ejemplo anterior, el archivo debe estar ubicado en el directorio del bosquejo. Alternativamente, el archivo puede ser cargado desde cualquier lugar del computador local usando una dirección absoluta (empieza con / en Unix y Linux, o una letra representando el disco en Windows), o el parámetro de nombre de archivo puede ser una URL donde esté el archivo dentro de una red. Este método es asíncrono, lo que significa que puede ser que su ejecución no termine antes de que se ejecute la siguiente línea del bosquejo.",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Arreglo: un arreglo de Strings",
            +      "params": {
            +        "filename": "String: nombre de archivo o URL a cargar",
            +        "callback": "Función: función a ser ejecutada después de que loadStrings() finalice, el arreglo es pasado como primer argumento",
            +        "errorCallback": "Función: función a ser ejecutada si es que hay un error, la respuesta es pasada como primer argumento"
            +      }
            +    },
            +    "loadTable": {
            +      "description": [
            +        "Lee los contenidos de un archivo o URL y crea un objeto p5.Table con sus valores. Si un archivo es especificado, debe ser ubicado en el directorio data del bosquejo. El parámetro de nombre de archivo puede también ser una URL de un archivo en línea. Por defecto, se asume que el archivo está separado por comas (formato CSV), La tabla sólo busca una fila de encabezado si es que se incluye la opción header. Las opciones posibles incluyen: csv: se procesan los datos como valores separados por comas, tsv: se procesan los datos como separados por tabulación, header: la tabla tiene una fila de encabezados (títulos). Si se incluyenn múltiples opciones, se deben ingresar como parámetros separados por comas. Todos los archivos son cargados y grabados usando codificación UTF-8. Este método es asíncrono, lo que significa que su ejecución puede no haber terminado antes de que se ejecute la siguiente línea del bosquejo. Si se llama a loadTable() dentro de preload() se garantiza que se complete la operación antes de que setup() y draw() sean llamadas. Fuera de preload(), puedes suplir una función callback para manejar el objeto.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called. Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object:",
            +        "All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Objeto Table conteniendo los datos",
            +      "params": {
            +        "filename": "String: nombre de archivo o URL a cargar",
            +        "extension": "String: (Optional) parse the table by comma-separated values \"csv\", semicolon-separated  values \"ssv\", or tab-separated values \"tsv\"",
            +        "header": "String: (Optional) \"header\" to indicate table has header row",
            +        "callback": "String|Strings: header, csv, tsv",
            +        "errorCallback": "Función: función a ser ejecutada después de que loadTable() finalice, el arreglo es pasado como primer argumento. Si es exitosa, el objeto Table es pasado como primer argumento, en caso contrario se pasa el valor boolean false."
            +      }
            +    },
            +    "loadXML": {
            +      "description": [
            +        "Lee los contenidos de un archivo y crea un objeto XML con sus valores. Si el nombre del archivo es usado como parámetro, el archivo debe estar ubicado en el directorio del bosquejo. Alternativamente, el archivo puede ser cargado desde cualquier lugar del computador local usando una dirección absoluta (que empieza con / en Unix y Linux, o con una letra que simbolice el disco duro en Windows). También se puede usar como parámetro de nombre de archivo una URL para un archivo en una red. Este método es asíncrono, lo que significa que su ejecución puede no estar completa antes de que se ejecute la siguiente línea de código en el bosquejo. Llamar a loadXML() dentro de preload() garantiza que la operación se complete antes de que setup() y draw() sean llamados. Fuera de preload(), puedes suplir una función callBack para manejar el objeto.",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.",
            +        "Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "objeto XML que contiene los datos",
            +      "params": {
            +        "filename": "String: nombre de archivo o URL a cargar",
            +        "callback": "Función: función a ser ejecutada después de que loadXML() finalice, el objeto XML es pasado como primer argumento",
            +        "errorCallback": "Función: la función a ser ejecutada si es que hay un error, la respuesta es pasada como primer argumento"
            +      }
            +    },
            +    "loadBytes": {
            +      "description": [
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: an object whose 'bytes' property will be the loaded buffer",
            +      "params": {
            +        "file": "String: name of the file or URL to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>  completes",
            +        "errorCallback": "Function: (Optional) function to be executed if there  is an error"
            +      }
            +    },
            +    "httpGet": {
            +      "description": [
            +        "Método para ejecutar una solicitud HTTP GET. Si no se especifica el tipo de datos, p5 tratará de adivinar basándose en la URL, usando texto por defecto."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "path": "String: nombre del archivo o URL a cargar",
            +        "datatype": "Objeto: parámetro de datos pasados con la solicitud enviada",
            +        "data": "String: json, jsonp, xml o text",
            +        "callback": "Función: función a ser ejecutada después de que httpGet() finalice, los datos son pasados como primer argumento",
            +        "errorCallback": "Función: función a ser ejecutada si es que hay un error, la respuesta es pasada como primer argumento"
            +      }
            +    },
            +    "httpPost": {
            +      "description": [
            +        "Método para ejecutar una solicitud HTTP POST. Si no se especifica el tipo de datos, p5 tratará de adivinar basándose en la URL, usando texto por defecto."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "path": "String: nombre del archivo o URL a cargar",
            +        "datatype": "Objeto: parámetro de datos pasados con la solicitud enviada",
            +        "data": "String: json, jsonp, xml o text",
            +        "callback": "Función: función a ser ejecutada después de que httpPost() finalice, los datos son pasados como primer argumento",
            +        "errorCallback": "Función: función a ser ejecutada si es que hay un error, la respuesta es pasada como primer argumento"
            +      }
            +    },
            +    "httpDo": {
            +      "description": [
            +        "Método para ejecutar una solicitud HTTP. Si no se especifica el tipo de datos, p5 tratará de adivinar basándose en la URL, usando texto por defecto. También puedes pasar un objeto especificando todos los parámetros de la solicitud siguiendo los ejemplos dentro de las llamadas de reqwest()"
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "path": "String: nombre del archivo o URL a cargar",
            +        "method": "Objeto: parámetro de datos pasados con la solicitud enviada",
            +        "datatype": "String: json, jsonp, xml o text",
            +        "data": "Función: función a ser ejecutada después de que httpDo() finalice, los datos son pasados como primer argumento",
            +        "callback": "Función: función a ser ejecutada si es que hay un error, la respuesta es pasada como primer argumento",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument",
            +        "options": "Object: Request object options as documented in the  \"fetch\" API <a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a>"
            +      }
            +    },
            +    "createWriter": {
            +      "returns": "p5.PrintWriter:",
            +      "params": {
            +        "name": "String: name of the file to be created",
            +        "extension": "String (Optional)"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "Graba una imagen, text, json, csv, wav o html. Hace que la descarga ocurra en el computador cliente. Notar que no es recomendado llamar a save() dentro de draw() si está en bucle, porque la función save() abrirá una ventana de diálogo en cada cuadro. El comportamiento por defecto es grabar el lienzo como una imagen. Puedes opcionalmente especificar un nombre de archivo. Por ejemplo: TODO. Alternativamente, el primer parámetro puede ser un puntero a un lienzo p5.Element, un arreglo de Strings, un arreglo de JSON, un objeto JSON, un p5.Table, un p5.Image, o un p5.SoundFile (requiere p5.sound). El segundo parámetro es el nombre del archivo (incluyendo la extensión). El tercer parámetro es para opciones específicas a este tipo de objeto. Este método grabará un archivo que se austa a los parámetros dados. Por ejemplo: TODO."
            +      ],
            +      "params": {
            +        "objectOrFilename": "Objeto|String: si se provee un nombre de archivo, se grabará el lienzo como una imagen con la extensión png o jpg, dependiendo del nombre del archivo. Si se provee un objeto, se grabará dependiendo del objeto y el nombre del archivo (ver los ejemplos anteriores)",
            +        "filename": "String: Si se provee un objeto como el primer parámetro, entonces el segundo parámetro indica el nombre del archivo, y debe incluir la extensión apropiada (ver los ejemplos anteriores).",
            +        "options": "Boolean|String: opciones adicionales depndiendo del tipo de archivo. Por ejemplo, cuando se graba un archivo JSON, true indica que la salida será optimizada según el tamaño del archivo, en vez de por legibilidad."
            +      }
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "Escribe los contenidos de un arreglo o un objeto JSON a un archivo .json. El proceso de grabación del archivo y su ubicación pueden variar entre navegadores web."
            +      ],
            +      "params": {
            +        "json": "Arreglo|Objeto:",
            +        "filename": "String",
            +        "optimize": "Boolean: si es verdadero (true), remueve los saltos de línea del archivo de salida para optimizar el tamaño del archivo, en desmedro de la legibilidad."
            +      }
            +    },
            +    "saveStrings": {
            +      "description": [
            +        "Escribe un arreglo de Strings a un archivo de texto, una línea por String. El proceso de grabación del archivo y su ubicación pueden variar entre navegadores web."
            +      ],
            +      "params": {
            +        "list": "Arreglo: arreglo de Strings a ser escrito",
            +        "filename": "String: nombre del archivo de salida",
            +        "extension": "String: (Optional) the filename's extension",
            +        "isCRLF": "Boolean: (Optional) if true, change line-break to CRLF"
            +      }
            +    },
            +    "saveTable": {
            +      "description": [
            +        "Escribe los contenidos de un objeto Table a un archivo. Por defecto es un archivo de texto con valores separados por coma (csv), pero también puede usar separación por tabulación (tsv), o generar una tabla HTML (html). El proceso de grabación del archivo y su ubicación pueden variar entre navegadores web."
            +      ],
            +      "params": {
            +        "Table": "p5.Table: the <a href=\"#/p5.Table\">Table</a> object to save to a file",
            +        "filename": "String: el nombre del archivo en el que Table será grabado",
            +        "options": "String: puede ser tsv, csv o html."
            +      }
            +    },
            +    "abs": {
            +      "description": [
            +        "Calcula el valor absoluto (magnitud) de un número. Usa Math.abs(). El valor absoluto de un número es siempre positivo."
            +      ],
            +      "returns": "Número: valor absoluto del número dado",
            +      "params": {
            +        "n": "Número: número a computar"
            +      }
            +    },
            +    "ceil": {
            +      "description": [
            +        "Calcula el entero más cercano que es mayor o igual que el valor del parámetro. Usa Math.ceil(). Por ejemplo, ceil(9.03) retorna el valor 10."
            +      ],
            +      "returns": "Número: número redondeado hacia arriba",
            +      "params": {
            +        "n": "Número: número a redondear"
            +      }
            +    },
            +    "constrain": {
            +      "description": [
            +        "Restringe un valor a estar entre un valor mínimo y uno máximo."
            +      ],
            +      "returns": "Número: número restringido",
            +      "params": {
            +        "n": "Número: número a restringir",
            +        "low": "Número: límite mínimo",
            +        "high": "Número: límite máximo"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "Calcula la distancia entre dos puntos"
            +      ],
            +      "returns": "Número: distancia entre los dos puntos",
            +      "params": {
            +        "x1": "Número: la coordenada x del primer punto",
            +        "y1": "Número: la coordenada y del primer punto",
            +        "x2": "Número: la coordenada x del segundo punto",
            +        "y2": "Número: la coordenada y del segundo punto",
            +        "z1": "Número: la coordenada z del primer punto",
            +        "z2": "Número: la coordenada z del segundo punto"
            +      }
            +    },
            +    "exp": {
            +      "description": [
            +        "Retorna el número de Euler (2.71828...) elevado al parámetro n. Usa Math.exp()."
            +      ],
            +      "returns": "e^n",
            +      "params": {
            +        "n": "Número: exponente a elevar"
            +      }
            +    },
            +    "floor": {
            +      "description": [
            +        "Calcula el valor entero más cercano que es menor o igual al parámetro. Usa Math.floor()."
            +      ],
            +      "returns": "Número: número redondeado hacia abajo",
            +      "params": {
            +        "n": "Número: número a ser redondeado hacia abajo"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "Calcula un número entre dos números a un incremento específico. El parámetro amt es la cantidad a interpolar entre los dos valores donde 0.0 es igual al primer punto, 0.1 está muy cerca del primer punto, 0.5 está a medio camino entre ambos números, etc. La función lerp es conveniente para crear movimiento a lo largo de un camino recto y para dibujar líneas punteadas."
            +      ],
            +      "returns": "Número: valor interpolado",
            +      "params": {
            +        "start": "Número: primer valor",
            +        "stop": "Número: segundo valor",
            +        "amt": "Número: número entre 0.0 y 1.0"
            +      }
            +    },
            +    "log": {
            +      "description": [
            +        "Calcula el logaritmo natural (logaritmo con base e) de un número. Esta función espera que el parámetro n sea de un valor más grande que 0.0. Usa Math.log()."
            +      ],
            +      "returns": "Número: logaritmo naturla de n",
            +      "params": {
            +        "n": "Number: number greater than 0"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "Calcula la magnitud (o tamaño) de un vector. Un vector es una dirección en el espacio comúnmente usada en gráfica computacional y álgebra lineal. Como no tiene posición de inicio, la magnitud del vector puede ser pensada como la distancia entre la coordenada 0,0 a su valor x,y. Por lo tanto, mag() es un atajo a escribir dist(0, 0, x, y)."
            +      ],
            +      "returns": "Número: magnitud del vector entre (0, 0) y (a, b)",
            +      "params": {
            +        "a": "Número: primer valor",
            +        "b": "Número: segundo valor"
            +      }
            +    },
            +    "map": {
            +      "description": [
            +        "Escala un nombre de un rango a otro rango. En el primer ejemplo anterior, el número 25 es convertido de un valor en el rango entre 0 y 100 a un valor cuyo rango está entre el borde izquierdo de la ventana (0) y el borde derecho (ancho).",
            +        "In the first example above, the number 25 is converted from a value in the range of 0 to 100 into a value that ranges from the left edge of the window (0) to the right edge (width)."
            +      ],
            +      "returns": "Número: número escalado",
            +      "params": {
            +        "value": "Número: el valor a ser convertido",
            +        "start1": "Número: límite inferior del rango actual",
            +        "stop1": "Número: límite superior del rango actual",
            +        "start2": "Número: límite inferior del rango deseado",
            +        "stop2": "Número: límite superior del rango deseado",
            +        "withinBounds": "Boolean: (Optional) constrain the value to the newly mapped range"
            +      }
            +    },
            +    "max": {
            +      "description": [
            +        "Determina el valor más grande en una secuencia de números, y luego retorna ese valor. max() acepta cualquier número de parámetros tipo número, o un arreglo de cualquier largo."
            +      ],
            +      "returns": "Número: número máximo",
            +      "params": {
            +        "n0": "Number: Number to compare",
            +        "n1": "Number: Number to compare",
            +        "nums": "Número|Arreglo: números a comparar"
            +      }
            +    },
            +    "min": {
            +      "description": [
            +        "Determina el valor más pequeño en una secuencia de números, y luego retorna ese valor. max() acepta cualquier número de parámetros tipo número, o un arreglo de cualquier largo."
            +      ],
            +      "returns": "Número: número mínimo",
            +      "params": {
            +        "n0": "Number: Number to compare",
            +        "n1": "Number: Number to compare",
            +        "nums": "Número|Arreglo: números a comparar"
            +      }
            +    },
            +    "norm": {
            +      "description": [
            +        "Normaliza un número de un rango a otro rango entre 0 y 1. Es idéntico a map(value, low, high, 0, 1). Los números fuera del rango no son saturados a 0 o 1, porque los números fuera de rango son muchas veces intencionales y útiles (ver el segundo ejemplo más arriba)"
            +      ],
            +      "returns": "Número: número normalizado",
            +      "params": {
            +        "value": "Número: valor entrante a ser normalizado",
            +        "start": "Número: límite inferior del rango actual",
            +        "stop": "Número: límite superior del rango actual"
            +      }
            +    },
            +    "pow": {
            +      "description": [
            +        "Facilita las expresiones exponenciales. La función pow() es una manera eficiente de multiplicar números po sí mismos (o sus recíprocos) en grandes cantidades. Por ejemplo, pow(3, 5) es equivalente a la expresión 3*3*3*3*3 y pow (3, -5) es equivalente a 1/3*3*3*3*3. Usa Math.pow()."
            +      ],
            +      "returns": "n^e",
            +      "params": {
            +        "n": "Número: base de la expresión exponencial",
            +        "e": "Número: potencia a la que se eleva la base"
            +      }
            +    },
            +    "round": {
            +      "description": [
            +        "Calcula el entero más cercano al parámetro n. Por ejemplo, round(133.8) retorna el valor 134. Usa la función Math.round()."
            +      ],
            +      "returns": "Número: número redondeado",
            +      "params": {
            +        "n": "Número: número a redondear",
            +        "decimals": "Number: (Optional) number of decimal places to round to, default is 0"
            +      }
            +    },
            +    "sq": {
            +      "description": [
            +        "Eleva al cuadrado un número (lo multiplica por sí mismo), El resultado es siempre un número positivo, porque multiplicar dos números negativos siempre resulta en un número positivo."
            +      ],
            +      "returns": "Número: número elevado al cuadrado",
            +      "params": {
            +        "n": "Número: número a elevar al cuadrado"
            +      }
            +    },
            +    "sqrt": {
            +      "description": [
            +        "Calcula la raíz cuadrada de un número. La raíz cuadrada de un número es siempre positiva, aunque puede haber una raíz cuadrada válida que sea negativa. La raíz cuadrada s de un número a es tal que s*s = a. Es lo opuesto a elevar al cuadrado. Usa Math.sqrt()."
            +      ],
            +      "returns": "Número: raíz cuadrada del número",
            +      "params": {
            +        "n": "Número: número no negativo al que se le calcula la raíz cuadrada"
            +      }
            +    },
            +    "fract": {
            +      "description": [
            +        "Calculates the fractional part of a number."
            +      ],
            +      "returns": "Number: fractional part of x, i.e, {x}",
            +      "params": {
            +        "num": "Number: Number whose fractional part needs to be found out"
            +      }
            +    },
            +    "createVector": {
            +      "description": [
            +        "Crea un nuevo objeto p5.Vector (el tipo de datos para almacenar vectores). Esto provee un vector de dos o tres dimensiones, específicamente un vector euclideano (también conocido como geométrico). Un vector es una entidad que tiene tanto magnitud como dirección."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "x": "Número: componente x del vector",
            +        "y": "Número: componente y del vector",
            +        "z": "Número: componente z del vector"
            +      }
            +    },
            +    "noise": {
            +      "description": [
            +        "Retorna el valor del ruido Perlin en las coordenadas específicas. El ruido Perlin es un generador de secuencias aleatorias produciendo una sucesión de números más naturalmente ordenada y armónica, en comparación con la función estándar random(). Fue inventada por Ken Perlin en los 1980s y ha sido usada desde entonces en aplicaciones gráficas para producir texturas procedurales, movimiento natural, figuras, terrenos, etc. La principal diferencia con la función random() es definida en una espacio infinito n-dimensional donde cada par de coordenadas corresponde a un valor fijo semi-aleatorio (fijado solo durante el tiempo de vida del programa; ver la función noiseSeed()). p5.js puede calcular ruido 1D, 2D y 3D, dependiendo del número de coordenadas dado. El valor resultante siempre estará entre 0.0 y 1.0. El valor de ruido puede ser animado moviéndose a través del espacio del ruido como fue demostrado en el ejemplo superior. Las dimensiones segunda y tercera también pueden ser interpretadas como tiempo. El ruido está estructurado de forma similar a una señal de audio, con respecto al uso de la función de las frecuencias. De forma similar al conecpto de armónicas en física, el ruido Perlin es calculado a lo largo de varias octavas que se han sumado para dar forma al resultado final. Otra manera de ajustar el caracter de la secuencia resultante es la escala de las coordenadas de entrada. Como la función trabaja en un espacio infinito, el valor de las coordenadas no importa como tal, solo la distancia entre las coordenadas sucesivas importa (por ejemplo: cuando se usa noise() dentro de un bucle). Como regla general, a menor la diferencia entre coordenadas, más suave es el ruido resultante. Pasos entre 0.005 y 0.03 funcionan mejor para la mayor parte de las aplicaciones, pero esto diferirá dependiendo del uso."
            +      ],
            +      "returns": "valor de ruido Perlin (entre 0 y 1) en las coordenadas especificadas",
            +      "params": {
            +        "x": "Número: coordenada x en el espacio del ruido",
            +        "y": "Número: coordenada y en el espacio del ruido",
            +        "z": "Número: coordenada z en el espacio del ruido"
            +      }
            +    },
            +    "noiseDetail": {
            +      "description": [
            +        "Ajusta el caracter y nivel de detalle producido por la función de ruido Perlin. Similar al concepto de armónicas en física, el ruido es calculado a lo largo de varias octavas. Las octavas más graves contribuyen de forma más significativa a la señal de salida y como define la intensidad general del ruido, mientras que las octavas más altas crean detalles más finos en la secuencia de ruido. Por defecto, el ruido es calculado a lo largo de 4 octavas, con cada octava contribuyendo exactamente la mitad que su predecesora, partiendo con una intensidad de 50% para la primera octava. Este tamaño de caída puede ser cambiado al añadir un parámetro adicional a la función. Por ejemplo, un factor de caída de 75% significa que cada octava tendrá un 75% de impacto (25% menos) que la octava anterior. Cualquier valor entre 0.0 y 1.0 es válido, sin embargo nota que valores superiores a 0.5 pueden resultar en que noise() retorne valores mayores a 1.0. Al cambiar estos parámetros, la señal creada por noise() puede ser adaptada para calzar con necesidades y características específicas."
            +      ],
            +      "params": {
            +        "lod": "Número: número de octavas a ser usadas por el ruido",
            +        "falloff": "Número: factor de caída para cada octava"
            +      }
            +    },
            +    "noiseSeed": {
            +      "description": [
            +        "Define el valor semilla para la función noise(). Por defecto, noise() produce diferentes resultados cada vez que el programa es ejecutado. Defines el parámetro value a una constante para que retorne la misma secuencia de números pseudo-aleatorios cada vez que el programa es ejecutado"
            +      ],
            +      "params": {
            +        "seed": "Número: el valor semilla"
            +      }
            +    },
            +    "randomSeed": {
            +      "description": [
            +        "Define la semilla para la función random(). Por defecto, la función random() produce diferentes resultados cada vez que el programa es ejecutado. Definir el parámetro semilla como una constante hace que retorne la misma secuencia de números pseudo-aleatorios cada vez que el programa es ejecutado.",
            +        "By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program is run. Set the seed parameter to a constant to return the same pseudo-random numbers each time the software is run."
            +      ],
            +      "params": {
            +        "seed": "Número: el valor semilla"
            +      }
            +    },
            +    "random": {
            +      "description": [
            +        "Retorna un número aleaotorio de tipo float (punto flotante). Acepta 0, 1 o 2 argumentos. Si no se le da un argumento, retorna un número aleatorio entre 0 y 1 (sin incluir 1). Si se da un argumento y es un número, retorna un número aleatorio entre 0 y hasta (pero sin incluir) el parámetro. Si se da un argumento y es un arreglo, retorna una elemento al azar del arreglo. Si se dan dos argumentos, retorna un número aleatorio entre el primer argumento y hasta (pero sin incluir) el segundo argumento.",
            +        "Takes either 0, 1 or 2 arguments.",
            +        "If no argument is given, returns a random number from 0 up to (but not including) 1.",
            +        "If one argument is given and it is a number, returns a random number from 0 up to (but not including) the number.",
            +        "If one argument is given and it is an array, returns a random element from that array.",
            +        "If two arguments are given, returns a random number from the first argument up to (but not including) the second argument."
            +      ],
            +      "returns": "Número: el número aleatorio o un elemento aleatorio de un conjunto de opciones",
            +      "params": {
            +        "min": "Número: el límite inferior (inclusivo)",
            +        "max": "Número: el límite superio (exclusivo)",
            +        "choices": "Arreglo: el arreglo del cual se elige"
            +      }
            +    },
            +    "randomGaussian": {
            +      "description": [
            +        "Retorna un número aleatorio ajjustado a una distribución Gaussiana o normal. No existe teóricamente un valor mínimo o máximo que la función randomGaussian() pueda retornar. En vez de eso, existe solo una muy baja probabilidad de retornar valores lejos de la media, y una alta probabilidad de retornar números cercanos a la media. Acepta 0, 1 o 2 argumentos. Si no tiene argumentos, retorna una media de 0 y una desviación estándar de 1. Si tiene un argumento, el argumento es la media (y la desviación estándar es 1). Si tiene dos argumentos, el primero es la media y el segundo es la desviación estándar."
            +      ],
            +      "returns": "el número aleatorio",
            +      "params": {
            +        "mean": "Número: la media",
            +        "sd": "Número: la desviación estándar"
            +      }
            +    },
            +    "acos": {
            +      "description": [
            +        "El inverso de la función cos(), retorna el arcocoseno de un valor. Esta función espera valores entre -1 y 1 y los valores retornados están en el rango entre 0 y PI (3.1415927)."
            +      ],
            +      "returns": "Número: el arcocoseno del valor",
            +      "params": {
            +        "value": "Número: el valor al que se aplica arcocoseno"
            +      }
            +    },
            +    "asin": {
            +      "description": [
            +        "El inverso de la función sin(), retorna el arcoseno de un valor. Esta función espera valores entre -1 y 1 y los valores retornados están en el rango entre -PI/2  y PI/2 ."
            +      ],
            +      "returns": "Número: el arcoseno del valor",
            +      "params": {
            +        "value": "Número: el valor al que se aplica arcoseno"
            +      }
            +    },
            +    "atan": {
            +      "description": [
            +        "El inverso de la función tan(), retorna el arcotangente de un valor. Esta función espera valores entre -Infinito e Infinito (exclusivo) y los valores retornados están en el rango entre -PI/2  y PI/2 ."
            +      ],
            +      "returns": "Número: el arcotangente del valor",
            +      "params": {
            +        "value": "Número: el valor al que se aplica arcotangente"
            +      }
            +    },
            +    "atan2": {
            +      "description": [
            +        "Calcula el ángulo (en radianes) desde un punto específico al origen, medido desde el eje x positivo. Los valores retornados son de tipo float entre  -PI/2  y PI/2. La función atan2() es más frecuentemente usada para orientar figuras figuras geométricas según la posición del cursor. Nota: la coordenada y del punto es el primer parámetro, y la coordenada x es el segundo parámetro, debido a la estructura para calcular la tangente.",
            +        "Note: The y-coordinate of the point is the first parameter, and the x-coordinate is the second parameter, due the the structure of calculating the tangent."
            +      ],
            +      "returns": "Número: el arcotangente del punto dado",
            +      "params": {
            +        "y": "Número: coordenada y del punto",
            +        "x": "Número: coordenada x del punto"
            +      }
            +    },
            +    "cos": {
            +      "description": [
            +        "calcula el coseno de un ángulo. Esta función toma en cuenta el modo actual de ángulo según angleMode(). Los valores son retornados en el rango entre -1 y 1."
            +      ],
            +      "returns": "Número: el coseno del ángulo",
            +      "params": {
            +        "angle": "Número: el ángulo"
            +      }
            +    },
            +    "sin": {
            +      "description": [
            +        "calcula el seno de un ángulo. Esta función toma en cuenta el modo actual de ángulo según angleMode(). Los valores son retornados en el rango entre -1 y 1."
            +      ],
            +      "returns": "Número: el seno del ángulo",
            +      "params": {
            +        "angle": "Número: el ángulo"
            +      }
            +    },
            +    "tan": {
            +      "description": [
            +        "calcula la tangente de un ángulo. Esta función toma en cuenta el modo actual de ángulo según angleMode(). Los valores son retornados en el rango entre -1 y 1."
            +      ],
            +      "returns": "Número: la tangente del ángulo",
            +      "params": {
            +        "angle": "Número: el ángulo"
            +      }
            +    },
            +    "degrees": {
            +      "description": [
            +        "Convierte una medida en radianes a su correspondiente valor en grados. Radianes y grados son dos maneras de calcular lo mismo. Hay 360 grados en un círculo y 2*PI radianes en un círculo. Por ejemplo, 90 grados equivalen a PI/2 radianes."
            +      ],
            +      "returns": "el ángulo convertido",
            +      "params": {
            +        "radians": "Número: valor en radianes a ser convertido a grados."
            +      }
            +    },
            +    "radians": {
            +      "description": [
            +        "Convierte una medida en grados a su correspondiente valor en radianes. Radianes y grados son dos maneras de calcular lo mismo. Hay 360 grados en un círculo y 2*PI radianes en un círculo. Por ejemplo, 90 grados equivalen a PI/2 radianes."
            +      ],
            +      "returns": "el ángulo convertido",
            +      "params": {
            +        "degrees": "Número: valor en grados a ser convertido a radianes."
            +      }
            +    },
            +    "angleMode": {
            +      "description": [
            +        "Define el modo actual de p5 para interpretar ángulos. El modo por defecto es en RADIANS (radianes)."
            +      ],
            +      "params": {
            +        "mode": "CONSTANTE: puede ser RADIANS (radianes) o DEGREES (grados)"
            +      }
            +    },
            +    "textAlign": {
            +      "description": [
            +        "Define el alineamiento actual para dibujar texto. Acepta dos argumentos: horizAlign(LEFT, CENTER o RIGHT) y vertAlign(TOP, BOTTOM, CENTER, o BASELINE). El parámetro horizAlign se refiere al valor x de la función text(), mientras que vel parámetro vertAlign al valor y. Así que si escribes textAlign(LEFT), estás alineando el borde izquierdo de tu texto al valor x dado en la función text(). Si escribes textAlign(RIGHT, TOP), estás alineando el borde derecho de tu texto con el valor x y el borde superior con el valor y del texto.",
            +        "The horizAlign parameter is in reference to the x value of the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter is in reference to the y value.",
            +        "So if you write textAlign(LEFT), you are aligning the left edge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>. If you write textAlign(RIGHT, TOP), you are aligning the right edge of your text to the x value and the top of edge of the text to the y value."
            +      ],
            +      "params": {
            +        "horizAlign": "Constante: alineamiento horizontal, puede ser LEFT, CENTER o RIGHT",
            +        "vertAlign": "Constante: alineamiento vertical, puede ser TOP, BOTTOM, CENTER o BASELINE"
            +      }
            +    },
            +    "textLeading": {
            +      "description": [
            +        "Define o retorna el espaciado, en pixeles, entre líneas de texto. Esta configuración será usada en todas las llamadas posteriores a la función text()."
            +      ],
            +      "params": {
            +        "leading": "Número: el tamaño en pixeles de espaciamiento entre líneas"
            +      }
            +    },
            +    "textSize": {
            +      "description": [
            +        "Define o retorna el tamaño actual de la tipografía. Este tamaño será usado en todas las llamadas posteriores a la función text(). El tamaño de la tipografía es medido en pixeles."
            +      ],
            +      "params": {
            +        "theSize": "Número: el tamaño en pixeles de las letras en pixeles"
            +      }
            +    },
            +    "textStyle": {
            +      "description": [
            +        "Define o retorna el estilo actual de la tipografía. Puede ser NORMAL (normal), ITALIC (cursivo) o BOLD (destacado). Notar que puede ser anulado por estilo CSS. Para tipografías que no sean de sistema (opentype, truetype, etc.), usa loadFont()."
            +      ],
            +      "params": {
            +        "theStyle": "Número|Constante: estilo del texto, puede ser NORMAL, ITALIC o BOLD"
            +      }
            +    },
            +    "textWidth": {
            +      "description": [
            +        "Calcula y retorna el ancho de cualquier caracter o string."
            +      ],
            +      "returns": "Número",
            +      "params": {
            +        "theText": "String: el String de caracteres a medir"
            +      }
            +    },
            +    "textAscent": {
            +      "description": [
            +        "Returns the ascent of the current font at its current size. The ascent represents the distance, in pixels, of the tallest character above the baseline."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "textDescent": {
            +      "description": [
            +        "Returns the descent of the current font at its current size. The descent represents the distance, in pixels, of the character with the longest descender below the baseline."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "textWrap": {
            +      "description": [
            +        "Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.",
            +        "WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.",
            +        "CHAR wrap style breaks lines wherever needed to stay within the text box.",
            +        "WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen."
            +      ],
            +      "returns": "String: wrapStyle",
            +      "params": {
            +        "wrapStyle": "Constant: text wrapping style, either WORD or CHAR"
            +      }
            +    },
            +    "loadFont": {
            +      "description": [
            +        "Carga un archivo de fuente de letra (.otf, .ttf) desde un archivo o URL, y retorna un objeto PFont. Este método es asíncrono, lo que significa que puede que no finalice antes de que la siguiente línea en tu bosquejo sea ejecutada. La ubicación del archivo debe ser relativo al archivo HTML que lo vincula con tu bosquejo. Cargar desde una URL u otra ubicación remota puede ser bloqueado por las opciones de seguridad del navegador.",
            +        "The path to the font should be relative to the HTML file that links in your sketch. Loading fonts from a URL or other remote location may be blocked due to your browser's built-in security."
            +      ],
            +      "returns": "Objeto: objeto p5.Font",
            +      "params": {
            +        "path": "String: número del archivo o URL a cargar",
            +        "callback": "Función: función a ser ejecutada después de que loadFont() es completada",
            +        "onError": "Function: (Optional) function to be executed if  an error occurs"
            +      }
            +    },
            +    "text": {
            +      "description": [
            +        "Dibuja texto en la pantalla. Muestra la información especificada en el primer parámetro en la pantalla, en la posición especificada por los parámetros adicionales. Una fuente por defecto será usada a menos que una fuente sea definida por la función textFont() y un tamaño por defecto será usado a menos que se use la función textSize(). Cambia el color del texto con la función fill(). Cambia la apariencia del texto con las funciones stroke() y strokeWeight(). El texto se muestra en relación a la función textAlign(), que da la opción de dibujar a la izuiqerda, derecha y centro de las coordenadas. Los parámetros x2 e y2 definen un área rectangular donde mostrar el texto y solo puede ser usado por los datos tipo String. Cuando estos parámetros son especificados, son interpretados según la configuración de rectMode(). El texto que no cabe completamente dentro del rectángulo especificado no será dibujado en pantalla.",
            +        "The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a> function, which gives the option to draw to the left, right, and center of the coordinates.",
            +        "The x2 and y2 parameters define a rectangular area to display within and may only be used with string data. When these parameters are specified, they are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a> setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. If x2 and y2 are not specified, the baseline alignment is the default, which means that the text will be drawn upwards from x and y.",
            +        "<b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font using the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above). <a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode."
            +      ],
            +      "params": {
            +        "str": "String: símbolos alfanuméricos a ser mostrados",
            +        "x": "Número: coordenada x del texto",
            +        "y": "Número: coordenada y del texto",
            +        "x2": "Número: por defecto, el ancho de la caja contenedora del texto, ver rectMode() para más información",
            +        "y2": "Número: por defecto, la altura de la caja contenedora del texto, ver rectMode() para más información"
            +      }
            +    },
            +    "textFont": {
            +      "description": [
            +        "Define la función actual con la que se dibujará el contenido de la función text()",
            +        "<b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported."
            +      ],
            +      "returns": "Objeto",
            +      "params": {
            +        "font": "Objeto|String: una fuente cargada con loadFont(), o un String representando una tipografía segura de la web (una fuente ampliamente disponible a lo largo de todos los sistemas).",
            +        "size": "Number: (Optional) the font size to use"
            +      }
            +    },
            +    "append": {
            +      "description": [
            +        "Añade un valor al final de un arreglo. Extiende el largo de un arreglo en una unidad. Usa la función Array.push()"
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "array": "Arreglo: Arreglo al que se agregará el dato",
            +        "value": "Cualquiera: a ser añadido al arreglo"
            +      }
            +    },
            +    "arrayCopy": {
            +      "description": [
            +        "Copia el arreglo (o una parte del arreglo) a otro arreglo. El arreglo fuente es copiado al arreglo de destino, empezando por la posición especificada por srcPosition y a la posición especificada por dstPosition. El número de elementos a copiar es determinado por el largo. Notar que al copiar valores se sobreescriben los valores existentes en el arreglo de destino. Para anexar valores en vez de sobreescribirlos, usa la función concat(). La versión simplificada con dos argumentos, arrayCopy(src, dest), copia un arreglo entero a otro del mismo tamaño. Es equivaletne a arrayCopy(src, 0, dst, 0, src.length). Usar esta función es mucho más eficiente para copiar datos de un arreglo que iterar con un bucle for() y copiar cada elemento individualmente.",
            +        "The simplified version with only two arguments, arrayCopy(src, dst), copies an entire array to another of the same size. It is equivalent to arrayCopy(src, 0, dst, 0, src.length).",
            +        "Using this function is far more efficient for copying array data than iterating through a for() loop and copying each element individually."
            +      ],
            +      "params": {
            +        "src": "Arreglo: el arreglo fuente",
            +        "srcPosition": "Número: posición inicial en el arreglo fuente",
            +        "dst": "Arreglo: el arreglo de destino",
            +        "dstPosition": "Número: posición inicial del arreglo de destino",
            +        "length": "Número: númeor de elementos del arreglo a ser copiados"
            +      }
            +    },
            +    "concat": {
            +      "description": [
            +        "Concatena dos arreglos, usa la función Array.concat(). No modifica los arreglos de entrada."
            +      ],
            +      "returns": "Arreglo: el arreglo concatenado",
            +      "params": {
            +        "a": "Arreglo: primer arreglo a concatenar",
            +        "b": "Arreglo: segundo arreglo a concatenar"
            +      }
            +    },
            +    "reverse": {
            +      "description": [
            +        "Invierte el orden un arreglo, usa Array.reverse()."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "list": "Arreglo: arreglo a ser invertido"
            +      }
            +    },
            +    "shorten": {
            +      "description": [
            +        "Disminuye un arreglo en un elemento y retorna el arreglo más corto, usa Array.pop()."
            +      ],
            +      "returns": "Arreglo: el arreglo acortado",
            +      "params": {
            +        "list": "Lista: arreglo a acortar"
            +      }
            +    },
            +    "shuffle": {
            +      "description": [
            +        "Ordena aleatoriamente los elementos de un arreglo. Implementa el algoritmo Fisher Yates."
            +      ],
            +      "returns": "Arreglo: retorna el arreglo ordenado",
            +      "params": {
            +        "array": "Arreglo: Arreglo a ordenar",
            +        "bool": "Boolean: modifica el arreglo"
            +      }
            +    },
            +    "sort": {
            +      "description": [
            +        "Ordena un arreglo de números, desde el más pequeño al más grande, o pone un arreglo de palabras en orden alfabético. El arreglo original no es modificado, un nuevo arreglo ordenado es retornado. El parámetro count define el número de elementos a ordenar. Por ejemplo, si hay 12 elementos en un arreglo y count es 5, los primeros 5 elementos del arreglo serán ordenados."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "list": "Arreglo: arreglo a ordenar",
            +        "count": "Número: número de elementos a ordenar, empezando desde 0"
            +      }
            +    },
            +    "splice": {
            +      "description": [
            +        "Inserta un valor o un arreglo de valores en un arreglo existente El primer parámetro especifica el arreglo inicial a ser modificado, y el segundo parámetro define los datos a insertarse. El tercer parámetro es un índice que especifica la posición del arreglo a partir de la que se insertarán los datos. Recuerda que el índice del arreglo empieza en 0, así que la primera posición es 0, la segunda es 1, etc."
            +      ],
            +      "returns": "el objeto p5",
            +      "params": {
            +        "list": "Arreglo: arreglo a ser modificado",
            +        "value": "Cualquiera: valor a ser introducido",
            +        "position": "Número: posición del arreglo donde se inserta el dato"
            +      }
            +    },
            +    "subset": {
            +      "description": [
            +        "Extrae un arreglo de elementos de un arreglo existente. El parámetro list define el arreglo desde el cual los elementos serán copiados, y los parámetros start y count especifican cuáles elementos extraer. Si no especifica count, los elementos serán extraidos desde el principio. Esta función no modifica el arreglo original"
            +      ],
            +      "returns": "Arreglo: arreglo de elementos extraidos",
            +      "params": {
            +        "list": "Arreglo: arreglo del cual se extrae",
            +        "start": "Número: posición de donde empezar a extraer",
            +        "count": "Número: número de valores a extraer"
            +      }
            +    },
            +    "float": {
            +      "description": [
            +        "Convierte un String a su representación de punto flotante. Los contenidos de un String deben parecerse a un número, en otro caso NaN es retornado. Por ejemplo, float('1234.56') evalua a 1234.56, pero float('giraffe') retorna NaN. Cuando un arreglo de valores es pasado, un arreglo de floats del mismo largo es retornado.",
            +        "When an array of values is passed in, then an array of floats of the same length is returned."
            +      ],
            +      "returns": "Número: representación en punto flotante de un string",
            +      "params": {
            +        "str": "String: string a ser procesado"
            +      }
            +    },
            +    "int": {
            +      "description": [
            +        "Convierte un boolean, string o float a su representación en número entero. Cuando un arreglo de valores es introducido, entonces un arreglo de enteros de la misma longitud es retornado."
            +      ],
            +      "returns": "Número: valor representado como entero",
            +      "params": {
            +        "n": "String|Boolean|Number: value to parse",
            +        "radix": "Integer: (Optional) the radix to convert to (default: 10)",
            +        "ns": "String|Boolean|Número|Arreglo: valor a procesar"
            +      }
            +    },
            +    "str": {
            +      "description": [
            +        "Convierte un boolean, string, o número a su representación en string. Cuando un arreglo de valores es introducido, entonces un arreglo de strings de la misma longitud es retornado."
            +      ],
            +      "returns": "String: valor representado como string",
            +      "params": {
            +        "n": "String|Boolean|Número|Arreglo: valor a procesar"
            +      }
            +    },
            +    "byte": {
            +      "description": [
            +        "Convierte un número, string o boolean a su representación en byte. Un byte puede solo ser un número entero entre -128 y 127, así que cuando un valor fuera de este rango es convertido, se hace wrap a la representación correspondiente en byte. Cuando un arreglo de números, string, o booleans es introducido, entonces un arreglo de bytes de la misma longitud es retornado."
            +      ],
            +      "returns": "Número: representación en formato byte del valor",
            +      "params": {
            +        "n": "String|Boolean|Número|Arreglo: valor a procesar",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "char": {
            +      "description": [
            +        "Convierte un número o string a su representaciómo como un string de un único caracter. Si se provee un parámetro, es primero pasado como entero y luego evaluado como un string de un único caracter. Cuando un arreglo de números o strings es introducido, entonces un arreglo de strings de un único caracter de la misma longitud es retornado."
            +      ],
            +      "returns": "String: representación en formato string del valor",
            +      "params": {
            +        "n": "String|Número|Arreglo: valor a procesar",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "unchar": {
            +      "description": [
            +        "Convierte un string de un único caracter a su correspondiente representación como valor entero. Cuando un arreglo de strings de un caracter es introducido, entonces un arreglo de enteros de la misma longitud es retornado."
            +      ],
            +      "returns": "Número: representación en formato entero del valor",
            +      "params": {
            +        "n": "String|Arreglo: valor a procesar",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "hex": {
            +      "description": [
            +        "Convierte un número a su correspondiente representación como hexadecimal. Si se ingersa un segundo parámetro, es usado para definir el número de caracteres a generar en la notación hexadecimal. Cuando un arreglo es introducido, entonces un arreglo de strings en notación hexadecimal de la misma longitud es retornado."
            +      ],
            +      "returns": "String: representación en formato string hexadecimal del valor",
            +      "params": {
            +        "n": "Número|Arreglo: valor a procesar",
            +        "digits": "Number (Optional)",
            +        "ns": "Number[]: array of values to parse"
            +      }
            +    },
            +    "unhex": {
            +      "description": [
            +        "Convierte una representación en string de un número hexadecimal a su correspondiente representación como valor entero. Cuando un arreglo de strings en notación hexadecimal es introducido, entonces un arreglo de enteros de la misma longitud es retornado."
            +      ],
            +      "returns": "Número: representación en formato entero del valor hexadecimal",
            +      "params": {
            +        "n": "String|Arreglo: valor a procesar",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "join": {
            +      "description": [
            +        "Combina una arreglo de Strings en un String, cada uno separado por los caracteres usados como parámetro separator. Para unir arreglos de enteros o floats, es necesario primero convertirlos a Strings usando las funciones nf() o nfs()."
            +      ],
            +      "returns": "String: String unificado",
            +      "params": {
            +        "list": "Arreglo: arreglo de Strings a ser unidos",
            +        "separator": "String: String a ser posicionado entre cada item"
            +      }
            +    },
            +    "match": {
            +      "description": [
            +        "Esta función es usada para aplicar una expresión regular a una porción de texto,  y retorna grupos coincidentes (elementos encontrados entre paréntesis) como un arreglo de Strings. Si no existen coincidencias, se retorna el valor null. Si no se especifican grupos en la expresión regular, pero la secuencia coincide, un arreglo de largo 1 (con el texto coincidente como primer elemento del arreglo) será retornado. Para usar la función, primero comprueba si el resultado es null. Si el resultado es null, entonces la secuencia no tuvo coincidencias. Si la secuencia tuvo coincidencias, retorna un arreglo. Si exsiten grupos (especificados como conjuntos de paréntesis) en la expresión regular, entonces los contenidos de cada uno serán retornados en el arreglo. El elemento[0] de una coincidencia de expresión regular retorna el string coincidente, y el grupo de coincidencia empieza en el elemento[1] (el primer grupo es [1], el segundo es [2], etc).",
            +        "To use the function, first check to see if the result is null. If the result is null, then the sequence did not match at all. If the sequence did match, an array is returned.",
            +        "If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Element [0] of a regular expression match returns the entire matching string, and the match groups start at element [1] (the first group is [1], the second [2], and so on)."
            +      ],
            +      "returns": "Arreglo: arreglo de Strings encontrados",
            +      "params": {
            +        "str": "String: el String a ser buscado",
            +        "regexp": "String: la expresión regular a ser usada para buscar coincidencias"
            +      }
            +    },
            +    "matchAll": {
            +      "description": [
            +        "Esta función es usada para aplicar una expresión regular a una porción de texto,  y retorna una lista de grupos coincidentes (elementos encontrados entre paréntesis) como un arreglo de Strings bidimensional. Si no existen coincidencias, se retorna el valor null. Si no se especifican grupos en la expresión regular, pero la secuencia coincide, un arreglo de dos dimensiones es retornado, pero es de largo 1. Para usar la función, primero comprueba si el resultado es null. Si el resultado es null, entonces la secuencia no tuvo coincidencias. Si la secuencia tuvo coincidencias, retorna un arreglo 2D. Si exsiten grupos (especificados como conjuntos de paréntesis) en la expresión regular, entonces los contenidos de cada uno serán retornados en el arreglo. El elemento[i][0] de una coincidencia de expresión regular retorna el string coincidente completo, y el grupo de coincidencia empieza en el elemento[i][1] (el primer grupo es [i][1], el segundo es [i][2], etc).",
            +        "To use the function, first check to see if the result is null. If the result is null, then the sequence did not match at all. If the sequence did match, a 2D array is returned.",
            +        "If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Assuming a loop with counter variable i, element [i][0] of a regular expression match returns the entire matching string, and the match groups start at element [i][1] (the first group is [i][1], the second [i][2], and so on)."
            +      ],
            +      "returns": "Arreglo: arreglo 2D de Strings encontrados",
            +      "params": {
            +        "str": "String: el String a ser buscado",
            +        "regexp": "String: la expresión regular a ser usada para buscar coincidencias"
            +      }
            +    },
            +    "nf": {
            +      "description": [
            +        "Función de utilidad para formatear números a strings. Existen dos veriones: una para formatear floats, y una para formatear enteros. Los valores de los dígitos y los parámetros left y right siempre deben ser enteros positivos"
            +      ],
            +      "returns": "String|Arreglo: String formateada",
            +      "params": {
            +        "num": "Número|Arreglo: el número a formatear",
            +        "left": "Número: número de dígitos a la izquierda del punto decimal",
            +        "right": "Número: número de dígitos a la derecha del punto decimal",
            +        "nums": "Array: the Numbers to format"
            +      }
            +    },
            +    "nfc": {
            +      "description": [
            +        "Función de utilidad para formatear números en strings y poner las comas apropiadas para señalar múltiplos de mil. Hay dos versiones: una para números enteros y otra para arreglos de enteros. El valor del parámetro right debe siempre ser un entero positivo."
            +      ],
            +      "returns": "String|Arreglo: String formateada",
            +      "params": {
            +        "num": "Número|Arreglo: el número a formatear",
            +        "right": "Número: número de dígitos a la derecha del punto decimal",
            +        "nums": "Array: the Numbers to format"
            +      }
            +    },
            +    "nfp": {
            +      "description": [
            +        "Función de utilidad para formatear números en strings. Similar a nf() pero pone un signo + en frente de los números positivos y un signo - en frente de números negativos. Hay dos versiones, una para formatear floats y otra para formatear enteros. Los valores de los parámetros left y right deben siempre ser enteros positivos."
            +      ],
            +      "returns": "String|Arreglo: String formateada",
            +      "params": {
            +        "num": "Número|Arreglo: el número a formatear",
            +        "left": "Número: número de dígitos a la izquierda del punto decimal",
            +        "right": "Número: número de dígitos a la derecha del punto decimal",
            +        "nums": "Number[]: the Numbers to format"
            +      }
            +    },
            +    "nfs": {
            +      "description": [
            +        "Función de utilidad para formatear números en strings. Similar a nf() pero pone un espacio en frente de los números positivos y un signo - en frente de números negativos. Hay dos versiones, una para formatear floats y otra para formatear enteros. Los valores de los parámetros left y right deben siempre ser enteros positivos."
            +      ],
            +      "returns": "String|Arreglo: String formateada",
            +      "params": {
            +        "num": "Número|Arreglo: el número a formatear",
            +        "left": "Número: número de dígitos a la izquierda del punto decimal",
            +        "right": "Número: número de dígitos a la derecha del punto decimal",
            +        "nums": "Array: the Numbers to format"
            +      }
            +    },
            +    "split": {
            +      "description": [
            +        "La función split usa String.split(), corta un String en pedazos usando un caracter o String como delimitador. El parámetro delim especifica el caracter o caracteres que marcan los bordes entre cada pieza. Un arreglo String[] es retornado, que contiene cada una de las piezas. La función splitTokens() funciona de forma similar, excepto que divide usango un rango de caracteres en vez de usar un caracter o una secuencia de caracteres específicos.",
            +        "The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it splits using a range of characters instead of a specific character or sequence."
            +      ],
            +      "returns": "Arreglo: arreglo de Strings",
            +      "params": {
            +        "value": "String: el String a ser dividido",
            +        "delim": "String: el String usado para separar los datos"
            +      }
            +    },
            +    "splitTokens": {
            +      "description": [
            +        "La función splitTokens() divide un String en uno o varios caracteres delimitadores o tokens. El parámetro delim especifica el o los caracteres a ser usados como borde.",
            +        "Si no se especifican caracteres delim, cualquier caracter tipo whitespace será usado para dividir. Los caracteres whitespace incluyen tabulación (\\t), nueva línea (\\n), retorno de carro (\\r), entrada de formulario (\\f), y espacio."
            +      ],
            +      "returns": "Arreglo: arreglo de Strings",
            +      "params": {
            +        "value": "String: el String a ser dividido",
            +        "delim": "String: lista de Strings individuales que serán usados como separadores"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "Remueve caracteres tipo whitespace (espacio en blanco) del comienzo y el final de un String. En adición a los caracteres estámdar de whitespace como espacio, retorno de carro y tabulación, esta función también remueve el caracter Unicode nbsp."
            +      ],
            +      "returns": "String|Arreglo: un String o arreglo de Strings recortados.",
            +      "params": {
            +        "str": "String: a String to be trimmed",
            +        "strs": "Array: an Array of Strings to be trimmed"
            +      }
            +    },
            +    "day": {
            +      "description": [
            +        "p5.js se comunica con el reloj de tu computador. La función day() retorna el día actual como un valor entre 1 y 31."
            +      ],
            +      "returns": "Número: el día actual"
            +    },
            +    "hour": {
            +      "description": [
            +        "p5.js se comunica con el reloj de tu computador. La función hour() retorna la hora actual como un valor entre 0 y 23."
            +      ],
            +      "returns": "Número: la hora actual"
            +    },
            +    "minute": {
            +      "description": [
            +        "p5.js se comunica con el reloj de tu computador. La función minute() retorna el minuto actual como un valor entre 0 y 59."
            +      ],
            +      "returns": "Número: el minuto actual"
            +    },
            +    "millis": {
            +      "description": [
            +        "Retorna el número de milisegundos (milésimas de segundo) desde que el programa empezó a correr. La información es usada a menudo para temporizar eventos y animar secuencias"
            +      ],
            +      "returns": "Número: el número de milisegundos desde que empezó el programa"
            +    },
            +    "month": {
            +      "description": [
            +        "p5.js se comunica con el reloj de tu computador. La función month() retorna el mes actual como un valor entre 1 y 12."
            +      ],
            +      "returns": "Número: el mes actual"
            +    },
            +    "second": {
            +      "description": [
            +        "p5.js se comunica con el reloj de tu computador. La función second() retorna el mes actual como un valor entre 0 y 59."
            +      ],
            +      "returns": "Número: el segundo actual"
            +    },
            +    "year": {
            +      "description": [
            +        "p5.js se comunica con el reloj de tu computador. La función year() retorna el año actual como un entero (2014, 2015, 2015, etc)."
            +      ],
            +      "returns": "Número: el año actual"
            +    },
            +    "plane": {
            +      "description": [
            +        "Dibuja un plano con ancho y altura dados."
            +      ],
            +      "params": {
            +        "width": "Número: ancho del plano",
            +        "height": "Número: altura del plano",
            +        "detailX": "Número: número opcional de subdivisiones triangulares en la dimensión x",
            +        "detailY": "Número: número opcional de subdivisiones triangulares en la dimensión y"
            +      }
            +    },
            +    "box": {
            +      "description": [
            +        "Dibuja una caja con ancho, altura y profundidad dados."
            +      ],
            +      "params": {
            +        "width": "Número: ancho de la caja",
            +        "Height": "Número: altura de la caja",
            +        "depth": "Número: profundidad de la caja",
            +        "detailX": "Número: número opcional de subdivisiones triangulares en la dimensión x",
            +        "detailY": "Número: número opcional de subdivisiones triangulares en la dimensión y"
            +      }
            +    },
            +    "sphere": {
            +      "description": [
            +        "Dibuja una esfera de radio dado.",
            +        "DetailX and detailY determines the number of subdivisions in the x-dimension and the y-dimension of a sphere. More subdivisions make the sphere seem smoother. The recommended maximum values are both 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "Número: radio del círculo",
            +        "detailX": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 24",
            +        "detailY": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 16"
            +      }
            +    },
            +    "cylinder": {
            +      "description": [
            +        "Dibuja un cilindro de radio y altura dados.",
            +        "DetailX and detailY determines the number of subdivisions in the x-dimension and the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother. The recommended maximum value for detailX is 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "Número: radio de la superficie",
            +        "height": "Número: altura del cilindro",
            +        "detailX": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 24",
            +        "detailY": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 16",
            +        "bottomCap": "Boolean: (Optional) whether to draw the bottom of the cylinder",
            +        "topCap": "Boolean: (Optional) whether to draw the top of the cylinder"
            +      }
            +    },
            +    "cone": {
            +      "description": [
            +        "Dibuja un cono de radio y altura dados.",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a cone. More subdivisions make the cone seem smoother. The recommended maximum value for detailX is 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "Número: radio de la superficie inferior",
            +        "height": "Número: altura del cono",
            +        "detailX": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 24",
            +        "detailY": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 16",
            +        "cap": "Boolean: (Optional) whether to draw the base of the cone"
            +      }
            +    },
            +    "ellipsoid": {
            +      "description": [
            +        "Dibuja un elipsoide de radio dado.",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother. Avoid detail number above 150, it may crash the browser."
            +      ],
            +      "params": {
            +        "radiusx": "Número: radio x del círculo",
            +        "radiusy": "Número: radio y del círculo",
            +        "radiusz": "Número: radio z del círculo",
            +        "detailX": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 24. Evita números mayores a 150 que podrían colapsar el navegador.",
            +        "detailY": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 16. Evita números mayores a 150 que podrían colapsar el navegador."
            +      }
            +    },
            +    "torus": {
            +      "description": [
            +        "Dibuja un toroide con radio y tubo dado.",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a torus. More subdivisions make the torus appear to be smoother. The default and maximum values for detailX and detailY are 24 and 16, respectively. Setting them to relatively small values like 4 and 6 allows you to create new shapes other than a torus."
            +      ],
            +      "params": {
            +        "radius": "Número: radio del anillo completo",
            +        "tubeRadius": "Número: radio del tubo",
            +        "detailX": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 24.",
            +        "detailY": "Número: opcional, número de segmentos, a mayor número de segmentos la geometría es más suave, por defecto es 16."
            +      }
            +    },
            +    "orbitControl": {
            +      "description": [
            +        "Allows movement around a 3D sketch using a mouse or trackpad. Left-clicking and dragging will rotate the camera position about the center of the sketch, right-clicking and dragging will pan the camera position without rotation, and using the mouse wheel (scrolling) will move the camera closer or further from the center of the sketch. This function can be called with parameters dictating sensitivity to mouse movement along the X and Y axes. Calling this function without parameters is equivalent to calling orbitControl(1,1). To reverse direction of movement in either axis, enter a negative number for sensitivity."
            +      ],
            +      "params": {
            +        "sensitivityX": "Number: (Optional) sensitivity to mouse movement along X axis",
            +        "sensitivityY": "Number: (Optional) sensitivity to mouse movement along Y axis",
            +        "sensitivityZ": "Number: (Optional) sensitivity to scroll movement along Z axis"
            +      }
            +    },
            +    "debugMode": {
            +      "description": [
            +        "debugMode() helps visualize 3D space by adding a grid to indicate where the ‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z directions. This function can be called without parameters to create a default grid and axes icon, or it can be called according to the examples above to customize the size and position of the grid and/or axes icon. The grid is drawn using the most recently set stroke color and weight. To specify these parameters, add a call to stroke() and strokeWeight() just before the end of the draw() loop.",
            +        "By default, the grid will run through the origin (0,0,0) of the sketch along the XZ plane and the axes icon will be offset from the origin. Both the grid and axes icon will be sized according to the current canvas size. Note that because the grid runs parallel to the default camera view, it is often helpful to use debugMode along with orbitControl to allow full view of the grid."
            +      ],
            +      "params": {
            +        "mode": "Constant: either GRID or AXES",
            +        "gridSize": "Number: (Optional) size of one side of the grid",
            +        "gridDivisions": "Number: (Optional) number of divisions in the grid",
            +        "xOff": "Number: (Optional) X axis offset from origin (0,0,0)",
            +        "yOff": "Number: (Optional) Y axis offset from origin (0,0,0)",
            +        "zOff": "Number: (Optional) Z axis offset from origin (0,0,0)",
            +        "axesSize": "Number: (Optional) size of axes icon",
            +        "gridXOff": "Number (Optional)",
            +        "gridYOff": "Number (Optional)",
            +        "gridZOff": "Number (Optional)",
            +        "axesXOff": "Number (Optional)",
            +        "axesYOff": "Number (Optional)",
            +        "axesZOff": "Number (Optional)"
            +      }
            +    },
            +    "noDebugMode": {
            +      "description": [
            +        "Turns off debugMode() in a 3D sketch."
            +      ]
            +    },
            +    "ambientLight": {
            +      "description": [
            +        "Crea una luz ambiente con color"
            +      ],
            +      "params": {
            +        "v1": "Número|Arreglo|String|p5.Color: valor de gris, rojo o tinte (dependiendo del modo de color actual), o arreglo de color o String de color CSS",
            +        "v2": "Número: opcional, valor de verde o saturación",
            +        "v3": "Número: opcional, valor de azul o brillo",
            +        "alpha": "Número: opcional, valor de opacidad",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the ambient light color"
            +      }
            +    },
            +    "specularColor": {
            +      "description": [
            +        "Set's the color of the specular highlight when using a specular material and specular light.",
            +        "This method can be combined with specularMaterial() and shininess() functions to set specular highlights. The default color is white, ie (255, 255, 255), which is used if this method is not called before specularMaterial(). If this method is called without specularMaterial(), There will be no effect.",
            +        "Note: specularColor is equivalent to the processing function <a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the ambient light color"
            +      }
            +    },
            +    "directionalLight": {
            +      "description": [
            +        "Crea una luz direccional con color y dirección",
            +        "A maximum of 5 directionalLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Número|Arreglo|String|p5.Color: valor de gris, rojo o tinte (dependiendo del modo de color actual), o arreglo de color o String de color CSS",
            +        "v2": "Número: opcional, valor de verde o saturación",
            +        "v3": "Número: opcional, valor de azul o brillo",
            +        "position": "p5.Vector: the direction of the light",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string,  or <a href=\"#/p5.Color\">p5.Color</a> value",
            +        "x": "Número|p5.Vector: dirección del eje x o un p5.Vector",
            +        "y": "Número: opcional, dirección del eje y",
            +        "z": "Número: opcional, dirección del eje z"
            +      }
            +    },
            +    "pointLight": {
            +      "description": [
            +        "Crea una luz puntual con color y posición",
            +        "A maximum of 5 pointLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Número|Arreglo|String|p5.Color: valor de gris, rojo o tinte (dependiendo del modo de color actual), o arreglo de color o String de color CSS",
            +        "v2": "Número: opcional, valor de verde o saturación",
            +        "v3": "Número: opcional, valor de azul o brillo",
            +        "x": "Número|p5.Vector: dirección del eje x o un p5.Vector",
            +        "y": "Número: opcional, dirección del eje y",
            +        "z": "Número: opcional, dirección del eje z",
            +        "position": "p5.Vector: the position of the light",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string, or <a href=\"#/p5.Color\">p5.Color</a> value"
            +      }
            +    },
            +    "lights": {
            +      "description": [
            +        "Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop."
            +      ]
            +    },
            +    "lightFalloff": {
            +      "description": [
            +        "Sets the falloff rates for point lights. It affects only the elements which are created after it in the code. The default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:",
            +        "d = distance from light position to vertex position",
            +        "falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)"
            +      ],
            +      "params": {
            +        "constant": "Number: constant value for determining falloff",
            +        "linear": "Number: linear value for determining falloff",
            +        "quadratic": "Number: quadratic value for determining falloff"
            +      }
            +    },
            +    "spotLight": {
            +      "description": [
            +        "Creates a spotlight with a given color, position, direction of light, angle and concentration. Here, angle refers to the opening or aperture of the cone of the spotlight, and concentration is used to focus the light towards the center. Both angle and concentration are optional, but if you want to provide concentration, you will also have to specify the angle.",
            +        "A maximum of 5 spotLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value (depending on the current color mode),",
            +        "v2": "Number: green or saturation value",
            +        "v3": "Number: blue or brightness value",
            +        "x": "Number: x axis position",
            +        "y": "Number: y axis position",
            +        "z": "Number: z axis position",
            +        "rx": "Number: x axis direction of light",
            +        "ry": "Number: y axis direction of light",
            +        "rz": "Number: z axis direction of light",
            +        "angle": "Number: (Optional) optional parameter for angle. Defaults to PI/3",
            +        "conc": "Number: (Optional) optional parameter for concentration. Defaults to 100",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string, or <a href=\"#/p5.Color\">p5.Color</a> value",
            +        "position": "p5.Vector: the position of the light",
            +        "direction": "p5.Vector: the direction of the light"
            +      }
            +    },
            +    "noLights": {
            +      "description": [
            +        "This function will remove all the lights from the sketch for the subsequent materials rendered. It affects all the subsequent methods. Calls to lighting methods made after noLights() will re-enable lights in the sketch."
            +      ]
            +    },
            +    "loadModel": {
            +      "description": [
            +        "Carga un modelo 3d desde un archivo OBJ. Una de las limitaciones del formato OBJ es que no trae incorporado un sentido de escala. Esto significa que los modelos exportados por distintos programas pueden ser de tamaños radicalmente distintos. Si tu modelo no está siendo mostrado en pantalla, trata llamando a la función loadMode() con el parámetro de normalización configurado como verdadero. Esto escalará el tamaño del modelo a una escala apropiada para p5. También puedes hacer cambios adicionales al tamaño final de tu modelo con la función scale().",
            +        "<a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>. This allows the model to load fully before the rest of your code is run.",
            +        "One of the limitations of the OBJ and STL format is that it doesn't have a built-in sense of scale. This means that models exported from different programs might be very different sizes. If your model isn't displaying, try calling <a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the model to a scale appropriate for p5. You can also make additional changes to the final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.",
            +        "Also, the support for colored STL files is not present. STL files with color will be rendered without color properties."
            +      ],
            +      "returns": "el objeto p5.Geometry3D",
            +      "params": {
            +        "path": "String: ubicación del modelo a cargar",
            +        "normalize": "Boolean:  Si es verdadero (true), escala el modelo a un tamaño estandarizado al momento de cargarlo.",
            +        "successCallback": "Función(p5.Geometry3D): función a ser llamada cuando el modelo se cargue. Será pasada al modelo del objeto 3D.",
            +        "failureCallback": "Función(evento): llamada con el error evento si la imagen no falla al cargar.",
            +        "fileType": "String: (Optional) The file extension of the model  (<code>.stl</code>, <code>.obj</code>)."
            +      }
            +    },
            +    "model": {
            +      "description": [
            +        "Hace el render de un modelo 3D en la pantalla."
            +      ],
            +      "params": {
            +        "model": "p5.Geometry: modelo 3D cargado para realizar render"
            +      }
            +    },
            +    "loadShader": {
            +      "description": [
            +        "Loads a custom shader from the provided vertex and fragment shader paths. The shader files are loaded asynchronously in the background, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.",
            +        "For now, there are three main types of shaders. p5 will automatically supply appropriate vertices, normals, colors, and lighting attributes if the parameters defined in the shader match the names."
            +      ],
            +      "returns": "p5.Shader: a shader object created from the provided vertex and fragment shader files.",
            +      "params": {
            +        "vertFilename": "String: path to file containing vertex shader source code",
            +        "fragFilename": "String: path to file containing fragment shader source code",
            +        "callback": "Function: (Optional) callback to be executed after loadShader completes. On success, the Shader object is passed as the first argument.",
            +        "errorCallback": "Function: (Optional) callback to be executed when an error occurs inside loadShader. On error, the error is passed as the first argument."
            +      }
            +    },
            +    "createShader": {
            +      "returns": "p5.Shader: a shader object created from the provided vertex and fragment shaders.",
            +      "params": {
            +        "vertSrc": "String: source code for the vertex shader",
            +        "fragSrc": "String: source code for the fragment shader"
            +      }
            +    },
            +    "shader": {
            +      "description": [
            +        "The <a href=\"#/p5/shader\">shader()</a> function lets the user provide a custom shader to fill in shapes in WEBGL mode. Users can create their own shaders by loading vertex and fragment shaders with <a href=\"#/p5/loadShader\">loadShader()</a>."
            +      ],
            +      "params": {
            +        "s": "p5.Shader: (Optional) the desired <a href=\"#/p5.Shader\">p5.Shader</a> to use for rendering shapes."
            +      }
            +    },
            +    "resetShader": {
            +      "description": [
            +        "This function restores the default shaders in WEBGL mode. Code that runs after resetShader() will not be affected by previously defined shaders. Should be run after <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "texture": {
            +      "description": [
            +        "Textura para geometría. Puedes ver todos los posibles materiales en este ejemplo (TODO)."
            +      ],
            +      "params": {
            +        "tex": "p5.Image|p5.MediaElement|p5.Graphics: gráfica bidimensional para hacer render como textura."
            +      }
            +    },
            +    "textureMode": {
            +      "description": [
            +        "Sets the coordinate space for texture mapping. The default mode is IMAGE which refers to the actual coordinates of the image. NORMAL refers to a normalized space of values ranging from 0 to 1. This function only works in WEBGL mode.",
            +        "With IMAGE, if an image is 100 x 200 pixels, mapping the image onto the entire size of a quad would require the points (0,0) (100, 0) (100,200) (0,200). The same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1)."
            +      ],
            +      "params": {
            +        "mode": "Constant: either IMAGE or NORMAL"
            +      }
            +    },
            +    "textureWrap": {
            +      "description": [
            +        "Sets the global texture wrapping mode. This controls how textures behave when their uv's go outside of the 0 - 1 range. There are three options: CLAMP, REPEAT, and MIRROR.",
            +        "CLAMP causes the pixels at the edge of the texture to extend to the bounds REPEAT causes the texture to tile repeatedly until reaching the bounds MIRROR works similarly to REPEAT but it flips the texture with every new tile",
            +        "REPEAT & MIRROR are only available if the texture is a power of two size (128, 256, 512, 1024, etc.).",
            +        "This method will affect all textures in your sketch until a subsequent textureWrap call is made.",
            +        "If only one argument is provided, it will be applied to both the horizontal and vertical axes."
            +      ],
            +      "params": {
            +        "wrapX": "Constant: either CLAMP, REPEAT, or MIRROR",
            +        "wrapY": "Constant: (Optional) either CLAMP, REPEAT, or MIRROR"
            +      }
            +    },
            +    "normalMaterial": {
            +      "description": [
            +        "Material normal para geometría. Puedes ver todos los posibles materiales en este ejemplo (TODO)."
            +      ]
            +    },
            +    "ambientMaterial": {
            +      "description": [
            +        "Material ambiente para geometría con un color dado. Puedes ver todos los posibles materiales en este ejemplo (TODO)."
            +      ],
            +      "params": {
            +        "v1": "Número|Arreglo|String|p5.Color: valor de gris, rojo o tinte (dependiendo del modo de color), o arreglo de color, o String de color CSS",
            +        "v2": "Número: opcional, valor de verde o saturación",
            +        "v3": "Número: opcional, valor de azul o brillo",
            +        "color": "Number[]|String|p5.Color: color, color Array, or CSS color string"
            +      }
            +    },
            +    "emissiveMaterial": {
            +      "description": [
            +        "Sets the emissive color of the material used for geometry drawn to the screen. This is a misnomer in the sense that the material does not actually emit light that effects surrounding polygons. Instead, it gives the appearance that the object is glowing. An emissive material will display at full strength even if there is no light for it to reflect."
            +      ],
            +      "params": {
            +        "v1": "Number: gray value, red or hue value  (depending on the current color mode),",
            +        "v2": "Number: (Optional) green or saturation value",
            +        "v3": "Number: (Optional) blue or brightness value",
            +        "a": "Number: (Optional) opacity",
            +        "color": "Number[]|String|p5.Color: color, color Array, or CSS color string"
            +      }
            +    },
            +    "specularMaterial": {
            +      "description": [
            +        "Material espejo para geometría con un color dado. Puedes ver todos los posibles materiales en este ejemplo."
            +      ],
            +      "params": {
            +        "gray": "Number: number specifying value between white and black.",
            +        "alpha": "Número: opcional, valor de opacidad",
            +        "v1": "Número|Arreglo|String|p5.Color: valor de gris, rojo o tinte (dependiendo del modo de color), o arreglo de color, o String de color CSS",
            +        "v2": "Número: opcional, valor de verde o saturación",
            +        "v3": "Número: opcional, valor de azul o brillo",
            +        "color": "Number[]|String|p5.Color: color Array, or CSS color string"
            +      }
            +    },
            +    "shininess": {
            +      "description": [
            +        "Sets the amount of gloss in the surface of shapes. Used in combination with specularMaterial() in setting the material properties of shapes. The default and minimum value is 1."
            +      ],
            +      "params": {
            +        "shine": "Number: Degree of Shininess.  Defaults to 1."
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "Define la posición de la cámara",
            +        "This function simulates the movements of the camera, allowing objects to be viewed from various angles. Remember, it does not move the objects themselves but the camera instead. For example when the centerX value is positive, and the camera is rotating to the right side of the sketch, the object will seem like it's moving to the left.",
            +        "See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a> to view the position of your camera.",
            +        "If no parameters are given, the following default is used: camera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)"
            +      ],
            +      "params": {
            +        "x": "Número: valor de la posición de la cámara en el eje x",
            +        "y": "Número: valor de la posición de la cámara en el eje y",
            +        "z": "Número: valor de la posición de la cámara en el eje z",
            +        "centerX": "Number: (Optional) x coordinate representing center of the sketch",
            +        "centerY": "Number: (Optional) y coordinate representing center of the sketch",
            +        "centerZ": "Number: (Optional) z coordinate representing center of the sketch",
            +        "upX": "Number: (Optional) x component of direction 'up' from camera",
            +        "upY": "Number: (Optional) y component of direction 'up' from camera",
            +        "upZ": "Number: (Optional) z component of direction 'up' from camera"
            +      }
            +    },
            +    "perspective": {
            +      "description": [
            +        "Define la perspectiva de la cámara",
            +        "The parameters to this function define the viewing frustum (the truncated pyramid within which objects are seen by the camera) through vertical field of view, aspect ratio (usually width/height), and near and far clipping planes.",
            +        "If no parameters are given, the following default is used: perspective(PI/3, width/height, eyeZ/10, eyeZ*10), where eyeZ is equal to ((height/2) / tan(PI/6))."
            +      ],
            +      "params": {
            +        "fovy": "Número: frustum del campo de visión vertical de la cámara, de abajo hacia arriba, en grados",
            +        "aspect": "Número: frustum de la relación de aspecto de la cámara",
            +        "near": "Número: frustum del largo del plano cercano",
            +        "far": "Número: frustum del largo del plano lejano"
            +      }
            +    },
            +    "ortho": {
            +      "description": [
            +        "Define la cámara ortogonal",
            +        "The parameters to this function specify the viewing frustum where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values.",
            +        "If no parameters are given, the following default is used: ortho(-width/2, width/2, -height/2, height/2)."
            +      ],
            +      "params": {
            +        "left": "Número: define el frustum del plano izquierdo de la cámara",
            +        "right": "Número: define el frustum del plano derecho de la cámara",
            +        "bottom": "Número: define el frustum del plano inferior de la cámara",
            +        "top": "Número: define el frustum del plano superior de la cámara",
            +        "near": "Número: define el frustum del plano cercano de la cámara",
            +        "far": "Número: define el frustum del plano lejano de la cámara"
            +      }
            +    },
            +    "frustum": {
            +      "description": [
            +        "Sets a perspective matrix as defined by the parameters.",
            +        "A frustum is a geometric form: a pyramid with its top cut off. With the viewer's eye at the imaginary top of the pyramid, the six planes of the frustum act as clipping planes when rendering a 3D view. Thus, any form inside the clipping planes is visible; anything outside those planes is not visible.",
            +        "Setting the frustum changes the perspective of the scene being rendered. This can be achieved more simply in many cases by using <a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.",
            +        "If no parameters are given, the following default is used: frustum(-width/2, width/2, -height/2, height/2, 0, max(width, height))."
            +      ],
            +      "params": {
            +        "left": "Number: (Optional) camera frustum left plane",
            +        "right": "Number: (Optional) camera frustum right plane",
            +        "bottom": "Number: (Optional) camera frustum bottom plane",
            +        "top": "Number: (Optional) camera frustum top plane",
            +        "near": "Number: (Optional) camera frustum near plane",
            +        "far": "Number: (Optional) camera frustum far plane"
            +      }
            +    },
            +    "createCamera": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and tells the renderer to use that camera. Returns the p5.Camera object.",
            +        "The new camera is initialized with a default position (see <a href=\"#/p5.Camera/camera\">camera()</a>) and a default perspective projection (see <a href=\"#/p5.Camera/perspective\">perspective()</a>). Its properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a> methods.",
            +        "Note: Every 3D sketch starts with a default camera initialized. This camera can be controlled with the global methods <a href=\"#/p5/camera\">camera()</a>, <a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>, and <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera in the scene."
            +      ],
            +      "returns": "p5.Camera: The newly created camera object."
            +    },
            +    "setCamera": {
            +      "description": [
            +        "Sets rendererGL's current camera to a p5.Camera object. Allows switching between multiple cameras."
            +      ],
            +      "params": {
            +        "cam": "p5.Camera: p5.Camera object"
            +      }
            +    },
            +    "setAttributes": {
            +      "description": [
            +        "Set attributes for the WebGL Drawing context. This is a way of adjusting how the WebGL renderer works to fine-tune the display and performance.",
            +        "Note that this will reinitialize the drawing context if called after the WebGL canvas is made.",
            +        "If an object is passed as the parameter, all attributes not declared in the object will be set to defaults.",
            +        "The available attributes are:  alpha - indicates if the canvas contains an alpha buffer default is true",
            +        "depth - indicates whether the drawing buffer has a depth buffer of at least 16 bits - default is true",
            +        "stencil - indicates whether the drawing buffer has a stencil buffer of at least 8 bits",
            +        "antialias - indicates whether or not to perform anti-aliasing default is false (true in Safari)",
            +        "premultipliedAlpha - indicates that the page compositor will assume the drawing buffer contains colors with pre-multiplied alpha default is false",
            +        "preserveDrawingBuffer - if true the buffers will not be cleared and and will preserve their values until cleared or overwritten by author (note that p5 clears automatically on draw loop) default is true",
            +        "perPixelLighting - if true, per-pixel lighting will be used in the lighting shader otherwise per-vertex lighting is used. default is true."
            +      ],
            +      "params": {
            +        "key": "String: Name of attribute",
            +        "value": "Boolean: New value of named attribute",
            +        "obj": "Object: object with key-value pairs"
            +      }
            +    },
            +    "getAudioContext": {
            +      "description": [
            +        "Returns the Audio Context for this sketch. Useful for users who would like to dig deeper into the <a target='_blank' href= 'http://webaudio.github.io/web-audio-api/'>Web Audio API </a>.",
            +        "Some browsers require users to startAudioContext with a user gesture, such as touchStarted in the example below."
            +      ],
            +      "returns": "Object: AudioContext for this sketch"
            +    },
            +    "userStartAudio": {
            +      "description": [
            +        "It is not only a good practice to give users control over starting audio. This policy is enforced by many web browsers, including iOS and <a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay policy\">Google Chrome</a>, which create the Web Audio API's <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\" title=\"Audio Context @ MDN\">Audio Context</a> in a suspended state.",
            +        "In these browser-specific policies, sound will not play until a user interaction event (i.e. <code>mousePressed()</code>) explicitly resumes the AudioContext, or starts an audio node. This can be accomplished by calling <code>start()</code> on a <code>p5.Oscillator</code>, <code> play()</code> on a <code>p5.SoundFile</code>, or simply <code>userStartAudio()</code>.",
            +        "<code>userStartAudio()</code> starts the AudioContext on a user gesture. The default behavior will enable audio on any mouseUp or touchEnd event. It can also be placed in a specific interaction function, such as <code>mousePressed()</code> as in the example below. This method utilizes <a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext </a>, a library by Yotam Mann (MIT Licence, 2016)."
            +      ],
            +      "returns": "Promise: Returns a Promise that resolves when  the AudioContext state is 'running'",
            +      "params": {
            +        "element(s)": "Element|Array: (Optional) This argument can be an Element,  Selector String, NodeList, p5.Element,  jQuery Element, or an Array of any of those.",
            +        "callback": "Function: (Optional) Callback to invoke when the AudioContext  has started"
            +      }
            +    },
            +    "getOutputVolume": {
            +      "description": [
            +        "Returns a number representing the output volume for sound in this sketch."
            +      ],
            +      "returns": "Number: Output volume for sound in this sketch.  Should be between 0.0 (silence) and 1.0."
            +    },
            +    "outputVolume": {
            +      "description": [
            +        "Scale the output of all sound in this sketch Scaled between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal.",
            +        "<b>How This Works</b>: When you load the p5.sound module, it creates a single instance of p5sound. All sound objects in this module output to p5sound before reaching your computer's output. So if you change the amplitude of p5sound, it impacts all of the sound in this module.",
            +        "If no value is provided, returns a Web Audio API Gain Node"
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "soundOut": {
            +      "description": [
            +        "<code>p5.soundOut</code> is the p5.sound final output bus. It sends output to the destination of this window's web audio context. It contains Web Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>), and Gain Nodes for <code>.input</code> and <code>.output</code>."
            +      ]
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Returns a number representing the sample rate, in samples per second, of all sound objects in this audio context. It is determined by the sampling rate of your operating system's sound card, and it is not currently possile to change. It is often 44100, or twice the range of human hearing."
            +      ],
            +      "returns": "Number: samplerate samples per second"
            +    },
            +    "freqToMidi": {
            +      "description": [
            +        "Returns the closest MIDI note value for a given frequency."
            +      ],
            +      "returns": "Number: MIDI note value",
            +      "params": {
            +        "frequency": "Number: A freqeuncy, for example, the \"A\"  above Middle C is 440Hz"
            +      }
            +    },
            +    "midiToFreq": {
            +      "description": [
            +        "Returns the frequency value of a MIDI note value. General MIDI treats notes as integers where middle C is 60, C# is 61, D is 62 etc. Useful for generating musical frequencies with oscillators."
            +      ],
            +      "returns": "Number: Frequency value of the given MIDI note",
            +      "params": {
            +        "midiNote": "Number: The number of a MIDI note"
            +      }
            +    },
            +    "soundFormats": {
            +      "description": [
            +        "List the SoundFile formats that you will include. LoadSound will search your directory for these extensions, and will pick a format that is compatable with the client's web browser. <a href=\"http://media.io/\">Here</a> is a free online file converter."
            +      ],
            +      "params": {
            +        "formats": "String: (Optional) i.e. 'mp3', 'wav', 'ogg'"
            +      }
            +    },
            +    "saveSound": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. For uploading audio to a server, use <a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile that you wish to save",
            +        "fileName": "String: name of the resulting .wav file."
            +      }
            +    },
            +    "loadSound": {
            +      "description": [
            +        "loadSound() returns a new p5.SoundFile from a specified path. If called during preload(), the p5.SoundFile will be ready to play in time for setup() and draw(). If called outside of preload, the p5.SoundFile will not be ready immediately, so loadSound accepts a callback as the second parameter. Using a <a href=\"https://github.com/processing/p5.js/wiki/Local-server\"> local server</a> is recommended when loading external files."
            +      ],
            +      "returns": "SoundFile: Returns a p5.SoundFile",
            +      "params": {
            +        "path": "String|Array: Path to the sound file, or an array with  paths to soundfiles in multiple formats  i.e. ['sound.ogg', 'sound.mp3'].  Alternately, accepts an object: either  from the HTML5 File API, or a p5.File.",
            +        "successCallback": "Function: (Optional) Name of a function to call once file loads",
            +        "errorCallback": "Function: (Optional) Name of a function to call if there is  an error loading the file.",
            +        "whileLoading": "Function: (Optional) Name of a function to call while file is loading.  This function will receive the percentage loaded  so far, from 0.0 to 1.0."
            +      }
            +    },
            +    "createConvolver": {
            +      "description": [
            +        "Create a p5.Convolver. Accepts a path to a soundfile that will be used to generate an impulse response."
            +      ],
            +      "returns": "p5.Convolver:",
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: (Optional) function to call if loading is successful.  The object will be passed in as the argument  to the callback function.",
            +        "errorCallback": "Function: (Optional) function to call if loading is not successful.  A custom error will be passed in as the argument  to the callback function."
            +      }
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the global tempo, in beats per minute, for all p5.Parts. This method will impact all active p5.Parts."
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.Color": {
            +    "description": [
            +      "Cada color almacena el modo de color y los niveles máximos que se aplicaron en el momento de su construcción. Estos se utilizan para interpretar los argumentos de entrada (en la construcción y más tarde para esa instancia de color) y para formatear el output, p. ej. cuando se solicita la <a href=\"#/p5/saturation\">saturation()</a>.",
            +      "Internamente almacenamos una matriz que representa los valores ideales de RGBA en forma de coma flotante, normalizada de 0 a 1. A partir de esto, calculamos el color de pantalla más cercano (niveles de RGBA de 0 a 255) y lo exponemos al renderizador.",
            +      "También almacenamos en caché normalizado, componentes de coma flotante de color flotante del color en varias representaciones a medida que se calculan. Esto se hace para evitar repetir una conversión que ya se ha realizado."
            +    ],
            +    "setRed": {
            +      "description": [
            +        "La función setRed establece el componente rojo de un color. El rango depende de su modo de color, en el modo RGB predeterminado está entre 0 y 255."
            +      ],
            +      "params": {
            +        "red": "Number: the new red value"
            +      }
            +    },
            +    "setGreen": {
            +      "description": [
            +        "La función setGreen establece el componente verde de un color. El rango depende de su modo de color, en el modo RGB predeterminado está entre 0 y 255."
            +      ],
            +      "params": {
            +        "green": "Number: the new green value"
            +      }
            +    },
            +    "setBlue": {
            +      "description": [
            +        "La función setBlue establece el componente azul de un color. El rango depende de su modo de color, en el modo RGB predeterminado está entre 0 y 255."
            +      ],
            +      "params": {
            +        "blue": "Number: the new blue value"
            +      }
            +    },
            +    "setAlpha": {
            +      "description": [
            +        "La función setAlpha establece el valor de transparencia (alfa) de un color. El rango depende de su modo de color, en el modo RGB predeterminado está entre 0 y 255."
            +      ],
            +      "params": {
            +        "alpha": "Number: the new alpha value"
            +      }
            +    }
            +  },
            +  "p5.Element": {
            +    "description": [
            +      "Clase base para todos los elementos añadidos al bosuqejo, incluyendo lienzo, buffers de gráficas, y otros elementos HTML. Los métodos en azul están incluidos en la funcionalidad base, los métodos en marrón son añadidos con la biblioteca p5.dom. No se ejecutan directamente, pero los objetos p5.Element son creados llamando a las funciones createCanvas(), createGraphics(), o en la biblioteca p5.dom, createDiv, createImg, createInput, etc."
            +    ],
            +    "params": {
            +      "elt": "String: node DOM envolvente.",
            +      "pInst": "Objeto: puntero a instancia p5."
            +    },
            +    "elt": {
            +      "description": [
            +        "Underlying HTML element. All normal HTML methods can be called on this."
            +      ]
            +    },
            +    "parent": {
            +      "description": [
            +        "Attaches the element to the parent specified. A way of setting  the container for the element. Accepts either a string ID, DOM  node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.  For more ways to position the canvas, see the  <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>  positioning the canvas</a> wiki page."
            +      ],
            +      "params": {
            +        "parent": "String|p5.Element|Object: the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>  of desired parent element"
            +      }
            +    },
            +    "id": {
            +      "description": [
            +        "Sets the ID of the element. If no ID argument is passed in, it instead  returns the current ID of the element.  Note that only one element can have a particular id in a page.  The <a href=\"#/p5.Element/class\">.class()</a> function can be used  to identify multiple elements with the same class name."
            +      ],
            +      "params": {
            +        "id": "String: ID of the element"
            +      }
            +    },
            +    "class": {
            +      "description": [
            +        "Adds given class to the element. If no class argument is passed in, it  instead returns a string containing the current class(es) of the element."
            +      ],
            +      "params": {
            +        "class": "String: class to add"
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called once after every time a mouse button is pressed over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  pressed over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a mouse button is pressed twice over the element. This can be used to attach element and action specific event listeners."
            +      ],
            +      "returns": "p5.Element:",
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  double clicked over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners.",
            +        "The function accepts a callback function as argument which will be executed when the <code>wheel</code> event is triggered on the element, the callback function is passed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code> except it reads the horizontal wheel scroll of the mouse wheel.",
            +        "On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are reversed."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  scrolled over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is called once after every time a mouse button is released over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  released over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is called once after a mouse button is pressed and released over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap.This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  clicked over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a mouse moves over the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse moves  over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseOver": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a mouse moves onto the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse moves  onto the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseOut": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a mouse moves off the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse  moves off of an element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch  starts over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch moves over  the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch ends  over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "dragOver": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a file is dragged over the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a file is  dragged over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "dragLeave": {
            +      "description": [
            +        "The .dragLeave() function is called once after every time a dragged file leaves the element area. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a file is  dragged off the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "addClass": {
            +      "description": [
            +        "Adds specified class to the element."
            +      ],
            +      "params": {
            +        "class": "String: name of class to add"
            +      }
            +    },
            +    "removeClass": {
            +      "description": [
            +        "Removes specified class from the element."
            +      ],
            +      "params": {
            +        "class": "String: name of class to remove"
            +      }
            +    },
            +    "hasClass": {
            +      "description": [
            +        "Checks if specified class already set to element"
            +      ],
            +      "returns": "Boolean: a boolean value if element has specified class",
            +      "params": {
            +        "c": "String: class name of class to check"
            +      }
            +    },
            +    "toggleClass": {
            +      "description": [
            +        "Toggles element class"
            +      ],
            +      "params": {
            +        "c": "String: class name to toggle"
            +      }
            +    },
            +    "child": {
            +      "description": [
            +        "Attaches the element as a child to the parent specified.  Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.  If no argument is specified, an array of children DOM nodes is returned."
            +      ],
            +      "returns": "Node[]: an array of child nodes",
            +      "params": {
            +        "child": "String|p5.Element: (Optional) the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>  to add to the current element"
            +      }
            +    },
            +    "center": {
            +      "description": [
            +        "Centers a p5 Element either vertically, horizontally, or both, relative to its parent or according to the body if the Element has no parent. If no argument is passed the Element is aligned both vertically and horizontally."
            +      ],
            +      "params": {
            +        "align": "String: (Optional) passing 'vertical', 'horizontal' aligns element accordingly"
            +      }
            +    },
            +    "html": {
            +      "description": [
            +        "If an argument is given, sets the inner HTML of the element,  replacing any existing html. If true is included as a second  argument, html is appended instead of replacing existing html.  If no arguments are given, returns  the inner HTML of the element."
            +      ],
            +      "returns": "String: the inner HTML of the element",
            +      "params": {
            +        "html": "String: (Optional) the HTML to be placed inside the element",
            +        "append": "Boolean: (Optional) whether to append HTML to existing"
            +      }
            +    },
            +    "position": {
            +      "description": [
            +        "Sets the position of the element. If no position type argument is given, the  position will be relative to (0, 0) of the window.  Essentially, this sets position:absolute and left and top  properties of style. If an optional third argument specifying position type is given,  the x and y coordinates will be interpreted based on the <a target=\"_blank\"  href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.  If no arguments given, the function returns the x and y position of the element. found documentation on how to be more specific with object type  <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a>"
            +      ],
            +      "returns": "Object: object of form { x: 0, y: 0 } containing the position of the element in an object",
            +      "params": {
            +        "x": "Number: (Optional) x-position relative to upper left of window (optional)",
            +        "y": "Number: (Optional) y-position relative to upper left of window (optional)",
            +        "positionType": "String: it can be static, fixed, relative, sticky, initial or inherit (optional)"
            +      }
            +    },
            +    "style": {
            +      "description": [
            +        "Sets the given style (css) property (1st arg) of the element with the given value (2nd arg). If a single argument is given, .style() returns the value of the given property; however, if the single argument is given in css syntax ('text-align:center'), .style() sets the css appropriately."
            +      ],
            +      "returns": "String: value of property",
            +      "params": {
            +        "property": "String: property to be set",
            +        "value": "String|p5.Color: value to assign to property"
            +      }
            +    },
            +    "attribute": {
            +      "description": [
            +        "Adds a new attribute or changes the value of an existing attribute  on the specified element. If no value is specified, returns the  value of the given attribute, or null if attribute is not set."
            +      ],
            +      "returns": "String: value of attribute",
            +      "params": {
            +        "attr": "String: attribute to set",
            +        "value": "String: value to assign to attribute"
            +      }
            +    },
            +    "removeAttribute": {
            +      "description": [
            +        "Removes an attribute on the specified element."
            +      ],
            +      "params": {
            +        "attr": "String: attribute to remove"
            +      }
            +    },
            +    "value": {
            +      "description": [
            +        "Either returns the value of the element if no arguments given, or sets the value of the element."
            +      ],
            +      "returns": "String|Number: value of the element",
            +      "params": {
            +        "value": "String|Number"
            +      }
            +    },
            +    "show": {
            +      "description": [
            +        "Shows the current element. Essentially, setting display:block for the style."
            +      ]
            +    },
            +    "hide": {
            +      "description": [
            +        "Hides the current element. Essentially, setting display:none for the style."
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "Sets the width and height of the element. AUTO can be used to  only adjust one dimension at a time. If no arguments are given, it  returns the width and height of the element in an object. In case of  elements which need to be loaded, such as images, it is recommended  to call the function after the element has finished loading."
            +      ],
            +      "returns": "Object: the width and height of the element in an object",
            +      "params": {
            +        "w": "Number|Constant: width of the element, either AUTO, or a number",
            +        "h": "Number|Constant: (Optional) height of the element, either AUTO, or a number"
            +      }
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the element, stops all media streams, and deregisters all listeners."
            +      ]
            +    },
            +    "drop": {
            +      "description": [
            +        "Registers a callback that gets called every time a file that is dropped on the element has been loaded. p5 will load every dropped file into memory and pass it as a p5.File object to the callback. Multiple files dropped at the same time will result in multiple calls to the callback.",
            +        "You can optionally pass a second callback which will be registered to the raw <a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event. The callback will thus be provided the original <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>. Dropping multiple files at the same time will trigger the second callback once per drop, whereas the first callback will trigger for each loaded file."
            +      ],
            +      "params": {
            +        "callback": "Function: callback to receive loaded file, called for each file dropped.",
            +        "fxn": "Function: (Optional) callback triggered once when files are dropped with the drop event."
            +      }
            +    }
            +  },
            +  "p5.Graphics": {
            +    "description": [
            +      "Contenedor fino alrededor de un renderizador, que se utilizará para crear un objeto de búfer de gráficos. Use esta clase si necesita dibujar en un búfer de gráficos fuera de la pantalla. Los dos parámetros definen el ancho y el alto en píxeles. Los campos y métodos para esta clase son extensos, pero reflejan la API de dibujo normal para p5."
            +    ],
            +    "params": {
            +      "w": "Número: ancho",
            +      "h": "Número: altura",
            +      "renderer": "Constant: renderer el renderizador a utilizar, ya sea P2D o WEBGL",
            +      "pInst": "P5: pointer a una instancia p5 (Opcional)"
            +    },
            +    "reset": {
            +      "description": [
            +        "Restablece ciertos valores, como los modificados por funciones en la categoría Transformar y en la categoría Luces que no se restablecen automáticamente con objetos gráficos de búfer. Llamando a esto en <a href='#/p5/draw'>draw()</a> copiará el comportamiento del canvas estándar."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Elimina un objeto Graphics de la página y libera todos los recursos asociados con él."
            +      ]
            +    }
            +  },
            +  "p5.Renderer": {
            +    "description": [
            +      "Main graphics and rendering context, as well as the base API implementation for p5.js \"core\". To be used as the superclass for Renderer2D and Renderer3D classes, respectively."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped",
            +      "pInst": "P5: (Optional) pointer to p5 instance",
            +      "isMainCanvas": "Boolean: (Optional) whether we're using it as main canvas"
            +    }
            +  },
            +  "JSON": {
            +    "stringify": {
            +      "description": [
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>: The JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>."
            +      ],
            +      "params": {
            +        "object": "Object: :Javascript object that you would like to convert to JSON"
            +      }
            +    }
            +  },
            +  "console": {
            +    "log": {
            +      "description": [
            +        "Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a> and <a href=\"#/p5/console/log\">console.log</a> interchangeably.",
            +        "The console is opened differently depending on which browser you are using. Here are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a> , <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>, and <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>. With the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console is embedded directly in the page underneath the code editor.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>: The Console method log() outputs a message to the web console. The message may be a single <a href=\"#/p5/string\">string</a> (with optional substitution values), or it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>."
            +      ],
            +      "params": {
            +        "message": "String|Expression|Object: :Message that you would like to print to the console"
            +      }
            +    }
            +  },
            +  "p5.TypedDict": {
            +    "description": [
            +      "Base class for all p5.Dictionary types. Specifically  typed Dictionary classes inherit from this class."
            +    ],
            +    "size": {
            +      "description": [
            +        "Returns the number of key-value pairs currently stored in the Dictionary."
            +      ],
            +      "returns": "Integer: the number of key-value pairs in the Dictionary"
            +    },
            +    "hasKey": {
            +      "description": [
            +        "Returns true if the given key exists in the Dictionary, otherwise returns false."
            +      ],
            +      "returns": "Boolean: whether that key exists in Dictionary",
            +      "params": {
            +        "key": "Number|String: that you want to look up"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Returns the value stored at the given key."
            +      ],
            +      "returns": "Number|String: the value stored at that key",
            +      "params": {
            +        "the": "Number|String: key you want to access"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Updates the value associated with the given key in case it already exists in the Dictionary. Otherwise a new key-value pair is added."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String"
            +      }
            +    },
            +    "create": {
            +      "description": [
            +        "Creates a new key-value pair in the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String",
            +        "obj": "Object: key/value pair"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Removes all previously stored key-value pairs from the Dictionary."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the key-value pair stored at the given key from the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String: for the pair to remove"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Logs the set of items currently stored in the Dictionary to the console."
            +      ]
            +    },
            +    "saveTable": {
            +      "description": [
            +        "Converts the Dictionary into a CSV file for local download."
            +      ]
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "Converts the Dictionary into a JSON file for local download."
            +      ]
            +    }
            +  },
            +  "p5.StringDict": {
            +    "description": [
            +      "A simple Dictionary class for Strings."
            +    ]
            +  },
            +  "p5.NumberDict": {
            +    "description": [
            +      "Una simple clase de Diccionario para Números."
            +    ],
            +    "add": {
            +      "description": [
            +        "Agregue el número dado al valor actualmente almacenado en la clave dada. La suma luego reemplaza el valor previamente almacenado en el Diccionario."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to add to",
            +        "Number": "Number: to add to the value"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtract the given number from the value currently stored at the given key. The difference then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to subtract from",
            +        "Number": "Number: to subtract from the value"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Resta el número dado del valor actualmente almacenado en la clave dada. La diferencia luego reemplaza el valor previamente almacenado en el Diccionario."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to multiply",
            +        "Amount": "Number: to multiply the value by"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Divida el número dado con el valor actualmente almacenado en la clave dada. El cociente luego reemplaza el valor previamente almacenado en el Diccionario."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to divide",
            +        "Amount": "Number: to divide the value by"
            +      }
            +    },
            +    "minValue": {
            +      "description": [
            +        "Devuelve el número más bajo actualmente almacenado en el Diccionario."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "maxValue": {
            +      "description": [
            +        "Devuelve el número más alto actualmente almacenado en el Diccionario."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "minKey": {
            +      "description": [
            +        "Devuelve la clave más baja utilizada actualmente en el Diccionario."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "maxKey": {
            +      "description": [
            +        "Devuelve la clave más alta utilizada actualmente en el Diccionario."
            +      ],
            +      "returns": "Number:"
            +    }
            +  },
            +  "p5.MediaElement": {
            +    "description": [
            +      "Extiende <a href=\"#/p5.Element\">p5.Element</a> para manejar audio y video. Además de los métodos de <a href=\"#/p5.Element\">p5.Element</a>, también contiene métodos para controlar los medios. No se llama directamente, pero <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s se crea llamando a <a href=\"#/p5/createVideo\">createVideo</a>, <a href=\"#/p5/createAudio\">createAudio</a> y <a href=\"#/p5/createCapture\">createCapture</a>."
            +    ],
            +    "params": {
            +      "elt": "String: nodo DOM que está envuelto"
            +    },
            +    "src": {
            +      "description": [
            +        "Ruta a la fuente del elemento multimedia."
            +      ],
            +      "returns": "String: src"
            +    },
            +    "play": {
            +      "description": [
            +        "Reproduce un elemento multimedia HTML5."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Detiene un elemento multimedia HTML5 (establece la hora actual en cero)"
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pausa un elemento multimedia HTML5."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Establezca 'loop' en verdadero para un elemento multimedia HTML5 y comienza a reproducir."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Set 'loop' to false for an HTML5 media element. Element will stop when it reaches the end."
            +      ]
            +    },
            +    "autoplay": {
            +      "description": [
            +        "Establezca 'loop' en falso para un elemento multimedia HTML5. El elemento se detendrá cuando llegue al final."
            +      ],
            +      "params": {
            +        "shouldAutoplay": "Boolean: whether the element should autoplay"
            +      }
            +    },
            +    "volume": {
            +      "description": [
            +        "Establece el volumen para este elemento multimedia HTML5. Si no se proporciona ningún argumento, devuelve el volumen actual."
            +      ],
            +      "returns": "Number: current volume",
            +      "params": {
            +        "val": "Number: volume between 0.0 and 1.0"
            +      }
            +    },
            +    "speed": {
            +      "description": [
            +        "Si no se dan argumentos, devuelve la velocidad de reproducción actual del elemento. El parámetro de velocidad establece la velocidad donde 2.0 reproducirá el elemento dos veces más rápido, 0.5 reproducirá a la mitad de la velocidad y -1 reproducirá el elemento a velocidad normal en reversa (tenga en cuenta que no todos los navegadores admiten la reproducción hacia atrás e incluso si lo hacen, la reproducción podría no ser fluido.)"
            +      ],
            +      "returns": "Number: current playback speed of the element",
            +      "params": {
            +        "speed": "Number: speed multiplier for element playback"
            +      }
            +    },
            +    "time": {
            +      "description": [
            +        "Si no se dan argumentos, devuelve la hora actual del elemento. Si se proporciona un argumento, la hora actual del elemento se establece a la indicada."
            +      ],
            +      "returns": "Number: current time (in seconds)",
            +      "params": {
            +        "time": "Number: time to jump to (in seconds)"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Devuelve la duración del elemento multimedia HTML5."
            +      ],
            +      "returns": "Number: duration"
            +    },
            +    "onended": {
            +      "description": [
            +        "Programe un evento para ser llamado cuando el elemento de audio o video llegue al final. Si el elemento está looping, esto no se llamará. El elemento se pasa como argumento para el onended callback."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended. The  media element will be passed  in as the argument to the  callback."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Envíe la salida de audio de este elemento a un objeto audioNode o p5.sound especificado. Si no se proporciona ningún elemento, se conecta a la salida maestra de p5. Esa conexión se establece cuando este método se llama por primera vez. Todas las conexiones se eliminan mediante el método .disconnect ().",
            +        "Este método está destinado a ser utilizado con la biblioteca de complementos p5.sound.js."
            +      ],
            +      "params": {
            +        "audioNode": "AudioNode|Object: AudioNode from the Web Audio API, or an object from the p5.sound library"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Desconecta todo el enrutamiento de audio web, incluso a la salida maestra. Esto es útil si desea redirigir la salida a través de efectos de audio, por ejemplo."
            +      ]
            +    },
            +    "showControls": {
            +      "description": [
            +        "Muestra los controles de MediaElement predeterminados, según lo determine el navegador web."
            +      ]
            +    },
            +    "hideControls": {
            +      "description": [
            +        "Ocultar los controles predeterminados de mediaElement."
            +      ]
            +    },
            +    "addCue": {
            +      "description": [
            +        "Programe eventos para que se activen cada vez que un MediaElement (audio / video) llegue a un punto de referencia de reproducción.",
            +        "Acepta una función de devolución de llamada, un tiempo (en segundos) para activar el callback y un parámetro opcional para el callback.",
            +        "El tiempo pasará como primer parámetro a la función de callback, y param será el segundo parámetro."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Eliminar una devolución de llamada en función de su ID. La identificación es devuelta por el método addCue."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Elimine todos los callbacks que originalmente se habían programado mediante el método addCue."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    }
            +  },
            +  "p5.File": {
            +    "description": [
            +      "Base class for a file. Used for Element.drop and createFileInput."
            +    ],
            +    "params": {
            +      "file": "File: File that is wrapped"
            +    },
            +    "file": {
            +      "description": [
            +        "Underlying File object. All normal File methods can be called on this."
            +      ]
            +    },
            +    "type": {
            +      "description": [
            +        "File type (image, text, etc.)"
            +      ]
            +    },
            +    "subtype": {
            +      "description": [
            +        "File subtype (usually the file extension jpg, png, xml, etc.)"
            +      ]
            +    },
            +    "name": {
            +      "description": [
            +        "File name"
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "File size"
            +      ]
            +    },
            +    "data": {
            +      "description": [
            +        "URL string containing either image data, the text contents of the file or a parsed object if file is JSON and p5.XML if XML"
            +      ]
            +    }
            +  },
            +  "p5.Image": {
            +    "description": [
            +      "Crea un nuevo <a href=\"#/p5.Image\">p5.Image</a>. Un <a href=\"#/p5.Image\">p5.Image</a> es una representación de una imagen respaldada por un canvas.",
            +      "p5 puede mostrar imágenes .gif, .jpg y .png. Las imágenes pueden mostrarse en espacio 2D y 3D. Antes de usar una imagen, debe cargarse con la función <a href=\"#/p5/loadImage\">loadImage()</a>. La clase <a href=\"#/p5.Image\">p5.Image</a> contiene campos para el ancho y alto de la imagen, así como una matriz llamada <a href=\"#/p5.Image/pixels\">pixels[]</a> que contiene los valores para cada píxel en la imagen.",
            +      "Los métodos descritos a continuación permiten un fácil acceso a los píxeles de la imagen y al canal alfa y simplifican el proceso de composición.",
            +      "Antes de usar la matriz de <a href=\"#/p5.Image/pixels\">pixels[]</a>, asegúrese de usar el método <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> en la imagen para asegurarse de que los datos de píxeles estén cargados correctamente."
            +    ],
            +    "params": {
            +      "width": "Número de ancho:",
            +      "height": "Número de altura:"
            +    },
            +    "width": {
            +      "description": [
            +        "Ancho de la imagen."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "Altura de imagen."
            +      ]
            +    },
            +    "pixels": {
            +      "description": [
            +        "Matriz que contiene los valores para todos los píxeles en la ventana de visualización. Estos valores son números. Esta matriz es el tamaño (incluya un factor apropiado para la densidad de píxeles) de la ventana de visualización x4, que representa los valores R, G, B, A en orden para cada píxel, moviéndose de izquierda a derecha a través de cada fila, luego hacia abajo en cada columna. La retina y otras pantallas de alta densidad pueden tener más píxeles (por un factor de densidad de píxeles ^ 2). Por ejemplo, si la imagen es de 100x100 píxeles, habrá 40,000. Con pixelDensity = 2, habrá 160,000. Los primeros cuatro valores (índices 0-3) en la matriz serán los valores R, G, B, A del píxel en (0, 0). Los segundos cuatro valores (índices 4-7) contendrán los valores R, G, B, A del píxel en (1, 0). Más generalmente, para establecer valores para un píxel en (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre>",
            +        "Antes de acceder a esta matriz, los datos deben cargarse con la función <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>. Después de que se hayan modificado los datos de la matriz, se debe ejecutar la función <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> para actualizar los cambios."
            +      ]
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "Carga los datos de píxeles para esta imagen en el atributo [píxeles]."
            +      ]
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "Actualiza el canvas de respaldo para esta imagen con el contenido de la matriz [píxeles].",
            +        "Si esta imagen es un GIF animado, los píxeles se actualizarán en el cuadro que se muestra actualmente"
            +      ],
            +      "params": {
            +        "x": "Integer: x-offset of the target update area for the  underlying canvas",
            +        "y": "Integer: y-offset of the target update area for the  underlying canvas",
            +        "w": "Integer: height of the target update area for the  underlying canvas",
            +        "h": "Integer: height of the target update area for the  underlying canvas"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Obtiene una región de píxeles de una imagen.",
            +        "Si no se pasan parámetros, se devuelve toda la imagen. Si x e y son los únicos parámetros pasados, se extrae un solo píxel. Si se pasan todos los parámetros, se extrae una región rectangular y se devuelve un <a href=\"#/p5.Image\">p5.Image</a>."
            +      ],
            +      "returns": "p5.Image: the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "w": "Number: width",
            +        "h": "Number: height"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Establece el color de un solo píxel o escribe una imagen en este <a href=\"#/p5.Image\">p5.Image</a>.",
            +        "Tenga en cuenta que para una gran cantidad de píxeles esto será más lento que manipular directamente la matriz de píxeles y luego llamar a <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "a": "Number|Number[]|Object: grayscale value | pixel array |  a <a href=\"#/p5.Color\">p5.Color</a> | image to copy"
            +      }
            +    },
            +    "resize": {
            +      "description": [
            +        "Cambiar el tamaño de la imagen a un nuevo ancho y alto. Para hacer que la imagen escale proporcionalmente, use 0 como valor para el parámetro ancho o alto. Por ejemplo, para hacer que el ancho de una imagen sea de 150 píxeles y cambiar la altura con la misma proporción, use cambiar el tamaño (150, 0)."
            +      ],
            +      "params": {
            +        "width": "Number: the resized image width",
            +        "height": "Number: the resized image height"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Copia una región de píxeles de una imagen a otra. Si no se especifica srcImage, se usa como fuente. Si las regiones de origen y destino no son del mismo tamaño, automáticamente redimensionará los píxeles de origen para que se ajusten a la región de destino especificada."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5.Element: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height"
            +      }
            +    },
            +    "mask": {
            +      "description": [
            +        "Enmascara parte de una imagen para que no se muestre cargando otra imagen y usando su canal alfa como canal alfa para esta imagen."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Aplica un filtro de imagen a un <a href=\"#/p5.Image\">p5.Image</a>",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used.",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used.",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used.",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges.",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur.",
            +        "ERODE Reduces the light areas. No parameter is used.",
            +        "DILATE Increases the light areas. No parameter is used.",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "Constant: either THRESHOLD, GRAY, OPAQUE, INVERT,  POSTERIZE, BLUR, ERODE, DILATE or BLUR.  See Filters.js for docs on  each available filter",
            +        "filterParam": "Number: (Optional) an optional parameter unique  to each filter, see above"
            +      }
            +    },
            +    "blend": {
            +      "description": [
            +        "Copia una región de píxeles de una imagen a otra, utilizando un modo de blend específico para realizar la operación."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height",
            +        "blendMode": "Constant: the blend mode. either  BLEND, DARKEST, LIGHTEST, DIFFERENCE,  MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD or NORMAL. Available blend modes are: normal | multiply | screen | overlay |  darken | lighten | color-dodge | color-burn | hard-light |  soft-light | difference | exclusion | hue | saturation |  color | luminosity <a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a>"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "Guarda la imagen en un archivo y obliga al navegador a descargarla. Acepta dos cadenas para nombre de archivo y extensión de archivo Admite png (predeterminado), jpg y gif  Tenga en cuenta que el archivo solo se descargará como un GIF animado si la p5.Image se cargó desde un archivo GIF."
            +      ],
            +      "params": {
            +        "filename": "String: give your file a name",
            +        "extension": "String: 'png' or 'jpg'"
            +      }
            +    },
            +    "reset": {
            +      "description": [
            +        "Inicia un GIF animado en el estado inicial."
            +      ]
            +    },
            +    "getCurrentFrame": {
            +      "description": [
            +        "Obtiene el índice del marco que está visible actualmente en un GIF animado."
            +      ],
            +      "returns": "Number: The index for the currently displaying frame in animated GIF"
            +    },
            +    "setFrame": {
            +      "description": [
            +        "Establece el índice del marco que está visible actualmente en un GIF animado"
            +      ],
            +      "params": {
            +        "index": "Number: the index for the frame that should be displayed"
            +      }
            +    },
            +    "numFrames": {
            +      "description": [
            +        "Devuelve el número de fotogramas en un GIF animado"
            +      ],
            +      "returns": "Number:"
            +    },
            +    "play": {
            +      "description": [
            +        "Reproduce un GIF animado que se detuvo con <a href=\"#/p5.Image/pause\">pause()</a>"
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pausa un GIF animado."
            +      ]
            +    },
            +    "delay": {
            +      "description": [
            +        "Cambia el retraso entre fotogramas en un GIF animado. Hay un segundo parámetro opcional que indica un índice para una trama específica que debería tener su retraso modificado. Si no se proporciona ningún índice, todos los cuadros tendrán el nuevo retraso."
            +      ],
            +      "params": {
            +        "d": "Number: the amount in milliseconds to delay between switching frames",
            +        "index": "Number: (Optional) the index of the frame that should have the new delay value {optional}"
            +      }
            +    }
            +  },
            +  "p5.PrintWriter": {
            +    "params": {
            +      "filename": "String",
            +      "extension": "String (Optional)"
            +    },
            +    "write": {
            +      "description": [
            +        "Writes data to the PrintWriter stream"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be written by the PrintWriter"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Writes data to the PrintWriter stream, and adds a new line at the end"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be printed by the PrintWriter"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Clears the data already written to the PrintWriter object"
            +      ]
            +    },
            +    "close": {
            +      "description": [
            +        "Closes the PrintWriter"
            +      ]
            +    }
            +  },
            +  "p5.Table": {
            +    "description": [
            +      "Los objetos Table almacenan datos con múltiples filas y columnas, tal como una hoja de cálculo tradicional. Los objetos Table pueden ser generados desde cero, dinámicamente, o usando datos desde un archivo existente."
            +    ],
            +    "params": {
            +      "rows": "Arreglo: un arreglo de objetos p5.TableRow"
            +    },
            +    "columns": {
            +      "description": [
            +        "Una matriz que contiene los nombres de las columnas en la tabla, si el \"header\" la tabla se carga con el parámetro \"header\"."
            +      ]
            +    },
            +    "rows": {
            +      "description": [
            +        "Una matriz que contiene los objetos <a href=\"#/p5.Table\">p5.TableRow</a> que forman las filas de la tabla. El mismo resultado que llamar <a href=\"#/p5/getRows\">getRows()</a>"
            +      ]
            +    },
            +    "addRow": {
            +      "description": [
            +        "Use <a href=\"#/p5/addRow\">addRow()</a> para agregar una nueva fila de datos a un objeto <a href=\"#/p5.Table\">p5.Table</a>. Por defecto, se crea una fila vacía. Por lo general, almacenaría una referencia a la nueva fila en un objeto TableRow (consulte newRow en el ejemplo anterior) y luego establecería valores individuales usando <a href=\"#/p5/set\">set()</a>.",
            +        "Si se incluye un objeto <a href=\"#/p5.TableRow\">p5.TableRow</a> como parámetro, entonces esa fila se duplica y se agrega a la tabla."
            +      ],
            +      "returns": "p5.TableRow: the row that was added",
            +      "params": {
            +        "row": "p5.TableRow: (Optional) row to be added to the table"
            +      }
            +    },
            +    "removeRow": {
            +      "description": [
            +        "Elimina una fila del objeto de tabla."
            +      ],
            +      "params": {
            +        "id": "Integer: ID number of the row to remove"
            +      }
            +    },
            +    "getRow": {
            +      "description": [
            +        "Devuelve una referencia al <a href=\"#/p5.TableRow\">p5.TableRow</a> especificado. La referencia se puede utilizar para obtener y establecer valores de la fila seleccionada."
            +      ],
            +      "returns": "p5.TableRow: <a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +      "params": {
            +        "rowID": "Integer: ID number of the row to get"
            +      }
            +    },
            +    "getRows": {
            +      "description": [
            +        "Obtiene todas las filas de la tabla. Devuelve una matriz de <a href=\"#/p5.TableRow\">p5.TableRow</a>s."
            +      ],
            +      "returns": "p5.TableRow[]: Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s"
            +    },
            +    "findRow": {
            +      "description": [
            +        "Encuentra la primera fila de la tabla que contiene el valor proporcionado y devuelve una referencia a esa fila. Incluso si varias filas son posibles coincidencias, solo se devuelve la primera fila coincidente. La columna a buscar puede especificarse por su ID o título."
            +      ],
            +      "returns": "p5.TableRow:",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "findRows": {
            +      "description": [
            +        "Encuentra las filas en la tabla que contienen el valor proporcionado y devuelve referencias a esas filas. Devuelve una matriz, por lo que debe usarse para recorrer en iteración todas las filas, como se muestra en el ejemplo anterior. La columna a buscar puede especificarse por su ID o título."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "matchRow": {
            +      "description": [
            +        "Encuentra la primera fila de la tabla que coincide con la expresión regular proporcionada y devuelve una referencia a esa fila. Incluso si varias filas son posibles coincidencias, solo se devuelve la primera fila coincidente. La columna a buscar puede especificarse por su ID o título."
            +      ],
            +      "returns": "p5.TableRow: TableRow object",
            +      "params": {
            +        "regexp": "String|RegExp: The regular expression to match",
            +        "column": "String|Integer: The column ID (number) or  title (string)"
            +      }
            +    },
            +    "matchRows": {
            +      "description": [
            +        "Encuentra las filas en la tabla que coinciden con la expresión regular proporcionada y devuelve referencias a esas filas. Devuelve una matriz, por lo que debe usarse para recorrer en iteración todas las filas, como se muestra en el ejemplo. La columna a buscar puede especificarse por su ID o título."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "regexp": "String: The regular expression to match",
            +        "column": "String|Integer: (Optional) The column ID (number) or  title (string)"
            +      }
            +    },
            +    "getColumn": {
            +      "description": [
            +        "Recupera todos los valores en la columna especificada y los devuelve como una matriz. La columna se puede especificar por su ID o título."
            +      ],
            +      "returns": "Array: Array of column values",
            +      "params": {
            +        "column": "String|Number: String or Number of the column to return"
            +      }
            +    },
            +    "clearRows": {
            +      "description": [
            +        "Elimina todas las filas de una tabla. Mientras se eliminan todas las filas, se mantienen las columnas y los títulos de las columnas."
            +      ]
            +    },
            +    "addColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/addColumn\">addColumn()</a> para agregar una nueva columna a un objeto <a href=\"#/p5.Table\">Table</a>. Por lo general, querrá especificar un título, por lo que la columna puede ser referenciada fácilmente más tarde por su nombre. (Si no se especifica ningún título, el título de la nueva columna será nulo)."
            +      ],
            +      "params": {
            +        "title": "String: (Optional) title of the given column"
            +      }
            +    },
            +    "getColumnCount": {
            +      "description": [
            +        "Devuelve el número total de columnas en una tabla."
            +      ],
            +      "returns": "Integer: Number of columns in this table"
            +    },
            +    "getRowCount": {
            +      "description": [
            +        "Devuelve el número total de filas en una tabla."
            +      ],
            +      "returns": "Integer: Number of rows in this table"
            +    },
            +    "removeTokens": {
            +      "description": [
            +        "Elimina cualquiera de los caracteres especificados (o \"tokens\").",
            +        "Si no se especifica ninguna columna, se procesan los valores en todas las columnas y filas. Se puede hacer referencia a una columna específica por su ID o título."
            +      ],
            +      "params": {
            +        "chars": "String: String listing characters to be removed",
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "Recorta los espacios en blanco iniciales y finales, como los espacios y las pestañas, a partir de los valores de la tabla de cadenas. Si no se especifica ninguna columna, los valores en todas las columnas y filas se recortan. Se puede hacer referencia a una columna específica por su ID o título."
            +      ],
            +      "params": {
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "removeColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/removeColumn\">removeColumn()</a> para eliminar una columna existente de un objeto Table. La columna que se eliminará puede identificarse por su título (una Cadena) o su valor de índice (un int). removeColumn (0) eliminaría la primera columna, removeColumn (1) eliminaría la segunda columna, y así sucesivamente."
            +      ],
            +      "params": {
            +        "column": "String|Integer: columnName (string) or ID (number)"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Almacena un valor en la fila y columna especificadas de la tabla. La fila se especifica por su ID, mientras que la columna se puede especificar por su ID o título."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String|Number: value to assign"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Almacena un valor flotante en la fila y columna especificadas de la tabla. La fila se especifica por su ID, mientras que la columna se puede especificar por su ID o título."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "Number: value to assign"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Almacena un valor de cadena en la fila y columna especificadas de la tabla. La fila se especifica por su ID, mientras que la columna se puede especificar por su ID o título."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String: value to assign"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Recupera un valor de la fila y columna especificadas en la Tabla. La fila se especifica por su ID, mientras que la columna se puede especificar por su ID o título."
            +      ],
            +      "returns": "String|Number:",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Recupera un valor flotante de la fila y columna especificadas en la tabla. La fila se especifica por su ID, mientras que la columna se puede especificar por su ID o título."
            +      ],
            +      "returns": "Number:",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Recupera un valor de cadena de la fila y columna especificadas en la tabla. La fila se especifica por su ID, mientras que la columna se puede especificar por su ID o título."
            +      ],
            +      "returns": "String:",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getObject": {
            +      "description": [
            +        "Recupera todos los datos de la tabla y los devuelve como un objeto. Si se pasa un nombre de columna, cada objeto de fila se almacenará con ese atributo como título."
            +      ],
            +      "returns": "Object:",
            +      "params": {
            +        "headerColumn": "String: (Optional) Name of the column which should be used to  title each row object (optional)"
            +      }
            +    },
            +    "getArray": {
            +      "description": [
            +        "Recupera todos los datos de la tabla y los devuelve como una matriz multidimensional."
            +      ],
            +      "returns": "Array:"
            +    }
            +  },
            +  "p5.TableRow": {
            +    "description": [
            +      "Un objeto TableRow representa una única fila de datos, grabados en columnas, de una tabla. Un objeto TableRow contiene tanto un arreglo ordenado, como un objeto JSON desordenado.",
            +      "A Table Row contains both an ordered array, and an unordered JSON object."
            +    ],
            +    "params": {
            +      "str": "String: opcional, puebla la fila con una serie de valores, separados por el separador",
            +      "separator": "String: por defecto, valores separados por coma (csv)"
            +    },
            +    "set": {
            +      "description": [
            +        "Stores a value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number: The value to be stored"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Stores a Float value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "Number|String: The value to be stored  as a Float"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Stores a String value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number|Boolean|Object: The value to be stored  as a String"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retrieves a value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String|Number:",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Retrieves a Float value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "Number: Float Floating point number",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Retrieves an String value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String: String",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    }
            +  },
            +  "p5.XML": {
            +    "description": [
            +      "XML es una representación de un objeto XML, capaz de procesar código XML. Usa loadXML() para cargar archivos externos XML y crear objetos XML"
            +    ],
            +    "getParent": {
            +      "description": [
            +        "Gets a copy of the element's parent. Returns the parent as another <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "returns": "p5.XML: element parent"
            +    },
            +    "getName": {
            +      "description": [
            +        "Gets the element's full name, which is returned as a String."
            +      ],
            +      "returns": "String: the name of the node"
            +    },
            +    "setName": {
            +      "description": [
            +        "Sets the element's name, which is specified as a String."
            +      ],
            +      "params": {
            +        "the": "String: new name of the node"
            +      }
            +    },
            +    "hasChildren": {
            +      "description": [
            +        "Checks whether or not the element has any children, and returns the result as a boolean."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "listChildren": {
            +      "description": [
            +        "Get the names of all of the element's children, and returns the names as an array of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a> on each child element individually."
            +      ],
            +      "returns": "String[]: names of the children of the element"
            +    },
            +    "getChildren": {
            +      "description": [
            +        "Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When the name parameter is specified, then it will return all children that match that name."
            +      ],
            +      "returns": "p5.XML[]: children of the element",
            +      "params": {
            +        "name": "String: (Optional) element name"
            +      }
            +    },
            +    "getChild": {
            +      "description": [
            +        "Returns the first of the element's children that matches the name parameter or the child of the given index.It returns undefined if no matching child is found."
            +      ],
            +      "returns": "p5.XML:",
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "addChild": {
            +      "description": [
            +        "Appends a new child to the element. The child can be specified with either a String, which will be used as the new tag's name, or as a reference to an existing <a href=\"#/p5.XML\">p5.XML</a> object. A reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "params": {
            +        "node": "p5.XML: a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added"
            +      }
            +    },
            +    "removeChild": {
            +      "description": [
            +        "Removes the element specified by name or index."
            +      ],
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "getAttributeCount": {
            +      "description": [
            +        "Counts the specified element's number of attributes, returned as an Number."
            +      ],
            +      "returns": "Integer:"
            +    },
            +    "listAttributes": {
            +      "description": [
            +        "Gets all of the specified element's attributes, and returns them as an array of Strings."
            +      ],
            +      "returns": "String[]: an array of strings containing the names of attributes"
            +    },
            +    "hasAttribute": {
            +      "description": [
            +        "Checks whether or not an element has the specified attribute."
            +      ],
            +      "returns": "Boolean: true if attribute found else false",
            +      "params": {
            +        "the": "String: attribute to be checked"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Returns an attribute value of the element as an Number. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, the value 0 is returned."
            +      ],
            +      "returns": "Number:",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Returns an attribute value of the element as an String. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, null is returned."
            +      ],
            +      "returns": "String:",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "setAttribute": {
            +      "description": [
            +        "Sets the content of an element's attribute. The first parameter specifies the attribute name, while the second specifies the new content."
            +      ],
            +      "params": {
            +        "name": "String: the full name of the attribute",
            +        "value": "Number|String|Boolean: the value of the attribute"
            +      }
            +    },
            +    "getContent": {
            +      "description": [
            +        "Returns the content of an element. If there is no such content, defaultValue is returned if specified, otherwise null is returned."
            +      ],
            +      "returns": "String:",
            +      "params": {
            +        "defaultValue": "String: (Optional) value returned if no content is found"
            +      }
            +    },
            +    "setContent": {
            +      "description": [
            +        "Sets the element's content."
            +      ],
            +      "params": {
            +        "text": "String: the new content"
            +      }
            +    },
            +    "serialize": {
            +      "description": [
            +        "Serializes the element into a string. This function is useful for preparing the content to be sent over a http request or saved to file."
            +      ],
            +      "returns": "String: Serialized string of the element"
            +    }
            +  },
            +  "p5.Vector": {
            +    "description": [
            +      "Una clase para describir un vector de dos o tres dimensiones, específicamente un vector euclideano (también conocido como geométrico). Un vector es una entidad que tiene tanto magnitud como dirección. El tipo de datos, sin embargo, graba los componentes del vector (x, y para 2D y x,y,z para 3D). La magnitud y la dirección pueden ser calculados con los métodos mag() y heading(). En muchos de los ejemplos de p5.js, verás que p5.Vector es usado para describir una posición, velocidad o aceleración. Por ejemplo, si consideras un rectángulo moviéndose a lo largo de la pantalla, en cada instante tiene una posición (un vector que apunta desde el origen hasta su ubicación), una velocidad(la tasa a la que la posición del objeto cambia por unidad de tiempo, expresada como vector), y aceleración (la tasa a la que la velocidad del objeto cambia por unidad de tiempo, expresada como vector). Como los vectores representan grupos de valores, no podemos simplemente usar las operaciones tradicionales de adición, multiplicación, etc. En vez de eso, necesitaremos hacer matemática de vectores, lo que es simplificado con los métodos dentro de la clase p5.Vector.",
            +      "In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a position, velocity, or acceleration. For example, if you consider a rectangle moving across the screen, at any given instant it has a position (a vector that points from the origin to its location), a velocity (the rate at which the object's position changes per time unit, expressed as a vector), and acceleration (the rate at which the object's velocity changes per time unit, expressed as a vector).",
            +      "Since vectors represent groupings of values, we cannot simply use traditional addition/multiplication/etc. Instead, we'll need to do some \"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class."
            +    ],
            +    "params": {
            +      "x": "Número: componente x del vector",
            +      "y": "Número: componente y del vector",
            +      "z": "Número: componente z del vector"
            +    },
            +    "x": {
            +      "description": [
            +        "The x component of the vector"
            +      ]
            +    },
            +    "y": {
            +      "description": [
            +        "The y component of the vector"
            +      ]
            +    },
            +    "z": {
            +      "description": [
            +        "The z component of the vector"
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Sets the x, y, and z component of the vector using two or three separate variables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array."
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) the x component of the vector",
            +        "y": "Number: (Optional) the y component of the vector",
            +        "z": "Number: (Optional) the z component of the vector",
            +        "value": "p5.Vector|Number[]: the vector to set"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object."
            +      ],
            +      "returns": "p5.Vector: the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    },
            +    "add": {
            +      "description": [
            +        "Adds x, y, and z components to a vector, adds one vector to another, or adds two independent vectors together. The version of the method that adds two vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to be added",
            +        "y": "Number: (Optional) the y component of the vector to be added",
            +        "z": "Number: (Optional) the z component of the vector to be added",
            +        "value": "p5.Vector|Number[]: the vector to add",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "rem": {
            +      "description": [
            +        "Gives remainder of a vector when it is divided by another vector. See examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of divisor vector",
            +        "y": "Number: the y component of divisor vector",
            +        "z": "Number: the z component of divisor vector",
            +        "value": "p5.Vector | Number[]: divisor vector",
            +        "v1": "p5.Vector: dividend <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: divisor <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtracts x, y, and z components from a vector, subtracts one vector from another, or subtracts two independent vectors. The version of the method that subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the other acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to subtract",
            +        "y": "Number: (Optional) the y component of the vector to subtract",
            +        "z": "Number: (Optional) the z component of the vector to subtract",
            +        "value": "p5.Vector|Number[]: the vector to subtract",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies the x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y, and z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector, the x, y, z components of both vectors are multiplied by each other (for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method creates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "n": "Number: The number to multiply with the vector",
            +        "x": "Number: The number to multiply with the x component of the vector",
            +        "y": "Number: The number to multiply with the y component of the vector",
            +        "z": "Number: (Optional) The number to multiply with the z component of the vector",
            +        "arr": "Number[]: The array to multiply with the components of the vector",
            +        "v": "p5.Vector: The vector to multiply with the components of the original vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and z components of two vectors against each other. When dividing a vector by a scalar, the x, y, and z components of the vector are all divided by the scalar. When dividing a vector by a vector, the x, y, z components of the source vector are treated as the dividend, and the x, y, z components of the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z). The static version of this method creates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "n": "Number: The number to divide the vector by",
            +        "x": "Number: The number to divide with the x component of the vector",
            +        "y": "Number: The number to divide with the y component of the vector",
            +        "z": "Number: (Optional) The number to divide with the z component of the vector",
            +        "arr": "Number[]: The array to divide the components of the vector by",
            +        "v": "p5.Vector: The vector to divide the components of the original vector by",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "Calculates the magnitude (length) of the vector and returns the result as a float (this is simply the equation sqrt(x*x + y*y + z*z).)"
            +      ],
            +      "returns": "Number: magnitude of the vector",
            +      "params": {
            +        "vecT": "p5.Vector: the vector to return the magnitude of"
            +      }
            +    },
            +    "magSq": {
            +      "description": [
            +        "Calculates the squared magnitude of the vector and returns the result as a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.) Faster if the real length is not required in the case of comparing vectors, etc."
            +      ],
            +      "returns": "Number: squared magnitude of the vector"
            +    },
            +    "dot": {
            +      "description": [
            +        "Calculates the dot product of two vectors. The version of the method that computes the dot product of two independent vectors is a static method. See the examples for more context."
            +      ],
            +      "returns": "Number: the dot product",
            +      "params": {
            +        "x": "Number: x component of the vector",
            +        "y": "Number: (Optional) y component of the vector",
            +        "z": "Number: (Optional) z component of the vector",
            +        "value": "p5.Vector: value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "cross": {
            +      "description": [
            +        "Calculates and returns a vector composed of the cross product between two vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>. See the examples for more context."
            +      ],
            +      "returns": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +      "params": {
            +        "v": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> to be crossed",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "Calculates the Euclidean distance between two points (considering a point as a vector object)."
            +      ],
            +      "returns": "Number: the distance",
            +      "params": {
            +        "v": "p5.Vector: the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "normalize": {
            +      "description": [
            +        "Normalize the vector to length 1 (make it a unit vector)."
            +      ],
            +      "returns": "p5.Vector: normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +      "params": {
            +        "v": "p5.Vector: the vector to normalize",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "limit": {
            +      "description": [
            +        "Limit the magnitude of this vector to the value used for the <b>max</b> parameter."
            +      ],
            +      "params": {
            +        "max": "Number: the maximum magnitude for the vector"
            +      }
            +    },
            +    "setMag": {
            +      "description": [
            +        "Set the magnitude of this vector to the value used for the <b>len</b> parameter."
            +      ],
            +      "params": {
            +        "len": "Number: the new length for this vector"
            +      }
            +    },
            +    "heading": {
            +      "description": [
            +        "Calculate the angle of rotation for this vector(only 2D vectors). p5.Vectors created using <a src=\"#/p5/createVector\">createVector()</a> will take the current <a = src=\"#/p5/angleMode\">angleMode</a> into consideration, and give the angle in radians or degree accordingly."
            +      ],
            +      "returns": "Number: the angle of rotation"
            +    },
            +    "setHeading": {
            +      "description": [
            +        "Rotate the vector to a specific angle (only 2D vectors), magnitude remains the same"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation"
            +      }
            +    },
            +    "rotate": {
            +      "description": [
            +        "Rotate the vector by an angle (only 2D vectors), magnitude remains the same"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation",
            +        "v": "p5.Vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "angleBetween": {
            +      "description": [
            +        "Calculates and returns the angle (in radians) between two vectors."
            +      ],
            +      "returns": "Number: the angle between (in radians)",
            +      "params": {
            +        "value": "p5.Vector: the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "Linear interpolate the vector to another vector"
            +      ],
            +      "params": {
            +        "x": "Number: the x component",
            +        "y": "Number: the y component",
            +        "z": "Number: the z component",
            +        "amt": "Number: the amount of interpolation; some value between 0.0  (old vector) and 1.0 (new vector). 0.9 is very near  the new vector. 0.5 is halfway in between.",
            +        "v": "p5.Vector: the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to",
            +        "v1": "p5.Vector",
            +        "v2": "p5.Vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "reflect": {
            +      "description": [
            +        "Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D This method acts on the vector directly"
            +      ],
            +      "params": {
            +        "surfaceNormal": "p5.Vector: the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method"
            +      }
            +    },
            +    "array": {
            +      "description": [
            +        "Return a representation of this vector as a float array. This is only for temporary use. If used in any other fashion, the contents should be copied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own array."
            +      ],
            +      "returns": "Number[]: an Array with the 3 values"
            +    },
            +    "equals": {
            +      "description": [
            +        "Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      ],
            +      "returns": "Boolean: whether the vectors are equals",
            +      "params": {
            +        "x": "Number: (Optional) the x component of the vector",
            +        "y": "Number: (Optional) the y component of the vector",
            +        "z": "Number: (Optional) the z component of the vector",
            +        "value": "p5.Vector|Array: the vector to compare"
            +      }
            +    },
            +    "fromAngle": {
            +      "description": [
            +        "Make a new 2D vector from an angle"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +      "params": {
            +        "angle": "Number: the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)",
            +        "length": "Number: (Optional) the length of the new vector (defaults to 1)"
            +      }
            +    },
            +    "fromAngles": {
            +      "description": [
            +        "Make a new 3D vector from a pair of ISO spherical angles"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +      "params": {
            +        "theta": "Number: the polar angle, in radians (zero is up)",
            +        "phi": "Number: the azimuthal angle, in radians  (zero is out of the screen)",
            +        "length": "Number: (Optional) the length of the new vector (defaults to 1)"
            +      }
            +    },
            +    "random2D": {
            +      "description": [
            +        "Make a new 2D unit vector from a random angle"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    },
            +    "random3D": {
            +      "description": [
            +        "Make a new random 3D unit vector."
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    }
            +  },
            +  "p5.Font": {
            +    "description": [
            +      "Clase base para manipulación de tipografía"
            +    ],
            +    "params": {
            +      "pInst": "Objeto: puntero a la instancia p5"
            +    },
            +    "font": {
            +      "description": [
            +        "Underlying opentype font implementation"
            +      ]
            +    },
            +    "textBounds": {
            +      "description": [
            +        "Returns a tight bounding box for the given text string using this font"
            +      ],
            +      "returns": "Object: a rectangle object with properties: x, y, w, h",
            +      "params": {
            +        "line": "String: a line of text",
            +        "x": "Number: x-position",
            +        "y": "Number: y-position",
            +        "fontSize": "Number: (Optional) font size to use (optional) Default is 12.",
            +        "options": "Object: (Optional) opentype options (optional)  opentype fonts contains alignment and baseline options.  Default is 'LEFT' and 'alphabetic'"
            +      }
            +    },
            +    "textToPoints": {
            +      "description": [
            +        "Computes an array of points following the path for specified text"
            +      ],
            +      "returns": "Array: an array of points, each with x, y, alpha (the path angle)",
            +      "params": {
            +        "txt": "String: a line of text",
            +        "x": "Number: x-position",
            +        "y": "Number: y-position",
            +        "fontSize": "Number: font size to use (optional)",
            +        "options": "Object: (Optional) an (optional) object that can contain: sampleFactor - the ratio of path-length to number of samples (default=.1); higher values yield more points and are therefore more precise simplifyThreshold - if set to a non-zero value, collinear points will be be removed from the polygon; the value represents the threshold angle to use when determining whether two edges are collinear"
            +      }
            +    }
            +  },
            +  "p5.Camera": {
            +    "description": [
            +      "This class describes a camera for use in p5's <a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\"> WebGL mode</a>. It contains camera position, orientation, and projection information necessary for rendering a 3D scene.",
            +      "New p5.Camera objects can be made through the <a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through the methods described below. A camera created in this way will use a default position in the scene and a default perspective projection until these properties are changed through the various methods available. It is possible to create multiple cameras, in which case the current camera can be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.",
            +      "Note: The methods below operate in two coordinate systems: the 'world' coordinate system describe positions in terms of their relationship to the origin along the X, Y and Z axes whereas the camera's 'local' coordinate system describes positions from the camera's point of view: left-right, up-down, and forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method, for instance, moves the camera along its own axes, whereas the <a href=\"#/p5.Camera/setPosition\">setPosition()</a> method sets the camera's position in world-space.",
            +      "The camera object propreties <code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code> which describes camera position, orientation, and projection are also accessible via the camera object generated using <a href=\"#/p5/createCamera\">createCamera()</a>"
            +    ],
            +    "params": {
            +      "rendererGL": "RendererGL: instance of WebGL renderer"
            +    },
            +    "eyeX": {
            +      "description": [
            +        "camera position value on x axis"
            +      ]
            +    },
            +    "eyeY": {
            +      "description": [
            +        "camera position value on y axis"
            +      ]
            +    },
            +    "eyeZ": {
            +      "description": [
            +        "camera position value on z axis"
            +      ]
            +    },
            +    "centerX": {
            +      "description": [
            +        "x coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerY": {
            +      "description": [
            +        "y coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerZ": {
            +      "description": [
            +        "z coordinate representing center of the sketch"
            +      ]
            +    },
            +    "upX": {
            +      "description": [
            +        "x component of direction 'up' from camera"
            +      ]
            +    },
            +    "upY": {
            +      "description": [
            +        "y component of direction 'up' from camera"
            +      ]
            +    },
            +    "upZ": {
            +      "description": [
            +        "z component of direction 'up' from camera"
            +      ]
            +    },
            +    "perspective": {
            +      "description": [
            +        "Sets a perspective projection for a p5.Camera object and sets parameters for that projection according to <a href=\"#/p5/perspective\">perspective()</a> syntax."
            +      ]
            +    },
            +    "ortho": {
            +      "description": [
            +        "Sets an orthographic projection for a p5.Camera object and sets parameters for that projection according to <a href=\"#/p5/ortho\">ortho()</a> syntax."
            +      ]
            +    },
            +    "frustum": {
            +      "description": [
            +        "Sets the camera's frustum. Accepts the same parameters as the global <a href=\"#/p5/frustum\">frustum()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Panning rotates the camera view to the left and right."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "tilt": {
            +      "description": [
            +        "Tilting rotates the camera view up and down."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "lookAt": {
            +      "description": [
            +        "Reorients the camera to look at a position in world space."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "Sets a camera's position and orientation. This is equivalent to calling <a href=\"#/p5/camera\">camera()</a> on a p5.Camera object."
            +      ]
            +    },
            +    "move": {
            +      "description": [
            +        "Move camera along its local axes while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: amount to move along camera's left-right axis",
            +        "y": "Number: amount to move along camera's up-down axis",
            +        "z": "Number: amount to move along camera's forward-backward axis"
            +      }
            +    },
            +    "setPosition": {
            +      "description": [
            +        "Set camera position in world-space while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    }
            +  },
            +  "p5.Geometry": {
            +    "description": [
            +      "p5 Geometry class"
            +    ],
            +    "params": {
            +      "detailX": "Integer: (Optional) number of vertices on horizontal surface",
            +      "detailY": "Integer: (Optional) number of vertices on horizontal surface",
            +      "callback": "Function: (Optional) function to call upon object instantiation."
            +    },
            +    "computeFaces": {
            +      "description": [
            +        "computes faces for geometry objects based on the vertices."
            +      ]
            +    },
            +    "computeNormals": {
            +      "description": [
            +        "computes smooth normals per vertex as an average of each face."
            +      ]
            +    },
            +    "averageNormals": {
            +      "description": [
            +        "Averages the vertex normals. Used in curved surfaces"
            +      ]
            +    },
            +    "averagePoleNormals": {
            +      "description": [
            +        "Averages pole normals. Used in spherical primitives"
            +      ]
            +    },
            +    "normalize": {
            +      "description": [
            +        "Modifies all vertices to be centered within the range -100 to 100."
            +      ]
            +    }
            +  },
            +  "p5.Shader": {
            +    "description": [
            +      "Clase Shader para el modo WEBGL"
            +    ],
            +    "params": {
            +      "renderer": "p5.RendererGL: una instancia de p5.RendererGL que servirá de contexto GL para este nuevo p5.Shader",
            +      "vertSrc": "String: código fuente para el vertex shader (en forma de string)",
            +      "fragSrc": "String: código fuente para el fragment shader (en forma de string)"
            +    },
            +    "setUniform": {
            +      "description": [
            +        "Wrapper de las funciones gl.uniform. Como almacenamos información de uniform en el shader, la podemos usar para revisar los datos provistos y llamar a la función apropiada."
            +      ],
            +      "params": {
            +        "uniformName": "String: the name of the uniform in the shader program",
            +        "data": "Object|Number|Boolean|Number[]: the data to be associated with that uniform; type varies (could be a single numerical value, array, matrix, or texture / sampler reference)"
            +      }
            +    }
            +  },
            +  "p5.sound": {},
            +  "p5.SoundFile": {
            +    "description": [
            +      "SoundFile object with a path to a file.",
            +      "The p5.SoundFile may not be available immediately because it loads the file information asynchronously.",
            +      "To do something with the sound as soon as it loads pass the name of a function as the second parameter.",
            +      "Only one file path is required. However, audio file formats (i.e. mp3, ogg, wav and m4a/aac) are not supported by all web browsers. If you want to ensure compatibility, instead of a single file path, you may include an Array of filepaths, and the browser will choose a format that works."
            +    ],
            +    "params": {
            +      "path": "String|Array: path to a sound file (String). Optionally,  you may include multiple file formats in  an array. Alternately, accepts an object  from the HTML5 File API, or a p5.File.",
            +      "successCallback": "Function: (Optional) Name of a function to call once file loads",
            +      "errorCallback": "Function: (Optional) Name of a function to call if file fails to  load. This function will receive an error or  XMLHttpRequest object with information  about what went wrong.",
            +      "whileLoadingCallback": "Function: (Optional) Name of a function to call while file  is loading. That function will  receive progress of the request to  load the sound file  (between 0 and 1) as its first  parameter. This progress  does not account for the additional  time needed to decode the audio data."
            +    },
            +    "isLoaded": {
            +      "description": [
            +        "Returns true if the sound file finished loading successfully."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "play": {
            +      "description": [
            +        "Play the p5.SoundFile"
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule playback to start (in seconds from now).",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) amplitude (volume)  of playback",
            +        "cueStart": "Number: (Optional) (optional) cue start time in seconds",
            +        "duration": "Number: (Optional) (optional) duration of playback in seconds"
            +      }
            +    },
            +    "playMode": {
            +      "description": [
            +        "p5.SoundFile has two play modes: <code>restart</code> and <code>sustain</code>. Play Mode determines what happens to a p5.SoundFile if it is triggered while in the middle of playback. In sustain mode, playback will continue simultaneous to the new playback. In restart mode, play() will stop playback and start over. With untilDone, a sound will play only if it's not already playing. Sustain is the default mode."
            +      ],
            +      "params": {
            +        "str": "String: 'restart' or 'sustain' or 'untilDone'"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses a file that is currently playing. If the file is not playing, then nothing will happen.",
            +        "After pausing, .play() will resume from the paused position. If p5.SoundFile had been set to loop before it was paused, it will continue to loop after it is unpaused with .play()."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop the p5.SoundFile. Accepts optional parameters to set the playback rate, playback volume, loopStart, loopEnd."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) playback volume",
            +        "cueLoopStart": "Number: (Optional) (optional) startTime in seconds",
            +        "duration": "Number: (Optional) (optional) loop duration in seconds"
            +      }
            +    },
            +    "setLoop": {
            +      "description": [
            +        "Set a p5.SoundFile's looping flag to true or false. If the sound is currently playing, this change will take effect when it reaches the end of the current playback."
            +      ],
            +      "params": {
            +        "Boolean": "Boolean: set looping to true or false"
            +      }
            +    },
            +    "isLooping": {
            +      "description": [
            +        "Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "isPlaying": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is playing, false if not (i.e. paused or stopped)."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "isPaused": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is paused, false if not (i.e. playing or stopped)."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop soundfile playback."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  in seconds from now"
            +      }
            +    },
            +    "pan": {
            +      "description": [
            +        "Set the stereo panning of a p5.sound object to a floating point number between -1.0 (left) and 1.0 (right). Default is 0.0 (center)."
            +      ],
            +      "params": {
            +        "panValue": "Number: (Optional) Set the stereo panner",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current stereo pan position (-1.0 to 1.0)"
            +      ],
            +      "returns": "Number: Returns the stereo pan setting of the Oscillator  as a number between -1.0 (left) and 1.0 (right).  0.0 is center and default."
            +    },
            +    "rate": {
            +      "description": [
            +        "Set the playback rate of a sound file. Will change the speed and the pitch. Values less than zero will reverse the audio buffer."
            +      ],
            +      "params": {
            +        "playbackRate": "Number: (Optional) Set the playback rate. 1.0 is normal,  .5 is half-speed, 2.0 is twice as fast.  Values less than zero play backwards."
            +      }
            +    },
            +    "setVolume": {
            +      "description": [
            +        "Multiply the output volume (amplitude) of a sound file between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal."
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of a sound file in seconds."
            +      ],
            +      "returns": "Number: The duration of the soundFile in seconds."
            +    },
            +    "currentTime": {
            +      "description": [
            +        "Return the current position of the p5.SoundFile playhead, in seconds. Time is relative to the normal buffer direction, so if <code>reverseBuffer</code> has been called, currentTime will count backwards."
            +      ],
            +      "returns": "Number: currentTime of the soundFile in seconds."
            +    },
            +    "jump": {
            +      "description": [
            +        "Move the playhead of a soundfile that is currently playing to a new position and a new duration, in seconds. If none are given, will reset the file to play entire duration from start to finish. To set the position of a soundfile that is not currently playing, use the <code>play</code> or <code>loop</code> methods."
            +      ],
            +      "params": {
            +        "cueTime": "Number: cueTime of the soundFile in seconds.",
            +        "duration": "Number: duration in seconds."
            +      }
            +    },
            +    "channels": {
            +      "description": [
            +        "Return the number of channels in a sound file. For example, Mono = 1, Stereo = 2."
            +      ],
            +      "returns": "Number: [channels]"
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Return the sample rate of the sound file."
            +      ],
            +      "returns": "Number: [sampleRate]"
            +    },
            +    "frames": {
            +      "description": [
            +        "Return the number of samples in a sound file. Equal to sampleRate * duration."
            +      ],
            +      "returns": "Number: [sampleCount]"
            +    },
            +    "getPeaks": {
            +      "description": [
            +        "Returns an array of amplitude peaks in a p5.SoundFile that can be used to draw a static waveform. Scans through the p5.SoundFile's audio buffer to find the greatest amplitudes. Accepts one parameter, 'length', which determines size of the array. Larger arrays result in more precise waveform visualizations.",
            +        "Inspired by Wavesurfer.js."
            +      ],
            +      "returns": "Float32Array: Array of peaks.",
            +      "params": {
            +        "length": "Number: (Optional) length is the size of the returned array.  Larger length results in more precision.  Defaults to 5*width of the browser window."
            +      }
            +    },
            +    "reverseBuffer": {
            +      "description": [
            +        "Reverses the p5.SoundFile's buffer source. Playback must be handled separately (see example)."
            +      ]
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the soundfile reaches the end of a buffer. If the soundfile is playing through once, this will be called when it ends. If it is looping, it will be called when stop is called."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connects the output of a p5sound object to input of another p5.sound object. For example, you may connect a p5.SoundFile to an FFT or an Effect. If no parameter is given, it will connect to the master output. Most p5sound objects connect to the master output when they are created."
            +      ],
            +      "params": {
            +        "object": "Object: (Optional) Audio object that accepts an input"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnects the output of this p5sound object."
            +      ]
            +    },
            +    "setPath": {
            +      "description": [
            +        "Reset the source for this SoundFile to a new path (URL)."
            +      ],
            +      "params": {
            +        "path": "String: path to audio file",
            +        "callback": "Function: Callback"
            +      }
            +    },
            +    "setBuffer": {
            +      "description": [
            +        "Replace the current Audio Buffer with a new Buffer."
            +      ],
            +      "params": {
            +        "buf": "Array: Array of Float32 Array(s). 2 Float32 Arrays  will create a stereo source. 1 will create  a mono source."
            +      }
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point.",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback.",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ]
            +    },
            +    "save": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. To upload a file to a server, see <a href=\"/docs/reference/#/p5.SoundFile/getBlob\">getBlob</a>"
            +      ],
            +      "params": {
            +        "fileName": "String: (Optional) name of the resulting .wav file."
            +      }
            +    },
            +    "getBlob": {
            +      "description": [
            +        "This method is useful for sending a SoundFile to a server. It returns the .wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at MDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\". A Blob is a file-like data object that can be uploaded to a server with an <a href=\"/docs/reference/#/p5/httpDo\">http</a> request. We'll use the <code>httpDo</code> options object to send a POST request with some specific options: we encode the request as <code>multipart/form-data</code>, and attach the blob as one of the form values using <code>FormData</code>."
            +      ],
            +      "returns": "Blob: A file-like data object"
            +    }
            +  },
            +  "p5.Amplitude": {
            +    "description": [
            +      "Amplitude measures volume between 0.0 and 1.0. Listens to all p5sound by default, or use setInput() to listen to a specific sound source. Accepts an optional smoothing value, which defaults to 0."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) between 0.0 and .999 to smooth  amplitude readings (defaults to 0)"
            +    },
            +    "setInput": {
            +      "description": [
            +        "Connects to the p5sound instance (master output) by default. Optionally, you can pass in a specific source (i.e. a soundfile)."
            +      ],
            +      "params": {
            +        "snd": "SoundObject|undefined: (Optional) set the sound source  (optional, defaults to  master output)",
            +        "smoothing": "Number|undefined: (Optional) a range between 0.0 and 1.0  to smooth amplitude readings"
            +      }
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Returns a single Amplitude reading at the moment it is called. For continuous readings, run in the draw loop."
            +      ],
            +      "returns": "Number: Amplitude as a number between 0.0 and 1.0",
            +      "params": {
            +        "channel": "Number: (Optional) Optionally return only channel 0 (left) or 1 (right)"
            +      }
            +    },
            +    "toggleNormalize": {
            +      "description": [
            +        "Determines whether the results of Amplitude.process() will be Normalized. To normalize, Amplitude finds the difference the loudest reading it has processed and the maximum amplitude of 1.0. Amplitude adds this difference to all values to produce results that will reliably map between 0.0 and 1.0. However, if a louder moment occurs, the amount that Normalize adds to all the values will change. Accepts an optional boolean parameter (true or false). Normalizing is off by default."
            +      ],
            +      "params": {
            +        "boolean": "Boolean: (Optional) set normalize to true (1) or false (0)"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth Amplitude analysis by averaging with the last analysis frame. Off by default."
            +      ],
            +      "params": {
            +        "set": "Number: smoothing from 0.0 <= 1"
            +      }
            +    }
            +  },
            +  "p5.FFT": {
            +    "description": [
            +      "FFT (Fast Fourier Transform) is an analysis algorithm that isolates individual <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\"> audio frequencies</a> within a waveform.",
            +      "Once instantiated, a p5.FFT object can return an array based on two types of analyses: • <code>FFT.waveform()</code> computes amplitude values along the time domain. The array indices correspond to samples across a brief moment in time. Each value represents amplitude of the waveform at that sample of time. • <code>FFT.analyze() </code> computes amplitude values along the frequency domain. The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Use with <code>getEnergy()</code> to measure amplitude at specific frequencies, or within a range of frequencies.",
            +      "FFT analyzes a very short snapshot of sound called a sample buffer. It returns an array of amplitude measurements, referred to as <code>bins</code>. The array is 1024 bins long by default. You can change the bin array length, but it must be a power of 2 between 16 and 1024 in order for the FFT algorithm to function correctly. The actual size of the FFT buffer is twice the number of bins, so given a standard sample rate, the buffer is 2048/44100 seconds long."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) Smooth results of Freq Spectrum.  0.0 < smoothing < 1.0.  Defaults to 0.8.",
            +      "bins": "Number: (Optional) Length of resulting array.  Must be a power of two between  16 and 1024. Defaults to 1024."
            +    },
            +    "setInput": {
            +      "description": [
            +        "Set the input source for the FFT analysis. If no source is provided, FFT will analyze all sound in the sketch."
            +      ],
            +      "params": {
            +        "source": "Object: (Optional) p5.sound object (or web audio API source node)"
            +      }
            +    },
            +    "waveform": {
            +      "description": [
            +        "Returns an array of amplitude values (between -1.0 and +1.0) that represent a snapshot of amplitude readings in a single buffer. Length will be equal to bins (defaults to 1024). Can be used to draw the waveform of a sound."
            +      ],
            +      "returns": "Array: Array Array of amplitude values (-1 to 1)  over time. Array length = bins.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "precision": "String: (Optional) If any value is provided, will return results  in a Float32 Array which is more precise  than a regular array."
            +      }
            +    },
            +    "analyze": {
            +      "description": [
            +        "Returns an array of amplitude values (between 0 and 255) across the frequency spectrum. Length is equal to FFT bins (1024 by default). The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Must be called prior to using <code>getEnergy()</code>."
            +      ],
            +      "returns": "Array: spectrum Array of energy (amplitude/volume)  values across the frequency spectrum.  Lowest energy (silence) = 0, highest  possible is 255.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "scale": "Number: (Optional) If \"dB,\" returns decibel  float measurements between  -140 and 0 (max).  Otherwise returns integers from 0-255."
            +      }
            +    },
            +    "getEnergy": {
            +      "description": [
            +        "Returns the amount of energy (volume) at a specific <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\"> frequency</a>, or the average amount of energy between two frequencies. Accepts Number(s) corresponding to frequency (in Hz), or a String corresponding to predefined frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\"). Returns a range between 0 (no energy/volume at that frequency) and 255 (maximum energy). <em>NOTE: analyze() must be called prior to getEnergy(). Analyze() tells the FFT to analyze frequency data, and getEnergy() uses the results determine the value at a specific frequency or range of frequencies.</em>"
            +      ],
            +      "returns": "Number: Energy Energy (volume/amplitude) from  0 and 255.",
            +      "params": {
            +        "frequency1": "Number|String: Will return a value representing  energy at this frequency. Alternately,  the strings \"bass\", \"lowMid\" \"mid\",  \"highMid\", and \"treble\" will return  predefined frequency ranges.",
            +        "frequency2": "Number: (Optional) If a second frequency is given,  will return average amount of  energy that exists between the  two frequencies."
            +      }
            +    },
            +    "getCentroid": {
            +      "description": [
            +        "Returns the <a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\"> spectral centroid</a> of the input signal. <em>NOTE: analyze() must be called prior to getCentroid(). Analyze() tells the FFT to analyze frequency data, and getCentroid() uses the results determine the spectral centroid.</em>"
            +      ],
            +      "returns": "Number: Spectral Centroid Frequency Frequency of the spectral centroid in Hz."
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth FFT analysis by averaging with the last analysis frame."
            +      ],
            +      "params": {
            +        "smoothing": "Number: 0.0 < smoothing < 1.0.  Defaults to 0.8."
            +      }
            +    },
            +    "linAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values for a given number of frequency bands split equally. N defaults to 16. <em>NOTE: analyze() must be called prior to linAverages(). Analyze() tells the FFT to analyze frequency data, and linAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: linearAverages Array of average amplitude values for each group",
            +      "params": {
            +        "N": "Number: Number of returned frequency groups"
            +      }
            +    },
            +    "logAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values of the spectrum, for a given set of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\"> Octave Bands</a> <em>NOTE: analyze() must be called prior to logAverages(). Analyze() tells the FFT to analyze frequency data, and logAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: logAverages Array of average amplitude values for each group",
            +      "params": {
            +        "octaveBands": "Array: Array of Octave Bands objects for grouping"
            +      }
            +    },
            +    "getOctaveBands": {
            +      "description": [
            +        "Calculates and Returns the 1/N <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a> N defaults to 3 and minimum central frequency to 15.625Hz. (1/3 Octave Bands ~= 31 Frequency Bands) Setting fCtr0 to a central value of a higher octave will ignore the lower bands and produce less frequency groups."
            +      ],
            +      "returns": "Array: octaveBands Array of octave band objects with their bounds",
            +      "params": {
            +        "N": "Number: Specifies the 1/N type of generated octave bands",
            +        "fCtr0": "Number: Minimum central frequency for the lowest band"
            +      }
            +    }
            +  },
            +  "p5.Oscillator": {
            +    "description": [
            +      "Creates a signal that oscillates between -1.0 and 1.0. By default, the oscillation takes the form of a sinusoidal shape ('sine'). Additional types include 'triangle', 'sawtooth' and 'square'. The frequency defaults to 440 oscillations per second (440Hz, equal to the pitch of an 'A' note).",
            +      "Set the type of oscillation with setType(), or by instantiating a specific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a href=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a href=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a href=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) frequency defaults to 440Hz",
            +      "type": "String: (Optional) type of oscillator. Options:  'sine' (default), 'triangle',  'sawtooth', 'square'"
            +    },
            +    "start": {
            +      "description": [
            +        "Start an oscillator.",
            +        "Starting an oscillator on a user gesture will enable audio in browsers that have a strict autoplay policy, including Chrome and most mobile devices. See also: <code>userStartAudio()</code>."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) startTime in seconds from now.",
            +        "frequency": "Number: (Optional) frequency in Hz."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop an oscillator. Accepts an optional parameter to determine how long (in seconds from now) until the oscillator stops."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: Time, in seconds from now."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the amplitude between 0 and 1.0. Or, pass in an object such as an oscillator to modulate amplitude with an audio signal."
            +      ],
            +      "returns": "AudioParam: gain If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's  gain/amplitude/volume)",
            +      "params": {
            +        "vol": "Number|Object: between 0 and 1.0  or a modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getAmp": {
            +      "description": [
            +        "Returns the value of output gain"
            +      ],
            +      "returns": "Number: Amplitude value between 0.0 and 1.0"
            +    },
            +    "freq": {
            +      "description": [
            +        "Set frequency of an oscillator to a value. Or, pass in an object such as an oscillator to modulate the frequency with an audio signal."
            +      ],
            +      "returns": "AudioParam: Frequency If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's frequency",
            +      "params": {
            +        "Frequency": "Number|Object: Frequency in Hz  or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Ramp time (in seconds)",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen  at x seconds from now"
            +      }
            +    },
            +    "getFreq": {
            +      "description": [
            +        "Returns the value of frequency of oscillator"
            +      ],
            +      "returns": "Number: Frequency of oscillator in Hertz"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type to 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "params": {
            +        "type": "String: 'sine', 'triangle', 'sawtooth' or 'square'."
            +      }
            +    },
            +    "getType": {
            +      "description": [
            +        "Returns current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "returns": "String: type of oscillator eg . 'sine', 'triangle', 'sawtooth' or 'square'."
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Pan between Left (-1) and Right (1)"
            +      ],
            +      "params": {
            +        "panning": "Number: Number between -1 and 1",
            +        "timeFromNow": "Number: schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current value of panPosition , between Left (-1) and Right (1)"
            +      ],
            +      "returns": "Number: panPosition of oscillator , between Left (-1) and Right (1)"
            +    },
            +    "phase": {
            +      "description": [
            +        "Set the phase of an oscillator between 0.0 and 1.0. In this implementation, phase is a delay time based on the oscillator's current frequency."
            +      ],
            +      "params": {
            +        "phase": "Number: float between 0.0 and 1.0"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Oscillator's output amplitude by a fixed value (i.e. turn it up!). Calling this method again will override the initial mult() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with multiplied output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this oscillator's amplitude values to a given range, and return the oscillator. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.SinOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SinOsc()</code>. This creates a Sine Wave Oscillator and is equivalent to <code> new p5.Oscillator('sine') </code> or creating a p5.Oscillator and then calling its method <code>setType('sine')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.TriOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.TriOsc()</code>. This creates a Triangle Wave Oscillator and is equivalent to <code>new p5.Oscillator('triangle') </code> or creating a p5.Oscillator and then calling its method <code>setType('triangle')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SawOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SawOsc()</code>. This creates a SawTooth Wave Oscillator and is equivalent to <code> new p5.Oscillator('sawtooth') </code> or creating a p5.Oscillator and then calling its method <code>setType('sawtooth')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SqrOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SqrOsc()</code>. This creates a Square Wave Oscillator and is equivalent to <code> new p5.Oscillator('square') </code> or creating a p5.Oscillator and then calling its method <code>setType('square')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.Envelope": {
            +    "description": [
            +      "Envelopes are pre-defined amplitude distribution over time. Typically, envelopes are used to control the output volume of an object, a series of fades referred to as Attack, Decay, Sustain and Release ( <a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a> ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can control an Oscillator's frequency like this: <code>osc.freq(env)</code>.",
            +      "Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level. Use <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.",
            +      "Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope, the <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger, or <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/ <code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff."
            +    ],
            +    "attackTime": {
            +      "description": [
            +        "Time until envelope reaches attackLevel"
            +      ]
            +    },
            +    "attackLevel": {
            +      "description": [
            +        "Level once attack is complete."
            +      ]
            +    },
            +    "decayTime": {
            +      "description": [
            +        "Time until envelope reaches decayLevel."
            +      ]
            +    },
            +    "decayLevel": {
            +      "description": [
            +        "Level after decay. The envelope will sustain here until it is released."
            +      ]
            +    },
            +    "releaseTime": {
            +      "description": [
            +        "Duration of the release portion of the envelope."
            +      ]
            +    },
            +    "releaseLevel": {
            +      "description": [
            +        "Level at the end of the release."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Reset the envelope with a series of time/value pairs."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds) before level  reaches attackLevel",
            +        "attackLevel": "Number: Typically an amplitude between  0.0 and 1.0",
            +        "decayTime": "Number: Time",
            +        "decayLevel": "Number: Amplitude (In a standard ADSR envelope,  decayLevel = sustainLevel)",
            +        "releaseTime": "Number: Release Time (in seconds)",
            +        "releaseLevel": "Number: Amplitude"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setRange": {
            +      "description": [
            +        "Set max (attackLevel) and min (releaseLevel) of envelope."
            +      ],
            +      "params": {
            +        "aLevel": "Number: attack level (defaults to 1)",
            +        "rLevel": "Number: release level (defaults to 0)"
            +      }
            +    },
            +    "setInput": {
            +      "description": [
            +        "Assign a parameter to be controlled by this envelope. If a p5.Sound object is given, then the p5.Envelope will control its output gain. If multiple inputs are provided, the env will control all of them."
            +      ],
            +      "params": {
            +        "inputs": "Object: (Optional) A p5.sound object or  Web Audio Param."
            +      }
            +    },
            +    "setExp": {
            +      "description": [
            +        "Set whether the envelope ramp is linear (default) or exponential. Exponential ramps can be useful because we perceive amplitude and frequency logarithmically."
            +      ],
            +      "params": {
            +        "isExp": "Boolean: true is exponential, false is linear"
            +      }
            +    },
            +    "play": {
            +      "description": [
            +        "Play tells the envelope to start acting on a given input. If the input is a p5.sound object (i.e. AudioIn, Oscillator, SoundFile), then Envelope will control its output volume. Envelopes can also be used to control any <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Audio Param.</a>"
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound object or  Web Audio Param.",
            +        "startTime": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go. Input can be any p5.sound object, or a <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Param</a>."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time from now (in seconds)"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the Release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "ramp": {
            +      "description": [
            +        "Exponentially ramp to a value using the first two values from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code> as <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\"> time constants</a> for simple exponential ramps. If the value is higher than current value, it uses attackTime, while a decrease uses decayTime."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: When to trigger the ramp",
            +        "v": "Number: Target value",
            +        "v2": "Number: (Optional) Second target value (optional)"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Envelope's output amplitude by a fixed value. Calling this method again will override the initial mult() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this envelope's amplitude values to a given range, and return the envelope. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.Noise": {
            +    "description": [
            +      "Noise is a type of oscillator that generates a buffer with random values."
            +    ],
            +    "params": {
            +      "type": "String: Type of noise can be 'white' (default),  'brown' or 'pink'."
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type of noise to 'white', 'pink' or 'brown'. White is the default."
            +      ],
            +      "params": {
            +        "type": "String: (Optional) 'white', 'pink' or 'brown'"
            +      }
            +    }
            +  },
            +  "p5.Pulse": {
            +    "description": [
            +      "Creates a Pulse object, an oscillator that implements Pulse Width Modulation. The pulse is created with two oscillators. Accepts a parameter for frequency, and to set the width between the pulses. See <a href=\" http://p5js.org/reference/#/p5.Oscillator\"> <code>p5.Oscillator</code> for a full list of methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Frequency in oscillations per second (Hz)",
            +      "w": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +    },
            +    "width": {
            +      "description": [
            +        "Set the width of a Pulse object (an oscillator that implements Pulse Width Modulation)."
            +      ],
            +      "params": {
            +        "width": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +      }
            +    }
            +  },
            +  "p5.AudioIn": {
            +    "description": [
            +      "Get audio from an input, i.e. your computer's microphone.",
            +      "Turn the mic on/off with the start() and stop() methods. When the mic is on, its volume can be measured with getLevel or by connecting an FFT object.",
            +      "If you want to hear the AudioIn, use the .connect() method. AudioIn does not connect to p5.sound output by default to prevent feedback.",
            +      "<em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/ Stream</a> API, which is not supported by certain browsers. Access in Chrome browser is limited to localhost and https, but access over http may be limited.</em>"
            +    ],
            +    "params": {
            +      "errorCallback": "Function: (Optional) A function to call if there is an error  accessing the AudioIn. For example,  Safari and iOS devices do not  currently allow microphone access."
            +    },
            +    "input": {},
            +    "output": {},
            +    "stream": {},
            +    "mediaStream": {},
            +    "currentSource": {},
            +    "enabled": {
            +      "description": [
            +        "Client must allow browser to access their microphone / audioin source. Default: false. Will become true when the client enables access."
            +      ]
            +    },
            +    "amplitude": {
            +      "description": [
            +        "Input amplitude, connect to it by default but not to master out"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start processing audio input. This enables the use of other AudioIn methods like getLevel(). Note that by default, AudioIn is not connected to p5.sound's output. So you won't hear anything unless you use the connect() method.<br/>",
            +        "Certain browsers limit access to the user's microphone. For example, Chrome only allows access from localhost and over https. For this reason, you may want to include an errorCallback—a function that is called in case the browser won't provide mic access."
            +      ],
            +      "params": {
            +        "successCallback": "Function: (Optional) Name of a function to call on  success.",
            +        "errorCallback": "Function: (Optional) Name of a function to call if  there was an error. For example,  some browsers do not support  getUserMedia."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel(). If re-starting, the user may be prompted for permission access."
            +      ]
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to an audio unit. If no parameter is provided, will connect to the master output (i.e. your speakers).<br/>"
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) An object that accepts audio input,  such as an FFT"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect the AudioIn from all audio units. For example, if connect() had been called, disconnect() will stop sending signal to your speakers.<br/>"
            +      ]
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Read the Amplitude (volume level) of an AudioIn. The AudioIn class contains its own instance of the Amplitude class to help make it easy to get a microphone's volume level. Accepts an optional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must .start() before using .getLevel().</em><br/>"
            +      ],
            +      "returns": "Number: Volume level (between 0.0 and 1.0)",
            +      "params": {
            +        "smoothing": "Number: (Optional) Smoothing is 0.0 by default.  Smooths values based on previous values."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set amplitude (volume) of a mic input between 0 and 1.0. <br/>"
            +      ],
            +      "params": {
            +        "vol": "Number: between 0 and 1.0",
            +        "time": "Number: (Optional) ramp time (optional)"
            +      }
            +    },
            +    "getSources": {
            +      "description": [
            +        "Returns a list of available input sources. This is a wrapper for <a title=\"MediaDevices.enumerateDevices() - Web APIs | MDN\" target=\"_blank\" href=  \"<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"\">https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"</a> <blockquote>"
            +      ],
            +      "returns": "Promise: Returns a Promise that can be used in place of the callbacks, similar  to the enumerateDevices() method",
            +      "params": {
            +        "successCallback": "Function: (Optional) This callback function handles the sources when they  have been enumerated. The callback function  receives the deviceList array as its only argument",
            +        "errorCallback": "Function: (Optional) This optional callback receives the error  message as its argument."
            +      }
            +    },
            +    "setSource": {
            +      "description": [
            +        "Set the input source. Accepts a number representing a position in the array returned by getSources(). This is only available in browsers that support <a title=\"MediaDevices.enumerateDevices() - Web APIs | MDN\" target=\"_blank\" href= \"<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"\">https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"</a> <blockquote>"
            +      ],
            +      "params": {
            +        "num": "Number: position of input source in the array"
            +      }
            +    }
            +  },
            +  "p5.Effect": {
            +    "description": [
            +      "Effect is a base class for audio effects in p5. This module handles the nodes and methods that are common and useful for current and future effects.",
            +      "This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>, <a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>, <a href=\"/reference/#/p5.Delay\">p5.Delay</a>, <a href=\"/reference/#/p5.Filter\">p5.Filter</a>, <a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>."
            +    ],
            +    "params": {
            +      "ac": "Object: (Optional) Reference to the audio context of the p5 object",
            +      "input": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "output": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "_drywet": "Object: (Optional) Tone.JS CrossFade node (defaults to value: 1)",
            +      "wet": "AudioNode: (Optional) Effects that extend this class should connect  to the wet signal to this gain node, so that dry and wet  signals are mixed properly."
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output volume of the filter."
            +      ],
            +      "params": {
            +        "vol": "Number: (Optional) amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts until rampTime",
            +        "tFromNow": "Number: (Optional) schedule this event to happen in tFromNow seconds"
            +      }
            +    },
            +    "chain": {
            +      "description": [
            +        "Link effects together in a chain Example usage: filter.chain(reverb, delay, panner); May be used with an open-ended number of arguments"
            +      ],
            +      "params": {
            +        "arguments": "Object: (Optional) Chain together multiple sound objects"
            +      }
            +    },
            +    "drywet": {
            +      "description": [
            +        "Adjust the dry/wet value."
            +      ],
            +      "params": {
            +        "fade": "Number: (Optional) The desired drywet value (0 - 1.0)"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.js-sound, Web Audio Node, or use signal to control an AudioParam"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Filter": {
            +    "description": [
            +      "A p5.Filter uses a Web Audio Biquad Filter to filter the frequency response of an input source. Subclasses include: <a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>: Allows frequencies below the cutoff frequency to pass through, and attenuates frequencies above the cutoff.<br/> <a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>: The opposite of a lowpass filter. <br/> <a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>: Allows a range of frequencies to pass through and attenuates the frequencies below and above this frequency range.<br/>",
            +      "The <code>.res()</code> method controls either width of the bandpass, or resonance of the low/highpass cutoff frequency.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "type": "String: (Optional) 'lowpass' (default), 'highpass', 'bandpass'"
            +    },
            +    "biquadFilter": {
            +      "description": [
            +        "The p5.Filter is built with a <a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\"> Web Audio BiquadFilter Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Filter an audio signal according to a set of filter parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance/Width of the filter frequency  from 0.001 to 1000"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the frequency and the resonance of the filter."
            +      ],
            +      "params": {
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance (Q) from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "freq": {
            +      "description": [
            +        "Set the filter frequency, in Hz, from 10 to 22050 (the range of human hearing, although in reality most people hear in a narrower range)."
            +      ],
            +      "returns": "Number: value Returns the current frequency value",
            +      "params": {
            +        "freq": "Number: Filter Frequency",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "res": {
            +      "description": [
            +        "Controls either width of a bandpass frequency, or the resonance of a low/highpass cutoff frequency."
            +      ],
            +      "returns": "Number: value Returns the current res value",
            +      "params": {
            +        "res": "Number: Resonance/Width of filter freq  from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "gain": {
            +      "description": [
            +        "Controls the gain attribute of a Biquad Filter. This is distinctly different from .amp() which is inherited from p5.Effect .amp() controls the volume via the output gain node p5.Filter.gain() controls the gain parameter of a Biquad Filter node."
            +      ],
            +      "returns": "Number: Returns the current or updated gain value",
            +      "params": {
            +        "gain": "Number"
            +      }
            +    },
            +    "toggle": {
            +      "description": [
            +        "Toggle function. Switches between the specified type and allpass"
            +      ],
            +      "returns": "Boolean: [Toggle value]"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set the type of a p5.Filter. Possible types include: \"lowpass\" (default), \"highpass\", \"bandpass\", \"lowshelf\", \"highshelf\", \"peaking\", \"notch\", \"allpass\"."
            +      ],
            +      "params": {
            +        "t": "String"
            +      }
            +    }
            +  },
            +  "p5.LowPass": {
            +    "description": [
            +      "Constructor: <code>new p5.LowPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('lowpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.HighPass": {
            +    "description": [
            +      "Constructor: <code>new p5.HighPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('highpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.BandPass": {
            +    "description": [
            +      "Constructor: <code>new p5.BandPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('bandpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.EQ": {
            +    "description": [
            +      "p5.EQ is an audio effect that performs the function of a multiband audio equalizer. Equalization is used to adjust the balance of frequency compoenents of an audio signal. This process is commonly used in sound production and recording to change the waveform before it reaches a sound output device. EQ can also be used as an audio effect to create interesting distortions by filtering out parts of the spectrum. p5.EQ is built using a chain of Web Audio Biquad Filter Nodes and can be instantiated with 3 or 8 bands. Bands can be added or removed from the EQ by directly modifying p5.EQ.bands (the array that stores filters).",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "returns": "Object: p5.EQ object",
            +    "params": {
            +      "_eqsize": "Number: (Optional) Constructor will accept 3 or 8, defaults to 3"
            +    },
            +    "bands": {
            +      "description": [
            +        "The p5.EQ is built with abstracted p5.Filter objects. To modify any bands, use methods of the <a href=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\"> p5.Filter</a> API, especially <code>gain</code> and <code>freq</code>. Bands are stored in an array, with indices 0 - 3, or 0 - 7"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process an input by connecting it to the EQ"
            +      ],
            +      "params": {
            +        "src": "Object: Audio source"
            +      }
            +    }
            +  },
            +  "p5.Panner3D": {
            +    "description": [
            +      "Panner3D is based on the <a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>. This panner is a spatial processing node that allows audio to be positioned and oriented in 3D space.",
            +      "The position is relative to an <a title=\"Web Audio Listener docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\"> Audio Context Listener</a>, which can be accessed by <code>p5.soundOut.audiocontext.listener</code>"
            +    ],
            +    "panner": {
            +      "description": [
            +        "<a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>",
            +        "Properties include <ul> <li><a title=\"w3 spec for Panning Model\" href=\"<a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\"\">https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\"</a><blockquote>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect an audio sorce"
            +      ],
            +      "params": {
            +        "src": "Object: Input source"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "positionX": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionY": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionZ": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orient": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "orientX": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientY": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientZ": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "setFalloff": {
            +      "description": [
            +        "Set the rolloff factor and max distance"
            +      ],
            +      "params": {
            +        "maxDistance": "Number (Optional)",
            +        "rolloffFactor": "Number (Optional)"
            +      }
            +    },
            +    "maxDist": {
            +      "description": [
            +        "Maxium distance between the source and the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "maxDistance": "Number"
            +      }
            +    },
            +    "rollof": {
            +      "description": [
            +        "How quickly the volume is reduced as the source moves away from the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "rolloffFactor": "Number"
            +      }
            +    }
            +  },
            +  "p5.Delay": {
            +    "description": [
            +      "Delay is an echo effect. It processes an existing sound source, and outputs a delayed version of that sound. The p5.Delay can produce different effects depending on the delayTime, feedback, filter, and type. In the example below, a feedback of 0.5 (the default value) will produce a looping delay that decreases in volume by 50% each repeat. A filter will cut out the high frequencies so that the delay does not sound as piercing as the original source.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "leftDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "rightDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Add delay to an audio signal according to a set of delay parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "delayTime": "Number: (Optional) Time (in seconds) of the delay/echo.  Some browsers limit delayTime to  1 second.",
            +        "feedback": "Number: (Optional) sends the delay back through itself  in a loop that decreases in volume  each time.",
            +        "lowPass": "Number: (Optional) Cutoff frequency. Only frequencies  below the lowPass will be part of the  delay."
            +      }
            +    },
            +    "delayTime": {
            +      "description": [
            +        "Set the delay (echo) time, in seconds. Usually this value will be a floating point number between 0.0 and 1.0."
            +      ],
            +      "params": {
            +        "delayTime": "Number: Time (in seconds) of the delay"
            +      }
            +    },
            +    "feedback": {
            +      "description": [
            +        "Feedback occurs when Delay sends its signal back through its input in a loop. The feedback amount determines how much signal to send each time through the loop. A feedback greater than 1.0 is not desirable because it will increase the overall output each time through the loop, creating an infinite feedback loop. The default value is 0.5"
            +      ],
            +      "returns": "Number: Feedback value",
            +      "params": {
            +        "feedback": "Number|Object: 0.0 to 1.0, or an object such as an  Oscillator that can be used to  modulate this param"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Set a lowpass filter frequency for the delay. A lowpass filter will cut off any frequencies higher than the filter frequency."
            +      ],
            +      "params": {
            +        "cutoffFreq": "Number|Object: A lowpass filter will cut off any  frequencies higher than the filter frequency.",
            +        "res": "Number|Object: Resonance of the filter frequency  cutoff, or an object (i.e. a p5.Oscillator)  that can be used to modulate this parameter.  High numbers (i.e. 15) will produce a resonance,  low numbers (i.e. .2) will produce a slope."
            +      }
            +    },
            +    "setType": {
            +      "description": [
            +        "Choose a preset type of delay. 'pingPong' bounces the signal from the left to the right channel to produce a stereo effect. Any other parameter will revert to the default delay setting."
            +      ],
            +      "params": {
            +        "type": "String|Number: 'pingPong' (1) or 'default' (0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the delay effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Reverb": {
            +    "description": [
            +      "Reverb adds depth to a sound through a large number of decaying echoes. It creates the perception that sound is occurring in a physical space. The p5.Reverb has parameters for Time (how long does the reverb last) and decayRate (how much the sound decays with each echo) that can be set with the .set() or .process() methods. The p5.Convolver extends p5.Reverb allowing you to recreate the sound of actual physical spaces through convolution.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "process": {
            +      "description": [
            +        "Connect a source to the reverb, and assign reverb parameters."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output.",
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the reverb settings. Similar to .process(), but without assigning a new input."
            +      ],
            +      "params": {
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the reverb effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Convolver": {
            +    "description": [
            +      "p5.Convolver extends p5.Reverb. It can emulate the sound of real physical spaces through a process called <a href=\" https://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\"> convolution</a>.",
            +      "Convolution multiplies any audio input by an \"impulse response\" to simulate the dispersion of sound over time. The impulse response is generated from an audio file that you provide. One way to generate an impulse response is to pop a balloon in a reverberant space and record the echo. Convolution can also be used to experiment with sound.",
            +      "Use the method <code>createConvolution(path)</code> to instantiate a p5.Convolver with a path to your impulse response audio file."
            +    ],
            +    "params": {
            +      "path": "String: path to a sound file",
            +      "callback": "Function: (Optional) function to call when loading succeeds",
            +      "errorCallback": "Function: (Optional) function to call if loading fails.  This function will receive an error or  XMLHttpRequest object with information  about what went wrong."
            +    },
            +    "convolverNode": {
            +      "description": [
            +        "Internally, the p5.Convolver uses the a <a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\"> Web Audio Convolver Node</a>."
            +      ]
            +    },
            +    "impulses": {
            +      "description": [
            +        "If you load multiple impulse files using the .addImpulse method, they will be stored as Objects in this Array. Toggle between them with the <code>toggleImpulse(id)</code> method."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect a source to the convolver."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "addImpulse": {
            +      "description": [
            +        "Load and assign a new Impulse Response to the p5.Convolver. The impulse is added to the <code>.impulses</code> array. Previous impulses can be accessed with the <code>.toggleImpulse(id)</code> method."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "resetImpulse": {
            +      "description": [
            +        "Similar to .addImpulse, except that the <code>.impulses</code> Array is reset to save memory. A new <code>.impulses</code> array is created with this impulse as the only item."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "toggleImpulse": {
            +      "description": [
            +        "If you have used <code>.addImpulse()</code> to add multiple impulses to a p5.Convolver, then you can use this method to toggle between the items in the <code>.impulses</code> Array. Accepts a parameter to identify which impulse you wish to use, identified either by its original filename (String) or by its position in the <code>.impulses </code> Array (Number).<br/> You can access the objects in the .impulses Array directly. Each Object has two attributes: an <code>.audioBuffer</code> (type: Web Audio <a href=\" http://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\"> AudioBuffer)</a> and a <code>.name</code>, a String that corresponds with the original filename."
            +      ],
            +      "params": {
            +        "id": "String|Number: Identify the impulse by its original filename  (String), or by its position in the  <code>.impulses</code> Array (Number)."
            +      }
            +    }
            +  },
            +  "p5.Phrase": {
            +    "description": [
            +      "A phrase is a pattern of musical events over time, i.e. a series of notes and rests.",
            +      "Phrases must be added to a p5.Part for playback, and each part can play multiple phrases at the same time. For example, one Phrase might be a kick drum, another could be a snare, and another could be the bassline.",
            +      "The first parameter is a name so that the phrase can be modified or deleted later. The callback is a a function that this phrase will call at every step—for example it might be called <code>playNote(value){}</code>. The array determines which value is passed into the callback at each step of the phrase. It can be numbers, an object with multiple numbers, or a zero (0) indicates a rest so the callback won't be called)."
            +    ],
            +    "params": {
            +      "name": "String: Name so that you can access the Phrase.",
            +      "callback": "Function: The name of a function that this phrase  will call. Typically it will play a sound,  and accept two parameters: a time at which  to play the sound (in seconds from now),  and a value from the sequence array. The  time should be passed into the play() or  start() method to ensure precision.",
            +      "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +    },
            +    "sequence": {
            +      "description": [
            +        "Array of values to pass into the callback at each step of the phrase. Depending on the callback function's requirements, these values may be numbers, strings, or an object with multiple parameters. Zero (0) indicates a rest."
            +      ]
            +    }
            +  },
            +  "p5.Part": {
            +    "description": [
            +      "A p5.Part plays back one or more p5.Phrases. Instantiate a part with steps and tatums. By default, each step represents a 1/16th note.",
            +      "See p5.Phrase for more about musical timing."
            +    ],
            +    "params": {
            +      "steps": "Number: (Optional) Steps in the part",
            +      "tatums": "Number: (Optional) Divisions of a beat, e.g. use 1/4, or 0.25 for a quarter note (default is 1/16, a sixteenth note)"
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo of this part, in Beats Per Minute."
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: (Optional) Seconds from now"
            +      }
            +    },
            +    "getBPM": {
            +      "description": [
            +        "Returns the tempo, in Beats Per Minute, of this part."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of this part. It will play through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of this part. It will begin looping through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Tell the part to stop looping."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the part. Playback will resume from the current step."
            +      ],
            +      "params": {
            +        "time": "Number: seconds from now"
            +      }
            +    },
            +    "addPhrase": {
            +      "description": [
            +        "Add a p5.Phrase to this Part."
            +      ],
            +      "params": {
            +        "phrase": "p5.Phrase: reference to a p5.Phrase"
            +      }
            +    },
            +    "removePhrase": {
            +      "description": [
            +        "Remove a phrase from this part, based on the name it was given when it was created."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "getPhrase": {
            +      "description": [
            +        "Get a phrase from this part, based on the name it was given when it was created. Now you can modify its array."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "replaceSequence": {
            +      "description": [
            +        "Find all sequences with the specified name, and replace their patterns with the specified array."
            +      ],
            +      "params": {
            +        "phraseName": "String",
            +        "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +      }
            +    },
            +    "onStep": {
            +      "description": [
            +        "Set the function that will be called at every step. This will clear the previous function."
            +      ],
            +      "params": {
            +        "callback": "Function: The name of the callback  you want to fire  on every beat/tatum."
            +      }
            +    }
            +  },
            +  "p5.Score": {
            +    "description": [
            +      "A Score consists of a series of Parts. The parts will be played back in order. For example, you could have an A part, a B part, and a C part, and play them back in this order <code>new p5.Score(a, a, b, a, c)</code>"
            +    ],
            +    "params": {
            +      "parts": "p5.Part: (Optional) One or multiple parts, to be played in sequence."
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of the score."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop playback of the score."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause playback of the score."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of the score."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Stop looping playback of the score. If it is currently playing, this will go into effect after the current round of playback completes."
            +      ]
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo for all parts in the score"
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.SoundLoop": {
            +    "description": [
            +      "SoundLoop"
            +    ],
            +    "params": {
            +      "callback": "Function: this function will be called on each iteration of theloop",
            +      "interval": "Number|String: (Optional) amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second."
            +    },
            +    "bpm": {
            +      "description": [
            +        "Getters and Setters, setting any paramter will result in a change in the clock's frequency, that will be reflected after the next callback beats per minute (defaults to 60)"
            +      ]
            +    },
            +    "timeSignature": {
            +      "description": [
            +        "number of quarter notes in a measure (defaults to 4)"
            +      ]
            +    },
            +    "interval": {
            +      "description": [
            +        "length of the loops interval"
            +      ]
            +    },
            +    "iterations": {
            +      "description": [
            +        "how many times the callback has been called so far"
            +      ]
            +    },
            +    "musicalTimeMode": {
            +      "description": [
            +        "musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention true if string, false if number"
            +      ]
            +    },
            +    "maxIterations": {
            +      "description": [
            +        "Set a limit to the number of loops to play. defaults to Infinity"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a starting time"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a stopping time"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a pausing time"
            +      }
            +    },
            +    "syncedStart": {
            +      "description": [
            +        "Synchronize loops. Use this method to start two more more loops in synchronization or to start a loop in synchronization with a loop that is already playing This method will schedule the implicit loop in sync with the explicit master loop i.e. loopToStart.syncedStart(loopToSyncWith)"
            +      ],
            +      "params": {
            +        "otherLoop": "Object: a p5.SoundLoop to sync with",
            +        "timeFromNow": "Number: (Optional) Start the loops in sync after timeFromNow seconds"
            +      }
            +    }
            +  },
            +  "p5.Compressor": {
            +    "description": [
            +      "Compressor is an audio effect class that performs dynamics compression on an audio input source. This is a very commonly used technique in music and sound production. Compression creates an overall louder, richer, and fuller sound by lowering the volume of louds and raising that of softs. Compression can be used to avoid clipping (sound distortion due to peaks in volume) and is especially useful when many sounds are played at once. Compression can be used on individual sound sources in addition to the master output.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "compressor": {
            +      "description": [
            +        "The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"  target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node  </a>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Performs the same function as .connect, but also accepts optional parameters to set compressor's audioParams"
            +      ],
            +      "params": {
            +        "src": "Object: Sound source to be connected",
            +        "attack": "Number: (Optional) The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: (Optional) The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: (Optional) The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the parameters of a compressor."
            +      ],
            +      "params": {
            +        "attack": "Number: The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "attack": {
            +      "description": [
            +        "Get current attack or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "attack": "Number: (Optional) Attack is the amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "knee": {
            +      "description": [
            +        "Get current knee or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "ratio": {
            +      "description": [
            +        "Get current ratio or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "threshold": {
            +      "description": [
            +        "Get current threshold or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "release": {
            +      "description": [
            +        "Get current release or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "reduction": {
            +      "description": [
            +        "Return the current reduction value"
            +      ],
            +      "returns": "Number: Value of the amount of gain reduction that is applied to the signal"
            +    }
            +  },
            +  "p5.PeakDetect": {
            +    "description": [
            +      "PeakDetect works in conjunction with p5.FFT to look for onsets in some or all of the frequency spectrum.",
            +      "To use p5.PeakDetect, call <code>update</code> in the draw loop and pass in a p5.FFT object.",
            +      "You can listen for a specific part of the frequency spectrum by setting the range between <code>freq1</code> and <code>freq2</code>.",
            +      "<code>threshold</code> is the threshold for detecting a peak, scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud as 1.0.",
            +      "The update method is meant to be run in the draw loop, and <b>frames</b> determines how many loops must pass before another peak can be detected. For example, if the frameRate() = 60, you could detect the beat of a 120 beat-per-minute song with this equation: <code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>",
            +      "Based on example contribtued by @b2renger, and a simple beat detection explanation by <a href=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\" target=\"_blank\">Felix Turner</a>."
            +    ],
            +    "params": {
            +      "freq1": "Number: (Optional) lowFrequency - defaults to 20Hz",
            +      "freq2": "Number: (Optional) highFrequency - defaults to 20000 Hz",
            +      "threshold": "Number: (Optional) Threshold for detecting a beat between 0 and 1  scaled logarithmically where 0.1 is 1/2 the loudness  of 1.0. Defaults to 0.35.",
            +      "framesPerPeak": "Number: (Optional) Defaults to 20."
            +    },
            +    "isDetected": {
            +      "description": [
            +        "isDetected is set to true when a peak is detected."
            +      ]
            +    },
            +    "update": {
            +      "description": [
            +        "The update method is run in the draw loop.",
            +        "Accepts an FFT object. You must call .analyze() on the FFT object prior to updating the peakDetect because it relies on a completed FFT analysis."
            +      ],
            +      "params": {
            +        "fftObject": "p5.FFT: A p5.FFT object"
            +      }
            +    },
            +    "onPeak": {
            +      "description": [
            +        "onPeak accepts two arguments: a function to call when a peak is detected. The value of the peak, between 0.0 and 1.0, is passed to the callback."
            +      ],
            +      "params": {
            +        "callback": "Function: Name of a function that will  be called when a peak is  detected.",
            +        "val": "Object: (Optional) Optional value to pass  into the function when  a peak is detected."
            +      }
            +    }
            +  },
            +  "p5.SoundRecorder": {
            +    "description": [
            +      "Record sounds for playback and/or to save as a .wav file. The p5.SoundRecorder records all sound output from your sketch, or can be assigned a specific source with setInput().",
            +      "The record() method accepts a p5.SoundFile as a parameter. When playback is stopped (either after the given amount of time, or with the stop() method), the p5.SoundRecorder will send its recording to that p5.SoundFile for playback."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a specific device to the p5.SoundRecorder. If no parameter is given, p5.SoundRecorer will record all audible p5.sound from your sketch."
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) p5.sound object or a web audio unit  that outputs sound"
            +      }
            +    },
            +    "record": {
            +      "description": [
            +        "Start recording. To access the recording, provide a p5.SoundFile as the first parameter. The p5.SoundRecorder will send its recording to that p5.SoundFile for playback once recording is complete. Optional parameters include duration (in seconds) of the recording, and a callback function that will be called once the complete recording has been transfered to the p5.SoundFile."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile",
            +        "duration": "Number: (Optional) Time (in seconds)",
            +        "callback": "Function: (Optional) The name of a function that will be  called once the recording completes"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the recording. Once the recording is stopped, the results will be sent to the p5.SoundFile that was given on .record(), and if a callback function was provided on record, that function will be called."
            +      ]
            +    }
            +  },
            +  "p5.Distortion": {
            +    "description": [
            +      "A Distortion effect created with a Waveshaper Node, with an approach adapted from <a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a>",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +      "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +    },
            +    "WaveShaperNode": {
            +      "description": [
            +        "The p5.Distortion is built with a <a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\"> Web Audio WaveShaper Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process a sound source, optionally specify amount and oversample values."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the amount and oversample of the waveshaper distortion."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "getAmount": {
            +      "description": [
            +        "Return the distortion amount, typically between 0-1."
            +      ],
            +      "returns": "Number: Unbounded distortion amount.  Normal values range from 0-1."
            +    },
            +    "getOversample": {
            +      "description": [
            +        "Return the oversampling."
            +      ],
            +      "returns": "String: Oversample can either be 'none', '2x', or '4x'."
            +    }
            +  },
            +  "p5.Gain": {
            +    "description": [
            +      "A gain node is useful to set the relative volume of sound. It's typically used to build mixers."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a source to the gain node."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the gain node."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    }
            +  },
            +  "p5.AudioVoice": {
            +    "description": [
            +      "Base class for monophonic synthesizers. Any extensions of this class should follow the API and implement the methods below in order to remain compatible with p5.PolySynth();"
            +    ],
            +    "connect": {
            +      "description": [
            +        "Connect to p5 objects or Web Audio Nodes"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect from soundOut"
            +      ]
            +    }
            +  },
            +  "p5.MonoSynth": {
            +    "description": [
            +      "A MonoSynth is used as a single voice for sound synthesis. This is a class to be used in conjunction with the PolySynth class. Custom synthesizers should be built inheriting from this class."
            +    ],
            +    "attack": {
            +      "description": [
            +        "Getters and Setters"
            +      ]
            +    },
            +    "decay": {},
            +    "sustain": {},
            +    "release": {},
            +    "play": {
            +      "description": [
            +        "Play tells the MonoSynth to start playing a note. This method schedules the calling of .triggerAttack and .triggerRelease."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope. Defaults to 0.15 seconds."
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "MonoSynth amp"
            +      ],
            +      "returns": "Number: new volume value",
            +      "params": {
            +        "vol": "Number: desired volume",
            +        "rampTime": "Number: (Optional) Time to reach new volume"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  },
            +  "p5.OnsetDetect": {
            +    "description": [
            +      "Listen for onsets (a sharp increase in volume) within a given frequency range."
            +    ],
            +    "params": {
            +      "freqLow": "Number: Low frequency",
            +      "freqHigh": "Number: High frequency",
            +      "threshold": "Number: Amplitude threshold between 0 (no energy) and 1 (maximum)",
            +      "callback": "Function: Function to call when an onset is detected"
            +    }
            +  },
            +  "p5.PolySynth": {
            +    "description": [
            +      "An AudioVoice is used as a single voice for sound synthesis. The PolySynth class holds an array of AudioVoice, and deals with voices allocations, with setting notes to be played, and parameters to be set."
            +    ],
            +    "params": {
            +      "synthVoice": "Number: (Optional) A monophonic synth voice inheriting  the AudioVoice class. Defaults to p5.MonoSynth",
            +      "maxVoices": "Number: (Optional) Number of voices, defaults to 8;"
            +    },
            +    "notes": {
            +      "description": [
            +        "An object that holds information about which notes have been played and which notes are currently being played. New notes are added as keys on the fly. While a note has been attacked, but not released, the value of the key is the audiovoice which is generating that note. When notes are released, the value of the key becomes undefined."
            +      ]
            +    },
            +    "polyvalue": {
            +      "description": [
            +        "A PolySynth must have at least 1 voice, defaults to 8"
            +      ]
            +    },
            +    "AudioVoice": {
            +      "description": [
            +        "Monosynth that generates the sound for each note that is triggered. The p5.PolySynth defaults to using the p5.MonoSynth as its voice."
            +      ]
            +    },
            +    "play": {
            +      "description": [
            +        "Play a note by triggering noteAttack and noteRelease with sustain time"
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note to play (ranging from 0 to 127 - 60 being a middle C)",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "noteADSR": {
            +      "description": [
            +        "noteADSR sets the envelope for a specific note that has just been triggered. Using this method modifies the envelope of whichever audiovoice is being used to play the desired note. The envelope should be reset before noteRelease is called in order to prevent the modified envelope from being used on other notes."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) Midi note on which ADSR should be set.",
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set the PolySynths global envelope. This method modifies the envelopes of each monosynth so that all notes are played with this envelope."
            +      ],
            +      "params": {
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "noteAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of a MonoSynth. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)/",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds)"
            +      }
            +    },
            +    "noteRelease": {
            +      "description": [
            +        "Trigger the Release of an AudioVoice note. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.  If no value is provided, all notes will be released.",
            +        "secondsFromNow": "Number: (Optional) time to trigger the release"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/reference/hi.json b/dist/assets/reference/hi.json
            new file mode 100644
            index 0000000000..0b61a04645
            --- /dev/null
            +++ b/dist/assets/reference/hi.json
            @@ -0,0 +1,7564 @@
            +{
            +  "h1": "संदर्भ",
            +  "reference-search": "एपीआई खोजें",
            +  "reference-description1": "आप जो खोज रहे हैं वह नहीं मिल रहा है? शायद आपको अंदर जांचना चाहिए",
            +  "reference-description3": "आप संदर्भ का एक संस्करण डाउनलोड कर सकते हैं",
            +  "reference-contribute2": "कृपया हमें बताएं",
            +  "reference-error1": "क्या आपको कोई गलती मिली?",
            +  "reference-error3": "कृपया बेझिझक करें",
            +  "reference-error5": "और पुल अनुरोध का संकेत देते हैं।",
            +  "reference-example": "उदाहरण",
            +  "reference-description": "विवरण",
            +  "reference-extends": "फैली",
            +  "reference-parameters": "मापदंडों",
            +  "reference-syntax": "वाक्य-विन्यास",
            +  "reference-returns": "रिटर्न",
            +  "Environment": "वातावरण",
            +  "Color": "रंग",
            +  "Color Conversion": "Color Conversion",
            +  "Creating & Reading": "सृजन और पढ़ना",
            +  "Setting": "विन्यास",
            +  "Shape": "आकार",
            +  "2D Primitives": "2D आदिम",
            +  "Attributes": "गुण",
            +  "Curves": "घटता",
            +  "Vertex": "कोने",
            +  "Constants": "स्थिरांक",
            +  "Structure": "संरचना",
            +  "DOM": "डोम",
            +  "Rendering": "प्रस्तुत करना",
            +  "Foundation": "Foundation",
            +  "Transform": "परिवर्तन",
            +  "Data": "डेटा",
            +  "LocalStorage": "LocalStorage",
            +  "Dictionary": "शब्दकोश",
            +  "Events": "घटनाक्रम",
            +  "Acceleration": "त्वरण",
            +  "Keyboard": "कीबोर्ड",
            +  "Mouse": "माउस",
            +  "Touch": "स्पर्श",
            +  "Image": "चित्र",
            +  "Loading & Displaying": "लोड और दिखाएँ",
            +  "Pixels": "पिक्सल",
            +  "IO": "प्रवेश और निकास",
            +  "Input": "प्रविष्टि",
            +  "Output": "उत्पादन",
            +  "Table": "तालिका",
            +  "Math": "गणित",
            +  "Calculation": "गणना",
            +  "Vector": "Vector",
            +  "Noise": "शोर",
            +  "Random": "Random",
            +  "Trigonometry": "त्रिकोणमिति",
            +  "Typography": "टाइपोग्राफी",
            +  "Array Functions": "सरणी कार्य करता है",
            +  "Conversion": "रूपांतरण",
            +  "String Functions": "स्ट्रिंग फ़ंक्शंस",
            +  "Time & Date": "समय और दिनांक",
            +  "3D Primitives": "3 डी प्रिमिटिव",
            +  "Lights, Camera": "रोशनी, कैमरा",
            +  "Interaction": "Interaction",
            +  "Lights": "दीपक",
            +  "3D Models": "3 डी मॉडल",
            +  "Material": "सामग्री",
            +  "Camera": "कैमरा",
            +  "p5": {
            +    "description": [
            +      "This is the p5 instance constructor.",
            +      "A p5 instance holds all the properties and methods related to a p5 sketch. It expects an incoming sketch closure and it can also take an optional node parameter for attaching the generated p5 canvas to a node. The sketch closure takes the newly created p5 instance as its sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>, <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.",
            +      "A p5 sketch can run in \"global\" or \"instance\" mode: \"global\" - all properties and methods are attached to the window \"instance\" - all properties and methods are bound to this p5 object"
            +    ],
            +    "returns": "P5: a p5 instance",
            +    "params": {
            +      "sketch": "Function: a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,  <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the  given p5 instance",
            +      "node": "HTMLElement: (Optional) element to attach canvas to"
            +    },
            +    "describe": {
            +      "description": [
            +        "Creates a screen reader accessible description for the canvas. The first parameter should be a string with a description of the canvas. The second parameter is optional. If specified, it determines how the description is displayed.",
            +        "<code class=\"language-javascript\">describe(text, LABEL)</code> displays the description to all users as a <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\"> tombstone or exhibit label/caption</a> in a div adjacent to the canvas. You can style it as you wish in your CSS.",
            +        "<code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the description accessible to screen-reader users only, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a>. If a second parameter is not specified, by default, the description will only be available to screen-reader users."
            +      ],
            +      "params": {
            +        "text": "String: description of the canvas",
            +        "display": "Constant: (Optional) either LABEL or FALLBACK"
            +      }
            +    },
            +    "describeElement": {
            +      "description": [
            +        "This function creates a screen-reader accessible description for elements —shapes or groups of shapes that create meaning together— in the canvas. The first paramater should be the name of the element. The second parameter should be a string with a description of the element. The third parameter is optional. If specified, it determines how the element description is displayed.",
            +        "<code class=\"language-javascript\">describeElement(name, text, LABEL)</code> displays the element description to all users as a <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\"> tombstone or exhibit label/caption</a> in a div adjacent to the canvas. You can style it as you wish in your CSS.",
            +        "<code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code> makes the element description accessible to screen-reader users only, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a>. If a second parameter is not specified, by default, the element description will only be available to screen-reader users."
            +      ],
            +      "params": {
            +        "name": "String: name of the element",
            +        "text": "String: description of the element",
            +        "display": "Constant: (Optional) either LABEL or FALLBACK"
            +      }
            +    },
            +    "textOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">textOutput()</code> creates a screenreader accessible output that describes the shapes present on the canvas. The general description of the canvas includes canvas size, canvas color, and number of elements in the canvas (example: 'Your output is a, 400 by 400 pixels, lavender blue canvas containing the following 4 shapes:'). This description is followed by a list of shapes where the color, position, and area of each shape are described (example: \"orange ellipse at top left covering 1% of the canvas\"). Each element can be selected to get more details. A table of elements is also provided. In this table, shape, color, location, coordinates and area are described (example: \"orange ellipse location=top left area=2\").",
            +        "<code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code> make the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a> which is accessible to screen readers. <code class=\"language-javascript\">textOutput(LABEL)</code> creates an additional div with the output adjacent to the canvas, this is useful for non-screen reader users that might want to display the output outside of the canvas' sub DOM as they code. However, using LABEL will create unnecessary redundancy for screen reader users. We recommend using LABEL only as part of the development process of a sketch and removing it before publishing or sharing with screen reader users."
            +      ],
            +      "params": {
            +        "display": "Constant: (Optional) either FALLBACK or LABEL"
            +      }
            +    },
            +    "gridOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">gridOutput()</code> lays out the content of the canvas in the form of a grid (html table) based on the spatial location of each shape. A brief description of the canvas is available before the table output. This description includes: color of the background, size of the canvas, number of objects, and object types (example: \"lavender blue canvas is 200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid describes the content spatially, each element is placed on a cell of the table depending on its position. Within each cell an element the color and type of shape of that element are available (example: \"orange ellipse\"). These descriptions can be selected individually to get more details. A list of elements where shape, color, location, and area are described (example: \"orange ellipse location=top left area=1%\") is also available.",
            +        "<code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code> make the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a> which is accessible to screen readers. <code class=\"language-javascript\">gridOutput(LABEL)</code> creates an additional div with the output adjacent to the canvas, this is useful for non-screen reader users that might want to display the output outside of the canvas' sub DOM as they code. However, using LABEL will create unnecessary redundancy for screen reader users. We recommend using LABEL only as part of the development process of a sketch and removing it before publishing or sharing with screen reader users."
            +      ],
            +      "params": {
            +        "display": "Constant: (Optional) either FALLBACK or LABEL"
            +      }
            +    },
            +    "alpha": {
            +      "description": [
            +        "Extracts the alpha value from a color or pixel array."
            +      ],
            +      "returns": "p5 ऑब्जेक्ट",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "blue": {
            +      "description": [
            +        "Extracts the blue value from a color or pixel array."
            +      ],
            +      "returns": "p5 ऑब्जेक्ट",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "brightness": {
            +      "description": [
            +        "Extracts the HSB brightness value from a color or pixel array."
            +      ],
            +      "returns": "p5 ऑब्जेक्ट",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "color": {
            +      "description": [
            +        "रंग डेटाटाइप के चरों में भंडारण के लिए रंग बनाता है। पैरामीटर को वर्तमान <a href=\"#/p5/colorMode\">colorMode()</a> के आधार पर RGB या HSB मानों के रूप में व्याख्यायित किया जाता है। डिफ़ॉल्ट मोड आरजीबी मान 0 से 255 तक है और इसलिए, फ़ंक्शन कॉल रंग (255, 204, 0) एक चमकदार पीला रंग लौटाएगा।",
            +        "ध्यान दें कि यदि <a href=\"#/p5/color\">color()</a> को केवल एक मान प्रदान किया जाता है, तो इसे ग्रेस्केल मान के रूप में समझा जाएगा। दूसरा मान जोड़ें, और यह होगा अल्फा पारदर्शिता के लिए उपयोग किया जाता है। जब तीन मान निर्दिष्ट किए जाते हैं, तो उन्हें आरजीबी या एचएसबी मान के रूप में व्याख्या किया जाता है। चौथा मान जोड़ने से अल्फा पारदर्शिता लागू होती है।",
            +        "यदि एक एकल स्ट्रिंग तर्क प्रदान किया जाता है, तो आरजीबी, आरजीबीए और हेक्स सीएसएस रंग स्ट्रिंग और सभी नामित रंग स्ट्रिंग समर्थित हैं। इस मामले में, दूसरे तर्क के रूप में अल्फा संख्या मान समर्थित नहीं है, आरजीबीए फॉर्म का उपयोग किया जाना चाहिए।"
            +      ],
            +      "returns": "फिक्स: परिणामस्वरूप रंग",
            +      "params": {
            +        "gray": "Number: number specifying value between white and black.",
            +        "alpha": "Number: (Optional) alpha value relative to current color range  (default is 0-255)",
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "value": "String: a color string",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color"
            +      }
            +    },
            +    "green": {
            +      "description": [
            +        "Extracts the green value from a color or pixel array."
            +      ],
            +      "returns": "p5 ऑब्जेक्ट",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "hue": {
            +      "description": [
            +        "रंग या पिक्सेल सरणी से रंग मान निकालता है।",
            +        "ह्यू एचएसबी और एचएसएल दोनों में मौजूद है। एचएसबी रंग ऑब्जेक्ट के साथ आपूर्ति किए जाने पर यह फ़ंक्शन एचएसबी-सामान्यीकृत रंग लौटाएगा (या जब रंग मोड एचएसबी होने पर पिक्सेल सरणी के साथ आपूर्ति की जाती है), लेकिन एचएसएल-सामान्यीकृत रंग के लिए डिफ़ॉल्ट होगा अन्यथा। (मान केवल तभी भिन्न होंगे जब प्रत्येक सिस्टम के लिए अधिकतम ह्यू सेटिंग अलग हो।)"
            +      ],
            +      "returns": "p5 ऑब्जेक्ट",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "lerpColor": {
            +      "description": [
            +        "दो रंगों को मिलाता है उनके बीच कहीं तीसरा रंग खोजने के लिए। एएमटी पैरामीटर दो मानों के बीच इंटरपोलेट करने की मात्रा है जहां 0.0 पहले रंग के बराबर है, 0.1 पहले रंग के बहुत करीब है, 0.5 बीच में आधा है, आदि। एक 0 से नीचे की राशि को 0 माना जाएगा। इसी तरह, 1 से ऊपर की राशि को 1 पर सीमित कर दिया जाएगा। यह <a href=\"#/p5/lerp\">lerp()</a> के व्यवहार से अलग है, लेकिन आवश्यक है क्योंकि अन्यथा सीमा के बाहर की संख्याएँ अजीब और अप्रत्याशित रंग उत्पन्न करेंगी।",
            +        "जिस तरह से रंगों को प्रक्षेपित किया जाता है वह वर्तमान रंग मोड पर निर्भर करता है।"
            +      ],
            +      "returns": "व्यवस्था / संख्या: प्रक्षेपित रंग",
            +      "params": {
            +        "c1": "p5.Color: interpolate from this color",
            +        "c2": "p5.Color: interpolate to this color",
            +        "amt": "Number: number between 0 and 1"
            +      }
            +    },
            +    "lightness": {
            +      "description": [
            +        "Extracts the HSL lightness value from a color or pixel array."
            +      ],
            +      "returns": "p5 ऑब्जेक्ट",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "red": {
            +      "description": [
            +        "Extracts the red value from a color or pixel array."
            +      ],
            +      "returns": "p5 ऑब्जेक्ट",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "saturation": {
            +      "description": [
            +        "रंग या पिक्सेल सरणी से संतृप्ति मान निकालता है।",
            +        "संतृप्ति को एचएसबी और एचएसएल में अलग-अलग स्केल किया जाता है। यह फ़ंक्शन एचएसबी रंग ऑब्जेक्ट के साथ आपूर्ति किए जाने पर एचएसबी संतृप्ति लौटाएगा (या जब रंग मोड एचएसबी है, तो पिक्सेल सरणी के साथ आपूर्ति की जाती है), लेकिन अन्यथा एचएसएल संतृप्ति में डिफ़ॉल्ट होगा।"
            +      ],
            +      "returns": "p5 ऑब्जेक्ट",
            +      "params": {
            +        "color": "p5.Color|Number[]|String: <a href=\"#/p5.Color\">p5.Color</a> object, color components,  or CSS color"
            +      }
            +    },
            +    "background": {
            +      "description": [
            +        "<a href=\"#/p5/background\">background()</a> फ़ंक्शन p5.js कैनवास की पृष्ठभूमि के लिए उपयोग किए गए रंग को सेट करता है। डिफ़ॉल्ट पृष्ठभूमि पारदर्शी होती है। यह फ़ंक्शन आमतौर पर अंदर उपयोग किया जाता है <a href=\"#/p5/draw\">draw()</a> प्रत्येक फ्रेम की शुरुआत में डिस्प्ले विंडो को साफ करने के लिए, लेकिन इसका उपयोग <a href=\"#/p5/setup\">सेटअप ()</a> एनिमेशन के पहले फ्रेम पर बैकग्राउंड सेट करने के लिए या अगर बैकग्राउंड को सिर्फ एक बार सेट करने की जरूरत है।",
            +        "रंग या तो आरजीबी, एचएसबी, या एचएसएल रंग के संदर्भ में निर्दिष्ट किया गया है जो वर्तमान <a href=\"#/p5/colorMode\">colorMode</a> पर निर्भर करता है। (डिफ़ॉल्ट रंग स्थान RGB है, जिसमें 0 से 255 तक की सीमा में प्रत्येक मान)। डिफ़ॉल्ट रूप से अल्फा श्रेणी भी 0 से 255 तक होती है।",
            +        "यदि एक एकल स्ट्रिंग तर्क प्रदान किया जाता है, तो आरजीबी, आरजीबीए और हेक्स सीएसएस रंग तार और सभी नामित रंग तार समर्थित हैं। इस मामले में, दूसरे तर्क के रूप में अल्फा संख्या मान समर्थित नहीं है, आरजीबीए फॉर्म का उपयोग किया जाना चाहिए।",
            +        "एक <a href=\"#/p5.Color\">p5.Color</a> ऑब्जेक्ट भी बैकग्राउंड कलर सेट करने के लिए दिया जा सकता है।",
            +        "एक <a href=\"#/p5.Image\">p5.Image</a> भी पृष्ठभूमि छवि सेट करने के लिए प्रदान किया जा सकता है।"
            +      ],
            +      "params": {
            +        "color": "p5.Color: any value created by the <a href=\"#/p5/color\">color()</a> function",
            +        "colorstring": "String: color string, possible formats include: integer  rgb() or rgba(), percentage rgb() or rgba(),  3-digit hex, 6-digit hex",
            +        "a": "Number: (Optional) opacity of the background relative to current  color range (default is 0-255)",
            +        "gray": "Number: specifies a value between white and black",
            +        "v1": "Number: red or hue value (depending on the current color  mode)",
            +        "v2": "Number: green or saturation value (depending on the current  color mode)",
            +        "v3": "Number: blue or brightness value (depending on the current  color mode)",
            +        "values": "Number[]: an array containing the red, green, blue  and alpha components of the color",
            +        "image": "p5.Image: image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,  to set as background  (must be same size as the sketch window)"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Clears the pixels within a buffer. This function only clears the canvas. It will not clear objects created by createX() methods such as <a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>. Unlike the main graphics context, pixels in additional graphics areas created with <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely or partially transparent. This function clears everything to make all of the pixels 100% transparent."
            +      ]
            +    },
            +    "colorMode": {
            +      "description": [
            +        "<a href=\"#/p5/colorMode\">colorMode()</a> p5.js रंग डेटा की व्याख्या करने के तरीके को बदल देता है। डिफ़ॉल्ट रूप से, <a href=\"#/p5/fill\">भरें()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>, और <a href=\"#/p5/color\">color()</a> को RGB रंग मॉडल का उपयोग करके 0 और 255 के बीच के मानों द्वारा परिभाषित किया जाता है। यह colorMode (RGB, 255) सेट करने के बराबर है कलरमोड (एचएसबी) सेट करने से आप इसके बजाय एचएसबी सिस्टम का उपयोग कर सकते हैं। डिफ़ॉल्ट रूप से, यह कलरमोड (एचएसबी, 360, 100, 100, 1) है। आप एचएसएल का भी उपयोग कर सकते हैं।",
            +        "नोट: मौजूदा रंगीन ऑब्जेक्ट उस मोड को याद रखते हैं जिसमें वे बनाए गए थे, इसलिए आप उनकी उपस्थिति को प्रभावित किए बिना अपनी पसंद के अनुसार मोड बदल सकते हैं।"
            +      ],
            +      "params": {
            +        "mode": "Constant: either RGB, HSB or HSL, corresponding to  Red/Green/Blue and Hue/Saturation/Brightness  (or Lightness)",
            +        "max": "Number: (Optional) range for all values",
            +        "max1": "Number: range for the red or hue depending on the  current color mode",
            +        "max2": "Number: range for the green or saturation depending  on the current color mode",
            +        "max3": "Number: range for the blue or brightness/lightness  depending on the current color mode",
            +        "maxA": "Number: (Optional) range for the alpha"
            +      }
            +    },
            +    "fill": {
            +      "description": [
            +        "आकृतियों को भरने के लिए प्रयुक्त रंग सेट करता है। उदाहरण के लिए, यदि आप भरण (204, 102, 0) चलाते हैं, तो भरण आदेश के बाद खींची गई सभी आकृतियों को नारंगी रंग से भर दिया जाएगा। यह रंग या तो आरजीबी के संदर्भ में निर्दिष्ट है या वर्तमान <a href=\"#/p5/colorMode\">colorMode()</a> के आधार पर HSB रंग। (डिफ़ॉल्ट रंग स्थान RGB है, जिसमें प्रत्येक मान 0 से 255 के बीच होता है)। अल्फा डिफ़ॉल्ट रूप से सीमा भी 0 से 255 तक होती है।",
            +        "यदि एक एकल स्ट्रिंग तर्क प्रदान किया जाता है, तो आरजीबी, आरजीबीए और हेक्स सीएसएस रंग तार और सभी नामित रंग तार समर्थित हैं। इस मामले में, दूसरे तर्क के रूप में अल्फा संख्या मान समर्थित नहीं है, आरजीबीए फॉर्म का उपयोग किया जाना चाहिए।",
            +        "एक p5 <a href=\"#/p5.Color\">Color</a> ऑब्जेक्ट भी भरण रंग सेट करने के लिए प्रदान किया जा सकता है।"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "alpha": "Number (Optional)",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the fill color"
            +      }
            +    },
            +    "noFill": {
            +      "description": [
            +        "Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called, nothing will be drawn to the screen."
            +      ]
            +    },
            +    "noStroke": {
            +      "description": [
            +        "स्ट्रोक (रूपरेखा) खींचना अक्षम करता है। यदि दोनों <a href=\"#/p5/noStroke\">noStroke()</a> और <a href=\"#/p5/noFill\">noFill() </a> कहा जाता है, स्क्रीन पर कुछ भी नहीं खींचा जाएगा।"
            +      ]
            +    },
            +    "stroke": {
            +      "description": [
            +        "आकृतियों के चारों ओर रेखाएँ और सीमाएँ खींचने के लिए उपयोग किए गए रंग को सेट करता है। यह रंग या तो RGB या HSB रंग के संदर्भ में निर्दिष्ट होता है जो वर्तमान <a href=\"#/p5/colorMode\">colorMode()</a>पर निर्भर करता है। (डिफ़ॉल्ट रंग स्थान आरजीबी है, प्रत्येक मान 0 से 255 तक की सीमा में है। डिफ़ॉल्ट रूप से अल्फा श्रेणी भी 0 से 255 है।",
            +        "यदि एक एकल स्ट्रिंग तर्क प्रदान किया जाता है, तो आरजीबी, आरजीबीए और हेक्स सीएसएस रंग तार और सभी नामित रंग तार समर्थित हैं। इस मामले में, दूसरे तर्क के रूप में अल्फा संख्या मान समर्थित नहीं है, आरजीबीए फॉर्म का उपयोग किया जाना चाहिए।",
            +        "स्ट्रोक रंग सेट करने के लिए एक p5 <a href=\"#/p5.Color\">Color</a> ऑब्जेक्ट भी प्रदान किया जा सकता है।"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "alpha": "Number (Optional)",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the stroke color"
            +      }
            +    },
            +    "erase": {
            +      "description": [
            +        "All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from the canvas.Erased areas will reveal the web page underneath the canvas.Erasing can be canceled with <a href=\"#/p5/noErase\">noErase()</a>.",
            +        "Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\"> background()</a> in between <a href=\"#/p5/erase\">erase()</a> and <a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual."
            +      ],
            +      "params": {
            +        "strengthFill": "Number: (Optional) A number (0-255) for the strength of erasing for a shape's fill.  This will default to 255 when no argument is given, which  is full strength.",
            +        "strengthStroke": "Number: (Optional) A number (0-255) for the strength of erasing for a shape's stroke.  This will default to 255 when no argument is given, which  is full strength."
            +      }
            +    },
            +    "noErase": {
            +      "description": [
            +        "Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>. The <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and <a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were prior to calling <a href=\"#/p5/erase\">erase()</a>."
            +      ]
            +    },
            +    "arc": {
            +      "description": [
            +        "स्क्रीन पर एक चाप बनाएं। यदि केवल एक्स, वाई, डब्ल्यू, एच, स्टार्ट और स्टॉप के साथ बुलाया जाता है, तो चाप को एक खुले पाई सेगमेंट के रूप में खींचा और भर दिया जाएगा। यदि एक मोड पैरामीटर प्रदान किया जाता है, तो चाप भर जाएगा एक खुला अर्ध-वृत्त (OPEN), एक बंद अर्ध-वृत्त (CHORD), या एक बंद पाई खंड (PIE) के रूप में। मूल को <a href=\"#/p5/ellipseMode\">ellipseMode()</a>से बदला जा सकता है  समारोह।",
            +        "चाप हमेशा दक्षिणावर्त खींची जाती है, जहां से प्रारंभ गिरती है, जहां दीर्घवृत्त पर स्टॉप गिरती है। किसी भी कोण में TWO_PI को जोड़ने या घटाने से वह नहीं बदलता जहां वे गिरते हैं। यदि दोनों प्रारंभ और स्टॉप एक ही स्थान पर गिरते हैं, तो एक पूर्ण दीर्घवृत्त खींचा जाएगा। ध्यान रखें कि y-अक्ष नीचे की दिशा में बढ़ता है, इसलिए कोणों को धनात्मक x-दिशा (\"3 बजे\") से दक्षिणावर्त मापा जाता है।"
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the arc's ellipse",
            +        "y": "Number: y-coordinate of the arc's ellipse",
            +        "w": "Number: width of the arc's ellipse by default",
            +        "h": "Number: height of the arc's ellipse by default",
            +        "start": "Number: angle to start the arc, specified in radians",
            +        "stop": "Number: angle to stop the arc, specified in radians",
            +        "mode": "Constant: (Optional) optional parameter to determine the way of drawing  the arc. either CHORD, PIE or OPEN",
            +        "detail": "Integer: (Optional) optional parameter for WebGL mode only. This is to  specify the number of vertices that makes up the  perimeter of the arc. Default value is 25. Won't  draw a stroke for a detail of more than 50."
            +      }
            +    },
            +    "ellipse": {
            +      "description": [
            +        "स्क्रीन पर एक अंडाकार (अंडाकार) खींचता है। डिफ़ॉल्ट रूप से, पहले दो पैरामीटर अंडाकार के केंद्र का स्थान निर्धारित करते हैं, और तीसरा और चौथा पैरामीटर आकार की चौड़ाई और ऊंचाई निर्धारित करता है। यदि कोई ऊंचाई निर्दिष्ट नहीं है, तो का मान चौड़ाई का उपयोग चौड़ाई और ऊंचाई दोनों के लिए किया जाता है। यदि एक नकारात्मक ऊंचाई या चौड़ाई निर्दिष्ट की जाती है, तो निरपेक्ष मान लिया जाता है।",
            +        "समान चौड़ाई और ऊंचाई वाला एक दीर्घवृत्त एक वृत्त है। मूल को <a href=\"#/p5/ellipseMode\">ellipseMode()</a> फ़ंक्शन के साथ बदला जा सकता है।"
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the center of ellipse.",
            +        "y": "Number: y-coordinate of the center of ellipse.",
            +        "w": "Number: width of the ellipse.",
            +        "h": "Number: (Optional) height of the ellipse.",
            +        "detail": "Integer: (Optional) optional parameter for WebGL mode only. This is to  specify the number of vertices that makes up the  perimeter of the ellipse. Default value is 25. Won't  draw a stroke for a detail of more than 50."
            +      }
            +    },
            +    "circle": {
            +      "description": [
            +        "Draws a circle to the screen. A circle is a simple closed shape. It is the set of all points in a plane that are at a given distance from a given point, the centre. This function is a special case of the ellipse() function, where the width and height of the ellipse are the same. Height and width of the ellipse correspond to the diameter of the circle. By default, the first two parameters set the location of the centre of the circle, the third sets the diameter of the circle."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the centre of the circle.",
            +        "y": "Number: y-coordinate of the centre of the circle.",
            +        "d": "Number: diameter of the circle."
            +      }
            +    },
            +    "line": {
            +      "description": [
            +        "स्क्रीन पर एक रेखा (दो बिंदुओं के बीच एक सीधा पथ) खींचता है। यदि केवल 4 पैरामीटर के साथ कॉल किया जाता है, तो यह 1 पिक्सेल की डिफ़ॉल्ट चौड़ाई के साथ 2D में एक रेखा खींचेगा। इस चौड़ाई को <a href=\"#/p5/strokeWeight\"> stokeWeight()</a>का उपयोग करके संशोधित किया जा सकता है फ़ंक्शन। एक लाइन को भरा नहीं जा सकता है, इसलिए <a href=\"#/p5/fill\">fill()</a> फंक्शन होगा किसी रेखा के रंग को प्रभावित न करें। इसलिए किसी रेखा को रंगने के लिए, <a href=\"#/p5/stroke\">stroke()</a> फ़ंक्शन का उपयोग करें।"
            +      ],
            +      "params": {
            +        "x1": "Number: the x-coordinate of the first point",
            +        "y1": "Number: the y-coordinate of the first point",
            +        "x2": "Number: the x-coordinate of the second point",
            +        "y2": "Number: the y-coordinate of the second point",
            +        "z1": "Number: the z-coordinate of the first point",
            +        "z2": "Number: the z-coordinate of the second point"
            +      }
            +    },
            +    "point": {
            +      "description": [
            +        "एक बिंदु खींचता है, एक पिक्सेल के आयाम पर अंतरिक्ष में एक निर्देशांक। पहला पैरामीटर बिंदु के लिए क्षैतिज मान है, दूसरा पैरामीटर बिंदु के लिए लंबवत मान है। बिंदु का रंग <a href =\"#/p5/stoke\">stoke()</a> के साथ बदल जाता है फ़ंक्शन। बिंदु का आकार <a href=\"#/p5/strokeWeight\">strokeWeight()</a से बदला जा सकता है > समारोह।"
            +      ],
            +      "params": {
            +        "x": "Number: the x-coordinate",
            +        "y": "Number: the y-coordinate",
            +        "z": "Number: (Optional) the z-coordinate (for WebGL mode)",
            +        "coordinate_vector": "p5.Vector: the coordinate vector"
            +      }
            +    },
            +    "quad": {
            +      "description": [
            +        "कैनवास पर एक क्वाड खींचता है। एक क्वाड एक चतुर्भुज, एक चार भुजा वाला बहुभुज है। यह एक आयत के समान है, लेकिन इसके किनारों के बीच के कोण नब्बे डिग्री तक सीमित नहीं हैं। मापदंडों की पहली जोड़ी (x1,y1) सेट पहले शीर्ष और बाद के जोड़े को परिभाषित आकार के चारों ओर दक्षिणावर्त या वामावर्त आगे बढ़ना चाहिए। z- तर्क केवल तभी काम करते हैं जब quad() का उपयोग WEBGL मोड में किया जाता है।"
            +      ],
            +      "params": {
            +        "x1": "Number: the x-coordinate of the first point",
            +        "y1": "Number: the y-coordinate of the first point",
            +        "x2": "Number: the x-coordinate of the second point",
            +        "y2": "Number: the y-coordinate of the second point",
            +        "x3": "Number: the x-coordinate of the third point",
            +        "y3": "Number: the y-coordinate of the third point",
            +        "x4": "Number: the x-coordinate of the fourth point",
            +        "y4": "Number: the y-coordinate of the fourth point",
            +        "detailX": "Integer: (Optional) number of segments in the x-direction",
            +        "detailY": "Integer: (Optional) number of segments in the y-direction",
            +        "z1": "Number: the z-coordinate of the first point",
            +        "z2": "Number: the z-coordinate of the second point",
            +        "z3": "Number: the z-coordinate of the third point",
            +        "z4": "Number: the z-coordinate of the fourth point"
            +      }
            +    },
            +    "rect": {
            +      "description": [
            +        "कैनवास पर एक आयत बनाता है। एक आयत एक चार-तरफा बंद आकार है जिसमें प्रत्येक कोण नब्बे डिग्री पर होता है। डिफ़ॉल्ट रूप से, पहले दो पैरामीटर ऊपरी-बाएं कोने का स्थान निर्धारित करते हैं, तीसरा चौड़ाई सेट करता है, और चौथा ऊंचाई सेट करता है। जिस तरह से इन मापदंडों की व्याख्या की जाती है, उसे <a href=\"#/p5/rectMode\">rectMode()</a> फ़ंक्शन के साथ बदला जा सकता है।",
            +        "पांचवां, छठा, सातवां और आठवां पैरामीटर, यदि निर्दिष्ट किया गया है, क्रमशः शीर्ष-बाएं, शीर्ष-दाएं, निचले-दाएं और निचले-बाएं कोनों के लिए कोने त्रिज्या निर्धारित करें। एक छोड़ा गया कोने त्रिज्या पैरामीटर के मान पर सेट किया गया है पैरामीटर सूची में पहले निर्दिष्ट त्रिज्या मान।"
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the rectangle.",
            +        "y": "Number: y-coordinate of the rectangle.",
            +        "w": "Number: width of the rectangle.",
            +        "h": "Number: (Optional) height of the rectangle.",
            +        "tl": "Number: (Optional) optional radius of top-left corner.",
            +        "tr": "Number: (Optional) optional radius of top-right corner.",
            +        "br": "Number: (Optional) optional radius of bottom-right corner.",
            +        "bl": "Number: (Optional) optional radius of bottom-left corner.",
            +        "detailX": "Integer: (Optional) number of segments in the x-direction (for WebGL mode)",
            +        "detailY": "Integer: (Optional) number of segments in the y-direction (for WebGL mode)"
            +      }
            +    },
            +    "square": {
            +      "description": [
            +        "Draws a square to the screen. A square is a four-sided shape with every angle at ninety degrees, and equal side size. This function is a special case of the rect() function, where the width and height are the same, and the parameter is called \"s\" for side size. By default, the first two parameters set the location of the upper-left corner, the third sets the side size of the square. The way these parameters are interpreted, may be changed with the <a href=\"#/p5/rectMode\">rectMode()</a> function.",
            +        "The fourth, fifth, sixth and seventh parameters, if specified, determine corner radius for the top-left, top-right, lower-right and lower-left corners, respectively. An omitted corner radius parameter is set to the value of the previously specified radius value in the parameter list."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the square.",
            +        "y": "Number: y-coordinate of the square.",
            +        "s": "Number: side size of the square.",
            +        "tl": "Number: (Optional) optional radius of top-left corner.",
            +        "tr": "Number: (Optional) optional radius of top-right corner.",
            +        "br": "Number: (Optional) optional radius of bottom-right corner.",
            +        "bl": "Number: (Optional) optional radius of bottom-left corner."
            +      }
            +    },
            +    "triangle": {
            +      "description": [
            +        "एक त्रिभुज को कैनवास पर खींचता है। एक त्रिभुज तीन बिंदुओं को जोड़कर बनाया गया एक विमान है। पहले दो तर्क पहले बिंदु को निर्दिष्ट करते हैं, मध्य दो तर्क दूसरे बिंदु को निर्दिष्ट करते हैं, और अंतिम दो तर्क तीसरे बिंदु को निर्दिष्ट करते हैं।"
            +      ],
            +      "params": {
            +        "x1": "Number: x-coordinate of the first point",
            +        "y1": "Number: y-coordinate of the first point",
            +        "x2": "Number: x-coordinate of the second point",
            +        "y2": "Number: y-coordinate of the second point",
            +        "x3": "Number: x-coordinate of the third point",
            +        "y3": "Number: y-coordinate of the third point"
            +      }
            +    },
            +    "ellipseMode": {
            +      "description": [
            +        "उस स्थान को संशोधित करता है जहां से दीर्घवृत्त खींचे जाते हैं, जिस तरह से पैरामीटर दिए गए हैं <a href=\"#/p5/ellipse\">ellipse()</a>, <a href=\"#/p5/circle\">circle()</a> और <a href=\" #/p5/arc\">arc()</a> की व्याख्या की जाती है।",
            +        "डिफ़ॉल्ट मोड CENTER है, जिसमें पहले दो मापदंडों की व्याख्या आकृति के केंद्र बिंदु के रूप में क्रमशः x और y निर्देशांक के रूप में की जाती है, जबकि तीसरा और चौथा पैरामीटर इसकी चौड़ाई और ऊंचाई है।",
            +        "ellipseMode(RADIUS) आकृति के केंद्र बिंदु के x और y निर्देशांक के रूप में पहले दो पैरामीटर का भी उपयोग करता है, लेकिन आकार की चौड़ाई और ऊंचाई के आधे हिस्से को निर्दिष्ट करने के लिए तीसरे और चौथे पैरामीटर का उपयोग करता है।",
            +        "ellipseMode(CORNER) आकृति के ऊपरी-बाएँ कोने के रूप में पहले दो मापदंडों की व्याख्या करता है, जबकि तीसरा और चौथा पैरामीटर इसकी चौड़ाई और ऊंचाई है।",
            +        "ellipseMode(CORNERS) पहले दो मापदंडों को दीर्घवृत्त के बाउंडिंग बॉक्स के एक कोने के स्थान के रूप में और तीसरे और चौथे पैरामीटर को विपरीत कोने के स्थान के रूप में व्याख्या करता है।",
            +        "इस पद्धति के पैरामीटर को सभी CAPS में लिखा जाना चाहिए क्योंकि वे सभी CAPS में स्थिरांक के रूप में पूर्वनिर्धारित हैं और जावास्क्रिप्ट एक केस-संवेदी भाषा है।"
            +      ],
            +      "params": {
            +        "mode": "Constant: either CENTER, RADIUS, CORNER, or CORNERS"
            +      }
            +    },
            +    "noSmooth": {
            +      "description": [
            +        "सभी ज्यामिति को दांतेदार (उपनाम) किनारों के साथ खींचता है। ध्यान दें कि <a href=\"#/p5/smooth\">smooth()</a> डिफ़ॉल्ट रूप से 2D मोड में सक्रिय है, इसलिए कॉल करना आवश्यक है <a href=\"#/p5/noSmooth\">noSmooth()</a> ज्योमेट्री, इमेज और फॉण्ट की स्मूदिंग को डिसेबल करने के लिए। 3D मोड में <a href=\"#/p5/noSmooth\">noSmooth()</a> डिफ़ॉल्ट रूप से सक्षम है, इसलिए <a href=\"#/p5/smooth\">smooth()</a> को कॉल करना आवश्यक है यदि आप अपनी ज्यामिति पर चिकने (एंटीअलाइज्ड) किनारे चाहते हैं।"
            +      ]
            +    },
            +    "rectMode": {
            +      "description": [
            +        "उस स्थान को संशोधित करता है जहां से पैरामीटर दिए गए तरीके को बदलकर आयतें खींची जाती हैं <a href=\"#/p5/rect\">rect()</a> की व्याख्या की जाती है।",
            +        "डिफ़ॉल्ट मोड कॉर्नर है, जो पहले दो मापदंडों को आकार के ऊपरी-बाएँ कोने के रूप में व्याख्या करता है, जबकि तीसरा और चौथा पैरामीटर इसकी चौड़ाई और ऊंचाई है।",
            +        "रेक्टमोड (कॉर्नर) पहले दो मापदंडों को कोनों में से एक के स्थान के रूप में और तीसरे और चौथे पैरामीटर को तिरछे विपरीत कोने के स्थान के रूप में व्याख्या करता है। ध्यान दें, आयत निर्देशांक के बीच खींचा जाता है, इसलिए यह आवश्यक नहीं है कि पहला कोना ऊपरी बाएँ कोना होगा।",
            +        "rectMode(CENTER) आकृति के केंद्र बिंदु के रूप में पहले दो मापदंडों की व्याख्या करता है, जबकि तीसरा और चौथा पैरामीटर इसकी चौड़ाई और ऊंचाई है।",
            +        "rectMode(RADIUS) आकृति के केंद्र बिंदु के रूप में पहले दो मापदंडों का भी उपयोग करता है, लेकिन क्रमशः आकार की चौड़ाई और ऊंचाई के आधे हिस्से को निर्दिष्ट करने के लिए तीसरे और चौथे पैरामीटर का उपयोग करता है।",
            +        "इस पद्धति के पैरामीटर को सभी CAPS में लिखा जाना चाहिए क्योंकि वे सभी CAPS में स्थिरांक के रूप में पूर्वनिर्धारित हैं और जावास्क्रिप्ट एक केस-संवेदी भाषा है।"
            +      ],
            +      "params": {
            +        "mode": "Constant: either CORNER, CORNERS, CENTER, or RADIUS"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "सभी ज्यामिति को चिकने (एंटी-अलियास) किनारों के साथ खींचता है। <a href=\"#/p5/smooth\">smooth()</a> आकार बदलने वाली छवियों की छवि गुणवत्ता में भी सुधार करेगा। ध्यान दें कि <a href=\"#/p5/smooth\">smooth()</a> डिफ़ॉल्ट रूप से 2D मोड में सक्रिय है; <a href=\"#/p5/noSmooth\">noSmooth()</a> का इस्तेमाल ज्योमेट्री, इमेज और फोंट की स्मूदिंग को डिसेबल करने के लिए किया जा सकता है। 3डी मोड में, <a href=\"#/p5/noSmooth\">noSmooth()</a> डिफ़ॉल्ट रूप से सक्षम है, इसलिए <a href=\"#/p5/smooth\">smooth()</a> को कॉल करना आवश्यक है यदि आप अपनी ज्यामिति पर चिकने (एंटीअलाइज्ड) किनारे चाहते हैं।"
            +      ]
            +    },
            +    "strokeCap": {
            +      "description": [
            +        "लाइन एंडिंग को रेंडर करने के लिए स्टाइल सेट करता है। ये सिरे या तो गोल, चौकोर या विस्तारित होते हैं, जिनमें से प्रत्येक को संबंधित मापदंडों के साथ निर्दिष्ट किया जाता है: ROUND, SQUARE और PROJECT। डिफ़ॉल्ट कैप राउंड है।",
            +        "इस पद्धति के पैरामीटर को सभी CAPS में लिखा जाना चाहिए क्योंकि वे सभी CAPS में स्थिरांक के रूप में पूर्वनिर्धारित हैं और जावास्क्रिप्ट एक केस-संवेदी भाषा है।"
            +      ],
            +      "params": {
            +        "cap": "Constant: either ROUND, SQUARE or PROJECT"
            +      }
            +    },
            +    "strokeJoin": {
            +      "description": [
            +        "जोड़ों की शैली सेट करता है जो लाइन सेगमेंट को जोड़ता है। ये जोड़ या तो मिटर्ड, बेवेल या गोलाकार होते हैं और संबंधित पैरामीटर एमआईटीईआर, बेवेल और राउंड के साथ निर्दिष्ट होते हैं। डिफ़ॉल्ट संयुक्त एमआईटीईआर है। इस पद्धति के पैरामीटर को सभी CAPS में लिखा जाना चाहिए क्योंकि वे सभी CAPS में स्थिरांक के रूप में पूर्वनिर्धारित हैं और जावास्क्रिप्ट एक केस-संवेदी भाषा है।",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "join": "Constant: either MITER, BEVEL, ROUND"
            +      }
            +    },
            +    "strokeWeight": {
            +      "description": [
            +        "Sets the width of the stroke used for lines, points and the border around shapes. All widths are set in units of pixels."
            +      ],
            +      "params": {
            +        "weight": "Number: the weight of the stroke (in pixels)"
            +      }
            +    },
            +    "bezier": {
            +      "description": [
            +        "स्क्रीन पर एक क्यूबिक बेज़ियर वक्र बनाता है। इन वक्रों को एंकर और नियंत्रण बिंदुओं की एक श्रृंखला द्वारा परिभाषित किया जाता है। पहले दो पैरामीटर पहले एंकर पॉइंट को निर्दिष्ट करते हैं और अंतिम दो पैरामीटर अन्य एंकर पॉइंट को निर्दिष्ट करते हैं, जो पहले और अंतिम बिंदु बन जाते हैं। वक्र पर। मध्य पैरामीटर दो नियंत्रण बिंदुओं को निर्दिष्ट करते हैं जो वक्र के आकार को परिभाषित करते हैं। लगभग बोलते हुए, नियंत्रण बिंदु वक्र को उनकी ओर \"खींचें\"।",
            +        "बेज़ियर कर्व्स फ्रांसीसी ऑटोमोटिव इंजीनियर पियरे बेज़ियर द्वारा विकसित किए गए थे, और आमतौर पर कंप्यूटर ग्राफिक्स में धीरे-धीरे ढलान वाले वक्रों को परिभाषित करने के लिए उपयोग किए जाते हैं। <a href=\"#/p5/curve\">वक्र()</a> भी देखें।"
            +      ],
            +      "params": {
            +        "x1": "Number: x-coordinate for the first anchor point",
            +        "y1": "Number: y-coordinate for the first anchor point",
            +        "x2": "Number: x-coordinate for the first control point",
            +        "y2": "Number: y-coordinate for the first control point",
            +        "x3": "Number: x-coordinate for the second control point",
            +        "y3": "Number: y-coordinate for the second control point",
            +        "x4": "Number: x-coordinate for the second anchor point",
            +        "y4": "Number: y-coordinate for the second anchor point",
            +        "z1": "Number: z-coordinate for the first anchor point",
            +        "z2": "Number: z-coordinate for the first control point",
            +        "z3": "Number: z-coordinate for the second control point",
            +        "z4": "Number: z-coordinate for the second anchor point"
            +      }
            +    },
            +    "bezierDetail": {
            +      "description": [
            +        "Sets the resolution at which Bezier's curve is displayed. The default value is 20.",
            +        "Note, This function is only useful when using the WEBGL renderer as the default canvas renderer does not use this information."
            +      ],
            +      "params": {
            +        "detail": "Number: resolution of the curves"
            +      }
            +    },
            +    "bezierPoint": {
            +      "description": [
            +        "बेज़ियर वक्र के नियंत्रण और एंकर बिंदुओं के x या y समन्वय मानों को देखते हुए, यह स्थिति t पर बेज़ियर के x या y निर्देशांक का मूल्यांकन करता है। पैरामीटर a और d पहले और अंतिम बिंदुओं के x या y निर्देशांक हैं। वक्र पर जबकि बी और सी नियंत्रण बिंदुओं के हैं। अंतिम पैरामीटर टी परिणामी बिंदु की स्थिति है जो 0 और 1 के बीच दिया गया है। यह एक बार x निर्देशांक के साथ और दूसरी बार y निर्देशांक के साथ किया जा सकता है t पर एक बेजियर वक्र का स्थान प्राप्त करें।"
            +      ],
            +      "returns": "स्थिति टी पर बेज़ियर वक्र का मूल्य",
            +      "params": {
            +        "a": "Number: coordinate of first point on the curve",
            +        "b": "Number: coordinate of first control point",
            +        "c": "Number: coordinate of second control point",
            +        "d": "Number: coordinate of second point on the curve",
            +        "t": "Number: value between 0 and 1"
            +      }
            +    },
            +    "bezierTangent": {
            +      "description": [
            +        "A, B, C, D के लिए स्थितिी t पर बेज़ियर के स्पर्शरेखा का मूल्यांकन करता है। पैरामीटर A और D वक्र पर पहले और आखिरी बिंदु हैं, और B और D नियंत्रण बिंदु हैं। अंतिम पैरामीटर t के बीच भिन्न होता है 0 और 1।"
            +      ],
            +      "returns": "स्थिति में स्पर्शरेखा t",
            +      "params": {
            +        "a": "Number: coordinate of first point on the curve",
            +        "b": "Number: coordinate of first control point",
            +        "c": "Number: coordinate of second control point",
            +        "d": "Number: coordinate of second point on the curve",
            +        "t": "Number: value between 0 and 1"
            +      }
            +    },
            +    "curve": {
            +      "description": [
            +        "स्क्रीन पर दो बिंदुओं के बीच एक घुमावदार रेखा खींचता है, जिसे मध्य चार मापदंडों के रूप में दिया गया है। पहले दो पैरामीटर एक नियंत्रण बिंदु हैं, जैसे कि वक्र इस बिंदु से आया है, भले ही वह खींचा न गया हो। अंतिम दो पैरामीटर समान रूप से दूसरे का वर्णन करते हैं नियंत्रण बिंदु। <br /><br /> <a href=\"#/p5/curve\">curve()</a> कार्यों की श्रृंखला को एक साथ रखकर या <a href= \"#/p5/curveVertex\">curveVertex()</a>। एक अतिरिक्त फ़ंक्शन जिसे <a href=\"#/p5/curveTightness\">curveTightness()</a> कहा जाता है, की दृश्य गुणवत्ता के लिए नियंत्रण प्रदान करता है वक्र। <a href=\"#/p5/curve\">curve()</a> फ़ंक्शन Catmull-Rom splines का कार्यान्वयन है।"
            +      ],
            +      "params": {
            +        "x1": "Number: x-coordinate for the beginning control point",
            +        "y1": "Number: y-coordinate for the beginning control point",
            +        "x2": "Number: x-coordinate for the first point",
            +        "y2": "Number: y-coordinate for the first point",
            +        "x3": "Number: x-coordinate for the second point",
            +        "y3": "Number: y-coordinate for the second point",
            +        "x4": "Number: x-coordinate for the ending control point",
            +        "y4": "Number: y-coordinate for the ending control point",
            +        "z1": "Number: z-coordinate for the beginning control point",
            +        "z2": "Number: z-coordinate for the first point",
            +        "z3": "Number: z-coordinate for the second point",
            +        "z4": "Number: z-coordinate for the ending control point"
            +      }
            +    },
            +    "curveDetail": {
            +      "description": [
            +        "Sets the resolution at which curves display. The default value is 20 while the minimum value is 3.",
            +        "This function is only useful when using the WEBGL renderer as the default canvas renderer does not use this information."
            +      ],
            +      "params": {
            +        "resolution": "Number: resolution of the curves"
            +      }
            +    },
            +    "curveTightness": {
            +      "description": [
            +        "Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a> and <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness determines how the curve fits to the vertex points. The value 0.0 is the default value for tightness (this value defines the curves to be Catmull-Rom splines) and the value 1.0 connects all the points with straight lines. Values within the range -5.0 and 5.0 will deform the curves but will leave them recognizable and as values increase in magnitude, they will continue to deform."
            +      ],
            +      "params": {
            +        "amount": "Number: amount of deformation from the original vertices"
            +      }
            +    },
            +    "curvePoint": {
            +      "description": [
            +        "Evaluates the curve at position t for points a, b, c, d. The parameter t varies between 0 and 1, a and d are control points of the curve, and b and c are the start and end points of the curve. This can be done once with the x coordinates and a second time with the y coordinates to get the location of a curve at t."
            +      ],
            +      "returns": "p5 ऑब्जेक्ट",
            +      "params": {
            +        "a": "Number: coordinate of first control point of the curve",
            +        "b": "Number: coordinate of first point",
            +        "c": "Number: coordinate of second point",
            +        "d": "Number: coordinate of second control point",
            +        "t": "Number: value between 0 and 1"
            +      }
            +    },
            +    "curveTangent": {
            +      "description": [
            +        "Evaluates the tangent to the curve at position t for points a, b, c, d. The parameter t varies between 0 and 1, a and d are points on the curve, and b and c are the control points."
            +      ],
            +      "returns": "स्थिति में स्पर्शरेखा t",
            +      "params": {
            +        "a": "Number: coordinate of first control point",
            +        "b": "Number: coordinate of first point on the curve",
            +        "c": "Number: coordinate of second point on the curve",
            +        "d": "Number: coordinate of second conrol point",
            +        "t": "Number: value between 0 and 1"
            +      }
            +    },
            +    "beginContour": {
            +      "description": [
            +        "नकारात्मक बनाने के लिए <a href=\"#/p5/beginContour\">beginContour()</a> और <a href=\"#/p5/endContour\">endContour()</a> फ़ंक्शन का उपयोग करें अक्षर 'O' के केंद्र जैसे आकार के भीतर आकार। <a href=\"#/p5/beginContour\">beginContour()</a> आकृति के लिए शीर्षों को रिकॉर्ड करना शुरू करता है और <a href=\"#/ p5/endContour\">endContour()</a> रिकॉर्डिंग बंद कर देता है। ऋणात्मक आकार को परिभाषित करने वाले शीर्षों को बाहरी आकार से विपरीत दिशा में \"wind\" होना चाहिए। पहले बाहरी दक्षिणावर्त क्रम के लिए शीर्ष बनाएं, फिर आंतरिक के लिए आकृतियाँ, वामावर्त में शीर्ष आकृतियाँ बनाएँ।",
            +        "इन कार्यों का उपयोग केवल <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> में किया जा सकता है। जोड़ी और रूपांतरण जैसे <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a> , और <a href=\"#/p5/scale\">scale()</a> एक <a href=\"#/p5/beginContour\">beginContour()</a>/ के भीतर काम नहीं करते हैं <a href=\"#/p5/endContour\">endContour()</a> जोड़ी। अन्य आकृतियों का उपयोग करना भी संभव नहीं है, जैसे कि <a href=\"#/p5/ellipse\">ellipse ()</a> या <a href=\"#/p5/rect\">rect()</a> भीतर।"
            +      ]
            +    },
            +    "beginShape": {
            +      "description": [
            +        "<a href=\"#/p5/beginShape\">beginShape()</a> और <a href=\"#/p5/endShape\">endShape()</a> फ़ंक्शन का उपयोग करने से और अधिक निर्माण करने की अनुमति मिलती है जटिल रूप। <a href=\"#/p5/beginShape\">beginShape()</a> एक आकृति के लिए शीर्षों को रिकॉर्ड करना शुरू करता है और <a href=\"#/p5/endShape\">endShape()</a> रिकॉर्डिंग बंद कर देता है। प्रकार के पैरामीटर का मान यह बताता है कि दिए गए शीर्षों से किस प्रकार की आकृतियाँ बनानी हैं। बिना किसी विधा के निर्दिष्ट किए, आकार कोई भी अनियमित बहुभुज हो सकता है।",
            +        "<a href=\"#/p5/beginShape\">beginShape()</a> के लिए उपलब्ध पैरामीटर POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, QUAD_STRIP, और TESS (केवल WebGL) हैं। कॉल करने के बाद <a href=\"#/p5/beginShape\">beginShape()</a> फ़ंक्शन, <a href=\"#/p5/vertex\">vertex()</a> कमांड की एक श्रृंखला होनी चाहिए अनुसरण करें। आकृति बनाना बंद करने के लिए, <a href=\"#/p5/endShape\">endShape()</a> पर कॉल करें। प्रत्येक आकृति को वर्तमान स्ट्रोक रंग से रेखांकित किया जाएगा और भरण रंग से भरा जाएगा।",
            +        "रूपांतरण जैसे <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, और <a href=\"#/p5/scale\">scale()</a> <a href=\"#/p5/beginShape\">beginShape()</a> के भीतर काम नहीं करते। यह भी नहीं है अन्य आकृतियों का उपयोग करना संभव है, जैसे कि <a href=\"#/p5/ellipse\">ellipse()</a> या <a href=\"#/p5/rect\">rect()</a > के भीतर <a href=\"#/p5/beginShape\">beginShape()</a>।",
            +        "LINES Draw a series of unconnected line segments (individual lines)",
            +        "TRIANGLES Draw a series of separate triangles",
            +        "TRIANGLE_FAN Draw a series of connected triangles sharing the first vertex in a fan-like fashion",
            +        "TRIANGLE_STRIP Draw a series of connected triangles in strip fashion",
            +        "QUADS Draw a series of seperate quad",
            +        "QUAD_STRIP Draw quad strip using adjacent edges to form the next quad",
            +        "TESS (WebGl only) Handle irregular polygon for filling curve by explicit tessellation",
            +        "After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop drawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the current stroke color and filled with the fill color.",
            +        "Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "kind": "Constant: (Optional) either POINTS, LINES, TRIANGLES, TRIANGLE_FAN  TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS"
            +      }
            +    },
            +    "bezierVertex": {
            +      "description": [
            +        "बेज़ियर कर्व्स के लिए वर्टेक्स निर्देशांक निर्दिष्ट करता है। bezierVertex() के लिए प्रत्येक कॉल दो नियंत्रण बिंदुओं की स्थिति और एक बेज़ियर वक्र के एक एंकर पॉइंट को परिभाषित करता है, एक लाइन या आकार में एक नया सेगमेंट जोड़ता है। वेबजीएल मोड के लिए bezierVertex() में इस्तेमाल किया जा सकता है 2डी और साथ ही 3डी मोड। 2डी मोड 6 पैरामीटर की अपेक्षा करता है, जबकि 3डी मोड 9 पैरामीटर (जेड निर्देशांक सहित) की अपेक्षा करता है।",
            +        "पहली बार bezierVertex() का उपयोग <a href=\"#/p5/beginShape\">beginShape()</a> कॉल के भीतर किया जाता है, इसे <a href=\"#/ पहला एंकर बिंदु सेट करने के लिए p5/vertex\">vertex()</a>। इस फ़ंक्शन का उपयोग <a href=\"#/p5/beginShape\">beginShape()</a> और <a के बीच किया जाना चाहिए href=\"#/p5/endShape\">endShape()</a> और केवल तभी जब <a href=\"#/p5/beginShape\">beginShape()</ में निर्दिष्ट कोई MODE या POINTS पैरामीटर न हो। ए>।"
            +      ],
            +      "params": {
            +        "x2": "Number: x-coordinate for the first control point",
            +        "y2": "Number: y-coordinate for the first control point",
            +        "x3": "Number: x-coordinate for the second control point",
            +        "y3": "Number: y-coordinate for the second control point",
            +        "x4": "Number: x-coordinate for the anchor point",
            +        "y4": "Number: y-coordinate for the anchor point",
            +        "z2": "Number: z-coordinate for the first control point (for WebGL mode)",
            +        "z3": "Number: z-coordinate for the second control point (for WebGL mode)",
            +        "z4": "Number: z-coordinate for the anchor point (for WebGL mode)"
            +      }
            +    },
            +    "curveVertex": {
            +      "description": [
            +        "वक्र के लिए शीर्ष निर्देशांक निर्दिष्ट करता है। इस फ़ंक्शन का उपयोग केवल <a href=\"#/p5/beginShape\">beginShape()</a> और <a href=\"#/p5/endShape\"> endShape()</a>के बीच किया जा सकता है और केवल तभी जब <a href=\"#/p5/beginShape\">beginShape()</a> के लिए निर्दिष्ट कोई मोड पैरामीटर न हो। WebGL मोड के लिए curveVertex() का उपयोग 2D में किया जा सकता है साथ ही 3D मोड। 2D मोड 2 पैरामीटर की अपेक्षा करता है, जबकि 3D मोड 3 पैरामीटर की अपेक्षा करता है।",
            +        "वक्र की शुरुआत और अंत को निर्देशित करने के लिए curveVertex() लाइनों की एक श्रृंखला में पहले और अंतिम बिंदुओं का उपयोग किया जाएगा। दूसरे और तीसरे बिंदुओं के बीच एक छोटा वक्र खींचने के लिए न्यूनतम चार बिंदुओं की आवश्यकता होती है। पांचवां जोड़ना curveVertex() के साथ बिंदु दूसरे, तीसरे और चौथे बिंदुओं के बीच वक्र खींचेगा। curveVertex() फ़ंक्शन कैटमुल-रोम स्प्लिन का कार्यान्वयन है।"
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the vertex",
            +        "y": "Number: y-coordinate of the vertex",
            +        "z": "Number: (Optional) z-coordinate of the vertex (for WebGL mode)"
            +      }
            +    },
            +    "endContour": {
            +      "description": [
            +        "ऋण बनाने के लिए <a href=\"#/p5/beginContour\">beginContour()</a> और <a href=\"#/p5/endContour\">endContour()</a> फ़ंक्शन का उपयोग करें अक्षर 'O' के केंद्र जैसे आकार के भीतर आकार। <a href=\"#/p5/beginContour\">beginContour()</a> आकृति के लिए शीर्षों को रिकॉर्ड करना शुरू करता है और <a href=\"#/ p5/endContour\">endContour()</a> रिकॉर्डिंग बंद कर देता है। ऋणात्मक आकार को परिभाषित करने वाले शीर्षों को बाहरी आकार से विपरीत दिशा में \"wind\" होना चाहिए। पहले बाहरी दक्षिणावर्त क्रम के लिए कोने बनाएं, फिर आंतरिक के लिए आकृतियाँ, वामावर्त में शीर्ष आकृतियाँ बनाएँ।",
            +        "इन कार्यों का उपयोग केवल <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> में किया जा सकता है। जोड़ी और रूपांतरण जैसे <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a> , और <a href=\"#/p5/scale\">scale()</a> एक <a href=\"#/p5/beginContour\">beginContour()</a>/ के भीतर काम नहीं करते हैं <a href=\"#/p5/endContour\">endContour()</a> जोड़ी। अन्य आकृतियों का उपयोग करना भी संभव नहीं है, जैसे कि <a href=\"#/p5/ellipse\">ellipse ()</a> या <a href=\"#/p5/rect\">rect()</a> भीतर।"
            +      ]
            +    },
            +    "endShape": {
            +      "description": [
            +        "<a href=\"#/p5/endShape\">endShape()</a> फ़ंक्शन <a href=\"#/p5/beginShape\">beginShape()</a> का सहयोगी है और <a href=\"#/p5/beginShape\">beginShape()</a> के बाद ही कॉल किया जा सकता है। जब <a href=\"#/p5/endshape\">endShape()</a> है कहा जाता है, पिछली कॉल के बाद से परिभाषित सभी छवि डेटा <a href=\"#/p5/beginShape\">beginShape()</a> को छवि बफर में लिखा जाता है। मोड पैरामीटर के मान के रूप में स्थिर बंद करें आकृति को बंद करने के लिए (शुरुआत और अंत को जोड़ने के लिए)।"
            +      ],
            +      "params": {
            +        "mode": "Constant: (Optional) use CLOSE to close the shape"
            +      }
            +    },
            +    "quadraticVertex": {
            +      "description": [
            +        "द्विघात बेज़ियर वक्रों के लिए शीर्ष निर्देशांक निर्दिष्ट करता है। quadraticVertex() के लिए प्रत्येक कॉल एक नियंत्रण बिंदु और एक Bezier वक्र के एक एंकर बिंदु की स्थिति को परिभाषित करता है, एक रेखा या आकार में एक नया खंड जोड़ता है। पहली बार quadraticVertex() का उपयोग किया जाता है एक <a href=\"#/p5/beginShape\">beginShape()</a> कॉल, इसे <a href=\"#/p5/vertex\">vertex()</a>पर कॉल के साथ पहले से तैयार किया जाना चाहिए पहला एंकर पॉइंट सेट करने के लिए। WebGL मोड के लिए quadraticVertex() का उपयोग 2D के साथ-साथ 3D मोड में भी किया जा सकता है। 2D मोड 4 पैरामीटर की अपेक्षा करता है, जबकि 3D मोड 6 पैरामीटर (z निर्देशांक सहित) की अपेक्षा करता है।",
            +        "इस फ़ंक्शन का उपयोग <a href=\"#/p5/beginShape\">beginShape()</a> और <a href=\"#/p5/endShape\">endShape()</a> के बीच किया जाना चाहिए और केवल तभी जब <a href=\"#/p5/beginShape\">beginShape()</a> में निर्दिष्ट कोई मोड या POINTS पैरामीटर न हो।"
            +      ],
            +      "params": {
            +        "cx": "Number: x-coordinate for the control point",
            +        "cy": "Number: y-coordinate for the control point",
            +        "x3": "Number: x-coordinate for the anchor point",
            +        "y3": "Number: y-coordinate for the anchor point",
            +        "cz": "Number: z-coordinate for the control point (for WebGL mode)",
            +        "z3": "Number: z-coordinate for the anchor point (for WebGL mode)"
            +      }
            +    },
            +    "vertex": {
            +      "description": [
            +        "सभी आकृतियों का निर्माण शीर्षों की एक श्रृंखला को जोड़कर किया जाता है। <a href=\"#/p5/vertex\">vertex()</a> का उपयोग बिंदुओं, रेखाओं, त्रिभुजों, चतुर्भुज और के लिए शीर्ष निर्देशांक निर्दिष्ट करने के लिए किया जाता है। बहुभुज। इसका उपयोग विशेष रूप से <a href=\"#/p5/beginShape\">beginShape()</a> और <a href=\"#/p5/endShape\">endShape()</a> में किया जाता है कार्य।"
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the vertex",
            +        "y": "Number: y-coordinate of the vertex",
            +        "z": "Number: z-coordinate of the vertex.  Defaults to 0 if not specified.",
            +        "u": "Number: the vertex's texture u-coordinate",
            +        "v": "Number: the vertex's texture v-coordinate"
            +      }
            +    },
            +    "normal": {
            +      "description": [
            +        "Sets the 3d vertex normal to use for subsequent vertices drawn with <a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally nearly perpendicular to a shape's surface which controls how much light will be reflected from that part of the surface."
            +      ],
            +      "params": {
            +        "vector": "Vector: A p5.Vector representing the vertex normal.",
            +        "x": "Number: The x component of the vertex normal.",
            +        "y": "Number: The y component of the vertex normal.",
            +        "z": "Number: The z component of the vertex normal."
            +      }
            +    },
            +    "VERSION": {
            +      "description": [
            +        "Version of this p5.js."
            +      ]
            +    },
            +    "P2D": {
            +      "description": [
            +        "The default, two-dimensional renderer."
            +      ]
            +    },
            +    "WEBGL": {
            +      "description": [
            +        "One of the two render modes in p5.js: P2D (default renderer) and WEBGL Enables 3D render by introducing the third dimension: Z"
            +      ]
            +    },
            +    "ARROW": {},
            +    "CROSS": {},
            +    "HAND": {},
            +    "MOVE": {},
            +    "TEXT": {},
            +    "WAIT": {},
            +    "HALF_PI": {
            +      "description": [
            +        "HALF_PI is a mathematical constant with the value 1.57079632679489661923. It is half the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "PI": {
            +      "description": [
            +        "PI is a mathematical constant with the value 3.14159265358979323846. It is the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "QUARTER_PI": {
            +      "description": [
            +        "QUARTER_PI is a mathematical constant with the value 0.7853982. It is one quarter the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "TAU": {
            +      "description": [
            +        "TAU is an alias for TWO_PI, a mathematical constant with the value 6.28318530717958647693. It is twice the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "TWO_PI": {
            +      "description": [
            +        "TWO_PI is a mathematical constant with the value 6.28318530717958647693. It is twice the ratio of the circumference of a circle to its diameter. It is useful in combination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "DEGREES": {
            +      "description": [
            +        "Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which p5.js interprets and calculates angles (either DEGREES or RADIANS)."
            +      ]
            +    },
            +    "RADIANS": {
            +      "description": [
            +        "Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which p5.js interprets and calculates angles (either RADIANS or DEGREES)."
            +      ]
            +    },
            +    "CORNER": {},
            +    "CORNERS": {},
            +    "RADIUS": {},
            +    "RIGHT": {},
            +    "LEFT": {},
            +    "CENTER": {},
            +    "TOP": {},
            +    "BOTTOM": {},
            +    "BASELINE": {},
            +    "POINTS": {},
            +    "LINES": {},
            +    "LINE_STRIP": {},
            +    "LINE_LOOP": {},
            +    "TRIANGLES": {},
            +    "TRIANGLE_FAN": {},
            +    "TRIANGLE_STRIP": {},
            +    "QUADS": {},
            +    "QUAD_STRIP": {},
            +    "TESS": {},
            +    "CLOSE": {},
            +    "OPEN": {},
            +    "CHORD": {},
            +    "PIE": {},
            +    "PROJECT": {},
            +    "SQUARE": {},
            +    "ROUND": {},
            +    "BEVEL": {},
            +    "MITER": {},
            +    "RGB": {},
            +    "HSB": {
            +      "description": [
            +        "HSB (hue, saturation, brightness) is a type of color model. You can learn more about it at <a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>."
            +      ]
            +    },
            +    "HSL": {},
            +    "AUTO": {
            +      "description": [
            +        "AUTO allows us to automatically set the width or height of an element (but not both), based on the current height and width of the element. Only one parameter can be passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time."
            +      ]
            +    },
            +    "ALT": {},
            +    "BACKSPACE": {},
            +    "CONTROL": {},
            +    "DELETE": {},
            +    "DOWN_ARROW": {},
            +    "ENTER": {},
            +    "ESCAPE": {},
            +    "LEFT_ARROW": {},
            +    "OPTION": {},
            +    "RETURN": {},
            +    "RIGHT_ARROW": {},
            +    "SHIFT": {},
            +    "TAB": {},
            +    "UP_ARROW": {},
            +    "BLEND": {},
            +    "REMOVE": {},
            +    "ADD": {},
            +    "DARKEST": {},
            +    "LIGHTEST": {},
            +    "DIFFERENCE": {},
            +    "SUBTRACT": {},
            +    "EXCLUSION": {},
            +    "MULTIPLY": {},
            +    "SCREEN": {},
            +    "REPLACE": {},
            +    "OVERLAY": {},
            +    "HARD_LIGHT": {},
            +    "SOFT_LIGHT": {},
            +    "DODGE": {},
            +    "BURN": {},
            +    "THRESHOLD": {},
            +    "GRAY": {},
            +    "OPAQUE": {},
            +    "INVERT": {},
            +    "POSTERIZE": {},
            +    "DILATE": {},
            +    "ERODE": {},
            +    "BLUR": {},
            +    "NORMAL": {},
            +    "ITALIC": {},
            +    "BOLD": {},
            +    "BOLDITALIC": {},
            +    "CHAR": {},
            +    "WORD": {},
            +    "LINEAR": {},
            +    "QUADRATIC": {},
            +    "BEZIER": {},
            +    "CURVE": {},
            +    "STROKE": {},
            +    "FILL": {},
            +    "TEXTURE": {},
            +    "IMMEDIATE": {},
            +    "IMAGE": {},
            +    "NEAREST": {},
            +    "REPEAT": {},
            +    "CLAMP": {},
            +    "MIRROR": {},
            +    "LANDSCAPE": {},
            +    "PORTRAIT": {},
            +    "GRID": {},
            +    "AXES": {},
            +    "LABEL": {},
            +    "FALLBACK": {},
            +    "print": {
            +      "description": [
            +        "The <a href=\"#/p5/print\">print()</a> function writes to the console area of your browser. This function is often helpful for looking at the data a program is producing. This function creates a new line of text for each call to the function. Individual elements can be separated with quotes (\"\") and joined with the addition operator (+).",
            +        "Note that calling print() without any arguments invokes the window.print() function which opens the browser's print dialog. To print a blank line to console you can write print('\\n')."
            +      ],
            +      "params": {
            +        "contents": "Any: any combination of Number, String, Object, Boolean,  Array to print"
            +      }
            +    },
            +    "frameCount": {
            +      "description": [
            +        "The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the number of frames that have been displayed since the program started. Inside <a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration of draw it is 1, etc."
            +      ]
            +    },
            +    "deltaTime": {
            +      "description": [
            +        "The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time difference between the beginning of the previous frame and the beginning of the current frame in milliseconds.",
            +        "This variable is useful for creating time sensitive animation or physics calculation that should stay constant regardless of frame rate."
            +      ]
            +    },
            +    "focused": {
            +      "description": [
            +        "Confirms if the window a p5.js program is in is \"focused,\" meaning that the sketch will accept mouse or keyboard input. This variable is \"true\" if the window is focused and \"false\" if not."
            +      ]
            +    },
            +    "cursor": {
            +      "description": [
            +        "Sets the cursor to a predefined symbol or an image, or makes it visible if already hidden. If you are trying to set an image as the cursor, the recommended size is 16x16 or 32x32 pixels. The values for parameters x and y must be less than the dimensions of the image."
            +      ],
            +      "params": {
            +        "type": "String|Constant: Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT  Native CSS properties: 'grab', 'progress', 'cell' etc.  External: path for cursor's images  (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)  For more information on Native CSS cursors and url visit:  <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a>",
            +        "x": "Number: (Optional) the horizontal active spot of the cursor (must be less than 32)",
            +        "y": "Number: (Optional) the vertical active spot of the cursor (must be less than 32)"
            +      }
            +    },
            +    "frameRate": {
            +      "description": [
            +        "प्रत्येक सेकंड में प्रदर्शित होने वाले फ़्रेमों की संख्या निर्दिष्ट करता है। उदाहरण के लिए, फ़ंक्शन कॉल frameRate(30) एक सेकंड में 30 बार ताज़ा करने का प्रयास करेगा। यदि प्रोसेसर निर्दिष्ट दर को बनाए रखने के लिए पर्याप्त तेज़ नहीं है, तो फ़्रेम दर नहीं होगी हासिल किया। फ्रेम दर को <a href=\"#/p5/setup\">setup()</a> के भीतर सेट करने की अनुशंसा की जाती है। डिफ़ॉल्ट फ्रेम दर प्रदर्शन की फ्रेम दर पर आधारित होती है (यहां इसे \" भी कहा जाता है) ताज़ा दर\"), जो अधिकांश कंप्यूटरों पर 60 फ़्रेम प्रति सेकंड पर सेट है। 24 फ़्रेम प्रति सेकंड (फ़िल्मों के लिए सामान्य) या इससे अधिक की फ़्रेम दर सुचारू एनिमेशन के लिए पर्याप्त होगी। यह setFrameRate(val) के समान है।",
            +        "कॉलिंग <a href=\"#/p5/frameRate\">frameRate()</a> बिना किसी तर्क के वर्तमान फ्रैमरेट लौटाती है। ड्रा फ़ंक्शन को मान वापस करने से पहले कम से कम एक बार चलना चाहिए। यह वही है <a href=\"#/p5/getFrameRate\">getFrameRate()</a> के रूप में।",
            +        "<a href=\"#/p5/frameRate\">frameRate()</a> को ऐसे तर्कों के साथ कॉल करना जो संख्याओं के प्रकार के नहीं हैं या जो सकारात्मक नहीं हैं, वर्तमान फ्रैमरेट भी लौटाते हैं।"
            +      ],
            +      "params": {
            +        "fps": "Number: number of frames to be displayed every second"
            +      }
            +    },
            +    "noCursor": {
            +      "description": [
            +        "Hides the cursor from view."
            +      ]
            +    },
            +    "displayWidth": {
            +      "description": [
            +        "सिस्टम वैरिएबल जो डिफ़ॉल्ट <a href=\"#/p5/pixelDensity\">pixelDensity</a> के अनुसार स्क्रीन डिस्प्ले की चौड़ाई को स्टोर करता है। इसका उपयोग किसी भी डिस्प्ले साइज पर फुल-स्क्रीन प्रोग्राम चलाने के लिए किया जाता है। वास्तविक स्क्रीन आकार वापस करने के लिए, इसे पिक्सेल घनत्व से गुणा करें।"
            +      ]
            +    },
            +    "displayHeight": {
            +      "description": [
            +        "सिस्टम वैरिएबल जो डिफ़ॉल्ट <a href=\"#/p5/pixelDensity\">pixelDensity</a> के अनुसार स्क्रीन डिस्प्ले की ऊंचाई को स्टोर करता है। इसका उपयोग किसी भी डिस्प्ले साइज पर फुल-स्क्रीन प्रोग्राम चलाने के लिए किया जाता है। वास्तविक स्क्रीन आकार वापस करने के लिए, इसे पिक्सेल घनत्व से गुणा करें।"
            +      ]
            +    },
            +    "windowWidth": {
            +      "description": [
            +        "System variable that stores the width of the inner window, it maps to window.innerWidth."
            +      ]
            +    },
            +    "windowHeight": {
            +      "description": [
            +        "System variable that stores the height of the inner window, it maps to window.innerHeight."
            +      ]
            +    },
            +    "windowResized": {
            +      "description": [
            +        "<a href=\"#/p5/windowResized\">windowResized()</a> फ़ंक्शन हर बार ब्राउज़र विंडो का आकार बदलने पर एक बार कॉल किया जाता है। कैनवास का आकार बदलने या इसके लिए कोई अन्य समायोजन करने के लिए यह एक अच्छी जगह है नई विंडो के आकार को समायोजित करें।"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional Event callback argument."
            +      }
            +    },
            +    "width": {
            +      "description": [
            +        "सिस्टम वैरिएबल जो ड्रॉइंग कैनवास की चौड़ाई को स्टोर करता है। यह मान <a href=\"#/p5/createCanvas\">createCanvas()</a> फ़ंक्शन के पहले पैरामीटर द्वारा सेट किया गया है। उदाहरण के लिए, फ़ंक्शन कॉल createCanvas(320, 240) चौड़ाई चर को मान 320 पर सेट करता है। चौड़ाई का मान डिफ़ॉल्ट रूप से 100 हो जाता है यदि <a href=\"#/p5/createCanvas\">createCanvas()</a> का उपयोग नहीं किया जाता है कार्यक्रम।"
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "सिस्टम वैरिएबल जो ड्राइंग कैनवास की ऊंचाई को स्टोर करता है। यह मान <a href=\"#/p5/createCanvas\">createCanvas()</a> फ़ंक्शन के दूसरे पैरामीटर द्वारा सेट किया गया है। उदाहरण के लिए, फ़ंक्शन कॉल createCanvas(320, 240) ऊंचाई चर को 240 मान पर सेट करता है। ऊंचाई का मान डिफ़ॉल्ट रूप से 100 हो जाता है यदि <a href=\"#/p5/createCanvas\">createCanvas()</a> का उपयोग नहीं किया जाता है कार्यक्रम।"
            +      ]
            +    },
            +    "fullscreen": {
            +      "description": [
            +        "यदि तर्क दिया गया है, तो तर्क के मूल्य के आधार पर स्केच को पूर्णस्क्रीन पर सेट करता है या नहीं। यदि कोई तर्क नहीं दिया जाता है, तो वर्तमान पूर्णस्क्रीन स्थिति लौटाता है। ध्यान दें कि ब्राउज़र प्रतिबंधों के कारण इसे केवल उपयोगकर्ता इनपुट पर ही कॉल किया जा सकता है, उदाहरण के लिए , माउस प्रेस पर नीचे दिए गए उदाहरण की तरह।"
            +      ],
            +      "returns": "बूलियन: वर्तमान पूर्ण स्क्रीन स्थिति",
            +      "params": {
            +        "val": "Boolean: (Optional) whether the sketch should be in fullscreen mode or not"
            +      }
            +    },
            +    "pixelDensity": {
            +      "description": [
            +        "उच्च पिक्सेल घनत्व डिस्प्ले के लिए पिक्सेल स्केलिंग सेट करता है। डिफ़ॉल्ट रूप से पिक्सेल घनत्व प्रदर्शन घनत्व से मेल खाने के लिए सेट होता है, इसे बंद करने के लिए पिक्सेल घनत्व (1) पर कॉल करें। <a href=\"#/p5/pixelDensity\">pixelDensity() </a>पर कॉल करना बिना किसी तर्क के स्केच का वर्तमान पिक्सेल घनत्व लौटाता है।"
            +      ],
            +      "params": {
            +        "val": "Number: whether or how much the sketch should scale"
            +      }
            +    },
            +    "displayDensity": {
            +      "description": [
            +        "Returns the pixel density of the current display the sketch is running on."
            +      ],
            +      "returns": "संख्या: मॉनिटर की वर्तमान पिक्सेल घनत्व"
            +    },
            +    "getURL": {
            +      "description": [
            +        "Gets the current URL. Note: when using the p5 Editor, this will return an empty object because the sketch is embedded in an iframe. It will work correctly if you view the sketch using the editor's present or share URLs."
            +      ],
            +      "returns": "स्ट्रिंग: URL"
            +    },
            +    "getURLPath": {
            +      "description": [
            +        "Gets the current URL path as an array. Note: when using the p5 Editor, this will return an empty object because the sketch is embedded in an iframe. It will work correctly if you view the sketch using the editor's present or share URLs."
            +      ],
            +      "returns": "फिक्स: पते के घटक"
            +    },
            +    "getURLParams": {
            +      "description": [
            +        "Gets the current URL params as an Object. Note: when using the p5 Editor, this will return an empty object because the sketch is embedded in an iframe. It will work correctly if you view the sketch using the editor's present or share URLs."
            +      ],
            +      "returns": "ऑब्जेक्ट: URL पैरामीटर"
            +    },
            +    "preload": {
            +      "description": [
            +        "<a href=\"#/p5/setup\">setup()</a> से पहले सीधे कॉल किया जाता है, <a href=\"#/p5/preload\">preload()</a> फ़ंक्शन है अवरुद्ध तरीके से बाहरी फ़ाइलों के एसिंक्रोनस लोडिंग को संभालने के लिए उपयोग किया जाता है। यदि एक प्रीलोड फ़ंक्शन परिभाषित किया गया है, तो <a href=\"#/p5/setup\">setup()</a> तब तक प्रतीक्षा करेगा जब तक कि कोई भी लोड कॉल समाप्त न हो जाए . लोड कॉल के अलावा कुछ नहीं (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href= \"#/p5/loadFont\">loadFont</a>, <a href=\"#/p5/loadStrings\">loadStrings</a>, आदि) प्रीलोड फ़ंक्शन के अंदर होना चाहिए। यदि एसिंक्रोनस लोडिंग है पसंदीदा, लोड विधियों को इसके बजाय <a href=\"#/p5/setup\">setup()</a> या कहीं भी कॉलबैक पैरामीटर के उपयोग के साथ कॉल किया जा सकता है।",
            +        "डिफ़ॉल्ट रूप से पाठ \"loading...\" प्रदर्शित किया जाएगा। अपना स्वयं का लोडिंग पृष्ठ बनाने के लिए, अपने पृष्ठ में आईडी \"p5_loading\" के साथ एक HTML तत्व शामिल करें। अधिक जानकारी <a href=\"http:/ /bit.ly/2kQ6Nio\">यहां</a>।"
            +      ]
            +    },
            +    "setup": {
            +      "description": [
            +        "<a href=\"#/p5/setup\">setup()</a> फ़ंक्शन को प्रोग्राम शुरू होने पर एक बार कॉल किया जाता है। इसका उपयोग प्रारंभिक पर्यावरण गुणों जैसे स्क्रीन आकार और पृष्ठभूमि रंग को परिभाषित करने और मीडिया लोड करने के लिए किया जाता है जैसे कि प्रोग्राम शुरू होने पर इमेज और फोंट। प्रत्येक प्रोग्राम के लिए केवल एक <a href=\"#/p5/setup\">setup()</a> फ़ंक्शन हो सकता है और इसे इसके बाद फिर से कॉल नहीं किया जाना चाहिए प्रारंभिक निष्पादन।",
            +        "ध्यान दें: <a href=\"#/p5/setup\">setup()</a> के अंतर्गत घोषित वैरिएबल <a href=\"#/p5/draw\">draw()</a> सहित अन्य कार्यों में पहुंच योग्य नहीं हैं।"
            +      ]
            +    },
            +    "draw": {
            +      "description": [
            +        "<a href=\"#/p5/setup\">setup()</a> के बाद सीधे कॉल किया जाता है, <a href=\"#/p5/draw\">draw()</a> लगातार काम करता है प्रोग्राम के बंद होने तक या <a href=\"#/p5/noLoop\">noLoop()</a> कॉल किए जाने तक अपने ब्लॉक के अंदर निहित कोड की पंक्तियों को निष्पादित करता है। नोट करें यदि <a href=\"#/p5 /noLoop\">noLoop()</a> को <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> में कॉल किया जाता है। रुकने से पहले एक बार निष्पादित किया जाएगा। <a href=\"#/p5/draw\">draw()</a> स्वचालित रूप से कॉल किया जाता है और इसे स्पष्ट रूप से कभी नहीं कहा जाना चाहिए।",
            +        "इसे हमेशा <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> से नियंत्रित किया जाना चाहिए और <a href=\"#/p5/loop\">loop()</a>। <a href=\"#/p5/noLoop\">noLoop()</a> के बाद कोड को में बंद कर देता है। <a href=\"#/p5/draw\">draw()</a> क्रियान्वित होने से, <a href=\"#/p5/redraw\">redraw()</a> कोड को <a href=\"#/p5/draw\">draw()</a> एक बार निष्पादित करने के लिए, और <a href=\"#/p5/loop\">loop()</a> कोड को अंदर कर देगा <a href=\"#/p5/draw\">draw()</a> लगातार क्रियान्वित करना फिर से शुरू करने के लिए।",
            +        "प्रत्येक सेकंड में <a href=\"#/p5/draw\">draw()</a> निष्पादित होने की संख्या को <a href=\"#/p5/frameRate\">frameRate()</a> से नियंत्रित किया जा सकता है समारोह।",
            +        "प्रत्येक स्केच के लिए केवल एक <a href=\"#/p5/draw\">draw()</a> फ़ंक्शन हो सकता है, और <a href=\"#/p5/draw\">draw()</a>हो सकता है। मौजूद होना चाहिए यदि आप चाहते हैं कि कोड लगातार चलता रहे, या <a href=\"#/p5/mousePressed\">mousePressed()</a> जैसी घटनाओं को संसाधित करने के लिए। कभी-कभी, आपके पास एक खाली हो सकता है अपने प्रोग्राम में <a href=\"#/p5/draw\">draw()</a> पर कॉल करें, जैसा कि ऊपर दिए गए उदाहरण में दिखाया गया है।",
            +        "यह ध्यान रखना महत्वपूर्ण है कि ड्रॉइंग कोऑर्डिनेट सिस्टम प्रत्येक"
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the entire p5 sketch. This will remove the canvas and any elements created by p5.js. It will also stop the draw loop and unbind any properties or methods from the window global scope. It will leave a variable p5 in case you wanted to create a new p5 sketch. If you like, you can set p5 = null to erase it. While all functions and variables and objects created by the p5 library will be removed, any other global variables created by your code will remain."
            +      ]
            +    },
            +    "disableFriendlyErrors": {
            +      "description": [
            +        "Allows for the friendly error system (FES) to be turned off when creating a sketch, which can give a significant boost to performance when needed. See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'> disabling the friendly error system</a>."
            +      ]
            +    },
            +    "let": {
            +      "description": [
            +        "Creates and names a new variable. A variable is a container for a value.",
            +        "Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope. This means that the variable only exists within the <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> block</a> that it is created within.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>: Declares a block scope local variable, optionally initializing it to a value."
            +      ]
            +    },
            +    "const": {
            +      "description": [
            +        "Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>, a constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value, however constants cannot be reassigned once they are declared. Although it is noteworthy that for non-primitive data types like objects & arrays, their elements can still be changeable. So if a variable is assigned an array, you can still add or remove elements from the array but cannot reassign another array to it. Also unlike <code>let</code>, you cannot declare variables without value using const.",
            +        "Constants have block-scope. This means that the constant only exists within the <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> block</a> that it is created within. A constant cannot be redeclared within a scope in which it already exists.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>: Declares a read-only named constant. Constants are block-scoped, much like variables defined using the 'let' statement. The value of a constant can't be changed through reassignment, and it can't be redeclared."
            +      ]
            +    },
            +    "===": {
            +      "description": [
            +        "The strict equality operator <a href=\"#/p5/===\">===</a> checks to see if two values are equal and of the same type. ",
            +        "A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>. ",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>: The non-identity operator returns true if the operands are not equal and/or not of the same type. ",
            +        "Note: In some examples around the web you may see a double-equals-sign <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>, used for comparison instead. This is the non-strict equality operator in Javascript. This will convert the two values being compared to the same type before comparing them."
            +      ]
            +    },
            +    ">": {
            +      "description": [
            +        "The greater than operator <a href=\"#/p5/>\">></a> evaluates to true if the left value is greater than the right value. <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\"> There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    ">=": {
            +      "description": [
            +        "The greater than or equal to operator <a href=\"#/p5/>=\">>=</a> evaluates to true if the left value is greater than or equal to the right value. ",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "<": {
            +      "description": [
            +        "The less than operator <a href=\"#/p5/<\"><</a> evaluates to true if the left value is less than the right value. ",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "<=": {
            +      "description": [
            +        "The less than or equal to operator <a href=\"#/p5/<=\"><=</a> evaluates to true if the left value is less than or equal to the right value. ",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "if-else": {
            +      "description": [
            +        "The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.",
            +        "A condition is placed between the parenthesis following 'if', when that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>, the code between the following curly braces is run. Alternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>, the code between the curly braces of 'else' block is run instead. Writing an else block is optional.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>: The 'if' statement executes a statement if a specified condition is truthy. If the condition is falsy, another statement can be executed"
            +      ]
            +    },
            +    "function": {
            +      "description": [
            +        "Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>. A <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.",
            +        "Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a> are variables that are scoped to the function, that can be assigned a value when calling the function.Multiple parameters can be given by seperating them with commmas.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>: Declares a function with the specified parameters."
            +      ]
            +    },
            +    "return": {
            +      "description": [
            +        "Specifies the value to be returned by a function. For more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\"> the MDN entry for return</a>."
            +      ]
            +    },
            +    "boolean": {
            +      "description": [
            +        "Converts a number or string to its boolean representation. For a number, any non-zero value (positive or negative) evaluates to true, while zero evaluates to false. For a string, the value \"true\" evaluates to true, while any other value evaluates to false. When an array of number or string values is passed in, then a array of booleans of the same length is returned."
            +      ],
            +      "returns": "Boolean: boolean representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number|Array: value to parse"
            +      }
            +    },
            +    "string": {
            +      "description": [
            +        "A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript. A string is a series of text characters. In Javascript, a string value must be surrounded by either single-quotation marks(') or double-quotation marks(\").",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>: A string is a sequence of characters used to represent text."
            +      ]
            +    },
            +    "number": {
            +      "description": [
            +        "A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript. A number can be a whole number or a decimal number.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a>"
            +      ]
            +    },
            +    "object": {
            +      "description": [
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:  An <a href=\"#/p5/object\">object</a> is a collection of related data and/or  functionality (which usually consists of several variables and functions —  which are called properties and methods when they are inside objects.)"
            +      ]
            +    },
            +    "class": {
            +      "description": [
            +        "Creates and names a <a href=\"#/p5/class\">class</a> which is a template for the creation of <a href=\"#/p5/object\">objects</a>.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>: The class declaration creates a new Class with a given name using prototype-based inheritance."
            +      ]
            +    },
            +    "for": {
            +      "description": [
            +        "<a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one section of code multiple times.",
            +        "A 'for loop' consists of three different expressions inside of a parenthesis, all of which are optional.These expressions are used to control the number of times the loop is run.The first expression is a statement that is used to set the initial state for the loop.The second expression is a condition that you would like to check before each loop. If this expression returns false then the loop will exit.The third expression is executed at the end of each loop. These expression are separated by ; (semi-colon).In case of an empty expression, only a semi-colon is written.",
            +        "The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second and third expression.",
            +        "As with any loop, it is important to ensure that the loop can 'exit', or that the test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop is the second expression detailed above. Ensuring that this expression can eventually become false ensures that your loop doesn't attempt to run an infinite amount of times, which can crash your browser.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>: Creates a loop that executes a specified statement until the test condition evaluates to false. The condition is evaluated after executing the statement, resulting in the specified statement executing at least once."
            +      ]
            +    },
            +    "while": {
            +      "description": [
            +        "<a href=\"#/p5/while\">while</a> creates a loop that is useful for executing one section of code multiple times.",
            +        "With a 'while loop', the code inside of the loop body (between the curly braces) is run repeatedly until the test condition (inside of the parenthesis) evaluates to false. The condition is tested before executing the code body with <a href=\"#/p5/while\">while</a>, so if the condition is initially false the loop body, or statement, will never execute.",
            +        "As with any loop, it is important to ensure that the loop can 'exit', or that the test condition will eventually evaluate to false. This is to keep your loop from trying to run an infinite amount of times, which can crash your browser.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>: The while statement creates a loop that executes a specified statement as long as the test condition evaluates to true.The condition is evaluated before executing the statement."
            +      ]
            +    },
            +    "createCanvas": {
            +      "description": [
            +        "दस्तावेज़ में एक कैनवास तत्व बनाता है, और इसके आयामों को पिक्सेल में सेट करता है। इस विधि को सेटअप के प्रारंभ में केवल एक बार कॉल किया जाना चाहिए। <a href=\"#/p5/createCanvas\">createCanvas</a>को कॉल करना  एक स्केच में एक से अधिक बार बहुत अप्रत्याशित व्यवहार होगा। यदि आप एक से अधिक ड्राइंग कैनवास चाहते हैं तो आप <a href=\"#/p5/createGraphics\">createGraphics</a> का उपयोग कर सकते हैं (डिफ़ॉल्ट रूप से छिपा हुआ लेकिन यह दिखाया जा सकता है)।",
            +        "महत्वपूर्ण नोट: 2D मोड में (अर्थात जब <code>p5.Renderer</code> सेट नहीं है) मूल (0,0) स्क्रीन के ऊपर बाईं ओर स्थित है। 3D मोड में (अर्थात जब <code> p5.Renderer</code> <code>WEBGL</code> पर सेट है), मूल कैनवास के केंद्र में स्थित है। <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> अधिक जानकारी के लिए।",
            +        "सिस्टम चर की चौड़ाई और ऊंचाई इस फ़ंक्शन को दिए गए पैरामीटर द्वारा निर्धारित की जाती है। यदि <a href=\"#/p5/createCanvas\">createCanvas()</a> का उपयोग नहीं किया जाता है, तो विंडो को एक डिफ़ॉल्ट दिया जाएगा 100x100 पिक्सेल का आकार।",
            +        "कैनवास को स्थान देने के और तरीकों के लिए, <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'> कैनवस की स्थिति</a> विकी पृष्ठ देखें।"
            +      ],
            +      "returns": "ऑब्जेक्ट: उत्पन्न कैनवास",
            +      "params": {
            +        "w": "Number: width of the canvas",
            +        "h": "Number: height of the canvas",
            +        "renderer": "Constant: (Optional) either P2D or WEBGL"
            +      }
            +    },
            +    "resizeCanvas": {
            +      "description": [
            +        "Resizes the canvas to given width and height. The canvas will be cleared and draw will be called immediately, allowing the sketch to re-render itself in the resized canvas."
            +      ],
            +      "params": {
            +        "w": "Number: width of the canvas",
            +        "h": "Number: height of the canvas",
            +        "noRedraw": "Boolean: (Optional) don't redraw the canvas immediately"
            +      }
            +    },
            +    "noCanvas": {
            +      "description": [
            +        "Removes the default canvas for a p5 sketch that doesn't require a canvas"
            +      ]
            +    },
            +    "createGraphics": {
            +      "description": [
            +        "Creates and returns a new p5.Renderer object. Use this class if you need to draw into an off-screen graphics buffer. The two parameters define the width and height in pixels."
            +      ],
            +      "returns": "स्क्रीन पर ग्राफिक बफर",
            +      "params": {
            +        "w": "Number: width of the offscreen graphics buffer",
            +        "h": "Number: height of the offscreen graphics buffer",
            +        "renderer": "Constant: (Optional) either P2D or WEBGL  undefined defaults to p2d"
            +      }
            +    },
            +    "blendMode": {
            +      "description": [
            +        "डिस्प्ले विंडो में पिक्सल को परिभाषित मोड के अनुसार ब्लेंड करता है। सोर्स पिक्सल (ए) को डिस्प्ले विंडो में पहले से मौजूद पिक्सल के साथ ब्लेंड करने के लिए निम्नलिखित मोड का विकल्प है: <ul> <li> <code>BLEND</code> - रंगों का रैखिक प्रक्षेप: C = A*factor + B. <b>यह डिफ़ॉल्ट सम्मिश्रण मोड है।</b></li> <li><code>ADD</code > - A और B का योग</li> <li><code>डार्केस्ट</code> - केवल सबसे गहरा रंग सफल होता है: C = min(A*factor, B).</li> <li><code> सबसे हल्का</code> - केवल सबसे हल्का रंग सफल होता है: C = max(A*factor, B).</li> <li><code>DIFFERENCE</code> - अंतर्निहित छवि से रंगों को घटाएं।</li> < li><code>EXCLUSION</code> - <code>DIFFERENCE</code> के समान, लेकिन कम चरम।</li> <li><code>MULTIPLY</code> - रंगों को गुणा करें, परिणाम हमेशा होगा गहरा।</li> <li><code>SCREEN</code> - विपरीत गुणा, रंगों के व्युत्क्रम मानों का उपयोग करता है।</li> <li><code>REPLACE</code> - पिक्सल पूरी तरह से दूसरों की जगह लेते हैं और अल्फ़ा (पारदर्शिता) मानों का उपयोग न करें।</li> <li><code>REMOVE</code> - A के अल्फा स्ट्रेंथ के साथ B से पिक्सेल निकालता है।</li> <li><code>Overlay</code> - <code>MULTIPLY</code> का मिश्रण और <कोड>स्क्रीन </कोड>। डार्क वैल्यू को गुणा करता है, और लाइट वैल्यू को स्क्रीन करता है। <em>(2D)</em></li> <li><code>HARD_LIGHT</code> - <code>SCREEN</code> जब ५०% से अधिक ग्रे, <code>MULTIPLY</code> जब निचला। <em>(2D)</em></li> <li><code>SOFT_LIGHT</code> - <code>DARKEST</code> और <code>LIGHTEST</code> का मिश्रण। <code>OVERLAY</code> की तरह काम करता है, लेकिन उतना कठोर नहीं। <em>(2D)</em> </li> <li><code>DODGE</code> - हल्के टोन को हल्का करता है और कंट्रास्ट को बढ़ाता है, अंधेरे को नज़रअंदाज़ करता है। <em>(2D)</em></li> <li><code>BURN</code> - गहरे रंग के क्षेत्र लगाए जाते हैं, कंट्रास्ट को बढ़ाते हुए, रोशनी को नज़रअंदाज़ किया जाता है। <em>(2D)</em></li> <li><code>सबट्रैक्ट</code> - A और B के शेष <em>(3D)</em></li> </ul>",
            +        "<em>(2D)</em> इंगित करता है कि यह मिश्रण मोड <b>केवल</b> 2D रेंडरर में काम करता है। <em>(3D)</em> इंगित करता है कि यह मिश्रण मोड <b>केवल< /b> WEBGL रेंडरर में काम करता है।"
            +      ],
            +      "params": {
            +        "mode": "Constant: blend mode to set for canvas.  either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,  EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT"
            +      }
            +    },
            +    "drawingContext": {
            +      "description": [
            +        "The p5.js API provides a lot of functionality for creating graphics, but there is some native HTML5 Canvas functionality that is not exposed by p5. You can still call it directly using the variable <code>drawingContext</code>, as in the example shown. This is the equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>. See this <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\"> reference for the native canvas API</a> for possible drawing functions you can call."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "p5.js को <a href=\"#/p5/draw\">draw()</a> में लगातार कोड निष्पादित करने से रोकता है। यदि <a href=\"#/p5/loop\">loop()</a> को कॉल किया जाता है, <a href=\"#/p5/draw\">draw()</a> में कोड लगातार चलने लगता है। यदि <a href=\"#/p5/ noLoop\">noLoop()</a> <a href=\"#/p5/setup\">setup()</a> में, यह ब्लॉक के अंदर की आखिरी लाइन होनी चाहिए।",
            +        "जब <a href=\"#/p5/noLoop\">noLoop()</a> का उपयोग किया जाता है, तो <a href=\"#/p5 जैसे ईवेंट हैंडलिंग फ़ंक्शंस के अंदर स्क्रीन में हेरफेर या एक्सेस करना संभव नहीं है /mousePressed\">mousePressed()</a> या <a href=\"#/p5/keyPressed\">keyPressed()</a>। इसके बजाय, <a href=\"#/ p5/redraw\">redraw()</a> या <a href=\"#/p5/loop\">loop()</a>, जो <a href=\"#/p5/draw \">draw()</a> चलेगा, जो स्क्रीन को ठीक से अपडेट कर सकता है। इसका मतलब है कि जब <a href=\"#/p5/noLoop\">noLoop()</a> को कॉल किया गया है, तो कोई भी ड्रॉइंग नहीं कर सकता होता है, और <a href=\"#/p5/saveFrames\">saveFrames()</a> या <a href=\"#/p5/loadPixels\">loadPixels()</a> जैसे कार्य नहीं हो सकते हैं इस्तेमाल किया गया।",
            +        "ध्यान दें कि अगर स्केच का आकार बदला जाता है, तो <a href=\"#/p5/redraw\">redraw()</a> को स्केच को अपडेट करने के लिए <a href=\"#/p5/noLoop\">noLoop()</a>के बाद भी कॉल किया जाएगा। निर्दिष्ट किया गया है। अन्यथा, <a href=\"#/p5/loop\">loop()</a> को कॉल किए जाने तक स्केच एक विषम स्थिति में प्रवेश करेगा।",
            +        "loop() की वर्तमान स्थिति की जांच करने के लिए <a href=\"#/p5/isLooping\">isLooping()</a> का उपयोग करें।"
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "डिफ़ॉल्ट रूप से, p5.js draw() के माध्यम से लगातार लूप करता है, इसके भीतर कोड निष्पादित करता है। हालांकि, <a href=\"#/p5/draw\">draw()</a> लूप को कॉल करके रोका जा सकता है <a href=\"#/p5/noLoop\">noLoop()</a>। उस स्थिति में, <a href=\"#/p5/draw\">draw()</a> लूप कर सकते हैं loop() के साथ फिर से शुरू करें।",
            +        "अंदर के setup() से loop() को कॉल करने से बचें।",
            +        "loop() की वर्तमान स्थिति की जांच करने के लिए <a href=\"#/p5/isLooping\">isLooping()</a> का उपयोग करें।"
            +      ]
            +    },
            +    "isLooping": {
            +      "description": [
            +        "By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously, executing the code within it. If the sketch is stopped with <a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>, isLooping() returns the current state for use within custom event handlers."
            +      ]
            +    },
            +    "push": {
            +      "description": [
            +        "<a href=\"#/p5/push\">push()</a> फ़ंक्शन वर्तमान आरेखण शैली सेटिंग्स और परिवर्तनों को सहेजता है, जबकि <a href=\"#/p5/pop\">pop()</a> इन सेटिंग्स को पुनर्स्थापित करता है। ध्यान दें कि ये फ़ंक्शन हमेशा एक साथ उपयोग किए जाते हैं। वे आपको शैली और परिवर्तन सेटिंग्स को बदलने की अनुमति देते हैं और बाद में जो आपके पास था उस पर वापस लौटते हैं। जब एक नया राज्य शुरू होता है <a href=\"# /p5/push\">push()</a>, यह वर्तमान शैली पर आधारित है और जानकारी को रूपांतरित करता है। <a href=\"#/p5/push\">push()</a> और <a href=\"#/p5/pop\">pop()</a> अधिक नियंत्रण प्रदान करने के लिए कार्यों को एम्बेड किया जा सकता है। (प्रदर्शन के लिए दूसरा उदाहरण देखें।)",
            +        "<a href=\"#/p5/push\">push()</a> निम्नलिखित कार्यों द्वारा नियंत्रित वर्तमान परिवर्तन स्थिति और शैली सेटिंग्स से संबंधित जानकारी संग्रहीत करता है: <a href=\"#/p5/fill \">भरें()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke() </a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"# /p5/strokeCap\">strokeCap()</a>, <a href=\"#/p5/strokeJoin\">strokeJoin()</a>, <a href=\"#/p5/imageMode\" >imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href =\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5 /textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix ()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a>, <a href=\" #/p5/noiseSeed\">noiseSeed()</a>.",
            +        "WEBGL मोड में अतिरिक्त स्टाइल सेटिंग्स संग्रहीत की जाती हैं। इन्हें निम्नलिखित कार्यों द्वारा नियंत्रित किया जाता है: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ ambientLight\">ambientLight ()</a>, <a href=\"#/p5/directionLight\">directionLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">shininess()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> और <a href=\" #/p5/shader\">shader()</a>।"
            +      ]
            +    },
            +    "pop": {
            +      "description": [
            +        "<a href=\"#/p5/push\">push()</a> फ़ंक्शन वर्तमान आरेखण शैली सेटिंग्स और परिवर्तनों को सहेजता है, जबकि <a href=\"#/p5/pop\">pop()</a> इन सेटिंग्स को पुनर्स्थापित करता है। ध्यान दें कि ये फ़ंक्शन हमेशा एक साथ उपयोग किए जाते हैं। वे आपको शैली और परिवर्तन सेटिंग्स को बदलने की अनुमति देते हैं और बाद में जो आपके पास था उस पर वापस लौटते हैं। जब एक नया राज्य शुरू होता है <a href=\"# /p5/push\">push()</a>, यह वर्तमान शैली पर आधारित है और जानकारी को रूपांतरित करता है। <a href=\"#/p5/push\">push()</a> और <a href=\"#/p5/pop\">pop()</a> अधिक नियंत्रण प्रदान करने के लिए कार्यों को एम्बेड किया जा सकता है। (प्रदर्शन के लिए दूसरा उदाहरण देखें।)",
            +        "<a href=\"#/p5/push\">push()</a> निम्नलिखित कार्यों द्वारा नियंत्रित वर्तमान परिवर्तन स्थिति और शैली सेटिंग्स से संबंधित जानकारी संग्रहीत करता है: <a href=\"#/p5/fill \">भरें()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke() </a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"# /p5/स्ट्रोककैप\">स्ट्रोककैप()</a>, <a href=\"#/p5/stokeJoint\">strokeJoint()</a>, <a href=\"#/p5/imageMode\" >imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a> a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href =\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5 /textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix ()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a>, <a href=\" #/p5/noiseSeed\">noiseSeed()</a>.",
            +        "WEBGL मोड में अतिरिक्त स्टाइल सेटिंग्स संग्रहीत की जाती हैं। इन्हें निम्नलिखित कार्यों द्वारा नियंत्रित किया जाता है: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ ambientLight\">ambientLight()</a>, <a href=\"#/p5/directionLight\">directionLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">चमकता()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> और <a href=\" #/p5/shader\">shader()</a>।"
            +      ]
            +    },
            +    "redraw": {
            +      "description": [
            +        "कोड को एक बार <a href=\"#/p5/draw\">draw()</a> के भीतर निष्पादित करता है। यह फ़ंक्शन प्रोग्राम को केवल आवश्यक होने पर ही डिस्प्ले विंडो को अपडेट करने की अनुमति देता है, उदाहरण के लिए जब कोई ईवेंट पंजीकृत किया जाता है <a href=\"#/p5/mousePressed\">mousePressed()</a> या <a href=\"#/p5/keyPressed\">keyPressed()</a> होता है।",
            +        "किसी प्रोग्राम की संरचना में, <a href=\"#/p5/mousePressed\" जैसे ईवेंट में </a> <a href=\"#/p5/redraw\">redraw()</a> को कॉल करना ही समझदारी है। >mousePressed()</a>. ऐसा इसलिए है क्योंकि <a href=\"#/p5/redraw\">redraw()</a> नहीं चलता है <a href=\"#/p5/draw\"> draw() </a> तुरंत (यह केवल एक ध्वज सेट करता है जो इंगित करता है कि एक अद्यतन की आवश्यकता है)।",
            +        "<a href=\"#/p5/redraw\">redraw()</a> फ़ंक्शन ठीक से काम नहीं करता है जब <a href=\"#/p5/draw\">draw()</a>के अंदर कॉल किया जाता है।. एनिमेशन को सक्षम/अक्षम करने के लिए, <a href=\"#/p5/loop\">loop()</a> और <a href=\"#/p5/noLoop\">noLoop()</a>का उपयोग करें।",
            +        "इसके अलावा आप प्रति मेथड कॉल के लिए रेड्रा की संख्या निर्धारित कर सकते हैं। बस एक पूर्णांक को एकल पैरामीटर के रूप में जोड़ें।"
            +      ],
            +      "params": {
            +        "n": "Integer: (Optional) Redraw for n-times. The default value is 1."
            +      }
            +    },
            +    "p5": {
            +      "description": [
            +        "The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal \"global mode\". This is an advanced topic. A short description and example is included below. Please see <a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\"> Dan Shiffman's Coding Train video tutorial</a> or this <a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a> for more info.",
            +        "By default, all p5.js functions are in the global namespace (i.e. bound to the window object), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this might be inconvenient if you are mixing with other JS libraries (synchronously or asynchronously) or writing long programs of your own. p5.js currently supports a way around this problem called \"instance mode\". In instance mode, all p5 functions are bound up in a single variable instead of polluting your global namespace.",
            +        "Optionally, you can specify a default container for the canvas and any other elements to append to with a second argument. You can give the ID of an element in your html, or an html node itself.",
            +        "Note that creating instances like this also allows you to have more than one p5 sketch on a single web page, as they will each be wrapped up with their own set up variables. Of course, you could also use iframes to have multiple sketches in global mode."
            +      ],
            +      "params": {
            +        "sketch": "Object: a function containing a p5.js sketch",
            +        "node": "String|Object: ID or pointer to HTML DOM node to contain sketch in"
            +      }
            +    },
            +    "applyMatrix": {
            +      "description": [
            +        "Multiplies the current matrix by the one specified through the parameters. This is a powerful operation that can perform the equivalent of translate, scale, shear and rotate all at once. You can learn more about transformation matrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\"> Wikipedia</a>.",
            +        "The naming of the arguments here follows the naming of the <a href= \"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\"> WHATWG specification</a> and corresponds to a transformation matrix of the form: <blockquote>",
            +        "<img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\" alt=\"The transformation matrix used when applyMatrix is called\"/> </blockquote>"
            +      ],
            +      "params": {
            +        "a": "Number|Array: numbers which define the 2x3 matrix to be multiplied, or an array of numbers",
            +        "b": "Number: numbers which define the 2x3 matrix to be multiplied",
            +        "c": "Number: numbers which define the 2x3 matrix to be multiplied",
            +        "d": "Number: numbers which define the 2x3 matrix to be multiplied",
            +        "e": "Number: numbers which define the 2x3 matrix to be multiplied",
            +        "f": "Number: numbers which define the 2x3 matrix to be multiplied"
            +      }
            +    },
            +    "resetMatrix": {
            +      "description": [
            +        "Replaces the current matrix with the identity matrix."
            +      ]
            +    },
            +    "rotate": {
            +      "description": [
            +        "कोण पैरामीटर द्वारा निर्दिष्ट राशि से एक आकृति को घुमाता है। यह फ़ंक्शन <a href=\"#/p5/angleMode\">angleMode</a> के लिए जिम्मेदार है, इसलिए कोणों को रेडियन या डिग्री में दर्ज किया जा सकता है।",
            +        "ऑब्जेक्ट्स को हमेशा उनकी सापेक्ष स्थिति के आसपास मूल में घुमाया जाता है और सकारात्मक संख्याएं वस्तुओं को एक दक्षिणावर्त दिशा में घुमाती हैं। परिवर्तन उन सभी चीजों पर लागू होता है जो फ़ंक्शन के बाद और बाद में कॉल के प्रभाव को जमा करते हैं। उदाहरण के लिए, रोटेट (HALF_PI) को कॉल करना और फिर घुमाएं (HALF_PI) रोटेट (PI) के समान है। <a href=\"#/p5/draw\">draw()</a> फिर से शुरू होने पर सभी रूपांतरण रीसेट हो जाते हैं।",
            +        "तकनीकी रूप से, <a href=\"#/p5/rotate\">rotate()</a> वर्तमान रूपांतरण मैट्रिक्स को एक रोटेशन मैट्रिक्स से गुणा करता है। इस फ़ंक्शन को <a href=\"#/p5/push\">push()</a>द्वारा और नियंत्रित किया जा सकता है।  और <a href=\"#/p5/pop\">pop()</a>।"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation, specified in radians  or degrees, depending on current angleMode",
            +        "axis": "p5.Vector|Number[]: (Optional) (in 3d) the axis to rotate around"
            +      }
            +    },
            +    "rotateX": {
            +      "description": [
            +        "कोण पैरामीटर में निर्दिष्ट राशि द्वारा एक्स अक्ष के चारों ओर एक आकृति घुमाता है। कोणों को रेडियंस या डिग्री में दर्ज किया जा सकता है।",
            +        "ऑब्जेक्ट हमेशा अपनी सापेक्ष स्थिति के आसपास मूल के लिए घुमाए जाते हैं और सकारात्मक संख्याएं वस्तुओं को दक्षिणावर्त दिशा में घुमाती हैं। सभी रूपांतरण रीसेट हो जाते हैं जब <a href=\"#/p5/draw\">draw()</a> फिर से शुरू होता है ।"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation, specified in radians  or degrees, depending on current angleMode"
            +      }
            +    },
            +    "rotateY": {
            +      "description": [
            +        "कोण पैरामीटर में निर्दिष्ट राशि द्वारा Z अक्ष के चारों ओर एक आकृति को घुमाता है। कोणों को रेडियन या डिग्री में दर्ज किया जा सकता है।",
            +        "यह विधि केवल WEBGL मोड में काम करती है।"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation, specified in radians  or degrees, depending on current angleMode"
            +      }
            +    },
            +    "rotateZ": {
            +      "description": [
            +        "Rotates a shape around Z axis by the amount specified in angle parameter. The angles can be entered in either RADIANS or DEGREES.",
            +        "This method works in WEBGL mode only.",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation, specified in radians  or degrees, depending on current angleMode"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "शीर्षों को विस्तारित या अनुबंधित करके आकार के आकार को बढ़ाता या घटाता है। वस्तुएं हमेशा अपने सापेक्ष मूल से समन्वय प्रणाली तक स्केल करती हैं। स्केल मान दशमलव प्रतिशत के रूप में निर्दिष्ट होते हैं। उदाहरण के लिए, फ़ंक्शन कॉल स्केल (2.0) एक के आयाम को बढ़ाता है 200% से आकार।",
            +        "रूपांतरण हर उस चीज़ पर लागू होता है जो फ़ंक्शन के बाद और बाद में होने वाली कॉल के प्रभाव को गुणा करती है। उदाहरण के लिए, कॉलिंग स्केल (2.0) और फिर स्केल (1.5) स्केल (3.0) के समान है। यदि <a href=\"#/ p5/scale\">scale()</a> को <a href=\"#/p5/draw\">draw()</a> में कॉल किया जाता है, जब लूप दोबारा शुरू होता है तो ट्रांसफॉर्मेशन रीसेट हो जाता है।",
            +        "Z पैरामीटर के साथ इस फ़ंक्शन का उपयोग करना केवल WEBGL मोड में उपलब्ध है। इस फ़ंक्शन को <a href=\"#/p5/push\">push()</a> और <a href=\"#/p5/pop\">pop()</a>के साथ और अधिक नियंत्रित किया जा सकता है।"
            +      ],
            +      "params": {
            +        "s": "Number|p5.Vector|Number[]: percent to scale the object, or percentage to  scale the object in the x-axis if multiple arguments  are given",
            +        "y": "Number: (Optional) percent to scale the object in the y-axis",
            +        "z": "Number: (Optional) percent to scale the object in the z-axis (webgl only)",
            +        "scales": "p5.Vector|Number[]: per-axis percents to scale the object"
            +      }
            +    },
            +    "shearX": {
            +      "description": [
            +        "कोण पैरामीटर द्वारा निर्दिष्ट राशि द्वारा एक्स-अक्ष के चारों ओर एक आकृति को कतरता है। कोणों को वर्तमान कोण मोड में निर्दिष्ट किया जाना चाहिए। वस्तुओं को हमेशा उनकी सापेक्ष स्थिति के आसपास मूल और सकारात्मक संख्याएं घड़ी की दिशा में वस्तुओं को कतरनी करती हैं।",
            +        "परिवर्तन सब कुछ पर लागू होता है जो फ़ंक्शन के बाद और बाद में कॉल के प्रभाव को जमा करता है। उदाहरण के लिए, शीयरएक्स (पीआई/2) और फिर शीयरएक्स (पीआई/2) को कॉल करना शीयरएक्स (पीआई) के समान है। यदि <a href= \"#/p5/shearX\">shearX()</a> को <a href=\"#/p5/draw\">draw()</a> के अंदर कॉल किया जाता है, जब लूप में ट्रांसफ़ॉर्मेशन रीसेट हो जाता है फिर से शुरू होता है।",
            +        "तकनीकी रूप से, <a href=\"#/p5/shearX\">shearX()</a> वर्तमान रूपांतरण मैट्रिक्स को एक रोटेशन मैट्रिक्स से गुणा करता है। इस फ़ंक्शन को <a href=\"#/p5/push\">push()</a>द्वारा और नियंत्रित किया जा सकता है और <a href=\"#/p5/pop\">pop()</a> फंक्शन।"
            +      ],
            +      "params": {
            +        "angle": "Number: angle of shear specified in radians or degrees,  depending on current angleMode"
            +      }
            +    },
            +    "shearY": {
            +      "description": [
            +        "y-अक्ष के चारों ओर एक आकार को कोण पैरामीटर द्वारा निर्दिष्ट राशि को कतरता है। कोणों को वर्तमान कोण मोड में निर्दिष्ट किया जाना चाहिए। वस्तुओं को हमेशा उनकी सापेक्ष स्थिति के आसपास मूल और सकारात्मक संख्याएं वस्तुओं को दक्षिणावर्त दिशा में कतरती हैं।",
            +        "परिवर्तन सब कुछ पर लागू होता है जो फ़ंक्शन के बाद और बाद में कॉल के प्रभाव को जमा करता है। उदाहरण के लिए, शीयरवाई (PI/2) और फिर शीयरवाई (PI/2) को कॉल करना शीयरवाई (PI) के समान है। यदि <a href= \"#/p5/shearY\">shearY()</a> को <a href=\"#/p5/draw\">draw()</a> में कॉल किया जाता है, जब लूप में ट्रांसफॉर्मेशन रीसेट हो जाता है फिर से शुरू होता है।",
            +        "तकनीकी रूप से, <a href=\"#/p5/shearY\">shearY()</a> वर्तमान रूपांतरण मैट्रिक्स को एक रोटेशन मैट्रिक्स से गुणा करता है। इस फ़ंक्शन को <a href=\"#/ द्वारा और नियंत्रित किया जा सकता है। p5/push\">push()</a> और <a href=\"#/p5/pop\">pop()</a> फंक्शन।"
            +      ],
            +      "params": {
            +        "angle": "Number: angle of shear specified in radians or degrees,  depending on current angleMode"
            +      }
            +    },
            +    "translate": {
            +      "description": [
            +        "डिस्प्ले विंडो के भीतर वस्तुओं को विस्थापित करने के लिए एक राशि निर्दिष्ट करता है। x पैरामीटर बाएँ/दाएँ अनुवाद निर्दिष्ट करता है, y पैरामीटर ऊपर/नीचे अनुवाद निर्दिष्ट करता है।",
            +        "रूपांतरण संचयी होते हैं और उन सभी चीजों पर लागू होते हैं जो फ़ंक्शन के बाद और बाद में कॉल के प्रभाव को जमा करते हैं। उदाहरण के लिए, अनुवाद को कॉल करना (50, 0) और फिर अनुवाद (20, 0) अनुवाद (70, 0) के समान है। यदि <a href=\"#/p5/translate\">translate()</a> को <a href=\"#/p5/draw\">draw()</a> में कॉल किया जाता है, तो रूपांतरण है लूप के फिर से शुरू होने पर रीसेट करें। इस फ़ंक्शन को <a href=\"#/p5/push\">push()</a> और <a href=\"#/p5/pop\">pop()</a>का उपयोग करके नियंत्रित किया जा सकता है।"
            +      ],
            +      "params": {
            +        "x": "Number: left/right translation",
            +        "y": "Number: up/down translation",
            +        "z": "Number: (Optional) forward/backward translation (webgl only)",
            +        "vector": "p5.Vector: the vector to translate by"
            +      }
            +    },
            +    "storeItem": {
            +      "description": [
            +        "Stores a value in local storage under the key name.  Local storage is saved in the browser and persists  between browsing sessions and page reloads.  The key can be the name of the variable but doesn't  have to be. To retrieve stored items  see <a href=\"#/p5/getItem\">getItem</a>. Sensitive data such as passwords or personal information  should not be stored in local storage."
            +      ],
            +      "params": {
            +        "key": "String",
            +        "value": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +      }
            +    },
            +    "getItem": {
            +      "description": [
            +        "Returns the value of an item that was stored in local storage  using storeItem()"
            +      ],
            +      "returns": "Number|Object|String|Boolean|p5.Color|p5.Vector: Value of stored item",
            +      "params": {
            +        "key": "String: name that you wish to use to store in local storage"
            +      }
            +    },
            +    "clearStorage": {
            +      "description": [
            +        "Clears all local storage items set with storeItem()  for the current domain."
            +      ]
            +    },
            +    "removeItem": {
            +      "description": [
            +        "Removes an item that was stored with storeItem()"
            +      ],
            +      "params": {
            +        "key": "String"
            +      }
            +    },
            +    "createStringDict": {
            +      "description": [
            +        "Creates a new instance of p5.StringDict using the key-value pair  or the object you provide."
            +      ],
            +      "returns": "p5.StringDict:",
            +      "params": {
            +        "key": "String",
            +        "value": "String",
            +        "object": "Object: object"
            +      }
            +    },
            +    "createNumberDict": {
            +      "description": [
            +        "Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair  or object you provide."
            +      ],
            +      "returns": "p5.NumberDict:",
            +      "params": {
            +        "key": "Number",
            +        "value": "Number",
            +        "object": "Object: object"
            +      }
            +    },
            +    "select": {
            +      "description": [
            +        "Searches the page for the first element that matches the given CSS selector string (can be an ID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>. The DOM node itself can be accessed with .elt. Returns null if none found. You can also specify a container to search within."
            +      ],
            +      "returns": "p5.Element|null: <a href=\"#/p5.Element\">p5.Element</a> containing node found",
            +      "params": {
            +        "selectors": "String: CSS selector string of element to search for",
            +        "container": "String|p5.Element|HTMLElement: (Optional) CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or  HTML element to search within"
            +      }
            +    },
            +    "selectAll": {
            +      "description": [
            +        "Searches the page for elements that match the given CSS selector string (can be an ID a class, tag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in an array. The DOM node itself can be accessed with .elt. Returns an empty array if none found. You can also specify a container to search within."
            +      ],
            +      "returns": "p5.Element[]: Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found",
            +      "params": {
            +        "selectors": "String: CSS selector string of elements to search for",
            +        "container": "String|p5.Element|HTMLElement: (Optional) CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>  , or HTML element to search within"
            +      }
            +    },
            +    "removeElements": {
            +      "description": [
            +        "Removes all elements created by p5, except any canvas / graphics elements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>. Event handlers are removed, and element is removed from the DOM."
            +      ]
            +    },
            +    "changed": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an element changes. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when the value of  an element changes.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "input": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is detected with an element. The input event is often used to detect keystrokes in a input element, or changes on a slider element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when any user input is  detected within the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "createDiv": {
            +      "description": [
            +        "Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createP": {
            +      "description": [
            +        "Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used for paragraph length text."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createSpan": {
            +      "description": [
            +        "Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createImg": {
            +      "description": [
            +        "Creates an <code>&lt;img&gt;</code> element in the DOM with given src and alternate text."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "src": "String: src path or url for image",
            +        "alt": "String: <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.",
            +        "crossOrigin": "String: <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used",
            +        "successCallback": "Function: (Optional) callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument"
            +      }
            +    },
            +    "createA": {
            +      "description": [
            +        "Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "href": "String: url of page to link to",
            +        "html": "String: inner html of link element to display",
            +        "target": "String: (Optional) target where new link should open,  could be _blank, _self, _parent, _top."
            +      }
            +    },
            +    "createSlider": {
            +      "description": [
            +        "Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM. Use .size() to set the display length of the slider."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "min": "Number: minimum value of the slider",
            +        "max": "Number: maximum value of the slider",
            +        "value": "Number: (Optional) default value of the slider",
            +        "step": "Number: (Optional) step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)"
            +      }
            +    },
            +    "createButton": {
            +      "description": [
            +        "Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM. Use .size() to set the display size of the button. Use .mousePressed() to specify behavior on press."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "label": "String: label displayed on the button",
            +        "value": "String: (Optional) value of the button"
            +      }
            +    },
            +    "createCheckbox": {
            +      "description": [
            +        "Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM. Calling .checked() on a checkbox returns if it is checked or not"
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "label": "String: (Optional) label displayed after checkbox",
            +        "value": "Boolean: (Optional) value of the checkbox; checked is true, unchecked is false"
            +      }
            +    },
            +    "createSelect": {
            +      "description": [
            +        "Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM. It also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box. <ul> <li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li> <li><code>.value()</code> will return the currently selected option.</li> <li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li> <li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li> <li><code>.disable()</code> marks whole of dropdown element as disabled.</li> <li><code>.disable(value)</code> marks given option as disabled</li> </ul>"
            +      ],
            +      "returns": "p5.Element:",
            +      "params": {
            +        "multiple": "Boolean: (Optional) true if dropdown should support multiple selections",
            +        "existing": "Object: DOM select element"
            +      }
            +    },
            +    "createRadio": {
            +      "description": [
            +        "Creates a radio button element in the DOM.It also helps existing radio buttons assign methods of <a href=\"#/p5.Element/\">p5.Element</a>. <ul> <li><code>.option(value, [label])</code> can be used to create a new option for the element. If an option with a value already exists, it will be returned. Optionally, a label can be provided as second argument for the option.</li> <li><code>.remove(value)</code> can be used to remove an option for the element.</li> <li><code>.value()</code> method will return the currently selected value.</li> <li><code>.selected()</code> method will return the currently selected input element.</li> <li><code>.selected(value)</code> method will select the option and return it.</li> <li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li> </ul>"
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "containerElement": "Object: An container HTML Element either a div or span inside which all existing radio inputs will be considered as options.",
            +        "name": "String: (Optional) A name parameter for each Input Element."
            +      }
            +    },
            +    "createColorPicker": {
            +      "description": [
            +        "Creates a colorPicker element in the DOM for color input. The .value() method will return a hex string (#rrggbb) of the color. The .color() method will return a p5.Color object with the current chosen color."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "value": "String|p5.Color: (Optional) default color of element"
            +      }
            +    },
            +    "createInput": {
            +      "description": [
            +        "Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input. Use .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "value": "String: default value of the input box",
            +        "type": "String: (Optional) type of text, ie text, password etc. Defaults to text.  Needs a value to be specified first."
            +      }
            +    },
            +    "createFileInput": {
            +      "description": [
            +        "Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'. This allows users to select local files for use in a sketch."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element",
            +      "params": {
            +        "callback": "Function: callback function for when a file is loaded",
            +        "multiple": "Boolean: (Optional) optional, to allow multiple files to be selected"
            +      }
            +    },
            +    "createVideo": {
            +      "description": [
            +        "Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback of audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a> and drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter can be either a single string path to a video file, or an array of string paths to different formats of the same video. This is useful for ensuring that your video can play across different browsers, as each supports different formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this page</a> for further information about supported formats."
            +      ],
            +      "returns": "p5.MediaElement: pointer to video <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "src": "String|String[]: path to a video file, or array of paths for  supporting different browsers",
            +        "callback": "Function: (Optional) callback function to be called upon  'canplaythrough' event fire, that is, when the  browser can play the media, and estimates that  enough data has been loaded to play the media  up to its end without having to stop for  further buffering of content"
            +      }
            +    },
            +    "createAudio": {
            +      "description": [
            +        "Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio playback. The first parameter can be either a single string path to a audio file, or an array of string paths to different formats of the same audio. This is useful for ensuring that your audio can play across different browsers, as each supports different formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this page for further information about supported formats</a>."
            +      ],
            +      "returns": "p5.MediaElement: pointer to audio <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "src": "String|String[]: (Optional) path to an audio file, or array of paths  for supporting different browsers",
            +        "callback": "Function: (Optional) callback function to be called upon  'canplaythrough' event fire, that is, when the  browser can play the media, and estimates that  enough data has been loaded to play the media  up to its end without having to stop for  further buffering of content"
            +      }
            +    },
            +    "VIDEO": {},
            +    "AUDIO": {},
            +    "createCapture": {
            +      "description": [
            +        "Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed from a webcam. The element is separate from the canvas and is displayed by default. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>. The feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>. The loadedmetadata property can be used to detect when the element has fully loaded (see second example).",
            +        "More specific properties of the feed can be passing in a Constraints object. See the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'> W3C spec</a> for possible properties. Note that not all of these are supported by all browsers.",
            +        "<em>Security note</em>: A new browser security specification requires that getUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>, only works when you're running the code locally, or on HTTPS. Learn more <a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a> and <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>."
            +      ],
            +      "returns": "p5.Element: capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "type": "String|Constant|Object: type of capture, either VIDEO or  AUDIO if none specified, default both,  or a Constraints object",
            +        "callback": "Function: (Optional) function to be called once  stream has loaded"
            +      }
            +    },
            +    "createElement": {
            +      "description": [
            +        "Creates element with given tag in the DOM with given content."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "tag": "String: tag for the new element",
            +        "content": "String: (Optional) html content to be inserted into the element"
            +      }
            +    },
            +    "deviceOrientation": {
            +      "description": [
            +        "The system variable deviceOrientation always contains the orientation of the device. The value of this variable will either be set 'landscape' or 'portrait'. If no data is available it will be set to 'undefined'. either LANDSCAPE or PORTRAIT."
            +      ]
            +    },
            +    "accelerationX": {
            +      "description": [
            +        "The system variable accelerationX always contains the acceleration of the device along the x axis. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "accelerationY": {
            +      "description": [
            +        "The system variable accelerationY always contains the acceleration of the device along the y axis. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "accelerationZ": {
            +      "description": [
            +        "The system variable accelerationZ always contains the acceleration of the device along the z axis. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "pAccelerationX": {
            +      "description": [
            +        "The system variable pAccelerationX always contains the acceleration of the device along the x axis in the frame previous to the current frame. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "pAccelerationY": {
            +      "description": [
            +        "The system variable pAccelerationY always contains the acceleration of the device along the y axis in the frame previous to the current frame. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "pAccelerationZ": {
            +      "description": [
            +        "The system variable pAccelerationZ always contains the acceleration of the device along the z axis in the frame previous to the current frame. Value is represented as meters per second squared."
            +      ]
            +    },
            +    "rotationX": {
            +      "description": [
            +        "The system variable rotationX always contains the rotation of the device along the x axis. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be -180 to 180. If it is set to RADIANS, the value will be -PI to PI.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "rotationY": {
            +      "description": [
            +        "The system variable rotationY always contains the rotation of the device along the y axis. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be -90 to 90. If it is set to RADIANS, the value will be -PI/2 to PI/2.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "rotationZ": {
            +      "description": [
            +        "The system variable rotationZ always contains the rotation of the device along the z axis. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be 0 to 360. If it is set to RADIANS, the value will be 0 to 2*PI.",
            +        "Unlike rotationX and rotationY, this variable is available for devices with a built-in compass only.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "pRotationX": {
            +      "description": [
            +        "The system variable pRotationX always contains the rotation of the device along the x axis in the frame previous to the current frame. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be -180 to 180. If it is set to RADIANS, the value will be -PI to PI.",
            +        "pRotationX can also be used with rotationX to determine the rotate direction of the device along the X-axis."
            +      ]
            +    },
            +    "pRotationY": {
            +      "description": [
            +        "The system variable pRotationY always contains the rotation of the device along the y axis in the frame previous to the current frame. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be -90 to 90. If it is set to RADIANS, the value will be -PI/2 to PI/2.",
            +        "pRotationY can also be used with rotationY to determine the rotate direction of the device along the Y-axis."
            +      ]
            +    },
            +    "pRotationZ": {
            +      "description": [
            +        "The system variable pRotationZ always contains the rotation of the device along the z axis in the frame previous to the current frame. If the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES, the value will be 0 to 360. If it is set to RADIANS, the value will be 0 to 2*PI.",
            +        "pRotationZ can also be used with rotationZ to determine the rotate direction of the device along the Z-axis."
            +      ]
            +    },
            +    "turnAxis": {
            +      "description": [
            +        "When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis variable. The turnAxis variable is only defined within the scope of deviceTurned()."
            +      ]
            +    },
            +    "setMoveThreshold": {
            +      "description": [
            +        "The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for the <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5."
            +      ],
            +      "params": {
            +        "value": "Number: The threshold value"
            +      }
            +    },
            +    "setShakeThreshold": {
            +      "description": [
            +        "The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for the <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30."
            +      ],
            +      "params": {
            +        "value": "Number: The threshold value"
            +      }
            +    },
            +    "deviceMoved": {
            +      "description": [
            +        "The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than the threshold value along X, Y or Z axis. The default threshold is set to 0.5. The threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>."
            +      ]
            +    },
            +    "deviceTurned": {
            +      "description": [
            +        "The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by more than 90 degrees continuously.",
            +        "The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis variable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis: X, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'."
            +      ]
            +    },
            +    "deviceShaken": {
            +      "description": [
            +        "The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration changes of accelerationX and accelerationY values is more than the threshold value. The default threshold is set to 30. The threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>."
            +      ]
            +    },
            +    "keyIsPressed": {
            +      "description": [
            +        "The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed and false if no keys are pressed."
            +      ]
            +    },
            +    "key": {
            +      "description": [
            +        "The system variable key always contains the value of the most recent key on the keyboard that was typed. To get the proper capitalization, it is best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a> variable."
            +      ]
            +    },
            +    "keyCode": {
            +      "description": [
            +        "The variable keyCode is used to detect special keys such as BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. You can also check for custom keys by looking up the keyCode of any key on a site like this: <a href=\"http://keycode.info/\">keycode.info</a>."
            +      ]
            +    },
            +    "keyPressed": {
            +      "description": [
            +        "The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The keyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.",
            +        "For non-ASCII keys, use the keyCode variable. You can check if the keyCode equals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.",
            +        "For ASCII keys, the key that was pressed is stored in the key variable. However, it does not distinguish between uppercase and lowercase. For this reason, it is recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the case of the variable will be distinguished.",
            +        "Because of how operating systems handle key repeats, holding down a key may cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The rate of repeat is set by the operating system and how each computer is configured. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyReleased": {
            +      "description": [
            +        "The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released. See <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyTyped": {
            +      "description": [
            +        "The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but action keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect a keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead. The most recent key typed will be stored in the key variable.",
            +        "Because of how operating systems handle key repeats, holding down a key will cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The rate of repeat is set by the operating system and how each computer is configured. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyIsDown": {
            +      "description": [
            +        "The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed. It can be used if you have an object that moves, and you want several keys to be able to affect its behaviour simultaneously, such as moving a sprite diagonally. You can put in any number representing the keyCode of the key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed <a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>."
            +      ],
            +      "returns": "Boolean: whether key is down or not",
            +      "params": {
            +        "code": "Number: The key to check for."
            +      }
            +    },
            +    "movedX": {
            +      "description": [
            +        "The variable movedX contains the horizontal movement of the mouse since the last frame"
            +      ]
            +    },
            +    "movedY": {
            +      "description": [
            +        "The variable movedY contains the vertical movement of the mouse since the last frame"
            +      ]
            +    },
            +    "mouseX": {
            +      "description": [
            +        "The system variable mouseX always contains the current horizontal position of the mouse, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. If touch is used instead of mouse input, mouseX will hold the x value of the most recent touch point."
            +      ]
            +    },
            +    "mouseY": {
            +      "description": [
            +        "The system variable mouseY always contains the current vertical position of the mouse, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. If touch is used instead of mouse input, mouseY will hold the y value of the most recent touch point."
            +      ]
            +    },
            +    "pmouseX": {
            +      "description": [
            +        "The system variable pmouseX always contains the horizontal position of the mouse or finger in the frame previous to the current frame, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX value at the start of each touch event."
            +      ]
            +    },
            +    "pmouseY": {
            +      "description": [
            +        "The system variable pmouseY always contains the vertical position of the mouse or finger in the frame previous to the current frame, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY value at the start of each touch event."
            +      ]
            +    },
            +    "winMouseX": {
            +      "description": [
            +        "The system variable winMouseX always contains the current horizontal position of the mouse, relative to (0, 0) of the window."
            +      ]
            +    },
            +    "winMouseY": {
            +      "description": [
            +        "The system variable winMouseY always contains the current vertical position of the mouse, relative to (0, 0) of the window."
            +      ]
            +    },
            +    "pwinMouseX": {
            +      "description": [
            +        "The system variable pwinMouseX always contains the horizontal position of the mouse in the frame previous to the current frame, relative to (0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX value at the start of each touch event."
            +      ]
            +    },
            +    "pwinMouseY": {
            +      "description": [
            +        "The system variable pwinMouseY always contains the vertical position of the mouse in the frame previous to the current frame, relative to (0, 0) of the window. Note: pwinMouseY will be reset to the current winMouseY value at the start of each touch event."
            +      ]
            +    },
            +    "mouseButton": {
            +      "description": [
            +        "p5 automatically tracks if the mouse button is pressed and which button is pressed. The value of the system variable mouseButton is either LEFT, RIGHT, or CENTER depending on which button was pressed last. Warning: different browsers may track mouseButton differently."
            +      ]
            +    },
            +    "mouseIsPressed": {
            +      "description": [
            +        "The boolean system variable mouseIsPressed is true if the mouse is pressed and false if not."
            +      ]
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse button is not pressed. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseDragged": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and a mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the <a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button is pressed. The mouseButton variable (see the related reference entry) can be used to determine which button has been pressed. If no <a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is released. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been pressed and then released. Browsers handle clicks differently, so this function is only guaranteed to be run when the left mouse button is clicked. To handle other mouse buttons being pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event listener has detected a dblclick event which is a part of the DOM L3 specification. The doubleClicked event is fired when a pointing device button (usually a mouse's primary button) is clicked twice on a single element. For more info on the dblclick event refer to mozilla's documentation here: <a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a>"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel event is detected either triggered by an actual mouse wheel or by a touchpad. The event.delta property returns the amount the mouse wheel have scrolled. The values can be positive or negative depending on the scroll direction (on OS X with \"natural\" scrolling enabled, the signs are inverted). Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method. Due to the current support of the \"wheel\" event on Safari, the function may only work as expected if \"return false\" is included while using Safari."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional WheelEvent callback argument."
            +      }
            +    },
            +    "requestPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a> locks the pointer to its current position and makes it invisible. Use <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since the last call of draw. Note that not all browsers support this feature. This enables you to create experiences that aren't limited by the mouse moving out of the screen even if it is repeatedly moved into one direction. For example, a first person perspective experience."
            +      ]
            +    },
            +    "exitPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a> exits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a> for example to make ui elements usable etc"
            +      ]
            +    },
            +    "touches": {
            +      "description": [
            +        "The system variable touches[] contains an array of the positions of all current touch points, relative to (0, 0) of the canvas, and IDs identifying a unique touch as it moves. Each element in the array is an object with x, y, and id properties.",
            +        "The touches[] array is not supported on Safari and IE on touch-based desktops (laptops)."
            +      ]
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "The touchStarted() function is called once after every time a touch is registered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various touch events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered. If no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various touch events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no <a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various touch events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "createImage": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a fresh buffer of pixels to play with. Set the size of the buffer with the width and height parameters.",
            +        ".<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels in the display window. These values are numbers. This array is the size (including an appropriate factor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for more info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.",
            +        "Before accessing the pixels of an image, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes."
            +      ],
            +      "returns": "p5.Image: the <a href=\"#/p5.Image\">p5.Image</a> object",
            +      "params": {
            +        "width": "Integer: width in pixels",
            +        "height": "Integer: height in pixels"
            +      }
            +    },
            +    "saveCanvas": {
            +      "description": [
            +        "Save the current canvas as an image. The browser will either save the file immediately, or prompt the user with a dialogue window."
            +      ],
            +      "params": {
            +        "selectedCanvas": "p5.Element|HTMLCanvasElement: a variable  representing a specific html5 canvas (optional)",
            +        "filename": "String (Optional)",
            +        "extension": "String: (Optional) 'jpg' or 'png'"
            +      }
            +    },
            +    "saveFrames": {
            +      "description": [
            +        "Capture a sequence of frames that can be used to create a movie. Accepts a callback. For example, you may wish to send the frames to a server where they can be stored or converted into a movie. If no callback is provided, the browser will pop up save dialogues in an attempt to download all of the images that have just been created. With the callback provided the image data isn't saved by default but instead passed as an argument to the callback function as an array of objects, with the size of array equal to the total number of frames.",
            +        "Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation. To export longer animations, you might look into a library like <a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>."
            +      ],
            +      "params": {
            +        "filename": "String",
            +        "extension": "String: 'jpg' or 'png'",
            +        "duration": "Number: Duration in seconds to save the frames for.",
            +        "framerate": "Number: Framerate to save the frames in.",
            +        "callback": "Function(Array): (Optional) A callback function that will be executed  to handle the image data. This function  should accept an array as argument. The  array will contain the specified number of  frames of objects. Each object has three  properties: imageData - an  image/octet-stream, filename and extension."
            +      }
            +    },
            +    "loadImage": {
            +      "description": [
            +        "Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.",
            +        "The image may not be immediately available for rendering. If you want to ensure that the image is ready before doing anything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>. You may also supply a callback function to handle the image when it's ready.",
            +        "The path to the image should be relative to the HTML file that links in your sketch. Loading an image from a URL or other remote location may be blocked due to your browser's built-in security.",
            +        "You can also pass in a string of a base64 encoded image as an alternative to the file path. Remember to add \"data:image/png;base64,\" in front of the string."
            +      ],
            +      "returns": "p5.Image: the <a href=\"#/p5.Image\">p5.Image</a> object",
            +      "params": {
            +        "path": "String: Path of the image to be loaded",
            +        "successCallback": "function(p5.Image): (Optional) Function to be called once  the image is loaded. Will be passed the  <a href=\"#/p5.Image\">p5.Image</a>.",
            +        "failureCallback": "Function(Event): (Optional) called with event error if  the image fails to load."
            +      }
            +    },
            +    "image": {
            +      "description": [
            +        "Draw an image to the p5.js canvas.",
            +        "This function can be used with different numbers of parameters. The simplest use requires only three parameters: img, x, and y—where (x, y) is the position of the image. Two more parameters can optionally be added to specify the width and height of the image.",
            +        "This function can also be used with all eight Number parameters. To differentiate between all these parameters, p5.js uses the language of \"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source image\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the \"source image\" dimensions can be useful when you want to display a subsection of the source image instead of the whole thing. Here's a diagram to explain further: <img src=\"assets/drawImage.png\"></img>"
            +      ],
            +      "params": {
            +        "img": "p5.Image|p5.Element: the image to display",
            +        "x": "Number: the x-coordinate of the top-left corner of the image",
            +        "y": "Number: the y-coordinate of the top-left corner of the image",
            +        "width": "Number: (Optional) the width to draw the image",
            +        "height": "Number: (Optional) the height to draw the image",
            +        "dx": "Number: the x-coordinate of the destination  rectangle in which to draw the source image",
            +        "dy": "Number: the y-coordinate of the destination  rectangle in which to draw the source image",
            +        "dWidth": "Number: the width of the destination rectangle",
            +        "dHeight": "Number: the height of the destination rectangle",
            +        "sx": "Number: the x-coordinate of the subsection of the source image to draw into the destination rectangle",
            +        "sy": "Number: the y-coordinate of the subsection of the source image to draw into the destination rectangle",
            +        "sWidth": "Number: (Optional) the width of the subsection of the  source image to draw into the destination  rectangle",
            +        "sHeight": "Number: (Optional) the height of the subsection of the  source image to draw into the destination rectangle"
            +      }
            +    },
            +    "tint": {
            +      "description": [
            +        "Sets the fill value for displaying images. Images can be tinted to specified colors or made transparent by including an alpha value.",
            +        "To apply transparency to an image without affecting its color, use white as the tint color and specify an alpha value. For instance, tint(255, 128) will make an image 50% transparent (assuming the default alpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).",
            +        "The value for the gray parameter must be less than or equal to the current maximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is 255."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "alpha": "Number (Optional)",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the tint color"
            +      }
            +    },
            +    "noTint": {
            +      "description": [
            +        "Removes the current fill value for displaying images and reverts to displaying images with their original hues."
            +      ]
            +    },
            +    "imageMode": {
            +      "description": [
            +        "Set image mode. Modifies the location from which images are drawn by changing the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted. The default mode is imageMode(CORNER), which interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If two additional parameters are specified, they are used to set the image's width and height.",
            +        "imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the location of one corner, and the fourth and fifth parameters as the opposite corner.",
            +        "imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the image's center point. If two additional parameters are specified, they are used to set the image's width and height."
            +      ],
            +      "params": {
            +        "mode": "Constant: either CORNER, CORNERS, or CENTER"
            +      }
            +    },
            +    "pixels": {
            +      "description": [
            +        "<a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a> containing the values for all the pixels in the display window. These values are numbers. This array is the size (include an appropriate factor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. Retina and other high density displays will have more pixels[] (by a factor of pixelDensity^2). For example, if the image is 100x100 pixels, there will be 40,000. On a retina display, there will be 160,000.",
            +        "The first four values (indices 0-3) in the array will be the R, G, B, A values of the pixel at (0, 0). The second four values (indices 4-7) will contain the R, G, B, A values of the pixel at (1, 0). More generally, to set values for a pixel at (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre>",
            +        "While the above method is complex, it is flexible enough to work with any pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of setting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at any pixelDensity, but the performance may not be as fast when lots of modifications are made to the pixel array.",
            +        "Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a> function must be run to update the changes.",
            +        "Note that this is not a standard javascript array. This means that standard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or <a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not work."
            +      ]
            +    },
            +    "blend": {
            +      "description": [
            +        "Copies a region of pixels from one image to another, using a specified blend mode to do the operation."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height",
            +        "blendMode": "Constant: the blend mode. either  BLEND, DARKEST, LIGHTEST, DIFFERENCE,  MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD or NORMAL."
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Copies a region of the canvas to another region of the canvas and copies a region of pixels from an image used as the srcImg parameter into the canvas srcImage is specified this is used as the source. If the source and destination regions aren't the same size, it will automatically resize source pixels to fit the specified target region."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5.Element: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Applies a filter to the canvas. The presets options are:",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used.",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used.",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used.",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges.",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur.",
            +        "ERODE Reduces the light areas. No parameter is used.",
            +        "DILATE Increases the light areas. No parameter is used.",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "Constant: either THRESHOLD, GRAY, OPAQUE, INVERT,  POSTERIZE, BLUR, ERODE, DILATE or BLUR.  See Filters.js for docs on  each available filter",
            +        "filterParam": "Number: (Optional) an optional parameter unique  to each filter, see above"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Get a region of pixels, or a single pixel, from the canvas.",
            +        "Returns an array of [R,G,B,A] values for any pixel or grabs a section of an image. If no parameters are specified, the entire image is returned. Use the x and y parameters to get the value of one pixel. Get a section of the display window by specifying additional w and h parameters. When getting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.",
            +        "Getting the color of a single pixel with get(x, y) is easy, but not as fast as grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to get(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is <pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates let off = (y * width + x) * d * 4; let components = [  pixels[off],  pixels[off + 1],  pixels[off + 2],  pixels[off + 3] ]; print(components);</code></pre>",
            +        "See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.",
            +        "If you want to extract an array of colors or a subimage from an p5.Image object, take a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a>"
            +      ],
            +      "returns": "p5.Image: the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "w": "Number: width",
            +        "h": "Number: height"
            +      }
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This function must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>. Note that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a> will occur."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Changes the color of any pixel, or writes an image directly to the display window. The x and y parameters specify the pixel to change and the c parameter specifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A] pixel array. It can also be a single grayscale value. When setting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.",
            +        "After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear. This should be called once all pixels have been set, and must be called before calling .<a href=\"#/p5/get\">get()</a> or drawing the image.",
            +        "Setting the color of a single pixel with set(x, y) is easy, but not as fast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a> values directly may be complicated when working with a retina display, but will perform better when lots of pixels need to be set directly on every loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "c": "Number|Number[]|Object: insert a grayscale value | a pixel array |  a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy"
            +      }
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array. Use in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from the array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only necessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the pixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with <a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur."
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) x-coordinate of the upper-left corner of region  to update",
            +        "y": "Number: (Optional) y-coordinate of the upper-left corner of region  to update",
            +        "w": "Number: (Optional) width of region to update",
            +        "h": "Number: (Optional) height of region to update"
            +      }
            +    },
            +    "loadJSON": {
            +      "description": [
            +        "Loads a JSON file from a file or a URL, and returns an Object. Note that even if the JSON file contains an Array, an Object will be returned with index numbers as keys.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. JSONP is supported via a polyfill and you can pass in as the second argument an object with definitions of the json callback following the syntax specified <a href=\"https://github.com/camsong/ fetch-jsonp\">here</a>.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object|Array: JSON data",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "jsonpOptions": "Object: (Optional) options object for jsonp related settings",
            +        "datatype": "String: (Optional) \"json\" or \"jsonp\"",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed  in as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadStrings": {
            +      "description": [
            +        "Reads the contents of a file and creates a String array of its individual lines. If the name of the file is used as the parameter, as in the above example, the file must be located in the sketch directory/folder.",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "String[]: Array of Strings",
            +      "params": {
            +        "filename": "String: name of the file or url to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>  completes, Array is passed in as first  argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadTable": {
            +      "description": [
            +        "Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with its values. If a file is specified, it must be located in the sketch's \"data\" folder. The filename parameter can also be a URL to a file found online. By default, the file is assumed to be comma-separated (in CSV format). Table only looks for a header row if the 'header' option is included.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called. Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object:",
            +        "All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: <a href=\"#/p5.Table\">Table</a> object containing data",
            +      "params": {
            +        "filename": "String: name of the file or URL to load",
            +        "extension": "String: (Optional) parse the table by comma-separated values \"csv\", semicolon-separated  values \"ssv\", or tab-separated values \"tsv\"",
            +        "header": "String: (Optional) \"header\" to indicate table has header row",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the  <a href=\"#/p5.Table\">Table</a> object is passed in as the  first argument.",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadXML": {
            +      "description": [
            +        "Reads the contents of a file and creates an XML object with its values. If the name of the file is used as the parameter, as in the above example, the file must be located in the sketch directory/folder.",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.",
            +        "Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: XML object containing data",
            +      "params": {
            +        "filename": "String: name of the file or URL to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>  completes, XML object is passed in as  first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadBytes": {
            +      "description": [
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: an object whose 'bytes' property will be the loaded buffer",
            +      "params": {
            +        "file": "String: name of the file or URL to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>  completes",
            +        "errorCallback": "Function: (Optional) function to be executed if there  is an error"
            +      }
            +    },
            +    "httpGet": {
            +      "description": [
            +        "Method for executing an HTTP GET request. If data type is not specified, p5 will try to guess based on the URL, defaulting to text. This is equivalent to calling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return a Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer which can be used to initialize typed arrays (such as Uint8Array)."
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "datatype": "String: (Optional) \"json\", \"jsonp\", \"binary\", \"arrayBuffer\",  \"xml\", or \"text\"",
            +        "data": "Object|Boolean: (Optional) param data passed sent with request",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in  as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "httpPost": {
            +      "description": [
            +        "Method for executing an HTTP POST request. If data type is not specified, p5 will try to guess based on the URL, defaulting to text. This is equivalent to calling <code>httpDo(path, 'POST')</code>."
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "datatype": "String: (Optional) \"json\", \"jsonp\", \"xml\", or \"text\".  If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.",
            +        "data": "Object|Boolean: (Optional) param data passed sent with request",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in  as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "httpDo": {
            +      "description": [
            +        "Method for executing an HTTP request. If data type is not specified, p5 will try to guess based on the URL, defaulting to text. For more advanced use, you may also pass in the path as the first argument and a object as the second argument, the signature follows the one specified in the Fetch API specification. This method is suitable for fetching files up to size of 64MB when \"GET\" is used."
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "method": "String: (Optional) either \"GET\", \"POST\", or \"PUT\",  defaults to \"GET\"",
            +        "datatype": "String: (Optional) \"json\", \"jsonp\", \"xml\", or \"text\"",
            +        "data": "Object: (Optional) param data passed sent with request",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in  as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument",
            +        "options": "Object: Request object options as documented in the  \"fetch\" API <a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a>"
            +      }
            +    },
            +    "createWriter": {
            +      "returns": "p5.PrintWriter:",
            +      "params": {
            +        "name": "String: name of the file to be created",
            +        "extension": "String (Optional)"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "Saves a given element(image, text, json, csv, wav, or html) to the client's computer. The first parameter can be a pointer to element we want to save. The element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of Strings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table </a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires p5.sound). The second parameter is a filename (including extension).The third parameter is for options specific to this type of object. This method will save a file that fits the given parameters. If it is called without specifying an element, by default it will save the whole canvas as an image file. You can optionally specify a filename as the first parameter in such a case. <strong>Note that it is not recommended to call this method within draw, as it will open a new save dialog on every render.</strong>"
            +      ],
            +      "params": {
            +        "objectOrFilename": "Object|String: (Optional) If filename is provided, will  save canvas as an image with  either png or jpg extension  depending on the filename.  If object is provided, will  save depending on the object  and filename (see examples  above).",
            +        "filename": "String: (Optional) If an object is provided as the first  parameter, then the second parameter  indicates the filename,  and should include an appropriate  file extension (see examples above).",
            +        "options": "Boolean|String: (Optional) Additional options depend on  filetype. For example, when saving JSON,  <code>true</code> indicates that the  output will be optimized for filesize,  rather than readability."
            +      }
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "Writes the contents of an Array or a JSON object to a .json file. The file saving process and location of the saved file will vary between web browsers."
            +      ],
            +      "params": {
            +        "json": "Array|Object",
            +        "filename": "String",
            +        "optimize": "Boolean: (Optional) If true, removes line breaks  and spaces from the output  file to optimize filesize  (but not readability)."
            +      }
            +    },
            +    "saveStrings": {
            +      "description": [
            +        "Writes an array of Strings to a text file, one line per String. The file saving process and location of the saved file will vary between web browsers."
            +      ],
            +      "params": {
            +        "list": "String[]: string array to be written",
            +        "filename": "String: filename for output",
            +        "extension": "String: (Optional) the filename's extension",
            +        "isCRLF": "Boolean: (Optional) if true, change line-break to CRLF"
            +      }
            +    },
            +    "saveTable": {
            +      "description": [
            +        "Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a text file with comma-separated-values ('csv') but can also use tab separation ('tsv'), or generate an HTML table ('html'). The file saving process and location of the saved file will vary between web browsers."
            +      ],
            +      "params": {
            +        "Table": "p5.Table: the <a href=\"#/p5.Table\">Table</a> object to save to a file",
            +        "filename": "String: the filename to which the Table should be saved",
            +        "options": "String: (Optional) can be one of \"tsv\", \"csv\", or \"html\""
            +      }
            +    },
            +    "abs": {
            +      "description": [
            +        "Calculates the absolute value (magnitude) of a number. Maps to Math.abs(). The absolute value of a number is always positive."
            +      ],
            +      "returns": "Number: absolute value of given number",
            +      "params": {
            +        "n": "Number: number to compute"
            +      }
            +    },
            +    "ceil": {
            +      "description": [
            +        "Calculates the closest int value that is greater than or equal to the value of the parameter. Maps to Math.ceil(). For example, ceil(9.03) returns the value 10."
            +      ],
            +      "returns": "Integer: rounded up number",
            +      "params": {
            +        "n": "Number: number to round up"
            +      }
            +    },
            +    "constrain": {
            +      "description": [
            +        "Constrains a value between a minimum and maximum value."
            +      ],
            +      "returns": "Number: constrained number",
            +      "params": {
            +        "n": "Number: number to constrain",
            +        "low": "Number: minimum limit",
            +        "high": "Number: maximum limit"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "Calculates the distance between two points, in either two or three dimensions. If you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a>"
            +      ],
            +      "returns": "Number: distance between the two points",
            +      "params": {
            +        "x1": "Number: x-coordinate of the first point",
            +        "y1": "Number: y-coordinate of the first point",
            +        "x2": "Number: x-coordinate of the second point",
            +        "y2": "Number: y-coordinate of the second point",
            +        "z1": "Number: z-coordinate of the first point",
            +        "z2": "Number: z-coordinate of the second point"
            +      }
            +    },
            +    "exp": {
            +      "description": [
            +        "Returns Euler's number e (2.71828...) raised to the power of the n parameter. Maps to Math.exp()."
            +      ],
            +      "returns": "Number: e^n",
            +      "params": {
            +        "n": "Number: exponent to raise"
            +      }
            +    },
            +    "floor": {
            +      "description": [
            +        "Calculates the closest int value that is less than or equal to the value of the parameter. Maps to Math.floor()."
            +      ],
            +      "returns": "Integer: rounded down number",
            +      "params": {
            +        "n": "Number: number to round down"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "Calculates a number between two numbers at a specific increment. The amt parameter is the amount to interpolate between the two values where 0.0 equal to the first point, 0.1 is very near the first point, 0.5 is half-way in between, and 1.0 is equal to the second point. If the value of amt is more than 1.0 or less than 0.0, the number will be calculated accordingly in the ratio of the two given numbers. The lerp function is convenient for creating motion along a straight path and for drawing dotted lines."
            +      ],
            +      "returns": "Number: lerped value",
            +      "params": {
            +        "start": "Number: first value",
            +        "stop": "Number: second value",
            +        "amt": "Number: number"
            +      }
            +    },
            +    "log": {
            +      "description": [
            +        "Calculates the natural logarithm (the base-e logarithm) of a number. This function expects the n parameter to be a value greater than 0.0. Maps to Math.log()."
            +      ],
            +      "returns": "Number: natural logarithm of n",
            +      "params": {
            +        "n": "Number: number greater than 0"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "Calculates the magnitude (or length) of a vector. A vector is a direction in space commonly used in computer graphics and linear algebra. Because it has no \"start\" position, the magnitude of a vector can be thought of as the distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is a shortcut for writing dist(0, 0, x, y)."
            +      ],
            +      "returns": "Number: magnitude of vector from (0,0) to (a,b)",
            +      "params": {
            +        "a": "Number: first value",
            +        "b": "Number: second value"
            +      }
            +    },
            +    "map": {
            +      "description": [
            +        "Re-maps a number from one range to another.",
            +        "In the first example above, the number 25 is converted from a value in the range of 0 to 100 into a value that ranges from the left edge of the window (0) to the right edge (width)."
            +      ],
            +      "returns": "Number: remapped number",
            +      "params": {
            +        "value": "Number: the incoming value to be converted",
            +        "start1": "Number: lower bound of the value's current range",
            +        "stop1": "Number: upper bound of the value's current range",
            +        "start2": "Number: lower bound of the value's target range",
            +        "stop2": "Number: upper bound of the value's target range",
            +        "withinBounds": "Boolean: (Optional) constrain the value to the newly mapped range"
            +      }
            +    },
            +    "max": {
            +      "description": [
            +        "Determines the largest value in a sequence of numbers, and then returns that value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array of any length."
            +      ],
            +      "returns": "Number: maximum Number",
            +      "params": {
            +        "n0": "Number: Number to compare",
            +        "n1": "Number: Number to compare",
            +        "nums": "Number[]: Numbers to compare"
            +      }
            +    },
            +    "min": {
            +      "description": [
            +        "Determines the smallest value in a sequence of numbers, and then returns that value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array of any length."
            +      ],
            +      "returns": "Number: minimum Number",
            +      "params": {
            +        "n0": "Number: Number to compare",
            +        "n1": "Number: Number to compare",
            +        "nums": "Number[]: Numbers to compare"
            +      }
            +    },
            +    "norm": {
            +      "description": [
            +        "Normalizes a number from another range into a value between 0 and 1. Identical to map(value, low, high, 0, 1). Numbers outside of the range are not clamped to 0 and 1, because out-of-range values are often intentional and useful. (See the example above.)"
            +      ],
            +      "returns": "Number: normalized number",
            +      "params": {
            +        "value": "Number: incoming value to be normalized",
            +        "start": "Number: lower bound of the value's current range",
            +        "stop": "Number: upper bound of the value's current range"
            +      }
            +    },
            +    "pow": {
            +      "description": [
            +        "Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient way of multiplying numbers by themselves (or their reciprocals) in large quantities. For example, pow(3, 5) is equivalent to the expression 3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 / 3 × 3 × 3 × 3 × 3. Maps to Math.pow()."
            +      ],
            +      "returns": "Number: n^e",
            +      "params": {
            +        "n": "Number: base of the exponential expression",
            +        "e": "Number: power by which to raise the base"
            +      }
            +    },
            +    "round": {
            +      "description": [
            +        "Calculates the integer closest to the n parameter. For example, round(133.8) returns the value 134. Maps to Math.round()."
            +      ],
            +      "returns": "Integer: rounded number",
            +      "params": {
            +        "n": "Number: number to round",
            +        "decimals": "Number: (Optional) number of decimal places to round to, default is 0"
            +      }
            +    },
            +    "sq": {
            +      "description": [
            +        "Squares a number (multiplies a number by itself). The result is always a positive number, as multiplying two negative numbers always yields a positive result. For example, -1 * -1 = 1."
            +      ],
            +      "returns": "Number: squared number",
            +      "params": {
            +        "n": "Number: number to square"
            +      }
            +    },
            +    "sqrt": {
            +      "description": [
            +        "Calculates the square root of a number. The square root of a number is always positive, even though there may be a valid negative root. The square root s of number a is such that s*s = a. It is the opposite of squaring. Maps to Math.sqrt()."
            +      ],
            +      "returns": "Number: square root of number",
            +      "params": {
            +        "n": "Number: non-negative number to square root"
            +      }
            +    },
            +    "fract": {
            +      "description": [
            +        "Calculates the fractional part of a number."
            +      ],
            +      "returns": "Number: fractional part of x, i.e, {x}",
            +      "params": {
            +        "num": "Number: Number whose fractional part needs to be found out"
            +      }
            +    },
            +    "createVector": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector. A vector is an entity that has both magnitude and direction."
            +      ],
            +      "returns": "p5.Vector:",
            +      "params": {
            +        "x": "Number: (Optional) x component of the vector",
            +        "y": "Number: (Optional) y component of the vector",
            +        "z": "Number: (Optional) z component of the vector"
            +      }
            +    },
            +    "noise": {
            +      "description": [
            +        "Returns the Perlin noise value at specified coordinates. Perlin noise is a random sequence generator producing a more naturally ordered, harmonic succession of numbers compared to the standard <b>random()</b> function. It was invented by Ken Perlin in the 1980s and been used since in graphical applications to produce procedural textures, natural motion, shapes, terrains etc.<br /><br /> The main difference to the <b>random()</b> function is that Perlin noise is defined in an infinite n-dimensional space where each pair of coordinates corresponds to a fixed semi-random value (fixed only for the lifespan of the program; see the <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise, depending on the number of coordinates given. The resulting value will always be between 0.0 and 1.0. The noise value can be animated by moving through the noise space as demonstrated in the example above. The 2nd and 3rd dimension can also be interpreted as time.<br /><br />The actual noise is structured similar to an audio signal, in respect to the function's use of frequencies. Similar to the concept of harmonics in physics, perlin noise is computed over several octaves which are added together for the final result. <br /><br />Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the function works within an infinite space the value of the coordinates doesn't matter as such, only the distance between successive coordinates does (eg. when using <b>noise()</b> within a loop). As a general rule the smaller the difference between coordinates, the smoother the resulting noise sequence will be. Steps of 0.005-0.03 work best for most applications, but this will differ depending on use."
            +      ],
            +      "returns": "Number: Perlin noise value (between 0 and 1) at specified  coordinates",
            +      "params": {
            +        "x": "Number: x-coordinate in noise space",
            +        "y": "Number: (Optional) y-coordinate in noise space",
            +        "z": "Number: (Optional) z-coordinate in noise space"
            +      }
            +    },
            +    "noiseDetail": {
            +      "description": [
            +        "Adjusts the character and level of detail produced by the Perlin noise  function. Similar to harmonics in physics, noise is computed over  several octaves. Lower octaves contribute more to the output signal and  as such define the overall intensity of the noise, whereas higher octaves  create finer grained details in the noise sequence. By default, noise is computed over 4 octaves with each octave contributing  exactly half than its predecessor, starting at 50% strength for the 1st  octave. This falloff amount can be changed by adding an additional function  parameter. Eg. a falloff factor of 0.75 means each octave will now have  75% impact (25% less) of the previous lower octave. Any value between  0.0 and 1.0 is valid, however note that values greater than 0.5 might  result in greater than 1.0 values returned by <b>noise()</b>. By changing these parameters, the signal created by the <b>noise()</b>  function can be adapted to fit very specific needs and characteristics."
            +      ],
            +      "params": {
            +        "lod": "Number: number of octaves to be used by the noise",
            +        "falloff": "Number: falloff factor for each octave"
            +      }
            +    },
            +    "noiseSeed": {
            +      "description": [
            +        "Sets the seed value for <b>noise()</b>. By default, <b>noise()</b> produces different results each time the program is run. Set the <b>value</b> parameter to a constant to return the same pseudo-random numbers each time the software is run."
            +      ],
            +      "params": {
            +        "seed": "Number: the seed value"
            +      }
            +    },
            +    "randomSeed": {
            +      "description": [
            +        "Sets the seed value for <a href=\"#/p5/random\">random()</a>.",
            +        "By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program is run. Set the seed parameter to a constant to return the same pseudo-random numbers each time the software is run."
            +      ],
            +      "params": {
            +        "seed": "Number: the seed value"
            +      }
            +    },
            +    "random": {
            +      "description": [
            +        "Return a random floating-point number.",
            +        "Takes either 0, 1 or 2 arguments.",
            +        "If no argument is given, returns a random number from 0 up to (but not including) 1.",
            +        "If one argument is given and it is a number, returns a random number from 0 up to (but not including) the number.",
            +        "If one argument is given and it is an array, returns a random element from that array.",
            +        "If two arguments are given, returns a random number from the first argument up to (but not including) the second argument."
            +      ],
            +      "returns": "Number: the random number",
            +      "params": {
            +        "min": "Number: (Optional) the lower bound (inclusive)",
            +        "max": "Number: (Optional) the upper bound (exclusive)",
            +        "choices": "Array: the array to choose from"
            +      }
            +    },
            +    "randomGaussian": {
            +      "description": [
            +        "Returns a random number fitting a Gaussian, or  normal, distribution. There is theoretically no minimum or maximum  value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is  just a very low probability that values far from the mean will be  returned; and a higher probability that numbers near the mean will  be returned. Takes either 0, 1 or 2 arguments.  If no args, returns a mean of 0 and standard deviation of 1.  If one arg, that arg is the mean (standard deviation is 1).  If two args, first is mean, second is standard deviation."
            +      ],
            +      "returns": "Number: the random number",
            +      "params": {
            +        "mean": "Number: (Optional) the mean",
            +        "sd": "Number: (Optional) the standard deviation"
            +      }
            +    },
            +    "acos": {
            +      "description": [
            +        "The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value. This function expects the values in the range of -1 to 1 and values are returned in the range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the angle mode is DEGREES."
            +      ],
            +      "returns": "Number: the arc cosine of the given value",
            +      "params": {
            +        "value": "Number: the value whose arc cosine is to be returned"
            +      }
            +    },
            +    "asin": {
            +      "description": [
            +        "The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value. This function expects the values in the range of -1 to 1 and values are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle mode is DEGREES."
            +      ],
            +      "returns": "Number: the arc sine of the given value",
            +      "params": {
            +        "value": "Number: the value whose arc sine is to be returned"
            +      }
            +    },
            +    "atan": {
            +      "description": [
            +        "The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value. This function expects the values in the range of -Infinity to Infinity (exclusive) and values are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle mode is DEGREES."
            +      ],
            +      "returns": "Number: the arc tangent of the given value",
            +      "params": {
            +        "value": "Number: the value whose arc tangent is to be returned"
            +      }
            +    },
            +    "atan2": {
            +      "description": [
            +        "Calculates the angle (in radians) from a specified point to the coordinate origin as measured from the positive x-axis. Values are returned as a float in the range from PI to -PI if the angleMode is RADIANS or 180 to -180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is most often used for orienting geometry to the position of the cursor.",
            +        "Note: The y-coordinate of the point is the first parameter, and the x-coordinate is the second parameter, due the the structure of calculating the tangent."
            +      ],
            +      "returns": "Number: the arc tangent of the given point",
            +      "params": {
            +        "y": "Number: y-coordinate of the point",
            +        "x": "Number: x-coordinate of the point"
            +      }
            +    },
            +    "cos": {
            +      "description": [
            +        "Calculates the cosine of an angle. This function takes into account the current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1."
            +      ],
            +      "returns": "Number: the cosine of the angle",
            +      "params": {
            +        "angle": "Number: the angle"
            +      }
            +    },
            +    "sin": {
            +      "description": [
            +        "Calculates the sine of an angle. This function takes into account the current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1."
            +      ],
            +      "returns": "Number: the sine of the angle",
            +      "params": {
            +        "angle": "Number: the angle"
            +      }
            +    },
            +    "tan": {
            +      "description": [
            +        "Calculates the tangent of an angle. This function takes into account the current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers."
            +      ],
            +      "returns": "Number: the tangent of the angle",
            +      "params": {
            +        "angle": "Number: the angle"
            +      }
            +    },
            +    "degrees": {
            +      "description": [
            +        "Converts a radian measurement to its corresponding value in degrees. Radians and degrees are two ways of measuring the same thing. There are 360 degrees in a circle and 2*PI radians in a circle. For example, 90° = PI/2 = 1.5707964. This function does not take into account the current <a href=\"#/p5/angleMode\">angleMode</a>."
            +      ],
            +      "returns": "Number: the converted angle",
            +      "params": {
            +        "radians": "Number: the radians value to convert to degrees"
            +      }
            +    },
            +    "radians": {
            +      "description": [
            +        "Converts a degree measurement to its corresponding value in radians. Radians and degrees are two ways of measuring the same thing. There are 360 degrees in a circle and 2*PI radians in a circle. For example, 90° = PI/2 = 1.5707964. This function does not take into account the current <a href=\"#/p5/angleMode\">angleMode</a>."
            +      ],
            +      "returns": "Number: the converted angle",
            +      "params": {
            +        "degrees": "Number: the degree value to convert to radians"
            +      }
            +    },
            +    "angleMode": {
            +      "description": [
            +        "Sets the current mode of p5 to given mode. Default mode is RADIANS."
            +      ],
            +      "params": {
            +        "mode": "Constant: either RADIANS or DEGREES"
            +      }
            +    },
            +    "textAlign": {
            +      "description": [
            +        "Sets the current alignment for drawing text. Accepts two arguments: horizAlign (LEFT, CENTER, or RIGHT) and vertAlign (TOP, BOTTOM, CENTER, or BASELINE).",
            +        "The horizAlign parameter is in reference to the x value of the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter is in reference to the y value.",
            +        "So if you write textAlign(LEFT), you are aligning the left edge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>. If you write textAlign(RIGHT, TOP), you are aligning the right edge of your text to the x value and the top of edge of the text to the y value."
            +      ],
            +      "params": {
            +        "horizAlign": "Constant: horizontal alignment, either LEFT,  CENTER, or RIGHT",
            +        "vertAlign": "Constant: (Optional) vertical alignment, either TOP,  BOTTOM, CENTER, or BASELINE"
            +      }
            +    },
            +    "textLeading": {
            +      "description": [
            +        "Sets/gets the spacing, in pixels, between lines of text. This setting will be used in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function."
            +      ],
            +      "params": {
            +        "leading": "Number: the size in pixels for spacing between lines"
            +      }
            +    },
            +    "textSize": {
            +      "description": [
            +        "Sets/gets the current font size. This size will be used in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels."
            +      ],
            +      "params": {
            +        "theSize": "Number: the size of the letters in units of pixels"
            +      }
            +    },
            +    "textStyle": {
            +      "description": [
            +        "Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC. Note: this may be is overridden by CSS styling. For non-system fonts (opentype, truetype, etc.) please load styled fonts instead."
            +      ],
            +      "params": {
            +        "theStyle": "Constant: styling for text, either NORMAL,  ITALIC, BOLD or BOLDITALIC"
            +      }
            +    },
            +    "textWidth": {
            +      "description": [
            +        "Calculates and returns the width of any character or text string."
            +      ],
            +      "returns": "Number: the calculated width",
            +      "params": {
            +        "theText": "String: the String of characters to measure"
            +      }
            +    },
            +    "textAscent": {
            +      "description": [
            +        "Returns the ascent of the current font at its current size. The ascent represents the distance, in pixels, of the tallest character above the baseline."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "textDescent": {
            +      "description": [
            +        "Returns the descent of the current font at its current size. The descent represents the distance, in pixels, of the character with the longest descender below the baseline."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "textWrap": {
            +      "description": [
            +        "Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.",
            +        "WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.",
            +        "CHAR wrap style breaks lines wherever needed to stay within the text box.",
            +        "WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen."
            +      ],
            +      "returns": "String: wrapStyle",
            +      "params": {
            +        "wrapStyle": "Constant: text wrapping style, either WORD or CHAR"
            +      }
            +    },
            +    "loadFont": {
            +      "description": [
            +        "Loads an opentype font file (.otf, .ttf) from a file or a URL, and returns a PFont Object. This method is asynchronous, meaning it may not finish before the next line in your sketch is executed.",
            +        "The path to the font should be relative to the HTML file that links in your sketch. Loading fonts from a URL or other remote location may be blocked due to your browser's built-in security."
            +      ],
            +      "returns": "p5.Font: <a href=\"#/p5.Font\">p5.Font</a> object",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/loadFont\">loadFont()</a> completes",
            +        "onError": "Function: (Optional) function to be executed if  an error occurs"
            +      }
            +    },
            +    "text": {
            +      "description": [
            +        "Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. A default font will be used unless a font is set with the <a href=\"#/p5/textFont\">textFont()</a> function and a default size will be used unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change the color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change the outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and <a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.",
            +        "The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a> function, which gives the option to draw to the left, right, and center of the coordinates.",
            +        "The x2 and y2 parameters define a rectangular area to display within and may only be used with string data. When these parameters are specified, they are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a> setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. If x2 and y2 are not specified, the baseline alignment is the default, which means that the text will be drawn upwards from x and y.",
            +        "<b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font using the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above). <a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode."
            +      ],
            +      "params": {
            +        "str": "String|Object|Array|Number|Boolean: the alphanumeric  symbols to be displayed",
            +        "x": "Number: x-coordinate of text",
            +        "y": "Number: y-coordinate of text",
            +        "x2": "Number: (Optional) by default, the width of the text box,  see <a href=\"#/p5/rectMode\">rectMode()</a> for more info",
            +        "y2": "Number: (Optional) by default, the height of the text box,  see <a href=\"#/p5/rectMode\">rectMode()</a> for more info"
            +      }
            +    },
            +    "textFont": {
            +      "description": [
            +        "Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function. If textFont() is called without any argument, it will return the current font if one has been set already. If not, it will return the name of the default font as a string. If textFont() is called with a font to use, it will return the p5 object.",
            +        "<b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported."
            +      ],
            +      "returns": "Object: the current font / p5 Object",
            +      "params": {
            +        "font": "Object|String: a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>, or a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a> (a font that is generally available across all systems)",
            +        "size": "Number: (Optional) the font size to use"
            +      }
            +    },
            +    "append": {
            +      "description": [
            +        "Adds a value to the end of an array. Extends the length of the array by one. Maps to Array.push()."
            +      ],
            +      "returns": "Array: the array that was appended to",
            +      "params": {
            +        "array": "Array: Array to append",
            +        "value": "Any: to be added to the Array"
            +      }
            +    },
            +    "arrayCopy": {
            +      "description": [
            +        "Copies an array (or part of an array) to another array. The src array is copied to the dst array, beginning at the position specified by srcPosition and into the position specified by dstPosition. The number of elements to copy is determined by length. Note that copying values overwrites existing values in the destination array. To append values instead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.",
            +        "The simplified version with only two arguments, arrayCopy(src, dst), copies an entire array to another of the same size. It is equivalent to arrayCopy(src, 0, dst, 0, src.length).",
            +        "Using this function is far more efficient for copying array data than iterating through a for() loop and copying each element individually."
            +      ],
            +      "params": {
            +        "src": "Array: the source Array",
            +        "srcPosition": "Integer: starting position in the source Array",
            +        "dst": "Array: the destination Array",
            +        "dstPosition": "Integer: starting position in the destination Array",
            +        "length": "Integer: number of Array elements to be copied"
            +      }
            +    },
            +    "concat": {
            +      "description": [
            +        "Concatenates two arrays, maps to Array.concat(). Does not modify the input arrays."
            +      ],
            +      "returns": "Array: concatenated array",
            +      "params": {
            +        "a": "Array: first Array to concatenate",
            +        "b": "Array: second Array to concatenate"
            +      }
            +    },
            +    "reverse": {
            +      "description": [
            +        "Reverses the order of an array, maps to Array.reverse()"
            +      ],
            +      "returns": "Array: the reversed list",
            +      "params": {
            +        "list": "Array: Array to reverse"
            +      }
            +    },
            +    "shorten": {
            +      "description": [
            +        "Decreases an array by one element and returns the shortened array, maps to Array.pop()."
            +      ],
            +      "returns": "Array: shortened Array",
            +      "params": {
            +        "list": "Array: Array to shorten"
            +      }
            +    },
            +    "shuffle": {
            +      "description": [
            +        "Randomizes the order of the elements of an array. Implements <a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank> Fisher-Yates Shuffle Algorithm</a>."
            +      ],
            +      "returns": "Array: shuffled Array",
            +      "params": {
            +        "array": "Array: Array to shuffle",
            +        "bool": "Boolean: (Optional) modify passed array"
            +      }
            +    },
            +    "sort": {
            +      "description": [
            +        "Sorts an array of numbers from smallest to largest, or puts an array of words in alphabetical order. The original array is not modified; a re-ordered array is returned. The count parameter states the number of elements to sort. For example, if there are 12 elements in an array and count is set to 5, only the first 5 elements in the array will be sorted."
            +      ],
            +      "returns": "Array: the sorted list",
            +      "params": {
            +        "list": "Array: Array to sort",
            +        "count": "Integer: (Optional) number of elements to sort, starting from 0"
            +      }
            +    },
            +    "splice": {
            +      "description": [
            +        "Inserts a value or an array of values into an existing array. The first parameter specifies the initial array to be modified, and the second parameter defines the data to be inserted. The third parameter is an index value which specifies the array position from which to insert data. (Remember that array index numbering starts at zero, so the first position is 0, the second position is 1, and so on.)"
            +      ],
            +      "returns": "Array: the list",
            +      "params": {
            +        "list": "Array: Array to splice into",
            +        "value": "Any: value to be spliced in",
            +        "position": "Integer: in the array from which to insert data"
            +      }
            +    },
            +    "subset": {
            +      "description": [
            +        "Extracts an array of elements from an existing array. The list parameter defines the array from which the elements will be copied, and the start and count parameters specify which elements to extract. If no count is given, elements will be extracted from the start to the end of the array. When specifying the start, remember that the first array element is 0. This function does not change the source array."
            +      ],
            +      "returns": "Array: Array of extracted elements",
            +      "params": {
            +        "list": "Array: Array to extract from",
            +        "start": "Integer: position to begin",
            +        "count": "Integer: (Optional) number of values to extract"
            +      }
            +    },
            +    "float": {
            +      "description": [
            +        "Converts a string to its floating point representation. The contents of a string must resemble a number, or NaN (not a number) will be returned. For example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\") will return NaN.",
            +        "When an array of values is passed in, then an array of floats of the same length is returned."
            +      ],
            +      "returns": "Number: floating point representation of string",
            +      "params": {
            +        "str": "String: float string to parse"
            +      }
            +    },
            +    "int": {
            +      "description": [
            +        "Converts a boolean, string, or float to its integer representation. When an array of values is passed in, then an int array of the same length is returned."
            +      ],
            +      "returns": "Number: integer representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number: value to parse",
            +        "radix": "Integer: (Optional) the radix to convert to (default: 10)",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "str": {
            +      "description": [
            +        "Converts a boolean, string or number to its string representation. When an array of values is passed in, then an array of strings of the same length is returned."
            +      ],
            +      "returns": "String: string representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number|Array: value to parse"
            +      }
            +    },
            +    "byte": {
            +      "description": [
            +        "Converts a number, string representation of a number, or boolean to its byte representation. A byte can be only a whole number between -128 and 127, so when a value outside of this range is converted, it wraps around to the corresponding byte representation. When an array of number, string or boolean values is passed in, then an array of bytes the same length is returned."
            +      ],
            +      "returns": "Number: byte representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "char": {
            +      "description": [
            +        "Converts a number or string to its corresponding single-character string representation. If a string parameter is provided, it is first parsed as an integer and then translated into a single-character string. When an array of number or string values is passed in, then an array of single-character strings of the same length is returned."
            +      ],
            +      "returns": "String: string representation of value",
            +      "params": {
            +        "n": "String|Number: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "unchar": {
            +      "description": [
            +        "Converts a single-character string to its corresponding integer representation. When an array of single-character string values is passed in, then an array of integers of the same length is returned."
            +      ],
            +      "returns": "Number: integer representation of value",
            +      "params": {
            +        "n": "String: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "hex": {
            +      "description": [
            +        "Converts a number to a string in its equivalent hexadecimal notation. If a second parameter is passed, it is used to set the number of characters to generate in the hexadecimal notation. When an array is passed in, an array of strings in hexadecimal notation of the same length is returned."
            +      ],
            +      "returns": "String: hexadecimal string representation of value",
            +      "params": {
            +        "n": "Number: value to parse",
            +        "digits": "Number (Optional)",
            +        "ns": "Number[]: array of values to parse"
            +      }
            +    },
            +    "unhex": {
            +      "description": [
            +        "Converts a string representation of a hexadecimal number to its equivalent integer value. When an array of strings in hexadecimal notation is passed in, an array of integers of the same length is returned."
            +      ],
            +      "returns": "Number: integer representation of hexadecimal value",
            +      "params": {
            +        "n": "String: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "join": {
            +      "description": [
            +        "Combines an array of Strings into one String, each separated by the character(s) used for the separator parameter. To join arrays of ints or floats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or nfs()."
            +      ],
            +      "returns": "String: joined String",
            +      "params": {
            +        "list": "Array: array of Strings to be joined",
            +        "separator": "String: String to be placed between each item"
            +      }
            +    },
            +    "match": {
            +      "description": [
            +        "This function is used to apply a regular expression to a piece of text, and return matching groups (elements found inside parentheses) as a String array. If there are no matches, a null value will be returned. If no groups are specified in the regular expression, but the sequence matches, an array of length 1 (with the matched text as the first element of the array) will be returned.",
            +        "To use the function, first check to see if the result is null. If the result is null, then the sequence did not match at all. If the sequence did match, an array is returned.",
            +        "If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Element [0] of a regular expression match returns the entire matching string, and the match groups start at element [1] (the first group is [1], the second [2], and so on)."
            +      ],
            +      "returns": "String[]: Array of Strings found",
            +      "params": {
            +        "str": "String: the String to be searched",
            +        "regexp": "String: the regexp to be used for matching"
            +      }
            +    },
            +    "matchAll": {
            +      "description": [
            +        "This function is used to apply a regular expression to a piece of text, and return a list of matching groups (elements found inside parentheses) as a two-dimensional String array. If there are no matches, a null value will be returned. If no groups are specified in the regular expression, but the sequence matches, a two dimensional array is still returned, but the second dimension is only of length one.",
            +        "To use the function, first check to see if the result is null. If the result is null, then the sequence did not match at all. If the sequence did match, a 2D array is returned.",
            +        "If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Assuming a loop with counter variable i, element [i][0] of a regular expression match returns the entire matching string, and the match groups start at element [i][1] (the first group is [i][1], the second [i][2], and so on)."
            +      ],
            +      "returns": "String[]: 2d Array of Strings found",
            +      "params": {
            +        "str": "String: the String to be searched",
            +        "regexp": "String: the regexp to be used for matching"
            +      }
            +    },
            +    "nf": {
            +      "description": [
            +        "Utility function for formatting numbers into strings. There are two versions: one for formatting floats, and one for formatting ints. The values for the digits, left, and right parameters should always be positive integers. (NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter if greater than the current length of the number. For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123 (integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than the result will be 123.200."
            +      ],
            +      "returns": "String: formatted String",
            +      "params": {
            +        "num": "Number|String: the Number to format",
            +        "left": "Integer|String: (Optional) number of digits to the left of the  decimal point",
            +        "right": "Integer|String: (Optional) number of digits to the right of the  decimal point",
            +        "nums": "Array: the Numbers to format"
            +      }
            +    },
            +    "nfc": {
            +      "description": [
            +        "Utility function for formatting numbers into strings and placing appropriate commas to mark units of 1000. There are two versions: one for formatting ints, and one for formatting an array of ints. The value for the right parameter should always be a positive integer."
            +      ],
            +      "returns": "String: formatted String",
            +      "params": {
            +        "num": "Number|String: the Number to format",
            +        "right": "Integer|String: (Optional) number of digits to the right of the  decimal point",
            +        "nums": "Array: the Numbers to format"
            +      }
            +    },
            +    "nfp": {
            +      "description": [
            +        "Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but puts a \"+\" in front of positive numbers and a \"-\" in front of negative numbers. There are two versions: one for formatting floats, and one for formatting ints. The values for left, and right parameters should always be positive integers."
            +      ],
            +      "returns": "String: formatted String",
            +      "params": {
            +        "num": "Number: the Number to format",
            +        "left": "Integer: (Optional) number of digits to the left of the decimal  point",
            +        "right": "Integer: (Optional) number of digits to the right of the  decimal point",
            +        "nums": "Number[]: the Numbers to format"
            +      }
            +    },
            +    "nfs": {
            +      "description": [
            +        "Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but puts an additional \"_\" (space) in front of positive numbers just in case to align it with negative numbers which includes \"-\" (minus) sign. The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative number with some negative number (See the example to get a clear picture). There are two versions: one for formatting float, and one for formatting int. The values for the digits, left, and right parameters should always be positive integers. (IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using. (NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter if greater than the current length of the number. For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123 (integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than the result will be 123.200."
            +      ],
            +      "returns": "String: formatted String",
            +      "params": {
            +        "num": "Number: the Number to format",
            +        "left": "Integer: (Optional) number of digits to the left of the decimal  point",
            +        "right": "Integer: (Optional) number of digits to the right of the  decimal point",
            +        "nums": "Array: the Numbers to format"
            +      }
            +    },
            +    "split": {
            +      "description": [
            +        "The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into pieces using a character or string as the delimiter. The delim parameter specifies the character or characters that mark the boundaries between each piece. A String[] array is returned that contains each of the pieces.",
            +        "The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it splits using a range of characters instead of a specific character or sequence."
            +      ],
            +      "returns": "String[]: Array of Strings",
            +      "params": {
            +        "value": "String: the String to be split",
            +        "delim": "String: the String used to separate the data"
            +      }
            +    },
            +    "splitTokens": {
            +      "description": [
            +        "The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character delimiters or \"tokens.\" The delim parameter specifies the character or characters to be used as a boundary.",
            +        "If no delim characters are specified, any whitespace character is used to split. Whitespace characters include tab (\\t), line feed (\\n), carriage return (\\r), form feed (\\f), and space."
            +      ],
            +      "returns": "String[]: Array of Strings",
            +      "params": {
            +        "value": "String: the String to be split",
            +        "delim": "String: (Optional) list of individual Strings that will be used as  separators"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "Removes whitespace characters from the beginning and end of a String. In addition to standard whitespace characters such as space, carriage return, and tab, this function also removes the Unicode \"nbsp\" character."
            +      ],
            +      "returns": "String: a trimmed String",
            +      "params": {
            +        "str": "String: a String to be trimmed",
            +        "strs": "Array: an Array of Strings to be trimmed"
            +      }
            +    },
            +    "day": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function returns the current day as a value from 1 - 31."
            +      ],
            +      "returns": "Integer: the current day"
            +    },
            +    "hour": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function returns the current hour as a value from 0 - 23."
            +      ],
            +      "returns": "Integer: the current hour"
            +    },
            +    "minute": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function returns the current minute as a value from 0 - 59."
            +      ],
            +      "returns": "Integer: the current minute"
            +    },
            +    "millis": {
            +      "description": [
            +        "Returns the number of milliseconds (thousandths of a second) since starting the sketch (when <code>setup()</code> is called). This information is often used for timing events and animation sequences."
            +      ],
            +      "returns": "Number: the number of milliseconds since starting the sketch"
            +    },
            +    "month": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function returns the current month as a value from 1 - 12."
            +      ],
            +      "returns": "Integer: the current month"
            +    },
            +    "second": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function returns the current second as a value from 0 - 59."
            +      ],
            +      "returns": "Integer: the current second"
            +    },
            +    "year": {
            +      "description": [
            +        "p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function returns the current year as an integer (2014, 2015, 2016, etc)."
            +      ],
            +      "returns": "Integer: the current year"
            +    },
            +    "plane": {
            +      "description": [
            +        "Draw a plane with given a width and height"
            +      ],
            +      "params": {
            +        "width": "Number: (Optional) width of the plane",
            +        "height": "Number: (Optional) height of the plane",
            +        "detailX": "Integer: (Optional) Optional number of triangle  subdivisions in x-dimension",
            +        "detailY": "Integer: (Optional) Optional number of triangle  subdivisions in y-dimension"
            +      }
            +    },
            +    "box": {
            +      "description": [
            +        "Draw a box with given width, height and depth"
            +      ],
            +      "params": {
            +        "width": "Number: (Optional) width of the box",
            +        "Height": "Number: (Optional) height of the box",
            +        "depth": "Number: (Optional) depth of the box",
            +        "detailX": "Integer: (Optional) Optional number of triangle  subdivisions in x-dimension",
            +        "detailY": "Integer: (Optional) Optional number of triangle  subdivisions in y-dimension"
            +      }
            +    },
            +    "sphere": {
            +      "description": [
            +        "Draw a sphere with given radius.",
            +        "DetailX and detailY determines the number of subdivisions in the x-dimension and the y-dimension of a sphere. More subdivisions make the sphere seem smoother. The recommended maximum values are both 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "Number: (Optional) radius of circle",
            +        "detailX": "Integer: (Optional) optional number of subdivisions in x-dimension",
            +        "detailY": "Integer: (Optional) optional number of subdivisions in y-dimension"
            +      }
            +    },
            +    "cylinder": {
            +      "description": [
            +        "Draw a cylinder with given radius and height",
            +        "DetailX and detailY determines the number of subdivisions in the x-dimension and the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother. The recommended maximum value for detailX is 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "Number: (Optional) radius of the surface",
            +        "height": "Number: (Optional) height of the cylinder",
            +        "detailX": "Integer: (Optional) number of subdivisions in x-dimension;  default is 24",
            +        "detailY": "Integer: (Optional) number of subdivisions in y-dimension;  default is 1",
            +        "bottomCap": "Boolean: (Optional) whether to draw the bottom of the cylinder",
            +        "topCap": "Boolean: (Optional) whether to draw the top of the cylinder"
            +      }
            +    },
            +    "cone": {
            +      "description": [
            +        "Draw a cone with given radius and height",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a cone. More subdivisions make the cone seem smoother. The recommended maximum value for detailX is 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "Number: (Optional) radius of the bottom surface",
            +        "height": "Number: (Optional) height of the cone",
            +        "detailX": "Integer: (Optional) number of segments,  the more segments the smoother geometry  default is 24",
            +        "detailY": "Integer: (Optional) number of segments,  the more segments the smoother geometry  default is 1",
            +        "cap": "Boolean: (Optional) whether to draw the base of the cone"
            +      }
            +    },
            +    "ellipsoid": {
            +      "description": [
            +        "Draw an ellipsoid with given radius",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother. Avoid detail number above 150, it may crash the browser."
            +      ],
            +      "params": {
            +        "radiusx": "Number: (Optional) x-radius of ellipsoid",
            +        "radiusy": "Number: (Optional) y-radius of ellipsoid",
            +        "radiusz": "Number: (Optional) z-radius of ellipsoid",
            +        "detailX": "Integer: (Optional) number of segments,  the more segments the smoother geometry  default is 24. Avoid detail number above  150, it may crash the browser.",
            +        "detailY": "Integer: (Optional) number of segments,  the more segments the smoother geometry  default is 16. Avoid detail number above  150, it may crash the browser."
            +      }
            +    },
            +    "torus": {
            +      "description": [
            +        "Draw a torus with given radius and tube radius",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a torus. More subdivisions make the torus appear to be smoother. The default and maximum values for detailX and detailY are 24 and 16, respectively. Setting them to relatively small values like 4 and 6 allows you to create new shapes other than a torus."
            +      ],
            +      "params": {
            +        "radius": "Number: (Optional) radius of the whole ring",
            +        "tubeRadius": "Number: (Optional) radius of the tube",
            +        "detailX": "Integer: (Optional) number of segments in x-dimension,  the more segments the smoother geometry  default is 24",
            +        "detailY": "Integer: (Optional) number of segments in y-dimension,  the more segments the smoother geometry  default is 16"
            +      }
            +    },
            +    "orbitControl": {
            +      "description": [
            +        "Allows movement around a 3D sketch using a mouse or trackpad. Left-clicking and dragging will rotate the camera position about the center of the sketch, right-clicking and dragging will pan the camera position without rotation, and using the mouse wheel (scrolling) will move the camera closer or further from the center of the sketch. This function can be called with parameters dictating sensitivity to mouse movement along the X and Y axes. Calling this function without parameters is equivalent to calling orbitControl(1,1). To reverse direction of movement in either axis, enter a negative number for sensitivity."
            +      ],
            +      "params": {
            +        "sensitivityX": "Number: (Optional) sensitivity to mouse movement along X axis",
            +        "sensitivityY": "Number: (Optional) sensitivity to mouse movement along Y axis",
            +        "sensitivityZ": "Number: (Optional) sensitivity to scroll movement along Z axis"
            +      }
            +    },
            +    "debugMode": {
            +      "description": [
            +        "debugMode() helps visualize 3D space by adding a grid to indicate where the ‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z directions. This function can be called without parameters to create a default grid and axes icon, or it can be called according to the examples above to customize the size and position of the grid and/or axes icon. The grid is drawn using the most recently set stroke color and weight. To specify these parameters, add a call to stroke() and strokeWeight() just before the end of the draw() loop.",
            +        "By default, the grid will run through the origin (0,0,0) of the sketch along the XZ plane and the axes icon will be offset from the origin. Both the grid and axes icon will be sized according to the current canvas size. Note that because the grid runs parallel to the default camera view, it is often helpful to use debugMode along with orbitControl to allow full view of the grid."
            +      ],
            +      "params": {
            +        "mode": "Constant: either GRID or AXES",
            +        "gridSize": "Number: (Optional) size of one side of the grid",
            +        "gridDivisions": "Number: (Optional) number of divisions in the grid",
            +        "xOff": "Number: (Optional) X axis offset from origin (0,0,0)",
            +        "yOff": "Number: (Optional) Y axis offset from origin (0,0,0)",
            +        "zOff": "Number: (Optional) Z axis offset from origin (0,0,0)",
            +        "axesSize": "Number: (Optional) size of axes icon",
            +        "gridXOff": "Number (Optional)",
            +        "gridYOff": "Number (Optional)",
            +        "gridZOff": "Number (Optional)",
            +        "axesXOff": "Number (Optional)",
            +        "axesYOff": "Number (Optional)",
            +        "axesZOff": "Number (Optional)"
            +      }
            +    },
            +    "noDebugMode": {
            +      "description": [
            +        "Turns off debugMode() in a 3D sketch."
            +      ]
            +    },
            +    "ambientLight": {
            +      "description": [
            +        "Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas. It has no particular source."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "alpha": "Number: (Optional) the alpha value",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the ambient light color"
            +      }
            +    },
            +    "specularColor": {
            +      "description": [
            +        "Set's the color of the specular highlight when using a specular material and specular light.",
            +        "This method can be combined with specularMaterial() and shininess() functions to set specular highlights. The default color is white, ie (255, 255, 255), which is used if this method is not called before specularMaterial(). If this method is called without specularMaterial(), There will be no effect.",
            +        "Note: specularColor is equivalent to the processing function <a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the ambient light color"
            +      }
            +    },
            +    "directionalLight": {
            +      "description": [
            +        "Creates a directional light with a color and a direction",
            +        "A maximum of 5 directionalLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value (depending on the current color mode),",
            +        "v2": "Number: green or saturation value",
            +        "v3": "Number: blue or brightness value",
            +        "position": "p5.Vector: the direction of the light",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string,  or <a href=\"#/p5.Color\">p5.Color</a> value",
            +        "x": "Number: x axis direction",
            +        "y": "Number: y axis direction",
            +        "z": "Number: z axis direction"
            +      }
            +    },
            +    "pointLight": {
            +      "description": [
            +        "Creates a point light with a color and a light position",
            +        "A maximum of 5 pointLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value (depending on the current color mode),",
            +        "v2": "Number: green or saturation value",
            +        "v3": "Number: blue or brightness value",
            +        "x": "Number: x axis position",
            +        "y": "Number: y axis position",
            +        "z": "Number: z axis position",
            +        "position": "p5.Vector: the position of the light",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string, or <a href=\"#/p5.Color\">p5.Color</a> value"
            +      }
            +    },
            +    "lights": {
            +      "description": [
            +        "Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop."
            +      ]
            +    },
            +    "lightFalloff": {
            +      "description": [
            +        "Sets the falloff rates for point lights. It affects only the elements which are created after it in the code. The default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:",
            +        "d = distance from light position to vertex position",
            +        "falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)"
            +      ],
            +      "params": {
            +        "constant": "Number: constant value for determining falloff",
            +        "linear": "Number: linear value for determining falloff",
            +        "quadratic": "Number: quadratic value for determining falloff"
            +      }
            +    },
            +    "spotLight": {
            +      "description": [
            +        "Creates a spotlight with a given color, position, direction of light, angle and concentration. Here, angle refers to the opening or aperture of the cone of the spotlight, and concentration is used to focus the light towards the center. Both angle and concentration are optional, but if you want to provide concentration, you will also have to specify the angle.",
            +        "A maximum of 5 spotLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value (depending on the current color mode),",
            +        "v2": "Number: green or saturation value",
            +        "v3": "Number: blue or brightness value",
            +        "x": "Number: x axis position",
            +        "y": "Number: y axis position",
            +        "z": "Number: z axis position",
            +        "rx": "Number: x axis direction of light",
            +        "ry": "Number: y axis direction of light",
            +        "rz": "Number: z axis direction of light",
            +        "angle": "Number: (Optional) optional parameter for angle. Defaults to PI/3",
            +        "conc": "Number: (Optional) optional parameter for concentration. Defaults to 100",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string, or <a href=\"#/p5.Color\">p5.Color</a> value",
            +        "position": "p5.Vector: the position of the light",
            +        "direction": "p5.Vector: the direction of the light"
            +      }
            +    },
            +    "noLights": {
            +      "description": [
            +        "This function will remove all the lights from the sketch for the subsequent materials rendered. It affects all the subsequent methods. Calls to lighting methods made after noLights() will re-enable lights in the sketch."
            +      ]
            +    },
            +    "loadModel": {
            +      "description": [
            +        "किसी OBJ या STL फ़ाइल से 3D मॉडल लोड करें।",
            +        "<a href=\"#/p5/loadModel\">loadModel()</a> को <a href=\"#/p5/preload\">preload()</a> के अंदर रखा जाना चाहिए। यह आपके शेष कोड के चलने से पहले मॉडल को पूरी तरह से लोड होने देता है।",
            +        "ओबीजे और एसटीएल प्रारूप की सीमाओं में से एक यह है कि इसमें अंतर्निहित पैमाने की भावना नहीं है। इसका मतलब है कि विभिन्न कार्यक्रमों से निर्यात किए गए मॉडल बहुत भिन्न आकार के हो सकते हैं। यदि आपका मॉडल प्रदर्शित नहीं हो रहा है, तो कॉल करने का प्रयास करें <a href=\"#/p5/loadModel\">loadModel()</a> सामान्यीकृत पैरामीटर के साथ सत्य पर सेट है। यह मॉडल को p5 के लिए उपयुक्त पैमाने पर आकार देगा। आप फाइनल में अतिरिक्त परिवर्तन भी कर सकते हैं <a href=\"#/p5/scale\">scale()</a> फ़ंक्शन के साथ आपके मॉडल का आकार।",
            +        "साथ ही, रंगीन एसटीएल फाइलों के लिए समर्थन मौजूद नहीं है। रंग के साथ एसटीएल फाइलें रंग गुणों के बिना प्रस्तुत की जाएंगी।"
            +      ],
            +      "returns": "p5.Geometry3D ऑब्जेक्ट",
            +      "params": {
            +        "path": "String: Path of the model to be loaded",
            +        "normalize": "Boolean: If true, scale the model to a  standardized size when loading",
            +        "successCallback": "function(p5.Geometry): (Optional) Function to be called  once the model is loaded. Will be passed  the 3D model object.",
            +        "failureCallback": "Function(Event): (Optional) called with event error if  the model fails to load.",
            +        "fileType": "String: (Optional) The file extension of the model  (<code>.stl</code>, <code>.obj</code>)."
            +      }
            +    },
            +    "model": {
            +      "description": [
            +        "Render a 3d model to the screen."
            +      ],
            +      "params": {
            +        "model": "p5.Geometry: Loaded 3d model to be rendered"
            +      }
            +    },
            +    "loadShader": {
            +      "description": [
            +        "Loads a custom shader from the provided vertex and fragment shader paths. The shader files are loaded asynchronously in the background, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.",
            +        "For now, there are three main types of shaders. p5 will automatically supply appropriate vertices, normals, colors, and lighting attributes if the parameters defined in the shader match the names."
            +      ],
            +      "returns": "p5.Shader: a shader object created from the provided vertex and fragment shader files.",
            +      "params": {
            +        "vertFilename": "String: path to file containing vertex shader source code",
            +        "fragFilename": "String: path to file containing fragment shader source code",
            +        "callback": "Function: (Optional) callback to be executed after loadShader completes. On success, the Shader object is passed as the first argument.",
            +        "errorCallback": "Function: (Optional) callback to be executed when an error occurs inside loadShader. On error, the error is passed as the first argument."
            +      }
            +    },
            +    "createShader": {
            +      "returns": "p5.Shader: a shader object created from the provided vertex and fragment shaders.",
            +      "params": {
            +        "vertSrc": "String: source code for the vertex shader",
            +        "fragSrc": "String: source code for the fragment shader"
            +      }
            +    },
            +    "shader": {
            +      "description": [
            +        "The <a href=\"#/p5/shader\">shader()</a> function lets the user provide a custom shader to fill in shapes in WEBGL mode. Users can create their own shaders by loading vertex and fragment shaders with <a href=\"#/p5/loadShader\">loadShader()</a>."
            +      ],
            +      "params": {
            +        "s": "p5.Shader: (Optional) the desired <a href=\"#/p5.Shader\">p5.Shader</a> to use for rendering shapes."
            +      }
            +    },
            +    "resetShader": {
            +      "description": [
            +        "This function restores the default shaders in WEBGL mode. Code that runs after resetShader() will not be affected by previously defined shaders. Should be run after <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "texture": {
            +      "description": [
            +        "Texture for geometry. You can view other possible materials in this <a href=\"https://p5js.org/examples/3d-materials.html\">example</a>."
            +      ],
            +      "params": {
            +        "tex": "p5.Image|p5.MediaElement|p5.Graphics: 2-dimensional graphics  to render as texture"
            +      }
            +    },
            +    "textureMode": {
            +      "description": [
            +        "Sets the coordinate space for texture mapping. The default mode is IMAGE which refers to the actual coordinates of the image. NORMAL refers to a normalized space of values ranging from 0 to 1. This function only works in WEBGL mode.",
            +        "With IMAGE, if an image is 100 x 200 pixels, mapping the image onto the entire size of a quad would require the points (0,0) (100, 0) (100,200) (0,200). The same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1)."
            +      ],
            +      "params": {
            +        "mode": "Constant: either IMAGE or NORMAL"
            +      }
            +    },
            +    "textureWrap": {
            +      "description": [
            +        "Sets the global texture wrapping mode. This controls how textures behave when their uv's go outside of the 0 - 1 range. There are three options: CLAMP, REPEAT, and MIRROR.",
            +        "CLAMP causes the pixels at the edge of the texture to extend to the bounds REPEAT causes the texture to tile repeatedly until reaching the bounds MIRROR works similarly to REPEAT but it flips the texture with every new tile",
            +        "REPEAT & MIRROR are only available if the texture is a power of two size (128, 256, 512, 1024, etc.).",
            +        "This method will affect all textures in your sketch until a subsequent textureWrap call is made.",
            +        "If only one argument is provided, it will be applied to both the horizontal and vertical axes."
            +      ],
            +      "params": {
            +        "wrapX": "Constant: either CLAMP, REPEAT, or MIRROR",
            +        "wrapY": "Constant: (Optional) either CLAMP, REPEAT, or MIRROR"
            +      }
            +    },
            +    "normalMaterial": {
            +      "description": [
            +        "Normal material for geometry is a material that is not affected by light. It is not reflective and is a placeholder material often used for debugging. Surfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue. You can view all possible materials in this <a href=\"https://p5js.org/examples/3d-materials.html\">example</a>."
            +      ]
            +    },
            +    "ambientMaterial": {
            +      "description": [
            +        "Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting. For example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light. Here's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>."
            +      ],
            +      "params": {
            +        "v1": "Number: gray value, red or hue value  (depending on the current color mode),",
            +        "v2": "Number: (Optional) green or saturation value",
            +        "v3": "Number: (Optional) blue or brightness value",
            +        "color": "Number[]|String|p5.Color: color, color Array, or CSS color string"
            +      }
            +    },
            +    "emissiveMaterial": {
            +      "description": [
            +        "Sets the emissive color of the material used for geometry drawn to the screen. This is a misnomer in the sense that the material does not actually emit light that effects surrounding polygons. Instead, it gives the appearance that the object is glowing. An emissive material will display at full strength even if there is no light for it to reflect."
            +      ],
            +      "params": {
            +        "v1": "Number: gray value, red or hue value  (depending on the current color mode),",
            +        "v2": "Number: (Optional) green or saturation value",
            +        "v3": "Number: (Optional) blue or brightness value",
            +        "a": "Number: (Optional) opacity",
            +        "color": "Number[]|String|p5.Color: color, color Array, or CSS color string"
            +      }
            +    },
            +    "specularMaterial": {
            +      "description": [
            +        "Specular material for geometry with a given color. Specular material is a shiny reflective material. Like ambient material it also defines the color the object reflects under ambient lighting. For example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light. For all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer. Here's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>."
            +      ],
            +      "params": {
            +        "gray": "Number: number specifying value between white and black.",
            +        "alpha": "Number: (Optional) alpha value relative to current color range  (default is 0-255)",
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "color": "Number[]|String|p5.Color: color Array, or CSS color string"
            +      }
            +    },
            +    "shininess": {
            +      "description": [
            +        "Sets the amount of gloss in the surface of shapes. Used in combination with specularMaterial() in setting the material properties of shapes. The default and minimum value is 1."
            +      ],
            +      "params": {
            +        "shine": "Number: Degree of Shininess.  Defaults to 1."
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "Sets the position of the current camera in a 3D sketch. Parameters for this function define the camera's position, the center of the sketch (where the camera is pointing), and an up direction (the orientation of the camera).",
            +        "This function simulates the movements of the camera, allowing objects to be viewed from various angles. Remember, it does not move the objects themselves but the camera instead. For example when the centerX value is positive, and the camera is rotating to the right side of the sketch, the object will seem like it's moving to the left.",
            +        "See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a> to view the position of your camera.",
            +        "If no parameters are given, the following default is used: camera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)"
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) camera position value on x axis",
            +        "y": "Number: (Optional) camera position value on y axis",
            +        "z": "Number: (Optional) camera position value on z axis",
            +        "centerX": "Number: (Optional) x coordinate representing center of the sketch",
            +        "centerY": "Number: (Optional) y coordinate representing center of the sketch",
            +        "centerZ": "Number: (Optional) z coordinate representing center of the sketch",
            +        "upX": "Number: (Optional) x component of direction 'up' from camera",
            +        "upY": "Number: (Optional) y component of direction 'up' from camera",
            +        "upZ": "Number: (Optional) z component of direction 'up' from camera"
            +      }
            +    },
            +    "perspective": {
            +      "description": [
            +        "Sets a perspective projection for the current camera in a 3D sketch. This projection represents depth through foreshortening: objects that are close to the camera appear their actual size while those that are further away from the camera appear smaller.",
            +        "The parameters to this function define the viewing frustum (the truncated pyramid within which objects are seen by the camera) through vertical field of view, aspect ratio (usually width/height), and near and far clipping planes.",
            +        "If no parameters are given, the following default is used: perspective(PI/3, width/height, eyeZ/10, eyeZ*10), where eyeZ is equal to ((height/2) / tan(PI/6))."
            +      ],
            +      "params": {
            +        "fovy": "Number: (Optional) camera frustum vertical field of view,  from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units",
            +        "aspect": "Number: (Optional) camera frustum aspect ratio",
            +        "near": "Number: (Optional) frustum near plane length",
            +        "far": "Number: (Optional) frustum far plane length"
            +      }
            +    },
            +    "ortho": {
            +      "description": [
            +        "Sets an orthographic projection for the current camera in a 3D sketch and defines a box-shaped viewing frustum within which objects are seen. In this projection, all objects with the same dimension appear the same size, regardless of whether they are near or far from the camera.",
            +        "The parameters to this function specify the viewing frustum where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values.",
            +        "If no parameters are given, the following default is used: ortho(-width/2, width/2, -height/2, height/2)."
            +      ],
            +      "params": {
            +        "left": "Number: (Optional) camera frustum left plane",
            +        "right": "Number: (Optional) camera frustum right plane",
            +        "bottom": "Number: (Optional) camera frustum bottom plane",
            +        "top": "Number: (Optional) camera frustum top plane",
            +        "near": "Number: (Optional) camera frustum near plane",
            +        "far": "Number: (Optional) camera frustum far plane"
            +      }
            +    },
            +    "frustum": {
            +      "description": [
            +        "Sets the frustum of the current camera as defined by the parameters.",
            +        "A frustum is a geometric form: a pyramid with its top cut off. With the viewer's eye at the imaginary top of the pyramid, the six planes of the frustum act as clipping planes when rendering a 3D view. Thus, any form inside the clipping planes is visible; anything outside those planes is not visible.",
            +        "Setting the frustum changes the perspective of the scene being rendered. This can be achieved more simply in many cases by using <a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.",
            +        "If no parameters are given, the following default is used: frustum(-width/2, width/2, -height/2, height/2, 0, max(width, height))."
            +      ],
            +      "params": {
            +        "left": "Number: (Optional) camera frustum left plane",
            +        "right": "Number: (Optional) camera frustum right plane",
            +        "bottom": "Number: (Optional) camera frustum bottom plane",
            +        "top": "Number: (Optional) camera frustum top plane",
            +        "near": "Number: (Optional) camera frustum near plane",
            +        "far": "Number: (Optional) camera frustum far plane"
            +      }
            +    },
            +    "createCamera": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it as the current (active) camera.",
            +        "The new camera is initialized with a default position (see <a href=\"#/p5.Camera/camera\">camera()</a>) and a default perspective projection (see <a href=\"#/p5.Camera/perspective\">perspective()</a>). Its properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a> methods.",
            +        "Note: Every 3D sketch starts with a default camera initialized. This camera can be controlled with the global methods <a href=\"#/p5/camera\">camera()</a>, <a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>, and <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera in the scene."
            +      ],
            +      "returns": "p5.Camera: The newly created camera object."
            +    },
            +    "setCamera": {
            +      "description": [
            +        "Sets the current (active) camera of a 3D sketch. Allows for switching between multiple cameras."
            +      ],
            +      "params": {
            +        "cam": "p5.Camera: p5.Camera object"
            +      }
            +    },
            +    "setAttributes": {
            +      "description": [
            +        "Set attributes for the WebGL Drawing context. This is a way of adjusting how the WebGL renderer works to fine-tune the display and performance.",
            +        "Note that this will reinitialize the drawing context if called after the WebGL canvas is made.",
            +        "If an object is passed as the parameter, all attributes not declared in the object will be set to defaults.",
            +        "The available attributes are:  alpha - indicates if the canvas contains an alpha buffer default is true",
            +        "depth - indicates whether the drawing buffer has a depth buffer of at least 16 bits - default is true",
            +        "stencil - indicates whether the drawing buffer has a stencil buffer of at least 8 bits",
            +        "antialias - indicates whether or not to perform anti-aliasing default is false (true in Safari)",
            +        "premultipliedAlpha - indicates that the page compositor will assume the drawing buffer contains colors with pre-multiplied alpha default is false",
            +        "preserveDrawingBuffer - if true the buffers will not be cleared and and will preserve their values until cleared or overwritten by author (note that p5 clears automatically on draw loop) default is true",
            +        "perPixelLighting - if true, per-pixel lighting will be used in the lighting shader otherwise per-vertex lighting is used. default is true."
            +      ],
            +      "params": {
            +        "key": "String: Name of attribute",
            +        "value": "Boolean: New value of named attribute",
            +        "obj": "Object: object with key-value pairs"
            +      }
            +    },
            +    "getAudioContext": {
            +      "description": [
            +        "Returns the Audio Context for this sketch. Useful for users who would like to dig deeper into the <a target='_blank' href= 'http://webaudio.github.io/web-audio-api/'>Web Audio API </a>.",
            +        "Some browsers require users to startAudioContext with a user gesture, such as touchStarted in the example below."
            +      ],
            +      "returns": "Object: AudioContext for this sketch"
            +    },
            +    "userStartAudio": {
            +      "description": [
            +        "It is not only a good practice to give users control over starting audio. This policy is enforced by many web browsers, including iOS and <a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay policy\">Google Chrome</a>, which create the Web Audio API's <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\" title=\"Audio Context @ MDN\">Audio Context</a> in a suspended state.",
            +        "In these browser-specific policies, sound will not play until a user interaction event (i.e. <code>mousePressed()</code>) explicitly resumes the AudioContext, or starts an audio node. This can be accomplished by calling <code>start()</code> on a <code>p5.Oscillator</code>, <code> play()</code> on a <code>p5.SoundFile</code>, or simply <code>userStartAudio()</code>.",
            +        "<code>userStartAudio()</code> starts the AudioContext on a user gesture. The default behavior will enable audio on any mouseUp or touchEnd event. It can also be placed in a specific interaction function, such as <code>mousePressed()</code> as in the example below. This method utilizes <a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext </a>, a library by Yotam Mann (MIT Licence, 2016)."
            +      ],
            +      "returns": "Promise: Returns a Promise that resolves when  the AudioContext state is 'running'",
            +      "params": {
            +        "element(s)": "Element|Array: (Optional) This argument can be an Element,  Selector String, NodeList, p5.Element,  jQuery Element, or an Array of any of those.",
            +        "callback": "Function: (Optional) Callback to invoke when the AudioContext  has started"
            +      }
            +    },
            +    "getOutputVolume": {
            +      "description": [
            +        "Returns a number representing the output volume for sound in this sketch."
            +      ],
            +      "returns": "Number: Output volume for sound in this sketch.  Should be between 0.0 (silence) and 1.0."
            +    },
            +    "outputVolume": {
            +      "description": [
            +        "Scale the output of all sound in this sketch Scaled between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal.",
            +        "<b>How This Works</b>: When you load the p5.sound module, it creates a single instance of p5sound. All sound objects in this module output to p5sound before reaching your computer's output. So if you change the amplitude of p5sound, it impacts all of the sound in this module.",
            +        "If no value is provided, returns a Web Audio API Gain Node"
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "soundOut": {
            +      "description": [
            +        "<code>p5.soundOut</code> is the p5.sound final output bus. It sends output to the destination of this window's web audio context. It contains Web Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>), and Gain Nodes for <code>.input</code> and <code>.output</code>."
            +      ]
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Returns a number representing the sample rate, in samples per second, of all sound objects in this audio context. It is determined by the sampling rate of your operating system's sound card, and it is not currently possile to change. It is often 44100, or twice the range of human hearing."
            +      ],
            +      "returns": "Number: samplerate samples per second"
            +    },
            +    "freqToMidi": {
            +      "description": [
            +        "Returns the closest MIDI note value for a given frequency."
            +      ],
            +      "returns": "Number: MIDI note value",
            +      "params": {
            +        "frequency": "Number: A freqeuncy, for example, the \"A\"  above Middle C is 440Hz"
            +      }
            +    },
            +    "midiToFreq": {
            +      "description": [
            +        "Returns the frequency value of a MIDI note value. General MIDI treats notes as integers where middle C is 60, C# is 61, D is 62 etc. Useful for generating musical frequencies with oscillators."
            +      ],
            +      "returns": "Number: Frequency value of the given MIDI note",
            +      "params": {
            +        "midiNote": "Number: The number of a MIDI note"
            +      }
            +    },
            +    "soundFormats": {
            +      "description": [
            +        "List the SoundFile formats that you will include. LoadSound will search your directory for these extensions, and will pick a format that is compatable with the client's web browser. <a href=\"http://media.io/\">Here</a> is a free online file converter."
            +      ],
            +      "params": {
            +        "formats": "String: (Optional) i.e. 'mp3', 'wav', 'ogg'"
            +      }
            +    },
            +    "saveSound": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. For uploading audio to a server, use <a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile that you wish to save",
            +        "fileName": "String: name of the resulting .wav file."
            +      }
            +    },
            +    "loadSound": {
            +      "description": [
            +        "loadSound() returns a new p5.SoundFile from a specified path. If called during preload(), the p5.SoundFile will be ready to play in time for setup() and draw(). If called outside of preload, the p5.SoundFile will not be ready immediately, so loadSound accepts a callback as the second parameter. Using a <a href=\"https://github.com/processing/p5.js/wiki/Local-server\"> local server</a> is recommended when loading external files."
            +      ],
            +      "returns": "SoundFile: Returns a p5.SoundFile",
            +      "params": {
            +        "path": "String|Array: Path to the sound file, or an array with  paths to soundfiles in multiple formats  i.e. ['sound.ogg', 'sound.mp3'].  Alternately, accepts an object: either  from the HTML5 File API, or a p5.File.",
            +        "successCallback": "Function: (Optional) Name of a function to call once file loads",
            +        "errorCallback": "Function: (Optional) Name of a function to call if there is  an error loading the file.",
            +        "whileLoading": "Function: (Optional) Name of a function to call while file is loading.  This function will receive the percentage loaded  so far, from 0.0 to 1.0."
            +      }
            +    },
            +    "createConvolver": {
            +      "description": [
            +        "Create a p5.Convolver. Accepts a path to a soundfile that will be used to generate an impulse response."
            +      ],
            +      "returns": "p5.Convolver:",
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: (Optional) function to call if loading is successful.  The object will be passed in as the argument  to the callback function.",
            +        "errorCallback": "Function: (Optional) function to call if loading is not successful.  A custom error will be passed in as the argument  to the callback function."
            +      }
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the global tempo, in beats per minute, for all p5.Parts. This method will impact all active p5.Parts."
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.Color": {
            +    "description": [
            +      "Each color stores the color mode and level maxes that was applied at the time of its construction. These are used to interpret the input arguments (at construction and later for that instance of color) and to format the output e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested. ",
            +      "Internally, we store an array representing the ideal RGBA values in floating point form, normalized from 0 to 1. From this we calculate the closest screen color (RGBA levels from 0 to 255) and expose this to the renderer. ",
            +      "We also cache normalized, floating point components of the color in various representations as they are calculated. This is done to prevent repeating a conversion that has already been performed."
            +    ],
            +    "setRed": {
            +      "description": [
            +        "The setRed function sets the red component of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "red": "Number: the new red value"
            +      }
            +    },
            +    "setGreen": {
            +      "description": [
            +        "The setGreen function sets the green component of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "green": "Number: the new green value"
            +      }
            +    },
            +    "setBlue": {
            +      "description": [
            +        "The setBlue function sets the blue component of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "blue": "Number: the new blue value"
            +      }
            +    },
            +    "setAlpha": {
            +      "description": [
            +        "The setAlpha function sets the transparency (alpha) value of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "alpha": "Number: the new alpha value"
            +      }
            +    }
            +  },
            +  "p5.Element": {
            +    "description": [
            +      "Base class for all elements added to a sketch, including canvas, graphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a> objects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>, <a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped",
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "elt": {
            +      "description": [
            +        "Underlying HTML element. All normal HTML methods can be called on this."
            +      ]
            +    },
            +    "parent": {
            +      "description": [
            +        "Attaches the element to the parent specified. A way of setting  the container for the element. Accepts either a string ID, DOM  node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.  For more ways to position the canvas, see the  <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>  positioning the canvas</a> wiki page."
            +      ],
            +      "params": {
            +        "parent": "String|p5.Element|Object: the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>  of desired parent element"
            +      }
            +    },
            +    "id": {
            +      "description": [
            +        "Sets the ID of the element. If no ID argument is passed in, it instead  returns the current ID of the element.  Note that only one element can have a particular id in a page.  The <a href=\"#/p5.Element/class\">.class()</a> function can be used  to identify multiple elements with the same class name."
            +      ],
            +      "params": {
            +        "id": "String: ID of the element"
            +      }
            +    },
            +    "class": {
            +      "description": [
            +        "Adds given class to the element. If no class argument is passed in, it  instead returns a string containing the current class(es) of the element."
            +      ],
            +      "params": {
            +        "class": "String: class to add"
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called once after every time a mouse button is pressed over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  pressed over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a mouse button is pressed twice over the element. This can be used to attach element and action specific event listeners."
            +      ],
            +      "returns": "p5.Element: ",
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  double clicked over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners. ",
            +        "The function accepts a callback function as argument which will be executed when the <code>wheel</code> event is triggered on the element, the callback function is passed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code> except it reads the horizontal wheel scroll of the mouse wheel. ",
            +        "On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are reversed."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  scrolled over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is called once after every time a mouse button is released over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  released over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is called once after a mouse button is pressed and released over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap.This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  clicked over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a mouse moves over the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse moves  over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseOver": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a mouse moves onto the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse moves  onto the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseOut": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a mouse moves off the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse  moves off of an element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch  starts over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch moves over  the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch ends  over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "dragOver": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a file is dragged over the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a file is  dragged over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "dragLeave": {
            +      "description": [
            +        "The .dragLeave() function is called once after every time a dragged file leaves the element area. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a file is  dragged off the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "addClass": {
            +      "description": [
            +        "Adds specified class to the element."
            +      ],
            +      "params": {
            +        "class": "String: name of class to add"
            +      }
            +    },
            +    "removeClass": {
            +      "description": [
            +        "Removes specified class from the element."
            +      ],
            +      "params": {
            +        "class": "String: name of class to remove"
            +      }
            +    },
            +    "hasClass": {
            +      "description": [
            +        "Checks if specified class already set to element"
            +      ],
            +      "returns": "Boolean: a boolean value if element has specified class",
            +      "params": {
            +        "c": "String: class name of class to check"
            +      }
            +    },
            +    "toggleClass": {
            +      "description": [
            +        "Toggles element class"
            +      ],
            +      "params": {
            +        "c": "String: class name to toggle"
            +      }
            +    },
            +    "child": {
            +      "description": [
            +        "Attaches the element as a child to the parent specified.  Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.  If no argument is specified, an array of children DOM nodes is returned."
            +      ],
            +      "returns": "Node[]: an array of child nodes",
            +      "params": {
            +        "child": "String|p5.Element: (Optional) the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>  to add to the current element"
            +      }
            +    },
            +    "center": {
            +      "description": [
            +        "Centers a p5 Element either vertically, horizontally, or both, relative to its parent or according to the body if the Element has no parent. If no argument is passed the Element is aligned both vertically and horizontally."
            +      ],
            +      "params": {
            +        "align": "String: (Optional) passing 'vertical', 'horizontal' aligns element accordingly"
            +      }
            +    },
            +    "html": {
            +      "description": [
            +        "If an argument is given, sets the inner HTML of the element,  replacing any existing html. If true is included as a second  argument, html is appended instead of replacing existing html.  If no arguments are given, returns  the inner HTML of the element."
            +      ],
            +      "returns": "String: the inner HTML of the element",
            +      "params": {
            +        "html": "String: (Optional) the HTML to be placed inside the element",
            +        "append": "Boolean: (Optional) whether to append HTML to existing"
            +      }
            +    },
            +    "position": {
            +      "description": [
            +        "Sets the position of the element. If no position type argument is given, the  position will be relative to (0, 0) of the window.  Essentially, this sets position:absolute and left and top  properties of style. If an optional third argument specifying position type is given,  the x and y coordinates will be interpreted based on the <a target=\"_blank\"  href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.  If no arguments given, the function returns the x and y position of the element. found documentation on how to be more specific with object type  <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a>"
            +      ],
            +      "returns": "Object: object of form { x: 0, y: 0 } containing the position of the element in an object",
            +      "params": {
            +        "x": "Number: (Optional) x-position relative to upper left of window (optional)",
            +        "y": "Number: (Optional) y-position relative to upper left of window (optional)",
            +        "positionType": "String: it can be static, fixed, relative, sticky, initial or inherit (optional)"
            +      }
            +    },
            +    "style": {
            +      "description": [
            +        "Sets the given style (css) property (1st arg) of the element with the given value (2nd arg). If a single argument is given, .style() returns the value of the given property; however, if the single argument is given in css syntax ('text-align:center'), .style() sets the css appropriately."
            +      ],
            +      "returns": "String: value of property",
            +      "params": {
            +        "property": "String: property to be set",
            +        "value": "String|p5.Color: value to assign to property"
            +      }
            +    },
            +    "attribute": {
            +      "description": [
            +        "Adds a new attribute or changes the value of an existing attribute  on the specified element. If no value is specified, returns the  value of the given attribute, or null if attribute is not set."
            +      ],
            +      "returns": "String: value of attribute",
            +      "params": {
            +        "attr": "String: attribute to set",
            +        "value": "String: value to assign to attribute"
            +      }
            +    },
            +    "removeAttribute": {
            +      "description": [
            +        "Removes an attribute on the specified element."
            +      ],
            +      "params": {
            +        "attr": "String: attribute to remove"
            +      }
            +    },
            +    "value": {
            +      "description": [
            +        "Either returns the value of the element if no arguments given, or sets the value of the element."
            +      ],
            +      "returns": "String|Number: value of the element",
            +      "params": {
            +        "value": "String|Number"
            +      }
            +    },
            +    "show": {
            +      "description": [
            +        "Shows the current element. Essentially, setting display:block for the style."
            +      ]
            +    },
            +    "hide": {
            +      "description": [
            +        "Hides the current element. Essentially, setting display:none for the style."
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "Sets the width and height of the element. AUTO can be used to  only adjust one dimension at a time. If no arguments are given, it  returns the width and height of the element in an object. In case of  elements which need to be loaded, such as images, it is recommended  to call the function after the element has finished loading."
            +      ],
            +      "returns": "Object: the width and height of the element in an object",
            +      "params": {
            +        "w": "Number|Constant: width of the element, either AUTO, or a number",
            +        "h": "Number|Constant: (Optional) height of the element, either AUTO, or a number"
            +      }
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the element, stops all media streams, and deregisters all listeners."
            +      ]
            +    },
            +    "drop": {
            +      "description": [
            +        "Registers a callback that gets called every time a file that is dropped on the element has been loaded. p5 will load every dropped file into memory and pass it as a p5.File object to the callback. Multiple files dropped at the same time will result in multiple calls to the callback. ",
            +        "You can optionally pass a second callback which will be registered to the raw <a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event. The callback will thus be provided the original <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>. Dropping multiple files at the same time will trigger the second callback once per drop, whereas the first callback will trigger for each loaded file."
            +      ],
            +      "params": {
            +        "callback": "Function: callback to receive loaded file, called for each file dropped.",
            +        "fxn": "Function: (Optional) callback triggered once when files are dropped with the drop event."
            +      }
            +    }
            +  },
            +  "p5.Graphics": {
            +    "description": [
            +      "Thin wrapper around a renderer, to be used for creating a graphics buffer object. Use this class if you need to draw into an off-screen graphics buffer. The two parameters define the width and height in pixels. The fields and methods for this class are extensive, but mirror the normal drawing API for p5."
            +    ],
            +    "params": {
            +      "w": "Number: width",
            +      "h": "Number: height",
            +      "renderer": "Constant: the renderer to use, either P2D or WEBGL",
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "reset": {
            +      "description": [
            +        "Resets certain values such as those modified by functions in the Transform category and in the Lights category that are not automatically reset with graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior of the standard canvas."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes a Graphics object from the page and frees any resources associated with it."
            +      ]
            +    }
            +  },
            +  "p5.Renderer": {
            +    "description": [
            +      "Main graphics and rendering context, as well as the base API implementation for p5.js \"core\". To be used as the superclass for Renderer2D and Renderer3D classes, respectively."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped",
            +      "pInst": "P5: (Optional) pointer to p5 instance",
            +      "isMainCanvas": "Boolean: (Optional) whether we're using it as main canvas"
            +    }
            +  },
            +  "JSON": {
            +    "stringify": {
            +      "description": [
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>: The JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>."
            +      ],
            +      "params": {
            +        "object": "Object: :Javascript object that you would like to convert to JSON"
            +      }
            +    }
            +  },
            +  "console": {
            +    "log": {
            +      "description": [
            +        "Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a> and <a href=\"#/p5/console/log\">console.log</a> interchangeably. ",
            +        "The console is opened differently depending on which browser you are using. Here are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a> , <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>, and <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>. With the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console is embedded directly in the page underneath the code editor. ",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>: The Console method log() outputs a message to the web console. The message may be a single <a href=\"#/p5/string\">string</a> (with optional substitution values), or it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>."
            +      ],
            +      "params": {
            +        "message": "String|Expression|Object: :Message that you would like to print to the console"
            +      }
            +    }
            +  },
            +  "p5.TypedDict": {
            +    "description": [
            +      "Base class for all p5.Dictionary types. Specifically  typed Dictionary classes inherit from this class."
            +    ],
            +    "size": {
            +      "description": [
            +        "Returns the number of key-value pairs currently stored in the Dictionary."
            +      ],
            +      "returns": "Integer: the number of key-value pairs in the Dictionary"
            +    },
            +    "hasKey": {
            +      "description": [
            +        "Returns true if the given key exists in the Dictionary, otherwise returns false."
            +      ],
            +      "returns": "Boolean: whether that key exists in Dictionary",
            +      "params": {
            +        "key": "Number|String: that you want to look up"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Returns the value stored at the given key."
            +      ],
            +      "returns": "Number|String: the value stored at that key",
            +      "params": {
            +        "the": "Number|String: key you want to access"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Updates the value associated with the given key in case it already exists in the Dictionary. Otherwise a new key-value pair is added."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String"
            +      }
            +    },
            +    "create": {
            +      "description": [
            +        "Creates a new key-value pair in the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String",
            +        "obj": "Object: key/value pair"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Removes all previously stored key-value pairs from the Dictionary."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the key-value pair stored at the given key from the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String: for the pair to remove"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Logs the set of items currently stored in the Dictionary to the console."
            +      ]
            +    },
            +    "saveTable": {
            +      "description": [
            +        "Converts the Dictionary into a CSV file for local download."
            +      ]
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "Converts the Dictionary into a JSON file for local download."
            +      ]
            +    }
            +  },
            +  "p5.StringDict": {
            +    "description": [
            +      "A simple Dictionary class for Strings."
            +    ]
            +  },
            +  "p5.NumberDict": {
            +    "description": [
            +      "A simple Dictionary class for Numbers."
            +    ],
            +    "add": {
            +      "description": [
            +        "Add the given number to the value currently stored at the given key. The sum then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to add to",
            +        "Number": "Number: to add to the value"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtract the given number from the value currently stored at the given key. The difference then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to subtract from",
            +        "Number": "Number: to subtract from the value"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the given number with the value currently stored at the given key. The product then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to multiply",
            +        "Amount": "Number: to multiply the value by"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Divide the given number with the value currently stored at the given key. The quotient then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to divide",
            +        "Amount": "Number: to divide the value by"
            +      }
            +    },
            +    "minValue": {
            +      "description": [
            +        "Return the lowest number currently stored in the Dictionary."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "maxValue": {
            +      "description": [
            +        "Return the highest number currently stored in the Dictionary."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "minKey": {
            +      "description": [
            +        "Return the lowest key currently used in the Dictionary."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "maxKey": {
            +      "description": [
            +        "Return the highest key currently used in the Dictionary."
            +      ],
            +      "returns": "Number: "
            +    }
            +  },
            +  "p5.MediaElement": {
            +    "description": [
            +      "Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods of <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not called directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>, <a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped"
            +    },
            +    "src": {
            +      "description": [
            +        "Path to the media element source."
            +      ],
            +      "returns": "String: src"
            +    },
            +    "play": {
            +      "description": [
            +        "Play an HTML5 media element."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stops an HTML5 media element (sets current time to zero)."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses an HTML5 media element."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Set 'loop' to true for an HTML5 media element, and starts playing."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Set 'loop' to false for an HTML5 media element. Element will stop when it reaches the end."
            +      ]
            +    },
            +    "autoplay": {
            +      "description": [
            +        "Set HTML5 media element to autoplay or not. If no argument is specified, by default it will autoplay."
            +      ],
            +      "params": {
            +        "shouldAutoplay": "Boolean: whether the element should autoplay"
            +      }
            +    },
            +    "volume": {
            +      "description": [
            +        "Sets volume for this HTML5 media element. If no argument is given, returns the current volume."
            +      ],
            +      "returns": "Number: current volume",
            +      "params": {
            +        "val": "Number: volume between 0.0 and 1.0"
            +      }
            +    },
            +    "speed": {
            +      "description": [
            +        "If no arguments are given, returns the current playback speed of the element. The speed parameter sets the speed where 2.0 will play the element twice as fast, 0.5 will play at half the speed, and -1 will play the element in normal speed in reverse.(Note that not all browsers support backward playback and even if they do, playback might not be smooth.)"
            +      ],
            +      "returns": "Number: current playback speed of the element",
            +      "params": {
            +        "speed": "Number: speed multiplier for element playback"
            +      }
            +    },
            +    "time": {
            +      "description": [
            +        "If no arguments are given, returns the current time of the element. If an argument is given the current time of the element is set to it."
            +      ],
            +      "returns": "Number: current time (in seconds)",
            +      "params": {
            +        "time": "Number: time to jump to (in seconds)"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of the HTML5 media element."
            +      ],
            +      "returns": "Number: duration"
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the audio or video element reaches the end. If the element is looping, this will not be called. The element is passed in as the argument to the onended callback."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended. The  media element will be passed  in as the argument to the  callback."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send the audio output of this element to a specified audioNode or p5.sound object. If no element is provided, connects to p5's main output. That connection is established when this method is first called. All connections are removed by the .disconnect() method. ",
            +        "This method is meant to be used with the p5.sound.js addon library."
            +      ],
            +      "params": {
            +        "audioNode": "AudioNode|Object: AudioNode from the Web Audio API, or an object from the p5.sound library"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all Web Audio routing, including to main output. This is useful if you want to re-route the output through audio effects, for example."
            +      ]
            +    },
            +    "showControls": {
            +      "description": [
            +        "Show the default MediaElement controls, as determined by the web browser."
            +      ]
            +    },
            +    "hideControls": {
            +      "description": [
            +        "Hide the default mediaElement controls."
            +      ]
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point. ",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback. ",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    }
            +  },
            +  "p5.File": {
            +    "description": [
            +      "Base class for a file. Used for Element.drop and createFileInput."
            +    ],
            +    "params": {
            +      "file": "File: File that is wrapped"
            +    },
            +    "file": {
            +      "description": [
            +        "Underlying File object. All normal File methods can be called on this."
            +      ]
            +    },
            +    "type": {
            +      "description": [
            +        "File type (image, text, etc.)"
            +      ]
            +    },
            +    "subtype": {
            +      "description": [
            +        "File subtype (usually the file extension jpg, png, xml, etc.)"
            +      ]
            +    },
            +    "name": {
            +      "description": [
            +        "File name"
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "File size"
            +      ]
            +    },
            +    "data": {
            +      "description": [
            +        "URL string containing either image data, the text contents of the file or a parsed object if file is JSON and p5.XML if XML"
            +      ]
            +    }
            +  },
            +  "p5.Image": {
            +    "description": [
            +      "Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an image. ",
            +      "p5 can display .gif, .jpg and .png images. Images may be displayed in 2D and 3D space. Before an image is used, it must be loaded with the <a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and height of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the values for every pixel in the image. ",
            +      "The methods described below allow easy access to the image's pixels and alpha channel and simplify the process of compositing. ",
            +      "Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on the image to make sure that the pixel data is properly loaded."
            +    ],
            +    "params": {
            +      "width": "Number",
            +      "height": "Number"
            +    },
            +    "width": {
            +      "description": [
            +        "Image width."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "Image height."
            +      ]
            +    },
            +    "pixels": {
            +      "description": [
            +        "Array containing the values for all the pixels in the display window. These values are numbers. This array is the size (include an appropriate factor for pixelDensity) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. Retina and other high density displays may have more pixels (by a factor of pixelDensity^2). For example, if the image is 100x100 pixels, there will be 40,000. With pixelDensity = 2, there will be 160,000. The first four values (indices 0-3) in the array will be the R, G, B, A values of the pixel at (0, 0). The second four values (indices 4-7) will contain the R, G, B, A values of the pixel at (1, 0). More generally, to set values for a pixel at (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre> ",
            +        "Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes."
            +      ]
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "Loads the pixels data for this image into the [pixels] attribute."
            +      ]
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "Updates the backing canvas for this image with the contents of the [pixels] array. ",
            +        "If this image is an animated GIF then the pixels will be updated in the frame that is currently displayed."
            +      ],
            +      "params": {
            +        "x": "Integer: x-offset of the target update area for the  underlying canvas",
            +        "y": "Integer: y-offset of the target update area for the  underlying canvas",
            +        "w": "Integer: height of the target update area for the  underlying canvas",
            +        "h": "Integer: height of the target update area for the  underlying canvas"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Get a region of pixels from an image. ",
            +        "If no params are passed, the whole image is returned. If x and y are the only params passed a single pixel is extracted. If all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a> is returned."
            +      ],
            +      "returns": "p5.Image: the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "w": "Number: width",
            +        "h": "Number: height"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the color of a single pixel or write an image into this <a href=\"#/p5.Image\">p5.Image</a>. ",
            +        "Note that for a large number of pixels this will be slower than directly manipulating the pixels array and then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "a": "Number|Number[]|Object: grayscale value | pixel array |  a <a href=\"#/p5.Color\">p5.Color</a> | image to copy"
            +      }
            +    },
            +    "resize": {
            +      "description": [
            +        "Resize the image to a new width and height. To make the image scale proportionally, use 0 as the value for the wide or high parameter. For instance, to make the width of an image 150 pixels, and change the height using the same proportion, use resize(150, 0)."
            +      ],
            +      "params": {
            +        "width": "Number: the resized image width",
            +        "height": "Number: the resized image height"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Copies a region of pixels from one image to another. If no srcImage is specified this is used as the source. If the source and destination regions aren't the same size, it will automatically resize source pixels to fit the specified target region."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5.Element: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height"
            +      }
            +    },
            +    "mask": {
            +      "description": [
            +        "Masks part of an image from displaying by loading another image and using its alpha channel as an alpha channel for this image. Masks are cumulative, one applied to an image object, they cannot be removed."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a> ",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used. ",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used. ",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used. ",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used. ",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges. ",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur. ",
            +        "ERODE Reduces the light areas. No parameter is used. ",
            +        "DILATE Increases the light areas. No parameter is used. ",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "Constant: either THRESHOLD, GRAY, OPAQUE, INVERT,  POSTERIZE, ERODE, DILATE or BLUR.  See Filters.js for docs on  each available filter",
            +        "filterParam": "Number: (Optional) an optional parameter unique  to each filter, see above"
            +      }
            +    },
            +    "blend": {
            +      "description": [
            +        "Copies a region of pixels from one image to another, using a specified blend mode to do the operation."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height",
            +        "blendMode": "Constant: the blend mode. either  BLEND, DARKEST, LIGHTEST, DIFFERENCE,  MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD or NORMAL. Available blend modes are: normal | multiply | screen | overlay |  darken | lighten | color-dodge | color-burn | hard-light |  soft-light | difference | exclusion | hue | saturation |  color | luminosity <a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a>"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "Saves the image to a file and force the browser to download it. Accepts two strings for filename and file extension Supports png (default), jpg, and gif  Note that the file will only be downloaded as an animated GIF if the p5.Image was loaded from a GIF file."
            +      ],
            +      "params": {
            +        "filename": "String: give your file a name",
            +        "extension": "String: 'png' or 'jpg'"
            +      }
            +    },
            +    "reset": {
            +      "description": [
            +        "Starts an animated GIF over at the beginning state."
            +      ]
            +    },
            +    "getCurrentFrame": {
            +      "description": [
            +        "Gets the index for the frame that is currently visible in an animated GIF."
            +      ],
            +      "returns": "Number: The index for the currently displaying frame in animated GIF"
            +    },
            +    "setFrame": {
            +      "description": [
            +        "Sets the index of the frame that is currently visible in an animated GIF"
            +      ],
            +      "params": {
            +        "index": "Number: the index for the frame that should be displayed"
            +      }
            +    },
            +    "numFrames": {
            +      "description": [
            +        "Returns the number of frames in an animated GIF"
            +      ],
            +      "returns": "Number: "
            +    },
            +    "play": {
            +      "description": [
            +        "Plays an animated GIF that was paused with <a href=\"#/p5.Image/pause\">pause()</a>"
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses an animated GIF."
            +      ]
            +    },
            +    "delay": {
            +      "description": [
            +        "Changes the delay between frames in an animated GIF. There is an optional second parameter that indicates an index for a specific frame that should have its delay modified. If no index is given, all frames will have the new delay."
            +      ],
            +      "params": {
            +        "d": "Number: the amount in milliseconds to delay between switching frames",
            +        "index": "Number: (Optional) the index of the frame that should have the new delay value {optional}"
            +      }
            +    }
            +  },
            +  "p5.PrintWriter": {
            +    "params": {
            +      "filename": "String",
            +      "extension": "String (Optional)"
            +    },
            +    "write": {
            +      "description": [
            +        "Writes data to the PrintWriter stream"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be written by the PrintWriter"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Writes data to the PrintWriter stream, and adds a new line at the end"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be printed by the PrintWriter"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Clears the data already written to the PrintWriter object"
            +      ]
            +    },
            +    "close": {
            +      "description": [
            +        "Closes the PrintWriter"
            +      ]
            +    }
            +  },
            +  "p5.Table": {
            +    "description": [
            +      "<a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much like in a traditional spreadsheet. Tables can be generated from scratch, dynamically, or using data from an existing file."
            +    ],
            +    "params": {
            +      "rows": "p5.TableRow[]: (Optional) An array of p5.TableRow objects"
            +    },
            +    "columns": {
            +      "description": [
            +        "An array containing the names of the columns in the table, if the \"header\" the table is loaded with the \"header\" parameter."
            +      ]
            +    },
            +    "rows": {
            +      "description": [
            +        "An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the rows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a>"
            +      ]
            +    },
            +    "addRow": {
            +      "description": [
            +        "Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default, an empty row is created. Typically, you would store a reference to the new row in a TableRow object (see newRow in the example above), and then set individual values using <a href=\"#/p5/set\">set()</a>. ",
            +        "If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is duplicated and added to the table."
            +      ],
            +      "returns": "p5.TableRow: the row that was added",
            +      "params": {
            +        "row": "p5.TableRow: (Optional) row to be added to the table"
            +      }
            +    },
            +    "removeRow": {
            +      "description": [
            +        "Removes a row from the table object."
            +      ],
            +      "params": {
            +        "id": "Integer: ID number of the row to remove"
            +      }
            +    },
            +    "getRow": {
            +      "description": [
            +        "Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference can then be used to get and set values of the selected row."
            +      ],
            +      "returns": "p5.TableRow: <a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +      "params": {
            +        "rowID": "Integer: ID number of the row to get"
            +      }
            +    },
            +    "getRows": {
            +      "description": [
            +        "Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s."
            +      ],
            +      "returns": "p5.TableRow[]: Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s"
            +    },
            +    "findRow": {
            +      "description": [
            +        "Finds the first row in the Table that contains the value provided, and returns a reference to that row. Even if multiple rows are possible matches, only the first matching row is returned. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow: ",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "findRows": {
            +      "description": [
            +        "Finds the rows in the Table that contain the value provided, and returns references to those rows. Returns an Array, so for must be used to iterate through all the rows, as shown in the example above. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "matchRow": {
            +      "description": [
            +        "Finds the first row in the Table that matches the regular expression provided, and returns a reference to that row. Even if multiple rows are possible matches, only the first matching row is returned. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow: TableRow object",
            +      "params": {
            +        "regexp": "String|RegExp: The regular expression to match",
            +        "column": "String|Integer: The column ID (number) or  title (string)"
            +      }
            +    },
            +    "matchRows": {
            +      "description": [
            +        "Finds the rows in the Table that match the regular expression provided, and returns references to those rows. Returns an array, so for must be used to iterate through all the rows, as shown in the example. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "regexp": "String: The regular expression to match",
            +        "column": "String|Integer: (Optional) The column ID (number) or  title (string)"
            +      }
            +    },
            +    "getColumn": {
            +      "description": [
            +        "Retrieves all values in the specified column, and returns them as an array. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "Array: Array of column values",
            +      "params": {
            +        "column": "String|Number: String or Number of the column to return"
            +      }
            +    },
            +    "clearRows": {
            +      "description": [
            +        "Removes all rows from a Table. While all rows are removed, columns and column titles are maintained."
            +      ]
            +    },
            +    "addColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object. Typically, you will want to specify a title, so the column may be easily referenced later by name. (If no title is specified, the new column's title will be null.)"
            +      ],
            +      "params": {
            +        "title": "String: (Optional) title of the given column"
            +      }
            +    },
            +    "getColumnCount": {
            +      "description": [
            +        "Returns the total number of columns in a Table."
            +      ],
            +      "returns": "Integer: Number of columns in this table"
            +    },
            +    "getRowCount": {
            +      "description": [
            +        "Returns the total number of rows in a Table."
            +      ],
            +      "returns": "Integer: Number of rows in this table"
            +    },
            +    "removeTokens": {
            +      "description": [
            +        "Removes any of the specified characters (or \"tokens\"). ",
            +        "If no column is specified, then the values in all columns and rows are processed. A specific column may be referenced by either its ID or title."
            +      ],
            +      "params": {
            +        "chars": "String: String listing characters to be removed",
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "Trims leading and trailing whitespace, such as spaces and tabs, from String table values. If no column is specified, then the values in all columns and rows are trimmed. A specific column may be referenced by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "removeColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table object. The column to be removed may be identified by either its title (a String) or its index value (an int). removeColumn(0) would remove the first column, removeColumn(1) would remove the second column, and so on."
            +      ],
            +      "params": {
            +        "column": "String|Integer: columnName (string) or ID (number)"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Stores a value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String|Number: value to assign"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Stores a Float value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "Number: value to assign"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Stores a String value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String: value to assign"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retrieves a value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "String|Number: ",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Retrieves a Float value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "Number: ",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Retrieves a String value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "String: ",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getObject": {
            +      "description": [
            +        "Retrieves all table data and returns as an object. If a column name is passed in, each row object will be stored with that attribute as its title."
            +      ],
            +      "returns": "Object: ",
            +      "params": {
            +        "headerColumn": "String: (Optional) Name of the column which should be used to  title each row object (optional)"
            +      }
            +    },
            +    "getArray": {
            +      "description": [
            +        "Retrieves all table data and returns it as a multidimensional array."
            +      ],
            +      "returns": "Array: "
            +    }
            +  },
            +  "p5.TableRow": {
            +    "description": [
            +      "A TableRow object represents a single row of data values, stored in columns, from a table. ",
            +      "A Table Row contains both an ordered array, and an unordered JSON object."
            +    ],
            +    "params": {
            +      "str": "String: (Optional) optional: populate the row with a  string of values, separated by the  separator",
            +      "separator": "String: (Optional) comma separated values (csv) by default"
            +    },
            +    "set": {
            +      "description": [
            +        "Stores a value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number: The value to be stored"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Stores a Float value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "Number|String: The value to be stored  as a Float"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Stores a String value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number|Boolean|Object: The value to be stored  as a String"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retrieves a value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String|Number: ",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Retrieves a Float value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "Number: Float Floating point number",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Retrieves an String value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String: String",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    }
            +  },
            +  "p5.XML": {
            +    "description": [
            +      "XML is a representation of an XML object, able to parse XML code. Use <a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects."
            +    ],
            +    "getParent": {
            +      "description": [
            +        "Gets a copy of the element's parent. Returns the parent as another <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "returns": "p5.XML: element parent"
            +    },
            +    "getName": {
            +      "description": [
            +        "Gets the element's full name, which is returned as a String."
            +      ],
            +      "returns": "String: the name of the node"
            +    },
            +    "setName": {
            +      "description": [
            +        "Sets the element's name, which is specified as a String."
            +      ],
            +      "params": {
            +        "the": "String: new name of the node"
            +      }
            +    },
            +    "hasChildren": {
            +      "description": [
            +        "Checks whether or not the element has any children, and returns the result as a boolean."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "listChildren": {
            +      "description": [
            +        "Get the names of all of the element's children, and returns the names as an array of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a> on each child element individually."
            +      ],
            +      "returns": "String[]: names of the children of the element"
            +    },
            +    "getChildren": {
            +      "description": [
            +        "Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When the name parameter is specified, then it will return all children that match that name."
            +      ],
            +      "returns": "p5.XML[]: children of the element",
            +      "params": {
            +        "name": "String: (Optional) element name"
            +      }
            +    },
            +    "getChild": {
            +      "description": [
            +        "Returns the first of the element's children that matches the name parameter or the child of the given index.It returns undefined if no matching child is found."
            +      ],
            +      "returns": "p5.XML: ",
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "addChild": {
            +      "description": [
            +        "Appends a new child to the element. The child can be specified with either a String, which will be used as the new tag's name, or as a reference to an existing <a href=\"#/p5.XML\">p5.XML</a> object. A reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "params": {
            +        "node": "p5.XML: a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added"
            +      }
            +    },
            +    "removeChild": {
            +      "description": [
            +        "Removes the element specified by name or index."
            +      ],
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "getAttributeCount": {
            +      "description": [
            +        "Counts the specified element's number of attributes, returned as an Number."
            +      ],
            +      "returns": "Integer: "
            +    },
            +    "listAttributes": {
            +      "description": [
            +        "Gets all of the specified element's attributes, and returns them as an array of Strings."
            +      ],
            +      "returns": "String[]: an array of strings containing the names of attributes"
            +    },
            +    "hasAttribute": {
            +      "description": [
            +        "Checks whether or not an element has the specified attribute."
            +      ],
            +      "returns": "Boolean: true if attribute found else false",
            +      "params": {
            +        "the": "String: attribute to be checked"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Returns an attribute value of the element as an Number. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, the value 0 is returned."
            +      ],
            +      "returns": "Number: ",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Returns an attribute value of the element as an String. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, null is returned."
            +      ],
            +      "returns": "String: ",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "setAttribute": {
            +      "description": [
            +        "Sets the content of an element's attribute. The first parameter specifies the attribute name, while the second specifies the new content."
            +      ],
            +      "params": {
            +        "name": "String: the full name of the attribute",
            +        "value": "Number|String|Boolean: the value of the attribute"
            +      }
            +    },
            +    "getContent": {
            +      "description": [
            +        "Returns the content of an element. If there is no such content, defaultValue is returned if specified, otherwise null is returned."
            +      ],
            +      "returns": "String: ",
            +      "params": {
            +        "defaultValue": "String: (Optional) value returned if no content is found"
            +      }
            +    },
            +    "setContent": {
            +      "description": [
            +        "Sets the element's content."
            +      ],
            +      "params": {
            +        "text": "String: the new content"
            +      }
            +    },
            +    "serialize": {
            +      "description": [
            +        "Serializes the element into a string. This function is useful for preparing the content to be sent over a http request or saved to file."
            +      ],
            +      "returns": "String: Serialized string of the element"
            +    }
            +  },
            +  "p5.Vector": {
            +    "description": [
            +      "A class to describe a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector. A vector is an entity that has both magnitude and direction. The datatype, however, stores the components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude and direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>. ",
            +      "In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a position, velocity, or acceleration. For example, if you consider a rectangle moving across the screen, at any given instant it has a position (a vector that points from the origin to its location), a velocity (the rate at which the object's position changes per time unit, expressed as a vector), and acceleration (the rate at which the object's velocity changes per time unit, expressed as a vector). ",
            +      "Since vectors represent groupings of values, we cannot simply use traditional addition/multiplication/etc. Instead, we'll need to do some \"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class."
            +    ],
            +    "params": {
            +      "x": "Number: (Optional) x component of the vector",
            +      "y": "Number: (Optional) y component of the vector",
            +      "z": "Number: (Optional) z component of the vector"
            +    },
            +    "x": {
            +      "description": [
            +        "The x component of the vector"
            +      ]
            +    },
            +    "y": {
            +      "description": [
            +        "The y component of the vector"
            +      ]
            +    },
            +    "z": {
            +      "description": [
            +        "The z component of the vector"
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Sets the x, y, and z component of the vector using two or three separate variables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array."
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) the x component of the vector",
            +        "y": "Number: (Optional) the y component of the vector",
            +        "z": "Number: (Optional) the z component of the vector",
            +        "value": "p5.Vector|Number[]: the vector to set"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object."
            +      ],
            +      "returns": "p5.Vector: the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    },
            +    "add": {
            +      "description": [
            +        "Adds x, y, and z components to a vector, adds one vector to another, or adds two independent vectors together. The version of the method that adds two vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to be added",
            +        "y": "Number: (Optional) the y component of the vector to be added",
            +        "z": "Number: (Optional) the z component of the vector to be added",
            +        "value": "p5.Vector|Number[]: the vector to add",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "rem": {
            +      "description": [
            +        "Gives remainder of a vector when it is divided by another vector. See examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of divisor vector",
            +        "y": "Number: the y component of divisor vector",
            +        "z": "Number: the z component of divisor vector",
            +        "value": "p5.Vector | Number[]: divisor vector",
            +        "v1": "p5.Vector: dividend <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: divisor <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtracts x, y, and z components from a vector, subtracts one vector from another, or subtracts two independent vectors. The version of the method that subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the other acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to subtract",
            +        "y": "Number: (Optional) the y component of the vector to subtract",
            +        "z": "Number: (Optional) the z component of the vector to subtract",
            +        "value": "p5.Vector|Number[]: the vector to subtract",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies the x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y, and z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector, the x, y, z components of both vectors are multiplied by each other (for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method creates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "n": "Number: The number to multiply with the vector",
            +        "x": "Number: The number to multiply with the x component of the vector",
            +        "y": "Number: The number to multiply with the y component of the vector",
            +        "z": "Number: (Optional) The number to multiply with the z component of the vector",
            +        "arr": "Number[]: The array to multiply with the components of the vector",
            +        "v": "p5.Vector: The vector to multiply with the components of the original vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and z components of two vectors against each other. When dividing a vector by a scalar, the x, y, and z components of the vector are all divided by the scalar. When dividing a vector by a vector, the x, y, z components of the source vector are treated as the dividend, and the x, y, z components of the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z). The static version of this method creates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "n": "Number: The number to divide the vector by",
            +        "x": "Number: The number to divide with the x component of the vector",
            +        "y": "Number: The number to divide with the y component of the vector",
            +        "z": "Number: (Optional) The number to divide with the z component of the vector",
            +        "arr": "Number[]: The array to divide the components of the vector by",
            +        "v": "p5.Vector: The vector to divide the components of the original vector by",
            +        "target": "p5.Vector: (Optional) the vector to receive the result",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "Calculates the magnitude (length) of the vector and returns the result as a float (this is simply the equation sqrt(x*x + y*y + z*z).)"
            +      ],
            +      "returns": "Number: magnitude of the vector",
            +      "params": {
            +        "vecT": "p5.Vector: the vector to return the magnitude of"
            +      }
            +    },
            +    "magSq": {
            +      "description": [
            +        "Calculates the squared magnitude of the vector and returns the result as a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.) Faster if the real length is not required in the case of comparing vectors, etc."
            +      ],
            +      "returns": "Number: squared magnitude of the vector"
            +    },
            +    "dot": {
            +      "description": [
            +        "Calculates the dot product of two vectors. The version of the method that computes the dot product of two independent vectors is a static method. See the examples for more context."
            +      ],
            +      "returns": "Number: the dot product",
            +      "params": {
            +        "x": "Number: x component of the vector",
            +        "y": "Number: (Optional) y component of the vector",
            +        "z": "Number: (Optional) z component of the vector",
            +        "value": "p5.Vector: value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "cross": {
            +      "description": [
            +        "Calculates and returns a vector composed of the cross product between two vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>. See the examples for more context."
            +      ],
            +      "returns": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +      "params": {
            +        "v": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> to be crossed",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "Calculates the Euclidean distance between two points (considering a point as a vector object). If you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a>"
            +      ],
            +      "returns": "Number: the distance",
            +      "params": {
            +        "v": "p5.Vector: the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "normalize": {
            +      "description": [
            +        "Normalize the vector to length 1 (make it a unit vector)."
            +      ],
            +      "returns": "p5.Vector: normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +      "params": {
            +        "v": "p5.Vector: the vector to normalize",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "limit": {
            +      "description": [
            +        "Limit the magnitude of this vector to the value used for the <b>max</b> parameter."
            +      ],
            +      "params": {
            +        "max": "Number: the maximum magnitude for the vector"
            +      }
            +    },
            +    "setMag": {
            +      "description": [
            +        "Set the magnitude of this vector to the value used for the <b>len</b> parameter."
            +      ],
            +      "params": {
            +        "len": "Number: the new length for this vector"
            +      }
            +    },
            +    "heading": {
            +      "description": [
            +        "Calculate the angle of rotation for this vector(only 2D vectors). p5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a> will take the current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and give the angle in radians or degree accordingly."
            +      ],
            +      "returns": "Number: the angle of rotation"
            +    },
            +    "setHeading": {
            +      "description": [
            +        "Rotate the vector to a specific angle (only 2D vectors), magnitude remains the same"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation"
            +      }
            +    },
            +    "rotate": {
            +      "description": [
            +        "Rotate the vector by an angle (only 2D vectors), magnitude remains the same"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation",
            +        "v": "p5.Vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "angleBetween": {
            +      "description": [
            +        "Calculates and returns the angle between two vectors. This function will take the current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and give the angle in radians or degree accordingly."
            +      ],
            +      "returns": "Number: the angle between (in radians)",
            +      "params": {
            +        "value": "p5.Vector: the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "Linear interpolate the vector to another vector"
            +      ],
            +      "params": {
            +        "x": "Number: the x component",
            +        "y": "Number: the y component",
            +        "z": "Number: the z component",
            +        "amt": "Number: the amount of interpolation; some value between 0.0  (old vector) and 1.0 (new vector). 0.9 is very near  the new vector. 0.5 is halfway in between.",
            +        "v": "p5.Vector: the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to",
            +        "v1": "p5.Vector",
            +        "v2": "p5.Vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result"
            +      }
            +    },
            +    "reflect": {
            +      "description": [
            +        "Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D This method acts on the vector directly"
            +      ],
            +      "params": {
            +        "surfaceNormal": "p5.Vector: the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method"
            +      }
            +    },
            +    "array": {
            +      "description": [
            +        "Return a representation of this vector as a float array. This is only for temporary use. If used in any other fashion, the contents should be copied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own array."
            +      ],
            +      "returns": "Number[]: an Array with the 3 values"
            +    },
            +    "equals": {
            +      "description": [
            +        "Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      ],
            +      "returns": "Boolean: whether the vectors are equals",
            +      "params": {
            +        "x": "Number: (Optional) the x component of the vector",
            +        "y": "Number: (Optional) the y component of the vector",
            +        "z": "Number: (Optional) the z component of the vector",
            +        "value": "p5.Vector|Array: the vector to compare"
            +      }
            +    },
            +    "fromAngle": {
            +      "description": [
            +        "Make a new 2D vector from an angle"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +      "params": {
            +        "angle": "Number: the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)",
            +        "length": "Number: (Optional) the length of the new vector (defaults to 1)"
            +      }
            +    },
            +    "fromAngles": {
            +      "description": [
            +        "Make a new 3D vector from a pair of ISO spherical angles"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +      "params": {
            +        "theta": "Number: the polar angle, in radians (zero is up)",
            +        "phi": "Number: the azimuthal angle, in radians  (zero is out of the screen)",
            +        "length": "Number: (Optional) the length of the new vector (defaults to 1)"
            +      }
            +    },
            +    "random2D": {
            +      "description": [
            +        "Make a new 2D unit vector from a random angle"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    },
            +    "random3D": {
            +      "description": [
            +        "Make a new random 3D unit vector."
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    }
            +  },
            +  "p5.Font": {
            +    "description": [
            +      "Base class for font handling"
            +    ],
            +    "params": {
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "font": {
            +      "description": [
            +        "Underlying opentype font implementation"
            +      ]
            +    },
            +    "textBounds": {
            +      "description": [
            +        "Returns a tight bounding box for the given text string using this font"
            +      ],
            +      "returns": "Object: a rectangle object with properties: x, y, w, h",
            +      "params": {
            +        "line": "String: a line of text",
            +        "x": "Number: x-position",
            +        "y": "Number: y-position",
            +        "fontSize": "Number: (Optional) font size to use (optional) Default is 12.",
            +        "options": "Object: (Optional) opentype options (optional)  opentype fonts contains alignment and baseline options.  Default is 'LEFT' and 'alphabetic'"
            +      }
            +    },
            +    "textToPoints": {
            +      "description": [
            +        "Computes an array of points following the path for specified text"
            +      ],
            +      "returns": "Array: an array of points, each with x, y, alpha (the path angle)",
            +      "params": {
            +        "txt": "String: a line of text",
            +        "x": "Number: x-position",
            +        "y": "Number: y-position",
            +        "fontSize": "Number: font size to use (optional)",
            +        "options": "Object: (Optional) an (optional) object that can contain: sampleFactor - the ratio of path-length to number of samples (default=.1); higher values yield more points and are therefore more precise simplifyThreshold - if set to a non-zero value, collinear points will be be removed from the polygon; the value represents the threshold angle to use when determining whether two edges are collinear"
            +      }
            +    }
            +  },
            +  "p5.Camera": {
            +    "description": [
            +      "This class describes a camera for use in p5's <a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\"> WebGL mode</a>. It contains camera position, orientation, and projection information necessary for rendering a 3D scene. ",
            +      "New p5.Camera objects can be made through the <a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through the methods described below. A camera created in this way will use a default position in the scene and a default perspective projection until these properties are changed through the various methods available. It is possible to create multiple cameras, in which case the current camera can be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method. ",
            +      "Note: The methods below operate in two coordinate systems: the 'world' coordinate system describe positions in terms of their relationship to the origin along the X, Y and Z axes whereas the camera's 'local' coordinate system describes positions from the camera's point of view: left-right, up-down, and forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method, for instance, moves the camera along its own axes, whereas the <a href=\"#/p5.Camera/setPosition\">setPosition()</a> method sets the camera's position in world-space. ",
            +      "The camera object propreties <code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code> which describes camera position, orientation, and projection are also accessible via the camera object generated using <a href=\"#/p5/createCamera\">createCamera()</a>"
            +    ],
            +    "params": {
            +      "rendererGL": "RendererGL: instance of WebGL renderer"
            +    },
            +    "eyeX": {
            +      "description": [
            +        "camera position value on x axis"
            +      ]
            +    },
            +    "eyeY": {
            +      "description": [
            +        "camera position value on y axis"
            +      ]
            +    },
            +    "eyeZ": {
            +      "description": [
            +        "camera position value on z axis"
            +      ]
            +    },
            +    "centerX": {
            +      "description": [
            +        "x coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerY": {
            +      "description": [
            +        "y coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerZ": {
            +      "description": [
            +        "z coordinate representing center of the sketch"
            +      ]
            +    },
            +    "upX": {
            +      "description": [
            +        "x component of direction 'up' from camera"
            +      ]
            +    },
            +    "upY": {
            +      "description": [
            +        "y component of direction 'up' from camera"
            +      ]
            +    },
            +    "upZ": {
            +      "description": [
            +        "z component of direction 'up' from camera"
            +      ]
            +    },
            +    "perspective": {
            +      "description": [
            +        "Sets a perspective projection. Accepts the same parameters as the global <a href=\"#/p5/perspective\">perspective()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "ortho": {
            +      "description": [
            +        "Sets an orthographic projection. Accepts the same parameters as the global <a href=\"#/p5/ortho\">ortho()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "frustum": {
            +      "description": [
            +        "Sets the camera's frustum. Accepts the same parameters as the global <a href=\"#/p5/frustum\">frustum()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Panning rotates the camera view to the left and right."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "tilt": {
            +      "description": [
            +        "Tilting rotates the camera view up and down."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "lookAt": {
            +      "description": [
            +        "Reorients the camera to look at a position in world space."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "Sets the camera's position and orientation. Accepts the same parameters as the global <a href=\"#/p5/camera\">camera()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "move": {
            +      "description": [
            +        "Move camera along its local axes while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: amount to move along camera's left-right axis",
            +        "y": "Number: amount to move along camera's up-down axis",
            +        "z": "Number: amount to move along camera's forward-backward axis"
            +      }
            +    },
            +    "setPosition": {
            +      "description": [
            +        "Set camera position in world-space while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    }
            +  },
            +  "p5.Geometry": {
            +    "description": [
            +      "p5 Geometry class"
            +    ],
            +    "params": {
            +      "detailX": "Integer: (Optional) number of vertices on horizontal surface",
            +      "detailY": "Integer: (Optional) number of vertices on horizontal surface",
            +      "callback": "Function: (Optional) function to call upon object instantiation."
            +    },
            +    "computeFaces": {
            +      "description": [
            +        "computes faces for geometry objects based on the vertices."
            +      ]
            +    },
            +    "computeNormals": {
            +      "description": [
            +        "computes smooth normals per vertex as an average of each face."
            +      ]
            +    },
            +    "averageNormals": {
            +      "description": [
            +        "Averages the vertex normals. Used in curved surfaces"
            +      ]
            +    },
            +    "averagePoleNormals": {
            +      "description": [
            +        "Averages pole normals. Used in spherical primitives"
            +      ]
            +    },
            +    "normalize": {
            +      "description": [
            +        "Modifies all vertices to be centered within the range -100 to 100."
            +      ]
            +    }
            +  },
            +  "p5.Shader": {
            +    "description": [
            +      "Shader class for WEBGL Mode"
            +    ],
            +    "params": {
            +      "renderer": "p5.RendererGL: an instance of p5.RendererGL that will provide the GL context for this new p5.Shader",
            +      "vertSrc": "String: source code for the vertex shader (as a string)",
            +      "fragSrc": "String: source code for the fragment shader (as a string)"
            +    },
            +    "setUniform": {
            +      "description": [
            +        "Wrapper around gl.uniform functions. As we store uniform info in the shader we can use that to do type checking on the supplied data and call the appropriate function."
            +      ],
            +      "params": {
            +        "uniformName": "String: the name of the uniform in the shader program",
            +        "data": "Object|Number|Boolean|Number[]: the data to be associated with that uniform; type varies (could be a single numerical value, array, matrix, or texture / sampler reference)"
            +      }
            +    }
            +  },
            +  "p5.sound": {},
            +  "p5.SoundFile": {
            +    "description": [
            +      "SoundFile object with a path to a file.  ",
            +      "The p5.SoundFile may not be available immediately because it loads the file information asynchronously.  ",
            +      "To do something with the sound as soon as it loads pass the name of a function as the second parameter.  ",
            +      "Only one file path is required. However, audio file formats (i.e. mp3, ogg, wav and m4a/aac) are not supported by all web browsers. If you want to ensure compatability, instead of a single file path, you may include an Array of filepaths, and the browser will choose a format that works."
            +    ],
            +    "params": {
            +      "path": "String|Array: path to a sound file (String). Optionally,  you may include multiple file formats in  an array. Alternately, accepts an object  from the HTML5 File API, or a p5.File.",
            +      "successCallback": "Function: (Optional) Name of a function to call once file loads",
            +      "errorCallback": "Function: (Optional) Name of a function to call if file fails to  load. This function will receive an error or  XMLHttpRequest object with information  about what went wrong.",
            +      "whileLoadingCallback": "Function: (Optional) Name of a function to call while file  is loading. That function will  receive progress of the request to  load the sound file  (between 0 and 1) as its first  parameter. This progress  does not account for the additional  time needed to decode the audio data."
            +    },
            +    "isLoaded": {
            +      "description": [
            +        "Returns true if the sound file finished loading successfully."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "play": {
            +      "description": [
            +        "Play the p5.SoundFile"
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule playback to start (in seconds from now).",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) amplitude (volume)  of playback",
            +        "cueStart": "Number: (Optional) (optional) cue start time in seconds",
            +        "duration": "Number: (Optional) (optional) duration of playback in seconds"
            +      }
            +    },
            +    "playMode": {
            +      "description": [
            +        "p5.SoundFile has two play modes: <code>restart</code> and <code>sustain</code>. Play Mode determines what happens to a p5.SoundFile if it is triggered while in the middle of playback. In sustain mode, playback will continue simultaneous to the new playback. In restart mode, play() will stop playback and start over. With untilDone, a sound will play only if it's not already playing. Sustain is the default mode."
            +      ],
            +      "params": {
            +        "str": "String: 'restart' or 'sustain' or 'untilDone'"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses a file that is currently playing. If the file is not playing, then nothing will happen. ",
            +        "After pausing, .play() will resume from the paused position. If p5.SoundFile had been set to loop before it was paused, it will continue to loop after it is unpaused with .play()."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop the p5.SoundFile. Accepts optional parameters to set the playback rate, playback volume, loopStart, loopEnd."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) playback volume",
            +        "cueLoopStart": "Number: (Optional) (optional) startTime in seconds",
            +        "duration": "Number: (Optional) (optional) loop duration in seconds"
            +      }
            +    },
            +    "setLoop": {
            +      "description": [
            +        "Set a p5.SoundFile's looping flag to true or false. If the sound is currently playing, this change will take effect when it reaches the end of the current playback."
            +      ],
            +      "params": {
            +        "Boolean": "Boolean: set looping to true or false"
            +      }
            +    },
            +    "isLooping": {
            +      "description": [
            +        "Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "isPlaying": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is playing, false if not (i.e. paused or stopped)."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "isPaused": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is paused, false if not (i.e. playing or stopped)."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop soundfile playback."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  in seconds from now"
            +      }
            +    },
            +    "pan": {
            +      "description": [
            +        "Set the stereo panning of a p5.sound object to a floating point number between -1.0 (left) and 1.0 (right). Default is 0.0 (center)."
            +      ],
            +      "params": {
            +        "panValue": "Number: (Optional) Set the stereo panner",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current stereo pan position (-1.0 to 1.0)"
            +      ],
            +      "returns": "Number: Returns the stereo pan setting of the Oscillator  as a number between -1.0 (left) and 1.0 (right).  0.0 is center and default."
            +    },
            +    "rate": {
            +      "description": [
            +        "Set the playback rate of a sound file. Will change the speed and the pitch. Values less than zero will reverse the audio buffer."
            +      ],
            +      "params": {
            +        "playbackRate": "Number: (Optional) Set the playback rate. 1.0 is normal,  .5 is half-speed, 2.0 is twice as fast.  Values less than zero play backwards."
            +      }
            +    },
            +    "setVolume": {
            +      "description": [
            +        "Multiply the output volume (amplitude) of a sound file between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class. ",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal."
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of a sound file in seconds."
            +      ],
            +      "returns": "Number: The duration of the soundFile in seconds."
            +    },
            +    "currentTime": {
            +      "description": [
            +        "Return the current position of the p5.SoundFile playhead, in seconds. Time is relative to the normal buffer direction, so if <code>reverseBuffer</code> has been called, currentTime will count backwards."
            +      ],
            +      "returns": "Number: currentTime of the soundFile in seconds."
            +    },
            +    "jump": {
            +      "description": [
            +        "Move the playhead of a soundfile that is currently playing to a new position and a new duration, in seconds. If none are given, will reset the file to play entire duration from start to finish. To set the position of a soundfile that is not currently playing, use the <code>play</code> or <code>loop</code> methods."
            +      ],
            +      "params": {
            +        "cueTime": "Number: cueTime of the soundFile in seconds.",
            +        "duration": "Number: duration in seconds."
            +      }
            +    },
            +    "channels": {
            +      "description": [
            +        "Return the number of channels in a sound file. For example, Mono = 1, Stereo = 2."
            +      ],
            +      "returns": "Number: [channels]"
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Return the sample rate of the sound file."
            +      ],
            +      "returns": "Number: [sampleRate]"
            +    },
            +    "frames": {
            +      "description": [
            +        "Return the number of samples in a sound file. Equal to sampleRate * duration."
            +      ],
            +      "returns": "Number: [sampleCount]"
            +    },
            +    "getPeaks": {
            +      "description": [
            +        "Returns an array of amplitude peaks in a p5.SoundFile that can be used to draw a static waveform. Scans through the p5.SoundFile's audio buffer to find the greatest amplitudes. Accepts one parameter, 'length', which determines size of the array. Larger arrays result in more precise waveform visualizations. ",
            +        "Inspired by Wavesurfer.js."
            +      ],
            +      "returns": "Float32Array: Array of peaks.",
            +      "params": {
            +        "length": "Number: (Optional) length is the size of the returned array.  Larger length results in more precision.  Defaults to 5*width of the browser window."
            +      }
            +    },
            +    "reverseBuffer": {
            +      "description": [
            +        "Reverses the p5.SoundFile's buffer source. Playback must be handled separately (see example)."
            +      ]
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the soundfile reaches the end of a buffer. If the soundfile is playing through once, this will be called when it ends. If it is looping, it will be called when stop is called."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connects the output of a p5sound object to input of another p5.sound object. For example, you may connect a p5.SoundFile to an FFT or an Effect. If no parameter is given, it will connect to the main output. Most p5sound objects connect to the master output when they are created."
            +      ],
            +      "params": {
            +        "object": "Object: (Optional) Audio object that accepts an input"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnects the output of this p5sound object."
            +      ]
            +    },
            +    "setPath": {
            +      "description": [
            +        "Reset the source for this SoundFile to a new path (URL)."
            +      ],
            +      "params": {
            +        "path": "String: path to audio file",
            +        "callback": "Function: Callback"
            +      }
            +    },
            +    "setBuffer": {
            +      "description": [
            +        "Replace the current Audio Buffer with a new Buffer."
            +      ],
            +      "params": {
            +        "buf": "Array: Array of Float32 Array(s). 2 Float32 Arrays  will create a stereo source. 1 will create  a mono source."
            +      }
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point. ",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback. ",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ]
            +    },
            +    "save": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. To upload a file to a server, see <a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a>"
            +      ],
            +      "params": {
            +        "fileName": "String: (Optional) name of the resulting .wav file."
            +      }
            +    },
            +    "getBlob": {
            +      "description": [
            +        "This method is useful for sending a SoundFile to a server. It returns the .wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at MDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\". A Blob is a file-like data object that can be uploaded to a server with an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll use the <code>httpDo</code> options object to send a POST request with some specific options: we encode the request as <code>multipart/form-data</code>, and attach the blob as one of the form values using <code>FormData</code>."
            +      ],
            +      "returns": "Blob: A file-like data object"
            +    }
            +  },
            +  "p5.Amplitude": {
            +    "description": [
            +      "Amplitude measures volume between 0.0 and 1.0. Listens to all p5sound by default, or use setInput() to listen to a specific sound source. Accepts an optional smoothing value, which defaults to 0."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) between 0.0 and .999 to smooth  amplitude readings (defaults to 0)"
            +    },
            +    "setInput": {
            +      "description": [
            +        "Connects to the p5sound instance (main output) by default. Optionally, you can pass in a specific source (i.e. a soundfile)."
            +      ],
            +      "params": {
            +        "snd": "SoundObject|undefined: (Optional) set the sound source  (optional, defaults to  main output)",
            +        "smoothing": "Number|undefined: (Optional) a range between 0.0 and 1.0  to smooth amplitude readings"
            +      }
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Returns a single Amplitude reading at the moment it is called. For continuous readings, run in the draw loop."
            +      ],
            +      "returns": "Number: Amplitude as a number between 0.0 and 1.0",
            +      "params": {
            +        "channel": "Number: (Optional) Optionally return only channel 0 (left) or 1 (right)"
            +      }
            +    },
            +    "toggleNormalize": {
            +      "description": [
            +        "Determines whether the results of Amplitude.process() will be Normalized. To normalize, Amplitude finds the difference the loudest reading it has processed and the maximum amplitude of 1.0. Amplitude adds this difference to all values to produce results that will reliably map between 0.0 and 1.0. However, if a louder moment occurs, the amount that Normalize adds to all the values will change. Accepts an optional boolean parameter (true or false). Normalizing is off by default."
            +      ],
            +      "params": {
            +        "boolean": "Boolean: (Optional) set normalize to true (1) or false (0)"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth Amplitude analysis by averaging with the last analysis frame. Off by default."
            +      ],
            +      "params": {
            +        "set": "Number: smoothing from 0.0 <= 1"
            +      }
            +    }
            +  },
            +  "p5.FFT": {
            +    "description": [
            +      "FFT (Fast Fourier Transform) is an analysis algorithm that isolates individual <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\"> audio frequencies</a> within a waveform.  ",
            +      "Once instantiated, a p5.FFT object can return an array based on two types of analyses: • <code>FFT.waveform()</code> computes amplitude values along the time domain. The array indices correspond to samples across a brief moment in time. Each value represents amplitude of the waveform at that sample of time. • <code>FFT.analyze() </code> computes amplitude values along the frequency domain. The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Use with <code>getEnergy()</code> to measure amplitude at specific frequencies, or within a range of frequencies. ",
            +      "FFT analyzes a very short snapshot of sound called a sample buffer. It returns an array of amplitude measurements, referred to as <code>bins</code>. The array is 1024 bins long by default. You can change the bin array length, but it must be a power of 2 between 16 and 1024 in order for the FFT algorithm to function correctly. The actual size of the FFT buffer is twice the number of bins, so given a standard sample rate, the buffer is 2048/44100 seconds long."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) Smooth results of Freq Spectrum.  0.0 < smoothing < 1.0.  Defaults to 0.8.",
            +      "bins": "Number: (Optional) Length of resulting array.  Must be a power of two between  16 and 1024. Defaults to 1024."
            +    },
            +    "setInput": {
            +      "description": [
            +        "Set the input source for the FFT analysis. If no source is provided, FFT will analyze all sound in the sketch."
            +      ],
            +      "params": {
            +        "source": "Object: (Optional) p5.sound object (or web audio API source node)"
            +      }
            +    },
            +    "waveform": {
            +      "description": [
            +        "Returns an array of amplitude values (between -1.0 and +1.0) that represent a snapshot of amplitude readings in a single buffer. Length will be equal to bins (defaults to 1024). Can be used to draw the waveform of a sound."
            +      ],
            +      "returns": "Array: Array Array of amplitude values (-1 to 1)  over time. Array length = bins.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "precision": "String: (Optional) If any value is provided, will return results  in a Float32 Array which is more precise  than a regular array."
            +      }
            +    },
            +    "analyze": {
            +      "description": [
            +        "Returns an array of amplitude values (between 0 and 255) across the frequency spectrum. Length is equal to FFT bins (1024 by default). The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Must be called prior to using <code>getEnergy()</code>."
            +      ],
            +      "returns": "Array: spectrum Array of energy (amplitude/volume)  values across the frequency spectrum.  Lowest energy (silence) = 0, highest  possible is 255.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "scale": "Number: (Optional) If \"dB,\" returns decibel  float measurements between  -140 and 0 (max).  Otherwise returns integers from 0-255."
            +      }
            +    },
            +    "getEnergy": {
            +      "description": [
            +        "Returns the amount of energy (volume) at a specific <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\"> frequency</a>, or the average amount of energy between two frequencies. Accepts Number(s) corresponding to frequency (in Hz), or a \"string\" corresponding to predefined frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\"). Returns a range between 0 (no energy/volume at that frequency) and 255 (maximum energy). <em>NOTE: analyze() must be called prior to getEnergy(). analyze() tells the FFT to analyze frequency data, and getEnergy() uses the results to determine the value at a specific frequency or range of frequencies.</em>"
            +      ],
            +      "returns": "Number: Energy Energy (volume/amplitude) from  0 and 255.",
            +      "params": {
            +        "frequency1": "Number|String: Will return a value representing  energy at this frequency. Alternately,  the strings \"bass\", \"lowMid\" \"mid\",  \"highMid\", and \"treble\" will return  predefined frequency ranges.",
            +        "frequency2": "Number: (Optional) If a second frequency is given,  will return average amount of  energy that exists between the  two frequencies."
            +      }
            +    },
            +    "getCentroid": {
            +      "description": [
            +        "Returns the <a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\"> spectral centroid</a> of the input signal. <em>NOTE: analyze() must be called prior to getCentroid(). Analyze() tells the FFT to analyze frequency data, and getCentroid() uses the results determine the spectral centroid.</em>"
            +      ],
            +      "returns": "Number: Spectral Centroid Frequency of the spectral centroid in Hz."
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth FFT analysis by averaging with the last analysis frame."
            +      ],
            +      "params": {
            +        "smoothing": "Number: 0.0 < smoothing < 1.0.  Defaults to 0.8."
            +      }
            +    },
            +    "linAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values for a given number of frequency bands split equally. N defaults to 16. <em>NOTE: analyze() must be called prior to linAverages(). Analyze() tells the FFT to analyze frequency data, and linAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: linearAverages Array of average amplitude values for each group",
            +      "params": {
            +        "N": "Number: Number of returned frequency groups"
            +      }
            +    },
            +    "logAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values of the spectrum, for a given set of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\"> Octave Bands</a> <em>NOTE: analyze() must be called prior to logAverages(). Analyze() tells the FFT to analyze frequency data, and logAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: logAverages Array of average amplitude values for each group",
            +      "params": {
            +        "octaveBands": "Array: Array of Octave Bands objects for grouping"
            +      }
            +    },
            +    "getOctaveBands": {
            +      "description": [
            +        "Calculates and Returns the 1/N <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a> N defaults to 3 and minimum central frequency to 15.625Hz. (1/3 Octave Bands ~= 31 Frequency Bands) Setting fCtr0 to a central value of a higher octave will ignore the lower bands and produce less frequency groups."
            +      ],
            +      "returns": "Array: octaveBands Array of octave band objects with their bounds",
            +      "params": {
            +        "N": "Number: Specifies the 1/N type of generated octave bands",
            +        "fCtr0": "Number: Minimum central frequency for the lowest band"
            +      }
            +    }
            +  },
            +  "p5.Oscillator": {
            +    "description": [
            +      "Creates a signal that oscillates between -1.0 and 1.0. By default, the oscillation takes the form of a sinusoidal shape ('sine'). Additional types include 'triangle', 'sawtooth' and 'square'. The frequency defaults to 440 oscillations per second (440Hz, equal to the pitch of an 'A' note).  ",
            +      "Set the type of oscillation with setType(), or by instantiating a specific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a href=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a href=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a href=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>. "
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) frequency defaults to 440Hz",
            +      "type": "String: (Optional) type of oscillator. Options:  'sine' (default), 'triangle',  'sawtooth', 'square'"
            +    },
            +    "start": {
            +      "description": [
            +        "Start an oscillator. ",
            +        "Starting an oscillator on a user gesture will enable audio in browsers that have a strict autoplay policy, including Chrome and most mobile devices. See also: <code>userStartAudio()</code>."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) startTime in seconds from now.",
            +        "frequency": "Number: (Optional) frequency in Hz."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop an oscillator. Accepts an optional parameter to determine how long (in seconds from now) until the oscillator stops."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: Time, in seconds from now."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the amplitude between 0 and 1.0. Or, pass in an object such as an oscillator to modulate amplitude with an audio signal."
            +      ],
            +      "returns": "AudioParam: gain If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's  gain/amplitude/volume)",
            +      "params": {
            +        "vol": "Number|Object: between 0 and 1.0  or a modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getAmp": {
            +      "description": [
            +        "Returns the value of output gain"
            +      ],
            +      "returns": "Number: Amplitude value between 0.0 and 1.0"
            +    },
            +    "freq": {
            +      "description": [
            +        "Set frequency of an oscillator to a value. Or, pass in an object such as an oscillator to modulate the frequency with an audio signal."
            +      ],
            +      "returns": "AudioParam: Frequency If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's frequency",
            +      "params": {
            +        "Frequency": "Number|Object: Frequency in Hz  or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Ramp time (in seconds)",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen  at x seconds from now"
            +      }
            +    },
            +    "getFreq": {
            +      "description": [
            +        "Returns the value of frequency of oscillator"
            +      ],
            +      "returns": "Number: Frequency of oscillator in Hertz"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type to 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "params": {
            +        "type": "String: 'sine', 'triangle', 'sawtooth' or 'square'."
            +      }
            +    },
            +    "getType": {
            +      "description": [
            +        "Returns current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "returns": "String: type of oscillator eg . 'sine', 'triangle', 'sawtooth' or 'square'."
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Pan between Left (-1) and Right (1)"
            +      ],
            +      "params": {
            +        "panning": "Number: Number between -1 and 1",
            +        "timeFromNow": "Number: schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current value of panPosition , between Left (-1) and Right (1)"
            +      ],
            +      "returns": "Number: panPosition of oscillator , between Left (-1) and Right (1)"
            +    },
            +    "phase": {
            +      "description": [
            +        "Set the phase of an oscillator between 0.0 and 1.0. In this implementation, phase is a delay time based on the oscillator's current frequency."
            +      ],
            +      "params": {
            +        "phase": "Number: float between 0.0 and 1.0"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Oscillator's output amplitude by a fixed value (i.e. turn it up!). Calling this method again will override the initial mult() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with multiplied output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this oscillator's amplitude values to a given range, and return the oscillator. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.SinOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SinOsc()</code>. This creates a Sine Wave Oscillator and is equivalent to <code> new p5.Oscillator('sine') </code> or creating a p5.Oscillator and then calling its method <code>setType('sine')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.TriOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.TriOsc()</code>. This creates a Triangle Wave Oscillator and is equivalent to <code>new p5.Oscillator('triangle') </code> or creating a p5.Oscillator and then calling its method <code>setType('triangle')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SawOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SawOsc()</code>. This creates a SawTooth Wave Oscillator and is equivalent to <code> new p5.Oscillator('sawtooth') </code> or creating a p5.Oscillator and then calling its method <code>setType('sawtooth')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SqrOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SqrOsc()</code>. This creates a Square Wave Oscillator and is equivalent to <code> new p5.Oscillator('square') </code> or creating a p5.Oscillator and then calling its method <code>setType('square')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.Envelope": {
            +    "description": [
            +      "Envelopes are pre-defined amplitude distribution over time. Typically, envelopes are used to control the output volume of an object, a series of fades referred to as Attack, Decay, Sustain and Release ( <a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a> ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can control an Oscillator's frequency like this: <code>osc.freq(env)</code>. ",
            +      "Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level. Use <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime. ",
            +      "Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope, the <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger, or <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/ <code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff."
            +    ],
            +    "attackTime": {
            +      "description": [
            +        "Time until envelope reaches attackLevel"
            +      ]
            +    },
            +    "attackLevel": {
            +      "description": [
            +        "Level once attack is complete."
            +      ]
            +    },
            +    "decayTime": {
            +      "description": [
            +        "Time until envelope reaches decayLevel."
            +      ]
            +    },
            +    "decayLevel": {
            +      "description": [
            +        "Level after decay. The envelope will sustain here until it is released."
            +      ]
            +    },
            +    "releaseTime": {
            +      "description": [
            +        "Duration of the release portion of the envelope."
            +      ]
            +    },
            +    "releaseLevel": {
            +      "description": [
            +        "Level at the end of the release."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Reset the envelope with a series of time/value pairs."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds) before level  reaches attackLevel",
            +        "attackLevel": "Number: Typically an amplitude between  0.0 and 1.0",
            +        "decayTime": "Number: Time",
            +        "decayLevel": "Number: Amplitude (In a standard ADSR envelope,  decayLevel = sustainLevel)",
            +        "releaseTime": "Number: Release Time (in seconds)",
            +        "releaseLevel": "Number: Amplitude"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setRange": {
            +      "description": [
            +        "Set max (attackLevel) and min (releaseLevel) of envelope."
            +      ],
            +      "params": {
            +        "aLevel": "Number: attack level (defaults to 1)",
            +        "rLevel": "Number: release level (defaults to 0)"
            +      }
            +    },
            +    "setInput": {
            +      "description": [
            +        "Assign a parameter to be controlled by this envelope. If a p5.Sound object is given, then the p5.Envelope will control its output gain. If multiple inputs are provided, the env will control all of them."
            +      ],
            +      "params": {
            +        "inputs": "Object: (Optional) A p5.sound object or  Web Audio Param."
            +      }
            +    },
            +    "setExp": {
            +      "description": [
            +        "Set whether the envelope ramp is linear (default) or exponential. Exponential ramps can be useful because we perceive amplitude and frequency logarithmically."
            +      ],
            +      "params": {
            +        "isExp": "Boolean: true is exponential, false is linear"
            +      }
            +    },
            +    "play": {
            +      "description": [
            +        "Play tells the envelope to start acting on a given input. If the input is a p5.sound object (i.e. AudioIn, Oscillator, SoundFile), then Envelope will control its output volume. Envelopes can also be used to control any <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Audio Param.</a>"
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound object or  Web Audio Param.",
            +        "startTime": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go. Input can be any p5.sound object, or a <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Param</a>."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time from now (in seconds)"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the Release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "ramp": {
            +      "description": [
            +        "Exponentially ramp to a value using the first two values from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code> as <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\"> time constants</a> for simple exponential ramps. If the value is higher than current value, it uses attackTime, while a decrease uses decayTime."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: When to trigger the ramp",
            +        "v": "Number: Target value",
            +        "v2": "Number: (Optional) Second target value"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Envelope's output amplitude by a fixed value. Calling this method again will override the initial mult() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this envelope's amplitude values to a given range, and return the envelope. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.Noise": {
            +    "description": [
            +      "Noise is a type of oscillator that generates a buffer with random values."
            +    ],
            +    "params": {
            +      "type": "String: Type of noise can be 'white' (default),  'brown' or 'pink'."
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type of noise to 'white', 'pink' or 'brown'. White is the default."
            +      ],
            +      "params": {
            +        "type": "String: (Optional) 'white', 'pink' or 'brown'"
            +      }
            +    }
            +  },
            +  "p5.Pulse": {
            +    "description": [
            +      "Creates a Pulse object, an oscillator that implements Pulse Width Modulation. The pulse is created with two oscillators. Accepts a parameter for frequency, and to set the width between the pulses. See <a href=\" http://p5js.org/reference/#/p5.Oscillator\"> <code>p5.Oscillator</code> for a full list of methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Frequency in oscillations per second (Hz)",
            +      "w": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +    },
            +    "width": {
            +      "description": [
            +        "Set the width of a Pulse object (an oscillator that implements Pulse Width Modulation)."
            +      ],
            +      "params": {
            +        "width": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +      }
            +    }
            +  },
            +  "p5.AudioIn": {
            +    "description": [
            +      "Get audio from an input, i.e. your computer's microphone.  ",
            +      "Turn the mic on/off with the start() and stop() methods. When the mic is on, its volume can be measured with getLevel or by connecting an FFT object.  ",
            +      "If you want to hear the AudioIn, use the .connect() method. AudioIn does not connect to p5.sound output by default to prevent feedback.  ",
            +      "<em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/ Stream</a> API, which is not supported by certain browsers. Access in Chrome browser is limited to localhost and https, but access over http may be limited.</em>"
            +    ],
            +    "params": {
            +      "errorCallback": "Function: (Optional) A function to call if there is an error  accessing the AudioIn. For example,  Safari and iOS devices do not  currently allow microphone access."
            +    },
            +    "input": {},
            +    "output": {},
            +    "stream": {},
            +    "mediaStream": {},
            +    "currentSource": {},
            +    "enabled": {
            +      "description": [
            +        "Client must allow browser to access their microphone / audioin source. Default: false. Will become true when the client enables access."
            +      ]
            +    },
            +    "amplitude": {
            +      "description": [
            +        "Input amplitude, connect to it by default but not to master out"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start processing audio input. This enables the use of other AudioIn methods like getLevel(). Note that by default, AudioIn is not connected to p5.sound's output. So you won't hear anything unless you use the connect() method.<br/> ",
            +        "Certain browsers limit access to the user's microphone. For example, Chrome only allows access from localhost and over https. For this reason, you may want to include an errorCallback—a function that is called in case the browser won't provide mic access."
            +      ],
            +      "params": {
            +        "successCallback": "Function: (Optional) Name of a function to call on  success.",
            +        "errorCallback": "Function: (Optional) Name of a function to call if  there was an error. For example,  some browsers do not support  getUserMedia."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel(). If re-starting, the user may be prompted for permission access."
            +      ]
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to an audio unit. If no parameter is provided, will connect to the main output (i.e. your speakers).<br/>"
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) An object that accepts audio input,  such as an FFT"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect the AudioIn from all audio units. For example, if connect() had been called, disconnect() will stop sending signal to your speakers.<br/>"
            +      ]
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Read the Amplitude (volume level) of an AudioIn. The AudioIn class contains its own instance of the Amplitude class to help make it easy to get a microphone's volume level. Accepts an optional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must .start() before using .getLevel().</em><br/>"
            +      ],
            +      "returns": "Number: Volume level (between 0.0 and 1.0)",
            +      "params": {
            +        "smoothing": "Number: (Optional) Smoothing is 0.0 by default.  Smooths values based on previous values."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set amplitude (volume) of a mic input between 0 and 1.0. <br/>"
            +      ],
            +      "params": {
            +        "vol": "Number: between 0 and 1.0",
            +        "time": "Number: (Optional) ramp time (optional)"
            +      }
            +    },
            +    "getSources": {
            +      "description": [
            +        "Returns a list of available input sources. This is a wrapper for <a href=\"https://developer.mozilla.org/ en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\"> MediaDevices.enumerateDevices() - Web APIs | MDN</a> and it returns a Promise."
            +      ],
            +      "returns": "Promise: Returns a Promise that can be used in place of the callbacks, similar  to the enumerateDevices() method",
            +      "params": {
            +        "successCallback": "Function: (Optional) This callback function handles the sources when they  have been enumerated. The callback function  receives the deviceList array as its only argument",
            +        "errorCallback": "Function: (Optional) This optional callback receives the error  message as its argument."
            +      }
            +    },
            +    "setSource": {
            +      "description": [
            +        "Set the input source. Accepts a number representing a position in the array returned by getSources(). This is only available in browsers that support  <a href=\"https://developer.mozilla.org/  en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">  navigator.mediaDevices.enumerateDevices()</a>"
            +      ],
            +      "params": {
            +        "num": "Number: position of input source in the array"
            +      }
            +    }
            +  },
            +  "p5.Effect": {
            +    "description": [
            +      "Effect is a base class for audio effects in p5. This module handles the nodes and methods that are common and useful for current and future effects. ",
            +      "This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>, <a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>, <a href=\"/reference/#/p5.Delay\">p5.Delay</a>, <a href=\"/reference/#/p5.Filter\">p5.Filter</a>, <a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>."
            +    ],
            +    "params": {
            +      "ac": "Object: (Optional) Reference to the audio context of the p5 object",
            +      "input": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "output": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "_drywet": "Object: (Optional) Tone.JS CrossFade node (defaults to value: 1)",
            +      "wet": "AudioNode: (Optional) Effects that extend this class should connect  to the wet signal to this gain node, so that dry and wet  signals are mixed properly."
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output volume of the filter."
            +      ],
            +      "params": {
            +        "vol": "Number: (Optional) amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts until rampTime",
            +        "tFromNow": "Number: (Optional) schedule this event to happen in tFromNow seconds"
            +      }
            +    },
            +    "chain": {
            +      "description": [
            +        "Link effects together in a chain Example usage: filter.chain(reverb, delay, panner); May be used with an open-ended number of arguments"
            +      ],
            +      "params": {
            +        "arguments": "Object: (Optional) Chain together multiple sound objects"
            +      }
            +    },
            +    "drywet": {
            +      "description": [
            +        "Adjust the dry/wet value."
            +      ],
            +      "params": {
            +        "fade": "Number: (Optional) The desired drywet value (0 - 1.0)"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.js-sound, Web Audio Node, or use signal to control an AudioParam"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Filter": {
            +    "description": [
            +      "A p5.Filter uses a Web Audio Biquad Filter to filter the frequency response of an input source. Subclasses include: <a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>: Allows frequencies below the cutoff frequency to pass through, and attenuates frequencies above the cutoff.<br/> <a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>: The opposite of a lowpass filter. <br/> <a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>: Allows a range of frequencies to pass through and attenuates the frequencies below and above this frequency range.<br/>  ",
            +      "The <code>.res()</code> method controls either width of the bandpass, or resonance of the low/highpass cutoff frequency. ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "type": "String: (Optional) 'lowpass' (default), 'highpass', 'bandpass'"
            +    },
            +    "biquadFilter": {
            +      "description": [
            +        "The p5.Filter is built with a <a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\"> Web Audio BiquadFilter Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Filter an audio signal according to a set of filter parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance/Width of the filter frequency  from 0.001 to 1000"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the frequency and the resonance of the filter."
            +      ],
            +      "params": {
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance (Q) from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "freq": {
            +      "description": [
            +        "Set the filter frequency, in Hz, from 10 to 22050 (the range of human hearing, although in reality most people hear in a narrower range)."
            +      ],
            +      "returns": "Number: value Returns the current frequency value",
            +      "params": {
            +        "freq": "Number: Filter Frequency",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "res": {
            +      "description": [
            +        "Controls either width of a bandpass frequency, or the resonance of a low/highpass cutoff frequency."
            +      ],
            +      "returns": "Number: value Returns the current res value",
            +      "params": {
            +        "res": "Number: Resonance/Width of filter freq  from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "gain": {
            +      "description": [
            +        "Controls the gain attribute of a Biquad Filter. This is distinctly different from .amp() which is inherited from p5.Effect .amp() controls the volume via the output gain node p5.Filter.gain() controls the gain parameter of a Biquad Filter node."
            +      ],
            +      "returns": "Number: Returns the current or updated gain value",
            +      "params": {
            +        "gain": "Number"
            +      }
            +    },
            +    "toggle": {
            +      "description": [
            +        "Toggle function. Switches between the specified type and allpass"
            +      ],
            +      "returns": "Boolean: [Toggle value]"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set the type of a p5.Filter. Possible types include: \"lowpass\" (default), \"highpass\", \"bandpass\", \"lowshelf\", \"highshelf\", \"peaking\", \"notch\", \"allpass\"."
            +      ],
            +      "params": {
            +        "t": "String"
            +      }
            +    }
            +  },
            +  "p5.LowPass": {
            +    "description": [
            +      "Constructor: <code>new p5.LowPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('lowpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.HighPass": {
            +    "description": [
            +      "Constructor: <code>new p5.HighPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('highpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.BandPass": {
            +    "description": [
            +      "Constructor: <code>new p5.BandPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('bandpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.EQ": {
            +    "description": [
            +      "p5.EQ is an audio effect that performs the function of a multiband audio equalizer. Equalization is used to adjust the balance of frequency compoenents of an audio signal. This process is commonly used in sound production and recording to change the waveform before it reaches a sound output device. EQ can also be used as an audio effect to create interesting distortions by filtering out parts of the spectrum. p5.EQ is built using a chain of Web Audio Biquad Filter Nodes and can be instantiated with 3 or 8 bands. Bands can be added or removed from the EQ by directly modifying p5.EQ.bands (the array that stores filters). ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "returns": "Object: p5.EQ object",
            +    "params": {
            +      "_eqsize": "Number: (Optional) Constructor will accept 3 or 8, defaults to 3"
            +    },
            +    "bands": {
            +      "description": [
            +        "The p5.EQ is built with abstracted p5.Filter objects. To modify any bands, use methods of the <a href=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\"> p5.Filter</a> API, especially <code>gain</code> and <code>freq</code>. Bands are stored in an array, with indices 0 - 3, or 0 - 7"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process an input by connecting it to the EQ"
            +      ],
            +      "params": {
            +        "src": "Object: Audio source"
            +      }
            +    }
            +  },
            +  "p5.Panner3D": {
            +    "description": [
            +      "Panner3D is based on the <a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>. This panner is a spatial processing node that allows audio to be positioned and oriented in 3D space. ",
            +      "The position is relative to an <a title=\"Web Audio Listener docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\"> Audio Context Listener</a>, which can be accessed by <code>p5.soundOut.audiocontext.listener</code>"
            +    ],
            +    "panner": {
            +      "description": [
            +        "<a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a> ",
            +        "Properties include  <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>  : \"equal power\" or \"HRTF\"  <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a> : \"linear\", \"inverse\", or \"exponential\""
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect an audio sorce"
            +      ],
            +      "params": {
            +        "src": "Object: Input source"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "positionX": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionY": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionZ": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orient": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "orientX": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientY": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientZ": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "setFalloff": {
            +      "description": [
            +        "Set the rolloff factor and max distance"
            +      ],
            +      "params": {
            +        "maxDistance": "Number (Optional)",
            +        "rolloffFactor": "Number (Optional)"
            +      }
            +    },
            +    "maxDist": {
            +      "description": [
            +        "Maxium distance between the source and the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "maxDistance": "Number"
            +      }
            +    },
            +    "rollof": {
            +      "description": [
            +        "How quickly the volume is reduced as the source moves away from the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "rolloffFactor": "Number"
            +      }
            +    }
            +  },
            +  "p5.Delay": {
            +    "description": [
            +      "Delay is an echo effect. It processes an existing sound source, and outputs a delayed version of that sound. The p5.Delay can produce different effects depending on the delayTime, feedback, filter, and type. In the example below, a feedback of 0.5 (the default value) will produce a looping delay that decreases in volume by 50% each repeat. A filter will cut out the high frequencies so that the delay does not sound as piercing as the original source. ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "leftDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "rightDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Add delay to an audio signal according to a set of delay parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "delayTime": "Number: (Optional) Time (in seconds) of the delay/echo.  Some browsers limit delayTime to  1 second.",
            +        "feedback": "Number: (Optional) sends the delay back through itself  in a loop that decreases in volume  each time.",
            +        "lowPass": "Number: (Optional) Cutoff frequency. Only frequencies  below the lowPass will be part of the  delay."
            +      }
            +    },
            +    "delayTime": {
            +      "description": [
            +        "Set the delay (echo) time, in seconds. Usually this value will be a floating point number between 0.0 and 1.0."
            +      ],
            +      "params": {
            +        "delayTime": "Number: Time (in seconds) of the delay"
            +      }
            +    },
            +    "feedback": {
            +      "description": [
            +        "Feedback occurs when Delay sends its signal back through its input in a loop. The feedback amount determines how much signal to send each time through the loop. A feedback greater than 1.0 is not desirable because it will increase the overall output each time through the loop, creating an infinite feedback loop. The default value is 0.5"
            +      ],
            +      "returns": "Number: Feedback value",
            +      "params": {
            +        "feedback": "Number|Object: 0.0 to 1.0, or an object such as an  Oscillator that can be used to  modulate this param"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Set a lowpass filter frequency for the delay. A lowpass filter will cut off any frequencies higher than the filter frequency."
            +      ],
            +      "params": {
            +        "cutoffFreq": "Number|Object: A lowpass filter will cut off any  frequencies higher than the filter frequency.",
            +        "res": "Number|Object: Resonance of the filter frequency  cutoff, or an object (i.e. a p5.Oscillator)  that can be used to modulate this parameter.  High numbers (i.e. 15) will produce a resonance,  low numbers (i.e. .2) will produce a slope."
            +      }
            +    },
            +    "setType": {
            +      "description": [
            +        "Choose a preset type of delay. 'pingPong' bounces the signal from the left to the right channel to produce a stereo effect. Any other parameter will revert to the default delay setting."
            +      ],
            +      "params": {
            +        "type": "String|Number: 'pingPong' (1) or 'default' (0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the delay effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Reverb": {
            +    "description": [
            +      "Reverb adds depth to a sound through a large number of decaying echoes. It creates the perception that sound is occurring in a physical space. The p5.Reverb has paramters for Time (how long does the reverb last) and decayRate (how much the sound decays with each echo) that can be set with the .set() or .process() methods. The p5.Convolver extends p5.Reverb allowing you to recreate the sound of actual physical spaces through convolution. ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "process": {
            +      "description": [
            +        "Connect a source to the reverb, and assign reverb parameters."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output.",
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the reverb settings. Similar to .process(), but without assigning a new input."
            +      ],
            +      "params": {
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the reverb effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Convolver": {
            +    "description": [
            +      "p5.Convolver extends p5.Reverb. It can emulate the sound of real physical spaces through a process called <a href=\" https://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\"> convolution</a>.  ",
            +      "Convolution multiplies any audio input by an \"impulse response\" to simulate the dispersion of sound over time. The impulse response is generated from an audio file that you provide. One way to generate an impulse response is to pop a balloon in a reverberant space and record the echo. Convolution can also be used to experiment with sound.  ",
            +      "Use the method <code>createConvolution(path)</code> to instantiate a p5.Convolver with a path to your impulse response audio file."
            +    ],
            +    "params": {
            +      "path": "String: path to a sound file",
            +      "callback": "Function: (Optional) function to call when loading succeeds",
            +      "errorCallback": "Function: (Optional) function to call if loading fails.  This function will receive an error or  XMLHttpRequest object with information  about what went wrong."
            +    },
            +    "convolverNode": {
            +      "description": [
            +        "Internally, the p5.Convolver uses the a <a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\"> Web Audio Convolver Node</a>."
            +      ]
            +    },
            +    "impulses": {
            +      "description": [
            +        "If you load multiple impulse files using the .addImpulse method, they will be stored as Objects in this Array. Toggle between them with the <code>toggleImpulse(id)</code> method."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect a source to the convolver."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "addImpulse": {
            +      "description": [
            +        "Load and assign a new Impulse Response to the p5.Convolver. The impulse is added to the <code>.impulses</code> array. Previous impulses can be accessed with the <code>.toggleImpulse(id)</code> method."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "resetImpulse": {
            +      "description": [
            +        "Similar to .addImpulse, except that the <code>.impulses</code> Array is reset to save memory. A new <code>.impulses</code> array is created with this impulse as the only item."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "toggleImpulse": {
            +      "description": [
            +        "If you have used <code>.addImpulse()</code> to add multiple impulses to a p5.Convolver, then you can use this method to toggle between the items in the <code>.impulses</code> Array. Accepts a parameter to identify which impulse you wish to use, identified either by its original filename (String) or by its position in the <code>.impulses </code> Array (Number).<br/> You can access the objects in the .impulses Array directly. Each Object has two attributes: an <code>.audioBuffer</code> (type: Web Audio <a href=\" http://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\"> AudioBuffer)</a> and a <code>.name</code>, a String that corresponds with the original filename."
            +      ],
            +      "params": {
            +        "id": "String|Number: Identify the impulse by its original filename  (String), or by its position in the  <code>.impulses</code> Array (Number)."
            +      }
            +    }
            +  },
            +  "p5.Phrase": {
            +    "description": [
            +      "A phrase is a pattern of musical events over time, i.e. a series of notes and rests.  ",
            +      "Phrases must be added to a p5.Part for playback, and each part can play multiple phrases at the same time. For example, one Phrase might be a kick drum, another could be a snare, and another could be the bassline.  ",
            +      "The first parameter is a name so that the phrase can be modified or deleted later. The callback is a a function that this phrase will call at every step—for example it might be called <code>playNote(value){}</code>. The array determines which value is passed into the callback at each step of the phrase. It can be numbers, an object with multiple numbers, or a zero (0) indicates a rest so the callback won't be called)."
            +    ],
            +    "params": {
            +      "name": "String: Name so that you can access the Phrase.",
            +      "callback": "Function: The name of a function that this phrase  will call. Typically it will play a sound,  and accept two parameters: a time at which  to play the sound (in seconds from now),  and a value from the sequence array. The  time should be passed into the play() or  start() method to ensure precision.",
            +      "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +    },
            +    "sequence": {
            +      "description": [
            +        "Array of values to pass into the callback at each step of the phrase. Depending on the callback function's requirements, these values may be numbers, strings, or an object with multiple parameters. Zero (0) indicates a rest."
            +      ]
            +    }
            +  },
            +  "p5.Part": {
            +    "description": [
            +      "A p5.Part plays back one or more p5.Phrases. Instantiate a part with steps and tatums. By default, each step represents a 1/16th note.  ",
            +      "See p5.Phrase for more about musical timing."
            +    ],
            +    "params": {
            +      "steps": "Number: (Optional) Steps in the part",
            +      "tatums": "Number: (Optional) Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)"
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo of this part, in Beats Per Minute."
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: (Optional) Seconds from now"
            +      }
            +    },
            +    "getBPM": {
            +      "description": [
            +        "Returns the tempo, in Beats Per Minute, of this part."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of this part. It will play through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of this part. It will begin looping through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Tell the part to stop looping."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the part. Playback will resume from the current step."
            +      ],
            +      "params": {
            +        "time": "Number: seconds from now"
            +      }
            +    },
            +    "addPhrase": {
            +      "description": [
            +        "Add a p5.Phrase to this Part."
            +      ],
            +      "params": {
            +        "phrase": "p5.Phrase: reference to a p5.Phrase"
            +      }
            +    },
            +    "removePhrase": {
            +      "description": [
            +        "Remove a phrase from this part, based on the name it was given when it was created."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "getPhrase": {
            +      "description": [
            +        "Get a phrase from this part, based on the name it was given when it was created. Now you can modify its array."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "replaceSequence": {
            +      "description": [
            +        "Find all sequences with the specified name, and replace their patterns with the specified array."
            +      ],
            +      "params": {
            +        "phraseName": "String",
            +        "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +      }
            +    },
            +    "onStep": {
            +      "description": [
            +        "Set the function that will be called at every step. This will clear the previous function."
            +      ],
            +      "params": {
            +        "callback": "Function: The name of the callback  you want to fire  on every beat/tatum."
            +      }
            +    }
            +  },
            +  "p5.Score": {
            +    "description": [
            +      "A Score consists of a series of Parts. The parts will be played back in order. For example, you could have an A part, a B part, and a C part, and play them back in this order <code>new p5.Score(a, a, b, a, c)</code>"
            +    ],
            +    "params": {
            +      "parts": "p5.Part: (Optional) One or multiple parts, to be played in sequence."
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of the score."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop playback of the score."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause playback of the score."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of the score."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Stop looping playback of the score. If it is currently playing, this will go into effect after the current round of playback completes."
            +      ]
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo for all parts in the score"
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.SoundLoop": {
            +    "description": [
            +      "SoundLoop"
            +    ],
            +    "params": {
            +      "callback": "Function: this function will be called on each iteration of theloop",
            +      "interval": "Number|String: (Optional) amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second."
            +    },
            +    "bpm": {
            +      "description": [
            +        "Getters and Setters, setting any paramter will result in a change in the clock's frequency, that will be reflected after the next callback beats per minute (defaults to 60)"
            +      ]
            +    },
            +    "timeSignature": {
            +      "description": [
            +        "number of quarter notes in a measure (defaults to 4)"
            +      ]
            +    },
            +    "interval": {
            +      "description": [
            +        "length of the loops interval"
            +      ]
            +    },
            +    "iterations": {
            +      "description": [
            +        "how many times the callback has been called so far"
            +      ]
            +    },
            +    "musicalTimeMode": {
            +      "description": [
            +        "musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention true if string, false if number"
            +      ]
            +    },
            +    "maxIterations": {
            +      "description": [
            +        "Set a limit to the number of loops to play. defaults to Infinity"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a starting time"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a stopping time"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a pausing time"
            +      }
            +    },
            +    "syncedStart": {
            +      "description": [
            +        "Synchronize loops. Use this method to start two or more loops in synchronization or to start a loop in synchronization with a loop that is already playing This method will schedule the implicit loop in sync with the explicit master loop i.e. loopToStart.syncedStart(loopToSyncWith)"
            +      ],
            +      "params": {
            +        "otherLoop": "Object: a p5.SoundLoop to sync with",
            +        "timeFromNow": "Number: (Optional) Start the loops in sync after timeFromNow seconds"
            +      }
            +    }
            +  },
            +  "p5.Compressor": {
            +    "description": [
            +      "Compressor is an audio effect class that performs dynamics compression on an audio input source. This is a very commonly used technique in music and sound production. Compression creates an overall louder, richer, and fuller sound by lowering the volume of louds and raising that of softs. Compression can be used to avoid clipping (sound distortion due to peaks in volume) and is especially useful when many sounds are played at once. Compression can be used on indivudal sound sources in addition to the main output. ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "compressor": {
            +      "description": [
            +        "The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"  target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node  </a>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Performs the same function as .connect, but also accepts optional parameters to set compressor's audioParams"
            +      ],
            +      "params": {
            +        "src": "Object: Sound source to be connected",
            +        "attack": "Number: (Optional) The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: (Optional) The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: (Optional) The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the paramters of a compressor."
            +      ],
            +      "params": {
            +        "attack": "Number: The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "attack": {
            +      "description": [
            +        "Get current attack or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "attack": "Number: (Optional) Attack is the amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "knee": {
            +      "description": [
            +        "Get current knee or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "ratio": {
            +      "description": [
            +        "Get current ratio or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "threshold": {
            +      "description": [
            +        "Get current threshold or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "release": {
            +      "description": [
            +        "Get current release or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "reduction": {
            +      "description": [
            +        "Return the current reduction value"
            +      ],
            +      "returns": "Number: Value of the amount of gain reduction that is applied to the signal"
            +    }
            +  },
            +  "p5.PeakDetect": {
            +    "description": [
            +      "PeakDetect works in conjunction with p5.FFT to look for onsets in some or all of the frequency spectrum.  ",
            +      " To use p5.PeakDetect, call <code>update</code> in the draw loop and pass in a p5.FFT object.  ",
            +      " You can listen for a specific part of the frequency spectrum by setting the range between <code>freq1</code> and <code>freq2</code>.   ",
            +      "<code>threshold</code> is the threshold for detecting a peak, scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud as 1.0.  ",
            +      " The update method is meant to be run in the draw loop, and <b>frames</b> determines how many loops must pass before another peak can be detected. For example, if the frameRate() = 60, you could detect the beat of a 120 beat-per-minute song with this equation: <code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>   ",
            +      " Based on example contribtued by @b2renger, and a simple beat detection explanation by <a href=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\" target=\"_blank\">Felix Turner</a>. "
            +    ],
            +    "params": {
            +      "freq1": "Number: (Optional) lowFrequency - defaults to 20Hz",
            +      "freq2": "Number: (Optional) highFrequency - defaults to 20000 Hz",
            +      "threshold": "Number: (Optional) Threshold for detecting a beat between 0 and 1  scaled logarithmically where 0.1 is 1/2 the loudness  of 1.0. Defaults to 0.35.",
            +      "framesPerPeak": "Number: (Optional) Defaults to 20."
            +    },
            +    "isDetected": {
            +      "description": [
            +        "isDetected is set to true when a peak is detected."
            +      ]
            +    },
            +    "update": {
            +      "description": [
            +        "The update method is run in the draw loop. ",
            +        "Accepts an FFT object. You must call .analyze() on the FFT object prior to updating the peakDetect because it relies on a completed FFT analysis."
            +      ],
            +      "params": {
            +        "fftObject": "p5.FFT: A p5.FFT object"
            +      }
            +    },
            +    "onPeak": {
            +      "description": [
            +        "onPeak accepts two arguments: a function to call when a peak is detected. The value of the peak, between 0.0 and 1.0, is passed to the callback."
            +      ],
            +      "params": {
            +        "callback": "Function: Name of a function that will  be called when a peak is  detected.",
            +        "val": "Object: (Optional) Optional value to pass  into the function when  a peak is detected."
            +      }
            +    }
            +  },
            +  "p5.SoundRecorder": {
            +    "description": [
            +      "Record sounds for playback and/or to save as a .wav file. The p5.SoundRecorder records all sound output from your sketch, or can be assigned a specific source with setInput(). ",
            +      "The record() method accepts a p5.SoundFile as a parameter. When playback is stopped (either after the given amount of time, or with the stop() method), the p5.SoundRecorder will send its recording to that p5.SoundFile for playback."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a specific device to the p5.SoundRecorder. If no parameter is given, p5.SoundRecorer will record all audible p5.sound from your sketch."
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) p5.sound object or a web audio unit  that outputs sound"
            +      }
            +    },
            +    "record": {
            +      "description": [
            +        "Start recording. To access the recording, provide a p5.SoundFile as the first parameter. The p5.SoundRecorder will send its recording to that p5.SoundFile for playback once recording is complete. Optional parameters include duration (in seconds) of the recording, and a callback function that will be called once the complete recording has been transfered to the p5.SoundFile."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile",
            +        "duration": "Number: (Optional) Time (in seconds)",
            +        "callback": "Function: (Optional) The name of a function that will be  called once the recording completes"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the recording. Once the recording is stopped, the results will be sent to the p5.SoundFile that was given on .record(), and if a callback function was provided on record, that function will be called."
            +      ]
            +    }
            +  },
            +  "p5.Distortion": {
            +    "description": [
            +      "A Distortion effect created with a Waveshaper Node, with an approach adapted from <a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a> ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +      "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +    },
            +    "WaveShaperNode": {
            +      "description": [
            +        "The p5.Distortion is built with a <a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\"> Web Audio WaveShaper Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process a sound source, optionally specify amount and oversample values."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the amount and oversample of the waveshaper distortion."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "getAmount": {
            +      "description": [
            +        "Return the distortion amount, typically between 0-1."
            +      ],
            +      "returns": "Number: Unbounded distortion amount.  Normal values range from 0-1."
            +    },
            +    "getOversample": {
            +      "description": [
            +        "Return the oversampling."
            +      ],
            +      "returns": "String: Oversample can either be 'none', '2x', or '4x'."
            +    }
            +  },
            +  "p5.Gain": {
            +    "description": [
            +      "A gain node is usefull to set the relative volume of sound. It's typically used to build mixers."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a source to the gain node."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the gain node."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    }
            +  },
            +  "p5.AudioVoice": {
            +    "description": [
            +      "Base class for monophonic synthesizers. Any extensions of this class should follow the API and implement the methods below in order to remain compatible with p5.PolySynth();"
            +    ],
            +    "connect": {
            +      "description": [
            +        "Connect to p5 objects or Web Audio Nodes"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect from soundOut"
            +      ]
            +    }
            +  },
            +  "p5.MonoSynth": {
            +    "description": [
            +      "A MonoSynth is used as a single voice for sound synthesis. This is a class to be used in conjunction with the PolySynth class. Custom synthetisers should be built inheriting from this class."
            +    ],
            +    "attack": {
            +      "description": [
            +        "Getters and Setters"
            +      ]
            +    },
            +    "decay": {},
            +    "sustain": {},
            +    "release": {},
            +    "play": {
            +      "description": [
            +        "Play tells the MonoSynth to start playing a note. This method schedules the calling of .triggerAttack and .triggerRelease."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope. Defaults to 0.15 seconds."
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "MonoSynth amp"
            +      ],
            +      "returns": "Number: new volume value",
            +      "params": {
            +        "vol": "Number: desired volume",
            +        "rampTime": "Number: (Optional) Time to reach new volume"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  },
            +  "p5.OnsetDetect": {
            +    "description": [
            +      "Listen for onsets (a sharp increase in volume) within a given frequency range."
            +    ],
            +    "params": {
            +      "freqLow": "Number: Low frequency",
            +      "freqHigh": "Number: High frequency",
            +      "threshold": "Number: Amplitude threshold between 0 (no energy) and 1 (maximum)",
            +      "callback": "Function: Function to call when an onset is detected"
            +    }
            +  },
            +  "p5.PolySynth": {
            +    "description": [
            +      "An AudioVoice is used as a single voice for sound synthesis. The PolySynth class holds an array of AudioVoice, and deals with voices allocations, with setting notes to be played, and parameters to be set."
            +    ],
            +    "params": {
            +      "synthVoice": "Number: (Optional) A monophonic synth voice inheriting  the AudioVoice class. Defaults to p5.MonoSynth",
            +      "maxVoices": "Number: (Optional) Number of voices, defaults to 8;"
            +    },
            +    "notes": {
            +      "description": [
            +        "An object that holds information about which notes have been played and which notes are currently being played. New notes are added as keys on the fly. While a note has been attacked, but not released, the value of the key is the audiovoice which is generating that note. When notes are released, the value of the key becomes undefined."
            +      ]
            +    },
            +    "polyvalue": {
            +      "description": [
            +        "A PolySynth must have at least 1 voice, defaults to 8"
            +      ]
            +    },
            +    "AudioVoice": {
            +      "description": [
            +        "Monosynth that generates the sound for each note that is triggered. The p5.PolySynth defaults to using the p5.MonoSynth as its voice."
            +      ]
            +    },
            +    "play": {
            +      "description": [
            +        "Play a note by triggering noteAttack and noteRelease with sustain time"
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note to play (ranging from 0 to 127 - 60 being a middle C)",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "noteADSR": {
            +      "description": [
            +        "noteADSR sets the envelope for a specific note that has just been triggered. Using this method modifies the envelope of whichever audiovoice is being used to play the desired note. The envelope should be reset before noteRelease is called in order to prevent the modified envelope from being used on other notes."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) Midi note on which ADSR should be set.",
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set the PolySynths global envelope. This method modifies the envelopes of each monosynth so that all notes are played with this envelope."
            +      ],
            +      "params": {
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "noteAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of a MonoSynth. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)/",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds)"
            +      }
            +    },
            +    "noteRelease": {
            +      "description": [
            +        "Trigger the Release of an AudioVoice note. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.  If no value is provided, all notes will be released.",
            +        "secondsFromNow": "Number: (Optional) time to trigger the release"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/reference/ko.json b/dist/assets/reference/ko.json
            new file mode 100644
            index 0000000000..94891022e4
            --- /dev/null
            +++ b/dist/assets/reference/ko.json
            @@ -0,0 +1,7674 @@
            +{
            +  "h1": "레퍼런스",
            +  "reference-search": "API 검색",
            +  "reference-description1": "찾는 항목이 없다면, 다음의 페이지를 살펴보세요:",
            +  "reference-description3": "오프라인 버전 다운로드",
            +  "reference-contribute2": "여기로 알려주세요.",
            +  "reference-error1": "오타나 버그를 발견했다면",
            +  "reference-error3": "p5.js에 기여하고 싶다면, ",
            +  "reference-error5": "에 풀 요청(pull request) 해주세요!",
            +  "reference-example": "예제",
            +  "reference-description": "설명",
            +  "reference-extends": "확장",
            +  "reference-parameters": "매개변수",
            +  "reference-syntax": "문법",
            +  "reference-returns": "반환값",
            +  "Environment": "환경",
            +  "Color": "색상",
            +  "Color Conversion": "색상 변환",
            +  "Creating & Reading": "창조 & 속성추출",
            +  "Setting": "설정",
            +  "Shape": "도형",
            +  "2D Primitives": "2D 기초 조형",
            +  "Attributes": "도형 속성",
            +  "Curves": "곡선",
            +  "Vertex": "정점 (Vertex)",
            +  "Constants": "상수",
            +  "Structure": "구조",
            +  "DOM": "문서 객체 모델 (DOM)",
            +  "Rendering": "렌더링",
            +  "Foundation": "기초",
            +  "Transform": "좌표계 변환",
            +  "Data": "데이터",
            +  "LocalStorage": "LocalStorage",
            +  "Dictionary": "사전",
            +  "Events": "이벤트 인식",
            +  "Acceleration": "가속도",
            +  "Keyboard": "키보드",
            +  "Mouse": "마우스",
            +  "Touch": "터치",
            +  "Image": "이미지",
            +  "Loading & Displaying": "불러오기 & 보이기",
            +  "Pixels": "픽셀",
            +  "IO": "입력 & 출력",
            +  "Input": "입력",
            +  "Output": "출력",
            +  "Table": "테이블",
            +  "Math": "수학",
            +  "Calculation": "계산",
            +  "Vector": "벡터",
            +  "Noise": "노이즈",
            +  "Random": "랜덤",
            +  "Trigonometry": "삼각법",
            +  "Typography": "타이포그래피",
            +  "Array Functions": "배열 기능",
            +  "Conversion": "변환",
            +  "String Functions": "문자열 기능",
            +  "Time & Date": "날짜 & 시간",
            +  "3D Primitives": "3D 기초 조형",
            +  "Lights, Camera": "조명, 카메라",
            +  "Interaction": "인터랙션",
            +  "Lights": "조명",
            +  "3D Models": "3D 모델",
            +  "Material": "재질(Material)",
            +  "Camera": "카메라",
            +  "p5": {
            +    "description": [
            +      "p5 인스턴스 생성자 입니다.",
            +      "p5 인스턴스는 p5 스케치와 관련된 모든 속성과 메소드(method)를 보유합니다. 도래할 스케치 클로저(closure)를 예상하고, 생성된 p5 캔버스를 노드에 연결하기 위해 선택적으로 노드 매개변수를 취할 수 있습니다. 스케치 클로저는 새로이 생성된 p5 인스턴스를 유일한 인수로 취하며, 또 선택적으로, 스케치 실행을 위해 <a href=\"#/p5/preload\">preload()</a>, <a href=\"#/p5/setup\">setup()</a>, 그리고/또는 <a href=\"#/p5/draw\">draw()</a> 속성을 담을 수 있습니다.",
            +      "p5 스케치는 \"전역\" 또는 \"인스턴스\" 모드에서 실행됩니다: \"전역 모드\" - 모든 속성과 메소드가 윈도우에 속함 \"인스턴스 모드\" - 모든 속성과 메소드가 특정 p5 객체에 구속됨"
            +    ],
            +    "returns": "P5: p5 인스턴스",
            +    "params": {
            +      "sketch": "함수: 주어진 p5 인스턴스에 선택적으로 <a href=\"#/p5/preload\">preload()</a>, <a href=\"#/p5/setup\">setup()</a>, 그리고/또는 <a href=\"#/p5/draw\">draw()</a> 속성을 설정할 수 있는 클로저",
            +      "node": "HTML Element: (선택 사항) 캔버스에 속할 요소"
            +    },
            +    "describe": {
            +      "description": [
            +        "스크린리더 (Screen Reader)를 위한 캔버스의 전체적인 서술적 묘사를 설정합니다. 첫 번째 매개변수는 문자열이며, 설정할 묘사입니다. 두 번째 매개변수는 선택 사항이며, 묘사의 표시법을 지정합니다.",
            +        "<code class=\"language-javascript\">describe(text, LABEL)</code>은 설명을 모든 사용자에게 <a href=\"https://ko.vvikipedia.org/wiki/Museum_label\" target=\"_blank\"> 박물관 라벨/캡션</a>을 캔버스 옆 <code class=\"language-javascript\"><div class=\"p5Label\"></div></code> 칸 안에 나타냅니다. CSS를 통해서 스타일을 자유자재로 바꿀 수 있습니다.",
            +        "<code class=\"language-javascript\">describe(text, FALLBACK)</code>는 설정된 묘사를 스크린리더 사용자들에게만 이용가능케 하며, <a href=\"https://developer.mozilla.org/ko/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">캔버스의 부가적 문서객체모델 (DOM)</a>에 설정됩니다. 두번 째 매개변수가 없을 시, 기본적으로 묘사는 스크린리더 사용자들에게만 이용가능합니다."
            +      ],
            +      "params": {
            +        "text": "문자열: 켄버스의 설명",
            +        "display": "상수: (선택 사항) LABEL 또는 FALLBACK"
            +      }
            +    },
            +    "describeElement": {
            +      "description": [
            +        "스크린리더 (Screen Reader)를 위한 캔버스의 요소(도형, 또는 도형의 모임)의 서술적 묘사를 설정합니다. 첫 번째 매개변수는 묘사할 요소의 이름입니다. 두 번째 매개변수는 문자열이며 설정할 묘사입니다. 세 번째 매개변수는 선택 사항이며, 묘사의 표시법을 지정합니다.",
            +        "<code class=\"language-javascript\">describe(text, LABEL)</code>은 설명을 모든 사용자에게 <a href=\"https://ko.vvikipedia.org/wiki/Museum_label\" target=\"_blank\"> 박물관 라벨/캡션</a>을 캔버스 옆 <code class=\"language-javascript\"> <div class=\"p5Label\"></div> </code> 칸 안에 나타냅니다. CSS를 통해서 스타일을 자유자재로 바꿀 수 있습니다.",
            +        "<code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>는 설정된 묘사를 스크린리더 사용자들에게만 이용가능케 하며, <a href=\"https://developer.mozilla.org/ko/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">캔버스의 부가적 문서객체모델 (DOM)</a>에 설정됩니다. 두번 째 매개변수가 없을 시, 기본적으로 묘사는 스크린리더 사용자들에게만 이용가능합니다."
            +      ],
            +      "params": {
            +        "name": "문자열: 요소의 이름",
            +        "text": "문자열: 요소의 설명 및 묘사",
            +        "display": "상수: (선택 사항) LABEL 또는 FALLBACK"
            +      }
            +    },
            +    "textOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">textOutput()</code> 함수는 스크린리더 (Screen Reader)를 위한 도형의 설명을 출력합니다. 이 설명은 자동적으로 만들어지며, 첫 부분은 캔버스의 높이 및 너비, 배경색, 그리고 캔버스상 요소 (도형, 또는 도형의 모임)의 개수를 출력합니다 (예: 'Your output is a, 400 by 400 pixels, lavender blue canvas containing the following 4 shapes:'). 다음은 각 요소의 색, 위치, 넓이 등의 정보를 출력합니다 (예: \"orange ellipse at top left covering 1% of the canvas\"). 각 요소에 대한 구체적 정보는 선택해서 볼 수 있습니다. 요소들의 목록이 제공됩니다. 이 목록에는 도형, 색, 위치, 좌표와 넓이가 묘사되어 있습니다 (예: \"orange ellipse location=top left area=2\").",
            +        "<code class=\"language-javascript\">textOutput()</code>과 <code class=\"language-javascript\">texOutput(FALLBACK)</code>은 출력물을 스크린리더 (Screen Reader)에 사용되는 <a href=\"https://developer.mozilla.org/ko/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> 캔버스의 부가적 문서객체모델 (DOM)</a>에 제공합니다. <code class=\"language-javascript\">textOutput(LABEL)</code>은 캔버스 옆 추가적인 div요소를 만들고 그 안에 설명을 출력합니다. 이는 스크린리더를 사용하지 않지만 코딩하는 동안 출력물을 보면서 하고 싶어하는 유저들에게 유용합니다. 하지만 LABEL을 사용할 시 스크린리더 사용자들에게는 의미없는 중복성을 만들 수 있습니다. 그 이유로 LABEL은 스케치를 만드는 동안에만 사용하고 스케치를 출판하거나 스크린리더 사용자들에게 나누기 전에 지우는 것을 권장합니다."
            +      ],
            +      "params": {
            +        "display": "상수: (선택 사항) FALLBACK 또는 LABEL"
            +      }
            +    },
            +    "gridOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">gridOutput()</code>은 캔버스의 내용물을 위치적에 따라 격자 (grid) 형식으로 나열합니다. 이 테이블을 출력하기 전에 컨버스의 전반적 설명을 출력합니다. 캔버스의 높이 및 너비, 배경색, 그리고 캔버스상 요소 (도형, 또는 도형의 모임)의 개수를 출력합니다 (예: 'Your output is a, 400 by 400 pixels, lavender blue canvas containing the following 4 shapes:'). 그리드는 내용물을 위치적으로 설명하며, 각 요소는 위치의 격자 위 셀 (cell)에 놓입니다. 각 셀에는 특정 요소의 색상과 모양이 저장되어 있습니다 (예: \"orange ellipse\"). 각 요소에 대한 구체적 정보는 선택해서 볼 수 있습니다. 각 요소의 모양, 색, 위치, 넓이 등의 정보가 표기되어 있는 목록 (예: \"orange ellipse location=top left area=1%\")도 사용 가능합니다.",
            +        "<code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>은 출력물을 스크린리더 (Screen Reader)에 사용되는 <a href=\"https://developer.mozilla.org/ko/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> 캔버스의 부가적 문서객체모델 (DOM)</a>에 제공합니다. <code class=\"language-javascript\">gridOutput(LABEL)</code>은 캔버스 옆 추가적인 div요소를 만들고 그 안에 설명을 출력합니다. 이는 스크린리더를 사용하지 않지만 코딩하는 동안 출력물을 보면서 하고 싶어하는 유저들에게 유용합니다. 하지만 LABEL을 사용할 시 스크린리더 사용자들에게는 의미없는 중복성을 만들 수 있습니다. 그 이유로 LABEL은 스케치를 만드는 동안에만 사용하고 스케치를 출판하거나 스크린리더 사용자들에게 나누기 전에 지우는 것을 권장합니다."
            +      ],
            +      "params": {
            +        "display": "상수: (선택 사항) FALLBACK 또는 LABEL"
            +      }
            +    },
            +    "alpha": {
            +      "description": [
            +        "픽셀 배열로부터 알파값을 추출합니다."
            +      ],
            +      "returns": "알파값",
            +      "params": {
            +        "color": "p5.Color|숫자 배열[]| 문자열: p5.Color 객체, 색상 요소 또는 CSS 색상"
            +      }
            +    },
            +    "blue": {
            +      "description": [
            +        "색상 또는 픽셀 배열로부터 파랑값을 추출합니다."
            +      ],
            +      "returns": "파랑값",
            +      "params": {
            +        "color": "p5.Color 객체, 색상 요소, CSS 색상"
            +      }
            +    },
            +    "brightness": {
            +      "description": [
            +        "색상 또는 픽셀 배열로부터 HSB 밝기값을 추출합니다."
            +      ],
            +      "returns": "밝기값",
            +      "params": {
            +        "color": "p5.Color 객체, 색상 요소, CSS 색상"
            +      }
            +    },
            +    "color": {
            +      "description": [
            +        "색상 함수를 이용해 색상 데이터의 매개변수를 저장합니다. 이 때, 매개변수는 colorMode()의 설정에 따라 RGB 또는 HSB 값으로 처리됩니다. 기본 모드인 RGB값은 0부터 255까지이며, 따라서 color(255,204,0)와 같은 함수는 밝은 노랑색을 반환하게 됩니다.",
            +        "만약에 color() 함수에 매개변수가 1개만 적히면, 회색 음영(grayscale)값으로 처리됩니다. 여기에 추가되는 두번째 변수는 투명도를 설정할 수 있는 알파값으로서 처리됩니다. 세번째 변수가 추가되었을 때 비로소 RGB나 HSB값으로 처리됩니다. RGB나 HSB값을 정하는 3개의 변수가 존재할 때 추가되는 네번째 변수는 알파값으로 적용됩니다.",
            +        "나아가, p5는 RGB, RGBA, Hex CSS 색상 문자열과 모든 색상명 문자열 역시 지원합니다. 그 경우, 알파값은 괄호 내 2번째 매개변수 추가를 통해서가 아닌, RGBA 형식에 따라 지정될 수 있습니다."
            +      ],
            +      "returns": "색상 결과",
            +      "params": {
            +        "gray": "숫자: 흑과 백 사이의 값 지정",
            +        "alpha": "숫자: 현재 색상 범위(기본값: 0-255)에 대한 알파값",
            +        "v1": "숫자: 현재 색상 범위 내 빨강색(R) 또는 색조값 지정",
            +        "v2": "숫자: green or saturation value  relative to the current color range",
            +        "v3": "숫자: 현재 색상 범위 내 파랑색(B) 또는 색조값 지정",
            +        "value": "문자열: 색상 문자열",
            +        "values": "숫자 배열[]: RGB 및 알파값을 포함한 숫자 배열",
            +        "color": "p5.Color"
            +      }
            +    },
            +    "green": {
            +      "description": [
            +        "색상 또는 픽셀 배열로부터 초록값을 추출합니다."
            +      ],
            +      "returns": "초록값",
            +      "params": {
            +        "color": "p5.Color 객체, 색상 요소, CSS 색상"
            +      }
            +    },
            +    "hue": {
            +      "description": [
            +        "색상 또는 픽셀 배열로부터 색조를 추출합니다.",
            +        "색조는 HSB와 HSL상 모두 존재합니다. 이 함수는 HSB 색상 객체를 사용할 경우(또는 HSB 색상 모드로 지정된 픽셀 배열을 사용할 경우) HSB로 표준화된 색조 값을 반환합니다. 기본값으로는 HSL로 표준화된 색조를 반환합니다. (단, 최대 색조를 별도 지정한 경우 다른 값을 반환합니다.)"
            +      ],
            +      "returns": "색조",
            +      "params": {
            +        "color": "객체, 색상 요소 또는 CSS 색상"
            +      }
            +    },
            +    "lerpColor": {
            +      "description": [
            +        "두 가지 색상을 혼합하고, 그 사이에 존재하는 제 3의 색상을 찾습니다. 여기서 매개변수 amt는 두 개의 값 사이를 선형적으로 보간합니다. 예를 들어, 0.0은 첫 번째 값과 동일한 색상값을, 0.1은 첫 번째 값에 매우 가까운 색상값을, 0.5는 두 값 사이의 중간 색상값을 나타내는 식입니다. 이 때, 0 미만의 값은 0으로, 1이상의 값은 1로 자동 변환됩니다. 이 점에서 lerpColor()는 lerp()와 다르게 작동하는 셈인데, 이처럼 lerpColor()는 색상값을 0과 1사이로 조정하여 지정된 범위를 벗어난 색상 생성을 방지합니다.",
            +        "색상이 보간되는 방식은 현재 지정된 색상 모드에 따라 달라집니다."
            +      ],
            +      "returns": "p5.Color: 선형적으로 보간된 색상",
            +      "params": {
            +        "c1": "이 색상으로부터 선형 보간",
            +        "c2": "이 색상을 향해 선형 보간",
            +        "amt": "숫자: 0과 1 사이의 숫자"
            +      }
            +    },
            +    "lightness": {
            +      "description": [
            +        "색상 또는 픽셀 배열로부터 HSL 명도를 추출합니다."
            +      ],
            +      "returns": "숫자: 명도",
            +      "params": {
            +        "color": "p5.Color|숫자 배열[]|문자열: p5.Color 객체, 색상 요소 또는 CSS 색상"
            +      }
            +    },
            +    "red": {
            +      "description": [
            +        "색상 또는 픽셀 배열로부터 빨강값을 추출합니다."
            +      ],
            +      "returns": "숫자: 빨강값",
            +      "params": {
            +        "color": "p5.Color|숫자 배열[]|문자열: p5.Color 객체, 색상 요소 또는 CSS 색상"
            +      }
            +    },
            +    "saturation": {
            +      "description": [
            +        "색상 또는 픽셀 배열로부터 채도값을 추출합니다. 채도값은 HSB와 HSL에서 각각 다르게 측정됩니다. 이 함수는 HSL 채도를 기본값으로 제공합니다. 하지만, HSB 색상 객체가 제공 될 때 (또는 색상 모드가 HSB이면서 픽셀 배열이 제공될 때) HSB 채도값을 반환합니다.",
            +        "Saturation is scaled differently in HSB and HSL. This function will return the HSB saturation when supplied with an HSB color object (or when supplied with a pixel array while the color mode is HSB), but will default to the HSL saturation otherwise."
            +      ],
            +      "returns": "숫자: 채도값",
            +      "params": {
            +        "color": "p5.Color|숫자 배열[]|문자열: p5.Color 객체, 색상 요소 또는 CSS 색상"
            +      }
            +    },
            +    "background": {
            +      "description": [
            +        "background() 함수는 p5.js 캔버스의 배경색을 설정합니다. 배경색의 기본값은 투명입니다. 이 함수는 주로 <a href=\"#/p5/draw\">draw()</a> 함수 안에 위치하며, 매 프레임마다 캔버스 화면을 초기화하기 위해 사용됩니다. 하지만, 애니메이션의 첫 프레임 배경을 지정하거나 배경색을 최초 한번만 지정할 경우, <a href=\"#/p5/setup\">setup()</a> 함수 안에 쓰이기도 합니다.",
            +        "색상은 현재 색상 모드(colorMode)에 따라 RGB, HSB, 또는 HSL값으로 지정됩니다. (기본값으로 제공되는 색상 모드는 RGB이고, 그 색상 범위는 0부터 255까지 해당합니다.) 알파값의 기본 제공 범위 역시 0부터 255까지입니다.",
            +        "단일한 문자열 인수에 대해 RGB, RGBA, Hex CSS 색상 문자열과 더불어 명명된 모든 색상 문자열이 지원됩니다. 단, 투명도인 알파값을 설정하기 위해서는 반드시 RGBA를 사용해야 합니다.",
            +        "<a href=\"#/p5.Color\">p5.Color</a> 객체를 통해 배경색을 설정할 수 있습니다.",
            +        "<a href=\"#/p5.Image\">p5.Image</a>를 통해 배경 이미지를 설정할 수 있습니다."
            +      ],
            +      "params": {
            +        "color": "p5.Color: color() 함수로 생성된 모든 값",
            +        "colorstring": "문자열, 지원되는 문자열 형식: 색상 문자열, 정수의 rgb()나 rgba(), 백분율의 rgb()나 rgba(), 3자리 숫자의 hex, 6자리 숫자의 hex",
            +        "a": "숫자: (선택 사항) 현재 색상 범위에 따른 배경색 투명도 (기본값은 0-255)",
            +        "gray": "숫자: 흑과 백 사이의 값 지정",
            +        "v1": "숫자: 빨강값 또는 색조값 (현재 색상 모드에 따라 상이)",
            +        "v2": "숫자: 초록값 또는 채도값 (현재 색상 모드에 따라 상이)",
            +        "v3": "숫자: 파랑값 또는 밝기값 (현재 색상 모드에 따라 상이)",
            +        "values": "숫자 배열[]: 빨강값, 초록값, 파랑값, 알파값을 포함한 배열",
            +        "image": "p5.Image: loadImage()나 createImage()로 생성된 이미지를 배경 이미지로 설정하는 경우 (스케치 화면과 반드시 동일한 사이즈일 것)"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "버퍼에 있는 픽셀들을 지우는 함수로, 오직 캔버스만 비게 됩니다. createVideo()나 createDiv()와 같은, createX()류의 메소드로 지정된 객체들을 제거하진 않습니다. 메인 그래픽이 아닌, createGraphics()로 생성된 부가적인 그래픽의 경우, 그 전체 또는 일부를 투명하게 처리할 수 있습니다. 이 함수는 모든 픽셀을 100% 투명하게 만듭니다."
            +      ]
            +    },
            +    "colorMode": {
            +      "description": [
            +        "colorMode()는 p5.js가 색상 데이터를 해석하는 방식을 결정합니다. 기본값으로, fill(), stroke(), background(), color()의 매개변수는 RGB 색상 모드에서 처리되며, 그 범위는 0부터 255까지입니다. 이 기본값은 colorMode(RGB, 255)와 동일한 효과를 지닙니다. colorMode(HSB)로 설정을 변경하면 HSB 색상 시스템을 사용할 수 있습니다. HSB 색상 시스템은 그 기본값으로 colorMode(HSB, 360, 100, 100, 1)와 같이 설정됩니다. 색상 모드는 HSL로도 설정가능합니다.",
            +        "참고: 모든 색상 객체들은 생성 당시에 지정된 색상 모드를 반영합니다. 따라서, 이미 생성된 색상 객체 중 일부에만 적용되는 색상 모드를 지정할 수도 있습니다."
            +      ],
            +      "params": {
            +        "mode": "상수: RGB(빨강Red/초록Green/파랑색Blue), HSB(색조Hue/채도Saturation/밝기Brightness), HSL(색조Hue/채도Saturation/명도Lightness) 중 하나",
            +        "max": "숫자: (선택 사항) 모든 값들의 범위",
            +        "max1": "숫자: (선택 사항) 모든 값들의 범위",
            +        "max2": "숫자: 현재 지정된 색상 모드의 색상 범위에 따른 빨강값 또는 색조값",
            +        "max3": "숫자: 현재 지정된 색상 모드의 색상 범위에 따른 초록값 또는 채도값",
            +        "maxA": "숫자: (선택 사항) 알파값의 범위"
            +      }
            +    },
            +    "fill": {
            +      "description": [
            +        "도형의 면을 채울 색상을 지정합니다. 예를 들어, fill(204, 102, 0) 함수를 실행하면, 이 명령어 다음에 그려진 모든 도형들이 주황색으로 칠해집니다. 이 때, 색상값은 colorMode()로 지정된 현재의 색상 모드에 따라 RGB 또는 HSB로 지정됩니다. (기본값으로 제공되는 색상 모드는 RGB이고, 그 색상 범위는 0부터 255까지 해당합니다.) 알파값의 기본 제공 범위 역시 0부터 255까지입니다.",
            +        "단일한 문자열 인수에 대해 RGB, RGBA, Hex CSS 색상 문자열과 더불어 명명된 모든 색상 문자열이 지원됩니다. 단, 투명도인 알파값을 설정하기 위해서는 반드시 RGBA를 사용해야 합니다.",
            +        "<a href=\"#/p5.Color\">Color</a> 객체로도 색상을 지정할 수 있습니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: 현재 지정된 색상 모드의 색상 범위에 따른 빨강값 또는 색조값",
            +        "v2": "숫자: 현재 지정된 색상 모드의 색상 범위에 따른 초록값 또는 채도값",
            +        "v3": "숫자:현재 지정된 색상 모드의 색상 범위에 따른 파랑값 또는 밝기값",
            +        "alpha": "숫자: (선택사항)",
            +        "value": "문자열: 색상 문자열",
            +        "gray": "숫자: 회색값",
            +        "values": "숫자 배열[]: 색상의 빨강값, 초록값, 파랑값, 그리고 알파값을 포함한 배열",
            +        "color": "p5.Color: 면채우기 색상"
            +      }
            +    },
            +    "noFill": {
            +      "description": [
            +        "도형에 색을 채우지 않도록 설정합니다. noStroke()과 noFill()을 동시에 사용하면, 화면에 아무것도 나타나지 않습니다."
            +      ]
            +    },
            +    "noStroke": {
            +      "description": [
            +        "선이나 윤곽선을 그리지 않도록 설정합니다. noStroke()과 noFill()을 동시에 사용하면, 화면에 아무것도 나타나지 않습니다."
            +      ]
            +    },
            +    "stroke": {
            +      "description": [
            +        "그려질 선 또는 도형 윤곽선의 색상을 설정합니다. 이 때, 색상값은 colorMode()로 지정된 현재의 색상 모드에 따라 RGB 또는 HSB로 지정됩니다. (기본값으로 제공되는 색상 모드는 RGB이고, 그 색상 범위는 0부터 255까지 해당합니다.)",
            +        "단일한 문자열 인수에 대해 RGB, RGBA, Hex CSS 색상 문자열과 더불어 명명된 모든 색상 문자열이 지원됩니다. 단, 투명도인 알파값을 설정하기 위해서는 반드시 RGBA를 사용해야 합니다.",
            +        "p5.Color 객체를 통해 선의 색상을 설정할 수 있습니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: 현재 지정된 색상 모드의 색상 범위에 따른 빨강값 또는 색조값",
            +        "v2": "숫자: 현재 지정된 색상 모드의 색상 범위에 따른 초록값 또는 채도값",
            +        "v3": "숫자:현재 지정된 색상 모드의 색상 범위에 따른 파랑값 또는 밝기값",
            +        "alpha": "숫자: (선택사항)",
            +        "value": "문자열: 색상 문자열",
            +        "gray": "숫자: 회색값",
            +        "values": "숫자 배열[]: 색상의 빨강값, 초록값, 파랑값, 그리고 알파값을 포함한 배열",
            +        "color": "p5.Color: 선의 색상"
            +      }
            +    },
            +    "erase": {
            +      "description": [
            +        "<a href=\"#/p5/erase\">erase()</a> 함수의 영향을 받는 모든 드로잉을 캔버스로부터 지웁니다. 지워진 영역은 캔버스 이면의 웹 페이지 화면을 드러냅니다. 이러한 지우기 행위는 <a href=\"#/p5/noErase\">noErase()</a>로 취소할 수 있습니다.",
            +        "<a href=\"#/p5/erase\">erase()</a> 함수와 <a href=\"#/p5/noErase\">noErase()</a> 함수 사이에서 <a href=\"#/p5/image\">image()</a>나 <a href=\"#/p5/background\">background()</a>로 그려진 드로잉은 캔버스에서 지워지지 않습니다."
            +      ],
            +      "params": {
            +        "strengthFill": "숫자: (선택 사항) 도형의 면을 지우는 강도로서의 (0부터 255사이) 숫자. 별도 지정한 숫자가 없는 경우, 최고 강도인 255가 기본값으로 적용",
            +        "strengthStroke": "숫자: (선택 사항) 도형의 테두리를 지우는 강도로서의 (0부터 255사이) 숫자. 별도 지정한 숫자가 없는 경우, 최고 강도인 255가 기본값으로 적용"
            +      }
            +    },
            +    "noErase": {
            +      "description": [
            +        "<a href=\"#/p5/erase\">erase()</a>의 지우기 행위를 중단합니다. <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, 그리고 <a href=\"#/p5/blendMode\">blendMode()</a> 함수로 설정된 사항들은 <a href=\"#/p5/erase\">erase()</a> 함수가 호출되기 전의 상태로 돌아갑니다."
            +      ]
            +    },
            +    "arc": {
            +      "description": [
            +        "화면에 호, 즉 아치형 선을 그립니다. x좌표, y좌표, w(너비), h(높이), 시작점, 끝점을 지정하면 호는 열린 파이 조각의 형태로 그려집니다. 모드 변수를 설정하기에 따라, 호는 각각 반원(OPEN), 닫힌 반원(CHORD), 닫힌 파이 조각(PIE) 형태로 그려집니다. <a href=\"#/p5/ellipseMode\">ellipseMode()</a> 함수를 이용하면 시작점을 변경할 수 있습니다.",
            +        "호는 언제나 시계방향으로 시작점으로부터 끝점까지 그려집니다. 만약 원 하나를 그리기 위해 arc()의 시작점을 0으로, 끝점을 TWO_PI으로 설정할 경우, 시작점과 끝점이 동일하여 아무것도 그려지지 않습니다. 원을 그릴 때는 <a href=\"#/p5/ellipse\">ellipse()</a> 함수를, 원의 일부를 그릴 때는 arc() 함수를 이용할 수 있습니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 호를 포함하는 원의 x좌표",
            +        "y": "숫자: 호를 포함하는 원의 y좌표값",
            +        "w": "숫자: 호를 포함하는 원의 너비값",
            +        "h": "숫자: 호를 포함하는 원의 높이값",
            +        "start": "숫자: 라디안 단위, 호의 시작점 각도값",
            +        "stop": "숫자: 라디안 단위, 호의 끝점 각도값",
            +        "mode": "상수: (선택 사항) 호를 그리는 방식들로, CHORD, PIEC, OPEN 중 선택 가능",
            +        "detail": "숫자: (선택 사항) 호의 윤곽선을 구성하는 꼭짓점 개수를 지정. 기본값은 25. (WebGL 모드용)"
            +      }
            +    },
            +    "ellipse": {
            +      "description": [
            +        "화면에 타원을 그립니다. 너비와 높이가 동일한 값으로 지정될 경우, 원이 그려집니다. 처음 두 변수는 각각 타원의 x좌표와 y좌표를, 3번째와 4번째 변수는 각각 타원의 너비와 높이를 지정합니다. 높이값 입력을 생략할 경우, 너비값이 높이값으로 동일하게 적용됩니다. 너비나 높이에 음수로 입력해도 그 절대값이 반영됩니다.",
            +        "<a href=\"#/p5/ellipseMode\">ellipseMode()</a> 함수를 이용하면 타원의 시작점을 원의 중심으로 지정할 지의 여부를 결정할 수 있습니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 타원의 x좌표",
            +        "y": "숫자: 타원의 y좌표값",
            +        "w": "숫자: 타원의 너비값",
            +        "h": "숫자: (선택사항) 타원의 높이값",
            +        "detail": "정수: (선택사항) 타원을 몇 개의 부분으로 나누어 그릴 것인지 지정 (WebGL 모드용)"
            +      }
            +    },
            +    "circle": {
            +      "description": [
            +        "화면에 원을 그립니다. 원은 닫힌 도형으로, 중심점으로부터 주어진 거리에있는 모든 점들의 집합입니다.이 함수는 높이와 너비가 다른 타원을 그려내는 ellipse() 함수와는 달리, 너비와 높이가 모두 동일한 원을 그립니다. 이 경우, 높이와 너비는 원의 지름과 같습니다. 기본값으로, 처음 두 매개변수는 원의 중심 위치를 설정하고, 세 번째 매개 변수는 원의 지름을 설정합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 원 중심점의 x좌표",
            +        "y": "숫자: 원 중심점의 y좌표",
            +        "d": "숫자: 원의 지름"
            +      }
            +    },
            +    "line": {
            +      "description": [
            +        "화면에 선분, 즉 두 점을 연결하는 곧은 선을 그립니다. line() 함수에 4개의 변수를 입력하여 이차원 평면에 선을 그릴 수 있습니다. stroke() 함수를 사용해 선의 색상을 지정할 수 있습니다. 선은 면을 갖지 않으므로, 면채우기 함수인 fill()은 적용되지 않습니다. 기본값으로 제공되는 선의 두께는 1픽셀이며, 이를 변경하기 위해 strokeWeight() 함수를 사용할 수 있습니다."
            +      ],
            +      "params": {
            +        "x1": "숫자: 1번째 점의 x좌표값",
            +        "y1": "숫자: 1번째 점의 y좌표값",
            +        "x2": "숫자: 2번째 점의 y좌표값",
            +        "y2": "숫자: 1번째 점의 z좌표값",
            +        "z1": "숫자: 2번째 점의 x좌표값",
            +        "z2": "숫자: 2번째 점의 z좌표값"
            +      }
            +    },
            +    "point": {
            +      "description": [
            +        "화면 좌표에 해당하는, 1픽셀 크기의 점을 그립니다. 첫 번째 매개변수는 점의 x좌표값을, 두 번째 매개변수는 점의 y좌표값입니다. 점의 색상은 stroke() 함수로 변경할 수 있습니다. 점의 크기는 strokeWeight() 함수로 변경할 수 있습니다."
            +      ],
            +      "params": {
            +        "x": "숫자: x좌표값",
            +        "y": "숫자: y좌표값",
            +        "z": "숫자: z좌표값 (WebGL 모드용)",
            +        "coordinate_vector": "p5.Vector: 좌표 벡터"
            +      }
            +    },
            +    "quad": {
            +      "description": [
            +        "사각형을 그립니다. 사각형은 4개의 변을 가진 다각형으로, 얼핏 직사각형과 유사하게 들리나 직사각형과는 달리 변 사이의 각도가 90도로 고정되어 있지 않습니다. 처음 한 쌍의 변수는 최초의 꼭짓점을 설정하며, 뒤이은 다른 쌍들은 시계 방향이나 반시계 방향에 따라 나머지 3개의 꼭짓점 위치를 설정합니다. z 변수는 WebGL 모드에서 quad() 함수를 사용하는 경우에만 적용됩니다."
            +      ],
            +      "params": {
            +        "x1": "숫자: 1번째 꼭짓점의 x좌표값",
            +        "y1": "숫자: 1번째 꼭짓점의 y좌표값",
            +        "x2": "숫자: 2번째 꼭짓점의 y좌표값",
            +        "y2": "숫자: 3번째 꼭짓점의 x좌표값",
            +        "x3": "숫자: 4번째 꼭짓점의 x좌표값",
            +        "y3": "숫자: 4번째 꼭짓점의 y좌표값",
            +        "x4": "숫자: 2번째 꼭짓점의 z좌표값",
            +        "y4": "숫자: 3번째 꼭짓점의 z좌표값",
            +        "detailX": "숫자: (선택 사항) 가로축에 있는 세그멘트의 수",
            +        "detailY": "숫자: (선택 사항) 세로축에 있는 세그멘트의 수",
            +        "z1": "숫자: 2번째 꼭짓점의 x좌표값",
            +        "z2": "숫자: 3번째 꼭짓점의 y좌표값",
            +        "z3": "숫자: 1번째 꼭짓점의 z좌표값",
            +        "z4": "숫자: 4번째 꼭짓점의 z좌표값"
            +      }
            +    },
            +    "rect": {
            +      "description": [
            +        "화면에 직사각형을 그립니다. 직사각형은 변이 4개이고 모든 변 사이의 각도가 90도인 도형을 뜻합니다. 처음 두 변수는 좌측 상단 꼭짓점의 좌표를, 3번째 변수는 사각형의 너비를, 4번째 변수는 그 높이를 설정합니다. rectMode() 함수로 사각형 그리기 모드를 변경하면, 모든 매개변수값들이 달리 해석됩니다.",
            +        "5번째, 6번째, 7번째, 8번째 매개변수를 입력하면, 각각 좌측 상단, 우측 상단, 우측 하단, 좌측 하단 모퉁이들의 각도를 지정하게 됩니다. 이 때 특정 각도 변수가 누락되면, 직전에 입력된 변수와 동일한 값이 적용됩니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 직사각형의 x좌표값",
            +        "y": "숫자: 직사각형의 y좌표값",
            +        "w": "숫자: 직사각형의 너비값",
            +        "h": "숫자: 직사각형의 높이값",
            +        "tl": "숫자: (선택 사항) 좌측 상단 모퉁이 각도값.",
            +        "tr": "숫자: (선택 사항) 우측 상단 모퉁이 각도값.",
            +        "br": "숫자: (선택 사항) 우측 하단 모퉁이 각도값.",
            +        "bl": "숫자: (선택 사항) 좌측 하단 모퉁이 각도값.",
            +        "detailX": "정수: (선택 사항) x축 방향의 선분 수 (WebGL 모드용)",
            +        "detailY": "정수: (선택 사항) y축 방향의 선분 수 (WebGL 모드용)"
            +      }
            +    },
            +    "square": {
            +      "description": [
            +        "화면에 정사각형을 그립니다. 정사각형은 동일한 길이의 네 개의 변을 갖고, 모든 변 사이의 각도가 90도인 도형을 뜻합니다. 이 함수는 rect()함수의 특수한 사례와도 같은데, 너비와 높이가 같고 변의 길이를 라는 매개변수로 처리하게 됩니다. 기본값으로, 처음 두 변수는 처음 두 변수는 좌측 상단 꼭짓점의 좌표를, 3번째 변수는 변의 길이를 지정합니다. rectMode() 함수로 사각형 그리기 모드를 변경하면, 모든 매개변수값들이 달리 해석됩니다.",
            +        "5번째, 6번째, 7번째매개변수를 입력하면, 각각 좌측 상단, 우측 상단, 우측 하단, 좌측 하단 모퉁이들의 각도를 지정하게 됩니다. 이 때 특정 각도 변수가 누락되면, 직전에 입력된 변수와 동일한 값이 적용됩니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 정사각형의 x좌표값",
            +        "y": "숫자: 정사각형의 y좌표값",
            +        "s": "숫자: 정사각형의 너비 및 높이값",
            +        "tl": "숫자: (선택 사항) 좌측 상단 모퉁이 각도값.",
            +        "tr": "숫자: (선택 사항) 우측 상단 모퉁이 각도값.",
            +        "br": "숫자: (선택 사항) 우측 하단 모퉁이 각도값.",
            +        "bl": "숫자: (선택 사항) 좌측 하단 모퉁이 각도값."
            +      }
            +    },
            +    "triangle": {
            +      "description": [
            +        "삼각형은 세 개의 점을 이어 만들어진 평면을 뜻합니다. 처음 두 인수는 1번째 꼭짓점을, 중간의 두 변수는 2번째 꼭짓점을, 마지막 두 인수는 3번째 꼭짓점을 지정합니다."
            +      ],
            +      "params": {
            +        "x1": "숫자:1번째 꼭짓점의 x좌표값",
            +        "y1": "숫자:1번째 꼭짓점의 y좌표값",
            +        "x2": "숫자:2번째 꼭짓점의 x좌표값",
            +        "y2": "숫자:2번째 꼭짓점의 y좌표값",
            +        "x3": "숫자:3번째 꼭짓점의 x좌표값",
            +        "y3": "숫자:3번째 꼭짓점의 y좌표값"
            +      }
            +    },
            +    "ellipseMode": {
            +      "description": [
            +        "ellipse(), circle(), 그리고 arc() 함수의 매개변수들이 해석되는 방식을 변경하여, 타원이 그려지는 시작점 위치를 변경합니다.",
            +        "기본적으로 제공되는 모드는 ellipseMode(CENTER) 함수와도 같습니다. 이는 ellipse() 함수의 처음 두 매개변수를 타원의 중심점으로, 3번째와 4번째 변수를 각각 그 너비와 높이값으로서 해석합니다.",
            +        "ellipseMode(RADIUS) 역시 ellipse() 함수의 처음 두 매개변수를 타원의 중심점으로 해석하나, 3번째와 4번째 변수를 각각 너비와 높이의 중간 지점값으로 해석합니다.",
            +        "ellipseMode(CORNER)는 ellipse() 함수의 처음 두 매개변수를 도형의 좌측 상단을 기준으로 해석하고, 3번째와 4번째 변수를 각각 그 너비와 높이로 해석합니다.",
            +        "ellipseMode(CORNERS)는 ellipse() 함수의 처음 두 매개변수를 도형의 바운딩 박스 중 한 모퉁이의 위치값으로서 해석합니다. 그리고, 3번째와 4번째 변수는 그 정반대 모퉁이의 위치값으로 해석합니다.",
            +        "이 함수의 모든 매개변수(CENTER, RADIUS, CORNER, CORNERS)들은 반드시 대문자로 작성되어야 합니다. 자바스크립트에서는 대소문자 구분이 매우 중요하답니다."
            +      ],
            +      "params": {
            +        "mode": "상수:CENTER, RADIUS, CORNER, 또는 CORNERS"
            +      }
            +    },
            +    "noSmooth": {
            +      "description": [
            +        "모든 그래픽의 가장자리를 울퉁불퉁하게 처리합니다. smooth() 함수는 2D 모드상 언제나 기본값으로 활성화되며, 그래픽을 부드럽게 처리합니다. 따라서, noSmooth() 함수를 호출해야만 도형, 이미지, 폰트 등의 부드러운 처리를 비활성화할 수 있습니다. 반면, 3D 모드에서는 noSmooth()가 기본값으로 활성화됩니다. 따라서, smooth() 함수를 호출해야만 부드러운 처리가 가능합니다."
            +      ]
            +    },
            +    "rectMode": {
            +      "description": [
            +        "rect() 함수의 매개변수들이 해석되는 방식을 변경하여, 직사각형이 그려지는 시작점 위치를 변경합니다.",
            +        "기본적으로 제공되는 모드는 rectMode(CORNER) 함수와도 같습니다. 이는 rect() 함수의 처음 두 매개변수를도형의 좌측 상단을 기준으로 해석하고, 3번째와 4번째 변수를 각각 그 너비와 높이값로서 해석합니다.",
            +        "rectMode(CORNERS)는 rect() 함수의 처음 두 매개변수를 한 모퉁이의 위치값으로 서 해석합니다. 그리고, 3번째와 4번째 변수는 그 정반대 모퉁이의 위치값으로 해석합니다.",
            +        "ellipseMode(CENTER)는 rect() 함수의 처음 두 매개변수를 타원의 중심점으로, 3번째와 4번째 변수를 각각 그 너비와 높이값으로서 해석합니다.",
            +        "rectMode(RADIUS) 역시 rect() 함수의 처음 두 매개변수를 타원의 중심점으로 해석하나, 3번째와 4번째 변수를 각각 너비와 높이의 중간 지점값으로 해석합니다.",
            +        "이 함수의 모든 매개변수(CORNER, CORNERS, CENTER, RADIUS)들은 반드시 대문자로 작성되어야 합니다. 자바스크립트에서는 대소문자 구분이 매우 중요하답니다."
            +      ],
            +      "params": {
            +        "mode": "상수:CORNER, CORNERS, CENTER 또는 RADIUS"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "모든 그래픽을 부드럽게 처리하며, 불러온 이미지 또는 크기가 재조정된 이미지의 화질을 향상합니다. smooth()는 2D 모드상 언제나 기본값으로 활성화되며. 따라서, noSmooth() 함수를 호출해야만 도형, 이미지, 폰트 등의 부드러운 그래픽 처리를 비활성화할 수 있습니다. 반면, 3D 모드에서는 noSmooth()가 기본값으로 활성화됩니다. 따라서, smooth() 함수를 호출해야만 부드러운 그래픽 처리가 가능합니다."
            +      ]
            +    },
            +    "strokeCap": {
            +      "description": [
            +        "선의 양끝에 대한 렌더링 스타일을 설정합니다. 선의 양끝은 매개변수 SQAURE로 각지게, PROJECT로 조금 더 길게, 그리고 ROUND로 둥글게 처리될 수 있습니다. 이 중에서 ROUND는 기본값으로 적용됩니다.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "cap": "상수:SQUARE, PROJECT 또는 ROUND"
            +      }
            +    },
            +    "strokeJoin": {
            +      "description": [
            +        "두 선분 간의 이음새에 대한 스타일을 설정합니다. 이음새는 매개변수 MITER로 각지게, BEVEL로 베벨 처리되듯 비스듬히 깎인 형태로, ROUND로 둥글게 처리될 수 있습니다. 이 중에서 MITER는 기본값으로 적용됩니다.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "join": "상수:MITER, BEVEL 또는 ROUND"
            +      }
            +    },
            +    "strokeWeight": {
            +      "description": [
            +        "선, 점, 그리고 도형 윤곽선을 그릴 때 쓰이는 함수인 stroke()의 결과값 두께를 설정합니다. 모든 두께는 픽셀 단위로 지정됩니다."
            +      ],
            +      "params": {
            +        "weight": "숫자:선의 두께 (픽셀 단위)"
            +      }
            +    },
            +    "bezier": {
            +      "description": [
            +        "화면에 3차 베지에 곡선을 그립니다. 베지에 곡선은 일련의 고정점 및 제어점들로 정의됩니다. 처음 두 매개변수는 1번째 고정점을, 마지막 두 매개변수는 마지막 고정점을 지정합니다. 중간의 두 매개변수는 두 개의 제어점을 지정하며, 이는 곧 곡선의 모양을 정의하게 됩니다. 여기서 제어점은 그 자신을 향해 곡선을 당기는 역할을 합니다.",
            +        "베지에 곡선은 프랑스 출신 자동차 엔지니어인 피에르 베지에(Pierre Bezier)가 개발하였으며, 컴퓨터 그래픽상 부드럽게 경사진 곡선을 정의하는 데에 주로 사용됩니다. <a href=\"#/p5/curve\">curve()</a> 함수와도 관련있습니다."
            +      ],
            +      "params": {
            +        "x1": "숫자: 1번째 고정점의 x좌표값",
            +        "y1": "숫자: 1번째 고정점의 y좌표값",
            +        "x2": "숫자: 1번째 제어점의 x좌표값",
            +        "y2": "숫자: 1번째 제어점의 y좌표값",
            +        "x3": "숫자: 2번째 제어점의 x좌표값",
            +        "y3": "숫자: 2번째 제어점의 y좌표값",
            +        "x4": "숫자: 2번째 고정점의 x좌표값",
            +        "y4": "숫자: 2번째 고정점의 y좌표값",
            +        "z1": "숫자: 1번째 고정점의 z좌표값",
            +        "z2": "숫자: 1번째 제어점의 z좌표값",
            +        "z3": "숫자: 2번째 제어점의 z좌표값",
            +        "z4": "숫자: 2번째 고정점의 z좌표값"
            +      }
            +    },
            +    "bezierDetail": {
            +      "description": [
            +        "베지에 곡선들의 해상도를 설정합니다. 기본값은 20입니다.",
            +        "이 함수는 WebGL 렌더러용으로만 사용되며, 기본 캔버스 렌더러에서는 이 함수를 사용하지 않습니다."
            +      ],
            +      "params": {
            +        "detail": "숫자: 곡선들의 해상도값"
            +      }
            +    },
            +    "bezierPoint": {
            +      "description": [
            +        "점 a, b, c, d로 정의된 베지에 곡선에서 위치 t를 계산합니다. 매개변수 a와 d는 각각 곡선의 1번째 점과 마지막 점에, b와 c는 제어점에 해당합니다. 마지막 매개변수인 t는 0과 1사이에서 표현됩니다. 함수는 먼저 x좌표를 호출한 다음, y좌표를 호출하여 위치 t를 찾게됩니다."
            +      ],
            +      "returns": "숫자: 위치 t에 해당하는 베지에 곡선의 값",
            +      "params": {
            +        "a": "숫자: 곡선의 1번째 점 좌표값",
            +        "b": "숫자: 1번째 제어점 좌표값",
            +        "c": "숫자: 2번째 제어점 좌표값",
            +        "d": "숫자: 곡선의 2번째 점 좌표값",
            +        "t": "숫자: 0과 1 사이의 값"
            +      }
            +    },
            +    "bezierTangent": {
            +      "description": [
            +        "위치 t에서 곡선의 점 a, b, c, d에 대한 탄젠트를 계산합니다. 매개변수 a와 d는 각각 곡선의 1번째 점과 마지막 점에, b와 c는 제어점에 해당합니다. 마지막 매개변수인 t는 0과 1사이에서 표현됩니다."
            +      ],
            +      "returns": "숫자: 위치 t에 해당하는 탄젠트",
            +      "params": {
            +        "a": "숫자: 곡선의 1번째 점 좌표값",
            +        "b": "숫자: 1번째 제어점 좌표값",
            +        "c": "숫자: 2번째 제어점 좌표값",
            +        "d": "숫자: 곡선의 2번째 점 좌표값",
            +        "t": "숫자: 0과 1 사이의 값"
            +      }
            +    },
            +    "curve": {
            +      "description": [
            +        "화면에 두 점 사이에 위치한 곡선을 그립니다. 이 때, 곡선의 형태는 함수의 매개변수들 중 가운데 네 개를 통해 정의됩니다. 처음 두 매개변수는 1번째 제어점의 좌표값을 지정하는데, 마치 이 제어점에서 곡선이 비롯된 것처럼 보이게 됩니다. 마지막 두 매개변수들은 마찬가지 원리로 또다른 제어점의 좌표를 지정합니다. curve() 함수를 조합하거나 curveVertex()를 사용하여 좀 더 긴 곡선을 만들 수 있습니다. 부가적으로, curveTightness()을 통해 곡선의 화질을 조절할 수 있습니다. curve() 함수는 캣멀롬 스플라인(Catmull-Rom Spline)을 구현합니다."
            +      ],
            +      "params": {
            +        "x1": "숫자: 최초 제어점의 x좌표값",
            +        "y1": "숫자: 최초 제어점의 y좌표값",
            +        "x2": "숫자: 1번째 점의 y좌표값",
            +        "y2": "숫자: 2번째 점의 x좌표값",
            +        "x3": "숫자: 마지막 제어점의 x좌표값",
            +        "y3": "숫자: 마지막 제어점의 y좌표값",
            +        "x4": "숫자: 1번째 점의 z좌표값",
            +        "y4": "숫자: 2번째 점의 z좌표값",
            +        "z1": "숫자: 1번째 점의 x좌표값",
            +        "z2": "숫자: 2번째 점의 y좌표값",
            +        "z3": "숫자: 최초 제어점의 z좌표값",
            +        "z4": "숫자: 마지막 제어점의 z좌표값"
            +      }
            +    },
            +    "curveDetail": {
            +      "description": [
            +        "곡선들의 해상도를 설정합니다. <br>기본값은 20이고, 최소값은 3입니다.",
            +        "이 함수는 WebGL 렌더러용으로만 사용되며, 기본 캔버스 렌더러에서는 이 함수를 사용하지 않습니다.",
            +        ""
            +      ],
            +      "params": {
            +        "resolution": "숫자: 곡선들의 해상도값"
            +      }
            +    },
            +    "curveTightness": {
            +      "description": [
            +        "curve()와 curveVertex() 함수를 사용하여 모양을 변경합니다. 곡선의 팽팽함(tightness)을 지정하는 매개변수 t는, 두 꼭짓점 사이에 곡선이 들어맞는 정도를 결정합니다. 값 0.0은 곡선의 팽팽함에 대한 기본값이며(이 값을 통해 곡선을 캣멀롬 스플라인으로 정의), 값 1.0은 모든 점을 직선 상태로 연결하게 됩니다. -5.0와 5.0 사이의 값들은 화면상 인식 가능한 범위 내에서 값의 크기에 비례하여 곡선을 변형합니다."
            +      ],
            +      "params": {
            +        "amount": "숫자: 원래 꼭짓점으로부터 변형된 정도의 양"
            +      }
            +    },
            +    "curvePoint": {
            +      "description": [
            +        "점 a, b, c, d로 정의된 곡선에서 위치 t를 계산합니다. 매개변수 a와 d는 곡선의 제어점에, b와 c는 각각 곡선의 시작점과 끝점에 해당합니다. 마지막 매개변수인 t는 0과 1사이에서 표현됩니다. 함수는 먼저 x좌표를 호출한 다음, y좌표를 호출하여 위치 t를 찾게됩니다."
            +      ],
            +      "returns": "숫자: 위치 t에 해당하는 베지어값",
            +      "params": {
            +        "a": "숫자: 곡선의 1번째 제어점 좌표값",
            +        "b": "숫자: 1번째 점 좌표값",
            +        "c": "숫자: 2번째 점 좌표값",
            +        "d": "숫자: 곡선의 2번째 제어점 좌표값",
            +        "t": "숫자: 0과 1 사이의 값"
            +      }
            +    },
            +    "curveTangent": {
            +      "description": [
            +        "위치 t에서 곡선의 점 a, b, c, d에 대한 탄젠트를 계산합니다. 매개변수 a와 d는 각각 곡선 위 점에, b와 c는 제어점에 해당합니다. 마지막 매개변수인 t는 0과 1사이에서 표현됩니다."
            +      ],
            +      "returns": "숫자: 위치 t에 해당하는 탄젠트",
            +      "params": {
            +        "a": "숫자: 곡선의 1번째 점 좌표값",
            +        "b": "숫자: 1번째 제어점 좌표값",
            +        "c": "숫자: 2번째 제어점 좌표값",
            +        "d": "숫자: 곡선의 2번째 점 좌표값",
            +        "t": "숫자: 0과 1 사이의 값"
            +      }
            +    },
            +    "beginContour": {
            +      "description": [
            +        "beginContour()와 endContour() 함수를 사용하여 특정 도형 내부에 그 음수 좌표에 상응하는 동일한 도형 윤곽선을 그릴 수 있습니다. 예를 들어, 동그라미의 안쪽에 또다른 작은 동그라미를 그릴 수 있습니다. beginContour()는 도형의 꼭짓점을 기록하기 시작하고, endContour()는 그 기록을 중지합니다. 이 때, 안쪽의 도형을 정의하는 꼭짓점은 바깥쪽의 도형과 반대 순서로 그려져야 합니다. 먼저 바깥에 위치한 원래 도형의 꼭짓점을 시계 방향으로 그리고, 그 다음 내부의 도형을 시계 반대 방향으로 그립니다.",
            +        "beginContour()/endContour() 함수는 반드시 <a href=\"#/p5/beginShape\">beginShape()/</a>/Shape\">endShape()</a> 함수 사이에 작성되어야 합니다. 또한, beingContour()/endContour() 함수 사이에는 translate(), rotate(), scale()과 같은 변형 함수나 ellipse() 및 rect()와 같은 도형그리기 함수가 사용될 수 없습니다.",
            +        ""
            +      ]
            +    },
            +    "beginShape": {
            +      "description": [
            +        "<a href=\"#/p5/beginShape\">beginShape()</a>과 <a href=\"#/p5/endShape\">endShape()</a>를 사용하여 좀 더 복잡한 모양을 만들 수 있습니다. beingShape()은 도형의 꼭짓점을 기록하기 시작하고, <a href=\"#/p5/endShape\">endShape()</a>은 그 기록을 중지합니다. 함수의 매개변수를 통해 꼭짓점으로 어떤 도형을 그릴지 결정할 수 있습니다. 별도의 매개변수가 지정되지 않으면, 비정형의 다각형이 그려집니다.",
            +        "<a href=\"#/p5/beginShape\">beginShape()</a>에 쓰이는 매개변수로는 POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, QUAD_STRIP, 그리고 TESS(WebGL 전용)가 있습니다. <a href=\"#/p5/beginShape\">beginShape()</a> 함수를 호출한 다음, 꼭짓점 지정을 위해 vertex() 명령문을 반드시 작성해야 합니다. 도형그리기를 멈추려면 <a href=\"#/p5/endShape\">endShape()</a> 함수를 호출하면 됩니다. 각 도형은 현재 지정된 선그리기(stroke) 및 면채우기(fill) 색상으로 그려집니다.",
            +        "<a href=\"#/p5/beginShape\">beginShape()</a>와 <a href=\"#/p5/endShape\">endShape()</a> 함수들 사이에는 <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>과 같은 변형 함수나 <a href=\"#/p5/ellipse\">ellipse()</a>, <a href=\"#/p5/rect\">rect()</a>와 같은 도형그리기 함수를 사용할 수 없습니다.",
            +        "LINES - 여려 개의 분리 된 선들을 그립니다.",
            +        "TRIANGLES - 여러 개의 분리 된 삼각형들을 그립니다.",
            +        "TRIANGLE_FAN - 여러 개의 연결 된 삼각형들을 그립니다. 이 삼각형들은 첫 꼭짓점을 공통적으로 하며 부채 모양으로 그려집니다.",
            +        "TRIANGLE_STRIP - 여러 개의 연결 된 삼각형들을 그립니다. 이 삼각형들은 한 줄로 그려집니다.",
            +        "QUADS - 여러 개의 분리 된 사각형들을 그립니다.",
            +        "QUAD_STRIP - 여러 개의 연결 된 사각형들을 한 줄로 그립니다.",
            +        "TESS (WebGl만 가능) - 모자이크 세공 (tessellation)을 위한 불규칙적 도형을 그립니다.",
            +        "<a href=\"#/p5/beginShape\">beginShape()</a> 함수는 호출할 시, 이후에 여러 개의 <a href=\"#/p5/vertex\">vertex()</a> 명령들을 호출해야 합니다.그림 그리기를 멈추려면 <a href=\"#/p5/endShape\">endShape()</a> 함수를 호출합니다. 각 도형은 현재의 윤곽선 색으로 그려지며, 면은 현재의 면 색으로 채워집니다.",
            +        "<a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, 또는 <a href=\"#/p5/scale\">scale()</a>와 같은 변형 함수들은 <a href=\"#/p5/beginShape\">beginShape()</a> 함수 안에서 사용할 수 없습니다. 또한, <a href=\"#/p5/ellipse\">ellipse()</a>와 <a href=\"#/p5/rect\">rect()</a> 같은 함수들을 <a href=\"#/p5/beginShape\">beginShape()</a> 함수 안에서 사용할 수 없습니다."
            +      ],
            +      "params": {
            +        "kind": "상수: (선택 사항) POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS 또는 QUAD_STRIP"
            +      }
            +    },
            +    "bezierVertex": {
            +      "description": [
            +        "베지에 곡선의 꼭짓점 좌표를 지정합니다. bezierVertex()은 매 호출마다 베지에 곡선의 제어점 2개와 고정점 1개의 위치를 정의하고, 이 새로운 선분을 선 또는 도형에 더합니다. bezierVertex()는 WebGL상 2D 및 3D 모드 모두에 적용될 수 있습니다. 2D 모드에서는 6개의 매개변수가, 3D 모드에서는 9개의 매개변수(z좌표값 포함)가 필요합니다.",
            +        "<a href=\"#/p5/beginShape\">beginShape()</a> 함수 안에 작성된 bezierVertex()를 호출하기에 앞서, vertex() 함수를 bezierVertex() 윗줄에 작성하여 곡선의 1번째 고정점을 설정해야 합니다. bezierVertex() 함수는 반드시 <a href=\"#/p5/beginShape\">beginShape()/</a>/Shape\">endShape()</a> 함수 사이에 작성되어야하며, <a href=\"#/p5/beginShape\">beginShape()</a> 함수에 MODE나 POINTS 매개변수가 지정되지 않은 경우에만 사용가능 합니다."
            +      ],
            +      "params": {
            +        "x2": "숫자: 1번째 제어점의 x좌표값",
            +        "y2": "숫자: 1번째 제어점의 y좌표값",
            +        "x3": "숫자: 2번째 제어점의 x좌표값",
            +        "y3": "숫자: 2번째 제어점의 y좌표값",
            +        "x4": "숫자: 고정점의 x좌표값",
            +        "y4": "숫자: 고정점의 y좌표값",
            +        "z2": "숫자: 1번째 제어점의 z좌표값 (WebGL 모드용)",
            +        "z3": "숫자: 2번째 제어점의 z좌표값 (WebGL 모드용)",
            +        "z4": "숫자: 고정점의 z좌표값 (WebGL 모드용)"
            +      }
            +    },
            +    "curveVertex": {
            +      "description": [
            +        "곡선의 꼭짓점 좌표를 지정합니다. 이 함수는 반드시 <a href=\"#/p5/beginShape\">beginShape()/</a>/Shape\">endShape()</a> 함수 사이에 작성되어야하며, <a href=\"#/p5/beginShape\">beginShape()</a> 함수에 MODE나 POINTS 매개변수가 지정되지 않은 경우에만 사용가능 합니다. 또한, 이 함수는 WebGL상 2D 및 3D 모드 모두에 적용될 수 있습니다. 2D 모드에서는 2개의 매개변수가, 3D 모드에서는 3개의 매개변수가 필요합니다.",
            +        "curveVertex()로 그려진 일련의 선들 중 1번째 점과 마지막 점을 통해 각각 전체 곡선의 시작점과 끝점을 알 수 있습니다. 2번째와 3번째 사이에도 작은 곡선을 만들기 위해선 최소 4개의 점들이 필요합니다. curveVertex() 함수로 5번째 점을 추가하면 함수는 2번째, 3번째, 4번째 점들 사이에 곡선을 그립니다. curveVertex() 함수는 캣멀롬 스플라인(Catmull-Rom Spline)을 구현합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 꼭짓점의 x좌표값",
            +        "y": "숫자: 꼭짓점의 y좌표값",
            +        "z": "숫자: (선택 사항) 꼭짓점의 z좌표값 (WebGL 모드용)"
            +      }
            +    },
            +    "endContour": {
            +      "description": [
            +        "beginContour()와 endContour() 함수를 사용하여 특정 도형 내부에 그 음수 좌표에 상응하는 동일한 도형 윤곽선을 그릴 수 있습니다. 예를 들어, 동그라미의 안쪽에 또다른 작은 동그라미를 그릴 수 있습니다. beginContour()는 도형의 꼭짓점을 기록하기 시작하고, endContour()는 그 기록을 중지합니다. 이 때, 안쪽의 도형을 정의하는 꼭짓점은 바깥쪽의 도형과 반대 순서로 그려져야 합니다. 먼저 바깥에 위치한 원래 도형의 꼭짓점을 시계 방향으로 그리고, 그 다음 내부의 도형을 시계 반대 방향으로 그립니다.",
            +        "beginContour()/endContour() 함수는 반드시 <a href=\"#/p5/beginShape\">beginShape()/</a>/Shape\">endShape()</a> 함수 사이에 작성되어야 합니다. 또한, beingContour()/endContour() 함수 사이에는 translate(), rotate(), scale()과 같은 변형 함수나 ellipse() 및 rect()와 같은 도형그리기 함수가 사용될 수 없습니다."
            +      ]
            +    },
            +    "endShape": {
            +      "description": [
            +        "<a href=\"#/p5/endShape\">endShape()</a>은 <a href=\"#/p5/beginShape\">beginShape()</a>과 한 쌍을 이루는 함수로, 반드시 beginShape() 다음에 호출될 수 있습니다. <a href=\"#/p5/endShape\">endShape()</a> 함수가 호출되면, <a href=\"#/p5/beginShape\">beginShape()</a> 함수가 호출된 이래로 정의된 모든 이미지 데이터가이미지 버퍼로서 처리됩니다. <a href=\"#/p5/endShape\">endShape()</a>의 MODE 매개변수로는 상수 CLOSE를 씁니다."
            +      ],
            +      "params": {
            +        "mode": "상수: CLOSE로 도형 닫기"
            +      }
            +    },
            +    "quadraticVertex": {
            +      "description": [
            +        "2차 베지에 곡선의 꼭짓점 좌표를 지정합니다. quadraticVertex()은 매 호출마다 베지에 곡선의 제어점 1개와 고정점 1개의 위치를 정의하고, 이 새로운 선분을 선 또는 도형에 더합니다. <a href=\"#/p5/beginShape\">beginShape()</a> 함수 안에 작성된 quadraticVertex()를 호출하기에 앞서, vertex() 함수를 quadraticVertex() 윗줄에 작성하여 곡선의 1번째 고정점을 설정해야 합니다. quadraticVertex()는 WebGL상 2D 및 3D 모드 모두에 적용될 수 있습니다. 2D 모드에서는 6개의 매개변수가, 3D 모드에서는 9개의 매개변수(z좌표값 포함)가 필요합니다.",
            +        "quadraticVertex() 함수는 반드시 <a href=\"#/p5/beginShape\">beginShape()/</a>/Shape\">endShape()</a> 함수 사이에 작성되어야하며, <a href=\"#/p5/beginShape\">beginShape()</a> 함수에 MODE나 POINTS 매개변수가 지정되지 않은 경우에만 사용가능 합니다."
            +      ],
            +      "params": {
            +        "cx": "숫자: 제어점의 x좌표값",
            +        "cy": "숫자: 제어점의 y좌표값",
            +        "x3": "숫자: 고정점의 y좌표값",
            +        "y3": "숫자: 제어점의 z좌표값 (WebGL 모드용)",
            +        "cz": "숫자: 고정점의 x좌표값",
            +        "z3": "숫자: 고정점의 z좌표값 (WebGL 모드용)"
            +      }
            +    },
            +    "vertex": {
            +      "description": [
            +        "모든 도형들은 꼭짓점 연결을 통해 구축됩니다. vertex() 함수를 사용하여 점, 선, 삼각형, 사각형, 그리고 다각형의 꼭짓점 좌표를 지정할 수 있습니다.는 데에 쓰입니다. 이 때, vertex() 함수는 반드시 <a href=\"#/p5/beginShape\">beginShape()/</a>/Shape\">endShape()</a> 함수 사이에 작성되어야합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 꼭짓점의 x좌표값",
            +        "y": "숫자: 꼭짓점의 y좌표값",
            +        "z": "숫자: 꼭짓점의 z좌표값",
            +        "u": "숫자: (선택 사항) 꼭짓점의 u좌표값",
            +        "v": "숫자: (선택 사항) 꼭짓점의 v좌표값"
            +      }
            +    },
            +    "normal": {
            +      "description": [
            +        "이후에 <a href=\"#/p5/vertex\">vertex()</a> 함수로 그려질 꼭짓점들을 위한 3D 꼭짓점의 노멀 (normal)을 설정합니다. 도형의 면에 수직방향이 노멀 벡터이며, 이는 빛의 반사량을 지정합니다."
            +      ],
            +      "params": {
            +        "vector": "벡터: 노멀을 표시하는 p5.Vector.",
            +        "x": "숫자: 꼭짓점의 x좌표값",
            +        "y": "숫자: 꼭짓점의 y좌표값",
            +        "z": "숫자: 꼭짓점의 z좌표값"
            +      }
            +    },
            +    "VERSION": {
            +      "description": [
            +        "본 p5.js 버전."
            +      ]
            +    },
            +    "P2D": {
            +      "description": [
            +        "기본적 이차원적 렌더러 (2D Renderer)."
            +      ]
            +    },
            +    "WEBGL": {
            +      "description": [
            +        "p5.js의 렌더 모드들 중 하나: P2D (기본)와 WEBGL. WEBGL은 제 3의 차원, 'Z'를 추가함으로서 3D 렌더를 가능하게 합니다."
            +      ]
            +    },
            +    "ARROW": {},
            +    "CROSS": {},
            +    "HAND": {},
            +    "MOVE": {},
            +    "TEXT": {},
            +    "WAIT": {},
            +    "HALF_PI": {
            +      "description": [
            +        "HALF_PI는 1.57079632679489661923 값을 갖는 상수입니다. 지름에 대한 원주율의 절반에 해당하며, 삼각 함수 <a href=\"#/p5/sin\">sin()</a>과 cos()와 함께 쓰면 더욱 유용합니다."
            +      ]
            +    },
            +    "PI": {
            +      "description": [
            +        "PI는 3.14159265358979323846 값을 갖는 상수입니다. 지름에 대한 원주율을 의미하며, 삼각 함수 <a href=\"#/p5/sin\">sin()</a>과 cos()와 함께 쓰면 더욱 유용합니다."
            +      ]
            +    },
            +    "QUARTER_PI": {
            +      "description": [
            +        "QUARTER_PI는 0.7853982 값을 갖는 상수입니다. 지름에 대한 원주율의 1/4에 해당하며, 삼각 함수 sin()과 cos()와 함께 쓰면 더욱 유용합니다."
            +      ]
            +    },
            +    "TAU": {
            +      "description": [
            +        "TAU는 TWO_PI의 약어로, 이는 6.28318530717958647693 값을 갖는 상수입니다. 지름에 대한 원주율의 2배에 해당하며, 삼각 함수 sin()과 cos()와 함께 쓰면 더욱 유용합니다."
            +      ]
            +    },
            +    "TWO_PI": {
            +      "description": [
            +        "TWO_PI는6.28318530717958647693 값을 갖는 상수입니다. 지름에 대한 원주율의 2배에 해당하며, 삼각 함수 sin()과 cos()와 함께 쓰면 더욱 유용합니다."
            +      ]
            +    },
            +    "DEGREES": {
            +      "description": [
            +        "p5.js가 각도를 해석하고 계산하는 방법을 설정하기 위해, angleMode() 함수와 그 매개변수(DEGREES 또는 RADIANS)를 사용합니다."
            +      ]
            +    },
            +    "RADIANS": {
            +      "description": [
            +        "p5.js가 각도를 해석하고 계산하는 방법을 설정하기 위해, angleMode() 함수와 그 매개변수(DEGREES 또는 RADIANS)를 사용합니다."
            +      ]
            +    },
            +    "CORNER": {},
            +    "CORNERS": {},
            +    "RADIUS": {},
            +    "RIGHT": {},
            +    "LEFT": {},
            +    "CENTER": {},
            +    "TOP": {},
            +    "BOTTOM": {},
            +    "BASELINE": {},
            +    "POINTS": {},
            +    "LINES": {},
            +    "LINE_STRIP": {},
            +    "LINE_LOOP": {},
            +    "TRIANGLES": {},
            +    "TRIANGLE_FAN": {},
            +    "TRIANGLE_STRIP": {},
            +    "QUADS": {},
            +    "QUAD_STRIP": {},
            +    "TESS": {},
            +    "CLOSE": {},
            +    "OPEN": {},
            +    "CHORD": {},
            +    "PIE": {},
            +    "PROJECT": {},
            +    "SQUARE": {},
            +    "ROUND": {},
            +    "BEVEL": {},
            +    "MITER": {},
            +    "RGB": {},
            +    "HSB": {
            +      "description": [
            +        "HSB (색도, 채도값, 발기)는 색상 모델의 일종입니다. <a href=\"https://www.theteams.kr/teams/12872/post/72252\">이 링크를</a> 통해 더 자세히 배울 수 있습니."
            +      ]
            +    },
            +    "HSL": {},
            +    "AUTO": {
            +      "description": [
            +        "AUTO는 특정 요소의 높이나 너비 (둘 중 하나)를 그 요소의 너비나 높이에 따라 자동적으로 정할 수 있게 합니다. 따라서 <a href=\"/#/p5.Element/size\">size()</a>에 AUTO를 지정할 수 있는 매개변수는 1 개로 제한됩니다."
            +      ]
            +    },
            +    "ALT": {},
            +    "BACKSPACE": {},
            +    "CONTROL": {},
            +    "DELETE": {},
            +    "DOWN_ARROW": {},
            +    "ENTER": {},
            +    "ESCAPE": {},
            +    "LEFT_ARROW": {},
            +    "OPTION": {},
            +    "RETURN": {},
            +    "RIGHT_ARROW": {},
            +    "SHIFT": {},
            +    "TAB": {},
            +    "UP_ARROW": {},
            +    "BLEND": {},
            +    "REMOVE": {},
            +    "ADD": {},
            +    "DARKEST": {},
            +    "LIGHTEST": {},
            +    "DIFFERENCE": {},
            +    "SUBTRACT": {},
            +    "EXCLUSION": {},
            +    "MULTIPLY": {},
            +    "SCREEN": {},
            +    "REPLACE": {},
            +    "OVERLAY": {},
            +    "HARD_LIGHT": {},
            +    "SOFT_LIGHT": {},
            +    "DODGE": {},
            +    "BURN": {},
            +    "THRESHOLD": {},
            +    "GRAY": {},
            +    "OPAQUE": {},
            +    "INVERT": {},
            +    "POSTERIZE": {},
            +    "DILATE": {},
            +    "ERODE": {},
            +    "BLUR": {},
            +    "NORMAL": {},
            +    "ITALIC": {},
            +    "BOLD": {},
            +    "BOLDITALIC": {},
            +    "CHAR": {},
            +    "WORD": {},
            +    "LINEAR": {},
            +    "QUADRATIC": {},
            +    "BEZIER": {},
            +    "CURVE": {},
            +    "STROKE": {},
            +    "FILL": {},
            +    "TEXTURE": {},
            +    "IMMEDIATE": {},
            +    "IMAGE": {},
            +    "NEAREST": {},
            +    "REPEAT": {},
            +    "CLAMP": {},
            +    "MIRROR": {},
            +    "LANDSCAPE": {},
            +    "PORTRAIT": {},
            +    "GRID": {},
            +    "AXES": {},
            +    "LABEL": {},
            +    "FALLBACK": {},
            +    "print": {
            +      "description": [
            +        "print() 함수는 브라우저 콘솔창에 출력할 때 사용됩니다. 프로그램이 생성하는 데이터를 확인할 때 주로 도움됩니다. 함수는 매번 호출될 때마다 콘솔창에 새로운 텍스트 줄을 만듭니다. 개별 요소는 큰따옴표로 분리하고, 더하기 연산자(+)로 두 요소를 결합할 수 있습니다.",
            +        "인수없이 print()를 호출하면, window.print()와 동일하게 브라우저상 인쇄 기능을 켭니다. 콘솔창에 빈 줄을 출력하려면 print('\n')을 작성하면 됩니다."
            +      ],
            +      "params": {
            +        "contents": "전부: 출력할 숫자, 문자열, 객체, 불리언, 배열의 조합"
            +      }
            +    },
            +    "frameCount": {
            +      "description": [
            +        "시스템 변수 frameCount는 프로그램 시작 이후 화면에 나타난 프레임의 개수를 측정합니다. <a href=\"#/p5/setup\">setup()</a> 함수의 기본값은 0이고, <a href=\"#/p5/draw\">draw()</a> 함수의 첫 번째 반복 실행이 마치면 1씩 증가하는 식입니다."
            +      ]
            +    },
            +    "deltaTime": {
            +      "description": [
            +        "<a href=\"#/p5/deltaTime\">deltaTime</a> 은 전 프레임의 시작 시간과 본 프레임의 시작 시간의 차를 저장합니다.",
            +        "이 변수는 시간적으로 민감한 애니매시션, 또는 프레임레이트와 관계없이 일정해야 하는 물리학적 계산에 유용합니다."
            +      ]
            +    },
            +    "focused": {
            +      "description": [
            +        "p5.js 프로그램이 등장하는 화면창의 초점이 맞는지 여부를 확인하며, 이는 곧 스케치가 마우스나 키보드 입력을 허용한다는 것을 의미합니다. 화면창의 초점이 맞으면 변수는 true이고, 그렇지 않으면 false입니다."
            +      ]
            +    },
            +    "cursor": {
            +      "description": [
            +        "마우스 커서를 사전에 정의된 기호나 이미지로 설정하거나, 숨김 상태일 경우 이를 해제합니다. 특정 이미지를 커서로 설정할 경우, 권장 사이즈는 16x16 또는 32x32 입니다. 매개변수 x와 y의 값은 이미지의 실제 크기보다 훨씬 더 작아야 합니다."
            +      ],
            +      "params": {
            +        "type": "문자열|상수: ARROW, CROSS, HAND, MOVE, TEXT, WAIT. CSS 요소인 'grab', 'progress', 'cell' 등. 외부: 커서 이미지의 경로(허용 파일 확장자:.cur, .gif, .jpg, .jpeg, .png, url 주소. 참고: <ah ref='https://developer.mozilla.org/ko/docs/Web/CSS/cursor'>https://developer.mozilla.org/ko/docs/Web/CSS/cursor</a>",
            +        "x": "숫자: (선택 사항) 커서의 수평 활성 지점 (32미만으로 지정)",
            +        "y": "숫자: (선택 사항) 커서의 수직 활성 지점 (32미만으로 지정)"
            +      }
            +    },
            +    "frameRate": {
            +      "description": [
            +        "화면에 나타날 프레임 수를 매 초단위로 지정합니다. 예를 들어, frameRate(30)은 초당 30회씩 새로 고침을 시도합니다. 프로세서가 지정된 속도를 유지할만큼 빠르지 않다면, 프레임 속도에 달성되지 않습니다. <a href=\"#/p5/setup\">setup()</a> 함수 내에서 프레임 속도를 설정하는 것을 권장합니다. 기본값으로 제공되는 프레임 속도는 디스플레이의 프레임 속도('새로 고침 빈도')를 기준으로 합니다. 초당 24 프레임 정도면 애니메이션을 부드럽게 재생할 수 있습니다. 이 함수는 setFrameRate(val)와 동일한 효과를 갖습니다.",
            +        "별도의 인수없이 frameRate() 함수를 호출하면 현재 프레임 속도가 반환됩니다. 프레임 속도를 반환하기 위해서는 <a href=\"#/p5/draw\">draw()</a> 함수를 한 번 이상 실행해야 합니다. 이는 getFrameRate() 함수와도 동일합니다.",
            +        "숫자형이 아니거나 양수가 아닌 숫자형의 인수로 frameRate() 함수를 호출하면 마찬가지로 현재 프레임 속도를 반환합니다."
            +      ],
            +      "params": {
            +        "fps": "숫자:1초 동안 화면에 나타날 프레임 수"
            +      }
            +    },
            +    "noCursor": {
            +      "description": [
            +        "화면상 커서를 숨깁니다."
            +      ]
            +    },
            +    "displayWidth": {
            +      "description": [
            +        "<a href=\"#/p5/pixelDensity\">pixelDensity</a> 함수의 기본값에 따라 화면의 너비값을 저장하는 시스템 변수입니다. 모든 디스플레이에서 프로그램을 전체 화면으로 실행시킬 때 사용합니다. 실제 화면 크기값을 반환하려면 여기에 pixelDensity를 곱하면 됩니다."
            +      ]
            +    },
            +    "displayHeight": {
            +      "description": [
            +        "<a href=\"#/p5/pixelDensity\">pixelDensity</a> 함수의 기본값에 따라 화면의 높이값을 저장하는 시스템 변수입니다. 모든 디스플레이에서 프로그램을 전체 화면으로 실행시킬 때 사용합니다. 실제 화면 크기값을 반환하려면 여기에 pixelDensity를 곱하면 됩니다."
            +      ]
            +    },
            +    "windowWidth": {
            +      "description": [
            +        "사용자의 윈도우 화면 너비값을 저장해주는 시스템 변수로, window.innerWidth에 매핑됩니다."
            +      ]
            +    },
            +    "windowHeight": {
            +      "description": [
            +        "사용자의 윈도우 화면 높이값을 저장해주는 시스템 변수로, window.innerHeight에 매핑됩니다."
            +      ]
            +    },
            +    "windowResized": {
            +      "description": [
            +        "<a href=\"#/p5/windowResized\">windowResized()</a> 함수는 브라우저 창의 크기가 조정될 때마다 한 번씩 호출됩니다. 캔버스 크기를 재조정하거나 새 윈도우 화면의 크기에 맞춰 조정할 때 유용합니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) 이벤트 콜백 (callback) 인자값."
            +      }
            +    },
            +    "width": {
            +      "description": [
            +        "생성된 캔버스의 너비값을 저장하는 시스템 변수입니다. 이 값은 <a href=\"#/p5/createCanvas\">createCanvas()</a> 함수의 1번째 매개변수로 지정됩니다. createCanvas(320, 240)는 너비 변수를 320으로 설정한 사례입니다. 프로그램에 <a href=\"#/p5/createCanvas\">createCanvas()</a>를 사용하지 않을 경우, 너비는 기본값인 100으로 설정됩니다."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "생성된 캔버스의 높이값을 저장하는 시스템 변수입니다. 이 값은 <a href=\"#/p5/createCanvas\">createCanvas()</a> 함수의 2번째 매개변수로 지정됩니다. createCanvas(320, 240)는 높이 변수를 240으로 설정한 사례입니다. 프로그램에 <a href=\"#/p5/createCanvas\">createCanvas()</a>를 사용하지 않을 경우, 높이는 기본값인 100으로 설정됩니다."
            +      ]
            +    },
            +    "fullscreen": {
            +      "description": [
            +        "사용자가 지정한 인수값을 기준으로 스케치를 전체 화면으로 설정합니다. 인수를 지정하지 않으면 현재 전체 화면 모드를 반환합니다. 위의 예제는 브라우저 제한으로 인해 마우스 입력과같은 사용자 입력이 있을 때 이 함수를 호출합니다."
            +      ],
            +      "returns": "불리언: 현재 전체 화면 상태",
            +      "params": {
            +        "val": "불리언: (선택 사항) 스케치를 전체 화면 모드로 실행할 지의 여부"
            +      }
            +    },
            +    "pixelDensity": {
            +      "description": [
            +        "픽셀 밀도가 높은 디스플레이의 픽셀 크기를 조정합니다. pixelDensity()는 그 기본값으로 화면의 픽셀 밀도와 일치하도록 설정되어 있으며, pixelDensity(1)를 호출하여 이를 해제할 수 있습니다. 별도의 인수없이 pixelDensity() 함수를 호출하면, 스케치의 현재 픽셀 밀도가 반환됩니다."
            +      ],
            +      "params": {
            +        "val": "숫자: 스케치의 픽셀 크기를 조정할 지 여부 또는 조정값"
            +      }
            +    },
            +    "displayDensity": {
            +      "description": [
            +        "스케치가 실행 중인 현재 디스플레이의 픽셀 밀도를 반환합니다."
            +      ],
            +      "returns": "숫자: 디스플레이의 현재 픽셀 밀도"
            +    },
            +    "getURL": {
            +      "description": [
            +        "현재 URL을 받아옵니다."
            +      ],
            +      "returns": "문자열: url"
            +    },
            +    "getURLPath": {
            +      "description": [
            +        "현재 URL 경로를 배열로 받아옵니다."
            +      ],
            +      "returns": "문자열 배열[]:경로 요소의 배열"
            +    },
            +    "getURLParams": {
            +      "description": [
            +        "현재 URL 매개변수들을 객체로 받아옵니다."
            +      ],
            +      "returns": "객체: URL 매개변수들"
            +    },
            +    "preload": {
            +      "description": [
            +        "<a href=\"#/p5/preload\">preload()</a> 함수는 <a href=\"#/p5/setup\">setup()</a> 함수 직전에 호출되며, 외부 파일의 비동기 불러오기를 차단하기 위해 사용됩니다. <a href=\"#/p5/preload\">preload()</a> 함수로 외부 파일 사전 불러오기가 설정되면, <a href=\"#/p5/setup\">setup()</a> 함수는 불러오기 호출이 완료될 때까지 대기합니다. 불러오기 호출 이외의 다른 함수(loadImage, loadJOSN, loadFont, loadString)는 <a href=\"#/p5/preload\">preload()</a> 함수 안에 포함되지 않아야 합니다. 만약 비동기 불러오기를 선호한다면, 불러오기 메소드를 <a href=\"#/p5/setup\">setup()</a> 함수 안에 포함시키거나, 그 외의 영역에서 callback 매개변수를 사용하여 호출하면 됩니다.",
            +        "기본값으로 'loading..'이라는 텍스트가 화면에 나타납니다. 나만의 로딩 페이지를 만들려면 id가 p5_loading으로 지정된 HTML 요소를 추가하면 됩니다. 자세한 정보는 <a href='http://bit.ly/2kQ6Nio'>여기</a>에 있습니다."
            +      ]
            +    },
            +    "setup": {
            +      "description": [
            +        "<a href=\"#/p5/setup\">setup()</a> 함수는 프로그램 실행시 단 한번 호출됩니다. 함수는 화면 크기나 배경색 등의 초기 환경 요소를 정의하고, 또 이미지나 폰트같은 미디어 파일을 불러오는 데에 쓰입니다. <a href=\"#/p5/setup\">setup()</a> 함수는 프로그램당 한 개씩만 존재할 수 있으며, 최초 한 번 실행된 이후에는 재호출되지 않아야 합니다.",
            +        "참고: <a href=\"#/p5/setup\">setup()</a> 함수 안에 선언된 변수는, <a href=\"#/p5/draw\">draw()</a> 함수를 비롯한 여타 함수들이 접근할 수 없습니다.",
            +        ""
            +      ]
            +    },
            +    "draw": {
            +      "description": [
            +        "<a href=\"#/p5/draw\">draw()</a> 함수는 <a href=\"#/p5/setup\">setup()</a> 함수 직후에 호출되며, 프로그램 실행이 중단되거나 <a href=\"#/p5/noLoop\">noLoop()</a> 함수가 호출되기 전까지 블록 내에 포함된 코드들을 계속 실행합니다. 만약 <a href=\"#/p5/setup\">setup()</a> 함수에서 <a href=\"#/p5/noLoop\">noLoop()</a>가 호출된다면, <a href=\"#/p5/draw\">draw()</a> 함수는 단 한 번 실행됩니다. <a href=\"#/p5/draw\">draw()</a> 함수는 자동으로 호출되며, 명시적으로 호출하면 안됩니다.",
            +        "<a href=\"#/p5/draw\">draw()</a> 함수는 항상 <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a>, 그리고 loop() 함수로 제어됩니다. <a href=\"#/p5/noLoop\">noLoop()</a>함수가 <a href=\"#/p5/draw\">draw()</a> 함수에 포함된 코드 실행을 멈추면, <a href=\"#/p5/redraw\">redraw()</a> 함수가 <a href=\"#/p5/draw\">draw()</a> 함수 안에 포함된 코드들을 한 번만 실행하게 됩니다. loop() 함수의 경우, <a href=\"#/p5/draw\">draw()</a> 함수 안에 있는 코드를 계속해서 반복적으로 실행되게 합니다.",
            +        "<a href=\"#/p5/draw\">draw()</a> 함수가 초당 호출되는 횟수는 frameRate() 함수를 통해 조정할 수 있습니다.",
            +        "<a href=\"#/p5/draw\">draw()</a> 함수는 한 스케치당 한 번만 작성되어야 하며, 코드를 계속 실행하거나 mousePressed()와 같은 이벤트를 처리할 때 반드시 필요합니다. 때로는 위의 예제처럼 비어있는 <a href=\"#/p5/draw\">draw()</a> 함수를 호출하기도 합니다.",
            +        "드로잉의 좌표계가 매 <a href=\"#/p5/draw\">draw()</a> 함수가 호출될 때마다 리셋되는 점에 유의해야 합니다. <a href=\"#/p5/draw\">draw()</a> 함수 안에서 변형 함수(scale, rotate, translate)가 실행될 경우, <a href=\"#/p5/draw\">draw()</a> 함수가 재호출되는 시점에 그 효과들은 무효화되고, 따라서 시간이 지나도 변형 내용이 누적되지 않습니다. 반면, 한 번 선언된 스타일(fill, stroke 등)은 계속해서 적용됩니다."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "전체 p5 스케치를 제거합니다. 이 함수는 캔버스와 p5.js로 생성한 모든 요소들을 제거합니다. 또한, 그리기 반복(draw loop)를 중지하고, 윈도우 전역 범위에서 선언된 속성이나 메소드의 구속력을 해제합니다. 새로운 p5 스케치를 만들고자 할 경우에는 변수 p5를 남겨둡니다. 원한다면 p5 = null로 처리하여 이를 제거할 수 있습니다. p5 라이브러리로 생성한 모든 함수, 변수, 그리고 객체가 제거되지만, 사용자가 코드로 생성한 여타 전역 변수들은 그대로 유지됩니다."
            +      ]
            +    },
            +    "disableFriendlyErrors": {
            +      "description": [
            +        "스케치를 만드는 동안 '친근한 에러 시스템 (Friendly Error System, FES)'을 필요시 비활성화하여 성능을 향상시킵니다. <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>친근한 에러 시스템 비활성화하기</a>에 더 자세히 기록되어 있습니다."
            +      ]
            +    },
            +    "let": {
            +      "description": [
            +        "새로운 변수를 생성하고 그 이름을 지정합니다. 변수는 값을 담는 컨테이너입니다.",
            +        "<a href=\"#/p5/let\">let</a>으로 선언된 변수는 블록 단위의 적용 범위를 갖습니다. 즉, 변수가 작성된 블록 내에서만 존재하고 사용될 수 있음을 뜻합니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let'>MDN Entry</a>에서 발췌: 블록 범위의 지역 변수를 선언하고, 선택적으로 그 값을 초기화합니다."
            +      ]
            +    },
            +    "const": {
            +      "description": [
            +        "새로운 상수를 생성하고 그 이름을 지정합니다. 마치 <a href=\"#/p5/let\">let</a>으로 생성된 변수처럼, <a href=\"#/p5/const\">const</a>로 생성된 상수는 값을 담는 컨테이너입니다. 하지만, 상수는 한 번 산언된 다음 변경할 수 없습니다.",
            +        "const로 선언된 상수는 블록 단위의 적용 범위를 갖습니다. 즉, 상수가 작성된 블록 내에서만 존재하고 사용될 수 있음을 뜻합니다. 상수는 자신이 존재하고 있는 범위 내에서 재선언될 수 없습니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/const'>MDN Entry</a>에서 발췌: 읽기만 가능한 상수를 선언합니다. const는 블록 단위로 적용되며, let으로 선언된 변수들과 유사합니다. 상수값은 재지정을 통해 변경될 수 없으며, 재선언될 수 없습니다."
            +      ]
            +    },
            +    "===": {
            +      "description": [
            +        "완전 항등 연산자 '===' 는 두 값이 같으면서 동시에 동일한 유형인지 여부를 확인합니다.",
            +        "비교 표현식은 항상 불리언으로 연산됩니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Comparison_Operators'>MDN Entry</a>에서 발췌: 이 연산자는 피연산자들이 동일한 값이 아니고/또는 동일한 유형이 아닐 때 참(true)을 반환합니다.",
            +        "웹상의 몇몇 예제에서 피연산자 간의 비교를 위해 이중 등호(==)를 사용하는 것을 볼 수 있습니다. 이는 자바스크립트상의 완전 항등 연산자(===)에 해당하지 않으며, 두 피연산자의 값들을 비교하기에 앞서, 그 유형이 동일한지의 여부를 비교하게 됩니다."
            +      ]
            +    },
            +    ">": {
            +      "description": [
            +        "비교 연산자 > 는 왼쪽 값이 오른쪽 값보다 큰 경우 참(true)으로 연산합니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Comparison_Operators'>MDN 발췌 비교 연산자 상세 설명은 여기에 있습니다.</a>"
            +      ]
            +    },
            +    ">=": {
            +      "description": [
            +        "비교 연산자 >= 는 왼쪽 값이 오른쪽 값보다 크거나 같은 경우 참(true)로 연산합니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Comparison_Operators'>MDN 발췌 비교 연산자 상세 설명은 여기에 있습니다.</a>",
            +        ""
            +      ]
            +    },
            +    "<": {
            +      "description": [
            +        "비교 연산자 < 는 왼쪽 값이 오른쪽 값보다 작은 경우 참(true)으로 연산합니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Comparison_Operators'>MDN 발췌 비교 연산자 상세 설명은 여기에 있습니다.</a>",
            +        ""
            +      ]
            +    },
            +    "<=": {
            +      "description": [
            +        "비교 연산자 <= 는 왼쪽 값이 오른쪽 값보다 작거나 같은 경우 참(true)로 연산합니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Comparison_Operators'>MDN 발췌 비교 연산자 상세 설명은 여기에 있습니다.</a>"
            +      ]
            +    },
            +    "if-else": {
            +      "description": [
            +        "if-else문으로 코드의 흐름을 제어할 수 있습니다.",
            +        "'if' 바로 다음 괄호 안에 조건을 지정할 수 있으며, 조건이 <a href = 'https://developer.mozilla.org/ko/docs/Glossary/truthy'>참(truthy)</a>으로 연산되면 뒤따른 중괄호 사이의 코드가 실행됩니다. 조건이 <a href = 'https://developer.mozilla.org/ko/docs/Glossary/Falsy'>거짓(falsy)</a>으로 연산되면 'else' 뒤에 오는 중괄호 사이의 코드가 대신 실행됩니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/if...else'>MDN Entry</a>에서 발췌: 지정된 조건이 참일 경우, if문은 명령문을 실행합니다. 조건이 거짓이면 다른 명령문을 실행할 수 잇습니다."
            +      ]
            +    },
            +    "function": {
            +      "description": [
            +        "새로운 <a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Functions'>함수 (function)</a>를 생성하고 함수명을 지정합니다. 함수란, 작업을 수행하는 일련의 명령문을 뜻합니다.",
            +        "선택적으로, 함수는 매개변수를 가질 수 있습니다.<a href = 'https://developer.mozilla.org/ko/docs/Glossary/Parameter'>매개변수(parameter)</a>란, 특정 함수에만 그 사용 범위가 지정된 변수를 뜻하며 함수 호출시 그 값을 지정할 수 있습니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/function'>MDN Entry</a>에서 발췌: 사용자가 지정한 매개변수를 사용하여 함수를 선언합니다."
            +      ]
            +    },
            +    "return": {
            +      "description": [
            +        "함수가 반환할 값을 지정합니다. <br><a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/return'>MDN Entry 발췌 함수(function) 상세 설명</a>"
            +      ]
            +    },
            +    "boolean": {
            +      "description": [
            +        "불리언 (boolean)은 자바스크립트에서 지정한 7개의 <a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures#Primitive_values'>기본 데이터 유형</a> 중 하나입니다. 불리언은 참(true) 또는 거짓(false)으로 값을 나타냅니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures#Boolean_type'>MDN Entry</a>에서 발췌: 불리언은 논리적 개체를 나타내며 참(true) 또는 거짓(false)이라는 두 개의 값만 갖습니다."
            +      ],
            +      "returns": "불리언: 특정 값의 불리언형 표식",
            +      "params": {
            +        "n": "문자열|불리언|숫자|배열[]: 분해할 값"
            +      }
            +    },
            +    "string": {
            +      "description": [
            +        "문자열(string)은 자바스크립트에서 지정한 7개의 <a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures#Primitive_values'>기본 데이터 유형</a> 중 하나입니다. 문자열은 일련의 텍스트 문자들을 뜻하며, 자바스크립트에서 문자열 값은 작은 따옴표나 큰따옴표로 묶여 표현됩니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Glossary/string'>MDN Entry</a>에서 발췌: 문자열은 텍스트를 나타낼 때 사용하는 일련의 문자들입니다."
            +      ]
            +    },
            +    "number": {
            +      "description": [
            +        "숫자(number)는 자바스크립트에서 지정한 7개의 <a href = 'https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures#Primitive_values'>기본 데이터 유형</a> 중 하나입니다. 숫자는 정수 또는 10진수로 표현됩니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Glossary/number'>MDN Entry 발췌 숫자(number) 상세 설명은 여기에 있습니다.</a>"
            +      ]
            +    },
            +    "object": {
            +      "description": [
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Basics'>MDN Entry 발췌 객체(object) 기초 설명</a>: 객체(object)는 데이터 그리고/또는 함수의 모음을 뜻합니다. 일반적으로 여러 개의 변수와 함수로 구성됩니다. 변수와 함수가 객체 안에 포함된 경우, 각각을 속성(property)과 메소드(method)라 부릅니다."
            +      ]
            +    },
            +    "class": {
            +      "description": [
            +        "클래스(class)를 생성하고 그 이름을 지정합니다. 클래스는 객체(object) 생성을 위한 하나의 템플릿입니다.",
            +        "<a href = 'https://developer.mozilla.org/ko/docs/Glossary/number'>MDN Entry</a>에서 발췌: 클래스 선언을 통해 새로운 Class를 생성합니다. 이 때, 새로운 Class의 이름은 프로토타입 기반 상속을 통해 지정됩니다."
            +      ]
            +    },
            +    "for": {
            +      "description": [
            +        "for문을 사용하여 특정 부분의 코드에 대한 반복문(loop)을 만듭니다.",
            +        "'for 반복문 (for loop)'은 괄호 속 3개의 다른 표현식들로 구성되며, 각각의 표현식은 모두 선택 사항입니다. 이 표현식들은 반복 실행(loop)의 횟수를 제어합니다. 1번째 표현식은 반복문의 초기 상태를 설정하는 명령문입니다. 2번째 표현식은 매 반복 실행에 앞서 조건 충족 여부를 확인합니다. 이 표현식이 거짓(false)를 반환하면 반복 실행이 종료됩니다. 3번째 표현식은 반복문의 가장 마지막 단계에 실행됩니다.",
            +        "for 반복문의 본문(중괄호 사이의 영역)에 포함된 코드는 2번째와 3번째 표현식의 연산과정 사이에 실행됩니다.",
            +        "여타 반복문과 마찬가지로, for 반복문 역시 반복이 '종료'되는 시점이나, 조건을 더이상 충족하지 않아 거짓(false)으로 연산되는 시점을 명시해야 합니다. 앞서 설명된 2번째 표현식을 통해, for 반복문의 조건이 거짓으로 연산되는 시점을 정할 수 있습니다. for반복문의 조건이 언젠가 거짓으로 처리되는 시점을 지정함으로써, 해당 반복문이 무한으로 실행되지 않도록 처리하기 위함입니다. 그렇지 않으면, 브라우저가 중단될 수 있습니다.",
            +        "<a href ='https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/for'>MDN Entry</a>에서 발췌: for 반복문은 조건이 거짓(false)으로 연산될 때까지 지정된 명령문을 실행합니다. 명령문을 실행한 후에는 조건 충족 여부를 다시 평가하여, 명령문이 최소 1번 실행되도록 합니다."
            +      ]
            +    },
            +    "while": {
            +      "description": [
            +        "while문을 사용하여 특정 부분의 코드에 대한 반복문(loop)을 만듭니다.",
            +        "'while 반복문(while loop)'을 사용하면, 소괄호 속 조건이 거짓(false)이 될 때까지 중괄호 속 본문의 코드가 반복적으로 실행됩니다. for 반복문과 달리, while 반복문은 그 본문 속 코드를 실행하기 앞서 조건 충족 여부를 먼저 확인합니다. 따라서, 최초 실행시 조건이 거짓일 경우, while문 속 본문과 명령문은 절대 실행되지 않습니다.",
            +        "여타 반복문과 마찬가지로, while 반복문 역시 반복이 '종료'되는 시점이나, 조건을 더이상 충족하지 않아 거짓(false)으로 연산되는 시점을 명시해야 합니다. while 반복문의 조건이 언젠가 거짓으로 처리되는 시점을 지정함으로써, 해당 반복문이 무한으로 실행되지 않도록 처리하기 위함입니다. 그렇지 않을 경우, 브라우저가 중단될 수 있습니다.",
            +        "<a href ='https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/while'>MDN Entry</a>에서 발췌: while 반복문은 조건이 참(true)인 경우에 한해 지정된 명령문을 실행합니다. 명령문 실행에 앞서 조건 충족 여부가 평가됩니다."
            +      ]
            +    },
            +    "createCanvas": {
            +      "description": [
            +        "캔버스를 생성하고 픽셀 단위로 크기를 설정합니다. <a href=\"#/p5/createCanvas\">createCanvas()</a>는 <a href=\"#/p5/setup\">setup()</a> 함수 시작시 단 한 번만 실행되어야 합니다. <a href=\"#/p5/createCanvas\">createCanvas()</a>를 한 번 이상 호출하면 스케치가 예기치 못한 반응을 보일 수 있습니다. 두 개 이상의 캔버스가 필요하다면 createGraphics()를 이용합니다.",
            +        "설정된 캔버스 사이즈는 시스템 변수인 너비(width)와 높이(height)에 각각 저장됩니다. <a href=\"#/p5/createCanvas\">createCanvas()</a> 함수를 생략하면, 스케치의 크기는 기본값인 100x100 픽셀로 지정됩니다.",
            +        "캔버스의 위치 지정 방법은 <a href = 'https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>캔버스 위치 지정하기</a> 위키 페이지에 있습니다."
            +      ],
            +      "returns": "p5.Renderer",
            +      "params": {
            +        "w": "숫자: 캔버스의 너비값",
            +        "h": "숫자: 캔버스의 높이값",
            +        "renderer": "상수: (선택 사항) P2D 또는 WEBGL"
            +      }
            +    },
            +    "resizeCanvas": {
            +      "description": [
            +        "사용자가 지정한 너비와 높이로 캔버스 크기를 재조정합니다. 이 함수를 사용하면 캔버스는 클리어되며, <a href=\"#/p5/draw\">draw()</a> 함수가 곧바로 호출되어 스케치를 재조정된 크기의 캔버스로 다시 렌더링되게 합니다."
            +      ],
            +      "params": {
            +        "w": "숫자: 캔버스의 너비값",
            +        "h": "숫자: 캔버스의 높이값",
            +        "noRedraw": "불리언: (선택 사항) 캔버스를 곧바로 다시 그리지 않도록 처리할지의 여부"
            +      }
            +    },
            +    "noCanvas": {
            +      "description": [
            +        "캔버스가 불필요한 p5 스케치를 위해 기본적으로 제공되는 캔버스를 제거합니다."
            +      ]
            +    },
            +    "createGraphics": {
            +      "description": [
            +        "새로운 p5.Renderer 객체를 생성하고 반환합니다. 화면 밖 그래픽 버퍼(off-screen graphic buffer)에 그리려면 이 클래스를 사용합니다. 2개의 매개변수는 너비와 높이를 픽셀 단위로 지정합니다."
            +      ],
            +      "returns": "p5.Graphics: 화면 밖 그래픽 버퍼",
            +      "params": {
            +        "w": "숫자: 화면 밖 그래픽 버퍼의 너비값",
            +        "h": "숫자: 화면 밖 그래픽 버퍼의 높이값",
            +        "renderer": "상수:P2D 또는 WEBGL, 기본값은 P2D"
            +      }
            +    },
            +    "blendMode": {
            +      "description": [
            +        "사용자가 지정한 모드에 따라 디스플레이 화면상의 픽셀들을 혼합합니다. 소스 픽셀 (A)를 디스플레이 화면 (B)상에 있는 픽셀과 혼합하기 위해 다음 모드를 선택할 수 있습니다:<br><ul><li><code>BLEND</code> - 색상 선형 보간:C = (A)*계수 + (B). 기본 혼합 모드입니다.</li><li><code>ADD</code> - (A)와 (B)의 합</li><li><code>DARKEST</code> - 가장 어두운 색상만 혼합됩니다:C = min(A*계수, B).</li><li><code>LIGHTEST </code> - 가장 밝은 색상만 혼합됩니다.:C = max(A*계수, B).</li><li><code>DIFFERENCE</code> - 기본 이미지에서 색상값을 뺄셈합니다.</li><li><code>EXCLUSION</code> - DIFFERENCE와 유사하지만 덜 극적입니다.</li><li><code>MULTIPLY</code> - 색상을 곱하는 것으로, 결과값은 좀 더 어둡습니다.</li><li><code>SCREEN</code> - MULTIPLY와 반대로 색상의 반전된 값을 사용합니다.</li><li><code>REPLACE</code> - 픽셀이 다른 픽셀을 완전히 대체하며 알파값(투명도)를 사용하지 않습니다.</li><li><code>OVERLAY</code> - MULTIPLY와 SCREEN의 혼합으로, 어두운 값을 곱하고 밝은 값의 반전된 값을 사용합니다. (2D)</li><li><code>HARD_LIGHT</code> - 회색값이 50%보다 높으면 SCREEN로, 낮으면 MULTIPLY로 처리합니다. (2D)</li><li><code>SOFT_LIGHT</code> - DARKEST와 LIGHTEST 혼합으로, OVERLAY처럼 작동하나 덜 강합니다. (2D)</li><li><code>DODGE</code> - 밝은 색조를 더 밝게 처리하고 대비를 높이며, 어두운 영역은 무시합니다. (2D)</li><li><code>BURN</code> - 어두운 영역이 적용되어 대비가 증가하고 밝기는 무시됩니다. (2D)</li><li><code>SUBTRACT</code> - (A)와 (B)의 나머지(3D)</li></ul>",
            +        "<em>(2D)</em>는 2D 렌더러에서만 작동하는 혼합 모드를 뜻합니다.",
            +        "<em>(3D)</em>는 WEBGL 렌더러에서만 작동하는 혼합 모드를 뜻합니다.",
            +        ""
            +      ],
            +      "params": {
            +        "mode": "상수:캔버스에 설정되는 혼합 모드. BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN, ADD, REMOVE 또는 SUBTRACT 중 하나"
            +      }
            +    },
            +    "drawingContext": {
            +      "description": [
            +        "p5.js API는 다양한 그래픽 제작 기능들을 제공하지만, p5에 노출되지 않는 HTML5 고유의 캔버스 기능이 있습니다. 그러한 기능들은 예제처럼 drawingContext 변수를 사용하여 직접 호출할 수 있습니다. 이는 canvas.getContext('2d') 또는 canvas.getContext('webgl') 함수를 호출하는 것과도 같습니다. 호출 가능한 함수는 <a href ='https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D'>기본 캔버스 API 레퍼런스</a>에 있습니다."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "p5.js가 <a href=\"#/p5/draw\">draw()</a> 함수 안에 포함된 코드를 계속 실행하지 않도록 합니다. loop() 함수가 호출될 경우, <a href=\"#/p5/draw\">draw()</a> 함수 안의 코드가 다시 계속 실행 됩니다. <a href=\"#/p5/setup\">setup()</a> 함수 안에 <a href=\"#/p5/noLoop\">noLoop()</a> 함수를 사용할 경우, <a href=\"#/p5/setup\">setup()</a> 함수 블록의 가장 마지막 줄에 작성합니다.",
            +        "<a href=\"#/p5/noLoop\">noLoop()</a>을 사용하면, mousePressed()나 keyPressed()와 같은 이벤트 처리 함수를 통해 화면에 접근하거나 조정할 수 없습니다. 대신,  <a href=\"#/p5/redraw\">redraw()</a>나 loop() 함수들을 이용하여, 화면 업데이트 함수인 <a href=\"#/p5/draw\">draw()</a>를 재실행시켜 이벤트 처리 함수를 실행할 수 있습니다. 다시 말해, <a href=\"#/p5/noLoop\">noLoop()</a> 함수가 호출된다는 것은 <a href=\"#/p5/draw\">draw()</a>가 실행되지 않으며, <a href=\"#/p5/saveFrames\">saveFrames()</a>이나 <a href=\"#/p5/loadPixels\">loadPixels()</a>와 같은 함수 역시 사용할 수 없음을 뜻합니다.",
            +        "스케치 크기를 재조정하면, <a href=\"#/p5/noLoop\">noLoop()</a> 함수가 호출되지 않더라도 <a href=\"#/p5/redraw\">redraw()</a>가 호출되어 스케치를 업데이트하는 점에 유의해야 합니다. 그렇지 않으면, 스케치는 <a href=\"#/p5/loop\">loop()</a>가 호출될 때까지 예기치 못한 반응을 보일 수 있습니다.",
            +        "loop()의 상태를 확인할 때 <a href=\"#/p5/isLooping\">isLooping()</a>를 사용합니다."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "기본적으로 p5.js는 <a href=\"#/p5/draw\">draw()</a> 함수 안에 포함된 코드를 계속해서 반복 실행(loop)합니다. 하지만 <a href=\"#/p5/draw\">draw()</a> 함수의 반복 실행 기능은 <a href=\"#/p5/noLoop\">noLoop()</a> 함수를 통해 중단할 수 있습니다. 이때 <a href=\"#/p5/draw\">draw()</a>의 반복 실행 기능은 loop() 함수를 통해 재개할 수 있습니다.",
            +        "<a href=\"#/p5/setup\">setup()</a> 함수 안에서 loop()의 사용을 권장하지 않습니다.",
            +        "loop()의 상태를 확인할 때 <a href=\"#/p5/isLooping\">isLooping()</a>를 사용합니다."
            +      ]
            +    },
            +    "isLooping": {
            +      "description": [
            +        "기본적으로 p5.js는 <a href=\"#/p5/draw\">draw()</a> 함수 안에 포함된 코드를 계속해서 반복 실행(loop)합니다. 하지만 <a href=\"#/p5/draw\">draw()</a> 함수의 반복 실행 기능은 <a href=\"#/p5/noLoop\">noLoop()</a> 함수를 통해 중단할 수 있고 <a href=\"#/p5/draw\">draw()</a>의 반복 실행 기능은 loop() 함수를 통해 재개할 수 있습니다. 이때 isLooping()은 현재 상태를 반환합니다."
            +      ]
            +    },
            +    "push": {
            +      "description": [
            +        "push() 함수는 현재의 드로잉 스타일 설정과 변형을 저장하고, pop() 함수는 이 설정들을 복구합니다. 이 함수들은 항상 함께 쓰이는 점에 유의해야 합니다. 이 함수들을 통해 스타일과 변형 설정을 변경한 뒤에도 이전 설정 상태로 돌아갈 수 있습니다. push()와 pop() 함수들은 설정 사항에 대해 좀 더 많은 권한을 제공합니다. (두 번째 예제를 참고)",
            +        "push()는 다음의 함수들을 통해 지정된 현재 변형 상태 및 스타일 설정 사항을 저장합니다: fill(), noFill(), noStroke(), stroke(), tint(), noTint(), strokeWeight(), strokeCap(), strokeJoin(), imageMode(), rectMode(), ellipseMode(), colorMode(), textAlign(), textFont(), textSize(), textLeading(), applyMatrix(), resetMatrix(), rotate(), scale(), shearX(), shearY(), translate(), noiseSeed().",
            +        "WebGL 모드에서는 다음의 함수들을 통해 지정된, 더욱 다양한 스타일 설정 사항이 저장될 수 있습니다:  setCamera(), ambientLight(), directionalLight(), pointLight(), texture(), specularMaterial(), shininess(), normalMaterial(), 그리고 shader()",
            +        "",
            +        ""
            +      ]
            +    },
            +    "pop": {
            +      "description": [
            +        "push() 함수는 현재의 드로잉 스타일 설정과 변형을 저장하고, pop() 함수는 이 설정들을 복구합니다. 이 함수들은 항상 함께 쓰이는 점에 유의해야 합니다. 이 함수들을 통해 스타일과 변형 설정을 변경한 뒤에도 이전 설정 상태로 돌아갈 수 있습니다. push()와 pop() 함수들은 설정 사항에 대해 좀 더 많은 권한을 제공합니다. (두 번째 예제.)",
            +        "push()는 다음의 함수들을 통해 지정된 현재 변형 상태 및 스타일 설정 사항을 저장합니다: fill(), noFill(), noStroke(), stroke(), tint(), noTint(), strokeWeight(), strokeCap(), strokeJoin(), imageMode(), rectMode(), ellipseMode(), colorMode(), textAlign(), textFont(), textSize(), textLeading(), applyMatrix(), resetMatrix(), rotate(), scale(), shearX(), shearY(), translate(), noiseSeed().",
            +        "WebGL 모드에서는 다음의 함수들을 통해 지정된, 더욱 다양한 스타일 설정 사항이 저장될 수 있습니다:  setCamera(), ambientLight(), directionalLight(), pointLight(), texture(), specularMaterial(), shininess(), normalMaterial(), 그리고 shader()",
            +        "",
            +        ""
            +      ]
            +    },
            +    "redraw": {
            +      "description": [
            +        "<a href=\"#/p5/draw\">draw()</a> 함수 안에 포함된 코드를 한 번 재실행합니다. 이 함수를 통해 필요시에만 화면을 업데이트할 수 있습니다. mousePressed()나 keyPressed()가 지정한 이벤트를 발생시킬 때가 그 예입니다.",
            +        "프로그램의 구조를 고려하면, mousePressed()와 같은 이벤트 함수에 <a href=\"#/p5/redraw\">redraw()</a>를 호출하는 것이 좋습니다. 이는 <a href=\"#/p5/redraw\">redraw()</a>가 <a href=\"#/p5/draw\">draw()</a>함수를 즉각적으로 실행시키지 않기 때문입니다. <a href=\"#/p5/redraw\">redraw()</a>는 화면 업데이트가 필요함을 알리는 표식 설정만합니다.",
            +        "",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "n": "정수: (선택 사항) n번 간 <a href=\"#/p5/redraw\">redraw()</a> 함수 실행. 기본값은 1"
            +      }
            +    },
            +    "p5": {
            +      "description": [
            +        "p5() 생성자로 전역 모드 대신 인스턴스 모드를 활성화할 수 있습니다. 이는 고급 활용 사례에 해당합니다. 간단한 설명과 예제가 아래에 있습니다. 자세한 내용은 다니엘 쉬프만(Dan Shiffman)의 <a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">코딩 트레인(Coding Train) 비디오 튜토리얼</a> 또는 <a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">이 페이지</a>에 있습니다.",
            +        "기본적으로 모든 p5.js 함수들은 전역 네임스페이스에 속합니다. (즉, 화면창 객체에 구속됩니다.) 이는, p5.js 함수들을 ellipse(), fill()과 같은 이름으로 불러올 수 있음을 뜻합니다. 하지만, 이러한 방식은 자바스크립트의 여타 (동기식 또는 비동기식) 라이브러리를 사용하거나 긴 코딩을 작성할 때 다소 불편할 수 있습니다. 따라서, p5.js는 인스턴스 모드를 통해 이 문제를 해결할 수 있는 방법을 지원합니다. 인스턴스 모드에서는 모든 p5 함수의 전역 네임 스페이스를 오염시키는 대신, 이를 단일 변수에 구속되게 만듭니다.",
            +        "선택적으로 캔버스나 다른 요소에 추가할 두 번째 인수로서 기본 컨테이너를 지정할 수 있습니다. HTML상 요소의 id나 노드 자체를 추가(append)할 수 있습니다.",
            +        "이처럼 인스턴스를 만들면, 단일 웹페이지에 두 개 이상의 p5 스케치를 사용할 수 있게 됩니다. 각각의 고유한 설정 변수에 의거하기 때문입니다. 물론, 전역 모드에서도 iframe 기능을 이용하면 복수의 스케치를 웹페이지에 사용할 수 있습니다."
            +      ],
            +      "params": {
            +        "sketch": "객체: p5.js 스케치를 포함하는 함수",
            +        "node": "문자열|객체: 스케치를 포함할 HTML DOM 노드 ID 또는 포인터"
            +      }
            +    },
            +    "applyMatrix": {
            +      "description": [
            +        "현재 행렬(matrix)에 매개변수로 지정된 행렬을 곱합니다. 평행 이동과 같은 연속 이동(translate), 크기 조정(scale), 전단(shear), 회전(rotate)을 한 번에 수행할 수 있습니다. <a href='https://ko.wikipedia.org/wiki/%EB%B3%80%ED%99%98%ED%96%89%EB%A0%AC'>변환행렬 위키피디아</a>에서 더 많은 정보를 확인할 수 있습니다.",
            +        "이 때, 인수들은 <a href='https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform'>WHATWG 사양</a>에 따라 그 이름이 지정되며, 다음과 같은 형식의 변환 행렬에 상응합니다:<blockquote><p><img style='max-width: 150px' src='assets/transformation-matrix.png' alt='applyMatrix() 함수 호출시 사용되는 변환 행렬'></p></blockquote>",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "a": "숫자: 곱할 2x3 행렬 정의",
            +        "b": "숫자: 곱할 2x3 행렬 정의",
            +        "c": "숫자: 곱할 2x3 행렬 정의",
            +        "d": "숫자: 곱할 2x3 행렬 정의",
            +        "e": "숫자: 곱할 2x3 행렬 정의",
            +        "f": "숫자: 곱할 2x3 행렬 정의"
            +      }
            +    },
            +    "resetMatrix": {
            +      "description": [
            +        "현재 행렬을 항등 행렬로 바꿉니다."
            +      ]
            +    },
            +    "rotate": {
            +      "description": [
            +        "사용자가 지정한 각도 매개변수에 따라 도형을 회전합니다. 이 함수는 angleMode() 함수의 영향을 받으며, 괄호 안에 RADIANS 또는 DEGREES를 입력하여  각도가 해석되는 방식을 지정할 수 있습니다.",
            +        "객체는 항상 원점에 대한 상대적 위치를 중심으로 회전하며, 양수를 입력할 경우 시계 방향으로 객체를 회전합니다. 이러한 변형(transformation) 함수는 그것이 호출된 뒤 후속적으로 호출된 모든 변형 함수들에 적용됩니다. 예를 들어, rotate(HALF_PI)를 호출한 뒤 rotate(HALF_PI)를 호출하면, 결과적으로 rotate(PI)와 동일한 효과를 갖습니다. 모든 변형은 <a href=\"#/p5/draw\">draw()</a> 함수가 다시 시작하는 시점에 리셋됩니다.",
            +        "좀 더 기술적으로 설명하자면, rotate() 함수는 현재 변환 행렬에 회전 행렬을 곱하는 셈입니다. 이 함수는 push()와 pop() 함수를 통해 추가적으로 제어 가능합니다.",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "angle": "숫자: 현재 angleMode의 매개변수인 RADIANS(라디안) 또는 DEGREES(도)의 설정 사항에 따른 회전각",
            +        "axis": "p5.Vector|숫자 배열[]: (선택 사항) 3D의 경우, 회전축"
            +      }
            +    },
            +    "rotateX": {
            +      "description": [
            +        "x축을 따라 회전합니다."
            +      ],
            +      "params": {
            +        "angle": "숫자: 현재 angleMode의 매개변수인 RADIANS(라디안) 또는 DEGREES(도)의 설정 사항에 따른 회전각"
            +      }
            +    },
            +    "rotateY": {
            +      "description": [
            +        "y축을 따라 회전합니다."
            +      ],
            +      "params": {
            +        "angle": "숫자: 현재 angleMode의 매개변수인 RADIANS(라디안) 또는 DEGREES(도)의 설정 사항에 따른 회전각"
            +      }
            +    },
            +    "rotateZ": {
            +      "description": [
            +        "z축을 따라 회전합니다. (WebGL 모드 전용)",
            +        "This method works in WEBGL mode only.",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "숫자: 현재 angleMode의 매개변수인 RADIANS(라디안) 또는 DEGREES(도)의 설정 사항에 따른 회전각"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "꼭짓점을 확장하거나 축소하여 도형의 크기를 키우거나 줄입니다. 객체의 크기는 언제나 좌표계에 대한 상대적 원점을 기준으로 조정됩니다. 크기값들은 10진수 백분율로 지정됩니다. 예를 들어, scale(2.0) 함수를 호출하면 도형의 크기를 200% 증가시킵니다.",
            +        "이러한 변형(transformation) 함수는 호출된 뒤 후속적으로 호출된 모든 변형 함수들에 적용됩니다. 예를 들어, scale(2.0)을 호출한 뒤 scale(1.5)를 호출하면, 결과적으로 scale(3.0)과 동일한 효과를 갖습니다. 모든 변형은 <a href=\"#/p5/draw\">draw()</a> 함수가 다시 시작하는 시점에 리셋됩니다.",
            +        "매개변수 z는 오직 WebGL 모드에서만 사용 가능합니다. 이 함수는 push()와 pop() 함수를 통해 추가적으로 제어 가능합니다.",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "s": "숫자|p5.Vector|숫자 배열[]:객체 크기를 조정하는 백분율, 또는 여러 인수를 지정할 경우 x축에서의 객체 크기 배율을 조정하는 백분율",
            +        "y": "숫자: (선택 사항) y축에서의 객체 크기를 조정하는 백분율",
            +        "z": "숫자: (선택 사항) z축에서의 객체 크기를 조정하는 백분율 (WebGL 모드용)",
            +        "scales": "p5.Vector|숫자 배열[]: 축을 기준으로 객체의 크기 조정"
            +      }
            +    },
            +    "shearX": {
            +      "description": [
            +        "사용자가 지정한 각도 매개변수에 따라 도형을 x축에서 전단(shear)합니다. 이 함수는 angleMode() 함수의 영향을 받습니다. 객체는 항상 원점에 대한 상대적 위치를 중심으로 전단되며, 양수를 입력할 경우 시계 방향으로 객체를 전단합니다.",
            +        "이러한 변형(transformation) 함수는  호출된 뒤 후속적으로 호출된 모든 변형 함수들에 적용되어, 그 효과들이 누적됩니다. 예를 들어, shearX(PI/2)를 호출한 뒤 shearX(PI/2)를 또 호출하면, 결과적으로 shearX(PI)와 동일한 효과를 갖습니다. <a href=\"#/p5/draw\">draw()</a> 함수 내에서 shearX()를 호출하면, 반복 실행이 다시 시작되는 시점에 모든 변형 내용이 리셋됩니다.",
            +        "보다 기술적으로 설명하자면, shearX() 함수는 현재 변환 행렬에 회전 행렬을 곱하는 셈입니다. 이 함수는 push()와 pop() 함수를 통해 추가적으로 제어 가능합니다.",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "angle": "숫자: 현재 angleMode의 매개변수인 RADIANS(라디안) 또는 DEGREES(도)의 설정 사항에 따른 전단각"
            +      }
            +    },
            +    "shearY": {
            +      "description": [
            +        "사용자가 지정한 각도 매개변수에 따라 도형을 y축에서 전단(shear)합니다. 이 함수는 angleMode() 함수의 영향을 받습니다. 객체는 항상 원점에 대한 상대적 위치를 중심으로 전단되며, 양수를 입력할 경우 시계 방향으로 객체를 전단합니다.",
            +        "이러한 변형(transformation) 함수는 호출된 뒤 후속적으로 호출된 모든 변형 함수들에 적용되어, 그 효과들이 누적됩니다. 예를 들어, shearY(PI/2)를 호출한 뒤 shearY(PI/2)를 또 호출하면, 결과적으로 shearY(PI)와 동일한 효과를 갖습니다. <a href=\"#/p5/draw\">draw()</a> 함수 내에서 shearY()를 호출하면, 반복 실행이 다시 시작되는 시점에 모든 변형 내용이 리셋됩니다.",
            +        "보다 기술적으로 설명하자면, shearY() 함수는 현재 변환 행렬에 회전 행렬을 곱하는 셈입니다. 이 함수는 push()와 pop() 함수를 통해 추가적으로 제어 가능합니다.",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "angle": "숫자: 현재 angleMode의 매개변수인 RADIANS(라디안) 또는 DEGREES(도)의 설정 사항에 따른 전단각"
            +      }
            +    },
            +    "translate": {
            +      "description": [
            +        "디스플레이 화면 내에서 객체를 이동시킬 정도를 지정합니다. 매개변수 x는 좌/우 이동을, 매개변수 y는 상/하 이동을 지정합니다.",
            +        "이러한 변형(transformation) 함수는 호출된 뒤 후속적으로 호출된 모든 변형 함수들에 적용되어, 그 효과들이 누적됩니다. 예를 들어, translate(50, 0)를 호출한 뒤 translate(20, 0)를 또 호출하면, 결과적으로 translate(70, 0)와 동일한 효과를 갖습니다. <a href=\"#/p5/draw\">draw()</a> 함수 내에서 translate()을 호출하면, 반복 실행이 다시 시작되는 시점에 모든 변형 내용이 리셋됩니다.",
            +        "이 함수는 push()와 pop() 함수를 통해 추가적으로 제어 가능합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 좌/우 이동",
            +        "y": "숫자: 상/하 이동",
            +        "z": "숫자: 앞/뒤 이동 (WebGL 모드용)",
            +        "vector": "p5.Vector: 이동시킬 벡터"
            +      }
            +    },
            +    "storeItem": {
            +      "description": [
            +        "로컬 저장소에 값을 키 이름(key name)으로 저장합니다. 로컬 저장소는 브라우저에 저장되며, 브라우징 세션과 페이지를 다시 불러오는 사이에 유지됩니다. 키(key)는 변수명과 동일하게 지정될 수 있으나, 반드시 그럴 필요는 없습니다. 저장된 항목(item)을 가져오는 방법은 <a href = 'https://p5js.org/reference/#/p5/getItem'>getItem</a>에 있습니다.",
            +        "비밀번호나 개인 정보와같이 민감한 데이터는 로컬 저장소에 저장되면 안됩니다."
            +      ],
            +      "params": {
            +        "key": "문자열:",
            +        "value": "문자열|숫자|객체|불리언|p5.Color|p5.Vector:"
            +      }
            +    },
            +    "getItem": {
            +      "description": [
            +        "storeItem()로 저장한 항목(item)의 값을 로컬 저장소로부터 반환합니다."
            +      ],
            +      "returns": "숫자|객체|문자열|불리언|p5.Color|p5.Vector: 저장된 항목의 값",
            +      "params": {
            +        "key": "문자열: 로컬 저장소에 저장시 사용할 이름"
            +      }
            +    },
            +    "clearStorage": {
            +      "description": [
            +        "현재 영역에서 storeItem()으로 설정된 모든 로컬 저장소 항목(item)을 제거합니다."
            +      ]
            +    },
            +    "removeItem": {
            +      "description": [
            +        "storeItem()으로 저장된 항목(item)을 제거합니다."
            +      ],
            +      "params": {
            +        "key": "문자열"
            +      }
            +    },
            +    "createStringDict": {
            +      "description": [
            +        "키-값(key-value) 쌍 또는 사용자가 지정한 객체를 사용하여 p5.StringDict의 새로운 인스턴스를 생성합니다."
            +      ],
            +      "returns": "p5.StringDict:",
            +      "params": {
            +        "key": "문자열:",
            +        "value": "문자열:",
            +        "object": "객체: 객체"
            +      }
            +    },
            +    "createNumberDict": {
            +      "description": [
            +        "키-값(key-value) 쌍 또는 사용자가 지정한 객체를 사용하여 p5.NumberDict의 새로운 인스턴스를 생성합니다."
            +      ],
            +      "returns": "p5.NumberDict:",
            +      "params": {
            +        "key": "숫자:",
            +        "value": "숫자",
            +        "object": "객체: 객체"
            +      }
            +    },
            +    "select": {
            +      "description": [
            +        "지정한 ID, 클래스, 또는 태그 이름(접두어 '#'로 ID를, '.'로 클래스 지정 가능, 태그는 별도의 접두어 없음)에 해당하는 요소를 페이지 내에서 검색하고, p5.Element를 반환합니다. 클래스나 태그의 이름이 2개 이상의 요소로 지정된 경우, 1번째 요소만 반환됩니다. 문서 객체 모델 (DOM) 노드는 .elt로 검섹할 수 있습니다. 아무 것도 검색되지 않을 경우 null을 반환합니다. 검색할 컨테이너를 별도로 지정할 수 있습니다."
            +      ],
            +      "returns": "검색된 노드를 포함한 p5.Element",
            +      "params": {
            +        "selectors": "문자열: 찾을 요소의 CSS 선택 문자열 (selector string)",
            +        "container": "문자열|p5.Element|HTML 요소: (선택 사항) id, p5.Element, 또는 HTML 요소 내에서 검색"
            +      }
            +    },
            +    "selectAll": {
            +      "description": [
            +        "지정한 클래스 또는 태그 이름('.'로 클래스 지정 가능, 태그는 별도의 접두어 없음)에 해당하는 요소를 페이지 내에서 검색하고, p5.Element 배열로 반환합니다. 문서 객체 모델 (DOM) 노드는 .elt로 검색할 수 있습니다. 아무 것도 검색되지 않을 경우 빈 배열을 반환합니다. 검색할 컨테이너를 별도로 지정할 수 있습니다."
            +      ],
            +      "returns": "검색된 노드를 포함한 p5.Element 배열",
            +      "params": {
            +        "selectors": "문자열: 찾을 요소의 CSS 선택 문자열 (selector string)",
            +        "container": "문자열: (선택 사항) id, p5.Element, 또는 HTML 요소 내에서 검색"
            +      }
            +    },
            +    "removeElements": {
            +      "description": [
            +        "createCanvase() 또는 createGraphics()로 생성된 캔버스와 그래픽을 제외하고, p5로 생성된 모든 요소를 제거합니다. 이벤트 핸들러 역시 제거되며, 요소가 문서 객체 모델 (DOM)에서 제거됩니다."
            +      ]
            +    },
            +    "changed": {
            +      "description": [
            +        ".changed() 함수는 요소값이 변경될 때 호출됩니다. 특정 요소의 이벤트 리스너와 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 요소값이 변경될 때 발생하는 함수. 거짓(false)이 전달되면 이전 실행 함수는 더이상 실행 불가"
            +      }
            +    },
            +    "input": {
            +      "description": [
            +        ".input() 함수는 요소가 사용자 입력을 감지할 때 호출됩니다. 입력 이벤트는 키 또는 슬라이더 요소의 변경을 감지합니다. 특정 요소의 이벤트 리스너와 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 요소가 사용자 입력을 감지할 때 발생하는 함수. 거짓(false)이 전달되면 이전 실행 함수는 더이상 실행 불가"
            +      }
            +    },
            +    "createDiv": {
            +      "description": [
            +        "주어진 내부 HTML을 사용하여 문서 객체 모델 (DOM)에 <div></div> 요소를 생성합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "html": "문자열: (선택 사항) 요소를 생성한 내부 HTML"
            +      }
            +    },
            +    "createP": {
            +      "description": [
            +        "주어진 내부 HTML을 사용하여 문서 객체 모델 (DOM)에 <p></p> 요소를 생성합니다. 문단형 텍스트 작성시 사용됩니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "html": "문자열: (선택 사항) 요소를 생성한 내부 HTML"
            +      }
            +    },
            +    "createSpan": {
            +      "description": [
            +        "주어진 내부 HTML을 사용하여 문서 객체 모델 (DOM)에 <span></span> 요소를 생성합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "html": "문자열: (선택 사항) 요소를 생성한 내부 HTML"
            +      }
            +    },
            +    "createImg": {
            +      "description": [
            +        "주어진 src와 대체 텍스트(alt text)를 사용하여 문서 객체 모델 (DOM)에 <img> 요소를 생성합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "src": "문자열: 이미지의 src 또는 url 경로",
            +        "alt": "문자열: 이미지가 로드되지 않을 경우 사용할 <a href='https://developer.mozilla.org/ko/docs/Web/HTML/Element/Img#Attributes'>대체 텍스트</a>. 빈 문자열(\" \")로 이미지 숨기기 가능",
            +        "crossOrigin": "문자열: img 요소의 <a href='https://developer.mozilla.org/ko/docs/Web/HTML/Attributes/crossorigin'>교차 출처 속성(crossOrigin property)</a>. '익명(anonymous)' 또는 '사용 자격 증명(use-credentials)'을 통해 교차 출처 권한이 있는 이미지를 검색할 수 있습니다. 이는 캔버스에 이미지를 사용하기 위함이며, 빈 문자열(\" \")이 전달된 경우 교차 출처 리소스 공유(CORS)는 사용되지 않습니다.",
            +        "successCallback": "함수: (선택 사항) 인수로 지정된 p5.Element가 이미지 데이터를 불러왔을 때 호출되는 콜백 함수"
            +      }
            +    },
            +    "createA": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 하이퍼링크를 포함한 <a></a> 요소를 생성합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "href": "문자열: 링크될 페이지 url",
            +        "html": "문자열: 화면에 보여질 링크 요소의 내부 HTML",
            +        "target": "문자열: (선택 사항) 새로운 링크가 보여질 대상, _blank, _self, _parent, _top 중 지정 가능"
            +      }
            +    },
            +    "createSlider": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 슬라이더 <input></input> 요소를 생성합니다. .size() 함수로 슬라이더의 길이를 설정합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "min": "숫자: 슬라이더의 최소값",
            +        "max": "숫자: 슬라이더의 최대값",
            +        "value": "숫자: (선택 사항) 슬라이더의 기본값",
            +        "step": "숫자: (선택 사항) 슬라이더의 단위당 이동 크기(이동 크기가 0으로 지정된 경우, 슬라이더는 최소값과 최대값 사이를 부드럽게 이동합니다.)"
            +      }
            +    },
            +    "createButton": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 <button></button> 요소를 생성합니다. .size() 함수로 버튼의 크기를 설정합니다. .mousePressed() 함수로 버튼이 클릭됐을 때의 행동을 지정합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "label": "문자열: 버튼 위에 나타나는 레이블",
            +        "value": "문자열: (선택 사항) 버튼값"
            +      }
            +    },
            +    "createCheckbox": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 체크박스<input></input> 요소를 생성합니다. .checked() 함수를 통해 체크되었는지의 여부를 반환합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "label": "문자열: (선택 사항) 체크박스 위에 나타나는 레이블",
            +        "value": "불리언: (선택 사항) 체크박스의 값. 체크는 참(true), 체크 해제는 거짓(false)"
            +      }
            +    },
            +    "createSelect": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 드롭다운 메뉴<select></select> 요소를 생성합니다. 이미 생성된 셀렉트 박스(select box)를 선택할 경우, p5.Element에 select-box 메소드를 지정하는 데에도 쓰입니다. 셀렉트 박스 생성 후, .option() 메소드로 선택지(option)를 설정할 수 있습니다. .selected() 메소드는 p5.Element 인스턴스인 현재 드롭다운 요소를 반환합니다. .selected() 메소드는 특정 선택지를 최초 페이지 로드시의 기본값으로서 설정할 수 있습니다. .disable() 메소드는 특정 선택지를 비활성화하고, 별도로 지정된 인수가 없는 경우엔 전체 드롭다운 요소를 비활성화 상태로 표시합니다."
            +      ],
            +      "returns": "p5.Element",
            +      "params": {
            +        "multiple": "불리언: (선택 사항) 드롭다운이 여러 개의 선택지를 제공할 경우 참(true)",
            +        "existing": "객체: 문서 객체 모델 셀렉트 요소"
            +      }
            +    },
            +    "createRadio": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 라디오 버튼<input></input> 요소를 생성합니다. 라디오 버튼 생성 후, .option() 메소드로 옵션을 설정할 수 있습니다. .value() 메소드는 현재 선택된 옵션을 반환합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "containerElement": "객체: 옵션으로 설정 될 모든 라디오 입력소들이 있는 div 또는 span의 HTML 컨테인어.",
            +        "name": "문자열: (선택 사항) 각 입력 요소의 매개변수 명."
            +      }
            +    },
            +    "createColorPicker": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 색상 입력을 위한 색상 추출(colorPicker) 요소를 생성합니다. .value() 메소드는 색상의 헥사(Hex) 문자열(#rrggbb)을 반환합니다. .color() 메소드는 현재 선택된 색상의 p5.Color 객체를 반환합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "value": "문자열|p5.Color: (선택 사항) 요소의 색상 기본값"
            +      }
            +    },
            +    "createInput": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 텍스트 입력을 위한 <input></input> 요소를 생성합니다. .size() 함수로 상자의 크기를 설정합니다."
            +      ],
            +      "returns": "p5.Element: 생성된 노드를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "value": "문자열: (선택 사항) 입력 상자의 기본값",
            +        "type": "문자열: (선택 사항) 텍스트 유형 (예: text, password 등) 기본값은 text"
            +      }
            +    },
            +    "createFileInput": {
            +      "description": [
            +        "'파일(file)' 유형의 문서 객체 모델 (DOM)에 <input></input> 요소를 생성합니다. 스케치에 사용할 로컬 파일을 선택할 수 있게 됩니다."
            +      ],
            +      "returns": "p5.Element: 생성된 DOM 요소를 담고있는 p5.Element에 대한 포인터",
            +      "params": {
            +        "callback": "함수: (선택 사항) 파일이 로드될 때의 콜백 함수",
            +        "multiple": "문자열: (선택 사항) 여러 파일 선택 허용"
            +      }
            +    },
            +    "createVideo": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 간단한 오디오/비디오 재생을 위한 HTML5 <video> 요소를 생성합니다. 화면에 나타나기가 기본값이며, .hide()로 숨길 수 있습니다. video() 함수를 통해 캔버스에 그릴 수 있습니다. 1번째 매개변수는 비디오 파일에 대한 단일 문자열 경로이거나, 또는 동일한 비디오 파일이 여러 개의 형식을 갖는 경우, 문자열 경로들의 배열로 지정됩니다. 특히, 다양한 파일 형식을 지정하여 여러 종류의 브라우저에서 재생될 수 있도록 하는 데에 용이합니다. 지원되는 파일 형식에 대한 자세한 내용은 <a href = 'https://developer.mozilla.org/ko/docs/Web/Media/Formats'>이 페이지</a>에 있습니다."
            +      ],
            +      "returns": "p5.MediaElement: 비디오 p5.Element에 대한 포인터",
            +      "params": {
            +        "src": "문자열|문자열 배열[]: 비디오 파일 경로, 또는 경로들의 배열(여러 종류의 브라우저 지원)",
            +        "callback": "함수: (선택 사항) 브라우저의 미디어 재생가능 상태를 뜻하는, 'canplaythrough' 이벤트 발생시에 호출되는 함수. 추가 버퍼링 없이도, 미디어를 끝까지 재생할 수 있는 충분한 데이터가 로드된 것으로 평가."
            +      }
            +    },
            +    "createAudio": {
            +      "description": [
            +        "문서 객체 모델 (DOM)에 간단한 오디오 재생을 위한 HTML5 <audio> 요소를 생성합니다. 1번째 매개변수는 오디오 파일에 대한 단일 문자열 경로이거나, 또는 동일한 오디오 파일이 여러 개의 형식을 갖는 경우, 문자열 경로들의 배열로 지정됩니다. 특히, 다양한 파일 형식을 지정하여 여러 종류의 브라우저에서 재생될 수 있도록 하는 데에 용이합니다. 지원되는 파일 형식에 대한 자세한 내용은 <a href = 'https://developer.mozilla.org/ko/docs/Web/Media/Formats'>이 페이지</a>에 있습니다."
            +      ],
            +      "returns": "p5.MediaElement: 오디오 p5.Element에 대한 포인터",
            +      "params": {
            +        "src": "문자열|문자열 배열[]: 오디오 파일 경로, 또는 경로들의 배열(여러 종류의 브라우저 지원)",
            +        "callback": "함수: (선택 사항) 브라우저의 미디어 재생가능 상태를 뜻하는, 'canplaythrough' 이벤트 발생시에 호출되는 함수. 추가 버퍼링 없이도, 미디어를 끝까지 재생할 수 있는 충분한 데이터가 로드된 것으로 평가."
            +      }
            +    },
            +    "VIDEO": {},
            +    "AUDIO": {},
            +    "createCapture": {
            +      "description": [
            +        "웹캠의 오디오/비디오 피드를 담는 <video> 요소를 생성합니다. 이 요소는 캔버스와는 별개로 작동합니다. '화면에 나타내기'가 기본값으로 주어지며, .hide()를 사용하여 화면으로부터 숨길 수 있습니다. image() 함수를 사용하여 피드를 캔버스에 그릴 수 있습니다. loadedmetadata 속성을 사용하여 요소가 완전히 로드된 시점을 감지할 수 있습니다. (2번째 예제 참고)",
            +        "피드의 구체적인 속성은 제약 조건(Constraints) 객체를 전달할 수 있습니다. 속성 및 제약 조건 객체에 대해 <a href = 'https://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>W3C 사양</a>에 더 자세하게 설명되어 있습니다. 이 기능을 지원하지 않는 브라우저도 있는 것을 유의해야 합니다.",
            +        "보안 정보: 최신 브라우저 보안 사양은 createCapture() 이면의 getUserMedia() 메소드가 로컬 또는 HTTPS에서 코드 실행시에만 작동할 것을 요구합니다. 자세한 사항은 <a href = 'https://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>여기</a>와 <a href = 'https://developer.mozilla.org/ko/docs/Web/API/MediaDevices/getUserMedia'>여기</a>에 있습니다.",
            +        "",
            +        ""
            +      ],
            +      "returns": "p5.Element: capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "type": "문자열|상수|객체: 캡처 유형, VIDEO 또는 AUDIO 중 하나로 지정 가능. 별도의 매개변수가 지정되지 않을 경우 기본값으로 둘 다 또는 제약 조건 객체",
            +        "callback": "함수: (선택 사항) 스트림 로드 완료 후 1번 호출되는 함수"
            +      }
            +    },
            +    "createElement": {
            +      "description": [
            +        "지정된 콘텐츠를 지닌 DOM에 태그된 요소를 생성합니다."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "tag": "문자열: 새로운 요소의 태그",
            +        "content": "문자열: (선택 사항) 요소 안에 삽입될 HTML 콘텐츠"
            +      }
            +    },
            +    "deviceOrientation": {
            +      "description": [
            +        "시스템 변수 deviceOrientation는 기기의 방향을 담습니다. 변수값은 LANDSCAPE(가로) 또는 PORTRAIT(세로)로 설정가능합니다. 사용 가능한 데이터가 없는 경우, '정의되지 않음(undefined)로 설정됩니다."
            +      ]
            +    },
            +    "accelerationX": {
            +      "description": [
            +        "시스템 변수 accelerationX는 기기의 x축상 가속도값을 담습니다. 값은 초당 미터 제곱으로 표기됩니다."
            +      ]
            +    },
            +    "accelerationY": {
            +      "description": [
            +        "시스템 변수 accelerationY는 기기의 y축상 가속도값을 담습니다. 값은 초당 미터 제곱으로 표기됩니다."
            +      ]
            +    },
            +    "accelerationZ": {
            +      "description": [
            +        "시스템 변수 accelerationZ는 기기의 z축상 가속도값을 담습니다. 값은 초당 미터 제곱으로 표기됩니다."
            +      ]
            +    },
            +    "pAccelerationX": {
            +      "description": [
            +        "시스템 변수 pAccelerationX는 기기의 직전 프레임부터 현재 프레임까지의 x축상 가속도값을 담습니다. 값은 초당 미터 제곱으로 표기됩니다."
            +      ]
            +    },
            +    "pAccelerationY": {
            +      "description": [
            +        "시스템 변수 pAccelerationY는 기기의 직전 프레임부터 현재 프레임까지의 y축상 가속도값을 담습니다. 값은 초당 미터 제곱으로 표기됩니다."
            +      ]
            +    },
            +    "pAccelerationZ": {
            +      "description": [
            +        "시스템 변수 pAccelerationZ는 기기의 직전 프레임부터 현재 프레임까지의 z축상 가속도값을 담습니다. 값은 초당 미터 제곱으로 표기됩니다."
            +      ]
            +    },
            +    "rotationX": {
            +      "description": [
            +        "시스템 변수 rotationX는 기기의 x축상 회전값을 담습니다. 스케치의 angleMode()가 DEGREES로 설정된 경우 값의 범위는 -180부터 180까지이고, RADIANS로 설정된 경우 -PI부터 PI까지입니다.",
            +        "참고: rotation 함수를 호출하는 순서를 주의해야 합니다. 여러 축에 대한 회전 함수를 동시에 사용할 경우, 반드시 Z-X-Y 순서로 호출해야 합니다. 그렇지 않으면 예기지 못한 결과가 발생할 수 있습니다."
            +      ]
            +    },
            +    "rotationY": {
            +      "description": [
            +        "시스템 변수 rotationY는 기기의 y축상 회전값을 담습니다. 스케치의 angleMode()가 DEGREES로 설정된 경우 값의 범위는 -90부터 90까지이고, RADIANS로 설정된 경우 -PI/2부터 PI/2까지입니다.",
            +        "참고: rotation 함수를 호출하는 순서를 주의해야 합니다. 여러 축에 대한 회전 함수를 동시에 사용할 경우, 반드시 Z-X-Y 순서로 호출해야 합니다. 그렇지 않으면 예기지 못한 결과가 발생할 수 있습니다."
            +      ]
            +    },
            +    "rotationZ": {
            +      "description": [
            +        "시스템 변수 rotationZ는 기기의 z축상 회전값을 담습니다. 스케치의 angleMode()가 DEGREES로 설정된 경우 값의 범위는 0부터 360까지이고, RADIANS로 설정된 경우 0부터 2*PI까지입니다.",
            +        "rotationX 및 rotationY와는 달리, 이 변수는 나침반이 내장된 기기에 한해 사용가능합니다.",
            +        "참고: rotation 함수를 호출하는 순서를 주의해야 합니다. 여러 축에 대한 회전 함수를 동시에 사용할 경우, 반드시 Z-X-Y 순서로 호출해야 합니다. 그렇지 않으면 예기지 못한 결과가 발생할 수 있습니다."
            +      ]
            +    },
            +    "pRotationX": {
            +      "description": [
            +        "시스템 변수 pRotationX는 기기의 직전 프레임부터 현재 프레임까지의 x축상 회전값을 담습니다. 스케치의 angleMode()가 DEGREES로 설정된 경우 값의 범위는 -180부터 180까지이고, RADIANS로 설정된 경우 -PI부터 PI까지입니다.",
            +        "pRotationX와 rotationX를 함께 사용하여 기기의 x축상 회전 방향을 정할 수 있습니다."
            +      ]
            +    },
            +    "pRotationY": {
            +      "description": [
            +        "시스템 변수 pRotationY는 기기의 직전 프레임부터 현재 프레임까지의 y축상 회전값을 담습니다. 스케치의 angleMode()가 DEGREES로 설정된 경우 값의 범위는 -90부터 90까지이고, RADIANS로 설정된 경우 -PI/2부터 PI/2까지입니다.",
            +        "pRotationY와 rotationY를 함께 사용하여 기기의 y축상 회전 방향을 정할 수 있습니다."
            +      ]
            +    },
            +    "pRotationZ": {
            +      "description": [
            +        "시스템 변수 pRotationZ는 기기의 직전 프레임부터 현재 프레임까지의 z축상 회전값을 담습니다. 스케치의 angleMode()가 DEGREES로 설정된 경우 값의 범위는 -90부터 90까지이고, RADIANS로 설정된 경우 0부터 2*PI까지입니다.",
            +        "pRotationZ와 rotationZ를 함께 사용하여 기기의 z축상 회전 방향을 정할 수 있습니다."
            +      ]
            +    },
            +    "turnAxis": {
            +      "description": [
            +        "장치가 회전시, deviceTurned() 메소드를 트리거하는 축을 turnAxis 변수에 저장합니다. turnAxis 변수는 deviceTurned() 함수가 지정한 범위 내에서만 정의됩니다."
            +      ]
            +    },
            +    "setMoveThreshold": {
            +      "description": [
            +        "setMoveThreshold() 함수로 deviceMoved() 함수의 이동 임계값을 설정합니다. 기본 임계값은 0.5입니다."
            +      ],
            +      "params": {
            +        "value": "숫자: 임계값"
            +      }
            +    },
            +    "setShakeThreshold": {
            +      "description": [
            +        "setShakeThreshold() 함수로 deviceShaken() 함수의 이동 임계값을 설정합니다. 기본 임계값은 30입니다."
            +      ],
            +      "params": {
            +        "value": "숫자: 임계값"
            +      }
            +    },
            +    "deviceMoved": {
            +      "description": [
            +        "deviceMoved() 함수는 장치가 X,Y,Z 축을 따라 임계값 이상으로 이동할 때 호출됩니다. 기본 임계값은 0.5입니다. 임계값은 setMoveThreshold()로 변경할 수 있습니다."
            +      ]
            +    },
            +    "deviceTurned": {
            +      "description": [
            +        "deviceTurned() 함수는 기기가 90도 이상을 계속해서 회전할 때 호출됩니다.",
            +        "deviceTurned() 메소드를 트리거하는 축이 turnAxis 변수에 저장됩니다. turnAxis 변수를 X,Y,Z와 비교하여, 메소드를 트리거할 축을 정하고 해당 설정을 잠글 수 있습니다."
            +      ]
            +    },
            +    "deviceShaken": {
            +      "description": [
            +        "deviceShaken() 함수는 accelerationX와 accelerationY의 전체 가속도 변화량이 임계값보다 클 때 호출됩니다. 기본 임계값은 30입니다. 임계값은 setShakeThreshold()로 변경할 수 있습니다."
            +      ]
            +    },
            +    "keyIsPressed": {
            +      "description": [
            +        "불리언 시스템 변수 keyIsPressed입니다. 자판키를 누르면 참(true)을, 누르지 않을 때 거짓(false)을 반환합니다."
            +      ]
            +    },
            +    "key": {
            +      "description": [
            +        "시스템 변수 key는 가장 마지막으로 입력된 자판키값을 담습니다. keyTyped() 함수를 통해 대소문자를 반영할 수 있습니다. ASCII 자판키가 아닌 경우, keyCode 변수를 사용합니다."
            +      ]
            +    },
            +    "keyCode": {
            +      "description": [
            +        "다음의 keyCode 변수로 특수키 입력을 감지할 수 있습니다: BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. <a href='http://keycode.info/'>keycode.info</a>에서 원하는 자판키의 keyCode를 확인할 수 있습니다."
            +      ]
            +    },
            +    "keyPressed": {
            +      "description": [
            +        "keyPressed() 함수는 자판을 누를 때마다 한 번씩 호출됩니다. 누른 키의 keyCode는 keyCode 변수에 저장됩니다.",
            +        "ASCII 자판키가 아닌 경우, keyCode 변수를 사용합니다. keyCode가 BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW에 해당하는지의 여부를 확인할 수 있습니다.",
            +        "ASCII 자판키의 경우, 가장 마지막으로 누른 자판키값이 key 변수에 저장되나, 대소문자가 구분되지 않습니다. 대소문자 구분을 원할 경우, keyTyped()를 통해 key 변수를 받을 수 있습니다.",
            +        "컴퓨터 운영 체제의 자판키 입력 반복 처리 방식으로 인해, 자판키를 계속 누르면 keyTyped()를 여러 번 호출하는 경우가 발생할 수 있습니다. 반복 속도는 운영 체제와 컴퓨터 구성 방식마다 다릅니다.",
            +        "자판키 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) KeyboardEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "keyReleased": {
            +      "description": [
            +        "keyReleased() 함수는 자판을 놓을 때마다 한 번씩 호출됩니다. 자세한 내용은 <a href='https://p5js.org/reference/#/p5/key'>key</a>와 <a href='https://p5js.org/reference/#/p5/keyCode'>keyCode</a>에 있습니다.",
            +        "자판키 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) KeyboardEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "keyTyped": {
            +      "description": [
            +        "keyTyped() 함수는 자판을 누를 때마다 한번씩 호출되지만, 백스페이즈, 딜리트, 컨트롤, 쉬프트, 알트키는 무시됩니다. 언급된 자판키 입력 감지를 원할 경우, keyPressed() 함수를 사용하면 됩니다. 가장 마지막으로 입력된 자판키값이 key 변수에 저장됩니다.",
            +        "컴퓨터 운영 체제의 자판키 입력 반복 처리 방식으로 인해, 자판키를 계속 누르면 keyTyped()를 여러 번 호출하는 경우가 발생할 수 있습니다. (keyReleased()도 마찬가지 입니다.) 반복 속도는 운영 체제와 컴퓨터 구성 방식마다 다릅니다.",
            +        "자판키 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) KeyboardEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "keyIsDown": {
            +      "description": [
            +        "keyIsDown() 함수는 키가 현재 내려가있는지, 즉 눌리는지의 여부를 확인합니다. 이미지를 대각선으로 움직일 때처럼, 동시에 여러 자판키가 객체의 이동 방향에 영향을 주도록 설정할 때 사용됩니다. <a href='http://p5js.org/zh-Hans/reference/#p5/keyCode'>여기</a>에 나열된 keyCode 변수 이름이나 keyCode 숫자를 넣을 수 있습니다."
            +      ],
            +      "returns": "불리언: 자판을 눌려있는지의 여부",
            +      "params": {
            +        "code": "숫자: 확인할 자판키"
            +      }
            +    },
            +    "movedX": {
            +      "description": [
            +        "movedX 변수는 직전 프레임 이후의 마우스 수평 이동을 담습니다."
            +      ]
            +    },
            +    "movedY": {
            +      "description": [
            +        "movedY 변수는 직전 프레임 이후의 마우스 수직 이동을 담습니다."
            +      ]
            +    },
            +    "mouseX": {
            +      "description": [
            +        "시스템 변수 mouseX는 캔버스 (0,0)에 대한 마우스의 현재 수평 위치를 담습니다. 2D상 (0,0)은 좌측 상단, WebGL상에서는 (-너비/2, 높이/2)를 의미합니다. 마우스 입력 대신 터치가 사용될 경우, mouseX는 가장 마지막 터치 지점의 x좌표값을 담습니다."
            +      ]
            +    },
            +    "mouseY": {
            +      "description": [
            +        "시스템 변수 mouseY는 캔버스 (0,0)에 대한 마우스의 현재 수직 위치를 담습니다. 2D상 (0,0)은 좌측 상단, WebGL상에서는 (-너비/2, 높이/2)를 의미합니다. 마우스 입력 대신 터치가 사용될 경우, mouseY는 가장 마지막 터치 지점의 y좌표값을 담습니다."
            +      ]
            +    },
            +    "pmouseX": {
            +      "description": [
            +        "시스템 변수 pmouseX는 직전 프레임에서의 캔버스 (0,0)에 대한 마우스 및 터치 수평 위치를 담습니다. 2D상 (0,0)은 좌측 상단, WebGL상에서는 (-너비/2, 높이/2)를 의미합니다. 참고: pmouseX는 매 터치 이벤트가 시작할 때마다 현재의 mouseX값으로 리셋됩니다."
            +      ]
            +    },
            +    "pmouseY": {
            +      "description": [
            +        "시스템 변수 pmouseY는 직전 프레임에서의 캔버스 (0,0)에 대한 마우스 및 터치 수직 위치를 담습니다. 2D상 (0,0)은 좌측 상단, WebGL상에서는 (-너비/2, 높이/2)를 의미합니다. 참고: pmouseY는 매 터치 이벤트가 시작할 때마다 현재의 mouseY값으로 리셋됩니다."
            +      ]
            +    },
            +    "winMouseX": {
            +      "description": [
            +        "시스템 변수 winMouseX는 캔버스 (0,0)에 대한 마우스의 현재 수평 위치를 담습니다."
            +      ]
            +    },
            +    "winMouseY": {
            +      "description": [
            +        "시스템 변수 winMouseY는 캔버스 (0,0)에 대한 마우스의 현재 수직 위치를 담습니다."
            +      ]
            +    },
            +    "pwinMouseX": {
            +      "description": [
            +        "시스템 변수 pwinMouseX는 직전 프레임에서의 캔버스 (0,0)에 대한 마우스 수평 위치를 담습니다. 2D상 (0,0)은 좌측 상단, WebGL상에서는 (-너비/2, 높이/2)를 의미합니다. 참고: pwinMouseX는 매 터치 이벤트가 시작할 때마다 현재의 winMouseX값으로 리셋됩니다."
            +      ]
            +    },
            +    "pwinMouseY": {
            +      "description": [
            +        "시스템 변수 pwinMouseY는 직전 프레임에서의 캔버스 (0,0)에 대한 마우스 수직 위치를 담습니다. 2D상 (0,0)은 좌측 상단, WebGL상에서는 (-너비/2, 높이/2)를 의미합니다. 참고: pwinMouseY는 매 터치 이벤트가 시작할 때마다 현재의 winMouseY값으로 리셋됩니다."
            +      ]
            +    },
            +    "mouseButton": {
            +      "description": [
            +        "p5는 마우스 버튼을 눌렀는 지의 여부와 어떤 버튼을 눌렀는지를 자동으로 추적합니다. 시스템 변수 mouseButton의 값은 마지막으로 누른 버튼에 따라 LEFT, RIGHT, 또는 CENTER로 처리됩니다. 경고: 브라우저에 따라 마우스 버튼을 다르게 추적할 수 있습니다."
            +      ]
            +    },
            +    "mouseIsPressed": {
            +      "description": [
            +        "불리언 시스템 변수 mouseIsPressed는 마우스가 눌렸을 경우 참(true)이고 그렇지 않을 경우 거짓(false)로 처리됩니다."
            +      ]
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "mouseMoved() 함수는 마우스 버튼이 눌리지 않은 상태에서 움직일 때마다 한 번씩 호출됩니다.",
            +        "마우스 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) MouseEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "mouseDragged": {
            +      "description": [
            +        "mouseDragged() 함수는 마우스 버튼이 눌린 상태에서 움직일 때마다 한 번씩 호출됩니다. mouseDragged() 함수가 정의되지 않고, touchMoved() 함수가 정의된 경우, 후자가 대신 호출됩니다.",
            +        "마우스 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) MouseEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "mousePressed() 함수는 마우스 버튼이 눌릴 때마다 한 번씩 호출됩니다. 이 때, mouseButton 변수(관련 레퍼런스 참고)를 통해 어떤 마우스 버튼이 눌렸는지 확인할 수 있습니다. mousePressed() 함수가 정의되지 않고, touchStarted() 함수가 정의된 경우, 후자가 대신 호출됩니다.",
            +        "마우스 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) MouseEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "mouseReleased() 함수는 마우스 버튼이 놓일 때마다 한 번씩 호출됩니다. mouseReleased() 함수가 정의되지 않고, touchEnded() 함수가 정의된 경우, 후자가 대신 호출됩니다.",
            +        "마우스 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) MouseEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "mouseClicked() 함수는 마우스 버튼이 눌리고 놓일 때마다 한 번씩 호출됩니다.",
            +        "이 함수는 마우스 왼쪽 버튼을 클릭할 때 실행되며, 브라우저마다 마우스 클릭을 다르게 처리합니다. 클릭하거나 놓을 여타 마우스 버튼을 처리하고 싶다면 mousePressed() 또는 mouseReleased()를 참고할 수 있습니다.",
            +        "마우스 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) MouseEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "doubleClicked() 함수는 이벤트 리스너가 DOM L3 사양 중 하나인 더블 클릭(dbclick)을 감지할 때마다 실행됩니다. doubleClicked 이벤트는 포인팅 장치의 버튼(보통, 마우스 기본 버튼)을 특정 요소 위에서 두 번 연속 클릭시 시작합니다. dbclick 이벤트에 대한 자세한 정보는 <a href='https://developer.mozilla.org/en-US/docs/Web/Events/dblclick'>Mozilla 문서</a>에서 확인할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) MouseEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "mouseWheel() 함수는 실제 마우스 휠 또는 터치 패드상의 수직 마우스 휠 이벤트를 감지할 때마다 실행됩니다.",
            +        "event.delta 속성은 마우스 휠이 스크롤된 양을 값으로 반환합니다. 값은 스크롤 방향에 따라 양수 또는 음수 부호와 함께 표기됩니다. ('자연' 스크롤이 활성화된 OS X의 경우, 부호가 반전됩니다.)",
            +        "마우스 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다.",
            +        "현재 Safari의 경우 'wheel' 이벤트를 지원하는 관계로, 메소드에 \"return false\"를 포함해야 함수가 예상대로 작동할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) WheelEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "requestPointerLock": {
            +      "description": [
            +        "requestPointerLock() 함수는 포인터를 현재 위치로 잠그고 숨깁니다. movedX와 movedY를 사용하여 <a href=\"#/p5/draw\">draw()</a> 함수의 마지막 호출 이후에 마우스가 이동한 값을 가져올 수 있습니다.",
            +        "모든 브라우저가 이 기능을 지원하지는 않습니다.",
            +        "이 함수를 사용하면 마우스를 특정 방향으로 계속 움직여도 화면 밖으로 벗어나지 않도록 처리할 수 있습니다. 1인칭 시점 구현 등에 용이합니다."
            +      ]
            +    },
            +    "exitPointerLock": {
            +      "description": [
            +        "exitPointerLock() 함수는 이전에 설정된 <a href ='https://p5js.org/reference/#/p5/requestPointerLock'>포인터 잠금</a>을 종료합니다. UI 요소 활성화 등을 위해 사용됩니다."
            +      ]
            +    },
            +    "touches": {
            +      "description": [
            +        "시스템 변수 touches[]는 캔버스 (0,0)에 대한 현재의 모든 터치 포인트 위치, 그리고 터치를 식별하는 고유 ID를 담습니다.배열 속 요소들은 각각 x, y, 그리고 id 속성을 갖는 객체들입니다.",
            +        "touch[] 배열은 터치 기반 데스크톱 및 노트북상의 Safari나 Internet Explorer에서 지원되지 않습니다.",
            +        ""
            +      ]
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "touchStarted() 함수는 터치가 등록될 때마다 한 번씩 호출됩니다. touchStarted() 함수가 정의되지 않고, mousePressed() 함수가 정의된 경우, 후자가 대신 호출됩니다.",
            +        "마우스 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) TouchEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "touchMoved() 함수는 터치가 등록될 때마다 한 번씩 호출됩니다. touchMoved() 함수가 정의되지 않고, mouseDragged() 함수가 정의된 경우, 후자가 대신 호출됩니다.",
            +        "마우스 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) TouchEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "touchEnded() 함수는 터치가 등록될 때마다 한 번씩 호출됩니다. touchEnded() 함수가 정의되지 않고, mouseReleased() 함수가 정의된 경우, 후자가 대신 호출됩니다.",
            +        "마우스 입력을 통한 이벤트 발생이 브라우저 기본값으로 설정되어있는 경우, 메소드 말미에 \"return false\"를 넣어 브라우저 기본값 이벤트 발생을 방지할 수 있습니다."
            +      ],
            +      "params": {
            +        "event": "객체: (선택 사항) TouchEvent 콜백 (callback) 인자값."
            +      }
            +    },
            +    "createImage": {
            +      "description": [
            +        "새로운 p5.Image(이미지 저장을 위한 데이터 유형)를 생성합니다. 이 함수는 새 픽셀 버퍼를 제공합니다. 너비 및 높이 매개변수로 버퍼 크기를 설정합니다.",
            +        ".pixels를 통해 디스플레이 화면의 모든 픽셀값이 담긴 배열에 접근합니다. 픽셀값은 숫자로 표현됩니다. 배열은 디스플레이 화면의 4배 크기(픽셀 밀도에 대한 인수 포함)로, 각 픽셀에 대한 R, G, B, A값을 나타냅니다. 배열은 행의 좌에서 우로, 그 다음 열로 내려가는 순으로 채워집니다. 자세한 내용은 .pixels 레퍼런스에 있습니다. 몇몇 경우에서는 set() 및 get() 함수를 사용하는 편이 더 편리할 수 있습니다.",
            +        "이미지의 픽셀에 접근하기에 앞서, loadPixels() 함수를 통해 픽셀을 불러와야 합니다. 또한, 배열 데이터를 수정한 후에는 updatePixels()로 수정된 내용을 반영해야 합니다."
            +      ],
            +      "returns": "p5.Image: p5.Image 객체",
            +      "params": {
            +        "width": "정수: 픽셀 단위 너비값",
            +        "height": "정수: 픽셀 단위 높이값"
            +      }
            +    },
            +    "saveCanvas": {
            +      "description": [
            +        "현재 캔버스를 이미지로 저장합니다. 브라우저에 따라 파일을 즉시 저장하거나 사용자에게 대화 상자를 표시합니다."
            +      ],
            +      "params": {
            +        "selectedCanvas": "p5.Element|HTMLCanvasElement: (선택 사항) 특정 HTML5 캔버스를 나타내는 변수",
            +        "filename": "문자열: (선택 사항) 저장할 경우 파일명",
            +        "extension": "문자열: (선택 사항) 'jpg' 또는 'png'로 저장될 파일형식"
            +      }
            +    },
            +    "saveFrames": {
            +      "description": [
            +        "동영상 제작에 사용되는 일련의 프레임을 캡처합니다. 콜백을 허용하는 함수로, 프레임을 서버로 보내 저장하거나 동영상으로 변환할 수 있습니다. 콜백을 지정하지 않으면, 생성된 모든 이미지 다운로드를 위한 대화 상자가 브라우저에 팝업창으로 나타납니다. 콜백을 지정할 경우 이미지 데이터를 자동 저장하는 대신, 총 프레임 수와 동일한 갯수의 크기를 갖는 객체 배열을 콜백 함수에 인수로서 전달합니다.",
            +        "saveFrames() 함수는 애니메이션의 처음 15개의 프레임만 저장합니다. 재생 시간이 더 긴 애니메이션을 만들 시 <a href='https://github.com/spite/ccapture.js/'>ccapture.js</a>와 같은 라이브러리를 참고할 수 있습니다.",
            +        ""
            +      ],
            +      "params": {
            +        "filename": "문자열:",
            +        "extension": "문자열: 'jpg' 또는 'png'",
            +        "duration": "숫자: 프레임을 저장할 시간(초)",
            +        "framerate": "숫자: 저장할 프레임 속도",
            +        "callback": "함수(배열): (선택 사항) 이미지 데이터를 처리하는 콜백 함수. 이 함수는 배열을 인수로만 받습니다. 지정된 개수의 객체 프레임이 배열에 포함됩니다. 각 객체는 다음의 3가지 속성을 가집니다: imageData - 이미지/옥텟 스트림, 파일명, 파일 확장자"
            +      }
            +    },
            +    "loadImage": {
            +      "description": [
            +        "사용자가 지정한 경로로부터 이미지를 불러오고 p5.Image를 생성합니다.",
            +        "이미지를 불러와도 곧바로 렌더링되지 않는 경우가 있습니다. 여타 작업을 수행하기에 앞서 이미지 로드를 완료하려면, loadImage()를 <a href=\"#/p5/preload\">preload()</a> 함수 안에서 호출하면 됩니다. 또는, 로드가 완료된 이미지 처리를 위한 콜백 함수를 지정할 수 있습니다.",
            +        "이미지 경로는 스케치에 링크된 HTML 파일에 대한 상대 경로를 사용합니다. URL이나 원격 경로를 이용하면 브라우저의 보안 설정에 따라 이미지를 불러오는 데에 문제가 생길 수 있습니다.",
            +        "이미지 경로 대신 base64 문자열로 된 이미지를 사용할 수 있습니다. 이때 \"data:image/png;base64,\"를 문자열 앞에 표기해야 합니다."
            +      ],
            +      "returns": "p5.Image: p5.Image 객체",
            +      "params": {
            +        "path": "문자열: 불러올 이미지 경로",
            +        "successCallback": "함수(p5.Image): (선택 사항) 이미지 불러오기 후 호출되는 함수로, p5.Image가 전달됩니다.",
            +        "failureCallback": "함수(Event): (선택 사항) 이미지 불러오기 실패시 이벤트 에러와 함께 호출되는 함수"
            +      }
            +    },
            +    "image": {
            +      "description": [
            +        "p5.js 캔버스에 이미지를 그립니다.",
            +        "image() 함수는 크게 세가지 방법으로 사용할 수 있습니다. 가장 간단한 방법은 img, x, y 3개의 변수를 사용하는 방법입니다. x, y는 이미지의 (x,y) 좌표값 위치입니다. img, x, y에 더해 이미지의 너비와 높이를 설정하는 2개의 변수를 추가로 사용합니다.",
            +        "8개의 변수를 모두 사용하는 경우도 있습니다. 먼저, 변수 구별을 위해 p5.js에서 사용하는 용어를 배워봅시다. 첫 번째 용어는 '목적 사각형(destination rectagle)'으로, dx, dy 등의 변수가 이에 해당합니다. 두 번째 용어는 '원본 이미지(source image)'로, sx, sy등의 변수가 이에 해당합니다. '원본 이미지'의 크기 설정을 통해 이미지의 일부만을 화면상 나타나게할 수 있습니다. 자세한 사항은 아래 도식에 있습니다. <img src=\"assets/drawImage.png\"></img>"
            +      ],
            +      "params": {
            +        "img": "p5.Image, p5.Element: 화면에 나타낼 이미지",
            +        "x": "숫자: 왼쪽 위 모서리의 x좌표값",
            +        "y": "숫자: 왼쪽 위 모서리의 y좌표값",
            +        "width": "숫자: (선택 사항) 이미지 너비값",
            +        "height": "숫자: (선택 사항) 이미지 높이값",
            +        "dx": "숫자: 원본 이미지를 배치할 목적지 사각형의 x좌표값",
            +        "dy": "숫자: 원본 이미지를 배치할 목적지 사각형의 y좌표값",
            +        "dWidth": "숫자: 목적지 사각형의 너비값",
            +        "dHeight": "숫자: 목적지 사각형의 높이값",
            +        "sx": "숫자: 목적지 사각형에 배치할 원본 이미지 일부의 x좌표값",
            +        "sy": "숫자: 목적지 사각형에 배치할 원본 이미지 일부의 y좌표값",
            +        "sWidth": "숫자: (선택 사항) 목적지 사각형에 배치할 원본 이미지 일부의 너비값",
            +        "sHeight": "숫자: (선택 사항) 목적지 사각형에 배치할 원본 이미지 일부의 높이값"
            +      }
            +    },
            +    "tint": {
            +      "description": [
            +        "화면에 나타날 이미지의 면채우기 값을 설정합니다. 이미지에 색조를 입히거나 알파값을 통해 투명도를 조정할 수 있습니다.",
            +        "이미지 본래의 색상을 유지하면서 투명도를 적용하려면, 흰색 색조에 알파값을 지정하면 됩니다. 예를 들어 tint(255, 128)는 이미지를 50% 투명하게 만듭니다. (기본 알파 범위 0-255를 가정, 범위는 colorMode()로 조정 가능)",
            +        "회색값 매개변수는 현재 colorMode()에 따른 최대값보다 작거나 같아야합니다. 기본 최대값은 255입니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: 현재 색상 범위에 대한 빨강값 또는 색조값",
            +        "v2": "숫자: 현재 색상 범위에 대한 초록값 또는 채도값",
            +        "v3": "숫자: 현재 색상 범위에 대한 파랑값 또는 밝기값",
            +        "alpha": "숫자:",
            +        "value": "문자열: 색상 문자열",
            +        "gray": "숫자: 회색값",
            +        "values": "숫자 배열[]: 색상의 R, G, B & 알파값을 담는 배열",
            +        "color": "p5.Color: 입힐 색조의 색상]"
            +      }
            +    },
            +    "noTint": {
            +      "description": [
            +        "화면에 나타날 이미지의 현재 면채우기 값을 제거하고 이미지의 본래 색상으로 되돌아갑니다."
            +      ]
            +    },
            +    "imageMode": {
            +      "description": [
            +        "이미지의 모드를 설정합니다. image()의 매개변수가 해석되는 방식을 변경하여 이미지가 그려지는 위치를 수정합니다. 기본 모드는 imageMode(CORNER)이며, image()의 2번째 및 3번째 매개변수를 이미지의 좌측 상단 모퉁이의 좌표값으로 해석합니다. 추가 매개변수 2개를 통해 이미지의 너비와 높이도 설정할 수 있습니다.",
            +        "imageMode(CORNERS)는 image()의 2번째 및 3번째 매개변수를 모퉁이 한 개의 좌표값으로 해석합니다. 그리고, 4번째 및 5번째 매개변수를 그 반대편 모퉁이의 좌표값으로 해석합니다.",
            +        "imageMode(CENTER)는 2번째 및 3번째 매개변수를 이미지의 중심점 좌표값으로 해석합니다. 추가 매개변수 2개를 통해 이미지의 너비와 높이도 설정할 수 있습니다."
            +      ],
            +      "params": {
            +        "mode": "상수: CORNER, CORNERS 또는 CENTER"
            +      }
            +    },
            +    "pixels": {
            +      "description": [
            +        "디스플레이 화면의 모든 픽셀값을 담는 <a href ='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray'>Uint8ClampedArray</a>입니다. 픽셀값은 숫자로 표현됩니다. 배열은 디스플레이 화면의 4배 크기(픽셀 밀도에 대한 인수 포함)로, 각 픽셀에 대한 R, G, B, A값을 나타냅니다. 배열은 행의 좌에서 우로, 그 다음 열로 내려가는 순으로 채워집니다. Retina를 비롯한 기타 고밀도 디스플레이는 (pixelDensity^2 계수로 인해) 크기가 더 큰 픽셀 배열[]을 갖기도 합니다. 일반 디스플레이 화면상 이미지가 100x100 픽셀이고 그 배열이 40,000이라면, Retina에서 배열은 160,000이 됩니다.",
            +        "배열상 처음 4개의 값들(즉, 인덱스 0-3)은 (0,0) 픽셀에서의 R, G, B, A값을, 그 다음 4개의 값들(즉, 인덱스 4-7)은 (1,0) 픽셀에서의 R, G, B, A값을 담습니다. 특정 좌표 (x,y)에서의 픽셀값을 설정하는 방법은 아래의 예제와 같습니다.",
            +        "다소 복잡해보이는 예제지만, 모든 픽셀 밀도(pixelDensity)를 사용할 수 있을정도로 유연합니다. set()은 임의의 pixelDensity에서 주어진 (x,y)에 대한 픽셀 배열[]의 모든 값들을 자동으로 설정합니다. 배열을 여러 차례 수정할 경우, 성능이 느려질 수 있습니다.",
            +        "이 배열을 사용하기 전, 데이터를 <a href=\"#/p5/loadPixels\">loadPixels()</a> 함수로 로딩해야 합니다. 또, 배열의 정보가 수정되었을 경우 <a href=\"#/p5/updatePixels\">updatePixels()</a> 함수를 호출해야 이 수정된 부분들을 반영할 수 있습니다.",
            +        "이 레퍼런스는 표준 자바스크립트 배열이 아니고, 따라서 <a href=\"#/p5/slice\">slice()</a>나 <a href=\"#/p5/arrayCopy\">arrayCopy()</a>와 같은 표준 자바스크립트 함수가 작동하지 않습니다."
            +      ]
            +    },
            +    "blend": {
            +      "description": [
            +        "사용자가 지정한 혼합 모드를 사용하여, 한 이미지의 픽셀 영역을 다른 이미지로 복사합니다."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: 원본 이미지",
            +        "sx": "정수: 원본 영역의 좌측 상단 모퉁이 x좌표값",
            +        "sy": "정수: 원본 영역의 좌측 상단 모퉁이 y좌표값",
            +        "sw": "정수: 원본 이미지 너비값",
            +        "sh": "정수: 원본 이미지 높이값",
            +        "dx": "정수: 대상 영역의 좌측 상단 모퉁이 x좌표값",
            +        "dy": "정수: 대상 영역의 좌측 상단 모퉁이 y좌표값",
            +        "dw": "정수: 대상 이미지 너비값",
            +        "dh": "정수: 대상 이미지 높이값",
            +        "blendMode": "상수: 혼합 모드. BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN, ADD or NORMAL 중 하나"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "캔버스의 한 영역을 다른 영역에 복사하고, srcImg 매개변수로 사용되는 한 이미지의 픽셀 영역을 캔버스에 복사합니다. srcImage는 원본 이미지로, 사용자가 지정합니다. 원본과 복사 대상 영역의 크기가 같지 않을 경우, 원본 픽셀 영역의 크기를 대상 영역의 크기에 맞게 자동으로 재조정합니다."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5 요소: 원본 이미지",
            +        "sx": "정수: 원본 영역의 좌측 상단 모퉁이 x좌표값",
            +        "sy": "정수: 원본 영역의 좌측 상단 모퉁이 y좌표값",
            +        "sw": "정수: 원본 이미지 너비값",
            +        "sh": "정수: 원본 이미지 높이값",
            +        "dx": "정수: 대상 영역의 좌측 상단 모퉁이 x좌표값",
            +        "dy": "정수: 대상 영역의 좌측 상단 모퉁이 y좌표값",
            +        "dw": "정수: 대상 이미지 너비값",
            +        "dh": "정수: 대상 이미지 높이값"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "캔버스에 필터를 적용합니다.",
            +        "THRESHOLD: 이미지를 인계값에 따라 흰색이나 검은색 픽셀로 바꿉니다. 이 인계값은 매개변수로 정해지며, 0.0 (검은)과 1.0 (흰) 사이에 있는 값입니다. 매개변수를 지정하지 않을 시 0.5가 사용됩니다.",
            +        "GRAY: 이미지의 모든 색상을 그레이 스케일로 변환합니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "OPAQUE: 알파 채널을 완전히 불투명하게 설정합니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "INVERT: 각 픽셀을 그 역의 값으로 설정합니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "POSTERIZE: 이미지의 각 채널을 매개변수로 지정한 색상 수로 제한합니다. 매개변수는 2부터 255사이의 값으로 설정 가능하나, 낮은 범위에서 가장 두드러진 결과를 볼 수 있습니다.",
            +        "BLUR: 블러 범위를 설정하는 level 매개변수를 사용하여 가우시안 블러를 실행합니다. 별도의 매개변수를 지정하지 않으면, 반경 1의 가우시안 블러와 동일한 효과가 됩니다. 값이 클수록 흐림 정도가 증가합니다.",
            +        "ERODE: 밝은 영역을 줄입니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "DILATE: 밝은 영역을 증가시킵니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "WebGL 모드에서는 filter()가 작동하지 않으나, 커스텀 셰이더를 사용하여 유사한 효과를 얻을 수 있습니다. 아담 페리스(Adam Ferriss)가 작성한 <a href='https://github.com/aferriss/p5jsShaderExamples'>셰이더 예제</a> 중, filter()와 유사한 효과를 나타내는 예제들이 있습니다."
            +      ],
            +      "params": {
            +        "filterType": "상수: THRESHOLD, GRAY, OPAQUE, INVERT, POSTERIZE, BLUR, ERODE, DILATE, BLUR 중 하나. 각 필터에 대한 문서는 Filters.js를 참조.",
            +        "filterParam": "숫자: (선택 사항) 각 필터 고유의 선택적 매개변수"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "지정된 픽셀 영역 또는 단일 픽셀을 캔버스로부터 받아옵니다.",
            +        "특정 픽셀에 대한 [R,G,B,A] 값의 배열이나, 이미지의 한 영역을 반환합니다. 별도의 매개변수를 지정하지 않는 경우, 전체 이미지를 반환합니다. 매개변수 x, y를 통해 특정 픽셀의 좌표값을 받아올 수 있습니다. 추가 매개변수 w, h를 통해 디스플레이 창의 한 영역을 지정할 수도 있습니다. 이미지를 받아올 때, 매개변수 x와 y는 현재 imageMode()와 관계없이 좌측 상단 모퉁이의 좌표값을 정의합니다.",
            +        "get(x,y) 함수로 픽셀 1개의 색상을 받아오는 것은 쉬운 방법이지만, pixels[] 배열로부터 직접 데이터를 받아오는 것만큼 빠르진 않습니다. pixels[] 배열과 픽셀 밀도 매개변수 d를 사용하여 get(x,y)과 동일한 효과를 나타낼 수 있고, 구체적인 명령문은 다음의 예제와 같습니다.",
            +        "더 많은 정보는 <a href=\"#/p5/pixels\">pixels[]</a> 레퍼런스를 확인할 수 있습니다.",
            +        "p5.Image 객체의 하위 이미지로부터 색상 배열을 추출하는 방법은 <a href=\"#/p5.Image/get\">p5.Image.get()</a>에 있습니다."
            +      ],
            +      "returns": "p5.Image: 직사각형 p5.Image",
            +      "params": {
            +        "x": "숫자: 픽셀의 x좌표값",
            +        "y": "숫자: 픽셀의 y좌표값",
            +        "w": "숫자: 너비",
            +        "h": "숫자: 높이"
            +      }
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "디스플레이 창의 픽셀 데이터를 pixels[] 배열에 불러옵니다. 이 함수는 pixels[] 배열을 작성하거나 읽어오기 전에 호출되어야 합니다. set() 함수 또는 pixels[] 배열 직접 조작을 통한 변경 사항만 반영합니다."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "특정 픽셀의 색상을 변경하거나, 디스플레이 창에 이미지를 직접 작성합니다.",
            +        "매개변수 x와 y는 변경할 픽셀을 지정하고, 매개변수 c는 색상값을 지정합니다. 색상값으로는 p5.Color 객체, [R,G,B,A] 베열, 또는 단일 그레이 스케일값을 사용할 수 있습니다. 이미지 설정시, 매개변수 x와 y는 현재 imageMode()와 관계없이 좌측 상단 모퉁이의 좌표값을 정의합니다.",
            +        "set() 함수 사용 후에는 반드시 updatePixels()를 호출하여 변경 사항을 반영해야 합니다. 호출 시점은 픽셀 설정을 완료한 이후이면서 동시에, .get() 또는 그리기 함수 호출 이전이어야 합니다.",
            +        "set(x,y) 함수로 픽셀 1개의 색상을 받아오는 것은 쉬운 방법이지만, pixels[] 배열로부터 직접 데이터를 받아오는 것만큼 빠르진 않습니다. 레티나 디스플레이에선 pixels[] 배열값을 직접 설정하는 것이 복잡할 수 있으나, 많은 양의 픽셀들이 반복 실행되도록 설정된 경우 그 작업 성능이 향상됩니다.",
            +        "자세한 내용은 pixels[]에 있습니다.",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "x": "숫자: 픽셀의 x좌표값",
            +        "y": "숫자: 픽셀의 y좌표값",
            +        "c": "숫자|숫자 배열[]|객체: 채도값 | 픽셀 배열 | <a href=\"#/p5.Color\">p5.Color</a> 객체 | <a href=\"#/p5.Image\">p5.Image</a> 객체"
            +      }
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "pixels[] 배열의 데이터로 디스플레이 창을 업데이트합니다. loadPixels()와 함께 사용합니다. 배열로부터 픽셀값을 읽어오기만 할 경우, updatePixels()를 사용할 필요가 없습니다. 업데이트는 배열값 변경 사항을 적용하는 데에만 필요합니다. updatePixels()는 픽셀 배열을 수정하거나 set() 함수를 호출할 때마다 매번 호출되어야하며, set() 함수 또는 pixels[] 배열 직접 조작을 통한 변경 사항만 반영합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: (선택 사항) 업데이트할 영역의 좌측 상단 모퉁이 x좌표값",
            +        "y": "숫자: (선택 사항) 업데이트할 영역의 좌측 상단 모퉁이 y좌표값",
            +        "w": "숫자: (선택 사항) 업데이트할 영역의 너비값",
            +        "h": "숫자: (선택 사항) 업데이트할 영역의 높이값"
            +      }
            +    },
            +    "loadJSON": {
            +      "description": [
            +        "파일 또는 URL로부터 JSON 파일을 불러오고, 객체를 반환합니다. JSON 파일에 배열이 포함된 경우, 인덱스 번호를 키(key)로 사용하여 객체를 반환할 수 있습니다.",
            +        "이는 비동기적 메소드으로, 스케치상의 다음 코드 줄이 실행되기 전에 함수 실행이 완료되지 않을 수 있습니다. JSONP는 polyfill을 통해 지원되며, <a href ='https://github.com/camsong/fetch-jsonp'>여기</a>의 구문에 따라 JSON 콜백 함수가 정의한 객체를 2번째 인수로 전달할 수 있습니다.",
            +        "이 방법은 최대 64MB 크기의 파일을 불러오는 데에 적합합니다.",
            +        "[1번째 예제] <a href=\"#/p5/preload\">preload()</a> 함수 안에 loadJSON() 함수를 호출하여, 모든 불러오기 작업이 <a href=\"#/p5/setup\">setup()</a>과 <a href=\"#/p5/draw\">draw()</a> 함수가 호출되기에 앞서 완료되도록 처리합니다.",
            +        "[2번째 예제] <a href=\"#/p5/preload\">preload()</a> 함수 밖의 영역에서 콜백 함수를 2번째 예제와 같이 작성하여 객체를 처리할 수 있습니다.",
            +        "",
            +        ""
            +      ],
            +      "returns": "객체|배열: JSON 데이터",
            +      "params": {
            +        "path": "문자열: 불러올 파일명 또는 URL",
            +        "jsonpOptions": "객체: (선택 사항) jsonp 관련 설정을 위한 객체",
            +        "datatype": "문자열: \"json\" 또는 \"jsonp\"",
            +        "callback": "함수: (선택 사항) loadJSON()이 완료된 이후 실행될 함수, 데이터를 1번재 인수로 전달",
            +        "errorCallback": "함수: (선택 사항) 에러 발생시 실행될 함수, 반응(response)이 1번째 인수로 전달"
            +      }
            +    },
            +    "loadStrings": {
            +      "description": [
            +        "파일의 내용을 읽어와 개별 행에 대한 문자열 배열을 생성합니다. 위의 예제처럼 파일명(filename)을 매개변수로 사용할 경우, 해당 파일이 스케치 디렉토리/폴더(directory/folder) 안에 있어야 합니다.",
            +        "절대 경로(Unix 및 Linux의 경우 with/on 으로, 윈도우의 경우 드라이브 문자로 시작)로도 로컬 컴퓨터로부터 파일을 불러올 수 있습니다. 또는, 매개변수 filename을 URL 또는 네트워크상의 파일로 지정할 수 있습니다.",
            +        "이는 비동기적 메소드으로, 스케치상의 다음 코드 줄이 실행되기 전에 함수 실행이 완료되지 않을 수 있습니다.",
            +        "이 방법은 최대 64MB 크기의 파일을 불러오는 데에 적합합니다.",
            +        "[1번째 예제] <a href=\"#/p5/preload\">preload()</a> 함수 안에 loadStrings() 함수를 호출하여, 모든 불러오기 작업이 <a href=\"#/p5/setup\">setup()</a>과 <a href=\"#/p5/draw\">draw()</a> 함수가 호출되기에 앞서 완료되도록 처리합니다.",
            +        "[2번째 예제] <a href=\"#/p5/preload\">preload()</a> 함수 밖의 영역에서 콜백 함수를 2번째 예제와 같이 작성하여 객체를 처리할 수 있습니다."
            +      ],
            +      "returns": "문자열 배열[]: 문자열들의 배열",
            +      "params": {
            +        "filename": "문자열: 불러올 파일명 또는 URL",
            +        "callback": "함수: (선택 사항) loadStrings()이 완료된 이후 실행될 함수, 배열을 1번째 인수로 전달",
            +        "errorCallback": "함수: (선택 사항) 에러 발생시 실행될 함수, 반응(response)이 1번째 인수로 전달"
            +      }
            +    },
            +    "loadTable": {
            +      "description": [
            +        "파일 또는 URL의 내용을 읽어와 그 값으로 p5.Table 객체를 만듭니다. 특정 파일을 지정하려면, 해당 파일이 'data' 폴더 안에 있어야 합니다. 매개변수 filename는 온라인 파일 URL로도 지정 가능합니다. 기본값으로, 파일 내용이 쉼표 단위로 구분된 것(CSV 형식)으로 간주합니다. 'header' 옵션이 포함된 경우, 헤더 행만 찾습니다.",
            +        "가능한 옵션은 다음과 같습니다:<ul><li>csv - 테이블을 쉼표로 구분된 값으로서 구문 분석</li><li>tsv - 테이블을 탭으로 구분된 값으로서 구문 분석</li><li>header - 테이블에 헤더 행이 있음을 표기</li></ul>",
            +        "여러 옵션을 사용할 경우, 매개변수들을 쉼표로 구분하여 전달할 수 있습니다. 예를 들면 다음과 같습니다:",
            +        "<code>loadTable('my_csv_file.csv', 'csv', 'header'); </code>",
            +        "불러오기 및 저장된 모든 파일은 UTF-8 인코딩을 사용합니다.",
            +        "이는 비동기적 메소드로, 스케치상의 다음 코드 줄이 실행되기 전에 함수 실행이 완료되지 않을 수 있습니다. 그 경우, <a href=\"#/p5/preload\">preload()</a> 함수 안에 <a href=\"#/p5/loadTable\">loadTable()</a> 함수를 호출하여, 모든 불러오기 작업이 <a href=\"#/p5/setup\">setup()</a>과 <a href=\"#/p5/draw\">draw()</a> 함수가 호출되기에 앞서 완료되도록 처리합니다.",
            +        "<a href=\"#/p5/preload\">preload()</a> 함수 밖의 영역에서 콜백 함수를  작성하여 객체를 처리할 수 있습니다.",
            +        "이 방법은 최대 64MB 크기의 파일을 불러오는 데에 적합합니다.",
            +        "",
            +        ""
            +      ],
            +      "returns": "객체: 데이터를 포함한 <a href=\"#/p5.Table\">Table</a> 객체",
            +      "params": {
            +        "filename": "문자열: 불러올 파일명 또는 URL",
            +        "extension": "문자열: (선택 사항) 테이블을 쉼표로 나눌 경우 \"csv\", 세미콜론으로 나눌 경우 \"ssv\", 또는 탭으로 나눌 경우 \"tsv\"",
            +        "header": "문자열: (선택 사항) \"header\"로 테이블이 헤더가 있음을 표시",
            +        "callback": "함수: (선택 사항) <a href=\"#/p5/loadTable\">loadTable()</a>이 완료된 이후 실행될 함수, 성공시 Table 객체를 1번째 인수로 전달",
            +        "errorCallback": "함수: (선택 사항) 에러 발생시 실행될 함수, 반응(response)이 1번째 인수로 전달"
            +      }
            +    },
            +    "loadXML": {
            +      "description": [
            +        "파일의 내용을 읽어와 그 값으로 XML 객체를 생성합니다. 위의 예제처럼 파일명(filename)을 매개변수로 사용할 경우, 해당 파일이 스케치 디렉토리/폴더(directory/folder) 안에 있어야 합니다.",
            +        "절대 경로(Unix 및 Linux의 경우 with/on 으로, 윈도우의 경우 드라이브 문자로 시작)로도 로컬 컴퓨터로부터 파일을 불러올 수 있습니다. 또는, 매개변수 filename을 URL 또는 네트워크상의 파일로 지정할 수 있습니다.",
            +        "이는 비동기적 메소드로, 스케치상의 다음 코드 줄이 실행되기 전에 함수 실행이 완료되지 않을 수 있습니다. 그 경우, <a href=\"#/p5/preload\">preload()</a> 함수 안에 <a href=\"#/p5/loadXML\">loadXML()</a> 함수를 호출하여, 모든 불러오기 작업이 <a href=\"#/p5/setup\">setup()</a>과 <a href=\"#/p5/draw\">draw()</a> 함수가 호출되기에 앞서 완료되도록 처리합니다.",
            +        "<a href=\"#/p5/preload\">preload()</a> 함수 밖의 영역에서 콜백 함수를  작성하여 객체를 처리할 수 있습니다.",
            +        "이 방법은 최대 64MB 크기의 파일을 불러오는 데에 적합합니다.",
            +        "",
            +        "",
            +        "",
            +        ""
            +      ],
            +      "returns": "객체: 데이터를 포함한 XML 객체",
            +      "params": {
            +        "filename": "문자열: 불러올 파일명 또는 URL",
            +        "callback": "함수: (선택 사항) <a href=\"#/p5/loadXML\">loadXML()</a>이 완료된 이후 실행될 함수, XML 객체를 1번째 인수로 전달",
            +        "errorCallback": "함수: (선택 사항) 에러 발생시 실행될 함수, 반응(response)이 1번째 인수로 전달"
            +      }
            +    },
            +    "loadBytes": {
            +      "description": [
            +        "이 방법은 최대 64MB 크기의 파일을 불러오는 데에 적합합니다."
            +      ],
            +      "returns": "객체: 'bytes' 속성을 로드 완료된 버퍼로서 갖는 객체",
            +      "params": {
            +        "file": "문자열: 불러올 파일명 또는 URL",
            +        "callback": "함수: (선택 사항) <a href=\"#/p5/loadBytes\">loadBytes()</a> 가 완료된 이후 실행될 함수",
            +        "errorCallback": "함수: (선택 사항) 에러 발생시 실행될 함수"
            +      }
            +    },
            +    "httpGet": {
            +      "description": [
            +        "HTTP GET 요청을 실행하는 메소드입니다. 별도의 데이터 유형(datatype)을 지정하지 않을 경우, p5는 URL을 기본값 텍스트로서 가정합니다. 이는 <code>httpDo(path, 'GET')</code>을 호출하는 것과 동일한 효과를 갖습니다. ‘binary’ 데이터 형식은 Blob 객체를, ‘arrayBuffer’ 데이터 형식은 지정된 형식의 배열(예: Uint8Array)을 초기화할 ArrayBuffer를 반환합니다."
            +      ],
            +      "returns": "약속: 작업 성공시 데이터로 해결되는 약속, 또는 오류 발생시 거부.",
            +      "params": {
            +        "path": "문자열: 불러올 파일명 또는 URL",
            +        "datatype": "문자열: \"json\",\"jsonp\",\"binary\",\"arrayBuffer\",\"xml\" 또는 \"text\"",
            +        "data": "객체|불리언: 요청과 함께 전달되는 매개변수 데이터",
            +        "callback": "함수: httpGet()이 완료된 이후 실행될 함수, 데이터를 1번째 인수로 전달",
            +        "errorCallback": "함수: (선택 사항) 에러 발생시 실행될 함수, 반응(response)이 1번째 인수로 전달"
            +      }
            +    },
            +    "httpPost": {
            +      "description": [
            +        "HTTP POST 요청을 실행하는 메소드입니다. 별도의 데이터 유형(datatype)을 지정하지 않을 경우, p5는 URL을 기본값 텍스트로서 가정합니다. 이는 httpDo(path, 'POST')를 호출하는 것과 동일한 효과를 갖습니다."
            +      ],
            +      "returns": "약속: 작업 성공시 데이터로 해결되는 약속, 또는 오류 발생시 거부",
            +      "params": {
            +        "path": "문자열: 불러올 파일명 또는 URL",
            +        "datatype": "문자열: \"json\",\"jsonp\",\"binary\",\"arrayBuffer\",\"xml\" 또는 \"text\". 생략할 경우, httpPost()가 임의로 가정합니다.",
            +        "data": "객체|불리언: (선택 사항) 요청과 함께 전달되는 매개변수 데이터",
            +        "callback": "함수: (선택 사항) httpPost()가 완료된 이후 실행될 함수, 데이터를 1번째 인수로 전달",
            +        "errorCallback": "함수: (선택 사항) 에러 발생시 실행될 함수, 반응(response)이 1번째 인수로 전달"
            +      }
            +    },
            +    "httpDo": {
            +      "description": [
            +        "HTTP 요청을 실행하는 메소드입니다. 별도의 데이터 유형(datatype)을 지정하지 않을 경우, p5는 URL을 기본값 텍스트로서 가정합니다.",
            +        "고급 응용 단계에서는 경로를 1번째 인수로, 객체를 2번째 인수로 전달할 수 있습니다. 서명은 Fetch API 사양을 따릅니다. 이 방법은 최대 64MB 크기의 파일을 불러오는 데에 적합합니다."
            +      ],
            +      "returns": "약속: 작업 성공시 데이터로 해결되는 약속, 또는 오류 발생시 거부",
            +      "params": {
            +        "path": "문자열: 불러올 파일명 또는 URL",
            +        "method": "문자열: \"GET\", \"POST\", \"PUT\" 중 하나, 기본값은 \"GET\"",
            +        "datatype": "문자열: (선택 사항) \"json\", \"jsonp\", \"xml\" 또는 \"text\"",
            +        "data": "객체: (선택 사항) 요청과 함께 전달되는 매개변수 데이터",
            +        "callback": "함수: (선택 사항) httpDo()가 완료된 이후 실행될 함수, 데이터를 1번째 인수로 전달",
            +        "errorCallback": "함수: (선택 사항) 에러 발생시 실행될 함수, 반응(response)이 1번째 인수로 전달",
            +        "options": "객체: <a href='https://developer.mozilla.org/ko/docs/Web/API/Fetch_API'>Fetch API 레퍼런스</a>에 따른 요청(request) 객체 옵션"
            +      }
            +    },
            +    "createWriter": {
            +      "returns": "p5.PrintWriter 객체",
            +      "params": {
            +        "name": "문자열: 생성될 파일의 이름",
            +        "extension": "문자열:"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "이미지, 텍스트, json, csv, wav, 또는 html을 저장합니다. 클라이언트 컴퓨터에 다운로드 대화 상자가 뜹니다. <b>save() 함수는 매 프레임마다 새로운 저장 대화 상자를 엽니다. 따라서, 반복 실행되는 함수인 <a href=\"#/p5/draw\">draw()</a> 안에서 save()를 호출하지 않는 것을 권장합니다.</b>",
            +        "첫 번째 매개변수는 캔버스 p5.Element애 대한 포인터, JSON 배열, JSON 객체, p5.Table, p5.Image, p5.SoundFile(p5.sound 필요)로 지정할 수 있습니다. 두 번째 매개변수로 파일명(확장자 포함)을 지정합니다. 세 번째 매개변수는 객체 유형에 따른 옵션을 설정합니다. 이 메소드는 사용자가 지정한 매개변수에 따라 파일을 저장합니다."
            +      ],
            +      "params": {
            +        "objectOrFilename": "객체|문자열: (선택 사항) 지정된 파일명에 따라 캔버스를 png 또는 jpg 확장자 이미지로 저장합니다. 객체 지정시, 객체와 파일명에 따라 저장합니다. (위의 예제 참고)",
            +        "filename": "문자열: (선택 사항) 객체를 1번째 매개변수로 지정할 경우, 2번째 매개변수는 파일명을 지시하게 되며, 이 경우 적절한 파일 확장자를 포함해야 합니다. (위의 예제 참고)",
            +        "options": "불리언|문자열: (선택 사항) 파일 유형에 따른 추가 옵션. 예를 들어 JSON을 저장할 경우, 참(true)은 결과물의 가독성이 아닌, 결과물 파일 크기의 최적화를 뜻합니다."
            +      }
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "배열 또는 JSON 객체의 내용을 .json 파일에 작성합니다. 파일 저장 처리 방식 및 저장 파일 위치는 웹 브라우저마다 다릅니다."
            +      ],
            +      "params": {
            +        "json": "배열|객체:",
            +        "filename": "문자열",
            +        "optimize": "불리언: (선택 사항) 참(true)일 경우, 출력 파일상 줄바꿈과 공백을 제거하여 파일 크기를 최적화합니다. (가독성은 최적화 제외)"
            +      }
            +    },
            +    "saveStrings": {
            +      "description": [
            +        "문자열 배열을 문자열당 1줄 단위로 텍스트 파일에 작성합니다. 파일 저장 처리 방식 및 저장 파일 위치는 웹 브라우저마다 다릅니다."
            +      ],
            +      "params": {
            +        "list": "문자열 배열[]: 작성할 문자열 배열",
            +        "filename": "문자열: 결과값을 위한 파일명",
            +        "extension": "문자열: (선택 사항) filename의 확장자",
            +        "isCRLF": "불리언: (선택 사항) 참(true)일 경우, 줄바꿈을 CRLF로 변환"
            +      }
            +    },
            +    "saveTable": {
            +      "description": [
            +        "테이블(<a href=\"#/p5.Table\">Table</a>) 객체의 내용을 파일에 작성합니다. 쉼표 단위로 값을 구분하는 텍스트 파일('csv')이 기본값으로 설정되지만, 탭 구분('tsv') 또는 HTML 테이블('html')도 생성가능합니다. 파일 저장 처리 방식 및 저장 파일 위치는 웹 브라우저마다 다릅니다."
            +      ],
            +      "params": {
            +        "Table": "p5.Table: 파일에 저장할 <a href=\"#/p5.Table\">Table</a> 객체",
            +        "filename": "문자열: Table을 저장할 파일명",
            +        "options": "문자열: (선택 사항) \"tsv\", \"csv\", \"html\" 중 하나"
            +      }
            +    },
            +    "abs": {
            +      "description": [
            +        "숫자의 절대값(크기)을 계산합니다. Math.abs()에 매핑합니다. 숫자의 절대값은 항상 양수입니다."
            +      ],
            +      "returns": "숫자: 지정된 숫자의 절대값",
            +      "params": {
            +        "n": "숫자: 계산할 숫자"
            +      }
            +    },
            +    "ceil": {
            +      "description": [
            +        "매개변수의 값보다 크거나 같은 수들 중, 가장 가까운 정수(int)값을 계산합니다. 예를 들어, Math.ceil()에 매핑합니다. 예를 들어, ceil(9.03)은 값 10을 반환합니다."
            +      ],
            +      "returns": "정수: 반올림된 숫자",
            +      "params": {
            +        "n": "숫자: 반올림할 숫자"
            +      }
            +    },
            +    "constrain": {
            +      "description": [
            +        "값을 최소값과 최대값 사이에 제한합니다."
            +      ],
            +      "returns": "숫자: 제한된 숫자",
            +      "params": {
            +        "n": "수자: 제한할 숫자",
            +        "low": "숫자: 최소 한계",
            +        "high": "숫자: 최대 한계"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "2차원 또는 3차원 상 두 점 사이의 거리를 계산합니다."
            +      ],
            +      "returns": "숫자: 두 점 사이의 거리",
            +      "params": {
            +        "x1": "숫자: 1번째 점의 x좌표값",
            +        "y1": "숫자: 1번째 점의 y좌표값",
            +        "x2": "숫자: 2번째 점의 y좌표값",
            +        "y2": "숫자: 1번째 점의 z좌표값",
            +        "z1": "숫자: 2번째 점의 x좌표값",
            +        "z2": "숫자: 2번째 점의 z좌표값"
            +      }
            +    },
            +    "exp": {
            +      "description": [
            +        "매개변수 n을 지수로 삼는 거듭 제곱 형식으로 오일러(Euler)의 수 e(2.71828...)를 반환합니다. Math.exp()에 매핑합니다."
            +      ],
            +      "returns": "숫자: e^n",
            +      "params": {
            +        "n": "숫자: 거듭 제곱의 지수"
            +      }
            +    },
            +    "floor": {
            +      "description": [
            +        "매개변수의 값보다 작거나 같은 수들 중, 가장 가까운 정수(int)값을 계산합니다. Math.floor()에 매핑합니다."
            +      ],
            +      "returns": "정수: 반내림된 숫자",
            +      "params": {
            +        "n": "숫자: 반내림할 숫자"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "지정된 증분(increment)을 통해 두 숫자 사이의 특정 숫자를 계산합니다. 여기서 매개변수 amt는 두 개의 값 사이를 선형적으로 보간합니다. 예를 들어, 0.0은 첫 번째 값과 동일한 색상값을, 0.1은 첫 번째 값에 매우 가까운 색상값을, 0.5는 두 값 사이의 중간 색상값을 나타내는 식입니다. 이 때, 0 미만의 값과 1이상의 값은 지정된 2개의 숫자의 비율에 따라 자동 처리됩니다. lerp() 함수는 직선 경로를 따라 모션을 생성하고 점선을 그리는 데에 사용됩니다."
            +      ],
            +      "returns": "숫자: 선형보간된 값",
            +      "params": {
            +        "start": "숫자: 1번째 값",
            +        "stop": "숫자: 2번째 값",
            +        "amt": "숫자: 숫자"
            +      }
            +    },
            +    "log": {
            +      "description": [
            +        "숫자의 자연 로그(밑이 e인 로그)를 계산합니다. 함수는 매개변수 n을 0.0보다 큰 값으로 예측합니다. Math.log()에 매핑합니다"
            +      ],
            +      "returns": "숫자: n의 자연 로그",
            +      "params": {
            +        "n": "숫자: 0보다 큰 숫자"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "벡터의 크기(또는 길이)를 계산합니다. 벡터는 컴퓨터 그래픽과 선형 대수에서 일반적으로 사용되며, 공간 속 방향을 뜻합니다. 벡터에는 시작점 개념이 없으므로, 그 크기는 좌표 0,0에서 x,y값까지의 거리에 비유할 수 있습니다. 이 점에서 mag()는 dist(0, 0, x, y)와 동일한 효과를 갖고 보다 간단하게 표현한 셈입니다."
            +      ],
            +      "returns": "숫자: (0,0)에서 (a,b)까지의 벡터 크기",
            +      "params": {
            +        "a": "숫자: 1번째 값",
            +        "b": "숫자: 2번째 값"
            +      }
            +    },
            +    "map": {
            +      "description": [
            +        "숫자의 범위를 다른 범위로 다시 매핑합니다.",
            +        "첫 번째 예제의 숫자 25는 화면상 좌측 상단 모퉁이(0)부터 우측 변(너비)에 이르는 범위에 해당하는데, 이는 0부터 100 사이에 해당하는 본래 범위에서 변환된 것입니다."
            +      ],
            +      "returns": "숫자: 다시 매핑된 숫자",
            +      "params": {
            +        "value": "숫자: 변환할 값",
            +        "start1": "숫자: 값의 현재 범위의 하한",
            +        "stop1": "숫자: 값의 현재 범위의 상한",
            +        "start2": "숫자: 값의 대상 범위의 하한",
            +        "stop2": "숫자: 값의 대상 범위의 상한",
            +        "withinBounds": "불리언: (선택 사항) 값을 새로 매핑된 범위에 제한"
            +      }
            +    },
            +    "max": {
            +      "description": [
            +        "일련의 숫자들 중, 가장 큰 값을 확인하고 이를 반환합니다. max() 함수는 매개변수 Number로 지정된 모든 숫자 또는 모든 길의의 배열을 허용합니다."
            +      ],
            +      "returns": "숫자: 최대 숫자",
            +      "params": {
            +        "n0": "숫자: 비교할 숫자",
            +        "n1": "숫자: 비교할 숫자",
            +        "nums": "숫자 배열[]: 비교할 숫자"
            +      }
            +    },
            +    "min": {
            +      "description": [
            +        "일련의 숫자들 중, 가장 작은 값을 확인하고 이를 반환합니다. min() 함수는 매개변수 Number로 지정된 모든 숫자 또는 모든 길의의 배열을 허용합니다."
            +      ],
            +      "returns": "숫자: 최소 숫자",
            +      "params": {
            +        "n0": "숫자: 비교할 숫자",
            +        "n1": "숫자: 비교할 숫자",
            +        "nums": "숫자 배열[]: 비교할 숫자"
            +      }
            +    },
            +    "norm": {
            +      "description": [
            +        "특정 범위 내의 숫자를 0과 1 범위의 값으로 정규화합니다. 이는 map(value, low, high, 0, 1)과도 동일한 효과를 갖습니다. 숫자가 0과 1 범위를 벗어나더라도, 사용자의 의도와 활용 가능성을 감안하여 0과 1 사이의 값으로 재고정하지 않습니다. (위의 예제에 표시되어 있습니다.)"
            +      ],
            +      "returns": "숫자: 정규화된 숫자",
            +      "params": {
            +        "value": "숫자: 정규화될 값",
            +        "start": "숫자: 값의 현재 범위 하한",
            +        "stop": "숫자: 값의 현재 범위 상한"
            +      }
            +    },
            +    "pow": {
            +      "description": [
            +        "pow() 함수는 지수 식을 효율적으로 사용하는 한 방법으로, 특정 숫자(또는 그 역수)를 반복하여 곱할 수 있습니다. 예를 들어, pow(3,5)는 3 x 3 x 3 x 3 x 3과 같고, pow(3,-5)는 1 / 3 x 3 x 3 x 3 x 3과 같습니다. Math.pow()에 매핑합니다."
            +      ],
            +      "returns": "숫자:n^e",
            +      "params": {
            +        "n": "숫자: 지수 식의 밑",
            +        "e": "숫자: 거듭 제곱의 지수"
            +      }
            +    },
            +    "round": {
            +      "description": [
            +        "매개변수 n에 가장 가까운 정수를 계산합니다. 예를 들어, round(133.8)은 값 134를 반환합니다. Math.round()에 매핑합니다."
            +      ],
            +      "returns": "정수: 반올림된 숫자",
            +      "params": {
            +        "n": "숫자: 반올림할 숫자",
            +        "decimals": "숫자: (선택 사항) 반올림할 소수점 자릿수, 기본값은 0"
            +      }
            +    },
            +    "sq": {
            +      "description": [
            +        "숫자를 제곱합니다. 음수를 제곱하면 그 결과는 항상 양수로 나옵니다. (예: -1 * -1 = 1)"
            +      ],
            +      "returns": "숫자: 제곱된 숫자",
            +      "params": {
            +        "n": "숫자: 제곱할 숫자"
            +      }
            +    },
            +    "sqrt": {
            +      "description": [
            +        "숫자의 제곱근을 계산합니다. 유효한 음의 근이 있더라도 제곱근은 항상 양수가 됩니다. 숫자 a의 제곱근은 s * s = a와 같습니다. 제곱의 반대입니다. Math.sqrt()에 매핑됩니다."
            +      ],
            +      "returns": "숫자: 숫자의 제곱근",
            +      "params": {
            +        "n": "숫자: 음수가 아닌 제곱근"
            +      }
            +    },
            +    "fract": {
            +      "description": [
            +        "숫자의 분수값을 계산합니다. 즉, 소숫자리를 계산합니다. 예를 들어, fract(3.146)은 0.146을 반환합니다."
            +      ],
            +      "returns": "숫자: 숫자 x의 분수값, i.e, {x}",
            +      "params": {
            +        "num": "숫자: 분수값 찾을 숫자"
            +      }
            +    },
            +    "createVector": {
            +      "description": [
            +        "새로운 <a href=\"#/p5.Vector\">p5.Vector</a>를 생성합니다. 이 <a href=\"#/p5.Vector\">p5.Vector</a>는 벡터를 저장하는 데이터형식입니다. 2차원 및 3차원 벡터, 특히 유클리드 (기하학) 벡터를 갖고 있입니다. 벡터는 크기와 방향을 모두 지닌 개체입니다."
            +      ],
            +      "returns": "p5.Vector:",
            +      "params": {
            +        "x": "숫자: (선택 사항) 벡터의 x성분",
            +        "y": "숫자: (선택 사항) 벡터의 y성분",
            +        "z": "숫자: (선택 사항) 벡터의 z성분"
            +      }
            +    },
            +    "noise": {
            +      "description": [
            +        "지정된 좌표에서의 펄린 노이즈(Perlin noise)값을 반환합니다. 일반 random() 함수에 비해, 펄린 노이즈는 고조파 연속 숫자를 보다 자연스러운 시퀀스로 생성합니다. 켄 펄린(Ken Perlin)이 1980년대에 발명하였으며, 그래픽 응용 프로그램상 절차적 텍스처, 자연스러운 모션, 형상, 지형 등을 생성하는 데에 사용됩니다.",
            +        "<b>random()</b> 함수와의 주요 차이점은, 펄린 노이즈가 반-무작위 값을 갖는 고정 좌표쌍을 n차원의 무한 공간에서 정의한다는 점에 있습니다. (이는 프로그램의 수명 동안에만 고정되며, 관련해서는 noiseSeed()함수를 참고할 수 있습니다.) p5.js는 사용자가 지정한 좌표 개수에 따라 1D, 2D, 3D 노이즈를 계산할 수 있습니다. 결과값은 항상 0.0과 1.0 사이입니다. 위의 예제처럼, 노이즈값은 공간 이동을 통해 애니메이션화 될 수 있습니다. 2차원 및 3차원 역시 시간으로 해석될 수 있습니다.",
            +        "노이즈 함수의 주파수 사용은 실제 오디오 신호와 유사하게 구성됩니다. 물리학에서의 고조파 개념과 마찬가지로, 펄린 노이즈는 여러 옥타브에 걸쳐 계산되며, 최종 결과 생성을 위해 모든 옥타브를 합칩니다.",
            +        "입력 좌표값의 크기를 통해서도 결과 시퀀스의 문자를 조정할 수 있습니다. 함수는 무한 공간 속에서 작동하기 때문에 좌표값이 크게 중요하지 않지만, 연속된 좌표들 사이의 거리만큼은 중요합니다 (예: 반복문 내에서 noise()를 실행하는 경우). 일반적으로, 좌표들 간의 거리차가 적을수록 노이즈 시퀀스가 더 매끄러워집니다. 0.0005부터 0.03 사이의 단계가 대부분의 응용 프로그램에서 사용하기에 가장 적합하나, 사용에 따라 달라질 수 있습니다."
            +      ],
            +      "returns": "숫자: 지정된 좌표에서의 펄린 노이즈 값 (0과 1 사이)",
            +      "params": {
            +        "x": "숫자: 노이즈 공간 속 x좌표값",
            +        "y": "숫자: (선택 사항) 노이즈 공간 속 y좌표값",
            +        "z": "숫자: (선택 사항) 노이즈 공간 속 z좌표값"
            +      }
            +    },
            +    "noiseDetail": {
            +      "description": [
            +        "펄린 노이즈 함수로 생성되는 문자와 세부 레벨을 조정합니다. 물리학의 고조파처럼, 노이즈 역시 여러 옥타브에 걸쳐 계산됩니다. 낮은 옥타브는 출력 신호에 더 많이 기여함으로써 노이즈의 전체 강도를 정의하는 반면, 높은 옥타브는 노이즈 시퀀스에서 세밀한 디테일을 만듭니다.",
            +        "기본값으로, 노이즈는 4 옥타브 이상으로 계산되고 각 옥타브는 이전 옥타브의 정확히 절반을 기여하도록 설정됩니다. 즉, 2번째 옥타브는 1번째 옥타브의 강도 50%에서 시작하는 식입니다. 이러한 감소량은 추가 매개변수를 통해 변경할 수 있습니다. 예: 감소 계수 0.75는 각 옥타브가 이전 하위 옥타브의 75%만큼 영향(25% 감소)을 받는다는 것을 뜻합니다. 0.0과 1.0 사이의 모든 값이 유효하나, 0.5보다 큰 값은 noise()에 의해 반환된 1.0보다 더 큰 결과값을 가질 수 있습니다.",
            +        "이처럼 매개변수를 변경하여, noise() 함수가 생성한 신호를 매우 구체적인 요구와 특성에 맞게 조정할 수 있습니다."
            +      ],
            +      "params": {
            +        "lod": "숫자: 노이즈가 사용한 옥타브 개수",
            +        "falloff": "숫자: 각 옥타브에 대한 감소 계수"
            +      }
            +    },
            +    "noiseSeed": {
            +      "description": [
            +        "noise()의 시드(seed) 값을 설정합니다. 기본적으로, noise()는 소프트웨어 프로그램이 실행될 때마다 매번 다른 결과를 생성합니다. 매 실행마다 동일한 유사-난수(random)를 반환하려면 매개변수 value를 상수로 설정합니다."
            +      ],
            +      "params": {
            +        "seed": "숫자: 시드값"
            +      }
            +    },
            +    "randomSeed": {
            +      "description": [
            +        "random() 함수의 시드(seed) 값을 설정합니다.",
            +        "기본적으로, random()은 소프트웨어 프로그램이 실행될 때마다 매번 다른 결과를 생성합니다. 매 실행마다 동일한 유사-난수(random)를 반환하려면 매개변수 value를 상수로 설정해야 합니다."
            +      ],
            +      "params": {
            +        "seed": "숫자: 시드값"
            +      }
            +    },
            +    "random": {
            +      "description": [
            +        "임의의 부동 소수점 숫자, 즉 실수(float)를 반환합니다.",
            +        "0, 1, 또는 2개의 인수를 사용합니다.",
            +        "별도의 인수를 지정하지 않을 경우, 0부터 1미만 사이의 난수(random)를 반환합니다.",
            +        "1개의 인수를 숫자로 지정할 경우, 0부터 해당 숫자 미만 사이의 난수를 반환합니다.",
            +        "1개의 인수를 배열로 지정할 경우, 해당 배열로부터 임의의 요소를 반환합니다.",
            +        "2개의 인수를 지정할 경우, 1번째 인수에서 2번째 인수 미만 사이의 난수를 반환합니다."
            +      ],
            +      "returns": "숫자: 난수",
            +      "params": {
            +        "min": "숫자: (선택 사항) 해당 숫자를 포함한 하한",
            +        "max": "숫자: (선택 사항) 해당 숫자를 제외한 상한",
            +        "choices": "배열: 요소를 골라올 배열"
            +      }
            +    },
            +    "randomGaussian": {
            +      "description": [
            +        "가우스 및 정규 분포에 맞는 난수를 반환합니다. randomGaussian()이 반환할 수 있는 최소값이나 최대값 개념은 이론상 없습니다. 평균으로부터 멀리 떨어진 값이 반환될 확률은 매우 낮고, 평균 근처의 숫자가 반환될 확률이 높습니다.",
            +        "0, 1, 또는 2개의 인수를 사용합니다.",
            +        "별도의 인수를 지정하지 않을 경우, 평균으로 0을, 표준 편차로 1을 반환합니다.",
            +        "1개의 인수를 지정할 경우, 해당 인수가 평균입니다. (표준 편차는 1)<br>2개의 인수를 지정할 경우, 1번째 인수는 평균, 2번째 인수는 표준 편차입니다."
            +      ],
            +      "returns": "숫자: 난수",
            +      "params": {
            +        "mean": "숫자: 평균",
            +        "sd": "숫자: 표준 편차"
            +      }
            +    },
            +    "acos": {
            +      "description": [
            +        "<a href=\"#/p5/cos\">cos()</a> 함수의 역으로, 값의 아크 코사인을 반환합니다. 이 함수는 -1부터 1까지 범위 내의 값을 예상하고, 0부터 PI(3.1415927)까지 범위 내의 값을 반환합니다."
            +      ],
            +      "returns": "숫자: 지정된 값의 아크 코사인",
            +      "params": {
            +        "value": "숫자: 아크 코사인으로 반환될 값"
            +      }
            +    },
            +    "asin": {
            +      "description": [
            +        "<a href=\"#/p5/sin\">sin()</a> 함수의 역으로, 값의 아크 사인을 반환합니다. 이 함수는 -1부터 1까지 범위 내의 값을 예상하고, -PI/2부터 PI/2까지 범위 내의 값을 반환합니다."
            +      ],
            +      "returns": "숫자: 지정된 값의 아크 사인",
            +      "params": {
            +        "value": "숫자: 아크 사인으로 반환될 값"
            +      }
            +    },
            +    "atan": {
            +      "description": [
            +        "<a href=\"#/p5/tan\">tan()</a> 함수의 역으로, 값의 아크 탄젠트를 반환합니다. 이 함수는 -무한부터 무한 미만까지 범위 내의 값을 예상하고, -PI/2부터 PI/2까지 범위 내의 값을 반환합니다."
            +      ],
            +      "returns": "숫자: 지정된 값의 아크 탄젠트",
            +      "params": {
            +        "value": "숫자: 아크 탄젠트로 반환될 값"
            +      }
            +    },
            +    "atan2": {
            +      "description": [
            +        "양의 x축상의 특정 좌표로부터 좌표 원점을 향한 각도(라디안, radian)를 계산합니다. 값은 PI부터 -PI까지 범위 내의 실수(float)로 반환됩니다. atan2() 함수는 도형을 커서 위치에 맞추는 데에 자주 사용됩니다.",
            +        "참고: 접선 계산 방식에 따라 1번째 매개변수를 점의 y좌표로, 2번째 매개변수를 x좌표로 지정합니다."
            +      ],
            +      "returns": "숫자: 지정된 점의 아크 탄젠트",
            +      "params": {
            +        "y": "숫자: 점의 y좌표값",
            +        "x": "숫자: 점의 x좌표값"
            +      }
            +    },
            +    "cos": {
            +      "description": [
            +        "각도의 코사인을 계산합니다. 이 함수는 현재 설정된 <a href=\"#/p5/angleMode\">angleMode</a>를 반영합니다. 값은 -1부터 1까지의 범위 내에서 반환됩니다."
            +      ],
            +      "returns": "숫자: 각도의 코사인",
            +      "params": {
            +        "angle": "숫자: 각도"
            +      }
            +    },
            +    "sin": {
            +      "description": [
            +        "각도의 사인을 계산합니다. 이 함수는 현재 설정된 <a href=\"#/p5/angleMode\">angleMode</a>를 반영합니다. 값은 -1부터 1까지의 범위 내에서 반환됩니다."
            +      ],
            +      "returns": "숫자: 각도의 사인",
            +      "params": {
            +        "angle": "숫자: 각도"
            +      }
            +    },
            +    "tan": {
            +      "description": [
            +        "각도의 탄젠트를 계산합니다. 이 함수는 현재 설정된 <a href=\"#/p5/angleMode\">angleMode</a>를 반영합니다. 모든 실수 범위 내에서의 값을 반환됩니다."
            +      ],
            +      "returns": "숫자: 각도의 탄젠트",
            +      "params": {
            +        "angle": "숫자: 각도"
            +      }
            +    },
            +    "degrees": {
            +      "description": [
            +        "라디안(radian) 측정값을 도(degree) 단위에 해당하는 값으로 변환합니다. 라디안과 도는 같은 것을 측정하는 2개의 다른 단위입니다. 원은 360도이면서 동시에 2*PI 라디안이기도 합니다. 또, 90° = PI/2 = 1.5707964 가 성립합니다. 이 함수는 현재 설정된 <a href=\"#/p5/angleMode\">angleMode</a>를 반영하지 않습니다."
            +      ],
            +      "returns": "숫자: 변환된 각도",
            +      "params": {
            +        "radians": "숫자: 도 단위로 변환할 라디안값"
            +      }
            +    },
            +    "radians": {
            +      "description": [
            +        "도(degree) 측정값을 라디안(radian) 단위에 해당하는 값으로 변환합니다. 라디안과 도는 같은 것을 측정하는 2개의 다른 단위입니다. 원은 360도이면서 동시에 2*PI 라디안이기도 합니다. 또, 90° = PI/2 = 1.5707964 가 성립합니다. 이 함수는 현재 설정된 <a href=\"#/p5/angleMode\">angleMode</a>를 반영하지 않습니다"
            +      ],
            +      "returns": "숫자: 변환된 각도",
            +      "params": {
            +        "degrees": "숫자: 라디안 단위로 변환할 도 값"
            +      }
            +    },
            +    "angleMode": {
            +      "description": [
            +        "p5의 현재 모드를 설정합니다. 기본 모드는 RADIANS(라디안) 입니다."
            +      ],
            +      "params": {
            +        "mode": "상수: RADIANS 또는 DEGREES 중 하나"
            +      }
            +    },
            +    "textAlign": {
            +      "description": [
            +        "텍스트 그리기에 대한 현재 정렬을 설정합니다. horizAlign(LEFT, CENTER, 또는 RIGHT)와 vertAlign(TOP, BOTTOM, CENTER, 또는 BASELINE)이라는 2개의 인수를 받습니다.",
            +        "매개변수 horizAlign은 <a href=\"#/p5/text\">text()</a> 함수의 x값을, 매개변수 vertAlign은 y값을 참조합니다.",
            +        "따라서, textAlign(LEFT)는 텍스트의 왼쪽 가장자리를 <a href=\"#/p5/text\">text()</a>에서 지정된 x값에 정렬합니다. textAlign(RIGHT, TOP)은 텍스트의 오른쪽 가장자리를 x값에, 텍스트의 가장자리 위쪽을 y값에 정렬합니다.",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "horizAlign": "상수: 가로 정렬, LEFT, CENTER, 또는 RIGHT 중 하나",
            +        "vertAlign": "상수: 세로 정렬, TOP, BOTTOM, CENTER, 또는 BASELINE 중 하나"
            +      }
            +    },
            +    "textLeading": {
            +      "description": [
            +        "텍스트 줄 사이의 간격을 픽셀 단위로 받아오거나 설정(get/set)합니다. 이 설정은 <a href=\"#/p5/text\">text()</a> 함수 이후에 호출되는 모든 함수들에 적용됩니다."
            +      ],
            +      "params": {
            +        "leading": "숫자: 픽셀 단위의 행간 간격"
            +      }
            +    },
            +    "textSize": {
            +      "description": [
            +        "현재 폰트 크기를 받아오거나 설정(get/set)합니다. 설정된 크기는 <a href=\"#/p5/text\">text()</a> 함수 이후에 호출되는 모든 함수들에 적용됩니다. 폰트 크기는 픽셀 단위로 측정됩니다."
            +      ],
            +      "params": {
            +        "theSize": "숫자: 픽셀 단위의 폰트 크기"
            +      }
            +    },
            +    "textStyle": {
            +      "description": [
            +        "시스템 글꼴의 텍스트 스타일을 NORMAL, ITALIC, BOLD, 또는 BOLD ITALIC으로 받아오거나 설정(get/set)합니다. 참고: 해당 설정은 CSS 스타일에 의해 재정의될 수 있습니다. 시스템 글꼴이 아닌 글꼴(개방형, 트루 타입 등)을 사용할 경우, 스타일이 지정된 글꼴을 대신 불러옵니다."
            +      ],
            +      "params": {
            +        "theStyle": "상수: 글꼴 설정, NORMAL, ITALIC, 또는 BOLD 중 하나"
            +      }
            +    },
            +    "textWidth": {
            +      "description": [
            +        "문자 또는 텍스트 문자열의 너비를 계산하고 반환합니다."
            +      ],
            +      "returns": "숫자",
            +      "params": {
            +        "theText": "문자열: 측정할 문자열"
            +      }
            +    },
            +    "textAscent": {
            +      "description": [
            +        "폰트의 현재 크기를 증가한 값을 반환합니다. 증가값은 기준선에서 가장 높이 뻗어있는 문자까지의 거리를 픽셀 단위로 나타냅니다."
            +      ],
            +      "returns": "숫자:"
            +    },
            +    "textDescent": {
            +      "description": [
            +        "폰트의 현재 크기를 감소한 값을 반환합니다. 감소값은 기준선에서 가장 밑으로 뻗어있는 문자까지의 거리를 픽셀 단위로 나타냅니다."
            +      ],
            +      "returns": "숫자:"
            +    },
            +    "textWrap": {
            +      "description": [
            +        "텍스트 상자에서 텍스트의 줄 바꿈 (wrap)을 설정합니다. 이것를 하기 위해서는 텍스트 너비의 최댓값을 지정해야하며, 이것은 <a href=\"#/p5/text\">text()</a> 함수의 <code>x2</code> 매개변수로 설정됩니다.",
            +        "WORD의 줄 바꿈 형식은 줄을 띄어쓰기 부분에서만 바꿉니다. 즉, 캔버스 또는 텍스트 상자의 너비를 초과하며 띄움이 없는 하나의 문자열의 경우에는 원하는 너비를 넘어 캔버스의 경계에서 벗어납니다. 이럴 때, 벗어난 문자열의 나머지는 보이지 않습니다.",
            +        "CHAR의 줄 바꿈 형식은 텍스트 상자 안에 있기 위해 필요한 부분에서 자동적으로 띄움 또는 글자에 상관없이 줄을 바꿉니다.",
            +        "WORD의 형식이 기본값이며, 두 형식은 모두 수동적 줄 바꿈 (<code>\\n</code>)에서 줄을 바꿉니다. 텍스트 상자의 높이 최댓값은 (<code>y2</code>)이며, 이는 형식에 상관없이 유효합니다. 즉, 텍스트가 상자 안 높이보다 많을 경우 남는 글자는 스크린에 표시되지 않습니다."
            +      ],
            +      "returns": "문자열: wrapStyle (줄 바꿈 형식)",
            +      "params": {
            +        "wrapStyle": "Constant: 줄 바꿈 형식, WORD 또는 CHAR"
            +      }
            +    },
            +    "loadFont": {
            +      "description": [
            +        "파일 또는 URL로부터 폰트 파일(.otf, .ttf)을 불러오고, PFont 객체를 반환합니다.",
            +        "이는 비동기적 메소드로, 스케치상의 다음 코드 줄이 실행되기 전에 함수 실행이 완료되지 않을 수 있습니다.",
            +        "폰트의 경로는 스케치상 링크된 HTML 파일을 기준으로 합니다. 브라우저의 내장 보안으로 인해 URL 또는 다른 원격 경로에서 폰트를 불러오는 것이 차단될 수 있습니다.",
            +        "[1번째 예제] <a href=\"#/p5/preload\">preload()</a> 함수 안에 loadJSON() 함수를 호출하여, 모든 불러오기 작업이 <a href=\"#/p5/setup\">setup()</a>과 <a href=\"#/p5/draw\">draw()</a> 함수가 호출되기에 앞서 완료되도록 처리합니다.",
            +        "[2번째 예제] <a href=\"#/p5/preload\">preload()</a> 함수 밖의 영역에서 콜백 함수를 2번째 예제와 같이 작성하여 객체를 처리할 수 있습니다.",
            +        ""
            +      ],
            +      "returns": "p5.Font: p5.Font 객체",
            +      "params": {
            +        "path": "문자열: 불러올 파일명 또는 URL",
            +        "callback": "함수: (선택 사항) <a href=\"#/p5/loadFont\">loadFont()</a>가 완료된 이후 실행될 함수",
            +        "onError": "함수: 에러 발생시 실행될 함수"
            +      }
            +    },
            +    "text": {
            +      "description": [
            +        "화면에 텍스트를 그립니다. 1번째 매개변수로 지정된 정보를 추가 매개변수로 지정한 화면 위치에 나타냅니다. textFont() 함수로 별도 폰트를 지정하지 않을 경우, 기본 폰트가 사용됩니다. textSize()로 별도의 글자 크기를 지정하지 않을 경우, 기본 글자 크기가 사용됩니다. fill() 함수로 텍스트의 색상을 변경할 수 있습니다. stroke() 및 strokeWeight() 함수로 텍스트의 윤곽선을 변경할 수 있습니다.",
            +        "텍스트는 textAlign() 함수의 매개변수에 따라 좌표를 기준으로 왼쪽, 오른쪽, 그리고 중심에서 텍스트를 그릴 수 있습니다.",
            +        "매개변수 x2와 y2는 화면에 나타날 텍스트 상자의 영역을 정의하며, 문자열 데이터에만 사용됩니다. 이 매개변수들은 현재 rectMode() 설정에 따라 해석됩니다. 사용자가 지정한 텍스트 상자 크기에 맞지 않는 텍스트는 그려지지 않습니다. 별도의 x2와 y2를 지정하지 않을 경우, 기준선 정렬이 기본값으로 제공됩니다. 즉, 텍스트가 x와 y로부터 위쪽으로 그려집니다.",
            +        "WebGL: 개방형(opentype)/트루 타입(truetype) 폰트만 지원됩니다. 반드시 <a href=\"#/p5/loadFont\">loadFont()</a> 메소드를 사용하여 폰트를 불러와야 합니다 (위의 예제 참고). stroke()는 현재 WebGL 모드에서 아무런 효과를 갖지 않습니다."
            +      ],
            +      "params": {
            +        "str": "문자열|객체|배열|숫자|불리언: 표시할 영숫자 기호",
            +        "x": "숫자: 텍스트의 x좌표값",
            +        "y": "숫자: 텍스트의 y좌표값",
            +        "x2": "숫자: (선택 사항) 기본값은 텍스트 상자의 너비, 자세한 사항은 rectMode()에 있습니다.",
            +        "y2": "숫자: (선택 사항) 기본값은 텍스트 상자의 높이, 자세한 사항은 rectMode()에 있습니다."
            +      }
            +    },
            +    "textFont": {
            +      "description": [
            +        "<a href=\"#/p5/text\">text()</a> 함수로 그릴 현재 폰트를 설정합니다.",
            +        "WebGL: <a href=\"#/p5/loadFont\">loadFont()</a>를 통해 불러온 폰트만 지원합니다.",
            +        ""
            +      ],
            +      "returns": "객체: 현재 폰트 또는 p5 객체",
            +      "params": {
            +        "font": "객체|문자열: <a href=\"#/p5/loadFont\">loadFont()</a>로 불러온 폰트 또는 <a href = 'https://developer.mozilla.org/ko/docs/Learn/CSS/Styling_text/Fundamentals#Web_safe_fonts'>웹 안전 폰트</a>(일반적으로 모든 시스템에서 사용가능한 폰트)를 나타내는 문자열",
            +        "size": "숫자: (선택 사항) 사용할 폰트 크기"
            +      }
            +    },
            +    "append": {
            +      "description": [
            +        "사용 불가: append()는 더이상 사용 불가하며, p5의 추후 버전에서 제거됩니다. <a href='https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/push'>array.push(value)</a>를 대신 사용할 수 있습니다.",
            +        "배열의 끝에 값을 추가하여, 그 길이를 1씩 확장합니다. Array.push()에 매핑합니다."
            +      ],
            +      "returns": "배열: 추가된 배열",
            +      "params": {
            +        "array": "배열: 추가할 배열",
            +        "value": "전부: 배열에 추가될 모든 것"
            +      }
            +    },
            +    "arrayCopy": {
            +      "description": [
            +        "사용 불가: copyArray()는 더이상 사용 불가하며, p5의 추후 버전에서 제거됩니다. 배열(또는 그 일부)을 다른 배열에 복사합니다. src 배열이 dst 배열에 복사되며, srcPosition으로 지정된 위치에서 시작하여 dstPosition으로 지정된 위치를 향합니다. 복사할 요소의 개수는 배열의 길이로 결정됩니다. 값을 복사하면 대상 배열의 기존값을 덮어씁니다. 덮어쓰기없이 값을 추가하려면 <a href=\"#/p5/concat\">concat()</a>을 사용합니다.",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "src": "Array: the source Array",
            +        "srcPosition": "Integer: starting position in the source Array",
            +        "dst": "Array: the destination Array",
            +        "dstPosition": "Integer: starting position in the destination Array",
            +        "length": "Integer: number of Array elements to be copied"
            +      }
            +    },
            +    "concat": {
            +      "description": [
            +        "사용 불가: concat()은 더이상 사용 불가하며, p5의 추후 버전에서 제거됩니다. <a href='https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/concat'>arr1.concat(arr2)</a>를 대신 사용할 수 있습니다.",
            +        ""
            +      ],
            +      "returns": "배열: concatenated array",
            +      "params": {
            +        "a": "Array: first Array to concatenate",
            +        "b": "Array: second Array to concatenate"
            +      }
            +    },
            +    "reverse": {
            +      "description": [
            +        "사용 불가: reverse()는 더이상 사용 불가하며, p5의 추후 버전에서 제거됩니다.<a href='https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse'>array.reverse()</a>를 대신 사용할 수 있습니다."
            +      ],
            +      "returns": "배열: the reversed list",
            +      "params": {
            +        "list": "Array: Array to reverse"
            +      }
            +    },
            +    "shorten": {
            +      "description": [
            +        "사용 불가: shorten()은 더이상 사용 불가하며, p5의 추후 버전에서 제거됩니다. <a href='https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/pop'>array.pop()</a>를 대신 사용할 수 있습니다.",
            +        ""
            +      ],
            +      "returns": "배열: shortened Array",
            +      "params": {
            +        "list": "Array: Array to shorten"
            +      }
            +    },
            +    "shuffle": {
            +      "description": [
            +        "사용 불가: shuffle()은 더이상 사용 불가하며, p5의 추후 버전에서 제거됩니다. <a hreh='https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array'>자바스크립트의 배열 섞기</a>를 대신 사용할 수 있습니다.",
            +        "<a href = 'https://bost.ocks.org/mike/shuffle/'>피셔-예이츠(Fisher-Yates) 셔플 알고리즘</a>을 구현합니다."
            +      ],
            +      "returns": "배열: shuffled Array",
            +      "params": {
            +        "array": "Array: Array to shuffle",
            +        "bool": "Boolean: (Optional) modify passed array"
            +      }
            +    },
            +    "sort": {
            +      "description": [
            +        "사용 불가: sort()는 더이상 사용 불가하며, p5의 추후 버전에서 제거됩니다. <a href='https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort'>array.sort()</a>를 대신 사용할 수 있습니다.",
            +        ""
            +      ],
            +      "returns": "배열: the sorted list",
            +      "params": {
            +        "list": "Array: Array to sort",
            +        "count": "Integer: (Optional) number of elements to sort, starting from 0"
            +      }
            +    },
            +    "splice": {
            +      "description": [
            +        "사용 불가: splice()는 더이상 사용 불가하며, p5의 추후 버전에서 제거됩니다. <a href='https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice'>array.splice()</a>를 대신 사용할 수 있습니다.",
            +        ""
            +      ],
            +      "returns": "배열: the list",
            +      "params": {
            +        "list": "Array: Array to splice into",
            +        "value": "Any: value to be spliced in",
            +        "position": "Integer: in the array from which to insert data"
            +      }
            +    },
            +    "subset": {
            +      "description": [
            +        "사용 불가:subset()은 더이상 사용 불가하며, p5의 추후 버전에서 제거됩니다. <a href='https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/slice'>array.slice()</a>를 대신 사용할 수 있습니다.",
            +        ""
            +      ],
            +      "returns": "배열: Array of extracted elements",
            +      "params": {
            +        "list": "Array: Array to extract from",
            +        "start": "Integer: position to begin",
            +        "count": "Integer: (Optional) number of values to extract"
            +      }
            +    },
            +    "float": {
            +      "description": [
            +        "문자열을 실수(float), 즉 부동 소수점 숫자형 표현으로 변환합니다. 이 때, 문자열의 구문은 숫자 형식과 유사해야 합니다. 그렇지 않으면 NaN(숫자 아님)이 반환됩니다. 예컨대, float (\"1234.56\")은 1234.56으로 연산되지만, float (\"giraffe\")는 NaN을 반환합니다.",
            +        "전달된 배열과 길이가 동일한 실수 배열이 반환됩니다."
            +      ],
            +      "returns": "숫자: 문자열의 부동 소수점 숫자형 표현",
            +      "params": {
            +        "str": "문자열: 구문 분석할 실수 문자열"
            +      }
            +    },
            +    "int": {
            +      "description": [
            +        "불리언(boolean), 문자열(string), 부동소수점 숫자(float)를 정수(int)형 표현으로 변환합니다. 전달된 배열과 길이가 동일한 정수 배열이 반환됩니다."
            +      ],
            +      "returns": "숫자: 값의 정수형 표현",
            +      "params": {
            +        "n": "문자열|불리언|숫자: 구문 분석할 값",
            +        "radix": "정수: (선택 사항) 기수로 변환 (기본값: 10)",
            +        "ns": "배열: 구문 분석할 값"
            +      }
            +    },
            +    "str": {
            +      "description": [
            +        "불리언(boolean), 문자열(string), 또는 숫자를 문자열 표현으로 변환합니다. 전달된 배열과 길이가 동일한 문자열 배열이 반환됩니다."
            +      ],
            +      "returns": "숫자: 값의 문자열 표현",
            +      "params": {
            +        "n": "문자열|불리언|숫자: 구문 분석할 값"
            +      }
            +    },
            +    "byte": {
            +      "description": [
            +        "숫자, 숫자의 문자열 표현, 또는 불리언을 바이트 표현으로 변환합니다. 바이트는 -128과 127 사이의 정수이므로, 이 범위를 벗어난 값은 상응하는 바이트 표현에 래핑됩니다. 숫자, 문자열, 또는 불리언 값의 배열을 전달하면, 동일한 길이의 바이트 배열이 반환됩니다."
            +      ],
            +      "returns": "값의 바이트형 표현",
            +      "params": {
            +        "n": "문자열|불리언|숫자: 구문 분석할 값",
            +        "ns": "배열: 구문 분석할 값"
            +      }
            +    },
            +    "char": {
            +      "description": [
            +        "숫자나 문자열을 단일 문자형(character) 문자열 표현으로 변환합니다. 사용자가 별도 지정한 문자열 매개변수의 경우, 먼저 정수로서 구문 분석된 후 단일 문자형 문자열로 변환됩니다. 숫자 또는 문자열 값의 배열을 전달하면, 동일한 길이의 단일 문자형 문자열이 반환됩니다."
            +      ],
            +      "returns": "값의 문자열 표현",
            +      "params": {
            +        "n": "문자열|숫자: 구문 분석할 값",
            +        "ns": "배열: 구문 분석할 값"
            +      }
            +    },
            +    "unchar": {
            +      "description": [
            +        "단일 문자형 문자열 표현을 정수로 변환합니다. 단일 문자열 문자열 값의 배열을 전달하면, 동일한 길이의 정수 배열이 반환됩니다."
            +      ],
            +      "returns": "값의 정수형 표현",
            +      "params": {
            +        "n": "문자열: 구문 분석할 값",
            +        "ns": "배열: 구문 분석할 값"
            +      }
            +    },
            +    "hex": {
            +      "description": [
            +        "숫자를 16진수 문자열로 변환합니다. 전달된 2번째 매개변수는 16진수 표기법으로 생성할 문자 개수를 설정합니다. 배열이 전달되면, 동일한 길이를 갖는 16진수 문자열을 반환합니다."
            +      ],
            +      "returns": "값의 16진수 문자열 표현",
            +      "params": {
            +        "n": "숫자: 구문 분석할 값",
            +        "digits": "숫자:",
            +        "ns": "숫자 배열[]: 구문 분석할 숫자 값들 배열"
            +      }
            +    },
            +    "unhex": {
            +      "description": [
            +        "16진수 문자열 표현을 정수로 변환합니다. 16진수 문자열 값의 배열을 전달하면, 동일한 길이의 정수 배열이 반환됩니다."
            +      ],
            +      "returns": "16진수 값의 정수형 표현",
            +      "params": {
            +        "n": "문자열: 구문 분석할 값",
            +        "ns": "배열: 구문 분석할 값"
            +      }
            +    },
            +    "join": {
            +      "description": [
            +        "문자열 배열을 결합하여 하나의 문자열을 만듭니다. 각 문자열은 사용자가 구분자 매개변수로 지정한 문자를 통해 구분됩니다. 정수(int) 또는 실수(float) 배열을 결합하려면, 먼저 nf() 또는 nfs()를 통해 문자열로 변환되어야 합니다."
            +      ],
            +      "returns": "문자열: 결합된 문자열",
            +      "params": {
            +        "list": "배열: 결합할 문자열 배열",
            +        "separator": "문자열: 각 항목 사이에 놓일 문자열"
            +      }
            +    },
            +    "match": {
            +      "description": [
            +        "이 함수는 정규표현식을 텍스트로 적용하고, 매치하는 그룹(괄호 안 요소들) 리스트를 문자열 배열로 반환합니다. 매치하는 내용이 없는 경우, null을 반환합니다. 정규표현식에 그룹이 지정되지 않지만 시퀀스가 일치하는 경우, 길이가 1인 배열(일치하는 텍스트가 배열의 첫 번째 요소인 배열)을 반환합니다.",
            +        "match() 함수 사용시, 결과값이 null인지를 확인합니다. 결과가 null이면 시퀀스도 일치하지 않는다는 뜻입니다. 시퀀스가 일치하는 경우, 배열이 반환됩니다.",
            +        "그룹(괄호들로 지정)이 정규식 표현인 경우, 각각의 내용들이 배열로 반환됩니다. 매치하는 정규식 표현의 요소[0]는 모든 매칭 문자열을 반환하는데, 이 경우 매칭 그룹은 요소[1](첫 번째 그룹은 [1], 두번째 그룹은 [2])에서 시작합니다.",
            +        "",
            +        ""
            +      ],
            +      "returns": "검색된 문자열들의 배열",
            +      "params": {
            +        "str": "문자열: 검색할 문자열",
            +        "regexp": "문자열: 매칭에 사용될 정규식 표현"
            +      }
            +    },
            +    "matchAll": {
            +      "description": [
            +        "이 함수는 정규표현식을 텍스트로 적용하고, 매치하는 그룹(괄호 안 요소들)의 리스트를 2차원 문자열 배열로 반환합니다. 매치하는 내용이 없는 경우, null을 반환합니다. 정규표현식에 그룹이 지정되지 않지만 시퀀스가 일치하는 경우, 2차원 배열이 반환되지만 2번째 차원의 길이는 1이 됩니다.",
            +        "matchAll() 함수 사용시, 결과값이 null인지를 확인합니다. 결과가 null이면 시퀀스도 일치하지 않는다는 뜻입니다. 시퀀스가 일치하는 경우, 2D 배열이 반환됩니다.",
            +        "그룹(괄호들로 지정)이 정규식 표현인 경우, 각각의 내용들이 배열로 반환됩니다. 카운터 변수 i가 있는 반복문을 가정할 때, 매칭되는 정규식의 [i][0] 요소는 모든 매칭 문자열을 반환하고, 매칭 그룹은 [i][1](첫 번째 그룹은 [i][1], 두번째 그룹은 [i][2], ...)에서 시작합니다.",
            +        "",
            +        ""
            +      ],
            +      "returns": "검색된 문자열들의 2D 배열",
            +      "params": {
            +        "str": "문자열: 검색할 문자열",
            +        "regexp": "문자열: 매칭에 사용될 정규식 표현"
            +      }
            +    },
            +    "nf": {
            +      "description": [
            +        "숫자를 문자열로 형식화하는 기능으로, 실수(float) 형식과 정수(int) 형식의 두 가지 버전이 있습니다. 매개변수로는 각각 자릿수(digit), 소수점 기준 왼쪽 자릿수(left), 소수점 기준 오른쪽 자릿수(right)를 지정할 수 있으며, 이 매개변수 값들은 항상 양의 정수여야 합니다. <br>참고: left와 right 매개변수 사용시, 그 값이 현재 숫자의 자릿수 길이보다 클 경우 자릿수를 맞추기 위해 매개변수에 0이 붙습니다. 예를 들어, 현재 숫자가 123.2이고 전달된 left 매개변수가 4인 경우, 그 길이가 num의 정수 부분인 123의 길이(즉, 3)보다 큽니다. 이 경우, 0123.2가 반환됩니다. right 매개변수의 경우에도 마찬가지로 값이 3인 정수 123.200이 반환됩니다."
            +      ],
            +      "returns": "문자열: 형식화된 문자열",
            +      "params": {
            +        "num": "숫자|문자열: 형식화할 숫자",
            +        "left": "정수|문자열: (선택 사항) 소수점 기준 왼쪽의 자릿수",
            +        "right": "정수|문자열: (선택 사항) 소수점 기준 오른쪽의 자릿수",
            +        "nums": "배열: 형식화할 숫자들"
            +      }
            +    },
            +    "nfc": {
            +      "description": [
            +        "숫자를 문자열로 형식화하고 1000을 단위로 표시하기 위해 쉼표를 배치하는 기능입니다. 크게 두 가지 버전이 제공되는데, 하나는 정수(int)를 형식화하는 것이고, 다른 하나는 정수 배열을 형식화합니다. 매개변수의 값들은 항상 양의 정수여야 합니다."
            +      ],
            +      "returns": "문자열: 형식화된 문자열",
            +      "params": {
            +        "num": "숫자|문자열: 형식화할 숫자",
            +        "right": "정수|문자열: (선택 사항) 소수점 기준 오른쪽의 자릿수",
            +        "nums": "배열: 형식화할 숫자들"
            +      }
            +    },
            +    "nfp": {
            +      "description": [
            +        "숫자를 문자열로 형식화하는 기능입니다. nf()와 유사하나, 양수 앞에 '+'를, 음수 앞에 '-' 기호를 추가합니다. 실수(float) 형식과 정수(int) 형식의 두 가지 버전이 있습니다. 매개변수 중, 소수점 기준 왼쪽 자릿수(left)와 소수점 기준 오른쪽 자릿수(right)의 값은 항상 양의 정수여야 합니다."
            +      ],
            +      "returns": "문자열: 형식화된 문자열",
            +      "params": {
            +        "num": "숫자: 형식화할 숫자",
            +        "left": "정수: (선택 사항) 소수점 기준 왼쪽의 자릿수",
            +        "right": "정수: (선택 사항) 소수점 기준 오른쪽의 자릿수",
            +        "nums": "숫자 배열[]: 형식화할 숫자들"
            +      }
            +    },
            +    "nfs": {
            +      "description": [
            +        "숫자를 문자열로 형식화하는 기능입니다. <a href=\"#/p5/nf\">nf()</a>와 유사하나, '-' 기호가 붙은 음수와 정렬할 경우를 위해 '_(공백)' 기호를 양수 앞에 추가합니다. nfs()는 주로 음수가 아닌 숫자의 자릿수에 음수를 맞출 때 사용됩니다. (명확한 이해를 위해 예제를 참고할 수 있습니다.) 실수(float) 형식과 정수(int) 형식의 두 가지 버전이 있습니다. 매개변수 중, 자릿수(digit), 소수점 기준 왼쪽 자릿수(left)와 소수점 기준 오른쪽 자릿수(right)의 값은 항상 양의 정수여야 합니다. <br>중요: 정렬 결과는 사용자의 타입페이스에 따라 달라집니다. <br>참고: left와 right 매개변수 사용시, 그 값이 현재 숫자의 자릿수 길이보다 클 경우 자릿수를 맞추기 위해 매개변수에 0이 붙습니다. 예를 들어, 현재 숫자가 123.2이고 전달된 left 매개변수가 4인 경우, 그 길이가 num의 정수 부분인 123의 길이(즉, 3)보다 큽니다. 이 경우, 0123.2가 반환됩니다. right 매개변수의 경우에도 마찬가지로 값이 3인 정수 123.200이 반환됩니다."
            +      ],
            +      "returns": "문자열: 형식화된 문자열",
            +      "params": {
            +        "num": "숫자: 형식화할 숫자",
            +        "left": "정수: (선택 사항) 소수점 기준 왼쪽의 자릿수",
            +        "right": "정수: (선택 사항) 소수점 기준 오른쪽의 자릿수",
            +        "nums": "배열: 형식화할 숫자들"
            +      }
            +    },
            +    "split": {
            +      "description": [
            +        "<a href=\"#/p5/split\">split()</a> 함수는 String.split()에 매핑되며, 구분 기호를 사용하여 문자 또는 문자열을 분할합니다. 분리 문자(delim) 매개변수는 분할 경계를 나타낼 기호를 지정합니다. 각 조각들을 포함한 문자열 배열이 반환됩니다.",
            +        "<a href=\"#/p5/splitTokens\">splitTokens()</a> 역시 비슷하게 작동하나, 특정 문자나 시퀀스 대신 여러 개의 분리 문자를 분할한다는 점에서 다릅니다."
            +      ],
            +      "returns": "문자열 배열[]: 문자열들의 배열",
            +      "params": {
            +        "value": "문자열: 분할될 문자열",
            +        "delim": "문자열: 데이터 분할에 쓰이는 문자열"
            +      }
            +    },
            +    "splitTokens": {
            +      "description": [
            +        "<a href=\"#/p5/splitTokens\">splitTokens()</a> 함수는 일명 '토큰(token)'이라 불리는, 하나 이상의 분리 문자를 사용하여 문자열을 분할합니다.",
            +        "분리 문자(delim) 매개변수를 지정하지 않는 경우, 공백 문자를 사용하여 분할합니다. 공백 문자는 탭(\\t), 줄바꾸기(\\n), 캐리지 반환(CR: Carriage Return)(\\r), 폼 피드(FF: Form Feed)(\\f), 그리고 공백을 포함합니다."
            +      ],
            +      "returns": "문자열 배열[]:문자열들의 배열",
            +      "params": {
            +        "value": "문자열: 분할될 문자열",
            +        "delim": "문자열: 데이터 분할에 쓰이는 문자열"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "문자열 앞뒤의 공백 문자를 제거합니다. 공백, 캐리지 반환(CR: Carriage Return), 탭과 같은 표준 공백 문자 외에, 유니코드 'nbsp' 문자도 제거합니다."
            +      ],
            +      "returns": "문자열: 트리밍된 문자열",
            +      "params": {
            +        "str": "문자열: 트리밍될 문자열",
            +        "strs": "배열: 트리밍될 문자열 배열"
            +      }
            +    },
            +    "day": {
            +      "description": [
            +        "p5.js는 컴퓨터의 시계와도 통신합니다. <a href=\"#/p5/day\">day()</a>  함수는 현재 날짜를 1부터 31에 해당하는 값으로 반환합니다."
            +      ],
            +      "returns": "정수: 현재 날짜"
            +    },
            +    "hour": {
            +      "description": [
            +        "p5.js는 컴퓨터의 시계와도 통신합니다. <a href=\"#/p5/hour\">hour()</a> 함수는 현재 시를 0부터 23에 해당하는 값으로 반환합니다."
            +      ],
            +      "returns": "정수: 현재 시"
            +    },
            +    "minute": {
            +      "description": [
            +        "p5.js는 컴퓨터의 시계와도 통신합니다. <a href=\"#/p5/minute\">minute()</a> 함수는 현재 분을 0부터 59에 해당하는 값으로 반환합니다."
            +      ],
            +      "returns": "정수: 현재 분"
            +    },
            +    "millis": {
            +      "description": [
            +        "스케치의 시작(즉, <a href=\"#/p5/setup\">setup()</a> 함수 호출 시점)이후의 시간을 밀리 세컨드(1/1000초)로 반환합니다. 주로 타이밍 이벤트나 애니메이션 시퀀스에 사용됩니다."
            +      ],
            +      "returns": "숫자: 스케치의 시작 이후의 밀리 세컨드 단위 시간"
            +    },
            +    "month": {
            +      "description": [
            +        "p5.js는 컴퓨터의 시계와도 통신합니다. <a href=\"#/p5/month\">month()</a> 함수는 현재 월을 1부터 12에 해당하는 값으로 반환합니다."
            +      ],
            +      "returns": "정수: 현재 월"
            +    },
            +    "second": {
            +      "description": [
            +        "p5.js는 컴퓨터의 시계와도 통신합니다. <a href=\"#/p5/second\">second()</a> 함수는 현재 초를 0부터 59에 해당하는 값으로 반환합니다."
            +      ],
            +      "returns": "정수: 현재 초"
            +    },
            +    "year": {
            +      "description": [
            +        "p5.js는 컴퓨터의 시계와도 통신합니다. <a href=\"#/p5/year\">year()</a> 함수는 현재 년도를 정수로 반환합니다. (2014, 2015, 2016, 등)"
            +      ],
            +      "returns": "정수: 현재 년도"
            +    },
            +    "plane": {
            +      "description": [
            +        "사용자가 지정한 너비와 높이로 평면을 그립니다."
            +      ],
            +      "params": {
            +        "width": "숫자: (선택 사항) 평면의 너비값",
            +        "height": "숫자: (선택 사항) 평면의 높이값",
            +        "detailX": "정수: (선택 사항) x-차원상의 삼각 세분면 개수",
            +        "detailY": "정수: (선택 사항) y-차원상의 삼각 세분면 개수"
            +      }
            +    },
            +    "box": {
            +      "description": [
            +        "사용자가 지정한 너비, 높이, 깊이로 상자를 그립니다."
            +      ],
            +      "params": {
            +        "width": "숫자: (선택 사항) 상자의 너비값",
            +        "Height": "숫자: (선택 사항) 상자의 높이값",
            +        "depth": "숫자: (선택 사항) 상자의 깊이값",
            +        "detailX": "정수: (선택 사항) x-차원상의 삼각 세분면 개수",
            +        "detailY": "정수: (선택 사항) y-차원상의 삼각 세분면 개수"
            +      }
            +    },
            +    "sphere": {
            +      "description": [
            +        "사용자가 지정한 반지름으로 구를 그립니다.",
            +        "detailX와 detailY는 각각 구에 대한 x-차원과 y-차원상의 삼각 세분면 개수를 정합니다. 세분면이 많아질수록 구가 매끄러워집니다. detailX와 detailY 모두 권장 최대값은 24입니다. 24보다 높은 값을 사용하면 경고창이 뜨거나 브라우저가 느려질 수 있습니다."
            +      ],
            +      "params": {
            +        "radius": "숫자: (선택 사항) 원의 반지름",
            +        "detailX": "정수: (선택 사항) x-차원상의 삼각 세분면",
            +        "detailY": "정수: (선택 사항) y-차원상의 삼각 세분면"
            +      }
            +    },
            +    "cylinder": {
            +      "description": [
            +        "사용자가 지정한 반지름과 높이로 원기둥을 그립니다.",
            +        "detailX와 detailY는 각각 원기둥에 대한 x-차원과 y-차원상의 세분면 개수를 정합니다. 세분면이 많아질수록 원기둥이 매끄러워집니다. detailX와 detailY 모두 권장 최대값은 24입니다. 24보다 높은 값을 사용하면 경고창이 뜨거나 브라우저가 느려질 수 있습니다."
            +      ],
            +      "params": {
            +        "radius": "숫자: (선택 사항) 원기둥의 높이",
            +        "height": "정수: (선택 사항) x-차원상의 세분면 개수, 기본값은 24",
            +        "detailX": "정수: (선택 사항) y-차원상의 세분면 개수, 기본값은 1",
            +        "detailY": "불리언: (선택 사항) 원기둥의 밑바닥면을 그릴 지의 여부",
            +        "bottomCap": "불리언: (선택 사항) 원기둥의 밑면을 그릴 지의 여부",
            +        "topCap": "불리언: (선택 사항) 원기둥의 윗면을 그릴 지의 여부"
            +      }
            +    },
            +    "cone": {
            +      "description": [
            +        "사용자가 지정한 반지름과 높이로 원뿔을 그립니다.",
            +        "detailX와 detailY는 각각 원뿔에 대한 x-차원과 y-차원상의 세분면 개수를 정합니다. 세분면이 많아질수록 원뿔이 매끄러워집니다. detailX의 권장 최대값은 24입니다. 24보다 높은 값을 사용하면 경고창이 뜨거나 브라우저가 느려질 수 있습니다."
            +      ],
            +      "params": {
            +        "radius": "숫자: (선택 사항) 밑표면의 반지름",
            +        "height": "숫자: (선택 사항) 원뿔의 높이",
            +        "detailX": "정수: (선택 사항) x-차원상의 세분면 개수, 기본값은 24",
            +        "detailY": "정수: (선택 사항) y-차원상의 세분면 개수, 기본값은 1",
            +        "cap": "불리언: (선택 사항) 원뿔의 밑바닥면을 그릴 지의 여부"
            +      }
            +    },
            +    "ellipsoid": {
            +      "description": [
            +        "사용자가 지정한 반지름으로 타원면을 그립니다.",
            +        "detailX와 detailY는 각각 x-차원과 y-차원상의 세분면 개수를 정합니다. 세분면이 많아질수록 타원면이 매끄러워집니다. 가급적 detailX와 detailY의 값이 150을 넘어가면 브라우저가 중단될 수 있습니다."
            +      ],
            +      "params": {
            +        "radiusx": "숫자: (선택 사항) 타원면의 x-반지름값",
            +        "radiusy": "숫자: (선택 사항) 타원면의 y-반지름값",
            +        "radiusz": "숫자: (선택 사항) 타원면의 z-반지름값",
            +        "detailX": "정수: (선택 사항) 세분면의 개수, 기본값은 24",
            +        "detailY": "정수: (선택 사항) 분점의 개수. 타원이 분점이 많을수록 곡선이 더욱 부드러워집니다. 기본값은 16입니다. 150 이상의 정수는 브라우저를 멈출 우려가 있으니 피하는 것을 권장합니다."
            +      }
            +    },
            +    "torus": {
            +      "description": [
            +        "사용자가 지정한 반지름과 튜브 반지름으로 원환을 그립니다.",
            +        "detailX와 detailY는 각각 원환에 대한 x-차원과 y-차원상의 세분면 개수를 정합니다. 세분면이 많아질수록 원환이 매끄러워집니다. detailX과 detailY의 권장 최대값은 각각 24와 16입니다. 4나 6처럼 조금 더 적은 값으로 설정하면, 원환이 아닌 새로운 모양을 만들 수 있습니다."
            +      ],
            +      "params": {
            +        "radius": "숫자: (선택 사항) 전체 원환의 반지름",
            +        "tubeRadius": "숫자: (선택 사항) 튜브의 반지름",
            +        "detailX": "정수: (선택 사항) x-차원상의 세분면 개수, 기본값은 24",
            +        "detailY": "정수: (선택 사항) y-차원상의 세분면 개수, 기본값은 16"
            +      }
            +    },
            +    "orbitControl": {
            +      "description": [
            +        "마우스 또는 트랙 패드로 3D 스케치 주위를 움직일 수 있습니다. 마우스 왼쪽 버튼을 클릭 후 드래그하면 스케치 중심을 기준으로 카메라 위치가 회전합니다. 마우스 오른쪽 버튼을 클릭 후 드래그하면 회전없이 카메라 위치가 이동합니다. 마우스 휠(스크롤)을 사용하면 카메라 위치가 스케치와 더 가까워지거나 멀어집니다. 함수 호출시, x축과 y축상의 마우스 이동에 대한 민감도를 매개변수를 사용할 수 있습니다. 별도로 지정한 매개변수없이 함수를 호출하면 orbitControl(1,1)과 동일한 효과를 갖습니다. 민감도 매개변수를 음수로 입력하면 각 축의 이동 방향을 지정할 수 있습니다."
            +      ],
            +      "params": {
            +        "sensitivityX": "숫자: (선택 사항) X축상의 마우스 이동에 대한 민감도",
            +        "sensitivityY": "숫자: (선택 사항) Y축상의 마우스 이동에 대한 민감도",
            +        "sensitivityZ": "숫자: (선택 사항) Z축상의 마우스 이동에 대한 민감도"
            +      }
            +    },
            +    "debugMode": {
            +      "description": [
            +        "debugMode()는 3D 스케치 상의 '지면'을 표현하는 그리드와 더불어, +X, +Y, +Z 방향을 나타내는 좌표축 아이콘을 추가 시각화합니다. 별도로 지정한 매개변수없이 함수를 호출하면, 기본 그리드와 좌표축 아이콘이 생성됩니다. 또는, 위의 예제처럼 별도의 매개변수를 지정하여 그리드/좌표축의 위치와 크기를 조정할 수 있습니다. 그리드는 가장 마지막으로 사용된 윤곽선(stroke)의 색과 두께로 그려집니다. 선에 대한 매개변수를 지정하려면, <a href=\"#/p5/draw\">draw()</a> 반복문이 끝나기 직전에 stroke() 함수와 strokeWeight() 호출하면 됩니다.",
            +        "기본적으로, 그리드는 XZ 평면을 따라 스케치의 원점(0,0,0)을 통과하며, 좌표축 아이콘은 원점에서 상쇄(offset)됩니다. 그리드 및 좌표축 아이콘 모두 현재 캔버스 크기에 따라 그 크기가 조정됩니다. 그리드는 기본 카메라 뷰와 평행하게 실행됩니다. 따라서, 그리드를 전체적으로 조망하려면, debugMode와 orbitControl을 함께 사용하면 됩니다.",
            +        ""
            +      ],
            +      "params": {
            +        "mode": "상수: GRID 또는 AXES 중 하나",
            +        "gridSize": "숫자: (선택 사항) 그리드 한 변의 크기",
            +        "gridDivisions": "숫자: (선택 사항) 그리드 분할 개수",
            +        "xOff": "숫자: (선택 사항) 원점(0,0,0)으로부터의 X축 상쇄값",
            +        "yOff": "숫자: (선택 사항) 원점(0,0,0)으로부터의 Y축 상쇄값",
            +        "zOff": "숫자: (선택 사항) 원점(0,0,0)으로부터의 Z축 상쇄값",
            +        "axesSize": "숫자: (선택 사항) 좌표축 아이콘 크기",
            +        "gridXOff": "숫자: (선택 사항)",
            +        "gridYOff": "숫자: (선택 사항)",
            +        "gridZOff": "숫자: (선택 사항)",
            +        "axesXOff": "숫자: (선택 사항)",
            +        "axesYOff": "숫자: (선택 사항)",
            +        "axesZOff": "숫자: (선택 사항)"
            +      }
            +    },
            +    "noDebugMode": {
            +      "description": [
            +        "3D 스케치의 debugMode() 실행을 종료합니다."
            +      ]
            +    },
            +    "ambientLight": {
            +      "description": [
            +        "색상을 갖는 앰비언트 라이트를 생성합니다. 앰비언트 라이트는 별도의 광원없이 캔버스의 모든 영역에서 나오는 조명을 뜻합니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: 현재 색상 범위에 따른 빨강값 또는 색조값",
            +        "v2": "현재 색상 범위에 따른 초록값 또는 채도값",
            +        "v3": "현재 색상 범위에 따른 파랑값 또는 밝기값",
            +        "alpha": "숫자: (선택 사항) 알파값",
            +        "value": "문자열: 색상 문자열",
            +        "gray": "숫자: 회색값",
            +        "values": "숫자 배열[]: 색상의 R, G, B & 알파값 성분을 포함한 배열",
            +        "color": "p5.Color: 앰비언트 라이트 색상"
            +      }
            +    },
            +    "specularColor": {
            +      "description": [
            +        "스페큘러 재질(material)과 조명에 쓰이는 스페큘러 하이라이트 색상을 설정합니다.",
            +        "이 메소드를 specularMaterial() 및 shininess() 함수에 결합하여 스페큘러 하이라이트를 설정할 수 있습니다. 기본값은 흰색, 즉 (255,25,255)이며, specularMaterial() 함수 이전에 메소드가 호출되지 않을 경우 사용됩니다.",
            +        "참고: specularColor는 프로세싱 함수 <a href='https://processing.org/reference/lightSpecular_.html'>lightSpecular</a>와 동읠한 효과를 갖습니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: 현재 색상 범위에 따른 빨강값 또는 색조값",
            +        "v2": "숫자: 현재 색상 범위에 따른 초록값 또는 채도값",
            +        "v3": "숫자: 현재 색상 범위에 따른 파랑값 또는 밝기값",
            +        "value": "문자열: 색상 문자열",
            +        "gray": "숫자: 회색값",
            +        "values": "숫자 배열[]: 색상의 R, G, B & 알파값 성분을 포함한 배열",
            +        "color": "p5.Color: 앰비언트 라이트 색상"
            +      }
            +    },
            +    "directionalLight": {
            +      "description": [
            +        "색상과 방향을 갖는 디렉셔널 라이트를 생성합니다.",
            +        "한 번에 최대 5개의 directionalLight를 활성화할 수 있습니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: (현재 색상 모드에 따른) 빨강값 또는 색조값",
            +        "v2": "숫자: 초록값 또는 채도값",
            +        "v3": "숫자: 파랑값 또는 밝기값",
            +        "position": "p5.Vector:조명의 방향",
            +        "color": "숫자 배열[]|문자열|p5.Color: 색상 배열, CSS 색상 문자열, 또는 p5.Color 값",
            +        "x": "숫자: x축 방향",
            +        "y": "숫자: y축 방향",
            +        "z": "숫자: z축 방향"
            +      }
            +    },
            +    "pointLight": {
            +      "description": [
            +        "색상과 조명 위치를 갖는 포인트 라이트를 생성합니다.",
            +        "한 번에 최대 5개의 pointlLight를 활성화할 수 있습니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: (현재 색상 모드에 따른) 빨강값 또는 색조값",
            +        "v2": "숫자: 초록값 또는 채도값",
            +        "v3": "숫자: 파랑값 또는 밝기값",
            +        "x": "숫자: x축 위치",
            +        "y": "숫자: y축 위치",
            +        "z": "숫자: z축 위치",
            +        "position": "p5.Vector: 조명의 위치",
            +        "color": "숫자 배열[]|문자열|p5.Color: 색상 배열, CSS 색상 문자열, 또는 p5.Color 값"
            +      }
            +    },
            +    "lights": {
            +      "description": [
            +        "기본 앰비언트 라이트와 디렉셔널 라이트를 설정합니다. 기본값은  ambientLight(128, 128, 128)과 directionalLight(128, 128, 128, 0, 0, -1)입니다. 반복 프로그램에서 조명의 지속성을 확보하려면 조명을 <a href=\"#/p5/draw\">draw()</a> 안에 작성해야 합니다. 반복 프로그램의 <a href=\"#/p5/setup\">setup()</a> 안에 작성할 경우, 반복문의 최초 실행시에만 조명 효과가 발생합니다."
            +      ]
            +    },
            +    "lightFalloff": {
            +      "description": [
            +        "포인트 라이트의 감소율을 설정합니다. 코드 내에서 생성된 요소에만 영향을 줍니다. 기본값은 lightFalloff (1.0, 0.0, 0.0)이며, 사용자가 지정한 매개변수를 다음의 감소량 계산 방정식에서 사용할 수 있습니다:",
            +        "d = 조명 위치에서 꼭짓점 위치까지의 거리",
            +        "감소량 = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)"
            +      ],
            +      "params": {
            +        "constant": "숫자: 감소량 결정을 위한 상수값",
            +        "linear": "선형 숫자: 감소량 결정을 위한 선형값",
            +        "quadratic": "2차 숫자: 감소량 결정을 위한 2차값"
            +      }
            +    },
            +    "spotLight": {
            +      "description": [
            +        "사용자가 지정한 색상, 위치, 조명 방향, 각도, 농도로 스포트라이트를 생성합니다. 여기서의 '각도'는 스포트라이트 원뿔의 개구부에 대한 각도를 의미합니다. 농도는 빛을 중앙으로 집중시키는 값을 뜻합니다. 각도와 농도는 모두 선택 사항이나, 농도 지정을 위해 각도를 반드시 지정해야 합니다.",
            +        "한 번에 최대 5개의 spotLight를 활성화할 수 있습니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: (현재 색상 모드에 따른) 빨강값 또는 색조값",
            +        "v2": "숫자: 초록값 또는 채도값",
            +        "v3": "숫자: 파랑값 또는 밝기값",
            +        "x": "숫자: x축 위치",
            +        "y": "숫자: y축 위치",
            +        "z": "숫자: z축 위치",
            +        "rx": "숫자: 조명의 x축 방향",
            +        "ry": "숫자: 조명의 y축 방향",
            +        "rz": "숫자: 조명의 z축 방향",
            +        "angle": "숫자: (선택 사항) 각도 매개변수. 기본값은 PI/3",
            +        "conc": "숫자: (선택 사항) 농도 매개변수. 기본값은 100",
            +        "color": "숫자 배열[]|문자열|p5.Color: 색상 배열, CSS 색상 문자열, 또는 p5.Color 값",
            +        "position": "p5.Vector: 조명의 위치",
            +        "direction": "p5.Vector: 조명의 방향"
            +      }
            +    },
            +    "noLights": {
            +      "description": [
            +        "noLights() 함수 호출 이후에 렌더링된 재질(material)들로부터 모든 조명을 제거합니다. 모든 후속 메소드에 영향을 줍니다. noLights() 이후에 작성된 조명 메소드를 호출할 경우, 스케치상 조명이 다시 활성화됩니다."
            +      ]
            +    },
            +    "loadModel": {
            +      "description": [
            +        "OBJ 또는 STL 파일로부터 3D 모델을 불러옵니다.",
            +        "loadModel() 함수는 반드시 <a href=\"#/p5/preload\">preload()</a> 함수 안에 작성되어야 하며, 이로써 3D 모델을 코드 실행에 앞서 온전히 불러올 수 있습니다.",
            +        "OBJ와 STL 파일 형식의 한계 중 하나는 빌트인 스케일 기능이 제공되지 않는다는 것입니다. 즉, 파일을 불러오는 소프트웨어 프로그램에 따라 3D 모델의 크기가 상이해집니다. 3D 모델이 보이지 않는다면 loadModel() 함수에 표준화된 매개변수인 true를 입력할 수 있습니다. 또한 불러온 3D 모델의 크기는 scale() 함수로 변경할 수 있습니다.",
            +        "색상이 지정된 STL 파일은 현재 지원하지 않아, 색상 요소가 제거된 상태로 렌더링될 수 있습니다."
            +      ],
            +      "returns": "p5.Geometry: p5.Geometry 객체",
            +      "params": {
            +        "path": "문자열: 불러올 3D 모델의 파일 경로",
            +        "normalize": "불리언: 참(true)이면, 3D 모델을 표준화된 크기로 불러오기",
            +        "successCallback": "함수(p5.Geometry): (선택 사항) 3D 모델을 불러온 뒤 일회적으로 호출되는 함수로, 3D 모델 객체를 전달.",
            +        "failureCallback": "함수(Event): (선택 사항) 3D 모델 불러오기를 실패할 경우 이벤트 에러와 함께 호출",
            +        "fileType": "문자열: (선택 사항) 모텔의 파일형식 (<code>.stl</code>, <code>.obj</code>)."
            +      }
            +    },
            +    "model": {
            +      "description": [
            +        "화면에 3D 모델을 렌더링합니다."
            +      ],
            +      "params": {
            +        "model": "p5.Geometry: 렌더링할, 불러온 3D 모델"
            +      }
            +    },
            +    "loadShader": {
            +      "description": [
            +        "버텍스 및 프래그먼트 셰이더 경로로부터 커스텀 셰이더를 불러옵니다. 셰이더 파일은 배경 화면과 비동기적으로 로드되므로, 이 메소드는 <a href=\"#/p5/preload\">preload()</a>에서 사용해야 합니다.",
            +        "현재 3가지 유형의 셰이더를 지원합니다. p5는 셰이더상 정의된 매개변수 이름과 일치하는 버텍스, 법선(normal), 색상, 조명 속성을 자동으로 제공합니다."
            +      ],
            +      "returns": "p5.Shader: 지정된 버텍스 및 프래그먼트 셰이더 파일로부터 생성된 셰이더 객체",
            +      "params": {
            +        "vertFilename": "문자열: 버텍스 셰이더 소스 코드 파일의 경로",
            +        "fragFilename": "문자열: (선택 사항) 프래그먼트 셰이더의 소스 코드 파일 경로",
            +        "callback": "함수: loadShader()가 완료된 이후 실행될 함수. 성공시, 셰이더 객체를 1번재 인수로 전달",
            +        "errorCallback": "함수: (선택 사항) loadShader 내에서 에러 발생시 실행될 함수. 에러 발생시, 에러를 1번째 인수로 전달"
            +      }
            +    },
            +    "createShader": {
            +      "returns": "p5.Shader: 지정된 버텍스 및 프래그먼트 셰이더 파일로부터 생성된 셰이더 객체",
            +      "params": {
            +        "vertSrc": "문자열: 버텍스 셰이더의 소스 코드",
            +        "fragSrc": "문자열: 프래그먼트 셰이더의 소스 코드"
            +      }
            +    },
            +    "shader": {
            +      "description": [
            +        "<a href=\"#/p5/shader\">shader()</a> 함수를 통해 WebGL 모드상의 도형을 커스텀 셰이더로 채울 수 있습니다. <a href=\"#/p5/loadShader\">loadShader()</a>로 버텍스 및 프래그먼트 셰이더를 불러와 사용자 자체적으로 셰이더를 생성할 수 있습니다."
            +      ],
            +      "params": {
            +        "s": "p5.Shader: (선택 사항) 도형 렌더링에 사용하기 원하는 p5.Shader"
            +      }
            +    },
            +    "resetShader": {
            +      "description": [
            +        "이 함수는 WebGL 모드 기본 셰이더를 복원합니다. resetShader() 이후에 실행되는 코드는 그 이전에 정의된 셰이더의 영향을 받지 않습니다. 반드시 <a href=\"#/p5/shader\">shader()</a> 함수 이후에 실행되어야 합니다."
            +      ]
            +    },
            +    "normalMaterial": {
            +      "description": [
            +        "도형의 기본 재질(material)은 조명의 영향을 받지 않습니다. 반사성을 갖지 않으며, 종종 디버깅을 위한 자리표시자(placeholder)로 사용됩니다. X축을 향한 표면은 빨강, Y축을 향한 표면은 초록, Z축을 향한 표면은 파랑이 됩니다. 이 <a href='https://p5js.org/ko/examples/3d-materials.html'>예제</a>에서 사용가능한 모든 재질들을 확인할 수 있습니다."
            +      ]
            +    },
            +    "texture": {
            +      "description": [
            +        "도형의 텍스처. 이 <a href='https://p5js.org/ko/examples/3d-materials.html'>예제</a>에서 사용가능한 모든 재질들을 확인할 수 있습니다."
            +      ],
            +      "params": {
            +        "tex": "p5.Image|p5.MediaElement|p5.Graphics: 텍스처로 렌더링할 2차원 그래픽"
            +      }
            +    },
            +    "textureMode": {
            +      "description": [
            +        "텍스처 매핑을 위한 좌표 공간을 설정합니다. 기본 모드는 IMAGE로, 이미지의 실제 좌표를 나타냅니다. NORMAL은 0부터 1 사이의 정규화된 값의 공간을 나타냅니다. 이 함수는 WebGL 모드에서만 작동합니다.",
            +        "예를 들어, IMAGE 모드에서 100 x 200 픽셀 이미지를 사용할 경우, 이미지를 사각면(quad)의 전체 크기에 매핑하기 위해 점 (0,0) (100, 0) (100,200) (0,200)이 필요합니다. 동일한 매핑을 NORMAL 모드에서 할 경우 (0,0) (1,0) (1,1) (0,1)입니다."
            +      ],
            +      "params": {
            +        "mode": "상수: IMAGE 또는 NORMAL 중 하나"
            +      }
            +    },
            +    "textureWrap": {
            +      "description": [
            +        "전역 텍스처 래핑 모드를 설정합니다. UV가 0부터 1까지의 범위를 벗어날 때의 텍스처 동작을 제어합니다. CLAMP, REPEAT, MIRROR의 3가지 옵션이 있습니다.",
            +        "CLAMP는 텍스처의 가장자리 픽셀 경계를 확장합니다. REPEAT는 경계에 도달할 때까지 텍스처가 반복적으로 타일링되도록 합니다. MIRROR는 REPEAT와 유사하지만, 매 타일마다 텍스처를 뒤집는다는 점에서 다릅니다.",
            +        "REPEAT & MIRROR는 텍스처의 크기가 2의 배수 단위(128, 256, 512, 1024 등)인 경우에 한해서만 사용 가능합니다.",
            +        "이 메소드는 그 이후에 작성된 textureWrap이 호출되기 전까지의 스케치 위 모든 텍스처에 영향을 줍니다.",
            +        "1개의 인수만 지정할 경우, 해당 인수가 수직 및 수평축 모두에 적용됩니다."
            +      ],
            +      "params": {
            +        "wrapX": "상수: CLAMP, REPEAT, 또는 MIRROR 중 하나",
            +        "wrapY": "상수: (선택 사항) CLAMP, REPEAT, 또는 MIRROR 중 하나"
            +      }
            +    },
            +    "ambientMaterial": {
            +      "description": [
            +        "지정된 색상의 도형에 입힐 앰비언트 재질입니다. 앰비언트 재질은 앰비언트 라이트 아래에서 객체가 반사하는 색상을 정의합니다. 예를 들어, 객체의 앰비언트 재질이 순수 빨강이고 앰비언트 라이트가 순수 초록인 경우, 객체는 빛을 반사하지 않습니다. 이 <a href='https://p5js.org/ko/examples/3d-materials.html'>예제</a>에서 사용가능한 모든 재질들을 확인할 수 있습니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: 회색값, (현재 색상 모드에 따른) 빨강값 또는 색조값",
            +        "v2": "숫자: (선택 사항) 초록값 또는 채도값",
            +        "v3": "숫자: (선택 사항) 파랑값 또는 밝기값",
            +        "color": "숫자 배열[]|문자열|p5.Color: 색상 배열, CSS 색상 문자열, 또는 p5.Color 값"
            +      }
            +    },
            +    "emissiveMaterial": {
            +      "description": [
            +        "재질의 방사형 색상을 설정합니다. 여기서의 '방사형'은 사실상 잘못된 표현입니다. 주변 도형에도 영향을 미치는 조명을 직접 방사한다기 보다는, 마치 객체가 빛나는 것처럼 보이기 때문입니다. 방사형 재질은 별도의 조명이 없어도 화면상 최대 강도로 빛날 수 있습니다."
            +      ],
            +      "params": {
            +        "v1": "숫자: 회색값, (현재 색상 모드에 따른) 빨강값 또는 색조값",
            +        "v2": "숫자: (선택 사항) 초록값 또는 채도값",
            +        "v3": "숫자: (선택 사항) 파랑값 또는 밝기값",
            +        "a": "숫자 배열[]|문자열|p5.Color: 색상 배열, CSS 색상 문자열, 또는 p5.Color 값",
            +        "color": "숫자 배열[]|문자열|p5.Color: 색상, 색상 배열, CSS 색상 문자열"
            +      }
            +    },
            +    "specularMaterial": {
            +      "description": [
            +        "지정된 색상의 도형에 입힐 스페큘러 재질입니다. 스페큘러 재질은 반짝이는 반사 재질입니다. 앰비언트 재질과 마찬가지로, 앰비언트 조명 아래에서 객체가 반사하는 색상을 정의합니다. 예를 들어, 객체의 스페큘러 재질이 순수 빨강이고 앰비언트 라이트가 순수 초록인 경우, 객체는 빛을 반사하지 않습니다. 스페큘러 재질은 포인트 라이트나 디렉셔널 라이트 등 모든 조명들의 광원 색상을 반영합니다. 이 <a href='https://p5js.org/ko/examples/3d-materials.html'>예제</a>에서 사용가능한 모든 재질들을 확인할 수 있습니다."
            +      ],
            +      "params": {
            +        "gray": "숫자: 검정과 하양 값들 사이에 있는 숫자.",
            +        "alpha": "숫자: (선택 사항) 색상 범위(기본값: 0-255)에 대한 알파값",
            +        "v1": "숫자: 회색값, (현재 색상 모드에 따른) 빨강값 또는 색조값",
            +        "v2": "숫자: (선택 사항) 초록값 또는 채도값",
            +        "v3": "숫자: (선택 사항) 파랑값 또는 밝기값",
            +        "color": "숫자 배열[]|문자열|p5.Color: 색상 배열, CSS 색상 문자열, 또는 p5.Color 값"
            +      }
            +    },
            +    "shininess": {
            +      "description": [
            +        "셰이더 표면의 광택 양을 설정합니다. specularMaterial()과 함께 사용하여 도형의 재질 속성을 설정할 수 있습니다. 기본값이자 최소값은 1입니다."
            +      ],
            +      "params": {
            +        "shine": "숫자: 광택의 양. 기본값은 1."
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "3D 스케치의 카메라 위치를 설정합니다. 이 함수의 매개변수들은 카메라의 위치, 스케치의 중심(카메라가 가리키는 위치), 그리고 위쪽 방향(카메라의 오리엔테이션)을 정의합니다.",
            +        "이 함수는 카메라 이동을 시뮬레이션하여, 객체를 다양한 각도에서 볼 수 있도록 합니다. 객체 자체가 아닌 카메라를 움직이는 점에 유의해야 합니다. 예를 들어, centerX 값이 양수인 경우, 카메라는 스케치의 우측으로 회전하여 마치 객체가 왼쪽으로 움직이듯 보이게 합니다.",
            +        "이 <a href = 'https://www.openprocessing.org/sketch/740258'>예제</a>에서 카메라의 위치 이동 방식이 자세하게 설명되어 있습니다.",
            +        "별도의 인수를 지정하지 않는 경우, 함수는 camera (0, 0, (height / 2.0) / tan (PI * 30.0 / 180.0), 0, 0, 0, 0, 1, 0)에 해당하는 기본 카메라를 생성합니다.",
            +        "",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "x": "숫자: (선택 사항) x축에서의 카메라 위치값",
            +        "y": "숫자: (선택 사항) y축에서의 카메라 위치값",
            +        "z": "숫자: (선택 사항) z축에서의 카메라 위치값",
            +        "centerX": "숫자: (선택 사항) 스케치 중심의 x좌표값",
            +        "centerY": "숫자: (선택 사항) 스케치 중심의 y좌표값",
            +        "centerZ": "숫자: (선택 사항) 스케치 중심의 z좌표값",
            +        "upX": "숫자: (선택 사항) 카메라로부터 위쪽 방향의 x성분",
            +        "upY": "숫자: (선택 사항) 카메라로부터 위쪽 방향의 y성분",
            +        "upZ": "숫자: (선택 사항) 카메라로부터 위쪽 방향의 z성분"
            +      }
            +    },
            +    "perspective": {
            +      "description": [
            +        "3D 스케치의 카메라 투시 투영법을 설정합니다. 이 투영법은 거리 단축 착시효과를 통해 깊이감을 나타냅니다. 카메라로부터 가까운 객체는 실제 크기로 보이고, 멀리 떨어진 객체는 더 작아 보입니다. 이 함수의 매개변수는 수직 시야, 종횡비(일반적으로, 너비/높이), 그리고 근거리 및 원거리에서 잘리는 평면을 통해 보이는 (즉, 카메라가 보는), 절두체 구도(카메라가 객체를 보는, 잘린 피라미드형 구도)를 정의합니다.",
            +        "별도의 인수를 지정하지 않는 경우, 기본값은 perspective(PI/3.0, width/height, eyeZ/10.0, eyeZ10.0)과도 동일한 효과를 가지며, 여기서 eyeZ는((height/2.0) / tan(PI60.0/360.0))과 같습니다.",
            +        ""
            +      ],
            +      "params": {
            +        "fovy": "숫자: (선택 사항) 하단에서 상단에 이르는 카메라의 절두체형 수직 시야각, angleMode 단위에 해당",
            +        "aspect": "숫자: (선택 사항) 카메라의 절두체형 종횡비",
            +        "near": "숫자: (선택 사항) 절두 근거리 길이",
            +        "far": "숫자: (선택 사항) 절두 원거리 길이"
            +      }
            +    },
            +    "ortho": {
            +      "description": [
            +        "3D 스케치의 카메라 직교 투영법을 설정하고, 객체에 대한 상자 모양의 절두체 구도를 정의합니다. 이 투영법은 동일한 차원상의 객체들을 카메라로부터 떨어져있는 거리와 상관없이 모두 동일한 크기로 나타냅니다. 이 함수의 매개변수는 좌우가 최소 및 최대 x값이고, 상하가 최소 및 최대 y값이며, 원근이 최소 및 최대 z값인 절두체 구도를 지정합니다. 별도의 인수를 지정하지 않을 경우, 기본값은 ortho(-width/2, width/2, -height/2, height/2)입니다."
            +      ],
            +      "params": {
            +        "left": "숫자: (선택 사항) 카메라 절두체의 왼쪽 평면",
            +        "right": "숫자: (선택 사항) 카메라 절두체의 오른쪽 평면",
            +        "bottom": "숫자: (선택 사항) 카메라 절두체의 아래쪽 평면",
            +        "top": "숫자: (선택 사항) 카메라 절두체의 위쪽 평면",
            +        "near": "숫자: (선택 사항) 카메라 절두체의 가까운 평면",
            +        "far": "숫자: (선택 사항) 카메라 절두체의 먼 평면"
            +      }
            +    },
            +    "frustum": {
            +      "description": [
            +        "주어진 인수로 퍼스펙티브 매트릭스 (perspective matrix)를 만듧니다.",
            +        "절두체 (frustum)은 피라미드 모양의 상단을 바닥과 평행한 면에서 잘라낸 기하학적 모양입니다. 이 피라미드의 위에 보는 사람의 눈이 있다 가정하면서 여섯 면은 장면의 특정 부분만 렌더링하는데에 쓰이는 가상의 면인 경계면 (clipping plane)입니다. 3D로 렌더링 할 시, 이 여섯 면 안에 있는 물체는 보이며, 그 바깥에 있는 물체는 보이지 않습니다. 이 <https://docs.unity3d.com/kr/530/Manual/UnderstandingFrustum.html\">링크</a>를 통해 더 자세히 알 수 있습니다.",
            +        "절두체를 설정하면 렌더링되는 장면이 달라집니다. 이는 간단하게 <a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a> 함수를 통해 이룰 수도 있습니다."
            +      ],
            +      "params": {
            +        "left": "숫자: (선택 사항) 카메라 절두체의 왼쪽 면",
            +        "right": "숫자: (선택 사항) 카메라 절두체의 오른쪽 면",
            +        "bottom": "숫자: (선택 사항) 카메라 절두체의 밑 면",
            +        "top": "숫자: (선택 사항) 카메라 절두체의 위 면",
            +        "near": "숫자: (선택 사항) 카메라 절두체의 근거리 면",
            +        "far": "숫자: (선택 사항) 카메라 절두체의 장거리 면"
            +      }
            +    },
            +    "createCamera": {
            +      "description": [
            +        "새로운 p5.Camera 객체를 생성하고 렌더러에게 해당 카메라를 사용하도록 지시합니다. p5.Camera 객체를 반환합니다.",
            +        "새로운 카메라는 기본적 위치가 설정이 되며 (<a href=\"#/p5.Camera/camera\">camera()</a> 참조), 기본적 관점도 설정됩니다 (<a href=\"#/p5.Camera/perspective\">perspective()</a> 참조). 카메라 객체의 속성들은 <a href=\"#/p5.Camera\">p5.Camera</a>의 메소드로 조정 가능합니다.",
            +        "모든 3D 스케치는 기본 카메라가 설정된 상태로 시작하는 점을 유의해야합니다. 이 카메라가 장면에 있는 유일한 케마라일 경우, 글로벌 메소드인 <a href=\"#/p5/camera\">camera()</a>, <a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>, 그리고 <a href=\"#/p5/frustum\">frustum()</a>으로 조정 가능합니다."
            +      ],
            +      "returns": "p5.Camera: 새로 생성된 카메라 객체"
            +    },
            +    "setCamera": {
            +      "description": [
            +        "rendererGL의 현재 카메라를 p5.Camera 객체로 설정합니다. 여러 카메라 간의 화면 전환이 가능합니다."
            +      ],
            +      "params": {
            +        "cam": "p5.Camera: p5.Camera 객체"
            +      }
            +    },
            +    "setAttributes": {
            +      "description": [
            +        "WebGL 그리기 컨텍스트 (Drawing Context)의 속성을 설정하여 WebGL 렌더러가 화면과 성능을 미세 조정할 수 있도록 합니다.",
            +        "WebGL 캔버스를 생성한 후에 이 함수를 호출하면 그리기 컨텍스트가 다시 초기화되는 점에 유의해야 합니다.",
            +        "객체가 매개변수로 전달될 경우, 객체에 선언되지 않은 모든 속성은 기본값으로 처리됩니다.",
            +        "사용한 가능한 속성은 다음과 같습니다: <br>alpha - 캔버스에 알파 버퍼가 있는지의 여부를 나타냅니다. 기본값은 참(true)입니다.",
            +        "depth - 그리기 버퍼 (drawing buffer)에 16비트 이상의 스텐실 버퍼가 있는지 여부를 나타냅니다.",
            +        "stencil - 그리기 버퍼에 8비트 이상의 스텐실 버퍼가 있는지 여부를 나타냅니다.",
            +        "antialias - 안티앨리어싱 기본값을 수행할지 여부를 나타냅니다. (Safari에서는 참)",
            +        "premultipliedAlpha - 그리기 버퍼에 포함된 색상이 미리 곱해진 알파 기본값을 포함하는 지의 여부에 대해, 페이지 컴포지터가 거짓 (false)으로 가정하고 있음을 나타냅니다.",
            +        "preserveDrawingBuffer - 참 (true)으로 설정될 경우, 그리기 버퍼들이 삭제되지 않고 작가의 의도적인 삭제나 편집이 없는 이상 값을 유지합니다. 기본값은 참입니다.",
            +        "perPixelLighting - 참으로 설정될 경우, 픽셀당 조명 (per-pixel lighting)이 조명 셰이더에 사용됩니다. 그렇지 않다면, 꼭짓점당 조명 (per-vertex lighting)이 사용됩니다. 기본값은 참입니다.",
            +        "",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "key": "문자열: 속성명",
            +        "value": "불리언: 명명된 속성의 새로운 값",
            +        "obj": "객체: 주요값들의 쌍을 갖는 객체"
            +      }
            +    },
            +    "getAudioContext": {
            +      "description": [
            +        "Returns the Audio Context for this sketch. Useful for users who would like to dig deeper into the <a target='_blank' href= 'http://webaudio.github.io/web-audio-api/'>Web Audio API </a>.",
            +        "Some browsers require users to startAudioContext with a user gesture, such as touchStarted in the example below."
            +      ],
            +      "returns": "객체: AudioContext for this sketch"
            +    },
            +    "userStartAudio": {
            +      "description": [
            +        "It is not only a good practice to give users control over starting audio. This policy is enforced by many web browsers, including iOS and <a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay policy\">Google Chrome</a>, which create the Web Audio API's <a href=\"https://developer.mozilla.org/ko/docs/Web/API/AudioContext\" title=\"Audio Context @ MDN\">Audio Context</a> in a suspended state.  ",
            +        "In these browser-specific policies, sound will not play until a user interaction event (i.e. <code>mousePressed()</code>) explicitly resumes the AudioContext, or starts an audio node. This can be accomplished by calling <code>start()</code> on a <code>p5.Oscillator</code>, <code> play()</code> on a <code>p5.SoundFile</code>, or simply <code>userStartAudio()</code>.  ",
            +        "<code>userStartAudio()</code> starts the AudioContext on a user gesture. The default behavior will enable audio on any mouseUp or touchEnd event. It can also be placed in a specific interaction function, such as <code>mousePressed()</code> as in the example below. This method utilizes <a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext </a>, a library by Yotam Mann (MIT Licence, 2016)."
            +      ],
            +      "returns": "Promise: Returns a Promise that resolves when  the AudioContext state is 'running'",
            +      "params": {
            +        "element(s)": "Element|배열: (선택 사항) This argument can be an Element,  Selector String, NodeList, p5.Element,  jQuery Element, or an Array of any of those.",
            +        "callback": "함수: (선택 사항) Callback to invoke when the AudioContext  has started"
            +      }
            +    },
            +    "getOutputVolume": {
            +      "description": [
            +        "Returns a number representing the output volume for sound in this sketch."
            +      ],
            +      "returns": "숫자: Output volume for sound in this sketch.  Should be between 0.0 (silence) and 1.0."
            +    },
            +    "outputVolume": {
            +      "description": [
            +        "Scale the output of all sound in this sketch Scaled between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal.",
            +        "<b>How This Works</b>: When you load the p5.sound module, it creates a single instance of p5sound. All sound objects in this module output to p5sound before reaching your computer's output. So if you change the amplitude of p5sound, it impacts all of the sound in this module.",
            +        "If no value is provided, returns a Web Audio API Gain Node"
            +      ],
            +      "params": {
            +        "volume": "숫자|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "숫자: (선택 사항) Fade for t seconds",
            +        "timeFromNow": "숫자: (선택 사항) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "soundOut": {
            +      "description": [
            +        "<code>p5.soundOut</code> is the p5.sound final output bus. It sends output to the destination of this window's web audio context. It contains Web Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>), and Gain Nodes for <code>.input</code> and <code>.output</code>."
            +      ]
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Returns a number representing the sample rate, in samples per second, of all sound objects in this audio context. It is determined by the sampling rate of your operating system's sound card, and it is not currently possile to change. It is often 44100, or twice the range of human hearing."
            +      ],
            +      "returns": "숫자: samplerate samples per second"
            +    },
            +    "freqToMidi": {
            +      "description": [
            +        "Returns the closest MIDI note value for a given frequency."
            +      ],
            +      "returns": "숫자: MIDI note value",
            +      "params": {
            +        "frequency": "숫자: A freqeuncy, for example, the \"A\"  above Middle C is 440Hz"
            +      }
            +    },
            +    "midiToFreq": {
            +      "description": [
            +        "Returns the frequency value of a MIDI note value. General MIDI treats notes as integers where middle C is 60, C# is 61, D is 62 etc. Useful for generating musical frequencies with oscillators."
            +      ],
            +      "returns": "숫자: Frequency value of the given MIDI note",
            +      "params": {
            +        "midiNote": "숫자: The number of a MIDI note"
            +      }
            +    },
            +    "soundFormats": {
            +      "description": [
            +        "List the SoundFile formats that you will include. LoadSound will search your directory for these extensions, and will pick a format that is compatable with the client's web browser. <a href=\"http://media.io/\">Here</a> is a free online file converter."
            +      ],
            +      "params": {
            +        "formats": "문자열: (선택 사항) i.e. 'mp3', 'wav', 'ogg'"
            +      }
            +    },
            +    "loadSound": {
            +      "description": [
            +        "loadSound() returns a new p5.SoundFile from a specified path. If called during <a href=\"#/p5/preload\">preload()</a>, the p5.SoundFile will be ready to play in time for <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a>. If called outside of preload, the p5.SoundFile will not be ready immediately, so loadSound accepts a callback as the second parameter. Using a <a href=\"https://github.com/processing/p5.js/wiki/Local-server\"> local server</a> is recommended when loading external files."
            +      ],
            +      "returns": "SoundFile: Returns a p5.SoundFile",
            +      "params": {
            +        "path": "문자열|배열: Path to the sound file, or an array with  paths to soundfiles in multiple formats  i.e. ['sound.ogg', 'sound.mp3'].  Alternately, accepts an object: either  from the HTML5 File API, or a p5.File.",
            +        "successCallback": "함수: (선택 사항) Name of a function to call once file loads",
            +        "errorCallback": "함수: (선택 사항) Name of a function to call if there is  an error loading the file.",
            +        "whileLoading": "함수: (선택 사항) Name of a function to call while file is loading.  This function will receive the percentage loaded  so far, from 0.0 to 1.0."
            +      }
            +    },
            +    "createConvolver": {
            +      "description": [
            +        "Create a p5.Convolver. Accepts a path to a soundfile that will be used to generate an impulse response."
            +      ],
            +      "returns": "p5.Convolver:",
            +      "params": {
            +        "path": "문자열: path to a sound file",
            +        "callback": "함수: (선택 사항) function to call if loading is successful.  The object will be passed in as the argument  to the callback function.",
            +        "errorCallback": "함수: (선택 사항) function to call if loading is not successful.  A custom error will be passed in as the argument  to the callback function."
            +      }
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the global tempo, in beats per minute, for all p5.Parts. This method will impact all active p5.Parts."
            +      ],
            +      "params": {
            +        "BPM": "숫자: Beats Per Minute",
            +        "rampTime": "숫자: Seconds from now"
            +      }
            +    },
            +    "saveSound": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. For uploading audio to a server, use <a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile that you wish to save",
            +        "fileName": "문자열: name of the resulting .wav file."
            +      }
            +    }
            +  },
            +  "p5.Color": {
            +    "description": [
            +      "처음 만들었을 때의 색상모드와 레벨들의 최댓값들을 저장합니다. 이 값들은 입력 인수로 사용되거나 (창조시기, 또는 같은 색의 인스턴스가 이후에 사용될 때)  출력의 체재를 설정하는데 사용됩니다 (<a href=\"#/p5/saturation\">saturation()</a>와 같은 함수들을 사용할 때).",
            +      "내적으로는 RGBA 값들을 부동소수점 형식으로 배열 안에 저장하며, 이 값들은 0과 1 사이로 정규화됩니다. 이 값들로 가장 가까운 색 (0과 255 사이)를 계산하며 렌더러에 전달합니다.",
            +      "다양한 형식의 부동소수점 구성요소들을 케시에 임시저장하기도 합니다. 이는 최근에 이루어진 계산을 반복하지 않기 위해서입니다."
            +    ],
            +    "setRed": {
            +      "description": [
            +        "setRed 함수는 색깔의 빨강값을 설정합니다. 컬러모드에 따라 다를 수도 있지만, RBG 모드는 0과 255 사이의 값입니다."
            +      ],
            +      "params": {
            +        "red": "숫자: 새로운 빨강값"
            +      }
            +    },
            +    "setGreen": {
            +      "description": [
            +        "setGreen 함수는 색깔의 초록값을 설정합니다. 컬러모드에 따라 다를 수도 있지만, RBG 모드는 0과 255 사이의 값입니다."
            +      ],
            +      "params": {
            +        "green": "숫자: 새로운 초록값"
            +      }
            +    },
            +    "setBlue": {
            +      "description": [
            +        "setBlue 함수는 색깔의 파랑값을 설정합니다. 컬러모드에 따라 다를 수도 있지만, RBG 모드는 0과 255 사이의 값입니다."
            +      ],
            +      "params": {
            +        "blue": "숫자: 새로운 파랑값"
            +      }
            +    },
            +    "setAlpha": {
            +      "description": [
            +        "setAlpha 함수는 색깔의 알파값 (투명도)을 설정합니다. 컬러모드에 따라 다를 수도 있지만, RBG 모드는 0과 255 사이의 값입니다."
            +      ],
            +      "params": {
            +        "alpha": "숫자: 새로운 알파값"
            +      }
            +    }
            +  },
            +  "p5.Element": {
            +    "description": [
            +      "캔버스, 그래픽 버퍼, 기타 HTML 요소를 비롯하여, 스케치에 추가된 모든 요소(element)들을 위한 기본 클래스입니다. p5.Element 클래스는 직접 호출되지 않지만, 그 객체는 createCanvas, createGraphics, createDiv, createImg, createInput 호출을 통해 생성됩니다."
            +    ],
            +    "params": {
            +      "elt": "문자열: 래핑된 DOM 노드",
            +      "pInst": "P5: (선택 사항) p5 인스턴스에 대한 포인터"
            +    },
            +    "elt": {
            +      "description": [
            +        "기본 HTML 요소로, 모든 일반 HTML 메소드를 호출."
            +      ]
            +    },
            +    "parent": {
            +      "description": [
            +        "지정된 부모 클래스에 요소를 연결합니다. 요소의 컨테이너를 설정하는 방법입니다. 문자열 ID, DOM 노드, 또는 p5.Element를 허용합니다. 별도의 인수가 지정되지 않을 경우, 부모 노드가 반환됩니다. 캔버스 배치하는 다른 방법들은 <a href= 'https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>이 위키 페이지</a>에서 확인할 수 있습니다."
            +      ],
            +      "params": {
            +        "parent": "문자열|p5.Element|객체: 지정된 부모 요소의 ID, DOM node, 또는 <a href=\"#/p5.Element\">p5.Element</a>"
            +      }
            +    },
            +    "id": {
            +      "description": [
            +        "요소의 ID를 설정합니다. 별도로 지정한 ID 인수가 없으면, 요소의 현재 ID를 반환합니다. 요소당 1개의 특정 id를 가질 수 있습니다. .class() 함수는 동일한 클래스 이름을 가진 여러 요소들을 식별하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "id": "문자열: 요소의 ID"
            +      }
            +    },
            +    "class": {
            +      "description": [
            +        "사용자가 지정한 클래스를 요소에 더합니다. 별도로 지정한 클래스 인수가 없으면, 요소의 현재 클래스(들)를 포함하는 문자열을 반환합니다."
            +      ],
            +      "params": {
            +        "class": "문자열: 추가할 클래스"
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        ".mousePressed() 함수는 요소 위에서 마우스 버튼이 눌릴 때마다 한 번씩 호출됩니다. 터치 스크린 기반의 모바일 브라우저에서는 손가락 탭을 통해 이벤트가 발생합니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 마우스를 요소 위에서 버튼이 눌릴 때 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        ".doubleClicked() 함수는 요소 위에서 마우스 버튼을 빠르게 두 번 클릭할 때마다 한 번씩 호출됩니다. 요소에 행동 특정적 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "returns": "p5.Element:",
            +      "params": {
            +        "fxn": "함수|불리언: 마우스를 요소 위에서 더블클릭 할 때 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        ".mouseWheel() 함수는 요소 위에서 마우스 휠을 스크롤 할 때마다 한 번싹 호출됩니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다.",
            +        "이 함수에서는 콜백 함수를 인수로서 사용할 수 있습니다. 그 경우, 요소 위에서 휠 이벤트가 발생할 때마다 콜백 함수가 하나의 event 인수로서 전달됩니다. event.deltaY 속성은 마우스 휠이 위쪽으로 회전하거나 사용자로부터 멀어지면 음수값을 반환하고, 그 반대 방향에선 양수값을 반환합니다. event.deltaX 속성은 마우스 가로 휠 스크롤을 읽는다는 점을 제외하고 event.deltaY와 동일하게 작동합니다.",
            +        "",
            +        ""
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 마우스를 요소 위에서 스크롤 할 때 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        ".mouseReleased() 함수는 요소 위에서 마우스 버튼을 놓을 때마다 한 번씩 호출됩니다. 터치 스크린 기반의 모바일 브라우저에서는 손가락 탭을 통해 이벤트가 발생합니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 마우스를 요소 위에서 버튼이 놓일 때 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        ".mouseClicked() 함수는 요소 위에서 마우스 버튼을 클릭한 뒤 놓을 때마다 한 번씩 호출됩니다. 터치 스크린 기반의 모바일 브라우저에서는 손가락 탭을 통해 이벤트가 발생합니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 마우스를 요소 위에서 클릭 할 때 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        ".mouseMoved() 함수는 마우스가 요소 위에서 움직일 때마다 한 번씩 호출됩니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 마우스를 요소 위에서 움직일 때 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "mouseOver": {
            +      "description": [
            +        ".mouseOver() 함수는 마우스가 요소 위에 올라올 때마다 한 번씩 호출됩니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 마우스를 요소 위로 움직일 때 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "mouseOut": {
            +      "description": [
            +        ".mouseOut() 함수는 마우스가 요소 위에서 벗어날 때마다 한 번씩 호출됩니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 마우스를 요소 위에서부터 다른 곳으로 움직일 때 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "touchStarted": {
            +      "description": [
            +        ".touchStarted() 함수는 터치가 등록될 때마다 한 번씩 호출됩니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 터치가 등록될 때마다 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        ".touchMoved() 함수는 터치 움직임이 등록될 때마다 한 번씩 호출됩니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 터치 움직임이 등록될 때마다 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        ".touchEnded() 함수는 터치의 끝이 등록될 때마다 한 번씩 호출됩니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 터치의 끝이 등록될 때마다 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "dragOver": {
            +      "description": [
            +        ".dragOver() 함수는 요소 위에 파일을 드래그할 때마다 한 번씩 호출됩니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 요소 위에 파일을 드래그할 때마다 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "dragLeave": {
            +      "description": [
            +        ".dragLeave() 함수는 드래그된 파일이 요소 영역을 벗어날 때마다 한 번씩 호출됩니다. 요소에 이벤트 리스너를 연결하는 데에 사용됩니다."
            +      ],
            +      "params": {
            +        "fxn": "함수|불리언: 드래그된 파일이 요소 영역을 벗어날 때마다 호출 될 함수. 대신 <code>false</code>을 사용할 시, 함수호출은 중지됩니다."
            +      }
            +    },
            +    "addClass": {
            +      "description": [
            +        "요소에 특정 클래스를 추가합니다."
            +      ],
            +      "params": {
            +        "class": "문자열: 추가할 클래스의 이름"
            +      }
            +    },
            +    "removeClass": {
            +      "description": [
            +        "요소로부터 특정 클래스를 제거합니다."
            +      ],
            +      "params": {
            +        "class": "문자열: 삭제할 클래스의 이름"
            +      }
            +    },
            +    "hasClass": {
            +      "description": [
            +        "요소에 이미 클래스가 설정되어 있는지 확인합니다."
            +      ],
            +      "returns": "불리언: 요소가 클래스가 있는 여부",
            +      "params": {
            +        "c": "문자열: 확인할 클래스의 이름"
            +      }
            +    },
            +    "toggleClass": {
            +      "description": [
            +        "요소 클래스를 토글합니다."
            +      ],
            +      "params": {
            +        "c": "문자열: 토글할 클래스의 이름"
            +      }
            +    },
            +    "child": {
            +      "description": [
            +        "지정된 부모 클래스에 요소를 자식으로서 연결합니다. 문자열 ID, DOM 노드, 또는 p5.Element를 허용합니다. 별도의 인수가 지정되지 않을 경우, 자식 DOM 노드 배열이 반환됩니다."
            +      ],
            +      "returns": "노드 배열[]: 자식 노드의 배열",
            +      "params": {
            +        "child": "문자열|p5.Element: (선택 사항) 본 객체애 연결할 객체의 ID, 문서 객체 모델 (DOM) 노드, 또는 <a href=\"#/p5.Element\">p5.Element</a>"
            +      }
            +    },
            +    "center": {
            +      "description": [
            +        "p5 Element를 수직으로, 수평으로, 또는 수직 및 수평으로 가운데 정렬합니다. 별도로 지정한 부모가 있는 경우 부모를 기준으로, 부모가 없는 경우 그 자신을 기준으로 합니다. 별도로 지정한 인수가 없으면 요소는 수직 및 수평으로 정렬됩니다."
            +      ],
            +      "params": {
            +        "align": "문자열: (선택 사항) 'vertical' 또는 'horizontal'로 요소를 수직 또는 수평적으로 정렬합니다"
            +      }
            +    },
            +    "html": {
            +      "description": [
            +        "사용자가 별도로 지정한 인수로서 요소의 내부 HTML을 설정하며, 기존의 모든 HTML를 대체합니다. 참(true)이 그 2번째 인수로서 포함된 경우, 기존의 모든 HTML을 대체하는 대신 새로운 HTML을 추가(append)합니다. 별도로 지정한 인수가 없으면 요소의 내부 HTML을 반환합니다."
            +      ],
            +      "returns": "문자열: 요소의 내부 HTML 요소",
            +      "params": {
            +        "html": "문자열: (선택 사항) 요소 안에 설정할 HTML",
            +        "append": "불리언: (선택 사항) 새로 입력한 HTML을 추가 (false의 경우 기존 HTML을 덮어 씁니다)"
            +      }
            +    },
            +    "position": {
            +      "description": [
            +        "요소의 위치를 설정합니다. 별도로 지정한 위치 유형 인수가 없는 경우, 화면창의 (0,0)을 기준으로 합니다. 기본적으로, 이 메소드를 통해 position:absolute와 left 및 top 스타일 속성을 설정합니다. 선택적으로, 3번째 인수를 통해 x 및 y 좌표의 <a href ='https://developer.mozilla.org/ko/docs/Web/CSS/position'>위치 지정 체계</a>를 설정할 수 있습니다. 별도로 지정한 인수가 없으면 함수는 요소의 x와 y의 위치를 반환합니다."
            +      ],
            +      "returns": "객체: 요소의 위치를 나타내는 { x: 0, y: 0 } 형식의 객체",
            +      "params": {
            +        "x": "숫자: (선택 사항) 윈도우 왼쪽 위 기준으로한 x 위치",
            +        "y": "숫자: (선택 사항) 윈도우 왼쪽 위 기준으로한 y 위치",
            +        "positionType": "문자열: static, fixed, relative, sticky, initial 또는 inherit"
            +      }
            +    },
            +    "style": {
            +      "description": [
            +        "별도 지정한 값(2번째 인수)으로 CSS 스타일 속성(1번째 인수)을 설정합니다. 1개의 인수만 지정할 경우, .style()은 주어진 속성의 값을 반환합니다. 그러나 이 인수를 CSS 구문('text-align:center')으로 작성할 경우, .style()은 CSS를 설정합니다."
            +      ],
            +      "returns": "문자열: 속성의 값",
            +      "params": {
            +        "property": "문자열: 설정할 속성",
            +        "value": "문자열|p5.Color: 속성에 설정할 값"
            +      }
            +    },
            +    "attribute": {
            +      "description": [
            +        "사용자가 지정한 요소에 새 속성을 추가하거나, 요소의 기존 속성값을 변경합니다. 별도로 지정한 값이 없는 경우 주어진 속성의 값을 반환하고, 속성이 설정되지 않은 경우 null을 반환합니다."
            +      ],
            +      "returns": "문자열: 속성의 값",
            +      "params": {
            +        "attr": "문자열: 설정할 속성",
            +        "value": "문자열: 설정할 속성값"
            +      }
            +    },
            +    "removeAttribute": {
            +      "description": [
            +        "요소로부터 속성을 제거합니다."
            +      ],
            +      "params": {
            +        "attr": "문자열: 삭제할 속성"
            +      }
            +    },
            +    "value": {
            +      "description": [
            +        "별도로 지정한 인수가 없는 경우, 요소의 값을 반환하거나 설정합니다."
            +      ],
            +      "returns": "문자열|숫자: 요소의 값",
            +      "params": {
            +        "value": "문자열|숫자"
            +      }
            +    },
            +    "show": {
            +      "description": [
            +        "현재 요소를 보여줍니다. display:block로 스타일을 설정합니다."
            +      ]
            +    },
            +    "hide": {
            +      "description": [
            +        "현재 요소를 숨깁니다. display:none으로 스타일을 설정합니다."
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "요소의 너비와 높이를 설정합니다. AUTO는 한 번에 한 개의 수치를 조정하는 데에 쓰입니다. 별도로 지정한 인수가 없는 경우, 객체 속 요소의 너비와 높이를 반환합니다. 이미지 파일과 같이 불러오기가 필요한 요소의 경우, 불러오기가 완료된 후 함수를 호출하는 것을 권장합니다."
            +      ],
            +      "returns": "객체: 객체 안 요소의 너비와 높이",
            +      "params": {
            +        "w": "숫자|상수: 요소의 너비 - AUTO, 또는 숫자",
            +        "h": "숫자|상수: (선택 사항) 요소의 높이 - AUTO, 또는 숫자"
            +      }
            +    },
            +    "remove": {
            +      "description": [
            +        "요소를 제거하고, 모든 미디어 스트림을 중지하며, 모든 리스너를 해제합니다."
            +      ]
            +    },
            +    "drop": {
            +      "description": [
            +        "요소에 드롭된 파일이 로드될 때마다 호출되는 콜백을 등록합니다. p5는 메모리에 드롭된 모든 파일을 로드하고 이를 p5.File 객체로서 콜백에 전달합니다. 동시에 여러 파일을 드롭할 경우, 콜백이 여러 번 호출됩니다. 선택적으로, raw 드롭 이벤트에 등록될 2번째 콜백을 전달할 수 있습니다.",
            +        "이 경우, 콜백에 본래 <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>도 제공됩니다. 동시에 여러 파일을 드롭하면 2번째 콜백이 드롭당 한 번씩 발생하며, 1번째 콜백은 로드된 파일당 한 번씩 발생합니다."
            +      ],
            +      "params": {
            +        "callback": "함수: 로딩된 파일을 사용할 콜백 함수. 파일이 드롭될 때마다 호출됩니다.",
            +        "fxn": "함수: (선택 사항) 파일들이 드롭될 경우 단 한번만 호출될 콜백 함수."
            +      }
            +    }
            +  },
            +  "p5.Graphics": {
            +    "description": [
            +      "렌더러을 둘러싼 얇은 래퍼(wrapper)로, 그래픽 버퍼 객체를 생성하는 데에 사용합니다. 화면 밖 그래픽 버퍼에 그리려면 이 클래스를 사용합니다. 2개의 매개변수는 너비와 높이를 픽셀 단위로 지정합니다. 이 클래스의 필드와 메소드는 확장성이 있으나, p5를 위한 일반적인 그리기 API를 반영합니다. p5.Element를 확장합니다."
            +    ],
            +    "params": {
            +      "w": "숫자: 너비값",
            +      "h": "숫자: 높이값",
            +      "renderer": "상수: 사용할 렌더러, P2D 또는 WEBGL",
            +      "pInst": "P5: (선택 사항) p5 인스턴스에 대한 포인터"
            +    },
            +    "reset": {
            +      "description": [
            +        "그래픽 버퍼 객체로 자동 재설정되지 않은 특정값들(예: 레퍼런스 중 변형(Transform) 또는 조명(Light) 항목에 해당하는 함수들로서 지정된 값들). 이 메소드를 <a href=\"#/p5/draw\">draw()</a> 함수 안에서 호출하면, 기본 캔버스의 행위를 복제합니다."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "페이지에서 그래픽 객체를 제거하고 이 객체에 연결된 모든 소스들을 연결 해제합니다."
            +      ]
            +    }
            +  },
            +  "p5.Renderer": {
            +    "description": [
            +      "그래픽과 렌더링의 기초되는 클래스이며, p5.js의 코어 (core)에 사용되는 기초적 API입니다. Render2D와 Renderer3D 클래스들의 부모클래스로 사용됩니다."
            +    ],
            +    "params": {
            +      "elt": "문자열: DOM 노드",
            +      "pInst": "P5: (선택 사항) p5 인스턴스에 향한 포인터",
            +      "isMainCanvas": "불리언: (선택 사항) 메인 캔버스임의 여부"
            +    }
            +  },
            +  "JSON": {
            +    "stringify": {
            +      "description": [
            +        "<a href=\"https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">MDN에서 참고</a>: JSON.stringify() 메서드는 JavaScript 값이나 객체를 JSON <a href=\"#/p5/string\">문자열</a>로 변환합니다. 선택적으로, replacer를 함수로 전달할 경우 변환 전 값을 변형할 수 있고, 배열로 전달할 경우 지정한 속성만 결과에 포함합니다."
            +      ],
            +      "params": {
            +        "object": "객체: JSON으로 변형하고 싶은 JavaScript 객체"
            +      }
            +    }
            +  },
            +  "console": {
            +    "log": {
            +      "description": [
            +        "브라우저의 메세지 콘솔에 메세지를 프린트합니다. p5에서는 <a href=\"#/p5/print\">print</a> 또는 <a href=\"#/p5/console/log\">console.log</a> 모두 사용가능합니다.",
            +        "콘솔은 브라우저에 따라 다르게 열립니다. 다음은 여러가지 방법이 제시되어 있습니다. <a href=\"https://developer.mozilla.org/ko/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a> , <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/ko-kr/microsoft-edge/devtools-guide/console\">Edge</a>, <a href=\"https://support.apple.com/ko-kr/guide/safari/sfri20948/mac\">Safari</a>. <br> <a href=\"https://editor.p5js.org/\">온라인 p5 에디터</a>에서는 콘솔이 코트 에디터 바로 밑에 고정되어 있습니다.",
            +        "From <a href=\"https://developer.mozilla.org/ko/docs/Web/API/Console/log\">the MDN entry</a>: The Console method log() outputs a message to the web console. The message may be a single <a href=\"#/p5/string\">string</a> (with optional substitution values), or it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>."
            +      ],
            +      "params": {
            +        "message": "문자열|Expression|객체: 콘솔에 프린트하고 싶은 메세지"
            +      }
            +    }
            +  },
            +  "p5.TypedDict": {
            +    "description": [
            +      "모든 p5.Dictionary 유형을 위한 기본 클래스 입니다. 사용자가 지정한 사전(Dictionary) 클래스는 이 클래스를 상속할 수 있습니다."
            +    ],
            +    "size": {
            +      "description": [
            +        "사전 안에 현재 저장된 키-값(key-value) 쌍의 개수를 반환합니다."
            +      ],
            +      "returns": "정수: 사전에 있는 쌍의 개수"
            +    },
            +    "hasKey": {
            +      "description": [
            +        "지정된 키(key)가 사전 안에 존재할 경우 참(true)을, 그렇지 않으면 거짓(false)를 반환합니다."
            +      ],
            +      "returns": "불리언: 특정 키가 사전에 존재하는지의 여부",
            +      "params": {
            +        "key": "숫자|문자열: 검색하고 싶은 키"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "지정된 키에 저장된 값을 반환합니다."
            +      ],
            +      "returns": "숫자|문자열: 키에 저장된 값",
            +      "params": {
            +        "the": "숫자|문자열: 읽고 싶은 키"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "지정된 키가 사전 안에 존재할 경우 연관된 값을 반환합니다. 그렇지 않으면 새로운 키-값 쌍이 추가됩니다."
            +      ],
            +      "params": {
            +        "key": "숫자|문자열",
            +        "value": "숫자|문자열"
            +      }
            +    },
            +    "create": {
            +      "description": [
            +        "새로운 키-값 쌍을 사전 안에 생성합니다."
            +      ],
            +      "params": {
            +        "key": "숫자|문자열",
            +        "value": "숫자|문자열",
            +        "obj": "객체: 키/값 쌍"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "기존에 저장된 모든 키-값 쌍들을 사전으로부터 제거합니다."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "특정 키에 저장된 키-값 쌍을 사전으로부터 제거합니다."
            +      ],
            +      "params": {
            +        "key": "숫자|문자열: for the pair to remove"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Dictionary에 현재 저장된 항목들의 로그를 콘솔창에 출력합니다."
            +      ]
            +    },
            +    "saveTable": {
            +      "description": [
            +        "로컬 다운로드를 위해 사전을 CSV 파일로 변환합니다."
            +      ]
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "로컬 다운로드를 위해 사전을 JSON 파일로 변환합니다."
            +      ]
            +    }
            +  },
            +  "p5.StringDict": {
            +    "description": [
            +      "문자열을 위한 간단한 사전."
            +    ]
            +  },
            +  "p5.NumberDict": {
            +    "description": [
            +      "숫자를 위한 간단한 사전 클래스<br>p5.TypedDict를 확장합니다."
            +    ],
            +    "add": {
            +      "description": [
            +        "특정 키에 현재 저장된 값에 사용자가 지정한 숫자를 더하고, 그 결과값은 사전 안에 저장되어있던 기존값을 대체합니다."
            +      ],
            +      "params": {
            +        "Key": "숫자: 숫자를 더하고 싶은 키",
            +        "Number": "숫자: 값에 더할 숫자"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "특정 키에 현재 저장된 값에서 사용자가 지정한 숫자를 빼고, 그 결과값은 사전 안에 저장되어있던 기존값을 대체합니다."
            +      ],
            +      "params": {
            +        "Key": "숫자: 숫자를 뻬고 싶은 키",
            +        "Number": "숫자: 값에서 뺄 숫자"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "특정 키에 현재 저장된 값에 사용자가 지정한 숫자를 곱하고, 그 결과값은 사전 안에 저장되어있던 기존값을 대체합니다."
            +      ],
            +      "params": {
            +        "Key": "숫자: 숫자를 곱하고 싶은 키",
            +        "Amount": "숫자: 값에 곱할 숫자"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "특정 키에 현재 저장된 값을 사용자가 지정한 숫자로 나누고, 그 몫은 사전 안에 저장되어있던 기존값을 대체합니다."
            +      ],
            +      "params": {
            +        "Key": "숫자: 숫자로 나누고 싶은 키",
            +        "Amount": "숫자: 값으로부터 나눌 숫자"
            +      }
            +    },
            +    "minValue": {
            +      "description": [
            +        "사전 안에 현재 저장된 값들 중 가장 낮은 숫자를 반환합니다."
            +      ],
            +      "returns": "숫자: 가장 낮은 숫자"
            +    },
            +    "maxValue": {
            +      "description": [
            +        "사전 안에 현재 저장된 값들 중 가장 높은 숫자를 반환합니다."
            +      ],
            +      "returns": "숫자: 가장 높은 숫자"
            +    },
            +    "minKey": {
            +      "description": [
            +        "사전에서 사용된 키들 중 가장 낮은 키를 반환합니다."
            +      ],
            +      "returns": "숫자: 가장 낮은 키"
            +    },
            +    "maxKey": {
            +      "description": [
            +        "사전에서 사용된 키들 중 가장 높은 키를 반환합니다."
            +      ],
            +      "returns": "숫자: 가장 높은 키"
            +    }
            +  },
            +  "p5.MediaElement": {
            +    "description": [
            +      "오디오/비디오 처리를 위해 p5.Element를 확장합니다. p5.Element의 메소드 뿐 아니라, 미디어 제어를 위한 메소드도 포함합니다. p5.MediaElements는 직접 호출되지 않지만, createVideo, createAudio, CreateCapture 호출을 통해 생성됩니다."
            +    ],
            +    "params": {
            +      "elt": "문자열: 래핑된 DOM 노드"
            +    },
            +    "src": {
            +      "description": [
            +        "미디어 요소 소스 경로"
            +      ],
            +      "returns": "문자열: 소스"
            +    },
            +    "play": {
            +      "description": [
            +        "HTML5 미디어 요소를 재생합니다."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "HTML5 미디어 요소를 중지합니다. (현재 시간을 0으로 설정)"
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "HTML5 미디어 요소를 일시정지합니다."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "HTML5 미디어 요소의 반복을 참(true)로 설정하고, 재생 시작합니다."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "HTML5 미디어 요소의 반복을 거짓(false)으로 설정합니다. 종료 시점에 도달하면 요소가 중지합니다."
            +      ]
            +    },
            +    "autoplay": {
            +      "description": [
            +        "HTML5 미디어 요소 자동재생 여부 설정"
            +      ],
            +      "params": {
            +        "shouldAutoplay": "불리언: 요소의 자동재생 여부"
            +      }
            +    },
            +    "volume": {
            +      "description": [
            +        "HTML5 미디어 요소의 볼륨을 설정합니다. 별도로 지정한 인수가 없으면, 현재 볼륨을 반환합니다."
            +      ],
            +      "returns": "숫자: 현재 볼륨",
            +      "params": {
            +        "val": "숫자: 0.0과 1.0 사이의 볼륨"
            +      }
            +    },
            +    "speed": {
            +      "description": [
            +        "별도로 지정한 인수가 없으면, 요소의 현재 재생 속도를 반환하빈다. 속도 매개변수는 2.0일 때 2배속으로, 0.5일 때 0.5배속으로, -1일 때 정상 속도로 역재생합니다. (모든 브라우저가 역재생을 지원하지 않으며, 일부 지원 브라우저에서도 부드럽게 재생되지 않을 수 있습니다.)"
            +      ],
            +      "returns": "숫자: 요소의 현재 재생 속도",
            +      "params": {
            +        "speed": "숫자: 배속도 매개변수"
            +      }
            +    },
            +    "time": {
            +      "description": [
            +        "별도로 지정한 인수가 없을 경우, 요소의 현재 시간을 반환합니다. 인수가 지정될 경우, 요소의 현재 시간이 해당 인수로 설정됩니다."
            +      ],
            +      "returns": "숫자: 현재 시간 (초)",
            +      "params": {
            +        "time": "숫자: 설정할 시간 (초)"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "HTML5 미디어 요소의 지속 시간을 반환합니다."
            +      ],
            +      "returns": "숫자: 지속 시간"
            +    },
            +    "onended": {
            +      "description": [
            +        "오디오/비디오 요소가 종료 시점에 도달할 때 호출할 이벤트를 예약합니다. 요소가 반복하는 경우 호출되지 않습니다. 요소는 oneded 콜백에 인수로 전달됩니다."
            +      ],
            +      "params": {
            +        "callback": "함수: 오디오/비디오 요소가 끝났을 때 호출될 함수. 요소는 콜백 함수의 인자값으로 지정됩니다."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "요소가 출력한 오디오를 특정 audioNode나 p5.sound 객체로 보냅니다. 요소가 없는 경우, p5의 마스터 출력에 연결합니다. 모든 연결은 .disconnect() 메소드로 제거할 수 있습니다.",
            +        "p5.sound.js 추가적 라이브러리로 이러한 방법을 사용할 수 있습니다."
            +      ],
            +      "params": {
            +        "audioNode": "AudioNode|객체: 웹 오디오 API의 AudioNode, 또는 p5.sound 라이브러리의 객체"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "마스터 출력을 비롯하여 모든 웹 오디오 라우팅을 분리합니다. 사용 예: 오디오 효과를 통해 출력을 다시 라우팅할 때"
            +      ]
            +    },
            +    "showControls": {
            +      "description": [
            +        "웹 브라우저가 지정한 기본 미디어 요소(MediaElement) 컨트롤을 나타냅니다."
            +      ]
            +    },
            +    "hideControls": {
            +      "description": [
            +        "기본 미디어 요소(MediaElement) 컨트롤을 숨깁니다."
            +      ]
            +    },
            +    "addCue": {
            +      "description": [
            +        "오디오/비디오와 같은 미디어 요소(MediaElement)가 재생 큐 지점에 도달할 때 발생할 이벤트를 예약합니다.",
            +        "콜백 함수, 콜백이 발생할 시간(초 단위), 콜백에 대한 선택적 매개변수를 허용합니다.",
            +        "첫 번째 매개변수는 시간(time)을, 두 번째 매개변수는 param을 콜백 함수에 전달합니다."
            +      ],
            +      "returns": "숫자: 큐의 ID. removeCue(id) 함수에 유용함.",
            +      "params": {
            +        "time": "숫자: 요소에 대한 초 단위의 시산. 예를 들어, 2초마다 이벤트를 발생시킬 시, 숫자 '2'를 인자값으로 합니다. 이 숫자는 콜백 함수의 첫 매개변수로 전달됩니다.",
            +        "callback": "함수: 호출될 함수. 콜백 함수는 매개변수로 'time'과 'param'을 받습니다.",
            +        "value": "객체: (선택 사항) 콜백 함수에 전달될 객체."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "ID를 기반으로 콜백을 제거합니다. ID는 addCue 메소드로 반환됩니다."
            +      ],
            +      "params": {
            +        "id": "숫자: addCue에서 반환되는 cue의 ID"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "addCue 메소드로 예약된 모든 콜백을 제거합니다."
            +      ],
            +      "params": {
            +        "id": "숫자: addCue에서 반환되는 cue의 ID"
            +      }
            +    }
            +  },
            +  "p5.File": {
            +    "description": [
            +      "파일을 위한 기본 클래스입니다. Element.drop()과 createFileInput()에 사용됩니다."
            +    ],
            +    "params": {
            +      "file": "파일: 래핑된 파일"
            +    },
            +    "file": {
            +      "description": [
            +        "기본 파일 객체. 모든 일반 File 메소드를 호출할 수 있습니다."
            +      ]
            +    },
            +    "type": {
            +      "description": [
            +        "파일 유형 (이미지, 텍스트 등)"
            +      ]
            +    },
            +    "subtype": {
            +      "description": [
            +        "파일 하위 유형 (주로 jpg, png, xml 등의 파일 확장자)"
            +      ]
            +    },
            +    "name": {
            +      "description": [
            +        "파일명"
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "파일 크기"
            +      ]
            +    },
            +    "data": {
            +      "description": [
            +        "이미지 데이터를 담는 URL 문자열"
            +      ]
            +    }
            +  },
            +  "p5.Image": {
            +    "description": [
            +      "Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an image.",
            +      "p5 can display .gif, .jpg and .png images. Images may be displayed in 2D and 3D space. Before an image is used, it must be loaded with the <a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and height of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the values for every pixel in the image.",
            +      "The methods described below allow easy access to the image's pixels and alpha channel and simplify the process of compositing.",
            +      "Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on the image to make sure that the pixel data is properly loaded."
            +    ],
            +    "params": {
            +      "width": "숫자",
            +      "height": "숫자"
            +    },
            +    "width": {
            +      "description": [
            +        "Image width."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "Image height."
            +      ]
            +    },
            +    "pixels": {
            +      "description": [
            +        "디스플레이 화면의 모든 픽셀값을 담는 <a href ='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray'>Uint8ClampedArray</a>입니다. 픽셀값은 숫자로 표현됩니다. 배열은 디스플레이 화면의 4배 크기(픽셀 밀도에 대한 인수 포함)로, 각 픽셀에 대한 R, G, B, A값을 나타냅니다. 배열은 행의 좌에서 우로, 그 다음 열로 내려가는 순으로 채워집니다. Retina를 비롯한 기타 고밀도 디스플레이는 (pixelDensity^2 계수로 인해) 크기가 더 큰 픽셀 배열[]을 갖기도 합니다. 일반 디스플레이 화면상 이미지가 100x100 픽셀이고 그 배열이 40,000이라면, Retina에서 배열은 160,000이 됩니다. ",
            +        "배열상 처음 4개의 값들(즉, 인덱스 0-3)은 (0,0) 픽셀에서의 R, G, B, A값을, 그 다음 4개의 값들(즉, 인덱스 4-7)은 (1,0) 픽셀에서의 R, G, B, A값을 담습니다. 특정 좌표 (x,y)에서의 픽셀값을 설정하는 방법은 아래의 예제와 같습니다.",
            +        "다소 복잡해보이는 예제지만, 모든 픽셀 밀도(pixelDensity)를 사용할 수 있을정도로 유연합니다. set()은 임의의 pixelDensity에서 주어진 (x,y)에 대한 픽셀 배열[]의 모든 값들을 자동으로 설정합니다. 배열을 여러 차례 수정할 경우, 성능이 느려질 수 있습니다.",
            +        "이 배열을 사용하기 전, 데이터를 <a href=\"#/p5/loadPixels\">loadPixels()</a> 함수로 로딩해야 합니다. 또, 배열의 정보가 수정되었을 경우 <a href=\"#/p5/updatePixels\">updatePixels()</a> 함수를 호출해야 이 수정된 부분들을 반영할 수 있습니다.",
            +        "이 레퍼런스는 표준 자바스크립트 배열이 아니고, 따라서 <a href=\"#/p5/slice\">slice()</a>나 <a href=\"#/p5/arrayCopy\">arrayCopy()</a>와 같은 표준 자바스크립트 함수가 작동하지 않습니다."
            +      ]
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "디스플레이 창의 픽셀 데이터를 pixels[] 배열에 불러옵니다."
            +      ]
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "pixels[] 배열의 데이터로 디스플레이 창을 업데이트합니다. loadPixels()와 함께 사용합니다. 배열로부터 픽셀값을 읽어오기만 할 경우, updatePixels()를 사용할 필요가 없습니다. 업데이트는 배열값 변경 사항을 적용하는 데에만 필요합니다. updatePixels()는 픽셀 배열을 수정하거나 set() 함수를 호출할 때마다 매번 호출되어야하며, set() 함수 또는 pixels[] 배열 직접 조작을 통한 변경 사항만 반영합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: (선택 사항) 업데이트할 영역의 좌측 상단 모퉁이 x좌표값",
            +        "y": "숫자: (선택 사항) 업데이트할 영역의 좌측 상단 모퉁이 y좌표값",
            +        "w": "숫자: (선택 사항) 업데이트할 영역의 너비값",
            +        "h": "숫자: (선택 사항) 업데이트할 영역의 높이값"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "지정된 픽셀 영역 또는 단일 픽셀을 캔버스로부터 받아옵니다.",
            +        "별도의 매개변수를 지정하지 않는 경우, 전체 이미지를 반환합니다. 매개변수 x, y를 통해 특정 픽셀의 좌표값을 받아올 수 있습니다. 추가 매개변수 w, h를 통해 디스플레이 창의 한 영역을 지정할 수도 있습니다. 이때 <a href=\"#/p5.Image\">p5.Image</a>의 객체가 반환됩니다."
            +      ],
            +      "returns": "p5.Image: 직사각형 <a href=\"#/p5.Image\">p5.Image</a> 객체",
            +      "params": {
            +        "x": "숫자: 픽셀의 x좌표값",
            +        "y": "숫자: 픽셀의 y좌표값",
            +        "w": "숫자: 너비",
            +        "h": "숫자: 높이"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "특정 픽셀의 색상을 변경하거나, <a href=\"#/p5.Image\">p5.Image</a>에 직접 작성합니다.",
            +        "참고로 다량의 픽셀을 변경할 시, 직접 픽셀 배열을 변경한 후 <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> 함수를 호출하는 것이 더 빠르고 간편할 수 있습니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 픽셀의 x좌표값",
            +        "y": "숫자: 픽셀의 y좌표값",
            +        "c": "숫자|숫자 배열[]|객체: 채도값 | 픽셀 배열 | <a href=\"#/p5.Color\">p5.Color</a> 객체 | <a href=\"#/p5.Image\">p5.Image</a> 객체"
            +      }
            +    },
            +    "resize": {
            +      "description": [
            +        "이미지의 높이와 너비를 재조정합니다. 비례적으로 재조정하고 싶다면 높이 또는 너비 인수를 0으로 지정하면 됩니다. 예를 들어, 너비를 150 픽셀로 하고 싶으면 resize(150,0)를 사용할 수 있습니다."
            +      ],
            +      "params": {
            +        "width": "숫자: 재조정할 이미지 너비",
            +        "height": "숫자: 재조정할 이미지 높이"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "캔버스의 한 영역을 다른 영역에 복사하고, srcImg 매개변수로 사용되는 한 이미지의 픽셀 영역을 캔버스에 복사합니다. srcImage는 원본 이미지로, 사용자가 지정합니다. 원본과 복사 대상 영역의 크기가 같지 않을 경우, 원본 픽셀 영역의 크기를 대상 영역의 크기에 맞게 자동으로 재조정합니다."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5 요소: 원본 이미지",
            +        "sx": "정수: 원본 영역의 좌측 상단 모퉁이 x좌표값",
            +        "sy": "정수: 원본 영역의 좌측 상단 모퉁이 y좌표값",
            +        "sw": "정수: 원본 이미지 너비값",
            +        "sh": "정수: 원본 이미지 높이값",
            +        "dx": "정수: 대상 영역의 좌측 상단 모퉁이 x좌표값",
            +        "dy": "정수: 대상 영역의 좌측 상단 모퉁이 y좌표값",
            +        "dw": "정수: 대상 이미지 너비값",
            +        "dh": "정수: 대상 이미지 높이값"
            +      }
            +    },
            +    "mask": {
            +      "description": [
            +        "이미지의 특정 부위가 보이지 않도록 다른 이미지를 알파 채널 (alpha channel)로 사용합니다."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: 원본 이미지"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "캔버스에 필터를 적용합니다.",
            +        "THRESHOLD: 이미지를 인계값에 따라 흰색이나 검은색 픽셀로 바꿉니다. 이 인계값은 매개변수로 정해지며, 0.0 (검은)과 1.0 (흰) 사이에 있는 값입니다. 매개변수를 지정하지 않을 시 0.5가 사용됩니다.",
            +        "GRAY: 이미지의 모든 색상을 그레이 스케일로 변환합니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "OPAQUE: 알파 채널을 완전히 불투명하게 설정합니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "INVERT: 각 픽셀을 그 역의 값으로 설정합니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "POSTERIZE: 이미지의 각 채널을 매개변수로 지정한 색상 수로 제한합니다. 매개변수는 2부터 255사이의 값으로 설정 가능하나, 낮은 범위에서 가장 두드러진 결과를 볼 수 있습니다.",
            +        "BLUR: 블러 범위를 설정하는 level 매개변수를 사용하여 가우시안 블러를 실행합니다. 별도의 매개변수를 지정하지 않으면, 반경 1의 가우시안 블러와 동일한 효과가 됩니다. 값이 클수록 흐림 정도가 증가합니다.",
            +        "ERODE: 밝은 영역을 줄입니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "DILATE: 밝은 영역을 증가시킵니다. 별도의 매개변수를 사용하지 않습니다.",
            +        "WebGL 모드에서는 filter()가 작동하지 않으나, 커스텀 셰이더를 사용하여 유사한 효과를 얻을 수 있습니다. 아담 페리스(Adam Ferriss)가 작성한 <a href='https://github.com/aferriss/p5jsShaderExamples'>셰이더 예제</a> 중, filter()와 유사한 효과를 나타내는 예제들이 있습니다."
            +      ],
            +      "params": {
            +        "filterType": "상수: THRESHOLD, GRAY, OPAQUE, INVERT, POSTERIZE, BLUR, ERODE, DILATE, BLUR 중 하나. 각 필터에 대한 문서는 Filters.js를 참조.",
            +        "filterParam": "숫자: (선택 사항) 각 필터 고유의 선택적 매개변수"
            +      }
            +    },
            +    "blend": {
            +      "description": [
            +        "사용자가 지정한 혼합 모드를 사용하여, 한 이미지의 픽셀 영역을 다른 이미지로 복사합니다."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: 원본 이미지",
            +        "sx": "정수: 원본 영역의 좌측 상단 모퉁이 x좌표값",
            +        "sy": "정수: 원본 영역의 좌측 상단 모퉁이 y좌표값",
            +        "sw": "정수: 원본 이미지 너비값",
            +        "sh": "정수: 원본 이미지 높이값",
            +        "dx": "정수: 대상 영역의 좌측 상단 모퉁이 x좌표값",
            +        "dy": "정수: 대상 영역의 좌측 상단 모퉁이 y좌표값",
            +        "dw": "정수: 대상 이미지 너비값",
            +        "dh": "정수: 대상 이미지 높이값",
            +        "blendMode": "상수: the blend mode. either  BLEND, DARKEST, LIGHTEST, DIFFERENCE,  MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD or NORMAL. Available blend modes are: normal | multiply | screen | overlay |  darken | lighten | color-dodge | color-burn | hard-light |  soft-light | difference | exclusion | hue | saturation |  color | luminosity <a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">(참고 링크)</a>"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "이미지를 파일로 저장하고 브라우저가 다운로드를 하도록 합니다. 인자값으로는 문자열 두 개를 받습니다. 첫 번째는 파일명, 두 번째는 파일형식입니다. 파일형식은 png (기본), jpg, 또는 gif으로 저장됩니다. 참고로 애니매이션이 있는 GIF 파일은 원본 p5.Image이 GIF 파일에서부터 로딩되었을 경우에만 애니매이션이 있는 상태로 저장됩니다."
            +      ],
            +      "params": {
            +        "filename": "문자열: 파일명",
            +        "extension": "문자열: 'png' 또는 'jpg'. 'gif'도 가능."
            +      }
            +    },
            +    "reset": {
            +      "description": [
            +        "애니매이션이 있는 GIF 파일을 처음부터 재생합니다."
            +      ]
            +    },
            +    "getCurrentFrame": {
            +      "description": [
            +        "애니매이션이 있는 GIF 파일에서 현재 보이는 프레임의 배열값를 반환합니다."
            +      ],
            +      "returns": "숫자: GIF 파일에서 현재 보이는 프레임의 배열값"
            +    },
            +    "setFrame": {
            +      "description": [
            +        "애니매이션이 있는 GIF 파일에서 현재 보이는 프레임의 배열값를 정합니다."
            +      ],
            +      "params": {
            +        "index": "숫자: GIF 파일에서 현재 보일 프레임의 배열값"
            +      }
            +    },
            +    "numFrames": {
            +      "description": [
            +        "애니매이션이 있는 GIF 파일의 프레임 수를 반환합니다."
            +      ],
            +      "returns": "숫자: 프레임 수"
            +    },
            +    "play": {
            +      "description": [
            +        "<a href=\"#/p5.Image/pause\">pause()</a> 함수로 멈춰있던 GIF 파일을 재생합니다."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "GIF 파일의 재생을 멈춥니다."
            +      ]
            +    },
            +    "delay": {
            +      "description": [
            +        "각 프레임 사이의 지연시간을 설정합니다. 선택적인 두 번째 매개변수를 사용할 시, 입력하는 특정 배열값의 프레임만 바뀌는 시간을 설정합니다. 두 번째 매개변수가 없을 시 모든 프레임에 지연시간을 동일하게 설정합니다."
            +      ],
            +      "params": {
            +        "d": "숫자: 지연시간 (밀리초 단위)",
            +        "index": "숫자: (선택 사항) 특정 프레임의 배열값"
            +      }
            +    }
            +  },
            +  "p5.PrintWriter": {
            +    "params": {
            +      "filename": "문자열:",
            +      "extension": "문자열: (선택 사항)"
            +    },
            +    "write": {
            +      "description": [
            +        "PrintWriter 스트림에 데이터를 작성합니다."
            +      ],
            +      "params": {
            +        "data": "배열: PrintWriter가 작성할 모든 데이터"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "PrintWriter 스트림에 데이터를 작성하고, 마지막에 새로운 한 줄을 추가합니다."
            +      ],
            +      "params": {
            +        "data": "배열: PrintWriter가 프린트 할 모든 데이터"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "PrintWriter 객체에 이미 작성된 데이터를 제거합니다."
            +      ]
            +    },
            +    "close": {
            +      "description": [
            +        "PrintWriter를 종료합니다."
            +      ]
            +    }
            +  },
            +  "p5.Table": {
            +    "description": [
            +      "테이블 객체는 기존의 스프레트 시트처럼 복수의 행과 열에 데이터를 저장합니다. 동적으로 새로운 테이블을 생성하거나, 기존 파일 데이터를 사용하여 생성할 수 있습니다."
            +    ],
            +    "params": {
            +      "rows": "p5.TableRow 배열[]: (선택 사항) p5.TableRow 객체의 배열"
            +    },
            +    "columns": {
            +      "description": [
            +        "테이블의 행명을 담는 배열. 테이블의 헤더(header)를 함께 불러올 경우, header 매개변수."
            +      ]
            +    },
            +    "rows": {
            +      "description": [
            +        "테이블의 행을 채우는 p5.TableRow 객체의 배열. getRows() 호출과 동일한 결과를 갖습니다."
            +      ]
            +    },
            +    "addRow": {
            +      "description": [
            +        "addRow()를 사용하여 p5.Table 객체에 새로운 행 데이터를 추가할 수 있습니다. 기본값으로 빈 행이 생성됩니다. 일반적으로, TableRow 객체에 있는 새로운 행에 레퍼런스를 저장하고 (위의 예제 중 newRow 참고), set()을 사용하여 각각의 개별값을 설정합니다. p5.TableRow 객체를 매개변수로 지정할 경우, 행을 복제하여 테이블에 추가합니다.",
            +        "If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is duplicated and added to the table."
            +      ],
            +      "returns": "p5.TableRow: 추가된 행",
            +      "params": {
            +        "row": "p5.TableRow: (선택 사항) 추가될 행"
            +      }
            +    },
            +    "removeRow": {
            +      "description": [
            +        "테이블 객체에서 행을 제거합니다."
            +      ],
            +      "params": {
            +        "id": "정수: 제거할 행의 ID"
            +      }
            +    },
            +    "getRow": {
            +      "description": [
            +        "지정된 p5.TableRow에 레퍼런스를 반환합니다. 반환된 레퍼런스는 지정된 행의 값을 받아오거나 설정할 때 사용할 수 있습니다."
            +      ],
            +      "returns": "p5.TableRow: <a href=\"#/p5.TableRow\">p5.TableRow</a> 객체",
            +      "params": {
            +        "rowID": "정수: 찾을 행의 ID"
            +      }
            +    },
            +    "getRows": {
            +      "description": [
            +        "테이블의 모든 행을 받아옵니다. p5.TableRow 배열들을 반환합니다."
            +      ],
            +      "returns": "p5.TableRow 배열[]: <a href=\"#/p5.TableRow\">p5.TableRow</a>의 배열"
            +    },
            +    "findRow": {
            +      "description": [
            +        "지정된 값을 포함하는 테이블 행 중 1번째 행을 검색하고, 해당 행의 레퍼런스를 반환합니다. 여러 개의 행들이 지정된 값을 포함하더라도, 오직 1번째 행만 반환됩니다. ID 또는 제목(title) 설정을 통해 검색할 열도 지정가능합니다."
            +      ],
            +      "returns": "p5.TableRow:",
            +      "params": {
            +        "value": "문자열: 검색할 값",
            +        "column": "정수|문자열: 검색할 열의 ID 또는 제목"
            +      }
            +    },
            +    "findRows": {
            +      "description": [
            +        "지정된 값을 포함하는 테이블 행들을 검색하고, 해당 행들의 레퍼런스를 반환합니다. 반환된 배열은 위의 예제처럼 모든 행을 반복 처리하는 데에 사용됩니다.ID 또는 제목(title) 설정을 통해 검색할 열도 지정가능합니다."
            +      ],
            +      "returns": "p5.TableRow 배열[]: <a href=\"#/p5.TableRow\">p5.TableRow</a>의 배열",
            +      "params": {
            +        "value": "문자열: 검색할 값",
            +        "column": "정수|문자열: 검색할 열의 ID 또는 제목"
            +      }
            +    },
            +    "matchRow": {
            +      "description": [
            +        "지정된 정규표현식과 매칭하는 테이블 행 중 1번째 행을 검색하고, 해당 행의 레퍼런스를 반환합니다. 반환된 배열은 모든 행을 반복 처리하는 데에 사용됩니다. ID 또는 제목(title) 설정을 통해 검색할 열도 지정가능합니다."
            +      ],
            +      "returns": "p5.TableRow: <a href=\"#/p5.TableRow\">p5.TableRow</a> 객체",
            +      "params": {
            +        "regexp": "문자열|RegExp: 검색할 정규표현식",
            +        "column": "문자열|정수: 검색할 열의 ID 또는 제목"
            +      }
            +    },
            +    "matchRows": {
            +      "description": [
            +        "지정된 정규표현식과 매칭하는 테이블 행들을 검색하고, 해당 행들의 배열을 반환합니다. 반환된 배열은 모든 행을 반복 처리하는 데에 사용됩니다. ID 또는 제목(title) 설정을 통해 검색할 열도 지정가능합니다."
            +      ],
            +      "returns": "p5.TableRow[]: <a href=\"#/p5.TableRow\">p5.TableRow</a>의 배열",
            +      "params": {
            +        "regexp": "문자열: 검색할 정규표현식",
            +        "column": "문자열|정수: (선택 사항) 검색할 열의 ID 또는 제목"
            +      }
            +    },
            +    "getColumn": {
            +      "description": [
            +        "특정 열의 모든 값들을 가져와 배열로 반환합니다. 열은 그 ID 또는 제목(title)으로 지정가능합니다."
            +      ],
            +      "returns": "배열: 열 값들의 배열",
            +      "params": {
            +        "column": "문자열|숫자: 반환할 열의 ID 또는 제목"
            +      }
            +    },
            +    "clearRows": {
            +      "description": [
            +        "테이블로부터 모든 행을 제거합니다. 모든 행들이 제거되어도 열과 열 제목은 유지됩니다."
            +      ]
            +    },
            +    "addColumn": {
            +      "description": [
            +        "addColumn()을 사용하여 p5.Table 객체에 새로운 열 데이터를 추가할 수 있습니다. 일반적으로 열 제목을 설정하여 이후 쉽게 참조되도록 합니다. (별도의 제목을 지정하지 않는 경우, 새로운 열의 제목은 null이 됩니다.)"
            +      ],
            +      "params": {
            +        "title": "문자열: (선택 사항) 해당 열의 제목"
            +      }
            +    },
            +    "getColumnCount": {
            +      "description": [
            +        "테이블의 전체 열 개수를 반환합니다."
            +      ],
            +      "returns": "정수: 테이블의 열 개수"
            +    },
            +    "getRowCount": {
            +      "description": [
            +        "테이블의 전체 행 개수를 반환합니다."
            +      ],
            +      "returns": "정수: 테이블의 행 개수"
            +    },
            +    "removeTokens": {
            +      "description": [
            +        "지정된 문자(또는 '토큰')을 제거합니다. 별도의 열을 지정하지 않는 경우, 모든 행과 열 속 값들이 처리됩니다. 열은 ID 또는 제목으로 참조가능합니다.",
            +        "If no column is specified, then the values in all columns and rows are processed. A specific column may be referenced by either its ID or title."
            +      ],
            +      "params": {
            +        "chars": "문자열: 제거할 문자들의 문자열",
            +        "column": "문자열|정수: (선택 사항) 열 ID (숫자) 또는 제목 (문자열)"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "문자열 테이블 값에서 스페이스나 탭과 같은 선행 및 후행 공백을 자릅니다. 별도의 열을 지정하지 않는 경우, 모든 행과 열 속 값들이 처리됩니다. 열은 ID 또는 제목으로 참조가능합니다."
            +      ],
            +      "params": {
            +        "column": "문자열|정수: (선택 사항) 열 ID (숫자) 또는 제목 (문자열)"
            +      }
            +    },
            +    "removeColumn": {
            +      "description": [
            +        "removeColumn()을 사용하여 테이블 객체로부터 특정 열을 제거합니다. 제거될 열은 그 제목(문자열) 또는 인덱스 값(정수)로 식별할 수 있습니다. removeColumn(0)은 1번째 열을, removeColumn(1)은 2번째 열을 제거합니다."
            +      ],
            +      "params": {
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "테이블 중 지정된 행과 열에 값을 저장합니다. 행은 ID로, 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "params": {
            +        "row": "정수: row ID",
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)",
            +        "value": "문자열|숫자: 저장할 값"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "테이블 중 지정된 행과 열에 실수(float)값을 저장합니다. 행은 ID로, 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "params": {
            +        "row": "정수: row ID",
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)",
            +        "value": "숫자: 저장할 값"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "테이블 중 지정된 행과 열에 문자열 값을 저장합니다. 행은 ID로, 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "params": {
            +        "row": "정수: row ID",
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)",
            +        "value": "문자열: 저장할 값"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "테이블 중 지정된 행과 열에 값을 받아옵니다. 행은 ID로, 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "returns": "문자열|숫자: 지정된 행과 열에 값",
            +      "params": {
            +        "row": "정수: 행 ID",
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "이블 중 지정된 행과 열에 실수(float)값을 받아옵니다. 행은 ID로, 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "returns": "숫자: 실수값",
            +      "params": {
            +        "row": "정수: 행 ID",
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "테이블 중 지정된 행과 열에 문자열 값을 받아옵니다. 행은 ID로, 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "returns": "문자열: 문자열 값",
            +      "params": {
            +        "row": "정수: 행 ID",
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)"
            +      }
            +    },
            +    "getObject": {
            +      "description": [
            +        "모든 테이블 데이터를 받아와 객체로 반환합니다. 열 이름이 전달될 경우, 각 행 객체는 해당 속성을 제목으로 저장합니다."
            +      ],
            +      "returns": "객체: 테이블 객체",
            +      "params": {
            +        "headerColumn": "문자열: (선택 사항) 행의 제목을 정할 열의 제목/이름"
            +      }
            +    },
            +    "getArray": {
            +      "description": [
            +        "모든 테이블 데이터를 받아와 다차원 배열로 반환합니다."
            +      ],
            +      "returns": "배열: 다차원 배열"
            +    }
            +  },
            +  "p5.TableRow": {
            +    "description": [
            +      "TableRow 객체는 테이블 중 열에 저장된 데이터 값들의 단일 행을 표현합니다.",
            +      "테이블 행은 정렬된 배열과 정렬되지 않은 JSON 객체를 모두 포함합니다.",
            +      ""
            +    ],
            +    "params": {
            +      "str": "문자열: (선택 사항) 구분 기호로 분리된 문자열값으로 행 채우기",
            +      "separator": "문자열: (선택 사항) 기본값은 쉼표 단위 구분(csv)"
            +    },
            +    "set": {
            +      "description": [
            +        "TableRow의 지정된 열에 값을 저장합니다. 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "params": {
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)",
            +        "value": "문자열|숫자: 저장될 값"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "TableRow의 지정된 열에 실수(float)값을 저장합니다. 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "params": {
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)",
            +        "value": "숫자|문자열: 저장될 값  as a Float"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "TableRow의 지정된 열에 문자열 값을 저장합니다. 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "params": {
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)",
            +        "value": "문자열|숫자|불리언|객체: 저장될 값"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "TableRow의 지정된 열로부터 값을 받습니다. 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "returns": "문자열|숫자:",
            +      "params": {
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "TableRow의 지정된 열로부터 실수(float)값을 받습니다. 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "returns": "숫자: 실수",
            +      "params": {
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "TableRow의 지정된 열로부터 문자열 값을 받습니다. 열은 ID 또는 제목으로 지정가능합니다."
            +      ],
            +      "returns": "문자열: String",
            +      "params": {
            +        "column": "문자열|정수: 열 ID (숫자) 또는 제목 (문자열)"
            +      }
            +    }
            +  },
            +  "p5.XML": {
            +    "description": [
            +      "XML은 XML 코드를 구문 분석할 수 있는 XML 객체의 표현입니다. <a href=\"#/p5/loadXML\">loadXML()</a>을 사용하여 외부 XML 파일을 불러와 XML 객체를 생성합니다."
            +    ],
            +    "getParent": {
            +      "description": [
            +        "요소 부모의 복사본을 가져와, 부모를 또다른 p5.XML 객체로 반환합니다."
            +      ],
            +      "returns": "p5.XML: 부모 객체"
            +    },
            +    "getName": {
            +      "description": [
            +        "요소의 전체 이름을 가져와 문자열로 반환합니다."
            +      ],
            +      "returns": "문자열: 요소의 이름"
            +    },
            +    "setName": {
            +      "description": [
            +        "문자열로 설정된 요소 이름을 지정합니다."
            +      ],
            +      "params": {
            +        "the": "문자열: 요소의 새 이름"
            +      }
            +    },
            +    "hasChildren": {
            +      "description": [
            +        "요소의 자식 유무 여부를 확인하고, 그 결과를 불리언으로 반환합니다."
            +      ],
            +      "returns": "불리언:"
            +    },
            +    "listChildren": {
            +      "description": [
            +        "모든 요소의 자식 이름을 가져와 그 값들을 문자열 배열로 반환합니다. 이는 각 자식 요소마다 getName()을 호출하는 것과 동일한 효과를 갖습니다."
            +      ],
            +      "returns": "문자열 배열[]: 요소의 자식요소의 배열"
            +    },
            +    "getChildren": {
            +      "description": [
            +        "요소의 모든 자식을 p5.XML 객체 배열로 반환합니다. 이름 매개변수를 지정할 경우, 해당 변수명과 일치하는 모든 자식을 반환합니다."
            +      ],
            +      "returns": "p5.XML 배열[]: 요소의 자식",
            +      "params": {
            +        "name": "문자열: (선택 사항) 요소의 이름"
            +      }
            +    },
            +    "getChild": {
            +      "description": [
            +        "이름 매개변수 또는 지정된 인덱스의 자식과 일치하는 요소의 1번째 자식을 반환합니다. 일치하는 자식을 찾지 못하는 경우, 'undefined'를 반환합니다."
            +      ],
            +      "returns": "p5.XML:",
            +      "params": {
            +        "name": "문자열|정수: 요소의 이름 또는 배열값"
            +      }
            +    },
            +    "addChild": {
            +      "description": [
            +        "요소에 새로운 자식을 추가합니다. 자식은 문자열로 지정될 수 있으며, 이는 새로운 태그명 또는 기존 p5.XML 객체에 대한 레퍼런스로서 사용할 수 있습니다. 새로 추가된 자식에 대한 레퍼런스는 p5.XML 객체로 반환됩니다."
            +      ],
            +      "params": {
            +        "node": "p5.XML: a <a href=\"#/p5.XML\">p5.XML</a> 자식요소가 될 요소 또는 객체"
            +      }
            +    },
            +    "removeChild": {
            +      "description": [
            +        "이름 또는 인덱스로 지정된 요소를 제거합니다"
            +      ],
            +      "params": {
            +        "name": "문자열|정수: 요소 이름 또는 배열값"
            +      }
            +    },
            +    "getAttributeCount": {
            +      "description": [
            +        "지정된 요소의 속성 개수를 숫자로 반환합니다."
            +      ],
            +      "returns": "정수: 요소의 속성 개수"
            +    },
            +    "listAttributes": {
            +      "description": [
            +        "지정된 요소의 모든 속성을 가져와 문자열 배열로 반환합니다."
            +      ],
            +      "returns": "문자열 배열[]: 속성의 이름들을 담은 문자열 배열"
            +    },
            +    "hasAttribute": {
            +      "description": [
            +        "요소가 지정된 속성을 갖는지 여부를 확인합니다."
            +      ],
            +      "returns": "불리언: 속성이 있을 시 참, 없을 시 거짓",
            +      "params": {
            +        "the": "문자열: 확인할 요소"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "요소의 속성값을 숫자로 반환합니다. 매개변수 defaultValue가 지정되고 속성이 존재하지 않으면 defaultValue를 반환합니다. 매개변수 defaultValue가 지정되지 않고 속성이 존재하지 않으면 값 0을 반환합니다."
            +      ],
            +      "returns": "숫자:",
            +      "params": {
            +        "name": "문자열: 속성의 부분적 이름",
            +        "defaultValue": "숫자: (선택 사항) 속성의 기본값"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "요소의 속성값을 문자열로 반환합니다. 매개변수 defaultValue가 지정되고 속성이 존재하지 않으면 'defaultValue'를 반환합니다. 매개변수 defaultValue가 지정되지 않고 속성이 존재하지 않으면 null을 반환합니다."
            +      ],
            +      "returns": "문자열:",
            +      "params": {
            +        "name": "문자열: 속성의 부분적 이름",
            +        "defaultValue": "숫자: (선택 사항) 속성의 기본값"
            +      }
            +    },
            +    "setAttribute": {
            +      "description": [
            +        "요소 속성의 내용을 설정합니다. 1번째 매개변수는 속성명을, 2번째 매개변수는 새로운 내용을 지정합니다."
            +      ],
            +      "params": {
            +        "name": "문자열: 속성의 부분적 이름",
            +        "value": "숫자|문자열|불리언: 속성의 값"
            +      }
            +    },
            +    "getContent": {
            +      "description": [
            +        "요소의 내용을 반환합니다. 매개변수 defaultValue가 지정되고 내용이 존재하지 않으면 'defaultValue'를 반환합니다. 매개변수 defaultValue가 지정되지 않고 내용이 존재하지 않으면 null을 반환합니다."
            +      ],
            +      "returns": "문자열: 요소의 내용",
            +      "params": {
            +        "defaultValue": "문자열: (선택 사항) 내용이 없을 시 반환될 문자열"
            +      }
            +    },
            +    "setContent": {
            +      "description": [
            +        "요소의 내용을 설정합니다."
            +      ],
            +      "params": {
            +        "text": "문자열: 새로운 내용"
            +      }
            +    },
            +    "serialize": {
            +      "description": [
            +        "요소를 문자열로 직렬화합니다. 요소의 내용을 http 요청으로 전송하거나 파일 저장을 준비할 때 사용됩니다."
            +      ],
            +      "returns": "문자열: 요소의 문자열 직렬화"
            +    }
            +  },
            +  "p5.Vector": {
            +    "description": [
            +      "2차원 및 3차원 벡터, 특히 유클리드 (기하학) 벡터를 설명하는 클래스입니다. 벡터는 크기와 방향을 모두 지닌 개체입니다. 하지만, 그 데이터 유형은 벡터의 성분(2D의 경우 x와 y, 3D의 경우 x, y, z)을 저장합니다. 크기와 방향은 각각 mag() 및 heading() 메소드를 통해 접근할 수 있습니다.",
            +      "p5.Vector는 위치, 속도, 가속을 다루는 수많은 p5.js 예제에서 사용됩니다. 예를 들어, 화면을 가로질러 움직이는 직사각형을 만들려면, 이 물체의 위치(원점에서 그 위치를 가리키는 벡터), 속도(단위 시간당 객체의 위치가 변하는 속도, 벡터로 표시), 그리고 가속도(단위 시간당 객체의 속도가 변하는 속도, 벡터로 표시)를 반드시 고려해야 합니다.",
            +      "벡터는 그룹화된 값들을 나타냅니다. 따라서, 전통적인 덧셈/곱셈 대신, p5.Vector 클래스 내부의 벡터 수학 메소드를 사용해서 계산해야 합니다."
            +    ],
            +    "params": {
            +      "x": "숫자: (선택 사항) 벡터의 x성분",
            +      "y": "숫자: (선택 사항) 벡터의 y성분",
            +      "z": "숫자: (선택 사항) 벡터의 z성분"
            +    },
            +    "x": {
            +      "description": [
            +        "벡터의 x성분"
            +      ]
            +    },
            +    "y": {
            +      "description": [
            +        "벡터의 y성분"
            +      ]
            +    },
            +    "z": {
            +      "description": [
            +        "벡터의 z성분"
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "두 세개의 개별 변수, p5.Vector 데이터, 또는 실수(float) 배열의 값들을 사용하여 벡터의 x, y, z 성분을 설정합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: (선택 사항) 벡터의 x 성분",
            +        "y": "숫자: (선택 사항) 벡터의 x 성분",
            +        "z": "숫자: (선택 사항) 벡터의 z 성분",
            +        "value": "p5.Vector|숫자 배열[]: 설정할 벡터"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "벡터의 복사본을 가져와 p5.Vector 객체를 반환합니다."
            +      ],
            +      "returns": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> 객체의 복사본"
            +    },
            +    "add": {
            +      "description": [
            +        "x, y, z 성분을 벡터에 더하거나, 한 벡터를 다른 벡터에 더하거나, 또는 2개의 독립 벡터를 더합니다. 2개의 독립 벡터를 더하는 메소드는 정적 메소드에 해당하며, p5.Vector를 반환합니다. 다른 메소드들은 벡터에 직접 작용합니다. 자세한 내용을 위해서 예제를 참고할 수 있습니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 추가할 벡터의 x 성분",
            +        "y": "숫자: (선택 사항) 추가할 벡터의 y 성분",
            +        "z": "숫자: (선택 사항) 추가할 벡터의 z 성분",
            +        "value": "p5.Vector|숫자 배열[]: 추가할 벡터",
            +        "v1": "p5.Vector: 추가할 <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: 추가할 <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "target": "p5.Vector: (선택 사항) 결과를 받을 벡터"
            +      }
            +    },
            +    "rem": {
            +      "description": [
            +        "한 벡터를 다른 벡터로 나눌 때의 나머지(remainder)를 구합니다. 자세한 내용을 위해서 예제를 참고할 수 있습니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 나누는 벡터의 x 성분",
            +        "y": "숫자: 나누는 벡터의 y 성분",
            +        "z": "숫자: 나누는 벡터의 z 성분",
            +        "value": "p5.Vector | 숫자 배열[]: 나누는 벡터",
            +        "v1": "p5.Vector: 나누어지는 <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: 나누는 <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "x, y, z성분을 벡터에서 빼거나, 한 벡터에서 다른 벡터를 빼거나, 또는 2개의 독립 벡터를 뺍니다. 2개의 독립 벡터를 빼는 메소드는 정적 메소드에 해당하며, p5.Vector를 반환합니다. 다른 메소드들은 벡터에 직접 작용합니다. 자세한 내용은 예제를 참고할 수 있습니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 뺄샘할 벡터의 x 성분",
            +        "y": "숫자: (선택 사항) 뺄샘할 벡터의 y 성분",
            +        "z": "숫자: (선택 사항) 뺄샘할 벡터의 z 성분",
            +        "value": "p5.Vector|숫자 배열[]: 뺄샘할 벡터",
            +        "v1": "p5.Vector: 뺄샘할 <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: 뺄샘할 <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "target": "p5.Vector: (선택 사항) 결과를 받을 벡터"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "벡터에 스칼라를 곱합니다. 정적 메소드인 경우 새로운 p5.Vector를 생성하는 반면, 정적 메소드가 아닌 경우 벡터에 직접 작용합니다. 자세한 내용을 위해서 예제를 참고할 수 있습니다."
            +      ],
            +      "params": {
            +        "n": "숫자: 벡터로 곱할 숫자",
            +        "x": "숫자: 벡터의 x 성분에 곱할 숫자",
            +        "y": "숫자: 벡터의 y 성분에 곱할 숫자",
            +        "z": "숫자: (선택 사항) 벡터의 z 성분에 곱할 숫자",
            +        "arr": "숫자 배열[]: 벡터의 성분들에 곱할 숫자 배열",
            +        "v": "p5.Vector: 원본 벡터의 성분들에 곱할 벡터",
            +        "target": "p5.Vector: (선택 사항) 결과를 받을 벡터",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "벡터를 스칼라로 나눕니다. 정적 메소드인 경우 새로운 p5.Vector를 생성하는 반면, 정적 메소드가 아닌 경우 벡터에 직접 작용합니다. 자세한 내용을 위해서 예제를 참고할 수 있습니다."
            +      ],
            +      "params": {
            +        "n": "숫자: 벡터를 나눌 숫자",
            +        "x": "숫자: 벡터의 x 성분에 나눌 숫자",
            +        "y": "숫자: 벡터의 y 성분에 나눌 숫자",
            +        "z": "숫자: (선택 사항) 벡터의 z 성분에 나눌 숫자",
            +        "arr": "숫자 배열[]: 벡터의 성분들을 나눌 숫자",
            +        "v": "p5.Vector: 원본 벡터의 성분들을 나눌 벡터",
            +        "target": "p5.Vector: (선택 사항) 결과를 받을 벡터",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "벡터의 크기(길이)를 계산하고 그 결과를 실수(float)으로 반환합니다. (이는 수식 sqrt(x*x + y*y + z*z)과도 같습니다.)"
            +      ],
            +      "returns": "숫자: 벡터의 크기(길이)",
            +      "params": {
            +        "vecT": "p5.Vector: 크기를 찾을 벡터"
            +      }
            +    },
            +    "magSq": {
            +      "description": [
            +        "벡터의 제곱 크기를 계산하고 그 결과를 실수(float)로 반환합니다. (이는 수식 sqrt(x*x + y*y + z*z)과도 같습니다.) 벡터를 비교하는 등의 경우에서 실제 길이를 포함하지 않으면 더 빠르게 계산됩니다."
            +      ],
            +      "returns": "숫자: 벡터 크기의 제곱"
            +    },
            +    "dot": {
            +      "description": [
            +        "두 벡터의 내적을 계산합니다. 2개의 독립 벡터의 내적을 계산하는 메소드는 정적 메소드에 해당합니다. 자세한 내용을 위해서 예제를 참고할 수 있습니다."
            +      ],
            +      "returns": "숫자: the dot product",
            +      "params": {
            +        "x": "숫자: 벡터의 x 성분",
            +        "y": "숫자: (선택 사항) 벡터의 y 성분",
            +        "z": "숫자: (선택 사항) 벡터의 z 성분",
            +        "value": "p5.Vector: 벡터의 내적 값 또는 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +        "v1": "p5.Vector: 첫 번째 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +        "v2": "p5.Vector: 두 번째 <a href=\"#/p5.Vector\">p5.Vector</a> 객체"
            +      }
            +    },
            +    "cross": {
            +      "description": [
            +        "두 벡터의 외적으로 구성된 벡터를 계산하고 반환합니다. 정적 및 비정적 메소드 모두 새로운 p5.Vector를 반환합니다. 자세한 내용을 위해서 예제를 참고할 수 있습니다."
            +      ],
            +      "returns": "p5.Vector: 외적을 가진 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +      "params": {
            +        "v": "p5.Vector: 외적을 구할 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +        "v1": "p5.Vector: 첫 번째 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +        "v2": "p5.Vector: 두 번째 <a href=\"#/p5.Vector\">p5.Vector</a> 객체"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "두 점 사이의 유클리드 거리를 계산합니다 (점을 벡터 객체로 간주)."
            +      ],
            +      "returns": "숫자: 두 점 사이의 거리",
            +      "params": {
            +        "v": "p5.Vector: x, y, z 좌표를 가진 <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "p5.Vector: 첫 번째 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +        "v2": "p5.Vector: 두 번째 <a href=\"#/p5.Vector\">p5.Vector</a> 객체"
            +      }
            +    },
            +    "normalize": {
            +      "description": [
            +        "벡터를 길이 1로 정규화합니다. (단위 벡터로 만듭니다.)"
            +      ],
            +      "returns": "p5.Vector: 정규화된 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +      "params": {
            +        "v": "p5.Vector: 정규화할 벡터",
            +        "target": "p5.Vector: (선택 사항) 결과를 받을 벡터"
            +      }
            +    },
            +    "limit": {
            +      "description": [
            +        "벡터의 크기를 매개변수 <b>max</b>의 값으로 제한합니다."
            +      ],
            +      "params": {
            +        "max": "숫자: 벡터의 최댓값"
            +      }
            +    },
            +    "setMag": {
            +      "description": [
            +        "벡터의 크기를 매개변수 <b>len</b>의 값으로 제한합니다."
            +      ],
            +      "params": {
            +        "len": "숫자: 벡터의 새로운 크리"
            +      }
            +    },
            +    "heading": {
            +      "description": [
            +        "벡터의 회전 각도를 계산합니다. (2D 벡터만 해당)"
            +      ],
            +      "returns": "숫자: 회전 각도"
            +    },
            +    "setHeading": {
            +      "description": [
            +        "벡터를 회전시킵니다 (2D 벡터만 해당. 벡터의 크기는 유지됩니다."
            +      ],
            +      "params": {
            +        "angle": "숫자: 회전의 각도"
            +      }
            +    },
            +    "rotate": {
            +      "description": [
            +        "벡터를 특정 각도로 회전하되 (2D 벡터만 해당), 크기는 동일하게 유지합니다."
            +      ],
            +      "params": {
            +        "angle": "숫자: 회전의 각도",
            +        "v": "p5.Vector",
            +        "target": "p5.Vector: (선택 사항) 결과를 받을 벡터"
            +      }
            +    },
            +    "angleBetween": {
            +      "description": [
            +        "두 벡터 사이의 각도 (라디안 단위)를 계산하고 반환합니다."
            +      ],
            +      "returns": "숫자: 벡터 사이의 각도 (라디안 단위)",
            +      "params": {
            +        "value": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> 객체의 x, y, z 성분"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "한 벡터와 다른 벡터를 선형적으로 보간합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 벡터의 x 성분",
            +        "y": "숫자: 벡터의 y 성분",
            +        "z": "숫자: 벡터의 z 성분",
            +        "amt": "숫자: 보간의 정도; 0.0 (구 벡터)과 1.0 (신 벡터) 사이의 값. 0.9은 새로운 벡터에 가까운 값입니다. 0.5은 두 벡터의 정중앙입니다.",
            +        "v": "p5.Vector: 선형적 보간을 할 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +        "v1": "p5.Vector",
            +        "v2": "p5.Vector",
            +        "target": "p5.Vector: (선택 사항) 결과를 받을 벡터"
            +      }
            +    },
            +    "reflect": {
            +      "description": [
            +        "2D 선 또는 3D 평면의 법선에 들어오는 벡터를 반영합니다. 이 메소드는 벡터에 직접 작용합니다."
            +      ],
            +      "params": {
            +        "surfaceNormal": "p5.Vector: 반영 법선이 될 <a href=\"#/p5.Vector\">p5.Vector</a> 객체가 정규화됩니다."
            +      }
            +    },
            +    "array": {
            +      "description": [
            +        "벡터의 표현을 실수 배열로 반환합니다. 이는 일시적으로만 사용됩니다. 다른 경우에도, p5.Vector.copy() 메소드를 통해 배열에 내용을 복사해야 합니다."
            +      ],
            +      "returns": "숫자 배열[]: 3 가지 값을 가진 배열"
            +    },
            +    "equals": {
            +      "description": [
            +        "p5.Vector에 대한 평등 검사"
            +      ],
            +      "returns": "불리언: 벡터의 평등함 여부",
            +      "params": {
            +        "x": "숫자: (선택 사항) 벡터의 x 성분",
            +        "y": "숫자: (선택 사항) 벡터의 y 성분",
            +        "z": "숫자: (선택 사항) 벡터의 z 성분",
            +        "value": "p5.Vector|배열: 비교할 벡터"
            +      }
            +    },
            +    "fromAngle": {
            +      "description": [
            +        "특정 각도에서 새로운 2D 벡터를 생성합니다."
            +      ],
            +      "returns": "p5.Vector: 새로운 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +      "params": {
            +        "angle": "숫자: 원하는 라디안 단위의 각도 (<a href=\"#/p5/angleMode\">angleMode</a>에 영향받지 않은 가도)",
            +        "length": "숫자: (선택 사항) 새로운 벡터의 크리 (기본값은 1)"
            +      }
            +    },
            +    "fromAngles": {
            +      "description": [
            +        "구면각 (spherical angle)의 쌍에서 새로운 3D 벡터를 생성합니다."
            +      ],
            +      "returns": "p5.Vector: 새로운 <a href=\"#/p5.Vector\">p5.Vector</a> 객체",
            +      "params": {
            +        "theta": "라디안 단위, 극각 (0는 위로 향함)",
            +        "phi": "숫자: 라디안 단위, 방위각 (0은 화면 바깥에 있음)",
            +        "length": "숫자: (선택 사항) 새로운 벡터의 크리 (기본값은 1)"
            +      }
            +    },
            +    "random2D": {
            +      "description": [
            +        "임의의 각도에서 새로운 2D 단위 벡터를 생성합니다."
            +      ],
            +      "returns": "p5.Vector: 새로운 <a href=\"#/p5.Vector\">p5.Vector</a> 객체"
            +    },
            +    "random3D": {
            +      "description": [
            +        "새로운 임의의 3D 단위 벡터를 생성합니다."
            +      ],
            +      "returns": "p5.Vector: 새로운 <a href=\"#/p5.Vector\">p5.Vector</a> 객체"
            +    }
            +  },
            +  "p5.Font": {
            +    "description": [
            +      "폰트 조정을 위한 기본 클래스"
            +    ],
            +    "params": {
            +      "pInst": "P5: (선택 사항) p5 인스턴스 포인터"
            +    },
            +    "font": {
            +      "description": [
            +        "기본 개방형 글꼴 구현"
            +      ]
            +    },
            +    "textBounds": {
            +      "description": [
            +        "이 폰트로 지정된 텍스트 문자열에 대한 바운딩 박스를 반환합니다. (현재 텍스트 한 줄씩만 지원합니다.)"
            +      ],
            +      "returns": "객체: x, y, w, h의 속성을 가진 직사각형의 객체",
            +      "params": {
            +        "line": "문자열: 텍스트 한 줄",
            +        "x": "숫자: x 위치",
            +        "y": "숫자: y 위치",
            +        "fontSize": "숫자: (선택 사항) 사용할 폰트의 크기. 기본값은 12.",
            +        "options": "객체: (선택 사항) OTF (OpenType Font) 파일의 설정 옵션. OpenType 폰트는 정렬과 기준 선 (baseline) 옵션이 있습니다. 기본값은 'LEFT'와 'alphabetic'입니다."
            +      }
            +    },
            +    "textToPoints": {
            +      "description": [
            +        "지정된 텍스트 경로를 따르는 점들의 배열을 계산합니다."
            +      ],
            +      "returns": "배열: an array of points, each with x, y, alpha (the path angle)",
            +      "params": {
            +        "txt": "문자열: 텍스트 한 줄",
            +        "x": "숫자: x 위치",
            +        "y": "숫자: y 위치",
            +        "fontSize": "숫자: (선택 사항) 사용할 폰트의 크기. 기본값은 12.",
            +        "options": "객체: (선택 사항) 객체 옵션으로 다음의 값을 가질 수 있습니다: sampleFactor - the ratio of path-length to number of samples (default=.1); higher values yield more points and are therefore more precise simplifyThreshold - if set to a non-zero value, collinear points will be be removed from the polygon; the value represents the threshold angle to use when determining whether two edges are collinear"
            +      }
            +    }
            +  },
            +  "p5.Camera": {
            +    "description": [
            +      "p5의 <a href = 'https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5'>WebGL 모드</a>용 카메라를 위한 클래스입니다. 3D씬 렌더링에 필요한 카메라 위치, 방향, 투영 정보 등을 포함합니다.",
            +      "createCamera()로 새로운 p5.Camera 객체를 생성하고, 아래의 메소드들을 통해 이를 제어할 수 있습니다. 이러한 방식으로 생성된 카메라는, 여타 메소드들을 통해 변경하지 않는 한, 화면에 기본값으로 설정된 위치 및 투시 투영법을 사용합니다. 여러 대의 카메라 생성 또한 가능한데, 이 경우 setCamera() 메소드로 현재 카메라를 설정할 수 있습니다.",
            +      "참고: 아래의 메소드들은 다음 2개의 좌표계에서 작동합니다: 월드 좌표계는 X,Y,Z축 상의 원점에 대한 위치를 나타내는 반면, 로컬 좌표계는 카메라 시점에서의 위치(좌-우, 위-아래, 앞-뒤)를 나타냅니다. move() 메소드는 카메라의 자체 축을 따라 움직이는 반면, setPosition()은 월드 공간에서의 카메라의 위치를 설정합니다.",
            +      "카메라 객체의 속성인 <code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code> 은 카메라 위치, 화면방향, 투영을 지정하며, <a href=\"#/p5/createCamera\">createCamera()</a> 함수를 통해 형성된 카메라 객체에도 찾을 수 있습니다."
            +    ],
            +    "params": {
            +      "rendererGL": "RendererGL: WebGL 렌더러의 인스턴스"
            +    },
            +    "eyeX": {
            +      "description": [
            +        "x 축에 있는 카메라 위치 값"
            +      ]
            +    },
            +    "eyeY": {
            +      "description": [
            +        "y 축에 있는 카메라 위치 값"
            +      ]
            +    },
            +    "eyeZ": {
            +      "description": [
            +        "z 축에 있는 카메라 위치 값"
            +      ]
            +    },
            +    "centerX": {
            +      "description": [
            +        "스케치의 중심을 표시하는 x 좌표"
            +      ]
            +    },
            +    "centerY": {
            +      "description": [
            +        "스케치의 중심을 표시하는 y 좌표"
            +      ]
            +    },
            +    "centerZ": {
            +      "description": [
            +        "스케치의 중심을 표시하는 z 좌표"
            +      ]
            +    },
            +    "upX": {
            +      "description": [
            +        "카메라의 '위' 방향을 표시하는 x 구성요소"
            +      ]
            +    },
            +    "upY": {
            +      "description": [
            +        "카메라의 '위' 방향을 표시하는 y 구성요소"
            +      ]
            +    },
            +    "upZ": {
            +      "description": [
            +        "카메라의 '위' 방향을 표시하는 z 구성요소"
            +      ]
            +    },
            +    "perspective": {
            +      "description": [
            +        "p5.Camera 객체의 투시 투영법을 설정하고, perspective() 구문에 따라 해당 투영법의 매개변수를 설정합니다."
            +      ]
            +    },
            +    "ortho": {
            +      "description": [
            +        "p5.Camera 객체의 직교 투영법을 설정하고, ortho() 구문에 따라 해당 투영법의 매개변수를 설정합니다."
            +      ]
            +    },
            +    "frustum": {
            +      "description": [
            +        "주어진 매개변수로 퍼스펙티브 매트릭스 (perspective matrix)를 만듧니다.",
            +        "frustum은 피라미드 모양의 상단을 바닥과 평행한 면에서 잘라낸 기하학적 모양입니다. 이 피라미드의 위에 보는 사람의 눈이 있다 가정하면서 여섯 면은 장면의 특정 부분만 렌더링하는데에 쓰이는 가상의 면인 clipping plane입니다. 3D로 렌더링 할 시, 이 여섯 면 안에 있는 물체는 보이며, 그 바깥에 있는 물체는 보이지 않습니다. 이 <https://docs.unity3d.com/kr/530/Manual/UnderstandingFrustum.html\">링크</a>를 통해 더 자세히 알 수 있습니다.",
            +        "frustum을 설정하면 렌더링되는 장면이 달라집니다. 이는 간단하게 <a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a> 함수를 통해 이룰 수도 있습니다."
            +      ],
            +      "params": {
            +        "left": "숫자: (선택 사항) 카메라 frustum의 왼쪽 면",
            +        "right": "숫자: (선택 사항) 카메라 frustum의 오른쪽 면",
            +        "bottom": "숫자: (선택 사항) 카메라 frustum의 밑 면",
            +        "top": "숫자: (선택 사항) 카메라 frustum의 위 면",
            +        "near": "숫자: (선택 사항) 카메라 frustum의 근거리 면",
            +        "far": "숫자: (선택 사항) 카메라 frustum의 장거리 면"
            +      }
            +    },
            +    "pan": {
            +      "description": [
            +        "패닝은 카메라 화면을 좌우로 회전합니다."
            +      ],
            +      "params": {
            +        "angle": "숫자: 현재 <a href=\"#/p5/angleMode\">angleMode</a> 단위로 카메라를 회전할 정도. 0을 초과하는 숫자는 카메라를 시계방향(왼쪽)으로 회전시킵니다."
            +      }
            +    },
            +    "tilt": {
            +      "description": [
            +        "틸트는 카메라 화면을 상하로 회전합니다."
            +      ],
            +      "params": {
            +        "angle": "숫자: 현재 <a href=\"#/p5/angleMode\">angleMode</a> 단위로 카메라를 회전할 정도. 0을 초과하는 숫자는 카메라를 시계방향(왼쪽)으로 회전시킵니다."
            +      }
            +    },
            +    "lookAt": {
            +      "description": [
            +        "월드 공간 위치에서 보도록 카메라 방향을 조정합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 월드 공간 속 한 점의 x 위치",
            +        "y": "숫자: 월드 공간 속 한 점의 y 위치",
            +        "z": "숫자: 월드 공간 속 한 점의 z 위치"
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "카메라의 위치와 방향을 설정합니다. p5.Camera 객체에 camera()를 호출하는 것과 동일한 효과를 갖습니다."
            +      ]
            +    },
            +    "move": {
            +      "description": [
            +        "현재 카메라 방향을 유지하면서 그 로컬축을 따라 이동합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 카메라의 좌우축에서 움직일 정도",
            +        "y": "숫자: 카메라의 상하축에서 움직일 정도",
            +        "z": "숫자: 카메라의 앞뒤축에서 움직일 정도"
            +      }
            +    },
            +    "setPosition": {
            +      "description": [
            +        "현재 카메라 방향을 유지하면서 카메라의 위치를 월드 공간에서의 위치로 설정합니다."
            +      ],
            +      "params": {
            +        "x": "숫자: 월드 공간 속 한 점의 x 위치",
            +        "y": "숫자: 월드 공간 속 한 점의 y 위치",
            +        "z": "숫자: 월드 공간 속 한 점의 z 위치"
            +      }
            +    }
            +  },
            +  "p5.Geometry": {
            +    "description": [
            +      "p5 기하 클래스"
            +    ],
            +    "params": {
            +      "detailX": "정수: (선택 사항) 수평 표면 위의 꼭짓점 개수",
            +      "detailY": "정수: (선택 사항) 수직 표면 위의 꼭짓점 개수",
            +      "callback": "함수: 객체를 인스턴스화할 때 호출할 함수"
            +    },
            +    "computeFaces": {
            +      "description": [
            +        "꼭짓점 기준으로 도형의 면들을 생성합니다."
            +      ]
            +    },
            +    "computeNormals": {
            +      "description": [
            +        "꼭짓점 당 부드러운 법선을 각 면의 평균으로서 만듧니다."
            +      ]
            +    },
            +    "averageNormals": {
            +      "description": [
            +        "꼭짓점 법선의 평균을 구합니다. 곡면에 사용됩니다."
            +      ]
            +    },
            +    "averagePoleNormals": {
            +      "description": [
            +        "극점 법선의 평균을 구합니다. 구형의 기초 조형에 사용됩니다."
            +      ]
            +    },
            +    "normalize": {
            +      "description": [
            +        "모든 꼭짓점이 -100부터 100사이의 중심에 오도록 수정합니다."
            +      ]
            +    }
            +  },
            +  "p5.Shader": {
            +    "description": [
            +      "WebGL 모드를 위한 셰이더 클래스"
            +    ],
            +    "params": {
            +      "renderer": "p5.RendererGL: 새로운 p5.Shader에 GL 문맥을 제공하는 p5.RendererGL 인스턴스",
            +      "vertSrc": "문자열: 버텍스 셰이더의 소스 코드 (문자열 형식)",
            +      "fragSrc": "문자열: 프래그먼트 셰이더의 소스 코드 (문자열 형식)"
            +    },
            +    "setUniform": {
            +      "description": [
            +        "gl.uniform 함수들을 감싸는 래퍼. uniform (셰이더의 변수)의 데이터를 셰이더에 저장하면서 타입 검증을 한 후 알맞은 함수를 호출합니다."
            +      ],
            +      "params": {
            +        "uniformName": "문자열: 셰이더 프로그램에 있는 uniform 속성의 이름",
            +        "data": "객체|숫자|불리언|숫자 배열[]: 선택한 uniform과 연관시킬 데이터; 타입은 다양합니다 (숫자 하나, 배열, 매트릭스, 또는 텍스쳐/샘플러 참고자료)."
            +      }
            +    }
            +  },
            +  "p5.sound": {},
            +  "p5.SoundFile": {
            +    "description": [
            +      "SoundFile object with a path to a file.",
            +      "The p5.SoundFile may not be available immediately because it loads the file information asynchronously.",
            +      "To do something with the sound as soon as it loads pass the name of a function as the second parameter.",
            +      "Only one file path is required. However, audio file formats (i.e. mp3, ogg, wav and m4a/aac) are not supported by all web browsers. If you want to ensure compatibility, instead of a single file path, you may include an Array of filepaths, and the browser will choose a format that works."
            +    ],
            +    "params": {
            +      "path": "문자열|Array: path to a sound file (String). Optionally,  you may include multiple file formats in  an array. Alternately, accepts an object  from the HTML5 File API, or a p5.File.",
            +      "successCallback": "함수: (선택 사항) Name of a function to call once file loads",
            +      "errorCallback": "함수: (선택 사항) Name of a function to call if file fails to  load. This function will receive an error or  XMLHttpRequest object with information  about what went wrong.",
            +      "whileLoadingCallback": "함수: (선택 사항) Name of a function to call while file  is loading. That function will  receive progress of the request to  load the sound file  (between 0 and 1) as its first  parameter. This progress  does not account for the additional  time needed to decode the audio data."
            +    },
            +    "isLoaded": {
            +      "description": [
            +        "Returns true if the sound file finished loading successfully."
            +      ],
            +      "returns": "불리언: "
            +    },
            +    "play": {
            +      "description": [
            +        "Play the p5.SoundFile"
            +      ],
            +      "params": {
            +        "startTime": "숫자: (선택 사항) (optional) schedule playback to start (in seconds from now).",
            +        "rate": "숫자: (선택 사항) (optional) playback rate",
            +        "amp": "숫자: (선택 사항) (optional) amplitude (volume)  of playback",
            +        "cueStart": "숫자: (선택 사항) (optional) cue start time in seconds",
            +        "duration": "숫자: (선택 사항) (optional) duration of playback in seconds"
            +      }
            +    },
            +    "playMode": {
            +      "description": [
            +        "p5.SoundFile has two play modes: <code>restart</code> and <code>sustain</code>. Play Mode determines what happens to a p5.SoundFile if it is triggered while in the middle of playback. In sustain mode, playback will continue simultaneous to the new playback. In restart mode, play() will stop playback and start over. With untilDone, a sound will play only if it's not already playing. Sustain is the default mode."
            +      ],
            +      "params": {
            +        "str": "문자열: 'restart' or 'sustain' or 'untilDone'"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses a file that is currently playing. If the file is not playing, then nothing will happen.",
            +        "After pausing, .play() will resume from the paused position. If p5.SoundFile had been set to loop before it was paused, it will continue to loop after it is unpaused with .play()."
            +      ],
            +      "params": {
            +        "startTime": "숫자: (선택 사항) (optional) schedule event to occur  seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop the p5.SoundFile. Accepts optional parameters to set the playback rate, playback volume, loopStart, loopEnd."
            +      ],
            +      "params": {
            +        "startTime": "숫자: (선택 사항) (optional) schedule event to occur  seconds from now",
            +        "rate": "숫자: (선택 사항) (optional) playback rate",
            +        "amp": "숫자: (선택 사항) (optional) playback volume",
            +        "cueLoopStart": "숫자: (선택 사항) (optional) startTime in seconds",
            +        "duration": "숫자: (선택 사항) (optional) loop duration in seconds"
            +      }
            +    },
            +    "setLoop": {
            +      "description": [
            +        "Set a p5.SoundFile's looping flag to true or false. If the sound is currently playing, this change will take effect when it reaches the end of the current playback."
            +      ],
            +      "params": {
            +        "Boolean": "불리언: set looping to true or false"
            +      }
            +    },
            +    "isLooping": {
            +      "description": [
            +        "Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not."
            +      ],
            +      "returns": "불리언: "
            +    },
            +    "isPlaying": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is playing, false if not (i.e. paused or stopped)."
            +      ],
            +      "returns": "불리언: "
            +    },
            +    "isPaused": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is paused, false if not (i.e. playing or stopped)."
            +      ],
            +      "returns": "불리언: "
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop soundfile playback."
            +      ],
            +      "params": {
            +        "startTime": "숫자: (선택 사항) (optional) schedule event to occur  in seconds from now"
            +      }
            +    },
            +    "pan": {
            +      "description": [
            +        "Set the stereo panning of a p5.sound object to a floating point number between -1.0 (left) and 1.0 (right). Default is 0.0 (center)."
            +      ],
            +      "params": {
            +        "panValue": "숫자: (선택 사항) Set the stereo panner",
            +        "timeFromNow": "숫자: (선택 사항) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current stereo pan position (-1.0 to 1.0)"
            +      ],
            +      "returns": "숫자: Returns the stereo pan setting of the Oscillator  as a number between -1.0 (left) and 1.0 (right).  0.0 is center and default."
            +    },
            +    "rate": {
            +      "description": [
            +        "Set the playback rate of a sound file. Will change the speed and the pitch. Values less than zero will reverse the audio buffer."
            +      ],
            +      "params": {
            +        "playbackRate": "숫자: (선택 사항) Set the playback rate. 1.0 is normal,  .5 is half-speed, 2.0 is twice as fast.  Values less than zero play backwards."
            +      }
            +    },
            +    "setVolume": {
            +      "description": [
            +        "Multiply the output volume (amplitude) of a sound file between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal."
            +      ],
            +      "params": {
            +        "volume": "숫자|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "숫자: (선택 사항) Fade for t seconds",
            +        "timeFromNow": "숫자: (선택 사항) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of a sound file in seconds."
            +      ],
            +      "returns": "숫자: The duration of the soundFile in seconds."
            +    },
            +    "currentTime": {
            +      "description": [
            +        "Return the current position of the p5.SoundFile playhead, in seconds. Time is relative to the normal buffer direction, so if <code>reverseBuffer</code> has been called, currentTime will count backwards."
            +      ],
            +      "returns": "숫자: currentTime of the soundFile in seconds."
            +    },
            +    "jump": {
            +      "description": [
            +        "Move the playhead of a soundfile that is currently playing to a new position and a new duration, in seconds. If none are given, will reset the file to play entire duration from start to finish. To set the position of a soundfile that is not currently playing, use the <code>play</code> or <code>loop</code> methods."
            +      ],
            +      "params": {
            +        "cueTime": "숫자: cueTime of the soundFile in seconds.",
            +        "duration": "숫자: duration in seconds."
            +      }
            +    },
            +    "channels": {
            +      "description": [
            +        "Return the number of channels in a sound file. For example, Mono = 1, Stereo = 2."
            +      ],
            +      "returns": "숫자: [channels]"
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Return the sample rate of the sound file."
            +      ],
            +      "returns": "숫자: [sampleRate]"
            +    },
            +    "frames": {
            +      "description": [
            +        "Return the number of samples in a sound file. Equal to sampleRate * duration."
            +      ],
            +      "returns": "숫자: [sampleCount]"
            +    },
            +    "getPeaks": {
            +      "description": [
            +        "Returns an array of amplitude peaks in a p5.SoundFile that can be used to draw a static waveform. Scans through the p5.SoundFile's audio buffer to find the greatest amplitudes. Accepts one parameter, 'length', which determines size of the array. Larger arrays result in more precise waveform visualizations.",
            +        "Inspired by Wavesurfer.js."
            +      ],
            +      "returns": "Float32Array: Array of peaks.",
            +      "params": {
            +        "length": "숫자: (선택 사항) length is the size of the returned array.  Larger length results in more precision.  Defaults to 5*width of the browser window."
            +      }
            +    },
            +    "reverseBuffer": {
            +      "description": [
            +        "Reverses the p5.SoundFile's buffer source. Playback must be handled separately (see example)."
            +      ]
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the soundfile reaches the end of a buffer. If the soundfile is playing through once, this will be called when it ends. If it is looping, it will be called when stop is called."
            +      ],
            +      "params": {
            +        "callback": "함수: function to call when the  soundfile has ended."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connects the output of a p5sound object to input of another p5.sound object. For example, you may connect a p5.SoundFile to an FFT or an Effect. If no parameter is given, it will connect to the master output. Most p5sound objects connect to the master output when they are created."
            +      ],
            +      "params": {
            +        "object": "객체: (선택 사항) Audio object that accepts an input"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnects the output of this p5sound object."
            +      ]
            +    },
            +    "setPath": {
            +      "description": [
            +        "Reset the source for this SoundFile to a new path (URL)."
            +      ],
            +      "params": {
            +        "path": "문자열: path to audio file",
            +        "callback": "함수: Callback"
            +      }
            +    },
            +    "setBuffer": {
            +      "description": [
            +        "Replace the current Audio Buffer with a new Buffer."
            +      ],
            +      "params": {
            +        "buf": "배열: Array of Float32 Array(s). 2 Float32 Arrays  will create a stereo source. 1 will create  a mono source."
            +      }
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point.",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback.",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "숫자: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "숫자: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "함수: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "객체: (선택 사항) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "숫자: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ]
            +    },
            +    "save": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. To upload a file to a server, see <a href=\"/docs/reference/#/p5.SoundFile/getBlob\">getBlob</a>"
            +      ],
            +      "params": {
            +        "fileName": "문자열: (선택 사항) name of the resulting .wav file."
            +      }
            +    },
            +    "getBlob": {
            +      "description": [
            +        "This method is useful for sending a SoundFile to a server. It returns the .wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at MDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\". A Blob is a file-like data object that can be uploaded to a server with an <a href=\"/docs/reference/#/p5/httpDo\">http</a> request. We'll use the <code>httpDo</code> options object to send a POST request with some specific options: we encode the request as <code>multipart/form-data</code>, and attach the blob as one of the form values using <code>FormData</code>."
            +      ],
            +      "returns": "Blob: A file-like data object"
            +    }
            +  },
            +  "p5.Amplitude": {
            +    "description": [
            +      "Amplitude measures volume between 0.0 and 1.0. Listens to all p5sound by default, or use setInput() to listen to a specific sound source. Accepts an optional smoothing value, which defaults to 0."
            +    ],
            +    "params": {
            +      "smoothing": "숫자: (선택 사항) between 0.0 and .999 to smooth  amplitude readings (defaults to 0)"
            +    },
            +    "setInput": {
            +      "description": [
            +        "Connects to the p5sound instance (master output) by default. Optionally, you can pass in a specific source (i.e. a soundfile)."
            +      ],
            +      "params": {
            +        "snd": "SoundObject|undefined: (선택 사항) set the sound source  (optional, defaults to  master output)",
            +        "smoothing": "숫자|undefined: (선택 사항) a range between 0.0 and 1.0  to smooth amplitude readings"
            +      }
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Returns a single Amplitude reading at the moment it is called. For continuous readings, run in the draw loop."
            +      ],
            +      "returns": "숫자: Amplitude as a number between 0.0 and 1.0",
            +      "params": {
            +        "channel": "숫자: (선택 사항) Optionally return only channel 0 (left) or 1 (right)"
            +      }
            +    },
            +    "toggleNormalize": {
            +      "description": [
            +        "Determines whether the results of Amplitude.process() will be Normalized. To normalize, Amplitude finds the difference the loudest reading it has processed and the maximum amplitude of 1.0. Amplitude adds this difference to all values to produce results that will reliably map between 0.0 and 1.0. However, if a louder moment occurs, the amount that Normalize adds to all the values will change. Accepts an optional boolean parameter (true or false). Normalizing is off by default."
            +      ],
            +      "params": {
            +        "boolean": "불리언: (선택 사항) set normalize to true (1) or false (0)"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth Amplitude analysis by averaging with the last analysis frame. Off by default."
            +      ],
            +      "params": {
            +        "set": "숫자: smoothing from 0.0 <= 1"
            +      }
            +    }
            +  },
            +  "p5.FFT": {
            +    "description": [
            +      "FFT (Fast Fourier Transform) is an analysis algorithm that isolates individual <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\"> audio frequencies</a> within a waveform.",
            +      "Once instantiated, a p5.FFT object can return an array based on two types of analyses: • <code>FFT.waveform()</code> computes amplitude values along the time domain. The array indices correspond to samples across a brief moment in time. Each value represents amplitude of the waveform at that sample of time. • <code>FFT.analyze() </code> computes amplitude values along the frequency domain. The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Use with <code>getEnergy()</code> to measure amplitude at specific frequencies, or within a range of frequencies.",
            +      "FFT analyzes a very short snapshot of sound called a sample buffer. It returns an array of amplitude measurements, referred to as <code>bins</code>. The array is 1024 bins long by default. You can change the bin array length, but it must be a power of 2 between 16 and 1024 in order for the FFT algorithm to function correctly. The actual size of the FFT buffer is twice the number of bins, so given a standard sample rate, the buffer is 2048/44100 seconds long."
            +    ],
            +    "params": {
            +      "smoothing": "숫자: (선택 사항) Smooth results of Freq Spectrum.  0.0 < smoothing < 1.0.  Defaults to 0.8.",
            +      "bins": "숫자: (선택 사항) Length of resulting array.  Must be a power of two between  16 and 1024. Defaults to 1024."
            +    },
            +    "setInput": {
            +      "description": [
            +        "Set the input source for the FFT analysis. If no source is provided, FFT will analyze all sound in the sketch."
            +      ],
            +      "params": {
            +        "source": "객체: (선택 사항) p5.sound object (or web audio API source node)"
            +      }
            +    },
            +    "waveform": {
            +      "description": [
            +        "Returns an array of amplitude values (between -1.0 and +1.0) that represent a snapshot of amplitude readings in a single buffer. Length will be equal to bins (defaults to 1024). Can be used to draw the waveform of a sound."
            +      ],
            +      "returns": "배열: Array Array of amplitude values (-1 to 1)  over time. Array length = bins.",
            +      "params": {
            +        "bins": "숫자: (선택 사항) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "precision": "문자열: (선택 사항) If any value is provided, will return results  in a Float32 Array which is more precise  than a regular array."
            +      }
            +    },
            +    "analyze": {
            +      "description": [
            +        "Returns an array of amplitude values (between 0 and 255) across the frequency spectrum. Length is equal to FFT bins (1024 by default). The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Must be called prior to using <code>getEnergy()</code>."
            +      ],
            +      "returns": "배열: spectrum Array of energy (amplitude/volume)  values across the frequency spectrum.  Lowest energy (silence) = 0, highest  possible is 255.",
            +      "params": {
            +        "bins": "숫자: (선택 사항) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "scale": "숫자: (선택 사항) If \"dB,\" returns decibel  float measurements between  -140 and 0 (max).  Otherwise returns integers from 0-255."
            +      }
            +    },
            +    "getEnergy": {
            +      "description": [
            +        "Returns the amount of energy (volume) at a specific <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\"> frequency</a>, or the average amount of energy between two frequencies. Accepts Number(s) corresponding to frequency (in Hz), or a String corresponding to predefined frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\"). Returns a range between 0 (no energy/volume at that frequency) and 255 (maximum energy). <em>NOTE: analyze() must be called prior to getEnergy(). Analyze() tells the FFT to analyze frequency data, and getEnergy() uses the results determine the value at a specific frequency or range of frequencies.</em>"
            +      ],
            +      "returns": "숫자: Energy Energy (volume/amplitude) from  0 and 255.",
            +      "params": {
            +        "frequency1": "숫자|String: Will return a value representing  energy at this frequency. Alternately,  the strings \"bass\", \"lowMid\" \"mid\",  \"highMid\", and \"treble\" will return  predefined frequency ranges.",
            +        "frequency2": "숫자: (선택 사항) If a second frequency is given,  will return average amount of  energy that exists between the  two frequencies."
            +      }
            +    },
            +    "getCentroid": {
            +      "description": [
            +        "Returns the <a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\"> spectral centroid</a> of the input signal. <em>NOTE: analyze() must be called prior to getCentroid(). Analyze() tells the FFT to analyze frequency data, and getCentroid() uses the results determine the spectral centroid.</em>"
            +      ],
            +      "returns": "숫자: Spectral Centroid Frequency Frequency of the spectral centroid in Hz."
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth FFT analysis by averaging with the last analysis frame."
            +      ],
            +      "params": {
            +        "smoothing": "숫자: 0.0 < smoothing < 1.0.  Defaults to 0.8."
            +      }
            +    },
            +    "linAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values for a given number of frequency bands split equally. N defaults to 16. <em>NOTE: analyze() must be called prior to linAverages(). Analyze() tells the FFT to analyze frequency data, and linAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "배열: linearAverages Array of average amplitude values for each group",
            +      "params": {
            +        "N": "숫자: Number of returned frequency groups"
            +      }
            +    },
            +    "logAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values of the spectrum, for a given set of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\"> Octave Bands</a> <em>NOTE: analyze() must be called prior to logAverages(). Analyze() tells the FFT to analyze frequency data, and logAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "배열: logAverages Array of average amplitude values for each group",
            +      "params": {
            +        "octaveBands": "배열: Array of Octave Bands objects for grouping"
            +      }
            +    },
            +    "getOctaveBands": {
            +      "description": [
            +        "Calculates and Returns the 1/N <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a> N defaults to 3 and minimum central frequency to 15.625Hz. (1/3 Octave Bands ~= 31 Frequency Bands) Setting fCtr0 to a central value of a higher octave will ignore the lower bands and produce less frequency groups."
            +      ],
            +      "returns": "배열: octaveBands Array of octave band objects with their bounds",
            +      "params": {
            +        "N": "숫자: Specifies the 1/N type of generated octave bands",
            +        "fCtr0": "숫자: Minimum central frequency for the lowest band"
            +      }
            +    }
            +  },
            +  "p5.Oscillator": {
            +    "description": [
            +      "Creates a signal that oscillates between -1.0 and 1.0. By default, the oscillation takes the form of a sinusoidal shape ('sine'). Additional types include 'triangle', 'sawtooth' and 'square'. The frequency defaults to 440 oscillations per second (440Hz, equal to the pitch of an 'A' note).",
            +      "Set the type of oscillation with setType(), or by instantiating a specific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a href=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a href=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a href=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>."
            +    ],
            +    "params": {
            +      "freq": "숫자: (선택 사항) frequency defaults to 440Hz",
            +      "type": "문자열: (선택 사항) type of oscillator. Options:  'sine' (default), 'triangle',  'sawtooth', 'square'"
            +    },
            +    "start": {
            +      "description": [
            +        "Start an oscillator.",
            +        "Starting an oscillator on a user gesture will enable audio in browsers that have a strict autoplay policy, including Chrome and most mobile devices. See also: <code>userStartAudio()</code>."
            +      ],
            +      "params": {
            +        "time": "숫자: (선택 사항) startTime in seconds from now.",
            +        "frequency": "숫자: (선택 사항) frequency in Hz."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop an oscillator. Accepts an optional parameter to determine how long (in seconds from now) until the oscillator stops."
            +      ],
            +      "params": {
            +        "secondsFromNow": "숫자: Time, in seconds from now."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the amplitude between 0 and 1.0. Or, pass in an object such as an oscillator to modulate amplitude with an audio signal."
            +      ],
            +      "returns": "AudioParam: gain If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's  gain/amplitude/volume)",
            +      "params": {
            +        "vol": "숫자|Object: between 0 and 1.0  or a modulating signal/oscillator",
            +        "rampTime": "숫자: (선택 사항) create a fade that lasts rampTime",
            +        "timeFromNow": "숫자: (선택 사항) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getAmp": {
            +      "description": [
            +        "Returns the value of output gain"
            +      ],
            +      "returns": "숫자: Amplitude value between 0.0 and 1.0"
            +    },
            +    "freq": {
            +      "description": [
            +        "Set frequency of an oscillator to a value. Or, pass in an object such as an oscillator to modulate the frequency with an audio signal."
            +      ],
            +      "returns": "AudioParam: Frequency If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's frequency",
            +      "params": {
            +        "Frequency": "숫자|Object: Frequency in Hz  or modulating signal/oscillator",
            +        "rampTime": "숫자: (선택 사항) Ramp time (in seconds)",
            +        "timeFromNow": "숫자: (선택 사항) Schedule this event to happen  at x seconds from now"
            +      }
            +    },
            +    "getFreq": {
            +      "description": [
            +        "Returns the value of frequency of oscillator"
            +      ],
            +      "returns": "숫자: Frequency of oscillator in Hertz"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type to 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "params": {
            +        "type": "문자열: 'sine', 'triangle', 'sawtooth' or 'square'."
            +      }
            +    },
            +    "getType": {
            +      "description": [
            +        "Returns current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "returns": "문자열: type of oscillator eg . 'sine', 'triangle', 'sawtooth' or 'square'."
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "객체: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Pan between Left (-1) and Right (1)"
            +      ],
            +      "params": {
            +        "panning": "숫자: Number between -1 and 1",
            +        "timeFromNow": "숫자: schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current value of panPosition , between Left (-1) and Right (1)"
            +      ],
            +      "returns": "숫자: panPosition of oscillator , between Left (-1) and Right (1)"
            +    },
            +    "phase": {
            +      "description": [
            +        "Set the phase of an oscillator between 0.0 and 1.0. In this implementation, phase is a delay time based on the oscillator's current frequency."
            +      ],
            +      "params": {
            +        "phase": "숫자: float between 0.0 and 1.0"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "number": "숫자: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Oscillator's output amplitude by a fixed value (i.e. turn it up!). Calling this method again will override the initial mult() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with multiplied output",
            +      "params": {
            +        "number": "숫자: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this oscillator's amplitude values to a given range, and return the oscillator. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "inMin": "숫자: input range minumum",
            +        "inMax": "숫자: input range maximum",
            +        "outMin": "숫자: input range minumum",
            +        "outMax": "숫자: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.SinOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SinOsc()</code>. This creates a Sine Wave Oscillator and is equivalent to <code> new p5.Oscillator('sine') </code> or creating a p5.Oscillator and then calling its method <code>setType('sine')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "숫자: (선택 사항) Set the frequency"
            +    }
            +  },
            +  "p5.TriOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.TriOsc()</code>. This creates a Triangle Wave Oscillator and is equivalent to <code>new p5.Oscillator('triangle') </code> or creating a p5.Oscillator and then calling its method <code>setType('triangle')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "숫자: (선택 사항) Set the frequency"
            +    }
            +  },
            +  "p5.SawOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SawOsc()</code>. This creates a SawTooth Wave Oscillator and is equivalent to <code> new p5.Oscillator('sawtooth') </code> or creating a p5.Oscillator and then calling its method <code>setType('sawtooth')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "숫자: (선택 사항) Set the frequency"
            +    }
            +  },
            +  "p5.SqrOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SqrOsc()</code>. This creates a Square Wave Oscillator and is equivalent to <code> new p5.Oscillator('square') </code> or creating a p5.Oscillator and then calling its method <code>setType('square')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "숫자: (선택 사항) Set the frequency"
            +    }
            +  },
            +  "p5.Envelope": {
            +    "description": [
            +      "Envelopes are pre-defined amplitude distribution over time. Typically, envelopes are used to control the output volume of an object, a series of fades referred to as Attack, Decay, Sustain and Release ( <a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a> ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can control an Oscillator's frequency like this: <code>osc.freq(env)</code>.",
            +      "Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level. Use <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.",
            +      "Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope, the <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger, or <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/ <code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff."
            +    ],
            +    "attackTime": {
            +      "description": [
            +        "Time until envelope reaches attackLevel"
            +      ]
            +    },
            +    "attackLevel": {
            +      "description": [
            +        "Level once attack is complete."
            +      ]
            +    },
            +    "decayTime": {
            +      "description": [
            +        "Time until envelope reaches decayLevel."
            +      ]
            +    },
            +    "decayLevel": {
            +      "description": [
            +        "Level after decay. The envelope will sustain here until it is released."
            +      ]
            +    },
            +    "releaseTime": {
            +      "description": [
            +        "Duration of the release portion of the envelope."
            +      ]
            +    },
            +    "releaseLevel": {
            +      "description": [
            +        "Level at the end of the release."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Reset the envelope with a series of time/value pairs."
            +      ],
            +      "params": {
            +        "attackTime": "숫자: Time (in seconds) before level  reaches attackLevel",
            +        "attackLevel": "숫자: Typically an amplitude between  0.0 and 1.0",
            +        "decayTime": "숫자: Time",
            +        "decayLevel": "숫자: Amplitude (In a standard ADSR envelope,  decayLevel = sustainLevel)",
            +        "releaseTime": "숫자: Release Time (in seconds)",
            +        "releaseLevel": "숫자: Amplitude"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "숫자: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "숫자: (선택 사항) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "숫자: (선택 사항) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "숫자: (선택 사항) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setRange": {
            +      "description": [
            +        "Set max (attackLevel) and min (releaseLevel) of envelope."
            +      ],
            +      "params": {
            +        "aLevel": "숫자: attack level (defaults to 1)",
            +        "rLevel": "숫자: release level (defaults to 0)"
            +      }
            +    },
            +    "setInput": {
            +      "description": [
            +        "Assign a parameter to be controlled by this envelope. If a p5.Sound object is given, then the p5.Envelope will control its output gain. If multiple inputs are provided, the env will control all of them."
            +      ],
            +      "params": {
            +        "inputs": "객체: (선택 사항) A p5.sound object or  Web Audio Param."
            +      }
            +    },
            +    "setExp": {
            +      "description": [
            +        "Set whether the envelope ramp is linear (default) or exponential. Exponential ramps can be useful because we perceive amplitude and frequency logarithmically."
            +      ],
            +      "params": {
            +        "isExp": "불리언: true is exponential, false is linear"
            +      }
            +    },
            +    "play": {
            +      "description": [
            +        "Play tells the envelope to start acting on a given input. If the input is a p5.sound object (i.e. AudioIn, Oscillator, SoundFile), then Envelope will control its output volume. Envelopes can also be used to control any <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Audio Param.</a>"
            +      ],
            +      "params": {
            +        "unit": "객체: A p5.sound object or  Web Audio Param.",
            +        "startTime": "숫자: (선택 사항) time from now (in seconds) at which to play",
            +        "sustainTime": "숫자: (선택 사항) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go. Input can be any p5.sound object, or a <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Param</a>."
            +      ],
            +      "params": {
            +        "unit": "객체: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "숫자: time from now (in seconds)"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the Release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "unit": "객체: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "숫자: time to trigger the release"
            +      }
            +    },
            +    "ramp": {
            +      "description": [
            +        "Exponentially ramp to a value using the first two values from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code> as <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\"> time constants</a> for simple exponential ramps. If the value is higher than current value, it uses attackTime, while a decrease uses decayTime."
            +      ],
            +      "params": {
            +        "unit": "객체: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "숫자: When to trigger the ramp",
            +        "v": "숫자: Target value",
            +        "v2": "숫자: (선택 사항) Second target value (optional)"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "숫자: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Envelope's output amplitude by a fixed value. Calling this method again will override the initial mult() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "숫자: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this envelope's amplitude values to a given range, and return the envelope. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "inMin": "숫자: input range minumum",
            +        "inMax": "숫자: input range maximum",
            +        "outMin": "숫자: input range minumum",
            +        "outMax": "숫자: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.Noise": {
            +    "description": [
            +      "Noise is a type of oscillator that generates a buffer with random values."
            +    ],
            +    "params": {
            +      "type": "문자열: Type of noise can be 'white' (default),  'brown' or 'pink'."
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type of noise to 'white', 'pink' or 'brown'. White is the default."
            +      ],
            +      "params": {
            +        "type": "문자열: (선택 사항) 'white', 'pink' or 'brown'"
            +      }
            +    }
            +  },
            +  "p5.Pulse": {
            +    "description": [
            +      "Creates a Pulse object, an oscillator that implements Pulse Width Modulation. The pulse is created with two oscillators. Accepts a parameter for frequency, and to set the width between the pulses. See <a href=\" http://p5js.org/reference/#/p5.Oscillator\"> <code>p5.Oscillator</code> for a full list of methods."
            +    ],
            +    "params": {
            +      "freq": "숫자: (선택 사항) Frequency in oscillations per second (Hz)",
            +      "w": "숫자: (선택 사항) Width between the pulses (0 to 1.0,  defaults to 0)"
            +    },
            +    "width": {
            +      "description": [
            +        "Set the width of a Pulse object (an oscillator that implements Pulse Width Modulation)."
            +      ],
            +      "params": {
            +        "width": "숫자: (선택 사항) Width between the pulses (0 to 1.0,  defaults to 0)"
            +      }
            +    }
            +  },
            +  "p5.AudioIn": {
            +    "description": [
            +      "Get audio from an input, i.e. your computer's microphone.",
            +      "Turn the mic on/off with the start() and stop() methods. When the mic is on, its volume can be measured with getLevel or by connecting an FFT object.",
            +      "If you want to hear the AudioIn, use the .connect() method. AudioIn does not connect to p5.sound output by default to prevent feedback.",
            +      "<em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/ Stream</a> API, which is not supported by certain browsers. Access in Chrome browser is limited to localhost and https, but access over http may be limited.</em>"
            +    ],
            +    "params": {
            +      "errorCallback": "함수: (선택 사항) A function to call if there is an error  accessing the AudioIn. For example,  Safari and iOS devices do not  currently allow microphone access."
            +    },
            +    "input": {},
            +    "output": {},
            +    "stream": {},
            +    "mediaStream": {},
            +    "currentSource": {},
            +    "enabled": {
            +      "description": [
            +        "Client must allow browser to access their microphone / audioin source. Default: false. Will become true when the client enables access."
            +      ]
            +    },
            +    "amplitude": {
            +      "description": [
            +        "Input amplitude, connect to it by default but not to master out"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start processing audio input. This enables the use of other AudioIn methods like getLevel(). Note that by default, AudioIn is not connected to p5.sound's output. So you won't hear anything unless you use the connect() method.<br/>",
            +        "Certain browsers limit access to the user's microphone. For example, Chrome only allows access from localhost and over https. For this reason, you may want to include an errorCallback—a function that is called in case the browser won't provide mic access."
            +      ],
            +      "params": {
            +        "successCallback": "함수: (선택 사항) Name of a function to call on  success.",
            +        "errorCallback": "함수: (선택 사항) Name of a function to call if  there was an error. For example,  some browsers do not support  getUserMedia."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel(). If re-starting, the user may be prompted for permission access."
            +      ]
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to an audio unit. If no parameter is provided, will connect to the master output (i.e. your speakers).<br/>"
            +      ],
            +      "params": {
            +        "unit": "객체: (선택 사항) An object that accepts audio input,  such as an FFT"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect the AudioIn from all audio units. For example, if connect() had been called, disconnect() will stop sending signal to your speakers.<br/>"
            +      ]
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Read the Amplitude (volume level) of an AudioIn. The AudioIn class contains its own instance of the Amplitude class to help make it easy to get a microphone's volume level. Accepts an optional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must .start() before using .getLevel().</em><br/>"
            +      ],
            +      "returns": "숫자: Volume level (between 0.0 and 1.0)",
            +      "params": {
            +        "smoothing": "숫자: (선택 사항) Smoothing is 0.0 by default.  Smooths values based on previous values."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set amplitude (volume) of a mic input between 0 and 1.0. <br/>"
            +      ],
            +      "params": {
            +        "vol": "숫자: between 0 and 1.0",
            +        "time": "숫자: (선택 사항) ramp time (optional)"
            +      }
            +    },
            +    "getSources": {
            +      "description": [
            +        "Returns a list of available input sources. This is a wrapper for <a title=\"MediaDevices.enumerateDevices() - Web APIs | MDN\" target=\"_blank\" href=  \"<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"\">https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"</a> <blockquote>"
            +      ],
            +      "returns": "Promise: Returns a Promise that can be used in place of the callbacks, similar  to the enumerateDevices() method",
            +      "params": {
            +        "successCallback": "함수: (선택 사항) This callback function handles the sources when they  have been enumerated. The callback function  receives the deviceList array as its only argument",
            +        "errorCallback": "함수: (선택 사항) This optional callback receives the error  message as its argument."
            +      }
            +    },
            +    "setSource": {
            +      "description": [
            +        "Set the input source. Accepts a number representing a position in the array returned by getSources(). This is only available in browsers that support <a title=\"MediaDevices.enumerateDevices() - Web APIs | MDN\" target=\"_blank\" href= \"<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"\">https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"</a> <blockquote>"
            +      ],
            +      "params": {
            +        "num": "숫자: position of input source in the array"
            +      }
            +    }
            +  },
            +  "p5.Effect": {
            +    "description": [
            +      "Effect is a base class for audio effects in p5. This module handles the nodes and methods that are common and useful for current and future effects.",
            +      "This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>, <a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>, <a href=\"/reference/#/p5.Delay\">p5.Delay</a>, <a href=\"/reference/#/p5.Filter\">p5.Filter</a>, <a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>."
            +    ],
            +    "params": {
            +      "ac": "객체: (선택 사항) Reference to the audio context of the p5 object",
            +      "input": "AudioNode: (선택 사항) Gain Node effect wrapper",
            +      "output": "AudioNode: (선택 사항) Gain Node effect wrapper",
            +      "_drywet": "객체: (선택 사항) Tone.JS CrossFade node (defaults to value: 1)",
            +      "wet": "AudioNode: (선택 사항) Effects that extend this class should connect  to the wet signal to this gain node, so that dry and wet  signals are mixed properly."
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output volume of the filter."
            +      ],
            +      "params": {
            +        "vol": "숫자: (선택 사항) amplitude between 0 and 1.0",
            +        "rampTime": "숫자: (선택 사항) create a fade that lasts until rampTime",
            +        "tFromNow": "숫자: (선택 사항) schedule this event to happen in tFromNow seconds"
            +      }
            +    },
            +    "chain": {
            +      "description": [
            +        "Link effects together in a chain Example usage: filter.chain(reverb, delay, panner); May be used with an open-ended number of arguments"
            +      ],
            +      "params": {
            +        "arguments": "객체: (선택 사항) Chain together multiple sound objects"
            +      }
            +    },
            +    "drywet": {
            +      "description": [
            +        "Adjust the dry/wet value."
            +      ],
            +      "params": {
            +        "fade": "숫자: (선택 사항) The desired drywet value (0 - 1.0)"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.js-sound, Web Audio Node, or use signal to control an AudioParam"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Filter": {
            +    "description": [
            +      "A p5.Filter uses a Web Audio Biquad Filter to filter the frequency response of an input source. Subclasses include: <a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>: Allows frequencies below the cutoff frequency to pass through, and attenuates frequencies above the cutoff.<br/> <a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>: The opposite of a lowpass filter. <br/> <a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>: Allows a range of frequencies to pass through and attenuates the frequencies below and above this frequency range.<br/>",
            +      "The <code>.res()</code> method controls either width of the bandpass, or resonance of the low/highpass cutoff frequency.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "type": "문자열: (선택 사항) 'lowpass' (default), 'highpass', 'bandpass'"
            +    },
            +    "biquadFilter": {
            +      "description": [
            +        "The p5.Filter is built with a <a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\"> Web Audio BiquadFilter Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Filter an audio signal according to a set of filter parameters."
            +      ],
            +      "params": {
            +        "Signal": "객체: An object that outputs audio",
            +        "freq": "숫자: (선택 사항) Frequency in Hz, from 10 to 22050",
            +        "res": "숫자: (선택 사항) Resonance/Width of the filter frequency  from 0.001 to 1000"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the frequency and the resonance of the filter."
            +      ],
            +      "params": {
            +        "freq": "숫자: (선택 사항) Frequency in Hz, from 10 to 22050",
            +        "res": "숫자: (선택 사항) Resonance (Q) from 0.001 to 1000",
            +        "timeFromNow": "숫자: (선택 사항) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "freq": {
            +      "description": [
            +        "Set the filter frequency, in Hz, from 10 to 22050 (the range of human hearing, although in reality most people hear in a narrower range)."
            +      ],
            +      "returns": "숫자: value Returns the current frequency value",
            +      "params": {
            +        "freq": "숫자: Filter Frequency",
            +        "timeFromNow": "숫자: (선택 사항) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "res": {
            +      "description": [
            +        "Controls either width of a bandpass frequency, or the resonance of a low/highpass cutoff frequency."
            +      ],
            +      "returns": "숫자: value Returns the current res value",
            +      "params": {
            +        "res": "숫자: Resonance/Width of filter freq  from 0.001 to 1000",
            +        "timeFromNow": "숫자: (선택 사항) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "gain": {
            +      "description": [
            +        "Controls the gain attribute of a Biquad Filter. This is distinctly different from .amp() which is inherited from p5.Effect .amp() controls the volume via the output gain node p5.Filter.gain() controls the gain parameter of a Biquad Filter node."
            +      ],
            +      "returns": "숫자: Returns the current or updated gain value",
            +      "params": {
            +        "gain": "숫자"
            +      }
            +    },
            +    "toggle": {
            +      "description": [
            +        "Toggle function. Switches between the specified type and allpass"
            +      ],
            +      "returns": "불리언: [Toggle value]"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set the type of a p5.Filter. Possible types include: \"lowpass\" (default), \"highpass\", \"bandpass\", \"lowshelf\", \"highshelf\", \"peaking\", \"notch\", \"allpass\"."
            +      ],
            +      "params": {
            +        "t": "String"
            +      }
            +    }
            +  },
            +  "p5.LowPass": {
            +    "description": [
            +      "Constructor: <code>new p5.LowPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('lowpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.HighPass": {
            +    "description": [
            +      "Constructor: <code>new p5.HighPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('highpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.BandPass": {
            +    "description": [
            +      "Constructor: <code>new p5.BandPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('bandpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.EQ": {
            +    "description": [
            +      "p5.EQ is an audio effect that performs the function of a multiband audio equalizer. Equalization is used to adjust the balance of frequency compoenents of an audio signal. This process is commonly used in sound production and recording to change the waveform before it reaches a sound output device. EQ can also be used as an audio effect to create interesting distortions by filtering out parts of the spectrum. p5.EQ is built using a chain of Web Audio Biquad Filter Nodes and can be instantiated with 3 or 8 bands. Bands can be added or removed from the EQ by directly modifying p5.EQ.bands (the array that stores filters).",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "returns": "객체: p5.EQ object",
            +    "params": {
            +      "_eqsize": "숫자: (선택 사항) Constructor will accept 3 or 8, defaults to 3"
            +    },
            +    "bands": {
            +      "description": [
            +        "The p5.EQ is built with abstracted p5.Filter objects. To modify any bands, use methods of the <a href=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\"> p5.Filter</a> API, especially <code>gain</code> and <code>freq</code>. Bands are stored in an array, with indices 0 - 3, or 0 - 7"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process an input by connecting it to the EQ"
            +      ],
            +      "params": {
            +        "src": "객체: Audio source"
            +      }
            +    }
            +  },
            +  "p5.Panner3D": {
            +    "description": [
            +      "Panner3D is based on the <a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>. This panner is a spatial processing node that allows audio to be positioned and oriented in 3D space.",
            +      "The position is relative to an <a title=\"Web Audio Listener docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\"> Audio Context Listener</a>, which can be accessed by <code>p5.soundOut.audiocontext.listener</code>"
            +    ],
            +    "panner": {
            +      "description": [
            +        "<a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>",
            +        "Properties include <ul> <li><a title=\"w3 spec for Panning Model\" href=\"<a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\"\">https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\"</a><blockquote>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect an audio sorce"
            +      ],
            +      "params": {
            +        "src": "객체: Input source"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "배열: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "숫자",
            +        "yVal": "숫자",
            +        "zVal": "숫자",
            +        "time": "숫자"
            +      }
            +    },
            +    "positionX": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "숫자: updated coordinate value"
            +    },
            +    "positionY": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "숫자: updated coordinate value"
            +    },
            +    "positionZ": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "숫자: updated coordinate value"
            +    },
            +    "orient": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "배열: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "숫자",
            +        "yVal": "숫자",
            +        "zVal": "숫자",
            +        "time": "숫자"
            +      }
            +    },
            +    "orientX": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "숫자: updated coordinate value"
            +    },
            +    "orientY": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "숫자: updated coordinate value"
            +    },
            +    "orientZ": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "숫자: updated coordinate value"
            +    },
            +    "setFalloff": {
            +      "description": [
            +        "Set the rolloff factor and max distance"
            +      ],
            +      "params": {
            +        "maxDistance": "숫자 (선택 사항)",
            +        "rolloffFactor": "숫자 (선택 사항)"
            +      }
            +    },
            +    "maxDist": {
            +      "description": [
            +        "Maxium distance between the source and the listener"
            +      ],
            +      "returns": "숫자: updated value",
            +      "params": {
            +        "maxDistance": "숫자"
            +      }
            +    },
            +    "rollof": {
            +      "description": [
            +        "How quickly the volume is reduced as the source moves away from the listener"
            +      ],
            +      "returns": "숫자: updated value",
            +      "params": {
            +        "rolloffFactor": "숫자"
            +      }
            +    }
            +  },
            +  "p5.Delay": {
            +    "description": [
            +      "Delay is an echo effect. It processes an existing sound source, and outputs a delayed version of that sound. The p5.Delay can produce different effects depending on the delayTime, feedback, filter, and type. In the example below, a feedback of 0.5 (the default value) will produce a looping delay that decreases in volume by 50% each repeat. A filter will cut out the high frequencies so that the delay does not sound as piercing as the original source.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "leftDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "rightDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Add delay to an audio signal according to a set of delay parameters."
            +      ],
            +      "params": {
            +        "Signal": "객체: An object that outputs audio",
            +        "delayTime": "숫자: (선택 사항) Time (in seconds) of the delay/echo.  Some browsers limit delayTime to  1 second.",
            +        "feedback": "숫자: (선택 사항) sends the delay back through itself  in a loop that decreases in volume  each time.",
            +        "lowPass": "숫자: (선택 사항) Cutoff frequency. Only frequencies  below the lowPass will be part of the  delay."
            +      }
            +    },
            +    "delayTime": {
            +      "description": [
            +        "Set the delay (echo) time, in seconds. Usually this value will be a floating point number between 0.0 and 1.0."
            +      ],
            +      "params": {
            +        "delayTime": "숫자: Time (in seconds) of the delay"
            +      }
            +    },
            +    "feedback": {
            +      "description": [
            +        "Feedback occurs when Delay sends its signal back through its input in a loop. The feedback amount determines how much signal to send each time through the loop. A feedback greater than 1.0 is not desirable because it will increase the overall output each time through the loop, creating an infinite feedback loop. The default value is 0.5"
            +      ],
            +      "returns": "숫자: Feedback value",
            +      "params": {
            +        "feedback": "숫자|Object: 0.0 to 1.0, or an object such as an  Oscillator that can be used to  modulate this param"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Set a lowpass filter frequency for the delay. A lowpass filter will cut off any frequencies higher than the filter frequency."
            +      ],
            +      "params": {
            +        "cutoffFreq": "숫자|Object: A lowpass filter will cut off any  frequencies higher than the filter frequency.",
            +        "res": "숫자|Object: Resonance of the filter frequency  cutoff, or an object (i.e. a p5.Oscillator)  that can be used to modulate this parameter.  High numbers (i.e. 15) will produce a resonance,  low numbers (i.e. .2) will produce a slope."
            +      }
            +    },
            +    "setType": {
            +      "description": [
            +        "Choose a preset type of delay. 'pingPong' bounces the signal from the left to the right channel to produce a stereo effect. Any other parameter will revert to the default delay setting."
            +      ],
            +      "params": {
            +        "type": "문자열|숫자: 'pingPong' (1) or 'default' (0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the delay effect."
            +      ],
            +      "params": {
            +        "volume": "숫자: amplitude between 0 and 1.0",
            +        "rampTime": "숫자: (선택 사항) create a fade that lasts rampTime",
            +        "timeFromNow": "숫자: (선택 사항) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Reverb": {
            +    "description": [
            +      "Reverb adds depth to a sound through a large number of decaying echoes. It creates the perception that sound is occurring in a physical space. The p5.Reverb has parameters for Time (how long does the reverb last) and decayRate (how much the sound decays with each echo) that can be set with the .set() or .process() methods. The p5.Convolver extends p5.Reverb allowing you to recreate the sound of actual physical spaces through convolution.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "process": {
            +      "description": [
            +        "Connect a source to the reverb, and assign reverb parameters."
            +      ],
            +      "params": {
            +        "src": "객체: p5.sound / Web Audio object with a sound  output.",
            +        "seconds": "숫자: (선택 사항) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "숫자: (선택 사항) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "불리언: (선택 사항) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the reverb settings. Similar to .process(), but without assigning a new input."
            +      ],
            +      "params": {
            +        "seconds": "숫자: (선택 사항) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "숫자: (선택 사항) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "불리언: (선택 사항) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the reverb effect."
            +      ],
            +      "params": {
            +        "volume": "숫자: amplitude between 0 and 1.0",
            +        "rampTime": "숫자: (선택 사항) create a fade that lasts rampTime",
            +        "timeFromNow": "숫자: (선택 사항) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Convolver": {
            +    "description": [
            +      "p5.Convolver extends p5.Reverb. It can emulate the sound of real physical spaces through a process called <a href=\" https://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\"> convolution</a>.",
            +      "Convolution multiplies any audio input by an \"impulse response\" to simulate the dispersion of sound over time. The impulse response is generated from an audio file that you provide. One way to generate an impulse response is to pop a balloon in a reverberant space and record the echo. Convolution can also be used to experiment with sound.",
            +      "Use the method <code>createConvolution(path)</code> to instantiate a p5.Convolver with a path to your impulse response audio file."
            +    ],
            +    "params": {
            +      "path": "문자열: path to a sound file",
            +      "callback": "함수: (선택 사항) function to call when loading succeeds",
            +      "errorCallback": "함수: (선택 사항) function to call if loading fails.  This function will receive an error or  XMLHttpRequest object with information  about what went wrong."
            +    },
            +    "convolverNode": {
            +      "description": [
            +        "Internally, the p5.Convolver uses the a <a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\"> Web Audio Convolver Node</a>."
            +      ]
            +    },
            +    "impulses": {
            +      "description": [
            +        "If you load multiple impulse files using the .addImpulse method, they will be stored as Objects in this Array. Toggle between them with the <code>toggleImpulse(id)</code> method."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect a source to the convolver."
            +      ],
            +      "params": {
            +        "src": "객체: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "addImpulse": {
            +      "description": [
            +        "Load and assign a new Impulse Response to the p5.Convolver. The impulse is added to the <code>.impulses</code> array. Previous impulses can be accessed with the <code>.toggleImpulse(id)</code> method."
            +      ],
            +      "params": {
            +        "path": "문자열: path to a sound file",
            +        "callback": "함수: function (optional)",
            +        "errorCallback": "함수: function (optional)"
            +      }
            +    },
            +    "resetImpulse": {
            +      "description": [
            +        "Similar to .addImpulse, except that the <code>.impulses</code> Array is reset to save memory. A new <code>.impulses</code> array is created with this impulse as the only item."
            +      ],
            +      "params": {
            +        "path": "문자열: path to a sound file",
            +        "callback": "함수: function (optional)",
            +        "errorCallback": "함수: function (optional)"
            +      }
            +    },
            +    "toggleImpulse": {
            +      "description": [
            +        "If you have used <code>.addImpulse()</code> to add multiple impulses to a p5.Convolver, then you can use this method to toggle between the items in the <code>.impulses</code> Array. Accepts a parameter to identify which impulse you wish to use, identified either by its original filename (String) or by its position in the <code>.impulses </code> Array (Number).<br/> You can access the objects in the .impulses Array directly. Each Object has two attributes: an <code>.audioBuffer</code> (type: Web Audio <a href=\" http://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\"> AudioBuffer)</a> and a <code>.name</code>, a String that corresponds with the original filename."
            +      ],
            +      "params": {
            +        "id": "문자열|숫자: Identify the impulse by its original filename  (String), or by its position in the  <code>.impulses</code> Array (Number)."
            +      }
            +    }
            +  },
            +  "p5.Phrase": {
            +    "description": [
            +      "A phrase is a pattern of musical events over time, i.e. a series of notes and rests.",
            +      "Phrases must be added to a p5.Part for playback, and each part can play multiple phrases at the same time. For example, one Phrase might be a kick drum, another could be a snare, and another could be the bassline.",
            +      "The first parameter is a name so that the phrase can be modified or deleted later. The callback is a a function that this phrase will call at every step—for example it might be called <code>playNote(value){}</code>. The array determines which value is passed into the callback at each step of the phrase. It can be numbers, an object with multiple numbers, or a zero (0) indicates a rest so the callback won't be called)."
            +    ],
            +    "params": {
            +      "name": "문자열: Name so that you can access the Phrase.",
            +      "callback": "함수: The name of a function that this phrase  will call. Typically it will play a sound,  and accept two parameters: a time at which  to play the sound (in seconds from now),  and a value from the sequence array. The  time should be passed into the play() or  start() method to ensure precision.",
            +      "sequence": "배열: Array of values to pass into the callback  at each step of the phrase."
            +    },
            +    "sequence": {
            +      "description": [
            +        "Array of values to pass into the callback at each step of the phrase. Depending on the callback function's requirements, these values may be numbers, strings, or an object with multiple parameters. Zero (0) indicates a rest."
            +      ]
            +    }
            +  },
            +  "p5.Part": {
            +    "description": [
            +      "A p5.Part plays back one or more p5.Phrases. Instantiate a part with steps and tatums. By default, each step represents a 1/16th note.",
            +      "See p5.Phrase for more about musical timing."
            +    ],
            +    "params": {
            +      "steps": "숫자: (선택 사항) Steps in the part",
            +      "tatums": "숫자: (선택 사항) Divisions of a beat, e.g. use 1/4, or 0.25 for a quarter note (default is 1/16, a sixteenth note)"
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo of this part, in Beats Per Minute."
            +      ],
            +      "params": {
            +        "BPM": "숫자: Beats Per Minute",
            +        "rampTime": "숫자: (선택 사항) Seconds from now"
            +      }
            +    },
            +    "getBPM": {
            +      "description": [
            +        "Returns the tempo, in Beats Per Minute, of this part."
            +      ],
            +      "returns": "숫자: "
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of this part. It will play through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "숫자: (선택 사항) seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of this part. It will begin looping through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "숫자: (선택 사항) seconds from now"
            +      }
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Tell the part to stop looping."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again."
            +      ],
            +      "params": {
            +        "time": "숫자: (선택 사항) seconds from now"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the part. Playback will resume from the current step."
            +      ],
            +      "params": {
            +        "time": "숫자: seconds from now"
            +      }
            +    },
            +    "addPhrase": {
            +      "description": [
            +        "Add a p5.Phrase to this Part."
            +      ],
            +      "params": {
            +        "phrase": "p5.Phrase: reference to a p5.Phrase"
            +      }
            +    },
            +    "removePhrase": {
            +      "description": [
            +        "Remove a phrase from this part, based on the name it was given when it was created."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "getPhrase": {
            +      "description": [
            +        "Get a phrase from this part, based on the name it was given when it was created. Now you can modify its array."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "replaceSequence": {
            +      "description": [
            +        "Find all sequences with the specified name, and replace their patterns with the specified array."
            +      ],
            +      "params": {
            +        "phraseName": "String",
            +        "sequence": "배열: Array of values to pass into the callback  at each step of the phrase."
            +      }
            +    },
            +    "onStep": {
            +      "description": [
            +        "Set the function that will be called at every step. This will clear the previous function."
            +      ],
            +      "params": {
            +        "callback": "함수: The name of the callback  you want to fire  on every beat/tatum."
            +      }
            +    }
            +  },
            +  "p5.Score": {
            +    "description": [
            +      "A Score consists of a series of Parts. The parts will be played back in order. For example, you could have an A part, a B part, and a C part, and play them back in this order <code>new p5.Score(a, a, b, a, c)</code>"
            +    ],
            +    "params": {
            +      "parts": "p5.Part: (선택 사항) One or multiple parts, to be played in sequence."
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of the score."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop playback of the score."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause playback of the score."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of the score."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Stop looping playback of the score. If it is currently playing, this will go into effect after the current round of playback completes."
            +      ]
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo for all parts in the score"
            +      ],
            +      "params": {
            +        "BPM": "숫자: Beats Per Minute",
            +        "rampTime": "숫자: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.SoundLoop": {
            +    "description": [
            +      "SoundLoop"
            +    ],
            +    "params": {
            +      "callback": "함수: this function will be called on each iteration of theloop",
            +      "interval": "숫자|String: (선택 사항) amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second."
            +    },
            +    "bpm": {
            +      "description": [
            +        "Getters and Setters, setting any paramter will result in a change in the clock's frequency, that will be reflected after the next callback beats per minute (defaults to 60)"
            +      ]
            +    },
            +    "timeSignature": {
            +      "description": [
            +        "number of quarter notes in a measure (defaults to 4)"
            +      ]
            +    },
            +    "interval": {
            +      "description": [
            +        "length of the loops interval"
            +      ]
            +    },
            +    "iterations": {
            +      "description": [
            +        "how many times the callback has been called so far"
            +      ]
            +    },
            +    "musicalTimeMode": {
            +      "description": [
            +        "musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention true if string, false if number"
            +      ]
            +    },
            +    "maxIterations": {
            +      "description": [
            +        "Set a limit to the number of loops to play. defaults to Infinity"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "숫자: (선택 사항) schedule a starting time"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "숫자: (선택 사항) schedule a stopping time"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "숫자: (선택 사항) schedule a pausing time"
            +      }
            +    },
            +    "syncedStart": {
            +      "description": [
            +        "Synchronize loops. Use this method to start two more more loops in synchronization or to start a loop in synchronization with a loop that is already playing This method will schedule the implicit loop in sync with the explicit master loop i.e. loopToStart.syncedStart(loopToSyncWith)"
            +      ],
            +      "params": {
            +        "otherLoop": "객체: a p5.SoundLoop to sync with",
            +        "timeFromNow": "숫자: (선택 사항) Start the loops in sync after timeFromNow seconds"
            +      }
            +    }
            +  },
            +  "p5.Compressor": {
            +    "description": [
            +      "Compressor is an audio effect class that performs dynamics compression on an audio input source. This is a very commonly used technique in music and sound production. Compression creates an overall louder, richer, and fuller sound by lowering the volume of louds and raising that of softs. Compression can be used to avoid clipping (sound distortion due to peaks in volume) and is especially useful when many sounds are played at once. Compression can be used on individual sound sources in addition to the master output.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "compressor": {
            +      "description": [
            +        "The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"  target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node  </a>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Performs the same function as .connect, but also accepts optional parameters to set compressor's audioParams"
            +      ],
            +      "params": {
            +        "src": "객체: Sound source to be connected",
            +        "attack": "숫자: (선택 사항) The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "숫자: (선택 사항) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "숫자: (선택 사항) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "숫자: (선택 사항) The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "숫자: (선택 사항) The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the parameters of a compressor."
            +      ],
            +      "params": {
            +        "attack": "숫자: The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "숫자: A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "숫자: The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "숫자: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "숫자: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "attack": {
            +      "description": [
            +        "Get current attack or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "attack": "숫자: (선택 사항) Attack is the amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "time": "숫자: (선택 사항) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "knee": {
            +      "description": [
            +        "Get current knee or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "knee": "숫자: (선택 사항) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "time": "숫자: (선택 사항) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "ratio": {
            +      "description": [
            +        "Get current ratio or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "ratio": "숫자: (선택 사항) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "time": "숫자: (선택 사항) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "threshold": {
            +      "description": [
            +        "Get current threshold or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "threshold": "숫자: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "time": "숫자: (선택 사항) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "release": {
            +      "description": [
            +        "Get current release or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "release": "숫자: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1",
            +        "time": "숫자: (선택 사항) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "reduction": {
            +      "description": [
            +        "Return the current reduction value"
            +      ],
            +      "returns": "숫자: Value of the amount of gain reduction that is applied to the signal"
            +    }
            +  },
            +  "p5.PeakDetect": {
            +    "description": [
            +      "PeakDetect works in conjunction with p5.FFT to look for onsets in some or all of the frequency spectrum.",
            +      "To use p5.PeakDetect, call <code>update</code> in the draw loop and pass in a p5.FFT object.",
            +      "You can listen for a specific part of the frequency spectrum by setting the range between <code>freq1</code> and <code>freq2</code>.",
            +      "<code>threshold</code> is the threshold for detecting a peak, scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud as 1.0.",
            +      "The update method is meant to be run in the draw loop, and <b>frames</b> determines how many loops must pass before another peak can be detected. For example, if the frameRate() = 60, you could detect the beat of a 120 beat-per-minute song with this equation: <code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>",
            +      "Based on example contribtued by @b2renger, and a simple beat detection explanation by <a href=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\" target=\"_blank\">Felix Turner</a>."
            +    ],
            +    "params": {
            +      "freq1": "숫자: (선택 사항) lowFrequency - defaults to 20Hz",
            +      "freq2": "숫자: (선택 사항) highFrequency - defaults to 20000 Hz",
            +      "threshold": "숫자: (선택 사항) Threshold for detecting a beat between 0 and 1  scaled logarithmically where 0.1 is 1/2 the loudness  of 1.0. Defaults to 0.35.",
            +      "framesPerPeak": "숫자: (선택 사항) Defaults to 20."
            +    },
            +    "isDetected": {
            +      "description": [
            +        "isDetected is set to true when a peak is detected."
            +      ]
            +    },
            +    "update": {
            +      "description": [
            +        "The update method is run in the draw loop.",
            +        "Accepts an FFT object. You must call .analyze() on the FFT object prior to updating the peakDetect because it relies on a completed FFT analysis."
            +      ],
            +      "params": {
            +        "fftObject": "p5.FFT: A p5.FFT object"
            +      }
            +    },
            +    "onPeak": {
            +      "description": [
            +        "onPeak accepts two arguments: a function to call when a peak is detected. The value of the peak, between 0.0 and 1.0, is passed to the callback."
            +      ],
            +      "params": {
            +        "callback": "함수: Name of a function that will  be called when a peak is  detected.",
            +        "val": "객체: (선택 사항) Optional value to pass  into the function when  a peak is detected."
            +      }
            +    }
            +  },
            +  "p5.SoundRecorder": {
            +    "description": [
            +      "Record sounds for playback and/or to save as a .wav file. The p5.SoundRecorder records all sound output from your sketch, or can be assigned a specific source with setInput().",
            +      "The record() method accepts a p5.SoundFile as a parameter. When playback is stopped (either after the given amount of time, or with the stop() method), the p5.SoundRecorder will send its recording to that p5.SoundFile for playback."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a specific device to the p5.SoundRecorder. If no parameter is given, p5.SoundRecorer will record all audible p5.sound from your sketch."
            +      ],
            +      "params": {
            +        "unit": "객체: (선택 사항) p5.sound object or a web audio unit  that outputs sound"
            +      }
            +    },
            +    "record": {
            +      "description": [
            +        "Start recording. To access the recording, provide a p5.SoundFile as the first parameter. The p5.SoundRecorder will send its recording to that p5.SoundFile for playback once recording is complete. Optional parameters include duration (in seconds) of the recording, and a callback function that will be called once the complete recording has been transfered to the p5.SoundFile."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile",
            +        "duration": "숫자: (선택 사항) Time (in seconds)",
            +        "callback": "함수: (선택 사항) The name of a function that will be  called once the recording completes"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the recording. Once the recording is stopped, the results will be sent to the p5.SoundFile that was given on .record(), and if a callback function was provided on record, that function will be called."
            +      ]
            +    }
            +  },
            +  "p5.Distortion": {
            +    "description": [
            +      "A Distortion effect created with a Waveshaper Node, with an approach adapted from <a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a>",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "amount": "숫자: (선택 사항) Unbounded distortion amount.  Normal values range from 0-1.",
            +      "oversample": "문자열: (선택 사항) 'none', '2x', or '4x'."
            +    },
            +    "WaveShaperNode": {
            +      "description": [
            +        "The p5.Distortion is built with a <a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\"> Web Audio WaveShaper Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process a sound source, optionally specify amount and oversample values."
            +      ],
            +      "params": {
            +        "amount": "숫자: (선택 사항) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "문자열: (선택 사항) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the amount and oversample of the waveshaper distortion."
            +      ],
            +      "params": {
            +        "amount": "숫자: (선택 사항) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "문자열: (선택 사항) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "getAmount": {
            +      "description": [
            +        "Return the distortion amount, typically between 0-1."
            +      ],
            +      "returns": "숫자: Unbounded distortion amount.  Normal values range from 0-1."
            +    },
            +    "getOversample": {
            +      "description": [
            +        "Return the oversampling."
            +      ],
            +      "returns": "문자열: Oversample can either be 'none', '2x', or '4x'."
            +    }
            +  },
            +  "p5.Gain": {
            +    "description": [
            +      "A gain node is useful to set the relative volume of sound. It's typically used to build mixers."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a source to the gain node."
            +      ],
            +      "params": {
            +        "src": "객체: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the gain node."
            +      ],
            +      "params": {
            +        "volume": "숫자: amplitude between 0 and 1.0",
            +        "rampTime": "숫자: (선택 사항) create a fade that lasts rampTime",
            +        "timeFromNow": "숫자: (선택 사항) schedule this event to happen  seconds from now"
            +      }
            +    }
            +  },
            +  "p5.AudioVoice": {
            +    "description": [
            +      "Base class for monophonic synthesizers. Any extensions of this class should follow the API and implement the methods below in order to remain compatible with p5.PolySynth();"
            +    ],
            +    "connect": {
            +      "description": [
            +        "Connect to p5 objects or Web Audio Nodes"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect from soundOut"
            +      ]
            +    }
            +  },
            +  "p5.MonoSynth": {
            +    "description": [
            +      "A MonoSynth is used as a single voice for sound synthesis. This is a class to be used in conjunction with the PolySynth class. Custom synthesizers should be built inheriting from this class."
            +    ],
            +    "attack": {
            +      "description": [
            +        "Getters and Setters"
            +      ]
            +    },
            +    "decay": {},
            +    "sustain": {},
            +    "release": {},
            +    "play": {
            +      "description": [
            +        "Play tells the MonoSynth to start playing a note. This method schedules the calling of .triggerAttack and .triggerRelease."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz.",
            +        "velocity": "숫자: (선택 사항) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "숫자: (선택 사항) time from now (in seconds) at which to play",
            +        "sustainTime": "숫자: (선택 사항) time to sustain before releasing the envelope. Defaults to 0.15 seconds."
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz",
            +        "velocity": "숫자: (선택 사항) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "숫자: (선택 사항) time from now (in seconds) at which to play"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "secondsFromNow": "숫자: time to trigger the release"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "숫자: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "숫자: (선택 사항) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "숫자: (선택 사항) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "숫자: (선택 사항) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "MonoSynth amp"
            +      ],
            +      "returns": "숫자: new volume value",
            +      "params": {
            +        "vol": "숫자: desired volume",
            +        "rampTime": "숫자: (선택 사항) Time to reach new volume"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "객체: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  },
            +  "p5.OnsetDetect": {
            +    "description": [
            +      "Listen for onsets (a sharp increase in volume) within a given frequency range."
            +    ],
            +    "params": {
            +      "freqLow": "숫자: Low frequency",
            +      "freqHigh": "숫자: High frequency",
            +      "threshold": "숫자: Amplitude threshold between 0 (no energy) and 1 (maximum)",
            +      "callback": "함수: Function to call when an onset is detected"
            +    }
            +  },
            +  "p5.PolySynth": {
            +    "description": [
            +      "An AudioVoice is used as a single voice for sound synthesis. The PolySynth class holds an array of AudioVoice, and deals with voices allocations, with setting notes to be played, and parameters to be set."
            +    ],
            +    "params": {
            +      "synthVoice": "숫자: (선택 사항) A monophonic synth voice inheriting  the AudioVoice class. Defaults to p5.MonoSynth",
            +      "maxVoices": "숫자: (선택 사항) Number of voices, defaults to 8;"
            +    },
            +    "notes": {
            +      "description": [
            +        "An object that holds information about which notes have been played and which notes are currently being played. New notes are added as keys on the fly. While a note has been attacked, but not released, the value of the key is the audiovoice which is generating that note. When notes are released, the value of the key becomes undefined."
            +      ]
            +    },
            +    "polyvalue": {
            +      "description": [
            +        "A PolySynth must have at least 1 voice, defaults to 8"
            +      ]
            +    },
            +    "AudioVoice": {
            +      "description": [
            +        "Monosynth that generates the sound for each note that is triggered. The p5.PolySynth defaults to using the p5.MonoSynth as its voice."
            +      ]
            +    },
            +    "play": {
            +      "description": [
            +        "Play a note by triggering noteAttack and noteRelease with sustain time"
            +      ],
            +      "params": {
            +        "note": "숫자: (선택 사항) midi note to play (ranging from 0 to 127 - 60 being a middle C)",
            +        "velocity": "숫자: (선택 사항) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "숫자: (선택 사항) time from now (in seconds) at which to play",
            +        "sustainTime": "숫자: (선택 사항) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "noteADSR": {
            +      "description": [
            +        "noteADSR sets the envelope for a specific note that has just been triggered. Using this method modifies the envelope of whichever audiovoice is being used to play the desired note. The envelope should be reset before noteRelease is called in order to prevent the modified envelope from being used on other notes."
            +      ],
            +      "params": {
            +        "note": "숫자: (선택 사항) Midi note on which ADSR should be set.",
            +        "attackTime": "숫자: (선택 사항) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "숫자: (선택 사항) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "숫자: (선택 사항) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "숫자: (선택 사항) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set the PolySynths global envelope. This method modifies the envelopes of each monosynth so that all notes are played with this envelope."
            +      ],
            +      "params": {
            +        "attackTime": "숫자: (선택 사항) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "숫자: (선택 사항) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "숫자: (선택 사항) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "숫자: (선택 사항) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "noteAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of a MonoSynth. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "숫자: (선택 사항) midi note on which attack should be triggered.",
            +        "velocity": "숫자: (선택 사항) velocity of the note to play (ranging from 0 to 1)/",
            +        "secondsFromNow": "숫자: (선택 사항) time from now (in seconds)"
            +      }
            +    },
            +    "noteRelease": {
            +      "description": [
            +        "Trigger the Release of an AudioVoice note. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "note": "숫자: (선택 사항) midi note on which attack should be triggered.  If no value is provided, all notes will be released.",
            +        "secondsFromNow": "숫자: (선택 사항) time to trigger the release"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "객체: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/assets/reference/pt-BR.json b/dist/assets/reference/pt-BR.json
            new file mode 100644
            index 0000000000..111b62461e
            --- /dev/null
            +++ b/dist/assets/reference/pt-BR.json
            @@ -0,0 +1,7601 @@
            +{
            +  "h1": "Referência",
            +  "reference-search": "Buscar referência",
            +  "reference-description1": "Não encontrou o que você estava buscando? Você pode tentar em",
            +  "reference-description3": "Você também pode baixar uma versão off-line da Referência.",
            +  "reference-contribute2": "Por favor nos comunique.",
            +  "reference-error1": "Encontrou algum erro?",
            +  "reference-error3": "Por favor fique à vontade para editar ",
            +  "reference-error5": "e iniciar um pull request!",
            +  "reference-example": "Exemplo",
            +  "reference-description": "Descrição",
            +  "reference-extends": "Extensões",
            +  "reference-parameters": "Parâmetros",
            +  "reference-syntax": "Sintaxe",
            +  "reference-returns": "Returns",
            +  "Environment": "Ambiente",
            +  "Color": "Cor",
            +  "Color Conversion": "Conversão de cor",
            +  "Creating & Reading": "Criando e lendo",
            +  "Setting": "Configuração",
            +  "Shape": "Forma",
            +  "2D Primitives": "2D Primitivos",
            +  "Attributes": "Atributos",
            +  "Curves": "Curvas",
            +  "Vertex": "Vértices",
            +  "Constants": "Constantes",
            +  "Structure": "Estrutura",
            +  "DOM": "DOM",
            +  "Rendering": "Renderização",
            +  "Foundation": "Fundação",
            +  "Transform": "Transformar",
            +  "Data": "Dados",
            +  "LocalStorage": "LocalStorage",
            +  "Dictionary": "Dicionário",
            +  "Events": "Eventos",
            +  "Acceleration": "Aceleração",
            +  "Keyboard": "Teclado",
            +  "Mouse": "Mouse",
            +  "Touch": "Toque",
            +  "Image": "Imagem",
            +  "Loading & Displaying": "Loading & Displaying",
            +  "Pixels": "Pixels",
            +  "IO": "IO",
            +  "Input": "Input",
            +  "Output": "Output",
            +  "Table": "Table",
            +  "Math": "Math",
            +  "Calculation": "Calculation",
            +  "Vector": "Vetor",
            +  "Noise": "Noise",
            +  "Random": "Aleatório",
            +  "Trigonometry": "Trigonometria",
            +  "Typography": "Tipografia",
            +  "Array Functions": "Array Functions",
            +  "Conversion": "Conversão",
            +  "String Functions": "String Functions",
            +  "Time & Date": "Hora e Data",
            +  "3D Primitives": "3D Primitivos",
            +  "Lights, Camera": "Luz, Câmera",
            +  "Interaction": "Interação",
            +  "Lights": "Luzes",
            +  "3D Models": "Modelos 3D",
            +  "Material": "Material",
            +  "Camera": "Câmera",
            +  "p5": {
            +    "description": [
            +      "Esse é o construtor de p5 instance (instância p5). ",
            +      "Uma instância p5 contém todas as propriedades e métodos relacionados a um sketch de p5. Ela gerencia os pedidos de um sketch e também pode servir como um parâmetro de node opcional para atrelar um canvas p5 a um node. O sketch gerado usa as novas instances (instâncias) p5 como um novo argumento e pode opcionalmente criar um <a href=\"#/p5/preload\">preload()</a>, <a href=\"#/p5/setup\">setup()</a>, e/ou <a href=\"#/p5/draw\">draw()</a> as propriedades de um sketch que já está rodando. ",
            +      "Um sketch p5 pode rodar em \"global\" ou \"instance\" modo: \"global\" - todas as propriedades e métodos estão atrelados à janela \"instance\" - todas as propriedades e métodos estão atrelados ao este objeto p5"
            +    ],
            +    "resultado": "P5: uma p5 instance (instância)",
            +    "params": {
            +      "sketch": "Função: uma closure (clausura) que pode definir um <a href=\"#/p5/preload\">preload()</a> opcional,  <a href=\"#/p5/setup\">setup()</a>, e/ou <a href=\"#/p5/draw\">draw()</a> as propriedades de uma p5 instance",
            +      "node": "HTMLElement: (Optional) element to attach canvas to"
            +    },
            +    "describe": {
            +      "description": [
            +        "Cria uma descrição acessível a leitores de tela para a canvas. O primeiro parâmetro deve ser uma string com a descrição da canvas. O segundo parâmetro é opcional. Se especificado, ele determina como a descrição será mostrada.",
            +        "<code class=\"language-javascript\">describe(texto, LABEL)</code> apresenta a descrição a todas as pessoas como uma <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">ETIQUETA DE MUSEU *****</a> em uma <code class=\"language-javascript\"><div class=\"p5Label\"></div></code> próxima à canvas. Você pode utilizar CSS para alterar a aparência dessa legenda.",
            +        "<code class=\"language-javascript\">describe(texto, FALLBACK)</code> torna a descrição acessível somente para pessoas utilizando leitores de tela, em um <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> sub DOM dentro do elemento canvas</a>. Se um segundo parâmetro não for especificado, por padrão, a descrição somente será acessível para pessoas que utilizem leitores de tela."
            +      ],
            +      "params": {
            +        "text": "String: descrição da canvas",
            +        "display": "Constante (opcional): LABEL ou FALLBACK"
            +      }
            +    },
            +    "describeElement": {
            +      "description": [
            +        "Esta função cria uma descrição acessível a leitores de tela para elementos - formas ou grupos de formas que só tem signficado juntas — na canvas. O primeiro parâmetro deve ser o nome do elemento. O segundo parâmetro deve ser uma string com a descrição do elemento. O terceiro parâmetro é opcional. Se especificado, ele determina como a descrição do elemento será mostrada.",
            +        "<code class=\"language-javascript\">describeElement(nome, texto, LABEL)</code> mostra a descrição do elemento a todas as pessoas como uma <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">ETIQUETA DE MUSEU *****/caption</a> em uma <code class=\"language-javascript\"><div class=\"p5Label\"></div></code> adjacente à canvas. Você pode definir o estilo como quiser no seu CSS.",
            +        "<code class=\"language-javascript\">describeElement(nome, texto, FALLBACK)</code> torna a descrição do elemento acessível somente a pessoas que estejam utilizando leitores de tela, em <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">um sub DOM dentro do elemento canvas</a>. Se um segundo parâmetro não for definido, por padrão a descrição do elemento estará disponível apenas a pessoas que façam uso de leitores de tela."
            +      ],
            +      "params": {
            +        "name": "String: nome do elemento",
            +        "text": "String: descrição do elemento",
            +        "display": "Constante (opcional): LABEL ou FALLBACK "
            +      }
            +    },
            +    "textOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">textOutput()</code> cria uma descrição em inglês das formas presentes na canvas de forma acessível a leitores de tela. A descrição geral da canvas inclui tamanho, cor, e o número de elementos na tela. Exemplo: 'Your output is a, 400 by 400 pixels, lavender blue canvas containing the following 4 shapes:\" (em português: \"Seu resultado é uma canvas lavanda-azulado, de 400 por 400 pixels, contendo as seguintes formas:\"), seguida de uma lista descrevendo a cor, posição e área de cada forma — exemplo: \"orange ellipse at top left covering 1% of the canvas\" (em português: uma elipse alaranjada no canto superior esquerdo cobrindo 1% da canvas). Cada elemento pode ser selecionado para acessar mais detalhes. Uma tabela de elementos também é fornecida. Nesta tabela são descritas a forma, cor, localização, coordenadas e área — exemplo: \"orange ellipse location=top left area=2\" (em português: \"laranja | elipse | localização = superior esquerda | área = 2\").",
            +        "<code class=\"language-javascript\">textOutput()</code> e <code class=\"language-javascript\">texOutput(FALLBACK)</code> disponibilizam a descrição em <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">um sub DOM dentro do elemento canvas</a>, sendo acessível através do uso de leitores de tela. <code class=\"language-javascript\">textOutput(LABEL)</code> cria um elemento <code class=\"language-javascript\">div</code> ao lado da canvas para conter o texto. Isto pode ser interessante para que pessoas que não utilizam leitores de tela possam visualizar a descrição enquanto programam. Porém, é importante notar que usar o parâmetro LABEL no código final irá criar redundância para leitores de tela. Recomendamos utilizar LABEL somente como parte do desenvolvimento do código, e removê-lo antes de publicar e compartilhar seu código com pessoas que utilizam leitores de tela."
            +      ],
            +      "params": {
            +        "display": "Constante (opcional): FALLBACK ou LABEL "
            +      }
            +    },
            +    "gridOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">gridOutput()</code> mostra o conteúdo da canvas na forma de uma tabela HTML (grade), baseando-se na localização de cada forma. Uma breve descrição da canvas em inglês é disponibilizada antes das informações da tabela. Esta descrição inclui: cor do fundo, tamanho da canvas, número de objetos, e tipos de objetos — exemplo: \"lavender blue canvas is 200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\" (em português: \"canvas lavanda-azulada mede 200 por 200 pixels e contém 4 objetos — 3 elipses 1 retângulo\"). A tabela descreve o conteúdo espacialmente, cada elemento é posicionado em uma célula da tabela a depender de sua posição. Cada célula apresenta a cor e o tipo de forma do elemento correspondente — exemplo: \"orange ellipse\" (em português: \"elipse laranja\"). As descrições podem ser selecionadas individualmente para mais detalhes. Também disponibiliza uma lista descritiva contendo forma, cor, localização e área de cada elemento — examplo: \"orange ellipse location=top left area=1%\" (em português: \"laranja | elipse | localização = topo esquerdo | área = 1%).",
            +        "<code class=\"language-javascript\">gridOutput()</code> e <code class=\"language-javascript\">gridOutput(FALLBACK)</code> disponibilizam a descrição em <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">um sub DOM dentro do elemento canvas</a>, sendo acessível através do uso de leitores de tela. <code class=\"language-javascript\">gridOutput(LABEL)</code> cria um elemento <code class=\"language-javascript\">div</code> ao lado da canvas para conter o texto. Isto pode ser interessante para que pessoas que não utilizam leitores de tela possam visualizar a descrição enquanto programam. Porém, é importante notar que usar o parâmetro LABEL no código final irá criar redundância para leitores de tela. Recomendamos utilizar LABEL somente como parte do desenvolvimento do código, e removê-lo antes de publicar e compartilhar seu código com pessoas que utilizam leitores de tela."
            +      ],
            +      "params": {
            +        "display": "Constante (opcional): FALLBACK ou LABEL"
            +      }
            +    },
            +    "alpha": {
            +      "description": [
            +        "Extrai o valor de transparência (alpha) de uma cor ou de uma array de pixels."
            +      ],
            +      "returns": "Número: o valor de transparência (alpha) presente na cor especificada",
            +      "params": {
            +        "color": "p5.Color | Número[] | String: objeto <a href=\"#/p5.Color\">p5.Color</a>, valores dos componentes da cor ou cor CSS"
            +      }
            +    },
            +    "blue": {
            +      "description": [
            +        "Extrai o valor de azul de uma cor ou de uma array de pixels."
            +      ],
            +      "returns": "Número: o valor de azul presente na cor especificada",
            +      "params": {
            +        "color": "p5.Color | Número[] | String: objeto <a href=\"#/p5.Color\">p5.Color</a>, valores dos componentes da cor ou cor CSS"
            +      }
            +    },
            +    "brightness": {
            +      "description": [
            +        "Extrai o valor do brilho de uma cor ou array de pixels seguindo o modo de cor HSB."
            +      ],
            +      "returns": "Número: o valor do brilho da cor especificada",
            +      "params": {
            +        "color": "p5.Color | Número[] | String: objeto <a href=\"#/p5.Color\">p5.Color</a>, valores dos componentes da cor ou cor CSS"
            +      }
            +    },
            +    "color": {
            +      "description": [
            +        "Cria um objeto para armazenar variáveis do tipo cor. Os parâmetros são interpretados como valores RGB ou HSB dependendo do modo de cor definido (<a href=\"#/p5/colorMode\">colorMode()</a>). O modo padrão usa valores RGB de 0 a 255 e, logo, a função color(255, 204, 0) retornará um amarelo claro.",
            +        "Note que se apenas um valor for fornecido ao <a href=\"#/p5/color\">color()</a> ele será interpretado como um valor em escala de cinza. Adicionando um segundo valor ele será interpretado como alpha (transparência). Quando três valores forem fornecidos eles serão interpretados como RGB (vermelho, verde e azul) ou HSB (matiz, saturação e brilho). Adicionando um quarto valor ele será usado como alpha (transparência).",
            +        "Também é possível passar à função um único argumento do tipo string. Assim, ele será interpretado como qualquer cor web nomeável, cores hex (#), rgb() ou rgba() (ver exemplos). Nesse caso, um valor para alpha não será possível pois a função não suporta um argumento do tipo número após uma string. Para cores com transparência, use o padrão RGBA."
            +      ],
            +      "returns": "p5.Color: a cor resultante",
            +      "params": {
            +        "gray": "Número: valor único da cor em escala de cinza",
            +        "alpha": "Número (opcional): alpha (transparência) a ser adicionada à cor especificada (por padrão, são válidos valores entre 0-255)",
            +        "v1": "Número: valor do vermelho em modo RGB ou da matiz de cor no modo HSB",
            +        "v2": "Número: valor do verde em modo RGB ou da saturação de cor no modo HSB",
            +        "v3": "Número: valor do azul em modo RGB ou do brilho de cor no modo HSB",
            +        "value": "String: string de cor — os formatos possíveis são: rgb() ou rgba() com números inteiros (0-255) ou porcentagens, hex de 3 ou de 6 dígitos, ou nomes de cores",
            +        "values": "Número[]: uma array contendo os valores de vermelho, verde, azul e alpha (transparência) da cor final",
            +        "color": "p5.Color"
            +      }
            +    },
            +    "green": {
            +      "description": [
            +        "Extrai o valor de verde de uma cor ou de uma array de pixels."
            +      ],
            +      "returns": "Número: o valor de verde presente na cor especificada",
            +      "params": {
            +        "color": "p5.Color | Número[] | String: objeto <a href=\"#/p5.Color\">p5.Color</a>, valores dos componentes da cor ou cor CSS"
            +      }
            +    },
            +    "hue": {
            +      "description": [
            +        "Extrai o valor da matiz de uma cor ou de uma arrray de pixels. ",
            +        "Matiz (hue) está presente nos padrões de cor HSB e HSL. Esta função retornará a matiz normalizada de acordo com o padrão HSB quando um objeto contendo uma cor neste formato for fornecido, ou quando uma array de pixels for fornecida enquanto o sketch estiver utilizando HSB como modo de cor (<a href=\"#/p5/colorMode\">colorMode()</a>). Porém, retornará uma matiz normalizada segundo o padrão HSL em qualquer outro caso. Os valores só serão diferentes se o valor máximo da matiz for diferente para cada sistema."
            +      ],
            +      "returns": "Número: a matiz da cor especificada",
            +      "params": {
            +        "color": "p5.Color | Número[] | String: objeto <a href=\"#/p5.Color\">p5.Color</a>, valores dos componentes da cor ou cor CSS"
            +      }
            +    },
            +    "lerpColor": {
            +      "description": [
            +        "Mistura duas cores para encontrar uma terceira entre as duas. O parâmetro amt é a quantidade para interpolar entre dois valores, onde 0 é igual à primeira cor, e 1 é igual à segunda — 0.1 é muito próximo da primeira cor, 0.5 é a média, etc. Um valor menor que 0 será considerado igual a 0. Da mesma maneira, valores acima de 1 serão considerados iguais a 1. Esse comportamento é diferente de <a href=\"#/p5/lerp\">lerp()</a>, mas necessário para evitar números fora do intervalo que podem produzir cores e resultados inesperados.",
            +        "A maneira que as cores são interpoladas depende do modo de cor em uso (<a href=\"#/p5/colorMode\">colorMode()</a>)."
            +      ],
            +      "returns": "p5.Color: a cor resultante da interpolação",
            +      "params": {
            +        "c1": "p5.Color: cor a interpolar de (equivalente a 0)",
            +        "c2": "p5.Color: cor a interpolar para (equivalente a 1)",
            +        "amt": "Número: número entre 0 e 1"
            +      }
            +    },
            +    "lightness": {
            +      "description": [
            +        "Extrai o valor do brilho de uma cor ou array de pixels seguindo o modo de cor HSL."
            +      ],
            +      "returns": "Número: o valor do brilho da cor especificada",
            +      "params": {
            +        "color": "p5.Color | Número[] | String: objeto <a href=\"#/p5.Color\">p5.Color</a>, valores dos componentes da cor ou cor CSS"
            +      }
            +    },
            +    "red": {
            +      "description": [
            +        "Extrai o valor de vermelho de uma cor ou de uma array de pixels."
            +      ],
            +      "returns": "Número: o valor de vermelho presente na cor especificada",
            +      "params": {
            +        "color": "p5.Color | Número[] | String: objeto <a href=\"#/p5.Color\">p5.Color</a>, valores dos componentes da cor ou cor CSS"
            +      }
            +    },
            +    "saturation": {
            +      "description": [
            +        "Extrai o valor de saturação da cor ou de uma array de pixels",
            +        "A Saturação funciona de forma diferente em HSB e HSL. Esta função retornará a saturação no modo HSB quando a cor ou array de pixels utilizar este formato, mas usará a saturação em HSL como padrão (caso não seja fornecido outro)."
            +      ],
            +      "returns": "Número: o valor de saturação da cor especificada",
            +      "params": {
            +        "color": "p5.Color | Número[] | String: objeto <a href=\"#/p5.Color\">p5.Color</a>, valores dos componentes da cor ou cor CSS"
            +      }
            +    },
            +    "background": {
            +      "description": [
            +        "A função <a href=\"#/p5/background\">background()</a> configura a cor de fundo da canvas. A cor padrão é transparente. Esta função geralmente é usada dentro de <a href=\"#/p5/draw\">draw()</a> para limpar a tela no início de cada frame, mas pode ser usada dentro de <a href=\"#/p5/setup\">setup()</a> para configurar o fundo no primeiro frame da animação ou se o fundo precisa ser configurado apenas uma vez.",
            +        "A cor é especificada em RGB, HSB ou HSL, dependendo do <a href=\"#/p5/colorMode\">colorMode()</a> usado. (O modo padrão de cores é RGB, com cada atributo indo de 0 a 255). O alpha (transparência) padrão também vai de 0 a 255.",
            +        "Também é possível passar à função um único argumento do tipo string. Assim, ele será interpretado como qualquer cor web nomeável, cores hex (#), rgb() ou rgba() (ver exemplos). Nesse caso, um valor para alpha não será possível pois a função não suporta um argumento do tipo número após uma string. Para cores com transparência, use o padrão RGBA.",
            +        "Um objeto <a href=\"#/p5.Color\">p5.Color</a> também pode ser utilizado para configurar a cor de fundo, ou ainda uma <a href=\"#/p5.Image\">p5.Image</a> pode ser utilizada para configurar uma imagem de fundo."
            +      ],
            +      "params": {
            +        "color": "p5.Color: qualquer valor criado pela função <a href=\"#/p5/color\">color()</a>",
            +        "colorstring": "String: string de cor — os formatos possíveis são: rgb() ou rgba() com números inteiros (0-255) ou porcentagens, hex de 3 ou de 6 dígitos, ou nomes de cores",
            +        "a": "Número (opcional): a opacidade (alpha) do fundo em relação ao intervalo de cor que está sendo utilizado (por padrão: 0 a 255)",
            +        "gray": "Número: específica um valor entre branco e preto (escala de cinza)",
            +        "v1": "Número: valor do vermelho em modo RGB ou da matiz de cor no modo HSB",
            +        "v2": "Número: valor do verde em modo RGB ou da saturação de cor no modo HSB",
            +        "v3": "Número: valor do azul em modo RGB ou do brilho de cor no modo HSB",
            +        "values": "Número[]: uma array contendo vermelho, verde, azul e o alpha (opacidade) da cor",
            +        "image": "p5.Image: imagem criada com os métodos <a href=\"#/p5/loadImage\">loadImage()</a> ou <a href=\"#/p5/createImage\">createImage()</a>, para configurar o fundo (deve ser do mesmo tamanho da janela do sketch)"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Limpa os pixels dentro de um buffer (memória temporária), tornando-os transparentes. Esta função limpa apenas a canvas, ela não limpará os objetos criados pelos métodos do tipo createX(), como o <a href=\"#/p5/createVideo\">createVideo()</a> ou o <a href=\"#/p5/createDiv\">createDiv()</a>. Diferentemente do contexto principal dos gráficos, os pixels em gráficos adicionais criados com <a href=\"#/p5/createGraphics\">createGraphics()</a> podem ser inteiramente ou parcialmente transparentes. Esta função torna todos os pixels 100% transparentes."
            +      ]
            +    },
            +    "colorMode": {
            +      "description": [
            +        "<a href=\"#/p5/colorMode\">colorMode()</a> muda a forma com que o p5.js interpreta os dados de cor. Por padrão, os parâmetros para <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>, e <a href=\"#/p5/color\">color()</a> são definidos por valores entre 0 e 255 utilizando o formato RGB. Isto é equivalente a configurar como colorMode(RGB, 255). Utilizar colorMode(HSB) permite que você use o sistema HSB. Por padrão, isso é (HSB, 360, 100, 100, 1). Você também pode usar HSL.",
            +        "Observação: as cores dos objetos já existentes lembram o modo de cor em que foram criados, logo, você pode mudá-lo sem afetar a aparência deles."
            +      ],
            +      "params": {
            +        "mode": "Constante: RGB, HSB ou HSL, correspondendo a Vermelho/Verde/Azul ou Matiz/Saturação/Brilho",
            +        "max": "Número (opcional): intervalo para todos os valores, isto é, o valor máximo para cada parâmetro",
            +        "max1": "Número: intervalo de vermelho ou de matiz (dependendo do formato de cor sendo utilizado)",
            +        "max2": "Número: intervalo de verde ou de saturação (dependendo do formato de cor sendo utilizado)",
            +        "max3": "Número: intervalo de azul ou de brilho (dependendo do formato de cor sendo utilizado)",
            +        "maxA": "Número (opcional): intervalo de alpha (transparência)"
            +      }
            +    },
            +    "fill": {
            +      "description": [
            +        "Configura a cor usada no preenchimento das formas. Por exemplo, se você configurar fill(204, 102, 0), todas as formas criadas depois desse comando serão preenchidas com a cor laranja. Essa cor é especificada em RGB ou HSB, dependendo do <a href=\"#/p5/colorMode\">colorMode()</a> atual. (O padrão é RGB, onde cada valor vai de 0 a 255). O alpha também vai de 0 a 255.",
            +        "Também é possível passar à função um único argumento do tipo string. Assim, ele será interpretado como qualquer cor web nomeável, cores hex (#), rgb() ou rgba() (ver exemplos). Nesse caso, um valor para alpha não será possível pois a função não suporta um argumento do tipo número após uma string. Para cores com transparência, use o padrão RGBA.",
            +        "Um objeto <a href=\"#/p5.Color\">Color</a> também pode ser utilizado para definir a cor do preenchimento."
            +      ],
            +      "params": {
            +        "v1": "Número: o valor de vermelho ou de matiz (dependendo do formato de cor sendo utilizado)",
            +        "v2": "Número: o valor de verde ou de saturação (dependendo do formato de cor sendo utilizado)",
            +        "v3": "Número: o valor de azul ou de brilho (dependendo do formato de cor sendo utilizado)",
            +        "alpha": "Número (opcional): valor de alpha (opacidade) do preenchimento",
            +        "value": "String: string de cor — os formatos possíveis são: rgb() ou rgba() com números inteiros (0-255) ou porcentagens, hex de 3 ou de 6 dígitos, ou nomes de cores",
            +        "gray": "Número: um valor de cinza",
            +        "values": "Número[]: uma array contendo vermelho, verde, azul e alpha",
            +        "color": "p5.Color: a cor do preenchimento"
            +      }
            +    },
            +    "noFill": {
            +      "description": [
            +        "Desabilita o preenchimento das formas que sejam criadas depois deste comando. Se <a href=\"#/p5/noStroke\">noStroke()</a> e <a href=\"#/p5/noFill\">noFill()</a> forem chamados, nada será criado na tela."
            +      ]
            +    },
            +    "noStroke": {
            +      "description": [
            +        "Desabilita o contorno das formas que sejam criadas depois deste comando. Se <a href=\"#/p5/noStroke\">noStroke()</a> e <a href=\"#/p5/noFill\">noFill()</a> forem chamados, nada será criado na tela."
            +      ]
            +    },
            +    "stroke": {
            +      "description": [
            +        "Define a cor usada para as linhas de contorno e bordas das formas. Essa cor é especificada em RGB ou HSB, dependendo do <a href=\"#/p5/colorMode\">colorMode()</a> atual — o padrão é RGB, onde cada valor vai de 0 a 255. O alpha também vai de 0 a 255.",
            +        "Também é possível passar à função um único argumento do tipo string. Assim, ele será interpretado como qualquer cor web nomeável, cores hex (#), rgb() ou rgba() (ver exemplos). Nesse caso, um valor para alpha não será possível pois a função não suporta um argumento do tipo número após uma string. Para cores com transparência, use o padrão RGBA.",
            +        "Um objeto <a href=\"#/p5.Color\">Color</a> também pode ser utilizado para definir a cor do contorno."
            +      ],
            +      "params": {
            +        "v1": "Número: o valor de vermelho ou de matiz (dependendo do formato de cor sendo utilizado)",
            +        "v2": "Número: o valor de verde ou de saturação (dependendo do formato de cor sendo utilizado)",
            +        "v3": "Número: o valor de azul ou de brilho (dependendo do formato de cor sendo utilizado)",
            +        "alpha": "Número (opcional): valor de alpha (opacidade) do contorno",
            +        "value": "String: string de cor — os formatos possíveis são: rgb() ou rgba() com números inteiros (0-255) ou porcentagens, hex de 3 ou de 6 dígitos, ou nomes de cores",
            +        "gray": "Número: um valor de cinza",
            +        "values": "Número[]: uma array contendo vermelho, verde, azul e alpha",
            +        "color": "p5.Color: a cor do contorno"
            +      }
            +    },
            +    "erase": {
            +      "description": [
            +        "Qualquer desenho criado depois do <a href=\"#/p5/erase\">erase()</a> será subtraído (apagado) da canvas. Áreas apagadas mostrarão a página web abaixo da canvas. Essa subtração pode ser cancelada com <a href=\"#/p5/noErase\">noErase()</a>. ",
            +        "Desenhos feitos com <a href=\"#/p5/image\">image()</a> e <a href=\"#/p5/background\"> background()</a> entre <a href=\"#/p5/erase\">erase()</a> e <a href=\"#/p5/noErase\">noErase()</a> não apagará a canvas, e funcionará normalmente."
            +      ],
            +      "params": {
            +        "strengthFill": "Número (opcional): Um número (0-255) que define a opacidade do apagamento do preenchimento da forma. O valor padrão quando nenhum outro valor for fornecido é de 255, resultando em transparência total.",
            +        "strengthStroke": "Número (opcional): Um número (0-255) que define a opacidade do apagamento do contorno da forma. O valor padrão quando nenhum outro valor for fornecido é de 255, resultando em transparência total."
            +      }
            +    },
            +    "noErase": {
            +      "description": [
            +        "Determina o fim do apagamento iniciado com <a href=\"#/p5/erase\">erase()</a>. O <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, e <a href=\"#/p5/blendMode\">blendMode()</a> retornarão ao que eram antes de chamar o <a href=\"#/p5/erase\">erase()</a>."
            +      ]
            +    },
            +    "arc": {
            +      "description": [
            +        "Desenha um arco na tela. Se for chamado apenas com x, y, w, h, start e stop, o arco será desenhado e preenchido como um segmento aberto. Se um parâmetro de modo for fornecido, o arco será preenchido como um semi-círculo aberto (OPEN),um semi-círculo fechado (CHORD), ou como uma geometria fechada (PIE). A origem pode ser definida com a função <a href=\"#/p5/ellipseMode\">ellipseMode()</a>. ",
            +        "O arco é desenhado sempre em sentido horário do ponto inicial ao final na elipse. Adicionar ou subtrair TWO_PI para qualquer um dos ângulos não muda onde eles caem. Se o início e o final caem no mesmo ponto uma elipse completa será desenhada. Leve em consideração que o eixo y aumenta indo para baixo, logo, os ângulos são medidos em sentido horário da direção x positiva (\"3 horas\")."
            +      ],
            +      "params": {
            +        "x": "Number: coordenada x da elipse do arco",
            +        "y": "Number: coordenada y da elipse do arco",
            +        "w": "Number: largura da elipse do arco por padrão",
            +        "h": "Number: altura da elipse do arco por padrão",
            +        "start": "Number: ângulo para iniciar o arco, especificado em radianos",
            +        "stop": "Number: ângulo para terminar o arco, especificado em radianos",
            +        "mode": "Constant: (Optional) parâmetro opcional para determinar como desenhar o arco, CHORD, PIE ou OPEN",
            +        "detail": "Integer: (Optional) parâmetro opcional apenas para WebGL. Serve para especificar o número de vertices que compõem o perímetro do arco. O valor padrão é 25. O detalhe máximo é de 50."
            +      }
            +    },
            +    "ellipse": {
            +      "description": [
            +        "Desenha uma elipse na tela. Por padrão, os primeiros dois parâmetros configuram a localização do centro da elipse, o terceiro e o quarto parâmetros definem a altura e a largura da geometria. Se nenhuma altura for definida, o padrão é utilizar o mesmo valor da largura. Se o valor for negativo, o valor absoluto será utilizado. ",
            +        "Uma elipse que possui a altura igual à largura é um círculo. A origem pode ser definida pela função <a href=\"#/p5/ellipseMode\">ellipseMode()</a>."
            +      ],
            +      "params": {
            +        "x": "Number: coordenada x do centro da elipse.",
            +        "y": "Number: coordenada y do centro da elipse.",
            +        "w": "Number: largura da elipse.",
            +        "h": "Number: (Optional) altura da elipse.",
            +        "detail": "Integer: (Optional) parâmetro opcional apenas para WebGL. Serve para especificar o número de vertices que compõem o perímetro da elipse. O valor padrão é 25. O detalhe máximo é de 50."
            +      }
            +    },
            +    "circle": {
            +      "description": [
            +        "Desenha um círculo na tela. O círculo é uma geometria simples e fechada. Seu ponto de referência é o centro. Essa função é um caso especial da ellipse(), onde a largura e a altura da elipse são iguais. A altura e a largura da elipse correspondem ao diâmetro do círculo. Por padrão, os 2 primeiros parâmetros configuram a localização do centro do círculo, o terceiro define o diâmetro."
            +      ],
            +      "params": {
            +        "x": "Number: coordenada x do centro do círculo.",
            +        "y": "Number: coordenada y do centro do círculo.",
            +        "d": "Number: diameter of the circle."
            +      }
            +    },
            +    "line": {
            +      "description": [
            +        "Desenha uma linha (um caminho direto entre dois pontos) na tela. Se criada com apenas 4 parâmetros, desenhará uma linha em 2D com a largura padrão de 1 pixel. Essa largura pode ser modificada usando a função <a href=\"#/p5/strokeWeight\"> strokeWeight()</a>. Uma linha não pode ser preenchida, logo a função <a href=\"#/p5/fill\">fill()</a> não afetará a cor da linha. Para definir a cor de uma linha use a função <a href=\"#/p5/stroke\">stroke()</a>."
            +      ],
            +      "params": {
            +        "x1": "Number: a coordenada x do primeiro ponto",
            +        "y1": "Number: a coordenada y do primeiro ponto",
            +        "x2": "Number: a coordenada x do segundo ponto",
            +        "y2": "Number: a coordenada y do segundo ponto",
            +        "z1": "Number: a coordenada z do primeiro ponto",
            +        "z2": "Number: a coordenada z do segundo ponto"
            +      }
            +    },
            +    "point": {
            +      "description": [
            +        "Desenha um ponto, uma coordenada no espaço com a dimensão de um pixel. O primeiro parâmetro é o valor da horizontal, o segundo é da vertical. A cor do ponto é definida pela função <a href=\"#/p5/stroke\">stroke()</a>. O tamanho do ponto pode ser definido pela função <a href=\"#/p5/strokeWeight\">strokeWeight()</a>."
            +      ],
            +      "params": {
            +        "x": "Number: a coordenada x",
            +        "y": "Number: a coordenada y",
            +        "z": "Number: (Optional) a coordenada z (para WebGL )",
            +        "coordinate_vector": "p5.Vector: o vetor da coordenada"
            +      }
            +    },
            +    "quad": {
            +      "description": [
            +        "Desenha um quadrilátero na canvas. Similar ao retângulo mas os ângulos não são necessariamente 90 graus. O primeiro par de parâmetros (x1,y1) define o primeiro vértice, os pares subsequentes vão em sentido horário ou anti-horário. Argumentos no eixo z funcionam apenas quando o quad() está em WEBGL."
            +      ],
            +      "params": {
            +        "x1": "Number: a coordenada x do primeiro ponto",
            +        "y1": "Number: a coordenada y do primeiro ponto",
            +        "x2": "Number: a coordenada x do segundo ponto",
            +        "y2": "Number: a coordenada y do segundo ponto",
            +        "x3": "Number: a coordenada x do terceiro ponto",
            +        "y3": "Number: a coordenada y do terceiro ponto",
            +        "x4": "Number: a coordenada x do quarto ponto",
            +        "y4": "Number: a coordenada y do quarto ponto",
            +        "detailX": "Integer: (Optional) número de segmentos na direção x",
            +        "detailY": "Integer: (Optional) número de segmentos na direção y",
            +        "z1": "Number: a coordenada z do primeiro ponto",
            +        "z2": "Number: a coordenada z do segundo ponto",
            +        "z3": "Number: a coordenada z do terceiro ponto",
            +        "z4": "Number: a coordenada z do quarto ponto"
            +      }
            +    },
            +    "rect": {
            +      "description": [
            +        "Desenha um retângulo na canvas. O retângulo é uma geometria de quatro lados com todos os ângulos iguais a 90 graus. Por padrão, os dois primeiros parâmetros configuram a localização do canto superior esquerdo, o terceiro define a largura e o quarto define a altura. A maneira em que esses parâmetros são interpretados pode ser modificada pela função <a href=\"#/p5/rectMode\">rectMode()</a>. ",
            +        "O quinto, sexto, sétimo e oitavo parâmetros, se especificados, determinam o raio dos cantos superiores esquerdo e direito e dos inferiores esquerdo e direito, respectivamente. Um raio de canto omitido utilizará o valor anteriormente especificado na lista de parâmetros."
            +      ],
            +      "params": {
            +        "x": "Number: coordenada x do retângulo.",
            +        "y": "Number: coordenada y do retângulo.",
            +        "w": "Number: largura do retângulo.",
            +        "h": "Number: (Optional) altura do retângulo.",
            +        "tl": "Number: (Optional) raio do canto superior esquerdo.",
            +        "tr": "Number: (Optional) raio do canto superior direito.",
            +        "br": "Number: (Optional) raio do canto inferior direito.",
            +        "bl": "Number: (Optional) raio do canto inferior esquerdo.",
            +        "detailX": "Integer: (Optional) número de segmentos na direção x (para WebGL)",
            +        "detailY": "Integer: (Optional) número de segmentos na direção y (para WebGL)"
            +      }
            +    },
            +    "square": {
            +      "description": [
            +        "Desenha um quadrado na tela. Um quadrado é uma geometria de quatro lados com todos os ângulos iguais a 90 graus e todos os lados do mesmo tamanho. Essa função é um caso especial da função rect(), onde a largura e a altura são iguais e o parâmetro \"s\" define o tamamho do lado. Por padrão, os primeiros dois parâmetros definem a localização do canto superior esquerdo, o terceiro define o tamanho do lado do quadrado. A maneira em que esses parâmetros são interpretados podem ser modificados pela função <a href=\"#/p5/rectMode\">rectMode()</a> . ",
            +        "O quarto, quinto, sexto e sétimo parâmetros, se especificados, determinam o raio dos cantos superiores esquerdo e direito e dos inferiores esquerdo e direito, respectivamente. Um raio de canto omitido utilizará o valor anteriormente especificado na lista de parâmetros."
            +      ],
            +      "params": {
            +        "x": "Number: coordenada x do quadrado.",
            +        "y": "Number: coordenada y do quadrado.",
            +        "s": "Number: tamanho do lado do quadrado.",
            +        "tl": "Number: (Optional) raio do canto superior esquerdo.",
            +        "tr": "Number: (Optional) raio do canto superior direito.",
            +        "br": "Number: (Optional) raio do canto inferior direito.",
            +        "bl": "Number: (Optional) raio do canto inferior esquerdo."
            +      }
            +    },
            +    "triangle": {
            +      "description": [
            +        "Desenha um triângulo na canvas. Um triângulo é um plano criado pela ligação de três pontos. Os primeiros dois argumentos especificam o primeiro ponto, os dois argumentos do meio especificam o segundo ponto e os dois últimos argumentos especificam o terceiro ponto."
            +      ],
            +      "params": {
            +        "x1": "Number: coordenada x do primeiro ponto",
            +        "y1": "Number: coordenada y do primeiro ponto",
            +        "x2": "Number: coordenada x do segundo ponto",
            +        "y2": "Number: coordenada y do segundo ponto",
            +        "x3": "Number: coordenada x do terceiro ponto",
            +        "y3": "Number: coordenada y do terceiro ponto"
            +      }
            +    },
            +    "ellipseMode": {
            +      "description": [
            +        "Modifica a localização de onde as elipses são desenhadas através da mudança da forma em que <a href=\"#/p5/ellipse\">ellipse()</a>, <a href=\"#/p5/circle\">circle()</a> e <a href=\"#/p5/arc\">arc()</a> são interpretadas. ",
            +        "O modo padrão é CENTER, em que os dois primeiros parâmetros são interpretados como x e y do centro da geometria, enquanto o terceiro e quarto parâmetros são sua largura e altura. ",
            +        "ellipseMode(RADIUS) também usa os dois primeiros parâmetros para definir o x e o y do centro da geometria, mas usa o terceiro e o quarto parâmetros para especificar a metade da largura e da altura da geometria. ",
            +        "ellipseMode(CORNER) interpreta os dois primeiros parâmetros como o canto superior esquerdo da geometria, enquanto o terceiro e o quarto parâmetros são sua largura e altura. ",
            +        "ellipseMode(CORNERS) interpreta os dois primeiros parâmetros como a localização de um canto da elipse que é utilizada como bounding box, o terceiro e o quarto parâmetros são a localização do canto oposto. ",
            +        "O parâmetro para este método deve ser escrito em CAPS porque eles são predefinidos como constantes e Javascript é uma linguagem que diferencia maiúsculas de minúsculas (case-sensitive)."
            +      ],
            +      "params": {
            +        "mode": "Constant: ou CENTER, RADIUS, CORNER, ou CORNERS"
            +      }
            +    },
            +    "noSmooth": {
            +      "description": [
            +        "Mostra toda a geometria com os contornos serrilhados. Note que <a href=\"#/p5/smooth\">smooth()</a> é ativado por padrão no modo 2D, logo, é necessário chamar <a href=\"#/p5/noSmooth\">noSmooth()</a> para desabilitar a suavização da geometria, imagens e fontes. No modo 3D, <a href=\"#/p5/noSmooth\">noSmooth()</a> está ativado por padrão, logo, é necessário chamar <a href=\"#/p5/smooth\">smooth()</a> se você quiser uma geometria suavizada (antialiased) no seu contorno."
            +      ]
            +    },
            +    "rectMode": {
            +      "description": [
            +        "Modifica a localização de onde os retângulos são criados através da mudança da maneira em que os parâmetros <a href=\"#/p5/rect\">rect()</a> são interpretados. ",
            +        "O modo padrão é CORNER, que interpretada os primeiros dois parâmetros como o canto superior esquerdo da shape, enquanto o terceiro e o quarto parâmetros são sua largura e altura. ",
            +        "rectMode(CORNERS) interpreta os dois primeiros parâmetros como a localização de um dos cantos e o segundo e terceiro parâmetros como a localização do canto diagonalmente oposto. Note que o retângulo é criado entre as coordenadas, não sendo necessário que o primeiro canto seja o superior esquerdo. ",
            +        "rectMode(CENTER) interpreta os dois primeiros parâmetros como o ponto central da shape, enquanto o terceiro e o quarto parâmetros são sua largura e altura. ",
            +        "rectMode(RADIUS) também usa os dois primeiros parâmetros como o ponto central da shape, mas usa o terceiro e quarto parâmetros para especificar metade da largura e da altura. ",
            +        "O parâmetro para este método deve ser escrito em CAPS porque eles são predefinidos como constantes e Javascript é uma linguagem que diferencia maiúsculas de minúsculas (case-sensitive)."
            +      ],
            +      "params": {
            +        "mode": "Constant: ou CORNER, CORNERS, CENTER, ou RADIUS"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "Desenha todas as geometrias com as boardas suavizadas (antialiased). <a href=\"#/p5/smooth\">smooth()</a> também melhorará a qualidade de uma imagem redimensionada. Leve em consideração que <a href=\"#/p5/smooth\">smooth()</a> está ativado por padrão no modo 2D; <a href=\"#/p5/noSmooth\">noSmooth()</a> também pode ser utilizado para desabilitar a suavização de uma geometria, imagem ou fonte. No modo 3D <a href=\"#/p5/noSmooth\">noSmooth()</a> está ligado por padrão, logo, é necessário usar <a href=\"#/p5/smooth\">smooth()</a> se você quiser suavizar (antialiased) as bordas da geometria."
            +      ]
            +    },
            +    "strokeCap": {
            +      "description": [
            +        "Define o estilo de renderização das pontas das linhas. Essas pontas são ou arredondadas, quadradas ou extendidas, e são especificadas com estes parâmetros: ROUND, SQUARE e PROJECT. O padrão é ROUND. ",
            +        "O parâmetro para este método deve ser escrito em CAPS porque eles são predefinidos como constantes e Javascript é uma linguagem que diferencia maiúsculas de minúsculas (case-sensitive)."
            +      ],
            +      "params": {
            +        "cap": "Constant: ou ROUND, SQUARE ou PROJECT"
            +      }
            +    },
            +    "strokeJoin": {
            +      "description": [
            +        "Define o estilo das conexões entre os segmentos de linha. Estas conexões são retas, chanfradas ou arredondadas, e são especificadas com estes parâmetros: MITER, BEVEL and ROUND. The default joint is MITER. ",
            +        "O parâmetro para este método deve ser escrito em CAPS porque eles são predefinidos como constantes e Javascript é uma linguagem que diferencia maiúsculas de minúsculas (case-sensitive)."
            +      ],
            +      "params": {
            +        "join": "Constant: ou MITER, BEVEL ou ROUND"
            +      }
            +    },
            +    "strokeWeight": {
            +      "description": [
            +        "Define a largura do contorno utilizado para as linhas, pontos e bordas de geometrias. Todas as larguras são definidas em pixels."
            +      ],
            +      "params": {
            +        "weight": "Number: a largura do contorno (em pixels)"
            +      }
            +    },
            +    "bezier": {
            +      "description": [
            +        "Cria uma curva de Bezier cúbico. Estas curvas são definidas por uma série de pontos âncora e de controle. Os dois primeiros parâmetros especificam o primeiro ponto âncora e os dois últimos parâmetros definem o outro ponto âncora, que se tornam o primeiro e último pontos da cuva. Os parâmetros do meio especificam dois pontos de controle que definem a forma da curva. Os pontos de controle \"puxam\" a curva em direção a eles. ",
            +        "As curvas Bezier foram desenvolvidas pelo engenheiro automotivo francês Pierre Bezier e são utilizadas geralmente em gráficos de computador para definir curvas suaves. Veja também <a href=\"#/p5/curve\">curve()</a>."
            +      ],
            +      "params": {
            +        "x1": "Number: coordenada x para o primeiro ponto âncora",
            +        "y1": "Number: coordenada y para o primeiro ponto âncora",
            +        "x2": "Number: coordenada x para o primeiro ponto de controle",
            +        "y2": "Number: coordenada y para o primeiro ponto de controle",
            +        "x3": "Number: coordenada x para o segundo ponto de controle",
            +        "y3": "Number: coordenada y para o segundo ponto de controle",
            +        "x4": "Number: coordenada x para o segundo ponto âncora",
            +        "y4": "Number: coordenada y para o segundo ponto âncora",
            +        "z1": "Number: coordenada z para o primeiro ponto âncora",
            +        "z2": "Number: coordenada z para o primeiro ponto de controle",
            +        "z3": "Number: coordenada z para o segundo ponto de controle",
            +        "z4": "Number: coordenada z para o segundo ponto âncora"
            +      }
            +    },
            +    "bezierDetail": {
            +      "description": [
            +        "Define a resolução em que a curva Bezier é mostrada. O valor padrão é 20. ",
            +        "Leve em consideração que essa função só é útil quando estiver renderizando em WEBGL, a canvas padrão não usa essa informação."
            +      ],
            +      "params": {
            +        "detail": "Number: resolução das curvas"
            +      }
            +    },
            +    "bezierPoint": {
            +      "description": [
            +        "Dadas as coordenadas x ou y dos pontos de controle e dos pontos âncora de uma curva bezier, esse parâmetro avalia as coordenadas bezier na posição t. Os parâmetros a e d são as coordenadas x ou y do primeiro e do último pontos na curva, enquanto b e c são os pontos de controle. O último parâmetro é a posição do ponto resultante, representado por um valor entre 0 e 1. Isso pode ser feito primeiramente com as coordenadas x e em uma segunda vez com as coordenadas y para identificar a posição de uma curva bezier em t."
            +      ],
            +      "returns": "Number: o valor de Bezier na posição t",
            +      "params": {
            +        "a": "Number: coordenada do primeiro ponto da curva",
            +        "b": "Number: coordenada do primeiro ponto de controle",
            +        "c": "Number: coordenada do segundo ponto de controle",
            +        "d": "Number: coordenada do segundo ponto da curva",
            +        "t": "Number: valor entre 0 e 1"
            +      }
            +    },
            +    "bezierTangent": {
            +      "description": [
            +        "Avalia a tangente ao Bezier na posição t para os pontos a, b, c, d. Os parâmetros a e d são o primeiro e último pontos na curva, b e c são os pontos de controle. O último parâmetro t varia entre 0 e 1."
            +      ],
            +      "returns": "Number: a tangente na posição t",
            +      "params": {
            +        "a": "Number: coordenada do primeiro ponto da curva",
            +        "b": "Number: coordenada do primeiro ponto de controle",
            +        "c": "Number: coordenada do segundo ponto de controle",
            +        "d": "Number: coordenada do segundo ponto da curva",
            +        "t": "Number: valor entre 0 e 1"
            +      }
            +    },
            +    "curve": {
            +      "description": [
            +        "Cria uma linha curva entre dois pontos, dada pelos quatro parâmetros do meio. Os dois primeiros parâmetros são um ponto de controle, como se a curva viesse desse ponto mesmo ele não aparecendo na tela. Os dois últimos parâmetros similarmente descrevem o outro ponto de controle.",
            +        "Curvas mais longas podem ser criadas usando uma série de funções <a href=\"#/p5/curve\">curve()</a> em conjunto ou usando <a href=\"#/p5/curveVertex\">curveVertex()</a>. Uma função adicionada chamada <a href=\"#/p5/curveTightness\">curveTightness()</a> faz o controle da qualidade visual da curva. A função <a href=\"#/p5/curve\">curve()</a> é uma implementação de splines Catmull-Rom."
            +      ],
            +      "params": {
            +        "x1": "Number: coordenada x do ponto de controle inicial",
            +        "y1": "Number: coordenada y do ponto de controle inicial",
            +        "x2": "Number: coordenada x do primeiro ponto",
            +        "y2": "Number: coordenada y do primeiro ponto",
            +        "x3": "Number: coordenada x do segundo ponto",
            +        "y3": "Number: coordenada y do segundo ponto",
            +        "x4": "Number: coordenada x do ponto de controle final",
            +        "y4": "Number: coordenada y do ponto de controle final",
            +        "z1": "Number: coordenada z do ponto de controle inicial",
            +        "z2": "Number: coordenada z do primeiro ponto",
            +        "z3": "Number: coordenada z do segundo ponto",
            +        "z4": "Number: coordenada z do ponto de controle final"
            +      }
            +    },
            +    "curveDetail": {
            +      "description": [
            +        "Define a resolução em que a curva será mostrada. O valor padrão é 20, enquanto o valor mínimo é 3. ",
            +        "Esta função só é útil quando estiver usando o WEBGL renderer, já que o renderer padrão não usa essa informação."
            +      ],
            +      "params": {
            +        "resolution": "Number: resolução das curvas"
            +      }
            +    },
            +    "curveTightness": {
            +      "description": [
            +        "Modifica a qualidade das formas criadas com <a href=\"#/p5/curve\">curve()</a> e <a href=\"#/p5/curveVertex\">curveVertex()</a>. O parâmetro tightness determina como a curva se encaixa nos pontos de vértice. O valor padrão é 0.0 (esse valor define as curvas como splines Catmull-Rom) e o valor 1.0 conecta todos os pontos com linhas retas. Valores no intervalo entre -5.0 e 5.0 vão deformar as curvas mas ainda deixaram elas reconhecíveis, ao aumentar a magnitude dos valores eles continuarão a deformar."
            +      ],
            +      "params": {
            +        "amount": "Number: quantidade de deformação dos vértices originais"
            +      }
            +    },
            +    "curvePoint": {
            +      "description": [
            +        "Avalia a curva na posição t para os pontos a, b, c, d. O parâmetro t varia entre 0 e 1, a e d são os pontos de controle da curva, b e c são os pontos de início e de final da curva. Isso pode ser feito primeiramente com as coordenadas x e em uma segunda vez com as coordenadas y para identificar a posição de uma curva bezier em t."
            +      ],
            +      "returns": "Number: valor bezier na posição t",
            +      "params": {
            +        "a": "Number: coordenada do primeiro ponto de controle da curva",
            +        "b": "Number: coordenada do primeiro ponto",
            +        "c": "Number: coordenada do segundo ponto",
            +        "d": "Number: coordenada do segundo ponto de controle da curva",
            +        "t": "Number: valor entre 0 e 1"
            +      }
            +    },
            +    "curveTangent": {
            +      "description": [
            +        "Avalia a curva na posição t para os pontos a, b, c, d. O parâmetro t varia entre 0 e 1, a e d são os pontos da curva, b e c são os pontos de controle."
            +      ],
            +      "returns": "Number: a tangente na posição t",
            +      "params": {
            +        "a": "Number: coordenada do primeiro ponto de controle",
            +        "b": "Number: coordenada do primeiro ponto na curva",
            +        "c": "Number: coordenada do segundo ponto na curva",
            +        "d": "Number: coordenada do segundo ponto de controle",
            +        "t": "Number: valor entre 0 e 1"
            +      }
            +    },
            +    "beginContour": {
            +      "description": [
            +        "Use as funções <a href=\"#/p5/beginContour\">beginContour()</a> e <a href=\"#/p5/endContour\">endContour()</a> para criar formas negativas dentro de outras formas, como o a do centro da letra 'O'. <a href=\"#/p5/beginContour\">beginContour()</a> inicia a gravação de vértices para a forma e <a href=\"#/p5/endContour\">endContour()</a> termina a gravação. O vértice que define a forma negativa deve \"girar\" na direção oposta da forma exterior. Primeiro desenhar os vértices para o exterior no sentido horário, e então, para as formas internas, desenhar os vértices no sentido anti-horário. ",
            +        "Estas funções só podem ser utilizadas com o par <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> e transformações como <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, e <a href=\"#/p5/scale\">scale()</a> não funciona com o par <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a>. Também não é possível usar outras formas, como a <a href=\"#/p5/ellipse\">ellipse()</a> ou <a href=\"#/p5/rect\">rect()</a>."
            +      ]
            +    },
            +    "beginShape": {
            +      "description": [
            +        "Usando as funções <a href=\"#/p5/beginShape\">beginShape()</a> e <a href=\"#/p5/endShape\">endShape()</a> permitem criar formas mais complexas. <a href=\"#/p5/beginShape\">beginShape()</a> inicia a gravação de vértices para a forma e <a href=\"#/p5/endShape\">endShape()</a> termina a gravação. O valor do tipo de parâmetro define que tipos de formas criar dos vértices providenciados. Se o modo não for especificado, a forma pode ser qualquer polígono irregular. ",
            +        "Os parâmetros disponíveis para <a href=\"#/p5/beginShape\">beginShape()</a> são POINTS, LINES, TRIANGLES, TRIANGLE_FAN, TRIANGLE_STRIP, QUADS, QUAD_STRIP, and TESS (apenas em WebGL). Após chamar a função <a href=\"#/p5/beginShape\">beginShape()</a>, uma série de comandos <a href=\"#/p5/vertex\">vertex()</a> devem ser providenciados. Para parar o desenho da forma, chame <a href=\"#/p5/endShape\">endShape()</a>. Cada forma será delineada com a cor de contorno vigente e preenchida com a cor de preenchimento vigente. ",
            +        "Transformações como <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, e <a href=\"#/p5/scale\">scale()</a> não funcionam com <a href=\"#/p5/beginShape\">beginShape()</a>. Também não é possível usar outras formas, como <a href=\"#/p5/ellipse\">ellipse()</a> ou <a href=\"#/p5/rect\">rect()</a> dentro de <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "kind": "Constante: (Opcional) either POINTS, LINES, TRIANGLES, TRIANGLE_FAN  TRIANGLE_STRIP, QUADS, QUAD_STRIP ou TESS"
            +      }
            +    },
            +    "bezierVertex": {
            +      "description": [
            +        "Especifica as coordenadas dos vértices para as curvas Bezier. Cada chamada do bezierVertex() define a posição de dois pontos de controle e um ponto âncora de uma curva Bezier, adicionando um novo segmento a uma linha ou forma. Para o modo WebGL, bezierVertex() pode ser usado tanto em 2D quando em 3D. O modo 2D espera 6 parâmetros, , enquanto o modo 3D espera 9 parâmetros (incluindo as coordenadas do eixo z). ",
            +        "Na primeira vez que bezierVertex() for usada com <a href=\"#/p5/beginShape\">beginShape()</a>, ela deve ser precedida com um <a href=\"#/p5/vertex\">vertex()</a> para definir o primeiro ponto âncora. Essa função pode ser usada entre <a href=\"#/p5/beginShape\">beginShape()</a> e <a href=\"#/p5/endShape\">endShape()</a> mas só quando não houver os parâmetros MODE ou POINTS especificados para <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "x2": "Number: coordenada x para o primeiro ponto de controle",
            +        "y2": "Number: coordenada y para o primeiro ponto de controle",
            +        "x3": "Number: coordenada x para o segundo ponto de controle",
            +        "y3": "Number: coordenada y para o segundo ponto de controle",
            +        "x4": "Number: coordenada x para o ponto âncora",
            +        "y4": "Number: coordenada y para o ponto âncora",
            +        "z2": "Number: coordenada z para o primeiro ponto de controle (para WebGL)",
            +        "z3": "Number: coordenada z para o segundo ponto de controle (para WebGL)",
            +        "z4": "Number: coordenada z para o ponto âncora (para WebGL)"
            +      }
            +    },
            +    "curveVertex": {
            +      "description": [
            +        "Especifica as coordenadas do vértices para as curvas. This function may only be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there is no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>. For WebGL mode curveVertex() can be used in 2D as well as 3D mode. 2D mode expects 2 parameters, while 3D mode expects 3 parameters. ",
            +        "The first and last points in a series of curveVertex() lines will be used to guide the beginning and end of a the curve. A minimum of four points is required to draw a tiny curve between the second and third points. Adding a fifth point with curveVertex() will draw the curve between the second, third, and fourth points. The curveVertex() function is an implementation of Catmull-Rom splines."
            +      ],
            +      "params": {
            +        "x": "Number: coordenada x do vértice",
            +        "y": "Number: coordenada y do vértice",
            +        "z": "Number: (Optional) coordenada z do vértice (for WebGL mode)"
            +      }
            +    },
            +    "endContour": {
            +      "description": [
            +        "Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a> begins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording. The vertices that define a negative shape must \"wind\" in the opposite direction from the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices shape in counter-clockwise. ",
            +        "These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within."
            +      ]
            +    },
            +    "endShape": {
            +      "description": [
            +        "The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be called after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data defined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image buffer. The constant CLOSE as the value for the MODE parameter to close the shape (to connect the beginning and the end)."
            +      ],
            +      "params": {
            +        "mode": "Constant: (Optional) use CLOSE to close the shape"
            +      }
            +    },
            +    "quadraticVertex": {
            +      "description": [
            +        "Specifies vertex coordinates for quadratic Bezier curves. Each call to quadraticVertex() defines the position of one control points and one anchor point of a Bezier curve, adding a new segment to a line or shape. The first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point. For WebGL mode quadraticVertex() can be used in 2D as well as 3D mode. 2D mode expects 4 parameters, while 3D mode expects 6 parameters (including z coordinates). ",
            +        "This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there is no MODE or POINTS parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "cx": "Number: x-coordinate for the control point",
            +        "cy": "Number: y-coordinate for the control point",
            +        "x3": "Number: x-coordinate para o ponto âncora",
            +        "y3": "Number: y-coordinate para o ponto âncora",
            +        "cz": "Number: z-coordinate for the control point (for WebGL mode)",
            +        "z3": "Number: z-coordinate para o ponto âncora (for WebGL mode)"
            +      }
            +    },
            +    "vertex": {
            +      "description": [
            +        "All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a> is used to specify the vertex coordinates for points, lines, triangles, quads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate do vértice",
            +        "y": "Number: y-coordinate do vértice",
            +        "z": "Number: z-coordinate do vértice",
            +        "u": "Number: (Optional) the vertex's texture u-coordinate",
            +        "v": "Number: (Optional) the vertex's texture v-coordinate"
            +      }
            +    },
            +    "VERSION": {
            +      "description": [
            +        "Version of this p5.js."
            +      ]
            +    },
            +    "P2D": {
            +      "description": [
            +        "The default, two-dimensional renderer."
            +      ]
            +    },
            +    "WEBGL": {
            +      "description": [
            +        "One of the two render modes in p5.js: P2D (default renderer) and WEBGL Enables 3D render by introducing the third dimension: Z"
            +      ]
            +    },
            +    "ARROW": {},
            +    "CROSS": {},
            +    "HAND": {},
            +    "MOVE": {},
            +    "TEXT": {},
            +    "WAIT": {},
            +    "HALF_PI": {
            +      "description": [
            +        "HALF_PI é uma constante matemática com o valor 1.57079632679489661923. É a metade da razão entre a circunferência de um círculo e seu diâmetro. É útil em combinação com as funções trigonométricas <a href=\"#/p5/sin\">sin()</a> e <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "PI": {
            +      "description": [
            +        "PI é uma constante matemática com o valor 3.14159265358979323846. É a razão entre a circunferência de um círculo e seu diâmetro. É útil em combinação com as funções trigonométricas <a href=\"#/p5/sin\">sin()</a> e <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "QUARTER_PI": {
            +      "description": [
            +        "QUARTER_PI é uma constante matemática com o valor 0.7853982. É um quarto da razão entre a circunferência de um círculo e seu diâmetro. É útil em combinação com as funções trigonométricas <a href=\"#/p5/sin\">sin()</a> e <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "TAU": {
            +      "description": [
            +        "TAU é uma abreviatura para TWO_PI, que é uma constante matemática com o valor 6.28318530717958647693. Equivale duas vezes a razão entre a circunferência de um círculo e seu diâmetro. É útil em combinação com as funções trigonométricas <a href=\"#/p5/sin\">sin()</a> e <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "TWO_PI": {
            +      "description": [
            +        "TWO_PI é uma constante matemática com o valor 6.28318530717958647693. Equivale duas vezes a razão entre a circunferência de um círculo e seu diâmetro. É útil em combinação com as funções trigonométricas <a href=\"#/p5/sin\">sin()</a> e <a href=\"#/p5/cos\">cos()</a>."
            +      ]
            +    },
            +    "DEGREES": {
            +      "description": [
            +        "Constante a ser usada com a função <a href=\"#/p5/angleMode\">angleMode()</a> , para definir o modo em que p5.js interpreta e calcula ângulos (GRAUS ou RADIANOS)."
            +      ]
            +    },
            +    "RADIANS": {
            +      "description": [
            +        "Constante a ser usada com a função <a href=\"#/p5/angleMode\">angleMode()</a> , para definir o modo em que p5.js interpreta e calcula ângulos (GRAUS ou RADIANOS)."
            +      ]
            +    },
            +    "CORNER": {},
            +    "CORNERS": {},
            +    "RADIUS": {},
            +    "RIGHT": {},
            +    "LEFT": {},
            +    "CENTER": {},
            +    "TOP": {},
            +    "BOTTOM": {},
            +    "BASELINE": {},
            +    "POINTS": {},
            +    "LINES": {},
            +    "LINE_STRIP": {},
            +    "LINE_LOOP": {},
            +    "TRIANGLES": {},
            +    "TRIANGLE_FAN": {},
            +    "TRIANGLE_STRIP": {},
            +    "QUADS": {},
            +    "QUAD_STRIP": {},
            +    "TESS": {},
            +    "CLOSE": {},
            +    "OPEN": {},
            +    "CHORD": {},
            +    "PIE": {},
            +    "PROJECT": {},
            +    "SQUARE": {},
            +    "ROUND": {},
            +    "BEVEL": {},
            +    "MITER": {},
            +    "RGB": {},
            +    "HSB": {
            +      "description": [
            +        "HSB (hue, saturation, brightness) is a type of color model. You can learn more about it at <a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>."
            +      ]
            +    },
            +    "HSL": {},
            +    "AUTO": {
            +      "description": [
            +        "AUTO allows us to automatically set the width or height of an element (but not both), based on the current height and width of the element. Only one parameter can be passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time."
            +      ]
            +    },
            +    "ALT": {},
            +    "BACKSPACE": {},
            +    "CONTROL": {},
            +    "DELETE": {},
            +    "DOWN_ARROW": {},
            +    "ENTER": {},
            +    "ESCAPE": {},
            +    "LEFT_ARROW": {},
            +    "OPTION": {},
            +    "RETURN": {},
            +    "RIGHT_ARROW": {},
            +    "SHIFT": {},
            +    "TAB": {},
            +    "UP_ARROW": {},
            +    "BLEND": {},
            +    "REMOVE": {},
            +    "ADD": {},
            +    "DARKEST": {},
            +    "LIGHTEST": {},
            +    "DIFFERENCE": {},
            +    "SUBTRACT": {},
            +    "EXCLUSION": {},
            +    "MULTIPLY": {},
            +    "SCREEN": {},
            +    "REPLACE": {},
            +    "OVERLAY": {},
            +    "HARD_LIGHT": {},
            +    "SOFT_LIGHT": {},
            +    "DODGE": {},
            +    "BURN": {},
            +    "THRESHOLD": {},
            +    "GRAY": {},
            +    "OPAQUE": {},
            +    "INVERT": {},
            +    "POSTERIZE": {},
            +    "DILATE": {},
            +    "ERODE": {},
            +    "BLUR": {},
            +    "NORMAL": {},
            +    "ITALIC": {},
            +    "BOLD": {},
            +    "BOLDITALIC": {},
            +    "LINEAR": {},
            +    "QUADRATIC": {},
            +    "BEZIER": {},
            +    "CURVE": {},
            +    "STROKE": {},
            +    "FILL": {},
            +    "TEXTURE": {},
            +    "IMMEDIATE": {},
            +    "IMAGE": {},
            +    "NEAREST": {},
            +    "REPEAT": {},
            +    "CLAMP": {},
            +    "MIRROR": {},
            +    "LANDSCAPE": {},
            +    "PORTRAIT": {},
            +    "GRID": {},
            +    "AXES": {},
            +    "LABEL": {},
            +    "FALLBACK": {},
            +    "print": {
            +      "description": [
            +        "A função <a href=\"#/p5/print\">print()</a> escreve uma mensagem no console do browser. Essa função é útil para que possamos observar os dados produzidos enquanto o programa está em execução — por exemplo, para verificar o valor de uma variável em um ponto específico do código. A função cria uma nova linha de texto a cada vez que é chamada. O argumento da função podem ser quaisquer valores válidos da linguagem, como cadeias de caracteres (strings / texto), números, variáveis, booleanos, objetos, arrays, expressões, etc.",
            +        "Para imprimir valores de tipos diferentes, podemos separá-los por vírgulas (,). Para juntar uma ou mais strings à variável que queremos verificar, como no exemplo acima, é possível utilizar o operador de adição (+) — que neste caso transforma o número em String. Por exemplo, podemos escrever <code>print(\"O valor de x é \" + x + \", e de y é \" + y)</code>.",
            +        "Também é possível utilizar <a href=\"https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Template_literals\" target=\"_blank\">template strings</a>, que é uma forma de escrever strings que permite embutir outros valores. Para tal, utilizamos acentos graves (``). Os caracteres são colocados entre os acentos, e quaisquer variáveis, expressões, ou outros valores que não strings são colocados após um cifrão, entre chaves (${}). O exemplo anterior fica: <code>print(`O valor de x é ${x}, e de y é ${y}`)</code>",
            +        "Note que chamar a função print() sem nenhum argumento invoca a função window.print(), que abre a janela de impressão do browser. Para escrever uma linha em branco no console, você pode escrever print(\"\\n\")."
            +      ],
            +      "params": {
            +        "contents": "Qualquer: qualquer sequência de números, Strings, objetos, booleanos ou array para escrever no console"
            +      }
            +    },
            +    "frameCount": {
            +      "description": [
            +        "A variável global <a href=\"#/p5/frameCount\">frameCount</a>, embutida na biblioteca p5.js, contém o número de quadros (frames) que foram mostrados desde que o programa iniciou. Dentro de <a href=\"#/p5/setup\">setup()</a> o valor é 0, depois da primeira iteração de <a href=\"#/p5/draw\">draw()</a> é 1, etc."
            +      ]
            +    },
            +    "deltaTime": {
            +      "description": [
            +        "A variável global <a href=\"#/p5/deltaTime\">deltaTime</a>, embutida na biblioteca p5.js, contém a diferença de tempo entre o início do quadro (frame) anterior e o início do quadro atual em milissegundos.",
            +        "Essa variável é útil para criar animações que dependem do tempo, ou cálculos de física que devam permanecem constantes mesmo que haja variação na taxa de quadros."
            +      ]
            +    },
            +    "focused": {
            +      "description": [
            +        "Confirma que a janela do sketch está em foco, ou seja, que ela irá aceitar interação de mouse ou teclado. Essa variável retorna <code>true</code> (verdadeiro) caso a janela esteja em foco, e <code>false</code> (falso) caso não esteja."
            +      ]
            +    },
            +    "cursor": {
            +      "description": [
            +        "Configura o cursor como uma imagem ou símbolo específico, ou o torna visível caso não esteja. Se você estiver buscando utilizar uma imagem como cursor, o tamanho recomendado é 16x16 ou 32x32 pixels. Os valores para os parâmetros x e y devem ser menores do que o tamanho da imagem."
            +      ],
            +      "params": {
            +        "type": "String|Constante: embutidas: ARROW, CROSS, HAND, MOVE, TEXT ou WAIT; propriedades nativas do CSS: 'grab', 'progress', 'cell', etc.; externas: endereço da imagem do cursor (extensões permitidas: .cur, .gif, .jpg, .jpeg, .png). Para mais informações em cursores nativos do CSS e URLs visite <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a>.",
            +        "x": "Número (opcional): o ponto ativo do cursor — o ponto em que ele clica — em relação ao eixo horizontal (precisa ser menor do que 32, e menor do que a imagem)",
            +        "y": "Número (opcional): o ponto ativo do cursor — o ponto em que ele clica — em relação ao eixo vertical (precisa ser menor do que 32, e menor do que a imagem)"
            +      }
            +    },
            +    "frameRate": {
            +      "description": [
            +        "Especifica a taxa de quadros, ou seja, o número de quadros (frames) a serem mostrados a cada segundo. Por exemplo, chamar a função <code>frameRate(30)</code> fará com que a canvas tente atualizar-se 30 vezes por segundo. Caso o processador não seja rápido o suficiente para manter a frequência especificada, a taxa de quadros não será atingida. É recomendado configurar a taxa de quadro dentro de <a href=\"#/p5/setup\">setup()</a>. A taxa de quadro padrão é baseada na taxa da tela (também conhecida como taxa de atualização), que na maioria dos computadores corresponde a 60 quadros por segundo (fps). Uma taxa de quadros igual ou superior a 24 quadros por segundo (valor típico de filmes) é suficiente para animações fluidas. Isto é o mesmo que <code>setFrameRate(valor)</code>",
            +        "Chamar <a href=\"#/p5/frameRate\">frameRate()</a> sem nenhum argumento, ou com argumentos que não sejam números positivos, retorna a taxa de quadros atual. A função draw() precisa rodar ao menos uma vez antes de retornar um valor. Isto é o mesmo que <a href=\"#/p5/getFrameRate\">getFrameRate()</a>."
            +      ],
            +      "params": {
            +        "fps": "Número: número de quadros a serem mostrados em um segundo"
            +      }
            +    },
            +    "noCursor": {
            +      "description": [
            +        "Esconde o cursor."
            +      ]
            +    },
            +    "displayWidth": {
            +      "description": [
            +        "Variável global embutida na biblioteca p5.js que armazena a largura da tela de acordo com a densidade de pixels (<a href=\"#/p5/pixelDensity\">pixelDensity</a>) padrão. Isto é utilizado para executar o programa em tela cheia independente do tamanho da tela. Para obter a largura real da tela, multiplique este número pela <a href=\"#/p5/pixelDensity\">pixelDensity</a>."
            +      ]
            +    },
            +    "displayHeight": {
            +      "description": [
            +        "Variável global embutida na biblioteca p5.js que armazena a altura da tela de acordo com a densidade de pixels (<a href=\"#/p5/pixelDensity\">pixelDensity</a>) padrão. Isto é utilizado para executar o programa em tela cheia independente do tamanho da tela. Para obter a altura real da tela, multiplique este número pela <a href=\"#/p5/pixelDensity\">pixelDensity</a>."
            +      ]
            +    },
            +    "windowWidth": {
            +      "description": [
            +        "Variável global embutida na biblioteca p5.js que armazena a largura interna da janela. É o mesmo que a propriedade window.innerWidth."
            +      ]
            +    },
            +    "windowHeight": {
            +      "description": [
            +        "Variável global embutida na biblioteca p5.js que armazena a altura interna da janela. É o mesmo que a propriedade window.innerHeight."
            +      ]
            +    },
            +    "windowResized": {
            +      "description": [
            +        "A função <a href=\"#/p5/windowResized\">windowResized()</a> é chamada a cada vez que a janela do browser muda de tamanho. É um bom lugar para redimensionar a canvas ou fazer quaisquer outros ajustes para acomodar o novo tamanho da janela."
            +      ],
            +      "params": {
            +        "event": "Objeto (opcional): argumentos do evento de callback."
            +      }
            +    },
            +    "width": {
            +      "description": [
            +        "Variável global embutida na biblioteca p5.js que armazena a largura da canvas. Este valor é definido pelo primeiro parâmetro da função <a href=\"#/p5/createCanvas\">createCanvas()</a>. Por exemplo, a chamada de função <code>createCanvas(320, 240)</code> atribui à variável <code>width</code> o valor 320. Se a função <a href=\"#/p5/createCanvas\">createCanvas()</a> não for chamada no programa, o valor padrão para a largura é 100."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "Variável global embutida na biblioteca p5.js que armazena a altura da canvas. Este valor é definido pelo segundo parâmetro da função <a href=\"#/p5/createCanvas\">createCanvas()</a>. Por exemplo, a chamada de função <code>createCanvas(320, 240)</code> atribui à variável <code>height</code> o valor 240. Se a função <a href=\"#/p5/createCanvas\">createCanvas()</a> não for chamada no programa, o valor padrão para a altura é 100."
            +      ]
            +    },
            +    "fullscreen": {
            +      "description": [
            +        "Se um argumento for passado, configura o sketch para telaa cheia baseado no valor deste argument. Caso contrário, retorna se o sketch está em tela cheia ou não. Note que, dado as restrições dos browsers, só é possível chamar essa função a partir de interação direta como, por exemplo, o clique do mouse."
            +      ],
            +      "returns": "Booleano: se o sketch está em tela cheia (true) ou não (false)",
            +      "params": {
            +        "val": "Boolean (opcional): se o sketch deve rodar em tela cheia (true) ou não (false)"
            +      }
            +    },
            +    "pixelDensity": {
            +      "description": [
            +        "Define a escala dos pixels para telas de alta densidade. Por padrão, a densidade de pixels é igual a densidade da tela — chame <code>pixelDensity(1)</code> para que isso não aconteça. Chamar <a href=\"#/p5/pixelDensity\">pixelDensity()</a> sem argumentos retorna a densidade de pixels atual do sketch."
            +      ],
            +      "params": {
            +        "val": "Número: se ou quanto o sketch deve ser redimensionado"
            +      }
            +    },
            +    "displayDensity": {
            +      "description": [
            +        "Retorna a densidade de pixels da tela em que o sketch está sendo executado."
            +      ],
            +      "returns": "Número: densidade de pixels da tela"
            +    },
            +    "getURL": {
            +      "description": [
            +        "Retorna a URL atual.",
            +        "Nota: ao utilizar o editor da p5, essa função retornará um objeto vazio, pois o objeto está embutido em uma iFrame. Ela funcionará corretamente se você visualizar o sketch utilizando o modo de apresentação, ou URLs compartilháveis."
            +      ],
            +      "returns": "String: URL"
            +    },
            +    "getURLPath": {
            +      "description": [
            +        "Retorna o caminho da URL atual como uma array.",
            +        "Nota: ao utilizar o editor da p5, essa função retornará um objeto vazio, pois o objeto está embutido em uma iFrame. Ela funcionará corretamente se você visualizar o sketch utilizando o modo de apresentação, ou URLs compartilháveis."
            +      ],
            +      "returns": "String[]: os componentes do caminho da URL"
            +    },
            +    "getURLParams": {
            +      "description": [
            +        "Retorna os parâmetros da URL atual como um objeto.",
            +        "Nota: ao utilizar o editor da p5, essa função retornará um objeto vazio, pois o objeto está embutido em uma iFrame. Ela funcionará corretamente se você visualizar o sketch utilizando o modo de apresentação, ou URLs compartilháveis."
            +      ],
            +      "returns": "Objeto: parâmetros da URL"
            +    },
            +    "preload": {
            +      "description": [
            +        "A função <a href=\"#/p5/preload\">preload()</a> é usada para lidar com o carregamento síncrono de arquivos externos de forma bloqueadora (blocking) e deve ser chamada diretamente antes de <a href=\"#/p5/setup\">setup()</a>. Quando há um bloco de <a href=\"#/p5/preload\">preload()</a> o restante do código esperará até que tudo nele seja concluído antes de ser executado. Observe que apenas chamadas de carregamento (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>, <a href=\"#/p5/loadStrings\">loadStrings</a> , etc.) devem estar dentro deste bloco, todas as outras inicializações devem acontecer no <a href=\"#/p5/setup\">setup()</a>. Os métodos de carregamento quando chamados fora de <a href=\"#/p5/preload\">preload()</a> ocorrem de forma assíncrona não bloqueadora (non-blocking), podendo haver nesse caso um parâmetro de <a href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#callbacks\">callback</a>. Mais informações sobre chamadas assíncronas e carregamento de arquivos <a href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#asynchronous-calls-and-file-loading\">aqui</a>.",
            +        "Por definição o texto \"loading...\" será exibido durante o carregamento dos arquivos. Para fazer sua própria página de carregamento, inclua um elemento HTML com <code>id=\"p5_loading\"</code> em sua página. Veja mais informações sobre como configurar sua tela de carregamento <a href=\"<a href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#loading-screen\">aqui</a>. "
            +      ]
            +    },
            +    "setup": {
            +      "description": [
            +        "A função <a href=\"#/p5/setup\">setup()</a> é chaada quando o programa começa. É utilizada para definir propriedades do ambiente como o tamanho da canvas e cor do a cor de fundo da canvas. Também pode conter chamadas de carregamento de mídias (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>, <a href=\"#/p5/loadStrings\">loadStrings</a>, etc.). Só pode haver um bloco de <a href=\"#/p5/setup\">setup()</a> por programa, não podendo ser chamado novamente após a execução inicial.",
            +        "Nota: váriaveis declaradas dentro de <a href=\"#/p5/setup\">setup()</a> não são acessíveis em outras funções, incluindo <a href=\"#/p5/draw\">draw()</a>."
            +      ]
            +    },
            +    "draw": {
            +      "description": [
            +        "A função <a href=\"#/p5/draw\">draw()</a>, geralmente chamada logo após o <a href=\"#/p5/setup\">setup()</a>, executa continuamente as linhas de código contidas dentro do bloco até que o programa seja interrompido. Atenção, <a href=\"#/p5/draw\">draw()</a> é chamada automaticamente e não deve ser chamada explicitamente. ",
            +        "Esta função pode ser controlada por <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. Para interromper a execução do código dentro de <a href=\"#/p5/draw\">draw()</a> deve ser utilizada a função <a href=\"#/p5/noLoop\">noLoop()</a>. Importante observar que se a função <a href=\"#/p5/noLoop\">noLoop()</a> for chamada dentro do bloco <a href=\"#/p5/setup\">setup()</a>, a função <a href=\"#/p5/draw\">draw()</a> será executada uma vez antes de ser interrompida. Com a execução de parada <a href=\"#/p5/draw\">draw()</a>, a função <a href=\"#/p5/redraw\">redraw()</a> faz com que o código dentro de <a href=\"#/p5/draw\">draw()</a> seja executado uma única vez. Já a função <a href=\"#/p5/loop\">loop()</a> fará com que o código volte a ser executado continuamente.",
            +        "A função <a href=\"#/p5/frameRate\">frameRate()</a> especifica a taxa de quadros por segundo, alterando o numero de vezes que a função <a href=\"#/p5/draw\">draw()</a> será executada por segundo. Por definição o valor do <a href=\"#/p5/frameRate\">frameRate()</a> é baseada na taxa da tela (também conhecida como taxa de atualização), que na maioria dos computadores corresponde a 60 quadros por segundo (fps).",
            +        "Atenção, só pode haver um bloco de <a href=\"#/p5/draw\">draw()</a> por sketch. Nâo é obrigatório que exista o bloco <a href=\"#/p5/draw\">draw()</a> no sketch, no entando, se você deseja que seu código seja executado continuamente ou se você deseja acionar eventos como <a href=\"#/p5/mousePressed\">mousePressed()</a>, é recomendado usar a função <a href=\"#/p5/draw\">draw()</a>. Por vezes poderá haver um chamada vazia de <a href=\"#/p5/draw\">draw()</a> em seu sketch, como mostrado no exemplo acima. ",
            +        "É importante lembrar que o sistema de coordenadas é resetado no início de cada chamada de <a href=\"#/p5/draw\">draw()</a>. Por isso, se alguma transformação for realizada dentro de <a href=\"#/p5/draw\">draw()</a> (ex: <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/translate\">translate()</a>), seus efeitos serão desfeitos na nova chamada e as transformações não serão acumuladas ao longo da execução do programa. Já os estilos aplicados (ex: <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, etc) permanecem na nova chamada."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Remove o sketch feito com P5.js completamente. Esta função remove todos os elementos criados com P5.js, inclusive a Canvas. Também para a execução de <a href=\"#/p5/draw\">draw()</a> e desvincula todas as propriedades e métodos vinculados ao objeto window no escopo global. A função deixa uma nova variável <code>p5</code> caso você queira criar um novo sketch com p5.js, caso contrário você pode configurar <code> p5 = null </code> para apagar a variável. Embora todas as funções, variáveis ​​e objetos criados pela biblioteca p5 sejam removidos, quaisquer outras variáveis ​​globais criadas por seu código permanecerão."
            +      ]
            +    },
            +    "disableFriendlyErrors": {
            +      "description": [
            +        "Desativa o Sistema de Erro Amigável (em inglês Friendly Errors Sistem ou FES) durante a criação do sketch. Quando você usa o arquivo p5.js não minimizado (no lugar de p5.min.js), há um sistema de erro amigável (FES) que irá avisá-lo, por exemplo, se você inserir argumentos inesperados em uma função. Este sistema de verificação de erros pode reduzir significativamente a velocidade do seu código (até ~ 10x em alguns casos), por isso desativar o FES pode melhorar o desempenho quando for preciso. Veja mais informaçãos sobre a desabilitação do FES <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'> aqui</a>."
            +      ]
            +    },
            +    "let": {
            +      "description": [
            +        "Cria e nomeia uma nova variável. Uma variável é um contêiner para um valor.",
            +        "Variáveis que são declaradas com <a href=\"#/p5/let\">let</a> terão escopo de bloco. Isso significa que a variável só existe dentro do <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> bloco</a> em que foi criada.",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\"> entrada MDN</a>: Declara uma variável local de escopo de bloco, opcionalmente inicializando-a com um valor."
            +      ]
            +    },
            +    "const": {
            +      "description": [
            +        "Cria e nomeia uma nova constante. Como uma variável criada com <a href=\"#/p5/let\">let</a>, uma constante que é criada com <a href=\"#/p5/const\">const</a> é um contêiner para um valor, no entanto, as constantes não podem ser reatribuídas depois de declaradas. Embora seja digno de nota que, para tipos de dados não primitivos, como objetos e arrays, seus elementos ainda podem ser mutáveis. Portanto, se uma variável é atribuída a um array, você ainda pode adicionar ou remover elementos do array, mas não pode reatribuir outro array a ele. Ainda, ao contrário de <code>let</code>, você não pode declarar variáveis sem valor usando const. ",
            +        "Constantes têm escopo de bloco. Isso significa que a constante só existe dentro do <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> bloco</a> em que é criada. Uma constante não pode ser declarada novamente dentro de um escopo no qual já existe. ",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">entrada MDN</a>: Declara uma constante nomeada somente para leitura. As constantes têm escopo de bloco, muito parecido com as variáveis definidas usando a instrução 'let'. O valor de uma constante não pode ser alterado por meio de reatribuição e não pode ser declarado novamente."
            +      ]
            +    },
            +    "===": {
            +      "description": [
            +        "O operador de igualdade estrita <a href=\"#/p5/===\">===</a> verifica se dois valores são iguais e do mesmo tipo. ",
            +        "Uma expressão de comparação sempre avalia como um <a href=\"#/p5/boolean\">booleano</a>. ",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">entrada MDN</a>: O operador de não identidade retorna true (verdadeiro) se os operandos não são iguais e / ou não são do mesmo tipo. ",
            +        "Observação: em alguns exemplos na web, você pode ver um sinal de igual duplo <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>, usado para comparação. Este é o operador de igualdade não estrita em Javascript. Ele converterá os dois valores que estão sendo comparados ao mesmo tipo antes de compará-los."
            +      ]
            +    },
            +    ">": {
            +      "description": [
            +        "O operador maior que <a href=\"#/p5/>\">></a> é avaliado como true (verdadeiro) se o valor à esquerda for maior que o valor à direita. <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">Mais informações sobre operadores de comparação no MDN.</a>"
            +      ]
            +    },
            +    ">=": {
            +      "description": [
            +        "O operador maior que ou igual a <a href=\"#/p5/>=\">>=</a> avalia como true (verdadeiro) se o valor da esquerda for maior ou igual ao valor da direita. ",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">Mais informações sobre operadores de comparação no MDN.</a>"
            +      ]
            +    },
            +    "<": {
            +      "description": [
            +        "O operador menor que <a href=\"#/p5/<\"><</a> avalia como true (verdadeiro) se o valor à esquerda for menor que o valor à direita. ",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">Mais informações sobre operadores de comparação no MDN.</a>"
            +      ]
            +    },
            +    "<=": {
            +      "description": [
            +        "O operador menor que ou igual a <a href=\"#/p5/<=\"><=</a> avalia como true  (verdadeiro) se o valor esquerdo for menor ou igual ao valor direito. ",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">Mais informações sobre operadores de comparação no MDN.</a>"
            +      ]
            +    },
            +    "if-else": {
            +      "description": [
            +        "A declaração <a href=\"#/p5/if-else\">if-else</a> (se/senão) ajuda a controlar o fluxo do seu código. ",
            +        "Uma condição é colocada entre parênteses após 'if' (se), quando essa condição é avaliada como <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">verdade</a>, o código entre as chaves seguintes é executado. Alternativamente, quando a condição é avalia como <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsa</a>, o código entre as chaves do bloco 'else' é executado em seu lugar. Escrever um bloco else é opcional. ",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">entrada MDN</a>: A declaração 'if' executa uma instrução se uma condição especificada for verdadeira. Se a condição for falsa, outra instrução pode ser executada."
            +      ]
            +    },
            +    "function": {
            +      "description": [
            +        "Cria e nomeia uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">função</a>. Uma <a href=\"#/p5/function\">função</a> é um conjunto de instruções que executam uma tarefa. ",
            +        "Opcionalmente, as funções podem ter parâmetros. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parâmetros</a> são variáveis que têm como escopo a função, que podem receber um valor ao chamar a função. Vários parâmetros podem ser dados separados por vírgulas. ",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">entrada MDN</a>: Declara uma função com os parâmetros especificados."
            +      ]
            +    },
            +    "return": {
            +      "description": [
            +        "Especifica o valor a ser retornado por uma função. Para obter mais informações, verifique <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">a entrada MDN para return</a>."
            +      ]
            +    },
            +    "boolean": {
            +      "description": [
            +        "Converte um número ou string em sua representação booleana. Para um número, qualquer valor diferente de zero (positivo ou negativo) é avaliado como true (verdadeiro), enquanto zero é avaliado como false (falso). Para uma string, o valor \"true \" é avaliado como verdadeiro, enquanto qualquer outro valor é avaliado como falso. Quando uma array de números ou valores de string é passada, então uma array de booleanos do mesmo comprimento é retornada."
            +      ],
            +      "returns": "Booleano: representação booleana de valor",
            +      "params": {
            +        "n": "String|Booleano|Número|Array: valor para analisar"
            +      }
            +    },
            +    "string": {
            +      "description": [
            +        "Uma <a href=\"#/p5/string\">string</a> é um dos 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">tipos de dados primitivos</a> em Javascript. Uma string é uma série de caracteres de texto. Em Javascript, um valor de string deve estar entre aspas simples (') ou aspas duplas (\"). ",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">entrada MDN</a>: Uma string é uma sequência de caracteres usada para representar texto."
            +      ]
            +    },
            +    "number": {
            +      "description": [
            +        "Um <a href=\"#/p5/number\">número</a> é um dos 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">tipos de dados primitivos</a> em Javascript. Um number pode ser um número inteiro ou decimal. ",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">A entrada MDN para um número</a>"
            +      ]
            +    },
            +    "object": {
            +      "description": [
            +        "A partir de um <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">objeto básico de MDN</a>:  Um <a href=\"#/p5/object\">objeto</a> é uma coleção de dados relacionados e/ou funcionalidades (que geralmente consistem em várias variáveis e funções - que são chamadas de propriedades e métodos quando estão dentro de objetos.)"
            +      ]
            +    },
            +    "class": {
            +      "description": [
            +        "Cria e nomeia uma <a href=\"#/p5/class\">classe</a> que é um modelo para a criação de <a href=\"#/p5/objects\">objetos</a>. ",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">entrada MDN</a>: A declaração de classe cria uma nova classe com um determinado nome usando herança baseada em protótipo."
            +      ]
            +    },
            +    "for": {
            +      "description": [
            +        "<a href=\"#/p5/for\">for</a> cria um loop que é útil para executar uma seção de código várias vezes. ",
            +        "Um 'loop for' consiste em três expressões diferentes entre parênteses, todas opcionais. Essas expressões são usadas para controlar o número de vezes que o loop é executado. A primeira expressão é uma instrução usada para definir o estado inicial para o loop. A segunda expressão é uma condição que você gostaria de verificar antes de cada loop. Se esta expressão retornar false (falso), então sairá do loop. A terceira expressão é executada no final de cada loop. Essas expressões são separadas por ; (ponto e vírgula). No caso de uma expressão vazia, apenas um ponto e vírgula é escrito. ",
            +        "O código dentro do corpo do loop (entre as chaves) é executado entre a avaliação da segunda e da terceira expressão.",
            +        "Como acontece com qualquer loop, é importante garantir que o loop possa 'sair' ou que a condição de teste acabe sendo avaliada como false (falsa). A condição de teste com um loop <a href=\"#/p5/for\">for</a> é a segunda expressão detalhada acima. Garantir que essa expressão possa eventualmente se tornar falsa garante que seu loop não tente ser executado uma quantidade infinita de vezes, o que pode travar seu navegador. ",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">entrada MDN</a>: Cria um loop que executa uma instrução especificada até que a condição de teste seja avaliada como falsa. A condição é avaliada após a execução da instrução, resultando na execução da instrução especificada pelo menos uma vez."
            +      ]
            +    },
            +    "while": {
            +      "description": [
            +        "<a href=\"#/p5/while\">while</a> (enquanto) cria um loop que é útil para executar uma seção de código várias vezes. ",
            +        "Com um 'loop while', o código dentro do corpo do loop (entre as chaves) é executado repetidamente até que a condição de teste (dentro dos parênteses) seja avaliada como false (falsa). A condição é testada antes de executar o corpo do código com <a href=\"#/p5/while\">while</a>, então, se a condição for inicialmente falsa, o corpo do loop, ou instrução, nunca serão executados. ",
            +        "Como acontece com qualquer loop, é importante garantir que o loop possa 'sair' ou que a condição de teste acabe sendo avaliada como falsa. Isso evita que seu loop tente ser executado uma quantidade infinita de vezes, o que pode travar seu navegador. ",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">entrada MDN</a>: A instrução while cria um loop que executa uma instrução especificada, desde que a condição de teste seja avaliada como true (verdadeira). A condição é avaliada antes de executar a instrução."
            +      ]
            +    },
            +    "createCanvas": {
            +      "description": [
            +        "Cria um elemento canvas no documento e define suas dimensões em pixels. Este método deve ser chamado apenas uma vez no início da configuração. Chamar <a href=\"#/p5/createCanvas\">createCanvas</a> mais de uma vez em um sketch resultará em um comportamento muito imprevisível. Se você quiser mais de um canvas de desenho, pode usar o <a href=\"#/p5/createGraphics\">createGraphics</a> (oculto por padrão, mas pode ser mostrado). ",
            +        "Nota importante: no modo 2D (ou seja, quando <code>p5.Renderer</code> não está definido) a origem (0,0) é posicionada na parte superior esquerda da tela. No modo 3D (ou seja, quando <code>p5.Renderer</code> está definido <code>WEBGL</code>), a origem é posicionada no centro do canvas. Veja <a href=\"https://github.com/processing/p5.js/issues/1545\">esse assunto</a> para mais informações.",
            +        "As variáveis de sistema largura e altura são definidas pelos parâmetros passados para esta função. Se <a href=\"#/p5/createCanvas\">createCanvas()</a> não for usado, a janela terá um tamanho padrão de 100x100 pixels. ",
            +        "Para obter mais maneiras de posicionar o canvas, consulte a página wiki <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'> posicionando o canvas</a> ."
            +      ],
            +      "returns": "p5.Renderer: ",
            +      "params": {
            +        "w": "Número: largura do canvas",
            +        "h": "Número: altura do canvas",
            +        "renderer": "Constante (opcional): tanto P2D ou WEBGL"
            +      }
            +    },
            +    "resizeCanvas": {
            +      "description": [
            +        "Redimensiona o canvas de acordo com a largura e a altura fornecidas. O canvas será limpo e draw será chamada imediatamente, permitindo que o sketch seja renderizado novamente na tela redimensionada."
            +      ],
            +      "params": {
            +        "w": "Número: largura do canvas",
            +        "h": "Número: altura do canvas",
            +        "noRedraw": "Booleano (opcional): não redesenha o canvas imediatamente"
            +      }
            +    },
            +    "noCanvas": {
            +      "description": [
            +        "Remove o canvas padrão para um sketch p5 que não requer um canvas"
            +      ]
            +    },
            +    "createGraphics": {
            +      "description": [
            +        "Cria e retorna um novo objeto p5.Renderer. Use esta classe se precisar desenhar em um buffer gráfico nos bastidores da tela (off-screen). Os dois parâmetros definem a largura e altura em pixels."
            +      ],
            +      "returns": "p5.Graphics: buffer gráfico nos bastidores da tela",
            +      "params": {
            +        "w": "Número: largura do buffer gráfico nos bastidores da tela",
            +        "h": "Número: altura do buffer gráfico nos bastidores da tela",
            +        "renderer": "Constante (opcional): tanto P2D ou WEBGL padrão indefinido para p2d"
            +      }
            +    },
            +    "blendMode": {
            +      "description": [
            +        "Combina os pixels na janela de exibição de acordo com o modo definido. Existe uma escolha dos seguintes modos para misturar os pixels de origem (A) com os pixels que já estão na janela de exibição (B): <ul> <li><code>BLEND</code> - interpolação linear de cores: C = A*fator + B. <b>Este é o modo de mistura padrão. </b></li> <li><code>ADD</code> - soma de A e B</li> <li><code>DARKEST</code> - apenas a cor mais escura aparece: C = min(A*fator, B).</li> <li><code>LIGHTEST</code> - apenas a cor mais clara aparece: C = max(A*fator, B).</li> <li><code>DIFFERENCE</code> - subtrai as cores da imagem subjacente.</li> <li><code>EXCLUSION</code> - similar a <code>DIFFERENCE</code>, porém, menos extremo.</li> <li><code>MULTIPLY</code> - multiplique as cores, o resultado sempre será mais escuro.</li> <li><code>SCREEN</code> - oposto a multiply, usa valores inversos das cores.</li> <li><code>REPLACE</code> - os pixels são inteiramente substituídos pelos outros e não utilizam valores alfa (transparência).</li> <li><code>REMOVE</code> - remove os pixels de B com a força alfa de A.</li> <li><code>OVERLAY</code> - mistura de <code>MULTIPLY</code> e <code>SCREEN </code>. Multiplica valores de escuridão e valores de luz. <em>(2D)</em></li> <li><code>HARD_LIGHT</code> - <code>SCREEN</code> quando maior que 50% cinza, <code>MULTIPLY</code> quando mais baixo. <em>(2D)</em></li> <li><code>SOFT_LIGHT</code> - mistura de <code>DARKEST</code> e <code>LIGHTEST</code>. Funciona como <code>OVERLAY</code>, mas não tão severo. <em>(2D)</em> </li> <li><code>DODGE</code> - clareia os tons claros e aumenta o contraste, ignora os escuros. <em>(2D)</em></li> <li><code>BURN</code> - áreas mais escuras são aplicadas, aumentando o contraste, ignora as luzes. <em>(2D)</em></li> <li><code>SUBTRACT</code> - restante de A e B <em>(3D)</em></li> </ul>  ",
            +        "<em>(2D)</em> indica que este modo de mistura <b>apenas</b> funciona no renderizador 2D. <em>(3D)</em> indica que este modo de mistura <b>apenas</b> funciona no renderizador WEBGL."
            +      ],
            +      "params": {
            +        "mode": "Constante: modo de mistura para definir o canvas. tanto BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,  EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD, REMOVE ou SUBTRACT"
            +      }
            +    },
            +    "drawingContext": {
            +      "description": [
            +        "A API do p5.js fornece muitas funcionalidades para a criação de gráficos, mas há algumas funcionalidades nativas do HTML5 Canvas que não são expostas pelo p5. Você ainda pode chamá-lo diretamente usando a variável  <code>drawingContext</code>, como no exemplo mostrado. Isso é o equivalente a chamar <code>canvas.getContext('2d');</code> ou <code>canvas.getContext('webgl');</code>. Veja isto <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\"> referência para a API nativa do canvas</a> para possíveis funções de desenho que você pode chamar."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Interrompe a execução contínua do código dentro do bloco <a href=\"#/p5/draw\">draw()</a>.",
            +        "Por padrão, o p5.js executa continuamente as linhas de código contidas dentro do bloco <a href=\"#/p5/draw\">draw()</a>. Para interromper a execução contínua utiliza-se a função <a href=\"#/p5/noLoop\">noLoop()</a>. Neste caso, a execução de <a href=\"#/p5/draw\">draw()</a> pode ser recomeçada com a função <a href=\"#/p5/loop\">loop()</a>.",
            +        "Caso a função <a href=\"#/p5/noLoop\">noLoop()</a> seja utilizada dentro de <a href=\"#/p5/setup\">setup()</a>, ela deverá estar na última linha de código dentro do bloco.",
            +        "Quando <a href=\"#/p5/noLoop\">noLoop()</a> é usado, não é possível manipular ou acessar a tela pelas funções de manipulação de eventos (event handlers), como <a href=\"#/p5/mousePressed\">mousePressed()</a> ou <a href=\"#/p5/keyPressed\">keyPressed()</a>. Isso significa que quando <a href=\"#/p5/noLoop\">noLoop()</a> é executado, nada mais pode ser desenhado e funções como <a href=\"#/p5/saveFrames\">saveFrames()</a> or <a href=\"#/p5/loadPixels\">loadPixels()</a> não podem ser usadas. Nestes casos, as funções de manipulação de eventos (event handlers) podem ser utilizadas para chamar <a href=\"#/p5/redraw\">redraw()</a> ou <a href=\"#/p5/loop\">loop()</a>, que ao executar <a href=\"#/p5/draw\">draw()</a> poderam atualizar a tela corretamente.",
            +        "Observe que se a Canvas for redimensionada, <a href=\"#/p5/redraw\"> redraw() </a> será chamado para atualizar o desenho, mesmo se <a href = \"#/p5/noLoop\">noLoop()</a> tiver sido chamado. Caso contrário, o desenho poderia ficar desconfigurado em relação ao tamanho da canvas até que <a href=\"#/p5/loop\">loop()</a> fosse chamado. ",
            +        "Utilize <a href=\"#/p5/isLooping\">isLooping()</a> para verificar o atual estado de <code>loop()</code>."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Retoma a execução contínua do código dentro do bloco <a href=\"#/p5/draw\">draw()</a>",
            +        "Por padrão, o p5.js executa continuamente as linhas de código contidas dentro do bloco <a href=\"#/p5/draw\">draw()</a>. Para interromper a execução contínua utiliza-se a função <a href=\"#/p5/noLoop\">noLoop()</a>. Neste caso, a execução de <a href=\"#/p5/draw\">draw()</a> pode ser recomeçada com a função <a href=\"#/p5/loop\">loop()</a>. ",
            +        "Nâo é recomendado chamar <code>loop</code> dentro de <a href=\"#/p5/setup\">setup()</a> ",
            +        "Utilize <a href=\"#/p5/isLooping\">isLooping()</a> para verificar o atual estado de <code>loop()</code>."
            +      ]
            +    },
            +    "isLooping": {
            +      "description": [
            +        "Retorna o estado atual de <a href=\"#/p5/loop\">loop()</a>.",
            +        "Por padrão, o p5.js executa continuamente as linhas de código contidas dentro do bloco <a href=\"#/p5/draw\">draw()</a>, a execução pode ser controlada pelas funções <a href=\"#/p5/noLoop\">noLoop()</a> e <a href=\"#/p5/loop\">loop()</a>. O valor que <code>isLooping()</code> retorna pode ser utilizado com manipuladores de eventos personalizados (custom event handlers). "
            +      ]
            +    },
            +    "push": {
            +      "description": [
            +        "A função <a href=\"#/p5/push\">push()</a> salva as configurações e transformações do estilo de desenho atual, enquanto <a href=\"#/p5/pop\">pop()</a> restaura essas configurações.",
            +        " As funções <a href=\"#/p5/push\">push()</a> e <a href=\"#/p5/pop\">pop()</a> sempre são utilizadas juntas. Elas permitem que as configurações de estilo e transformação sejam alteradas e, posteriormente, permite que elas sejam restauradas. Quando um novo estado é iniciado com push (), ele se baseia no estilo atual e nas informações de transformação. As funções push () e pop () podem ser incorporadas para fornecer mais controle. (Veja o segundo exemplo.) ",
            +        "<a href=\"#/p5/push\">push()</a> armazena informações relacionadas ao estado de transformação atual e configurações de estilo controladas pelas seguintes funções: <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"#/p5/strokeCap\">strokeCap()</a>, <a href=\"#/p5/strokeJoin\">strokeJoin()</a>, <a href=\"#/p5/imageMode\">imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href=\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5/textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a> e <a href=\"#/p5/noiseSeed\">noiseSeed()</a>. ",
            +        "No modo WEBGL, configurações de estilo adicionais são armazenadas. Elas são controlados pelas seguintes funções: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ambientLight\">ambientLight()</a>, <a href=\"#/p5/directionalLight\">directionalLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">shininess()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> e <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "pop": {
            +      "description": [
            +        "A função <a href=\"#/p5/push\">push()</a> salva as configurações e transformações do estilo de desenho atual, enquanto <a href=\"#/p5/pop\">pop()</a> restaura essas configurações.",
            +        " As funções <a href=\"#/p5/push\">push()</a> e <a href=\"#/p5/pop\">pop()</a> sempre são utilizadas juntas. Elas permitem que as configurações de estilo e transformação sejam alteradas e, posteriormente, permite que elas sejam restauradas. Quando um novo estado é iniciado com push (), ele se baseia no estilo atual e nas informações de transformação. As funções push () e pop () podem ser incorporadas para fornecer mais controle. (Veja o segundo exemplo.) ",
            +        "<a href=\"#/p5/push\">push()</a> armazena informações relacionadas ao estado de transformação atual e configurações de estilo controladas pelas seguintes funções: <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"#/p5/strokeCap\">strokeCap()</a>, <a href=\"#/p5/strokeJoin\">strokeJoin()</a>, <a href=\"#/p5/imageMode\">imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href=\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5/textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a> e <a href=\"#/p5/noiseSeed\">noiseSeed()</a>. ",
            +        "No modo WEBGL, configurações de estilo adicionais são armazenadas. Elas são controlados pelas seguintes funções: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ambientLight\">ambientLight()</a>, <a href=\"#/p5/directionalLight\">directionalLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">shininess()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> e <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "redraw": {
            +      "description": [
            +        "A função <a href=\"#/p5/redraw\">redraw()</a> faz com que o código dentro de <a href=\"#/p5/draw\">draw()</a> seja executado uma única vez.",
            +        "Esta função permite que o programa atualize a janela de exibição apenas quando necessário, por exemplo, quando ocorre um evento registrado por <a href=\"#/p5/mousePressed\">mousePressed()</a> ou <a href=\"#/p5/keyPressed\">keyPressed()</a>.",
            +        "Na estruturação de um programa, só faz sentido chamar <a href=\"#/p5/redraw\">redraw()</a> em eventos como <a href=\"#/p5/mousePressed\">mousePressed()</a>. Isso ocorre porque <a href=\"#/p5/redraw\">redraw()</a> não executa <a href=\"#/p5/draw\">draw()</a> imediatamente (apenas define um sinalizador que indica que uma atualização é necessária).",
            +        "A função <a href=\"#/p5/redraw\">redraw()</a> não funciona corretamente quando é chamada dentro de <a href=\"#/p5/draw\">draw()</a>.Para ativar/desatiar animações utilize <a href=\"#/p5/loop\">loop()</a> e <a href=\"#/p5/noLoop\">noLoop()</a>. ",
            +        "Além disso, você pode definir o número de redraws (o número de vezes que o código dentro de <a href=\"#/p5/draw\">draw()</a> será executado) por chamada de método. Basta adicionar um inteiro como parâmetro único para o número de redraws."
            +      ],
            +      "params": {
            +        "n": "Número inteiro (optional): Redraw n-vezes. O valor padrão é 1."
            +      }
            +    },
            +    "p5": {
            +      "description": [
            +        "O construtor <code>p5()</code> permite que você ative o \"instance mode\" em vez do \"global mode\". ",
            +        "Este é um tópico avançado, uma breve descrição e um exemplo estão incluídos abaixo. Por favor, assista <a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\"> o tutorial em vídeo do Coding Train de Dan Shiffman</a> eu acesse este <a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial</a> para mais informações. ",
            +        "Por padrão, todas as funções p5.js estão no global namespace (ou seja, vinculadas ao objeto window), o que significa que você pode chamá-las simplesmente de elipse (), preenchimento (), etc. No entanto, isso pode ser inconveniente se você estiver utilizando junto outras Bibliotecas JS (de forma síncrona ou assíncrona) ou escrevendo seus próprios programas longos. O p5.js atualmente suporta uma maneira de contornar este problema chamado \"instance mode\". No modo de instância, todas as funções do p5 são agrupadas em uma única variável, em vez de poluir seu global namespace. ",
            +        "Opcionalmente, você pode especificar um elemento HTML do tipo container (ex. <code>&lt;div&gt;</code>) padrão para a canvas e quaisquer outros elementos para anexar com um segundo argumento. Você pode fornecer o ID de um elemento em seu html, ou o próprio node (nó) html.",
            +        "Observe que a criação de instâncias como essa também permite que você tenha mais de um sketch do p5 em uma única página da web, pois cada um deles será empacotado (wrapped) com suas próprias variáveis de configuração. Você também pode usar <code>&lt;iframe&gt;</code> para ter vários sketches no modo global."
            +      ],
            +      "params": {
            +        "sketch": "Objeto: uma função contendo o sketch do p5.js",
            +        "node": "String|Objeto: ID ou ponteiro para o node (nó) HTML no DOM contendo o sketch do p5.js"
            +      }
            +    },
            +    "applyMatrix": {
            +      "description": [
            +        "Multiplica a matriz atual por aquela especificada nos parâmetros. Esta é uma operação poderosa que pode realizar o equivalente a translação, escala, distorção e rotação, tudo de uma vez. Você pode aprender mais sobre matrizes de transformação em <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\"> Wikipedia</a>. ",
            +        "A nomenclatura dos argumentos aqui segue a nomenclatura da <a href= \"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\"> especificação WHATWG</a> and corresponds to a transformation matrix of the form: <blockquote> ",
            +        "<img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\" alt=\"a matriz de transformação usada quando applyMatrix é chamado\"/> </blockquote>"
            +      ],
            +      "params": {
            +        "a": "Número|Array: números que definem a matriz 2x3 a ser multiplicada, ou uma matriz de números",
            +        "b": "Número: números que definem a matriz 2x3 a ser multiplicada",
            +        "c": "Número: números que definem a matriz 2x3 a ser multiplicada",
            +        "d": "Número: números que definem a matriz 2x3 a ser multiplicada",
            +        "e": "Número: números que definem a matriz 2x3 a ser multiplicada",
            +        "f": "Número: números que definem a matriz 2x3 a ser multiplicada"
            +      }
            +    },
            +    "resetMatrix": {
            +      "description": [
            +        "Substitui a matriz atual pela matriz de identidade."
            +      ]
            +    },
            +    "rotate": {
            +      "description": [
            +        "Gira uma forma pela quantidade especificada pelo parâmetro de ângulo. Esta função é responsável por <a href=\"#/p5/angleMode\">angleMode</a>, então os ângulos podem ser inseridos em RADIANOS ou GRAUS. ",
            +        "Os objetos são sempre girados em torno de sua posição relativa à origem e os números positivos giram os objetos no sentido horário. As transformações se aplicam a tudo o que acontece depois e as chamadas subsequentes para a função acumulam o efeito. Por exemplo, chamar rotate(HALF_PI) e então rotate(HALF_PI) é o mesmo que rotate(PI). Todas as transformações são redefinidas quando <a href=\"#/p5/draw\">draw()</a> iniciar novamente. ",
            +        "Tecnicamente, <a href=\"#/p5/rotate\">rotate()</a> multiplica a matriz de transformação atual por uma matriz de rotação. Esta função pode ser controlada posteriormente pelo <a href=\"#/p5/push\">push()</a> e <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "angle": "Número: o ângulo de rotação, especificado em radianos ou graus, dependendo do atual angleMode",
            +        "axis": "p5.Vector|Número[] (opcional): (em 3d) eixos de rotação"
            +      }
            +    },
            +    "rotateX": {
            +      "description": [
            +        "Gira uma forma em torno do eixo X pela quantidade especificada no parâmetro de ângulo. Os ângulos podem ser inseridos em RADIANOS ou GRAUS.",
            +        "Os objetos são sempre girados em torno de sua posição relativa à origem e os números positivos giram os objetos no sentido horário. Todas as transformações são reiniciadas quando <a href=\"#/p5/draw\">draw()</a> for iterado novamente."
            +      ],
            +      "params": {
            +        "angle": "Número: o ângulo de rotação, especificado em radianos ou graus, dependendo do atual angleMode"
            +      }
            +    },
            +    "rotateY": {
            +      "description": [
            +        "Gira uma forma em torno do eixo Y pelo valor especificado no parâmetro de ângulo. Os ângulos podem ser inseridos em RADIANOS ou GRAUS. ",
            +        "Os objetos são sempre girados em torno de sua posição relativa à origem e os números positivos giram os objetos no sentido horário. Todas as transformações são reiniciadas quando <a href=\"#/p5/draw\">draw()</a>  for iterado novamente."
            +      ],
            +      "params": {
            +        "angle": "Número: o ângulo de rotação, especificado em radianos ou graus, dependendo do atual angleMode"
            +      }
            +    },
            +    "rotateZ": {
            +      "description": [
            +        "Gira uma forma em torno do eixo Z pelo valor especificado no parâmetro de ângulo. Os ângulos podem ser inseridos em RADIANOS ou GRAUS. ",
            +        "Este método apenas funciona em modo WEBGL. ",
            +        "Os objetos são sempre girados em torno de sua posição relativa à origem e os números positivos giram os objetos no sentido horário. Todas as transformações são reiniciadas quando <a href=\"#/p5/draw\">draw()</a> for iterado novamente."
            +      ],
            +      "params": {
            +        "angle": "Número: o ângulo de rotação, especificado em radianos ou graus, dependendo do atual angleMode"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Aumenta ou diminui o tamanho de uma forma expandindo ou contraindo vértices. Os objetos sempre são escalonados de sua origem relativa ao sistema de coordenadas. Os valores da escala são especificados como porcentagens decimais. Por exemplo, a chamada de função scale (2.0) aumenta a dimensão de uma forma em 200%. ",
            +        "As transformações se aplicam a tudo o que acontece depois e as chamadas subsequentes à função multiplicam o efeito. Por exemplo, chamar escala (2,0) e depois escala (1,5) é o mesmo que escala (3,0). Se <a href=\"#/p5/scale\">scale()</a> é chamado dentro de <a href=\"#/p5/draw\">draw()</a>, a transformação é reiniciada quando o loop for iterado novamente. ",
            +        "O uso desta função com o parâmetro z está disponível apenas no modo WEBGL. Esta função pode ser controlada posteriormente com <a href=\"#/p5/push\">push()</a> e <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "s": "Número|p5.Vector|Número[] (opcional): porcentagem para dimensionar o objeto no eixo x se vários argumentos forem fornecidos",
            +        "y": "Número (optional): percentual para dimensionar o objeto no eixo y ",
            +        "z": "Número (optional): percentual para dimensionar o objeto no eixo z (apenas em webgl)",
            +        "scales": "p5.Vector|Número[]: percentagens por eixo para dimensionar o objeto"
            +      }
            +    },
            +    "shearX": {
            +      "description": [
            +        "Corta uma forma em torno do eixo x pelo valor especificado pelo parâmetro de ângulo. Os ângulos devem ser especificados no angleMode atual. Os objetos são sempre cortados em torno de sua posição relativa à origem e os números positivos cortam os objetos no sentido horário. ",
            +        "As transformações se aplicam a tudo o que acontece depois e as chamadas subsequentes para a função acumulam o efeito. Por exemplo, chamar shearX(PI/2) e então shearX(PI/2) é o mesmo que shearX(PI). Se <a href=\"#/p5/shearX\">shearX()</a> é chamado dentro de <a href=\"#/p5/draw\">draw()</a>, a transformação é reiniciada quando o loop  for iterado novamente. ",
            +        "Tecnicamente, <a href=\"#/p5/shearX\">shearX()</a> multiplica a matriz de transformação atual por uma matriz de rotação. Esta função pode ser controlada posteriormente pelas funções <a href=\"#/p5/push\">push()</a> e <a href=\"#/p5/pop\">pop()</a> ."
            +      ],
            +      "params": {
            +        "angle": "Número: ângulo de corte especificado em radianos ou graus, dependendo do angleMode atual"
            +      }
            +    },
            +    "shearY": {
            +      "description": [
            +        "Corta uma forma em torno do eixo y de acordo com o valor especificado pelo parâmetro de ângulo. Os ângulos devem ser especificados no angleMode atual. Os objetos são sempre cortados em torno de sua posição relativa à origem e os números positivos cortam os objetos no sentido horário. ",
            +        "As transformações se aplicam a tudo o que acontece depois e as chamadas subsequentes para a função acumulam o efeito. Por exemplo, chamar shearY (PI/2) e depois shearY(PI/2) é o mesmo que shearY(PI). Se  <a href=\"#/p5/shearY\">shearY()</a> é chamado dentro de <a href=\"#/p5/draw\">draw()</a>, a transformação é reiniciada quando o loop rodar novamente. ",
            +        "Tecnicamente, <a href=\"#/p5/shearY\">shearY()</a> multiplica a matriz de transformação atual por uma matriz de rotação. Esta função pode ser controlada posteriormente pelas funções <a href=\"#/p5/push\">push()</a> e <a href=\"#/p5/pop\">pop()</a> ."
            +      ],
            +      "params": {
            +        "angle": "Número: ângulo de corte especificado em radianos ou graus, dependendo do atual angleMode"
            +      }
            +    },
            +    "translate": {
            +      "description": [
            +        "Especifica uma quantidade para deslocar objetos na janela de exibição. O parâmetro x especifica a translação esquerda / direita, o parâmetro y especifica a translação para cima / para baixo. ",
            +        "As transformações são cumulativas e se aplicam a tudo o que acontece depois e as chamadas subsequentes para a função acumulam o efeito. Por exemplo, chamar a translação (50, 0) e então a translação (20, 0) é o mesmo que a translação de (70, 0). Se <a href=\"#/p5/translate\">translate()</a> for chamado dentro de <a href=\"#/p5/draw\">draw()</a>, a transformação é reiniciada quando o loop for iterado novamente. Esta função pode ser posteriormente controlada usando <a href=\"#/p5/push\">push()</a> e <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "x": "Número: translação esquerda/direita",
            +        "y": "Número: translação para cima/ para baixo",
            +        "z": "Número (opcional): translação para frente/ para trás (apenas em webgl)",
            +        "vector": "p5.Vector: o vetor para translação"
            +      }
            +    },
            +    "storeItem": {
            +      "description": [
            +        "Armazena um valor(value) no local storage sob o nome da chave (key). O armazenamento local é salvo no navegador e permanece salvo entre as sessões de navegação e recarregamentos de página. A chave (key) pode ser o nome da variável, mas não obrigatoriamente. Para recuperar os itens armazenados, consulte <a href=\"#/p5/getItem\">getItem</a>. Dados sensíveis como senhas ou infromações pessoais não devem ser armazenados no armazenamento local."
            +      ],
            +      "params": {
            +        "key": "String",
            +        "value": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +      }
            +    },
            +    "getItem": {
            +      "description": [
            +        "Retorna o valor de um item que foi armazenado do armazenamento local usando storeItem()"
            +      ],
            +      "returns": "Number|Object|String|Boolean|p5.Color|p5.Vector: valor do item armazenado",
            +      "params": {
            +        "key": "String: nome que você deseja utilizar para armazenar no armazenar no armazenamento local"
            +      }
            +    },
            +    "clearStorage": {
            +      "description": [
            +        "Esvazia todos os itens armazenados localmente configurados com storeItem() para o domínio atual."
            +      ]
            +    },
            +    "removeItem": {
            +      "description": [
            +        "Remove um item que foi armazenado com storeItem()"
            +      ],
            +      "params": {
            +        "key": "String"
            +      }
            +    },
            +    "createStringDict": {
            +      "description": [
            +        "Cria uma nova instancia de p5.StringDict utilizando o par chave-valor (key-value) ou o objeto que você fornecer."
            +      ],
            +      "returns": "p5.StringDict: ",
            +      "params": {
            +        "key": "String",
            +        "value": "String",
            +        "object": "Object: object"
            +      }
            +    },
            +    "createNumberDict": {
            +      "description": [
            +        "Cria uma nova instancia de <a href=\"#/p5.NumberDict\">p5.NumberDict</a> utilizando o par chave-valor (key-value) ou o objeto que você fornecer"
            +      ],
            +      "returns": "p5.NumberDict: ",
            +      "params": {
            +        "key": "Number",
            +        "value": "Number",
            +        "object": "Object: object"
            +      }
            +    },
            +    "select": {
            +      "description": [
            +        "Busca a pagina o primeiro elemento que corresponde a string do seletor CSS determinada (pode ser uma ID, classe, tag ou uma combinação) e o retorna como um <a href=\"#/p5.Element\">p5.Element</a>. O node do DOM pode ser acessado com .elt. Retorna nulo se nenhum for encontrado. Você também pode especificar um container dentro do qual a pesquisa será feita."
            +      ],
            +      "returns": "p5.Element|null: <a href=\"#/p5.Element\">p5.Element</a> contendo o node encontrado",
            +      "params": {
            +        "selectors": "String: string do seletor CSS do elemento a ser buscado",
            +        "container": "String|p5.Element|HTMLElement (Opcional): string do seletor CSS, <a href=\"#/p5.Element\">p5.Element</a>  , ou elemento HTML dentro do qual deve ser buscado "
            +      }
            +    },
            +    "selectAll": {
            +      "description": [
            +        "Busca na pagina todos os elementos que correspondem a string do seletor CSS determinada (pode ser uma ID, classe, tag ou uma combinação) e os retornam como <a href=\"#/p5.Element\">p5.Element</a>s em um array(array?). O node do DOM pode ser acessado com .elt. Retorna um array vazio se nada for encondrado. Você também pode especificar um container dentro do qual a pesquisa será feita."
            +      ],
            +      "returns": "p5.Element[]: Uma array de <a href=\"#/p5.Element\">p5.Element</a>s contendo os nodes encontrados",
            +      "params": {
            +        "selectors": "String: string do seletor CSS do elemento a ser buscado",
            +        "container": "String|p5.Element|HTMLElement (Opcional): string do seletor CSS, <a href=\"#/p5.Element\">p5.Element</a>, ou elemento HTML dentro do qual deve ser buscado "
            +      }
            +    },
            +    "removeElements": {
            +      "description": [
            +        "Remove todos os elementos criados pelo p5, exceto a canvas ou elementos gráficos criados por <a href=\"#/p5/createCanvas\">createCanvas</a> ou <a href=\"#/p5/createGraphics\">createGraphics</a>. !! Event handlers e o elemento são removidos do DOM."
            +      ]
            +    },
            +    "changed": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/changed\">changed()</a> é chamada quando o valor de um elemento é alterado. Pode ser utilizada !! para anexar um !!event listener específico de um elemeto. "
            +      ],
            +      "params": {
            +        "fxn": "Função | Booleano: função a ser disparada quando o valor de um elemento é alterado. Se  <code>false</code> (falso) for passado como parâmetro, a função disparadora anterior não será mais disparada."
            +      }
            +    },
            +    "input": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/input\">input()</a> é chamada quando é detectado aulgum input do usuário dentro de um elemento. O evento de input normalmente é usado para detectar pressionamentos de teclas em um elemento de input ou  alterações em um elemento slider (controle deslizante). Pode ser utilizada !! para anexar um !!event listener específico de um elemeto."
            +      ],
            +      "params": {
            +        "fxn": "Função | Booleano: função a ser disparada quando algum input do usuário é detectado dentro do elemento. Se  <code>false</code> for passado como parâmetro, a função disparadora anterior não será mais disparada."
            +      }
            +    },
            +    "createDiv": {
            +      "description": [
            +        "Cria um elemento <code>&lt;div&gt;</code> no DOM com o HTML interno fornecido."
            +      ],
            +      "returns": "p5.Element: ponteiro para <a href=\"#/p5.Element\">p5.Element</a> que contém o node criado.",
            +      "params": {
            +        "html": "String (Opcional):  HTML interno para o elemento criado."
            +      }
            +    },
            +    "createP": {
            +      "description": [
            +        "Cria um elemento <code>&lt;p&gt;&lt;/p&gt;</code> (parágrafo) no DOM com o HTML interno fornecido."
            +      ],
            +      "returns": "p5.Element: ponteiro para <a href=\"#/p5.Element\">p5.Element</a> que contém o node criado.",
            +      "params": {
            +        "html": "String(Opcional):  HTML interno para o elemento criado."
            +      }
            +    },
            +    "createSpan": {
            +      "description": [
            +        "Cria um elemento <code>&lt;span&gt;&lt;/span&gt;</code> no DOM com o HTML interno fornecido."
            +      ],
            +      "returns": "p5.Element: ponteiro para <a href=\"#/p5.Element\">p5.Element</a> que contém o node criado.",
            +      "params": {
            +        "html": "String(Opcional):  HTML interno para o elemento criado."
            +      }
            +    },
            +    "createImg": {
            +      "description": [
            +        "Cria um elemento <code>&lt;img&gt;</code> no DOM com a fonte (src) e o texto altenativo (alt) fornecidos."
            +      ],
            +      "returns": "p5.Element: ponteiro para <a href=\"#/p5.Element\">p5.Element</a> que contém o node criado.",
            +      "params": {
            +        "src": "String: fonte (src) da Imagem, pode ser o endereço do arquivo ou uma url.",
            +        "alt": "String: <a href=\"https://developer.mozilla.org/pt-BR/docs/Web/HTML/Element/Img#attr-alt\">texto alternativo</a> (alt) atributo da imagem usado caso o arquivo não possa ser carregado. Você também pode usar uma string vazia (<code>\"\"</code>) caso a intençao seja que a imagem não seja vista.",
            +        "crossOrigin": "String: <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">atributo crossorigin</a> do elemento <code>&lt;img&gt;</code>; ",
            +        "successCallback": "Função  callback a ser chamada quando os dados da image são carregados com o <a href=\"#/p5.Element\">p5.Element</a> como argumento"
            +      }
            +    },
            +    "createA": {
            +      "description": [
            +        "Cia um elemento <code>&lt;a&gt;&lt;/a&gt;</code> no DOM com um hyperlink (hiperligação)."
            +      ],
            +      "returns": "p5.Element: ponteiro para o <a href=\"#/p5.Element\">p5.Element</a> contendo o node (nó) criado ",
            +      "params": {
            +        "href": "String: url da página a ser vinculada",
            +        "html": "String: HTML interno do elemento.",
            +        "target": "String (Opcional): atributo target, este atributo define a forma como o hyperlink (hiperligação) será aberta. Podem ser definidos os valores: _blank, _self, _parent, _top."
            +      }
            +    },
            +    "createSlider": {
            +      "description": [
            +        "Cria um elemento de <code>&lt;input&gt;&lt;/input&gt;</code> em forma de slider (controle deslizante) no DOM. Use .size() para configurar o comprimento do slider (controle deslizante)."
            +      ],
            +      "returns": "p5.Element: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> contendo o node (nó) criado ",
            +      "params": {
            +        "min": "Número: valor mínimo do slider",
            +        "max": "Número: valor máximo do slider",
            +        "value": "Número (opcional): valor padrão do slider",
            +        "step": "Número (opcional); valor do incremento para cada marcação do slider (se o valor do incremento for 0, o slider vai se movimentar continuamente entre o valor mínimo e o máximo)"
            +      }
            +    },
            +    "createButton": {
            +      "description": [
            +        "Cia um elemento <code>&lt;button&gt;&lt;/button&gt;</code> no DOM. Use .size() para configurara o tamanho do botão. Use .mousePressed() para especificar o comportamento ao pressionar."
            +      ],
            +      "returns": "p5.Element: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> contendo o node (nó) criado",
            +      "params": {
            +        "label": "String: label (etiqueta) exibida no botão",
            +        "value": "String (Opcional): valor do botão"
            +      }
            +    },
            +    "createCheckbox": {
            +      "description": [
            +        "Cria um elemento de <code>&lt;input&gt;&lt;/input&gt;</code> em forma de checkbox (caixas de seleção) no DOM. Chamando .checked() on a checkbox retorna true (verdadeiro) se ela estiver marcada ou false (falso) caso não esteja."
            +      ],
            +      "returns": "p5.Element: pontero para um <a href=\"#/p5.Element\">p5.Element</a> contendo o node (nó) criado",
            +      "params": {
            +        "label": "String (Opcional): label (etiqueta) exibida após a checkbox",
            +        "value": "Booleano (Ocional): valor da checkbox; se a caixa estiver marcada o valor será true (verdadeiro), se a caixa estiver desmarcada será false (falso)"
            +      }
            +    },
            +    "createSelect": {
            +      "description": [
            +        "Cria um elemento de seleção <code>&lt;select&gt;&lt;/select&gt;</code> em forma de lista suspensa no DOM. Também ajuda a atribuir métodos de caixa de seleção a <a href=\"#/p5.Element\"> p5.Element </a> ao selecionar a caixa de seleção existente. <li><code>.option(name, [value])</code> pode ser utilizado para configurar opções para a selecão depois de criada.</li><li><code>.value()</code> retornará a opção selecionada no momento.</li><li><code>.selected()</code> retornará o elemento da lista suspensa atual que é uma instância do <a href=\"#/p5.Element\">p5.Element</a>.</li><li><code>.selected(value)</code> pode ser usado para tornar determinado item selecionado por padrão quando a página é carregada pela primeira vez.</li><li><code>.disable()</code> marca toda lista suspensa como desativada.</li><li><code>.disable(value)</code> marca o item determinado como desativado.</li> </ul>"
            +      ],
            +      "returns": "p5.Element: ",
            +      "params": {
            +        "multiple": "Booleano (Opcional): true (verdadeiro) se o elemento suportar várias seleções",
            +        "existing": "Objeto: elemento de seleção do DOM"
            +      }
            +    },
            +    "createRadio": {
            +      "description": [
            +        "Cria um elemento HTML de <code>&lt;input&gt;&lt;/input&gt;</code> do tipo botão de escolha <a href= \"https:\/\/developer.mozilla.org\/pt-BR\/docs\/Web\/HTML\/Element\/input#:~:text=radio%3A%20Um%20bot%C3%A3o,de%20cada%20vez..\">(tipe = \"radio\")</a> no DOM. Também auxilia a atribuir métodos de <a href=\"#/p5.Element/\">p5.Element</a> a botões de escolha (radio) existentes.<ul> <li>O método <code>.option(value, [label])</code> pode ser utilizado para criar um novo item para o elemento. Se já existir um item com o valor indicado, o método retornará este item. Opcionalmente, um label (etiqueta) pode ser fornecido como segundo argumento para o item.</li><li>O método <code>.remove(value)</code> pode ser utilizado para remover um item do elemento.</li><li>O método <code>.value()</code> retorna o valor do item selecionado no momento.</li><li>O método <code>.selected()</code> retorna o elemento de input selecionado no momento.</li><li>O método <code>.selected(value)</code> marca um item como selecionado, retorna ele mesmo.</li><li>O método <code>.disable(Boolean)</code> desativa/ativa o elemento todo.</li> </ul>"
            +      ],
            +      "returns": "p5.Element: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> contendo o node (nó) criado.",
            +      "params": {
            +        "containerElement": "Objeto: Um elemento container de HTML, pode ser um <code>&lt;div&gt;&lt;/div&gt;</code> ou <code>&lt;span&gt;&lt;/span&gt;</code>, dentro do qual todas os inputs existentes serão considerados como itens do botão de escolha.",
            +        "name": "String (Opcional): parâmetro nome para cada elemnto de input."
            +      }
            +    },
            +    "createColorPicker": {
            +      "description": [
            +        "Cria um elemento no DOM para input de cor. O método <code>.value()<code> retorna uma string HEX (#rrggbb) da cor. O método <code>.color()<code> retorna um objeto p5.Color com a selecão de cor atual."
            +      ],
            +      "returns": "p5.Element: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> contendo o node (nó) criado.",
            +      "params": {
            +        "value": "String|p5.Color (Opcional): cor padrão do elemento."
            +      }
            +    },
            +    "createInput": {
            +      "description": [
            +        "Cria um elemento de <code>&lt;input&gt;&lt;/input&gt;</code> de texto no DOM. Use .<a href=\"#/p5.Element/size\">size()</a> para configurar o tamanho da caixa de texto."
            +      ],
            +      "returns": "p5.Element: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> contendo o node (nó) do DOM criado.",
            +      "params": {
            +        "value": "String: default valor padrão da caixa de texto do input",
            +        "type": "String (Opcional): tipo do texto, por ex.: \"text\", \"password\" etc. Por padrão o tipo definido é \"text\"."
            +      }
            +    },
            +    "createFileInput": {
            +      "description": [
            +        "Cria um elemento de <code>&lt;input&gt;&lt;/input&gt;</code> de arquivo no DOM. Permite que usuários carreguem arquivos locais para utilizar em um sketch."
            +      ],
            +      "returns": "p5.Element: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> contendo o node (nó) do DOM criado.",
            +      "params": {
            +        "callback": "Função: Funcão callback para quando o arquivo é carregado.",
            +        "multiple": "Booleano (Opcional): permite que múltiplos arquivos sejam selecionados."
            +      }
            +    },
            +    "createVideo": {
            +      "description": [
            +        "Cria um elemento de <code>&lt;video&gt;</code> HTML5 no DOM para a reprodução simples de áudio/video. O elemento de vídeo é definido como visível por padrão, pode ser ocultado com o método .<a href=\"#/p5.Element/hide\">hide()</a>  e desenhado na canvas utilizando <a href=\"#/p5/image\">image()</a>. O primeiro parâmetro pode ser uma única string com o caminho para um arquivo de vídeo ou uma array de strings com endereços de arquivos de videos em diferentes formatos de arquivo. Isso é útil para garantir que seu vídeo possa ser reproduzido em diferentes navegadores, já que cada um suporta formatos diferentes. Você pode encontrar mais informações sobre os formatos de mídias suportados <a href = \"https:\/\/developer.mozilla.org\/pt-BR/docs/Web/Media/Formats\"> aqui </a>."
            +      ],
            +      "returns": "p5.MediaElement: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> de vídeo.",
            +      "params": {
            +        "src": "String | String[]: endereço do arquivo de video ou uma array de endereços de arquivos de video em formatos diferentes.",
            +        "callback": "Função (Optional): função callback chamada no disparo do evento 'canplaythrough', ou seja, quando a mídia está pronta para ser reproduzida, e estima que já foram carregados dados suficientes para reproduzir a mídia sem interrupcões para mais buffering."
            +      }
            +    },
            +    "createAudio": {
            +      "description": [
            +        "Cria um elemento de <code>&lt;audio&gt;</code> HTML5 no DOM element in the DOM para a reprodução simples de áudio. Por definição, o elemento de áudio é criado como um elemento oculto (hidden). O primeiro parâmetro pode ser uma única string com o caminho para um arquivo de áudio ou uma array de strings com endereços de arquivos de áudio em diferentes formatos de arquivo. Isso é útil para garantir que seu vídeo possa ser reproduzido em diferentes navegadores, já que cada um suporta formatos diferentes. Você pode encontrar mais informações sobre os formatos de mídias suportados <a href = \"https:\/\/developer.mozilla.org\/pt-BR/docs/Web/Media/Formats\">aqui</a>."
            +      ],
            +      "returns": "p5.MediaElement: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> de áudio.",
            +      "params": {
            +        "src": "String | String[] (Opcional): endereço do arquivo ou uma array de endereços de arquivos em formatos diferentes.",
            +        "callback": "Função (Opcional): função chamada no disparo do evento 'canplaythrough', ou seja, quando a mídia está pronta para ser reproduzida, e estima que já foram carregados dados suficientes para reproduzir a mídia sem interrupcões para mais buffering."
            +      }
            +    },
            +    "VIDEO": {},
            +    "AUDIO": {},
            +    "createCapture": {
            +      "description": [
            +        "Cria um novo elemento <code>&lt;video&gt;</code> HTML5 que contém o fluxo de áudio e vídeo de uma webcam. O elemento de vídeo é definido como visível por padrão, pode ser ocultado com o método .<a href=\"#/p5.Element/hide\">hide()</a>  e desenhado na canvas utilizando <a href=\"#/p5/image\">image()</a>. A propriedade loadedmetadata pode ser utilizada para detectar quando o elemento for totalmente carregado (ver o segundo exemplo). ",
            +        " !! More specific properties of the feed can be passing in a Constraints object. See the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'> W3C spec</a> for possible properties. Note that not all of these are supported by all browsers. ",
            +        "<em>Nota de segurança</em>: Devido a especificações de segurança dos navegadores é preciso solicitar ao usuário permissão para utilizar entradas de mídia como a webcam, para isso o método <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/MediaDevices\/getUserMedia\"> .getUserMedia() </a> é utilizado dentro da função <a href=\"#/p5/createCapture\">createCapture()</a>, também por razões de segurança este método só pode ser executado quando o código está rodando localmente ou sob o protocolo HTTPS."
            +      ],
            +      "returns": "p5.Element: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> com fluxo de video da webcam",
            +      "params": {
            +        "type": "String | Constante | Objeto: tipo da captura. AUDIO e VIDEO são as definições padrão caso nenhuma especificação seja passada. !! Também pode ser definido por !! Constraints object",
            +        "callback": "Função (Opcional): função chamada quando o fluxo de mídia é carregado."
            +      }
            +    },
            +    "createElement": {
            +      "description": [
            +        "Cria um elemento HTML no DOM com segundo a tag definida."
            +      ],
            +      "returns": "p5.Element: ponteiro para um <a href=\"#/p5.Element\">p5.Element</a> contendo o node (nó) criado.",
            +      "params": {
            +        "tag": "String: tag HTML do novo elemento",
            +        "content": "String (Opcional): conteúdo HTML do elemento."
            +      }
            +    },
            +    "deviceOrientation": {
            +      "description": [
            +        "A variável global <code>deviceOrientation</code>, embutida na biblioteca p5.js, armazena a orientação do dispositivo em que o sketch está sendo executado. O valor da variável será LANDSCAPE (horizontal) ou PORTRAIT (vertical). Se nenhuma informação estiver disponível, o valor será <i>undefined</i> (indefinido)."
            +      ]
            +    },
            +    "accelerationX": {
            +      "description": [
            +        "A variável global <code>accelerationX</code>, embutida na biblioteca p5.js, armazena a aceleração do dispositivo no eixo X. O valor é representado como metros por segundo ao quadrado."
            +      ]
            +    },
            +    "accelerationY": {
            +      "description": [
            +        "A variável global <code>accelerationY</code>, embutida na biblioteca p5.js, armazena a aceleração do dispositivo no eixo Y. O valor é representado como metros por segundo ao quadrado."
            +      ]
            +    },
            +    "accelerationZ": {
            +      "description": [
            +        "A variável global <code>accelerationZ</code>, embutida na biblioteca p5.js, armazena a aceleração do dispositivo no eixo Z. O valor é representado como metros por segundo ao quadrado."
            +      ]
            +    },
            +    "pAccelerationX": {
            +      "description": [
            +        "A variável global <code>pAccelerationX</code>, embutida na biblioteca p5.js, armazena a aceleração do dispositivo no eixo X no frame anterior ao atual. O valor é representado como metros por segundo ao quadrado."
            +      ]
            +    },
            +    "pAccelerationY": {
            +      "description": [
            +        "A variável global <code>pAccelerationY</code>, embutida na biblioteca p5.js, armazena a aceleração do dispositivo no eixo Y no frame anterior ao atual. O valor é representado como metros por segundo ao quadrado."
            +      ]
            +    },
            +    "pAccelerationZ": {
            +      "description": [
            +        "A variável global <code>pAccelerationZ</code>, embutida na biblioteca p5.js, armazena a aceleração do dispositivo no eixo Z no frame anterior ao atual. O valor é representado como metros por segundo ao quadrado."
            +      ]
            +    },
            +    "rotationX": {
            +      "description": [
            +        "A variável global <code>rotationX</code>, embutida na biblioteca p5.js, armazena a rotação do dispositivo em relação ao eixo X. Se o modo de ângulo do sketch (<a href=\"#/p5/angleMode\">angleMode()</a>) estiver definido como graus (DEGREES), o valor será entre -180 e 180. Caso esteja definido como radianos (RADIANS), o valor será entre -PI e PI.",
            +        "Nota: A ordem em que as rotações são chamas é importate. Se usadas em conjunto, é preciso chamá-las na ordem Z-X-Y, ou é possível que aconteçam comportamentos inesperados."
            +      ]
            +    },
            +    "rotationY": {
            +      "description": [
            +        "A variável global <code>rotationY</code>, embutida na biblioteca p5.js, armazena a rotação do dispositivo em relação ao eixo Y. Se o modo de ângulo do sketch (<a href=\"#/p5/angleMode\">angleMode()</a>) estiver definido como graus (DEGREES), o valor será entre -90 e 90. Caso esteja definido como radianos (RADIANS), o valor será entre -PI/2 e PI/2.",
            +        "Nota: A ordem em que as rotações são chamas é importate. Se usadas em conjunto, é preciso chamá-las na ordem Z-X-Y, ou é possível que aconteçam comportamentos inesperados."
            +      ]
            +    },
            +    "rotationZ": {
            +      "description": [
            +        "A variável global <code>rotationZ</code>, embutida na biblioteca p5.js, armazena a rotação do dispositivo em relação ao eixo Z. Se o modo de ângulo do sketch (<a href=\"#/p5/angleMode\">angleMode()</a>) estiver definido como graus (DEGREES), o valor será entre 0 e 360. Caso esteja definido como radianos (RADIANS), o valor será entre 0 e 2*PI.",
            +        "Nota: A ordem em que as rotações são chamas é importate. Se usadas em conjunto, é preciso chamá-las na ordem Z-X-Y, ou é possível que aconteçam comportamentos inesperados."
            +      ]
            +    },
            +    "pRotationX": {
            +      "description": [
            +        "A variável global <code>pRotationX</code>, embutida na biblioteca p5.js, armazena a rotação do dispositivo em relação ao eixo X no frame anterior ao atual. Se o modo de ângulo do sketch (<a href=\"#/p5/angleMode\">angleMode()</a>) estiver definido como graus (DEGREES), o valor será entre -180 e 180. Caso esteja definido como radianos (RADIANS), o valor será entre -PI e PI.",
            +        "<code>pRotationX</code> pode ser utilizada em conjunto com <a href=\"#/p5/rotationX\"><code>rotationX</code></a> para determinar a direção de rotação do dispositivo no eixo X."
            +      ]
            +    },
            +    "pRotationY": {
            +      "description": [
            +        "A variável global <code>pRotationY</code>, embutida na biblioteca p5.js, armazena a rotação do dispositivo em relação ao eixo Y no frame anterior ao atual. Se o modo de ângulo do sketch (<a href=\"#/p5/angleMode\">angleMode()</a>) estiver definido como graus (DEGREES), o valor será entre -90 e 90. Caso esteja definido como radianos (RADIANS), o valor será entre -PI/2 e PI/2.",
            +        "<code>pRotationY</code> pode ser utilizada em conjunto com <code><a href=\"#/p5/rotationY\">rotationY</a></code> para determinar a direção de rotação do dispositivo no eixo Y."
            +      ]
            +    },
            +    "pRotationZ": {
            +      "description": [
            +        "A variável global <code>pRotationZ</code>, embutida na biblioteca p5.js, armazena a rotação do dispositivo em relação ao eixo Z no frame anterior ao atual. Se o modo de ângulo do sketch (<a href=\"#/p5/angleMode\">angleMode()</a>) estiver definido como graus (DEGREES), o valor será entre 0 e 360. Caso esteja definido como radianos (RADIANS), o valor será entre 0 e 2*PI.",
            +        "<code>pRotationZ</code> pode ser utilizada em conjunto com <code><a href=\"#/p5/rotationZ\">rotationZ</a></code> para determinar a direção de rotação do dispositivo no eixo Z."
            +      ]
            +    },
            +    "turnAxis": {
            +      "description": [
            +        "Quanto o dispositivo é rotacionado, o método <a href=\"#/p5/deviceTurned\"><code>deviceTurned()</code></a> é acionado, e o eixo de rotação é armazenado na variável <code>turnAxis</code>. Essa variável só é definida dentro do escopo de <code>deviceTurned()</code>."
            +      ]
            +    },
            +    "setMoveThreshold": {
            +      "description": [
            +        "A função <a href=\"#/p5/setMoveThreshold\"><code>setMoveThreshold()</code></a> é utilizada para definir o limiar de movimento da função <a href=\"#/p5/deviceMoved\"><code>deviceMoved()</code></a>. O valor limiar padrão é 0.5."
            +      ],
            +      "params": {
            +        "value": "Número: o valor do limiar"
            +      }
            +    },
            +    "setShakeThreshold": {
            +      "description": [
            +        "A função <a href=\"#/p5/setShakeThreshold\"><code>setShakeThreshold()</code></a> é utilizada para definir o limiar de movimento da função <a href=\"#/p5/deviceShaken\"><code>deviceShaken()</code></a>. O valor limiar padrão é 30."
            +      ],
            +      "params": {
            +        "value": "Número: o valor do limiar"
            +      }
            +    },
            +    "deviceMoved": {
            +      "description": [
            +        "A função <a href=\"#/p5/deviceMoved\"><code>deviceMoved()</code></a> é chamada quando o dispositivo for movido para além do limiar em qualquer um dos eixos (X, Y ou Z). O valor limiar padrão é 0.5, e pode ser alterado através da função <a href=\"#/p5/setMoveThreshold\"><code>setMoveThreshold()</code></a>."
            +      ]
            +    },
            +    "deviceTurned": {
            +      "description": [
            +        "A função <a href=\"#/p5/deviceTurned\"><code>deviceTurned()</code></a> é chamada quando o dispositivo for rotacionado mais de 90 graus contínuos em qualquer eixo (X, Y ou Z).",
            +        "O eixo que dispara este método é armazenado na variável <a href=\"#/p5/turnAxis\"><code>turnAxis</code></a>. Assim, é possível direcionar sua execução para eixos específicos ao comparar a variável <a href=\"#/p5/turnAxis\"><code>turnAxis</code></a> com 'X', 'Y' ou 'Z'"
            +      ]
            +    },
            +    "deviceShaken": {
            +      "description": [
            +        "A função <a href=\"#/p5/deviceShaken\"><code>deviceShaken()</code></a> é chamada quando a aceleração total do dispositivo nos eixos X (<a href=\"#/p5/accelerationX\"><code>accelerationX</code></a>) e Y (<a href=\"#/p5/accelerationY\"><code>accelerationY</code></a>) for superior ao valor limiar.",
            +        "Por padrão, este valor é 30, mas pode ser alterado através da função <a href=\"#/p5/setShakeThreshold\"><code>setShakeThreshold()</code></a>."
            +      ]
            +    },
            +    "keyIsPressed": {
            +      "description": [
            +        "A variável booleana global <a href=\"#/p5/keyIsPressed\"><code>keyIsPressed</code></a> é <code>true</code> (verdadeira) quando uma tecla está pressionada, e <code>false</code> (falsa) quando não."
            +      ]
            +    },
            +    "key": {
            +      "description": [
            +        "A variável global <code>key</code> armazena o valor da última tecla que foi pressionada no teclado. Para garantir que o resultado transmita a informação correta em relação a minúsculas ou maiúsculas, é melhor utilizá-la dentro da função <a href=\"#/p5/keyTyped\"><code>keyTyped()</code></a>. Para teclas especiais ou caracteres fora do padrão <a href=\"https://pt.wikipedia.org/wiki/ASCII\" target=\"_blank\">ASCII</a>, utilize a variável <a href=\"#/p5/keyCode\"><code>keyCode</code></a>."
            +      ]
            +    },
            +    "keyCode": {
            +      "description": [
            +        "A variável global <code>keyCode</code> armazena o código correspondente à última tecla que foi pressionada no teclado. Diferente da variável <a href=\"#/p5/key\"><code>key</code></a>, <code>keyCode</code> permite detectar teclas especiais. Para tal, é preciso comparar a variável com o código correspondente à tecla especial desejada, ou com as constantes correspondentes como <code>BACKSPACE</code>, <code>DELETE</code>, <code>ENTER</code>, <code>RETURN</code>, <code>TAB</code>, <code>ESCAPE</code>, <code>SHIFT</code>, <code>CONTROL</code>, <code>OPTION</code>, <code>ALT</code>, <code>UP_ARROW</code> (seta superior), <code>DOWN_ARROW</code> (seta inferior), <code>LEFT_ARROW</code> (seta esquerda), <code>RIGHT_ARROW</code> (seta direita). Você também pode utilizar um site como <a href=\"http://keycode.info/\">keycode.info</a> para encontrar o código da tecla (key code) de qualquer tecla em seu teclado."
            +      ]
            +    },
            +    "keyPressed": {
            +      "description": [
            +        "A função <code>keyPressed()</code> é chamada a cada vez que uma tecla é pressionada. O código da tecla e seu valor são então armazenados nas variáveis <a href=\"#/p5/keyCode\"><code>keyCode</code></a> e <a href=\"#/p5/key\"><code>key</code></a>.",
            +        "Para caracteres dentro do padrão <a href=\"https://pt.wikipedia.org/wiki/ASCII\" target=\"_blank\">ASCII</a>, o valor da tecla é armazenado na variável <a href=\"#/p5/key\"><code>key</code></a>. No entanto, a distinção entre maiúsculas e minúsculas não é garantida. Caso essa distinção seja necessária, é recomendado ler a variável dentro da função <a href=\"#/p5/keyTyped\"><code>keyTyped()</code></a>.",
            +        "Para caracteres fora do padrão <a href=\"https://pt.wikipedia.org/wiki/ASCII\" target=\"_blank\">ASCII</a>, o código da tecla é armazenado na variável <a href=\"#/p5/keyCode\"><code>keyCode</code></a>. Ela permite detectar teclas especiais ao ser comparada com o código correspondente à tecla especial desejada, ou com as constantes correspondentes como <code>BACKSPACE</code>, <code>DELETE</code>, <code>ENTER</code>, <code>RETURN</code>, <code>TAB</code>, <code>ESCAPE</code>, <code>SHIFT</code>, <code>CONTROL</code>, <code>OPTION</code>, <code>ALT</code>, <code>UP_ARROW</code> (seta superior), <code>DOWN_ARROW</code> (seta inferior), <code>LEFT_ARROW</code> (seta esquerda), <code>RIGHT_ARROW</code> (seta direita).",
            +        "Por causa da forma com que os sistemas operacionais tratam repetições nas teclas, pressionar continuamente uma tecla pode causar chamadas múltiplas aos métodos <code>keyPressed()</code>, <a href=\"#/p5/keyTyped\">keyTyped()</a> e <a href=\"#/p5/keyReleased\">keyReleased()</a>. A frequência de repetição é definida pelo sistema operacional, e pela configuração de cada dispositivo. Navegadores podem ter comportamentos diferentes relacionados a cada evento de tecla. Para previnir qualquer comportamento padrão, adicione <code>return false</code> ao fim do método."
            +      ],
            +      "params": {
            +        "event": "Objeto (opcional): argumento de callback do tipo <a href=\"https://developer.mozilla.org/pt-BR/docs/Web/API/KeyboardEvent\">KeyboardEvent</a> (evento de teclado)"
            +      }
            +    },
            +    "keyReleased": {
            +      "description": [
            +        "A função <code>keyReleased()</code> é chamada a cada vez que uma tecla é liberada após ser pressionada. Veja <a href=\"#/p5/key\"><code>key</code></a> e <a href=\"#/p5/keyCode\"><code>keyCode</code></a> para mais detalhes.",
            +        "Navegadores podem ter comportamentos diferentes relacionados a cada evento de tecla. Para previnir qualquer comportamento padrão, adicione <code>return false</code> ao fim do método."
            +      ],
            +      "params": {
            +        "event": "Objeto (opcional): argumento de callback do tipo <a href=\"https://developer.mozilla.org/pt-BR/docs/Web/API/KeyboardEvent\">KeyboardEvent</a> (evento de teclado)"
            +      }
            +    },
            +    "keyTyped": {
            +      "description": [
            +        "A função <code>keyTyped()</code> é chamada a cada vez que uma tecla é pressionada, mas teclas de ação como Backspace, Delete, Ctrl, Shift, e Alt são ignoradas. A última tecla pressionada é armazenada na variável <a href=\"#/p5/key\"><code>key</code></a>. Caso esteja buscando o código da tecla, utilize a função <a href=\"#/p5/keyPressed\"><code>keyPressed()</code></a>.",
            +        "Por causa da forma com que os sistemas operacionais tratam repetições nas teclas, pressionar continuamente uma tecla pode causar chamadas múltiplas aos métodos <code>keyTyped()</code>, <a href=\"#/p5/keyPressed\"><code>keyPressed()</code></a> e <a href=\"#/p5/keyReleased\"><code>keyReleased()</code></a>. A frequência de repetição é definida pelo sistema operacional, e pela configuração de cada dispositivo. Navegadores podem ter comportamentos diferentes relacionados a cada evento de tecla. Para previnir qualquer comportamento padrão, adicione <code>return false</code> ao fim do método."
            +      ],
            +      "params": {
            +        "event": "Objeto (opcional): argumento de callback do tipo <a href=\"https://developer.mozilla.org/pt-BR/docs/Web/API/KeyboardEvent\">KeyboardEvent</a> (evento de teclado)"
            +      }
            +    },
            +    "keyIsDown": {
            +      "description": [
            +        "A função <code>keyIsDown()</code> verifica se alguma tecla está sendo pressionada. Ela pode ser utilizada caso você queira que diversas teclas afetem o comportamento de um objeto simultaneamente. Por exemplo, você pode querer que um objeto mova diagonalmente somente se as setas esquerda e superior estejam pressionadas ao mesmo tempo.",
            +        "Você pode verificar qualquer tecla através do seu código de tecla (key code), ou utilizar uma das contantes: <code>BACKSPACE</code>, <code>DELETE</code>, <code>ENTER</code>, <code>RETURN</code>, <code>TAB</code>, <code>ESCAPE</code>, <code>SHIFT</code>, <code>CONTROL</code>, <code>OPTION</code>, <code>ALT</code>, <code>UP_ARROW</code> (seta superior), <code>DOWN_ARROW</code> (seta inferior), <code>LEFT_ARROW</code> (seta esquerda), <code>RIGHT_ARROW</code> (seta direita)."
            +      ],
            +      "returns": "Booleano: se a tecla está pressionada ou não",
            +      "params": {
            +        "code": "Número: A tecla a ser verificada"
            +      }
            +    },
            +    "movedX": {
            +      "description": [
            +        "The variable movedX contains the horizontal movement of the mouse since the last frame"
            +      ]
            +    },
            +    "movedY": {
            +      "description": [
            +        "The variable movedY contains the vertical movement of the mouse since the last frame"
            +      ]
            +    },
            +    "mouseX": {
            +      "description": [
            +        "The system variable mouseX always contains the current horizontal position of the mouse, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. If touch is used instead of mouse input, mouseX will hold the x value of the most recent touch point."
            +      ]
            +    },
            +    "mouseY": {
            +      "description": [
            +        "The system variable mouseY always contains the current vertical position of the mouse, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. If touch is used instead of mouse input, mouseY will hold the y value of the most recent touch point."
            +      ]
            +    },
            +    "pmouseX": {
            +      "description": [
            +        "The system variable pmouseX always contains the horizontal position of the mouse or finger in the frame previous to the current frame, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX value at the start of each touch event."
            +      ]
            +    },
            +    "pmouseY": {
            +      "description": [
            +        "The system variable pmouseY always contains the vertical position of the mouse or finger in the frame previous to the current frame, relative to (0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY value at the start of each touch event."
            +      ]
            +    },
            +    "winMouseX": {
            +      "description": [
            +        "The system variable winMouseX always contains the current horizontal position of the mouse, relative to (0, 0) of the window."
            +      ]
            +    },
            +    "winMouseY": {
            +      "description": [
            +        "The system variable winMouseY always contains the current vertical position of the mouse, relative to (0, 0) of the window."
            +      ]
            +    },
            +    "pwinMouseX": {
            +      "description": [
            +        "The system variable pwinMouseX always contains the horizontal position of the mouse in the frame previous to the current frame, relative to (0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX value at the start of each touch event."
            +      ]
            +    },
            +    "pwinMouseY": {
            +      "description": [
            +        "The system variable pwinMouseY always contains the vertical position of the mouse in the frame previous to the current frame, relative to (0, 0) of the window. Note: pwinMouseY will be reset to the current winMouseY value at the start of each touch event."
            +      ]
            +    },
            +    "mouseButton": {
            +      "description": [
            +        "Processing automatically tracks if the mouse button is pressed and which button is pressed. The value of the system variable mouseButton is either LEFT, RIGHT, or CENTER depending on which button was pressed last. Warning: different browsers may track mouseButton differently."
            +      ]
            +    },
            +    "mouseIsPressed": {
            +      "description": [
            +        "The boolean system variable mouseIsPressed is true if the mouse is pressed and false if not."
            +      ]
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse button is not pressed. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseDragged": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and a mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the <a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button is pressed. The mouseButton variable (see the related reference entry) can be used to determine which button has been pressed. If no <a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is released. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been pressed and then released. Browsers handle clicks differently, so this function is only guaranteed to be run when the left mouse button is clicked. To handle other mouse buttons being pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>. Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event listener has detected a dblclick event which is a part of the DOM L3 specification. The doubleClicked event is fired when a pointing device button (usually a mouse's primary button) is clicked twice on a single element. For more info on the dblclick event refer to mozilla's documentation here: <a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a>"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel event is detected either triggered by an actual mouse wheel or by a touchpad. The event.delta property returns the amount the mouse wheel have scrolled. The values can be positive or negative depending on the scroll direction (on OS X with \"natural\" scrolling enabled, the signs are inverted). Browsers may have different default behaviors attached to various mouse events. To prevent any default behavior for this event, add \"return false\" to the end of the method. Due to the current support of the \"wheel\" event on Safari, the function may only work as expected if \"return false\" is included while using Safari."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional WheelEvent callback argument."
            +      }
            +    },
            +    "requestPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a> locks the pointer to its current position and makes it invisible. Use <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since the last call of draw. Note that not all browsers support this feature. This enables you to create experiences that aren't limited by the mouse moving out of the screen even if it is repeatedly moved into one direction. For example, a first person perspective experience."
            +      ]
            +    },
            +    "exitPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a> exits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a> for example to make ui elements usable etc"
            +      ]
            +    },
            +    "touches": {
            +      "description": [
            +        "The system variable touches[] contains an array of the positions of all current touch points, relative to (0, 0) of the canvas, and IDs identifying a unique touch as it moves. Each element in the array is an object with x, y, and id properties. ",
            +        "The touches[] array is not supported on Safari and IE on touch-based desktops (laptops)."
            +      ]
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "The touchStarted() function is called once after every time a touch is registered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various touch events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered. If no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various touch events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no <a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be called instead if it is defined. Browsers may have different default behaviors attached to various touch events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "createImage": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a fresh buffer of pixels to play with. Set the size of the buffer with the width and height parameters. ",
            +        ".<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels in the display window. These values are numbers. This array is the size (including an appropriate factor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for more info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>. ",
            +        "Before accessing the pixels of an image, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes."
            +      ],
            +      "returns": "p5.Image: the <a href=\"#/p5.Image\">p5.Image</a> object",
            +      "params": {
            +        "width": "Integer: width in pixels",
            +        "height": "Integer: height in pixels"
            +      }
            +    },
            +    "saveCanvas": {
            +      "description": [
            +        "Save the current canvas as an image. The browser will either save the file immediately, or prompt the user with a dialogue window."
            +      ],
            +      "params": {
            +        "selectedCanvas": "p5.Element|HTMLCanvasElement: a variable  representing a specific html5 canvas (optional)",
            +        "filename": "String (Optional)",
            +        "extension": "String: (Optional) 'jpg' or 'png'"
            +      }
            +    },
            +    "saveFrames": {
            +      "description": [
            +        "Capture a sequence of frames that can be used to create a movie. Accepts a callback. For example, you may wish to send the frames to a server where they can be stored or converted into a movie. If no callback is provided, the browser will pop up save dialogues in an attempt to download all of the images that have just been created. With the callback provided the image data isn't saved by default but instead passed as an argument to the callback function as an array of objects, with the size of array equal to the total number of frames. ",
            +        "Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation. To export longer animations, you might look into a library like <a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>."
            +      ],
            +      "params": {
            +        "filename": "String",
            +        "extension": "String: 'jpg' or 'png'",
            +        "duration": "Number: Duration in seconds to save the frames for.",
            +        "framerate": "Number: Framerate to save the frames in.",
            +        "callback": "Function(Array): (Optional) A callback function that will be executed  to handle the image data. This function  should accept an array as argument. The  array will contain the specified number of  frames of objects. Each object has three  properties: imageData - an  image/octet-stream, filename and extension."
            +      }
            +    },
            +    "loadImage": {
            +      "description": [
            +        "Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it. ",
            +        "The image may not be immediately available for rendering. If you want to ensure that the image is ready before doing anything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>. You may also supply a callback function to handle the image when it's ready. ",
            +        "The path to the image should be relative to the HTML file that links in your sketch. Loading an image from a URL or other remote location may be blocked due to your browser's built-in security. ",
            +        "You can also pass in a string of a base64 encoded image as an alternative to the file path. Remember to add \"data:image/png;base64,\" in front of the string."
            +      ],
            +      "returns": "p5.Image: the <a href=\"#/p5.Image\">p5.Image</a> object",
            +      "params": {
            +        "path": "String: Path of the image to be loaded",
            +        "successCallback": "function(p5.Image): (Optional) Function to be called once  the image is loaded. Will be passed the  <a href=\"#/p5.Image\">p5.Image</a>.",
            +        "failureCallback": "Function(Event): (Optional) called with event error if  the image fails to load."
            +      }
            +    },
            +    "image": {
            +      "description": [
            +        "Draw an image to the p5.js canvas. ",
            +        "This function can be used with different numbers of parameters. The simplest use requires only three parameters: img, x, and y—where (x, y) is the position of the image. Two more parameters can optionally be added to specify the width and height of the image. ",
            +        "This function can also be used with all eight Number parameters. To differentiate between all these parameters, p5.js uses the language of \"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source image\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the \"source image\" dimensions can be useful when you want to display a subsection of the source image instead of the whole thing. Here's a diagram to explain further: <img src=\"assets/drawImage.png\"></img>"
            +      ],
            +      "params": {
            +        "img": "p5.Image|p5.Element: the image to display",
            +        "x": "Number: the x-coordinate of the top-left corner of the image",
            +        "y": "Number: the y-coordinate of the top-left corner of the image",
            +        "width": "Number: (Optional) the width to draw the image",
            +        "height": "Number: (Optional) the height to draw the image",
            +        "dx": "Number: the x-coordinate of the destination  rectangle in which to draw the source image",
            +        "dy": "Number: the y-coordinate of the destination  rectangle in which to draw the source image",
            +        "dWidth": "Number: the width of the destination rectangle",
            +        "dHeight": "Number: the height of the destination rectangle",
            +        "sx": "Number: the x-coordinate of the subsection of the source image to draw into the destination rectangle",
            +        "sy": "Number: the y-coordinate of the subsection of the source image to draw into the destination rectangle",
            +        "sWidth": "Number: (Optional) the width of the subsection of the  source image to draw into the destination  rectangle",
            +        "sHeight": "Number: (Optional) the height of the subsection of the  source image to draw into the destination rectangle"
            +      }
            +    },
            +    "tint": {
            +      "description": [
            +        "Sets the fill value for displaying images. Images can be tinted to specified colors or made transparent by including an alpha value. ",
            +        "To apply transparency to an image without affecting its color, use white as the tint color and specify an alpha value. For instance, tint(255, 128) will make an image 50% transparent (assuming the default alpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>). ",
            +        "The value for the gray parameter must be less than or equal to the current maximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is 255."
            +      ],
            +      "params": {
            +        "v1": "Number: o valor de vermelho ou de matiz (dependendo do formato de cor sendo utilizado)",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "alpha": "Number (Optional)",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the tint color"
            +      }
            +    },
            +    "noTint": {
            +      "description": [
            +        "Removes the current fill value for displaying images and reverts to displaying images with their original hues."
            +      ]
            +    },
            +    "imageMode": {
            +      "description": [
            +        "Set image mode. Modifies the location from which images are drawn by changing the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted. The default mode is imageMode(CORNER), which interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If two additional parameters are specified, they are used to set the image's width and height. ",
            +        "imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the location of one corner, and the fourth and fifth parameters as the opposite corner. ",
            +        "imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the image's center point. If two additional parameters are specified, they are used to set the image's width and height."
            +      ],
            +      "params": {
            +        "mode": "Constant: either CORNER, CORNERS, or CENTER"
            +      }
            +    },
            +    "pixels": {
            +      "description": [
            +        "<a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a> containing the values for all the pixels in the display window. These values are numbers. This array is the size (include an appropriate factor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. Retina and other high density displays will have more pixels[] (by a factor of pixelDensity^2). For example, if the image is 100x100 pixels, there will be 40,000. On a retina display, there will be 160,000. ",
            +        "The first four values (indices 0-3) in the array will be the R, G, B, A values of the pixel at (0, 0). The second four values (indices 4-7) will contain the R, G, B, A values of the pixel at (1, 0). More generally, to set values for a pixel at (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre> ",
            +        "While the above method is complex, it is flexible enough to work with any pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of setting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at any pixelDensity, but the performance may not be as fast when lots of modifications are made to the pixel array. ",
            +        "Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a> function must be run to update the changes. ",
            +        "Note that this is not a standard javascript array. This means that standard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or <a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not work."
            +      ]
            +    },
            +    "blend": {
            +      "description": [
            +        "Copies a region of pixels from one image to another, using a specified blend mode to do the operation."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height",
            +        "blendMode": "Constant: the blend mode. either  BLEND, DARKEST, LIGHTEST, DIFFERENCE,  MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD or NORMAL."
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Copies a region of the canvas to another region of the canvas and copies a region of pixels from an image used as the srcImg parameter into the canvas srcImage is specified this is used as the source. If the source and destination regions aren't the same size, it will automatically resize source pixels to fit the specified target region."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5.Element: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Applies a filter to the canvas. The presets options are: ",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used. ",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used. ",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used. ",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used. ",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges. ",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur. ",
            +        "ERODE Reduces the light areas. No parameter is used. ",
            +        "DILATE Increases the light areas. No parameter is used. ",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "Constant: either THRESHOLD, GRAY, OPAQUE, INVERT,  POSTERIZE, BLUR, ERODE, DILATE or BLUR.  See Filters.js for docs on  each available filter",
            +        "filterParam": "Number: (Optional) an optional parameter unique  to each filter, see above"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Get a region of pixels, or a single pixel, from the canvas. ",
            +        "Returns an array of [R,G,B,A] values for any pixel or grabs a section of an image. If no parameters are specified, the entire image is returned. Use the x and y parameters to get the value of one pixel. Get a section of the display window by specifying additional w and h parameters. When getting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>. ",
            +        "Getting the color of a single pixel with get(x, y) is easy, but not as fast as grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to get(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is <pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates let off = (y * width + x) * d * 4; let components = [  pixels[off],  pixels[off + 1],  pixels[off + 2],  pixels[off + 3] ]; print(components);</code></pre> ",
            +        "See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information. ",
            +        "If you want to extract an array of colors or a subimage from an p5.Image object, take a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a>"
            +      ],
            +      "returns": "p5.Image: the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "w": "Number: width",
            +        "h": "Number: height"
            +      }
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This function must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>. Note that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a> will occur."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Changes the color of any pixel, or writes an image directly to the display window. The x and y parameters specify the pixel to change and the c parameter specifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A] pixel array. It can also be a single grayscale value. When setting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>. ",
            +        "After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear. This should be called once all pixels have been set, and must be called before calling .<a href=\"#/p5/get\">get()</a> or drawing the image. ",
            +        "Setting the color of a single pixel with set(x, y) is easy, but not as fast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a> values directly may be complicated when working with a retina display, but will perform better when lots of pixels need to be set directly on every loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "c": "Number|Number[]|Object: insert a grayscale value | a pixel array |  a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy"
            +      }
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array. Use in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from the array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only necessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the pixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with <a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur."
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) x-coordinate of the upper-left corner of region  to update",
            +        "y": "Number: (Optional) y-coordinate of the upper-left corner of region  to update",
            +        "w": "Number: (Optional) width of region to update",
            +        "h": "Number: (Optional) height of region to update"
            +      }
            +    },
            +    "loadJSON": {
            +      "description": [
            +        "Loads a JSON file from a file or a URL, and returns an Object. Note that even if the JSON file contains an Array, an Object will be returned with index numbers as keys. ",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. JSONP is supported via a polyfill and you can pass in as the second argument an object with definitions of the json callback following the syntax specified <a href=\"https://github.com/camsong/ fetch-jsonp\">here</a>. ",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object|Array: JSON data",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "jsonpOptions": "Object: (Optional) options object for jsonp related settings",
            +        "datatype": "String: (Optional) \"json\" or \"jsonp\"",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed  in as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadStrings": {
            +      "description": [
            +        "Reads the contents of a file and creates a String array of its individual lines. If the name of the file is used as the parameter, as in the above example, the file must be located in the sketch directory/folder. ",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. ",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. ",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "String[]: Array of Strings",
            +      "params": {
            +        "filename": "String: name of the file or url to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>  completes, Array is passed in as first  argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadTable": {
            +      "description": [
            +        "Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with its values. If a file is specified, it must be located in the sketch's \"data\" folder. The filename parameter can also be a URL to a file found online. By default, the file is assumed to be comma-separated (in CSV format). Table only looks for a header row if the 'header' option is included. ",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called. Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object: ",
            +        "All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: <a href=\"#/p5.Table\">Table</a> object containing data",
            +      "params": {
            +        "filename": "String: name of the file or URL to load",
            +        "extension": "String: (Optional) parse the table by comma-separated values \"csv\", semicolon-separated  values \"ssv\", or tab-separated values \"tsv\"",
            +        "header": "String: (Optional) \"header\" to indicate table has header row",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the  <a href=\"#/p5.Table\">Table</a> object is passed in as the  first argument.",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadXML": {
            +      "description": [
            +        "Reads the contents of a file and creates an XML object with its values. If the name of the file is used as the parameter, as in the above example, the file must be located in the sketch directory/folder. ",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network. ",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called. ",
            +        "Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object. ",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: XML object containing data",
            +      "params": {
            +        "filename": "String: name of the file or URL to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>  completes, XML object is passed in as  first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "loadBytes": {
            +      "description": [
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "Object: an object whose 'bytes' property will be the loaded buffer",
            +      "params": {
            +        "file": "String: name of the file or URL to load",
            +        "callback": "Function: (Optional) function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>  completes",
            +        "errorCallback": "Function: (Optional) function to be executed if there  is an error"
            +      }
            +    },
            +    "httpGet": {
            +      "description": [
            +        "Method for executing an HTTP GET request. If data type is not specified, p5 will try to guess based on the URL, defaulting to text. This is equivalent to calling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return a Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer which can be used to initialize typed arrays (such as Uint8Array)."
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "datatype": "String: (Optional) \"json\", \"jsonp\", \"binary\", \"arrayBuffer\",  \"xml\", or \"text\"",
            +        "data": "Object|Boolean: (Optional) param data passed sent with request",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in  as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "httpPost": {
            +      "description": [
            +        "Method for executing an HTTP POST request. If data type is not specified, p5 will try to guess based on the URL, defaulting to text. This is equivalent to calling <code>httpDo(path, 'POST')</code>."
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "datatype": "String: (Optional) \"json\", \"jsonp\", \"xml\", or \"text\".  If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.",
            +        "data": "Object|Boolean: (Optional) param data passed sent with request",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in  as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument"
            +      }
            +    },
            +    "httpDo": {
            +      "description": [
            +        "Method for executing an HTTP request. If data type is not specified, p5 will try to guess based on the URL, defaulting to text. For more advanced use, you may also pass in the path as the first argument and a object as the second argument, the signature follows the one specified in the Fetch API specification. This method is suitable for fetching files up to size of 64MB when \"GET\" is used."
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "method": "String: (Optional) either \"GET\", \"POST\", or \"PUT\",  defaults to \"GET\"",
            +        "datatype": "String: (Optional) \"json\", \"jsonp\", \"xml\", or \"text\"",
            +        "data": "Object: (Optional) param data passed sent with request",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in  as first argument",
            +        "errorCallback": "Function: (Optional) function to be executed if  there is an error, response is passed  in as first argument",
            +        "options": "Object: Request object options as documented in the  \"fetch\" API <a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a>"
            +      }
            +    },
            +    "createWriter": {
            +      "returns": "p5.PrintWriter: ",
            +      "params": {
            +        "name": "String: name of the file to be created",
            +        "extension": "String (Optional)"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "Saves a given element(image, text, json, csv, wav, or html) to the client's computer. The first parameter can be a pointer to element we want to save. The element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of Strings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table </a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires p5.sound). The second parameter is a filename (including extension).The third parameter is for options specific to this type of object. This method will save a file that fits the given parameters. If it is called without specifying an element, by default it will save the whole canvas as an image file. You can optionally specify a filename as the first parameter in such a case. <strong>Note that it is not recommended to call this method within draw, as it will open a new save dialog on every render.</strong>"
            +      ],
            +      "params": {
            +        "objectOrFilename": "Object|String: (Optional) If filename is provided, will  save canvas as an image with  either png or jpg extension  depending on the filename.  If object is provided, will  save depending on the object  and filename (see examples  above).",
            +        "filename": "String: (Optional) If an object is provided as the first  parameter, then the second parameter  indicates the filename,  and should include an appropriate  file extension (see examples above).",
            +        "options": "Boolean|String: (Optional) Additional options depend on  filetype. For example, when saving JSON,  <code>true</code> indicates that the  output will be optimized for filesize,  rather than readability."
            +      }
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "Writes the contents of an Array or a JSON object to a .json file. The file saving process and location of the saved file will vary between web browsers."
            +      ],
            +      "params": {
            +        "json": "Array|Object",
            +        "filename": "String",
            +        "optimize": "Boolean: (Optional) If true, removes line breaks  and spaces from the output  file to optimize filesize  (but not readability)."
            +      }
            +    },
            +    "saveStrings": {
            +      "description": [
            +        "Writes an array of Strings to a text file, one line per String. The file saving process and location of the saved file will vary between web browsers."
            +      ],
            +      "params": {
            +        "list": "String[]: string array to be written",
            +        "filename": "String: filename for output",
            +        "extension": "String: (Optional) the filename's extension",
            +        "isCRLF": "Boolean: (Optional) if true, change line-break to CRLF"
            +      }
            +    },
            +    "saveTable": {
            +      "description": [
            +        "Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a text file with comma-separated-values ('csv') but can also use tab separation ('tsv'), or generate an HTML table ('html'). The file saving process and location of the saved file will vary between web browsers."
            +      ],
            +      "params": {
            +        "Table": "p5.Table: the <a href=\"#/p5.Table\">Table</a> object to save to a file",
            +        "filename": "String: the filename to which the Table should be saved",
            +        "options": "String: (Optional) can be one of \"tsv\", \"csv\", or \"html\""
            +      }
            +    },
            +    "abs": {
            +      "description": [
            +        "Calculates the absolute value (magnitude) of a number. Maps to Math.abs(). The absolute value of a number is always positive."
            +      ],
            +      "returns": "Number: absolute value of given number",
            +      "params": {
            +        "n": "Number: number to compute"
            +      }
            +    },
            +    "ceil": {
            +      "description": [
            +        "Calculates the closest int value that is greater than or equal to the value of the parameter. Maps to Math.ceil(). For example, ceil(9.03) returns the value 10."
            +      ],
            +      "returns": "Integer: rounded up number",
            +      "params": {
            +        "n": "Number: number to round up"
            +      }
            +    },
            +    "constrain": {
            +      "description": [
            +        "Constrains a value between a minimum and maximum value."
            +      ],
            +      "returns": "Number: constrained number",
            +      "params": {
            +        "n": "Number: number to constrain",
            +        "low": "Number: minimum limit",
            +        "high": "Number: maximum limit"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "Calculates the distance between two points, in either two or three dimensions."
            +      ],
            +      "returns": "Number: distance between the two points",
            +      "params": {
            +        "x1": "Number: x-coordinate do primeiro ponto",
            +        "y1": "Number: y-coordinate do primeiro ponto",
            +        "x2": "Number: x-coordinate do segundo ponto",
            +        "y2": "Number: y-coordinate do segundo ponto",
            +        "z1": "Number: z-coordinate do primeiro ponto",
            +        "z2": "Number: z-coordinate do segundo ponto"
            +      }
            +    },
            +    "exp": {
            +      "description": [
            +        "Returns Euler's number e (2.71828...) raised to the power of the n parameter. Maps to Math.exp()."
            +      ],
            +      "returns": "Number: e^n",
            +      "params": {
            +        "n": "Number: exponent to raise"
            +      }
            +    },
            +    "floor": {
            +      "description": [
            +        "Calculates the closest int value that is less than or equal to the value of the parameter. Maps to Math.floor()."
            +      ],
            +      "returns": "Integer: rounded down number",
            +      "params": {
            +        "n": "Number: number to round down"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "Calculates a number between two numbers at a specific increment. The amt parameter is the amount to interpolate between the two values where 0.0 equal to the first point, 0.1 is very near the first point, 0.5 is half-way in between, and 1.0 is equal to the second point. If the value of amt is more than 1.0 or less than 0.0, the number will be calculated accordingly in the ratio of the two given numbers. The lerp function is convenient for creating motion along a straight path and for drawing dotted lines."
            +      ],
            +      "returns": "Number: lerped value",
            +      "params": {
            +        "start": "Number: first value",
            +        "stop": "Number: second value",
            +        "amt": "Number: number"
            +      }
            +    },
            +    "log": {
            +      "description": [
            +        "Calculates the natural logarithm (the base-e logarithm) of a number. This function expects the n parameter to be a value greater than 0.0. Maps to Math.log()."
            +      ],
            +      "returns": "Number: natural logarithm of n",
            +      "params": {
            +        "n": "Number: number greater than 0"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "Calculates the magnitude (or length) of a vector. A vector is a direction in space commonly used in computer graphics and linear algebra. Because it has no \"start\" position, the magnitude of a vector can be thought of as the distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is a shortcut for writing dist(0, 0, x, y)."
            +      ],
            +      "returns": "Number: magnitude of vector from (0,0) to (a,b)",
            +      "params": {
            +        "a": "Number: first value",
            +        "b": "Number: second value"
            +      }
            +    },
            +    "map": {
            +      "description": [
            +        "Re-maps a number from one range to another. ",
            +        "In the first example above, the number 25 is converted from a value in the range of 0 to 100 into a value that ranges from the left edge of the window (0) to the right edge (width)."
            +      ],
            +      "returns": "Number: remapped number",
            +      "params": {
            +        "value": "Number: the incoming value to be converted",
            +        "start1": "Number: lower bound of the value's current range",
            +        "stop1": "Number: upper bound of the value's current range",
            +        "start2": "Number: lower bound of the value's target range",
            +        "stop2": "Number: upper bound of the value's target range",
            +        "withinBounds": "Boolean: (Optional) constrain the value to the newly mapped range"
            +      }
            +    },
            +    "max": {
            +      "description": [
            +        "Determines the largest value in a sequence of numbers, and then returns that value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array of any length."
            +      ],
            +      "returns": "Number: maximum Number",
            +      "params": {
            +        "n0": "Number: Number to compare",
            +        "n1": "Number: Number to compare",
            +        "nums": "Number[]: Numbers to compare"
            +      }
            +    },
            +    "min": {
            +      "description": [
            +        "Determines the smallest value in a sequence of numbers, and then returns that value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array of any length."
            +      ],
            +      "returns": "Number: minimum Number",
            +      "params": {
            +        "n0": "Number: Number to compare",
            +        "n1": "Number: Number to compare",
            +        "nums": "Number[]: Numbers to compare"
            +      }
            +    },
            +    "norm": {
            +      "description": [
            +        "Normalizes a number from another range into a value between 0 and 1. Identical to map(value, low, high, 0, 1). Numbers outside of the range are not clamped to 0 and 1, because out-of-range values are often intentional and useful. (See the example above.)"
            +      ],
            +      "returns": "Number: normalized number",
            +      "params": {
            +        "value": "Number: incoming value to be normalized",
            +        "start": "Number: lower bound of the value's current range",
            +        "stop": "Number: upper bound of the value's current range"
            +      }
            +    },
            +    "pow": {
            +      "description": [
            +        "Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient way of multiplying numbers by themselves (or their reciprocals) in large quantities. For example, pow(3, 5) is equivalent to the expression 3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 / 3 × 3 × 3 × 3 × 3. Maps to Math.pow()."
            +      ],
            +      "returns": "Number: n^e",
            +      "params": {
            +        "n": "Number: base of the exponential expression",
            +        "e": "Number: power by which to raise the base"
            +      }
            +    },
            +    "round": {
            +      "description": [
            +        "Calculates the integer closest to the n parameter. For example, round(133.8) returns the value 134. Maps to Math.round()."
            +      ],
            +      "returns": "Integer: rounded number",
            +      "params": {
            +        "n": "Number: number to round",
            +        "decimals": "Number: (Optional) number of decimal places to round to, default is 0"
            +      }
            +    },
            +    "sq": {
            +      "description": [
            +        "Squares a number (multiplies a number by itself). The result is always a positive number, as multiplying two negative numbers always yields a positive result. For example, -1 * -1 = 1."
            +      ],
            +      "returns": "Number: squared number",
            +      "params": {
            +        "n": "Number: number to square"
            +      }
            +    },
            +    "sqrt": {
            +      "description": [
            +        "Calculates the square root of a number. The square root of a number is always positive, even though there may be a valid negative root. The square root s of number a is such that s*s = a. It is the opposite of squaring. Maps to Math.sqrt()."
            +      ],
            +      "returns": "Number: square root of number",
            +      "params": {
            +        "n": "Number: non-negative number to square root"
            +      }
            +    },
            +    "fract": {
            +      "description": [
            +        "Calculates the fractional part of a number."
            +      ],
            +      "returns": "Number: fractional part of x, i.e, {x}",
            +      "params": {
            +        "num": "Number: Number whose fractional part needs to be found out"
            +      }
            +    },
            +    "createVector": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector. A vector is an entity that has both magnitude and direction."
            +      ],
            +      "returns": "p5.Vector: ",
            +      "params": {
            +        "x": "Number: (Optional) x component of the vector",
            +        "y": "Number: (Optional) y component of the vector",
            +        "z": "Number: (Optional) z component of the vector"
            +      }
            +    },
            +    "noise": {
            +      "description": [
            +        "Returns the Perlin noise value at specified coordinates. Perlin noise is a random sequence generator producing a more naturally ordered, harmonic succession of numbers compared to the standard <b>random()</b> function. It was invented by Ken Perlin in the 1980s and been used since in graphical applications to produce procedural textures, natural motion, shapes, terrains etc.",
            +        "The main difference to the <b>random()</b> function is that Perlin noise is defined in an infinite n-dimensional space where each pair of coordinates corresponds to a fixed semi-random value (fixed only for the lifespan of the program; see the <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise, depending on the number of coordinates given. The resulting value will always be between 0.0 and 1.0. The noise value can be animated by moving through the noise space as demonstrated in the example above. The 2nd and 3rd dimension can also be interpreted as time.",
            +        "The actual noise is structured similar to an audio signal, in respect to the function's use of frequencies. Similar to the concept of harmonics in physics, perlin noise is computed over several octaves which are added together for the final result. ",
            +        "Another way to adjust the character of the resulting sequence is the scale of the input coordinates. As the function works within an infinite space the value of the coordinates doesn't matter as such, only the distance between successive coordinates does (eg. when using <b>noise()</b> within a loop). As a general rule the smaller the difference between coordinates, the smoother the resulting noise sequence will be. Steps of 0.005-0.03 work best for most applications, but this will differ depending on use."
            +      ],
            +      "returns": "Number: Perlin noise value (between 0 and 1) at specified  coordinates",
            +      "params": {
            +        "x": "Number: x-coordinate in noise space",
            +        "y": "Number: (Optional) y-coordinate in noise space",
            +        "z": "Number: (Optional) z-coordinate in noise space"
            +      }
            +    },
            +    "noiseDetail": {
            +      "description": [
            +        "Adjusts the character and level of detail produced by the Perlin noise  function. Similar to harmonics in physics, noise is computed over  several octaves. Lower octaves contribute more to the output signal and  as such define the overall intensity of the noise, whereas higher octaves  create finer grained details in the noise sequence. By default, noise is computed over 4 octaves with each octave contributing  exactly half than its predecessor, starting at 50% strength for the 1st  octave. This falloff amount can be changed by adding an additional function  parameter. Eg. a falloff factor of 0.75 means each octave will now have  75% impact (25% less) of the previous lower octave. Any value between  0.0 and 1.0 is valid, however note that values greater than 0.5 might  result in greater than 1.0 values returned by <b>noise()</b>. By changing these parameters, the signal created by the <b>noise()</b>  function can be adapted to fit very specific needs and characteristics."
            +      ],
            +      "params": {
            +        "lod": "Number: number of octaves to be used by the noise",
            +        "falloff": "Number: falloff factor for each octave"
            +      }
            +    },
            +    "noiseSeed": {
            +      "description": [
            +        "Sets the seed value for <b>noise()</b>. By default, <b>noise()</b> produces different results each time the program is run. Set the <b>value</b> parameter to a constant to return the same pseudo-random numbers each time the software is run."
            +      ],
            +      "params": {
            +        "seed": "Number: the seed value"
            +      }
            +    },
            +    "randomSeed": {
            +      "description": [
            +        "Sets the seed value for <a href=\"#/p5/random\">random()</a>. ",
            +        "By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program is run. Set the seed parameter to a constant to return the same pseudo-random numbers each time the software is run."
            +      ],
            +      "params": {
            +        "seed": "Number: the seed value"
            +      }
            +    },
            +    "random": {
            +      "description": [
            +        "Return a random floating-point number. ",
            +        "Takes either 0, 1 or 2 arguments. ",
            +        "If no argument is given, returns a random number from 0 up to (but not including) 1. ",
            +        "If one argument is given and it is a number, returns a random number from 0 up to (but not including) the number. ",
            +        "If one argument is given and it is an array, returns a random element from that array. ",
            +        "If two arguments are given, returns a random number from the first argument up to (but not including) the second argument."
            +      ],
            +      "returns": "Number: the random number",
            +      "params": {
            +        "min": "Number: (Optional) the lower bound (inclusive)",
            +        "max": "Number: (Optional) the upper bound (exclusive)",
            +        "choices": "Array: the array to choose from"
            +      }
            +    },
            +    "randomGaussian": {
            +      "description": [
            +        "Returns a random number fitting a Gaussian, or  normal, distribution. There is theoretically no minimum or maximum  value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is  just a very low probability that values far from the mean will be  returned; and a higher probability that numbers near the mean will  be returned. Takes either 0, 1 or 2 arguments.  If no args, returns a mean of 0 and standard deviation of 1.  If one arg, that arg is the mean (standard deviation is 1).  If two args, first is mean, second is standard deviation."
            +      ],
            +      "returns": "Number: the random number",
            +      "params": {
            +        "mean": "Number: (Optional) the mean",
            +        "sd": "Number: (Optional) the standard deviation"
            +      }
            +    },
            +    "acos": {
            +      "description": [
            +        "The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value. This function expects the values in the range of -1 to 1 and values are returned in the range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the angle mode is DEGREES."
            +      ],
            +      "returns": "Number: the arc cosine of the given value",
            +      "params": {
            +        "value": "Number: the value whose arc cosine is to be returned"
            +      }
            +    },
            +    "asin": {
            +      "description": [
            +        "The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value. This function expects the values in the range of -1 to 1 and values are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle mode is DEGREES."
            +      ],
            +      "returns": "Number: the arc sine of the given value",
            +      "params": {
            +        "value": "Number: the value whose arc sine is to be returned"
            +      }
            +    },
            +    "atan": {
            +      "description": [
            +        "The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value. This function expects the values in the range of -Infinity to Infinity (exclusive) and values are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle mode is DEGREES."
            +      ],
            +      "returns": "Number: the arc tangent of the given value",
            +      "params": {
            +        "value": "Number: the value whose arc tangent is to be returned"
            +      }
            +    },
            +    "atan2": {
            +      "description": [
            +        "Calculates the angle (in radians) from a specified point to the coordinate origin as measured from the positive x-axis. Values are returned as a float in the range from PI to -PI if the angleMode is RADIANS or 180 to -180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is most often used for orienting geometry to the position of the cursor. ",
            +        "Note: The y-coordinate of the point is the first parameter, and the x-coordinate is the second parameter, due the the structure of calculating the tangent."
            +      ],
            +      "returns": "Number: the arc tangent of the given point",
            +      "params": {
            +        "y": "Number: y-coordinate of the point",
            +        "x": "Number: x-coordinate of the point"
            +      }
            +    },
            +    "cos": {
            +      "description": [
            +        "Calculates the cosine of an angle. This function takes into account the current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1."
            +      ],
            +      "returns": "Number: the cosine of the angle",
            +      "params": {
            +        "angle": "Number: the angle"
            +      }
            +    },
            +    "sin": {
            +      "description": [
            +        "Calculates the sine of an angle. This function takes into account the current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1."
            +      ],
            +      "returns": "Number: the sine of the angle",
            +      "params": {
            +        "angle": "Number: the angle"
            +      }
            +    },
            +    "tan": {
            +      "description": [
            +        "Calculates the tangent of an angle. This function takes into account the current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers."
            +      ],
            +      "returns": "Number: the tangent of the angle",
            +      "params": {
            +        "angle": "Number: the angle"
            +      }
            +    },
            +    "degrees": {
            +      "description": [
            +        "Converts a radian measurement to its corresponding value in degrees. Radians and degrees are two ways of measuring the same thing. There are 360 degrees in a circle and 2*PI radians in a circle. For example, 90° = PI/2 = 1.5707964. This function does not take into account the current <a href=\"#/p5/angleMode\">angleMode</a>."
            +      ],
            +      "returns": "Number: the converted angle",
            +      "params": {
            +        "radians": "Number: the radians value to convert to degrees"
            +      }
            +    },
            +    "radians": {
            +      "description": [
            +        "Converts a degree measurement to its corresponding value in radians. Radians and degrees are two ways of measuring the same thing. There are 360 degrees in a circle and 2*PI radians in a circle. For example, 90° = PI/2 = 1.5707964. This function does not take into account the current <a href=\"#/p5/angleMode\">angleMode</a>."
            +      ],
            +      "returns": "Number: the converted angle",
            +      "params": {
            +        "degrees": "Number: the degree value to convert to radians"
            +      }
            +    },
            +    "angleMode": {
            +      "description": [
            +        "Sets the current mode of p5 to given mode. Default mode is RADIANS."
            +      ],
            +      "params": {
            +        "mode": "Constant: either RADIANS or DEGREES"
            +      }
            +    },
            +    "textAlign": {
            +      "description": [
            +        "Sets the current alignment for drawing text. Accepts two arguments: horizAlign (LEFT, CENTER, or RIGHT) and vertAlign (TOP, BOTTOM, CENTER, or BASELINE). ",
            +        "The horizAlign parameter is in reference to the x value of the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter is in reference to the y value. ",
            +        "So if you write textAlign(LEFT), you are aligning the left edge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>. If you write textAlign(RIGHT, TOP), you are aligning the right edge of your text to the x value and the top of edge of the text to the y value."
            +      ],
            +      "params": {
            +        "horizAlign": "Constant: horizontal alignment, either LEFT,  CENTER, or RIGHT",
            +        "vertAlign": "Constant: (Optional) vertical alignment, either TOP,  BOTTOM, CENTER, or BASELINE"
            +      }
            +    },
            +    "textLeading": {
            +      "description": [
            +        "Sets/gets the spacing, in pixels, between lines of text. This setting will be used in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function."
            +      ],
            +      "params": {
            +        "leading": "Number: the size in pixels for spacing between lines"
            +      }
            +    },
            +    "textSize": {
            +      "description": [
            +        "Sets/gets the current font size. This size will be used in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels."
            +      ],
            +      "params": {
            +        "theSize": "Number: the size of the letters in units of pixels"
            +      }
            +    },
            +    "textStyle": {
            +      "description": [
            +        "Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC. Note: this may be is overridden by CSS styling. For non-system fonts (opentype, truetype, etc.) please load styled fonts instead."
            +      ],
            +      "params": {
            +        "theStyle": "Constant: styling for text, either NORMAL,  ITALIC, BOLD or BOLDITALIC"
            +      }
            +    },
            +    "textWidth": {
            +      "description": [
            +        "Calculates and returns the width of any character or text string."
            +      ],
            +      "returns": "Number: the calculated width",
            +      "params": {
            +        "theText": "String: the String of characters to measure"
            +      }
            +    },
            +    "textAscent": {
            +      "description": [
            +        "Returns the ascent of the current font at its current size. The ascent represents the distance, in pixels, of the tallest character above the baseline."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "textDescent": {
            +      "description": [
            +        "Returns the descent of the current font at its current size. The descent represents the distance, in pixels, of the character with the longest descender below the baseline."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "loadFont": {
            +      "description": [
            +        "Loads an opentype font file (.otf, .ttf) from a file or a URL, and returns a PFont Object. This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. ",
            +        "The path to the font should be relative to the HTML file that links in your sketch. Loading fonts from a URL or other remote location may be blocked due to your browser's built-in security."
            +      ],
            +      "returns": "p5.Font: <a href=\"#/p5.Font\">p5.Font</a> object",
            +      "params": {
            +        "path": "String: name of the file or url to load",
            +        "callback": "Function: (Optional) function to be executed after  <a href=\"#/p5/loadFont\">loadFont()</a> completes",
            +        "onError": "Function: (Optional) function to be executed if  an error occurs"
            +      }
            +    },
            +    "text": {
            +      "description": [
            +        "Draws text to the screen. Displays the information specified in the first parameter on the screen in the position specified by the additional parameters. A default font will be used unless a font is set with the <a href=\"#/p5/textFont\">textFont()</a> function and a default size will be used unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change the color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change the outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and <a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions. ",
            +        "The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a> function, which gives the option to draw to the left, right, and center of the coordinates. ",
            +        "The x2 and y2 parameters define a rectangular area to display within and may only be used with string data. When these parameters are specified, they are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a> setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. If x2 and y2 are not specified, the baseline alignment is the default, which means that the text will be drawn upwards from x and y. ",
            +        "<b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font using the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above). <a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode."
            +      ],
            +      "params": {
            +        "str": "String|Object|Array|Number|Boolean: the alphanumeric  symbols to be displayed",
            +        "x": "Number: x-coordinate of text",
            +        "y": "Number: y-coordinate of text",
            +        "x2": "Number: (Optional) by default, the width of the text box,  see <a href=\"#/p5/rectMode\">rectMode()</a> for more info",
            +        "y2": "Number: (Optional) by default, the height of the text box,  see <a href=\"#/p5/rectMode\">rectMode()</a> for more info"
            +      }
            +    },
            +    "textFont": {
            +      "description": [
            +        "Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function. If textFont() is called without any argument, it will return the current font if one has been set already. If not, it will return the name of the default font as a string. If textFont() is called with a font to use, it will return the p5 object. ",
            +        "<b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported."
            +      ],
            +      "returns": "Object: the current font / p5 Object",
            +      "params": {
            +        "font": "Object|String: a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>, or a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a> (a font that is generally available across all systems)",
            +        "size": "Number: (Optional) the font size to use"
            +      }
            +    },
            +    "append": {
            +      "description": [
            +        "Adds a value to the end of an array. Extends the length of the array by one. Maps to Array.push()."
            +      ],
            +      "returns": "Array: the array that was appended to",
            +      "params": {
            +        "array": "Array: Array to append",
            +        "value": "Any: to be added to the Array"
            +      }
            +    },
            +    "arrayCopy": {
            +      "description": [
            +        "Copies an array (or part of an array) to another array. The src array is copied to the dst array, beginning at the position specified by srcPosition and into the position specified by dstPosition. The number of elements to copy is determined by length. Note that copying values overwrites existing values in the destination array. To append values instead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>. ",
            +        "The simplified version with only two arguments, arrayCopy(src, dst), copies an entire array to another of the same size. It is equivalent to arrayCopy(src, 0, dst, 0, src.length). ",
            +        "Using this function is far more efficient for copying array data than iterating through a for() loop and copying each element individually."
            +      ],
            +      "params": {
            +        "src": "Array: the source Array",
            +        "srcPosition": "Integer: starting position in the source Array",
            +        "dst": "Array: the destination Array",
            +        "dstPosition": "Integer: starting position in the destination Array",
            +        "length": "Integer: number of Array elements to be copied"
            +      }
            +    },
            +    "concat": {
            +      "description": [
            +        "Concatenates two arrays, maps to Array.concat(). Does not modify the input arrays."
            +      ],
            +      "returns": "Array: concatenated array",
            +      "params": {
            +        "a": "Array: first Array to concatenate",
            +        "b": "Array: second Array to concatenate"
            +      }
            +    },
            +    "reverse": {
            +      "description": [
            +        "Reverses the order of an array, maps to Array.reverse()"
            +      ],
            +      "returns": "Array: the reversed list",
            +      "params": {
            +        "list": "Array: Array to reverse"
            +      }
            +    },
            +    "shorten": {
            +      "description": [
            +        "Decreases an array by one element and returns the shortened array, maps to Array.pop()."
            +      ],
            +      "returns": "Array: shortened Array",
            +      "params": {
            +        "list": "Array: Array to shorten"
            +      }
            +    },
            +    "shuffle": {
            +      "description": [
            +        "Randomizes the order of the elements of an array. Implements <a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank> Fisher-Yates Shuffle Algorithm</a>."
            +      ],
            +      "returns": "Array: shuffled Array",
            +      "params": {
            +        "array": "Array: Array to shuffle",
            +        "bool": "Boolean: (Optional) modify passed array"
            +      }
            +    },
            +    "sort": {
            +      "description": [
            +        "Sorts an array of numbers from smallest to largest, or puts an array of words in alphabetical order. The original array is not modified; a re-ordered array is returned. The count parameter states the number of elements to sort. For example, if there are 12 elements in an array and count is set to 5, only the first 5 elements in the array will be sorted."
            +      ],
            +      "returns": "Array: the sorted list",
            +      "params": {
            +        "list": "Array: Array to sort",
            +        "count": "Integer: (Optional) number of elements to sort, starting from 0"
            +      }
            +    },
            +    "splice": {
            +      "description": [
            +        "Inserts a value or an array of values into an existing array. The first parameter specifies the initial array to be modified, and the second parameter defines the data to be inserted. The third parameter is an index value which specifies the array position from which to insert data. (Remember that array index numbering starts at zero, so the first position is 0, the second position is 1, and so on.)"
            +      ],
            +      "returns": "Array: the list",
            +      "params": {
            +        "list": "Array: Array to splice into",
            +        "value": "Any: value to be spliced in",
            +        "position": "Integer: in the array from which to insert data"
            +      }
            +    },
            +    "subset": {
            +      "description": [
            +        "Extracts an array of elements from an existing array. The list parameter defines the array from which the elements will be copied, and the start and count parameters specify which elements to extract. If no count is given, elements will be extracted from the start to the end of the array. When specifying the start, remember that the first array element is 0. This function does not change the source array."
            +      ],
            +      "returns": "Array: Array of extracted elements",
            +      "params": {
            +        "list": "Array: Array to extract from",
            +        "start": "Integer: position to begin",
            +        "count": "Integer: (Optional) number of values to extract"
            +      }
            +    },
            +    "float": {
            +      "description": [
            +        "Converts a string to its floating point representation. The contents of a string must resemble a number, or NaN (not a number) will be returned. For example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\") will return NaN. ",
            +        "When an array of values is passed in, then an array of floats of the same length is returned."
            +      ],
            +      "returns": "Number: floating point representation of string",
            +      "params": {
            +        "str": "String: float string to parse"
            +      }
            +    },
            +    "int": {
            +      "description": [
            +        "Converts a boolean, string, or float to its integer representation. When an array of values is passed in, then an int array of the same length is returned."
            +      ],
            +      "returns": "Number: integer representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number: value to parse",
            +        "radix": "Integer: (Optional) the radix to convert to (default: 10)",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "str": {
            +      "description": [
            +        "Converts a boolean, string or number to its string representation. When an array of values is passed in, then an array of strings of the same length is returned."
            +      ],
            +      "returns": "String: string representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number|Array: value to parse"
            +      }
            +    },
            +    "byte": {
            +      "description": [
            +        "Converts a number, string representation of a number, or boolean to its byte representation. A byte can be only a whole number between -128 and 127, so when a value outside of this range is converted, it wraps around to the corresponding byte representation. When an array of number, string or boolean values is passed in, then an array of bytes the same length is returned."
            +      ],
            +      "returns": "Number: byte representation of value",
            +      "params": {
            +        "n": "String|Boolean|Number: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "char": {
            +      "description": [
            +        "Converts a number or string to its corresponding single-character string representation. If a string parameter is provided, it is first parsed as an integer and then translated into a single-character string. When an array of number or string values is passed in, then an array of single-character strings of the same length is returned."
            +      ],
            +      "returns": "String: string representation of value",
            +      "params": {
            +        "n": "String|Number: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "unchar": {
            +      "description": [
            +        "Converts a single-character string to its corresponding integer representation. When an array of single-character string values is passed in, then an array of integers of the same length is returned."
            +      ],
            +      "returns": "Number: integer representation of value",
            +      "params": {
            +        "n": "String: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "hex": {
            +      "description": [
            +        "Converts a number to a string in its equivalent hexadecimal notation. If a second parameter is passed, it is used to set the number of characters to generate in the hexadecimal notation. When an array is passed in, an array of strings in hexadecimal notation of the same length is returned."
            +      ],
            +      "returns": "String: hexadecimal string representation of value",
            +      "params": {
            +        "n": "Number: value to parse",
            +        "digits": "Number (Optional)",
            +        "ns": "Number[]: array of values to parse"
            +      }
            +    },
            +    "unhex": {
            +      "description": [
            +        "Converts a string representation of a hexadecimal number to its equivalent integer value. When an array of strings in hexadecimal notation is passed in, an array of integers of the same length is returned."
            +      ],
            +      "returns": "Number: integer representation of hexadecimal value",
            +      "params": {
            +        "n": "String: value to parse",
            +        "ns": "Array: values to parse"
            +      }
            +    },
            +    "join": {
            +      "description": [
            +        "Combines an array of Strings into one String, each separated by the character(s) used for the separator parameter. To join arrays of ints or floats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or nfs()."
            +      ],
            +      "returns": "String: joined String",
            +      "params": {
            +        "list": "Array: array of Strings to be joined",
            +        "separator": "String: String to be placed between each item"
            +      }
            +    },
            +    "match": {
            +      "description": [
            +        "Esta função é usada para aplicar uma expressão regular a um trecho de texto e retornar grupos correspondentes (elementos encontrados entre parênteses) como um vetor de Strings. Se não houver correspondências, um valor nulo será retornado. Se nenhum grupo for especificado na expressão regular, mas a sequência corresponder, um vetor de comprimento 1 (com o texto correspondente como o primeiro elemento do vetor) será retornado.",
            +        "Para usar a função, primeiro verifique se o resultado é nulo. Se o resultado for nulo, então a sequência não coincidiu. Se a sequência coincidiu, um vetor é retornada.",
            +        "Se houver grupos (especificados por conjuntos de parênteses) na expressão regular, os conteúdos de cada um serão retornados no vetor. O elemento [0] de uma correspondência de uma expressão regular retorna toda a string correspondente e os grupos de correspondência começam no elemento [1] (o primeiro grupo é [1], o segundo [2] e assim por diante)."
            +      ],
            +      "returns": "String[]: Vetor de Strings encontrado",
            +      "params": {
            +        "str": "String: a String a ser procurada",
            +        "regexp": "String: a expressão regular a ser usada para procurar correspondências"
            +      }
            +    },
            +    "matchAll": {
            +      "description": [
            +        "Esta função é usada para aplicar uma expressão regular a um trecho de texto e retornar uma lista de grupos correspondentes (elementos encontrados entre parênteses) como uma matriz de strings bidimensional. Se não houver correspondências, um valor nulo será retornado. Se nenhum grupo for especificado na expressão regular, mas a sequência corresponder, uma matriz bidimensional ainda será retornada, mas a segunda dimensão terá apenas o comprimento um.",
            +        "Para usar a função, primeiro verifique se o resultado é nulo. Se o resultado for nulo, então a sequência não coincidiu. Se a sequência coincidiu, uma matriz 2D é retornada.",
            +        "Se houver grupos (especificados por conjuntos de parênteses) na expressão regular, os conteúdos de cada um serão retornados na matriz. Assumindo um loop com variável de contador i, o elemento [i][0] de uma correspondência de expressão regular retorna toda a string correspondente e os grupos de correspondência começam no elemento [i][1] (o primeiro grupo é [i][1] , o segundo [i][2] e assim por diante)."
            +      ],
            +      "returns": "String[]: Array 2D de strings encontradas",
            +      "params": {
            +        "str": "String: a String a ser procurada",
            +        "regexp": "String: a expressão regular a ser usada para procurar correspondências"
            +      }
            +    },
            +    "nf": {
            +      "description": [
            +        "Função utilitária para formatar números em strings. Existem duas versões: uma para formatar floats e outra para formatar ints. Os valores dos dígitos, parâmetros esquerdo e direito devem ser sempre inteiros positivos. (NOTA): Tenha cautela ao usar os parâmetros esquerdo e direito, uma vez que eles adicionam números de 0s se o parâmetro for maior que o comprimento atual do número. Por exemplo, se o número for 123,2 e o parâmetro esquerdo passado for de 4, que é maior que o comprimento de 123 (parte inteira), ou seja, 3, o resultado será 0123,2. Mesmo caso para o parâmetro direito, ou seja, se o direito for 3, o resultado será 123,200."
            +      ],
            +      "returns": "String: String formatada",
            +      "params": {
            +        "num": "Número|String: o número a ser formatado",
            +        "left": "Inteiro|String (opcional): número de dígitos à esquerda da vírgula decimal",
            +        "right": "Inteiro|String (opcional):número de dígitos à direita da vírgula decimal ",
            +        "nums": "Array: os números a se formatar"
            +      }
            +    },
            +    "nfc": {
            +      "description": [
            +        "Função utilitária para formatar números em strings e colocar vírgulas apropriadas para marcar unidades de 1000. Existem duas versões: uma para formatar ints e outra para formatar uma array de ints. O valor do parâmetro correto deve ser sempre um número inteiro positivo."
            +      ],
            +      "returns": "String: String formatada",
            +      "params": {
            +        "num": "Numero|String: o número a ser formatado",
            +        "right": "Inteiro|String (opcional): número de dígitos à direita da vírgula decimal",
            +        "nums": "Array: os números a se formatar"
            +      }
            +    },
            +    "nfp": {
            +      "description": [
            +        "Função utilitária para formatar números em strings. Similar a <a href=\"#/p5/nf\">nf()</a> mas coloca um \"+\" na frente de números positivos e um \"-\" na frente de números negativos. Existem duas versões: uma para formatar floats e outra para formatar ints. Os valores dos parâmetros esquerdo e direito devem ser sempre inteiros positivos. "
            +      ],
            +   "returns": "String: String formatada",
            +      "params": {
            +        "num": "Número: o número a ser formatado",
            +        "left": "Número (opcional): número de dígitos à esquerda da vírgula decimal",
            +        "right": "Número (opcional): número de dígitos à direita da vírgula decimal ",
            +        "nums": "Número[]: os números a se formatar"
            +      }
            +    },
            +    "nfs": {
            +      "description": [
            +        "Função utilitária para formatar números em strings. Similar a <a href=\"#/p5/nf\">nf()</a> mas coloca um \"_\" (espaço) adicional na frente de números positivos a fim de alinhá-los com números negativos que incluem o sinal \"-\" (menos). O principal tipo de uso de nfs() pode ser visto quando se deseja alinhar os dígitos (valores de posição) de um número não negativo com algum número negativo (veja o exemplo para obter uma imagem clara). Existem duas versões: uma para formatar floats e outra para formatar ints. Os valores dos dígitos, parâmetros esquerdo e direito, devem ser sempre inteiros positivos. <br/> Importante: o resultado mostrado no Canvas do alinhamento esperado pode variar com base no tipo de fonte tipográfica que você está usando. <br/> (NOTA): Tenha cautela ao usar os parâmetros esquerdo e direito, uma vez que eles adicionam números de 0s se o parâmetro for maior que o comprimento atual do número. Por exemplo, se o número for 123,2 e o parâmetro esquerdo passado for de 4, que é maior que o comprimento de 123 (parte inteira), ou seja, 3, o resultado será 0123,2. Mesmo caso para o parâmetro direito, ou seja, se o direito for 3, o resultado será 123,200."
            +      ],
            +      "returns": "String: String formatada",
            +      "params": {
            +        "num": "Número: o número a ser formatado",
            +        "left": "Número (opcional): número de dígitos à esquerda da vírgula decimal",
            +        "right": "Número (opcional): número de dígitos à direita da vírgula decimal ",
            +        "nums": "Array: os números a se formatar"
            +      }
            +    },
            +    "split": {
            +      "description": [
            +        "A função <a href=\"#/p5/split\">split()</a> mapeia para String.split(), ela divide uma String em pedaços usando um caractere ou string como delimitador. O parâmetro delim especifica o caractere ou caracteres que marcam os limites entre cada pedaço. Uma array de String[] é retornado contendo cada uma das peças. ",
            +        "A função <a href=\"#/p5/splitTokens\">splitTokens()</a> funciona de maneira semelhante, exceto por se dividir usando um intervalo de caracteres em vez de um caractere ou sequência específica. "
            +      ],
            +      "returns": "String[]: Array de Strings",
            +      "params": {
            +        "value": "String: a String a ser dividida",
            +        "delim": "String: a String usada para separar os dados"
            +      }
            +    },
            +    "splitTokens": {
            +      "description": [
            +        "A função <a href=\"#/p5/splitTokens\">splitTokens()</a> divide uma String em um ou mais delimitadores de caracteres ou \"tokens.\" O parâmetro delim especifica o caractere ou caracteres a serem usados como limite. ",
            +        "Se nenhum caractere delim for especificado, qualquer caractere de espaço em branco será usado para dividir. Os caracteres de espaço em branco incluem tab (\\t), nova linha (\\n), retorno de carro (\\r), alimentação de formulário (\\f), e espaço. "
            +      ],
            +      "returns": "String[]: Array de Strings",
            +      "params": {
            +        "value": "String: a String a ser dividida",
            +        "delim": "String (opcional): lista de Strings individuais que serão usadas como separadores"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "Remove os caracteres de espaço em branco do início e do final de uma String. Além dos caracteres de espaço em branco padrão, como espaço, retorno de carro e tab, esta função também remove o caractere Unicode \"nbsp\"."
            +      ],
            +      "returns": "String: uma String aparada",
            +      "params": {
            +        "str": "String: uma String a ser aparada",
            +        "strs": "Array: uma Array de Strings a ser aparado"
            +      }
            +    },
            +    "day": {
            +      "description": [
            +        "p5.js se comunica com o relógio do seu computador. A função <a href=\"#/p5/day\">day()</a> retorna o dia atual como um valor de 1 - 31."
            +      ],
            +      "returns": "Inteiro: o dia atual"
            +    },
            +    "hour": {
            +      "description": [
            +        "p5.js se comunica com o relógio do seu computador. A função <a href=\"#/p5/hour\">hour()</a> retorna a hora atual como um valor de 0 - 23."
            +      ],
            +      "returns": "Inteiro: a hora atual"
            +    },
            +    "minute": {
            +      "description": [
            +        "p5.js se comunica com o relógio do seu computador. A função <a href=\"#/p5/minute\">minute()</a> retorna o minuto atual como um valor de 0 - 59."
            +      ],
            +      "returns": "Inteiro: o minuto atual"
            +    },
            +    "millis": {
            +      "description": [
            +        "retorna o número de milissegundos (milésimos de segundo) desde que o programa começou a ser executado (quando <code>setup()</code> é chamado). Esta informação é frequentemente usada para eventos de temporização e sequências de animação."
            +      ],
            +      "returns": "Número: o número de milissegundos desde que o programa começou a ser executado "
            +    },
            +    "month": {
            +      "description": [
            +        "p5.js se comunica com o relógio do seu computador. A função <a href=\"#/p5/month\">month()</a> retorna o mês atual como um valor de 1 - 12."
            +      ],
            +      "returns": "Inteiro: o mês atual"
            +    },
            +    "second": {
            +      "description": [
            +        "p5.js se comunica com o relógio do seu computador. A função <a href=\"#/p5/second\">second()</a> retorna o segundo atual como um valor de 0 - 59."
            +      ],
            +      "returns": "Inteiro: o segundo atual"
            +    },
            +    "year": {
            +      "description": [
            +        "p5.js se comunica com o relógio do seu computador. A função <a href=\"#/p5/year\">year()</a> retorna o ano atual como um inteiro (2014, 2015, 2016, etc)."
            +      ],
            +      "returns": "Inteiro: o ano atual"
            +    },
            +    "plane": {
            +      "description": [
            +        "Desenha um plano com largura e altura fornecidas"
            +      ],
            +      "params": {
            +        "width": "Número (opcional): largura do plano",
            +        "height": "Número (opcional): altura do plano",
            +        "detailX": "Número (opcional): Número opcional de subdivisões de triângulo na dimensão x",
            +        "detailY": "Número (opcional): Número opcional de subdivisões de triângulo na dimensão y"
            +      }
            +    },
            +    "box": {
            +      "description": [
            +        "Desenha uma caixa com largura, altura e profundidade fornecidas"
            +      ],
            +      "params": {
            +        "width": "Número (opcional): largura da caixa",
            +        "Height": "Número (opcional): altura da caixa",
            +        "depth": "Número (opcional): profundidade da caixa",
            +        "detailX": "Número (opcional): Número opcional de subdivisões de triângulo na dimensão x",
            +        "detailY": "Número (opcional): Número opcional de subdivisões de triângulo na dimensão y"
            +      }
            +    },
            +    "sphere": {
            +      "description": [
            +        "Desenha uma esfera com determinado raio.",
            +        "DetailX e detailY determinam o número de subdivisões na dimensão x e na dimensão y de uma esfera. Mais subdivisões fazem a esfera parecer mais regular. Os valores máximos recomendados são ambos 24. Usar um valor maior que 24 pode causar um alerta ou tornar o navegador mais lento."
            +      ],
            +      "params": {
            +        "radius": "Número (opcional): raio do círculo",
            +        "detailX": "Número (opcional): Número opcional de subdivisões na dimensão x",
            +        "detailY": "Número (opcional): Número opcional de subdivisões na dimensão y"
            +      }
            +    },
            +    "cylinder": {
            +      "description": [
            +        "Desenha um cilindro com determinado raio e altura ",
            +        "DetailX e detailY determinam o número de subdivisões na dimensão x e na dimensão y de um cilindro. Mais subdivisões fazem o cilindro parecer mais regular. O valor máximo recomendado para detailX é 24. Usar um valor maior que 24 pode causar um alerta ou tornar o navegador mais lento."
            +      ],
            +      "params": {
            +        "radius": "Número (opcional): raio da superfície",
            +        "height": "Número (opcional): altura do cilindro",
            +        "detailX": "Número (opcional): Número de subdivisões na dimensão x;  o padrão é 24",
            +        "detailY": "Número (opcional): Número de subdivisões na dimensão y; o padrão é 1",
            +        "bottomCap": "Booleano (opcional): se deve desenhar a base do cilindro",
            +        "topCap": "Booleano (opcional): se deve desenhar o topo do cilindro"
            +      }
            +    },
            +    "cone": {
            +      "description": [
            +        "Desenha um cone com determinado raio e altura ",
            +        "DetailX e detailY determinam o número de subdivisões na dimensão x e na dimensão y de um cone. Mais subdivisões fazem o cone parecer mais regular. O valor máximo recomendado para detailX é 24. Usar um valor maior que 24 pode causar um alerta ou tornar o navegador mais lento."
            +      ],
            +      "params": {
            +        "radius": "Número (opcional): raio da base",
            +        "height": "Número (opcional): altura do cone",
            +        "detailX": "Número (opcional): Número de segmentos, por padrão é 24, quanto mais segmentos, mais regular sua geometria.",
            +        "detailY": "Número (opcional): Número de segmentos, por padrão é 1, quanto mais segmentos, mais regular sua geometria",
            +        "cap": "Booleano (opcional): se deve desenhar a base do cone"
            +      }
            +    },
            +    "ellipsoid": {
            +      "description": [
            +        "Desenha um elipsóide com determinado raio",
            +        "DetailX e detailY determinam o número de subdivisões na dimensão x e na dimensão y de um cone. Mais subdivisões fazem o elipsóide parecer mais regular. Evite o número do parâmetro acima de 150, pois pode travar o navegador."
            +      ],
            +      "params": {
            +        "radiusx": "Número (opcional): raio x do elipsóide",
            +        "radiusy": "Número (opcional): raio y do elipsóide",
            +        "radiusz": "Número (opcional): raio z do elipsóide",
            +        "detailX": "Número (opcional): Número de segmentos, por padrão é 24, quanto mais segmentos, mais regular sua geometria. Evite o número do parâmetro acima de 150, pois pode travar o navegador.",
            +        "detailY": "Número (opcional): Número de segmentos, por padrão é 16, quanto mais segmentos, mais regular sua geometria. Evite o número do parâmetro acima de 150, pois pode travar o navegador."
            +      }
            +    },
            +    "torus": {
            +      "description": [
            +        "Desenha um toro com determinado raio e raio do tubo ",
            +        "DetailX e detailY determinam o número de subdivisões na dimensão x e na dimensão y de um toro. Mais subdivisões fazem o toro parecer mais regular. Os valores padrão e máximos para detailX e detailY são 24 e 16, respectivamente. Configurá-los com valores relativamente pequenos, como 4 e 6, permite criar novas formas além de um toro."
            +      ],
            +      "params": {
            +        "radius": "Número (opcional): raio do anel todo",
            +        "tubeRadius": "Número (opcional): raio do tubo",
            +        "detailX": "Número (opcional): Número de segmentos na dimensão x, por padrão é 24, quanto mais segmentos, mais regular sua geometria.",
            +        "detailY": "Número (opcional): Número de segmentos na dimensão y, por padrão é 16, quanto mais segmentos, mais regular sua geometria."
            +      }
            +    },
            +    "orbitControl": {
            +      "description": [
            +        "Permite o movimento em torno de um sketch 3D usando um mouse ou trackpad. Clicar e arrastar com o botão esquerdo girará a posição da câmera sobre o centro do sketch, ao clicar e arrastar com o botão direito, irá mover a câmera horizontalmente sem rotação, e usando a roda do mouse (rolagem), irá mover a câmera para mais perto ou mais longe do centro do sketch. Esta função pode ser chamada com parâmetros que ditam a sensibilidade ao movimento do mouse ao longo dos eixos X e Y. Chamar esta função sem parâmetros é equivalente a chamar orbitControl(1,1). Para inverter a direção do movimento em qualquer um dos eixos, insira um número negativo para sensibilidade. "
            +      ],
            +      "params": {
            +        "sensitivityX": "Número (opcional): sensibilidade ao movimento do mouse ao longo do eixo X",
            +        "sensitivityY": "Número (opcional): sensibilidade ao movimento do mouse ao longo do eixo Y",
            +        "sensitivityZ": "Número (opcional): sensibilidade para rolar o movimento ao longo do eixo Z"
            +      }
            +    },
            +    "debugMode": {
            +      "description": [
            +        "debugMode() ajuda a visualizar o espaço 3D adicionando uma grade para indicar onde o \"solo\" está em um sketch e um ícone de eixo que indica as direções + X, + Y e + Z. Esta função pode ser chamada sem parâmetros para criar um padrão de grade e ícone de eixos, ou pode ser chamada de acordo com os exemplos acima para personalizar o tamanho e a posição da grade e/ou ícone de eixos. A grade é desenhada usando a cor e a espessura do traço definidas por último. Para especificar esses parâmetros, adicione uma chamada para stroke() e strokeWeight() antes do final do loop draw().",
            +        "Por padrão, a grade percorrerá a origem (0,0,0) do sketch ao longo do plano XZ e o ícone dos eixos será deslocado da origem. Ambos, a grade e ícone de eixos serão dimensionados de acordo com o tamanho do Canvas atual. Observe que, como a grade é executada paralelamente à visualização padrão da câmera, muitas vezes é útil usar o debugMode junto com orbitControl para permitir a visualização completa da grade."
            +      ],
            +      "params": {
            +        "mode": "Constante: tanto GRADE quanto EIXOS",
            +        "gridSize": "Número (opcional): tamanho de um lado da grade",
            +        "gridDivisions": "Número (opcional): Número de divisões na grade",
            +        "xOff": "Número (opcional): deslocamento do eixo X da origem (0,0,0)",
            +        "yOff": "Número (opcional): deslocamento do eixo Y da origem (0,0,0)",
            +        "zOff": "Número (opcional): deslocamento do eixo Z da origem (0,0,0)",
            +        "axesSize": "Número (opcional): tamanho do ícone de eixos",
            +        "gridXOff": "Número (opcional)",
            +        "gridYOff": "Número (opcional)",
            +        "gridZOff": "Número (opcional)",
            +        "axesXOff": "Número (opcional)",
            +        "axesYOff": "Número (opcional)",
            +        "axesZOff": "Número (opcional)"
            +      }
            +    },
            +    "noDebugMode": {
            +      "description": [
            +        "Desativa o debugMode() em um sketch 3D."
            +      ]
            +    },
            +    "ambientLight": {
            +      "description": [
            +        "Cria uma luz ambiente com uma cor. A luz ambiente é a luz que vem de todos os lugares do canvas. Não tem uma fonte particular."
            +      ],
            +      "params": {
            +        "v1": "Número: vermelho ou valor de matiz relativo ao intervalo de cores atual",
            +        "v2": "Número: verde ou valor de saturação relativo ao intervalo de cores atual",
            +        "v3": "Número: azul ou valor de brilho relativo ao intervalo de cores atual",
            +        "alpha": "Número (opcional): valor de alpha",
            +        "value": "String: uma string de cor",
            +        "gray": "Número: um valor de cinza",
            +        "values": "Número[]: uma array contendo os componentes vermelho, verde, azul e alfa da cor",
            +        "color": "p5.Color: a cor da luz ambiente"
            +      }
            +    },
            +    "specularColor": {
            +      "description": [
            +        "Define a cor do realce especular ao usar um material especular e luz especular.",
            +        "Este método pode ser combinado com as funções specularMaterial() e shininess() para definir realces especulares. A cor padrão é o branco, isto é (255, 255, 255), que é usado se este método não for chamado antes de specularMaterial(). Se este método é chamado sem specularMaterial(), não haverá efeito. ",
            +        "Nota: specularColor é equivalente à função do processing <a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>."
            +      ],
            +      "params": {
            +        "v1": "Número: vermelho ou valor de matiz relativo ao intervalo de cores atual",
            +        "v2": "Número: verde ou valor de saturação relativo ao intervalo de cores atual",
            +        "v3": "Número: azul ou valor de brilho relativo ao intervalo de cores atual",
            +        "alpha": "Número (opcional): valor de alpha",
            +        "value": "String: uma string de cor",
            +        "gray": "Número: um valor de cinza",
            +        "values": "Número[]: uma array contendo os componentes vermelho, verde, azul e alfa da cor",
            +        "color": "p5.Color: a cor da luz ambiente"
            +      }
            +    },
            +    "directionalLight": {
            +      "description": [
            +        "Cria uma luz direcional com uma cor e uma direção",
            +        "Um máximo de 5 luzes direcionais podem estar ativas ao mesmo tempo"
            +      ],
            +      "params": {
            +        "v1": "Número: vermelho ou valor de matiz (dependendo do modelo de cores atual)",
            +        "v2": "Número: verde ou valor de saturação",
            +        "v3": "Número: azul ou valor de brilho",
            +        "position": "p5.Vector: a direção da luz",
            +        "color": "Número[]|String|p5.Color: Array de cor, string CSS de cor,  ou valor de <a href=\"#/p5.Color\">p5.Color</a>",
            +        "x": "Número: direção do eixo x",
            +        "y": "Número: direção do eixo y",
            +        "z": "Número: direção do eixo z"
            +      }
            +    },
            +    "pointLight": {
            +      "description": [
            +        "Cria um ponto de luz com uma cor e uma posição de luz ",
            +         "Um máximo de 5 pontos de luz podem estar ativos ao mesmo tempo"
            +      ],
            +      "params": {
            +        "v1": "Número: vermelho ou valor de matiz (dependendo do modelo de cores atual)",
            +        "v2": "Número: verde ou valor de saturação",
            +        "v3": "Número: azul ou valor de brilho",
            +        "x": "Número: posição do eixo x",
            +        "y": "Número: posição do eixo y",
            +        "z": "Número: posição do eixo z",
            +        "position": "p5.Vector: a posição da luz",
            +        "color": "Número[]|String|p5.Color: Array de cor, string CSS de cor,  ou valor de <a href=\"#/p5.Color\">p5.Color</a>"
            +      }
            +    },
            +    "lights": {
            +      "description": [
            +        "Define a luz ambiente e direcional padrão. Os padrões são <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> e <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. As luzes precisam ser incluídas no <a href=\"#/p5/draw\">draw()</a> para permanecerem persistentes em um programa de loop. Colocando-as no <a href=\"#/p5/setup\">setup()</a> de um programa de loop, fará com que tenham efeito apenas na primeira vez que o loop rodar.."
            +      ]
            +    },
            +    "lightFalloff": {
            +      "description": [
            +        "Define as taxas de queda (falloff) para luzes pontuais. Afeta apenas os elementos que são criados depois dele no código. Por padrão o valor é lightFalloff(1.0, 0.0, 0.0), e os parâmetros são usados para calcular a queda (falloff) com a seguinte equação:",
            +        "d = distância da posição da luz à posição do vértice ",
            +        "falloff = 1 / (Constante + d * LINEAR + ( d * d ) * QUADRATIC)"
            +      ],
            +      "params": {
            +        "Constante": "Número: valor constante para determinar a queda (falloff)",
            +        "linear": "Número: valor linear para determinar a queda (falloff)",
            +        "quadratic": "Número: valor quadrático para determinar a queda (falloff)"
            +      }
            +    },
            +    "spotLight": {
            +      "description": [
            +        "Cria um holofote com uma determinada cor, posição, direção de luz, ângulo e concentração. Aqui, ângulo se refere à abertura do cone do holofote, e a concentração é usada para focar a luz em direção ao centro. Ambos o ângulo e a concentração são opcionais, mas se você quiser fornecer a concentração, também terá que especificar o ângulo. ",
            +        "Um máximo de 5 holofotes podem estar ativos ao mesmo tempo"
            +      ],
            +      "params": {
            +        "v1": "Número: vermelho ou valor de matiz (dependendo do modelo de cores atual)",
            +        "v2": "Número: verde ou valor de saturação",
            +        "v3": "Número: azul ou valor de brilho",
            +        "x": "Número: posição do eixo x",
            +        "y": "Número: posição do eixo y",
            +        "z": "Número: posição do eixo z",
            +        "rx": "Número: direção do eixo x da luz",
            +        "ry": "Número: direção do eixo y da luz",
            +        "rz": "Número: direção do eixo z da luz",
            +        "angle": "Número (opcional): parâmetro opcional para ângulo. Por padrão até PI/3",
            +        "conc": "Número (opcional): parâmetro opcional para concentração. Por padrão até 100",
            +        "color": "Número[]|String|p5.Color: Array de cor, string CSS de cor,  ou valor de <a href=\"#/p5.Color\">p5.Color</a>",
            +        "position": "p5.Vector: a posição da luz",
            +        "direction": "p5.Vector: a direção da luz"
            +      }
            +    },
            +    "noLights": {
            +      "description": [
            +        "Esta função irá remover todas as luzes do sketch para os materiais renderizados subsequentes. Ela afeta todos os métodos subsequentes. Chamadas para métodos de iluminação feitas após o noLights() irão reativar as luzes no sketch."
            +      ]
            +    },
            +    "loadModel": {
            +      "description": [
            +        "Carregar um modelo 3D de um arquivo OBJ ou STL. ",
            +        "<a href=\"#/p5/loadModel\">loadModel()</a> deve ser colocado dentro de <a href=\"#/p5/preload\">preload()</a>. Isso permite que o modelo carregue totalmente antes que o resto do seu código seja executado. ",
            +        "Uma das limitações dos formatos OBJ e STL é que eles não têm um senso de escala embutido. Isso significa que os modelos exportados de programas diferentes podem ter tamanhos muito diferentes. Se o seu modelo não estiver sendo exibido, tente chamar <a href=\"#/p5/loadModel\">loadModel()</a> com o parâmetro normalize definido como true (verdadeiro).Isso redimensionará o modelo para uma escala apropriada para p5. Você também pode fazer alterações adicionais no tamanho final do seu modelo com a função <a href=\"#/p5/scale\">scale()</a> . ",
            +        "Além disso, o suporte para arquivos STL coloridos não está presente. Arquivos STL com cor serão renderizados sem propriedades de cor."
            +      ],
            +      "returns": "o objeto p5.Geometry: <a href=\"#/p5.Geometry\">p5.Geometry</a>",
            +      "params": {
            +        "path": "String: endereço do modelo a ser carregado",
            +        "normalize": "Booleano: Se true (verdadeiro), dimensiona o modelo para um tamanho padronizado ao carregar",
            +        "successCallback": "função(p5.Geometry) (opcional): Função a ser chamada assim que o modelo for carregado. Será passado o objeto do modelo 3D.",
            +        "failureCallback": "Função(evento) (opcional): chamado com erro de evento se o modelo não carregar.",
            +        "fileType": "String (opcional): A extensão de arquivo do modelo (<code>.stl</code>, <code>.obj</code>)."
            +      }
            +    },
            +    "model": {
            +      "description": [
            +        "Renderizar um modelo 3D para a tela."
            +      ],
            +      "params": {
            +        "model": "p5.Geometry: Modelo 3D carregado para ser renderizado"
            +      }
            +    },
            +    "loadShader": {
            +      "description": [
            +        "Carrega uma shader personalizado dos caminhos de vértice e fragmento de shader  fornecidos. Os arquivos de shader são carregados de forma assíncrona em segundo plano, portanto, este método deve ser usado em <a href=\"#/p5/preload\">preload()</a>. ",
            +        "Por enquanto, existem três tipos principais de shaders. O p5 fornecerá automaticamente vértices, normais, cores e atributos de iluminação apropriados se os parâmetros definidos na shader corresponderem aos nomes."
            +      ],
            +      "returns": "p5.Shader: um objeto de shader criado a partir dos arquivos de shaders de vértice e fragmento fornecidos.",
            +      "params": {
            +        "vertFilename": "String: endereço para o arquivo que contém o código fonte do vértice da shader",
            +        "fragFilename": "String: endereço para o arquivo que contém o código fonte do fragmento da shader",
            +        "callback": "Função (opcional): callback a ser executado após a conclusão de loadShader. Em caso de sucesso, o objeto Shader é passado como o primeiro argumento.",
            +        "errorCallback": "Função (opcional): callback a ser executado quando ocorrer um erro dentro do loadShader. Em caso de erro, o erro é passado como o primeiro argumento."
            +      }
            +    },
            +    "createShader": {
            +      "returns": "p5.Shader: um objeto de shader criado a partir dos vértices e fragmentos de shader fornecidos.",
            +      "params": {
            +        "vertSrc": "String: código fonte para o vértice da shader",
            +        "fragSrc": "String: código fonte para o fragmento da shader"
            +      }
            +    },
            +    "shader": {
            +      "description": [
            +        "A função <a href=\"#/p5/shader\">shader()</a> permite que o usuário forneça uma shader personalizada para preencher as formas no modo WEBGL. Os usuários podem criar suas próprias shaders carregando seus vértices e fragmentos com <a href=\"#/p5/loadShader\">loadShader()</a>."
            +      ],
            +      "params": {
            +        "s": "p5.Shader (opcional): a desejada <a href=\"#/p5.Shader\">p5.Shader</a> para usar para renderizar formas."
            +      }
            +    },
            +    "resetShader": {
            +      "description": [
            +        "Esta função restaura os padrões de shaders no modo WEBGL. O código que for executado após o resetShader() não será afetado pelas definições de shaders anteriores. Deve ser executado depois de <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "normalMaterial": {
            +      "description": [
            +        "O material normal para geometria é um material que não é afetado pela luz. Não é reflexivo e é um material de placeholder (espaço reservado) frequentemente usado para depurar (debug). As superfícies voltadas para o eixo X tornam-se vermelhas, as voltadas para o eixo Y tornam-se verdes e as voltadas para o eixo Z tornam-se azuis. Você pode ver todos os materiais possíveis neste <a href=\"https://p5js.org/examples/3d-materials.html\">exemplo</a>."
            +      ]
            +    },
            +    "texture": {
            +      "description": [
            +        "Textura para geometria. Você pode ver outros materiais possíveis neste <a href=\"https://p5js.org/examples/3d-materials.html\">exemplo</a>."
            +      ],
            +      "params": {
            +        "tex": "p5.Image|p5.MediaElement|p5.Graphics: Gráficos bidimensionais para renderizar como textura"
            +      }
            +    },
            +    "textureMode": {
            +      "description": [
            +        "Define o espaço de coordenadas para mapeamento de textura. O modo padrão é IMAGE, que se refere às coordenadas reais da imagem. NORMAL refere-se a um espaço normalizado de valores que variam de 0 a 1. Esta função só funciona no modo WEBGL. ",
            +        "Em modo IMAGE, se uma imagem é de 100 x 200 pixels, mapear a imagem por todo o tamanho de um quadrante exigiria os pontos (0,0) (100, 0) (100,200) (0,200). O mesmo mapeamento em NORMAL é (0,0) (1,0) (1,1) (0,1)."
            +      ],
            +      "params": {
            +        "mode": "Constante: tanto IMAGE ou NORMAL"
            +      }
            +    },
            +    "textureWrap": {
            +      "description": [
            +        "Define o wrapping mode (modo de embrulhamento) de textura global. Isso controla como as texturas se comportam quando seu mapeamento uv sai do intervalo 0 - 1. Existem três opções: CLAMP, REPEAT e MIRROR. ",
            +        "faz com que os pixels na extremidade da textura se estendam para os limites. REPEAT faz com que a textura se espalhe repetidamente até atingir os limites. MIRROR funciona de forma semelhante a REPEAT, mas inverte a textura a cada novo tile (ladrilho).",
            +
            +        "REPEAT & MIRROR só estão disponíveis se a textura for uma for uma multiplicação de dois (128, 256, 512, 1024, etc.).",
            +
            +        "Este método afetará todas as texturas em seu sketch até que uma chamada de textureWrap subsequente seja feita.",
            +         "Se apenas um argumento for fornecido, ele será aplicado aos eixos horizontal e vertical."
            +      ],
            +      "params": {
            +        "wrapX": "Constante: tanto CLAMP, REPEAT ou MIRROR",
            +        "wrapY": "Constante (opcional): tanto CLAMP, REPEAT ou MIRROR"
            +      }
            +    },
            +    "ambientMaterial": {
            +      "description": [
            +        "Material ambiente para geometria com uma determinada cor. O material ambiente define a cor que o objeto reflete sob qualquer iluminação. Por exemplo, se o material ambiente de um objeto for vermelho puro, mas a iluminação ambiente contiver apenas verde, o objeto não refletirá nenhuma luz. Aqui está um <a href=\"https://p5js.org/examples/3d-materials.html\">exemplo contendo todos os materiais possíveis</a>."
            +      ],
            +      "params": {
            +        "v1": "Número: valor de cinza, de vermelho ou valor de matiz (dependendo do modo de cor atual),",
            +        "v2": "Número (opcional): verde ou valor de saturação",
            +        "v3": "Número (opcional): azul ou valor de brilho",
            +        "color": "Número[]|String|p5.Color: cor, array de cor ou string de cor CSS"
            +      }
            +    },
            +    "emissiveMaterial": {
            +      "description": [
            +        "Define a cor emissiva do material usado para a geometria desenhada na tela. Este é um nome incorreto no sentido de que o material não emite luz que afeta os polígonos circundantes. Em vez disso, dá a aparência de que o objeto está brilhando. Um material emissivo será exibido com força total, mesmo se não houver luz para ele refletir."
            +      ],
            +      "params": {
            +        "v1": "Número: valor de cinza, de vermelho ou valor de matiz (dependendo do modo de cor atual),",
            +        "v2": "Número (opcional): valor de verde ou de saturação",
            +        "v3": "Número (opcional): valor de azul ou de brilho",
            +        "a": "Número (opcional): opacidade",
            +        "color": "Número[]|String|p5.Color: cor, array de cor ou string de cor CSS"
            +      }
            +    },
            +    "specularMaterial": {
            +      "description": [
            +        "Material especular para geometria com uma determinada cor. O material especular é um material reflexivo brilhante. Como o material ambiente, também define a cor que o objeto reflete sob a iluminação ambiente. Por exemplo, se o material especular de um objeto for vermelho puro, mas a iluminação ambiente contiver apenas verde, o objeto não refletirá nenhuma luz. Para todos os outros tipos de luz como ponto de luz e luz direcional, um material especular refletirá a cor da fonte de luz para o observador. Aqui está um <a href=\"https://p5js.org/examples/3d-materials.html\">exemplo contendo todos os materiais possíveis</a>."
            +      ],
            +      "params": {
            +        "gray": "Número: Número especificando o valor entre branco e preto.",
            +        "alpha": "Número (opcional): valor alfa relativo ao intervalo de cores atual (por padrão é 0 - 255)",
            +        "v1": "Número: valor de cinza, de vermelho ou valor de matiz relativo ao intervalo de cores atual ,",
            +        "v2": "Número (opcional): valor de verde ou de saturação relativo ao intervalo de cores atual ",
            +        "v3": "Número (opcional): valor de azul ou de brilho relativo ao intervalo de cores atual ",
            +        "color": "Número[]|String|p5.Color: cor, array de cor ou string de cor CSS"
            +      }
            +    },
            +    "shininess": {
            +      "description": [
            +        "Define a quantidade de brilho na superfície de formas. Usado em combinação com specularMaterial() para definir as propriedades do material das formas. O valor padrão e mínimo é 1."
            +      ],
            +      "params": {
            +        "shine": "Número: grau de brilho. Por padrão 1."
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "Define a posição da câmera para um sketch 3D. Os parâmetros para esta função definem a posição da câmera, o centro do sketch (para onde a câmera está apontando) e uma direção para cima (a orientação da câmera). ",
            +        "Esta função simula os movimentos da câmera, permitindo que os objetos sejam visualizados de vários ângulos. Lembre-se de que ele não move os próprios objetos, mas sim a câmera. Por exemplo, quando o valor centerX é positivo, a câmera está girando para o lado direito do sketch, então o objeto parece estar se movendo para a esquerda. ",
            +        "Veja este  <a href = \"https://www.openprocessing.org/sketch/740258\">exemplo</a> para ver a posição de sua câmera. ",
            +        "Quando chamada sem argumentos, esta função cria uma câmera padrão equivalente à camera(0, 0, (height/2.0) / tan(PI*30.0 / 180.0), 0, 0, 0, 0, 1, 0);"
            +      ],
            +      "params": {
            +        "x": "Número (opcional): valor da posição da câmera no eixo x",
            +        "y": "Número (opcional): valor da posição da câmera no eixo y",
            +        "z": "Número (opcional): valor da posição da câmera no eixo z",
            +        "centerX": "Número (opcional): coordenada x representando o centro do sketch",
            +        "centerY": "Número (opcional): coordenada y representando o centro do sketch",
            +        "centerZ": "Número (opcional): coordenada z representando o centro do sketch",
            +        "upX": "Número (opcional): componente x da direção 'para cima' da câmera",
            +        "upY": "Número (opcional): componente y da direção 'para cima' da câmera",
            +        "upZ": "Número (opcional): componente z da direção 'para cima' da câmera"
            +      }
            +    },
            +    "perspective": {
            +      "description": [
            +        "Define uma projeção em perspectiva para a câmera em um sketch 3D. Esta projeção representa a profundidade através da técnica de Escorço (encurtamento): os objetos que estão perto da câmera aparecem em seu tamanho real, enquanto os que estão mais distantes da câmera parecem menores. Os parâmetros para esta função definem o frustum (tronco) de visualização (a pirâmide frustum dentro da qual os objetos são vistos pela câmera) por meio do campo de visão vertical, relação de aspecto (geralmente largura / altura) e planos de recorte próximos e distantes. ",
            +        "Quando chamada sem argumentos, os padrões fornecidos são equivalentes a perspective(PI/3.0, width/height, eyeZ/10.0, eyeZ<em>10.0), where eyeZ is equal to ((height/2.0) / tan(PI</em>60.0/360.0));"
            +      ],
            +      "params": {
            +        "fovy": "Número (opcional): tronco do campo de visão vertical da câmera, de baixo para cima, em <a href=\"#/p5/angleMode\">angleMode</a> graus",
            +        "aspect": "Número (opcional): relação de aspecto da câmara de frustum (tronco)",
            +        "near": "Número (opcional): frustum (tronco) perto do plano de comprimento",
            +        "far": "Número (opcional): frustum (tronco) distante do plano de comprimento"
            +      }
            +    },
            +    "ortho": {
            +      "description": [
            +        "Define uma projeção ortográfica para a câmera em um sketch 3D e define um frustum de visualização em forma de caixa dentro do qual os objetos são vistos. Nesta projeção, todos os objetos com a mesma dimensão aparecem do mesmo tamanho, independentemente de estarem próximos ou distantes da câmera. Os parâmetros para esta função especificam o frustum (tronco) de visualização onde esquerda e direita são os valores x mínimo e máximo, topo e fundo são os valores y mínimo e máximo e próximo e longe são os valores z mínimo e máximo. Se nenhum parâmetro for fornecido, por padrão será usado: ortho(-width/2, width/2, -height/2, height/2)."
            +      ],
            +      "params": {
            +        "left": "Número (opcional): câmera frustum (tronco) do plano esquerdo",
            +        "right": "Número (opcional): câmera frustum (tronco) do plano direito",
            +        "bottom": "Número (opcional): câmera frustum (tronco) do plano inferior",
            +        "top": "Número (opcional): câmera frustum (tronco) do plano superior",
            +        "near": "Número (opcional): câmera frustum (tronco) próxima ao plano",
            +        "far": "Número (opcional): câmera frustum (tronco) longe do plano"
            +      }
            +    },
            +    "frustum": {
            +      "description": [
            +        "Define uma matriz de perspectiva conforme definida pelos parâmetros. ",
            +        "Um frustum (tronco) é uma forma geométrica: uma pirâmide com o topo cortado. Com o olho do observador no topo imaginário da pirâmide, os seis planos do frustum atuam como planos de recorte ao renderizar uma vista 3D. Assim, qualquer forma dentro dos planos de recorte é visível; qualquer coisa fora desses planos não é visível. ",
            +        "Definir o frustum muda a perspectiva da cena sendo renderizada. Isso pode ser alcançado de forma mais simples em muitos casos, usando <a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>."
            +      ],
            +      "params": {
            +        "left": "Número (opcional): câmera frustum (tronco) do plano esquerdo",
            +        "right": "Número (opcional): câmera frustum (tronco) do plano direito",
            +        "bottom": "Número (opcional): câmera frustum (tronco) do plano inferior",
            +        "top": "Número (opcional): câmera frustum (tronco)  do plano superior",
            +        "near": "Número (opcional): câmera frustum (tronco) próxima ao plano",
            +        "far": "Número (opcional): câmera frustum (tronco) longe do plano"
            +      }
            +    },
            +    "createCamera": {
            +      "description": [
            +        "Cria um novo objeto <a href=\"#/p5.Camera\">p5.Camera</a> e diz ao renderizador para usar aquela câmera. Retorna o objeto p5.Camera."
            +      ],
            +      "returns": "p5.Camera: O objeto de câmera recém-criado."
            +    },
            +    "setCamera": {
            +      "description": [
            +        "Define a câmera atual do rendererGL para um objeto p5.Camera. Permite alternar entre várias câmeras."
            +      ],
            +      "params": {
            +        "cam": "p5.Camera: objeto p5.Camera"
            +      }
            +    },
            +    "setAttributes": {
            +      "description": [
            +        "Define atributos para o contexto de desenho WebGL. Esta é uma maneira de ajustar a forma como o renderizador WebGL funciona para afinar a exibição e o desempenho. ",
            +        "Observe que isso reinicializará o contexto de desenho se for chamado depois que o canvas WebGL for feito.",
            +        "Se um objeto for passado como parâmetro, todos os atributos não declarados no objeto serão configurados como padrão.",
            +        "Os atributos disponíveis são: alfa - indica se a tela contém um buffer alfa. Por padrão é true (verdadeiro).",
            +        "depth - indica se o buffer do desenho tem um buffer de profundidade de pelo menos 16 bits. Por padrão é true (verdadeiro).",
            +        "stencil - indica se o buffer do desenho tem um buffer de estêncil de pelo menos 8 bits.",
            +        "antialias - indica se deve ou não executar anti-aliasing. Por padrão é false (true no Safari).",
            +        "premultipliedAlpha - indica que o compositor da página irá assumir que o buffer do desenho contém cores com alfa pré-multiplicado. Por padrão é false (falso).",
            +        "preserveDrawingBuffer - se true (verdadeiro) os buffers não serão apagados e preservarão seus valores até que sejam apagados ou sobrescritos pelo autor (observe que o p5 apaga automaticamente no loop de desenho - draw). Por padrão é true (verdadeiro).",
            +        "perPixelLighting - se true (verdadeiro), a iluminação por pixel será usada na shader de iluminação, caso contrário, a iluminação por vértice será usada. Por padrão é true (verdadeiro)."
            +      ],
            +      "params": {
            +        "key": "String: Nome do atributo",
            +        "value": "Booleano: Novo valor do atributo nomeado",
            +        "obj": "Objeto: objeto com pares de chave-valor"
            +      }
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "retorna um número que representa a taxa de amostragem, em amostras por segundo, de todos os objetos de som neste contexto de áudio. É determinado pela taxa de amostragem da placa de som do seu sistema operacional e atualmente não é possível mudar. Freqüentemente, é 44100, ou duas vezes o alcance da audição humana. "
            +      ],
            +      "returns": "Número: taxa de amostragem de amostras por segundo"
            +    },
            +    "freqToMidi": {
            +      "description": [
            +        "retorna o valor de nota MIDI mais próximo para uma determinada frequência."
            +      ],
            +      "returns": "Número: valor da nota MIDI",
            +      "params": {
            +        "frequency": "Número: uma frequência, por exemplo, o \"A\" acima do C médio é 440Hz."
            +      }
            +    },
            +    "midiToFreq": {
            +      "description": [
            +        "retorna o valor da frequência de um valor de nota MIDI. O MIDI geral trata as notas como inteiros onde o C médio é 60, o C# é 61, D é 62 etc. Útil para gerar frequências musicais com osciladores."
            +      ],
            +      "returns": "Número: valor de frequência da nota MIDI fornecida",
            +      "params": {
            +        "midiNote": "Número: o número de uma nota MIDI"
            +      }
            +    },
            +    "soundFormats": {
            +      "description": [
            +        "Lista os formatos de SoundFile que você incluirá. O LoadSound pesquisará essas extensões em seu diretório e escolherá um formato compatível com o navegador da Web do cliente. <a href=\"http://media.io/\">Aqui</a> há um conversor de arquivos online grátis."
            +      ],
            +      "params": {
            +        "formats": "String (opcional): i.e. 'mp3', 'wav', 'ogg'"
            +      }
            +    },
            +    "getAudioContext": {
            +      "description": [
            +        "retorna o contexto de áudio para este sketch. Útil para usuários que desejam se aprofundar no <a target='_blank' href= 'http://webaudio.github.io/web-audio-api/'>Web Audio API </a>.  ",
            +        "Alguns navegadores exigem que os usuários iniciem o AudioContext com um gesto do usuário, como o touchStarted no exemplo abaixo."
            +      ],
            +      "returns": "Objeto: AudioContext para este sketch."
            +    },
            +    "userStartAudio": {
            +      "description": [
            +        "Não é apenas uma boa prática dar aos usuários controle sobre como iniciar o áudio. Esta política é aplicada por muitos navegadores da web, incluindo iOS e <a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay policy\">Google Chrome</a>, que criou a Web Audio API <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\" title=\"Audio Context @ MDN\">Audio Context</a> em um estado suspenso.  ",
            +        "Nessas políticas específicas do navegador, o som não será reproduzido até um evento de interação do usuário (i.e. <code>mousePressed()</code>) retoma explicitamente o AudioContext, ou inicia um audio node (nó). Isso pode ser feito chamando <code>start()</code> em um <code>p5.Oscillator</code>, <code> play()</code> em um <code>p5.SoundFile</code>, ou simplesmente <code>userStartAudio()</code>.  ",
            +        "<code>userStartAudio()</code> inicia o AudioContext em um gesto do usuário. O comportamento padrão habilitará o áudio em qualquer evento mouseUp ou touchEnd. Ele também pode ser colocado em uma função de interação específica, como o <code>mousePressed()</code> como no exemplo abaixo. Este método utiliza <a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext </a>, uma biblioteca por Yotam Mann (MIT Licence, 2016)."
            +      ],
            +      "returns": "Promise: retorna uma Promise que é resolvida quando o estado AudioContext está 'em execução'",
            +      "params": {
            +        "element(s)": "Elemento|Array (opcional): Este argumento pode ser um Element,  Selector String, NodeList, p5.Element,  jQuery Element, ou um Array de qualquer um desses.",
            +        "callback": "Função (opcional): Callback para invocar quando o AudioContext for iniciado"
            +      }
            +    },
            +    "loadSound": {
            +      "description": [
            +        "loadSound() retorna um novo p5.SoundFile de um endereço de arquivo especificado. Se chamado durante o preload(), o p5.SoundFile estará pronto para tocar a tempo para o setup() e draw(). Se chamado fora do preload, o p5.SoundFile não estará pronto imediatamente, então o loadSound aceita um callback como segundo parâmetro. Usar um <a href=\"https://github.com/processing/p5.js/wiki/Local-server\"> servidor local</a> é recomendado ao carregar arquivos externos."
            +      ],
            +      "returns": "SoundFile: retorna um p5.SoundFile",
            +      "params": {
            +        "path": "String|Array: endereço para o arquivo de som, ou um array com os endereços dos arquivos para os soundfiles em vários formatos   i.e. ['sound.ogg', 'sound.mp3'].  Alternativamente, aceita um objeto: tanto do arquivo de API HTML5, ou um p5.File.",
            +        "successCallback": "Função (opcional): nome de uma função a ser chamada assim que o arquivo carregar",
            +        "errorCallback": "Função (opcional): nome de uma função a ser chamada se houver um erro ao carregar o arquivo.",
            +        "whileLoading": "Função (opcional): Nome de uma função a ser chamada durante o carregamento do arquivo. Esta função receberá a porcentagem carregada até o momento, de 0.0 a 1.0."
            +      }
            +    },
            +    "createConvolver": {
            +      "description": [
            +        "Cria um p5.Convolver. Aceita um caminho para um arquivo de som que será usado para gerar uma resposta de impulso."
            +      ],
            +      "returns": "p5.Convolver: ",
            +      "params": {
            +        "path": "String: endereço para o arquivo de som.",
            +        "callback": "Função (opcional): função a ser chamada se o carregamento for bem-sucedido. O objeto será passado como argumento para a função de callback.",
            +        "errorCallback": "Função (opcional): função a ser chamada se o carregamento não for bem-sucedido. Um erro personalizado será passado como argumento para a função de callback."
            +      }
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Define o tempo global, em batidas por minuto, para todas as p5.Parts. Este método afetará todas as p5.Parts ativas."
            +      ],
            +      "params": {
            +        "BPM": "Número: Beats Por Minuto",
            +        "rampTime": "Número: Daqui a segundos"
            +      }
            +    },
            +    "saveSound": {
            +      "description": [
            +        "Salva um p5.SoundFile como um arquivo .wav. O navegador solicitará que o usuário baixe o arquivo em seu dispositivo. Para fazer upload de áudio para um servidor, use <a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile que você deseja salvar",
            +        "fileName": "String: nome do arquivo .wav resultante."
            +      }
            +    }
            +  },
            +  "p5.Color": {
            +    "description": [
            +      "Cada cor armazena o modo de cor e os máximos de nível que foram aplicados no momento de sua construção. Eles são usados para interpretar os argumentos de entrada (na construção e posteriormente para essa instância de cor) e para formatar a saída, por exemplo, quando <a href=\"#/p5/saturation\">saturação()</a> é requerida. ",
            +      "Internamente, armazenamos um array representando os valores RGBA ideais na forma de ponto flutuante, normalizado de 0 a 1. A partir disso, calculamos a cor de tela mais próxima (níveis RGBA de 0 a 255) e a expomos ao renderizador. ",
            +      "Também colocamos em cache normalizado, os componentes de ponto flutuante da cor em várias representações como eles são calculados. Isso é feito para evitar a repetição de uma conversão que já foi realizada."
            +    ],
            +    "toString": {
            +      "description": [
            +        "Esta função retorna a cor formatada como string. Isso pode ser útil para depurar (debug) ou para usar p5.js com outras bibliotecas. "
            +      ],
            +      "returns": "String: a cor formatada como string",
            +      "params": {
            +        "format": "String (opcional): Como a sequência de cores será formatada. Deixar este parâmetro vazio formata a string como rgba (r, g, b, a). '#rgb' '#rgba' '#rrggbb' e '#rrggbbaa' formata como códigos de cores hexadecimais. 'rgb' 'hsb' e 'hsl' retornam a cor formatada no modo de cor especificado. 'rgba' 'hsba' e 'hsla' são iguais aos anteriores, mas com canais alfa. 'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' e 'hsla%' formata como porcentagens. "
            +      }
            +    },
            +    "setRed": {
            +      "description": [
            +        "A função setRed define o componente vermelho de uma cor. O intervalo depende do seu modo de cor, no modo RGB padrão é entre 0 e 255."
            +      ],
            +      "params": {
            +        "red": "Número: o novo valor de vermelho"
            +      }
            +    },
            +    "setGreen": {
            +      "description": [
            +        "A função setGreen define o componente verde de uma cor. O intervalo depende do seu modo de cor, no modo RGB padrão é entre 0 e 255. "
            +      ],
            +      "params": {
            +        "green": "Número: o novo valor de verde"
            +      }
            +    },
            +    "setBlue": {
            +      "description": [
            +        "A função setBlue define o componente azul de uma cor. O intervalo depende do seu modo de cor, no modo RGB padrão é entre 0 e 255."
            +      ],
            +      "params": {
            +        "blue": "Número: o novo valor de azul"
            +      }
            +    },
            +    "setAlpha": {
            +      "description": [
            +        "A função setAlpha define o valor de transparência (alfa) de uma cor. O intervalo depende do seu modo de cor, no modo RGB padrão é entre 0 e 255. "
            +      ],
            +      "params": {
            +        "alpha": "Número: o novo valor de alpha"
            +      }
            +    }
            +  },
            +  "p5.Element": {
            +    "description": [
            +      "Classe base para todos os elementos adicionados a um sketch, incluindo o canvas, buffers gráficos e outros elementos HTML. Não é chamado diretamente, mas os objetos <a href=\"#/p5.Element\">p5.Element</a> são criados ao chamar <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>, <a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc."
            +    ],
            +    "params": {
            +      "elt": "String: nó DOM que está embrulhado",
            +      "pInst": "P5 (opcional): ponteiro para instância p5"
            +    },
            +    "elt": {
            +      "description": [
            +        "Elemento HTML subjacente. Todos os métodos HTML normais podem ser chamados para isso."
            +      ]
            +    },
            +    "parent": {
            +      "description": [
            +        "Anexa o elemento ao pai especificado. Uma maneira de definir o contêiner para o elemento. Aceita tanto uma ID de string, nó DOM ou <a href=\"#/p5.Element\"> p5.Element </a>. Se nenhum argumento for fornecido, o nó pai será retornado. Para obter mais maneiras de posicionar o canvas, consulte o <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>  posicionando o canvas</a> wiki page."
            +      ],
            +      "params": {
            +        "parent": "String|p5.Element|Objeto: a ID, nó DOM, ou <a href=\"#/p5.Element\">p5.Element</a> do elemento pai desejado"
            +      }
            +    },
            +    "id": {
            +      "description": [
            +        "Define o ID do elemento. Se nenhum argumento de ID for passado, ele retorna o ID atual do elemento. Observe que apenas um elemento pode ter um id particular em uma página. A função <a href=\"#/p5.Element/class\"> .class () </a> pode ser usada para identificar vários elementos com o mesmo nome de classe."
            +      ],
            +      "params": {
            +        "id": "String: ID do elemento"
            +      }
            +    },
            +    "class": {
            +      "description": [
            +        "Adiciona determinada classe ao elemento. Se nenhum argumento de classe for passado, ele retorna uma string contendo a(s) classe(s) atual(is) do elemento."
            +      ],
            +      "params": {
            +        "class": "String: classe para adicionar"
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/mousePressed\">mousePressed()</a> é chamada toda vez que um botão do mouse é pressionado sobre o elemento. Alguns navegadores em dispositivos móveis também podem acionar este evento em uma tela sensível ao toque, se o usuário executar um toque rápido. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento e ação."       ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando o mouse é pressionado sobre o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais acionada."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> é chamada uma vez que um botão do mouse é pressionado duas vezes sobre o elemento. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento e ação."
            +      ],
            +      "returns": "p5.Element: ",
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando o mouse é clicado duas vezes sobre o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> é chamada uma vez que a roda do mouse é rolada sobre o elemento. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento.",
            +        " A função aceita uma função de callback como argumento que será executada quando o evento <code>wheel</code> for acionado no elemento, a função de callback receberá um argumento <code>event</code>. A propriedade <code>event.deltaY</code> retorna valores negativos se a roda do mouse for girada para cima ou para longe do usuário e positiva na outra direção. A <code>event.deltaX</code> faz o mesmo que a <code>event.deltaY</code> exceto que lê a roda horizontal da roda do mouse. ",
            +        "No OS X com rolagem \"natural\" habilitada, na <code>event.deltaY</code> os valores são invertidos."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando o mouse é rolado sobre o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> é chamada uma vez que um botão do mouse é liberado sobre o elemento. Alguns navegadores em dispositivos móveis também podem acionar este evento em uma tela sensível ao toque, se o usuário executar um toque rápido. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando o mouse é liberado sobre o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais acionada."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> é chamada uma vez que um botão do mouse é pressionado e liberado sobre o elemento. Alguns navegadores em dispositivos móveis também podem acionar este evento em uma tela sensível ao toque, se o usuário executar um toque rápido. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento"
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando o mouse é clicado sobre o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada. "
            +      }
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> é chamada uma vez que o mouse se move sobre o elemento. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando o mouse mouse se move sobre o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada. "
            +      }
            +    },
            +    "mouseOver": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/mouseOver\">mouseOver()</a> é chamada uma vez que o mouse se move para o elemento. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando o mouse se move para o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada. "
            +      }
            +    },
            +    "mouseOut": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/mouseOut\">mouseOut()</a> é chamada uma vez que o mouse se move para fora do elemento. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando o mouse se move para fora do elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada. "
            +      }
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/touchStarted\">touchStarted()</a> é chamada uma vez que um toque é registrado. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando um toque é registrado. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada. "
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/touchMoved\">touchMoved()</a> é chamada uma vez que um movimento de toque é registrado. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando um toque se move sobre o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada. "
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/touchEnded\">touchEnded()</a> é chamada uma vez que um toque é registrado. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando um toque termina sobre o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada. "
            +      }
            +    },
            +    "dragOver": {
            +      "description": [
            +        "A função <a href=\"#/p5.Element/dragOver\">dragOver()</a> é chamada uma vez que um arquivo é arrastado sobre o elemento. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando um arquivo é arrastado sobre o elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada. "
            +      }
            +    },
            +    "dragLeave": {
            +      "description": [
            +        "A função dragLeave() é chamada uma vez que um arquivo arrastado sai da área do elemento. Isso pode ser usado para anexar funções de escuta de eventos específicos de elemento."
            +      ],
            +      "params": {
            +        "fxn": "Função|Booleano: função a ser disparada quando um arquivo é arrastado para fora do elemento. Se <code>false</code> for passado, a função de disparo anterior não será mais disparada. "
            +      }
            +    },
            +    "addClass": {
            +      "description": [
            +        "Adiciona uma classe especificada ao elemento."
            +      ],
            +      "params": {
            +        "class": "String: nome da classe a ser adicionada"
            +      }
            +    },
            +    "removeClass": {
            +      "description": [
            +        "Remove uma classe especificada do elemento."
            +      ],
            +      "params": {
            +        "class": "String: nome da classe a ser removida."
            +      }
            +    },
            +    "hasClass": {
            +      "description": [
            +        "Verifica se a classe especificada já está definida para o elemento."
            +      ],
            +      "returns": "Booleano: um valor Booleano se o elemento possui a classe especificada.",
            +      "params": {
            +        "c": "String: nome da classe para verificação"
            +      }
            +    },
            +    "toggleClass": {
            +      "description": [
            +        "Alterna classe de elemento."
            +      ],
            +      "params": {
            +        "c": "String: nome da classe a ser alternada"
            +      }
            +    },
            +    "child": {
            +      "description": [
            +        "Anexa o elemento como filho do pai especificado. Aceita tanto um ID de string, um nó DOM, ou um <a href=\"#/p5.Element\">p5.Element</a>. Se nenhum argumento for especificado, uma matriz de nós DOM filhos será retornada. "
            +      ],
            +      "returns": "Node[]: um array de nós filhos",
            +      "params": {
            +        "child": "String|p5.Element (opcional): a ID, nó DOM, ou <a href=\"#/p5.Element\">p5.Element</a>  para adicionar ao elemento atual."
            +      }
            +    },
            +    "center": {
            +      "description": [
            +        "Centraliza um elemento p5 verticalmente, horizontalmente ou ambos, em relação ao seu pai ou de acordo com o body (corpo) se o elemento não tiver pai. Se nenhum argumento for passado, o elemento é alinhado tanto vertical quanto horizontalmente."
            +      ],
            +      "params": {
            +        "align": "String (opcional): passar 'vertical', 'horizontal' alinha o elemento de acordo"
            +      }
            +    },
            +    "html": {
            +      "description": [
            +        "Se um argumento for fornecido, define o HTML interno do elemento, substituindo qualquer HTML existente. Se true (verdadeiro) for incluído como um segundo argumento, o HTML é anexado em vez de substituir o HTML existente. Se nenhum argumento for fornecido, retorna o HTML interno do elemento."
            +      ],
            +      "returns": "String: o HTML interno do elemento",
            +      "params": {
            +        "html": "String (opcional): o HTML a ser colocado dentro do elemento",
            +        "append": "Booleano (opcional): se deve anexar o novo HTML ao existente"
            +      }
            +    },
            +    "position": {
            +      "description": [
            +        "Sets the position of the element. If no position type argument is given, the  position will be relative to (0, 0) of the window.  Essentially, this sets position:absolute and left and top  properties of style. If an optional third argument specifying position type is given,  the x and y coordinates will be interpreted based on the <a target=\"_blank\"  href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.  If no arguments given, the function returns the x and y position of the element. found documentation on how to be more specific with object type  <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a>"
            +      ],
            +      "returns": "Object: object of form { x: 0, y: 0 } containing the position of the element in an object",
            +      "params": {
            +        "x": "Number: (Optional) x-position relative to upper left of window (optional)",
            +        "y": "Number: (Optional) y-position relative to upper left of window (optional)",
            +        "positionType": "String: it can be static, fixed, relative, sticky, initial or inherit (optional)"
            +      }
            +    },
            +    "style": {
            +      "description": [
            +        "Sets the given style (css) property (1st arg) of the element with the given value (2nd arg). If a single argument is given, .style() returns the value of the given property; however, if the single argument is given in css syntax ('text-align:center'), .style() sets the css appropriately."
            +      ],
            +      "returns": "String: value of property",
            +      "params": {
            +        "property": "String: property to be set",
            +        "value": "String|p5.Color: value to assign to property"
            +      }
            +    },
            +    "attribute": {
            +      "description": [
            +        "Adds a new attribute or changes the value of an existing attribute  on the specified element. If no value is specified, returns the  value of the given attribute, or null if attribute is not set."
            +      ],
            +      "returns": "String: value of attribute",
            +      "params": {
            +        "attr": "String: attribute to set",
            +        "value": "String: value to assign to attribute"
            +      }
            +    },
            +    "removeAttribute": {
            +      "description": [
            +        "Removes an attribute on the specified element."
            +      ],
            +      "params": {
            +        "attr": "String: attribute to remove"
            +      }
            +    },
            +    "value": {
            +      "description": [
            +        "Either returns the value of the element if no arguments given, or sets the value of the element."
            +      ],
            +      "returns": "String|Number: value of the element",
            +      "params": {
            +        "value": "String|Number"
            +      }
            +    },
            +    "show": {
            +      "description": [
            +        "Shows the current element. Essentially, setting display:block for the style."
            +      ]
            +    },
            +    "hide": {
            +      "description": [
            +        "Hides the current element. Essentially, setting display:none for the style."
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "Sets the width and height of the element. AUTO can be used to  only adjust one dimension at a time. If no arguments are given, it  returns the width and height of the element in an object. In case of  elements which need to be loaded, such as images, it is recommended  to call the function after the element has finished loading."
            +      ],
            +      "returns": "Object: the width and height of the element in an object",
            +      "params": {
            +        "w": "Number|Constant: width of the element, either AUTO, or a number",
            +        "h": "Number|Constant: (Optional) height of the element, either AUTO, or a number"
            +      }
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the element, stops all media streams, and deregisters all listeners."
            +      ]
            +    },
            +    "drop": {
            +      "description": [
            +        "Registers a callback that gets called every time a file that is dropped on the element has been loaded. p5 will load every dropped file into memory and pass it as a p5.File object to the callback. Multiple files dropped at the same time will result in multiple calls to the callback. ",
            +        "You can optionally pass a second callback which will be registered to the raw <a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event. The callback will thus be provided the original <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>. Dropping multiple files at the same time will trigger the second callback once per drop, whereas the first callback will trigger for each loaded file."
            +      ],
            +      "params": {
            +        "callback": "Function: callback to receive loaded file, called for each file dropped.",
            +        "fxn": "Function: (Optional) callback triggered once when files are dropped with the drop event."
            +      }
            +    }
            +  },
            +  "p5.Graphics": {
            +    "description": [
            +      "Thin wrapper around a renderer, to be used for creating a graphics buffer object. Use this class if you need to draw into an off-screen graphics buffer. The two parameters define the width and height in pixels. The fields and methods for this class are extensive, but mirror the normal drawing API for p5."
            +    ],
            +    "params": {
            +      "w": "Number: width",
            +      "h": "Number: height",
            +      "renderer": "Constant: the renderer to use, either P2D or WEBGL",
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "reset": {
            +      "description": [
            +        "Resets certain values such as those modified by functions in the Transform category and in the Lights category that are not automatically reset with graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior of the standard canvas."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes a Graphics object from the page and frees any resources associated with it."
            +      ]
            +    }
            +  },
            +  "p5.Renderer": {
            +    "description": [
            +      "Main graphics and rendering context, as well as the base API implementation for p5.js \"core\". To be used as the superclass for Renderer2D and Renderer3D classes, respectively."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped",
            +      "pInst": "P5: (Optional) pointer to p5 instance",
            +      "isMainCanvas": "Boolean: (Optional) whether we're using it as main canvas"
            +    }
            +  },
            +  "JSON": {
            +    "stringify": {
            +      "description": [
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">entrada MDN</a>: O método JSON.stringify() converte um objeto ou valor JavaScript em uma <a href=\"#/p5/string\">string</a> JSON."
            +      ],
            +      "params": {
            +        "object": "Objeto: Objeto Javascript que você gostaria de converter para JSON"
            +      }
            +    }
            +  },
            +  "console": {
            +    "log": {
            +      "description": [
            +        "Imprime uma mensagem no console da web do seu navegador. Ao usar o p5, você pode usar <a href=\"#/p5/print\">print</a> (imprimir) e <a href=\"#/p5/console/log\">console.log</a> indistintamente. ",
            +        "O console é aberto de forma diferente dependendo de qual navegador você está usando. Aqui estão os links sobre como abrir o console no <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a> , <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>, e <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>. Com o  <a href=\"https://editor.p5js.org/\">editor online do p5 </a> o console é incorporado diretamente na página abaixo do editor de código. ",
            +        "A partir de uma <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">entrada MDN</a>: O método do console log() tem como saída uma mensagem para o console da web. A mensagem pode ser uma única <a href=\"#/p5/string\">string</a> (com valores de substituição opcionais), ou pode ser qualquer um ou mais <a href=\"#/p5/object\">objetos</a> JavaScript."
            +      ],
            +      "params": {
            +        "message": "String|Expressão|Objeto: Mensagem que você gostaria de imprimir no console."
            +      }
            +    }
            +  },
            +  "p5.TypedDict": {
            +    "description": [
            +      "Base class for all p5.Dictionary types. Specifically  typed Dictionary classes inherit from this class."
            +    ],
            +    "size": {
            +      "description": [
            +        "Returns the number of key-value pairs currently stored in the Dictionary."
            +      ],
            +      "returns": "Integer: the number of key-value pairs in the Dictionary"
            +    },
            +    "hasKey": {
            +      "description": [
            +        "Returns true if the given key exists in the Dictionary, otherwise returns false."
            +      ],
            +      "returns": "Boolean: whether that key exists in Dictionary",
            +      "params": {
            +        "key": "Number|String: that you want to look up"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Returns the value stored at the given key."
            +      ],
            +      "returns": "Number|String: the value stored at that key",
            +      "params": {
            +        "the": "Number|String: key you want to access"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Updates the value associated with the given key in case it already exists in the Dictionary. Otherwise a new key-value pair is added."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String"
            +      }
            +    },
            +    "create": {
            +      "description": [
            +        "Creates a new key-value pair in the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String",
            +        "obj": "Object: key/value pair"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Removes all previously stored key-value pairs from the Dictionary."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the key-value pair stored at the given key from the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String: for the pair to remove"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Logs the set of items currently stored in the Dictionary to the console."
            +      ]
            +    },
            +    "saveTable": {
            +      "description": [
            +        "Converts the Dictionary into a CSV file for local download."
            +      ]
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "Converts the Dictionary into a JSON file for local download."
            +      ]
            +    }
            +  },
            +  "p5.StringDict": {
            +    "description": [
            +      "A simple Dictionary class for Strings."
            +    ]
            +  },
            +  "p5.NumberDict": {
            +    "description": [
            +      "A simple Dictionary class for Numbers."
            +    ],
            +    "add": {
            +      "description": [
            +        "Add the given number to the value currently stored at the given key. The sum then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to add to",
            +        "Number": "Number: to add to the value"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtract the given number from the value currently stored at the given key. The difference then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to subtract from",
            +        "Number": "Number: to subtract from the value"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the given number with the value currently stored at the given key. The product then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to multiply",
            +        "Amount": "Number: to multiply the value by"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Divide the given number with the value currently stored at the given key. The quotient then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to divide",
            +        "Amount": "Number: to divide the value by"
            +      }
            +    },
            +    "minValue": {
            +      "description": [
            +        "Return the lowest number currently stored in the Dictionary."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "maxValue": {
            +      "description": [
            +        "Return the highest number currently stored in the Dictionary."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "minKey": {
            +      "description": [
            +        "Return the lowest key currently used in the Dictionary."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "maxKey": {
            +      "description": [
            +        "Return the highest key currently used in the Dictionary."
            +      ],
            +      "returns": "Number: "
            +    }
            +  },
            +  "p5.MediaElement": {
            +    "description": [
            +      "Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods of <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not called directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>, <a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped"
            +    },
            +    "src": {
            +      "description": [
            +        "Path to the media element source."
            +      ],
            +      "returns": "String: src"
            +    },
            +    "play": {
            +      "description": [
            +        "Play an HTML5 media element."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stops an HTML5 media element (sets current time to zero)."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses an HTML5 media element."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Set 'loop' to true for an HTML5 media element, and starts playing."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Set 'loop' to false for an HTML5 media element. Element will stop when it reaches the end."
            +      ]
            +    },
            +    "autoplay": {
            +      "description": [
            +        "Set HTML5 media element to autoplay or not. If no argument is specified, by default it will autoplay."
            +      ],
            +      "params": {
            +        "shouldAutoplay": "Boolean: whether the element should autoplay"
            +      }
            +    },
            +    "volume": {
            +      "description": [
            +        "Sets volume for this HTML5 media element. If no argument is given, returns the current volume."
            +      ],
            +      "returns": "Number: current volume",
            +      "params": {
            +        "val": "Number: volume between 0.0 and 1.0"
            +      }
            +    },
            +    "speed": {
            +      "description": [
            +        "If no arguments are given, returns the current playback speed of the element. The speed parameter sets the speed where 2.0 will play the element twice as fast, 0.5 will play at half the speed, and -1 will play the element in normal speed in reverse.(Note that not all browsers support backward playback and even if they do, playback might not be smooth.)"
            +      ],
            +      "returns": "Number: current playback speed of the element",
            +      "params": {
            +        "speed": "Number: speed multiplier for element playback"
            +      }
            +    },
            +    "time": {
            +      "description": [
            +        "If no arguments are given, returns the current time of the element. If an argument is given the current time of the element is set to it."
            +      ],
            +      "returns": "Number: current time (in seconds)",
            +      "params": {
            +        "time": "Number: time to jump to (in seconds)"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of the HTML5 media element."
            +      ],
            +      "returns": "Number: duration"
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the audio or video element reaches the end. If the element is looping, this will not be called. The element is passed in as the argument to the onended callback."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended. The  media element will be passed  in as the argument to the  callback."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send the audio output of this element to a specified audioNode or p5.sound object. If no element is provided, connects to p5's main output. That connection is established when this method is first called. All connections are removed by the .disconnect() method. ",
            +        "This method is meant to be used with the p5.sound.js addon library."
            +      ],
            +      "params": {
            +        "audioNode": "AudioNode|Object: AudioNode from the Web Audio API, or an object from the p5.sound library"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all Web Audio routing, including to main output. This is useful if you want to re-route the output through audio effects, for example."
            +      ]
            +    },
            +    "showControls": {
            +      "description": [
            +        "Show the default MediaElement controls, as determined by the web browser."
            +      ]
            +    },
            +    "hideControls": {
            +      "description": [
            +        "Hide the default mediaElement controls."
            +      ]
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point. ",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback. ",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    }
            +  },
            +  "p5.File": {
            +    "description": [
            +      "Base class for a file. Used for Element.drop and createFileInput."
            +    ],
            +    "params": {
            +      "file": "File: File that is wrapped"
            +    },
            +    "file": {
            +      "description": [
            +        "Underlying File object. All normal File methods can be called on this."
            +      ]
            +    },
            +    "type": {
            +      "description": [
            +        "File type (image, text, etc.)"
            +      ]
            +    },
            +    "subtype": {
            +      "description": [
            +        "File subtype (usually the file extension jpg, png, xml, etc.)"
            +      ]
            +    },
            +    "name": {
            +      "description": [
            +        "File name"
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "File size"
            +      ]
            +    },
            +    "data": {
            +      "description": [
            +        "URL string containing either image data, the text contents of the file or a parsed object if file is JSON and p5.XML if XML"
            +      ]
            +    }
            +  },
            +  "p5.Image": {
            +    "description": [
            +      "Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an image. ",
            +      "p5 can display .gif, .jpg and .png images. Images may be displayed in 2D and 3D space. Before an image is used, it must be loaded with the <a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and height of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the values for every pixel in the image. ",
            +      "The methods described below allow easy access to the image's pixels and alpha channel and simplify the process of compositing. ",
            +      "Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on the image to make sure that the pixel data is properly loaded."
            +    ],
            +    "params": {
            +      "width": "Number",
            +      "height": "Number"
            +    },
            +    "width": {
            +      "description": [
            +        "Image width."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "Image height."
            +      ]
            +    },
            +    "pixels": {
            +      "description": [
            +        "Array containing the values for all the pixels in the display window. These values are numbers. This array is the size (include an appropriate factor for pixelDensity) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. Retina and other high density displays may have more pixels (by a factor of pixelDensity^2). For example, if the image is 100x100 pixels, there will be 40,000. With pixelDensity = 2, there will be 160,000. The first four values (indices 0-3) in the array will be the R, G, B, A values of the pixel at (0, 0). The second four values (indices 4-7) will contain the R, G, B, A values of the pixel at (1, 0). More generally, to set values for a pixel at (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre> ",
            +        "Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes."
            +      ]
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "Loads the pixels data for this image into the [pixels] attribute."
            +      ]
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "Updates the backing canvas for this image with the contents of the [pixels] array. ",
            +        "If this image is an animated GIF then the pixels will be updated in the frame that is currently displayed."
            +      ],
            +      "params": {
            +        "x": "Integer: x-offset of the target update area for the  underlying canvas",
            +        "y": "Integer: y-offset of the target update area for the  underlying canvas",
            +        "w": "Integer: height of the target update area for the  underlying canvas",
            +        "h": "Integer: height of the target update area for the  underlying canvas"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Get a region of pixels from an image. ",
            +        "If no params are passed, the whole image is returned. If x and y are the only params passed a single pixel is extracted. If all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a> is returned."
            +      ],
            +      "returns": "p5.Image: the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "w": "Number: width",
            +        "h": "Number: height"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the color of a single pixel or write an image into this <a href=\"#/p5.Image\">p5.Image</a>. ",
            +        "Note that for a large number of pixels this will be slower than directly manipulating the pixels array and then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "a": "Number|Number[]|Object: grayscale value | pixel array |  a <a href=\"#/p5.Color\">p5.Color</a> | image to copy"
            +      }
            +    },
            +    "resize": {
            +      "description": [
            +        "Resize the image to a new width and height. To make the image scale proportionally, use 0 as the value for the wide or high parameter. For instance, to make the width of an image 150 pixels, and change the height using the same proportion, use resize(150, 0)."
            +      ],
            +      "params": {
            +        "width": "Number: the resized image width",
            +        "height": "Number: the resized image height"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Copies a region of pixels from one image to another. If no srcImage is specified this is used as the source. If the source and destination regions aren't the same size, it will automatically resize source pixels to fit the specified target region."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5.Element: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height"
            +      }
            +    },
            +    "mask": {
            +      "description": [
            +        "Masks part of an image from displaying by loading another image and using its alpha channel as an alpha channel for this image. Masks are cumulative, one applied to an image object, they cannot be removed."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a> ",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used. ",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used. ",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used. ",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used. ",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges. ",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur. ",
            +        "ERODE Reduces the light areas. No parameter is used. ",
            +        "DILATE Increases the light areas. No parameter is used. ",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "Constant: either THRESHOLD, GRAY, OPAQUE, INVERT,  POSTERIZE, ERODE, DILATE or BLUR.  See Filters.js for docs on  each available filter",
            +        "filterParam": "Number: (Optional) an optional parameter unique  to each filter, see above"
            +      }
            +    },
            +    "blend": {
            +      "description": [
            +        "Copies a region of pixels from one image to another, using a specified blend mode to do the operation."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height",
            +        "blendMode": "Constant: the blend mode. either  BLEND, DARKEST, LIGHTEST, DIFFERENCE,  MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD or NORMAL. Available blend modes are: normal | multiply | screen | overlay |  darken | lighten | color-dodge | color-burn | hard-light |  soft-light | difference | exclusion | hue | saturation |  color | luminosity <a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a>"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "Saves the image to a file and force the browser to download it. Accepts two strings for filename and file extension Supports png (default), jpg, and gif  Note that the file will only be downloaded as an animated GIF if the p5.Image was loaded from a GIF file."
            +      ],
            +      "params": {
            +        "filename": "String: give your file a name",
            +        "extension": "String: 'png' or 'jpg'"
            +      }
            +    },
            +    "reset": {
            +      "description": [
            +        "Starts an animated GIF over at the beginning state."
            +      ]
            +    },
            +    "getCurrentFrame": {
            +      "description": [
            +        "Gets the index for the frame that is currently visible in an animated GIF."
            +      ],
            +      "returns": "Number: The index for the currently displaying frame in animated GIF"
            +    },
            +    "setFrame": {
            +      "description": [
            +        "Sets the index of the frame that is currently visible in an animated GIF"
            +      ],
            +      "params": {
            +        "index": "Number: the index for the frame that should be displayed"
            +      }
            +    },
            +    "numFrames": {
            +      "description": [
            +        "Returns the number of frames in an animated GIF"
            +      ],
            +      "returns": "Number: "
            +    },
            +    "play": {
            +      "description": [
            +        "Plays an animated GIF that was paused with <a href=\"#/p5.Image/pause\">pause()</a>"
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses an animated GIF."
            +      ]
            +    },
            +    "delay": {
            +      "description": [
            +        "Changes the delay between frames in an animated GIF. There is an optional second parameter that indicates an index for a specific frame that should have its delay modified. If no index is given, all frames will have the new delay."
            +      ],
            +      "params": {
            +        "d": "Number: the amount in milliseconds to delay between switching frames",
            +        "index": "Number: (Optional) the index of the frame that should have the new delay value {optional}"
            +      }
            +    }
            +  },
            +  "p5.PrintWriter": {
            +    "params": {
            +      "filename": "String",
            +      "extension": "String (Optional)"
            +    },
            +    "write": {
            +      "description": [
            +        "Writes data to the PrintWriter stream"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be written by the PrintWriter"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Writes data to the PrintWriter stream, and adds a new line at the end"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be printed by the PrintWriter"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Clears the data already written to the PrintWriter object"
            +      ]
            +    },
            +    "close": {
            +      "description": [
            +        "Closes the PrintWriter"
            +      ]
            +    }
            +  },
            +  "p5.Table": {
            +    "description": [
            +      "<a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much like in a traditional spreadsheet. Tables can be generated from scratch, dynamically, or using data from an existing file."
            +    ],
            +    "params": {
            +      "rows": "p5.TableRow[]: (Optional) An array of p5.TableRow objects"
            +    },
            +    "columns": {
            +      "description": [
            +        "An array containing the names of the columns in the table, if the \"header\" the table is loaded with the \"header\" parameter."
            +      ]
            +    },
            +    "rows": {
            +      "description": [
            +        "An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the rows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a>"
            +      ]
            +    },
            +    "addRow": {
            +      "description": [
            +        "Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default, an empty row is created. Typically, you would store a reference to the new row in a TableRow object (see newRow in the example above), and then set individual values using <a href=\"#/p5/set\">set()</a>. ",
            +        "If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is duplicated and added to the table."
            +      ],
            +      "returns": "p5.TableRow: the row that was added",
            +      "params": {
            +        "row": "p5.TableRow: (Optional) row to be added to the table"
            +      }
            +    },
            +    "removeRow": {
            +      "description": [
            +        "Removes a row from the table object."
            +      ],
            +      "params": {
            +        "id": "Integer: ID number of the row to remove"
            +      }
            +    },
            +    "getRow": {
            +      "description": [
            +        "Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference can then be used to get and set values of the selected row."
            +      ],
            +      "returns": "p5.TableRow: <a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +      "params": {
            +        "rowID": "Integer: ID number of the row to get"
            +      }
            +    },
            +    "getRows": {
            +      "description": [
            +        "Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s."
            +      ],
            +      "returns": "p5.TableRow[]: Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s"
            +    },
            +    "findRow": {
            +      "description": [
            +        "Finds the first row in the Table that contains the value provided, and returns a reference to that row. Even if multiple rows are possible matches, only the first matching row is returned. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow: ",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "findRows": {
            +      "description": [
            +        "Finds the rows in the Table that contain the value provided, and returns references to those rows. Returns an Array, so for must be used to iterate through all the rows, as shown in the example above. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "matchRow": {
            +      "description": [
            +        "Finds the first row in the Table that matches the regular expression provided, and returns a reference to that row. Even if multiple rows are possible matches, only the first matching row is returned. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow: TableRow object",
            +      "params": {
            +        "regexp": "String|RegExp: The regular expression to match",
            +        "column": "String|Integer: The column ID (number) or  title (string)"
            +      }
            +    },
            +    "matchRows": {
            +      "description": [
            +        "Finds the rows in the Table that match the regular expression provided, and returns references to those rows. Returns an array, so for must be used to iterate through all the rows, as shown in the example. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "regexp": "String: The regular expression to match",
            +        "column": "String|Integer: (Optional) The column ID (number) or  title (string)"
            +      }
            +    },
            +    "getColumn": {
            +      "description": [
            +        "Retrieves all values in the specified column, and returns them as an array. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "Array: Array of column values",
            +      "params": {
            +        "column": "String|Number: String or Number of the column to return"
            +      }
            +    },
            +    "clearRows": {
            +      "description": [
            +        "Removes all rows from a Table. While all rows are removed, columns and column titles are maintained."
            +      ]
            +    },
            +    "addColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object. Typically, you will want to specify a title, so the column may be easily referenced later by name. (If no title is specified, the new column's title will be null.)"
            +      ],
            +      "params": {
            +        "title": "String: (Optional) title of the given column"
            +      }
            +    },
            +    "getColumnCount": {
            +      "description": [
            +        "Returns the total number of columns in a Table."
            +      ],
            +      "returns": "Integer: Number of columns in this table"
            +    },
            +    "getRowCount": {
            +      "description": [
            +        "Returns the total number of rows in a Table."
            +      ],
            +      "returns": "Integer: Number of rows in this table"
            +    },
            +    "removeTokens": {
            +      "description": [
            +        "Removes any of the specified characters (or \"tokens\"). ",
            +        "If no column is specified, then the values in all columns and rows are processed. A specific column may be referenced by either its ID or title."
            +      ],
            +      "params": {
            +        "chars": "String: String listing characters to be removed",
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "Trims leading and trailing whitespace, such as spaces and tabs, from String table values. If no column is specified, then the values in all columns and rows are trimmed. A specific column may be referenced by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "removeColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table object. The column to be removed may be identified by either its title (a String) or its index value (an int). removeColumn(0) would remove the first column, removeColumn(1) would remove the second column, and so on."
            +      ],
            +      "params": {
            +        "column": "String|Integer: columnName (string) or ID (number)"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Stores a value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String|Number: value to assign"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Stores a Float value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "Number: value to assign"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Stores a String value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String: value to assign"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retrieves a value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "String|Number: ",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Retrieves a Float value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "Number: ",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Retrieves a String value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "String: ",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getObject": {
            +      "description": [
            +        "Retrieves all table data and returns as an object. If a column name is passed in, each row object will be stored with that attribute as its title."
            +      ],
            +      "returns": "Object: ",
            +      "params": {
            +        "headerColumn": "String: (Optional) Name of the column which should be used to  title each row object (optional)"
            +      }
            +    },
            +    "getArray": {
            +      "description": [
            +        "Retrieves all table data and returns it as a multidimensional array."
            +      ],
            +      "returns": "Array: "
            +    }
            +  },
            +  "p5.TableRow": {
            +    "description": [
            +      "A TableRow object represents a single row of data values, stored in columns, from a table. ",
            +      "A Table Row contains both an ordered array, and an unordered JSON object."
            +    ],
            +    "params": {
            +      "str": "String: (Optional) optional: populate the row with a  string of values, separated by the  separator",
            +      "separator": "String: (Optional) comma separated values (csv) by default"
            +    },
            +    "set": {
            +      "description": [
            +        "Stores a value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number: The value to be stored"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Stores a Float value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "Number|String: The value to be stored  as a Float"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Stores a String value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number|Boolean|Object: The value to be stored  as a String"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retrieves a value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String|Number: ",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Retrieves a Float value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "Number: Float Floating point number",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Retrieves an String value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String: String",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    }
            +  },
            +  "p5.XML": {
            +    "description": [
            +      "XML is a representation of an XML object, able to parse XML code. Use <a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects."
            +    ],
            +    "getParent": {
            +      "description": [
            +        "Gets a copy of the element's parent. Returns the parent as another <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "returns": "p5.XML: element parent"
            +    },
            +    "getName": {
            +      "description": [
            +        "Gets the element's full name, which is returned as a String."
            +      ],
            +      "returns": "String: the name of the node"
            +    },
            +    "setName": {
            +      "description": [
            +        "Sets the element's name, which is specified as a String."
            +      ],
            +      "params": {
            +        "the": "String: new name of the node"
            +      }
            +    },
            +    "hasChildren": {
            +      "description": [
            +        "Checks whether or not the element has any children, and returns the result as a boolean."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "listChildren": {
            +      "description": [
            +        "Get the names of all of the element's children, and returns the names as an array of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a> on each child element individually."
            +      ],
            +      "returns": "String[]: names of the children of the element"
            +    },
            +    "getChildren": {
            +      "description": [
            +        "Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When the name parameter is specified, then it will return all children that match that name."
            +      ],
            +      "returns": "p5.XML[]: children of the element",
            +      "params": {
            +        "name": "String: (Optional) element name"
            +      }
            +    },
            +    "getChild": {
            +      "description": [
            +        "Returns the first of the element's children that matches the name parameter or the child of the given index.It returns undefined if no matching child is found."
            +      ],
            +      "returns": "p5.XML: ",
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "addChild": {
            +      "description": [
            +        "Appends a new child to the element. The child can be specified with either a String, which will be used as the new tag's name, or as a reference to an existing <a href=\"#/p5.XML\">p5.XML</a> object. A reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "params": {
            +        "node": "p5.XML: a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added"
            +      }
            +    },
            +    "removeChild": {
            +      "description": [
            +        "Removes the element specified by name or index."
            +      ],
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "getAttributeCount": {
            +      "description": [
            +        "Counts the specified element's number of attributes, returned as an Number."
            +      ],
            +      "returns": "Integer: "
            +    },
            +    "listAttributes": {
            +      "description": [
            +        "Gets all of the specified element's attributes, and returns them as an array of Strings."
            +      ],
            +      "returns": "String[]: an array of strings containing the names of attributes"
            +    },
            +    "hasAttribute": {
            +      "description": [
            +        "Checks whether or not an element has the specified attribute."
            +      ],
            +      "returns": "Boolean: true if attribute found else false",
            +      "params": {
            +        "the": "String: attribute to be checked"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Returns an attribute value of the element as an Number. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, the value 0 is returned."
            +      ],
            +      "returns": "Number: ",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Returns an attribute value of the element as an String. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, null is returned."
            +      ],
            +      "returns": "String: ",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "setAttribute": {
            +      "description": [
            +        "Sets the content of an element's attribute. The first parameter specifies the attribute name, while the second specifies the new content."
            +      ],
            +      "params": {
            +        "name": "String: the full name of the attribute",
            +        "value": "Number|String|Boolean: the value of the attribute"
            +      }
            +    },
            +    "getContent": {
            +      "description": [
            +        "Returns the content of an element. If there is no such content, defaultValue is returned if specified, otherwise null is returned."
            +      ],
            +      "returns": "String: ",
            +      "params": {
            +        "defaultValue": "String: (Optional) value returned if no content is found"
            +      }
            +    },
            +    "setContent": {
            +      "description": [
            +        "Sets the element's content."
            +      ],
            +      "params": {
            +        "text": "String: the new content"
            +      }
            +    },
            +    "serialize": {
            +      "description": [
            +        "Serializes the element into a string. This function is useful for preparing the content to be sent over a http request or saved to file."
            +      ],
            +      "returns": "String: Serialized string of the element"
            +    }
            +  },
            +  "p5.Vector": {
            +    "description": [
            +      "A class to describe a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector. A vector is an entity that has both magnitude and direction. The datatype, however, stores the components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude and direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>. ",
            +      "In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a position, velocity, or acceleration. For example, if you consider a rectangle moving across the screen, at any given instant it has a position (a vector that points from the origin to its location), a velocity (the rate at which the object's position changes per time unit, expressed as a vector), and acceleration (the rate at which the object's velocity changes per time unit, expressed as a vector). ",
            +      "Since vectors represent groupings of values, we cannot simply use traditional addition/multiplication/etc. Instead, we'll need to do some \"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class."
            +    ],
            +    "params": {
            +      "x": "Number: (Optional) x component of the vector",
            +      "y": "Number: (Optional) y component of the vector",
            +      "z": "Number: (Optional) z component of the vector"
            +    },
            +    "x": {
            +      "description": [
            +        "The x component of the vector"
            +      ]
            +    },
            +    "y": {
            +      "description": [
            +        "The y component of the vector"
            +      ]
            +    },
            +    "z": {
            +      "description": [
            +        "The z component of the vector"
            +      ]
            +    },
            +    "toString": {
            +      "description": [
            +        "Returns a string representation of a vector v by calling String(v) or v.toString(). This method is useful for logging vectors in the console."
            +      ],
            +      "returns": "String: "
            +    },
            +    "set": {
            +      "description": [
            +        "Sets the x, y, and z component of the vector using two or three separate variables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array."
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) the x component of the vector",
            +        "y": "Number: (Optional) the y component of the vector",
            +        "z": "Number: (Optional) the z component of the vector",
            +        "value": "p5.Vector|Number[]: the vector to set"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object."
            +      ],
            +      "returns": "p5.Vector: the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    },
            +    "add": {
            +      "description": [
            +        "Adds x, y, and z components to a vector, adds one vector to another, or adds two independent vectors together. The version of the method that adds two vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to be added",
            +        "y": "Number: (Optional) the y component of the vector to be added",
            +        "z": "Number: (Optional) the z component of the vector to be added",
            +        "value": "p5.Vector|Number[]: the vector to add",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "rem": {
            +      "description": [
            +        "Gives remainder of a vector when it is divided by another vector. See examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of divisor vector",
            +        "y": "Number: the y component of divisor vector",
            +        "z": "Number: the z component of divisor vector",
            +        "value": "p5.Vector | Number[]: divisor vector",
            +        "v1": "p5.Vector: dividend <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: divisor <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtracts x, y, and z components from a vector, subtracts one vector from another, or subtracts two independent vectors. The version of the method that subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the other acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to subtract",
            +        "y": "Number: (optional) the y component of the vector to subtract",
            +        "z": "Number: (optional) the z component of the vector to subtract",
            +        "value": "p5.Vector|Number[]: the vector to subtract",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract",
            +        "target": "p5.Vector: (optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Este método pode multiplicar o vetor por um valor escalar, multiplicar os valores x, y e z de um vetor, ou multiplicar os componentes x, y e z de dois vetores independentes. Ao multiplicar um vetor por um valor escalar, cada variável que o compõe será multiplicada pelo valor. Ao multiplicar dois vetores, os valores dos vetores serão multiplicados individualmente um pelo outro -- por exemplo, com dois vetores A e B, teremos como resultado: [A.x * B.x, A.y * B.y, A.z * B.z].",
            +        "A versão estática do método retorna um novo <a href=\"#/p5.Vector\">p5.Vector</a>, enquanto a versão não-estática modifica o vetor diretamente.",
            +        "Além disso, você pode utilizar uma array como argumento. Veja os exemplos para compreender o método em seu contexto."
            +      ],
            +      "params": {
            +        "n": "Número: o número a ser multiplicado pelo vetor.",
            +        "x": "Número: o número a ser multiplicado pelo valor x do vetor",
            +        "y": "Número: o número a ser multiplicado pelo valor y do vetor",
            +        "z": "Número (opcional): o número a ser multiplicado pelo valor z do vetor",
            +        "arr": "Número[]: a array a ser multiplicada pelos valores do vetor",
            +        "v": "p5.Vector: o vetor a ser multiplicado pelos valores do vetor original",
            +        "target": "p5.Vector (opcional): o vetor que receberá o resultado",
            +        "v0": "p5.Vector: um vetor a ser multiplicado",
            +        "v1": "p5.Vector: um vetor a ser multiplicado"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Este método pode dividir o vetor por um valor escalar, dividir os valores x, y e z de um vetor, ou dividir os componentes x, y e z de dois vetores independentes. Ao dividir um vetor por um valor escalar, cada variável que o compõe será dividida pelo valor. Ao dividir um vetor por outro, cada valor do vetor original será dividido pelo valor correspondente do outro -- por exemplo, com dois vetores A e B, teremos como resultado: [A.x / B.x, A.y / B.y, A.z / B.z].",
            +        "A versão estática do método retorna um novo <a href=\"#/p5.Vector\">p5.Vector</a>, enquanto a versão não-estática modifica o vetor diretamente.",
            +        "Além disso, você pode utilizar uma array como argumento. Veja os exemplos para compreender o método em seu contexto."
            +      ],
            +      "params": {
            +        "n": "Número: o número pelo qual o vetor será dividido",
            +        "x": "Número: o número pelo qual o valor x do vetor será dividido",
            +        "y": "Número: o número pelo qual o valor y do vetor será dividido",
            +        "z": "Número (opcional): o número pelo qual o valor z do vetor será dividido",
            +        "arr": "Número[]: a array pelo qual os valores do vetor serão divididos",
            +        "v": "p5.Vector: o vetor cujos valores irão dividir o vetor original",
            +        "target": "p5.Vector (opcional): o vetor que receberá o resultado",
            +        "v0": "p5.Vector: um vetor a ser dividido",
            +        "v1": "p5.Vector: um vetor cujos valores irão dividir o vetor original"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "Calcula a magnitude (comprimento) de um vetor, e retorna um número. Corresponde à equação <code>sqrt(x*x + y*y + z*z)</code>."
            +      ],
            +      "returns": "Número: magnitude do vetor",
            +      "params": {
            +        "vecT": "p5.Vector: o vetor que se quer saber a magnitude"
            +      }
            +    },
            +    "magSq": {
            +      "description": [
            +        "Calcula a magnitude (comprimento) quadrada do vetor, e retorna um número. Corresponde à equação <em>(x*x + y*y + z*z)</em>. É mais veloz caso o comprimento real não seja necessário ao comparar vetores."
            +      ],
            +      "returns": "Número: magnitude quadrada do vetor"
            +    },
            +    "dot": {
            +      "description": [
            +        "Calcula o produto escalar de dois vetores. A versão deste método que computa o produto escalar de dois vetores independentes é o método estático. Veja os exemplos para compreender o método em seu contexto."
            +      ],
            +      "returns": "Número: o produto escalar",
            +      "params": {
            +        "x": "Número: componente x do vetor",
            +        "y": "Número (opcional): componente y do vetor",
            +        "z": "Número (opcional): componente z do vetor",
            +        "value": "p5.Vector: os valores de um vetor, ou um <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "<a href=\"#/p5.Vector\">p5.Vector</a>: o primeiro vetor",
            +        "v2": "<a href=\"#/p5.Vector\">p5.Vector</a>: o segundo vetor"
            +      }
            +    },
            +    "cross": {
            +      "description": [
            +        "Calcula e retorna o produto vetorial entre dois vetores. Tanto o modo estático quando o modo não-estático retornam um novo <a href=\"#/p5.Vector\">p5.Vector</a>. Veja os exemplos para compreender o método em seu contexto."
            +      ],
            +      "returns": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> resultante do produto escalar",
            +      "params": {
            +        "v": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> a ser comparado",
            +        "v1": "p5.Vector: o primeiro <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: o segundo <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "Calcula a distância euclidiana entre dois pontos, considerando um ponto como um vetor."
            +      ],
            +      "returns": "Número: a distância",
            +      "params": {
            +        "v": "p5.Vector: o <a href=\"#/p5.Vector\">p5.Vector</a> para calcular a distância",
            +        "v1": "p5.Vector: o primeiro <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: o segundo <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "normalize": {
            +      "description": [
            +        "Normalizar o vetor para comprimento 1 — transformá-lo em um vetor unitário."
            +      ],
            +      "returns": "p5.Vector: o <a href=\"#/p5.Vector\">p5.Vector</a> normalizado",
            +      "params": {
            +        "v": "p5.Vector: o vetor a ser normalizado",
            +        "target": "p5.Vector (opcional): o vetor para receber o resultado"
            +      }
            +    },
            +    "limit": {
            +      "description": [
            +        "Limita a magnitude (comprimento) do vetor ao valor dado como parâmetro."
            +      ],
            +      "params": {
            +        "max": "Número: valor máximo para a magnitude do vetor"
            +      }
            +    },
            +    "setMag": {
            +      "description": [
            +        "Transforma a magnitude (comprimento) do vetor no valor dado como parâmetro."
            +      ],
            +      "params": {
            +        "len": "Número: o novo comprimento do vetor"
            +      }
            +    },
            +    "heading": {
            +      "description": [
            +        "Calcula o ângulo de rotação de um vetor 2D. <a href=\"#/p5.Vector\">p5.Vectors</a> criados utilizando a função <a src=\"#/p5/createVector\">createVector()</a> utilizarão graus ou radianos, de acordo com o modo de ângulo (<a = src=\"#/p5/angleMode\">angleMode</a>) definido no código."
            +      ],
            +      "returns": "Número: o ângulo de rotação"
            +    },
            +    "setHeading": {
            +      "description": [
            +        "Rotaciona um vetor 2D até um ângulo específico. A magnitude (comprimento) permanece a mesma."
            +      ],
            +      "params": {
            +        "angle": "Número: o ângulo de rotação"
            +      }
            +    },
            +    "rotate": {
            +      "description": [
            +        "Rotaciona um vetor em 2D pelo ângulo dado como parâmetro. A magnitude (comprimento) permanece a mesma."
            +      ],
            +      "params": {
            +        "angle": "Número: o ângulo de rotação",
            +        "v": "vetor a ser rotacionado",
            +        "target": "p5.Vector (opcional): um vetor para receber o resultado"
            +      }
            +    },
            +    "angleBetween": {
            +      "description": [
            +        "Calcula e retorna o ângulo entre dois vetores em radianos."
            +      ],
            +      "returns": "Número: o ângulo entre os vetores (em radianos)",
            +      "params": {
            +        "value": "p5.Vector: os componentes x, y e z de um <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "Interpolação linear entre dois vetores."
            +      ],
            +      "params": {
            +        "x": "Número: o componente x do vetor",
            +        "y": "Número: o componente y do vetor",
            +        "z": "Número: o componente z do vetor",
            +        "amt": "Número: a quatia de interpolação — um valor entre 0.0 (primeiro vetor) e 1.0 (segundo vetor). 0.9 é bem próximo do segundo vetor, 0.5 é entre os dois.",
            +        "v": "p5.Vector: o vetor para interpolar",
            +        "v1": "p5.Vector: o primeiro vetor",
            +        "v2": "p5.Vector: o segundo vetor",
            +        "target": "p5.Vector (opcional): o vetor para receber o resultado"
            +      }
            +    },
            +    "reflect": {
            +      "description": [
            +        "Reflete o vetor incidente, resultando em sua normal como uma linha em 2D, ou um plano em 3D. Este método age diretamente no vetor."
            +      ],
            +      "params": {
            +        "surfaceNormal": "p5.Vector: o <a href=\"#/p5.Vector\">p5.Vector</a> a ser refletido, que será normalizado pelo método."
            +      }
            +    },
            +    "array": {
            +      "description": [
            +        "Retorna uma representação do vetor como uma array de números. Isto é somente para uso temporário. Se utilizado de outra maneira, o conteúdo deve ser copiado usando o método <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> para criar uma nova array."
            +      ],
            +      "returns": "Número[]: uma Array com três valores"
            +    },
            +    "equals": {
            +      "description": [
            +        "Checa se o vetor é igual a outro."
            +      ],
            +      "returns": "Booleano: retorna true (verdadeiro) caso os vetores sejam iguais, ou false (falso) caso não sejam",
            +      "params": {
            +        "x": "Número (opcional): o componente x do vetor",
            +        "y": "Número (opcional): o componente y do vetor",
            +        "z": "Número (opcional): o componente z do vetor",
            +        "value": "p5.Vector|Array: o vetor a ser comparado"
            +      }
            +    },
            +    "fromAngle": {
            +      "description": [
            +        "Faz um novo vetor 2D a partir de um ângulo."
            +      ],
            +      "returns": "p5.Vector: um novo <a href=\"#/p5.Vector\">p5.Vector</a>",
            +      "params": {
            +        "angle": "Número: o ângulo desejado em radianos (não é afetado pelo modo de ângulo — <a href=\"#/p5/angleMode\">angleMode</a>)",
            +        "length": "Número (opcional): o comprimento do novo vetor — caso não seja declarado, utiliza o valor 1 por padrão"
            +      }
            +    },
            +    "fromAngles": {
            +      "description": [
            +        "Cria um novo vetor 3D a partir de um par de ângulos em coordenadas esféricas. Utiliza o padrão norte-americano (<a href=\"https://www.iso.org/standard/64973.html\" target=\"_blank\">ISO</a>)."
            +      ],
            +      "returns": "p5.Vector: o novo <a href=\"#/p5.Vector\">p5.Vector</a>",
            +      "params": {
            +        "theta": "Número: ângulo polar (também conhecido como colatidude ou ângulo zenital) — ângulo que o vetor faz com o eixo Z positivo, em radianos; 0 significa para cima",
            +        "phi": "Número: azimute (ou longitude) — ângulo que a projeção do vetor sobre o eixo XY faz com o eixo X positivo, em radianos",
            +        "length": "Número (opcional): o comprimento do novo vetor — caso não seja especificado, é utilizado como padrão o valor 1"
            +      }
            +    },
            +    "random2D": {
            +      "description": [
            +        "Cria um novo vetor unitário 2D a partir de um ângulo aleatório."
            +      ],
            +      "returns": "p5.Vector: um novo <a href=\"#/p5.Vector\">p5.Vector</a>"
            +    },
            +    "random3D": {
            +      "description": [
            +        "Cria um novo vetor unitário 3D aleatório."
            +      ],
            +      "returns": "p5.Vector: um novo <a href=\"#/p5.Vector\">p5.Vector</a>"
            +    }
            +  },
            +  "p5.Font": {
            +    "description": [
            +      "Classe base para o uso de fontes."
            +    ],
            +    "params": {
            +      "pInst": "P5 (opcional): ponteiro para a instância do p5"
            +    },
            +    "font": {
            +      "description": [
            +        "Implementação subjacente de fontes opentype."
            +      ]
            +    },
            +    "textBounds": {
            +      "description": [
            +        "Retorna um retângulo contornando o texto dado, usando a fonte escolhida."
            +      ],
            +      "returns": "Objeto: um retângulo com as propriedades x, y, largura, e altura",
            +      "params": {
            +        "line": "String: um texto",
            +        "x": "Número: coordenada x",
            +        "y": "Número: coordenada y",
            +        "fontSize": "Número (opcional): o tamanho da fonte a ser utilizada — o padrão é 12",
            +        "options": "Objeto (opcional): opções opentype — fontes opentype possuem opções de alinhamento e linha de base, sendo o padrão 'LEFT' e 'alphabetic'"
            +      }
            +    },
            +    "textToPoints": {
            +      "description": [
            +        "Calcula uma array de pontos que segue o contorno do texto especificado."
            +      ],
            +      "returns": "Array: uma array de pontos, cada um consistindo em x, y, e alpha (o ângulo do contorno)",
            +      "params": {
            +        "txt": "String: o texto a ser convertido em pontos",
            +        "x": "Número: coordenada x",
            +        "y": "Número: coordenada y",
            +        "fontSize": "Número (opcional): tamanho da fonte a ser utilizada",
            +        "options": "Objeto (opcional): um objeto que pode conter: sampleFactor - a proporção de pontos por segmento de traço, sendo que quanto maior o valor, mais pontos, e portanto mais precisão (o padrão é 1). simplifyThreshold - se este valor não for 0, pontos colineares serão removidos do polígono. O valor representa o ângulo limite para determinar se dois pontos são colineares ou não."
            +      }
            +    }
            +  },
            +  "p5.Camera": {
            +    "description": [
            +      "Esta classe descreve a câmera a ser utilizada no <a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\"> modo WebGL</a> do p5. Ela contém a posição da câmera, orientação, e informação de projeção necessária para renderizar uma cena 3D. ",
            +      "Novos objetos p5.Camera podem ser criados através da função <a href=\"#/p5/createCamera\">createCamera()</a>, e controlados a partir dos métodos descritos abaixo. A câmera criada dessa forma utilizará a posição e projeção de perspectiva padrão até que estas propriedades sejam modificadas através dos métodos disponíveis. É possível criar múltiplas câmeras, e então alternar entre elas utilizando o método <a href=\"#/p5/setCamera\">setCamera()</a> ",
            +      "Nota: Os métodos abaixo operam em dois sistemas de coordenadas — o sistema do 'mundo' se refere às posições em relação à origem ao longo dos eixos X, Y e Z. O sistema 'local' da câmera se refere a posições a partir do ponto de vista da própria câmera: esquerda-direita, cima-baixo, frente-trás. O método <a href=\"#/p5.Camera/move\">move()</a>, por exemplo, move a câmera em seus próprios eixos, enquanto <a href=\"#/p5.Camera/setPosition\">setPosition()</a> define a posição da câmera em relação ao espaço-mundo. ",
            +      "As propriedades <code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code> que descrevem a posição, orientação e projeção da câmera, também são acessíveis a partir do objeto criado utilizando <a href=\"#/p5/createCamera\">createCamera()</a>"
            +    ],
            +    "params": {
            +      "rendererGL": "RendererGL: instance of WebGL renderer"
            +    },
            +    "eyeX": {
            +      "description": [
            +        "camera position value on x axis"
            +      ]
            +    },
            +    "eyeY": {
            +      "description": [
            +        "camera position value on y axis"
            +      ]
            +    },
            +    "eyeZ": {
            +      "description": [
            +        "camera position value on z axis"
            +      ]
            +    },
            +    "centerX": {
            +      "description": [
            +        "x coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerY": {
            +      "description": [
            +        "y coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerZ": {
            +      "description": [
            +        "z coordinate representing center of the sketch"
            +      ]
            +    },
            +    "upX": {
            +      "description": [
            +        "x component of direction 'up' from camera"
            +      ]
            +    },
            +    "upY": {
            +      "description": [
            +        "y component of direction 'up' from camera"
            +      ]
            +    },
            +    "upZ": {
            +      "description": [
            +        "z component of direction 'up' from camera"
            +      ]
            +    },
            +    "perspective": {
            +      "description": [
            +        "Sets a perspective projection for a p5.Camera object and sets parameters for that projection according to <a href=\"#/p5/perspective\">perspective()</a> syntax."
            +      ]
            +    },
            +    "ortho": {
            +      "description": [
            +        "Sets an orthographic projection for a p5.Camera object and sets parameters for that projection according to <a href=\"#/p5/ortho\">ortho()</a> syntax."
            +      ]
            +    },
            +    "frustum": {},
            +    "pan": {
            +      "description": [
            +        "Panning rotates the camera view to the left and right."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "tilt": {
            +      "description": [
            +        "Tilting rotates the camera view up and down."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "lookAt": {
            +      "description": [
            +        "Reorients the camera to look at a position in world space."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "Sets a camera's position and orientation. This is equivalent to calling <a href=\"#/p5/camera\">camera()</a> on a p5.Camera object."
            +      ]
            +    },
            +    "move": {
            +      "description": [
            +        "Move camera along its local axes while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: amount to move along camera's left-right axis",
            +        "y": "Number: amount to move along camera's up-down axis",
            +        "z": "Number: amount to move along camera's forward-backward axis"
            +      }
            +    },
            +    "setPosition": {
            +      "description": [
            +        "Set camera position in world-space while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    }
            +  },
            +  "p5.Geometry": {
            +    "description": [
            +      "p5 Geometry class"
            +    ],
            +    "params": {
            +      "detailX": "Integer: (Optional) number of vertices on horizontal surface",
            +      "detailY": "Integer: (Optional) number of vertices on horizontal surface",
            +      "callback": "Function: (Optional) function to call upon object instantiation."
            +    },
            +    "computeFaces": {
            +      "description": [
            +        "computes faces for geometry objects based on the vertices."
            +      ]
            +    },
            +    "computeNormals": {
            +      "description": [
            +        "computes smooth normals per vertex as an average of each face."
            +      ]
            +    },
            +    "averageNormals": {
            +      "description": [
            +        "Averages the vertex normals. Used in curved surfaces"
            +      ]
            +    },
            +    "averagePoleNormals": {
            +      "description": [
            +        "Averages pole normals. Used in spherical primitives"
            +      ]
            +    },
            +    "normalize": {
            +      "description": [
            +        "Modifies all vertices to be centered within the range -100 to 100."
            +      ]
            +    }
            +  },
            +  "p5.Shader": {
            +    "description": [
            +      "Shader class for WEBGL Mode"
            +    ],
            +    "params": {
            +      "renderer": "p5.RendererGL: an instance of p5.RendererGL that will provide the GL context for this new p5.Shader",
            +      "vertSrc": "String: source code for the vertex shader (as a string)",
            +      "fragSrc": "String: source code for the fragment shader (as a string)"
            +    },
            +    "setUniform": {
            +      "description": [
            +        "Wrapper around gl.uniform functions. As we store uniform info in the shader we can use that to do type checking on the supplied data and call the appropriate function."
            +      ],
            +      "params": {
            +        "uniformName": "String: the name of the uniform in the shader program",
            +        "data": "Object|Number|Boolean|Number[]: the data to be associated with that uniform; type varies (could be a single numerical value, array, matrix, or texture / sampler reference)"
            +      }
            +    }
            +  },
            +  "p5.sound": {
            +    "getMasterVolume": {
            +      "description": [
            +        "Returns a number representing the master amplitude (volume) for sound in this sketch."
            +      ],
            +      "returns": "Number: Master amplitude (volume) for sound in this sketch.  Should be between 0.0 (silence) and 1.0."
            +    },
            +    "masterVolume": {
            +      "description": [
            +        "Scale the output of all sound in this sketch Scaled between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.  ",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal. ",
            +        "<b>How This Works</b>: When you load the p5.sound module, it creates a single instance of p5sound. All sound objects in this module output to p5sound before reaching your computer's output. So if you change the amplitude of p5sound, it impacts all of the sound in this module.  ",
            +        "If no value is provided, returns a Web Audio API Gain Node"
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "soundOut": {
            +      "description": [
            +        "<code>p5.soundOut</code> is the p5.sound master output. It sends output to the destination of this window's web audio context. It contains Web Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>), and Gain Nodes for <code>.input</code> and <code>.output</code>."
            +      ]
            +    }
            +  },
            +  "p5.Effect": {
            +    "description": [
            +      "Effect is a base class for audio effects in p5. This module handles the nodes and methods that are common and useful for current and future effects. ",
            +      "This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>, <a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>, <a href=\"/reference/#/p5.Delay\">p5.Delay</a>, <a href=\"/reference/#/p5.Filter\">p5.Filter</a>, <a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>."
            +    ],
            +    "params": {
            +      "ac": "Object: (Optional) Reference to the audio context of the p5 object",
            +      "input": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "output": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "_drywet": "Object: (Optional) Tone.JS CrossFade node (defaults to value: 1)",
            +      "wet": "AudioNode: (Optional) Effects that extend this class should connect  to the wet signal to this gain node, so that dry and wet  signals are mixed properly."
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output volume of the filter."
            +      ],
            +      "params": {
            +        "vol": "Number: (Optional) amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts until rampTime",
            +        "tFromNow": "Number: (Optional) schedule this event to happen in tFromNow seconds"
            +      }
            +    },
            +    "chain": {
            +      "description": [
            +        "Link effects together in a chain Example usage: filter.chain(reverb, delay, panner); May be used with an open-ended number of arguments"
            +      ],
            +      "params": {
            +        "arguments": "Object: (Optional) Chain together multiple sound objects"
            +      }
            +    },
            +    "drywet": {
            +      "description": [
            +        "Adjust the dry/wet value."
            +      ],
            +      "params": {
            +        "fade": "Number: (Optional) The desired drywet value (0 - 1.0)"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.js-sound, Web Audio Node, or use signal to control an AudioParam"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Filter": {
            +    "description": [
            +      "A p5.Filter uses a Web Audio Biquad Filter to filter the frequency response of an input source. Subclasses include: <a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>: Allows frequencies below the cutoff frequency to pass through, and attenuates frequencies above the cutoff.",
            +      "<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>: The opposite of a lowpass filter.",
            +      "<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>: Allows a range of frequencies to pass through and attenuates the frequencies below and above this frequency range.",
            +      "The <code>.res()</code> method controls either width of the bandpass, or resonance of the low/highpass cutoff frequency. ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "type": "String: (Optional) 'lowpass' (default), 'highpass', 'bandpass'"
            +    },
            +    "biquadFilter": {
            +      "description": [
            +        "The p5.Filter is built with a <a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\"> Web Audio BiquadFilter Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Filter an audio signal according to a set of filter parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance/Width of the filter frequency  from 0.001 to 1000"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the frequency and the resonance of the filter."
            +      ],
            +      "params": {
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance (Q) from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "freq": {
            +      "description": [
            +        "Set the filter frequency, in Hz, from 10 to 22050 (the range of human hearing, although in reality most people hear in a narrower range)."
            +      ],
            +      "returns": "Number: value Returns the current frequency value",
            +      "params": {
            +        "freq": "Number: Filter Frequency",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "res": {
            +      "description": [
            +        "Controls either width of a bandpass frequency, or the resonance of a low/highpass cutoff frequency."
            +      ],
            +      "returns": "Number: value Returns the current res value",
            +      "params": {
            +        "res": "Number: Resonance/Width of filter freq  from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "gain": {
            +      "description": [
            +        "Controls the gain attribute of a Biquad Filter. This is distinctly different from .amp() which is inherited from p5.Effect .amp() controls the volume via the output gain node p5.Filter.gain() controls the gain parameter of a Biquad Filter node."
            +      ],
            +      "returns": "Number: Returns the current or updated gain value",
            +      "params": {
            +        "gain": "Number"
            +      }
            +    },
            +    "toggle": {
            +      "description": [
            +        "Toggle function. Switches between the specified type and allpass"
            +      ],
            +      "returns": "Boolean: [Toggle value]"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set the type of a p5.Filter. Possible types include: \"lowpass\" (default), \"highpass\", \"bandpass\", \"lowshelf\", \"highshelf\", \"peaking\", \"notch\", \"allpass\"."
            +      ],
            +      "params": {
            +        "t": "String"
            +      }
            +    }
            +  },
            +  "p5.LowPass": {
            +    "description": [
            +      "Constructor: <code>new p5.LowPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('lowpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.HighPass": {
            +    "description": [
            +      "Constructor: <code>new p5.HighPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('highpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.BandPass": {
            +    "description": [
            +      "Constructor: <code>new p5.BandPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('bandpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.Oscillator": {
            +    "description": [
            +      "Creates a signal that oscillates between -1.0 and 1.0. By default, the oscillation takes the form of a sinusoidal shape ('sine'). Additional types include 'triangle', 'sawtooth' and 'square'. The frequency defaults to 440 oscillations per second (440Hz, equal to the pitch of an 'A' note).  ",
            +      "Set the type of oscillation with setType(), or by instantiating a specific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a href=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a href=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a href=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>. "
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) frequency defaults to 440Hz",
            +      "type": "String: (Optional) type of oscillator. Options:  'sine' (default), 'triangle',  'sawtooth', 'square'"
            +    },
            +    "start": {
            +      "description": [
            +        "Start an oscillator. ",
            +        "Starting an oscillator on a user gesture will enable audio in browsers that have a strict autoplay policy, including Chrome and most mobile devices. See also: <code>userStartAudio()</code>."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) startTime in seconds from now.",
            +        "frequency": "Number: (Optional) frequency in Hz."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop an oscillator. Accepts an optional parameter to determine how long (in seconds from now) until the oscillator stops."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: Time, in seconds from now."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the amplitude between 0 and 1.0. Or, pass in an object such as an oscillator to modulate amplitude with an audio signal."
            +      ],
            +      "returns": "AudioParam: gain If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's  gain/amplitude/volume)",
            +      "params": {
            +        "vol": "Number|Object: between 0 and 1.0  or a modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "freq": {
            +      "description": [
            +        "Set frequency of an oscillator to a value. Or, pass in an object such as an oscillator to modulate the frequency with an audio signal."
            +      ],
            +      "returns": "AudioParam: Frequency If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's frequency",
            +      "params": {
            +        "Frequency": "Number|Object: Frequency in Hz  or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Ramp time (in seconds)",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen  at x seconds from now"
            +      }
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type to 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "params": {
            +        "type": "String: 'sine', 'triangle', 'sawtooth' or 'square'."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Pan between Left (-1) and Right (1)"
            +      ],
            +      "params": {
            +        "panning": "Number: Number between -1 and 1",
            +        "timeFromNow": "Number: schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "phase": {
            +      "description": [
            +        "Set the phase of an oscillator between 0.0 and 1.0. In this implementation, phase is a delay time based on the oscillator's current frequency."
            +      ],
            +      "params": {
            +        "phase": "Number: float between 0.0 and 1.0"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Oscillator's output amplitude by a fixed value (i.e. turn it up!). Calling this method again will override the initial mult() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with multiplied output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this oscillator's amplitude values to a given range, and return the oscillator. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.SinOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SinOsc()</code>. This creates a Sine Wave Oscillator and is equivalent to <code> new p5.Oscillator('sine') </code> or creating a p5.Oscillator and then calling its method <code>setType('sine')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.TriOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.TriOsc()</code>. This creates a Triangle Wave Oscillator and is equivalent to <code>new p5.Oscillator('triangle') </code> or creating a p5.Oscillator and then calling its method <code>setType('triangle')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SawOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SawOsc()</code>. This creates a SawTooth Wave Oscillator and is equivalent to <code> new p5.Oscillator('sawtooth') </code> or creating a p5.Oscillator and then calling its method <code>setType('sawtooth')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SqrOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SqrOsc()</code>. This creates a Square Wave Oscillator and is equivalent to <code> new p5.Oscillator('square') </code> or creating a p5.Oscillator and then calling its method <code>setType('square')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.MonoSynth": {
            +    "description": [
            +      "A MonoSynth is used as a single voice for sound synthesis. This is a class to be used in conjunction with the PolySynth class. Custom synthetisers should be built inheriting from this class."
            +    ],
            +    "play": {
            +      "description": [
            +        "Play tells the MonoSynth to start playing a note. This method schedules the calling of .triggerAttack and .triggerRelease."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope. Defaults to 0.15 seconds."
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "attack": {
            +      "description": [
            +        "Getters and Setters"
            +      ]
            +    },
            +    "decay": {},
            +    "sustain": {},
            +    "release": {},
            +    "amp": {
            +      "description": [
            +        "MonoSynth amp"
            +      ],
            +      "returns": "Number: new volume value",
            +      "params": {
            +        "vol": "Number: desired volume",
            +        "rampTime": "Number: (Optional) Time to reach new volume"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  },
            +  "p5.AudioVoice": {
            +    "description": [
            +      "Base class for monophonic synthesizers. Any extensions of this class should follow the API and implement the methods below in order to remain compatible with p5.PolySynth();"
            +    ],
            +    "connect": {
            +      "description": [
            +        "Connect to p5 objects or Web Audio Nodes"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect from soundOut"
            +      ]
            +    }
            +  },
            +  "p5.PolySynth": {
            +    "description": [
            +      "An AudioVoice is used as a single voice for sound synthesis. The PolySynth class holds an array of AudioVoice, and deals with voices allocations, with setting notes to be played, and parameters to be set."
            +    ],
            +    "params": {
            +      "synthVoice": "Number: (Optional) A monophonic synth voice inheriting  the AudioVoice class. Defaults to p5.MonoSynth",
            +      "maxVoices": "Number: (Optional) Number of voices, defaults to 8;"
            +    },
            +    "notes": {
            +      "description": [
            +        "An object that holds information about which notes have been played and which notes are currently being played. New notes are added as keys on the fly. While a note has been attacked, but not released, the value of the key is the audiovoice which is generating that note. When notes are released, the value of the key becomes undefined."
            +      ]
            +    },
            +    "polyvalue": {
            +      "description": [
            +        "A PolySynth must have at least 1 voice, defaults to 8"
            +      ]
            +    },
            +    "AudioVoice": {
            +      "description": [
            +        "Monosynth that generates the sound for each note that is triggered. The p5.PolySynth defaults to using the p5.MonoSynth as its voice."
            +      ]
            +    },
            +    "play": {
            +      "description": [
            +        "Play a note by triggering noteAttack and noteRelease with sustain time"
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note to play (ranging from 0 to 127 - 60 being a middle C)",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "noteADSR": {
            +      "description": [
            +        "noteADSR sets the envelope for a specific note that has just been triggered. Using this method modifies the envelope of whichever audiovoice is being used to play the desired note. The envelope should be reset before noteRelease is called in order to prevent the modified envelope from being used on other notes."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) Midi note on which ADSR should be set.",
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set the PolySynths global envelope. This method modifies the envelopes of each monosynth so that all notes are played with this envelope."
            +      ],
            +      "params": {
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "noteAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of a MonoSynth. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)/",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds)"
            +      }
            +    },
            +    "noteRelease": {
            +      "description": [
            +        "Trigger the Release of an AudioVoice note. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.  If no value is provided, all notes will be released.",
            +        "secondsFromNow": "Number: (Optional) time to trigger the release"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  },
            +  "p5.SoundFile": {
            +    "description": [
            +      "SoundFile object with a path to a file.  ",
            +      "The p5.SoundFile may not be available immediately because it loads the file information asynchronously.  ",
            +      "To do something with the sound as soon as it loads pass the name of a function as the second parameter.  ",
            +      "Only one file path is required. However, audio file formats (i.e. mp3, ogg, wav and m4a/aac) are not supported by all web browsers. If you want to ensure compatability, instead of a single file path, you may include an Array of filepaths, and the browser will choose a format that works."
            +    ],
            +    "params": {
            +      "path": "String|Array: path to a sound file (String). Optionally,  you may include multiple file formats in  an array. Alternately, accepts an object  from the HTML5 File API, or a p5.File.",
            +      "successCallback": "Function: (Optional) Name of a function to call once file loads",
            +      "errorCallback": "Function: (Optional) Name of a function to call if file fails to  load. This function will receive an error or  XMLHttpRequest object with information  about what went wrong.",
            +      "whileLoadingCallback": "Function: (Optional) Name of a function to call while file  is loading. That function will  receive progress of the request to  load the sound file  (between 0 and 1) as its first  parameter. This progress  does not account for the additional  time needed to decode the audio data."
            +    },
            +    "isLoaded": {
            +      "description": [
            +        "Returns true if the sound file finished loading successfully."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "play": {
            +      "description": [
            +        "Play the p5.SoundFile"
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule playback to start (in seconds from now).",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) amplitude (volume)  of playback",
            +        "cueStart": "Number: (Optional) (optional) cue start time in seconds",
            +        "duration": "Number: (Optional) (optional) duration of playback in seconds"
            +      }
            +    },
            +    "playMode": {
            +      "description": [
            +        "p5.SoundFile has two play modes: <code>restart</code> and <code>sustain</code>. Play Mode determines what happens to a p5.SoundFile if it is triggered while in the middle of playback. In sustain mode, playback will continue simultaneous to the new playback. In restart mode, play() will stop playback and start over. With untilDone, a sound will play only if it's not already playing. Sustain is the default mode."
            +      ],
            +      "params": {
            +        "str": "String: 'restart' or 'sustain' or 'untilDone'"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses a file that is currently playing. If the file is not playing, then nothing will happen. ",
            +        "After pausing, .play() will resume from the paused position. If p5.SoundFile had been set to loop before it was paused, it will continue to loop after it is unpaused with .play()."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop the p5.SoundFile. Accepts optional parameters to set the playback rate, playback volume, loopStart, loopEnd."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) playback volume",
            +        "cueLoopStart": "Number: (Optional) (optional) startTime in seconds",
            +        "duration": "Number: (Optional) (optional) loop duration in seconds"
            +      }
            +    },
            +    "setLoop": {
            +      "description": [
            +        "Set a p5.SoundFile's looping flag to true or false. If the sound is currently playing, this change will take effect when it reaches the end of the current playback."
            +      ],
            +      "params": {
            +        "Boolean": "Boolean: set looping to true or false"
            +      }
            +    },
            +    "isLooping": {
            +      "description": [
            +        "Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "isPlaying": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is playing, false if not (i.e. paused or stopped)."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "isPaused": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is paused, false if not (i.e. playing or stopped)."
            +      ],
            +      "returns": "Boolean: "
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop soundfile playback."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  in seconds from now"
            +      }
            +    },
            +    "setVolume": {
            +      "description": [
            +        "Multiply the output volume (amplitude) of a sound file between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class. ",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal."
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "pan": {
            +      "description": [
            +        "Set the stereo panning of a p5.sound object to a floating point number between -1.0 (left) and 1.0 (right). Default is 0.0 (center)."
            +      ],
            +      "params": {
            +        "panValue": "Number: (Optional) Set the stereo panner",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current stereo pan position (-1.0 to 1.0)"
            +      ],
            +      "returns": "Number: Returns the stereo pan setting of the Oscillator  as a number between -1.0 (left) and 1.0 (right).  0.0 is center and default."
            +    },
            +    "rate": {
            +      "description": [
            +        "Set the playback rate of a sound file. Will change the speed and the pitch. Values less than zero will reverse the audio buffer."
            +      ],
            +      "params": {
            +        "playbackRate": "Number: (Optional) Set the playback rate. 1.0 is normal,  .5 is half-speed, 2.0 is twice as fast.  Values less than zero play backwards."
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of a sound file in seconds."
            +      ],
            +      "returns": "Number: The duration of the soundFile in seconds."
            +    },
            +    "currentTime": {
            +      "description": [
            +        "Return the current position of the p5.SoundFile playhead, in seconds. Time is relative to the normal buffer direction, so if <code>reverseBuffer</code> has been called, currentTime will count backwards."
            +      ],
            +      "returns": "Number: currentTime of the soundFile in seconds."
            +    },
            +    "jump": {
            +      "description": [
            +        "Move the playhead of a soundfile that is currently playing to a new position and a new duration, in seconds. If none are given, will reset the file to play entire duration from start to finish. To set the position of a soundfile that is not currently playing, use the <code>play</code> or <code>loop</code> methods."
            +      ],
            +      "params": {
            +        "cueTime": "Number: cueTime of the soundFile in seconds.",
            +        "duration": "Number: duration in seconds."
            +      }
            +    },
            +    "channels": {
            +      "description": [
            +        "Return the number of channels in a sound file. For example, Mono = 1, Stereo = 2."
            +      ],
            +      "returns": "Number: [channels]"
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Return the sample rate of the sound file."
            +      ],
            +      "returns": "Number: [sampleRate]"
            +    },
            +    "frames": {
            +      "description": [
            +        "Return the number of samples in a sound file. Equal to sampleRate * duration."
            +      ],
            +      "returns": "Number: [sampleCount]"
            +    },
            +    "getPeaks": {
            +      "description": [
            +        "Returns an array of amplitude peaks in a p5.SoundFile that can be used to draw a static waveform. Scans through the p5.SoundFile's audio buffer to find the greatest amplitudes. Accepts one parameter, 'length', which determines size of the array. Larger arrays result in more precise waveform visualizations. ",
            +        "Inspired by Wavesurfer.js."
            +      ],
            +      "returns": "Float32Array: Array of peaks.",
            +      "params": {
            +        "length": "Number: (Optional) length is the size of the returned array.  Larger length results in more precision.  Defaults to 5*width of the browser window."
            +      }
            +    },
            +    "reverseBuffer": {
            +      "description": [
            +        "Reverses the p5.SoundFile's buffer source. Playback must be handled separately (see example)."
            +      ]
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the soundfile reaches the end of a buffer. If the soundfile is playing through once, this will be called when it ends. If it is looping, it will be called when stop is called."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connects the output of a p5sound object to input of another p5.sound object. For example, you may connect a p5.SoundFile to an FFT or an Effect. If no parameter is given, it will connect to the master output. Most p5sound objects connect to the master output when they are created."
            +      ],
            +      "params": {
            +        "object": "Object: (Optional) Audio object that accepts an input"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnects the output of this p5sound object."
            +      ]
            +    },
            +    "setPath": {
            +      "description": [
            +        "Reset the source for this SoundFile to a new path (URL)."
            +      ],
            +      "params": {
            +        "path": "String: path to audio file",
            +        "callback": "Function: Callback"
            +      }
            +    },
            +    "setBuffer": {
            +      "description": [
            +        "Replace the current Audio Buffer with a new Buffer."
            +      ],
            +      "params": {
            +        "buf": "Array: Array of Float32 Array(s). 2 Float32 Arrays  will create a stereo source. 1 will create  a mono source."
            +      }
            +    },
            +    "processPeaks": {
            +      "description": [
            +        "processPeaks returns an array of timestamps where it thinks there is a beat. ",
            +        "This is an asynchronous function that processes the soundfile in an offline audio context, and sends the results to your callback function. ",
            +        "The process involves running the soundfile through a lowpass filter, and finding all of the peaks above the initial threshold. If the total number of peaks are below the minimum number of peaks, it decreases the threshold and re-runs the analysis until either minPeaks or minThreshold are reached."
            +      ],
            +      "returns": "Array: Array of timestamped peaks",
            +      "params": {
            +        "callback": "Function: a function to call once this data is returned",
            +        "initThreshold": "Number: (Optional) initial threshold defaults to 0.9",
            +        "minThreshold": "Number: (Optional) minimum threshold defaults to 0.22",
            +        "minPeaks": "Number: (Optional) minimum number of peaks defaults to 200"
            +      }
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point. ",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback. ",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ]
            +    },
            +    "save": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. To upload a file to a server, see <a href=\"/docs/reference/#/p5.SoundFile/getBlob\">getBlob</a>"
            +      ],
            +      "params": {
            +        "fileName": "String: (Optional) name of the resulting .wav file."
            +      }
            +    },
            +    "getBlob": {
            +      "description": [
            +        "This method is useful for sending a SoundFile to a server. It returns the .wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at MDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\". A Blob is a file-like data object that can be uploaded to a server with an <a href=\"/docs/reference/#/p5/httpDo\">http</a> request. We'll use the <code>httpDo</code> options object to send a POST request with some specific options: we encode the request as <code>multipart/form-data</code>, and attach the blob as one of the form values using <code>FormData</code>."
            +      ],
            +      "returns": "Blob: A file-like data object"
            +    }
            +  },
            +  "p5.Amplitude": {
            +    "description": [
            +      "Amplitude measures volume between 0.0 and 1.0. Listens to all p5sound by default, or use setInput() to listen to a specific sound source. Accepts an optional smoothing value, which defaults to 0."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) between 0.0 and .999 to smooth  amplitude readings (defaults to 0)"
            +    },
            +    "setInput": {
            +      "description": [
            +        "Connects to the p5sound instance (master output) by default. Optionally, you can pass in a specific source (i.e. a soundfile)."
            +      ],
            +      "params": {
            +        "snd": "SoundObject|undefined: (Optional) set the sound source  (optional, defaults to  master output)",
            +        "smoothing": "Number|undefined: (Optional) a range between 0.0 and 1.0  to smooth amplitude readings"
            +      }
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Returns a single Amplitude reading at the moment it is called. For continuous readings, run in the draw loop."
            +      ],
            +      "returns": "Number: Amplitude as a number between 0.0 and 1.0",
            +      "params": {
            +        "channel": "Number: (Optional) Optionally return only channel 0 (left) or 1 (right)"
            +      }
            +    },
            +    "toggleNormalize": {
            +      "description": [
            +        "Determines whether the results of Amplitude.process() will be Normalized. To normalize, Amplitude finds the difference the loudest reading it has processed and the maximum amplitude of 1.0. Amplitude adds this difference to all values to produce results that will reliably map between 0.0 and 1.0. However, if a louder moment occurs, the amount that Normalize adds to all the values will change. Accepts an optional boolean parameter (true or false). Normalizing is off by default."
            +      ],
            +      "params": {
            +        "boolean": "Boolean: (Optional) set normalize to true (1) or false (0)"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth Amplitude analysis by averaging with the last analysis frame. Off by default."
            +      ],
            +      "params": {
            +        "set": "Number: smoothing from 0.0 <= 1"
            +      }
            +    }
            +  },
            +  "p5.FFT": {
            +    "description": [
            +      "FFT (Fast Fourier Transform) is an analysis algorithm that isolates individual <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\"> audio frequencies</a> within a waveform.  ",
            +      "Once instantiated, a p5.FFT object can return an array based on two types of analyses: • <code>FFT.waveform()</code> computes amplitude values along the time domain. The array indices correspond to samples across a brief moment in time. Each value represents amplitude of the waveform at that sample of time. • <code>FFT.analyze() </code> computes amplitude values along the frequency domain. The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Use with <code>getEnergy()</code> to measure amplitude at specific frequencies, or within a range of frequencies. ",
            +      "FFT analyzes a very short snapshot of sound called a sample buffer. It returns an array of amplitude measurements, referred to as <code>bins</code>. The array is 1024 bins long by default. You can change the bin array length, but it must be a power of 2 between 16 and 1024 in order for the FFT algorithm to function correctly. The actual size of the FFT buffer is twice the number of bins, so given a standard sample rate, the buffer is 2048/44100 seconds long."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) Smooth results of Freq Spectrum.  0.0 < smoothing < 1.0.  Defaults to 0.8.",
            +      "bins": "Number: (Optional) Length of resulting array.  Must be a power of two between  16 and 1024. Defaults to 1024."
            +    },
            +    "setInput": {
            +      "description": [
            +        "Set the input source for the FFT analysis. If no source is provided, FFT will analyze all sound in the sketch."
            +      ],
            +      "params": {
            +        "source": "Object: (Optional) p5.sound object (or web audio API source node)"
            +      }
            +    },
            +    "waveform": {
            +      "description": [
            +        "Returns an array of amplitude values (between -1.0 and +1.0) that represent a snapshot of amplitude readings in a single buffer. Length will be equal to bins (defaults to 1024). Can be used to draw the waveform of a sound."
            +      ],
            +      "returns": "Array: Array Array of amplitude values (-1 to 1)  over time. Array length = bins.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "precision": "String: (Optional) If any value is provided, will return results  in a Float32 Array which is more precise  than a regular array."
            +      }
            +    },
            +    "analyze": {
            +      "description": [
            +        "Returns an array of amplitude values (between 0 and 255) across the frequency spectrum. Length is equal to FFT bins (1024 by default). The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Must be called prior to using <code>getEnergy()</code>."
            +      ],
            +      "returns": "Array: spectrum Array of energy (amplitude/volume)  values across the frequency spectrum.  Lowest energy (silence) = 0, highest  possible is 255.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "scale": "Number: (Optional) If \"dB,\" returns decibel  float measurements between  -140 and 0 (max).  Otherwise returns integers from 0-255."
            +      }
            +    },
            +    "getEnergy": {
            +      "description": [
            +        "Returns the amount of energy (volume) at a specific <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\"> frequency</a>, or the average amount of energy between two frequencies. Accepts Number(s) corresponding to frequency (in Hz), or a String corresponding to predefined frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\"). Returns a range between 0 (no energy/volume at that frequency) and 255 (maximum energy). <em>NOTE: analyze() must be called prior to getEnergy(). Analyze() tells the FFT to analyze frequency data, and getEnergy() uses the results determine the value at a specific frequency or range of frequencies.</em>"
            +      ],
            +      "returns": "Number: Energy Energy (volume/amplitude) from  0 and 255.",
            +      "params": {
            +        "frequency1": "Number|String: Will return a value representing  energy at this frequency. Alternately,  the strings \"bass\", \"lowMid\" \"mid\",  \"highMid\", and \"treble\" will return  predefined frequency ranges.",
            +        "frequency2": "Number: (Optional) If a second frequency is given,  will return average amount of  energy that exists between the  two frequencies."
            +      }
            +    },
            +    "getCentroid": {
            +      "description": [
            +        "Returns the <a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\"> spectral centroid</a> of the input signal. <em>NOTE: analyze() must be called prior to getCentroid(). Analyze() tells the FFT to analyze frequency data, and getCentroid() uses the results determine the spectral centroid.</em>"
            +      ],
            +      "returns": "Number: Spectral Centroid Frequency Frequency of the spectral centroid in Hz."
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth FFT analysis by averaging with the last analysis frame."
            +      ],
            +      "params": {
            +        "smoothing": "Number: 0.0 < smoothing < 1.0.  Defaults to 0.8."
            +      }
            +    },
            +    "linAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values for a given number of frequency bands split equally. N defaults to 16. <em>NOTE: analyze() must be called prior to linAverages(). Analyze() tells the FFT to analyze frequency data, and linAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: linearAverages Array of average amplitude values for each group",
            +      "params": {
            +        "N": "Number: Number of returned frequency groups"
            +      }
            +    },
            +    "logAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values of the spectrum, for a given set of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\"> Octave Bands</a> <em>NOTE: analyze() must be called prior to logAverages(). Analyze() tells the FFT to analyze frequency data, and logAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: logAverages Array of average amplitude values for each group",
            +      "params": {
            +        "octaveBands": "Array: Array of Octave Bands objects for grouping"
            +      }
            +    },
            +    "getOctaveBands": {
            +      "description": [
            +        "Calculates and Returns the 1/N <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a> N defaults to 3 and minimum central frequency to 15.625Hz. (1/3 Octave Bands ~= 31 Frequency Bands) Setting fCtr0 to a central value of a higher octave will ignore the lower bands and produce less frequency groups."
            +      ],
            +      "returns": "Array: octaveBands Array of octave band objects with their bounds",
            +      "params": {
            +        "N": "Number: Specifies the 1/N type of generated octave bands",
            +        "fCtr0": "Number: Minimum central frequency for the lowest band"
            +      }
            +    }
            +  },
            +  "p5.Signal": {
            +    "description": [
            +      "p5.Signal is a constant audio-rate signal used by p5.Oscillator and p5.Envelope for modulation math.  ",
            +      "This is necessary because Web Audio is processed on a seprate clock. For example, the p5 draw loop runs about 60 times per second. But the audio clock must process samples 44100 times per second. If we want to add a value to each of those samples, we can't do it in the draw loop, but we can do it by adding a constant-rate audio signal.</p.  ",
            +      "This class mostly functions behind the scenes in p5.sound, and returns a Tone.Signal from the Tone.js library by Yotam Mann. If you want to work directly with audio signals for modular synthesis, check out <a href='http://bit.ly/1oIoEng' target=_'blank'>tone.js.</a>"
            +    ],
            +    "returns": "Tone.Signal: A Signal object from the Tone.js library",
            +    "fade": {
            +      "description": [
            +        "Fade to value, for smooth transitions"
            +      ],
            +      "params": {
            +        "value": "Number: Value to set this signal",
            +        "secondsFromNow": "Number: (Optional) Length of fade, in seconds from now"
            +      }
            +    },
            +    "setInput": {
            +      "description": [
            +        "Connect a p5.sound object or Web Audio node to this p5.Signal so that its amplitude values can be scaled."
            +      ],
            +      "params": {
            +        "input": "Object"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a constant value to this audio signal, and return the resulting audio signal. Does not change the value of the original signal, instead it returns a new p5.SignalAdd."
            +      ],
            +      "returns": "p5.Signal: object",
            +      "params": {
            +        "number": "Number"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply this signal by a constant value, and return the resulting audio signal. Does not change the value of the original signal, instead it returns a new p5.SignalMult."
            +      ],
            +      "returns": "p5.Signal: object",
            +      "params": {
            +        "number": "Number: to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this signal value to a given range, and return the result as an audio signal. Does not change the value of the original signal, instead it returns a new p5.SignalScale."
            +      ],
            +      "returns": "p5.Signal: object",
            +      "params": {
            +        "number": "Number: to multiply",
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.Envelope": {
            +    "description": [
            +      "Envelopes are pre-defined amplitude distribution over time. Typically, envelopes are used to control the output volume of an object, a series of fades referred to as Attack, Decay, Sustain and Release ( <a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a> ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can control an Oscillator's frequency like this: <code>osc.freq(env)</code>. ",
            +      "Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level. Use <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime. ",
            +      "Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope, the <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger, or <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/ <code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff."
            +    ],
            +    "attackTime": {
            +      "description": [
            +        "Time until envelope reaches attackLevel"
            +      ]
            +    },
            +    "attackLevel": {
            +      "description": [
            +        "Level once attack is complete."
            +      ]
            +    },
            +    "decayTime": {
            +      "description": [
            +        "Time until envelope reaches decayLevel."
            +      ]
            +    },
            +    "decayLevel": {
            +      "description": [
            +        "Level after decay. The envelope will sustain here until it is released."
            +      ]
            +    },
            +    "releaseTime": {
            +      "description": [
            +        "Duration of the release portion of the envelope."
            +      ]
            +    },
            +    "releaseLevel": {
            +      "description": [
            +        "Level at the end of the release."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Reset the envelope with a series of time/value pairs."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds) before level  reaches attackLevel",
            +        "attackLevel": "Number: Typically an amplitude between  0.0 and 1.0",
            +        "decayTime": "Number: Time",
            +        "decayLevel": "Number: Amplitude (In a standard ADSR envelope,  decayLevel = sustainLevel)",
            +        "releaseTime": "Number: Release Time (in seconds)",
            +        "releaseLevel": "Number: Amplitude"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setRange": {
            +      "description": [
            +        "Set max (attackLevel) and min (releaseLevel) of envelope."
            +      ],
            +      "params": {
            +        "aLevel": "Number: attack level (defaults to 1)",
            +        "rLevel": "Number: release level (defaults to 0)"
            +      }
            +    },
            +    "setInput": {
            +      "description": [
            +        "Assign a parameter to be controlled by this envelope. If a p5.Sound object is given, then the p5.Envelope will control its output gain. If multiple inputs are provided, the env will control all of them."
            +      ],
            +      "params": {
            +        "inputs": "Object: (Optional) A p5.sound object or  Web Audio Param."
            +      }
            +    },
            +    "setExp": {
            +      "description": [
            +        "Set whether the envelope ramp is linear (default) or exponential. Exponential ramps can be useful because we perceive amplitude and frequency logarithmically."
            +      ],
            +      "params": {
            +        "isExp": "Boolean: true is exponential, false is linear"
            +      }
            +    },
            +    "play": {
            +      "description": [
            +        "Play tells the envelope to start acting on a given input. If the input is a p5.sound object (i.e. AudioIn, Oscillator, SoundFile), then Envelope will control its output volume. Envelopes can also be used to control any <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Audio Param.</a>"
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound object or  Web Audio Param.",
            +        "startTime": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go. Input can be any p5.sound object, or a <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Param</a>."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time from now (in seconds)"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the Release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "ramp": {
            +      "description": [
            +        "Exponentially ramp to a value using the first two values from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code> as <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\"> time constants</a> for simple exponential ramps. If the value is higher than current value, it uses attackTime, while a decrease uses decayTime."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: When to trigger the ramp",
            +        "v": "Number: Target value",
            +        "v2": "Number: (Optional) Second target value (optional)"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Envelope's output amplitude by a fixed value. Calling this method again will override the initial mult() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this envelope's amplitude values to a given range, and return the envelope. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.Pulse": {
            +    "description": [
            +      "Creates a Pulse object, an oscillator that implements Pulse Width Modulation. The pulse is created with two oscillators. Accepts a parameter for frequency, and to set the width between the pulses. See <a href=\" http://p5js.org/reference/#/p5.Oscillator\"> <code>p5.Oscillator</code> for a full list of methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Frequency in oscillations per second (Hz)",
            +      "w": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +    },
            +    "width": {
            +      "description": [
            +        "Set the width of a Pulse object (an oscillator that implements Pulse Width Modulation)."
            +      ],
            +      "params": {
            +        "width": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +      }
            +    }
            +  },
            +  "p5.Noise": {
            +    "description": [
            +      "Noise is a type of oscillator that generates a buffer with random values."
            +    ],
            +    "params": {
            +      "type": "String: Type of noise can be 'white' (default),  'brown' or 'pink'."
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type of noise to 'white', 'pink' or 'brown'. White is the default."
            +      ],
            +      "params": {
            +        "type": "String: (Optional) 'white', 'pink' or 'brown'"
            +      }
            +    }
            +  },
            +  "p5.AudioIn": {
            +    "description": [
            +      "Get audio from an input, i.e. your computer's microphone.  ",
            +      "Turn the mic on/off with the start() and stop() methods. When the mic is on, its volume can be measured with getLevel or by connecting an FFT object.  ",
            +      "If you want to hear the AudioIn, use the .connect() method. AudioIn does not connect to p5.sound output by default to prevent feedback.  ",
            +      "<em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/ Stream</a> API, which is not supported by certain browsers. Access in Chrome browser is limited to localhost and https, but access over http may be limited.</em>"
            +    ],
            +    "params": {
            +      "errorCallback": "Function: (Optional) A function to call if there is an error  accessing the AudioIn. For example,  Safari and iOS devices do not  currently allow microphone access."
            +    },
            +    "input": {},
            +    "output": {},
            +    "stream": {},
            +    "mediaStream": {},
            +    "currentSource": {},
            +    "enabled": {
            +      "description": [
            +        "Client must allow browser to access their microphone / audioin source. Default: false. Will become true when the client enables access."
            +      ]
            +    },
            +    "amplitude": {
            +      "description": [
            +        "Input amplitude, connect to it by default but not to master out"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start processing audio input. This enables the use of other AudioIn methods like getLevel(). Note that by default, AudioIn is not connected to p5.sound's output. So you won't hear anything unless you use the connect() method.",
            +        "Certain browsers limit access to the user's microphone. For example, Chrome only allows access from localhost and over https. For this reason, you may want to include an errorCallback—a function that is called in case the browser won't provide mic access."
            +      ],
            +      "params": {
            +        "successCallback": "Function: (Optional) Name of a function to call on  success.",
            +        "errorCallback": "Function: (Optional) Name of a function to call if  there was an error. For example,  some browsers do not support  getUserMedia."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel(). If re-starting, the user may be prompted for permission access."
            +      ]
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to an audio unit. If no parameter is provided, will connect to the master output (i.e. your speakers)."
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) An object that accepts audio input,  such as an FFT"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect the AudioIn from all audio units. For example, if connect() had been called, disconnect() will stop sending signal to your speakers."
            +      ]
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Read the Amplitude (volume level) of an AudioIn. The AudioIn class contains its own instance of the Amplitude class to help make it easy to get a microphone's volume level. Accepts an optional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must .start() before using .getLevel().</em>"
            +      ],
            +      "returns": "Number: Volume level (between 0.0 and 1.0)",
            +      "params": {
            +        "smoothing": "Number: (Optional) Smoothing is 0.0 by default.  Smooths values based on previous values."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set amplitude (volume) of a mic input between 0 and 1.0. "
            +      ],
            +      "params": {
            +        "vol": "Number: between 0 and 1.0",
            +        "time": "Number: (Optional) ramp time (optional)"
            +      }
            +    },
            +    "getSources": {
            +      "description": [
            +        "Returns a list of available input sources. This is a wrapper for <a title=\"MediaDevices.enumerateDevices() - Web APIs | MDN\" target=\"_blank\" href=  \"<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"\">https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"</a> <blockquote> ",
            +        "and it returns a Promise. </blockquote>"
            +      ],
            +      "returns": "Promise: Returns a Promise that can be used in place of the callbacks, similar  to the enumerateDevices() method",
            +      "params": {
            +        "successCallback": "Function: (Optional) This callback function handles the sources when they  have been enumerated. The callback function  receives the deviceList array as its only argument",
            +        "errorCallback": "Function: (Optional) This optional callback receives the error  message as its argument."
            +      }
            +    },
            +    "setSource": {
            +      "description": [
            +        "Set the input source. Accepts a number representing a position in the array returned by getSources(). This is only available in browsers that support <a title=\"MediaDevices.enumerateDevices() - Web APIs | MDN\" target=\"_blank\" href= \"<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"\">https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"</a> <blockquote> ",
            +        "navigator.mediaDevices.enumerateDevices()</a>.</blockquote>"
            +      ],
            +      "params": {
            +        "num": "Number: position of input source in the array"
            +      }
            +    }
            +  },
            +  "p5.EQ": {
            +    "description": [
            +      "p5.EQ is an audio effect that performs the function of a multiband audio equalizer. Equalization is used to adjust the balance of frequency compoenents of an audio signal. This process is commonly used in sound production and recording to change the waveform before it reaches a sound output device. EQ can also be used as an audio effect to create interesting distortions by filtering out parts of the spectrum. p5.EQ is built using a chain of Web Audio Biquad Filter Nodes and can be instantiated with 3 or 8 bands. Bands can be added or removed from the EQ by directly modifying p5.EQ.bands (the array that stores filters). ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "returns": "Object: p5.EQ object",
            +    "params": {
            +      "_eqsize": "Number: (Optional) Constructor will accept 3 or 8, defaults to 3"
            +    },
            +    "bands": {
            +      "description": [
            +        "The p5.EQ is built with abstracted p5.Filter objects. To modify any bands, use methods of the <a href=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\"> p5.Filter</a> API, especially <code>gain</code> and <code>freq</code>. Bands are stored in an array, with indices 0 - 3, or 0 - 7"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process an input by connecting it to the EQ"
            +      ],
            +      "params": {
            +        "src": "Object: Audio source"
            +      }
            +    }
            +  },
            +  "p5.Panner3D": {
            +    "description": [
            +      "Panner3D is based on the <a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>. This panner is a spatial processing node that allows audio to be positioned and oriented in 3D space. ",
            +      "The position is relative to an <a title=\"Web Audio Listener docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\"> Audio Context Listener</a>, which can be accessed by <code>p5.soundOut.audiocontext.listener</code>"
            +    ],
            +    "panner": {
            +      "description": [
            +        "<a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a> ",
            +        "Properties include <ul> <li><a title=\"w3 spec for Panning Model\" href=\"<a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\"\">https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\"</a><blockquote> ",
            +        "panningModel</a>: \"equal power\" or \"HRTF\" </blockquote> </li> <li><a title=\"w3 spec for Distance Model\" href=\"<a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\"\">https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\"</a><blockquote> ",
            +        "distanceModel</a>: \"linear\", \"inverse\", or \"exponential\" </blockquote> </li> </ul>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect an audio sorce"
            +      ],
            +      "params": {
            +        "src": "Object: Input source"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "positionX": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionY": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionZ": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orient": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "orientX": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientY": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientZ": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "setFalloff": {
            +      "description": [
            +        "Set the rolloff factor and max distance"
            +      ],
            +      "params": {
            +        "maxDistance": "Number (Optional)",
            +        "rolloffFactor": "Number (Optional)"
            +      }
            +    },
            +    "maxDist": {
            +      "description": [
            +        "Maxium distance between the source and the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "maxDistance": "Number"
            +      }
            +    },
            +    "rollof": {
            +      "description": [
            +        "How quickly the volume is reduced as the source moves away from the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "rolloffFactor": "Number"
            +      }
            +    }
            +  },
            +  "p5.Delay": {
            +    "description": [
            +      "Delay is an echo effect. It processes an existing sound source, and outputs a delayed version of that sound. The p5.Delay can produce different effects depending on the delayTime, feedback, filter, and type. In the example below, a feedback of 0.5 (the default value) will produce a looping delay that decreases in volume by 50% each repeat. A filter will cut out the high frequencies so that the delay does not sound as piercing as the original source. ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "leftDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "rightDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Add delay to an audio signal according to a set of delay parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "delayTime": "Number: (Optional) Time (in seconds) of the delay/echo.  Some browsers limit delayTime to  1 second.",
            +        "feedback": "Number: (Optional) sends the delay back through itself  in a loop that decreases in volume  each time.",
            +        "lowPass": "Number: (Optional) Cutoff frequency. Only frequencies  below the lowPass will be part of the  delay."
            +      }
            +    },
            +    "delayTime": {
            +      "description": [
            +        "Set the delay (echo) time, in seconds. Usually this value will be a floating point number between 0.0 and 1.0."
            +      ],
            +      "params": {
            +        "delayTime": "Number: Time (in seconds) of the delay"
            +      }
            +    },
            +    "feedback": {
            +      "description": [
            +        "Feedback occurs when Delay sends its signal back through its input in a loop. The feedback amount determines how much signal to send each time through the loop. A feedback greater than 1.0 is not desirable because it will increase the overall output each time through the loop, creating an infinite feedback loop. The default value is 0.5"
            +      ],
            +      "returns": "Number: Feedback value",
            +      "params": {
            +        "feedback": "Number|Object: 0.0 to 1.0, or an object such as an  Oscillator that can be used to  modulate this param"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Set a lowpass filter frequency for the delay. A lowpass filter will cut off any frequencies higher than the filter frequency."
            +      ],
            +      "params": {
            +        "cutoffFreq": "Number|Object: A lowpass filter will cut off any  frequencies higher than the filter frequency.",
            +        "res": "Number|Object: Resonance of the filter frequency  cutoff, or an object (i.e. a p5.Oscillator)  that can be used to modulate this parameter.  High numbers (i.e. 15) will produce a resonance,  low numbers (i.e. .2) will produce a slope."
            +      }
            +    },
            +    "setType": {
            +      "description": [
            +        "Choose a preset type of delay. 'pingPong' bounces the signal from the left to the right channel to produce a stereo effect. Any other parameter will revert to the default delay setting."
            +      ],
            +      "params": {
            +        "type": "String|Number: 'pingPong' (1) or 'default' (0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the delay effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Reverb": {
            +    "description": [
            +      "Reverb adds depth to a sound through a large number of decaying echoes. It creates the perception that sound is occurring in a physical space. The p5.Reverb has paramters for Time (how long does the reverb last) and decayRate (how much the sound decays with each echo) that can be set with the .set() or .process() methods. The p5.Convolver extends p5.Reverb allowing you to recreate the sound of actual physical spaces through convolution. ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "process": {
            +      "description": [
            +        "Connect a source to the reverb, and assign reverb parameters."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output.",
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the reverb settings. Similar to .process(), but without assigning a new input."
            +      ],
            +      "params": {
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the reverb effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Convolver": {
            +    "description": [
            +      "p5.Convolver extends p5.Reverb. It can emulate the sound of real physical spaces through a process called <a href=\" https://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\"> convolution</a>.  ",
            +      "Convolution multiplies any audio input by an \"impulse response\" to simulate the dispersion of sound over time. The impulse response is generated from an audio file that you provide. One way to generate an impulse response is to pop a balloon in a reverberant space and record the echo. Convolution can also be used to experiment with sound.  ",
            +      "Use the method <code>createConvolution(path)</code> to instantiate a p5.Convolver with a path to your impulse response audio file."
            +    ],
            +    "params": {
            +      "path": "String: path to a sound file",
            +      "callback": "Function: (Optional) function to call when loading succeeds",
            +      "errorCallback": "Function: (Optional) function to call if loading fails.  This function will receive an error or  XMLHttpRequest object with information  about what went wrong."
            +    },
            +    "convolverNode": {
            +      "description": [
            +        "Internally, the p5.Convolver uses the a <a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\"> Web Audio Convolver Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect a source to the convolver."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "impulses": {
            +      "description": [
            +        "If you load multiple impulse files using the .addImpulse method, they will be stored as Objects in this Array. Toggle between them with the <code>toggleImpulse(id)</code> method."
            +      ]
            +    },
            +    "addImpulse": {
            +      "description": [
            +        "Load and assign a new Impulse Response to the p5.Convolver. The impulse is added to the <code>.impulses</code> array. Previous impulses can be accessed with the <code>.toggleImpulse(id)</code> method."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "resetImpulse": {
            +      "description": [
            +        "Similar to .addImpulse, except that the <code>.impulses</code> Array is reset to save memory. A new <code>.impulses</code> array is created with this impulse as the only item."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "toggleImpulse": {
            +      "description": [
            +        "If you have used <code>.addImpulse()</code> to add multiple impulses to a p5.Convolver, then you can use this method to toggle between the items in the <code>.impulses</code> Array. Accepts a parameter to identify which impulse you wish to use, identified either by its original filename (String) or by its position in the <code>.impulses </code> Array (Number).",
            +        "You can access the objects in the .impulses Array directly. Each Object has two attributes: an <code>.audioBuffer</code> (type: Web Audio <a href=\" http://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\"> AudioBuffer)</a> and a <code>.name</code>, a String that corresponds with the original filename."
            +      ],
            +      "params": {
            +        "id": "String|Number: Identify the impulse by its original filename  (String), or by its position in the  <code>.impulses</code> Array (Number)."
            +      }
            +    }
            +  },
            +  "p5.Phrase": {
            +    "description": [
            +      "A phrase is a pattern of musical events over time, i.e. a series of notes and rests.  ",
            +      "Phrases must be added to a p5.Part for playback, and each part can play multiple phrases at the same time. For example, one Phrase might be a kick drum, another could be a snare, and another could be the bassline.  ",
            +      "The first parameter is a name so that the phrase can be modified or deleted later. The callback is a a function that this phrase will call at every step—for example it might be called <code>playNote(value){}</code>. The array determines which value is passed into the callback at each step of the phrase. It can be numbers, an object with multiple numbers, or a zero (0) indicates a rest so the callback won't be called)."
            +    ],
            +    "params": {
            +      "name": "String: Name so that you can access the Phrase.",
            +      "callback": "Function: The name of a function that this phrase  will call. Typically it will play a sound,  and accept two parameters: a time at which  to play the sound (in seconds from now),  and a value from the sequence array. The  time should be passed into the play() or  start() method to ensure precision.",
            +      "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +    },
            +    "sequence": {
            +      "description": [
            +        "Array of values to pass into the callback at each step of the phrase. Depending on the callback function's requirements, these values may be numbers, strings, or an object with multiple parameters. Zero (0) indicates a rest."
            +      ]
            +    }
            +  },
            +  "p5.Part": {
            +    "description": [
            +      "A p5.Part plays back one or more p5.Phrases. Instantiate a part with steps and tatums. By default, each step represents a 1/16th note.  ",
            +      "See p5.Phrase for more about musical timing."
            +    ],
            +    "params": {
            +      "steps": "Number: (Optional) Steps in the part",
            +      "tatums": "Number: (Optional) Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)"
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo of this part, in Beats Per Minute."
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: (Optional) Seconds from now"
            +      }
            +    },
            +    "getBPM": {
            +      "description": [
            +        "Returns the tempo, in Beats Per Minute, of this part."
            +      ],
            +      "returns": "Number: "
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of this part. It will play through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of this part. It will begin looping through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Tell the part to stop looping."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the part. Playback will resume from the current step."
            +      ],
            +      "params": {
            +        "time": "Number: seconds from now"
            +      }
            +    },
            +    "addPhrase": {
            +      "description": [
            +        "Add a p5.Phrase to this Part."
            +      ],
            +      "params": {
            +        "phrase": "p5.Phrase: reference to a p5.Phrase"
            +      }
            +    },
            +    "removePhrase": {
            +      "description": [
            +        "Remove a phrase from this part, based on the name it was given when it was created."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "getPhrase": {
            +      "description": [
            +        "Get a phrase from this part, based on the name it was given when it was created. Now you can modify its array."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "replaceSequence": {
            +      "description": [
            +        "Find all sequences with the specified name, and replace their patterns with the specified array."
            +      ],
            +      "params": {
            +        "phraseName": "String",
            +        "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +      }
            +    },
            +    "onStep": {
            +      "description": [
            +        "Set the function that will be called at every step. This will clear the previous function."
            +      ],
            +      "params": {
            +        "callback": "Function: The name of the callback  you want to fire  on every beat/tatum."
            +      }
            +    }
            +  },
            +  "p5.Score": {
            +    "description": [
            +      "A Score consists of a series of Parts. The parts will be played back in order. For example, you could have an A part, a B part, and a C part, and play them back in this order <code>new p5.Score(a, a, b, a, c)</code>"
            +    ],
            +    "params": {
            +      "parts": "p5.Part: (Optional) One or multiple parts, to be played in sequence."
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of the score."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop playback of the score."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause playback of the score."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of the score."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Stop looping playback of the score. If it is currently playing, this will go into effect after the current round of playback completes."
            +      ]
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo for all parts in the score"
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.SoundLoop": {
            +    "description": [
            +      "SoundLoop"
            +    ],
            +    "params": {
            +      "callback": "Function: this function will be called on each iteration of theloop",
            +      "interval": "Number|String: (Optional) amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second."
            +    },
            +    "musicalTimeMode": {
            +      "description": [
            +        "musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention true if string, false if number"
            +      ]
            +    },
            +    "maxIterations": {
            +      "description": [
            +        "Set a limit to the number of loops to play. defaults to Infinity"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a starting time"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a stopping time"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a pausing time"
            +      }
            +    },
            +    "syncedStart": {
            +      "description": [
            +        "Synchronize loops. Use this method to start two more more loops in synchronization or to start a loop in synchronization with a loop that is already playing This method will schedule the implicit loop in sync with the explicit master loop i.e. loopToStart.syncedStart(loopToSyncWith)"
            +      ],
            +      "params": {
            +        "otherLoop": "Object: a p5.SoundLoop to sync with",
            +        "timeFromNow": "Number: (Optional) Start the loops in sync after timeFromNow seconds"
            +      }
            +    },
            +    "bpm": {
            +      "description": [
            +        "Getters and Setters, setting any paramter will result in a change in the clock's frequency, that will be reflected after the next callback beats per minute (defaults to 60)"
            +      ]
            +    },
            +    "timeSignature": {
            +      "description": [
            +        "number of quarter notes in a measure (defaults to 4)"
            +      ]
            +    },
            +    "interval": {
            +      "description": [
            +        "length of the loops interval"
            +      ]
            +    },
            +    "iterations": {
            +      "description": [
            +        "how many times the callback has been called so far"
            +      ]
            +    }
            +  },
            +  "p5.Compressor": {
            +    "description": [
            +      "Compressor is an audio effect class that performs dynamics compression on an audio input source. This is a very commonly used technique in music and sound production. Compression creates an overall louder, richer, and fuller sound by lowering the volume of louds and raising that of softs. Compression can be used to avoid clipping (sound distortion due to peaks in volume) and is especially useful when many sounds are played at once. Compression can be used on indivudal sound sources in addition to the master output. ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "compressor": {
            +      "description": [
            +        "The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"  target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node  </a>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Performs the same function as .connect, but also accepts optional parameters to set compressor's audioParams"
            +      ],
            +      "params": {
            +        "src": "Object: Sound source to be connected",
            +        "attack": "Number: (Optional) The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: (Optional) The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: (Optional) The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the paramters of a compressor."
            +      ],
            +      "params": {
            +        "attack": "Number: The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "attack": {
            +      "description": [
            +        "Get current attack or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "attack": "Number: (Optional) Attack is the amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "knee": {
            +      "description": [
            +        "Get current knee or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "ratio": {
            +      "description": [
            +        "Get current ratio or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "threshold": {
            +      "description": [
            +        "Get current threshold or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "release": {
            +      "description": [
            +        "Get current release or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "reduction": {
            +      "description": [
            +        "Return the current reduction value"
            +      ],
            +      "returns": "Number: Value of the amount of gain reduction that is applied to the signal"
            +    }
            +  },
            +  "p5.SoundRecorder": {
            +    "description": [
            +      "Record sounds for playback and/or to save as a .wav file. The p5.SoundRecorder records all sound output from your sketch, or can be assigned a specific source with setInput(). ",
            +      "The record() method accepts a p5.SoundFile as a parameter. When playback is stopped (either after the given amount of time, or with the stop() method), the p5.SoundRecorder will send its recording to that p5.SoundFile for playback."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a specific device to the p5.SoundRecorder. If no parameter is given, p5.SoundRecorer will record all audible p5.sound from your sketch."
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) p5.sound object or a web audio unit  that outputs sound"
            +      }
            +    },
            +    "record": {
            +      "description": [
            +        "Start recording. To access the recording, provide a p5.SoundFile as the first parameter. The p5.SoundRecorder will send its recording to that p5.SoundFile for playback once recording is complete. Optional parameters include duration (in seconds) of the recording, and a callback function that will be called once the complete recording has been transfered to the p5.SoundFile."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile",
            +        "duration": "Number: (Optional) Time (in seconds)",
            +        "callback": "Function: (Optional) The name of a function that will be  called once the recording completes"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the recording. Once the recording is stopped, the results will be sent to the p5.SoundFile that was given on .record(), and if a callback function was provided on record, that function will be called."
            +      ]
            +    }
            +  },
            +  "p5.PeakDetect": {
            +    "description": [
            +      "PeakDetect works in conjunction with p5.FFT to look for onsets in some or all of the frequency spectrum.  ",
            +      "To use p5.PeakDetect, call <code>update</code> in the draw loop and pass in a p5.FFT object.  ",
            +      "You can listen for a specific part of the frequency spectrum by setting the range between <code>freq1</code> and <code>freq2</code>.",
            +      "<code>threshold</code> is the threshold for detecting a peak, scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud as 1.0.",
            +      "The update method is meant to be run in the draw loop, and <b>frames</b> determines how many loops must pass before another peak can be detected. For example, if the frameRate() = 60, you could detect the beat of a 120 beat-per-minute song with this equation: <code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>   ",
            +      "Based on example contribtued by @b2renger, and a simple beat detection explanation by <a href=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\" target=\"_blank\">Felix Turner</a>. "
            +    ],
            +    "params": {
            +      "freq1": "Number: (Optional) lowFrequency - defaults to 20Hz",
            +      "freq2": "Number: (Optional) highFrequency - defaults to 20000 Hz",
            +      "threshold": "Number: (Optional) Threshold for detecting a beat between 0 and 1  scaled logarithmically where 0.1 is 1/2 the loudness  of 1.0. Defaults to 0.35.",
            +      "framesPerPeak": "Number: (Optional) Defaults to 20."
            +    },
            +    "isDetected": {
            +      "description": [
            +        "isDetected is set to true when a peak is detected."
            +      ]
            +    },
            +    "update": {
            +      "description": [
            +        "The update method is run in the draw loop. ",
            +        "Accepts an FFT object. You must call .analyze() on the FFT object prior to updating the peakDetect because it relies on a completed FFT analysis."
            +      ],
            +      "params": {
            +        "fftObject": "p5.FFT: A p5.FFT object"
            +      }
            +    },
            +    "onPeak": {
            +      "description": [
            +        "onPeak accepts two arguments: a function to call when a peak is detected. The value of the peak, between 0.0 and 1.0, is passed to the callback."
            +      ],
            +      "params": {
            +        "callback": "Function: Name of a function that will  be called when a peak is  detected.",
            +        "val": "Object: (Optional) Optional value to pass  into the function when  a peak is detected."
            +      }
            +    }
            +  },
            +  "p5.Gain": {
            +    "description": [
            +      "A gain node is usefull to set the relative volume of sound. It's typically used to build mixers."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a source to the gain node."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the gain node."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    }
            +  },
            +  "p5.Distortion": {
            +    "description": [
            +      "A Distortion effect created with a Waveshaper Node, with an approach adapted from <a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a> ",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +      "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +    },
            +    "WaveShaperNode": {
            +      "description": [
            +        "The p5.Distortion is built with a <a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\"> Web Audio WaveShaper Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process a sound source, optionally specify amount and oversample values."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the amount and oversample of the waveshaper distortion."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "getAmount": {
            +      "description": [
            +        "Return the distortion amount, typically between 0-1."
            +      ],
            +      "returns": "Number: Unbounded distortion amount.  Normal values range from 0-1."
            +    },
            +    "getOversample": {
            +      "description": [
            +        "Return the oversampling."
            +      ],
            +      "returns": "String: Oversample can either be 'none', '2x', or '4x'."
            +    }
            +  }
            +}
            diff --git a/dist/assets/reference/zh-Hans.json b/dist/assets/reference/zh-Hans.json
            new file mode 100644
            index 0000000000..6fde609040
            --- /dev/null
            +++ b/dist/assets/reference/zh-Hans.json
            @@ -0,0 +1,7564 @@
            +{
            +  "h1": "参考文献",
            +  "reference-search": "搜寻 API",
            +  "reference-description1": "找不到您要的条目吗?您或许要查看",
            +  "reference-description3": "You can download an offline version of the reference.",
            +  "reference-contribute2": "请让我们知道",
            +  "reference-error1": "发现错字或错误吗?",
            +  "reference-error3": "非常欢迎您",
            +  "reference-error5": "并开启一个 pull request。",
            +  "reference-example": "范例",
            +  "reference-description": "说明",
            +  "reference-extends": "继承",
            +  "reference-parameters": "参数",
            +  "reference-syntax": "语法",
            +  "reference-returns": "返回",
            +  "Environment": "环境",
            +  "Color": "颜色",
            +  "Color Conversion": "Color Conversion",
            +  "Creating & Reading": "创造及读取",
            +  "Setting": "设置",
            +  "Shape": "形状",
            +  "2D Primitives": "2D 形状",
            +  "Attributes": "属性",
            +  "Curves": "弧形",
            +  "Vertex": "顶点",
            +  "Constants": "常量",
            +  "Structure": "结构",
            +  "DOM": "DOM",
            +  "Rendering": "渲染",
            +  "Foundation": "Foundation",
            +  "Transform": "变形",
            +  "Data": "资料",
            +  "LocalStorage": "LocalStorage",
            +  "Dictionary": "字典",
            +  "Events": "事件",
            +  "Acceleration": "加速度",
            +  "Keyboard": "键盘",
            +  "Mouse": "滑鼠",
            +  "Touch": "触动",
            +  "Image": "图像",
            +  "Loading & Displaying": "加载和显示",
            +  "Pixels": "像素",
            +  "IO": "输入和输出",
            +  "Input": "输入",
            +  "Output": "输出",
            +  "Table": "表格",
            +  "Math": "数学",
            +  "Calculation": "计算",
            +  "Vector": "Vector",
            +  "Noise": "噪声",
            +  "Random": "Random",
            +  "Trigonometry": "三角学",
            +  "Typography": "字体",
            +  "Array Functions": "数组函数",
            +  "Conversion": "转换",
            +  "String Functions": "字符串函数",
            +  "Time & Date": "时间和日期",
            +  "3D Primitives": "3D 形状",
            +  "Lights, Camera": "灯光、相机",
            +  "Interaction": "Interaction",
            +  "Lights": "灯光",
            +  "3D Models": "3D 模型",
            +  "Material": "材料",
            +  "Camera": "相机",
            +  "p5": {
            +    "description": [
            +      "This is the p5 instance constructor.",
            +      "A p5 instance holds all the properties and methods related to a p5 sketch. It expects an incoming sketch closure and it can also take an optional node parameter for attaching the generated p5 canvas to a node. The sketch closure takes the newly created p5 instance as its sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>, <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.",
            +      "A p5 sketch can run in \"global\" or \"instance\" mode: \"global\" - all properties and methods are attached to the window \"instance\" - all properties and methods are bound to this p5 object"
            +    ],
            +    "returns": "P5: a p5 instance",
            +    "params": {
            +      "sketch": "Function: a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,  <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the  given p5 instance",
            +      "node": "HTMLElement: (Optional) element to attach canvas to"
            +    },
            +    "describe": {
            +      "description": [
            +        "Creates a screen reader accessible description for the canvas. The first parameter should be a string with a description of the canvas. The second parameter is optional. If specified, it determines how the description is displayed.",
            +        "<code class=\"language-javascript\">describe(text, LABEL)</code> displays the description to all users as a <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\"> tombstone or exhibit label/caption</a> in a <code class=\"language-javascript\"><div class=\"p5Label\"></div></code> adjacent to the canvas. You can style it as you wish in your CSS.",
            +        "<code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the description accessible to screen-reader users only, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a>. If a second parameter is not specified, by default, the description will only be available to screen-reader users."
            +      ],
            +      "params": {
            +        "text": "String: description of the canvas",
            +        "display": "Constant: (Optional) either LABEL or FALLBACK (Optional)"
            +      }
            +    },
            +    "describeElement": {
            +      "description": [
            +        "This function creates a screen-reader accessible description for elements —shapes or groups of shapes that create meaning together— in the canvas. The first paramater should be the name of the element. The second parameter should be a string with a description of the element. The third parameter is optional. If specified, it determines how the element description is displayed.",
            +        "<code class=\"language-javascript\">describeElement(name, text, LABEL)</code> displays the element description to all users as a <a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\"> tombstone or exhibit label/caption</a> in a <code class=\"language-javascript\"><div class=\"p5Label\"></div></code> adjacent to the canvas. You can style it as you wish in your CSS.",
            +        "<code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code> makes the element description accessible to screen-reader users only, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a>. If a second parameter is not specified, by default, the element description will only be available to screen-reader users."
            +      ],
            +      "params": {
            +        "name": "String: name of the element",
            +        "text": "String: description of the element",
            +        "display": "Constant: (Optional) either LABEL or FALLBACK (Optional)"
            +      }
            +    },
            +    "textOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">textOutput()</code> creates a screenreader accessible output that describes the shapes present on the canvas. The general description of the canvas includes canvas size, canvas color, and number of elements in the canvas (example: 'Your output is a, 400 by 400 pixels, lavender blue canvas containing the following 4 shapes:'). This description is followed by a list of shapes where the color, position, and area of each shape are described (example: \"orange ellipse at top left covering 1% of the canvas\"). Each element can be selected to get more details. A table of elements is also provided. In this table, shape, color, location, coordinates and area are described (example: \"orange ellipse location=top left area=2\").",
            +        "<code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">texOutput(FALLBACK)</code> make the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a> which is accessible to screen readers. <code class=\"language-javascript\">textOutput(LABEL)</code> creates an additional div with the output adjacent to the canvas, this is useful for non-screen reader users that might want to display the output outside of the canvas' sub DOM as they code. However, using LABEL will create unnecessary redundancy for screen reader users. We recommend using LABEL only as part of the development process of a sketch and removing it before publishing or sharing with screen reader users."
            +      ],
            +      "params": {
            +        "display": "Constant: (Optional) either FALLBACK or LABEL (Optional)"
            +      }
            +    },
            +    "gridOutput": {
            +      "description": [
            +        "<code class=\"language-javascript\">gridOutput()</code> lays out the content of the canvas in the form of a grid (html table) based on the spatial location of each shape. A brief description of the canvas is available before the table output. This description includes: color of the background, size of the canvas, number of objects, and object types (example: \"lavender blue canvas is 200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid describes the content spatially, each element is placed on a cell of the table depending on its position. Within each cell an element the color and type of shape of that element are available (example: \"orange ellipse\"). These descriptions can be selected individually to get more details. A list of elements where shape, color, location, and area are described (example: \"orange ellipse location=top left area=1%\") is also available.",
            +        "<code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code> make the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\"> a sub DOM inside the canvas element</a> which is accessible to screen readers. <code class=\"language-javascript\">gridOutput(LABEL)</code> creates an additional div with the output adjacent to the canvas, this is useful for non-screen reader users that might want to display the output outside of the canvas' sub DOM as they code. However, using LABEL will create unnecessary redundancy for screen reader users. We recommend using LABEL only as part of the development process of a sketch and removing it before publishing or sharing with screen reader users."
            +      ],
            +      "params": {
            +        "display": "Constant: (Optional) either FALLBACK or LABEL (Optional)"
            +      }
            +    },
            +    "alpha": {
            +      "description": [
            +        "从颜色或像素数组中提取透明度(alpha)值。"
            +      ],
            +      "returns": "数字:该透明度值",
            +      "params": {
            +        "color": "p5.Color | 数字数组 | 字符串:p5.Color 物件、颜色部件或 CSS 颜色值"
            +      }
            +    },
            +    "blue": {
            +      "description": [
            +        "从颜色或像素数组中提取蓝色彩值。"
            +      ],
            +      "returns": "数字:该蓝色彩值",
            +      "params": {
            +        "color": "p5.Color | 数字数组 | 字符串:p5.Color 物件、颜色部件或 CSS 颜色值"
            +      }
            +    },
            +    "brightness": {
            +      "description": [
            +        "从颜色或像素数组中提取 HSB 的亮度值。"
            +      ],
            +      "returns": "数字:该亮度值",
            +      "params": {
            +        "color": "p5.Color | 数字数组 | 字符串:p5.Color 物件、颜色部件或 CSS 颜色值"
            +      }
            +    },
            +    "color": {
            +      "description": [
            +        "创造颜色物件并将其存放在颜色变量内。依当时的颜色模式而定,参数可被解读成 RGB 或 HSB 值。默认模式为 RGB 值从 0 至 255,因此调用函数 color(255, 204, 0) 将返回亮黄色。<br><br>请注意如果 color() 值被提供一个参数,它将被解读成灰阶值;增加多一个参数,它将被用来定义透明度。当被提供三个参数时,它们将被解读成 RGB 或 HSB 值;增加第四个参数将定义透明度。<br><br>如果只提供单一字符串参数,RGB、RGBA 和 十六进制 CSS 颜色字符串都为受支持的模式。在这情况下,提供第二个参数以定义透明度值并不被支持,而需使用 RGBA 字符串。",
            +        "Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted as a grayscale value. Add a second value, and it will be used for alpha transparency. When three values are specified, they are interpreted as either RGB or HSB values. Adding a fourth value applies alpha transparency.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used."
            +      ],
            +      "returns": "p5.Color:返回的颜色",
            +      "params": {
            +        "gray": "数字:一个定义白与黑之间的数值",
            +        "alpha": "数字:透明度值,需在被定义的范围内(默认为 0 至 255)",
            +        "v1": "数字:红彩值或色调值,需在被定义的范围内",
            +        "v2": "数字:绿彩值或饱和度值,需在被定义的范围内",
            +        "v3": "数字:蓝彩值或亮度值,需在被定义的范围内",
            +        "value": "字符串:颜色字符串",
            +        "values": "数字[]:一个有红、绿、蓝及透明度值的数组",
            +        "color": "p5.Color:"
            +      }
            +    },
            +    "green": {
            +      "description": [
            +        "从颜色或像素数组中提取绿色彩值。"
            +      ],
            +      "returns": "数字:该绿色彩值",
            +      "params": {
            +        "color": "p5.Color | 数字数组 | 字符串:p5.Color 物件、颜色部件或 CSS 颜色值"
            +      }
            +    },
            +    "hue": {
            +      "description": [
            +        "从颜色或像素数组中提取色调值。<br><br>色调值可在 HSB 及 HSL 颜色中找到。此函数会返回标准化 HSB 值的色调值只要被提供的参数是 HSB 颜色物件(或如果被提供的参数是像素数组,颜色模式是 HSB),不然默认将会返回标准化 HSL 值的色调值。(两者的值只有在这两个不同的系统有不同的最高色调值时才会有差别)",
            +        "Hue exists in both HSB and HSL. This function will return the HSB-normalized hue when supplied with an HSB color object (or when supplied with a pixel array while the color mode is HSB), but will default to the HSL-normalized hue otherwise. (The values will only be different if the maximum hue setting for each system is different.)"
            +      ],
            +      "returns": "数字:该色调值",
            +      "params": {
            +        "color": "p5.Color | 数字数组 | 字符串:p5.Color 物件、颜色部件或 CSS 颜色值"
            +      }
            +    },
            +    "lerpColor": {
            +      "description": [
            +        "混合两个颜色以找到一个介于它们之间的颜色。<br><br>amt 参数代表两个值之间插入的量,0.0 代表第一个颜色、0.1 代表非常接近第一个颜色、0.5 代表两个颜色之间的一半等等。低于 0 的值将被当作 0 看待。这和 lerp() 的行为不一样不过这是因为在范围外的值可能产生奇怪和意料之外的颜色。",
            +        "The way that colors are interpolated depends on the current color mode."
            +      ],
            +      "returns": "p5.Color:插值颜色",
            +      "params": {
            +        "c1": "p5.Color:从这颜色开始插入",
            +        "c2": "p5.Color:在这颜色结束插入",
            +        "amt": "数字:一个介于 0 和 1 的数字"
            +      }
            +    },
            +    "lightness": {
            +      "description": [
            +        "从颜色或像素数组中提取 HSL 的光度值。"
            +      ],
            +      "returns": "数字:该光度值",
            +      "params": {
            +        "color": "p5.Color | 数字数组 | 字符串:p5.Color 物件、颜色部件或 CSS 颜色值"
            +      }
            +    },
            +    "red": {
            +      "description": [
            +        "从颜色或像素数组中提取红色彩值。"
            +      ],
            +      "returns": "数字:该红色彩值",
            +      "params": {
            +        "color": "p5.Color | 数字数组 | 字符串:p5.Color 物件、颜色部件或 CSS 颜色值"
            +      }
            +    },
            +    "saturation": {
            +      "description": [
            +        "从颜色或像素数组中提取饱和度值。<br><br>饱和度在 HSB 和 HSL 模式中的缩放比例不同。此函数将会返回 HSB 值的饱和度值只要被提供的参数是 HSB 颜色物件(或如果被提供的参数是像素数组,颜色模式是 HSB),不然默认将会返回 HSL 值的饱和度值。",
            +        "Saturation is scaled differently in HSB and HSL. This function will return the HSB saturation when supplied with an HSB color object (or when supplied with a pixel array while the color mode is HSB), but will default to the HSL saturation otherwise."
            +      ],
            +      "returns": "数字:该饱和度值",
            +      "params": {
            +        "color": "p5.Color | 数字数组 | 字符串:p5.Color 物件、颜色部件或 CSS 颜色值"
            +      }
            +    },
            +    "background": {
            +      "description": [
            +        "background() 函数设定 p5.js 画布的背景颜色。默认背景颜色为浅灰色。这函数通常用在 draw() 函数内以在各画面开始时清空画布,不过它也能在 setup() 内使用以定义第一个画面的背景颜色或当背景颜色只需要被定义一次时。<br><br>背景颜色可用 RGB、HSB 或 HSL 颜色定义,取决于当时的颜色模式(默认色彩空间是 RGB,而每个数值都介于 0 至 255 之间)。默认透明度值也介于 0 至 255 之间。<br><br>如果所提供的参数是单一字符串,RGB、RGBA 和十六进制 CSS 颜色字符串及所有命名颜色都可以使用。在这情况下,提供第二个参数以定义透明度值并不被支持,而需使用 RGBA 字符串。<br><br>p5.Color 物件也能被用来定义背景颜色。<br><br>p5.Image 也能被用来提供背景图像。",
            +        "The color is either specified in terms of the RGB, HSB, or HSL color depending on the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space is RGB, with each value in the range from 0 to 255). The alpha range by default is also 0 to 255.",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used.",
            +        "A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.",
            +        "A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image."
            +      ],
            +      "params": {
            +        "color": "p5.Color:任何使用 color() 函数创造的颜色",
            +        "colorstring": "字符串:颜色字符串,可接受的格式包括:整数 rgb() 或 rgba()、百分率 rgb() 或 rgba()、3 位十六进制、6 位十六进制",
            +        "a": "数字:透明度值,需在被定义的范围内(默认为 0 至 255)",
            +        "gray": "数字:一个定义白与黑之间的数值",
            +        "v1": "数字:红彩值或色调值(取决于当时的颜色模式)",
            +        "v2": "数字:绿彩值或饱和度值(取决于当时的颜色模式)",
            +        "v3": "数字:蓝彩值或亮度值(取决于当时的颜色模式)",
            +        "values": "数字[]:一个有红、绿、蓝及透明度值的数组",
            +        "image": "p5.Image:一个使用 loadImage() 或 createImage() 创造的图像,用以设定背景图像(必须和画布有相同的大小)"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "清除图形缓冲区内的像素。这函数只能用于使用 createCanvas() 函数创造的 p5.Canvas 物件,而不能用于主要的显示窗口。使用 createGraphics() 创造的图形缓冲并不像主要的图形缓冲,它们能是完全透明或半透明的。这函数将清空所有东西使每个像素都是 100% 透明。"
            +      ]
            +    },
            +    "colorMode": {
            +      "description": [
            +        "colorMode() 改变 p5.js 解读颜色资料的方式。默认情况下,fill()、stroke()、background() 及 color() 的参数都是介于 0 至 255 的 RGB 颜色值。这和设置 colorMode(RGB, 255) 的效果一样。设置 colorMode(HSB) 让您使用 HSB 模式,默认情况下,这代表 colorMode(HSB, 360, 100, 100, 1)。您也可以使用 HSL。",
            +        "Note: existing color objects remember the mode that they were created in, so you can change modes as you like without affecting their appearance."
            +      ],
            +      "params": {
            +        "mode": "常量: RGB、HSB 或 HSL,分别代表红绿蓝及色调/饱和度/亮度(或光度)",
            +        "max": "数字:所有数值的最大值",
            +        "max1": "数字:红色值或色调值的最大值,取决于当时的颜色模式",
            +        "max2": "数字:绿色值或饱和度值的最大值,取决于当时的颜色模式",
            +        "max3": "数字:蓝色值或亮度/光度值的最大值,取决于当时的颜色模式",
            +        "maxA": "数字:透明度值的最大值"
            +      }
            +    },
            +    "fill": {
            +      "description": [
            +        "设置形状的填充色。比如说,如果您调用 fill(204, 102, 0),所有接下来的形状都会被填上橙色。这颜色可用 RGB 或 HSB 颜色定义,取决于当时的颜色模式(默认色彩空间是 RGB,而每个数值都介于 0 至 255 之间)。默认透明度值也介于 0 至 255 之间。<br><br>如果所提供的参数是单一字符串,RGB、RGBA 和十六进制 CSS 颜色字符串及所有命名颜色都可以使用。在这情况下,提供第二个参数以定义透明度值并不被支持,而需使用 RGBA 字符串。<br><br>p5.Color 物件也能被用来定义填充颜色。",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used.",
            +        "A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color."
            +      ],
            +      "params": {
            +        "v1": "数字:红彩值或色调值,需在被定义的范围内",
            +        "v2": "数字:绿彩值或饱和度值,需在被定义的范围内",
            +        "v3": "数字:蓝彩值或亮度值,需在被定义的范围内",
            +        "alpha": "数字:",
            +        "value": "字符串:颜色字符串",
            +        "gray": "数字:灰阶值",
            +        "values": "数字[]:一个有红、绿、蓝及透明度值的数组",
            +        "color": "p5.Color:填充色"
            +      }
            +    },
            +    "noFill": {
            +      "description": [
            +        "禁用形状填充。如果 noStroke() 和 noFill() 都被调用的话,没有形状会被画在荧幕上。"
            +      ]
            +    },
            +    "noStroke": {
            +      "description": [
            +        "禁用形状外线。如果 noStroke() 和 noFill() 都被调用的话,没有形状会被画在荧幕上。"
            +      ]
            +    },
            +    "stroke": {
            +      "description": [
            +        "设置形状的外形线色。这颜色可用 RGB 或 HSB 颜色定义,取决于当时的颜色模式(默认色彩空间是 RGB,而每个数值都介于 0 至 255 之间)。默认透明度值也介于 0 至 255 之间。<br><br>如果所提供的参数是单一字符串,RGB、RGBA 和十六进制 CSS 颜色字符串及所有命名颜色都可以使用。在这情况下,提供第二个参数以定义透明度值并不被支持,而需使用 RGBA 字符串。<br><br>p5.Color 物件也能被用来定义外形线颜色。",
            +        "If a single string argument is provided, RGB, RGBA and Hex CSS color strings and all named color strings are supported. In this case, an alpha number value as a second argument is not supported, the RGBA form should be used.",
            +        "A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color."
            +      ],
            +      "params": {
            +        "v1": "数字:红彩值或色调值,需在被定义的范围内",
            +        "v2": "数字:绿彩值或饱和度值,需在被定义的范围内",
            +        "v3": "数字:蓝彩值或亮度值,需在被定义的范围内",
            +        "alpha": "数字:",
            +        "value": "字符串:颜色字符串",
            +        "gray": "数字:灰阶值",
            +        "values": "数字[]:一个有红、绿、蓝及透明度值的数组",
            +        "color": "p5.Color:外形线色"
            +      }
            +    },
            +    "erase": {
            +      "description": [
            +        "All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from the canvas.Erased areas will reveal the web page underneath the canvas.Erasing can be canceled with <a href=\"#/p5/noErase\">noErase()</a>.",
            +        "Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\"> background()</a> in between <a href=\"#/p5/erase\">erase()</a> and <a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual."
            +      ],
            +      "params": {
            +        "strengthFill": "Number: (Optional) A number (0-255) for the strength of erasing for a shape's fill.  This will default to 255 when no argument is given, which  is full strength.",
            +        "strengthStroke": "Number: (Optional) A number (0-255) for the strength of erasing for a shape's stroke.  This will default to 255 when no argument is given, which  is full strength."
            +      }
            +    },
            +    "noErase": {
            +      "description": [
            +        "Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>. The <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and <a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were prior to calling <a href=\"#/p5/erase\">erase()</a>."
            +      ]
            +    },
            +    "arc": {
            +      "description": [
            +        "在荧幕上画个弧形。如果函数调用只提供 x、y、w、h、start 及 stop 参数,弧形将会被画成开放的饼形段。如果提供 mode 参数,弧形可是开放式半圆形(OPEN)、封闭式半圆形(CHORD)或封闭式饼形段(PIE)。原点可使用 ellipseMode() 函数设定。",
            +        "The arc is always drawn clockwise from wherever start falls to wherever stop falls on the ellipse. Adding or subtracting TWO_PI to either angle does not change where they fall. If both start and stop fall at the same place, a full ellipse will be drawn. Be aware that the y-axis increases in the downward direction, therefore angles are measured clockwise from the positive x-direction (\"3 o'clock\")."
            +      ],
            +      "params": {
            +        "x": "数字:弧形的椭圆形的 x 坐标",
            +        "y": "数字:弧形的椭圆形的 y 坐标",
            +        "w": "数字:弧形的椭圆形的宽度",
            +        "h": "数字:弧形的椭圆形的高度",
            +        "start": "数字:弧形开始的角度,用弧度定义",
            +        "stop": "数字:弧形结束的角度,用弧度定义",
            +        "mode": "常数:可选参数用以定义弧形的画法,可用 CHORD、PIE 或 OPEN",
            +        "detail": "Number: (Optional) optional parameter for WebGL mode only. This is to  specify the number of vertices that makes up the  perimeter of the arc. Default value is 25."
            +      }
            +    },
            +    "ellipse": {
            +      "description": [
            +        "在荧幕上画个椭圆形。宽度和高度相同的椭圆形为正圆形。在默认上,前两个参数将定义位置而第三和第四个参数将定义形状的宽度和高度。如果高度参数没有被提供的话,宽度参数值将为用来定义高度和宽度。如果高度或宽度为负数,函数将会取绝对值。原点可使用 ellipseMode() 函数设定。",
            +        "An ellipse with equal width and height is a circle. The origin may be changed with the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function."
            +      ],
            +      "params": {
            +        "x": "数字:椭圆形的 x 坐标",
            +        "y": "数字:椭圆形的 y 坐标",
            +        "w": "数字:椭圆形的宽度",
            +        "h": "数字:椭圆形的高度",
            +        "detail": "整数:椭圆形的径向扇区数"
            +      }
            +    },
            +    "circle": {
            +      "description": [
            +        "Draws a circle to the screen. A circle is a simple closed shape.It is the set of all points in a plane that are at a given distance from a given point, the centre.This function is a special case of the ellipse() function, where the width and height of the ellipse are the same. Height and width of the ellipse correspond to the diameter of the circle. By default, the first two parameters set the location of the centre of the circle, the third sets the diameter of the circle."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the centre of the circle.",
            +        "y": "Number: y-coordinate of the centre of the circle.",
            +        "d": "Number: diameter of the circle."
            +      }
            +    },
            +    "line": {
            +      "description": [
            +        "在荧幕上画个直线(两点之间的直接路径)。有四个参数的 line() 函数将画个二维直线。如果要将直线上色,可使用 stroke() 函数。直线并不能有填充色,因此 fill() 函数将不会影响直线的颜色。二维直线在默认情况下有一像素的宽度,不过您可以使用 strokeWeight() 函数更改宽度。"
            +      ],
            +      "params": {
            +        "x1": "数字:第一个点的 x 坐标",
            +        "y1": "数字:第一个点的 y 坐标",
            +        "x2": "数字:第二个点的 y 坐标",
            +        "y2": "数字:第一个点的 z 坐标",
            +        "z1": "数字:第二个点的 x 坐标",
            +        "z2": "数字:第二个点的 z 坐标"
            +      }
            +    },
            +    "point": {
            +      "description": [
            +        "画一个点,一个在空间内一像素的坐标。第一个参数是点的横向值,第二个参数是点的垂直值。点的颜色是由当时的外线色决定。"
            +      ],
            +      "params": {
            +        "x": "数字:x 坐标",
            +        "y": "数字:y 坐标",
            +        "z": "数字:z 坐标(用于 WEBGL 模式",
            +        "coordinate_vector": "p5.Vector: the coordinate vector"
            +      }
            +    },
            +    "quad": {
            +      "description": [
            +        "画一个四角形。四角形或四边形是个有四个边的多边形。他和方形相似不过四个角并不需要是九十度。前两个参数 (x1、x2)定义第一个点而随后的配对参数应该以顺时或逆时针的方向定义。"
            +      ],
            +      "params": {
            +        "x1": "数字:第一个点的 x 坐标",
            +        "y1": "数字:第一个点的 y 坐标",
            +        "x2": "数字:第二个点的 y 坐标",
            +        "y2": "数字:第三个点的 x 坐标",
            +        "x3": "数字:第四个点的 x 坐标",
            +        "y3": "数字:第四个点的 y 坐标",
            +        "x4": "数字:",
            +        "y4": "数字:",
            +        "detailX": "Integer: (Optional) number of segments in the x-direction",
            +        "detailY": "Integer: (Optional) number of segments in the y-direction",
            +        "z1": "数字:第二个点的 x 坐标",
            +        "z2": "数字:第三个点的 y 坐标",
            +        "z3": "数字:",
            +        "z4": "数字:"
            +      }
            +    },
            +    "rect": {
            +      "description": [
            +        "在荧幕上画个方形。方形是每个角都为九十度的四边形。在默认上,前两个参数将定义位置而第三和第四个参数将定义形状的宽度和高度。这些参数被解读的方式可用 rectMode() 函数改变。<br><br>如果提供第五、六、七及八个参数,将定义左上角、右上角、右下角及左下角的拐角半径。没被定义的拐角半径参数将被定义为参数列内上一个定义的拐角半径值。",
            +        "The fifth, sixth, seventh and eighth parameters, if specified, determine corner radius for the top-left, top-right, lower-right and lower-left corners, respectively. An omitted corner radius parameter is set to the value of the previously specified radius value in the parameter list."
            +      ],
            +      "params": {
            +        "x": "数字:方形的 x 坐标",
            +        "y": "数字:方形的 y 坐标",
            +        "w": "数字:方形的宽度",
            +        "h": "数字:方形的高度",
            +        "tl": "数字:可选性左上角拐角半径值",
            +        "tr": "数字:可选性右上角拐角半径值",
            +        "br": "数字:可选性右下角拐角半径值",
            +        "bl": "数字:可选性左下角拐角半径值",
            +        "detailX": "整数:x 方向段数",
            +        "detailY": "整数:y 方向段数"
            +      }
            +    },
            +    "square": {
            +      "description": [
            +        "Draws a square to the screen. A square is a four-sided shape with every angle at ninety degrees, and equal side size. This function is a special case of the rect() function, where the width and height are the same, and the parameter is called \"s\" for side size. By default, the first two parameters set the location of the upper-left corner, the third sets the side size of the square. The way these parameters are interpreted, may be changed with the <a href=\"#/p5/rectMode\">rectMode()</a> function.",
            +        "The fourth, fifth, sixth and seventh parameters, if specified, determine corner radius for the top-left, top-right, lower-right and lower-left corners, respectively. An omitted corner radius parameter is set to the value of the previously specified radius value in the parameter list."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the square.",
            +        "y": "Number: y-coordinate of the square.",
            +        "s": "Number: side size of the square.",
            +        "tl": "Number: (Optional) optional radius of top-left corner.",
            +        "tr": "Number: (Optional) optional radius of top-right corner.",
            +        "br": "Number: (Optional) optional radius of bottom-right corner.",
            +        "bl": "Number: (Optional) optional radius of bottom-left corner."
            +      }
            +    },
            +    "triangle": {
            +      "description": [
            +        "三角形是个由连接三个点所形成的平面形。前两个参数定义第一个点,中间两个参数定义第二个点而最后两个参数定义第三个点。"
            +      ],
            +      "params": {
            +        "x1": "数字:第一个点的 x 坐标",
            +        "y1": "数字:第一个点的 y 坐标",
            +        "x2": "数字:第二个点的 x 坐标",
            +        "y2": "数字:第二个点的 y 坐标",
            +        "x3": "数字:第三个点的 x 坐标",
            +        "y3": "数字:第三个点的 y 坐标"
            +      }
            +    },
            +    "ellipseMode": {
            +      "description": [
            +        "更改 ellipse() 参数被解读的方式,用以更改椭圆形被画在画布上的位置。<br><br>默认模式为 ellipseMode(CENTER),ellipse() 前两个参数将被解读成椭圆形的中心点,而第三和第四个参数为宽度和高度。<br><br>ellipseMode(RADIUS) 将 ellipse() 的前两个参数解读成形状的中心点,但是第三和第四个参数被用于定义形状的半径宽度和半径高度<br><br>ellipseMode(CORNER) 将 ellipse() 的前两个参数解读成形状左上角的位置,而第三和第四个参数为宽度和高度<br><br>ellipseMode(CORNERS) 将 ellipse() 的前两个参数解读成形状其中一个角落的位置,而第三和第四个参数则被解读成对面角落的位置。<br><br>参数必须全是大写因为 Javascript 是个区分大小写的编程语言。",
            +        "The default mode is CENTER, in which the first two parameters are interpreted as the shape's center point's x and y coordinates respectively, while the third and fourth parameters are its width and height.",
            +        "ellipseMode(RADIUS) also uses the first two parameters as the shape's center point's x and y coordinates, but uses the third and fourth parameters to specify half of the shapes's width and height.",
            +        "ellipseMode(CORNER) interprets the first two parameters as the upper-left corner of the shape, while the third and fourth parameters are its width and height.",
            +        "ellipseMode(CORNERS) interprets the first two parameters as the location of one corner of the ellipse's bounding box, and the third and fourth parameters as the location of the opposite corner.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "mode": "常量:CENTER、RADIUS、CORNER 或 CORNERS"
            +      }
            +    },
            +    "noSmooth": {
            +      "description": [
            +        "所有形状的边缘都为锯齿状。注意 smooth() 为默认模式所以您必须调用 noSmooth() 以禁用平滑形状、图像及字体。"
            +      ]
            +    },
            +    "rectMode": {
            +      "description": [
            +        "更改 rect() 参数被解读的方式,用以更改方形被画在画布上的位置。<br><br>默认模式为 rectMode(CORNER), rect() 前两个参数将被解读成形状的左上角的位置,而第三和第四个参数为宽度和高度。<br><br>rectMode(CORNERS) 将 rect() 的前两个参数解读成形状其中一个角落的位置,而第三和第四个参数则被解读成对面角落的位置。<br><br>rectMode(CENTER) 将 rect() 的前两个参数解读成形状的中心点,而第三和第四个参数为宽度和高度。<br><br>rectMode(RADIUS) 也将的前两个参数解读成形状的中心点,但第三和第四个参数被用来定义形状一半的宽度和一半的高度。<br><br>参数必须全是大写因为 Javascript 是个区分大小写的编程语言。",
            +        "The default mode is CORNER, which interprets the first two parameters as the upper-left corner of the shape, while the third and fourth parameters are its width and height.",
            +        "rectMode(CORNERS) interprets the first two parameters as the location of one of the corners, and the third and fourth parameters as the location of the diagonally opposite corner. Note, the rectangle is drawn between the coordinates, so it is not neccesary that the first corner be the upper left corner.",
            +        "rectMode(CENTER) interprets the first two parameters as the shape's center point, while the third and fourth parameters are its width and height.",
            +        "rectMode(RADIUS) also uses the first two parameters as the shape's center point, but uses the third and fourth parameters to specify half of the shape's width and height respectively.",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "mode": "常量:CORNER、CORNERS、CENTER 或 RADIUS"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "所有形状的边缘都为非锯齿(平滑)状。smooth() 也将提高调整过大小的图像的素质。注意 smooth() 为默认模式;noSmooth() 也能用来禁用平滑形状、图像及字体。"
            +      ]
            +    },
            +    "strokeCap": {
            +      "description": [
            +        "定义线条顶点的风格。顶点风格可以是方形、扩展式或圆形,它们个别参数为:SQUARE、PROJECT 及 ROUND。默认模式为 ROUND。",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "cap": "常量:SQUARE、PROJECT 或 ROUND"
            +      }
            +    },
            +    "strokeJoin": {
            +      "description": [
            +        "定义线条连接的风格。这些链接可以是尖角、斜角或圆角,它们个别参数为:MITER、BEVEL 及 ROUND。默认模式为 MITER。",
            +        "The parameter to this method must be written in ALL CAPS because they are predefined as constants in ALL CAPS and Javascript is a case-sensitive language."
            +      ],
            +      "params": {
            +        "join": "常量:MITER、BEVEL 或 ROUND"
            +      }
            +    },
            +    "strokeWeight": {
            +      "description": [
            +        "定义线条、点及形状边线的宽度(粗度)。所有宽度单位都是像素。"
            +      ],
            +      "params": {
            +        "weight": "数字:线条的粗度(像素单位)"
            +      }
            +    },
            +    "bezier": {
            +      "description": [
            +        "在荧幕上画个三次贝塞尔曲线。这些曲线是由一系列锚点和控制点所定义的。前两个参数定义第一个锚点而最后两个参数定义另一个锚点,这也是曲线的第一和最后一个点。中间的参数是用来定义控制点的位置并将决定曲线的形状。一般来说,控制点会将曲线“拉”向它们的方向。",
            +        "Bezier curves were developed by French automotive engineer Pierre Bezier, and are commonly used in computer graphics to define gently sloping curves. See also <a href=\"#/p5/curve\">curve()</a>."
            +      ],
            +      "params": {
            +        "x1": "数字:第一个锚点的 x 坐标",
            +        "y1": "数字:第一个锚点的 y 坐标",
            +        "x2": "数字:第一个控制点的 y 坐标",
            +        "y2": "数字:第二个控制点的 x 坐标",
            +        "x3": "数字:第二个锚点的 x 坐标",
            +        "y3": "数字:第二个锚点的 y 坐标",
            +        "x4": "数字:第一个控制点的 z 坐标",
            +        "y4": "数字:第二个锚点的 z 坐标",
            +        "z1": "数字:第一个控制点的 x 坐标",
            +        "z2": "数字:第二个控制点的 y 坐标",
            +        "z3": "数字:第一个锚点的 z 坐标",
            +        "z4": "数字:第二个控制点的 z 坐标"
            +      }
            +    },
            +    "bezierDetail": {
            +      "description": [
            +        "定义贝塞尔曲线的解析度<br><br>默认值为 20。<br><br>这函数只有在 WEBGL 模式下有效果因为默认画布渲染模式并不会使用这设定。",
            +        "Note, This function is only useful when using the WEBGL renderer as the default canvas renderer does not use this information."
            +      ],
            +      "params": {
            +        "detail": "数字:曲线的解析度"
            +      }
            +    },
            +    "bezierPoint": {
            +      "description": [
            +        "计算在 a、b、c、d 点定义的贝塞尔曲线上 t 位置的坐标。a 和 d 参数分别为曲线上第一和最后一个点,而 b 和 c 为控制点。最后一个 t 参数可在 0 和 1 的范围内。这函数可以先调用 x 坐标然后在调用 y 坐标已找到曲线上 t 位置的点坐标。"
            +      ],
            +      "returns": "数字:贝塞尔曲线上 t 位置的值",
            +      "params": {
            +        "a": "数字:曲线上第一个点的坐标",
            +        "b": "数字:第一个控制点的坐标",
            +        "c": "数字:第二个控制点的坐标",
            +        "d": "数字:曲线上第二个点的坐标",
            +        "t": "数字:介于 0 和 1 之间的值"
            +      }
            +    },
            +    "bezierTangent": {
            +      "description": [
            +        "计算在 a、b、c、d 点定义的贝塞尔曲线上 t 位置的切线值。a 和 d 参数分别为曲线上第一和最后一个点,而 b 和 c 为控制点。最后一个 t 参数可在 0 和 1 的范围内。"
            +      ],
            +      "returns": "数字:贝塞尔曲线上 t 位置的切线值",
            +      "params": {
            +        "a": "数字:曲线上第一个点的坐标",
            +        "b": "数字:第一个控制点的坐标",
            +        "c": "数字:第二个控制点的坐标",
            +        "d": "数字:曲线上第二个点的坐标",
            +        "t": "数字:介于 0 和 1 之间的值"
            +      }
            +    },
            +    "curve": {
            +      "description": [
            +        "在荧幕上的两点之间画一个曲线,两点由中间四个参数定义。前两个参数为控制点,可以当作曲线是从这个点开始的虽然它并不会被画出来。最后两个参数同样也是用来定义另外一个控制点。<br><br>更长的曲线能使用一系列 curve() 函数创造或使用 curveVertex()。另外一个叫 curveTightness() 的函数提供曲线视觉质量的控制。curve() 函数使用的是 Catmull-Rom 样条函数。"
            +      ],
            +      "params": {
            +        "x1": "数字:起点控制点的 x 坐标",
            +        "y1": "数字:起点控制点的 y 坐标",
            +        "x2": "数字:第一个点的 y 坐标",
            +        "y2": "数字:第二个点的 x 坐标",
            +        "x3": "数字:终点控制点的 x 坐标",
            +        "y3": "数字:终点控制点的 y 坐标",
            +        "x4": "数字:第一个点的 z 坐标",
            +        "y4": "数字:第二个点的 z 坐标",
            +        "z1": "数字:第一个点的 x 坐标",
            +        "z2": "数字:第二个点的 y 坐标",
            +        "z3": "数字:起点控制点的 z 坐标",
            +        "z4": "数字:终点控制点的 z 坐标"
            +      }
            +    },
            +    "curveDetail": {
            +      "description": [
            +        "定义曲线的解析度<br><br>默认值为 20。<br><br>这函数只有在 WEBGL 模式下有效果因为默认画布渲染模式并不会使用这设定。",
            +        "This function is only useful when using the WEBGL renderer as the default canvas renderer does not use this information."
            +      ],
            +      "params": {
            +        "resolution": "数字:曲线的解析度"
            +      }
            +    },
            +    "curveTightness": {
            +      "description": [
            +        "更改由 curve() 及 curveVertex() 所创造的曲线的质量。所提供的参数将决定曲线如何切合顶点。0.0 是紧实度的默认值(这值表示曲线为 Catmull-Rom 样条)而 1.0 将使用直线连接所有点。在 -5.0 及 5.0 之间的值会是曲线变形不过他们仍然能被识别而当值越来越大时,曲线也会跟着变形。"
            +      ],
            +      "params": {
            +        "amount": "数字:从原顶点的变形量"
            +      }
            +    },
            +    "curvePoint": {
            +      "description": [
            +        "计算在 a、b、c、d 点定义的曲线上 t 位置的坐标。a 和 d 参数分别为曲线上第一和最后一个点,而 b 和 c 为控制点。最后一个 t 参数可在 0 和 1 的范围内。这函数可以先调用 x 坐标然后在调用 y 坐标已找到曲线上 t 位置的点坐标。"
            +      ],
            +      "returns": "数字:贝塞尔曲线上 t 位置的值",
            +      "params": {
            +        "a": "数字:曲线上第一个点的坐标",
            +        "b": "数字:第一个控制点的坐标",
            +        "c": "数字:第二个控制点的坐标",
            +        "d": "数字:曲线上第二个点的坐标",
            +        "t": "数字:介于 0 和 1 之间的值"
            +      }
            +    },
            +    "curveTangent": {
            +      "description": [
            +        "计算在 a、b、c、d 点定义的曲线上 t 位置的切线值。a 和 d 参数分别为曲线上第一和最后一个点,而 b 和 c 为控制点。最后一个 t 参数可在 0 和 1 的范围内。"
            +      ],
            +      "returns": "数字:贝塞尔曲线上 t 位置的切线值",
            +      "params": {
            +        "a": "数字:曲线上第一个点的坐标",
            +        "b": "数字:第一个控制点的坐标",
            +        "c": "数字:第二个控制点的坐标",
            +        "d": "数字:曲线上第二个点的坐标",
            +        "t": "数字:介于 0 和 1 之间的值"
            +      }
            +    },
            +    "beginContour": {
            +      "description": [
            +        "使用 beginContour() 及 endContour() 函数以在其他形状内创造剪影形状,比如说 “O” 字母内的空间。beginContour() 将开始记录形状的顶点而 endContour() 则停止记录。定义剪影形状的顶点定义的方向(顺时或逆时针)必须和包含它的形状不同。如果外形的顶点是顺时针方向定义的,那么它里面的形状的顶点需是逆时针方向定义。<br><br>这些函数只能在一对 beginShape()/endShape() 函数之间使用而变形函数如 translate()、rotate() 及 scale() 在一对 beginContour()/endContour() 内并不会有任何效果。其他形状如 ellipse() 或 rect() 也不能在里面使用。",
            +        "These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within."
            +      ]
            +    },
            +    "beginShape": {
            +      "description": [
            +        "使用 beginShape() 及 endShape() 函数可让您创造更复杂的形状。beginShape() 将开始记录形状的顶点而 endShape() 则停止记录。所提供的参数将决定由所提供的顶点该画出怎样的形状。如果模式没有被提供,所定义的形状可以是任何不规则的多边形。<br><br>可提供给 beginShape() 的参数包括 POINTS、LINES、TRIANGLES、TRIANGLE_FAN、TRIANGLE_STRIP、QUADS 及 QUAD_STRIP。在调用 beginShape() 函数之后,一系列 vertex() 函数必须接着调用。调用 endShape() 以停止绘制形状。每个形状都将会有由当时外线色所定义的外线色及当时的填充色。<br><br>变形函数如 translate()、rotate() 及 scale() 在 beginShape() 内不会有任何效果。其他形状如 ellipse() 或 rect() 也不能在beginShape()里面使用。",
            +        "The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:",
            +        "POINTS Draw a series of points",
            +        "LINES Draw a series of unconnected line segments (individual lines)",
            +        "TRIANGLES Draw a series of separate triangles",
            +        "TRIANGLE_FAN Draw a series of connected triangles sharing the first vertex in a fan-like fashion",
            +        "TRIANGLE_STRIP Draw a series of connected triangles in strip fashion",
            +        "QUADS Draw a series of seperate quad",
            +        "QUAD_STRIP Draw quad strip using adjacent edges to form the next quad",
            +        "TESS (WebGl only) Handle irregular polygon for filling curve by explicit tessellation",
            +        "After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop drawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the current stroke color and filled with the fill color.",
            +        "Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "kind": "常量:POINTS、LINES、TRIANGLES、TRIANGLE_FAN、TRIANGLE_STRIP、QUADS 或 QUAD_STRIP"
            +      }
            +    },
            +    "bezierVertex": {
            +      "description": [
            +        "定义贝塞尔曲线的顶点坐标。每次调用 bezierVertex() 将定义贝塞尔曲线的两个控制点和一个锚点,以在线或形状上增加一个新部分。<br><br>在 beginShape() 内第一次调用 bezierVertex() 之前必须先调用一次 vertex() 以定义第一个锚点。这函数只能在 beginShape() 和 endShape() 之间使用并且也只能在 beginShape() 没有任何 MODE(模式)参数的情况下使用。",
            +        "The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there is no MODE or POINTS parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "x2": "数字:第一个控制点的 x 坐标",
            +        "y2": "数字:第一个控制点的 y 坐标",
            +        "x3": "数字:第二个控制点的 x 坐标",
            +        "y3": "数字:第二个控制点的 y 坐标",
            +        "x4": "数字:第一个锚点的 x 坐标",
            +        "y4": "数字:第二个锚点的 x 坐标",
            +        "z2": "Number: z-coordinate for the first control point (for WebGL mode)",
            +        "z3": "Number: z-coordinate for the second control point (for WebGL mode)",
            +        "z4": "Number: z-coordinate for the anchor point (for WebGL mode)"
            +      }
            +    },
            +    "curveVertex": {
            +      "description": [
            +        "定义曲线顶点的坐标。这函数只能在 beginShape() 和 endShape() 之间使用并且也只能在 beginShape() 没有任何 MODE(模式)参数的情况下使用。<br><br>在一系列 curveVertex() 线条中第一个和最后一个点将被用来引导曲线的起点和终点。至少必须提供四个点以画一个介于第二和第三个点的小曲线。增加第五个点将会在第二、第三及第四个点之间画个曲线。curveVertex() 函数使用的是 Catmull-Rom 样条函数。",
            +        "The first and last points in a series of curveVertex() lines will be used to guide the beginning and end of a the curve. A minimum of four points is required to draw a tiny curve between the second and third points. Adding a fifth point with curveVertex() will draw the curve between the second, third, and fourth points. The curveVertex() function is an implementation of Catmull-Rom splines."
            +      ],
            +      "params": {
            +        "x": "数字:顶点的 x 坐标",
            +        "y": "数字:顶点的 y 坐标",
            +        "z": "Number: (Optional) z-coordinate of the vertex (for WebGL mode)"
            +      }
            +    },
            +    "endContour": {
            +      "description": [
            +        "使用 beginContour() 及 endContour() 函数以在其他形状内创造剪影形状,比如说 “O” 字母内的空间。beginContour() 将开始记录形状的顶点而 endContour() 则停止记录。定义剪影形状的顶点定义的方向(顺时或逆时针)必须和包含它的形状不同。如果外形的顶点是顺时针方向定义的,那么它里面的形状的顶点需是逆时针方向定义。<br><br>这些函数只能在一对 beginShape()/endShape() 函数之间使用而变形函数如 translate()、rotate() 及 scale() 在一对 beginContour()/endContour() 内并不会有任何效果。其他形状如 ellipse() 或 rect() 也不能在里面使用。",
            +        "These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work within a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use other shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within."
            +      ]
            +    },
            +    "endShape": {
            +      "description": [
            +        "endShape() 函数和 beginShape() 是一对的而且它只能在 beginShape() 后使用。当 endshape() 被调用时,自上一次 beginShape() 调用后的所有被定义的图像资料将被写进图像缓冲区。定义常量 CLOSE 给 MODE 参数将会关闭该形状(连接起点和终点)。"
            +      ],
            +      "params": {
            +        "mode": "常量:使用 CLOSE 以关闭形状"
            +      }
            +    },
            +    "quadraticVertex": {
            +      "description": [
            +        "定义二次贝塞尔曲线顶点的坐标。每次调用 quadraticVertex() 将定义贝塞尔曲线的一个控制点和一个锚点,以在线或形状上增加一个新部分。在 beginShape() 内第一次调用 quadraticVertex() 之前必须先调用一次 vertex() 以定义第一个锚点。这函数只能在 beginShape() 和 endShape() 之间使用并且也只能在 beginShape() 没有任何 MODE(模式)参数的情况下使用。",
            +        "This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there is no MODE or POINTS parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>."
            +      ],
            +      "params": {
            +        "cx": "数字:控制点的 x 坐标",
            +        "cy": "数字:控制点的 y 坐标",
            +        "x3": "数字:锚点的 x 坐标",
            +        "y3": "数字:锚点的 y 坐标",
            +        "cz": "Number: z-coordinate for the control point (for WebGL mode)",
            +        "z3": "Number: z-coordinate for the anchor point (for WebGL mode)"
            +      }
            +    },
            +    "vertex": {
            +      "description": [
            +        "所有形状都是由连接一系列顶点形成的。vertex() 可用于定义点、线、三角形、四角形及多边形的顶点坐标。它只能在 beginShape() 和 endShape() 函数之间使用。"
            +      ],
            +      "params": {
            +        "x": "数字:顶点的 x 坐标",
            +        "y": "数字:顶点的 y 坐标",
            +        "z": "数字:顶点的 z 坐标",
            +        "u": "数字:顶点的纹理 u 坐标",
            +        "v": "数字:顶点的纹理 v 坐标"
            +      }
            +    },
            +    "normal": {
            +      "description": [
            +        "Sets the 3d vertex normal to use for subsequent vertices drawn with <a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally nearly perpendicular to a shape's surface which controls how much light will be reflected from that part of the surface."
            +      ],
            +      "params": {
            +        "vector": "Vector: A p5.Vector representing the vertex normal.",
            +        "x": "Number: The x component of the vertex normal.",
            +        "y": "Number: The y component of the vertex normal.",
            +        "z": "Number: The z component of the vertex normal."
            +      }
            +    },
            +    "VERSION": {
            +      "description": [
            +        "Version of this p5.js."
            +      ]
            +    },
            +    "P2D": {
            +      "description": [
            +        "The default, two-dimensional renderer."
            +      ]
            +    },
            +    "WEBGL": {
            +      "description": [
            +        "One of the two render modes in p5.js: P2D (default renderer) and WEBGL Enables 3D render by introducing the third dimension: Z"
            +      ]
            +    },
            +    "ARROW": {},
            +    "CROSS": {},
            +    "HAND": {},
            +    "MOVE": {},
            +    "TEXT": {},
            +    "WAIT": {},
            +    "HALF_PI": {
            +      "description": [
            +        "HALF_PI 是个值为 1.57079632679489661923 的数学常量。它是圆形周长与直径的比例的一半。它能有效的与三角函数如 sin() 及 cos() 一起使用。"
            +      ]
            +    },
            +    "PI": {
            +      "description": [
            +        "PI 是个值为 3.14159265358979323846 的数学常量。它是圆形周长与直径的比例。它能有效的与三角函数如 sin() 及 cos() 一起使用。"
            +      ]
            +    },
            +    "QUARTER_PI": {
            +      "description": [
            +        "QUARTER_PI 是个值为 0.7853982 的数学常量。它是圆形周长与直径的比例的四分之一。它能有效的与三角函数如 sin() 及 cos() 一起使用。"
            +      ]
            +    },
            +    "TAU": {
            +      "description": [
            +        "TAU 是 TWO_PI 的别名,是个值为 6.28318530717958647693 的数学常量。它是圆形周长与直径的比例的两倍。它能有效的与三角函数如 sin() 及 cos() 一起使用。"
            +      ]
            +    },
            +    "TWO_PI": {
            +      "description": [
            +        "TWO_PI 是个值为 6.28318530717958647693 的数学常量。它是圆形周长与直径的比例的两倍。它能有效的与三角函数如 sin() 及 cos() 一起使用。"
            +      ]
            +    },
            +    "DEGREES": {
            +      "description": [
            +        "与 angleMode() 函数一起使用的常量,用于设定 p5.js 如何解读及计算角度(可以是 DEGREES 或 RADIANS)。"
            +      ]
            +    },
            +    "RADIANS": {
            +      "description": [
            +        "与 angleMode() 函数一起使用的常量,用于设定 p5.js 如何解读及计算角度(可以是 DEGREES 或 RADIANS)。"
            +      ]
            +    },
            +    "CORNER": {},
            +    "CORNERS": {},
            +    "RADIUS": {},
            +    "RIGHT": {},
            +    "LEFT": {},
            +    "CENTER": {},
            +    "TOP": {},
            +    "BOTTOM": {},
            +    "BASELINE": {},
            +    "POINTS": {},
            +    "LINES": {},
            +    "LINE_STRIP": {},
            +    "LINE_LOOP": {},
            +    "TRIANGLES": {},
            +    "TRIANGLE_FAN": {},
            +    "TRIANGLE_STRIP": {},
            +    "QUADS": {},
            +    "QUAD_STRIP": {},
            +    "TESS": {},
            +    "CLOSE": {},
            +    "OPEN": {},
            +    "CHORD": {},
            +    "PIE": {},
            +    "PROJECT": {},
            +    "SQUARE": {},
            +    "ROUND": {},
            +    "BEVEL": {},
            +    "MITER": {},
            +    "RGB": {},
            +    "HSB": {
            +      "description": [
            +        "HSB (hue, saturation, brightness) is a type of color model. You can learn more about it at <a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>."
            +      ]
            +    },
            +    "HSL": {},
            +    "AUTO": {
            +      "description": [
            +        "AUTO allows us to automatically set the width or height of an element (but not both), based on the current height and width of the element. Only one parameter can be passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time."
            +      ]
            +    },
            +    "ALT": {},
            +    "BACKSPACE": {},
            +    "CONTROL": {},
            +    "DELETE": {},
            +    "DOWN_ARROW": {},
            +    "ENTER": {},
            +    "ESCAPE": {},
            +    "LEFT_ARROW": {},
            +    "OPTION": {},
            +    "RETURN": {},
            +    "RIGHT_ARROW": {},
            +    "SHIFT": {},
            +    "TAB": {},
            +    "UP_ARROW": {},
            +    "BLEND": {},
            +    "REMOVE": {},
            +    "ADD": {},
            +    "DARKEST": {},
            +    "LIGHTEST": {},
            +    "DIFFERENCE": {},
            +    "SUBTRACT": {},
            +    "EXCLUSION": {},
            +    "MULTIPLY": {},
            +    "SCREEN": {},
            +    "REPLACE": {},
            +    "OVERLAY": {},
            +    "HARD_LIGHT": {},
            +    "SOFT_LIGHT": {},
            +    "DODGE": {},
            +    "BURN": {},
            +    "THRESHOLD": {},
            +    "GRAY": {},
            +    "OPAQUE": {},
            +    "INVERT": {},
            +    "POSTERIZE": {},
            +    "DILATE": {},
            +    "ERODE": {},
            +    "BLUR": {},
            +    "NORMAL": {},
            +    "ITALIC": {},
            +    "BOLD": {},
            +    "BOLDITALIC": {},
            +    "CHAR": {},
            +    "WORD": {},
            +    "LINEAR": {},
            +    "QUADRATIC": {},
            +    "BEZIER": {},
            +    "CURVE": {},
            +    "STROKE": {},
            +    "FILL": {},
            +    "TEXTURE": {},
            +    "IMMEDIATE": {},
            +    "IMAGE": {},
            +    "NEAREST": {},
            +    "REPEAT": {},
            +    "CLAMP": {},
            +    "MIRROR": {},
            +    "LANDSCAPE": {},
            +    "PORTRAIT": {},
            +    "GRID": {},
            +    "AXES": {},
            +    "LABEL": {},
            +    "FALLBACK": {},
            +    "print": {
            +      "description": [
            +        "print() 函数将写入浏览器的控制台区。这函数适用于查看程式生成的资料。这函数每一次被调用将创造新的一行字串。个别元素可使用引号(\"\")分隔并使用加号(+)连接在一起。",
            +        "Note that calling print() without any arguments invokes the window.print() function which opens the browser's print dialog. To print a blank line to console you can write print('\\n')."
            +      ],
            +      "params": {
            +        "contents": "任何:任何要写进控制台的数字、字符串、物件、布尔值或数组的组合"
            +      }
            +    },
            +    "frameCount": {
            +      "description": [
            +        "系统变量 frameCount 存着自程序开始已被展示的影格数量。在 setup() 这值为 0,在第一次执行 draw() 后为 1 等等。"
            +      ]
            +    },
            +    "deltaTime": {
            +      "description": [
            +        "The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time difference between the beginning of the previous frame and the beginning of the current frame in milliseconds.",
            +        "This variable is useful for creating time sensitive animation or physics calculation that should stay constant regardless of frame rate."
            +      ]
            +    },
            +    "focused": {
            +      "description": [
            +        "确定 p5.js 程式正在运行的窗口是否获得“焦点”,这表示绘图可接受滑鼠或键盘输入。如果窗口获得焦点,次变量为 “true” 否则为 “false”。"
            +      ]
            +    },
            +    "cursor": {
            +      "description": [
            +        "设置鼠标成预定的符号或一个图像,或者如果鼠标被隐藏显示鼠标。如果你想要设置一个图像为鼠标,建议的图像大小为 16x16 或 32x32 像素。 It is not possible to load an image as the cursor if you are exporting your program for the Web, and not all MODES work with all browsers. 参数 x 及 y 必须低于图像的大小。"
            +      ],
            +      "params": {
            +        "type": "字符串|常量:ARROW、CROSS、HAND、MOVE、TEXT 或图像的路径",
            +        "x": "数字:鼠标的横向活跃点",
            +        "y": "数字:鼠标的直向活跃点"
            +      }
            +    },
            +    "frameRate": {
            +      "description": [
            +        "定义每一秒应该显示的影格数。比如说,调用 frameRate(30) 将使绘图每秒刷新 30 次。如果处理器没法跟上所定义的速率,该帧率将不会被达到。建议在 setup() 内设置帧率。默认的帧率值为每秒 60 影格。这和调用 setFrameRate(val) 的效果一样。<br><br>调用 frameRate() 但不给予任何参数将会返回当时的帧率。draw() 函数必须至少执行一次它才会返回帧率。这和调用 getFrameRate() 的效果一样。<br><br>调用 frameRate() 并给予任何不是数字或正数的参数也将会返回当时的帧率。",
            +        "Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate. The draw function must run at least once before it will return a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.",
            +        "Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not of the type numbers or are non positive also returns current framerate."
            +      ],
            +      "params": {
            +        "fps": "数字:每一秒该显示的影格数"
            +      }
            +    },
            +    "noCursor": {
            +      "description": [
            +        "隐藏鼠标。"
            +      ]
            +    },
            +    "displayWidth": {
            +      "description": [
            +        "储存整个荧幕宽度的系统变量。这可用来在任何大小的荧幕制作任何大小的全屏程序。"
            +      ]
            +    },
            +    "displayHeight": {
            +      "description": [
            +        "储存整个荧幕高度的系统变量。这可用来在任何大小的荧幕制作任何大小的全屏程序。"
            +      ]
            +    },
            +    "windowWidth": {
            +      "description": [
            +        "储存窗口内部宽度的系统变量, 此函数映射 window.innerWidth。"
            +      ]
            +    },
            +    "windowHeight": {
            +      "description": [
            +        "储存窗口内部高度的系统变量, 此函数映射 window.innerHeight。"
            +      ]
            +    },
            +    "windowResized": {
            +      "description": [
            +        "windowResized() 函数将在每次浏览器窗口缩放时被调用。这是个适合缩放画布及或任何其他调整以符合新的窗口大小的地方。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional Event callback argument."
            +      }
            +    },
            +    "width": {
            +      "description": [
            +        "储存画布宽度的系统变量。这值是由 createCanvas() 函数的第一个参数所定义。比如说,调用函数 createCanvas(320, 240) 将定义此宽度变量为 320。如果一个程式没有使用 createCanvas() 宽度值将默认为 100。"
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "储存画布高度的系统变量。这值是由 createCanvas() 函数的第二个参数所定义。比如说,调用函数 createCanvas(320, 240) 将定义此高度变量为 240。如果一个程式没有使用 createCanvas() 高度值将默认为 100。"
            +      ]
            +    },
            +    "fullscreen": {
            +      "description": [
            +        "如果提供一个参数,依该参数而定该绘图是否是全屏。如果没有给予任何参数,将返回当时的全屏状态。注意因为浏览器限制,此函数只能在使用者输入时调用,比如说在滑鼠点击时如以上范例。"
            +      ],
            +      "returns": "布尔值:当时的全屏状态",
            +      "params": {
            +        "val": "布尔值:该绘图是否应该是全屏"
            +      }
            +    },
            +    "pixelDensity": {
            +      "description": [
            +        "定义像素缩放值,用于高像素密度显示器。默认像素密度为显示器的像素密度,可调用 pixelDensity(1) 以关闭此功能。调用 pixelDensity() 并不给予任何参数将返回该绘图的像素密度。"
            +      ],
            +      "params": {
            +        "val": "数字:绘图是否应该缩放及缩放多少"
            +      }
            +    },
            +    "displayDensity": {
            +      "description": [
            +        "返回正在运行该绘图的显示器的像素密度。"
            +      ],
            +      "returns": "数字:该显示器的像素密度"
            +    },
            +    "getURL": {
            +      "description": [
            +        "返回当下的网址。"
            +      ],
            +      "returns": "字符串:网址"
            +    },
            +    "getURLPath": {
            +      "description": [
            +        "返回当下的网址的路径数组"
            +      ],
            +      "returns": "字符串[]:路径组"
            +    },
            +    "getURLParams": {
            +      "description": [
            +        "返回当下网址的参数物件"
            +      ],
            +      "returns": "物件:网址参数"
            +    },
            +    "preload": {
            +      "description": [
            +        "在 setup() 之前被调用,preload() 函数可用来以阻断的方式处理异步加载外来文件。如果 preload 函数有被定义,setup() 将等到其中的加载工作都完成后才开始执行。preload 函数只能含有加载函数(如 loadImage、loadJSON、loadFont、loadStrings 等)。如果您想使用异步加载,加载函数可在 setup() 内或任何其他地方调用,您只需使用其回调函数参数。<br><br>在默认情况下 “loading...” 字眼将会被显示。如果您想只做您自己的加载页面,只需在您也页面上加个 id 为 “p5_loading” 的 HTML 元素。更多详情请查看<a href='http://bit.ly/2kQ6Nio'>这里</a>。",
            +        "By default the text \"loading...\" will be displayed. To make your own loading page, include an HTML element with id \"p5_loading\" in your page. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>."
            +      ]
            +    },
            +    "setup": {
            +      "description": [
            +        "setup() 函数将在程式开始时被调用一次。它可在程序开始时被用来定义初始的环境属性如荧幕大小、背景颜色及媒体加载如图像及字体。每个程序只能有一个 setup() 函数并且他不能在一开始执行后再次被调用。<br><br>请注意:在 setup() 内定义的变量并不能在其他函数内使用,这包括 draw() 。",
            +        "Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other functions, including <a href=\"#/p5/draw\">draw()</a>."
            +      ]
            +    },
            +    "draw": {
            +      "description": [
            +        "在 setup() 之后被调用,draw() 函数将持续地重复执行其中的代码直到该程式终止或当 noLoop() 被调用。注意如果 noLoop() 在 setup() 内被调用,draw() 仍然会被执行一个然后才停止。draw() 将会自动被调用并不应该被直接调用。<br><br>您应该使用 noLoop()、redraw() 及 loop() 来控制它。当 noLoop() 停止执行 draw() 内的代码,redraw() 会使 draw() 内的代码执行一次,而 loop() 将会使 draw() 内的代码继续重复执行。<br><br>每一秒 draw() 执行的次数可使用 frameRate() 函数来控制。<br><br>每个绘图只能有一个 draw() 函数,而如果您想持续重复执行代码或处理事件如 mousePressed(),draw() 必须存在。有时候您的程式可能会有空白的 draw() 函数,如以上的范例所示。<br><br>请特别注意绘图坐标系统将在每次 draw() 在开始被调用时重置。任何在 draw() 内执行的变形指令(如 scale、rotate、translate)将会在下一个 draw() 开始时复原,所以变形指令并不会随着时间积累。另一方面,样式(如 fill、stroke等)将会持续同样的效果。",
            +        "It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After <a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the code inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code inside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.",
            +        "The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with the <a href=\"#/p5/frameRate\">frameRate()</a> function.",
            +        "There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must exist if you want the code to run continuously, or to process events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in your program, as shown in the above example.",
            +        "It is important to note that the drawing coordinate system will be reset at the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed within <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be undone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate over time. On the other hand, styling applied (ex: fill, stroke, etc) will remain in effect."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "移除整个 p5 绘图。这函数将移除画布及任何由 p5.js 创造的元素。它也会终止绘图循环及解除任何被绑定在窗口对象的属性或函数。它会留下一个 p5 变量以防您还想创造一个新的 p5 绘图。您也可以舍去 p5 = null 以完全删除它。虽然所有由 p5 程式库所创造的函数、变量和物件将会被移除,任何其他由您的代码所定义的公共变量将会被保留。"
            +      ]
            +    },
            +    "disableFriendlyErrors": {
            +      "description": [
            +        "Allows for the friendly error system (FES) to be turned off when creating a sketch, which can give a significant boost to performance when needed. See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'> disabling the friendly error system</a>."
            +      ]
            +    },
            +    "let": {
            +      "description": [
            +        "Creates and names a new variable. A variable is a container for a value.",
            +        "Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope. This means that the variable only exists within the <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> block</a> that it is created within.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>: Declares a block scope local variable, optionally initializing it to a value."
            +      ]
            +    },
            +    "const": {
            +      "description": [
            +        "Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>, a constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value, however constants cannot be reassigned once they are declared. Although it is noteworthy that for non-primitive data types like objects & arrays, their elements can still be changeable. So if a variable is assigned an array, you can still add or remove elements from the array but cannot reassign another array to it. Also unlike <code>let</code>, you cannot declare variables without value using const.",
            +        "Constants have block-scope. This means that the constant only exists within the <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\"> block</a> that it is created within. A constant cannot be redeclared within a scope in which it already exists.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>: Declares a read-only named constant. Constants are block-scoped, much like variables defined using the 'let' statement. The value of a constant can't be changed through reassignment, and it can't be redeclared."
            +      ]
            +    },
            +    "===": {
            +      "description": [
            +        "The strict equality operator <a href=\"#/p5/===\">===</a> checks to see if two values are equal and of the same type.",
            +        "A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>: The non-identity operator returns true if the operands are not equal and/or not of the same type.",
            +        "Note: In some examples around the web you may see a double-equals-sign <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>, used for comparison instead. This is the non-strict equality operator in Javascript. This will convert the two values being compared to the same type before comparing them."
            +      ]
            +    },
            +    ">": {
            +      "description": [
            +        "The greater than operator <a href=\"#/p5/>\">></a> evaluates to true if the left value is greater than the right value. <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\"> There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    ">=": {
            +      "description": [
            +        "The greater than or equal to operator <a href=\"#/p5/>=\">>=</a> evaluates to true if the left value is greater than or equal to the right value.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "<": {
            +      "description": [
            +        "The less than operator <a href=\"#/p5/<\"><</a> evaluates to true if the left value is less than the right value.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "<=": {
            +      "description": [
            +        "The less than or equal to operator <a href=\"#/p5/<=\"><=</a> evaluates to true if the left value is less than or equal to the right value.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a>"
            +      ]
            +    },
            +    "if-else": {
            +      "description": [
            +        "The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.",
            +        "A condition is placed between the parenthesis following 'if', when that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>, the code between the following curly braces is run. Alternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>, the code between the curly braces of 'else' block is run instead. Writing an else block is optional.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>: The 'if' statement executes a statement if a specified condition is truthy. If the condition is falsy, another statement can be executed"
            +      ]
            +    },
            +    "function": {
            +      "description": [
            +        "Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>. A <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.",
            +        "Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a> are variables that are scoped to the function, that can be assigned a value when calling the function.Multiple parameters can be given by seperating them with commas.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>: Declares a function with the specified parameters."
            +      ]
            +    },
            +    "return": {
            +      "description": [
            +        "Specifies the value to be returned by a function. For more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\"> the MDN entry for return</a>."
            +      ]
            +    },
            +    "boolean": {
            +      "description": [
            +        "转换一个数字或字符串成其布尔值。在数字上,任何非零的值(无论正负)都将转换为 true,而零将转换为 false。在字符串上,\"true\" 将转换成 true,而任何其他值都会转换成 false。当给予一数组的数字或字符串时,将返回一个等同大小的布尔值数组。"
            +      ],
            +      "returns": "布尔值:该值的布尔值",
            +      "params": {
            +        "n": "字符串|布尔值|数字|数组:该解析的值"
            +      }
            +    },
            +    "string": {
            +      "description": [
            +        "A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript. A string is a series of text characters. In Javascript, a string value must be surrounded by either single-quotation marks(') or double-quotation marks(\").",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>: A string is a sequence of characters used to represent text."
            +      ]
            +    },
            +    "number": {
            +      "description": [
            +        "A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript. A number can be a whole number or a decimal number.",
            +        "<a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a>"
            +      ]
            +    },
            +    "object": {
            +      "description": [
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:  An <a href=\"#/p5/object\">object</a> is a collection of related data and/or  functionality (which usually consists of several variables and functions —  which are called properties and methods when they are inside objects.)"
            +      ]
            +    },
            +    "class": {
            +      "description": [
            +        "Creates and names a <a href=\"#/p5/class\">class</a> which is a template for the creation of <a href=\"#/p5/objects\">objects</a>.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>: The class declaration creates a new Class with a given name using prototype-based inheritance."
            +      ]
            +    },
            +    "for": {
            +      "description": [
            +        "<a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one section of code multiple times.",
            +        "A 'for loop' consists of three different expressions inside of a parenthesis, all of which are optional.These expressions are used to control the number of times the loop is run.The first expression is a statement that is used to set the initial state for the loop.The second expression is a condition that you would like to check before each loop. If this expression returns false then the loop will exit.The third expression is executed at the end of each loop. These expression are separated by ; (semi-colon).In case of an empty expression, only a semi-colon is written.",
            +        "The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second and third expression.",
            +        "As with any loop, it is important to ensure that the loop can 'exit', or that the test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop is the second expression detailed above. Ensuring that this expression can eventually become false ensures that your loop doesn't attempt to run an infinite amount of times, which can crash your browser.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>: Creates a loop that executes a specified statement until the test condition evaluates to false. The condition is evaluated after executing the statement, resulting in the specified statement executing at least once."
            +      ]
            +    },
            +    "while": {
            +      "description": [
            +        "<a href=\"#/p5/while\">while</a> creates a loop that is useful for executing one section of code multiple times.",
            +        "With a 'while loop', the code inside of the loop body (between the curly braces) is run repeatedly until the test condition (inside of the parenthesis) evaluates to false. The condition is tested before executing the code body with <a href=\"#/p5/while\">while</a>, so if the condition is initially false the loop body, or statement, will never execute.",
            +        "As with any loop, it is important to ensure that the loop can 'exit', or that the test condition will eventually evaluate to false. This is to keep your loop from trying to run an infinite amount of times, which can crash your browser.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>: The while statement creates a loop that executes a specified statement as long as the test condition evaluates to true.The condition is evaluated before executing the statement."
            +      ]
            +    },
            +    "createCanvas": {
            +      "description": [
            +        "在文件内创造一个画布元素,并以像素定义其大小。这函数只应该在 setup() 开始时被调用一次。在同一个绘图里调用 createCanvas 多过一次将造成难以预料的行为。如果你想要使用多过一个绘图画布您可以使用 createGraphics(默认上会被隐藏可是可以被显示)。<br><br>给予这函数的宽度和高度参数将被用来定义 width 和 height 系统变量。如果 createCanvas() 没有被使用,画布将会被给予默认大小 100x100。<br><br>以知更多放置画布的方法,请参考<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>画布放置维基</a>(英文页面)。",
            +        "Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0) is positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code> is set to <code>WEBGL</code>), the origin is positioned at the center of the canvas. See <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.",
            +        "The system variables width and height are set by the parameters passed to this function. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the window will be given a default size of 100x100 pixels.",
            +        "For more ways to position the canvas, see the <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'> positioning the canvas</a> wiki page."
            +      ],
            +      "returns": "p5.Renderer:",
            +      "params": {
            +        "w": "数字:画布的宽度",
            +        "h": "数字:画布的高度",
            +        "renderer": "常量:P2D 或 WEBGL"
            +      }
            +    },
            +    "resizeCanvas": {
            +      "description": [
            +        "缩放画布至给予的宽度和高度。该画布将会马上被清空及调用 draw(),使得画布能在缩放后重新渲染。"
            +      ],
            +      "params": {
            +        "w": "数字:画布的宽度",
            +        "h": "数字:画布的高度",
            +        "noRedraw": "布尔值:不要马上更新画布"
            +      }
            +    },
            +    "noCanvas": {
            +      "description": [
            +        "如果该 p5 绘图不需要画布,此函数将移除默认画布。"
            +      ]
            +    },
            +    "createGraphics": {
            +      "description": [
            +        "创造及返回一个新的 p5.Renderer 物件。如果您需要在一个画面外的图形缓冲区作画,您可以使用这个函数。前两个参数将定义宽度和高度像素。"
            +      ],
            +      "returns": "buffer gráfico fuera de pantalla",
            +      "params": {
            +        "w": "数字:画面外图形缓冲区的宽度",
            +        "h": "数字:画面外图形缓冲区的高度",
            +        "renderer": "常量:P2D 或 WEBGL,默认为 P2D"
            +      }
            +    },
            +    "blendMode": {
            +      "description": [
            +        "根据所设定的模式在显示窗口内混合像素。以下模式选择可用来混合源像素(A)与已经在显示窗口的像素(B):<ul><li><code>BLEND</code> - 颜色线性插值:C = A*系数 + B。这是默认混合模式。</li><li><code>ADD</code> - A 与 B 的总和</li><li><code>DARKEST</code> - 将显示当中最深的颜色:C = min(A*系数, B)。</li><li><code>LIGHTEST </code> - 将显示当中最浅的颜色:C = max(A*系数, B)。</li><li><code>DIFFERENCE</code> - 从底下的图像中减去颜色。</li><li><code>EXCLUSION</code> - 与 DIFFERENCE 相似但不那么强烈。</li><li><code>MULTIPLY</code> - 将颜色相乘,效果一定会更暗。</li><li><code>SCREEN</code> - 与 MULTIPLY 相反,使用颜色的反值。</li><li><code>REPLACE</code> - 像素将完全盖过其他像素并将不会使用透明度值。</li><li><code>OVERLAY</code> - MULTIPLY 及 SCREEN 和混合。暗值将相乘,亮值将相乘反值。</li><li><code>HARD_LIGHT</code> - 当高于 50% 灰时 SCREEN,低于时 MULTIPLY。</li><li><code>SOFT_LIGHT</code> - DARKEST 及 LIGHTEST 的混合。与 OVERLAY 的效果相似,但不那么强烈。</li><li><code>DODGE</code> - 使浅色更浅及增加对比度,忽略暗色。</li><li><code>BURN</code> - 是深色更深及增加对比度,忽略浅色。</li></ul>",
            +        "<em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer. <em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer."
            +      ],
            +      "params": {
            +        "mode": "常量:画布的混合模式。BLEND、DARKEST、LIGHTEST、DIFFERENCE、MULTIPLY、EXCLUSION、SCREEN、REPLACE、OVERLAY、HARD_LIGHT、SOFT_LIGHT、DODGE、BURN、ADD 或 NORMAL"
            +      }
            +    },
            +    "drawingContext": {
            +      "description": [
            +        "The p5.js API provides a lot of functionality for creating graphics, but there is some native HTML5 Canvas functionality that is not exposed by p5. You can still call it directly using the variable <code>drawingContext</code>, as in the example shown. This is the equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>. See this <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\"> reference for the native canvas API</a> for possible drawing functions you can call."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "停止 p5.js 持续重复执行 draw() 内的代码。如果 loop() 被调用,draw() 内的代码将开始继续重复执行。如果 noLoop() 在 setup() 被调用,它应该是代码块的最后一行代码。<br><br>在使用 noLoop() 时,您并不能在事件处理函数如 mousePressed() 或 keyPressed() 内操纵或存取荧幕。不过您可以使用哪些函数调用 redraw() 或 loop(),从而执行 draw(),以正确的更新荧幕。这表示当 noLoop() 被调用后,您不能绘制任何东西,同时某些函数如 saveFrame() 或 loadPixels() 也不能使用。<br><br>注意如果绘图的大小改变,redraw() 将会被调用以更新绘图,即使 noLoop() 已经被调用,不然绘图将会处于一个奇怪的状态直到 loop() 再次被调用。",
            +        "When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate or access the screen inside event handling functions such as <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to call <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>, which will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen properly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been called, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a> or <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.",
            +        "Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will be called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a> has been specified. Otherwise, the sketch would enter an odd state until <a href=\"#/p5/loop\">loop()</a> was called.",
            +        "Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop()."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "在默认下,p5.js 将会循环执行 draw() 内的代码。不过 draw() 循环能使用 noLoop() 停止。在这情况下 draw() 循环可使用 loop() 函数恢复执行。",
            +        "Avoid calling loop() from inside setup().",
            +        "Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop()."
            +      ]
            +    },
            +    "isLooping": {
            +      "description": [
            +        "By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously, executing the code within it. If the sketch is stopped with <a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>, isLooping() returns the current state for use within custom event handlers."
            +      ]
            +    },
            +    "push": {
            +      "description": [
            +        "push() 函数将储存当时的绘画样式设置及变形,而 pop() 将恢复这些设置。注意这两个函数需要一起使用。它们让您改变样式及变形设置然后再回到您之前的设置。当使用 push() 开始一个新的状态时,它将继续建立在当时的样式和变形上。push() 和 pop() 函数可被重复嵌入以提供更复杂的控制。(请参考第二个范例)<br><br>push() 将现有的变形及样式设置资料储存上来,这包括以下的函数:fill()、stroke()、tint()、strokeWeight()、strokeCap()、strokeJoin()、imageMode()、rectMode()、ellipseMode()、colorMode()、textAlign()、textFont()、textMode()、textSize()、textLeading()。",
            +        "<a href=\"#/p5/push\">push()</a> stores information related to the current transformation state and style settings controlled by the following functions: <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"#/p5/strokeCap\">strokeCap()</a>, <a href=\"#/p5/strokeJoin\">strokeJoin()</a>, <a href=\"#/p5/imageMode\">imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href=\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5/textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/noiseSeed\">noiseSeed()</a>.",
            +        "In WEBGL mode additional style settings are stored. These are controlled by the following functions: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ambientLight\">ambientLight()</a>, <a href=\"#/p5/directionalLight\">directionalLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">shininess()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> and <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "pop": {
            +      "description": [
            +        "push() 函数将储存当时的绘画样式设置及变形,而 pop() 将恢复这些设置。注意这两个函数需要一起使用。它们让您改变样式及变形设置然后再回到您之前的设置。当使用 push() 开始一个新的状态时,它将继续建立在当时的样式和变形上。push() 和 pop() 函数可被重复嵌入以提供更复杂的控制。(请参考第二个范例)<br><br>push() 将现有的变形及样式设置资料储存上来,这包括以下的函数:fill()、stroke()、tint()、strokeWeight()、strokeCap()、strokeJoin()、imageMode()、rectMode()、ellipseMode()、colorMode()、textAlign()、textFont()、textMode()、textSize()、textLeading()。",
            +        "<a href=\"#/p5/push\">push()</a> stores information related to the current transformation state and style settings controlled by the following functions: <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/noFill\">noFill()</a>, <a href=\"#/p5/noStroke\">noStroke()</a>, <a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/tint\">tint()</a>, <a href=\"#/p5/noTint\">noTint()</a>, <a href=\"#/p5/strokeWeight\">strokeWeight()</a>, <a href=\"#/p5/strokeCap\">strokeCap()</a>, <a href=\"#/p5/strokeJoin\">strokeJoin()</a>, <a href=\"#/p5/imageMode\">imageMode()</a>, <a href=\"#/p5/rectMode\">rectMode()</a>, <a href=\"#/p5/ellipseMode\">ellipseMode()</a>, <a href=\"#/p5/colorMode\">colorMode()</a>, <a href=\"#/p5/textAlign\">textAlign()</a>, <a href=\"#/p5/textFont\">textFont()</a>, <a href=\"#/p5/textSize\">textSize()</a>, <a href=\"#/p5/textLeading\">textLeading()</a>, <a href=\"#/p5/applyMatrix\">applyMatrix()</a>, <a href=\"#/p5/resetMatrix\">resetMatrix()</a>, <a href=\"#/p5/rotate\">rotate()</a>, <a href=\"#/p5/scale\">scale()</a>, <a href=\"#/p5/shearX\">shearX()</a>, <a href=\"#/p5/shearY\">shearY()</a>, <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/noiseSeed\">noiseSeed()</a>.",
            +        "In WEBGL mode additional style settings are stored. These are controlled by the following functions: <a href=\"#/p5/setCamera\">setCamera()</a>, <a href=\"#/p5/ambientLight\">ambientLight()</a>, <a href=\"#/p5/directionalLight\">directionalLight()</a>, <a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>, <a href=\"#/p5/specularMaterial\">specularMaterial()</a>, <a href=\"#/p5/shininess\">shininess()</a>, <a href=\"#/p5/normalMaterial\">normalMaterial()</a> and <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "redraw": {
            +      "description": [
            +        "执行在 draw() 内的代码一次。这函数让该程序只在需要的时候更新显示窗口,比如说当 mousePressed() 或 keyPressed()事件被触发时。<br><br>再构造程式时,只有在如 mousePressed() 之类的时间内调用 redraw() 才有意义,因为 redraw() 并不会直接调用 draw() (它只会表示绘图有需要更新)。<br><br>redraw() 函数并不会在 draw() 内正常运作。以启用/禁用动画,请使用 loop() 及 noLoop()。<br><br>此外您也能定义每次调用 redraw() 将使 draw() 被调用几次。您这需给予一个整数参数已表示执行的次数。",
            +        "In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a> within events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This is because <a href=\"#/p5/redraw\">redraw()</a> does not run <a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates an update is needed).",
            +        "The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when called inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations, use <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.",
            +        "In addition you can set the number of redraws per method call. Just add an integer as single parameter for the number of redraws."
            +      ],
            +      "params": {
            +        "n": "整数:重绘 n 次。默认值为 1"
            +      }
            +    },
            +    "p5": {
            +      "description": [
            +        "The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal \"global mode\". This is an advanced topic. A short description and example is included below. Please see <a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\"> Dan Shiffman's Coding Train video tutorial</a> or this <a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a> for more info.",
            +        "By default, all p5.js functions are in the global namespace (i.e. bound to the window object), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this might be inconvenient if you are mixing with other JS libraries (synchronously or asynchronously) or writing long programs of your own. p5.js currently supports a way around this problem called \"instance mode\". In instance mode, all p5 functions are bound up in a single variable instead of polluting your global namespace.",
            +        "Optionally, you can specify a default container for the canvas and any other elements to append to with a second argument. You can give the ID of an element in your html, or an html node itself.",
            +        "Note that creating instances like this also allows you to have more than one p5 sketch on a single web page, as they will each be wrapped up with their own set up variables. Of course, you could also use iframes to have multiple sketches in global mode."
            +      ],
            +      "params": {
            +        "sketch": "Object: a function containing a p5.js sketch",
            +        "node": "String|Object: ID or pointer to HTML DOM node to contain sketch in"
            +      }
            +    },
            +    "applyMatrix": {
            +      "description": [
            +        "将现有的矩阵乘于由参数所定义的矩阵。这是个强大的功能并能够同时执行平移、缩放、切变及旋转。您能在<a href='https://zh.wikipedia.org/wiki/%E5%8F%98%E6%8D%A2%E7%9F%A9%E9%98%B5'>维基百科</a>了解更多关于变形矩阵的资讯。<br><br>这里的参数命名跟着 <a href='https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform'>WHATWG 规范</a>(英文页面)的命名方式并代表着一个如下的变形矩阵:<blockquote><p><img style='max-width: 150px' src='assets/transformation-matrix.png' alt='当 applyMatrix 被调用时所使用的变形矩阵'></p></blockquote>",
            +        "The naming of the arguments here follows the naming of the <a href= \"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\"> WHATWG specification</a> and corresponds to a transformation matrix of the form: <blockquote>",
            +        "<img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\" alt=\"The transformation matrix used when applyMatrix is called\"/> </blockquote>"
            +      ],
            +      "params": {
            +        "a": "数字:定义该乘于的 2x3 矩阵",
            +        "b": "数字:定义该乘于的 2x3 矩阵",
            +        "c": "数字:定义该乘于的 2x3 矩阵",
            +        "d": "数字:定义该乘于的 2x3 矩阵",
            +        "e": "数字:定义该乘于的 2x3 矩阵",
            +        "f": "数字:定义该乘于的 2x3 矩阵"
            +      }
            +    },
            +    "resetMatrix": {
            +      "description": [
            +        "将现有的矩阵替换成单位矩阵。"
            +      ]
            +    },
            +    "rotate": {
            +      "description": [
            +        "将一个形状根据参数所定义的角度旋转。这函数将考虑角度模式,所以角度可以是弧度或角度定义。<br><br>所有物件都会绕着原点旋转而正数将使物件在顺时针方向旋转。此变形将影响接下来所有的绘图并且接下来此函数调用效果将累积。比如说,调用 rotate(HALF_PI) 然后 rotate(HALF_PI) 效果会与 rotate(PI) 相同。所有变形将会在 draw() 重新开始时恢复。",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling rotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI). All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.",
            +        "Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "angle": "数字:旋转的角度,根据当时的角度模式,以弧度或角度定义",
            +        "axis": "p5.Vector|数字[]:(3D 模式下)旋转轴"
            +      }
            +    },
            +    "rotateX": {
            +      "description": [
            +        "绕着 x 轴旋转。",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "数字:旋转角度,根据当时的角度模式,以弧度或角度定义"
            +      }
            +    },
            +    "rotateY": {
            +      "description": [
            +        "绕着 y 轴旋转。",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "数字:旋转角度,根据当时的角度模式,以弧度或角度定义"
            +      }
            +    },
            +    "rotateZ": {
            +      "description": [
            +        "绕着 x 轴旋转。只适用于 WEBGL 模式。",
            +        "This method works in WEBGL mode only.",
            +        "Objects are always rotated around their relative position to the origin and positive numbers rotate objects in a clockwise direction. All transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again."
            +      ],
            +      "params": {
            +        "angle": "数字:旋转角度,根据当时的角度模式,以弧度或角度定义"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "通过扩大和收缩顶点,放大或缩小形状。形状物件将会从坐标系统的原点开始缩放。缩放值为十进制百分比。比如说,调用函数 scale(2.0) 将使该形状放大 200%。<br><br>此变形将影响接下来所有的绘图并且接下来此函数调用效果将累积相乘。比如说,调用 scale(2.0) 然后 scale(1.5) 效果会与 scale(3.0) 相同。如果 scale() 在 draw() 内被调用,变形将会在下一次循环开始时恢复。<br><br>给予此函数一个 z 参数只在 WEBGL 模式下受支持。这函数能使用 push() 及 pop() 控制。",
            +        "Transformations apply to everything that happens after and subsequent calls to the function multiply the effect. For example, calling scale(2.0) and then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.",
            +        "Using this function with the z parameter is only available in WEBGL mode. This function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "s": "数字|p5.Vector|数字[]:缩放物件的百分比,或如果给予多个参数 x 轴的缩放百分比",
            +        "y": "数字:y 轴的缩放百分比",
            +        "z": "数字:z 轴的缩放百分比(只适用于 WEBGL 模式)",
            +        "scales": "p5.Vector|数字[]:各轴缩放百分比"
            +      }
            +    },
            +    "shearX": {
            +      "description": [
            +        "有角度参数所定义的形状 x 轴切变量。角度必须符合当时的角度模式。形状物件将会从坐标系统的原点开始切变而正数表示切变方向为顺时针方向。<br><br>此变形将影响接下来所有的绘图并且接下来此函数调用效果将累积。比如说,调用 shearX(PI/2) 然后 shearX(PI/2) 效果会与 shearX(PI) 相同。如果 shearX() 在 draw() 内被调用,变形将会在下一次循环开始时恢复。<br><br>技术上,shearX() 将现有的变形矩阵乘以一个旋转矩阵。这函数能使用 push() 及 pop() 控制。",
            +        "Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling shearX(PI/2) and then shearX(PI/2) is the same as shearX(PI). If <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.",
            +        "Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions."
            +      ],
            +      "params": {
            +        "angle": "数字:根据当时的角度模式,以弧度或角度定义和切变角度"
            +      }
            +    },
            +    "shearY": {
            +      "description": [
            +        "有角度参数所定义的形状 y 轴切变量。角度必须符合当时的角度模式。形状物件将会从坐标系统的原点开始切变而正数表示切变方向为顺时针方向。<br><br>此变形将影响接下来所有的绘图并且接下来此函数调用效果将累积。比如说,调用 shearY(PI/2) 然后 shearY(PI/2) 效果会与 shearY(PI) 相同。如果 shearY() 在 draw() 内被调用,变形将会在下一次循环开始时恢复。<br><br>技术上,shearY() 将现有的变形矩阵乘以一个旋转矩阵。这函数能使用 push() 及 pop() 控制。",
            +        "Transformations apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling shearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If <a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.",
            +        "Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a rotation matrix. This function can be further controlled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions."
            +      ],
            +      "params": {
            +        "angle": "数字:根据当时的角度模式,以弧度或角度定义和切变角度"
            +      }
            +    },
            +    "translate": {
            +      "description": [
            +        "定义在显示窗口内平移物件的量。x 参数将定义左/右平移,y 参数将定义上/下平移。<br><br>此变形将影响接下来所有的绘图并且接下来此函数调用效果将累积。比如说,调用 translate(50, 0) 然后 translate(20, 0) 效果会与 translate(70, 0) 相同。如果 translate() 在 draw() 内被调用,变形将会在下一次循环开始时恢复。这函数能使用 push() 及 pop() 控制。",
            +        "Transformations are cumulative and apply to everything that happens after and subsequent calls to the function accumulates the effect. For example, calling translate(50, 0) and then translate(20, 0) is the same as translate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again. This function can be further controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>."
            +      ],
            +      "params": {
            +        "x": "数字:左/右平移",
            +        "y": "数字:上/下平移",
            +        "z": "数字:前/后平移(只适用于 WEBGL 模式)",
            +        "vector": "p5.Vector:平移向量"
            +      }
            +    },
            +    "storeItem": {
            +      "description": [
            +        "Stores a value in local storage under the key name.  Local storage is saved in the browser and persists  between browsing sessions and page reloads.  The key can be the name of the variable but doesn't  have to be. To retrieve stored items  see <a href=\"#/p5/getItem\">getItem</a>. Sensitive data such as passwords or personal information  should not be stored in local storage."
            +      ],
            +      "params": {
            +        "key": "String",
            +        "value": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +      }
            +    },
            +    "getItem": {
            +      "description": [
            +        "Returns the value of an item that was stored in local storage  using storeItem()"
            +      ],
            +      "returns": "Number|Object|String|Boolean|p5.Color|p5.Vector: Value of stored item",
            +      "params": {
            +        "key": "String: name that you wish to use to store in local storage"
            +      }
            +    },
            +    "clearStorage": {
            +      "description": [
            +        "Clears all local storage items set with storeItem()  for the current domain."
            +      ]
            +    },
            +    "removeItem": {
            +      "description": [
            +        "Removes an item that was stored with storeItem()"
            +      ],
            +      "params": {
            +        "key": "String"
            +      }
            +    },
            +    "createStringDict": {
            +      "description": [
            +        "Creates a new instance of p5.StringDict using the key-value pair  or the object you provide."
            +      ],
            +      "returns": "p5.StringDict:",
            +      "params": {
            +        "key": "String",
            +        "value": "String",
            +        "object": "Object: object"
            +      }
            +    },
            +    "createNumberDict": {
            +      "description": [
            +        "Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair  or object you provide."
            +      ],
            +      "returns": "p5.NumberDict:",
            +      "params": {
            +        "key": "Number",
            +        "value": "Number",
            +        "object": "Object: object"
            +      }
            +    },
            +    "select": {
            +      "description": [
            +        "Searches the page for the first element that matches the given CSS selector string (can be an ID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>. The DOM node itself can be accessed with .elt. Returns null if none found. You can also specify a container to search within."
            +      ],
            +      "returns": "p5.Element|null: <a href=\"#/p5.Element\">p5.Element</a> containing node found",
            +      "params": {
            +        "selectors": "String: CSS selector string of element to search for",
            +        "container": "String|p5.Element|HTMLElement: (Optional) CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or  HTML element to search within"
            +      }
            +    },
            +    "selectAll": {
            +      "description": [
            +        "Searches the page for elements that match the given CSS selector string (can be an ID a class, tag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in an array. The DOM node itself can be accessed with .elt. Returns an empty array if none found. You can also specify a container to search within."
            +      ],
            +      "returns": "p5.Element[]: Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found",
            +      "params": {
            +        "selectors": "String: CSS selector string of elements to search for",
            +        "container": "String|p5.Element|HTMLElement: (Optional) CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>  , or HTML element to search within"
            +      }
            +    },
            +    "removeElements": {
            +      "description": [
            +        "Removes all elements created by p5, except any canvas / graphics elements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>. Event handlers are removed, and element is removed from the DOM."
            +      ]
            +    },
            +    "changed": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an element changes. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when the value of  an element changes.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "input": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is detected with an element. The input event is often used to detect keystrokes in a input element, or changes on a slider element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when any user input is  detected within the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "createDiv": {
            +      "description": [
            +        "Creates a <div></div> element in the DOM with given inner HTML."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createP": {
            +      "description": [
            +        "Creates a"
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createSpan": {
            +      "description": [
            +        "Creates a <span></span> element in the DOM with given inner HTML."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "html": "String: (Optional) inner HTML for element created"
            +      }
            +    },
            +    "createImg": {
            +      "description": [
            +        "Creates an <img> element in the DOM with given src and alternate text."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "src": "String: src path or url for image",
            +        "alt": "String: <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.",
            +        "crossOrigin": "String: <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used",
            +        "successCallback": "Function: (Optional) callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument"
            +      }
            +    },
            +    "createA": {
            +      "description": [
            +        "Creates an <a></a> element in the DOM for including a hyperlink."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "href": "String: url of page to link to",
            +        "html": "String: inner html of link element to display",
            +        "target": "String: (Optional) target where new link should open,  could be _blank, _self, _parent, _top."
            +      }
            +    },
            +    "createSlider": {
            +      "description": [
            +        "Creates a slider <input></input> element in the DOM. Use .size() to set the display length of the slider."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "min": "Number: minimum value of the slider",
            +        "max": "Number: maximum value of the slider",
            +        "value": "Number: (Optional) default value of the slider",
            +        "step": "Number: (Optional) step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)"
            +      }
            +    },
            +    "createButton": {
            +      "description": [
            +        "Creates a <button></button> element in the DOM. Use .size() to set the display size of the button. Use .mousePressed() to specify behavior on press."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "label": "String: label displayed on the button",
            +        "value": "String: (Optional) value of the button"
            +      }
            +    },
            +    "createCheckbox": {
            +      "description": [
            +        "Creates a checkbox <input></input> element in the DOM. Calling .checked() on a checkbox returns if it is checked or not"
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "label": "String: (Optional) label displayed after checkbox",
            +        "value": "Boolean: (Optional) value of the checkbox; checked is true, unchecked is false"
            +      }
            +    },
            +    "createSelect": {
            +      "description": [
            +        "Creates a dropdown menu <select></select> element in the DOM. It also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box. <ul> <li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li> <li><code>.value()</code> will return the currently selected option.</li> <li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li> <li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li> <li><code>.disable()</code> marks whole of dropdown element as disabled.</li> <li><code>.disable(value)</code> marks given option as disabled</li> </ul>"
            +      ],
            +      "returns": "p5.Element:",
            +      "params": {
            +        "multiple": "Boolean: (Optional) true if dropdown should support multiple selections",
            +        "existing": "Object: DOM select element"
            +      }
            +    },
            +    "createRadio": {
            +      "description": [
            +        "Creates a radio button element in the DOM.It also helps existing radio buttons assign methods of <a href=\"#/p5.Element/\">p5.Element</a>. <ul> <li><code>.option(value, [label])</code> can be used to create a new option for the element. If an option with a value already exists, it will be returned. Optionally, a label can be provided as second argument for the option.</li> <li><code>.remove(value)</code> can be used to remove an option for the element.</li> <li><code>.value()</code> method will return the currently selected value.</li> <li><code>.selected()</code> method will return the currently selected input element.</li> <li><code>.selected(value)</code> method will select the option and return it.</li> <li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li> </ul>"
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "containerElement": "Object: An container HTML Element either a div or span inside which all existing radio inputs will be considered as options.",
            +        "name": "String: (Optional) A name parameter for each Input Element."
            +      }
            +    },
            +    "createColorPicker": {
            +      "description": [
            +        "Creates a colorPicker element in the DOM for color input. The .value() method will return a hex string (#rrggbb) of the color. The .color() method will return a p5.Color object with the current chosen color."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "value": "String|p5.Color: (Optional) default color of element"
            +      }
            +    },
            +    "createInput": {
            +      "description": [
            +        "Creates an <input></input> element in the DOM for text input. Use .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "value": "String: default value of the input box",
            +        "type": "String: (Optional) type of text, ie text, password etc. Defaults to text.  Needs a value to be specified first."
            +      }
            +    },
            +    "createFileInput": {
            +      "description": [
            +        "Creates an <input></input> element in the DOM of type 'file'. This allows users to select local files for use in a sketch."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element",
            +      "params": {
            +        "callback": "Function: callback function for when a file is loaded",
            +        "multiple": "Boolean: (Optional) optional, to allow multiple files to be selected"
            +      }
            +    },
            +    "createVideo": {
            +      "description": [
            +        "Creates an HTML5 <video> element in the DOM for simple playback of audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a> and drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter can be either a single string path to a video file, or an array of string paths to different formats of the same video. This is useful for ensuring that your video can play across different browsers, as each supports different formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this page</a> for further information about supported formats."
            +      ],
            +      "returns": "p5.MediaElement: pointer to video <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "src": "String|String[]: path to a video file, or array of paths for  supporting different browsers",
            +        "callback": "Function: (Optional) callback function to be called upon  'canplaythrough' event fire, that is, when the  browser can play the media, and estimates that  enough data has been loaded to play the media  up to its end without having to stop for  further buffering of content"
            +      }
            +    },
            +    "createAudio": {
            +      "description": [
            +        "Creates a hidden HTML5 <audio> element in the DOM for simple audio playback. The first parameter can be either a single string path to a audio file, or an array of string paths to different formats of the same audio. This is useful for ensuring that your audio can play across different browsers, as each supports different formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this page for further information about supported formats</a>."
            +      ],
            +      "returns": "p5.MediaElement: pointer to audio <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "src": "String|String[]: (Optional) path to an audio file, or array of paths  for supporting different browsers",
            +        "callback": "Function: (Optional) callback function to be called upon  'canplaythrough' event fire, that is, when the  browser can play the media, and estimates that  enough data has been loaded to play the media  up to its end without having to stop for  further buffering of content"
            +      }
            +    },
            +    "VIDEO": {},
            +    "AUDIO": {},
            +    "createCapture": {
            +      "description": [
            +        "Creates a new HTML5 <video> element that contains the audio/video feed from a webcam. The element is separate from the canvas and is displayed by default. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>. The feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>. The loadedmetadata property can be used to detect when the element has fully loaded (see second example).",
            +        "More specific properties of the feed can be passing in a Constraints object. See the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'> W3C spec</a> for possible properties. Note that not all of these are supported by all browsers.",
            +        "<em>Security note</em>: A new browser security specification requires that getUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>, only works when you're running the code locally, or on HTTPS. Learn more <a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a> and <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>."
            +      ],
            +      "returns": "p5.Element: capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +      "params": {
            +        "type": "String|Constant|Object: type of capture, either VIDEO or  AUDIO if none specified, default both,  or a Constraints object",
            +        "callback": "Function: (Optional) function to be called once  stream has loaded"
            +      }
            +    },
            +    "createElement": {
            +      "description": [
            +        "Creates element with given tag in the DOM with given content."
            +      ],
            +      "returns": "p5.Element: pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +      "params": {
            +        "tag": "String: tag for the new element",
            +        "content": "String: (Optional) html content to be inserted into the element"
            +      }
            +    },
            +    "deviceOrientation": {
            +      "description": [
            +        "deviceOrientation 系统变量将会储存设备的旋转方向。此变量的值可以是 ‘landscape’ 或 ‘portrait’。如果没有资料可用他会被定义成 ‘undefined’。LANDSCAPE 或 PORTRAIT。"
            +      ]
            +    },
            +    "accelerationX": {
            +      "description": [
            +        "accelerationX 系统变量将会储存设备的 x 轴加速度。值的单位为每平方秒米。"
            +      ]
            +    },
            +    "accelerationY": {
            +      "description": [
            +        "accelerationY 系统变量将会储存设备的 y 轴加速度。值的单位为每平方秒米。"
            +      ]
            +    },
            +    "accelerationZ": {
            +      "description": [
            +        "accelerationZ 系统变量将会储存设备的 z 轴加速度。值的单位为每平方秒米。"
            +      ]
            +    },
            +    "pAccelerationX": {
            +      "description": [
            +        "pAccelerationX 系统变量将会储存上一个影格该设备的 x 轴加速度。值的单位为每平方秒米。"
            +      ]
            +    },
            +    "pAccelerationY": {
            +      "description": [
            +        "pAccelerationY 系统变量将会储存上一个影格该设备的 y 轴加速度。值的单位为每平方秒米。"
            +      ]
            +    },
            +    "pAccelerationZ": {
            +      "description": [
            +        "pAccelerationZ 系统变量将会储存上一个影格该设备的 z 轴加速度。值的单位为每平方秒米。"
            +      ]
            +    },
            +    "rotationX": {
            +      "description": [
            +        "rotationX 系统变量将会储存设备在 x 轴的旋转角度。值介于 0 与 +/-180 度之间。<br><br>注意:旋转的顺序很重要,比如说,如果同时使用它们必须依 Z-X-Y 的顺序调用或可能会有难以预料的行为。",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "rotationY": {
            +      "description": [
            +        "rotationY 系统变量将会储存设备在 y 轴的旋转角度。值介于 0 与 +/-90 度之间。<br><br>注意:旋转的顺序很重要,比如说,如果同时使用它们必须依 Z-X-Y 的顺序调用或可能会有难以预料的行为。",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "rotationZ": {
            +      "description": [
            +        "rotationZ 系统变量将会储存设备在 z 轴的旋转角度。值介于 0 与 359 度之间。<br><br>与 rotationX 及 rotationY 不同的是,这变量只能在有内建指南针的设备使用。<br><br>注意:旋转的顺序很重要,比如说,如果同时使用它们必须依 Z-X-Y 的顺序调用或可能会有难以预料的行为。",
            +        "Unlike rotationX and rotationY, this variable is available for devices with a built-in compass only.",
            +        "Note: The order the rotations are called is important, ie. if used together, it must be called in the order Z-X-Y or there might be unexpected behaviour."
            +      ]
            +    },
            +    "pRotationX": {
            +      "description": [
            +        "pRotationX 系统变量将会储存上一个影格该设备在 x 轴的旋转角度。值介于 0 与 +/-180 度之间。<br><br>pRotationX 可以和 rotationX 一起使用以找出设备 x 轴的旋转方向。",
            +        "pRotationX can also be used with rotationX to determine the rotate direction of the device along the X-axis."
            +      ]
            +    },
            +    "pRotationY": {
            +      "description": [
            +        "pRotationY 系统变量将会储存上一个影格该设备在 y 轴的旋转角度。值介于 0 与 +/-90 度之间。<br><br>pRotationY 可以和 rotationY 一起使用以找出设备 y 轴的旋转方向。",
            +        "pRotationY can also be used with rotationY to determine the rotate direction of the device along the Y-axis."
            +      ]
            +    },
            +    "pRotationZ": {
            +      "description": [
            +        "pRotationZ 系统变量将会储存上一个影格该设备在 z 轴的旋转角度。值介于 0 与 359 度之间。<br><br>pRotationZ 可以和 rotationZ 一起使用以找出设备 z 轴的旋转方向。",
            +        "pRotationZ can also be used with rotationZ to determine the rotate direction of the device along the Z-axis."
            +      ]
            +    },
            +    "turnAxis": {
            +      "description": [
            +        "When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis variable. The turnAxis variable is only defined within the scope of deviceTurned()."
            +      ]
            +    },
            +    "setMoveThreshold": {
            +      "description": [
            +        "setMoveThreshold() 函数可用来设置 deviceMoved() 函数的移动阈值。默认阈值为 0.5。"
            +      ],
            +      "params": {
            +        "value": "数字:阈值"
            +      }
            +    },
            +    "setShakeThreshold": {
            +      "description": [
            +        "setShakeThreshold() 函数可用来设置 deviceShaken() 函数的摇动阈值。默认阈值为 30。"
            +      ],
            +      "params": {
            +        "value": "数字:阈值"
            +      }
            +    },
            +    "deviceMoved": {
            +      "description": [
            +        "deviceMoved() 函数将在设备在 X、Y 或 Z 轴被移动多过阈值时被调用。默认阈值为 0.5。"
            +      ]
            +    },
            +    "deviceTurned": {
            +      "description": [
            +        "deviceTurned() 函数将在设备被连续旋转多过 90 度时被调用。<br><br>触发 deviceTurned() 的旋转轴将被储存在 turnAxis 变量中。deviceTurned() 函数能被锁定在 X、Y 或 Z 以确保只有所定义的轴会导致函数被调用,您只需比较 turnAxis 变量和 'X'、'Y' 或 'Z' 字符串。",
            +        "The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis variable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis: X, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'."
            +      ]
            +    },
            +    "deviceShaken": {
            +      "description": [
            +        "deviceShaken() 函数将在设备的 accelerationX 及 accelerationY 加速度值改变超过阈值。默认阈值为 30。"
            +      ]
            +    },
            +    "keyIsPressed": {
            +      "description": [
            +        "keyIsPressed 布尔系统变量将会在任何键被按下时为真(true)而没键被按下时为假(false)。"
            +      ]
            +    },
            +    "key": {
            +      "description": [
            +        "key 系统变量将会储存上一个被键入的键盘键值。以获得正确的大小写,最好在 keyTyped() 内使用。至于非 ASCII 值的键,请使用 keyCode 变量。"
            +      ]
            +    },
            +    "keyCode": {
            +      "description": [
            +        "keyCode 变量可用来探测特别键如 BACKSPACE、DELETE、ENTER、RETURN、TAB、ESCAPE、SHIFT、CONTROL、OPTION、ALT、UP_ARROW、DOWN_ARROW、LEFT_ARROW、RIGHT_ARROW 是否被按下。您也可以使用特别网站如 <a href='http://keycode.info/'>keycode.info</a> 以找出自定义键的 keyCode。"
            +      ]
            +    },
            +    "keyPressed": {
            +      "description": [
            +        "keyPressed() 函数将会在每一次任何键被按下时被调用。被按下的键的 keyCode 将被储存在 keyCode 变量内。<br><br>对于非 ASCII 值的键,请使用 keyCode 变量。您能查看 keyCode 是否等于 BACKSPACE、DELETE、ENTER、RETURN、TAB、ESCAPE、SHIFT、CONTROL、OPTION、ALT、UP_ARROW、DOWN_ARROW、LEFT_ARROW、RIGHT_ARROW。<br><br>至于 ASCII 键值它们的值会被储存在 key 变量内。不过,它并不会分辨大小写。因此,建议使用 keyTyped() 以读取 key 变量,因为其大小写在这里会被分辨出来。<br><br>取决于操作系统如何处理按键重复,按住一个键可能使 keyTyped() (及 keyReleased())被调用多过一次。重复的速度应操作系统及该电脑的设置而定。<br><br>不同浏览器可能会有不同附属于个别键盘事件的默认行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。",
            +        "For non-ASCII keys, use the keyCode variable. You can check if the keyCode equals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.",
            +        "For ASCII keys, the key that was pressed is stored in the key variable. However, it does not distinguish between uppercase and lowercase. For this reason, it is recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the case of the variable will be distinguished.",
            +        "Because of how operating systems handle key repeats, holding down a key may cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The rate of repeat is set by the operating system and how each computer is configured. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyReleased": {
            +      "description": [
            +        "keyReleased() 函数将会在每一次任何键被释放时被调用。请查看 key 及 keyCode 以知更多详情。<br><br>不同浏览器可能会有不同附属于个别键盘事件的默认行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyTyped": {
            +      "description": [
            +        "keyTyped() 函数将会在每一次任何键被按下时被调用,可是会忽略操作键如 Ctrl、Shift 及 Alt。被按下的键的 keyCode 将被储存在 keyCode 变量内。<br><br>取决于操作系统如何处理按键重复,按住一个键可能使 keyTyped() (及 keyReleased())被调用多过一次。重复的速度应操作系统及该电脑的设置而定。<br><br>不同浏览器可能会有不同附属于个别键盘事件的默认行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。",
            +        "Because of how operating systems handle key repeats, holding down a key will cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The rate of repeat is set by the operating system and how each computer is configured. Browsers may have different default behaviors attached to various key events. To prevent any default behavior for this event, add \"return false\" to the end of the method."
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional KeyboardEvent callback argument."
            +      }
            +    },
            +    "keyIsDown": {
            +      "description": [
            +        "keyIsDown() 函数将查看被提供的键是否正被按下。它能在当您需要使用多个不同的键同时用来移动一个物件时使用(如将一个图像往斜移动)。您能给予任何代表该键的 keyCode 会任何<a href='http://p5js.org/zh-Hans/reference/#p5/keyCode'>此页</a>的 keyCode 变量名为参数。"
            +      ],
            +      "returns": "Boolean: whether key is down or not",
            +      "params": {
            +        "code": "数字:该查看的键"
            +      }
            +    },
            +    "movedX": {
            +      "description": [
            +        "The variable movedX contains the horizontal movement of the mouse since the last frame"
            +      ]
            +    },
            +    "movedY": {
            +      "description": [
            +        "The variable movedY contains the vertical movement of the mouse since the last frame"
            +      ]
            +    },
            +    "mouseX": {
            +      "description": [
            +        "mouseX 系统变量将会储存当时的鼠标相对于画布 (0, 0) 位置的的横向位置。如果使用的是触动而不是滑鼠的话,mouseX 将会储存上一个触动点的 x 值。"
            +      ]
            +    },
            +    "mouseY": {
            +      "description": [
            +        "mouseY 系统变量将会储存当时的鼠标相对于画布 (0, 0) 位置的的直向位置。如果使用的是触动而不是滑鼠的话,mouseY 将会储存上一个触动点的 y 值。"
            +      ]
            +    },
            +    "pmouseX": {
            +      "description": [
            +        "pmouseX 系统变量将会储存上一个影格鼠标或触动点相对于画布 (0, 0) 位置的的横向位置。"
            +      ]
            +    },
            +    "pmouseY": {
            +      "description": [
            +        "pmouseY 系统变量将会储存上一个影格鼠标或触动点相对于画布 (0, 0) 位置的的直向位置。"
            +      ]
            +    },
            +    "winMouseX": {
            +      "description": [
            +        "winMouseX 系统变量将会储存当时鼠标相对于窗口 (0, 0) 位置的横向位置。"
            +      ]
            +    },
            +    "winMouseY": {
            +      "description": [
            +        "winMouseY 系统变量将会储存当时鼠标相对于窗口 (0, 0) 位置的直向位置。"
            +      ]
            +    },
            +    "pwinMouseX": {
            +      "description": [
            +        "pwinMouseX 系统变量将会储存上一个影格鼠标相对于窗口 (0, 0) 位置的横向位置。"
            +      ]
            +    },
            +    "pwinMouseY": {
            +      "description": [
            +        "pwinMouseY 系统变量将会储存上一个影格鼠标相对于窗口 (0, 0) 位置的直向位置。"
            +      ]
            +    },
            +    "mouseButton": {
            +      "description": [
            +        "p5 将自动记录滑鼠键是否被按下及哪个键被按下。mouseButton 系统变量的值可能是 LEFT、RIGHT 或 CENTER,取决于上一个被按下的滑鼠键。请注意:不同的浏览器可能记录不同的 mouseButton 值。"
            +      ]
            +    },
            +    "mouseIsPressed": {
            +      "description": [
            +        "mouseIsPressed 系统变量将会在滑鼠键被按下时为真(true),而没按下时为假(false)。"
            +      ]
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "mouseMoved() 函数将在每次鼠标移动而滑鼠键没有被按下的时候被调用。<br><br>不同浏览器可能有不同附属于个别滑鼠事件的行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseDragged": {
            +      "description": [
            +        "mouseDragged() 函数将在每次鼠标移动及滑鼠键正被按下的时候被调用。如果 mouseDragged() 函数并未有被定义,touchMoved() 函数有被定义的话将会被调用。<br><br>不同浏览器可能有不同附属于个别滑鼠事件的行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "mousePressed() 函数将在每次滑鼠键被按下时被调用。mouseButton 函数(请参考其文献)可以被用来探测哪一个滑鼠键刚被按下。如果 mousePressed() 函数并未有被定义,touchStarted() 函数有被定义的话将会被调用。<br><br>不同浏览器可能有不同附属于个别滑鼠事件的行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "mouseReleased() 函数将在每次滑鼠键被释放时被调用。如果 mouseReleased() 函数并未有被定义,touchEnded() 函数有被定义的话将会被调用。<br><br>不同浏览器可能有不同附属于个别滑鼠事件的行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "mouseClicked() 函数将在滑鼠键被按下然后被释放后被调用。<br><br>不同浏览器处理滑鼠点击的方式不大一样,所以这函数只有在滑鼠左键被点击时才保证会被触发。如果想要处理其他滑鼠键的点击或释放事件,请参考 mousePressed() 或 mouseReleased()。<br><br>不同浏览器可能有不同附属于个别滑鼠事件的行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "doubleClicked() 函数将在 dblclick 事件被触发式被调用,dblclick 时间是 DOM L3 规范的一部分。doubleClicked 将在滑鼠键(通常为左键)连续两次在同样一个元素上点击时被触发。以知更多详情请参考 Mozilla 的参考文献:<a href='https://developer.mozilla.org/en-US/docs/Web/Events/dblclick'>https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a>。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional MouseEvent callback argument."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "mouseWheel() 函数将在每次直向滑鼠滚轮事件被触发式被调用,可以由实际的滑鼠滚轮或摸板触发。<br><br>event.delta 属性将返回滑鼠滚轮所滚动的量。这值可以是正数或负数,取决于滚动的方向(在 OS X 如果启用“自然”滚屏方向,正反方向将相反)。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional WheelEvent callback argument."
            +      }
            +    },
            +    "requestPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a> locks the pointer to its current position and makes it invisible. Use <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since the last call of draw. Note that not all browsers support this feature. This enables you to create experiences that aren't limited by the mouse moving out of the screen even if it is repeatedly moved into one direction. For example, a first person perspective experience."
            +      ]
            +    },
            +    "exitPointerLock": {
            +      "description": [
            +        "The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a> exits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a> for example to make ui elements usable etc"
            +      ]
            +    },
            +    "touches": {
            +      "description": [
            +        "touches[] 系统变量将储存一个含有现在所有触动点相对于画布 (0, 0) 位置的位置数组,及分辨个别触动点移动时的 ID。数组内的每个元素都会有 x、y 及 id 属性。<br><br>touches[] 数组并不受 Safari 及 IE 移动设备(包括手提电脑)所支持。",
            +        "The touches[] array is not supported on Safari and IE on touch-based desktops (laptops)."
            +      ]
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "touchStarted() 函数将在每次触动事件被触发时被调用。如果 touchStarted() 函数并未有被定义,mousePressed() 函数有被定义的话将会被调用。<br><br>不同浏览器可能有不同附属于个别触动事件的行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "touchMoved() 函数将在每次触点移动事件被触发时被调用。如果 touchMoved() 函数并未有被定义,mouseDragged() 函数有被定义的话将会被调用。<br><br>不同浏览器可能有不同附属于个别触动事件的行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "touchEnded() 函数将在每次触动结束时被调用。如果 touchEnded() 函数并未有被定义,mouseReleased() 函数有被定义的话将会被调用。<br><br>不同浏览器可能有不同附属于个别触动事件的行为。以防止这些默认行为发生,只需在函数尾端加 “return false”。"
            +      ],
            +      "params": {
            +        "event": "Object: (Optional) optional TouchEvent callback argument."
            +      }
            +    },
            +    "createImage": {
            +      "description": [
            +        "创造一个新的 p5.Image 物件(储存图像的数据类型)。这将提供一个全新的像素缓冲供您使用。缓冲区的大小将由所提供的宽度和高度参数决定。<br><br>.pixels 将提供一个含有所有像素资料的数组。这些值都为数字。这数组的大小为(同时考虑像素密度)显示窗口的大小 x4,分别代表每个像素由左到右,上到下的 R、G、B、A 值。请参考 .pixels 文献。您也能使用更简单的 set() 或 get()。<br><br>在获取一个图像的像素之前,像素资料必须先使用 loadPixels() 函数加载。在数组资料被修改后,updatePixels() 函数必须被调用以更新图像资料。",
            +        ".<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels in the display window. These values are numbers. This array is the size (including an appropriate factor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for more info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.",
            +        "Before accessing the pixels of an image, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes."
            +      ],
            +      "returns": "p5.Image:p5.Image 物件",
            +      "params": {
            +        "width": "整数:像素宽度",
            +        "height": "整数:像素宽度"
            +      }
            +    },
            +    "saveCanvas": {
            +      "description": [
            +        "将现有的画布储存成图像。In Safari, this will open the image in the window and the user must provide their own filename on save-as. Other browsers will either save the file immediately, or prompt the user with a dialogue window."
            +      ],
            +      "params": {
            +        "selectedCanvas": "p5.Element|HTMLCanvasElement:una variable representando un canvas HTML5 específico (opcional)",
            +        "filename": "字符串",
            +        "extension": "字符串:'jpg' 或 'png'"
            +      }
            +    },
            +    "saveFrames": {
            +      "description": [
            +        "捕捉一系列可用于制作影响的影格图像。接受回调函数。比如说,您可能想要将影格传送至伺服器以方便储存或转变成影像。如果回调函数没有被提供,浏览器将弹出储存文件对话框以尝试下载所有刚被创造的图像。如果提供回调函数,图像资料默认上并不会被储存而是以物件数组的形式被转送至回调函数做参数,数组大小为储存影格的总数。",
            +        "Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation. To export longer animations, you might look into a library like <a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>."
            +      ],
            +      "params": {
            +        "filename": "字符串",
            +        "extension": "字符串:'jpg' 或 'png'",
            +        "duration": "数字:该捕捉的影格的秒数",
            +        "framerate": "数字:捕捉影格的帧率",
            +        "callback": "函数(数组):一个用来处理图像资料的回调函数。此函数将会被给予一个数组为参数。此数组将会储存所定义的捕捉影格物件。每一个物件都会有三个属性:imageData - 为 image/octet-stream 类型、filename 及 extension。"
            +      }
            +    },
            +    "loadImage": {
            +      "description": [
            +        "从被给予的路径加载一个图像并使用其图像创造一个  p5.Image 物件。<br><br>该图像或许不能立刻被渲染,如果您想要保证您在图像加载完毕后才开始做任何事情,您可以将 loadImage() 函数调用在 preload() 里。您也能提供回调函数以在图像加载完毕时处理图像资料。<br><br>图像的路径应该相对于链接您的绘图的 HTML 文件。从其他 URL 或远程位置加载图像可能会被浏览器的内建安全模式阻止。",
            +        "The image may not be immediately available for rendering. If you want to ensure that the image is ready before doing anything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>. You may also supply a callback function to handle the image when it's ready.",
            +        "The path to the image should be relative to the HTML file that links in your sketch. Loading an image from a URL or other remote location may be blocked due to your browser's built-in security.",
            +        "You can also pass in a string of a base64 encoded image as an alternative to the file path. Remember to add \"data:image/png;base64,\" in front of the string."
            +      ],
            +      "returns": "p5.Image:p5.Image 物件",
            +      "params": {
            +        "path": "字符串:欲加载的图像的路径",
            +        "successCallback": "函数(p5.Image):图像加载结束调用的函数。会被给予 p5.Image 做参数。",
            +        "failureCallback": "函数(错误物件):如果图像加载失败此函数将被调用并给予错误物件做参数。"
            +      }
            +    },
            +    "image": {
            +      "description": [
            +        "在 p5 画布上画一个图像。<br><br>此函数能使用几个不同数量的参数。最简单的用法只需要三个参数:img(图像)、x 及 y - (x, y) 为图像的位置。多两个可选参数能用来定义绘制图像的宽度及高度。<br><br>此函数也能使用所有八个数字参数。以分辨所有的参数,p5.js 在以下将使用“终点方形”(应对于 “dx”、“dy” 等)及“原图像”(应对于 “sx”、“sy”等)的名词。提供“原图像”大小可用来显示原图像的一个子部分而不需要显示整个图像。以下图表能解释得更清楚:<img src='assets/drawImage.png'>",
            +        "This function can be used with different numbers of parameters. The simplest use requires only three parameters: img, x, and y—where (x, y) is the position of the image. Two more parameters can optionally be added to specify the width and height of the image.",
            +        "This function can also be used with all eight Number parameters. To differentiate between all these parameters, p5.js uses the language of \"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source image\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the \"source image\" dimensions can be useful when you want to display a subsection of the source image instead of the whole thing. Here's a diagram to explain further: <img src=\"assets/drawImage.png\"></img>"
            +      ],
            +      "params": {
            +        "img": "p5.Image|p5.Element:该显示的图像",
            +        "x": "数字:图像左上角的 x 坐标",
            +        "y": "数字:图像左上角的 y 坐标",
            +        "width": "数字:绘制图像的宽度",
            +        "height": "数字:绘制图像的高度",
            +        "dx": "数字:绘制图像的终点方形的 x 坐标位置",
            +        "dy": "数字:绘制图像的终点方形的 y 坐标位置",
            +        "dWidth": "数字:终点方形的宽度",
            +        "dHeight": "数字:终点方形的高度",
            +        "sx": "数字:该画进终点方形的原图像子部分的 x 坐标",
            +        "sy": "数字:该画进终点方形的原图像子部分的 y 坐标",
            +        "sWidth": "数字:该画进终点方形的原图像子部分的宽度",
            +        "sHeight": "数字:该画进终点方形的原图像子部分的高度"
            +      }
            +    },
            +    "tint": {
            +      "description": [
            +        "定义显示图像的填色值。图像能着色成所定义的颜色或提供透明度值以使其透明化。<br><br>如想是图像透明化但不想影响其颜色,可使用白色为着色值并定义透明度值。比如说,tint(255, 128) 将会使一个图像成为 50% 透明(假设为默认透明度范围 0-255,可使用 colorMode() 调整)。<br><br>灰阶值参数必须低于或等于当时 colorMode() 所定义的最高值。默认最高值为 255。",
            +        "To apply transparency to an image without affecting its color, use white as the tint color and specify an alpha value. For instance, tint(255, 128) will make an image 50% transparent (assuming the default alpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).",
            +        "The value for the gray parameter must be less than or equal to the current maximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is 255."
            +      ],
            +      "params": {
            +        "v1": "数字:红彩值或色调值,需在被定义的范围内",
            +        "v2": "数字:绿彩值或饱和度值,需在被定义的范围内",
            +        "v3": "数字:蓝彩值或亮度值,需在被定义的范围内",
            +        "alpha": "数字:",
            +        "value": "字符串:颜色字符串",
            +        "gray": "数字:灰阶值",
            +        "values": "数字[]:一个有红、绿、蓝及透明度值的数组",
            +        "color": "p5.Color:着色色值"
            +      }
            +    },
            +    "noTint": {
            +      "description": [
            +        "移除当时显示图像的填色值并将其恢复成显示图形的原色调。"
            +      ]
            +    },
            +    "imageMode": {
            +      "description": [
            +        "定义图像模式。更改 image() 解读参数的方式以更改图像开始绘制的位置。默认模式为 imageMode(CORNER),此模式将解读第二及第三个参数为图像的左上角位置。如果加多两个参数,它们则被用来定义图像的宽度和高度。<br><br>imageMode(CORNERS) 将使 image() 函数解读第二及第三个参数为一个角落的位置,而第四个第五个参数为对面角落的位置。<br><br>imageMode(CENTER) 将使 image() 函数解读第二及第三个参数为图像的中心点。如果提供多两个参数,它们将被用来定义图像的宽度和高度。",
            +        "imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the location of one corner, and the fourth and fifth parameters as the opposite corner.",
            +        "imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a> as the image's center point. If two additional parameters are specified, they are used to set the image's width and height."
            +      ],
            +      "params": {
            +        "mode": "常量:CORNER、CORNERS 或 CENTER"
            +      }
            +    },
            +    "pixels": {
            +      "description": [
            +        "此数组为一个储存显示窗口内所有像素值的 Uint8ClampedArray。这些值都为数字。这数组的大小为(同时考虑像素密度)显示窗口的大小 x4,分别代表每个像素由左到右,上到下的 R、G、B、A 值。视网膜显示及其他高密度显示器将会有更多像素(pixelDensity^2 倍)。比如说,如果图像为 100x100 像素,总共会有 40,000 个元素在 pixels[] 数组内。而在一个视网膜显示,将会有 160,000 个元素。<br><br>数组内最初四个值(指数 0-3)将会是在坐标 (0, 0) 的像素的 R、G、B、A 值。下四个值(指数 4-7)将会是在坐标 (1, 0) 的像素的 R、G、B、A 值。一般上,如果要设置像素 (x, y) 的值: <pre>CODE BLOCK PENDING</pre> 虽然以上的方式有点复杂,它能提供足够的弹性以应对任何像素密度的显示。注意 set() 将会自动处理设定所有在任何像素密度下 (x, y) 坐标在 pixels[] 内的值,不过程序性能可能在像素数组被更改很多次时时不佳。<br><br>在使用这个数组之前,像素资料必须先使用 loadPixels() 函数加载。在数组资料被修改后,updatePixels() 函数必须被调用以更新图像资料。<br><br>注意这不是个普通的 Javascript 数组。这表示 Javascript 数组函数如 <code>slice()</code> 或 <code>arrayCopy()</code> 将不会有效果。",
            +        "The first four values (indices 0-3) in the array will be the R, G, B, A values of the pixel at (0, 0). The second four values (indices 4-7) will contain the R, G, B, A values of the pixel at (1, 0). More generally, to set values for a pixel at (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre>",
            +        "While the above method is complex, it is flexible enough to work with any pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of setting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at any pixelDensity, but the performance may not be as fast when lots of modifications are made to the pixel array.",
            +        "Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a> function must be run to update the changes.",
            +        "Note that this is not a standard javascript array. This means that standard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or <a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not work."
            +      ]
            +    },
            +    "blend": {
            +      "description": [
            +        "将一个图像内一个区域的像素复制去另一个图像,同时使用所定义的混合模式执行复制。"
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image:原图像",
            +        "sx": "整数:原图像的左上角 x 坐标",
            +        "sy": "整数:原图像的左上角 y 坐标",
            +        "sw": "整数:原图像的宽度",
            +        "sh": "整数:原图像的高度",
            +        "dx": "整数:终点图像左上角的 x 坐标",
            +        "dy": "整数:终点图像左上角的 y 坐标",
            +        "dw": "整数:终点图像的宽度",
            +        "dh": "整数:终点图像的高度",
            +        "blendMode": "常量:混合模式。BLEND、DARKEST、LIGHTEST、DIFFERENCE、MULTIPLY、EXCLUSION、SCREEN、REPLACE、OVERLAY、HARD_LIGHT、SOFT_LIGHT、DODGE、BURN、ADD 或 NORMAL。"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "将画布内一个区域的像素复制去画布内另外一个区域同时也复制一个由 srcImg 参数所定义的图像内一个区域的像素去定义 srcImage 的画布上,这将是原图像。如果原图像与重点区域的大小不同,它将会自动缩放原图像的像素以符合所定义的终点区域。"
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image:原图像",
            +        "sx": "整数:原图像的左上角 x 坐标",
            +        "sy": "整数:原图像的左上角 y 坐标",
            +        "sw": "整数:原图像的宽度",
            +        "sh": "整数:原图像的高度",
            +        "dx": "整数:终点图像左上角的 x 坐标",
            +        "dy": "整数:终点图像左上角的 y 坐标",
            +        "dw": "整数:终点图像的宽度",
            +        "dh": "整数:终点图像的高度"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "在画布上使用过滤器。<br><br>预设选择为:<br><br>THRESHOLD 将图像转换成黑与白像素,取决于它们是否高于或低于所定义的 level 参数值。参数值必须在 0.0(黑色)与 1.0(白色)之间。如果并没有提供参数的话,默认将设为 0.5。<br><br>GRAY 将图像内的颜色转换成灰阶色。不使用任何参数。<br><br>OPAQUE 设置所有透明度值成完全不透明。不使用任何参数。<br><br>INVERT 设置每个像素成其反值。不使用任何参数。<br><br>POSTERIZE 将限制每个图像的彩色通道至参数所定义的颜色数。参数值可以介于 2 至 255 之间,但是效果会在较低值是比较明显。<br><br>BLUR 将使用 level 参数所定义的模糊度执行高斯模糊。如果没有提供参数,模糊度为高斯模糊半径为 1。越大的值越模糊。<br><br>ERODE 减少亮区。不使用任何参数。<br><br>DILATE 增加亮区。不使用任何参数。",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used.",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used.",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used.",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges.",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur.",
            +        "ERODE Reduces the light areas. No parameter is used.",
            +        "DILATE Increases the light areas. No parameter is used.",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "常量:THRESHOLD、GRAY、OPAQUE、INVERT、POSTERIZE、BLUR、ERODE、DILATE 或 BLUR。",
            +        "filterParam": "数字:每个过滤器独有的可选性参数,请看以上"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "返回任何像素值的一个为 [R,G,B,A] 的数组或捕捉图像的一部分。如果没有提供任何参数,将会返回整个图像。可使用 x 及 y 参数以取得一个像素的值。多加定义 w 及 h 参数可取的显示窗口的一部分。当在取得图像时,x 及 y 参数将定义图像的左上角坐标值,无论当时的图像模式为何。<br><br>如果欲取得的像素在图像外,将返回 [0,0,0,255]。以取得根据当时的颜色值范围及颜色模式的数字,请使用 getColor 而不是 get。<br><br>使用 get(x, y) 以取得一个像素的颜色相对来说简单,但是其速度并没有直接从 pixels[] 数组获取数据来的快。与使用 get(x, y) 有相同的效果但使用 pixels[] 及像素密度 d 的范例如下 <code>var x, y, d; // 设置这为坐标 var off = (y width + x) d * 4; var components = [ pixels[off], pixels[off + 1], pixels[off + 2], pixels[off + 3] ]; print(components);</code><br><br>请参考 pixels[] 文献以知更多详情。",
            +        "Returns an array of [R,G,B,A] values for any pixel or grabs a section of an image. If no parameters are specified, the entire image is returned. Use the x and y parameters to get the value of one pixel. Get a section of the display window by specifying additional w and h parameters. When getting an image, the x and y parameters define the coordinates for the upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.",
            +        "Getting the color of a single pixel with get(x, y) is easy, but not as fast as grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to get(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is <pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates let off = (y * width + x) * d * 4; let components = [  pixels[off],  pixels[off + 1],  pixels[off + 2],  pixels[off + 3] ]; print(components);</code></pre>",
            +        "See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.",
            +        "If you want to extract an array of colors or a subimage from an p5.Image object, take a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a>"
            +      ],
            +      "returns": "数字[]|p5.Image:在 x,y 的像素值数组或 p5.Image",
            +      "params": {
            +        "x": "数字:像素的 x 坐标",
            +        "y": "数字:像素的 y 坐标",
            +        "w": "数字:宽度",
            +        "h": "数字:高度"
            +      }
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "将显示窗口的像素资料加载到 pixels[] 数组里。这函数必须在读写 pixels[] 之前被调用。注意只有使用 set() 或直接修改 pixels[] 的改变会发生。"
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "改变任何像素的颜色,或直接在显示窗口内绘画一个图像。<br><br>x 及 y 参数用于定义该改变的像素而 c 参数用于定义颜色值。这可以是一个 p5.Color 物件或一个 [R, G, B, A] 像素数组。它也能是一个灰阶值。在设定一个图像时,x 及 y 参数将定义图像左上角的坐标值,无论当时的图像模式为何。<br><br>在使用 set() 后,您必须调用 updatePixels() 以使您的改变生效。这应该在所有像素都被设定后才被调用,而且也必须在调用 get() 或绘制图像之前调用。<br><br>使用 set(x, y) 设置一个像素的颜色相对来说简单,但使其速度并没有直接将数据写在 pixels[] 数组里来的快。直接使用 pixels[] 设置像素值可能在使用视网膜显示器时比较复杂,不过它会在每一个循环有很多像素需要被设定时表现得更好。<br><br>请参考 pixels[] 文献以知更多详情。",
            +        "After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear. This should be called once all pixels have been set, and must be called before calling .<a href=\"#/p5/get\">get()</a> or drawing the image.",
            +        "Setting the color of a single pixel with set(x, y) is easy, but not as fast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a> values directly may be complicated when working with a retina display, but will perform better when lots of pixels need to be set directly on every loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information."
            +      ],
            +      "params": {
            +        "x": "数字:像素的 x 坐标",
            +        "y": "数字:像素的 y 坐标",
            +        "c": "数字|数字[]|物件:插入一个灰阶值 | 一个像素数组 | 一个 p5.Color 物件 | 一个用于复制的 p5.Image"
            +      }
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "使用 pixels[] 数组内的资料更新显示窗口。通常与 loadPixels() 一起使用。如果您只需从该数组中读取像素资料,您不需要调用 updatePixels() — 更新只有在进行更改时需要被调用。updatePixels() 应该在像素数组被更改或 set() 被调用时使用,只有使用 set() 或直接修改 pixels[] 的改变会发生。"
            +      ],
            +      "params": {
            +        "x": "数字:欲更新的区域的左上角 x 坐标",
            +        "y": "数字:欲更新的区域的左上角 y 坐标",
            +        "w": "数字:欲更新的区域的宽度",
            +        "h": "数字:欲更新的区域的高度"
            +      }
            +    },
            +    "loadJSON": {
            +      "description": [
            +        "从一个文件或网址加载一个 JSON 文件,将返回一个物件。注意如果该 JSON 文件内涵一个数组,此函数仍然会返回一个以数字为指数的物件。<br><br>这函数为异步进行,这表示它可能不会在您绘图的下一行代码执行前完成。JSONP 功能支持是由填充工具所提供而您可以使用第二个参数来定义一个有 JSON 回调定义的物件,只需跟从这里的<a href='https://github.com/camsong/fetch-jsonp'>指示</a>。",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. JSONP is supported via a polyfill and you can pass in as the second argument an object with definitions of the json callback following the syntax specified <a href=\"https://github.com/camsong/ fetch-jsonp\">here</a>.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "物件:JSON 数据",
            +      "params": {
            +        "path": "字符串:该加载的文件名或网址",
            +        "jsonpOptions": "物件:关于 jsonp 设置的设置物件",
            +        "datatype": "字符串:\"json\" 或 \"jsonp\"",
            +        "callback": "函数:在 loadJSON() 完成后该执行的函数,返回的数据将会是函数第一个参数",
            +        "errorCallback": "函数:在发生错误时该执行的函数,回复将会是函数第一个参数"
            +      }
            +    },
            +    "loadStrings": {
            +      "description": [
            +        "读取一个文件的内容并使用个别字行创造一个字符串数组。如果文件名被用作第一个参数,如以上范例,该文件必须被储存在绘图文件夹内。<br><br>除此之外,该文件也能从本地电脑任何位置加载,只需使用绝对路径(任何在 Unix 及 Linux 内由 / 开始的路径,或在 Windows 内由驱动器符号开始的路径),又或者任何在网络上的文件网址也能用来当作 filename 参数。<br><br>这函数为异步进行,这表示它可能不会在您绘图的下一行代码执行前完成。",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "字符串[]:字符串数组",
            +      "params": {
            +        "filename": "字符串:该加载的文件名或网址",
            +        "callback": "函数:在 loadStrings() 完成后该执行的函数,返回的数组将会是函数第一个参数",
            +        "errorCallback": "函数:在发生错误时该执行的函数,回复将会是函数第一个参数"
            +      }
            +    },
            +    "loadTable": {
            +      "description": [
            +        "读取一个文件的内容并使用其内容创造一个 p5.Table 物件。如果文件名被用作第一个参数,该文件必须被储存在绘图文件夹内。文件名参数也能是一个在网络上的文件的网址。默认上,该文件被假定为以逗号分隔(格式为 CSV)。该表格只会在 ‘header’ 设置被使用时才会寻找标签。<br><br>可使用的设置包括:<ul><li>csv - 将表格解析为逗号分隔值</li><li>tsv - 将表格解析为制表符分隔值</li><li>header - 这表格有标签行</li></ul><br><br>当使用多个设置时,您只需将他们分为个别的参数并使用逗号分隔。例如:<br><br><code>loadTable('my_csv_file.csv', 'csv', 'header'); </code><br><br>所有加载及储存的文件都需使用 UTF-8 编码。<br><br>这函数为异步进行,这表示它可能不会在您绘图的下一行代码执行前完成。在 preload() 内调用 loadTable() 将保证加载工作会在 setup() 及 draw() 被调用前完成<br><br>在 preload() 外,您可以提供一个回调函数以处理加载物件。",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called. Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object:",
            +        "All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "物件:含有数据的 Table 物件",
            +      "params": {
            +        "filename": "字符串:该加载的文件名或网址",
            +        "extension": "String: (Optional) parse the table by comma-separated values \"csv\", semicolon-separated  values \"ssv\", or tab-separated values \"tsv\"",
            +        "header": "String: (Optional) \"header\" to indicate table has header row",
            +        "callback": "函数:在 loadTable() 完成后该执行的函数,返回的 Table 物件将会是函数第一个参数",
            +        "errorCallback": "函数:在发生错误时该执行的函数,回复将会是函数第一个参数"
            +      }
            +    },
            +    "loadXML": {
            +      "description": [
            +        "读取一个文件的内容并使用其内容创造一个 XML 物件。如果文件名被用作第一个参数,该文件必须被储存在绘图文件夹内。<br><br>除此之外,该文件也能从本地电脑任何位置加载,只需使用绝对路径(任何在 Unix 及 Linux 内由 / 开始的路径,或在 Windows 内由驱动器符号开始的路径),又或者任何在网络上的文件网址也能用来当作 filename 参数。<br><br>这函数为异步进行,这表示它可能不会在您绘图的下一行代码执行前完成。在 preload() 内调用 loadTable() 将保证加载工作会在 setup() 及 draw() 被调用前完成<br><br>在 preload() 外,您可以提供一个回调函数以处理加载物件。",
            +        "Alternatively, the file maybe be loaded from anywhere on the local computer using an absolute path (something that starts with / on Unix and Linux, or a drive letter on Windows), or the filename parameter can be a URL for a file found on a network.",
            +        "This method is asynchronous, meaning it may not finish before the next line in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.",
            +        "Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the object.",
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "物件:含有数据的 XML 物件",
            +      "params": {
            +        "filename": "字符串:该加载的文件名或网址",
            +        "callback": "函数:在 loadXML() 完成后该执行的函数,返回的 XML 物件将会是函数第一个参数",
            +        "errorCallback": "函数:在发生错误时该执行的函数,回复将会是函数第一个参数"
            +      }
            +    },
            +    "loadBytes": {
            +      "description": [
            +        "This method is suitable for fetching files up to size of 64MB."
            +      ],
            +      "returns": "物件:一个 ‘bytes’ 属性将为被加载的缓冲区的物件",
            +      "params": {
            +        "file": "字符串:该加载的文件名或网址",
            +        "callback": "函数:在 load() 完成后该执行的函数",
            +        "errorCallback": "函数:在发生错误时该执行的函数"
            +      }
            +    },
            +    "httpGet": {
            +      "description": [
            +        "执行 HTTP GET 请求的函数。如果数据类型(datatype)没有被定义的话,p5 将会尝试根据网址猜返回数据的类型,默认为文字。这和调用 httpDo(path, 'GET') 的效果一样。‘binary’ 数据类型将会返回一个 Blob 物件,而 ‘arrayBuffer’ 数据类型将会返回一个 ArrayBuffer 并可用来创造类型化数组(如 Uint8Array)。"
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "字符串:该加载的文件名或网址",
            +        "datatype": "字符串:\"json\"、\"jsonp\"、\"binary\"、\"arrayBuffer\"、\"xml\"或\"text\"",
            +        "data": "物件|布尔值:与请求一起传送的参数资料",
            +        "callback": "函数:在 httpGet() 完成后该执行的函数,返回的资料物件将会是函数第一个参数",
            +        "errorCallback": "函数:在发生错误时该执行的函数,回复将会是函数第一个参数"
            +      }
            +    },
            +    "httpPost": {
            +      "description": [
            +        "执行 HTTP POST 请求的函数。如果数据类型(datatype)没有被定义的话,p5 将会尝试根据网址猜返回数据的类型,默认为文字。这和调用 httpDo(path, 'POST') 的效果一样。"
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "字符串:该加载的文件名或网址",
            +        "datatype": "字符串:\"json\"、\"jsonp\"、\"xml\" 或 \"text\"。如果不提供此参数,httpPost() 将尝试猜",
            +        "data": "物件|布尔值:与请求一起传送的参数资料",
            +        "callback": "函数:在 httpPost() 完成后该执行的函数,返回的资料物件将会是函数第一个参数",
            +        "errorCallback": "函数:在发生错误时该执行的函数,回复将会是函数第一个参数"
            +      }
            +    },
            +    "httpDo": {
            +      "description": [
            +        "执行 HTTP 请求的函数。如果数据类型(datatype)没有被定义的话,p5 将会尝试根据网址猜返回数据的类型,默认为文字。<br><br>如果需要更高等的使用法,您可以在第一个参数给予路径而第二个参数给予一个物件,物件内容设置与 Fetch API 规范的一样。"
            +      ],
            +      "returns": "Promise: A promise that resolves with the data when the operation  completes successfully or rejects with the error after  one occurs.",
            +      "params": {
            +        "path": "字符串:该加载的文件名或网址",
            +        "method": "字符串:\"GET\"、\"POST\" 或 \"PUT\",默认为 \"GET\"",
            +        "datatype": "字符串:\"json\"、\"jsonp\"、\"xml\" 或 \"text\"",
            +        "data": "物件|布尔值:与请求一起传送的参数资料",
            +        "callback": "函数:在 httpDo() 完成后该执行的函数,返回的资料物件将会是函数第一个参数",
            +        "errorCallback": "函数:在发生错误时该执行的函数,回复将会是函数第一个参数",
            +        "options": "物件:Request 物件,请参考 “fetch” API <a href='https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API'>文献</a>以了解可使用设置"
            +      }
            +    },
            +    "createWriter": {
            +      "returns": "p5.PrintWriter:",
            +      "params": {
            +        "name": "字符串:该创造的文件的名",
            +        "extension": "字符串:"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "储存一个图像、文字、JSON、csv、wav 或 html 文件。将提示客户电脑下载文件。<b>注意 save() 函数不建议在正在循环执行的 draw 函数内使用,因为每一次被调用 save() 函数将会弹出一个储存对话框。</b><br><br>默认上此函数将储存画布成一个图像。您也可以选择定义一个文件名。例如:<pre>CODE BLOCK PENDING</pre>除此之外,第一个参数也能是个画布 p5.Element 的对象、字符串数组、JSON 数组、JSON 物件、p5.Table、p5.Image 或 p5.SoundFile(需要 p5.sound)。第二个参数为文件名(包括扩展名)。第三个参数适用于特别给这一类物件的设定。这函数将会储存一个符合给予的参数的文件。例如:<pre>CODE BLOCK PENDING</pre>"
            +      ],
            +      "params": {
            +        "objectOrFilename": "Object|String: (Optional) If filename is provided, will  save canvas as an image with  either png or jpg extension  depending on the filename.  If object is provided, will  save depending on the object  and filename (see examples  above).",
            +        "filename": "物件|字符串:如果所提供的是文件名,此函数将会使用该文件名加上 png 或 jpg 文件扩展名来储存画布为一个图像。如果所提供的是物件,此函数则会一物件所定义的方式储存文件(请参考以上范例)。",
            +        "options": "布尔值|字符串:依文件类型而定的设定。比如说,在储存 JSON 时,true 表示输出文件将会针对文件大小进行优化,而同时牺牲可读性。"
            +      }
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "将一个数组或 JSON 物件的内容写进一个 .json 文件内。文件的储存方式及地点在不同浏览器之间有所不同。"
            +      ],
            +      "params": {
            +        "json": "数组|物件:",
            +        "filename": "String",
            +        "optimize": "布尔值:如果为 true,将移除输出文件内的换行符及空格以优化文件大小(但牺牲可读性)"
            +      }
            +    },
            +    "saveStrings": {
            +      "description": [
            +        "将一个字符串数组写进一个文字文件内,每一行为每一组字符串。文件的储存方式及地点在不同浏览器之间有所不同。"
            +      ],
            +      "params": {
            +        "list": "字符串[]:该输出的字符串数组",
            +        "filename": "字符串:输出文件的名字",
            +        "extension": "字符串:文件扩展名",
            +        "isCRLF": "Boolean: (Optional) if true, change line-break to CRLF"
            +      }
            +    },
            +    "saveTable": {
            +      "description": [
            +        "将一个表格(Table)物件的内容写进一个文件内。默认将储存为逗号分隔值('csv')的文字文件但也可以使用制表符分隔('tsv')或生成一个 HTML 表格('html')。文件的储存方式及地点在不同浏览器之间有所不同。"
            +      ],
            +      "params": {
            +        "Table": "p5.Table: the <a href=\"#/p5.Table\">Table</a> object to save to a file",
            +        "filename": "字符串:储存表格文件的名字",
            +        "options": "字符串:可以是 \"tsv\"、\"csv\" 或 \"html\""
            +      }
            +    },
            +    "abs": {
            +      "description": [
            +        "计算一个数字的绝对值(大小值)。映射到 Math.abs()。一个数字的绝对值一定是个正数。"
            +      ],
            +      "returns": "数字:被给予数字的绝对值",
            +      "params": {
            +        "n": "数字:用于计算的数字"
            +      }
            +    },
            +    "ceil": {
            +      "description": [
            +        "计算最靠近并大于或等于参数值的整数。映射到 Math.ceil()。比如说,ceil(9.03) 将返回 10。"
            +      ],
            +      "returns": "整数:取整后的数字",
            +      "params": {
            +        "n": "数字:该取整的数字"
            +      }
            +    },
            +    "constrain": {
            +      "description": [
            +        "限制一个数字于最低值与最高值之间。"
            +      ],
            +      "returns": "数字:被限制后的数字",
            +      "params": {
            +        "n": "数字:该限制的数字",
            +        "low": "数字:最低值",
            +        "high": "数字:最高值"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "计算两点之间的距离。"
            +      ],
            +      "returns": "数字:两点之间的距离",
            +      "params": {
            +        "x1": "数字:第一个点的 x 坐标",
            +        "y1": "数字:第一个点的 y 坐标",
            +        "x2": "数字:第二个点的 y 坐标",
            +        "y2": "数字:第一个点的 z 坐标",
            +        "z1": "数字:第二个点的 x 坐标",
            +        "z2": "数字:第二个点的 z 坐标"
            +      }
            +    },
            +    "exp": {
            +      "description": [
            +        "返回欧拉数 e (2.71828...)提升到由参数 n 定义的指数。映射到 Math.exp()。"
            +      ],
            +      "returns": "数字:e^n",
            +      "params": {
            +        "n": "数字:该提升的指数"
            +      }
            +    },
            +    "floor": {
            +      "description": [
            +        "计算最靠近并小于或等于参数值的整数。映射到 Math.floor()。"
            +      ],
            +      "returns": "整数:取整后的数字",
            +      "params": {
            +        "n": "数字:该取整的数字"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "计算一个介于两个数字之间所定义的插值量位置的数字。amt 参数为两个值之间的插值量,0.0 为第一个值,0.1 为非常接近第一个值,0.5 为两者之间等等。lerp 函数可用来沿着直线制作动画及绘制虚线。"
            +      ],
            +      "returns": "数字:插值",
            +      "params": {
            +        "start": "数字:第一个值",
            +        "stop": "数字:第二个值",
            +        "amt": "数字:介于 0.0 与 1.0 之间的数字"
            +      }
            +    },
            +    "log": {
            +      "description": [
            +        "计算一个数字的自然对数(e 为底数的对数)。这函数需要 n 参数大于 0.0。映射到 Math.log()。"
            +      ],
            +      "returns": "数字:n 的自然对数",
            +      "params": {
            +        "n": "Number: number greater than 0"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "计算一个向量的大小(或长度)。向量为一个空间内的方向,通常用于电脑图形及线性代数。因为它没有“开始”位置,一个向量的大小可以被想成是 0,0 坐标与向量 x,y 坐标之间的距离。因此,mag() 是 dist(0, 0, x, y) 的缩写。"
            +      ],
            +      "returns": "数字:从 (0, 0) 至 (a, b) 的向量的大小",
            +      "params": {
            +        "a": "数字:第一个值",
            +        "b": "数字:第二个值"
            +      }
            +    },
            +    "map": {
            +      "description": [
            +        "从一个范围内映射一个数字去另一个范围。<br><br>在以上第一个范例,25 被从 0 至 100 之间的范围映射去窗口最左方 (0) 至最右方 (width) 的范围内。",
            +        "In the first example above, the number 25 is converted from a value in the range of 0 to 100 into a value that ranges from the left edge of the window (0) to the right edge (width)."
            +      ],
            +      "returns": "数字:映射后的数字",
            +      "params": {
            +        "value": "数字:该转换的值",
            +        "start1": "数字:现在值的最低值",
            +        "stop1": "数字:现在值的最高值",
            +        "start2": "数字:目标值的最低值",
            +        "stop2": "数字:目标值的最高值",
            +        "withinBounds": "布尔值:限制目标值在最高及最低值之间"
            +      }
            +    },
            +    "max": {
            +      "description": [
            +        "找出一系列数字中最大的值,并返回该值。max() 能接受任何数量的数字参数,或是一个任何大小的数组。"
            +      ],
            +      "returns": "数字:最高值的数字",
            +      "params": {
            +        "n0": "数字:用于比较的数字",
            +        "n1": "数字:用于比较的数字",
            +        "nums": "Number[]: Numbers to compare"
            +      }
            +    },
            +    "min": {
            +      "description": [
            +        "找出一系列数字中最小的值,并返回该值。min() 能接受任何数量的数字参数,或是一个任何大小的数组。"
            +      ],
            +      "returns": "数字:最低值的数字",
            +      "params": {
            +        "n0": "数字:用于比较的数字",
            +        "n1": "数字:用于比较的数字",
            +        "nums": "Number[]: Numbers to compare"
            +      }
            +    },
            +    "norm": {
            +      "description": [
            +        "将一个数字由一个范围标准化成介于 0 及 1 之间的值。与 map(value, low, high, 0, 1) 的效果相同。在范围外的数字将不会被限制在 0 与 1 之间,因为范围外的值通常是有意及有用的。(参考以上第二个范例)"
            +      ],
            +      "returns": "数字:标准化后的数字",
            +      "params": {
            +        "value": "数字:该标准化的值",
            +        "start": "数字:现在值的最低值",
            +        "stop": "数字:现在值的最高值"
            +      }
            +    },
            +    "pow": {
            +      "description": [
            +        "执行幂运算。pow() 函数是个能有效率地将数字大量乘于自己(或其倒数)的方式。比如说,pow(3, 5) 等同于 3*3*3*3*3 而 pow(3, -5) 等同于 1 / (3*3*3*3*3)。映射到 Math.pow()。"
            +      ],
            +      "returns": "数字:n^e",
            +      "params": {
            +        "n": "数字:幂运算的底数",
            +        "e": "数字:幂运算的指数"
            +      }
            +    },
            +    "round": {
            +      "description": [
            +        "计算最靠近 n 参数的整数。比如说,round(133.8) 将返回 134。映射到 Math.round()。"
            +      ],
            +      "returns": "整数:取整后的数字",
            +      "params": {
            +        "n": "数字:该取整的数字",
            +        "decimals": "Number: (Optional) number of decimal places to round to, default is 0"
            +      }
            +    },
            +    "sq": {
            +      "description": [
            +        "平方一个数字(将数字乘于自己)。结果一定是个正数,因为将两个负数相乘一定会有一个正数结果。比如说 -1 * -1 = 1。"
            +      ],
            +      "returns": "数字:平方后的数字",
            +      "params": {
            +        "n": "数字:该平方的数字"
            +      }
            +    },
            +    "sqrt": {
            +      "description": [
            +        "计算一个数字的平方根。一个数字的平方根一定是个正数,虽然也可能有正确的负数平方根。一个数字 a 的平方根 s 有以下属性 s*s = a。此函数为取平方的相反。映射到 Math.sqrt()。"
            +      ],
            +      "returns": "数字:取平方根后的数字",
            +      "params": {
            +        "n": "数字:该取平方根的非负数"
            +      }
            +    },
            +    "fract": {
            +      "description": [
            +        "Calculates the fractional part of a number."
            +      ],
            +      "returns": "Number: fractional part of x, i.e, {x}",
            +      "params": {
            +        "num": "Number: Number whose fractional part needs to be found out"
            +      }
            +    },
            +    "createVector": {
            +      "description": [
            +        "创造一个新的 p5.Vector 向量(用以储存向量的数据类型)。此函数将提供一个二维或三维的向量,准确来说一个欧几里得(也称为几何)向量。向量为一个有大小及方向的量。"
            +      ],
            +      "returns": "p5.Vector",
            +      "params": {
            +        "x": "数字:该向量的 x 分量",
            +        "y": "数字:该向量的 y 分量",
            +        "z": "数字:该向量的 z 分量"
            +      }
            +    },
            +    "noise": {
            +      "description": [
            +        "返回所定义坐标的柏林噪声值。柏林噪声是个用来生成比 random() 所能生成更自然及更谐波的随机数字系列。在 1980 年代有 Ken Perlin 所发明,柏林噪声至今常被用在图形应用程序中生成程序纹理、自然运动、形状、地形等等。<br><br>柏林噪声与 random() 函数最主要的不同点在于前者是在一个无限的 n 维空间内定义的,这空间内每一对坐标都相对于一个固定的半随机值(只有在程序进行时为固定的;请参考 noiseSeed() 函数)。p5.js 能计算 1 维、2 维及 3 维噪声,这取决于所给予的坐标数。返回的值一定会在 0.0 至 1.0 之间。噪音值可以通过在噪音空间内移动以制成动画,如以上范例所示。第二及第三个空间维度也能被解读成时间。<br><br>所生成的噪音结构上和一般音频信号相似,尤其是此函数的频率。与物理学上谐波的概念相似,泊林噪音也是在计算几个八度后再将其结果加起来以得到最后的结果。<br><br>另外一个控制返回随机数系列的特征的方法是控制输入坐标值的大小。因为此函数能在无限之的空内内应用,输入坐标的值并不重要,只有个别坐标之间的距离需要被注意(如在循环内使用 noise() 时)。一般来说坐标之间的距离越小,生成噪声随机数列将会越平滑。介于 0.005-0.03 之间的距离应该适合大多数应用场合,不过这可能因应用需求而变。"
            +      ],
            +      "returns": "数字:柏林噪声在特定坐标的值(介于 0 与 1 之间)",
            +      "params": {
            +        "x": "数字:噪声空间的 x 坐标",
            +        "y": "数字:噪声空间的 y 坐标",
            +        "z": "数字:噪声空间的 z 坐标"
            +      }
            +    },
            +    "noiseDetail": {
            +      "description": [
            +        "调整柏林噪声函数所生成的噪声特征及细节度。与物理学上谐波的概念相似,泊林噪音也是在计算几个八度后才得到最后的结果。越低的八度将会影响输出信号值越多因此同时会定义噪音的整体强度,而较高的八度将会在噪音系列中制作更精细的细节。<br><br>默认上,此噪音将使用四个八度计算而每个八度将有其前者一半的影响力,第一个八度的影响力为 50% 。这衰退值能通过加多一个参数而改变。比如说如果衰退因数为 0.75 那表示每个八度将会有其前者的 75% 的影响力(减少 25%)。任何介于 0.0 与 1.0 的值都能被接受,不过注意高于 0.5 的值可能会造成 noise() 函数会返回大于 1.0 的值。<br><br>通过改变这些参数,noise() 函数所生成的信号可适应于非常特别的需求或特点。"
            +      ],
            +      "params": {
            +        "lod": "数字:噪音该使用的八度数",
            +        "falloff": "数字:每个八度的衰退因数"
            +      }
            +    },
            +    "noiseSeed": {
            +      "description": [
            +        "定义 noise() 使用的随机种子值。默认上,noise() 将在每一次改程序被执行时生成不同的结果。只需定义 value 参数至一个常量就能确保每一次软件执行时都会返回一样的随机数列。"
            +      ],
            +      "params": {
            +        "seed": "数字:随机种子值"
            +      }
            +    },
            +    "randomSeed": {
            +      "description": [
            +        "定义 random() 使用的随机种子值。<br><br>默认上,random() 将在每一次改程序被执行时生成不同的结果。只需定义 seed 参数至一个常量就能确保每一次软件执行时都会返回一样的伪随机数。",
            +        "By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program is run. Set the seed parameter to a constant to return the same pseudo-random numbers each time the software is run."
            +      ],
            +      "params": {
            +        "seed": "数字:随机种子值"
            +      }
            +    },
            +    "random": {
            +      "description": [
            +        "返回一个随机的浮点数。<br><br>可使用 0、1 或 2 个参数。<br><br>如果并没有定义任何参数,将返回一个介于 0 与 1(但不包括 1)的随机数。<br><br>如果只定义一个参数并且该参数为数字,将返回一个介于 0 与 该数字(但不包括该数字)的随机数。<br><br>如果值定义一个参数并且该参数为数组,将返回该数组中随机一个元素。<br><br>如果定义两个参数,将返回一个介于第一个参数与第二个参数(但不包括第二个参数)的随机数。",
            +        "Takes either 0, 1 or 2 arguments.",
            +        "If no argument is given, returns a random number from 0 up to (but not including) 1.",
            +        "If one argument is given and it is a number, returns a random number from 0 up to (but not including) the number.",
            +        "If one argument is given and it is an array, returns a random element from that array.",
            +        "If two arguments are given, returns a random number from the first argument up to (but not including) the second argument."
            +      ],
            +      "returns": "数字:随机数",
            +      "params": {
            +        "min": "数字:最低值(包括此值)",
            +        "max": "数字:最高值(不包括此值)",
            +        "choices": "数组:供选择的数组"
            +      }
            +    },
            +    "randomGaussian": {
            +      "description": [
            +        "返回一个符合高斯,或正态,分布的随机数。理论上 randomGaussian() 没有最高或最低返回值。不过,差均值很多的值被返回的机率将会很低;而接近均质的值被返回的机率将会相对较高。<br><br>可使用 0、1 或 2 个参数。<br>如果并没有定义任何参数,将使用均值为 0 与 标准差为 1。<br>如果只定义一个参数,该参数将为均值(标准差为 1)。<br>如果定义两个参数,第一个参数为均值,第二个参数为标准差。"
            +      ],
            +      "returns": "数字:随机数",
            +      "params": {
            +        "mean": "数字:均值",
            +        "sd": "数字:标准偏差"
            +      }
            +    },
            +    "acos": {
            +      "description": [
            +        "cos() 的反值,将返回一个值的反余弦值。此函数接受介于 -1 与 1 之间的值并将返回介于 0 与 PI(3.1415927)之间的值。"
            +      ],
            +      "returns": "数字:该值的反余弦值",
            +      "params": {
            +        "value": "数字:该取反余弦值的值"
            +      }
            +    },
            +    "asin": {
            +      "description": [
            +        "sin() 的反值,将返回一个值的反正弦值。此函数接受介于 -1 与 1 之间的值并将返回介于 -PI/2 与 PI/2 之间的值。"
            +      ],
            +      "returns": "数字:该值的反正弦值",
            +      "params": {
            +        "value": "数字:该取反正弦值的值"
            +      }
            +    },
            +    "atan": {
            +      "description": [
            +        "tan() 的反值,将返回一个值的反正切值。此函数接受介于 -Infinity 与 Infinity(包括 Infinity)之间的值并将返回介于 -PI/2 与 PI/2 之间的值。"
            +      ],
            +      "returns": "数字:该值的反正切值",
            +      "params": {
            +        "value": "数字:该取反正切值的值"
            +      }
            +    },
            +    "atan2": {
            +      "description": [
            +        "计算从一个被定义的点到坐标原点的弧度,并由正 x 轴开始计算。将返回介于 PI 与 -PI 之间的浮点数。atan2() 函数通常用于定向几何图形至鼠标的位置。<br><br>注意:第一个参数为 y 坐标,而第二个参数为 x 坐标,这是为了适应计算正切值的结构。",
            +        "Note: The y-coordinate of the point is the first parameter, and the x-coordinate is the second parameter, due the the structure of calculating the tangent."
            +      ],
            +      "returns": "数字:该点的反正切值",
            +      "params": {
            +        "y": "数字:该点的 y 坐标",
            +        "x": "数字:该点的 x 坐标"
            +      }
            +    },
            +    "cos": {
            +      "description": [
            +        "计算一个角度的余弦值。此函数将使用当时的角度模式。返回值将介于 -1 与 1 之间的值。"
            +      ],
            +      "returns": "数字:该角度的余弦值",
            +      "params": {
            +        "angle": "数字:角度"
            +      }
            +    },
            +    "sin": {
            +      "description": [
            +        "计算一个角度的正弦值。此函数将使用当时的角度模式。返回值将介于 -1 与 1 之间的值。"
            +      ],
            +      "returns": "数字:该角度的正弦值",
            +      "params": {
            +        "angle": "数字:角度"
            +      }
            +    },
            +    "tan": {
            +      "description": [
            +        "计算一个角度的正切值。此函数将使用当时的角度模式。返回值将介于 -1 与 1 之间的值。"
            +      ],
            +      "returns": "数字:该角度的正切值",
            +      "params": {
            +        "angle": "数字:角度"
            +      }
            +    },
            +    "degrees": {
            +      "description": [
            +        "将一个弧度值转换成其相对的角度值。弧度和角度为两个测量同样一个东西的方法。一个圆形里有 360 度而也有 2*PI 个弧度。比如说,90° = PI/2 = 1.5707964。此函数将不会使用当时的角度模式。"
            +      ],
            +      "returns": "数字:转换后的角度值",
            +      "params": {
            +        "radians": "数字:由弧度转换成角度的值"
            +      }
            +    },
            +    "radians": {
            +      "description": [
            +        "将一个角度值转换成其相对的弧度值。弧度和角度为两个测量同样一个东西的方法。一个圆形里有 360 度而也有 2*PI 个弧度。比如说,90° = PI/2 = 1.5707964。此函数将不会使用当时的角度模式。"
            +      ],
            +      "returns": "数字:转换后的角度值",
            +      "params": {
            +        "degrees": "数字:由角度转换成弧度的值"
            +      }
            +    },
            +    "angleMode": {
            +      "description": [
            +        "定义当时 p5 的角度模式。默认模式为 RADIANS(弧度)。"
            +      ],
            +      "params": {
            +        "mode": "常量:RADIANS 或 DEGREES"
            +      }
            +    },
            +    "textAlign": {
            +      "description": [
            +        "定义绘制问题的对齐方向。使用两个参数:horizAlign(LEFT、CENTER 或 RIGHT)及 vertAlign(TOP、BOTTOM、CENTER 或 BASELINE)。<br><br>horizAlign 参数为 text() 函数的 x 值,而 vertAlign 参数为 y 值。<br><br>因此如果您使用 textAlign(LEFT),您将会使文字最左方对齐 text() 函数所使用的 x 参数。如果您使用 textAlign(RIGHT, TOP),您将会使文字最右方对齐 x 值而文字最上方对齐 y 值。",
            +        "The horizAlign parameter is in reference to the x value of the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter is in reference to the y value.",
            +        "So if you write textAlign(LEFT), you are aligning the left edge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>. If you write textAlign(RIGHT, TOP), you are aligning the right edge of your text to the x value and the top of edge of the text to the y value."
            +      ],
            +      "params": {
            +        "horizAlign": "常量:水平对齐,LEFT、CENTER 或 RIGHT",
            +        "vertAlign": "常量:垂直对齐,TOP、BOTTOM、CENTER 或 BASELINE"
            +      }
            +    },
            +    "textLeading": {
            +      "description": [
            +        "定义或获取行与行之间的像素距离。此设置将会在所有接下来的 text() 函数调用时生效。"
            +      ],
            +      "params": {
            +        "leading": "数字:行与行之间的像素距离"
            +      }
            +    },
            +    "textSize": {
            +      "description": [
            +        "定义或获取当时的字体大小。这大小将会在所有接下来的 text() 函数调用时生效。字形大小是使用像素定义。"
            +      ],
            +      "params": {
            +        "theSize": "数字:字体的像素大小"
            +      }
            +    },
            +    "textStyle": {
            +      "description": [
            +        "定义或获取系统字体的风格,可以是 NORMAL、ITALIC 或 BOLD。注意:这可能被 CSS 风格所覆盖。至与非系统字体(opentype、truetype 等)请直接加载已风格化的字体。"
            +      ],
            +      "params": {
            +        "theStyle": "常量:字体的风格,可以是 NORMAL、ITALIC 或 BOLD"
            +      }
            +    },
            +    "textWidth": {
            +      "description": [
            +        "计算及返回任何字符或字符串的宽度。"
            +      ],
            +      "returns": "数字",
            +      "params": {
            +        "theText": "字符串:该测量的字符串"
            +      }
            +    },
            +    "textAscent": {
            +      "description": [
            +        "返回当时字体在当时所定的大小的整体高度。这高度代表从基准线算起至最高字体的顶点的距离。"
            +      ],
            +      "returns": "数字"
            +    },
            +    "textDescent": {
            +      "description": [
            +        "返回当时字体在当时所定的大小的下端线高度。"
            +      ],
            +      "returns": "数字"
            +    },
            +    "textWrap": {
            +      "description": [
            +        "Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.",
            +        "WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.",
            +        "CHAR wrap style breaks lines wherever needed to stay within the text box.",
            +        "WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen."
            +      ],
            +      "returns": "String: wrapStyle",
            +      "params": {
            +        "wrapStyle": "Constant: text wrapping style, either WORD or CHAR"
            +      }
            +    },
            +    "loadFont": {
            +      "description": [
            +        "从一个文件或网址加载一个 opentype 字形文件(.otf、.ttf),将返回一个 p5.Font 物件。这函数为异步进行,这表示它可能不会在您绘图的下一行代码执行前完成。<br><br>字形的路径应该相对于链接您的绘图的 HTML 文件。从其他 URL 或远程位置加载字形可能会被浏览器的内建安全模式阻止。",
            +        "The path to the font should be relative to the HTML file that links in your sketch. Loading fonts from a URL or other remote location may be blocked due to your browser's built-in security."
            +      ],
            +      "returns": "p5.Font:p5.Font 物件",
            +      "params": {
            +        "path": "字符串:该加载的字形名字或网址",
            +        "callback": "函数:在 loadFont() 完成后该调用的函数",
            +        "onError": "函数:在发生错误时该调用的函数"
            +      }
            +    },
            +    "text": {
            +      "description": [
            +        "将文字绘制在荧幕上。显示第一个参数内的资料在荧幕上由其他参数所定义的位置。将会使用默认字形除非使用 textFont() 函数定义使用其他字形同时也将使用默认大小除非使用 textSize() 定义文字大小。文字的颜色可使用 fill() 函数定义。可使用 stroke() 及 strokeWeight() 函数添加文字外形线。<br><br>文字显示将位于 textAlign() 函数所定义的位置,您可将文字绘制在坐标的左边、右边或中间。<br><br>x2 及 y2 参数将定义一个方形文字显示区而且只适用于字符串资料类型。当这两个参数被定义时,它们将使用当时的 rectMode() 设置被解读。不符合方形大小的文字将不会被绘制在荧幕上。",
            +        "The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a> function, which gives the option to draw to the left, right, and center of the coordinates.",
            +        "The x2 and y2 parameters define a rectangular area to display within and may only be used with string data. When these parameters are specified, they are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a> setting. Text that does not fit completely within the rectangle specified will not be drawn to the screen. If x2 and y2 are not specified, the baseline alignment is the default, which means that the text will be drawn upwards from x and y.",
            +        "<b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font using the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above). <a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode."
            +      ],
            +      "params": {
            +        "str": "字符串|物件|数组|数字|布尔值:该显示的字母数字符号",
            +        "x": "数字:文字的 x 坐标",
            +        "y": "数字:文字的 y 坐标",
            +        "x2": "数字:默认上,文字格的宽度,请参考 rectMode()",
            +        "y2": "数字:默认上,文字格的高度,请参考 rectMode()"
            +      }
            +    },
            +    "textFont": {
            +      "description": [
            +        "定义使用 text() 函数绘制文字时该使用的字形。",
            +        "<b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported."
            +      ],
            +      "returns": "Object: the current font",
            +      "params": {
            +        "font": "物件|字符串:一个使用 loadFont() 加载的字形,或一个代表 Web 安全字体(一个所有系统都通用的字形)的字符串",
            +        "size": "数字:字形大小"
            +      }
            +    },
            +    "append": {
            +      "description": [
            +        "弃用:append() 已被弃用并将会在未来的 p5 版本中移除。请改用 <a href='https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/push'>array.push(value)</a>。<br><br>在数组的尾端增加一个值。将增加数组的一个大小。映射到 Array.push()。"
            +      ],
            +      "returns": "Array: the array that was appended to",
            +      "params": {
            +        "array": "数组:该附加到的数组",
            +        "value": "任何:该附加进数组的元素"
            +      }
            +    },
            +    "arrayCopy": {
            +      "description": [
            +        "弃用:arrayCopy() 已被弃用并将会在未来的 p5 版本中移除。<br><br>复制一个数组(或该数组的一部分)去另外一个数组。src 数组将会被复制去 dst 数组,开端位置由 srcPosition 参数定义并复制进由 dstPosition 定义的位置。该复制的元素数量由 length 参数定义。注意在复制元素时该元素将覆盖终点数组原有的元素。如果想要添加元素,请使用 use concat()。<br><br>简化版本将只使用两个参数:arrayCopy(src, dst) 将复制整个数组去另一个相同大小的数组。这等同于使用 arrayCopy(src, 0, dst, 0, src.length)。<br><br>使用这函数将比使用 for 循环数组内每一个元素并一一复制来的更有效率。",
            +        "The simplified version with only two arguments, arrayCopy(src, dst), copies an entire array to another of the same size. It is equivalent to arrayCopy(src, 0, dst, 0, src.length).",
            +        "Using this function is far more efficient for copying array data than iterating through a for() loop and copying each element individually."
            +      ],
            +      "params": {
            +        "src": "数组:原数组",
            +        "srcPosition": "数字:在原数组内的开端指数",
            +        "dst": "数组:终点数组",
            +        "dstPosition": "数字:在终点数组内的开端指数",
            +        "length": "数字:该复制的元素量"
            +      }
            +    },
            +    "concat": {
            +      "description": [
            +        "弃用:concat() 已被弃用并将会在未来的 p5 版本中移除。请改用 <a href='https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/concat'>arr1.concat(arr2)</a>。<br><br>串接两个数组,映射到 Array.concat()。将不会修改原有数组。"
            +      ],
            +      "returns": "数组:串接后的数组",
            +      "params": {
            +        "a": "数组:串接的第一个数组",
            +        "b": "数组:串接的第二个数组"
            +      }
            +    },
            +    "reverse": {
            +      "description": [
            +        "弃用:reverse() 已被弃用并将会在未来的 p5 版本中移除。请改用 <a href='https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse'>array.reverse()</a>。<br><br>倒转数组内元素的次序,映射到 Array.reverse()。"
            +      ],
            +      "returns": "Array: the reversed list",
            +      "params": {
            +        "list": "数组:该倒转的数组"
            +      }
            +    },
            +    "shorten": {
            +      "description": [
            +        "弃用:shorten() 已被弃用并将会在未来的 p5 版本中移除。请改用 <a href='https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/pop'>array.pop()</a>。<br><br>将数组减少一个元素并返回缩短后的数组,映射到 Array.pop()。"
            +      ],
            +      "returns": "数组:缩短后的数组",
            +      "params": {
            +        "list": "数组:该缩短的数组"
            +      }
            +    },
            +    "shuffle": {
            +      "description": [
            +        "弃用:shuffle() 已被弃用并将会在未来的 p5 版本中移除。请参考<a hreh='https://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array'>使用 Javascript 混洗数组</a>(英文页面)。<br><br>随机排列数组内的元素。使用 Fisher-Yates 混洗函数。"
            +      ],
            +      "returns": "数组:混洗后的数组",
            +      "params": {
            +        "array": "数组:该混洗的数组",
            +        "bool": "布尔值:修改所给予的数组"
            +      }
            +    },
            +    "sort": {
            +      "description": [
            +        "弃用:sort() 已被弃用并将会在未来的 p5 版本中移除。请改用 <a href='https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort'>array.sort()</a>。<br><br>将一个含有数字的数组有最小到最大值重新排列,或将一个含有文字的数组依字母顺序排列。原数组将不会被修改,而将会返回重新排列后的数组。count 参数定义该排列的元素量。比如说,如果数组内有 12 个元素而 count 被设为 5,只有数组内前五个元素将会被排列。"
            +      ],
            +      "returns": "Array: the sorted list",
            +      "params": {
            +        "list": "数组:该排列的数组",
            +        "count": "整数:该排列的元素数,由 0 开始"
            +      }
            +    },
            +    "splice": {
            +      "description": [
            +        "弃用:splice() 已被弃用并将会在未来的 p5 版本中移除。请改用 <a href='https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/splice'>array.splice()</a>。<br><br>在一个原有的数组内添加一个值或另一数组的值。第一个参数定义该修改的数组,而第二个参数定义该添加的资料。第三个参数为该添加元素的位置的数组指数。(记得数组指数从零开始,因此第一个位置为 0,而第二的位置为 1 等等。)"
            +      ],
            +      "returns": "Array: the list",
            +      "params": {
            +        "list": "数组:拼接进的数组",
            +        "value": "任何:欲拼接进数组的值",
            +        "position": "整数:数组内该添加该元素的位置"
            +      }
            +    },
            +    "subset": {
            +      "description": [
            +        "弃用:subset() 已被弃用并将会在未来的 p5 版本中移除。请改用 <a href='https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice'>array.slice()</a>。<br><br>从一个现有的数组中提取一数组的元素。list 参数定义该复制提取元素的数组,而 start 及 count 参数定义该提取哪一些元素。如果没有提供 count 参数,那将会提取数组由开头到结尾的元素。在定义 start 参数时,记得数组第一个指数为 0。这函数将不会修改原数组。"
            +      ],
            +      "returns": "数组:提取出来的元素数组",
            +      "params": {
            +        "list": "数组:该提取元素的数组",
            +        "start": "整数:开始位置",
            +        "count": "整数:提取元素数"
            +      }
            +    },
            +    "float": {
            +      "description": [
            +        "将一个字符串转换成其浮点值。字符串内内容必须是数字,不然将返回 NaN(不是数字)。比如说,float(\"1234.56\") 将返回 1234.56,但 float(\"giraffe\") 将返回 NaN。<br><br>当给予一数组的值时,将返回一个等同大小的浮点数组。",
            +        "When an array of values is passed in, then an array of floats of the same length is returned."
            +      ],
            +      "returns": "数字:该字符串的浮点值",
            +      "params": {
            +        "str": "字符串:该解析的浮点字符串"
            +      }
            +    },
            +    "int": {
            +      "description": [
            +        "转换一个布尔值、字符串或浮点值成其整数值。当给予一数组的值时,将返回一个等同大小的整数数组。"
            +      ],
            +      "returns": "数字:该值的整数值",
            +      "params": {
            +        "n": "字符串|布尔值|数字:该解析的值",
            +        "radix": "整数:该转换成的基数",
            +        "ns": "数组:该解析的值"
            +      }
            +    },
            +    "str": {
            +      "description": [
            +        "转换一个布尔值、字符串或数字成其字符串值。当给予一数组的值时,将返回一个等同大小的字符串数组。"
            +      ],
            +      "returns": "字符串:该值的字符串值",
            +      "params": {
            +        "n": "字符串|布尔值|数字|数组:该解析的值"
            +      }
            +    },
            +    "byte": {
            +      "description": [
            +        "转换一个数字、代表数字的字符串或布尔值成其字节值.一个字节只能是一个介于 -128 与 127 之间的整数,因此如果在这范围外的值被转换时,它将会绕回相对的字节值。当给予一数组的数字、字符串或布尔值时,将返回一个等同大小的字节数组。"
            +      ],
            +      "returns": "数字:该值的字节值",
            +      "params": {
            +        "n": "字符串|布尔值|数字:该解析的值",
            +        "ns": "数组:该解析的值"
            +      }
            +    },
            +    "char": {
            +      "description": [
            +        "转换一个数字或字符串成其单一字符的值。如果提供一个字符串参数,它将会先被解析成整数然后再被转换成单一字符。当给予一数组的数字或字符串时,将返回一个等同大小的单一字符数组。"
            +      ],
            +      "returns": "字符串:该值的字符串值",
            +      "params": {
            +        "n": "字符串|数字:该解析的值",
            +        "ns": "数组:该解析的值"
            +      }
            +    },
            +    "unchar": {
            +      "description": [
            +        "转换一个单一字符成其整数值。当给予一数组的单一字符值时,将返回一个等同大小的整数数组。"
            +      ],
            +      "returns": "数字:该值的整数值",
            +      "params": {
            +        "n": "字符串:该解析的值",
            +        "ns": "数组:该解析的值"
            +      }
            +    },
            +    "hex": {
            +      "description": [
            +        "转换一个数字成其十六进制值的字符串。如果提供第二个参数,它将被用来定义该生成的十六进制值的字符量。当给予一数组时,将返回一个等同大小的十六进制字符串数组。"
            +      ],
            +      "returns": "字符串:该值的十六进制值",
            +      "params": {
            +        "n": "数字:该解析的值",
            +        "digits": "数字",
            +        "ns": "数字[]:该解析的值"
            +      }
            +    },
            +    "unhex": {
            +      "description": [
            +        "转换一个十六进制字符串成其整数值。当给予一数组的十六进制字符串时,将返回一个等同大小的整数数组。"
            +      ],
            +      "returns": "数字:该十六进制值的整数值",
            +      "params": {
            +        "n": "数字:该解析的值",
            +        "ns": "数组:该解析的值"
            +      }
            +    },
            +    "join": {
            +      "description": [
            +        "将一数组的字符串合成一个字符串,每一个元素由 separator 参数定义的字符分隔开。如果要连接整数或浮点数数组,它们必须先使用 nf() 或 nfs() 转换成字符串。"
            +      ],
            +      "returns": "字符串:连接后的字符串",
            +      "params": {
            +        "list": "数组:该连接的字符串",
            +        "separator": "字符串:在个元素之间穿插的字符串"
            +      }
            +    },
            +    "match": {
            +      "description": [
            +        "这函数可被用来在一段文字上应用正则表达式,并将返回含有符合表达式的组合(在括号内的元素)的字符串数组。如果没找到任何匹配组合,将返回 null。如果正则表达式内没有定义任何组合,但有搜寻到匹配序列,将返回一个大小为 1 的数组(匹配的文字为数组的第一个元素)。<br><br>使用此函数时,先查看结果是否为 null。如果结果为 null,那表示该段文字没有匹配序列。如果有找到匹配序列,将返回一个数组。<br><br>如果正则表达式内有组合(由括号定义),那个别内容将会以数组的形式返回。正则表达式匹配返回的元素 [0] 将会是整个匹配的字符串,而匹配组合将从元素 [1] 开始(第一组为 [1]、第二组为 [2] 等)。",
            +        "To use the function, first check to see if the result is null. If the result is null, then the sequence did not match at all. If the sequence did match, an array is returned.",
            +        "If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Element [0] of a regular expression match returns the entire matching string, and the match groups start at element [1] (the first group is [1], the second [2], and so on)."
            +      ],
            +      "returns": "数组:搜寻到的字符串数组",
            +      "params": {
            +        "str": "字符串:在此字符串内搜寻",
            +        "regexp": "字符串:用于搜寻的正则表达式"
            +      }
            +    },
            +    "matchAll": {
            +      "description": [
            +        "这函数可被用来在一段文字上应用正则表达式,并将返回含有符合表达式的组合(在括号内的元素)的二维字符串数组。如果没找到任何匹配组合,将返回 null。如果正则表达式内没有定义任何组合,但有搜寻到匹配序列,仍然将返回一个二维数组,但第二维度数组的大小将为一。<br><br>使用此函数时,先查看结果是否为 null。如果结果为 null,那表示该段文字没有匹配序列。如果有找到匹配序列,将返回一个二维数组。<br><br>如果正则表达式内有组合(由括号定义),那个别内容将会以数组的形式返回。假设有一个有计算其变量 i 的循环,正则表达式匹配返回的元素 [i][0] 将会是整个匹配的字符串,而匹配组合将从元素 [i][1] 开始(第一组为 [i][1]、第二组为 [i][2] 等)。",
            +        "To use the function, first check to see if the result is null. If the result is null, then the sequence did not match at all. If the sequence did match, a 2D array is returned.",
            +        "If there are groups (specified by sets of parentheses) in the regular expression, then the contents of each will be returned in the array. Assuming a loop with counter variable i, element [i][0] of a regular expression match returns the entire matching string, and the match groups start at element [i][1] (the first group is [i][1], the second [i][2], and so on)."
            +      ],
            +      "returns": "字符串[]:搜寻到的二维字符串数组",
            +      "params": {
            +        "str": "字符串:在此字符串内搜寻",
            +        "regexp": "字符串:用于搜寻的正则表达式"
            +      }
            +    },
            +    "nf": {
            +      "description": [
            +        "用于将数字格式化成字符串的辅助函数。此函数有两个版本:一个用于格式化浮点数,另一个用于格式化整数。参数 left 及 right 的值必须是正整数。"
            +      ],
            +      "returns": "字符串:格式化后的字符串",
            +      "params": {
            +        "num": "数字|字符串:该格式化的数字",
            +        "left": "整数|字符串:小数点左边的位数",
            +        "right": "整数|字符串:小数点右边的位数",
            +        "nums": "数组:该格式化的数字"
            +      }
            +    },
            +    "nfc": {
            +      "description": [
            +        "用于将数字格式化成字符串并在适当的地方添加逗号以示意 1000 位的辅助函数。此函数有两个版本:一个用于格式化整数,另一个用于格式化一数组的整数。参数 right 的值必须是正整数。"
            +      ],
            +      "returns": "字符串:格式化后的字符串",
            +      "params": {
            +        "num": "数字|字符串:该格式化的数字",
            +        "right": "整数|字符串:小数点左边的位数",
            +        "nums": "数组:该格式化的数字"
            +      }
            +    },
            +    "nfp": {
            +      "description": [
            +        "用于将数字格式化成字符串的辅助函数。与 nf() 相似但会在正数前加个 \"+\" 号而在负数前加个 \"-\" 号。此函数有两个版本:一个用于格式化浮点数,另一个用于格式化整数。参数 left 及 right 的值必须是正整数。"
            +      ],
            +      "returns": "字符串:格式化后的字符串",
            +      "params": {
            +        "num": "数字|字符串:该格式化的数字",
            +        "left": "整数|字符串:小数点右边的位数",
            +        "right": "数组:该格式化的数字",
            +        "nums": "Number[]: the Numbers to format"
            +      }
            +    },
            +    "nfs": {
            +      "description": [
            +        "用于将数字格式化成字符串的辅助函数。与 nf() 相似但会在正数前加个 \" \"(空格)而在负数前加个 \"-\" 号。此函数有两个版本:一个用于格式化浮点数,另一个用于格式化整数。参数 left 及 right 的值必须是正整数。"
            +      ],
            +      "returns": "字符串:格式化后的字符串",
            +      "params": {
            +        "num": "数字:该格式化的数字",
            +        "left": "整数:小数点左边的位数",
            +        "right": "整数:小数点右边的位数",
            +        "nums": "数组:该格式化的数字"
            +      }
            +    },
            +    "split": {
            +      "description": [
            +        "split() 函数映射到 String.split(),它使用一个字符或字符串为分隔号以将另一个字符串拆分成多个部分。delim 参数定义用于标示各个部分之间边界的字符或字符串。将返回一个含有各个部分的字符串数组。<br><br>splitTokens() 函数也与此函数相似,不过它将使用一系列字符以拆分字符串而不是使用特别定义的单一字符或字符串。",
            +        "The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it splits using a range of characters instead of a specific character or sequence."
            +      ],
            +      "returns": "字符串[]:字符串数组",
            +      "params": {
            +        "value": "字符串:还拆分的字符串",
            +        "delim": "字符串:用于分隔资料的字符串"
            +      }
            +    },
            +    "splitTokens": {
            +      "description": [
            +        "splitTokens() 函数将在一个或多个字符(或 “tokens”)所标示的地方拆分一个字符串。delim 参数将定义用于标示各个部分之间边界的字符或字符串。<br><br>如果 delim 参数没有被定义,此函数将使用任何空白字符拆分。空白字符包括制表符(\\t)、换行符(\\n)、回车符(\\r)、新页符(\\f)及空格。",
            +        "If no delim characters are specified, any whitespace character is used to split. Whitespace characters include tab (\\t), line feed (\\n), carriage return (\\r), form feed (\\f), and space."
            +      ],
            +      "returns": "字符串[]:字符串数组",
            +      "params": {
            +        "value": "字符串:还拆分的字符串",
            +        "delim": "字符串:用于分隔资料的字符串列"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "从一个字符串的前端及后端删除空白字符。除了一般的空白字符如空格、回车及制表符之外,这函数也将删除 Unicode “nbsp” 字符。"
            +      ],
            +      "returns": "字符串:修剪后的字符串",
            +      "params": {
            +        "str": "字符串:该修剪的字符串",
            +        "strs": "数组:该修剪的字符串数组"
            +      }
            +    },
            +    "day": {
            +      "description": [
            +        "p5.js 将与您的电脑的时钟沟通,day() 函数将返回当天的日期天数在 1 - 31 的范围内。"
            +      ],
            +      "returns": "整数:当天的日期天数"
            +    },
            +    "hour": {
            +      "description": [
            +        "p5.js 将与您的电脑的时钟沟通,hour() 函数将返回当时时间的小时数在 0 - 23 的范围内。"
            +      ],
            +      "returns": "整数:当时时间的小时数"
            +    },
            +    "minute": {
            +      "description": [
            +        "p5.js 将与您的电脑的时钟沟通,minute() 函数将返回当时时间的分钟数在 0 - 59 的范围内。"
            +      ],
            +      "returns": "整数:当时时间的分钟数"
            +    },
            +    "millis": {
            +      "description": [
            +        "返回自程序开始以来的毫秒(一秒的一千分之一)数。这资料一般可用于定时事件及动画序列。"
            +      ],
            +      "returns": "整数:自程序开始以来的毫秒数"
            +    },
            +    "month": {
            +      "description": [
            +        "p5.js 将与您的电脑的时钟沟通,month() 函数将返回当天的日期月数在 1 - 12 的范围内。"
            +      ],
            +      "returns": "整数:当时日期的月数"
            +    },
            +    "second": {
            +      "description": [
            +        "p5.js 将与您的电脑的时钟沟通,second() 函数将返回当时时间的秒数在 0 - 59 的范围内。"
            +      ],
            +      "returns": "整数:当时时间的秒数"
            +    },
            +    "year": {
            +      "description": [
            +        "p5.js 将与您的电脑的时钟沟通,year() 函数将返回当天的日期年数为一个整数(2014、2015、2016等等)。"
            +      ],
            +      "returns": "整数:当时日期的年数"
            +    },
            +    "plane": {
            +      "description": [
            +        "用给予的宽度和高度画一个平面。"
            +      ],
            +      "params": {
            +        "width": "数字:平面的宽度",
            +        "height": "数字:平面的高度",
            +        "detailX": "整数:(可选)在 x 轴的三角形细分数",
            +        "detailY": "整数:(可选)在 y 轴的三角形细分数"
            +      }
            +    },
            +    "box": {
            +      "description": [
            +        "用给予的宽度、高度及深度画一个立方体。"
            +      ],
            +      "params": {
            +        "width": "数字:立方体的宽度",
            +        "Height": "数字:立方体的高度",
            +        "depth": "数字:立方体的深度",
            +        "detailX": "整数:(可选)在 x 轴的三角形细分数",
            +        "detailY": "整数:(可选)在 y 轴的三角形细分数"
            +      }
            +    },
            +    "sphere": {
            +      "description": [
            +        "用给予的半径画一个球形。",
            +        "DetailX and detailY determines the number of subdivisions in the x-dimension and the y-dimension of a sphere. More subdivisions make the sphere seem smoother. The recommended maximum values are both 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "数字:球形的半径",
            +        "detailX": "整数:分割的数量,越多分割几何形越平滑,默认值为 24",
            +        "detailY": "整数:分割的数量,越多分割几何形越平滑,默认值为 16"
            +      }
            +    },
            +    "cylinder": {
            +      "description": [
            +        "用给予的半径和高度画一个圆筒形。",
            +        "DetailX and detailY determines the number of subdivisions in the x-dimension and the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother. The recommended maximum value for detailX is 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "数字:表面的半径",
            +        "height": "数字:圆筒形的高度",
            +        "detailX": "整数:分割的数量,越多分割几何形越平滑,默认值为 24",
            +        "detailY": "整数:y 轴分割的数量,越多分割几何形越平滑,默认值为 1",
            +        "bottomCap": "布尔值:是否该画圆筒形的底部",
            +        "topCap": "布尔值:是否该画圆筒形的顶部"
            +      }
            +    },
            +    "cone": {
            +      "description": [
            +        "用给予的半径和高度画一个锥体形。",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a cone. More subdivisions make the cone seem smoother. The recommended maximum value for detailX is 24. Using a value greater than 24 may cause a warning or slow down the browser."
            +      ],
            +      "params": {
            +        "radius": "数字:底部表面的半径",
            +        "height": "数字:锥体形的高度",
            +        "detailX": "整数:分割的数量,越多分割几何形越平滑,默认值为 24",
            +        "detailY": "整数:分割的数量,越多分割几何形越平滑,默认值为 1",
            +        "cap": "布尔值:是否该画锥体形的底部"
            +      }
            +    },
            +    "ellipsoid": {
            +      "description": [
            +        "用给予的半径画一个椭球形。",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother. Avoid detail number above 150, it may crash the browser."
            +      ],
            +      "params": {
            +        "radiusx": "数字:椭球形 x 轴的半径",
            +        "radiusy": "数字:椭球形 y 轴的半径",
            +        "radiusz": "数字:椭球形 z 轴的半径",
            +        "detailX": "整数:分割的数量,越多分割几何形越平滑,默认值为 24。避免多于 150 的细节数量,因为它可能是浏览器停止运作。",
            +        "detailY": "整数:分割的数量,越多分割几何形越平滑,默认值为 16。避免多于 150 的细节数量,因为它可能是浏览器停止运作。"
            +      }
            +    },
            +    "torus": {
            +      "description": [
            +        "用给予的半径和管半径画一个圆环形。",
            +        "DetailX and detailY determine the number of subdivisions in the x-dimension and the y-dimension of a torus. More subdivisions make the torus appear to be smoother. The default and maximum values for detailX and detailY are 24 and 16, respectively. Setting them to relatively small values like 4 and 6 allows you to create new shapes other than a torus."
            +      ],
            +      "params": {
            +        "radius": "数字:整个圆环形的半径",
            +        "tubeRadius": "数字:圆管的半径",
            +        "detailX": "整数:x 轴分割的数量,越多分割几何形越平滑,默认值为 24。",
            +        "detailY": "整数:y 轴分割的数量,越多分割几何形越平滑,默认值为 16。"
            +      }
            +    },
            +    "orbitControl": {
            +      "description": [
            +        "Allows movement around a 3D sketch using a mouse or trackpad. Left-clicking and dragging will rotate the camera position about the center of the sketch, right-clicking and dragging will pan the camera position without rotation, and using the mouse wheel (scrolling) will move the camera closer or further from the center of the sketch. This function can be called with parameters dictating sensitivity to mouse movement along the X and Y axes. Calling this function without parameters is equivalent to calling orbitControl(1,1). To reverse direction of movement in either axis, enter a negative number for sensitivity."
            +      ],
            +      "params": {
            +        "sensitivityX": "Number: (Optional) sensitivity to mouse movement along X axis",
            +        "sensitivityY": "Number: (Optional) sensitivity to mouse movement along Y axis",
            +        "sensitivityZ": "Number: (Optional) sensitivity to scroll movement along Z axis"
            +      }
            +    },
            +    "debugMode": {
            +      "description": [
            +        "debugMode() helps visualize 3D space by adding a grid to indicate where the ‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z directions. This function can be called without parameters to create a default grid and axes icon, or it can be called according to the examples above to customize the size and position of the grid and/or axes icon. The grid is drawn using the most recently set stroke color and weight. To specify these parameters, add a call to stroke() and strokeWeight() just before the end of the draw() loop.",
            +        "By default, the grid will run through the origin (0,0,0) of the sketch along the XZ plane and the axes icon will be offset from the origin. Both the grid and axes icon will be sized according to the current canvas size. Note that because the grid runs parallel to the default camera view, it is often helpful to use debugMode along with orbitControl to allow full view of the grid."
            +      ],
            +      "params": {
            +        "mode": "Constant: either GRID or AXES",
            +        "gridSize": "Number: (Optional) size of one side of the grid",
            +        "gridDivisions": "Number: (Optional) number of divisions in the grid",
            +        "xOff": "Number: (Optional) X axis offset from origin (0,0,0)",
            +        "yOff": "Number: (Optional) Y axis offset from origin (0,0,0)",
            +        "zOff": "Number: (Optional) Z axis offset from origin (0,0,0)",
            +        "axesSize": "Number: (Optional) size of axes icon",
            +        "gridXOff": "Number (Optional)",
            +        "gridYOff": "Number (Optional)",
            +        "gridZOff": "Number (Optional)",
            +        "axesXOff": "Number (Optional)",
            +        "axesYOff": "Number (Optional)",
            +        "axesZOff": "Number (Optional)"
            +      }
            +    },
            +    "noDebugMode": {
            +      "description": [
            +        "Turns off debugMode() in a 3D sketch."
            +      ]
            +    },
            +    "ambientLight": {
            +      "description": [
            +        "使用所定义的颜色创造一个环境光。"
            +      ],
            +      "params": {
            +        "v1": "数字:红彩值或色调值,需在被定义的范围内",
            +        "v2": "数字:绿彩值或饱和度值,需在被定义的范围内",
            +        "v3": "数字:蓝彩值或亮度值,需在被定义的范围内",
            +        "alpha": "数字:",
            +        "value": "字符串:颜色字符串",
            +        "gray": "数字:灰阶值",
            +        "values": "数字[]:一个有红、绿、蓝及透明度值的数组",
            +        "color": "p5.Color:环境光色"
            +      }
            +    },
            +    "specularColor": {
            +      "description": [
            +        "Set's the color of the specular highlight when using a specular material and specular light.",
            +        "This method can be combined with specularMaterial() and shininess() functions to set specular highlights. The default color is white, ie (255, 255, 255), which is used if this method is not called before specularMaterial(). If this method is called without specularMaterial(), There will be no effect.",
            +        "Note: specularColor is equivalent to the processing function <a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>."
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value relative to  the current color range",
            +        "v2": "Number: green or saturation value  relative to the current color range",
            +        "v3": "Number: blue or brightness value  relative to the current color range",
            +        "value": "String: a color string",
            +        "gray": "Number: a gray value",
            +        "values": "Number[]: an array containing the red,green,blue &  and alpha components of the color",
            +        "color": "p5.Color: the ambient light color"
            +      }
            +    },
            +    "directionalLight": {
            +      "description": [
            +        "使用所定义的颜色及方向创造一个定向光。",
            +        "A maximum of 5 directionalLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "数字:红彩值或色调值,需在被定义的范围内",
            +        "v2": "数字:绿彩值或饱和度值",
            +        "v3": "数字:蓝彩值或亮度值",
            +        "position": "p5.Vector:光的方向",
            +        "color": "数字[]|字符串|p5.Color:颜色数组、CSS 颜色字符串或 p5.Color 颜色值",
            +        "x": "数字:x 轴方向",
            +        "y": "数字:y 轴方向",
            +        "z": "数字:z 轴方向"
            +      }
            +    },
            +    "pointLight": {
            +      "description": [
            +        "使用所定义的颜色及灯光位置创造一个点光源。",
            +        "A maximum of 5 pointLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "数字:红彩值或色调值,需在被定义的范围内",
            +        "v2": "数字:绿彩值或饱和度值",
            +        "v3": "数字:蓝彩值或亮度值",
            +        "x": "数字:x 轴方向",
            +        "y": "数字:y 轴方向",
            +        "z": "数字:z 轴方向",
            +        "position": "p5.Vector:光的方向",
            +        "color": "数字[]|字符串|p5.Color:颜色数组、CSS 颜色字符串或 p5.Color 颜色值"
            +      }
            +    },
            +    "lights": {
            +      "description": [
            +        "Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop."
            +      ]
            +    },
            +    "lightFalloff": {
            +      "description": [
            +        "Sets the falloff rates for point lights. It affects only the elements which are created after it in the code. The default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:",
            +        "d = distance from light position to vertex position",
            +        "falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)"
            +      ],
            +      "params": {
            +        "constant": "Number: constant value for determining falloff",
            +        "linear": "Number: linear value for determining falloff",
            +        "quadratic": "Number: quadratic value for determining falloff"
            +      }
            +    },
            +    "spotLight": {
            +      "description": [
            +        "Creates a spotlight with a given color, position, direction of light, angle and concentration. Here, angle refers to the opening or aperture of the cone of the spotlight, and concentration is used to focus the light towards the center. Both angle and concentration are optional, but if you want to provide concentration, you will also have to specify the angle.",
            +        "A maximum of 5 spotLight can be active at one time"
            +      ],
            +      "params": {
            +        "v1": "Number: red or hue value (depending on the current color mode),",
            +        "v2": "Number: green or saturation value",
            +        "v3": "Number: blue or brightness value",
            +        "x": "Number: x axis position",
            +        "y": "Number: y axis position",
            +        "z": "Number: z axis position",
            +        "rx": "Number: x axis direction of light",
            +        "ry": "Number: y axis direction of light",
            +        "rz": "Number: z axis direction of light",
            +        "angle": "Number: (Optional) optional parameter for angle. Defaults to PI/3",
            +        "conc": "Number: (Optional) optional parameter for concentration. Defaults to 100",
            +        "color": "Number[]|String|p5.Color: color Array, CSS color string, or <a href=\"#/p5.Color\">p5.Color</a> value",
            +        "position": "p5.Vector: the position of the light",
            +        "direction": "p5.Vector: the direction of the light"
            +      }
            +    },
            +    "noLights": {
            +      "description": [
            +        "This function will remove all the lights from the sketch for the subsequent materials rendered. It affects all the subsequent methods. Calls to lighting methods made after noLights() will re-enable lights in the sketch."
            +      ]
            +    },
            +    "loadModel": {
            +      "description": [
            +        "从一个 OBJ 档案加载一个三维模型。<br><br>OBJ 格式的其中一个限制是它没有内建的大小值。这表示不同程式输出的模型可能有非常不同的大小。如果您的模型没被展示的话,请试着调用 loadModel() 并给予 normalized 参数“真”(true)值。这会将模型缩放成适合 p5 的大小。您也可以使用 scale() 函数对您的模型最后大小做与更多的调整。",
            +        "<a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>. This allows the model to load fully before the rest of your code is run.",
            +        "One of the limitations of the OBJ and STL format is that it doesn't have a built-in sense of scale. This means that models exported from different programs might be very different sizes. If your model isn't displaying, try calling <a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the model to a scale appropriate for p5. You can also make additional changes to the final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.",
            +        "Also, the support for colored STL files is not present. STL files with color will be rendered without color properties."
            +      ],
            +      "returns": "p5.Geometry:p5.Geometry 物件",
            +      "params": {
            +        "path": "字符串:要加载的模型的路径",
            +        "normalize": "布尔值:如果为真,在加载时将模型缩放成标准大小。",
            +        "successCallback": "函数(p5.Geometry):此函数将在模型完成加载后被调用,将被给予该三维模型为参数。",
            +        "failureCallback": "函数(Event):如果模型加载失败,此函数将被调用并给予错误事件(event)为参数。",
            +        "fileType": "String: (Optional) The file extension of the model  (<code>.stl</code>, <code>.obj</code>)."
            +      }
            +    },
            +    "model": {
            +      "description": [
            +        "将一个三维模型渲染在荧幕上。"
            +      ],
            +      "params": {
            +        "model": "p5.Geometry:要渲染的已加载的模型"
            +      }
            +    },
            +    "loadShader": {
            +      "description": [
            +        "从所定义的顶点及片断着色器文件路径加载自定的着色器。着色器是在背景异步加载的,因此此函数应该在 preload() 内使用。<br><br>现在为止有三种主要的着色器种类。只要相对的参数有在着色器内被定义,p5 将会自动提供相对的顶点、法线、颜色及灯光属性。",
            +        "For now, there are three main types of shaders. p5 will automatically supply appropriate vertices, normals, colors, and lighting attributes if the parameters defined in the shader match the names."
            +      ],
            +      "returns": "p5.Shader:由所定义的顶点及片断着色器所创造的着色器物件",
            +      "params": {
            +        "vertFilename": "字符串:存有顶点着色器源代码的文件的路径",
            +        "fragFilename": "字符串:存有片断着色器源代码的文件的路径",
            +        "callback": "Function: (Optional) callback to be executed after loadShader completes. On success, the Shader object is passed as the first argument.",
            +        "errorCallback": "Function: (Optional) callback to be executed when an error occurs inside loadShader. On error, the error is passed as the first argument."
            +      }
            +    },
            +    "createShader": {
            +      "returns": "p5.Shader:由所定义的顶点及片断着色器所创造的着色器物件",
            +      "params": {
            +        "vertSrc": "字符串:顶点着色器的源代码",
            +        "fragSrc": "字符串:片断着色器的源代码"
            +      }
            +    },
            +    "shader": {
            +      "description": [
            +        "shader() 函数让其使用者提供自定的着色器以用于在 WEBGL 模式下渲染形状。使用这能使用 loadShader() 加载自定义的着色器。"
            +      ],
            +      "params": {
            +        "s": "p5.Shader:欲用于渲染形状用的 p5.Shader"
            +      }
            +    },
            +    "resetShader": {
            +      "description": [
            +        "This function restores the default shaders in WEBGL mode. Code that runs after resetShader() will not be affected by previously defined shaders. Should be run after <a href=\"#/p5/shader\">shader()</a>."
            +      ]
            +    },
            +    "texture": {
            +      "description": [
            +        "形状的纹理。您可在此<a href='https://p5js.org/zh-Hans/examples/3d-materials.html'>范例</a>查看所有可用的材料。"
            +      ],
            +      "params": {
            +        "tex": "p5.Image|p5.MediaElement|p5.Graphics:该渲染成纹理的二维图像"
            +      }
            +    },
            +    "textureMode": {
            +      "description": [
            +        "Sets the coordinate space for texture mapping. The default mode is IMAGE which refers to the actual coordinates of the image. NORMAL refers to a normalized space of values ranging from 0 to 1. This function only works in WEBGL mode.",
            +        "With IMAGE, if an image is 100 x 200 pixels, mapping the image onto the entire size of a quad would require the points (0,0) (100, 0) (100,200) (0,200). The same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1)."
            +      ],
            +      "params": {
            +        "mode": "Constant: either IMAGE or NORMAL"
            +      }
            +    },
            +    "textureWrap": {
            +      "description": [
            +        "Sets the global texture wrapping mode. This controls how textures behave when their uv's go outside of the 0 - 1 range. There are three options: CLAMP, REPEAT, and MIRROR.",
            +        "CLAMP causes the pixels at the edge of the texture to extend to the bounds REPEAT causes the texture to tile repeatedly until reaching the bounds MIRROR works similarly to REPEAT but it flips the texture with every new tile",
            +        "REPEAT & MIRROR are only available if the texture is a power of two size (128, 256, 512, 1024, etc.).",
            +        "This method will affect all textures in your sketch until a subsequent textureWrap call is made.",
            +        "If only one argument is provided, it will be applied to both the horizontal and vertical axes."
            +      ],
            +      "params": {
            +        "wrapX": "Constant: either CLAMP, REPEAT, or MIRROR",
            +        "wrapY": "Constant: (Optional) either CLAMP, REPEAT, or MIRROR"
            +      }
            +    },
            +    "normalMaterial": {
            +      "description": [
            +        "形状的法线材料。您可在此<a href='https://p5js.org/zh-Hans/examples/3d-materials.html'>范例</a>查看所有可用的材料。"
            +      ]
            +    },
            +    "ambientMaterial": {
            +      "description": [
            +        "使用所给予颜色定义形状的环境材料。您可在此<a href='https://p5js.org/zh-Hans/examples/3d-materials.html'>范例</a>查看所有可用的材料。"
            +      ],
            +      "params": {
            +        "v1": "数字:红彩值或色调值,需在被定义的范围内",
            +        "v2": "数字:绿彩值或饱和度值",
            +        "v3": "数字:蓝彩值或亮度值",
            +        "color": "数字[]|字符串|p5.Color:颜色数组、CSS 颜色字符串或 p5.Color 颜色值"
            +      }
            +    },
            +    "emissiveMaterial": {
            +      "description": [
            +        "Sets the emissive color of the material used for geometry drawn to the screen. This is a misnomer in the sense that the material does not actually emit light that effects surrounding polygons. Instead, it gives the appearance that the object is glowing. An emissive material will display at full strength even if there is no light for it to reflect."
            +      ],
            +      "params": {
            +        "v1": "Number: gray value, red or hue value  (depending on the current color mode),",
            +        "v2": "Number: (Optional) green or saturation value",
            +        "v3": "Number: (Optional) blue or brightness value",
            +        "a": "Number: (Optional) opacity",
            +        "color": "Number[]|String|p5.Color: color, color Array, or CSS color string"
            +      }
            +    },
            +    "specularMaterial": {
            +      "description": [
            +        "使用所给予颜色定义形状的镜面材料。您可在此<a href='https://p5js.org/zh-Hans/examples/3d-materials.html'>范例</a>查看所有可用的材料。"
            +      ],
            +      "params": {
            +        "gray": "Number: number specifying value between white and black.",
            +        "alpha": "数字:透明度",
            +        "v1": "数字:红彩值或色调值,需在被定义的范围内",
            +        "v2": "数字:绿彩值或饱和度值",
            +        "v3": "数字:蓝彩值或亮度值",
            +        "color": "数字[]|字符串|p5.Color:颜色数组、CSS 颜色字符串或 p5.Color 颜色值"
            +      }
            +    },
            +    "shininess": {
            +      "description": [
            +        "Sets the amount of gloss in the surface of shapes. Used in combination with specularMaterial() in setting the material properties of shapes. The default and minimum value is 1."
            +      ],
            +      "params": {
            +        "shine": "Number: Degree of Shininess.  Defaults to 1."
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "定义在一个三维绘图内相机的位置。此函数的行为与 gluLookAt 相似,不过它会覆盖原有的模型视图矩阵而不会在原有的模型视图上添加任何变形。当没有给予任何参数时,此函数将定义默认相机为 camera(0, 0, (height/2.0) / tan(PI*30.0 / 180.0), 0, 0, 0, 0, 1, 0);",
            +        "This function simulates the movements of the camera, allowing objects to be viewed from various angles. Remember, it does not move the objects themselves but the camera instead. For example when the centerX value is positive, and the camera is rotating to the right side of the sketch, the object will seem like it's moving to the left.",
            +        "See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a> to view the position of your camera.",
            +        "If no parameters are given, the following default is used: camera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)"
            +      ],
            +      "params": {
            +        "x": "数字:相机在 x 轴的位置",
            +        "y": "数字:相机在 y 轴的位置",
            +        "z": "数字:相机在 z 轴的位置",
            +        "centerX": "数字:代表绘图中心点的 x 坐标",
            +        "centerY": "数字:代表绘图中心点的 y 坐标",
            +        "centerZ": "数字:代表绘图中心点的 z 坐标",
            +        "upX": "数字:相机向上方向量的 x 分量",
            +        "upY": "数字:相机向上方向量的 y 分量",
            +        "upZ": "数字:相机向上方向量的 z 分量"
            +      }
            +    },
            +    "perspective": {
            +      "description": [
            +        "定义透视相机。当没有给予任何参数时,此函数将定义默认相机为 perspective(PI/3.0, width/height, cameraZ/10.0, cameraZ*10.0) 其中 cameraZ 为 ((height/2.0) / tan(PI60.0/360.0));",
            +        "The parameters to this function define the viewing frustum (the truncated pyramid within which objects are seen by the camera) through vertical field of view, aspect ratio (usually width/height), and near and far clipping planes.",
            +        "If no parameters are given, the following default is used: perspective(PI/3, width/height, eyeZ/10, eyeZ*10), where eyeZ is equal to ((height/2) / tan(PI/6))."
            +      ],
            +      "params": {
            +        "fovy": "数字:相机视锥的垂直视野,使用角度模式单位定义视野底部到顶部的角度",
            +        "aspect": "数字:相机视锥的长宽比",
            +        "near": "数字:视锥近平面的长度",
            +        "far": "数字:视锥远平面的长度"
            +      }
            +    },
            +    "ortho": {
            +      "description": [
            +        "定义正射相机。",
            +        "The parameters to this function specify the viewing frustum where left and right are the minimum and maximum x values, top and bottom are the minimum and maximum y values, and near and far are the minimum and maximum z values.",
            +        "If no parameters are given, the following default is used: ortho(-width/2, width/2, -height/2, height/2)."
            +      ],
            +      "params": {
            +        "left": "数字:相机视锥的左平面",
            +        "right": "数字:相机视锥的右平面",
            +        "bottom": "数字:相机视锥的底平面",
            +        "top": "数字:相机视锥的顶平面",
            +        "near": "数字:相机视锥的近平面",
            +        "far": "数字:相机视锥的远平面"
            +      }
            +    },
            +    "frustum": {
            +      "description": [
            +        "Sets a perspective matrix as defined by the parameters.",
            +        "A frustum is a geometric form: a pyramid with its top cut off. With the viewer's eye at the imaginary top of the pyramid, the six planes of the frustum act as clipping planes when rendering a 3D view. Thus, any form inside the clipping planes is visible; anything outside those planes is not visible.",
            +        "Setting the frustum changes the perspective of the scene being rendered. This can be achieved more simply in many cases by using <a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.",
            +        "If no parameters are given, the following default is used: frustum(-width/2, width/2, -height/2, height/2, 0, max(width, height))."
            +      ],
            +      "params": {
            +        "left": "Number: (Optional) camera frustum left plane",
            +        "right": "Number: (Optional) camera frustum right plane",
            +        "bottom": "Number: (Optional) camera frustum bottom plane",
            +        "top": "Number: (Optional) camera frustum top plane",
            +        "near": "Number: (Optional) camera frustum near plane",
            +        "far": "Number: (Optional) camera frustum far plane"
            +      }
            +    },
            +    "createCamera": {
            +      "description": [
            +        "Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and tells the renderer to use that camera. Returns the p5.Camera object.",
            +        "The new camera is initialized with a default position (see <a href=\"#/p5.Camera/camera\">camera()</a>) and a default perspective projection (see <a href=\"#/p5.Camera/perspective\">perspective()</a>). Its properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a> methods.",
            +        "Note: Every 3D sketch starts with a default camera initialized. This camera can be controlled with the global methods <a href=\"#/p5/camera\">camera()</a>, <a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>, and <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera in the scene."
            +      ],
            +      "returns": "p5.Camera: The newly created camera object."
            +    },
            +    "setCamera": {
            +      "description": [
            +        "Sets rendererGL's current camera to a p5.Camera object. Allows switching between multiple cameras."
            +      ],
            +      "params": {
            +        "cam": "p5.Camera: p5.Camera object"
            +      }
            +    },
            +    "setAttributes": {
            +      "description": [
            +        "设置 WebGL 绘图环境的属性。这是调整 WebGL 渲染器的一个方法,可用于微调显示及性能。这函数应该在 setup() 内使用。可使用的属性为:<br>alpha - 表示画布是否有透明度缓冲,默认为 true<br><br>depth - 表示绘图缓冲是否有至少 16 bits 的深度缓冲 - 默认为 true<br><br>stencil - 表示绘图缓冲是否有至少 8 bits 的模版缓冲<br><br>antialias - 表示是否应该执行抗锯齿,默认为 false<br><br>premultipliedAlpha - 表示页面合成器将假设绘图缓冲存在着预乘透明值的颜色,默认为 false<br><br>preserveDrawingBuffer - 如果为真缓冲区将不会被清空并将会保留现有的值直到它们被清空或被作者覆盖(注意 p5 在绘图循环将自动清空),默认为 true<br><br>perPixelLighting - 如果为真,照明着色器将使用个别像素照明。默认为 false",
            +        "Note that this will reinitialize the drawing context if called after the WebGL canvas is made.",
            +        "If an object is passed as the parameter, all attributes not declared in the object will be set to defaults.",
            +        "The available attributes are:  alpha - indicates if the canvas contains an alpha buffer default is true",
            +        "depth - indicates whether the drawing buffer has a depth buffer of at least 16 bits - default is true",
            +        "stencil - indicates whether the drawing buffer has a stencil buffer of at least 8 bits",
            +        "antialias - indicates whether or not to perform anti-aliasing default is false (true in Safari)",
            +        "premultipliedAlpha - indicates that the page compositor will assume the drawing buffer contains colors with pre-multiplied alpha default is false",
            +        "preserveDrawingBuffer - if true the buffers will not be cleared and and will preserve their values until cleared or overwritten by author (note that p5 clears automatically on draw loop) default is true",
            +        "perPixelLighting - if true, per-pixel lighting will be used in the lighting shader otherwise per-vertex lighting is used. default is true."
            +      ],
            +      "params": {
            +        "key": "字符串:属性名",
            +        "value": "布尔值:属性的新值",
            +        "obj": "物件:有键值对的物件"
            +      }
            +    },
            +    "getAudioContext": {
            +      "description": [
            +        "Returns the Audio Context for this sketch. Useful for users who would like to dig deeper into the <a target='_blank' href= 'http://webaudio.github.io/web-audio-api/'>Web Audio API </a>.",
            +        "Some browsers require users to startAudioContext with a user gesture, such as touchStarted in the example below."
            +      ],
            +      "returns": "Object: AudioContext for this sketch"
            +    },
            +    "userStartAudio": {
            +      "description": [
            +        "It is not only a good practice to give users control over starting audio. This policy is enforced by many web browsers, including iOS and <a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay policy\">Google Chrome</a>, which create the Web Audio API's <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\" title=\"Audio Context @ MDN\">Audio Context</a> in a suspended state.",
            +        "In these browser-specific policies, sound will not play until a user interaction event (i.e. <code>mousePressed()</code>) explicitly resumes the AudioContext, or starts an audio node. This can be accomplished by calling <code>start()</code> on a <code>p5.Oscillator</code>, <code> play()</code> on a <code>p5.SoundFile</code>, or simply <code>userStartAudio()</code>.",
            +        "<code>userStartAudio()</code> starts the AudioContext on a user gesture. The default behavior will enable audio on any mouseUp or touchEnd event. It can also be placed in a specific interaction function, such as <code>mousePressed()</code> as in the example below. This method utilizes <a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext </a>, a library by Yotam Mann (MIT Licence, 2016)."
            +      ],
            +      "returns": "Promise: Returns a Promise that resolves when  the AudioContext state is 'running'",
            +      "params": {
            +        "element(s)": "Element|Array: (Optional) This argument can be an Element,  Selector String, NodeList, p5.Element,  jQuery Element, or an Array of any of those.",
            +        "callback": "Function: (Optional) Callback to invoke when the AudioContext  has started"
            +      }
            +    },
            +    "getOutputVolume": {
            +      "description": [
            +        "Returns a number representing the output volume for sound in this sketch."
            +      ],
            +      "returns": "Number: Output volume for sound in this sketch.  Should be between 0.0 (silence) and 1.0."
            +    },
            +    "outputVolume": {
            +      "description": [
            +        "Scale the output of all sound in this sketch Scaled between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal.",
            +        "<b>How This Works</b>: When you load the p5.sound module, it creates a single instance of p5sound. All sound objects in this module output to p5sound before reaching your computer's output. So if you change the amplitude of p5sound, it impacts all of the sound in this module.",
            +        "If no value is provided, returns a Web Audio API Gain Node"
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "soundOut": {
            +      "description": [
            +        "<code>p5.soundOut</code> is the p5.sound final output bus. It sends output to the destination of this window's web audio context. It contains Web Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>), and Gain Nodes for <code>.input</code> and <code>.output</code>."
            +      ]
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Returns a number representing the sample rate, in samples per second, of all sound objects in this audio context. It is determined by the sampling rate of your operating system's sound card, and it is not currently possile to change. It is often 44100, or twice the range of human hearing."
            +      ],
            +      "returns": "Number: samplerate samples per second"
            +    },
            +    "freqToMidi": {
            +      "description": [
            +        "Returns the closest MIDI note value for a given frequency."
            +      ],
            +      "returns": "Number: MIDI note value",
            +      "params": {
            +        "frequency": "Number: A freqeuncy, for example, the \"A\"  above Middle C is 440Hz"
            +      }
            +    },
            +    "midiToFreq": {
            +      "description": [
            +        "Returns the frequency value of a MIDI note value. General MIDI treats notes as integers where middle C is 60, C# is 61, D is 62 etc. Useful for generating musical frequencies with oscillators."
            +      ],
            +      "returns": "Number: Frequency value of the given MIDI note",
            +      "params": {
            +        "midiNote": "Number: The number of a MIDI note"
            +      }
            +    },
            +    "soundFormats": {
            +      "description": [
            +        "List the SoundFile formats that you will include. LoadSound will search your directory for these extensions, and will pick a format that is compatable with the client's web browser. <a href=\"http://media.io/\">Here</a> is a free online file converter."
            +      ],
            +      "params": {
            +        "formats": "String: (Optional) i.e. 'mp3', 'wav', 'ogg'"
            +      }
            +    },
            +    "saveSound": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. For uploading audio to a server, use <a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile that you wish to save",
            +        "fileName": "String: name of the resulting .wav file."
            +      }
            +    },
            +    "loadSound": {
            +      "description": [
            +        "loadSound() returns a new p5.SoundFile from a specified path. If called during preload(), the p5.SoundFile will be ready to play in time for setup() and draw(). If called outside of preload, the p5.SoundFile will not be ready immediately, so loadSound accepts a callback as the second parameter. Using a <a href=\"https://github.com/processing/p5.js/wiki/Local-server\"> local server</a> is recommended when loading external files."
            +      ],
            +      "returns": "SoundFile: Returns a p5.SoundFile",
            +      "params": {
            +        "path": "String|Array: Path to the sound file, or an array with  paths to soundfiles in multiple formats  i.e. ['sound.ogg', 'sound.mp3'].  Alternately, accepts an object: either  from the HTML5 File API, or a p5.File.",
            +        "successCallback": "Function: (Optional) Name of a function to call once file loads",
            +        "errorCallback": "Function: (Optional) Name of a function to call if there is  an error loading the file.",
            +        "whileLoading": "Function: (Optional) Name of a function to call while file is loading.  This function will receive the percentage loaded  so far, from 0.0 to 1.0."
            +      }
            +    },
            +    "createConvolver": {
            +      "description": [
            +        "Create a p5.Convolver. Accepts a path to a soundfile that will be used to generate an impulse response."
            +      ],
            +      "returns": "p5.Convolver:",
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: (Optional) function to call if loading is successful.  The object will be passed in as the argument  to the callback function.",
            +        "errorCallback": "Function: (Optional) function to call if loading is not successful.  A custom error will be passed in as the argument  to the callback function."
            +      }
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the global tempo, in beats per minute, for all p5.Parts. This method will impact all active p5.Parts."
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.Color": {
            +    "description": [
            +      "Each color stores the color mode and level maxes that was applied at the time of its construction. These are used to interpret the input arguments (at construction and later for that instance of color) and to format the output e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.",
            +      "Internally, we store an array representing the ideal RGBA values in floating point form, normalized from 0 to 1. From this we calculate the closest screen color (RGBA levels from 0 to 255) and expose this to the renderer.",
            +      "We also cache normalized, floating point components of the color in various representations as they are calculated. This is done to prevent repeating a conversion that has already been performed."
            +    ],
            +    "setRed": {
            +      "description": [
            +        "The setRed function sets the red component of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "red": "Number: the new red value"
            +      }
            +    },
            +    "setGreen": {
            +      "description": [
            +        "The setGreen function sets the green component of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "green": "Number: the new green value"
            +      }
            +    },
            +    "setBlue": {
            +      "description": [
            +        "The setBlue function sets the blue component of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "blue": "Number: the new blue value"
            +      }
            +    },
            +    "setAlpha": {
            +      "description": [
            +        "The setAlpha function sets the transparency (alpha) value of a color. The range depends on your color mode, in the default RGB mode it's between 0 and 255."
            +      ],
            +      "params": {
            +        "alpha": "Number: the new alpha value"
            +      }
            +    }
            +  },
            +  "p5.Element": {
            +    "description": [
            +      "Base class for all elements added to a sketch, including canvas, graphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a> objects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>, <a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped",
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "elt": {
            +      "description": [
            +        "Underlying HTML element. All normal HTML methods can be called on this."
            +      ]
            +    },
            +    "parent": {
            +      "description": [
            +        "Attaches the element to the parent specified. A way of setting  the container for the element. Accepts either a string ID, DOM  node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.  For more ways to position the canvas, see the  <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>  positioning the canvas</a> wiki page."
            +      ],
            +      "params": {
            +        "parent": "String|p5.Element|Object: the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>  of desired parent element"
            +      }
            +    },
            +    "id": {
            +      "description": [
            +        "Sets the ID of the element. If no ID argument is passed in, it instead  returns the current ID of the element.  Note that only one element can have a particular id in a page.  The <a href=\"#/p5.Element/class\">.class()</a> function can be used  to identify multiple elements with the same class name."
            +      ],
            +      "params": {
            +        "id": "String: ID of the element"
            +      }
            +    },
            +    "class": {
            +      "description": [
            +        "Adds given class to the element. If no class argument is passed in, it  instead returns a string containing the current class(es) of the element."
            +      ],
            +      "params": {
            +        "class": "String: class to add"
            +      }
            +    },
            +    "mousePressed": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called once after every time a mouse button is pressed over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  pressed over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "doubleClicked": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a mouse button is pressed twice over the element. This can be used to attach element and action specific event listeners."
            +      ],
            +      "returns": "p5.Element:",
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  double clicked over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseWheel": {
            +      "description": [
            +        "The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners.",
            +        "The function accepts a callback function as argument which will be executed when the <code>wheel</code> event is triggered on the element, the callback function is passed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code> except it reads the horizontal wheel scroll of the mouse wheel.",
            +        "On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are reversed."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  scrolled over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseReleased": {
            +      "description": [
            +        "The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is called once after every time a mouse button is released over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  released over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseClicked": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is called once after a mouse button is pressed and released over the element. Some mobile browsers may also trigger this event on a touch screen, if the user performs a quick tap.This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when mouse is  clicked over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseMoved": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a mouse moves over the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse moves  over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseOver": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a mouse moves onto the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse moves  onto the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "mouseOut": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a mouse moves off the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a mouse  moves off of an element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchStarted": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch  starts over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchMoved": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch moves over  the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "touchEnded": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is registered. This can be used to attach element specific event listeners."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a touch ends  over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "dragOver": {
            +      "description": [
            +        "The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a file is dragged over the element. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a file is  dragged over the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "dragLeave": {
            +      "description": [
            +        "The .dragLeave() function is called once after every time a dragged file leaves the element area. This can be used to attach an element specific event listener."
            +      ],
            +      "params": {
            +        "fxn": "Function|Boolean: function to be fired when a file is  dragged off the element.  if <code>false</code> is passed instead, the previously  firing function will no longer fire."
            +      }
            +    },
            +    "addClass": {
            +      "description": [
            +        "Adds specified class to the element."
            +      ],
            +      "params": {
            +        "class": "String: name of class to add"
            +      }
            +    },
            +    "removeClass": {
            +      "description": [
            +        "Removes specified class from the element."
            +      ],
            +      "params": {
            +        "class": "String: name of class to remove"
            +      }
            +    },
            +    "hasClass": {
            +      "description": [
            +        "Checks if specified class already set to element"
            +      ],
            +      "returns": "Boolean: a boolean value if element has specified class",
            +      "params": {
            +        "c": "String: class name of class to check"
            +      }
            +    },
            +    "toggleClass": {
            +      "description": [
            +        "Toggles element class"
            +      ],
            +      "params": {
            +        "c": "String: class name to toggle"
            +      }
            +    },
            +    "child": {
            +      "description": [
            +        "Attaches the element as a child to the parent specified.  Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.  If no argument is specified, an array of children DOM nodes is returned."
            +      ],
            +      "returns": "Node[]: an array of child nodes",
            +      "params": {
            +        "child": "String|p5.Element: (Optional) the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>  to add to the current element"
            +      }
            +    },
            +    "center": {
            +      "description": [
            +        "Centers a p5 Element either vertically, horizontally, or both, relative to its parent or according to the body if the Element has no parent. If no argument is passed the Element is aligned both vertically and horizontally."
            +      ],
            +      "params": {
            +        "align": "String: (Optional) passing 'vertical', 'horizontal' aligns element accordingly"
            +      }
            +    },
            +    "html": {
            +      "description": [
            +        "If an argument is given, sets the inner HTML of the element,  replacing any existing html. If true is included as a second  argument, html is appended instead of replacing existing html.  If no arguments are given, returns  the inner HTML of the element."
            +      ],
            +      "returns": "String: the inner HTML of the element",
            +      "params": {
            +        "html": "String: (Optional) the HTML to be placed inside the element",
            +        "append": "Boolean: (Optional) whether to append HTML to existing"
            +      }
            +    },
            +    "position": {
            +      "description": [
            +        "Sets the position of the element. If no position type argument is given, the  position will be relative to (0, 0) of the window.  Essentially, this sets position:absolute and left and top  properties of style. If an optional third argument specifying position type is given,  the x and y coordinates will be interpreted based on the <a target=\"_blank\"  href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.  If no arguments given, the function returns the x and y position of the element. found documentation on how to be more specific with object type  <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a>"
            +      ],
            +      "returns": "Object: object of form { x: 0, y: 0 } containing the position of the element in an object",
            +      "params": {
            +        "x": "Number: (Optional) x-position relative to upper left of window (optional)",
            +        "y": "Number: (Optional) y-position relative to upper left of window (optional)",
            +        "positionType": "String: it can be static, fixed, relative, sticky, initial or inherit (optional)"
            +      }
            +    },
            +    "style": {
            +      "description": [
            +        "Sets the given style (css) property (1st arg) of the element with the given value (2nd arg). If a single argument is given, .style() returns the value of the given property; however, if the single argument is given in css syntax ('text-align:center'), .style() sets the css appropriately."
            +      ],
            +      "returns": "String: value of property",
            +      "params": {
            +        "property": "String: property to be set",
            +        "value": "String|p5.Color: value to assign to property"
            +      }
            +    },
            +    "attribute": {
            +      "description": [
            +        "Adds a new attribute or changes the value of an existing attribute  on the specified element. If no value is specified, returns the  value of the given attribute, or null if attribute is not set."
            +      ],
            +      "returns": "String: value of attribute",
            +      "params": {
            +        "attr": "String: attribute to set",
            +        "value": "String: value to assign to attribute"
            +      }
            +    },
            +    "removeAttribute": {
            +      "description": [
            +        "Removes an attribute on the specified element."
            +      ],
            +      "params": {
            +        "attr": "String: attribute to remove"
            +      }
            +    },
            +    "value": {
            +      "description": [
            +        "Either returns the value of the element if no arguments given, or sets the value of the element."
            +      ],
            +      "returns": "String|Number: value of the element",
            +      "params": {
            +        "value": "String|Number"
            +      }
            +    },
            +    "show": {
            +      "description": [
            +        "Shows the current element. Essentially, setting display:block for the style."
            +      ]
            +    },
            +    "hide": {
            +      "description": [
            +        "Hides the current element. Essentially, setting display:none for the style."
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "Sets the width and height of the element. AUTO can be used to  only adjust one dimension at a time. If no arguments are given, it  returns the width and height of the element in an object. In case of  elements which need to be loaded, such as images, it is recommended  to call the function after the element has finished loading."
            +      ],
            +      "returns": "Object: the width and height of the element in an object",
            +      "params": {
            +        "w": "Number|Constant: width of the element, either AUTO, or a number",
            +        "h": "Number|Constant: (Optional) height of the element, either AUTO, or a number"
            +      }
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the element, stops all media streams, and deregisters all listeners."
            +      ]
            +    },
            +    "drop": {
            +      "description": [
            +        "Registers a callback that gets called every time a file that is dropped on the element has been loaded. p5 will load every dropped file into memory and pass it as a p5.File object to the callback. Multiple files dropped at the same time will result in multiple calls to the callback.",
            +        "You can optionally pass a second callback which will be registered to the raw <a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event. The callback will thus be provided the original <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>. Dropping multiple files at the same time will trigger the second callback once per drop, whereas the first callback will trigger for each loaded file."
            +      ],
            +      "params": {
            +        "callback": "Function: callback to receive loaded file, called for each file dropped.",
            +        "fxn": "Function: (Optional) callback triggered once when files are dropped with the drop event."
            +      }
            +    }
            +  },
            +  "p5.Graphics": {
            +    "description": [
            +      "Thin wrapper around a renderer, to be used for creating a graphics buffer object. Use this class if you need to draw into an off-screen graphics buffer. The two parameters define the width and height in pixels. The fields and methods for this class are extensive, but mirror the normal drawing API for p5."
            +    ],
            +    "params": {
            +      "w": "Number: width",
            +      "h": "Number: height",
            +      "renderer": "Constant: the renderer to use, either P2D or WEBGL",
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "reset": {
            +      "description": [
            +        "Resets certain values such as those modified by functions in the Transform category and in the Lights category that are not automatically reset with graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior of the standard canvas."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes a Graphics object from the page and frees any resources associated with it."
            +      ]
            +    }
            +  },
            +  "p5.Renderer": {
            +    "description": [
            +      "Main graphics and rendering context, as well as the base API implementation for p5.js \"core\". To be used as the superclass for Renderer2D and Renderer3D classes, respectively."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped",
            +      "pInst": "P5: (Optional) pointer to p5 instance",
            +      "isMainCanvas": "Boolean: (Optional) whether we're using it as main canvas"
            +    }
            +  },
            +  "JSON": {
            +    "stringify": {
            +      "description": [
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>: The JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>."
            +      ],
            +      "params": {
            +        "object": "Object: :Javascript object that you would like to convert to JSON"
            +      }
            +    }
            +  },
            +  "console": {
            +    "log": {
            +      "description": [
            +        "Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a> and <a href=\"#/p5/console/log\">console.log</a> interchangeably.",
            +        "The console is opened differently depending on which browser you are using. Here are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a> , <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>, and <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>. With the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console is embedded directly in the page underneath the code editor.",
            +        "From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>: The Console method log() outputs a message to the web console. The message may be a single <a href=\"#/p5/string\">string</a> (with optional substitution values), or it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>."
            +      ],
            +      "params": {
            +        "message": "String|Expression|Object: :Message that you would like to print to the console"
            +      }
            +    }
            +  },
            +  "p5.TypedDict": {
            +    "description": [
            +      "Base class for all p5.Dictionary types. Specifically  typed Dictionary classes inherit from this class."
            +    ],
            +    "size": {
            +      "description": [
            +        "Returns the number of key-value pairs currently stored in the Dictionary."
            +      ],
            +      "returns": "Integer: the number of key-value pairs in the Dictionary"
            +    },
            +    "hasKey": {
            +      "description": [
            +        "Returns true if the given key exists in the Dictionary, otherwise returns false."
            +      ],
            +      "returns": "Boolean: whether that key exists in Dictionary",
            +      "params": {
            +        "key": "Number|String: that you want to look up"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Returns the value stored at the given key."
            +      ],
            +      "returns": "Number|String: the value stored at that key",
            +      "params": {
            +        "the": "Number|String: key you want to access"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Updates the value associated with the given key in case it already exists in the Dictionary. Otherwise a new key-value pair is added."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String"
            +      }
            +    },
            +    "create": {
            +      "description": [
            +        "Creates a new key-value pair in the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String",
            +        "value": "Number|String",
            +        "obj": "Object: key/value pair"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Removes all previously stored key-value pairs from the Dictionary."
            +      ]
            +    },
            +    "remove": {
            +      "description": [
            +        "Removes the key-value pair stored at the given key from the Dictionary."
            +      ],
            +      "params": {
            +        "key": "Number|String: for the pair to remove"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Logs the set of items currently stored in the Dictionary to the console."
            +      ]
            +    },
            +    "saveTable": {
            +      "description": [
            +        "Converts the Dictionary into a CSV file for local download."
            +      ]
            +    },
            +    "saveJSON": {
            +      "description": [
            +        "Converts the Dictionary into a JSON file for local download."
            +      ]
            +    }
            +  },
            +  "p5.StringDict": {
            +    "description": [
            +      "A simple Dictionary class for Strings."
            +    ]
            +  },
            +  "p5.NumberDict": {
            +    "description": [
            +      "A simple Dictionary class for Numbers."
            +    ],
            +    "add": {
            +      "description": [
            +        "Add the given number to the value currently stored at the given key. The sum then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to add to",
            +        "Number": "Number: to add to the value"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtract the given number from the value currently stored at the given key. The difference then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for the value you wish to subtract from",
            +        "Number": "Number: to subtract from the value"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the given number with the value currently stored at the given key. The product then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to multiply",
            +        "Amount": "Number: to multiply the value by"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Divide the given number with the value currently stored at the given key. The quotient then replaces the value previously stored in the Dictionary."
            +      ],
            +      "params": {
            +        "Key": "Number: for value you wish to divide",
            +        "Amount": "Number: to divide the value by"
            +      }
            +    },
            +    "minValue": {
            +      "description": [
            +        "Return the lowest number currently stored in the Dictionary."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "maxValue": {
            +      "description": [
            +        "Return the highest number currently stored in the Dictionary."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "minKey": {
            +      "description": [
            +        "Return the lowest key currently used in the Dictionary."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "maxKey": {
            +      "description": [
            +        "Return the highest key currently used in the Dictionary."
            +      ],
            +      "returns": "Number:"
            +    }
            +  },
            +  "p5.MediaElement": {
            +    "description": [
            +      "Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods of <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not called directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>, <a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>."
            +    ],
            +    "params": {
            +      "elt": "String: DOM node that is wrapped"
            +    },
            +    "src": {
            +      "description": [
            +        "Path to the media element source."
            +      ],
            +      "returns": "String: src"
            +    },
            +    "play": {
            +      "description": [
            +        "Play an HTML5 media element."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stops an HTML5 media element (sets current time to zero)."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses an HTML5 media element."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Set 'loop' to true for an HTML5 media element, and starts playing."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Set 'loop' to false for an HTML5 media element. Element will stop when it reaches the end."
            +      ]
            +    },
            +    "autoplay": {
            +      "description": [
            +        "Set HTML5 media element to autoplay or not. If no argument is specified, by default it will autoplay."
            +      ],
            +      "params": {
            +        "shouldAutoplay": "Boolean: whether the element should autoplay"
            +      }
            +    },
            +    "volume": {
            +      "description": [
            +        "Sets volume for this HTML5 media element. If no argument is given, returns the current volume."
            +      ],
            +      "returns": "Number: current volume",
            +      "params": {
            +        "val": "Number: volume between 0.0 and 1.0"
            +      }
            +    },
            +    "speed": {
            +      "description": [
            +        "If no arguments are given, returns the current playback speed of the element. The speed parameter sets the speed where 2.0 will play the element twice as fast, 0.5 will play at half the speed, and -1 will play the element in normal speed in reverse.(Note that not all browsers support backward playback and even if they do, playback might not be smooth.)"
            +      ],
            +      "returns": "Number: current playback speed of the element",
            +      "params": {
            +        "speed": "Number: speed multiplier for element playback"
            +      }
            +    },
            +    "time": {
            +      "description": [
            +        "If no arguments are given, returns the current time of the element. If an argument is given the current time of the element is set to it."
            +      ],
            +      "returns": "Number: current time (in seconds)",
            +      "params": {
            +        "time": "Number: time to jump to (in seconds)"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of the HTML5 media element."
            +      ],
            +      "returns": "Number: duration"
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the audio or video element reaches the end. If the element is looping, this will not be called. The element is passed in as the argument to the onended callback."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended. The  media element will be passed  in as the argument to the  callback."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send the audio output of this element to a specified audioNode or p5.sound object. If no element is provided, connects to p5's main output. That connection is established when this method is first called. All connections are removed by the .disconnect() method.",
            +        "This method is meant to be used with the p5.sound.js addon library."
            +      ],
            +      "params": {
            +        "audioNode": "AudioNode|Object: AudioNode from the Web Audio API, or an object from the p5.sound library"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all Web Audio routing, including to main output. This is useful if you want to re-route the output through audio effects, for example."
            +      ]
            +    },
            +    "showControls": {
            +      "description": [
            +        "Show the default MediaElement controls, as determined by the web browser."
            +      ]
            +    },
            +    "hideControls": {
            +      "description": [
            +        "Hide the default mediaElement controls."
            +      ]
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point.",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback.",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    }
            +  },
            +  "p5.File": {
            +    "description": [
            +      "Base class for a file. Used for Element.drop and createFileInput."
            +    ],
            +    "params": {
            +      "file": "File: File that is wrapped"
            +    },
            +    "file": {
            +      "description": [
            +        "Underlying File object. All normal File methods can be called on this."
            +      ]
            +    },
            +    "type": {
            +      "description": [
            +        "File type (image, text, etc.)"
            +      ]
            +    },
            +    "subtype": {
            +      "description": [
            +        "File subtype (usually the file extension jpg, png, xml, etc.)"
            +      ]
            +    },
            +    "name": {
            +      "description": [
            +        "File name"
            +      ]
            +    },
            +    "size": {
            +      "description": [
            +        "File size"
            +      ]
            +    },
            +    "data": {
            +      "description": [
            +        "URL string containing either image data, the text contents of the file or a parsed object if file is JSON and p5.XML if XML"
            +      ]
            +    }
            +  },
            +  "p5.Image": {
            +    "description": [
            +      "Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an image.",
            +      "p5 can display .gif, .jpg and .png images. Images may be displayed in 2D and 3D space. Before an image is used, it must be loaded with the <a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and height of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the values for every pixel in the image.",
            +      "The methods described below allow easy access to the image's pixels and alpha channel and simplify the process of compositing.",
            +      "Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on the image to make sure that the pixel data is properly loaded."
            +    ],
            +    "params": {
            +      "width": "Number",
            +      "height": "Number"
            +    },
            +    "width": {
            +      "description": [
            +        "Image width."
            +      ]
            +    },
            +    "height": {
            +      "description": [
            +        "Image height."
            +      ]
            +    },
            +    "pixels": {
            +      "description": [
            +        "Array containing the values for all the pixels in the display window. These values are numbers. This array is the size (include an appropriate factor for pixelDensity) of the display window x4, representing the R, G, B, A values in order for each pixel, moving from left to right across each row, then down each column. Retina and other high density displays may have more pixels (by a factor of pixelDensity^2). For example, if the image is 100x100 pixels, there will be 40,000. With pixelDensity = 2, there will be 160,000. The first four values (indices 0-3) in the array will be the R, G, B, A values of the pixel at (0, 0). The second four values (indices 4-7) will contain the R, G, B, A values of the pixel at (1, 0). More generally, to set values for a pixel at (x, y): <pre><code class=\"language-javascript\">let d = pixelDensity(); for (let i = 0; i < d; i++) {  for (let j = 0; j < d; j++) {  // loop over  index = 4 * ((y * d + j) * width * d + (x * d + i));  pixels[index] = r;  pixels[index+1] = g;  pixels[index+2] = b;  pixels[index+3] = a;  } }</code></pre>",
            +        "Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes."
            +      ]
            +    },
            +    "loadPixels": {
            +      "description": [
            +        "Loads the pixels data for this image into the [pixels] attribute."
            +      ]
            +    },
            +    "updatePixels": {
            +      "description": [
            +        "Updates the backing canvas for this image with the contents of the [pixels] array.",
            +        "If this image is an animated GIF then the pixels will be updated in the frame that is currently displayed."
            +      ],
            +      "params": {
            +        "x": "Integer: x-offset of the target update area for the  underlying canvas",
            +        "y": "Integer: y-offset of the target update area for the  underlying canvas",
            +        "w": "Integer: height of the target update area for the  underlying canvas",
            +        "h": "Integer: height of the target update area for the  underlying canvas"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Get a region of pixels from an image.",
            +        "If no params are passed, the whole image is returned. If x and y are the only params passed a single pixel is extracted. If all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a> is returned."
            +      ],
            +      "returns": "p5.Image: the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "w": "Number: width",
            +        "h": "Number: height"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the color of a single pixel or write an image into this <a href=\"#/p5.Image\">p5.Image</a>.",
            +        "Note that for a large number of pixels this will be slower than directly manipulating the pixels array and then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>."
            +      ],
            +      "params": {
            +        "x": "Number: x-coordinate of the pixel",
            +        "y": "Number: y-coordinate of the pixel",
            +        "a": "Number|Number[]|Object: grayscale value | pixel array |  a <a href=\"#/p5.Color\">p5.Color</a> | image to copy"
            +      }
            +    },
            +    "resize": {
            +      "description": [
            +        "Resize the image to a new width and height. To make the image scale proportionally, use 0 as the value for the wide or high parameter. For instance, to make the width of an image 150 pixels, and change the height using the same proportion, use resize(150, 0)."
            +      ],
            +      "params": {
            +        "width": "Number: the resized image width",
            +        "height": "Number: the resized image height"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Copies a region of pixels from one image to another. If no srcImage is specified this is used as the source. If the source and destination regions aren't the same size, it will automatically resize source pixels to fit the specified target region."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image|p5.Element: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height"
            +      }
            +    },
            +    "mask": {
            +      "description": [
            +        "Masks part of an image from displaying by loading another image and using its alpha channel as an alpha channel for this image."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a>",
            +        "THRESHOLD Converts the image to black and white pixels depending if they are above or below the threshold defined by the level parameter. The parameter must be between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.",
            +        "GRAY Converts any colors in the image to grayscale equivalents. No parameter is used.",
            +        "OPAQUE Sets the alpha channel to entirely opaque. No parameter is used.",
            +        "INVERT Sets each pixel to its inverse value. No parameter is used.",
            +        "POSTERIZE Limits each channel of the image to the number of colors specified as the parameter. The parameter can be set to values between 2 and 255, but results are most noticeable in the lower ranges.",
            +        "BLUR Executes a Gaussian blur with the level parameter specifying the extent of the blurring. If no parameter is used, the blur is equivalent to Gaussian blur of radius 1. Larger values increase the blur.",
            +        "ERODE Reduces the light areas. No parameter is used.",
            +        "DILATE Increases the light areas. No parameter is used.",
            +        "filter() does not work in WEBGL mode. A similar effect can be achieved in WEBGL mode using custom shaders. Adam Ferriss has written a <a href=\"https://github.com/aferriss/p5jsShaderExamples\" target='_blank'>selection of shader examples</a> that contains many of the effects present in the filter examples."
            +      ],
            +      "params": {
            +        "filterType": "Constant: either THRESHOLD, GRAY, OPAQUE, INVERT,  POSTERIZE, BLUR, ERODE, DILATE or BLUR.  See Filters.js for docs on  each available filter",
            +        "filterParam": "Number: (Optional) an optional parameter unique  to each filter, see above"
            +      }
            +    },
            +    "blend": {
            +      "description": [
            +        "Copies a region of pixels from one image to another, using a specified blend mode to do the operation."
            +      ],
            +      "params": {
            +        "srcImage": "p5.Image: source image",
            +        "sx": "Integer: X coordinate of the source's upper left corner",
            +        "sy": "Integer: Y coordinate of the source's upper left corner",
            +        "sw": "Integer: source image width",
            +        "sh": "Integer: source image height",
            +        "dx": "Integer: X coordinate of the destination's upper left corner",
            +        "dy": "Integer: Y coordinate of the destination's upper left corner",
            +        "dw": "Integer: destination image width",
            +        "dh": "Integer: destination image height",
            +        "blendMode": "Constant: the blend mode. either  BLEND, DARKEST, LIGHTEST, DIFFERENCE,  MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,  SOFT_LIGHT, DODGE, BURN, ADD or NORMAL. Available blend modes are: normal | multiply | screen | overlay |  darken | lighten | color-dodge | color-burn | hard-light |  soft-light | difference | exclusion | hue | saturation |  color | luminosity <a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a>"
            +      }
            +    },
            +    "save": {
            +      "description": [
            +        "Saves the image to a file and force the browser to download it. Accepts two strings for filename and file extension Supports png (default), jpg, and gif  Note that the file will only be downloaded as an animated GIF if the p5.Image was loaded from a GIF file."
            +      ],
            +      "params": {
            +        "filename": "String: give your file a name",
            +        "extension": "String: 'png' or 'jpg'"
            +      }
            +    },
            +    "reset": {
            +      "description": [
            +        "Starts an animated GIF over at the beginning state."
            +      ]
            +    },
            +    "getCurrentFrame": {
            +      "description": [
            +        "Gets the index for the frame that is currently visible in an animated GIF."
            +      ],
            +      "returns": "Number: The index for the currently displaying frame in animated GIF"
            +    },
            +    "setFrame": {
            +      "description": [
            +        "Sets the index of the frame that is currently visible in an animated GIF"
            +      ],
            +      "params": {
            +        "index": "Number: the index for the frame that should be displayed"
            +      }
            +    },
            +    "numFrames": {
            +      "description": [
            +        "Returns the number of frames in an animated GIF"
            +      ],
            +      "returns": "Number:"
            +    },
            +    "play": {
            +      "description": [
            +        "Plays an animated GIF that was paused with <a href=\"#/p5.Image/pause\">pause()</a>"
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses an animated GIF."
            +      ]
            +    },
            +    "delay": {
            +      "description": [
            +        "Changes the delay between frames in an animated GIF. There is an optional second parameter that indicates an index for a specific frame that should have its delay modified. If no index is given, all frames will have the new delay."
            +      ],
            +      "params": {
            +        "d": "Number: the amount in milliseconds to delay between switching frames",
            +        "index": "Number: (Optional) the index of the frame that should have the new delay value {optional}"
            +      }
            +    }
            +  },
            +  "p5.PrintWriter": {
            +    "params": {
            +      "filename": "String",
            +      "extension": "String (Optional)"
            +    },
            +    "write": {
            +      "description": [
            +        "Writes data to the PrintWriter stream"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be written by the PrintWriter"
            +      }
            +    },
            +    "print": {
            +      "description": [
            +        "Writes data to the PrintWriter stream, and adds a new line at the end"
            +      ],
            +      "params": {
            +        "data": "Array: all data to be printed by the PrintWriter"
            +      }
            +    },
            +    "clear": {
            +      "description": [
            +        "Clears the data already written to the PrintWriter object"
            +      ]
            +    },
            +    "close": {
            +      "description": [
            +        "Closes the PrintWriter"
            +      ]
            +    }
            +  },
            +  "p5.Table": {
            +    "description": [
            +      "<a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much like in a traditional spreadsheet. Tables can be generated from scratch, dynamically, or using data from an existing file."
            +    ],
            +    "params": {
            +      "rows": "p5.TableRow[]: (Optional) An array of p5.TableRow objects"
            +    },
            +    "columns": {
            +      "description": [
            +        "An array containing the names of the columns in the table, if the \"header\" the table is loaded with the \"header\" parameter."
            +      ]
            +    },
            +    "rows": {
            +      "description": [
            +        "An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the rows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a>"
            +      ]
            +    },
            +    "addRow": {
            +      "description": [
            +        "Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default, an empty row is created. Typically, you would store a reference to the new row in a TableRow object (see newRow in the example above), and then set individual values using <a href=\"#/p5/set\">set()</a>.",
            +        "If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is duplicated and added to the table."
            +      ],
            +      "returns": "p5.TableRow: the row that was added",
            +      "params": {
            +        "row": "p5.TableRow: (Optional) row to be added to the table"
            +      }
            +    },
            +    "removeRow": {
            +      "description": [
            +        "Removes a row from the table object."
            +      ],
            +      "params": {
            +        "id": "Integer: ID number of the row to remove"
            +      }
            +    },
            +    "getRow": {
            +      "description": [
            +        "Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference can then be used to get and set values of the selected row."
            +      ],
            +      "returns": "p5.TableRow: <a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +      "params": {
            +        "rowID": "Integer: ID number of the row to get"
            +      }
            +    },
            +    "getRows": {
            +      "description": [
            +        "Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s."
            +      ],
            +      "returns": "p5.TableRow[]: Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s"
            +    },
            +    "findRow": {
            +      "description": [
            +        "Finds the first row in the Table that contains the value provided, and returns a reference to that row. Even if multiple rows are possible matches, only the first matching row is returned. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow:",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "findRows": {
            +      "description": [
            +        "Finds the rows in the Table that contain the value provided, and returns references to those rows. Returns an Array, so for must be used to iterate through all the rows, as shown in the example above. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "value": "String: The value to match",
            +        "column": "Integer|String: ID number or title of the  column to search"
            +      }
            +    },
            +    "matchRow": {
            +      "description": [
            +        "Finds the first row in the Table that matches the regular expression provided, and returns a reference to that row. Even if multiple rows are possible matches, only the first matching row is returned. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow: TableRow object",
            +      "params": {
            +        "regexp": "String|RegExp: The regular expression to match",
            +        "column": "String|Integer: The column ID (number) or  title (string)"
            +      }
            +    },
            +    "matchRows": {
            +      "description": [
            +        "Finds the rows in the Table that match the regular expression provided, and returns references to those rows. Returns an array, so for must be used to iterate through all the rows, as shown in the example. The column to search may be specified by either its ID or title."
            +      ],
            +      "returns": "p5.TableRow[]: An Array of TableRow objects",
            +      "params": {
            +        "regexp": "String: The regular expression to match",
            +        "column": "String|Integer: (Optional) The column ID (number) or  title (string)"
            +      }
            +    },
            +    "getColumn": {
            +      "description": [
            +        "Retrieves all values in the specified column, and returns them as an array. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "Array: Array of column values",
            +      "params": {
            +        "column": "String|Number: String or Number of the column to return"
            +      }
            +    },
            +    "clearRows": {
            +      "description": [
            +        "Removes all rows from a Table. While all rows are removed, columns and column titles are maintained."
            +      ]
            +    },
            +    "addColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object. Typically, you will want to specify a title, so the column may be easily referenced later by name. (If no title is specified, the new column's title will be null.)"
            +      ],
            +      "params": {
            +        "title": "String: (Optional) title of the given column"
            +      }
            +    },
            +    "getColumnCount": {
            +      "description": [
            +        "Returns the total number of columns in a Table."
            +      ],
            +      "returns": "Integer: Number of columns in this table"
            +    },
            +    "getRowCount": {
            +      "description": [
            +        "Returns the total number of rows in a Table."
            +      ],
            +      "returns": "Integer: Number of rows in this table"
            +    },
            +    "removeTokens": {
            +      "description": [
            +        "Removes any of the specified characters (or \"tokens\").",
            +        "If no column is specified, then the values in all columns and rows are processed. A specific column may be referenced by either its ID or title."
            +      ],
            +      "params": {
            +        "chars": "String: String listing characters to be removed",
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "trim": {
            +      "description": [
            +        "Trims leading and trailing whitespace, such as spaces and tabs, from String table values. If no column is specified, then the values in all columns and rows are trimmed. A specific column may be referenced by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: (Optional) Column ID (number)  or name (string)"
            +      }
            +    },
            +    "removeColumn": {
            +      "description": [
            +        "Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table object. The column to be removed may be identified by either its title (a String) or its index value (an int). removeColumn(0) would remove the first column, removeColumn(1) would remove the second column, and so on."
            +      ],
            +      "params": {
            +        "column": "String|Integer: columnName (string) or ID (number)"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Stores a value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String|Number: value to assign"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Stores a Float value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "Number: value to assign"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Stores a String value in the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: column ID (Number)  or title (String)",
            +        "value": "String: value to assign"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retrieves a value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "String|Number:",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Retrieves a Float value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "Number:",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Retrieves a String value from the Table's specified row and column. The row is specified by its ID, while the column may be specified by either its ID or title."
            +      ],
            +      "returns": "String:",
            +      "params": {
            +        "row": "Integer: row ID",
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getObject": {
            +      "description": [
            +        "Retrieves all table data and returns as an object. If a column name is passed in, each row object will be stored with that attribute as its title."
            +      ],
            +      "returns": "Object:",
            +      "params": {
            +        "headerColumn": "String: (Optional) Name of the column which should be used to  title each row object (optional)"
            +      }
            +    },
            +    "getArray": {
            +      "description": [
            +        "Retrieves all table data and returns it as a multidimensional array."
            +      ],
            +      "returns": "Array:"
            +    }
            +  },
            +  "p5.TableRow": {
            +    "description": [
            +      "A TableRow object represents a single row of data values, stored in columns, from a table.",
            +      "A Table Row contains both an ordered array, and an unordered JSON object."
            +    ],
            +    "params": {
            +      "str": "String: (Optional) optional: populate the row with a  string of values, separated by the  separator",
            +      "separator": "String: (Optional) comma separated values (csv) by default"
            +    },
            +    "set": {
            +      "description": [
            +        "Stores a value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number: The value to be stored"
            +      }
            +    },
            +    "setNum": {
            +      "description": [
            +        "Stores a Float value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "Number|String: The value to be stored  as a Float"
            +      }
            +    },
            +    "setString": {
            +      "description": [
            +        "Stores a String value in the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "params": {
            +        "column": "String|Integer: Column ID (Number)  or Title (String)",
            +        "value": "String|Number|Boolean|Object: The value to be stored  as a String"
            +      }
            +    },
            +    "get": {
            +      "description": [
            +        "Retrieves a value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String|Number:",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Retrieves a Float value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "Number: Float Floating point number",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Retrieves an String value from the TableRow's specified column. The column may be specified by either its ID or title."
            +      ],
            +      "returns": "String: String",
            +      "params": {
            +        "column": "String|Integer: columnName (string) or  ID (number)"
            +      }
            +    }
            +  },
            +  "p5.XML": {
            +    "description": [
            +      "XML is a representation of an XML object, able to parse XML code. Use <a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects."
            +    ],
            +    "getParent": {
            +      "description": [
            +        "Gets a copy of the element's parent. Returns the parent as another <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "returns": "p5.XML: element parent"
            +    },
            +    "getName": {
            +      "description": [
            +        "Gets the element's full name, which is returned as a String."
            +      ],
            +      "returns": "String: the name of the node"
            +    },
            +    "setName": {
            +      "description": [
            +        "Sets the element's name, which is specified as a String."
            +      ],
            +      "params": {
            +        "the": "String: new name of the node"
            +      }
            +    },
            +    "hasChildren": {
            +      "description": [
            +        "Checks whether or not the element has any children, and returns the result as a boolean."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "listChildren": {
            +      "description": [
            +        "Get the names of all of the element's children, and returns the names as an array of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a> on each child element individually."
            +      ],
            +      "returns": "String[]: names of the children of the element"
            +    },
            +    "getChildren": {
            +      "description": [
            +        "Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When the name parameter is specified, then it will return all children that match that name."
            +      ],
            +      "returns": "p5.XML[]: children of the element",
            +      "params": {
            +        "name": "String: (Optional) element name"
            +      }
            +    },
            +    "getChild": {
            +      "description": [
            +        "Returns the first of the element's children that matches the name parameter or the child of the given index.It returns undefined if no matching child is found."
            +      ],
            +      "returns": "p5.XML:",
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "addChild": {
            +      "description": [
            +        "Appends a new child to the element. The child can be specified with either a String, which will be used as the new tag's name, or as a reference to an existing <a href=\"#/p5.XML\">p5.XML</a> object. A reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object."
            +      ],
            +      "params": {
            +        "node": "p5.XML: a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added"
            +      }
            +    },
            +    "removeChild": {
            +      "description": [
            +        "Removes the element specified by name or index."
            +      ],
            +      "params": {
            +        "name": "String|Integer: element name or index"
            +      }
            +    },
            +    "getAttributeCount": {
            +      "description": [
            +        "Counts the specified element's number of attributes, returned as an Number."
            +      ],
            +      "returns": "Integer:"
            +    },
            +    "listAttributes": {
            +      "description": [
            +        "Gets all of the specified element's attributes, and returns them as an array of Strings."
            +      ],
            +      "returns": "String[]: an array of strings containing the names of attributes"
            +    },
            +    "hasAttribute": {
            +      "description": [
            +        "Checks whether or not an element has the specified attribute."
            +      ],
            +      "returns": "Boolean: true if attribute found else false",
            +      "params": {
            +        "the": "String: attribute to be checked"
            +      }
            +    },
            +    "getNum": {
            +      "description": [
            +        "Returns an attribute value of the element as an Number. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, the value 0 is returned."
            +      ],
            +      "returns": "Number:",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "getString": {
            +      "description": [
            +        "Returns an attribute value of the element as an String. If the defaultValue parameter is specified and the attribute doesn't exist, then defaultValue is returned. If no defaultValue is specified and the attribute doesn't exist, null is returned."
            +      ],
            +      "returns": "String:",
            +      "params": {
            +        "name": "String: the non-null full name of the attribute",
            +        "defaultValue": "Number: (Optional) the default value of the attribute"
            +      }
            +    },
            +    "setAttribute": {
            +      "description": [
            +        "Sets the content of an element's attribute. The first parameter specifies the attribute name, while the second specifies the new content."
            +      ],
            +      "params": {
            +        "name": "String: the full name of the attribute",
            +        "value": "Number|String|Boolean: the value of the attribute"
            +      }
            +    },
            +    "getContent": {
            +      "description": [
            +        "Returns the content of an element. If there is no such content, defaultValue is returned if specified, otherwise null is returned."
            +      ],
            +      "returns": "String:",
            +      "params": {
            +        "defaultValue": "String: (Optional) value returned if no content is found"
            +      }
            +    },
            +    "setContent": {
            +      "description": [
            +        "Sets the element's content."
            +      ],
            +      "params": {
            +        "text": "String: the new content"
            +      }
            +    },
            +    "serialize": {
            +      "description": [
            +        "Serializes the element into a string. This function is useful for preparing the content to be sent over a http request or saved to file."
            +      ],
            +      "returns": "String: Serialized string of the element"
            +    }
            +  },
            +  "p5.Vector": {
            +    "description": [
            +      "A class to describe a two or three dimensional vector, specifically a Euclidean (also known as geometric) vector. A vector is an entity that has both magnitude and direction. The datatype, however, stores the components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude and direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.",
            +      "In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a position, velocity, or acceleration. For example, if you consider a rectangle moving across the screen, at any given instant it has a position (a vector that points from the origin to its location), a velocity (the rate at which the object's position changes per time unit, expressed as a vector), and acceleration (the rate at which the object's velocity changes per time unit, expressed as a vector).",
            +      "Since vectors represent groupings of values, we cannot simply use traditional addition/multiplication/etc. Instead, we'll need to do some \"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class."
            +    ],
            +    "params": {
            +      "x": "Number: (Optional) x component of the vector",
            +      "y": "Number: (Optional) y component of the vector",
            +      "z": "Number: (Optional) z component of the vector"
            +    },
            +    "x": {
            +      "description": [
            +        "The x component of the vector"
            +      ]
            +    },
            +    "y": {
            +      "description": [
            +        "The y component of the vector"
            +      ]
            +    },
            +    "z": {
            +      "description": [
            +        "The z component of the vector"
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Sets the x, y, and z component of the vector using two or three separate variables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array."
            +      ],
            +      "params": {
            +        "x": "Number: (Optional) the x component of the vector",
            +        "y": "Number: (Optional) the y component of the vector",
            +        "z": "Number: (Optional) the z component of the vector",
            +        "value": "p5.Vector|Number[]: the vector to set"
            +      }
            +    },
            +    "copy": {
            +      "description": [
            +        "Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object."
            +      ],
            +      "returns": "p5.Vector: the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    },
            +    "add": {
            +      "description": [
            +        "Adds x, y, and z components to a vector, adds one vector to another, or adds two independent vectors together. The version of the method that adds two vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to be added",
            +        "y": "Number: (Optional) the y component of the vector to be added",
            +        "z": "Number: (Optional) the z component of the vector to be added",
            +        "value": "p5.Vector|Number[]: the vector to add",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to add",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "rem": {
            +      "description": [
            +        "Gives remainder of a vector when it is divided by another vector. See examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of divisor vector",
            +        "y": "Number: the y component of divisor vector",
            +        "z": "Number: the z component of divisor vector",
            +        "value": "p5.Vector | Number[]: divisor vector",
            +        "v1": "p5.Vector: dividend <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: divisor <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "sub": {
            +      "description": [
            +        "Subtracts x, y, and z components from a vector, subtracts one vector from another, or subtracts two independent vectors. The version of the method that subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the other acts directly on the vector. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "x": "Number: the x component of the vector to subtract",
            +        "y": "Number: (Optional) the y component of the vector to subtract",
            +        "z": "Number: (Optional) the z component of the vector to subtract",
            +        "value": "p5.Vector|Number[]: the vector to subtract",
            +        "v1": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from",
            +        "v2": "p5.Vector: a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies the x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y, and z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector, the x, y, z components of both vectors are multiplied by each other (for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method creates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "n": "Number: The number to multiply with the vector",
            +        "x": "Number: The number to multiply with the x component of the vector",
            +        "y": "Number: The number to multiply with the y component of the vector",
            +        "z": "Number: (Optional) The number to multiply with the z component of the vector",
            +        "arr": "Number[]: The array to multiply with the components of the vector",
            +        "v": "p5.Vector: The vector to multiply with the components of the original vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "div": {
            +      "description": [
            +        "Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and z components of two vectors against each other. When dividing a vector by a scalar, the x, y, and z components of the vector are all divided by the scalar. When dividing a vector by a vector, the x, y, z components of the source vector are treated as the dividend, and the x, y, z components of the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z). The static version of this method creates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly. Additionally, you may provide arguments to this function as an array. See the examples for more context."
            +      ],
            +      "params": {
            +        "n": "Number: The number to divide the vector by",
            +        "x": "Number: The number to divide with the x component of the vector",
            +        "y": "Number: The number to divide with the y component of the vector",
            +        "z": "Number: (Optional) The number to divide with the z component of the vector",
            +        "arr": "Number[]: The array to divide the components of the vector by",
            +        "v": "p5.Vector: The vector to divide the components of the original vector by",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)",
            +        "v0": "p5.Vector",
            +        "v1": "p5.Vector"
            +      }
            +    },
            +    "mag": {
            +      "description": [
            +        "Calculates the magnitude (length) of the vector and returns the result as a float (this is simply the equation sqrt(x*x + y*y + z*z).)"
            +      ],
            +      "returns": "Number: magnitude of the vector",
            +      "params": {
            +        "vecT": "p5.Vector: the vector to return the magnitude of"
            +      }
            +    },
            +    "magSq": {
            +      "description": [
            +        "Calculates the squared magnitude of the vector and returns the result as a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.) Faster if the real length is not required in the case of comparing vectors, etc."
            +      ],
            +      "returns": "Number: squared magnitude of the vector"
            +    },
            +    "dot": {
            +      "description": [
            +        "Calculates the dot product of two vectors. The version of the method that computes the dot product of two independent vectors is a static method. See the examples for more context."
            +      ],
            +      "returns": "Number: the dot product",
            +      "params": {
            +        "x": "Number: x component of the vector",
            +        "y": "Number: (Optional) y component of the vector",
            +        "z": "Number: (Optional) z component of the vector",
            +        "value": "p5.Vector: value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "cross": {
            +      "description": [
            +        "Calculates and returns a vector composed of the cross product between two vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>. See the examples for more context."
            +      ],
            +      "returns": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +      "params": {
            +        "v": "p5.Vector: <a href=\"#/p5.Vector\">p5.Vector</a> to be crossed",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "dist": {
            +      "description": [
            +        "Calculates the Euclidean distance between two points (considering a point as a vector object)."
            +      ],
            +      "returns": "Number: the distance",
            +      "params": {
            +        "v": "p5.Vector: the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v1": "p5.Vector: the first <a href=\"#/p5.Vector\">p5.Vector</a>",
            +        "v2": "p5.Vector: the second <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "normalize": {
            +      "description": [
            +        "Normalize the vector to length 1 (make it a unit vector)."
            +      ],
            +      "returns": "p5.Vector: normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +      "params": {
            +        "v": "p5.Vector: the vector to normalize",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "limit": {
            +      "description": [
            +        "Limit the magnitude of this vector to the value used for the <b>max</b> parameter."
            +      ],
            +      "params": {
            +        "max": "Number: the maximum magnitude for the vector"
            +      }
            +    },
            +    "setMag": {
            +      "description": [
            +        "Set the magnitude of this vector to the value used for the <b>len</b> parameter."
            +      ],
            +      "params": {
            +        "len": "Number: the new length for this vector"
            +      }
            +    },
            +    "heading": {
            +      "description": [
            +        "Calculate the angle of rotation for this vector(only 2D vectors). p5.Vectors created using <a src=\"#/p5/createVector\">createVector()</a> will take the current <a = src=\"#/p5/angleMode\">angleMode</a> into consideration, and give the angle in radians or degree accordingly."
            +      ],
            +      "returns": "Number: the angle of rotation"
            +    },
            +    "setHeading": {
            +      "description": [
            +        "Rotate the vector to a specific angle (only 2D vectors), magnitude remains the same"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation"
            +      }
            +    },
            +    "rotate": {
            +      "description": [
            +        "Rotate the vector by an angle (only 2D vectors), magnitude remains the same"
            +      ],
            +      "params": {
            +        "angle": "Number: the angle of rotation",
            +        "v": "p5.Vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "angleBetween": {
            +      "description": [
            +        "Calculates and returns the angle (in radians) between two vectors."
            +      ],
            +      "returns": "Number: the angle between (in radians)",
            +      "params": {
            +        "value": "p5.Vector: the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      }
            +    },
            +    "lerp": {
            +      "description": [
            +        "Linear interpolate the vector to another vector"
            +      ],
            +      "params": {
            +        "x": "Number: the x component",
            +        "y": "Number: the y component",
            +        "z": "Number: the z component",
            +        "amt": "Number: the amount of interpolation; some value between 0.0  (old vector) and 1.0 (new vector). 0.9 is very near  the new vector. 0.5 is halfway in between.",
            +        "v": "p5.Vector: the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to",
            +        "v1": "p5.Vector",
            +        "v2": "p5.Vector",
            +        "target": "p5.Vector: (Optional) the vector to receive the result (Optional)"
            +      }
            +    },
            +    "reflect": {
            +      "description": [
            +        "Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D This method acts on the vector directly"
            +      ],
            +      "params": {
            +        "surfaceNormal": "p5.Vector: the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method"
            +      }
            +    },
            +    "array": {
            +      "description": [
            +        "Return a representation of this vector as a float array. This is only for temporary use. If used in any other fashion, the contents should be copied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own array."
            +      ],
            +      "returns": "Number[]: an Array with the 3 values"
            +    },
            +    "equals": {
            +      "description": [
            +        "Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a>"
            +      ],
            +      "returns": "Boolean: whether the vectors are equals",
            +      "params": {
            +        "x": "Number: (Optional) the x component of the vector",
            +        "y": "Number: (Optional) the y component of the vector",
            +        "z": "Number: (Optional) the z component of the vector",
            +        "value": "p5.Vector|Array: the vector to compare"
            +      }
            +    },
            +    "fromAngle": {
            +      "description": [
            +        "Make a new 2D vector from an angle"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +      "params": {
            +        "angle": "Number: the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)",
            +        "length": "Number: (Optional) the length of the new vector (defaults to 1)"
            +      }
            +    },
            +    "fromAngles": {
            +      "description": [
            +        "Make a new 3D vector from a pair of ISO spherical angles"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +      "params": {
            +        "theta": "Number: the polar angle, in radians (zero is up)",
            +        "phi": "Number: the azimuthal angle, in radians  (zero is out of the screen)",
            +        "length": "Number: (Optional) the length of the new vector (defaults to 1)"
            +      }
            +    },
            +    "random2D": {
            +      "description": [
            +        "Make a new 2D unit vector from a random angle"
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    },
            +    "random3D": {
            +      "description": [
            +        "Make a new random 3D unit vector."
            +      ],
            +      "returns": "p5.Vector: the new <a href=\"#/p5.Vector\">p5.Vector</a> object"
            +    }
            +  },
            +  "p5.Font": {
            +    "description": [
            +      "Base class for font handling"
            +    ],
            +    "params": {
            +      "pInst": "P5: (Optional) pointer to p5 instance"
            +    },
            +    "font": {
            +      "description": [
            +        "Underlying opentype font implementation"
            +      ]
            +    },
            +    "textBounds": {
            +      "description": [
            +        "Returns a tight bounding box for the given text string using this font"
            +      ],
            +      "returns": "Object: a rectangle object with properties: x, y, w, h",
            +      "params": {
            +        "line": "String: a line of text",
            +        "x": "Number: x-position",
            +        "y": "Number: y-position",
            +        "fontSize": "Number: (Optional) font size to use (optional) Default is 12.",
            +        "options": "Object: (Optional) opentype options (optional)  opentype fonts contains alignment and baseline options.  Default is 'LEFT' and 'alphabetic'"
            +      }
            +    },
            +    "textToPoints": {
            +      "description": [
            +        "Computes an array of points following the path for specified text"
            +      ],
            +      "returns": "Array: an array of points, each with x, y, alpha (the path angle)",
            +      "params": {
            +        "txt": "String: a line of text",
            +        "x": "Number: x-position",
            +        "y": "Number: y-position",
            +        "fontSize": "Number: font size to use (optional)",
            +        "options": "Object: (Optional) an (optional) object that can contain: sampleFactor - the ratio of path-length to number of samples (default=.1); higher values yield more points and are therefore more precise simplifyThreshold - if set to a non-zero value, collinear points will be be removed from the polygon; the value represents the threshold angle to use when determining whether two edges are collinear"
            +      }
            +    }
            +  },
            +  "p5.Camera": {
            +    "description": [
            +      "This class describes a camera for use in p5's <a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\"> WebGL mode</a>. It contains camera position, orientation, and projection information necessary for rendering a 3D scene.",
            +      "New p5.Camera objects can be made through the <a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through the methods described below. A camera created in this way will use a default position in the scene and a default perspective projection until these properties are changed through the various methods available. It is possible to create multiple cameras, in which case the current camera can be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.",
            +      "Note: The methods below operate in two coordinate systems: the 'world' coordinate system describe positions in terms of their relationship to the origin along the X, Y and Z axes whereas the camera's 'local' coordinate system describes positions from the camera's point of view: left-right, up-down, and forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method, for instance, moves the camera along its own axes, whereas the <a href=\"#/p5.Camera/setPosition\">setPosition()</a> method sets the camera's position in world-space.",
            +      "The camera object propreties <code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code> which describes camera position, orientation, and projection are also accessible via the camera object generated using <a href=\"#/p5/createCamera\">createCamera()</a>"
            +    ],
            +    "params": {
            +      "rendererGL": "RendererGL: instance of WebGL renderer"
            +    },
            +    "eyeX": {
            +      "description": [
            +        "camera position value on x axis"
            +      ]
            +    },
            +    "eyeY": {
            +      "description": [
            +        "camera position value on y axis"
            +      ]
            +    },
            +    "eyeZ": {
            +      "description": [
            +        "camera position value on z axis"
            +      ]
            +    },
            +    "centerX": {
            +      "description": [
            +        "x coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerY": {
            +      "description": [
            +        "y coordinate representing center of the sketch"
            +      ]
            +    },
            +    "centerZ": {
            +      "description": [
            +        "z coordinate representing center of the sketch"
            +      ]
            +    },
            +    "upX": {
            +      "description": [
            +        "x component of direction 'up' from camera"
            +      ]
            +    },
            +    "upY": {
            +      "description": [
            +        "y component of direction 'up' from camera"
            +      ]
            +    },
            +    "upZ": {
            +      "description": [
            +        "z component of direction 'up' from camera"
            +      ]
            +    },
            +    "perspective": {
            +      "description": [
            +        "Sets a perspective projection for a p5.Camera object and sets parameters for that projection according to <a href=\"#/p5/perspective\">perspective()</a> syntax."
            +      ]
            +    },
            +    "ortho": {
            +      "description": [
            +        "Sets an orthographic projection for a p5.Camera object and sets parameters for that projection according to <a href=\"#/p5/ortho\">ortho()</a> syntax."
            +      ]
            +    },
            +    "frustum": {
            +      "description": [
            +        "Sets the camera's frustum. Accepts the same parameters as the global <a href=\"#/p5/frustum\">frustum()</a>. More information on this function can be found there."
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Panning rotates the camera view to the left and right."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "tilt": {
            +      "description": [
            +        "Tilting rotates the camera view up and down."
            +      ],
            +      "params": {
            +        "angle": "Number: amount to rotate camera in current <a href=\"#/p5/angleMode\">angleMode</a> units. Greater than 0 values rotate counterclockwise (to the left)."
            +      }
            +    },
            +    "lookAt": {
            +      "description": [
            +        "Reorients the camera to look at a position in world space."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    },
            +    "camera": {
            +      "description": [
            +        "Sets a camera's position and orientation. This is equivalent to calling <a href=\"#/p5/camera\">camera()</a> on a p5.Camera object."
            +      ]
            +    },
            +    "move": {
            +      "description": [
            +        "Move camera along its local axes while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: amount to move along camera's left-right axis",
            +        "y": "Number: amount to move along camera's up-down axis",
            +        "z": "Number: amount to move along camera's forward-backward axis"
            +      }
            +    },
            +    "setPosition": {
            +      "description": [
            +        "Set camera position in world-space while maintaining current camera orientation."
            +      ],
            +      "params": {
            +        "x": "Number: x position of a point in world space",
            +        "y": "Number: y position of a point in world space",
            +        "z": "Number: z position of a point in world space"
            +      }
            +    }
            +  },
            +  "p5.Geometry": {
            +    "description": [
            +      "p5 Geometry class"
            +    ],
            +    "params": {
            +      "detailX": "Integer: (Optional) number of vertices on horizontal surface",
            +      "detailY": "Integer: (Optional) number of vertices on horizontal surface",
            +      "callback": "Function: (Optional) function to call upon object instantiation."
            +    },
            +    "computeFaces": {
            +      "description": [
            +        "computes faces for geometry objects based on the vertices."
            +      ]
            +    },
            +    "computeNormals": {
            +      "description": [
            +        "computes smooth normals per vertex as an average of each face."
            +      ]
            +    },
            +    "averageNormals": {
            +      "description": [
            +        "Averages the vertex normals. Used in curved surfaces"
            +      ]
            +    },
            +    "averagePoleNormals": {
            +      "description": [
            +        "Averages pole normals. Used in spherical primitives"
            +      ]
            +    },
            +    "normalize": {
            +      "description": [
            +        "Modifies all vertices to be centered within the range -100 to 100."
            +      ]
            +    }
            +  },
            +  "p5.Shader": {
            +    "description": [
            +      "Shader class for WEBGL Mode"
            +    ],
            +    "params": {
            +      "renderer": "p5.RendererGL: an instance of p5.RendererGL that will provide the GL context for this new p5.Shader",
            +      "vertSrc": "String: source code for the vertex shader (as a string)",
            +      "fragSrc": "String: source code for the fragment shader (as a string)"
            +    },
            +    "setUniform": {
            +      "description": [
            +        "Wrapper around gl.uniform functions. As we store uniform info in the shader we can use that to do type checking on the supplied data and call the appropriate function."
            +      ],
            +      "params": {
            +        "uniformName": "String: the name of the uniform in the shader program",
            +        "data": "Object|Number|Boolean|Number[]: the data to be associated with that uniform; type varies (could be a single numerical value, array, matrix, or texture / sampler reference)"
            +      }
            +    }
            +  },
            +  "p5.sound": {},
            +  "p5.SoundFile": {
            +    "description": [
            +      "SoundFile object with a path to a file.",
            +      "The p5.SoundFile may not be available immediately because it loads the file information asynchronously.",
            +      "To do something with the sound as soon as it loads pass the name of a function as the second parameter.",
            +      "Only one file path is required. However, audio file formats (i.e. mp3, ogg, wav and m4a/aac) are not supported by all web browsers. If you want to ensure compatibility, instead of a single file path, you may include an Array of filepaths, and the browser will choose a format that works."
            +    ],
            +    "params": {
            +      "path": "String|Array: path to a sound file (String). Optionally,  you may include multiple file formats in  an array. Alternately, accepts an object  from the HTML5 File API, or a p5.File.",
            +      "successCallback": "Function: (Optional) Name of a function to call once file loads",
            +      "errorCallback": "Function: (Optional) Name of a function to call if file fails to  load. This function will receive an error or  XMLHttpRequest object with information  about what went wrong.",
            +      "whileLoadingCallback": "Function: (Optional) Name of a function to call while file  is loading. That function will  receive progress of the request to  load the sound file  (between 0 and 1) as its first  parameter. This progress  does not account for the additional  time needed to decode the audio data."
            +    },
            +    "isLoaded": {
            +      "description": [
            +        "Returns true if the sound file finished loading successfully."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "play": {
            +      "description": [
            +        "Play the p5.SoundFile"
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule playback to start (in seconds from now).",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) amplitude (volume)  of playback",
            +        "cueStart": "Number: (Optional) (optional) cue start time in seconds",
            +        "duration": "Number: (Optional) (optional) duration of playback in seconds"
            +      }
            +    },
            +    "playMode": {
            +      "description": [
            +        "p5.SoundFile has two play modes: <code>restart</code> and <code>sustain</code>. Play Mode determines what happens to a p5.SoundFile if it is triggered while in the middle of playback. In sustain mode, playback will continue simultaneous to the new playback. In restart mode, play() will stop playback and start over. With untilDone, a sound will play only if it's not already playing. Sustain is the default mode."
            +      ],
            +      "params": {
            +        "str": "String: 'restart' or 'sustain' or 'untilDone'"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pauses a file that is currently playing. If the file is not playing, then nothing will happen.",
            +        "After pausing, .play() will resume from the paused position. If p5.SoundFile had been set to loop before it was paused, it will continue to loop after it is unpaused with .play()."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop the p5.SoundFile. Accepts optional parameters to set the playback rate, playback volume, loopStart, loopEnd."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  seconds from now",
            +        "rate": "Number: (Optional) (optional) playback rate",
            +        "amp": "Number: (Optional) (optional) playback volume",
            +        "cueLoopStart": "Number: (Optional) (optional) startTime in seconds",
            +        "duration": "Number: (Optional) (optional) loop duration in seconds"
            +      }
            +    },
            +    "setLoop": {
            +      "description": [
            +        "Set a p5.SoundFile's looping flag to true or false. If the sound is currently playing, this change will take effect when it reaches the end of the current playback."
            +      ],
            +      "params": {
            +        "Boolean": "Boolean: set looping to true or false"
            +      }
            +    },
            +    "isLooping": {
            +      "description": [
            +        "Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "isPlaying": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is playing, false if not (i.e. paused or stopped)."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "isPaused": {
            +      "description": [
            +        "Returns true if a p5.SoundFile is paused, false if not (i.e. playing or stopped)."
            +      ],
            +      "returns": "Boolean:"
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop soundfile playback."
            +      ],
            +      "params": {
            +        "startTime": "Number: (Optional) (optional) schedule event to occur  in seconds from now"
            +      }
            +    },
            +    "pan": {
            +      "description": [
            +        "Set the stereo panning of a p5.sound object to a floating point number between -1.0 (left) and 1.0 (right). Default is 0.0 (center)."
            +      ],
            +      "params": {
            +        "panValue": "Number: (Optional) Set the stereo panner",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current stereo pan position (-1.0 to 1.0)"
            +      ],
            +      "returns": "Number: Returns the stereo pan setting of the Oscillator  as a number between -1.0 (left) and 1.0 (right).  0.0 is center and default."
            +    },
            +    "rate": {
            +      "description": [
            +        "Set the playback rate of a sound file. Will change the speed and the pitch. Values less than zero will reverse the audio buffer."
            +      ],
            +      "params": {
            +        "playbackRate": "Number: (Optional) Set the playback rate. 1.0 is normal,  .5 is half-speed, 2.0 is twice as fast.  Values less than zero play backwards."
            +      }
            +    },
            +    "setVolume": {
            +      "description": [
            +        "Multiply the output volume (amplitude) of a sound file between 0.0 (silence) and 1.0 (full volume). 1.0 is the maximum amplitude of a digital sound, so multiplying by greater than 1.0 may cause digital distortion. To fade, provide a <code>rampTime</code> parameter. For more complex fades, see the Envelope class.",
            +        "Alternately, you can pass in a signal source such as an oscillator to modulate the amplitude with an audio signal."
            +      ],
            +      "params": {
            +        "volume": "Number|Object: Volume (amplitude) between 0.0  and 1.0 or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Fade for t seconds",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen at  t seconds in the future"
            +      }
            +    },
            +    "duration": {
            +      "description": [
            +        "Returns the duration of a sound file in seconds."
            +      ],
            +      "returns": "Number: The duration of the soundFile in seconds."
            +    },
            +    "currentTime": {
            +      "description": [
            +        "Return the current position of the p5.SoundFile playhead, in seconds. Time is relative to the normal buffer direction, so if <code>reverseBuffer</code> has been called, currentTime will count backwards."
            +      ],
            +      "returns": "Number: currentTime of the soundFile in seconds."
            +    },
            +    "jump": {
            +      "description": [
            +        "Move the playhead of a soundfile that is currently playing to a new position and a new duration, in seconds. If none are given, will reset the file to play entire duration from start to finish. To set the position of a soundfile that is not currently playing, use the <code>play</code> or <code>loop</code> methods."
            +      ],
            +      "params": {
            +        "cueTime": "Number: cueTime of the soundFile in seconds.",
            +        "duration": "Number: duration in seconds."
            +      }
            +    },
            +    "channels": {
            +      "description": [
            +        "Return the number of channels in a sound file. For example, Mono = 1, Stereo = 2."
            +      ],
            +      "returns": "Number: [channels]"
            +    },
            +    "sampleRate": {
            +      "description": [
            +        "Return the sample rate of the sound file."
            +      ],
            +      "returns": "Number: [sampleRate]"
            +    },
            +    "frames": {
            +      "description": [
            +        "Return the number of samples in a sound file. Equal to sampleRate * duration."
            +      ],
            +      "returns": "Number: [sampleCount]"
            +    },
            +    "getPeaks": {
            +      "description": [
            +        "Returns an array of amplitude peaks in a p5.SoundFile that can be used to draw a static waveform. Scans through the p5.SoundFile's audio buffer to find the greatest amplitudes. Accepts one parameter, 'length', which determines size of the array. Larger arrays result in more precise waveform visualizations.",
            +        "Inspired by Wavesurfer.js."
            +      ],
            +      "returns": "Float32Array: Array of peaks.",
            +      "params": {
            +        "length": "Number: (Optional) length is the size of the returned array.  Larger length results in more precision.  Defaults to 5*width of the browser window."
            +      }
            +    },
            +    "reverseBuffer": {
            +      "description": [
            +        "Reverses the p5.SoundFile's buffer source. Playback must be handled separately (see example)."
            +      ]
            +    },
            +    "onended": {
            +      "description": [
            +        "Schedule an event to be called when the soundfile reaches the end of a buffer. If the soundfile is playing through once, this will be called when it ends. If it is looping, it will be called when stop is called."
            +      ],
            +      "params": {
            +        "callback": "Function: function to call when the  soundfile has ended."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connects the output of a p5sound object to input of another p5.sound object. For example, you may connect a p5.SoundFile to an FFT or an Effect. If no parameter is given, it will connect to the master output. Most p5sound objects connect to the master output when they are created."
            +      ],
            +      "params": {
            +        "object": "Object: (Optional) Audio object that accepts an input"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnects the output of this p5sound object."
            +      ]
            +    },
            +    "setPath": {
            +      "description": [
            +        "Reset the source for this SoundFile to a new path (URL)."
            +      ],
            +      "params": {
            +        "path": "String: path to audio file",
            +        "callback": "Function: Callback"
            +      }
            +    },
            +    "setBuffer": {
            +      "description": [
            +        "Replace the current Audio Buffer with a new Buffer."
            +      ],
            +      "params": {
            +        "buf": "Array: Array of Float32 Array(s). 2 Float32 Arrays  will create a stereo source. 1 will create  a mono source."
            +      }
            +    },
            +    "addCue": {
            +      "description": [
            +        "Schedule events to trigger every time a MediaElement (audio/video) reaches a playback cue point.",
            +        "Accepts a callback function, a time (in seconds) at which to trigger the callback, and an optional parameter for the callback.",
            +        "Time will be passed as the first parameter to the callback function, and param will be the second parameter."
            +      ],
            +      "returns": "Number: id ID of this cue,  useful for removeCue(id)",
            +      "params": {
            +        "time": "Number: Time in seconds, relative to this media  element's playback. For example, to trigger  an event every time playback reaches two  seconds, pass in the number 2. This will be  passed as the first parameter to  the callback function.",
            +        "callback": "Function: Name of a function that will be  called at the given time. The callback will  receive time and (optionally) param as its  two parameters.",
            +        "value": "Object: (Optional) An object to be passed as the  second parameter to the  callback function."
            +      }
            +    },
            +    "removeCue": {
            +      "description": [
            +        "Remove a callback based on its ID. The ID is returned by the addCue method."
            +      ],
            +      "params": {
            +        "id": "Number: ID of the cue, as returned by addCue"
            +      }
            +    },
            +    "clearCues": {
            +      "description": [
            +        "Remove all of the callbacks that had originally been scheduled via the addCue method."
            +      ]
            +    },
            +    "save": {
            +      "description": [
            +        "Save a p5.SoundFile as a .wav file. The browser will prompt the user to download the file to their device. To upload a file to a server, see <a href=\"/docs/reference/#/p5.SoundFile/getBlob\">getBlob</a>"
            +      ],
            +      "params": {
            +        "fileName": "String: (Optional) name of the resulting .wav file."
            +      }
            +    },
            +    "getBlob": {
            +      "description": [
            +        "This method is useful for sending a SoundFile to a server. It returns the .wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at MDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\". A Blob is a file-like data object that can be uploaded to a server with an <a href=\"/docs/reference/#/p5/httpDo\">http</a> request. We'll use the <code>httpDo</code> options object to send a POST request with some specific options: we encode the request as <code>multipart/form-data</code>, and attach the blob as one of the form values using <code>FormData</code>."
            +      ],
            +      "returns": "Blob: A file-like data object"
            +    }
            +  },
            +  "p5.Amplitude": {
            +    "description": [
            +      "Amplitude measures volume between 0.0 and 1.0. Listens to all p5sound by default, or use setInput() to listen to a specific sound source. Accepts an optional smoothing value, which defaults to 0."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) between 0.0 and .999 to smooth  amplitude readings (defaults to 0)"
            +    },
            +    "setInput": {
            +      "description": [
            +        "Connects to the p5sound instance (master output) by default. Optionally, you can pass in a specific source (i.e. a soundfile)."
            +      ],
            +      "params": {
            +        "snd": "SoundObject|undefined: (Optional) set the sound source  (optional, defaults to  master output)",
            +        "smoothing": "Number|undefined: (Optional) a range between 0.0 and 1.0  to smooth amplitude readings"
            +      }
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Returns a single Amplitude reading at the moment it is called. For continuous readings, run in the draw loop."
            +      ],
            +      "returns": "Number: Amplitude as a number between 0.0 and 1.0",
            +      "params": {
            +        "channel": "Number: (Optional) Optionally return only channel 0 (left) or 1 (right)"
            +      }
            +    },
            +    "toggleNormalize": {
            +      "description": [
            +        "Determines whether the results of Amplitude.process() will be Normalized. To normalize, Amplitude finds the difference the loudest reading it has processed and the maximum amplitude of 1.0. Amplitude adds this difference to all values to produce results that will reliably map between 0.0 and 1.0. However, if a louder moment occurs, the amount that Normalize adds to all the values will change. Accepts an optional boolean parameter (true or false). Normalizing is off by default."
            +      ],
            +      "params": {
            +        "boolean": "Boolean: (Optional) set normalize to true (1) or false (0)"
            +      }
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth Amplitude analysis by averaging with the last analysis frame. Off by default."
            +      ],
            +      "params": {
            +        "set": "Number: smoothing from 0.0 <= 1"
            +      }
            +    }
            +  },
            +  "p5.FFT": {
            +    "description": [
            +      "FFT (Fast Fourier Transform) is an analysis algorithm that isolates individual <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\"> audio frequencies</a> within a waveform.",
            +      "Once instantiated, a p5.FFT object can return an array based on two types of analyses: • <code>FFT.waveform()</code> computes amplitude values along the time domain. The array indices correspond to samples across a brief moment in time. Each value represents amplitude of the waveform at that sample of time. • <code>FFT.analyze() </code> computes amplitude values along the frequency domain. The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Use with <code>getEnergy()</code> to measure amplitude at specific frequencies, or within a range of frequencies.",
            +      "FFT analyzes a very short snapshot of sound called a sample buffer. It returns an array of amplitude measurements, referred to as <code>bins</code>. The array is 1024 bins long by default. You can change the bin array length, but it must be a power of 2 between 16 and 1024 in order for the FFT algorithm to function correctly. The actual size of the FFT buffer is twice the number of bins, so given a standard sample rate, the buffer is 2048/44100 seconds long."
            +    ],
            +    "params": {
            +      "smoothing": "Number: (Optional) Smooth results of Freq Spectrum.  0.0 < smoothing < 1.0.  Defaults to 0.8.",
            +      "bins": "Number: (Optional) Length of resulting array.  Must be a power of two between  16 and 1024. Defaults to 1024."
            +    },
            +    "setInput": {
            +      "description": [
            +        "Set the input source for the FFT analysis. If no source is provided, FFT will analyze all sound in the sketch."
            +      ],
            +      "params": {
            +        "source": "Object: (Optional) p5.sound object (or web audio API source node)"
            +      }
            +    },
            +    "waveform": {
            +      "description": [
            +        "Returns an array of amplitude values (between -1.0 and +1.0) that represent a snapshot of amplitude readings in a single buffer. Length will be equal to bins (defaults to 1024). Can be used to draw the waveform of a sound."
            +      ],
            +      "returns": "Array: Array Array of amplitude values (-1 to 1)  over time. Array length = bins.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "precision": "String: (Optional) If any value is provided, will return results  in a Float32 Array which is more precise  than a regular array."
            +      }
            +    },
            +    "analyze": {
            +      "description": [
            +        "Returns an array of amplitude values (between 0 and 255) across the frequency spectrum. Length is equal to FFT bins (1024 by default). The array indices correspond to frequencies (i.e. pitches), from the lowest to the highest that humans can hear. Each value represents amplitude at that slice of the frequency spectrum. Must be called prior to using <code>getEnergy()</code>."
            +      ],
            +      "returns": "Array: spectrum Array of energy (amplitude/volume)  values across the frequency spectrum.  Lowest energy (silence) = 0, highest  possible is 255.",
            +      "params": {
            +        "bins": "Number: (Optional) Must be a power of two between  16 and 1024. Defaults to 1024.",
            +        "scale": "Number: (Optional) If \"dB,\" returns decibel  float measurements between  -140 and 0 (max).  Otherwise returns integers from 0-255."
            +      }
            +    },
            +    "getEnergy": {
            +      "description": [
            +        "Returns the amount of energy (volume) at a specific <a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\"> frequency</a>, or the average amount of energy between two frequencies. Accepts Number(s) corresponding to frequency (in Hz), or a String corresponding to predefined frequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\"). Returns a range between 0 (no energy/volume at that frequency) and 255 (maximum energy). <em>NOTE: analyze() must be called prior to getEnergy(). Analyze() tells the FFT to analyze frequency data, and getEnergy() uses the results determine the value at a specific frequency or range of frequencies.</em>"
            +      ],
            +      "returns": "Number: Energy Energy (volume/amplitude) from  0 and 255.",
            +      "params": {
            +        "frequency1": "Number|String: Will return a value representing  energy at this frequency. Alternately,  the strings \"bass\", \"lowMid\" \"mid\",  \"highMid\", and \"treble\" will return  predefined frequency ranges.",
            +        "frequency2": "Number: (Optional) If a second frequency is given,  will return average amount of  energy that exists between the  two frequencies."
            +      }
            +    },
            +    "getCentroid": {
            +      "description": [
            +        "Returns the <a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\"> spectral centroid</a> of the input signal. <em>NOTE: analyze() must be called prior to getCentroid(). Analyze() tells the FFT to analyze frequency data, and getCentroid() uses the results determine the spectral centroid.</em>"
            +      ],
            +      "returns": "Number: Spectral Centroid Frequency Frequency of the spectral centroid in Hz."
            +    },
            +    "smooth": {
            +      "description": [
            +        "Smooth FFT analysis by averaging with the last analysis frame."
            +      ],
            +      "params": {
            +        "smoothing": "Number: 0.0 < smoothing < 1.0.  Defaults to 0.8."
            +      }
            +    },
            +    "linAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values for a given number of frequency bands split equally. N defaults to 16. <em>NOTE: analyze() must be called prior to linAverages(). Analyze() tells the FFT to analyze frequency data, and linAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: linearAverages Array of average amplitude values for each group",
            +      "params": {
            +        "N": "Number: Number of returned frequency groups"
            +      }
            +    },
            +    "logAverages": {
            +      "description": [
            +        "Returns an array of average amplitude values of the spectrum, for a given set of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\"> Octave Bands</a> <em>NOTE: analyze() must be called prior to logAverages(). Analyze() tells the FFT to analyze frequency data, and logAverages() uses the results to group them into a smaller set of averages.</em>"
            +      ],
            +      "returns": "Array: logAverages Array of average amplitude values for each group",
            +      "params": {
            +        "octaveBands": "Array: Array of Octave Bands objects for grouping"
            +      }
            +    },
            +    "getOctaveBands": {
            +      "description": [
            +        "Calculates and Returns the 1/N <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a> N defaults to 3 and minimum central frequency to 15.625Hz. (1/3 Octave Bands ~= 31 Frequency Bands) Setting fCtr0 to a central value of a higher octave will ignore the lower bands and produce less frequency groups."
            +      ],
            +      "returns": "Array: octaveBands Array of octave band objects with their bounds",
            +      "params": {
            +        "N": "Number: Specifies the 1/N type of generated octave bands",
            +        "fCtr0": "Number: Minimum central frequency for the lowest band"
            +      }
            +    }
            +  },
            +  "p5.Oscillator": {
            +    "description": [
            +      "Creates a signal that oscillates between -1.0 and 1.0. By default, the oscillation takes the form of a sinusoidal shape ('sine'). Additional types include 'triangle', 'sawtooth' and 'square'. The frequency defaults to 440 oscillations per second (440Hz, equal to the pitch of an 'A' note).",
            +      "Set the type of oscillation with setType(), or by instantiating a specific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a href=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a href=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a href=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) frequency defaults to 440Hz",
            +      "type": "String: (Optional) type of oscillator. Options:  'sine' (default), 'triangle',  'sawtooth', 'square'"
            +    },
            +    "start": {
            +      "description": [
            +        "Start an oscillator.",
            +        "Starting an oscillator on a user gesture will enable audio in browsers that have a strict autoplay policy, including Chrome and most mobile devices. See also: <code>userStartAudio()</code>."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) startTime in seconds from now.",
            +        "frequency": "Number: (Optional) frequency in Hz."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop an oscillator. Accepts an optional parameter to determine how long (in seconds from now) until the oscillator stops."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: Time, in seconds from now."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the amplitude between 0 and 1.0. Or, pass in an object such as an oscillator to modulate amplitude with an audio signal."
            +      ],
            +      "returns": "AudioParam: gain If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's  gain/amplitude/volume)",
            +      "params": {
            +        "vol": "Number|Object: between 0 and 1.0  or a modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getAmp": {
            +      "description": [
            +        "Returns the value of output gain"
            +      ],
            +      "returns": "Number: Amplitude value between 0.0 and 1.0"
            +    },
            +    "freq": {
            +      "description": [
            +        "Set frequency of an oscillator to a value. Or, pass in an object such as an oscillator to modulate the frequency with an audio signal."
            +      ],
            +      "returns": "AudioParam: Frequency If no value is provided,  returns the Web Audio API  AudioParam that controls  this oscillator's frequency",
            +      "params": {
            +        "Frequency": "Number|Object: Frequency in Hz  or modulating signal/oscillator",
            +        "rampTime": "Number: (Optional) Ramp time (in seconds)",
            +        "timeFromNow": "Number: (Optional) Schedule this event to happen  at x seconds from now"
            +      }
            +    },
            +    "getFreq": {
            +      "description": [
            +        "Returns the value of frequency of oscillator"
            +      ],
            +      "returns": "Number: Frequency of oscillator in Hertz"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type to 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "params": {
            +        "type": "String: 'sine', 'triangle', 'sawtooth' or 'square'."
            +      }
            +    },
            +    "getType": {
            +      "description": [
            +        "Returns current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'."
            +      ],
            +      "returns": "String: type of oscillator eg . 'sine', 'triangle', 'sawtooth' or 'square'."
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "pan": {
            +      "description": [
            +        "Pan between Left (-1) and Right (1)"
            +      ],
            +      "params": {
            +        "panning": "Number: Number between -1 and 1",
            +        "timeFromNow": "Number: schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "getPan": {
            +      "description": [
            +        "Returns the current value of panPosition , between Left (-1) and Right (1)"
            +      ],
            +      "returns": "Number: panPosition of oscillator , between Left (-1) and Right (1)"
            +    },
            +    "phase": {
            +      "description": [
            +        "Set the phase of an oscillator between 0.0 and 1.0. In this implementation, phase is a delay time based on the oscillator's current frequency."
            +      ],
            +      "params": {
            +        "phase": "Number: float between 0.0 and 1.0"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Oscillator's output amplitude by a fixed value (i.e. turn it up!). Calling this method again will override the initial mult() with a new value."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with multiplied output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this oscillator's amplitude values to a given range, and return the oscillator. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Oscillator: Oscillator Returns this oscillator  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.SinOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SinOsc()</code>. This creates a Sine Wave Oscillator and is equivalent to <code> new p5.Oscillator('sine') </code> or creating a p5.Oscillator and then calling its method <code>setType('sine')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.TriOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.TriOsc()</code>. This creates a Triangle Wave Oscillator and is equivalent to <code>new p5.Oscillator('triangle') </code> or creating a p5.Oscillator and then calling its method <code>setType('triangle')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SawOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SawOsc()</code>. This creates a SawTooth Wave Oscillator and is equivalent to <code> new p5.Oscillator('sawtooth') </code> or creating a p5.Oscillator and then calling its method <code>setType('sawtooth')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.SqrOsc": {
            +    "description": [
            +      "Constructor: <code>new p5.SqrOsc()</code>. This creates a Square Wave Oscillator and is equivalent to <code> new p5.Oscillator('square') </code> or creating a p5.Oscillator and then calling its method <code>setType('square')</code>. See p5.Oscillator for methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Set the frequency"
            +    }
            +  },
            +  "p5.Envelope": {
            +    "description": [
            +      "Envelopes are pre-defined amplitude distribution over time. Typically, envelopes are used to control the output volume of an object, a series of fades referred to as Attack, Decay, Sustain and Release ( <a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a> ). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can control an Oscillator's frequency like this: <code>osc.freq(env)</code>.",
            +      "Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level. Use <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.",
            +      "Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope, the <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger, or <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/ <code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff."
            +    ],
            +    "attackTime": {
            +      "description": [
            +        "Time until envelope reaches attackLevel"
            +      ]
            +    },
            +    "attackLevel": {
            +      "description": [
            +        "Level once attack is complete."
            +      ]
            +    },
            +    "decayTime": {
            +      "description": [
            +        "Time until envelope reaches decayLevel."
            +      ]
            +    },
            +    "decayLevel": {
            +      "description": [
            +        "Level after decay. The envelope will sustain here until it is released."
            +      ]
            +    },
            +    "releaseTime": {
            +      "description": [
            +        "Duration of the release portion of the envelope."
            +      ]
            +    },
            +    "releaseLevel": {
            +      "description": [
            +        "Level at the end of the release."
            +      ]
            +    },
            +    "set": {
            +      "description": [
            +        "Reset the envelope with a series of time/value pairs."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds) before level  reaches attackLevel",
            +        "attackLevel": "Number: Typically an amplitude between  0.0 and 1.0",
            +        "decayTime": "Number: Time",
            +        "decayLevel": "Number: Amplitude (In a standard ADSR envelope,  decayLevel = sustainLevel)",
            +        "releaseTime": "Number: Release Time (in seconds)",
            +        "releaseLevel": "Number: Amplitude"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setRange": {
            +      "description": [
            +        "Set max (attackLevel) and min (releaseLevel) of envelope."
            +      ],
            +      "params": {
            +        "aLevel": "Number: attack level (defaults to 1)",
            +        "rLevel": "Number: release level (defaults to 0)"
            +      }
            +    },
            +    "setInput": {
            +      "description": [
            +        "Assign a parameter to be controlled by this envelope. If a p5.Sound object is given, then the p5.Envelope will control its output gain. If multiple inputs are provided, the env will control all of them."
            +      ],
            +      "params": {
            +        "inputs": "Object: (Optional) A p5.sound object or  Web Audio Param."
            +      }
            +    },
            +    "setExp": {
            +      "description": [
            +        "Set whether the envelope ramp is linear (default) or exponential. Exponential ramps can be useful because we perceive amplitude and frequency logarithmically."
            +      ],
            +      "params": {
            +        "isExp": "Boolean: true is exponential, false is linear"
            +      }
            +    },
            +    "play": {
            +      "description": [
            +        "Play tells the envelope to start acting on a given input. If the input is a p5.sound object (i.e. AudioIn, Oscillator, SoundFile), then Envelope will control its output volume. Envelopes can also be used to control any <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Audio Param.</a>"
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound object or  Web Audio Param.",
            +        "startTime": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go. Input can be any p5.sound object, or a <a href=\" http://docs.webplatform.org/wiki/apis/webaudio/AudioParam\"> Web Audio Param</a>."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time from now (in seconds)"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the Release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "ramp": {
            +      "description": [
            +        "Exponentially ramp to a value using the first two values from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code> as <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\"> time constants</a> for simple exponential ramps. If the value is higher than current value, it uses attackTime, while a decrease uses decayTime."
            +      ],
            +      "params": {
            +        "unit": "Object: p5.sound Object or Web Audio Param",
            +        "secondsFromNow": "Number: When to trigger the ramp",
            +        "v": "Number: Target value",
            +        "v2": "Number: (Optional) Second target value (optional)"
            +      }
            +    },
            +    "add": {
            +      "description": [
            +        "Add a value to the p5.Oscillator's output amplitude, and return the oscillator. Calling this method again will override the initial add() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to add"
            +      }
            +    },
            +    "mult": {
            +      "description": [
            +        "Multiply the p5.Envelope's output amplitude by a fixed value. Calling this method again will override the initial mult() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "number": "Number: Constant number to multiply"
            +      }
            +    },
            +    "scale": {
            +      "description": [
            +        "Scale this envelope's amplitude values to a given range, and return the envelope. Calling this method again will override the initial scale() with new values."
            +      ],
            +      "returns": "p5.Envelope: Envelope Returns this envelope  with scaled output",
            +      "params": {
            +        "inMin": "Number: input range minumum",
            +        "inMax": "Number: input range maximum",
            +        "outMin": "Number: input range minumum",
            +        "outMax": "Number: input range maximum"
            +      }
            +    }
            +  },
            +  "p5.Noise": {
            +    "description": [
            +      "Noise is a type of oscillator that generates a buffer with random values."
            +    ],
            +    "params": {
            +      "type": "String: Type of noise can be 'white' (default),  'brown' or 'pink'."
            +    },
            +    "setType": {
            +      "description": [
            +        "Set type of noise to 'white', 'pink' or 'brown'. White is the default."
            +      ],
            +      "params": {
            +        "type": "String: (Optional) 'white', 'pink' or 'brown'"
            +      }
            +    }
            +  },
            +  "p5.Pulse": {
            +    "description": [
            +      "Creates a Pulse object, an oscillator that implements Pulse Width Modulation. The pulse is created with two oscillators. Accepts a parameter for frequency, and to set the width between the pulses. See <a href=\" http://p5js.org/reference/#/p5.Oscillator\"> <code>p5.Oscillator</code> for a full list of methods."
            +    ],
            +    "params": {
            +      "freq": "Number: (Optional) Frequency in oscillations per second (Hz)",
            +      "w": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +    },
            +    "width": {
            +      "description": [
            +        "Set the width of a Pulse object (an oscillator that implements Pulse Width Modulation)."
            +      ],
            +      "params": {
            +        "width": "Number: (Optional) Width between the pulses (0 to 1.0,  defaults to 0)"
            +      }
            +    }
            +  },
            +  "p5.AudioIn": {
            +    "description": [
            +      "Get audio from an input, i.e. your computer's microphone.",
            +      "Turn the mic on/off with the start() and stop() methods. When the mic is on, its volume can be measured with getLevel or by connecting an FFT object.",
            +      "If you want to hear the AudioIn, use the .connect() method. AudioIn does not connect to p5.sound output by default to prevent feedback.",
            +      "<em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/ Stream</a> API, which is not supported by certain browsers. Access in Chrome browser is limited to localhost and https, but access over http may be limited.</em>"
            +    ],
            +    "params": {
            +      "errorCallback": "Function: (Optional) A function to call if there is an error  accessing the AudioIn. For example,  Safari and iOS devices do not  currently allow microphone access."
            +    },
            +    "input": {},
            +    "output": {},
            +    "stream": {},
            +    "mediaStream": {},
            +    "currentSource": {},
            +    "enabled": {
            +      "description": [
            +        "Client must allow browser to access their microphone / audioin source. Default: false. Will become true when the client enables access."
            +      ]
            +    },
            +    "amplitude": {
            +      "description": [
            +        "Input amplitude, connect to it by default but not to master out"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start processing audio input. This enables the use of other AudioIn methods like getLevel(). Note that by default, AudioIn is not connected to p5.sound's output. So you won't hear anything unless you use the connect() method.<br/>",
            +        "Certain browsers limit access to the user's microphone. For example, Chrome only allows access from localhost and over https. For this reason, you may want to include an errorCallback—a function that is called in case the browser won't provide mic access."
            +      ],
            +      "params": {
            +        "successCallback": "Function: (Optional) Name of a function to call on  success.",
            +        "errorCallback": "Function: (Optional) Name of a function to call if  there was an error. For example,  some browsers do not support  getUserMedia."
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel(). If re-starting, the user may be prompted for permission access."
            +      ]
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to an audio unit. If no parameter is provided, will connect to the master output (i.e. your speakers).<br/>"
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) An object that accepts audio input,  such as an FFT"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect the AudioIn from all audio units. For example, if connect() had been called, disconnect() will stop sending signal to your speakers.<br/>"
            +      ]
            +    },
            +    "getLevel": {
            +      "description": [
            +        "Read the Amplitude (volume level) of an AudioIn. The AudioIn class contains its own instance of the Amplitude class to help make it easy to get a microphone's volume level. Accepts an optional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must .start() before using .getLevel().</em><br/>"
            +      ],
            +      "returns": "Number: Volume level (between 0.0 and 1.0)",
            +      "params": {
            +        "smoothing": "Number: (Optional) Smoothing is 0.0 by default.  Smooths values based on previous values."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set amplitude (volume) of a mic input between 0 and 1.0. <br/>"
            +      ],
            +      "params": {
            +        "vol": "Number: between 0 and 1.0",
            +        "time": "Number: (Optional) ramp time (optional)"
            +      }
            +    },
            +    "getSources": {
            +      "description": [
            +        "Returns a list of available input sources. This is a wrapper for <a title=\"MediaDevices.enumerateDevices() - Web APIs | MDN\" target=\"_blank\" href=  \"<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"\">https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"</a> <blockquote>"
            +      ],
            +      "returns": "Promise: Returns a Promise that can be used in place of the callbacks, similar  to the enumerateDevices() method",
            +      "params": {
            +        "successCallback": "Function: (Optional) This callback function handles the sources when they  have been enumerated. The callback function  receives the deviceList array as its only argument",
            +        "errorCallback": "Function: (Optional) This optional callback receives the error  message as its argument."
            +      }
            +    },
            +    "setSource": {
            +      "description": [
            +        "Set the input source. Accepts a number representing a position in the array returned by getSources(). This is only available in browsers that support <a title=\"MediaDevices.enumerateDevices() - Web APIs | MDN\" target=\"_blank\" href= \"<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"\">https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices\"</a> <blockquote>"
            +      ],
            +      "params": {
            +        "num": "Number: position of input source in the array"
            +      }
            +    }
            +  },
            +  "p5.Effect": {
            +    "description": [
            +      "Effect is a base class for audio effects in p5. This module handles the nodes and methods that are common and useful for current and future effects.",
            +      "This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>, <a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>, <a href=\"/reference/#/p5.Delay\">p5.Delay</a>, <a href=\"/reference/#/p5.Filter\">p5.Filter</a>, <a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>."
            +    ],
            +    "params": {
            +      "ac": "Object: (Optional) Reference to the audio context of the p5 object",
            +      "input": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "output": "AudioNode: (Optional) Gain Node effect wrapper",
            +      "_drywet": "Object: (Optional) Tone.JS CrossFade node (defaults to value: 1)",
            +      "wet": "AudioNode: (Optional) Effects that extend this class should connect  to the wet signal to this gain node, so that dry and wet  signals are mixed properly."
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output volume of the filter."
            +      ],
            +      "params": {
            +        "vol": "Number: (Optional) amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts until rampTime",
            +        "tFromNow": "Number: (Optional) schedule this event to happen in tFromNow seconds"
            +      }
            +    },
            +    "chain": {
            +      "description": [
            +        "Link effects together in a chain Example usage: filter.chain(reverb, delay, panner); May be used with an open-ended number of arguments"
            +      ],
            +      "params": {
            +        "arguments": "Object: (Optional) Chain together multiple sound objects"
            +      }
            +    },
            +    "drywet": {
            +      "description": [
            +        "Adjust the dry/wet value."
            +      ],
            +      "params": {
            +        "fade": "Number: (Optional) The desired drywet value (0 - 1.0)"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.js-sound, Web Audio Node, or use signal to control an AudioParam"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Filter": {
            +    "description": [
            +      "A p5.Filter uses a Web Audio Biquad Filter to filter the frequency response of an input source. Subclasses include: <a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>: Allows frequencies below the cutoff frequency to pass through, and attenuates frequencies above the cutoff.<br/> <a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>: The opposite of a lowpass filter. <br/> <a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>: Allows a range of frequencies to pass through and attenuates the frequencies below and above this frequency range.<br/>",
            +      "The <code>.res()</code> method controls either width of the bandpass, or resonance of the low/highpass cutoff frequency.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "type": "String: (Optional) 'lowpass' (default), 'highpass', 'bandpass'"
            +    },
            +    "biquadFilter": {
            +      "description": [
            +        "The p5.Filter is built with a <a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\"> Web Audio BiquadFilter Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Filter an audio signal according to a set of filter parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance/Width of the filter frequency  from 0.001 to 1000"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the frequency and the resonance of the filter."
            +      ],
            +      "params": {
            +        "freq": "Number: (Optional) Frequency in Hz, from 10 to 22050",
            +        "res": "Number: (Optional) Resonance (Q) from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "freq": {
            +      "description": [
            +        "Set the filter frequency, in Hz, from 10 to 22050 (the range of human hearing, although in reality most people hear in a narrower range)."
            +      ],
            +      "returns": "Number: value Returns the current frequency value",
            +      "params": {
            +        "freq": "Number: Filter Frequency",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "res": {
            +      "description": [
            +        "Controls either width of a bandpass frequency, or the resonance of a low/highpass cutoff frequency."
            +      ],
            +      "returns": "Number: value Returns the current res value",
            +      "params": {
            +        "res": "Number: Resonance/Width of filter freq  from 0.001 to 1000",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "gain": {
            +      "description": [
            +        "Controls the gain attribute of a Biquad Filter. This is distinctly different from .amp() which is inherited from p5.Effect .amp() controls the volume via the output gain node p5.Filter.gain() controls the gain parameter of a Biquad Filter node."
            +      ],
            +      "returns": "Number: Returns the current or updated gain value",
            +      "params": {
            +        "gain": "Number"
            +      }
            +    },
            +    "toggle": {
            +      "description": [
            +        "Toggle function. Switches between the specified type and allpass"
            +      ],
            +      "returns": "Boolean: [Toggle value]"
            +    },
            +    "setType": {
            +      "description": [
            +        "Set the type of a p5.Filter. Possible types include: \"lowpass\" (default), \"highpass\", \"bandpass\", \"lowshelf\", \"highshelf\", \"peaking\", \"notch\", \"allpass\"."
            +      ],
            +      "params": {
            +        "t": "String"
            +      }
            +    }
            +  },
            +  "p5.LowPass": {
            +    "description": [
            +      "Constructor: <code>new p5.LowPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('lowpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.HighPass": {
            +    "description": [
            +      "Constructor: <code>new p5.HighPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('highpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.BandPass": {
            +    "description": [
            +      "Constructor: <code>new p5.BandPass()</code> Filter. This is the same as creating a p5.Filter and then calling its method <code>setType('bandpass')</code>. See p5.Filter for methods."
            +    ]
            +  },
            +  "p5.EQ": {
            +    "description": [
            +      "p5.EQ is an audio effect that performs the function of a multiband audio equalizer. Equalization is used to adjust the balance of frequency compoenents of an audio signal. This process is commonly used in sound production and recording to change the waveform before it reaches a sound output device. EQ can also be used as an audio effect to create interesting distortions by filtering out parts of the spectrum. p5.EQ is built using a chain of Web Audio Biquad Filter Nodes and can be instantiated with 3 or 8 bands. Bands can be added or removed from the EQ by directly modifying p5.EQ.bands (the array that stores filters).",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "returns": "Object: p5.EQ object",
            +    "params": {
            +      "_eqsize": "Number: (Optional) Constructor will accept 3 or 8, defaults to 3"
            +    },
            +    "bands": {
            +      "description": [
            +        "The p5.EQ is built with abstracted p5.Filter objects. To modify any bands, use methods of the <a href=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\"> p5.Filter</a> API, especially <code>gain</code> and <code>freq</code>. Bands are stored in an array, with indices 0 - 3, or 0 - 7"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process an input by connecting it to the EQ"
            +      ],
            +      "params": {
            +        "src": "Object: Audio source"
            +      }
            +    }
            +  },
            +  "p5.Panner3D": {
            +    "description": [
            +      "Panner3D is based on the <a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>. This panner is a spatial processing node that allows audio to be positioned and oriented in 3D space.",
            +      "The position is relative to an <a title=\"Web Audio Listener docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\"> Audio Context Listener</a>, which can be accessed by <code>p5.soundOut.audiocontext.listener</code>"
            +    ],
            +    "panner": {
            +      "description": [
            +        "<a title=\"Web Audio Panner docs\" href= \"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\"> Web Audio Spatial Panner Node</a>",
            +        "Properties include <ul> <li><a title=\"w3 spec for Panning Model\" href=\"<a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\"\">https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\"</a><blockquote>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect an audio sorce"
            +      ],
            +      "params": {
            +        "src": "Object: Input source"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "positionX": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionY": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "positionZ": {
            +      "description": [
            +        "Getter and setter methods for position coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orient": {
            +      "description": [
            +        "Set the X,Y,Z position of the Panner"
            +      ],
            +      "returns": "Array: Updated x, y, z values as an array",
            +      "params": {
            +        "xVal": "Number",
            +        "yVal": "Number",
            +        "zVal": "Number",
            +        "time": "Number"
            +      }
            +    },
            +    "orientX": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientY": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "orientZ": {
            +      "description": [
            +        "Getter and setter methods for orient coordinates"
            +      ],
            +      "returns": "Number: updated coordinate value"
            +    },
            +    "setFalloff": {
            +      "description": [
            +        "Set the rolloff factor and max distance"
            +      ],
            +      "params": {
            +        "maxDistance": "Number (Optional)",
            +        "rolloffFactor": "Number (Optional)"
            +      }
            +    },
            +    "maxDist": {
            +      "description": [
            +        "Maxium distance between the source and the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "maxDistance": "Number"
            +      }
            +    },
            +    "rollof": {
            +      "description": [
            +        "How quickly the volume is reduced as the source moves away from the listener"
            +      ],
            +      "returns": "Number: updated value",
            +      "params": {
            +        "rolloffFactor": "Number"
            +      }
            +    }
            +  },
            +  "p5.Delay": {
            +    "description": [
            +      "Delay is an echo effect. It processes an existing sound source, and outputs a delayed version of that sound. The p5.Delay can produce different effects depending on the delayTime, feedback, filter, and type. In the example below, a feedback of 0.5 (the default value) will produce a looping delay that decreases in volume by 50% each repeat. A filter will cut out the high frequencies so that the delay does not sound as piercing as the original source.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "leftDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "rightDelay": {
            +      "description": [
            +        "The p5.Delay is built with two <a href=\"http://www.w3.org/TR/webaudio/#DelayNode\"> Web Audio Delay Nodes</a>, one for each stereo channel."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Add delay to an audio signal according to a set of delay parameters."
            +      ],
            +      "params": {
            +        "Signal": "Object: An object that outputs audio",
            +        "delayTime": "Number: (Optional) Time (in seconds) of the delay/echo.  Some browsers limit delayTime to  1 second.",
            +        "feedback": "Number: (Optional) sends the delay back through itself  in a loop that decreases in volume  each time.",
            +        "lowPass": "Number: (Optional) Cutoff frequency. Only frequencies  below the lowPass will be part of the  delay."
            +      }
            +    },
            +    "delayTime": {
            +      "description": [
            +        "Set the delay (echo) time, in seconds. Usually this value will be a floating point number between 0.0 and 1.0."
            +      ],
            +      "params": {
            +        "delayTime": "Number: Time (in seconds) of the delay"
            +      }
            +    },
            +    "feedback": {
            +      "description": [
            +        "Feedback occurs when Delay sends its signal back through its input in a loop. The feedback amount determines how much signal to send each time through the loop. A feedback greater than 1.0 is not desirable because it will increase the overall output each time through the loop, creating an infinite feedback loop. The default value is 0.5"
            +      ],
            +      "returns": "Number: Feedback value",
            +      "params": {
            +        "feedback": "Number|Object: 0.0 to 1.0, or an object such as an  Oscillator that can be used to  modulate this param"
            +      }
            +    },
            +    "filter": {
            +      "description": [
            +        "Set a lowpass filter frequency for the delay. A lowpass filter will cut off any frequencies higher than the filter frequency."
            +      ],
            +      "params": {
            +        "cutoffFreq": "Number|Object: A lowpass filter will cut off any  frequencies higher than the filter frequency.",
            +        "res": "Number|Object: Resonance of the filter frequency  cutoff, or an object (i.e. a p5.Oscillator)  that can be used to modulate this parameter.  High numbers (i.e. 15) will produce a resonance,  low numbers (i.e. .2) will produce a slope."
            +      }
            +    },
            +    "setType": {
            +      "description": [
            +        "Choose a preset type of delay. 'pingPong' bounces the signal from the left to the right channel to produce a stereo effect. Any other parameter will revert to the default delay setting."
            +      ],
            +      "params": {
            +        "type": "String|Number: 'pingPong' (1) or 'default' (0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the delay effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Reverb": {
            +    "description": [
            +      "Reverb adds depth to a sound through a large number of decaying echoes. It creates the perception that sound is occurring in a physical space. The p5.Reverb has parameters for Time (how long does the reverb last) and decayRate (how much the sound decays with each echo) that can be set with the .set() or .process() methods. The p5.Convolver extends p5.Reverb allowing you to recreate the sound of actual physical spaces through convolution.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "process": {
            +      "description": [
            +        "Connect a source to the reverb, and assign reverb parameters."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output.",
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the reverb settings. Similar to .process(), but without assigning a new input."
            +      ],
            +      "params": {
            +        "seconds": "Number: (Optional) Duration of the reverb, in seconds.  Min: 0, Max: 10. Defaults to 3.",
            +        "decayRate": "Number: (Optional) Percentage of decay with each echo.  Min: 0, Max: 100. Defaults to 2.",
            +        "reverse": "Boolean: (Optional) Play the reverb backwards or forwards."
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the reverb effect."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    }
            +  },
            +  "p5.Convolver": {
            +    "description": [
            +      "p5.Convolver extends p5.Reverb. It can emulate the sound of real physical spaces through a process called <a href=\" https://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\"> convolution</a>.",
            +      "Convolution multiplies any audio input by an \"impulse response\" to simulate the dispersion of sound over time. The impulse response is generated from an audio file that you provide. One way to generate an impulse response is to pop a balloon in a reverberant space and record the echo. Convolution can also be used to experiment with sound.",
            +      "Use the method <code>createConvolution(path)</code> to instantiate a p5.Convolver with a path to your impulse response audio file."
            +    ],
            +    "params": {
            +      "path": "String: path to a sound file",
            +      "callback": "Function: (Optional) function to call when loading succeeds",
            +      "errorCallback": "Function: (Optional) function to call if loading fails.  This function will receive an error or  XMLHttpRequest object with information  about what went wrong."
            +    },
            +    "convolverNode": {
            +      "description": [
            +        "Internally, the p5.Convolver uses the a <a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\"> Web Audio Convolver Node</a>."
            +      ]
            +    },
            +    "impulses": {
            +      "description": [
            +        "If you load multiple impulse files using the .addImpulse method, they will be stored as Objects in this Array. Toggle between them with the <code>toggleImpulse(id)</code> method."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Connect a source to the convolver."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "addImpulse": {
            +      "description": [
            +        "Load and assign a new Impulse Response to the p5.Convolver. The impulse is added to the <code>.impulses</code> array. Previous impulses can be accessed with the <code>.toggleImpulse(id)</code> method."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "resetImpulse": {
            +      "description": [
            +        "Similar to .addImpulse, except that the <code>.impulses</code> Array is reset to save memory. A new <code>.impulses</code> array is created with this impulse as the only item."
            +      ],
            +      "params": {
            +        "path": "String: path to a sound file",
            +        "callback": "Function: function (optional)",
            +        "errorCallback": "Function: function (optional)"
            +      }
            +    },
            +    "toggleImpulse": {
            +      "description": [
            +        "If you have used <code>.addImpulse()</code> to add multiple impulses to a p5.Convolver, then you can use this method to toggle between the items in the <code>.impulses</code> Array. Accepts a parameter to identify which impulse you wish to use, identified either by its original filename (String) or by its position in the <code>.impulses </code> Array (Number).<br/> You can access the objects in the .impulses Array directly. Each Object has two attributes: an <code>.audioBuffer</code> (type: Web Audio <a href=\" http://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\"> AudioBuffer)</a> and a <code>.name</code>, a String that corresponds with the original filename."
            +      ],
            +      "params": {
            +        "id": "String|Number: Identify the impulse by its original filename  (String), or by its position in the  <code>.impulses</code> Array (Number)."
            +      }
            +    }
            +  },
            +  "p5.Phrase": {
            +    "description": [
            +      "A phrase is a pattern of musical events over time, i.e. a series of notes and rests.",
            +      "Phrases must be added to a p5.Part for playback, and each part can play multiple phrases at the same time. For example, one Phrase might be a kick drum, another could be a snare, and another could be the bassline.",
            +      "The first parameter is a name so that the phrase can be modified or deleted later. The callback is a a function that this phrase will call at every step—for example it might be called <code>playNote(value){}</code>. The array determines which value is passed into the callback at each step of the phrase. It can be numbers, an object with multiple numbers, or a zero (0) indicates a rest so the callback won't be called)."
            +    ],
            +    "params": {
            +      "name": "String: Name so that you can access the Phrase.",
            +      "callback": "Function: The name of a function that this phrase  will call. Typically it will play a sound,  and accept two parameters: a time at which  to play the sound (in seconds from now),  and a value from the sequence array. The  time should be passed into the play() or  start() method to ensure precision.",
            +      "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +    },
            +    "sequence": {
            +      "description": [
            +        "Array of values to pass into the callback at each step of the phrase. Depending on the callback function's requirements, these values may be numbers, strings, or an object with multiple parameters. Zero (0) indicates a rest."
            +      ]
            +    }
            +  },
            +  "p5.Part": {
            +    "description": [
            +      "A p5.Part plays back one or more p5.Phrases. Instantiate a part with steps and tatums. By default, each step represents a 1/16th note.",
            +      "See p5.Phrase for more about musical timing."
            +    ],
            +    "params": {
            +      "steps": "Number: (Optional) Steps in the part",
            +      "tatums": "Number: (Optional) Divisions of a beat, e.g. use 1/4, or 0.25 for a quarter note (default is 1/16, a sixteenth note)"
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo of this part, in Beats Per Minute."
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: (Optional) Seconds from now"
            +      }
            +    },
            +    "getBPM": {
            +      "description": [
            +        "Returns the tempo, in Beats Per Minute, of this part."
            +      ],
            +      "returns": "Number:"
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of this part. It will play through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of this part. It will begin looping through all of its phrases at a speed determined by setBPM."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Tell the part to stop looping."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again."
            +      ],
            +      "params": {
            +        "time": "Number: (Optional) seconds from now"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the part. Playback will resume from the current step."
            +      ],
            +      "params": {
            +        "time": "Number: seconds from now"
            +      }
            +    },
            +    "addPhrase": {
            +      "description": [
            +        "Add a p5.Phrase to this Part."
            +      ],
            +      "params": {
            +        "phrase": "p5.Phrase: reference to a p5.Phrase"
            +      }
            +    },
            +    "removePhrase": {
            +      "description": [
            +        "Remove a phrase from this part, based on the name it was given when it was created."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "getPhrase": {
            +      "description": [
            +        "Get a phrase from this part, based on the name it was given when it was created. Now you can modify its array."
            +      ],
            +      "params": {
            +        "phraseName": "String"
            +      }
            +    },
            +    "replaceSequence": {
            +      "description": [
            +        "Find all sequences with the specified name, and replace their patterns with the specified array."
            +      ],
            +      "params": {
            +        "phraseName": "String",
            +        "sequence": "Array: Array of values to pass into the callback  at each step of the phrase."
            +      }
            +    },
            +    "onStep": {
            +      "description": [
            +        "Set the function that will be called at every step. This will clear the previous function."
            +      ],
            +      "params": {
            +        "callback": "Function: The name of the callback  you want to fire  on every beat/tatum."
            +      }
            +    }
            +  },
            +  "p5.Score": {
            +    "description": [
            +      "A Score consists of a series of Parts. The parts will be played back in order. For example, you could have an A part, a B part, and a C part, and play them back in this order <code>new p5.Score(a, a, b, a, c)</code>"
            +    ],
            +    "params": {
            +      "parts": "p5.Part: (Optional) One or multiple parts, to be played in sequence."
            +    },
            +    "start": {
            +      "description": [
            +        "Start playback of the score."
            +      ]
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop playback of the score."
            +      ]
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause playback of the score."
            +      ]
            +    },
            +    "loop": {
            +      "description": [
            +        "Loop playback of the score."
            +      ]
            +    },
            +    "noLoop": {
            +      "description": [
            +        "Stop looping playback of the score. If it is currently playing, this will go into effect after the current round of playback completes."
            +      ]
            +    },
            +    "setBPM": {
            +      "description": [
            +        "Set the tempo for all parts in the score"
            +      ],
            +      "params": {
            +        "BPM": "Number: Beats Per Minute",
            +        "rampTime": "Number: Seconds from now"
            +      }
            +    }
            +  },
            +  "p5.SoundLoop": {
            +    "description": [
            +      "SoundLoop"
            +    ],
            +    "params": {
            +      "callback": "Function: this function will be called on each iteration of theloop",
            +      "interval": "Number|String: (Optional) amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second."
            +    },
            +    "bpm": {
            +      "description": [
            +        "Getters and Setters, setting any paramter will result in a change in the clock's frequency, that will be reflected after the next callback beats per minute (defaults to 60)"
            +      ]
            +    },
            +    "timeSignature": {
            +      "description": [
            +        "number of quarter notes in a measure (defaults to 4)"
            +      ]
            +    },
            +    "interval": {
            +      "description": [
            +        "length of the loops interval"
            +      ]
            +    },
            +    "iterations": {
            +      "description": [
            +        "how many times the callback has been called so far"
            +      ]
            +    },
            +    "musicalTimeMode": {
            +      "description": [
            +        "musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention true if string, false if number"
            +      ]
            +    },
            +    "maxIterations": {
            +      "description": [
            +        "Set a limit to the number of loops to play. defaults to Infinity"
            +      ]
            +    },
            +    "start": {
            +      "description": [
            +        "Start the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a starting time"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a stopping time"
            +      }
            +    },
            +    "pause": {
            +      "description": [
            +        "Pause the loop"
            +      ],
            +      "params": {
            +        "timeFromNow": "Number: (Optional) schedule a pausing time"
            +      }
            +    },
            +    "syncedStart": {
            +      "description": [
            +        "Synchronize loops. Use this method to start two more more loops in synchronization or to start a loop in synchronization with a loop that is already playing This method will schedule the implicit loop in sync with the explicit master loop i.e. loopToStart.syncedStart(loopToSyncWith)"
            +      ],
            +      "params": {
            +        "otherLoop": "Object: a p5.SoundLoop to sync with",
            +        "timeFromNow": "Number: (Optional) Start the loops in sync after timeFromNow seconds"
            +      }
            +    }
            +  },
            +  "p5.Compressor": {
            +    "description": [
            +      "Compressor is an audio effect class that performs dynamics compression on an audio input source. This is a very commonly used technique in music and sound production. Compression creates an overall louder, richer, and fuller sound by lowering the volume of louds and raising that of softs. Compression can be used to avoid clipping (sound distortion due to peaks in volume) and is especially useful when many sounds are played at once. Compression can be used on individual sound sources in addition to the master output.",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "compressor": {
            +      "description": [
            +        "The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"  target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node  </a>"
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Performs the same function as .connect, but also accepts optional parameters to set compressor's audioParams"
            +      ],
            +      "params": {
            +        "src": "Object: Sound source to be connected",
            +        "attack": "Number: (Optional) The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: (Optional) The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: (Optional) The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the parameters of a compressor."
            +      ],
            +      "params": {
            +        "attack": "Number: The amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "knee": "Number: A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "ratio": "Number: The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1"
            +      }
            +    },
            +    "attack": {
            +      "description": [
            +        "Get current attack or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "attack": "Number: (Optional) Attack is the amount of time (in seconds) to reduce the gain by 10dB,  default = .003, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "knee": {
            +      "description": [
            +        "Get current knee or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "knee": "Number: (Optional) A decibel value representing the range above the  threshold where the curve smoothly transitions to the \"ratio\" portion.  default = 30, range 0 - 40",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "ratio": {
            +      "description": [
            +        "Get current ratio or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "ratio": "Number: (Optional) The amount of dB change in input for a 1 dB change in output  default = 12, range 1 - 20",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "threshold": {
            +      "description": [
            +        "Get current threshold or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "threshold": "Number: The decibel value above which the compression will start taking effect  default = -24, range -100 - 0",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "release": {
            +      "description": [
            +        "Get current release or set value w/ time ramp"
            +      ],
            +      "params": {
            +        "release": "Number: The amount of time (in seconds) to increase the gain by 10dB  default = .25, range 0 - 1",
            +        "time": "Number: (Optional) Assign time value to schedule the change in value"
            +      }
            +    },
            +    "reduction": {
            +      "description": [
            +        "Return the current reduction value"
            +      ],
            +      "returns": "Number: Value of the amount of gain reduction that is applied to the signal"
            +    }
            +  },
            +  "p5.PeakDetect": {
            +    "description": [
            +      "PeakDetect works in conjunction with p5.FFT to look for onsets in some or all of the frequency spectrum.",
            +      "To use p5.PeakDetect, call <code>update</code> in the draw loop and pass in a p5.FFT object.",
            +      "You can listen for a specific part of the frequency spectrum by setting the range between <code>freq1</code> and <code>freq2</code>.",
            +      "<code>threshold</code> is the threshold for detecting a peak, scaled between 0 and 1. It is logarithmic, so 0.1 is half as loud as 1.0.",
            +      "The update method is meant to be run in the draw loop, and <b>frames</b> determines how many loops must pass before another peak can be detected. For example, if the frameRate() = 60, you could detect the beat of a 120 beat-per-minute song with this equation: <code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>",
            +      "Based on example contribtued by @b2renger, and a simple beat detection explanation by <a href=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\" target=\"_blank\">Felix Turner</a>."
            +    ],
            +    "params": {
            +      "freq1": "Number: (Optional) lowFrequency - defaults to 20Hz",
            +      "freq2": "Number: (Optional) highFrequency - defaults to 20000 Hz",
            +      "threshold": "Number: (Optional) Threshold for detecting a beat between 0 and 1  scaled logarithmically where 0.1 is 1/2 the loudness  of 1.0. Defaults to 0.35.",
            +      "framesPerPeak": "Number: (Optional) Defaults to 20."
            +    },
            +    "isDetected": {
            +      "description": [
            +        "isDetected is set to true when a peak is detected."
            +      ]
            +    },
            +    "update": {
            +      "description": [
            +        "The update method is run in the draw loop.",
            +        "Accepts an FFT object. You must call .analyze() on the FFT object prior to updating the peakDetect because it relies on a completed FFT analysis."
            +      ],
            +      "params": {
            +        "fftObject": "p5.FFT: A p5.FFT object"
            +      }
            +    },
            +    "onPeak": {
            +      "description": [
            +        "onPeak accepts two arguments: a function to call when a peak is detected. The value of the peak, between 0.0 and 1.0, is passed to the callback."
            +      ],
            +      "params": {
            +        "callback": "Function: Name of a function that will  be called when a peak is  detected.",
            +        "val": "Object: (Optional) Optional value to pass  into the function when  a peak is detected."
            +      }
            +    }
            +  },
            +  "p5.SoundRecorder": {
            +    "description": [
            +      "Record sounds for playback and/or to save as a .wav file. The p5.SoundRecorder records all sound output from your sketch, or can be assigned a specific source with setInput().",
            +      "The record() method accepts a p5.SoundFile as a parameter. When playback is stopped (either after the given amount of time, or with the stop() method), the p5.SoundRecorder will send its recording to that p5.SoundFile for playback."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a specific device to the p5.SoundRecorder. If no parameter is given, p5.SoundRecorer will record all audible p5.sound from your sketch."
            +      ],
            +      "params": {
            +        "unit": "Object: (Optional) p5.sound object or a web audio unit  that outputs sound"
            +      }
            +    },
            +    "record": {
            +      "description": [
            +        "Start recording. To access the recording, provide a p5.SoundFile as the first parameter. The p5.SoundRecorder will send its recording to that p5.SoundFile for playback once recording is complete. Optional parameters include duration (in seconds) of the recording, and a callback function that will be called once the complete recording has been transfered to the p5.SoundFile."
            +      ],
            +      "params": {
            +        "soundFile": "p5.SoundFile: p5.SoundFile",
            +        "duration": "Number: (Optional) Time (in seconds)",
            +        "callback": "Function: (Optional) The name of a function that will be  called once the recording completes"
            +      }
            +    },
            +    "stop": {
            +      "description": [
            +        "Stop the recording. Once the recording is stopped, the results will be sent to the p5.SoundFile that was given on .record(), and if a callback function was provided on record, that function will be called."
            +      ]
            +    }
            +  },
            +  "p5.Distortion": {
            +    "description": [
            +      "A Distortion effect created with a Waveshaper Node, with an approach adapted from <a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a>",
            +      "This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>. Methods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>, <a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and <a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available."
            +    ],
            +    "params": {
            +      "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +      "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +    },
            +    "WaveShaperNode": {
            +      "description": [
            +        "The p5.Distortion is built with a <a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\"> Web Audio WaveShaper Node</a>."
            +      ]
            +    },
            +    "process": {
            +      "description": [
            +        "Process a sound source, optionally specify amount and oversample values."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "set": {
            +      "description": [
            +        "Set the amount and oversample of the waveshaper distortion."
            +      ],
            +      "params": {
            +        "amount": "Number: (Optional) Unbounded distortion amount.  Normal values range from 0-1.",
            +        "oversample": "String: (Optional) 'none', '2x', or '4x'."
            +      }
            +    },
            +    "getAmount": {
            +      "description": [
            +        "Return the distortion amount, typically between 0-1."
            +      ],
            +      "returns": "Number: Unbounded distortion amount.  Normal values range from 0-1."
            +    },
            +    "getOversample": {
            +      "description": [
            +        "Return the oversampling."
            +      ],
            +      "returns": "String: Oversample can either be 'none', '2x', or '4x'."
            +    }
            +  },
            +  "p5.Gain": {
            +    "description": [
            +      "A gain node is useful to set the relative volume of sound. It's typically used to build mixers."
            +    ],
            +    "setInput": {
            +      "description": [
            +        "Connect a source to the gain node."
            +      ],
            +      "params": {
            +        "src": "Object: p5.sound / Web Audio object with a sound  output."
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Send output to a p5.sound or web audio object"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all output."
            +      ]
            +    },
            +    "amp": {
            +      "description": [
            +        "Set the output level of the gain node."
            +      ],
            +      "params": {
            +        "volume": "Number: amplitude between 0 and 1.0",
            +        "rampTime": "Number: (Optional) create a fade that lasts rampTime",
            +        "timeFromNow": "Number: (Optional) schedule this event to happen  seconds from now"
            +      }
            +    }
            +  },
            +  "p5.AudioVoice": {
            +    "description": [
            +      "Base class for monophonic synthesizers. Any extensions of this class should follow the API and implement the methods below in order to remain compatible with p5.PolySynth();"
            +    ],
            +    "connect": {
            +      "description": [
            +        "Connect to p5 objects or Web Audio Nodes"
            +      ],
            +      "params": {
            +        "unit": "Object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect from soundOut"
            +      ]
            +    }
            +  },
            +  "p5.MonoSynth": {
            +    "description": [
            +      "A MonoSynth is used as a single voice for sound synthesis. This is a class to be used in conjunction with the PolySynth class. Custom synthesizers should be built inheriting from this class."
            +    ],
            +    "attack": {
            +      "description": [
            +        "Getters and Setters"
            +      ]
            +    },
            +    "decay": {},
            +    "sustain": {},
            +    "release": {},
            +    "play": {
            +      "description": [
            +        "Play tells the MonoSynth to start playing a note. This method schedules the calling of .triggerAttack and .triggerRelease."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope. Defaults to 0.15 seconds."
            +      }
            +    },
            +    "triggerAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of the Envelope. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "String | Number: the note you want to play, specified as a  frequency in Hertz (Number) or as a midi  value in Note/Octave format (\"C4\", \"Eb3\"...etc\")  See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">  Tone</a>. Defaults to 440 hz",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play"
            +      }
            +    },
            +    "triggerRelease": {
            +      "description": [
            +        "Trigger the release of the Envelope. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "secondsFromNow": "Number: time to trigger the release"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set values like a traditional <a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\"> ADSR envelope </a>."
            +      ],
            +      "params": {
            +        "attackTime": "Number: Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "amp": {
            +      "description": [
            +        "MonoSynth amp"
            +      ],
            +      "returns": "Number: new volume value",
            +      "params": {
            +        "vol": "Number: desired volume",
            +        "rampTime": "Number: (Optional) Time to reach new volume"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  },
            +  "p5.OnsetDetect": {
            +    "description": [
            +      "Listen for onsets (a sharp increase in volume) within a given frequency range."
            +    ],
            +    "params": {
            +      "freqLow": "Number: Low frequency",
            +      "freqHigh": "Number: High frequency",
            +      "threshold": "Number: Amplitude threshold between 0 (no energy) and 1 (maximum)",
            +      "callback": "Function: Function to call when an onset is detected"
            +    }
            +  },
            +  "p5.PolySynth": {
            +    "description": [
            +      "An AudioVoice is used as a single voice for sound synthesis. The PolySynth class holds an array of AudioVoice, and deals with voices allocations, with setting notes to be played, and parameters to be set."
            +    ],
            +    "params": {
            +      "synthVoice": "Number: (Optional) A monophonic synth voice inheriting  the AudioVoice class. Defaults to p5.MonoSynth",
            +      "maxVoices": "Number: (Optional) Number of voices, defaults to 8;"
            +    },
            +    "notes": {
            +      "description": [
            +        "An object that holds information about which notes have been played and which notes are currently being played. New notes are added as keys on the fly. While a note has been attacked, but not released, the value of the key is the audiovoice which is generating that note. When notes are released, the value of the key becomes undefined."
            +      ]
            +    },
            +    "polyvalue": {
            +      "description": [
            +        "A PolySynth must have at least 1 voice, defaults to 8"
            +      ]
            +    },
            +    "AudioVoice": {
            +      "description": [
            +        "Monosynth that generates the sound for each note that is triggered. The p5.PolySynth defaults to using the p5.MonoSynth as its voice."
            +      ]
            +    },
            +    "play": {
            +      "description": [
            +        "Play a note by triggering noteAttack and noteRelease with sustain time"
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note to play (ranging from 0 to 127 - 60 being a middle C)",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds) at which to play",
            +        "sustainTime": "Number: (Optional) time to sustain before releasing the envelope"
            +      }
            +    },
            +    "noteADSR": {
            +      "description": [
            +        "noteADSR sets the envelope for a specific note that has just been triggered. Using this method modifies the envelope of whichever audiovoice is being used to play the desired note. The envelope should be reset before noteRelease is called in order to prevent the modified envelope from being used on other notes."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) Midi note on which ADSR should be set.",
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "setADSR": {
            +      "description": [
            +        "Set the PolySynths global envelope. This method modifies the envelopes of each monosynth so that all notes are played with this envelope."
            +      ],
            +      "params": {
            +        "attackTime": "Number: (Optional) Time (in seconds before envelope  reaches Attack Level",
            +        "decayTime": "Number: (Optional) Time (in seconds) before envelope  reaches Decay/Sustain Level",
            +        "susRatio": "Number: (Optional) Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,  where 1.0 = attackLevel, 0.0 = releaseLevel.  The susRatio determines the decayLevel and the level at which the  sustain portion of the envelope will sustain.  For example, if attackLevel is 0.4, releaseLevel is 0,  and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is  increased to 1.0 (using <code>setRange</code>),  then decayLevel would increase proportionally, to become 0.5.",
            +        "releaseTime": "Number: (Optional) Time in seconds from now (defaults to 0)"
            +      }
            +    },
            +    "noteAttack": {
            +      "description": [
            +        "Trigger the Attack, and Decay portion of a MonoSynth. Similar to holding down a key on a piano, but it will hold the sustain level until you let go."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.",
            +        "velocity": "Number: (Optional) velocity of the note to play (ranging from 0 to 1)/",
            +        "secondsFromNow": "Number: (Optional) time from now (in seconds)"
            +      }
            +    },
            +    "noteRelease": {
            +      "description": [
            +        "Trigger the Release of an AudioVoice note. This is similar to releasing the key on a piano and letting the sound fade according to the release level and release time."
            +      ],
            +      "params": {
            +        "note": "Number: (Optional) midi note on which attack should be triggered.  If no value is provided, all notes will be released.",
            +        "secondsFromNow": "Number: (Optional) time to trigger the release"
            +      }
            +    },
            +    "connect": {
            +      "description": [
            +        "Connect to a p5.sound / Web Audio object."
            +      ],
            +      "params": {
            +        "unit": "Object: A p5.sound or Web Audio object"
            +      }
            +    },
            +    "disconnect": {
            +      "description": [
            +        "Disconnect all outputs"
            +      ]
            +    },
            +    "dispose": {
            +      "description": [
            +        "Get rid of the MonoSynth and free up its resources / memory."
            +      ]
            +    }
            +  }
            +}
            \ No newline at end of file
            diff --git a/dist/books/index.html b/dist/books/index.html
            new file mode 100644
            index 0000000000..11a8b1f23c
            --- /dev/null
            +++ b/dist/books/index.html
            @@ -0,0 +1,308 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +
            +<head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">books | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +</head>
            +
            +<body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +        <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +        <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +            <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +            <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +            <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +            <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +            <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +        </ul>
            +    </div>
            +    <!-- .container -->
            +    <div class="container">
            +
            +        <!-- logo -->
            +        <header id="lockup">
            +            <a href="/">
            +                <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +                <div id="p5_logo"></div>
            +            </a>
            +        </header>
            +        <!-- close logo -->
            +
            +
            +
            +        <div id="books-page">
            +
            +
            +            <!-- site navigation -->
            +            <div class="column-span">
            +                <nav class="sidebar-menu-nav-element">
            +                    <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +                    <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +                    <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +                    <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +                        <li><a href="/">Home</a></li>
            +                        <li><a href="https://editor.p5js.org">Editor</a></li>
            +                        <li><a href="/download/">Download</a></li>
            +                        <li><a href="/download/support.html">Donate</a></li>
            +                        <li><a href="/get-started/">Get Started</a></li>
            +                        <li><a href="/reference/">Reference</a></li>
            +                        <li><a href="/libraries/">Libraries</a></li>
            +                        <li><a href="/learn/">Learn</a></li>
            +                        <li><a href="/teach/">Teach</a></li>
            +                        <li><a href="/examples/">Examples</a></li>
            +                        <li><a href="/books/">Books</a></li>
            +                        <li><a href="/community/">Community</a></li>
            +                        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +                        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +                        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +                        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +                        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +                        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +                    </ul>
            +                </nav>
            +            </div>
            +
            +            <div class="column-span">
            +
            +                <main id="content">
            +                    <h1>Books</h1>
            +                    <br>
            +
            +
            +                    <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/gettingstarted.jpg" alt="book cover getting started with p5.js">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>Getting Started with p5.js</h2>
            +
            +                            <p>Lauren McCarthy, Casey Reas, and Ben Fry. Illustrations by Taeyoon Choi.</p>
            +                            <p>
            +                                Published October 2015, Maker Media. 246 pages. Paperback.
            +                            </p>
            +
            +                            <p>Written by the lead p5.js developer and the founders of Processing, this book provides an introduction to the creative possibilities of today's Web, using JavaScript and HTML.</p>
            +
            +                            <p><a href="http://shop.oreilly.com/product/0636920032076.do" target="_blank">Order Print/Ebook from O'Reilly</a></p>
            +                            <p><a href="http://www.amazon.com/Make-Interactive-Graphics-JavaScript-Processing/dp/1457186772" target="_blank">Order from Amazon</a></p>
            +
            +                        </div>
            +                    </div>
            +
            +                    <div style='clear:both; height: 2em'></div>
            +
            +                    <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/gettingstarted-es.jpg" alt="book cover Introducción a p5.js">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>Introduction to p5.js (Spanish Edition)</h2>
            +
            +                            <p>Lauren McCarthy, Casey Reas, and Ben Fry. Translated by Aarón Montoya-Moraga. Ilustraciones de Taeyoon Choi.</p>
            +                            <p>
            +                                Published 2018, Processing Foundation, Inc. 246 pages. Soft cover.
            +                            </p>
            +
            +                            <p>Written by the lead p5.js developer and the founders of Processing, this book provides an introduction to the creative possibilities of today's Web, using JavaScript and HTML.</p>
            +
            +                            <p><a href="https://processingfoundation.press/product/introduccion-a-p5-js/" target="_blank">Order the PDF from The Processing Foundation Press</a></p>
            +                            <p><a href="https://www.amazon.com/Introducci%C3%B3n-p5-js-Spanish-Lauren-McCarthy/dp/0999881302/" target="_blank">Order the physical version from Amazon</a></p>
            +
            +                        </div>
            +                    </div>
            +
            +                    <div style='clear:both; height: 2em'></div>
            +
            +                    <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/generative_design.jpg" alt="book cover generative design">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>Generative Design</h2>
            +
            +                            <p>Benedikt Gross, Hartmut Bohnacker, Julia Laub and Claudius Lazzeroni.</p>
            +                            <p>
            +                                Published October 30, 2018, Princeton Architectural Press; Reprint edition. 255 pages. Paperback.
            +                            </p>
            +
            +                            <p>By using simple languages such as JavaScript in p5.js, artists and makers can create everything from interactive typography and textiles to 3D-printed furniture to complex and elegant infographics.</p>
            +
            +                            <p><a href="https://www.papress.com/html/product.details.dna?isbn=9781616897581" target="_blank">Order from Princeton Architectural Press</a></p>
            +                            <p><a href="https://www.amazon.com/Generative-Design-Visualize-Program-JavaScript/dp/1616897589" target="_blank">Order from Amazon</a></p>
            +
            +                        </div>
            +                    </div>
            +
            +                    <div style='clear:both; height: 2em'></div>
            +
            +                    <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/generative_gestaltung.jpg" alt="book cover Generative Gestaltung">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>Generative Gestaltung (German Edition)</h2>
            +
            +                            <p>Benedikt Gross, Hartmut Bohnacker, Julia Laub and Claudius Lazzeroni.</p>
            +                            <p>
            +                                Published March 1, 2018, Schmidt Hermann Verlag. 256 pages. Hardcover.
            +                            </p>
            +
            +                            <p>By using simple languages such as JavaScript in p5.js, artists and makers can create everything from interactive typography and textiles to 3D-printed furniture to complex and elegant infographics.</p>
            +
            +                            <p><a href="https://typografie.de/produkt/generative-gestaltung-creative-coding-im-web/" target="_blank">Order from Verlag Hermann Schmidt</a></p>
            +                            <p><a href="https://www.amazon.com/Generative-Gestaltung/dp/3874399028" target="_blank">Order from Amazon</a></p>
            +
            +                        </div>
            +                    </div>
            +
            +                    <div style='clear:both; height: 2em'></div>
            +
            +                    <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/learn_javascript.jpg" alt="book cover learn javascript">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>Learn JavaScript with p5.js</h2>
            +
            +                            <p>Engin Arslan.</p>
            +                            <p>
            +                                Published 2018, Apress. 217 pages. Paperback.
            +                            </p>
            +
            +                            <p>Learn coding from scratch in a highly engaging and visual manner using the vastly popular JavaScript with the programming library p5.js. The skills you will acquire from this book are highly transferable to a myriad of industries
            +                                and can be used towards building web applications, programmable robots, or generative art.</p>
            +
            +                            <p><a href="https://www.apress.com/gp/book/9781484234259" target="_blank">Order from Apress</a></p>
            +                            <p><a href="https://www.amazon.com/Learn-JavaScript-p5-js-Coding-Learners/dp/1484234251" target="_blank">Order from Amazon</a></p>
            +
            +                        </div>
            +                    </div>
            +
            +                    <div style='clear:both; height: 2em'></div>
            +
            +                    <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/aesthetic-programming.jpg" alt="book cover learn javascript">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>Aesthetic Programming: A Handbook of Software Studies</h2>
            +
            +                            <p>Winnie Soon, Geoff Cox. </p>
            +                            <p>
            +                                Published 2020, Open Humanities Press. 298 pages. Hardcover.
            +                            </p>
            +
            +                            <p>Using p5.js, this book introduces and demonstrates the reflexive practice of aesthetic programming, engaging with learning to program as a way to understand and question existing technological objects and paradigms, and to
            +                                explore the potential for reprogramming wider eco-socio-technical systems.</p>
            +
            +                            <p><a href="http://openhumanitiespress.org/books/download/Soon-Cox_2020_Aesthetic-Programming.pdf" target="_blank">Download the PDF (FREE)</a></p>
            +                            <p><a href="https://www.barnesandnoble.com/w/aesthetic-programming-winnie-soon/1138820949" target="_blank">Order from Barnes & Noble</a></p>
            +
            +                        </div>
            +                    </div>
            +                    <br>
            +                    <div style='clear:both; height: 2em'></div>
            +                </main>
            +
            +
            +                <footer>
            +                    <h2 class="sr-only">Credits</h2>
            +                    <p>
            +                        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>.
            +                        p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity
            +                        and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +                    </p>
            +                </footer>
            +
            +            </div>
            +            <!-- end column-span -->
            +
            +
            +            <!-- outside of column for footer to go across both -->
            +
            +            <p class="clearfix"> &nbsp; </p>
            +
            +            <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +        </div>
            +        <!-- end id="books-page"  -->
            +
            +
            +    </div>
            +    <!-- close class='container'-->
            +
            +
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +        <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +        <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +            <li><a href="https://processing.org">Processing</a></li>
            +            <li><a class="here" href="/">p5.js</a></li>
            +            <li><a href="https://py.processing.org/">Processing.py</a></li>
            +            <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +            <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +            <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +        </ul>
            +        <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +
            +
            +    </nav>
            +    <script>
            +        var langs = ["en", "es", "hi", "ko", "zh-Hans"];
            +
            +        (function(i, s, o, g, r, a, m) {
            +            i['GoogleAnalyticsObject'] = r;
            +            i[r] = i[r] || function() {
            +                (i[r].q = i[r].q || []).push(arguments)
            +            }, i[r].l = 1 * new Date();
            +            a = s.createElement(o),
            +                m = s.getElementsByTagName(o)[0];
            +            a.async = 1;
            +            a.src = g;
            +            m.parentNode.insertBefore(a, m)
            +        })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
            +        ga('create', 'UA-53383000-1', 'auto');
            +        ga('send', 'pageview');
            +
            +        $(window).ready(function() {
            +            if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +                $('#top').remove();
            +            } else {
            +                $('#top').show();
            +            }
            +        });
            +    </script>
            +
            +
            +</body>
            +
            +</html>
            \ No newline at end of file
            diff --git a/dist/community/contributors-conference-2015.html b/dist/community/contributors-conference-2015.html
            new file mode 100644
            index 0000000000..5591c0263e
            --- /dev/null
            +++ b/dist/community/contributors-conference-2015.html
            @@ -0,0 +1,286 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Contributors Conference 2015</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>May 25-31</h2>
            +
            +      <p>A group of approximately 30 participants gathered spent a week at the <a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a>, advancing the code, documentation, and community outreach tools of the p5.js programming environment. Participants came from as far away as Hong Kong, Seattle, Los Angeles, Boston and New York. Most were working professionals in the fields of creative technology, interaction design, and new-media arts, but the group also included a half-dozen undergraduate and graduate students from Carnegie Mellon’s Schools of Art and Architecture.
            +      </p>
            +      </div>
            +
            +      <img src="../assets/img/community/2015_1.jpg" alt='Diverse group of participants smile and make a p5 sign with their hands"'/>
            +      <img src="../assets/img/community/2015_3.jpg" alt='Woman presenting the p5.js community statement from her laptop"'/>
            +      <img src="../assets/img/community/2015_4.jpg" alt='Woman expressively speaks into a microphone while two male collaborators look on"'/>
            +      <img src="../assets/img/community/2015_5.jpg" alt='Participants attentively smile and listen to a presentation"'/>
            +      <img src="../assets/img/community/2015_6.jpg" alt='Woman reads about p5.js into a microphone to three female students"'/>
            +      <img src="../assets/img/community/2015_7.jpg" alt='Participants sit in a circle around a white board with sticky notes on it while a female student speaks into a microphone"'/>
            +      <img src="../assets/img/community/2015_8.jpg" alt='Participants sit around a table looking at each others laptops and compare code"'/>
            +      <img src="../assets/img/community/2015_9.jpg" alt='Whiteboard with different colored sticky and written notes about programming"'/>
            +      <img src="../assets/img/community/2015_10.jpg" alt='Woman speaking into a microphone about valuing different skill sets while a group of participants with laptops look at her powerpoint in a classroom"'/>
            +      <img src="../assets/img/community/2015_11.jpg" alt='Woman speaks at a podium in an auditorium while three participants sit on the stage and another three are skyping in on the stage screen"'/>
            +      <img src="../assets/img/community/2015_12.jpg" alt='Overhead view of a classroom with participants working on their laptops"'/>
            +      <img src="../assets/img/community/2015_13.jpg" alt='Five people having a discussion in a circle"'/>
            +      <img src="../assets/img/community/2015_14.jpg" alt='Five people in a circle with their laptops sharing their notes"'/>
            +      <img src="../assets/img/community/2015_15.jpg" alt='Man in a classroom with a microphone speaking out to a group of participants"'/>
            +      <img src="../assets/img/community/2015_2.jpg" alt='Participants jump, smile and throw their hands in the air on a green lawn"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/80913365@N04/albums/72157653238862069/with/17613092994/" target="_blank">Photos by Taeyoon Choi</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>Participants</h2>
            +      <p>
            +        <a href='http://huah.net/jason/' target='_blank'>Jason Alderman</a>,
            +        <a href='http://sepans.com/' target='_blank'>Sepand Ansari</a>,
            +        <a href='http://tegabrain.com' target='_blank'>Tega Brain</a>,
            +        <a href='https://medium.com/@emchenNYC/' target='_blank'>Emily Chen</a>,
            +        <a href='http://andrescolubri.net/' target='_blank'>Andres Colubri</a>,
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>,
            +        <a href='http://guydebree.com/' target='_blank'>Guy de Bree</a>,
            +        <a href='http://www.cjdecarteret.com/' target='_blank'>Christine de Carteret</a>,
            +        <a href='http://xystudio.cc/' target='_blank'>Xy Feng</a>,
            +        <a href='http://www.sarahgp.com/' target='_blank'>Sarah Groff-Palermo</a>,
            +        <a href='http://www.crhallberg.com/' target='_blank'>Chris Hallberg</a>,
            +        <a href='http://valhead.com/' target='_blank'>Val Head</a>,
            +        <a href='http://johannahedva.com' target='_blank'>Johanna Hedva</a>,
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>,
            +        <a href='http://web.media.mit.edu/~jacobsj/' target='_blank'>Jennifer Jacobs</a>,
            +        <a href='http://www.epicjefferson.com/' target='_blank'>Epic Jefferson</a>,
            +        <a href='http://michellepartogi.com' target='_blank'>Michelle Partogi</a>,
            +        <a href='http://lav.io/' target='_blank'>Sam Lavigne</a>,
            +        <a href='http://flong.com' target='_blank'>Golan Levin</a>,
            +        <a href='http://www.liuchangitp.com/' target='_blank'>Cici Liu</a>,
            +        <a href='http://www.mayaman.cc/' target='_blank'>Maya Man</a>,
            +        <a href='http://lauren-mccarthy.com' target='_blank'>Lauren McCarthy</a>,
            +        <a href='http://www.workergnome.com/' target='_blank'>David Newbury</a>,
            +        <a href='http://molleindustria.org/' target='_blank'>Paolo Pedercini</a>,
            +        <a href='http://luisaph.com' target='_blank'>Luisa Pereira</a>,
            +        <a href='http://mileshiroo.info/' target='_blank'>Miles Peyton</a>,
            +        <a href='http://carolinerecord.com/' target='_blank'>Caroline Record</a>,
            +        <a href='http://b2renger.github.io/' target='_blank'>Berenger Recoules</a>,
            +        <a href='https://pibloginthesky.wordpress.com/' target='_blank'>Stephanie Pi</a>,
            +        <a href='http://jasonsigal.cc' target='_blank'>Jason Sigal</a>,
            +        <a href='http://studioindefinit.com/' target='_blank'>Kevin Siwoff</a>,
            +        <a href='http://charlottestiles.com/' target='_blank'>Charlotte Stiles</a>
            +      </p>
            +      </div>
            +
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Diversity</h2>
            +        <p>Alongside technical development, one of the main focuses of this conference was outreach, community, and diversity. The conference began with a panel—<a href="http://studioforcreativeinquiry.org/events/diversity-seven-voices-on-race-gender-ability-class-for-floss-and-the-internet" target="_blank">Diversity: Seven Voices on Race, Gender, Ability &amp; Class for FLOSS and the Internet</a>. Organized by <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>
            +        and <a  href="http://lauren-mccarthy.com" target="_blank">Lauren McCarthy</a>, the panel took place Tuesday, 25 May 2015 in Kresge Auditorium at Carnegie Mellon University. Speakers included <a href="http://www.mayaman.cc/" target='_blank'>Maya Man</a>, <a href="http://reas.com/" target='_blank'>Casey
            +        Reas</a>, <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>, <a href="https://pibloginthesky.wordpress.com/" target='_blank'>Stephanie Pi</a>,
            +        <a href="http://phoenixperry.com/" target='_blank'>Phoenix Perry</a>, <a href="http://taeyoonchoi.com/" target='_blank'>Taeyoon Choi</a>,
            +        <a href="http://ablersite.org/" target='_blank'>Sara Hendren</a>, <a href="http://www.epicjefferson.com/" target='_blank'>Epic Jefferson</a>,
            +        and <a href="http://chandlermcwilliams.com/" target='_blank'>Chandler McWilliams</a>.
            +        <img class="alignleft size-full wp-image-8423" src="http://studioforcreativeinquiry.org/wp-content/uploads/2015/05/diversity_640.jpg" alt="diversity_640"/>
            +        </p>
            +        <iframe src="https://player.vimeo.com/video/129140298?color=ffffff&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +        
            +        <table style="margin-top: 10px; background-color: #ffffff; border-collapse: collapse; border: 0px; width: 720px;">
            +        <tbody>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129151416?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Casey Reas</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129151418?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Johanna Hedva</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129160951?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Stephanie Pi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129163155?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Phoenix Perry</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129173628?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Taeyoon Choi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129177689?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Sara Hendren</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129183825?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Epic Jefferson</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129187909?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Chandler McWilliams</td>
            +        </tr>
            +        </tbody>
            +        </table>
            +        <iframe src="https://player.vimeo.com/video/129192014?color=ffffff&amp;title=1&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +      </div>
            +
            +
            +<!--       <div class="contributors-subsection">
            +      <h3>Documentation</h3>
            +      <p><a href='https://medium.com/@tchoi8/diversity-at-sfpc-d494d7390375' target=_blank>Diversity at SFPC
            +      (talk by Taeyoon Choi at “Diversity: Seven Voices on Race, Gender, Ability &amp; Class for FLOSS and
            +      the Internet”)</a></p>
            +      </div> -->
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Support</h2>
            +
            +      <p>Our contributor conference took place at the <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> at Carnegie Mellon University, an academic laboratory for atypical, anti-disciplinary, and inter-institutional research at the intersections of arts, science, technology, and culture.</p>
            +
            +      <p>This event was made possible by a grant from the <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      and generous support from the <a href="https://tisch.nyu.edu/itp" target="_blank">NYU Interactive Telecommunications Program</a>
            +      (ITP), <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href="http://theartificial.nl/" target="_blank">TheArtificial</a>, <a href="http://bocoup.com/" target="_blank">Bocoup</a>, <a href="http://tinysubversions.com/" target="_blank">Darius Kazemi</a>, and <a href="http://www.du.edu/ahss/edp/" target="_blank">Emergent Digital Practices | University of Denver</a><br><b>Thank you!</b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../assets/img/community/nea.jpg' alt=""></a></div>
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:18%' src='../assets/img/community/studio.png' alt=""/></a>
            +      <a class='nounderline' href='http://itp.nyu.edu/itp/' target=_blank ><img style='width:18%' src='../assets/img/community/itp.png' alt=""/></a>
            +      <a class='nounderline' href='http://www.du.edu/ahss/edp/' target=_blank ><img style='width:18%' src='../assets/img/community/edp.png' alt=""/></a>
            +      <a class='nounderline' href='http://bocoup.com/' target=_blank ><img style='width:18%' src='../assets/img/community/bocoup.png' alt=""/></a>
            +      <a class='nounderline' href='http://theartificial.nl/' target=_blank ><img style='width:18%' src='../assets/img/community/theartificial.png' alt=""/></a>
            +
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/community/contributors-conference-2019.html b/dist/community/contributors-conference-2019.html
            new file mode 100644
            index 0000000000..c4416392b3
            --- /dev/null
            +++ b/dist/community/contributors-conference-2019.html
            @@ -0,0 +1,307 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Contributors Conference 2019</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>August 13-18</h2>
            +
            +      <p>An interdisciplinary group of 35 participants gathered at the <a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a>, advancing the code, documentation, and community outreach tools and exploring the current landscape of the p5.js programming environment. Comprising a diverse range of participants within the fields of creative technology, interaction design, and new media arts, the conference was aimed at fostering dialogue through a multidisciplinary lens. Working groups focused on several topic areas: Access; Music and Code in Performance; Landscape of Creative Tech; and Internationalization.
            +      </p>
            +      </div>
            +      
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/YkfG7Ggpi_o" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/At1newHnZpA" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <p><a href="https://www.youtube.com/channel/UCzMs9qg50AW2LEpLDzHT5NA" target="_blank">Videos by Qianqian Ye</a></p><br>
            +
            +      <img src="../assets/img/community/2019_1.jpg" alt='Man at a podium giving a presentation to the group"'/>
            +      <img src="../assets/img/community/2019_2.jpg" alt='Participants sitting at a long table having lunch and a discussion"'/>
            +      <img src="../assets/img/community/2019_4.jpg" alt='Classroom of participants working on their laptops"'/>
            +      <img src="../assets/img/community/2019_5.jpg" alt='Participants in a meeting in a dark classroom"'/>
            +      <img src="../assets/img/community/2019_6.jpg" alt='Woman giving presentation in a classroom of diverse participants"'/>
            +      <img src="../assets/img/community/2019_7.jpg" alt='Participants conversing in a busy classroom"'/>
            +      <img src="../assets/img/community/2019_8.jpg" alt='Woman with microphone speaking to fellow participants in a classroom"'/>
            +      <img src="../assets/img/community/2019_9.jpg" alt='Participant speaks at a podium in front of projected text about the problem with anonymyzing data"'/>
            +      <img src="../assets/img/community/2019_10.jpg" alt='Person with a microphone speaking to fellow participants in front of text that reads p5.js will not add any new features except those that increase access"'/>
            +      <img src="../assets/img/community/2019_11.jpg" alt='Woman speaking into a microphone talking to fellow participants "'/>
            +      <img src="../assets/img/community/2019_12.jpg" alt='A man with a microphone speaking to fellow participants"'/>
            +      <img src="../assets/img/community/2019_13.jpg" alt='Participants sit in a classroom towards the speakers listening intently"'/>
            +      <img src="../assets/img/community/2019_15.jpg" alt='Woman with microphone speaking to fellow participants with the text sacred boundaries in the projection behind her"'/>
            +      <img src="../assets/img/community/2019_16.jpg" alt='Overhead view of participants listening to a panel of people with an image of a 3d rendered man on it"'/>
            +      <img src="../assets/img/community/2019_17.jpg" alt='Participants sit around a table with their laptops and observe code on a screen"'/>
            +      <img src="../assets/img/community/2019_18.jpg" alt='Woman sitting next to a lifesize teddy bear works on her laptop"'/>
            +      <img src="../assets/img/community/2019_19.jpg" alt='Participants standing outside smiling"'/>
            +      <img src="../assets/img/community/2019_20.jpg" alt='Four participants standing in a circle conversing"'/>
            +      <img src="../assets/img/community/2019_21.jpg" alt='Participants sitting outside eating lunch together"'/>
            +      <img src="../assets/img/community/2019_22.jpg" alt='Participants sitting around a large U shaped table looking towards the front of the classroom"'/>
            +      <img src="../assets/img/community/2019_23.jpg" alt='Man sitting in front of the classroom speaking energetically into a microphone"'/>
            +      <img src="../assets/img/community/campfire.jpg" alt='Group of people sit around campfire made from four LCD monitors."'/>
            +      <img src="../assets/img/community/2019_24.jpg" alt='Group photo of participants smiling enthusiastically with their hands in the air"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/creativeinquiry/albums/72157710545834046/" target="_blank">Photos by Jacquelyn Johnson</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>Participants</h2>
            +      <p>
            +        <a href='https://americanartist.us/biocv' target='_blank'>American Artist</a>, 
            +        <a href='https://www.omayeli.com/' target='_blank'>Omayeli Arenyeka</a>, 
            +        <a href='http://www.sinabahram.com/' target='_blank'>Sina Bahram</a>, 
            +        <a href='https://aatishb.com/' target='_blank'>Aatish Bhatia</a>, 
            +        <a href='https://natalie.computer/' target='_blank'>Natalie Braginsky</a>, 
            +        <a href='https://jonchambers.net/' target='_blank'>Jon Chambers</a>, 
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>, 
            +        <a href='https://www.linkedin.com/in/aren-davey-bb3496103/' target='_blank'>Aren Davey</a>, 
            +        <a href='https://teddavis.org/' target='_blank'>Ted Davis</a>, 
            +        <a href='http://l05.is/' target='_blank'>Carlos Garcia</a>, 
            +        <a href='http://stalgiagrigg.name/' target='_blank'>Stalgia Grigg</a>, 
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>, 
            +        <a href='http://www.shawnemichaelainholloway.com/' target='_blank'>shawné michaelain holloway</a>, 
            +        <a href='http://www.takinglifeseriously.com/index.html' target='_blank'>Claire Kearney-Volpe</a>, 
            +        <a href='https://www.sonalee.me/' target='_blank'>Sona Lee</a>, 
            +        <a href='https://designerken.be/designing' target='_blank'>Kenneth Lim</a>, 
            +        <a href='https://www.outofambit.com/' target='_blank'>Evelyn Masso</a>, 
            +        <a href='http://lauren-mccarthy.com/' target='_blank'>Lauren McCarthy</a>, 
            +        <a href='https://laja.me/' target='_blank'>LaJuné McMillian</a>, 
            +        <a href='https://www.decontextualize.com/' target='_blank'>Allison Parrish</a>, 
            +        <a href='http://www.luisapereira.net/' target='_blank'>Luisa Pereira</a>, 
            +        <a href='https://guillemontecinos.cl/' target='_blank'>Guillermo Montecinos</a>, 
            +        <a href='http://montoyamoraga.io/' target='_blank'>Aarón Montoya-Moraga</a>,
            +        <a href='http://lm-m.com/' target='_blank'>Luis Morales-Navarro</a>, 
            +        Shefali Nayak, 
            +        <a href='http://everest-pipkin.com/' target='_blank'>Everest Pipkin</a>, 
            +        <a href='http://oross.net/' target='_blank'>Olivia Ross</a>, 
            +        <a href='https://dorothysantos.com/' target='_blank'>Dorothy R. Santos</a>, 
            +        <a href='https://www.yashengshe.com/' target='_blank'>Yasheng She</a>, 
            +        <a href='https://junshern.github.io/' target='_blank'>Jun Shern Chan</a>, 
            +        <a href='https://cassietarakajian.com/' target='_blank'>Cassie Tarakajian</a>, 
            +        <a href='https://www.laurenvalley.com/' target='_blank'>Lauren Valley</a>, 
            +        <a href='https://xin-xin.info' target='_blank'>Xin Xin</a>, 
            +        <a href='https://ayxx.me/' target='_blank'>Alex Yixuan Xu</a>, 
            +        <a href='http://www.qianqian-ye.com/' target='_blank'>Qianqian Ye</a>
            +      </p>
            +      </div>
            +
            +
            +      <div class="outputs-subsection">
            +      <h2 id='outputs'>Outputs</h2>
            +      <ul aria-labelledby='outputs' class='list_view bullets'>
            +        <!-- arts -->
            +        <li>A panel on Blackness and Gender in Virtual Space led by American Artist, with shawné michaelain holloway and LaJuné McMillian.</li>
            +        <li>New art installations by Stalgia Grigg, LaJuné McMillian, Aatish Bhatia, and Jon Chambers.</li>
            +        <!-- landscape -->
            +        <li>A prototype of a  <a href="https://github.com/aparrish/nb5js-proof-of-concept" target="_blank">notebook interface for p5.js.</a> Created by Allison Parrish.</li>
            +        <li>A design of the p5.js library system for the p5 Editor. Created by Cassie Tarakajian and Luca Damasco.</li>
            +        <li>Prototypes connecting p5 to other libraries. Created by Alex Yixuan Xu and Lauren Valley.</li>
            +
            +        <!-- global -->
            +        <li><a href="https://docs.google.com/document/d/1NPSVTWlTxWv8_rWLr8j91Qf8CcJA5ns8I8zFjCCmwuk/edit#heading=h.ea0uhs87h6fk" target="_blank">p5.js Global Contributor's Toolkit.</a> Created by Aarón Montoya-Moraga, Kenneth Lim, Guillermo Montecinos, Qianqian Ye,  Dorothy R. Santos, and Yasheng She.</li>
            +
            +        <!-- access -->
            +        <li><a href="https://docs.google.com/presentation/d/19xxc2zWWdFMAQjT6tRdN5ZU13vAKSwM7jojaC2U4F6Q/edit" target="_blank">How to write non-violent creative code.</a> A zine led by Olivia Ross.</li>
            +        <li>An overhaul of the p5.js website for accessibility. Including updates for screen reader accessibility, and improvements to the home, download, getting started, and reference pages. With contributions from Claire Kearney-Volpe, Sina Bahram, Kate Hollenbach, Olivia Ross, Luis Morales-Navarro, Lauren McCarthy, and Evelyn Masso.</li>
            +
            +        <!-- music performance -->
            +        <li><a href="https://github.com/aahdee/p5grid">p5grid</a>. An implementation of highly flexible triangle, square, hexagon, and octagon girds for p5.js. Created by Aren Davey.</li>
            +        <li><a href="https://github.com/L05/p5.multiplayer">p5.multiplayer</a>. A set of template files for building a multi-device, multiplayer game where multiple clients can connect to a specified host page. Created by L05.</li>
            +        <li>Experiments using <a href="https://teddavis.org/p5live/">P5LIVE</a>, testing early implementations of softCompile, OSC interfacing and added connectivity with demo for MIDI setup. A p5.js collaborative live-coding vj environment! Created by Ted Davis.</li>
            +        <li>Collaborative performances by Luisa Pereira, Jun Shern Chan, Shefali Nayak, Sona Lee, Ted Davis, and Carlos Garcia.</li>
            +        <li>A performance by Natalie Braginsky.</li>
            +  
            +        <!-- workshops -->
            +        <li>Workshops led by Everest Pipkin and Jon Chambers.</li>
            +
            +        <!-- closing -->
            +        <li>A closing campfire circle led by Golan Levin.</li>
            +        
            +      </ul>
            +      </div>
            +
            +      <div class="contributors-subsection">
            +      <h2>Support</h2>
            +
            +      <p>Our contributor conference took place at the <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> at Carnegie Mellon University, an academic laboratory for atypical, anti-disciplinary, and inter-institutional research at the intersections of arts, science, technology, and culture.</p>
            +
            +      <p>This event was made possible by a grant from the <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      and generous support from the <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href='https://www.mozilla.org/en-US/moss/' target=_blank>Mozilla Foundation</a>, <a href='https://www.du.edu/ahss/opensourcearts/' target=_blank>Clinic for Open Source Arts (COSA) at the University of Denver</a>, <a href='http://idm.engineering.nyu.edu/' target=_blank>NYU Tandon IDM</a>, <a href='https://tisch.nyu.edu/itp' target=_blank> NYU ITP</a>, <a href='http://thebaselschoolofdesign.ch/' target=_blank>FHNW Academy of Art and Design</a>, <a href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank>DePaul University College of Computing and Digital Media</a>, and <a href='http://amt.parsons.edu/' target=_blank>Parsons School of Art, Media, and Technology at the New School</a>.
            +      <br><b>Thank you!</b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../assets/img/community/nea.jpg' alt=""></a></div>
            +      
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:20%' src='../assets/img/community/studio.png' alt=""/></a>
            +      
            +      <a class='nounderline' href='http://thebaselschoolofdesign.ch/' target=_blank ><img style='width:70%' src='../assets/img/community/HGK.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://foundation.processing.org' target=_blank ><img style='width:14%' src='../assets/img/community/processing-foundation.png' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='https://www.du.edu/ahss/opensourcearts/' target=_blank ><img style='width:22%' src='../assets/img/community/COSA.png' alt=""/></a>
            +
            +      <a class='nounderline' href='http://idm.engineering.nyu.edu/' target=_blank ><img style='width:50%' src='../assets/img/community/IDM.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://amt.parsons.edu/' target=_blank ><img style='width:22%' src='../assets/img/community/Parsons.jpg' alt=""/></a>
            +
            +      <a class='nounderline' href='https://tisch.nyu.edu/itp' target=_blank ><img style='width:14%' src='../assets/img/community/itp.png' alt=""/></a>
            +
            +      <a class='nounderline' href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank ><img style='width:50%' src='../assets/img/community/depaul.png' alt=""/></a>
            +
            +      
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/community/developer-docs.html b/dist/community/developer-docs.html
            new file mode 100644
            index 0000000000..c382c869e2
            --- /dev/null
            +++ b/dist/community/developer-docs.html
            @@ -0,0 +1,141 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<link rel="stylesheet" href="https://unpkg.com/docsify/lib/themes/buble.css">
            +
            +<div id="community-page">
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <div id="app"></div>
            +      <script>
            +        window.$docsify = {
            +          auto2top: true,
            +          executeScript: true,
            +          loadSidebar: 'sidebar.md',
            +          autoHeader: true,
            +          loadNavbar: 'navbar.md',
            +          mergeNavbar: true,
            +          subMaxLevel: 2,
            +          themeColor: '#ed225d',
            +          basePath:
            +          'https://raw.githubusercontent.com/processing/p5.js/master/contributor_docs/',
            +          logo: '../assets/img/p5js.svg',
            +          name: 'p5.js Developer Docs',
            +          repo: 'https://github.com/processing/p5.js',
            +        }
            +      </script>
            +      <script src="https://unpkg.com/docsify/lib/docsify.min.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/community/index.html b/dist/community/index.html
            new file mode 100644
            index 0000000000..ea387fca7e
            --- /dev/null
            +++ b/dist/community/index.html
            @@ -0,0 +1,234 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content">
            +      <h1>Community</h1>
            +      <div class="community-statement">
            +        <h2 class="community-title">p5.js Community Statement </h2>
            +        <p>p5.js is a community interested in exploring the creation of art and design with technology.
            +        </p>
            +
            +        <p>We are a community of, and in solidarity with, people from every gender identity and expression, sexual orientation, race, ethnicity, language, neuro-type, size, ability, class, religion, culture, subculture, political opinion, age, skill level, occupation, and background. We acknowledge that not everyone has the time, financial means, or capacity to actively participate, but we recognize and encourage involvement of all kinds. We facilitate and foster access and empowerment. We are all learners.
            +        </p>
            +
            +        <p>We like these hashtags: #noCodeSnobs (because we value community over efficiency), #newKidLove (because we all started somewhere), #unassumeCore (because we don't assume knowledge), and #BlackLivesMatter (because of course).
            +        </p>
            +
            +        <h3 id="in-practice">In practice:</h3>
            +        <ul aria-labelledby="in-practice" class="bullets list_view">
            +          <li> We are not code snobs. We do not assume knowledge or imply there are things that somebody should know.  </li>
            +          <li>We insist on actively engaging with requests for feedback regardless of their complexity. </li>
            +          <li>We welcome newcomers and prioritize the education of others. We strive to approach all tasks with the enthusiasm of a newcomer. Because we believe that newcomers are just as valuable in this effort as experts. </li>
            +          <li>We consistently make the effort to actively recognize and validate multiple types of contributions. </li>
            +          <li>We are always willing to offer help or guidance. </li>
            +        </ul>
            +
            +        <h3 id="in-conflict">In times of conflict:</h3>
            +        <ul aria-labelledby="in-conflict" class="bullets list_view">
            +          <li>We listen.</li>
            +          <li>We clearly communicate while acknowledging other's feelings.</li>
            +          <li>We admit when we're wrong, apologize, and accept responsibility for our actions.</li>
            +          <li>We are continuously seeking to improve ourselves and our community.</li>
            +          <li>We keep our community respectful and open. </li>
            +          <li>We make everyone feel heard.</li>
            +          <li>We are mindful and kind in our interactions.</li>
            +        </ul>
            +
            +        <h3 id="in-future">In the future:</h3>
            +        <ul aria-labelledby="in-future" class="bullets list_view">
            +          <li>The future is now.</li>
            +        </ul>
            +        <br>
            +        <h3 id="notes" class='sr-only'>Notes</h3>
            +        <p>Please also visit our  <a href="https://github.com/processing/p5.js/blob/main/CODE_OF_CONDUCT.md#p5js-code-of-conduct">p5.js Code of Conduct</a>. The p5.js Community Statement is licensed under a <a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons license</a>. Please feel free to share and remix with attribution.</p>
            +      </div>
            +
            +      <h2 id="contribute">Contribute</h2>
            +      <p>Our community is always looking for enthusiasts to help in all different ways.</p>
            +
            +      <p><b>Develop.</b> <a href="https://github.com/processing/p5.js" target="blank_">GitHub</a> is the main place where code is collected, issues are documented, and discussions about code are had. Check out the  <a href="https://p5js.org/contributor-docs" target="blank_"> development tutorial </a>  to get started, or  <a href="../libraries/#create-your-own"> create your own library. </a></p>
            +
            +      <p><b>Document.</b> Everyone loves documentation. Help is needed <a href="https://github.com/processing/p5.js-website/blob/main/contributor_docs/Adding_examples.md" target="blank_">porting examples</a>, and<a href="https://p5js.org/contributor-docs/#/inline_documentation" target="blank_"> adding documentation</a>, and creating tutorials.</p>
            +
            +      <p><b>Teach.</b> Teach a workshop, a class, a friend, a collaborator! Tag @p5xjs on Twitter and we will do our best to share what you're doing.</p>
            +
            +      <p><b>Create.</b> p5.js is looking for designers, artists, coders, programmers to bring your creative and amazing work to show on the front page and inspire other people. Submit your work to <a href="mailto:hello@p5js.org">hello@p5js.org</a>.</p>
            +
            +      <p><b>Donate.</b> p5.js is free and open source and made by artists. Help support the development of p5.js through a donation to the <a href="https://processingfoundation.org/support">Processing Foundation</a>.</p>
            +
            +
            +      <h2>p5.js Contributors Conference</h2>
            +      <p>While most work happens online, we also convene IRL. We've had two contributors conferences held at the<a href="http://studioforcreativeinquiry.org">Frank-Ratchye STUDIO for Creative Inquiry</a> at Carnegie Mellon University in Pittsburgh, PA. Artists, designers, developers, educators, and got together to advance the p5.js project.
            +      </p>
            +      <h2 id="conferences" class="sr-only">Past Conferences</h2>
            +      <ul aria-labelledby="conferences" class="list_view bullets">
            +        <li><a href="contributors-conference-2019.html">Contributors Conference 2019</a></li>
            +        <li><a href="contributors-conference-2015.html">Contributors Conference 2015</a></li>
            +      </ul>
            +
            +      <img src="../assets/img/community/2015_12.jpg" alt='Overhead view of a classroom with participants working on their laptops"'/>
            +
            +      <h2>Mailing list</h2>
            +      <div class="email-octopus-form-wrapper">
            +        <p class="email-octopus-success-message"></p>
            +        <p class="email-octopus-error-message"></p>
            +        <form method="post" action="https://emailoctopus.com/lists/537b6ec8-d123-11e6-8561-06ead731d453/members/external-add" class="email-octopus-form">
            +          <p>Enter your email address to receive occasional updates from the Processing Foundation.</p>
            +          <div class="email-octopus-form-row">
            +            <input type="email" name="emailAddress" placeholder="email" class="email-octopus-email-address">
            +            <button type="submit">subscribe</button>
            +          </div>
            +          <div class="email-octopus-form-row-hp" aria-hidden="true">
            +            <input type="text" name="hp537b6ec8-d123-11e6-8561-06ead731d453" tabindex="-1">
            +          </div>
            +          <div class="email-octopus-form-row-subscribe">
            +            <input type="hidden" name="successRedirectUrl" class="email-octopus-success-redirect-url" value="">
            +          </div>
            +        </form>
            +      </div>
            +      <script src="https://emailoctopus.com/bundles/emailoctopuslist/js/formEmbed.js"></script>
            +      <br><br>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/contributor-docs/index.html b/dist/contributor-docs/index.html
            new file mode 100644
            index 0000000000..cd7da0d55c
            --- /dev/null
            +++ b/dist/contributor-docs/index.html
            @@ -0,0 +1,34 @@
            +<!DOCTYPE html>
            +<html lang="en">
            +<head>
            +  <meta charset="UTF-8">
            +  <title>p5.js Contributor Docs</title>
            +  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            +  <meta name="description" content="p5.js Contributor Docs">
            +  <meta name="viewport" content="width=device-width, initial-scale=1.0">
            +  <link rel="shortcut icon" href="/assets/img/favicon.ico">
            +  <link rel="icon" href="/assets/img/favicon.ico">
            +  <link rel="stylesheet" href="https://unpkg.com/docsify/lib/themes/buble.css">
            +</head>
            +<body>
            +  <div id="app"></div>
            +  <script>
            +    window.$docsify = {
            +      auto2top: true,
            +      executeScript: true,
            +      loadSidebar: 'sidebar.md',
            +      autoHeader: true,
            +      loadNavbar: 'navbar.md',
            +      mergeNavbar: true,
            +      subMaxLevel: 2,
            +      themeColor: '#ed225d',
            +      basePath:
            +      'https://raw.githubusercontent.com/processing/p5.js/main/contributor_docs/',
            +      logo: '../assets/img/p5js.svg',
            +      name: 'p5.js Contributor Docs',
            +      repo: 'https://github.com/processing/p5.js',
            +    }
            +  </script>
            +  <script src="https://unpkg.com/docsify/lib/docsify.min.js"></script>
            +</body>
            +</html>
            diff --git a/dist/copyright.html b/dist/copyright.html
            new file mode 100644
            index 0000000000..c4766e79a1
            --- /dev/null
            +++ b/dist/copyright.html
            @@ -0,0 +1,154 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">copyright | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/assets/img/favicon.ico">
            +    <link rel="icon" href="/assets/img/favicon.ico">
            +
            +
            +    <script src="/assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Copyright Information</h1>
            +      <p>The p5.js library is free software; you can redistribute it and/or modify it under the terms of the<a href="https://github.com/processing/p5.js/blob/main/license.txt">GNU Lesser General 
            +      Public License</a> as published by the Free Software Foundation, version 2.1.</p>
            +      <p>The Reference for the language is under a <a href='http://creativecommons.org/licenses/by-nc-sa/4.0/'>Creative Commons</a> license which makes it possible to reuse this content for non-commercial purposes if it is credited.</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/download/index.html b/dist/download/index.html
            new file mode 100644
            index 0000000000..54b10e14d9
            --- /dev/null
            +++ b/dist/download/index.html
            @@ -0,0 +1,272 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>Download</h1>
            +
            +      <h2 class='sr-only'>Introduction</h2>
            +      <p>Welcome! While titled "Download" this page actually contains a collection of links to either download the library or begin working with it online. We've tried to order things to reflect what a beginner might want first, to resources that more experienced programmers may be looking for.</p>
            +
            +      <!-- EDITOR -->
            +      <div class="link_group">
            +        <h2>Editor</h2>
            +        <p>This link redirects you to the p5.js Editor online so you can begin using p5.js immediately.</p>
            +
            +        <a class='support_link' href="https://editor.p5js.org" target="_blank">
            +          <div class="download_box">
            +
            +            <span class="download_name">p5.js Editor</span>
            +            <p>Start coding using the p5.js Editor, no setup required!</p>
            +
            +          </div>
            +        </a>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- COMPLETE LIBRARY -->
            +      <div class="link_group">
            +        <h2>Complete Library</h2>
            +        <p>This is a download containing the p5.js library file, the p5.sound addon, and an example project. It does not contain an editor. Visit <a href="/get-started/">Get Started</a> to learn how to setup a p5.js project.</p>
            +
            +        <a  class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.zip">
            +          <div class="download_box">
            +
            +            <span class="download_name">p5.js complete</span>
            +            <p>Includes:
            +              <br>p5.js, p5.sound.js, and an example project
            +            <br>Version  <span id="p5_version"></span> (<span id="p5_date"></span>)
            +            </p>
            +
            +          </div>
            +        </a>
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- SINGLE FILES -->
            +      <div class="link_group">
            +
            +        <h2 id="single-files">Single Files</h2>
            +        <p>These are downloads or links to the p5.js library file. No additional contents are included.</p>
            +        <ul aria-labelledby="single-files">
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.js</span>
            +                <p>Single file: 
            +                  <br>Full uncompressed version</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.min.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.min.js</span>
            +                <p>Single file: 
            +                  <br>Compressed version</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://cdnjs.com/libraries/p5.js" target="_blank">
            +              <div class="download_box half_box last_box">
            +                <span class="download_name">CDN</span>
            +                <p>Link: 
            +                  <br>Statically hosted file</p>
            +              </div>
            +            </a>
            +          </li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +
            +      </div>
            +
            +      <!-- Github resources -->
            +      <div class="link_group">
            +        <h2 id="etc">Github Resources</h2>
            +        <ul aria-labelledby="etc" id='etc_list' class="list_view bullets">
            +          <li><a href="https://github.com/processing/p5.js/releases">Previous versions (older releases and changelog)</a></li>
            +          <li><a href="https://github.com/processing/p5.js">Code repository (GitHub)</a></li>
            +          <li><a href="https://github.com/processing/p5.js/issues">Report issues, bugs, and errors</a></li>
            +          <li><a href="https://github.com/processing/p5.js/blob/main/contributor_docs/supported_browsers.md">Supported browsers </a></li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +    </main>
            +
            +    <script>
            +      $.getJSON('/download/version.json', function(data) {
            +        $('#p5_version').text(data.version);
            +        $('#p5_date').text(data.date);
            +        $('.p5_link').each(function() {
            +          var link = $(this).attr('href').replace('[p5_version]', data.version);
            +          $(this).attr('href', link);
            +        });
            +        $('.editor_version').text(data.editor_version);
            +        $('.editor_link').each(function() {
            +          var link = $(this).attr('href').replace('[editor_version]', data.editor_version);
            +          $(this).attr('href', link);
            +        });
            +      });
            +      $('.support_link').on('click', function (e) {
            +        if ($(this).hasClass('p5_link')) {
            +          e.preventDefault();
            +          window.location = $(this).attr('href');
            +          setTimeout( function() { window.location = 'support.html'; }, 10000);
            +        } else {
            +          setTimeout( function() { window.location = 'support.html'; }, 1000);
            +        }
            +
            +      });
            +
            +    </script>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/download/support.html b/dist/download/support.html
            new file mode 100644
            index 0000000000..cb494d2d0b
            --- /dev/null
            +++ b/dist/download/support.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>Support p5.js!</h1>
            +
            +      <p>We need your help! p5.js is free, open-source software. We want to make our community as open and inclusive as possible. You can support this work by making a donation to the<a href="https://processingfoundation.org/support/">Processing Foundation</a>, the organization that supports p5.js. Your donation supports software development for p5.js, education resources like code examples and tutorials, <a href="https://processingfoundation.org/fellowships">Fellowships</a>, and <a href="https://processingfoundation.org/advocacy">community events.</a></p>
            +      <script src="https://donorbox.org/widget.js" paypalExpress="true"></script><iframe allowpaymentrequest="" height="900" name="donorbox" src="https://donorbox.org/embed/support-the-processing-foundation?hide_donation_meter=true" style="max-width: 500px; min-width: 250px; max-height:none!important; margin-top: 1em" ></iframe>
            +      
            +      <p><a href="https://processingfoundation.org">The Processing Foundation</a> was founded in 2012 after more than a decade of work with the original Processing software. The Foundation’s mission is to promote software literacy within the visual arts, and visual literacy within technology-related fields — and to make these fields accessible to diverse communities. Our goal is to empower people of all interests and backgrounds to learn how to program and make creative work with code, especially those who might not otherwise have access to these tools and resources.</p>
            +
            +      <div id="slideshow">
            +        <div>
            +          <img src="../assets/img/download/p5js-5939.jpg" alt="support-17-alt">
            +          <p>p5.js Contributors Conference at CMU STUDIO for Creative Inquiry in Pittsburgh (Image credit: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/saskia-project.jpg" alt="support-18-alt">
            +          <p>Processing Fellow Saskia Freeke is organizing Code Liberation x Processing workshops in London (Image credit: Code Liberation Foundation)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/LearningToTeach45-small.jpg" alt="support-19-alt">
            +          <p>Learning to Teach, Teaching to Learn conference with SFPC (Image credit: Kira Simon-Kennedy)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/Cassie_CodeMiami0.png" alt="support-20-alt">
            +          <p>Processing Foundation Fellow Cassie Tarakajian's workshop at Code Art Miami (Image credit: Christian Arévalo Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/signingcoders2.jpg" alt="support-21-alt">
            +          <p>Taeyoon Choi and ASL interpretor at Signing Coders p5.js workshop (Image credit: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/gsoc_kickoff.jpg" alt="support-22-alt">
            +          <p>Google Summer of Code kickoff (Image credit: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/Cassie_CodeMiami5.png" alt="support-23-alt">
            +          <p>Processing Foundation Fellow Cassie Tarakajian's workshop at Code Art Miami (Image credit: Christian Arévalo Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/signingcoders0.jpg" alt="support-24-alt">
            +          <p>Luisa Pereira and Yeseul Song helping facilitate a sign language based p5.js workshop led by Taeyoon Choi (Image credit: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/conf2.jpg" alt="support-25-alt">
            +          <p>p5.js Contributors Conference at CMU STUDIO for Creative Inquiry in Pittsburgh (Image credit: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/digitalcitizens-panel3.png" alt="support-26-alt">
            +          <p>Processing Fellow Digital Citizens Lab hosts a panel on STEM teaching at the International Center of Photography (Image credit: International Center of Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/aaron.jpg" alt="support-27-alt">
            +          <p>Participants at p5.js workshop in Santiago, Chile, led by Aarón Montoya-Moraga (Image credit: Aarón Montoya-Moraga.)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/signingcoders3.jpg" alt="support-28-alt">
            +          <p>Claire Kearney-Volpe helping facilitate a sign language based p5.js workshop led by Taeyoon Choi (Image credit: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/diygirls1.jpg" alt="support-29-alt">
            +          <p>Processing Foundation Fellow DIY Girls run a creative coding program in Los Angeles (Image credit: DIY Girls)</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/digitalcitizens7.jpg" alt="support-30-alt">
            +          <p>Processing Fellow Digital Citizens Lab</p>
            +        </div>
            +        <div>
            +          <img src="../assets/img/download/p5-coast2coast.jpg" alt="support-31-alt">
            +          <p>Bicoastal p5.js meetup at UCLA DMA and NYU ITP</p>
            +        </div>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<script src="../assets/js/slideshow.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/books/index.html b/dist/es/books/index.html
            new file mode 100644
            index 0000000000..2dc4ae8f9f
            --- /dev/null
            +++ b/dist/es/books/index.html
            @@ -0,0 +1,302 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">books | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="books-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Libros</h1>
            +      <br>
            +
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/gettingstarted.jpg" alt="book cover getting started with p5.js">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Getting Started with p5.js</h2>
            +
            +          <p>Lauren McCarthy, Casey Reas, y Ben Fry. Illustrations by Taeyoon Choi.</p>
            +          <p>
            +            Publicado 2015, Maker Media. 
            +            246 páginas. 
            +            Tapa blanda. 
            +          </p>
            +
            +          <p>Escrito por la desarolladora principal de p5.js y los fundadores de Processing, este libro provee una introducción a las posibilidades creativas de la web actual, usando Javascript y HTML.</p>
            +
            +          <p><a href="http://shop.oreilly.com/product/0636920032076.do" target="_blank">Ordena desde O'Reilly</a></p>
            +          <p><a href="http://www.amazon.com/Make-Interactive-Graphics-JavaScript-Processing/dp/1457186772" target="_blank">Ordena desde Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/gettingstarted-es.jpg" alt="book cover Introducción a p5.js">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Introducción a p5.js (edición en español)</h2>
            +
            +          <p>Lauren McCarthy, Casey Reas, y Ben Fry. Traducido por Aarón Montoya-Moraga. Ilustraciones de Taeyoon Choi.</p>
            +          <p>
            +            Publicado 2018, Processing Foundation, Inc. 
            +            246 páginas. 
            +            Tapa blanda. 
            +          </p>
            +
            +          <p>Escrito por la desarolladora principal de p5.js y los fundadores de Processing, este libro provee una introducción a las posibilidades creativas de la web actual, usando Javascript y HTML.</p>
            +
            +          <p><a href="https://processingfoundation.press/product/introduccion-a-p5-js/" target="_blank">Ordena el pdf desde The Processing Foundation Press</a></p>
            +          <p><a href="https://www.amazon.com/Introducci%C3%B3n-p5-js-Spanish-Lauren-McCarthy/dp/0999881302/" target="_blank">Ordena la versión física desde Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/generative_design.jpg" alt="book cover generative design">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Generative Design</h2>
            +
            +          <p>Benedikt Gross, Hartmut Bohnacker, Julia Laub and Claudius Lazzeroni.</p>
            +          <p>
            +            Publicado 2018, Princeton Architectural Press; Reprint edition. 
            +            255 páginas. 
            +            Tapa blanda. 
            +          </p>
            +
            +          <p>By using simple languages such as JavaScript in p5.js, artists and makers can create everything from interactive typography and textiles to 3D-printed furniture to complex and elegant infographics.</p>
            +
            +          <p><a href="https://www.papress.com/html/product.details.dna?isbn=9781616897581" target="_blank">Ordena desde Princeton Architectural Press</a></p>
            +          <p><a href="https://www.amazon.com/Generative-Design-Visualize-Program-JavaScript/dp/1616897589" target="_blank">Ordena desde Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/generative_gestaltung.jpg" alt="book cover Generative Gestaltung">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Generative Gestaltung (German Edition)</h2>
            +
            +          <p>Benedikt Gross, Hartmut Bohnacker, Julia Laub and Claudius Lazzeroni.</p>
            +          <p>
            +            Publicado 2018, Schmidt Hermann Verlag. 
            +            256 páginas. 
            +            Tapa dura. 
            +          </p>
            +
            +          <p>By using simple languages such as JavaScript in p5.js, artists and makers can create everything from interactive typography and textiles to 3D-printed furniture to complex and elegant infographics.</p>
            +
            +          <p><a href="https://typografie.de/produkt/generative-gestaltung-creative-coding-im-web/" target="_blank">Ordena desde Verlag Hermann Schmidt</a></p>
            +          <p><a href="https://www.amazon.com/Generative-Gestaltung/dp/3874399028" target="_blank">Ordena desde Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/learn_javascript.jpg" alt="book cover learn javascript">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Learn JavaScript with p5.js</h2>
            +
            +          <p>Engin Arslan.</p>
            +          <p>
            +            Publicado 2018, Apress. 
            +            217 páginas. 
            +            Tapa blanda. 
            +          </p>
            +
            +          <p>Learn coding from scratch in a highly engaging and visual manner using the vastly popular JavaScript with the programming library p5.js. The skills you will acquire from this book are highly transferable to a myriad of industries and can be used towards building web applications, programmable robots, or generative art. </p>
            +
            +          <p><a href="https://www.apress.com/gp/book/9781484234259" target="_blank">Ordena desde Apress</a></p>
            +          <p><a href="https://www.amazon.com/Learn-JavaScript-p5-js-Coding-Learners/dp/1484234251" target="_blank">Ordena desde Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/aesthetic-programming.jpg" alt="book cover learn javascript">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Aesthetic Programming: A Handbook of Software Studies</h2>
            +
            +          <p>Winnie Soon, Geoff Cox. </p>
            +          <p>
            +            Publicado en 2020, por Open Humanities Press. 
            +            298 páginas. 
            +            Tapa dura.
            +          </p>
            +
            +          <p>Usando p5.js, este libro introduce y demuestra la práctica reflexiva de la programación estética, promoviendo aprender a programar como una forma de entender y cuestaionar los objetos y paradigmas tecnológios existentes, y explorar el potencial de reprogramar sistemas más amplios en las esferas económica, social y técnica.</p>
            +
            +          <p><a href="http://openhumanitiespress.org/books/download/Soon-Cox_2020_Aesthetic-Programming.pdf" target="_blank">Descarga en PDF (gratis)</a></p>
            +          <p><a href="https://www.barnesandnoble.com/w/aesthetic-programming-winnie-soon/1138820949" target="_blank">Comprar en Barnes & Noble</a></p>
            +
            +        </div>
            +      </div>
            +      <br>
            +      <div style='clear:both; height: 2em'></div>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="books-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/community/contributors-conference-2015.html b/dist/es/community/contributors-conference-2015.html
            new file mode 100644
            index 0000000000..88f4b90fb7
            --- /dev/null
            +++ b/dist/es/community/contributors-conference-2015.html
            @@ -0,0 +1,286 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Conferencia de contribuyentes 2015</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>Mayo 25-31</h2>
            +
            +      <p>Un diverso grupo de aproximadamente 30 participantes se reunieron durante una semana en el <a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a>, haciendo avances en el código, la documentación y las herramientas de extensión para la comunidad en torno al ambiente de programación p5.js. Los participantes vinieron de lugares tan distantes como Hong Kong, Seattle, Los Angeles, Boston y New York. La mayoría eran profesionales que trabajan en los campos de tecnología creativa, diseño de interacciónn, y artes mediales, pero el grupo también incluyó a una media docena de estudiantes de pregrado y posgrado de las escuelas de Arte y Arquitectura de Carnegie Mellon University.
            +      </p>
            +      </div>
            +
            +      <img src="../../assets/img/community/2015_1.jpg" alt='Un diverso grupo de participantes sonríe y hace un signo de p5 con sus manos"'/>
            +      <img src="../../assets/img/community/2015_3.jpg" alt='Mujer presenta la Declaración de comunidad en torno a p5.js utilizando su computadora"'/>
            +      <img src="../../assets/img/community/2015_4.jpg" alt='Mujer al micrófono habla expresivamente mientras que dos colaboradores observan"'/>
            +      <img src="../../assets/img/community/2015_5.jpg" alt='Participantes sonríen con atención al frente del aula"'/>
            +      <img src="../../assets/img/community/2015_6.jpg" alt='Mujer al micrófono lee sobre p5.js into a tres estudiantas"'/>
            +      <img src="../../assets/img/community/2015_7.jpg" alt='Participantes se sientan en un círculo alrededor de una pizarra con notas de colores mientras que una estudianta habla al micrófono"'/>
            +      <img src="../../assets/img/community/2015_8.jpg" alt='Participants sit around a table looking at each others laptops and compare code "'/>
            +      <img src="../../assets/img/community/2015_9.jpg" alt='Pizarra con notas de distintos colores y notas sobre programación "'/>
            +      <img src="../../assets/img/community/2015_10.jpg" alt='Mujer al micrófono habla sobre la importancia de valorar distintas habilidades mientras que un grupo de participantes en sus computadoras observan su presentación en un aula "'/>
            +      <img src="../../assets/img/community/2015_11.jpg" alt='Mujer habla desde un podio en un auditorio mientras que tres participantes se sientan en el escenario y otros tres participan en una videollamada "'/>
            +      <img src="../../assets/img/community/2015_12.jpg" alt='Vista aérea de un aula con participantes trabajando en sus computadoras portátiles "'/>
            +      <img src="../../assets/img/community/2015_13.jpg" alt='Cinco personas discutiendo en un círculo "'/>
            +      <img src="../../assets/img/community/2015_14.jpg" alt='Cinco personas en un círculo con sus computadoras portátiles compartiendo notas "'/>
            +      <img src="../../assets/img/community/2015_15.jpg" alt='Hombe al micrófono habla a un grupo de participantes dentro de un aula "'/>
            +      <img src="../../assets/img/community/2015_2.jpg" alt='Participantes saltan, sonríen y alzan sus manos en el aire sobre un campo de césped"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/80913365@N04/albums/72157653238862069/with/17613092994/" target="_blank">Fotos por Taeyoon Choi</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>Participantes</h2>
            +      <p>
            +        <a href='http://huah.net/jason/' target='_blank'>Jason Alderman</a>,
            +        <a href='http://sepans.com/' target='_blank'>Sepand Ansari</a>,
            +        <a href='http://tegabrain.com' target='_blank'>Tega Brain</a>,
            +        <a href='https://medium.com/@emchenNYC/' target='_blank'>Emily Chen</a>,
            +        <a href='http://andrescolubri.net/' target='_blank'>Andres Colubri</a>,
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>,
            +        <a href='http://guydebree.com/' target='_blank'>Guy de Bree</a>,
            +        <a href='http://www.cjdecarteret.com/' target='_blank'>Christine de Carteret</a>,
            +        <a href='http://xystudio.cc/' target='_blank'>Xy Feng</a>,
            +        <a href='http://www.sarahgp.com/' target='_blank'>Sarah Groff-Palermo</a>,
            +        <a href='http://www.crhallberg.com/' target='_blank'>Chris Hallberg</a>,
            +        <a href='http://valhead.com/' target='_blank'>Val Head</a>,
            +        <a href='http://johannahedva.com' target='_blank'>Johanna Hedva</a>,
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>,
            +        <a href='http://web.media.mit.edu/~jacobsj/' target='_blank'>Jennifer Jacobs</a>,
            +        <a href='http://www.epicjefferson.com/' target='_blank'>Epic Jefferson</a>,
            +        <a href='http://michellepartogi.com' target='_blank'>Michelle Partogi</a>,
            +        <a href='http://lav.io/' target='_blank'>Sam Lavigne</a>,
            +        <a href='http://flong.com' target='_blank'>Golan Levin</a>,
            +        <a href='http://www.liuchangitp.com/' target='_blank'>Cici Liu</a>,
            +        <a href='http://www.mayaman.cc/' target='_blank'>Maya Man</a>,
            +        <a href='http://lauren-mccarthy.com' target='_blank'>Lauren McCarthy</a>,
            +        <a href='http://www.workergnome.com/' target='_blank'>David Newbury</a>,
            +        <a href='http://molleindustria.org/' target='_blank'>Paolo Pedercini</a>,
            +        <a href='http://luisaph.com' target='_blank'>Luisa Pereira</a>,
            +        <a href='http://mileshiroo.info/' target='_blank'>Miles Peyton</a>,
            +        <a href='http://carolinerecord.com/' target='_blank'>Caroline Record</a>,
            +        <a href='http://b2renger.github.io/' target='_blank'>Berenger Recoules</a>,
            +        <a href='https://pibloginthesky.wordpress.com/' target='_blank'>Stephanie Pi</a>,
            +        <a href='http://jasonsigal.cc' target='_blank'>Jason Sigal</a>,
            +        <a href='http://studioindefinit.com/' target='_blank'>Kevin Siwoff</a>,
            +        <a href='http://charlottestiles.com/' target='_blank'>Charlotte Stiles</a>
            +      </p>
            +      </div>
            +
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Diversidad</h2>
            +        <p>Además de desarrollo técnico, otros de los principales enfoques de esta conferencia fueron extensión y diversidad. La conferencia comenzó con un panel—<a href="http://studioforcreativeinquiry.org/events/diversity-seven-voices-on-race-gender-ability-class-for-floss-and-the-internet" target="_blank">Diversidad: Siete voces discuten sobre raza, género, habilidades &amp; clase en FLOSS e Internet</a>. Organizado por <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>
            +        y <a  href="http://lauren-mccarthy.com" target="_blank">Lauren McCarthy</a>, el panel ocurrió el martes 25 de mayo 2015 en el Kresge Auditorium en Carnegie Mellon University. Los oradores incluyeron <a href="http://www.mayaman.cc/" target='_blank'>Maya Man</a>, <a href="http://reas.com/" target='_blank'>Casey
            +        Reas</a>, <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>, <a href="https://pibloginthesky.wordpress.com/" target='_blank'>Stephanie Pi</a>,
            +        <a href="http://phoenixperry.com/" target='_blank'>Phoenix Perry</a>, <a href="http://taeyoonchoi.com/" target='_blank'>Taeyoon Choi</a>,
            +        <a href="http://ablersite.org/" target='_blank'>Sara Hendren</a>, <a href="http://www.epicjefferson.com/" target='_blank'>Epic Jefferson</a>,
            +        y <a href="http://chandlermcwilliams.com/" target='_blank'>Chandler McWilliams</a>.
            +        <img class="alignleft size-full wp-image-8423" src="http://studioforcreativeinquiry.org/wp-content/uploads/2015/05/diversity_640.jpg" alt="diversity_640"/>
            +        </p>
            +        <iframe src="https://player.vimeo.com/video/129140298?color=ffffff&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +        
            +        <table style="margin-top: 10px; background-color: #ffffff; border-collapse: collapse; border: 0px; width: 720px;">
            +        <tbody>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129151416?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Casey Reas</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129151418?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Johanna Hedva</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129160951?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Stephanie Pi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129163155?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Phoenix Perry</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129173628?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Taeyoon Choi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129177689?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Sara Hendren</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129183825?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Epic Jefferson</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129187909?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Chandler McWilliams</td>
            +        </tr>
            +        </tbody>
            +        </table>
            +        <iframe src="https://player.vimeo.com/video/129192014?color=ffffff&amp;title=1&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +      </div>
            +
            +
            +<!--       <div class="contributors-subsection">
            +      <h3>Documentation</h3>
            +      <p><a href='https://medium.com/@tchoi8/diversity-at-sfpc-d494d7390375' target=_blank>Diversity at SFPC
            +      (talk by Taeyoon Choi at “Diversity: Seven Voices on Race, Gender, Ability &amp; Class for FLOSS and
            +      the Internet”)</a></p>
            +      </div> -->
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Apoyo</h2>
            +
            +      <p>Nuestra conferencia de contribuyentes fue realizada en el <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> en Carnegie Mellon University, un laboratorio académico para investigación atípica, anti-disciplinaria, e inter-institucional, en la intersección del arte, la ciencia, la tecnología y la cultura.</p>
            +
            +      <p>Este evento fue posible gracias a fondos del <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      y el generoso apoyo de <a href="https://tisch.nyu.edu/itp" target="_blank">NYU Interactive Telecommunications Program</a>
            +      (ITP), <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href="http://theartificial.nl/" target="_blank">TheArtificial</a>, <a href="http://bocoup.com/" target="_blank">Bocoup</a>, <a href="http://tinysubversions.com/" target="_blank">Darius Kazemi</a>, y <a href="http://www.du.edu/ahss/edp/" target="_blank">Emergent Digital Practices | University of Denver</a><br><b>¡Gracias!</b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../../assets/img/community/nea.jpg' alt=""></a></div>
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:18%' src='../../assets/img/community/studio.png' alt=""/></a>
            +      <a class='nounderline' href='http://itp.nyu.edu/itp/' target=_blank ><img style='width:18%' src='../../assets/img/community/itp.png' alt=""/></a>
            +      <a class='nounderline' href='http://www.du.edu/ahss/edp/' target=_blank ><img style='width:18%' src='../../assets/img/community/edp.png' alt=""/></a>
            +      <a class='nounderline' href='http://bocoup.com/' target=_blank ><img style='width:18%' src='../../assets/img/community/bocoup.png' alt=""/></a>
            +      <a class='nounderline' href='http://theartificial.nl/' target=_blank ><img style='width:18%' src='../../assets/img/community/theartificial.png' alt=""/></a>
            +
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/community/contributors-conference-2019.html b/dist/es/community/contributors-conference-2019.html
            new file mode 100644
            index 0000000000..c4aa3ae316
            --- /dev/null
            +++ b/dist/es/community/contributors-conference-2019.html
            @@ -0,0 +1,307 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Conferencia de contribuyentes 2019</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>Agosto 13-18</h2>
            +
            +      <p>Un grupo interdisciplinario de 35 participantes se reunió en <a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a>, para programar, documentar, crear herramientas para la comunidad y explorar el estado del ambiente de programación p5.js. Los participantes vinieron de diversos campos incluyendo tecnología creativa, diseño de interación y artes new media. La conferencia se enfocó en promover el diálogo a través de un abordaje multidisciplinario. Grupos de trabajo se enfocaron en varias áreas temáticas: Acceso; Música y Código en Performance; el Estado de la Tecnología; e Internacionalización.
            +      </p>
            +      </div>
            +      
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/YkfG7Ggpi_o" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/At1newHnZpA" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <p><a href="https://www.youtube.com/channel/UCzMs9qg50AW2LEpLDzHT5NA" target="_blank">Videos por Qianqian Ye</a></p><br>
            +
            +      <img src="../../assets/img/community/2019_1.jpg" alt='Hombre en un podio de la universidad dando una presentación a un aula llena"'/>
            +      <img src="../../assets/img/community/2019_2.jpg" alt='Participantes sentados en una mesa larga almorzando y conversando"'/>
            +      <img src="../../assets/img/community/2019_4.jpg" alt='Aula con participantes trabajando en sus computadoras portátiles"'/>
            +      <img src="../../assets/img/community/2019_5.jpg" alt='Participantes reunidos a oscuras en un un aula"'/>
            +      <img src="../../assets/img/community/2019_6.jpg" alt='Mujer presenta en un aula con participantes diversos"'/>
            +      <img src="../../assets/img/community/2019_7.jpg" alt='Participantes conversan en un aula llena de personas"'/>
            +      <img src="../../assets/img/community/2019_8.jpg" alt='Mujer al micrófono habla con participantes en un aula"'/>
            +      <img src="../../assets/img/community/2019_9.jpg" alt='Participante en el podio habla frente a un texto proyectado sobre el problema de anonimizar datos "'/>
            +      <img src="../../assets/img/community/2019_10.jpg" alt='Person with a microphone speaking to fellow participants in front of text that reads p5.js will not add any new features except those that increase access"'/>
            +      <img src="../../assets/img/community/2019_11.jpg" alt='Mujer al micrófono habla con participantes en un aula"'/>
            +      <img src="../../assets/img/community/2019_12.jpg" alt='Hombre al micrófono habla con participantes"'/>
            +      <img src="../../assets/img/community/2019_13.jpg" alt='Participantes sentados en un aula escuchando atentamente a quienes presentan "'/>
            +      <img src="../../assets/img/community/2019_15.jpg" alt='Mujer al micrófono habla con participantes sobre los límites sagrados del en proyecto detrás suyo "'/>
            +      <img src="../../assets/img/community/2019_16.jpg" alt='Vista aéra de participantes escuchando un panel y viendo una proyección de una imagen en 3d sobre persona "'/>
            +      <img src="../../assets/img/community/2019_17.jpg" alt='Participantes sentados al rededor de una mesa con sus computadoras portátiles observando el código en una pantalla"'/>
            +      <img src="../../assets/img/community/2019_18.jpg" alt='Mujer sentada al lado de un oso de pelucho del mismo tamaño trabaja en su computadora "'/>
            +      <img src="../../assets/img/community/2019_19.jpg" alt='Participantes de pie sonriendo al aire libre "'/>
            +      <img src="../../assets/img/community/2019_20.jpg" alt='Cuatro participantes de pie conversan en un círculo"'/>
            +      <img src="../../assets/img/community/2019_21.jpg" alt='Participantes almorzando juntos sentados al aire libre"'/>
            +      <img src="../../assets/img/community/2019_22.jpg" alt='Participantes sentados al rededor de una mesa en forma de U video hacia el frente del aula"'/>
            +      <img src="../../assets/img/community/2019_23.jpg" alt='Hombre sentado al frente del aula hablando enérgicamente al micrófono "'/>
            +      <img src="../../assets/img/community/campfire.jpg" alt='Grupo de personas sentadas al rededor de una fogata hecha con cuatro monitores LCD."'/>
            +      <img src="../../assets/img/community/2019_24.jpg" alt='Foto grupal de participantes con sus manos en el aire sonriendo con entusiasmo"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/creativeinquiry/albums/72157710545834046/" target="_blank">Fotos por Jacquelyn Johnson</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>Participantes</h2>
            +      <p>
            +        <a href='https://americanartist.us/biocv' target='_blank'>American Artist</a>, 
            +        <a href='https://www.omayeli.com/' target='_blank'>Omayeli Arenyeka</a>, 
            +        <a href='http://www.sinabahram.com/' target='_blank'>Sina Bahram</a>, 
            +        <a href='https://aatishb.com/' target='_blank'>Aatish Bhatia</a>, 
            +        <a href='https://natalie.computer/' target='_blank'>Natalie Braginsky</a>, 
            +        <a href='https://jonchambers.net/' target='_blank'>Jon Chambers</a>, 
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>, 
            +        <a href='https://www.linkedin.com/in/aren-davey-bb3496103/' target='_blank'>Aren Davey</a>, 
            +        <a href='https://teddavis.org/' target='_blank'>Ted Davis</a>, 
            +        <a href='http://l05.is/' target='_blank'>Carlos Garcia</a>, 
            +        <a href='http://stalgiagrigg.name/' target='_blank'>Stalgia Grigg</a>, 
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>, 
            +        <a href='http://www.shawnemichaelainholloway.com/' target='_blank'>shawné michaelain holloway</a>, 
            +        <a href='http://www.takinglifeseriously.com/index.html' target='_blank'>Claire Kearney-Volpe</a>, 
            +        <a href='https://www.sonalee.me/' target='_blank'>Sona Lee</a>, 
            +        <a href='https://designerken.be/designing' target='_blank'>Kenneth Lim</a>, 
            +        <a href='https://www.outofambit.com/' target='_blank'>Evelyn Masso</a>, 
            +        <a href='http://lauren-mccarthy.com/' target='_blank'>Lauren McCarthy</a>, 
            +        <a href='https://laja.me/' target='_blank'>LaJuné McMillian</a>, 
            +        <a href='https://www.decontextualize.com/' target='_blank'>Allison Parrish</a>, 
            +        <a href='http://www.luisapereira.net/' target='_blank'>Luisa Pereira</a>, 
            +        <a href='https://guillemontecinos.cl/' target='_blank'>Guillermo Montecinos</a>, 
            +        <a href='http://montoyamoraga.io/' target='_blank'>Aarón Montoya-Moraga</a>,
            +        <a href='http://lm-m.com/' target='_blank'>Luis Morales-Navarro</a>, 
            +        Shefali Nayak, 
            +        <a href='http://everest-pipkin.com/' target='_blank'>Everest Pipkin</a>, 
            +        <a href='http://oross.net/' target='_blank'>Olivia Ross</a>, 
            +        <a href='https://dorothysantos.com/' target='_blank'>Dorothy R. Santos</a>, 
            +        <a href='https://www.yashengshe.com/' target='_blank'>Yasheng She</a>, 
            +        <a href='https://junshern.github.io/' target='_blank'>Jun Shern Chan</a>, 
            +        <a href='https://cassietarakajian.com/' target='_blank'>Cassie Tarakajian</a>, 
            +        <a href='https://www.laurenvalley.com/' target='_blank'>Lauren Valley</a>, 
            +        <a href='https://xin-xin.info' target='_blank'>Xin Xin</a>, 
            +        <a href='https://ayxx.me/' target='_blank'>Alex Yixuan Xu</a>, 
            +        <a href='http://www.qianqian-ye.com/' target='_blank'>Qianqian Ye</a>
            +      </p>
            +      </div>
            +
            +
            +      <div class="outputs-subsection">
            +      <h2 id='outputs'>Resultados</h2>
            +      <ul aria-labelledby='outputs' class='list_view bullets'>
            +        <!-- arts -->
            +        <li>Un panel sobre género y afro-desendencia en espacios virtuales liderado por American Artist, con shawné michaelain holloway y LaJuné McMillian.</li>
            +        <li>Nuevas instalaciones artísticas por by Stalgia Grigg, LaJuné McMillian, Aatish Bhatia, y Jon Chambers.</li>
            +        <!-- landscape -->
            +        <li>Un prototipo de  <a href="https://github.com/aparrish/nb5js-proof-of-concept" target="_blank">interface notebook para p5.js.</a> Creado por Allison Parrish.</li>
            +        <li>El diseño de un sistema de bibliotecas para el editor de p5.js. Creado por Cassie Tarakajian y Luca Damasco.</li>
            +        <li>Prototipos para conectar p5 a otras bibliotecas. Creado por Alex Yixuan Xu y Lauren Valley.</li>
            +
            +        <!-- global -->
            +        <li><a href="https://docs.google.com/document/d/1NPSVTWlTxWv8_rWLr8j91Qf8CcJA5ns8I8zFjCCmwuk/edit#heading=h.ea0uhs87h6fk" target="_blank">Herramientas para contribuyentes globales de p5.js.</a> Creado por Aarón Montoya-Moraga, Kenneth Lim, Guillermo Montecinos, Qianqian Ye,  Dorothy R. Santos, y Yasheng She.</li>
            +
            +        <!-- access -->
            +        <li><a href="https://docs.google.com/presentation/d/19xxc2zWWdFMAQjT6tRdN5ZU13vAKSwM7jojaC2U4F6Q/edit" target="_blank">Como escribir código creativo no-violento.</a> Una revista liderada por Olivia Ross.</li>
            +        <li>Una reforma del sitio web para accesibilidad. Incluyendo actualizaciones para accesibilidad usando lectores de pantalla, y mejoras a las páginas principal, descargas, empezar y referencia. Con contribuciones de Claire Kearney-Volpe, Sina Bahram, Kate Hollenbach, Olivia Ross, Luis Morales-Navarro, Lauren McCarthy y Evelyn Masso.</li>
            +
            +        <!-- music performance -->
            +        <li><a href="https://github.com/aahdee/p5grid">p5grid</a>. La implementación de patrones flexibles con formas de triángulos, cuadrados, hexágonos y octágonos para p5.js. Creado por Aren Davey.</li>
            +        <li><a href="https://github.com/L05/p5.multiplayer">p5.multiplayer</a>. Una serie de plantillas para construir juegos para varios jugadores en distintos dispositivos donde multiples clientes se conectan a un servidor. Creado por L05.</li>
            +        <li>Experimentos utilizando <a href="https://teddavis.org/p5live/">P5LIVE</a>, pruebas de una implementación temprana de softCompile, interface OSC y conectividad aumentada con un demo para su uso con MIDI. ¡Un ambiente de vj colaborativo para codificar en vivo con p5.js! Creado por Ted Davis.</li>
            +        <li>Presentaciones colaborativas por Luisa Pereira, Jun Shern Chan, Shefali Nayak, Sona Lee, Ted Davis, y Carlos Garcia.</li>
            +        <li>Una presentación por Natalie Braginsky.</li>
            +  
            +        <!-- workshops -->
            +        <li>Talleres liderados por Everest Pipkin y Jon Chambers.</li>
            +
            +        <!-- closing -->
            +        <li>Una fogata de cierre liderada por Golan Levin.</li>
            +        
            +      </ul>
            +      </div>
            +
            +      <div class="contributors-subsection">
            +      <h2>Apoyo</h2>
            +
            +      <p>Nuestra conferencia de contribuyentes fue realizada en el <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> en Carnegie Mellon University, un laboratorio académico para investigación atípica, anti-disciplinaria, e inter-institucional, en la intersección del arte, la ciencia, la tecnología y la cultura.</p>
            +
            +      <p>Este evento fue posible gracias a fondos del <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      y el generoso apoyo de <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href='https://www.mozilla.org/en-US/moss/' target=_blank>Mozilla Foundation</a>, <a href='https://www.du.edu/ahss/opensourcearts/' target=_blank>Clinic for Open Source Arts (COSA) at the University of Denver</a>, <a href='http://idm.engineering.nyu.edu/' target=_blank>NYU Tandon IDM</a>, <a href='https://tisch.nyu.edu/itp' target=_blank> NYU ITP</a>, <a href='http://thebaselschoolofdesign.ch/' target=_blank>FHNW Academy of Art and Design</a>, <a href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank>DePaul University College of Computing and Digital Media</a>, y <a href='http://amt.parsons.edu/' target=_blank>Parsons School of Art, Media, and Technology at the New School</a>.
            +      <br><b>¡Gracias!</b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../../assets/img/community/nea.jpg' alt=""></a></div>
            +      
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:20%' src='../../assets/img/community/studio.png' alt=""/></a>
            +      
            +      <a class='nounderline' href='http://thebaselschoolofdesign.ch/' target=_blank ><img style='width:70%' src='../../assets/img/community/HGK.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://foundation.processing.org' target=_blank ><img style='width:14%' src='../../assets/img/community/processing-foundation.png' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='https://www.du.edu/ahss/opensourcearts/' target=_blank ><img style='width:22%' src='../../assets/img/community/COSA.png' alt=""/></a>
            +
            +      <a class='nounderline' href='http://idm.engineering.nyu.edu/' target=_blank ><img style='width:50%' src='../../assets/img/community/IDM.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://amt.parsons.edu/' target=_blank ><img style='width:22%' src='../../assets/img/community/Parsons.jpg' alt=""/></a>
            +
            +      <a class='nounderline' href='https://tisch.nyu.edu/itp' target=_blank ><img style='width:14%' src='../../assets/img/community/itp.png' alt=""/></a>
            +
            +      <a class='nounderline' href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank ><img style='width:50%' src='../../assets/img/community/depaul.png' alt=""/></a>
            +
            +      
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/community/developer-docs.html b/dist/es/community/developer-docs.html
            new file mode 100644
            index 0000000000..24b7b816f3
            --- /dev/null
            +++ b/dist/es/community/developer-docs.html
            @@ -0,0 +1,141 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<link rel="stylesheet" href="https://unpkg.com/docsify/lib/themes/buble.css">
            +
            +<div id="community-page">
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <div id="app"></div>
            +      <script>
            +        window.$docsify = {
            +          auto2top: true,
            +          executeScript: true,
            +          loadSidebar: 'sidebar.md',
            +          autoHeader: true,
            +          loadNavbar: 'navbar.md',
            +          mergeNavbar: true,
            +          subMaxLevel: 2,
            +          themeColor: '#ed225d',
            +          basePath:
            +          'https://raw.githubusercontent.com/processing/p5.js/master/contributor_docs/',
            +          logo: '../assets/img/p5js.svg',
            +          name: 'p5.js Developer Docs',
            +          repo: 'https://github.com/processing/p5.js',
            +        }
            +      </script>
            +      <script src="https://unpkg.com/docsify/lib/docsify.min.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/community/index.html b/dist/es/community/index.html
            new file mode 100644
            index 0000000000..564099eee9
            --- /dev/null
            +++ b/dist/es/community/index.html
            @@ -0,0 +1,234 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content">
            +      <h1>Comunidad</h1>
            +      <div class="community-statement">
            +        <h2 class="community-title">Declaración de comunidad en torno a p5.js </h2>
            +        <p>p5.js es una comunidad interesada en explorar la creación de arte y diseño con tecnología.
            +        </p>
            +
            +        <p>Somos una comunidad de, y en solidaridad con, gente de todas las identidades y expresiones de género, orientación sexual, raza, etnicidad, lenguaje, neurotipo, tamaño, habilidad, clase, religión, cultura, subcultura, opinión política, edad, nivel de habilidades, ocupación y bagaje. Reconocemos que no todos tienen el tiempo, medios económicos o la capacidad de participar activamente, pero sí reconocemos y promovemos el involucramiento de todo tipo. Facilitamos y fomentamos tanto acceso como empoderamiento. Todos somos estudiantes.
            +        </p>
            +
            +        <p>Nos gustan estos hashtags: #noCodeSnobs (porque valoramos la comunidad por sobre la eficiencia), #newKidLove (porque todos empezamos en alguna parte), #unassumeCore (porque no asumimos conocimiento previo) y #BlackLivesMatter (obviamente).
            +        </p>
            +
            +        <h3 id="in-practice">En la práctica:</h3>
            +        <ul aria-labelledby="in-practice" class="bullets list_view">
            +          <li> No somos programadores snob. No asumimos conocimiento previo ni damos por sentado que hay cosas que todos deberían saber.  </li>
            +          <li>Insistimos en involucrarnos de manera activa en las peticiones de respuesn, sin importar su complejidad. </li>
            +          <li>Le damos la bienvenida a los novatos y priorizamos la educación de otros. Apuntamos a aproximarnos a todas las tareas con el entusiasmo de un novato. Porque creemos que son tan importantes en este esfuerzo como los expertos. </li>
            +          <li>Hacemos un esfuerzo constante en activamente reconocer y validar múltiples tipos de contribuciones. </li>
            +          <li>Siempre estamos dispuestos a ofrecer ayuda y consejo. </li>
            +        </ul>
            +
            +        <h3 id="in-conflict">En tiempos de conflicto:</h3>
            +        <ul aria-labelledby="in-conflict" class="bullets list_view">
            +          <li>Escuchamos</li>
            +          <li>Comunicamos claramente y reconocemos los sentimientos del otro.</li>
            +          <li>Admitimos nuestros errores, pedimos disculpas, y aceptamos responsabilidad por nuestras acciones.</li>
            +          <li>Buscamos continuamente mejorar nosotros mismos y nuestra comunidad.</li>
            +          <li>Mantenemos nuestra comunidad respetuosa y abierta. </li>
            +          <li>Hacemos que todos se sientan escuchados.</li>
            +          <li>Somos conscientes y amables en nuestras interacciones.</li>
            +        </ul>
            +
            +        <h3 id="in-future">En el futuro:</h3>
            +        <ul aria-labelledby="in-future" class="bullets list_view">
            +          <li>El futuro es ahora.</li>
            +        </ul>
            +        <br>
            +        <h3 id="notes" class='sr-only'>Notes</h3>
            +        <p>Please also see our  <a href="https://github.com/processing/p5.js/blob/main/CODE_OF_CONDUCT.md#p5js-code-of-conduct">p5.js Code of Conduct</a>. Esta Declaración de comunidad en torno a p5.js está licenciada bajo <a href="https://creativecommons.org/licenses/by-sa/4.0/">Licencia de Creative Commons</a>. Por favor comparte y remezcla con atribución.</p>
            +      </div>
            +
            +      <h2 id="contribute">Contribuye</h2>
            +      <p>Nuestra comunidad siempre está buscando entusiastas para ayudar de diferentes maneras.</p>
            +
            +      <p><b>Desarrolla.</b> <a href="https://github.com/processing/p5.js" target="blank_">GitHub</a> es el principal lugar donde se almacena el código, se documentan los problemas y se discute sobre el código. Revisa el  <a href="https://p5js.org/contributor-docs" target="blank_"> tutorial de desarrollo </a>  para introducirte al tema, o  <a href="../libraries/#create-your-own"> crea tu propia biblioteca. </a></p>
            +
            +      <p><b>Documenta.</b> Todos amamos la documentación. Necesitamos ayuda <a href="https://github.com/processing/p5.js-website/blob/main/contributor_docs/Adding_examples.md" target="blank_">agregando ejemplos</a>, <a href="https://p5js.org/contributor-docs/#/inline_documentation" target="blank_"> añadiendo documentación</a> y creando tutoriales.</p>
            +
            +      <p><b>Enseña.</b> Haz un taller, da una clase, enséñale a tus amigos y colaboradores! Etiqueta a @p5xjs en Twitter y haremos lo posible para compartir lo que estás haciendo.</p>
            +
            +      <p><b>Crea.</b> p5.js está buscando diseñadores, artistas y  programadores que contribuyan con una obra increíble y creativa para ser mostrada en la página principal y así inspirar al resto. Envía tu trabajo a <a href="mailto:hello@p5js.org">hello@p5js.org</a>.</p>
            +
            +      <p><b>Dona.</b> p5.js es gratuito y de código abierto y hecho por artistas. Ayuda al desarrollo de p5.js a través de una donación a la <a href="https://processingfoundation.org/support">Processing Foundation</a>.</p>
            +
            +
            +      <h2>Conferencia de contribuyentes</h2>
            +      <p>Anque la mayor parte del trabajo sucede en línea, también nos reunimos en persona. Hemos tenido dos conferencias de contribuyentes realizadas en <a href="http://studioforcreativeinquiry.org">Frank-Ratchye STUDIO for Creative Inquiry</a>  en la Universidad Carnegie Mellon en Pittsburgh, PA. Artistas, diseñadores, desarrolladores, y educadores se reunieron para llevar el proyecto p5.js adelante.
            +      </p>
            +      <h2 id="conferences" class="sr-only">Past Conferences</h2>
            +      <ul aria-labelledby="conferences" class="list_view bullets">
            +        <li><a href="contributors-conference-2019.html">Conferencia de contribuyentes 2019</a></li>
            +        <li><a href="contributors-conference-2015.html">Conferencia de contribuyentes 2015</a></li>
            +      </ul>
            +
            +      <img src="../../assets/img/community/2015_12.jpg" alt='Vista aérea de un aula con participantes trabajando en sus computadoras portátiles "'/>
            +
            +      <h2>Boletín</h2>
            +      <div class="email-octopus-form-wrapper">
            +        <p class="email-octopus-success-message"></p>
            +        <p class="email-octopus-error-message"></p>
            +        <form method="post" action="https://emailoctopus.com/lists/537b6ec8-d123-11e6-8561-06ead731d453/members/external-add" class="email-octopus-form">
            +          <p>Ingresa tu dirección de correo electrónico para recibir ocasionalmente novedades de la Processing Foundation.</p>
            +          <div class="email-octopus-form-row">
            +            <input type="email" name="emailAddress" placeholder="email" class="email-octopus-email-address">
            +            <button type="submit">subscribe</button>
            +          </div>
            +          <div class="email-octopus-form-row-hp" aria-hidden="true">
            +            <input type="text" name="hp537b6ec8-d123-11e6-8561-06ead731d453" tabindex="-1">
            +          </div>
            +          <div class="email-octopus-form-row-subscribe">
            +            <input type="hidden" name="successRedirectUrl" class="email-octopus-success-redirect-url" value="">
            +          </div>
            +        </form>
            +      </div>
            +      <script src="https://emailoctopus.com/bundles/emailoctopuslist/js/formEmbed.js"></script>
            +      <br><br>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/copyright.html b/dist/es/copyright.html
            new file mode 100644
            index 0000000000..933a0409f8
            --- /dev/null
            +++ b/dist/es/copyright.html
            @@ -0,0 +1,154 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">copyright | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Información de Copyright</h1>
            +      <p>La biblioteca p5.js es software libre; puedes redistribuirla y/o modificarla según los términos de la <a href="https://github.com/processing/p5.js/blob/main/license.txt">GNU Lesser General 
            +      Public License</a> publicada por la Free Software Foundation, versión 2.1.</p>
            +      <p>La Referencia del lenguaje se encuentra bajo una licencia <a href='http://creativecommons.org/licenses/by-nc-sa/4.0/'>Creative Commons</a> que permite reusar este contenido para propósitos no-comerciales si se otorga el crédito correspondiente.</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/download/index.html b/dist/es/download/index.html
            new file mode 100644
            index 0000000000..93997739af
            --- /dev/null
            +++ b/dist/es/download/index.html
            @@ -0,0 +1,272 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>Descargar</h1>
            +
            +      <h2 class='sr-only'>Introduction</h2>
            +      <p>¡Bienvenidos! Aunque esta página se titula "Descargar", en realidad contiene una colección de enlaces para descargar la biblioteca o comenzar a trabajar en línea. Hemos tratado de ordenar cosas desde lo que un principiante podría desear explorar primero, a los recursos que los programadores más experimentados pueden estar buscando.</p>
            +
            +      <!-- EDITOR -->
            +      <div class="link_group">
            +        <h2>Editor</h2>
            +        <p>Este enlace te redirige al Editor p5.js en línea para que puedas comenzar a usar p5.js de inmediato.</p>
            +
            +        <a class='support_link' href="https://editor.p5js.org" target="_blank">
            +          <div class="download_box">
            +
            +            <span class="download_name">Editor de p5.js</span>
            +            <p>Empieza a programar usando el Editor de p5.js, ¡no requiere instalación!</p>
            +
            +          </div>
            +        </a>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- COMPLETE LIBRARY -->
            +      <div class="link_group">
            +        <h2>Biblioteca completa</h2>
            +        <p>Esta es una descarga contiene el archivo de la biblioteca p5.js, el complemento p5.sound y un proyecto de ejemplo. No contiene un editor. Explora  <a href="/es/get-started/">Empezar</a> para aprender cómo crear un proyecto de p5.js.</p>
            +
            +        <a  class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.zip">
            +          <div class="download_box">
            +
            +            <span class="download_name">p5.js completo</span>
            +            <p>Incluye:
            +              <br>p5.js, p5.sound.js y un proyecto de ejemplo
            +            <br>Versión  <span id="p5_version"></span> (<span id="p5_date"></span>)
            +            </p>
            +
            +          </div>
            +        </a>
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- SINGLE FILES -->
            +      <div class="link_group">
            +
            +        <h2 id="single-files">Archivos por separado</h2>
            +        <p>Estas son descargas o enlaces al archivo de biblioteca p5.js. No incluyen contenidos adicionales.</p>
            +        <ul aria-labelledby="single-files">
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.js</span>
            +                <p>Archivo: 
            +                  <br> versión completa sin compresión</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.min.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.min.js</span>
            +                <p>Archivo: 
            +                  <br>versión comprimida</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://cdnjs.com/libraries/p5.js" target="_blank">
            +              <div class="download_box half_box last_box">
            +                <span class="download_name">CDN</span>
            +                <p>Enlace: 
            +                  <br>archivo almacenado estáticamente</p>
            +              </div>
            +            </a>
            +          </li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +
            +      </div>
            +
            +      <!-- Github resources -->
            +      <div class="link_group">
            +        <h2 id="etc">Recursos de GitHub</h2>
            +        <ul aria-labelledby="etc" id='etc_list' class="list_view bullets">
            +          <li><a href="https://github.com/processing/p5.js/releases">Versiones antiguas / bitácora de cambios </a></li>
            +          <li><a href="https://github.com/processing/p5.js">Repositorio de Código (GitHub)</a></li>
            +          <li><a href="https://github.com/processing/p5.js/issues">Reporta errores </a></li>
            +          <li><a href="https://github.com/processing/p5.js/blob/main/contributor_docs/supported_browsers.md">Navegadores soportados </a></li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +    </main>
            +
            +    <script>
            +      $.getJSON('/download/version.json', function(data) {
            +        $('#p5_version').text(data.version);
            +        $('#p5_date').text(data.date);
            +        $('.p5_link').each(function() {
            +          var link = $(this).attr('href').replace('[p5_version]', data.version);
            +          $(this).attr('href', link);
            +        });
            +        $('.editor_version').text(data.editor_version);
            +        $('.editor_link').each(function() {
            +          var link = $(this).attr('href').replace('[editor_version]', data.editor_version);
            +          $(this).attr('href', link);
            +        });
            +      });
            +      $('.support_link').on('click', function (e) {
            +        if ($(this).hasClass('p5_link')) {
            +          e.preventDefault();
            +          window.location = $(this).attr('href');
            +          setTimeout( function() { window.location = 'support.html'; }, 10000);
            +        } else {
            +          setTimeout( function() { window.location = 'support.html'; }, 1000);
            +        }
            +
            +      });
            +
            +    </script>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/download/support.html b/dist/es/download/support.html
            new file mode 100644
            index 0000000000..d70a9fec62
            --- /dev/null
            +++ b/dist/es/download/support.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>¡Apoya a p5.js!</h1>
            +
            +      <p>¡Necesitamos tu ayuda! p5.js es un software gratuito y de código abierto.  Queremos hacer nuestra comunidad lo más abierta e inclusiva posible.  You can support this work by making a donation to the <a href="https://processingfoundation.org/support/">Processing Foundation</a>, the organization that supports p5.js. Your donation supports software development for p5.js, education resources like code examples and tutorials, <a href="https://processingfoundation.org/fellowships">becarios</a>, y <a href="https://processingfoundation.org/advocacy">eventos para la comunidad.</a></p>
            +      <script src="https://donorbox.org/widget.js" paypalExpress="true"></script><iframe allowpaymentrequest="" height="900" name="donorbox" src="https://donorbox.org/embed/support-the-processing-foundation?hide_donation_meter=true" style="max-width: 500px; min-width: 250px; max-height:none!important; margin-top: 1em" ></iframe>
            +      
            +      <p><a href="https://processingfoundation.org">The Processing Foundation</a> fue fundada en 2012 después de más de de una década de trabajo con el software original de Processing. La misión de la fundación es promover la alfabetización de software dentro de las artes visuales, y la alfabetización visual dentro de las disciplinas relacionadas a la tecnología - y hacer estas disciplinas accesibles a comunidades más diversas. Nuestra meta es empoderar a gente de diversos intereses para que aprenda a programar y que realice trabajo creativo con código, especialmente aquellos que de otra forma no hubieran tenido acceso a estas herramientas y recursos.</p>
            +
            +      <div id="slideshow">
            +        <div>
            +          <img src="../../assets/img/download/p5js-5939.jpg" alt="support-17-alt">
            +          <p>Conferencia de contribuyentes de p5.js en el CMU STUDIO for Creative Inquiry en Pittsburgh (crédito de imagen: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/saskia-project.jpg" alt="support-18-alt">
            +          <p>Saskia Freeke, becaria Processing, organiza talleres Code Liberation x Processing en Londres (crédito de imagen: Code Liberation Foundation)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/LearningToTeach45-small.jpg" alt="support-19-alt">
            +          <p>Conferencia Learning to Teach, Teaching to Learn en conjunto con SFPC (crédito de imagen: Kira Simon-Kennedy)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/Cassie_CodeMiami0.png" alt="support-20-alt">
            +          <p>Taller de Cassie Tarakajian, becaria de Processing Foundation, en Code Art Miami (crédito de imagen: Christian Arévalo Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders2.jpg" alt="support-21-alt">
            +          <p>Taeyoon Choi y un intérprete de señas en el taller Signing Coders de p5.js (crédito de imagen: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/gsoc_kickoff.jpg" alt="support-22-alt">
            +          <p>Lanzamiento de Google Summer of Code (crédito de imagen: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/Cassie_CodeMiami5.png" alt="support-23-alt">
            +          <p>Cassie Tarakajian, becaria de Processing Foundation, realiza un taller en Code Art Miami (crédito de imagen: Christian Arévalo Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders0.jpg" alt="support-24-alt">
            +          <p>Luisa Pereira y Yeseul Song ayudan en la realización de un taller de p5.js basado en lenguaje de señas, enseñado por Taeyoon Choi (crédito de imagen: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/conf2.jpg" alt="support-25-alt">
            +          <p>Conferencia de contribuyentes de p5.js en el CMU STUDIO for Creative Inquiry en Pittsburgh (crédito de imagen: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/digitalcitizens-panel3.png" alt="support-26-alt">
            +          <p>Digital Citizens Lab, becarios Processing, participan eun panel sobre enseñanza STEM en el International Center of Photography (crédito de imagen: International Center of Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/aaron.jpg" alt="support-27-alt">
            +          <p>Participantes de un taller de p5.js in Santiago, Chile, dictado por Aarón Montoya-Moraga (crédito de imagen: Aarón Montoya-Moraga.)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders3.jpg" alt="support-28-alt">
            +          <p>Claire Kearney-Volpe ayuda en la realización de un taller de p5.js basado en lenguaje de señas, enseñado por Taeyoon Choi (crédito de imagen: Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/diygirls1.jpg" alt="support-29-alt">
            +          <p>DIY Girls, becarios de la Processing Foundation, realizan un curso de programación creativa en Los Angeles (crédito de imagen: DIY Girls)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/digitalcitizens7.jpg" alt="support-30-alt">
            +          <p>Processing Fellow Digital Citizens Lab</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/p5-coast2coast.jpg" alt="support-31-alt">
            +          <p>Junta bicostal de p5.js entre UCLA DMA y NYU ITP</p>
            +        </div>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<script src="../../assets/js/slideshow.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/examples/index.html b/dist/es/examples/index.html
            new file mode 100644
            index 0000000000..d4508d912f
            --- /dev/null
            +++ b/dist/es/examples/index.html
            @@ -0,0 +1,3381 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">examples | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="examples-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Ejemplos</h1>
            +
            +      <div class="column_0 column">
            +      
            +        <h3 name='structure' class='anchor'>Estructura</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="structure-comments-and-statements
            .html"
            +            
            +                data-en='Comments/Statements
            '
            +            
            +                data-es='Comments and Statements
            '
            +            
            +                data-hi='निर्देशांक
            '
            +            
            +                data-ko='스테이트멘트와 코멘트
            '
            +            
            +                data-zh-Hans='Comments and Statements
            '
            +            
            +          >Comments/Statements
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-coordinates
            .html"
            +            
            +                data-en='Coordinates
            '
            +            
            +                data-es='Coordenadas
            '
            +            
            +                data-hi='चौड़ाई और ऊंचाई
            '
            +            
            +                data-ko='좌표
            '
            +            
            +                data-zh-Hans='坐标
            '
            +            
            +          >Coordinates
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-width-and-height
            .html"
            +            
            +                data-en='Width/Height
            '
            +            
            +                data-es='width y height
            '
            +            
            +                data-hi='सेटअप और ड्रा
            '
            +            
            +                data-ko='너비와 높이
            '
            +            
            +                data-zh-Hans='Width 和 Height
            '
            +            
            +          >Width/Height
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-setup-and-draw
            .html"
            +            
            +                data-en='Setup/Draw
            '
            +            
            +                data-es='Setup y Draw
            '
            +            
            +                data-hi='और ड्रा
            '
            +            
            +                data-ko='설정하고 그리기
            '
            +            
            +                data-zh-Hans='Setup 与 Draw
            '
            +            
            +          >Setup/Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-no-loop
            .html"
            +            
            +                data-en='No Loop
            '
            +            
            +                data-es='No Loop
            '
            +            
            +                data-hi='लूप
            '
            +            
            +                data-ko='루프 중단
            '
            +            
            +                data-zh-Hans='No Loop
            '
            +            
            +          >No Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-loop
            .html"
            +            
            +                data-en='Loop
            '
            +            
            +                data-es='Bucle
            '
            +            
            +                data-hi='रेड्रा
            '
            +            
            +                data-ko='루프
            '
            +            
            +                data-zh-Hans='Loop
            '
            +            
            +          >Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-redraw
            .html"
            +            
            +                data-en='Redraw
            '
            +            
            +                data-es='Redraw
            '
            +            
            +                data-hi='कार्य
            '
            +            
            +                data-ko='다시 그리기
            '
            +            
            +                data-zh-Hans='Redraw
            '
            +            
            +          >Redraw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-functions
            .html"
            +            
            +                data-en='Functions
            '
            +            
            +                data-es='Funciones
            '
            +            
            +                data-hi='रिकर्सन
            '
            +            
            +                data-ko='그 외 함수들
            '
            +            
            +                data-zh-Hans='函数
            '
            +            
            +          >Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-recursion
            .html"
            +            
            +                data-en='Recursion
            '
            +            
            +                data-es='Recursión
            '
            +            
            +                data-hi='ग्राफिक्स बनाएं
            '
            +            
            +                data-ko='재귀 함수
            '
            +            
            +                data-zh-Hans='递归
            '
            +            
            +          >Recursion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-create-graphics
            .html"
            +            
            +                data-en='Create Graphics
            '
            +            
            +                data-es='createGraphics
            '
            +            
            +                data-ko='그래픽 만들기
            '
            +            
            +                data-zh-Hans='Create Graphics
            '
            +            
            +          >Create Graphics
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='form' class='anchor'>Forma</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="form-points-and-lines
            .html"
            +            
            +                data-en='Points/Lines
            '
            +            
            +                data-es='Puntos y líneas
            '
            +            
            +                data-hi='अंक और रेखाएं
            '
            +            
            +                data-ko='점과 선
            '
            +            
            +                data-zh-Hans='Points 与 Lines
            '
            +            
            +          >Points/Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-shape-primitives
            .html"
            +            
            +                data-en='Shape Primitives
            '
            +            
            +                data-es='Figuras primitivas
            '
            +            
            +                data-hi='शेप प्रिमिटिव्स
            '
            +            
            +                data-ko='기본 조형
            '
            +            
            +                data-zh-Hans='基本形状
            '
            +            
            +          >Shape Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-pie-chart
            .html"
            +            
            +                data-en='Pie Chart
            '
            +            
            +                data-es='Gráfico de sectores
            '
            +            
            +                data-hi='पाई चार्ट
            '
            +            
            +                data-ko='파이형 차트
            '
            +            
            +                data-zh-Hans='饼状图
            '
            +            
            +          >Pie Chart
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-regular-polygon
            .html"
            +            
            +                data-en='Regular Polygon
            '
            +            
            +                data-es='Polígono regular
            '
            +            
            +                data-hi='नियमित बहुभुज
            '
            +            
            +                data-ko='정다각형
            '
            +            
            +                data-zh-Hans='正多边形
            '
            +            
            +          >Regular Polygon
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-star
            .html"
            +            
            +                data-en='Star
            '
            +            
            +                data-es='Estrella
            '
            +            
            +                data-hi='स्टार
            '
            +            
            +                data-ko='별모양
            '
            +            
            +                data-zh-Hans='Star
            '
            +            
            +          >Star
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-triangle-strip
            .html"
            +            
            +                data-en='Triangle Strip
            '
            +            
            +                data-es='Tira de triángulos
            '
            +            
            +                data-hi='त्रिभुज पट्टी
            '
            +            
            +                data-ko='삼각형 고리
            '
            +            
            +                data-zh-Hans='Triangle Strip
            '
            +            
            +          >Triangle Strip
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-bezier
            .html"
            +            
            +                data-en='Bezier
            '
            +            
            +                data-es='Bezier
            '
            +            
            +                data-hi='बेज़ियर
            '
            +            
            +                data-ko='베지어 곡선
            '
            +            
            +                data-zh-Hans='Bezier
            '
            +            
            +          >Bezier
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-3d-primitives
            .html"
            +            
            +                data-en='3D Primitives
            '
            +            
            +                data-es='Primitivas 3D
            '
            +            
            +                data-hi='३डी प्रिमिटिव्स
            '
            +            
            +                data-ko='3D 기본 조형
            '
            +            
            +                data-zh-Hans='基本 3D 形状
            '
            +            
            +          >3D Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-trig-wheels-and-pie-chart
            .html"
            +            
            +                data-en='Trig Wheels/Pie Chart
            '
            +            
            +                data-es='Trig Wheels and Pie Chart
            '
            +            
            +                data-ko='단위원과 파이 차트
            '
            +            
            +                data-zh-Hans='Trig Wheels and Pie Chart
            '
            +            
            +          >Trig Wheels/Pie Chart
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='data' class='anchor'>Datos</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="data-variables
            .html"
            +            
            +                data-en='Variables
            '
            +            
            +                data-es='Variables
            '
            +            
            +                data-hi='चर
            '
            +            
            +                data-ko='변수
            '
            +            
            +                data-zh-Hans='变量
            '
            +            
            +          >Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-true-and-false
            .html"
            +            
            +                data-en='True/False
            '
            +            
            +                data-es='True y False
            '
            +            
            +                data-hi='सही और गलत
            '
            +            
            +                data-ko='참과 거짓
            '
            +            
            +                data-zh-Hans='True 和 False
            '
            +            
            +          >True/False
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-variable-scope
            .html"
            +            
            +                data-en='Variable Scope
            '
            +            
            +                data-es='Alcance de variabless
            '
            +            
            +                data-hi='परिवर्तनीय दायरा
            '
            +            
            +                data-ko='변수 범위
            '
            +            
            +                data-zh-Hans='变量范围
            '
            +            
            +          >Variable Scope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-numbers
            .html"
            +            
            +                data-en='Numbers
            '
            +            
            +                data-es='Números
            '
            +            
            +                data-hi='नंबर
            '
            +            
            +                data-ko='숫자값
            '
            +            
            +                data-zh-Hans='Numbers
            '
            +            
            +          >Numbers
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='arrays' class='anchor'>Arreglos</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="arrays-array
            .html"
            +            
            +                data-en='Array
            '
            +            
            +                data-es='Arreglo
            '
            +            
            +                data-hi='ऐरे
            '
            +            
            +                data-ko='배열
            '
            +            
            +                data-zh-Hans='数组
            '
            +            
            +          >Array
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-2d
            .html"
            +            
            +                data-en='Array 2D
            '
            +            
            +                data-es='Arreglo 2D
            '
            +            
            +                data-hi='ऐरे 2D
            '
            +            
            +                data-ko='2D 배열
            '
            +            
            +                data-zh-Hans='2D 数组
            '
            +            
            +          >Array 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-objects
            .html"
            +            
            +                data-en='Array Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='ऐरे ऑब्जेक्ट्स
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='数组对象
            '
            +            
            +          >Array Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-walk-over-2darray
            .html"
            +            
            +                data-en='Walk Over 2dArray
            '
            +            
            +                data-es='Walk Over 2dArray
            '
            +            
            +                data-ko='Walk Over 2dArray
            '
            +            
            +                data-zh-Hans='Walk Over 2dArray
            '
            +            
            +          >Walk Over 2dArray
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='control' class='anchor'>Control</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="control-iteration
            .html"
            +            
            +                data-en='Iteration
            '
            +            
            +                data-es='Iteración
            '
            +            
            +                data-hi='पुनरावृत्ति
            '
            +            
            +                data-ko='for 반복문
            '
            +            
            +                data-zh-Hans='迭代
            '
            +            
            +          >Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-embedded-iteration
            .html"
            +            
            +                data-en='Embedded Iteration
            '
            +            
            +                data-es='Iteración anidada
            '
            +            
            +                data-hi='एंबेडेड इटरेशन
            '
            +            
            +                data-ko='for 내장 반복문
            '
            +            
            +                data-zh-Hans='嵌入式迭代
            '
            +            
            +          >Embedded Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-1
            .html"
            +            
            +                data-en='Conditionals 1
            '
            +            
            +                data-es='Condicionales 1
            '
            +            
            +                data-hi='सशर्त 1
            '
            +            
            +                data-ko='조건문 1
            '
            +            
            +                data-zh-Hans='条件 1
            '
            +            
            +          >Conditionals 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-2
            .html"
            +            
            +                data-en='Conditionals 2
            '
            +            
            +                data-es='Condicionales 2
            '
            +            
            +                data-hi='सशर्त 2
            '
            +            
            +                data-ko='조건문 2
            '
            +            
            +                data-zh-Hans='条件 2
            '
            +            
            +          >Conditionals 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators
            .html"
            +            
            +                data-en='Logical Operators
            '
            +            
            +                data-es='Operadores lógicos
            '
            +            
            +                data-hi='लॉजिकल ऑपरेटर्स
            '
            +            
            +                data-ko='논리적 연산자
            '
            +            
            +                data-zh-Hans='逻辑操作符
            '
            +            
            +          >Logical Operators
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators-2
            .html"
            +            
            +                data-en='Logical Operators 2
            '
            +            
            +                data-es='Logical Operators 2
            '
            +            
            +                data-ko='Logical Operators 2
            '
            +            
            +                data-zh-Hans='Logical Operators 2
            '
            +            
            +          >Logical Operators 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditional-shapes
            .html"
            +            
            +                data-en='Conditional Shapes
            '
            +            
            +                data-es='Conditional Shapes
            '
            +            
            +                data-ko='Conditional Shapes
            '
            +            
            +                data-zh-Hans='Conditional Shapes
            '
            +            
            +          >Conditional Shapes
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='image' class='anchor'>Imagen</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="image-load-and-display-image
            .html"
            +            
            +                data-en='Load/Display Image
            '
            +            
            +                data-es='Cargar y mostrar imagen
            '
            +            
            +                data-hi='लोड और डिस्प्ले इमेज
            '
            +            
            +                data-ko='이미지 불러오기 및 보이기
            '
            +            
            +                data-zh-Hans='加载(Load)和显示(Display)图像
            '
            +            
            +          >Load/Display Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-background-image
            .html"
            +            
            +                data-en='Background Image
            '
            +            
            +                data-es='Imagen de fondo
            '
            +            
            +                data-hi='पृष्ठभूमि छवि
            '
            +            
            +                data-ko='배경 이미지
            '
            +            
            +                data-zh-Hans='背景图像
            '
            +            
            +          >Background Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-transparency
            .html"
            +            
            +                data-en='Transparency
            '
            +            
            +                data-es='Transparencia
            '
            +            
            +                data-hi='पारदर्शिता
            '
            +            
            +                data-ko='투명도
            '
            +            
            +                data-zh-Hans='透明度
            '
            +            
            +          >Transparency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-alpha-mask
            .html"
            +            
            +                data-en='Alpha Mask
            '
            +            
            +                data-es='Alpha Mask
            '
            +            
            +                data-hi='अल्फा मास्क
            '
            +            
            +                data-ko='알파 마스크
            '
            +            
            +                data-zh-Hans='透明度遮罩 (Alpha Mask)
            '
            +            
            +          >Alpha Mask
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-create-image
            .html"
            +            
            +                data-en='Create Image
            '
            +            
            +                data-es='Crear una imagen
            '
            +            
            +                data-hi='इमेज बनाएं
            '
            +            
            +                data-ko='이미지 만들기
            '
            +            
            +                data-zh-Hans='创建图像
            '
            +            
            +          >Create Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-pointillism
            .html"
            +            
            +                data-en='Pointillism
            '
            +            
            +                data-es='Puntillismo
            '
            +            
            +                data-hi='पॉइंटिलिज्म
            '
            +            
            +                data-ko='점묘법
            '
            +            
            +                data-zh-Hans='点画(Pointillism)
            '
            +            
            +          >Pointillism
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-blur
            .html"
            +            
            +                data-en='Blur
            '
            +            
            +                data-es='Blur
            '
            +            
            +                data-ko='Blur
            '
            +            
            +                data-zh-Hans='Blur
            '
            +            
            +          >Blur
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-edge-detection
            .html"
            +            
            +                data-en='Edge Detection
            '
            +            
            +                data-es='Edge Detection
            '
            +            
            +                data-ko='Edge Detection
            '
            +            
            +                data-zh-Hans='Edge Detection
            '
            +            
            +          >Edge Detection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brightness
            '
            +            
            +                data-ko='Brightness
            '
            +            
            +                data-zh-Hans='Brightness
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-convolution
            .html"
            +            
            +                data-en='Convolution
            '
            +            
            +                data-es='Convolution
            '
            +            
            +                data-ko='Convolution
            '
            +            
            +                data-zh-Hans='Convolution
            '
            +            
            +          >Convolution
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-copy-method
            .html"
            +            
            +                data-en='Copy() method
            '
            +            
            +                data-es='Método copy()
            '
            +            
            +                data-ko='Copy() method
            '
            +            
            +                data-zh-Hans='Copy() 函数
            '
            +            
            +          >Copy() method
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='color' class='anchor'>Color</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="color-hue
            .html"
            +            
            +                data-en='Hue
            '
            +            
            +                data-es='Tinte
            '
            +            
            +                data-hi='ह्यू
            '
            +            
            +                data-ko='색조
            '
            +            
            +                data-zh-Hans='色调
            '
            +            
            +          >Hue
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-saturation
            .html"
            +            
            +                data-en='Saturation
            '
            +            
            +                data-es='Saturación
            '
            +            
            +                data-hi='संतृप्ति
            '
            +            
            +                data-ko='채도
            '
            +            
            +                data-zh-Hans='饱和度
            '
            +            
            +          >Saturation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brillo
            '
            +            
            +                data-hi='चमक
            '
            +            
            +                data-ko='밝기
            '
            +            
            +                data-zh-Hans='亮度
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-color-variables
            .html"
            +            
            +                data-en='Color Variables
            '
            +            
            +                data-es='Variables de color
            '
            +            
            +                data-hi='रंग चर
            '
            +            
            +                data-ko='색상 변수
            '
            +            
            +                data-zh-Hans='颜色变量
            '
            +            
            +          >Color Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-relativity
            .html"
            +            
            +                data-en='Relativity
            '
            +            
            +                data-es='Relatividad
            '
            +            
            +                data-hi='सापेक्षता
            '
            +            
            +                data-ko='상대성
            '
            +            
            +                data-zh-Hans='相对性
            '
            +            
            +          >Relativity
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-linear-gradient
            .html"
            +            
            +                data-en='Linear Gradient
            '
            +            
            +                data-es='Gradiente linear
            '
            +            
            +                data-hi='रैखिक ढाल
            '
            +            
            +                data-ko='선형 그래디언트
            '
            +            
            +                data-zh-Hans='线性渐变
            '
            +            
            +          >Linear Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-radial-gradient
            .html"
            +            
            +                data-en='Radial Gradient
            '
            +            
            +                data-es='Gradiente radial
            '
            +            
            +                data-hi='रेडियल ग्रेडिएंट
            '
            +            
            +                data-ko='방사형 그래디언트
            '
            +            
            +                data-zh-Hans='径向渐变
            '
            +            
            +          >Radial Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-lerp-color
            .html"
            +            
            +                data-en='Lerp Color
            '
            +            
            +                data-es='Interpolación de color
            '
            +            
            +                data-hi='Lerp Color
            '
            +            
            +                data-ko='선형 보간(lerp) 색상
            '
            +            
            +                data-zh-Hans='插值颜色
            '
            +            
            +          >Lerp Color
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='math' class='anchor'>Matemática</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="math-increment-decrement
            .html"
            +            
            +                data-en='Increment Decrement
            '
            +            
            +                data-es='Incremento y decremento
            '
            +            
            +                data-hi='वेतन वृद्धि
            '
            +            
            +                data-ko='증가와 감소
            '
            +            
            +                data-zh-Hans='增量/减量
            '
            +            
            +          >Increment Decrement
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-operator-precedence
            .html"
            +            
            +                data-en='Operator Precedence
            '
            +            
            +                data-es='Precedencia de operadores
            '
            +            
            +                data-hi='ऑपरेटर वरीयता
            '
            +            
            +                data-ko='연산자 우선 순위
            '
            +            
            +                data-zh-Hans='操作符优先级
            '
            +            
            +          >Operator Precedence
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-1d
            .html"
            +            
            +                data-en='Distance 1D
            '
            +            
            +                data-es='Distancia 1D
            '
            +            
            +                data-hi='दूरी 1डी
            '
            +            
            +                data-ko='1D 거리
            '
            +            
            +                data-zh-Hans='一维间距
            '
            +            
            +          >Distance 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-2d
            .html"
            +            
            +                data-en='Distance 2D
            '
            +            
            +                data-es='Distancia 2D
            '
            +            
            +                data-hi='दूरी 2डी
            '
            +            
            +                data-ko='2D 거리
            '
            +            
            +                data-zh-Hans='二维间距
            '
            +            
            +          >Distance 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine
            .html"
            +            
            +                data-en='Sine
            '
            +            
            +                data-es='Seno
            '
            +            
            +                data-hi='साइन
            '
            +            
            +                data-ko='사인
            '
            +            
            +                data-zh-Hans='正弦
            '
            +            
            +          >Sine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-cosine
            .html"
            +            
            +                data-en='Sine Cosine
            '
            +            
            +                data-es='Seno y coseno
            '
            +            
            +                data-hi='साइन कोसाइन
            '
            +            
            +                data-ko='사인 코사인
            '
            +            
            +                data-zh-Hans='正弦余弦
            '
            +            
            +          >Sine Cosine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-wave
            .html"
            +            
            +                data-en='Sine Wave
            '
            +            
            +                data-es='Onda sinusoidal
            '
            +            
            +                data-hi='साइन वेव
            '
            +            
            +                data-ko='사인파
            '
            +            
            +                data-zh-Hans='正弦波
            '
            +            
            +          >Sine Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-additive-wave
            .html"
            +            
            +                data-en='Additive Wave
            '
            +            
            +                data-es='Onda aditiva
            '
            +            
            +                data-hi='Additive Wave
            '
            +            
            +                data-ko='파형 추가
            '
            +            
            +                data-zh-Hans='加性波
            '
            +            
            +          >Additive Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-polartocartesian
            .html"
            +            
            +                data-en='PolarToCartesian
            '
            +            
            +                data-es='Polar a cartesiano
            '
            +            
            +                data-hi='PolarToCartesian
            '
            +            
            +                data-ko='극좌표를 직교 좌표로
            '
            +            
            +                data-zh-Hans='PolarToCartesian
            '
            +            
            +          >PolarToCartesian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-arctangent
            .html"
            +            
            +                data-en='Arctangent
            '
            +            
            +                data-es='Arcotangente
            '
            +            
            +                data-hi='आर्कटिक
            '
            +            
            +                data-ko='아크탄젠트
            '
            +            
            +                data-zh-Hans='反正切
            '
            +            
            +          >Arctangent
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-linear-interpolation
            .html"
            +            
            +                data-en='Linear Interpolation
            '
            +            
            +                data-es='Interpolación Lineal
            '
            +            
            +                data-hi='रैखिक इंटरपोलेशन
            '
            +            
            +                data-ko='선형 보간법
            '
            +            
            +                data-zh-Hans='线性插值
            '
            +            
            +          >Linear Interpolation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-double-random
            .html"
            +            
            +                data-en='Double Random
            '
            +            
            +                data-es='Doble aleatorio
            '
            +            
            +                data-hi='डबल रैंडम
            '
            +            
            +                data-ko='이중 랜덤
            '
            +            
            +                data-zh-Hans='双重随机
            '
            +            
            +          >Double Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random
            .html"
            +            
            +                data-en='Random
            '
            +            
            +                data-es='Aleatorio
            '
            +            
            +                data-hi='रैंडम
            '
            +            
            +                data-ko='랜덤
            '
            +            
            +                data-zh-Hans='随机
            '
            +            
            +          >Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise1d
            .html"
            +            
            +                data-en='Noise1D
            '
            +            
            +                data-es='Ruido 1D
            '
            +            
            +                data-hi='Noise1D
            '
            +            
            +                data-ko='1D 노이즈
            '
            +            
            +                data-zh-Hans='一维噪声 (Noise1D)
            '
            +            
            +          >Noise1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise-wave
            .html"
            +            
            +                data-en='Noise Wave
            '
            +            
            +                data-es='Onda de ruido
            '
            +            
            +                data-hi='शोर लहर
            '
            +            
            +                data-ko='노이즈 파형
            '
            +            
            +                data-zh-Hans='噪声波
            '
            +            
            +          >Noise Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise2d
            .html"
            +            
            +                data-en='Noise2D
            '
            +            
            +                data-es='Ruido 2D
            '
            +            
            +                data-hi='Noise2D
            '
            +            
            +                data-ko='2D 노이즈
            '
            +            
            +                data-zh-Hans='二维噪声 (Noise2D)
            '
            +            
            +          >Noise2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise3d
            .html"
            +            
            +                data-en='Noise3D
            '
            +            
            +                data-es='Ruido 3D
            '
            +            
            +                data-hi='Noise3D
            '
            +            
            +                data-ko='3D 노이즈
            '
            +            
            +                data-zh-Hans='三维噪声 (Noise3D)
            '
            +            
            +          >Noise3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-chords
            .html"
            +            
            +                data-en='Random Chords
            '
            +            
            +                data-es='Cuerdas Aleatorias
            '
            +            
            +                data-hi='रैंडम कॉर्ड्स
            '
            +            
            +                data-ko='랜덤 선들
            '
            +            
            +                data-zh-Hans='随机弦
            '
            +            
            +          >Random Chords
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-gaussian
            .html"
            +            
            +                data-en='Random Gaussian
            '
            +            
            +                data-es='Mapear
            '
            +            
            +                data-hi='नक्शा
            '
            +            
            +                data-ko='매핑(map)
            '
            +            
            +                data-zh-Hans='映射 (Map)
            '
            +            
            +          >Random Gaussian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-map
            .html"
            +            
            +                data-en='Map
            '
            +            
            +                data-es='Ecuaciones Paramétricas
            '
            +            
            +                data-hi='पैरामीट्रिक समीकरण
            '
            +            
            +                data-ko='매개변수 방정식
            '
            +            
            +                data-zh-Hans='参数方程
            '
            +            
            +          >Map
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-graphing-2d-equations
            .html"
            +            
            +                data-en='Graphing 2D Equations
            '
            +            
            +                data-es='Graphing 2D Equations
            '
            +            
            +                data-ko='Graphing 2D Equations
            '
            +            
            +                data-zh-Hans='Graphing 2D Equations
            '
            +            
            +          >Graphing 2D Equations
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-parametric-equations
            .html"
            +            
            +                data-en='Parametric Equations
            '
            +            
            +                data-es='Parametric Equations
            '
            +            
            +                data-ko='Parametric Equations
            '
            +            
            +                data-zh-Hans='Parametric Equations
            '
            +            
            +          >Parametric Equations
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_1 column">
            +        
            +      
            +        <h3 name='simulate' class='anchor'>Simulación</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="simulate-forces
            .html"
            +            
            +                data-en='Forces
            '
            +            
            +                data-es='Fuerzas
            '
            +            
            +                data-hi='बल
            '
            +            
            +                data-ko='힘
            '
            +            
            +                data-zh-Hans='Forces
            '
            +            
            +          >Forces
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particle-system
            .html"
            +            
            +                data-en='Particle System
            '
            +            
            +                data-es='Sistema de partículas
            '
            +            
            +                data-hi='कण प्रणाली
            '
            +            
            +                data-ko='파티클 시스템
            '
            +            
            +                data-zh-Hans='Particle System
            '
            +            
            +          >Particle System
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-wolfram-ca
            .html"
            +            
            +                data-en='Wolfram CA
            '
            +            
            +                data-es='Wolfram CA
            '
            +            
            +                data-hi='वोल्फ्राम सीए
            '
            +            
            +                data-ko='울프램 셀룰러 오토마타
            '
            +            
            +                data-zh-Hans='Wolfram CA
            '
            +            
            +          >Wolfram CA
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-game-of-life
            .html"
            +            
            +                data-en='Game of Life
            '
            +            
            +                data-es='Juego de la vida
            '
            +            
            +                data-hi='Game of Life
            '
            +            
            +                data-ko='라이프 게임
            '
            +            
            +                data-zh-Hans='Game of Life
            '
            +            
            +          >Game of Life
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-multiple-particle-systems
            .html"
            +            
            +                data-en='Multiple Particle Systems
            '
            +            
            +                data-es='Múltiples sistemas de partículas
            '
            +            
            +                data-hi='मल्टीपल पार्टिकल सिस्टम
            '
            +            
            +                data-ko='멀티플 파티클 시스템
            '
            +            
            +                data-zh-Hans='Multiple Particle Systems
            '
            +            
            +          >Multiple Particle Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spirograph
            .html"
            +            
            +                data-en='Spirograph
            '
            +            
            +                data-es='Espirógrafo
            '
            +            
            +                data-hi='स्पाइरोग्राफ
            '
            +            
            +                data-ko='스피로그래프
            '
            +            
            +                data-zh-Hans='Spirograph
            '
            +            
            +          >Spirograph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-l-systems
            .html"
            +            
            +                data-en='L-Systems
            '
            +            
            +                data-es='Sístemas-L
            '
            +            
            +                data-hi='एल-सिस्टम्स
            '
            +            
            +                data-ko='L-시스템
            '
            +            
            +                data-zh-Hans='L-Systems
            '
            +            
            +          >L-Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spring
            .html"
            +            
            +                data-en='Spring
            '
            +            
            +                data-es='Resorte
            '
            +            
            +                data-hi='वसंत
            '
            +            
            +                data-ko='용수철
            '
            +            
            +                data-zh-Hans='Spring
            '
            +            
            +          >Spring
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-springs
            .html"
            +            
            +                data-en='Springs
            '
            +            
            +                data-es='Resortes
            '
            +            
            +                data-hi='स्प्रिंग्स
            '
            +            
            +                data-ko='용수철들
            '
            +            
            +                data-zh-Hans='Springs
            '
            +            
            +          >Springs
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-soft-body
            .html"
            +            
            +                data-en='Soft Body
            '
            +            
            +                data-es='Cuerpo blando
            '
            +            
            +                data-hi='शीतल शरीर
            '
            +            
            +                data-ko='소프트 바디
            '
            +            
            +                data-zh-Hans='Soft Body
            '
            +            
            +          >Soft Body
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-smokeparticles
            .html"
            +            
            +                data-en='SmokeParticles
            '
            +            
            +                data-es='Partículas de humo
            '
            +            
            +                data-hi='स्मोकपार्टिकल्स
            '
            +            
            +                data-ko='연기 파티클
            '
            +            
            +                data-zh-Hans='SmokeParticles
            '
            +            
            +          >SmokeParticles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Movimiento browniano
            '
            +            
            +                data-hi='ब्राउनियन मोशन
            '
            +            
            +                data-ko='브라운 운동
            '
            +            
            +                data-zh-Hans='Brownian Motion
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-chain
            .html"
            +            
            +                data-en='Chain
            '
            +            
            +                data-es='Cadena
            '
            +            
            +                data-hi='चैन
            '
            +            
            +                data-ko='사슬
            '
            +            
            +                data-zh-Hans='Chain
            '
            +            
            +          >Chain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-snowflakes
            .html"
            +            
            +                data-en='Snowflakes
            '
            +            
            +                data-es='Copos de Nieve
            '
            +            
            +                data-hi='स्नोफ्लेक्स
            '
            +            
            +                data-ko='눈송이 파티클
            '
            +            
            +                data-zh-Hans='Snowflakes
            '
            +            
            +          >Snowflakes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-penrose-tiles
            .html"
            +            
            +                data-en='Penrose Tiles
            '
            +            
            +                data-es='Baldosas de Penrose
            '
            +            
            +                data-hi='पेनरोज़ टाइलें
            '
            +            
            +                data-ko='펜로즈 타일
            '
            +            
            +                data-zh-Hans='Penrose Tiles
            '
            +            
            +          >Penrose Tiles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-recursive-tree
            .html"
            +            
            +                data-en='Recursive Tree
            '
            +            
            +                data-es='Árbol Recursivo
            '
            +            
            +                data-hi='रिकर्सिव ट्री
            '
            +            
            +                data-ko='재귀 나무
            '
            +            
            +                data-zh-Hans='Recursive Tree
            '
            +            
            +          >Recursive Tree
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-the-mandelbrot-set
            .html"
            +            
            +                data-en='The Mandelbrot Set
            '
            +            
            +                data-es='El Conjunto de Mandelbrot
            '
            +            
            +                data-hi='मंडेलब्रॉट सेत
            '
            +            
            +                data-ko='망델브로 집합
            '
            +            
            +                data-zh-Hans='The Mandelbrot Set
            '
            +            
            +          >The Mandelbrot Set
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-koch-curve
            .html"
            +            
            +                data-en='Koch Curve
            '
            +            
            +                data-es='Curva Koch
            '
            +            
            +                data-hi='कोच कर्व
            '
            +            
            +                data-ko='코흐 곡선
            '
            +            
            +                data-zh-Hans='Koch Curve
            '
            +            
            +          >Koch Curve
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-bubble-sort
            .html"
            +            
            +                data-en='Bubble Sort
            '
            +            
            +                data-es='Ordenamiento de Burbuja
            '
            +            
            +                data-hi='बबल सॉर्ट
            '
            +            
            +                data-ko='버블 정렬
            '
            +            
            +                data-zh-Hans='Bubble Sort
            '
            +            
            +          >Bubble Sort
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-stepping-feet-illusion
            .html"
            +            
            +                data-en='Stepping Feet Illusion
            '
            +            
            +                data-es='Ilusión de los Pasos
            '
            +            
            +                data-hi='स्टेपिंग फीट इल्यूजन
            '
            +            
            +                data-ko='걷는발 착시효과
            '
            +            
            +                data-zh-Hans='Stepping Feet Illusion
            '
            +            
            +          >Stepping Feet Illusion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particles
            .html"
            +            
            +                data-en='Particles
            '
            +            
            +                data-es='Partículas
            '
            +            
            +                data-hi='कण
            '
            +            
            +                data-ko='파티클
            '
            +            
            +                data-zh-Hans='Particles
            '
            +            
            +          >Particles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-quicksort
            .html"
            +            
            +                data-en='Quicksort
            '
            +            
            +                data-es='Quicksort
            '
            +            
            +                data-ko='Quicksort
            '
            +            
            +                data-zh-Hans='Quicksort
            '
            +            
            +          >Quicksort
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='interaction' class='anchor'>Interacción</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="interaction-tickle
            .html"
            +            
            +                data-en='Tickle
            '
            +            
            +                data-es='Cosquillas
            '
            +            
            +                data-hi='टिकल 
            '
            +            
            +                data-ko='간질간질
            '
            +            
            +                data-zh-Hans='Tickle
            '
            +            
            +          >Tickle
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-weight-line
            .html"
            +            
            +                data-en='Weight Line
            '
            +            
            +                data-es='Weight Line
            '
            +            
            +                data-hi='फॉलो 1
            '
            +            
            +                data-ko='Weight Line
            '
            +            
            +                data-zh-Hans='Weight Line
            '
            +            
            +          >Weight Line
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-1
            .html"
            +            
            +                data-en='Follow 1
            '
            +            
            +                data-es='Seguir 1
            '
            +            
            +                data-hi='फॉलो 2
            '
            +            
            +                data-ko='따라다니기 1
            '
            +            
            +                data-zh-Hans='跟随 1
            '
            +            
            +          >Follow 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-2
            .html"
            +            
            +                data-en='Follow 2
            '
            +            
            +                data-es='Seguir 2
            '
            +            
            +                data-hi='फॉलो 3
            '
            +            
            +                data-ko='따라다니기 2
            '
            +            
            +                data-zh-Hans='跟随 2
            '
            +            
            +          >Follow 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-3
            .html"
            +            
            +                data-en='Follow 3
            '
            +            
            +                data-es='Seguir 3
            '
            +            
            +                data-hi='सांप का खेल
            '
            +            
            +                data-ko='따라다니기 3
            '
            +            
            +                data-zh-Hans='跟随 3
            '
            +            
            +          >Follow 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-snake-game
            .html"
            +            
            +                data-en='Snake game
            '
            +            
            +                data-es='Juego de Serpiente
            '
            +            
            +                data-hi='वेवमेकर
            '
            +            
            +                data-ko='스네이크 게임
            '
            +            
            +                data-zh-Hans='贪吃蛇
            '
            +            
            +          >Snake game
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-wavemaker
            .html"
            +            
            +                data-en='Wavemaker
            '
            +            
            +                data-es='Wavemaker
            '
            +            
            +                data-hi='रीच 1
            '
            +            
            +                data-ko='파도 만들기
            '
            +            
            +                data-zh-Hans='造波器
            '
            +            
            +          >Wavemaker
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-1
            .html"
            +            
            +                data-en='Reach 1
            '
            +            
            +                data-es='Alcanzar 1
            '
            +            
            +                data-hi='रीच 2
            '
            +            
            +                data-ko='팔닿기 1
            '
            +            
            +                data-zh-Hans='延伸 1
            '
            +            
            +          >Reach 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-2
            .html"
            +            
            +                data-en='Reach 2
            '
            +            
            +                data-es='Alcanzar 2
            '
            +            
            +                data-hi='पहुंच ३
            '
            +            
            +                data-ko='팔닿기 2
            '
            +            
            +                data-zh-Hans='延伸 2
            '
            +            
            +          >Reach 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-3
            .html"
            +            
            +                data-en='Reach 3
            '
            +            
            +                data-es='Alcanzar 3
            '
            +            
            +                data-hi='Arduino सेंसर डेटा WebJack के माध्यम से
            '
            +            
            +                data-ko='팔닿기 3
            '
            +            
            +                data-zh-Hans='延伸 3
            '
            +            
            +          >Reach 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-arduino-sensor-data-via-webjack
            .html"
            +            
            +                data-en='Arduino sensor data via WebJack
            '
            +            
            +                data-es='Datos de un sensor Arduino vía WebJack
            '
            +            
            +                data-hi='बहुरूपदर्शक
            '
            +            
            +                data-ko='웹잭과 아두이노 센서 데이터
            '
            +            
            +                data-zh-Hans='通过 WebJack 读取 Arduino 传感器数据
            '
            +            
            +          >Arduino sensor data via WebJack
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-kaleidoscope
            .html"
            +            
            +                data-en='Kaleidoscope
            '
            +            
            +                data-es='Caleidoscopio
            '
            +            
            +                data-ko='만화경
            '
            +            
            +                data-zh-Hans='万花筒
            '
            +            
            +          >Kaleidoscope
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='objects' class='anchor'>Objetos</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="objects-objects
            .html"
            +            
            +                data-en='Objects
            '
            +            
            +                data-es='Objetos
            '
            +            
            +                data-hi='वस्तु
            '
            +            
            +                data-ko='객체
            '
            +            
            +                data-zh-Hans='物件 (Objects)
            '
            +            
            +          >Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-multiple-objects
            .html"
            +            
            +                data-en='Multiple Objects
            '
            +            
            +                data-es='Múltiples objetos
            '
            +            
            +                data-hi='वस्तुओं का नाम दें
            '
            +            
            +                data-ko='복수 객체
            '
            +            
            +                data-zh-Hans='多个物件
            '
            +            
            +          >Multiple Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-array-of-objects
            .html"
            +            
            +                data-en='Array of Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='वस्तुओं की सरणी
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='物件数组
            '
            +            
            +          >Array of Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-objects-2
            .html"
            +            
            +                data-en='Objects 2
            '
            +            
            +                data-es='Objetos 2
            '
            +            
            +                data-hi='वस्तु 2
            '
            +            
            +                data-ko='객체 2
            '
            +            
            +                data-zh-Hans='物件 2
            '
            +            
            +          >Objects 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-inheritance
            .html"
            +            
            +                data-en='Inheritance
            '
            +            
            +                data-es='Herencia
            '
            +            
            +                data-hi='वंशानुक्रम
            '
            +            
            +                data-ko='상속
            '
            +            
            +                data-zh-Hans='继承 (Inheritance)
            '
            +            
            +          >Inheritance
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-composite-objects
            .html"
            +            
            +                data-en='Composite Objects
            '
            +            
            +                data-es='Objetos Compuestos
            '
            +            
            +                data-hi='समग्र वस्तु
            '
            +            
            +                data-ko='합성 객체
            '
            +            
            +                data-zh-Hans='复合物件
            '
            +            
            +          >Composite Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-car-instances
            .html"
            +            
            +                data-en='Car Instances
            '
            +            
            +                data-es='Car Instances
            '
            +            
            +                data-ko='Car Instances
            '
            +            
            +                data-zh-Hans='Car Instances
            '
            +            
            +          >Car Instances
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='lights' class='anchor'>Luces</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="lights-directional
            .html"
            +            
            +                data-en='Directional
            '
            +            
            +                data-es='Direccional
            '
            +            
            +                data-hi='दिशात्मक
            '
            +            
            +                data-ko='디렉셔널 라이트
            '
            +            
            +                data-zh-Hans='定向光
            '
            +            
            +          >Directional
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="lights-mixture
            .html"
            +            
            +                data-en='Mixture
            '
            +            
            +                data-es='Mezcla
            '
            +            
            +                data-hi='मिश्रण
            '
            +            
            +                data-ko='혼합 라이트
            '
            +            
            +                data-zh-Hans='混合光
            '
            +            
            +          >Mixture
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='motion' class='anchor'>Movimiento</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="motion-non-orthogonal-reflection
            .html"
            +            
            +                data-en='Non Orthogonal Reflection
            '
            +            
            +                data-es='Reflejo no ortogonal
            '
            +            
            +                data-hi='नॉन ऑर्थोगोनल रिफ्लेक्शन
            '
            +            
            +                data-ko='비직각 반사
            '
            +            
            +                data-zh-Hans='Non Orthogonal Reflection
            '
            +            
            +          >Non Orthogonal Reflection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-linear
            .html"
            +            
            +                data-en='Linear
            '
            +            
            +                data-es='Lineal
            '
            +            
            +                data-hi='रैखिक
            '
            +            
            +                data-ko='선형
            '
            +            
            +                data-zh-Hans='Linear
            '
            +            
            +          >Linear
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bounce
            .html"
            +            
            +                data-en='Bounce
            '
            +            
            +                data-es='Rebote
            '
            +            
            +                data-hi='उछाल
            '
            +            
            +                data-ko='바운스
            '
            +            
            +                data-zh-Hans='Bounce
            '
            +            
            +          >Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bouncy-bubbles
            .html"
            +            
            +                data-en='Bouncy Bubbles
            '
            +            
            +                data-es='Burbujas Saltarinas
            '
            +            
            +                data-hi='उछाल वाले बुलबुले
            '
            +            
            +                data-ko='버블 바운스
            '
            +            
            +                data-zh-Hans='Bouncy Bubbles
            '
            +            
            +          >Bouncy Bubbles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Transformar
            '
            +            
            +                data-hi='मॉर्फ
            '
            +            
            +                data-ko='변형(morph)
            '
            +            
            +                data-zh-Hans='Morph
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-morph
            .html"
            +            
            +                data-en='Morph
            '
            +            
            +                data-es='Moviéndose por Curvas
            '
            +            
            +                data-hi='मूविंग ऑन कर्व्स
            '
            +            
            +                data-ko='곡선 위 움직이기
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Morph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-circle-collision
            .html"
            +            
            +                data-en='Circle Collision
            '
            +            
            +                data-es='Circle Collision
            '
            +            
            +                data-ko='Circle Collision
            '
            +            
            +                data-zh-Hans='Circle Collision
            '
            +            
            +          >Circle Collision
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-moving-on-curves
            .html"
            +            
            +                data-en='Moving On Curves
            '
            +            
            +                data-es='Moving On Curves
            '
            +            
            +                data-ko='Moving On Curves
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Moving On Curves
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='instance_mode' class='anchor'>Modo Instancia</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="instance-mode-instantiation
            .html"
            +            
            +                data-en='Instantiation
            '
            +            
            +                data-es='Instaciación
            '
            +            
            +                data-hi='इंस्टेंटेशन
            '
            +            
            +                data-ko='인스턴스화
            '
            +            
            +                data-zh-Hans='创建实例
            '
            +            
            +          >Instantiation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="instance-mode-instance-container
            .html"
            +            
            +                data-en='Instance Container
            '
            +            
            +                data-es='Contenedor de instancia
            '
            +            
            +                data-hi='इंस्टेंस कंटेनर
            '
            +            
            +                data-ko='인스턴스 컨테이너
            '
            +            
            +                data-zh-Hans='实例容器
            '
            +            
            +          >Instance Container
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='dom' class='anchor'>DOM</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="dom-input-and-button
            .html"
            +            
            +                data-en='Input/Button
            '
            +            
            +                data-es='Entrada y botón
            '
            +            
            +                data-hi='इनपुट और बटन
            '
            +            
            +                data-ko='입력과 버튼
            '
            +            
            +                data-zh-Hans='Input and Button
            '
            +            
            +          >Input/Button
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-slider
            .html"
            +            
            +                data-en='Slider
            '
            +            
            +                data-es='Barra deslizante
            '
            +            
            +                data-hi='स्लाइडर
            '
            +            
            +                data-ko='슬라이더
            '
            +            
            +                data-zh-Hans='Slider
            '
            +            
            +          >Slider
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-modifying-the-dom
            .html"
            +            
            +                data-en='Modifying the DOM
            '
            +            
            +                data-es='Modificar el DOM
            '
            +            
            +                data-hi='डोम को संशोधित करना
            '
            +            
            +                data-ko='DOM 변경
            '
            +            
            +                data-zh-Hans='Modifying the DOM
            '
            +            
            +          >Modifying the DOM
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video
            .html"
            +            
            +                data-en='Video
            '
            +            
            +                data-es='Video
            '
            +            
            +                data-hi='वीडियो
            '
            +            
            +                data-ko='비디오
            '
            +            
            +                data-zh-Hans='Video
            '
            +            
            +          >Video
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-canvas
            .html"
            +            
            +                data-en='Video Canvas
            '
            +            
            +                data-es='Lienzo y video
            '
            +            
            +                data-hi='वीडियो कैनवास
            '
            +            
            +                data-ko='비디오 캔버스
            '
            +            
            +                data-zh-Hans='Video Canvas
            '
            +            
            +          >Video Canvas
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-pixels
            .html"
            +            
            +                data-en='Video Pixels
            '
            +            
            +                data-es='Pixeles de video
            '
            +            
            +                data-hi='वीडियो पिक्सल
            '
            +            
            +                data-ko='비디오 픽셀
            '
            +            
            +                data-zh-Hans='Video Pixels
            '
            +            
            +          >Video Pixels
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-capture
            .html"
            +            
            +                data-en='Video Capture
            '
            +            
            +                data-es='Captura de video
            '
            +            
            +                data-hi='वीडियो कैप्चर
            '
            +            
            +                data-ko='실시간 비디오
            '
            +            
            +                data-zh-Hans='Video Capture
            '
            +            
            +          >Video Capture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-drop
            .html"
            +            
            +                data-en='Drop
            '
            +            
            +                data-es='Arrojar
            '
            +            
            +                data-hi='छोड़ देना
            '
            +            
            +                data-ko='드롭 기능
            '
            +            
            +                data-zh-Hans='Drop
            '
            +            
            +          >Drop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-dom-form-elements
            .html"
            +            
            +                data-en='DOM Form Elements
            '
            +            
            +                data-es='DOM Form Elements
            '
            +            
            +                data-ko='DOM Form Elements
            '
            +            
            +                data-zh-Hans='DOM Form Elements
            '
            +            
            +          >DOM Form Elements
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='drawing' class='anchor'>Dibujo</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="drawing-continuous-lines
            .html"
            +            
            +                data-en='Continuous Lines
            '
            +            
            +                data-es='Líneas continuas
            '
            +            
            +                data-hi='सतत रेखा 
            '
            +            
            +                data-ko='연속된 선
            '
            +            
            +                data-zh-Hans='Líneas continuas
            '
            +            
            +          >Continuous Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-patterns
            .html"
            +            
            +                data-en='Patterns
            '
            +            
            +                data-es='Patrones
            '
            +            
            +                data-hi='पैटर्न
            '
            +            
            +                data-ko='패턴
            '
            +            
            +                data-zh-Hans='Patrones
            '
            +            
            +          >Patterns
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-pulses
            .html"
            +            
            +                data-en='Pulses
            '
            +            
            +                data-es='Pulsos
            '
            +            
            +                data-hi='दालें
            '
            +            
            +                data-ko='율동
            '
            +            
            +                data-zh-Hans='Pulsos
            '
            +            
            +          >Pulses
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='transform' class='anchor'>Transformar</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="transform-translate
            .html"
            +            
            +                data-en='Translate
            '
            +            
            +                data-es='Translate
            '
            +            
            +                data-hi='अनुवाद
            '
            +            
            +                data-ko='위치 이동(Translate)
            '
            +            
            +                data-zh-Hans='Translate
            '
            +            
            +          >Translate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-scale
            .html"
            +            
            +                data-en='Scale
            '
            +            
            +                data-es='Escalar
            '
            +            
            +                data-hi='स्केल
            '
            +            
            +                data-ko='크기 조정(Scale)
            '
            +            
            +                data-zh-Hans='Scale
            '
            +            
            +          >Scale
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-rotate
            .html"
            +            
            +                data-en='Rotate
            '
            +            
            +                data-es='Rotate
            '
            +            
            +                data-hi='घुमाएँ
            '
            +            
            +                data-ko='회전(Rotate)
            '
            +            
            +                data-zh-Hans='Rotate
            '
            +            
            +          >Rotate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-arm
            .html"
            +            
            +                data-en='Arm
            '
            +            
            +                data-es='Brazo
            '
            +            
            +                data-hi='आर्म
            '
            +            
            +                data-ko='팔모양
            '
            +            
            +                data-zh-Hans='Arm
            '
            +            
            +          >Arm
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_2 column">
            +        
            +      
            +        <h3 name='typography' class='anchor'>Tipografía</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="typography-letters
            .html"
            +            
            +                data-en='Letters
            '
            +            
            +                data-es='Letters
            '
            +            
            +                data-hi='पत्र
            '
            +            
            +                data-ko='글자
            '
            +            
            +                data-zh-Hans='Letters
            '
            +            
            +          >Letters
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-words
            .html"
            +            
            +                data-en='Words
            '
            +            
            +                data-es='Words
            '
            +            
            +                data-hi='शब्द
            '
            +            
            +                data-ko='단어
            '
            +            
            +                data-zh-Hans='Words
            '
            +            
            +          >Words
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-text-rotation
            .html"
            +            
            +                data-en='Text Rotation
            '
            +            
            +                data-es='Text Rotation
            '
            +            
            +                data-ko='텍스트 회전
            '
            +            
            +                data-zh-Hans='Text Rotation
            '
            +            
            +          >Text Rotation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='3d' class='anchor'>3D</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="3d-geometries
            .html"
            +            
            +                data-en='Geometries
            '
            +            
            +                data-es='Geometrías
            '
            +            
            +                data-hi='ज्यामिति
            '
            +            
            +                data-ko='기하
            '
            +            
            +                data-zh-Hans='Geometries
            '
            +            
            +          >Geometries
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-sine-cosine-in-3d
            .html"
            +            
            +                data-en='Sine Cosine in 3D
            '
            +            
            +                data-es='Seno Coseno en 3D
            '
            +            
            +                data-hi='3D में साइन कोसाइन
            '
            +            
            +                data-ko='3D속 사인 코사인
            '
            +            
            +                data-zh-Hans='Sine Cosine in 3D
            '
            +            
            +          >Sine Cosine in 3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-multiple-lights
            .html"
            +            
            +                data-en='Multiple Lights
            '
            +            
            +                data-es='Múltiples luces
            '
            +            
            +                data-hi='मल्टीपल लाइट्स
            '
            +            
            +                data-ko='복수의 조명들
            '
            +            
            +                data-zh-Hans='Multiple Lights
            '
            +            
            +          >Multiple Lights
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-materials
            .html"
            +            
            +                data-en='Materials
            '
            +            
            +                data-es='Materiales
            '
            +            
            +                data-hi='सामग्री
            '
            +            
            +                data-ko='재질(Materials)
            '
            +            
            +                data-zh-Hans='Materials
            '
            +            
            +          >Materials
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-textures
            .html"
            +            
            +                data-en='Textures
            '
            +            
            +                data-es='Texturas
            '
            +            
            +                data-hi='बनावट
            '
            +            
            +                data-ko='텍스처
            '
            +            
            +                data-zh-Hans='Textures
            '
            +            
            +          >Textures
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-ray-casting
            .html"
            +            
            +                data-en='Ray Casting
            '
            +            
            +                data-es='Ray Casting
            '
            +            
            +                data-hi='रे कास्टिंग
            '
            +            
            +                data-ko='레이 캐스팅
            '
            +            
            +                data-zh-Hans='Ray Casting
            '
            +            
            +          >Ray Casting
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-orbit-control
            .html"
            +            
            +                data-en='Orbit Control
            '
            +            
            +                data-es='Control de órbita
            '
            +            
            +                data-hi='कक्षा नियंत्रण
            '
            +            
            +                data-ko='궤도 제어
            '
            +            
            +                data-zh-Hans='Orbit Control
            '
            +            
            +          >Orbit Control
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-basic-shader
            .html"
            +            
            +                data-en='Basic Shader
            '
            +            
            +                data-es='Basic Shader
            '
            +            
            +                data-hi='बेसिक शेडर
            '
            +            
            +                data-ko='셰이더 기초
            '
            +            
            +                data-zh-Hans='Basic Shader
            '
            +            
            +          >Basic Shader
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-as-a-texture
            .html"
            +            
            +                data-en='Shader as a Texture
            '
            +            
            +                data-es='Shader as a Texture
            '
            +            
            +                data-hi='शेडर एक बनावट के रूप में
            '
            +            
            +                data-ko='셰이더로 텍스처 만들기
            '
            +            
            +                data-zh-Hans='Shader as a Texture
            '
            +            
            +          >Shader as a Texture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-passing-shader-uniforms
            .html"
            +            
            +                data-en='Passing Shader Uniforms
            '
            +            
            +                data-es='Passing Shader Uniforms
            '
            +            
            +                data-hi='पासिंग शेडर यूनिफॉर्म
            '
            +            
            +                data-ko='셰이더 유니폼
            '
            +            
            +                data-zh-Hans='Passing Shader Uniforms
            '
            +            
            +          >Passing Shader Uniforms
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-using-webcam
            .html"
            +            
            +                data-en='Shader Using Webcam
            '
            +            
            +                data-es='Shader Using Webcam
            '
            +            
            +                data-hi='Shader वेबकैम का उपयोग कर रहा है
            '
            +            
            +                data-ko='웹캠을 사용한 셰이더
            '
            +            
            +                data-zh-Hans='Shader Using Webcam
            '
            +            
            +          >Shader Using Webcam
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='input' class='anchor'>Input</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="input-clock
            .html"
            +            
            +                data-en='Clock
            '
            +            
            +                data-es='Clock
            '
            +            
            +                data-hi='घड़ी
            '
            +            
            +                data-ko='시계
            '
            +            
            +                data-zh-Hans='Clock
            '
            +            
            +          >Clock
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-constrain
            .html"
            +            
            +                data-en='Constrain
            '
            +            
            +                data-es='Constrain
            '
            +            
            +                data-hi='बाधा
            '
            +            
            +                data-ko='제한
            '
            +            
            +                data-zh-Hans='Constrain
            '
            +            
            +          >Constrain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-easing
            .html"
            +            
            +                data-en='Easing
            '
            +            
            +                data-es='Easing
            '
            +            
            +                data-hi='आसान
            '
            +            
            +                data-ko='이징(Easing)
            '
            +            
            +                data-zh-Hans='Easing
            '
            +            
            +          >Easing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-keyboard
            .html"
            +            
            +                data-en='Keyboard
            '
            +            
            +                data-es='Keyboard
            '
            +            
            +                data-hi='कीबोर्ड
            '
            +            
            +                data-ko='키보드
            '
            +            
            +                data-zh-Hans='Keyboard
            '
            +            
            +          >Keyboard
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-milliseconds
            .html"
            +            
            +                data-en='Milliseconds
            '
            +            
            +                data-es='Mouse 1D
            '
            +            
            +                data-hi='माउस 1D
            '
            +            
            +                data-ko='1D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 1D
            '
            +            
            +          >Milliseconds
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-1d
            .html"
            +            
            +                data-en='Mouse 1D
            '
            +            
            +                data-es='Mouse 2D
            '
            +            
            +                data-hi='माउस 2D
            '
            +            
            +                data-ko='2D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 2D
            '
            +            
            +          >Mouse 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-2d
            .html"
            +            
            +                data-en='Mouse 2D
            '
            +            
            +                data-es='Mouse Press
            '
            +            
            +                data-hi='माउस प्रेस
            '
            +            
            +                data-ko='마우스 버튼
            '
            +            
            +                data-zh-Hans='Mouse Press
            '
            +            
            +          >Mouse 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-functions
            .html"
            +            
            +                data-en='Mouse Functions
            '
            +            
            +                data-es='Mouse Functions
            '
            +            
            +                data-hi='माउस फंक्शन्स
            '
            +            
            +                data-ko='마우스 함수
            '
            +            
            +                data-zh-Hans='Mouse Functions
            '
            +            
            +          >Mouse Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-signals
            .html"
            +            
            +                data-en='Mouse Signals
            '
            +            
            +                data-es='Mouse Signals
            '
            +            
            +                data-hi='माउस सिग्नल
            '
            +            
            +                data-ko='마우스 신호
            '
            +            
            +                data-zh-Hans='Mouse Signals
            '
            +            
            +          >Mouse Signals
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-press
            .html"
            +            
            +                data-en='Mouse Press
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-hi='भंडारण इनपुट
            '
            +            
            +                data-ko='입력값 저장
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Mouse Press
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-rollover
            .html"
            +            
            +                data-en='Rollover
            '
            +            
            +                data-es='Rollover
            '
            +            
            +                data-ko='롤오버 (Rollover)
            '
            +            
            +                data-zh-Hans='Rollover
            '
            +            
            +          >Rollover
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-storing-input
            .html"
            +            
            +                data-en='Storing Input
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-ko='Storing Input
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Storing Input
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='advanced_data' class='anchor'>Avanzado Datos</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-json
            .html"
            +            
            +                data-en='Load Saved JSON
            '
            +            
            +                data-es='Load Saved JSON
            '
            +            
            +                data-hi='लोड सेव किया गया JSON
            '
            +            
            +                data-ko='저장된 JSON 불러오기
            '
            +            
            +                data-zh-Hans='Load Saved JSON
            '
            +            
            +          >Load Saved JSON
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-table
            .html"
            +            
            +                data-en='Load Saved Table
            '
            +            
            +                data-es='Load Saved Table
            '
            +            
            +                data-ko='Load Saved Table
            '
            +            
            +                data-zh-Hans='Load Saved Table
            '
            +            
            +          >Load Saved Table
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='sound' class='anchor'>Sonido</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="sound-load-and-play-sound
            .html"
            +            
            +                data-en='Load/Play Sound
            '
            +            
            +                data-es='Cargar y reproducir sonido
            '
            +            
            +                data-hi='लोड और प्ले साउंड
            '
            +            
            +                data-ko='사운드 불러오기/재생
            '
            +            
            +                data-zh-Hans='Load and Play Sound
            '
            +            
            +          >Load/Play Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-preload-soundfile
            .html"
            +            
            +                data-en='Preload SoundFile
            '
            +            
            +                data-es='Precargar archivo de sonido
            '
            +            
            +                data-hi='प्रीलोड साउंडफाइल
            '
            +            
            +                data-ko='사운드 파일 미리 불러오기
            '
            +            
            +                data-zh-Hans='Preload SoundFile
            '
            +            
            +          >Preload SoundFile
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-soundformats
            .html"
            +            
            +                data-en='soundFormats
            '
            +            
            +                data-es='Formatos de sonido
            '
            +            
            +                data-hi='ध्वनि प्रारूप
            '
            +            
            +                data-ko='사운드 파일 형식
            '
            +            
            +                data-zh-Hans='soundFormats
            '
            +            
            +          >soundFormats
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-play-mode
            .html"
            +            
            +                data-en='Play Mode
            '
            +            
            +                data-es='Modo de reproducción
            '
            +            
            +                data-hi='प्ले मोड
            '
            +            
            +                data-ko='재생 모드
            '
            +            
            +                data-zh-Hans='Play Mode
            '
            +            
            +          >Play Mode
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-pan-sound
            .html"
            +            
            +                data-en='Pan Sound
            '
            +            
            +                data-es='Paneo
            '
            +            
            +                data-hi='पैन साउंड
            '
            +            
            +                data-ko='사운드 패닝
            '
            +            
            +                data-zh-Hans='Pan Sound
            '
            +            
            +          >Pan Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-sound-effect
            .html"
            +            
            +                data-en='Sound Effect
            '
            +            
            +                data-es='Efecto de sonido
            '
            +            
            +                data-hi='ध्वनि प्रभाव
            '
            +            
            +                data-ko='사운드 효과
            '
            +            
            +                data-zh-Hans='Sound Effect
            '
            +            
            +          >Sound Effect
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-playback-rate
            .html"
            +            
            +                data-en='Playback Rate
            '
            +            
            +                data-es='Tasa de reproducción
            '
            +            
            +                data-hi='प्लेबैक दर
            '
            +            
            +                data-ko='재생 속도
            '
            +            
            +                data-zh-Hans='Playback Rate
            '
            +            
            +          >Playback Rate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-measuring-amplitude
            .html"
            +            
            +                data-en='Measuring Amplitude
            '
            +            
            +                data-es=' Midiendo la amplitud
            '
            +            
            +                data-hi='मापने वाला आयाम
            '
            +            
            +                data-ko='진폭 측정
            '
            +            
            +                data-zh-Hans='Measuring Amplitude
            '
            +            
            +          >Measuring Amplitude
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-noise-drum-envelope
            .html"
            +            
            +                data-en='Noise Drum Envelope
            '
            +            
            +                data-es='Tambor con envolvente y ruido
            '
            +            
            +                data-hi='शोर ड्रम लिफाफा
            '
            +            
            +                data-ko='노이즈 드럼 엔벨로프
            '
            +            
            +                data-zh-Hans='Noise Drum Envelope
            '
            +            
            +          >Noise Drum Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-note-envelope
            .html"
            +            
            +                data-en='Note Envelope
            '
            +            
            +                data-es=' Envolvente de nota
            '
            +            
            +                data-hi='नोट लिफाफा
            '
            +            
            +                data-ko='음계 엔벨로프
            '
            +            
            +                data-zh-Hans='Note Envelope
            '
            +            
            +          >Note Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-oscillator-frequency
            .html"
            +            
            +                data-en='Oscillator Frequency
            '
            +            
            +                data-es='Frecuencia de oscilador
            '
            +            
            +                data-hi='थरथरानवाला आवृत्ति
            '
            +            
            +                data-ko='오실레이터 주파수
            '
            +            
            +                data-zh-Hans='Oscillator Frequency
            '
            +            
            +          >Oscillator Frequency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-input
            .html"
            +            
            +                data-en='Mic Input
            '
            +            
            +                data-es='Entrada de micrófono
            '
            +            
            +                data-hi='Mic Input
            '
            +            
            +                data-ko='마이크 입력
            '
            +            
            +                data-zh-Hans='Mic Input
            '
            +            
            +          >Mic Input
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-spectrum
            .html"
            +            
            +                data-en='Frequency Spectrum
            '
            +            
            +                data-es='Espectro de frecuencia
            '
            +            
            +                data-hi='फ्रीक्वेंसी स्पेक्ट्रम Spec
            '
            +            
            +                data-ko='주파수 스펙트럼
            '
            +            
            +                data-zh-Hans='Frequency Spectrum
            '
            +            
            +          >Frequency Spectrum
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-threshold
            .html"
            +            
            +                data-en='Mic Threshold
            '
            +            
            +                data-es='Umbral de micrófono
            '
            +            
            +                data-hi='माइक थ्रेशोल्ड
            '
            +            
            +                data-ko='마이크 임계값
            '
            +            
            +                data-zh-Hans='Mic Threshold
            '
            +            
            +          >Mic Threshold
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-lowpass
            .html"
            +            
            +                data-en='Filter LowPass
            '
            +            
            +                data-es=' Filtro pasabajos
            '
            +            
            +                data-hi='फ़िल्टर लोपास
            '
            +            
            +                data-ko='로우패스 필터
            '
            +            
            +                data-zh-Hans='Filter LowPass
            '
            +            
            +          >Filter LowPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-bandpass
            .html"
            +            
            +                data-en='Filter BandPass
            '
            +            
            +                data-es=' Filtro pasabanda
            '
            +            
            +                data-hi='फ़िल्टर बैंडपास
            '
            +            
            +                data-ko='밴드패스 필터
            '
            +            
            +                data-zh-Hans='Filter BandPass
            '
            +            
            +          >Filter BandPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-delay
            .html"
            +            
            +                data-en='Delay
            '
            +            
            +                data-es=' Delay
            '
            +            
            +                data-hi='देरी
            '
            +            
            +                data-ko='딜레이 필터
            '
            +            
            +                data-zh-Hans='Delay
            '
            +            
            +          >Delay
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-reverb
            .html"
            +            
            +                data-en='Reverb
            '
            +            
            +                data-es=' Reverb
            '
            +            
            +                data-hi='रेवरब
            '
            +            
            +                data-ko='리버브
            '
            +            
            +                data-zh-Hans='Reverb
            '
            +            
            +          >Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-convolution-reverb
            .html"
            +            
            +                data-en='Convolution Reverb
            '
            +            
            +                data-es=' Reverb de convolución
            '
            +            
            +                data-hi='कनवल्शन रेवरब
            '
            +            
            +                data-ko='컨볼루션 리버브
            '
            +            
            +                data-zh-Hans='Convolution Reverb
            '
            +            
            +          >Convolution Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-record-save-audio
            .html"
            +            
            +                data-en='Record Save Audio
            '
            +            
            +                data-es=' Graba y almacena audio
            '
            +            
            +                data-hi='रिकॉर्ड ऑडियो सहेजें
            '
            +            
            +                data-ko='오디오 녹음/저장
            '
            +            
            +                data-zh-Hans='Record Save Audio
            '
            +            
            +          >Record Save Audio
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-modulation
            .html"
            +            
            +                data-en='Frequency Modulation
            '
            +            
            +                data-es='Modulación en frecuencia
            '
            +            
            +                data-hi='फ़्रीक्वेंसी मॉडुलन
            '
            +            
            +                data-ko='주파수 변조(FM)
            '
            +            
            +                data-zh-Hans='Frequency Modulation
            '
            +            
            +          >Frequency Modulation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-amplitude-modulation
            .html"
            +            
            +                data-en='Amplitude Modulation
            '
            +            
            +                data-es='Modulación en amplitud
            '
            +            
            +                data-hi='आयाम मॉडुलन
            '
            +            
            +                data-ko='진폭 변조(AM)
            '
            +            
            +                data-zh-Hans='Amplitude Modulation
            '
            +            
            +          >Amplitude Modulation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='mobile' class='anchor'>Móvil</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-ball-bounce
            .html"
            +            
            +                data-en='Acceleration Ball Bounce
            '
            +            
            +                data-es='Pelota rebote aceleración
            '
            +            
            +                data-hi='एक्सेलेरेशन बॉल बाउंस
            '
            +            
            +                data-ko='가속도와 바운스
            '
            +            
            +                data-zh-Hans='Acceleration Ball Bounce
            '
            +            
            +          >Acceleration Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-simple-draw
            .html"
            +            
            +                data-en='Simple Draw
            '
            +            
            +                data-es='Dibujo simple
            '
            +            
            +                data-hi='सिंपल ड्रा
            '
            +            
            +                data-ko='간단한 드로잉
            '
            +            
            +                data-zh-Hans='Simple Draw
            '
            +            
            +          >Simple Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-color
            .html"
            +            
            +                data-en='Acceleration Color
            '
            +            
            +                data-es='Aceleración y color
            '
            +            
            +                data-hi='त्वरण रंग
            '
            +            
            +                data-ko='가속도 색상
            '
            +            
            +                data-zh-Hans='Acceleration Color
            '
            +            
            +          >Acceleration Color
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-shake-ball-bounce
            .html"
            +            
            +                data-en='Shake Ball Bounce
            '
            +            
            +                data-es='Pelota rebote agitar
            '
            +            
            +                data-hi='शेक बॉल बाउंस
            '
            +            
            +                data-ko='흔들기와 바운스
            '
            +            
            +                data-zh-Hans='Shake Ball Bounce
            '
            +            
            +          >Shake Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-tilted-3d-box
            .html"
            +            
            +                data-en='Tilted 3D Box
            '
            +            
            +                data-es='Caja 3D
            '
            +            
            +                data-hi='झुका हुआ 3D बॉक्स
            '
            +            
            +                data-ko='기울어진 3D상자
            '
            +            
            +                data-zh-Hans='Tilted 3D Box
            '
            +            
            +          >Tilted 3D Box
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='hello_p5' class='anchor'>Hola p5</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="hello-p5-simple-shapes
            .html"
            +            
            +                data-en='Simple Shapes
            '
            +            
            +                data-es='Figuras simples
            '
            +            
            +                data-hi='सरल आकार
            '
            +            
            +                data-ko='간단한 도형들
            '
            +            
            +                data-zh-Hans='Simple Shapes
            '
            +            
            +          >Simple Shapes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-1
            .html"
            +            
            +                data-en='Interactivity 1
            '
            +            
            +                data-es='Interactividad 1
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 1
            '
            +            
            +                data-ko='인터랙티비티 1
            '
            +            
            +                data-zh-Hans='Interactivity 1
            '
            +            
            +          >Interactivity 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-2
            .html"
            +            
            +                data-en='Interactivity 2
            '
            +            
            +                data-es='Interactividad 2
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 2
            '
            +            
            +                data-ko='인터랙티비티 2
            '
            +            
            +                data-zh-Hans='Interactivity 2
            '
            +            
            +          >Interactivity 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-animation
            .html"
            +            
            +                data-en='Animation
            '
            +            
            +                data-es='Animación
            '
            +            
            +                data-hi='एनिमेशन
            '
            +            
            +                data-ko='애니메이션
            '
            +            
            +                data-zh-Hans='Animation
            '
            +            
            +          >Animation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-weather
            .html"
            +            
            +                data-en='Weather
            '
            +            
            +                data-es='Clima
            '
            +            
            +                data-hi='मौसम
            '
            +            
            +                data-ko='날씨
            '
            +            
            +                data-zh-Hans='Weather
            '
            +            
            +          >Weather
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-drawing
            .html"
            +            
            +                data-en='Drawing
            '
            +            
            +                data-es='Dibujar
            '
            +            
            +                data-hi='ड्राइंग
            '
            +            
            +                data-ko='드로잉
            '
            +            
            +                data-zh-Hans='Drawing
            '
            +            
            +          >Drawing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-song
            .html"
            +            
            +                data-en='Song
            '
            +            
            +                data-es='Canción
            '
            +            
            +                data-hi='गीत
            '
            +            
            +                data-ko='노래
            '
            +            
            +                data-zh-Hans='Song
            '
            +            
            +          >Song
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +      </div>
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/get-started/index.html b/dist/es/get-started/index.html
            new file mode 100644
            index 0000000000..b6c6e65ef4
            --- /dev/null
            +++ b/dist/es/get-started/index.html
            @@ -0,0 +1,343 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">get started | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="get-started-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>Empezar</h1>
            +
            +      <p>Esta página te guía para configurar un proyecto p5.js y crear tu primer bosquejo. La forma más fácil de comenzar es usando el  <a href="https://editor.p5js.org" target="_blank">editor p5.js</a>, puedes abrir el editor web y dirigirte a la sección  <a href="#sketch">tu primer bosquejo</a>. Si deseas trabajar en la versión de escritorio de p5.js, puedes ir a las  <a href="#settingUp">instrucciones de descarga</a>.
            +      </p>
            +
            +
            +
            +      <h2 class="start-element" id="sketch">Tu primer bosquejo</h2>
            +
            +      <div class="info">
            +        <h3 class="sr-only">Bloque de código con elipse</h3>
            +        <p>En el <a href='https://editor.p5js.org/'>editor web p5.js</a> vas encontrar el siguiente código:</p>
            +
            +<pre id="first-sketch1"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch1" class="copy_button">Copy</button>
            +        </div>
            +        <p>Despúes de <code class="language-javascript">background(220);</code> incluye esta línea de código: <code class="language-javascript">ellipse(50,50,80,80);</code>.</p>
            +
            +        <p>Ahora tu código debe estar así: </p>
            +        <h3 class="sr-only">Bloque de código con elipse</h3>
            +
            +<pre id="first-sketch2"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +  ellipse(50,50,80,80);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch2" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">La línea que acabas de agreagar dibuja una elipse, con su centro a 50 píxeles del borde izquierdo y 50 píxeles del borde superior del bosquejo, con un ancho y un alto de 80 píxeles.</p>
            +        <p>¡En el editor presiona play para ejecutar el código!</p>
            +        <h3 class="sr-only">Nota para usuarios de lectores de pantalla</h3>
            +        <p>Si estas utilizando un lector de pantalla, tienes que activar las salidas accesibles en el editor, fuera del editor tienes que agregar la biblioteca de accesibilidad a tu html. Para aprender más visita el <a href="../learn/p5-screen-reader.html" target="_blank"> tutorial usando p5 con un lector de pantalla.</a>
            +        </p>
            +        <p>Si escribiste todo correctamente, esto aparecerá en tu ventana de visualización:</p>
            +
            +        <img src="../../assets/img/get-started/first-sketch.png" alt='canvas tiene un circulo de ancho y alto 50 en la posición 80 x y 80 ye'/>
            +
            +        <p>Si nada aparece, el editor puede estar teniendo problemas entendiendo lo que escribiste. Si esto sucede, asegúrate de haber copiado el ejemplo de código tal y como está: los números deben estar separados por comas y contenidos entre paréntesis, la línea debe terminar con punto y coma, y la palabra "ellipse" debe estar escrita como en inglés.</p>
            +
            +        <p>Una de las cosas más difíciles de comenzar a programar es que debes ser muy específicx con la sintaxis. El navegador no siempre es lo suficientemente inteligente como para saber lo que quieres decir, y puede ser bastante exigente con respecto a la ubicación de la puntuación. Ya te acostrumbrarás, sólo toma un poco de práctica. En la parte inferior izquierda del editor vas encontrar la sección de consola. Aquí, encontrarás mensajes del editor con detalles de cualquier error que se encuentre.</p>
            +
            +        <h3 class="sr-only">Bloque de código con Interacción</h3>
            +        <p>Ahora, vamos a crear un bosquejo que es un poco más interesante. Modica el ejemplo anterior para probar lo siguiente:</p>
            +
            +<pre id="first-sketch3"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  if (mouseIsPressed) {
            +    fill(0);
            +  } else {
            +    fill(255);
            +  }
            +  ellipse(mouseX, mouseY, 80, 80);
            +}
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch3" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">Este programa crea un canvas que es de 400 píxeles de ancho y 400 píxeles de alto, y luego empieza a dibujar círculos blancos en la posición del ratón. Cuando algún botón del ratón es presionado, el color del círculo cambia a negro. Ejecuta el código, mueve el cursor, y has click para experimentarlo.
            +        </p>
            +
            +        <img src="../../assets/img/get-started/first-sketch2.png" alt='canvas tiene múltiples círculos dibujados que siguen los movimientos del cursor'/>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="next">¿Qué viene después?</h2>
            +
            +      <div class='info'>
            +        <ul class="list_view">
            +          <li>Visita las páginas <a href="../learn/">aprender</a> y <a href="../examples">ejemplos</a> para conocer la biblioteca.</li>
            +
            +          <li>Mira los video tutoriales de <a href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6Zy51Q-x9tMWIv9cueOFTFA">The Coding Train</a> y <a href="https://www.kadenze.com/courses/introduction-to-programming-for-the-visual-arts-with-p5-js/info">Kadenze</a>.</li>
            +
            +          <li>Visita la <a href="../reference/"> referencia</a> para explorar la documentación completa. </li>
            +          <li>Si deseas utilizar p5 con un lector de pantalla, visita el <a href="../learn/p5-screen-reader.html">tutorial p5 con un lector de pantalla</a>.</li>
            +          <li>Si has usado Processing en el pasado, lee el <a href='https://github.com/processing/p5.js/wiki/Processing-transition'>tutorial de transición desde Processing</a> para aprender cómo convertir programas de Processing a p5.js, y cuáles son las principales diferencias entre estos.</li>
            +
            +        </ul>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="settingUp">Configura p5.js con un editor en tu computadora personal</h2>
            +
            +      <div class="info">
            +        <p>Puedes usar el 
            +          <a href='https://es.wikipedia.org/wiki/Editor_de_codigo_fuente' target="_blank">
            +             editor de código </a>
            +            que prefieras. Las instrucciones para usar y configurar  
            +            <a href="http://www.sublimetext.com/2" target="_blank"> Sublime Text 2</a>
            +             están incluidas a continuación, otras buenas opciones de editores incluyen <a href='http://brackets.io/' target=_blank>Brackets</a>  y <a href='https://atom.io/' target=_blank>Atom</a>. Si estás utilizando un lector de pantalla y no usas el editor de p5, te recomendamos usar  <a href="https://notepad-plus-plus.org/">Notepad++</a>  o 
            +            <a href="https://www.eclipse.org/ide/" target="_blank">Eclipse</a>.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="download">Descarga una copia de la biblioteca p5.js</h3>
            +
            +      <div class="info">
            +        <p>La manera más simple de empezar es usando el ejemplo en blanco incluido en
            +          <a href="../download/">p5.js completo</a>
            +          disponible en el sitio.
            +        </p>
            +
            +        <p>
            +          After download, you need to set up a local server. See instructions 
            +          <a href="https://github.com/processing/p5.js/wiki/Local-server" target="_blank">here</a>
            +          . Run your local server within the downloaded folder and on your browser, go to 
            +          <code>http://localhost:{your-port-num}/empty-example</code>
            +        </p>
            +
            +        <p>Si revisas el archivo index.html, te darás cuenta que tiene un enlace al archivo p5.js. Si estás buscando usar la versión reducida (comprimida para que las páginas carguen más rápidamente), cambia el enlace a p5.min.js.</p>
            +
            +        <pre id="markup1"><code class="language-markup">&lt;script src="../p5.min.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_script" class="copy_button">Copy</button>
            +        </div>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="hosted">Utiliza una versión alojada de la biblioteca p5.js</h3>
            +      <div class="info">
            +        <p>De forma alternativa, puedes enlazar a un archivo p5.js alojado en línea. Todas las versiones de p5.js están almacenadas en un CDN (Content Delivery Network). Puedes ver un historial de estas versiones aquí: 
            +          <a target="_blank" href="https://cdn.jsdelivr.net/npm/p5/lib/">
            +            p5.js CDN</a>. En este caso, puedes cambiar el enlace a: 
            +        </p>
            +
            +        <pre id="cdn-link" class='p5-replace'><code class="language-markup">&lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_link" class="copy_button">Copy</button>
            +        </div>
            +        <p>Una página HTML de ejemplo podría verse así:</p>
            +
            +        <pre id="sample-html" class='p5-replace'><code class="language-markup">
            +&lt;html&gt;
            +  &lt;head&gt;
            +    &lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script&gt;
            +    &lt;script src="sketch.js">&lt;/script&gt;
            +  &lt;/head&gt;
            +  &lt;body&gt;
            +    &lt;main&gt;
            +    &lt;/main&gt;
            +  &lt;/body&gt;
            +&lt;/html&gt;
            +        </code></pre>
            +      <div class="edit_space">
            +          <button id="copy_p5_html" class="copy_button">Copy</button>
            +      </div>
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="environment">Ambiente</h3>
            +      <div class="info">
            +        <p>
            +          Abre Sublime. Despliega el menú File (archivo) y elige Open (abrir) ... y selecciona el directorio donde se encuentran tus archivos html y js. En la barra lateral izquierda, podrás encontrar el nombre del directorio en la parte superior, y a continuación una lista con los archivos contenidos en el directorio.
            +        </p>
            +
            +        <p>
            +          Haz click en tu archivo sketch.js y éste se abrirá a la derecha de tu pantalla, donde podrás editarlo. 
            +          <img src="../../assets/img/get-started/sublime2.png" alt='el código de inicio de p5 en el editor sublime."'/>
            +        </p>
            +
            +        <p>
            +          Abre el archivo index.html en tu navegador haciendo doble click en él o escribiendo: <code>file:///la/ubicacion/de/tu/archivo/html</code>
            +           (or  <code>http://localhost:{your-port-num}/empty-example</code>
            +           if you are using a local server)
            +           en la barra de direcciones de tu navegador para ver tu bosquejo.
            +        </p>
            +      </div>
            +
            +      <div>Partes de este tutorial fueron adaptadas de "Getting Started with p5.js" por Lauren McCarthy, Casey Reas y Ben Fry, O'Reilly / Make 2015. Copyright © 2015. Todos los derechos reservados. Última modificación en la Conferencia de Contribuyentes p5.js 2019.</div>
            +
            +      <script>
            +        $.getJSON('../download/version.json', function(data) {
            +          $('.p5-replace').each(function() {
            +            var html = $(this).html().replace('[p5_version]', data.version);
            +            $(this).html(html);
            +          });
            +        });
            +      </script>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +</div><!-- end id="get-started-page"  -->
            +<script src="/../../assets/js/get-started.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/index.html b/dist/es/index.html
            new file mode 100644
            index 0000000000..4dc2cfdf0b
            --- /dev/null
            +++ b/dist/es/index.html
            @@ -0,0 +1,177 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">home | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<div id="home-page">
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content" class="home">
            +      <form id="search" method="get" action="https://www.google.com/search">
            +        <input type="hidden" name="as_sitesearch" value="p5js.org">
            +        <input id="search_button" type="submit" aria-label="Search" class='sr-only'>
            +        <input tabindex="2" id='search_field' type="text" size="20" placeholder="Search p5js.org" name="q">
            +        <label class="sr-only" for="search_field">Search p5js.org</label>
            +      </form>
            +
            +      <h1>¡Hola!</h1>
            +      <p style="margin-top:1em">¡p5.js es una biblioteca de JavaScript para la programación creativa, que busca hacer que programar sea accesible e inclusivo para artistas, diseñadores, educadores, principiantes y cualquier otra persona! p5.js es gratuito y de código abierto porque creemos que el software y las herramientas para aprenderlo deben ser accesibles para todos.</p>
            +      <p>Usando la metáfora de bosquejear, p5.js tiene un conjunto completo de funcionalidades para dibujar. Sin embargo, no estás limitado solo a dibujar en tu lienzo. Puedes tomar toda la página del navegador como tu bosquejo, incluyendo los objetos HTML5 para texto, entrada, video, cámara web y sonido.</p>
            +      <p><a href="https://discord.gg/SHQ8dH25r9">Join the p5.js Discord!</a></p>
            +      <a href="https://editor.p5js.org"><span class='button_box'>¡Empieza a crear con el Editor de p5!</span></a>
            +
            +      <h2>Comunidad</h2>
            +      <p>Somos una comunidad de, y en solidaridad con, personas de todas las identidades y expresiones de género, orientación sexual, raza, etnia, idioma, tipo neurológico, tamaño, competencia, clase, religión, cultura, subcultura, opinión política, edad, nivel de habilidad, ocupación y antecedentes. Sabemos que no todas las personas tienen el tiempo, los medios financieros o la capacidad para participar activamente, pero reconocemos y alentamos cualquier tipo participación. Facilitamos y fomentamos el acceso y el empoderamiento. Todos estamos aprendiendo.</p>
            +      <p>p5.js es una interpretación <a href="https://processing.org"
            +          target="_blank">Processing</a> para la web. Realizamos eventos y operamos con el apoyo de <a href="https://processingfoundation.org"
            +          target="_blank">Processing Foundation</a>.</p>
            +      <p>Conoce más sobre <a href="community/">nuestra comunidad</a>.</p>
            +
            +      <h2>Empezar</h2>
            +      <p>Crea tu primer bosquejo en el <a href="https://editor.p5js.org" target="_blank">p5.js
            +          Editor</a>. Aprende más sobre cómo dibujar con p5.js en la <a
            +          href="get-started/">página de empezar</a> y sobre todo lo que puedes hacer en la <a
            +          href="reference/">referencia</a>.</p>
            +
            +      <h2>Participa</h2>
            +      <p>Existen muchas formas de contribuir a p5.js:</p>
            +      <h2 id="involvement-options" class="sr-only">Opciones para participar</h2>
            +      <ul aria-labelledby="involvement-options" class="list_view bullets">
            +        <li><a href="/es/teach">Imparte un taller o una clase.</a></li>
            +        <li><a href="https://day.processing.org" target="_blank">Organiza una reunión.</a></li>
            +        <li><a href="https://github.com/processing/p5.js/tree/main/contributor_docs"
            +            target="_blank">Contribuye al código fuente.</a></li>
            +      </ul>
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +  </div> <!-- end column-span -->
            +
            +
            +  <p class="clearfix">&nbsp;</p>
            +
            +  <object tabindex=-1 type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element"
            +    aria-hidden="true">*</object>
            +</div> <!-- end home-page -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/basics.html b/dist/es/learn/basics.html
            new file mode 100644
            index 0000000000..3d364e5f4e
            --- /dev/null
            +++ b/dist/es/learn/basics.html
            @@ -0,0 +1,348 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +<style>
            +img {
            +  width: 50%;
            +}
            +</style>
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Basics of Drawing</h1>
            +
            +      <h2>Introduction</h2>
            +      <p>
            +      Today we are going to be learning how to write computer code using a tool called <a href='http://p5js.org' target=_blank>p5</a>. Code is a set of instructions for the computer, telling it something to do. In our case, we will tell it to make a scene with shapes and colors.
            +      </p>
            +
            +
            +      <h2>First Sketch</h2>
            +      <p>
            +      When you open p5, your first sketch will look like this. There are two parts: setup and draw. Inside the curly brackets after setup and draw we will add code to create a drawing.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +
            +}
            +      </script>
            +
            +      <h2>background(red, green, blue)</h2>
            +      <p>
            +      background() sets the background color of your drawing. You give it three numbers that represent the amount of red, green, and blue you want mixed into the background. The numbers range from 0-255.
            +      <span class='try'>Try changing the numbers inside the parentheses to see what happens.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +
            +      <h2>createCanvas(width, height)</h2>
            +      <p>
            +      createCanvas() sets the size of the drawing canvas. By default it is 100x100. You give it two numbers that represent the width and the height that you want your canvas to be.
            +      <span class='try'>Try making your canvas different sizes by changing the width and height.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100)
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +      <h2>line(x1, y1, x2, y2)</h2>
            +      <p>
            +      line() draws a line on your canvas. You give it four numbers – the x and y position of one end, and the x and y position of the other end.<br>
            +      <img src='../../assets/learn/basics/line.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 200, 255)
            +  line(10, 10, 200, 200)
            +}
            +      </script>
            +
            +      <h2>rect(x, y, width, height)</h2>
            +      <p>
            +      rect() draws a rectangle on your canvas. You give it four numbers – the x position, the y position, the width, and the height. For a rectangle, you give it the x,y position of the top left corner.<br>
            +      <img src='../../assets/learn/basics/rect.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(55, 100, 255)
            +  rect(10, 10, 50, 200)
            +}
            +      </script>
            +
            +      <h2>ellipse(x, y, width, height)</h2>
            +      <p>
            +      To draw a shape, think of your canvas like a piece of graph paper. However, square (0, 0) is in the top left.
            +      <br>
            +      <img src='../../assets/learn/basics/graph.svg'>
            +      ellipse() draws an ellipse on your canvas. You give it four numbers – the x position, the y position, the width, and the height.<br>
            +      <img src='../../assets/learn/basics/ellipse.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 0, 255)
            +  ellipse(150, 150, 100, 200)
            +}
            +      </script>
            +
            +      <h2>fill(red, green, blue)</h2>
            +      <p>You can set the color of your shapes by using fill(). You give it three numbers – the red, green, and blue mixture you want, just like background.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>stroke(red, green, blue)</h2>
            +      <p>You can set the outline color of your shapes by using stroke(). You give it three numbers – the red, green, and blue mixture you want, just like fill() and background().
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  stroke(0, 150, 0)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>strokeWeight(weight)</h2>
            +      <p>You can set the thickness of the outline for your shapes by using strokeWeight(). The default stroke weight is 1.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  strokeWeight(10)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>mouseX, mouseY</h2>
            +      <p>mouseX and mouseY can be used to get the current position of your mouse. They are called <b>variables</b>. You can replace a number in your code with mouseX or mouseY and that number will change as you move your mouse.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +      <h2>random(max)</h2>
            +      <p>random() will choose a random number for you, anywhere from 0 - max.</p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(random(255), random(255), random(255))
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +
            +      <h2>Links</h2>
            +      <p><a href='http://p5js.org/reference' target=_blank>Reference</a> – available p5.js variables and functions<br>
            +      <a href='http://p5js.org/examples' target=_blank>Examples</a> – more complicated code examples</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/color.html b/dist/es/learn/color.html
            new file mode 100644
            index 0000000000..ab6793dcbb
            --- /dev/null
            +++ b/dist/es/learn/color.html
            @@ -0,0 +1,295 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">Este tutorial proviene del libro Learning Processing de Daniel Shiffman, publicado por Morgan Kaufmann, © 2008 Elsevier Inc. Todos los derechos reservados. Fue transcrito a p5 por Kelly Chang. Si detectas algún error o tienes comentarios, <a href="https://github.com/processing/p5.js/issues"> por favor escríbenos.</a>
            +
            +      </div>
            +
            +      <h1>Color</h1>
            +
            +      <p>
            +      En el mundo digital hablar de color requiere precisión. No basta con decir, por ejemplo: ¿Puedes hacer un círculo verde azulado?, ya que el color se define como un arreglo de números. Comencemos con el caso más simple: negro, blanco y escala de grises. 0 significa negro, 255 significa blanco. Entre medio, cualquier otro número -50, 87, 162, 209, etc- es un tono gris que va entre negro y blanco.
            +      </p>
            +
            +      <img src="../../assets/learn/color/grayscale.svg">
            +
            +      <p>
            +      Al agregar las funciones <a href="/es/reference/#/p5/stroke"> stroke()</a> y <a href="/es/reference/#/p5/fill">fill()</a> antes de dibujar podemos definir el color de cualquier forma deseada. También existe la función <a href="/es/reference/#/p5/background">background()</a>, que define el color del lienzo en nuestra pantalla. A continuación hay un ejemplo.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        background(255);    // Define el color del lienzo como blanco 
            + stroke(0);          // Define el contorno de la forma (stroke) como negro 
            + fill(150);          // Define el interior de la forma (fill) como gris 
            + rect(50,50,75,100); // Dibuja un rectángulo
            +      </code></pre>
            +
            +      <p>
            +      Tanto el contorno como el interior de la forma pueden ser eliminados con las funciones: <a href="/es/reference/#/p5/noStroke">noStroke()</a> y <a href="/es/reference/#/p5/noFill">noFill()</a>. Instintivamente podríamos pensar en utilizar "stroke(0)" para eliminar el contorno, sin embargo, es importante recordar que 0 no significa "nada", sino que indica un color negro. Además, recuerda no eliminar ambos, con <b>noStroke()</b> y <b>noFill()</b>, porque ¡nada aparecerá!
            +      </p>
            +
            +      <p>Adicionalmente si dibujamos dos figuras, p5.js siempre utilizará la última especificación de contorno y llenado, leyendo el código de arriba a abajo.</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +  background(150);
            +  stroke(0);
            +  line(0, 0, 100, 100);
            +  stroke(255);
            +  noFill();
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <h2>Color RGB</h2>
            +
            +      <p>
            +      ¿Alguna vez pintaste con las manos? Al mezclar los colores "primarios" podías generar cualquier otro color. Mezclar todos los colores resultaba en un color café fango, y mientras más pintura añadías más oscuro era el resultado. En el mundo digital los colores también se construyen mezclando los tres colores primarios, pero funciona un poco diferente. Primero, los tres colores primarios son otros: rojo, verde y azul (en inglés red, green and blue, es decir, "RGB"). Luego, con los colores en tu pantalla estás mezclando luz, no pintura, por lo que las reglas de esta mezcla también son otras.
            +      </p>
            +
            +      <img src="../../assets/learn/color/rgb.jpg">
            +      <p>
            +        <ul class="list_view">
            +          <li>Rojo + Verde = Amarillo</li>
            +          <li>Rojo + Azul = Púrpura</li>
            +          <li>Verde + Azul = Cian (azul-verde)</li>
            +          <li>Rojo + Verde + Azul = Blanco</li>
            +          <li>Ausencia de colores = Negro</li>
            +        </ul>
            +      </p>
            +
            +      <p>Lo anterior presupone que los colores son tan brillantes como sea posible, pero por supuesto, hay un rango de color disponible, por lo que un poco de rojo más un poco de verde y azul genera gris, mientras que un poco de rojo más un poco de azul genera púrpura oscuro. 
            + Si bien puede tomar tiempo acostumbrarte a esto, mientras más programes y experimentes con color RGB, más rápido se hará instintivo, como mezclar pintura con los dedos. 
            + Y por supuesto no puedes decir "Mezcla un poco de de rojo con un poco de azul", debes proveer una cantidad. Así como en la escala de grises, los elementos de color son expresados en rangos desde 0 (ausencia del color) hasta 255 (presencia máxima del color), y son listados en orden R (rojo), G (verde) y B (azul). Obtendrás el resultado de mezclar color RGB por experimentación, pero en adelante cubriremos mediante ejercicios colores más comunes.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  noStroke();
            +
            +  // Bright red
            +  fill(255,0,0);
            +  ellipse(20,20,16,16);
            +
            +  // Dark red
            +  fill(127,0,0);
            +  ellipse(40,20,16,16);
            +
            +  // Pink (pale red)
            +  fill(255,200,200);
            +  ellipse(60,20,16,16);
            +}
            +      </script>
            +
            +
            +
            +      <h2>Transparencia</h2>
            +
            +      <p>Además de los componentes rojo, verde y azul de cada color, existe un cuarto componente opcional denominado "alfa" (alpha, en inglés). Alfa significa transparencia y es particularmente útil cuando deseas dibujar figuras que se superponen y a través de las cuales quieres ver. Los valores de alfa de una imagen son llamados también "canal alfa" de una imagen.</p>
            +      <p>Es importante notar que los pixeles no son literalmente transparentes, esto es simplemente una ilusión lograda al mezclar colores. Tras bambalinas p5.js toma los valores de cada color y les asigna un porcentaje, creando una percepción óptica de la mezcla (Si estás interesado en programar vidrios "color rosa", aquí es donde debes comenzar).</p>
            +
            +      <p>Los valores de alfa también se definen en un rango de 0 a 255, donde 0 es completamente transparente (es decir, 0% de opacidad) y 255 es completamente opaco (es decir, 100% opaco).</p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +  createCanvas(100, 100);
            +  fill(0,0,255);
            +  rect(0,0,50,100);
            +
            +  // 255 means 100% opacity.
            +  fill(255,0,0,255);
            +  rect(0,0,100,20);
            +
            +  // 75% opacity.
            +  fill(255,0,0,191);
            +  rect(0,25,100,20);
            +
            +  // 55% opacity.
            +  fill(255,0,0,127);
            +  rect(0,50,100,20);
            +
            +  // 25% opacity.
            +  fill(255,0,0,63);
            +  rect(0,75,100,20);
            +
            +      </script>
            +
            +      <h2>Rangos de Color Personalizados</h2>
            +
            +      <p>
            +      El modo RGB con rangos de 0 a 255 no es la única forma en que podemos manipular color en p5.js, de hecho p5.js nos permite pensar el color de la manera que deseemos. Por ejemplo, tu podrías preferir pensar el color en rangos de 0 a 100 (como un porcentaje). Esto lo puedes hacer especificando un modo específico de color con la función <a href="/es/reference/#/p5/colorMode">colorMode()</a>.
            +      </p>
            +
            +      <pre><code>
            +      colorMode(RGB,100);
            +      </code></pre>
            +
            +      <p>La expresión anterior dice: "Ok, queremos pensar el color en términos de rojo, verde y azul, o RGB, en que el rango de cada color pueda estar entre 0  100."</p>
            +
            +      <p>Aunque rara vez sea conveniente, tu también puedes definir distintos rangos para cada componente de color:</p>
            +
            +      <pre><code>
            +      colorMode(RGB,100,500,10,255);
            +      </code></pre>
            +
            +      <p>Con la expresión anterior queremos decir: "Rango valores en color rojo va de 0 a 100, verde de 0 a 500, azul de 0 a 10 y alfa de 0 a 255."</p>
            +
            +      <p>Finalmente, si bien es probable que tu código requiera sólamente el modo de color RGB, también puedes especificar colores en el modo HSB (tono, saturación y brillo). Sin entrar mayormente en detalle, el color HSB funciona como sigue:</p>
            +
            +      <img src="../../assets/learn/color/hsb.png">
            +      <ul class="list_view">
            +        <li><b>Tono o Matiz</b>—El tipo de color, valores por definición van de 0 a 360.</li>
            +        <li><b>Saturación</b>—La vivacidad del color, 0 a 100 por definición.</li>
            +        <li><b>Brillo</b>—Es el brillo del color, 0 a 100 por definición.</li>
            +      </ul>
            +
            +      <p>Con <a href="/es/reference/#/p5/colorMode">colorMode()</a> puedes definir tu propio rango de valores. Algunos prefieren un rango de 0-360 para el tono (piensa en los 360 grados de la rueda de color) y 0-100 para la saturación y brillo (piensa en 0-100%).</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/coordinate-system-and-shapes.html b/dist/es/learn/coordinate-system-and-shapes.html
            new file mode 100644
            index 0000000000..fb264cb33a
            --- /dev/null
            +++ b/dist/es/learn/coordinate-system-and-shapes.html
            @@ -0,0 +1,279 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      Este tutorial proviene del libro <em>Learning Processing</em> de Daniel Shiffman, publicado por Morgan Kaufmann, © 2008 Elsevier Inc. Todos los derechos reservados. Fue transcrito a p5.js por Alex Yixuan Xu. Si detectas algún error o tienes comentarios, por favor <a href="https://github.com/processing/processing-docs/issues?state=open">escríbenos</a>.</div>
            +
            +      <h1>Sistema Coordenado y Figuras</h1>
            +      <p>Antes de comenzar a programar con p5.js debemos primero remontarnos a nuestra infancia, tomar un trozo de papel y dibujar una línea. La distancia más corta entre dos puntos es una línea y ese es nuestro punto de partida, con dos puntos en un gráfico.</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-01.png" alt="">
            +
            +      <p>La figura anterior muestra una línea que une un punto A (1,0) y un punto B (4,5). Si le hubieras pedido a un amigo que dibujara la línea por ti, tendrías que haberle dado las indicaciones "traza una línea desde el punto uno coma cero hasta el punto cuatro coma cinco, por favor". Bueno, por el momento imagina que tu amigo era un computador al que solicitaste dibujar la misma línea en su pantalla. El mismo comando aplica (solo que en esta caso puedes obviar formalidades y deberás utilizar un formato preciso). Aquí la instrucción es como sigue:</p>
            +
            +      <pre><code class="language-javascript">
            +        line(1,0,4,5);
            +      </code></pre>
            +
            +      <p>Aun sin haber estudiado la sintaxis, la expresión anterior debiera haberte hecho sentido. Estamos entregando a la máquina un comando llamado "línea" (al que nos referiremos como "función") para ser ejecutado. Adicionalmente estamos espcificando argumentos que indican cómo la línea debería ser dibujada, desde un punto A (1,0) hasta un punto B (4,5). Si pensamos una línea de código como una frase, la función es un verbo y los argumentos son los objetos de la frase. La frase de código termina con un punto y coma en vez de un punto final.</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-02.png" alt="">
            +
            +      <p>La clave aquí es darse cuenta que la pantalla del computador es la abstracción de un trozo de papel. Cada pixel de la pantalla es una coordenada -dos números, "x" (horizontal) e "y" (vertical)- que determinan la ubicación de un punto en el espacio. Y es nuestro trabajo especificar qué figuras y colores debieran apareceren en dicha coordenada de pixeles.</p>
            +
            +      <p>Sin embargo hay una trampa. El gráfico que nos enseñaron cuando chicos ("Sistema Coordenado Cartesiano") ubicaba el punto (0,0) en el centro con el "eje y" apuntando hacia arriba, y el "eje x" apuntando hacia la derecho (hacia los números positivos, los negativos hacia la izquierda y abajo). El sistema coordenado para pixeles en una pantalla de computador, en cambio, está invertido en el eje y. (0,0) se ubica en la parte superior izquierda con la dirección positiva apuntando horizontalmente hacia la derecha y abajo.</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-03.svg" alt="">
            +
            +      <h2>Formas Primitivas</h2>
            +      <p>La mayoría de los ejemplos en p5.js son de naturaleza visual. Ellos implican principalmente dibujar figuras y definir coordenadas de pixeles. Comencemos observando las cuatro formas primitivas.</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-04.png" alt="">
            +
            +      <p>Para cada figura nos debemos preguntar qué información requerimos para especificar su ubicación y tamaño (y luego su color) y entender cómo p5.js espera recibir dicha información. En cada uno de los siguientes diagramas asumiremos una ventana de 100 pixeles de ancho y 100 pixeles de alto.</p>
            +
            +      <p>Un <a href="/reference/#/p5/point">point()</a> es la forma más simple y un buen lugar para comenzar. Para dibujar un punto solo necesitamos un par ordenado (x,y).</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  point(40, 50); // point(x, y)
            +}
            +</script>
            +
            +      <p>Una <a href="/reference/#/p5/line">line()</a> tampoco es terriblemente compleja y solo requiere dos puntos: (x1,y1) y (x2,y2):</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  line(10, 20, 50, 20); // line(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>Una vez que llegamos a dibujar un <a href="/reference/#/p5/rect">rect()</a>, las cosas se tornan un poco más complejas. En p5.js un rectángulo se especifica con las coordenadas de su esquina superior izquierda, así como ancho y alto.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  rect(10, 20, 40, 30); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>Una segunda manera de dibujar un rectángulo requiere especificar su punto central junto con su ancho y alto. Si preferimos este método, debemos indicar previamente que queremos utilizar el modo <a href="/reference/#/p5/CENTER">CENTER</a> antes de la instrucción del propio rectángulo. Notemos que p5.js es sensible a cada caso.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(30, 20, 40, 20); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>Finalmente podemos dibujar un rectángulo con dos puntos (la esquina superior izquierda y la esquina superior derecha). El modo en este caso es <a href="/reference/#/p5/CORNERS">CORNERS</a>. Notar que este ejemplo entrega el mismo resultado en pantalla que el ejemplo anterior.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CORNERS);
            +}
            +function draw(){
            +  rect(10, 10, 50, 30); // rect(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>Una vez que nos hemos familiarizado con el concepto de dibujar un rectángulo, una <a href="/reference/#/p5/ellipse">ellipse()</a> es muy sencilla de dibujar. De hecho es idéntica al <a href="/reference/#/p5/rect">rect()</a> con la diferencia de que la elipse se dibuja donde la caja que contiene al rectángulo debiera estar. El modo por defecto para la <a href="/reference/#/p5/ellipse">ellipse()</a> es <a href="/reference/#/p5/CENTER">CENTER</a>, en vez de <a href="/reference/#/p5/CORNER">CORNER</a>.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CENTER);
            +}
            +function draw(){
            +  ellipse(30, 30, 40, 60); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNER);
            +}
            +function draw(){
            +  ellipse(10, 10, 30, 50); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNERS);
            +}
            +function draw(){
            +  ellipse(10, 10, 40, 50); // ellipse(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>Ahora observemos una aplicación un poco más realista, con una pantalla de dimensiones 200 por 200. Notemos el uso de la función createCanvas() para especificar el tamaño de la ventana.</p>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(200, 200);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(100,100,20,100);
            +  ellipse(100,70,60,60);
            +  ellipse(81,70,16,32);
            +  ellipse(119,70,16,32);
            +  line(90,150,80,160);
            +  line(110,150,120,160);
            +}
            +</script>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/curves.html b/dist/es/learn/curves.html
            new file mode 100644
            index 0000000000..172d07697b
            --- /dev/null
            +++ b/dist/es/learn/curves.html
            @@ -0,0 +1,328 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by J David Eisenberg and ported by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +      This work is licensed under a <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"> Creative Commons Attribution-NonCommercial-ShareAlinke 4.0 International License.</a>
            +
            +      </div>
            +
            +      <h1>Curves</h1>
            +
            +      <p>
            +      This short tutorial introduces you to the three types of curves in p5.js: arcs, spline curves, and Bézier curves.
            +      </p>
            +
            +      <h2> Arcs </h2>
            +
            +      <p>
            +      Arcs are the simplest curves to draw, it is defined an arc as a section of an ellipse. You call the function with these parameters:
            +      </p>
            +
            +      <p>
            +      arc (x, y, w, h, start, stop, [mode])
            +      </p>
            +
            +      <p>
            +      The first four parameters (x,y,w,h) define the boundary box for your arc and the next two (start, stop), are the start and stop angles for the arc. These angles are given in radians
            +      and are measured clockwise with zero degrees pointing east and PI radians equals 180°.
            +      </p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +          createCanvas(150,200);
            +          background(150);
            +          stroke(0);
            +          arc(35, 35, 50, 50, 0, PI / 2.0); // lower quarter circle
            +          arc(105, 35, 50, 50, -PI, 0, CHORD);  // upper half of circle
            +          arc(175, 35, 50, 50, -PI / 6, PI / 6, PIE); // 60 degrees
            +          noFill();
            +          arc(105, 105, 100, 50, PI / 2, 3 * PI / 2, OPEN); // 180 degrees
            +        }
            +      </script>
            +
            +      <h2>Spline Curves</h2>
            +
            +      <p>
            +      Arcs are fine, but they’re plain. The next function, curve(), lets you draw curves that aren’t necessarily part of an arc. This function draws what is technically called a Rom-Catmull Spline.
            +      To draw the curve, you must specify the (x, y) coordinates of the points where the curve starts and ends. You must also specify two control points which determine the direction and amount of curvature.
            +      The first two and last two parameters are the control points of the curve.
            +      A call to curve() uses these parameters:
            +      </p>
            +
            +      <p>
            +      curve (cpx1, cpy1, x1, y1, x2, y2, cpx2, cpy2);
            +      </p>
            +
            +      <p>
            +      How do the control points affect the way the curve looks?
            +      </p>
            +
            +      <p>
            +        The tangent to the curve at the start point is parallel to the line between control point one and the end of the curve. The tangent to the curve at the end point is parallel to the line between the start point and control point 2.
            +      </p>
            +
            +      <p>
            +      The following diagram shows a curve and the points can be dragged to show how the control point affects the curve:
            +      </p>
            +
            +      <!-- iframe for the curve and dragging points -->
            +      <iframe src="../../assets/learn/curves/curve_ex/embed.html" width="350" height="350">
            +      </iframe>
            +
            +
            +      <h2>Continuous Spline Curves</h2>
            +
            +      <p>
            +      In isolation, a single curve() is not particularly appealing. To draw a continuous curve through several points, you are better off using the curveVertex() function.
            +      You can only use this function when you are creating a shape with the beginShape() and endShape() functions.In common usage, people use the first point of the curve
            +      as the first control point and the last point of the curve as the last control point.
            +      </p>
            +
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      let coords = [40, 40, 80, 60, 100, 100, 60, 120, 50, 150];
            +
            +      function setup() {
            +        createCanvas(150, 200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        curveVertex(40,40);
            +        curveVertex(40,40);
            +        curveVertex(80,60);
            +        curveVertex(100,100);
            +        curveVertex(60,120);
            +        curveVertex(50,150);
            +        curveVertex(50,150);
            +        endShape();
            +
            +         for (let i = 0; i < coords.length; i+= 2){
            +          ellipse(coords[i], coords[i+1], 10, 10);
            +         }
            +      }
            +      </script>
            +
            +      <h2>Bézier Curves</h2>
            +
            +      <p>
            +        Though better than arcs, spline curves don’t seem to have those graceful, swooping curves that say “art.” For those, you need to draw Bézier curves with the bezier() function.
            +        As with spline curves, the bezier() function has eight parameters, but the order is different. The first two and last two parameters are the start and end points while middle 
            +        four points are the control points.
            +      </p>
            +
            +      <p> bezier(x1, y1, cpx1, cpy1, cpx2, cpy2, x2, y2); </p>
            +
            +      <!-- iframe of Bezier example -->
            +      <iframe src="../../assets/learn/curves/bezier/embed.html" width="400" height="400">
            +      </iframe>
            +
            +      <p>
            +      While it is difficult to visualize how the control points affect a curve(), it is slightly easier to see how the control points affect Bézier curves.
            +      Imagine two poles and several rubber bands. The poles connect the control points to the endpoints of the curve. A rubber band connects the tops of the poles.
            +      Two more rubber bands connect the midpoints of the poles to the midpoint of the first rubber band. One more rubber band connects their midpoints.
            +      The center of that last rubber band is tied to the curve. This diagram helps to explain, the points can be moved to change the curve.
            +    </p>
            +
            +      <!-- image of bezier with lines -->
            +      <img src="../../assets/learn/curves/bezier_with_lines/bezier_with_lines.png" style="width:150px;">
            +
            +      <h2> Continuous Bézier Curves</h2>
            +
            +      <p>
            +      Just as curveVertex() allows you to make continuous spline curves, bezierVertex() lets you make continuous Bézier curves.
            +      Again, you must be within a beginShape() / endShape() sequence. You must use vertex(startX, startY) to specify the starting anchor point of the curve.
            +      Subsequent points are specified with a call to:
            +      </P>
            +
            +      <p>bezierVertex(cpx1, cpy1, cpx2, cpy2, x, y);</P>
            +
            +      <p>
            +      Here is a continuous Bézier curve, but it doesn’t join smoothly. In order to make two curves A and B smoothly continuous, the last control point of A,
            +      the last point of A, and the first control point of B have to be on a straight line.
            +      </P>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +        createCanvas(150,200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        vertex(30, 70); // first point
            +        bezierVertex(25, 25, 100, 50, 50, 100);
            +        bezierVertex(50, 140, 75, 140, 120, 120); // if first 2 numbers are changed to 20, 130 it becomes continuous
            +        endShape();
            +
            +        ellipse(25, 25, 5, 5);
            +        ellipse(100, 50, 5, 5);
            +        ellipse(50, 140, 5, 5);//change to (20, 130, 5, 5) to reflect control point
            +        ellipse(75, 140, 5, 5);
            +      }
            +      </script>
            +
            +      <h2>Summary</h2>
            +        <p>
            +          <ul class="list_view">
            +            <li>Use arc() when you need a segment of a circle or an ellipse. You can’t make continuous arcs or use them as part of a shape.</li>
            +            <li>Use curve() when you need a small curve between two points. Use curveVertex() to make a continuous series of curves as part of a shape.</li>
            +            <li>Use bezier() when you need long, smooth curves. Use bezierVertex() to make a continuous series of Bézier curves as part of a shape.</li>
            +          </ul>
            +        </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/debugging.html b/dist/es/learn/debugging.html
            new file mode 100644
            index 0000000000..a06f82be67
            --- /dev/null
            +++ b/dist/es/learn/debugging.html
            @@ -0,0 +1,319 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +        This tutorial was made by the Education Working Group, during the p5.js contributor conference at the Frank-Ratchye Studio for Creative Inquiry, Carnegie Mellon University in May of 2015. The contributors to this tutorial include <a href="http://huah.net/jason/">Jason Alderman</a>, <a href="http://tegabrain.com/">Tega Brain</a>, <a href="http://taeyoonchoi.com/">Taeyoon Choi</a> and <a href="http://luisaph.com/">Luisa Pereira</a>.
            +      </div>
            +      <img src="../../assets/learn/debugging/0-0.jpg" alt="" />
            +
            +      <p>
            +        This is a field guide for debugging for everyone—whether you are beginning to code or whether you have been coding for a long time, this guide breaks down the mysterious process of solving problems.
            +      </p>
            +
            +      <h3 class="start-element tutorial-btn" id="introduction">0. Debugging is a Creative Act</h3>
            +      <div class="info">
            +        <p>At all levels, programmers encounter bugs and will often spend more time debugging than actually programming the application. You can expect to spend a lot of time doing this and so it is important to develop good strategies for identifying and working through bugs as you learn to program in p5.js.</p>
            +        <p>
            +          A bug is a gap between what you think your system is doing, and what it is actually doing. <a target="_blank"
            +          href="https://vimeo.com/channels/debugging" >Clay Shirky aptly describes </a>a bug as "the moment when there is both a technical problem with your code as well as a problem with your mental picture of what is happening in your code." </p>
            +          <img src="../../assets/learn/debugging/0-1.jpg" alt="" />
            +        </p>
            +
            +        <p>You think you are telling the computer one thing, but it is doing something else. It may also be crashing or throwing errors. In order to close the gap, you must investigate. </p>
            +        <p>When you are working on a project, you may play many different roles. You are an architect when designing and planning your program, an engineer when you are developing it. Then you will be an explorer, discovering the problems and errors and testing it in all the situations in which it needs to run. You are trying to find out where it might break. Finally, when debugging you are a detective, trying to figure out how and why things broke.</p>
            +        <img class="small" src="../../assets/learn/debugging/0-3.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-4.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-5.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-6.png" alt="" />
            +
            +        <p>So how can you become a good detective and debug your program? Here are the ten steps that can help you become a good code sleuth. </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="Change Perspectives">1. Change Perspectives.</h3>
            +      <div class="info">
            +        <p>Don't panic.</p>
            +        <p>When you encounter a bug that you do not know how to solve, stop, pause and take a deep breath. Stand up, say hi to the dog, take a walk or if it's late go get some sleep. When you are frustrated, tired and upset, you are not in a good frame of mind to learn or solve a  problem.</p>
            +        <p>To find your errors you will need to change perspectives and become the detective. The goal is to find out what the program IS doing, rather than why it's not doing what it's supposed to. We need to get the computer to show us what it's doing.</p>
            +        <p>The clues are in the values of variables and flow of program.</p>
            +        <img class="small_center" src="../../assets/learn/debugging/1-0.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="problem">2. Observe the problem </h3>
            +      <div class="info">
            +        <p>Walk someone through the issue even if they themselves do not know how to program. If no one is around, draft an email explaining what you have done and breaking down what the problem is.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-1.png" alt="" />
            +        <p>You probably won't need to actually send this email as often the act of writing it will help you to locate and identify what you need to do next. Some programmers have even been known to explain their problem to a friendly inanimate object like a rubber ducky.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-2.png" alt="" />
            +        <p>
            +          This is also a good time to add comments to your code that tell you exactly what each of your functions is doing.
            +          Some coders also print out their code (or a section of it) and go through it line by line, tracing the path of variables and making notes.
            +        </p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-3.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="start">3. Before you start... </h3>
            +      <div class="info">
            +        <p>Before doing anything,  save a copy of your code that you can go back to.  While debugging you are likely to introduce other problems, break things or accidentally delete good work.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/3-1.png" alt="" />
            +        <p>You don't want to make bigger bugs in the process of debugging.</p>
            +        <img class="small_center" src="../../assets/learn/debugging/3-2.png" alt="" />
            +        <p>If you make a mistake or your problem gets more worse, you can always UNDO or revert back to your saved file.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/3-3.jpg" alt="" />
            +        <p>You can try version control such as <a href="http://github.com">GitHub</a>.</p>
            +        <img src="../../assets/learn/debugging/3-4.png" alt="" />
            +        <p>Write a list of what you are trying, so you can keep track of what still needs to be checked. Be  methodical, it will save you a lot of time in the long run.</p>
            +        <p>
            +          Only ever change one thing at a time.
            +          <img class="med_right" src="../../assets/learn/debugging/3-5.jpg" alt="" />
            +          As you debug, you will be turning parts of your code on and off.
            +          Every time you make a change, test your program. If you make multiple changes before testing, you will not know which change has what effect and are likely to break things further.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="basics">4. Check the basics </h3>
            +      <div class="info">
            +        <p>Many bugs end up being very basic mistakes, equivalent to forgetting to plug in the power cord. These mistakes are so obvious they are often invisible. Check the dumb stuff like...</p>
            +        <ul class="list_view">
            +          <li>Are you editing the file that you are actually running (and not, for example, editing the local file, and looking at a different file on the server)?</li>
            +          <li>Are all of your external files where you think they are?</li>
            +          <li>Are your file dependencies correct?</li>
            +          <li>Are there any typos in your paths?</li>
            +          <li>Check your server? etc.</li>
            +        </ul>
            +        <img src="../../assets/learn/debugging/4-1.png" alt="" />
            +        <img src="../../assets/learn/debugging/4-2.png" alt="" />
            +        <img src="../../assets/learn/debugging/4-3.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="blackboxes">5. Black boxes</h3>
            +      <div class="info">
            +        <p>A black box describes any part of your system you do not understand the inner workings of. For example, a library or perhaps a function that you have not written for yourself. Systematically take out each black box one-by-one and run your program. This will help to see if these parts of the program contain the error.</p>
            +        <img class="med_left" src="../../assets/learn/debugging/5-1.jpg" alt="" />
            +        <img class="med_right" src="../../assets/learn/debugging/5-2.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="reporting">6. Add error reporting</h3>
            +      <div class="info">
            +        <p>
            +          <img class="med_right" src="../../assets/learn/debugging/6-1.png" alt="" />
            +          Error reporting is how your program tells you what it is doing.
            +          p5.js comes with some built-in error reporting that will tell you if you have made specific syntax errors.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in your own error reporting using the console.log() function.
            +          <img class="med_right" src="../../assets/learn/debugging/6-2.png" alt="" />
            +          To check your program flow, add in console.log() statements to the parts of your code.
            +          Then when you look at your console you can see the order that things happen and where you encounter problems.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in console.log()s to print out values of variables so that you can see what they are doing.
            +          <img class="med_center" src="../../assets/learn/debugging/6-3.jpg" alt="" />
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="help">7. Search for more help </h3>
            +      <div class="info">
            +        <p>So none of this works? There are many places you can look online to get more help.</p>
            +        <ul class="list_view">
            +          <li>Do a Google search, if you have had this problem chances are many other people will have too.</li>
            +          <li>Search the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> using the p5.js tag.</li>
            +          <li>Search development forums like <a href="http://stackoverflow.com/">Stack Overflow</a>.</li>
            +        </ul>
            +        <p> More general javascript resources:</p>
            +        <ul class="list_view">
            +          <li>First chapter of Bocoup's and Rebecca Murphey's interactive textbook, <a href="http://jqfundamentals.com/chapter/javascript-basics">jQuery Fundamentals</a>.</li>
            +          <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">  Mozilla's JavaScript Guide</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference ">JavaScript Reference </a>(this is really helpful for finding all of the built-in methods for, say a String).</li>
            +        </ul>
            +        <img class="med_center" src="../../assets/learn/debugging/7-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="people">8. Ask people </h3>
            +      <div class="info">
            +        <p>
            +          Still not working?
            +          <img class="med_right" src="../../assets/learn/debugging/8-0.jpg" alt="" />
            +          You can also ask people for help! They might be delighted to help you.
            +        </p>
            +        <p>
            +          Send that email you wrote at the start.<br>
            +          Post to the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> succinctly articulating your problem and what you want to know. <br>
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="prevent">9. Good coding practices and how to prevent bugs!</h3>
            +      <div class="info">
            +        <ul class="list_view">
            +          <li>Do not optimize prematurely. Clear code is more important than high-performing code as you're building your program.</li>
            +          <li>Do not abstract prematurely. You don't need to make functions for things you think you're going to use multiple times...until you actually have to use it more than once.</li>
            +          <li>
            +            Start with pseudocode as comments, then add code underneath each step.<br>
            +            Put console.log()s in your code as you develop (and test frequently—so if something changes, you know what you did since the last time you tested).<br>
            +          </li>
            +        </ul>
            +        <p>ALSO: start with small problems! Do one thing at a time. It's ok to make smaller sketches to test one thing (draw a star! check twitter!) and then voltron them together into a bigger sketch (draw a star that turns red when you have a notification on twitter!)</p>
            +        <img class="med_center" src="../../assets/learn/debugging/9-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="resources">10. More resources </h3>
            +      <div class="info">
            +        <p>
            +          This guide has been inspired by several other fantastic resources on debugging when coding. Some of these are here:
            +        </p>
            +          <ul class="list_view">
            +            <li>Matt Gemmel, <a href="http://mattgemmell.com/what-have-you-tried/">What have you tried?</a></li>
            +            <li>Clay Shirky, <a href="https://vimeo.com/channels/debugging">A brief introduction to debugging</a></li>
            +            <li>Eric Steven Raymond, <a href="http://www.catb.org/esr/faqs/smart-questions.html"> How to ask questions the smart way</a></li>
            +            <li>ITP Residents, <a href="https://docs.google.com/presentation/d/1RXzITwS4otVKnYkuNu2w7CrpYy35WBO2HUlmkSc2p8g/edit?copiedFromTrash#slide=id.g2ffb36b3_0_44">10 Tips for Debugging</a></li>
            +            <li>Rurouni Jones, <a href="http://rurounijones.github.io/blog/2009/03/17/how-to-ask-for-help-on-irc//">How to ask for help on IRC</a></li>
            +          </ul>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/index.html b/dist/es/learn/index.html
            new file mode 100644
            index 0000000000..81a95199e8
            --- /dev/null
            +++ b/dist/es/learn/index.html
            @@ -0,0 +1,490 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>Aprender</h1>
            +
            +      <p>Estos tutoriales proveen una revisión en mayor profundidad o paso a paso sobre temas particulares. Revisa la 
            +        <a href="/es/examples">página de ejemplos
            +        </a> para explorar demostraciones cortas sobre diversos temas de p5.js.
            +      </p>
            +
            +      
            +        <h2 class="tutorial-title">Introducción a p5.js</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="/es/get-started/">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Empezar</h3>
            +                </a>
            +              </div>
            +              <p>¡Bienvenido a p5.js!<br>Esta introducción cubre lo básico de cómo configurar un proyecto con p5.js </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js-overview">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Panorámica de p5.js</h3>
            +                </a>
            +              </div>
            +              <p>Una panorámica de las principales características de p5.js </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Processing-transition">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js y Processing</h3>
            +                </a>
            +              </div>
            +              <p>Las principales diferencias entre ambos, y cómo convertir de uno a otro. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Local-server">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Usando un servidor local</h3>
            +                </a>
            +              </div>
            +              <p>Cómo configurar un servidor local en Mac OS X, Windows o Linux. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js wiki</h3>
            +                </a>
            +              </div>
            +              <p>Documentación adicional y tutoriales aportados por la comunidad. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="p5-screen-reader.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5 con un lector de pantalla</h3>
            +                </a>
            +              </div>
            +              <p>Configurando p5 para que pueda ser usado fácilmente con un lector de pantalla. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">Conectando p5.js</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>node.js y socket.io</h3>
            +                </a>
            +              </div>
            +              <p>Uso de un servidor node.js con p5.js y comunicación vía socket.io. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">Tópicos de programación</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Beyond-the-canvas">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Más allá del lienzo</h3>
            +                </a>
            +              </div>
            +              <p>Creación y manipulación de elementos en la página, más allá del lienzo. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>3D/WebGL</h3>
            +                </a>
            +              </div>
            +              <p>Desarrollo de aplicaciones con gráficas avanzadas en p5.js usando el modo WEBGL. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="color.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Color</h3>
            +                </a>
            +              </div>
            +              <p>Una introducción al color digital. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="coordinate-system-and-shapes.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Sistema de Coordenadas y Figuras</h3>
            +                </a>
            +              </div>
            +              <p>Dibuja figuras simples utilizando el sistema de coordenadas. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="curves.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Curvas</h3>
            +                </a>
            +              </div>
            +              <p>Una introducción a los tres tipos de curvas en p5.js: arcos, curvas spline y curvas Bézier. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="interactivity.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Interactividad</h3>
            +                </a>
            +              </div>
            +              <p>Introducción a interactividad con el ratón y el teclado. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="program-flow.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Flujo de programa</h3>
            +                </a>
            +              </div>
            +              <p>Introducción al control del flujo de programa en p5.js. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">Cómo programar mejor</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="debugging.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Depurar</h3>
            +                </a>
            +              </div>
            +              <p>Guía de cómo depurar tu código para todo público. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Optimizar código para mejor rendimiento</h3>
            +                </a>
            +              </div>
            +              <p>Un tutorial de consejos y trucos para optimizar tu código para que corra más rápida y fluidamente. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tdd.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Unit testing y desarrollo según pruebas</h3>
            +                </a>
            +              </div>
            +              <p>Sálvate de la agonía al instalar. ¿Qué es unit testing y cómo usarlo? Por Andy Timmons. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">Contribuir a la comunidad</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Desarrollo</h3>
            +                </a>
            +              </div>
            +              <p>Introducción y panorámica general sobre cómo contribuir al desarrollo. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://www.luisapereira.net/teaching/materials/processing-foundation">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Adentro de p5</h3>
            +                </a>
            +              </div>
            +              <p>Una introducción a la estructura de archivos y herramientas para el desarrollo con p5.js, por Luisa Pereira. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tutorial-guide.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Escribir un tutorial</h3>
            +                </a>
            +              </div>
            +              <p>Una guía sobre cómo crear un tutorial de programación en p5.js. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Crear bibliotecas</h3>
            +                </a>
            +              </div>
            +              <p>Creando bibliotecas adicionales para p5.js. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/interactivity.html b/dist/es/learn/interactivity.html
            new file mode 100644
            index 0000000000..96d4b41c92
            --- /dev/null
            +++ b/dist/es/learn/interactivity.html
            @@ -0,0 +1,959 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This is based on the Interactivity chapter from the second edition of<em>
            +      <a href="https://processing.org/handbook/">Processing: A Programming Handbook for Visual Designers and Artists</a></em>, published by MIT Press. Copyright 2013 MIT Press. This tutorial was originally written for Processing version 2.0+ but has been ported and updated here for P5 by Alex Yixuan Xu. If you see any errors or have comments, please
            +      <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Interactivity</h1>
            +
            +      <p>The screen forms a bridge between our bodies and the realm of circuits and electricity inside computers. We control elements on screen through a variety of devices such as touch pads, trackballs, and joysticks, but the keyboard and mouse remain the most common input devices for desktop computers. The computer mouse dates back to the late 1960s, when Douglas Engelbart presented the device as an element of the oN-Line System (NLS), one of the first computer systems with a video display. The mouse concept was further developed at the Xerox Palo Alto Research Center (PARC), but its introduction with the Apple Macintosh in 1984 was the catalyst for its current ubiquity. The design of the mouse has gone through many revisions in the last forty years, but its function has remained the same. In Engelbart's original patent application in 1970 he referred to the mouse as an "X-Y position indicator," and this still accurately, but dryly, defines its contemporary use.</p>
            +
            +      <p>The physical mouse object is used to control the position of the cursor on screen and to select interface elements. The cursor position is read by computer programs as two numbers, the x-coordinate and the y-coordinate. These numbers can be used to control attributes of elements on screen. If these coordinates are collected and analyzed, they can be used to extract higher-level information such as the speed and direction of the mouse. This data can in turn be used for gesture and pattern recognition.</p>
            +
            +      <p>Keyboards are typically used to input characters for composing documents, email, and instant messages, but the keyboard has potential for use beyond its original intent. The migration of the keyboard from typewriter to computer expanded its function to enable launching software, moving through the menus of software applications, and navigating 3D environments in games. When writing your own software, you have the freedom to use the keyboard data any way you wish. For example, basic information such as the speed and rhythm of the fingers can be determined by the rate at which keys are pressed. This information could control the speed of an event or the quality of motion. It's also possible to ignore the characters printed on the keyboard itself and use the location of each key relative to the keyboard grid as a numeric position.</p>
            +
            +      <p>The modern computer keyboard is a direct descendant of the typewriter. The position of the keys on an English-language keyboard is inherited from early typewriters. This layout is called QWERTY because of the order of the top row of letter keys. It was developed for typewriters to put physical distance between frequently typed letter pairs, helping reduce the likelihood of the typebars colliding and jamming as they hit the ribbon. This more than one-hundred-year-old mechanical legacy still affects how we write software today.</p>
            +
            +      <h2>Mouse Data</h2>
            +
            +      <p>The variables <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> (note the capital X and Y) store the x-coordinate and y-coordinate of the cursor relative to the origin in the upper-left corner of the display window. To see the actual values produced while moving the mouse, run this program to print the values to the screen:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text("X: "+mouseX, 0, height/4);
            +  text("Y: "+mouseY, 0, height/2);
            +}
            +      </script>
            +
            +      <p>When a program starts, the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> values are 0. If the cursor moves into the display window, the values are set to the current position of the cursor. If the cursor is at the left, the mouseX value is 0 and the value increases as the cursor moves to the right. If the cursor is at the top, the mouseY value is 0 and the value increases as the cursor moves down. If mouseX and mouseY are used in programs without a <a href="/reference/#/p5/draw"> draw()</a> or if <a href="/reference/#/p5/noLoop">noLoop()</a> is run in <a href="/reference/#/p5/setup">setup()</a>, the values will always be 0.</p>
            +
            +      <p>The mouse position is most commonly used to control the location of visual elements on screen. More interesting relations are created when the visual elements relate differently to the mouse values, rather than simply mimicking the current position. Adding and subtracting values from the mouse position creates relationships that remain constant, while multiplying and dividing these values creates changing visual relationships between the mouse position and the elements on the screen. In the first of the following examples, the circle is directly mapped to the cursor, in the second, numbers are added and subtracted from the cursor position to create offsets, and in the third, multiplication and division are used to scale the offsets.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);    // Top circle
            +  ellipse(mouseX+20, 50, 33, 33); // Middle circle
            +  ellipse(mouseX-20, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);   // Top circle
            +  ellipse(mouseX/2, 50, 33, 33); // Middle circle
            +  ellipse(mouseX*2, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <p>To invert the value of the mouse, subtract the mouseX value from the width of the window and subtract the mouseY value from the height of the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  let x = mouseX;
            +  let y = mouseY;
            +  let ix = width - mouseX;  // Inverse X
            +  let iy = height - mouseY; // Inverse Y
            +  background(126);
            +  fill(255, 150);
            +  ellipse(x, height/2, y, y);
            +  fill(0, 159);
            +  ellipse(ix, height/2, iy, iy);
            +}
            +      </script>
            +
            +      <p>The variables <a href="/reference/#/p5/pmouseX">pmouseX</a> and <a href="/reference/#/p5/pmouseY">pmouseY</a> store the mouse values from the previous frame. If the mouse does not move, the values will be the same, but if the mouse is moving quickly there can be large differences between the values. To see the difference, run the following program and alternate moving the mouse slowly and quickly. Watch the values print to the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text(pmouseX - mouseX, 0, height/4);
            +}
            +      </script>
            +
            +      <p>Draw a line from the previous mouse position to the current position to show the changing position in one frame and reveal the speed and direction of the mouse. When the mouse is not moving, a point is drawn, but quick mouse movements create long lines.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(8);
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, mouseY, pmouseX, pmouseY);
            +}
            +      </script>
            +
            +      <p>Use the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables with an if structure to allow the cursor to select regions of the screen. The following examples demonstrate the cursor making a selection between different areas of the display window. The first divides the screen into halves, and the second divides the screen into thirds.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 50) {
            +    rect(0, 0, 50, 100);  // Left
            +  }
            +  else {
            +    rect(50, 0, 50, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 33) {
            +    rect(0, 0, 33, 100);  // Left
            +  }
            +  else if (mouseX < 66) {
            +    rect(33, 0, 33, 100); // Middle
            +  }
            +  else {
            +    rect(66, 0, 33, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <p>Use the logical operator &amp;&amp; with an if structure to select a rectangular region of the screen. As demonstrated in the following example, when a relational expression is made to test each edge of a rectangle (left, right, top, bottom) and these are concatenated with a logical AND, the entire relational expression is true only when the cursor is inside the rectangle.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX > 40) && (mouseX < 80) && (mouseY > 20) && (mouseY < 80)){
            +    fill(255);
            +  }
            +  else {
            +    fill(0);
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>This code asks, "Is the cursor to the right of the left edge and is the cursor to the left of the right edge and is the cursor beyond the top edge and is the cursor above the bottom?" The code for the next example asks a set of similar questions and combines them with the keyword else to determine which one of the defined areas contains the cursor.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX <= 50) && (mouseY <= 50)) {
            +    rect(0, 0, 50, 50);   // Upper-left
            +  }
            +  else if ((mouseX <= 50) && (mouseY > 50)) {
            +    rect(0, 50, 50, 50);  // Lower-left
            +  }
            +  else if ((mouseX > 50) && (mouseY <= 50)) {
            +    rect(50, 0, 50, 50);  // Upper-right
            +  }
            +  else {
            +    rect(50, 50, 50, 50); // Lower-right
            +  }
            +}
            +      </script>
            +
            +      <h2>Mouse buttons</h2>
            +      <p>Computer mice and other related input devices typically have between one and three buttons; p5 can detect when these buttons are pressed with the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> and <a href="/reference/#/p5/mouseButton">mouseButton</a> variables. Used with the button status, the cursor position enables the mouse to perform different actions. For example, a button press when the mouse is over an icon can select it, so the icon can be moved to a different location on screen. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true if any mouse button is pressed and false if no mouse button is pressed. The variable <a href="/reference/#/p5/mouseButton">mouseButton</a> is LEFT, CENTER, or RIGHT depending on the mouse button most recently pressed. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable reverts to false as soon as the button is released, but the <a href="/reference/#/p5/mouseButton">mouseButton</a> variable retains its value until a different button is pressed. These variables can be used independently or in combination to control the software. Run these programs to see how the software responds to your fingers.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(0);   // Black
            +  }
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseButton == LEFT) {
            +    fill(0);   // Black
            +  }
            +  else if (mouseButton == RIGHT) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(126); // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    if (mouseButton == LEFT) {
            +      fill(0);   // Black
            +    }
            +    else if (mouseButton == RIGHT) {
            +      fill(255); // White
            +    }
            +  }
            +  else {
            +    fill(126);   // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>Not all mice have multiple buttons, and if software is distributed widely, the interaction should not rely on detecting which button is pressed.</p>
            +
            +      <h2>Keyboard data</h2>
            +
            +      <p>p5 registers the most recently pressed key and whether a key is currently pressed. The boolean variable <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> is true if a key is pressed and is false if not. Include this variable in the test of an if structure to allow lines of code to run only if a key is pressed. The <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable remains true while the key is held down and becomes false only when the key is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) {  // If the key is pressed,
            +    line(20, 20, 80, 80);      // draw a line;
            +  }
            +  else {                       // Otherwise,
            +    rect(40, 40, 20, 20);      // draw a rectangle.
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 20;
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) { // If the key is pressed,
            +    x++;                      // add 1 to x.
            +  }
            +  line(x, 20, x-60, 80);
            +}
            +      </script>
            +      <!-- made changes about the key variable not guaranteed to be case sensitive in p5 -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable stores a single alphanumeric character. Specifically, it holds the most recently pressed key. However, it is not guaranteed to be case sensitive. To get the proper capitalization, it is best to use it within <a href="/reference/#/p5/keyTyped">keyTyped()</a>. For non-ASCII keys, use the <a href="/reference/#/p5/keyCode">keyCode</a> variable. The key can be displayed on screen with the <a href="/reference/#/p5/text">text()</a> function (p. 150).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  textSize(60);
            +  fill(255);
            +}
            +function draw() {
            +  background(0);
            +  text(key, 20, 75); // Draw at coordinate (20,75)
            +}
            +      </script>
            +
            +      <!-- no differences in "" and '' in p5, made changes -->
            +      <!-- <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. The single quotes signify A as the data type char (p. 144). The expression key == "A" will cause an error because the double quotes signify the A as a String, and it's not possible to compare a String with a char. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyPressed">keyPressed</a> variable to ascertain that the key pressed is the uppercase A.</p> -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. Note the use of double quotation marks or single quotation marks has no influence on the program as long as you are consistent. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable to ascertain that the key pressed is the uppercase A.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +  stroke(255);
            +}
            +function draw() {
            +  background(0);
            +  // If the 'A' key is pressed, draw a line
            +  if ((keyIsPressed == true) && (key == 'A')) {
            +    line(50, 25, 50, 75);
            +  }
            +  else { // Otherwise, draw an ellipse
            +    ellipse(50, 50, 50, 50);
            +  }
            +}
            +      </script>
            +
            +      <p>The previous example works with an uppercase A, but not if the lowercase letter is pressed. To check for both uppercase and lowercase letters, extend the relational expression with a logical OR, the || relational operator. Line 9 in the previous program would be changed to:</p>
            +      <pre><code class="language-javascript">
            +        if ((keyIsPressed == true) &amp;&amp; ((key == 'a') || (key == 'A'))) {
            +      </code></pre>
            +
            +      <!-- changes made -->
            +      <h2>Coded keys</h2>
            +      <p>Because each character has a numeric value as defined by the <a href="https://www.w3schools.com/charsets/ref_html_ascii.asp">ASCII table</a>, the value of the <a href="/reference/#/p5/keyCode">keyCode</a> variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script>
            +
            +      <!--made changes to original content here -->
            +<!--       <p>Because each character has a numeric value as defined by the ASCII table (p. 605), the value of the key variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +      <h2>Coded keys</h2>
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script> -->
            +
            +      <h2>Events</h2>
            +      <p>A category of functions called events alter the normal flow of a program when an action such as a key press or mouse movement takes place. An event is a polite interruption of the normal flow of a program. Key presses and mouse movements are stored until the end of <a href="/reference/#/p5/draw">draw()</a>, where they can take action that won't disturb drawing that's currently in progress. The code inside an event function is run once each time the corresponding event occurs. For example, if a mouse button is pressed, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function will run once and will not run again until the button is pressed again. This allows data produced by the mouse and keyboard to be read independently from what is happening in the rest of the program.</p>
            +
            +      <h2>Mouse events</h2>
            +      <!-- added mouseClicked() mouseOver() mouseOut() doubleClicked()-->
            +      <p>The mouse event functions are <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, <a href="/reference/#/p5/mouseDragged">mouseDragged()</a>, <a href="/reference/#/p5/mouseOver">mouseOver()</a>, and <a href="/reference/#/p5/mouseOut">mouseOut()</a>:</p>
            +
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block is run one time when the mouse is moved while a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>The <a href="/reference/#/p5/mousePressed">mousePressed()</a> function works differently than the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable. The value of the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true until the mouse button is released. It can therefore be used within <a href="/reference/#/p5/draw">draw()</a> to have a line of code run while the mouse is pressed. In contrast, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function only runs once when a button is pressed. This makes it useful when a mouse click is used to trigger an action, such as clearing the screen. In the following example, the background value becomes lighter each time a mouse button is pressed. Run the example on your computer to see the change in response to your finger.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mousePressed() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>The following example is the same as the one above, but the gray variable is set in the <a href="/reference/#/p5/mouseReleased">mouseReleased()</a> event function, which is called once every time a button is released. This difference can be seen only by running the program and clicking the mouse button. Keep the mouse button pressed for a long time and notice that the background value changes only when the button is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseReleased() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <!-- mouseClicked() example added-->
            +      <p>Similarly, the gray variable is set in the <a href="/reference/#/p5/mouseClicked">mouseClicked()</a> event function, which is called once after a mouse button has been pressed and then released. Browsers handle clicks differently, so this function is only guaranteed to be run when the left mouse button is clicked. To handle other mouse buttons being pressed or released, use <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>. </p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseClicked() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>It is generally not a good idea to draw inside an event function, but it can be done under certain conditions. Before drawing inside these functions, it's important to think about the flow of the program. In this example, squares are drawn inside <a href="/reference/#/p5/mousePressed">mousePressed()</a> and they remain on screen because there is no <a href="/reference/#/p5/background">background()</a> inside <a href="/reference/#/p5/draw">draw()</a>. But if <a href="/reference/#/p5/background">background()</a> is used, visual elements drawn within one of the mouse event functions will appear on screen for only a single frame, or, by default, 1/60th of a second. In fact, you'll notice this example has nothing at all inside <a href="/reference/#/p5/draw">draw()</a>, but it needs to be there to force P5 to keep listening for the events. If a <a href="/reference/#/p5/background">background()</a> function were run inside <a href="/reference/#/p5/draw">draw()</a>, the rectangles would flash onto the screen and disappear.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  fill(0, 102);
            +  background(204); // Draw once to give a little color
            +}
            +function draw() {
            +} // Empty draw() keeps the program running
            +function mousePressed() {
            +  rect(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <p>The code inside the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> and <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> event functions are run when there is a change in the mouse position. The code in the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> block is run at the end of each frame when the mouse moves and no button is pressed. The code in the <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> block does the same when the mouse button is pressed. If the mouse stays in the same position from frame to frame, the code inside these functions does not run. In this example, the gray circle follows the mouse when the button is not pressed, and the black circle follows the mouse when a mouse button is pressed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let dragX, dragY, moveX, moveY;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  fill(0);
            +  ellipse(dragX, dragY, 33, 33); // Black circle
            +  fill(153);
            +  ellipse(moveX, moveY, 33, 33); // Gray circle
            +}
            +function mouseMoved() {   // Move gray circle
            +  moveX = mouseX;
            +  moveY = mouseY;
            +}
            +function mouseDragged() { // Move black circle
            +  dragX = mouseX;
            +  dragY = mouseY;
            +}
            +      </script>
            +
            +      <!-- examples added for mouseOut() and mouseOver() -->
            +      <p>The <a href="/reference/#/p5/mouseOver">.mouseOver()</a> function is called once after every time a mouse moves onto the element. In this example, the diameter of the ellipse increase by 10 every time the mouse moves onto the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOver(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/mouseOut">.mouseOut()</a> function is called once after every time a mouse moves off the element. Similar to the above example, the diameter of the ellipse increase by 10 every time the mouse moves out of the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOut(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <h2>Wheel Events</h2>
            +      <p>The <a href="/reference/#/p5/mouseWheel">.mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners. The function accepts a callback function as argument which will be executed when the wheel event is triggered on the element. The <a href="/reference/#/p5/deltaY">event.deltaY</a> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <a href="/reference/#/p5/deltaX">event.deltaX</a> does the same as <a href="/reference/#/p5/deltaY">event.deltaY</a> except it reads the horizontal wheel scroll of the mouse wheel. On OS X with "natural" scrolling enabled, the <a href="/reference/#/p5/deltaY">event.deltaY</a> values are reversed.</p>
            +      <p>In this example, an event listener is attached to the canvas element, and function changeSize() would run when scrolling is performed on canvas. By using the <a href="/reference/#/p5/deltaY">event.deltaY</a> variable, scrolling up on canvas would increase the diameter of the ellipse and scrolling down would decrease the diameter. If scrolling is performed anywhere in any direction, the background is going to be darker.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseWheel(changeSize); // attach listener for activity on canvas only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with mousewheel movement anywhere on screen
            +function mouseWheel() {
            +  g = g + 10;
            +}
            +
            +// this function fires with mousewheel movement over canvas only
            +function changeSize(event) {
            +  if (event.deltaY > 0) {
            +    d = d + 10;
            +  }
            +  else {
            +    d = d - 10;
            +  }
            +}
            +      </script>
            +
            +      <h2>Key events</h2>
            +      <!-- keyTyped() added -->
            +      <p>Each key press is registered through the keyboard event functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyPressed">keyTyped()</a> and <a href="/reference/#/p5/keyReleased">keyReleased()</a>:</p>
            +      
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block is run one time when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is run one time when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is run one time when any key is released</li>
            +      </ul>
            +
            +      <p>Each time a key is pressed, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block is run once. Within this block, it's possible to test which key has been pressed and to use this value for any purpose. If a key is held down for an extended time, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block might run many times in a rapid succession because most operating systems will take over and repeatedly call the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. The amount of time it takes to start repeating and the rate of repetitions will be different from computer to computer, depending on the keyboard preference settings. In this example, the value of the boolean variable drawT is set from false to true when the T key is pressed; this causes the lines of code to render the rectangles in <a href="/reference/#/p5/draw">draw()</a> to start running.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +      </script>
            +
            +      <!-- added this information to distinguish keyPressed() and keyTyped() -->
            +      <p>When ASCII keys are pressed, the character is stored in the <a href="https://p5js.org/reference/#/p5/key">key </a>variable. However, this variable does not distinguish between uppercase and lowercase when used with the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. For this reason, it is recommended to use <a href="/reference/#/p5/keyTyped">keyTyped()</a>. When used with the <a href="/reference/#/p5/key">key</a> variable this function will recognize case. </p>
            +
            +      <p>Each time a key is released, the code inside the <a href="/reference/#/p5/keyReleased">keyReleased()</a> block is run once. The following example builds on the previous code; each time the key is released the boolean variable drawT is set back to false to stop the shape from displaying within <a href="/reference/#/p5/draw">draw()</a>.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +function keyReleased() {
            +  drawT = false;
            +}
            +      </script>
            +
            +      <h2>Event flow</h2>
            +      <p>As discussed previously, programs written with <a href="/reference/#/p5/draw">draw()</a> display frames to the screen sixty frames each second. The <a href="/reference/#/p5/frameRate">frameRate()</a> function is used to set a limit on the number of frames that will display each second, and the <a href="/reference/#/p5/noLoop">noLoop()</a> function can be used to stop draw() from looping. The additional functions <a href="/reference/#/p5/loop">loop()</a> and <a href="/reference/#/p5/redraw">redraw()</a> provide more options when used in combination with the mouse and keyboard event functions. If a program has been paused with <a href="/reference/#/p5/noLoop">noLoop()</a>, running <a href="/reference/#/p5/loop">loop()</a> resumes its action. Because the event functions are the only elements that continue to run when a program is paused with noLoop(), the loop() function can be used within these events to continue running the code in draw(). The following example runs the draw() function for about two seconds each time a mouse button is pressed and then pauses the program after that time has elapsed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let frame = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  if (frame > 120) {              // If 120 frames since the mouse
            +    noLoop();                     // was pressed, stop the program
            +    background(0);                // and turn the background black.
            +  }
            +  else {                          // Otherwise, set the background
            +    background(204);              // to light gray and draw lines
            +    line(mouseX, 0, mouseX, 100); // at the mouse position
            +    line(0, mouseY, 100, mouseY);
            +    frame++;
            +  }
            +}
            +function mousePressed() {
            +  frame = 0;
            +  loop();
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/redraw">redraw()</a> function runs the code in draw() one time and then halts the execution. It's helpful when the display needn't be updated continuously. The following example runs the code in draw() once each time a mouse button is pressed.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, 0, mouseX, 100);
            +  line(0, mouseY, 100, mouseY);
            +}
            +function mousePressed() {
            +  redraw(); // Run the code in draw one time
            +}
            +      </script>
            +
            +      <!-- event listener and callback functions explained??? -->
            +      <!-- This should probably be explained in a another tutorial more in-depth -->
            + <!--      Functions like mousePressed(), mouseClicked(), mouseReleased(), mouseMoved(), mouseOver(), and mouseOut() can be used as event listeners. They can be attached to certain elements</p>
            +      <p>Function|Boolean: function to be fired when mouse is pressed over the element. if false is passed instead, the previously firing function will no longer fire.</p>
            +      <p>In this example</p>
            +       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +-->
            +      <h2>Cursor icon</h2>
            +      <p>The cursor can be hidden with the <a href="/reference/#/p5/noCursor">noCursor()</a> function and can be set to appear as a different icon or image with the <a href="/reference/#/p5/cursor">cursor()</a> function. When the noCursor() function is run, the cursor icon disappears as it moves into the display window. To give feedback about the location of the cursor within the software, a custom cursor can be drawn and controlled with the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(7);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  ellipse(mouseX, mouseY, 10, 10);
            +}
            +      </script>
            +
            +      <p>If <a href="/reference/#/p5/noCursor">noCursor()</a> is run, the cursor will be hidden while the program is running until the <a href="/reference/#/p5/cursor">cursor()</a> function is run to reveal it.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor();
            +  }
            +  else {
            +    noCursor();
            +  }
            +}
            +      </script>
            +
            +      <p>Add a parameter to the cursor() function to change it to another icon or image. Either load and use image, or use the self-descriptive options are ARROW, CROSS, HAND, MOVE, TEXT, and WAIT.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor(HAND);  // Draw cursor as hand
            +  }
            +  else {
            +    cursor(CROSS); // Draw cursor as cross
            +  }
            +  line(mouseX, 0, mouseX, height);
            +  line(0, mouseY, height, mouseY);
            +}
            +      </script>
            +      <p>These cursor icons are part of your computer's operating system and will appear different on different machines.</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div>
            +  <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/p5-screen-reader.html b/dist/es/learn/p5-screen-reader.html
            new file mode 100644
            index 0000000000..78808f2587
            --- /dev/null
            +++ b/dist/es/learn/p5-screen-reader.html
            @@ -0,0 +1,604 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Using p5 with a screen reader</h1>
            +
            +      <p>
            +        This page introduces some of the screen reader friendly features of the p5js web editor, it provides an overview of accessible outputs, and examples and tutorials on how to get started with p5 when using a screen reader.
            +      </p>
            +      <p>
            +        p5.js is a library that starts with the original goal of Processing –to make to make coding accessible for artists, designers, educators, and beginners– and reinterprets it for the web using the metaphor of a software sketchbook with a set of drawing functionality. With p5.js we are able to draw in the canvas. The canvas is perhaps the most inaccessible element in HTML. The reason for this is simple: the canvas behaves just like a physical canvas, once you put paint on it, it covers up what’s behind it, making it hard to understand how the pixels comprise shapes and elements. Within the p5.js web editor it is possible to access the content of the canvas using a screen reader through text, a spatial table, and sound outputs.
            +      </p>
            +
            +
            +      <h2>What is the p5.js Web Editor</h2>
            +      <p>
            +        The p5.js web editor is a essentially a web page where you can type code in p5.js and run the code to view the output. It allows us to code in and for the browser. The web editor has features that make it screen reader friendly. You can access the <a href="http://editor.p5js.org/">p5 web editor here.</a>
            +      </p>
            +
            +      <h2>Pairings</h2>
            +      <p>
            +        Please note - the p5.accessibility library is currently not supported on MacOS.
            +      </p>
            +      <p>
            +        Using the p5.js web editor with a screen reader works better when you have one of the following screen reader/browser/operating system pairings:
            +      </p>
            +        <ul class="list_view">
            +          <li>NVDA and Firefox</li>
            +          <li>JAWS and Chrome</li>
            +        </ul>
            +
            +      <h2>Outputs</h2>
            +      <p>
            +        With a screen reader we can access the content of the canvas through the following outputs:
            +      </p>
            +
            +      <h3>Plain Text Output</h3>
            +      <p>
            +        This output describes the visual content present on the canvas in plain text.
            +      </p>
            +
            +      <h3>Table Output</h3>
            +      <p>
            +        The table output laids out the content of the canvas in the form of a table based on the spatial location of each element.
            +
            +      </p>
            +
            +      <h3>Sound Output</h3>
            +      <p>
            +        This mode explains the movement of the objects present in the canvas. Top to bottom movement is represented by a decrease in frequency and left to right through panning.
            +      </p>
            +
            +      <h2>How to select an output:</h2>
            +      <p>
            +        In the p5.js web editor there are two ways to select the accessible outputs that we want to make available.
            +      </p>
            +      <ol>
            +        <li>
            +          When we press the “play sketch, button” accessible to screen readers the “plain-text output” will automatically be available.
            +        </li>
            +        <li>
            +          If we want to access other outputs we should do the following:
            +          <ul class="list_view">
            +            <li>
            +              First, stop the sketch by pressing the “stop sketch, button” and go to “Settings”.
            +            </li>
            +            <li>
            +              Within settings we must find the “Accessibility” tab.
            +            </li>
            +            <li>
            +              In the “Accessibility” tab and under the “Accessible text-based canvas” section we can choose our preferred outputs.
            +            </li>
            +          </ul>
            +        </li>
            +      </ol>
            +      <p>
            +        Within “Settings” and under the “Accessibility” tab it is also possible to activate a lint warning sound that should make debugging easier. In “Settings” and under the  “General Settings” tab we can increase the size of the font and select a high contrast theme. After choosing our settings we can close the “Settings” window and go back to coding and playing our sketch.
            +      </p>
            +      <p>
            +        It is possible to add these accessible outputs to p5 sketches outside of the p5.js web editor by including the p5.accessibility.js library. <a  target="_blank" href="https://github.com/processing/p5.accessibility">You can learn more about the library here.</a>
            +      </p>
            +
            +      <h3>Keyboard Shortcuts</h3>
            +      <p>
            +        There are also ways to turn on the accessible outputs using keyboard shortcuts. Once we are on the code editor area we can use the following shortcuts (we have listed the shortcuts  for Windows computers, if you are using Mac OS please use the command key instead of control):
            +      </p>
            +      <ul class="list_view">
            +        <li>
            +          Shift + Control +1 - Turns on ALL the accessible output options, including audio
            +        </li>
            +        <li>
            +          Shift + Control +2 - Turns off ALL the accessible output options
            +        </li>
            +        <li>
            +          Control + Enter - This is used to run a sketch. If you already have accessibility options turned on, they will show up as well
            +        </li>
            +        <li>
            +          Shift + Control + Enter - This is used to stop a sketch.
            +        </li>
            +      </ul>
            +      <p>
            +        The full list of shortcuts is also available in the p5 web editor, under Keyboard Shortcuts in the Help and Feedback section of the menu
            +      </p>
            +
            +      <h1>Lessons</h1>
            +      <h2>Lesson 1: Hello World</h2>
            +      <p>
            +        In this section we go through some basic functions in p5 and look at how the screen reader will read the output.
            +
            +        There are two main functions we will use in our programs. The setup() function runs once, and is typically used for initialization, or for creating a program that does not need a loop running code repeatedly. The draw() function runs over and over again, and is used to perform a certain action repeatedly and for animation.
            +        Now we can open the editor: alpha.p5js.org and look for the code edit area. If you notice, there’s some code there already. Whenever you open the editor by default it will create a setup() function and a draw() function. However, for our first "Hello World" program we will take a step back and delete everything. Once we have a blank editor, we create a setup() block and add one line:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(200,200);
            +        }
            +      </code></pre>
            +
            +    <p>
            +      The createCanvas() function creates a canvas for us  to draw  or display the output. The canvas is the space on which the output is “drawn” or displayed. The code above creates a canvas of width and height 200 pixels. Since there is no movement, we will take a look only at the text and table outputs.
            +    </p>
            +    <h3>Text output for Lesson 1</h3>
            +    <p>
            +      Your output is a 200 by 200 white canvas containing the following 0 object
            +    </p>
            +    <h3>Table output for Lesson 1</h3>
            +    <p>
            +      white canvas is 200 by 200 of area 40000 contains 0 objects
            +    </p>
            +    <p>
            +      As expected, the outputs do not have any details apart from that of the canvas. Now, let’s move on to the next lesson where we add some basic shapes.
            +    </p>
            +
            +      <h2>Lesson 2: Basic Shapes</h2>
            +      <p>
            +        In this example, we will draw an ellipse on the top left, and a rectangle on the bottom right of the canvas of size 500 by 500 pixels. First, let's create the canvas and draw a shape in the setup function. Feel free to copy the code to the editor and run it.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        This code creates a canvas of 500 by 500 pixels and then draws an ellipse. The first 2 numbers we pass to the ellipse indicate where the center of the ellipse will be on the canvas. In this case, that is 50 and 50 pixels. The next 2 numbers indicate the width and height of the ellipse. In this case, they are both 20 pixels, implying we want to draw a circle. It is important to note that the top left corner of the canvas is point 0,0 pixels and the bottom right corner of the canvas is point 500,500 pixels.
            +      </p>
            +      <p>
            +        Now, we can also type this code a bit differently. We can create the canvas in the setup() function and draw the shape in the draw() function.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +        }
            +        function draw() {
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        In the previous case, the ellipse is drawn ONCE in setup and never again. But, in this case, the ellipse is drawn again and again in the canvas. Since, the numbers passed to the ellipse are the same each time, it doesn’t make a difference. However, if we wanted to change it’s position each time and make it move, then we would have to do it in draw.
            +      </p>
            +      <p>
            +        NOTE: remember, that everything in the canvas is drawn one over the other.
            +      </p>
            +      <p>
            +        In this case the output will be following:
            +      </p>
            +
            +      <h3>Text output for Lesson 2</h3>
            +      <p>
            +        The overview for the text output contains “Your output is a 500 by 500 white canvas containing the following 1 object:”.
            +      </p>
            +      <p>
            +        This description is followed by a list of elements where the shape, color, position, and area of each element are described (in this case: “white ellipse at top left covering 0.13% of the canvas” ). Each element can be selected to get more details. A table of elements is also provided. In this table, shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”).
            +      </p>
            +      <h3>Table output for Lesson 2</h3>
            +      <p>
            +        The overview for the table output contains “white canvas is 500 by 500 of area 250000 Contains 1 objects - 1 ellipse”
            +      </p>
            +      <p>
            +        This is followed by a table that describes the content spatially. It is a 10 by 10 table structure where each element is placed on a cell of the table depending on its position. Within each cell an element the color and type of shape of that element are available (example: “white ellipse”). These descriptions can be selected individually to get more details. A list of elements where shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”) is also available.
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rk4uO1bJX">basic shapes example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Lesson 3: Color</h2>
            +      <p>
            +        In these examples, we  look at different ways to add color to our sketch
            +        First, let’s look at ‘background()’. We can use this function to add a background color to the canvas. Copy the below code to try it out.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +      </code></pre>
            +      <p>
            +        Here, we have given the color in RGB format. In this format we can describe colors by saying how much, Red, Green and Blue the color has. RGB values must be integers between 0 and 255 with 0 being no color, and 255 highest amount of a certain color. The outputs will now contain “Red (255,0,0) canvas”.
            +      </p>
            +      <p>
            +        Now we can give color to our shapes using the function, fill().
            +      </p>
            +      <p>
            +        Copy the below code to try it out:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +
            +        function draw() {
            +          fill(200,50,8);
            +          ellipse(50,50,20,20);
            +          fill(20,250,8);
            +          ellipse(250,250,20,20);
            +          fill(20,150,250);
            +          ellipse(450,450,20,20);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now, in the plain text and grid output, we will notice that each shape is prepended with the color of the shape.
            +      </p>
            +
            +      <h3>Text output for Lesson 3</h3>
            +      <p>
            +        In the text output the overview is as follows
            +        “Your output is a 500 by 500 red(255,0,0) canvas containing the following 3 objects”
            +      </p>
            +      <p>
            +        After this we see the list of objects, with their color name and the RGB value. For example -  “crimson(200, 50, 8) ellipse at top left covering 0.13% of the canvas” Each object contains a link that when selected provides more details.
            +      </p>
            +
            +      <h3>Grid output for Lesson 3</h3>
            +      <p>
            +        The overview is as follows “red(255,0,0) canvas is 500 by 500 of area 250000 contains 3 0bjects - 3 ellipse”
            +      </p>
            +      <p>
            +        And in the table, we will find the objects in the grids corresponding to their location. “crimson(200,50,8) ellipse” and “green(20,250,8) ellipse”
            +      </p>
            +
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rJ-OSs-k7">color example on the p5 editor</a>
            +      </p>
            +
            +      <p>
            +        Instead of using Red, Green and Blue values, we can also pass just one value from 0 to 255. This is known as grayscale. It means that Red, Green and Blue will take the same value and the result will be between black and white. 0 being black, and 255 white.
            +      </p>
            +
            +      <h2>Lesson 4: Text</h2>
            +      <p>
            +        With p5, it is also possible to draw text on the canvas!
            +        We can add text to the canvas using the text() function. This function requires us input three values inside the parentheses: the text we want to display written between quotation marks, followed by the x and y position in pixels to display the text in the canvas.
            +      </p>
            +      <p>
            +        Copy and try out the below code.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(200);
            +        }
            +
            +        function draw() {
            +          fill(255,0,0);
            +          text("hello world!", 50,50)
            +        }
            +      </code></pre>
            +      <p>
            +        Note that fill() also affects text() and that the text we want to write has to be written between quotation marks. Now, let’s go through the output to see what it says.
            +      </p>
            +
            +      <h3>Text output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows  :
            +        “Your output is a 500 by 500 grey(200,200,200) canvas containing the following 1 object”
            +      </p>
            +      <p>
            +        Then there is a list of the objects. (For example - “hello world!” (red(255,0,0)) at top left of the canvas
            +      </p>
            +
            +      <h3>Grid output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows:
            +        “grey(200,200,200) canvas is 500 by 500 of area 250000 contains 1 object - 1 text”
            +      </p>
            +      <p>
            +        And in the table you will see the actual text and it’s color in the appropriate location (example - “hello world! (red(255,0,0))”
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/r1BFz3Zkm">text example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Exercise: Bar Graph</h2>
            +      <p>
            +        Now that we have covered how to draw basic shapes and write text on the canvas, let’s look at how we can create a bar chart with them.
            +      </p>
            +      <p>
            +        Using rectangles and some numbers, we can create bar graphs. Since we expect the entire sketch to be static, we can do the whole thing in the setup function
            +      </p>
            +      <p>
            +        Let’s start with a sample dataset that we want to depict.
            +      </p>
            +      <p>Animals in the park:</p>
            +      <ul class="list_view">
            +        <li>Dogs - 260</li>
            +        <li>Cats - 300</li>
            +        <li>Hamsters -100</li>
            +        <li>Rabbits - 50</li>
            +        <li>Spiders - 10</li>
            +      </ul>
            +
            +      <p>
            +        First we create a canvas:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        createCanvas(500,500);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now we can add some rectangles that represent each animal type. Notice that we will be adding comments in our code. Comments are lines in our code that are not executed and can be notes to ourselves. They start with // in the beginning of the line. We will create 5 rectangles, one for each animal type.
            +      </p>
            +
            +      <p>
            +        Remember that when we draw a rectangle, the first 2 values indicate the top left of the rectangle. If we want our bar graph to start on the left of our canvas, we need to calculate the numbers based on that. If we decide to make each bar with 50 pixels height, and to make the width represent the number of animals, for our first rectangle that represents the number of dogs the width would be 260 because there are 260 dogs. Then the values for this rectangle would be (0,0,260,50).
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	//We will use the fill() function to add color to the first bar of our chart.
            +        fill(255,0,0);
            +        //In this case our color is 255 red, 0 green, 0 blue.
            +        	rect(0, 0, 260, 50);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now let’s add the corresponding text:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	//Remember that the function text() requires the text, and the x, and y values for its position
            +        }
            +      </code></pre>
            +      <p>
            +        And voila! We just added the first bar on our graph chart.
            +      </p>
            +
            +      <h3>Text output for Bar Graph 1</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 2 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now lets add rectangles to represent 300 cats, 100 hamsters, 50 rabbits, and 10 spiders. Remember that the values for the function rect() in our case should be: rect(0, y position, number of animals, 50).
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	rect(0, 100, 300, 50); // here the second value, y position, is 100 so that we can draw the second bar under the first bar.
            +        	text('Cats - 300', 0, 175);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        The text output would be:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 2</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(red(255, 0, 0)) at top left</li>
            +      </ul>
            +      <p>
            +        Now we can add different colors to each bar:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	fill(0,255,0);
            +        	rect(0, 100, 300, 50);
            +        	text('Cats - 300', 0, 175);
            +        	fill(0,0,255);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	fill(200,100,0);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	fill(0,200,200);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +      <p>
            +        Our bar graph is ready! Here is the output:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 3</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>green(0, 255, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(green(0, 255, 0)) at top left</li>
            +        <li>blue( 0, 0, 255) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(blue( 0, 0, 255)) at top left</li>
            +        <li>orange(200, 100, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(orange(200, 100, 0)) at top left</li>
            +        <li>cyan( 0, 200, 200) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(cyan( 0, 200, 200)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now that we created a graph together you should be able to do it by yourself and share the results with your friends!
            +      </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/program-flow.html b/dist/es/learn/program-flow.html
            new file mode 100644
            index 0000000000..91d1d795d7
            --- /dev/null
            +++ b/dist/es/learn/program-flow.html
            @@ -0,0 +1,580 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This tutorial is written by Alex Yixuan Xu with reference to <em>Getting Started With p5.js</em> by Lauren McCarthy, Casey Reas, and Ben Fry. Copyright 2016 Maker Media, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">MDN JavaScript documentation</a> and <a href="https://www.w3schools.com/js">W3Schools JavaScript tutorials</a>. If you see any errors or have comments, please <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Program Flow</h1>
            +      <!-- TOPICS -->
            +      <!-- Branching: if/else -->
            +      <!-- Loops: for/while loop -->
            +      <!-- noLoop(), loop() and redraw() -->
            +      <!-- Asynchronicity in p5.js: intro to loadImage(), preload(), callbacks -->
            +      <!-- Loading JSON & APIs -->
            +      <!-- Functions and Callbacks: list of functions -->
            +      <!-- Interactivity and Event Listeners: list of event listeners such as mousePressed() -->
            +
            +
            +
            +      <!-- https://docs.microsoft.com/en-us/scripting/javascript/controlling-program-flow-javascript -->
            +      <p>This tutorial outlines some various techniques for controlling the sequence and timing of events in your code, which is known as program flow.</p>
            +
            +      <!-- if/else stuff -->
            +      <h2>Branching</h2>
            +      <!-- https://www.w3schools.com/js/js_if_else.asp -->
            +      <p>We can use conditional statements to control the program flow. Conditional statements perform different actions based on tests for different conditions. JavaScript has the following conditional statements:</p>
            +      <ul class="list_view">
            +        <li>Use <em>if</em> to specify a block of code to be executed, if a specified condition is true</li>
            +        <li>Use <em>else</em> to specify a block of code to be executed, if the same condition is false</li>
            +        <li>Use <em>else if</em> to specify a new condition to test, if the first condition is false</li>
            +      </ul>
            +      <p>In the following example, change the value for variable i to change the color of the rectangle. If i equals to 0, the condition for the <em>if</em> statement is satisfied, and the filling color is red. In this case, the program continues to draw the rectangle skipping the <em>else if</em> and <em>else</em> statements. If i equals to 1, the condition for the <em>if</em> statement is not satisfied, and the program moves on to check the condition for the <em>else if</em> statement. Since <em>else if</em> condition is satisfied, the filling color is green. If neither the <em>if</em> nor the <em>else if</em> conditions are satisfied, the program runs the <em>else</em> statement, and the filling color is blue.</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0; // change the value of i to see the change
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  background(200);
            +  if (i==0){
            +    fill(255, 0, 0);
            +  }
            +  else if (i==1){
            +    fill(0, 255, 0);
            +  }
            +  else{
            +    fill(0, 0, 255);
            +  }
            +  rect(width/2, height/2, 50, 50);
            +}
            +      </script>
            +
            +      <!-- for loop and while loop -->
            +      <h2>Loops</h2>
            +      <p>Loops can execute a block of code repeatedly. p5 supports several different kinds of loops in JavaScript:</p>
            +      <ul class="list_view">
            +        <li>for - loops through a block of code a specified number of times</li>
            +        <li>for/in - loops through the properties of an object</li>
            +        <li>while - loops through a block of code while a specified condition is true</li>
            +        <li>do/while - also loops through a block of code while a specified condition is true</li>
            +      </ul>
            +
            +      <p>The <em>for</em> loop sets up a variable (usually i or x) that is then incrementally changed for each loop. It has the following structure:</p>
            +      <pre><code class="language-javascript">
            +        for (statement 1; statement 2; statement 3) {
            +            code block to be executed
            +        }
            +      </code></pre>
            +      <ul class="list_view">
            +        <li>Statement 1 is executed (one time) before the execution of the code block. It sets the starting value for the variable</li>
            +        <li>Statement 2 defines the condition that must be true for the code block to be executed.</li>
            +        <li>Statement 3 is executed every time  after the code block has finished running if statement 2 evaluated to be true.</li>
            +      </ul>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  for (let i=0; i<5; i++){
            +    text(i, i*10, height/2);
            +  }
            +}
            +      </script>
            +      <p>In this example, variable i is initially set to 0. Every time the <em>for</em> loop runs, i is displayed on the screen and 1 is added to i. Note the <em>for</em> loop will only run until i equals to 4 because after this the condition that i be less than 5 will be false.</p>
            +
            +      <p>The <em>for/in</em> statement loops through the properties of an object:</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let person = {fname:"John", lname:"Doe", age:25};
            +let myText = "";
            +function setup(){
            +  let x;
            +  for (x in person) {
            +      myText += person[x];
            +      myText += " ";
            +  }
            +  text(myText, 0, height/2);
            +}
            +      </script>
            +      <p>In this example, as the <em>for</em> loop cycles through each property of the person object, the property value is added to myText string.</p>
            +
            +      <p>The while loop cycles through a block of code as long as its specified condition is true.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  while (i<5){
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +}
            +      </script>
            +      <p>This example gives the same result as the <em>for</em> loop example above. Sometimes <em>while</em> loops and <em>for</em> loops can be used interchangeably.</p>
            +
            +      <p>The <em>do/while</em> loop is a variant of the <em>while</em> loop. This loop will execute the code block once, before checking if the condition is true, it will then repeat the loop as long as the condition is true.</p>
            +      <!-- Is there an example particular to do/while? -->
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  do {
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +  while (i < 5);
            +}
            +      </script>
            +
            +
            +      <!-- this is particular to p5 -->
            +      <h2>noLoop(), loop() and redraw()</h2>
            +      <p>The <a href="/reference/#/p5/draw">draw()</a> function in p5 runs as a loop. The code inside the draw() function runs continuously from top to bottom until the program is stopped. The draw() loop may be stopped by calling <a href="/reference/#/p5/noLoop">noLoop()</a>, and can then be resumed with <a href="/reference/#/p5/loop">loop()</a>. If using <a href="/reference/#/p5/noLoop">noLoop()</a> in <a href="/reference/#/p5/setup">setup()</a>, it should be the last line inside the block.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(200);
            +  ellipse(x, height/2, 20, 20);
            +  x ++;
            +}
            +function mousePressed() {
            +  loop();
            +}
            +function mouseReleased() {
            +  noLoop();
            +}
            +        </script>
            +        <p>In this example, <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a>, so the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. Since <a href="/reference/#/p5/loop">loop()</a> is placed in <a href="/reference/#/p5/mousePressed">mousePressed()</a>, the draw() block will resume looping when mouse is pressed. When mouse is released, <a href="/reference/#/p5/noLoop">noLoop()</a> is called again and hence the draw() loop stops.</p>
            +
            +        <p>The function <a href="/reference/#/p5/redraw">redraw()</a> executes the code within <a href="/reference/#/p5/draw">draw()</a> one time. This functions allows the program to update the display window only when necessary, such as when an event registered by <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/keyPressed">keyPressed()</a> occurs. In structuring a program, it only makes sense to call <a href="/reference/#/p5/redraw">redraw()</a> within events such as <a href="/reference/#/p5/mousePressed">mousePressed()</a> outside of the draw() loop. The redraw() function does not work properly when called inside draw(). In addition, you can set the number of loops through draw by adding a single argument (an integer) to the redraw() function.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +   createCanvas(100, 100);
            +   noLoop();
            + }
            +function draw() {
            +   background(200);
            +   ellipse(x, height/2, 20, 20);
            +   x ++;
            + }
            +function mousePressed() {
            +   redraw();
            + }
            +      </script>
            +      <p>This example is similar to the previous one, where <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a> and the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. However, when mouse is pressed, <a href="/reference/#/p5/redraw">redraw()</a> is called and <a href="/reference/#/p5/draw">draw()</a> will only loop once. To make smooth animations, it is easier to work with noLoop() and loop().</p>
            +
            +
            +      <h2>Asynchronicity in p5.js</h2>
            +      <p>In JavaScript, events may occur concurrently with the main program flow. This is considered as asynchronicity in programming. In p5, for example, when we use <a href="/reference/#/p5/loadImage">loadImage()</a> in <a href="/reference/#/p5/setup">setup()</a>, the browser begins the process of loading the image but skip onto the next line before it is finised loading. The following example demonstrates such asynchronicity.</p>
            +        <pre><code class="language-javascript">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +    </code></pre>
            +    <iframe src="/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.html" width="150" height="150"></iframe>
            +      <!-- what's the file location??????????????????? -->
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p>When you run this program, you'll notice that the drawing canvas is grey with no image displayed. This is because <a href="/reference/#/p5/loadImage">loadImage()</a> begins to load the image, but does not have time to finish this task before the program continues on through the rest of <a href="/reference/#/p5/setup">setup()</a> and on to <a href="/reference/#/p5/draw">draw()</a>. Even with the <a href="/reference/#/p5/noLoop">noLoop()</a> function that stops p5.js from continuously executing the code within draw(). The <a href="/reference/#/p5/image">image()</a> function is unable to display the image as it is not properly loaded.</p>
            +
            +      <h2>Introduction to Preload</h2>
            +      <p>To help with this issue of asynchronicity, p5.js has the <a href="/reference/#/p5/preload">preload()</a> function. Unlike <a href="/reference/#/p5/setup">setup()</a>, preload() forces the program to wait until everything has loaded before moving on. It is best to only make load calls in preload(), and do all other setup in setup().</p>
            +      <pre><code class="language-javascript">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.html" width="150" height="150"></iframe>
            +
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p><a href="/reference/#/p5/preload">preload()</a> ensures that the image has been loaded before running the other code. </p>
            +
            +
            +
            +      <h2>Loading with a Callback</h2>
            +      <p>An alternative to <a href="/reference/#/p5/preload">preload()</a> is to use a <em>callback function</em>. A callback function is a function that is passed as an argument to a second function, and that runs after the second function has completed. The following example illustrates this technique.</p>
            +      <pre><code class="language-javascript">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.html" width="150" height="150"></iframe>
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </script> -->
            +      <p>In this example, the second argument in <a href="/reference/#/p5/loadImage">loadImage()</a> is the function we want to run after the load is complete. Once the image has loaded, this callback function, drawImage(), is automatically called. It has one argument which contains the image that was just loaded. There is no need to create a global variable to hold the image. The image is passed directly into the callback function, as the parameter name chosen in the function definition.</p>
            +
            +
            +
            +      <h2>Loading JSON & APIs</h2>
            +      <!-- page 187 -->
            +      <p>The JSON (JavaScript Object Notation) format is a common system for storing data. Like HTML and XML formats, the elements have labels associated with them. One way to load JSON file is to use <a href="/reference/#/p5/loadJSON">loadJSON()</a> function in <a href="/reference/#/p5/preload">preload()</a>.</p>
            +      <!-- example where loadJSON() in preload() -->
            +      <p>The following request at https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson returns data of recent earthquakes in the world from USGS.</p>
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let earthquakes;
            +function preload(){
            +  earthquakes = loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson');
            +}
            +function setup(){
            +  createCanvas(200, 100);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +
            +      <p>Alternatively, <a href="/reference/#/p5/loadJSON">loadJSON()</a> can also take a callback. To use data from an API, you may need a callback function as, like with an image, the data takes time to load. API (Application Programming Interface) requests are commands that request data from a service. A lot of APIs will return data in JSON format. Some need you to authenticate with the API to use it (e.g. register as a developer and get keys). You can’t always use <a href="/reference/#/p5/preload">preload()</a> when getting data from APIs because the data might change while you sketch is running and you will want your program to respond accordingly.</p>
            +
            +      <p><a href="/reference/#/p5/loadJSON">loadJSON()</a> can be used in a few ways: </p>
            +      <ul class="list_view">
            +        <li>loadJSON(path)</li>
            +        <li>loadJSON(path, callback)</li>
            +        <li>loadJSON(path, callback, datatype)</li>
            +        <li>loadJSON(path, callback, errorCallback)</li>
            +        <li>loadJSON(path, datatype, callback, errorCallback)</li>
            +        <li>loadJSON(path, jsonpOptions, datatype, callback, errorCallback)</li>
            +      </ul>
            +      <p>
            +        where:
            +      </p>
            +      <ul class="list_view">
            +        <li>path - String: name of the file or url to load</li>
            +        <li>jsonpOptions - Object: options object for jsonp related settings</li>
            +        <li>datatype - String: "json" or "jsonp"</li>
            +        <li>callback - Function: function to be executed after loadJSON() completes, data is passed in as first argument</li>
            +        <li>errorCallback - Function: function to be executed if there is an error, response is passed in as first argument</li>
            +      </ul>
            +      <!-- example where loadJSON() takes a callback -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(200, 100);
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +      <p>In this example, the <a href="/reference/#/p5/loadJSON">loadJSON()</a> function is placed in <a href="/reference/#/p5/setup">setup()</a> and takes a custom callback function showEarthquake(). This means when the program finishes loading the JSON file from the USGS earthquakes API, the function showEarthQuake() is called. The place and magnitude of the most recent earthquake listed by the API is stored in local variables within showEarthquake and are then displayed on the screen.</p>
            +
            +      <p>Sometimes we use <a href="/reference/#/p5/setInterval">setInterval()</a> to control the frequency of requests made to the API. setInterval() can also take a callback function. If you call setInterval() in <a href="/reference/#/p5/setup">setup()</a>, it will run repeatedly for the duration of the program at the interval set.</p>
            +      <!-- example setInterval() is used -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let i=1; // counter variable to keep track of the interval
            +function setup() {
            +  createCanvas(200, 100);
            +  getEarthquake();
            +  setInterval(getEarthquake, 5000); // get data every 5 seconds
            +}
            +function getEarthquake(){
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  background(255);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text("Data grabbed "+i, 0, height/3);
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +  i++;
            +}
            +      </script>
            +      <p>In this example, the earthquake data is grabbed from the API every 5 seconds and is displayed on the screen.</p>
            +
            +
            +
            +
            +      <!-- list the functions that accept callbacks? Is this section necessary?-->
            +      <h2>More Callback Functions</h2>
            +      <p>In addition to the <a href="/reference/#/p5/loadImage">loadImage()</a>, <a href="/reference/#/p5/loadJSON">loadJSON()</a> and <a href="/reference/#/p5/setInterval">setInterval()</a>, there are other functions in p5 that accept callbacks. Typically, functions that involve loading data of some kind accept callbacks, or should be put in <a href="/reference/#/p5/preload">preload()</a>. For example:</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/loadFont">loadFont()</a></li>
            +        <li><a href="/reference/#/p5/loadSound">loadSound()</a></li>
            +        <li><a href="/reference/#/p5/loadStrings">loadStrings()</a></li>
            +        <li><a href="/reference/#/p5/loadTable">loadTable()</a></li>
            +        <li><a href="/reference/#/p5/loadXML">loadXML()</a></li>
            +        <li><a href="/reference/#/p5/loadBytes">loadBytes()</a></li>
            +        <li><a href="/reference/#/p5/loadModel">loadModel()</a></li>
            +      </ul>
            +
            +      <p>DOM functionality makes it easy to interact with other HTML5 objects, including text, hyperlink, image, input, video, audio, and webcam. Some DOM creation methods also accept callbacks: </p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/createImg">createImg()</a></li>
            +        <li><a href="/reference/#/p5/createFileInput">createFileInput()</a></li>
            +        <li><a href="/reference/#/p5/createVideo">createVideo()</a></li>
            +        <li><a href="/reference/#/p5/createAudio">createAudio()</a></li>
            +        <li><a href="/reference/#/p5/createCapture">createCapture()</a></li>
            +      </ul>
            +
            +
            +      <h2>Interactivity and Event Listeners</h2>
            +      <p>Callback functions are functions that can be passed as an argument into another function and be executed after the first function is complete. An event listener or handler is a type of callback. It is called whenever an event occurs such as when the mouse is pressed, or a key is pressed etc.</p>
            +      <p>Mouse functions like <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, etc. can be used as event listeners. They can be attached to certain elements in a sketch.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseWheel">mouseWheel()</a> - Code inside this block is run once when mouse wheel is scrolled over the element</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>In this example, a canvas element is created and an event listener <a href="/reference/#/p5/mousePressed">mousePressed()</a> is attached. Function changeGrey() will only run when the mouse is pressed over the canvas, and will will change the background color to a random grey. If the mouse is pressed anywhere, even outside of the canvas, the diameter of the ellipse will increase by 10 pixels. The custom function changeGray(), in this instance, is placed within the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function and is to be triggered when mouse is pressed over the canvas element. If the mouse is not pressed, false is passed and changeGrey() will not run.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +
            +      <p>The above mouse functions can be attached to an element like the canvas or can be used without specifying an element. The keyboard functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyReleased">keyReleased()</a>, <a href="/reference/#/p5/keyTyped">keyTyped()</a>, and mouse function <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> cannot be attached to a specific element.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block runs once when the mouse is moved and the mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block runs once when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is runs once when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is runs once when any key is released</li>
            +      </ul>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/tdd.html b/dist/es/learn/tdd.html
            new file mode 100644
            index 0000000000..32b3219f77
            --- /dev/null
            +++ b/dist/es/learn/tdd.html
            @@ -0,0 +1,660 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Unit Testing and Test Driven Development</h1>
            +      <div class="attribution">
            +        This tutorial was written by <a href='https://github.com/andrewjtimmons'>Andy Timmons</a>.
            +      </div>
            +
            +      <h2>Overview</h2>
            +      <p>
            +        This tutorial will walk you through setting up your development environment to run unit tests against your code. Unit testing is a method of applying tests to the classes and functions in your code. It can catch bugs, help you collaborate with others, and code faster. Test driven development is a method of writing your tests before you write code so you have all of your tests when you finish.
            +      </p>
            +      <p>
            +        This tutorial is intended for people who:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>Have written p5.js sketches before.</li>
            +          <li>Are comfortable using javascript <a href='http://p5js.org/examples/structure-functions.html'>functions.</a></li>
            +          <li>Can run basic terminal commands.  If you are not familiar using a terminal here is a <a href='http://lifehacker.com/5633909/who-needs-a-mouse-learn-to-use-the-command-line-for-almost-anything'>good tutorial for getting comfortable.</a></li>
            +        </ul>
            +
            +      <h2> Why unit test?</h2>
            +      <p>
            +        In late 1998 NASA launched the Mars Climate Orbiter in collaboration with Lockheed Martin. This robotic space probe cost 193 million dollars and took one year to arrive and establish its orbit around Mars. Minutes later it crashed into Mars and exploded. NASA later determined it was a software error. The Lockheed Martin navigation code gave measurements in English units like feet, and the NASA code expected the measurements to be in metric units like meters. The difference between the two caused the crash. [<a href='https://en.wikipedia.org/wiki/Mars_Climate_Orbiter'>Citation</a>]
            +      </p>
            +      <p>
            +        Unit testing could have prevented this error and while you might not be launching spaceships (but by all means please try), unit testing can prevent a lot of headaches from the outset of your project to install day. It can help you:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>improve your design and reduce bugs</li>
            +          <li>collaborate with others</li>
            +          <li>finish your project faster</li>
            +        </ul>
            +
            +      <h2>Setting up for unit testing</h2>
            +      <p>
            +        Installing node:
            +      </p>
            +        <ol>
            +          <li>First you must install node. If you already have node installed this assumes you are using version 4 or higher.  Node is a open source runtime environment for building server side applications.  Don’t worry if that sentence didn’t make sense.  You don’t have to understand all there is to know about node to do this tutorial.  If you are curious to learn more you can read the <a href='https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io'>p5.js node tutorial.</a></li>
            +          <li>On Mac, Linux, Windows:  Go to <a href='https://nodejs.org/en/'>https://nodejs.org/en/</a> and download the installer.  Open the installer and follow the directions.</li>
            +          <li>
            +            Once the installer finishes open a terminal and run the following command to verify it installed correctly.  You should see something like "v6.6.0" or some other numbers that indicate the version you installed.<br />
            +            <pre><code class="language-javascript">
            +            node -v
            +            </code></pre>
            +          </li>
            +        </ol>
            +      <p>
            +        Update npm, the Node Package Manager.  Npm is a program that allows you to install software libraries that are compatible with node.  In your open terminal run the command:
            +        <pre><code class="language-javascript">
            +          sudo npm install npm@latest -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the chai assertion library.  This is what you will use to build your tests.  In the terminal window run the command:
            +        <pre><code class="language-javascript">
            +          npm install chai -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the mocha test running library.  Mocha drives your chai tests.  Much like a person drives a car.  In the terminal window run:
            +        <pre><code class="language-javascript">
            +          npm install mocha -g
            +        </code></pre>
            +      </p>
            +
            +      <h2>A sketch without tests</h2>
            +      <p>
            +        Your goal today is to make a sketch with a square whose fill color loops over every RGB color.
            +      </p>
            +      <p>
            +        Let’s set up the project. This is what it would look like without any unit tests.
            +      </p>
            +        <ol>
            +          <li>Make a folder called color_unit_test and open it</li>
            +          <li>
            +            Make a file called index.html and type the following code.  While you can just copy/paste it, typing it out will help you understand what it is doing better.  It is worth the time!<br />
            +            <pre><code class="language-javascript">
            +              &lt;!DOCTYPE html&gt;
            +              &lt;html&gt;
            +              &lt;head&gt;
            +                &lt;meta charset="UTF-8"&gt;
            +                &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
            +                &lt;script src="https://cdn.jsdelivr.net/npm/p5@0.4.20/lib/p5.js"&gt;&lt;/script&gt;
            +                &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +                &lt;style&gt; body {padding: 0; margin: 0;} &lt;/style&gt;
            +              &lt;/head&gt;
            +              &lt;body&gt;
            +              &lt;/body&gt;
            +              &lt;/html&gt;
            +            </code></pre>
            +          </li>
            +          <li>
            +            make a file called sketch.js and put in the following code<br />
            +            <pre><code class="language-javascript">
            +              // This is for a unit test tutorial.
            +              // it should create a rectangle and allow you to iterate over
            +              // every single color.
            +              //
            +              // colorValueIncrease sets the amount the color changes on each
            +              // draw loop. Values greater than 255 will break the sketch.
            +              // fillColor will be the color of the rectangle.
            +              // colorIncreaser will become an instance of our ColorIncreaser class.
            +
            +              let colorValueIncrease = 1;
            +              let fillColor;
            +              let colorIncreaser;
            +
            +              function setup() {
            +                createCanvas(500, 500);
            +                background(0);
            +                fillColor = color(0, 0, 0, 255);
            +                noStroke();
            +              }
            +
            +              function draw() {
            +                fill(fillColor);
            +                rect(0, 0, 500, 500);
            +
            +                // increment the red value
            +                fillColor.levels[0] += colorValueIncrease;
            +                // If the red value is maxed out increment the green value
            +                // and reset the red value.
            +                if (fillColor.levels[0] > 255) {
            +                  fillColor.levels[0] = 0;
            +                  fillColor.levels[1] += colorValueIncrease;
            +                }
            +                // If the green value is maxed out increment the blue value
            +                // and reset the green value.
            +                if (fillColor.levels[1] > 255) {
            +                  fillColor.levels[1] = 0;
            +                  fillColor.levels[2] += colorValueIncrease;
            +                }
            +                // If the blue value is maxed out reset the green value.
            +                if (fillColor.levels[2] > 255) {
            +                  fillColor.levels[2] = 0;
            +                }
            +              }
            +            </code></pre>
            +          </li>
            +          <li>
            +           Open the index.html file in your browser (you don’t need to run a local server in this case). You should see a black box become red and then black again. This is the basis of looping over all the RGB colors. The problem you face is that there are 256 values for red, green, and blue, which means there are over 16 million combinations of colors! You can make this faster. However, making this faster will cause flashing lights which might give some people headaches or seizures. Please only increase this value if you do not have issues with flashing lights. The rest of the tutorial should be fine.  In the sketch.js file change the<pre><code class="language-javascript">let colorValueIncrease = 33;</code></pre> and reload the page. However this still doesn’t guarantee this is working properly. You don’t have time to watch all the colors change nor can you tell yourself if it is iterating through the millions of colors. Change the colorValueIncrease variable back to 1 before you move on.
            +          </li>
            +          <li>
            +            At 30 draw loops per second it would take over six days to loop through all of the colors. You certainly don’t have time to do that once, and would never be able to check and see if it worked every time you updated our code. What if you accidentally change something in our draw loop that breaks the code right before install?  You wouldn’t know until it was live and everyone saw your sketch break.
            +          </li>
            +        </ol>
            +
            +      <h2>Your first unit tests</h2>
            +      <p>
            +        Unit testing can help us out here. The majority of the time spent in this program is the actual drawing of the pixels. Adding 1 and checking a few if statements is very fast if you don’t need to draw the actual pixels. So you can check if the color values increase as expected without having to actually watch them all increase on your screen.
            +      </p>
            +      <p>
            +        In the folder called color_unit_test that you already created, make a new folder called test.  Open the test folder and make a file called test.js.  Type this code into test.js
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +
            +
            +          // Create the variable you are going to test
            +          let p5js = 'awesome';
            +
            +
            +          // describe lets you comment on what this block of code is for.
            +          describe('these are my first tests for p5js', function() {
            +
            +
            +            // it() lets you comment on what an individual test is about.
            +            it('should be a string', function(done) {
            +              // expect is the actual test.  This test checks if the var is a string.
            +              expect(p5js).to.be.a('string');
            +              // done tells the program the test is complete.
            +              done();
            +            });
            +
            +
            +            it('should be equal to awesome', function(done) {
            +              // This expect tests the value of the string.
            +              expect(p5js).to.equal('awesome');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your command line and <a href='http://ss64.com/bash/cd.html'>cd</a> into the main directory of our sketch called color_unit_test.  Type the command
            +        <pre><code class="language-javascript">mocha</code></pre>
            +      </p>
            +      <p>
            +        into the command line and watch your first test run!  You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              ✓ should be a string
            +              ✓ should be equal to awesome
            +            2 passing (14ms)
            +        </code></pre>
            +      </p>
            +      <p>
            +        Let's look at what happens when tests fail. Change line 6 in test.js from:
            +        <pre><code class="language-javascript">let p5js = 'awesome';</code></pre>
            +      </p>
            +      <p>
            +        to
            +        <pre><code class="language-javascript">let p5js = 42;</code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your terminal and run the mocha command again. You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              1) should be a string
            +              2) should be equal to awesome
            +
            +            0 passing (18ms)
            +            2 failing
            +
            +            1) these are my first tests for p5js should be a string:
            +               AssertionError: expected 42 to be a string
            +                at Context.<anonymous> (test/test.js:14:24)
            +
            +            2) these are my first tests for p5js should be equal to awesome:
            +               AssertionError: expected 42 to equal 'awesome'
            +                at Context.<anonymous> (test/test.js:21:21)
            +        </code></pre>
            +      </p>
            +      <p>
            +        What is nice about these errors is:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>They tell you the name of the test that you put in the describe() and it() functions</li>
            +          <li>They tell you what they expected with AssertionError: expected 42 to be a string</li>
            +          <li>They tell you what file and line of code had the problem test/test.js:14:24</li>
            +        </ul>
            +      <p>
            +        Now that you know the basics of unit testing you are ready to write some tests against your code and refactor your sketch!
            +      </p>
            +
            +      <h2>Test Driven Development</h2>
            +      <p>
            +        You are going to use Test Driven Development for the rest of this tutorial.  The idea is you write your unit tests first, run them and watch them fail, and then add code to sketch.js to make the tests pass.  This way you ensure your code is working as you expect every step of the way and that new code doesn’t break old code.  Your goal is to create a ColorIncreaser class that:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>takes in an integer as the value to increase each time called colorValueIncrease.</li>
            +          <li>takes in an instance of the <a href='http://p5js.org/reference/#/p5/color'>p5 color class.</a></li>
            +          <li>has a function to increase the values in the color by the value in colorValueIncreases.</li>
            +        </ul>
            +      <p>
            +        Delete everything in test.js and replace it with this
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +          // Import our ColorIncreaser class.
            +          const ColorIncreaser = require('../sketch');
            +
            +          describe('ColorIncreaser tests', function() {
            +            // Will hold the reference to the ColorIncreaser class
            +            let colorIncreaser;
            +
            +            // beforeEach is a special function that is similar to the setup function in
            +            // p5.js.  The major difference it that this function runs before each it()
            +            // test you create instead of running just once before the draw loop
            +            // beforeEach lets you setup the objects you want to test in an easy fashion.
            +            beforeEach(function() {
            +                colorIncreaser = new ColorIncreaser();
            +            });
            +
            +            it('should be an object', function(done) {
            +              expect(colorIncreaser).to.be.a('object');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command in your terminal and watch your new test fail!  The crux of the error is “TypeError: ColorIncreaser is not a constructor”.  This makes sense because you have not created a ColorIncreaser class in our sketch yet. <br />
            +
            +        Go to the bottom of your sketch.js file, below the closing bracket } for the draw function, and add this:
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor() {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +            }
            +          }
            +
            +          module.exports = ColorIncreaser;
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  The function line will be our color increasing object.  The module.exports line is what allows our test.js file to import our ColorIncreaser with the line you already added that looks like this:
            +        <pre><code class="language-javascript">
            +           const ColorIncreaser = require('../sketch');
            +        </code></pre>
            +      </p>
            +      <p>
            +        If you go back to your terminal and run mocha your test should pass.<br />
            +
            +        Now get your ColorIncreaser function to actually do something.  Start by storing the colorValueIncrease as a variable in your class.  Before you change the code in sketch.js you have to write your tests.  Change the beforeEach function in test.js to look like this
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        and add a new it() test below it like this
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command and you will get the pivotal line:<br />
            +        AssertionError: expected undefined to equal 1<br />
            +        because you have not added this to your class yet. You need to add that value to get this to work. Add this line to the setup function in sketch.js under noStroke();
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +        </code></pre>
            +        and change the ColorIncreaser function to look like this
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser() {
            +            constructor(colorValueIncrease) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +            }
            +          }
            +        </code></pre>
            +        Let’s run the mocha test again.  It should pass!
            +      </p>
            +
            +      <h2>Testing when your object is composed of other objects</h2>
            +      <p>
            +        Now you need to add an instance of the p5 color class to our ColorIncreaser. However, for your tests, you don’t want to use an actual instance of the color() class because you don’t want to test external dependencies given by another library.You just want to make sure that your increment function works. So you are going to create what is called a mock of the p5 color class so you can test without worrying about the implementation of code you didn’t write.
            +      </p>
            +      <p>
            +        The original way of incrementing colors just used the color.levels and changed the red, green and blue values at index [0], [1], and [2].  You can see this in the draw function in sketch.js.  The implementation of color just stores those values in a javascript array so you can mock it out very easily.  Put this code in test.js below the const ColorIncreaser = require… line and above the describe line
            +        <pre><code class="language-javascript">
            +          function mockColor(red, green, blue, alpha) {
            +              // Mock of the color class from p5
            +              this.levels = [];
            +              this.levels[0] = red;
            +              this.levels[1] = green;
            +              this.levels[2] = blue;
            +              this.levels[3] = alpha;
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Update your beforeEach() function
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              let fillColor = new mockColor(0, 0, 0, 255);
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And update the it('should initialize without mutation', function block
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[3]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And run the tests!  Failure!   TypeError: Cannot read property 'levels' of undefined<br />
            +        You have to update the ColorIncreaser class to take in a fillColor variable.  It is an easy fix.  In sketch.js change the colorIncreaser line in setup() to look like this
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +        </code></pre>
            +      </p>
            +      <p>
            +        and update the ColorValueIncreaser function
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor(colorValueIncrease, fillColor) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +              this.fillColor = fillColor;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Run the tests again and they should pass!
            +      </p>
            +      <p>
            +        Now you have all the initialized variables you need to make the class work.  This provides the scaffold on which you will build your method to increase the color value and iterate over every color.
            +      </p>
            +
            +      <h2>Testing class methods</h2>
            +      <p>
            +        You are going to make a class method called increaseFillColor. It will basically run the code that is currently in our draw loop, but use the values stored in our ColorIncreaser class to do it.
            +      </p>
            +      <p>
            +        As covered before there are 256 values for red, green and blue giving 16,777,216 color combinations. While that might seem overwhelming you can test it easily because you know what values should be present in red, green and blue after each time you call our increaseFillColor function. For example if you start with the color black with the rgb levels 0,0,0 and you call increaseFillColor once you know you should now have the values 1,0,0.  So you are going to add tests in test.js for calling increaseFillColor 255, 65535 and 16777215 times.
            +        <pre><code class="language-javascript">
            +          it('should have rgb values 255, 0, 0 after calling increaseFillColor 255 times', function(done) {
            +            //it is 256^1 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 255; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 0 after calling increaseFillColor 65535 times', function(done) {
            +            //it is 256^2 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 65535; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 255 after calling increaseFillColor 16777215 times', function(done) {
            +            //it is 256^3 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 16777215; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And when you run mocha the tests will fail because that function does not exist!  Let’s add a skeleton function in sketch.js inside the ColorIncreaser class below the constructor function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Now when you run mocha the tests fail for a different reason.  It finds the function, but it doesn’t do what you expect it to.  Let’s change the function in sketch.js to look like what is inside the draw function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +
            +            this.fillColor.levels[0] += this.colorValueIncrease
            +            this.numColorsSoFar += 1
            +
            +
            +            if (this.fillColor.levels[0] > 255) {
            +              this.fillColor.levels[0] = 0
            +              this.fillColor.levels[1] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[1] > 255) {
            +              this.fillColor.levels[1] = 0
            +              this.fillColor.levels[2] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[2] > 255) {
            +              this.fillColor.levels[2] = 0;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        And now your tests pass!  Hooray!<br />
            +        Now you just need to get the draw function set up.  Replace the draw function in sketch.js with this:
            +        <pre><code class="language-javascript">
            +          function draw() {
            +            fill(colorIncreaser.fillColor);
            +            rect(0, 0, 500, 500);
            +            colorIncreaser.increaseFillColor()
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        All tests should pass now and you can expect your code to behave as you want!  As a bonus when you change the code in the future the tests will let you know that it still works as intended!<br />
            +        Congratulations, you made it to the end! Unit tests and Test Driven Development are powerful ways to build code that you know works just as you expect. <br />
            +        You can continue to build on your skills by
            +      </p>
            +        <ul class="bullet-list">
            +          <li>adding tests to your own sketches and projects</li>
            +          <li>Reading up on the tools we’ve used here:</li>
            +          <ul class="bullet-list">
            +            <li><a href='http://www.agiledata.org/essays/tdd.html'>Test Driven Development and Unit tests</a></li>
            +            <li><a href='https://www.npmjs.com/'>Node Package Manager (NPM)</a></li>
            +            <li><a href='http://chaijs.com/'>Chai</a></li>
            +            <li><a href='https://mochajs.org/'>Mocha</a></li>
            +            <li><a href='https://en.wikipedia.org/wiki/Mock_object'>Mock Objects</a></li>
            +          </ul>
            +        </ul>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/test-tutorial.html b/dist/es/learn/test-tutorial.html
            new file mode 100644
            index 0000000000..205071c7b6
            --- /dev/null
            +++ b/dist/es/learn/test-tutorial.html
            @@ -0,0 +1,178 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>test tutorial title</h1>
            +
            +      <p>Blah blah blah. Here is some formatted code:</p>
            +
            +      <pre><code class="language-javascript">
            +      var note = "this is formatted code!";
            +      </code></pre>
            +
            +      <p>Blah blah blah. Here is an iframe embedded:</p>
            +
            +      <iframe src="../../assets/learn/test-tutorial/embed.html" width="600" height="400"></iframe>
            +
            +      <p>Blah blah blah. Here is p5-widget embedded:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +
            +function draw() {
            +  background(255, 0, 200);
            +}
            +</script>
            +
            +      <p>The end!</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/transformations.html b/dist/es/learn/transformations.html
            new file mode 100644
            index 0000000000..222af03248
            --- /dev/null
            +++ b/dist/es/learn/transformations.html
            @@ -0,0 +1,615 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by Gene Kogan. It was ported to P5 by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +
            +      </div>
            +
            +      <h1>Transformations</h1>
            +
            +      <p>
            +      The p5.js canvas works like a piece of graph paper. When you want to draw something, you specify its coordinates on the graph. For example, we can draw a 40x40 pixel rectangle at the point (30, 30).
            +      </p>
            +
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      If you want to move your rectangle 50 pixels to the right and 50 pixels down, you can add that to the x and y-coordinates of the rectangle and run rect(80, 80, 40, 40). But there is another way to do this:
            +      move the graph paper itself. If you move the graph paper 50 pixels right and 50 pixels down, you will get exactly the same visual result. Moving the coordinate system is called translation, and can be done using the translate() function.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	translate(50, 50);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      As far as the rectangle is concerned, it hasn't moved at all. Its upper left corner is still at (30, 70). When you use transformations, the things you draw never change position; the coordinate system itself does. We will see how this can be useful in the next section.
            +    </p>
            +      <h2>push() and pop()</h2>
            +
            +      <p>
            +      Sometimes, a sketch will involve multiple translations to draw the same thing in different locations. If we want to draw the same rectangle in three separate locations -- say at (25, 25), (50, 75), and (75, 100) -- we can use push() and pop() to
            +      keep track of and revert our translations as we go. The function pop() undoes all translations made following the previous push(). push() and pop() also track and revert style and,  color changes -- fill(), stroke(), etc -- in the same way. Thus all translations
            +      and style/color commands made between a single push() and pop() apply only to the operations made between them. Take a look at the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw() {
            +	background(240);
            +
            +	push();
            +  	translate(25, 25);
            +	fill(255, 0, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(75, 100);
            +	fill(0, 255, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(50, 75);
            +	fill(0, 0, 255);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +}
            +      </script>
            +
            +      <p>
            +      The first triangle in red is drawn at (0, 0) after the coordinate system has been translated to the right and down by 25 pixels each. After the first pop() is called, the first translation is undone and the coordinate (0, 0) reverts back to the top-left corner of the canvas.
            +      We call push() and translate(75, 100), now moving the the canvas 75 pixels right and 100 pixels done, and then draw the green rectangle. The second pop() undoes that translation as well. Finally, the blue triangle is done after making the same operation, this time translating 50 pixels right and 75 pixels down.
            +    </p>
            +
            +      <h2>What's the Advantage</h2>
            +
            +      <p>In the last sketch, we could have achieved the same visual output by simply drawing the rectangles at those exact points. Or we could have used translate() without the push() and pop() blocks by undoing each translation manually, e.g. translate(-25, -25) to undo the first translation of (25, 25).</p>
            +      <p>For simple shapes like rectangles, it is easier to not use translations, but rather to specify the points manually. But when we begin to draw more complex shapes, translations become advantageous. Let's take a look at an example where translate(), push(), and pop() are really useful.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +	for (var x = 5; x < 150; x = x+25){
            +		for (var y = 5; y < 200; y = y+25){
            +			push();
            +			translate(x, y);
            +	  		drawHouse();
            +			pop();
            +		}
            +	}
            +}
            +
            +function drawHouse() {
            +	triangle(7.5, 0, 0, 7.5, 15, 7.5);
            +	rect(0, 7.5, 15, 12.5);
            +	rect(6, 15, 5, 5);
            +}
            +      </script>
            +
            +      <p>
            +      In this example, we draw a grid of houses. Instead of having to keep track of the coordinates for every vertex of every house, we simply have one function, drawHouse() which draws a house relative to the point (0, 0). We then create a loop which will translate to the correct point before drawing each house.
            +      </p>
            +
            +      <p>
            +      Using the transformations command allows us to use a single drawing function irrespective of where we intend to draw it on the canvas, while push() and pop() allow us to reserve transformations only to the relevant code blocks.
            +      </p>
            +
            +      <h2>Rotation</h2>
            +
            +      <p>
            +      In addition to translating the grid, you can also rotate it with the rotate() function. This function takes one argument, the angle of rotation. It then rotates the canvas around the origin point (0, 0). It's as though you have a piece of graph paper, place your finger on the point (0, 0), and then rotate the paper around your finger.
            +      </p>
            +
            +      <p>Angle is measured clockwise with zero being at 3 o'clock. In p5.js, all the functions having to do with angles take radians. A single rotation or a full circle has 360° or 2π radians. Here is a diagram of how p5.js measures angles in degrees (black) and radians (red).</p>
            +
            +      <img src="../../assets/learn/transformations/angles.png" style="width:150px;">
            +
            +      <p>Since most people think in degrees, p5.js has a built-in radians() function which takes a number of degrees as its argument and converts it to radians for you. It also has a degrees() function that converts radians to degrees. Take a look at the following example which rotates the canvas by an angle measurement set by the mouseX position.
            +      The red square is drawn before rotation, and the green one after rotation.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw() {
            +	var deg = mouseX;
            +	var rad = radians(deg);
            +
            +	background(240);
            +
            +	// the red rectangle is drawn before the rotation so
            +	// it will stay in place
            +	fill(255, 0, 0);
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 50);
            +
            +	fill(0, 255, 0);
            +	text("rotate "+floor(deg)+" degrees", 50, 25);
            +
            +	// rotation is done here. all subsequent drawing
            +	// is done post-rotation
            +	rotate(rad);
            +
            +	// draw the grid
            +	drawGrid();
            +
            +	// the green rectangle and grid is drawn after rotating the canvas
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 500);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +    fill(120);
            +	for (var x=-2*width; x < 2*width; x+=40) {
            +		line(x, -2*height, x, 2*height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-2*height; y < 2*height; y+=40) {
            +		line(-2*width, y, 2*width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <h2> Rotating in place</h2>
            +
            +      <p>In the last example, the green square goes off the screen as we rotate the canvas more. Sometimes we want to be able to rotate a shape in place, rather than around the top-left corner of the screen. We can do this by combining translate() and rotate() together. Recall that translate() moves the origin (0,0) to another place in the canvas and that rotate() rotates the canvas around the origin.
            +        Thus if we want to draw a shape in the middle of the screen and then rotate it in place, we should first translate the canvas to the point we want to draw the shape, then rotate, then draw the shape at (0, 0). Take a look at the following example.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +        <p>If you want the rectangle to rotate around its own center point rather than by its corner, we can use the command rectMode(CENTER) to set p5.js to interpret the coordinates of rectangles to refer to the center of the rectangle rather than the top-left corner. The following example is the same as the previous one but with centered coordinates.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +	rectMode(CENTER);	// now the first two arguments of a rect are its center point, not corner
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +      <p>Here is a program that generates a wheel of colors by using rotation, and draws a strip every 25 frames.</p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	background(240);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	// the modulo operator % calculates the remainder.
            +	// example: 24 % 25 = 24, 25 % 25 = 0, 26 % 25 = 1, etc.
            +	// thus this if statement will evaluate True every 25 frames.
            +	if (frameCount % 25 == 0) {
            +		fill(random(255), random(255), random(255));
            +		push();
            +		translate(75, 100);
            +		rotate(radians(frameCount));
            +		rect(0, 0, 100, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +        <h2>Rotational Symmetry</h2>
            +
            +        <p>
            +        Let's take a look at a more complicated example where we can use translate and rotate together to create interesting symmetries around the center of the canvas. Let's first build it by drawing 8 squares which are evenly distributed along a circle around the center of the canvas. What we do is we first translate to the center of the screen, translating the canvas by (width/2, height/2).
            +        We then rotate the canvas to the 8 angles evenly distributed between 0 and 2π radians. We then draw a circle 50 pixels away from the center, after each of these rotations.
            +        </p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		rect(50, 0, 10, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +      <p>
            +        Look at the line rect(50, 0, 10, 10). Recall that you can draw a shape in the same place by translating to it first and then drawing it at (0, 0). So we can do another another translation after we've rotated, to translate along the right-pointing line after it's been rotated. So we can replace the statement rect(50, 0, 10, 10) with the following two: translate(50, 0) and rect(0, 0, 10, 10).
            +        By doing so, we bring the pivot point or origin of the canvas to each of the eight rectangles we just drew.
            +      </p>
            +
            +      <p>
            +        This is convenient because now we can do something even more interesting. Instead of simply drawing a rectangle at each of those points, let's create another loop which will draw six smaller squares evenly distributed around a small circle around each of these new pivot points. See the following.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		translate(50, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			rect(15, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <p>
            +        Now that we have achieved an interesting geometry, we can embellish this program by making a variable for the first translation amount and for the x-position of the rectangle, and modulating them in interesting ways. In the following example, we'll modulate those two values using Perlin noise. If you haven't used Perlin noise before, take a look at the tutorial on Perlin noise.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		var tx = 100 * noise(0.01*frameCount);
            +		translate(tx, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			var rx = 30 * noise(0.01*frameCount + 10);
            +			rect(rx, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +      <p>Now we're getting somewhere! Let's take the previous example and make the following additions to it to make it even more interesting.</p>
            +
            +      <p>
            +        <ul class="list_view">
            +          <li>Extra rotation variables so the whole circle rotates with perlin noise</li>
            +          <li>Red + Blue = Purple</li>
            +          <li>Additional noisy in-place rotation of the drawn shapes</li>
            +          <li>Noisy modulation of the size of the shapes being drawn</li>
            +        </ul>
            +      </p>4
            +
            +      <p>All the noisy variables will be calculated at the top of the draw loop for better organization. Looks cool, right?!</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +	fill(0, 50);
            +	stroke(255, 50);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var ang1 = TWO_PI * noise(0.01*frameCount + 10);
            +	var ang2 = TWO_PI * noise(0.01*frameCount + 20);
            +	var ang3 = TWO_PI * noise(0.01*frameCount + 30);
            +	var rx = 30 * noise(0.01*frameCount + 40);
            +	var tx = 100 * noise(0.01*frameCount + 50);
            +	var size1 = 100 * noise(0.01*frameCount + 60);
            +	var size2 = 20 * noise(0.01*frameCount + 60);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(ang1 + TWO_PI * i / 8);
            +		translate(tx, 0);
            +		rect(0, 0, size1, size1);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(ang2 + TWO_PI * j / 6);
            +			translate(rx, 0);
            +			rotate(ang3);
            +			rect(rx, 0, size2, size2);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <h2>Scaling</h2>
            +
            +      <p>
            +        There is one more function which transforms the coordinate system, and that is scale(). Scale changes the size of the grid by multiplying the coordinate system. See the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var scaleAmount = mouseX / 100;
            +  	scale(scaleAmount);
            +
            +	drawGrid();
            +  	fill(255, 255, 0);
            +  	rect(20, 20, 50, 50);
            +}
            +
            +function drawGrid() {
            +	fill(0);
            +	stroke(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/trigonometry.html b/dist/es/learn/trigonometry.html
            new file mode 100644
            index 0000000000..ea41ee631a
            --- /dev/null
            +++ b/dist/es/learn/trigonometry.html
            @@ -0,0 +1,189 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <h2>Trigonometry Primer</h2>
            +      <p>(learning to love triangles)</p>
            +      <div class="attribution">
            +        This tutorial was written during the first p5.js developers conference by Tega Brain.
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="pythagoras">Pythagoras Theorum</h3>
            +      <div class="info">
            +        <p>Trigonometry is a branch of geometry that is fundamental to all graphics programming.  It provides useful equations that enable you to figure out distances between points and how curves and circles can be described in Cartesian coordinates. Remember Cartesian coordinates are points described by x and y values. Trigonmetry also enables you to do things like move shapes in circular motion or oscillate values smoothly back and forth between two extremes.</p>
            +
            +
            +        <p>The right angled triangle is one of the most important parts of trigonometry and Pythagoras was a guy who got pretty famous for figuring out a theorem that relates the length of each of its sides. Pythagora figured out that in every right hand triangle, if you square each of the two shortest sides, their sum equals the square of the longest side.</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/pythagoras1.jpg" />
            +
            +        <p>Right angled triangles are special also because each of their angles has a specific relationship to the ratio between the length of two of their sides. This is what sine, cosine and tangent functions describe. Sin cos and tan are known as trigonometric functions and they give us the relationship between the ratio of two of the triangle’s sides and one of the angles of the triangle. You may recall the acronym: SOH-CAH-TOA that helps you remember how sinθ, cosθ and tanθ relate to the ratio of which of the triangle’s sides.</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/hypotenuse.jpg" />
            +        
            +        <p>This is all pretty great, because is means that with just a couple of pieces of information about a right angled triangle, like knowing two of its side lengths or maybe knowing one of its angle and a side length, you can use Pythagora’s theorem in combination with the sin, cos and tan equations to figure out everything else.</p>
            +
            +        <p>These triangles are also helpful as they help us to map and understand the x and y coordinates of points along curves and circles. Notice how in the drawing below you can see how any point on a circle will have a relationship to a right angled triangle. This relationship means that a point on a circle can be understood in two ways. Firstly, as we have seen a point can be described by Cartesian coordinates which are of course, by x and y co-ordinates, but it can also be described using polar coordinates. Polar coodinates are an angle and a distance from the origin (the radius of the circle).</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/polar.jpg" />
            +      </div>
            +        
            +      <h3 class = "start-element tutorial-btn" id="Polar Coordinates">Polar Coordinates</h3>
            +      <div class="info">
            +        <p>Polar coordinates describe a point using an angle and a distance from the origin. This is useful when you are coding something like an analog clock. When drawing a clock, you would need to place each hand at a particular angle, for example, 3pm is at zero degrees and midday is at 90 degrees. Each hand would be coded as a line drawn onto a screen, that connects two points. So these hand would connect the origin to the x,y coordinates that is at the position of the time. Putting anything on a screen always requires you to describe it in terms of x and y.</p>
            +        
            +        <p>So how do we convert between polar coordinates and x-y coordinates?</p>
            +        
            +        <p>The relationship between polar coordinates and x,y coordinates can be calculated using a unit circle. This is a circle that has a radius of 1 unit which is useful because it means the hypotenuse in your right angled triange is always 1.</p>
            +
            +        <iframe src="../../assets/learn/trigonometry/unitCircle/embed.html" width="600" height="400"></iframe>
            +
            +
            +      </div>
            +      
            +      <h3 class="start-element tutorial-btn" id="sin">Using Sin and Cosine</h3>
            +      <div class="info">
            +        <iframe src="../../assets/learn/trigonometry/sincoscurves/embed.html" width="800" height="750"></iframe>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/learn/tutorial-guide.html b/dist/es/learn/tutorial-guide.html
            new file mode 100644
            index 0000000000..26efef48a3
            --- /dev/null
            +++ b/dist/es/learn/tutorial-guide.html
            @@ -0,0 +1,262 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Guía para contribuir con tutoriales de p5.js</h1>
            +      <div class="attribution">
            +        Este tutorial fue escrito por Tega Brain.
            +      </div>
            +      <p>
            +        Invitamos a los educadores, colaboradores y entusiastas en general a contribuir con tutoriales de p5js. El proyecto de p5js hace que la programación creativa y el desarrollo de código abierto sean más accesibles para una comunidad diversa y estamos muy emocionados de publicar tutoriales sobre todos los aspectos del proceso de desarrollo. Nuestros materiales de aprendizaje hasta el momento incluyen guías sobre el aprendizaje de p5, la técnica de programación y cómo contribuir a un proyecto de código abierto.
            +      </p>
            +      <p>
            +        Le damos la bienvenida a la contribución de nuevos tutoriales escritos y esta guía describe los pasos para proponer, preparar y contribuir con un tutorial.
            +      </p>
            +
            +      <h2>Cómo empezar:</h2>
            +      <ul class="list_view">
            +        <li>
            +          Comprueba que el tema que hayas propuesto no haya sido cubierto antes. Puedes encontrar <a href="https://docs.google.com/spreadsheets/d/1sh3IwcCUY4Bm8N4fRZw6CwSDdQmmXgY_awjVj-UC8mo/edit#gid=0">una lista aquí</a>
            +          con los tutoriales que están en progreso. Si tu tema está marcado en esta lista como en progreso, tal vez puedes añadir al trabajo que se está llevando a cabo y cooperar preparando el trabajo ya existente para su publicación así que por favor contáctate con nosotros.
            +        </li>
            +        <li>
            +          Si tu tema no está cubierto y no está enlistado como en progreso, por favor escribe unas líneas sobre lo que propones cubrir y mándanos un email con esta descripción a education@p5js.org.
            +        </li>
            +      </ul>
            +      <h2>Cómo preparar un tutorial de p5js para su publicación en línea:</h2>
            +      <p>
            +        Cuando tu tutorial esté listo para ser publicado, por favor sigue los siguientes pasos para preparar tu contenido para el sitio de p5js.
            +      </p>
            +      <p>
            +        Guarda el contenido de tu tutorial en un archivo tutorial-name.hbs con <a href="https://github.com/mayaman/p5js-website/blob/master/src/templates/pages/learn/test-tutorial.hbs">esta estructura básica.</a>
            +         Como se muestra en este archivo, tiene que contener un un encabezado como se muestra a continuación:
            +      </p>
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-1.png" alt="Screenshot">
            +
            +      <p>
            +        La carpeta que contiene tu tutorial se colocará en la carpeta 'tutoriales' del sitio de p5js. El archivo llamado index.hbs es la <a href="/es/learn/">página de destino de los tutoriales de p5js,</a>
            +        y el archivo test-tutorial.hbs es el tutorial de prueba.
            +      </p>
            +      <p>
            +        Todos los contenidos deben de ir en las:
            +       
            +        &lt;section &gt; &lt;/section&gt;
            +        etiquetas de la página, con el fórmato definido por las etiquetas &lt;h1&gt; y &lt;h2&gt; y las etiquetas de párrafo &lt;p&gt; como se muestra en la <a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs"> página del tutorial de prueba.</a></p>
            +      <p>
            +        Si tu tutorial contiene imágenes, deben colocarse en la carpeta 'assets' del sitio p5, en la ubicación src / assets / learn / test-tutorial / images, como se muestra a continuación.
            +      </p>
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-2.png" alt="Screenshot">
            +      <p>
            +        Para formatear correctamente el código en el html de la página, utiliza la etiqueta:
            +      </p>
            +       
            +        <pre><code class="language-javascript">
            +&lt;pre&gt;&lt;code class="language-javascript"&gt;
            +Your code here!
            +&lt;/code>&lt;/pre&gt;
            +
            +</code></pre>
            +
            +      <h2>Incorporar bosquejos p5.js</h2>
            +      <p>
            +        Usar  p5js significa que puedes ilustrar tu tutorial con ejemplos de código animados, interactivos o editables para demostrar conceptos de programación. Tus ejemplos deben estar preparados como bosquejos p5.js y pueden ser incorporados en el tutorial de dos maneras.
            +      </p>
            +
            +      <ol>
            +        <li>
            +          Si el ejemplo es editable como en<a href="http://p5js.org/reference/#/p5/ellipse"> las páginas de referencia</a>del sitio de p5js, el bosquejo p5js debe ser incorporado en la página html usando el widget p5js. Sigue<a href="https://toolness.github.io/p5.js-widget/"> esta guía </a>sobre cómo incorporar bosquejos p5js usando el widget escrito por <a href="https://github.com/toolness">Toolness</a>. También puedes encontrar esto en la <a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs"> página del tutorial de prueba</a>.</li>
            +        <li>
            +          Si el ejemplo es animado y/o interactivo pero no editable, entonces el bosquejo p5js debe de ser incorporado en la página como un iframe como se describe a continuación.
            +        </li>
            +      </ol>
            +
            +      <h2>Incorporar un bosquejo p5js usando un iframe</h2>
            +
            +      <p>
            +        Un iframe es cómo crear una ventana a través de la cual puedes ver otra página, aislada del resto de tú página. En este caso va a ser una ventana al archivo index.html que contiene tu bosquejo p5js. 
            +      </p>
            +      <img src="https://github.com/tegacodes/p5.js-education/raw/master/images/iframe-2.jpg" alt="tutorialFileStructure" width="600">
            +
            +      <p>
            +        Coloca tus bosquejos p5 en la carpeta /src/assets/learn del sitio, en una carpeta etiquetada con el nombre de tu bosquejo como se muestra en la captura de pantalla. Aquí es donde todas las imágenes y bosquejos p5 enlazados por el iframe deben de estar guardados. 
            +      </p>
            +
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-3.png" alt="Screenshot">
            +
            +<p>En las subcarpetas que contienen tus ejemplos p5 debe de haber un archivo sketch.js y otro embed.html para tu bosquejo. </p>
            +<img src="../../assets/learn/tutorial-guide/images/screenshot-4.png" alt="Screenshot">
            +
            +<p>Asegúrate que tu archivo embed.html tenga la ruta correcta hacia las librerías p5 del sitio. Si la estructura de tus archivos es igual a la de arriba, la ruta hacia las librerías p5 debe ser "../../../js/p5.min.js".</p>
            +<p>Una vez comprobado esto, ya puedes incorporar los archivos 'index' de p5js como iframes en el archivo .hbs que contiene el contenido de tu tutorial. El código de inserción para el iframe sería entonces:</p>
            +  <pre><code class="language-javascript">
            +&lt;iframe src="http://p5js.org/assets/learn/tes-tutorial/embed.html" width="600" height="400"&gt;
            +&lt;/iframe&gt;
            +</code></pre>
            +
            +<p>Estilo para el iframe (esto podría directamente en la entrada o en una hoja de estilos):</p>
            +  <pre><code class="language-javascript">
            +&lt;style&gt; iframe{ border: none; } &lt;/style&gt;
            +</code></pre>
            +
            +<p>Aquí puedes explorar el bosquejo puro en ejecución: </p>
            +<a href="http://staging.p5js.org/assets/learn/test-tutorial/embed.html">http://staging.p5js.org/assets/learn/test-tutorial/embed.html</a>
            +
            +<p>Y aquí está incorporado en el sitio p5 usando el código a continuación: </p>
            +<a href="http://staging.p5js.org/learn/test-tutorial.html">http://staging.p5js.org/learn/test-tutorial.html</a>
            +
            +<p>Una cosa a recalcar es que necesitas ajustar manualmente el tamaño del iframe para que funcione de la mejor manera posible si las cosas son de tamaño estándar.</p>
            +
            +<p>También nota que los enlaces a los archivos de las librerías de p5.js no provienen de la página con extensión .eps con todo el contenido del tutorial. En su lugar, van a estar localizados en la página html que está procesando tu bosquejo (en este caso se llama embed.html).</p>
            +
            +<p>Más información sobre cómo incorporar bosquejos de p5.js se pueden encontrar <a href="https://github.com/processing/p5.js/wiki/Embedding-p5.js">aquí.</a></p>
            +<h2>Los últimos detalles</h2>
            +<p>Una vez que hayas terminado de escribir tu tutorial y tu contenido haya sido aprobado, copia (fork) desde GitHub el repositorio del sitio de p5.js, prepara tu contenido como lo hemos descrito anteriormente y finalmente crea una solicitud de (pull request) al repositorio del sitio de p5.js para que podamos agregar tu contenido y publicar tu contribución. ¡Felicidades!</p>
            +
            +    <p>¡Muchas gracias!</p>
            +
            +  </main>
            +
            +  
            +  <footer>
            +    <h2 class="sr-only">Créditos</h2>
            +    <p>
            +      p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +    </p>
            +  </footer>
            +
            +</div> <!-- end column-span -->
            +
            +
            +<!-- outside of column for footer to go across both -->
            +
            +<p class="clearfix"> &nbsp; </p>
            +
            +<object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +</object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/libraries/index.html b/dist/es/libraries/index.html
            new file mode 100644
            index 0000000000..b3502bb2f6
            --- /dev/null
            +++ b/dist/es/libraries/index.html
            @@ -0,0 +1,932 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">libraries | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="libraries-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>Bibliotecas</h1>
            +
            +      <h2>Usando una biblioteca</h2>
            +
            +      <p>Una biblioteca p5.js puede ser cualquier código p5.js que extiende o añade a las funcionalidades centrales de p5.js. Existen dos tipos de bibliotecas. Las bibliotecas centrales (<a
            +          href="/es/reference/#/libraries/p5.sound">p5.sound</a>) son parte de la distribución de p5.js, mientras que las bibliotecas contribuidas son mantenidas y  desarrolladas por y de propiedad de los miembros de la comunidad de p5.js.</p>
            +
            +      <p>Para incluir una biblioteca en tu bosquejo, enlázala en tu archivo HTML, después que hayas enlazado p5.js. Un archivo HTML como ejemplo podría lucir así:</p>
            +      <pre><code class="language-markup">&lt;!doctype html&gt;
            +&lt;html>
            +&lt;head>
            +  &lt;script src="p5.js"&gt;&lt;/script&gt;
            +  &lt;script src="p5.sound.js"&gt;&lt;/script&gt;
            +  &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +&lt;/head&gt;
            +&lt;body&gt;
            +&lt;/body&gt;
            +&lt;/html&gt;
            +      </code></pre>
            +
            +      <h2>Crea tu propia biblioteca</h2>
            +
            +      <p>p5.js acepta las bibliotecas contribuidas por la comunidad p5.js Revisa el
            +        <a href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +          tutorial de bibliotecas</a>
            +        para revisar los detalles específicos de cómo crear una.
            +        <a href="https://docs.google.com/forms/d/e/1FAIpQLSdWWb95cfvosaIFI7msA7XC5zOEVsNruaA5klN1jH95ESJVcw/viewform"
            +          target="_blank">¡Si has creado una biblioteca y quieres incluirla en esta página, llena este formulario!</a></p>
            +
            +      
            +      
            +      <h2 class="tutorial-title">Bibliotecas principales</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="/es/reference/#/libraries/p5.sound" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.sound.jpg">
            +              <h3>p5.sound</h3>
            +            </a>
            +          </div>
            +          <p>p5.sound extiende p5 con funcionalidad de Web Audio, incluyendo entrada de audio, reproducción, análisis y síntesis. Creada por:
            +            <a href="https://www.jasonsigal.cc/"
            +              target="_blank">Jason Sigal</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/processing/p5.accessibility" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.accessibility.jpg">
            +              <h3>p5.accessibility</h3>
            +            </a>
            +          </div>
            +          <p>p5.accessibility permite que el canvas de p5 sea más accesible a personas con discapacidad visual. 
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +      
            +      <h2 class="tutorial-title">Bibliotecas de la comunidad</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/asciiart" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/asciiart.jpg">
            +              <h3>asciiart</h3>
            +            </a>
            +          </div>
            +          <p>p5.asciiart te permite convertir de forma simple y fácil imágenes - a - arte ASCII dentro de p5js. Creada por:
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://itpnyu.github.io/p5ble-website/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.ble.jpg">
            +              <h3>p5.ble</h3>
            +            </a>
            +          </div>
            +          <p>Una biblioteca que facilita la comunicación entre dispositivos BLE y bosquejos p5.js. Creada por:
            +            <a href="https://1023.io"
            +              target="_blank">Yining Shi</a>, <a href="https://www.jingwen-zhu.com/"
            +              target="_blank">Jingwen Zhu</a>, <a href="https://tigoe.com/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/sarahgp/p5bots" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.bots.jpg">
            +              <h3>p5.bots</h3>
            +            </a>
            +          </div>
            +          <p>Con p5.bots puedes interactuar con Arduino (u otro microprocesador) desde el navegador. Usa los datos de los sensores para controlar tu bosquejo, usa un bosquejo para controlar LEDs, motores, y más. Creada por:
            +            <a href="http://www.sarahgp.com"
            +              target="_blank">Sarah Groff-Palermo</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Lartu/p5.clickable" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.clickable.jpg">
            +              <h3>p5.clickable</h3>
            +            </a>
            +          </div>
            +          <p>Biblioteca para crear botones y eventos fácilmente con p5.js.  Creada por:
            +            <a href="https://www.lartu.net"
            +              target="_blank">Martín del Río</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/p5.cmyk.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.cmyk.js.jpg">
            +              <h3>p5.cmyk.js</h3>
            +            </a>
            +          </div>
            +          <p>Espacio de color cian-magenta-amarillo-negro. Creada por:
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.collide2D" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.collide2D.jpg">
            +              <h3>p5.collide2D</h3>
            +            </a>
            +          </div>
            +          <p>p5.collide2D provee herramientas para calcular detección de colisiones en geometría 2D con p5.js. Creada por:
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.npmjs.com/package/p5.createloop" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.createloop.jpg">
            +              <h3>p5.createloop</h3>
            +            </a>
            +          </div>
            +          <p>Crea ciclos de animaciones con ruido y exporta GIF en una sola línea de código.  Creada por:
            +            <a href="https://www.piratesjustar.com/"
            +              target="_blank">Peter Hayman</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Smilebags/p5.dimensions.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.dimensions.jpg">
            +              <h3>p5.dimensions</h3>
            +            </a>
            +          </div>
            +          <p>p5.dimensions extiende las funciones de vector de p5.js para que funcione con cualquier número de dimensiones. Creada por:
            +            <a href="https://github.com/Smilebags"
            +              target="_blank">Smilebags</a>, <a href="https://github.com/max0410"
            +              target="_blank">Max Segal</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/freshfork/p5.EasyCam" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.EasyCam.jpg">
            +              <h3>p5.EasyCam</h3>
            +            </a>
            +          </div>
            +          <p>Control de cámara 3D simple con desplazamiento, zoom y rotación inerciales. Major contributions by Thomas Diewald. Creada por:
            +            <a href="https://jwilliamdunn.com"
            +              target="_blank">jWilliam Dunn</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/loneboarder/p5.experience.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.experience.jpg">
            +              <h3>p5.experience</h3>
            +            </a>
            +          </div>
            +          <p>Biblioteca extensa para p5.js que agrega eventos adicionales para crear aplicaciones web basadas en el canvas.  Creada por:
            +            <a href="https://github.com/loneboarder"
            +              target="_blank">Felix Meichelböck</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-func" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.func.jpg">
            +              <h3>p5.func</h3>
            +            </a>
            +          </div>
            +          <p>p5.func es una extensión de p5 que provee nuevos objetos y utilidades para generación de funciones en los dominios de tiempo, frecuencia y espacio. Creada por:
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.geolocation" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.geolocation.jpg">
            +              <h3>p5.geolocation</h3>
            +            </a>
            +          </div>
            +          <p>p5.geolocation provee técnicas para adquirir, observar, calcular y georeferenciar ubicaciones de usuario para p5.js. Creada por:
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://charlie-roberts.com/gibber/p5-gibber/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.gibber.jpg">
            +              <h3>p5.gibber</h3>
            +            </a>
            +          </div>
            +          <p>p5.gibber provee capacidades de secuenciamiento de música y de síntesis de audio. Creada por:
            +            <a href="https://charlie-roberts.com"
            +              target="_blank">Charlie Roberts</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jagracar/grafica.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/grafica.js.jpg">
            +              <h3>grafica.js</h3>
            +            </a>
            +          </div>
            +          <p>grafica.js te permite añadir gráficas 2D simples pero altamente configurables a tus bosquejos de p5.js. Creada por:
            +            <a href="https://jagracar.com/p5jsSketches.php"
            +              target="_blank">Javier Graciá Carpio</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bitcraftlab/p5.gui" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.gui.jpg">
            +              <h3>p5.gui</h3>
            +            </a>
            +          </div>
            +          <p>p5.gui genera una interfaz gráfica de usuario para tus bosquejos p5. Creada por:
            +            <a href="https://www.bitcraftlab.com/"
            +              target="_blank">Martin Schneider</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.localmessage" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.localmessage.jpg">
            +              <h3>p5.localmessage</h3>
            +            </a>
            +          </div>
            +          <p>p5.provee una interfaz simple para enviar mensajes locales de un bosquejo a otro y así dibujar en múltiples ventanas! Creada por:
            +            <a href="https://benmoren.com"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/marching" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/marching.jpg">
            +              <h3>marching</h3>
            +            </a>
            +          </div>
            +          <p>Conversión de trama a vector, isosuperficies. Creada por:
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/cvalenzuela/Mappa" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/mappa.jpg">
            +              <h3>mappa</h3>
            +            </a>
            +          </div>
            +          <p>Mappa es una biblioteca que provee un conjunto de herramientas para trabajar con mapas estáticos y geo-datos, además de otras herramientas útiles para desarrollar representaciones visuales de datos con geolocalización. Creada por:
            +            <a href="https://github.com/cvalenzuela/"
            +              target="_blank">Cristóbal Valenzuela</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://ml5js.org/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/ml5.js.jpg">
            +              <h3>ml5.js</h3>
            +            </a>
            +          </div>
            +          <p>ml5.js esta construido sobre TensorFlow.js y provee un acceso amigable a algoritmos de inteligencia artificial y machine learning desde el navegador. Creada por:
            +            <a href="https://ml5js.org/"
            +              target="_blank">NYU ITP/IMA and contributors</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="http://p5play.molleindustria.org" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.play.jpg">
            +              <h3>p5.play</h3>
            +            </a>
            +          </div>
            +          <p>p5.play provee funciones de sprites, animaciones, entrada y colisión para juegos y aplicaciones afines. Creada por:
            +            <a href="https://www.molleindustria.org/"
            +              target="_blank">Paolo Pedercini</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bobcgausa/cook-js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.particle.jpg">
            +              <h3>p5.particle</h3>
            +            </a>
            +          </div>
            +          <p>Los objetos Particle y Fountain pueden ser usados para crear efectos controlados por datos que son definidos a través de estructuras de usuario o entrada JSON y funciones de usuario para dibujar. Creada por:
            +            <a href="http://professorcook.org/"
            +              target="_blank">Robert Cook</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://antiboredom.github.io/p5.riso" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.Riso.jpg">
            +              <h3>p5.Riso</h3>
            +            </a>
            +          </div>
            +          <p>p5.Riso.js es una biblioteca para impresión de Risograph. Creada por:
            +            <a href="https://lav.io/"
            +              target="_blank">Sam Lavigne</a>, <a href="https://tegabrain.com/"
            +              target="_blank">Tega Brain</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://rednoise.org/rita" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/rita.js.jpg">
            +              <h3>rita.js</h3>
            +            </a>
            +          </div>
            +          <p>RiTa.js provee un conjunto de objetos de procesamiento de lenguaje natural para literatura generativa. Creada por:
            +            <a href="https://rednoise.org/daniel"
            +              target="_blank">Daniel C. Howe</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://codeforartists.com/RotatingKnobMaker" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/Rotating_knobs.jpg">
            +              <h3>Rotating knobs</h3>
            +            </a>
            +          </div>
            +          <p>Hacer perillas se puede girar con gráficos personalizados y volver rangos de valores Creada por:
            +            <a href="https://codeforartists.com"
            +              target="_blank">Miles DeCoster</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/mveteanu/p5.SceneManager" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.scenemanager.jpg">
            +              <h3>p5.scenemanager</h3>
            +            </a>
            +          </div>
            +          <p>p5.SceneManager te ayuda a crear bosquejos con múltiples estados / escenas. Cada escena es como un bosquejo dentro del bosquejo principal. Creada por:
            +            <a href="https://github.com/mveteanu/"
            +              target="_blank">Marian Veteanu</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bohnacker/p5js-screenPosition" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.screenPosition.jpg">
            +              <h3>p5.screenPosition</h3>
            +            </a>
            +          </div>
            +          <p>Agrega las variables screenX and screenY con las cordenadas del cursor en la pantalla. Creada por:
            +            <a href="https://hartmut-bohnacker.de/"
            +              target="_blank">Hartmut Bohnacker</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/generative-light/p5.scribble.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.scribble.jpg">
            +              <h3>p5.scribble</h3>
            +            </a>
            +          </div>
            +          <p>Dibujar primitivas 2D con una apariencia poco acabada. Creada por Janneck Wullschleger, basada en un puerto de la biblioteca original de Processing. Creada por:
            +            <a href="https://github.com/gicentre/handy"
            +              target="_blank">handy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/vanevery/p5.serialport" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.serial.jpg">
            +              <h3>p5.serial</h3>
            +            </a>
            +          </div>
            +          <p>p5.serial permite la comunicación serial entre dispositivos que soportan serial (RS-232) y bosquejos p5 corriendo en el navegador. Creada por:
            +            <a href="https://www.walking-productions.com/notslop/abou/"
            +              target="_blank">Shawn Van Every</a>, <a href="https://kaganjd.github.io/portfolio/"
            +              target="_blank">Jen Kagan</a>, <a href="https://tigoe.net/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/pfe1223/Shape5js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/Shape5.jpg">
            +              <h3>Shape5</h3>
            +            </a>
            +          </div>
            +          <p>Shape5 is a 2D primative library for elementary students who are learning to code for the first time. Creada por:
            +            <a href="https://github.com/pfe1223"
            +              target="_blank">Patrick Ester</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/gaba5/p5.shape.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.shape.js.jpg">
            +              <h3>p5.shape.js</h3>
            +            </a>
            +          </div>
            +          <p>Una biblioteca creada para agregar formas más simples al marco p5.js. Creada por:
            +            <a href="https://github.com/gaba5"
            +              target="_blank">Sebastien Lorentz</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-speech/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.speech.jpg">
            +              <h3>p5.speech</h3>
            +            </a>
            +          </div>
            +          <p>p5.speech provee acceso simple y claro a las APIs de Habla Web y Detección de Habla, permitiendo la creación de bosquejos sencillos que pueden hablar y escuchar. Creada por:
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/eltapir/p5.start2d.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.start2d.js.jpg">
            +              <h3>p5.start2d.js</h3>
            +            </a>
            +          </div>
            +          <p>extensión para p5 para crear gráficos 2D estáticos usnado px, mm, cm or inches Creada por:
            +            <a href="https://github.com/eltapir"
            +              target="_blank">Kris HEYSE</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/linux-man/p5.tiledmap" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.tiledmap.jpg">
            +              <h3>p5.tiledmap</h3>
            +            </a>
            +          </div>
            +          <p>p5.tiledmap provides drawing and helper functions to include maps in your sketches. Creada por:
            +            <a href="https://softlab.pt/"
            +              target="_blank">Caldas Lopes</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/L05/p5.touchgui" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.touchgui.jpg">
            +              <h3>p5.touchgui</h3>
            +            </a>
            +          </div>
            +          <p>Una biblioteca de interfaz gráfica de usuario (GUI) multi-tacto y para el ratón. Creada por:
            +            <a href="https://L05.is"
            +              target="_blank">Carlos L05 Garcia</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.tramontana.xyz" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/tramontana.jpg">
            +              <h3>tramontana</h3>
            +            </a>
            +          </div>
            +          <p>Tramontana es una platforma para utilizar múltiples dispositos (iOS, Android, tramontana Board, ...) para crear ambientes interactivos o prototipar experiencias a escala. Creada por:
            +            <a href="https://www.pierdr.com"
            +              target="_blank">Pierluigi Dalla Rosa</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/vida" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/vida.jpg">
            +              <h3>vida</h3>
            +            </a>
            +          </div>
            +          <p>Vida es una biblioteca simple que agrega detección de movimiento utilizando la camara y la función de seguimiento blob a p5js. Creada por:
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Dozed12/p5.voronoi" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.voronoi.jpg">
            +              <h3>p5.voronoi</h3>
            +            </a>
            +          </div>
            +          <p>p5.voronoi brinda un conjunto de herramientas para dibujar y utilizar diagramas voronoi en tus bosquejos de p5.js. Creada por:
            +            <a href="https://github.com/Dozed12"
            +              target="_blank">Francisco Moreira</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://p5xr.org/#/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.xr.jpg">
            +              <h3>p5.xr</h3>
            +            </a>
            +          </div>
            +          <p>Una biblioteca para crear bocetos VR y AR con p5. Creada por:
            +            <a href="https://www.stalgiagrigg.name/"
            +              target="_blank">Stalgia Grigg</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/FreddieRa/p5.3D" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.3D.jpg">
            +              <h3>p5.3D</h3>
            +            </a>
            +          </div>
            +          <p>Texto 3D e imágenes en WebGL.  Creada por:
            +            <a href="https://freddierawlins.wixsite.com/site"
            +              target="_blank">Freddie Rawlins</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/reference/assets/Bold.ttf b/dist/es/reference/assets/Bold.ttf
            new file mode 100644
            index 0000000000..50d81bdad5
            Binary files /dev/null and b/dist/es/reference/assets/Bold.ttf differ
            diff --git a/dist/es/reference/assets/Damscray.mp3 b/dist/es/reference/assets/Damscray.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/es/reference/assets/Damscray.mp3 differ
            diff --git a/dist/es/reference/assets/Damscray.ogg b/dist/es/reference/assets/Damscray.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/es/reference/assets/Damscray.ogg differ
            diff --git a/dist/es/reference/assets/Damscray_-_Dancing_Tiger_01.ogg b/dist/es/reference/assets/Damscray_-_Dancing_Tiger_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/es/reference/assets/Damscray_-_Dancing_Tiger_01.ogg differ
            diff --git a/dist/es/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 b/dist/es/reference/assets/Damscray_-_Dancing_Tiger_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/es/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 differ
            diff --git a/dist/es/reference/assets/Damscray_01.mp3 b/dist/es/reference/assets/Damscray_01.mp3
            new file mode 100644
            index 0000000000..9653a67bb6
            Binary files /dev/null and b/dist/es/reference/assets/Damscray_01.mp3 differ
            diff --git a/dist/es/reference/assets/Damscray_01.ogg b/dist/es/reference/assets/Damscray_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/es/reference/assets/Damscray_01.ogg differ
            diff --git a/dist/es/reference/assets/Damscray_02.mp3 b/dist/es/reference/assets/Damscray_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/es/reference/assets/Damscray_02.mp3 differ
            diff --git a/dist/es/reference/assets/Damscray_02.ogg b/dist/es/reference/assets/Damscray_02.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/es/reference/assets/Damscray_02.ogg differ
            diff --git a/dist/es/reference/assets/Damscray_DancingTiger.mp3 b/dist/es/reference/assets/Damscray_DancingTiger.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/es/reference/assets/Damscray_DancingTiger.mp3 differ
            diff --git a/dist/es/reference/assets/Italic.ttf b/dist/es/reference/assets/Italic.ttf
            new file mode 100644
            index 0000000000..e5a1a86e63
            Binary files /dev/null and b/dist/es/reference/assets/Italic.ttf differ
            diff --git a/dist/es/reference/assets/Regular.otf b/dist/es/reference/assets/Regular.otf
            new file mode 100644
            index 0000000000..38941ae72f
            Binary files /dev/null and b/dist/es/reference/assets/Regular.otf differ
            diff --git a/dist/es/reference/assets/arnott-wallace-eye-loop-forever.gif b/dist/es/reference/assets/arnott-wallace-eye-loop-forever.gif
            new file mode 100644
            index 0000000000..992757bbaf
            Binary files /dev/null and b/dist/es/reference/assets/arnott-wallace-eye-loop-forever.gif differ
            diff --git a/dist/es/reference/assets/arnott-wallace-wink-loop-once.gif b/dist/es/reference/assets/arnott-wallace-wink-loop-once.gif
            new file mode 100644
            index 0000000000..94f2015ff3
            Binary files /dev/null and b/dist/es/reference/assets/arnott-wallace-wink-loop-once.gif differ
            diff --git a/dist/es/reference/assets/beat.mp3 b/dist/es/reference/assets/beat.mp3
            new file mode 100644
            index 0000000000..3e5802604c
            Binary files /dev/null and b/dist/es/reference/assets/beat.mp3 differ
            diff --git a/dist/es/reference/assets/beat.ogg b/dist/es/reference/assets/beat.ogg
            new file mode 100644
            index 0000000000..c13f86a41f
            Binary files /dev/null and b/dist/es/reference/assets/beat.ogg differ
            diff --git a/dist/es/reference/assets/beatbox.mp3 b/dist/es/reference/assets/beatbox.mp3
            new file mode 100644
            index 0000000000..23fb92eb71
            Binary files /dev/null and b/dist/es/reference/assets/beatbox.mp3 differ
            diff --git a/dist/es/reference/assets/beatbox.ogg b/dist/es/reference/assets/beatbox.ogg
            new file mode 100644
            index 0000000000..b2593a6340
            Binary files /dev/null and b/dist/es/reference/assets/beatbox.ogg differ
            diff --git a/dist/es/reference/assets/blobs.csv b/dist/es/reference/assets/blobs.csv
            new file mode 100644
            index 0000000000..2b7f05d1a0
            --- /dev/null
            +++ b/dist/es/reference/assets/blobs.csv
            @@ -0,0 +1,3 @@
            +ID,Name,Flavor,Shape,Color
            +Blob1,Blobby,Sweet,Blob,Pink
            +Blob2,Saddy,Savory,Blob,Blue
            \ No newline at end of file
            diff --git a/dist/es/reference/assets/bricks.jpg b/dist/es/reference/assets/bricks.jpg
            new file mode 100644
            index 0000000000..231161d752
            Binary files /dev/null and b/dist/es/reference/assets/bricks.jpg differ
            diff --git a/dist/es/reference/assets/bricks_third.jpg b/dist/es/reference/assets/bricks_third.jpg
            new file mode 100644
            index 0000000000..2fdb075996
            Binary files /dev/null and b/dist/es/reference/assets/bricks_third.jpg differ
            diff --git a/dist/es/reference/assets/bx-spring.mp3 b/dist/es/reference/assets/bx-spring.mp3
            new file mode 100644
            index 0000000000..4a955ab7fa
            Binary files /dev/null and b/dist/es/reference/assets/bx-spring.mp3 differ
            diff --git a/dist/es/reference/assets/bx-spring.ogg b/dist/es/reference/assets/bx-spring.ogg
            new file mode 100644
            index 0000000000..b01abee927
            Binary files /dev/null and b/dist/es/reference/assets/bx-spring.ogg differ
            diff --git a/dist/es/reference/assets/concrete-tunnel.mp3 b/dist/es/reference/assets/concrete-tunnel.mp3
            new file mode 100644
            index 0000000000..1bfbd4f8f8
            Binary files /dev/null and b/dist/es/reference/assets/concrete-tunnel.mp3 differ
            diff --git a/dist/es/reference/assets/concrete-tunnel.ogg b/dist/es/reference/assets/concrete-tunnel.ogg
            new file mode 100644
            index 0000000000..be5f66b72c
            Binary files /dev/null and b/dist/es/reference/assets/concrete-tunnel.ogg differ
            diff --git a/dist/es/reference/assets/doorbell.mp3 b/dist/es/reference/assets/doorbell.mp3
            new file mode 100644
            index 0000000000..44b6367916
            Binary files /dev/null and b/dist/es/reference/assets/doorbell.mp3 differ
            diff --git a/dist/es/reference/assets/doorbell.ogg b/dist/es/reference/assets/doorbell.ogg
            new file mode 100644
            index 0000000000..e816288c97
            Binary files /dev/null and b/dist/es/reference/assets/doorbell.ogg differ
            diff --git a/dist/es/reference/assets/drawImage.png b/dist/es/reference/assets/drawImage.png
            new file mode 100644
            index 0000000000..1a7aa5d1d8
            Binary files /dev/null and b/dist/es/reference/assets/drawImage.png differ
            diff --git a/dist/es/reference/assets/drum.mp3 b/dist/es/reference/assets/drum.mp3
            new file mode 100644
            index 0000000000..9cd8727617
            Binary files /dev/null and b/dist/es/reference/assets/drum.mp3 differ
            diff --git a/dist/es/reference/assets/drum.ogg b/dist/es/reference/assets/drum.ogg
            new file mode 100644
            index 0000000000..5061a1b319
            Binary files /dev/null and b/dist/es/reference/assets/drum.ogg differ
            diff --git a/dist/es/reference/assets/favicon.ico b/dist/es/reference/assets/favicon.ico
            new file mode 100644
            index 0000000000..33ad9806c8
            Binary files /dev/null and b/dist/es/reference/assets/favicon.ico differ
            diff --git a/dist/es/reference/assets/fingers.mov b/dist/es/reference/assets/fingers.mov
            new file mode 100644
            index 0000000000..a9cbbbe3ea
            Binary files /dev/null and b/dist/es/reference/assets/fingers.mov differ
            diff --git a/dist/es/reference/assets/gradient.png b/dist/es/reference/assets/gradient.png
            new file mode 100644
            index 0000000000..5245af69cd
            Binary files /dev/null and b/dist/es/reference/assets/gradient.png differ
            diff --git a/dist/es/reference/assets/inconsolata.otf b/dist/es/reference/assets/inconsolata.otf
            new file mode 100644
            index 0000000000..e7e1fa0cd7
            Binary files /dev/null and b/dist/es/reference/assets/inconsolata.otf differ
            diff --git a/dist/es/reference/assets/index.html b/dist/es/reference/assets/index.html
            new file mode 100644
            index 0000000000..487fe15b2a
            --- /dev/null
            +++ b/dist/es/reference/assets/index.html
            @@ -0,0 +1,10 @@
            +<!doctype html>
            +<html>
            +    <head>
            +        <title>Redirector</title>
            +        <meta http-equiv="refresh" content="0;url=../">
            +    </head>
            +    <body>
            +        <a href="../">Click here to redirect</a>
            +    </body>
            +</html>
            diff --git a/dist/es/reference/assets/laDefense.jpg b/dist/es/reference/assets/laDefense.jpg
            new file mode 100644
            index 0000000000..3b8fdfe4b8
            Binary files /dev/null and b/dist/es/reference/assets/laDefense.jpg differ
            diff --git a/dist/es/reference/assets/large-dark-plate.mp3 b/dist/es/reference/assets/large-dark-plate.mp3
            new file mode 100644
            index 0000000000..b9a15cbed7
            Binary files /dev/null and b/dist/es/reference/assets/large-dark-plate.mp3 differ
            diff --git a/dist/es/reference/assets/large-dark-plate.ogg b/dist/es/reference/assets/large-dark-plate.ogg
            new file mode 100644
            index 0000000000..40115377e5
            Binary files /dev/null and b/dist/es/reference/assets/large-dark-plate.ogg differ
            diff --git a/dist/es/reference/assets/lucky_dragons.mp3 b/dist/es/reference/assets/lucky_dragons.mp3
            new file mode 100644
            index 0000000000..c54c70c01a
            Binary files /dev/null and b/dist/es/reference/assets/lucky_dragons.mp3 differ
            diff --git a/dist/es/reference/assets/lucky_dragons.ogg b/dist/es/reference/assets/lucky_dragons.ogg
            new file mode 100644
            index 0000000000..1e5b9e7abc
            Binary files /dev/null and b/dist/es/reference/assets/lucky_dragons.ogg differ
            diff --git a/dist/es/reference/assets/mammals.csv b/dist/es/reference/assets/mammals.csv
            new file mode 100644
            index 0000000000..549984e37e
            --- /dev/null
            +++ b/dist/es/reference/assets/mammals.csv
            @@ -0,0 +1,4 @@
            +id,species,name
            +0,Capra hircus,Goat
            +1,Panthera pardus,Leopard
            +2,Equus zebra,Zebra
            \ No newline at end of file
            diff --git a/dist/es/reference/assets/mammals.xml b/dist/es/reference/assets/mammals.xml
            new file mode 100644
            index 0000000000..752da754bf
            --- /dev/null
            +++ b/dist/es/reference/assets/mammals.xml
            @@ -0,0 +1,6 @@
            +<?xml version="1.0"?>
            +<mammals>
            +  <animal id="0" species="Capra hircus">Goat</animal>
            +  <animal id="1" species="Panthera pardus">Leopard</animal>
            +  <animal id="2" species="Equus zebra">Zebra</animal>
            +</mammals>
            \ No newline at end of file
            diff --git a/dist/es/reference/assets/mask.png b/dist/es/reference/assets/mask.png
            new file mode 100644
            index 0000000000..a6737489b9
            Binary files /dev/null and b/dist/es/reference/assets/mask.png differ
            diff --git a/dist/es/reference/assets/mask2.png b/dist/es/reference/assets/mask2.png
            new file mode 100644
            index 0000000000..2fb4aea99b
            Binary files /dev/null and b/dist/es/reference/assets/mask2.png differ
            diff --git a/dist/es/reference/assets/moonwalk.jpg b/dist/es/reference/assets/moonwalk.jpg
            new file mode 100644
            index 0000000000..c418e6f573
            Binary files /dev/null and b/dist/es/reference/assets/moonwalk.jpg differ
            diff --git a/dist/es/reference/assets/nancy-liang-wind-loop-forever.gif b/dist/es/reference/assets/nancy-liang-wind-loop-forever.gif
            new file mode 100644
            index 0000000000..a946253ede
            Binary files /dev/null and b/dist/es/reference/assets/nancy-liang-wind-loop-forever.gif differ
            diff --git a/dist/es/reference/assets/octahedron.obj b/dist/es/reference/assets/octahedron.obj
            new file mode 100644
            index 0000000000..fed774d32a
            --- /dev/null
            +++ b/dist/es/reference/assets/octahedron.obj
            @@ -0,0 +1,15 @@
            +v 0.000000E+00 0.000000E+00 40.0000
            +v 22.5000 22.5000 0.000000E+00
            +v 22.5000 -22.5000 0.000000E+00
            +v -22.5000 -22.5000 0.000000E+00
            +v -22.5000 22.5000 0.000000E+00
            +v 0.000000E+00 0.000000E+00 -40.0000
            +
            +f     1 2 3
            +f     1 3 4
            +f     1 4 5
            +f     1 5 2
            +f     6 5 4
            +f     6 4 3
            +f     6 3 2
            +f     6 2 5
            diff --git a/dist/es/reference/assets/rockies.jpg b/dist/es/reference/assets/rockies.jpg
            new file mode 100644
            index 0000000000..9bc0e4a372
            Binary files /dev/null and b/dist/es/reference/assets/rockies.jpg differ
            diff --git a/dist/es/reference/assets/rockies128.jpg b/dist/es/reference/assets/rockies128.jpg
            new file mode 100644
            index 0000000000..bf55d812b2
            Binary files /dev/null and b/dist/es/reference/assets/rockies128.jpg differ
            diff --git a/dist/es/reference/assets/shader-gradient.frag b/dist/es/reference/assets/shader-gradient.frag
            new file mode 100644
            index 0000000000..09a0cdc64b
            --- /dev/null
            +++ b/dist/es/reference/assets/shader-gradient.frag
            @@ -0,0 +1,22 @@
            +// Code adopted from "Creating a Gradient Color in Fragment Shader"
            +// by Bahadır on stackoverflow.com
            +// https://stackoverflow.com/questions/47376499/creating-a-gradient-color-in-fragment-shader
            +
            +
            +precision highp float; varying vec2 vPos;
            +uniform vec2 offset;
            +uniform vec3 colorCenter;
            +uniform vec3 colorBackground;
            +
            +void main() {
            +
            +  vec2 st = vPos.xy + offset.xy;
            +
            +  // color1 = vec3(1.0,0.55,0);
            +  // color2 = vec3(0.226,0.000,0.615);
            +
            +  float mixValue = distance(st,vec2(0,1));
            +  vec3 color = mix(colorCenter,colorBackground,mixValue);
            +
            +  gl_FragColor = vec4(color,mixValue);
            +}
            \ No newline at end of file
            diff --git a/dist/es/reference/assets/shader.frag b/dist/es/reference/assets/shader.frag
            new file mode 100644
            index 0000000000..d3d76eb77a
            --- /dev/null
            +++ b/dist/es/reference/assets/shader.frag
            @@ -0,0 +1,16 @@
            +precision highp float; varying vec2 vPos;
            +uniform vec2 p;
            +uniform float r;
            +const int I = 500;
            +void main() {
            +  vec2 c = p + vPos * r, z = c;
            +  float n = 0.0;
            +  for (int i = I; i > 0; i --) {
            +    if(z.x*z.x+z.y*z.y > 4.0) {
            +      n = float(i)/float(I);
            +      break;
            +    }
            +    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;
            +  }
            +  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);
            +}
            diff --git a/dist/es/reference/assets/shader.vert b/dist/es/reference/assets/shader.vert
            new file mode 100644
            index 0000000000..ea310c6770
            --- /dev/null
            +++ b/dist/es/reference/assets/shader.vert
            @@ -0,0 +1,3 @@
            +precision highp float; varying vec2 vPos;
            +attribute vec3 aPosition;
            +void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }
            diff --git a/dist/es/reference/assets/small-plate.mp3 b/dist/es/reference/assets/small-plate.mp3
            new file mode 100644
            index 0000000000..656e154a5f
            Binary files /dev/null and b/dist/es/reference/assets/small-plate.mp3 differ
            diff --git a/dist/es/reference/assets/small-plate.ogg b/dist/es/reference/assets/small-plate.ogg
            new file mode 100644
            index 0000000000..7b70d3349d
            Binary files /dev/null and b/dist/es/reference/assets/small-plate.ogg differ
            diff --git a/dist/es/reference/assets/small.mp4 b/dist/es/reference/assets/small.mp4
            new file mode 100644
            index 0000000000..1fc478842f
            Binary files /dev/null and b/dist/es/reference/assets/small.mp4 differ
            diff --git a/dist/es/reference/assets/small.ogv b/dist/es/reference/assets/small.ogv
            new file mode 100644
            index 0000000000..2b35a41aa4
            Binary files /dev/null and b/dist/es/reference/assets/small.ogv differ
            diff --git a/dist/es/reference/assets/small.webm b/dist/es/reference/assets/small.webm
            new file mode 100644
            index 0000000000..da946da529
            Binary files /dev/null and b/dist/es/reference/assets/small.webm differ
            diff --git a/dist/es/reference/assets/studio-b.mp3 b/dist/es/reference/assets/studio-b.mp3
            new file mode 100644
            index 0000000000..cbc792bfc9
            Binary files /dev/null and b/dist/es/reference/assets/studio-b.mp3 differ
            diff --git a/dist/es/reference/assets/studio-b.ogg b/dist/es/reference/assets/studio-b.ogg
            new file mode 100644
            index 0000000000..cd68db07e6
            Binary files /dev/null and b/dist/es/reference/assets/studio-b.ogg differ
            diff --git a/dist/es/reference/assets/teapot.obj b/dist/es/reference/assets/teapot.obj
            new file mode 100644
            index 0000000000..cedb196a4e
            --- /dev/null
            +++ b/dist/es/reference/assets/teapot.obj
            @@ -0,0 +1,4663 @@
            +# Blender v2.61 (sub 0) OBJ File: ''
            +# www.blender.org
            +v 0.605903 0.005903 -0.000000
            +v 0.000000 0.000000 0.000000
            +v 0.584584 0.005902 -0.162696
            +v 0.524218 0.005902 -0.307888
            +v 0.430191 0.005901 -0.430191
            +v 0.307888 0.005901 -0.524218
            +v 0.162696 0.005901 -0.584584
            +v 0.000000 0.005901 -0.605903
            +v -0.162696 0.005901 -0.584584
            +v -0.307888 0.005901 -0.524218
            +v -0.430191 0.005901 -0.430191
            +v -0.524218 0.005902 -0.307888
            +v -0.584584 0.005902 -0.162696
            +v -0.605903 0.005903 -0.000000
            +v -0.584584 0.005904 0.162696
            +v -0.524218 0.005904 0.307888
            +v -0.430191 0.005905 0.430191
            +v -0.307888 0.005905 0.524218
            +v -0.162696 0.005905 0.584584
            +v 0.000000 0.005905 0.605903
            +v 0.162696 0.005905 0.584584
            +v 0.307888 0.005905 0.524218
            +v 0.430191 0.005905 0.430191
            +v 0.524218 0.005904 0.307888
            +v 0.584584 0.005904 0.162696
            +v 1.400000 2.400000 -0.000008
            +v 1.350740 2.400000 0.375917
            +v 1.332760 2.454690 0.370913
            +v 1.381370 2.454690 -0.000009
            +v 1.384260 2.487500 -0.000009
            +v 1.335550 2.487500 0.371690
            +v 1.403120 2.498440 -0.000009
            +v 1.353760 2.498440 0.376756
            +v 1.382010 2.487500 0.384619
            +v 1.432410 2.487500 -0.000009
            +v 1.414950 2.454690 0.393787
            +v 1.466550 2.454690 -0.000009
            +v 1.447220 2.400000 0.402769
            +v 1.500000 2.400000 -0.000008
            +v 1.211260 2.400000 0.711398
            +v 1.195140 2.454690 0.701929
            +v 1.197640 2.487500 0.703400
            +v 1.213960 2.498440 0.712986
            +v 1.239300 2.487500 0.727866
            +v 1.268840 2.454690 0.745216
            +v 1.297780 2.400000 0.762213
            +v 0.994000 2.400000 0.993991
            +v 0.980770 2.454690 0.980761
            +v 0.982824 2.487500 0.982815
            +v 0.996219 2.498440 0.996210
            +v 1.017010 2.487500 1.017000
            +v 1.041250 2.454690 1.041240
            +v 1.065000 2.400000 1.064990
            +v 0.711407 2.400000 1.211250
            +v 0.701938 2.454690 1.195130
            +v 0.703409 2.487500 1.197630
            +v 0.712995 2.498440 1.213950
            +v 0.727875 2.487500 1.239290
            +v 0.745225 2.454690 1.268830
            +v 0.762222 2.400000 1.297770
            +v 0.375926 2.400010 1.350730
            +v 0.370922 2.454690 1.332750
            +v 0.371699 2.487500 1.335540
            +v 0.376765 2.498450 1.353750
            +v 0.384628 2.487500 1.382000
            +v 0.393796 2.454700 1.414940
            +v 0.402778 2.400010 1.447210
            +v 0.000000 2.400010 1.399990
            +v 0.000000 2.454690 1.381360
            +v 0.000000 2.487500 1.384250
            +v 0.000000 2.498450 1.403110
            +v 0.000000 2.487510 1.432400
            +v 0.000000 2.454700 1.466540
            +v 0.000000 2.400010 1.499990
            +v -0.375926 2.400010 1.350730
            +v -0.370922 2.454690 1.332750
            +v -0.371699 2.487500 1.335540
            +v -0.376765 2.498450 1.353750
            +v -0.384628 2.487500 1.382000
            +v -0.393796 2.454700 1.414940
            +v -0.402778 2.400010 1.447210
            +v -0.711407 2.400000 1.211250
            +v -0.701938 2.454690 1.195130
            +v -0.703409 2.487500 1.197630
            +v -0.712995 2.498440 1.213950
            +v -0.727875 2.487500 1.239290
            +v -0.745225 2.454690 1.268830
            +v -0.762222 2.400000 1.297770
            +v -0.994000 2.400000 0.993991
            +v -0.980770 2.454690 0.980761
            +v -0.982824 2.487500 0.982815
            +v -0.996219 2.498440 0.996210
            +v -1.017010 2.487500 1.017000
            +v -1.041250 2.454690 1.041240
            +v -1.065000 2.400000 1.064990
            +v -1.211260 2.400000 0.711398
            +v -1.195140 2.454690 0.701929
            +v -1.197640 2.487500 0.703400
            +v -1.213960 2.498440 0.712986
            +v -1.239300 2.487500 0.727866
            +v -1.268840 2.454690 0.745216
            +v -1.297780 2.400000 0.762213
            +v -1.350740 2.400000 0.375917
            +v -1.332760 2.454690 0.370913
            +v -1.335550 2.487500 0.371690
            +v -1.353760 2.498440 0.376756
            +v -1.382010 2.487500 0.384619
            +v -1.414950 2.454690 0.393787
            +v -1.447220 2.400000 0.402769
            +v -1.400000 2.400000 -0.000008
            +v -1.381370 2.454690 -0.000009
            +v -1.384260 2.487500 -0.000009
            +v -1.403120 2.498440 -0.000009
            +v -1.432410 2.487500 -0.000009
            +v -1.466550 2.454690 -0.000009
            +v -1.500000 2.400000 -0.000008
            +v -1.350740 2.400000 -0.375935
            +v -1.332760 2.454690 -0.370931
            +v -1.335550 2.487500 -0.371708
            +v -1.353760 2.498440 -0.376774
            +v -1.382010 2.487500 -0.384637
            +v -1.414950 2.454690 -0.393805
            +v -1.447220 2.400000 -0.402787
            +v -1.211260 2.400000 -0.711416
            +v -1.195140 2.454690 -0.701947
            +v -1.197640 2.487500 -0.703418
            +v -1.213960 2.498440 -0.713004
            +v -1.239300 2.487500 -0.727884
            +v -1.268840 2.454690 -0.745234
            +v -1.297780 2.400000 -0.762231
            +v -0.994000 2.400000 -0.994009
            +v -0.980770 2.454690 -0.980779
            +v -0.982824 2.487500 -0.982833
            +v -0.996219 2.498440 -0.996228
            +v -1.017010 2.487500 -1.017020
            +v -1.041250 2.454690 -1.041260
            +v -1.065000 2.400000 -1.065010
            +v -0.711407 2.400000 -1.211270
            +v -0.701938 2.454690 -1.195150
            +v -0.703409 2.487500 -1.197650
            +v -0.712995 2.498440 -1.213970
            +v -0.727875 2.487500 -1.239310
            +v -0.745225 2.454690 -1.268850
            +v -0.762222 2.400000 -1.297790
            +v -0.375926 2.400000 -1.350750
            +v -0.370922 2.454680 -1.332770
            +v -0.371699 2.487490 -1.335560
            +v -0.376765 2.498440 -1.353770
            +v -0.384628 2.487490 -1.382020
            +v -0.393796 2.454680 -1.414960
            +v -0.402778 2.399990 -1.447230
            +v 0.000000 2.399990 -1.400010
            +v 0.000000 2.454680 -1.381380
            +v 0.000000 2.487490 -1.384270
            +v 0.000000 2.498430 -1.403130
            +v 0.000000 2.487490 -1.432420
            +v 0.000000 2.454680 -1.466560
            +v 0.000000 2.399990 -1.500010
            +v 0.375926 2.400000 -1.350750
            +v 0.370922 2.454680 -1.332770
            +v 0.371699 2.487490 -1.335560
            +v 0.376765 2.498440 -1.353770
            +v 0.384628 2.487490 -1.382020
            +v 0.393796 2.454680 -1.414960
            +v 0.402778 2.399990 -1.447230
            +v 0.711407 2.400000 -1.211270
            +v 0.701938 2.454690 -1.195150
            +v 0.703409 2.487500 -1.197650
            +v 0.712995 2.498440 -1.213970
            +v 0.727875 2.487500 -1.239310
            +v 0.745225 2.454690 -1.268850
            +v 0.762222 2.400000 -1.297790
            +v 0.994000 2.400000 -0.994009
            +v 0.980770 2.454690 -0.980779
            +v 0.982824 2.487500 -0.982833
            +v 0.996219 2.498440 -0.996228
            +v 1.017010 2.487500 -1.017020
            +v 1.041250 2.454690 -1.041260
            +v 1.065000 2.400000 -1.065010
            +v 1.211260 2.400000 -0.711416
            +v 1.195140 2.454690 -0.701947
            +v 1.197640 2.487500 -0.703418
            +v 1.213960 2.498440 -0.713004
            +v 1.239300 2.487500 -0.727884
            +v 1.268840 2.454690 -0.745234
            +v 1.297780 2.400000 -0.762231
            +v 1.350740 2.400000 -0.375935
            +v 1.332760 2.454690 -0.370931
            +v 1.335550 2.487500 -0.371708
            +v 1.353760 2.498440 -0.376774
            +v 1.382010 2.487500 -0.384637
            +v 1.414950 2.454690 -0.393805
            +v 1.447220 2.400000 -0.402787
            +v 1.566710 2.137850 0.436024
            +v 1.623840 2.137850 -0.000008
            +v 1.679490 1.877780 0.467414
            +v 1.740740 1.877780 -0.000007
            +v 1.778880 1.621880 0.495075
            +v 1.843750 1.621870 -0.000006
            +v 1.858160 1.372220 0.517142
            +v 1.925930 1.372220 -0.000005
            +v 1.910650 1.130900 0.531750
            +v 1.980320 1.130900 -0.000004
            +v 1.929630 0.900002 0.537034
            +v 2.000000 0.900000 -0.000003
            +v 1.404920 2.137850 0.825145
            +v 1.506060 1.877780 0.884547
            +v 1.595190 1.621880 0.936892
            +v 1.666280 1.372220 0.978651
            +v 1.713350 1.130900 1.006300
            +v 1.730370 0.900004 1.016300
            +v 1.152930 2.137850 1.152920
            +v 1.235930 1.877780 1.235920
            +v 1.309060 1.621870 1.309050
            +v 1.367410 1.372230 1.367400
            +v 1.406030 1.130910 1.406030
            +v 1.420000 0.900005 1.420000
            +v 0.825153 2.137860 1.404910
            +v 0.884554 1.877790 1.506050
            +v 0.936898 1.621890 1.595180
            +v 0.978656 1.372230 1.666270
            +v 1.006300 1.130910 1.713350
            +v 1.016300 0.900006 1.730370
            +v 0.436032 2.137860 1.566700
            +v 0.467421 1.877790 1.679480
            +v 0.495081 1.621880 1.778870
            +v 0.517147 1.372230 1.858150
            +v 0.531754 1.130910 1.910650
            +v 0.537037 0.900007 1.929630
            +v 0.000000 2.137860 1.623830
            +v 0.000000 1.877790 1.740730
            +v 0.000000 1.621880 1.843740
            +v 0.000000 1.372230 1.925920
            +v 0.000000 1.130910 1.980320
            +v 0.000000 0.900007 2.000000
            +v -0.436032 2.137860 1.566700
            +v -0.467421 1.877790 1.679480
            +v -0.495081 1.621890 1.778870
            +v -0.517147 1.372230 1.858150
            +v -0.531754 1.130910 1.910650
            +v -0.537037 0.900007 1.929630
            +v -0.825153 2.137860 1.404910
            +v -0.884554 1.877790 1.506050
            +v -0.936898 1.621890 1.595180
            +v -0.978656 1.372230 1.666270
            +v -1.006300 1.130910 1.713350
            +v -1.016300 0.900006 1.730370
            +v -1.152930 2.137850 1.152920
            +v -1.235930 1.877780 1.235920
            +v -1.309060 1.621870 1.309050
            +v -1.367410 1.372230 1.367400
            +v -1.406030 1.130910 1.406030
            +v -1.420000 0.900005 1.420000
            +v -1.404920 2.137850 0.825145
            +v -1.506060 1.877780 0.884547
            +v -1.595190 1.621880 0.936892
            +v -1.666280 1.372220 0.978651
            +v -1.713350 1.130900 1.006300
            +v -1.730370 0.900004 1.016300
            +v -1.566710 2.137850 0.436024
            +v -1.679490 1.877780 0.467414
            +v -1.778880 1.621870 0.495075
            +v -1.858160 1.372220 0.517142
            +v -1.910650 1.130900 0.531750
            +v -1.929630 0.900002 0.537034
            +v -1.623840 2.137850 -0.000008
            +v -1.740740 1.877780 -0.000007
            +v -1.843750 1.621870 -0.000006
            +v -1.925930 1.372220 -0.000005
            +v -1.980320 1.130900 -0.000004
            +v -2.000000 0.900000 -0.000003
            +v -1.566710 2.137850 -0.436040
            +v -1.679490 1.877780 -0.467428
            +v -1.778880 1.621880 -0.495087
            +v -1.858160 1.372220 -0.517152
            +v -1.910650 1.130900 -0.531758
            +v -1.929630 0.899998 -0.537040
            +v -1.404920 2.137850 -0.825161
            +v -1.506060 1.877780 -0.884561
            +v -1.595190 1.621880 -0.936904
            +v -1.666280 1.372220 -0.978661
            +v -1.713350 1.130900 -1.006300
            +v -1.730370 0.899996 -1.016300
            +v -1.152930 2.137850 -1.152940
            +v -1.235930 1.877780 -1.235940
            +v -1.309060 1.621870 -1.309070
            +v -1.367410 1.372220 -1.367420
            +v -1.406030 1.130890 -1.406030
            +v -1.420000 0.899995 -1.420000
            +v -0.825153 2.137840 -1.404930
            +v -0.884554 1.877770 -1.506070
            +v -0.936898 1.621870 -1.595200
            +v -0.978656 1.372210 -1.666290
            +v -1.006300 1.130890 -1.713350
            +v -1.016300 0.899994 -1.730370
            +v -0.436032 2.137840 -1.566720
            +v -0.467421 1.877770 -1.679500
            +v -0.495081 1.621860 -1.778890
            +v -0.517147 1.372210 -1.858170
            +v -0.531754 1.130890 -1.910650
            +v -0.537037 0.899993 -1.929630
            +v 0.000000 2.137840 -1.623850
            +v 0.000000 1.877770 -1.740750
            +v 0.000000 1.621860 -1.843760
            +v 0.000000 1.372210 -1.925940
            +v 0.000000 1.130890 -1.980320
            +v 0.000000 0.899993 -2.000000
            +v 0.436032 2.137840 -1.566720
            +v 0.467421 1.877770 -1.679500
            +v 0.495081 1.621870 -1.778890
            +v 0.517147 1.372210 -1.858170
            +v 0.531754 1.130890 -1.910650
            +v 0.537037 0.899993 -1.929630
            +v 0.825153 2.137840 -1.404930
            +v 0.884554 1.877770 -1.506070
            +v 0.936898 1.621870 -1.595200
            +v 0.978656 1.372210 -1.666290
            +v 1.006300 1.130890 -1.713350
            +v 1.016300 0.899994 -1.730370
            +v 1.152930 2.137850 -1.152940
            +v 1.235930 1.877780 -1.235940
            +v 1.309060 1.621870 -1.309070
            +v 1.367410 1.372220 -1.367420
            +v 1.406030 1.130890 -1.406030
            +v 1.420000 0.899995 -1.420000
            +v 1.404920 2.137850 -0.825161
            +v 1.506060 1.877780 -0.884561
            +v 1.595190 1.621880 -0.936904
            +v 1.666280 1.372220 -0.978661
            +v 1.713350 1.130900 -1.006300
            +v 1.730370 0.899996 -1.016300
            +v 1.566710 2.137850 -0.436040
            +v 1.679490 1.877780 -0.467428
            +v 1.778880 1.621870 -0.495087
            +v 1.858160 1.372220 -0.517152
            +v 1.910650 1.130900 -0.531758
            +v 1.929630 0.899998 -0.537040
            +v 1.893900 0.693405 0.527089
            +v 1.962960 0.693403 -0.000002
            +v 1.804560 0.522224 0.502227
            +v 1.870370 0.522222 -0.000002
            +v 1.688430 0.384377 0.469906
            +v 1.750000 0.384375 -0.000001
            +v 1.572290 0.277780 0.437585
            +v 1.629630 0.277778 -0.000001
            +v 1.482960 0.200349 0.412722
            +v 1.537040 0.200347 -0.000001
            +v 1.447220 0.150001 0.402777
            +v 1.500000 0.150000 -0.000001
            +v 1.698330 0.693407 0.997473
            +v 1.618220 0.522225 0.950423
            +v 1.514070 0.384378 0.889258
            +v 1.409930 0.277781 0.828092
            +v 1.329820 0.200350 0.781042
            +v 1.297780 0.150003 0.762221
            +v 1.393700 0.693408 1.393700
            +v 1.327960 0.522227 1.327960
            +v 1.242500 0.384380 1.242500
            +v 1.157040 0.277782 1.157040
            +v 1.091300 0.200351 1.091300
            +v 1.065000 0.150004 1.065000
            +v 0.997476 0.693409 1.698330
            +v 0.950425 0.522228 1.618220
            +v 0.889259 0.384381 1.514070
            +v 0.828093 0.277783 1.409930
            +v 0.781043 0.200352 1.329820
            +v 0.762222 0.150005 1.297780
            +v 0.527092 0.693410 1.893900
            +v 0.502229 0.522229 1.804560
            +v 0.469907 0.384381 1.688430
            +v 0.437586 0.277784 1.572290
            +v 0.412723 0.200352 1.482960
            +v 0.402778 0.150005 1.447220
            +v 0.000000 0.693410 1.962960
            +v 0.000000 0.522229 1.870370
            +v 0.000000 0.384381 1.750000
            +v 0.000000 0.277784 1.629630
            +v 0.000000 0.200353 1.537040
            +v 0.000000 0.150006 1.500000
            +v -0.527092 0.693410 1.893900
            +v -0.502229 0.522229 1.804560
            +v -0.469907 0.384381 1.688430
            +v -0.437586 0.277784 1.572290
            +v -0.412723 0.200352 1.482960
            +v -0.402778 0.150005 1.447220
            +v -0.997476 0.693409 1.698330
            +v -0.950425 0.522228 1.618220
            +v -0.889259 0.384381 1.514070
            +v -0.828093 0.277783 1.409930
            +v -0.781043 0.200352 1.329820
            +v -0.762222 0.150005 1.297780
            +v -1.393700 0.693408 1.393700
            +v -1.327960 0.522227 1.327960
            +v -1.242500 0.384380 1.242500
            +v -1.157040 0.277782 1.157040
            +v -1.091300 0.200351 1.091300
            +v -1.065000 0.150004 1.065000
            +v -1.698330 0.693407 0.997473
            +v -1.618220 0.522225 0.950423
            +v -1.514070 0.384378 0.889258
            +v -1.409930 0.277781 0.828092
            +v -1.329820 0.200350 0.781042
            +v -1.297780 0.150003 0.762221
            +v -1.893900 0.693405 0.527089
            +v -1.804560 0.522224 0.502227
            +v -1.688430 0.384377 0.469906
            +v -1.572290 0.277780 0.437585
            +v -1.482960 0.200349 0.412722
            +v -1.447220 0.150001 0.402777
            +v -1.962960 0.693403 -0.000002
            +v -1.870370 0.522222 -0.000002
            +v -1.750000 0.384375 -0.000001
            +v -1.629630 0.277778 -0.000001
            +v -1.537040 0.200347 -0.000001
            +v -1.500000 0.150000 -0.000001
            +v -1.893900 0.693401 -0.527095
            +v -1.804560 0.522220 -0.502231
            +v -1.688430 0.384373 -0.469908
            +v -1.572290 0.277776 -0.437587
            +v -1.482960 0.200345 -0.412724
            +v -1.447220 0.149999 -0.402779
            +v -1.698330 0.693399 -0.997479
            +v -1.618220 0.522218 -0.950427
            +v -1.514070 0.384372 -0.889260
            +v -1.409930 0.277775 -0.828094
            +v -1.329820 0.200344 -0.781044
            +v -1.297780 0.149997 -0.762223
            +v -1.393700 0.693398 -1.393700
            +v -1.327960 0.522217 -1.327960
            +v -1.242500 0.384370 -1.242500
            +v -1.157040 0.277774 -1.157040
            +v -1.091300 0.200343 -1.091300
            +v -1.065000 0.149996 -1.065000
            +v -0.997476 0.693397 -1.698330
            +v -0.950425 0.522216 -1.618220
            +v -0.889259 0.384369 -1.514070
            +v -0.828093 0.277773 -1.409930
            +v -0.781043 0.200342 -1.329820
            +v -0.762222 0.149995 -1.297780
            +v -0.527092 0.693396 -1.893900
            +v -0.502229 0.522215 -1.804560
            +v -0.469907 0.384369 -1.688430
            +v -0.437586 0.277772 -1.572290
            +v -0.412723 0.200342 -1.482960
            +v -0.402778 0.149995 -1.447220
            +v 0.000000 0.693396 -1.962960
            +v 0.000000 0.522215 -1.870370
            +v 0.000000 0.384369 -1.750000
            +v 0.000000 0.277772 -1.629630
            +v 0.000000 0.200341 -1.537040
            +v 0.000000 0.149994 -1.500000
            +v 0.527092 0.693396 -1.893900
            +v 0.502229 0.522215 -1.804560
            +v 0.469907 0.384369 -1.688430
            +v 0.437586 0.277772 -1.572290
            +v 0.412723 0.200342 -1.482960
            +v 0.402778 0.149995 -1.447220
            +v 0.997476 0.693397 -1.698330
            +v 0.950425 0.522216 -1.618220
            +v 0.889259 0.384369 -1.514070
            +v 0.828093 0.277773 -1.409930
            +v 0.781043 0.200342 -1.329820
            +v 0.762222 0.149995 -1.297780
            +v 1.393700 0.693398 -1.393700
            +v 1.327960 0.522217 -1.327960
            +v 1.242500 0.384370 -1.242500
            +v 1.157040 0.277774 -1.157040
            +v 1.091300 0.200343 -1.091300
            +v 1.065000 0.149996 -1.065000
            +v 1.698330 0.693399 -0.997479
            +v 1.618220 0.522218 -0.950427
            +v 1.514070 0.384372 -0.889260
            +v 1.409930 0.277775 -0.828094
            +v 1.329820 0.200344 -0.781044
            +v 1.297780 0.149997 -0.762223
            +v 1.893900 0.693401 -0.527095
            +v 1.804560 0.522220 -0.502231
            +v 1.688430 0.384373 -0.469908
            +v 1.572290 0.277776 -0.437587
            +v 1.482960 0.200345 -0.412724
            +v 1.447220 0.149999 -0.402779
            +v 1.022220 0.022222 -0.000000
            +v 0.986255 0.022221 -0.274486
            +v 1.284370 0.046875 -0.000000
            +v 1.239180 0.046874 -0.344878
            +v 1.427780 0.077778 -0.000000
            +v 1.377540 0.077777 -0.383385
            +v 1.487850 0.112847 -0.000000
            +v 1.435500 0.112846 -0.399515
            +v 0.884412 0.022220 -0.519440
            +v 1.111220 0.046873 -0.652653
            +v 1.235290 0.077775 -0.725523
            +v 1.287260 0.112844 -0.756047
            +v 0.725778 0.022219 -0.725778
            +v 0.911906 0.046872 -0.911906
            +v 1.013720 0.077774 -1.013720
            +v 1.056370 0.112843 -1.056370
            +v 0.519440 0.022219 -0.884412
            +v 0.652653 0.046871 -1.111220
            +v 0.725523 0.077774 -1.235290
            +v 0.756047 0.112842 -1.287260
            +v 0.274486 0.022219 -0.986255
            +v 0.344878 0.046871 -1.239180
            +v 0.383385 0.077773 -1.377540
            +v 0.399515 0.112842 -1.435500
            +v 0.000000 0.022218 -1.022220
            +v 0.000000 0.046871 -1.284370
            +v 0.000000 0.077773 -1.427780
            +v 0.000000 0.112842 -1.487850
            +v -0.274486 0.022219 -0.986255
            +v -0.344878 0.046871 -1.239180
            +v -0.383385 0.077773 -1.377540
            +v -0.399515 0.112842 -1.435500
            +v -0.519440 0.022219 -0.884412
            +v -0.652653 0.046871 -1.111220
            +v -0.725523 0.077774 -1.235290
            +v -0.756047 0.112842 -1.287260
            +v -0.725778 0.022219 -0.725778
            +v -0.911906 0.046872 -0.911906
            +v -1.013720 0.077774 -1.013720
            +v -1.056370 0.112843 -1.056370
            +v -0.884412 0.022220 -0.519440
            +v -1.111220 0.046873 -0.652653
            +v -1.235290 0.077775 -0.725523
            +v -1.287260 0.112844 -0.756047
            +v -0.986255 0.022221 -0.274486
            +v -1.239180 0.046874 -0.344878
            +v -1.377540 0.077777 -0.383385
            +v -1.435500 0.112846 -0.399515
            +v -1.022220 0.022222 -0.000000
            +v -1.284370 0.046875 -0.000000
            +v -1.427780 0.077778 -0.000000
            +v -1.487850 0.112847 -0.000000
            +v -0.986255 0.022223 0.274486
            +v -1.239180 0.046876 0.344878
            +v -1.377540 0.077779 0.383385
            +v -1.435500 0.112848 0.399515
            +v -0.884412 0.022224 0.519440
            +v -1.111220 0.046877 0.652653
            +v -1.235290 0.077781 0.725523
            +v -1.287260 0.112850 0.756047
            +v -0.725778 0.022225 0.725778
            +v -0.911906 0.046878 0.911906
            +v -1.013720 0.077782 1.013720
            +v -1.056370 0.112851 1.056370
            +v -0.519440 0.022225 0.884412
            +v -0.652653 0.046879 1.111220
            +v -0.725523 0.077782 1.235290
            +v -0.756047 0.112852 1.287260
            +v -0.274486 0.022225 0.986255
            +v -0.344878 0.046879 1.239180
            +v -0.383385 0.077783 1.377540
            +v -0.399515 0.112852 1.435500
            +v 0.000000 0.022226 1.022220
            +v 0.000000 0.046879 1.284370
            +v 0.000000 0.077783 1.427780
            +v 0.000000 0.112852 1.487850
            +v 0.274486 0.022225 0.986255
            +v 0.344878 0.046879 1.239180
            +v 0.383385 0.077783 1.377540
            +v 0.399515 0.112852 1.435500
            +v 0.519440 0.022225 0.884412
            +v 0.652653 0.046879 1.111220
            +v 0.725523 0.077782 1.235290
            +v 0.756047 0.112852 1.287260
            +v 0.725778 0.022225 0.725778
            +v 0.911906 0.046878 0.911906
            +v 1.013720 0.077782 1.013720
            +v 1.056370 0.112851 1.056370
            +v 0.884412 0.022224 0.519440
            +v 1.111220 0.046877 0.652653
            +v 1.235290 0.077781 0.725523
            +v 1.287260 0.112850 0.756047
            +v 0.986255 0.022223 0.274486
            +v 1.239180 0.046876 0.344878
            +v 1.377540 0.077779 0.383385
            +v 1.435500 0.112848 0.399515
            +v 0.192963 2.700000 0.053694
            +v 0.200000 2.700000 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.173037 2.700000 0.101620
            +v 0.148234 2.785420 0.087096
            +v 0.142000 2.700000 0.141990
            +v 0.121672 2.785420 0.121662
            +v 0.101630 2.700000 0.173027
            +v 0.087106 2.785420 0.148224
            +v 0.053704 2.700000 0.192953
            +v 0.046045 2.785420 0.165269
            +v 0.000000 2.700000 0.199990
            +v 0.000000 2.785420 0.171286
            +v -0.053704 2.700000 0.192953
            +v -0.046045 2.785420 0.165269
            +v -0.101630 2.700000 0.173027
            +v -0.087106 2.785420 0.148224
            +v -0.142000 2.700000 0.141990
            +v -0.121672 2.785420 0.121662
            +v -0.173037 2.700000 0.101620
            +v -0.148234 2.785420 0.087096
            +v -0.192963 2.700000 0.053694
            +v -0.165279 2.785420 0.046035
            +v -0.200000 2.700000 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.192963 2.700000 -0.053714
            +v -0.165279 2.785420 -0.046055
            +v -0.173037 2.700000 -0.101640
            +v -0.148234 2.785420 -0.087116
            +v -0.142000 2.700000 -0.142010
            +v -0.121672 2.785420 -0.121682
            +v -0.101630 2.700000 -0.173047
            +v -0.087106 2.785420 -0.148244
            +v -0.053704 2.700000 -0.192973
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 2.700000 -0.200010
            +v 0.000000 2.785420 -0.171306
            +v 0.053704 2.700000 -0.192973
            +v 0.046045 2.785420 -0.165289
            +v 0.101630 2.700000 -0.173047
            +v 0.087106 2.785420 -0.148244
            +v 0.142000 2.700000 -0.142010
            +v 0.121672 2.785420 -0.121682
            +v 0.173037 2.700000 -0.101640
            +v 0.148234 2.785420 -0.087116
            +v 0.192963 2.700000 -0.053714
            +v 0.165279 2.785420 -0.046055
            +v 0.338579 2.636110 0.094221
            +v 0.350926 2.636110 -0.000009
            +v 0.553875 2.588890 0.154140
            +v 0.574074 2.588890 -0.000009
            +v 0.795972 2.550000 0.221519
            +v 0.825000 2.550000 -0.000009
            +v 1.021990 2.511110 0.284422
            +v 1.059260 2.511110 -0.000009
            +v 1.189040 2.463890 0.330915
            +v 1.232410 2.463890 -0.000009
            +v 1.254260 2.400000 0.349065
            +v 1.300000 2.400000 -0.000008
            +v 0.303616 2.636110 0.178312
            +v 0.496680 2.588890 0.291705
            +v 0.713778 2.550000 0.419213
            +v 0.916455 2.511110 0.538252
            +v 1.066260 2.463890 0.626237
            +v 1.124740 2.400000 0.660584
            +v 0.249157 2.636110 0.249147
            +v 0.407593 2.588890 0.407583
            +v 0.585750 2.550000 0.585741
            +v 0.752074 2.511110 0.752065
            +v 0.875009 2.463890 0.875000
            +v 0.923000 2.400000 0.922991
            +v 0.178322 2.636110 0.303606
            +v 0.291715 2.588890 0.496670
            +v 0.419222 2.550000 0.713769
            +v 0.538261 2.511110 0.916446
            +v 0.626246 2.463890 1.066250
            +v 0.660593 2.400000 1.124730
            +v 0.094230 2.636110 0.338569
            +v 0.154150 2.588890 0.553865
            +v 0.221528 2.550000 0.795963
            +v 0.284431 2.511110 1.021980
            +v 0.330924 2.463890 1.189030
            +v 0.349074 2.400000 1.254250
            +v 0.000000 2.636110 0.350916
            +v 0.000000 2.588890 0.574064
            +v 0.000000 2.550000 0.824991
            +v 0.000000 2.511110 1.059250
            +v 0.000000 2.463890 1.232400
            +v 0.000000 2.400000 1.299990
            +v -0.094230 2.636110 0.338569
            +v -0.154150 2.588890 0.553865
            +v -0.221528 2.550000 0.795963
            +v -0.284431 2.511110 1.021980
            +v -0.330924 2.463890 1.189030
            +v -0.349074 2.400000 1.254250
            +v -0.178322 2.636110 0.303606
            +v -0.291715 2.588890 0.496670
            +v -0.419222 2.550000 0.713769
            +v -0.538261 2.511110 0.916446
            +v -0.626246 2.463890 1.066250
            +v -0.660593 2.400000 1.124730
            +v -0.249157 2.636110 0.249147
            +v -0.407593 2.588890 0.407583
            +v -0.585750 2.550000 0.585741
            +v -0.752074 2.511110 0.752065
            +v -0.875009 2.463890 0.875000
            +v -0.923000 2.400000 0.922991
            +v -0.303616 2.636110 0.178312
            +v -0.496680 2.588890 0.291705
            +v -0.713778 2.550000 0.419213
            +v -0.916455 2.511110 0.538252
            +v -1.066260 2.463890 0.626237
            +v -1.124740 2.400000 0.660584
            +v -0.338579 2.636110 0.094221
            +v -0.553875 2.588890 0.154140
            +v -0.795972 2.550000 0.221519
            +v -1.021990 2.511110 0.284422
            +v -1.189040 2.463890 0.330915
            +v -1.254260 2.400000 0.349065
            +v -0.350926 2.636110 -0.000009
            +v -0.574074 2.588890 -0.000009
            +v -0.825000 2.550000 -0.000009
            +v -1.059260 2.511110 -0.000009
            +v -1.232410 2.463890 -0.000009
            +v -1.300000 2.400000 -0.000008
            +v -0.338579 2.636110 -0.094239
            +v -0.553875 2.588890 -0.154160
            +v -0.795972 2.550000 -0.221537
            +v -1.021990 2.511110 -0.284440
            +v -1.189040 2.463890 -0.330933
            +v -1.254260 2.400000 -0.349083
            +v -0.303616 2.636110 -0.178332
            +v -0.496680 2.588890 -0.291725
            +v -0.713778 2.550000 -0.419231
            +v -0.916455 2.511110 -0.538270
            +v -1.066260 2.463890 -0.626255
            +v -1.124740 2.400000 -0.660602
            +v -0.249157 2.636110 -0.249167
            +v -0.407593 2.588890 -0.407603
            +v -0.585750 2.550000 -0.585759
            +v -0.752074 2.511110 -0.752083
            +v -0.875009 2.463890 -0.875018
            +v -0.923000 2.400000 -0.923009
            +v -0.178322 2.636110 -0.303626
            +v -0.291715 2.588890 -0.496690
            +v -0.419222 2.550000 -0.713787
            +v -0.538261 2.511110 -0.916464
            +v -0.626246 2.463890 -1.066270
            +v -0.660593 2.400000 -1.124750
            +v -0.094230 2.636110 -0.338589
            +v -0.154150 2.588890 -0.553885
            +v -0.221528 2.550000 -0.795981
            +v -0.284431 2.511110 -1.022000
            +v -0.330924 2.463890 -1.189050
            +v -0.349074 2.400000 -1.254270
            +v 0.000000 2.636110 -0.350936
            +v 0.000000 2.588890 -0.574084
            +v 0.000000 2.550000 -0.825009
            +v 0.000000 2.511110 -1.059270
            +v 0.000000 2.463890 -1.232420
            +v 0.000000 2.400000 -1.300010
            +v 0.094230 2.636110 -0.338589
            +v 0.154150 2.588890 -0.553885
            +v 0.221528 2.550000 -0.795981
            +v 0.284431 2.511110 -1.022000
            +v 0.330924 2.463890 -1.189050
            +v 0.349074 2.400000 -1.254270
            +v 0.178322 2.636110 -0.303626
            +v 0.291715 2.588890 -0.496690
            +v 0.419222 2.550000 -0.713787
            +v 0.538261 2.511110 -0.916464
            +v 0.626246 2.463890 -1.066270
            +v 0.660593 2.400000 -1.124750
            +v 0.249157 2.636110 -0.249167
            +v 0.407593 2.588890 -0.407603
            +v 0.585750 2.550000 -0.585759
            +v 0.752074 2.511110 -0.752083
            +v 0.875009 2.463890 -0.875018
            +v 0.923000 2.400000 -0.923009
            +v 0.303616 2.636110 -0.178332
            +v 0.496680 2.588890 -0.291725
            +v 0.713778 2.550000 -0.419231
            +v 0.916455 2.511110 -0.538270
            +v 1.066260 2.463890 -0.626255
            +v 1.124740 2.400000 -0.660602
            +v 0.338579 2.636110 -0.094239
            +v 0.553875 2.588890 -0.154160
            +v 0.795972 2.550000 -0.221537
            +v 1.021990 2.511110 -0.284440
            +v 1.189040 2.463890 -0.330933
            +v 1.254260 2.400000 -0.349083
            +v -1.924540 2.023960 -0.000007
            +v -1.600000 2.025000 -0.000007
            +v -1.927040 2.040550 0.124992
            +v -1.592590 2.041670 0.124992
            +v -2.196300 2.016670 -0.000007
            +v -2.206450 2.032720 0.124992
            +v -2.428240 2.011460 0.124993
            +v -2.412500 1.996870 -0.000007
            +v -2.589850 1.970060 0.124993
            +v -2.570370 1.958330 -0.000007
            +v -2.688700 1.901810 0.124993
            +v -2.667130 1.894790 -0.000007
            +v -2.722220 1.800000 0.124993
            +v -2.700000 1.800000 -0.000006
            +v -1.933300 2.082020 0.199992
            +v -1.574070 2.083330 0.199992
            +v -2.231820 2.072840 0.199992
            +v -2.467590 2.047920 0.199992
            +v -2.638550 1.999380 0.199993
            +v -2.742630 1.919370 0.199993
            +v -2.777780 1.800000 0.199993
            +v -1.941440 2.135940 0.224992
            +v -1.550000 2.137500 0.224992
            +v -2.264810 2.125000 0.224992
            +v -2.518750 2.095310 0.224992
            +v -2.701850 2.037500 0.224992
            +v -2.812730 1.942190 0.224993
            +v -2.850000 1.800000 0.224993
            +v -1.949570 2.189850 0.199992
            +v -1.525930 2.191670 0.199992
            +v -2.297810 2.177160 0.199992
            +v -2.569910 2.142710 0.199992
            +v -2.765160 2.075620 0.199992
            +v -2.882840 1.965010 0.199993
            +v -2.922220 1.800000 0.199993
            +v -1.955830 2.231330 0.124992
            +v -1.507410 2.233330 0.124992
            +v -2.323180 2.217280 0.124992
            +v -2.609260 2.179170 0.124992
            +v -2.813850 2.104940 0.124992
            +v -2.936760 1.982560 0.124993
            +v -2.977780 1.800000 0.124993
            +v -1.958330 2.247920 -0.000008
            +v -1.500000 2.250000 -0.000008
            +v -2.333330 2.233330 -0.000008
            +v -2.625000 2.193750 -0.000008
            +v -2.833330 2.116670 -0.000007
            +v -2.958330 1.989580 -0.000007
            +v -3.000000 1.800000 -0.000006
            +v -1.507410 2.233330 -0.125008
            +v -1.955830 2.231330 -0.125008
            +v -2.323180 2.217280 -0.125008
            +v -2.609260 2.179170 -0.125008
            +v -2.813850 2.104940 -0.125008
            +v -2.936760 1.982560 -0.125007
            +v -2.977780 1.800000 -0.125007
            +v -1.525930 2.191670 -0.200008
            +v -1.949570 2.189850 -0.200008
            +v -2.297810 2.177160 -0.200008
            +v -2.569910 2.142710 -0.200008
            +v -2.765160 2.075620 -0.200008
            +v -2.882840 1.965010 -0.200007
            +v -2.922220 1.800000 -0.200007
            +v -1.550000 2.137500 -0.225008
            +v -1.941440 2.135940 -0.225008
            +v -2.264810 2.125000 -0.225008
            +v -2.518750 2.095310 -0.225008
            +v -2.701850 2.037500 -0.225008
            +v -2.812730 1.942190 -0.225007
            +v -2.850000 1.800000 -0.225007
            +v -1.574070 2.083330 -0.200008
            +v -1.933300 2.082020 -0.200008
            +v -2.231820 2.072840 -0.200008
            +v -2.467590 2.047920 -0.200008
            +v -2.638550 1.999380 -0.200007
            +v -2.742630 1.919370 -0.200007
            +v -2.777780 1.800000 -0.200007
            +v -1.592590 2.041670 -0.125008
            +v -1.927040 2.040550 -0.125008
            +v -2.206450 2.032720 -0.125008
            +v -2.428240 2.011460 -0.125007
            +v -2.589850 1.970060 -0.125007
            +v -2.688700 1.901810 -0.125007
            +v -2.722220 1.800000 -0.125007
            +v -2.704180 1.663980 0.124994
            +v -2.682870 1.670830 -0.000006
            +v -2.648290 1.505350 0.124994
            +v -2.629630 1.516670 -0.000005
            +v -2.551850 1.335760 0.124995
            +v -2.537500 1.350000 -0.000005
            +v -2.412210 1.166870 0.124996
            +v -2.403700 1.183330 -0.000004
            +v -2.226680 1.010330 0.124996
            +v -2.225460 1.029170 -0.000004
            +v -1.992590 0.877778 0.124997
            +v -2.000000 0.900000 -0.000003
            +v -2.757470 1.646840 0.199994
            +v -2.694920 1.477060 0.199995
            +v -2.587730 1.300170 0.199995
            +v -2.433470 1.125720 0.199996
            +v -2.229720 0.963228 0.199996
            +v -1.974070 0.822223 0.199997
            +v -2.826740 1.624570 0.224994
            +v -2.755560 1.440280 0.224995
            +v -2.634370 1.253910 0.224995
            +v -2.461110 1.072220 0.224996
            +v -2.233680 0.901998 0.224997
            +v -1.950000 0.750001 0.224997
            +v -2.896000 1.602290 0.199994
            +v -2.816190 1.403500 0.199995
            +v -2.681020 1.207640 0.199996
            +v -2.488750 1.018720 0.199996
            +v -2.237640 0.840767 0.199997
            +v -1.925930 0.677779 0.199997
            +v -2.949290 1.585150 0.124994
            +v -2.862830 1.375210 0.124995
            +v -2.716900 1.172050 0.124996
            +v -2.510010 0.977573 0.124996
            +v -2.240680 0.793666 0.124997
            +v -1.907410 0.622222 0.124998
            +v -2.970600 1.578300 -0.000006
            +v -2.881480 1.363890 -0.000005
            +v -2.731250 1.157810 -0.000004
            +v -2.518520 0.961111 -0.000003
            +v -2.241900 0.774826 -0.000003
            +v -1.900000 0.600000 -0.000002
            +v -2.949290 1.585150 -0.125006
            +v -2.862830 1.375210 -0.125005
            +v -2.716900 1.172050 -0.125004
            +v -2.510010 0.977572 -0.125004
            +v -2.240680 0.793666 -0.125003
            +v -1.907410 0.622222 -0.125002
            +v -2.896000 1.602290 -0.200006
            +v -2.816190 1.403500 -0.200005
            +v -2.681020 1.207640 -0.200004
            +v -2.488750 1.018720 -0.200004
            +v -2.237640 0.840765 -0.200003
            +v -1.925930 0.677777 -0.200003
            +v -2.826740 1.624570 -0.225006
            +v -2.755560 1.440280 -0.225005
            +v -2.634370 1.253910 -0.225005
            +v -2.461110 1.072220 -0.225004
            +v -2.233680 0.901996 -0.225003
            +v -1.950000 0.749999 -0.225003
            +v -2.757470 1.646840 -0.200006
            +v -2.694920 1.477060 -0.200005
            +v -2.587730 1.300170 -0.200005
            +v -2.433470 1.125720 -0.200004
            +v -2.229720 0.963226 -0.200004
            +v -1.974070 0.822221 -0.200003
            +v -2.704180 1.663980 -0.125006
            +v -2.648290 1.505350 -0.125006
            +v -2.551850 1.335760 -0.125005
            +v -2.412210 1.166870 -0.125004
            +v -2.226680 1.010330 -0.125004
            +v -1.992590 0.877778 -0.125003
            +v 1.700000 1.425000 -0.000005
            +v 1.700000 1.363890 0.274995
            +v 2.072380 1.425210 0.262341
            +v 2.058800 1.476390 -0.000005
            +v 2.290120 1.572020 0.230704
            +v 2.270370 1.611110 -0.000006
            +v 2.409720 1.773610 0.189576
            +v 2.387500 1.800000 -0.000006
            +v 2.487650 1.999280 0.148450
            +v 2.462960 2.013890 -0.000007
            +v 2.580400 2.218310 0.116813
            +v 2.549540 2.223610 -0.000008
            +v 2.700000 2.400000 -0.000008
            +v 2.744440 2.400000 0.104158
            +v 1.700000 1.211110 0.439996
            +v 2.106330 1.297250 0.419748
            +v 2.339510 1.474280 0.369131
            +v 2.465280 1.707640 0.303327
            +v 2.549380 1.962760 0.237524
            +v 2.657560 2.205070 0.186906
            +v 2.855560 2.400000 0.166658
            +v 1.700000 1.012500 0.494996
            +v 2.150460 1.130900 0.472218
            +v 2.403700 1.347220 0.415273
            +v 2.537500 1.621870 0.341244
            +v 2.629630 1.915280 0.267215
            +v 2.757870 2.187850 0.210270
            +v 3.000000 2.400000 0.187491
            +v 1.700000 0.813891 0.439997
            +v 2.194600 0.964560 0.419749
            +v 2.467900 1.220160 0.369132
            +v 2.609720 1.536110 0.303327
            +v 2.709880 1.867800 0.237524
            +v 2.858180 2.170630 0.186906
            +v 3.144440 2.400000 0.166658
            +v 1.700000 0.661112 0.274998
            +v 2.228550 0.836601 0.262343
            +v 2.517280 1.122430 0.230706
            +v 2.665280 1.470140 0.189578
            +v 2.771600 1.831280 0.148450
            +v 2.935340 2.157380 0.116813
            +v 3.255560 2.400000 0.104158
            +v 1.700000 0.600000 -0.000002
            +v 2.242130 0.785417 -0.000003
            +v 2.537040 1.083330 -0.000004
            +v 2.687500 1.443750 -0.000005
            +v 2.796300 1.816670 -0.000006
            +v 2.966200 2.152080 -0.000008
            +v 3.300000 2.400000 -0.000008
            +v 1.700000 0.661110 -0.275002
            +v 2.228550 0.836599 -0.262349
            +v 2.517280 1.122430 -0.230714
            +v 2.665280 1.470140 -0.189588
            +v 2.771600 1.831280 -0.148464
            +v 2.935340 2.157380 -0.116829
            +v 3.255560 2.400000 -0.104176
            +v 1.700000 0.813887 -0.440003
            +v 2.194600 0.964556 -0.419757
            +v 2.467900 1.220160 -0.369141
            +v 2.609720 1.536110 -0.303339
            +v 2.709880 1.867800 -0.237538
            +v 2.858180 2.170630 -0.186922
            +v 3.144440 2.400000 -0.166676
            +v 1.700000 1.012500 -0.495004
            +v 2.150460 1.130900 -0.472226
            +v 2.403700 1.347220 -0.415283
            +v 2.537500 1.621870 -0.341256
            +v 2.629630 1.915280 -0.267229
            +v 2.757870 2.187850 -0.210286
            +v 3.000000 2.400000 -0.187509
            +v 1.700000 1.211110 -0.440004
            +v 2.106330 1.297250 -0.419758
            +v 2.339510 1.474280 -0.369141
            +v 2.465280 1.707640 -0.303339
            +v 2.549380 1.962760 -0.237538
            +v 2.657560 2.205070 -0.186922
            +v 2.855560 2.400000 -0.166676
            +v 1.700000 1.363890 -0.275005
            +v 2.072380 1.425210 -0.262351
            +v 2.290120 1.572020 -0.230716
            +v 2.409720 1.773610 -0.189590
            +v 2.487650 1.999280 -0.148464
            +v 2.580400 2.218310 -0.116829
            +v 2.744440 2.400000 -0.104176
            +v 2.749070 2.431250 -0.000009
            +v 2.796410 2.431930 0.101023
            +v 2.792590 2.450000 -0.000009
            +v 2.839780 2.451230 0.092969
            +v 2.825000 2.456250 -0.000009
            +v 2.869680 2.457810 0.082022
            +v 2.881210 2.451540 0.070207
            +v 2.840740 2.450000 -0.000009
            +v 2.869490 2.432310 0.059549
            +v 2.834260 2.431250 -0.000009
            +v 2.829630 2.400000 0.052074
            +v 2.800000 2.400000 -0.000008
            +v 2.914740 2.433610 0.161565
            +v 2.957750 2.454320 0.148139
            +v 2.981370 2.461720 0.129158
            +v 2.982370 2.455400 0.107398
            +v 2.957560 2.434960 0.085639
            +v 2.903700 2.400000 0.066658
            +v 3.068580 2.435810 0.181675
            +v 3.111110 2.458330 0.165963
            +v 3.126560 2.466800 0.142960
            +v 3.113890 2.460420 0.115269
            +v 3.072050 2.438410 0.085495
            +v 3.000000 2.400000 0.056241
            +v 3.222410 2.438000 0.161411
            +v 3.264470 2.462350 0.146905
            +v 3.271760 2.471870 0.124991
            +v 3.245400 2.465430 0.097522
            +v 3.186540 2.441860 0.066349
            +v 3.096300 2.400000 0.033324
            +v 3.340750 2.439690 0.100830
            +v 3.382440 2.465430 0.091426
            +v 3.383450 2.475780 0.076814
            +v 3.346570 2.469290 0.057861
            +v 3.274610 2.444510 0.035437
            +v 3.170370 2.400000 0.010408
            +v 3.388080 2.440360 -0.000009
            +v 3.429630 2.466670 -0.000009
            +v 3.428130 2.477340 -0.000009
            +v 3.387040 2.470830 -0.000009
            +v 3.309840 2.445570 -0.000009
            +v 3.200000 2.400000 -0.000008
            +v 3.340750 2.439690 -0.101089
            +v 3.382440 2.465430 -0.093373
            +v 3.383450 2.475780 -0.083342
            +v 3.346570 2.469290 -0.073312
            +v 3.274610 2.444510 -0.065595
            +v 3.170370 2.400000 -0.062509
            +v 3.222410 2.438000 -0.161737
            +v 3.264470 2.462350 -0.149392
            +v 3.271760 2.471870 -0.133342
            +v 3.245400 2.465430 -0.117293
            +v 3.186540 2.441860 -0.104947
            +v 3.096300 2.400000 -0.100009
            +v 3.068580 2.435810 -0.181953
            +v 3.111110 2.458330 -0.168065
            +v 3.126560 2.466800 -0.150009
            +v 3.113890 2.460420 -0.131953
            +v 3.072050 2.438410 -0.118065
            +v 3.000000 2.400000 -0.112509
            +v 2.914740 2.433610 -0.161737
            +v 2.957750 2.454320 -0.149392
            +v 2.981370 2.461720 -0.133342
            +v 2.982370 2.455400 -0.117293
            +v 2.957560 2.434960 -0.104947
            +v 2.903700 2.400000 -0.100009
            +v 2.796410 2.431930 -0.101089
            +v 2.839780 2.451230 -0.093373
            +v 2.869680 2.457810 -0.083342
            +v 2.881210 2.451540 -0.073312
            +v 2.869490 2.432310 -0.065595
            +v 2.829630 2.400000 -0.062509
            +v 0.278704 3.127080 -0.000011
            +v 0.000000 3.150000 -0.000011
            +v 0.268946 3.127080 0.075067
            +v 0.241285 3.127080 0.141920
            +v 0.198140 3.127080 0.198129
            +v 0.141931 3.127080 0.241274
            +v 0.075078 3.127080 0.268935
            +v 0.000000 3.127080 0.278693
            +v -0.075078 3.127080 0.268935
            +v -0.141931 3.127080 0.241274
            +v -0.198140 3.127080 0.198129
            +v -0.241285 3.127080 0.141920
            +v -0.268946 3.127080 0.075067
            +v -0.278704 3.127080 -0.000011
            +v -0.268946 3.127080 -0.075089
            +v -0.241285 3.127080 -0.141942
            +v -0.198140 3.127080 -0.198151
            +v -0.141931 3.127080 -0.241296
            +v -0.075078 3.127080 -0.268957
            +v 0.000000 3.127080 -0.278715
            +v 0.075078 3.127080 -0.268957
            +v 0.141931 3.127080 -0.241296
            +v 0.198140 3.127080 -0.198151
            +v 0.241285 3.127080 -0.141942
            +v 0.268946 3.127080 -0.075089
            +v 0.350254 3.066670 0.097760
            +v 0.362963 3.066670 -0.000011
            +v 0.313617 2.981250 0.087518
            +v 0.325000 2.981250 -0.000011
            +v 0.228728 2.883330 0.063793
            +v 0.237037 2.883330 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.314228 3.066670 0.184824
            +v 0.281352 2.981250 0.165470
            +v 0.205180 2.883330 0.120636
            +v 0.148234 2.785420 0.087096
            +v 0.258037 3.066670 0.258027
            +v 0.231031 2.981250 0.231020
            +v 0.168463 2.883330 0.168452
            +v 0.121672 2.785420 0.121662
            +v 0.184834 3.066670 0.314218
            +v 0.165481 2.981250 0.281341
            +v 0.120647 2.883330 0.205169
            +v 0.087106 2.785420 0.148224
            +v 0.097771 3.066670 0.350244
            +v 0.087529 2.981250 0.313606
            +v 0.063803 2.883330 0.228717
            +v 0.046045 2.785420 0.165269
            +v 0.000000 3.066670 0.362953
            +v 0.000000 2.981250 0.324989
            +v 0.000000 2.883330 0.237026
            +v 0.000000 2.785420 0.171286
            +v -0.097771 3.066670 0.350244
            +v -0.087529 2.981250 0.313606
            +v -0.063803 2.883330 0.228717
            +v -0.046045 2.785420 0.165269
            +v -0.184834 3.066670 0.314218
            +v -0.165481 2.981250 0.281341
            +v -0.120647 2.883330 0.205169
            +v -0.087106 2.785420 0.148224
            +v -0.258037 3.066670 0.258027
            +v -0.231031 2.981250 0.231020
            +v -0.168463 2.883330 0.168452
            +v -0.121672 2.785420 0.121662
            +v -0.314228 3.066670 0.184824
            +v -0.281352 2.981250 0.165470
            +v -0.205180 2.883330 0.120636
            +v -0.148234 2.785420 0.087096
            +v -0.350254 3.066670 0.097760
            +v -0.313617 2.981250 0.087518
            +v -0.228728 2.883330 0.063793
            +v -0.165279 2.785420 0.046035
            +v -0.362963 3.066670 -0.000011
            +v -0.325000 2.981250 -0.000011
            +v -0.237037 2.883330 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.350254 3.066670 -0.097782
            +v -0.313617 2.981250 -0.087540
            +v -0.228728 2.883330 -0.063813
            +v -0.165279 2.785420 -0.046055
            +v -0.314228 3.066670 -0.184844
            +v -0.281352 2.981250 -0.165492
            +v -0.205180 2.883330 -0.120658
            +v -0.148234 2.785420 -0.087116
            +v -0.258037 3.066670 -0.258047
            +v -0.231031 2.981250 -0.231042
            +v -0.168463 2.883330 -0.168474
            +v -0.121672 2.785420 -0.121682
            +v -0.184834 3.066670 -0.314238
            +v -0.165481 2.981250 -0.281363
            +v -0.120647 2.883330 -0.205191
            +v -0.087106 2.785420 -0.148244
            +v -0.097771 3.066670 -0.350264
            +v -0.087529 2.981250 -0.313628
            +v -0.063803 2.883330 -0.228739
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 3.066670 -0.362973
            +v 0.000000 2.981250 -0.325011
            +v 0.000000 2.883330 -0.237048
            +v 0.000000 2.785420 -0.171306
            +v 0.097771 3.066670 -0.350264
            +v 0.087529 2.981250 -0.313628
            +v 0.063803 2.883330 -0.228739
            +v 0.046045 2.785420 -0.165289
            +v 0.184834 3.066670 -0.314238
            +v 0.165481 2.981250 -0.281363
            +v 0.120647 2.883330 -0.205191
            +v 0.087106 2.785420 -0.148244
            +v 0.258037 3.066670 -0.258047
            +v 0.231031 2.981250 -0.231042
            +v 0.168463 2.883330 -0.168474
            +v 0.121672 2.785420 -0.121682
            +v 0.314228 3.066670 -0.184844
            +v 0.281352 2.981250 -0.165492
            +v 0.205180 2.883330 -0.120658
            +v 0.148234 2.785420 -0.087116
            +v 0.350254 3.066670 -0.097782
            +v 0.313617 2.981250 -0.087540
            +v 0.228728 2.883330 -0.063813
            +v 0.165279 2.785420 -0.046055
            +vn 0.025666 -0.999664 0.000000
            +vn 0.000000 -1.000000 0.000000
            +vn 0.024781 -0.999664 -0.006623
            +vn 0.022156 -0.999664 -0.012787
            +vn 0.018067 -0.999664 -0.018067
            +vn 0.012787 -0.999664 -0.022126
            +vn 0.006623 -0.999664 -0.024751
            +vn 0.000000 -0.999664 -0.025666
            +vn -0.006623 -0.999664 -0.024751
            +vn -0.012787 -0.999664 -0.022126
            +vn -0.018067 -0.999664 -0.018067
            +vn -0.022156 -0.999664 -0.012787
            +vn -0.024781 -0.999664 -0.006623
            +vn -0.025666 -0.999664 0.000000
            +vn -0.024781 -0.999664 0.006623
            +vn -0.022156 -0.999664 0.012787
            +vn -0.018067 -0.999664 0.018067
            +vn -0.012787 -0.999664 0.022156
            +vn -0.006623 -0.999664 0.024781
            +vn 0.000000 -0.999664 0.025666
            +vn 0.006623 -0.999664 0.024781
            +vn 0.012787 -0.999664 0.022156
            +vn 0.018067 -0.999664 0.018067
            +vn 0.022156 -0.999664 0.012787
            +vn 0.024781 -0.999664 0.006623
            +vn -0.946562 -0.322459 0.000000
            +vn -0.913999 -0.322947 -0.245491
            +vn -0.958617 -0.122227 -0.257057
            +vn -0.992523 -0.122013 0.000000
            +vn -0.832057 0.554674 0.000000
            +vn -0.803217 0.555376 -0.215308
            +vn -0.048616 0.998810 0.000000
            +vn -0.046205 0.998840 -0.012726
            +vn 0.525376 0.839106 0.140843
            +vn 0.544267 0.838893 0.000000
            +vn 0.756340 0.621845 0.202918
            +vn 0.783471 0.621387 0.000000
            +vn 0.850551 0.473769 0.228217
            +vn 0.880886 0.473281 0.000000
            +vn -0.818842 -0.323435 -0.474166
            +vn -0.859004 -0.122410 -0.497085
            +vn -0.719657 0.555559 -0.416425
            +vn -0.041749 0.998810 -0.024415
            +vn 0.470107 0.839625 0.272011
            +vn 0.677236 0.622608 0.391980
            +vn 0.761803 0.474471 0.440962
            +vn -0.669027 -0.323679 -0.669027
            +vn -0.701773 -0.122440 -0.701773
            +vn -0.587878 0.555650 -0.587878
            +vn -0.034272 0.998810 -0.034272
            +vn 0.383831 0.839808 0.383831
            +vn 0.553148 0.622913 0.553148
            +vn 0.622303 0.474776 0.622303
            +vn -0.474166 -0.323435 -0.818842
            +vn -0.497085 -0.122410 -0.859004
            +vn -0.416425 0.555528 -0.719657
            +vn -0.024415 0.998810 -0.041749
            +vn 0.272011 0.839625 0.470077
            +vn 0.392010 0.622608 0.677236
            +vn 0.440962 0.474502 0.761803
            +vn -0.245460 -0.322977 -0.913999
            +vn -0.257057 -0.122257 -0.958617
            +vn -0.215339 0.555193 -0.803308
            +vn -0.012726 0.998840 -0.046236
            +vn 0.140873 0.839076 0.525437
            +vn 0.202918 0.621906 0.756310
            +vn 0.228217 0.473769 0.850551
            +vn 0.000000 -0.322489 -0.946562
            +vn 0.000000 -0.122044 -0.992523
            +vn 0.000000 0.554491 -0.832179
            +vn 0.000000 0.998779 -0.048799
            +vn 0.000000 0.838893 0.544267
            +vn 0.000000 0.621387 0.783471
            +vn 0.000000 0.473281 0.880886
            +vn 0.245460 -0.322977 -0.913999
            +vn 0.257057 -0.122257 -0.958617
            +vn 0.215339 0.555193 -0.803308
            +vn 0.012726 0.998840 -0.046236
            +vn -0.140873 0.839076 0.525437
            +vn -0.202918 0.621906 0.756310
            +vn -0.228217 0.473769 0.850551
            +vn 0.474166 -0.323435 -0.818842
            +vn 0.497085 -0.122410 -0.859004
            +vn 0.416425 0.555528 -0.719657
            +vn 0.024415 0.998810 -0.041749
            +vn -0.272011 0.839625 0.470077
            +vn -0.392010 0.622608 0.677236
            +vn -0.440962 0.474502 0.761803
            +vn 0.669027 -0.323679 -0.669027
            +vn 0.701773 -0.122440 -0.701773
            +vn 0.587878 0.555650 -0.587878
            +vn 0.034272 0.998810 -0.034272
            +vn -0.383831 0.839808 0.383831
            +vn -0.553148 0.622913 0.553148
            +vn -0.622303 0.474776 0.622303
            +vn 0.818842 -0.323435 -0.474166
            +vn 0.859004 -0.122410 -0.497085
            +vn 0.719657 0.555559 -0.416425
            +vn 0.041749 0.998810 -0.024415
            +vn -0.470107 0.839625 0.272011
            +vn -0.677236 0.622608 0.391980
            +vn -0.761803 0.474471 0.440962
            +vn 0.913999 -0.322947 -0.245491
            +vn 0.958617 -0.122227 -0.257057
            +vn 0.803217 0.555376 -0.215308
            +vn 0.046205 0.998840 -0.012726
            +vn -0.525376 0.839106 0.140843
            +vn -0.756340 0.621845 0.202918
            +vn -0.850551 0.473769 0.228217
            +vn 0.946562 -0.322459 0.000000
            +vn 0.992523 -0.122013 0.000000
            +vn 0.832057 0.554674 0.000000
            +vn 0.048616 0.998810 0.000000
            +vn -0.544267 0.838893 0.000000
            +vn -0.783471 0.621387 0.000000
            +vn -0.880886 0.473281 0.000000
            +vn 0.913999 -0.322947 0.245491
            +vn 0.958617 -0.122227 0.257057
            +vn 0.803217 0.555376 0.215308
            +vn 0.046205 0.998840 0.012726
            +vn -0.525376 0.839106 -0.140843
            +vn -0.756340 0.621845 -0.202918
            +vn -0.850551 0.473769 -0.228217
            +vn 0.818842 -0.323435 0.474166
            +vn 0.859004 -0.122410 0.497085
            +vn 0.719657 0.555559 0.416425
            +vn 0.041749 0.998810 0.024415
            +vn -0.470107 0.839625 -0.272011
            +vn -0.677236 0.622608 -0.391980
            +vn -0.761803 0.474471 -0.440962
            +vn 0.669027 -0.323679 0.669027
            +vn 0.701773 -0.122440 0.701773
            +vn 0.587878 0.555650 0.587878
            +vn 0.034272 0.998810 0.034272
            +vn -0.383831 0.839808 -0.383831
            +vn -0.553148 0.622913 -0.553148
            +vn -0.622303 0.474776 -0.622303
            +vn 0.474166 -0.323435 0.818842
            +vn 0.497085 -0.122410 0.859004
            +vn 0.416425 0.555559 0.719657
            +vn 0.024415 0.998810 0.041749
            +vn -0.272011 0.839625 -0.470107
            +vn -0.391980 0.622608 -0.677236
            +vn -0.440962 0.474471 -0.761803
            +vn 0.245460 -0.322977 0.913999
            +vn 0.257027 -0.122257 0.958617
            +vn 0.215369 0.555193 0.803308
            +vn 0.012726 0.998840 0.046236
            +vn -0.140873 0.839045 -0.525498
            +vn -0.202918 0.621845 -0.756371
            +vn -0.228187 0.473769 -0.850551
            +vn 0.000000 -0.322459 0.946562
            +vn 0.000000 -0.122013 0.992523
            +vn 0.000000 0.554674 0.832057
            +vn 0.000000 0.998810 0.048616
            +vn 0.000000 0.838893 -0.544267
            +vn 0.000000 0.621387 -0.783471
            +vn 0.000000 0.473281 -0.880886
            +vn -0.245460 -0.322977 0.913999
            +vn -0.257027 -0.122257 0.958617
            +vn -0.215369 0.555193 0.803308
            +vn -0.012726 0.998840 0.046236
            +vn 0.140873 0.839045 -0.525498
            +vn 0.202918 0.621845 -0.756371
            +vn 0.228187 0.473769 -0.850551
            +vn -0.474166 -0.323435 0.818842
            +vn -0.497085 -0.122410 0.859004
            +vn -0.416425 0.555559 0.719657
            +vn -0.024415 0.998810 0.041749
            +vn 0.272011 0.839625 -0.470107
            +vn 0.391980 0.622608 -0.677236
            +vn 0.440962 0.474471 -0.761803
            +vn -0.669027 -0.323679 0.669027
            +vn -0.701773 -0.122440 0.701773
            +vn -0.587878 0.555650 0.587878
            +vn -0.034272 0.998810 0.034272
            +vn 0.383831 0.839808 -0.383831
            +vn 0.553148 0.622913 -0.553148
            +vn 0.622303 0.474776 -0.622303
            +vn -0.818842 -0.323435 0.474166
            +vn -0.859004 -0.122410 0.497085
            +vn -0.719657 0.555559 0.416425
            +vn -0.041749 0.998810 0.024415
            +vn 0.470107 0.839625 -0.272011
            +vn 0.677236 0.622608 -0.391980
            +vn 0.761803 0.474471 -0.440962
            +vn -0.913999 -0.322947 0.245491
            +vn -0.958617 -0.122227 0.257057
            +vn -0.803217 0.555376 0.215308
            +vn -0.046205 0.998840 0.012726
            +vn 0.525376 0.839106 -0.140843
            +vn 0.756340 0.621845 -0.202918
            +vn 0.850551 0.473769 -0.228217
            +vn 0.877041 0.418744 0.235298
            +vn 0.908292 0.418256 0.000000
            +vn 0.888668 0.391644 0.238441
            +vn 0.920286 0.391156 0.000000
            +vn 0.907315 0.342753 0.243446
            +vn 0.939543 0.342357 0.000000
            +vn 0.931028 0.265908 0.249855
            +vn 0.964080 0.265542 0.000000
            +vn 0.954558 0.152104 0.256172
            +vn 0.988372 0.151891 0.000000
            +vn 0.964782 -0.045717 0.258980
            +vn 0.998932 -0.045656 0.000000
            +vn 0.785638 0.419416 0.454756
            +vn 0.796075 0.392285 0.460799
            +vn 0.812830 0.343333 0.470504
            +vn 0.834162 0.266366 0.482864
            +vn 0.855312 0.152409 0.495132
            +vn 0.864498 -0.045808 0.500504
            +vn 0.641804 0.419691 0.641804
            +vn 0.650349 0.392529 0.650349
            +vn 0.664052 0.343577 0.664052
            +vn 0.681509 0.266579 0.681509
            +vn 0.698813 0.152501 0.698813
            +vn 0.706351 -0.045869 0.706351
            +vn 0.454756 0.419416 0.785638
            +vn 0.460799 0.392285 0.796075
            +vn 0.470504 0.343333 0.812830
            +vn 0.482864 0.266396 0.834162
            +vn 0.495132 0.152409 0.855312
            +vn 0.500504 -0.045808 0.864498
            +vn 0.235298 0.418744 0.877041
            +vn 0.238441 0.391644 0.888668
            +vn 0.243446 0.342753 0.907315
            +vn 0.249825 0.265908 0.931028
            +vn 0.256172 0.152135 0.954558
            +vn 0.258980 -0.045717 0.964782
            +vn 0.000000 0.418256 0.908292
            +vn 0.000000 0.391156 0.920286
            +vn 0.000000 0.342357 0.939543
            +vn 0.000000 0.265572 0.964080
            +vn 0.000000 0.151921 0.988372
            +vn 0.000000 -0.045656 0.998932
            +vn -0.235298 0.418744 0.877041
            +vn -0.238441 0.391644 0.888668
            +vn -0.243446 0.342753 0.907315
            +vn -0.249825 0.265908 0.931028
            +vn -0.256172 0.152135 0.954558
            +vn -0.258980 -0.045717 0.964782
            +vn -0.454756 0.419416 0.785638
            +vn -0.460799 0.392285 0.796075
            +vn -0.470504 0.343333 0.812830
            +vn -0.482864 0.266396 0.834162
            +vn -0.495132 0.152409 0.855312
            +vn -0.500504 -0.045808 0.864498
            +vn -0.641804 0.419691 0.641804
            +vn -0.650349 0.392529 0.650349
            +vn -0.664052 0.343577 0.664052
            +vn -0.681509 0.266579 0.681509
            +vn -0.698813 0.152501 0.698813
            +vn -0.706351 -0.045869 0.706351
            +vn -0.785638 0.419416 0.454756
            +vn -0.796075 0.392285 0.460799
            +vn -0.812830 0.343333 0.470504
            +vn -0.834162 0.266366 0.482864
            +vn -0.855312 0.152409 0.495132
            +vn -0.864498 -0.045808 0.500504
            +vn -0.877041 0.418744 0.235298
            +vn -0.888668 0.391644 0.238441
            +vn -0.907315 0.342753 0.243446
            +vn -0.931028 0.265908 0.249825
            +vn -0.954558 0.152104 0.256172
            +vn -0.964782 -0.045717 0.258980
            +vn -0.908292 0.418256 0.000000
            +vn -0.920286 0.391156 0.000000
            +vn -0.939543 0.342357 0.000000
            +vn -0.964080 0.265542 0.000000
            +vn -0.988372 0.151891 0.000000
            +vn -0.998932 -0.045656 0.000000
            +vn -0.877041 0.418744 -0.235298
            +vn -0.888668 0.391644 -0.238441
            +vn -0.907315 0.342753 -0.243446
            +vn -0.931028 0.265877 -0.249855
            +vn -0.954558 0.152104 -0.256172
            +vn -0.964782 -0.045717 -0.258980
            +vn -0.785638 0.419416 -0.454756
            +vn -0.796075 0.392285 -0.460799
            +vn -0.812830 0.343333 -0.470504
            +vn -0.834162 0.266366 -0.482864
            +vn -0.855312 0.152379 -0.495132
            +vn -0.864498 -0.045808 -0.500504
            +vn -0.641804 0.419691 -0.641804
            +vn -0.650349 0.392529 -0.650349
            +vn -0.664052 0.343547 -0.664052
            +vn -0.681509 0.266549 -0.681509
            +vn -0.698813 0.152470 -0.698813
            +vn -0.706351 -0.045869 -0.706351
            +vn -0.454756 0.419416 -0.785638
            +vn -0.460768 0.392285 -0.796075
            +vn -0.470504 0.343333 -0.812830
            +vn -0.482864 0.266366 -0.834162
            +vn -0.495132 0.152379 -0.855312
            +vn -0.500504 -0.045808 -0.864498
            +vn -0.235298 0.418744 -0.877041
            +vn -0.238441 0.391644 -0.888668
            +vn -0.243446 0.342753 -0.907315
            +vn -0.249855 0.265877 -0.931059
            +vn -0.256172 0.152074 -0.954558
            +vn -0.258980 -0.045717 -0.964782
            +vn 0.000000 0.418256 -0.908292
            +vn 0.000000 0.391156 -0.920286
            +vn 0.000000 0.342357 -0.939543
            +vn 0.000000 0.265511 -0.964080
            +vn 0.000000 0.151891 -0.988372
            +vn 0.000000 -0.045656 -0.998932
            +vn 0.235298 0.418744 -0.877041
            +vn 0.238441 0.391644 -0.888668
            +vn 0.243446 0.342753 -0.907315
            +vn 0.249855 0.265877 -0.931059
            +vn 0.256172 0.152074 -0.954558
            +vn 0.258980 -0.045717 -0.964782
            +vn 0.454756 0.419416 -0.785638
            +vn 0.460768 0.392285 -0.796075
            +vn 0.470504 0.343333 -0.812830
            +vn 0.482864 0.266366 -0.834162
            +vn 0.495132 0.152379 -0.855312
            +vn 0.500504 -0.045808 -0.864498
            +vn 0.641804 0.419691 -0.641804
            +vn 0.650349 0.392529 -0.650349
            +vn 0.664052 0.343547 -0.664052
            +vn 0.681509 0.266549 -0.681509
            +vn 0.698813 0.152470 -0.698813
            +vn 0.706351 -0.045869 -0.706351
            +vn 0.785638 0.419416 -0.454756
            +vn 0.796075 0.392285 -0.460799
            +vn 0.812830 0.343333 -0.470504
            +vn 0.834162 0.266366 -0.482864
            +vn 0.855312 0.152379 -0.495132
            +vn 0.864498 -0.045808 -0.500504
            +vn 0.877041 0.418744 -0.235298
            +vn 0.888668 0.391644 -0.238441
            +vn 0.907315 0.342753 -0.243446
            +vn 0.931028 0.265908 -0.249825
            +vn 0.954558 0.152104 -0.256172
            +vn 0.964782 -0.045717 -0.258980
            +vn 0.912839 -0.326609 0.245003
            +vn 0.945250 -0.326273 0.000000
            +vn 0.795892 -0.566485 0.213538
            +vn 0.824396 -0.565996 0.000000
            +vn 0.687399 -0.702445 0.184393
            +vn 0.712180 -0.701987 0.000000
            +vn 0.630146 -0.757805 0.169012
            +vn 0.652974 -0.757347 0.000000
            +vn 0.698752 -0.690329 0.187445
            +vn 0.724021 -0.689749 0.000000
            +vn 0.855861 -0.463454 0.229530
            +vn 0.886380 -0.462905 0.000000
            +vn 0.817774 -0.327158 0.473434
            +vn 0.712729 -0.567248 0.412549
            +vn 0.615375 -0.703146 0.356151
            +vn 0.564043 -0.758446 0.326456
            +vn 0.625660 -0.690939 0.362102
            +vn 0.766625 -0.464125 0.443678
            +vn 0.668111 -0.327403 0.668111
            +vn 0.582171 -0.567522 0.582171
            +vn 0.502579 -0.703421 0.502579
            +vn 0.460646 -0.758660 0.460646
            +vn 0.510971 -0.691183 0.510971
            +vn 0.626209 -0.464370 0.626209
            +vn 0.473434 -0.327158 0.817774
            +vn 0.412549 -0.567248 0.712729
            +vn 0.356151 -0.703146 0.615375
            +vn 0.326456 -0.758446 0.564043
            +vn 0.362102 -0.690939 0.625660
            +vn 0.443678 -0.464125 0.766625
            +vn 0.245003 -0.326609 0.912839
            +vn 0.213538 -0.566485 0.795892
            +vn 0.184393 -0.702445 0.687399
            +vn 0.169012 -0.757805 0.630146
            +vn 0.187414 -0.690329 0.698752
            +vn 0.229530 -0.463454 0.855831
            +vn 0.000000 -0.326273 0.945250
            +vn 0.000000 -0.565996 0.824396
            +vn 0.000000 -0.701987 0.712180
            +vn 0.000000 -0.757347 0.652974
            +vn 0.000000 -0.689749 0.724021
            +vn 0.000000 -0.462905 0.886380
            +vn -0.245003 -0.326609 0.912839
            +vn -0.213538 -0.566485 0.795892
            +vn -0.184393 -0.702445 0.687399
            +vn -0.169012 -0.757805 0.630146
            +vn -0.187414 -0.690329 0.698752
            +vn -0.229530 -0.463454 0.855831
            +vn -0.473434 -0.327158 0.817774
            +vn -0.412549 -0.567248 0.712729
            +vn -0.356151 -0.703146 0.615375
            +vn -0.326456 -0.758446 0.564043
            +vn -0.362102 -0.690939 0.625660
            +vn -0.443678 -0.464125 0.766625
            +vn -0.668111 -0.327403 0.668111
            +vn -0.582171 -0.567522 0.582171
            +vn -0.502579 -0.703421 0.502579
            +vn -0.460646 -0.758660 0.460646
            +vn -0.510971 -0.691183 0.510971
            +vn -0.626209 -0.464370 0.626209
            +vn -0.817774 -0.327158 0.473434
            +vn -0.712729 -0.567248 0.412549
            +vn -0.615375 -0.703146 0.356151
            +vn -0.564043 -0.758446 0.326456
            +vn -0.625660 -0.690939 0.362102
            +vn -0.766625 -0.464125 0.443678
            +vn -0.912839 -0.326609 0.245003
            +vn -0.795892 -0.566485 0.213538
            +vn -0.687399 -0.702445 0.184393
            +vn -0.630146 -0.757805 0.169012
            +vn -0.698752 -0.690329 0.187445
            +vn -0.855861 -0.463454 0.229530
            +vn -0.945250 -0.326273 0.000000
            +vn -0.824396 -0.565996 0.000000
            +vn -0.712180 -0.701987 0.000000
            +vn -0.652974 -0.757347 0.000000
            +vn -0.724021 -0.689749 0.000000
            +vn -0.886380 -0.462905 0.000000
            +vn -0.912839 -0.326609 -0.245003
            +vn -0.795892 -0.566485 -0.213538
            +vn -0.687399 -0.702445 -0.184393
            +vn -0.630146 -0.757805 -0.169012
            +vn -0.698752 -0.690329 -0.187414
            +vn -0.855831 -0.463454 -0.229530
            +vn -0.817774 -0.327158 -0.473434
            +vn -0.712729 -0.567248 -0.412549
            +vn -0.615375 -0.703146 -0.356151
            +vn -0.564043 -0.758446 -0.326456
            +vn -0.625660 -0.690939 -0.362102
            +vn -0.766625 -0.464125 -0.443678
            +vn -0.668111 -0.327403 -0.668111
            +vn -0.582171 -0.567522 -0.582171
            +vn -0.502579 -0.703421 -0.502579
            +vn -0.460646 -0.758660 -0.460646
            +vn -0.510971 -0.691183 -0.510971
            +vn -0.626209 -0.464370 -0.626209
            +vn -0.473434 -0.327158 -0.817774
            +vn -0.412549 -0.567248 -0.712729
            +vn -0.356151 -0.703146 -0.615375
            +vn -0.326456 -0.758446 -0.564043
            +vn -0.362102 -0.690939 -0.625660
            +vn -0.443678 -0.464125 -0.766625
            +vn -0.245003 -0.326609 -0.912839
            +vn -0.213538 -0.566485 -0.795892
            +vn -0.184393 -0.702445 -0.687399
            +vn -0.169012 -0.757805 -0.630146
            +vn -0.187414 -0.690329 -0.698752
            +vn -0.229530 -0.463454 -0.855831
            +vn 0.000000 -0.326273 -0.945250
            +vn 0.000000 -0.565996 -0.824396
            +vn 0.000000 -0.701987 -0.712149
            +vn 0.000000 -0.757347 -0.652974
            +vn 0.000000 -0.689749 -0.724021
            +vn 0.000000 -0.462905 -0.886380
            +vn 0.245003 -0.326609 -0.912839
            +vn 0.213538 -0.566485 -0.795892
            +vn 0.184393 -0.702445 -0.687399
            +vn 0.169012 -0.757805 -0.630146
            +vn 0.187414 -0.690329 -0.698752
            +vn 0.229530 -0.463454 -0.855831
            +vn 0.473434 -0.327158 -0.817774
            +vn 0.412549 -0.567248 -0.712729
            +vn 0.356151 -0.703146 -0.615375
            +vn 0.326456 -0.758446 -0.564043
            +vn 0.362102 -0.690939 -0.625660
            +vn 0.443678 -0.464125 -0.766625
            +vn 0.668111 -0.327403 -0.668111
            +vn 0.582171 -0.567522 -0.582171
            +vn 0.502579 -0.703421 -0.502579
            +vn 0.460646 -0.758660 -0.460646
            +vn 0.510971 -0.691183 -0.510971
            +vn 0.626209 -0.464370 -0.626209
            +vn 0.817774 -0.327158 -0.473434
            +vn 0.712729 -0.567248 -0.412549
            +vn 0.615375 -0.703146 -0.356151
            +vn 0.564043 -0.758446 -0.326456
            +vn 0.625660 -0.690939 -0.362102
            +vn 0.766625 -0.464125 -0.443678
            +vn 0.912839 -0.326609 -0.245003
            +vn 0.795892 -0.566485 -0.213538
            +vn 0.687399 -0.702445 -0.184393
            +vn 0.630146 -0.757805 -0.169012
            +vn 0.698752 -0.690329 -0.187414
            +vn 0.855831 -0.463454 -0.229530
            +vn 0.068667 -0.997620 0.000000
            +vn 0.066256 -0.997620 -0.017731
            +vn 0.157170 -0.987548 0.000000
            +vn 0.151677 -0.987579 -0.040620
            +vn 0.373150 -0.927763 0.000000
            +vn 0.360149 -0.927885 -0.096469
            +vn 0.789148 -0.614154 0.000000
            +vn 0.762017 -0.614399 -0.204474
            +vn 0.059236 -0.997650 -0.034242
            +vn 0.135624 -0.987640 -0.078463
            +vn 0.322153 -0.928129 -0.186346
            +vn 0.682333 -0.615131 -0.394971
            +vn 0.048341 -0.997650 -0.048341
            +vn 0.110691 -0.987640 -0.110691
            +vn 0.262947 -0.928251 -0.262947
            +vn 0.557329 -0.615375 -0.557329
            +vn 0.034272 -0.997650 -0.059236
            +vn 0.078463 -0.987640 -0.135624
            +vn 0.186377 -0.928129 -0.322153
            +vn 0.394971 -0.615131 -0.682333
            +vn 0.017731 -0.997620 -0.066256
            +vn 0.040620 -0.987579 -0.151677
            +vn 0.096469 -0.927885 -0.360118
            +vn 0.204505 -0.614399 -0.762017
            +vn 0.000000 -0.997620 -0.068667
            +vn 0.000000 -0.987548 -0.157170
            +vn 0.000000 -0.927763 -0.373150
            +vn 0.000000 -0.614154 -0.789148
            +vn -0.017731 -0.997620 -0.066256
            +vn -0.040620 -0.987579 -0.151677
            +vn -0.096469 -0.927885 -0.360118
            +vn -0.204505 -0.614399 -0.762017
            +vn -0.034272 -0.997650 -0.059236
            +vn -0.078463 -0.987640 -0.135624
            +vn -0.186377 -0.928129 -0.322153
            +vn -0.394971 -0.615131 -0.682333
            +vn -0.048341 -0.997650 -0.048341
            +vn -0.110691 -0.987640 -0.110691
            +vn -0.262947 -0.928251 -0.262947
            +vn -0.557329 -0.615375 -0.557329
            +vn -0.059236 -0.997650 -0.034242
            +vn -0.135624 -0.987640 -0.078463
            +vn -0.322153 -0.928129 -0.186346
            +vn -0.682333 -0.615131 -0.394971
            +vn -0.066256 -0.997620 -0.017731
            +vn -0.151677 -0.987579 -0.040620
            +vn -0.360149 -0.927885 -0.096469
            +vn -0.762017 -0.614399 -0.204474
            +vn -0.068667 -0.997620 0.000000
            +vn -0.157170 -0.987548 0.000000
            +vn -0.373150 -0.927763 0.000000
            +vn -0.789148 -0.614154 0.000000
            +vn -0.066256 -0.997620 0.017731
            +vn -0.151677 -0.987579 0.040620
            +vn -0.360118 -0.927885 0.096469
            +vn -0.762017 -0.614399 0.204505
            +vn -0.059236 -0.997650 0.034272
            +vn -0.135624 -0.987640 0.078463
            +vn -0.322153 -0.928129 0.186377
            +vn -0.682333 -0.615131 0.394971
            +vn -0.048341 -0.997650 0.048341
            +vn -0.110691 -0.987640 0.110691
            +vn -0.262947 -0.928251 0.262947
            +vn -0.557329 -0.615375 0.557329
            +vn -0.034272 -0.997650 0.059236
            +vn -0.078463 -0.987640 0.135624
            +vn -0.186377 -0.928129 0.322153
            +vn -0.394971 -0.615131 0.682333
            +vn -0.017731 -0.997620 0.066256
            +vn -0.040620 -0.987579 0.151677
            +vn -0.096469 -0.927885 0.360149
            +vn -0.204474 -0.614399 0.762017
            +vn 0.000000 -0.997620 0.068667
            +vn 0.000000 -0.987548 0.157170
            +vn 0.000000 -0.927763 0.373150
            +vn 0.000000 -0.614154 0.789148
            +vn 0.017731 -0.997620 0.066256
            +vn 0.040620 -0.987579 0.151677
            +vn 0.096469 -0.927885 0.360149
            +vn 0.204474 -0.614399 0.762017
            +vn 0.034272 -0.997650 0.059236
            +vn 0.078463 -0.987640 0.135624
            +vn 0.186377 -0.928129 0.322153
            +vn 0.394971 -0.615131 0.682333
            +vn 0.048341 -0.997650 0.048341
            +vn 0.110691 -0.987640 0.110691
            +vn 0.262947 -0.928251 0.262947
            +vn 0.557329 -0.615375 0.557329
            +vn 0.059236 -0.997650 0.034272
            +vn 0.135624 -0.987640 0.078463
            +vn 0.322153 -0.928129 0.186377
            +vn 0.682333 -0.615101 0.394971
            +vn 0.066256 -0.997620 0.017731
            +vn 0.151677 -0.987579 0.040620
            +vn 0.360118 -0.927885 0.096469
            +vn 0.762017 -0.614399 0.204505
            +vn 0.692129 0.697470 0.185583
            +vn 0.717063 0.696982 0.000000
            +vn 0.915586 0.318766 0.245064
            +vn 0.947905 0.318522 0.000000
            +vn 0.620045 0.697653 0.358837
            +vn 0.820429 0.318979 0.474410
            +vn 0.506546 0.697684 0.506546
            +vn 0.670125 0.319041 0.670125
            +vn 0.358837 0.697653 0.620045
            +vn 0.474410 0.318979 0.820429
            +vn 0.185583 0.697470 0.692129
            +vn 0.245064 0.318766 0.915586
            +vn 0.000000 0.696982 0.717063
            +vn 0.000000 0.318522 0.947905
            +vn -0.185583 0.697470 0.692129
            +vn -0.245064 0.318766 0.915586
            +vn -0.358837 0.697653 0.620045
            +vn -0.474410 0.318979 0.820429
            +vn -0.506546 0.697684 0.506546
            +vn -0.670125 0.319041 0.670125
            +vn -0.620045 0.697653 0.358837
            +vn -0.820429 0.318979 0.474410
            +vn -0.692129 0.697470 0.185583
            +vn -0.915586 0.318766 0.245064
            +vn -0.717063 0.696982 0.000000
            +vn -0.947905 0.318522 0.000000
            +vn -0.692129 0.697470 -0.185583
            +vn -0.915586 0.318766 -0.245064
            +vn -0.620045 0.697653 -0.358837
            +vn -0.820429 0.318979 -0.474410
            +vn -0.506546 0.697684 -0.506546
            +vn -0.670125 0.319041 -0.670125
            +vn -0.358837 0.697653 -0.620045
            +vn -0.474410 0.318979 -0.820429
            +vn -0.185583 0.697470 -0.692129
            +vn -0.245064 0.318766 -0.915586
            +vn 0.000000 0.696982 -0.717063
            +vn 0.000000 0.318522 -0.947905
            +vn 0.185583 0.697470 -0.692129
            +vn 0.245064 0.318766 -0.915586
            +vn 0.358837 0.697653 -0.620045
            +vn 0.474410 0.318979 -0.820429
            +vn 0.506546 0.697684 -0.506546
            +vn 0.670125 0.319041 -0.670125
            +vn 0.620045 0.697653 -0.358837
            +vn 0.820429 0.318979 -0.474410
            +vn 0.692129 0.697470 -0.185583
            +vn 0.915586 0.318766 -0.245064
            +vn 0.282083 0.956389 0.075686
            +vn 0.292520 0.956236 0.000000
            +vn 0.171606 0.984069 0.046022
            +vn 0.177953 0.984008 0.000000
            +vn 0.153264 0.987304 0.041078
            +vn 0.158879 0.987274 0.000000
            +vn 0.210059 0.976043 0.056276
            +vn 0.217719 0.975982 0.000000
            +vn 0.487197 0.863460 0.130558
            +vn 0.504715 0.863277 0.000000
            +vn 0.662801 0.727226 0.178198
            +vn 0.686911 0.726707 0.000000
            +vn 0.252388 0.956511 0.146092
            +vn 0.153508 0.984130 0.088839
            +vn 0.137059 0.987365 0.079318
            +vn 0.187872 0.976135 0.108676
            +vn 0.435926 0.863887 0.252205
            +vn 0.593310 0.727866 0.343730
            +vn 0.206091 0.956572 0.206091
            +vn 0.125340 0.984161 0.125340
            +vn 0.111911 0.987396 0.111911
            +vn 0.153356 0.976196 0.153356
            +vn 0.355907 0.864071 0.355907
            +vn 0.484664 0.728111 0.484664
            +vn 0.146092 0.956511 0.252388
            +vn 0.088839 0.984130 0.153508
            +vn 0.079318 0.987365 0.137059
            +vn 0.108676 0.976135 0.187872
            +vn 0.252205 0.863887 0.435926
            +vn 0.343730 0.727866 0.593310
            +vn 0.075686 0.956389 0.282083
            +vn 0.046022 0.984069 0.171606
            +vn 0.041078 0.987304 0.153264
            +vn 0.056276 0.976043 0.210059
            +vn 0.130558 0.863460 0.487197
            +vn 0.178198 0.727226 0.662801
            +vn 0.000000 0.956236 0.292520
            +vn 0.000000 0.984008 0.177953
            +vn 0.000000 0.987274 0.158879
            +vn 0.000000 0.975982 0.217719
            +vn 0.000000 0.863277 0.504715
            +vn 0.000000 0.726707 0.686911
            +vn -0.075686 0.956389 0.282083
            +vn -0.046022 0.984069 0.171606
            +vn -0.041078 0.987304 0.153264
            +vn -0.056276 0.976043 0.210059
            +vn -0.130558 0.863460 0.487197
            +vn -0.178198 0.727226 0.662801
            +vn -0.146092 0.956511 0.252388
            +vn -0.088839 0.984130 0.153508
            +vn -0.079318 0.987365 0.137059
            +vn -0.108676 0.976135 0.187872
            +vn -0.252205 0.863887 0.435926
            +vn -0.343730 0.727866 0.593310
            +vn -0.206091 0.956572 0.206091
            +vn -0.125340 0.984161 0.125340
            +vn -0.111911 0.987396 0.111911
            +vn -0.153356 0.976196 0.153356
            +vn -0.355907 0.864071 0.355907
            +vn -0.484664 0.728111 0.484664
            +vn -0.252388 0.956511 0.146092
            +vn -0.153508 0.984130 0.088839
            +vn -0.137059 0.987365 0.079318
            +vn -0.187872 0.976135 0.108676
            +vn -0.435926 0.863887 0.252205
            +vn -0.593310 0.727866 0.343730
            +vn -0.282083 0.956389 0.075686
            +vn -0.171606 0.984069 0.046022
            +vn -0.153264 0.987304 0.041078
            +vn -0.210059 0.976043 0.056276
            +vn -0.487197 0.863460 0.130558
            +vn -0.662801 0.727226 0.178198
            +vn -0.292520 0.956236 0.000000
            +vn -0.177953 0.984008 0.000000
            +vn -0.158879 0.987274 0.000000
            +vn -0.217719 0.975982 0.000000
            +vn -0.504715 0.863277 0.000000
            +vn -0.686911 0.726707 0.000000
            +vn -0.282083 0.956389 -0.075686
            +vn -0.171606 0.984069 -0.046022
            +vn -0.153264 0.987304 -0.041078
            +vn -0.210059 0.976043 -0.056276
            +vn -0.487197 0.863460 -0.130558
            +vn -0.662801 0.727226 -0.178198
            +vn -0.252388 0.956511 -0.146092
            +vn -0.153508 0.984130 -0.088839
            +vn -0.137059 0.987365 -0.079318
            +vn -0.187872 0.976135 -0.108676
            +vn -0.435926 0.863887 -0.252205
            +vn -0.593310 0.727866 -0.343730
            +vn -0.206091 0.956572 -0.206091
            +vn -0.125340 0.984161 -0.125340
            +vn -0.111911 0.987396 -0.111911
            +vn -0.153356 0.976196 -0.153356
            +vn -0.355907 0.864071 -0.355907
            +vn -0.484664 0.728111 -0.484664
            +vn -0.146092 0.956511 -0.252388
            +vn -0.088839 0.984130 -0.153508
            +vn -0.079318 0.987365 -0.137059
            +vn -0.108676 0.976135 -0.187872
            +vn -0.252205 0.863887 -0.435926
            +vn -0.343730 0.727866 -0.593310
            +vn -0.075686 0.956389 -0.282083
            +vn -0.046022 0.984069 -0.171606
            +vn -0.041078 0.987304 -0.153264
            +vn -0.056276 0.976043 -0.210059
            +vn -0.130558 0.863460 -0.487197
            +vn -0.178198 0.727226 -0.662801
            +vn 0.000000 0.956236 -0.292520
            +vn 0.000000 0.984008 -0.177953
            +vn 0.000000 0.987274 -0.158879
            +vn 0.000000 0.975982 -0.217719
            +vn 0.000000 0.863277 -0.504715
            +vn 0.000000 0.726707 -0.686911
            +vn 0.075686 0.956389 -0.282083
            +vn 0.046022 0.984069 -0.171606
            +vn 0.041078 0.987304 -0.153264
            +vn 0.056276 0.976043 -0.210059
            +vn 0.130558 0.863460 -0.487197
            +vn 0.178198 0.727226 -0.662801
            +vn 0.146092 0.956511 -0.252388
            +vn 0.088839 0.984130 -0.153508
            +vn 0.079318 0.987365 -0.137059
            +vn 0.108676 0.976135 -0.187872
            +vn 0.252205 0.863887 -0.435926
            +vn 0.343730 0.727866 -0.593310
            +vn 0.206091 0.956572 -0.206091
            +vn 0.125340 0.984161 -0.125340
            +vn 0.111911 0.987396 -0.111911
            +vn 0.153356 0.976196 -0.153356
            +vn 0.355907 0.864071 -0.355907
            +vn 0.484664 0.728111 -0.484664
            +vn 0.252388 0.956511 -0.146092
            +vn 0.153508 0.984130 -0.088839
            +vn 0.137059 0.987365 -0.079318
            +vn 0.187872 0.976135 -0.108676
            +vn 0.435926 0.863887 -0.252205
            +vn 0.593310 0.727866 -0.343730
            +vn 0.282083 0.956389 -0.075686
            +vn 0.171606 0.984069 -0.046022
            +vn 0.153264 0.987304 -0.041078
            +vn 0.210059 0.976043 -0.056276
            +vn 0.487197 0.863460 -0.130558
            +vn 0.662801 0.727226 -0.178198
            +vn 0.015290 -0.999878 0.000000
            +vn 0.003296 -0.999969 0.000000
            +vn 0.015168 -0.949339 0.313852
            +vn 0.003265 -0.944395 0.328715
            +vn 0.058870 -0.998260 0.000000
            +vn 0.058046 -0.947630 0.314005
            +vn 0.158361 -0.934690 0.318155
            +vn 0.159764 -0.987152 0.000000
            +vn 0.373943 -0.860958 0.344798
            +vn 0.391583 -0.920103 0.000000
            +vn 0.726829 -0.553880 0.406049
            +vn 0.784570 -0.620014 0.000000
            +vn 0.908139 -0.082766 0.410321
            +vn 0.994995 -0.099796 0.000000
            +vn 0.011902 -0.679403 0.733634
            +vn 0.002380 -0.636219 0.771477
            +vn 0.046449 -0.674398 0.736869
            +vn 0.125980 -0.648946 0.750298
            +vn 0.270089 -0.562120 0.781671
            +vn 0.460067 -0.316263 0.829615
            +vn 0.563036 -0.041200 0.825373
            +vn 0.000153 0.004242 0.999969
            +vn -0.000519 0.113254 0.993561
            +vn 0.003510 0.014008 0.999878
            +vn 0.005921 0.035951 0.999329
            +vn -0.007813 0.058840 0.998230
            +vn -0.046510 0.041536 0.998047
            +vn -0.039155 0.003113 0.999207
            +vn -0.014161 0.682394 0.730796
            +vn -0.003204 0.727744 0.685812
            +vn -0.055361 0.680074 0.731010
            +vn -0.150029 0.655660 0.739952
            +vn -0.322520 0.565203 0.759239
            +vn -0.537645 0.315806 0.781762
            +vn -0.611530 0.029939 0.790613
            +vn -0.020569 0.949400 0.313334
            +vn -0.004273 0.954772 0.297281
            +vn -0.082705 0.944945 0.316507
            +vn -0.229591 0.914548 0.332926
            +vn -0.502335 0.785943 0.360454
            +vn -0.810633 0.443220 0.382611
            +vn -0.921232 0.039705 0.386944
            +vn -0.021851 0.999756 0.000000
            +vn -0.004517 0.999969 0.000000
            +vn -0.087649 0.996124 0.000000
            +vn -0.246223 0.969207 0.000000
            +vn -0.549211 0.835658 0.000000
            +vn -0.881039 0.472976 0.000000
            +vn -0.999115 0.041444 0.000000
            +vn -0.004273 0.954772 -0.297281
            +vn -0.020569 0.949400 -0.313334
            +vn -0.082705 0.944945 -0.316507
            +vn -0.229591 0.914548 -0.332926
            +vn -0.502335 0.785943 -0.360454
            +vn -0.810633 0.443220 -0.382611
            +vn -0.921232 0.039705 -0.386944
            +vn -0.003204 0.727744 -0.685812
            +vn -0.014161 0.682394 -0.730796
            +vn -0.055361 0.680074 -0.731010
            +vn -0.150029 0.655660 -0.739952
            +vn -0.322520 0.565203 -0.759239
            +vn -0.537645 0.315806 -0.781762
            +vn -0.611530 0.029939 -0.790613
            +vn -0.000519 0.113254 -0.993561
            +vn 0.000153 0.004242 -0.999969
            +vn 0.003510 0.014008 -0.999878
            +vn 0.005921 0.035951 -0.999329
            +vn -0.007813 0.058809 -0.998230
            +vn -0.046510 0.041536 -0.998047
            +vn -0.039155 0.003113 -0.999207
            +vn 0.002380 -0.636219 -0.771477
            +vn 0.011902 -0.679403 -0.733634
            +vn 0.046449 -0.674398 -0.736869
            +vn 0.125980 -0.648946 -0.750298
            +vn 0.270089 -0.562151 -0.781671
            +vn 0.460067 -0.316263 -0.829615
            +vn 0.563036 -0.041231 -0.825373
            +vn 0.003265 -0.944395 -0.328715
            +vn 0.015168 -0.949339 -0.313852
            +vn 0.058046 -0.947630 -0.314005
            +vn 0.158361 -0.934690 -0.318155
            +vn 0.373943 -0.860958 -0.344798
            +vn 0.726829 -0.553880 -0.406049
            +vn 0.908139 -0.082766 -0.410321
            +vn 0.890500 0.214759 0.401044
            +vn 0.972930 0.231025 0.000000
            +vn 0.836634 0.384075 0.390515
            +vn 0.912503 0.408979 0.000000
            +vn 0.765191 0.530198 0.365123
            +vn 0.828791 0.559496 0.000000
            +vn 0.671041 0.663228 0.331339
            +vn 0.718955 0.695029 0.000000
            +vn 0.549455 0.776238 0.309000
            +vn 0.580859 0.813990 0.000000
            +vn 0.461165 0.821528 0.335215
            +vn 0.497085 0.867672 0.000000
            +vn 0.559679 0.139714 0.816828
            +vn 0.528581 0.255501 0.809473
            +vn 0.494888 0.359783 0.790948
            +vn 0.445143 0.467879 0.763451
            +vn 0.376049 0.559984 0.738212
            +vn 0.287332 0.527940 0.799188
            +vn -0.024537 -0.005737 0.999664
            +vn -0.020844 -0.012207 0.999695
            +vn -0.014466 -0.014466 0.999786
            +vn -0.009796 -0.013276 0.999847
            +vn -0.014771 -0.013886 0.999786
            +vn -0.101779 -0.196661 0.975158
            +vn -0.585437 -0.154668 0.795801
            +vn -0.538499 -0.291696 0.790490
            +vn -0.487228 -0.408918 0.771599
            +vn -0.428327 -0.511948 0.744560
            +vn -0.360820 -0.584735 0.726524
            +vn -0.357311 -0.691549 0.627735
            +vn -0.889126 -0.238868 0.390332
            +vn -0.807001 -0.448500 0.384075
            +vn -0.700980 -0.613392 0.363750
            +vn -0.590442 -0.733757 0.336009
            +vn -0.486190 -0.814966 0.315256
            +vn -0.440138 -0.855586 0.272439
            +vn -0.965453 -0.260506 0.000000
            +vn -0.872097 -0.489273 0.000000
            +vn -0.748253 -0.663381 0.000000
            +vn -0.621784 -0.783166 0.000000
            +vn -0.507614 -0.861568 0.000000
            +vn -0.456954 -0.889462 0.000000
            +vn -0.889126 -0.238868 -0.390332
            +vn -0.807001 -0.448531 -0.384075
            +vn -0.700980 -0.613392 -0.363750
            +vn -0.590442 -0.733757 -0.336009
            +vn -0.486190 -0.814966 -0.315256
            +vn -0.440138 -0.855586 -0.272439
            +vn -0.585437 -0.154668 -0.795801
            +vn -0.538499 -0.291696 -0.790490
            +vn -0.487228 -0.408918 -0.771599
            +vn -0.428327 -0.511948 -0.744560
            +vn -0.360820 -0.584735 -0.726524
            +vn -0.357311 -0.691549 -0.627705
            +vn -0.024537 -0.005737 -0.999664
            +vn -0.020844 -0.012238 -0.999695
            +vn -0.014466 -0.014466 -0.999786
            +vn -0.009766 -0.013276 -0.999847
            +vn -0.014771 -0.013916 -0.999786
            +vn -0.101779 -0.196661 -0.975158
            +vn 0.559679 0.139714 -0.816828
            +vn 0.528581 0.255501 -0.809473
            +vn 0.494888 0.359783 -0.790948
            +vn 0.445143 0.467879 -0.763451
            +vn 0.376049 0.559984 -0.738212
            +vn 0.287332 0.527940 -0.799188
            +vn 0.890500 0.214759 -0.401044
            +vn 0.836634 0.384075 -0.390515
            +vn 0.765191 0.530198 -0.365123
            +vn 0.671041 0.663228 -0.331339
            +vn 0.549455 0.776238 -0.309000
            +vn 0.461165 0.821528 -0.335215
            +vn -0.149937 0.988678 0.000000
            +vn -0.137028 0.872402 0.469131
            +vn -0.297769 0.840358 0.452895
            +vn -0.350505 0.936552 0.000000
            +vn -0.617512 0.663961 0.421613
            +vn -0.715506 0.698569 0.000000
            +vn -0.801324 0.450209 0.393872
            +vn -0.900845 0.434065 0.000000
            +vn -0.828028 0.379803 0.412397
            +vn -0.929289 0.369274 0.000000
            +vn -0.729179 0.503464 0.463393
            +vn -0.857875 0.513810 0.000000
            +vn -0.663076 0.748527 0.000000
            +vn -0.531449 0.686514 0.496170
            +vn -0.066713 0.491440 0.868313
            +vn -0.117893 0.503159 0.856105
            +vn -0.254341 0.474349 0.842769
            +vn -0.411115 0.399182 0.819483
            +vn -0.459395 0.346446 0.817835
            +vn -0.385876 0.395734 0.833338
            +vn -0.270669 0.487838 0.829890
            +vn 0.062716 -0.043458 0.997070
            +vn 0.135929 -0.002472 0.990692
            +vn 0.247963 0.095187 0.964049
            +vn 0.209296 0.170660 0.962828
            +vn 0.096194 0.178625 0.979186
            +vn 0.009552 0.154332 0.987945
            +vn -0.000122 0.151952 0.988372
            +vn 0.202582 -0.542894 0.814966
            +vn 0.360088 -0.479232 0.800378
            +vn 0.611988 -0.282235 0.738762
            +vn 0.679220 -0.106754 0.726096
            +vn 0.583911 -0.078524 0.807978
            +vn 0.402722 -0.205237 0.891995
            +vn 0.279519 -0.338694 0.898404
            +vn 0.294107 -0.855037 0.427015
            +vn 0.488418 -0.768700 0.412915
            +vn 0.784570 -0.501511 0.364544
            +vn 0.893918 -0.279611 0.350291
            +vn 0.861415 -0.285287 0.420179
            +vn 0.679373 -0.540422 0.496323
            +vn 0.458357 -0.754540 0.469588
            +vn 0.320780 -0.947142 0.000000
            +vn 0.525101 -0.851009 0.000000
            +vn 0.827570 -0.561327 0.000000
            +vn 0.943419 -0.331523 0.000000
            +vn 0.933561 -0.358409 0.000000
            +vn 0.756340 -0.654134 0.000000
            +vn 0.491928 -0.870602 0.000092
            +vn 0.294107 -0.855037 -0.427015
            +vn 0.488418 -0.768700 -0.412915
            +vn 0.784570 -0.501511 -0.364544
            +vn 0.893918 -0.279611 -0.350291
            +vn 0.861385 -0.285287 -0.420179
            +vn 0.679373 -0.540422 -0.496323
            +vn 0.457839 -0.755608 -0.468368
            +vn 0.202582 -0.542894 -0.814966
            +vn 0.360088 -0.479232 -0.800378
            +vn 0.611988 -0.282235 -0.738762
            +vn 0.679220 -0.106754 -0.726096
            +vn 0.583911 -0.078524 -0.807978
            +vn 0.402722 -0.205237 -0.891995
            +vn 0.279153 -0.342235 -0.897153
            +vn 0.062716 -0.043458 -0.997070
            +vn 0.135929 -0.002472 -0.990692
            +vn 0.247963 0.095187 -0.964049
            +vn 0.209296 0.170629 -0.962828
            +vn 0.096194 0.178625 -0.979186
            +vn 0.009552 0.154332 -0.987945
            +vn -0.000458 0.149358 -0.988769
            +vn -0.066713 0.491440 -0.868313
            +vn -0.117893 0.503159 -0.856105
            +vn -0.254341 0.474319 -0.842769
            +vn -0.411115 0.399182 -0.819514
            +vn -0.459395 0.346446 -0.817835
            +vn -0.385876 0.395734 -0.833338
            +vn -0.271035 0.487136 -0.830164
            +vn -0.137028 0.872402 -0.469131
            +vn -0.297769 0.840358 -0.452895
            +vn -0.617512 0.663961 -0.421613
            +vn -0.801324 0.450209 -0.393872
            +vn -0.828028 0.379803 -0.412397
            +vn -0.729209 0.503464 -0.463393
            +vn -0.531541 0.686453 -0.496200
            +vn -0.480697 0.876858 0.000000
            +vn -0.394635 0.815363 0.423536
            +vn -0.320750 0.947142 0.000092
            +vn -0.255287 0.921964 0.291086
            +vn 0.002686 0.999969 -0.000732
            +vn -0.007172 0.999939 -0.007599
            +vn 0.366832 0.704398 -0.607624
            +vn 0.853236 0.521226 -0.016388
            +vn 0.567492 -0.154088 -0.808802
            +vn 0.803766 -0.594409 -0.024964
            +vn 0.580920 -0.584490 -0.566424
            +vn 0.673757 -0.738639 -0.020966
            +vn -0.206824 0.638203 0.741539
            +vn -0.129490 0.862056 0.489944
            +vn -0.034486 0.999023 0.026704
            +vn 0.041597 0.871334 -0.488876
            +vn 0.103488 0.553880 -0.826136
            +vn 0.189642 0.174200 -0.966247
            +vn 0.020112 0.322611 0.946287
            +vn 0.021943 0.748894 0.662282
            +vn -0.025697 0.995392 0.092166
            +vn -0.056551 0.931608 -0.358989
            +vn -0.070711 0.782006 -0.619190
            +vn -0.066408 0.651509 -0.755699
            +vn 0.281747 -0.174993 0.943388
            +vn 0.303903 0.444136 0.842830
            +vn 0.035279 0.983856 0.175329
            +vn -0.109928 0.953551 -0.280435
            +vn -0.149571 0.847682 -0.508927
            +vn -0.145634 0.777520 -0.611744
            +vn 0.467238 -0.683218 0.561144
            +vn 0.699515 0.004364 0.714560
            +vn 0.354900 0.892758 0.277444
            +vn -0.174383 0.969054 -0.174596
            +vn -0.252998 0.894314 -0.368938
            +vn -0.191443 0.807947 -0.557237
            +vn 0.495346 -0.868679 0.001587
            +vn 0.933897 -0.357311 0.011017
            +vn 0.704215 0.709830 0.013337
            +vn -0.205634 0.978576 -0.006623
            +vn -0.322367 0.945708 -0.041169
            +vn -0.314951 0.916288 -0.247322
            +vn 0.459120 -0.703757 -0.542100
            +vn 0.693655 -0.096530 -0.713767
            +vn 0.408673 0.848415 -0.336344
            +vn -0.198248 0.963439 0.180151
            +vn -0.306833 0.888516 0.341075
            +vn -0.335978 0.808863 0.482498
            +vn 0.277047 -0.215796 -0.936277
            +vn 0.306192 0.349864 -0.885311
            +vn 0.056246 0.971099 -0.231819
            +vn -0.146733 0.912168 0.382611
            +vn -0.202612 0.700797 0.683950
            +vn -0.159368 0.444777 0.881314
            +vn 0.016907 0.300088 -0.953734
            +vn 0.019349 0.701865 -0.712027
            +vn -0.023713 0.995361 -0.093081
            +vn -0.047395 0.829371 0.556658
            +vn -0.015259 0.386608 0.922086
            +vn 0.080721 0.001404 0.996704
            +vn -0.209967 0.632160 -0.745811
            +vn -0.137394 0.849117 -0.509995
            +vn -0.023438 0.999695 -0.004883
            +vn 0.120426 0.724540 0.678579
            +vn 0.260750 0.006531 0.965361
            +vn 0.341502 -0.385510 0.857143
            +vn -0.395489 0.814814 -0.423841
            +vn -0.257942 0.920621 -0.293039
            +vn 0.005005 0.999908 0.011628
            +vn 0.466628 0.599811 0.649983
            +vn 0.621937 -0.400861 0.672628
            +vn 0.584826 -0.661397 0.469558
            +vn 0.363842 0.931455 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.351451 0.931516 0.093509
            +vn 0.314432 0.931791 0.181280
            +vn 0.256386 0.931913 0.256386
            +vn 0.181280 0.931791 0.314432
            +vn 0.093509 0.931516 0.351451
            +vn 0.000000 0.931455 0.363842
            +vn -0.093509 0.931516 0.351451
            +vn -0.181280 0.931791 0.314432
            +vn -0.256386 0.931913 0.256386
            +vn -0.314432 0.931791 0.181280
            +vn -0.351451 0.931516 0.093509
            +vn -0.363842 0.931455 0.000000
            +vn -0.351451 0.931516 -0.093509
            +vn -0.314432 0.931791 -0.181280
            +vn -0.256417 0.931913 -0.256417
            +vn -0.181280 0.931791 -0.314432
            +vn -0.093509 0.931516 -0.351451
            +vn 0.000000 0.931455 -0.363842
            +vn 0.093509 0.931516 -0.351451
            +vn 0.181280 0.931791 -0.314432
            +vn 0.256417 0.931913 -0.256417
            +vn 0.314432 0.931791 -0.181280
            +vn 0.351451 0.931516 -0.093509
            +vn 0.935423 0.249763 0.250160
            +vn 0.968261 0.249916 0.000000
            +vn 0.813959 -0.538713 0.217322
            +vn 0.842860 -0.538102 0.000000
            +vn 0.759484 -0.618030 0.202887
            +vn 0.786767 -0.617206 0.000000
            +vn 0.801569 -0.558184 0.214148
            +vn 0.830195 -0.557421 0.000000
            +vn 0.838404 0.249825 0.484359
            +vn 0.729026 -0.539720 0.420881
            +vn 0.680013 -0.619098 0.392712
            +vn 0.717765 -0.559343 0.414594
            +vn 0.684652 0.249886 0.684652
            +vn 0.595050 -0.540147 0.595050
            +vn 0.555040 -0.619526 0.555040
            +vn 0.585894 -0.559862 0.585894
            +vn 0.484359 0.249825 0.838404
            +vn 0.420881 -0.539720 0.729026
            +vn 0.392712 -0.619098 0.680013
            +vn 0.414594 -0.559343 0.717765
            +vn 0.250160 0.249763 0.935423
            +vn 0.217322 -0.538713 0.813959
            +vn 0.202887 -0.618030 0.759514
            +vn 0.214148 -0.558184 0.801569
            +vn 0.000000 0.249916 0.968261
            +vn 0.000000 -0.538102 0.842860
            +vn 0.000000 -0.617206 0.786767
            +vn 0.000000 -0.557421 0.830195
            +vn -0.250160 0.249763 0.935423
            +vn -0.217322 -0.538713 0.813959
            +vn -0.202887 -0.618030 0.759514
            +vn -0.214148 -0.558184 0.801569
            +vn -0.484359 0.249825 0.838404
            +vn -0.420881 -0.539720 0.729026
            +vn -0.392712 -0.619098 0.680013
            +vn -0.414594 -0.559343 0.717765
            +vn -0.684652 0.249886 0.684652
            +vn -0.595050 -0.540147 0.595050
            +vn -0.555040 -0.619526 0.555040
            +vn -0.585894 -0.559862 0.585894
            +vn -0.838404 0.249825 0.484359
            +vn -0.729026 -0.539720 0.420881
            +vn -0.680013 -0.619098 0.392712
            +vn -0.717765 -0.559343 0.414594
            +vn -0.935423 0.249763 0.250160
            +vn -0.813959 -0.538713 0.217322
            +vn -0.759484 -0.618030 0.202887
            +vn -0.801569 -0.558184 0.214148
            +vn -0.968261 0.249916 0.000000
            +vn -0.842860 -0.538102 0.000000
            +vn -0.786767 -0.617206 0.000000
            +vn -0.830195 -0.557421 0.000000
            +vn -0.935423 0.249763 -0.250160
            +vn -0.813959 -0.538713 -0.217322
            +vn -0.759484 -0.618030 -0.202887
            +vn -0.801569 -0.558184 -0.214148
            +vn -0.838404 0.249825 -0.484359
            +vn -0.729026 -0.539720 -0.420881
            +vn -0.680013 -0.619098 -0.392712
            +vn -0.717765 -0.559343 -0.414594
            +vn -0.684652 0.249886 -0.684652
            +vn -0.595050 -0.540147 -0.595050
            +vn -0.555040 -0.619526 -0.555040
            +vn -0.585864 -0.559862 -0.585894
            +vn -0.484359 0.249825 -0.838404
            +vn -0.420881 -0.539720 -0.729026
            +vn -0.392712 -0.619098 -0.680013
            +vn -0.414594 -0.559343 -0.717765
            +vn -0.250160 0.249763 -0.935423
            +vn -0.217322 -0.538713 -0.813959
            +vn -0.202887 -0.618030 -0.759484
            +vn -0.214148 -0.558214 -0.801569
            +vn 0.000000 0.249916 -0.968261
            +vn 0.000000 -0.538102 -0.842860
            +vn 0.000000 -0.617206 -0.786767
            +vn 0.000000 -0.557421 -0.830195
            +vn 0.250160 0.249763 -0.935423
            +vn 0.217322 -0.538713 -0.813959
            +vn 0.202887 -0.618030 -0.759484
            +vn 0.214148 -0.558214 -0.801569
            +vn 0.484359 0.249825 -0.838404
            +vn 0.420881 -0.539720 -0.729026
            +vn 0.392712 -0.619098 -0.680013
            +vn 0.414594 -0.559343 -0.717765
            +vn 0.684652 0.249886 -0.684652
            +vn 0.595050 -0.540147 -0.595050
            +vn 0.555040 -0.619526 -0.555040
            +vn 0.585864 -0.559862 -0.585894
            +vn 0.838404 0.249825 -0.484359
            +vn 0.729026 -0.539720 -0.420881
            +vn 0.680013 -0.619098 -0.392712
            +vn 0.717765 -0.559343 -0.414594
            +vn 0.935423 0.249763 -0.250160
            +vn 0.813959 -0.538713 -0.217322
            +vn 0.759484 -0.618030 -0.202887
            +vn 0.801569 -0.558184 -0.214148
            +s 1
            +f 1//1 2//2 3//3
            +f 3//3 2//2 4//4
            +f 4//4 2//2 5//5
            +f 5//5 2//2 6//6
            +f 6//6 2//2 7//7
            +f 7//7 2//2 8//8
            +f 8//8 2//2 9//9
            +f 9//9 2//2 10//10
            +f 10//10 2//2 11//11
            +f 11//11 2//2 12//12
            +f 12//12 2//2 13//13
            +f 13//13 2//2 14//14
            +f 14//14 2//2 15//15
            +f 15//15 2//2 16//16
            +f 16//16 2//2 17//17
            +f 17//17 2//2 18//18
            +f 18//18 2//2 19//19
            +f 19//19 2//2 20//20
            +f 20//20 2//2 21//21
            +f 21//21 2//2 22//22
            +f 22//22 2//2 23//23
            +f 23//23 2//2 24//24
            +f 24//24 2//2 25//25
            +f 2//2 1//1 25//25
            +f 26//26 27//27 28//28
            +f 28//28 29//29 26//26
            +f 29//29 28//28 30//30
            +f 31//31 30//30 28//28
            +f 30//30 31//31 32//32
            +f 33//33 32//32 31//31
            +f 34//34 35//35 33//33
            +f 32//32 33//33 35//35
            +f 36//36 37//37 34//34
            +f 35//35 34//34 37//37
            +f 38//38 39//39 36//36
            +f 37//37 36//36 39//39
            +f 27//27 40//40 41//41
            +f 41//41 28//28 27//27
            +f 28//28 41//41 31//31
            +f 42//42 31//31 41//41
            +f 31//31 42//42 33//33
            +f 43//43 33//33 42//42
            +f 44//44 34//34 43//43
            +f 33//33 43//43 34//34
            +f 45//45 36//36 44//44
            +f 34//34 44//44 36//36
            +f 46//46 38//38 45//45
            +f 36//36 45//45 38//38
            +f 40//40 47//47 48//48
            +f 48//48 41//41 40//40
            +f 41//41 48//48 42//42
            +f 49//49 42//42 48//48
            +f 42//42 49//49 43//43
            +f 50//50 43//43 49//49
            +f 51//51 44//44 50//50
            +f 43//43 50//50 44//44
            +f 52//52 45//45 51//51
            +f 44//44 51//51 45//45
            +f 53//53 46//46 52//52
            +f 45//45 52//52 46//46
            +f 47//47 54//54 48//48
            +f 55//55 48//48 54//54
            +f 48//48 55//55 49//49
            +f 56//56 49//49 55//55
            +f 49//49 56//56 57//57
            +f 57//57 50//50 49//49
            +f 58//58 51//51 50//50
            +f 50//50 57//57 58//58
            +f 59//59 52//52 51//51
            +f 51//51 58//58 59//59
            +f 60//60 53//53 52//52
            +f 52//52 59//59 60//60
            +f 54//54 61//61 55//55
            +f 62//62 55//55 61//61
            +f 55//55 62//62 63//63
            +f 63//63 56//56 55//55
            +f 56//56 63//63 64//64
            +f 64//64 57//57 56//56
            +f 65//65 58//58 57//57
            +f 57//57 64//64 65//65
            +f 66//66 59//59 58//58
            +f 58//58 65//65 66//66
            +f 67//67 60//60 59//59
            +f 59//59 66//66 67//67
            +f 61//61 68//68 62//62
            +f 69//69 62//62 68//68
            +f 62//62 69//69 70//70
            +f 70//70 63//63 62//62
            +f 63//63 70//70 71//71
            +f 71//71 64//64 63//63
            +f 72//72 65//65 64//64
            +f 64//64 71//71 72//72
            +f 73//73 66//66 65//65
            +f 65//65 72//72 73//73
            +f 74//74 67//67 66//66
            +f 66//66 73//73 74//74
            +f 68//68 75//75 76//76
            +f 76//76 69//69 68//68
            +f 69//69 76//76 70//70
            +f 77//77 70//70 76//76
            +f 70//70 77//77 71//71
            +f 78//78 71//71 77//77
            +f 79//79 72//72 78//78
            +f 71//71 78//78 72//72
            +f 80//80 73//73 79//79
            +f 72//72 79//79 73//73
            +f 81//81 74//74 80//80
            +f 73//73 80//80 74//74
            +f 75//75 82//82 83//83
            +f 83//83 76//76 75//75
            +f 76//76 83//83 77//77
            +f 84//84 77//77 83//83
            +f 77//77 84//84 78//78
            +f 85//85 78//78 84//84
            +f 86//86 79//79 85//85
            +f 78//78 85//85 79//79
            +f 87//87 80//80 86//86
            +f 79//79 86//86 80//80
            +f 88//88 81//81 87//87
            +f 80//80 87//87 81//81
            +f 82//82 89//89 90//90
            +f 90//90 83//83 82//82
            +f 83//83 90//90 91//91
            +f 91//91 84//84 83//83
            +f 84//84 91//91 85//85
            +f 92//92 85//85 91//91
            +f 93//93 86//86 92//92
            +f 85//85 92//92 86//86
            +f 94//94 87//87 93//93
            +f 86//86 93//93 87//87
            +f 95//95 88//88 94//94
            +f 87//87 94//94 88//88
            +f 89//89 96//96 90//90
            +f 97//97 90//90 96//96
            +f 90//90 97//97 98//98
            +f 98//98 91//91 90//90
            +f 91//91 98//98 99//99
            +f 99//99 92//92 91//91
            +f 100//100 93//93 92//92
            +f 92//92 99//99 100//100
            +f 101//101 94//94 93//93
            +f 93//93 100//100 101//101
            +f 102//102 95//95 94//94
            +f 94//94 101//101 102//102
            +f 96//96 103//103 97//97
            +f 104//104 97//97 103//103
            +f 97//97 104//104 105//105
            +f 105//105 98//98 97//97
            +f 98//98 105//105 106//106
            +f 106//106 99//99 98//98
            +f 107//107 100//100 99//99
            +f 99//99 106//106 107//107
            +f 108//108 101//101 100//100
            +f 100//100 107//107 108//108
            +f 109//109 102//102 101//101
            +f 101//101 108//108 109//109
            +f 103//103 110//110 104//104
            +f 111//111 104//104 110//110
            +f 104//104 111//111 112//112
            +f 112//112 105//105 104//104
            +f 105//105 112//112 113//113
            +f 113//113 106//106 105//105
            +f 114//114 107//107 106//106
            +f 106//106 113//113 114//114
            +f 115//115 108//108 107//107
            +f 107//107 114//114 115//115
            +f 116//116 109//109 108//108
            +f 108//108 115//115 116//116
            +f 110//110 117//117 118//118
            +f 118//118 111//111 110//110
            +f 111//111 118//118 119//119
            +f 119//119 112//112 111//111
            +f 112//112 119//119 113//113
            +f 120//120 113//113 119//119
            +f 121//121 114//114 120//120
            +f 113//113 120//120 114//114
            +f 122//122 115//115 121//121
            +f 114//114 121//121 115//115
            +f 123//123 116//116 122//122
            +f 115//115 122//122 116//116
            +f 117//117 124//124 125//125
            +f 125//125 118//118 117//117
            +f 118//118 125//125 119//119
            +f 126//126 119//119 125//125
            +f 119//119 126//126 120//120
            +f 127//127 120//120 126//126
            +f 128//128 121//121 127//127
            +f 120//120 127//127 121//121
            +f 129//129 122//122 128//128
            +f 121//121 128//128 122//122
            +f 130//130 123//123 129//129
            +f 122//122 129//129 123//123
            +f 124//124 131//131 132//132
            +f 132//132 125//125 124//124
            +f 125//125 132//132 133//133
            +f 133//133 126//126 125//125
            +f 126//126 133//133 127//127
            +f 134//134 127//127 133//133
            +f 135//135 128//128 134//134
            +f 127//127 134//134 128//128
            +f 136//136 129//129 135//135
            +f 128//128 135//135 129//129
            +f 137//137 130//130 136//136
            +f 129//129 136//136 130//130
            +f 131//131 138//138 132//132
            +f 139//139 132//132 138//138
            +f 132//132 139//139 140//140
            +f 140//140 133//133 132//132
            +f 133//133 140//140 141//141
            +f 141//141 134//134 133//133
            +f 142//142 135//135 134//134
            +f 134//134 141//141 142//142
            +f 143//143 136//136 135//135
            +f 135//135 142//142 143//143
            +f 144//144 137//137 136//136
            +f 136//136 143//143 144//144
            +f 138//138 145//145 139//139
            +f 146//146 139//139 145//145
            +f 139//139 146//146 147//147
            +f 147//147 140//140 139//139
            +f 140//140 147//147 148//148
            +f 148//148 141//141 140//140
            +f 149//149 142//142 141//141
            +f 141//141 148//148 149//149
            +f 150//150 143//143 142//142
            +f 142//142 149//149 150//150
            +f 151//151 144//144 143//143
            +f 143//143 150//150 151//151
            +f 145//145 152//152 146//146
            +f 153//153 146//146 152//152
            +f 146//146 153//153 154//154
            +f 154//154 147//147 146//146
            +f 147//147 154//154 155//155
            +f 155//155 148//148 147//147
            +f 156//156 149//149 148//148
            +f 148//148 155//155 156//156
            +f 157//157 150//150 149//149
            +f 149//149 156//156 157//157
            +f 158//158 151//151 150//150
            +f 150//150 157//157 158//158
            +f 152//152 159//159 160//160
            +f 160//160 153//153 152//152
            +f 153//153 160//160 154//154
            +f 161//161 154//154 160//160
            +f 154//154 161//161 155//155
            +f 162//162 155//155 161//161
            +f 163//163 156//156 162//162
            +f 155//155 162//162 156//156
            +f 164//164 157//157 163//163
            +f 156//156 163//163 157//157
            +f 165//165 158//158 164//164
            +f 157//157 164//164 158//158
            +f 159//159 166//166 167//167
            +f 167//167 160//160 159//159
            +f 160//160 167//167 161//161
            +f 168//168 161//161 167//167
            +f 161//161 168//168 162//162
            +f 169//169 162//162 168//168
            +f 170//170 163//163 169//169
            +f 162//162 169//169 163//163
            +f 171//171 164//164 170//170
            +f 163//163 170//170 164//164
            +f 172//172 165//165 171//171
            +f 164//164 171//171 165//165
            +f 166//166 173//173 174//174
            +f 174//174 167//167 166//166
            +f 167//167 174//174 168//168
            +f 175//175 168//168 174//174
            +f 168//168 175//175 169//169
            +f 176//176 169//169 175//175
            +f 177//177 170//170 176//176
            +f 169//169 176//176 170//170
            +f 178//178 171//171 177//177
            +f 170//170 177//177 171//171
            +f 179//179 172//172 178//178
            +f 171//171 178//178 172//172
            +f 173//173 180//180 174//174
            +f 181//181 174//174 180//180
            +f 174//174 181//181 175//175
            +f 182//182 175//175 181//181
            +f 175//175 182//182 183//183
            +f 183//183 176//176 175//175
            +f 184//184 177//177 176//176
            +f 176//176 183//183 184//184
            +f 185//185 178//178 177//177
            +f 177//177 184//184 185//185
            +f 186//186 179//179 178//178
            +f 178//178 185//185 186//186
            +f 180//180 187//187 181//181
            +f 188//188 181//181 187//187
            +f 181//181 188//188 189//189
            +f 189//189 182//182 181//181
            +f 182//182 189//189 190//190
            +f 190//190 183//183 182//182
            +f 191//191 184//184 183//183
            +f 183//183 190//190 191//191
            +f 192//192 185//185 184//184
            +f 184//184 191//191 192//192
            +f 193//193 186//186 185//185
            +f 185//185 192//192 193//193
            +f 187//187 26//26 188//188
            +f 29//29 188//188 26//26
            +f 188//188 29//29 189//189
            +f 30//30 189//189 29//29
            +f 189//189 30//30 32//32
            +f 32//32 190//190 189//189
            +f 35//35 191//191 190//190
            +f 190//190 32//32 35//35
            +f 37//37 192//192 191//191
            +f 191//191 35//35 37//37
            +f 39//39 193//193 192//192
            +f 192//192 37//37 39//39
            +f 194//194 195//195 38//38
            +f 39//39 38//38 195//195
            +f 196//196 197//197 194//194
            +f 195//195 194//194 197//197
            +f 198//198 199//199 196//196
            +f 197//197 196//196 199//199
            +f 200//200 201//201 198//198
            +f 199//199 198//198 201//201
            +f 202//202 203//203 200//200
            +f 201//201 200//200 203//203
            +f 204//204 205//205 202//202
            +f 203//203 202//202 205//205
            +f 206//206 194//194 46//46
            +f 38//38 46//46 194//194
            +f 207//207 196//196 206//206
            +f 194//194 206//206 196//196
            +f 208//208 198//198 207//207
            +f 196//196 207//207 198//198
            +f 209//209 200//200 208//208
            +f 198//198 208//208 200//200
            +f 210//210 202//202 209//209
            +f 200//200 209//209 202//202
            +f 211//211 204//204 210//210
            +f 202//202 210//210 204//204
            +f 212//212 206//206 53//53
            +f 46//46 53//53 206//206
            +f 213//213 207//207 212//212
            +f 206//206 212//212 207//207
            +f 214//214 208//208 213//213
            +f 207//207 213//213 208//208
            +f 215//215 209//209 214//214
            +f 208//208 214//214 209//209
            +f 216//216 210//210 215//215
            +f 209//209 215//215 210//210
            +f 217//217 211//211 216//216
            +f 210//210 216//216 211//211
            +f 218//218 212//212 53//53
            +f 53//53 60//60 218//218
            +f 219//219 213//213 212//212
            +f 212//212 218//218 219//219
            +f 220//220 214//214 213//213
            +f 213//213 219//219 220//220
            +f 221//221 215//215 214//214
            +f 214//214 220//220 221//221
            +f 222//222 216//216 215//215
            +f 215//215 221//221 222//222
            +f 223//223 217//217 216//216
            +f 216//216 222//222 223//223
            +f 224//224 218//218 60//60
            +f 60//60 67//67 224//224
            +f 225//225 219//219 218//218
            +f 218//218 224//224 225//225
            +f 226//226 220//220 219//219
            +f 219//219 225//225 226//226
            +f 227//227 221//221 220//220
            +f 220//220 226//226 227//227
            +f 228//228 222//222 221//221
            +f 221//221 227//227 228//228
            +f 229//229 223//223 222//222
            +f 222//222 228//228 229//229
            +f 230//230 224//224 67//67
            +f 67//67 74//74 230//230
            +f 231//231 225//225 224//224
            +f 224//224 230//230 231//231
            +f 232//232 226//226 225//225
            +f 225//225 231//231 232//232
            +f 233//233 227//227 226//226
            +f 226//226 232//232 233//233
            +f 234//234 228//228 227//227
            +f 227//227 233//233 234//234
            +f 235//235 229//229 228//228
            +f 228//228 234//234 235//235
            +f 236//236 230//230 81//81
            +f 74//74 81//81 230//230
            +f 237//237 231//231 236//236
            +f 230//230 236//236 231//231
            +f 238//238 232//232 237//237
            +f 231//231 237//237 232//232
            +f 239//239 233//233 238//238
            +f 232//232 238//238 233//233
            +f 240//240 234//234 239//239
            +f 233//233 239//239 234//234
            +f 241//241 235//235 240//240
            +f 234//234 240//240 235//235
            +f 242//242 236//236 88//88
            +f 81//81 88//88 236//236
            +f 243//243 237//237 242//242
            +f 236//236 242//242 237//237
            +f 244//244 238//238 243//243
            +f 237//237 243//243 238//238
            +f 245//245 239//239 244//244
            +f 238//238 244//244 239//239
            +f 246//246 240//240 245//245
            +f 239//239 245//245 240//240
            +f 247//247 241//241 246//246
            +f 240//240 246//246 241//241
            +f 248//248 242//242 95//95
            +f 88//88 95//95 242//242
            +f 249//249 243//243 248//248
            +f 242//242 248//248 243//243
            +f 250//250 244//244 249//249
            +f 243//243 249//249 244//244
            +f 251//251 245//245 250//250
            +f 244//244 250//250 245//245
            +f 252//252 246//246 251//251
            +f 245//245 251//251 246//246
            +f 253//253 247//247 252//252
            +f 246//246 252//252 247//247
            +f 254//254 248//248 95//95
            +f 95//95 102//102 254//254
            +f 255//255 249//249 248//248
            +f 248//248 254//254 255//255
            +f 256//256 250//250 249//249
            +f 249//249 255//255 256//256
            +f 257//257 251//251 250//250
            +f 250//250 256//256 257//257
            +f 258//258 252//252 251//251
            +f 251//251 257//257 258//258
            +f 259//259 253//253 252//252
            +f 252//252 258//258 259//259
            +f 260//260 254//254 102//102
            +f 102//102 109//109 260//260
            +f 261//261 255//255 254//254
            +f 254//254 260//260 261//261
            +f 262//262 256//256 255//255
            +f 255//255 261//261 262//262
            +f 263//263 257//257 256//256
            +f 256//256 262//262 263//263
            +f 264//264 258//258 257//257
            +f 257//257 263//263 264//264
            +f 265//265 259//259 258//258
            +f 258//258 264//264 265//265
            +f 266//266 260//260 109//109
            +f 109//109 116//116 266//266
            +f 267//267 261//261 260//260
            +f 260//260 266//266 267//267
            +f 268//268 262//262 261//261
            +f 261//261 267//267 268//268
            +f 269//269 263//263 262//262
            +f 262//262 268//268 269//269
            +f 270//270 264//264 263//263
            +f 263//263 269//269 270//270
            +f 271//271 265//265 264//264
            +f 264//264 270//270 271//271
            +f 272//272 266//266 123//123
            +f 116//116 123//123 266//266
            +f 273//273 267//267 272//272
            +f 266//266 272//272 267//267
            +f 274//274 268//268 273//273
            +f 267//267 273//273 268//268
            +f 275//275 269//269 274//274
            +f 268//268 274//274 269//269
            +f 276//276 270//270 275//275
            +f 269//269 275//275 270//270
            +f 277//277 271//271 276//276
            +f 270//270 276//276 271//271
            +f 278//278 272//272 130//130
            +f 123//123 130//130 272//272
            +f 279//279 273//273 278//278
            +f 272//272 278//278 273//273
            +f 280//280 274//274 279//279
            +f 273//273 279//279 274//274
            +f 281//281 275//275 280//280
            +f 274//274 280//280 275//275
            +f 282//282 276//276 281//281
            +f 275//275 281//281 276//276
            +f 283//283 277//277 282//282
            +f 276//276 282//282 277//277
            +f 284//284 278//278 137//137
            +f 130//130 137//137 278//278
            +f 285//285 279//279 284//284
            +f 278//278 284//284 279//279
            +f 286//286 280//280 285//285
            +f 279//279 285//285 280//280
            +f 287//287 281//281 286//286
            +f 280//280 286//286 281//281
            +f 288//288 282//282 287//287
            +f 281//281 287//287 282//282
            +f 289//289 283//283 288//288
            +f 282//282 288//288 283//283
            +f 290//290 284//284 137//137
            +f 137//137 144//144 290//290
            +f 291//291 285//285 284//284
            +f 284//284 290//290 291//291
            +f 292//292 286//286 285//285
            +f 285//285 291//291 292//292
            +f 293//293 287//287 286//286
            +f 286//286 292//292 293//293
            +f 294//294 288//288 287//287
            +f 287//287 293//293 294//294
            +f 295//295 289//289 288//288
            +f 288//288 294//294 295//295
            +f 296//296 290//290 144//144
            +f 144//144 151//151 296//296
            +f 297//297 291//291 290//290
            +f 290//290 296//296 297//297
            +f 298//298 292//292 291//291
            +f 291//291 297//297 298//298
            +f 299//299 293//293 292//292
            +f 292//292 298//298 299//299
            +f 300//300 294//294 293//293
            +f 293//293 299//299 300//300
            +f 301//301 295//295 294//294
            +f 294//294 300//300 301//301
            +f 302//302 296//296 151//151
            +f 151//151 158//158 302//302
            +f 303//303 297//297 296//296
            +f 296//296 302//302 303//303
            +f 304//304 298//298 297//297
            +f 297//297 303//303 304//304
            +f 305//305 299//299 298//298
            +f 298//298 304//304 305//305
            +f 306//306 300//300 299//299
            +f 299//299 305//305 306//306
            +f 307//307 301//301 300//300
            +f 300//300 306//306 307//307
            +f 308//308 302//302 165//165
            +f 158//158 165//165 302//302
            +f 309//309 303//303 308//308
            +f 302//302 308//308 303//303
            +f 310//310 304//304 309//309
            +f 303//303 309//309 304//304
            +f 311//311 305//305 310//310
            +f 304//304 310//310 305//305
            +f 312//312 306//306 311//311
            +f 305//305 311//311 306//306
            +f 313//313 307//307 312//312
            +f 306//306 312//312 307//307
            +f 314//314 308//308 172//172
            +f 165//165 172//172 308//308
            +f 315//315 309//309 314//314
            +f 308//308 314//314 309//309
            +f 316//316 310//310 315//315
            +f 309//309 315//315 310//310
            +f 317//317 311//311 316//316
            +f 310//310 316//316 311//311
            +f 318//318 312//312 317//317
            +f 311//311 317//317 312//312
            +f 319//319 313//313 318//318
            +f 312//312 318//318 313//313
            +f 320//320 314//314 179//179
            +f 172//172 179//179 314//314
            +f 321//321 315//315 320//320
            +f 314//314 320//320 315//315
            +f 322//322 316//316 321//321
            +f 315//315 321//321 316//316
            +f 323//323 317//317 322//322
            +f 316//316 322//322 317//317
            +f 324//324 318//318 323//323
            +f 317//317 323//323 318//318
            +f 325//325 319//319 324//324
            +f 318//318 324//324 319//319
            +f 326//326 320//320 179//179
            +f 179//179 186//186 326//326
            +f 327//327 321//321 320//320
            +f 320//320 326//326 327//327
            +f 328//328 322//322 321//321
            +f 321//321 327//327 328//328
            +f 329//329 323//323 322//322
            +f 322//322 328//328 329//329
            +f 330//330 324//324 323//323
            +f 323//323 329//329 330//330
            +f 331//331 325//325 324//324
            +f 324//324 330//330 331//331
            +f 332//332 326//326 186//186
            +f 186//186 193//193 332//332
            +f 333//333 327//327 326//326
            +f 326//326 332//332 333//333
            +f 334//334 328//328 327//327
            +f 327//327 333//333 334//334
            +f 335//335 329//329 328//328
            +f 328//328 334//334 335//335
            +f 336//336 330//330 329//329
            +f 329//329 335//335 336//336
            +f 337//337 331//331 330//330
            +f 330//330 336//336 337//337
            +f 195//195 332//332 193//193
            +f 193//193 39//39 195//195
            +f 197//197 333//333 332//332
            +f 332//332 195//195 197//197
            +f 199//199 334//334 333//333
            +f 333//333 197//197 199//199
            +f 201//201 335//335 334//334
            +f 334//334 199//199 201//201
            +f 203//203 336//336 335//335
            +f 335//335 201//201 203//203
            +f 205//205 337//337 336//336
            +f 336//336 203//203 205//205
            +f 338//338 339//339 205//205
            +f 205//205 204//204 338//338
            +f 340//340 341//341 339//339
            +f 339//339 338//338 340//340
            +f 342//342 343//343 341//341
            +f 341//341 340//340 342//342
            +f 344//344 345//345 343//343
            +f 343//343 342//342 344//344
            +f 346//346 347//347 345//345
            +f 345//345 344//344 346//346
            +f 348//348 349//349 347//347
            +f 347//347 346//346 348//348
            +f 350//350 338//338 204//204
            +f 204//204 211//211 350//350
            +f 351//351 340//340 338//338
            +f 338//338 350//350 351//351
            +f 352//352 342//342 340//340
            +f 340//340 351//351 352//352
            +f 353//353 344//344 342//342
            +f 342//342 352//352 353//353
            +f 354//354 346//346 344//344
            +f 344//344 353//353 354//354
            +f 355//355 348//348 346//346
            +f 346//346 354//354 355//355
            +f 356//356 350//350 211//211
            +f 211//211 217//217 356//356
            +f 357//357 351//351 350//350
            +f 350//350 356//356 357//357
            +f 358//358 352//352 351//351
            +f 351//351 357//357 358//358
            +f 359//359 353//353 352//352
            +f 352//352 358//358 359//359
            +f 360//360 354//354 353//353
            +f 353//353 359//359 360//360
            +f 361//361 355//355 354//354
            +f 354//354 360//360 361//361
            +f 362//362 356//356 223//223
            +f 217//217 223//223 356//356
            +f 363//363 357//357 362//362
            +f 356//356 362//362 357//357
            +f 364//364 358//358 363//363
            +f 357//357 363//363 358//358
            +f 365//365 359//359 364//364
            +f 358//358 364//364 359//359
            +f 366//366 360//360 365//365
            +f 359//359 365//365 360//360
            +f 367//367 361//361 366//366
            +f 360//360 366//366 361//361
            +f 368//368 362//362 229//229
            +f 223//223 229//229 362//362
            +f 369//369 363//363 368//368
            +f 362//362 368//368 363//363
            +f 370//370 364//364 369//369
            +f 363//363 369//369 364//364
            +f 371//371 365//365 370//370
            +f 364//364 370//370 365//365
            +f 372//372 366//366 371//371
            +f 365//365 371//371 366//366
            +f 373//373 367//367 372//372
            +f 366//366 372//372 367//367
            +f 374//374 368//368 235//235
            +f 229//229 235//235 368//368
            +f 375//375 369//369 374//374
            +f 368//368 374//374 369//369
            +f 376//376 370//370 375//375
            +f 369//369 375//375 370//370
            +f 377//377 371//371 376//376
            +f 370//370 376//376 371//371
            +f 378//378 372//372 377//377
            +f 371//371 377//377 372//372
            +f 379//379 373//373 378//378
            +f 372//372 378//378 373//373
            +f 380//380 374//374 235//235
            +f 235//235 241//241 380//380
            +f 381//381 375//375 374//374
            +f 374//374 380//380 381//381
            +f 382//382 376//376 375//375
            +f 375//375 381//381 382//382
            +f 383//383 377//377 376//376
            +f 376//376 382//382 383//383
            +f 384//384 378//378 377//377
            +f 377//377 383//383 384//384
            +f 385//385 379//379 378//378
            +f 378//378 384//384 385//385
            +f 386//386 380//380 241//241
            +f 241//241 247//247 386//386
            +f 387//387 381//381 380//380
            +f 380//380 386//386 387//387
            +f 388//388 382//382 381//381
            +f 381//381 387//387 388//388
            +f 389//389 383//383 382//382
            +f 382//382 388//388 389//389
            +f 390//390 384//384 383//383
            +f 383//383 389//389 390//390
            +f 391//391 385//385 384//384
            +f 384//384 390//390 391//391
            +f 392//392 386//386 247//247
            +f 247//247 253//253 392//392
            +f 393//393 387//387 386//386
            +f 386//386 392//392 393//393
            +f 394//394 388//388 387//387
            +f 387//387 393//393 394//394
            +f 395//395 389//389 388//388
            +f 388//388 394//394 395//395
            +f 396//396 390//390 389//389
            +f 389//389 395//395 396//396
            +f 397//397 391//391 390//390
            +f 390//390 396//396 397//397
            +f 398//398 392//392 259//259
            +f 253//253 259//259 392//392
            +f 399//399 393//393 398//398
            +f 392//392 398//398 393//393
            +f 400//400 394//394 399//399
            +f 393//393 399//399 394//394
            +f 401//401 395//395 400//400
            +f 394//394 400//400 395//395
            +f 402//402 396//396 401//401
            +f 395//395 401//401 396//396
            +f 403//403 397//397 402//402
            +f 396//396 402//402 397//397
            +f 404//404 398//398 265//265
            +f 259//259 265//265 398//398
            +f 405//405 399//399 404//404
            +f 398//398 404//404 399//399
            +f 406//406 400//400 405//405
            +f 399//399 405//405 400//400
            +f 407//407 401//401 406//406
            +f 400//400 406//406 401//401
            +f 408//408 402//402 407//407
            +f 401//401 407//407 402//402
            +f 409//409 403//403 408//408
            +f 402//402 408//408 403//403
            +f 410//410 404//404 271//271
            +f 265//265 271//271 404//404
            +f 411//411 405//405 410//410
            +f 404//404 410//410 405//405
            +f 412//412 406//406 411//411
            +f 405//405 411//411 406//406
            +f 413//413 407//407 412//412
            +f 406//406 412//412 407//407
            +f 414//414 408//408 413//413
            +f 407//407 413//413 408//408
            +f 415//415 409//409 414//414
            +f 408//408 414//414 409//409
            +f 416//416 410//410 271//271
            +f 271//271 277//277 416//416
            +f 417//417 411//411 410//410
            +f 410//410 416//416 417//417
            +f 418//418 412//412 411//411
            +f 411//411 417//417 418//418
            +f 419//419 413//413 412//412
            +f 412//412 418//418 419//419
            +f 420//420 414//414 413//413
            +f 413//413 419//419 420//420
            +f 421//421 415//415 414//414
            +f 414//414 420//420 421//421
            +f 422//422 416//416 277//277
            +f 277//277 283//283 422//422
            +f 423//423 417//417 416//416
            +f 416//416 422//422 423//423
            +f 424//424 418//418 417//417
            +f 417//417 423//423 424//424
            +f 425//425 419//419 418//418
            +f 418//418 424//424 425//425
            +f 426//426 420//420 419//419
            +f 419//419 425//425 426//426
            +f 427//427 421//421 420//420
            +f 420//420 426//426 427//427
            +f 428//428 422//422 283//283
            +f 283//283 289//289 428//428
            +f 429//429 423//423 422//422
            +f 422//422 428//428 429//429
            +f 430//430 424//424 423//423
            +f 423//423 429//429 430//430
            +f 431//431 425//425 424//424
            +f 424//424 430//430 431//431
            +f 432//432 426//426 425//425
            +f 425//425 431//431 432//432
            +f 433//433 427//427 426//426
            +f 426//426 432//432 433//433
            +f 434//434 428//428 295//295
            +f 289//289 295//295 428//428
            +f 435//435 429//429 434//434
            +f 428//428 434//434 429//429
            +f 436//436 430//430 435//435
            +f 429//429 435//435 430//430
            +f 437//437 431//431 436//436
            +f 430//430 436//436 431//431
            +f 438//438 432//432 437//437
            +f 431//431 437//437 432//432
            +f 439//439 433//433 438//438
            +f 432//432 438//438 433//433
            +f 440//440 434//434 301//301
            +f 295//295 301//301 434//434
            +f 441//441 435//435 440//440
            +f 434//434 440//440 435//435
            +f 442//442 436//436 441//441
            +f 435//435 441//441 436//436
            +f 443//443 437//437 442//442
            +f 436//436 442//442 437//437
            +f 444//444 438//438 443//443
            +f 437//437 443//443 438//438
            +f 445//445 439//439 444//444
            +f 438//438 444//444 439//439
            +f 446//446 440//440 307//307
            +f 301//301 307//307 440//440
            +f 447//447 441//441 446//446
            +f 440//440 446//446 441//441
            +f 448//448 442//442 447//447
            +f 441//441 447//447 442//442
            +f 449//449 443//443 448//448
            +f 442//442 448//448 443//443
            +f 450//450 444//444 449//449
            +f 443//443 449//449 444//444
            +f 451//451 445//445 450//450
            +f 444//444 450//450 445//445
            +f 452//452 446//446 307//307
            +f 307//307 313//313 452//452
            +f 453//453 447//447 446//446
            +f 446//446 452//452 453//453
            +f 454//454 448//448 447//447
            +f 447//447 453//453 454//454
            +f 455//455 449//449 448//448
            +f 448//448 454//454 455//455
            +f 456//456 450//450 449//449
            +f 449//449 455//455 456//456
            +f 457//457 451//451 450//450
            +f 450//450 456//456 457//457
            +f 458//458 452//452 313//313
            +f 313//313 319//319 458//458
            +f 459//459 453//453 452//452
            +f 452//452 458//458 459//459
            +f 460//460 454//454 453//453
            +f 453//453 459//459 460//460
            +f 461//461 455//455 454//454
            +f 454//454 460//460 461//461
            +f 462//462 456//456 455//455
            +f 455//455 461//461 462//462
            +f 463//463 457//457 456//456
            +f 456//456 462//462 463//463
            +f 464//464 458//458 319//319
            +f 319//319 325//325 464//464
            +f 465//465 459//459 458//458
            +f 458//458 464//464 465//465
            +f 466//466 460//460 459//459
            +f 459//459 465//465 466//466
            +f 467//467 461//461 460//460
            +f 460//460 466//466 467//467
            +f 468//468 462//462 461//461
            +f 461//461 467//467 468//468
            +f 469//469 463//463 462//462
            +f 462//462 468//468 469//469
            +f 470//470 464//464 331//331
            +f 325//325 331//331 464//464
            +f 471//471 465//465 470//470
            +f 464//464 470//470 465//465
            +f 472//472 466//466 471//471
            +f 465//465 471//471 466//466
            +f 473//473 467//467 472//472
            +f 466//466 472//472 467//467
            +f 474//474 468//468 473//473
            +f 467//467 473//473 468//468
            +f 475//475 469//469 474//474
            +f 468//468 474//474 469//469
            +f 476//476 470//470 337//337
            +f 331//331 337//337 470//470
            +f 477//477 471//471 476//476
            +f 470//470 476//476 471//471
            +f 478//478 472//472 477//477
            +f 471//471 477//477 472//472
            +f 479//479 473//473 478//478
            +f 472//472 478//478 473//473
            +f 480//480 474//474 479//479
            +f 473//473 479//479 474//474
            +f 481//481 475//475 480//480
            +f 474//474 480//480 475//475
            +f 339//339 476//476 205//205
            +f 337//337 205//205 476//476
            +f 341//341 477//477 339//339
            +f 476//476 339//339 477//477
            +f 343//343 478//478 341//341
            +f 477//477 341//341 478//478
            +f 345//345 479//479 343//343
            +f 478//478 343//343 479//479
            +f 347//347 480//480 345//345
            +f 479//479 345//345 480//480
            +f 349//349 481//481 347//347
            +f 480//480 347//347 481//481
            +f 1//1 3//3 482//482
            +f 483//483 482//482 3//3
            +f 482//482 483//483 484//484
            +f 485//485 484//484 483//483
            +f 484//484 485//485 486//486
            +f 487//487 486//486 485//485
            +f 486//486 487//487 488//488
            +f 489//489 488//488 487//487
            +f 488//488 489//489 349//349
            +f 481//481 349//349 489//489
            +f 3//3 4//4 483//483
            +f 490//490 483//483 4//4
            +f 483//483 490//490 485//485
            +f 491//491 485//485 490//490
            +f 485//485 491//491 487//487
            +f 492//492 487//487 491//491
            +f 487//487 492//492 489//489
            +f 493//493 489//489 492//492
            +f 489//489 493//493 481//481
            +f 475//475 481//481 493//493
            +f 4//4 5//5 490//490
            +f 494//494 490//490 5//5
            +f 490//490 494//494 491//491
            +f 495//495 491//491 494//494
            +f 491//491 495//495 492//492
            +f 496//496 492//492 495//495
            +f 492//492 496//496 493//493
            +f 497//497 493//493 496//496
            +f 493//493 497//497 475//475
            +f 469//469 475//475 497//497
            +f 5//5 6//6 498//498
            +f 498//498 494//494 5//5
            +f 494//494 498//498 499//499
            +f 499//499 495//495 494//494
            +f 495//495 499//499 500//500
            +f 500//500 496//496 495//495
            +f 496//496 500//500 501//501
            +f 501//501 497//497 496//496
            +f 497//497 501//501 463//463
            +f 463//463 469//469 497//497
            +f 6//6 7//7 502//502
            +f 502//502 498//498 6//6
            +f 498//498 502//502 503//503
            +f 503//503 499//499 498//498
            +f 499//499 503//503 504//504
            +f 504//504 500//500 499//499
            +f 500//500 504//504 505//505
            +f 505//505 501//501 500//500
            +f 501//501 505//505 457//457
            +f 457//457 463//463 501//501
            +f 7//7 8//8 506//506
            +f 506//506 502//502 7//7
            +f 502//502 506//506 507//507
            +f 507//507 503//503 502//502
            +f 503//503 507//507 508//508
            +f 508//508 504//504 503//503
            +f 504//504 508//508 509//509
            +f 509//509 505//505 504//504
            +f 505//505 509//509 451//451
            +f 451//451 457//457 505//505
            +f 8//8 9//9 506//506
            +f 510//510 506//506 9//9
            +f 506//506 510//510 507//507
            +f 511//511 507//507 510//510
            +f 507//507 511//511 508//508
            +f 512//512 508//508 511//511
            +f 508//508 512//512 509//509
            +f 513//513 509//509 512//512
            +f 509//509 513//513 451//451
            +f 445//445 451//451 513//513
            +f 9//9 10//10 510//510
            +f 514//514 510//510 10//10
            +f 510//510 514//514 511//511
            +f 515//515 511//511 514//514
            +f 511//511 515//515 512//512
            +f 516//516 512//512 515//515
            +f 512//512 516//516 513//513
            +f 517//517 513//513 516//516
            +f 513//513 517//517 445//445
            +f 439//439 445//445 517//517
            +f 10//10 11//11 514//514
            +f 518//518 514//514 11//11
            +f 514//514 518//518 515//515
            +f 519//519 515//515 518//518
            +f 515//515 519//519 516//516
            +f 520//520 516//516 519//519
            +f 516//516 520//520 517//517
            +f 521//521 517//517 520//520
            +f 517//517 521//521 439//439
            +f 433//433 439//439 521//521
            +f 11//11 12//12 522//522
            +f 522//522 518//518 11//11
            +f 518//518 522//522 523//523
            +f 523//523 519//519 518//518
            +f 519//519 523//523 524//524
            +f 524//524 520//520 519//519
            +f 520//520 524//524 525//525
            +f 525//525 521//521 520//520
            +f 521//521 525//525 427//427
            +f 427//427 433//433 521//521
            +f 12//12 13//13 526//526
            +f 526//526 522//522 12//12
            +f 522//522 526//526 527//527
            +f 527//527 523//523 522//522
            +f 523//523 527//527 528//528
            +f 528//528 524//524 523//523
            +f 524//524 528//528 529//529
            +f 529//529 525//525 524//524
            +f 525//525 529//529 421//421
            +f 421//421 427//427 525//525
            +f 13//13 14//14 530//530
            +f 530//530 526//526 13//13
            +f 526//526 530//530 531//531
            +f 531//531 527//527 526//526
            +f 527//527 531//531 532//532
            +f 532//532 528//528 527//527
            +f 528//528 532//532 533//533
            +f 533//533 529//529 528//528
            +f 529//529 533//533 415//415
            +f 415//415 421//421 529//529
            +f 14//14 15//15 530//530
            +f 534//534 530//530 15//15
            +f 530//530 534//534 531//531
            +f 535//535 531//531 534//534
            +f 531//531 535//535 532//532
            +f 536//536 532//532 535//535
            +f 532//532 536//536 533//533
            +f 537//537 533//533 536//536
            +f 533//533 537//537 415//415
            +f 409//409 415//415 537//537
            +f 15//15 16//16 534//534
            +f 538//538 534//534 16//16
            +f 534//534 538//538 535//535
            +f 539//539 535//535 538//538
            +f 535//535 539//539 536//536
            +f 540//540 536//536 539//539
            +f 536//536 540//540 537//537
            +f 541//541 537//537 540//540
            +f 537//537 541//541 409//409
            +f 403//403 409//409 541//541
            +f 16//16 17//17 538//538
            +f 542//542 538//538 17//17
            +f 538//538 542//542 539//539
            +f 543//543 539//539 542//542
            +f 539//539 543//543 540//540
            +f 544//544 540//540 543//543
            +f 540//540 544//544 541//541
            +f 545//545 541//541 544//544
            +f 541//541 545//545 403//403
            +f 397//397 403//403 545//545
            +f 17//17 18//18 546//546
            +f 546//546 542//542 17//17
            +f 542//542 546//546 547//547
            +f 547//547 543//543 542//542
            +f 543//543 547//547 548//548
            +f 548//548 544//544 543//543
            +f 544//544 548//548 549//549
            +f 549//549 545//545 544//544
            +f 545//545 549//549 391//391
            +f 391//391 397//397 545//545
            +f 18//18 19//19 550//550
            +f 550//550 546//546 18//18
            +f 546//546 550//550 551//551
            +f 551//551 547//547 546//546
            +f 547//547 551//551 552//552
            +f 552//552 548//548 547//547
            +f 548//548 552//552 553//553
            +f 553//553 549//549 548//548
            +f 549//549 553//553 385//385
            +f 385//385 391//391 549//549
            +f 19//19 20//20 554//554
            +f 554//554 550//550 19//19
            +f 550//550 554//554 555//555
            +f 555//555 551//551 550//550
            +f 551//551 555//555 556//556
            +f 556//556 552//552 551//551
            +f 552//552 556//556 557//557
            +f 557//557 553//553 552//552
            +f 553//553 557//557 379//379
            +f 379//379 385//385 553//553
            +f 20//20 21//21 554//554
            +f 558//558 554//554 21//21
            +f 554//554 558//558 555//555
            +f 559//559 555//555 558//558
            +f 555//555 559//559 556//556
            +f 560//560 556//556 559//559
            +f 556//556 560//560 557//557
            +f 561//561 557//557 560//560
            +f 557//557 561//561 379//379
            +f 373//373 379//379 561//561
            +f 21//21 22//22 558//558
            +f 562//562 558//558 22//22
            +f 558//558 562//562 559//559
            +f 563//563 559//559 562//562
            +f 559//559 563//563 560//560
            +f 564//564 560//560 563//563
            +f 560//560 564//564 561//561
            +f 565//565 561//561 564//564
            +f 561//561 565//565 373//373
            +f 367//367 373//373 565//565
            +f 22//22 23//23 562//562
            +f 566//566 562//562 23//23
            +f 562//562 566//566 563//563
            +f 567//567 563//563 566//566
            +f 563//563 567//567 564//564
            +f 568//568 564//564 567//567
            +f 564//564 568//568 565//565
            +f 569//569 565//565 568//568
            +f 565//565 569//569 367//367
            +f 361//361 367//367 569//569
            +f 23//23 24//24 570//570
            +f 570//570 566//566 23//23
            +f 566//566 570//570 571//571
            +f 571//571 567//567 566//566
            +f 567//567 571//571 572//572
            +f 572//572 568//568 567//567
            +f 568//568 572//572 573//573
            +f 573//573 569//569 568//568
            +f 569//569 573//573 355//355
            +f 355//355 361//361 569//569
            +f 24//24 25//25 574//574
            +f 574//574 570//570 24//24
            +f 570//570 574//574 575//575
            +f 575//575 571//571 570//570
            +f 571//571 575//575 576//576
            +f 576//576 572//572 571//571
            +f 572//572 576//576 577//577
            +f 577//577 573//573 572//572
            +f 573//573 577//577 348//348
            +f 348//348 355//355 573//573
            +f 25//25 1//1 482//482
            +f 482//482 574//574 25//25
            +f 574//574 482//482 484//484
            +f 484//484 575//575 574//574
            +f 575//575 484//484 486//486
            +f 486//486 576//576 575//575
            +f 576//576 486//486 488//488
            +f 488//488 577//577 576//576
            +f 577//577 488//488 349//349
            +f 349//349 348//348 577//577
            +f 578//578 579//579 580//580
            +f 581//581 580//580 579//579
            +f 582//582 578//578 583//583
            +f 580//580 583//583 578//578
            +f 584//584 582//582 585//585
            +f 583//583 585//585 582//582
            +f 586//586 584//584 585//585
            +f 585//585 587//587 586//586
            +f 588//588 586//586 587//587
            +f 587//587 589//589 588//588
            +f 590//590 588//588 589//589
            +f 589//589 591//591 590//590
            +f 592//592 590//590 593//593
            +f 591//591 593//593 590//590
            +f 594//594 592//592 595//595
            +f 593//593 595//595 592//592
            +f 596//596 594//594 597//597
            +f 595//595 597//597 594//594
            +f 598//598 596//596 597//597
            +f 597//597 599//599 598//598
            +f 600//600 598//598 599//599
            +f 599//599 601//601 600//600
            +f 602//602 600//600 601//601
            +f 601//601 603//603 602//602
            +f 604//604 602//602 605//605
            +f 603//603 605//605 602//602
            +f 606//606 604//604 607//607
            +f 605//605 607//607 604//604
            +f 608//608 606//606 609//609
            +f 607//607 609//609 606//606
            +f 610//610 608//608 609//609
            +f 609//609 611//611 610//610
            +f 612//612 610//610 611//611
            +f 611//611 613//613 612//612
            +f 614//614 612//612 613//613
            +f 613//613 615//615 614//614
            +f 616//616 614//614 617//617
            +f 615//615 617//617 614//614
            +f 618//618 616//616 619//619
            +f 617//617 619//619 616//616
            +f 620//620 618//618 621//621
            +f 619//619 621//621 618//618
            +f 622//622 620//620 621//621
            +f 621//621 623//623 622//622
            +f 624//624 622//622 623//623
            +f 623//623 625//625 624//624
            +f 579//579 624//624 625//625
            +f 625//625 581//581 579//579
            +f 626//626 627//627 578//578
            +f 579//579 578//578 627//627
            +f 628//628 629//629 626//626
            +f 627//627 626//626 629//629
            +f 630//630 631//631 628//628
            +f 629//629 628//628 631//631
            +f 632//632 633//633 630//630
            +f 631//631 630//630 633//633
            +f 634//634 635//635 632//632
            +f 633//633 632//632 635//635
            +f 636//636 637//637 634//634
            +f 635//635 634//634 637//637
            +f 638//638 626//626 582//582
            +f 578//578 582//582 626//626
            +f 639//639 628//628 638//638
            +f 626//626 638//638 628//628
            +f 640//640 630//630 639//639
            +f 628//628 639//639 630//630
            +f 641//641 632//632 640//640
            +f 630//630 640//640 632//632
            +f 642//642 634//634 641//641
            +f 632//632 641//641 634//634
            +f 643//643 636//636 642//642
            +f 634//634 642//642 636//636
            +f 644//644 638//638 584//584
            +f 582//582 584//584 638//638
            +f 645//645 639//639 644//644
            +f 638//638 644//644 639//639
            +f 646//646 640//640 645//645
            +f 639//639 645//645 640//640
            +f 647//647 641//641 646//646
            +f 640//640 646//646 641//641
            +f 648//648 642//642 647//647
            +f 641//641 647//647 642//642
            +f 649//649 643//643 648//648
            +f 642//642 648//648 643//643
            +f 650//650 644//644 584//584
            +f 584//584 586//586 650//650
            +f 651//651 645//645 644//644
            +f 644//644 650//650 651//651
            +f 652//652 646//646 645//645
            +f 645//645 651//651 652//652
            +f 653//653 647//647 646//646
            +f 646//646 652//652 653//653
            +f 654//654 648//648 647//647
            +f 647//647 653//653 654//654
            +f 655//655 649//649 648//648
            +f 648//648 654//654 655//655
            +f 656//656 650//650 586//586
            +f 586//586 588//588 656//656
            +f 657//657 651//651 650//650
            +f 650//650 656//656 657//657
            +f 658//658 652//652 651//651
            +f 651//651 657//657 658//658
            +f 659//659 653//653 652//652
            +f 652//652 658//658 659//659
            +f 660//660 654//654 653//653
            +f 653//653 659//659 660//660
            +f 661//661 655//655 654//654
            +f 654//654 660//660 661//661
            +f 662//662 656//656 588//588
            +f 588//588 590//590 662//662
            +f 663//663 657//657 656//656
            +f 656//656 662//662 663//663
            +f 664//664 658//658 657//657
            +f 657//657 663//663 664//664
            +f 665//665 659//659 658//658
            +f 658//658 664//664 665//665
            +f 666//666 660//660 659//659
            +f 659//659 665//665 666//666
            +f 667//667 661//661 660//660
            +f 660//660 666//666 667//667
            +f 668//668 662//662 592//592
            +f 590//590 592//592 662//662
            +f 669//669 663//663 668//668
            +f 662//662 668//668 663//663
            +f 670//670 664//664 669//669
            +f 663//663 669//669 664//664
            +f 671//671 665//665 670//670
            +f 664//664 670//670 665//665
            +f 672//672 666//666 671//671
            +f 665//665 671//671 666//666
            +f 673//673 667//667 672//672
            +f 666//666 672//672 667//667
            +f 674//674 668//668 594//594
            +f 592//592 594//594 668//668
            +f 675//675 669//669 674//674
            +f 668//668 674//674 669//669
            +f 676//676 670//670 675//675
            +f 669//669 675//675 670//670
            +f 677//677 671//671 676//676
            +f 670//670 676//676 671//671
            +f 678//678 672//672 677//677
            +f 671//671 677//677 672//672
            +f 679//679 673//673 678//678
            +f 672//672 678//678 673//673
            +f 680//680 674//674 596//596
            +f 594//594 596//596 674//674
            +f 681//681 675//675 680//680
            +f 674//674 680//680 675//675
            +f 682//682 676//676 681//681
            +f 675//675 681//681 676//676
            +f 683//683 677//677 682//682
            +f 676//676 682//682 677//677
            +f 684//684 678//678 683//683
            +f 677//677 683//683 678//678
            +f 685//685 679//679 684//684
            +f 678//678 684//684 679//679
            +f 686//686 680//680 596//596
            +f 596//596 598//598 686//686
            +f 687//687 681//681 680//680
            +f 680//680 686//686 687//687
            +f 688//688 682//682 681//681
            +f 681//681 687//687 688//688
            +f 689//689 683//683 682//682
            +f 682//682 688//688 689//689
            +f 690//690 684//684 683//683
            +f 683//683 689//689 690//690
            +f 691//691 685//685 684//684
            +f 684//684 690//690 691//691
            +f 692//692 686//686 598//598
            +f 598//598 600//600 692//692
            +f 693//693 687//687 686//686
            +f 686//686 692//692 693//693
            +f 694//694 688//688 687//687
            +f 687//687 693//693 694//694
            +f 695//695 689//689 688//688
            +f 688//688 694//694 695//695
            +f 696//696 690//690 689//689
            +f 689//689 695//695 696//696
            +f 697//697 691//691 690//690
            +f 690//690 696//696 697//697
            +f 698//698 692//692 600//600
            +f 600//600 602//602 698//698
            +f 699//699 693//693 692//692
            +f 692//692 698//698 699//699
            +f 700//700 694//694 693//693
            +f 693//693 699//699 700//700
            +f 701//701 695//695 694//694
            +f 694//694 700//700 701//701
            +f 702//702 696//696 695//695
            +f 695//695 701//701 702//702
            +f 703//703 697//697 696//696
            +f 696//696 702//702 703//703
            +f 704//704 698//698 604//604
            +f 602//602 604//604 698//698
            +f 705//705 699//699 704//704
            +f 698//698 704//704 699//699
            +f 706//706 700//700 705//705
            +f 699//699 705//705 700//700
            +f 707//707 701//701 706//706
            +f 700//700 706//706 701//701
            +f 708//708 702//702 707//707
            +f 701//701 707//707 702//702
            +f 709//709 703//703 708//708
            +f 702//702 708//708 703//703
            +f 710//710 704//704 606//606
            +f 604//604 606//606 704//704
            +f 711//711 705//705 710//710
            +f 704//704 710//710 705//705
            +f 712//712 706//706 711//711
            +f 705//705 711//711 706//706
            +f 713//713 707//707 712//712
            +f 706//706 712//712 707//707
            +f 714//714 708//708 713//713
            +f 707//707 713//713 708//708
            +f 715//715 709//709 714//714
            +f 708//708 714//714 709//709
            +f 716//716 710//710 608//608
            +f 606//606 608//608 710//710
            +f 717//717 711//711 716//716
            +f 710//710 716//716 711//711
            +f 718//718 712//712 717//717
            +f 711//711 717//717 712//712
            +f 719//719 713//713 718//718
            +f 712//712 718//718 713//713
            +f 720//720 714//714 719//719
            +f 713//713 719//719 714//714
            +f 721//721 715//715 720//720
            +f 714//714 720//720 715//715
            +f 722//722 716//716 608//608
            +f 608//608 610//610 722//722
            +f 723//723 717//717 716//716
            +f 716//716 722//722 723//723
            +f 724//724 718//718 717//717
            +f 717//717 723//723 724//724
            +f 725//725 719//719 718//718
            +f 718//718 724//724 725//725
            +f 726//726 720//720 719//719
            +f 719//719 725//725 726//726
            +f 727//727 721//721 720//720
            +f 720//720 726//726 727//727
            +f 728//728 722//722 610//610
            +f 610//610 612//612 728//728
            +f 729//729 723//723 722//722
            +f 722//722 728//728 729//729
            +f 730//730 724//724 723//723
            +f 723//723 729//729 730//730
            +f 731//731 725//725 724//724
            +f 724//724 730//730 731//731
            +f 732//732 726//726 725//725
            +f 725//725 731//731 732//732
            +f 733//733 727//727 726//726
            +f 726//726 732//732 733//733
            +f 734//734 728//728 612//612
            +f 612//612 614//614 734//734
            +f 735//735 729//729 728//728
            +f 728//728 734//734 735//735
            +f 736//736 730//730 729//729
            +f 729//729 735//735 736//736
            +f 737//737 731//731 730//730
            +f 730//730 736//736 737//737
            +f 738//738 732//732 731//731
            +f 731//731 737//737 738//738
            +f 739//739 733//733 732//732
            +f 732//732 738//738 739//739
            +f 740//740 734//734 616//616
            +f 614//614 616//616 734//734
            +f 741//741 735//735 740//740
            +f 734//734 740//740 735//735
            +f 742//742 736//736 741//741
            +f 735//735 741//741 736//736
            +f 743//743 737//737 742//742
            +f 736//736 742//742 737//737
            +f 744//744 738//738 743//743
            +f 737//737 743//743 738//738
            +f 745//745 739//739 744//744
            +f 738//738 744//744 739//739
            +f 746//746 740//740 618//618
            +f 616//616 618//618 740//740
            +f 747//747 741//741 746//746
            +f 740//740 746//746 741//741
            +f 748//748 742//742 747//747
            +f 741//741 747//747 742//742
            +f 749//749 743//743 748//748
            +f 742//742 748//748 743//743
            +f 750//750 744//744 749//749
            +f 743//743 749//749 744//744
            +f 751//751 745//745 750//750
            +f 744//744 750//750 745//745
            +f 752//752 746//746 620//620
            +f 618//618 620//620 746//746
            +f 753//753 747//747 752//752
            +f 746//746 752//752 747//747
            +f 754//754 748//748 753//753
            +f 747//747 753//753 748//748
            +f 755//755 749//749 754//754
            +f 748//748 754//754 749//749
            +f 756//756 750//750 755//755
            +f 749//749 755//755 750//750
            +f 757//757 751//751 756//756
            +f 750//750 756//756 751//751
            +f 758//758 752//752 620//620
            +f 620//620 622//622 758//758
            +f 759//759 753//753 752//752
            +f 752//752 758//758 759//759
            +f 760//760 754//754 753//753
            +f 753//753 759//759 760//760
            +f 761//761 755//755 754//754
            +f 754//754 760//760 761//761
            +f 762//762 756//756 755//755
            +f 755//755 761//761 762//762
            +f 763//763 757//757 756//756
            +f 756//756 762//762 763//763
            +f 764//764 758//758 622//622
            +f 622//622 624//624 764//764
            +f 765//765 759//759 758//758
            +f 758//758 764//764 765//765
            +f 766//766 760//760 759//759
            +f 759//759 765//765 766//766
            +f 767//767 761//761 760//760
            +f 760//760 766//766 767//767
            +f 768//768 762//762 761//761
            +f 761//761 767//767 768//768
            +f 769//769 763//763 762//762
            +f 762//762 768//768 769//769
            +f 627//627 764//764 624//624
            +f 624//624 579//579 627//627
            +f 629//629 765//765 764//764
            +f 764//764 627//627 629//629
            +f 631//631 766//766 765//765
            +f 765//765 629//629 631//631
            +f 633//633 767//767 766//766
            +f 766//766 631//631 633//633
            +f 635//635 768//768 767//767
            +f 767//767 633//633 635//635
            +f 637//637 769//769 768//768
            +f 768//768 635//635 637//637
            +f 770//770 771//771 772//772
            +f 773//773 772//772 771//771
            +f 774//774 770//770 775//775
            +f 772//772 775//775 770//770
            +f 776//776 777//777 774//774
            +f 774//774 775//775 776//776
            +f 778//778 779//779 776//776
            +f 777//777 776//776 779//779
            +f 780//780 781//781 778//778
            +f 779//779 778//778 781//781
            +f 782//782 783//783 780//780
            +f 781//781 780//780 783//783
            +f 772//772 773//773 784//784
            +f 785//785 784//784 773//773
            +f 775//775 772//772 786//786
            +f 784//784 786//786 772//772
            +f 776//776 775//775 787//787
            +f 786//786 787//787 775//775
            +f 788//788 778//778 776//776
            +f 776//776 787//787 788//788
            +f 789//789 780//780 788//788
            +f 778//778 788//788 780//780
            +f 790//790 782//782 789//789
            +f 780//780 789//789 782//782
            +f 784//784 785//785 791//791
            +f 792//792 791//791 785//785
            +f 786//786 784//784 793//793
            +f 791//791 793//793 784//784
            +f 787//787 786//786 794//794
            +f 793//793 794//794 786//786
            +f 795//795 788//788 787//787
            +f 787//787 794//794 795//795
            +f 796//796 789//789 795//795
            +f 788//788 795//795 789//789
            +f 797//797 790//790 796//796
            +f 789//789 796//796 790//790
            +f 791//791 792//792 798//798
            +f 799//799 798//798 792//792
            +f 793//793 791//791 800//800
            +f 798//798 800//800 791//791
            +f 794//794 793//793 801//801
            +f 800//800 801//801 793//793
            +f 802//802 795//795 794//794
            +f 794//794 801//801 802//802
            +f 803//803 796//796 802//802
            +f 795//795 802//802 796//796
            +f 804//804 797//797 803//803
            +f 796//796 803//803 797//797
            +f 798//798 799//799 805//805
            +f 806//806 805//805 799//799
            +f 800//800 798//798 807//807
            +f 805//805 807//807 798//798
            +f 801//801 800//800 808//808
            +f 807//807 808//808 800//800
            +f 809//809 802//802 801//801
            +f 801//801 808//808 809//809
            +f 810//810 803//803 809//809
            +f 802//802 809//809 803//803
            +f 811//811 804//804 810//810
            +f 803//803 810//810 804//804
            +f 805//805 806//806 812//812
            +f 813//813 812//812 806//806
            +f 807//807 805//805 814//814
            +f 812//812 814//814 805//805
            +f 815//815 808//808 814//814
            +f 807//807 814//814 808//808
            +f 816//816 809//809 815//815
            +f 808//808 815//815 809//809
            +f 817//817 810//810 816//816
            +f 809//809 816//816 810//810
            +f 818//818 811//811 817//817
            +f 810//810 817//817 811//811
            +f 819//819 820//820 812//812
            +f 812//812 813//813 819//819
            +f 820//820 821//821 814//814
            +f 814//814 812//812 820//820
            +f 822//822 815//815 814//814
            +f 814//814 821//821 822//822
            +f 823//823 816//816 815//815
            +f 815//815 822//822 823//823
            +f 824//824 817//817 816//816
            +f 816//816 823//823 824//824
            +f 825//825 818//818 817//817
            +f 817//817 824//824 825//825
            +f 826//826 827//827 820//820
            +f 820//820 819//819 826//826
            +f 827//827 828//828 821//821
            +f 821//821 820//820 827//827
            +f 828//828 829//829 822//822
            +f 822//822 821//821 828//828
            +f 830//830 823//823 829//829
            +f 822//822 829//829 823//823
            +f 831//831 824//824 823//823
            +f 823//823 830//830 831//831
            +f 832//832 825//825 824//824
            +f 824//824 831//831 832//832
            +f 833//833 834//834 827//827
            +f 827//827 826//826 833//833
            +f 834//834 835//835 828//828
            +f 828//828 827//827 834//834
            +f 835//835 836//836 829//829
            +f 829//829 828//828 835//835
            +f 837//837 830//830 836//836
            +f 829//829 836//836 830//830
            +f 838//838 831//831 830//830
            +f 830//830 837//837 838//838
            +f 839//839 832//832 831//831
            +f 831//831 838//838 839//839
            +f 840//840 841//841 834//834
            +f 834//834 833//833 840//840
            +f 841//841 842//842 835//835
            +f 835//835 834//834 841//841
            +f 842//842 843//843 836//836
            +f 836//836 835//835 842//842
            +f 844//844 837//837 843//843
            +f 836//836 843//843 837//837
            +f 845//845 838//838 837//837
            +f 837//837 844//844 845//845
            +f 846//846 839//839 838//838
            +f 838//838 845//845 846//846
            +f 847//847 848//848 841//841
            +f 841//841 840//840 847//847
            +f 848//848 849//849 842//842
            +f 842//842 841//841 848//848
            +f 849//849 850//850 843//843
            +f 843//843 842//842 849//849
            +f 851//851 844//844 850//850
            +f 843//843 850//850 844//844
            +f 852//852 845//845 844//844
            +f 844//844 851//851 852//852
            +f 853//853 846//846 845//845
            +f 845//845 852//852 853//853
            +f 771//771 770//770 848//848
            +f 848//848 847//847 771//771
            +f 770//770 774//774 849//849
            +f 849//849 848//848 770//770
            +f 777//777 850//850 774//774
            +f 849//849 774//774 850//850
            +f 779//779 851//851 850//850
            +f 850//850 777//777 779//779
            +f 781//781 852//852 851//851
            +f 851//851 779//779 781//781
            +f 783//783 853//853 852//852
            +f 852//852 781//781 783//783
            +f 854//854 855//855 782//782
            +f 783//783 782//782 855//855
            +f 856//856 857//857 855//855
            +f 855//855 854//854 856//856
            +f 858//858 859//859 857//857
            +f 857//857 856//856 858//858
            +f 860//860 861//861 859//859
            +f 859//859 858//858 860//860
            +f 862//862 863//863 861//861
            +f 861//861 860//860 862//862
            +f 864//864 865//865 863//863
            +f 863//863 862//862 864//864
            +f 866//866 854//854 782//782
            +f 782//782 790//790 866//866
            +f 867//867 856//856 854//854
            +f 854//854 866//866 867//867
            +f 868//868 858//858 856//856
            +f 856//856 867//867 868//868
            +f 869//869 860//860 858//858
            +f 858//858 868//868 869//869
            +f 870//870 862//862 860//860
            +f 860//860 869//869 870//870
            +f 871//871 864//864 870//870
            +f 862//862 870//870 864//864
            +f 872//872 866//866 790//790
            +f 790//790 797//797 872//872
            +f 873//873 867//867 866//866
            +f 866//866 872//872 873//873
            +f 874//874 868//868 867//867
            +f 867//867 873//873 874//874
            +f 875//875 869//869 874//874
            +f 868//868 874//874 869//869
            +f 876//876 870//870 875//875
            +f 869//869 875//875 870//870
            +f 877//877 871//871 876//876
            +f 870//870 876//876 871//871
            +f 878//878 872//872 797//797
            +f 797//797 804//804 878//878
            +f 879//879 873//873 872//872
            +f 872//872 878//878 879//879
            +f 880//880 874//874 873//873
            +f 873//873 879//879 880//880
            +f 881//881 875//875 880//880
            +f 874//874 880//880 875//875
            +f 882//882 876//876 881//881
            +f 875//875 881//881 876//876
            +f 883//883 877//877 882//882
            +f 876//876 882//882 877//877
            +f 884//884 878//878 804//804
            +f 804//804 811//811 884//884
            +f 885//885 879//879 878//878
            +f 878//878 884//884 885//885
            +f 886//886 880//880 879//879
            +f 879//879 885//885 886//886
            +f 887//887 881//881 880//880
            +f 880//880 886//886 887//887
            +f 888//888 882//882 881//881
            +f 881//881 887//887 888//888
            +f 889//889 883//883 888//888
            +f 882//882 888//888 883//883
            +f 890//890 884//884 811//811
            +f 811//811 818//818 890//890
            +f 891//891 885//885 884//884
            +f 884//884 890//890 891//891
            +f 892//892 886//886 885//885
            +f 885//885 891//891 892//892
            +f 893//893 887//887 886//886
            +f 886//886 892//892 893//893
            +f 894//894 888//888 887//887
            +f 887//887 893//893 894//894
            +f 895//895 889//889 888//888
            +f 888//888 894//894 895//895
            +f 896//896 890//890 825//825
            +f 818//818 825//825 890//890
            +f 897//897 891//891 896//896
            +f 890//890 896//896 891//891
            +f 898//898 892//892 897//897
            +f 891//891 897//897 892//892
            +f 899//899 893//893 898//898
            +f 892//892 898//898 893//893
            +f 900//900 894//894 899//899
            +f 893//893 899//899 894//894
            +f 901//901 895//895 900//900
            +f 894//894 900//900 895//895
            +f 902//902 896//896 832//832
            +f 825//825 832//832 896//896
            +f 903//903 897//897 902//902
            +f 896//896 902//902 897//897
            +f 904//904 898//898 903//903
            +f 897//897 903//903 898//898
            +f 905//905 899//899 904//904
            +f 898//898 904//904 899//899
            +f 906//906 900//900 905//905
            +f 899//899 905//905 900//900
            +f 907//907 901//901 900//900
            +f 900//900 906//906 907//907
            +f 908//908 902//902 839//839
            +f 832//832 839//839 902//902
            +f 909//909 903//903 908//908
            +f 902//902 908//908 903//903
            +f 910//910 904//904 909//909
            +f 903//903 909//909 904//904
            +f 911//911 905//905 904//904
            +f 904//904 910//910 911//911
            +f 912//912 906//906 905//905
            +f 905//905 911//911 912//912
            +f 913//913 907//907 906//906
            +f 906//906 912//912 913//913
            +f 914//914 908//908 846//846
            +f 839//839 846//846 908//908
            +f 915//915 909//909 914//914
            +f 908//908 914//914 909//909
            +f 916//916 910//910 915//915
            +f 909//909 915//915 910//910
            +f 917//917 911//911 910//910
            +f 910//910 916//916 917//917
            +f 918//918 912//912 911//911
            +f 911//911 917//917 918//918
            +f 919//919 913//913 912//912
            +f 912//912 918//918 919//919
            +f 920//920 914//914 853//853
            +f 846//846 853//853 914//914
            +f 921//921 915//915 920//920
            +f 914//914 920//920 915//915
            +f 922//922 916//916 921//921
            +f 915//915 921//921 916//916
            +f 923//923 917//917 922//922
            +f 916//916 922//922 917//917
            +f 924//924 918//918 923//923
            +f 917//917 923//923 918//918
            +f 925//925 919//919 918//918
            +f 918//918 924//924 925//925
            +f 855//855 920//920 853//853
            +f 853//853 783//783 855//855
            +f 857//857 921//921 855//855
            +f 920//920 855//855 921//921
            +f 859//859 922//922 857//857
            +f 921//921 857//857 922//922
            +f 861//861 923//923 859//859
            +f 922//922 859//859 923//923
            +f 863//863 924//924 861//861
            +f 923//923 861//861 924//924
            +f 865//865 925//925 863//863
            +f 924//924 863//863 925//925
            +f 926//926 927//927 928//928
            +f 928//928 929//929 926//926
            +f 929//929 928//928 930//930
            +f 930//930 931//931 929//929
            +f 931//931 930//930 932//932
            +f 932//932 933//933 931//931
            +f 933//933 932//932 934//934
            +f 934//934 935//935 933//933
            +f 935//935 934//934 936//936
            +f 936//936 937//937 935//935
            +f 937//937 936//936 938//938
            +f 939//939 938//938 936//936
            +f 940//940 941//941 927//927
            +f 928//928 927//927 941//941
            +f 928//928 941//941 942//942
            +f 942//942 930//930 928//928
            +f 930//930 942//942 943//943
            +f 943//943 932//932 930//930
            +f 932//932 943//943 944//944
            +f 944//944 934//934 932//932
            +f 934//934 944//944 936//936
            +f 945//945 936//936 944//944
            +f 936//936 945//945 939//939
            +f 946//946 939//939 945//945
            +f 947//947 948//948 940//940
            +f 941//941 940//940 948//948
            +f 941//941 948//948 949//949
            +f 949//949 942//942 941//941
            +f 942//942 949//949 943//943
            +f 950//950 943//943 949//949
            +f 943//943 950//950 944//944
            +f 951//951 944//944 950//950
            +f 944//944 951//951 945//945
            +f 952//952 945//945 951//951
            +f 945//945 952//952 946//946
            +f 953//953 946//946 952//952
            +f 954//954 955//955 947//947
            +f 948//948 947//947 955//955
            +f 948//948 955//955 956//956
            +f 956//956 949//949 948//948
            +f 949//949 956//956 950//950
            +f 957//957 950//950 956//956
            +f 950//950 957//957 951//951
            +f 958//958 951//951 957//957
            +f 951//951 958//958 952//952
            +f 959//959 952//952 958//958
            +f 952//952 959//959 953//953
            +f 960//960 953//953 959//959
            +f 954//954 961//961 962//962
            +f 962//962 955//955 954//954
            +f 955//955 962//962 956//956
            +f 963//963 956//956 962//962
            +f 956//956 963//963 957//957
            +f 964//964 957//957 963//963
            +f 957//957 964//964 958//958
            +f 965//965 958//958 964//964
            +f 958//958 965//965 959//959
            +f 966//966 959//959 965//965
            +f 959//959 966//966 960//960
            +f 967//967 960//960 966//966
            +f 961//961 968//968 962//962
            +f 969//969 962//962 968//968
            +f 962//962 969//969 963//963
            +f 970//970 963//963 969//969
            +f 963//963 970//970 964//964
            +f 971//971 964//964 970//970
            +f 964//964 971//971 965//965
            +f 972//972 965//965 971//971
            +f 965//965 972//972 966//966
            +f 973//973 966//966 972//972
            +f 966//966 973//973 967//967
            +f 974//974 967//967 973//973
            +f 968//968 975//975 976//976
            +f 976//976 969//969 968//968
            +f 969//969 976//976 977//977
            +f 977//977 970//970 969//969
            +f 970//970 977//977 978//978
            +f 978//978 971//971 970//970
            +f 971//971 978//978 979//979
            +f 979//979 972//972 971//971
            +f 972//972 979//979 980//980
            +f 980//980 973//973 972//972
            +f 973//973 980//980 981//981
            +f 981//981 974//974 973//973
            +f 975//975 982//982 976//976
            +f 983//983 976//976 982//982
            +f 976//976 983//983 984//984
            +f 984//984 977//977 976//976
            +f 977//977 984//984 985//985
            +f 985//985 978//978 977//977
            +f 978//978 985//985 986//986
            +f 986//986 979//979 978//978
            +f 979//979 986//986 987//987
            +f 987//987 980//980 979//979
            +f 980//980 987//987 988//988
            +f 988//988 981//981 980//980
            +f 983//983 982//982 989//989
            +f 989//989 990//990 983//983
            +f 983//983 990//990 984//984
            +f 991//991 984//984 990//990
            +f 984//984 991//991 992//992
            +f 992//992 985//985 984//984
            +f 985//985 992//992 993//993
            +f 993//993 986//986 985//985
            +f 986//986 993//993 994//994
            +f 994//994 987//987 986//986
            +f 987//987 994//994 995//995
            +f 995//995 988//988 987//987
            +f 990//990 989//989 996//996
            +f 996//996 997//997 990//990
            +f 990//990 997//997 991//991
            +f 998//998 991//991 997//997
            +f 991//991 998//998 999//999
            +f 999//999 992//992 991//991
            +f 992//992 999//999 1000//1000
            +f 1000//1000 993//993 992//992
            +f 993//993 1000//1000 1001//1001
            +f 1001//1001 994//994 993//993
            +f 994//994 1001//1001 1002//1002
            +f 1002//1002 995//995 994//994
            +f 997//997 996//996 1003//1003
            +f 1003//1003 1004//1004 997//997
            +f 997//997 1004//1004 998//998
            +f 1005//1005 998//998 1004//1004
            +f 998//998 1005//1005 999//999
            +f 1006//1006 999//999 1005//1005
            +f 999//999 1006//1006 1000//1000
            +f 1007//1007 1000//1000 1006//1006
            +f 1000//1000 1007//1007 1008//1008
            +f 1008//1008 1001//1001 1000//1000
            +f 1001//1001 1008//1008 1009//1009
            +f 1009//1009 1002//1002 1001//1001
            +f 1003//1003 926//926 1004//1004
            +f 929//929 1004//1004 926//926
            +f 1004//1004 929//929 1005//1005
            +f 931//931 1005//1005 929//929
            +f 1005//1005 931//931 1006//1006
            +f 933//933 1006//1006 931//931
            +f 1006//1006 933//933 1007//1007
            +f 935//935 1007//1007 933//933
            +f 1007//1007 935//935 1008//1008
            +f 937//937 1008//1008 935//935
            +f 1008//1008 937//937 938//938
            +f 938//938 1009//1009 1008//1008
            +f 938//938 939//939 1010//1010
            +f 1011//1011 1010//1010 939//939
            +f 1010//1010 1011//1011 1012//1012
            +f 1013//1013 1012//1012 1011//1011
            +f 1012//1012 1013//1013 1014//1014
            +f 1015//1015 1014//1014 1013//1013
            +f 1016//1016 1017//1017 1014//1014
            +f 1014//1014 1015//1015 1016//1016
            +f 1018//1018 1019//1019 1017//1017
            +f 1017//1017 1016//1016 1018//1018
            +f 1020//1020 1021//1021 1019//1019
            +f 1019//1019 1018//1018 1020//1020
            +f 939//939 946//946 1011//1011
            +f 1022//1022 1011//1011 946//946
            +f 1011//1011 1022//1022 1013//1013
            +f 1023//1023 1013//1013 1022//1022
            +f 1013//1013 1023//1023 1015//1015
            +f 1024//1024 1015//1015 1023//1023
            +f 1025//1025 1016//1016 1015//1015
            +f 1015//1015 1024//1024 1025//1025
            +f 1026//1026 1018//1018 1016//1016
            +f 1016//1016 1025//1025 1026//1026
            +f 1027//1027 1020//1020 1018//1018
            +f 1018//1018 1026//1026 1027//1027
            +f 946//946 953//953 1022//1022
            +f 1028//1028 1022//1022 953//953
            +f 1022//1022 1028//1028 1023//1023
            +f 1029//1029 1023//1023 1028//1028
            +f 1023//1023 1029//1029 1024//1024
            +f 1030//1030 1024//1024 1029//1029
            +f 1031//1031 1025//1025 1024//1024
            +f 1024//1024 1030//1030 1031//1031
            +f 1032//1032 1026//1026 1025//1025
            +f 1025//1025 1031//1031 1032//1032
            +f 1033//1033 1027//1027 1026//1026
            +f 1026//1026 1032//1032 1033//1033
            +f 953//953 960//960 1028//1028
            +f 1034//1034 1028//1028 960//960
            +f 1028//1028 1034//1034 1029//1029
            +f 1035//1035 1029//1029 1034//1034
            +f 1029//1029 1035//1035 1030//1030
            +f 1036//1036 1030//1030 1035//1035
            +f 1037//1037 1031//1031 1030//1030
            +f 1030//1030 1036//1036 1037//1037
            +f 1038//1038 1032//1032 1031//1031
            +f 1031//1031 1037//1037 1038//1038
            +f 1039//1039 1033//1033 1032//1032
            +f 1032//1032 1038//1038 1039//1039
            +f 960//960 967//967 1034//1034
            +f 1040//1040 1034//1034 967//967
            +f 1034//1034 1040//1040 1035//1035
            +f 1041//1041 1035//1035 1040//1040
            +f 1035//1035 1041//1041 1036//1036
            +f 1042//1042 1036//1036 1041//1041
            +f 1043//1043 1037//1037 1036//1036
            +f 1036//1036 1042//1042 1043//1043
            +f 1044//1044 1038//1038 1037//1037
            +f 1037//1037 1043//1043 1044//1044
            +f 1045//1045 1039//1039 1038//1038
            +f 1038//1038 1044//1044 1045//1045
            +f 967//967 974//974 1040//1040
            +f 1046//1046 1040//1040 974//974
            +f 1040//1040 1046//1046 1041//1041
            +f 1047//1047 1041//1041 1046//1046
            +f 1041//1041 1047//1047 1042//1042
            +f 1048//1048 1042//1042 1047//1047
            +f 1049//1049 1043//1043 1042//1042
            +f 1042//1042 1048//1048 1049//1049
            +f 1050//1050 1044//1044 1043//1043
            +f 1043//1043 1049//1049 1050//1050
            +f 1051//1051 1045//1045 1044//1044
            +f 1044//1044 1050//1050 1051//1051
            +f 974//974 981//981 1052//1052
            +f 1052//1052 1046//1046 974//974
            +f 1046//1046 1052//1052 1053//1053
            +f 1053//1053 1047//1047 1046//1046
            +f 1047//1047 1053//1053 1054//1054
            +f 1054//1054 1048//1048 1047//1047
            +f 1055//1055 1049//1049 1054//1054
            +f 1048//1048 1054//1054 1049//1049
            +f 1056//1056 1050//1050 1055//1055
            +f 1049//1049 1055//1055 1050//1050
            +f 1057//1057 1051//1051 1056//1056
            +f 1050//1050 1056//1056 1051//1051
            +f 981//981 988//988 1058//1058
            +f 1058//1058 1052//1052 981//981
            +f 1052//1052 1058//1058 1059//1059
            +f 1059//1059 1053//1053 1052//1052
            +f 1053//1053 1059//1059 1060//1060
            +f 1060//1060 1054//1054 1053//1053
            +f 1061//1061 1055//1055 1060//1060
            +f 1054//1054 1060//1060 1055//1055
            +f 1062//1062 1056//1056 1061//1061
            +f 1055//1055 1061//1061 1056//1056
            +f 1063//1063 1057//1057 1062//1062
            +f 1056//1056 1062//1062 1057//1057
            +f 988//988 995//995 1064//1064
            +f 1064//1064 1058//1058 988//988
            +f 1058//1058 1064//1064 1065//1065
            +f 1065//1065 1059//1059 1058//1058
            +f 1059//1059 1065//1065 1066//1066
            +f 1066//1066 1060//1060 1059//1059
            +f 1067//1067 1061//1061 1066//1066
            +f 1060//1060 1066//1066 1061//1061
            +f 1068//1068 1062//1062 1067//1067
            +f 1061//1061 1067//1067 1062//1062
            +f 1069//1069 1063//1063 1068//1068
            +f 1062//1062 1068//1068 1063//1063
            +f 995//995 1002//1002 1070//1070
            +f 1070//1070 1064//1064 995//995
            +f 1064//1064 1070//1070 1071//1071
            +f 1071//1071 1065//1065 1064//1064
            +f 1065//1065 1071//1071 1072//1072
            +f 1072//1072 1066//1066 1065//1065
            +f 1073//1073 1067//1067 1072//1072
            +f 1066//1066 1072//1072 1067//1067
            +f 1074//1074 1068//1068 1073//1073
            +f 1067//1067 1073//1073 1068//1068
            +f 1075//1075 1069//1069 1074//1074
            +f 1068//1068 1074//1074 1069//1069
            +f 1002//1002 1009//1009 1076//1076
            +f 1076//1076 1070//1070 1002//1002
            +f 1070//1070 1076//1076 1077//1077
            +f 1077//1077 1071//1071 1070//1070
            +f 1071//1071 1077//1077 1078//1078
            +f 1078//1078 1072//1072 1071//1071
            +f 1079//1079 1073//1073 1078//1078
            +f 1072//1072 1078//1078 1073//1073
            +f 1080//1080 1074//1074 1079//1079
            +f 1073//1073 1079//1079 1074//1074
            +f 1081//1081 1075//1075 1080//1080
            +f 1074//1074 1080//1080 1075//1075
            +f 1009//1009 938//938 1010//1010
            +f 1010//1010 1076//1076 1009//1009
            +f 1076//1076 1010//1010 1012//1012
            +f 1012//1012 1077//1077 1076//1076
            +f 1077//1077 1012//1012 1014//1014
            +f 1014//1014 1078//1078 1077//1077
            +f 1017//1017 1079//1079 1014//1014
            +f 1078//1078 1014//1014 1079//1079
            +f 1019//1019 1080//1080 1017//1017
            +f 1079//1079 1017//1017 1080//1080
            +f 1021//1021 1081//1081 1019//1019
            +f 1080//1080 1019//1019 1081//1081
            +f 1082//1082 1083//1083 1084//1084
            +f 1084//1084 1083//1083 1085//1085
            +f 1085//1085 1083//1083 1086//1086
            +f 1086//1086 1083//1083 1087//1087
            +f 1087//1087 1083//1083 1088//1088
            +f 1088//1088 1083//1083 1089//1089
            +f 1089//1089 1083//1083 1090//1090
            +f 1090//1090 1083//1083 1091//1091
            +f 1091//1091 1083//1083 1092//1092
            +f 1092//1092 1083//1083 1093//1093
            +f 1093//1093 1083//1083 1094//1094
            +f 1094//1094 1083//1083 1095//1095
            +f 1095//1095 1083//1083 1096//1096
            +f 1096//1096 1083//1083 1097//1097
            +f 1097//1097 1083//1083 1098//1098
            +f 1098//1098 1083//1083 1099//1099
            +f 1099//1099 1083//1083 1100//1100
            +f 1100//1100 1083//1083 1101//1101
            +f 1101//1101 1083//1083 1102//1102
            +f 1102//1102 1083//1083 1103//1103
            +f 1103//1103 1083//1083 1104//1104
            +f 1104//1104 1083//1083 1105//1105
            +f 1105//1105 1083//1083 1106//1106
            +f 1106//1106 1083//1083 1082//1082
            +f 1107//1107 1108//1108 1084//1084
            +f 1082//1082 1084//1084 1108//1108
            +f 1109//1109 1110//1110 1108//1108
            +f 1108//1108 1107//1107 1109//1109
            +f 1111//1111 1112//1112 1110//1110
            +f 1110//1110 1109//1109 1111//1111
            +f 1113//1113 1114//1114 1112//1112
            +f 1112//1112 1111//1111 1113//1113
            +f 1115//1115 1107//1107 1085//1085
            +f 1084//1084 1085//1085 1107//1107
            +f 1116//1116 1109//1109 1107//1107
            +f 1107//1107 1115//1115 1116//1116
            +f 1117//1117 1111//1111 1109//1109
            +f 1109//1109 1116//1116 1117//1117
            +f 1118//1118 1113//1113 1111//1111
            +f 1111//1111 1117//1117 1118//1118
            +f 1119//1119 1115//1115 1086//1086
            +f 1085//1085 1086//1086 1115//1115
            +f 1120//1120 1116//1116 1115//1115
            +f 1115//1115 1119//1119 1120//1120
            +f 1121//1121 1117//1117 1116//1116
            +f 1116//1116 1120//1120 1121//1121
            +f 1122//1122 1118//1118 1117//1117
            +f 1117//1117 1121//1121 1122//1122
            +f 1123//1123 1119//1119 1086//1086
            +f 1086//1086 1087//1087 1123//1123
            +f 1124//1124 1120//1120 1123//1123
            +f 1119//1119 1123//1123 1120//1120
            +f 1125//1125 1121//1121 1124//1124
            +f 1120//1120 1124//1124 1121//1121
            +f 1126//1126 1122//1122 1125//1125
            +f 1121//1121 1125//1125 1122//1122
            +f 1127//1127 1123//1123 1087//1087
            +f 1087//1087 1088//1088 1127//1127
            +f 1128//1128 1124//1124 1127//1127
            +f 1123//1123 1127//1127 1124//1124
            +f 1129//1129 1125//1125 1128//1128
            +f 1124//1124 1128//1128 1125//1125
            +f 1130//1130 1126//1126 1129//1129
            +f 1125//1125 1129//1129 1126//1126
            +f 1131//1131 1127//1127 1088//1088
            +f 1088//1088 1089//1089 1131//1131
            +f 1132//1132 1128//1128 1131//1131
            +f 1127//1127 1131//1131 1128//1128
            +f 1133//1133 1129//1129 1132//1132
            +f 1128//1128 1132//1132 1129//1129
            +f 1134//1134 1130//1130 1133//1133
            +f 1129//1129 1133//1133 1130//1130
            +f 1135//1135 1131//1131 1090//1090
            +f 1089//1089 1090//1090 1131//1131
            +f 1136//1136 1132//1132 1131//1131
            +f 1131//1131 1135//1135 1136//1136
            +f 1137//1137 1133//1133 1132//1132
            +f 1132//1132 1136//1136 1137//1137
            +f 1138//1138 1134//1134 1133//1133
            +f 1133//1133 1137//1137 1138//1138
            +f 1139//1139 1135//1135 1091//1091
            +f 1090//1090 1091//1091 1135//1135
            +f 1140//1140 1136//1136 1135//1135
            +f 1135//1135 1139//1139 1140//1140
            +f 1141//1141 1137//1137 1136//1136
            +f 1136//1136 1140//1140 1141//1141
            +f 1142//1142 1138//1138 1137//1137
            +f 1137//1137 1141//1141 1142//1142
            +f 1143//1143 1139//1139 1092//1092
            +f 1091//1091 1092//1092 1139//1139
            +f 1144//1144 1140//1140 1139//1139
            +f 1139//1139 1143//1143 1144//1144
            +f 1145//1145 1141//1141 1140//1140
            +f 1140//1140 1144//1144 1145//1145
            +f 1146//1146 1142//1142 1141//1141
            +f 1141//1141 1145//1145 1146//1146
            +f 1147//1147 1143//1143 1092//1092
            +f 1092//1092 1093//1093 1147//1147
            +f 1148//1148 1144//1144 1147//1147
            +f 1143//1143 1147//1147 1144//1144
            +f 1149//1149 1145//1145 1148//1148
            +f 1144//1144 1148//1148 1145//1145
            +f 1150//1150 1146//1146 1149//1149
            +f 1145//1145 1149//1149 1146//1146
            +f 1151//1151 1147//1147 1093//1093
            +f 1093//1093 1094//1094 1151//1151
            +f 1152//1152 1148//1148 1151//1151
            +f 1147//1147 1151//1151 1148//1148
            +f 1153//1153 1149//1149 1152//1152
            +f 1148//1148 1152//1152 1149//1149
            +f 1154//1154 1150//1150 1153//1153
            +f 1149//1149 1153//1153 1150//1150
            +f 1155//1155 1151//1151 1094//1094
            +f 1094//1094 1095//1095 1155//1155
            +f 1156//1156 1152//1152 1155//1155
            +f 1151//1151 1155//1155 1152//1152
            +f 1157//1157 1153//1153 1156//1156
            +f 1152//1152 1156//1156 1153//1153
            +f 1158//1158 1154//1154 1157//1157
            +f 1153//1153 1157//1157 1154//1154
            +f 1159//1159 1155//1155 1096//1096
            +f 1095//1095 1096//1096 1155//1155
            +f 1160//1160 1156//1156 1155//1155
            +f 1155//1155 1159//1159 1160//1160
            +f 1161//1161 1157//1157 1156//1156
            +f 1156//1156 1160//1160 1161//1161
            +f 1162//1162 1158//1158 1157//1157
            +f 1157//1157 1161//1161 1162//1162
            +f 1163//1163 1159//1159 1097//1097
            +f 1096//1096 1097//1097 1159//1159
            +f 1164//1164 1160//1160 1159//1159
            +f 1159//1159 1163//1163 1164//1164
            +f 1165//1165 1161//1161 1160//1160
            +f 1160//1160 1164//1164 1165//1165
            +f 1166//1166 1162//1162 1161//1161
            +f 1161//1161 1165//1165 1166//1166
            +f 1167//1167 1163//1163 1098//1098
            +f 1097//1097 1098//1098 1163//1163
            +f 1168//1168 1164//1164 1163//1163
            +f 1163//1163 1167//1167 1168//1168
            +f 1169//1169 1165//1165 1164//1164
            +f 1164//1164 1168//1168 1169//1169
            +f 1170//1170 1166//1166 1165//1165
            +f 1165//1165 1169//1169 1170//1170
            +f 1171//1171 1167//1167 1098//1098
            +f 1098//1098 1099//1099 1171//1171
            +f 1172//1172 1168//1168 1171//1171
            +f 1167//1167 1171//1171 1168//1168
            +f 1173//1173 1169//1169 1172//1172
            +f 1168//1168 1172//1172 1169//1169
            +f 1174//1174 1170//1170 1173//1173
            +f 1169//1169 1173//1173 1170//1170
            +f 1175//1175 1171//1171 1099//1099
            +f 1099//1099 1100//1100 1175//1175
            +f 1176//1176 1172//1172 1175//1175
            +f 1171//1171 1175//1175 1172//1172
            +f 1177//1177 1173//1173 1176//1176
            +f 1172//1172 1176//1176 1173//1173
            +f 1178//1178 1174//1174 1177//1177
            +f 1173//1173 1177//1177 1174//1174
            +f 1179//1179 1175//1175 1100//1100
            +f 1100//1100 1101//1101 1179//1179
            +f 1180//1180 1176//1176 1179//1179
            +f 1175//1175 1179//1179 1176//1176
            +f 1181//1181 1177//1177 1180//1180
            +f 1176//1176 1180//1180 1177//1177
            +f 1182//1182 1178//1178 1181//1181
            +f 1177//1177 1181//1181 1178//1178
            +f 1183//1183 1179//1179 1102//1102
            +f 1101//1101 1102//1102 1179//1179
            +f 1184//1184 1180//1180 1179//1179
            +f 1179//1179 1183//1183 1184//1184
            +f 1185//1185 1181//1181 1180//1180
            +f 1180//1180 1184//1184 1185//1185
            +f 1186//1186 1182//1182 1181//1181
            +f 1181//1181 1185//1185 1186//1186
            +f 1187//1187 1183//1183 1103//1103
            +f 1102//1102 1103//1103 1183//1183
            +f 1188//1188 1184//1184 1183//1183
            +f 1183//1183 1187//1187 1188//1188
            +f 1189//1189 1185//1185 1184//1184
            +f 1184//1184 1188//1188 1189//1189
            +f 1190//1190 1186//1186 1185//1185
            +f 1185//1185 1189//1189 1190//1190
            +f 1191//1191 1187//1187 1104//1104
            +f 1103//1103 1104//1104 1187//1187
            +f 1192//1192 1188//1188 1187//1187
            +f 1187//1187 1191//1191 1192//1192
            +f 1193//1193 1189//1189 1188//1188
            +f 1188//1188 1192//1192 1193//1193
            +f 1194//1194 1190//1190 1189//1189
            +f 1189//1189 1193//1193 1194//1194
            +f 1195//1195 1191//1191 1104//1104
            +f 1104//1104 1105//1105 1195//1195
            +f 1196//1196 1192//1192 1195//1195
            +f 1191//1191 1195//1195 1192//1192
            +f 1197//1197 1193//1193 1196//1196
            +f 1192//1192 1196//1196 1193//1193
            +f 1198//1198 1194//1194 1197//1197
            +f 1193//1193 1197//1197 1194//1194
            +f 1199//1199 1195//1195 1105//1105
            +f 1105//1105 1106//1106 1199//1199
            +f 1200//1200 1196//1196 1199//1199
            +f 1195//1195 1199//1199 1196//1196
            +f 1201//1201 1197//1197 1200//1200
            +f 1196//1196 1200//1200 1197//1197
            +f 1202//1202 1198//1198 1201//1201
            +f 1197//1197 1201//1201 1198//1198
            +f 1108//1108 1199//1199 1106//1106
            +f 1106//1106 1082//1082 1108//1108
            +f 1110//1110 1200//1200 1108//1108
            +f 1199//1199 1108//1108 1200//1200
            +f 1112//1112 1201//1201 1110//1110
            +f 1200//1200 1110//1110 1201//1201
            +f 1114//1114 1202//1202 1112//1112
            +f 1201//1201 1112//1112 1202//1202
            diff --git a/dist/es/reference/assets/test.txt b/dist/es/reference/assets/test.txt
            new file mode 100644
            index 0000000000..9dc2445af3
            --- /dev/null
            +++ b/dist/es/reference/assets/test.txt
            @@ -0,0 +1,6 @@
            +I am a cat
            +I like apples
            +I have three feet
            +I like my nose
            +I smell like butter
            +I talk like an orange
            \ No newline at end of file
            diff --git a/dist/es/reference/assets/transformation-matrix.png b/dist/es/reference/assets/transformation-matrix.png
            new file mode 100644
            index 0000000000..0d42542922
            Binary files /dev/null and b/dist/es/reference/assets/transformation-matrix.png differ
            diff --git a/dist/es/reference/data.json b/dist/es/reference/data.json
            new file mode 100644
            index 0000000000..16f3ad430e
            --- /dev/null
            +++ b/dist/es/reference/data.json
            @@ -0,0 +1,30598 @@
            +{
            +    "project": {
            +        "name": "p5",
            +        "description": "[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)",
            +        "version": "1.4.1",
            +        "url": "https://github.com/processing/p5.js#readme"
            +    },
            +    "files": {
            +        "src/accessibility/color_namer.js": {
            +            "name": "src/accessibility/color_namer.js",
            +            "modules": {
            +                "Environment": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/describe.js": {
            +            "name": "src/accessibility/describe.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/gridOutput.js": {
            +            "name": "src/accessibility/gridOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/outputs.js": {
            +            "name": "src/accessibility/outputs.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/textOutput.js": {
            +            "name": "src/accessibility/textOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/color_conversion.js": {
            +            "name": "src/color/color_conversion.js",
            +            "modules": {
            +                "Color Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/creating_reading.js": {
            +            "name": "src/color/creating_reading.js",
            +            "modules": {
            +                "Creating & Reading": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/p5.Color.js": {
            +            "name": "src/color/p5.Color.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/setting.js": {
            +            "name": "src/color/setting.js",
            +            "modules": {
            +                "Setting": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/fes_core.js": {
            +            "name": "src/core/friendly_errors/fes_core.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/file_errors.js": {
            +            "name": "src/core/friendly_errors/file_errors.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/sketch_reader.js": {
            +            "name": "src/core/friendly_errors/sketch_reader.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/stacktrace.js": {
            +            "name": "src/core/friendly_errors/stacktrace.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/validate_params.js": {
            +            "name": "src/core/friendly_errors/validate_params.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/2d_primitives.js": {
            +            "name": "src/core/shape/2d_primitives.js",
            +            "modules": {
            +                "2D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/attributes.js": {
            +            "name": "src/core/shape/attributes.js",
            +            "modules": {
            +                "Attributes": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/curves.js": {
            +            "name": "src/core/shape/curves.js",
            +            "modules": {
            +                "Curves": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/vertex.js": {
            +            "name": "src/core/shape/vertex.js",
            +            "modules": {
            +                "Vertex": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/constants.js": {
            +            "name": "src/core/constants.js",
            +            "modules": {
            +                "Constants": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/environment.js": {
            +            "name": "src/core/environment.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/helpers.js": {
            +            "name": "src/core/helpers.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/init.js": {
            +            "name": "src/core/init.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/internationalization.js": {
            +            "name": "src/core/internationalization.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/legacy.js": {
            +            "name": "src/core/legacy.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/main.js": {
            +            "name": "src/core/main.js",
            +            "modules": {
            +                "Structure": 1
            +            },
            +            "classes": {
            +                "p5": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Element.js": {
            +            "name": "src/core/p5.Element.js",
            +            "modules": {
            +                "DOM": 1
            +            },
            +            "classes": {
            +                "p5.Element": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Graphics.js": {
            +            "name": "src/core/p5.Graphics.js",
            +            "modules": {
            +                "Rendering": 1
            +            },
            +            "classes": {
            +                "p5.Graphics": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer.js": {
            +            "name": "src/core/p5.Renderer.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer2D.js": {
            +            "name": "src/core/p5.Renderer2D.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/reference.js": {
            +            "name": "src/core/reference.js",
            +            "modules": {
            +                "Foundation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/rendering.js": {
            +            "name": "src/core/rendering.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shim.js": {
            +            "name": "src/core/shim.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/structure.js": {
            +            "name": "src/core/structure.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/transform.js": {
            +            "name": "src/core/transform.js",
            +            "modules": {
            +                "Transform": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/local_storage.js": {
            +            "name": "src/data/local_storage.js",
            +            "modules": {
            +                "LocalStorage": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/p5.TypedDict.js": {
            +            "name": "src/data/p5.TypedDict.js",
            +            "modules": {
            +                "Dictionary": 1
            +            },
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/dom/dom.js": {
            +            "name": "src/dom/dom.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/acceleration.js": {
            +            "name": "src/events/acceleration.js",
            +            "modules": {
            +                "Acceleration": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/keyboard.js": {
            +            "name": "src/events/keyboard.js",
            +            "modules": {
            +                "Keyboard": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/mouse.js": {
            +            "name": "src/events/mouse.js",
            +            "modules": {
            +                "Mouse": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/touch.js": {
            +            "name": "src/events/touch.js",
            +            "modules": {
            +                "Touch": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/filters.js": {
            +            "name": "src/image/filters.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/image.js": {
            +            "name": "src/image/image.js",
            +            "modules": {
            +                "Image": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/loading_displaying.js": {
            +            "name": "src/image/loading_displaying.js",
            +            "modules": {
            +                "Loading & Displaying": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/p5.Image.js": {
            +            "name": "src/image/p5.Image.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/pixels.js": {
            +            "name": "src/image/pixels.js",
            +            "modules": {
            +                "Pixels": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/files.js": {
            +            "name": "src/io/files.js",
            +            "modules": {
            +                "Input": 1,
            +                "Output": 1
            +            },
            +            "classes": {
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/p5.Table.js": {
            +            "name": "src/io/p5.Table.js",
            +            "modules": {
            +                "Table": 1
            +            },
            +            "classes": {
            +                "p5.Table": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.TableRow.js": {
            +            "name": "src/io/p5.TableRow.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.XML.js": {
            +            "name": "src/io/p5.XML.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/calculation.js": {
            +            "name": "src/math/calculation.js",
            +            "modules": {
            +                "Calculation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/math.js": {
            +            "name": "src/math/math.js",
            +            "modules": {
            +                "Vector": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/noise.js": {
            +            "name": "src/math/noise.js",
            +            "modules": {
            +                "Noise": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/p5.Vector.js": {
            +            "name": "src/math/p5.Vector.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/random.js": {
            +            "name": "src/math/random.js",
            +            "modules": {
            +                "Random": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/trigonometry.js": {
            +            "name": "src/math/trigonometry.js",
            +            "modules": {
            +                "Trigonometry": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/attributes.js": {
            +            "name": "src/typography/attributes.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/loading_displaying.js": {
            +            "name": "src/typography/loading_displaying.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/p5.Font.js": {
            +            "name": "src/typography/p5.Font.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/utilities/array_functions.js": {
            +            "name": "src/utilities/array_functions.js",
            +            "modules": {
            +                "Array Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/conversion.js": {
            +            "name": "src/utilities/conversion.js",
            +            "modules": {
            +                "Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/string_functions.js": {
            +            "name": "src/utilities/string_functions.js",
            +            "modules": {
            +                "String Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/time_date.js": {
            +            "name": "src/utilities/time_date.js",
            +            "modules": {
            +                "Time & Date": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/3d_primitives.js": {
            +            "name": "src/webgl/3d_primitives.js",
            +            "modules": {
            +                "3D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/interaction.js": {
            +            "name": "src/webgl/interaction.js",
            +            "modules": {
            +                "Interaction": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/light.js": {
            +            "name": "src/webgl/light.js",
            +            "modules": {
            +                "Lights": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/loading.js": {
            +            "name": "src/webgl/loading.js",
            +            "modules": {
            +                "3D Models": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/material.js": {
            +            "name": "src/webgl/material.js",
            +            "modules": {
            +                "Material": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Camera.js": {
            +            "name": "src/webgl/p5.Camera.js",
            +            "modules": {
            +                "Camera": 1
            +            },
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Geometry.js": {
            +            "name": "src/webgl/p5.Geometry.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Matrix.js": {
            +            "name": "src/webgl/p5.Matrix.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Matrix": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RenderBuffer.js": {
            +            "name": "src/webgl/p5.RenderBuffer.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Immediate.js": {
            +            "name": "src/webgl/p5.RendererGL.Immediate.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Retained.js": {
            +            "name": "src/webgl/p5.RendererGL.Retained.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.js": {
            +            "name": "src/webgl/p5.RendererGL.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.RendererGL": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Shader.js": {
            +            "name": "src/webgl/p5.Shader.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Shader": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Texture.js": {
            +            "name": "src/webgl/p5.Texture.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/text.js": {
            +            "name": "src/webgl/text.js",
            +            "modules": {},
            +            "classes": {
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.js": {
            +            "name": "lib/addons/p5.sound.js",
            +            "modules": {
            +                "p5.sound": 1
            +            },
            +            "classes": {
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.min.js": {
            +            "name": "lib/addons/p5.sound.min.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        }
            +    },
            +    "modules": {
            +        "Environment": {
            +            "name": "Environment",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Environment",
            +            "file": "src/accessibility/color_namer.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Color": {
            +            "name": "Color",
            +            "submodules": {
            +                "Color Conversion": 1,
            +                "Creating & Reading": 1,
            +                "Setting": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/color/p5.Color.js",
            +            "line": 14
            +        },
            +        "Color Conversion": {
            +            "name": "Color Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/color_conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Creating & Reading": {
            +            "name": "Creating & Reading",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ],
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"
            +        },
            +        "Setting": {
            +            "name": "Setting",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/setting.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Shape": {
            +            "name": "Shape",
            +            "submodules": {
            +                "2D Primitives": 1,
            +                "Curves": 1,
            +                "Vertex": 1,
            +                "3D Primitives": 1,
            +                "3D Models": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1,
            +                "p5.Matrix": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/p5.Matrix.js",
            +            "line": 19
            +        },
            +        "2D Primitives": {
            +            "name": "2D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Attributes": {
            +            "name": "Attributes",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/core/shape/attributes.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Curves": {
            +            "name": "Curves",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/curves.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vertex": {
            +            "name": "Vertex",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Constants": {
            +            "name": "Constants",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Constants",
            +            "file": "src/core/constants.js",
            +            "line": 1
            +        },
            +        "Structure": {
            +            "name": "Structure",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "IO",
            +            "file": "src/core/main.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ]
            +        },
            +        "DOM": {
            +            "name": "DOM",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Element": 1,
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "DOM",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n",
            +            "requires": [
            +                "p5"
            +            ]
            +        },
            +        "Rendering": {
            +            "name": "Rendering",
            +            "submodules": {
            +                "undefined": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.RendererGL": 1,
            +                "p5.Graphics": 1,
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Rendering",
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 603,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"
            +        },
            +        "Foundation": {
            +            "name": "Foundation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {},
            +            "module": "Foundation",
            +            "file": "src/core/reference.js",
            +            "line": 1
            +        },
            +        "Transform": {
            +            "name": "Transform",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Transform",
            +            "file": "src/core/transform.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Data": {
            +            "name": "Data",
            +            "submodules": {
            +                "LocalStorage": 1,
            +                "Dictionary": 1,
            +                "Array Functions": 1,
            +                "Conversion": 1,
            +                "String Functions": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.TypedDict": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410
            +        },
            +        "LocalStorage": {
            +            "name": "LocalStorage",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/local_storage.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for working with local storage"
            +            ]
            +        },
            +        "Dictionary": {
            +            "name": "Dictionary",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."
            +            ],
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"
            +        },
            +        "Events": {
            +            "name": "Events",
            +            "submodules": {
            +                "Acceleration": 1,
            +                "Keyboard": 1,
            +                "Mouse": 1,
            +                "Touch": 1
            +            },
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "Acceleration": {
            +            "name": "Acceleration",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/acceleration.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Keyboard": {
            +            "name": "Keyboard",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/keyboard.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Mouse": {
            +            "name": "Mouse",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/mouse.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Touch": {
            +            "name": "Touch",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/touch.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Image": {
            +            "name": "Image",
            +            "submodules": {
            +                "Pixels": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Image",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"
            +        },
            +        "Loading & Displaying": {
            +            "name": "Loading & Displaying",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"
            +        },
            +        "Pixels": {
            +            "name": "Pixels",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Image",
            +            "namespace": "",
            +            "file": "src/image/pixels.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "IO": {
            +            "name": "IO",
            +            "submodules": {
            +                "Structure": 1,
            +                "Input": 1,
            +                "Output": 1,
            +                "Table": 1,
            +                "Time & Date": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1,
            +                "p5.Table": 1,
            +                "p5.TableRow": 1,
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/io/p5.XML.js",
            +            "line": 9
            +        },
            +        "Input": {
            +            "name": "Input",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"
            +        },
            +        "Output": {
            +            "name": "Output",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"
            +        },
            +        "Table": {
            +            "name": "Table",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Table": 1,
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"
            +        },
            +        "Math": {
            +            "name": "Math",
            +            "submodules": {
            +                "Calculation": 1,
            +                "Vector": 1,
            +                "Noise": 1,
            +                "Random": 1,
            +                "Trigonometry": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10
            +        },
            +        "Calculation": {
            +            "name": "Calculation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/calculation.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vector": {
            +            "name": "Vector",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"
            +        },
            +        "Noise": {
            +            "name": "Noise",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/noise.js",
            +            "line": 14,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Random": {
            +            "name": "Random",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/random.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Trigonometry": {
            +            "name": "Trigonometry",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/trigonometry.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Typography": {
            +            "name": "Typography",
            +            "submodules": {
            +                "Attributes": 1,
            +                "Loading & Displaying": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13
            +        },
            +        "Array Functions": {
            +            "name": "Array Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/array_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Conversion": {
            +            "name": "Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "String Functions": {
            +            "name": "String Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/string_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Time & Date": {
            +            "name": "Time & Date",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/utilities/time_date.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Primitives": {
            +            "name": "3D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ],
            +            "description": "<p>p5 Geometry class</p>\n"
            +        },
            +        "3D": {
            +            "name": "3D",
            +            "submodules": {
            +                "Interaction": 1,
            +                "Lights": 1,
            +                "Material": 1,
            +                "Camera": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1,
            +                "p5.Shader": 1,
            +                "p5.Texture": 1,
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/text.js",
            +            "line": 260
            +        },
            +        "Interaction": {
            +            "name": "Interaction",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/interaction.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Lights": {
            +            "name": "Lights",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/light.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Models": {
            +            "name": "3D Models",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/loading.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ]
            +        },
            +        "Material": {
            +            "name": "Material",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Shader": 1,
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Texture.js",
            +            "line": 12,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the p5.Shader class</p>\n"
            +        },
            +        "Camera": {
            +            "name": "Camera",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.sound": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {},
            +            "module": "p5.sound",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>",
            +            "tag": "main",
            +            "itemtype": "main"
            +        }
            +    },
            +    "classes": {
            +        "p5": {
            +            "name": "p5",
            +            "shortname": "p5",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/core/main.js",
            +            "line": 13,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>element to attach canvas to</p>\n",
            +                    "type": "HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a p5 instance",
            +                "type": "P5"
            +            }
            +        },
            +        "p5.Color": {
            +            "name": "p5.Color",
            +            "shortname": "p5.Color",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Element": {
            +            "name": "p5.Element",
            +            "shortname": "p5.Element",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/core/p5.Element.js",
            +            "line": 9,
            +            "description": "<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Graphics": {
            +            "name": "p5.Graphics",
            +            "shortname": "p5.Graphics",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 10,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>the renderer to use, either P2D or WEBGL</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Renderer": {
            +            "name": "p5.Renderer",
            +            "shortname": "p5.Renderer",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 10,
            +            "description": "<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isMainCanvas",
            +                    "description": "<p>whether we're using it as main canvas</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "JSON": {
            +            "name": "JSON",
            +            "shortname": "JSON",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "console": {
            +            "name": "console",
            +            "shortname": "console",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "p5.TypedDict": {
            +            "name": "p5.TypedDict",
            +            "shortname": "p5.TypedDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 82,
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.StringDict": {
            +            "name": "p5.StringDict",
            +            "shortname": "p5.StringDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 394,
            +            "description": "<p>A simple Dictionary class for Strings.</p>\n",
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.NumberDict": {
            +            "name": "p5.NumberDict",
            +            "shortname": "p5.NumberDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "description": "<p>A simple Dictionary class for Numbers.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.MediaElement": {
            +            "name": "p5.MediaElement",
            +            "shortname": "p5.MediaElement",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 2377,
            +            "description": "<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.File": {
            +            "name": "p5.File",
            +            "shortname": "p5.File",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>File that is wrapped</p>\n",
            +                    "type": "File"
            +                }
            +            ]
            +        },
            +        "p5.Image": {
            +            "name": "p5.Image",
            +            "shortname": "p5.Image",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Image",
            +            "submodule": "Image",
            +            "namespace": "",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"
            +            ],
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ]
            +        },
            +        "p5.PrintWriter": {
            +            "name": "p5.PrintWriter",
            +            "shortname": "p5.PrintWriter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Table": {
            +            "name": "p5.Table",
            +            "shortname": "p5.Table",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.Table.js",
            +            "line": 33,
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "rows",
            +                    "description": "<p>An array of p5.TableRow objects</p>\n",
            +                    "type": "p5.TableRow[]",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TableRow": {
            +            "name": "p5.TableRow",
            +            "shortname": "p5.TableRow",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "description": "<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>comma separated values (csv) by default</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.XML": {
            +            "name": "p5.XML",
            +            "shortname": "p5.XML",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Input",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed"
            +        },
            +        "p5.Vector": {
            +            "name": "p5.Vector",
            +            "shortname": "p5.Vector",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "2 white ellipses. One center-left the other bottom right and off canvas"
            +        },
            +        "p5.Font": {
            +            "name": "p5.Font",
            +            "shortname": "p5.Font",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "description": "<p>Base class for font handling</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Camera": {
            +            "name": "p5.Camera",
            +            "shortname": "p5.Camera",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Camera",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n",
            +            "params": [
            +                {
            +                    "name": "rendererGL",
            +                    "description": "<p>instance of WebGL renderer</p>\n",
            +                    "type": "RendererGL"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes."
            +        },
            +        "p5.Geometry": {
            +            "name": "p5.Geometry",
            +            "shortname": "p5.Geometry",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Shape",
            +            "submodule": "3D Primitives",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "description": "<p>p5 Geometry class</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of vertices along the x-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of vertices along the y-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call upon object instantiation.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Shader": {
            +            "name": "p5.Shader",
            +            "shortname": "p5.Shader",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Material",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 11,
            +            "description": "<p>Shader class for WEBGL Mode</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n",
            +                    "type": "p5.RendererGL"
            +                },
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader (as a string)</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader (as a string)</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "shortname": "p5.sound",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": ""
            +        },
            +        "p5.SoundFile": {
            +            "name": "p5.SoundFile",
            +            "shortname": "p5.SoundFile",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1405,
            +            "description": "<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoadingCallback",
            +                    "description": "<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"
            +            ]
            +        },
            +        "p5.Amplitude": {
            +            "name": "p5.Amplitude",
            +            "shortname": "p5.Amplitude",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3022,
            +            "description": "<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.FFT": {
            +            "name": "p5.FFT",
            +            "shortname": "p5.FFT",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3347,
            +            "description": "<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Oscillator": {
            +            "name": "p5.Oscillator",
            +            "shortname": "p5.Oscillator",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4060,
            +            "description": "<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>frequency defaults to 440Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"
            +            ]
            +        },
            +        "p5.SinOsc": {
            +            "name": "p5.SinOsc",
            +            "shortname": "p5.SinOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4602,
            +            "description": "<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TriOsc": {
            +            "name": "p5.TriOsc",
            +            "shortname": "p5.TriOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4629,
            +            "description": "<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SawOsc": {
            +            "name": "p5.SawOsc",
            +            "shortname": "p5.SawOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4656,
            +            "description": "<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SqrOsc": {
            +            "name": "p5.SqrOsc",
            +            "shortname": "p5.SqrOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4683,
            +            "description": "<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Envelope": {
            +            "name": "p5.Envelope",
            +            "shortname": "p5.Envelope",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4721,
            +            "description": "<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Noise": {
            +            "name": "p5.Noise",
            +            "shortname": "p5.Noise",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5620,
            +            "description": "<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.Pulse": {
            +            "name": "p5.Pulse",
            +            "shortname": "p5.Pulse",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5779,
            +            "description": "<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in oscillations per second (Hz)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioIn": {
            +            "name": "p5.AudioIn",
            +            "shortname": "p5.AudioIn",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6015,
            +            "description": "<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Effect": {
            +            "name": "p5.Effect",
            +            "shortname": "p5.Effect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6423,
            +            "description": "<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "ac",
            +                    "description": "<p>Reference to the audio context of the p5 object</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "input",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "output",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "_drywet",
            +                    "description": "<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "wet",
            +                    "description": "<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Filter": {
            +            "name": "p5.Filter",
            +            "shortname": "p5.Filter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6628,
            +            "description": "<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.LowPass": {
            +            "name": "p5.LowPass",
            +            "shortname": "p5.LowPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6914,
            +            "description": "<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.HighPass": {
            +            "name": "p5.HighPass",
            +            "shortname": "p5.HighPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6938,
            +            "description": "<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.BandPass": {
            +            "name": "p5.BandPass",
            +            "shortname": "p5.BandPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6962,
            +            "description": "<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.EQ": {
            +            "name": "p5.EQ",
            +            "shortname": "p5.EQ",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7105,
            +            "description": "<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect",
            +            "params": [
            +                {
            +                    "name": "_eqsize",
            +                    "description": "<p>Constructor will accept 3 or 8, defaults to 3</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "p5.EQ object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Panner3D": {
            +            "name": "p5.Panner3D",
            +            "shortname": "p5.Panner3D",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7602,
            +            "description": "<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Delay": {
            +            "name": "p5.Delay",
            +            "shortname": "p5.Delay",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7926,
            +            "description": "<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Reverb": {
            +            "name": "p5.Reverb",
            +            "shortname": "p5.Reverb",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8308,
            +            "description": "<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Convolver": {
            +            "name": "p5.Convolver",
            +            "shortname": "p5.Convolver",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8549,
            +            "description": "<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when loading succeeds</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Phrase": {
            +            "name": "p5.Phrase",
            +            "shortname": "p5.Phrase",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9103,
            +            "description": "<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>Name so that you can access the Phrase.</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Part": {
            +            "name": "p5.Part",
            +            "shortname": "p5.Part",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9185,
            +            "description": "<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "steps",
            +                    "description": "<p>Steps in the part</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tatums",
            +                    "description": "<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Score": {
            +            "name": "p5.Score",
            +            "shortname": "p5.Score",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9493,
            +            "description": "<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "parts",
            +                    "description": "<p>One or multiple parts, to be played in sequence.</p>\n",
            +                    "type": "p5.Part",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ]
            +        },
            +        "p5.SoundLoop": {
            +            "name": "p5.SoundLoop",
            +            "shortname": "p5.SoundLoop",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9673,
            +            "description": "<p>SoundLoop</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>this function will be called on each iteration of theloop</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "interval",
            +                    "description": "<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n",
            +                    "type": "Number|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Compressor": {
            +            "name": "p5.Compressor",
            +            "shortname": "p5.Compressor",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10036,
            +            "description": "<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect"
            +        },
            +        "p5.PeakDetect": {
            +            "name": "p5.PeakDetect",
            +            "shortname": "p5.PeakDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10312,
            +            "description": "<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq1",
            +                    "description": "<p>lowFrequency - defaults to 20Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "freq2",
            +                    "description": "<p>highFrequency - defaults to 20000 Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "framesPerPeak",
            +                    "description": "<p>Defaults to 20.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.SoundRecorder": {
            +            "name": "p5.SoundRecorder",
            +            "shortname": "p5.SoundRecorder",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10559,
            +            "description": "<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"
            +            ]
            +        },
            +        "p5.Distortion": {
            +            "name": "p5.Distortion",
            +            "shortname": "p5.Distortion",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10816,
            +            "description": "<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ]
            +        },
            +        "p5.Gain": {
            +            "name": "p5.Gain",
            +            "shortname": "p5.Gain",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10973,
            +            "description": "<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioVoice": {
            +            "name": "p5.AudioVoice",
            +            "shortname": "p5.AudioVoice",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11149,
            +            "description": "<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.MonoSynth": {
            +            "name": "p5.MonoSynth",
            +            "shortname": "p5.MonoSynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11247,
            +            "description": "<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.OnsetDetect": {
            +            "name": "p5.OnsetDetect",
            +            "shortname": "p5.OnsetDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11624,
            +            "description": "<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freqLow",
            +                    "description": "<p>Low frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "freqHigh",
            +                    "description": "<p>High frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Function to call when an onset is detected</p>\n",
            +                    "type": "Function"
            +                }
            +            ]
            +        },
            +        "p5.PolySynth": {
            +            "name": "p5.PolySynth",
            +            "shortname": "p5.PolySynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "synthVoice",
            +                    "description": "<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "maxVoices",
            +                    "description": "<p>Number of voices, defaults to 8;</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ]
            +        }
            +    },
            +    "elements": {},
            +    "classitems": [
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 18,
            +            "description": "<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describe",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the canvas</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 114,
            +            "description": "<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describeElement",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 10,
            +            "description": "<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "textOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 88,
            +            "description": "<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "gridOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 8,
            +            "description": "<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 19,
            +            "description": "<p>Convert an HSBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 45,
            +            "description": "<p>Convert an HSBA array to RGBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 100,
            +            "description": "<p>Convert an HSLA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 123,
            +            "description": "<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 187,
            +            "description": "<p>Convert an RGBA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 226,
            +            "description": "<p>Convert an RGBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 16,
            +            "description": "<p>Extracts the alpha value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "alpha",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the alpha value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 43,
            +            "description": "<p>Extracts the blue value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "blue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the blue value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 69,
            +            "description": "<p>Extracts the HSB brightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "brightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the brightness value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 113,
            +            "description": "<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n",
            +            "itemtype": "method",
            +            "name": "color",
            +            "return": {
            +                "description": "resulting color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "overloads": [
            +                {
            +                    "line": 113,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "resulting color",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 257,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 269,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 282,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 297,
            +            "description": "<p>Extracts the green value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "green",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the green value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 325,
            +            "description": "<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n",
            +            "itemtype": "method",
            +            "name": "hue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the hue",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 359,
            +            "description": "<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerpColor",
            +            "params": [
            +                {
            +                    "name": "c1",
            +                    "description": "<p>interpolate from this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "c2",
            +                    "description": "<p>interpolate to this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "interpolated color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 449,
            +            "description": "<p>Extracts the HSL lightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "lightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the lightness",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 478,
            +            "description": "<p>Extracts the red value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "red",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the red value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 517,
            +            "description": "<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n",
            +            "itemtype": "method",
            +            "name": "saturation",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the saturation value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 51,
            +            "description": "<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "params": [
            +                {
            +                    "name": "format",
            +                    "description": "<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the formatted string",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 254,
            +            "description": "<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRed",
            +            "params": [
            +                {
            +                    "name": "red",
            +                    "description": "<p>the new red value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 281,
            +            "description": "<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setGreen",
            +            "params": [
            +                {
            +                    "name": "green",
            +                    "description": "<p>the new green value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 304,
            +            "description": "<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBlue",
            +            "params": [
            +                {
            +                    "name": "blue",
            +                    "description": "<p>the new blue value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 327,
            +            "description": "<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAlpha",
            +            "params": [
            +                {
            +                    "name": "alpha",
            +                    "description": "<p>the new alpha value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 396,
            +            "description": "<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 427,
            +            "description": "<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 446,
            +            "description": "<p>CSS named colors.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 600,
            +            "description": "<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 613,
            +            "description": "<p>Full color string patterns. The capture groups are necessary.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 960,
            +            "description": "<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 13,
            +            "description": "<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n",
            +            "itemtype": "method",
            +            "name": "background",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "colorstring",
            +                            "description": "<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 140,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>specifies a value between white and black</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 147,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current color\n                       mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 159,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 166,
            +                    "params": [
            +                        {
            +                            "name": "image",
            +                            "description": "<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 179,
            +            "description": "<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"
            +            ],
            +            "params": [
            +                {
            +                    "name": "r",
            +                    "description": "<p>normalized red val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "g",
            +                    "description": "<p>normalized green val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>normalized blue val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>normalized alpha val.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 229,
            +            "description": "<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n",
            +            "itemtype": "method",
            +            "name": "colorMode",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 229,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>range for all values</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 306,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max1",
            +                            "description": "<p>range for the red or hue depending on the\n                             current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max2",
            +                            "description": "<p>range for the green or saturation depending\n                             on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max3",
            +                            "description": "<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "maxA",
            +                            "description": "<p>range for the alpha</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 350,
            +            "description": "<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n",
            +            "itemtype": "method",
            +            "name": "fill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 350,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 475,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 488,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 495,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the fill color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 507,
            +            "description": "<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noFill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 547,
            +            "description": "<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noStroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 585,
            +            "description": "<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n",
            +            "itemtype": "method",
            +            "name": "stroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 585,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 722,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 728,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 735,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 742,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the stroke color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 755,
            +            "description": "<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n",
            +            "itemtype": "method",
            +            "name": "erase",
            +            "params": [
            +                {
            +                    "name": "strengthFill",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "strengthStroke",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 836,
            +            "description": "<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "noErase",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis is the main file for the Friendly Error System (FES)",
            +                "containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters",
            +                "(2) _friendlyFileLoadError",
            +                "(3) _friendlyError",
            +                "(4) helpForMisusedAtTopLevelCode",
            +                "or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this",
            +                "there's also a file stacktrace.js",
            +                "which contains the code\nto parse the error stack",
            +                "borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions",
            +                "including the call\nsequence of each function",
            +                "please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 915,
            +            "description": "<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n",
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/file_errors.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/sketch_reader.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/stacktrace.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/validate_params.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 16,
            +            "description": "<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 102,
            +            "description": "<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n",
            +            "itemtype": "method",
            +            "name": "arc",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>angle to start the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>angle to stop the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "mode",
            +                    "description": "<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detail",
            +                    "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 235,
            +            "description": "<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipse",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 235,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the ellipse.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 261,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detail",
            +                            "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 277,
            +            "description": "<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n",
            +            "itemtype": "method",
            +            "name": "circle",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>diameter of the circle.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 340,
            +            "description": "<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "line",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 340,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 404,
            +            "description": "<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "point",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 404,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z-coordinate (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 455,
            +                    "params": [
            +                        {
            +                            "name": "coordinate_vector",
            +                            "description": "<p>the coordinate vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 483,
            +            "description": "<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "quad",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 483,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>the x-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>the y-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>the x-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>the y-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>the z-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>the z-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 556,
            +            "description": "<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "rect",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 556,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the rectangle.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tl",
            +                            "description": "<p>optional radius of top-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tr",
            +                            "description": "<p>optional radius of top-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "br",
            +                            "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "bl",
            +                            "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 608,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 623,
            +            "description": "<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "square",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "s",
            +                    "description": "<p>side size of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "tl",
            +                    "description": "<p>optional radius of top-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tr",
            +                    "description": "<p>optional radius of top-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "br",
            +                    "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bl",
            +                    "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 713,
            +            "description": "<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n",
            +            "itemtype": "method",
            +            "name": "triangle",
            +            "params": [
            +                {
            +                    "name": "x1",
            +                    "description": "<p>x-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y1",
            +                    "description": "<p>y-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>x-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>y-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x3",
            +                    "description": "<p>x-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y3",
            +                    "description": "<p>y-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 12,
            +            "description": "<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipseMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 81,
            +            "description": "<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "noSmooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses to left & right of center, black background",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 115,
            +            "description": "<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "rectMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 184,
            +            "description": "<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses one left one right of center. On black.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 219,
            +            "description": "<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeCap",
            +            "params": [
            +                {
            +                    "name": "cap",
            +                    "description": "<p>either ROUND, SQUARE or PROJECT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 259,
            +            "description": "<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeJoin",
            +            "params": [
            +                {
            +                    "name": "join",
            +                    "description": "<p>either MITER, BEVEL, ROUND</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 331,
            +            "description": "<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeWeight",
            +            "params": [
            +                {
            +                    "name": "weight",
            +                    "description": "<p>the weight of the stroke (in pixels)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"
            +            ],
            +            "alt": "3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 13,
            +            "description": "<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezier",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 62,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 92,
            +            "description": "<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierDetail",
            +            "params": [
            +                {
            +                    "name": "detail",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape with a low level of bezier detail",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 130,
            +            "description": "<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierPoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value of the Bezier at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "10 points plotted on a given bezier at equal distances.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 185,
            +            "description": "<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 264,
            +            "description": "<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curve",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 264,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 332,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 358,
            +            "description": "<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveDetail",
            +            "params": [
            +                {
            +                    "name": "resolution",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white arch shape with a low level of curve detail.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 398,
            +            "description": "<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTightness",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>amount of deformation from the original vertices</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Line shaped like right-facing arrow,points move with mouse-x and warp shape.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 444,
            +            "description": "<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "curvePoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point of the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "bezier value at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 493,
            +            "description": "<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second conrol point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "right curving line mid-right of canvas with 7 short lines radiating from it.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 20,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 67,
            +            "description": "<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginShape",
            +            "params": [
            +                {
            +                    "name": "kind",
            +                    "description": "<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 293,
            +            "description": "<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 375,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 415,
            +            "description": "<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Upside-down u-shape line, mid canvas. left point extends beyond canvas view.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 415,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 460,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 524,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "endContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 583,
            +            "description": "<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n",
            +            "itemtype": "method",
            +            "name": "endShape",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>use CLOSE to close the shape</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Triangle line shape with smallest interior angle on bottom and upside-down L.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 668,
            +            "description": "<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "quadraticVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 668,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "<p>x-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "<p>y-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 733,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cz",
            +                            "description": "<p>z-coordinate for the control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 826,
            +            "description": "<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "vertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 826,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 957,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 965,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "u",
            +                            "description": "<p>the vertex's texture u-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vertex's texture v-coordinate</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1003,
            +            "description": "<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n",
            +            "itemtype": "method",
            +            "name": "normal",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 1003,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>A p5.Vector representing the vertex normal.</p>\n",
            +                            "type": "Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1040,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The x component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The y component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The z component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 9,
            +            "description": "<p>Version of this p5.js.</p>\n",
            +            "itemtype": "property",
            +            "name": "VERSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 18,
            +            "description": "<p>The default, two-dimensional renderer.</p>\n",
            +            "itemtype": "property",
            +            "name": "P2D",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 24,
            +            "description": "<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n",
            +            "itemtype": "property",
            +            "name": "WEBGL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 33,
            +            "itemtype": "property",
            +            "name": "ARROW",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 38,
            +            "itemtype": "property",
            +            "name": "CROSS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 43,
            +            "itemtype": "property",
            +            "name": "HAND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 48,
            +            "itemtype": "property",
            +            "name": "MOVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 53,
            +            "itemtype": "property",
            +            "name": "TEXT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 58,
            +            "itemtype": "property",
            +            "name": "WAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 66,
            +            "description": "<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HALF_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white quarter-circle with curve toward bottom right of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 84,
            +            "description": "<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"
            +            ],
            +            "alt": "white half-circle with curve toward bottom of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 102,
            +            "description": "<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "QUARTER_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"
            +            ],
            +            "alt": "white eighth-circle rotated about 40 degrees with curve bottom right canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 120,
            +            "description": "<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TAU",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 138,
            +            "description": "<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TWO_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 156,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n",
            +            "itemtype": "property",
            +            "name": "DEGREES",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 170,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n",
            +            "itemtype": "property",
            +            "name": "RADIANS",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 188,
            +            "itemtype": "property",
            +            "name": "CORNER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 193,
            +            "itemtype": "property",
            +            "name": "CORNERS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 198,
            +            "itemtype": "property",
            +            "name": "RADIUS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 203,
            +            "itemtype": "property",
            +            "name": "RIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 208,
            +            "itemtype": "property",
            +            "name": "LEFT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 213,
            +            "itemtype": "property",
            +            "name": "CENTER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 218,
            +            "itemtype": "property",
            +            "name": "TOP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 223,
            +            "itemtype": "property",
            +            "name": "BOTTOM",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 228,
            +            "itemtype": "property",
            +            "name": "BASELINE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "alphabetic",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 234,
            +            "itemtype": "property",
            +            "name": "POINTS",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0000",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 240,
            +            "itemtype": "property",
            +            "name": "LINES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0001",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 246,
            +            "itemtype": "property",
            +            "name": "LINE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0003",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 252,
            +            "itemtype": "property",
            +            "name": "LINE_LOOP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0002",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 258,
            +            "itemtype": "property",
            +            "name": "TRIANGLES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0004",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 264,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_FAN",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0006",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 270,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0005",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 276,
            +            "itemtype": "property",
            +            "name": "QUADS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 281,
            +            "itemtype": "property",
            +            "name": "QUAD_STRIP",
            +            "type": "String",
            +            "final": 1,
            +            "default": "quad_strip",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 287,
            +            "itemtype": "property",
            +            "name": "TESS",
            +            "type": "String",
            +            "final": 1,
            +            "default": "tess",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 293,
            +            "itemtype": "property",
            +            "name": "CLOSE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 298,
            +            "itemtype": "property",
            +            "name": "OPEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 303,
            +            "itemtype": "property",
            +            "name": "CHORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 308,
            +            "itemtype": "property",
            +            "name": "PIE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 313,
            +            "itemtype": "property",
            +            "name": "PROJECT",
            +            "type": "String",
            +            "final": 1,
            +            "default": "square",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 319,
            +            "itemtype": "property",
            +            "name": "SQUARE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "butt",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 325,
            +            "itemtype": "property",
            +            "name": "ROUND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 330,
            +            "itemtype": "property",
            +            "name": "BEVEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 335,
            +            "itemtype": "property",
            +            "name": "MITER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 342,
            +            "itemtype": "property",
            +            "name": "RGB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 347,
            +            "description": "<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HSB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 356,
            +            "itemtype": "property",
            +            "name": "HSL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 363,
            +            "description": "<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n",
            +            "itemtype": "property",
            +            "name": "AUTO",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 373,
            +            "itemtype": "property",
            +            "name": "ALT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 379,
            +            "itemtype": "property",
            +            "name": "BACKSPACE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 384,
            +            "itemtype": "property",
            +            "name": "CONTROL",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 389,
            +            "itemtype": "property",
            +            "name": "DELETE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 394,
            +            "itemtype": "property",
            +            "name": "DOWN_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 399,
            +            "itemtype": "property",
            +            "name": "ENTER",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 404,
            +            "itemtype": "property",
            +            "name": "ESCAPE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 409,
            +            "itemtype": "property",
            +            "name": "LEFT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 414,
            +            "itemtype": "property",
            +            "name": "OPTION",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 419,
            +            "itemtype": "property",
            +            "name": "RETURN",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 424,
            +            "itemtype": "property",
            +            "name": "RIGHT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 429,
            +            "itemtype": "property",
            +            "name": "SHIFT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 434,
            +            "itemtype": "property",
            +            "name": "TAB",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 439,
            +            "itemtype": "property",
            +            "name": "UP_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 446,
            +            "itemtype": "property",
            +            "name": "BLEND",
            +            "type": "String",
            +            "final": 1,
            +            "default": "source-over",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 452,
            +            "itemtype": "property",
            +            "name": "REMOVE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "destination-out",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 458,
            +            "itemtype": "property",
            +            "name": "ADD",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighter",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 466,
            +            "itemtype": "property",
            +            "name": "DARKEST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 471,
            +            "itemtype": "property",
            +            "name": "LIGHTEST",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighten",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 477,
            +            "itemtype": "property",
            +            "name": "DIFFERENCE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 482,
            +            "itemtype": "property",
            +            "name": "SUBTRACT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 487,
            +            "itemtype": "property",
            +            "name": "EXCLUSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 492,
            +            "itemtype": "property",
            +            "name": "MULTIPLY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 497,
            +            "itemtype": "property",
            +            "name": "SCREEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 502,
            +            "itemtype": "property",
            +            "name": "REPLACE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "copy",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 508,
            +            "itemtype": "property",
            +            "name": "OVERLAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 513,
            +            "itemtype": "property",
            +            "name": "HARD_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 518,
            +            "itemtype": "property",
            +            "name": "SOFT_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 523,
            +            "itemtype": "property",
            +            "name": "DODGE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-dodge",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 529,
            +            "itemtype": "property",
            +            "name": "BURN",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-burn",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 537,
            +            "itemtype": "property",
            +            "name": "THRESHOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 542,
            +            "itemtype": "property",
            +            "name": "GRAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 547,
            +            "itemtype": "property",
            +            "name": "OPAQUE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 552,
            +            "itemtype": "property",
            +            "name": "INVERT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 557,
            +            "itemtype": "property",
            +            "name": "POSTERIZE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 562,
            +            "itemtype": "property",
            +            "name": "DILATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 567,
            +            "itemtype": "property",
            +            "name": "ERODE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 572,
            +            "itemtype": "property",
            +            "name": "BLUR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 579,
            +            "itemtype": "property",
            +            "name": "NORMAL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 584,
            +            "itemtype": "property",
            +            "name": "ITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 589,
            +            "itemtype": "property",
            +            "name": "BOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 594,
            +            "itemtype": "property",
            +            "name": "BOLDITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 599,
            +            "itemtype": "property",
            +            "name": "CHAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 604,
            +            "itemtype": "property",
            +            "name": "WORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 616,
            +            "itemtype": "property",
            +            "name": "LINEAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 621,
            +            "itemtype": "property",
            +            "name": "QUADRATIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 626,
            +            "itemtype": "property",
            +            "name": "BEZIER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 631,
            +            "itemtype": "property",
            +            "name": "CURVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 638,
            +            "itemtype": "property",
            +            "name": "STROKE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 643,
            +            "itemtype": "property",
            +            "name": "FILL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 648,
            +            "itemtype": "property",
            +            "name": "TEXTURE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 653,
            +            "itemtype": "property",
            +            "name": "IMMEDIATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 661,
            +            "itemtype": "property",
            +            "name": "IMAGE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 669,
            +            "itemtype": "property",
            +            "name": "NEAREST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 674,
            +            "itemtype": "property",
            +            "name": "REPEAT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 679,
            +            "itemtype": "property",
            +            "name": "CLAMP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 684,
            +            "itemtype": "property",
            +            "name": "MIRROR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 691,
            +            "itemtype": "property",
            +            "name": "LANDSCAPE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 696,
            +            "itemtype": "property",
            +            "name": "PORTRAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 706,
            +            "itemtype": "property",
            +            "name": "GRID",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 712,
            +            "itemtype": "property",
            +            "name": "AXES",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 718,
            +            "itemtype": "property",
            +            "name": "LABEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 723,
            +            "itemtype": "property",
            +            "name": "FALLBACK",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 20,
            +            "description": "<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "contents",
            +                    "description": "<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"
            +            ],
            +            "alt": "default grey canvas",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 52,
            +            "description": "<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n",
            +            "itemtype": "property",
            +            "name": "frameCount",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "numbers rapidly counting upward with frame count set to 30.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 79,
            +            "description": "<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n",
            +            "itemtype": "property",
            +            "name": "deltaTime",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 129,
            +            "description": "<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "focused",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "green 50×50 ellipse at top left. Red X covers canvas when page focus changes",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 160,
            +            "description": "<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n",
            +            "itemtype": "method",
            +            "name": "cursor",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n",
            +                    "type": "String|Constant"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>the horizontal active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>the vertical active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 228,
            +            "description": "<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n",
            +            "itemtype": "method",
            +            "name": "frameRate",
            +            "chainable": 1,
            +            "example": [
            +                "\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "blue rect moves left to right, followed by red rect moving faster. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 228,
            +                    "params": [
            +                        {
            +                            "name": "fps",
            +                            "description": "<p>number of frames to be displayed every second</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 288,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current frameRate",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 331,
            +            "description": "<p>Hides the cursor from view.</p>\n",
            +            "itemtype": "method",
            +            "name": "noCursor",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "cursor becomes 10×10 white ellipse the moves with mouse x and y.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 354,
            +            "description": "<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 372,
            +            "description": "<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 390,
            +            "description": "<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 405,
            +            "description": "<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 421,
            +            "description": "<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n",
            +            "itemtype": "method",
            +            "name": "windowResized",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional Event callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 476,
            +            "description": "<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 488,
            +            "description": "<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 500,
            +            "description": "<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n",
            +            "itemtype": "method",
            +            "name": "fullscreen",
            +            "params": [
            +                {
            +                    "name": "val",
            +                    "description": "<p>whether the sketch should be in fullscreen mode\nor not</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "current fullscreen state",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 550,
            +            "description": "<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "pixelDensity",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 550,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>whether or how much the sketch should scale</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 586,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current pixel density of the sketch",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 605,
            +            "description": "<p>Returns the pixel density of the current display the sketch is running on.</p>\n",
            +            "itemtype": "method",
            +            "name": "displayDensity",
            +            "return": {
            +                "description": "current pixel density of the display",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 660,
            +            "description": "<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURL",
            +            "return": {
            +                "description": "url",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "current url (http://p5js.org/reference/#/p5/getURL) moves right to left.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 691,
            +            "description": "<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLPath",
            +            "return": {
            +                "description": "path components",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 713,
            +            "description": "<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLParams",
            +            "return": {
            +                "description": "URL params",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/helpers.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 30,
            +            "description": "<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 126,
            +            "description": "<p>Set up our translation function, with loaded languages</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 171,
            +            "description": "<p>Returns a list of languages we have translations loaded for</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 178,
            +            "description": "<p>Returns the current language selected for translation</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 185,
            +            "description": "<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/legacy.js",
            +            "line": 1,
            +            "requires": [
            +                "core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name",
            +                "in others",
            +                "they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 42,
            +            "description": "<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "preload",
            +            "example": [
            +                "\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 83,
            +            "description": "<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setup",
            +            "example": [
            +                "\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 114,
            +            "description": "<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "draw",
            +            "example": [
            +                "\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 415,
            +            "description": "<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 693,
            +            "description": "<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "disableFriendlyErrors",
            +            "type": "Boolean",
            +            "example": [
            +                "\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 21,
            +            "description": "<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "elt",
            +            "readonly": "",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 47,
            +            "description": "<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "parent",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 47,
            +                    "params": [
            +                        {
            +                            "name": "parent",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n",
            +                            "type": "String|p5.Element|Object"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 93,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 114,
            +            "description": "<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n",
            +            "itemtype": "method",
            +            "name": "id",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 114,
            +                    "params": [
            +                        {
            +                            "name": "id",
            +                            "description": "<p>ID of the element</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the id of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 154,
            +            "description": "<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "class",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 154,
            +                    "params": [
            +                        {
            +                            "name": "class",
            +                            "description": "<p>class to add</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the class of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 189,
            +            "description": "<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 246,
            +            "description": "<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 292,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 354,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 403,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 454,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 510,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 551,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOut",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 592,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 639,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 678,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 725,
            +            "description": "<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 763,
            +            "description": "<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragLeave",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 827,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 70,
            +            "description": "<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 122,
            +            "description": "<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image\na multi-colored circle moving back and forth over a scrolling background.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 99,
            +            "description": "<p>Resize our canvas element.</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 415,
            +            "description": "<p>Helper function to check font type (system or otf)</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 467,
            +            "description": "<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 7,
            +            "description": "<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 402,
            +            "description": "<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 7,
            +            "description": "<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n",
            +            "itemtype": "property",
            +            "name": "let",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 34,
            +            "description": "<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n",
            +            "itemtype": "property",
            +            "name": "const",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"
            +            ],
            +            "alt": "These examples do not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 87,
            +            "description": "<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n",
            +            "itemtype": "property",
            +            "name": "===",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 115,
            +            "description": "<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>",
            +            "itemtype": "property",
            +            "name": ">",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 137,
            +            "description": "<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": ">=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 158,
            +            "description": "<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 179,
            +            "description": "<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 200,
            +            "description": "<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n",
            +            "itemtype": "property",
            +            "name": "if-else",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 231,
            +            "description": "<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n",
            +            "itemtype": "property",
            +            "name": "function",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 267,
            +            "description": "<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "return",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 288,
            +            "description": "<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n",
            +            "itemtype": "property",
            +            "name": "boolean",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 309,
            +            "description": "<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n",
            +            "itemtype": "property",
            +            "name": "string",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 331,
            +            "description": "<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n",
            +            "itemtype": "property",
            +            "name": "number",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 351,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n",
            +            "itemtype": "property",
            +            "name": "object",
            +            "example": [
            +                "\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 379,
            +            "description": "<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n",
            +            "itemtype": "property",
            +            "name": "class",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 408,
            +            "description": "<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n",
            +            "itemtype": "property",
            +            "name": "for",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 448,
            +            "description": "<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n",
            +            "itemtype": "property",
            +            "name": "while",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 490,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "stringify",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>:Javascript object that you would like to convert to JSON</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "JSON",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 512,
            +            "description": "<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "message",
            +                    "description": "<p>:Message that you would like to print to the console</p>\n",
            +                    "type": "String|Expression|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "console",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 15,
            +            "description": "<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Renderer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Black line extending from top-left of canvas to bottom right.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 125,
            +            "description": "<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "resizeCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "noRedraw",
            +                    "description": "<p>don't redraw the canvas immediately</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "No image displayed.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 183,
            +            "description": "<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n",
            +            "itemtype": "method",
            +            "name": "noCanvas",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 204,
            +            "description": "<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "createGraphics",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "offscreen graphics buffer",
            +                "type": "p5.Graphics"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 grey squares alternating light and dark grey. White quarter circle mid-left.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 243,
            +            "description": "<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n",
            +            "itemtype": "method",
            +            "name": "blendMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"
            +            ],
            +            "alt": "translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 326,
            +            "description": "<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n",
            +            "itemtype": "property",
            +            "name": "drawingContext",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white ellipse with shadow blur effect around edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 18,
            +            "description": "<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 39,
            +            "description": "<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 10,
            +            "description": "<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 83,
            +            "description": "<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "example": [
            +                "\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 134,
            +            "description": "<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "example": [
            +                "\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 192,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "push",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 290,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "pop",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 391,
            +            "description": "<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n",
            +            "itemtype": "method",
            +            "name": "redraw",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>Redraw for n-times. The default value is 1.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black line on far left of canvas\nblack line on far left of canvas",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 497,
            +            "description": "<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "p5",
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a function containing a p5.js sketch</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>ID or pointer to HTML DOM node to contain sketch in</p>\n",
            +                    "type": "String|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"
            +            ],
            +            "alt": "white rectangle on black background",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 11,
            +            "description": "<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n",
            +            "itemtype": "method",
            +            "name": "applyMatrix",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n",
            +                    "type": "Number|Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "f",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 168,
            +            "description": "<p>Replaces the current matrix with the identity matrix.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetMatrix",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"
            +            ],
            +            "alt": "A rotated rectangle in the center with another at the top left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 193,
            +            "description": "<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "axis",
            +                    "description": "<p>(in 3d) the axis to rotate around</p>\n",
            +                    "type": "p5.Vector|Number[]",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 232,
            +            "description": "<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the x axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 268,
            +            "description": "<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the y axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 304,
            +            "description": "<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateZ",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the z axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 342,
            +            "description": "<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 342,
            +                    "params": [
            +                        {
            +                            "name": "s",
            +                            "description": "<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n",
            +                            "type": "Number|p5.Vector|Number[]"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>percent to scale the object in the y-axis</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>percent to scale the object in the z-axis (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 386,
            +                    "params": [
            +                        {
            +                            "name": "scales",
            +                            "description": "<p>per-axis percents to scale the object</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 416,
            +            "description": "<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at top middle.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 455,
            +            "description": "<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at middle bottom.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 494,
            +            "description": "<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "translate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 494,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>left/right translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>up/down translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>forward/backward translation (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>the vector to translate by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 10,
            +            "description": "<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n",
            +            "itemtype": "method",
            +            "name": "storeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"
            +            ],
            +            "alt": "When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 101,
            +            "description": "<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "getItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>name that you wish to use to store in local storage</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Value of stored item",
            +                "type": "Number|Object|String|Boolean|p5.Color|p5.Vector"
            +            },
            +            "example": [
            +                "\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"
            +            ],
            +            "alt": "If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 177,
            +            "description": "<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearStorage",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 205,
            +            "description": "<p>Removes an item that was stored with storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "removeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 14,
            +            "description": "<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createStringDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.StringDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 14,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                },
            +                {
            +                    "line": 37,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 48,
            +            "description": "<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createNumberDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.NumberDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 48,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 101,
            +            "description": "<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the number of key-value pairs in the Dictionary",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 122,
            +            "description": "<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasKey",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>that you want to look up</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether that key exists in Dictionary",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 144,
            +            "description": "<p>Returns the value stored at the given key.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>key you want to access</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value stored at that key",
            +                "type": "Number|String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 170,
            +            "description": "<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 197,
            +            "description": "<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 208,
            +            "description": "<p>Creates a new key-value pair in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "create",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 208,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 226,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>key/value pair</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 244,
            +            "description": "<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 265,
            +            "description": "<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>for the pair to remove</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 294,
            +            "description": "<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 318,
            +            "description": "<p>Converts the Dictionary into a CSV file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 356,
            +            "description": "<p>Converts the Dictionary into a JSON file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 387,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 425,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 432,
            +            "description": "<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to add to</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to add to the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 459,
            +            "description": "<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to subtract from</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to subtract from the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 482,
            +            "description": "<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to multiply</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to multiply the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 509,
            +            "description": "<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to divide</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to divide the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 536,
            +            "description": "<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 560,
            +            "description": "<p>Return the lowest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 580,
            +            "description": "<p>Return the highest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 600,
            +            "description": "<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 622,
            +            "description": "<p>Return the lowest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 642,
            +            "description": "<p>Return the highest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 21,
            +            "description": "<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "select",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of element to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Element\">p5.Element</a> containing node found",
            +                "type": "p5.Element|null"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 68,
            +            "description": "<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "selectAll",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of elements to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found",
            +                "type": "p5.Element[]"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 127,
            +            "description": "<p>Helper function for select and selectAll</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 142,
            +            "description": "<p>Helper function for getElement and getElements.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 176,
            +            "description": "<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeElements",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 204,
            +            "description": "<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "changed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 271,
            +            "description": "<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "input",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 309,
            +            "description": "<p>Helpers for create methods.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 322,
            +            "description": "<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createDiv",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 341,
            +            "description": "<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createP",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 361,
            +            "description": "<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSpan",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 379,
            +            "description": "<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImg",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>src path or url for image</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 396,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "crossOrigin",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 426,
            +            "description": "<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n",
            +            "itemtype": "method",
            +            "name": "createA",
            +            "params": [
            +                {
            +                    "name": "href",
            +                    "description": "<p>url of page to link to</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner html of link element to display</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "target",
            +                    "description": "<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 450,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 452,
            +            "description": "<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSlider",
            +            "params": [
            +                {
            +                    "name": "min",
            +                    "description": "<p>minimum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "max",
            +                    "description": "<p>maximum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>default value of the slider</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "step",
            +                    "description": "<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 507,
            +            "description": "<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n",
            +            "itemtype": "method",
            +            "name": "createButton",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed on the button</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the button</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 541,
            +            "description": "<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n",
            +            "itemtype": "method",
            +            "name": "createCheckbox",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed after checkbox</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the checkbox; checked is true, unchecked is false</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 622,
            +            "description": "<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createSelect",
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "multiple",
            +                            "description": "<p>true if dropdown should support multiple selections</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 673,
            +                    "params": [
            +                        {
            +                            "name": "existing",
            +                            "description": "<p>DOM select element</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 770,
            +            "description": "<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createRadio",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 770,
            +                    "params": [
            +                        {
            +                            "name": "containerElement",
            +                            "description": "<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "name",
            +                            "description": "<p>A name parameter for each Input Element.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 832,
            +                    "params": [
            +                        {
            +                            "name": "name",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 837,
            +                    "params": [],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 978,
            +            "description": "<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n",
            +            "itemtype": "method",
            +            "name": "createColorPicker",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>default color of element</p>\n",
            +                    "type": "String|p5.Color",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1066,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n",
            +            "itemtype": "method",
            +            "name": "createInput",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1066,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>default value of the input box</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "type",
            +                            "description": "<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1104,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "createFileInput",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function for when a file is loaded</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "multiple",
            +                    "description": "<p>optional, to allow multiple files to be selected</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1164,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1211,
            +            "description": "<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVideo",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n",
            +                    "type": "String|String[]"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1257,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1259,
            +            "description": "<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createAudio",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n",
            +                    "type": "String|String[]",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1296,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1298,
            +            "itemtype": "property",
            +            "name": "VIDEO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1304,
            +            "itemtype": "property",
            +            "name": "AUDIO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1341,
            +            "description": "<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCapture",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n",
            +                    "type": "String|Constant|Object"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be called once\n                                  stream has loaded</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1478,
            +            "description": "<p>Creates element with given tag in the DOM with given content.</p>\n",
            +            "itemtype": "method",
            +            "name": "createElement",
            +            "params": [
            +                {
            +                    "name": "tag",
            +                    "description": "<p>tag for the new element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "content",
            +                    "description": "<p>html content to be inserted into the element</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1504,
            +            "description": "<p>Adds specified class to the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "addClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to add</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1529,
            +            "description": "<p>Removes specified class from the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1560,
            +            "description": "<p>Checks if specified class already set to element</p>\n",
            +            "itemtype": "method",
            +            "name": "hasClass",
            +            "return": {
            +                "description": "a boolean value if element has specified class",
            +                "type": "Boolean"
            +            },
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name of class to check</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1589,
            +            "description": "<p>Toggles element class</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleClass",
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name to toggle</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1622,
            +            "description": "<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "child",
            +            "return": {
            +                "description": "an array of child nodes",
            +                "type": "Node[]"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1622,
            +                    "params": [],
            +                    "return": {
            +                        "description": "an array of child nodes",
            +                        "type": "Node[]"
            +                    }
            +                },
            +                {
            +                    "line": 1650,
            +                    "params": [
            +                        {
            +                            "name": "child",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n",
            +                            "type": "String|p5.Element",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1675,
            +            "description": "<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n",
            +            "itemtype": "method",
            +            "name": "center",
            +            "params": [
            +                {
            +                    "name": "align",
            +                    "description": "<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1726,
            +            "description": "<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "html",
            +            "return": {
            +                "description": "the inner HTML of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1726,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the inner HTML of the element",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1747,
            +                    "params": [
            +                        {
            +                            "name": "html",
            +                            "description": "<p>the HTML to be placed inside the element</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "append",
            +                            "description": "<p>whether to append HTML to existing</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1765,
            +            "description": "<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n",
            +            "itemtype": "method",
            +            "name": "position",
            +            "return": {
            +                "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1765,
            +                    "params": [],
            +                    "return": {
            +                        "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 1798,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "positionType",
            +                            "description": "<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1885,
            +            "description": "<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n",
            +            "itemtype": "method",
            +            "name": "style",
            +            "return": {
            +                "description": "value of property",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1885,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "<p>property to be set</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "value of property",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1923,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to property</p>\n",
            +                            "type": "String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1,
            +                    "return": {
            +                        "description": "current value of property, if no value is given as second argument",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1980,
            +            "description": "<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n",
            +            "itemtype": "method",
            +            "name": "attribute",
            +            "return": {
            +                "description": "value of attribute",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1980,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of attribute",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1995,
            +                    "params": [
            +                        {
            +                            "name": "attr",
            +                            "description": "<p>attribute to set</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to attribute</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2024,
            +            "description": "<p>Removes an attribute on the specified element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeAttribute",
            +            "params": [
            +                {
            +                    "name": "attr",
            +                    "description": "<p>attribute to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2069,
            +            "description": "<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "value",
            +            "return": {
            +                "description": "value of the element",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2069,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of the element",
            +                        "type": "String|Number"
            +                    }
            +                },
            +                {
            +                    "line": 2099,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2115,
            +            "description": "<p>Shows the current element. Essentially, setting display:block for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "show",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2133,
            +            "description": "<p>Hides the current element. Essentially, setting display:none for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "hide",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2149,
            +            "description": "<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the width and height of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2149,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the width and height of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 2173,
            +                    "params": [
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2230,
            +            "description": "<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2268,
            +            "description": "<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n",
            +            "itemtype": "method",
            +            "name": "drop",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to receive loaded file, called for each file dropped.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>callback triggered once when files are dropped with the drop event.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"
            +            ],
            +            "alt": "Canvas turns into whatever image is dragged/dropped onto it.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2400,
            +            "description": "<p>Path to the media element source.</p>\n",
            +            "itemtype": "property",
            +            "name": "src",
            +            "return": {
            +                "description": "src",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2466,
            +            "description": "<p>Play an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2530,
            +            "description": "<p>Stops an HTML5 media element (sets current time to zero).</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2594,
            +            "description": "<p>Pauses an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2656,
            +            "description": "<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2712,
            +            "description": "<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2778,
            +            "description": "<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n",
            +            "itemtype": "method",
            +            "name": "autoplay",
            +            "params": [
            +                {
            +                    "name": "shouldAutoplay",
            +                    "description": "<p>whether the element should autoplay</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2845,
            +            "description": "<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n",
            +            "itemtype": "method",
            +            "name": "volume",
            +            "return": {
            +                "description": "current volume",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2845,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current volume",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2918,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>volume between 0.0 and 1.0</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2931,
            +            "description": "<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n",
            +            "itemtype": "method",
            +            "name": "speed",
            +            "return": {
            +                "description": "current playback speed of the element",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2931,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current playback speed of the element",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3003,
            +                    "params": [
            +                        {
            +                            "name": "speed",
            +                            "description": "<p>speed multiplier for element playback</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3020,
            +            "description": "<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n",
            +            "itemtype": "method",
            +            "name": "time",
            +            "return": {
            +                "description": "current time (in seconds)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 3020,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current time (in seconds)",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3065,
            +                    "params": [
            +                        {
            +                            "name": "time",
            +                            "description": "<p>time to jump to (in seconds)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3079,
            +            "description": "<p>Returns the duration of the HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "duration",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3201,
            +            "description": "<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3232,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3234,
            +            "description": "<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "audioNode",
            +                    "description": "<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n",
            +                    "type": "AudioNode|Object"
            +                }
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3283,
            +            "description": "<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3298,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3300,
            +            "description": "<p>Show the default MediaElement controls, as determined by the web browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "showControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3331,
            +            "description": "<p>Hide the default mediaElement controls.</p>\n",
            +            "itemtype": "method",
            +            "name": "hideControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3360,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3371,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3434,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3476,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3542,
            +            "description": "<p>Underlying File object. All normal File methods can be called on this.</p>\n",
            +            "itemtype": "property",
            +            "name": "file",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3554,
            +            "description": "<p>File type (image, text, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "type",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3560,
            +            "description": "<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "subtype",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3566,
            +            "description": "<p>File name</p>\n",
            +            "itemtype": "property",
            +            "name": "name",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3572,
            +            "description": "<p>File size</p>\n",
            +            "itemtype": "property",
            +            "name": "size",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3579,
            +            "description": "<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n",
            +            "itemtype": "property",
            +            "name": "data",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 11,
            +            "description": "<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n",
            +            "itemtype": "property",
            +            "name": "deviceOrientation",
            +            "type": "Constant",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 23,
            +            "description": "<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 46,
            +            "description": "<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 69,
            +            "description": "<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 94,
            +            "description": "<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 104,
            +            "description": "<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 114,
            +            "description": "<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 135,
            +            "description": "<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 168,
            +            "description": "<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 201,
            +            "description": "<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "rotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 239,
            +            "description": "<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 285,
            +            "description": "<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 330,
            +            "description": "<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 389,
            +            "description": "<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n",
            +            "itemtype": "property",
            +            "name": "turnAxis",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 428,
            +            "description": "<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMoveThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 471,
            +            "description": "<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n",
            +            "itemtype": "method",
            +            "name": "setShakeThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 515,
            +            "description": "<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceMoved",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 546,
            +            "description": "<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceTurned",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 604,
            +            "description": "<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceShaken",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device shakes",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 10,
            +            "description": "<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect that turns black on keypress.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 36,
            +            "description": "<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n",
            +            "itemtype": "property",
            +            "name": "key",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"
            +            ],
            +            "alt": "canvas displays any key value that is pressed in pink font.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 64,
            +            "description": "<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyCode",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"
            +            ],
            +            "alt": "Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 103,
            +            "description": "<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyPressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 190,
            +            "description": "<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when pressed again",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 243,
            +            "description": "<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyTyped",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when 'a' key typed and black when 'b' pressed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 298,
            +            "description": "<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 308,
            +            "description": "<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyIsDown",
            +            "params": [
            +                {
            +                    "name": "code",
            +                    "description": "<p>The key to check for.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether key is down or not",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 12,
            +            "description": "<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"
            +            ],
            +            "alt": "box moves left and right according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 43,
            +            "description": "<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "box moves up and down according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 80,
            +            "description": "<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal black line moves left and right with mouse x-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 106,
            +            "description": "<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black line moves up and down with mouse y-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 132,
            +            "description": "<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "line trail is created from cursor movements. faster movement make longer line.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 164,
            +            "description": "<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect center, fuchsia background. rect flickers on mouse movement",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 195,
            +            "description": "<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 233,
            +            "description": "<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 271,
            +            "description": "<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 311,
            +            "description": "<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 351,
            +            "description": "<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseButton",
            +            "type": "Constant",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 389,
            +            "description": "<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 481,
            +            "description": "<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 535,
            +            "description": "<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseDragged",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 615,
            +            "description": "<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 696,
            +            "description": "<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 772,
            +            "description": "<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 841,
            +            "description": "<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 926,
            +            "description": "<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional WheelEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect moves up and down with vertical scroll. fuchsia background",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 979,
            +            "description": "<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n",
            +            "itemtype": "method",
            +            "name": "requestPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3D scene moves according to mouse mouse movement in a first person perspective",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 1025,
            +            "description": "<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n",
            +            "itemtype": "method",
            +            "name": "exitPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "cursor gets locked / unlocked on mouse-click",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 10,
            +            "description": "<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n",
            +            "itemtype": "property",
            +            "name": "touches",
            +            "type": "Object[]",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Number of touches currently registered are displayed on the canvas",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 71,
            +            "description": "<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch event.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 151,
            +            "description": "<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns lighter with touch until white. resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 223,
            +            "description": "<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/image/filters.js",
            +            "line": 3,
            +            "description": "<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n",
            +            "class": "p5",
            +            "module": "Events"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 8,
            +            "description": "<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 15,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImage",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width in pixels</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height in pixels</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 94,
            +            "description": "<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveCanvas",
            +            "example": [
            +                "\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed\n no image displayed\n no image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 94,
            +                    "params": [
            +                        {
            +                            "name": "selectedCanvas",
            +                            "description": "<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n",
            +                            "type": "p5.Element|HTMLCanvasElement"
            +                        },
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "<p>'jpg' or 'png'</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 413,
            +            "description": "<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveFrames",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'jpg' or 'png'</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Duration in seconds to save the frames for.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "framerate",
            +                    "description": "<p>Framerate to save the frames in.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n",
            +                    "type": "Function(Array)",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"
            +            ],
            +            "alt": "canvas background goes from light to dark with mouse x.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 18,
            +            "description": "<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadImage",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path of the image to be loaded</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n",
            +                    "type": "function(p5.Image)",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "failureCallback",
            +                    "description": "<p>called with event error if\n                               the image fails to load.</p>\n",
            +                    "type": "Function(Event)",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 162,
            +            "description": "<p>Helper function for loading GIF-based images</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 301,
            +            "description": "<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n",
            +            "itemtype": "method",
            +            "name": "image",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 301,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "<p>the image to display</p>\n",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "width",
            +                            "description": "<p>the width to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "height",
            +                            "description": "<p>the height to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 388,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dWidth",
            +                            "description": "<p>the width of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dHeight",
            +                            "description": "<p>the height of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sWidth",
            +                            "description": "<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "sHeight",
            +                            "description": "<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 471,
            +            "description": "<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n",
            +            "itemtype": "method",
            +            "name": "tint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 471,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 542,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 553,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 559,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the tint color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 569,
            +            "description": "<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n",
            +            "itemtype": "method",
            +            "name": "noTint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of bricks, left image with blue tint",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 633,
            +            "description": "<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n",
            +            "itemtype": "method",
            +            "name": "imageMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, or CENTER</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 9,
            +            "description": "<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 88,
            +            "description": "<p>Image width.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains in top and horizontal lines in corresponding colors in bottom.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 115,
            +            "description": "<p>Image height.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains on right and vertical lines in corresponding colors on left.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 152,
            +            "description": "<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 222,
            +            "description": "<p>Helper function for animating GIF-based images with time</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 253,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 261,
            +            "description": "<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 296,
            +            "description": "<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 296,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 338,
            +                    "params": []
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 346,
            +            "description": "<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with 50×50 green rect in front",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 346,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 383,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 387,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 400,
            +            "description": "<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"
            +            ],
            +            "alt": "2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 437,
            +            "description": "<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n",
            +            "itemtype": "method",
            +            "name": "resize",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>the resized image width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>the resized image height</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. zoomed in",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 548,
            +            "description": "<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains and smaller image on top of bricks at top left",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 548,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 588,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 603,
            +            "description": "<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mask",
            +            "params": [
            +                {
            +                    "name": "srcImage",
            +                    "description": "<p>source image</p>\n",
            +                    "type": "p5.Image"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 665,
            +            "description": "<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains left one in color, right in black and white",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 738,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 738,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 815,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 859,
            +            "description": "<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>give your file a name</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'png' or 'jpg'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 900,
            +            "description": "<p>Starts an animated GIF over at the beginning state.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 941,
            +            "description": "<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "getCurrentFrame",
            +            "return": {
            +                "description": "The index for the currently displaying frame in animated GIF",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 972,
            +            "description": "<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "setFrame",
            +            "params": [
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index for the frame that should be displayed</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1017,
            +            "description": "<p>Returns the number of frames in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "numFrames",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1052,
            +            "description": "<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1089,
            +            "description": "<p>Pauses an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1125,
            +            "description": "<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n",
            +            "itemtype": "method",
            +            "name": "delay",
            +            "params": [
            +                {
            +                    "name": "d",
            +                    "description": "<p>the amount in milliseconds to delay between switching frames</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index of the frame that should have the new delay value {optional}</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 12,
            +            "description": "<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"
            +            ],
            +            "alt": "top half of canvas pink, bottom grey",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 80,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 80,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 152,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 173,
            +            "description": "<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 173,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 215,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 307,
            +            "description": "<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 481,
            +            "description": "<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 551,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 555,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 566,
            +            "description": "<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 602,
            +            "description": "<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 674,
            +            "description": "<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 20,
            +            "description": "<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadJSON",
            +            "return": {
            +                "description": "JSON data",
            +                "type": "Object|Array"
            +            },
            +            "example": [
            +                "\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 20,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "jsonpOptions",
            +                            "description": "<p>options object for jsonp related settings</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\" or \"jsonp\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "JSON data",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 104,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 112,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 183,
            +            "description": "<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadStrings",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 303,
            +            "description": "<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadTable",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "header",
            +                    "description": "<p>\"header\" to indicate table has header row</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Table\">Table</a> object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 583,
            +            "description": "<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadXML",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "XML object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 693,
            +            "description": "<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadBytes",
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if there\n                                   is an error</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an object whose 'bytes' property will be the loaded buffer",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 752,
            +            "description": "<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n",
            +            "itemtype": "method",
            +            "name": "httpGet",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 752,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 806,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 814,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 829,
            +            "description": "<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpPost",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 896,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 904,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 919,
            +            "description": "<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpDo",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 919,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "method",
            +                            "description": "<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 990,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "options",
            +                            "description": "<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1155,
            +            "itemtype": "method",
            +            "name": "createWriter",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the file to be created</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.PrintWriter"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1210,
            +            "description": "<p>Writes data to the PrintWriter stream</p>\n",
            +            "itemtype": "method",
            +            "name": "write",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be written by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1269,
            +            "description": "<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be printed by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1310,
            +            "description": "<p>Clears the data already written to the PrintWriter object</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1344,
            +            "description": "<p>Closes the PrintWriter</p>\n",
            +            "itemtype": "method",
            +            "name": "close",
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1393,
            +            "description": "<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "objectOrFilename",
            +                    "description": "<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n",
            +                    "type": "Object|String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n",
            +                    "type": "Boolean|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"
            +            ],
            +            "alt": "An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1535,
            +            "description": "<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "params": [
            +                {
            +                    "name": "json",
            +                    "description": "",
            +                    "type": "Array|Object"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "optimize",
            +                    "description": "<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1592,
            +            "description": "<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveStrings",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>string array to be written</p>\n",
            +                    "type": "String[]"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>filename for output</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>the filename's extension</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isCRLF",
            +                    "description": "<p>if true, change line-break to CRLF</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1656,
            +            "description": "<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "params": [
            +                {
            +                    "name": "Table",
            +                    "description": "<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n",
            +                    "type": "p5.Table"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>the filename to which the Table should be saved</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 9,
            +            "description": "<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 43,
            +            "description": "<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n",
            +            "itemtype": "property",
            +            "name": "columns",
            +            "type": "String[]",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 77,
            +            "description": "<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n",
            +            "itemtype": "property",
            +            "name": "rows",
            +            "type": "p5.TableRow[]",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 85,
            +            "description": "<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n",
            +            "itemtype": "method",
            +            "name": "addRow",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row to be added to the table</p>\n",
            +                    "type": "p5.TableRow",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the row that was added",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 148,
            +            "description": "<p>Removes a row from the table object.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeRow",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID number of the row to remove</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 195,
            +            "description": "<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRow",
            +            "params": [
            +                {
            +                    "name": "rowID",
            +                    "description": "<p>ID number of the row to get</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 240,
            +            "description": "<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRows",
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 288,
            +            "description": "<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRow",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 352,
            +            "description": "<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRows",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 420,
            +            "description": "<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRow",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String|RegExp"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "TableRow object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 478,
            +            "description": "<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRows",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 545,
            +            "description": "<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>String or Number of the column to return</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of column values",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 597,
            +            "description": "<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearRows",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 638,
            +            "description": "<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n",
            +            "itemtype": "method",
            +            "name": "addColumn",
            +            "params": [
            +                {
            +                    "name": "title",
            +                    "description": "<p>title of the given column</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 688,
            +            "description": "<p>Returns the total number of columns in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumnCount",
            +            "return": {
            +                "description": "Number of columns in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 724,
            +            "description": "<p>Returns the total number of rows in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRowCount",
            +            "return": {
            +                "description": "Number of rows in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 760,
            +            "description": "<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeTokens",
            +            "params": [
            +                {
            +                    "name": "chars",
            +                    "description": "<p>String listing characters to be removed</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 832,
            +            "description": "<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 896,
            +            "description": "<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 960,
            +            "description": "<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1009,
            +            "description": "<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1055,
            +            "description": "<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1100,
            +            "description": "<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1146,
            +            "description": "<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1190,
            +            "description": "<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1242,
            +            "description": "<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getObject",
            +            "params": [
            +                {
            +                    "name": "headerColumn",
            +                    "description": "<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1305,
            +            "description": "<p>Retrieves all table data and returns it as a multidimensional array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getArray",
            +            "return": {
            +                "description": "",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 40,
            +            "description": "<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 102,
            +            "description": "<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a Float</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 146,
            +            "description": "<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a String</p>\n",
            +                    "type": "String|Number|Boolean|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 191,
            +            "description": "<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 239,
            +            "description": "<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "Float Floating point number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 295,
            +            "description": "<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 62,
            +            "description": "<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "getParent",
            +            "return": {
            +                "description": "element parent",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 100,
            +            "description": "<p>Gets the element's full name, which is returned as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "getName",
            +            "return": {
            +                "description": "the name of the node",
            +                "type": "String"
            +            },
            +            "example": [
            +                "&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 135,
            +            "description": "<p>Sets the element's name, which is specified as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "setName",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>new name of the node</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 181,
            +            "description": "<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasChildren",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 217,
            +            "description": "<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "listChildren",
            +            "return": {
            +                "description": "names of the children of the element",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 258,
            +            "description": "<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChildren",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "children of the element",
            +                "type": "p5.XML[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 314,
            +            "description": "<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 374,
            +            "description": "<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "addChild",
            +            "params": [
            +                {
            +                    "name": "node",
            +                    "description": "<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n",
            +                    "type": "p5.XML"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 426,
            +            "description": "<p>Removes the element specified by name or index.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 498,
            +            "description": "<p>Counts the specified element's number of attributes, returned as an Number.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAttributeCount",
            +            "return": {
            +                "description": "",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 534,
            +            "description": "<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n",
            +            "itemtype": "method",
            +            "name": "listAttributes",
            +            "return": {
            +                "description": "an array of strings containing the names of attributes",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 577,
            +            "description": "<p>Checks whether or not an element has the specified attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasAttribute",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>attribute to be checked</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "true if attribute found else false",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 622,
            +            "description": "<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 669,
            +            "description": "<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 716,
            +            "description": "<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttribute",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value of the attribute</p>\n",
            +                    "type": "Number|String|Boolean"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 757,
            +            "description": "<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getContent",
            +            "params": [
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>value returned if no content is found</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 798,
            +            "description": "<p>Sets the element's content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setContent",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>the new content</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 839,
            +            "description": "<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n",
            +            "itemtype": "method",
            +            "name": "serialize",
            +            "return": {
            +                "description": "Serialized string of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 10,
            +            "description": "<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n",
            +            "itemtype": "method",
            +            "name": "abs",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to compute</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "absolute value of given number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 33,
            +            "description": "<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n",
            +            "itemtype": "method",
            +            "name": "ceil",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round up</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded up number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 72,
            +            "description": "<p>Constrains a value between a minimum and maximum value.</p>\n",
            +            "itemtype": "method",
            +            "name": "constrain",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to constrain</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "low",
            +                    "description": "<p>minimum limit</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "high",
            +                    "description": "<p>maximum limit</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "constrained number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"
            +            ],
            +            "alt": "2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 116,
            +            "description": "<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "distance between the two points",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"
            +            ],
            +            "alt": "2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 116,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 161,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 182,
            +            "description": "<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n",
            +            "itemtype": "method",
            +            "name": "exp",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>exponent to raise</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "e^n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. e^n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 231,
            +            "description": "<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n",
            +            "itemtype": "method",
            +            "name": "floor",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round down</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded down number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 269,
            +            "description": "<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "params": [
            +                {
            +                    "name": "start",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "lerped value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"
            +            ],
            +            "alt": "5 points horizontally staggered mid-canvas. mid 3 are grey, outer black",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 316,
            +            "description": "<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number greater than 0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "natural logarithm of n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. natural logarithm of n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 371,
            +            "description": "<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "magnitude of vector from (0,0) to (a,b)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"
            +            ],
            +            "alt": "4 lines of different length radiate from top left of canvas.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 409,
            +            "description": "<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n",
            +            "itemtype": "method",
            +            "name": "map",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the incoming value to be converted</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start1",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop1",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start2",
            +                    "description": "<p>lower bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop2",
            +                    "description": "<p>upper bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "withinBounds",
            +                    "description": "<p>constrain the value to the newly mapped range</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "remapped number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"
            +            ],
            +            "alt": "10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 464,
            +            "description": "<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "max",
            +            "return": {
            +                "description": "maximum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 464,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "maximum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 499,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 512,
            +            "description": "<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "min",
            +            "return": {
            +                "description": "minimum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "minimum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 560,
            +            "description": "<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n",
            +            "itemtype": "method",
            +            "name": "norm",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>incoming value to be normalized</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "normalized number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves with mouse. 0 shown left & 100 right and updating values center",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 612,
            +            "description": "<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n",
            +            "itemtype": "method",
            +            "name": "pow",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>base of the exponential expression</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>power by which to raise the base</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "n^e",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"
            +            ],
            +            "alt": "small to large ellipses radiating from top left of canvas",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 646,
            +            "description": "<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n",
            +            "itemtype": "method",
            +            "name": "round",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decimals",
            +                    "description": "<p>number of decimal places to round to, default is 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 701,
            +            "description": "<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sq",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to square</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "squared number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squared values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 745,
            +            "description": "<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n",
            +            "itemtype": "method",
            +            "name": "sqrt",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>non-negative number to square root</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "square root of number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squareroot values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 832,
            +            "description": "<p>Calculates the fractional part of a number.</p>\n",
            +            "itemtype": "method",
            +            "name": "fract",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>Number whose fractional part needs to be found out</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "fractional part of x, i.e, {x}",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"
            +            ],
            +            "alt": "first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/math.js",
            +            "line": 10,
            +            "description": "<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVector",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"
            +            ],
            +            "alt": "draws a line from center of canvas to mouse pointer position.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 36,
            +            "description": "<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n",
            +            "itemtype": "method",
            +            "name": "noise",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate in noise space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Perlin noise value (between 0 and 1) at specified\n                     coordinates",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 178,
            +            "description": "<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseDetail",
            +            "params": [
            +                {
            +                    "name": "lod",
            +                    "description": "<p>number of octaves to be used by the noise</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "falloff",
            +                    "description": "<p>falloff factor for each octave</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "2 vertical grey smokey patterns affected my mouse x-position and noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 243,
            +            "description": "<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical grey lines drawing in pattern affected by noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 69,
            +            "description": "<p>The x component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "x",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 74,
            +            "description": "<p>The y component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "y",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 79,
            +            "description": "<p>The z component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "z",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 86,
            +            "description": "<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 136,
            +            "description": "<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 195,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to set</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 219,
            +            "description": "<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "return": {
            +                "description": "the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 248,
            +            "description": "<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 248,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to be added</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 325,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to add</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2059,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 372,
            +            "description": "<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "rem",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 372,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 401,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>divisor vector</p>\n",
            +                            "type": "p5.Vector | Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2085,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2091,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 461,
            +            "description": "<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 461,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to subtract</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 538,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to subtract</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2110,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 562,
            +            "description": "<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 562,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to multiply with the vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 655,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to multiply with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to multiply with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to multiply with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 663,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to multiply with the components of the vector</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 669,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to multiply with the components of the original vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2139,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2148,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2156,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2164,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 754,
            +            "description": "<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 754,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to divide the vector by</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 847,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to divide with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to divide with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to divide with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 855,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to divide the components of the vector by</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 861,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to divide the components of the original vector by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2218,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2227,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2235,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2243,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 959,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "return": {
            +                "description": "magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 959,
            +                    "params": [],
            +                    "return": {
            +                        "description": "magnitude of the vector",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2343,
            +                    "params": [
            +                        {
            +                            "name": "vecT",
            +                            "description": "<p>the vector to return the magnitude of</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the magnitude of vecT",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1007,
            +            "description": "<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n",
            +            "itemtype": "method",
            +            "name": "magSq",
            +            "return": {
            +                "description": "squared magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1061,
            +            "description": "<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "dot",
            +            "return": {
            +                "description": "the dot product",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1061,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2270,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1103,
            +            "description": "<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "cross",
            +            "return": {
            +                "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1103,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2284,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the cross product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1145,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "the distance",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1145,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2299,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1217,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "return": {
            +                "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1217,
            +                    "params": [],
            +                    "return": {
            +                        "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2360,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vector to normalize</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "v normalized to a length of 1",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1287,
            +            "description": "<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "limit",
            +            "params": [
            +                {
            +                    "name": "max",
            +                    "description": "<p>the maximum magnitude for the vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1345,
            +            "description": "<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMag",
            +            "params": [
            +                {
            +                    "name": "len",
            +                    "description": "<p>the new length for this vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1401,
            +            "description": "<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "heading",
            +            "return": {
            +                "description": "the angle of rotation",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1473,
            +            "description": "<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "setHeading",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1498,
            +            "description": "<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1498,
            +                    "params": [
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>the angle of rotation</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2191,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1567,
            +            "description": "<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleBetween",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "return": {
            +                "description": "the angle between (in radians)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1647,
            +            "description": "<p>Linear interpolate the vector to another vector</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1647,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1720,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2314,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the lerped value",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1736,
            +            "description": "<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n",
            +            "itemtype": "method",
            +            "name": "reflect",
            +            "params": [
            +                {
            +                    "name": "surfaceNormal",
            +                    "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1791,
            +            "description": "<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n",
            +            "itemtype": "method",
            +            "name": "array",
            +            "return": {
            +                "description": "an Array with the 3 values",
            +                "type": "Number[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1823,
            +            "description": "<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +            "itemtype": "method",
            +            "name": "equals",
            +            "return": {
            +                "description": "whether the vectors are equals",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1823,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "whether the vectors are equals",
            +                        "type": "Boolean"
            +                    }
            +                },
            +                {
            +                    "line": 1853,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to compare</p>\n",
            +                            "type": "p5.Vector|Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Boolean"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1878,
            +            "description": "<p>Make a new 2D vector from an angle</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngle",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1929,
            +            "description": "<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngles",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "theta",
            +                    "description": "<p>the polar angle, in radians (zero is up)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "phi",
            +                    "description": "<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1978,
            +            "description": "<p>Make a new 2D unit vector from a random angle</p>\n",
            +            "itemtype": "method",
            +            "name": "random2D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2031,
            +            "description": "<p>Make a new random 3D unit vector.</p>\n",
            +            "itemtype": "method",
            +            "name": "random3D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2135,
            +            "description": "<p>Multiplies a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2187,
            +            "description": "<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2214,
            +            "description": "<p>Divides a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2267,
            +            "description": "<p>Calculates the dot product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2281,
            +            "description": "<p>Calculates the cross product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2295,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2310,
            +            "description": "<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2339,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2357,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 37,
            +            "description": "<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "many vertical lines drawn in white, black or grey.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 66,
            +            "description": "<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n",
            +            "itemtype": "method",
            +            "name": "random",
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"
            +            ],
            +            "alt": "100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random",
            +            "overloads": [
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "min",
            +                            "description": "<p>the lower bound (inclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>the upper bound (exclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 119,
            +                    "params": [
            +                        {
            +                            "name": "choices",
            +                            "description": "<p>the array to choose from</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random element from the array",
            +                        "type": "*"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 153,
            +            "description": "<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomGaussian",
            +            "params": [
            +                {
            +                    "name": "mean",
            +                    "description": "<p>the mean</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sd",
            +                    "description": "<p>the standard deviation</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 18,
            +            "description": "<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "acos",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc cosine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc cosine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 53,
            +            "description": "<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "asin",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc sine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc sine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 88,
            +            "description": "<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc tangent is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 123,
            +            "description": "<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan2",
            +            "params": [
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given point",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60 by 10 rect at center of canvas rotates with mouse movements",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 159,
            +            "description": "<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "cos",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the cosine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines form wave patterns, extend-down on left and right side",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 186,
            +            "description": "<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sin",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the sine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines extend down and up from center to form wave pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 213,
            +            "description": "<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n",
            +            "itemtype": "method",
            +            "name": "tan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"
            +            ],
            +            "alt": "vertical black lines end down and up from center to form spike pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 239,
            +            "description": "<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "degrees",
            +            "params": [
            +                {
            +                    "name": "radians",
            +                    "description": "<p>the radians value to convert to degrees</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 262,
            +            "description": "<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "radians",
            +            "params": [
            +                {
            +                    "name": "degrees",
            +                    "description": "<p>the degree value to convert to radians</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 285,
            +            "description": "<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either RADIANS or DEGREES</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"
            +            ],
            +            "alt": "40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 11,
            +            "description": "<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAlign",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"
            +            ],
            +            "alt": "Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "horizAlign",
            +                            "description": "<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "vertAlign",
            +                            "description": "<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n",
            +                            "type": "Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 72,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 81,
            +            "description": "<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "textLeading",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"
            +            ],
            +            "alt": "A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 81,
            +                    "params": [
            +                        {
            +                            "name": "leading",
            +                            "description": "<p>the size in pixels for spacing between lines</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 109,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 118,
            +            "description": "<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "textSize",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 118,
            +                    "params": [
            +                        {
            +                            "name": "theSize",
            +                            "description": "<p>the size of the letters in units of pixels</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 141,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 150,
            +            "description": "<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n",
            +            "itemtype": "method",
            +            "name": "textStyle",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 150,
            +                    "params": [
            +                        {
            +                            "name": "theStyle",
            +                            "description": "<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 178,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 187,
            +            "description": "<p>Calculates and returns the width of any character or text string.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWidth",
            +            "params": [
            +                {
            +                    "name": "theText",
            +                    "description": "<p>the String of characters to measure</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the calculated width",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"
            +            ],
            +            "alt": "Letter P and p5.js are displayed with vertical lines at end.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 222,
            +            "description": "<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAscent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 251,
            +            "description": "<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textDescent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 280,
            +            "description": "<p>Helper function to measure ascent and descent.</p>\n",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 287,
            +            "description": "<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWrap",
            +            "params": [
            +                {
            +                    "name": "wrapStyle",
            +                    "description": "<p>text wrapping style, either WORD or CHAR</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "return": {
            +                "description": "wrapStyle",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 16,
            +            "description": "<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadFont",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "onError",
            +                    "description": "<p>function to be executed if\n                                   an error occurs</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Font\">p5.Font</a> object",
            +                "type": "p5.Font"
            +            },
            +            "example": [
            +                "\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"
            +            ],
            +            "alt": "p5*js in p5's theme dark pink\np5*js in p5's theme dark pink",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 140,
            +            "description": "<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "text",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the alphanumeric\n                                            symbols to be displayed</p>\n",
            +                    "type": "String|Object|Array|Number|Boolean"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 231,
            +            "description": "<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n",
            +            "itemtype": "method",
            +            "name": "textFont",
            +            "return": {
            +                "description": "the current font / p5 Object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 231,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the current font / p5 Object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "font",
            +                            "description": "<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n",
            +                            "type": "Object|String"
            +                        },
            +                        {
            +                            "name": "size",
            +                            "description": "<p>the font size to use</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 24,
            +            "description": "<p>Underlying opentype font implementation</p>\n",
            +            "itemtype": "property",
            +            "name": "font",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 31,
            +            "description": "<p>Returns a tight bounding box for the given text string using this\nfont</p>\n",
            +            "itemtype": "method",
            +            "name": "textBounds",
            +            "params": [
            +                {
            +                    "name": "line",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional) Default is 12.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a rectangle object with properties: x, y, w, h",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "words Lorem ipsum dol go off canvas and contained by white bounding box",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 175,
            +            "description": "<p>Computes an array of points following the path for specified text</p>\n",
            +            "itemtype": "method",
            +            "name": "textToPoints",
            +            "params": [
            +                {
            +                    "name": "txt",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an array of points, each with x, y, alpha (the path angle)",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 10,
            +            "description": "<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n",
            +            "itemtype": "method",
            +            "name": "append",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to append</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>to be added to the Array</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "return": {
            +                "description": "the array that was appended to",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 35,
            +            "description": "<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "arrayCopy",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions",
            +            "overloads": [
            +                {
            +                    "line": 35,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>the source Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "srcPosition",
            +                            "description": "<p>starting position in the source Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "<p>the destination Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dstPosition",
            +                            "description": "<p>starting position in the destination Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "<p>number of Array elements to be copied</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 73,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 112,
            +            "description": "<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n",
            +            "itemtype": "method",
            +            "name": "concat",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first Array to concatenate</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second Array to concatenate</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "concatenated array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 141,
            +            "description": "<p>Reverses the order of an array, maps to Array.reverse()</p>\n",
            +            "itemtype": "method",
            +            "name": "reverse",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to reverse</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "the reversed list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 161,
            +            "description": "<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n",
            +            "itemtype": "method",
            +            "name": "shorten",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to shorten</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "shortened Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 185,
            +            "description": "<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "shuffle",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to shuffle</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "bool",
            +                    "description": "<p>modify passed array</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "shuffled Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 227,
            +            "description": "<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n",
            +            "itemtype": "method",
            +            "name": "sort",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to sort</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of elements to sort, starting from 0</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the sorted list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 273,
            +            "description": "<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n",
            +            "itemtype": "method",
            +            "name": "splice",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to splice into</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to be spliced in</p>\n",
            +                    "type": "Any"
            +                },
            +                {
            +                    "name": "position",
            +                    "description": "<p>in the array from which to insert data</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 308,
            +            "description": "<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n",
            +            "itemtype": "method",
            +            "name": "subset",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to extract from</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>position to begin</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of values to extract</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of extracted elements",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 10,
            +            "description": "<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "float",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>float string to parse</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "floating point representation of string",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "alt": "20 by 20 white ellipse in the center of the canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 44,
            +            "description": "<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "int",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 44,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "<p>the radix to convert to (default: 10)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 88,
            +            "description": "<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "str",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 114,
            +            "description": "<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n",
            +            "itemtype": "method",
            +            "name": "boolean",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "boolean representation of value",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 146,
            +            "description": "<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "byte",
            +            "return": {
            +                "description": "byte representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 146,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "byte representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 168,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of byte representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 182,
            +            "description": "<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "char",
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 182,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 201,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 216,
            +            "description": "<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unchar",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 216,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 232,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 245,
            +            "description": "<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "hex",
            +            "return": {
            +                "description": "hexadecimal string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 245,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 265,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>array of values to parse</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 295,
            +            "description": "<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unhex",
            +            "return": {
            +                "description": "integer representation of hexadecimal value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 295,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of hexadecimal value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representations of hexadecimal value",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 15,
            +            "description": "<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n",
            +            "itemtype": "method",
            +            "name": "join",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>array of Strings to be joined</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>String to be placed between each item</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "joined String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"hello world!\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 43,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "match",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"p5js*\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 83,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "matchAll",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "2d Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 130,
            +            "description": "<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nf",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" middle top, -1321.00\" middle bottom canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 237,
            +            "description": "<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfc",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 237,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                                 decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 311,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfp",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 352,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 373,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfs",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" top middle and \"-1321.00\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 373,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 430,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 451,
            +            "description": "<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n",
            +            "itemtype": "method",
            +            "name": "split",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>the String used to separate the data</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 484,
            +            "description": "<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n",
            +            "itemtype": "method",
            +            "name": "splitTokens",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>list of individual Strings that will be used as\n                         separators</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 537,
            +            "description": "<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "return": {
            +                "description": "a trimmed String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"No new lines here\" displayed center canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 537,
            +                    "params": [
            +                        {
            +                            "name": "str",
            +                            "description": "<p>a String to be trimmed</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "a trimmed String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 557,
            +                    "params": [
            +                        {
            +                            "name": "strs",
            +                            "description": "<p>an Array of Strings to be trimmed</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "an Array of trimmed Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 10,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n",
            +            "itemtype": "method",
            +            "name": "day",
            +            "return": {
            +                "description": "the current day",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current day is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 31,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n",
            +            "itemtype": "method",
            +            "name": "hour",
            +            "return": {
            +                "description": "the current hour",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current hour is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 52,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "minute",
            +            "return": {
            +                "description": "the current minute",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current minute is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 73,
            +            "description": "<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n",
            +            "itemtype": "method",
            +            "name": "millis",
            +            "return": {
            +                "description": "the number of milliseconds since starting the sketch",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"
            +            ],
            +            "alt": "number of milliseconds since sketch has started displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 100,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n",
            +            "itemtype": "method",
            +            "name": "month",
            +            "return": {
            +                "description": "the current month",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current month is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 122,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "second",
            +            "return": {
            +                "description": "the current second",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current second is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 143,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n",
            +            "itemtype": "method",
            +            "name": "year",
            +            "return": {
            +                "description": "the current year",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current year is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 13,
            +            "description": "<p>Draw a plane with given a width and height</p>\n",
            +            "itemtype": "method",
            +            "name": "plane",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 97,
            +            "description": "<p>Draw a box with given width, height and depth</p>\n",
            +            "itemtype": "method",
            +            "name": "box",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "Height",
            +                    "description": "<p>height of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "depth",
            +                    "description": "<p>depth of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 215,
            +            "description": "<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "sphere",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of circle</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>optional number of subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>optional number of subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 419,
            +            "description": "<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cylinder",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cylinder</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottomCap",
            +                    "description": "<p>whether to draw the bottom of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "topCap",
            +                    "description": "<p>whether to draw the top of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 554,
            +            "description": "<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cone",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the bottom surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cone</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cap",
            +                    "description": "<p>whether to draw the base of the cone</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 669,
            +            "description": "<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipsoid",
            +            "params": [
            +                {
            +                    "name": "radiusx",
            +                    "description": "<p>x-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusy",
            +                    "description": "<p>y-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusz",
            +                    "description": "<p>z-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 804,
            +            "description": "<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n",
            +            "itemtype": "method",
            +            "name": "torus",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the whole ring</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tubeRadius",
            +                    "description": "<p>radius of the tube</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 11,
            +            "description": "<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n",
            +            "itemtype": "method",
            +            "name": "orbitControl",
            +            "params": [
            +                {
            +                    "name": "sensitivityX",
            +                    "description": "<p>sensitivity to mouse movement along X axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityY",
            +                    "description": "<p>sensitivity to mouse movement along Y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityZ",
            +                    "description": "<p>sensitivity to scroll movement along Z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Camera orbits around a box when mouse is hold-clicked & then moved.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 145,
            +            "description": "<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n",
            +            "itemtype": "method",
            +            "name": "debugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction",
            +            "overloads": [
            +                {
            +                    "line": 145,
            +                    "params": []
            +                },
            +                {
            +                    "line": 278,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either GRID or AXES</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 283,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "gridSize",
            +                            "description": "<p>size of one side of the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "<p>number of divisions in the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "<p>X axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "<p>Y axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "<p>Z axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "<p>size of axes icon</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 302,
            +                    "params": [
            +                        {
            +                            "name": "gridSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 353,
            +            "description": "<p>Turns off debugMode() in a 3D sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noDebugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 11,
            +            "description": "<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "evenly distributed light across a sphere\nevenly distributed light across a rotating sphere",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>the alpha value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 51,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 57,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 64,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 92,
            +            "description": "<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularColor",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "different specular light sources from top and bottom of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 92,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 145,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 151,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 158,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 177,
            +            "description": "<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "directionalLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "light source on canvas changeable with mouse position",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 177,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 210,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis direction</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 220,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 227,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 280,
            +            "description": "<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "pointLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "spot light on canvas changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 322,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 331,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 341,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 387,
            +            "description": "<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "lights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "the light is partially ambient and partially directional",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 425,
            +            "description": "<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n",
            +            "itemtype": "method",
            +            "name": "lightFalloff",
            +            "params": [
            +                {
            +                    "name": "constant",
            +                    "description": "<p>constant value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "linear",
            +                    "description": "<p>linear value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "quadratic",
            +                    "description": "<p>quadratic value for determining falloff</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two spheres with different falloff values show different intensity of light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 519,
            +            "description": "<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "spotLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Spot light on a sphere which changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 519,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "<p>x axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "<p>y axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "<p>z axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>optional parameter for angle. Defaults to PI/3</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "<p>optional parameter for concentration. Defaults to 100</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 571,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 580,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 590,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 600,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 610,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 634,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 859,
            +            "description": "<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Three white spheres. Each appears as a different\ncolor due to lighting.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 12,
            +            "description": "<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadModel",
            +            "return": {
            +                "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                "type": "p5.Geometry"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d teapot with red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models",
            +            "overloads": [
            +                {
            +                    "line": 12,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>Path of the model to be loaded</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "normalize",
            +                            "description": "<p>If true, scale the model to a\n                                     standardized size when loading</p>\n",
            +                            "type": "Boolean"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "<p>called with event error if\n                                        the model fails to load.</p>\n",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                },
            +                {
            +                    "line": 96,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 179,
            +            "description": "<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 290,
            +            "description": "<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 317,
            +            "description": "<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 344,
            +            "description": "<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 356,
            +            "description": "<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 444,
            +            "description": "<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 588,
            +            "description": "<p>Render a 3d model to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "model",
            +            "params": [
            +                {
            +                    "name": "model",
            +                    "description": "<p>Loaded 3d model to be rendered</p>\n",
            +                    "type": "p5.Geometry"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d octahedron.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 12,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadShader",
            +            "params": [
            +                {
            +                    "name": "vertFilename",
            +                    "description": "<p>path to file containing vertex shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragFilename",
            +                    "description": "<p>path to file containing fragment shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shader files.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 111,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "createShader",
            +            "params": [
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shaders.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 184,
            +            "description": "<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "shader",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "s",
            +                    "description": "<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n",
            +                    "type": "p5.Shader"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 282,
            +            "description": "<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "resetShader",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 368,
            +            "description": "<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "texture",
            +            "params": [
            +                {
            +                    "name": "tex",
            +                    "description": "<p>image to use as texture</p>\n",
            +                    "type": "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using normalized coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 511,
            +            "description": "<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n",
            +            "itemtype": "method",
            +            "name": "textureMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either IMAGE or NORMAL</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using image coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 587,
            +            "description": "<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n",
            +            "itemtype": "method",
            +            "name": "textureWrap",
            +            "params": [
            +                {
            +                    "name": "wrapX",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "wrapY",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "an image of the rocky mountains repeated in mirrored tiles",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 659,
            +            "description": "<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 697,
            +            "description": "<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 697,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 757,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 777,
            +            "description": "<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n",
            +            "itemtype": "method",
            +            "name": "emissiveMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 777,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 809,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 829,
            +            "description": "<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "torus with specular material",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 870,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 882,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 902,
            +            "description": "<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "shininess",
            +            "params": [
            +                {
            +                    "name": "shine",
            +                    "description": "<p>Degree of Shininess.\n                      Defaults to 1.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Shininess on Camera changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 13,
            +            "description": "<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>camera position value on x axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>camera position value on y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>camera position value on z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerX",
            +                    "description": "<p>x coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerY",
            +                    "description": "<p>y coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerZ",
            +                    "description": "<p>z coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upX",
            +                    "description": "<p>x component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upY",
            +                    "description": "<p>y component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upZ",
            +                    "description": "<p>z component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 115,
            +            "description": "<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "params": [
            +                {
            +                    "name": "fovy",
            +                    "description": "<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "aspect",
            +                    "description": "<p>camera frustum aspect ratio</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>frustum near plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>frustum far plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 176,
            +            "description": "<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 236,
            +            "description": "<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 303,
            +            "description": "<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCamera",
            +            "return": {
            +                "description": "The newly created camera object.",
            +                "type": "p5.Camera"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"
            +            ],
            +            "alt": "An example that creates a camera and moves it around the box.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 444,
            +            "description": "<p>camera position value on x axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 472,
            +            "description": "<p>camera position value on y axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 499,
            +            "description": "<p>camera position value on z axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 526,
            +            "description": "<p>x coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 554,
            +            "description": "<p>y coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 582,
            +            "description": "<p>z coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 610,
            +            "description": "<p>x component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 633,
            +            "description": "<p>y component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 656,
            +            "description": "<p>z component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 683,
            +            "description": "<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 801,
            +            "description": "<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 897,
            +            "description": "<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1040,
            +            "description": "<p>Panning rotates the camera view to the left and right.</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1098,
            +            "description": "<p>Tilting rotates the camera view up and down.</p>\n",
            +            "itemtype": "method",
            +            "name": "tilt",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view tilts up and down across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1156,
            +            "description": "<p>Reorients the camera to look at a position in world space.</p>\n",
            +            "itemtype": "method",
            +            "name": "lookAt",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view of rotating 3D cubes changes to look at a new random\npoint every second .",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1223,
            +            "description": "<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1386,
            +            "description": "<p>Move camera along its local axes while maintaining current camera orientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "move",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>amount to move along camera's left-right axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>amount to move along camera's up-down axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>amount to move along camera's forward-backward axis</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1458,
            +            "description": "<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "setPosition",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera position changes as the user presses keys, altering view of a 3D box",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1723,
            +            "description": "<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n",
            +            "itemtype": "method",
            +            "name": "setCamera",
            +            "params": [
            +                {
            +                    "name": "cam",
            +                    "description": "<p>p5.Camera object</p>\n",
            +                    "type": "p5.Camera"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Canvas switches between two camera views, each showing a series of spinning\n3D boxes.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 71,
            +            "description": "<p>computes faces for geometry objects based on the vertices.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeFaces",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 114,
            +            "description": "<p>computes smooth normals per vertex as an average of each\nface.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 153,
            +            "description": "<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n",
            +            "itemtype": "method",
            +            "name": "averageNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 174,
            +            "description": "<p>Averages pole normals.  Used in spherical primitives</p>\n",
            +            "itemtype": "method",
            +            "name": "averagePoleNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 267,
            +            "description": "<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 334,
            +            "description": "<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttributes",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a rotating cube with smoother edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "overloads": [
            +                {
            +                    "line": 334,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "<p>Name of attribute</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>New value of named attribute</p>\n",
            +                            "type": "Boolean"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 473,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>object with key-value pairs</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 306,
            +            "description": "<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n",
            +            "itemtype": "method",
            +            "name": "setUniform",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "uniformName",
            +                    "description": "<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "data",
            +                    "description": "<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n",
            +                    "type": "Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5.Shader",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1,
            +            "class": "p5.sound",
            +            "module": "3D"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 52,
            +            "description": "<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n",
            +            "class": "p5.sound",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 159,
            +            "description": "<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>",
            +            "itemtype": "method",
            +            "name": "getAudioContext",
            +            "return": {
            +                "description": "AudioContext for this sketch",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 198,
            +            "description": "<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>",
            +            "params": [
            +                {
            +                    "name": "element(s)",
            +                    "description": "<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n",
            +                    "type": "Element|Array",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback to invoke when the AudioContext\n                              has started</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that resolves when\n                                     the AudioContext state is 'running'",
            +                "type": "Promise"
            +            },
            +            "itemtype": "method",
            +            "name": "userStartAudio",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 401,
            +            "description": "<p>This module has shims</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 536,
            +            "description": "<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 726,
            +            "description": "<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOutputVolume",
            +            "return": {
            +                "description": "Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 738,
            +            "description": "<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>",
            +            "itemtype": "method",
            +            "name": "outputVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 782,
            +            "description": "<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n",
            +            "itemtype": "property",
            +            "name": "soundOut",
            +            "type": "Object",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 807,
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 811,
            +            "description": "<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "samplerate samples per second",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 825,
            +            "description": "<p>Returns the closest MIDI note value for\na given frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "freqToMidi",
            +            "params": [
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "MIDI note value",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 841,
            +            "description": "<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n",
            +            "itemtype": "method",
            +            "name": "midiToFreq",
            +            "params": [
            +                {
            +                    "name": "midiNote",
            +                    "description": "<p>The number of a MIDI note</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency value of the given MIDI note",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 925,
            +            "description": "<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n",
            +            "itemtype": "method",
            +            "name": "soundFormats",
            +            "params": [
            +                {
            +                    "name": "formats",
            +                    "description": "<p>i.e. 'mp3', 'wav', 'ogg'</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1040,
            +            "description": "<p>Used by Osc and Envelope to chain signal math</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1145,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveSound",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile that you wish to save</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1662,
            +            "description": "<p>Returns true if the sound file finished loading successfully.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLoaded",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1679,
            +            "description": "<p>Play the p5.SoundFile</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule playback to start (in seconds from now).</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) amplitude (volume)\n                                    of playback</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueStart",
            +                    "description": "<p>(optional) cue start time in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) duration of playback in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1787,
            +            "description": "<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "playMode",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>'restart' or 'sustain' or 'untilDone'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1847,
            +            "description": "<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                             seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1905,
            +            "description": "<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) playback volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueLoopStart",
            +                    "description": "<p>(optional) startTime in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) loop duration in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1950,
            +            "description": "<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "setLoop",
            +            "params": [
            +                {
            +                    "name": "Boolean",
            +                    "description": "<p>set looping to true or false</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1976,
            +            "description": "<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1997,
            +            "description": "<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPlaying",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2011,
            +            "description": "<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPaused",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2025,
            +            "description": "<p>Stop soundfile playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            in seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2087,
            +            "description": "<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panValue",
            +                    "description": "<p>Set the stereo panner</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                                seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2131,
            +            "description": "<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2146,
            +            "description": "<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "rate",
            +            "params": [
            +                {
            +                    "name": "playbackRate",
            +                    "description": "<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2239,
            +            "description": "<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "setVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2276,
            +            "description": "<p>Returns the duration of a sound file in seconds.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "The duration of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2293,
            +            "description": "<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n",
            +            "itemtype": "method",
            +            "name": "currentTime",
            +            "return": {
            +                "description": "currentTime of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2308,
            +            "description": "<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n",
            +            "itemtype": "method",
            +            "name": "jump",
            +            "params": [
            +                {
            +                    "name": "cueTime",
            +                    "description": "<p>cueTime of the soundFile in seconds.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>duration in seconds.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2340,
            +            "description": "<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n",
            +            "itemtype": "method",
            +            "name": "channels",
            +            "return": {
            +                "description": "[channels]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2354,
            +            "description": "<p>Return the sample rate of the sound file.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "[sampleRate]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2367,
            +            "description": "<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n",
            +            "itemtype": "method",
            +            "name": "frames",
            +            "return": {
            +                "description": "[sampleCount]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2381,
            +            "description": "<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPeaks",
            +            "params": [
            +                {
            +                    "name": "length",
            +                    "description": "<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of peaks.",
            +                "type": "Float32Array"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2443,
            +            "description": "<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n",
            +            "itemtype": "method",
            +            "name": "reverseBuffer",
            +            "example": [
            +                "\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2497,
            +            "description": "<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2565,
            +            "description": "<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>Audio object that accepts an input</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2590,
            +            "description": "<p>Disconnects the output of this p5sound object.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2604,
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2612,
            +            "description": "<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n",
            +            "itemtype": "method",
            +            "name": "setPath",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to audio file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2630,
            +            "description": "<p>Replace the current Audio Buffer with a new Buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBuffer",
            +            "params": [
            +                {
            +                    "name": "buf",
            +                    "description": "<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2719,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2790,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2817,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2850,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2882,
            +            "description": "<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBlob",
            +            "return": {
            +                "description": "A file-like data object",
            +                "type": "Blob"
            +            },
            +            "example": [
            +                "\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2946,
            +            "description": "<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadSound",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoading",
            +                    "description": "<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a p5.SoundFile",
            +                "type": "SoundFile"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3117,
            +            "description": "<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "snd",
            +                    "description": "<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n",
            +                    "type": "SoundObject|undefined",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n",
            +                    "type": "Number|undefined",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3209,
            +            "description": "<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "channel",
            +                    "description": "<p>Optionally return only channel 0 (left) or 1 (right)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Amplitude as a number between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3264,
            +            "description": "<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleNormalize",
            +            "params": [
            +                {
            +                    "name": "boolean",
            +                    "description": "<p>set normalize to true (1) or false (0)</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3293,
            +            "description": "<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "set",
            +                    "description": "<p>smoothing from 0.0 <= 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3476,
            +            "description": "<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "source",
            +                    "description": "<p>p5.sound object (or web audio API source node)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3501,
            +            "description": "<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n",
            +            "itemtype": "method",
            +            "name": "waveform",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "precision",
            +                    "description": "<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3553,
            +            "description": "<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "analyze",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "scale",
            +                    "description": "<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3650,
            +            "description": "<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getEnergy",
            +            "params": [
            +                {
            +                    "name": "frequency1",
            +                    "description": "<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "frequency2",
            +                    "description": "<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Energy   Energy (volume/amplitude) from\n                            0 and 255.",
            +                "type": "Number"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3739,
            +            "description": "<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getCentroid",
            +            "return": {
            +                "description": "Spectral Centroid Frequency  of the spectral centroid in Hz.",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3826,
            +            "description": "<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3854,
            +            "description": "<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "linAverages",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Number of returned frequency groups</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "linearAverages   Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3889,
            +            "description": "<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "logAverages",
            +            "params": [
            +                {
            +                    "name": "octaveBands",
            +                    "description": "<p>Array of Octave Bands objects for grouping</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "logAverages    Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3925,
            +            "description": "<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOctaveBands",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Specifies the 1/N type of generated octave bands</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fCtr0",
            +                    "description": "<p>Minimum central frequency for the lowest band</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "octaveBands   Array of octave band objects with their bounds",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4168,
            +            "description": "<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>startTime in seconds from now.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>frequency in Hz.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4218,
            +            "description": "<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>Time, in seconds from now.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4238,
            +            "description": "<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)",
            +                "type": "AudioParam"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4271,
            +            "description": "<p>Returns the value of output gain</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmp",
            +            "return": {
            +                "description": "Amplitude value between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4285,
            +            "description": "<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "Frequency",
            +                    "description": "<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Ramp time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen\n                                 at x seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency",
            +                "type": "AudioParam"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4360,
            +            "description": "<p>Returns the value of frequency of oscillator</p>\n",
            +            "itemtype": "method",
            +            "name": "getFreq",
            +            "return": {
            +                "description": "Frequency of oscillator in Hertz",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4373,
            +            "description": "<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4386,
            +            "description": "<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "getType",
            +            "return": {
            +                "description": "type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4399,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4420,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4444,
            +            "description": "<p>Pan between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panning",
            +                    "description": "<p>Number between -1 and 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4460,
            +            "description": "<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "panPosition of oscillator , between Left (-1) and Right (1)",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4494,
            +            "description": "<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "phase",
            +            "params": [
            +                {
            +                    "name": "phase",
            +                    "description": "<p>float between 0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4522,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4543,
            +            "description": "<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with multiplied output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4563,
            +            "description": "<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4767,
            +            "description": "<p>Time until envelope reaches attackLevel</p>\n",
            +            "itemtype": "property",
            +            "name": "attackTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4772,
            +            "description": "<p>Level once attack is complete.</p>\n",
            +            "itemtype": "property",
            +            "name": "attackLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4778,
            +            "description": "<p>Time until envelope reaches decayLevel.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4784,
            +            "description": "<p>Level after decay. The envelope will sustain here until it is released.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4790,
            +            "description": "<p>Duration of the release portion of the envelope.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4796,
            +            "description": "<p>Level at the end of the release.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4833,
            +            "description": "<p>Reset the envelope with a series of time/value pairs.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "attackLevel",
            +                    "description": "<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayLevel",
            +                    "description": "<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Release Time (in seconds)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseLevel",
            +                    "description": "<p>Amplitude</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4895,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4964,
            +            "description": "<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRange",
            +            "params": [
            +                {
            +                    "name": "aLevel",
            +                    "description": "<p>attack level (defaults to 1)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rLevel",
            +                    "description": "<p>release level (defaults to 0)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5037,
            +            "description": "<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "inputs",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5055,
            +            "description": "<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n",
            +            "itemtype": "method",
            +            "name": "setExp",
            +            "params": [
            +                {
            +                    "name": "isExp",
            +                    "description": "<p>true is exponential, false is linear</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5078,
            +            "description": "<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5148,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5256,
            +            "description": "<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5350,
            +            "description": "<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n",
            +            "itemtype": "method",
            +            "name": "ramp",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>When to trigger the ramp</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v",
            +                    "description": "<p>Target value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v2",
            +                    "description": "<p>Second target value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5460,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5479,
            +            "description": "<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5498,
            +            "description": "<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5657,
            +            "description": "<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'white', 'pink' or 'brown'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Noise",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5871,
            +            "description": "<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n",
            +            "itemtype": "method",
            +            "name": "width",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Pulse",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6066,
            +            "itemtype": "property",
            +            "name": "input",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6070,
            +            "itemtype": "property",
            +            "name": "output",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6075,
            +            "itemtype": "property",
            +            "name": "stream",
            +            "type": "MediaStream|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6080,
            +            "itemtype": "property",
            +            "name": "mediaStream",
            +            "type": "MediaStreamAudioSourceNode|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6085,
            +            "itemtype": "property",
            +            "name": "currentSource",
            +            "type": "Number|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6090,
            +            "description": "<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n",
            +            "itemtype": "property",
            +            "name": "enabled",
            +            "type": "Boolean",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6098,
            +            "description": "<p>Input amplitude, connect to it by default but not to master out</p>\n",
            +            "itemtype": "property",
            +            "name": "amplitude",
            +            "type": "p5.Amplitude",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6114,
            +            "description": "<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call on\n                                  success.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6171,
            +            "description": "<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6191,
            +            "description": "<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>An object that accepts audio input,\n                        such as an FFT</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6216,
            +            "description": "<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6234,
            +            "description": "<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Volume level (between 0.0 and 1.0)",
            +                "type": "Number"
            +            },
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6257,
            +            "description": "<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>ramp time (optional)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6280,
            +            "description": "<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n",
            +            "itemtype": "method",
            +            "name": "getSources",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>This optional callback receives the error\n                                   message as its argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6340,
            +            "description": "<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "setSource",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>position of input source in the array</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6462,
            +            "description": "<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6478,
            +            "description": "<p>Set the output volume of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts until rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tFromNow",
            +                    "description": "<p>schedule this event to happen in tFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6502,
            +            "description": "<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n",
            +            "itemtype": "method",
            +            "name": "chain",
            +            "params": [
            +                {
            +                    "name": "arguments",
            +                    "description": "<p>Chain together multiple sound objects</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6525,
            +            "description": "<p>Adjust the dry/wet value.</p>\n",
            +            "itemtype": "method",
            +            "name": "drywet",
            +            "params": [
            +                {
            +                    "name": "fade",
            +                    "description": "<p>The desired drywet value (0 - 1.0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6542,
            +            "description": "<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6557,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6719,
            +            "description": "<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "biquadFilter",
            +            "type": "DelayNode",
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6742,
            +            "description": "<p>Filter an audio signal according to a set\nof filter parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6760,
            +            "description": "<p>Set the frequency and the resonance of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance (Q) from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6781,
            +            "description": "<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Filter Frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value  Returns the current frequency value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6811,
            +            "description": "<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "res",
            +            "params": [
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value Returns the current res value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6838,
            +            "description": "<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n",
            +            "itemtype": "method",
            +            "name": "gain",
            +            "params": [
            +                {
            +                    "name": "gain",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns the current or updated gain value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6864,
            +            "description": "<p>Toggle function. Switches between the specified type and allpass</p>\n",
            +            "itemtype": "method",
            +            "name": "toggle",
            +            "return": {
            +                "description": "[Toggle value]",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6884,
            +            "description": "<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "t",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7198,
            +            "description": "<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n",
            +            "itemtype": "property",
            +            "name": "bands",
            +            "type": "Array",
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7239,
            +            "description": "<p>Process an input by connecting it to the EQ</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Audio source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7629,
            +            "description": "<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n",
            +            "itemtype": "property",
            +            "name": "panner",
            +            "type": "AudioNode",
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7654,
            +            "description": "<p>Connect an audio sorce</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Input source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7668,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7687,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7694,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7701,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7753,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "orient",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7772,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7779,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7786,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7838,
            +            "description": "<p>Set the rolloff factor and max distance</p>\n",
            +            "itemtype": "method",
            +            "name": "setFalloff",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7852,
            +            "description": "<p>Maxium distance between the source and the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "maxDist",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7869,
            +            "description": "<p>How quickly the volume is reduced as the source moves away from the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "rollof",
            +            "params": [
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7989,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "leftDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7999,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "rightDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8049,
            +            "description": "<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "lowPass",
            +                    "description": "<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8094,
            +            "description": "<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n",
            +            "itemtype": "method",
            +            "name": "delayTime",
            +            "params": [
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8116,
            +            "description": "<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n",
            +            "itemtype": "method",
            +            "name": "feedback",
            +            "params": [
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "return": {
            +                "description": "Feedback value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8148,
            +            "description": "<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "cutoffFreq",
            +                    "description": "<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8170,
            +            "description": "<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'pingPong' (1) or 'default' (0)</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8223,
            +            "description": "<p>Set the output level of the delay effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8234,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8242,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8409,
            +            "description": "<p>Connect a source to the reverb, and assign reverb parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8446,
            +            "description": "<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8482,
            +            "description": "<p>Set the output level of the reverb effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8493,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8501,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8621,
            +            "description": "<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "convolverNode",
            +            "type": "ConvolverNode",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8645,
            +            "description": "<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n",
            +            "itemtype": "property",
            +            "name": "impulses",
            +            "type": "Array",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8737,
            +            "description": "<p>Connect a source to the convolver.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8786,
            +            "description": "<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n",
            +            "itemtype": "method",
            +            "name": "addImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8808,
            +            "description": "<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8831,
            +            "description": "<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleImpulse",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8885,
            +            "description": "<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n",
            +            "itemtype": "method",
            +            "name": "createConvolver",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Convolver"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9084,
            +            "description": "<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9173,
            +            "description": "<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n",
            +            "itemtype": "property",
            +            "name": "sequence",
            +            "type": "Array",
            +            "class": "p5.Phrase",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9263,
            +            "description": "<p>Set the tempo of this part, in Beats Per Minute.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9278,
            +            "description": "<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBPM",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9291,
            +            "description": "<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9311,
            +            "description": "<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9333,
            +            "description": "<p>Tell the part to stop looping.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9349,
            +            "description": "<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9363,
            +            "description": "<p>Pause the part. Playback will resume\nfrom the current step.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9379,
            +            "description": "<p>Add a p5.Phrase to this Part.</p>\n",
            +            "itemtype": "method",
            +            "name": "addPhrase",
            +            "params": [
            +                {
            +                    "name": "phrase",
            +                    "description": "<p>reference to a p5.Phrase</p>\n",
            +                    "type": "p5.Phrase"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9406,
            +            "description": "<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n",
            +            "itemtype": "method",
            +            "name": "removePhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9424,
            +            "description": "<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9442,
            +            "description": "<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n",
            +            "itemtype": "method",
            +            "name": "replaceSequence",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9473,
            +            "description": "<p>Set the function that will be called at every step. This will clear the previous function.</p>\n",
            +            "itemtype": "method",
            +            "name": "onStep",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9542,
            +            "description": "<p>Start playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9555,
            +            "description": "<p>Stop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9569,
            +            "description": "<p>Pause playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9581,
            +            "description": "<p>Loop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9594,
            +            "description": "<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9628,
            +            "description": "<p>Set the tempo for all parts in the score</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9729,
            +            "description": "<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n",
            +            "itemtype": "property",
            +            "name": "bpm",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9750,
            +            "description": "<p>number of quarter notes in a measure (defaults to 4)</p>\n",
            +            "itemtype": "property",
            +            "name": "timeSignature",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9770,
            +            "description": "<p>length of the loops interval</p>\n",
            +            "itemtype": "property",
            +            "name": "interval",
            +            "type": "Number|String",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9787,
            +            "description": "<p>how many times the callback has been called so far</p>\n",
            +            "itemtype": "property",
            +            "name": "iterations",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9800,
            +            "description": "<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n",
            +            "itemtype": "property",
            +            "name": "musicalTimeMode",
            +            "type": "Boolean",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9808,
            +            "description": "<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9816,
            +            "description": "<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n",
            +            "itemtype": "property",
            +            "name": "maxIterations",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9826,
            +            "description": "<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9841,
            +            "description": "<p>Start the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a starting time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9860,
            +            "description": "<p>Stop the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a stopping time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9878,
            +            "description": "<p>Pause the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a pausing time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9896,
            +            "description": "<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n",
            +            "itemtype": "method",
            +            "name": "syncedStart",
            +            "params": [
            +                {
            +                    "name": "otherLoop",
            +                    "description": "<p>a p5.SoundLoop to sync with</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Start the loops in sync after timeFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10068,
            +            "description": "<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n",
            +            "itemtype": "property",
            +            "name": "compressor",
            +            "type": "AudioNode",
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10084,
            +            "description": "<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Sound source to be connected</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10112,
            +            "description": "<p>Set the paramters of a compressor.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10152,
            +            "description": "<p>Get current attack or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "attack",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10178,
            +            "description": "<p>Get current knee or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "knee",
            +            "params": [
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10204,
            +            "description": "<p>Get current ratio or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "ratio",
            +            "params": [
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10228,
            +            "description": "<p>Get current threshold or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "threshold",
            +            "params": [
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10252,
            +            "description": "<p>Get current release or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "release",
            +            "params": [
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10277,
            +            "description": "<p>Return the current reduction value</p>\n",
            +            "itemtype": "method",
            +            "name": "reduction",
            +            "return": {
            +                "description": "Value of the amount of gain reduction that is applied to the signal",
            +                "type": "Number"
            +            },
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10419,
            +            "description": "<p>isDetected is set to true when a peak is detected.</p>\n",
            +            "itemtype": "attribute",
            +            "name": "isDetected",
            +            "type": "Boolean",
            +            "default": "false",
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10432,
            +            "description": "<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n",
            +            "itemtype": "method",
            +            "name": "update",
            +            "params": [
            +                {
            +                    "name": "fftObject",
            +                    "description": "<p>A p5.FFT object</p>\n",
            +                    "type": "p5.FFT"
            +                }
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10470,
            +            "description": "<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onPeak",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "val",
            +                    "description": "<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10676,
            +            "description": "<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10703,
            +            "description": "<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n",
            +            "itemtype": "method",
            +            "name": "record",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that will be\n                              called once the recording completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10739,
            +            "description": "<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10864,
            +            "description": "<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "WaveShaperNode",
            +            "type": "AudioNode",
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10883,
            +            "description": "<p>Process a sound source, optionally specify amount and oversample values.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10900,
            +            "description": "<p>Set the amount and oversample of the waveshaper distortion.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10923,
            +            "description": "<p>Return the distortion amount, typically between 0-1.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmount",
            +            "return": {
            +                "description": "Unbounded distortion amount.\n                 Normal values range from 0-1.",
            +                "type": "Number"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10937,
            +            "description": "<p>Return the oversampling.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOversample",
            +            "return": {
            +                "description": "Oversample can either be 'none', '2x', or '4x'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11055,
            +            "description": "<p>Connect a source to the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11070,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11084,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11098,
            +            "description": "<p>Set the output level of the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11181,
            +            "description": "<p>Connect to p5 objects or Web Audio Nodes</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11194,
            +            "description": "<p>Disconnect from soundOut</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11322,
            +            "description": "<p>Getters and Setters</p>\n",
            +            "itemtype": "property",
            +            "name": "attack",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11328,
            +            "itemtype": "property",
            +            "name": "decay",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11333,
            +            "itemtype": "property",
            +            "name": "sustain",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11338,
            +            "itemtype": "property",
            +            "name": "release",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11379,
            +            "description": "<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11431,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11478,
            +            "description": "<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11516,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11544,
            +            "description": "<p>MonoSynth amp</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>desired volume</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Time to reach new volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "new volume value",
            +                "type": "Number"
            +            },
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11564,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11578,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11592,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11742,
            +            "description": "<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n",
            +            "itemtype": "property",
            +            "name": "notes",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11755,
            +            "description": "<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n",
            +            "itemtype": "property",
            +            "name": "polyvalue",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11761,
            +            "description": "<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n",
            +            "itemtype": "property",
            +            "name": "AudioVoice",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11800,
            +            "description": "<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11849,
            +            "description": "<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteADSR",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>Midi note on which ADSR should be set.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11881,
            +            "description": "<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11909,
            +            "description": "<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteAttack",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)/</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12021,
            +            "description": "<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteRelease",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12105,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12119,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12133,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        }
            +    ],
            +    "warnings": [
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:120"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:216"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:316"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:457"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:1001"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:223"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:248"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/validate_params.js:336"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:219"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:259"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:185"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:264"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:358"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:398"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:493"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:67"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:293"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:460"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:524"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:583"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:668"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:733"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:826"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:84"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:120"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:138"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:79"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:129"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:160"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:228"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:372"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:390"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:405"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:421"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:500"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:550"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:586"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:660"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:691"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:713"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:42"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:47"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:154"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:189"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:246"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:292"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:403"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:454"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:510"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:551"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:639"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:678"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:725"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:763"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:70"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:7"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:34"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:87"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:137"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:158"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:179"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:200"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:267"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:309"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:379"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:408"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:448"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:490"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:326"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:134"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:192"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:290"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:391"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:497"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:193"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:232"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:304"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:342"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:416"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:455"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:494"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:101"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1560"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1622"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1726"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1765"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1885"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2778"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:23"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:46"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:69"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:135"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:201"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:285"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:330"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:428"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:515"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:546"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:604"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:64"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:103"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:308"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:106"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:132"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:164"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:233"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:271"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:615"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:696"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:772"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:841"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:926"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:979"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:1025"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:71"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:151"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:94"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:413"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:18"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:301"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:569"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:88"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:152"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:261"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:296"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:346"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:400"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:437"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:548"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:665"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:738"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:900"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:941"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:972"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1017"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1052"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1089"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:173"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:307"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:566"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:602"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:674"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:583"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1393"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:85"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:148"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:240"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:352"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:545"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:597"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:638"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:896"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:960"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1009"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1055"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1242"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1305"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:40"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:191"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:295"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.XML.js:9"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:33"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:72"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:116"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:182"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:269"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:316"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:371"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:409"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:464"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:560"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:612"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:646"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:701"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:745"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/math.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:178"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/p5.Vector.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:37"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:153"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:123"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:159"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:186"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:213"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:285"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:320"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:335"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:350"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:118"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:150"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:187"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:16"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:140"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/p5.Font.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/conversion.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:237"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:373"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:451"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:537"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:73"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:143"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/3d_primitives.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:353"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:177"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:280"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:387"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:425"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:519"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:588"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:12"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:282"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:587"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:659"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:697"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:777"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:829"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:902"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:176"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:236"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:357"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:444"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:472"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:499"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:526"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:554"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:582"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:610"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:683"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:801"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:897"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1040"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1098"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1156"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1386"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1458"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1723"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:334"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:644"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:749"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Shader.js:306"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:115"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:158"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:191"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:236"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:250"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:456"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:471"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:556"
            +        },
            +        {
            +            "message": "replacing incorrect tag: params with param",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2882"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4360"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4386"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4460"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:6280"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:8116"
            +        },
            +        {
            +            "message": "Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.",
            +            "line": " src/color/color_conversion.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:19"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to RGBA.",
            +            "line": " src/color/color_conversion.js:45"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to HSBA.",
            +            "line": " src/color/color_conversion.js:100"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.",
            +            "line": " src/color/color_conversion.js:123"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSBA.",
            +            "line": " src/color/color_conversion.js:187"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:226"
            +        },
            +        {
            +            "message": "Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.",
            +            "line": " src/color/p5.Color.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.",
            +            "line": " src/color/p5.Color.js:427"
            +        },
            +        {
            +            "message": "Missing item type\nCSS named colors.",
            +            "line": " src/color/p5.Color.js:446"
            +        },
            +        {
            +            "message": "Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.",
            +            "line": " src/color/p5.Color.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nFull color string patterns. The capture groups are necessary.",
            +            "line": " src/color/p5.Color.js:613"
            +        },
            +        {
            +            "message": "Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.",
            +            "line": " src/color/p5.Color.js:750"
            +        },
            +        {
            +            "message": "Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.",
            +            "line": " src/color/p5.Color.js:960"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/fes_core.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.",
            +            "line": " src/core/friendly_errors/fes_core.js:915"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/file_errors.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/sketch_reader.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/stacktrace.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nGiven an Error object, extract the most information from it.",
            +            "line": " src/core/friendly_errors/stacktrace.js:34"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/validate_params.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).",
            +            "line": " src/core/shape/2d_primitives.js:16"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current framerate.",
            +            "line": " src/core/environment.js:305"
            +        },
            +        {
            +            "message": "Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.",
            +            "line": " src/core/environment.js:315"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/helpers.js:1"
            +        },
            +        {
            +            "message": "Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing",
            +            "line": " src/core/init.js:4"
            +        },
            +        {
            +            "message": "Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.",
            +            "line": " src/core/internationalization.js:30"
            +        },
            +        {
            +            "message": "Missing item type\nSet up our translation function, with loaded languages",
            +            "line": " src/core/internationalization.js:126"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a list of languages we have translations loaded for",
            +            "line": " src/core/internationalization.js:171"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current language selected for translation",
            +            "line": " src/core/internationalization.js:178"
            +        },
            +        {
            +            "message": "Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.",
            +            "line": " src/core/internationalization.js:185"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/legacy.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/core/p5.Element.js:827"
            +        },
            +        {
            +            "message": "Missing item type\nResize our canvas element.",
            +            "line": " src/core/p5.Renderer.js:99"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to check font type (system or otf)",
            +            "line": " src/core/p5.Renderer.js:415"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178",
            +            "line": " src/core/p5.Renderer.js:467"
            +        },
            +        {
            +            "message": "Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer",
            +            "line": " src/core/p5.Renderer2D.js:7"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.",
            +            "line": " src/core/p5.Renderer2D.js:402"
            +        },
            +        {
            +            "message": "Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.",
            +            "line": " src/core/shim.js:18"
            +        },
            +        {
            +            "message": "Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign",
            +            "line": " src/core/shim.js:39"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()",
            +            "line": " src/data/p5.TypedDict.js:197"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:387"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:425"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:536"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for select and selectAll",
            +            "line": " src/dom/dom.js:127"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for getElement and getElements.",
            +            "line": " src/dom/dom.js:142"
            +        },
            +        {
            +            "message": "Missing item type\nHelpers for create methods.",
            +            "line": " src/dom/dom.js:309"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:450"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1164"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1257"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1296"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3232"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3298"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3360"
            +        },
            +        {
            +            "message": "Missing item type\n_updatePAccelerations updates the pAcceleration values",
            +            "line": " src/events/acceleration.js:124"
            +        },
            +        {
            +            "message": "Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.",
            +            "line": " src/events/keyboard.js:298"
            +        },
            +        {
            +            "message": "Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.",
            +            "line": " src/events/keyboard.js:384"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.",
            +            "line": " src/image/filters.js:3"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the pixel buffer for a canvas",
            +            "line": " src/image/filters.js:24"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.",
            +            "line": " src/image/filters.js:60"
            +        },
            +        {
            +            "message": "Missing item type\nModifies pixels RGBA values to values contained in the data object.",
            +            "line": " src/image/filters.js:81"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData",
            +            "line": " src/image/filters.js:101"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a blank ImageData object.",
            +            "line": " src/image/filters.js:121"
            +        },
            +        {
            +            "message": "Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.",
            +            "line": " src/image/filters.js:136"
            +        },
            +        {
            +            "message": "Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:189"
            +        },
            +        {
            +            "message": "Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:223"
            +        },
            +        {
            +            "message": "Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.",
            +            "line": " src/image/filters.js:246"
            +        },
            +        {
            +            "message": "Missing item type\nSets each pixel to its inverse value. No parameter is used.",
            +            "line": " src/image/filters.js:262"
            +        },
            +        {
            +            "message": "Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation",
            +            "line": " src/image/filters.js:277"
            +        },
            +        {
            +            "message": "Missing item type\nreduces the bright areas in an image",
            +            "line": " src/image/filters.js:309"
            +        },
            +        {
            +            "message": "Missing item type\nincreases the bright areas in an image",
            +            "line": " src/image/filters.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.",
            +            "line": " src/image/image.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for loading GIF-based images",
            +            "line": " src/image/loading_displaying.js:162"
            +        },
            +        {
            +            "message": "Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.",
            +            "line": " src/image/loading_displaying.js:597"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.",
            +            "line": " src/image/p5.Image.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for animating GIF-based images with time",
            +            "line": " src/image/p5.Image.js:222"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/image/p5.Image.js:253"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.",
            +            "line": " src/io/files.js:1789"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.",
            +            "line": " src/io/files.js:1857"
            +        },
            +        {
            +            "message": "Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.",
            +            "line": " src/io/files.js:1890"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.",
            +            "line": " src/io/files.js:1902"
            +        },
            +        {
            +            "message": "Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "line": " src/io/p5.Table.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nMultiplies a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2135"
            +        },
            +        {
            +            "message": "Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2187"
            +        },
            +        {
            +            "message": "Missing item type\nDivides a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2214"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the dot product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2267"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the cross product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2281"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).",
            +            "line": " src/math/p5.Vector.js:2295"
            +        },
            +        {
            +            "message": "Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.",
            +            "line": " src/math/p5.Vector.js:2310"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)",
            +            "line": " src/math/p5.Vector.js:2339"
            +        },
            +        {
            +            "message": "Missing item type\nNormalize the vector to length 1 (make it a unit vector).",
            +            "line": " src/math/p5.Vector.js:2357"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to measure ascent and descent.",
            +            "line": " src/typography/attributes.js:280"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.",
            +            "line": " src/typography/p5.Font.js:273"
            +        },
            +        {
            +            "message": "Missing item type\nReturns an opentype path for the supplied string and position.",
            +            "line": " src/typography/p5.Font.js:288"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/3d_primitives.js:301"
            +        },
            +        {
            +            "message": "Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.",
            +            "line": " src/webgl/3d_primitives.js:955"
            +        },
            +        {
            +            "message": "Missing item type\nDraw a line given two points",
            +            "line": " src/webgl/3d_primitives.js:1393"
            +        },
            +        {
            +            "message": "Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1",
            +            "line": " src/webgl/loading.js:179"
            +        },
            +        {
            +            "message": "Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.",
            +            "line": " src/webgl/loading.js:290"
            +        },
            +        {
            +            "message": "Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.",
            +            "line": " src/webgl/loading.js:317"
            +        },
            +        {
            +            "message": "Missing item type\nThis function matches the `query` at the provided `offset`",
            +            "line": " src/webgl/loading.js:344"
            +        },
            +        {
            +            "message": "Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.",
            +            "line": " src/webgl/loading.js:356"
            +        },
            +        {
            +            "message": "Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`",
            +            "line": " src/webgl/loading.js:444"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:947"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:978"
            +        },
            +        {
            +            "message": "Missing item type\nCreate a 2D array for establishing stroke connections",
            +            "line": " src/webgl/p5.Geometry.js:212"
            +        },
            +        {
            +            "message": "Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU",
            +            "line": " src/webgl/p5.Geometry.js:233"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/p5.Matrix.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPRIVATE",
            +            "line": " src/webgl/p5.Matrix.js:722"
            +        },
            +        {
            +            "message": "Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.",
            +            "line": " src/webgl/p5.RenderBuffer.js:12"
            +        },
            +        {
            +            "message": "Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nEnd shape drawing and render vertices to screen.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:129"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:169"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:248"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:268"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:302"
            +        },
            +        {
            +            "message": "Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:59"
            +        },
            +        {
            +            "message": "Missing item type\nDraws buffers given a geometry key ID",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:110"
            +        },
            +        {
            +            "message": "Missing item type\nmodel view, projection, & normal\nmatrices",
            +            "line": " src/webgl/p5.RendererGL.js:117"
            +        },
            +        {
            +            "message": "Missing item type\n[background description]",
            +            "line": " src/webgl/p5.RendererGL.js:586"
            +        },
            +        {
            +            "message": "Missing item type\n[resize description]",
            +            "line": " src/webgl/p5.RendererGL.js:860"
            +        },
            +        {
            +            "message": "Missing item type\nclears color and depth buffers\nwith r,g,b,a",
            +            "line": " src/webgl/p5.RendererGL.js:890"
            +        },
            +        {
            +            "message": "Missing item type\n[translate description]",
            +            "line": " src/webgl/p5.RendererGL.js:924"
            +        },
            +        {
            +            "message": "Missing item type\nScales the Model View Matrix by a vector",
            +            "line": " src/webgl/p5.RendererGL.js:943"
            +        },
            +        {
            +            "message": "Missing item type\nturn a two dimensional array into one dimensional array",
            +            "line": " src/webgl/p5.RendererGL.js:1366"
            +        },
            +        {
            +            "message": "Missing item type\nturn a p5.Vector Array into a one dimensional number array",
            +            "line": " src/webgl/p5.RendererGL.js:1403"
            +        },
            +        {
            +            "message": "Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.",
            +            "line": " src/webgl/p5.RendererGL.js:1421"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:1"
            +        },
            +        {
            +            "message": "Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/",
            +            "line": " lib/addons/p5.sound.js:52"
            +        },
            +        {
            +            "message": "Missing item type\nThis module has shims",
            +            "line": " lib/addons/p5.sound.js:401"
            +        },
            +        {
            +            "message": "Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats",
            +            "line": " lib/addons/p5.sound.js:536"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:807"
            +        },
            +        {
            +            "message": "Missing item type\nUsed by Osc and Envelope to chain signal math",
            +            "line": " lib/addons/p5.sound.js:1040"
            +        },
            +        {
            +            "message": "Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.",
            +            "line": " lib/addons/p5.sound.js:1542"
            +        },
            +        {
            +            "message": "Missing item type\nStop playback on all of this soundfile's sources.",
            +            "line": " lib/addons/p5.sound.js:2056"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:2604"
            +        },
            +        {
            +            "message": "Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade",
            +            "line": " lib/addons/p5.sound.js:6455"
            +        },
            +        {
            +            "message": "Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter",
            +            "line": " lib/addons/p5.sound.js:6462"
            +        },
            +        {
            +            "message": "Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ",
            +            "line": " lib/addons/p5.sound.js:7009"
            +        },
            +        {
            +            "message": "Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.",
            +            "line": " lib/addons/p5.sound.js:8508"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.",
            +            "line": " lib/addons/p5.sound.js:8659"
            +        },
            +        {
            +            "message": "Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string",
            +            "line": " lib/addons/p5.sound.js:9808"
            +        },
            +        {
            +            "message": "Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached",
            +            "line": " lib/addons/p5.sound.js:9826"
            +        },
            +        {
            +            "message": "Missing item type\ncallback invoked when the recording is over",
            +            "line": " lib/addons/p5.sound.js:10660"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release",
            +            "line": " lib/addons/p5.sound.js:11995"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.min.js:1"
            +        }
            +    ],
            +    "consts": {
            +        "LABEL": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "FALLBACK": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "RGB": [
            +            "p5.colorMode"
            +        ],
            +        "HSB": [
            +            "p5.colorMode"
            +        ],
            +        "HSL": [
            +            "p5.colorMode"
            +        ],
            +        "CHORD": [
            +            "p5.arc"
            +        ],
            +        "PIE": [
            +            "p5.arc"
            +        ],
            +        "OPEN": [
            +            "p5.arc"
            +        ],
            +        "CENTER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode",
            +            "p5.textAlign"
            +        ],
            +        "RADIUS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode"
            +        ],
            +        "CORNER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "CORNERS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "ROUND": [
            +            "p5.strokeCap",
            +            "p5.strokeJoin"
            +        ],
            +        "SQUARE": [
            +            "p5.strokeCap"
            +        ],
            +        "PROJECT": [
            +            "p5.strokeCap"
            +        ],
            +        "MITER": [
            +            "p5.strokeJoin"
            +        ],
            +        "BEVEL": [
            +            "p5.strokeJoin"
            +        ],
            +        "POINTS": [
            +            "p5.beginShape"
            +        ],
            +        "LINES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_FAN": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "QUADS": [
            +            "p5.beginShape"
            +        ],
            +        "QUAD_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "TESS": [
            +            "p5.beginShape"
            +        ],
            +        "CLOSE": [
            +            "p5.endShape"
            +        ],
            +        "ARROW": [
            +            "p5.cursor"
            +        ],
            +        "CROSS": [
            +            "p5.cursor"
            +        ],
            +        "HAND": [
            +            "p5.cursor"
            +        ],
            +        "MOVE": [
            +            "p5.cursor"
            +        ],
            +        "TEXT": [
            +            "p5.cursor"
            +        ],
            +        "P2D": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "WEBGL": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "BLEND": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DARKEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "LIGHTEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DIFFERENCE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "MULTIPLY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "EXCLUSION": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SCREEN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REPLACE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "OVERLAY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "HARD_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SOFT_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DODGE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "BURN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "ADD": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REMOVE": [
            +            "p5.blendMode"
            +        ],
            +        "SUBTRACT": [
            +            "p5.blendMode"
            +        ],
            +        "VIDEO": [
            +            "p5.createCapture"
            +        ],
            +        "AUDIO": [
            +            "p5.createCapture"
            +        ],
            +        "THRESHOLD": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "GRAY": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "OPAQUE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "INVERT": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "POSTERIZE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "ERODE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "DILATE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "BLUR": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "NORMAL": [
            +            "p5.Image.blend",
            +            "p5.blend",
            +            "p5.textStyle",
            +            "p5.textureMode"
            +        ],
            +        "RADIANS": [
            +            "p5.angleMode"
            +        ],
            +        "DEGREES": [
            +            "p5.angleMode"
            +        ],
            +        "LEFT": [
            +            "p5.textAlign"
            +        ],
            +        "RIGHT": [
            +            "p5.textAlign"
            +        ],
            +        "TOP": [
            +            "p5.textAlign"
            +        ],
            +        "BOTTOM": [
            +            "p5.textAlign"
            +        ],
            +        "BASELINE": [
            +            "p5.textAlign"
            +        ],
            +        "ITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "BOLD": [
            +            "p5.textStyle"
            +        ],
            +        "BOLDITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "WORD": [
            +            "p5.textWrap"
            +        ],
            +        "CHAR": [
            +            "p5.textWrap"
            +        ],
            +        "IMAGE": [
            +            "p5.textureMode"
            +        ],
            +        "CLAMP": [
            +            "p5.textureWrap"
            +        ],
            +        "REPEAT": [
            +            "p5.textureWrap"
            +        ],
            +        "MIRROR": [
            +            "p5.textureWrap"
            +        ]
            +    }
            +}
            \ No newline at end of file
            diff --git a/dist/es/reference/data.min.json b/dist/es/reference/data.min.json
            new file mode 100644
            index 0000000000..b719e76314
            --- /dev/null
            +++ b/dist/es/reference/data.min.json
            @@ -0,0 +1 @@
            +{"project":{"name":"p5","description":"[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)","version":"1.4.1","url":"https://github.com/processing/p5.js#readme"},"files":{"src/accessibility/color_namer.js":{"name":"src/accessibility/color_namer.js","modules":{"Environment":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/describe.js":{"name":"src/accessibility/describe.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/gridOutput.js":{"name":"src/accessibility/gridOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/outputs.js":{"name":"src/accessibility/outputs.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/textOutput.js":{"name":"src/accessibility/textOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/color_conversion.js":{"name":"src/color/color_conversion.js","modules":{"Color Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/creating_reading.js":{"name":"src/color/creating_reading.js","modules":{"Creating & Reading":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/p5.Color.js":{"name":"src/color/p5.Color.js","modules":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{}},"src/color/setting.js":{"name":"src/color/setting.js","modules":{"Setting":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/fes_core.js":{"name":"src/core/friendly_errors/fes_core.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/file_errors.js":{"name":"src/core/friendly_errors/file_errors.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/sketch_reader.js":{"name":"src/core/friendly_errors/sketch_reader.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/stacktrace.js":{"name":"src/core/friendly_errors/stacktrace.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/validate_params.js":{"name":"src/core/friendly_errors/validate_params.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/2d_primitives.js":{"name":"src/core/shape/2d_primitives.js","modules":{"2D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/attributes.js":{"name":"src/core/shape/attributes.js","modules":{"Attributes":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/curves.js":{"name":"src/core/shape/curves.js","modules":{"Curves":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/vertex.js":{"name":"src/core/shape/vertex.js","modules":{"Vertex":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/constants.js":{"name":"src/core/constants.js","modules":{"Constants":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/environment.js":{"name":"src/core/environment.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/helpers.js":{"name":"src/core/helpers.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/init.js":{"name":"src/core/init.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/internationalization.js":{"name":"src/core/internationalization.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/legacy.js":{"name":"src/core/legacy.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/main.js":{"name":"src/core/main.js","modules":{"Structure":1},"classes":{"p5":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Element.js":{"name":"src/core/p5.Element.js","modules":{"DOM":1},"classes":{"p5.Element":1},"fors":{"p5.Element":1},"namespaces":{}},"src/core/p5.Graphics.js":{"name":"src/core/p5.Graphics.js","modules":{"Rendering":1},"classes":{"p5.Graphics":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer.js":{"name":"src/core/p5.Renderer.js","modules":{},"classes":{"p5.Renderer":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer2D.js":{"name":"src/core/p5.Renderer2D.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/reference.js":{"name":"src/core/reference.js","modules":{"Foundation":1},"classes":{},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{}},"src/core/rendering.js":{"name":"src/core/rendering.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shim.js":{"name":"src/core/shim.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/structure.js":{"name":"src/core/structure.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/transform.js":{"name":"src/core/transform.js","modules":{"Transform":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/local_storage.js":{"name":"src/data/local_storage.js","modules":{"LocalStorage":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/p5.TypedDict.js":{"name":"src/data/p5.TypedDict.js","modules":{"Dictionary":1},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"namespaces":{}},"src/dom/dom.js":{"name":"src/dom/dom.js","modules":{},"classes":{"p5.MediaElement":1,"p5.File":1},"fors":{"p5":1,"p5.Element":1},"namespaces":{}},"src/events/acceleration.js":{"name":"src/events/acceleration.js","modules":{"Acceleration":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/keyboard.js":{"name":"src/events/keyboard.js","modules":{"Keyboard":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/mouse.js":{"name":"src/events/mouse.js","modules":{"Mouse":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/touch.js":{"name":"src/events/touch.js","modules":{"Touch":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/filters.js":{"name":"src/image/filters.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/image/image.js":{"name":"src/image/image.js","modules":{"Image":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/loading_displaying.js":{"name":"src/image/loading_displaying.js","modules":{"Loading & Displaying":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/p5.Image.js":{"name":"src/image/p5.Image.js","modules":{},"classes":{"p5.Image":1},"fors":{},"namespaces":{}},"src/image/pixels.js":{"name":"src/image/pixels.js","modules":{"Pixels":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/io/files.js":{"name":"src/io/files.js","modules":{"Input":1,"Output":1},"classes":{"p5.PrintWriter":1},"fors":{"p5":1},"namespaces":{}},"src/io/p5.Table.js":{"name":"src/io/p5.Table.js","modules":{"Table":1},"classes":{"p5.Table":1},"fors":{},"namespaces":{}},"src/io/p5.TableRow.js":{"name":"src/io/p5.TableRow.js","modules":{},"classes":{"p5.TableRow":1},"fors":{},"namespaces":{}},"src/io/p5.XML.js":{"name":"src/io/p5.XML.js","modules":{},"classes":{"p5.XML":1},"fors":{},"namespaces":{}},"src/math/calculation.js":{"name":"src/math/calculation.js","modules":{"Calculation":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/math.js":{"name":"src/math/math.js","modules":{"Vector":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/noise.js":{"name":"src/math/noise.js","modules":{"Noise":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/p5.Vector.js":{"name":"src/math/p5.Vector.js","modules":{},"classes":{"p5.Vector":1},"fors":{},"namespaces":{}},"src/math/random.js":{"name":"src/math/random.js","modules":{"Random":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/trigonometry.js":{"name":"src/math/trigonometry.js","modules":{"Trigonometry":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/attributes.js":{"name":"src/typography/attributes.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/loading_displaying.js":{"name":"src/typography/loading_displaying.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/p5.Font.js":{"name":"src/typography/p5.Font.js","modules":{},"classes":{"p5.Font":1},"fors":{},"namespaces":{}},"src/utilities/array_functions.js":{"name":"src/utilities/array_functions.js","modules":{"Array Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/conversion.js":{"name":"src/utilities/conversion.js","modules":{"Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/string_functions.js":{"name":"src/utilities/string_functions.js","modules":{"String Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/time_date.js":{"name":"src/utilities/time_date.js","modules":{"Time & Date":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/3d_primitives.js":{"name":"src/webgl/3d_primitives.js","modules":{"3D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/interaction.js":{"name":"src/webgl/interaction.js","modules":{"Interaction":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/light.js":{"name":"src/webgl/light.js","modules":{"Lights":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/loading.js":{"name":"src/webgl/loading.js","modules":{"3D Models":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/material.js":{"name":"src/webgl/material.js","modules":{"Material":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Camera.js":{"name":"src/webgl/p5.Camera.js","modules":{"Camera":1},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{}},"src/webgl/p5.Geometry.js":{"name":"src/webgl/p5.Geometry.js","modules":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Matrix.js":{"name":"src/webgl/p5.Matrix.js","modules":{},"classes":{"p5.Matrix":1},"fors":{},"namespaces":{}},"src/webgl/p5.RenderBuffer.js":{"name":"src/webgl/p5.RenderBuffer.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Immediate.js":{"name":"src/webgl/p5.RendererGL.Immediate.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Retained.js":{"name":"src/webgl/p5.RendererGL.Retained.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.js":{"name":"src/webgl/p5.RendererGL.js","modules":{},"classes":{"p5.RendererGL":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Shader.js":{"name":"src/webgl/p5.Shader.js","modules":{},"classes":{"p5.Shader":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Texture.js":{"name":"src/webgl/p5.Texture.js","modules":{},"classes":{"p5.Texture":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/text.js":{"name":"src/webgl/text.js","modules":{},"classes":{"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{},"namespaces":{}},"lib/addons/p5.sound.js":{"name":"lib/addons/p5.sound.js","modules":{"p5.sound":1},"classes":{"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{}},"lib/addons/p5.sound.min.js":{"name":"lib/addons/p5.sound.min.js","modules":{},"classes":{},"fors":{},"namespaces":{}}},"modules":{"Environment":{"name":"Environment","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Environment","file":"src/accessibility/color_namer.js","line":1,"requires":["core"]},"Color":{"name":"Color","submodules":{"Color Conversion":1,"Creating & Reading":1,"Setting":1},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{},"file":"src/color/p5.Color.js","line":14},"Color Conversion":{"name":"Color Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/color_conversion.js","line":1,"requires":["core"]},"Creating & Reading":{"name":"Creating & Reading","submodules":{},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/p5.Color.js","line":14,"requires":["core","constants"],"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"},"Setting":{"name":"Setting","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/setting.js","line":1,"requires":["core","constants"]},"Shape":{"name":"Shape","submodules":{"2D Primitives":1,"Curves":1,"Vertex":1,"3D Primitives":1,"3D Models":1},"elements":{},"classes":{"p5.Geometry":1,"p5.Matrix":1},"fors":{"p5":1},"namespaces":{},"file":"src/webgl/p5.Matrix.js","line":19},"2D Primitives":{"name":"2D Primitives","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/2d_primitives.js","line":1,"requires":["core","constants"]},"Attributes":{"name":"Attributes","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/core/shape/attributes.js","line":1,"requires":["core","constants"]},"Curves":{"name":"Curves","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/curves.js","line":1,"requires":["core"]},"Vertex":{"name":"Vertex","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/vertex.js","line":1,"requires":["core","constants"]},"Constants":{"name":"Constants","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Constants","file":"src/core/constants.js","line":1},"Structure":{"name":"Structure","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"IO","file":"src/core/main.js","line":1,"requires":["constants"]},"DOM":{"name":"DOM","submodules":{},"elements":{},"classes":{"p5.Element":1,"p5.MediaElement":1,"p5.File":1},"fors":{"p5.Element":1,"p5":1},"namespaces":{},"module":"DOM","file":"src/dom/dom.js","line":3533,"description":"<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n","requires":["p5"]},"Rendering":{"name":"Rendering","submodules":{"undefined":1},"elements":{},"classes":{"p5.RendererGL":1,"p5.Graphics":1,"p5.Renderer":1},"fors":{"p5":1},"namespaces":{},"module":"Rendering","file":"src/webgl/p5.RendererGL.js","line":603,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"},"Foundation":{"name":"Foundation","submodules":{},"elements":{},"classes":{"JSON":1,"console":1},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{},"module":"Foundation","file":"src/core/reference.js","line":1},"Transform":{"name":"Transform","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Transform","file":"src/core/transform.js","line":1,"requires":["core","constants"]},"Data":{"name":"Data","submodules":{"LocalStorage":1,"Dictionary":1,"Array Functions":1,"Conversion":1,"String Functions":1},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5":1,"p5.TypedDict":1},"namespaces":{},"file":"src/data/p5.TypedDict.js","line":410},"LocalStorage":{"name":"LocalStorage","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/local_storage.js","line":1,"requires":["core\n\nThis module defines the p5 methods for working with local storage"]},"Dictionary":{"name":"Dictionary","submodules":{},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"requires":["core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."],"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"},"Events":{"name":"Events","submodules":{"Acceleration":1,"Keyboard":1,"Mouse":1,"Touch":1},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"Acceleration":{"name":"Acceleration","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/acceleration.js","line":1,"requires":["core"]},"Keyboard":{"name":"Keyboard","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/keyboard.js","line":1,"requires":["core"]},"Mouse":{"name":"Mouse","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/mouse.js","line":1,"requires":["core","constants"]},"Touch":{"name":"Touch","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/touch.js","line":1,"requires":["core"]},"Image":{"name":"Image","submodules":{"Pixels":1},"elements":{},"classes":{"p5.Image":1},"fors":{"p5":1},"namespaces":{},"module":"Image","file":"src/image/p5.Image.js","line":21,"requires":["core"],"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"},"Loading & Displaying":{"name":"Loading & Displaying","submodules":{},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/typography/p5.Font.js","line":13,"requires":["core"],"description":"<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"},"Pixels":{"name":"Pixels","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Image","namespace":"","file":"src/image/pixels.js","line":1,"requires":["core"]},"IO":{"name":"IO","submodules":{"Structure":1,"Input":1,"Output":1,"Table":1,"Time & Date":1},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1,"p5.Table":1,"p5.TableRow":1,"p5.XML":1},"fors":{"p5":1},"namespaces":{},"file":"src/io/p5.XML.js","line":9},"Input":{"name":"Input","submodules":{},"elements":{},"classes":{"p5.XML":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.XML.js","line":9,"requires":["core"],"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"},"Output":{"name":"Output","submodules":{},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/files.js","line":1200,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"},"Table":{"name":"Table","submodules":{},"elements":{},"classes":{"p5.Table":1,"p5.TableRow":1},"fors":{},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.TableRow.js","line":9,"requires":["core"],"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"},"Math":{"name":"Math","submodules":{"Calculation":1,"Vector":1,"Noise":1,"Random":1,"Trigonometry":1},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"namespaces":{},"file":"src/math/p5.Vector.js","line":10},"Calculation":{"name":"Calculation","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/calculation.js","line":1,"requires":["core"]},"Vector":{"name":"Vector","submodules":{},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/p5.Vector.js","line":10,"requires":["core"],"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"},"Noise":{"name":"Noise","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/noise.js","line":14,"requires":["core"]},"Random":{"name":"Random","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/random.js","line":1,"requires":["core"]},"Trigonometry":{"name":"Trigonometry","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/trigonometry.js","line":1,"requires":["core","constants"]},"Typography":{"name":"Typography","submodules":{"Attributes":1,"Loading & Displaying":1},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"namespaces":{},"file":"src/typography/p5.Font.js","line":13},"Array Functions":{"name":"Array Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/array_functions.js","line":1,"requires":["core"]},"Conversion":{"name":"Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/conversion.js","line":1,"requires":["core"]},"String Functions":{"name":"String Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/string_functions.js","line":1,"requires":["core"]},"Time & Date":{"name":"Time & Date","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/utilities/time_date.js","line":1,"requires":["core"]},"3D Primitives":{"name":"3D Primitives","submodules":{},"elements":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"requires":["core","p5.Geometry"],"description":"<p>p5 Geometry class</p>\n"},"3D":{"name":"3D","submodules":{"Interaction":1,"Lights":1,"Material":1,"Camera":1},"elements":{},"classes":{"p5.Camera":1,"p5.Shader":1,"p5.Texture":1,"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{},"file":"src/webgl/text.js","line":260},"Interaction":{"name":"Interaction","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/interaction.js","line":1,"requires":["core"]},"Lights":{"name":"Lights","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/light.js","line":1,"requires":["core"]},"3D Models":{"name":"3D Models","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/loading.js","line":1,"requires":["core","p5.Geometry"]},"Material":{"name":"Material","submodules":{},"elements":{},"classes":{"p5.Shader":1,"p5.Texture":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Texture.js","line":12,"requires":["core"],"description":"<p>This module defines the p5.Shader class</p>\n"},"Camera":{"name":"Camera","submodules":{},"elements":{},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"requires":["core"],"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"},"p5.sound":{"name":"p5.sound","submodules":{},"elements":{},"classes":{"p5.sound":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{},"module":"p5.sound","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>","tag":"main","itemtype":"main"}},"classes":{"p5":{"name":"p5","shortname":"p5","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/core/main.js","line":13,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n","is_constructor":1,"params":[{"name":"sketch","description":"<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n","type":"Function"},{"name":"node","description":"<p>element to attach canvas to</p>\n","type":"HTMLElement","optional":true}],"return":{"description":"a p5 instance","type":"P5"}},"p5.Color":{"name":"p5.Color","shortname":"p5.Color","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Color","submodule":"Creating & Reading","namespace":"","file":"src/color/p5.Color.js","line":14,"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n","is_constructor":1},"p5.Element":{"name":"p5.Element","shortname":"p5.Element","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/core/p5.Element.js","line":9,"description":"<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Graphics":{"name":"p5.Graphics","shortname":"p5.Graphics","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Graphics.js","line":10,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"},{"name":"renderer","description":"<p>the renderer to use, either P2D or WEBGL</p>\n","type":"Constant"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Renderer":{"name":"p5.Renderer","shortname":"p5.Renderer","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Renderer.js","line":10,"description":"<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true},{"name":"isMainCanvas","description":"<p>whether we're using it as main canvas</p>\n","type":"Boolean","optional":true}]},"JSON":{"name":"JSON","shortname":"JSON","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"console":{"name":"console","shortname":"console","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"p5.TypedDict":{"name":"p5.TypedDict","shortname":"p5.TypedDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":82,"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n","is_constructor":1},"p5.StringDict":{"name":"p5.StringDict","shortname":"p5.StringDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":394,"description":"<p>A simple Dictionary class for Strings.</p>\n","extends":"p5.TypedDict"},"p5.NumberDict":{"name":"p5.NumberDict","shortname":"p5.NumberDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"description":"<p>A simple Dictionary class for Numbers.</p>\n","is_constructor":1,"extends":"p5.TypedDict"},"p5.MediaElement":{"name":"p5.MediaElement","shortname":"p5.MediaElement","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":2377,"description":"<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"}]},"p5.File":{"name":"p5.File","shortname":"p5.File","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":3533,"description":"<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n","is_constructor":1,"params":[{"name":"file","description":"<p>File that is wrapped</p>\n","type":"File"}]},"p5.Image":{"name":"p5.Image","shortname":"p5.Image","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Image","submodule":"Image","namespace":"","file":"src/image/p5.Image.js","line":21,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n","example":["\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"],"is_constructor":1,"params":[{"name":"width","description":"","type":"Number"},{"name":"height","description":"","type":"Number"}]},"p5.PrintWriter":{"name":"p5.PrintWriter","shortname":"p5.PrintWriter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/io/files.js","line":1200,"params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"","type":"String","optional":true}]},"p5.Table":{"name":"p5.Table","shortname":"p5.Table","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.Table.js","line":33,"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n","is_constructor":1,"params":[{"name":"rows","description":"<p>An array of p5.TableRow objects</p>\n","type":"p5.TableRow[]","optional":true}]},"p5.TableRow":{"name":"p5.TableRow","shortname":"p5.TableRow","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.TableRow.js","line":9,"description":"<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n","is_constructor":1,"params":[{"name":"str","description":"<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n","type":"String","optional":true},{"name":"separator","description":"<p>comma separated values (csv) by default</p>\n","type":"String","optional":true}]},"p5.XML":{"name":"p5.XML","shortname":"p5.XML","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Input","namespace":"","file":"src/io/p5.XML.js","line":9,"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n","is_constructor":1,"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed"},"p5.Vector":{"name":"p5.Vector","shortname":"p5.Vector","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Math","submodule":"Vector","namespace":"","file":"src/math/p5.Vector.js","line":10,"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n","is_constructor":1,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"],"alt":"2 white ellipses. One center-left the other bottom right and off canvas"},"p5.Font":{"name":"p5.Font","shortname":"p5.Font","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Typography","submodule":"Loading & Displaying","namespace":"","file":"src/typography/p5.Font.js","line":13,"description":"<p>Base class for font handling</p>\n","is_constructor":1,"params":[{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Camera":{"name":"p5.Camera","shortname":"p5.Camera","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Camera","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n","params":[{"name":"rendererGL","description":"<p>instance of WebGL renderer</p>\n","type":"RendererGL"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes."},"p5.Geometry":{"name":"p5.Geometry","shortname":"p5.Geometry","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Shape","submodule":"3D Primitives","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"description":"<p>p5 Geometry class</p>\n","is_constructor":1,"params":[{"name":"detailX","description":"<p>number of vertices along the x-axis.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of vertices along the y-axis.</p>\n","type":"Integer","optional":true},{"name":"callback","description":"<p>function to call upon object instantiation.</p>\n","type":"Function","optional":true}]},"p5.Shader":{"name":"p5.Shader","shortname":"p5.Shader","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Material","namespace":"","file":"src/webgl/p5.Shader.js","line":11,"description":"<p>Shader class for WEBGL Mode</p>\n","is_constructor":1,"params":[{"name":"renderer","description":"<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n","type":"p5.RendererGL"},{"name":"vertSrc","description":"<p>source code for the vertex shader (as a string)</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader (as a string)</p>\n","type":"String"}]},"p5.sound":{"name":"p5.sound","shortname":"p5.sound","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":""},"p5.SoundFile":{"name":"p5.SoundFile","shortname":"p5.SoundFile","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":1405,"description":"<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true},{"name":"whileLoadingCallback","description":"<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"]},"p5.Amplitude":{"name":"p5.Amplitude","shortname":"p5.Amplitude","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3022,"description":"<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n","is_constructor":1,"params":[{"name":"smoothing","description":"<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"]},"p5.FFT":{"name":"p5.FFT","shortname":"p5.FFT","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3347,"description":"<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>","is_constructor":1,"params":[{"name":"smoothing","description":"<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n","type":"Number","optional":true},{"name":"bins","description":"<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"]},"p5.Oscillator":{"name":"p5.Oscillator","shortname":"p5.Oscillator","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4060,"description":"<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>","is_constructor":1,"params":[{"name":"freq","description":"<p>frequency defaults to 440Hz</p>\n","type":"Number","optional":true},{"name":"type","description":"<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"]},"p5.SinOsc":{"name":"p5.SinOsc","shortname":"p5.SinOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4602,"description":"<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.TriOsc":{"name":"p5.TriOsc","shortname":"p5.TriOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4629,"description":"<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SawOsc":{"name":"p5.SawOsc","shortname":"p5.SawOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4656,"description":"<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SqrOsc":{"name":"p5.SqrOsc","shortname":"p5.SqrOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4683,"description":"<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.Envelope":{"name":"p5.Envelope","shortname":"p5.Envelope","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4721,"description":"<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>","is_constructor":1,"example":["\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"]},"p5.Noise":{"name":"p5.Noise","shortname":"p5.Noise","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5620,"description":"<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"type","description":"<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n","type":"String"}]},"p5.Pulse":{"name":"p5.Pulse","shortname":"p5.Pulse","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5779,"description":"<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"freq","description":"<p>Frequency in oscillations per second (Hz)</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"]},"p5.AudioIn":{"name":"p5.AudioIn","shortname":"p5.AudioIn","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6015,"description":"<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>","is_constructor":1,"params":[{"name":"errorCallback","description":"<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"]},"p5.Effect":{"name":"p5.Effect","shortname":"p5.Effect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6423,"description":"<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n","is_constructor":1,"params":[{"name":"ac","description":"<p>Reference to the audio context of the p5 object</p>\n","type":"Object","optional":true},{"name":"input","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"output","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"_drywet","description":"<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n","type":"Object","optional":true},{"name":"wet","description":"<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n","type":"AudioNode","optional":true}]},"p5.Filter":{"name":"p5.Filter","shortname":"p5.Filter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6628,"description":"<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"type","description":"<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"]},"p5.LowPass":{"name":"p5.LowPass","shortname":"p5.LowPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6914,"description":"<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.HighPass":{"name":"p5.HighPass","shortname":"p5.HighPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6938,"description":"<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.BandPass":{"name":"p5.BandPass","shortname":"p5.BandPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6962,"description":"<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.EQ":{"name":"p5.EQ","shortname":"p5.EQ","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7105,"description":"<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect","params":[{"name":"_eqsize","description":"<p>Constructor will accept 3 or 8, defaults to 3</p>\n","type":"Number","optional":true}],"return":{"description":"p5.EQ object","type":"Object"},"example":["\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"]},"p5.Panner3D":{"name":"p5.Panner3D","shortname":"p5.Panner3D","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7602,"description":"<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n","is_constructor":1},"p5.Delay":{"name":"p5.Delay","shortname":"p5.Delay","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7926,"description":"<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"]},"p5.Reverb":{"name":"p5.Reverb","shortname":"p5.Reverb","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8308,"description":"<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"]},"p5.Convolver":{"name":"p5.Convolver","shortname":"p5.Convolver","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8549,"description":"<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>","extends":"p5.Effect","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call when loading succeeds</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"]},"p5.Phrase":{"name":"p5.Phrase","shortname":"p5.Phrase","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9103,"description":"<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>","is_constructor":1,"params":[{"name":"name","description":"<p>Name so that you can access the Phrase.</p>\n","type":"String"},{"name":"callback","description":"<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n","type":"Function"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"example":["\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"]},"p5.Part":{"name":"p5.Part","shortname":"p5.Part","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9185,"description":"<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>","is_constructor":1,"params":[{"name":"steps","description":"<p>Steps in the part</p>\n","type":"Number","optional":true},{"name":"tatums","description":"<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"]},"p5.Score":{"name":"p5.Score","shortname":"p5.Score","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9493,"description":"<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n","is_constructor":1,"params":[{"name":"parts","description":"<p>One or multiple parts, to be played in sequence.</p>\n","type":"p5.Part","optional":true,"multiple":true}]},"p5.SoundLoop":{"name":"p5.SoundLoop","shortname":"p5.SoundLoop","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9673,"description":"<p>SoundLoop</p>\n","is_constructor":1,"params":[{"name":"callback","description":"<p>this function will be called on each iteration of theloop</p>\n","type":"Function"},{"name":"interval","description":"<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n","type":"Number|String","optional":true}],"example":["\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"]},"p5.Compressor":{"name":"p5.Compressor","shortname":"p5.Compressor","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10036,"description":"<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect"},"p5.PeakDetect":{"name":"p5.PeakDetect","shortname":"p5.PeakDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10312,"description":"<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>","is_constructor":1,"params":[{"name":"freq1","description":"<p>lowFrequency - defaults to 20Hz</p>\n","type":"Number","optional":true},{"name":"freq2","description":"<p>highFrequency - defaults to 20000 Hz</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n","type":"Number","optional":true},{"name":"framesPerPeak","description":"<p>Defaults to 20.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"]},"p5.SoundRecorder":{"name":"p5.SoundRecorder","shortname":"p5.SoundRecorder","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10559,"description":"<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>","is_constructor":1,"example":["\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"]},"p5.Distortion":{"name":"p5.Distortion","shortname":"p5.Distortion","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10816,"description":"<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}]},"p5.Gain":{"name":"p5.Gain","shortname":"p5.Gain","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10973,"description":"<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n","is_constructor":1,"example":["\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"]},"p5.AudioVoice":{"name":"p5.AudioVoice","shortname":"p5.AudioVoice","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11149,"description":"<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n","is_constructor":1},"p5.MonoSynth":{"name":"p5.MonoSynth","shortname":"p5.MonoSynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11247,"description":"<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n","is_constructor":1,"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"]},"p5.OnsetDetect":{"name":"p5.OnsetDetect","shortname":"p5.OnsetDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11624,"description":"<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n","is_constructor":1,"params":[{"name":"freqLow","description":"<p>Low frequency</p>\n","type":"Number"},{"name":"freqHigh","description":"<p>High frequency</p>\n","type":"Number"},{"name":"threshold","description":"<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n","type":"Number"},{"name":"callback","description":"<p>Function to call when an onset is detected</p>\n","type":"Function"}]},"p5.PolySynth":{"name":"p5.PolySynth","shortname":"p5.PolySynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n","is_constructor":1,"params":[{"name":"synthVoice","description":"<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n","type":"Number","optional":true},{"name":"maxVoices","description":"<p>Number of voices, defaults to 8;</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"]}},"elements":{},"classitems":[{"file":"src/accessibility/describe.js","line":18,"description":"<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n","itemtype":"method","name":"describe","params":[{"name":"text","description":"<p>description of the canvas</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/describe.js","line":114,"description":"<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n","itemtype":"method","name":"describeElement","params":[{"name":"name","description":"<p>name of the element</p>\n","type":"String"},{"name":"text","description":"<p>description of the element</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":10,"description":"<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"textOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":88,"description":"<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"gridOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/color/color_conversion.js","line":8,"description":"<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":19,"description":"<p>Convert an HSBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":45,"description":"<p>Convert an HSBA array to RGBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":100,"description":"<p>Convert an HSLA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":123,"description":"<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":187,"description":"<p>Convert an RGBA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":226,"description":"<p>Convert an RGBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/creating_reading.js","line":16,"description":"<p>Extracts the alpha value from a color or pixel array.</p>\n","itemtype":"method","name":"alpha","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the alpha value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":43,"description":"<p>Extracts the blue value from a color or pixel array.</p>\n","itemtype":"method","name":"blue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the blue value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":69,"description":"<p>Extracts the HSB brightness value from a color or pixel array.</p>\n","itemtype":"method","name":"brightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the brightness value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":113,"description":"<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n","itemtype":"method","name":"color","return":{"description":"resulting color","type":"p5.Color"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading","overloads":[{"line":113,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"return":{"description":"resulting color","type":"p5.Color"}},{"line":257,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"return":{"description":"","type":"p5.Color"}},{"line":269,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"return":{"description":"","type":"p5.Color"}},{"line":275,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"return":{"description":"","type":"p5.Color"}},{"line":282,"params":[{"name":"color","description":"","type":"p5.Color"}],"return":{"description":"","type":"p5.Color"}}]},{"file":"src/color/creating_reading.js","line":297,"description":"<p>Extracts the green value from a color or pixel array.</p>\n","itemtype":"method","name":"green","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the green value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":325,"description":"<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n","itemtype":"method","name":"hue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the hue","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":359,"description":"<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n","itemtype":"method","name":"lerpColor","params":[{"name":"c1","description":"<p>interpolate from this color</p>\n","type":"p5.Color"},{"name":"c2","description":"<p>interpolate to this color</p>\n","type":"p5.Color"},{"name":"amt","description":"<p>number between 0 and 1</p>\n","type":"Number"}],"return":{"description":"interpolated color","type":"p5.Color"},"example":["\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":449,"description":"<p>Extracts the HSL lightness value from a color or pixel array.</p>\n","itemtype":"method","name":"lightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the lightness","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":478,"description":"<p>Extracts the red value from a color or pixel array.</p>\n","itemtype":"method","name":"red","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the red value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":517,"description":"<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n","itemtype":"method","name":"saturation","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the saturation value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":51,"description":"<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n","itemtype":"method","name":"toString","params":[{"name":"format","description":"<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n","type":"String","optional":true}],"return":{"description":"the formatted string","type":"String"},"example":["\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":254,"description":"<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setRed","params":[{"name":"red","description":"<p>the new red value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":281,"description":"<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setGreen","params":[{"name":"green","description":"<p>the new green value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":304,"description":"<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setBlue","params":[{"name":"blue","description":"<p>the new blue value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":327,"description":"<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setAlpha","params":[{"name":"alpha","description":"<p>the new alpha value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":396,"description":"<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":427,"description":"<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":446,"description":"<p>CSS named colors.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":600,"description":"<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":613,"description":"<p>Full color string patterns. The capture groups are necessary.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":960,"description":"<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/setting.js","line":13,"description":"<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n","itemtype":"method","name":"background","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":13,"params":[{"name":"color","description":"<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n","type":"p5.Color"}],"chainable":1},{"line":130,"params":[{"name":"colorstring","description":"<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n","type":"String"},{"name":"a","description":"<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":140,"params":[{"name":"gray","description":"<p>specifies a value between white and black</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":147,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current color\n                       mode)</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":159,"params":[{"name":"values","description":"<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":166,"params":[{"name":"image","description":"<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n","type":"p5.Image"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":179,"description":"<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n","itemtype":"method","name":"clear","chainable":1,"example":["\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"],"params":[{"name":"r","description":"<p>normalized red val.</p>\n","type":"Number"},{"name":"g","description":"<p>normalized green val.</p>\n","type":"Number"},{"name":"b","description":"<p>normalized blue val.</p>\n","type":"Number"},{"name":"a","description":"<p>normalized alpha val.</p>\n","type":"Number"}],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":229,"description":"<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n","itemtype":"method","name":"colorMode","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":229,"params":[{"name":"mode","description":"<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n","type":"Constant"},{"name":"max","description":"<p>range for all values</p>\n","type":"Number","optional":true}],"chainable":1},{"line":306,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"max1","description":"<p>range for the red or hue depending on the\n                             current color mode</p>\n","type":"Number"},{"name":"max2","description":"<p>range for the green or saturation depending\n                             on the current color mode</p>\n","type":"Number"},{"name":"max3","description":"<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n","type":"Number"},{"name":"maxA","description":"<p>range for the alpha</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":350,"description":"<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n","itemtype":"method","name":"fill","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":350,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":475,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":481,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":488,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":495,"params":[{"name":"color","description":"<p>the fill color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":507,"description":"<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noFill","chainable":1,"example":["\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":547,"description":"<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noStroke","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":585,"description":"<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n","itemtype":"method","name":"stroke","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":585,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":722,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":728,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":735,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":742,"params":[{"name":"color","description":"<p>the stroke color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":755,"description":"<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n","itemtype":"method","name":"erase","params":[{"name":"strengthFill","description":"<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true},{"name":"strengthStroke","description":"<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":836,"description":"<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n","itemtype":"method","name":"noErase","chainable":1,"example":["\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/core/friendly_errors/fes_core.js","line":1,"requires":["core\n\nThis is the main file for the Friendly Error System (FES)","containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters","(2) _friendlyFileLoadError","(3) _friendlyError","(4) helpForMisusedAtTopLevelCode","or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this","there's also a file stacktrace.js","which contains the code\nto parse the error stack","borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions","including the call\nsequence of each function","please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/fes_core.js","line":915,"description":"<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n","class":"p5","module":"Color"},{"file":"src/core/friendly_errors/file_errors.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/sketch_reader.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/stacktrace.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/validate_params.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/shape/2d_primitives.js","line":16,"description":"<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n","class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":102,"description":"<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n","itemtype":"method","name":"arc","params":[{"name":"x","description":"<p>x-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"w","description":"<p>width of the arc's ellipse by default</p>\n","type":"Number"},{"name":"h","description":"<p>height of the arc's ellipse by default</p>\n","type":"Number"},{"name":"start","description":"<p>angle to start the arc, specified in radians</p>\n","type":"Number"},{"name":"stop","description":"<p>angle to stop the arc, specified in radians</p>\n","type":"Number"},{"name":"mode","description":"<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n","type":"Constant","optional":true},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":235,"description":"<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n","itemtype":"method","name":"ellipse","chainable":1,"example":["\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":235,"params":[{"name":"x","description":"<p>x-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the ellipse.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the ellipse.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":261,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}]}]},{"file":"src/core/shape/2d_primitives.js","line":277,"description":"<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n","itemtype":"method","name":"circle","params":[{"name":"x","description":"<p>x-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"d","description":"<p>diameter of the circle.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":340,"description":"<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n","itemtype":"method","name":"line","chainable":1,"example":["\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":340,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"}],"chainable":1},{"line":379,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":404,"description":"<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n","itemtype":"method","name":"point","chainable":1,"example":["\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":404,"params":[{"name":"x","description":"<p>the x-coordinate</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate</p>\n","type":"Number"},{"name":"z","description":"<p>the z-coordinate (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":455,"params":[{"name":"coordinate_vector","description":"<p>the coordinate vector</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":483,"description":"<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n","itemtype":"method","name":"quad","chainable":1,"example":["\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":483,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>the x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>the y-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"<p>the x-coordinate of the fourth point</p>\n","type":"Number"},{"name":"y4","description":"<p>the y-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction</p>\n","type":"Integer","optional":true}],"chainable":1},{"line":512,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>the z-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>the z-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"","type":"Integer","optional":true},{"name":"detailY","description":"","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":556,"description":"<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"rect","chainable":1,"example":["\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":556,"params":[{"name":"x","description":"<p>x-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the rectangle.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the rectangle.</p>\n","type":"Number","optional":true},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":608,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction (for WebGL mode)</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction (for WebGL mode)</p>\n","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":623,"description":"<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"square","params":[{"name":"x","description":"<p>x-coordinate of the square.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the square.</p>\n","type":"Number"},{"name":"s","description":"<p>side size of the square.</p>\n","type":"Number"},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":713,"description":"<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n","itemtype":"method","name":"triangle","params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate of the third point</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/attributes.js","line":12,"description":"<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"ellipseMode","params":[{"name":"mode","description":"<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"],"alt":"60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":81,"description":"<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"noSmooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses to left & right of center, black background","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":115,"description":"<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"rectMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"],"alt":"50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":184,"description":"<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"smooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses one left one right of center. On black.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":219,"description":"<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeCap","params":[{"name":"cap","description":"<p>either ROUND, SQUARE or PROJECT</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"],"alt":"3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":259,"description":"<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeJoin","params":[{"name":"join","description":"<p>either MITER, BEVEL, ROUND</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"],"alt":"Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":331,"description":"<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n","itemtype":"method","name":"strokeWeight","params":[{"name":"weight","description":"<p>the weight of the stroke (in pixels)</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"],"alt":"3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/curves.js","line":13,"description":"<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n","itemtype":"method","name":"bezier","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"],"alt":"stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":13,"params":[{"name":"x1","description":"<p>x-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the second anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1},{"line":62,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":92,"description":"<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n","itemtype":"method","name":"bezierDetail","params":[{"name":"detail","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"],"alt":"stretched black s-shape with a low level of bezier detail","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":130,"description":"<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n","itemtype":"method","name":"bezierPoint","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the value of the Bezier at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"],"alt":"10 points plotted on a given bezier at equal distances.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":185,"description":"<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n","itemtype":"method","name":"bezierTangent","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":264,"description":"<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n","itemtype":"method","name":"curve","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"],"alt":"horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":264,"params":[{"name":"x1","description":"<p>x-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the ending control point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1},{"line":332,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":358,"description":"<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n","itemtype":"method","name":"curveDetail","params":[{"name":"resolution","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"],"alt":"white arch shape with a low level of curve detail.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":398,"description":"<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n","itemtype":"method","name":"curveTightness","params":[{"name":"amount","description":"<p>amount of deformation from the original vertices</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"],"alt":"Line shaped like right-facing arrow,points move with mouse-x and warp shape.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":444,"description":"<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n","itemtype":"method","name":"curvePoint","params":[{"name":"a","description":"<p>coordinate of first control point of the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"bezier value at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"],"class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":493,"description":"<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n","itemtype":"method","name":"curveTangent","params":[{"name":"a","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second conrol point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"right curving line mid-right of canvas with 7 short lines radiating from it.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/vertex.js","line":20,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"beginContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":67,"description":"<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"beginShape","params":[{"name":"kind","description":"<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":293,"description":"<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"bezierVertex","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"],"alt":"crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":293,"params":[{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":375,"params":[{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":415,"description":"<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n","itemtype":"method","name":"curveVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"],"alt":"Upside-down u-shape line, mid canvas. left point extends beyond canvas view.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":415,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":460,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":524,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"endContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":583,"description":"<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n","itemtype":"method","name":"endShape","params":[{"name":"mode","description":"<p>use CLOSE to close the shape</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"],"alt":"Triangle line shape with smallest interior angle on bottom and upside-down L.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":668,"description":"<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"quadraticVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"],"alt":"arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":668,"params":[{"name":"cx","description":"<p>x-coordinate for the control point</p>\n","type":"Number"},{"name":"cy","description":"<p>y-coordinate for the control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":733,"params":[{"name":"cx","description":"","type":"Number"},{"name":"cy","description":"","type":"Number"},{"name":"cz","description":"<p>z-coordinate for the control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":826,"description":"<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n","itemtype":"method","name":"vertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"],"alt":"4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":826,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":957,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n","type":"Number"}],"chainable":1},{"line":965,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true},{"name":"u","description":"<p>the vertex's texture u-coordinate</p>\n","type":"Number"},{"name":"v","description":"<p>the vertex's texture v-coordinate</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":1003,"description":"<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n","itemtype":"method","name":"normal","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":1003,"params":[{"name":"vector","description":"<p>A p5.Vector representing the vertex normal.</p>\n","type":"Vector"}],"chainable":1},{"line":1040,"params":[{"name":"x","description":"<p>The x component of the vertex normal.</p>\n","type":"Number"},{"name":"y","description":"<p>The y component of the vertex normal.</p>\n","type":"Number"},{"name":"z","description":"<p>The z component of the vertex normal.</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/constants.js","line":9,"description":"<p>Version of this p5.js.</p>\n","itemtype":"property","name":"VERSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":18,"description":"<p>The default, two-dimensional renderer.</p>\n","itemtype":"property","name":"P2D","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":24,"description":"<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n","itemtype":"property","name":"WEBGL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":33,"itemtype":"property","name":"ARROW","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":38,"itemtype":"property","name":"CROSS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":43,"itemtype":"property","name":"HAND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":48,"itemtype":"property","name":"MOVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":53,"itemtype":"property","name":"TEXT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":58,"itemtype":"property","name":"WAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":66,"description":"<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"HALF_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"],"alt":"80×80 white quarter-circle with curve toward bottom right of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":84,"description":"<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"],"alt":"white half-circle with curve toward bottom of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":102,"description":"<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"QUARTER_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"],"alt":"white eighth-circle rotated about 40 degrees with curve bottom right canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":120,"description":"<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TAU","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":138,"description":"<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TWO_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":156,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n","itemtype":"property","name":"DEGREES","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":170,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n","itemtype":"property","name":"RADIANS","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":188,"itemtype":"property","name":"CORNER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":193,"itemtype":"property","name":"CORNERS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":198,"itemtype":"property","name":"RADIUS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":203,"itemtype":"property","name":"RIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":208,"itemtype":"property","name":"LEFT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":213,"itemtype":"property","name":"CENTER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":218,"itemtype":"property","name":"TOP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":223,"itemtype":"property","name":"BOTTOM","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":228,"itemtype":"property","name":"BASELINE","type":"String","final":1,"default":"alphabetic","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":234,"itemtype":"property","name":"POINTS","type":"Number","final":1,"default":"0x0000","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":240,"itemtype":"property","name":"LINES","type":"Number","final":1,"default":"0x0001","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":246,"itemtype":"property","name":"LINE_STRIP","type":"Number","final":1,"default":"0x0003","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":252,"itemtype":"property","name":"LINE_LOOP","type":"Number","final":1,"default":"0x0002","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":258,"itemtype":"property","name":"TRIANGLES","type":"Number","final":1,"default":"0x0004","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":264,"itemtype":"property","name":"TRIANGLE_FAN","type":"Number","final":1,"default":"0x0006","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":270,"itemtype":"property","name":"TRIANGLE_STRIP","type":"Number","final":1,"default":"0x0005","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":276,"itemtype":"property","name":"QUADS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":281,"itemtype":"property","name":"QUAD_STRIP","type":"String","final":1,"default":"quad_strip","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":287,"itemtype":"property","name":"TESS","type":"String","final":1,"default":"tess","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":293,"itemtype":"property","name":"CLOSE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":298,"itemtype":"property","name":"OPEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":303,"itemtype":"property","name":"CHORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":308,"itemtype":"property","name":"PIE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":313,"itemtype":"property","name":"PROJECT","type":"String","final":1,"default":"square","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":319,"itemtype":"property","name":"SQUARE","type":"String","final":1,"default":"butt","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":325,"itemtype":"property","name":"ROUND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":330,"itemtype":"property","name":"BEVEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":335,"itemtype":"property","name":"MITER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":342,"itemtype":"property","name":"RGB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":347,"description":"<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n","itemtype":"property","name":"HSB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":356,"itemtype":"property","name":"HSL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":363,"description":"<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n","itemtype":"property","name":"AUTO","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":373,"itemtype":"property","name":"ALT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":379,"itemtype":"property","name":"BACKSPACE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":384,"itemtype":"property","name":"CONTROL","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":389,"itemtype":"property","name":"DELETE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":394,"itemtype":"property","name":"DOWN_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":399,"itemtype":"property","name":"ENTER","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":404,"itemtype":"property","name":"ESCAPE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":409,"itemtype":"property","name":"LEFT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":414,"itemtype":"property","name":"OPTION","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":419,"itemtype":"property","name":"RETURN","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":424,"itemtype":"property","name":"RIGHT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":429,"itemtype":"property","name":"SHIFT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":434,"itemtype":"property","name":"TAB","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":439,"itemtype":"property","name":"UP_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":446,"itemtype":"property","name":"BLEND","type":"String","final":1,"default":"source-over","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":452,"itemtype":"property","name":"REMOVE","type":"String","final":1,"default":"destination-out","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":458,"itemtype":"property","name":"ADD","type":"String","final":1,"default":"lighter","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":466,"itemtype":"property","name":"DARKEST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":471,"itemtype":"property","name":"LIGHTEST","type":"String","final":1,"default":"lighten","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":477,"itemtype":"property","name":"DIFFERENCE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":482,"itemtype":"property","name":"SUBTRACT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":487,"itemtype":"property","name":"EXCLUSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":492,"itemtype":"property","name":"MULTIPLY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":497,"itemtype":"property","name":"SCREEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":502,"itemtype":"property","name":"REPLACE","type":"String","final":1,"default":"copy","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":508,"itemtype":"property","name":"OVERLAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":513,"itemtype":"property","name":"HARD_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":518,"itemtype":"property","name":"SOFT_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":523,"itemtype":"property","name":"DODGE","type":"String","final":1,"default":"color-dodge","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":529,"itemtype":"property","name":"BURN","type":"String","final":1,"default":"color-burn","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":537,"itemtype":"property","name":"THRESHOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":542,"itemtype":"property","name":"GRAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":547,"itemtype":"property","name":"OPAQUE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":552,"itemtype":"property","name":"INVERT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":557,"itemtype":"property","name":"POSTERIZE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":562,"itemtype":"property","name":"DILATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":567,"itemtype":"property","name":"ERODE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":572,"itemtype":"property","name":"BLUR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":579,"itemtype":"property","name":"NORMAL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":584,"itemtype":"property","name":"ITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":589,"itemtype":"property","name":"BOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":594,"itemtype":"property","name":"BOLDITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":599,"itemtype":"property","name":"CHAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":604,"itemtype":"property","name":"WORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":616,"itemtype":"property","name":"LINEAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":621,"itemtype":"property","name":"QUADRATIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":626,"itemtype":"property","name":"BEZIER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":631,"itemtype":"property","name":"CURVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":638,"itemtype":"property","name":"STROKE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":643,"itemtype":"property","name":"FILL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":648,"itemtype":"property","name":"TEXTURE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":653,"itemtype":"property","name":"IMMEDIATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":661,"itemtype":"property","name":"IMAGE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":669,"itemtype":"property","name":"NEAREST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":674,"itemtype":"property","name":"REPEAT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":679,"itemtype":"property","name":"CLAMP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":684,"itemtype":"property","name":"MIRROR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":691,"itemtype":"property","name":"LANDSCAPE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":696,"itemtype":"property","name":"PORTRAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":706,"itemtype":"property","name":"GRID","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":712,"itemtype":"property","name":"AXES","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":718,"itemtype":"property","name":"LABEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":723,"itemtype":"property","name":"FALLBACK","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/environment.js","line":20,"description":"<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n","itemtype":"method","name":"print","params":[{"name":"contents","description":"<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n","type":"Any"}],"example":["\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"],"alt":"default grey canvas","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":52,"description":"<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n","itemtype":"property","name":"frameCount","type":"Integer","readonly":"","example":["\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"],"alt":"numbers rapidly counting upward with frame count set to 30.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":79,"description":"<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n","itemtype":"property","name":"deltaTime","type":"Integer","readonly":"","example":["\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":129,"description":"<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n","itemtype":"property","name":"focused","type":"Boolean","readonly":"","example":["\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"],"alt":"green 50×50 ellipse at top left. Red X covers canvas when page focus changes","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":160,"description":"<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n","itemtype":"method","name":"cursor","params":[{"name":"type","description":"<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n","type":"String|Constant"},{"name":"x","description":"<p>the horizontal active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the vertical active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"],"alt":"canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":228,"description":"<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n","itemtype":"method","name":"frameRate","chainable":1,"example":["\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"blue rect moves left to right, followed by red rect moving faster. Loops.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":228,"params":[{"name":"fps","description":"<p>number of frames to be displayed every second</p>\n","type":"Number"}],"chainable":1},{"line":288,"params":[],"return":{"description":"current frameRate","type":"Number"}}]},{"file":"src/core/environment.js","line":331,"description":"<p>Hides the cursor from view.</p>\n","itemtype":"method","name":"noCursor","example":["\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"],"alt":"cursor becomes 10×10 white ellipse the moves with mouse x and y.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":354,"description":"<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":372,"description":"<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":390,"description":"<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n","itemtype":"property","name":"windowWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":405,"description":"<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n","itemtype":"property","name":"windowHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":421,"description":"<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n","itemtype":"method","name":"windowResized","params":[{"name":"event","description":"<p>optional Event callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":476,"description":"<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":488,"description":"<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":500,"description":"<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n","itemtype":"method","name":"fullscreen","params":[{"name":"val","description":"<p>whether the sketch should be in fullscreen mode\nor not</p>\n","type":"Boolean","optional":true}],"return":{"description":"current fullscreen state","type":"Boolean"},"example":["\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":550,"description":"<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n","itemtype":"method","name":"pixelDensity","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":550,"params":[{"name":"val","description":"<p>whether or how much the sketch should scale</p>\n","type":"Number"}],"chainable":1},{"line":586,"params":[],"return":{"description":"current pixel density of the sketch","type":"Number"}}]},{"file":"src/core/environment.js","line":605,"description":"<p>Returns the pixel density of the current display the sketch is running on.</p>\n","itemtype":"method","name":"displayDensity","return":{"description":"current pixel density of the display","type":"Number"},"example":["\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":660,"description":"<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURL","return":{"description":"url","type":"String"},"example":["\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"],"alt":"current url (http://p5js.org/reference/#/p5/getURL) moves right to left.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":691,"description":"<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLPath","return":{"description":"path components","type":"String[]"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":713,"description":"<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLParams","return":{"description":"URL params","type":"Object"},"example":["\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/helpers.js","line":1,"requires":["constants"],"class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":30,"description":"<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":126,"description":"<p>Set up our translation function, with loaded languages</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":171,"description":"<p>Returns a list of languages we have translations loaded for</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":178,"description":"<p>Returns the current language selected for translation</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":185,"description":"<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/legacy.js","line":1,"requires":["core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name","in others","they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."],"class":"p5","module":"Environment"},{"file":"src/core/main.js","line":42,"description":"<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n","itemtype":"method","name":"preload","example":["\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":83,"description":"<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n","itemtype":"method","name":"setup","example":["\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":114,"description":"<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n","itemtype":"method","name":"draw","example":["\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":415,"description":"<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":693,"description":"<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n","itemtype":"property","name":"disableFriendlyErrors","type":"Boolean","example":["\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"],"class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/p5.Element.js","line":21,"description":"<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"],"itemtype":"property","name":"elt","readonly":"","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":47,"description":"<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"parent","chainable":1,"example":["\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":47,"params":[{"name":"parent","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n","type":"String|p5.Element|Object"}],"chainable":1},{"line":93,"params":[],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/core/p5.Element.js","line":114,"description":"<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n","itemtype":"method","name":"id","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":114,"params":[{"name":"id","description":"<p>ID of the element</p>\n","type":"String"}],"chainable":1},{"line":139,"params":[],"return":{"description":"the id of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":154,"description":"<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n","itemtype":"method","name":"class","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":154,"params":[{"name":"class","description":"<p>class to add</p>\n","type":"String"}],"chainable":1},{"line":176,"params":[],"return":{"description":"the class of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":189,"description":"<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":246,"description":"<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"return":{"description":"","type":"p5.Element"},"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":292,"description":"<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":354,"description":"<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":403,"description":"<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":454,"description":"<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":510,"description":"<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOver","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":551,"description":"<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOut","params":[{"name":"fxn","description":"<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":592,"description":"<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"fxn","description":"<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":639,"description":"<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"fxn","description":"<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":678,"description":"<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"fxn","description":"<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":725,"description":"<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragOver","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":763,"description":"<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragLeave","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":827,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Graphics.js","line":70,"description":"<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n","itemtype":"method","name":"reset","example":["\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"],"alt":"A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Graphics.js","line":122,"description":"<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"],"alt":"no image\na multi-colored circle moving back and forth over a scrolling background.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":99,"description":"<p>Resize our canvas element.</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":415,"description":"<p>Helper function to check font type (system or otf)</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":467,"description":"<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":7,"description":"<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":402,"description":"<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/reference.js","line":7,"description":"<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n","itemtype":"property","name":"let","example":["\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":34,"description":"<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n","itemtype":"property","name":"const","example":["\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"],"alt":"These examples do not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":87,"description":"<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n","itemtype":"property","name":"===","example":["\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":115,"description":"<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>","itemtype":"property","name":">","example":["\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":137,"description":"<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":">=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":158,"description":"<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<","example":["\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":179,"description":"<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":200,"description":"<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n","itemtype":"property","name":"if-else","example":["\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":231,"description":"<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n","itemtype":"property","name":"function","example":["\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":267,"description":"<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n","itemtype":"property","name":"return","example":["\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":288,"description":"<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n","itemtype":"property","name":"boolean","example":["\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":309,"description":"<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n","itemtype":"property","name":"string","example":["\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":331,"description":"<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n","itemtype":"property","name":"number","example":["\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":351,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n","itemtype":"property","name":"object","example":["\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":379,"description":"<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n","itemtype":"property","name":"class","example":["\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":408,"description":"<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n","itemtype":"property","name":"for","example":["\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":448,"description":"<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n","itemtype":"property","name":"while","example":["\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":490,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n","itemtype":"method","name":"stringify","static":1,"params":[{"name":"object","description":"<p>:Javascript object that you would like to convert to JSON</p>\n","type":"Object"}],"example":["\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"JSON","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":512,"description":"<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n","itemtype":"method","name":"log","static":1,"params":[{"name":"message","description":"<p>:Message that you would like to print to the console</p>\n","type":"String|Expression|Object"}],"example":["\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"console","module":"Foundation","submodule":"Foundation"},{"file":"src/core/rendering.js","line":15,"description":"<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"createCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL</p>\n","type":"Constant","optional":true}],"return":{"description":"","type":"p5.Renderer"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"],"alt":"Black line extending from top-left of canvas to bottom right.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":125,"description":"<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n","itemtype":"method","name":"resizeCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"noRedraw","description":"<p>don't redraw the canvas immediately</p>\n","type":"Boolean","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"No image displayed.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":183,"description":"<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n","itemtype":"method","name":"noCanvas","example":["\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":204,"description":"<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n","itemtype":"method","name":"createGraphics","params":[{"name":"w","description":"<p>width of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"h","description":"<p>height of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n","type":"Constant","optional":true}],"return":{"description":"offscreen graphics buffer","type":"p5.Graphics"},"example":["\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"4 grey squares alternating light and dark grey. White quarter circle mid-left.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":243,"description":"<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n","itemtype":"method","name":"blendMode","params":[{"name":"mode","description":"<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"],"alt":"translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":326,"description":"<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n","itemtype":"property","name":"drawingContext","example":["\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"white ellipse with shadow blur effect around edges","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/shim.js","line":18,"description":"<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/shim.js","line":39,"description":"<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n","class":"p5","module":"Rendering"},{"file":"src/core/structure.js","line":10,"description":"<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"noLoop","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"],"alt":"113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":83,"description":"<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"loop","example":["\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"],"alt":"horizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":134,"description":"<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n","itemtype":"method","name":"isLooping","example":["\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"],"alt":"Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":192,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"push","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":290,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"pop","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":391,"description":"<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n","itemtype":"method","name":"redraw","params":[{"name":"n","description":"<p>Redraw for n-times. The default value is 1.</p>\n","type":"Integer","optional":true}],"example":["\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"],"alt":"black line on far left of canvas\nblack line on far left of canvas","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":497,"description":"<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n","itemtype":"method","name":"p5","params":[{"name":"sketch","description":"<p>a function containing a p5.js sketch</p>\n","type":"Object"},{"name":"node","description":"<p>ID or pointer to HTML DOM node to contain sketch in</p>\n","type":"String|Object"}],"example":["\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"],"alt":"white rectangle on black background","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/transform.js","line":11,"description":"<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n","itemtype":"method","name":"applyMatrix","params":[{"name":"a","description":"<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n","type":"Number|Array"},{"name":"b","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"c","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"d","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"e","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"f","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":168,"description":"<p>Replaces the current matrix with the identity matrix.</p>\n","itemtype":"method","name":"resetMatrix","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"],"alt":"A rotated rectangle in the center with another at the top left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":193,"description":"<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"rotate","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"},{"name":"axis","description":"<p>(in 3d) the axis to rotate around</p>\n","type":"p5.Vector|Number[]","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":232,"description":"<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateX","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the x axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":268,"description":"<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateY","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the y axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":304,"description":"<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateZ","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the z axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":342,"description":"<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"scale","chainable":1,"example":["\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":342,"params":[{"name":"s","description":"<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n","type":"Number|p5.Vector|Number[]"},{"name":"y","description":"<p>percent to scale the object in the y-axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>percent to scale the object in the z-axis (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":386,"params":[{"name":"scales","description":"<p>per-axis percents to scale the object</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/core/transform.js","line":416,"description":"<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearX","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at top middle.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":455,"description":"<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearY","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at middle bottom.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":494,"description":"<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"translate","chainable":1,"example":["\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"],"alt":"white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":494,"params":[{"name":"x","description":"<p>left/right translation</p>\n","type":"Number"},{"name":"y","description":"<p>up/down translation</p>\n","type":"Number"},{"name":"z","description":"<p>forward/backward translation (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":547,"params":[{"name":"vector","description":"<p>the vector to translate by</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/data/local_storage.js","line":10,"description":"<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n","itemtype":"method","name":"storeItem","params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String|Number|Object|Boolean|p5.Color|p5.Vector"}],"example":["\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"],"alt":"When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":101,"description":"<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n","itemtype":"method","name":"getItem","params":[{"name":"key","description":"<p>name that you wish to use to store in local storage</p>\n","type":"String"}],"return":{"description":"Value of stored item","type":"Number|Object|String|Boolean|p5.Color|p5.Vector"},"example":["\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"],"alt":"If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":177,"description":"<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n","itemtype":"method","name":"clearStorage","example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":205,"description":"<p>Removes an item that was stored with storeItem()</p>\n","itemtype":"method","name":"removeItem","params":[{"name":"key","description":"","type":"String"}],"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/p5.TypedDict.js","line":14,"description":"<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n","itemtype":"method","name":"createStringDict","return":{"description":"","type":"p5.StringDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":14,"params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String"}],"return":{"description":"","type":"p5.StringDict"}},{"line":37,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.StringDict"}}]},{"file":"src/data/p5.TypedDict.js","line":48,"description":"<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n","itemtype":"method","name":"createNumberDict","return":{"description":"","type":"p5.NumberDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":48,"params":[{"name":"key","description":"","type":"Number"},{"name":"value","description":"","type":"Number"}],"return":{"description":"","type":"p5.NumberDict"}},{"line":71,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.NumberDict"}}]},{"file":"src/data/p5.TypedDict.js","line":101,"description":"<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n","itemtype":"method","name":"size","return":{"description":"the number of key-value pairs in the Dictionary","type":"Integer"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":122,"description":"<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n","itemtype":"method","name":"hasKey","params":[{"name":"key","description":"<p>that you want to look up</p>\n","type":"Number|String"}],"return":{"description":"whether that key exists in Dictionary","type":"Boolean"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":144,"description":"<p>Returns the value stored at the given key.</p>\n","itemtype":"method","name":"get","params":[{"name":"the","description":"<p>key you want to access</p>\n","type":"Number|String"}],"return":{"description":"the value stored at that key","type":"Number|String"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":170,"description":"<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n","itemtype":"method","name":"set","params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":197,"description":"<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":208,"description":"<p>Creates a new key-value pair in the Dictionary.</p>\n","itemtype":"method","name":"create","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary","overloads":[{"line":208,"params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}]},{"line":226,"params":[{"name":"obj","description":"<p>key/value pair</p>\n","type":"Object"}]}]},{"file":"src/data/p5.TypedDict.js","line":244,"description":"<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n","itemtype":"method","name":"clear","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":265,"description":"<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n","itemtype":"method","name":"remove","params":[{"name":"key","description":"<p>for the pair to remove</p>\n","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":294,"description":"<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n","itemtype":"method","name":"print","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":318,"description":"<p>Converts the Dictionary into a CSV file for local download.</p>\n","itemtype":"method","name":"saveTable","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":356,"description":"<p>Converts the Dictionary into a JSON file for local download.</p>\n","itemtype":"method","name":"saveJSON","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":387,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":425,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":432,"description":"<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"add","params":[{"name":"Key","description":"<p>for the value you wish to add to</p>\n","type":"Number"},{"name":"Number","description":"<p>to add to the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":459,"description":"<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"sub","params":[{"name":"Key","description":"<p>for the value you wish to subtract from</p>\n","type":"Number"},{"name":"Number","description":"<p>to subtract from the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":482,"description":"<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"mult","params":[{"name":"Key","description":"<p>for value you wish to multiply</p>\n","type":"Number"},{"name":"Amount","description":"<p>to multiply the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":509,"description":"<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"div","params":[{"name":"Key","description":"<p>for value you wish to divide</p>\n","type":"Number"},{"name":"Amount","description":"<p>to divide the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":536,"description":"<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":560,"description":"<p>Return the lowest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"minValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":580,"description":"<p>Return the highest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"maxValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":600,"description":"<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":622,"description":"<p>Return the lowest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"minKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":642,"description":"<p>Return the highest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"maxKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/dom/dom.js","line":21,"description":"<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n","itemtype":"method","name":"select","params":[{"name":"selectors","description":"<p>CSS selector string of element to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"<a href=\"#/p5.Element\">p5.Element</a> containing node found","type":"p5.Element|null"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":68,"description":"<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n","itemtype":"method","name":"selectAll","params":[{"name":"selectors","description":"<p>CSS selector string of elements to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found","type":"p5.Element[]"},"example":["\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":127,"description":"<p>Helper function for select and selectAll</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":142,"description":"<p>Helper function for getElement and getElements.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":176,"description":"<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n","itemtype":"method","name":"removeElements","example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":204,"description":"<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n","itemtype":"method","name":"changed","params":[{"name":"fxn","description":"<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"],"alt":"dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":271,"description":"<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n","itemtype":"method","name":"input","params":[{"name":"fxn","description":"<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"alt":"no display.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":309,"description":"<p>Helpers for create methods.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":322,"description":"<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createDiv","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":341,"description":"<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n","itemtype":"method","name":"createP","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":361,"description":"<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createSpan","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":379,"description":"<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n","itemtype":"method","name":"createImg","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":379,"params":[{"name":"src","description":"<p>src path or url for image</p>\n","type":"String"},{"name":"alt","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":396,"params":[{"name":"src","description":"","type":"String"},{"name":"alt","description":"","type":"String"},{"name":"crossOrigin","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n","type":"String"},{"name":"successCallback","description":"<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":426,"description":"<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n","itemtype":"method","name":"createA","params":[{"name":"href","description":"<p>url of page to link to</p>\n","type":"String"},{"name":"html","description":"<p>inner html of link element to display</p>\n","type":"String"},{"name":"target","description":"<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":450,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":452,"description":"<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n","itemtype":"method","name":"createSlider","params":[{"name":"min","description":"<p>minimum value of the slider</p>\n","type":"Number"},{"name":"max","description":"<p>maximum value of the slider</p>\n","type":"Number"},{"name":"value","description":"<p>default value of the slider</p>\n","type":"Number","optional":true},{"name":"step","description":"<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n","type":"Number","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":507,"description":"<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n","itemtype":"method","name":"createButton","params":[{"name":"label","description":"<p>label displayed on the button</p>\n","type":"String"},{"name":"value","description":"<p>value of the button</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":541,"description":"<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n","itemtype":"method","name":"createCheckbox","params":[{"name":"label","description":"<p>label displayed after checkbox</p>\n","type":"String","optional":true},{"name":"value","description":"<p>value of the checkbox; checked is true, unchecked is false</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":622,"description":"<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n","itemtype":"method","name":"createSelect","return":{"description":"","type":"p5.Element"},"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":622,"params":[{"name":"multiple","description":"<p>true if dropdown should support multiple selections</p>\n","type":"Boolean","optional":true}],"return":{"description":"","type":"p5.Element"}},{"line":673,"params":[{"name":"existing","description":"<p>DOM select element</p>\n","type":"Object"}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":770,"description":"<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n","itemtype":"method","name":"createRadio","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":770,"params":[{"name":"containerElement","description":"<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n","type":"Object"},{"name":"name","description":"<p>A name parameter for each Input Element.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":832,"params":[{"name":"name","description":"","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":837,"params":[],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":978,"description":"<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n","itemtype":"method","name":"createColorPicker","params":[{"name":"value","description":"<p>default color of element</p>\n","type":"String|p5.Color","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1066,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n","itemtype":"method","name":"createInput","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":1066,"params":[{"name":"value","description":"<p>default value of the input box</p>\n","type":"String"},{"name":"type","description":"<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":1091,"params":[{"name":"value","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":1104,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n","itemtype":"method","name":"createFileInput","params":[{"name":"callback","description":"<p>callback function for when a file is loaded</p>\n","type":"Function"},{"name":"multiple","description":"<p>optional, to allow multiple files to be selected</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element","type":"p5.Element"},"example":["\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1164,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1211,"description":"<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n","itemtype":"method","name":"createVideo","params":[{"name":"src","description":"<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n","type":"String|String[]"},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1257,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1259,"description":"<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n","itemtype":"method","name":"createAudio","params":[{"name":"src","description":"<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n","type":"String|String[]","optional":true},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1296,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1298,"itemtype":"property","name":"VIDEO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1304,"itemtype":"property","name":"AUDIO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1341,"description":"<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n","itemtype":"method","name":"createCapture","params":[{"name":"type","description":"<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n","type":"String|Constant|Object"},{"name":"callback","description":"<p>function to be called once\n                                  stream has loaded</p>\n","type":"Function","optional":true}],"return":{"description":"capture video <a href=\"#/p5.Element\">p5.Element</a>","type":"p5.Element"},"example":["\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1478,"description":"<p>Creates element with given tag in the DOM with given content.</p>\n","itemtype":"method","name":"createElement","params":[{"name":"tag","description":"<p>tag for the new element</p>\n","type":"String"},{"name":"content","description":"<p>html content to be inserted into the element</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1504,"description":"<p>Adds specified class to the element.</p>\n","itemtype":"method","name":"addClass","params":[{"name":"class","description":"<p>name of class to add</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1529,"description":"<p>Removes specified class from the element.</p>\n","itemtype":"method","name":"removeClass","params":[{"name":"class","description":"<p>name of class to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1560,"description":"<p>Checks if specified class already set to element</p>\n","itemtype":"method","name":"hasClass","return":{"description":"a boolean value if element has specified class","type":"Boolean"},"params":[{"name":"c","description":"<p>class name of class to check</p>\n","type":"String"}],"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1589,"description":"<p>Toggles element class</p>\n","itemtype":"method","name":"toggleClass","params":[{"name":"c","description":"<p>class name to toggle</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1622,"description":"<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n","itemtype":"method","name":"child","return":{"description":"an array of child nodes","type":"Node[]"},"example":["\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1622,"params":[],"return":{"description":"an array of child nodes","type":"Node[]"}},{"line":1650,"params":[{"name":"child","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n","type":"String|p5.Element","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1675,"description":"<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n","itemtype":"method","name":"center","params":[{"name":"align","description":"<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n","type":"String","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1726,"description":"<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n","itemtype":"method","name":"html","return":{"description":"the inner HTML of the element","type":"String"},"example":["\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1726,"params":[],"return":{"description":"the inner HTML of the element","type":"String"}},{"line":1747,"params":[{"name":"html","description":"<p>the HTML to be placed inside the element</p>\n","type":"String","optional":true},{"name":"append","description":"<p>whether to append HTML to existing</p>\n","type":"Boolean","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1765,"description":"<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n","itemtype":"method","name":"position","return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"},"example":["\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1765,"params":[],"return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"}},{"line":1798,"params":[{"name":"x","description":"<p>x-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"positionType","description":"<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n","type":"String","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1885,"description":"<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n","itemtype":"method","name":"style","return":{"description":"value of property","type":"String"},"example":["\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1885,"params":[{"name":"property","description":"<p>property to be set</p>\n","type":"String"}],"return":{"description":"value of property","type":"String"}},{"line":1923,"params":[{"name":"property","description":"","type":"String"},{"name":"value","description":"<p>value to assign to property</p>\n","type":"String|p5.Color"}],"chainable":1,"return":{"description":"current value of property, if no value is given as second argument","type":"String"}}]},{"file":"src/dom/dom.js","line":1980,"description":"<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n","itemtype":"method","name":"attribute","return":{"description":"value of attribute","type":"String"},"example":["\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1980,"params":[],"return":{"description":"value of attribute","type":"String"}},{"line":1995,"params":[{"name":"attr","description":"<p>attribute to set</p>\n","type":"String"},{"name":"value","description":"<p>value to assign to attribute</p>\n","type":"String"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2024,"description":"<p>Removes an attribute on the specified element.</p>\n","itemtype":"method","name":"removeAttribute","params":[{"name":"attr","description":"<p>attribute to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2069,"description":"<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n","itemtype":"method","name":"value","return":{"description":"value of the element","type":"String|Number"},"example":["\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2069,"params":[],"return":{"description":"value of the element","type":"String|Number"}},{"line":2099,"params":[{"name":"value","description":"","type":"String|Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2115,"description":"<p>Shows the current element. Essentially, setting display:block for the style.</p>\n","itemtype":"method","name":"show","chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2133,"description":"<p>Hides the current element. Essentially, setting display:none for the style.</p>\n","itemtype":"method","name":"hide","chainable":1,"example":["\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2149,"description":"<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n","itemtype":"method","name":"size","return":{"description":"the width and height of the element in an object","type":"Object"},"example":["\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2149,"params":[],"return":{"description":"the width and height of the element in an object","type":"Object"}},{"line":2173,"params":[{"name":"w","description":"<p>width of the element, either AUTO, or a number</p>\n","type":"Number|Constant"},{"name":"h","description":"<p>height of the element, either AUTO, or a number</p>\n","type":"Number|Constant","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":2230,"description":"<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2268,"description":"<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n","itemtype":"method","name":"drop","params":[{"name":"callback","description":"<p>callback to receive loaded file, called for each file dropped.</p>\n","type":"Function"},{"name":"fxn","description":"<p>callback triggered once when files are dropped with the drop event.</p>\n","type":"Function","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"],"alt":"Canvas turns into whatever image is dragged/dropped onto it.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2400,"description":"<p>Path to the media element source.</p>\n","itemtype":"property","name":"src","return":{"description":"src","type":"String"},"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2466,"description":"<p>Play an HTML5 media element.</p>\n","itemtype":"method","name":"play","chainable":1,"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2530,"description":"<p>Stops an HTML5 media element (sets current time to zero).</p>\n","itemtype":"method","name":"stop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2594,"description":"<p>Pauses an HTML5 media element.</p>\n","itemtype":"method","name":"pause","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2656,"description":"<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n","itemtype":"method","name":"loop","chainable":1,"example":["\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2712,"description":"<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n","itemtype":"method","name":"noLoop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2778,"description":"<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n","itemtype":"method","name":"autoplay","params":[{"name":"shouldAutoplay","description":"<p>whether the element should autoplay</p>\n","type":"Boolean"}],"chainable":1,"example":["\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"],"alt":"An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2845,"description":"<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n","itemtype":"method","name":"volume","return":{"description":"current volume","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2845,"params":[],"return":{"description":"current volume","type":"Number"}},{"line":2918,"params":[{"name":"val","description":"<p>volume between 0.0 and 1.0</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2931,"description":"<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n","itemtype":"method","name":"speed","return":{"description":"current playback speed of the element","type":"Number"},"example":["\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2931,"params":[],"return":{"description":"current playback speed of the element","type":"Number"}},{"line":3003,"params":[{"name":"speed","description":"<p>speed multiplier for element playback</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3020,"description":"<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n","itemtype":"method","name":"time","return":{"description":"current time (in seconds)","type":"Number"},"example":["\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":3020,"params":[],"return":{"description":"current time (in seconds)","type":"Number"}},{"line":3065,"params":[{"name":"time","description":"<p>time to jump to (in seconds)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3079,"description":"<p>Returns the duration of the HTML5 media element.</p>\n","itemtype":"method","name":"duration","return":{"description":"duration","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3201,"description":"<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n","type":"Function"}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3232,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3234,"description":"<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n","itemtype":"method","name":"connect","params":[{"name":"audioNode","description":"<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n","type":"AudioNode|Object"}],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3283,"description":"<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n","itemtype":"method","name":"disconnect","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3298,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3300,"description":"<p>Show the default MediaElement controls, as determined by the web browser.</p>\n","itemtype":"method","name":"showControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3331,"description":"<p>Hide the default mediaElement controls.</p>\n","itemtype":"method","name":"hideControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3360,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3371,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3434,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3476,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3542,"description":"<p>Underlying File object. All normal File methods can be called on this.</p>\n","itemtype":"property","name":"file","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3554,"description":"<p>File type (image, text, etc.)</p>\n","itemtype":"property","name":"type","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3560,"description":"<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n","itemtype":"property","name":"subtype","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3566,"description":"<p>File name</p>\n","itemtype":"property","name":"name","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3572,"description":"<p>File size</p>\n","itemtype":"property","name":"size","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3579,"description":"<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n","itemtype":"property","name":"data","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/events/acceleration.js","line":11,"description":"<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n","itemtype":"property","name":"deviceOrientation","type":"Constant","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":23,"description":"<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":46,"description":"<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":69,"description":"<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationZ","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":94,"description":"<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":104,"description":"<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":114,"description":"<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":135,"description":"<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationX","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":168,"description":"<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":201,"description":"<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"itemtype":"property","name":"rotationZ","type":"Number","readonly":"","alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":239,"description":"<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":285,"description":"<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":330,"description":"<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":389,"description":"<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n","itemtype":"property","name":"turnAxis","type":"String","readonly":"","example":["\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":428,"description":"<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n","itemtype":"method","name":"setMoveThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":471,"description":"<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n","itemtype":"method","name":"setShakeThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":515,"description":"<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n","itemtype":"method","name":"deviceMoved","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":546,"description":"<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n","itemtype":"method","name":"deviceTurned","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":604,"description":"<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n","itemtype":"method","name":"deviceShaken","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device shakes","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/keyboard.js","line":10,"description":"<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n","itemtype":"property","name":"keyIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white rect that turns black on keypress.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":36,"description":"<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n","itemtype":"property","name":"key","type":"String","readonly":"","example":["\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"],"alt":"canvas displays any key value that is pressed in pink font.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":64,"description":"<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n","itemtype":"property","name":"keyCode","type":"Integer","readonly":"","example":["\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"],"alt":"Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":103,"description":"<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyPressed","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":190,"description":"<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyReleased","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when pressed again","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":243,"description":"<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"keyTyped","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"],"alt":"black rect center. turns white when 'a' key typed and black when 'b' pressed","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":298,"description":"<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":308,"description":"<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n","itemtype":"method","name":"keyIsDown","params":[{"name":"code","description":"<p>The key to check for.</p>\n","type":"Number"}],"return":{"description":"whether key is down or not","type":"Boolean"},"example":["\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"],"alt":"50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/mouse.js","line":12,"description":"<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedX","type":"Number","readonly":"","example":["\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"],"alt":"box moves left and right according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":43,"description":"<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedY","type":"Number","readonly":"","example":["\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"box moves up and down according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":80,"description":"<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"],"alt":"horizontal black line moves left and right with mouse x-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":106,"description":"<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"],"alt":"vertical black line moves up and down with mouse y-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":132,"description":"<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"],"alt":"line trail is created from cursor movements. faster movement make longer line.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":164,"description":"<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"],"alt":"60×60 black rect center, fuchsia background. rect flickers on mouse movement","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":195,"description":"<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":233,"description":"<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":271,"description":"<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":311,"description":"<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":351,"description":"<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n","itemtype":"property","name":"mouseButton","type":"Constant","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"],"alt":"50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":389,"description":"<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n","itemtype":"property","name":"mouseIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":481,"description":"<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":535,"description":"<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseDragged","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":615,"description":"<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":696,"description":"<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":772,"description":"<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":841,"description":"<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":926,"description":"<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"event","description":"<p>optional WheelEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"],"alt":"black 50×50 rect moves up and down with vertical scroll. fuchsia background","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":979,"description":"<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n","itemtype":"method","name":"requestPointerLock","example":["\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"],"alt":"3D scene moves according to mouse mouse movement in a first person perspective","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":1025,"description":"<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n","itemtype":"method","name":"exitPointerLock","example":["\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"],"alt":"cursor gets locked / unlocked on mouse-click","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/touch.js","line":10,"description":"<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n","itemtype":"property","name":"touches","type":"Object[]","readonly":"","example":["\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"],"alt":"Number of touches currently registered are displayed on the canvas","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":71,"description":"<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch event.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":151,"description":"<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns lighter with touch until white. resets\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":223,"description":"<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/image/filters.js","line":3,"description":"<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n","class":"p5","module":"Events"},{"file":"src/image/image.js","line":8,"description":"<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":15,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n","itemtype":"method","name":"createImage","params":[{"name":"width","description":"<p>width in pixels</p>\n","type":"Integer"},{"name":"height","description":"<p>height in pixels</p>\n","type":"Integer"}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":94,"description":"<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n","itemtype":"method","name":"saveCanvas","example":["\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"],"alt":"no image displayed\n no image displayed\n no image displayed","class":"p5","module":"Image","submodule":"Image","overloads":[{"line":94,"params":[{"name":"selectedCanvas","description":"<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n","type":"p5.Element|HTMLCanvasElement"},{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String","optional":true}]},{"line":136,"params":[{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"","type":"String","optional":true}]}]},{"file":"src/image/image.js","line":413,"description":"<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n","itemtype":"method","name":"saveFrames","params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String"},{"name":"duration","description":"<p>Duration in seconds to save the frames for.</p>\n","type":"Number"},{"name":"framerate","description":"<p>Framerate to save the frames in.</p>\n","type":"Number"},{"name":"callback","description":"<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n","type":"Function(Array)","optional":true}],"example":["\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"],"alt":"canvas background goes from light to dark with mouse x.","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/loading_displaying.js","line":18,"description":"<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n","itemtype":"method","name":"loadImage","params":[{"name":"path","description":"<p>Path of the image to be loaded</p>\n","type":"String"},{"name":"successCallback","description":"<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n","type":"function(p5.Image)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                               the image fails to load.</p>\n","type":"Function(Event)","optional":true}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":162,"description":"<p>Helper function for loading GIF-based images</p>\n","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":301,"description":"<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n","itemtype":"method","name":"image","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":301,"params":[{"name":"img","description":"<p>the image to display</p>\n","type":"p5.Image|p5.Element|p5.Texture"},{"name":"x","description":"<p>the x-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"width","description":"<p>the width to draw the image</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>the height to draw the image</p>\n","type":"Number","optional":true}]},{"line":388,"params":[{"name":"img","description":"","type":"p5.Image|p5.Element|p5.Texture"},{"name":"dx","description":"<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dy","description":"<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dWidth","description":"<p>the width of the destination rectangle</p>\n","type":"Number"},{"name":"dHeight","description":"<p>the height of the destination rectangle</p>\n","type":"Number"},{"name":"sx","description":"<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sy","description":"<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sWidth","description":"<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n","type":"Number","optional":true},{"name":"sHeight","description":"<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n","type":"Number","optional":true}]}]},{"file":"src/image/loading_displaying.js","line":471,"description":"<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n","itemtype":"method","name":"tint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":471,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":542,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}]},{"line":547,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":553,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}]},{"line":559,"params":[{"name":"color","description":"<p>the tint color</p>\n","type":"p5.Color"}]}]},{"file":"src/image/loading_displaying.js","line":569,"description":"<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n","itemtype":"method","name":"noTint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of bricks, left image with blue tint","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":633,"description":"<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n","itemtype":"method","name":"imageMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, or CENTER</p>\n","type":"Constant"}],"example":["\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"],"alt":"small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/p5.Image.js","line":9,"description":"<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":88,"description":"<p>Image width.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"],"alt":"rocky mountains in top and horizontal lines in corresponding colors in bottom.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":115,"description":"<p>Image height.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"],"alt":"rocky mountains on right and vertical lines in corresponding colors on left.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":152,"description":"<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":222,"description":"<p>Helper function for animating GIF-based images with time</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":253,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":261,"description":"<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":296,"description":"<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n","itemtype":"method","name":"updatePixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":296,"params":[{"name":"x","description":"<p>x-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"y","description":"<p>y-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"w","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"h","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"}]},{"line":338,"params":[]}]},{"file":"src/image/p5.Image.js","line":346,"description":"<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"],"alt":"image of rocky mountains with 50×50 green rect in front","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":346,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":383,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":387,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/p5.Image.js","line":400,"description":"<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"a","description":"<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"],"alt":"2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":437,"description":"<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n","itemtype":"method","name":"resize","params":[{"name":"width","description":"<p>the resized image width</p>\n","type":"Number"},{"name":"height","description":"<p>the resized image height</p>\n","type":"Number"}],"example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"],"alt":"image of rocky mountains. zoomed in","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":548,"description":"<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains and smaller image on top of bricks at top left","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":548,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":588,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/p5.Image.js","line":603,"description":"<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n","itemtype":"method","name":"mask","params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"}],"example":["\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":665,"description":"<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"],"alt":"2 images of rocky mountains left one in color, right in black and white","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":738,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":738,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n","type":"Constant"}]},{"line":815,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/p5.Image.js","line":859,"description":"<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n","itemtype":"method","name":"save","params":[{"name":"filename","description":"<p>give your file a name</p>\n","type":"String"},{"name":"extension","description":"<p>'png' or 'jpg'</p>\n","type":"String"}],"example":["\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"],"alt":"image of rocky mountains.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":900,"description":"<p>Starts an animated GIF over at the beginning state.</p>\n","itemtype":"method","name":"reset","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"],"alt":"Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":941,"description":"<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n","itemtype":"method","name":"getCurrentFrame","return":{"description":"The index for the currently displaying frame in animated GIF","type":"Number"},"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"],"alt":"Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":972,"description":"<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n","itemtype":"method","name":"setFrame","params":[{"name":"index","description":"<p>the index for the frame that should be displayed</p>\n","type":"Number"}],"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1017,"description":"<p>Returns the number of frames in an animated GIF</p>\n","itemtype":"method","name":"numFrames","return":{"description":"","type":"Number"},"example":["     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1052,"description":"<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n","itemtype":"method","name":"play","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1089,"description":"<p>Pauses an animated GIF.</p>\n","itemtype":"method","name":"pause","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1125,"description":"<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n","itemtype":"method","name":"delay","params":[{"name":"d","description":"<p>the amount in milliseconds to delay between switching frames</p>\n","type":"Number"},{"name":"index","description":"<p>the index of the frame that should have the new delay value {optional}</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"],"alt":"Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/pixels.js","line":12,"description":"<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"],"alt":"top half of canvas pink, bottom grey","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":80,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":80,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n","type":"Constant"}]},{"line":152,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/pixels.js","line":173,"description":"<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":173,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":215,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/pixels.js","line":307,"description":"<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"],"alt":"black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":481,"description":"<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":481,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":551,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":555,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/pixels.js","line":566,"description":"<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":602,"description":"<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"c","description":"<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"],"alt":"4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":674,"description":"<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n","itemtype":"method","name":"updatePixels","params":[{"name":"x","description":"<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>width of region to update</p>\n","type":"Number","optional":true},{"name":"h","description":"<p>height of region to update</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/io/files.js","line":20,"description":"<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadJSON","return":{"description":"JSON data","type":"Object|Array"},"example":["\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"],"alt":"50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity","class":"p5","module":"IO","submodule":"Input","overloads":[{"line":20,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"jsonpOptions","description":"<p>options object for jsonp related settings</p>\n","type":"Object","optional":true},{"name":"datatype","description":"<p>\"json\" or \"jsonp\"</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"JSON data","type":"Object|Array"}},{"line":104,"params":[{"name":"path","description":"","type":"String"},{"name":"datatype","description":"","type":"String"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}},{"line":112,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}}]},{"file":"src/io/files.js","line":183,"description":"<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadStrings","params":[{"name":"filename","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":303,"description":"<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadTable","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"extension","description":"<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n","type":"String","optional":true},{"name":"header","description":"<p>\"header\" to indicate table has header row</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Table\">Table</a> object containing data","type":"Object"},"example":["\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":583,"description":"<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadXML","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"XML object containing data","type":"Object"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":693,"description":"<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadBytes","params":[{"name":"file","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if there\n                                   is an error</p>\n","type":"Function","optional":true}],"return":{"description":"an object whose 'bytes' property will be the loaded buffer","type":"Object"},"example":["\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":752,"description":"<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n","itemtype":"method","name":"httpGet","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":752,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":806,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":814,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":829,"description":"<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n","itemtype":"method","name":"httpPost","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":829,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":896,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":904,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":919,"description":"<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n","itemtype":"method","name":"httpDo","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":919,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"method","description":"<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n","type":"String","optional":true},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":990,"params":[{"name":"path","description":"","type":"String"},{"name":"options","description":"<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n","type":"Object"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":1155,"itemtype":"method","name":"createWriter","params":[{"name":"name","description":"<p>name of the file to be created</p>\n","type":"String"},{"name":"extension","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.PrintWriter"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1210,"description":"<p>Writes data to the PrintWriter stream</p>\n","itemtype":"method","name":"write","params":[{"name":"data","description":"<p>all data to be written by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1269,"description":"<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n","itemtype":"method","name":"print","params":[{"name":"data","description":"<p>all data to be printed by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1310,"description":"<p>Clears the data already written to the PrintWriter object</p>\n","itemtype":"method","name":"clear","example":["\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1344,"description":"<p>Closes the PrintWriter</p>\n","itemtype":"method","name":"close","example":["\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1393,"description":"<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n","itemtype":"method","name":"save","params":[{"name":"objectOrFilename","description":"<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n","type":"Object|String","optional":true},{"name":"filename","description":"<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n","type":"String","optional":true},{"name":"options","description":"<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n","type":"Boolean|String","optional":true}],"example":["\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"],"alt":"An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1535,"description":"<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveJSON","params":[{"name":"json","description":"","type":"Array|Object"},{"name":"filename","description":"","type":"String"},{"name":"optimize","description":"<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1592,"description":"<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveStrings","params":[{"name":"list","description":"<p>string array to be written</p>\n","type":"String[]"},{"name":"filename","description":"<p>filename for output</p>\n","type":"String"},{"name":"extension","description":"<p>the filename's extension</p>\n","type":"String","optional":true},{"name":"isCRLF","description":"<p>if true, change line-break to CRLF</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1656,"description":"<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveTable","params":[{"name":"Table","description":"<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n","type":"p5.Table"},{"name":"filename","description":"<p>the filename to which the Table should be saved</p>\n","type":"String"},{"name":"options","description":"<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n","type":"String","optional":true}],"example":["\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/p5.Table.js","line":9,"description":"<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":43,"description":"<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n","itemtype":"property","name":"columns","type":"String[]","example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":77,"description":"<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n","itemtype":"property","name":"rows","type":"p5.TableRow[]","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":85,"description":"<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n","itemtype":"method","name":"addRow","params":[{"name":"row","description":"<p>row to be added to the table</p>\n","type":"p5.TableRow","optional":true}],"return":{"description":"the row that was added","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":148,"description":"<p>Removes a row from the table object.</p>\n","itemtype":"method","name":"removeRow","params":[{"name":"id","description":"<p>ID number of the row to remove</p>\n","type":"Integer"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":195,"description":"<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n","itemtype":"method","name":"getRow","params":[{"name":"rowID","description":"<p>ID number of the row to get</p>\n","type":"Integer"}],"return":{"description":"<a href=\"#/p5.TableRow\">p5.TableRow</a> object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":240,"description":"<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n","itemtype":"method","name":"getRows","return":{"description":"Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":288,"description":"<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"findRow","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":352,"description":"<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"findRows","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":420,"description":"<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"matchRow","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String|RegExp"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer"}],"return":{"description":"TableRow object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":478,"description":"<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n","itemtype":"method","name":"matchRows","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer","optional":true}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":545,"description":"<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"getColumn","params":[{"name":"column","description":"<p>String or Number of the column to return</p>\n","type":"String|Number"}],"return":{"description":"Array of column values","type":"Array"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":597,"description":"<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n","itemtype":"method","name":"clearRows","example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":638,"description":"<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n","itemtype":"method","name":"addColumn","params":[{"name":"title","description":"<p>title of the given column</p>\n","type":"String","optional":true}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":688,"description":"<p>Returns the total number of columns in a Table.</p>\n","itemtype":"method","name":"getColumnCount","return":{"description":"Number of columns in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":724,"description":"<p>Returns the total number of rows in a Table.</p>\n","itemtype":"method","name":"getRowCount","return":{"description":"Number of rows in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":760,"description":"<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n","itemtype":"method","name":"removeTokens","params":[{"name":"chars","description":"<p>String listing characters to be removed</p>\n","type":"String"},{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":832,"description":"<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n","itemtype":"method","name":"trim","params":[{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":896,"description":"<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n","itemtype":"method","name":"removeColumn","params":[{"name":"column","description":"<p>columnName (string) or ID (number)</p>\n","type":"String|Integer"}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":960,"description":"<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String|Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1009,"description":"<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1055,"description":"<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String"}],"example":["\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1100,"description":"<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1146,"description":"<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1190,"description":"<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1242,"description":"<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n","itemtype":"method","name":"getObject","params":[{"name":"headerColumn","description":"<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n","type":"String","optional":true}],"return":{"description":"","type":"Object"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1305,"description":"<p>Retrieves all table data and returns it as a multidimensional array.</p>\n","itemtype":"method","name":"getArray","return":{"description":"","type":"Array"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":40,"description":"<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored</p>\n","type":"String|Number"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":102,"description":"<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a Float</p>\n","type":"Number|String"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":146,"description":"<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a String</p>\n","type":"String|Number|Boolean|Object"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":191,"description":"<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":239,"description":"<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"Float Floating point number","type":"Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":295,"description":"<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getString","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"String","type":"String"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.XML.js","line":62,"description":"<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"getParent","return":{"description":"element parent","type":"p5.XML"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":100,"description":"<p>Gets the element's full name, which is returned as a String.</p>\n","itemtype":"method","name":"getName","return":{"description":"the name of the node","type":"String"},"example":["&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":135,"description":"<p>Sets the element's name, which is specified as a String.</p>\n","itemtype":"method","name":"setName","params":[{"name":"the","description":"<p>new name of the node</p>\n","type":"String"}],"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":181,"description":"<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n","itemtype":"method","name":"hasChildren","return":{"description":"","type":"Boolean"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":217,"description":"<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n","itemtype":"method","name":"listChildren","return":{"description":"names of the children of the element","type":"String[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":258,"description":"<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n","itemtype":"method","name":"getChildren","params":[{"name":"name","description":"<p>element name</p>\n","type":"String","optional":true}],"return":{"description":"children of the element","type":"p5.XML[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":314,"description":"<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n","itemtype":"method","name":"getChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"return":{"description":"","type":"p5.XML"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":374,"description":"<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"addChild","params":[{"name":"node","description":"<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n","type":"p5.XML"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":426,"description":"<p>Removes the element specified by name or index.</p>\n","itemtype":"method","name":"removeChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":498,"description":"<p>Counts the specified element's number of attributes, returned as an Number.</p>\n","itemtype":"method","name":"getAttributeCount","return":{"description":"","type":"Integer"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":534,"description":"<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n","itemtype":"method","name":"listAttributes","return":{"description":"an array of strings containing the names of attributes","type":"String[]"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":577,"description":"<p>Checks whether or not an element has the specified attribute.</p>\n","itemtype":"method","name":"hasAttribute","params":[{"name":"the","description":"<p>attribute to be checked</p>\n","type":"String"}],"return":{"description":"true if attribute found else false","type":"Boolean"},"example":["\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":622,"description":"<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"Number"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":669,"description":"<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n","itemtype":"method","name":"getString","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":716,"description":"<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n","itemtype":"method","name":"setAttribute","params":[{"name":"name","description":"<p>the full name of the attribute</p>\n","type":"String"},{"name":"value","description":"<p>the value of the attribute</p>\n","type":"Number|String|Boolean"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":757,"description":"<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n","itemtype":"method","name":"getContent","params":[{"name":"defaultValue","description":"<p>value returned if no content is found</p>\n","type":"String","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":798,"description":"<p>Sets the element's content.</p>\n","itemtype":"method","name":"setContent","params":[{"name":"text","description":"<p>the new content</p>\n","type":"String"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":839,"description":"<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n","itemtype":"method","name":"serialize","return":{"description":"Serialized string of the element","type":"String"},"example":["\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/math/calculation.js","line":10,"description":"<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n","itemtype":"method","name":"abs","params":[{"name":"n","description":"<p>number to compute</p>\n","type":"Number"}],"return":{"description":"absolute value of given number","type":"Number"},"example":["\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":33,"description":"<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n","itemtype":"method","name":"ceil","params":[{"name":"n","description":"<p>number to round up</p>\n","type":"Number"}],"return":{"description":"rounded up number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":72,"description":"<p>Constrains a value between a minimum and maximum value.</p>\n","itemtype":"method","name":"constrain","params":[{"name":"n","description":"<p>number to constrain</p>\n","type":"Number"},{"name":"low","description":"<p>minimum limit</p>\n","type":"Number"},{"name":"high","description":"<p>maximum limit</p>\n","type":"Number"}],"return":{"description":"constrained number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"],"alt":"2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":116,"description":"<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"distance between the two points","type":"Number"},"example":["\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"],"alt":"2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":116,"params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}},{"line":161,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}}]},{"file":"src/math/calculation.js","line":182,"description":"<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n","itemtype":"method","name":"exp","params":[{"name":"n","description":"<p>exponent to raise</p>\n","type":"Number"}],"return":{"description":"e^n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. e^n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":231,"description":"<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n","itemtype":"method","name":"floor","params":[{"name":"n","description":"<p>number to round down</p>\n","type":"Number"}],"return":{"description":"rounded down number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":269,"description":"<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n","itemtype":"method","name":"lerp","params":[{"name":"start","description":"<p>first value</p>\n","type":"Number"},{"name":"stop","description":"<p>second value</p>\n","type":"Number"},{"name":"amt","description":"<p>number</p>\n","type":"Number"}],"return":{"description":"lerped value","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"],"alt":"5 points horizontally staggered mid-canvas. mid 3 are grey, outer black","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":316,"description":"<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n","itemtype":"method","name":"log","params":[{"name":"n","description":"<p>number greater than 0</p>\n","type":"Number"}],"return":{"description":"natural logarithm of n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. natural logarithm of n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":371,"description":"<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n","itemtype":"method","name":"mag","params":[{"name":"a","description":"<p>first value</p>\n","type":"Number"},{"name":"b","description":"<p>second value</p>\n","type":"Number"}],"return":{"description":"magnitude of vector from (0,0) to (a,b)","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"],"alt":"4 lines of different length radiate from top left of canvas.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":409,"description":"<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n","itemtype":"method","name":"map","params":[{"name":"value","description":"<p>the incoming value to be converted</p>\n","type":"Number"},{"name":"start1","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop1","description":"<p>upper bound of the value's current range</p>\n","type":"Number"},{"name":"start2","description":"<p>lower bound of the value's target range</p>\n","type":"Number"},{"name":"stop2","description":"<p>upper bound of the value's target range</p>\n","type":"Number"},{"name":"withinBounds","description":"<p>constrain the value to the newly mapped range</p>\n","type":"Boolean","optional":true}],"return":{"description":"remapped number","type":"Number"},"example":["\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"],"alt":"10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":464,"description":"<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"max","return":{"description":"maximum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":464,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"maximum Number","type":"Number"}},{"line":499,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":512,"description":"<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"min","return":{"description":"minimum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":512,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"minimum Number","type":"Number"}},{"line":547,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":560,"description":"<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n","itemtype":"method","name":"norm","params":[{"name":"value","description":"<p>incoming value to be normalized</p>\n","type":"Number"},{"name":"start","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop","description":"<p>upper bound of the value's current range</p>\n","type":"Number"}],"return":{"description":"normalized number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"],"alt":"ellipse moves with mouse. 0 shown left & 100 right and updating values center","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":612,"description":"<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n","itemtype":"method","name":"pow","params":[{"name":"n","description":"<p>base of the exponential expression</p>\n","type":"Number"},{"name":"e","description":"<p>power by which to raise the base</p>\n","type":"Number"}],"return":{"description":"n^e","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"],"alt":"small to large ellipses radiating from top left of canvas","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":646,"description":"<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n","itemtype":"method","name":"round","params":[{"name":"n","description":"<p>number to round</p>\n","type":"Number"},{"name":"decimals","description":"<p>number of decimal places to round to, default is 0</p>\n","type":"Number","optional":true}],"return":{"description":"rounded number","type":"Integer"},"example":["\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":701,"description":"<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n","itemtype":"method","name":"sq","params":[{"name":"n","description":"<p>number to square</p>\n","type":"Number"}],"return":{"description":"squared number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squared values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":745,"description":"<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n","itemtype":"method","name":"sqrt","params":[{"name":"n","description":"<p>non-negative number to square root</p>\n","type":"Number"}],"return":{"description":"square root of number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squareroot values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":832,"description":"<p>Calculates the fractional part of a number.</p>\n","itemtype":"method","name":"fract","params":[{"name":"num","description":"<p>Number whose fractional part needs to be found out</p>\n","type":"Number"}],"return":{"description":"fractional part of x, i.e, {x}","type":"Number"},"example":["\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"],"alt":"first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/math.js","line":10,"description":"<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n","itemtype":"method","name":"createVector","params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"p5.Vector"},"example":["\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"],"alt":"draws a line from center of canvas to mouse pointer position.","class":"p5","module":"Math","submodule":"Vector"},{"file":"src/math/noise.js","line":36,"description":"<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n","itemtype":"method","name":"noise","params":[{"name":"x","description":"<p>x-coordinate in noise space</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate in noise space</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z-coordinate in noise space</p>\n","type":"Number","optional":true}],"return":{"description":"Perlin noise value (between 0 and 1) at specified\n                     coordinates","type":"Number"},"example":["\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"],"alt":"vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":178,"description":"<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n","itemtype":"method","name":"noiseDetail","params":[{"name":"lod","description":"<p>number of octaves to be used by the noise</p>\n","type":"Number"},{"name":"falloff","description":"<p>falloff factor for each octave</p>\n","type":"Number"}],"example":["\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"],"alt":"2 vertical grey smokey patterns affected my mouse x-position and noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":243,"description":"<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n","itemtype":"method","name":"noiseSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"],"alt":"vertical grey lines drawing in pattern affected by noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/p5.Vector.js","line":69,"description":"<p>The x component of the vector</p>\n","itemtype":"property","name":"x","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":74,"description":"<p>The y component of the vector</p>\n","itemtype":"property","name":"y","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":79,"description":"<p>The z component of the vector</p>\n","itemtype":"property","name":"z","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":86,"description":"<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n","itemtype":"method","name":"toString","return":{"description":"","type":"String"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":136,"description":"<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n","itemtype":"method","name":"set","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":136,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":195,"params":[{"name":"value","description":"<p>the vector to set</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/math/p5.Vector.js","line":219,"description":"<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n","itemtype":"method","name":"copy","return":{"description":"the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":248,"description":"<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"add","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":248,"params":[{"name":"x","description":"<p>the x component of the vector to be added</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to be added</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to be added</p>\n","type":"Number","optional":true}],"chainable":1},{"line":325,"params":[{"name":"value","description":"<p>the vector to add</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2059,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":372,"description":"<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n","itemtype":"method","name":"rem","chainable":1,"example":["\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":372,"params":[{"name":"x","description":"<p>the x component of divisor vector</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of divisor vector</p>\n","type":"Number"},{"name":"z","description":"<p>the z component of divisor vector</p>\n","type":"Number"}],"chainable":1},{"line":401,"params":[{"name":"value","description":"<p>divisor vector</p>\n","type":"p5.Vector | Number[]"}],"chainable":1},{"line":2085,"params":[{"name":"v1","description":"<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1},{"line":2091,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":461,"description":"<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"sub","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":461,"params":[{"name":"x","description":"<p>the x component of the vector to subtract</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to subtract</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to subtract</p>\n","type":"Number","optional":true}],"chainable":1},{"line":538,"params":[{"name":"value","description":"<p>the vector to subtract</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2110,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":562,"description":"<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"mult","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":562,"params":[{"name":"n","description":"<p>The number to multiply with the vector</p>\n","type":"Number"}],"chainable":1},{"line":655,"params":[{"name":"x","description":"<p>The number to multiply with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to multiply with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to multiply with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":663,"params":[{"name":"arr","description":"<p>The array to multiply with the components of the vector</p>\n","type":"Number[]"}],"chainable":1},{"line":669,"params":[{"name":"v","description":"<p>The vector to multiply with the components of the original vector</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2139,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2148,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2156,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2164,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":754,"description":"<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"div","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":754,"params":[{"name":"n","description":"<p>The number to divide the vector by</p>\n","type":"Number"}],"chainable":1},{"line":847,"params":[{"name":"x","description":"<p>The number to divide with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to divide with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to divide with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":855,"params":[{"name":"arr","description":"<p>The array to divide the components of the vector by</p>\n","type":"Number[]"}],"chainable":1},{"line":861,"params":[{"name":"v","description":"<p>The vector to divide the components of the original vector by</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2218,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2227,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2235,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2243,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":959,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","itemtype":"method","name":"mag","return":{"description":"magnitude of the vector","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":959,"params":[],"return":{"description":"magnitude of the vector","type":"Number"}},{"line":2343,"params":[{"name":"vecT","description":"<p>the vector to return the magnitude of</p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the magnitude of vecT","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1007,"description":"<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n","itemtype":"method","name":"magSq","return":{"description":"squared magnitude of the vector","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1061,"description":"<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n","itemtype":"method","name":"dot","return":{"description":"the dot product","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1061,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"the dot product","type":"Number"}},{"line":1091,"params":[{"name":"value","description":"<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"","type":"Number"}},{"line":2270,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the dot product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1103,"description":"<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n","itemtype":"method","name":"cross","return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1103,"params":[{"name":"v","description":"<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n","type":"p5.Vector"}],"return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"}},{"line":2284,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the cross product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1145,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"the distance","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1145,"params":[{"name":"v","description":"<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the distance","type":"Number"}},{"line":2299,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the distance","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1217,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","itemtype":"method","name":"normalize","return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1217,"params":[],"return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2360,"params":[{"name":"v","description":"<p>the vector to normalize</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"v normalized to a length of 1","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1287,"description":"<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n","itemtype":"method","name":"limit","params":[{"name":"max","description":"<p>the maximum magnitude for the vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1345,"description":"<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n","itemtype":"method","name":"setMag","params":[{"name":"len","description":"<p>the new length for this vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1401,"description":"<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"heading","return":{"description":"the angle of rotation","type":"Number"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1473,"description":"<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"setHeading","params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1498,"description":"<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"rotate","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1498,"params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1},{"line":2191,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":1567,"description":"<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"angleBetween","params":[{"name":"value","description":"<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the angle between (in radians)","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1647,"description":"<p>Linear interpolate the vector to another vector</p>\n","itemtype":"method","name":"lerp","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1647,"params":[{"name":"x","description":"<p>the x component</p>\n","type":"Number"},{"name":"y","description":"<p>the y component</p>\n","type":"Number"},{"name":"z","description":"<p>the z component</p>\n","type":"Number"},{"name":"amt","description":"<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n","type":"Number"}],"chainable":1},{"line":1720,"params":[{"name":"v","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"}],"chainable":1},{"line":2314,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the lerped value","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1736,"description":"<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n","itemtype":"method","name":"reflect","params":[{"name":"surfaceNormal","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n","type":"p5.Vector"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1791,"description":"<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n","itemtype":"method","name":"array","return":{"description":"an Array with the 3 values","type":"Number[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1823,"description":"<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","itemtype":"method","name":"equals","return":{"description":"whether the vectors are equals","type":"Boolean"},"example":["\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1823,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"whether the vectors are equals","type":"Boolean"}},{"line":1853,"params":[{"name":"value","description":"<p>the vector to compare</p>\n","type":"p5.Vector|Array"}],"return":{"description":"","type":"Boolean"}}]},{"file":"src/math/p5.Vector.js","line":1878,"description":"<p>Make a new 2D vector from an angle</p>\n","itemtype":"method","name":"fromAngle","static":1,"params":[{"name":"angle","description":"<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1929,"description":"<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n","itemtype":"method","name":"fromAngles","static":1,"params":[{"name":"theta","description":"<p>the polar angle, in radians (zero is up)</p>\n","type":"Number"},{"name":"phi","description":"<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1978,"description":"<p>Make a new 2D unit vector from a random angle</p>\n","itemtype":"method","name":"random2D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2031,"description":"<p>Make a new random 3D unit vector.</p>\n","itemtype":"method","name":"random3D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2135,"description":"<p>Multiplies a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2187,"description":"<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2214,"description":"<p>Divides a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2267,"description":"<p>Calculates the dot product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2281,"description":"<p>Calculates the cross product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2295,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2310,"description":"<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2339,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2357,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/random.js","line":37,"description":"<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n","itemtype":"method","name":"randomSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"],"alt":"many vertical lines drawn in white, black or grey.","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/random.js","line":66,"description":"<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n","itemtype":"method","name":"random","return":{"description":"the random number","type":"Number"},"example":["\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"],"alt":"100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog","class":"p5","module":"Math","submodule":"Random","overloads":[{"line":66,"params":[{"name":"min","description":"<p>the lower bound (inclusive)</p>\n","type":"Number","optional":true},{"name":"max","description":"<p>the upper bound (exclusive)</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"}},{"line":119,"params":[{"name":"choices","description":"<p>the array to choose from</p>\n","type":"Array"}],"return":{"description":"the random element from the array","type":"*"}}]},{"file":"src/math/random.js","line":153,"description":"<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n","itemtype":"method","name":"randomGaussian","params":[{"name":"mean","description":"<p>the mean</p>\n","type":"Number","optional":true},{"name":"sd","description":"<p>the standard deviation</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"},"example":["\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"],"alt":"100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/trigonometry.js","line":18,"description":"<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n","itemtype":"method","name":"acos","params":[{"name":"value","description":"<p>the value whose arc cosine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc cosine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":53,"description":"<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n","itemtype":"method","name":"asin","params":[{"name":"value","description":"<p>the value whose arc sine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc sine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":88,"description":"<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n","itemtype":"method","name":"atan","params":[{"name":"value","description":"<p>the value whose arc tangent is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":123,"description":"<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n","itemtype":"method","name":"atan2","params":[{"name":"y","description":"<p>y-coordinate of the point</p>\n","type":"Number"},{"name":"x","description":"<p>x-coordinate of the point</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given point","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"],"alt":"60 by 10 rect at center of canvas rotates with mouse movements","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":159,"description":"<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"cos","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the cosine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines form wave patterns, extend-down on left and right side","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":186,"description":"<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"sin","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the sine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines extend down and up from center to form wave pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":213,"description":"<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n","itemtype":"method","name":"tan","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the tangent of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"],"alt":"vertical black lines end down and up from center to form spike pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":239,"description":"<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"degrees","params":[{"name":"radians","description":"<p>the radians value to convert to degrees</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":262,"description":"<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"radians","params":[{"name":"degrees","description":"<p>the degree value to convert to radians</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":285,"description":"<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n","itemtype":"method","name":"angleMode","params":[{"name":"mode","description":"<p>either RADIANS or DEGREES</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"],"alt":"40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/typography/attributes.js","line":11,"description":"<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n","itemtype":"method","name":"textAlign","chainable":1,"example":["\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"],"alt":"Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":11,"params":[{"name":"horizAlign","description":"<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n","type":"Constant"},{"name":"vertAlign","description":"<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n","type":"Constant","optional":true}],"chainable":1},{"line":72,"params":[],"return":{"description":"","type":"Object"}}]},{"file":"src/typography/attributes.js","line":81,"description":"<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n","itemtype":"method","name":"textLeading","chainable":1,"example":["\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"],"alt":"A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":81,"params":[{"name":"leading","description":"<p>the size in pixels for spacing between lines</p>\n","type":"Number"}],"chainable":1},{"line":109,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":118,"description":"<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n","itemtype":"method","name":"textSize","chainable":1,"example":["\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"],"alt":"'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":118,"params":[{"name":"theSize","description":"<p>the size of the letters in units of pixels</p>\n","type":"Number"}],"chainable":1},{"line":141,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":150,"description":"<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n","itemtype":"method","name":"textStyle","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"],"alt":"Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":150,"params":[{"name":"theStyle","description":"<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n","type":"Constant"}],"chainable":1},{"line":178,"params":[],"return":{"description":"","type":"String"}}]},{"file":"src/typography/attributes.js","line":187,"description":"<p>Calculates and returns the width of any character or text string.</p>\n","itemtype":"method","name":"textWidth","params":[{"name":"theText","description":"<p>the String of characters to measure</p>\n","type":"String"}],"return":{"description":"the calculated width","type":"Number"},"example":["\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"],"alt":"Letter P and p5.js are displayed with vertical lines at end.","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":222,"description":"<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n","itemtype":"method","name":"textAscent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":251,"description":"<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n","itemtype":"method","name":"textDescent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":280,"description":"<p>Helper function to measure ascent and descent.</p>\n","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":287,"description":"<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n","itemtype":"method","name":"textWrap","params":[{"name":"wrapStyle","description":"<p>text wrapping style, either WORD or CHAR</p>\n","type":"Constant"}],"return":{"description":"wrapStyle","type":"String"},"example":["\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/loading_displaying.js","line":16,"description":"<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n","itemtype":"method","name":"loadFont","params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n","type":"Function","optional":true},{"name":"onError","description":"<p>function to be executed if\n                                   an error occurs</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Font\">p5.Font</a> object","type":"p5.Font"},"example":["\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"],"alt":"p5*js in p5's theme dark pink\np5*js in p5's theme dark pink","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":140,"description":"<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n","itemtype":"method","name":"text","params":[{"name":"str","description":"<p>the alphanumeric\n                                            symbols to be displayed</p>\n","type":"String|Object|Array|Number|Boolean"},{"name":"x","description":"<p>x-coordinate of text</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of text</p>\n","type":"Number"},{"name":"x2","description":"<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true},{"name":"y2","description":"<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"],"alt":"'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":231,"description":"<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n","itemtype":"method","name":"textFont","return":{"description":"the current font / p5 Object","type":"Object"},"example":["\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"],"alt":"word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold","class":"p5","module":"Typography","submodule":"Loading & Displaying","overloads":[{"line":231,"params":[],"return":{"description":"the current font / p5 Object","type":"Object"}},{"line":280,"params":[{"name":"font","description":"<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n","type":"Object|String"},{"name":"size","description":"<p>the font size to use</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/typography/p5.Font.js","line":24,"description":"<p>Underlying opentype font implementation</p>\n","itemtype":"property","name":"font","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":31,"description":"<p>Returns a tight bounding box for the given text string using this\nfont</p>\n","itemtype":"method","name":"textBounds","params":[{"name":"line","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional) Default is 12.</p>\n","type":"Number","optional":true},{"name":"options","description":"<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n","type":"Object","optional":true}],"return":{"description":"a rectangle object with properties: x, y, w, h","type":"Object"},"example":["\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"],"alt":"words Lorem ipsum dol go off canvas and contained by white bounding box","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":175,"description":"<p>Computes an array of points following the path for specified text</p>\n","itemtype":"method","name":"textToPoints","params":[{"name":"txt","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional)</p>\n","type":"Number"},{"name":"options","description":"<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n","type":"Object","optional":true}],"return":{"description":"an array of points, each with x, y, alpha (the path angle)","type":"Array"},"example":["\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"],"class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/utilities/array_functions.js","line":10,"description":"<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n","itemtype":"method","name":"append","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.","params":[{"name":"array","description":"<p>Array to append</p>\n","type":"Array"},{"name":"value","description":"<p>to be added to the Array</p>\n","type":"Any"}],"return":{"description":"the array that was appended to","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":35,"description":"<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n","itemtype":"method","name":"arrayCopy","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.","example":["\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions","overloads":[{"line":35,"params":[{"name":"src","description":"<p>the source Array</p>\n","type":"Array"},{"name":"srcPosition","description":"<p>starting position in the source Array</p>\n","type":"Integer"},{"name":"dst","description":"<p>the destination Array</p>\n","type":"Array"},{"name":"dstPosition","description":"<p>starting position in the destination Array</p>\n","type":"Integer"},{"name":"length","description":"<p>number of Array elements to be copied</p>\n","type":"Integer"}]},{"line":73,"params":[{"name":"src","description":"","type":"Array"},{"name":"dst","description":"","type":"Array"},{"name":"length","description":"","type":"Integer","optional":true}]}]},{"file":"src/utilities/array_functions.js","line":112,"description":"<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n","itemtype":"method","name":"concat","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.","params":[{"name":"a","description":"<p>first Array to concatenate</p>\n","type":"Array"},{"name":"b","description":"<p>second Array to concatenate</p>\n","type":"Array"}],"return":{"description":"concatenated array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":141,"description":"<p>Reverses the order of an array, maps to Array.reverse()</p>\n","itemtype":"method","name":"reverse","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.","params":[{"name":"list","description":"<p>Array to reverse</p>\n","type":"Array"}],"return":{"description":"the reversed list","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":161,"description":"<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n","itemtype":"method","name":"shorten","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.","params":[{"name":"list","description":"<p>Array to shorten</p>\n","type":"Array"}],"return":{"description":"shortened Array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":185,"description":"<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n","itemtype":"method","name":"shuffle","params":[{"name":"array","description":"<p>Array to shuffle</p>\n","type":"Array"},{"name":"bool","description":"<p>modify passed array</p>\n","type":"Boolean","optional":true}],"return":{"description":"shuffled Array","type":"Array"},"example":["\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":227,"description":"<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n","itemtype":"method","name":"sort","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.","params":[{"name":"list","description":"<p>Array to sort</p>\n","type":"Array"},{"name":"count","description":"<p>number of elements to sort, starting from 0</p>\n","type":"Integer","optional":true}],"return":{"description":"the sorted list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":273,"description":"<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n","itemtype":"method","name":"splice","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.","params":[{"name":"list","description":"<p>Array to splice into</p>\n","type":"Array"},{"name":"value","description":"<p>value to be spliced in</p>\n","type":"Any"},{"name":"position","description":"<p>in the array from which to insert data</p>\n","type":"Integer"}],"return":{"description":"the list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":308,"description":"<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n","itemtype":"method","name":"subset","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.","params":[{"name":"list","description":"<p>Array to extract from</p>\n","type":"Array"},{"name":"start","description":"<p>position to begin</p>\n","type":"Integer"},{"name":"count","description":"<p>number of values to extract</p>\n","type":"Integer","optional":true}],"return":{"description":"Array of extracted elements","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/conversion.js","line":10,"description":"<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n","itemtype":"method","name":"float","params":[{"name":"str","description":"<p>float string to parse</p>\n","type":"String"}],"return":{"description":"floating point representation of string","type":"Number"},"example":["\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"],"alt":"20 by 20 white ellipse in the center of the canvas","class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":44,"description":"<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n","itemtype":"method","name":"int","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":44,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"},{"name":"radix","description":"<p>the radix to convert to (default: 10)</p>\n","type":"Integer","optional":true}],"return":{"description":"integer representation of value","type":"Number"}},{"line":66,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"},{"name":"radix","description":"","type":"Integer","optional":true}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":88,"description":"<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n","itemtype":"method","name":"str","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":114,"description":"<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n","itemtype":"method","name":"boolean","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"boolean representation of value","type":"Boolean"},"example":["\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":146,"description":"<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n","itemtype":"method","name":"byte","return":{"description":"byte representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":146,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"}],"return":{"description":"byte representation of value","type":"Number"}},{"line":168,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of byte representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":182,"description":"<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n","itemtype":"method","name":"char","return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":182,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Number"}],"return":{"description":"string representation of value","type":"String"}},{"line":201,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":216,"description":"<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unchar","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":216,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of value","type":"Number"}},{"line":232,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":245,"description":"<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n","itemtype":"method","name":"hex","return":{"description":"hexadecimal string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":245,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"Number"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of value","type":"String"}},{"line":265,"params":[{"name":"ns","description":"<p>array of values to parse</p>\n","type":"Number[]"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":295,"description":"<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unhex","return":{"description":"integer representation of hexadecimal value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":295,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of hexadecimal value","type":"Number"}},{"line":311,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representations of hexadecimal value","type":"Number[]"}}]},{"file":"src/utilities/string_functions.js","line":15,"description":"<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n","itemtype":"method","name":"join","params":[{"name":"list","description":"<p>array of Strings to be joined</p>\n","type":"Array"},{"name":"separator","description":"<p>String to be placed between each item</p>\n","type":"String"}],"return":{"description":"joined String","type":"String"},"example":["\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"],"alt":"\"hello world!\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":43,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n","itemtype":"method","name":"match","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"Array of Strings found","type":"String[]"},"example":["\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"],"alt":"\"p5js*\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":83,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n","itemtype":"method","name":"matchAll","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"2d Array of Strings found","type":"String[]"},"example":["\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":130,"description":"<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nf","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" middle top, -1321.00\" middle bottom canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":130,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"left","description":"<p>number of digits to the left of the\n                               decimal point</p>\n","type":"Integer|String","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":176,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer|String","optional":true},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":237,"description":"<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n","itemtype":"method","name":"nfc","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":237,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"right","description":"<p>number of digits to the right of the\n                                 decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":275,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":311,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n","itemtype":"method","name":"nfp","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":311,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":352,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Number[]"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":373,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nfs","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" top middle and \"-1321.00\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":373,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":430,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":451,"description":"<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n","itemtype":"method","name":"split","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>the String used to separate the data</p>\n","type":"String"}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"],"alt":"\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":484,"description":"<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n","itemtype":"method","name":"splitTokens","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>list of individual Strings that will be used as\n                         separators</p>\n","type":"String","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":537,"description":"<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n","itemtype":"method","name":"trim","return":{"description":"a trimmed String","type":"String"},"example":["\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"],"alt":"\"No new lines here\" displayed center canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":537,"params":[{"name":"str","description":"<p>a String to be trimmed</p>\n","type":"String"}],"return":{"description":"a trimmed String","type":"String"}},{"line":557,"params":[{"name":"strs","description":"<p>an Array of Strings to be trimmed</p>\n","type":"Array"}],"return":{"description":"an Array of trimmed Strings","type":"String[]"}}]},{"file":"src/utilities/time_date.js","line":10,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n","itemtype":"method","name":"day","return":{"description":"the current day","type":"Integer"},"example":["\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"],"alt":"Current day is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":31,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n","itemtype":"method","name":"hour","return":{"description":"the current hour","type":"Integer"},"example":["\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"],"alt":"Current hour is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":52,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n","itemtype":"method","name":"minute","return":{"description":"the current minute","type":"Integer"},"example":["\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current minute is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":73,"description":"<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n","itemtype":"method","name":"millis","return":{"description":"the number of milliseconds since starting the sketch","type":"Number"},"example":["\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"],"alt":"number of milliseconds since sketch has started displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":100,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n","itemtype":"method","name":"month","return":{"description":"the current month","type":"Integer"},"example":["\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current month is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":122,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n","itemtype":"method","name":"second","return":{"description":"the current second","type":"Integer"},"example":["\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"],"alt":"Current second is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":143,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n","itemtype":"method","name":"year","return":{"description":"the current year","type":"Integer"},"example":["\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"],"alt":"Current year is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/webgl/3d_primitives.js","line":13,"description":"<p>Draw a plane with given a width and height</p>\n","itemtype":"method","name":"plane","params":[{"name":"width","description":"<p>width of the plane</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the plane</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"],"alt":"Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.","class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":97,"description":"<p>Draw a box with given width, height and depth</p>\n","itemtype":"method","name":"box","params":[{"name":"width","description":"<p>width of the box</p>\n","type":"Number","optional":true},{"name":"Height","description":"<p>height of the box</p>\n","type":"Number","optional":true},{"name":"depth","description":"<p>depth of the box</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":215,"description":"<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"sphere","params":[{"name":"radius","description":"<p>radius of circle</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>optional number of subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>optional number of subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":419,"description":"<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cylinder","params":[{"name":"radius","description":"<p>radius of the surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cylinder</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n","type":"Integer","optional":true},{"name":"bottomCap","description":"<p>whether to draw the bottom of the cylinder</p>\n","type":"Boolean","optional":true},{"name":"topCap","description":"<p>whether to draw the top of the cylinder</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":554,"description":"<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cone","params":[{"name":"radius","description":"<p>radius of the bottom surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cone</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n","type":"Integer","optional":true},{"name":"cap","description":"<p>whether to draw the base of the cone</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":669,"description":"<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n","itemtype":"method","name":"ellipsoid","params":[{"name":"radiusx","description":"<p>x-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusy","description":"<p>y-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusz","description":"<p>z-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":804,"description":"<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n","itemtype":"method","name":"torus","params":[{"name":"radius","description":"<p>radius of the whole ring</p>\n","type":"Number","optional":true},{"name":"tubeRadius","description":"<p>radius of the tube</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/interaction.js","line":11,"description":"<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n","itemtype":"method","name":"orbitControl","params":[{"name":"sensitivityX","description":"<p>sensitivity to mouse movement along X axis</p>\n","type":"Number","optional":true},{"name":"sensitivityY","description":"<p>sensitivity to mouse movement along Y axis</p>\n","type":"Number","optional":true},{"name":"sensitivityZ","description":"<p>sensitivity to scroll movement along Z axis</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"],"alt":"Camera orbits around a box when mouse is hold-clicked & then moved.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/interaction.js","line":145,"description":"<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n","itemtype":"method","name":"debugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.","class":"p5","module":"3D","submodule":"Interaction","overloads":[{"line":145,"params":[]},{"line":278,"params":[{"name":"mode","description":"<p>either GRID or AXES</p>\n","type":"Constant"}]},{"line":283,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"gridSize","description":"<p>size of one side of the grid</p>\n","type":"Number","optional":true},{"name":"gridDivisions","description":"<p>number of divisions in the grid</p>\n","type":"Number","optional":true},{"name":"xOff","description":"<p>X axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"yOff","description":"<p>Y axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"zOff","description":"<p>Z axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true}]},{"line":293,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"axesSize","description":"<p>size of axes icon</p>\n","type":"Number","optional":true},{"name":"xOff","description":"","type":"Number","optional":true},{"name":"yOff","description":"","type":"Number","optional":true},{"name":"zOff","description":"","type":"Number","optional":true}]},{"line":302,"params":[{"name":"gridSize","description":"","type":"Number","optional":true},{"name":"gridDivisions","description":"","type":"Number","optional":true},{"name":"gridXOff","description":"","type":"Number","optional":true},{"name":"gridYOff","description":"","type":"Number","optional":true},{"name":"gridZOff","description":"","type":"Number","optional":true},{"name":"axesSize","description":"","type":"Number","optional":true},{"name":"axesXOff","description":"","type":"Number","optional":true},{"name":"axesYOff","description":"","type":"Number","optional":true},{"name":"axesZOff","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/interaction.js","line":353,"description":"<p>Turns off debugMode() in a 3D sketch.</p>\n","itemtype":"method","name":"noDebugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/light.js","line":11,"description":"<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n","itemtype":"method","name":"ambientLight","chainable":1,"example":["\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"],"alt":"evenly distributed light across a sphere\nevenly distributed light across a rotating sphere","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":11,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"<p>the alpha value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":51,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":57,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":64,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":71,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":92,"description":"<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n","itemtype":"method","name":"specularColor","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"different specular light sources from top and bottom of canvas","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":92,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"}],"chainable":1},{"line":139,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":145,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"}],"chainable":1},{"line":151,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":158,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":177,"description":"<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n","itemtype":"method","name":"directionalLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"light source on canvas changeable with mouse position","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":177,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"position","description":"<p>the direction of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":210,"params":[{"name":"color","description":"<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"<p>x axis direction</p>\n","type":"Number"},{"name":"y","description":"<p>y axis direction</p>\n","type":"Number"},{"name":"z","description":"<p>z axis direction</p>\n","type":"Number"}],"chainable":1},{"line":220,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1},{"line":227,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1}]},{"file":"src/webgl/light.js","line":280,"description":"<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n","itemtype":"method","name":"pointLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"spot light on canvas changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":280,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"}],"chainable":1},{"line":322,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":331,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1},{"line":341,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1}]},{"file":"src/webgl/light.js","line":387,"description":"<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n","itemtype":"method","name":"lights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"the light is partially ambient and partially directional","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":425,"description":"<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n","itemtype":"method","name":"lightFalloff","params":[{"name":"constant","description":"<p>constant value for determining falloff</p>\n","type":"Number"},{"name":"linear","description":"<p>linear value for determining falloff</p>\n","type":"Number"},{"name":"quadratic","description":"<p>quadratic value for determining falloff</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"],"alt":"Two spheres with different falloff values show different intensity of light","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":519,"description":"<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n","itemtype":"method","name":"spotLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Spot light on a sphere which changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":519,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"},{"name":"rx","description":"<p>x axis direction of light</p>\n","type":"Number"},{"name":"ry","description":"<p>y axis direction of light</p>\n","type":"Number"},{"name":"rz","description":"<p>z axis direction of light</p>\n","type":"Number"},{"name":"angle","description":"<p>optional parameter for angle. Defaults to PI/3</p>\n","type":"Number","optional":true},{"name":"conc","description":"<p>optional parameter for concentration. Defaults to 100</p>\n","type":"Number","optional":true}],"chainable":1},{"line":571,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"},{"name":"direction","description":"<p>the direction of the light</p>\n","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":580,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":590,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":600,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":610,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":622,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":634,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/light.js","line":859,"description":"<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n","itemtype":"method","name":"noLights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"],"alt":"Three white spheres. Each appears as a different\ncolor due to lighting.","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/loading.js","line":12,"description":"<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n","itemtype":"method","name":"loadModel","return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"},"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>","\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d teapot with red, green and blue gradient.","class":"p5","module":"Shape","submodule":"3D Models","overloads":[{"line":12,"params":[{"name":"path","description":"<p>Path of the model to be loaded</p>\n","type":"String"},{"name":"normalize","description":"<p>If true, scale the model to a\n                                     standardized size when loading</p>\n","type":"Boolean"},{"name":"successCallback","description":"<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                                        the model fails to load.</p>\n","type":"Function(Event)","optional":true},{"name":"fileType","description":"<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}},{"line":96,"params":[{"name":"path","description":"","type":"String"},{"name":"successCallback","description":"","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"","type":"Function(Event)","optional":true},{"name":"fileType","description":"","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}}]},{"file":"src/webgl/loading.js","line":179,"description":"<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":290,"description":"<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":317,"description":"<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":344,"description":"<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":356,"description":"<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":444,"description":"<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":588,"description":"<p>Render a 3d model to the screen.</p>\n","itemtype":"method","name":"model","params":[{"name":"model","description":"<p>Loaded 3d model to be rendered</p>\n","type":"p5.Geometry"}],"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d octahedron.","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/material.js","line":12,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"loadShader","params":[{"name":"vertFilename","description":"<p>path to file containing vertex shader\nsource code</p>\n","type":"String"},{"name":"fragFilename","description":"<p>path to file containing fragment shader\nsource code</p>\n","type":"String"},{"name":"callback","description":"<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n","type":"Function","optional":true}],"return":{"description":"a shader object created from the provided\nvertex and fragment shader files.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":111,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"createShader","params":[{"name":"vertSrc","description":"<p>source code for the vertex shader</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader</p>\n","type":"String"}],"return":{"description":"a shader object created from the provided\nvertex and fragment shaders.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":184,"description":"<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"shader","chainable":1,"params":[{"name":"s","description":"<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n","type":"p5.Shader"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":282,"description":"<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n","itemtype":"method","name":"resetShader","chainable":1,"example":["\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"],"alt":"Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":368,"description":"<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"texture","params":[{"name":"tex","description":"<p>image to use as texture</p>\n","type":"p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"}],"chainable":1,"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>","\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>","\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using normalized coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":511,"description":"<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n","itemtype":"method","name":"textureMode","params":[{"name":"mode","description":"<p>either IMAGE or NORMAL</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using image coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":587,"description":"<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n","itemtype":"method","name":"textureWrap","params":[{"name":"wrapX","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant"},{"name":"wrapY","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"],"alt":"an image of the rocky mountains repeated in mirrored tiles","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":659,"description":"<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"normalMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Red, green and blue gradient.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":697,"description":"<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"ambientMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":697,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":757,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":777,"description":"<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n","itemtype":"method","name":"emissiveMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":777,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true},{"name":"a","description":"<p>opacity</p>\n","type":"Number","optional":true}],"chainable":1},{"line":809,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":829,"description":"<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"specularMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"],"alt":"torus with specular material","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":829,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":870,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":882,"params":[{"name":"color","description":"<p>color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":902,"description":"<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n","itemtype":"method","name":"shininess","params":[{"name":"shine","description":"<p>Degree of Shininess.\n                      Defaults to 1.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"],"alt":"Shininess on Camera changes position with mouse","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/p5.Camera.js","line":13,"description":"<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n","itemtype":"method","name":"camera","is_constructor":1,"params":[{"name":"x","description":"<p>camera position value on x axis</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>camera position value on y axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>camera position value on z axis</p>\n","type":"Number","optional":true},{"name":"centerX","description":"<p>x coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerY","description":"<p>y coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerZ","description":"<p>z coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"upX","description":"<p>x component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upY","description":"<p>y component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upZ","description":"<p>z component of direction 'up' from camera</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":115,"description":"<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n","itemtype":"method","name":"perspective","params":[{"name":"fovy","description":"<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n","type":"Number","optional":true},{"name":"aspect","description":"<p>camera frustum aspect ratio</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>frustum near plane length</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>frustum far plane length</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":176,"description":"<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n","itemtype":"method","name":"ortho","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":236,"description":"<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n","itemtype":"method","name":"frustum","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":303,"description":"<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n","itemtype":"method","name":"createCamera","return":{"description":"The newly created camera object.","type":"p5.Camera"},"example":["\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"],"alt":"An example that creates a camera and moves it around the box.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":444,"description":"<p>camera position value on x axis</p>\n","itemtype":"property","name":"eyeX","type":"Number","readonly":"","example":["\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":472,"description":"<p>camera position value on y axis</p>\n","itemtype":"property","name":"eyeY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":499,"description":"<p>camera position value on z axis</p>\n","itemtype":"property","name":"eyeZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":526,"description":"<p>x coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":554,"description":"<p>y coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":582,"description":"<p>z coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":610,"description":"<p>x component of direction 'up' from camera</p>\n","itemtype":"property","name":"upX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":633,"description":"<p>y component of direction 'up' from camera</p>\n","itemtype":"property","name":"upY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":656,"description":"<p>z component of direction 'up' from camera</p>\n","itemtype":"property","name":"upZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":683,"description":"<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"perspective","example":["\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":801,"description":"<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"ortho","example":["\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":897,"description":"<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"frustum","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1040,"description":"<p>Panning rotates the camera view to the left and right.</p>\n","itemtype":"method","name":"pan","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1098,"description":"<p>Tilting rotates the camera view up and down.</p>\n","itemtype":"method","name":"tilt","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view tilts up and down across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1156,"description":"<p>Reorients the camera to look at a position in world space.</p>\n","itemtype":"method","name":"lookAt","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view of rotating 3D cubes changes to look at a new random\npoint every second .","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1223,"description":"<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"camera","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1386,"description":"<p>Move camera along its local axes while maintaining current camera orientation.</p>\n","itemtype":"method","name":"move","params":[{"name":"x","description":"<p>amount to move along camera's left-right axis</p>\n","type":"Number"},{"name":"y","description":"<p>amount to move along camera's up-down axis</p>\n","type":"Number"},{"name":"z","description":"<p>amount to move along camera's forward-backward axis</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"],"alt":"camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1458,"description":"<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n","itemtype":"method","name":"setPosition","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"],"alt":"camera position changes as the user presses keys, altering view of a 3D box","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1723,"description":"<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n","itemtype":"method","name":"setCamera","params":[{"name":"cam","description":"<p>p5.Camera object</p>\n","type":"p5.Camera"}],"example":["\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"Canvas switches between two camera views, each showing a series of spinning\n3D boxes.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Geometry.js","line":71,"description":"<p>computes faces for geometry objects based on the vertices.</p>\n","itemtype":"method","name":"computeFaces","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":114,"description":"<p>computes smooth normals per vertex as an average of each\nface.</p>\n","itemtype":"method","name":"computeNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":153,"description":"<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n","itemtype":"method","name":"averageNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":174,"description":"<p>Averages pole normals.  Used in spherical primitives</p>\n","itemtype":"method","name":"averagePoleNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":267,"description":"<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n","itemtype":"method","name":"normalize","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.RendererGL.js","line":334,"description":"<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n","itemtype":"method","name":"setAttributes","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"],"alt":"a rotating cube with smoother edges","class":"p5","module":"Rendering","submodule":"Rendering","overloads":[{"line":334,"params":[{"name":"key","description":"<p>Name of attribute</p>\n","type":"String"},{"name":"value","description":"<p>New value of named attribute</p>\n","type":"Boolean"}]},{"line":473,"params":[{"name":"obj","description":"<p>object with key-value pairs</p>\n","type":"Object"}]}]},{"file":"src/webgl/p5.Shader.js","line":306,"description":"<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n","itemtype":"method","name":"setUniform","chainable":1,"params":[{"name":"uniformName","description":"<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n","type":"String"},{"name":"data","description":"<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n","type":"Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5.Shader","module":"3D","submodule":"Material"},{"file":"lib/addons/p5.sound.js","line":1,"class":"p5.sound","module":"3D"},{"file":"lib/addons/p5.sound.js","line":52,"description":"<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n","class":"p5.sound","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":159,"description":"<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>","itemtype":"method","name":"getAudioContext","return":{"description":"AudioContext for this sketch","type":"Object"},"example":["\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":198,"description":"<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>","params":[{"name":"element(s)","description":"<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n","type":"Element|Array","optional":true},{"name":"callback","description":"<p>Callback to invoke when the AudioContext\n                              has started</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that resolves when\n                                     the AudioContext state is 'running'","type":"Promise"},"itemtype":"method","name":"userStartAudio","example":["\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":401,"description":"<p>This module has shims</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":536,"description":"<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":726,"description":"<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n","itemtype":"method","name":"getOutputVolume","return":{"description":"Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":738,"description":"<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>","itemtype":"method","name":"outputVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":782,"description":"<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n","itemtype":"property","name":"soundOut","type":"Object","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":807,"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":811,"description":"<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"samplerate samples per second","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":825,"description":"<p>Returns the closest MIDI note value for\na given frequency.</p>\n","itemtype":"method","name":"freqToMidi","params":[{"name":"frequency","description":"<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n","type":"Number"}],"return":{"description":"MIDI note value","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":841,"description":"<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n","itemtype":"method","name":"midiToFreq","params":[{"name":"midiNote","description":"<p>The number of a MIDI note</p>\n","type":"Number"}],"return":{"description":"Frequency value of the given MIDI note","type":"Number"},"example":["\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":925,"description":"<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n","itemtype":"method","name":"soundFormats","params":[{"name":"formats","description":"<p>i.e. 'mp3', 'wav', 'ogg'</p>\n","type":"String","optional":true,"multiple":true}],"example":["\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1040,"description":"<p>Used by Osc and Envelope to chain signal math</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1145,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n","itemtype":"method","name":"saveSound","params":[{"name":"soundFile","description":"<p>p5.SoundFile that you wish to save</p>\n","type":"p5.SoundFile"},{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1662,"description":"<p>Returns true if the sound file finished loading successfully.</p>\n","itemtype":"method","name":"isLoaded","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1679,"description":"<p>Play the p5.SoundFile</p>\n","itemtype":"method","name":"play","params":[{"name":"startTime","description":"<p>(optional) schedule playback to start (in seconds from now).</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) amplitude (volume)\n                                    of playback</p>\n","type":"Number","optional":true},{"name":"cueStart","description":"<p>(optional) cue start time in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) duration of playback in seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1787,"description":"<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n","itemtype":"method","name":"playMode","params":[{"name":"str","description":"<p>'restart' or 'sustain' or 'untilDone'</p>\n","type":"String"}],"example":["\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1847,"description":"<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n","itemtype":"method","name":"pause","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                             seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1905,"description":"<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n","itemtype":"method","name":"loop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            seconds from now</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) playback volume</p>\n","type":"Number","optional":true},{"name":"cueLoopStart","description":"<p>(optional) startTime in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) loop duration in seconds</p>\n","type":"Number","optional":true}],"example":["\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1950,"description":"<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n","itemtype":"method","name":"setLoop","params":[{"name":"Boolean","description":"<p>set looping to true or false</p>\n","type":"Boolean"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1976,"description":"<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n","itemtype":"method","name":"isLooping","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1997,"description":"<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n","itemtype":"method","name":"isPlaying","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2011,"description":"<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n","itemtype":"method","name":"isPaused","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2025,"description":"<p>Stop soundfile playback.</p>\n","itemtype":"method","name":"stop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            in seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2087,"description":"<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n","itemtype":"method","name":"pan","params":[{"name":"panValue","description":"<p>Set the stereo panner</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                                seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2131,"description":"<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n","itemtype":"method","name":"getPan","return":{"description":"Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2146,"description":"<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n","itemtype":"method","name":"rate","params":[{"name":"playbackRate","description":"<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2239,"description":"<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n","itemtype":"method","name":"setVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2276,"description":"<p>Returns the duration of a sound file in seconds.</p>\n","itemtype":"method","name":"duration","return":{"description":"The duration of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2293,"description":"<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n","itemtype":"method","name":"currentTime","return":{"description":"currentTime of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2308,"description":"<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n","itemtype":"method","name":"jump","params":[{"name":"cueTime","description":"<p>cueTime of the soundFile in seconds.</p>\n","type":"Number"},{"name":"duration","description":"<p>duration in seconds.</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2340,"description":"<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n","itemtype":"method","name":"channels","return":{"description":"[channels]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2354,"description":"<p>Return the sample rate of the sound file.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"[sampleRate]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2367,"description":"<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n","itemtype":"method","name":"frames","return":{"description":"[sampleCount]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2381,"description":"<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n","itemtype":"method","name":"getPeaks","params":[{"name":"length","description":"<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n","type":"Number","optional":true}],"return":{"description":"Array of peaks.","type":"Float32Array"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2443,"description":"<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n","itemtype":"method","name":"reverseBuffer","example":["\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2497,"description":"<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended.</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2565,"description":"<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n","itemtype":"method","name":"connect","params":[{"name":"object","description":"<p>Audio object that accepts an input</p>\n","type":"Object","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2590,"description":"<p>Disconnects the output of this p5sound object.</p>\n","itemtype":"method","name":"disconnect","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2604,"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2612,"description":"<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n","itemtype":"method","name":"setPath","params":[{"name":"path","description":"<p>path to audio file</p>\n","type":"String"},{"name":"callback","description":"<p>Callback</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2630,"description":"<p>Replace the current Audio Buffer with a new Buffer.</p>\n","itemtype":"method","name":"setBuffer","params":[{"name":"buf","description":"<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n","type":"Array"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2719,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2790,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2817,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2850,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n","itemtype":"method","name":"save","params":[{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String","optional":true}],"example":["\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2882,"description":"<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n","itemtype":"method","name":"getBlob","return":{"description":"A file-like data object","type":"Blob"},"example":["\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2946,"description":"<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n","itemtype":"method","name":"loadSound","params":[{"name":"path","description":"<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n","type":"Function","optional":true},{"name":"whileLoading","description":"<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a p5.SoundFile","type":"SoundFile"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3117,"description":"<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n","itemtype":"method","name":"setInput","params":[{"name":"snd","description":"<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n","type":"SoundObject|undefined","optional":true},{"name":"smoothing","description":"<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n","type":"Number|undefined","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3209,"description":"<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n","itemtype":"method","name":"getLevel","params":[{"name":"channel","description":"<p>Optionally return only channel 0 (left) or 1 (right)</p>\n","type":"Number","optional":true}],"return":{"description":"Amplitude as a number between 0.0 and 1.0","type":"Number"},"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3264,"description":"<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n","itemtype":"method","name":"toggleNormalize","params":[{"name":"boolean","description":"<p>set normalize to true (1) or false (0)</p>\n","type":"Boolean","optional":true}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3293,"description":"<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"set","description":"<p>smoothing from 0.0 <= 1</p>\n","type":"Number"}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3476,"description":"<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"source","description":"<p>p5.sound object (or web audio API source node)</p>\n","type":"Object","optional":true}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3501,"description":"<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n","itemtype":"method","name":"waveform","params":[{"name":"bins","description":"<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"precision","description":"<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n","type":"String","optional":true}],"return":{"description":"Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3553,"description":"<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n","itemtype":"method","name":"analyze","params":[{"name":"bins","description":"<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"scale","description":"<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n","type":"Number","optional":true}],"return":{"description":"spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.","type":"Array"},"example":["\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3650,"description":"<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n","itemtype":"method","name":"getEnergy","params":[{"name":"frequency1","description":"<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n","type":"Number|String"},{"name":"frequency2","description":"<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n","type":"Number","optional":true}],"return":{"description":"Energy   Energy (volume/amplitude) from\n                            0 and 255.","type":"Number"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3739,"description":"<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n","itemtype":"method","name":"getCentroid","return":{"description":"Spectral Centroid Frequency  of the spectral centroid in Hz.","type":"Number"},"example":["\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3826,"description":"<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"smoothing","description":"<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n","type":"Number"}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3854,"description":"<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"linAverages","params":[{"name":"N","description":"<p>Number of returned frequency groups</p>\n","type":"Number"}],"return":{"description":"linearAverages   Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3889,"description":"<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"logAverages","params":[{"name":"octaveBands","description":"<p>Array of Octave Bands objects for grouping</p>\n","type":"Array"}],"return":{"description":"logAverages    Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3925,"description":"<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n","itemtype":"method","name":"getOctaveBands","params":[{"name":"N","description":"<p>Specifies the 1/N type of generated octave bands</p>\n","type":"Number"},{"name":"fCtr0","description":"<p>Minimum central frequency for the lowest band</p>\n","type":"Number"}],"return":{"description":"octaveBands   Array of octave band objects with their bounds","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4168,"description":"<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>startTime in seconds from now.</p>\n","type":"Number","optional":true},{"name":"frequency","description":"<p>frequency in Hz.</p>\n","type":"Number","optional":true}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4218,"description":"<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n","itemtype":"method","name":"stop","params":[{"name":"secondsFromNow","description":"<p>Time, in seconds from now.</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4238,"description":"<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)","type":"AudioParam"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4271,"description":"<p>Returns the value of output gain</p>\n","itemtype":"method","name":"getAmp","return":{"description":"Amplitude value between 0.0 and 1.0","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4285,"description":"<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n","itemtype":"method","name":"freq","params":[{"name":"Frequency","description":"<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Ramp time (in seconds)</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen\n                                 at x seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency","type":"AudioParam"},"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4360,"description":"<p>Returns the value of frequency of oscillator</p>\n","itemtype":"method","name":"getFreq","return":{"description":"Frequency of oscillator in Hertz","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4373,"description":"<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","type":"String"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4386,"description":"<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"getType","return":{"description":"type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.","type":"String"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4399,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4420,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4444,"description":"<p>Pan between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"pan","params":[{"name":"panning","description":"<p>Number between -1 and 1</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4460,"description":"<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"getPan","return":{"description":"panPosition of oscillator , between Left (-1) and Right (1)","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4494,"description":"<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n","itemtype":"method","name":"phase","params":[{"name":"phase","description":"<p>float between 0.0 and 1.0</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4522,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4543,"description":"<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with multiplied output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4563,"description":"<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4767,"description":"<p>Time until envelope reaches attackLevel</p>\n","itemtype":"property","name":"attackTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4772,"description":"<p>Level once attack is complete.</p>\n","itemtype":"property","name":"attackLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4778,"description":"<p>Time until envelope reaches decayLevel.</p>\n","itemtype":"property","name":"decayTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4784,"description":"<p>Level after decay. The envelope will sustain here until it is released.</p>\n","itemtype":"property","name":"decayLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4790,"description":"<p>Duration of the release portion of the envelope.</p>\n","itemtype":"property","name":"releaseTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4796,"description":"<p>Level at the end of the release.</p>\n","itemtype":"property","name":"releaseLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4833,"description":"<p>Reset the envelope with a series of time/value pairs.</p>\n","itemtype":"method","name":"set","params":[{"name":"attackTime","description":"<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n","type":"Number"},{"name":"attackLevel","description":"<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time</p>\n","type":"Number"},{"name":"decayLevel","description":"<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n","type":"Number"},{"name":"releaseTime","description":"<p>Release Time (in seconds)</p>\n","type":"Number"},{"name":"releaseLevel","description":"<p>Amplitude</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4895,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4964,"description":"<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n","itemtype":"method","name":"setRange","params":[{"name":"aLevel","description":"<p>attack level (defaults to 1)</p>\n","type":"Number"},{"name":"rLevel","description":"<p>release level (defaults to 0)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5037,"description":"<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"inputs","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object","optional":true,"multiple":true}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5055,"description":"<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n","itemtype":"method","name":"setExp","params":[{"name":"isExp","description":"<p>true is exponential, false is linear</p>\n","type":"Boolean"}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5078,"description":"<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>","itemtype":"method","name":"play","params":[{"name":"unit","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object"},{"name":"startTime","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5148,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n","itemtype":"method","name":"triggerAttack","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5256,"description":"<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"triggerRelease","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5350,"description":"<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n","itemtype":"method","name":"ramp","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>When to trigger the ramp</p>\n","type":"Number"},{"name":"v","description":"<p>Target value</p>\n","type":"Number"},{"name":"v2","description":"<p>Second target value</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5460,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5479,"description":"<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5498,"description":"<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5657,"description":"<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'white', 'pink' or 'brown'</p>\n","type":"String","optional":true}],"class":"p5.Noise","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5871,"description":"<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n","itemtype":"method","name":"width","params":[{"name":"width","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.Pulse","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6066,"itemtype":"property","name":"input","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6070,"itemtype":"property","name":"output","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6075,"itemtype":"property","name":"stream","type":"MediaStream|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6080,"itemtype":"property","name":"mediaStream","type":"MediaStreamAudioSourceNode|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6085,"itemtype":"property","name":"currentSource","type":"Number|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6090,"description":"<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n","itemtype":"property","name":"enabled","type":"Boolean","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6098,"description":"<p>Input amplitude, connect to it by default but not to master out</p>\n","itemtype":"property","name":"amplitude","type":"p5.Amplitude","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6114,"description":"<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n","itemtype":"method","name":"start","params":[{"name":"successCallback","description":"<p>Name of a function to call on\n                                  success.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n","type":"Function","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6171,"description":"<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n","itemtype":"method","name":"stop","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6191,"description":"<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>An object that accepts audio input,\n                        such as an FFT</p>\n","type":"Object","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6216,"description":"<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6234,"description":"<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n","itemtype":"method","name":"getLevel","params":[{"name":"smoothing","description":"<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n","type":"Number","optional":true}],"return":{"description":"Volume level (between 0.0 and 1.0)","type":"Number"},"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6257,"description":"<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0</p>\n","type":"Number"},{"name":"time","description":"<p>ramp time (optional)</p>\n","type":"Number","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6280,"description":"<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n","itemtype":"method","name":"getSources","params":[{"name":"successCallback","description":"<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>This optional callback receives the error\n                                   message as its argument.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method","type":"Promise"},"example":["\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6340,"description":"<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n","itemtype":"method","name":"setSource","params":[{"name":"num","description":"<p>position of input source in the array</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6462,"description":"<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6478,"description":"<p>Set the output volume of the filter.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number","optional":true},{"name":"rampTime","description":"<p>create a fade that lasts until rampTime</p>\n","type":"Number","optional":true},{"name":"tFromNow","description":"<p>schedule this event to happen in tFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6502,"description":"<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n","itemtype":"method","name":"chain","params":[{"name":"arguments","description":"<p>Chain together multiple sound objects</p>\n","type":"Object","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6525,"description":"<p>Adjust the dry/wet value.</p>\n","itemtype":"method","name":"drywet","params":[{"name":"fade","description":"<p>The desired drywet value (0 - 1.0)</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6542,"description":"<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6557,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6719,"description":"<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n","itemtype":"property","name":"biquadFilter","type":"DelayNode","class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6742,"description":"<p>Filter an audio signal according to a set\nof filter parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6760,"description":"<p>Set the frequency and the resonance of the filter.</p>\n","itemtype":"method","name":"set","params":[{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance (Q) from 0.001 to 1000</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6781,"description":"<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n","itemtype":"method","name":"freq","params":[{"name":"freq","description":"<p>Filter Frequency</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value  Returns the current frequency value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6811,"description":"<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n","itemtype":"method","name":"res","params":[{"name":"res","description":"<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value Returns the current res value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6838,"description":"<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n","itemtype":"method","name":"gain","params":[{"name":"gain","description":"","type":"Number"}],"return":{"description":"Returns the current or updated gain value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6864,"description":"<p>Toggle function. Switches between the specified type and allpass</p>\n","itemtype":"method","name":"toggle","return":{"description":"[Toggle value]","type":"Boolean"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6884,"description":"<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n","itemtype":"method","name":"setType","params":[{"name":"t","description":"","type":"String"}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7198,"description":"<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n","itemtype":"property","name":"bands","type":"Array","class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7239,"description":"<p>Process an input by connecting it to the EQ</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Audio source</p>\n","type":"Object"}],"class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7629,"description":"<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n","itemtype":"property","name":"panner","type":"AudioNode","class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7654,"description":"<p>Connect an audio sorce</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Input source</p>\n","type":"Object"}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7668,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"set","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7687,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7694,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7701,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7753,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"orient","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7772,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7779,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7786,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7838,"description":"<p>Set the rolloff factor and max distance</p>\n","itemtype":"method","name":"setFalloff","params":[{"name":"maxDistance","description":"","type":"Number","optional":true},{"name":"rolloffFactor","description":"","type":"Number","optional":true}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7852,"description":"<p>Maxium distance between the source and the listener</p>\n","itemtype":"method","name":"maxDist","params":[{"name":"maxDistance","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7869,"description":"<p>How quickly the volume is reduced as the source moves away from the listener</p>\n","itemtype":"method","name":"rollof","params":[{"name":"rolloffFactor","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7989,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"leftDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7999,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"rightDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8049,"description":"<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"delayTime","description":"<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n","type":"Number","optional":true},{"name":"feedback","description":"<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n","type":"Number","optional":true},{"name":"lowPass","description":"<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8094,"description":"<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n","itemtype":"method","name":"delayTime","params":[{"name":"delayTime","description":"<p>Time (in seconds) of the delay</p>\n","type":"Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8116,"description":"<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n","itemtype":"method","name":"feedback","params":[{"name":"feedback","description":"<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n","type":"Number|Object"}],"return":{"description":"Feedback value","type":"Number"},"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8148,"description":"<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n","itemtype":"method","name":"filter","params":[{"name":"cutoffFreq","description":"<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n","type":"Number|Object"},{"name":"res","description":"<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n","type":"Number|Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8170,"description":"<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'pingPong' (1) or 'default' (0)</p>\n","type":"String|Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8223,"description":"<p>Set the output level of the delay effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8234,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8242,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8409,"description":"<p>Connect a source to the reverb, and assign reverb parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"},{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8446,"description":"<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n","itemtype":"method","name":"set","params":[{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8482,"description":"<p>Set the output level of the reverb effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8493,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8501,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8621,"description":"<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n","itemtype":"property","name":"convolverNode","type":"ConvolverNode","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8645,"description":"<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n","itemtype":"property","name":"impulses","type":"Array","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8737,"description":"<p>Connect a source to the convolver.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8786,"description":"<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n","itemtype":"method","name":"addImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8808,"description":"<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n","itemtype":"method","name":"resetImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8831,"description":"<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n","itemtype":"method","name":"toggleImpulse","params":[{"name":"id","description":"<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n","type":"String|Number"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8885,"description":"<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n","itemtype":"method","name":"createConvolver","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true}],"return":{"description":"","type":"p5.Convolver"},"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9084,"description":"<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9173,"description":"<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n","itemtype":"property","name":"sequence","type":"Array","class":"p5.Phrase","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9263,"description":"<p>Set the tempo of this part, in Beats Per Minute.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9278,"description":"<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n","itemtype":"method","name":"getBPM","return":{"description":"","type":"Number"},"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9291,"description":"<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9311,"description":"<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"loop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9333,"description":"<p>Tell the part to stop looping.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9349,"description":"<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n","itemtype":"method","name":"stop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9363,"description":"<p>Pause the part. Playback will resume\nfrom the current step.</p>\n","itemtype":"method","name":"pause","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9379,"description":"<p>Add a p5.Phrase to this Part.</p>\n","itemtype":"method","name":"addPhrase","params":[{"name":"phrase","description":"<p>reference to a p5.Phrase</p>\n","type":"p5.Phrase"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9406,"description":"<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n","itemtype":"method","name":"removePhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9424,"description":"<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n","itemtype":"method","name":"getPhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9442,"description":"<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n","itemtype":"method","name":"replaceSequence","params":[{"name":"phraseName","description":"","type":"String"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9473,"description":"<p>Set the function that will be called at every step. This will clear the previous function.</p>\n","itemtype":"method","name":"onStep","params":[{"name":"callback","description":"<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n","type":"Function"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9542,"description":"<p>Start playback of the score.</p>\n","itemtype":"method","name":"start","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9555,"description":"<p>Stop playback of the score.</p>\n","itemtype":"method","name":"stop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9569,"description":"<p>Pause playback of the score.</p>\n","itemtype":"method","name":"pause","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9581,"description":"<p>Loop playback of the score.</p>\n","itemtype":"method","name":"loop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9594,"description":"<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9628,"description":"<p>Set the tempo for all parts in the score</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9729,"description":"<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n","itemtype":"property","name":"bpm","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9750,"description":"<p>number of quarter notes in a measure (defaults to 4)</p>\n","itemtype":"property","name":"timeSignature","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9770,"description":"<p>length of the loops interval</p>\n","itemtype":"property","name":"interval","type":"Number|String","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9787,"description":"<p>how many times the callback has been called so far</p>\n","itemtype":"property","name":"iterations","type":"Number","readonly":"","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9800,"description":"<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n","itemtype":"property","name":"musicalTimeMode","type":"Boolean","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9808,"description":"<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9816,"description":"<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n","itemtype":"property","name":"maxIterations","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9826,"description":"<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9841,"description":"<p>Start the loop</p>\n","itemtype":"method","name":"start","params":[{"name":"timeFromNow","description":"<p>schedule a starting time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9860,"description":"<p>Stop the loop</p>\n","itemtype":"method","name":"stop","params":[{"name":"timeFromNow","description":"<p>schedule a stopping time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9878,"description":"<p>Pause the loop</p>\n","itemtype":"method","name":"pause","params":[{"name":"timeFromNow","description":"<p>schedule a pausing time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9896,"description":"<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n","itemtype":"method","name":"syncedStart","params":[{"name":"otherLoop","description":"<p>a p5.SoundLoop to sync with</p>\n","type":"Object"},{"name":"timeFromNow","description":"<p>Start the loops in sync after timeFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10068,"description":"<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n","itemtype":"property","name":"compressor","type":"AudioNode","class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10084,"description":"<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Sound source to be connected</p>\n","type":"Object"},{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number","optional":true},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10112,"description":"<p>Set the paramters of a compressor.</p>\n","itemtype":"method","name":"set","params":[{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number"},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number"},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number"},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10152,"description":"<p>Get current attack or set value w/ time ramp</p>\n","itemtype":"method","name":"attack","params":[{"name":"attack","description":"<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10178,"description":"<p>Get current knee or set value w/ time ramp</p>\n","itemtype":"method","name":"knee","params":[{"name":"knee","description":"<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10204,"description":"<p>Get current ratio or set value w/ time ramp</p>\n","itemtype":"method","name":"ratio","params":[{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10228,"description":"<p>Get current threshold or set value w/ time ramp</p>\n","itemtype":"method","name":"threshold","params":[{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10252,"description":"<p>Get current release or set value w/ time ramp</p>\n","itemtype":"method","name":"release","params":[{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10277,"description":"<p>Return the current reduction value</p>\n","itemtype":"method","name":"reduction","return":{"description":"Value of the amount of gain reduction that is applied to the signal","type":"Number"},"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10419,"description":"<p>isDetected is set to true when a peak is detected.</p>\n","itemtype":"attribute","name":"isDetected","type":"Boolean","default":"false","class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10432,"description":"<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n","itemtype":"method","name":"update","params":[{"name":"fftObject","description":"<p>A p5.FFT object</p>\n","type":"p5.FFT"}],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10470,"description":"<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n","itemtype":"method","name":"onPeak","params":[{"name":"callback","description":"<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n","type":"Function"},{"name":"val","description":"<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n","type":"Object","optional":true}],"example":["\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10676,"description":"<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"unit","description":"<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n","type":"Object","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10703,"description":"<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n","itemtype":"method","name":"record","params":[{"name":"soundFile","description":"<p>p5.SoundFile</p>\n","type":"p5.SoundFile"},{"name":"duration","description":"<p>Time (in seconds)</p>\n","type":"Number","optional":true},{"name":"callback","description":"<p>The name of a function that will be\n                              called once the recording completes</p>\n","type":"Function","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10739,"description":"<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n","itemtype":"method","name":"stop","class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10864,"description":"<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n","itemtype":"property","name":"WaveShaperNode","type":"AudioNode","class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10883,"description":"<p>Process a sound source, optionally specify amount and oversample values.</p>\n","itemtype":"method","name":"process","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10900,"description":"<p>Set the amount and oversample of the waveshaper distortion.</p>\n","itemtype":"method","name":"set","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10923,"description":"<p>Return the distortion amount, typically between 0-1.</p>\n","itemtype":"method","name":"getAmount","return":{"description":"Unbounded distortion amount.\n                 Normal values range from 0-1.","type":"Number"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10937,"description":"<p>Return the oversampling.</p>\n","itemtype":"method","name":"getOversample","return":{"description":"Oversample can either be 'none', '2x', or '4x'.","type":"String"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11055,"description":"<p>Connect a source to the gain node.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11070,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11084,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11098,"description":"<p>Set the output level of the gain node.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11181,"description":"<p>Connect to p5 objects or Web Audio Nodes</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11194,"description":"<p>Disconnect from soundOut</p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11322,"description":"<p>Getters and Setters</p>\n","itemtype":"property","name":"attack","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11328,"itemtype":"property","name":"decay","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11333,"itemtype":"property","name":"sustain","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11338,"itemtype":"property","name":"release","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11379,"description":"<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11431,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true}],"itemtype":"method","name":"triggerAttack","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11478,"description":"<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","params":[{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"itemtype":"method","name":"triggerRelease","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11516,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11544,"description":"<p>MonoSynth amp</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>desired volume</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Time to reach new volume</p>\n","type":"Number","optional":true}],"return":{"description":"new volume value","type":"Number"},"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11564,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11578,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11592,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11742,"description":"<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n","itemtype":"property","name":"notes","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11755,"description":"<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n","itemtype":"property","name":"polyvalue","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11761,"description":"<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n","itemtype":"property","name":"AudioVoice","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11800,"description":"<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11849,"description":"<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n","itemtype":"method","name":"noteADSR","params":[{"name":"note","description":"<p>Midi note on which ADSR should be set.</p>\n","type":"Number","optional":true},{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11881,"description":"<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11909,"description":"<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","itemtype":"method","name":"noteAttack","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)/</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12021,"description":"<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"noteRelease","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12105,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12119,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12133,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"}],"warnings":[{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:120"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:216"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:316"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:457"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:1001"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:223"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:248"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/validate_params.js:336"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:12"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:81"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:115"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:184"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:219"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:259"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:331"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:13"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:92"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:130"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:185"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:264"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:358"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:398"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:493"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:20"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:67"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:293"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:415"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:460"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:524"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:583"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:668"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:733"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:826"},{"message":"unknown tag: alt","line":" src/core/constants.js:66"},{"message":"unknown tag: alt","line":" src/core/constants.js:84"},{"message":"unknown tag: alt","line":" src/core/constants.js:102"},{"message":"unknown tag: alt","line":" src/core/constants.js:120"},{"message":"unknown tag: alt","line":" src/core/constants.js:138"},{"message":"unknown tag: alt","line":" src/core/environment.js:20"},{"message":"unknown tag: alt","line":" src/core/environment.js:52"},{"message":"unknown tag: alt","line":" src/core/environment.js:79"},{"message":"unknown tag: alt","line":" src/core/environment.js:129"},{"message":"unknown tag: alt","line":" src/core/environment.js:160"},{"message":"unknown tag: alt","line":" src/core/environment.js:228"},{"message":"unknown tag: alt","line":" src/core/environment.js:331"},{"message":"unknown tag: alt","line":" src/core/environment.js:354"},{"message":"unknown tag: alt","line":" src/core/environment.js:372"},{"message":"unknown tag: alt","line":" src/core/environment.js:390"},{"message":"unknown tag: alt","line":" src/core/environment.js:405"},{"message":"unknown tag: alt","line":" src/core/environment.js:421"},{"message":"unknown tag: alt","line":" src/core/environment.js:500"},{"message":"unknown tag: alt","line":" src/core/environment.js:550"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:586"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:660"},{"message":"unknown tag: alt","line":" src/core/environment.js:691"},{"message":"unknown tag: alt","line":" src/core/environment.js:713"},{"message":"replacing incorrect tag: function with method","line":" src/core/internationalization.js:105"},{"message":"replacing incorrect tag: returns with return","line":" src/core/internationalization.js:105"},{"message":"unknown tag: alt","line":" src/core/main.js:42"},{"message":"unknown tag: alt","line":" src/core/main.js:83"},{"message":"unknown tag: alt","line":" src/core/main.js:114"},{"message":"unknown tag: alt","line":" src/core/main.js:415"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:47"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:114"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:154"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:189"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:246"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:292"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:354"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:403"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:454"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:510"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:551"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:592"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:639"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:678"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:725"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:763"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:70"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:122"},{"message":"unknown tag: alt","line":" src/core/reference.js:7"},{"message":"unknown tag: alt","line":" src/core/reference.js:34"},{"message":"unknown tag: alt","line":" src/core/reference.js:87"},{"message":"unknown tag: alt","line":" src/core/reference.js:115"},{"message":"unknown tag: alt","line":" src/core/reference.js:137"},{"message":"unknown tag: alt","line":" src/core/reference.js:158"},{"message":"unknown tag: alt","line":" src/core/reference.js:179"},{"message":"unknown tag: alt","line":" src/core/reference.js:200"},{"message":"unknown tag: alt","line":" src/core/reference.js:231"},{"message":"unknown tag: alt","line":" src/core/reference.js:267"},{"message":"unknown tag: alt","line":" src/core/reference.js:288"},{"message":"unknown tag: alt","line":" src/core/reference.js:309"},{"message":"unknown tag: alt","line":" src/core/reference.js:331"},{"message":"unknown tag: alt","line":" src/core/reference.js:351"},{"message":"unknown tag: alt","line":" src/core/reference.js:379"},{"message":"unknown tag: alt","line":" src/core/reference.js:408"},{"message":"unknown tag: alt","line":" src/core/reference.js:448"},{"message":"unknown tag: alt","line":" src/core/reference.js:490"},{"message":"unknown tag: alt","line":" src/core/reference.js:512"},{"message":"unknown tag: alt","line":" src/core/rendering.js:15"},{"message":"unknown tag: alt","line":" src/core/rendering.js:125"},{"message":"unknown tag: alt","line":" src/core/rendering.js:183"},{"message":"unknown tag: alt","line":" src/core/rendering.js:204"},{"message":"unknown tag: alt","line":" src/core/rendering.js:243"},{"message":"unknown tag: alt","line":" src/core/rendering.js:326"},{"message":"unknown tag: alt","line":" src/core/structure.js:10"},{"message":"unknown tag: alt","line":" src/core/structure.js:83"},{"message":"unknown tag: alt","line":" src/core/structure.js:134"},{"message":"unknown tag: alt","line":" src/core/structure.js:192"},{"message":"unknown tag: alt","line":" src/core/structure.js:290"},{"message":"unknown tag: alt","line":" src/core/structure.js:391"},{"message":"unknown tag: alt","line":" src/core/structure.js:497"},{"message":"unknown tag: alt","line":" src/core/transform.js:11"},{"message":"unknown tag: alt","line":" src/core/transform.js:168"},{"message":"unknown tag: alt","line":" src/core/transform.js:193"},{"message":"unknown tag: alt","line":" src/core/transform.js:232"},{"message":"unknown tag: alt","line":" src/core/transform.js:268"},{"message":"unknown tag: alt","line":" src/core/transform.js:304"},{"message":"unknown tag: alt","line":" src/core/transform.js:342"},{"message":"unknown tag: alt","line":" src/core/transform.js:416"},{"message":"unknown tag: alt","line":" src/core/transform.js:455"},{"message":"unknown tag: alt","line":" src/core/transform.js:494"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:10"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:101"},{"message":"unknown tag: alt","line":" src/dom/dom.js:204"},{"message":"unknown tag: alt","line":" src/dom/dom.js:271"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1560"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1622"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1726"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1765"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1885"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2268"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2778"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:23"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:46"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:69"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:135"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:168"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:201"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:239"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:285"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:330"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:389"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:428"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:471"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:515"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:546"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:604"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:10"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:36"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:64"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:103"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:190"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:243"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:308"},{"message":"unknown tag: alt","line":" src/events/mouse.js:12"},{"message":"unknown tag: alt","line":" src/events/mouse.js:43"},{"message":"unknown tag: alt","line":" src/events/mouse.js:80"},{"message":"unknown tag: alt","line":" src/events/mouse.js:106"},{"message":"unknown tag: alt","line":" src/events/mouse.js:132"},{"message":"unknown tag: alt","line":" src/events/mouse.js:164"},{"message":"unknown tag: alt","line":" src/events/mouse.js:195"},{"message":"unknown tag: alt","line":" src/events/mouse.js:233"},{"message":"unknown tag: alt","line":" src/events/mouse.js:271"},{"message":"unknown tag: alt","line":" src/events/mouse.js:311"},{"message":"unknown tag: alt","line":" src/events/mouse.js:351"},{"message":"unknown tag: alt","line":" src/events/mouse.js:389"},{"message":"unknown tag: alt","line":" src/events/mouse.js:481"},{"message":"unknown tag: alt","line":" src/events/mouse.js:535"},{"message":"unknown tag: alt","line":" src/events/mouse.js:615"},{"message":"unknown tag: alt","line":" src/events/mouse.js:696"},{"message":"unknown tag: alt","line":" src/events/mouse.js:772"},{"message":"unknown tag: alt","line":" src/events/mouse.js:841"},{"message":"unknown tag: alt","line":" src/events/mouse.js:926"},{"message":"unknown tag: alt","line":" src/events/mouse.js:979"},{"message":"unknown tag: alt","line":" src/events/mouse.js:1025"},{"message":"unknown tag: alt","line":" src/events/touch.js:10"},{"message":"unknown tag: alt","line":" src/events/touch.js:71"},{"message":"unknown tag: alt","line":" src/events/touch.js:151"},{"message":"unknown tag: alt","line":" src/events/touch.js:223"},{"message":"unknown tag: alt","line":" src/image/image.js:15"},{"message":"unknown tag: alt","line":" src/image/image.js:94"},{"message":"unknown tag: alt","line":" src/image/image.js:413"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:18"},{"message":"replacing incorrect tag: returns with return","line":" src/image/loading_displaying.js:284"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:301"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:471"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:569"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:633"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:88"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:115"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:152"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:261"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:296"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:346"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:400"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:437"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:548"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:603"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:665"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:738"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:859"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:900"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:941"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:972"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1017"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1052"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1089"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1125"},{"message":"unknown tag: alt","line":" src/image/pixels.js:12"},{"message":"unknown tag: alt","line":" src/image/pixels.js:80"},{"message":"unknown tag: alt","line":" src/image/pixels.js:173"},{"message":"unknown tag: alt","line":" src/image/pixels.js:307"},{"message":"unknown tag: alt","line":" src/image/pixels.js:481"},{"message":"unknown tag: alt","line":" src/image/pixels.js:566"},{"message":"unknown tag: alt","line":" src/image/pixels.js:602"},{"message":"unknown tag: alt","line":" src/image/pixels.js:674"},{"message":"unknown tag: alt","line":" src/io/files.js:20"},{"message":"unknown tag: alt","line":" src/io/files.js:183"},{"message":"unknown tag: alt","line":" src/io/files.js:303"},{"message":"unknown tag: alt","line":" src/io/files.js:583"},{"message":"replacing incorrect tag: returns with return","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:1393"},{"message":"unknown tag: alt","line":" src/io/files.js:1535"},{"message":"unknown tag: alt","line":" src/io/files.js:1592"},{"message":"unknown tag: alt","line":" src/io/files.js:1656"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:85"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:148"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:195"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:240"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:288"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:352"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:545"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:597"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:638"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:896"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:960"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1009"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1055"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1100"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1146"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1190"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1242"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1305"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:40"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:102"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:146"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:191"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:239"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:295"},{"message":"unknown tag: alt","line":" src/io/p5.XML.js:9"},{"message":"unknown tag: alt","line":" src/math/calculation.js:10"},{"message":"unknown tag: alt","line":" src/math/calculation.js:33"},{"message":"unknown tag: alt","line":" src/math/calculation.js:72"},{"message":"unknown tag: alt","line":" src/math/calculation.js:116"},{"message":"unknown tag: alt","line":" src/math/calculation.js:182"},{"message":"unknown tag: alt","line":" src/math/calculation.js:231"},{"message":"unknown tag: alt","line":" src/math/calculation.js:269"},{"message":"unknown tag: alt","line":" src/math/calculation.js:316"},{"message":"unknown tag: alt","line":" src/math/calculation.js:371"},{"message":"unknown tag: alt","line":" src/math/calculation.js:409"},{"message":"unknown tag: alt","line":" src/math/calculation.js:464"},{"message":"unknown tag: alt","line":" src/math/calculation.js:512"},{"message":"unknown tag: alt","line":" src/math/calculation.js:560"},{"message":"unknown tag: alt","line":" src/math/calculation.js:612"},{"message":"unknown tag: alt","line":" src/math/calculation.js:646"},{"message":"unknown tag: alt","line":" src/math/calculation.js:701"},{"message":"unknown tag: alt","line":" src/math/calculation.js:745"},{"message":"replacing incorrect tag: returns with return","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/math.js:10"},{"message":"unknown tag: alt","line":" src/math/noise.js:36"},{"message":"unknown tag: alt","line":" src/math/noise.js:178"},{"message":"unknown tag: alt","line":" src/math/noise.js:243"},{"message":"unknown tag: alt","line":" src/math/p5.Vector.js:10"},{"message":"unknown tag: alt","line":" src/math/random.js:37"},{"message":"unknown tag: alt","line":" src/math/random.js:66"},{"message":"unknown tag: alt","line":" src/math/random.js:153"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:123"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:159"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:186"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:213"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:285"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:320"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:335"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:350"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:11"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:81"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:118"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:150"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:187"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:16"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:140"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:231"},{"message":"unknown tag: alt","line":" src/typography/p5.Font.js:31"},{"message":"unknown tag: alt","line":" src/utilities/conversion.js:10"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:15"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:43"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:130"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:237"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:311"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:373"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:451"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:537"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:10"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:31"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:52"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:73"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:100"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:122"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:143"},{"message":"unknown tag: alt","line":" src/webgl/3d_primitives.js:13"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:11"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:353"},{"message":"unknown tag: alt","line":" src/webgl/light.js:11"},{"message":"unknown tag: alt","line":" src/webgl/light.js:92"},{"message":"unknown tag: alt","line":" src/webgl/light.js:177"},{"message":"unknown tag: alt","line":" src/webgl/light.js:280"},{"message":"unknown tag: alt","line":" src/webgl/light.js:387"},{"message":"unknown tag: alt","line":" src/webgl/light.js:425"},{"message":"unknown tag: alt","line":" src/webgl/light.js:519"},{"message":"unknown tag: alt","line":" src/webgl/light.js:859"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:588"},{"message":"unknown tag: alt","line":" src/webgl/material.js:12"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:184"},{"message":"unknown tag: alt","line":" src/webgl/material.js:282"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:587"},{"message":"unknown tag: alt","line":" src/webgl/material.js:659"},{"message":"unknown tag: alt","line":" src/webgl/material.js:697"},{"message":"unknown tag: alt","line":" src/webgl/material.js:777"},{"message":"unknown tag: alt","line":" src/webgl/material.js:829"},{"message":"unknown tag: alt","line":" src/webgl/material.js:902"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:13"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:115"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:176"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:236"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:303"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:357"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:444"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:472"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:499"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:526"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:554"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:582"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:610"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:633"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:656"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:683"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:801"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:897"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1040"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1098"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1156"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1386"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1458"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1723"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:334"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:603"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:644"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:749"},{"message":"unknown tag: alt","line":" src/webgl/p5.Shader.js:306"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:115"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:158"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:191"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:203"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:236"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:250"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:456"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:471"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:556"},{"message":"replacing incorrect tag: params with param","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2882"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4271"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4360"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4386"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4460"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:6280"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:8116"},{"message":"Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.","line":" src/color/color_conversion.js:8"},{"message":"Missing item type\nConvert an HSBA array to HSLA.","line":" src/color/color_conversion.js:19"},{"message":"Missing item type\nConvert an HSBA array to RGBA.","line":" src/color/color_conversion.js:45"},{"message":"Missing item type\nConvert an HSLA array to HSBA.","line":" src/color/color_conversion.js:100"},{"message":"Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.","line":" src/color/color_conversion.js:123"},{"message":"Missing item type\nConvert an RGBA array to HSBA.","line":" src/color/color_conversion.js:187"},{"message":"Missing item type\nConvert an RGBA array to HSLA.","line":" src/color/color_conversion.js:226"},{"message":"Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.","line":" src/color/p5.Color.js:396"},{"message":"Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.","line":" src/color/p5.Color.js:427"},{"message":"Missing item type\nCSS named colors.","line":" src/color/p5.Color.js:446"},{"message":"Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.","line":" src/color/p5.Color.js:600"},{"message":"Missing item type\nFull color string patterns. The capture groups are necessary.","line":" src/color/p5.Color.js:613"},{"message":"Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.","line":" src/color/p5.Color.js:750"},{"message":"Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.","line":" src/color/p5.Color.js:960"},{"message":"Missing item type","line":" src/core/friendly_errors/fes_core.js:1"},{"message":"Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.","line":" src/core/friendly_errors/fes_core.js:915"},{"message":"Missing item type","line":" src/core/friendly_errors/file_errors.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/sketch_reader.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/stacktrace.js:1"},{"message":"Missing item type\nGiven an Error object, extract the most information from it.","line":" src/core/friendly_errors/stacktrace.js:34"},{"message":"Missing item type","line":" src/core/friendly_errors/validate_params.js:1"},{"message":"Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).","line":" src/core/shape/2d_primitives.js:16"},{"message":"Missing item type\nReturns the current framerate.","line":" src/core/environment.js:305"},{"message":"Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.","line":" src/core/environment.js:315"},{"message":"Missing item type","line":" src/core/helpers.js:1"},{"message":"Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing","line":" src/core/init.js:4"},{"message":"Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.","line":" src/core/internationalization.js:30"},{"message":"Missing item type\nSet up our translation function, with loaded languages","line":" src/core/internationalization.js:126"},{"message":"Missing item type\nReturns a list of languages we have translations loaded for","line":" src/core/internationalization.js:171"},{"message":"Missing item type\nReturns the current language selected for translation","line":" src/core/internationalization.js:178"},{"message":"Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.","line":" src/core/internationalization.js:185"},{"message":"Missing item type","line":" src/core/legacy.js:1"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/core/p5.Element.js:827"},{"message":"Missing item type\nResize our canvas element.","line":" src/core/p5.Renderer.js:99"},{"message":"Missing item type\nHelper function to check font type (system or otf)","line":" src/core/p5.Renderer.js:415"},{"message":"Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178","line":" src/core/p5.Renderer.js:467"},{"message":"Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer","line":" src/core/p5.Renderer2D.js:7"},{"message":"Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.","line":" src/core/p5.Renderer2D.js:402"},{"message":"Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.","line":" src/core/shim.js:18"},{"message":"Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign","line":" src/core/shim.js:39"},{"message":"Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()","line":" src/data/p5.TypedDict.js:197"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:387"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:425"},{"message":"Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:536"},{"message":"Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:600"},{"message":"Missing item type\nHelper function for select and selectAll","line":" src/dom/dom.js:127"},{"message":"Missing item type\nHelper function for getElement and getElements.","line":" src/dom/dom.js:142"},{"message":"Missing item type\nHelpers for create methods.","line":" src/dom/dom.js:309"},{"message":"Missing item type","line":" src/dom/dom.js:450"},{"message":"Missing item type","line":" src/dom/dom.js:1164"},{"message":"Missing item type","line":" src/dom/dom.js:1257"},{"message":"Missing item type","line":" src/dom/dom.js:1296"},{"message":"Missing item type","line":" src/dom/dom.js:3232"},{"message":"Missing item type","line":" src/dom/dom.js:3298"},{"message":"Missing item type","line":" src/dom/dom.js:3360"},{"message":"Missing item type\n_updatePAccelerations updates the pAcceleration values","line":" src/events/acceleration.js:124"},{"message":"Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.","line":" src/events/keyboard.js:298"},{"message":"Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.","line":" src/events/keyboard.js:384"},{"message":"Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.","line":" src/image/filters.js:3"},{"message":"Missing item type\nReturns the pixel buffer for a canvas","line":" src/image/filters.js:24"},{"message":"Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.","line":" src/image/filters.js:60"},{"message":"Missing item type\nModifies pixels RGBA values to values contained in the data object.","line":" src/image/filters.js:81"},{"message":"Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData","line":" src/image/filters.js:101"},{"message":"Missing item type\nReturns a blank ImageData object.","line":" src/image/filters.js:121"},{"message":"Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.","line":" src/image/filters.js:136"},{"message":"Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:189"},{"message":"Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:223"},{"message":"Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.","line":" src/image/filters.js:246"},{"message":"Missing item type\nSets each pixel to its inverse value. No parameter is used.","line":" src/image/filters.js:262"},{"message":"Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation","line":" src/image/filters.js:277"},{"message":"Missing item type\nreduces the bright areas in an image","line":" src/image/filters.js:309"},{"message":"Missing item type\nincreases the bright areas in an image","line":" src/image/filters.js:396"},{"message":"Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.","line":" src/image/image.js:8"},{"message":"Missing item type\nHelper function for loading GIF-based images","line":" src/image/loading_displaying.js:162"},{"message":"Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height","line":" src/image/loading_displaying.js:284"},{"message":"Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.","line":" src/image/loading_displaying.js:597"},{"message":"Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.","line":" src/image/p5.Image.js:9"},{"message":"Missing item type\nHelper function for animating GIF-based images with time","line":" src/image/p5.Image.js:222"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/image/p5.Image.js:253"},{"message":"Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.","line":" src/io/files.js:1789"},{"message":"Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.","line":" src/io/files.js:1857"},{"message":"Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.","line":" src/io/files.js:1890"},{"message":"Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.","line":" src/io/files.js:1902"},{"message":"Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","line":" src/io/p5.Table.js:9"},{"message":"Missing item type\nMultiplies a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2135"},{"message":"Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.","line":" src/math/p5.Vector.js:2187"},{"message":"Missing item type\nDivides a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2214"},{"message":"Missing item type\nCalculates the dot product of two vectors.","line":" src/math/p5.Vector.js:2267"},{"message":"Missing item type\nCalculates the cross product of two vectors.","line":" src/math/p5.Vector.js:2281"},{"message":"Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).","line":" src/math/p5.Vector.js:2295"},{"message":"Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.","line":" src/math/p5.Vector.js:2310"},{"message":"Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)","line":" src/math/p5.Vector.js:2339"},{"message":"Missing item type\nNormalize the vector to length 1 (make it a unit vector).","line":" src/math/p5.Vector.js:2357"},{"message":"Missing item type\nHelper function to measure ascent and descent.","line":" src/typography/attributes.js:280"},{"message":"Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.","line":" src/typography/p5.Font.js:273"},{"message":"Missing item type\nReturns an opentype path for the supplied string and position.","line":" src/typography/p5.Font.js:288"},{"message":"Missing item type","line":" src/webgl/3d_primitives.js:301"},{"message":"Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.","line":" src/webgl/3d_primitives.js:955"},{"message":"Missing item type\nDraw a line given two points","line":" src/webgl/3d_primitives.js:1393"},{"message":"Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1","line":" src/webgl/loading.js:179"},{"message":"Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.","line":" src/webgl/loading.js:290"},{"message":"Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.","line":" src/webgl/loading.js:317"},{"message":"Missing item type\nThis function matches the `query` at the provided `offset`","line":" src/webgl/loading.js:344"},{"message":"Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.","line":" src/webgl/loading.js:356"},{"message":"Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`","line":" src/webgl/loading.js:444"},{"message":"Missing item type","line":" src/webgl/material.js:947"},{"message":"Missing item type","line":" src/webgl/material.js:978"},{"message":"Missing item type\nCreate a 2D array for establishing stroke connections","line":" src/webgl/p5.Geometry.js:212"},{"message":"Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU","line":" src/webgl/p5.Geometry.js:233"},{"message":"Missing item type","line":" src/webgl/p5.Matrix.js:1"},{"message":"Missing item type\nPRIVATE","line":" src/webgl/p5.Matrix.js:722"},{"message":"Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.","line":" src/webgl/p5.RenderBuffer.js:12"},{"message":"Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.","line":" src/webgl/p5.RendererGL.Immediate.js:1"},{"message":"Missing item type\nEnd shape drawing and render vertices to screen.","line":" src/webgl/p5.RendererGL.Immediate.js:129"},{"message":"Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:169"},{"message":"Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:248"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:268"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:302"},{"message":"Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.","line":" src/webgl/p5.RendererGL.Retained.js:59"},{"message":"Missing item type\nDraws buffers given a geometry key ID","line":" src/webgl/p5.RendererGL.Retained.js:110"},{"message":"Missing item type\nmodel view, projection, & normal\nmatrices","line":" src/webgl/p5.RendererGL.js:117"},{"message":"Missing item type\n[background description]","line":" src/webgl/p5.RendererGL.js:586"},{"message":"Missing item type\n[resize description]","line":" src/webgl/p5.RendererGL.js:860"},{"message":"Missing item type\nclears color and depth buffers\nwith r,g,b,a","line":" src/webgl/p5.RendererGL.js:890"},{"message":"Missing item type\n[translate description]","line":" src/webgl/p5.RendererGL.js:924"},{"message":"Missing item type\nScales the Model View Matrix by a vector","line":" src/webgl/p5.RendererGL.js:943"},{"message":"Missing item type\nturn a two dimensional array into one dimensional array","line":" src/webgl/p5.RendererGL.js:1366"},{"message":"Missing item type\nturn a p5.Vector Array into a one dimensional number array","line":" src/webgl/p5.RendererGL.js:1403"},{"message":"Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.","line":" src/webgl/p5.RendererGL.js:1421"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:1"},{"message":"Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/","line":" lib/addons/p5.sound.js:52"},{"message":"Missing item type\nThis module has shims","line":" lib/addons/p5.sound.js:401"},{"message":"Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats","line":" lib/addons/p5.sound.js:536"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:807"},{"message":"Missing item type\nUsed by Osc and Envelope to chain signal math","line":" lib/addons/p5.sound.js:1040"},{"message":"Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.","line":" lib/addons/p5.sound.js:1542"},{"message":"Missing item type\nStop playback on all of this soundfile's sources.","line":" lib/addons/p5.sound.js:2056"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:2604"},{"message":"Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade","line":" lib/addons/p5.sound.js:6455"},{"message":"Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter","line":" lib/addons/p5.sound.js:6462"},{"message":"Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ","line":" lib/addons/p5.sound.js:7009"},{"message":"Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.","line":" lib/addons/p5.sound.js:8508"},{"message":"Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.","line":" lib/addons/p5.sound.js:8659"},{"message":"Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string","line":" lib/addons/p5.sound.js:9808"},{"message":"Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached","line":" lib/addons/p5.sound.js:9826"},{"message":"Missing item type\ncallback invoked when the recording is over","line":" lib/addons/p5.sound.js:10660"},{"message":"Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release","line":" lib/addons/p5.sound.js:11995"},{"message":"Missing item type","line":" lib/addons/p5.sound.min.js:1"}],"consts":{"LABEL":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"FALLBACK":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"RGB":["p5.colorMode"],"HSB":["p5.colorMode"],"HSL":["p5.colorMode"],"CHORD":["p5.arc"],"PIE":["p5.arc"],"OPEN":["p5.arc"],"CENTER":["p5.ellipseMode","p5.rectMode","p5.imageMode","p5.textAlign"],"RADIUS":["p5.ellipseMode","p5.rectMode"],"CORNER":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"CORNERS":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"ROUND":["p5.strokeCap","p5.strokeJoin"],"SQUARE":["p5.strokeCap"],"PROJECT":["p5.strokeCap"],"MITER":["p5.strokeJoin"],"BEVEL":["p5.strokeJoin"],"POINTS":["p5.beginShape"],"LINES":["p5.beginShape"],"TRIANGLES":["p5.beginShape"],"TRIANGLE_FAN":["p5.beginShape"],"TRIANGLE_STRIP":["p5.beginShape"],"QUADS":["p5.beginShape"],"QUAD_STRIP":["p5.beginShape"],"TESS":["p5.beginShape"],"CLOSE":["p5.endShape"],"ARROW":["p5.cursor"],"CROSS":["p5.cursor"],"HAND":["p5.cursor"],"MOVE":["p5.cursor"],"TEXT":["p5.cursor"],"P2D":["p5.createCanvas","p5.createGraphics"],"WEBGL":["p5.createCanvas","p5.createGraphics"],"BLEND":["p5.blendMode","p5.Image.blend","p5.blend"],"DARKEST":["p5.blendMode","p5.Image.blend","p5.blend"],"LIGHTEST":["p5.blendMode","p5.Image.blend","p5.blend"],"DIFFERENCE":["p5.blendMode","p5.Image.blend","p5.blend"],"MULTIPLY":["p5.blendMode","p5.Image.blend","p5.blend"],"EXCLUSION":["p5.blendMode","p5.Image.blend","p5.blend"],"SCREEN":["p5.blendMode","p5.Image.blend","p5.blend"],"REPLACE":["p5.blendMode","p5.Image.blend","p5.blend"],"OVERLAY":["p5.blendMode","p5.Image.blend","p5.blend"],"HARD_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"SOFT_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"DODGE":["p5.blendMode","p5.Image.blend","p5.blend"],"BURN":["p5.blendMode","p5.Image.blend","p5.blend"],"ADD":["p5.blendMode","p5.Image.blend","p5.blend"],"REMOVE":["p5.blendMode"],"SUBTRACT":["p5.blendMode"],"VIDEO":["p5.createCapture"],"AUDIO":["p5.createCapture"],"THRESHOLD":["p5.Image.filter","p5.filter"],"GRAY":["p5.Image.filter","p5.filter"],"OPAQUE":["p5.Image.filter","p5.filter"],"INVERT":["p5.Image.filter","p5.filter"],"POSTERIZE":["p5.Image.filter","p5.filter"],"ERODE":["p5.Image.filter","p5.filter"],"DILATE":["p5.Image.filter","p5.filter"],"BLUR":["p5.Image.filter","p5.filter"],"NORMAL":["p5.Image.blend","p5.blend","p5.textStyle","p5.textureMode"],"RADIANS":["p5.angleMode"],"DEGREES":["p5.angleMode"],"LEFT":["p5.textAlign"],"RIGHT":["p5.textAlign"],"TOP":["p5.textAlign"],"BOTTOM":["p5.textAlign"],"BASELINE":["p5.textAlign"],"ITALIC":["p5.textStyle"],"BOLD":["p5.textStyle"],"BOLDITALIC":["p5.textStyle"],"WORD":["p5.textWrap"],"CHAR":["p5.textWrap"],"IMAGE":["p5.textureMode"],"CLAMP":["p5.textureWrap"],"REPEAT":["p5.textureWrap"],"MIRROR":["p5.textureWrap"]}}
            \ No newline at end of file
            diff --git a/dist/es/reference/index.html b/dist/es/reference/index.html
            new file mode 100644
            index 0000000000..e6f76d1f63
            --- /dev/null
            +++ b/dist/es/reference/index.html
            @@ -0,0 +1,294 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">reference | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="reference-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Reference</h1>
            +
            +      <div id="search" class="search-wrapper" role="search"></div>
            +      <div id="collection-list-nav"></div>
            +
            +          <!--class="container-fluid"-->
            +      <div id="list" tabindex="2" class="list-wrapper allItems-collection"></div>
            +      <div id="item" tabindex="1" class="item-wrapper apidocs"></div>
            +      <div id="file" class="file-wrapper"></div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  <script src='/assets/js/p5.min.js?v=fbf148'></script>
            +  <script src='/assets/js/p5.sound.min.js?v=53b7c5'></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
            +  <script src="/assets/js/vendor/require.min.js"></script>
            +  <script src="/assets/js/render.js?v=56ab24"></script>
            +  <script src="/assets/js/reference.js?v=c69268"></script>
            +
            +  <script>
            +
            +    var translations;
            +
            +    $(document).ready(function() {
            +      var routes = window.location.pathname.split('/');
            +      var lang = routes[1];
            +      if (langs.indexOf(lang) != -1) {
            +        $.getJSON('/assets/reference/'+lang+'.json', function(data) {
            +          translations = data;
            +
            +          window.addEventListener('reference-rendered', function() {
            +            console.log("rendered");
            +            updateLanguage();
            +          }, false);
            +        });
            +      }
            +    });
            +
            +    function removePlaceholder() {
            +      $('#search input').attr('placeholder', '');
            +    }
            +
            +    function updateLanguage() {
            +      if (translations) {
            +        // reference title
            +        $('h1').html(translations['h1']);
            +        $('#search input').attr('placeholder', translations['reference-search']);
            +        $('#search input').on('focus', removePlaceholder);
            +        $('#search input').focusout(function () {
            +          $('#search input').attr('placeholder', translations['reference-search']);
            +        })
            +        $('#search input').attr('title', translations['reference-search']);
            +        // reference description
            +        $('#reference-description1').html(translations['reference-description1']);
            +        $('#reference-description2').html(translations['reference-description2']);
            +        $('#reference-description3').html(translations['reference-description3']);
            +        $('#reference-description4').html(translations['reference-description4']);
            +        // reference contribute
            +        $('#reference-contribute1').html(translations['reference-contribute1']);
            +        $('#reference-contribute2').html(translations['reference-contribute2']);
            +        // reference error
            +        $('#reference-error1').html(translations['reference-error1']);
            +        $('#reference-error2').html(translations['reference-error2']);
            +        $('#reference-error3').html(translations['reference-error3']);
            +        $('#reference-error4').html(translations['reference-error4']);
            +        $('#reference-error5').html(translations['reference-error5']);
            +        // reference texts
            +        $('#reference-example').html(translations['reference-example']);
            +        $('#reference-description').html(translations['reference-description'])
            +        $('#reference-extends').html(translations['reference-extends']);
            +        $('#reference-parameters').html(translations['reference-parameters']);
            +        $('#reference-syntax').html(translations['reference-syntax']);
            +        $('#reference-returns').html(translations['reference-returns']);
            +        $('.group-name, .subgroup-name').each(function() {
            +          $(this).text(translations[$(this).text()]);
            +        });
            +        var routes = window.location.hash.split('/');
            +        var obj = routes[1];
            +        var name = routes[2];
            +
            +        // class page
            +        if (routes.length == 2) {
            +          var entry = translations[obj];
            +          for (var k in entry) {
            +            if (k == 'description') {
            +              $('.description-text').html('');
            +              entry.description.forEach(function (p) {
            +                $('.description-text').append('<p>' + p + '</p>');
            +              });
            +            }
            +            else if (k == 'params') {
            +              $('.params').find('ul').children('li').each(function () {
            +                var paramname = $(this).children('.paramname').text();
            +                $(this).children('.paramtype').text(entry.params[paramname]);
            +              });
            +            }
            +            else if (k == 'returns') {
            +              $('.returns').text(entry.returns);
            +            }
            +            // fields and methods sections
            +            else {
            +              // field
            +              $("[aria-labelledby='reference-fields']").children('li').each(function (i) {
            +                var fieldName = $(this).children('.paramname').children('a').text();
            +                let descr = '';
            +                var paragraphs = entry[fieldName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +              // method
            +              $("[aria-labelledby='reference-methods']").children('li').each(function (i) {
            +                var method = $(this).children('.paramname').children('a').text();
            +                // removes the brackets
            +                var methodName = method.substring(0, method.length - 2);
            +                let descr = '';
            +                var paragraphs = entry[methodName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +            }
            +          }
            +        }
            +
            +        // method/field page
            +        if (routes.length == 3) {
            +          if (translations[obj] && translations[obj][name]) {
            +            var entry = translations[obj][name];
            +
            +            $('.description-text').html('');
            +            entry.description.forEach(function (p) {
            +              $('.description-text').append('<p>' + p + '</p>');
            +            });
            +            $('.returns').html(entry.returns);
            +            $('.params').find('ul').children('li').each(function () {
            +              var paramname = $(this).children('.paramname').text();
            +              $(this).children('.paramtype').html(entry.params[paramname]);
            +            });
            +          }
            +        }
            +      }
            +    }
            +    </script>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="reference-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/reference/staticStrings.json b/dist/es/reference/staticStrings.json
            new file mode 100644
            index 0000000000..4ba85d3402
            --- /dev/null
            +++ b/dist/es/reference/staticStrings.json
            @@ -0,0 +1,16 @@
            +{
            +  "h1": "Reference",
            +  "reference-search": "Search reference",
            +  "reference-description1": "Can't find what you're looking for? You may want to check out",
            +  "reference-description3": "You can also download an offline version of the reference.",
            +  "reference-contribute2": "Please let us know.",
            +  "reference-error1": "Notice any errors or typos?",
            +  "reference-error3": "Please feel free to edit ",
            +  "reference-error5": "and issue a pull request!",
            +  "reference-example": "Example",
            +  "reference-description": "Description",
            +  "reference-extends": "Extends",
            +  "reference-parameters": "Parameters",
            +  "reference-syntax": "Syntax",
            +  "reference-returns": "Returns"
            +}
            diff --git a/dist/es/showcase/featuring/casey-louise.html b/dist/es/showcase/featuring/casey-louise.html
            new file mode 100644
            index 0000000000..a5ab64395e
            --- /dev/null
            +++ b/dist/es/showcase/featuring/casey-louise.html
            @@ -0,0 +1,240 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>p5.js Shaders</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <div class="glitch-embed-wrap" style="height: 420px; width: 100%;">
            +        <iframe src="https://glitch.com/embed/#!/embed/shader-on-vertex?path=&previewSize=100"
            +          title="A Glitch project showing how to apply shaders to a vertex shape in p5.js."
            +          style="height: 100%; width: 100%; border: 0;">
            +        </iframe>
            +      </div>
            +    </section>
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Creado Por</h3>
            +        <p>Casey Conchinha <span class="note">(el)</span></p>
            +        <p>Louise Lessél <span class="note">(ella)</span></p>
            +        <p class="creator-from">De Nueva York, Nueva York</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Enlaces de proyectos</h3>
            +        <ul class='links' aria-labelledby="resources">
            +          <li><a href="https://bit.ly/p5shaders" target="_blank">Guía de p5.js Shaders</a></li>
            +          <li><a href="https://bit.ly/p5shadersexamples" target="_blank">Colección glitch de ejemplos con p5.js shader</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué haces ahora?</h3>
            +        <p class='project-a'>Casey: Soy un estudiante de NYU ITP que está interesado en gráficos computacionales y espacios interactivos, físicos y digitales.</p>
            +        <p class='project-a'>Louise: Soy una estudiante de NYU ITP que está interesada en gráficos computacionales y espacios interactivos basados en tecnologías de sensores.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo empezaste con p5.js?</h3>
            +        <p class='project-a'>Casey: Comencé a aprender p5.js en 2018 en mi primer semestre en ITP, aunque había estado incursionando en <a href="https://processing.org/"
            +            target="_blank">Processing</a> desde 2012. Mi amigo Pedro me introdujo a Processing cuando estudiaba diseño gráfico, y me impresionó. La idea de crear mis propias herramientas para crear gráficos y arte interactivo despertó mi interés, pero una vez que lo intenté, me enganché. El primer proyecto que puedo recordar fue un ojo que te seguía por la pantalla, y se ponía triste cuando lo dejabas solo.</p>
            +        <p class='project-a'>Louise: Inicialmente aprendí p5.js para hacer que un sitio web que ya estaba creando para que fuera más divertido. Soy una programadora de C#, así que este fue un buen segway a JavaScript para mí.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo usaste p5.js en este proyecto?</h3>
            +        <p class='project-a'>Casey: Estuve posponiendo los sombreadores de aprendizaje durante mucho tiempo, y también tenía curiosidad por saber si podría usarlos en p5.js. Luego escuché acerca de una subvención para proyectos de código abierto, narración de historias y recursos de aprendizaje en ITP llamada <a href="https://www.itpxstory.com/"
            +            target="_blank">xStory</a>. Como no encontraba mucho en la documentación de p5.js + shader, decidí descubrir cómo se implementan en p5.js y crear un recurso para que otros aprendan. Cuando le conté a Louise sobre el proyecto, ella estaba inmediatamente entusiasmada por aprender y enseñar sombreadores en p5.js. Ella ha sido excelente al asegurarse de que el proyecto sea un recurso de aprendizaje y no solo una colección de ejemplos.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cuál es tu función favorita de p5.js?</h3>
            +        <p class='project-a'>Casey: ¿<a href="https://thecodingtrain.com/"
            +            target="_blank">Shiffman</a> cuenta como una función? También me encanta tener la capacidad de compartir mis programas en la web para que las personas no tengan que instalar un software especial o venir a Nueva York para ver mi trabajo.</p>
            +        <p class='project-a'>
            +          Louise: Mi función favorita es <code><a href="https://p5js.org/reference/#/p5/push" target="_blank">push()</a></code> y <code><a href="https://p5js.org/reference/#/p5/pop" target="_blank">pop()</a></code> para la transformación del sistema de coordenadas para hacer imágenes generativas.
            +        </p>
            +
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Enfrentó algún desafío al trabajar en este proyecto? Si es así, ¿cómo los superaste?</h3>
            +        <p class='project-a'>Casey: El comienzo del proyecto (descubrir cómo funcionan las cosas) fue que contactamos a personas increíbles, les hicimos preguntas y les pedimos permiso para usar sus ejemplos en nuestro proyecto. <a
            +            href="https://github.com/aferriss/p5jsShaderExamples"
            +            target="_blank">GitHub repo de Adam Ferriss</a> realmente nos dio las bases para comprender cómo funcionan los shaders en p5.js y proporcionó un marco de ejemplos accesibles para que podamos crear proyectos. Para algunos problemas específicos relacionados con p5.js que teníamos, nos comunicamos con <a
            +            href="http://www.katehollenbach.com/" target="_blank">Kate
            +            Hollenbach</a> y <a href="https://stalgiagrigg.name/"
            +            target="_blank">Stalgia Grigg</a> (quienes trabajaron en la <a
            +            href="https://github.com/processing/p5.js/issues?q=is%3Aissue+is%3Aopen+webgl+label%3Aarea%3Awebgl"
            +            target="_blank">implementación de WebGL en p5.js</a>), y fueron muy útiles.
            +        </p>
            +        <p class='project-a'>Louise: La curva de aprendizaje fue bastante empinada para implementar shaders en p5. Afortunadamente, hubo algunos ejemplos muy bien documentados en GitHub por Adam Ferriss. Nuestro objetivo era hacerlo de manera que un principiante pueda entender cómo implementarlo, por lo que fue tanto un desafío técnico como un desafío en la enseñanza del código a extraños y principiantes. Aquí nos inspiramos en la forma en que está escrito el <a
            +            href="https://openframeworks.cc/ofBook/chapters/foreword.html"
            +            target="_blank">libro de openFrameworks</a>. Creemos en un enfoque divertido de "oye, no es difícil y tú también puedes hacerlo".
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué es algo cool que deberíamos explorar?</h3>
            +        <p class='project-a'>¡Visiten <a href="https://github.com/ITP-xStory"
            +            target="_blank">xStory GitHub</a> para explorar los increíbles proyectos de subvenciones de nuestros compañeros!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿En dónde se puede aprender más sobre ti?</h3>
            +        <p class='project-a'>Casey: <a href="https://cargocollective.com/kcconch"
            +            target="_blank">cargocollective.com/kcconch</a>, <a href="https://github.com/kcconch"
            +            target="_blank">@kcconch</a> (GitHub)</p>
            +        <p class='project-a'>Louise: <a href="http://www.louiselessel.com/" target="_blank">louiselessel.com</a>, <a
            +            href="https://github.com/louiselessel" target="_blank">@louiselessel</a> (GitHub)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/showcase/featuring/daein-chung.html b/dist/es/showcase/featuring/daein-chung.html
            new file mode 100644
            index 0000000000..c9e8242f51
            --- /dev/null
            +++ b/dist/es/showcase/featuring/daein-chung.html
            @@ -0,0 +1,225 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Chillin'</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only' id="info">Project Info</h2>
            +      <img src="../../../assets/img/showcase/daein-chung/daein-chung_chillin.png" alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device.
            +        At the top, there is a text input box to enter a message and download your own poster.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Creado Por</h3>
            +        <p>Dae In Chung <span class="note">(el)</span></p>
            +        <p class="creator-from">From Baltimore, Maryland</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Enlaces de proyectos</h3>
            +        <ul class="links">
            +          <li><a href="https://exp.paperdove.com/chillin/" target="_blank">Vean Chillin'</a></li>
            +          <li><a href="https://github.com/cdaein/exp/tree/gh-pages/chillin"
            +              target="_blank">Código para Chillin’ en GitHub</a></li>
            +          <li><a href="https://paperdove.com/work/2019-chillin/" target="_blank">Más info en el portafolio de Dae In Chung</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué haces ahora?</h3>
            +        <p class='project-a'>Soy diseñador gráfico y miembro de la facultad en Maryland Institute College of Art, donde enseño principalmente programación (con p5.js y Processing, por supuesto) y motion graphics.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo empezaste con p5.js?</h3>
            +        <p class='project-a'>He estado usando <a href="https://processing.org/"
            +            target="_blank">Processing</a> durante algún tiempo, y cuando apareció p5.js, comencé a usarlo sin pensarlo dos veces porque era fácil convertir el código de Processing existente y compartir proyectos en línea.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo usaste p5.js en este proyecto?</h3>
            +        <p class='project-a'>Este verano, me di el desafío de hacer carteles tipográficos con programación, y este es uno de los carteles que hice. Hasta hace muy poco, no sabía que podía usar los datos del sensor de movimiento con p5.js. También estaba viendo los <a
            +            href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6bLh3T_4wtrmVHOrOEM1ig_"
            +            target="_blank">video tutoriales de Dan Shiffman matter.js</a>, así que pensé ¿por qué no combinar los dos y practicar lo que estaba aprendiendo?
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cuál es tu función favorita de p5.js?</h3>
            +        <p class='project-a'>Hay muchas cosas que me encantan de p5.js, como la comunidad en línea y la amabilidad de los principiantes. Lo que realmente me gusta en este momento es el <a href="https://editor.p5js.org/"
            +            target="_blank">online editor</a>, con el que no solo puedo trabajar en línea para mí, sino también compartir el URL rápidamente en el modo actual. Para este proyecto en particular, tuve que hacer muchas pruebas en mi teléfono, y fue mucho más fácil y rápido que comprometerme con GitHub.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Enfrentó algún desafío al trabajar en este proyecto? Si es así, ¿cómo los superaste?</h3>
            +        <p class='project-a'>Tuve algunos problemas con el manejo de la fuente, el canal alfa y z-depth en el modo <a
            +            href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5"
            +            target="_blank">WebGL</a>. Todavía no estoy contento con todas mis decisiones. Pero en general, fue útil buscar en el foro y no olvidar dividir los problemas en otros más pequeños e iterar poco a poco. Además, tuve problemas para renderizar archivos de video directamente desde p5.js. La grabación de pantalla no era una opción debido a caídas de frecuencia de cuadros intermitentes (mi computadora portátil es bastante lenta). Después de investigar un poco, decidí aprender algunos conceptos básicos de <a href="https://electronjs.org/"
            +            target="_blank">Electron</a> y crear una herramienta para mí.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué es algo cool que deberíamos explorar?</h3>
            +        <p class='project-a'>Como se mencionó anteriormente, si desea renderizar cuadros y archivos de video a partir de bocetos de p5.js, consulte mi <a
            +            href="https://github.com/cdaein/p5js-electron-canvas-saver-boilerplate" target="_blank">Canvas Saver
            +            boilerplate</a> y hazme saber lo que piensas.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿En dónde se puede aprender más sobre ti?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/cdaein/" target="_blank">@cdaein</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/showcase/featuring/moon-xin.html b/dist/es/showcase/featuring/moon-xin.html
            new file mode 100644
            index 0000000000..aa8510ff4f
            --- /dev/null
            +++ b/dist/es/showcase/featuring/moon-xin.html
            @@ -0,0 +1,232 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Moving Responsive Posters</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png"
            +        alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Creado Por</h3>
            +        <p>Moon Jang <span class="note">(ella)</span></p>
            +        <p>Xin Xin <span class="note">(elle)</span></p>
            +        <p class="creator-from">De Atenas, Georgia</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Posters hechos por</h3>
            +        <ul class="links">
            +          <li><a href="https://editor.p5js.org/avezray/present/JTjhOdGRB" target="_blank">Avery Ray</a></li>
            +          <li><a href="https://editor.p5js.org/carcarw/present/DyKJHUtCN" target="_blank">Carlee Wooddell</a></li>
            +          <li><a href="https://editor.p5js.org/mdh54215/present/h5wp4EYen" target="_blank">Mia Hofmann</a></li>
            +          <li><a href="https://editor.p5js.org/katiehuang1998@gmail.com/present/1GhSDw-Og" target="_blank">Katie
            +              Huang</a></li>
            +          <li><a href="https://editor.p5js.org/borderrider@gmail.com/present/Lg_pSPRHF" target="_blank">Lila
            +              Mitchell</a></li>
            +          <li><a href="https://editor.p5js.org/wallacekd/present/GqWZOYUSN" target="_blank">Kathryn Wallace</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué haces ahora?</h3>
            +        <p class='project-a'>Moon: Soy diseñadora gráfica, artista visual y educadora de diseño. Este verano, impartí un curso de diseño gráfico en el programa Cortona de la Universidad de Georgia en Italia, presentando algunos conceptos básicos de p5.js. Este otoño, planeo enseñar y estudiar plataformas digitales en UGA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo empezaste con p5.js?</h3>
            +        <p class='project-a'>Mi ex colega, <a href="https://xin-xin.info/" target="_blank">Xin
            +            Xin</a>, me invitó a <a href="https://medium.com/processing-foundation/pcd/home"
            +            target="_blank">Processing Community Day</a> en <a
            +            href="https://day.processing.org/pcd-la.html"
            +            target="_blank">LA en enero de 2019</a>. Me ayudaron con las herramientas y la lógica de p5.js. Fue una excelente experiencia de enseñanza y aprendizaje.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo usaste p5.js en este proyecto?</h3>
            +        <p class='project-a'>Seguimos tutoriales básicos, <a href="https://thecodingtrain.com/"
            +            target="_blank">los videos de Daniel en YouTube</a>, y <a
            +            href="https://p5js.org/reference/"
            +            target="_blank">Referencia en el sitio web p5.js</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cuál es tu función favorita de p5.js?</h3>
            +        <p class='project-a'>Mi función favorita está relacionada con <a
            +            href="https://p5js.org/reference/#group-Typography"
            +            target="_blank">type</a> y <a
            +            href="https://p5js.org/reference/#group-Transform"
            +            target="_blank">transformation</a>: <code><a href="https://p5js.org/reference/#/p5/rotate" target="_blank">rotate()</a></code>. Pude usar y enseñar esta herramienta para visualizar varias ideas sobre el tiempo en movimiento.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Enfrentó algún desafío al trabajar en este proyecto? Si es así, ¿cómo los superaste?</h3>
            +        <p class='project-a'>Para mí, un principiante, fue un desafío comprender la estructura general de p5.js y cómo funciona el código en general. Tuve que repetir los conceptos básicos de p5.js un par de veces, y luego dibujé un cuadro para memorizar y enseñar la forma en que entendí la estructura y el código de p5.js con fuertes restricciones que configuré. Fue una excelente experiencia de enseñanza y aprendizaje.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué es algo cool que deberíamos explorar?</h3>
            +        <p class='project-a'>Echa un vistazo a <a href="http://www.brokennature.org/"
            +            target="_blank">Design Triennale</a> en Milán, Italia.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿En dónde se puede aprender más sobre ti?</h3>
            +        <p class='project-a'><a href="http://www.moonjang.com/" target="_blank">moonjang.com</a>
            +          <br><a href="https://www.instagram.com/borderrider/" target="_blank">@borderrider</a> (Instagram)
            +        </p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/showcase/featuring/phuong-ngo.html b/dist/es/showcase/featuring/phuong-ngo.html
            new file mode 100644
            index 0000000000..1fb5685d5b
            --- /dev/null
            +++ b/dist/es/showcase/featuring/phuong-ngo.html
            @@ -0,0 +1,232 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Airi Flies</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" alt="A screenshot of a poster of Airi Flies, a game to help Airi fly by saying pew.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Creado Por</h3>
            +        <p>Phuong Ngo <span class="note">(ella)</span></p>
            +        <p class="creator-from">De Kiev, Ucrania</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Enlaces de proyectos</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://www.yonaymoris.me/AiriFlies/" target="_blank">Juega Airi Flies!</a></li>
            +          <li><a href="https://github.com/yonaymoris/AiriFlies" target="_blank">Código para AiriFlies en GitHub</a>
            +          </li>
            +          <li><a href="https://www.yonaymoris.me/projects/airiflies"
            +              target="_blank">Más info en el portafolio de Phuong Ngo</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué haces ahora?</h3>
            +        <p class='project-a'>Soy una programadora y diseñadora creativa, un receptor de la beca de diversidad <a href="https://schoolofma.org/"
            +            target="_blank">School of Machines, Making & Make-Believe</a>, y solo una criatura curiosa.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo empezaste con p5.js?</h3>
            +        <p class='project-a'>Estaba tomando un curso en la Escuela de Máquinas en Berlín este verano llamado "<a href="https://schoolofma.org/bots.html"
            +            target="_blank">Bots and Machine Learning</a>", principalmente impartido por <a
            +            href="https://1023.io/" target="_blank">Yining Shi</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo usaste p5.js en este proyecto?</h3>
            +        <p class='project-a'>Usé p5.js para trabajar en la parte visual del juego. Los sprites de animación para Airi y los fantasmas se dibujaron en una aplicación para iPad llamada <a href="https://rizer.co/pixaki/"
            +            target="_blank">Pixaki</a> y luego se integraron en el código <a
            +            href="http://molleindustria.github.io/p5.play/"
            +            target="_blank">p5.play</a>. Principalmente utilicé ejemplos en p5.play como referencia.</p>
            +        <p class='project-a'>Para el fondo de desplazamiento sin fin, encontré un <a
            +            href="https://editor.p5js.org/chjno/sketches/ByZlypKWM"
            +            target="_blank">p5 sketch de chjno</a>. Establecí una condición para que cada vez que se detectara la palabra "pew" o un clic del mouse, la velocidad de desplazamiento cambiara para crear una ilusión de Airi volando hacia arriba. Cuando el usuario no hace nada, la velocidad de desplazamiento es negativa, hace que parezca que Airi se está cayendo.
            +        </p>
            +        <p class='project-a'>Para el reconocimiento de sonido, utilicé <a
            +            href="https://teachablemachine.withgoogle.com/io19" target="_blank">Google's Teachable Machine
            +            2</a>  (actualmente, hay una versión beta que aún no está disponible en público, ¡pero lo estará muy pronto!). Agregué alrededor de 120 muestras de mis compañeros de clase diciendo la palabra "pew" con diferentes entonaciones y 80 muestras de ruido de fondo para entrenarlo. Luego integré el modelo en el juego con <a href="https://ml5js.org/" target="_blank">ml5.js</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cuál es tu función favorita de p5.js?</h3>
            +        <p class='project-a'>Realmente me encanta lo fácil que se puede crear, manipular y eliminar bloques y clases HTML con la <a href="https://p5js.org/reference/"
            +            target="_blank">p5.js
            +            library</a> a través de <code><a href="https://p5js.org/reference/#/p5/createDiv" target="_blank">createDiv()</a></code>,
            +          <code><a href="https://p5js.org/reference/#/p5.Element/addClass" target="_blank">addClass()</a></code> etc. But my most favorite function is <code><a href="https://p5js.org/reference/#/p5/draw" target="_blank">draw()</a></code>, etc. Pero mi función favorita es 
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Enfrentó algún desafío al trabajar en este proyecto? Si es así, ¿cómo los superaste?</h3>
            +        <p class='project-a'>Hubieron muchos desafíos simplemente porque p5.js era algo nuevo para mí. No había trabajado mucho con JavaScript en general antes. Leer documentación y buscar ejemplos similares ayudó mucho.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué es algo cool que deberíamos explorar?</h3>
            +        <p class='project-a'>¡Chequen los <a href="https://schoolofma.org/programs"
            +            target="_blank">cursos de School of Machines</a>! Se esfuerzan por conectar a las personas más creativas del mundo y hasta ahora lo hacen bien. ❤️
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿En dónde se puede aprender más sobre ti?</h3>
            +        <p class='project-a'><a href="https://www.yonaymoris.me/" target="_blank">yonaymoris.me</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/showcase/featuring/qianqian-ye.html b/dist/es/showcase/featuring/qianqian-ye.html
            new file mode 100644
            index 0000000000..b9951c69a9
            --- /dev/null
            +++ b/dist/es/showcase/featuring/qianqian-ye.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Qtv</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" alt="A guest talk video (Guest Talk #1) on Qtv by Qianqian Ye, featuring Kaikai and Cheng Xu.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Creado Por</h3>
            +        <p>Qianqian Ye <span class="note">(ella)</span></p>
            +        <p class="creator-from">Los Ángeles, California</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Recursos del Proyecto</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://bit.ly/2XVzPAv" target="_blank">Qtv YouTube</a></li>
            +          <li><a href="https://www.instagram.com/q_tv_/" target="_blank">Qtv Instagram</a></li>
            +          <li><a href="https://space.bilibili.com/442343394" target="_blank">Qtv Bilibili</a></li>
            +          <li><a href='https://v.douyin.com/sopAGk/' target='_blank'>@Q_tv TikTok</a></li>
            +          <li><a href="https://medium.com/processing-foundation/interview-with-2019-fellow-qianqian-ye-799c0115c295"
            +              target="_blank">Entrevista de Processing Foundation con Qianqian Ye</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué haces ahora?</h3>
            +        <p class='project-a'>Soy una artista y diseñadora china con sede en Los Ángeles.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo empezaste con p5.js?</h3>
            +        <p class='project-a'>Mi pareja me presentó p5.js y en el cual aprendí principalmente al ver videos tutoriales gratuitos en línea. Mi primer proyecto de p5.js fue dibujar algunas formas con diferentes colores.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo usaste p5.js en este proyecto?</h3>
            +        <p class='project-a'>Este proyecto comenzó con la idea de enseñarle a mi mamá, que vive en China y no habla inglés, a programar con p5.js. Este proyecto fue difícil en diferentes niveles y quería comenzar identificando las razones principales por las que es más difícil para alguien como mi madre aprender a programar, principalmente debido a la falta de recursos educativos gratuitos de programación creativa. La mayoría de los recursos gratuitos para aprender la programación creativa no están disponibles en China. Los tutoriales de p5.js en YouTube, así como las cuentas de p5.js en Twitter e Instagram son inaccesibles en China debido a la censura del internet.</p>
            +        <p class='project-a'>Aprendí mucho de los videos de YouTube, como el <a href="https://thecodingtrain.com/"
            +            target="_blank">Coding Train</a>, pero cuanto más miraba los tutoriales de programación en línea, más me daba cuenta de lo difícil que es encontrar otras mujeres y personas de color enseñando programación, especialmente en mandarín. Quería ayudar a otras mujeres chinas a relacionarse con la programación creativa.</p>
            +        <p class='project-a'>Estoy trabajando para abrir los canales de video a otrxs creativxs chinxs que quieran contribuir al recurso educativo juntxs, como entrevistas y tutoriales invitadxs. Si te interesa enseñar/hablar sobre programación creativa en mandarín, ¡Avísame!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cuál es tu función favorita de p5.js?</h3>
            +        <p class='project-a'>El <a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a> es mi función favorita. Hace que la programación creativa en línea sea perfecta.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Enfrentó algún desafío al trabajar en este proyecto? Si es así, ¿cómo los superaste?</h3>
            +        <p class='project-a'>Aprender a programar en un segundo idioma fue difícil y la falta de comunidad hizo que este proceso fuera aún más arduo. Espero hablar desde mi experiencia como principiante y alguien que alguna vez se sintió como un extraño al mundo de la programación creativa y el de los videos tutoriales.</p>
            +        <p class='project-a'>Paso mucho tiempo investigando la tecnología más actual para mis videos. Al final, decidí usar mi teléfono para grabar y iMovie para editar. Espero alentar a otros a que no se necesitan muchas cosas costosas para comenzar a hacer videos instructivos.</p>
            +        <p class='project-a'>Otro problema que encontré fue mi propio miedo a ponerme en línea. Primero tuve que superar mi ansiedad de cometer errores en los videos o recibir comentarios negativos en línea. A menudo, mujeres y personas de color son víctimas de acoso en línea. Espero ayudar a establecer un ejemplo para otras mujeres y personas de color que está bien ponerse en línea y fortalecer sus comunidades compartiendo su conocimiento. Eventualmente, podremos detener el acoso en línea creando comunidades diversas y fuertes.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué es algo cool que deberíamos explorar?</h3>
            +        <p class='project-a'>Estoy muy entusiasmado por <a href="http://tinytechzines.org/"
            +            target="_blank">Tiny Tech Zines</a> en LA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿En dónde se puede aprender más sobre ti?</h3>
            +        <p class='project-a'><a href="http://www.qianqian-ye.com/" target="_blank">qianqian-ye.com</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/showcase/featuring/roni-cantor.html b/dist/es/showcase/featuring/roni-cantor.html
            new file mode 100644
            index 0000000000..49db5598e6
            --- /dev/null
            +++ b/dist/es/showcase/featuring/roni-cantor.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Programmed Plotter Drawings</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img class='half-image' src="../../../assets/img/showcase/roni-cantor/roni-cantor_plotter-turquoise.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a turquoise gel pen.">
            +      <img class='half-image' src="../../../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a white gel pen.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Creado Por</h3>
            +        <p>Roni Cantor <span class="note">(ella)</span></p>
            +        <p class="creator-from">De Toronto, Canadá</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Enlaces de proyectos</h3>
            +        <ul class="links" aria-labelledby="resources">
            +          <li><a href="https://editor.p5js.org/ronicantor/sketches/eq2bIhmh2"
            +              target="_blank">Sketch de ejemplo en p5.js Web Editor</a></li>
            +          <li><a href="https://drive.google.com/file/d/1UJy6q5cDl6Hg79O9mX1ZN7NFp0NXSYCs/view?usp=sharing"
            +              target="_blank">AxiDraw V3 demo video</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué haces ahora?</h3>
            +        <p class='project-a'>Me acabo de graduar del programa de Nuevos Medios (New Media) de la Universidad de Ryerson. Después de 4 años de programación y fabricación de robots, decidí tomar un descanso y jugar con algunas formas de arte más tradicionales, mientras que todavía programando y jugando con robots.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo empezaste con p5.js?</h3>
            +        <p class='project-a'>¡Comencé a usar p5.js en <a href="https://itp.nyu.edu/camp2019/"
            +            target="_blank">NYU ITP Camp</a>! After using <a
            +            href="https://processing.org/" target="_blank">Processing</a>! Después de usar Processing durante muchos años, quería probar algo nuevo.
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cómo usaste p5.js en este proyecto?</h3>
            +        <p class='project-a'>Utilicé p5.js en este proyecto para generar las fórmulas de onda sinusoidal y lerp (interpolación lineal) y mostrar las imágenes en el <a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a>. Luego usé una función en mi código que exportaba mi gráfico programado a un archivo <a
            +            href="https://developer.mozilla.org/en-US/docs/Web/SVG"
            +            target="_blank">SVG</a>. Necesitaba un archivo SVG para darle al plotter, un <a
            +            href="https://shop.evilmadscientist.com/productsmenu/846" target="_blank">AxiDraw
            +            V3</a>, para que entendiera dónde dibujar las líneas que programé. ¡Envié esta información al trazador con un programa llamado <a href="https://inkscape.org/"
            +            target="_blank">Inkscape</a>!</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Cuál es tu función favorita de p5.js?</h3>
            +        <p class='project-a'>
            +          <code><a href="https://p5js.org/reference/#/p5/lerp" target="_blank">lerp()</a></code> porque las líneas son divertidas y "lerp" es una palabra divertida para decir!
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Enfrentó algún desafío al trabajar en este proyecto? Si es así, ¿cómo los superaste?</h3>
            +        <p class='project-a'>¡Era la primera vez que usaba p5.js, Inkscape y un plotter! Realmente me beneficié de las personas a mi alrededor que habían usado p5 antes, así como de guías y foros en línea.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿Qué es algo cool que deberíamos explorar?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/gandyworks/"
            +            target="_blank">@gandyworks</a> en Instagram: cosas de plotter análogo súper geniales.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>¿En dónde se puede aprender más sobre ti?</h3>
            +        <p class='project-a'><a href="https://ronicantor.com/" target="_blank">ronicantor.com</a>
            +          <br><a href="https://www.instagram.com/roni.cantor/"
            +            target="_blank">@roni.cantor</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/showcase/index.html b/dist/es/showcase/index.html
            new file mode 100644
            index 0000000000..b8c3d0bc2e
            --- /dev/null
            +++ b/dist/es/showcase/index.html
            @@ -0,0 +1,245 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main  id="content" class="column-span">
            +    <section class="showcase-intro">
            +      <h1>Showcase</h1>
            +      
            +      <p>Presentamos Showcase, creada por <a href="https://ashleykang.dev" target="_blank">Ashley Kang</a>
            +       en 2019 y actualmente curada por <a href="https://katiechan.cargo.site/" target="_blank">Katie Chan</a>.
            +      Estamos celebrando cómo las personas usan p5.js para hacer que trabajos creativos, el aprendizaje y fuente abierta sean más interesantes e inclusivos. Juntos, hacemos una comunidad. Durante el verano de 2020, le pedimos a creadores que compartieran cómo usan p5.js en variados proyectos y piezas.</p>
            +      <p>Durante el verano 2020, Showcase está abierto a postulaciones, ¡nomina el trabajo con p5.js de alguien o el tuyo para ser incluid aquí!</p>
            +
            +      <span id="nominate" class="nominate"><a href="https://forms.gle/ETP7kjAocBcfGTuj8" target="_blank">Nomina un Proyecto</a></span>
            +    </section>
            +
            +    <section class="showcase-featured">
            +      <h2 class="featuring">Presentando</h2>
            +
            +      <div class="left-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/roni-cantor.html">Programmed Plotter Drawings</a></h3>
            +          <p class="credit">Roni Cantor</p>
            +          <a href="./featuring/roni-cantor.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg" 
            +            alt="A drawing of a sine wave lerp plotted on black paper using an AxiDraw V3 and a white gel pen.">
            +          </a>
            +          <p class="description">Ondas senoidales y lerps generadas en p5.js, exportados como SVG y dibujados con un plotter y bolígrafos.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5/lerp">lerp()</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/daein-chung.html">Chillin'</a></h3>
            +          <p class="credit">Dae In Chung</p>
            +          <a href="./featuring/daein-chung.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/daein-chung/daein-chung_chillin.png" 
            +              alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device. 
            +              At the top, there is a text input box to enter a message and download your own poster">
            +          </a>
            +          <p class="description">Un póster tipográfico interactivo que utiliza el sensor de movimiento de un dispositivo móvil con p5.js.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://brm.io/matter-js/">matter.js</a></li>
            +            <li><a class="tag" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">p5 WebGL</a></li>
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5.Camera">p5.Camera</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/casey-louise.html">p5.js Shaders</a></h3>
            +          <p class="credit">Casey Conchinha, Louise Lessél</p>
            +          <a href="./featuring/casey-louise.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/casey-louise/casey-louise_p5js-shaders.png" 
            +              alt="A screenshot of the Introduction page of the p5.js Shaders guide website">
            +          </a>
            +          <p class="description">Un recurso para aprender el qué, por qué y cómo usar shaders en p5.js.</p>
            +          <ul class="project-tags">
            +         </ul>
            +        </div>
            +      </div>
            +
            +      <div class="right-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/phuong-ngo.html">Airi Flies</a></h3>
            +          <p class="credit">Phuong Ngo</p>
            +          <a href="./featuring/phuong-ngo.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" 
            +              alt="A screenshot of the instructions and scoreboard for the online game Airi Flies">
            +          </a>
            +          <p class="description">En este juego desarrollado con p5.play, ayuda a Airi volar diciendo PEW. Creado para alentar a las personas para que se salgan de su zona de confort y sentirse más seguros de sí mismos independientemente de cómo lo que hagan y cómo se vean o escuchen.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="http://molleindustria.github.io/p5.play/">p5.play</a></li>
            +            <li><a class="tag" href="https://ml5js.org/">ml5.js</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +          <h3 class="title"><a href="./featuring/qianqian-ye.html">Qtv</a></h3>
            +          <p class="credit">Qianqian Ye</p>
            +          <a href="./featuring/qianqian-ye.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" 
            +              alt="A screenshot of a Qtv video (Guest Talk #1) featuring Chinese womxn designers and artists Kaikai and Cheng Xu">
            +          </a>
            +          <p class="description">Un canal de video con videos de 1-minuto en Mandarín sobre programación creativa, arte y tecnología, que incluye tutoriales de p5.js para principiantes. Disponible en  YouTube, Instagram, Bilibili y TikTok.</p>
            +          <ul class="project-tags">
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/moon-xin.html">Moving Responsive Posters</a></h3>
            +          <p class="credit">Moon Jang, Xin Xin, and students</p>
            +          <a href="./featuring/moon-xin.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png" 
            +              alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right">
            +          </a>
            +          <p class="description">Pósters móviles basados en el navegador que utilizan sistemas gráficos, métodos de transformación y p5.js para abordar las connotaciones de una palabra de menos de 8 letras. Diseñado por estudiantes para un curso de diseño gráfico (Visual Narrative Systems / Sistemas Narrativos Visuales) en la Universidad de Georgia.</p>
            +          <ul class="project-tags">
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/rect">rect()</a></li>
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/translate">translate()</a></li>
            +          </ul>
            +        </div>
            +      </div>
            +    </section>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/es/teach/index.html b/dist/es/teach/index.html
            new file mode 100644
            index 0000000000..5cb961a4fc
            --- /dev/null
            +++ b/dist/es/teach/index.html
            @@ -0,0 +1,856 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="es">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">teach | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Ir al contenido</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Preferencias de idioma</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/es/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="teach-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Navegación del sitio</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/es/">Inicio</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/es/download/">Descargar</a></li>
            +        <li><a href="/es/download/support.html">Donar</a></li>
            +        <li><a href="/es/get-started/">Empezar</a></li>
            +        <li><a href="/es/reference/">Referencia</a></li>
            +        <li><a href="/es/libraries/">Bibliotecas</a></li>
            +        <li><a href="/es/learn/">Aprender</a></li>
            +        <li><a href="/es/teach/">Enseñar</a></li>
            +        <li><a href="/es/examples/">Ejemplos</a></li>
            +        <li><a href="/es/books/">Libros</a></li>
            +        <li><a href="/es/community/">Comunidad</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Foro</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            + <main id="content" class="column-span">
            +  	<section class= "teach-intro">
            +      <h1>Teach</h1>
            +
            +	      <p>Every teaching has its own unique goals, messages, conditions, and environments. By documenting and sharing p5 workshops, classes, and materials, we hope to better connect the p5.js learner and educator communities around the world. <a href="" onclick= "window.open('https://docs.google.com/forms/d/e/1FAIpQLSei8yHX2BROMnMQeZT_tsSXJOH13TPRG6CB4GVHH1oL1hzkZg/viewform?usp=sf_link', '_blank')">Share or recommend</a> your own teaching experiences, too!</p>
            +						
            +    </section>
            +
            +	<section>
            +
            +		<div id="resources"></div>
            +			<h2 class = "heading">p5 Teaching Resources</h2> 
            +			
            +			<div class="search-filter"><input type="checkbox"><label> Search Filter &#x2192;</label></div>
            +
            +     		<!-- search-results -->
            +
            +     		<div class="filter-panel">
            +
            +							
            +				<ul class="filters" id="filters">
            +
            +					<li><p class = "filter-title">&#x1F33A; Diversity & Inclusion : </p></li>
            +					<li><input type="checkbox" id="gender" value="gender"><label for="gender">Gender</label></li>
            +					<li><input type="checkbox" id="race-ethnicity" value="race-ethnicity"><label for="race-ethnicity">Race & Ethnicity</label></li>
            +					<li><input type="checkbox" id="language" value="language"><label for="language">Language</label></li>
            +					<li><input type="checkbox" id="neuro-type" value="neuro-type"><label for="neuro-type">Neuro-Type</label></li>
            +					<li><input type="checkbox" id="ability" value="ability"><label for="ability">Ability</label></li>
            +					<li><input type="checkbox" id="class" value="class"><label for="class">Class</label></li>
            +					<li><input type="checkbox" id="religion" value="religion"><label for="religion">Religion</label></li>
            +					<li><input type="checkbox" id="subculture" value="subculture"><label for="subculture">(Sub-)Culture</label></li>
            +					<li><input type="checkbox" id="political-opinion" value="political-opinion"><label for="political-opinion">Political Opinion</label></li>
            +					<li><input type="checkbox" id="age" value="age"><label for="age">Age</label></li>
            +					<li><input type="checkbox" id="skill-level" value="skill-level"><label for="skill-level">Skill Level</label></li>
            +					<li><input type="checkbox" id="occupation" value="occupation"><label for="occupation">Occupation</label></li>
            +					<li><input type="checkbox" id="noCodeSnobs" value="noCodeSnobs"><label for="noCodeSnobs">#noCodeSnobs</label></li>
            +					<li><input type="checkbox" id="newKidLove" value="newKidLove"><label for="newKidLove">#newKidLove</label></li>
            +					<li><input type="checkbox" id="unassumeCore" value="unassumeCore"><label for="unassumeCore">#unassumeCore</label></li>
            +					<li><input type="checkbox" id="BlackLivesMatter" value="BlackLivesMatter"><label for="BlackLivesMatter">#BlackLivesMatter</label></li>
            +							
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CD; Venue : </p></li>
            +
            +					<li><input type="checkbox" id="africa" value="africa"><label for="africa">Africa</label></li>
            +					<li><input type="checkbox" id="asia" value="asia"><label for="asia">Asia</label></li>
            +					<li><input type="checkbox" id="europe" value="europe"><label for="europe">Europe</label></li>
            +					<li><input type="checkbox" id="north-america" value="north-america"><label for="north-america">North America</label></li>
            +					<li><input type="checkbox" id="oceania" value="oceania"><label for="oceania">Oceania</label></li>
            +					<li><input type="checkbox" id="south-america" value="south-america"><label for="south-america">South America</label></li>
            +					<li><input type="checkbox" id="virtual-online" value="virtual-online"><label for="virtual-online">Virtual-Online  &#x1F310;</label></li>
            +
            +
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4C5; Year : </p></li>
            +					<li><input type="checkbox" id="2014" value="2014"><label for="2014">~2014</label></li>
            +					<li><input type="checkbox" id="2015" value="2015"><label for="2015">2015</label></li>
            +					<li><input type="checkbox" id="2016" value="2016"><label for="2016">2016</label></li>
            +					<li><input type="checkbox" id="2017" value="2017"><label for="2017">2017</label></li>
            +					<li><input type="checkbox" id="2018" value="2018"><label for="2018">2018</label></li>
            +					<li><input type="checkbox" id="2019" value="2019"><label for="2019">2019</label></li>
            +					<li><input type="checkbox" id="2020" value="2020"><label for="2020">2020</label></li>
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CA; Level of Difficulty : </p></li>
            +					<li><input type="checkbox" id="elementary" value="elementary"><label for="elementary">Elementary</label></li>
            +					<li><input type="checkbox" id="intermediate" value="intermediate"><label for="intermediate">Intermediate</label></li>
            +					<li><input type="checkbox" id="advanced" value="advanced"><label for="advanced">Advanced</label></li>
            +				 </ul>
            +
            +						  <br>
            +								
            +
            +			</div>
            +												
            +			<div class = "results-wrapper">
            +
            +						
            +				<div class="results" id="search-results">
            +					<ul>
            +				  		<li class="case-list" data-category="2019 europe gender race-ethnicity age skill-level BlackLivesMatter advanced"><a href="#case1" class="caseBtn" >"p5.js à l'Ubuntu Party!", Basile Pesin</a></li>
            +
            +				  		 <li class="case-list" data-category="2020 asia age skill-level occupation elementary advanced"><a href="#case2" class="caseBtn">"Making The Thing that Makes the Thing: Exploring Generative Art &#x0026; Design with p5.js", Priti Pandurangan &#x0026; Ajith Ranka</a></li>
            +
            +						  <li class="case-list" data-category="2016 2019 2020 elementary intermediate advanced north-america gender race-ethnicity language neuro-type ability subculture occupation north-america"><a href="#case3" class="caseBtn">CC Fest (Creative Coding Festival), Saber</a></li>
            +
            +						  <li class="case-list" data-category="2018 virtual-online south-america gender race-ethnicity language neuro-type religion subculture age noCodeSnobs newKidLove unassumeCore elementary intermediate advanced"><a href="#case4" class="caseBtn" >"Taller Introducci&#x00F3;n a la Programaci&#x00F3;n Creativa con p5.js", Aar&#x00F3;n Montoya-Moraga</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america gender race-ethnicity class subculture age skill-level elementary"><a href="#case5" class="caseBtn" >"Introduction to Generative Drawing", Adam Herst</a></li>
            +
            +						  <li class="case-list" data-category="2020 asia virtual-online gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation elementary"><a href="#case6" class="caseBtn" >Open Lecture "Creative Coding: 2020", Shunsuke Takawo</a></li>
            +
            +
            +						  <li class="case-list" data-category="2020 asia gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation intermediate"><a href="#case7" class="caseBtn" >"Creative Coding for Static Graphics", Shunsuke Takawo</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america virtual-online race-ethnicity language subculture skill-level"><a href="#case8" class="caseBtn" >"Generative Typography", Dae In Chung</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity language age skill-level occupation noCodeSnobs new unassumeCore BlackLivesMatter elementary intermediate"><a href="#case9" class="caseBtn" >"Machine Learning for the Web", Yining Shi</a></li>
            +
            +
            +						  <li class="case-list" data-category="europe virtual-online gender elementary"><a href="#case10" class="caseBtn" >"Introduction to p5.js and JavaScript", Nico Reski</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity skill-level occupation"><a href="#case11" class="caseBtn">"Digital Weaving &#x0026; Physical Computing Workshop Series", Qianqian Ye &#x0026; Evelyn Masso</a></li>
            +
            +						  <li class="case-list" data-category="2015 2020 north-america asia gender race-ethnicity language neuro-type ability class skill-level"><a href="#case12" class="caseBtn">"Signing Coders", Taeyoon Choi</a></li>
            +	    			</ul>
            +						<br>
            +				</div> 
            +			</div>
            +						
            +
            +						
            +
            +		<!--modal box section-->
            +		
            +			<!--modal boxes-->
            +
            +			<div id="caseModals" class="modal">
            +
            +				<!--modal box #1-->
            +
            +				  <div class="modal-content" id="case1"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>p5.js à l'Ubuntu Party!</span></li>
            +				        	<li class = "case"><p class="lead-name">Basile Pesin</p></li>
            +
            +				          	<li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date<p><a href="https://ubuntu-paris.org/">2020 Ubuntu Party, </a>Cité des Sciences et de l'Industrie, Paris, France</p></li> 
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Any age, including children and parents, young and older adults.
            +				            </p></li>		         
            +
            +				            <li class = "clear"></li>  				
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To introduce a new public to programming through fun and compelling examples. </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Method: in-person workshop, 1 hour per session, with different participant each times. The students were using (Ubuntu) machines with the p5.js web editor. I was teaching using a video projector as well as a board.</p><p>Materials: The exercises I gave where accessible through p5.js web-editor links available in <a href = "https://vertmo.github.io/ubuntu-party-p5/">GitHub</a>.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Age</label><label>Skill Level</label><label>#BlackLivesMatter</label>
            +				            </li>
            +		             
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				<!--modal box #2-->
            +	
            +				  <div class="modal-content" id="case2"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Making The Thing that Makes the Thing: Exploring Generative Art & Design with p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Priti Pandurangan & Ajith Ranka</p></li>
            +				        	
            +				        	<li class = "clear"></li>
            +             				<li class = "clear"></li>
            +             				<li class = "case"><img src="https://drive.google.com/uc?id=1udID-B1qADY7QxDkYkAh6ZYX7D8BfrnD" alt="A group of participants collaborating to create some designs using the p5.js web editor on their laptops."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date<p>&#x1F4CD; National Institute of Design, Bangalore</p><p>&#x1F4C5; 2020 February 8, 2:30-4:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Priti: Intermediate & Ajith: Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To explore generative art &#x0026; design and recreate some classical works with p5.js. </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: In-person, collaborative, hands-on workshop.</p><p>Materials: <a href="https://musingswithcode.studio/generative-design-workshop">course page </a> linking to sketches on the p5 editor, <a href="https://musingswithcode.studio/generative-design-workshop/explainers">interactive reference guide </a>to p5 basics</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Skill Level</label><label>Occupation</label></li>			    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +				  <!--modal box #3-->
            +	
            +				  <div class="modal-content" id="case3"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>CC Fest (Creative Coding Festival)</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Saber</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Love p5.js. It has meant so much to me, my students, and this community."</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; New York, Los Angeles, San Francisco, Virtual-Online &#x1F310;</p><p>&#x1F4C5; Twice a year in NYC for four years; once a year in LA for three years; once a year in SF for two years; now virtual</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To build a teacher and student community around p5 for middle and high school.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>A half-day of workshop led by volunteer teachers. We saw lots of different methods and materials. Most used some sort of slides or documentation, some live coding using an editor, with work time for participant to remix.</p><p>&#x1F517; <a href="https://http://ccfest.rocks/lessons">CC Fest Lessons page</a> for teaching materials</p><p>&#x1F4F8; <a href="http://ccfest.rocks/pictures">More photos</a></li>
            +
            +              				<!--<li class = "case"><iframe src="http://ccfest.rocks/pictures" height= "200" alt="Pictures of CC Fest"></iframe></li>-->
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>(Sub-)Culture</label><label>Occupation</label></li>	
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #4-->
            +	
            +				  <div class="modal-content" id="case4"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Taller Introducción a la Programación Creativa con p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Aarón Montoya-Moraga</p></li>
            +
            +				        	<li class = "case"><p class = speech>"p5.js is my happy place &#x1F495; "</p></li>
            +
            +				        	<li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://miro.medium.com/max/1000/1*OIn_NKGuKyto9-_h6CAmmw.jpeg" alt="A group of 20 people sitting on a large shared table with their laptops looking at a projected screen."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD;  PlusCode Media Arts Festival, Buenos Aires, Argentina & Virtual-Online  &#x1F310;</p><p>&#x1F4C5; 2018 November 14, 3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>I had around 16 students in the workshop, and a team including 3 people from the PlusCode festival, and one person at the venue.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary, Intermediate, Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Introduction to beginners and artists of graphic web programming and open source, using p5.js, in Spanish :)</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>I used the material on this <a href="https://github.com/montoyamoraga/workshop-p5js-pluscode-2018">GitHub repo</a>, we used the p5.js web editor, we had a three hour long workshop</p><p>&#x1F517; <a href="https://medium.com/processing-foundation/code-electronic-art-festival-2018-argentina-803d3ca8092c">+CODE electronic art festival 2018, Argentina</a>, Medium</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Religion</label><label>(Sub-)Culture</label><label>Age</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label></li>
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				  <!--modal box #5-->
            +	
            +				  <div class="modal-content" id="case5"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to Generative Drawing</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Adam Herst</p></li>
            +
            +				        	<li class = "case"><p class = speech>"My greatest source of uncertainty in developing the workshop was whether it was trying to teach art to programmers or to teach programming to artists."</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; <a href="https://interaccess.org/studio">Inter/Access</a> (artist-run centre), Toronto, Ontario, Canada</p><p>In-person with a self-paced workbook for remote work</p><p>&#x1F4C5; 2020 February 12, 7PM-9PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>15 artists
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To introduce p5.js to artists with little or no programming experience and to suggest one way an analogue practice can migrate to a digital form.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD;Method & Materials</p><p>A printed workbook with activities that used the p5.js web editor to show how translate an physical drawing into a digital drawing.</p><p>&#x1F517;<a href="https://interaccess.org/event/2019/processing-community-day-generative-drawing">Processing Community Day 2019: Generative Drawing at Inter/Access</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Letter PDF</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Booklet PDF</a></p></li>		
            +
            +				    		<li class = "clear"></li>
            +				        	<li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Class</label><label>(Sub-)Culture</label><label>Age</label><label>Skill Level</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #6-->
            +	
            +				  <div class="modal-content" id="case6"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Open Lecture, Creative Coding: 2020</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I love p5.js because it's so easy to read and write code in p5.js. Coding in your everyday life!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				          	<li class = "clear"></li>	
            +				          	<li class = "case"><img src="https://lh3.googleusercontent.com/pw/ACtC-3eYswa6tJH5pvfvvAAfXQJO71ncsdgpwDBvbPAL-qcwnLkkpuoAVpggOb2-LYSLqo0Htd8cgnv5i8yLJg6Wh7J_rW2MMy6y8XZRznRByjj2mGJHf8XFmDI-8W6mH7urrEQC2tyUMF1HWaamLTNBqmIyeQ=w1560-h878-no?authuser=0" alt="A table on which there is a laptop, some sheets of papers, colorful pens and two automatic machines drawing something with a pen on a sheet."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Kyoto University of Art and Design, Kyoto, Japan & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2020 March 16-18, 1-7 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Students of Kyoto University of Art and Design, and anyone.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Making code as a tool for artistic expression.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/Day1-1-p5.js-i15dvmUETr4ef1xnydzru">Syllabus</a><p>&#x1F517; <a href="https://youtu.be/aS5CvADPdk0">Day 1</a>, <a href="https://youtu.be/ZCO-8CubifI">Day 2</a>, <a href="https://youtu.be/nbcckC5iwIcsyllabus">Day 3</a>, YouTube</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Religion</label><label>(Sub-)Culture</label><label>Political Opinion</label><label>Age</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #7-->
            +	
            +				  <div class="modal-content" id="case7"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Creative Coding for Static Graphics</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Coding in p5.js is a lot of fun. If you haven't started yet, I encourage you to give it a try!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://uc6d9323e0272069edcf30e9c501.previews.dropboxusercontent.com/p/thumb/AA5dvRUhxkQ9wLU6mHcrEmLvXnV7gbapPG2PvVf5K8K9ktlC59RCtvbSCP7YfEgPcFtnsgQekujWSD8iEfc6UT2pouzLdZUElblXhh9wg_b2UKDU-OO1u8VaiuC91g73tQX9S9mTHIgvm4h_Jw9-P4F6-iyjqBz57CvFWhilM5CpNbiPIjVRX6NsMkSYA3IexYreShT6Bt2hOWnorsocCsaafJiAd3cZbplWnGiuZmCn5R7BJ4u770YRjqX-AKh6AaoOb3kZHwBBnPQSU7zxiHqZbrWirjwLprw5D5UKW4bMI6We85Yn8cDPlJ6CktIqwpepAhdRi7scaxLxGnpIE4XjnoxK6T1jHkWZXGkvPplV1qlvrC7qz2jTY1_cULKcAcV8F-I-xvAL5I0n3rRHCZqr/p.jpeg?fv_content=true&size_mode=5" alt=""></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; FabCafe MTRL, Tokyo, Japan</p><p>&#x1F4C5; 2019 September 15, 4-7 PM </p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Anyone who wants to try coding in p5.js.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To code from the graphic design's perspective.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/--A6IUdC5pD_0QfbWt1PQ5u~PiAg-Fk8qxFWjaJWeH1cAc8FT0">Syllabus & Material</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Religion</label><label>(Sub-)Culture</label><label>Political Opinion</label><label>Age</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #8-->
            +	
            +				  <div class="modal-content" id="case8"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Generative Typography</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Dae In Chung</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://drive.google.com/uc?id=1TqcLurMLFioe8EcoJGtdK9_gs9bZ5odW" alt="A image with black background displaying the letter 'b' in 5 different styles along with a menu with various styling options to choose."></li>
            +
            +            	            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Baltimore, Maryland, USA & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2019 January 21 - May 08, every Wednesday, 4-10 PM</p></li>  
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>14 undergrads and grad students who had little to no experience in coding.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Experiment with typographic forms and structures through computation.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: online/offline lectures and critiques.</p><p>Materials: p5js online editor, Github, youtube tutorials.</p><p>&#x1F517; <a href="https://drive.google.com/drive/folders/15aFXijbqworOoLpc0fD283YOgi7UIHMA?usp=sharing">Works of participants</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Race & Ethnicity</label><label>Language</label><label>(Sub-)Culture</label><label>Skill Level</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +
            +				  <!--modal box #9-->
            +	
            +				  <div class="modal-content" id="case9"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Machine Learning for the Web</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Yining Shi</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://drive.google.com/uc?id=1pO3s4lraBwtLcZoCIeHGVncuwtzHqN6o" alt="A group of 16 people sitting around tables with their laptops, mobile phones and some other accessories, facing towards a large television screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; ITP, NYU, 370 Jay St, Brooklyn, NY 11201, USA</p><p>&#x1F4C5;2019 March 09 - October 12, every Tuesday, 6:30-9:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Students at Interactive Telecommunications Program, New York University. 16 people.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary, Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>The goal of this class is to learn and understand common machine learning techniques and apply them to generate creative outputs in the browser using ml5.js and p5.js.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>This class is a mix of lectures, coding sessions, group discussions, and presentations. I used <a href="https://github.com/yining1023/machine-learning-for-the-web">GitHub</a> to host class syllabus and all the coding materials, Google Slides for lectures and p5.js Web Editor for live coding sessions. Every week, there were one-on-one office hours to talk about any difficulties of coming up with an idea for the homework or any coding changes.</p><p>Methods: online/offline lectures and critiques.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Age</label><label>Skill Level</label><label>Occupation</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label><label>#BlackLivesMatter</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #10-->
            +	
            +				  <div class="modal-content" id="case10"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to p5.js and JavaScript</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Nico Reski</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date<p>&#x1F4CD; Currently available as self-study at own pace with accompanying slides, linked below.</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Beginner, Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Introduce learners (potentially with no coding experiences at all) to the very basics of p5.js (and JavaScript), in order to encourage creative coding and enable them to pursue own projects in a safe environment.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>p5.js source code (for the introductory project), JavaScript source code (illustrating some basic JavaScript functionalities), accompanying slides in .pdf format, all hosted publicly on GitHub. </p><p>&#x1F517; <a href="https://reski.nicoversity.com/ws_cc_p5js_introduction.html">Overview</a> of the workshop and its contents (including all links to the material hosted on GitHub) on my academic webpage.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #11-->
            +	
            +				  <div class="modal-content" id="case11"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Digital Weaving & Physical Computing Workshop Series</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Qianqian Ye & Evelyn Masso</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +				            <li class = "case"><img src="https://drive.google.com/uc?id=1QXtrew8S2YQ-_6R0H1FhwiEJj9_LLcpU" alt="This image is divided in two parts. The left part shows a group of 15 women sitting on chairs with their laptops and looking at a presentor who is explaining a code on a projected screen. The right part of the image shows a person learning weaving using a physical pattern and a weaving tool."></li>
            +
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Womens Center for Creative Work (WCCW), Los Angeles, CA, US</p><p>&#x1F4C5; 2019 October 19 - November 02, every Saturday 3-6 PM</p></li>  		
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>15 women and non-binary artists, designer, makers, programers. </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary
            +				            </p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Over the course of three workshops, we will draw and create patterns using p5.js, an open-source graphical library; we will learn and apply computational concepts to transform patterns and finally, we will bring a weaving to life with electronic microcontrollers.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: small team session</p><p>Materials: slides, p5.js web editor, pen and paper to draw pattern, physical pattern weaving tool.</p><p>&#x1F517; <a href="https://docs.google.com/presentation/d/1gJ67aKVGydSNoeUraS7U_QevcnOuxnSFQ_4640Qlifo/edit?usp=sharing">Workshop Slide #1</a>, <a href="https://docs.google.com/presentation/d/1nuje9-j_o5HbCoxXR_EJhAYmSEjTQOkAHmBsuKRlwwA/edit?usp=sharing">Workshop Slide #2</a></p><p>&#x1F517; <a href="https://womenscenterforcreativework.com/events/digital-weaving-physical-computing/">Workshop Information</a> on WCCW website.</p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +  				  <!--modal box #12-->
            +	
            +				  <div class="modal-content" id="case12"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Signing Coders</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Taeyoon Choi</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I'm working on a new series of coding class for Disabled students in South Korea. I'm researching about the pedagogy and translation. I plan to hold workshops in December 2020. The project is supported by the Open Society Foundation Human Rights Initiative and Korea Disability Arts & Culture Center."</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><img src="http://taeyoonchoi.com/wp-content/uploads/2016/04/day1-7852-768x512.jpg" alt="Two volunteers explaining concepts using a white board and a screen to a bunch of deaf and hard of hearing students, each student facing a computer screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD;  WRIC, New York City, USA & Seoul Museum of Art, Seoul, South Korea.</p><p>5 Sessions, each 2~3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Deaf and Hard of Hearing students age 10~50 who live in NYC.
            +				            </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To help Deaf and Hard of Hearing students learn about computer programming through playful exercises. To make ASL tutorial of basic coding concepts.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>We used p5.js Web editor and code examples on the website. We also used dice, playing cards and various paper tools to help students learn about coding concepts.</p><p>&#x1F517; <a href="http://taeyoonchoi.com/soft-care/signing-coders/">Syllabus & Material</a></p><p>&#x1F4F8; <a href="http://taeyoonchoi.com/soft-care/signing-coders/signing-coders-1/">More photos</a></p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Skill Level</label></li>
            +				         
            +
            +
            +				            </ul>
            +				        
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +			</div> <!--modal boxes end-->
            +
            +			
            +			
            +
            +	</section>
            +
            +
            +	<!--modal-->
            +
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Créditos</h2>
            +      <p>
            +        p5.js actualmente está dirigido por <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>y fue creado por<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> p5.js es desarrollado por una comunidad de colaboradores, con apoyo de <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> y <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identidad y diseño gráfico por <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/es/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +<!--jquery script-->
            +
            +<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
            +<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
            +<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
            +
            +
            +<!--filter search-->
            +
            +
            +<script>
            +    $("#filters :checkbox").click(function() {
            +
            +       var re = new RegExp($("#filters :checkbox:checked").map(function() {
            +                              return this.value;
            +                           }).get().join("|") ); //.join("|")
            +       $(".case-list").each(function() {
            +          var $this = $(this);
            +          $this[re.source!="" && re.test($this.attr("data-category")) ? "fadeIn" : "hide"]();
            +       });
            +    });
            +</script>
            +
            +
            +<!--modal box-->
            +
            +
            +<script>
            +$(document).on('click','.caseBtn',function(){
            +	var openModal =  $(this).attr('href');
            +	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +	
            +	$('#caseModals').fadeIn();
            +	$(openModal).fadeIn();
            +  return false;
            +});
            +
            +$("body" ).on( "click",".close", function() {
            +  	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +});
            +
            +</script>
            +
            +<!--search accordion menu-->
            +
            +<script>
            +
            +
            +var acc = document.getElementsByClassName("search-filter");
            +var i;
            +
            +for (i = 0; i < acc.length; i++) {
            +  acc[i].addEventListener("click", function() {
            +    this.classList.toggle("active");
            +    var panel = this.nextElementSibling;
            +    if (panel.style.maxHeight) {
            +      panel.style.maxHeight = null;
            +    } else {
            +      panel.style.maxHeight = panel.scrollHeight + "px";
            +    } 
            +
            +  });
            +}
            +</script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/es/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/examples/index.html b/dist/examples/index.html
            new file mode 100644
            index 0000000000..f55c77d645
            --- /dev/null
            +++ b/dist/examples/index.html
            @@ -0,0 +1,3381 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">examples | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="examples-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Examples</h1>
            +
            +      <div class="column_0 column">
            +      
            +        <h3 name='structure' class='anchor'>Structure</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="structure-comments-and-statements
            .html"
            +            
            +                data-en='Comments/Statements
            '
            +            
            +                data-es='Comments and Statements
            '
            +            
            +                data-hi='निर्देशांक
            '
            +            
            +                data-ko='스테이트멘트와 코멘트
            '
            +            
            +                data-zh-Hans='Comments and Statements
            '
            +            
            +          >Comments/Statements
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-coordinates
            .html"
            +            
            +                data-en='Coordinates
            '
            +            
            +                data-es='Coordenadas
            '
            +            
            +                data-hi='चौड़ाई और ऊंचाई
            '
            +            
            +                data-ko='좌표
            '
            +            
            +                data-zh-Hans='坐标
            '
            +            
            +          >Coordinates
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-width-and-height
            .html"
            +            
            +                data-en='Width/Height
            '
            +            
            +                data-es='width y height
            '
            +            
            +                data-hi='सेटअप और ड्रा
            '
            +            
            +                data-ko='너비와 높이
            '
            +            
            +                data-zh-Hans='Width 和 Height
            '
            +            
            +          >Width/Height
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-setup-and-draw
            .html"
            +            
            +                data-en='Setup/Draw
            '
            +            
            +                data-es='Setup y Draw
            '
            +            
            +                data-hi='और ड्रा
            '
            +            
            +                data-ko='설정하고 그리기
            '
            +            
            +                data-zh-Hans='Setup 与 Draw
            '
            +            
            +          >Setup/Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-no-loop
            .html"
            +            
            +                data-en='No Loop
            '
            +            
            +                data-es='No Loop
            '
            +            
            +                data-hi='लूप
            '
            +            
            +                data-ko='루프 중단
            '
            +            
            +                data-zh-Hans='No Loop
            '
            +            
            +          >No Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-loop
            .html"
            +            
            +                data-en='Loop
            '
            +            
            +                data-es='Bucle
            '
            +            
            +                data-hi='रेड्रा
            '
            +            
            +                data-ko='루프
            '
            +            
            +                data-zh-Hans='Loop
            '
            +            
            +          >Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-redraw
            .html"
            +            
            +                data-en='Redraw
            '
            +            
            +                data-es='Redraw
            '
            +            
            +                data-hi='कार्य
            '
            +            
            +                data-ko='다시 그리기
            '
            +            
            +                data-zh-Hans='Redraw
            '
            +            
            +          >Redraw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-functions
            .html"
            +            
            +                data-en='Functions
            '
            +            
            +                data-es='Funciones
            '
            +            
            +                data-hi='रिकर्सन
            '
            +            
            +                data-ko='그 외 함수들
            '
            +            
            +                data-zh-Hans='函数
            '
            +            
            +          >Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-recursion
            .html"
            +            
            +                data-en='Recursion
            '
            +            
            +                data-es='Recursión
            '
            +            
            +                data-hi='ग्राफिक्स बनाएं
            '
            +            
            +                data-ko='재귀 함수
            '
            +            
            +                data-zh-Hans='递归
            '
            +            
            +          >Recursion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-create-graphics
            .html"
            +            
            +                data-en='Create Graphics
            '
            +            
            +                data-es='createGraphics
            '
            +            
            +                data-ko='그래픽 만들기
            '
            +            
            +                data-zh-Hans='Create Graphics
            '
            +            
            +          >Create Graphics
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='form' class='anchor'>Form</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="form-points-and-lines
            .html"
            +            
            +                data-en='Points/Lines
            '
            +            
            +                data-es='Puntos y líneas
            '
            +            
            +                data-hi='अंक और रेखाएं
            '
            +            
            +                data-ko='점과 선
            '
            +            
            +                data-zh-Hans='Points 与 Lines
            '
            +            
            +          >Points/Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-shape-primitives
            .html"
            +            
            +                data-en='Shape Primitives
            '
            +            
            +                data-es='Figuras primitivas
            '
            +            
            +                data-hi='शेप प्रिमिटिव्स
            '
            +            
            +                data-ko='기본 조형
            '
            +            
            +                data-zh-Hans='基本形状
            '
            +            
            +          >Shape Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-pie-chart
            .html"
            +            
            +                data-en='Pie Chart
            '
            +            
            +                data-es='Gráfico de sectores
            '
            +            
            +                data-hi='पाई चार्ट
            '
            +            
            +                data-ko='파이형 차트
            '
            +            
            +                data-zh-Hans='饼状图
            '
            +            
            +          >Pie Chart
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-regular-polygon
            .html"
            +            
            +                data-en='Regular Polygon
            '
            +            
            +                data-es='Polígono regular
            '
            +            
            +                data-hi='नियमित बहुभुज
            '
            +            
            +                data-ko='정다각형
            '
            +            
            +                data-zh-Hans='正多边形
            '
            +            
            +          >Regular Polygon
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-star
            .html"
            +            
            +                data-en='Star
            '
            +            
            +                data-es='Estrella
            '
            +            
            +                data-hi='स्टार
            '
            +            
            +                data-ko='별모양
            '
            +            
            +                data-zh-Hans='Star
            '
            +            
            +          >Star
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-triangle-strip
            .html"
            +            
            +                data-en='Triangle Strip
            '
            +            
            +                data-es='Tira de triángulos
            '
            +            
            +                data-hi='त्रिभुज पट्टी
            '
            +            
            +                data-ko='삼각형 고리
            '
            +            
            +                data-zh-Hans='Triangle Strip
            '
            +            
            +          >Triangle Strip
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-bezier
            .html"
            +            
            +                data-en='Bezier
            '
            +            
            +                data-es='Bezier
            '
            +            
            +                data-hi='बेज़ियर
            '
            +            
            +                data-ko='베지어 곡선
            '
            +            
            +                data-zh-Hans='Bezier
            '
            +            
            +          >Bezier
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-3d-primitives
            .html"
            +            
            +                data-en='3D Primitives
            '
            +            
            +                data-es='Primitivas 3D
            '
            +            
            +                data-hi='३डी प्रिमिटिव्स
            '
            +            
            +                data-ko='3D 기본 조형
            '
            +            
            +                data-zh-Hans='基本 3D 形状
            '
            +            
            +          >3D Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-trig-wheels-and-pie-chart
            .html"
            +            
            +                data-en='Trig Wheels/Pie Chart
            '
            +            
            +                data-es='Trig Wheels and Pie Chart
            '
            +            
            +                data-ko='단위원과 파이 차트
            '
            +            
            +                data-zh-Hans='Trig Wheels and Pie Chart
            '
            +            
            +          >Trig Wheels/Pie Chart
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='data' class='anchor'>Data</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="data-variables
            .html"
            +            
            +                data-en='Variables
            '
            +            
            +                data-es='Variables
            '
            +            
            +                data-hi='चर
            '
            +            
            +                data-ko='변수
            '
            +            
            +                data-zh-Hans='变量
            '
            +            
            +          >Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-true-and-false
            .html"
            +            
            +                data-en='True/False
            '
            +            
            +                data-es='True y False
            '
            +            
            +                data-hi='सही और गलत
            '
            +            
            +                data-ko='참과 거짓
            '
            +            
            +                data-zh-Hans='True 和 False
            '
            +            
            +          >True/False
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-variable-scope
            .html"
            +            
            +                data-en='Variable Scope
            '
            +            
            +                data-es='Alcance de variabless
            '
            +            
            +                data-hi='परिवर्तनीय दायरा
            '
            +            
            +                data-ko='변수 범위
            '
            +            
            +                data-zh-Hans='变量范围
            '
            +            
            +          >Variable Scope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-numbers
            .html"
            +            
            +                data-en='Numbers
            '
            +            
            +                data-es='Números
            '
            +            
            +                data-hi='नंबर
            '
            +            
            +                data-ko='숫자값
            '
            +            
            +                data-zh-Hans='Numbers
            '
            +            
            +          >Numbers
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='arrays' class='anchor'>Arrays</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="arrays-array
            .html"
            +            
            +                data-en='Array
            '
            +            
            +                data-es='Arreglo
            '
            +            
            +                data-hi='ऐरे
            '
            +            
            +                data-ko='배열
            '
            +            
            +                data-zh-Hans='数组
            '
            +            
            +          >Array
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-2d
            .html"
            +            
            +                data-en='Array 2D
            '
            +            
            +                data-es='Arreglo 2D
            '
            +            
            +                data-hi='ऐरे 2D
            '
            +            
            +                data-ko='2D 배열
            '
            +            
            +                data-zh-Hans='2D 数组
            '
            +            
            +          >Array 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-objects
            .html"
            +            
            +                data-en='Array Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='ऐरे ऑब्जेक्ट्स
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='数组对象
            '
            +            
            +          >Array Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-walk-over-2darray
            .html"
            +            
            +                data-en='Walk Over 2dArray
            '
            +            
            +                data-es='Walk Over 2dArray
            '
            +            
            +                data-ko='Walk Over 2dArray
            '
            +            
            +                data-zh-Hans='Walk Over 2dArray
            '
            +            
            +          >Walk Over 2dArray
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='control' class='anchor'>Control</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="control-iteration
            .html"
            +            
            +                data-en='Iteration
            '
            +            
            +                data-es='Iteración
            '
            +            
            +                data-hi='पुनरावृत्ति
            '
            +            
            +                data-ko='for 반복문
            '
            +            
            +                data-zh-Hans='迭代
            '
            +            
            +          >Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-embedded-iteration
            .html"
            +            
            +                data-en='Embedded Iteration
            '
            +            
            +                data-es='Iteración anidada
            '
            +            
            +                data-hi='एंबेडेड इटरेशन
            '
            +            
            +                data-ko='for 내장 반복문
            '
            +            
            +                data-zh-Hans='嵌入式迭代
            '
            +            
            +          >Embedded Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-1
            .html"
            +            
            +                data-en='Conditionals 1
            '
            +            
            +                data-es='Condicionales 1
            '
            +            
            +                data-hi='सशर्त 1
            '
            +            
            +                data-ko='조건문 1
            '
            +            
            +                data-zh-Hans='条件 1
            '
            +            
            +          >Conditionals 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-2
            .html"
            +            
            +                data-en='Conditionals 2
            '
            +            
            +                data-es='Condicionales 2
            '
            +            
            +                data-hi='सशर्त 2
            '
            +            
            +                data-ko='조건문 2
            '
            +            
            +                data-zh-Hans='条件 2
            '
            +            
            +          >Conditionals 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators
            .html"
            +            
            +                data-en='Logical Operators
            '
            +            
            +                data-es='Operadores lógicos
            '
            +            
            +                data-hi='लॉजिकल ऑपरेटर्स
            '
            +            
            +                data-ko='논리적 연산자
            '
            +            
            +                data-zh-Hans='逻辑操作符
            '
            +            
            +          >Logical Operators
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators-2
            .html"
            +            
            +                data-en='Logical Operators 2
            '
            +            
            +                data-es='Logical Operators 2
            '
            +            
            +                data-ko='Logical Operators 2
            '
            +            
            +                data-zh-Hans='Logical Operators 2
            '
            +            
            +          >Logical Operators 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditional-shapes
            .html"
            +            
            +                data-en='Conditional Shapes
            '
            +            
            +                data-es='Conditional Shapes
            '
            +            
            +                data-ko='Conditional Shapes
            '
            +            
            +                data-zh-Hans='Conditional Shapes
            '
            +            
            +          >Conditional Shapes
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='image' class='anchor'>Image</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="image-load-and-display-image
            .html"
            +            
            +                data-en='Load/Display Image
            '
            +            
            +                data-es='Cargar y mostrar imagen
            '
            +            
            +                data-hi='लोड और डिस्प्ले इमेज
            '
            +            
            +                data-ko='이미지 불러오기 및 보이기
            '
            +            
            +                data-zh-Hans='加载(Load)和显示(Display)图像
            '
            +            
            +          >Load/Display Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-background-image
            .html"
            +            
            +                data-en='Background Image
            '
            +            
            +                data-es='Imagen de fondo
            '
            +            
            +                data-hi='पृष्ठभूमि छवि
            '
            +            
            +                data-ko='배경 이미지
            '
            +            
            +                data-zh-Hans='背景图像
            '
            +            
            +          >Background Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-transparency
            .html"
            +            
            +                data-en='Transparency
            '
            +            
            +                data-es='Transparencia
            '
            +            
            +                data-hi='पारदर्शिता
            '
            +            
            +                data-ko='투명도
            '
            +            
            +                data-zh-Hans='透明度
            '
            +            
            +          >Transparency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-alpha-mask
            .html"
            +            
            +                data-en='Alpha Mask
            '
            +            
            +                data-es='Alpha Mask
            '
            +            
            +                data-hi='अल्फा मास्क
            '
            +            
            +                data-ko='알파 마스크
            '
            +            
            +                data-zh-Hans='透明度遮罩 (Alpha Mask)
            '
            +            
            +          >Alpha Mask
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-create-image
            .html"
            +            
            +                data-en='Create Image
            '
            +            
            +                data-es='Crear una imagen
            '
            +            
            +                data-hi='इमेज बनाएं
            '
            +            
            +                data-ko='이미지 만들기
            '
            +            
            +                data-zh-Hans='创建图像
            '
            +            
            +          >Create Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-pointillism
            .html"
            +            
            +                data-en='Pointillism
            '
            +            
            +                data-es='Puntillismo
            '
            +            
            +                data-hi='पॉइंटिलिज्म
            '
            +            
            +                data-ko='점묘법
            '
            +            
            +                data-zh-Hans='点画(Pointillism)
            '
            +            
            +          >Pointillism
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-blur
            .html"
            +            
            +                data-en='Blur
            '
            +            
            +                data-es='Blur
            '
            +            
            +                data-ko='Blur
            '
            +            
            +                data-zh-Hans='Blur
            '
            +            
            +          >Blur
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-edge-detection
            .html"
            +            
            +                data-en='Edge Detection
            '
            +            
            +                data-es='Edge Detection
            '
            +            
            +                data-ko='Edge Detection
            '
            +            
            +                data-zh-Hans='Edge Detection
            '
            +            
            +          >Edge Detection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brightness
            '
            +            
            +                data-ko='Brightness
            '
            +            
            +                data-zh-Hans='Brightness
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-convolution
            .html"
            +            
            +                data-en='Convolution
            '
            +            
            +                data-es='Convolution
            '
            +            
            +                data-ko='Convolution
            '
            +            
            +                data-zh-Hans='Convolution
            '
            +            
            +          >Convolution
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-copy-method
            .html"
            +            
            +                data-en='Copy() method
            '
            +            
            +                data-es='Método copy()
            '
            +            
            +                data-ko='Copy() method
            '
            +            
            +                data-zh-Hans='Copy() 函数
            '
            +            
            +          >Copy() method
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='color' class='anchor'>Color</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="color-hue
            .html"
            +            
            +                data-en='Hue
            '
            +            
            +                data-es='Tinte
            '
            +            
            +                data-hi='ह्यू
            '
            +            
            +                data-ko='색조
            '
            +            
            +                data-zh-Hans='色调
            '
            +            
            +          >Hue
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-saturation
            .html"
            +            
            +                data-en='Saturation
            '
            +            
            +                data-es='Saturación
            '
            +            
            +                data-hi='संतृप्ति
            '
            +            
            +                data-ko='채도
            '
            +            
            +                data-zh-Hans='饱和度
            '
            +            
            +          >Saturation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brillo
            '
            +            
            +                data-hi='चमक
            '
            +            
            +                data-ko='밝기
            '
            +            
            +                data-zh-Hans='亮度
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-color-variables
            .html"
            +            
            +                data-en='Color Variables
            '
            +            
            +                data-es='Variables de color
            '
            +            
            +                data-hi='रंग चर
            '
            +            
            +                data-ko='색상 변수
            '
            +            
            +                data-zh-Hans='颜色变量
            '
            +            
            +          >Color Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-relativity
            .html"
            +            
            +                data-en='Relativity
            '
            +            
            +                data-es='Relatividad
            '
            +            
            +                data-hi='सापेक्षता
            '
            +            
            +                data-ko='상대성
            '
            +            
            +                data-zh-Hans='相对性
            '
            +            
            +          >Relativity
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-linear-gradient
            .html"
            +            
            +                data-en='Linear Gradient
            '
            +            
            +                data-es='Gradiente linear
            '
            +            
            +                data-hi='रैखिक ढाल
            '
            +            
            +                data-ko='선형 그래디언트
            '
            +            
            +                data-zh-Hans='线性渐变
            '
            +            
            +          >Linear Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-radial-gradient
            .html"
            +            
            +                data-en='Radial Gradient
            '
            +            
            +                data-es='Gradiente radial
            '
            +            
            +                data-hi='रेडियल ग्रेडिएंट
            '
            +            
            +                data-ko='방사형 그래디언트
            '
            +            
            +                data-zh-Hans='径向渐变
            '
            +            
            +          >Radial Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-lerp-color
            .html"
            +            
            +                data-en='Lerp Color
            '
            +            
            +                data-es='Interpolación de color
            '
            +            
            +                data-hi='Lerp Color
            '
            +            
            +                data-ko='선형 보간(lerp) 색상
            '
            +            
            +                data-zh-Hans='插值颜色
            '
            +            
            +          >Lerp Color
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='math' class='anchor'>Math</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="math-increment-decrement
            .html"
            +            
            +                data-en='Increment Decrement
            '
            +            
            +                data-es='Incremento y decremento
            '
            +            
            +                data-hi='वेतन वृद्धि
            '
            +            
            +                data-ko='증가와 감소
            '
            +            
            +                data-zh-Hans='增量/减量
            '
            +            
            +          >Increment Decrement
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-operator-precedence
            .html"
            +            
            +                data-en='Operator Precedence
            '
            +            
            +                data-es='Precedencia de operadores
            '
            +            
            +                data-hi='ऑपरेटर वरीयता
            '
            +            
            +                data-ko='연산자 우선 순위
            '
            +            
            +                data-zh-Hans='操作符优先级
            '
            +            
            +          >Operator Precedence
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-1d
            .html"
            +            
            +                data-en='Distance 1D
            '
            +            
            +                data-es='Distancia 1D
            '
            +            
            +                data-hi='दूरी 1डी
            '
            +            
            +                data-ko='1D 거리
            '
            +            
            +                data-zh-Hans='一维间距
            '
            +            
            +          >Distance 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-2d
            .html"
            +            
            +                data-en='Distance 2D
            '
            +            
            +                data-es='Distancia 2D
            '
            +            
            +                data-hi='दूरी 2डी
            '
            +            
            +                data-ko='2D 거리
            '
            +            
            +                data-zh-Hans='二维间距
            '
            +            
            +          >Distance 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine
            .html"
            +            
            +                data-en='Sine
            '
            +            
            +                data-es='Seno
            '
            +            
            +                data-hi='साइन
            '
            +            
            +                data-ko='사인
            '
            +            
            +                data-zh-Hans='正弦
            '
            +            
            +          >Sine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-cosine
            .html"
            +            
            +                data-en='Sine Cosine
            '
            +            
            +                data-es='Seno y coseno
            '
            +            
            +                data-hi='साइन कोसाइन
            '
            +            
            +                data-ko='사인 코사인
            '
            +            
            +                data-zh-Hans='正弦余弦
            '
            +            
            +          >Sine Cosine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-wave
            .html"
            +            
            +                data-en='Sine Wave
            '
            +            
            +                data-es='Onda sinusoidal
            '
            +            
            +                data-hi='साइन वेव
            '
            +            
            +                data-ko='사인파
            '
            +            
            +                data-zh-Hans='正弦波
            '
            +            
            +          >Sine Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-additive-wave
            .html"
            +            
            +                data-en='Additive Wave
            '
            +            
            +                data-es='Onda aditiva
            '
            +            
            +                data-hi='Additive Wave
            '
            +            
            +                data-ko='파형 추가
            '
            +            
            +                data-zh-Hans='加性波
            '
            +            
            +          >Additive Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-polartocartesian
            .html"
            +            
            +                data-en='PolarToCartesian
            '
            +            
            +                data-es='Polar a cartesiano
            '
            +            
            +                data-hi='PolarToCartesian
            '
            +            
            +                data-ko='극좌표를 직교 좌표로
            '
            +            
            +                data-zh-Hans='PolarToCartesian
            '
            +            
            +          >PolarToCartesian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-arctangent
            .html"
            +            
            +                data-en='Arctangent
            '
            +            
            +                data-es='Arcotangente
            '
            +            
            +                data-hi='आर्कटिक
            '
            +            
            +                data-ko='아크탄젠트
            '
            +            
            +                data-zh-Hans='反正切
            '
            +            
            +          >Arctangent
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-linear-interpolation
            .html"
            +            
            +                data-en='Linear Interpolation
            '
            +            
            +                data-es='Interpolación Lineal
            '
            +            
            +                data-hi='रैखिक इंटरपोलेशन
            '
            +            
            +                data-ko='선형 보간법
            '
            +            
            +                data-zh-Hans='线性插值
            '
            +            
            +          >Linear Interpolation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-double-random
            .html"
            +            
            +                data-en='Double Random
            '
            +            
            +                data-es='Doble aleatorio
            '
            +            
            +                data-hi='डबल रैंडम
            '
            +            
            +                data-ko='이중 랜덤
            '
            +            
            +                data-zh-Hans='双重随机
            '
            +            
            +          >Double Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random
            .html"
            +            
            +                data-en='Random
            '
            +            
            +                data-es='Aleatorio
            '
            +            
            +                data-hi='रैंडम
            '
            +            
            +                data-ko='랜덤
            '
            +            
            +                data-zh-Hans='随机
            '
            +            
            +          >Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise1d
            .html"
            +            
            +                data-en='Noise1D
            '
            +            
            +                data-es='Ruido 1D
            '
            +            
            +                data-hi='Noise1D
            '
            +            
            +                data-ko='1D 노이즈
            '
            +            
            +                data-zh-Hans='一维噪声 (Noise1D)
            '
            +            
            +          >Noise1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise-wave
            .html"
            +            
            +                data-en='Noise Wave
            '
            +            
            +                data-es='Onda de ruido
            '
            +            
            +                data-hi='शोर लहर
            '
            +            
            +                data-ko='노이즈 파형
            '
            +            
            +                data-zh-Hans='噪声波
            '
            +            
            +          >Noise Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise2d
            .html"
            +            
            +                data-en='Noise2D
            '
            +            
            +                data-es='Ruido 2D
            '
            +            
            +                data-hi='Noise2D
            '
            +            
            +                data-ko='2D 노이즈
            '
            +            
            +                data-zh-Hans='二维噪声 (Noise2D)
            '
            +            
            +          >Noise2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise3d
            .html"
            +            
            +                data-en='Noise3D
            '
            +            
            +                data-es='Ruido 3D
            '
            +            
            +                data-hi='Noise3D
            '
            +            
            +                data-ko='3D 노이즈
            '
            +            
            +                data-zh-Hans='三维噪声 (Noise3D)
            '
            +            
            +          >Noise3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-chords
            .html"
            +            
            +                data-en='Random Chords
            '
            +            
            +                data-es='Cuerdas Aleatorias
            '
            +            
            +                data-hi='रैंडम कॉर्ड्स
            '
            +            
            +                data-ko='랜덤 선들
            '
            +            
            +                data-zh-Hans='随机弦
            '
            +            
            +          >Random Chords
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-gaussian
            .html"
            +            
            +                data-en='Random Gaussian
            '
            +            
            +                data-es='Mapear
            '
            +            
            +                data-hi='नक्शा
            '
            +            
            +                data-ko='매핑(map)
            '
            +            
            +                data-zh-Hans='映射 (Map)
            '
            +            
            +          >Random Gaussian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-map
            .html"
            +            
            +                data-en='Map
            '
            +            
            +                data-es='Ecuaciones Paramétricas
            '
            +            
            +                data-hi='पैरामीट्रिक समीकरण
            '
            +            
            +                data-ko='매개변수 방정식
            '
            +            
            +                data-zh-Hans='参数方程
            '
            +            
            +          >Map
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-graphing-2d-equations
            .html"
            +            
            +                data-en='Graphing 2D Equations
            '
            +            
            +                data-es='Graphing 2D Equations
            '
            +            
            +                data-ko='Graphing 2D Equations
            '
            +            
            +                data-zh-Hans='Graphing 2D Equations
            '
            +            
            +          >Graphing 2D Equations
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-parametric-equations
            .html"
            +            
            +                data-en='Parametric Equations
            '
            +            
            +                data-es='Parametric Equations
            '
            +            
            +                data-ko='Parametric Equations
            '
            +            
            +                data-zh-Hans='Parametric Equations
            '
            +            
            +          >Parametric Equations
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_1 column">
            +        
            +      
            +        <h3 name='simulate' class='anchor'>Simulate</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="simulate-forces
            .html"
            +            
            +                data-en='Forces
            '
            +            
            +                data-es='Fuerzas
            '
            +            
            +                data-hi='बल
            '
            +            
            +                data-ko='힘
            '
            +            
            +                data-zh-Hans='Forces
            '
            +            
            +          >Forces
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particle-system
            .html"
            +            
            +                data-en='Particle System
            '
            +            
            +                data-es='Sistema de partículas
            '
            +            
            +                data-hi='कण प्रणाली
            '
            +            
            +                data-ko='파티클 시스템
            '
            +            
            +                data-zh-Hans='Particle System
            '
            +            
            +          >Particle System
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-wolfram-ca
            .html"
            +            
            +                data-en='Wolfram CA
            '
            +            
            +                data-es='Wolfram CA
            '
            +            
            +                data-hi='वोल्फ्राम सीए
            '
            +            
            +                data-ko='울프램 셀룰러 오토마타
            '
            +            
            +                data-zh-Hans='Wolfram CA
            '
            +            
            +          >Wolfram CA
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-game-of-life
            .html"
            +            
            +                data-en='Game of Life
            '
            +            
            +                data-es='Juego de la vida
            '
            +            
            +                data-hi='Game of Life
            '
            +            
            +                data-ko='라이프 게임
            '
            +            
            +                data-zh-Hans='Game of Life
            '
            +            
            +          >Game of Life
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-multiple-particle-systems
            .html"
            +            
            +                data-en='Multiple Particle Systems
            '
            +            
            +                data-es='Múltiples sistemas de partículas
            '
            +            
            +                data-hi='मल्टीपल पार्टिकल सिस्टम
            '
            +            
            +                data-ko='멀티플 파티클 시스템
            '
            +            
            +                data-zh-Hans='Multiple Particle Systems
            '
            +            
            +          >Multiple Particle Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spirograph
            .html"
            +            
            +                data-en='Spirograph
            '
            +            
            +                data-es='Espirógrafo
            '
            +            
            +                data-hi='स्पाइरोग्राफ
            '
            +            
            +                data-ko='스피로그래프
            '
            +            
            +                data-zh-Hans='Spirograph
            '
            +            
            +          >Spirograph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-l-systems
            .html"
            +            
            +                data-en='L-Systems
            '
            +            
            +                data-es='Sístemas-L
            '
            +            
            +                data-hi='एल-सिस्टम्स
            '
            +            
            +                data-ko='L-시스템
            '
            +            
            +                data-zh-Hans='L-Systems
            '
            +            
            +          >L-Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spring
            .html"
            +            
            +                data-en='Spring
            '
            +            
            +                data-es='Resorte
            '
            +            
            +                data-hi='वसंत
            '
            +            
            +                data-ko='용수철
            '
            +            
            +                data-zh-Hans='Spring
            '
            +            
            +          >Spring
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-springs
            .html"
            +            
            +                data-en='Springs
            '
            +            
            +                data-es='Resortes
            '
            +            
            +                data-hi='स्प्रिंग्स
            '
            +            
            +                data-ko='용수철들
            '
            +            
            +                data-zh-Hans='Springs
            '
            +            
            +          >Springs
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-soft-body
            .html"
            +            
            +                data-en='Soft Body
            '
            +            
            +                data-es='Cuerpo blando
            '
            +            
            +                data-hi='शीतल शरीर
            '
            +            
            +                data-ko='소프트 바디
            '
            +            
            +                data-zh-Hans='Soft Body
            '
            +            
            +          >Soft Body
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-smokeparticles
            .html"
            +            
            +                data-en='SmokeParticles
            '
            +            
            +                data-es='Partículas de humo
            '
            +            
            +                data-hi='स्मोकपार्टिकल्स
            '
            +            
            +                data-ko='연기 파티클
            '
            +            
            +                data-zh-Hans='SmokeParticles
            '
            +            
            +          >SmokeParticles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Movimiento browniano
            '
            +            
            +                data-hi='ब्राउनियन मोशन
            '
            +            
            +                data-ko='브라운 운동
            '
            +            
            +                data-zh-Hans='Brownian Motion
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-chain
            .html"
            +            
            +                data-en='Chain
            '
            +            
            +                data-es='Cadena
            '
            +            
            +                data-hi='चैन
            '
            +            
            +                data-ko='사슬
            '
            +            
            +                data-zh-Hans='Chain
            '
            +            
            +          >Chain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-snowflakes
            .html"
            +            
            +                data-en='Snowflakes
            '
            +            
            +                data-es='Copos de Nieve
            '
            +            
            +                data-hi='स्नोफ्लेक्स
            '
            +            
            +                data-ko='눈송이 파티클
            '
            +            
            +                data-zh-Hans='Snowflakes
            '
            +            
            +          >Snowflakes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-penrose-tiles
            .html"
            +            
            +                data-en='Penrose Tiles
            '
            +            
            +                data-es='Baldosas de Penrose
            '
            +            
            +                data-hi='पेनरोज़ टाइलें
            '
            +            
            +                data-ko='펜로즈 타일
            '
            +            
            +                data-zh-Hans='Penrose Tiles
            '
            +            
            +          >Penrose Tiles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-recursive-tree
            .html"
            +            
            +                data-en='Recursive Tree
            '
            +            
            +                data-es='Árbol Recursivo
            '
            +            
            +                data-hi='रिकर्सिव ट्री
            '
            +            
            +                data-ko='재귀 나무
            '
            +            
            +                data-zh-Hans='Recursive Tree
            '
            +            
            +          >Recursive Tree
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-the-mandelbrot-set
            .html"
            +            
            +                data-en='The Mandelbrot Set
            '
            +            
            +                data-es='El Conjunto de Mandelbrot
            '
            +            
            +                data-hi='मंडेलब्रॉट सेत
            '
            +            
            +                data-ko='망델브로 집합
            '
            +            
            +                data-zh-Hans='The Mandelbrot Set
            '
            +            
            +          >The Mandelbrot Set
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-koch-curve
            .html"
            +            
            +                data-en='Koch Curve
            '
            +            
            +                data-es='Curva Koch
            '
            +            
            +                data-hi='कोच कर्व
            '
            +            
            +                data-ko='코흐 곡선
            '
            +            
            +                data-zh-Hans='Koch Curve
            '
            +            
            +          >Koch Curve
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-bubble-sort
            .html"
            +            
            +                data-en='Bubble Sort
            '
            +            
            +                data-es='Ordenamiento de Burbuja
            '
            +            
            +                data-hi='बबल सॉर्ट
            '
            +            
            +                data-ko='버블 정렬
            '
            +            
            +                data-zh-Hans='Bubble Sort
            '
            +            
            +          >Bubble Sort
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-stepping-feet-illusion
            .html"
            +            
            +                data-en='Stepping Feet Illusion
            '
            +            
            +                data-es='Ilusión de los Pasos
            '
            +            
            +                data-hi='स्टेपिंग फीट इल्यूजन
            '
            +            
            +                data-ko='걷는발 착시효과
            '
            +            
            +                data-zh-Hans='Stepping Feet Illusion
            '
            +            
            +          >Stepping Feet Illusion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particles
            .html"
            +            
            +                data-en='Particles
            '
            +            
            +                data-es='Partículas
            '
            +            
            +                data-hi='कण
            '
            +            
            +                data-ko='파티클
            '
            +            
            +                data-zh-Hans='Particles
            '
            +            
            +          >Particles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-quicksort
            .html"
            +            
            +                data-en='Quicksort
            '
            +            
            +                data-es='Quicksort
            '
            +            
            +                data-ko='Quicksort
            '
            +            
            +                data-zh-Hans='Quicksort
            '
            +            
            +          >Quicksort
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='interaction' class='anchor'>Interaction</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="interaction-tickle
            .html"
            +            
            +                data-en='Tickle
            '
            +            
            +                data-es='Cosquillas
            '
            +            
            +                data-hi='टिकल 
            '
            +            
            +                data-ko='간질간질
            '
            +            
            +                data-zh-Hans='Tickle
            '
            +            
            +          >Tickle
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-weight-line
            .html"
            +            
            +                data-en='Weight Line
            '
            +            
            +                data-es='Weight Line
            '
            +            
            +                data-hi='फॉलो 1
            '
            +            
            +                data-ko='Weight Line
            '
            +            
            +                data-zh-Hans='Weight Line
            '
            +            
            +          >Weight Line
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-1
            .html"
            +            
            +                data-en='Follow 1
            '
            +            
            +                data-es='Seguir 1
            '
            +            
            +                data-hi='फॉलो 2
            '
            +            
            +                data-ko='따라다니기 1
            '
            +            
            +                data-zh-Hans='跟随 1
            '
            +            
            +          >Follow 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-2
            .html"
            +            
            +                data-en='Follow 2
            '
            +            
            +                data-es='Seguir 2
            '
            +            
            +                data-hi='फॉलो 3
            '
            +            
            +                data-ko='따라다니기 2
            '
            +            
            +                data-zh-Hans='跟随 2
            '
            +            
            +          >Follow 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-3
            .html"
            +            
            +                data-en='Follow 3
            '
            +            
            +                data-es='Seguir 3
            '
            +            
            +                data-hi='सांप का खेल
            '
            +            
            +                data-ko='따라다니기 3
            '
            +            
            +                data-zh-Hans='跟随 3
            '
            +            
            +          >Follow 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-snake-game
            .html"
            +            
            +                data-en='Snake game
            '
            +            
            +                data-es='Juego de Serpiente
            '
            +            
            +                data-hi='वेवमेकर
            '
            +            
            +                data-ko='스네이크 게임
            '
            +            
            +                data-zh-Hans='贪吃蛇
            '
            +            
            +          >Snake game
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-wavemaker
            .html"
            +            
            +                data-en='Wavemaker
            '
            +            
            +                data-es='Wavemaker
            '
            +            
            +                data-hi='रीच 1
            '
            +            
            +                data-ko='파도 만들기
            '
            +            
            +                data-zh-Hans='造波器
            '
            +            
            +          >Wavemaker
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-1
            .html"
            +            
            +                data-en='Reach 1
            '
            +            
            +                data-es='Alcanzar 1
            '
            +            
            +                data-hi='रीच 2
            '
            +            
            +                data-ko='팔닿기 1
            '
            +            
            +                data-zh-Hans='延伸 1
            '
            +            
            +          >Reach 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-2
            .html"
            +            
            +                data-en='Reach 2
            '
            +            
            +                data-es='Alcanzar 2
            '
            +            
            +                data-hi='पहुंच ३
            '
            +            
            +                data-ko='팔닿기 2
            '
            +            
            +                data-zh-Hans='延伸 2
            '
            +            
            +          >Reach 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-3
            .html"
            +            
            +                data-en='Reach 3
            '
            +            
            +                data-es='Alcanzar 3
            '
            +            
            +                data-hi='Arduino सेंसर डेटा WebJack के माध्यम से
            '
            +            
            +                data-ko='팔닿기 3
            '
            +            
            +                data-zh-Hans='延伸 3
            '
            +            
            +          >Reach 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-arduino-sensor-data-via-webjack
            .html"
            +            
            +                data-en='Arduino sensor data via WebJack
            '
            +            
            +                data-es='Datos de un sensor Arduino vía WebJack
            '
            +            
            +                data-hi='बहुरूपदर्शक
            '
            +            
            +                data-ko='웹잭과 아두이노 센서 데이터
            '
            +            
            +                data-zh-Hans='通过 WebJack 读取 Arduino 传感器数据
            '
            +            
            +          >Arduino sensor data via WebJack
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-kaleidoscope
            .html"
            +            
            +                data-en='Kaleidoscope
            '
            +            
            +                data-es='Caleidoscopio
            '
            +            
            +                data-ko='만화경
            '
            +            
            +                data-zh-Hans='万花筒
            '
            +            
            +          >Kaleidoscope
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='objects' class='anchor'>Objects</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="objects-objects
            .html"
            +            
            +                data-en='Objects
            '
            +            
            +                data-es='Objetos
            '
            +            
            +                data-hi='वस्तु
            '
            +            
            +                data-ko='객체
            '
            +            
            +                data-zh-Hans='物件 (Objects)
            '
            +            
            +          >Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-multiple-objects
            .html"
            +            
            +                data-en='Multiple Objects
            '
            +            
            +                data-es='Múltiples objetos
            '
            +            
            +                data-hi='वस्तुओं का नाम दें
            '
            +            
            +                data-ko='복수 객체
            '
            +            
            +                data-zh-Hans='多个物件
            '
            +            
            +          >Multiple Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-array-of-objects
            .html"
            +            
            +                data-en='Array of Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='वस्तुओं की सरणी
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='物件数组
            '
            +            
            +          >Array of Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-objects-2
            .html"
            +            
            +                data-en='Objects 2
            '
            +            
            +                data-es='Objetos 2
            '
            +            
            +                data-hi='वस्तु 2
            '
            +            
            +                data-ko='객체 2
            '
            +            
            +                data-zh-Hans='物件 2
            '
            +            
            +          >Objects 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-inheritance
            .html"
            +            
            +                data-en='Inheritance
            '
            +            
            +                data-es='Herencia
            '
            +            
            +                data-hi='वंशानुक्रम
            '
            +            
            +                data-ko='상속
            '
            +            
            +                data-zh-Hans='继承 (Inheritance)
            '
            +            
            +          >Inheritance
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-composite-objects
            .html"
            +            
            +                data-en='Composite Objects
            '
            +            
            +                data-es='Objetos Compuestos
            '
            +            
            +                data-hi='समग्र वस्तु
            '
            +            
            +                data-ko='합성 객체
            '
            +            
            +                data-zh-Hans='复合物件
            '
            +            
            +          >Composite Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-car-instances
            .html"
            +            
            +                data-en='Car Instances
            '
            +            
            +                data-es='Car Instances
            '
            +            
            +                data-ko='Car Instances
            '
            +            
            +                data-zh-Hans='Car Instances
            '
            +            
            +          >Car Instances
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='lights' class='anchor'>Lights</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="lights-directional
            .html"
            +            
            +                data-en='Directional
            '
            +            
            +                data-es='Direccional
            '
            +            
            +                data-hi='दिशात्मक
            '
            +            
            +                data-ko='디렉셔널 라이트
            '
            +            
            +                data-zh-Hans='定向光
            '
            +            
            +          >Directional
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="lights-mixture
            .html"
            +            
            +                data-en='Mixture
            '
            +            
            +                data-es='Mezcla
            '
            +            
            +                data-hi='मिश्रण
            '
            +            
            +                data-ko='혼합 라이트
            '
            +            
            +                data-zh-Hans='混合光
            '
            +            
            +          >Mixture
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='motion' class='anchor'>Motion</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="motion-non-orthogonal-reflection
            .html"
            +            
            +                data-en='Non Orthogonal Reflection
            '
            +            
            +                data-es='Reflejo no ortogonal
            '
            +            
            +                data-hi='नॉन ऑर्थोगोनल रिफ्लेक्शन
            '
            +            
            +                data-ko='비직각 반사
            '
            +            
            +                data-zh-Hans='Non Orthogonal Reflection
            '
            +            
            +          >Non Orthogonal Reflection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-linear
            .html"
            +            
            +                data-en='Linear
            '
            +            
            +                data-es='Lineal
            '
            +            
            +                data-hi='रैखिक
            '
            +            
            +                data-ko='선형
            '
            +            
            +                data-zh-Hans='Linear
            '
            +            
            +          >Linear
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bounce
            .html"
            +            
            +                data-en='Bounce
            '
            +            
            +                data-es='Rebote
            '
            +            
            +                data-hi='उछाल
            '
            +            
            +                data-ko='바운스
            '
            +            
            +                data-zh-Hans='Bounce
            '
            +            
            +          >Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bouncy-bubbles
            .html"
            +            
            +                data-en='Bouncy Bubbles
            '
            +            
            +                data-es='Burbujas Saltarinas
            '
            +            
            +                data-hi='उछाल वाले बुलबुले
            '
            +            
            +                data-ko='버블 바운스
            '
            +            
            +                data-zh-Hans='Bouncy Bubbles
            '
            +            
            +          >Bouncy Bubbles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Transformar
            '
            +            
            +                data-hi='मॉर्फ
            '
            +            
            +                data-ko='변형(morph)
            '
            +            
            +                data-zh-Hans='Morph
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-morph
            .html"
            +            
            +                data-en='Morph
            '
            +            
            +                data-es='Moviéndose por Curvas
            '
            +            
            +                data-hi='मूविंग ऑन कर्व्स
            '
            +            
            +                data-ko='곡선 위 움직이기
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Morph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-circle-collision
            .html"
            +            
            +                data-en='Circle Collision
            '
            +            
            +                data-es='Circle Collision
            '
            +            
            +                data-ko='Circle Collision
            '
            +            
            +                data-zh-Hans='Circle Collision
            '
            +            
            +          >Circle Collision
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-moving-on-curves
            .html"
            +            
            +                data-en='Moving On Curves
            '
            +            
            +                data-es='Moving On Curves
            '
            +            
            +                data-ko='Moving On Curves
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Moving On Curves
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='instance_mode' class='anchor'>Instance Mode</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="instance-mode-instantiation
            .html"
            +            
            +                data-en='Instantiation
            '
            +            
            +                data-es='Instaciación
            '
            +            
            +                data-hi='इंस्टेंटेशन
            '
            +            
            +                data-ko='인스턴스화
            '
            +            
            +                data-zh-Hans='创建实例
            '
            +            
            +          >Instantiation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="instance-mode-instance-container
            .html"
            +            
            +                data-en='Instance Container
            '
            +            
            +                data-es='Contenedor de instancia
            '
            +            
            +                data-hi='इंस्टेंस कंटेनर
            '
            +            
            +                data-ko='인스턴스 컨테이너
            '
            +            
            +                data-zh-Hans='实例容器
            '
            +            
            +          >Instance Container
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='dom' class='anchor'>DOM</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="dom-input-and-button
            .html"
            +            
            +                data-en='Input/Button
            '
            +            
            +                data-es='Entrada y botón
            '
            +            
            +                data-hi='इनपुट और बटन
            '
            +            
            +                data-ko='입력과 버튼
            '
            +            
            +                data-zh-Hans='Input and Button
            '
            +            
            +          >Input/Button
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-slider
            .html"
            +            
            +                data-en='Slider
            '
            +            
            +                data-es='Barra deslizante
            '
            +            
            +                data-hi='स्लाइडर
            '
            +            
            +                data-ko='슬라이더
            '
            +            
            +                data-zh-Hans='Slider
            '
            +            
            +          >Slider
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-modifying-the-dom
            .html"
            +            
            +                data-en='Modifying the DOM
            '
            +            
            +                data-es='Modificar el DOM
            '
            +            
            +                data-hi='डोम को संशोधित करना
            '
            +            
            +                data-ko='DOM 변경
            '
            +            
            +                data-zh-Hans='Modifying the DOM
            '
            +            
            +          >Modifying the DOM
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video
            .html"
            +            
            +                data-en='Video
            '
            +            
            +                data-es='Video
            '
            +            
            +                data-hi='वीडियो
            '
            +            
            +                data-ko='비디오
            '
            +            
            +                data-zh-Hans='Video
            '
            +            
            +          >Video
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-canvas
            .html"
            +            
            +                data-en='Video Canvas
            '
            +            
            +                data-es='Lienzo y video
            '
            +            
            +                data-hi='वीडियो कैनवास
            '
            +            
            +                data-ko='비디오 캔버스
            '
            +            
            +                data-zh-Hans='Video Canvas
            '
            +            
            +          >Video Canvas
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-pixels
            .html"
            +            
            +                data-en='Video Pixels
            '
            +            
            +                data-es='Pixeles de video
            '
            +            
            +                data-hi='वीडियो पिक्सल
            '
            +            
            +                data-ko='비디오 픽셀
            '
            +            
            +                data-zh-Hans='Video Pixels
            '
            +            
            +          >Video Pixels
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-capture
            .html"
            +            
            +                data-en='Video Capture
            '
            +            
            +                data-es='Captura de video
            '
            +            
            +                data-hi='वीडियो कैप्चर
            '
            +            
            +                data-ko='실시간 비디오
            '
            +            
            +                data-zh-Hans='Video Capture
            '
            +            
            +          >Video Capture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-drop
            .html"
            +            
            +                data-en='Drop
            '
            +            
            +                data-es='Arrojar
            '
            +            
            +                data-hi='छोड़ देना
            '
            +            
            +                data-ko='드롭 기능
            '
            +            
            +                data-zh-Hans='Drop
            '
            +            
            +          >Drop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-dom-form-elements
            .html"
            +            
            +                data-en='DOM Form Elements
            '
            +            
            +                data-es='DOM Form Elements
            '
            +            
            +                data-ko='DOM Form Elements
            '
            +            
            +                data-zh-Hans='DOM Form Elements
            '
            +            
            +          >DOM Form Elements
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='drawing' class='anchor'>Drawing</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="drawing-continuous-lines
            .html"
            +            
            +                data-en='Continuous Lines
            '
            +            
            +                data-es='Líneas continuas
            '
            +            
            +                data-hi='सतत रेखा 
            '
            +            
            +                data-ko='연속된 선
            '
            +            
            +                data-zh-Hans='Líneas continuas
            '
            +            
            +          >Continuous Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-patterns
            .html"
            +            
            +                data-en='Patterns
            '
            +            
            +                data-es='Patrones
            '
            +            
            +                data-hi='पैटर्न
            '
            +            
            +                data-ko='패턴
            '
            +            
            +                data-zh-Hans='Patrones
            '
            +            
            +          >Patterns
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-pulses
            .html"
            +            
            +                data-en='Pulses
            '
            +            
            +                data-es='Pulsos
            '
            +            
            +                data-hi='दालें
            '
            +            
            +                data-ko='율동
            '
            +            
            +                data-zh-Hans='Pulsos
            '
            +            
            +          >Pulses
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='transform' class='anchor'>Transform</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="transform-translate
            .html"
            +            
            +                data-en='Translate
            '
            +            
            +                data-es='Translate
            '
            +            
            +                data-hi='अनुवाद
            '
            +            
            +                data-ko='위치 이동(Translate)
            '
            +            
            +                data-zh-Hans='Translate
            '
            +            
            +          >Translate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-scale
            .html"
            +            
            +                data-en='Scale
            '
            +            
            +                data-es='Escalar
            '
            +            
            +                data-hi='स्केल
            '
            +            
            +                data-ko='크기 조정(Scale)
            '
            +            
            +                data-zh-Hans='Scale
            '
            +            
            +          >Scale
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-rotate
            .html"
            +            
            +                data-en='Rotate
            '
            +            
            +                data-es='Rotate
            '
            +            
            +                data-hi='घुमाएँ
            '
            +            
            +                data-ko='회전(Rotate)
            '
            +            
            +                data-zh-Hans='Rotate
            '
            +            
            +          >Rotate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-arm
            .html"
            +            
            +                data-en='Arm
            '
            +            
            +                data-es='Brazo
            '
            +            
            +                data-hi='आर्म
            '
            +            
            +                data-ko='팔모양
            '
            +            
            +                data-zh-Hans='Arm
            '
            +            
            +          >Arm
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_2 column">
            +        
            +      
            +        <h3 name='typography' class='anchor'>Typography</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="typography-letters
            .html"
            +            
            +                data-en='Letters
            '
            +            
            +                data-es='Letters
            '
            +            
            +                data-hi='पत्र
            '
            +            
            +                data-ko='글자
            '
            +            
            +                data-zh-Hans='Letters
            '
            +            
            +          >Letters
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-words
            .html"
            +            
            +                data-en='Words
            '
            +            
            +                data-es='Words
            '
            +            
            +                data-hi='शब्द
            '
            +            
            +                data-ko='단어
            '
            +            
            +                data-zh-Hans='Words
            '
            +            
            +          >Words
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-text-rotation
            .html"
            +            
            +                data-en='Text Rotation
            '
            +            
            +                data-es='Text Rotation
            '
            +            
            +                data-ko='텍스트 회전
            '
            +            
            +                data-zh-Hans='Text Rotation
            '
            +            
            +          >Text Rotation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='3d' class='anchor'>3D</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="3d-geometries
            .html"
            +            
            +                data-en='Geometries
            '
            +            
            +                data-es='Geometrías
            '
            +            
            +                data-hi='ज्यामिति
            '
            +            
            +                data-ko='기하
            '
            +            
            +                data-zh-Hans='Geometries
            '
            +            
            +          >Geometries
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-sine-cosine-in-3d
            .html"
            +            
            +                data-en='Sine Cosine in 3D
            '
            +            
            +                data-es='Seno Coseno en 3D
            '
            +            
            +                data-hi='3D में साइन कोसाइन
            '
            +            
            +                data-ko='3D속 사인 코사인
            '
            +            
            +                data-zh-Hans='Sine Cosine in 3D
            '
            +            
            +          >Sine Cosine in 3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-multiple-lights
            .html"
            +            
            +                data-en='Multiple Lights
            '
            +            
            +                data-es='Múltiples luces
            '
            +            
            +                data-hi='मल्टीपल लाइट्स
            '
            +            
            +                data-ko='복수의 조명들
            '
            +            
            +                data-zh-Hans='Multiple Lights
            '
            +            
            +          >Multiple Lights
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-materials
            .html"
            +            
            +                data-en='Materials
            '
            +            
            +                data-es='Materiales
            '
            +            
            +                data-hi='सामग्री
            '
            +            
            +                data-ko='재질(Materials)
            '
            +            
            +                data-zh-Hans='Materials
            '
            +            
            +          >Materials
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-textures
            .html"
            +            
            +                data-en='Textures
            '
            +            
            +                data-es='Texturas
            '
            +            
            +                data-hi='बनावट
            '
            +            
            +                data-ko='텍스처
            '
            +            
            +                data-zh-Hans='Textures
            '
            +            
            +          >Textures
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-ray-casting
            .html"
            +            
            +                data-en='Ray Casting
            '
            +            
            +                data-es='Ray Casting
            '
            +            
            +                data-hi='रे कास्टिंग
            '
            +            
            +                data-ko='레이 캐스팅
            '
            +            
            +                data-zh-Hans='Ray Casting
            '
            +            
            +          >Ray Casting
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-orbit-control
            .html"
            +            
            +                data-en='Orbit Control
            '
            +            
            +                data-es='Control de órbita
            '
            +            
            +                data-hi='कक्षा नियंत्रण
            '
            +            
            +                data-ko='궤도 제어
            '
            +            
            +                data-zh-Hans='Orbit Control
            '
            +            
            +          >Orbit Control
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-basic-shader
            .html"
            +            
            +                data-en='Basic Shader
            '
            +            
            +                data-es='Basic Shader
            '
            +            
            +                data-hi='बेसिक शेडर
            '
            +            
            +                data-ko='셰이더 기초
            '
            +            
            +                data-zh-Hans='Basic Shader
            '
            +            
            +          >Basic Shader
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-as-a-texture
            .html"
            +            
            +                data-en='Shader as a Texture
            '
            +            
            +                data-es='Shader as a Texture
            '
            +            
            +                data-hi='शेडर एक बनावट के रूप में
            '
            +            
            +                data-ko='셰이더로 텍스처 만들기
            '
            +            
            +                data-zh-Hans='Shader as a Texture
            '
            +            
            +          >Shader as a Texture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-passing-shader-uniforms
            .html"
            +            
            +                data-en='Passing Shader Uniforms
            '
            +            
            +                data-es='Passing Shader Uniforms
            '
            +            
            +                data-hi='पासिंग शेडर यूनिफॉर्म
            '
            +            
            +                data-ko='셰이더 유니폼
            '
            +            
            +                data-zh-Hans='Passing Shader Uniforms
            '
            +            
            +          >Passing Shader Uniforms
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-using-webcam
            .html"
            +            
            +                data-en='Shader Using Webcam
            '
            +            
            +                data-es='Shader Using Webcam
            '
            +            
            +                data-hi='Shader वेबकैम का उपयोग कर रहा है
            '
            +            
            +                data-ko='웹캠을 사용한 셰이더
            '
            +            
            +                data-zh-Hans='Shader Using Webcam
            '
            +            
            +          >Shader Using Webcam
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='input' class='anchor'>Input</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="input-clock
            .html"
            +            
            +                data-en='Clock
            '
            +            
            +                data-es='Clock
            '
            +            
            +                data-hi='घड़ी
            '
            +            
            +                data-ko='시계
            '
            +            
            +                data-zh-Hans='Clock
            '
            +            
            +          >Clock
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-constrain
            .html"
            +            
            +                data-en='Constrain
            '
            +            
            +                data-es='Constrain
            '
            +            
            +                data-hi='बाधा
            '
            +            
            +                data-ko='제한
            '
            +            
            +                data-zh-Hans='Constrain
            '
            +            
            +          >Constrain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-easing
            .html"
            +            
            +                data-en='Easing
            '
            +            
            +                data-es='Easing
            '
            +            
            +                data-hi='आसान
            '
            +            
            +                data-ko='이징(Easing)
            '
            +            
            +                data-zh-Hans='Easing
            '
            +            
            +          >Easing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-keyboard
            .html"
            +            
            +                data-en='Keyboard
            '
            +            
            +                data-es='Keyboard
            '
            +            
            +                data-hi='कीबोर्ड
            '
            +            
            +                data-ko='키보드
            '
            +            
            +                data-zh-Hans='Keyboard
            '
            +            
            +          >Keyboard
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-milliseconds
            .html"
            +            
            +                data-en='Milliseconds
            '
            +            
            +                data-es='Mouse 1D
            '
            +            
            +                data-hi='माउस 1D
            '
            +            
            +                data-ko='1D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 1D
            '
            +            
            +          >Milliseconds
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-1d
            .html"
            +            
            +                data-en='Mouse 1D
            '
            +            
            +                data-es='Mouse 2D
            '
            +            
            +                data-hi='माउस 2D
            '
            +            
            +                data-ko='2D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 2D
            '
            +            
            +          >Mouse 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-2d
            .html"
            +            
            +                data-en='Mouse 2D
            '
            +            
            +                data-es='Mouse Press
            '
            +            
            +                data-hi='माउस प्रेस
            '
            +            
            +                data-ko='마우스 버튼
            '
            +            
            +                data-zh-Hans='Mouse Press
            '
            +            
            +          >Mouse 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-functions
            .html"
            +            
            +                data-en='Mouse Functions
            '
            +            
            +                data-es='Mouse Functions
            '
            +            
            +                data-hi='माउस फंक्शन्स
            '
            +            
            +                data-ko='마우스 함수
            '
            +            
            +                data-zh-Hans='Mouse Functions
            '
            +            
            +          >Mouse Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-signals
            .html"
            +            
            +                data-en='Mouse Signals
            '
            +            
            +                data-es='Mouse Signals
            '
            +            
            +                data-hi='माउस सिग्नल
            '
            +            
            +                data-ko='마우스 신호
            '
            +            
            +                data-zh-Hans='Mouse Signals
            '
            +            
            +          >Mouse Signals
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-press
            .html"
            +            
            +                data-en='Mouse Press
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-hi='भंडारण इनपुट
            '
            +            
            +                data-ko='입력값 저장
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Mouse Press
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-rollover
            .html"
            +            
            +                data-en='Rollover
            '
            +            
            +                data-es='Rollover
            '
            +            
            +                data-ko='롤오버 (Rollover)
            '
            +            
            +                data-zh-Hans='Rollover
            '
            +            
            +          >Rollover
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-storing-input
            .html"
            +            
            +                data-en='Storing Input
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-ko='Storing Input
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Storing Input
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='advanced_data' class='anchor'>Advanced Data</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-json
            .html"
            +            
            +                data-en='Load Saved JSON
            '
            +            
            +                data-es='Load Saved JSON
            '
            +            
            +                data-hi='लोड सेव किया गया JSON
            '
            +            
            +                data-ko='저장된 JSON 불러오기
            '
            +            
            +                data-zh-Hans='Load Saved JSON
            '
            +            
            +          >Load Saved JSON
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-table
            .html"
            +            
            +                data-en='Load Saved Table
            '
            +            
            +                data-es='Load Saved Table
            '
            +            
            +                data-ko='Load Saved Table
            '
            +            
            +                data-zh-Hans='Load Saved Table
            '
            +            
            +          >Load Saved Table
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='sound' class='anchor'>Sound</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="sound-load-and-play-sound
            .html"
            +            
            +                data-en='Load/Play Sound
            '
            +            
            +                data-es='Cargar y reproducir sonido
            '
            +            
            +                data-hi='लोड और प्ले साउंड
            '
            +            
            +                data-ko='사운드 불러오기/재생
            '
            +            
            +                data-zh-Hans='Load and Play Sound
            '
            +            
            +          >Load/Play Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-preload-soundfile
            .html"
            +            
            +                data-en='Preload SoundFile
            '
            +            
            +                data-es='Precargar archivo de sonido
            '
            +            
            +                data-hi='प्रीलोड साउंडफाइल
            '
            +            
            +                data-ko='사운드 파일 미리 불러오기
            '
            +            
            +                data-zh-Hans='Preload SoundFile
            '
            +            
            +          >Preload SoundFile
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-soundformats
            .html"
            +            
            +                data-en='soundFormats
            '
            +            
            +                data-es='Formatos de sonido
            '
            +            
            +                data-hi='ध्वनि प्रारूप
            '
            +            
            +                data-ko='사운드 파일 형식
            '
            +            
            +                data-zh-Hans='soundFormats
            '
            +            
            +          >soundFormats
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-play-mode
            .html"
            +            
            +                data-en='Play Mode
            '
            +            
            +                data-es='Modo de reproducción
            '
            +            
            +                data-hi='प्ले मोड
            '
            +            
            +                data-ko='재생 모드
            '
            +            
            +                data-zh-Hans='Play Mode
            '
            +            
            +          >Play Mode
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-pan-sound
            .html"
            +            
            +                data-en='Pan Sound
            '
            +            
            +                data-es='Paneo
            '
            +            
            +                data-hi='पैन साउंड
            '
            +            
            +                data-ko='사운드 패닝
            '
            +            
            +                data-zh-Hans='Pan Sound
            '
            +            
            +          >Pan Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-sound-effect
            .html"
            +            
            +                data-en='Sound Effect
            '
            +            
            +                data-es='Efecto de sonido
            '
            +            
            +                data-hi='ध्वनि प्रभाव
            '
            +            
            +                data-ko='사운드 효과
            '
            +            
            +                data-zh-Hans='Sound Effect
            '
            +            
            +          >Sound Effect
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-playback-rate
            .html"
            +            
            +                data-en='Playback Rate
            '
            +            
            +                data-es='Tasa de reproducción
            '
            +            
            +                data-hi='प्लेबैक दर
            '
            +            
            +                data-ko='재생 속도
            '
            +            
            +                data-zh-Hans='Playback Rate
            '
            +            
            +          >Playback Rate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-measuring-amplitude
            .html"
            +            
            +                data-en='Measuring Amplitude
            '
            +            
            +                data-es=' Midiendo la amplitud
            '
            +            
            +                data-hi='मापने वाला आयाम
            '
            +            
            +                data-ko='진폭 측정
            '
            +            
            +                data-zh-Hans='Measuring Amplitude
            '
            +            
            +          >Measuring Amplitude
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-noise-drum-envelope
            .html"
            +            
            +                data-en='Noise Drum Envelope
            '
            +            
            +                data-es='Tambor con envolvente y ruido
            '
            +            
            +                data-hi='शोर ड्रम लिफाफा
            '
            +            
            +                data-ko='노이즈 드럼 엔벨로프
            '
            +            
            +                data-zh-Hans='Noise Drum Envelope
            '
            +            
            +          >Noise Drum Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-note-envelope
            .html"
            +            
            +                data-en='Note Envelope
            '
            +            
            +                data-es=' Envolvente de nota
            '
            +            
            +                data-hi='नोट लिफाफा
            '
            +            
            +                data-ko='음계 엔벨로프
            '
            +            
            +                data-zh-Hans='Note Envelope
            '
            +            
            +          >Note Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-oscillator-frequency
            .html"
            +            
            +                data-en='Oscillator Frequency
            '
            +            
            +                data-es='Frecuencia de oscilador
            '
            +            
            +                data-hi='थरथरानवाला आवृत्ति
            '
            +            
            +                data-ko='오실레이터 주파수
            '
            +            
            +                data-zh-Hans='Oscillator Frequency
            '
            +            
            +          >Oscillator Frequency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-input
            .html"
            +            
            +                data-en='Mic Input
            '
            +            
            +                data-es='Entrada de micrófono
            '
            +            
            +                data-hi='Mic Input
            '
            +            
            +                data-ko='마이크 입력
            '
            +            
            +                data-zh-Hans='Mic Input
            '
            +            
            +          >Mic Input
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-spectrum
            .html"
            +            
            +                data-en='Frequency Spectrum
            '
            +            
            +                data-es='Espectro de frecuencia
            '
            +            
            +                data-hi='फ्रीक्वेंसी स्पेक्ट्रम Spec
            '
            +            
            +                data-ko='주파수 스펙트럼
            '
            +            
            +                data-zh-Hans='Frequency Spectrum
            '
            +            
            +          >Frequency Spectrum
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-threshold
            .html"
            +            
            +                data-en='Mic Threshold
            '
            +            
            +                data-es='Umbral de micrófono
            '
            +            
            +                data-hi='माइक थ्रेशोल्ड
            '
            +            
            +                data-ko='마이크 임계값
            '
            +            
            +                data-zh-Hans='Mic Threshold
            '
            +            
            +          >Mic Threshold
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-lowpass
            .html"
            +            
            +                data-en='Filter LowPass
            '
            +            
            +                data-es=' Filtro pasabajos
            '
            +            
            +                data-hi='फ़िल्टर लोपास
            '
            +            
            +                data-ko='로우패스 필터
            '
            +            
            +                data-zh-Hans='Filter LowPass
            '
            +            
            +          >Filter LowPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-bandpass
            .html"
            +            
            +                data-en='Filter BandPass
            '
            +            
            +                data-es=' Filtro pasabanda
            '
            +            
            +                data-hi='फ़िल्टर बैंडपास
            '
            +            
            +                data-ko='밴드패스 필터
            '
            +            
            +                data-zh-Hans='Filter BandPass
            '
            +            
            +          >Filter BandPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-delay
            .html"
            +            
            +                data-en='Delay
            '
            +            
            +                data-es=' Delay
            '
            +            
            +                data-hi='देरी
            '
            +            
            +                data-ko='딜레이 필터
            '
            +            
            +                data-zh-Hans='Delay
            '
            +            
            +          >Delay
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-reverb
            .html"
            +            
            +                data-en='Reverb
            '
            +            
            +                data-es=' Reverb
            '
            +            
            +                data-hi='रेवरब
            '
            +            
            +                data-ko='리버브
            '
            +            
            +                data-zh-Hans='Reverb
            '
            +            
            +          >Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-convolution-reverb
            .html"
            +            
            +                data-en='Convolution Reverb
            '
            +            
            +                data-es=' Reverb de convolución
            '
            +            
            +                data-hi='कनवल्शन रेवरब
            '
            +            
            +                data-ko='컨볼루션 리버브
            '
            +            
            +                data-zh-Hans='Convolution Reverb
            '
            +            
            +          >Convolution Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-record-save-audio
            .html"
            +            
            +                data-en='Record Save Audio
            '
            +            
            +                data-es=' Graba y almacena audio
            '
            +            
            +                data-hi='रिकॉर्ड ऑडियो सहेजें
            '
            +            
            +                data-ko='오디오 녹음/저장
            '
            +            
            +                data-zh-Hans='Record Save Audio
            '
            +            
            +          >Record Save Audio
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-modulation
            .html"
            +            
            +                data-en='Frequency Modulation
            '
            +            
            +                data-es='Modulación en frecuencia
            '
            +            
            +                data-hi='फ़्रीक्वेंसी मॉडुलन
            '
            +            
            +                data-ko='주파수 변조(FM)
            '
            +            
            +                data-zh-Hans='Frequency Modulation
            '
            +            
            +          >Frequency Modulation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-amplitude-modulation
            .html"
            +            
            +                data-en='Amplitude Modulation
            '
            +            
            +                data-es='Modulación en amplitud
            '
            +            
            +                data-hi='आयाम मॉडुलन
            '
            +            
            +                data-ko='진폭 변조(AM)
            '
            +            
            +                data-zh-Hans='Amplitude Modulation
            '
            +            
            +          >Amplitude Modulation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='mobile' class='anchor'>Mobile</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-ball-bounce
            .html"
            +            
            +                data-en='Acceleration Ball Bounce
            '
            +            
            +                data-es='Pelota rebote aceleración
            '
            +            
            +                data-hi='एक्सेलेरेशन बॉल बाउंस
            '
            +            
            +                data-ko='가속도와 바운스
            '
            +            
            +                data-zh-Hans='Acceleration Ball Bounce
            '
            +            
            +          >Acceleration Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-simple-draw
            .html"
            +            
            +                data-en='Simple Draw
            '
            +            
            +                data-es='Dibujo simple
            '
            +            
            +                data-hi='सिंपल ड्रा
            '
            +            
            +                data-ko='간단한 드로잉
            '
            +            
            +                data-zh-Hans='Simple Draw
            '
            +            
            +          >Simple Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-color
            .html"
            +            
            +                data-en='Acceleration Color
            '
            +            
            +                data-es='Aceleración y color
            '
            +            
            +                data-hi='त्वरण रंग
            '
            +            
            +                data-ko='가속도 색상
            '
            +            
            +                data-zh-Hans='Acceleration Color
            '
            +            
            +          >Acceleration Color
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-shake-ball-bounce
            .html"
            +            
            +                data-en='Shake Ball Bounce
            '
            +            
            +                data-es='Pelota rebote agitar
            '
            +            
            +                data-hi='शेक बॉल बाउंस
            '
            +            
            +                data-ko='흔들기와 바운스
            '
            +            
            +                data-zh-Hans='Shake Ball Bounce
            '
            +            
            +          >Shake Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-tilted-3d-box
            .html"
            +            
            +                data-en='Tilted 3D Box
            '
            +            
            +                data-es='Caja 3D
            '
            +            
            +                data-hi='झुका हुआ 3D बॉक्स
            '
            +            
            +                data-ko='기울어진 3D상자
            '
            +            
            +                data-zh-Hans='Tilted 3D Box
            '
            +            
            +          >Tilted 3D Box
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='hello_p5' class='anchor'>Hello p5</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="hello-p5-simple-shapes
            .html"
            +            
            +                data-en='Simple Shapes
            '
            +            
            +                data-es='Figuras simples
            '
            +            
            +                data-hi='सरल आकार
            '
            +            
            +                data-ko='간단한 도형들
            '
            +            
            +                data-zh-Hans='Simple Shapes
            '
            +            
            +          >Simple Shapes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-1
            .html"
            +            
            +                data-en='Interactivity 1
            '
            +            
            +                data-es='Interactividad 1
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 1
            '
            +            
            +                data-ko='인터랙티비티 1
            '
            +            
            +                data-zh-Hans='Interactivity 1
            '
            +            
            +          >Interactivity 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-2
            .html"
            +            
            +                data-en='Interactivity 2
            '
            +            
            +                data-es='Interactividad 2
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 2
            '
            +            
            +                data-ko='인터랙티비티 2
            '
            +            
            +                data-zh-Hans='Interactivity 2
            '
            +            
            +          >Interactivity 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-animation
            .html"
            +            
            +                data-en='Animation
            '
            +            
            +                data-es='Animación
            '
            +            
            +                data-hi='एनिमेशन
            '
            +            
            +                data-ko='애니메이션
            '
            +            
            +                data-zh-Hans='Animation
            '
            +            
            +          >Animation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-weather
            .html"
            +            
            +                data-en='Weather
            '
            +            
            +                data-es='Clima
            '
            +            
            +                data-hi='मौसम
            '
            +            
            +                data-ko='날씨
            '
            +            
            +                data-zh-Hans='Weather
            '
            +            
            +          >Weather
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-drawing
            .html"
            +            
            +                data-en='Drawing
            '
            +            
            +                data-es='Dibujar
            '
            +            
            +                data-hi='ड्राइंग
            '
            +            
            +                data-ko='드로잉
            '
            +            
            +                data-zh-Hans='Drawing
            '
            +            
            +          >Drawing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-song
            .html"
            +            
            +                data-en='Song
            '
            +            
            +                data-es='Canción
            '
            +            
            +                data-hi='गीत
            '
            +            
            +                data-ko='노래
            '
            +            
            +                data-zh-Hans='Song
            '
            +            
            +          >Song
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +      </div>
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/get-started/index.html b/dist/get-started/index.html
            new file mode 100644
            index 0000000000..f80f360ea5
            --- /dev/null
            +++ b/dist/get-started/index.html
            @@ -0,0 +1,343 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">get started | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="get-started-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>Get Started</h1>
            +
            +      <p>This page walks you through setting up a p5.js project and making your first sketch. The easiest way to start is using the  <a href="https://editor.p5js.org" target="_blank">p5.js editor</a>, you can open the web editor and can scroll down to  <a href="#sketch">Your First Sketch</a>. If you would like to work on the desktop version of p5.js you can scroll down to <a href="#settingUp">downloading instructions</a>.
            +      </p>
            +
            +
            +
            +      <h2 class="start-element" id="sketch">Your First Sketch</h2>
            +
            +      <div class="info">
            +        <h3 class="sr-only">Code snippet with ellipse</h3>
            +        <p>In the <a href='https://editor.p5js.org/'>p5.js web editor</a> you should find the following code:</p>
            +
            +<pre id="first-sketch1"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch1" class="copy_button">Copy</button>
            +        </div>
            +        <p>After <code class="language-javascript">background(220);</code> include this line of code: <code class="language-javascript">ellipse(50,50,80,80);</code>.</p>
            +
            +        <p>Now your code should be like this: </p>
            +        <h3 class="sr-only">Code snippet with ellipse</h3>
            +
            +<pre id="first-sketch2"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +  ellipse(50,50,80,80);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch2" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">The line you just added draws an ellipse, with its center 50 pixels over from the left and 50 pixels down from the top, with a width and height of 80 pixels.</p>
            +        <p>On the editor press play to display your code in action!</p>
            +        <h3 class="sr-only">Note for screenreader users</h3>
            +        <p>If you are using a screen reader, you must turn on the accessible outputs in the p5 online editor, outside the editor you must add the accessibility library in your html. To learn more visit&#32;<a href="../learn/p5-screen-reader.html" target="_blank">using p5 with a screen reader tutorial.</a>
            +        </p>
            +        <p>If you've typed everything correctly, this will appear in the display window:</p>
            +
            +        <img src="../assets/img/get-started/first-sketch.png" alt='canvas has a circle of width and height 50 at position 80 x and 80 y'/>
            +
            +        <p>If nothing appears, the editor may be having trouble understanding what you’ve typed. If this happens, make sure that you've copied the example code exactly: the numbers should be contained within parentheses and have commas between each of them, the line should end with a semicolon, and ellipse has to be spelled correctly.</p>
            +
            +        <p>One of the most difficult things about getting started with programming is that you have to be very specific about the syntax. The browser isn't always smart enough to know what you mean, and can be quite fussy about the placement of punctuation. You'll get used to it with a little practice. In the bottom left of the editor you will find the console section. Here, you can find messages from the editor with details about any errors it encounters.</p>
            +
            +        <h3 class="sr-only">Code snippet with interaction</h3>
            +        <p>Next, we'll skip ahead to a sketch that's a little more exciting. Modify the last example to try this:</p>
            +
            +<pre id="first-sketch3"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  if (mouseIsPressed) {
            +    fill(0);
            +  } else {
            +    fill(255);
            +  }
            +  ellipse(mouseX, mouseY, 80, 80);
            +}
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch3" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">This program creates a canvas that is 400 pixels wide and 400 pixels high, and then starts drawing white circles at the position of the mouse. When a mouse button is pressed, the circle color changes to black. Run the code, move the mouse, and click to experience it.
            +        </p>
            +
            +        <img src="../assets/img/get-started/first-sketch2.png" alt='canvas has multiple circles drawn on it following the path of the mouse'/>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="next">What Next?</h2>
            +
            +      <div class='info'>
            +        <ul class="list_view">
            +          <li>Check out the <a href="../learn/">learn page</a> and <a href="../examples">examples page</a> for more.</li>
            +
            +          <li>Watch <a href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6Zy51Q-x9tMWIv9cueOFTFA">The Coding Train</a> and <a href="https://www.kadenze.com/courses/introduction-to-programming-for-the-visual-arts-with-p5-js/info">Kadenze</a> video tutorials.</li>
            +
            +          <li>View the <a href="../reference/"> reference</a> for full documentation. </li>
            +          <li>If you wish to use p5 with a screenreader, check out the <a href="../learn/p5-screen-reader.html">p5 with a screenreader tutorial</a>.</li>
            +          <li>If you have used Processing in the past, read the <a href='https://github.com/processing/p5.js/wiki/Processing-transition'>Processing transition tutorial</a> to learn how to convert from Processing to p5.js, and the main differences between them.</li>
            +
            +        </ul>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="settingUp">Setting up p5.js with an editor on your own computer</h2>
            +
            +      <div class="info">
            +        <p>To run p5.js in your computer you will need a text editor. You can use the 
            +          <a href='http://en.wikipedia.org/wiki/Source_code_editor' target="_blank">
            +             code editor </a>
            +            of your choice. Instructions for getting set up with 
            +            <a href="http://www.sublimetext.com/2" target="_blank"> Sublime Text 2</a>
            +             are included below, other good editor options include <a href='http://brackets.io/' target=_blank>Brackets</a>  and <a href='https://atom.io/' target=_blank>Atom</a>. If you are a screen reader user and not using the p5 web editor, you may want to use <a href="https://notepad-plus-plus.org/">Notepad++</a>  or 
            +            <a href="https://www.eclipse.org/ide/" target="_blank">Eclipse</a>.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="download">Downloading a copy of the p5.js library</h3>
            +
            +      <div class="info">
            +        <p>The easiest way to start is by using the empty example that comes with the 
            +          <a href="../download/">p5.js complete</a>
            +           download.
            +        </p>
            +
            +        <p>
            +          After download, you need to set up a local server. See instructions 
            +          <a href="https://github.com/processing/p5.js/wiki/Local-server" target="_blank">here</a>
            +          . Run your local server within the downloaded folder and on your browser, go to 
            +          <code>http://localhost:{your-port-num}/empty-example</code>
            +        </p>
            +
            +        <p>If you look in index.html, you'll notice that it links to the file p5.js. If you would like to use the minified version (compressed for faster page loading), change the link to p5.min.js.</p>
            +
            +        <pre id="markup1"><code class="language-markup">&lt;script src="../p5.min.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_script" class="copy_button">Copy</button>
            +        </div>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="hosted">Using a hosted version of the p5.js library</h3>
            +      <div class="info">
            +        <p>Alternatively, you can link to a p5.js file hosted online. All versions of p5.js are stored in a CDN (Content Delivery Network). You can find a history of these versions in the
            +          <a target="_blank" href="https://cdn.jsdelivr.net/npm/p5/lib/">
            +            p5.js CDN</a>. In this case you can change the link to:
            +        </p>
            +
            +        <pre id="cdn-link" class='p5-replace'><code class="language-markup">&lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_link" class="copy_button">Copy</button>
            +        </div>
            +        <p>A sample HTML page might look like this:</p>
            +
            +        <pre id="sample-html" class='p5-replace'><code class="language-markup">
            +&lt;html&gt;
            +  &lt;head&gt;
            +    &lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script&gt;
            +    &lt;script src="sketch.js">&lt;/script&gt;
            +  &lt;/head&gt;
            +  &lt;body&gt;
            +    &lt;main&gt;
            +    &lt;/main&gt;
            +  &lt;/body&gt;
            +&lt;/html&gt;
            +        </code></pre>
            +      <div class="edit_space">
            +          <button id="copy_p5_html" class="copy_button">Copy</button>
            +      </div>
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="environment">Environment</h3>
            +      <div class="info">
            +        <p>
            +          Open Sublime. Go to the File menu and choose Open... and choose the folder that your html and js files are located in. On the left sidebar, you should find the folder name at the top, with a list of the files contained in the folder directly below.
            +        </p>
            +
            +        <p>
            +          Click on your sketch.js file and it will open on the right where you can edit it.
            +          <img src="../assets/img/get-started/sublime2.png" alt='p5 starter code opened up in sublime editor."'/>
            +        </p>
            +
            +        <p>
            +          Open the index.html file in your browser by double clicking on it in your file manager or type: <code>file:///the/file/path/to/your/html</code>
            +           (or  <code>http://localhost:{your-port-num}/empty-example</code>
            +           if you are using a local server)
            +           in the address bar to view your sketch.
            +        </p>
            +      </div>
            +
            +      <div>Parts of this tutorial were adapted from the book, Getting Started with p5.js, by Lauren McCarthy, Casey Reas, and Ben Fry, O'Reilly / Make 2015. Copyright © 2015. All rights reserved. Last modified at the p5.js 2019 Contributors Conference.</div>
            +
            +      <script>
            +        $.getJSON('../download/version.json', function(data) {
            +          $('.p5-replace').each(function() {
            +            var html = $(this).html().replace('[p5_version]', data.version);
            +            $(this).html(html);
            +          });
            +        });
            +      </script>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +</div><!-- end id="get-started-page"  -->
            +<script src="/../assets/js/get-started.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/books/index.html b/dist/hi/books/index.html
            new file mode 100644
            index 0000000000..492b7fa204
            --- /dev/null
            +++ b/dist/hi/books/index.html
            @@ -0,0 +1,307 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">books | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="books-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>पुस्तकें</h1>
            +      <br>
            +
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/gettingstarted.jpg" alt="book cover getting started with p5.js">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>p5.js . के साथ शुरुआत करना</h2>
            +
            +          <p>लॉरेन मैकार्थी, केसी रियास और बेन फ्राई। ताइयून चोई द्वारा चित्रण।</p>
            +          <p>
            +            अक्टूबर 2015 को प्रकाशित, मेकर मीडिया।
            +            246 पृष्ठ।
            +            पेपरबैक।
            +          </p>
            +
            +          <p>प्रमुख p5.js डेवलपर और प्रसंस्करण के संस्थापकों द्वारा लिखित, यह पुस्तक आज के वेब की रचनात्मक संभावनाओं का परिचय प्रदान करती है, जावास्क्रिप्ट और एचटीएमएल का उपयोग करना।</p>
            +
            +          <p><a href="http://shop.oreilly.com/product/0636920032076.do" target="_blank">O'Reilly . से प्रिंट/ईबुक ऑर्डर करें</a></p>
            +          <p><a href="http://www.amazon.com/Make-Interactive-Graphics-JavaScript-Processing/dp/1457186772" target="_blank">अमेज़न से ऑर्डर करें</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/gettingstarted-es.jpg" alt="book cover Introducción a p5.js">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>p5.js का परिचय (स्पेनिश संस्करण)</h2>
            +
            +          <p>लॉरेन मैकार्थी, केसी रियास और बेन फ्राई। एरोनो द्वारा अनुवादित मोंटोया-मोरागा। Ilustraciones de Taeyoon Choi।"</p>
            +          <p>
            +            प्रकाशित 2018, प्रोसेसिंग फाउंडेशन, इंक।
            +            246 पृष्ठ।
            +            मुलायम आवरण।
            +          </p>
            +
            +          <p>प्रमुख p5.js डेवलपर और प्रसंस्करण के संस्थापकों द्वारा लिखित, यह
            + पुस्तक आज के वेब की रचनात्मक संभावनाओं का परिचय प्रदान करती है,
            + जावास्क्रिप्ट और एचटीएमएल का उपयोग करना।</p>
            +
            +          <p><a href="https://processingfoundation.press/product/introduccion-a-p5-js/" target="_blank">प्रोसेसिंग फाउंडेशन प्रेस से पीडीएफ ऑर्डर करें</a></p>
            +          <p><a href="https://www.amazon.com/Introducci%C3%B3n-p5-js-Spanish-Lauren-McCarthy/dp/0999881302/" target="_blank">Amazon से भौतिक संस्करण ऑर्डर करें</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/generative_design.jpg" alt="book cover generative design">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>जनरेटिव डिजाइन</h2>
            +
            +          <p>बेनेडिक्ट ग्रॉस, हार्टमुट बोहनेकर, जूलिया लाउब और क्लॉडियस लेज़ेरोनी।</p>
            +          <p>
            +            30 अक्टूबर, 2018 को प्रकाशित, प्रिंसटन आर्किटेक्चरल प्रेस; पुनर्मुद्रण संस्करण।
            +            255 पेज।
            +            पेपरबैक।
            +          </p>
            +
            +          <p>p5.js, कलाकारों और निर्माताओं में जावास्क्रिप्ट जैसी सरल भाषाओं का उपयोग करके इंटरैक्टिव टाइपोग्राफी और टेक्सटाइल से लेकर 3डी-प्रिंटेड तक सब कुछ बना सकते हैं जटिल और सुरुचिपूर्ण इन्फोग्राफिक्स के लिए फर्नीचर।</p>
            +
            +          <p><a href="https://www.papress.com/html/product.details.dna?isbn=9781616897581" target="_blank">प्रिंसटन आर्किटेक्चरल प्रेस से आदेश</a></p>
            +          <p><a href="https://www.amazon.com/Generative-Design-Visualize-Program-JavaScript/dp/1616897589" target="_blank">अमेज़न से ऑर्डर करें</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/generative_gestaltung.jpg" alt="book cover Generative Gestaltung">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>जनरेटिव गेस्टाल्टुंग (जर्मन संस्करण)</h2>
            +
            +          <p>बेनेडिक्ट ग्रॉस, हार्टमुट बोहनेकर, जूलिया लाउब और क्लॉडियस लेज़ेरोनी।</p>
            +          <p>
            +            1 मार्च, 2018 को प्रकाशित, श्मिट हरमन वेरलाग।
            +            256 पृष्ठ।
            +            हार्डकवर।
            +          </p>
            +
            +          <p>p5.js, कलाकारों और निर्माताओं में जावास्क्रिप्ट जैसी सरल भाषाओं का उपयोग करके इंटरैक्टिव टाइपोग्राफी और टेक्सटाइल से लेकर 3डी-प्रिंटेड तक सब कुछ बना सकते हैं जटिल और सुरुचिपूर्ण इन्फोग्राफिक्स के लिए फर्नीचर।</p>
            +
            +          <p><a href="https://typografie.de/produkt/generative-gestaltung-creative-coding-im-web/" target="_blank">वेरलाग हरमन श्मिट से आदेश</a></p>
            +          <p><a href="https://www.amazon.com/Generative-Gestaltung/dp/3874399028" target="_blank">अमेज़न से ऑर्डर करें</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/learn_javascript.jpg" alt="book cover learn javascript">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>p5.js के साथ जावास्क्रिप्ट सीखें</h2>
            +
            +          <p>इंजिन अर्सलान</p>
            +          <p>
            +            प्रकाशित 2018, एप्रेस।
            +            217 पृष्ठ।
            +            पेपरबैक
            +          </p>
            +
            +          <p>का उपयोग करके अत्यधिक आकर्षक और दृश्य तरीके से शुरू से कोडिंग सीखें प्रोग्रामिंग लाइब्रेरी p5.js के साथ अत्यधिक लोकप्रिय जावास्क्रिप्ट। कौशल आप इस पुस्तक से प्राप्त होने वाले बहुत से असंख्य को अत्यधिक हस्तांतरणीय हैं उद्योगों और वेब अनुप्रयोगों के निर्माण के लिए इस्तेमाल किया जा सकता है, प्रोग्राम करने योग्य रोबोट, या जनरेटिव आर्ट।</p>
            +
            +          <p><a href="https://www.apress.com/gp/book/9781484234259" target="_blank">अप्रेस से आदेश Order</a></p>
            +          <p><a href="https://www.amazon.com/Learn-JavaScript-p5-js-Coding-Learners/dp/1484234251" target="_blank">अमेज़न से ऑर्डर करें</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/aesthetic-programming.jpg" alt="book cover learn javascript">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>एस्थेटिक प्रोग्रामिंग: ए हैंडबुक ऑफ सॉफ्टवेयर स्टडीज</h2>
            +
            +          <p>विनी सून, ज्योफ कॉक्स।</p>
            +          <p>
            +            प्रकाशित 2020, ओपन ह्यूमैनिटीज प्रेस।
            +            298 पृष्ठ।
            +            हार्डकवर
            +          </p>
            +
            +          <p>p5.js का उपयोग करते हुए, यह पुस्तक रिफ्लेक्टिव अभ्यास का परिचय और प्रदर्शन करती है
            + सौंदर्य प्रोग्रामिंग की, एक तरह से कार्यक्रम के लिए सीखने के साथ संलग्न
            + मौजूदा तकनीकी वस्तुओं और प्रतिमानों को समझें और सवाल करें,
            + और व्यापक पारिस्थितिक-सामाजिक-तकनीकी प्रणालियों को पुन: प्रोग्राम करने की क्षमता का पता लगाने के लिए।</p>
            +
            +          <p><a href="http://openhumanitiespress.org/books/download/Soon-Cox_2020_Aesthetic-Programming.pdf" target="_blank">पीडीएफ डाउनलोड करें (फ्री)</a></p>
            +          <p><a href="https://www.barnesandnoble.com/w/aesthetic-programming-winnie-soon/1138820949" target="_blank">बार्न्स एंड नोबल से आदेश</a></p>
            +
            +        </div>
            +      </div>
            +      <br>
            +      <div style='clear:both; height: 2em'></div>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="books-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/community/contributors-conference-2015.html b/dist/hi/community/contributors-conference-2015.html
            new file mode 100644
            index 0000000000..7b4b27ac1b
            --- /dev/null
            +++ b/dist/hi/community/contributors-conference-2015.html
            @@ -0,0 +1,286 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>योगदानकर्ता सम्मेलन 2015</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>25-31 मई</h2>
            +
            +      <p>लगभग 30 प्रतिभागियों के एक समूह ने एक सप्ताह बिताया<a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a>, p5.js प्रोग्रामिंग वातावरण के कोड, दस्तावेज़ीकरण और सामुदायिक आउटरीच टूल को आगे बढ़ाया। प्रतिभागी हांगकांग, सिएटल, लॉस एंजिल्स, बोस्टन और न्यूयॉर्क जैसे दूर से आए थे। अधिकांश रचनात्मक प्रौद्योगिकी, इंटरेक्शन डिज़ाइन और न्यू-मीडिया कला के क्षेत्र में काम कर रहे पेशेवर थे, लेकिन समूह में कार्नेगी मेलॉन के स्कूल ऑफ आर्ट एंड आर्किटेक्चर के आधा दर्जन स्नातक और स्नातक छात्र भी शामिल थे।
            +      </p>
            +      </div>
            +
            +      <img src="../../assets/img/community/2015_1.jpg" alt='प्रतिभागियों के विविध समूह मुस्कुराते हैं और अपने हाथों से एक पी 5 संकेत बनाते हैं"'/>
            +      <img src="../../assets/img/community/2015_3.jpg" alt='महिला अपने लैपटॉप से ​​p5.js समुदाय का बयान प्रस्तुत करती है"'/>
            +      <img src="../../assets/img/community/2015_4.jpg" alt='महिला स्पष्ट रूप से एक माइक्रोफोन में बात करती है जबकि दो पुरुष सहयोगी दिखते हैं"'/>
            +      <img src="../../assets/img/community/2015_5.jpg" alt='प्रतिभागी मुस्कुराते हैं और एक प्रस्तुति सुनते हैं"'/>
            +      <img src="../../assets/img/community/2015_6.jpg" alt='तीन महिला छात्रों के लिए माइक्रोफ़ोन में महिला p5.js के बारे में पढ़ती है"'/>
            +      <img src="../../assets/img/community/2015_7.jpg" alt='प्रतिभागी एक व्हाइटबोर्ड के चारों ओर एक सर्कल में बैठते हैं, जिस पर स्टिक नोट्स होते हैं, जबकि एक महिला छात्र माइक्रोफोन में बोलती है"'/>
            +      <img src="../../assets/img/community/2015_8.jpg" alt='प्रतिभागी एक दूसरे के लैपटॉप को देखते हुए टेबल के चारों ओर बैठते हैं और कोड की तुलना करते हैं"'/>
            +      <img src="../../assets/img/community/2015_9.jpg" alt='विभिन्न रंगीन स्टिक नोट्स और प्रोग्रामिंग के बारे में लिखित नोट्स के साथ व्हाइटबोर्ड "'/>
            +      <img src="../../assets/img/community/2015_10.jpg" alt='विभिन्न कौशल सेटों के मूल्य निर्धारण के बारे में माइक्रोफोन में बोलने वाली महिला, जबकि लैपटॉप वाले प्रतिभागियों का एक समूह कक्षा में उसके पावरपॉइंट को देखता है"'/>
            +      <img src="../../assets/img/community/2015_11.jpg" alt='महिला एक सभागार में पोडियम पर बोलती है जबकि तीन प्रतिभागी मंच पर बैठते हैं और एक अन्य तीन मंच स्क्रीन पर लंघन कर रहे हैं"'/>
            +      <img src="../../assets/img/community/2015_12.jpg" alt='अपने लैपटॉप पर काम करने वाले प्रतिभागियों के साथ एक कक्षा का ओवरहेड दृश्य"'/>
            +      <img src="../../assets/img/community/2015_13.jpg" alt='एक सर्कल में पांच लोगों की चर्चा"'/>
            +      <img src="../../assets/img/community/2015_14.jpg" alt='एक सर्कल में पांच लोग अपने लैपटॉप के साथ अपने नोट्स साझा करते हैं"'/>
            +      <img src="../../assets/img/community/2015_15.jpg" alt='प्रतिभागियों के एक समूह के लिए एक माइक्रोफोन के साथ कक्षा में आदमी"'/>
            +      <img src="../../assets/img/community/2015_2.jpg" alt='हरे लॉन में प्रतिभागियों ने छलांग लगाई, मुस्कुराए और खुशी से हवा में हाथ हिलाया।"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/80913365@N04/albums/72157653238862069/with/17613092994/" target="_blank">तस्वीरें तायून चोई द्वारा</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>प्रतिभागी</h2>
            +      <p>
            +        <a href='http://huah.net/jason/' target='_blank'>Jason Alderman</a>,
            +        <a href='http://sepans.com/' target='_blank'>Sepand Ansari</a>,
            +        <a href='http://tegabrain.com' target='_blank'>Tega Brain</a>,
            +        <a href='https://medium.com/@emchenNYC/' target='_blank'>Emily Chen</a>,
            +        <a href='http://andrescolubri.net/' target='_blank'>Andres Colubri</a>,
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>,
            +        <a href='http://guydebree.com/' target='_blank'>Guy de Bree</a>,
            +        <a href='http://www.cjdecarteret.com/' target='_blank'>Christine de Carteret</a>,
            +        <a href='http://xystudio.cc/' target='_blank'>Xy Feng</a>,
            +        <a href='http://www.sarahgp.com/' target='_blank'>Sarah Groff-Palermo</a>,
            +        <a href='http://www.crhallberg.com/' target='_blank'>Chris Hallberg</a>,
            +        <a href='http://valhead.com/' target='_blank'>Val Head</a>,
            +        <a href='http://johannahedva.com' target='_blank'>Johanna Hedva</a>,
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>,
            +        <a href='http://web.media.mit.edu/~jacobsj/' target='_blank'>Jennifer Jacobs</a>,
            +        <a href='http://www.epicjefferson.com/' target='_blank'>Epic Jefferson</a>,
            +        <a href='http://michellepartogi.com' target='_blank'>Michelle Partogi</a>,
            +        <a href='http://lav.io/' target='_blank'>Sam Lavigne</a>,
            +        <a href='http://flong.com' target='_blank'>Golan Levin</a>,
            +        <a href='http://www.liuchangitp.com/' target='_blank'>Cici Liu</a>,
            +        <a href='http://www.mayaman.cc/' target='_blank'>Maya Man</a>,
            +        <a href='http://lauren-mccarthy.com' target='_blank'>Lauren McCarthy</a>,
            +        <a href='http://www.workergnome.com/' target='_blank'>David Newbury</a>,
            +        <a href='http://molleindustria.org/' target='_blank'>Paolo Pedercini</a>,
            +        <a href='http://luisaph.com' target='_blank'>Luisa Pereira</a>,
            +        <a href='http://mileshiroo.info/' target='_blank'>Miles Peyton</a>,
            +        <a href='http://carolinerecord.com/' target='_blank'>Caroline Record</a>,
            +        <a href='http://b2renger.github.io/' target='_blank'>Berenger Recoules</a>,
            +        <a href='https://pibloginthesky.wordpress.com/' target='_blank'>Stephanie Pi</a>,
            +        <a href='http://jasonsigal.cc' target='_blank'>Jason Sigal</a>,
            +        <a href='http://studioindefinit.com/' target='_blank'>Kevin Siwoff</a>,
            +        <a href='http://charlottestiles.com/' target='_blank'>Charlotte Stiles</a>
            +      </p>
            +      </div>
            +
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>विविधता</h2>
            +        <p>तकनीकी विकास के साथ-साथ, इस सम्मेलन का एक मुख्य फोकस आउटरीच, समुदाय और विविधता थी। सम्मेलन एक पैनल के साथ शुरू हुआ—<a href="http://studioforcreativeinquiry.org/events/diversity-seven-voices-on-race-gender-ability-class-for-floss-and-the-internet" target="_blank">विविधता: रेस, जेंडर, एबिलिटी पर सात आवाज़ें, FLOSS और इंटरनेट के लिए क्लास</a>। Organized by <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>
            +        तथा <a  href="http://lauren-mccarthy.com" target="_blank">Lauren McCarthy</a> के द्वारा आयोजित, यह पैनल मंगलवार 25 मई 2015 को कार्नेगी मेलन विश्वविद्यालय में क्रेगे सभागार में हुआ। वक्ताओं में शामिल <a href="http://www.mayaman.cc/" target='_blank'>Maya Man</a>, <a href="http://reas.com/" target='_blank'>Casey
            +        Reas</a>, <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>, <a href="https://pibloginthesky.wordpress.com/" target='_blank'>Stephanie Pi</a>,
            +        <a href="http://phoenixperry.com/" target='_blank'>Phoenix Perry</a>, <a href="http://taeyoonchoi.com/" target='_blank'>Taeyoon Choi</a>,
            +        <a href="http://ablersite.org/" target='_blank'>Sara Hendren</a>, <a href="http://www.epicjefferson.com/" target='_blank'>Epic Jefferson</a>,
            +        तथा <a href="http://chandlermcwilliams.com/" target='_blank'>Chandler McWilliams</a>।
            +        <img class="alignleft size-full wp-image-8423" src="http://studioforcreativeinquiry.org/wp-content/uploads/2015/05/diversity_640.jpg" alt="diversity_640"/>
            +        </p>
            +        <iframe src="https://player.vimeo.com/video/129140298?color=ffffff&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +        
            +        <table style="margin-top: 10px; background-color: #ffffff; border-collapse: collapse; border: 0px; width: 720px;">
            +        <tbody>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129151416?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Casey Reas</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129151418?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Johanna Hedva</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129160951?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Stephanie Pi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129163155?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Phoenix Perry</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129173628?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Taeyoon Choi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129177689?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Sara Hendren</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129183825?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Epic Jefferson</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129187909?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Chandler McWilliams</td>
            +        </tr>
            +        </tbody>
            +        </table>
            +        <iframe src="https://player.vimeo.com/video/129192014?color=ffffff&amp;title=1&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +      </div>
            +
            +
            +<!--       <div class="contributors-subsection">
            +      <h3>Documentation</h3>
            +      <p><a href='https://medium.com/@tchoi8/diversity-at-sfpc-d494d7390375' target=_blank>Diversity at SFPC
            +      (talk by Taeyoon Choi at “Diversity: Seven Voices on Race, Gender, Ability &amp; Class for FLOSS and
            +      the Internet”)</a></p>
            +      </div> -->
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>सहयोग </h2>
            +
            +      <p>हमारा योगदान सम्मेलन <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> कार्नेगी मेलन विश्वविद्यालय में हुआ, जो कला, विज्ञान, प्रौद्योगिकी और संस्कृति के चौराहों पर एक अकादमिक प्रयोगशाला है।</p>
            +
            +      <p>यह अयोजन <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      के अनुदान से और <a href="https://tisch.nyu.edu/itp" target="_blank">NYU Interactive Telecommunications Program</a>
            +      (ITP), <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href="http://theartificial.nl/" target="_blank">TheArtificial</a>, <a href="http://bocoup.com/" target="_blank">Bocoup</a>, <a href="http://tinysubversions.com/" target="_blank">Darius Kazemi</a>, और <a href="http://www.du.edu/ahss/edp/" target="_blank">Emergent Digital Practices | University of Denver</a><br><b>धन्यवाद! </b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../../assets/img/community/nea.jpg' alt=""></a></div>
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:18%' src='../../assets/img/community/studio.png' alt=""/></a>
            +      <a class='nounderline' href='http://itp.nyu.edu/itp/' target=_blank ><img style='width:18%' src='../../assets/img/community/itp.png' alt=""/></a>
            +      <a class='nounderline' href='http://www.du.edu/ahss/edp/' target=_blank ><img style='width:18%' src='../../assets/img/community/edp.png' alt=""/></a>
            +      <a class='nounderline' href='http://bocoup.com/' target=_blank ><img style='width:18%' src='../../assets/img/community/bocoup.png' alt=""/></a>
            +      <a class='nounderline' href='http://theartificial.nl/' target=_blank ><img style='width:18%' src='../../assets/img/community/theartificial.png' alt=""/></a>
            +
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/community/contributors-conference-2019.html b/dist/hi/community/contributors-conference-2019.html
            new file mode 100644
            index 0000000000..91bbfffb2a
            --- /dev/null
            +++ b/dist/hi/community/contributors-conference-2019.html
            @@ -0,0 +1,307 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>योगदानकर्ता सम्मेलन 2019</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>13-18 अगस्त</h2>
            +
            +      <p>35 प्रतिभागियों का एक अंतःविषय समूह में एकत्र हुए<a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a>कोड, दस्तावेज़ीकरण, और सामुदायिक आउटरीच टूल को आगे बढ़ाते हुए एकत्र हुआ और p5.js प्रोग्रामिंग वातावरण के वर्तमान परिदृश्य की खोज। रचनात्मक के क्षेत्र में प्रतिभागियों की एक विविध श्रेणी का मिश्रण प्रौद्योगिकी, बातचीत डिजाइन, और नई मीडिया कला, सम्मेलन का उद्देश्य था बहु-विषयक लेंस के माध्यम से संवाद को बढ़ावा देना। कामकाजी समूह कई विषय क्षेत्रों पर ध्यान केंद्रित: पहुंच; प्रदर्शन में संगीत और कोड; क्रिएटिव टेक का लैंडस्केप; और अंतर्राष्ट्रीयकरण।
            +      </p>
            +      </div>
            +      
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/YkfG7Ggpi_o" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/At1newHnZpA" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <p><a href="https://www.youtube.com/channel/UCzMs9qg50AW2LEpLDzHT5NA" target="_blank">Qianqian Ye द्वारा वीडियो</a></p><br>
            +
            +      <img src="../../assets/img/community/2019_1.jpg" alt='समूह में प्रस्तुति देने वाले पोडियम पर आदमी"'/>
            +      <img src="../../assets/img/community/2019_2.jpg" alt='दोपहर के भोजन और एक चर्चा में एक लंबी मेज पर बैठे प्रतिभागी"'/>
            +      <img src="../../assets/img/community/2019_4.jpg" alt='अपने लैपटॉप पर काम करने वाले प्रतिभागियों की कक्षा"'/>
            +      <img src="../../assets/img/community/2019_5.jpg" alt='एक अंधेरे कक्षा में एक बैठक में भाग लेने वाले"'/>
            +      <img src="../../assets/img/community/2019_6.jpg" alt='विविध प्रतिभागियों की कक्षा में प्रस्तुति देती महिला"'/>
            +      <img src="../../assets/img/community/2019_7.jpg" alt='एक व्यस्त कक्षा में बातचीत करने वाले प्रतिभागी"'/>
            +      <img src="../../assets/img/community/2019_8.jpg" alt='एक कक्षा में साथी प्रतिभागियों के साथ बोलने वाली माइक्रोफोन वाली महिला"'/>
            +      <img src="../../assets/img/community/2019_9.jpg" alt='प्रतिभागी अनुमानित पाठ के सामने पोडियम पर डेटा को अज्ञात करने की समस्या के बारे में बोलता है"'/>
            +      <img src="../../assets/img/community/2019_10.jpg" alt='P5.js पाठ के सामने साथी प्रतिभागियों से बात करने वाले माइक्रोफोन के साथ एक व्यक्ति जो पहुंच बढ़ाने के अलावा कोई नई सुविधा नहीं जोड़ेंगे"'/>
            +      <img src="../../assets/img/community/2019_11.jpg" alt='साथी प्रतिभागियों से बात करते माइक्रोफोन में बोलती महिला"'/>
            +      <img src="../../assets/img/community/2019_12.jpg" alt='साथी प्रतिभागियों से बात करने वाला एक माइक्रोफोन"'/>
            +      <img src="../../assets/img/community/2019_13.jpg" alt='प्रतिभागी एक कक्षा में वक्ताओं की ओर ध्यान से सुनते हैं"'/>
            +      <img src="../../assets/img/community/2019_15.jpg" alt='उसके पीछे के प्रक्षेपण में पाठ पवित्र सीमाओं के साथ साथी प्रतिभागियों के साथ बोलने वाली माइक्रोफोन"'/>
            +      <img src="../../assets/img/community/2019_16.jpg" alt='3D की छवि वाले लोगों के एक पैनल को सुनने वाले प्रतिभागियों का ओवरहेड दृश्य इस पर प्रस्तुत किया गया है"'/>
            +      <img src="../../assets/img/community/2019_17.jpg" alt='प्रतिभागी अपने लैपटॉप के साथ एक मेज के चारों ओर बैठते हैं और एक स्क्रीन पर कोड का निरीक्षण करते हैं"'/>
            +      <img src="../../assets/img/community/2019_18.jpg" alt='एक आदमकद टेडी बियर के बगल में बैठी महिला अपने लैपटॉप पर काम करती है"'/>
            +      <img src="../../assets/img/community/2019_19.jpg" alt='मुस्कुराते हुए बाहर खड़े प्रतिभागी"'/>
            +      <img src="../../assets/img/community/2019_20.jpg" alt='एक वार्तालाप में चार प्रतिभागी खड़े होते हैं"'/>
            +      <img src="../../assets/img/community/2019_21.jpg" alt='दोपहर के भोजन के साथ बाहर बैठे प्रतिभागी"'/>
            +      <img src="../../assets/img/community/2019_22.jpg" alt='एक बड़े यू आकार की मेज के चारों ओर बैठे प्रतिभागी कक्षा के सामने की ओर देखते हैं"'/>
            +      <img src="../../assets/img/community/2019_23.jpg" alt='कक्षा में सामने बैठा आदमी ऊर्जावान ढंग से माइक्रोफोन में बोल रहा है"'/>
            +      <img src="../../assets/img/community/campfire.jpg" alt='लोगों के समूह चार एलसीडी मॉनिटर से बने कैम्प फायर के आसपास बैठते हैं।"'/>
            +      <img src="../../assets/img/community/2019_24.jpg" alt='प्रतिभागियों के समूह फोटो हवा में अपने हाथों से उत्साह से मुस्कुराते हुए"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/creativeinquiry/albums/72157710545834046/" target="_blank">जैकलीन जॉनसन द्वारा तस्वीरें</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>प्रतिभागी</h2>
            +      <p>
            +        <a href='https://americanartist.us/biocv' target='_blank'>American Artist</a>, 
            +        <a href='https://www.omayeli.com/' target='_blank'>Omayeli Arenyeka</a>, 
            +        <a href='http://www.sinabahram.com/' target='_blank'>Sina Bahram</a>, 
            +        <a href='https://aatishb.com/' target='_blank'>Aatish Bhatia</a>, 
            +        <a href='https://natalie.computer/' target='_blank'>Natalie Braginsky</a>, 
            +        <a href='https://jonchambers.net/' target='_blank'>Jon Chambers</a>, 
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>, 
            +        <a href='https://www.linkedin.com/in/aren-davey-bb3496103/' target='_blank'>Aren Davey</a>, 
            +        <a href='https://teddavis.org/' target='_blank'>Ted Davis</a>, 
            +        <a href='http://l05.is/' target='_blank'>Carlos Garcia</a>, 
            +        <a href='http://stalgiagrigg.name/' target='_blank'>Stalgia Grigg</a>, 
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>, 
            +        <a href='http://www.shawnemichaelainholloway.com/' target='_blank'>shawné michaelain holloway</a>, 
            +        <a href='http://www.takinglifeseriously.com/index.html' target='_blank'>Claire Kearney-Volpe</a>, 
            +        <a href='https://www.sonalee.me/' target='_blank'>Sona Lee</a>, 
            +        <a href='https://designerken.be/designing' target='_blank'>Kenneth Lim</a>, 
            +        <a href='https://www.outofambit.com/' target='_blank'>Evelyn Masso</a>, 
            +        <a href='http://lauren-mccarthy.com/' target='_blank'>Lauren McCarthy</a>, 
            +        <a href='https://laja.me/' target='_blank'>LaJuné McMillian</a>, 
            +        <a href='https://www.decontextualize.com/' target='_blank'>Allison Parrish</a>, 
            +        <a href='http://www.luisapereira.net/' target='_blank'>Luisa Pereira</a>, 
            +        <a href='https://guillemontecinos.cl/' target='_blank'>Guillermo Montecinos</a>, 
            +        <a href='http://montoyamoraga.io/' target='_blank'>Aarón Montoya-Moraga</a>,
            +        <a href='http://lm-m.com/' target='_blank'>Luis Morales-Navarro</a>, 
            +        Shefali Nayak, 
            +        <a href='http://everest-pipkin.com/' target='_blank'>Everest Pipkin</a>, 
            +        <a href='http://oross.net/' target='_blank'>Olivia Ross</a>, 
            +        <a href='https://dorothysantos.com/' target='_blank'>Dorothy R. Santos</a>, 
            +        <a href='https://www.yashengshe.com/' target='_blank'>Yasheng She</a>, 
            +        <a href='https://junshern.github.io/' target='_blank'>Jun Shern Chan</a>, 
            +        <a href='https://cassietarakajian.com/' target='_blank'>Cassie Tarakajian</a>, 
            +        <a href='https://www.laurenvalley.com/' target='_blank'>Lauren Valley</a>, 
            +        <a href='https://xin-xin.info' target='_blank'>Xin Xin</a>, 
            +        <a href='https://ayxx.me/' target='_blank'>Alex Yixuan Xu</a>, 
            +        <a href='http://www.qianqian-ye.com/' target='_blank'>Qianqian Ye</a>
            +      </p>
            +      </div>
            +
            +
            +      <div class="outputs-subsection">
            +      <h2 id='outputs'>आउटपुट</h2>
            +      <ul aria-labelledby='outputs' class='list_view bullets'>
            +        <!-- arts -->
            +        <li>अमेरिकी कलाकार के नेतृत्व में वर्चुअल स्पेस में ब्लैकनेस एंड जेंडर पर एक पैनल, जिसमें श्वेनी माइकेलैन खोखला और लाजुन मैकमिलियन थे।</li>
            +        <li>स्टालजिया ग्रिग, लाजुन मैकमिलियन, आतिश भाटिया और जॉन चेम्बर्स द्वारा नई कला स्थापना।</li>
            +        <!-- landscape -->
            +        <li>A prototype of a  <a href="https://github.com/aparrish/nb5js-proof-of-concept" target="_blank">p5.js. के लिए नोटबुक इंटरफ़ेस </a> का एक प्रोटोटाइप एलीसन पैरिश द्वारा बनाया गया।</li>
            +        <li>P5 संपादक के लिए p5.js लाइब्रेरी सिस्टम का एक डिज़ाइन। Cassie Tarakajian और Luca Damasco द्वारा बनाया गया।</li>
            +        <li>P5 को अन्य लाइब्रेरीज से जोड़ने वाला प्रोटोटाइप। एलेक्स यिक्सुआन जू और लॉरेन वैली द्वारा बनाया गया।</li>
            +
            +        <!-- global -->
            +        <li><a href="https://docs.google.com/document/d/1NPSVTWlTxWv8_rWLr8j91Qf8CcJA5ns8I8zFjCCmwuk/edit#heading=h.ea0uhs87h6fk" target="_blank">p5.js वैश्विक योगदानकर्ता का टूलकिट।</a> आरोन मोन्टोया-मोरागा, केनेथ लिम, गुइलेर्मो मोंटेकिनो, कियानकियन ये, डोरोथी आर सैंटोस और यशेंग शी द्वारा बनाया गया।</li>
            +
            +        <!-- access -->
            +        <li><a href="https://docs.google.com/presentation/d/19xxc2zWWdFMAQjT6tRdN5ZU13vAKSwM7jojaC2U4F6Q/edit" target="_blank">अहिंसक रचनात्मक कोड कैसे लिखें।</a>ओलिविया रॉस के नेतृत्व में एक ज़ीन।</li>
            +        <li>पहुँच के लिए p5.js वेबसाइट का एक ओवरहाल। स्क्रीन रीडर पहुंच के लिए अद्यतन और होम, डाउनलोड, आरंभ करे और संदर्भ पृष्ठ में सुधार करना। क्लेयर किर्नी-वोल्पे, सिना बहराम, केट होलेनबाख, ओलिविया रॉस, लुइस मोरालेस-नवारो, लॉरेन मैकार्थी और एवलिन मासो के योगदान के साथ।</li>
            +
            +        <!-- music performance -->
            +        <li><a href="https://github.com/aahdee/p5grid">p5grid</a>। P5.js. के लिए अत्यधिक लचीले त्रिभुज, वर्ग, षट्भुज और अष्टकोणीय परिंदों का क्रियान्वयन एरेन डेवी द्वारा बनाया गया।</li>
            +        <li><a href="https://github.com/L05/p5.multiplayer">p5.multiplayer</a>। मल्टी-डिवाइस, मल्टीप्लेयर गेम के निर्माण के लिए टेम्प्लेट फ़ाइलों का एक सेट जहां कई क्लाइंट एक निर्दिष्ट होस्ट पेज से जुड़ सकते हैं। L05 द्वारा बनाया गया।</li>
            +        <li>Experiments using <a href="https://teddavis.org/p5live/">P5LIVE</a> के साथ प्रयोग, सॉफ्टकॉमपाइल के शुरुआती कार्यान्वयन का परीक्षण, ओएससी इंटरफेसिंग और मिडी सेटअप के लिए डेमो के साथ जुड़ाव। एक p5.js सहयोगी लाइव-कोडिंग vj वातावरण! टेड डेविस द्वारा बनाया गया।</li>
            +        <li>लुइसा परेरा, जून शर्न चैन, शेफाली नायक, सोना ली, टेड डेविस और कार्लोस गार्सिया द्वारा सहयोगपूर्ण प्रदर्शन।</li>
            +        <li>नताली ब्रिगिंस्की का एक प्रदर्शन।</li>
            +  
            +        <!-- workshops -->
            +        <li>एवरेस्ट पिपकिन और जॉन चैंबर्स के नेतृत्व में कार्यशालाएं।</li>
            +
            +        <!-- closing -->
            +        <li>गोलान लेविन के नेतृत्व में एक समापन कैम्प सर्कल।</li>
            +        
            +      </ul>
            +      </div>
            +
            +      <div class="contributors-subsection">
            +      <h2>सहयोग </h2>
            +
            +      <p>हमारा योगदान सम्मेलन <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> कार्नेगी मेलन विश्वविद्यालय में हुआ, जो कला, विज्ञान, प्रौद्योगिकी और संस्कृति के चौराहों पर एक अकादमिक प्रयोगशाला है।</p>
            +
            +      <p>यह अयोजन <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      के अनुदान से और <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href='https://www.mozilla.org/en-US/moss/' target=_blank>Mozilla Foundation</a>, <a href='https://www.du.edu/ahss/opensourcearts/' target=_blank>Clinic for Open Source Arts (COSA) at the University of Denver</a>, <a href='http://idm.engineering.nyu.edu/' target=_blank>NYU Tandon IDM</a>, <a href='https://tisch.nyu.edu/itp' target=_blank> NYU ITP</a>, <a href='http://thebaselschoolofdesign.ch/' target=_blank>FHNW Academy of Art and Design</a>, <a href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank>DePaul University College of Computing and Digital Media</a>, और <a href='http://amt.parsons.edu/' target=_blank>Parsons School of Art, Media, and Technology at the New School</a>.
            +      <br><b>धन्यवाद! </b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../../assets/img/community/nea.jpg' alt=""></a></div>
            +      
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:20%' src='../../assets/img/community/studio.png' alt=""/></a>
            +      
            +      <a class='nounderline' href='http://thebaselschoolofdesign.ch/' target=_blank ><img style='width:70%' src='../../assets/img/community/HGK.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://foundation.processing.org' target=_blank ><img style='width:14%' src='../../assets/img/community/processing-foundation.png' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='https://www.du.edu/ahss/opensourcearts/' target=_blank ><img style='width:22%' src='../../assets/img/community/COSA.png' alt=""/></a>
            +
            +      <a class='nounderline' href='http://idm.engineering.nyu.edu/' target=_blank ><img style='width:50%' src='../../assets/img/community/IDM.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://amt.parsons.edu/' target=_blank ><img style='width:22%' src='../../assets/img/community/Parsons.jpg' alt=""/></a>
            +
            +      <a class='nounderline' href='https://tisch.nyu.edu/itp' target=_blank ><img style='width:14%' src='../../assets/img/community/itp.png' alt=""/></a>
            +
            +      <a class='nounderline' href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank ><img style='width:50%' src='../../assets/img/community/depaul.png' alt=""/></a>
            +
            +      
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/community/developer-docs.html b/dist/hi/community/developer-docs.html
            new file mode 100644
            index 0000000000..7830e8fd5a
            --- /dev/null
            +++ b/dist/hi/community/developer-docs.html
            @@ -0,0 +1,141 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<link rel="stylesheet" href="https://unpkg.com/docsify/lib/themes/buble.css">
            +
            +<div id="community-page">
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <div id="app"></div>
            +      <script>
            +        window.$docsify = {
            +          auto2top: true,
            +          executeScript: true,
            +          loadSidebar: 'sidebar.md',
            +          autoHeader: true,
            +          loadNavbar: 'navbar.md',
            +          mergeNavbar: true,
            +          subMaxLevel: 2,
            +          themeColor: '#ed225d',
            +          basePath:
            +          'https://raw.githubusercontent.com/processing/p5.js/master/contributor_docs/',
            +          logo: '../assets/img/p5js.svg',
            +          name: 'p5.js Developer Docs',
            +          repo: 'https://github.com/processing/p5.js',
            +        }
            +      </script>
            +      <script src="https://unpkg.com/docsify/lib/docsify.min.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/community/index.html b/dist/hi/community/index.html
            new file mode 100644
            index 0000000000..ce382af179
            --- /dev/null
            +++ b/dist/hi/community/index.html
            @@ -0,0 +1,234 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content">
            +      <h1>समुदाय</h1>
            +      <div class="community-statement">
            +        <h2 class="community-title">p5.js समुदाय वक्तव्य </h2>
            +        <p>p5.js प्रौद्योगिकी के साथ कला और डिजाइन के निर्माण की खोज में रुचि रखने वाला समुदाय है।
            +        </p>
            +
            +        <p>हम एक समुदाय हैं, और हर लिंग के लोगों के साथ एकजुटता में हैं पहचान और अभिव्यक्ति, यौन अभिविन्यास, जाति, जातीयता, भाषा, न्यूरो-प्रकार, आकार, क्षमता, वर्ग, धर्म, संस्कृति, उपसंस्कृति, राजनीतिक राय, आयु, कौशल स्तर, व्यवसाय और पृष्ठभूमि। हम मानते हैं कि हर किसी के पास सक्रिय रूप से समय, वित्तीय साधन या क्षमता नहीं है भाग लेते हैं, लेकिन हम सभी प्रकार की भागीदारी को पहचानते हैं और प्रोत्साहित करते हैं। हम पहुंच और सशक्तिकरण को सुगम और बढ़ावा देना। हम सब शिक्षार्थी हैं।
            +        </p>
            +
            +        <p>हमें ये हैशटैग पसंद हैं: #noCodeSnobs (क्योंकि हम समुदाय को महत्व देते हैं दक्षता), #newKidLove (क्योंकि हम सभी ने कहीं न कहीं शुरुआत की है), #unassumeCore (क्योंकि हम ज्ञान को ग्रहण नहीं करते हैं), और #BlackLivesMatter (क्योंकि हम समानता में विश्वास करते हैं)।
            +        </p>
            +
            +        <h3 id="in-practice">प्रयोग में:</h3>
            +        <ul aria-labelledby="in-practice" class="bullets list_view">
            +          <li>हम कोड स्नोब नहीं हैं। हम यह नहीं मानते हैं कि किसी के पास पूर्व ज्ञान या ऐसी चीजें हैं जिन्हें जानने की जरूरत है। </li>
            +          <li>हम प्रतिक्रिया के अनुरोधों के साथ सक्रिय रूप से जुड़ने पर जोर देते हैं, चाहे उनकी जटिलता कुछ भी हो। </li>
            +          <li>हम नवागंतुकों का स्वागत करते हैं और दूसरों की शिक्षा को प्राथमिकता देते हैं। हम प्रयास करते हैं किसी नवागंतुक के उत्साह के साथ सभी कार्यों को पूरा करें। क्योंकि हम मानते हैं कि नवागंतुक इस प्रयास में उतने ही मूल्यवान हैं जितने कि विशेषज्ञ। </li>
            +          <li>हम लगातार कई प्रकार के योगदानों को सक्रिय रूप से पहचानने और मान्य करने का प्रयास करते हैं। </li>
            +          <li>हम हमेशा मदद या मार्गदर्शन देने के लिए तैयार हैं। </li>
            +        </ul>
            +
            +        <h3 id="in-conflict">संघर्ष के समय में:</h3>
            +        <ul aria-labelledby="in-conflict" class="bullets list_view">
            +          <li>हम सुनते हैं।</li>
            +          <li>हम दूसरे की भावनाओं को स्वीकार करते हुए स्पष्ट रूप से संवाद करते हैं।</li>
            +          <li>हम स्वीकार करते हैं कि हम गलत हैं, माफी माँगते हैं, और अपने कार्यों के लिए जिम्मेदारी स्वीकार करते हैं।</li>
            +          <li>हम लगातार खुद को और अपने समुदाय को बेहतर बनाने की कोशिश कर रहे हैं।</li>
            +          <li>हम अपने समुदाय को सम्मानजनक और खुले रखते हैं। </li>
            +          <li>हम सभी को सुना हुआ महसूस कराते हैं।</li>
            +          <li>हम अपनी बातचीत में सावधान और दयालु हैं।</li>
            +        </ul>
            +
            +        <h3 id="in-future">भविष्य में:</h3>
            +        <ul aria-labelledby="in-future" class="bullets list_view">
            +          <li>भविष्य आज है।</li>
            +        </ul>
            +        <br>
            +        <h3 id="notes" class='sr-only'>नोट्स</h3>
            +        <p>कृपया हमारे  <a href="https://github.com/processing/p5.js/blob/main/CODE_OF_CONDUCT.md#p5js-code-of-conduct">p5.js Code of Conduct</a> पर भी जाएं। P5.js समुदाय कथन एक <a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons license</a> के तहत लाइसेंस प्राप्त है। एट्रिब्यूशन के साथ साझा करने और रीमिक्स करने के लिए स्वतंत्र महसूस करें। </p>
            +      </div>
            +
            +      <h2 id="contribute">योगदान</h2>
            +      <p>हमारा समुदाय हमेशा उत्साही लोगों की तलाश में रहता है जो हर तरह से मदद करें।</p>
            +
            +      <p><b>विकास करना।</b> <a href="https://github.com/processing/p5.js" target="blank_">GitHub</a> मुख्य स्थान है जहां कोड एकत्र किया जाता है, मुद्दों का दस्तावेजीकरण किया जाता है, और कोड के बारे में चर्चा की जाती है। आरंभ करने के लिए  <a href="https://p5js.org/contributor-docs" target="blank_"> विकास शिक्षण </a>  देखें, या  <a href="../libraries/#create-your-own"> अपना स्वयं का लाइब्रेरी बनाएं। </a></p>
            +
            +      <p><b>प्रलेखन।</b> सभी को प्रलेखन पसंद है। मदद की जरूरत है <a href="https://github.com/processing/p5.js-website/blob/main/contributor_docs/Adding_examples.md" target="blank_">उदाहरणों को पोर्ट करने</a>, और<a href="https://p5js.org/contributor-docs/#/inline_documentation" target="blank_"> प्रलेखन को जोड़ने</a>, और शिक्षण बनाने में।</p>
            +
            +      <p><b>सिखाओ।</b> एक कार्यशाला, एक कक्षा, एक दोस्त, एक सहयोगी को पढ़ाएं! ट्विटर पर @ p5xjs टैग करें और आप जो कर रहे हैं उसे साझा करने के लिए हम पूरी कोशिश करेंगे।</p>
            +
            +      <p><b>सर्जन करना।</b> p5.js आपके रचनात्मक और अद्भुत काम को सामने वाले पृष्ठ पर दिखाने और अन्य लोगों को प्रेरित करने के लिए डिजाइनरों, कलाकारों, कोडर्स, प्रोग्रामर की तलाश में है। अपना काम <a href="mailto:hello@p5js.org">hello@p5js.org</a>पर भेजें।</p>
            +
            +      <p><b>दान देना।</b> p5.js स्वतंत्र और खुला स्रोत है और कलाकारों द्वारा बनाया गया है। <a href="https://processingfoundation.org/support">प्रोसेसिंग फाउंडेशन</a> को दान के माध्यम से p5.js के विकास में सहायता करें। </p>
            +
            +
            +      <h2>p5.js योगदानकर्ता सम्मेलन</h2>
            +      <p>जबकि अधिकांश कार्य ऑनलाइन होते है, हम IRL भी आयोजित करते हैं। हमने पिट्सबर्ग, पेंसिल्वेनिया में <a href="http://studioforcreativeinquiry.org">Frank-Ratchye STUDIO for Creative Inquiry</a> कार्नेगी मेलन विश्वविद्यालय में योगदानकर्ताओं के दो सम्मेलन आयोजित किए। कलाकार, डिजाइनर, डेवलपर्स, शिक्षक p5.js परियोजना को आगे बढ़ाने के लिए एक साथ शामिल हुए। 
            +      </p>
            +      <h2 id="conferences" class="sr-only">Past Conferences</h2>
            +      <ul aria-labelledby="conferences" class="list_view bullets">
            +        <li><a href="contributors-conference-2019.html">योगदानकर्ता सम्मेलन 2019</a></li>
            +        <li><a href="contributors-conference-2015.html">योगदानकर्ता सम्मेलन 2015</a></li>
            +      </ul>
            +
            +      <img src="../../assets/img/community/2015_12.jpg" alt='अपने लैपटॉप पर काम करने वाले प्रतिभागियों के साथ एक कक्षा का ओवरहेड दृश्य"'/>
            +
            +      <h2>मेलिंग सूची</h2>
            +      <div class="email-octopus-form-wrapper">
            +        <p class="email-octopus-success-message"></p>
            +        <p class="email-octopus-error-message"></p>
            +        <form method="post" action="https://emailoctopus.com/lists/537b6ec8-d123-11e6-8561-06ead731d453/members/external-add" class="email-octopus-form">
            +          <p>प्रोसेसिंग फाउंडेशन से कभी-कभार अपडेट प्राप्त करने के लिए अपना ईमेल पता दर्ज करें।</p>
            +          <div class="email-octopus-form-row">
            +            <input type="email" name="emailAddress" placeholder="email" class="email-octopus-email-address">
            +            <button type="submit">subscribe</button>
            +          </div>
            +          <div class="email-octopus-form-row-hp" aria-hidden="true">
            +            <input type="text" name="hp537b6ec8-d123-11e6-8561-06ead731d453" tabindex="-1">
            +          </div>
            +          <div class="email-octopus-form-row-subscribe">
            +            <input type="hidden" name="successRedirectUrl" class="email-octopus-success-redirect-url" value="">
            +          </div>
            +        </form>
            +      </div>
            +      <script src="https://emailoctopus.com/bundles/emailoctopuslist/js/formEmbed.js"></script>
            +      <br><br>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/copyright.html b/dist/hi/copyright.html
            new file mode 100644
            index 0000000000..6dccc4e9ca
            --- /dev/null
            +++ b/dist/hi/copyright.html
            @@ -0,0 +1,154 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">copyright | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>कॉपीराइट संबंधी जानकारी</h1>
            +      <p>p5.js लाइब्रेरी मुफ्त सॉफ्टवेयर है; आप नि: शुल्क सॉफ्टवेयर फाउंडेशन, संस्करण 2.1 द्वारा प्रकाशित <a href="https://github.com/processing/p5.js/blob/main/license.txt">GNU Lesser General 
            +      Public License</a> के तहत इसे पुनर्वितरित कर सकते हैं और / या संशोधित कर सकते हैं। भाषा के लिए संदर्भ एक लाइसेंस के तहत है</p>
            +      <p> जो गैर-वाणिज्यिक उद्देश्यों के लिए इस सामग्री का पुन: उपयोग करना <a href='http://creativecommons.org/licenses/by-nc-sa/4.0/'>Creative Commons</a> संभव बनाता है यदि इसे श्रेय दिया जाता है।</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/download/index.html b/dist/hi/download/index.html
            new file mode 100644
            index 0000000000..287352d8eb
            --- /dev/null
            +++ b/dist/hi/download/index.html
            @@ -0,0 +1,272 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>डाउनलोड</h1>
            +
            +      <h2 class='sr-only'>Introduction</h2>
            +      <p>स्वागत हे! इस पृष्ठ पर "डाउनलोड" शीर्षक से, वास्तव में इस पृष्ठ पर लाइब्रेरी को डाउनलोड करने या इसके साथ ऑनलाइन काम शुरू करने के लिए लिंक का एक संग्रह है। हमने उन चीजों को ऑर्डर करने की कोशिश की है जो यह बता सकती हैं कि नौसिखिया को क्या चाहिए, संसाधनों के लिए जो अधिक अनुभवी प्रोग्रामर की तलाश में हो सकते हैं।</p>
            +
            +      <!-- EDITOR -->
            +      <div class="link_group">
            +        <h2>संपादक</h2>
            +        <p>यह लिंक आपको ऑनलाइन p5.js संपादक पर पुनर्निर्देशित करता है ताकि आप तुरंत p5.js का उपयोग शुरू कर सकें।</p>
            +
            +        <a class='support_link' href="https://editor.p5js.org" target="_blank">
            +          <div class="download_box">
            +
            +            <span class="download_name">p5.js वेब एडिटर</span>
            +            <p>P5.js वेब एडिटर का उपयोग करके कोडिंग शुरू करें, कोई सेटअप आवश्यक नहीं है!</p>
            +
            +          </div>
            +        </a>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- COMPLETE LIBRARY -->
            +      <div class="link_group">
            +        <h2>पूरी लाइब्रेरी</h2>
            +        <p>यह p5.js लाइब्रेरी फ़ाइल, p5.sound एडऑन और एक उदाहरण प्रोजेक्ट वाली एक डाउनलोड है। इसमें संपादक नहीं है।  P5.js प्रोजेक्ट को सेटअप करने का तरीका जानने के लिए  <a href="/hi/get-started/">आरंभ करें</a> देखें।</p>
            +
            +        <a  class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.zip">
            +          <div class="download_box">
            +
            +            <span class="download_name"> पूर्ण p5.js</span>
            +            <p>शामिल हैं:
            +              <br>p5.js, p5.dom.js, p5.sound.js और एक उदाहरण परियोजना है
            +            <br> संस्करण  <span id="p5_version"></span> (<span id="p5_date"></span>)
            +            </p>
            +
            +          </div>
            +        </a>
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- SINGLE FILES -->
            +      <div class="link_group">
            +
            +        <h2 id="single-files">एक दस्तावेज </h2>
            +        <p>ये p5.js लाइब्रेरी फ़ाइल के डाउनलोड या लिंक हैं। कोई अतिरिक्त सामग्री शामिल नहीं है।</p>
            +        <ul aria-labelledby="single-files">
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.js</span>
            +                <p>एक दस्तावेज: 
            +                  <br>पूर्ण असम्बद्ध संस्करण</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.min.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.min.js</span>
            +                <p>एक दस्तावेज: 
            +                  <br>संकुचित संस्करण</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://cdnjs.com/libraries/p5.js" target="_blank">
            +              <div class="download_box half_box last_box">
            +                <span class="download_name">CDN</span>
            +                <p>लिंक: 
            +                  <br>स्टेटिकली होस्ट की गई फ़ाइल</p>
            +              </div>
            +            </a>
            +          </li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +
            +      </div>
            +
            +      <!-- Github resources -->
            +      <div class="link_group">
            +        <h2 id="etc">आदि</h2>
            +        <ul aria-labelledby="etc" id='etc_list' class="list_view bullets">
            +          <li><a href="https://github.com/processing/p5.js/releases">पुराने रिलीज / चैंज </a></li>
            +          <li><a href="https://github.com/processing/p5.js">कोड भंडार (GitHub)</a></li>
            +          <li><a href="https://github.com/processing/p5.js/issues">समस्याओं, बग और त्रुटियों की रिपोर्ट करें </a></li>
            +          <li><a href="https://github.com/processing/p5.js/blob/main/contributor_docs/supported_browsers.md">समर्थित ब्राउज़र </a></li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +    </main>
            +
            +    <script>
            +      $.getJSON('/download/version.json', function(data) {
            +        $('#p5_version').text(data.version);
            +        $('#p5_date').text(data.date);
            +        $('.p5_link').each(function() {
            +          var link = $(this).attr('href').replace('[p5_version]', data.version);
            +          $(this).attr('href', link);
            +        });
            +        $('.editor_version').text(data.editor_version);
            +        $('.editor_link').each(function() {
            +          var link = $(this).attr('href').replace('[editor_version]', data.editor_version);
            +          $(this).attr('href', link);
            +        });
            +      });
            +      $('.support_link').on('click', function (e) {
            +        if ($(this).hasClass('p5_link')) {
            +          e.preventDefault();
            +          window.location = $(this).attr('href');
            +          setTimeout( function() { window.location = 'support.html'; }, 10000);
            +        } else {
            +          setTimeout( function() { window.location = 'support.html'; }, 1000);
            +        }
            +
            +      });
            +
            +    </script>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/download/support.html b/dist/hi/download/support.html
            new file mode 100644
            index 0000000000..be9f078e92
            --- /dev/null
            +++ b/dist/hi/download/support.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>समर्थन p5.js!</h1>
            +
            +      <p>p5.js फ्री, ओपन-सोर्स सॉफ्टवेयर है। हम अपने समुदाय को यथासंभव खुला और समावेशी बनाना चाहते हैं। आप एक व्यक्ति, एक स्टूडियो या एक शैक्षिक संस्थान के रूप में प्रोसेसिंग फाउंडेशन के <a href="https://processingfoundation.org/support/">Processing Foundation</a>सदस्य बनकर <a href="https://processingfoundation.org/fellowships"> इस काम का समर्थन कर सकते हैं। </a> आप सदस्यता खरीदे बिना<a href="https://processingfoundation.org/advocacy"> भी दान कर सकते हैं। </a></p>
            +      <script src="https://donorbox.org/widget.js" paypalExpress="true"></script><iframe allowpaymentrequest="" height="900" name="donorbox" src="https://donorbox.org/embed/support-the-processing-foundation?hide_donation_meter=true" style="max-width: 500px; min-width: 250px; max-height:none!important; margin-top: 1em" ></iframe>
            +      
            +      <p><a href="https://processingfoundation.org">प्रोसेसिंग फाउंडेशन</a> मूल प्रोसेसिंग सॉफ्टवेयर के साथ एक दशक से अधिक काम करने के बाद 2012 में स्थापित किया गया था। फाउंडेशन का मिशन दृश्य कला के भीतर सॉफ्टवेयर साक्षरता को बढ़ावा देना है, और प्रौद्योगिकी से संबंधित क्षेत्रों के भीतर दृश्य साक्षरता - और इन क्षेत्रों को विविध समुदायों के लिए सुलभ बनाना है। हमारा लक्ष्य सभी हितों और पृष्ठभूमि के लोगों को सशक्त बनाना है कि कैसे कोड के साथ रचनात्मक कार्य करना सीखें और विशेष रूप से उन लोगों के लिए, जिनके पास अन्यथा इन उपकरणों और संसाधनों तक पहुंच नहीं है।</p>
            +
            +      <div id="slideshow">
            +        <div>
            +          <img src="../../assets/img/download/p5js-5939.jpg" alt="support-17-alt">
            +          <p>पिट्सबर्ग में क्रिएटिव इंक्वायरी के लिए CMU स्टूडियो में p5.js योगदानकर्ताओं का सम्मेलन (छवि क्रेडिट: तायून चोई)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/saskia-project.jpg" alt="support-18-alt">
            +          <p>प्रोसेसिंग फेलो सास्किया फ्रीके लंदन में कोड लिबरेशन एक्स प्रोसेसिंग वर्कशॉप आयोजित कर रहा है (इमेज क्रेडिट: कोड लिबरेशन फाउंडेशन)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/LearningToTeach45-small.jpg" alt="support-19-alt">
            +          <p>एसएफपीसी के साथ सम्मेलन में सीखना, सिखाना सीखना (छवि क्रेडिट: कीरा साइमन-कैनेडी)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/Cassie_CodeMiami0.png" alt="support-20-alt">
            +          <p>कोड आर्ट मियामी में प्रोसेसिंग फाउंडेशन फेलो कैसी तारकाजियान की कार्यशाला (छवि क्रेडिट: क्रिश्चियन एरेवलो फोटोग्राफी)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders2.jpg" alt="support-21-alt">
            +          <p>साइनिंग कोडर्स p5.js कार्यशाला में टैयून चोई और एएसएल दुभाषिया (छवि क्रेडिट: टायून चोई)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/gsoc_kickoff.jpg" alt="support-22-alt">
            +          <p>कोड किकऑफ़ की Google समर (छवि क्रेडिट: ताइओन चोई)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/Cassie_CodeMiami5.png" alt="support-23-alt">
            +          <p>कोड आर्ट मियामी में प्रोसेसिंग फाउंडेशन फेलो कैसी तारकाजियान की कार्यशाला (छवि क्रेडिट: क्रिश्चियन एरेवलो फोटोग्राफी)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders0.jpg" alt="support-24-alt">
            +          <p>लुइसा परेरा और येसेउल सांग टायून चोई की अगुवाई में एक सांकेतिक भाषा आधारित p5.js कार्यशाला को सुविधाजनक बनाने में मदद करते हैं (छवि क्रेडिट: तायून चोई)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/conf2.jpg" alt="support-25-alt">
            +          <p>पिट्सबर्ग में क्रिएटिव इंक्वायरी के लिए CMU स्टूडियो में p5.js योगदानकर्ताओं का सम्मेलन (छवि क्रेडिट: तायून चोई)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/digitalcitizens-panel3.png" alt="support-26-alt">
            +          <p>प्रोसेसिंग फ़ेलो डिजिटल सिटिज़ंस लैब इंटरनेशनल सेंटर ऑफ़ फ़ोटोग्राफ़ी में STEM शिक्षण पर एक पैनल होस्ट करता है (छवि क्रेडिट: इंटरनेशनल सेंटर ऑफ़ फ़ोटोग्राफ़ी)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/aaron.jpg" alt="support-27-alt">
            +          <p>सैंटियागो, मोरागा के नेतृत्व में सैंटियागो, चिली में p5.js कार्यशाला में प्रतिभागी (छवि क्रेडिट: आरोन मोंटोया-मोरागा।)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders3.jpg" alt="support-28-alt">
            +          <p>क्लेयर केर्नी-वोल्पे ने एक साइन लैंग्वेज आधारित p5.js वर्कशॉप की सुविधा दी, जिसका नेतृत्व ताइओन चोई (छवि क्रेडिट: तायून चोई) ने किया</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/diygirls1.jpg" alt="support-29-alt">
            +          <p>प्रोसेसिंग फाउंडेशन फेलो DIY गर्ल्स लॉस एंजेल्स में एक क्रिएटिव कोडिंग प्रोग्राम चलाती हैं (इमेज क्रेडिट: DIY गर्ल्स)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/digitalcitizens7.jpg" alt="support-30-alt">
            +          <p>प्रोसेसिंग डिजिटल डिजिटल लैब प्रयोगशाला</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/p5-coast2coast.jpg" alt="support-31-alt">
            +          <p>UCLA DMA और NYU ITP में Bicoastal p5.js मीटअप</p>
            +        </div>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<script src="../../assets/js/slideshow.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/examples/index.html b/dist/hi/examples/index.html
            new file mode 100644
            index 0000000000..256f7e8ac4
            --- /dev/null
            +++ b/dist/hi/examples/index.html
            @@ -0,0 +1,3381 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">examples | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="examples-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>उदाहरण</h1>
            +
            +      <div class="column_0 column">
            +      
            +        <h3 name='structure' class='anchor'>संरचना</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="structure-comments-and-statements
            .html"
            +            
            +                data-en='Comments/Statements
            '
            +            
            +                data-es='Comments and Statements
            '
            +            
            +                data-hi='निर्देशांक
            '
            +            
            +                data-ko='스테이트멘트와 코멘트
            '
            +            
            +                data-zh-Hans='Comments and Statements
            '
            +            
            +          >Comments/Statements
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-coordinates
            .html"
            +            
            +                data-en='Coordinates
            '
            +            
            +                data-es='Coordenadas
            '
            +            
            +                data-hi='चौड़ाई और ऊंचाई
            '
            +            
            +                data-ko='좌표
            '
            +            
            +                data-zh-Hans='坐标
            '
            +            
            +          >Coordinates
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-width-and-height
            .html"
            +            
            +                data-en='Width/Height
            '
            +            
            +                data-es='width y height
            '
            +            
            +                data-hi='सेटअप और ड्रा
            '
            +            
            +                data-ko='너비와 높이
            '
            +            
            +                data-zh-Hans='Width 和 Height
            '
            +            
            +          >Width/Height
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-setup-and-draw
            .html"
            +            
            +                data-en='Setup/Draw
            '
            +            
            +                data-es='Setup y Draw
            '
            +            
            +                data-hi='और ड्रा
            '
            +            
            +                data-ko='설정하고 그리기
            '
            +            
            +                data-zh-Hans='Setup 与 Draw
            '
            +            
            +          >Setup/Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-no-loop
            .html"
            +            
            +                data-en='No Loop
            '
            +            
            +                data-es='No Loop
            '
            +            
            +                data-hi='लूप
            '
            +            
            +                data-ko='루프 중단
            '
            +            
            +                data-zh-Hans='No Loop
            '
            +            
            +          >No Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-loop
            .html"
            +            
            +                data-en='Loop
            '
            +            
            +                data-es='Bucle
            '
            +            
            +                data-hi='रेड्रा
            '
            +            
            +                data-ko='루프
            '
            +            
            +                data-zh-Hans='Loop
            '
            +            
            +          >Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-redraw
            .html"
            +            
            +                data-en='Redraw
            '
            +            
            +                data-es='Redraw
            '
            +            
            +                data-hi='कार्य
            '
            +            
            +                data-ko='다시 그리기
            '
            +            
            +                data-zh-Hans='Redraw
            '
            +            
            +          >Redraw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-functions
            .html"
            +            
            +                data-en='Functions
            '
            +            
            +                data-es='Funciones
            '
            +            
            +                data-hi='रिकर्सन
            '
            +            
            +                data-ko='그 외 함수들
            '
            +            
            +                data-zh-Hans='函数
            '
            +            
            +          >Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-recursion
            .html"
            +            
            +                data-en='Recursion
            '
            +            
            +                data-es='Recursión
            '
            +            
            +                data-hi='ग्राफिक्स बनाएं
            '
            +            
            +                data-ko='재귀 함수
            '
            +            
            +                data-zh-Hans='递归
            '
            +            
            +          >Recursion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-create-graphics
            .html"
            +            
            +                data-en='Create Graphics
            '
            +            
            +                data-es='createGraphics
            '
            +            
            +                data-ko='그래픽 만들기
            '
            +            
            +                data-zh-Hans='Create Graphics
            '
            +            
            +          >Create Graphics
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='form' class='anchor'>प्रपत्र</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="form-points-and-lines
            .html"
            +            
            +                data-en='Points/Lines
            '
            +            
            +                data-es='Puntos y líneas
            '
            +            
            +                data-hi='अंक और रेखाएं
            '
            +            
            +                data-ko='점과 선
            '
            +            
            +                data-zh-Hans='Points 与 Lines
            '
            +            
            +          >Points/Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-shape-primitives
            .html"
            +            
            +                data-en='Shape Primitives
            '
            +            
            +                data-es='Figuras primitivas
            '
            +            
            +                data-hi='शेप प्रिमिटिव्स
            '
            +            
            +                data-ko='기본 조형
            '
            +            
            +                data-zh-Hans='基本形状
            '
            +            
            +          >Shape Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-pie-chart
            .html"
            +            
            +                data-en='Pie Chart
            '
            +            
            +                data-es='Gráfico de sectores
            '
            +            
            +                data-hi='पाई चार्ट
            '
            +            
            +                data-ko='파이형 차트
            '
            +            
            +                data-zh-Hans='饼状图
            '
            +            
            +          >Pie Chart
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-regular-polygon
            .html"
            +            
            +                data-en='Regular Polygon
            '
            +            
            +                data-es='Polígono regular
            '
            +            
            +                data-hi='नियमित बहुभुज
            '
            +            
            +                data-ko='정다각형
            '
            +            
            +                data-zh-Hans='正多边形
            '
            +            
            +          >Regular Polygon
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-star
            .html"
            +            
            +                data-en='Star
            '
            +            
            +                data-es='Estrella
            '
            +            
            +                data-hi='स्टार
            '
            +            
            +                data-ko='별모양
            '
            +            
            +                data-zh-Hans='Star
            '
            +            
            +          >Star
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-triangle-strip
            .html"
            +            
            +                data-en='Triangle Strip
            '
            +            
            +                data-es='Tira de triángulos
            '
            +            
            +                data-hi='त्रिभुज पट्टी
            '
            +            
            +                data-ko='삼각형 고리
            '
            +            
            +                data-zh-Hans='Triangle Strip
            '
            +            
            +          >Triangle Strip
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-bezier
            .html"
            +            
            +                data-en='Bezier
            '
            +            
            +                data-es='Bezier
            '
            +            
            +                data-hi='बेज़ियर
            '
            +            
            +                data-ko='베지어 곡선
            '
            +            
            +                data-zh-Hans='Bezier
            '
            +            
            +          >Bezier
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-3d-primitives
            .html"
            +            
            +                data-en='3D Primitives
            '
            +            
            +                data-es='Primitivas 3D
            '
            +            
            +                data-hi='३डी प्रिमिटिव्स
            '
            +            
            +                data-ko='3D 기본 조형
            '
            +            
            +                data-zh-Hans='基本 3D 形状
            '
            +            
            +          >3D Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-trig-wheels-and-pie-chart
            .html"
            +            
            +                data-en='Trig Wheels/Pie Chart
            '
            +            
            +                data-es='Trig Wheels and Pie Chart
            '
            +            
            +                data-ko='단위원과 파이 차트
            '
            +            
            +                data-zh-Hans='Trig Wheels and Pie Chart
            '
            +            
            +          >Trig Wheels/Pie Chart
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='data' class='anchor'>डेटा</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="data-variables
            .html"
            +            
            +                data-en='Variables
            '
            +            
            +                data-es='Variables
            '
            +            
            +                data-hi='चर
            '
            +            
            +                data-ko='변수
            '
            +            
            +                data-zh-Hans='变量
            '
            +            
            +          >Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-true-and-false
            .html"
            +            
            +                data-en='True/False
            '
            +            
            +                data-es='True y False
            '
            +            
            +                data-hi='सही और गलत
            '
            +            
            +                data-ko='참과 거짓
            '
            +            
            +                data-zh-Hans='True 和 False
            '
            +            
            +          >True/False
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-variable-scope
            .html"
            +            
            +                data-en='Variable Scope
            '
            +            
            +                data-es='Alcance de variabless
            '
            +            
            +                data-hi='परिवर्तनीय दायरा
            '
            +            
            +                data-ko='변수 범위
            '
            +            
            +                data-zh-Hans='变量范围
            '
            +            
            +          >Variable Scope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-numbers
            .html"
            +            
            +                data-en='Numbers
            '
            +            
            +                data-es='Números
            '
            +            
            +                data-hi='नंबर
            '
            +            
            +                data-ko='숫자값
            '
            +            
            +                data-zh-Hans='Numbers
            '
            +            
            +          >Numbers
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='arrays' class='anchor'>Arrays</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="arrays-array
            .html"
            +            
            +                data-en='Array
            '
            +            
            +                data-es='Arreglo
            '
            +            
            +                data-hi='ऐरे
            '
            +            
            +                data-ko='배열
            '
            +            
            +                data-zh-Hans='数组
            '
            +            
            +          >Array
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-2d
            .html"
            +            
            +                data-en='Array 2D
            '
            +            
            +                data-es='Arreglo 2D
            '
            +            
            +                data-hi='ऐरे 2D
            '
            +            
            +                data-ko='2D 배열
            '
            +            
            +                data-zh-Hans='2D 数组
            '
            +            
            +          >Array 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-objects
            .html"
            +            
            +                data-en='Array Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='ऐरे ऑब्जेक्ट्स
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='数组对象
            '
            +            
            +          >Array Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-walk-over-2darray
            .html"
            +            
            +                data-en='Walk Over 2dArray
            '
            +            
            +                data-es='Walk Over 2dArray
            '
            +            
            +                data-ko='Walk Over 2dArray
            '
            +            
            +                data-zh-Hans='Walk Over 2dArray
            '
            +            
            +          >Walk Over 2dArray
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='control' class='anchor'>नियंत्रण</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="control-iteration
            .html"
            +            
            +                data-en='Iteration
            '
            +            
            +                data-es='Iteración
            '
            +            
            +                data-hi='पुनरावृत्ति
            '
            +            
            +                data-ko='for 반복문
            '
            +            
            +                data-zh-Hans='迭代
            '
            +            
            +          >Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-embedded-iteration
            .html"
            +            
            +                data-en='Embedded Iteration
            '
            +            
            +                data-es='Iteración anidada
            '
            +            
            +                data-hi='एंबेडेड इटरेशन
            '
            +            
            +                data-ko='for 내장 반복문
            '
            +            
            +                data-zh-Hans='嵌入式迭代
            '
            +            
            +          >Embedded Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-1
            .html"
            +            
            +                data-en='Conditionals 1
            '
            +            
            +                data-es='Condicionales 1
            '
            +            
            +                data-hi='सशर्त 1
            '
            +            
            +                data-ko='조건문 1
            '
            +            
            +                data-zh-Hans='条件 1
            '
            +            
            +          >Conditionals 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-2
            .html"
            +            
            +                data-en='Conditionals 2
            '
            +            
            +                data-es='Condicionales 2
            '
            +            
            +                data-hi='सशर्त 2
            '
            +            
            +                data-ko='조건문 2
            '
            +            
            +                data-zh-Hans='条件 2
            '
            +            
            +          >Conditionals 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators
            .html"
            +            
            +                data-en='Logical Operators
            '
            +            
            +                data-es='Operadores lógicos
            '
            +            
            +                data-hi='लॉजिकल ऑपरेटर्स
            '
            +            
            +                data-ko='논리적 연산자
            '
            +            
            +                data-zh-Hans='逻辑操作符
            '
            +            
            +          >Logical Operators
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators-2
            .html"
            +            
            +                data-en='Logical Operators 2
            '
            +            
            +                data-es='Logical Operators 2
            '
            +            
            +                data-ko='Logical Operators 2
            '
            +            
            +                data-zh-Hans='Logical Operators 2
            '
            +            
            +          >Logical Operators 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditional-shapes
            .html"
            +            
            +                data-en='Conditional Shapes
            '
            +            
            +                data-es='Conditional Shapes
            '
            +            
            +                data-ko='Conditional Shapes
            '
            +            
            +                data-zh-Hans='Conditional Shapes
            '
            +            
            +          >Conditional Shapes
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='image' class='anchor'>छवि</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="image-load-and-display-image
            .html"
            +            
            +                data-en='Load/Display Image
            '
            +            
            +                data-es='Cargar y mostrar imagen
            '
            +            
            +                data-hi='लोड और डिस्प्ले इमेज
            '
            +            
            +                data-ko='이미지 불러오기 및 보이기
            '
            +            
            +                data-zh-Hans='加载(Load)和显示(Display)图像
            '
            +            
            +          >Load/Display Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-background-image
            .html"
            +            
            +                data-en='Background Image
            '
            +            
            +                data-es='Imagen de fondo
            '
            +            
            +                data-hi='पृष्ठभूमि छवि
            '
            +            
            +                data-ko='배경 이미지
            '
            +            
            +                data-zh-Hans='背景图像
            '
            +            
            +          >Background Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-transparency
            .html"
            +            
            +                data-en='Transparency
            '
            +            
            +                data-es='Transparencia
            '
            +            
            +                data-hi='पारदर्शिता
            '
            +            
            +                data-ko='투명도
            '
            +            
            +                data-zh-Hans='透明度
            '
            +            
            +          >Transparency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-alpha-mask
            .html"
            +            
            +                data-en='Alpha Mask
            '
            +            
            +                data-es='Alpha Mask
            '
            +            
            +                data-hi='अल्फा मास्क
            '
            +            
            +                data-ko='알파 마스크
            '
            +            
            +                data-zh-Hans='透明度遮罩 (Alpha Mask)
            '
            +            
            +          >Alpha Mask
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-create-image
            .html"
            +            
            +                data-en='Create Image
            '
            +            
            +                data-es='Crear una imagen
            '
            +            
            +                data-hi='इमेज बनाएं
            '
            +            
            +                data-ko='이미지 만들기
            '
            +            
            +                data-zh-Hans='创建图像
            '
            +            
            +          >Create Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-pointillism
            .html"
            +            
            +                data-en='Pointillism
            '
            +            
            +                data-es='Puntillismo
            '
            +            
            +                data-hi='पॉइंटिलिज्म
            '
            +            
            +                data-ko='점묘법
            '
            +            
            +                data-zh-Hans='点画(Pointillism)
            '
            +            
            +          >Pointillism
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-blur
            .html"
            +            
            +                data-en='Blur
            '
            +            
            +                data-es='Blur
            '
            +            
            +                data-ko='Blur
            '
            +            
            +                data-zh-Hans='Blur
            '
            +            
            +          >Blur
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-edge-detection
            .html"
            +            
            +                data-en='Edge Detection
            '
            +            
            +                data-es='Edge Detection
            '
            +            
            +                data-ko='Edge Detection
            '
            +            
            +                data-zh-Hans='Edge Detection
            '
            +            
            +          >Edge Detection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brightness
            '
            +            
            +                data-ko='Brightness
            '
            +            
            +                data-zh-Hans='Brightness
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-convolution
            .html"
            +            
            +                data-en='Convolution
            '
            +            
            +                data-es='Convolution
            '
            +            
            +                data-ko='Convolution
            '
            +            
            +                data-zh-Hans='Convolution
            '
            +            
            +          >Convolution
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-copy-method
            .html"
            +            
            +                data-en='Copy() method
            '
            +            
            +                data-es='Método copy()
            '
            +            
            +                data-ko='Copy() method
            '
            +            
            +                data-zh-Hans='Copy() 函数
            '
            +            
            +          >Copy() method
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='color' class='anchor'>रंग</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="color-hue
            .html"
            +            
            +                data-en='Hue
            '
            +            
            +                data-es='Tinte
            '
            +            
            +                data-hi='ह्यू
            '
            +            
            +                data-ko='색조
            '
            +            
            +                data-zh-Hans='色调
            '
            +            
            +          >Hue
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-saturation
            .html"
            +            
            +                data-en='Saturation
            '
            +            
            +                data-es='Saturación
            '
            +            
            +                data-hi='संतृप्ति
            '
            +            
            +                data-ko='채도
            '
            +            
            +                data-zh-Hans='饱和度
            '
            +            
            +          >Saturation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brillo
            '
            +            
            +                data-hi='चमक
            '
            +            
            +                data-ko='밝기
            '
            +            
            +                data-zh-Hans='亮度
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-color-variables
            .html"
            +            
            +                data-en='Color Variables
            '
            +            
            +                data-es='Variables de color
            '
            +            
            +                data-hi='रंग चर
            '
            +            
            +                data-ko='색상 변수
            '
            +            
            +                data-zh-Hans='颜色变量
            '
            +            
            +          >Color Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-relativity
            .html"
            +            
            +                data-en='Relativity
            '
            +            
            +                data-es='Relatividad
            '
            +            
            +                data-hi='सापेक्षता
            '
            +            
            +                data-ko='상대성
            '
            +            
            +                data-zh-Hans='相对性
            '
            +            
            +          >Relativity
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-linear-gradient
            .html"
            +            
            +                data-en='Linear Gradient
            '
            +            
            +                data-es='Gradiente linear
            '
            +            
            +                data-hi='रैखिक ढाल
            '
            +            
            +                data-ko='선형 그래디언트
            '
            +            
            +                data-zh-Hans='线性渐变
            '
            +            
            +          >Linear Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-radial-gradient
            .html"
            +            
            +                data-en='Radial Gradient
            '
            +            
            +                data-es='Gradiente radial
            '
            +            
            +                data-hi='रेडियल ग्रेडिएंट
            '
            +            
            +                data-ko='방사형 그래디언트
            '
            +            
            +                data-zh-Hans='径向渐变
            '
            +            
            +          >Radial Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-lerp-color
            .html"
            +            
            +                data-en='Lerp Color
            '
            +            
            +                data-es='Interpolación de color
            '
            +            
            +                data-hi='Lerp Color
            '
            +            
            +                data-ko='선형 보간(lerp) 색상
            '
            +            
            +                data-zh-Hans='插值颜色
            '
            +            
            +          >Lerp Color
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='math' class='anchor'>गणित</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="math-increment-decrement
            .html"
            +            
            +                data-en='Increment Decrement
            '
            +            
            +                data-es='Incremento y decremento
            '
            +            
            +                data-hi='वेतन वृद्धि
            '
            +            
            +                data-ko='증가와 감소
            '
            +            
            +                data-zh-Hans='增量/减量
            '
            +            
            +          >Increment Decrement
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-operator-precedence
            .html"
            +            
            +                data-en='Operator Precedence
            '
            +            
            +                data-es='Precedencia de operadores
            '
            +            
            +                data-hi='ऑपरेटर वरीयता
            '
            +            
            +                data-ko='연산자 우선 순위
            '
            +            
            +                data-zh-Hans='操作符优先级
            '
            +            
            +          >Operator Precedence
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-1d
            .html"
            +            
            +                data-en='Distance 1D
            '
            +            
            +                data-es='Distancia 1D
            '
            +            
            +                data-hi='दूरी 1डी
            '
            +            
            +                data-ko='1D 거리
            '
            +            
            +                data-zh-Hans='一维间距
            '
            +            
            +          >Distance 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-2d
            .html"
            +            
            +                data-en='Distance 2D
            '
            +            
            +                data-es='Distancia 2D
            '
            +            
            +                data-hi='दूरी 2डी
            '
            +            
            +                data-ko='2D 거리
            '
            +            
            +                data-zh-Hans='二维间距
            '
            +            
            +          >Distance 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine
            .html"
            +            
            +                data-en='Sine
            '
            +            
            +                data-es='Seno
            '
            +            
            +                data-hi='साइन
            '
            +            
            +                data-ko='사인
            '
            +            
            +                data-zh-Hans='正弦
            '
            +            
            +          >Sine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-cosine
            .html"
            +            
            +                data-en='Sine Cosine
            '
            +            
            +                data-es='Seno y coseno
            '
            +            
            +                data-hi='साइन कोसाइन
            '
            +            
            +                data-ko='사인 코사인
            '
            +            
            +                data-zh-Hans='正弦余弦
            '
            +            
            +          >Sine Cosine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-wave
            .html"
            +            
            +                data-en='Sine Wave
            '
            +            
            +                data-es='Onda sinusoidal
            '
            +            
            +                data-hi='साइन वेव
            '
            +            
            +                data-ko='사인파
            '
            +            
            +                data-zh-Hans='正弦波
            '
            +            
            +          >Sine Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-additive-wave
            .html"
            +            
            +                data-en='Additive Wave
            '
            +            
            +                data-es='Onda aditiva
            '
            +            
            +                data-hi='Additive Wave
            '
            +            
            +                data-ko='파형 추가
            '
            +            
            +                data-zh-Hans='加性波
            '
            +            
            +          >Additive Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-polartocartesian
            .html"
            +            
            +                data-en='PolarToCartesian
            '
            +            
            +                data-es='Polar a cartesiano
            '
            +            
            +                data-hi='PolarToCartesian
            '
            +            
            +                data-ko='극좌표를 직교 좌표로
            '
            +            
            +                data-zh-Hans='PolarToCartesian
            '
            +            
            +          >PolarToCartesian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-arctangent
            .html"
            +            
            +                data-en='Arctangent
            '
            +            
            +                data-es='Arcotangente
            '
            +            
            +                data-hi='आर्कटिक
            '
            +            
            +                data-ko='아크탄젠트
            '
            +            
            +                data-zh-Hans='反正切
            '
            +            
            +          >Arctangent
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-linear-interpolation
            .html"
            +            
            +                data-en='Linear Interpolation
            '
            +            
            +                data-es='Interpolación Lineal
            '
            +            
            +                data-hi='रैखिक इंटरपोलेशन
            '
            +            
            +                data-ko='선형 보간법
            '
            +            
            +                data-zh-Hans='线性插值
            '
            +            
            +          >Linear Interpolation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-double-random
            .html"
            +            
            +                data-en='Double Random
            '
            +            
            +                data-es='Doble aleatorio
            '
            +            
            +                data-hi='डबल रैंडम
            '
            +            
            +                data-ko='이중 랜덤
            '
            +            
            +                data-zh-Hans='双重随机
            '
            +            
            +          >Double Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random
            .html"
            +            
            +                data-en='Random
            '
            +            
            +                data-es='Aleatorio
            '
            +            
            +                data-hi='रैंडम
            '
            +            
            +                data-ko='랜덤
            '
            +            
            +                data-zh-Hans='随机
            '
            +            
            +          >Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise1d
            .html"
            +            
            +                data-en='Noise1D
            '
            +            
            +                data-es='Ruido 1D
            '
            +            
            +                data-hi='Noise1D
            '
            +            
            +                data-ko='1D 노이즈
            '
            +            
            +                data-zh-Hans='一维噪声 (Noise1D)
            '
            +            
            +          >Noise1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise-wave
            .html"
            +            
            +                data-en='Noise Wave
            '
            +            
            +                data-es='Onda de ruido
            '
            +            
            +                data-hi='शोर लहर
            '
            +            
            +                data-ko='노이즈 파형
            '
            +            
            +                data-zh-Hans='噪声波
            '
            +            
            +          >Noise Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise2d
            .html"
            +            
            +                data-en='Noise2D
            '
            +            
            +                data-es='Ruido 2D
            '
            +            
            +                data-hi='Noise2D
            '
            +            
            +                data-ko='2D 노이즈
            '
            +            
            +                data-zh-Hans='二维噪声 (Noise2D)
            '
            +            
            +          >Noise2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise3d
            .html"
            +            
            +                data-en='Noise3D
            '
            +            
            +                data-es='Ruido 3D
            '
            +            
            +                data-hi='Noise3D
            '
            +            
            +                data-ko='3D 노이즈
            '
            +            
            +                data-zh-Hans='三维噪声 (Noise3D)
            '
            +            
            +          >Noise3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-chords
            .html"
            +            
            +                data-en='Random Chords
            '
            +            
            +                data-es='Cuerdas Aleatorias
            '
            +            
            +                data-hi='रैंडम कॉर्ड्स
            '
            +            
            +                data-ko='랜덤 선들
            '
            +            
            +                data-zh-Hans='随机弦
            '
            +            
            +          >Random Chords
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-gaussian
            .html"
            +            
            +                data-en='Random Gaussian
            '
            +            
            +                data-es='Mapear
            '
            +            
            +                data-hi='नक्शा
            '
            +            
            +                data-ko='매핑(map)
            '
            +            
            +                data-zh-Hans='映射 (Map)
            '
            +            
            +          >Random Gaussian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-map
            .html"
            +            
            +                data-en='Map
            '
            +            
            +                data-es='Ecuaciones Paramétricas
            '
            +            
            +                data-hi='पैरामीट्रिक समीकरण
            '
            +            
            +                data-ko='매개변수 방정식
            '
            +            
            +                data-zh-Hans='参数方程
            '
            +            
            +          >Map
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-graphing-2d-equations
            .html"
            +            
            +                data-en='Graphing 2D Equations
            '
            +            
            +                data-es='Graphing 2D Equations
            '
            +            
            +                data-ko='Graphing 2D Equations
            '
            +            
            +                data-zh-Hans='Graphing 2D Equations
            '
            +            
            +          >Graphing 2D Equations
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-parametric-equations
            .html"
            +            
            +                data-en='Parametric Equations
            '
            +            
            +                data-es='Parametric Equations
            '
            +            
            +                data-ko='Parametric Equations
            '
            +            
            +                data-zh-Hans='Parametric Equations
            '
            +            
            +          >Parametric Equations
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_1 column">
            +        
            +      
            +        <h3 name='simulate' class='anchor'>सिम्यलट</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="simulate-forces
            .html"
            +            
            +                data-en='Forces
            '
            +            
            +                data-es='Fuerzas
            '
            +            
            +                data-hi='बल
            '
            +            
            +                data-ko='힘
            '
            +            
            +                data-zh-Hans='Forces
            '
            +            
            +          >Forces
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particle-system
            .html"
            +            
            +                data-en='Particle System
            '
            +            
            +                data-es='Sistema de partículas
            '
            +            
            +                data-hi='कण प्रणाली
            '
            +            
            +                data-ko='파티클 시스템
            '
            +            
            +                data-zh-Hans='Particle System
            '
            +            
            +          >Particle System
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-wolfram-ca
            .html"
            +            
            +                data-en='Wolfram CA
            '
            +            
            +                data-es='Wolfram CA
            '
            +            
            +                data-hi='वोल्फ्राम सीए
            '
            +            
            +                data-ko='울프램 셀룰러 오토마타
            '
            +            
            +                data-zh-Hans='Wolfram CA
            '
            +            
            +          >Wolfram CA
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-game-of-life
            .html"
            +            
            +                data-en='Game of Life
            '
            +            
            +                data-es='Juego de la vida
            '
            +            
            +                data-hi='Game of Life
            '
            +            
            +                data-ko='라이프 게임
            '
            +            
            +                data-zh-Hans='Game of Life
            '
            +            
            +          >Game of Life
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-multiple-particle-systems
            .html"
            +            
            +                data-en='Multiple Particle Systems
            '
            +            
            +                data-es='Múltiples sistemas de partículas
            '
            +            
            +                data-hi='मल्टीपल पार्टिकल सिस्टम
            '
            +            
            +                data-ko='멀티플 파티클 시스템
            '
            +            
            +                data-zh-Hans='Multiple Particle Systems
            '
            +            
            +          >Multiple Particle Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spirograph
            .html"
            +            
            +                data-en='Spirograph
            '
            +            
            +                data-es='Espirógrafo
            '
            +            
            +                data-hi='स्पाइरोग्राफ
            '
            +            
            +                data-ko='스피로그래프
            '
            +            
            +                data-zh-Hans='Spirograph
            '
            +            
            +          >Spirograph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-l-systems
            .html"
            +            
            +                data-en='L-Systems
            '
            +            
            +                data-es='Sístemas-L
            '
            +            
            +                data-hi='एल-सिस्टम्स
            '
            +            
            +                data-ko='L-시스템
            '
            +            
            +                data-zh-Hans='L-Systems
            '
            +            
            +          >L-Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spring
            .html"
            +            
            +                data-en='Spring
            '
            +            
            +                data-es='Resorte
            '
            +            
            +                data-hi='वसंत
            '
            +            
            +                data-ko='용수철
            '
            +            
            +                data-zh-Hans='Spring
            '
            +            
            +          >Spring
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-springs
            .html"
            +            
            +                data-en='Springs
            '
            +            
            +                data-es='Resortes
            '
            +            
            +                data-hi='स्प्रिंग्स
            '
            +            
            +                data-ko='용수철들
            '
            +            
            +                data-zh-Hans='Springs
            '
            +            
            +          >Springs
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-soft-body
            .html"
            +            
            +                data-en='Soft Body
            '
            +            
            +                data-es='Cuerpo blando
            '
            +            
            +                data-hi='शीतल शरीर
            '
            +            
            +                data-ko='소프트 바디
            '
            +            
            +                data-zh-Hans='Soft Body
            '
            +            
            +          >Soft Body
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-smokeparticles
            .html"
            +            
            +                data-en='SmokeParticles
            '
            +            
            +                data-es='Partículas de humo
            '
            +            
            +                data-hi='स्मोकपार्टिकल्स
            '
            +            
            +                data-ko='연기 파티클
            '
            +            
            +                data-zh-Hans='SmokeParticles
            '
            +            
            +          >SmokeParticles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Movimiento browniano
            '
            +            
            +                data-hi='ब्राउनियन मोशन
            '
            +            
            +                data-ko='브라운 운동
            '
            +            
            +                data-zh-Hans='Brownian Motion
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-chain
            .html"
            +            
            +                data-en='Chain
            '
            +            
            +                data-es='Cadena
            '
            +            
            +                data-hi='चैन
            '
            +            
            +                data-ko='사슬
            '
            +            
            +                data-zh-Hans='Chain
            '
            +            
            +          >Chain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-snowflakes
            .html"
            +            
            +                data-en='Snowflakes
            '
            +            
            +                data-es='Copos de Nieve
            '
            +            
            +                data-hi='स्नोफ्लेक्स
            '
            +            
            +                data-ko='눈송이 파티클
            '
            +            
            +                data-zh-Hans='Snowflakes
            '
            +            
            +          >Snowflakes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-penrose-tiles
            .html"
            +            
            +                data-en='Penrose Tiles
            '
            +            
            +                data-es='Baldosas de Penrose
            '
            +            
            +                data-hi='पेनरोज़ टाइलें
            '
            +            
            +                data-ko='펜로즈 타일
            '
            +            
            +                data-zh-Hans='Penrose Tiles
            '
            +            
            +          >Penrose Tiles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-recursive-tree
            .html"
            +            
            +                data-en='Recursive Tree
            '
            +            
            +                data-es='Árbol Recursivo
            '
            +            
            +                data-hi='रिकर्सिव ट्री
            '
            +            
            +                data-ko='재귀 나무
            '
            +            
            +                data-zh-Hans='Recursive Tree
            '
            +            
            +          >Recursive Tree
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-the-mandelbrot-set
            .html"
            +            
            +                data-en='The Mandelbrot Set
            '
            +            
            +                data-es='El Conjunto de Mandelbrot
            '
            +            
            +                data-hi='मंडेलब्रॉट सेत
            '
            +            
            +                data-ko='망델브로 집합
            '
            +            
            +                data-zh-Hans='The Mandelbrot Set
            '
            +            
            +          >The Mandelbrot Set
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-koch-curve
            .html"
            +            
            +                data-en='Koch Curve
            '
            +            
            +                data-es='Curva Koch
            '
            +            
            +                data-hi='कोच कर्व
            '
            +            
            +                data-ko='코흐 곡선
            '
            +            
            +                data-zh-Hans='Koch Curve
            '
            +            
            +          >Koch Curve
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-bubble-sort
            .html"
            +            
            +                data-en='Bubble Sort
            '
            +            
            +                data-es='Ordenamiento de Burbuja
            '
            +            
            +                data-hi='बबल सॉर्ट
            '
            +            
            +                data-ko='버블 정렬
            '
            +            
            +                data-zh-Hans='Bubble Sort
            '
            +            
            +          >Bubble Sort
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-stepping-feet-illusion
            .html"
            +            
            +                data-en='Stepping Feet Illusion
            '
            +            
            +                data-es='Ilusión de los Pasos
            '
            +            
            +                data-hi='स्टेपिंग फीट इल्यूजन
            '
            +            
            +                data-ko='걷는발 착시효과
            '
            +            
            +                data-zh-Hans='Stepping Feet Illusion
            '
            +            
            +          >Stepping Feet Illusion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particles
            .html"
            +            
            +                data-en='Particles
            '
            +            
            +                data-es='Partículas
            '
            +            
            +                data-hi='कण
            '
            +            
            +                data-ko='파티클
            '
            +            
            +                data-zh-Hans='Particles
            '
            +            
            +          >Particles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-quicksort
            .html"
            +            
            +                data-en='Quicksort
            '
            +            
            +                data-es='Quicksort
            '
            +            
            +                data-ko='Quicksort
            '
            +            
            +                data-zh-Hans='Quicksort
            '
            +            
            +          >Quicksort
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='interaction' class='anchor'>इंटरेक्शन</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="interaction-tickle
            .html"
            +            
            +                data-en='Tickle
            '
            +            
            +                data-es='Cosquillas
            '
            +            
            +                data-hi='टिकल 
            '
            +            
            +                data-ko='간질간질
            '
            +            
            +                data-zh-Hans='Tickle
            '
            +            
            +          >Tickle
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-weight-line
            .html"
            +            
            +                data-en='Weight Line
            '
            +            
            +                data-es='Weight Line
            '
            +            
            +                data-hi='फॉलो 1
            '
            +            
            +                data-ko='Weight Line
            '
            +            
            +                data-zh-Hans='Weight Line
            '
            +            
            +          >Weight Line
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-1
            .html"
            +            
            +                data-en='Follow 1
            '
            +            
            +                data-es='Seguir 1
            '
            +            
            +                data-hi='फॉलो 2
            '
            +            
            +                data-ko='따라다니기 1
            '
            +            
            +                data-zh-Hans='跟随 1
            '
            +            
            +          >Follow 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-2
            .html"
            +            
            +                data-en='Follow 2
            '
            +            
            +                data-es='Seguir 2
            '
            +            
            +                data-hi='फॉलो 3
            '
            +            
            +                data-ko='따라다니기 2
            '
            +            
            +                data-zh-Hans='跟随 2
            '
            +            
            +          >Follow 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-3
            .html"
            +            
            +                data-en='Follow 3
            '
            +            
            +                data-es='Seguir 3
            '
            +            
            +                data-hi='सांप का खेल
            '
            +            
            +                data-ko='따라다니기 3
            '
            +            
            +                data-zh-Hans='跟随 3
            '
            +            
            +          >Follow 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-snake-game
            .html"
            +            
            +                data-en='Snake game
            '
            +            
            +                data-es='Juego de Serpiente
            '
            +            
            +                data-hi='वेवमेकर
            '
            +            
            +                data-ko='스네이크 게임
            '
            +            
            +                data-zh-Hans='贪吃蛇
            '
            +            
            +          >Snake game
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-wavemaker
            .html"
            +            
            +                data-en='Wavemaker
            '
            +            
            +                data-es='Wavemaker
            '
            +            
            +                data-hi='रीच 1
            '
            +            
            +                data-ko='파도 만들기
            '
            +            
            +                data-zh-Hans='造波器
            '
            +            
            +          >Wavemaker
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-1
            .html"
            +            
            +                data-en='Reach 1
            '
            +            
            +                data-es='Alcanzar 1
            '
            +            
            +                data-hi='रीच 2
            '
            +            
            +                data-ko='팔닿기 1
            '
            +            
            +                data-zh-Hans='延伸 1
            '
            +            
            +          >Reach 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-2
            .html"
            +            
            +                data-en='Reach 2
            '
            +            
            +                data-es='Alcanzar 2
            '
            +            
            +                data-hi='पहुंच ३
            '
            +            
            +                data-ko='팔닿기 2
            '
            +            
            +                data-zh-Hans='延伸 2
            '
            +            
            +          >Reach 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-3
            .html"
            +            
            +                data-en='Reach 3
            '
            +            
            +                data-es='Alcanzar 3
            '
            +            
            +                data-hi='Arduino सेंसर डेटा WebJack के माध्यम से
            '
            +            
            +                data-ko='팔닿기 3
            '
            +            
            +                data-zh-Hans='延伸 3
            '
            +            
            +          >Reach 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-arduino-sensor-data-via-webjack
            .html"
            +            
            +                data-en='Arduino sensor data via WebJack
            '
            +            
            +                data-es='Datos de un sensor Arduino vía WebJack
            '
            +            
            +                data-hi='बहुरूपदर्शक
            '
            +            
            +                data-ko='웹잭과 아두이노 센서 데이터
            '
            +            
            +                data-zh-Hans='通过 WebJack 读取 Arduino 传感器数据
            '
            +            
            +          >Arduino sensor data via WebJack
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-kaleidoscope
            .html"
            +            
            +                data-en='Kaleidoscope
            '
            +            
            +                data-es='Caleidoscopio
            '
            +            
            +                data-ko='만화경
            '
            +            
            +                data-zh-Hans='万花筒
            '
            +            
            +          >Kaleidoscope
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='objects' class='anchor'>वस्तुओं</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="objects-objects
            .html"
            +            
            +                data-en='Objects
            '
            +            
            +                data-es='Objetos
            '
            +            
            +                data-hi='वस्तु
            '
            +            
            +                data-ko='객체
            '
            +            
            +                data-zh-Hans='物件 (Objects)
            '
            +            
            +          >Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-multiple-objects
            .html"
            +            
            +                data-en='Multiple Objects
            '
            +            
            +                data-es='Múltiples objetos
            '
            +            
            +                data-hi='वस्तुओं का नाम दें
            '
            +            
            +                data-ko='복수 객체
            '
            +            
            +                data-zh-Hans='多个物件
            '
            +            
            +          >Multiple Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-array-of-objects
            .html"
            +            
            +                data-en='Array of Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='वस्तुओं की सरणी
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='物件数组
            '
            +            
            +          >Array of Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-objects-2
            .html"
            +            
            +                data-en='Objects 2
            '
            +            
            +                data-es='Objetos 2
            '
            +            
            +                data-hi='वस्तु 2
            '
            +            
            +                data-ko='객체 2
            '
            +            
            +                data-zh-Hans='物件 2
            '
            +            
            +          >Objects 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-inheritance
            .html"
            +            
            +                data-en='Inheritance
            '
            +            
            +                data-es='Herencia
            '
            +            
            +                data-hi='वंशानुक्रम
            '
            +            
            +                data-ko='상속
            '
            +            
            +                data-zh-Hans='继承 (Inheritance)
            '
            +            
            +          >Inheritance
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-composite-objects
            .html"
            +            
            +                data-en='Composite Objects
            '
            +            
            +                data-es='Objetos Compuestos
            '
            +            
            +                data-hi='समग्र वस्तु
            '
            +            
            +                data-ko='합성 객체
            '
            +            
            +                data-zh-Hans='复合物件
            '
            +            
            +          >Composite Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-car-instances
            .html"
            +            
            +                data-en='Car Instances
            '
            +            
            +                data-es='Car Instances
            '
            +            
            +                data-ko='Car Instances
            '
            +            
            +                data-zh-Hans='Car Instances
            '
            +            
            +          >Car Instances
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='lights' class='anchor'>रोशनी</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="lights-directional
            .html"
            +            
            +                data-en='Directional
            '
            +            
            +                data-es='Direccional
            '
            +            
            +                data-hi='दिशात्मक
            '
            +            
            +                data-ko='디렉셔널 라이트
            '
            +            
            +                data-zh-Hans='定向光
            '
            +            
            +          >Directional
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="lights-mixture
            .html"
            +            
            +                data-en='Mixture
            '
            +            
            +                data-es='Mezcla
            '
            +            
            +                data-hi='मिश्रण
            '
            +            
            +                data-ko='혼합 라이트
            '
            +            
            +                data-zh-Hans='混合光
            '
            +            
            +          >Mixture
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='motion' class='anchor'>गति</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="motion-non-orthogonal-reflection
            .html"
            +            
            +                data-en='Non Orthogonal Reflection
            '
            +            
            +                data-es='Reflejo no ortogonal
            '
            +            
            +                data-hi='नॉन ऑर्थोगोनल रिफ्लेक्शन
            '
            +            
            +                data-ko='비직각 반사
            '
            +            
            +                data-zh-Hans='Non Orthogonal Reflection
            '
            +            
            +          >Non Orthogonal Reflection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-linear
            .html"
            +            
            +                data-en='Linear
            '
            +            
            +                data-es='Lineal
            '
            +            
            +                data-hi='रैखिक
            '
            +            
            +                data-ko='선형
            '
            +            
            +                data-zh-Hans='Linear
            '
            +            
            +          >Linear
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bounce
            .html"
            +            
            +                data-en='Bounce
            '
            +            
            +                data-es='Rebote
            '
            +            
            +                data-hi='उछाल
            '
            +            
            +                data-ko='바운스
            '
            +            
            +                data-zh-Hans='Bounce
            '
            +            
            +          >Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bouncy-bubbles
            .html"
            +            
            +                data-en='Bouncy Bubbles
            '
            +            
            +                data-es='Burbujas Saltarinas
            '
            +            
            +                data-hi='उछाल वाले बुलबुले
            '
            +            
            +                data-ko='버블 바운스
            '
            +            
            +                data-zh-Hans='Bouncy Bubbles
            '
            +            
            +          >Bouncy Bubbles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Transformar
            '
            +            
            +                data-hi='मॉर्फ
            '
            +            
            +                data-ko='변형(morph)
            '
            +            
            +                data-zh-Hans='Morph
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-morph
            .html"
            +            
            +                data-en='Morph
            '
            +            
            +                data-es='Moviéndose por Curvas
            '
            +            
            +                data-hi='मूविंग ऑन कर्व्स
            '
            +            
            +                data-ko='곡선 위 움직이기
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Morph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-circle-collision
            .html"
            +            
            +                data-en='Circle Collision
            '
            +            
            +                data-es='Circle Collision
            '
            +            
            +                data-ko='Circle Collision
            '
            +            
            +                data-zh-Hans='Circle Collision
            '
            +            
            +          >Circle Collision
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-moving-on-curves
            .html"
            +            
            +                data-en='Moving On Curves
            '
            +            
            +                data-es='Moving On Curves
            '
            +            
            +                data-ko='Moving On Curves
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Moving On Curves
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='instance_mode' class='anchor'>उदाहरण मोड</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="instance-mode-instantiation
            .html"
            +            
            +                data-en='Instantiation
            '
            +            
            +                data-es='Instaciación
            '
            +            
            +                data-hi='इंस्टेंटेशन
            '
            +            
            +                data-ko='인스턴스화
            '
            +            
            +                data-zh-Hans='创建实例
            '
            +            
            +          >Instantiation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="instance-mode-instance-container
            .html"
            +            
            +                data-en='Instance Container
            '
            +            
            +                data-es='Contenedor de instancia
            '
            +            
            +                data-hi='इंस्टेंस कंटेनर
            '
            +            
            +                data-ko='인스턴스 컨테이너
            '
            +            
            +                data-zh-Hans='实例容器
            '
            +            
            +          >Instance Container
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='dom' class='anchor'>DOM</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="dom-input-and-button
            .html"
            +            
            +                data-en='Input/Button
            '
            +            
            +                data-es='Entrada y botón
            '
            +            
            +                data-hi='इनपुट और बटन
            '
            +            
            +                data-ko='입력과 버튼
            '
            +            
            +                data-zh-Hans='Input and Button
            '
            +            
            +          >Input/Button
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-slider
            .html"
            +            
            +                data-en='Slider
            '
            +            
            +                data-es='Barra deslizante
            '
            +            
            +                data-hi='स्लाइडर
            '
            +            
            +                data-ko='슬라이더
            '
            +            
            +                data-zh-Hans='Slider
            '
            +            
            +          >Slider
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-modifying-the-dom
            .html"
            +            
            +                data-en='Modifying the DOM
            '
            +            
            +                data-es='Modificar el DOM
            '
            +            
            +                data-hi='डोम को संशोधित करना
            '
            +            
            +                data-ko='DOM 변경
            '
            +            
            +                data-zh-Hans='Modifying the DOM
            '
            +            
            +          >Modifying the DOM
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video
            .html"
            +            
            +                data-en='Video
            '
            +            
            +                data-es='Video
            '
            +            
            +                data-hi='वीडियो
            '
            +            
            +                data-ko='비디오
            '
            +            
            +                data-zh-Hans='Video
            '
            +            
            +          >Video
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-canvas
            .html"
            +            
            +                data-en='Video Canvas
            '
            +            
            +                data-es='Lienzo y video
            '
            +            
            +                data-hi='वीडियो कैनवास
            '
            +            
            +                data-ko='비디오 캔버스
            '
            +            
            +                data-zh-Hans='Video Canvas
            '
            +            
            +          >Video Canvas
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-pixels
            .html"
            +            
            +                data-en='Video Pixels
            '
            +            
            +                data-es='Pixeles de video
            '
            +            
            +                data-hi='वीडियो पिक्सल
            '
            +            
            +                data-ko='비디오 픽셀
            '
            +            
            +                data-zh-Hans='Video Pixels
            '
            +            
            +          >Video Pixels
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-capture
            .html"
            +            
            +                data-en='Video Capture
            '
            +            
            +                data-es='Captura de video
            '
            +            
            +                data-hi='वीडियो कैप्चर
            '
            +            
            +                data-ko='실시간 비디오
            '
            +            
            +                data-zh-Hans='Video Capture
            '
            +            
            +          >Video Capture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-drop
            .html"
            +            
            +                data-en='Drop
            '
            +            
            +                data-es='Arrojar
            '
            +            
            +                data-hi='छोड़ देना
            '
            +            
            +                data-ko='드롭 기능
            '
            +            
            +                data-zh-Hans='Drop
            '
            +            
            +          >Drop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-dom-form-elements
            .html"
            +            
            +                data-en='DOM Form Elements
            '
            +            
            +                data-es='DOM Form Elements
            '
            +            
            +                data-ko='DOM Form Elements
            '
            +            
            +                data-zh-Hans='DOM Form Elements
            '
            +            
            +          >DOM Form Elements
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='drawing' class='anchor'>चित्रकारी</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="drawing-continuous-lines
            .html"
            +            
            +                data-en='Continuous Lines
            '
            +            
            +                data-es='Líneas continuas
            '
            +            
            +                data-hi='सतत रेखा 
            '
            +            
            +                data-ko='연속된 선
            '
            +            
            +                data-zh-Hans='Líneas continuas
            '
            +            
            +          >Continuous Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-patterns
            .html"
            +            
            +                data-en='Patterns
            '
            +            
            +                data-es='Patrones
            '
            +            
            +                data-hi='पैटर्न
            '
            +            
            +                data-ko='패턴
            '
            +            
            +                data-zh-Hans='Patrones
            '
            +            
            +          >Patterns
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-pulses
            .html"
            +            
            +                data-en='Pulses
            '
            +            
            +                data-es='Pulsos
            '
            +            
            +                data-hi='दालें
            '
            +            
            +                data-ko='율동
            '
            +            
            +                data-zh-Hans='Pulsos
            '
            +            
            +          >Pulses
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='transform' class='anchor'>परिवर्तन</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="transform-translate
            .html"
            +            
            +                data-en='Translate
            '
            +            
            +                data-es='Translate
            '
            +            
            +                data-hi='अनुवाद
            '
            +            
            +                data-ko='위치 이동(Translate)
            '
            +            
            +                data-zh-Hans='Translate
            '
            +            
            +          >Translate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-scale
            .html"
            +            
            +                data-en='Scale
            '
            +            
            +                data-es='Escalar
            '
            +            
            +                data-hi='स्केल
            '
            +            
            +                data-ko='크기 조정(Scale)
            '
            +            
            +                data-zh-Hans='Scale
            '
            +            
            +          >Scale
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-rotate
            .html"
            +            
            +                data-en='Rotate
            '
            +            
            +                data-es='Rotate
            '
            +            
            +                data-hi='घुमाएँ
            '
            +            
            +                data-ko='회전(Rotate)
            '
            +            
            +                data-zh-Hans='Rotate
            '
            +            
            +          >Rotate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-arm
            .html"
            +            
            +                data-en='Arm
            '
            +            
            +                data-es='Brazo
            '
            +            
            +                data-hi='आर्म
            '
            +            
            +                data-ko='팔모양
            '
            +            
            +                data-zh-Hans='Arm
            '
            +            
            +          >Arm
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_2 column">
            +        
            +      
            +        <h3 name='typography' class='anchor'>टाइपोग्राफी</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="typography-letters
            .html"
            +            
            +                data-en='Letters
            '
            +            
            +                data-es='Letters
            '
            +            
            +                data-hi='पत्र
            '
            +            
            +                data-ko='글자
            '
            +            
            +                data-zh-Hans='Letters
            '
            +            
            +          >Letters
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-words
            .html"
            +            
            +                data-en='Words
            '
            +            
            +                data-es='Words
            '
            +            
            +                data-hi='शब्द
            '
            +            
            +                data-ko='단어
            '
            +            
            +                data-zh-Hans='Words
            '
            +            
            +          >Words
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-text-rotation
            .html"
            +            
            +                data-en='Text Rotation
            '
            +            
            +                data-es='Text Rotation
            '
            +            
            +                data-ko='텍스트 회전
            '
            +            
            +                data-zh-Hans='Text Rotation
            '
            +            
            +          >Text Rotation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='3d' class='anchor'>3 डी</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="3d-geometries
            .html"
            +            
            +                data-en='Geometries
            '
            +            
            +                data-es='Geometrías
            '
            +            
            +                data-hi='ज्यामिति
            '
            +            
            +                data-ko='기하
            '
            +            
            +                data-zh-Hans='Geometries
            '
            +            
            +          >Geometries
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-sine-cosine-in-3d
            .html"
            +            
            +                data-en='Sine Cosine in 3D
            '
            +            
            +                data-es='Seno Coseno en 3D
            '
            +            
            +                data-hi='3D में साइन कोसाइन
            '
            +            
            +                data-ko='3D속 사인 코사인
            '
            +            
            +                data-zh-Hans='Sine Cosine in 3D
            '
            +            
            +          >Sine Cosine in 3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-multiple-lights
            .html"
            +            
            +                data-en='Multiple Lights
            '
            +            
            +                data-es='Múltiples luces
            '
            +            
            +                data-hi='मल्टीपल लाइट्स
            '
            +            
            +                data-ko='복수의 조명들
            '
            +            
            +                data-zh-Hans='Multiple Lights
            '
            +            
            +          >Multiple Lights
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-materials
            .html"
            +            
            +                data-en='Materials
            '
            +            
            +                data-es='Materiales
            '
            +            
            +                data-hi='सामग्री
            '
            +            
            +                data-ko='재질(Materials)
            '
            +            
            +                data-zh-Hans='Materials
            '
            +            
            +          >Materials
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-textures
            .html"
            +            
            +                data-en='Textures
            '
            +            
            +                data-es='Texturas
            '
            +            
            +                data-hi='बनावट
            '
            +            
            +                data-ko='텍스처
            '
            +            
            +                data-zh-Hans='Textures
            '
            +            
            +          >Textures
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-ray-casting
            .html"
            +            
            +                data-en='Ray Casting
            '
            +            
            +                data-es='Ray Casting
            '
            +            
            +                data-hi='रे कास्टिंग
            '
            +            
            +                data-ko='레이 캐스팅
            '
            +            
            +                data-zh-Hans='Ray Casting
            '
            +            
            +          >Ray Casting
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-orbit-control
            .html"
            +            
            +                data-en='Orbit Control
            '
            +            
            +                data-es='Control de órbita
            '
            +            
            +                data-hi='कक्षा नियंत्रण
            '
            +            
            +                data-ko='궤도 제어
            '
            +            
            +                data-zh-Hans='Orbit Control
            '
            +            
            +          >Orbit Control
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-basic-shader
            .html"
            +            
            +                data-en='Basic Shader
            '
            +            
            +                data-es='Basic Shader
            '
            +            
            +                data-hi='बेसिक शेडर
            '
            +            
            +                data-ko='셰이더 기초
            '
            +            
            +                data-zh-Hans='Basic Shader
            '
            +            
            +          >Basic Shader
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-as-a-texture
            .html"
            +            
            +                data-en='Shader as a Texture
            '
            +            
            +                data-es='Shader as a Texture
            '
            +            
            +                data-hi='शेडर एक बनावट के रूप में
            '
            +            
            +                data-ko='셰이더로 텍스처 만들기
            '
            +            
            +                data-zh-Hans='Shader as a Texture
            '
            +            
            +          >Shader as a Texture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-passing-shader-uniforms
            .html"
            +            
            +                data-en='Passing Shader Uniforms
            '
            +            
            +                data-es='Passing Shader Uniforms
            '
            +            
            +                data-hi='पासिंग शेडर यूनिफॉर्म
            '
            +            
            +                data-ko='셰이더 유니폼
            '
            +            
            +                data-zh-Hans='Passing Shader Uniforms
            '
            +            
            +          >Passing Shader Uniforms
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-using-webcam
            .html"
            +            
            +                data-en='Shader Using Webcam
            '
            +            
            +                data-es='Shader Using Webcam
            '
            +            
            +                data-hi='Shader वेबकैम का उपयोग कर रहा है
            '
            +            
            +                data-ko='웹캠을 사용한 셰이더
            '
            +            
            +                data-zh-Hans='Shader Using Webcam
            '
            +            
            +          >Shader Using Webcam
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='input' class='anchor'>इनपुट</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="input-clock
            .html"
            +            
            +                data-en='Clock
            '
            +            
            +                data-es='Clock
            '
            +            
            +                data-hi='घड़ी
            '
            +            
            +                data-ko='시계
            '
            +            
            +                data-zh-Hans='Clock
            '
            +            
            +          >Clock
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-constrain
            .html"
            +            
            +                data-en='Constrain
            '
            +            
            +                data-es='Constrain
            '
            +            
            +                data-hi='बाधा
            '
            +            
            +                data-ko='제한
            '
            +            
            +                data-zh-Hans='Constrain
            '
            +            
            +          >Constrain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-easing
            .html"
            +            
            +                data-en='Easing
            '
            +            
            +                data-es='Easing
            '
            +            
            +                data-hi='आसान
            '
            +            
            +                data-ko='이징(Easing)
            '
            +            
            +                data-zh-Hans='Easing
            '
            +            
            +          >Easing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-keyboard
            .html"
            +            
            +                data-en='Keyboard
            '
            +            
            +                data-es='Keyboard
            '
            +            
            +                data-hi='कीबोर्ड
            '
            +            
            +                data-ko='키보드
            '
            +            
            +                data-zh-Hans='Keyboard
            '
            +            
            +          >Keyboard
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-milliseconds
            .html"
            +            
            +                data-en='Milliseconds
            '
            +            
            +                data-es='Mouse 1D
            '
            +            
            +                data-hi='माउस 1D
            '
            +            
            +                data-ko='1D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 1D
            '
            +            
            +          >Milliseconds
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-1d
            .html"
            +            
            +                data-en='Mouse 1D
            '
            +            
            +                data-es='Mouse 2D
            '
            +            
            +                data-hi='माउस 2D
            '
            +            
            +                data-ko='2D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 2D
            '
            +            
            +          >Mouse 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-2d
            .html"
            +            
            +                data-en='Mouse 2D
            '
            +            
            +                data-es='Mouse Press
            '
            +            
            +                data-hi='माउस प्रेस
            '
            +            
            +                data-ko='마우스 버튼
            '
            +            
            +                data-zh-Hans='Mouse Press
            '
            +            
            +          >Mouse 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-functions
            .html"
            +            
            +                data-en='Mouse Functions
            '
            +            
            +                data-es='Mouse Functions
            '
            +            
            +                data-hi='माउस फंक्शन्स
            '
            +            
            +                data-ko='마우스 함수
            '
            +            
            +                data-zh-Hans='Mouse Functions
            '
            +            
            +          >Mouse Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-signals
            .html"
            +            
            +                data-en='Mouse Signals
            '
            +            
            +                data-es='Mouse Signals
            '
            +            
            +                data-hi='माउस सिग्नल
            '
            +            
            +                data-ko='마우스 신호
            '
            +            
            +                data-zh-Hans='Mouse Signals
            '
            +            
            +          >Mouse Signals
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-press
            .html"
            +            
            +                data-en='Mouse Press
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-hi='भंडारण इनपुट
            '
            +            
            +                data-ko='입력값 저장
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Mouse Press
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-rollover
            .html"
            +            
            +                data-en='Rollover
            '
            +            
            +                data-es='Rollover
            '
            +            
            +                data-ko='롤오버 (Rollover)
            '
            +            
            +                data-zh-Hans='Rollover
            '
            +            
            +          >Rollover
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-storing-input
            .html"
            +            
            +                data-en='Storing Input
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-ko='Storing Input
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Storing Input
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='advanced_data' class='anchor'>उन्नत डेटा</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-json
            .html"
            +            
            +                data-en='Load Saved JSON
            '
            +            
            +                data-es='Load Saved JSON
            '
            +            
            +                data-hi='लोड सेव किया गया JSON
            '
            +            
            +                data-ko='저장된 JSON 불러오기
            '
            +            
            +                data-zh-Hans='Load Saved JSON
            '
            +            
            +          >Load Saved JSON
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-table
            .html"
            +            
            +                data-en='Load Saved Table
            '
            +            
            +                data-es='Load Saved Table
            '
            +            
            +                data-ko='Load Saved Table
            '
            +            
            +                data-zh-Hans='Load Saved Table
            '
            +            
            +          >Load Saved Table
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='sound' class='anchor'>ध्वनि</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="sound-load-and-play-sound
            .html"
            +            
            +                data-en='Load/Play Sound
            '
            +            
            +                data-es='Cargar y reproducir sonido
            '
            +            
            +                data-hi='लोड और प्ले साउंड
            '
            +            
            +                data-ko='사운드 불러오기/재생
            '
            +            
            +                data-zh-Hans='Load and Play Sound
            '
            +            
            +          >Load/Play Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-preload-soundfile
            .html"
            +            
            +                data-en='Preload SoundFile
            '
            +            
            +                data-es='Precargar archivo de sonido
            '
            +            
            +                data-hi='प्रीलोड साउंडफाइल
            '
            +            
            +                data-ko='사운드 파일 미리 불러오기
            '
            +            
            +                data-zh-Hans='Preload SoundFile
            '
            +            
            +          >Preload SoundFile
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-soundformats
            .html"
            +            
            +                data-en='soundFormats
            '
            +            
            +                data-es='Formatos de sonido
            '
            +            
            +                data-hi='ध्वनि प्रारूप
            '
            +            
            +                data-ko='사운드 파일 형식
            '
            +            
            +                data-zh-Hans='soundFormats
            '
            +            
            +          >soundFormats
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-play-mode
            .html"
            +            
            +                data-en='Play Mode
            '
            +            
            +                data-es='Modo de reproducción
            '
            +            
            +                data-hi='प्ले मोड
            '
            +            
            +                data-ko='재생 모드
            '
            +            
            +                data-zh-Hans='Play Mode
            '
            +            
            +          >Play Mode
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-pan-sound
            .html"
            +            
            +                data-en='Pan Sound
            '
            +            
            +                data-es='Paneo
            '
            +            
            +                data-hi='पैन साउंड
            '
            +            
            +                data-ko='사운드 패닝
            '
            +            
            +                data-zh-Hans='Pan Sound
            '
            +            
            +          >Pan Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-sound-effect
            .html"
            +            
            +                data-en='Sound Effect
            '
            +            
            +                data-es='Efecto de sonido
            '
            +            
            +                data-hi='ध्वनि प्रभाव
            '
            +            
            +                data-ko='사운드 효과
            '
            +            
            +                data-zh-Hans='Sound Effect
            '
            +            
            +          >Sound Effect
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-playback-rate
            .html"
            +            
            +                data-en='Playback Rate
            '
            +            
            +                data-es='Tasa de reproducción
            '
            +            
            +                data-hi='प्लेबैक दर
            '
            +            
            +                data-ko='재생 속도
            '
            +            
            +                data-zh-Hans='Playback Rate
            '
            +            
            +          >Playback Rate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-measuring-amplitude
            .html"
            +            
            +                data-en='Measuring Amplitude
            '
            +            
            +                data-es=' Midiendo la amplitud
            '
            +            
            +                data-hi='मापने वाला आयाम
            '
            +            
            +                data-ko='진폭 측정
            '
            +            
            +                data-zh-Hans='Measuring Amplitude
            '
            +            
            +          >Measuring Amplitude
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-noise-drum-envelope
            .html"
            +            
            +                data-en='Noise Drum Envelope
            '
            +            
            +                data-es='Tambor con envolvente y ruido
            '
            +            
            +                data-hi='शोर ड्रम लिफाफा
            '
            +            
            +                data-ko='노이즈 드럼 엔벨로프
            '
            +            
            +                data-zh-Hans='Noise Drum Envelope
            '
            +            
            +          >Noise Drum Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-note-envelope
            .html"
            +            
            +                data-en='Note Envelope
            '
            +            
            +                data-es=' Envolvente de nota
            '
            +            
            +                data-hi='नोट लिफाफा
            '
            +            
            +                data-ko='음계 엔벨로프
            '
            +            
            +                data-zh-Hans='Note Envelope
            '
            +            
            +          >Note Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-oscillator-frequency
            .html"
            +            
            +                data-en='Oscillator Frequency
            '
            +            
            +                data-es='Frecuencia de oscilador
            '
            +            
            +                data-hi='थरथरानवाला आवृत्ति
            '
            +            
            +                data-ko='오실레이터 주파수
            '
            +            
            +                data-zh-Hans='Oscillator Frequency
            '
            +            
            +          >Oscillator Frequency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-input
            .html"
            +            
            +                data-en='Mic Input
            '
            +            
            +                data-es='Entrada de micrófono
            '
            +            
            +                data-hi='Mic Input
            '
            +            
            +                data-ko='마이크 입력
            '
            +            
            +                data-zh-Hans='Mic Input
            '
            +            
            +          >Mic Input
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-spectrum
            .html"
            +            
            +                data-en='Frequency Spectrum
            '
            +            
            +                data-es='Espectro de frecuencia
            '
            +            
            +                data-hi='फ्रीक्वेंसी स्पेक्ट्रम Spec
            '
            +            
            +                data-ko='주파수 스펙트럼
            '
            +            
            +                data-zh-Hans='Frequency Spectrum
            '
            +            
            +          >Frequency Spectrum
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-threshold
            .html"
            +            
            +                data-en='Mic Threshold
            '
            +            
            +                data-es='Umbral de micrófono
            '
            +            
            +                data-hi='माइक थ्रेशोल्ड
            '
            +            
            +                data-ko='마이크 임계값
            '
            +            
            +                data-zh-Hans='Mic Threshold
            '
            +            
            +          >Mic Threshold
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-lowpass
            .html"
            +            
            +                data-en='Filter LowPass
            '
            +            
            +                data-es=' Filtro pasabajos
            '
            +            
            +                data-hi='फ़िल्टर लोपास
            '
            +            
            +                data-ko='로우패스 필터
            '
            +            
            +                data-zh-Hans='Filter LowPass
            '
            +            
            +          >Filter LowPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-bandpass
            .html"
            +            
            +                data-en='Filter BandPass
            '
            +            
            +                data-es=' Filtro pasabanda
            '
            +            
            +                data-hi='फ़िल्टर बैंडपास
            '
            +            
            +                data-ko='밴드패스 필터
            '
            +            
            +                data-zh-Hans='Filter BandPass
            '
            +            
            +          >Filter BandPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-delay
            .html"
            +            
            +                data-en='Delay
            '
            +            
            +                data-es=' Delay
            '
            +            
            +                data-hi='देरी
            '
            +            
            +                data-ko='딜레이 필터
            '
            +            
            +                data-zh-Hans='Delay
            '
            +            
            +          >Delay
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-reverb
            .html"
            +            
            +                data-en='Reverb
            '
            +            
            +                data-es=' Reverb
            '
            +            
            +                data-hi='रेवरब
            '
            +            
            +                data-ko='리버브
            '
            +            
            +                data-zh-Hans='Reverb
            '
            +            
            +          >Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-convolution-reverb
            .html"
            +            
            +                data-en='Convolution Reverb
            '
            +            
            +                data-es=' Reverb de convolución
            '
            +            
            +                data-hi='कनवल्शन रेवरब
            '
            +            
            +                data-ko='컨볼루션 리버브
            '
            +            
            +                data-zh-Hans='Convolution Reverb
            '
            +            
            +          >Convolution Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-record-save-audio
            .html"
            +            
            +                data-en='Record Save Audio
            '
            +            
            +                data-es=' Graba y almacena audio
            '
            +            
            +                data-hi='रिकॉर्ड ऑडियो सहेजें
            '
            +            
            +                data-ko='오디오 녹음/저장
            '
            +            
            +                data-zh-Hans='Record Save Audio
            '
            +            
            +          >Record Save Audio
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-modulation
            .html"
            +            
            +                data-en='Frequency Modulation
            '
            +            
            +                data-es='Modulación en frecuencia
            '
            +            
            +                data-hi='फ़्रीक्वेंसी मॉडुलन
            '
            +            
            +                data-ko='주파수 변조(FM)
            '
            +            
            +                data-zh-Hans='Frequency Modulation
            '
            +            
            +          >Frequency Modulation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-amplitude-modulation
            .html"
            +            
            +                data-en='Amplitude Modulation
            '
            +            
            +                data-es='Modulación en amplitud
            '
            +            
            +                data-hi='आयाम मॉडुलन
            '
            +            
            +                data-ko='진폭 변조(AM)
            '
            +            
            +                data-zh-Hans='Amplitude Modulation
            '
            +            
            +          >Amplitude Modulation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='mobile' class='anchor'>मोबाइल</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-ball-bounce
            .html"
            +            
            +                data-en='Acceleration Ball Bounce
            '
            +            
            +                data-es='Pelota rebote aceleración
            '
            +            
            +                data-hi='एक्सेलेरेशन बॉल बाउंस
            '
            +            
            +                data-ko='가속도와 바운스
            '
            +            
            +                data-zh-Hans='Acceleration Ball Bounce
            '
            +            
            +          >Acceleration Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-simple-draw
            .html"
            +            
            +                data-en='Simple Draw
            '
            +            
            +                data-es='Dibujo simple
            '
            +            
            +                data-hi='सिंपल ड्रा
            '
            +            
            +                data-ko='간단한 드로잉
            '
            +            
            +                data-zh-Hans='Simple Draw
            '
            +            
            +          >Simple Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-color
            .html"
            +            
            +                data-en='Acceleration Color
            '
            +            
            +                data-es='Aceleración y color
            '
            +            
            +                data-hi='त्वरण रंग
            '
            +            
            +                data-ko='가속도 색상
            '
            +            
            +                data-zh-Hans='Acceleration Color
            '
            +            
            +          >Acceleration Color
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-shake-ball-bounce
            .html"
            +            
            +                data-en='Shake Ball Bounce
            '
            +            
            +                data-es='Pelota rebote agitar
            '
            +            
            +                data-hi='शेक बॉल बाउंस
            '
            +            
            +                data-ko='흔들기와 바운스
            '
            +            
            +                data-zh-Hans='Shake Ball Bounce
            '
            +            
            +          >Shake Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-tilted-3d-box
            .html"
            +            
            +                data-en='Tilted 3D Box
            '
            +            
            +                data-es='Caja 3D
            '
            +            
            +                data-hi='झुका हुआ 3D बॉक्स
            '
            +            
            +                data-ko='기울어진 3D상자
            '
            +            
            +                data-zh-Hans='Tilted 3D Box
            '
            +            
            +          >Tilted 3D Box
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='hello_p5' class='anchor'>हैलो पी 5</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="hello-p5-simple-shapes
            .html"
            +            
            +                data-en='Simple Shapes
            '
            +            
            +                data-es='Figuras simples
            '
            +            
            +                data-hi='सरल आकार
            '
            +            
            +                data-ko='간단한 도형들
            '
            +            
            +                data-zh-Hans='Simple Shapes
            '
            +            
            +          >Simple Shapes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-1
            .html"
            +            
            +                data-en='Interactivity 1
            '
            +            
            +                data-es='Interactividad 1
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 1
            '
            +            
            +                data-ko='인터랙티비티 1
            '
            +            
            +                data-zh-Hans='Interactivity 1
            '
            +            
            +          >Interactivity 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-2
            .html"
            +            
            +                data-en='Interactivity 2
            '
            +            
            +                data-es='Interactividad 2
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 2
            '
            +            
            +                data-ko='인터랙티비티 2
            '
            +            
            +                data-zh-Hans='Interactivity 2
            '
            +            
            +          >Interactivity 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-animation
            .html"
            +            
            +                data-en='Animation
            '
            +            
            +                data-es='Animación
            '
            +            
            +                data-hi='एनिमेशन
            '
            +            
            +                data-ko='애니메이션
            '
            +            
            +                data-zh-Hans='Animation
            '
            +            
            +          >Animation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-weather
            .html"
            +            
            +                data-en='Weather
            '
            +            
            +                data-es='Clima
            '
            +            
            +                data-hi='मौसम
            '
            +            
            +                data-ko='날씨
            '
            +            
            +                data-zh-Hans='Weather
            '
            +            
            +          >Weather
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-drawing
            .html"
            +            
            +                data-en='Drawing
            '
            +            
            +                data-es='Dibujar
            '
            +            
            +                data-hi='ड्राइंग
            '
            +            
            +                data-ko='드로잉
            '
            +            
            +                data-zh-Hans='Drawing
            '
            +            
            +          >Drawing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-song
            .html"
            +            
            +                data-en='Song
            '
            +            
            +                data-es='Canción
            '
            +            
            +                data-hi='गीत
            '
            +            
            +                data-ko='노래
            '
            +            
            +                data-zh-Hans='Song
            '
            +            
            +          >Song
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +      </div>
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/get-started/index.html b/dist/hi/get-started/index.html
            new file mode 100644
            index 0000000000..850461e652
            --- /dev/null
            +++ b/dist/hi/get-started/index.html
            @@ -0,0 +1,343 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">get started | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="get-started-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>आरंभ करे</h1>
            +
            +      <p>यह पृष्ठ आपको एक p5.js प्रोजेक्ट सेट करने और आपका पहला स्केच बनाने के बारे में बताता है। शुरू करने का सबसे आसान तरीका <a href="https://editor.p5js.org" target="_blank">p5.js editor</a>, का उपयोग करना है आप वेब संपादक खोल सकते हैं और अपने <a href="#sketch">आपका पहला स्केच </a>तक नीचे स्क्रॉल कर सकते हैं। यदि आप p5.js के डेस्कटॉप संस्करण पर काम करना चाहते हैं तो आप नीचे स्क्रॉल कर सकते हैं <a href="#settingUp">निर्देश डाउनलोड</a>.
            +      </p>
            +
            +
            +
            +      <h2 class="start-element" id="sketch">आपका पहला स्केच</h2>
            +
            +      <div class="info">
            +        <h3 class="sr-only">अंडाकार के साथ कोड स्निपेट</h3>
            +        <p>In the<a href='https://editor.p5js.org/'>p5.js वेब संपादक</a>आपको निम्न कोड मिलना चाहिए:</p>
            +
            +<pre id="first-sketch1"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch1" class="copy_button">Copy</button>
            +        </div>
            +        <p>उपरांत<code class="language-javascript">background(220);</code>कोड की इस पंक्ति को शामिल करें: <code class="language-javascript">ellipse(50,50,80,80);</code>.</p>
            +
            +        <p>अब आपका कोड इस तरह होना चाहिए:</p>
            +        <h3 class="sr-only">अंडाकार के साथ कोड स्निपेट</h3>
            +
            +<pre id="first-sketch2"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +  ellipse(50,50,80,80);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch2" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">आपके द्वारा अभी जोड़ी गई रेखा एक दीर्घवृत्त खींचती है, जिसका केंद्र बाईं ओर से 50 पिक्सेल ऊपर और ऊपर से 50 पिक्सेल नीचे है, जिसकी चौड़ाई और ऊँचाई 80 पिक्सेल है।</p>
            +        <p>अपने कोड को क्रिया में प्रदर्शित करने के लिए संपादक पर प्ले दबाएं!</p>
            +        <h3 class="sr-only">स्क्रीनरीडर उपयोगकर्ताओं के लिए नोट</h3>
            +        <p>यदि आप एक स्क्रीन रीडर का उपयोग कर रहे हैं, तो आपको p5 ऑनलाइन संपादक में पहुंच योग्य आउटपुट को चालू करना होगा, संपादक के बाहर आपको अपने एचटीएमएल में एक्सेसिबिलिटी लाइब्रेरी को जोड़ना होगा। अधिक जानने के लिए &#32;<a href="../learn/p5-screen-reader.html" target="_blank">स्क्रीन रीडर ट्यूटोरियल के साथ p5 का उपयोग करना.</a>
            +        </p>
            +        <p>यदि आपने सब कुछ सही टाइप किया है, तो यह डिस्प्ले विंडो में दिखाई देगा:</p>
            +
            +        <img src="../../assets/img/get-started/first-sketch.png" alt='80 x और 80 y of की स्थिति में कैनवास की चौड़ाई और ऊंचाई 50 का एक वृत्त है'/>
            +
            +        <p>यदि कुछ दिखाई नहीं देता है, तो संपादक को यह समझने में समस्या हो सकती है कि आपने क्या लिखा है। यदि ऐसा होता है, तो सुनिश्चित करें कि आपने उदाहरण कोड को ठीक से कॉपी किया है: संख्याएं कोष्ठक के भीतर होनी चाहिए और उनमें से प्रत्येक के बीच अल्पविराम होना चाहिए, रेखा अर्धविराम के साथ समाप्त होनी चाहिए, और दीर्घवृत्त की वर्तनी सही होनी चाहिए।</p>
            +
            +        <p>प्रोग्रामिंग के साथ आरंभ करने के बारे में सबसे कठिन चीजों में से एक यह है कि आपको सिंटैक्स के बारे में बहुत विशिष्ट होना चाहिए। आपका मतलब जानने के लिए ब्राउज़र हमेशा पर्याप्त स्मार्ट नहीं होता है और विराम चिह्नों की नियुक्ति के बारे में काफी उधम मचा सकता है। थोड़े से अभ्यास से आपको इसकी आदत हो जाएगी। संपादक के नीचे बाईं ओर, आपको कंसोल अनुभाग मिलेगा। यहां, आप संपादक से प्राप्त होने वाली किसी भी त्रुटि के विवरण के साथ संदेश पा सकते हैं।</p>
            +
            +        <h3 class="sr-only">इंटरैक्शन के साथ कोड स्निपेट</h3>
            +        <p>इसके बाद, हम एक स्केच पर आगे बढ़ेंगे जो थोड़ा अधिक रोमांचक है। इसे आज़माने के लिए अंतिम उदाहरण को संशोधित करें:</p>
            +
            +<pre id="first-sketch3"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  if (mouseIsPressed) {
            +    fill(0);
            +  } else {
            +    fill(255);
            +  }
            +  ellipse(mouseX, mouseY, 80, 80);
            +}
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch3" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">यह प्रोग्राम एक कैनवास बनाता है जो 400 पिक्सेल चौड़ा और 400 पिक्सेल ऊँचा होता है, और फिर माउस की स्थिति में सफेद घेरे बनाना शुरू करता है। जब माउस बटन दबाया जाता है, तो वृत्त का रंग बदलकर काला हो जाता है। कोड चलाएँ, माउस ले जाएँ, और इसका अनुभव करने के लिए क्लिक करें।
            +        </p>
            +
            +        <img src="../../assets/img/get-started/first-sketch2.png" alt='कैनवास पर माउस के पथ का अनुसरण करते हुए कई वृत्त खींचे जाते हैं'/>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="next">आगे क्या?</h2>
            +
            +      <div class='info'>
            +        <ul class="list_view">
            +          <li>अधिक जनने के लिए <a href="../learn/">learn page</a> तथा <a href="../examples">examples page</a>देखें।</li>
            +
            +          <li>देखें <a href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6Zy51Q-x9tMWIv9cueOFTFA">The Coding Train</a> तथा  <a href="https://www.kadenze.com/courses/introduction-to-programming-for-the-visual-arts-with-p5-js/info">Kadenze</a> अनके वीडियो शिक्षण।</li>
            +
            +          <li>पूर्ण दस्तावेज़ीकरण के लिए<a href="../reference/"> reference</a> देखें।  </li>
            +          <li>यदि आप स्क्रीन रीडर के साथ p5 का उपयोग करना चाहते हैं, तो देखें <a href="../learn/p5-screen-reader.html">p5 with a screenreader tutorial</a>.</li>
            +          <li>यदि आपने पूर्व में प्रसंस्करण का उपयोग किया है, तो पढ़ें <a href='https://github.com/processing/p5.js/wiki/Processing-transition'>Processing transition tutorial</a> प्रोसेसिंग से p5.js में कनवर्ट करने का तरीका, और उनके बीच मुख्य अंतर जानने के लिए।</li>
            +
            +        </ul>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="settingUp">अपने कंप्यूटर पर एक संपादक के साथ p5.js सेट करना</h2>
            +
            +      <div class="info">
            +        <p>अपने कंप्यूटर में p5.js चलाने के लिए आपको एक टेक्स्ट एडिटर की आवश्यकता होगी। आप अपनी पसंद के
            +          <a href='http://en.wikipedia.org/wiki/Source_code_editor' target="_blank">
            +            कोड एडिटर</a>
            +            का उपयोग कर सकते हैं। Sublime Text 2 के साथ 
            +            <a href="http://www.sublimetext.com/2" target="_blank"> Sublime Text 2</a>
            +             सेटअप करने के निर्देश नीचे दिए गए हैं, अन्य अच्छे संपादक विकल्पों में <a href='http://brackets.io/' target=_blank>Brackets</a>  तथा <a href='https://atom.io/' target=_blank>Atom</a>. शामिल हैं। यदि आप एक स्क्रीन रीडर उपयोगकर्ता हैं और p5 वेब संपादक का उपयोग नहीं कर रहे हैं, तो आप इसका उपयोग करना चाह सकते हैं <a href="https://notepad-plus-plus.org/">Notepad++</a>  या 
            +            <a href="https://www.eclipse.org/ide/" target="_blank">Eclipse</a>.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="download">p5.js पुस्तकालय की एक प्रति डाउनलोड करना</h3>
            +
            +      <div class="info">
            +        <p>'शुरू करने का सबसे आसान तरीका खाली उदाहरण का उपयोग करना है जो' के साथ आता है।
            +          <a href="../download/">p5.js पूर्ण</a>
            +           download.
            +        </p>
            +
            +        <p>
            +           डाउनलोड करने के बाद, आपको एक स्थानीय सर्वर सेट करना होगा। निर्देश देखें 
            +          <a href="https://github.com/processing/p5.js/wiki/Local-server" target="_blank">यहां</a>
            +          '। अपने स्थानीय सर्वर को डाउनलोड किए गए फ़ोल्डर में चलाएँ और अपने ब्राउज़र पर, 'पर जाएँ
            +          <code>http://localhost:{your-port-num}/empty-example</code>
            +        </p>
            +
            +        <p>यदि आप index.html में देखते हैं, तो आप देखेंगे कि यह फ़ाइल p5.js से लिंक है। यदि आप छोटे संस्करण का उपयोग करना चाहते हैं (तेज़ पृष्ठ लोड करने के लिए संपीड़ित), तो लिंक को p5.min.js में बदलें।</p>
            +
            +        <pre id="markup1"><code class="language-markup">&lt;script src="../p5.min.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_script" class="copy_button">Copy</button>
            +        </div>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="hosted">p5.js लाइब्रेरी के होस्ट किए गए संस्करण का उपयोग करना</h3>
            +      <div class="info">
            +        <p>वैकल्पिक रूप से, आप ऑनलाइन होस्ट की गई p5.js फ़ाइल से लिंक कर सकते हैं। p5.js के सभी संस्करण एक सीडीएन (सामग्री वितरण नेटवर्क) में संग्रहीत हैं। आप इन संस्करणों का इतिहास में पा सकते हैं
            +          <a target="_blank" href="https://cdn.jsdelivr.net/npm/p5/lib/">
            +            p5.js CDN</a>। इस मामले में आप लिंक को इसमें बदल सकते हैं:
            +        </p>
            +
            +        <pre id="cdn-link" class='p5-replace'><code class="language-markup">&lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_link" class="copy_button">Copy</button>
            +        </div>
            +        <p>एक नमूना HTML पृष्ठ इस तरह दिख सकता है:</p>
            +
            +        <pre id="sample-html" class='p5-replace'><code class="language-markup">
            +&lt;html&gt;
            +  &lt;head&gt;
            +    &lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script&gt;
            +    &lt;script src="sketch.js">&lt;/script&gt;
            +  &lt;/head&gt;
            +  &lt;body&gt;
            +    &lt;main&gt;
            +    &lt;/main&gt;
            +  &lt;/body&gt;
            +&lt;/html&gt;
            +        </code></pre>
            +      <div class="edit_space">
            +          <button id="copy_p5_html" class="copy_button">Copy</button>
            +      </div>
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="environment">वातावरण</h3>
            +      <div class="info">
            +        <p>
            +          Sublime खोलें। फ़ाइल मेनू पर जाएँ और Open चुनें... और उस फ़ोल्डर को चुनें जिसमें आपकी html और js फ़ाइलें स्थित हैं। बाईं साइडबार पर, आपको फ़ोल्डर में निहित फ़ाइलों की सूची के साथ शीर्ष पर फ़ोल्डर का नाम मिलना चाहिए। 
            +        </p>
            +
            +        <p>
            +          अपनी sketch.js फ़ाइल पर क्लिक करें और यह दाईं ओर खुलेगी जहाँ आप इसे संपादित कर सकते हैं।
            +          <img src="../../assets/img/get-started/sublime2.png" alt='p5 स्टार्टर कोड उदात्त संपादक में खुला।"'/>
            +        </p>
            +
            +        <p>
            +          अपने ब्राउज़र में index.html फ़ाइल को अपने फ़ाइल प्रबंधक में डबल क्लिक करके खोलें या टाइप करें: <code>file:///the/file/path/to/your/html</code>
            +           (or  <code>http://localhost:{your-port-num}/empty-example</code>
            +          यदि आप स्थानीय सर्वर का उपयोग कर रहे हैं)
            +           अपना स्केच देखने के लिए एड्रेस बार में।
            +        </p>
            +      </div>
            +
            +      <div>इस ट्यूटोरियल के कुछ हिस्सों को लॉरेन मैकार्थी, केसी रियास, और बेन फ्राई, ओ'रेली / मेक 2015 द्वारा पुस्तक, गेटिंग स्टार्टिंग विद p5.js से अनुकूलित किया गया था। कॉपीराइट © 2015। सभी अधिकार सुरक्षित। अंतिम बार p5.js 2019 योगदानकर्ता सम्मेलन में संशोधित किया गया।</div>
            +
            +      <script>
            +        $.getJSON('../download/version.json', function(data) {
            +          $('.p5-replace').each(function() {
            +            var html = $(this).html().replace('[p5_version]', data.version);
            +            $(this).html(html);
            +          });
            +        });
            +      </script>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +</div><!-- end id="get-started-page"  -->
            +<script src="/../../assets/js/get-started.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/index.html b/dist/hi/index.html
            new file mode 100644
            index 0000000000..c3efc0ab90
            --- /dev/null
            +++ b/dist/hi/index.html
            @@ -0,0 +1,177 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">home | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<div id="home-page">
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content" class="home">
            +      <form id="search" method="get" action="https://www.google.com/search">
            +        <input type="hidden" name="as_sitesearch" value="p5js.org">
            +        <input id="search_button" type="submit" aria-label="Search" class='sr-only'>
            +        <input tabindex="2" id='search_field' type="text" size="20" placeholder="Search p5js.org" name="q">
            +        <label class="sr-only" for="search_field">Search p5js.org</label>
            +      </form>
            +
            +      <h1>नमस्ते!</h1>
            +      <p style="margin-top:1em">p5.js रचनात्मक कोडिंग के लिए एक जावास्क्रिप्ट लाइब्रेरी है, जिसमें कलाकारों, डिजाइनरों, शिक्षकों, शुरुआती लोगों के लिए कोडिंग को सुलभ और समावेशी बनाने पर ध्यान केंद्रित किया गया है। p5.js स्वतंत्र और खुला-स्रोत है क्योंकि हम सॉफ्टवेयर पर विश्वास करते हैं, और इसे सीखने के उपकरण सभी के लिए सुलभ होने चाहिए।</p>
            +      <p>एक स्केच के रूपक का उपयोग करते हुए, p5.js में ड्राइंग कार्यक्षमता का एक पूरा सेट है। हालाँकि, आप अपने ड्राइंग कैनवास तक सीमित नहीं हैं। आप अपने पूरे ब्राउज़र पृष्ठ को अपने स्केच के रूप में सोच सकते हैं, जिसमें टेक्स्ट, इनपुट, वीडियो, वेब कैमरा और ध्वनि के लिए HTML5 ऑब्जेक्ट शामिल हैं।</p>
            +      <p><a href="https://discord.gg/SHQ8dH25r9">Join the p5.js Discord!</a></p>
            +      <a href="https://editor.p5js.org"><span class='button_box'>P5 संपादक के साथ बनाना शुरू करें!</span></a>
            +
            +      <h2>समुदाय</h2>
            +      <p>हम हर लिंग पहचान और अभिव्यक्ति, यौन अभिविन्यास, जाति, जातीयता, भाषा, न्यूरो-प्रकार, आकार, क्षमता, वर्ग, धर्म, संस्कृति, उपसंस्कृति, राजनीतिक राय, आयु, कौशल, स्तर, व्यवसाय और पृष्ठभूमि के साथ और एकजुटता का एक समुदाय हैं। हम स्वीकार करते हैं कि सभी के पास सक्रिय रूप से भाग लेने के लिए समय, वित्तीय साधन या क्षमता नहीं है, लेकिन हम सभी प्रकार की भागीदारी को समझते हैं और प्रोत्साहित करते हैं। हम सुविधा और सशक्तिकरण को बढ़ावा देते हैं। हम सभी शिक्षार्थी हैं।</p>
            +      <p>p5.js आज के वेब के लिए <a href="https://processing.org"
            +          target="_blank">Processing</a> की व्याख्या है। हम ईवेंट का संचालन करते हैं और हमारे कार्य का समर्थन करता है <a href="https://processingfoundation.org"
            +          target="_blank">Processing Foundation</a>।</p>
            +      <p>हमारे <a href="community/">समुदाय </a>के बारे में अधिक जानें।</p>
            +
            +      <h2>शुरू करें</h2>
            +      <p> <a href="https://editor.p5js.org" target="_blank">p5.js
            +          Editor</a> में अपना पहला स्केच बनाएं। <a
            +          href="get-started/">आरंभ पृष्ठ</a> पर p5.js के साथ स्केचिंग के बारे में अधिक जानें और <a
            +          href="reference/">संदर्भ</a> में जाने आप जो कुछ भी कर सकते हैं।</p>
            +
            +      <h2>शामिल होइए</h2>
            +      <p>P5.js में योगदान करने के कई तरीके हैं:</p>
            +      <h2 id="involvement-options" class="sr-only">भागीदारी के विकल्प</h2>
            +      <ul aria-labelledby="involvement-options" class="list_view bullets">
            +        <li><a href="/hi/teach">एक कार्यशाला या कक्षा पढ़ाएं करें।</a></li>
            +        <li><a href="https://day.processing.org" target="_blank">सम्मलेन का आयोजन करें।</a></li>
            +        <li><a href="https://github.com/processing/p5.js/tree/main/contributor_docs"
            +            target="_blank">कोडबेस में योगदान करें।</a></li>
            +      </ul>
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +  </div> <!-- end column-span -->
            +
            +
            +  <p class="clearfix">&nbsp;</p>
            +
            +  <object tabindex=-1 type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element"
            +    aria-hidden="true">*</object>
            +</div> <!-- end home-page -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/basics.html b/dist/hi/learn/basics.html
            new file mode 100644
            index 0000000000..090f43d2c8
            --- /dev/null
            +++ b/dist/hi/learn/basics.html
            @@ -0,0 +1,348 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +<style>
            +img {
            +  width: 50%;
            +}
            +</style>
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Basics of Drawing</h1>
            +
            +      <h2>Introduction</h2>
            +      <p>
            +      Today we are going to be learning how to write computer code using a tool called <a href='http://p5js.org' target=_blank>p5</a>. Code is a set of instructions for the computer, telling it something to do. In our case, we will tell it to make a scene with shapes and colors.
            +      </p>
            +
            +
            +      <h2>First Sketch</h2>
            +      <p>
            +      When you open p5, your first sketch will look like this. There are two parts: setup and draw. Inside the curly brackets after setup and draw we will add code to create a drawing.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +
            +}
            +      </script>
            +
            +      <h2>background(red, green, blue)</h2>
            +      <p>
            +      background() sets the background color of your drawing. You give it three numbers that represent the amount of red, green, and blue you want mixed into the background. The numbers range from 0-255.
            +      <span class='try'>Try changing the numbers inside the parentheses to see what happens.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +
            +      <h2>createCanvas(width, height)</h2>
            +      <p>
            +      createCanvas() sets the size of the drawing canvas. By default it is 100x100. You give it two numbers that represent the width and the height that you want your canvas to be.
            +      <span class='try'>Try making your canvas different sizes by changing the width and height.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100)
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +      <h2>line(x1, y1, x2, y2)</h2>
            +      <p>
            +      line() draws a line on your canvas. You give it four numbers – the x and y position of one end, and the x and y position of the other end.<br>
            +      <img src='../../assets/learn/basics/line.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 200, 255)
            +  line(10, 10, 200, 200)
            +}
            +      </script>
            +
            +      <h2>rect(x, y, width, height)</h2>
            +      <p>
            +      rect() draws a rectangle on your canvas. You give it four numbers – the x position, the y position, the width, and the height. For a rectangle, you give it the x,y position of the top left corner.<br>
            +      <img src='../../assets/learn/basics/rect.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(55, 100, 255)
            +  rect(10, 10, 50, 200)
            +}
            +      </script>
            +
            +      <h2>ellipse(x, y, width, height)</h2>
            +      <p>
            +      To draw a shape, think of your canvas like a piece of graph paper. However, square (0, 0) is in the top left.
            +      <br>
            +      <img src='../../assets/learn/basics/graph.svg'>
            +      ellipse() draws an ellipse on your canvas. You give it four numbers – the x position, the y position, the width, and the height.<br>
            +      <img src='../../assets/learn/basics/ellipse.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 0, 255)
            +  ellipse(150, 150, 100, 200)
            +}
            +      </script>
            +
            +      <h2>fill(red, green, blue)</h2>
            +      <p>You can set the color of your shapes by using fill(). You give it three numbers – the red, green, and blue mixture you want, just like background.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>stroke(red, green, blue)</h2>
            +      <p>You can set the outline color of your shapes by using stroke(). You give it three numbers – the red, green, and blue mixture you want, just like fill() and background().
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  stroke(0, 150, 0)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>strokeWeight(weight)</h2>
            +      <p>You can set the thickness of the outline for your shapes by using strokeWeight(). The default stroke weight is 1.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  strokeWeight(10)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>mouseX, mouseY</h2>
            +      <p>mouseX and mouseY can be used to get the current position of your mouse. They are called <b>variables</b>. You can replace a number in your code with mouseX or mouseY and that number will change as you move your mouse.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +      <h2>random(max)</h2>
            +      <p>random() will choose a random number for you, anywhere from 0 - max.</p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(random(255), random(255), random(255))
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +
            +      <h2>Links</h2>
            +      <p><a href='http://p5js.org/reference' target=_blank>Reference</a> – available p5.js variables and functions<br>
            +      <a href='http://p5js.org/examples' target=_blank>Examples</a> – more complicated code examples</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/color.html b/dist/hi/learn/color.html
            new file mode 100644
            index 0000000000..3bcfda2c02
            --- /dev/null
            +++ b/dist/hi/learn/color.html
            @@ -0,0 +1,293 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">यह शिक्षण डैनियल शिफमैन की पुस्तक लर्निंग प्रोसेसिंग से है, जिसे मॉर्गन कॉफमैन द्वारा प्रकाशित किया गया था, © 2008 एल्सेवियर इंक। सभी अधिकार सुरक्षित। इसे केली चांग ने P5 में रखा था। यदि आप कोई त्रुटि देखते हैं या टिप्पणी करते हैं, <a href="https://github.com/processing/p5.js/issues"> तो कृपया हमें बताएं।</a>
            +
            +      </div>
            +
            +      <h1>रंग</h1>
            +
            +      <p>
            +      डिजिटल दुनिया में, जब हम किसी रंग के बारे में बात करना चाहते हैं, तो सटीकता की आवश्यकता होती है। "अरे, क्या आप उस सर्कल को हरा-हरा बना सकते हैं?" नहीं करूँगा। रंग, बल्कि, संख्याओं की एक सीमा के रूप में परिभाषित किया गया है। चलो सबसे सरल मामले से शुरू करते हैं: काले और सफेद या ग्रेस्केल। 0 का मतलब है काला, 255 का मतलब है सफेद। बीच में, हर दूसरे नंबर- 50, 87, 162, 209, और इसी तरह से ग्रे की एक छाया है जो काले से सफेद तक होती है।
            +      </p>
            +
            +      <img src="../../assets/learn/color/grayscale.svg">
            +
            +      <p>
            +      कुछ खींचने से पहले <a href="/hi/reference/#/p5/stroke"> stroke()</a> और <a href="/hi/reference/#/p5/fill">fill()</a>  कार्य करने से पहले, हम किसी भी दिए गए आकार का रंग निर्धारित कर सकते हैं.  ़ ंक्शन <a href="/hi/reference/#/p5/background">background()</a> भी है ,  ो खिड़की के लिए एक पृष्ठभूमि रंग सेट करता है। यहाँ एक उदाहरण है 
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        background(255);    // सफेद करने के लिए पृष्ठभूमि की स्थापना 
            + stroke(0);          // काला करने के लिए रूपरेखा (स्ट्रोक) की स्थापना 
            + fill(150);          // एक आकृति के इंटीरियर को सेट करना (भरना) ग्रे करने के लिए 
            + rect(50,50,75,100); // आयत खींचना
            +      </code></pre>
            +
            +      <p>
            +      स्ट्रोक या भरण को कार्यों के साथ समाप्त किया जा सकता है: <a href="/hi/reference/#/p5/noStroke">noStroke()</a> और <a href="/hi/reference/#/p5/noFill">noFill()</a> हमारी प्रवृत्ति को बिना किसी रूपरेखा के "स्ट्रोक (0)" कहना हो सकता है, हालांकि, यह याद रखना महत्वपूर्ण है कि 0 "कुछ भी नहीं" है, बल्कि रंग काले को दर्शाता है। इसके अलावा, दोनों को खत्म करने के लिए याद रखें - <b>noStroke()</b> और  <b>noFill()</b> ,कुछ भी नहीं दिखाई देगा!
            +      </p>
            +
            +      <p>इसके अलावा, अगर हम दो आकृतियाँ बनाते हैं, तो p5.js हमेशा सबसे हाल ही में निर्दिष्ट स्ट्रोक का उपयोग करेगा और ऊपर से नीचे तक कोड को पढ़ेगा।</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +  background(150);
            +  stroke(0);
            +  line(0, 0, 100, 100);
            +  stroke(255);
            +  noFill();
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <h2>RGB रंग</h2>
            +
            +      <p>
            +      फिंगर पेंटिंग याद है? तीन " प्राथमिक " रंगों को मिलाकर, किसी भी रंग को उत्पन्न किया जा सकता है। सभी रंगों को एक साथ घूमने से मैला भूरा हुआ। जितना अधिक पेंट आपने जोड़ा, उतना ही गहरा। डिजिटल रंगों का निर्माण भी तीन प्राथमिक रंगों को मिलाकर किया जाता है, लेकिन यह पेंट से अलग तरह से काम करता है। सबसे पहले, प्राइमरी अलग हैं: लाल, हरा और नीला (यानी, " RGB " रंग)। और स्क्रीन पर रंग के साथ, आप प्रकाश मिश्रण कर रहे हैं, पेंट नहीं कर रहे हैं, इसलिए मिश्रण के नियम भी अलग हैं।
            +      </p>
            +
            +      <img src="../../assets/learn/color/rgb.jpg">
            +      <p>
            +        <ul class="list_view">
            +          <li>लाल + हरा = पीला</li>
            +          <li>लाल + नीला = बैंगनी</li>
            +          <li>हरा + नीला = सियान (नीला-हरा)</li>
            +          <li>लाल + हरा + नीला = सफेद</li>
            +          <li>कोई रंग नहीं = काला</li>
            +        </ul>
            +      </p>
            +
            +      <p>यह मानता है कि रंग सभी के रूप में संभव के रूप में उज्ज्वल हैं, लेकिन निश्चित रूप से, आपके पास उपलब्ध रंग की एक सीमा है, इसलिए कुछ लाल प्लस कुछ हरे रंग के साथ कुछ नीले बराबर ग्रे, और लाल रंग का एक सा नीला नीला बैंगनी के बराबर है। हालांकि यह कुछ करने के लिए इस्तेमाल किया जा सकता है, जितना अधिक आप आरजीबी रंग के साथ कार्यक्रम और प्रयोग करते हैं, उतना ही यह सहज हो जाएगा, बहुत कुछ अपनी उंगलियों के साथ घूमता रंगों की तरह। और निश्चित रूप से आप कुछ नीले रंग के साथ कुछ लाल मिश्रण नहीं कर सकते, आपको एक सटीक राशि प्रदान करनी होगी। ग्रेस्केल के साथ, व्यक्तिगत रंग तत्वों को 0 (उस रंग में से कोई भी) से लेकर 255 तक (जितना संभव हो) के रूप में व्यक्त किया जाता है, और वे आर, जी और बी क्रम में सूचीबद्ध होते हैं। प्रयोग के माध्यम से रंग मिश्रण, लेकिन अगले हम कुछ सामान्य रंगों का उपयोग करके कुछ कोड को कवर करेंगे।</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  noStroke();
            +
            +  // Bright red
            +  fill(255,0,0);
            +  ellipse(20,20,16,16);
            +
            +  // Dark red
            +  fill(127,0,0);
            +  ellipse(40,20,16,16);
            +
            +  // Pink (pale red)
            +  fill(255,200,200);
            +  ellipse(60,20,16,16);
            +}
            +      </script>
            +
            +
            +
            +      <h2>रंग पारदर्शिता</h2>
            +
            +      <p>प्रत्येक रंग के लाल, हरे और नीले रंग के घटकों के अलावा, एक अतिरिक्त वैकल्पिक चौथा घटक है, जिसे रंग के " अल्फा " के रूप में जाना जाता है। अल्फा का अर्थ पारदर्शिता है और विशेष रूप से उपयोगी है जब आप उन तत्वों को आकर्षित करना चाहते हैं जो आंशिक रूप से एक-दूसरे के ऊपर से देखते हैं। किसी छवि के लिए अल्फा मान कभी-कभी सामूहिक रूप से एक छवि के " अल्फा चैनल " के रूप में संदर्भित होते हैं।</p>
            +      <p>यह महसूस करना महत्वपूर्ण है कि पिक्सेल सचमुच पारदर्शी नहीं हैं, यह बस एक सुविधाजनक भ्रम है जो रंगों को सम्मिश्रण करने से पूरा होता है। पर्दे के पीछे, p5.js रंग संख्या लेता है और सम्मिश्रण की ऑप्टिकल धारणा बनाते हुए एक प्रतिशत को दूसरे के प्रतिशत में जोड़ता है। (यदि आप प्रोग्रामिंग में रुचि रखते हैं " गुलाब के रंग का " चश्मा, तो यह वह जगह है जहाँ आप शुरू करेंगे।)</p>
            +
            +      <p>अल्फा मान भी 0 से 255 तक होता है, जिसमें 0 पूरी तरह से पारदर्शी होता है (यानी, 0% अपारदर्शी) और 255 पूरी तरह से अपारदर्शी (यानी, 100% अपारदर्शी).</p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +  createCanvas(100, 100);
            +  fill(0,0,255);
            +  rect(0,0,50,100);
            +
            +  // 255 means 100% opacity.
            +  fill(255,0,0,255);
            +  rect(0,0,100,20);
            +
            +  // 75% opacity.
            +  fill(255,0,0,191);
            +  rect(0,25,100,20);
            +
            +  // 55% opacity.
            +  fill(255,0,0,127);
            +  rect(0,50,100,20);
            +
            +  // 25% opacity.
            +  fill(255,0,0,63);
            +  rect(0,75,100,20);
            +
            +      </script>
            +
            +      <h2>कस्टम रंग रेंज</h2>
            +
            +      <p>
            +       0 से 255 के बीच आरजीबी रंग एकमात्र तरीका नहीं है जो आप पी 5.js में रंग संभाल सकते हैं, वास्तव में, यह हमें किसी भी तरह से रंग के बारे में सोचने की अनुमति देता है। उदाहरण के लिए, आप रंग के बारे में सोचना पसंद कर सकते हैं जो 0 से लेकर 100 (प्रतिशत की तरह) तक हो सकता है। आप एक कस्टम colorMode () निर्दिष्ट करके ऐसा कर सकते हैं। <a href="/hi/reference/#/p5/colorMode">colorMode()</a>.
            +      </p>
            +
            +      <pre><code>
            +      colorMode(RGB,100);
            +      </code></pre>
            +
            +      <p>उपरोक्त फ़ंक्शन कहता है: " ठीक है, हम लाल, हरे और नीले रंग के संदर्भ में रंग के बारे में सोचना चाहते हैं। RGB मूल्यों की सीमा 0 से 100 तक होगी। " </p>
            +
            +      <p>हालाँकि ऐसा करने के लिए यह शायद ही सुविधाजनक है, आप प्रत्येक रंग घटक के लिए अलग-अलग रेंज भी रख सकते हैं: </p>
            +
            +      <pre><code>
            +      colorMode(RGB,100,500,10,255);
            +      </code></pre>
            +
            +      <p>अब हम कह रहे हैं कि "लाल मान 0 से 100 तक जाते हैं, 0 से 500 तक हरा, 0 से 10 तक नीला और 0 से 255 तक अल्फा। "</p>
            +
            +      <p>अंत में, जबकि आपको अपनी सभी प्रोग्रामिंग जरूरतों के लिए केवल RGB रंग की आवश्यकता होगी, आप HSB (ह्यू, संतृप्ति और चमक) मोड में भी रंग निर्दिष्ट कर सकते हैं। बहुत अधिक विस्तार में आए बिना, एचएसबी रंग निम्नानुसार काम करता है:</p>
            +
            +      <img src="../../assets/learn/color/hsb.png">
            +      <ul class="list_view">
            +        <li><b>रंग</b>- रंग प्रकार, डिफ़ॉल्ट रूप से 0 से 255 तक होता है।</li>
            +        <li><b>परिपूर्णता</b>- रंग की जीवंतता, डिफ़ॉल्ट रूप से 0 से 255।</li>
            +        <li><b>चमक</b>, रंग की चमक, डिफ़ॉल्ट रूप से 0 से 255।</li>
            +      </ul>
            +
            +      <p>साथ में <a href="/hi/reference/#/p5/colorMode">colorMode()</a> आप इन मूल्यों के लिए अपनी सीमाएं निर्धारित कर सकते हैं। कुछ लोग ह्यू के लिए 0-360 (रंग व्हील पर 360 डिग्री सोचते हैं) और संतृप्ति और चमक के लिए 0-100 (0-100% के बारे में सोचें) की एक सीमा पसंद करते हैं।</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/coordinate-system-and-shapes.html b/dist/hi/learn/coordinate-system-and-shapes.html
            new file mode 100644
            index 0000000000..b2aa272574
            --- /dev/null
            +++ b/dist/hi/learn/coordinate-system-and-shapes.html
            @@ -0,0 +1,279 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      यह शिक्षण डैनियल शिफमैन की पुस्तक <em>लर्निंग प्रोसेसिंग</em> से है, जिसे मॉर्गन कॉफमैन द्वारा प्रकाशित किया गया था, © 2008 एल्सेवियर इंक। सभी अधिकार सुरक्षित इसे एलेक्स Yixuan Xu द्वारा p5.js पर पोर्ट किया गया था। यदि आप कोई त्रुटि देखते हैं या टिप्पणी करते हैं <a href="https://github.com/processing/processing-docs/issues?state=open">कृपया हमें बताएं</a>।</div>
            +
            +      <h1>समन्वय प्रणाली और आकृतियाँ</h1>
            +      <p>पी 5 के साथ प्रोग्रामिंग शुरू करने से पहले, हमें पहले अपने आठवीं कक्षा के स्वयं को चैनल करना चाहिए, ग्राफ पेपर के एक टुकड़े को बाहर निकालना चाहिए, और एक रेखा खींचना चाहिए। दो बिंदुओं के बीच की सबसे छोटी दूरी एक अच्छी पुरानी जमाने की रेखा है, और यह वह जगह है जहाँ हम शुरू करते हैं, उस ग्राफ़ पेपर पर दो बिंदुओं के साथ।</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-01.png" alt="">
            +
            +      <p>उपरोक्त आंकड़ा बिंदु A (1,0) और बिंदु B (4,5) के बीच एक रेखा दिखाता है। यदि आप अपने किसी मित्र को उसी रेखा को खींचने के लिए निर्देशित करना चाहते हैं, तो आप उन्हें एक चिल्लाहट देंगे और कहेंगे " बिंदु वन-शून्य से बिंदु चार-पाँच तक एक रेखा खींचिए, कृपया। " , कल्पना कीजिए कि आपका दोस्त एक कंप्यूटर था और आप इस डिजिटल पाल को उसकी स्क्रीन पर उसी लाइन को प्रदर्शित करने का निर्देश देना चाहते थे। एक ही आदेश लागू होता है (केवल इस बार आप सुखदताओं को छोड़ सकते हैं और आपको एक सटीक स्वरूपण को लागू करने की आवश्यकता होगी)। यहाँ, निर्देश इस तरह दिखेगा:</p>
            +
            +      <pre><code class="language-javascript">
            +        line(1,0,4,5);
            +      </code></pre>
            +
            +      <p>यहां तक ​​कि लेखन कोड के वाक्यविन्यास का अध्ययन किए बिना, उपरोक्त कथन को उचित मात्रा में समझ में आना चाहिए। हम एक आदेश प्रदान कर रहे हैं (जिसे हम मशीन के लिए " फ़ंक्शन " के रूप में संदर्भित करेंगे) "लाइन।" (1,0) से बी तक (4,5)। यदि आप एक वाक्य के रूप में कोड की उस पंक्ति के बारे में सोचते हैं, तो फ़ंक्शन एक क्रिया है और तर्क वाक्य की वस्तुएं हैं। कोड की सजा भी एक अवधि के बजाय एक अर्धविराम के साथ समाप्त होती है।</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-02.png" alt="">
            +
            +      <p>यहां कुंजी यह महसूस करना है कि कंप्यूटर स्क्रीन ग्राफ पेपर के एक कट्टर टुकड़े से ज्यादा कुछ नहीं है। स्क्रीन का प्रत्येक पिक्सेल एक समन्वय होता है - दो नंबर, एक " x " (क्षैतिज) और एक " y " (ऊर्ध्वाधर) - जो अंतरिक्ष में एक बिंदु के स्थान को निर्धारित करता है। और यह निर्दिष्ट करना हमारा काम है कि इन पिक्सेल निर्देशांक में किस आकार और रंग दिखाई देने चाहिए।</p>
            +
            +      <p>फिर भी, यहाँ एक पकड़ है। आठवीं कक्षा से ग्राफ पेपर (" कार्टेशियन कोऑर्डिनेट सिस्टम ") केंद्र में रखा गया (0,0) y- अक्ष की ओर इशारा करता है और x- अक्ष दाईं ओर इंगित करता है (सकारात्मक दिशा में, नकारात्मक नीचे और) छोडा)। कंप्यूटर विंडो में पिक्सेल के लिए समन्वय प्रणाली, हालांकि, y- अक्ष के साथ उलट है। (0,0) सकारात्मक दिशा के साथ बाईं ओर शीर्ष पर क्षैतिज और लंबवत नीचे पाया जा सकता है।</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-03.svg" alt="">
            +
            +      <h2>सरल आकृतियाँ</h2>
            +      <p>P5 के साथ आपके द्वारा देखे जाने वाले अधिकांश प्रोग्रामिंग उदाहरण प्रकृति में दृश्य हैं। इन उदाहरणों में, उनके मूल में, आकृतियाँ आरेखित करना और पिक्सेल सेट करना शामिल है। चलो चार आदिम आकृतियों को देखकर शुरू करते हैं।</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-04.png" alt="">
            +
            +      <p>प्रत्येक आकृति के लिए, हम स्वयं से पूछेंगे कि उस आकृति के स्थान और आकार (और बाद में रंग) को निर्दिष्ट करने के लिए कौन सी जानकारी आवश्यक है और जानें कि p5 उस जानकारी को प्राप्त करने की अपेक्षा करता है। नीचे दिए गए प्रत्येक चित्र में, हम 10 पिक्सेल की चौड़ाई और 10 पिक्सेल की ऊँचाई के साथ एक विंडो मानेंगे। यह विशेष रूप से वास्तविक नहीं है क्योंकि जब आप वास्तव में कोडिंग शुरू करते हैं, तो आप बहुत अधिक बड़ी खिड़कियों के साथ काम करने की संभावना करेंगे (10x10 पिक्सेल स्क्रीन स्पेस के मुश्किल से कुछ मिलीमीटर हैं।) फिर भी प्रदर्शन प्रयोजनों के लिए, क्रम में छोटी संख्या के साथ काम करना अच्छा है। पिक्सेल को प्रस्तुत करें क्योंकि वे कोड के प्रत्येक पंक्ति के आंतरिक कामकाज को बेहतर ढंग से चित्रित करने के लिए ग्राफ पेपर (अभी के लिए) पर दिखाई दे सकते हैं।</p>
            +
            +      <p>A <a href="/reference/#/p5/point">point()</a> (बिंदु) आकृतियों का सबसे आसान और शुरू करने के लिए एक अच्छी जगह है। एक बिंदु खींचने के लिए, हमें केवल एक x और y समन्वय की आवश्यकता है।</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  point(40, 50); // point(x, y)
            +}
            +</script>
            +
            +      <p>A <a href="/reference/#/p5/line">line()</a> लाइन बहुत मुश्किल नहीं है और बस दो बिंदुओं की आवश्यकता है: (X1, y1) और (x2, y2):</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  line(10, 20, 50, 20); // line(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>एक बार जब हम एक <a href="/reference/#/p5/rect">rect()</a> (आयत) बनाने आए, चीजें थोड़ी और जटिल हो जाती हैं। P5 में, एक आयत आयत के शीर्ष बाएं कोने के लिए समन्वय द्वारा निर्दिष्ट किया गया है, साथ ही इसकी चौड़ाई और ऊंचाई भी।</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  rect(10, 20, 40, 30); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>आयत बनाने का दूसरा तरीका चौड़ाई और ऊंचाई के साथ-साथ केंद्र बिंदु को निर्दिष्ट करना शामिल है। यदि हम इस विधि को पसंद करते हैं, तो हम पहले संकेत करते हैं कि हम आयत के लिए निर्देश से पहले <a href="/reference/#/p5/CENTER">CENTER</a> (केंद्र) मोड का उपयोग करना चाहते हैं।. ध्यान दें कि पी 5 केस-संवेदी है।</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(30, 20, 40, 20); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>अंत में, हम दो बिंदुओं (शीर्ष बाएं कोने और नीचे दाएं कोने) के साथ एक आयत भी खींच सकते हैं। यहां मोड  <a href="/reference/#/p5/CORNERS">CORNERS</a>  (कॉर्नर) है। ध्यान दें कि यह उदाहरण ऊपर दिए गए उदाहरण के समान स्क्रीन पर परिणाम देता है।</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CORNERS);
            +}
            +function draw(){
            +  rect(10, 10, 50, 30); // rect(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>एक बार जब हम एक आयत बनाने की अवधारणा के साथ सहज हो गए हैं, <a href="/reference/#/p5/ellipse">ellipse()</a> (दीर्घवृत्त ()) एक तस्वीर है।. वास्तव में, यह <a href="/reference/#/p5/rect">rect()</a> के समान है () इस अंतर के साथ कि एक दीर्घवृत्त खींचा जाता है जहां आयत का बाउंडिंग बॉक्स होगा। <a href="/reference/#/p5/ellipse">ellipse()</a> है <a href="/reference/#/p5/CENTER">CENTER</a>, ना की <a href="/reference/#/p5/CORNER">CORNER</a>.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CENTER);
            +}
            +function draw(){
            +  ellipse(30, 30, 40, 60); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNER);
            +}
            +function draw(){
            +  ellipse(10, 10, 30, 50); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNERS);
            +}
            +function draw(){
            +  ellipse(10, 10, 40, 50); // ellipse(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>अब देखते हैं कि 200 से 200 के विंडो आयाम के साथ अधिक यथार्थवादी सेटिंग में आकृतियों के साथ कुछ कोड क्या हैं। विंडो की चौड़ाई और ऊंचाई को निर्दिष्ट करने के लिए createCanvas () फ़ंक्शन के उपयोग पर ध्यान दें।</p>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(200, 200);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(100,100,20,100);
            +  ellipse(100,70,60,60);
            +  ellipse(81,70,16,32);
            +  ellipse(119,70,16,32);
            +  line(90,150,80,160);
            +  line(110,150,120,160);
            +}
            +</script>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/curves.html b/dist/hi/learn/curves.html
            new file mode 100644
            index 0000000000..cdd159c032
            --- /dev/null
            +++ b/dist/hi/learn/curves.html
            @@ -0,0 +1,328 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by J David Eisenberg and ported by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +      This work is licensed under a <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"> Creative Commons Attribution-NonCommercial-ShareAlinke 4.0 International License.</a>
            +
            +      </div>
            +
            +      <h1>Curves</h1>
            +
            +      <p>
            +      This short tutorial introduces you to the three types of curves in p5.js: arcs, spline curves, and Bézier curves.
            +      </p>
            +
            +      <h2> Arcs </h2>
            +
            +      <p>
            +      Arcs are the simplest curves to draw, it is defined an arc as a section of an ellipse. You call the function with these parameters:
            +      </p>
            +
            +      <p>
            +      arc (x, y, w, h, start, stop, [mode])
            +      </p>
            +
            +      <p>
            +      The first four parameters (x,y,w,h) define the boundary box for your arc and the next two (start, stop), are the start and stop angles for the arc. These angles are given in radians
            +      and are measured clockwise with zero degrees pointing east and PI radians equals 180°.
            +      </p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +          createCanvas(150,200);
            +          background(150);
            +          stroke(0);
            +          arc(35, 35, 50, 50, 0, PI / 2.0); // lower quarter circle
            +          arc(105, 35, 50, 50, -PI, 0, CHORD);  // upper half of circle
            +          arc(175, 35, 50, 50, -PI / 6, PI / 6, PIE); // 60 degrees
            +          noFill();
            +          arc(105, 105, 100, 50, PI / 2, 3 * PI / 2, OPEN); // 180 degrees
            +        }
            +      </script>
            +
            +      <h2>Spline Curves</h2>
            +
            +      <p>
            +      Arcs are fine, but they’re plain. The next function, curve(), lets you draw curves that aren’t necessarily part of an arc. This function draws what is technically called a Rom-Catmull Spline.
            +      To draw the curve, you must specify the (x, y) coordinates of the points where the curve starts and ends. You must also specify two control points which determine the direction and amount of curvature.
            +      The first two and last two parameters are the control points of the curve.
            +      A call to curve() uses these parameters:
            +      </p>
            +
            +      <p>
            +      curve (cpx1, cpy1, x1, y1, x2, y2, cpx2, cpy2);
            +      </p>
            +
            +      <p>
            +      How do the control points affect the way the curve looks?
            +      </p>
            +
            +      <p>
            +        The tangent to the curve at the start point is parallel to the line between control point one and the end of the curve. The tangent to the curve at the end point is parallel to the line between the start point and control point 2.
            +      </p>
            +
            +      <p>
            +      The following diagram shows a curve and the points can be dragged to show how the control point affects the curve:
            +      </p>
            +
            +      <!-- iframe for the curve and dragging points -->
            +      <iframe src="../../assets/learn/curves/curve_ex/embed.html" width="350" height="350">
            +      </iframe>
            +
            +
            +      <h2>Continuous Spline Curves</h2>
            +
            +      <p>
            +      In isolation, a single curve() is not particularly appealing. To draw a continuous curve through several points, you are better off using the curveVertex() function.
            +      You can only use this function when you are creating a shape with the beginShape() and endShape() functions.In common usage, people use the first point of the curve
            +      as the first control point and the last point of the curve as the last control point.
            +      </p>
            +
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      let coords = [40, 40, 80, 60, 100, 100, 60, 120, 50, 150];
            +
            +      function setup() {
            +        createCanvas(150, 200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        curveVertex(40,40);
            +        curveVertex(40,40);
            +        curveVertex(80,60);
            +        curveVertex(100,100);
            +        curveVertex(60,120);
            +        curveVertex(50,150);
            +        curveVertex(50,150);
            +        endShape();
            +
            +         for (let i = 0; i < coords.length; i+= 2){
            +          ellipse(coords[i], coords[i+1], 10, 10);
            +         }
            +      }
            +      </script>
            +
            +      <h2>Bézier Curves</h2>
            +
            +      <p>
            +        Though better than arcs, spline curves don’t seem to have those graceful, swooping curves that say “art.” For those, you need to draw Bézier curves with the bezier() function.
            +        As with spline curves, the bezier() function has eight parameters, but the order is different. The first two and last two parameters are the start and end points while middle 
            +        four points are the control points.
            +      </p>
            +
            +      <p> bezier(x1, y1, cpx1, cpy1, cpx2, cpy2, x2, y2); </p>
            +
            +      <!-- iframe of Bezier example -->
            +      <iframe src="../../assets/learn/curves/bezier/embed.html" width="400" height="400">
            +      </iframe>
            +
            +      <p>
            +      While it is difficult to visualize how the control points affect a curve(), it is slightly easier to see how the control points affect Bézier curves.
            +      Imagine two poles and several rubber bands. The poles connect the control points to the endpoints of the curve. A rubber band connects the tops of the poles.
            +      Two more rubber bands connect the midpoints of the poles to the midpoint of the first rubber band. One more rubber band connects their midpoints.
            +      The center of that last rubber band is tied to the curve. This diagram helps to explain, the points can be moved to change the curve.
            +    </p>
            +
            +      <!-- image of bezier with lines -->
            +      <img src="../../assets/learn/curves/bezier_with_lines/bezier_with_lines.png" style="width:150px;">
            +
            +      <h2> Continuous Bézier Curves</h2>
            +
            +      <p>
            +      Just as curveVertex() allows you to make continuous spline curves, bezierVertex() lets you make continuous Bézier curves.
            +      Again, you must be within a beginShape() / endShape() sequence. You must use vertex(startX, startY) to specify the starting anchor point of the curve.
            +      Subsequent points are specified with a call to:
            +      </P>
            +
            +      <p>bezierVertex(cpx1, cpy1, cpx2, cpy2, x, y);</P>
            +
            +      <p>
            +      Here is a continuous Bézier curve, but it doesn’t join smoothly. In order to make two curves A and B smoothly continuous, the last control point of A,
            +      the last point of A, and the first control point of B have to be on a straight line.
            +      </P>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +        createCanvas(150,200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        vertex(30, 70); // first point
            +        bezierVertex(25, 25, 100, 50, 50, 100);
            +        bezierVertex(50, 140, 75, 140, 120, 120); // if first 2 numbers are changed to 20, 130 it becomes continuous
            +        endShape();
            +
            +        ellipse(25, 25, 5, 5);
            +        ellipse(100, 50, 5, 5);
            +        ellipse(50, 140, 5, 5);//change to (20, 130, 5, 5) to reflect control point
            +        ellipse(75, 140, 5, 5);
            +      }
            +      </script>
            +
            +      <h2>Summary</h2>
            +        <p>
            +          <ul class="list_view">
            +            <li>Use arc() when you need a segment of a circle or an ellipse. You can’t make continuous arcs or use them as part of a shape.</li>
            +            <li>Use curve() when you need a small curve between two points. Use curveVertex() to make a continuous series of curves as part of a shape.</li>
            +            <li>Use bezier() when you need long, smooth curves. Use bezierVertex() to make a continuous series of Bézier curves as part of a shape.</li>
            +          </ul>
            +        </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/debugging.html b/dist/hi/learn/debugging.html
            new file mode 100644
            index 0000000000..dac513b7bb
            --- /dev/null
            +++ b/dist/hi/learn/debugging.html
            @@ -0,0 +1,319 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +        This tutorial was made by the Education Working Group, during the p5.js contributor conference at the Frank-Ratchye Studio for Creative Inquiry, Carnegie Mellon University in May of 2015. The contributors to this tutorial include <a href="http://huah.net/jason/">Jason Alderman</a>, <a href="http://tegabrain.com/">Tega Brain</a>, <a href="http://taeyoonchoi.com/">Taeyoon Choi</a> and <a href="http://luisaph.com/">Luisa Pereira</a>.
            +      </div>
            +      <img src="../../assets/learn/debugging/0-0.jpg" alt="" />
            +
            +      <p>
            +        This is a field guide for debugging for everyone—whether you are beginning to code or whether you have been coding for a long time, this guide breaks down the mysterious process of solving problems.
            +      </p>
            +
            +      <h3 class="start-element tutorial-btn" id="introduction">0. Debugging is a Creative Act</h3>
            +      <div class="info">
            +        <p>At all levels, programmers encounter bugs and will often spend more time debugging than actually programming the application. You can expect to spend a lot of time doing this and so it is important to develop good strategies for identifying and working through bugs as you learn to program in p5.js.</p>
            +        <p>
            +          A bug is a gap between what you think your system is doing, and what it is actually doing. <a target="_blank"
            +          href="https://vimeo.com/channels/debugging" >Clay Shirky aptly describes </a>a bug as "the moment when there is both a technical problem with your code as well as a problem with your mental picture of what is happening in your code." </p>
            +          <img src="../../assets/learn/debugging/0-1.jpg" alt="" />
            +        </p>
            +
            +        <p>You think you are telling the computer one thing, but it is doing something else. It may also be crashing or throwing errors. In order to close the gap, you must investigate. </p>
            +        <p>When you are working on a project, you may play many different roles. You are an architect when designing and planning your program, an engineer when you are developing it. Then you will be an explorer, discovering the problems and errors and testing it in all the situations in which it needs to run. You are trying to find out where it might break. Finally, when debugging you are a detective, trying to figure out how and why things broke.</p>
            +        <img class="small" src="../../assets/learn/debugging/0-3.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-4.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-5.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-6.png" alt="" />
            +
            +        <p>So how can you become a good detective and debug your program? Here are the ten steps that can help you become a good code sleuth. </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="Change Perspectives">1. Change Perspectives.</h3>
            +      <div class="info">
            +        <p>Don't panic.</p>
            +        <p>When you encounter a bug that you do not know how to solve, stop, pause and take a deep breath. Stand up, say hi to the dog, take a walk or if it's late go get some sleep. When you are frustrated, tired and upset, you are not in a good frame of mind to learn or solve a  problem.</p>
            +        <p>To find your errors you will need to change perspectives and become the detective. The goal is to find out what the program IS doing, rather than why it's not doing what it's supposed to. We need to get the computer to show us what it's doing.</p>
            +        <p>The clues are in the values of variables and flow of program.</p>
            +        <img class="small_center" src="../../assets/learn/debugging/1-0.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="problem">2. Observe the problem </h3>
            +      <div class="info">
            +        <p>Walk someone through the issue even if they themselves do not know how to program. If no one is around, draft an email explaining what you have done and breaking down what the problem is.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-1.png" alt="" />
            +        <p>You probably won't need to actually send this email as often the act of writing it will help you to locate and identify what you need to do next. Some programmers have even been known to explain their problem to a friendly inanimate object like a rubber ducky.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-2.png" alt="" />
            +        <p>
            +          This is also a good time to add comments to your code that tell you exactly what each of your functions is doing.
            +          Some coders also print out their code (or a section of it) and go through it line by line, tracing the path of variables and making notes.
            +        </p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-3.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="start">3. Before you start... </h3>
            +      <div class="info">
            +        <p>Before doing anything,  save a copy of your code that you can go back to.  While debugging you are likely to introduce other problems, break things or accidentally delete good work.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/3-1.png" alt="" />
            +        <p>You don't want to make bigger bugs in the process of debugging.</p>
            +        <img class="small_center" src="../../assets/learn/debugging/3-2.png" alt="" />
            +        <p>If you make a mistake or your problem gets more worse, you can always UNDO or revert back to your saved file.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/3-3.jpg" alt="" />
            +        <p>You can try version control such as <a href="http://github.com">GitHub</a>.</p>
            +        <img src="../../assets/learn/debugging/3-4.png" alt="" />
            +        <p>Write a list of what you are trying, so you can keep track of what still needs to be checked. Be  methodical, it will save you a lot of time in the long run.</p>
            +        <p>
            +          Only ever change one thing at a time.
            +          <img class="med_right" src="../../assets/learn/debugging/3-5.jpg" alt="" />
            +          As you debug, you will be turning parts of your code on and off.
            +          Every time you make a change, test your program. If you make multiple changes before testing, you will not know which change has what effect and are likely to break things further.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="basics">4. Check the basics </h3>
            +      <div class="info">
            +        <p>Many bugs end up being very basic mistakes, equivalent to forgetting to plug in the power cord. These mistakes are so obvious they are often invisible. Check the dumb stuff like...</p>
            +        <ul class="list_view">
            +          <li>Are you editing the file that you are actually running (and not, for example, editing the local file, and looking at a different file on the server)?</li>
            +          <li>Are all of your external files where you think they are?</li>
            +          <li>Are your file dependencies correct?</li>
            +          <li>Are there any typos in your paths?</li>
            +          <li>Check your server? etc.</li>
            +        </ul>
            +        <img src="../../assets/learn/debugging/4-1.png" alt="" />
            +        <img src="../../assets/learn/debugging/4-2.png" alt="" />
            +        <img src="../../assets/learn/debugging/4-3.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="blackboxes">5. Black boxes</h3>
            +      <div class="info">
            +        <p>A black box describes any part of your system you do not understand the inner workings of. For example, a library or perhaps a function that you have not written for yourself. Systematically take out each black box one-by-one and run your program. This will help to see if these parts of the program contain the error.</p>
            +        <img class="med_left" src="../../assets/learn/debugging/5-1.jpg" alt="" />
            +        <img class="med_right" src="../../assets/learn/debugging/5-2.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="reporting">6. Add error reporting</h3>
            +      <div class="info">
            +        <p>
            +          <img class="med_right" src="../../assets/learn/debugging/6-1.png" alt="" />
            +          Error reporting is how your program tells you what it is doing.
            +          p5.js comes with some built-in error reporting that will tell you if you have made specific syntax errors.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in your own error reporting using the console.log() function.
            +          <img class="med_right" src="../../assets/learn/debugging/6-2.png" alt="" />
            +          To check your program flow, add in console.log() statements to the parts of your code.
            +          Then when you look at your console you can see the order that things happen and where you encounter problems.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in console.log()s to print out values of variables so that you can see what they are doing.
            +          <img class="med_center" src="../../assets/learn/debugging/6-3.jpg" alt="" />
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="help">7. Search for more help </h3>
            +      <div class="info">
            +        <p>So none of this works? There are many places you can look online to get more help.</p>
            +        <ul class="list_view">
            +          <li>Do a Google search, if you have had this problem chances are many other people will have too.</li>
            +          <li>Search the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> using the p5.js tag.</li>
            +          <li>Search development forums like <a href="http://stackoverflow.com/">Stack Overflow</a>.</li>
            +        </ul>
            +        <p> More general javascript resources:</p>
            +        <ul class="list_view">
            +          <li>First chapter of Bocoup's and Rebecca Murphey's interactive textbook, <a href="http://jqfundamentals.com/chapter/javascript-basics">jQuery Fundamentals</a>.</li>
            +          <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">  Mozilla's JavaScript Guide</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference ">JavaScript Reference </a>(this is really helpful for finding all of the built-in methods for, say a String).</li>
            +        </ul>
            +        <img class="med_center" src="../../assets/learn/debugging/7-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="people">8. Ask people </h3>
            +      <div class="info">
            +        <p>
            +          Still not working?
            +          <img class="med_right" src="../../assets/learn/debugging/8-0.jpg" alt="" />
            +          You can also ask people for help! They might be delighted to help you.
            +        </p>
            +        <p>
            +          Send that email you wrote at the start.<br>
            +          Post to the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> succinctly articulating your problem and what you want to know. <br>
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="prevent">9. Good coding practices and how to prevent bugs!</h3>
            +      <div class="info">
            +        <ul class="list_view">
            +          <li>Do not optimize prematurely. Clear code is more important than high-performing code as you're building your program.</li>
            +          <li>Do not abstract prematurely. You don't need to make functions for things you think you're going to use multiple times...until you actually have to use it more than once.</li>
            +          <li>
            +            Start with pseudocode as comments, then add code underneath each step.<br>
            +            Put console.log()s in your code as you develop (and test frequently—so if something changes, you know what you did since the last time you tested).<br>
            +          </li>
            +        </ul>
            +        <p>ALSO: start with small problems! Do one thing at a time. It's ok to make smaller sketches to test one thing (draw a star! check twitter!) and then voltron them together into a bigger sketch (draw a star that turns red when you have a notification on twitter!)</p>
            +        <img class="med_center" src="../../assets/learn/debugging/9-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="resources">10. More resources </h3>
            +      <div class="info">
            +        <p>
            +          This guide has been inspired by several other fantastic resources on debugging when coding. Some of these are here:
            +        </p>
            +          <ul class="list_view">
            +            <li>Matt Gemmel, <a href="http://mattgemmell.com/what-have-you-tried/">What have you tried?</a></li>
            +            <li>Clay Shirky, <a href="https://vimeo.com/channels/debugging">A brief introduction to debugging</a></li>
            +            <li>Eric Steven Raymond, <a href="http://www.catb.org/esr/faqs/smart-questions.html"> How to ask questions the smart way</a></li>
            +            <li>ITP Residents, <a href="https://docs.google.com/presentation/d/1RXzITwS4otVKnYkuNu2w7CrpYy35WBO2HUlmkSc2p8g/edit?copiedFromTrash#slide=id.g2ffb36b3_0_44">10 Tips for Debugging</a></li>
            +            <li>Rurouni Jones, <a href="http://rurounijones.github.io/blog/2009/03/17/how-to-ask-for-help-on-irc//">How to ask for help on IRC</a></li>
            +          </ul>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/index.html b/dist/hi/learn/index.html
            new file mode 100644
            index 0000000000..3a9bbea668
            --- /dev/null
            +++ b/dist/hi/learn/index.html
            @@ -0,0 +1,490 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>सीखना</h1>
            +
            +      <p>ये शिक्षण विशेष विषयों के अधिक गहराई या चरण-दर-चरण साक्षात्कार प्रदान करते हैं 
            +        <a href="/hi/examples">उदाहरण पृष्ठ देखें
            +        </a>विभिन्न p5.js विषयों के छोटे प्रदर्शनों को देखने के लिए।
            +      </p>
            +
            +      
            +        <h2 class="tutorial-title">P5.js का परिचय</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="/hi/get-started/">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>शुरू करना</h3>
            +                </a>
            +              </div>
            +              <p>P5.js में आपका स्वागत है! <br> इस परिचय में p5.js प्रोजेक्ट स्थापित करने की मूल बातें शामिल हैं। </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js-overview">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js अवलोकन</h3>
            +                </a>
            +              </div>
            +              <p>p5.js की मुख्य विशेषताओं का अवलोकन। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Processing-transition">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js और प्रोसेसिंग</h3>
            +                </a>
            +              </div>
            +              <p>दोनों के बीच मुख्य अंतर, और एक से दूसरे में कैसे परिवर्तित किया जाए। </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Local-server">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>स्थानीय सर्वर का उपयोग करना</h3>
            +                </a>
            +              </div>
            +              <p>Mac OSX, Windows, या Linux पर स्थानीय सर्वर कैसे सेट करें। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js विकी</h3>
            +                </a>
            +              </div>
            +              <p>समुदाय द्वारा योगदान किए गए अतिरिक्त दस्तावेज़ीकरण और शिक्षण </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="p5-screen-reader.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>स्क्रीन रीडर के साथ p5</h3>
            +                </a>
            +              </div>
            +              <p>P5 सेट करना ताकि इसे स्क्रीन रीडर के साथ आसानी से उपयोग किया जा सके। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">कनेक्टिंग p5.js</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>node.js और socket.io</h3>
            +                </a>
            +              </div>
            +              <p>p5.js के साथ node.js सर्वर का उपयोग करना, socket.io के माध्यम से संचार करना। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">प्रोग्रामिंग विषय</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Beyond-the-canvas">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>कैनवास से परे</h3>
            +                </a>
            +              </div>
            +              <p>कैनवास से परे पृष्ठ पर तत्वों को बनाना और उनमें परिवर्तन करना। </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>3D / WebGL</h3>
            +                </a>
            +              </div>
            +              <p>WebGL मोड का उपयोग करके p5.js में उन्नत ग्राफ़िक्स एप्लिकेशन विकसित करना। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="color.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>रंग</h3>
            +                </a>
            +              </div>
            +              <p>डिजिटल रंग के लिए एक परिचय। </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="coordinate-system-and-shapes.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>समन्वय प्रणाली और आकृतियाँ</h3>
            +                </a>
            +              </div>
            +              <p>सरल आकृतियों को आकर्षित करना और समन्वय प्रणाली का उपयोग करना। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="curves.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>कर्व</h3>
            +                </a>
            +              </div>
            +              <p>p5.js में तीन प्रकार के कर्व्स का परिचय: आर्क्स, स्पलाइन कर्व्स और बेज़ियर कर्व्स।  </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="interactivity.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>अन्तरक्रियाशीलता</h3>
            +                </a>
            +              </div>
            +              <p>माउस और कीबोर्ड के साथ अन्तरक्रियाशीलता का परिचय। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="program-flow.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>रोग्राम का प्रवाह</h3>
            +                </a>
            +              </div>
            +              <p>p5.js में प्रोग्राम प्रवाह को नियंत्रित करने का परिचय। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">एक बेहतर प्रोग्रामर बनना</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="debugging.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>डिबगिंग</h3>
            +                </a>
            +              </div>
            +              <p>सभी के लिए डिबगिंग के लिए फील्ड गाइड। </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>प्रदर्शन के लिए p5.js कोड का अनुकूलन</h3>
            +                </a>
            +              </div>
            +              <p>अपने कोड को अनुकूलित करने के लिए युक्तियों और युक्तियों का एक शिक्षण इसे तेज और सुचारू रूप से चलाने के लिए। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tdd.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>इकाई परीक्षण और परीक्षण संचालित विकास</h3>
            +                </a>
            +              </div>
            +              <p>इंस्टालेशन के समय पर खुद को पीड़ा से बचाएं। यूनिट परीक्षण क्या है और इसका उपयोग कैसे करें? एंडी टिम्मन्स द्वारा। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">समुदाय में योगदान</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>विकास</h3>
            +                </a>
            +              </div>
            +              <p>शुरुआत करना और विकास में योगदान के लिए अवलोकन। </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://www.luisapereira.net/teaching/materials/processing-foundation">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5 के अंदर</h3>
            +                </a>
            +              </div>
            +              <p>लुईसाा परेरा द्वारा p5.js विकास के लिए फ़ाइल संरचना और उपकरणों के लिए एक अनुकूल परिचय। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tutorial-guide.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>एक शिक्षण लेखन</h3>
            +                </a>
            +              </div>
            +              <p>एक गाइड p5.js प्रोग्रामिंग शिक्षण लिखने के लिए। </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>लाइब्रेरी बनाना </h3>
            +                </a>
            +              </div>
            +              <p>P5.js एडोन लाइब्रेरीज़ बनाना। </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/interactivity.html b/dist/hi/learn/interactivity.html
            new file mode 100644
            index 0000000000..ab694d22cd
            --- /dev/null
            +++ b/dist/hi/learn/interactivity.html
            @@ -0,0 +1,959 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This is based on the Interactivity chapter from the second edition of<em>
            +      <a href="https://processing.org/handbook/">Processing: A Programming Handbook for Visual Designers and Artists</a></em>, published by MIT Press. Copyright 2013 MIT Press. This tutorial was originally written for Processing version 2.0+ but has been ported and updated here for P5 by Alex Yixuan Xu. If you see any errors or have comments, please
            +      <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Interactivity</h1>
            +
            +      <p>The screen forms a bridge between our bodies and the realm of circuits and electricity inside computers. We control elements on screen through a variety of devices such as touch pads, trackballs, and joysticks, but the keyboard and mouse remain the most common input devices for desktop computers. The computer mouse dates back to the late 1960s, when Douglas Engelbart presented the device as an element of the oN-Line System (NLS), one of the first computer systems with a video display. The mouse concept was further developed at the Xerox Palo Alto Research Center (PARC), but its introduction with the Apple Macintosh in 1984 was the catalyst for its current ubiquity. The design of the mouse has gone through many revisions in the last forty years, but its function has remained the same. In Engelbart's original patent application in 1970 he referred to the mouse as an "X-Y position indicator," and this still accurately, but dryly, defines its contemporary use.</p>
            +
            +      <p>The physical mouse object is used to control the position of the cursor on screen and to select interface elements. The cursor position is read by computer programs as two numbers, the x-coordinate and the y-coordinate. These numbers can be used to control attributes of elements on screen. If these coordinates are collected and analyzed, they can be used to extract higher-level information such as the speed and direction of the mouse. This data can in turn be used for gesture and pattern recognition.</p>
            +
            +      <p>Keyboards are typically used to input characters for composing documents, email, and instant messages, but the keyboard has potential for use beyond its original intent. The migration of the keyboard from typewriter to computer expanded its function to enable launching software, moving through the menus of software applications, and navigating 3D environments in games. When writing your own software, you have the freedom to use the keyboard data any way you wish. For example, basic information such as the speed and rhythm of the fingers can be determined by the rate at which keys are pressed. This information could control the speed of an event or the quality of motion. It's also possible to ignore the characters printed on the keyboard itself and use the location of each key relative to the keyboard grid as a numeric position.</p>
            +
            +      <p>The modern computer keyboard is a direct descendant of the typewriter. The position of the keys on an English-language keyboard is inherited from early typewriters. This layout is called QWERTY because of the order of the top row of letter keys. It was developed for typewriters to put physical distance between frequently typed letter pairs, helping reduce the likelihood of the typebars colliding and jamming as they hit the ribbon. This more than one-hundred-year-old mechanical legacy still affects how we write software today.</p>
            +
            +      <h2>Mouse Data</h2>
            +
            +      <p>The variables <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> (note the capital X and Y) store the x-coordinate and y-coordinate of the cursor relative to the origin in the upper-left corner of the display window. To see the actual values produced while moving the mouse, run this program to print the values to the screen:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text("X: "+mouseX, 0, height/4);
            +  text("Y: "+mouseY, 0, height/2);
            +}
            +      </script>
            +
            +      <p>When a program starts, the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> values are 0. If the cursor moves into the display window, the values are set to the current position of the cursor. If the cursor is at the left, the mouseX value is 0 and the value increases as the cursor moves to the right. If the cursor is at the top, the mouseY value is 0 and the value increases as the cursor moves down. If mouseX and mouseY are used in programs without a <a href="/reference/#/p5/draw"> draw()</a> or if <a href="/reference/#/p5/noLoop">noLoop()</a> is run in <a href="/reference/#/p5/setup">setup()</a>, the values will always be 0.</p>
            +
            +      <p>The mouse position is most commonly used to control the location of visual elements on screen. More interesting relations are created when the visual elements relate differently to the mouse values, rather than simply mimicking the current position. Adding and subtracting values from the mouse position creates relationships that remain constant, while multiplying and dividing these values creates changing visual relationships between the mouse position and the elements on the screen. In the first of the following examples, the circle is directly mapped to the cursor, in the second, numbers are added and subtracted from the cursor position to create offsets, and in the third, multiplication and division are used to scale the offsets.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);    // Top circle
            +  ellipse(mouseX+20, 50, 33, 33); // Middle circle
            +  ellipse(mouseX-20, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);   // Top circle
            +  ellipse(mouseX/2, 50, 33, 33); // Middle circle
            +  ellipse(mouseX*2, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <p>To invert the value of the mouse, subtract the mouseX value from the width of the window and subtract the mouseY value from the height of the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  let x = mouseX;
            +  let y = mouseY;
            +  let ix = width - mouseX;  // Inverse X
            +  let iy = height - mouseY; // Inverse Y
            +  background(126);
            +  fill(255, 150);
            +  ellipse(x, height/2, y, y);
            +  fill(0, 159);
            +  ellipse(ix, height/2, iy, iy);
            +}
            +      </script>
            +
            +      <p>The variables <a href="/reference/#/p5/pmouseX">pmouseX</a> and <a href="/reference/#/p5/pmouseY">pmouseY</a> store the mouse values from the previous frame. If the mouse does not move, the values will be the same, but if the mouse is moving quickly there can be large differences between the values. To see the difference, run the following program and alternate moving the mouse slowly and quickly. Watch the values print to the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text(pmouseX - mouseX, 0, height/4);
            +}
            +      </script>
            +
            +      <p>Draw a line from the previous mouse position to the current position to show the changing position in one frame and reveal the speed and direction of the mouse. When the mouse is not moving, a point is drawn, but quick mouse movements create long lines.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(8);
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, mouseY, pmouseX, pmouseY);
            +}
            +      </script>
            +
            +      <p>Use the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables with an if structure to allow the cursor to select regions of the screen. The following examples demonstrate the cursor making a selection between different areas of the display window. The first divides the screen into halves, and the second divides the screen into thirds.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 50) {
            +    rect(0, 0, 50, 100);  // Left
            +  }
            +  else {
            +    rect(50, 0, 50, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 33) {
            +    rect(0, 0, 33, 100);  // Left
            +  }
            +  else if (mouseX < 66) {
            +    rect(33, 0, 33, 100); // Middle
            +  }
            +  else {
            +    rect(66, 0, 33, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <p>Use the logical operator &amp;&amp; with an if structure to select a rectangular region of the screen. As demonstrated in the following example, when a relational expression is made to test each edge of a rectangle (left, right, top, bottom) and these are concatenated with a logical AND, the entire relational expression is true only when the cursor is inside the rectangle.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX > 40) && (mouseX < 80) && (mouseY > 20) && (mouseY < 80)){
            +    fill(255);
            +  }
            +  else {
            +    fill(0);
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>This code asks, "Is the cursor to the right of the left edge and is the cursor to the left of the right edge and is the cursor beyond the top edge and is the cursor above the bottom?" The code for the next example asks a set of similar questions and combines them with the keyword else to determine which one of the defined areas contains the cursor.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX <= 50) && (mouseY <= 50)) {
            +    rect(0, 0, 50, 50);   // Upper-left
            +  }
            +  else if ((mouseX <= 50) && (mouseY > 50)) {
            +    rect(0, 50, 50, 50);  // Lower-left
            +  }
            +  else if ((mouseX > 50) && (mouseY <= 50)) {
            +    rect(50, 0, 50, 50);  // Upper-right
            +  }
            +  else {
            +    rect(50, 50, 50, 50); // Lower-right
            +  }
            +}
            +      </script>
            +
            +      <h2>Mouse buttons</h2>
            +      <p>Computer mice and other related input devices typically have between one and three buttons; p5 can detect when these buttons are pressed with the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> and <a href="/reference/#/p5/mouseButton">mouseButton</a> variables. Used with the button status, the cursor position enables the mouse to perform different actions. For example, a button press when the mouse is over an icon can select it, so the icon can be moved to a different location on screen. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true if any mouse button is pressed and false if no mouse button is pressed. The variable <a href="/reference/#/p5/mouseButton">mouseButton</a> is LEFT, CENTER, or RIGHT depending on the mouse button most recently pressed. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable reverts to false as soon as the button is released, but the <a href="/reference/#/p5/mouseButton">mouseButton</a> variable retains its value until a different button is pressed. These variables can be used independently or in combination to control the software. Run these programs to see how the software responds to your fingers.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(0);   // Black
            +  }
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseButton == LEFT) {
            +    fill(0);   // Black
            +  }
            +  else if (mouseButton == RIGHT) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(126); // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    if (mouseButton == LEFT) {
            +      fill(0);   // Black
            +    }
            +    else if (mouseButton == RIGHT) {
            +      fill(255); // White
            +    }
            +  }
            +  else {
            +    fill(126);   // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>Not all mice have multiple buttons, and if software is distributed widely, the interaction should not rely on detecting which button is pressed.</p>
            +
            +      <h2>Keyboard data</h2>
            +
            +      <p>p5 registers the most recently pressed key and whether a key is currently pressed. The boolean variable <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> is true if a key is pressed and is false if not. Include this variable in the test of an if structure to allow lines of code to run only if a key is pressed. The <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable remains true while the key is held down and becomes false only when the key is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) {  // If the key is pressed,
            +    line(20, 20, 80, 80);      // draw a line;
            +  }
            +  else {                       // Otherwise,
            +    rect(40, 40, 20, 20);      // draw a rectangle.
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 20;
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) { // If the key is pressed,
            +    x++;                      // add 1 to x.
            +  }
            +  line(x, 20, x-60, 80);
            +}
            +      </script>
            +      <!-- made changes about the key variable not guaranteed to be case sensitive in p5 -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable stores a single alphanumeric character. Specifically, it holds the most recently pressed key. However, it is not guaranteed to be case sensitive. To get the proper capitalization, it is best to use it within <a href="/reference/#/p5/keyTyped">keyTyped()</a>. For non-ASCII keys, use the <a href="/reference/#/p5/keyCode">keyCode</a> variable. The key can be displayed on screen with the <a href="/reference/#/p5/text">text()</a> function (p. 150).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  textSize(60);
            +  fill(255);
            +}
            +function draw() {
            +  background(0);
            +  text(key, 20, 75); // Draw at coordinate (20,75)
            +}
            +      </script>
            +
            +      <!-- no differences in "" and '' in p5, made changes -->
            +      <!-- <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. The single quotes signify A as the data type char (p. 144). The expression key == "A" will cause an error because the double quotes signify the A as a String, and it's not possible to compare a String with a char. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyPressed">keyPressed</a> variable to ascertain that the key pressed is the uppercase A.</p> -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. Note the use of double quotation marks or single quotation marks has no influence on the program as long as you are consistent. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable to ascertain that the key pressed is the uppercase A.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +  stroke(255);
            +}
            +function draw() {
            +  background(0);
            +  // If the 'A' key is pressed, draw a line
            +  if ((keyIsPressed == true) && (key == 'A')) {
            +    line(50, 25, 50, 75);
            +  }
            +  else { // Otherwise, draw an ellipse
            +    ellipse(50, 50, 50, 50);
            +  }
            +}
            +      </script>
            +
            +      <p>The previous example works with an uppercase A, but not if the lowercase letter is pressed. To check for both uppercase and lowercase letters, extend the relational expression with a logical OR, the || relational operator. Line 9 in the previous program would be changed to:</p>
            +      <pre><code class="language-javascript">
            +        if ((keyIsPressed == true) &amp;&amp; ((key == 'a') || (key == 'A'))) {
            +      </code></pre>
            +
            +      <!-- changes made -->
            +      <h2>Coded keys</h2>
            +      <p>Because each character has a numeric value as defined by the <a href="https://www.w3schools.com/charsets/ref_html_ascii.asp">ASCII table</a>, the value of the <a href="/reference/#/p5/keyCode">keyCode</a> variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script>
            +
            +      <!--made changes to original content here -->
            +<!--       <p>Because each character has a numeric value as defined by the ASCII table (p. 605), the value of the key variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +      <h2>Coded keys</h2>
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script> -->
            +
            +      <h2>Events</h2>
            +      <p>A category of functions called events alter the normal flow of a program when an action such as a key press or mouse movement takes place. An event is a polite interruption of the normal flow of a program. Key presses and mouse movements are stored until the end of <a href="/reference/#/p5/draw">draw()</a>, where they can take action that won't disturb drawing that's currently in progress. The code inside an event function is run once each time the corresponding event occurs. For example, if a mouse button is pressed, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function will run once and will not run again until the button is pressed again. This allows data produced by the mouse and keyboard to be read independently from what is happening in the rest of the program.</p>
            +
            +      <h2>Mouse events</h2>
            +      <!-- added mouseClicked() mouseOver() mouseOut() doubleClicked()-->
            +      <p>The mouse event functions are <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, <a href="/reference/#/p5/mouseDragged">mouseDragged()</a>, <a href="/reference/#/p5/mouseOver">mouseOver()</a>, and <a href="/reference/#/p5/mouseOut">mouseOut()</a>:</p>
            +
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block is run one time when the mouse is moved while a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>The <a href="/reference/#/p5/mousePressed">mousePressed()</a> function works differently than the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable. The value of the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true until the mouse button is released. It can therefore be used within <a href="/reference/#/p5/draw">draw()</a> to have a line of code run while the mouse is pressed. In contrast, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function only runs once when a button is pressed. This makes it useful when a mouse click is used to trigger an action, such as clearing the screen. In the following example, the background value becomes lighter each time a mouse button is pressed. Run the example on your computer to see the change in response to your finger.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mousePressed() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>The following example is the same as the one above, but the gray variable is set in the <a href="/reference/#/p5/mouseReleased">mouseReleased()</a> event function, which is called once every time a button is released. This difference can be seen only by running the program and clicking the mouse button. Keep the mouse button pressed for a long time and notice that the background value changes only when the button is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseReleased() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <!-- mouseClicked() example added-->
            +      <p>Similarly, the gray variable is set in the <a href="/reference/#/p5/mouseClicked">mouseClicked()</a> event function, which is called once after a mouse button has been pressed and then released. Browsers handle clicks differently, so this function is only guaranteed to be run when the left mouse button is clicked. To handle other mouse buttons being pressed or released, use <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>. </p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseClicked() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>It is generally not a good idea to draw inside an event function, but it can be done under certain conditions. Before drawing inside these functions, it's important to think about the flow of the program. In this example, squares are drawn inside <a href="/reference/#/p5/mousePressed">mousePressed()</a> and they remain on screen because there is no <a href="/reference/#/p5/background">background()</a> inside <a href="/reference/#/p5/draw">draw()</a>. But if <a href="/reference/#/p5/background">background()</a> is used, visual elements drawn within one of the mouse event functions will appear on screen for only a single frame, or, by default, 1/60th of a second. In fact, you'll notice this example has nothing at all inside <a href="/reference/#/p5/draw">draw()</a>, but it needs to be there to force P5 to keep listening for the events. If a <a href="/reference/#/p5/background">background()</a> function were run inside <a href="/reference/#/p5/draw">draw()</a>, the rectangles would flash onto the screen and disappear.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  fill(0, 102);
            +  background(204); // Draw once to give a little color
            +}
            +function draw() {
            +} // Empty draw() keeps the program running
            +function mousePressed() {
            +  rect(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <p>The code inside the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> and <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> event functions are run when there is a change in the mouse position. The code in the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> block is run at the end of each frame when the mouse moves and no button is pressed. The code in the <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> block does the same when the mouse button is pressed. If the mouse stays in the same position from frame to frame, the code inside these functions does not run. In this example, the gray circle follows the mouse when the button is not pressed, and the black circle follows the mouse when a mouse button is pressed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let dragX, dragY, moveX, moveY;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  fill(0);
            +  ellipse(dragX, dragY, 33, 33); // Black circle
            +  fill(153);
            +  ellipse(moveX, moveY, 33, 33); // Gray circle
            +}
            +function mouseMoved() {   // Move gray circle
            +  moveX = mouseX;
            +  moveY = mouseY;
            +}
            +function mouseDragged() { // Move black circle
            +  dragX = mouseX;
            +  dragY = mouseY;
            +}
            +      </script>
            +
            +      <!-- examples added for mouseOut() and mouseOver() -->
            +      <p>The <a href="/reference/#/p5/mouseOver">.mouseOver()</a> function is called once after every time a mouse moves onto the element. In this example, the diameter of the ellipse increase by 10 every time the mouse moves onto the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOver(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/mouseOut">.mouseOut()</a> function is called once after every time a mouse moves off the element. Similar to the above example, the diameter of the ellipse increase by 10 every time the mouse moves out of the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOut(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <h2>Wheel Events</h2>
            +      <p>The <a href="/reference/#/p5/mouseWheel">.mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners. The function accepts a callback function as argument which will be executed when the wheel event is triggered on the element. The <a href="/reference/#/p5/deltaY">event.deltaY</a> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <a href="/reference/#/p5/deltaX">event.deltaX</a> does the same as <a href="/reference/#/p5/deltaY">event.deltaY</a> except it reads the horizontal wheel scroll of the mouse wheel. On OS X with "natural" scrolling enabled, the <a href="/reference/#/p5/deltaY">event.deltaY</a> values are reversed.</p>
            +      <p>In this example, an event listener is attached to the canvas element, and function changeSize() would run when scrolling is performed on canvas. By using the <a href="/reference/#/p5/deltaY">event.deltaY</a> variable, scrolling up on canvas would increase the diameter of the ellipse and scrolling down would decrease the diameter. If scrolling is performed anywhere in any direction, the background is going to be darker.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseWheel(changeSize); // attach listener for activity on canvas only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with mousewheel movement anywhere on screen
            +function mouseWheel() {
            +  g = g + 10;
            +}
            +
            +// this function fires with mousewheel movement over canvas only
            +function changeSize(event) {
            +  if (event.deltaY > 0) {
            +    d = d + 10;
            +  }
            +  else {
            +    d = d - 10;
            +  }
            +}
            +      </script>
            +
            +      <h2>Key events</h2>
            +      <!-- keyTyped() added -->
            +      <p>Each key press is registered through the keyboard event functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyPressed">keyTyped()</a> and <a href="/reference/#/p5/keyReleased">keyReleased()</a>:</p>
            +      
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block is run one time when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is run one time when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is run one time when any key is released</li>
            +      </ul>
            +
            +      <p>Each time a key is pressed, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block is run once. Within this block, it's possible to test which key has been pressed and to use this value for any purpose. If a key is held down for an extended time, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block might run many times in a rapid succession because most operating systems will take over and repeatedly call the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. The amount of time it takes to start repeating and the rate of repetitions will be different from computer to computer, depending on the keyboard preference settings. In this example, the value of the boolean variable drawT is set from false to true when the T key is pressed; this causes the lines of code to render the rectangles in <a href="/reference/#/p5/draw">draw()</a> to start running.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +      </script>
            +
            +      <!-- added this information to distinguish keyPressed() and keyTyped() -->
            +      <p>When ASCII keys are pressed, the character is stored in the <a href="https://p5js.org/reference/#/p5/key">key </a>variable. However, this variable does not distinguish between uppercase and lowercase when used with the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. For this reason, it is recommended to use <a href="/reference/#/p5/keyTyped">keyTyped()</a>. When used with the <a href="/reference/#/p5/key">key</a> variable this function will recognize case. </p>
            +
            +      <p>Each time a key is released, the code inside the <a href="/reference/#/p5/keyReleased">keyReleased()</a> block is run once. The following example builds on the previous code; each time the key is released the boolean variable drawT is set back to false to stop the shape from displaying within <a href="/reference/#/p5/draw">draw()</a>.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +function keyReleased() {
            +  drawT = false;
            +}
            +      </script>
            +
            +      <h2>Event flow</h2>
            +      <p>As discussed previously, programs written with <a href="/reference/#/p5/draw">draw()</a> display frames to the screen sixty frames each second. The <a href="/reference/#/p5/frameRate">frameRate()</a> function is used to set a limit on the number of frames that will display each second, and the <a href="/reference/#/p5/noLoop">noLoop()</a> function can be used to stop draw() from looping. The additional functions <a href="/reference/#/p5/loop">loop()</a> and <a href="/reference/#/p5/redraw">redraw()</a> provide more options when used in combination with the mouse and keyboard event functions. If a program has been paused with <a href="/reference/#/p5/noLoop">noLoop()</a>, running <a href="/reference/#/p5/loop">loop()</a> resumes its action. Because the event functions are the only elements that continue to run when a program is paused with noLoop(), the loop() function can be used within these events to continue running the code in draw(). The following example runs the draw() function for about two seconds each time a mouse button is pressed and then pauses the program after that time has elapsed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let frame = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  if (frame > 120) {              // If 120 frames since the mouse
            +    noLoop();                     // was pressed, stop the program
            +    background(0);                // and turn the background black.
            +  }
            +  else {                          // Otherwise, set the background
            +    background(204);              // to light gray and draw lines
            +    line(mouseX, 0, mouseX, 100); // at the mouse position
            +    line(0, mouseY, 100, mouseY);
            +    frame++;
            +  }
            +}
            +function mousePressed() {
            +  frame = 0;
            +  loop();
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/redraw">redraw()</a> function runs the code in draw() one time and then halts the execution. It's helpful when the display needn't be updated continuously. The following example runs the code in draw() once each time a mouse button is pressed.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, 0, mouseX, 100);
            +  line(0, mouseY, 100, mouseY);
            +}
            +function mousePressed() {
            +  redraw(); // Run the code in draw one time
            +}
            +      </script>
            +
            +      <!-- event listener and callback functions explained??? -->
            +      <!-- This should probably be explained in a another tutorial more in-depth -->
            + <!--      Functions like mousePressed(), mouseClicked(), mouseReleased(), mouseMoved(), mouseOver(), and mouseOut() can be used as event listeners. They can be attached to certain elements</p>
            +      <p>Function|Boolean: function to be fired when mouse is pressed over the element. if false is passed instead, the previously firing function will no longer fire.</p>
            +      <p>In this example</p>
            +       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +-->
            +      <h2>Cursor icon</h2>
            +      <p>The cursor can be hidden with the <a href="/reference/#/p5/noCursor">noCursor()</a> function and can be set to appear as a different icon or image with the <a href="/reference/#/p5/cursor">cursor()</a> function. When the noCursor() function is run, the cursor icon disappears as it moves into the display window. To give feedback about the location of the cursor within the software, a custom cursor can be drawn and controlled with the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(7);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  ellipse(mouseX, mouseY, 10, 10);
            +}
            +      </script>
            +
            +      <p>If <a href="/reference/#/p5/noCursor">noCursor()</a> is run, the cursor will be hidden while the program is running until the <a href="/reference/#/p5/cursor">cursor()</a> function is run to reveal it.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor();
            +  }
            +  else {
            +    noCursor();
            +  }
            +}
            +      </script>
            +
            +      <p>Add a parameter to the cursor() function to change it to another icon or image. Either load and use image, or use the self-descriptive options are ARROW, CROSS, HAND, MOVE, TEXT, and WAIT.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor(HAND);  // Draw cursor as hand
            +  }
            +  else {
            +    cursor(CROSS); // Draw cursor as cross
            +  }
            +  line(mouseX, 0, mouseX, height);
            +  line(0, mouseY, height, mouseY);
            +}
            +      </script>
            +      <p>These cursor icons are part of your computer's operating system and will appear different on different machines.</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div>
            +  <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/p5-screen-reader.html b/dist/hi/learn/p5-screen-reader.html
            new file mode 100644
            index 0000000000..c0e3da5291
            --- /dev/null
            +++ b/dist/hi/learn/p5-screen-reader.html
            @@ -0,0 +1,604 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Using p5 with a screen reader</h1>
            +
            +      <p>
            +        This page introduces some of the screen reader friendly features of the p5js web editor, it provides an overview of accessible outputs, and examples and tutorials on how to get started with p5 when using a screen reader.
            +      </p>
            +      <p>
            +        p5.js is a library that starts with the original goal of Processing –to make to make coding accessible for artists, designers, educators, and beginners– and reinterprets it for the web using the metaphor of a software sketchbook with a set of drawing functionality. With p5.js we are able to draw in the canvas. The canvas is perhaps the most inaccessible element in HTML. The reason for this is simple: the canvas behaves just like a physical canvas, once you put paint on it, it covers up what’s behind it, making it hard to understand how the pixels comprise shapes and elements. Within the p5.js web editor it is possible to access the content of the canvas using a screen reader through text, a spatial table, and sound outputs.
            +      </p>
            +
            +
            +      <h2>What is the p5.js Web Editor</h2>
            +      <p>
            +        The p5.js web editor is a essentially a web page where you can type code in p5.js and run the code to view the output. It allows us to code in and for the browser. The web editor has features that make it screen reader friendly. You can access the <a href="http://editor.p5js.org/">p5 web editor here.</a>
            +      </p>
            +
            +      <h2>Pairings</h2>
            +      <p>
            +        Please note - the p5.accessibility library is currently not supported on MacOS.
            +      </p>
            +      <p>
            +        Using the p5.js web editor with a screen reader works better when you have one of the following screen reader/browser/operating system pairings:
            +      </p>
            +        <ul class="list_view">
            +          <li>NVDA and Firefox</li>
            +          <li>JAWS and Chrome</li>
            +        </ul>
            +
            +      <h2>Outputs</h2>
            +      <p>
            +        With a screen reader we can access the content of the canvas through the following outputs:
            +      </p>
            +
            +      <h3>Plain Text Output</h3>
            +      <p>
            +        This output describes the visual content present on the canvas in plain text.
            +      </p>
            +
            +      <h3>Table Output</h3>
            +      <p>
            +        The table output laids out the content of the canvas in the form of a table based on the spatial location of each element.
            +
            +      </p>
            +
            +      <h3>Sound Output</h3>
            +      <p>
            +        This mode explains the movement of the objects present in the canvas. Top to bottom movement is represented by a decrease in frequency and left to right through panning.
            +      </p>
            +
            +      <h2>How to select an output:</h2>
            +      <p>
            +        In the p5.js web editor there are two ways to select the accessible outputs that we want to make available.
            +      </p>
            +      <ol>
            +        <li>
            +          When we press the “play sketch, button” accessible to screen readers the “plain-text output” will automatically be available.
            +        </li>
            +        <li>
            +          If we want to access other outputs we should do the following:
            +          <ul class="list_view">
            +            <li>
            +              First, stop the sketch by pressing the “stop sketch, button” and go to “Settings”.
            +            </li>
            +            <li>
            +              Within settings we must find the “Accessibility” tab.
            +            </li>
            +            <li>
            +              In the “Accessibility” tab and under the “Accessible text-based canvas” section we can choose our preferred outputs.
            +            </li>
            +          </ul>
            +        </li>
            +      </ol>
            +      <p>
            +        Within “Settings” and under the “Accessibility” tab it is also possible to activate a lint warning sound that should make debugging easier. In “Settings” and under the  “General Settings” tab we can increase the size of the font and select a high contrast theme. After choosing our settings we can close the “Settings” window and go back to coding and playing our sketch.
            +      </p>
            +      <p>
            +        It is possible to add these accessible outputs to p5 sketches outside of the p5.js web editor by including the p5.accessibility.js library. <a  target="_blank" href="https://github.com/processing/p5.accessibility">You can learn more about the library here.</a>
            +      </p>
            +
            +      <h3>Keyboard Shortcuts</h3>
            +      <p>
            +        There are also ways to turn on the accessible outputs using keyboard shortcuts. Once we are on the code editor area we can use the following shortcuts (we have listed the shortcuts  for Windows computers, if you are using Mac OS please use the command key instead of control):
            +      </p>
            +      <ul class="list_view">
            +        <li>
            +          Shift + Control +1 - Turns on ALL the accessible output options, including audio
            +        </li>
            +        <li>
            +          Shift + Control +2 - Turns off ALL the accessible output options
            +        </li>
            +        <li>
            +          Control + Enter - This is used to run a sketch. If you already have accessibility options turned on, they will show up as well
            +        </li>
            +        <li>
            +          Shift + Control + Enter - This is used to stop a sketch.
            +        </li>
            +      </ul>
            +      <p>
            +        The full list of shortcuts is also available in the p5 web editor, under Keyboard Shortcuts in the Help and Feedback section of the menu
            +      </p>
            +
            +      <h1>Lessons</h1>
            +      <h2>Lesson 1: Hello World</h2>
            +      <p>
            +        In this section we go through some basic functions in p5 and look at how the screen reader will read the output.
            +
            +        There are two main functions we will use in our programs. The setup() function runs once, and is typically used for initialization, or for creating a program that does not need a loop running code repeatedly. The draw() function runs over and over again, and is used to perform a certain action repeatedly and for animation.
            +        Now we can open the editor: alpha.p5js.org and look for the code edit area. If you notice, there’s some code there already. Whenever you open the editor by default it will create a setup() function and a draw() function. However, for our first "Hello World" program we will take a step back and delete everything. Once we have a blank editor, we create a setup() block and add one line:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(200,200);
            +        }
            +      </code></pre>
            +
            +    <p>
            +      The createCanvas() function creates a canvas for us  to draw  or display the output. The canvas is the space on which the output is “drawn” or displayed. The code above creates a canvas of width and height 200 pixels. Since there is no movement, we will take a look only at the text and table outputs.
            +    </p>
            +    <h3>Text output for Lesson 1</h3>
            +    <p>
            +      Your output is a 200 by 200 white canvas containing the following 0 object
            +    </p>
            +    <h3>Table output for Lesson 1</h3>
            +    <p>
            +      white canvas is 200 by 200 of area 40000 contains 0 objects
            +    </p>
            +    <p>
            +      As expected, the outputs do not have any details apart from that of the canvas. Now, let’s move on to the next lesson where we add some basic shapes.
            +    </p>
            +
            +      <h2>Lesson 2: Basic Shapes</h2>
            +      <p>
            +        In this example, we will draw an ellipse on the top left, and a rectangle on the bottom right of the canvas of size 500 by 500 pixels. First, let's create the canvas and draw a shape in the setup function. Feel free to copy the code to the editor and run it.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        This code creates a canvas of 500 by 500 pixels and then draws an ellipse. The first 2 numbers we pass to the ellipse indicate where the center of the ellipse will be on the canvas. In this case, that is 50 and 50 pixels. The next 2 numbers indicate the width and height of the ellipse. In this case, they are both 20 pixels, implying we want to draw a circle. It is important to note that the top left corner of the canvas is point 0,0 pixels and the bottom right corner of the canvas is point 500,500 pixels.
            +      </p>
            +      <p>
            +        Now, we can also type this code a bit differently. We can create the canvas in the setup() function and draw the shape in the draw() function.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +        }
            +        function draw() {
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        In the previous case, the ellipse is drawn ONCE in setup and never again. But, in this case, the ellipse is drawn again and again in the canvas. Since, the numbers passed to the ellipse are the same each time, it doesn’t make a difference. However, if we wanted to change it’s position each time and make it move, then we would have to do it in draw.
            +      </p>
            +      <p>
            +        NOTE: remember, that everything in the canvas is drawn one over the other.
            +      </p>
            +      <p>
            +        In this case the output will be following:
            +      </p>
            +
            +      <h3>Text output for Lesson 2</h3>
            +      <p>
            +        The overview for the text output contains “Your output is a 500 by 500 white canvas containing the following 1 object:”.
            +      </p>
            +      <p>
            +        This description is followed by a list of elements where the shape, color, position, and area of each element are described (in this case: “white ellipse at top left covering 0.13% of the canvas” ). Each element can be selected to get more details. A table of elements is also provided. In this table, shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”).
            +      </p>
            +      <h3>Table output for Lesson 2</h3>
            +      <p>
            +        The overview for the table output contains “white canvas is 500 by 500 of area 250000 Contains 1 objects - 1 ellipse”
            +      </p>
            +      <p>
            +        This is followed by a table that describes the content spatially. It is a 10 by 10 table structure where each element is placed on a cell of the table depending on its position. Within each cell an element the color and type of shape of that element are available (example: “white ellipse”). These descriptions can be selected individually to get more details. A list of elements where shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”) is also available.
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rk4uO1bJX">basic shapes example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Lesson 3: Color</h2>
            +      <p>
            +        In these examples, we  look at different ways to add color to our sketch
            +        First, let’s look at ‘background()’. We can use this function to add a background color to the canvas. Copy the below code to try it out.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +      </code></pre>
            +      <p>
            +        Here, we have given the color in RGB format. In this format we can describe colors by saying how much, Red, Green and Blue the color has. RGB values must be integers between 0 and 255 with 0 being no color, and 255 highest amount of a certain color. The outputs will now contain “Red (255,0,0) canvas”.
            +      </p>
            +      <p>
            +        Now we can give color to our shapes using the function, fill().
            +      </p>
            +      <p>
            +        Copy the below code to try it out:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +
            +        function draw() {
            +          fill(200,50,8);
            +          ellipse(50,50,20,20);
            +          fill(20,250,8);
            +          ellipse(250,250,20,20);
            +          fill(20,150,250);
            +          ellipse(450,450,20,20);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now, in the plain text and grid output, we will notice that each shape is prepended with the color of the shape.
            +      </p>
            +
            +      <h3>Text output for Lesson 3</h3>
            +      <p>
            +        In the text output the overview is as follows
            +        “Your output is a 500 by 500 red(255,0,0) canvas containing the following 3 objects”
            +      </p>
            +      <p>
            +        After this we see the list of objects, with their color name and the RGB value. For example -  “crimson(200, 50, 8) ellipse at top left covering 0.13% of the canvas” Each object contains a link that when selected provides more details.
            +      </p>
            +
            +      <h3>Grid output for Lesson 3</h3>
            +      <p>
            +        The overview is as follows “red(255,0,0) canvas is 500 by 500 of area 250000 contains 3 0bjects - 3 ellipse”
            +      </p>
            +      <p>
            +        And in the table, we will find the objects in the grids corresponding to their location. “crimson(200,50,8) ellipse” and “green(20,250,8) ellipse”
            +      </p>
            +
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rJ-OSs-k7">color example on the p5 editor</a>
            +      </p>
            +
            +      <p>
            +        Instead of using Red, Green and Blue values, we can also pass just one value from 0 to 255. This is known as grayscale. It means that Red, Green and Blue will take the same value and the result will be between black and white. 0 being black, and 255 white.
            +      </p>
            +
            +      <h2>Lesson 4: Text</h2>
            +      <p>
            +        With p5, it is also possible to draw text on the canvas!
            +        We can add text to the canvas using the text() function. This function requires us input three values inside the parentheses: the text we want to display written between quotation marks, followed by the x and y position in pixels to display the text in the canvas.
            +      </p>
            +      <p>
            +        Copy and try out the below code.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(200);
            +        }
            +
            +        function draw() {
            +          fill(255,0,0);
            +          text("hello world!", 50,50)
            +        }
            +      </code></pre>
            +      <p>
            +        Note that fill() also affects text() and that the text we want to write has to be written between quotation marks. Now, let’s go through the output to see what it says.
            +      </p>
            +
            +      <h3>Text output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows  :
            +        “Your output is a 500 by 500 grey(200,200,200) canvas containing the following 1 object”
            +      </p>
            +      <p>
            +        Then there is a list of the objects. (For example - “hello world!” (red(255,0,0)) at top left of the canvas
            +      </p>
            +
            +      <h3>Grid output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows:
            +        “grey(200,200,200) canvas is 500 by 500 of area 250000 contains 1 object - 1 text”
            +      </p>
            +      <p>
            +        And in the table you will see the actual text and it’s color in the appropriate location (example - “hello world! (red(255,0,0))”
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/r1BFz3Zkm">text example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Exercise: Bar Graph</h2>
            +      <p>
            +        Now that we have covered how to draw basic shapes and write text on the canvas, let’s look at how we can create a bar chart with them.
            +      </p>
            +      <p>
            +        Using rectangles and some numbers, we can create bar graphs. Since we expect the entire sketch to be static, we can do the whole thing in the setup function
            +      </p>
            +      <p>
            +        Let’s start with a sample dataset that we want to depict.
            +      </p>
            +      <p>Animals in the park:</p>
            +      <ul class="list_view">
            +        <li>Dogs - 260</li>
            +        <li>Cats - 300</li>
            +        <li>Hamsters -100</li>
            +        <li>Rabbits - 50</li>
            +        <li>Spiders - 10</li>
            +      </ul>
            +
            +      <p>
            +        First we create a canvas:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        createCanvas(500,500);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now we can add some rectangles that represent each animal type. Notice that we will be adding comments in our code. Comments are lines in our code that are not executed and can be notes to ourselves. They start with // in the beginning of the line. We will create 5 rectangles, one for each animal type.
            +      </p>
            +
            +      <p>
            +        Remember that when we draw a rectangle, the first 2 values indicate the top left of the rectangle. If we want our bar graph to start on the left of our canvas, we need to calculate the numbers based on that. If we decide to make each bar with 50 pixels height, and to make the width represent the number of animals, for our first rectangle that represents the number of dogs the width would be 260 because there are 260 dogs. Then the values for this rectangle would be (0,0,260,50).
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	//We will use the fill() function to add color to the first bar of our chart.
            +        fill(255,0,0);
            +        //In this case our color is 255 red, 0 green, 0 blue.
            +        	rect(0, 0, 260, 50);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now let’s add the corresponding text:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	//Remember that the function text() requires the text, and the x, and y values for its position
            +        }
            +      </code></pre>
            +      <p>
            +        And voila! We just added the first bar on our graph chart.
            +      </p>
            +
            +      <h3>Text output for Bar Graph 1</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 2 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now lets add rectangles to represent 300 cats, 100 hamsters, 50 rabbits, and 10 spiders. Remember that the values for the function rect() in our case should be: rect(0, y position, number of animals, 50).
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	rect(0, 100, 300, 50); // here the second value, y position, is 100 so that we can draw the second bar under the first bar.
            +        	text('Cats - 300', 0, 175);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        The text output would be:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 2</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(red(255, 0, 0)) at top left</li>
            +      </ul>
            +      <p>
            +        Now we can add different colors to each bar:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	fill(0,255,0);
            +        	rect(0, 100, 300, 50);
            +        	text('Cats - 300', 0, 175);
            +        	fill(0,0,255);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	fill(200,100,0);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	fill(0,200,200);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +      <p>
            +        Our bar graph is ready! Here is the output:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 3</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>green(0, 255, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(green(0, 255, 0)) at top left</li>
            +        <li>blue( 0, 0, 255) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(blue( 0, 0, 255)) at top left</li>
            +        <li>orange(200, 100, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(orange(200, 100, 0)) at top left</li>
            +        <li>cyan( 0, 200, 200) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(cyan( 0, 200, 200)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now that we created a graph together you should be able to do it by yourself and share the results with your friends!
            +      </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/program-flow.html b/dist/hi/learn/program-flow.html
            new file mode 100644
            index 0000000000..da80b79608
            --- /dev/null
            +++ b/dist/hi/learn/program-flow.html
            @@ -0,0 +1,580 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This tutorial is written by Alex Yixuan Xu with reference to <em>Getting Started With p5.js</em> by Lauren McCarthy, Casey Reas, and Ben Fry. Copyright 2016 Maker Media, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">MDN JavaScript documentation</a> and <a href="https://www.w3schools.com/js">W3Schools JavaScript tutorials</a>. If you see any errors or have comments, please <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Program Flow</h1>
            +      <!-- TOPICS -->
            +      <!-- Branching: if/else -->
            +      <!-- Loops: for/while loop -->
            +      <!-- noLoop(), loop() and redraw() -->
            +      <!-- Asynchronicity in p5.js: intro to loadImage(), preload(), callbacks -->
            +      <!-- Loading JSON & APIs -->
            +      <!-- Functions and Callbacks: list of functions -->
            +      <!-- Interactivity and Event Listeners: list of event listeners such as mousePressed() -->
            +
            +
            +
            +      <!-- https://docs.microsoft.com/en-us/scripting/javascript/controlling-program-flow-javascript -->
            +      <p>This tutorial outlines some various techniques for controlling the sequence and timing of events in your code, which is known as program flow.</p>
            +
            +      <!-- if/else stuff -->
            +      <h2>Branching</h2>
            +      <!-- https://www.w3schools.com/js/js_if_else.asp -->
            +      <p>We can use conditional statements to control the program flow. Conditional statements perform different actions based on tests for different conditions. JavaScript has the following conditional statements:</p>
            +      <ul class="list_view">
            +        <li>Use <em>if</em> to specify a block of code to be executed, if a specified condition is true</li>
            +        <li>Use <em>else</em> to specify a block of code to be executed, if the same condition is false</li>
            +        <li>Use <em>else if</em> to specify a new condition to test, if the first condition is false</li>
            +      </ul>
            +      <p>In the following example, change the value for variable i to change the color of the rectangle. If i equals to 0, the condition for the <em>if</em> statement is satisfied, and the filling color is red. In this case, the program continues to draw the rectangle skipping the <em>else if</em> and <em>else</em> statements. If i equals to 1, the condition for the <em>if</em> statement is not satisfied, and the program moves on to check the condition for the <em>else if</em> statement. Since <em>else if</em> condition is satisfied, the filling color is green. If neither the <em>if</em> nor the <em>else if</em> conditions are satisfied, the program runs the <em>else</em> statement, and the filling color is blue.</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0; // change the value of i to see the change
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  background(200);
            +  if (i==0){
            +    fill(255, 0, 0);
            +  }
            +  else if (i==1){
            +    fill(0, 255, 0);
            +  }
            +  else{
            +    fill(0, 0, 255);
            +  }
            +  rect(width/2, height/2, 50, 50);
            +}
            +      </script>
            +
            +      <!-- for loop and while loop -->
            +      <h2>Loops</h2>
            +      <p>Loops can execute a block of code repeatedly. p5 supports several different kinds of loops in JavaScript:</p>
            +      <ul class="list_view">
            +        <li>for - loops through a block of code a specified number of times</li>
            +        <li>for/in - loops through the properties of an object</li>
            +        <li>while - loops through a block of code while a specified condition is true</li>
            +        <li>do/while - also loops through a block of code while a specified condition is true</li>
            +      </ul>
            +
            +      <p>The <em>for</em> loop sets up a variable (usually i or x) that is then incrementally changed for each loop. It has the following structure:</p>
            +      <pre><code class="language-javascript">
            +        for (statement 1; statement 2; statement 3) {
            +            code block to be executed
            +        }
            +      </code></pre>
            +      <ul class="list_view">
            +        <li>Statement 1 is executed (one time) before the execution of the code block. It sets the starting value for the variable</li>
            +        <li>Statement 2 defines the condition that must be true for the code block to be executed.</li>
            +        <li>Statement 3 is executed every time  after the code block has finished running if statement 2 evaluated to be true.</li>
            +      </ul>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  for (let i=0; i<5; i++){
            +    text(i, i*10, height/2);
            +  }
            +}
            +      </script>
            +      <p>In this example, variable i is initially set to 0. Every time the <em>for</em> loop runs, i is displayed on the screen and 1 is added to i. Note the <em>for</em> loop will only run until i equals to 4 because after this the condition that i be less than 5 will be false.</p>
            +
            +      <p>The <em>for/in</em> statement loops through the properties of an object:</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let person = {fname:"John", lname:"Doe", age:25};
            +let myText = "";
            +function setup(){
            +  let x;
            +  for (x in person) {
            +      myText += person[x];
            +      myText += " ";
            +  }
            +  text(myText, 0, height/2);
            +}
            +      </script>
            +      <p>In this example, as the <em>for</em> loop cycles through each property of the person object, the property value is added to myText string.</p>
            +
            +      <p>The while loop cycles through a block of code as long as its specified condition is true.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  while (i<5){
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +}
            +      </script>
            +      <p>This example gives the same result as the <em>for</em> loop example above. Sometimes <em>while</em> loops and <em>for</em> loops can be used interchangeably.</p>
            +
            +      <p>The <em>do/while</em> loop is a variant of the <em>while</em> loop. This loop will execute the code block once, before checking if the condition is true, it will then repeat the loop as long as the condition is true.</p>
            +      <!-- Is there an example particular to do/while? -->
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  do {
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +  while (i < 5);
            +}
            +      </script>
            +
            +
            +      <!-- this is particular to p5 -->
            +      <h2>noLoop(), loop() and redraw()</h2>
            +      <p>The <a href="/reference/#/p5/draw">draw()</a> function in p5 runs as a loop. The code inside the draw() function runs continuously from top to bottom until the program is stopped. The draw() loop may be stopped by calling <a href="/reference/#/p5/noLoop">noLoop()</a>, and can then be resumed with <a href="/reference/#/p5/loop">loop()</a>. If using <a href="/reference/#/p5/noLoop">noLoop()</a> in <a href="/reference/#/p5/setup">setup()</a>, it should be the last line inside the block.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(200);
            +  ellipse(x, height/2, 20, 20);
            +  x ++;
            +}
            +function mousePressed() {
            +  loop();
            +}
            +function mouseReleased() {
            +  noLoop();
            +}
            +        </script>
            +        <p>In this example, <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a>, so the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. Since <a href="/reference/#/p5/loop">loop()</a> is placed in <a href="/reference/#/p5/mousePressed">mousePressed()</a>, the draw() block will resume looping when mouse is pressed. When mouse is released, <a href="/reference/#/p5/noLoop">noLoop()</a> is called again and hence the draw() loop stops.</p>
            +
            +        <p>The function <a href="/reference/#/p5/redraw">redraw()</a> executes the code within <a href="/reference/#/p5/draw">draw()</a> one time. This functions allows the program to update the display window only when necessary, such as when an event registered by <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/keyPressed">keyPressed()</a> occurs. In structuring a program, it only makes sense to call <a href="/reference/#/p5/redraw">redraw()</a> within events such as <a href="/reference/#/p5/mousePressed">mousePressed()</a> outside of the draw() loop. The redraw() function does not work properly when called inside draw(). In addition, you can set the number of loops through draw by adding a single argument (an integer) to the redraw() function.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +   createCanvas(100, 100);
            +   noLoop();
            + }
            +function draw() {
            +   background(200);
            +   ellipse(x, height/2, 20, 20);
            +   x ++;
            + }
            +function mousePressed() {
            +   redraw();
            + }
            +      </script>
            +      <p>This example is similar to the previous one, where <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a> and the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. However, when mouse is pressed, <a href="/reference/#/p5/redraw">redraw()</a> is called and <a href="/reference/#/p5/draw">draw()</a> will only loop once. To make smooth animations, it is easier to work with noLoop() and loop().</p>
            +
            +
            +      <h2>Asynchronicity in p5.js</h2>
            +      <p>In JavaScript, events may occur concurrently with the main program flow. This is considered as asynchronicity in programming. In p5, for example, when we use <a href="/reference/#/p5/loadImage">loadImage()</a> in <a href="/reference/#/p5/setup">setup()</a>, the browser begins the process of loading the image but skip onto the next line before it is finised loading. The following example demonstrates such asynchronicity.</p>
            +        <pre><code class="language-javascript">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +    </code></pre>
            +    <iframe src="/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.html" width="150" height="150"></iframe>
            +      <!-- what's the file location??????????????????? -->
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p>When you run this program, you'll notice that the drawing canvas is grey with no image displayed. This is because <a href="/reference/#/p5/loadImage">loadImage()</a> begins to load the image, but does not have time to finish this task before the program continues on through the rest of <a href="/reference/#/p5/setup">setup()</a> and on to <a href="/reference/#/p5/draw">draw()</a>. Even with the <a href="/reference/#/p5/noLoop">noLoop()</a> function that stops p5.js from continuously executing the code within draw(). The <a href="/reference/#/p5/image">image()</a> function is unable to display the image as it is not properly loaded.</p>
            +
            +      <h2>Introduction to Preload</h2>
            +      <p>To help with this issue of asynchronicity, p5.js has the <a href="/reference/#/p5/preload">preload()</a> function. Unlike <a href="/reference/#/p5/setup">setup()</a>, preload() forces the program to wait until everything has loaded before moving on. It is best to only make load calls in preload(), and do all other setup in setup().</p>
            +      <pre><code class="language-javascript">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.html" width="150" height="150"></iframe>
            +
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p><a href="/reference/#/p5/preload">preload()</a> ensures that the image has been loaded before running the other code. </p>
            +
            +
            +
            +      <h2>Loading with a Callback</h2>
            +      <p>An alternative to <a href="/reference/#/p5/preload">preload()</a> is to use a <em>callback function</em>. A callback function is a function that is passed as an argument to a second function, and that runs after the second function has completed. The following example illustrates this technique.</p>
            +      <pre><code class="language-javascript">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.html" width="150" height="150"></iframe>
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </script> -->
            +      <p>In this example, the second argument in <a href="/reference/#/p5/loadImage">loadImage()</a> is the function we want to run after the load is complete. Once the image has loaded, this callback function, drawImage(), is automatically called. It has one argument which contains the image that was just loaded. There is no need to create a global variable to hold the image. The image is passed directly into the callback function, as the parameter name chosen in the function definition.</p>
            +
            +
            +
            +      <h2>Loading JSON & APIs</h2>
            +      <!-- page 187 -->
            +      <p>The JSON (JavaScript Object Notation) format is a common system for storing data. Like HTML and XML formats, the elements have labels associated with them. One way to load JSON file is to use <a href="/reference/#/p5/loadJSON">loadJSON()</a> function in <a href="/reference/#/p5/preload">preload()</a>.</p>
            +      <!-- example where loadJSON() in preload() -->
            +      <p>The following request at https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson returns data of recent earthquakes in the world from USGS.</p>
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let earthquakes;
            +function preload(){
            +  earthquakes = loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson');
            +}
            +function setup(){
            +  createCanvas(200, 100);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +
            +      <p>Alternatively, <a href="/reference/#/p5/loadJSON">loadJSON()</a> can also take a callback. To use data from an API, you may need a callback function as, like with an image, the data takes time to load. API (Application Programming Interface) requests are commands that request data from a service. A lot of APIs will return data in JSON format. Some need you to authenticate with the API to use it (e.g. register as a developer and get keys). You can’t always use <a href="/reference/#/p5/preload">preload()</a> when getting data from APIs because the data might change while you sketch is running and you will want your program to respond accordingly.</p>
            +
            +      <p><a href="/reference/#/p5/loadJSON">loadJSON()</a> can be used in a few ways: </p>
            +      <ul class="list_view">
            +        <li>loadJSON(path)</li>
            +        <li>loadJSON(path, callback)</li>
            +        <li>loadJSON(path, callback, datatype)</li>
            +        <li>loadJSON(path, callback, errorCallback)</li>
            +        <li>loadJSON(path, datatype, callback, errorCallback)</li>
            +        <li>loadJSON(path, jsonpOptions, datatype, callback, errorCallback)</li>
            +      </ul>
            +      <p>
            +        where:
            +      </p>
            +      <ul class="list_view">
            +        <li>path - String: name of the file or url to load</li>
            +        <li>jsonpOptions - Object: options object for jsonp related settings</li>
            +        <li>datatype - String: "json" or "jsonp"</li>
            +        <li>callback - Function: function to be executed after loadJSON() completes, data is passed in as first argument</li>
            +        <li>errorCallback - Function: function to be executed if there is an error, response is passed in as first argument</li>
            +      </ul>
            +      <!-- example where loadJSON() takes a callback -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(200, 100);
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +      <p>In this example, the <a href="/reference/#/p5/loadJSON">loadJSON()</a> function is placed in <a href="/reference/#/p5/setup">setup()</a> and takes a custom callback function showEarthquake(). This means when the program finishes loading the JSON file from the USGS earthquakes API, the function showEarthQuake() is called. The place and magnitude of the most recent earthquake listed by the API is stored in local variables within showEarthquake and are then displayed on the screen.</p>
            +
            +      <p>Sometimes we use <a href="/reference/#/p5/setInterval">setInterval()</a> to control the frequency of requests made to the API. setInterval() can also take a callback function. If you call setInterval() in <a href="/reference/#/p5/setup">setup()</a>, it will run repeatedly for the duration of the program at the interval set.</p>
            +      <!-- example setInterval() is used -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let i=1; // counter variable to keep track of the interval
            +function setup() {
            +  createCanvas(200, 100);
            +  getEarthquake();
            +  setInterval(getEarthquake, 5000); // get data every 5 seconds
            +}
            +function getEarthquake(){
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  background(255);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text("Data grabbed "+i, 0, height/3);
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +  i++;
            +}
            +      </script>
            +      <p>In this example, the earthquake data is grabbed from the API every 5 seconds and is displayed on the screen.</p>
            +
            +
            +
            +
            +      <!-- list the functions that accept callbacks? Is this section necessary?-->
            +      <h2>More Callback Functions</h2>
            +      <p>In addition to the <a href="/reference/#/p5/loadImage">loadImage()</a>, <a href="/reference/#/p5/loadJSON">loadJSON()</a> and <a href="/reference/#/p5/setInterval">setInterval()</a>, there are other functions in p5 that accept callbacks. Typically, functions that involve loading data of some kind accept callbacks, or should be put in <a href="/reference/#/p5/preload">preload()</a>. For example:</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/loadFont">loadFont()</a></li>
            +        <li><a href="/reference/#/p5/loadSound">loadSound()</a></li>
            +        <li><a href="/reference/#/p5/loadStrings">loadStrings()</a></li>
            +        <li><a href="/reference/#/p5/loadTable">loadTable()</a></li>
            +        <li><a href="/reference/#/p5/loadXML">loadXML()</a></li>
            +        <li><a href="/reference/#/p5/loadBytes">loadBytes()</a></li>
            +        <li><a href="/reference/#/p5/loadModel">loadModel()</a></li>
            +      </ul>
            +
            +      <p>DOM functionality makes it easy to interact with other HTML5 objects, including text, hyperlink, image, input, video, audio, and webcam. Some DOM creation methods also accept callbacks: </p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/createImg">createImg()</a></li>
            +        <li><a href="/reference/#/p5/createFileInput">createFileInput()</a></li>
            +        <li><a href="/reference/#/p5/createVideo">createVideo()</a></li>
            +        <li><a href="/reference/#/p5/createAudio">createAudio()</a></li>
            +        <li><a href="/reference/#/p5/createCapture">createCapture()</a></li>
            +      </ul>
            +
            +
            +      <h2>Interactivity and Event Listeners</h2>
            +      <p>Callback functions are functions that can be passed as an argument into another function and be executed after the first function is complete. An event listener or handler is a type of callback. It is called whenever an event occurs such as when the mouse is pressed, or a key is pressed etc.</p>
            +      <p>Mouse functions like <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, etc. can be used as event listeners. They can be attached to certain elements in a sketch.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseWheel">mouseWheel()</a> - Code inside this block is run once when mouse wheel is scrolled over the element</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>In this example, a canvas element is created and an event listener <a href="/reference/#/p5/mousePressed">mousePressed()</a> is attached. Function changeGrey() will only run when the mouse is pressed over the canvas, and will will change the background color to a random grey. If the mouse is pressed anywhere, even outside of the canvas, the diameter of the ellipse will increase by 10 pixels. The custom function changeGray(), in this instance, is placed within the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function and is to be triggered when mouse is pressed over the canvas element. If the mouse is not pressed, false is passed and changeGrey() will not run.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +
            +      <p>The above mouse functions can be attached to an element like the canvas or can be used without specifying an element. The keyboard functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyReleased">keyReleased()</a>, <a href="/reference/#/p5/keyTyped">keyTyped()</a>, and mouse function <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> cannot be attached to a specific element.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block runs once when the mouse is moved and the mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block runs once when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is runs once when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is runs once when any key is released</li>
            +      </ul>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/tdd.html b/dist/hi/learn/tdd.html
            new file mode 100644
            index 0000000000..6dc9ae7bcb
            --- /dev/null
            +++ b/dist/hi/learn/tdd.html
            @@ -0,0 +1,660 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Unit Testing and Test Driven Development</h1>
            +      <div class="attribution">
            +        This tutorial was written by <a href='https://github.com/andrewjtimmons'>Andy Timmons</a>.
            +      </div>
            +
            +      <h2>Overview</h2>
            +      <p>
            +        This tutorial will walk you through setting up your development environment to run unit tests against your code. Unit testing is a method of applying tests to the classes and functions in your code. It can catch bugs, help you collaborate with others, and code faster. Test driven development is a method of writing your tests before you write code so you have all of your tests when you finish.
            +      </p>
            +      <p>
            +        This tutorial is intended for people who:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>Have written p5.js sketches before.</li>
            +          <li>Are comfortable using javascript <a href='http://p5js.org/examples/structure-functions.html'>functions.</a></li>
            +          <li>Can run basic terminal commands.  If you are not familiar using a terminal here is a <a href='http://lifehacker.com/5633909/who-needs-a-mouse-learn-to-use-the-command-line-for-almost-anything'>good tutorial for getting comfortable.</a></li>
            +        </ul>
            +
            +      <h2> Why unit test?</h2>
            +      <p>
            +        In late 1998 NASA launched the Mars Climate Orbiter in collaboration with Lockheed Martin. This robotic space probe cost 193 million dollars and took one year to arrive and establish its orbit around Mars. Minutes later it crashed into Mars and exploded. NASA later determined it was a software error. The Lockheed Martin navigation code gave measurements in English units like feet, and the NASA code expected the measurements to be in metric units like meters. The difference between the two caused the crash. [<a href='https://en.wikipedia.org/wiki/Mars_Climate_Orbiter'>Citation</a>]
            +      </p>
            +      <p>
            +        Unit testing could have prevented this error and while you might not be launching spaceships (but by all means please try), unit testing can prevent a lot of headaches from the outset of your project to install day. It can help you:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>improve your design and reduce bugs</li>
            +          <li>collaborate with others</li>
            +          <li>finish your project faster</li>
            +        </ul>
            +
            +      <h2>Setting up for unit testing</h2>
            +      <p>
            +        Installing node:
            +      </p>
            +        <ol>
            +          <li>First you must install node. If you already have node installed this assumes you are using version 4 or higher.  Node is a open source runtime environment for building server side applications.  Don’t worry if that sentence didn’t make sense.  You don’t have to understand all there is to know about node to do this tutorial.  If you are curious to learn more you can read the <a href='https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io'>p5.js node tutorial.</a></li>
            +          <li>On Mac, Linux, Windows:  Go to <a href='https://nodejs.org/en/'>https://nodejs.org/en/</a> and download the installer.  Open the installer and follow the directions.</li>
            +          <li>
            +            Once the installer finishes open a terminal and run the following command to verify it installed correctly.  You should see something like "v6.6.0" or some other numbers that indicate the version you installed.<br />
            +            <pre><code class="language-javascript">
            +            node -v
            +            </code></pre>
            +          </li>
            +        </ol>
            +      <p>
            +        Update npm, the Node Package Manager.  Npm is a program that allows you to install software libraries that are compatible with node.  In your open terminal run the command:
            +        <pre><code class="language-javascript">
            +          sudo npm install npm@latest -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the chai assertion library.  This is what you will use to build your tests.  In the terminal window run the command:
            +        <pre><code class="language-javascript">
            +          npm install chai -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the mocha test running library.  Mocha drives your chai tests.  Much like a person drives a car.  In the terminal window run:
            +        <pre><code class="language-javascript">
            +          npm install mocha -g
            +        </code></pre>
            +      </p>
            +
            +      <h2>A sketch without tests</h2>
            +      <p>
            +        Your goal today is to make a sketch with a square whose fill color loops over every RGB color.
            +      </p>
            +      <p>
            +        Let’s set up the project. This is what it would look like without any unit tests.
            +      </p>
            +        <ol>
            +          <li>Make a folder called color_unit_test and open it</li>
            +          <li>
            +            Make a file called index.html and type the following code.  While you can just copy/paste it, typing it out will help you understand what it is doing better.  It is worth the time!<br />
            +            <pre><code class="language-javascript">
            +              &lt;!DOCTYPE html&gt;
            +              &lt;html&gt;
            +              &lt;head&gt;
            +                &lt;meta charset="UTF-8"&gt;
            +                &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
            +                &lt;script src="https://cdn.jsdelivr.net/npm/p5@0.4.20/lib/p5.js"&gt;&lt;/script&gt;
            +                &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +                &lt;style&gt; body {padding: 0; margin: 0;} &lt;/style&gt;
            +              &lt;/head&gt;
            +              &lt;body&gt;
            +              &lt;/body&gt;
            +              &lt;/html&gt;
            +            </code></pre>
            +          </li>
            +          <li>
            +            make a file called sketch.js and put in the following code<br />
            +            <pre><code class="language-javascript">
            +              // This is for a unit test tutorial.
            +              // it should create a rectangle and allow you to iterate over
            +              // every single color.
            +              //
            +              // colorValueIncrease sets the amount the color changes on each
            +              // draw loop. Values greater than 255 will break the sketch.
            +              // fillColor will be the color of the rectangle.
            +              // colorIncreaser will become an instance of our ColorIncreaser class.
            +
            +              let colorValueIncrease = 1;
            +              let fillColor;
            +              let colorIncreaser;
            +
            +              function setup() {
            +                createCanvas(500, 500);
            +                background(0);
            +                fillColor = color(0, 0, 0, 255);
            +                noStroke();
            +              }
            +
            +              function draw() {
            +                fill(fillColor);
            +                rect(0, 0, 500, 500);
            +
            +                // increment the red value
            +                fillColor.levels[0] += colorValueIncrease;
            +                // If the red value is maxed out increment the green value
            +                // and reset the red value.
            +                if (fillColor.levels[0] > 255) {
            +                  fillColor.levels[0] = 0;
            +                  fillColor.levels[1] += colorValueIncrease;
            +                }
            +                // If the green value is maxed out increment the blue value
            +                // and reset the green value.
            +                if (fillColor.levels[1] > 255) {
            +                  fillColor.levels[1] = 0;
            +                  fillColor.levels[2] += colorValueIncrease;
            +                }
            +                // If the blue value is maxed out reset the green value.
            +                if (fillColor.levels[2] > 255) {
            +                  fillColor.levels[2] = 0;
            +                }
            +              }
            +            </code></pre>
            +          </li>
            +          <li>
            +           Open the index.html file in your browser (you don’t need to run a local server in this case). You should see a black box become red and then black again. This is the basis of looping over all the RGB colors. The problem you face is that there are 256 values for red, green, and blue, which means there are over 16 million combinations of colors! You can make this faster. However, making this faster will cause flashing lights which might give some people headaches or seizures. Please only increase this value if you do not have issues with flashing lights. The rest of the tutorial should be fine.  In the sketch.js file change the<pre><code class="language-javascript">let colorValueIncrease = 33;</code></pre> and reload the page. However this still doesn’t guarantee this is working properly. You don’t have time to watch all the colors change nor can you tell yourself if it is iterating through the millions of colors. Change the colorValueIncrease variable back to 1 before you move on.
            +          </li>
            +          <li>
            +            At 30 draw loops per second it would take over six days to loop through all of the colors. You certainly don’t have time to do that once, and would never be able to check and see if it worked every time you updated our code. What if you accidentally change something in our draw loop that breaks the code right before install?  You wouldn’t know until it was live and everyone saw your sketch break.
            +          </li>
            +        </ol>
            +
            +      <h2>Your first unit tests</h2>
            +      <p>
            +        Unit testing can help us out here. The majority of the time spent in this program is the actual drawing of the pixels. Adding 1 and checking a few if statements is very fast if you don’t need to draw the actual pixels. So you can check if the color values increase as expected without having to actually watch them all increase on your screen.
            +      </p>
            +      <p>
            +        In the folder called color_unit_test that you already created, make a new folder called test.  Open the test folder and make a file called test.js.  Type this code into test.js
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +
            +
            +          // Create the variable you are going to test
            +          let p5js = 'awesome';
            +
            +
            +          // describe lets you comment on what this block of code is for.
            +          describe('these are my first tests for p5js', function() {
            +
            +
            +            // it() lets you comment on what an individual test is about.
            +            it('should be a string', function(done) {
            +              // expect is the actual test.  This test checks if the var is a string.
            +              expect(p5js).to.be.a('string');
            +              // done tells the program the test is complete.
            +              done();
            +            });
            +
            +
            +            it('should be equal to awesome', function(done) {
            +              // This expect tests the value of the string.
            +              expect(p5js).to.equal('awesome');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your command line and <a href='http://ss64.com/bash/cd.html'>cd</a> into the main directory of our sketch called color_unit_test.  Type the command
            +        <pre><code class="language-javascript">mocha</code></pre>
            +      </p>
            +      <p>
            +        into the command line and watch your first test run!  You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              ✓ should be a string
            +              ✓ should be equal to awesome
            +            2 passing (14ms)
            +        </code></pre>
            +      </p>
            +      <p>
            +        Let's look at what happens when tests fail. Change line 6 in test.js from:
            +        <pre><code class="language-javascript">let p5js = 'awesome';</code></pre>
            +      </p>
            +      <p>
            +        to
            +        <pre><code class="language-javascript">let p5js = 42;</code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your terminal and run the mocha command again. You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              1) should be a string
            +              2) should be equal to awesome
            +
            +            0 passing (18ms)
            +            2 failing
            +
            +            1) these are my first tests for p5js should be a string:
            +               AssertionError: expected 42 to be a string
            +                at Context.<anonymous> (test/test.js:14:24)
            +
            +            2) these are my first tests for p5js should be equal to awesome:
            +               AssertionError: expected 42 to equal 'awesome'
            +                at Context.<anonymous> (test/test.js:21:21)
            +        </code></pre>
            +      </p>
            +      <p>
            +        What is nice about these errors is:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>They tell you the name of the test that you put in the describe() and it() functions</li>
            +          <li>They tell you what they expected with AssertionError: expected 42 to be a string</li>
            +          <li>They tell you what file and line of code had the problem test/test.js:14:24</li>
            +        </ul>
            +      <p>
            +        Now that you know the basics of unit testing you are ready to write some tests against your code and refactor your sketch!
            +      </p>
            +
            +      <h2>Test Driven Development</h2>
            +      <p>
            +        You are going to use Test Driven Development for the rest of this tutorial.  The idea is you write your unit tests first, run them and watch them fail, and then add code to sketch.js to make the tests pass.  This way you ensure your code is working as you expect every step of the way and that new code doesn’t break old code.  Your goal is to create a ColorIncreaser class that:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>takes in an integer as the value to increase each time called colorValueIncrease.</li>
            +          <li>takes in an instance of the <a href='http://p5js.org/reference/#/p5/color'>p5 color class.</a></li>
            +          <li>has a function to increase the values in the color by the value in colorValueIncreases.</li>
            +        </ul>
            +      <p>
            +        Delete everything in test.js and replace it with this
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +          // Import our ColorIncreaser class.
            +          const ColorIncreaser = require('../sketch');
            +
            +          describe('ColorIncreaser tests', function() {
            +            // Will hold the reference to the ColorIncreaser class
            +            let colorIncreaser;
            +
            +            // beforeEach is a special function that is similar to the setup function in
            +            // p5.js.  The major difference it that this function runs before each it()
            +            // test you create instead of running just once before the draw loop
            +            // beforeEach lets you setup the objects you want to test in an easy fashion.
            +            beforeEach(function() {
            +                colorIncreaser = new ColorIncreaser();
            +            });
            +
            +            it('should be an object', function(done) {
            +              expect(colorIncreaser).to.be.a('object');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command in your terminal and watch your new test fail!  The crux of the error is “TypeError: ColorIncreaser is not a constructor”.  This makes sense because you have not created a ColorIncreaser class in our sketch yet. <br />
            +
            +        Go to the bottom of your sketch.js file, below the closing bracket } for the draw function, and add this:
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor() {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +            }
            +          }
            +
            +          module.exports = ColorIncreaser;
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  The function line will be our color increasing object.  The module.exports line is what allows our test.js file to import our ColorIncreaser with the line you already added that looks like this:
            +        <pre><code class="language-javascript">
            +           const ColorIncreaser = require('../sketch');
            +        </code></pre>
            +      </p>
            +      <p>
            +        If you go back to your terminal and run mocha your test should pass.<br />
            +
            +        Now get your ColorIncreaser function to actually do something.  Start by storing the colorValueIncrease as a variable in your class.  Before you change the code in sketch.js you have to write your tests.  Change the beforeEach function in test.js to look like this
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        and add a new it() test below it like this
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command and you will get the pivotal line:<br />
            +        AssertionError: expected undefined to equal 1<br />
            +        because you have not added this to your class yet. You need to add that value to get this to work. Add this line to the setup function in sketch.js under noStroke();
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +        </code></pre>
            +        and change the ColorIncreaser function to look like this
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser() {
            +            constructor(colorValueIncrease) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +            }
            +          }
            +        </code></pre>
            +        Let’s run the mocha test again.  It should pass!
            +      </p>
            +
            +      <h2>Testing when your object is composed of other objects</h2>
            +      <p>
            +        Now you need to add an instance of the p5 color class to our ColorIncreaser. However, for your tests, you don’t want to use an actual instance of the color() class because you don’t want to test external dependencies given by another library.You just want to make sure that your increment function works. So you are going to create what is called a mock of the p5 color class so you can test without worrying about the implementation of code you didn’t write.
            +      </p>
            +      <p>
            +        The original way of incrementing colors just used the color.levels and changed the red, green and blue values at index [0], [1], and [2].  You can see this in the draw function in sketch.js.  The implementation of color just stores those values in a javascript array so you can mock it out very easily.  Put this code in test.js below the const ColorIncreaser = require… line and above the describe line
            +        <pre><code class="language-javascript">
            +          function mockColor(red, green, blue, alpha) {
            +              // Mock of the color class from p5
            +              this.levels = [];
            +              this.levels[0] = red;
            +              this.levels[1] = green;
            +              this.levels[2] = blue;
            +              this.levels[3] = alpha;
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Update your beforeEach() function
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              let fillColor = new mockColor(0, 0, 0, 255);
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And update the it('should initialize without mutation', function block
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[3]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And run the tests!  Failure!   TypeError: Cannot read property 'levels' of undefined<br />
            +        You have to update the ColorIncreaser class to take in a fillColor variable.  It is an easy fix.  In sketch.js change the colorIncreaser line in setup() to look like this
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +        </code></pre>
            +      </p>
            +      <p>
            +        and update the ColorValueIncreaser function
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor(colorValueIncrease, fillColor) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +              this.fillColor = fillColor;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Run the tests again and they should pass!
            +      </p>
            +      <p>
            +        Now you have all the initialized variables you need to make the class work.  This provides the scaffold on which you will build your method to increase the color value and iterate over every color.
            +      </p>
            +
            +      <h2>Testing class methods</h2>
            +      <p>
            +        You are going to make a class method called increaseFillColor. It will basically run the code that is currently in our draw loop, but use the values stored in our ColorIncreaser class to do it.
            +      </p>
            +      <p>
            +        As covered before there are 256 values for red, green and blue giving 16,777,216 color combinations. While that might seem overwhelming you can test it easily because you know what values should be present in red, green and blue after each time you call our increaseFillColor function. For example if you start with the color black with the rgb levels 0,0,0 and you call increaseFillColor once you know you should now have the values 1,0,0.  So you are going to add tests in test.js for calling increaseFillColor 255, 65535 and 16777215 times.
            +        <pre><code class="language-javascript">
            +          it('should have rgb values 255, 0, 0 after calling increaseFillColor 255 times', function(done) {
            +            //it is 256^1 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 255; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 0 after calling increaseFillColor 65535 times', function(done) {
            +            //it is 256^2 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 65535; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 255 after calling increaseFillColor 16777215 times', function(done) {
            +            //it is 256^3 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 16777215; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And when you run mocha the tests will fail because that function does not exist!  Let’s add a skeleton function in sketch.js inside the ColorIncreaser class below the constructor function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Now when you run mocha the tests fail for a different reason.  It finds the function, but it doesn’t do what you expect it to.  Let’s change the function in sketch.js to look like what is inside the draw function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +
            +            this.fillColor.levels[0] += this.colorValueIncrease
            +            this.numColorsSoFar += 1
            +
            +
            +            if (this.fillColor.levels[0] > 255) {
            +              this.fillColor.levels[0] = 0
            +              this.fillColor.levels[1] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[1] > 255) {
            +              this.fillColor.levels[1] = 0
            +              this.fillColor.levels[2] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[2] > 255) {
            +              this.fillColor.levels[2] = 0;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        And now your tests pass!  Hooray!<br />
            +        Now you just need to get the draw function set up.  Replace the draw function in sketch.js with this:
            +        <pre><code class="language-javascript">
            +          function draw() {
            +            fill(colorIncreaser.fillColor);
            +            rect(0, 0, 500, 500);
            +            colorIncreaser.increaseFillColor()
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        All tests should pass now and you can expect your code to behave as you want!  As a bonus when you change the code in the future the tests will let you know that it still works as intended!<br />
            +        Congratulations, you made it to the end! Unit tests and Test Driven Development are powerful ways to build code that you know works just as you expect. <br />
            +        You can continue to build on your skills by
            +      </p>
            +        <ul class="bullet-list">
            +          <li>adding tests to your own sketches and projects</li>
            +          <li>Reading up on the tools we’ve used here:</li>
            +          <ul class="bullet-list">
            +            <li><a href='http://www.agiledata.org/essays/tdd.html'>Test Driven Development and Unit tests</a></li>
            +            <li><a href='https://www.npmjs.com/'>Node Package Manager (NPM)</a></li>
            +            <li><a href='http://chaijs.com/'>Chai</a></li>
            +            <li><a href='https://mochajs.org/'>Mocha</a></li>
            +            <li><a href='https://en.wikipedia.org/wiki/Mock_object'>Mock Objects</a></li>
            +          </ul>
            +        </ul>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/test-tutorial.html b/dist/hi/learn/test-tutorial.html
            new file mode 100644
            index 0000000000..f2df4c2165
            --- /dev/null
            +++ b/dist/hi/learn/test-tutorial.html
            @@ -0,0 +1,178 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>test tutorial title</h1>
            +
            +      <p>Blah blah blah. Here is some formatted code:</p>
            +
            +      <pre><code class="language-javascript">
            +      var note = "this is formatted code!";
            +      </code></pre>
            +
            +      <p>Blah blah blah. Here is an iframe embedded:</p>
            +
            +      <iframe src="../../assets/learn/test-tutorial/embed.html" width="600" height="400"></iframe>
            +
            +      <p>Blah blah blah. Here is p5-widget embedded:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +
            +function draw() {
            +  background(255, 0, 200);
            +}
            +</script>
            +
            +      <p>The end!</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/transformations.html b/dist/hi/learn/transformations.html
            new file mode 100644
            index 0000000000..9b6e547146
            --- /dev/null
            +++ b/dist/hi/learn/transformations.html
            @@ -0,0 +1,615 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by Gene Kogan. It was ported to P5 by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +
            +      </div>
            +
            +      <h1>Transformations</h1>
            +
            +      <p>
            +      The p5.js canvas works like a piece of graph paper. When you want to draw something, you specify its coordinates on the graph. For example, we can draw a 40x40 pixel rectangle at the point (30, 30).
            +      </p>
            +
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      If you want to move your rectangle 50 pixels to the right and 50 pixels down, you can add that to the x and y-coordinates of the rectangle and run rect(80, 80, 40, 40). But there is another way to do this:
            +      move the graph paper itself. If you move the graph paper 50 pixels right and 50 pixels down, you will get exactly the same visual result. Moving the coordinate system is called translation, and can be done using the translate() function.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	translate(50, 50);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      As far as the rectangle is concerned, it hasn't moved at all. Its upper left corner is still at (30, 70). When you use transformations, the things you draw never change position; the coordinate system itself does. We will see how this can be useful in the next section.
            +    </p>
            +      <h2>push() and pop()</h2>
            +
            +      <p>
            +      Sometimes, a sketch will involve multiple translations to draw the same thing in different locations. If we want to draw the same rectangle in three separate locations -- say at (25, 25), (50, 75), and (75, 100) -- we can use push() and pop() to
            +      keep track of and revert our translations as we go. The function pop() undoes all translations made following the previous push(). push() and pop() also track and revert style and,  color changes -- fill(), stroke(), etc -- in the same way. Thus all translations
            +      and style/color commands made between a single push() and pop() apply only to the operations made between them. Take a look at the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw() {
            +	background(240);
            +
            +	push();
            +  	translate(25, 25);
            +	fill(255, 0, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(75, 100);
            +	fill(0, 255, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(50, 75);
            +	fill(0, 0, 255);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +}
            +      </script>
            +
            +      <p>
            +      The first triangle in red is drawn at (0, 0) after the coordinate system has been translated to the right and down by 25 pixels each. After the first pop() is called, the first translation is undone and the coordinate (0, 0) reverts back to the top-left corner of the canvas.
            +      We call push() and translate(75, 100), now moving the the canvas 75 pixels right and 100 pixels done, and then draw the green rectangle. The second pop() undoes that translation as well. Finally, the blue triangle is done after making the same operation, this time translating 50 pixels right and 75 pixels down.
            +    </p>
            +
            +      <h2>What's the Advantage</h2>
            +
            +      <p>In the last sketch, we could have achieved the same visual output by simply drawing the rectangles at those exact points. Or we could have used translate() without the push() and pop() blocks by undoing each translation manually, e.g. translate(-25, -25) to undo the first translation of (25, 25).</p>
            +      <p>For simple shapes like rectangles, it is easier to not use translations, but rather to specify the points manually. But when we begin to draw more complex shapes, translations become advantageous. Let's take a look at an example where translate(), push(), and pop() are really useful.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +	for (var x = 5; x < 150; x = x+25){
            +		for (var y = 5; y < 200; y = y+25){
            +			push();
            +			translate(x, y);
            +	  		drawHouse();
            +			pop();
            +		}
            +	}
            +}
            +
            +function drawHouse() {
            +	triangle(7.5, 0, 0, 7.5, 15, 7.5);
            +	rect(0, 7.5, 15, 12.5);
            +	rect(6, 15, 5, 5);
            +}
            +      </script>
            +
            +      <p>
            +      In this example, we draw a grid of houses. Instead of having to keep track of the coordinates for every vertex of every house, we simply have one function, drawHouse() which draws a house relative to the point (0, 0). We then create a loop which will translate to the correct point before drawing each house.
            +      </p>
            +
            +      <p>
            +      Using the transformations command allows us to use a single drawing function irrespective of where we intend to draw it on the canvas, while push() and pop() allow us to reserve transformations only to the relevant code blocks.
            +      </p>
            +
            +      <h2>Rotation</h2>
            +
            +      <p>
            +      In addition to translating the grid, you can also rotate it with the rotate() function. This function takes one argument, the angle of rotation. It then rotates the canvas around the origin point (0, 0). It's as though you have a piece of graph paper, place your finger on the point (0, 0), and then rotate the paper around your finger.
            +      </p>
            +
            +      <p>Angle is measured clockwise with zero being at 3 o'clock. In p5.js, all the functions having to do with angles take radians. A single rotation or a full circle has 360° or 2π radians. Here is a diagram of how p5.js measures angles in degrees (black) and radians (red).</p>
            +
            +      <img src="../../assets/learn/transformations/angles.png" style="width:150px;">
            +
            +      <p>Since most people think in degrees, p5.js has a built-in radians() function which takes a number of degrees as its argument and converts it to radians for you. It also has a degrees() function that converts radians to degrees. Take a look at the following example which rotates the canvas by an angle measurement set by the mouseX position.
            +      The red square is drawn before rotation, and the green one after rotation.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw() {
            +	var deg = mouseX;
            +	var rad = radians(deg);
            +
            +	background(240);
            +
            +	// the red rectangle is drawn before the rotation so
            +	// it will stay in place
            +	fill(255, 0, 0);
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 50);
            +
            +	fill(0, 255, 0);
            +	text("rotate "+floor(deg)+" degrees", 50, 25);
            +
            +	// rotation is done here. all subsequent drawing
            +	// is done post-rotation
            +	rotate(rad);
            +
            +	// draw the grid
            +	drawGrid();
            +
            +	// the green rectangle and grid is drawn after rotating the canvas
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 500);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +    fill(120);
            +	for (var x=-2*width; x < 2*width; x+=40) {
            +		line(x, -2*height, x, 2*height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-2*height; y < 2*height; y+=40) {
            +		line(-2*width, y, 2*width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <h2> Rotating in place</h2>
            +
            +      <p>In the last example, the green square goes off the screen as we rotate the canvas more. Sometimes we want to be able to rotate a shape in place, rather than around the top-left corner of the screen. We can do this by combining translate() and rotate() together. Recall that translate() moves the origin (0,0) to another place in the canvas and that rotate() rotates the canvas around the origin.
            +        Thus if we want to draw a shape in the middle of the screen and then rotate it in place, we should first translate the canvas to the point we want to draw the shape, then rotate, then draw the shape at (0, 0). Take a look at the following example.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +        <p>If you want the rectangle to rotate around its own center point rather than by its corner, we can use the command rectMode(CENTER) to set p5.js to interpret the coordinates of rectangles to refer to the center of the rectangle rather than the top-left corner. The following example is the same as the previous one but with centered coordinates.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +	rectMode(CENTER);	// now the first two arguments of a rect are its center point, not corner
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +      <p>Here is a program that generates a wheel of colors by using rotation, and draws a strip every 25 frames.</p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	background(240);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	// the modulo operator % calculates the remainder.
            +	// example: 24 % 25 = 24, 25 % 25 = 0, 26 % 25 = 1, etc.
            +	// thus this if statement will evaluate True every 25 frames.
            +	if (frameCount % 25 == 0) {
            +		fill(random(255), random(255), random(255));
            +		push();
            +		translate(75, 100);
            +		rotate(radians(frameCount));
            +		rect(0, 0, 100, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +        <h2>Rotational Symmetry</h2>
            +
            +        <p>
            +        Let's take a look at a more complicated example where we can use translate and rotate together to create interesting symmetries around the center of the canvas. Let's first build it by drawing 8 squares which are evenly distributed along a circle around the center of the canvas. What we do is we first translate to the center of the screen, translating the canvas by (width/2, height/2).
            +        We then rotate the canvas to the 8 angles evenly distributed between 0 and 2π radians. We then draw a circle 50 pixels away from the center, after each of these rotations.
            +        </p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		rect(50, 0, 10, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +      <p>
            +        Look at the line rect(50, 0, 10, 10). Recall that you can draw a shape in the same place by translating to it first and then drawing it at (0, 0). So we can do another another translation after we've rotated, to translate along the right-pointing line after it's been rotated. So we can replace the statement rect(50, 0, 10, 10) with the following two: translate(50, 0) and rect(0, 0, 10, 10).
            +        By doing so, we bring the pivot point or origin of the canvas to each of the eight rectangles we just drew.
            +      </p>
            +
            +      <p>
            +        This is convenient because now we can do something even more interesting. Instead of simply drawing a rectangle at each of those points, let's create another loop which will draw six smaller squares evenly distributed around a small circle around each of these new pivot points. See the following.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		translate(50, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			rect(15, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <p>
            +        Now that we have achieved an interesting geometry, we can embellish this program by making a variable for the first translation amount and for the x-position of the rectangle, and modulating them in interesting ways. In the following example, we'll modulate those two values using Perlin noise. If you haven't used Perlin noise before, take a look at the tutorial on Perlin noise.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		var tx = 100 * noise(0.01*frameCount);
            +		translate(tx, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			var rx = 30 * noise(0.01*frameCount + 10);
            +			rect(rx, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +      <p>Now we're getting somewhere! Let's take the previous example and make the following additions to it to make it even more interesting.</p>
            +
            +      <p>
            +        <ul class="list_view">
            +          <li>Extra rotation variables so the whole circle rotates with perlin noise</li>
            +          <li>Red + Blue = Purple</li>
            +          <li>Additional noisy in-place rotation of the drawn shapes</li>
            +          <li>Noisy modulation of the size of the shapes being drawn</li>
            +        </ul>
            +      </p>4
            +
            +      <p>All the noisy variables will be calculated at the top of the draw loop for better organization. Looks cool, right?!</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +	fill(0, 50);
            +	stroke(255, 50);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var ang1 = TWO_PI * noise(0.01*frameCount + 10);
            +	var ang2 = TWO_PI * noise(0.01*frameCount + 20);
            +	var ang3 = TWO_PI * noise(0.01*frameCount + 30);
            +	var rx = 30 * noise(0.01*frameCount + 40);
            +	var tx = 100 * noise(0.01*frameCount + 50);
            +	var size1 = 100 * noise(0.01*frameCount + 60);
            +	var size2 = 20 * noise(0.01*frameCount + 60);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(ang1 + TWO_PI * i / 8);
            +		translate(tx, 0);
            +		rect(0, 0, size1, size1);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(ang2 + TWO_PI * j / 6);
            +			translate(rx, 0);
            +			rotate(ang3);
            +			rect(rx, 0, size2, size2);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <h2>Scaling</h2>
            +
            +      <p>
            +        There is one more function which transforms the coordinate system, and that is scale(). Scale changes the size of the grid by multiplying the coordinate system. See the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var scaleAmount = mouseX / 100;
            +  	scale(scaleAmount);
            +
            +	drawGrid();
            +  	fill(255, 255, 0);
            +  	rect(20, 20, 50, 50);
            +}
            +
            +function drawGrid() {
            +	fill(0);
            +	stroke(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/trigonometry.html b/dist/hi/learn/trigonometry.html
            new file mode 100644
            index 0000000000..7cbe50699e
            --- /dev/null
            +++ b/dist/hi/learn/trigonometry.html
            @@ -0,0 +1,189 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <h2>Trigonometry Primer</h2>
            +      <p>(learning to love triangles)</p>
            +      <div class="attribution">
            +        This tutorial was written during the first p5.js developers conference by Tega Brain.
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="pythagoras">Pythagoras Theorum</h3>
            +      <div class="info">
            +        <p>Trigonometry is a branch of geometry that is fundamental to all graphics programming.  It provides useful equations that enable you to figure out distances between points and how curves and circles can be described in Cartesian coordinates. Remember Cartesian coordinates are points described by x and y values. Trigonmetry also enables you to do things like move shapes in circular motion or oscillate values smoothly back and forth between two extremes.</p>
            +
            +
            +        <p>The right angled triangle is one of the most important parts of trigonometry and Pythagoras was a guy who got pretty famous for figuring out a theorem that relates the length of each of its sides. Pythagora figured out that in every right hand triangle, if you square each of the two shortest sides, their sum equals the square of the longest side.</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/pythagoras1.jpg" />
            +
            +        <p>Right angled triangles are special also because each of their angles has a specific relationship to the ratio between the length of two of their sides. This is what sine, cosine and tangent functions describe. Sin cos and tan are known as trigonometric functions and they give us the relationship between the ratio of two of the triangle’s sides and one of the angles of the triangle. You may recall the acronym: SOH-CAH-TOA that helps you remember how sinθ, cosθ and tanθ relate to the ratio of which of the triangle’s sides.</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/hypotenuse.jpg" />
            +        
            +        <p>This is all pretty great, because is means that with just a couple of pieces of information about a right angled triangle, like knowing two of its side lengths or maybe knowing one of its angle and a side length, you can use Pythagora’s theorem in combination with the sin, cos and tan equations to figure out everything else.</p>
            +
            +        <p>These triangles are also helpful as they help us to map and understand the x and y coordinates of points along curves and circles. Notice how in the drawing below you can see how any point on a circle will have a relationship to a right angled triangle. This relationship means that a point on a circle can be understood in two ways. Firstly, as we have seen a point can be described by Cartesian coordinates which are of course, by x and y co-ordinates, but it can also be described using polar coordinates. Polar coodinates are an angle and a distance from the origin (the radius of the circle).</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/polar.jpg" />
            +      </div>
            +        
            +      <h3 class = "start-element tutorial-btn" id="Polar Coordinates">Polar Coordinates</h3>
            +      <div class="info">
            +        <p>Polar coordinates describe a point using an angle and a distance from the origin. This is useful when you are coding something like an analog clock. When drawing a clock, you would need to place each hand at a particular angle, for example, 3pm is at zero degrees and midday is at 90 degrees. Each hand would be coded as a line drawn onto a screen, that connects two points. So these hand would connect the origin to the x,y coordinates that is at the position of the time. Putting anything on a screen always requires you to describe it in terms of x and y.</p>
            +        
            +        <p>So how do we convert between polar coordinates and x-y coordinates?</p>
            +        
            +        <p>The relationship between polar coordinates and x,y coordinates can be calculated using a unit circle. This is a circle that has a radius of 1 unit which is useful because it means the hypotenuse in your right angled triange is always 1.</p>
            +
            +        <iframe src="../../assets/learn/trigonometry/unitCircle/embed.html" width="600" height="400"></iframe>
            +
            +
            +      </div>
            +      
            +      <h3 class="start-element tutorial-btn" id="sin">Using Sin and Cosine</h3>
            +      <div class="info">
            +        <iframe src="../../assets/learn/trigonometry/sincoscurves/embed.html" width="800" height="750"></iframe>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/learn/tutorial-guide.html b/dist/hi/learn/tutorial-guide.html
            new file mode 100644
            index 0000000000..c89a292875
            --- /dev/null
            +++ b/dist/hi/learn/tutorial-guide.html
            @@ -0,0 +1,262 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>P5.js शिक्षण के योगदान के लिए गाइड</h1>
            +      <div class="attribution">
            +        यह शिक्षण टेगा ब्रेन द्वारा लिखा गया था।
            +      </div>
            +      <p>
            +        हम शिक्षकों, योगदानकर्ताओं और सामान्य उत्साही लोगों को p5js शिक्षण में योगदान करने के लिए आमंत्रित करते हैं। P5js परियोजना रचनात्मक कोडिंग और खुले स्रोत के विकास को विविध समुदाय के लिए अधिक सुलभ बनाती है और हम विकास प्रक्रिया के सभी पहलुओं पर शिक्षण प्रकाशित करने के लिए उत्साहित हैं। अब तक की हमारी शिक्षण सामग्री में सीखने की पी 5, प्रोग्रामिंग तकनीक और एक ओपन सोर्स प्रोजेक्ट में योगदान करने के तरीके शामिल हैं।
            +      </p>
            +      <p>
            +        हम नए लिखित शिक्षण योगदानों का स्वागत करते हैं और यह गाइड प्रस्ताव, तैयारी और योगदान करने के तरीके की रूपरेखा प्रस्तुत करता है।
            +      </p>
            +
            +      <h2>शुरुआत कैसे करें:</h2>
            +      <ul class="list_view">
            +        <li>
            +          जांचें कि आपका प्रस्तावित विषय पहले से ही कवर नहीं किया गया है। <a href="https://docs.google.com/spreadsheets/d/1sh3IwcCUY4Bm8N4fRZw6CwSDdQmmXgY_awjVj-UC8mo/edit#gid=0">यहां एक वर्किंग स्प्रेडशीट है </a>
            +          जो प्रगति शिक्षण में रूपरेखा है। यदि आपके विषय को प्रगति के रूप में सूचीबद्ध किया गया है, तो शायद आप काम करने के लिए जोड़ सकते हैं और प्रकाशन के लिए मौजूदा काम को तैयार करने में योगदान कर सकते हैं ताकि कृपया हमारे पास पहुंचें।
            +        </li>
            +        <li>
            +          यदि आपका विषय पहले से ही कवर नहीं है और प्रगति के रूप में सूचीबद्ध नहीं है, तो कृपया कुछ वाक्यों को लिखें, जो आप हमें इस विवरण को education@p5js.org पर कवर करने और ईमेल करने का प्रस्ताव देते हैं।
            +        </li>
            +      </ul>
            +      <h2>ऑनलाइन प्रकाशन के लिए एक p5js शिक्षण कैसे तैयार करें:</h2>
            +      <p>
            +        जब आपका शिक्षण प्रकाशन के लिए तैयार हो जाता है, तो कृपया p5js वेबसाइट के लिए अपनी सामग्री तैयार करने के लिए इन चरणों का पालन करें।
            +      </p>
            +      <p>
            +        Prepare the content of your tutorial as a tutorial-name.hbs file with <a href="https://github.com/mayaman/p5js-website/blob/master/src/templates/pages/learn/test-tutorial.hbs">इस मूल संरचना के साथ</a>
            +         एक शिक्षण-name.hbs फ़ाइल के रूप में अपने शिक्षण की सामग्री तैयार करें। जैसा कि इस फ़ाइल में दिखाया गया है, इसमें एक हैडर होना चाहिए जैसा कि नीचे दिखाया गया है:
            +      </p>
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-1.png" alt="Screenshot">
            +
            +      <p>
            +        आपके शिक्षण वाले फ़ोल्डर को p5js साइट के 'शिक्षण' फ़ोल्डर में रखा जाएगा। index.hbs नामक फ़ाइल <a href="/hi/learn/">p5.js शिक्षण लैंडिंग पेज ,</a>
            +         है, और परीक्षण-शिक्षण.एचबीएस फ़ाइल परीक्षण शिक्षण है।
            +      </p>
            +      <p>
            +        सभी सामग्री में जाना चाहिए:
            +       
            +        &lt;section &gt; &lt;/section&gt;
            +        पृष्ठ पर टैग &lt;h1 &gt; और &lt;h2 &gt; टैग द्वारा परिभाषित स्वरूपण के साथ, &lt;p &gt; पैराग्राफ टैग के रूप में दिखाया गया है <a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs">शिक्षण पृष्ठ का परीक्षण करें।</a></p>
            +      <p>
            +        यदि आपके शिक्षण में छवियां हैं, तो उन्हें नीचे दिए गए स्थान के अनुसार, स्थान src/assets/learn/test-tutorial/images में, P5 साइट के asset फ़ोल्डर में रखा जाना है।
            +      </p>
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-2.png" alt="Screenshot">
            +      <p>
            +        पृष्ठ के HTML में कोड को सही ढंग से प्रारूपित करने के लिए टैग का उपयोग करें:
            +      </p>
            +       
            +        <pre><code class="language-javascript">
            +&lt;pre&gt;&lt;code class="language-javascript"&gt;
            +Your code here!
            +&lt;/code>&lt;/pre&gt;
            +
            +</code></pre>
            +
            +      <h2>P5.js स्केच एम्बेड करना</h2>
            +      <p>
            +        P5js का उपयोग करने का मतलब है कि आप अपने शिक्षण को प्रोग्रामिंग अवधारणाओं को प्रदर्शित करने के लिए एनिमेटेड, इंटरैक्टिव या संपादन योग्य कोड उदाहरणों के साथ चित्रित कर सकते हैं। आपके उदाहरणों को p5.js स्केच के रूप में तैयार किया जाना चाहिए और इसे दो तरीकों से शिक्षण में एम्बेड किया जा सकता है।
            +      </p>
            +
            +      <ol>
            +        <li>
            +          यदि उदाहरण p5js साइट के <a href="http://p5js.org/reference/#/p5/ellipse">संदर्भ पृष्ठों</a> की तरह संपादन योग्य होना है, तो p5js विजेट का उपयोग करके HTML पृष्ठ में p5 स्केच को एम्बेड किया जाना चाहिए।  टूल द्वारा लिखित विजेट का उपयोग करके p5js स्केच को एम्बेड करने के तरीके पर <a href="https://toolness.github.io/p5.js-widget/">इस गाइड </a>का पालन करें। <a href="https://github.com/toolness">Toolness</a>आप इसे <a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs"> परीक्षण शिक्षण पृष्ठ </a> पर कार्रवाई में भी देख सकते हैं।</li>
            +        <li>
            +           यदि उदाहरण एनिमेटेड और / या इंटरैक्टिव होना है, लेकिन संपादन योग्य नहीं है। P5.js स्केच को नीचे वर्णित अनुसार iframe के रूप में पृष्ठ में एम्बेड किया जाना चाहिए।
            +        </li>
            +      </ol>
            +
            +      <h2>एक iframe का उपयोग करके एक p5 स्केच एम्बेड करें</h2>
            +
            +      <p>
            +        एक iframe एक विंडो बनाने जैसा है, जिसके माध्यम से आप अपने पेज के बाकी हिस्सों से सैंडबॉक्स कर सकते हैं। इस स्थिति में यह आपके p5.js स्केच वाले index.html की एक विंडो होगी। 
            +      </p>
            +      <img src="https://github.com/tegacodes/p5.js-education/raw/master/images/iframe-2.jpg" alt="tutorialFileStructure" width="600">
            +
            +      <p>
            +         स्क्रीनशॉट में दिखाए अनुसार आपके स्केच के नाम के साथ लेबल वाले फ़ोल्डर में, साइट के / src / आस्तियों / सीखने के फ़ोल्डर में अपने p5 स्केच डालें। यह वह जगह है जहाँ iframe से जुड़े सभी चित्र और p5 स्केच संग्रहीत किए जाने चाहिए।
            +      </p>
            +
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-3.png" alt="Screenshot">
            +
            +<p>आपके p5 उदाहरण वाले सबफ़ोल्डर्स में एक स्केच.जेएस फ़ाइल और स्केच के लिए embed.html फ़ाइल होनी चाहिए। </p>
            +<img src="../../assets/learn/tutorial-guide/images/screenshot-4.png" alt="Screenshot">
            +
            +<p>सुनिश्चित करें कि आपकी embed.html फ़ाइल में साइट के p5 लाइब्रेरीज  के लिए सही रास्ते हैं। यदि आपकी फ़ाइल संरचना ऊपर के समान है, तो p5.js लाइब्रेरी का पथ ".. ..///..s/ js / p5.min.js " होना चाहिए।</p>
            +<p>इसके बाद आप .hbs फ़ाइल के रूप में p5js इंडेक्स फाइल को अपने शिक्षण सामग्री में एम्बेड कर सकते हैं। Iframe के लिए एम्बेड कोड तब होगा: </p>
            +  <pre><code class="language-javascript">
            +&lt;iframe src="http://p5js.org/assets/learn/tes-tutorial/embed.html" width="600" height="400"&gt;
            +&lt;/iframe&gt;
            +</code></pre>
            +
            +<p>आइफ्रेम के लिए स्टाइलिंग (यह सीधे पोस्ट या स्टाइलशीट में हो सकता है):  </p>
            +  <pre><code class="language-javascript">
            +&lt;style&gt; iframe{ border: none; } &lt;/style&gt;
            +</code></pre>
            +
            +<p>यहाँ आप नग्न स्केच को चलते हुए देख सकते हैं: </p>
            +<a href="http://staging.p5js.org/assets/learn/test-tutorial/embed.html">http://staging.p5js.org/assets/learn/test-tutorial/embed.html</a>
            +
            +<p>और यहाँ नीचे कोड का उपयोग करके इसे p5 साइट में एम्बेड किया गया है:  </p>
            +<a href="http://staging.p5js.org/learn/test-tutorial.html">http://staging.p5js.org/learn/test-tutorial.html</a>
            +
            +<p>ध्यान देने वाली एक बात यह है कि आपको मैन्युअल रूप से iframe का आकार निर्धारित करने की आवश्यकता है, इसलिए यह सबसे अच्छा काम करता है यदि चीजें एक मानक आकार हैं।</p>
            +
            +<p>यह भी ध्यान दें कि p5.js लाइब्रेरी फ़ाइलों के लिंक सभी शिक्षण सामग्री के साथ .eps पेज से नहीं होते हैं। इसके बजाय वे html पृष्ठ में स्थित होंगे जो आपके स्केच का प्रतिपादन कर रहा है (इस मामले में, जिसे embed.html कहा जाता है)।</p>
            +
            +<p>एम्बेडिंग p5.js स्केच के बारे में अधिक जानकारी <a href="https://github.com/processing/p5.js/wiki/Embedding-p5.js">यहाँ पाई जा सकती है।</a></p>
            +<h2>पूरी तरह खत्म करना</h2>
            +<p>एक बार जब आप अपना शिक्षण लिखना समाप्त कर लेते हैं और आपकी सामग्री को अंगूठा दे दिया जाता है। वेबसाइट के भंडार के लिए p5.js को फोर्क करें, ऊपर वर्णित अनुसार अपनी सामग्री तैयार करें और फिर p5.js वेबसाइट रिपॉजिटरी के लिए एक पुल अनुरोध जारी करें ताकि हम आपके योगदान को प्रकाशित कर सकें!</p>
            +
            +    <p>धन्यवाद!</p>
            +
            +  </main>
            +
            +  
            +  <footer>
            +    <h2 class="sr-only">आभार सूची</h2>
            +    <p>
            +      p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +    </p>
            +  </footer>
            +
            +</div> <!-- end column-span -->
            +
            +
            +<!-- outside of column for footer to go across both -->
            +
            +<p class="clearfix"> &nbsp; </p>
            +
            +<object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +</object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/libraries/index.html b/dist/hi/libraries/index.html
            new file mode 100644
            index 0000000000..b36fc61c45
            --- /dev/null
            +++ b/dist/hi/libraries/index.html
            @@ -0,0 +1,932 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">libraries | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="libraries-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रेरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>लाइब्रेरी</h1>
            +
            +      <h2>पुस्तकालय का उपयोग करना</h2>
            +
            +      <p>एक p5.js पुस्तकालय कोई भी JavaScript कोड हो सकता है जो p5.js मुख्य कार्यक्षमता को बढ़ाता या जोड़ता है। पुस्तकालयों की दो श्रेणियां हैं। कोर लाइब्रेरी (<a
            +          href="/hi/reference/#/libraries/p5.sound">p5.sound</a>) p5.js वितरण का हिस्सा हैं, जबकि योगदान की गई लाइब्रेरी p5.js समुदाय के सदस्यों द्वारा विकसित, स्वामित्व और रखरखाव की जाती हैं।</p>
            +
            +      <p>अपने स्केच में लाइब्रेरी शामिल करने के लिए, इसे p5.js. में लिंक करने के बाद अपनी HTML फ़ाइल में लिंक करें। उदाहरण के लिए एक HTML फ़ाइल कुछ इस तरह दिख सकती है</p>
            +      <pre><code class="language-markup">&lt;!doctype html&gt;
            +&lt;html>
            +&lt;head>
            +  &lt;script src="p5.js"&gt;&lt;/script&gt;
            +  &lt;script src="p5.sound.js"&gt;&lt;/script&gt;
            +  &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +&lt;/head&gt;
            +&lt;body&gt;
            +&lt;/body&gt;
            +&lt;/html&gt;
            +      </code></pre>
            +
            +      <h2>खुद से बनाए</h2>
            +
            +      <p>p5.js दूसरों द्वारा योगदान किए गए लाइब्रेरी का स्वागत करता है! एक लाइब्रेरी बनाने के तरीके के बारे में अधिक विशिष्टताओं के लिए
            +        <a href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +          लाइब्रेरी शिक्षण</a>
            +        की जाँच करें।
            +        <a href="https://docs.google.com/forms/d/e/1FAIpQLSdWWb95cfvosaIFI7msA7XC5zOEVsNruaA5klN1jH95ESJVcw/viewform"
            +          target="_blank">यदि आपने एक लाइब्रेरी बनाई है और इसे इस पृष्ठ पर शामिल करना चाहते हैं, तो इस फॉर्म को जमा करें!</a></p>
            +
            +      
            +      
            +      <h2 class="tutorial-title">कोर लाइब्रेरी</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="/hi/reference/#/libraries/p5.sound" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.sound.jpg">
            +              <h3>p5.sound</h3>
            +            </a>
            +          </div>
            +          <p>p5.sound ऑडियो इनपुट, प्लेबैक, विश्लेषण और संश्लेषण सहित वेब ऑडियो कार्यक्षमता के साथ p5 का विस्तार करता है।  निर्माता:
            +            <a href="https://www.jasonsigal.cc/"
            +              target="_blank">Jason Sigal</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/processing/p5.accessibility" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.accessibility.jpg">
            +              <h3>p5.accessibility</h3>
            +            </a>
            +          </div>
            +          <p>p5.accessibility उन लोगों के लिए p5 कैनवास को अधिक सुलभ बनाती है जो नेत्रहीन और दृष्टिबाधित हैं। 
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +      
            +      <h2 class="tutorial-title">सामुदायिक लाइब्रेरी</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/asciiart" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/asciiart.jpg">
            +              <h3>asciiart</h3>
            +            </a>
            +          </div>
            +          <p>p5.asciiart p5js के लिए एक सरल और आसान छवि-से-ASCII कला कनवर्टर है।  निर्माता:
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://itpnyu.github.io/p5ble-website/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.ble.jpg">
            +              <h3>p5.ble</h3>
            +            </a>
            +          </div>
            +          <p>एक जावास्क्रिप्ट लाइब्रेरी जो BLE उपकरणों और p5 स्केच के बीच संचार को सक्षम करता है।  निर्माता:
            +            <a href="https://1023.io"
            +              target="_blank">Yining Shi</a>, <a href="https://www.jingwen-zhu.com/"
            +              target="_blank">Jingwen Zhu</a>, <a href="https://tigoe.com/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/sarahgp/p5bots" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.bots.jpg">
            +              <h3>p5.bots</h3>
            +            </a>
            +          </div>
            +          <p>p5.bots के साथ आप ब्राउज़र के भीतर से अपने Arduino (या अन्य माइक्रोप्रोसेसर) के साथ बातचीत कर सकते हैं। स्केच चलाने के लिए सेंसर डेटा का उपयोग करें; एल ई डी, मोटर, और बहुत कुछ चलाने के लिए एक स्केच का उपयोग करें! निर्माता:
            +            <a href="http://www.sarahgp.com"
            +              target="_blank">Sarah Groff-Palermo</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Lartu/p5.clickable" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.clickable.jpg">
            +              <h3>p5.clickable</h3>
            +            </a>
            +          </div>
            +          <p>p5.js के लिए इवेंट संचालित, उपयोग में आसान बटन लाइब्रेरी। निर्माता:
            +            <a href="https://www.lartu.net"
            +              target="_blank">Martín del Río</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/p5.cmyk.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.cmyk.js.jpg">
            +              <h3>p5.cmyk.js</h3>
            +            </a>
            +          </div>
            +          <p>CMYK कलरस्पेस।  निर्माता:
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.collide2D" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.collide2D.jpg">
            +              <h3>p5.collide2D</h3>
            +            </a>
            +          </div>
            +          <p>p5.collide2D p5.js के साथ 2D ज्यामिति के लिए टकराव का पता लगाने की गणना के लिए उपकरण प्रदान करता है। निर्माता:
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.npmjs.com/package/p5.createloop" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.createloop.jpg">
            +              <h3>p5.createloop</h3>
            +            </a>
            +          </div>
            +          <p>कोड की एक पंक्ति में ध्वनि और GIF निर्यात के साथ एनीमेशन लूप बनाएं।  निर्माता:
            +            <a href="https://www.piratesjustar.com/"
            +              target="_blank">Peter Hayman</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Smilebags/p5.dimensions.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.dimensions.jpg">
            +              <h3>p5.dimensions</h3>
            +            </a>
            +          </div>
            +          <p>p5.dimensions किसी भी संख्या के आयामों में काम करने के लिए p5.js के वेक्टर फ़ंक्शन का विस्तार करता है।  निर्माता:
            +            <a href="https://github.com/Smilebags"
            +              target="_blank">Smilebags</a>, <a href="https://github.com/max0410"
            +              target="_blank">Max Segal</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/freshfork/p5.EasyCam" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.EasyCam.jpg">
            +              <h3>p5.EasyCam</h3>
            +            </a>
            +          </div>
            +          <p>जड़त्वीय पैन, ज़ूम और रोटेट के साथ सरल 3D कैमरा नियंत्रण। थॉमस डाइवाल्ड का प्रमुख योगदान। निर्माता:
            +            <a href="https://jwilliamdunn.com"
            +              target="_blank">jWilliam Dunn</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/loneboarder/p5.experience.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.experience.jpg">
            +              <h3>p5.experience</h3>
            +            </a>
            +          </div>
            +          <p>p5.js के लिए विस्तृत लाइब्रेरी जो कैनवास-आधारित वेब एप्लिकेशन बनाने के लिए अतिरिक्त ईवेंट-सुनने की कार्यक्षमता जोड़ती है। निर्माता:
            +            <a href="https://github.com/loneboarder"
            +              target="_blank">Felix Meichelböck</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-func" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.func.jpg">
            +              <h3>p5.func</h3>
            +            </a>
            +          </div>
            +          <p>p5.func एक p5 एक्सटेंशन है जो समय, आवृत्ति और स्थानिक डोमेन में फ़ंक्शन जनरेशन के लिए नई ऑब्जेक्ट और उपयोगिताओं को प्रदान करता है। निर्माता:
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.geolocation" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.geolocation.jpg">
            +              <h3>p5.geolocation</h3>
            +            </a>
            +          </div>
            +          <p>p5.geolocation p5.js के लिए उपयोगकर्ता स्थानों को प्राप्त करने, देखने, गणना करने और जियोफेंसिंग के लिए तकनीक प्रदान करता है। निर्माता:
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://charlie-roberts.com/gibber/p5-gibber/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.gibber.jpg">
            +              <h3>p5.gibber</h3>
            +            </a>
            +          </div>
            +          <p>p5.gibber तेजी से संगीत अनुक्रमण और ऑडियो संश्लेषण क्षमता प्रदान करता है। निर्माता:
            +            <a href="https://charlie-roberts.com"
            +              target="_blank">Charlie Roberts</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jagracar/grafica.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/grafica.js.jpg">
            +              <h3>grafica.js</h3>
            +            </a>
            +          </div>
            +          <p>grafica.js आपको अपने p5.js स्केच में सरल लेकिन अत्यधिक विन्यास योग्य 2D प्लॉट जोड़ने देता है। निर्माता:
            +            <a href="https://jagracar.com/p5jsSketches.php"
            +              target="_blank">Javier Graciá Carpio</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bitcraftlab/p5.gui" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.gui.jpg">
            +              <h3>p5.gui</h3>
            +            </a>
            +          </div>
            +          <p>p5.gui आपके p5.js स्केच के लिए एक ग्राफिकल यूजर इंटरफेस बनाता है।  निर्माता:
            +            <a href="https://www.bitcraftlab.com/"
            +              target="_blank">Martin Schneider</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.localmessage" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.localmessage.jpg">
            +              <h3>p5.localmessage</h3>
            +            </a>
            +          </div>
            +          <p>p5.localmessage आसान मल्टी-विंडो स्केचिंग के लिए स्थानीय रूप से एक स्केच से दूसरे में संदेश भेजने के लिए एक सरल इंटरफ़ेस प्रदान करता है! निर्माता:
            +            <a href="https://benmoren.com"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/marching" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/marching.jpg">
            +              <h3>marching</h3>
            +            </a>
            +          </div>
            +          <p>वेक्टर रूपांतरण के लिए रेखापुंज, आइसोसर्फेस। निर्माता:
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/cvalenzuela/Mappa" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/mappa.jpg">
            +              <h3>mappa</h3>
            +            </a>
            +          </div>
            +          <p>मप्पा स्थिर मानचित्रों, टाइल मानचित्रों और भू-डेटा के साथ काम करने के लिए उपकरणों का एक सेट प्रदान करता है। भौगोलिक स्थान-आधारित दृश्य अभ्यावेदन बनाते समय उपयोगी। निर्माता:
            +            <a href="https://github.com/cvalenzuela/"
            +              target="_blank">Cristóbal Valenzuela</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://ml5js.org/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/ml5.js.jpg">
            +              <h3>ml5.js</h3>
            +            </a>
            +          </div>
            +          <p>ml5.js Tensorflow.js पर बनाता है और ब्राउज़र में मशीन लर्निंग एल्गोरिदम और मॉडल के लिए अनुकूल पहुँच प्रदान करता है।  निर्माता:
            +            <a href="https://ml5js.org/"
            +              target="_blank">NYU ITP/IMA and contributors</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="http://p5play.molleindustria.org" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.play.jpg">
            +              <h3>p5.play</h3>
            +            </a>
            +          </div>
            +          <p>p5.play गेम और गेमेलिक एप्लिकेशन के लिए स्प्राइट, एनिमेशन, इनपुट और कोलिजन फंक्शन प्रदान करता है। निर्माता:
            +            <a href="https://www.molleindustria.org/"
            +              target="_blank">Paolo Pedercini</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bobcgausa/cook-js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.particle.jpg">
            +              <h3>p5.particle</h3>
            +            </a>
            +          </div>
            +          <p>कण और फव्वारा वस्तुओं का उपयोग डेटा-संचालित प्रभाव बनाने के लिए किया जा सकता है जो उपयोगकर्ता संरचनाओं या JSON इनपुट और उपयोगकर्ता-ड्रा फ़ंक्शन के माध्यम से परिभाषित होते हैं।  निर्माता:
            +            <a href="http://professorcook.org/"
            +              target="_blank">Robert Cook</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://antiboredom.github.io/p5.riso" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.Riso.jpg">
            +              <h3>p5.Riso</h3>
            +            </a>
            +          </div>
            +          <p>p5.Riso, Risograph मुद्रण के लिए उपयुक्त फ़ाइलें बनाने के लिए एक पुस्तकालय है। यह आपके रेखाचित्रों को बहु-रंगीन प्रिंटों में बदलने में मदद करता है।  निर्माता:
            +            <a href="https://lav.io/"
            +              target="_blank">Sam Lavigne</a>, <a href="https://tegabrain.com/"
            +              target="_blank">Tega Brain</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://rednoise.org/rita" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/rita.js.jpg">
            +              <h3>rita.js</h3>
            +            </a>
            +          </div>
            +          <p>RiTa.js जनरेटिव साहित्य के लिए प्राकृतिक भाषा प्रसंस्करण वस्तुओं का एक सेट प्रदान करता है।  निर्माता:
            +            <a href="https://rednoise.org/daniel"
            +              target="_blank">Daniel C. Howe</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://codeforartists.com/RotatingKnobMaker" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/Rotating_knobs.jpg">
            +              <h3>Rotating knobs</h3>
            +            </a>
            +          </div>
            +          <p>Make knobs you can rotate with custom graphics and return value ranges. निर्माता:
            +            <a href="https://codeforartists.com"
            +              target="_blank">Miles DeCoster</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/mveteanu/p5.SceneManager" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.scenemanager.jpg">
            +              <h3>p5.scenemanager</h3>
            +            </a>
            +          </div>
            +          <p>p5.SceneManager आपको कई राज्यों/दृश्यों के साथ रेखाचित्र बनाने में मदद करता है। प्रत्येक दृश्य मुख्य स्केच के भीतर एक स्केच की तरह है। निर्माता:
            +            <a href="https://github.com/mveteanu/"
            +              target="_blank">Marian Veteanu</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bohnacker/p5js-screenPosition" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.screenPosition.jpg">
            +              <h3>p5.screenPosition</h3>
            +            </a>
            +          </div>
            +          <p>प्रोसेसिंग से P5js तक ScreenX और ScreenY कार्यक्षमता जोड़ता है। निर्माता:
            +            <a href="https://hartmut-bohnacker.de/"
            +              target="_blank">Hartmut Bohnacker</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/generative-light/p5.scribble.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.scribble.jpg">
            +              <h3>p5.scribble</h3>
            +            </a>
            +          </div>
            +          <p>स्केची लुक में 2D प्रिमिटिव ड्रा करें। मूल प्रसंस्करण पुस्तकालय के एक बंदरगाह के आधार पर, जेनेक वुल्सचलेगर द्वारा बनाया गया। निर्माता:
            +            <a href="https://github.com/gicentre/handy"
            +              target="_blank">handy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/vanevery/p5.serialport" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.serial.jpg">
            +              <h3>p5.serial</h3>
            +            </a>
            +          </div>
            +          <p>p5.serial उन उपकरणों के बीच धारावाहिक संचार को सक्षम बनाता है जो ब्राउज़र में चल रहे सीरियल (RS-232) और p5 स्केच का समर्थन करते हैं। निर्माता:
            +            <a href="https://www.walking-productions.com/notslop/abou/"
            +              target="_blank">Shawn Van Every</a>, <a href="https://kaganjd.github.io/portfolio/"
            +              target="_blank">Jen Kagan</a>, <a href="https://tigoe.net/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/pfe1223/Shape5js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/Shape5.jpg">
            +              <h3>Shape5</h3>
            +            </a>
            +          </div>
            +          <p>Shape5 उन प्राथमिक छात्रों के लिए एक 2D प्राइमरी लाइब्रेरी है जो पहली बार कोड करना सीख रहे हैं। निर्माता:
            +            <a href="https://github.com/pfe1223"
            +              target="_blank">Patrick Ester</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/gaba5/p5.shape.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.shape.js.jpg">
            +              <h3>p5.shape.js</h3>
            +            </a>
            +          </div>
            +          <p>P5.js ढांचे में और अधिक सरल आकृतियों को जोड़ने के लिए बनाया गया एक फ्रेमवर्क।  निर्माता:
            +            <a href="https://github.com/gaba5"
            +              target="_blank">Sebastien Lorentz</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-speech/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.speech.jpg">
            +              <h3>p5.speech</h3>
            +            </a>
            +          </div>
            +          <p>p5.speech वेब स्पीच और स्पीच रिकग्निशन एपीआई के लिए सरल, स्पष्ट पहुंच प्रदान करता है, जिससे स्केच के आसान निर्माण की अनुमति मिलती है जो बात कर सकते हैं और सुन सकते हैं। निर्माता:
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/eltapir/p5.start2d.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.start2d.js.jpg">
            +              <h3>p5.start2d.js</h3>
            +            </a>
            +          </div>
            +          <p>px, mm, cm या इंच का उपयोग करके 2D स्थिर कला के लिए p5 एक्सटेंशन निर्माता:
            +            <a href="https://github.com/eltapir"
            +              target="_blank">Kris HEYSE</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/linux-man/p5.tiledmap" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.tiledmap.jpg">
            +              <h3>p5.tiledmap</h3>
            +            </a>
            +          </div>
            +          <p>p5.tiledmap आपके रेखाचित्रों में मानचित्रों को शामिल करने के लिए आरेखण और सहायक कार्य प्रदान करता है। निर्माता:
            +            <a href="https://softlab.pt/"
            +              target="_blank">Caldas Lopes</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/L05/p5.touchgui" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.touchgui.jpg">
            +              <h3>p5.touchgui</h3>
            +            </a>
            +          </div>
            +          <p>p5.js के लिए एक मल्टी-टच और माउस GUI लाइब्रेरी। निर्माता:
            +            <a href="https://L05.is"
            +              target="_blank">Carlos L05 Garcia</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.tramontana.xyz" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/tramontana.jpg">
            +              <h3>tramontana</h3>
            +            </a>
            +          </div>
            +          <p>ट्रैमोंटाना इंटरएक्टिव वातावरण, इंटरेक्टिव स्पेस या पैमाने पर और अंतरिक्ष में सिर्फ प्रोटोटाइप अनुभव बनाने के लिए आसानी से कई उपकरणों (आईओएस, एंड्रॉइड, ट्रैमोंटाना बोर्ड, ...) का उपयोग करने के लिए एक मंच है। निर्माता:
            +            <a href="https://www.pierdr.com"
            +              target="_blank">Pierluigi Dalla Rosa</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/vida" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/vida.jpg">
            +              <h3>vida</h3>
            +            </a>
            +          </div>
            +          <p>विडा एक साधारण पुस्तकालय है जो कैमरा (या वीडियो) आधारित गति पहचान और ब्लॉब ट्रैकिंग कार्यक्षमता को p5js में जोड़ता है।  निर्माता:
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Dozed12/p5.voronoi" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.voronoi.jpg">
            +              <h3>p5.voronoi</h3>
            +            </a>
            +          </div>
            +          <p>p5.voronoi आपके p5.js रेखाचित्रों में वोरोनोई आरेख बनाने और उनका उपयोग करने के लिए उपकरणों का एक सेट प्रदान करता है। निर्माता:
            +            <a href="https://github.com/Dozed12"
            +              target="_blank">Francisco Moreira</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://p5xr.org/#/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.xr.jpg">
            +              <h3>p5.xr</h3>
            +            </a>
            +          </div>
            +          <p>A library for creating VR and AR sketches with p5. निर्माता:
            +            <a href="https://www.stalgiagrigg.name/"
            +              target="_blank">Stalgia Grigg</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/FreddieRa/p5.3D" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.3D.jpg">
            +              <h3>p5.3D</h3>
            +            </a>
            +          </div>
            +          <p>WebGL में 3D पाठ और छवियां।  निर्माता:
            +            <a href="https://freddierawlins.wixsite.com/site"
            +              target="_blank">Freddie Rawlins</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/reference/assets/Bold.ttf b/dist/hi/reference/assets/Bold.ttf
            new file mode 100644
            index 0000000000..50d81bdad5
            Binary files /dev/null and b/dist/hi/reference/assets/Bold.ttf differ
            diff --git a/dist/hi/reference/assets/Damscray.mp3 b/dist/hi/reference/assets/Damscray.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/hi/reference/assets/Damscray.mp3 differ
            diff --git a/dist/hi/reference/assets/Damscray.ogg b/dist/hi/reference/assets/Damscray.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/hi/reference/assets/Damscray.ogg differ
            diff --git a/dist/hi/reference/assets/Damscray_-_Dancing_Tiger_01.ogg b/dist/hi/reference/assets/Damscray_-_Dancing_Tiger_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/hi/reference/assets/Damscray_-_Dancing_Tiger_01.ogg differ
            diff --git a/dist/hi/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 b/dist/hi/reference/assets/Damscray_-_Dancing_Tiger_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/hi/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 differ
            diff --git a/dist/hi/reference/assets/Damscray_01.mp3 b/dist/hi/reference/assets/Damscray_01.mp3
            new file mode 100644
            index 0000000000..9653a67bb6
            Binary files /dev/null and b/dist/hi/reference/assets/Damscray_01.mp3 differ
            diff --git a/dist/hi/reference/assets/Damscray_01.ogg b/dist/hi/reference/assets/Damscray_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/hi/reference/assets/Damscray_01.ogg differ
            diff --git a/dist/hi/reference/assets/Damscray_02.mp3 b/dist/hi/reference/assets/Damscray_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/hi/reference/assets/Damscray_02.mp3 differ
            diff --git a/dist/hi/reference/assets/Damscray_02.ogg b/dist/hi/reference/assets/Damscray_02.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/hi/reference/assets/Damscray_02.ogg differ
            diff --git a/dist/hi/reference/assets/Damscray_DancingTiger.mp3 b/dist/hi/reference/assets/Damscray_DancingTiger.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/hi/reference/assets/Damscray_DancingTiger.mp3 differ
            diff --git a/dist/hi/reference/assets/Italic.ttf b/dist/hi/reference/assets/Italic.ttf
            new file mode 100644
            index 0000000000..e5a1a86e63
            Binary files /dev/null and b/dist/hi/reference/assets/Italic.ttf differ
            diff --git a/dist/hi/reference/assets/Regular.otf b/dist/hi/reference/assets/Regular.otf
            new file mode 100644
            index 0000000000..38941ae72f
            Binary files /dev/null and b/dist/hi/reference/assets/Regular.otf differ
            diff --git a/dist/hi/reference/assets/arnott-wallace-eye-loop-forever.gif b/dist/hi/reference/assets/arnott-wallace-eye-loop-forever.gif
            new file mode 100644
            index 0000000000..992757bbaf
            Binary files /dev/null and b/dist/hi/reference/assets/arnott-wallace-eye-loop-forever.gif differ
            diff --git a/dist/hi/reference/assets/arnott-wallace-wink-loop-once.gif b/dist/hi/reference/assets/arnott-wallace-wink-loop-once.gif
            new file mode 100644
            index 0000000000..94f2015ff3
            Binary files /dev/null and b/dist/hi/reference/assets/arnott-wallace-wink-loop-once.gif differ
            diff --git a/dist/hi/reference/assets/beat.mp3 b/dist/hi/reference/assets/beat.mp3
            new file mode 100644
            index 0000000000..3e5802604c
            Binary files /dev/null and b/dist/hi/reference/assets/beat.mp3 differ
            diff --git a/dist/hi/reference/assets/beat.ogg b/dist/hi/reference/assets/beat.ogg
            new file mode 100644
            index 0000000000..c13f86a41f
            Binary files /dev/null and b/dist/hi/reference/assets/beat.ogg differ
            diff --git a/dist/hi/reference/assets/beatbox.mp3 b/dist/hi/reference/assets/beatbox.mp3
            new file mode 100644
            index 0000000000..23fb92eb71
            Binary files /dev/null and b/dist/hi/reference/assets/beatbox.mp3 differ
            diff --git a/dist/hi/reference/assets/beatbox.ogg b/dist/hi/reference/assets/beatbox.ogg
            new file mode 100644
            index 0000000000..b2593a6340
            Binary files /dev/null and b/dist/hi/reference/assets/beatbox.ogg differ
            diff --git a/dist/hi/reference/assets/blobs.csv b/dist/hi/reference/assets/blobs.csv
            new file mode 100644
            index 0000000000..2b7f05d1a0
            --- /dev/null
            +++ b/dist/hi/reference/assets/blobs.csv
            @@ -0,0 +1,3 @@
            +ID,Name,Flavor,Shape,Color
            +Blob1,Blobby,Sweet,Blob,Pink
            +Blob2,Saddy,Savory,Blob,Blue
            \ No newline at end of file
            diff --git a/dist/hi/reference/assets/bricks.jpg b/dist/hi/reference/assets/bricks.jpg
            new file mode 100644
            index 0000000000..231161d752
            Binary files /dev/null and b/dist/hi/reference/assets/bricks.jpg differ
            diff --git a/dist/hi/reference/assets/bricks_third.jpg b/dist/hi/reference/assets/bricks_third.jpg
            new file mode 100644
            index 0000000000..2fdb075996
            Binary files /dev/null and b/dist/hi/reference/assets/bricks_third.jpg differ
            diff --git a/dist/hi/reference/assets/bx-spring.mp3 b/dist/hi/reference/assets/bx-spring.mp3
            new file mode 100644
            index 0000000000..4a955ab7fa
            Binary files /dev/null and b/dist/hi/reference/assets/bx-spring.mp3 differ
            diff --git a/dist/hi/reference/assets/bx-spring.ogg b/dist/hi/reference/assets/bx-spring.ogg
            new file mode 100644
            index 0000000000..b01abee927
            Binary files /dev/null and b/dist/hi/reference/assets/bx-spring.ogg differ
            diff --git a/dist/hi/reference/assets/concrete-tunnel.mp3 b/dist/hi/reference/assets/concrete-tunnel.mp3
            new file mode 100644
            index 0000000000..1bfbd4f8f8
            Binary files /dev/null and b/dist/hi/reference/assets/concrete-tunnel.mp3 differ
            diff --git a/dist/hi/reference/assets/concrete-tunnel.ogg b/dist/hi/reference/assets/concrete-tunnel.ogg
            new file mode 100644
            index 0000000000..be5f66b72c
            Binary files /dev/null and b/dist/hi/reference/assets/concrete-tunnel.ogg differ
            diff --git a/dist/hi/reference/assets/doorbell.mp3 b/dist/hi/reference/assets/doorbell.mp3
            new file mode 100644
            index 0000000000..44b6367916
            Binary files /dev/null and b/dist/hi/reference/assets/doorbell.mp3 differ
            diff --git a/dist/hi/reference/assets/doorbell.ogg b/dist/hi/reference/assets/doorbell.ogg
            new file mode 100644
            index 0000000000..e816288c97
            Binary files /dev/null and b/dist/hi/reference/assets/doorbell.ogg differ
            diff --git a/dist/hi/reference/assets/drawImage.png b/dist/hi/reference/assets/drawImage.png
            new file mode 100644
            index 0000000000..1a7aa5d1d8
            Binary files /dev/null and b/dist/hi/reference/assets/drawImage.png differ
            diff --git a/dist/hi/reference/assets/drum.mp3 b/dist/hi/reference/assets/drum.mp3
            new file mode 100644
            index 0000000000..9cd8727617
            Binary files /dev/null and b/dist/hi/reference/assets/drum.mp3 differ
            diff --git a/dist/hi/reference/assets/drum.ogg b/dist/hi/reference/assets/drum.ogg
            new file mode 100644
            index 0000000000..5061a1b319
            Binary files /dev/null and b/dist/hi/reference/assets/drum.ogg differ
            diff --git a/dist/hi/reference/assets/favicon.ico b/dist/hi/reference/assets/favicon.ico
            new file mode 100644
            index 0000000000..33ad9806c8
            Binary files /dev/null and b/dist/hi/reference/assets/favicon.ico differ
            diff --git a/dist/hi/reference/assets/fingers.mov b/dist/hi/reference/assets/fingers.mov
            new file mode 100644
            index 0000000000..a9cbbbe3ea
            Binary files /dev/null and b/dist/hi/reference/assets/fingers.mov differ
            diff --git a/dist/hi/reference/assets/gradient.png b/dist/hi/reference/assets/gradient.png
            new file mode 100644
            index 0000000000..5245af69cd
            Binary files /dev/null and b/dist/hi/reference/assets/gradient.png differ
            diff --git a/dist/hi/reference/assets/inconsolata.otf b/dist/hi/reference/assets/inconsolata.otf
            new file mode 100644
            index 0000000000..e7e1fa0cd7
            Binary files /dev/null and b/dist/hi/reference/assets/inconsolata.otf differ
            diff --git a/dist/hi/reference/assets/index.html b/dist/hi/reference/assets/index.html
            new file mode 100644
            index 0000000000..487fe15b2a
            --- /dev/null
            +++ b/dist/hi/reference/assets/index.html
            @@ -0,0 +1,10 @@
            +<!doctype html>
            +<html>
            +    <head>
            +        <title>Redirector</title>
            +        <meta http-equiv="refresh" content="0;url=../">
            +    </head>
            +    <body>
            +        <a href="../">Click here to redirect</a>
            +    </body>
            +</html>
            diff --git a/dist/hi/reference/assets/laDefense.jpg b/dist/hi/reference/assets/laDefense.jpg
            new file mode 100644
            index 0000000000..3b8fdfe4b8
            Binary files /dev/null and b/dist/hi/reference/assets/laDefense.jpg differ
            diff --git a/dist/hi/reference/assets/large-dark-plate.mp3 b/dist/hi/reference/assets/large-dark-plate.mp3
            new file mode 100644
            index 0000000000..b9a15cbed7
            Binary files /dev/null and b/dist/hi/reference/assets/large-dark-plate.mp3 differ
            diff --git a/dist/hi/reference/assets/large-dark-plate.ogg b/dist/hi/reference/assets/large-dark-plate.ogg
            new file mode 100644
            index 0000000000..40115377e5
            Binary files /dev/null and b/dist/hi/reference/assets/large-dark-plate.ogg differ
            diff --git a/dist/hi/reference/assets/lucky_dragons.mp3 b/dist/hi/reference/assets/lucky_dragons.mp3
            new file mode 100644
            index 0000000000..c54c70c01a
            Binary files /dev/null and b/dist/hi/reference/assets/lucky_dragons.mp3 differ
            diff --git a/dist/hi/reference/assets/lucky_dragons.ogg b/dist/hi/reference/assets/lucky_dragons.ogg
            new file mode 100644
            index 0000000000..1e5b9e7abc
            Binary files /dev/null and b/dist/hi/reference/assets/lucky_dragons.ogg differ
            diff --git a/dist/hi/reference/assets/mammals.csv b/dist/hi/reference/assets/mammals.csv
            new file mode 100644
            index 0000000000..549984e37e
            --- /dev/null
            +++ b/dist/hi/reference/assets/mammals.csv
            @@ -0,0 +1,4 @@
            +id,species,name
            +0,Capra hircus,Goat
            +1,Panthera pardus,Leopard
            +2,Equus zebra,Zebra
            \ No newline at end of file
            diff --git a/dist/hi/reference/assets/mammals.xml b/dist/hi/reference/assets/mammals.xml
            new file mode 100644
            index 0000000000..752da754bf
            --- /dev/null
            +++ b/dist/hi/reference/assets/mammals.xml
            @@ -0,0 +1,6 @@
            +<?xml version="1.0"?>
            +<mammals>
            +  <animal id="0" species="Capra hircus">Goat</animal>
            +  <animal id="1" species="Panthera pardus">Leopard</animal>
            +  <animal id="2" species="Equus zebra">Zebra</animal>
            +</mammals>
            \ No newline at end of file
            diff --git a/dist/hi/reference/assets/mask.png b/dist/hi/reference/assets/mask.png
            new file mode 100644
            index 0000000000..a6737489b9
            Binary files /dev/null and b/dist/hi/reference/assets/mask.png differ
            diff --git a/dist/hi/reference/assets/mask2.png b/dist/hi/reference/assets/mask2.png
            new file mode 100644
            index 0000000000..2fb4aea99b
            Binary files /dev/null and b/dist/hi/reference/assets/mask2.png differ
            diff --git a/dist/hi/reference/assets/moonwalk.jpg b/dist/hi/reference/assets/moonwalk.jpg
            new file mode 100644
            index 0000000000..c418e6f573
            Binary files /dev/null and b/dist/hi/reference/assets/moonwalk.jpg differ
            diff --git a/dist/hi/reference/assets/nancy-liang-wind-loop-forever.gif b/dist/hi/reference/assets/nancy-liang-wind-loop-forever.gif
            new file mode 100644
            index 0000000000..a946253ede
            Binary files /dev/null and b/dist/hi/reference/assets/nancy-liang-wind-loop-forever.gif differ
            diff --git a/dist/hi/reference/assets/octahedron.obj b/dist/hi/reference/assets/octahedron.obj
            new file mode 100644
            index 0000000000..fed774d32a
            --- /dev/null
            +++ b/dist/hi/reference/assets/octahedron.obj
            @@ -0,0 +1,15 @@
            +v 0.000000E+00 0.000000E+00 40.0000
            +v 22.5000 22.5000 0.000000E+00
            +v 22.5000 -22.5000 0.000000E+00
            +v -22.5000 -22.5000 0.000000E+00
            +v -22.5000 22.5000 0.000000E+00
            +v 0.000000E+00 0.000000E+00 -40.0000
            +
            +f     1 2 3
            +f     1 3 4
            +f     1 4 5
            +f     1 5 2
            +f     6 5 4
            +f     6 4 3
            +f     6 3 2
            +f     6 2 5
            diff --git a/dist/hi/reference/assets/rockies.jpg b/dist/hi/reference/assets/rockies.jpg
            new file mode 100644
            index 0000000000..9bc0e4a372
            Binary files /dev/null and b/dist/hi/reference/assets/rockies.jpg differ
            diff --git a/dist/hi/reference/assets/rockies128.jpg b/dist/hi/reference/assets/rockies128.jpg
            new file mode 100644
            index 0000000000..bf55d812b2
            Binary files /dev/null and b/dist/hi/reference/assets/rockies128.jpg differ
            diff --git a/dist/hi/reference/assets/shader-gradient.frag b/dist/hi/reference/assets/shader-gradient.frag
            new file mode 100644
            index 0000000000..09a0cdc64b
            --- /dev/null
            +++ b/dist/hi/reference/assets/shader-gradient.frag
            @@ -0,0 +1,22 @@
            +// Code adopted from "Creating a Gradient Color in Fragment Shader"
            +// by Bahadır on stackoverflow.com
            +// https://stackoverflow.com/questions/47376499/creating-a-gradient-color-in-fragment-shader
            +
            +
            +precision highp float; varying vec2 vPos;
            +uniform vec2 offset;
            +uniform vec3 colorCenter;
            +uniform vec3 colorBackground;
            +
            +void main() {
            +
            +  vec2 st = vPos.xy + offset.xy;
            +
            +  // color1 = vec3(1.0,0.55,0);
            +  // color2 = vec3(0.226,0.000,0.615);
            +
            +  float mixValue = distance(st,vec2(0,1));
            +  vec3 color = mix(colorCenter,colorBackground,mixValue);
            +
            +  gl_FragColor = vec4(color,mixValue);
            +}
            \ No newline at end of file
            diff --git a/dist/hi/reference/assets/shader.frag b/dist/hi/reference/assets/shader.frag
            new file mode 100644
            index 0000000000..d3d76eb77a
            --- /dev/null
            +++ b/dist/hi/reference/assets/shader.frag
            @@ -0,0 +1,16 @@
            +precision highp float; varying vec2 vPos;
            +uniform vec2 p;
            +uniform float r;
            +const int I = 500;
            +void main() {
            +  vec2 c = p + vPos * r, z = c;
            +  float n = 0.0;
            +  for (int i = I; i > 0; i --) {
            +    if(z.x*z.x+z.y*z.y > 4.0) {
            +      n = float(i)/float(I);
            +      break;
            +    }
            +    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;
            +  }
            +  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);
            +}
            diff --git a/dist/hi/reference/assets/shader.vert b/dist/hi/reference/assets/shader.vert
            new file mode 100644
            index 0000000000..ea310c6770
            --- /dev/null
            +++ b/dist/hi/reference/assets/shader.vert
            @@ -0,0 +1,3 @@
            +precision highp float; varying vec2 vPos;
            +attribute vec3 aPosition;
            +void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }
            diff --git a/dist/hi/reference/assets/small-plate.mp3 b/dist/hi/reference/assets/small-plate.mp3
            new file mode 100644
            index 0000000000..656e154a5f
            Binary files /dev/null and b/dist/hi/reference/assets/small-plate.mp3 differ
            diff --git a/dist/hi/reference/assets/small-plate.ogg b/dist/hi/reference/assets/small-plate.ogg
            new file mode 100644
            index 0000000000..7b70d3349d
            Binary files /dev/null and b/dist/hi/reference/assets/small-plate.ogg differ
            diff --git a/dist/hi/reference/assets/small.mp4 b/dist/hi/reference/assets/small.mp4
            new file mode 100644
            index 0000000000..1fc478842f
            Binary files /dev/null and b/dist/hi/reference/assets/small.mp4 differ
            diff --git a/dist/hi/reference/assets/small.ogv b/dist/hi/reference/assets/small.ogv
            new file mode 100644
            index 0000000000..2b35a41aa4
            Binary files /dev/null and b/dist/hi/reference/assets/small.ogv differ
            diff --git a/dist/hi/reference/assets/small.webm b/dist/hi/reference/assets/small.webm
            new file mode 100644
            index 0000000000..da946da529
            Binary files /dev/null and b/dist/hi/reference/assets/small.webm differ
            diff --git a/dist/hi/reference/assets/studio-b.mp3 b/dist/hi/reference/assets/studio-b.mp3
            new file mode 100644
            index 0000000000..cbc792bfc9
            Binary files /dev/null and b/dist/hi/reference/assets/studio-b.mp3 differ
            diff --git a/dist/hi/reference/assets/studio-b.ogg b/dist/hi/reference/assets/studio-b.ogg
            new file mode 100644
            index 0000000000..cd68db07e6
            Binary files /dev/null and b/dist/hi/reference/assets/studio-b.ogg differ
            diff --git a/dist/hi/reference/assets/teapot.obj b/dist/hi/reference/assets/teapot.obj
            new file mode 100644
            index 0000000000..cedb196a4e
            --- /dev/null
            +++ b/dist/hi/reference/assets/teapot.obj
            @@ -0,0 +1,4663 @@
            +# Blender v2.61 (sub 0) OBJ File: ''
            +# www.blender.org
            +v 0.605903 0.005903 -0.000000
            +v 0.000000 0.000000 0.000000
            +v 0.584584 0.005902 -0.162696
            +v 0.524218 0.005902 -0.307888
            +v 0.430191 0.005901 -0.430191
            +v 0.307888 0.005901 -0.524218
            +v 0.162696 0.005901 -0.584584
            +v 0.000000 0.005901 -0.605903
            +v -0.162696 0.005901 -0.584584
            +v -0.307888 0.005901 -0.524218
            +v -0.430191 0.005901 -0.430191
            +v -0.524218 0.005902 -0.307888
            +v -0.584584 0.005902 -0.162696
            +v -0.605903 0.005903 -0.000000
            +v -0.584584 0.005904 0.162696
            +v -0.524218 0.005904 0.307888
            +v -0.430191 0.005905 0.430191
            +v -0.307888 0.005905 0.524218
            +v -0.162696 0.005905 0.584584
            +v 0.000000 0.005905 0.605903
            +v 0.162696 0.005905 0.584584
            +v 0.307888 0.005905 0.524218
            +v 0.430191 0.005905 0.430191
            +v 0.524218 0.005904 0.307888
            +v 0.584584 0.005904 0.162696
            +v 1.400000 2.400000 -0.000008
            +v 1.350740 2.400000 0.375917
            +v 1.332760 2.454690 0.370913
            +v 1.381370 2.454690 -0.000009
            +v 1.384260 2.487500 -0.000009
            +v 1.335550 2.487500 0.371690
            +v 1.403120 2.498440 -0.000009
            +v 1.353760 2.498440 0.376756
            +v 1.382010 2.487500 0.384619
            +v 1.432410 2.487500 -0.000009
            +v 1.414950 2.454690 0.393787
            +v 1.466550 2.454690 -0.000009
            +v 1.447220 2.400000 0.402769
            +v 1.500000 2.400000 -0.000008
            +v 1.211260 2.400000 0.711398
            +v 1.195140 2.454690 0.701929
            +v 1.197640 2.487500 0.703400
            +v 1.213960 2.498440 0.712986
            +v 1.239300 2.487500 0.727866
            +v 1.268840 2.454690 0.745216
            +v 1.297780 2.400000 0.762213
            +v 0.994000 2.400000 0.993991
            +v 0.980770 2.454690 0.980761
            +v 0.982824 2.487500 0.982815
            +v 0.996219 2.498440 0.996210
            +v 1.017010 2.487500 1.017000
            +v 1.041250 2.454690 1.041240
            +v 1.065000 2.400000 1.064990
            +v 0.711407 2.400000 1.211250
            +v 0.701938 2.454690 1.195130
            +v 0.703409 2.487500 1.197630
            +v 0.712995 2.498440 1.213950
            +v 0.727875 2.487500 1.239290
            +v 0.745225 2.454690 1.268830
            +v 0.762222 2.400000 1.297770
            +v 0.375926 2.400010 1.350730
            +v 0.370922 2.454690 1.332750
            +v 0.371699 2.487500 1.335540
            +v 0.376765 2.498450 1.353750
            +v 0.384628 2.487500 1.382000
            +v 0.393796 2.454700 1.414940
            +v 0.402778 2.400010 1.447210
            +v 0.000000 2.400010 1.399990
            +v 0.000000 2.454690 1.381360
            +v 0.000000 2.487500 1.384250
            +v 0.000000 2.498450 1.403110
            +v 0.000000 2.487510 1.432400
            +v 0.000000 2.454700 1.466540
            +v 0.000000 2.400010 1.499990
            +v -0.375926 2.400010 1.350730
            +v -0.370922 2.454690 1.332750
            +v -0.371699 2.487500 1.335540
            +v -0.376765 2.498450 1.353750
            +v -0.384628 2.487500 1.382000
            +v -0.393796 2.454700 1.414940
            +v -0.402778 2.400010 1.447210
            +v -0.711407 2.400000 1.211250
            +v -0.701938 2.454690 1.195130
            +v -0.703409 2.487500 1.197630
            +v -0.712995 2.498440 1.213950
            +v -0.727875 2.487500 1.239290
            +v -0.745225 2.454690 1.268830
            +v -0.762222 2.400000 1.297770
            +v -0.994000 2.400000 0.993991
            +v -0.980770 2.454690 0.980761
            +v -0.982824 2.487500 0.982815
            +v -0.996219 2.498440 0.996210
            +v -1.017010 2.487500 1.017000
            +v -1.041250 2.454690 1.041240
            +v -1.065000 2.400000 1.064990
            +v -1.211260 2.400000 0.711398
            +v -1.195140 2.454690 0.701929
            +v -1.197640 2.487500 0.703400
            +v -1.213960 2.498440 0.712986
            +v -1.239300 2.487500 0.727866
            +v -1.268840 2.454690 0.745216
            +v -1.297780 2.400000 0.762213
            +v -1.350740 2.400000 0.375917
            +v -1.332760 2.454690 0.370913
            +v -1.335550 2.487500 0.371690
            +v -1.353760 2.498440 0.376756
            +v -1.382010 2.487500 0.384619
            +v -1.414950 2.454690 0.393787
            +v -1.447220 2.400000 0.402769
            +v -1.400000 2.400000 -0.000008
            +v -1.381370 2.454690 -0.000009
            +v -1.384260 2.487500 -0.000009
            +v -1.403120 2.498440 -0.000009
            +v -1.432410 2.487500 -0.000009
            +v -1.466550 2.454690 -0.000009
            +v -1.500000 2.400000 -0.000008
            +v -1.350740 2.400000 -0.375935
            +v -1.332760 2.454690 -0.370931
            +v -1.335550 2.487500 -0.371708
            +v -1.353760 2.498440 -0.376774
            +v -1.382010 2.487500 -0.384637
            +v -1.414950 2.454690 -0.393805
            +v -1.447220 2.400000 -0.402787
            +v -1.211260 2.400000 -0.711416
            +v -1.195140 2.454690 -0.701947
            +v -1.197640 2.487500 -0.703418
            +v -1.213960 2.498440 -0.713004
            +v -1.239300 2.487500 -0.727884
            +v -1.268840 2.454690 -0.745234
            +v -1.297780 2.400000 -0.762231
            +v -0.994000 2.400000 -0.994009
            +v -0.980770 2.454690 -0.980779
            +v -0.982824 2.487500 -0.982833
            +v -0.996219 2.498440 -0.996228
            +v -1.017010 2.487500 -1.017020
            +v -1.041250 2.454690 -1.041260
            +v -1.065000 2.400000 -1.065010
            +v -0.711407 2.400000 -1.211270
            +v -0.701938 2.454690 -1.195150
            +v -0.703409 2.487500 -1.197650
            +v -0.712995 2.498440 -1.213970
            +v -0.727875 2.487500 -1.239310
            +v -0.745225 2.454690 -1.268850
            +v -0.762222 2.400000 -1.297790
            +v -0.375926 2.400000 -1.350750
            +v -0.370922 2.454680 -1.332770
            +v -0.371699 2.487490 -1.335560
            +v -0.376765 2.498440 -1.353770
            +v -0.384628 2.487490 -1.382020
            +v -0.393796 2.454680 -1.414960
            +v -0.402778 2.399990 -1.447230
            +v 0.000000 2.399990 -1.400010
            +v 0.000000 2.454680 -1.381380
            +v 0.000000 2.487490 -1.384270
            +v 0.000000 2.498430 -1.403130
            +v 0.000000 2.487490 -1.432420
            +v 0.000000 2.454680 -1.466560
            +v 0.000000 2.399990 -1.500010
            +v 0.375926 2.400000 -1.350750
            +v 0.370922 2.454680 -1.332770
            +v 0.371699 2.487490 -1.335560
            +v 0.376765 2.498440 -1.353770
            +v 0.384628 2.487490 -1.382020
            +v 0.393796 2.454680 -1.414960
            +v 0.402778 2.399990 -1.447230
            +v 0.711407 2.400000 -1.211270
            +v 0.701938 2.454690 -1.195150
            +v 0.703409 2.487500 -1.197650
            +v 0.712995 2.498440 -1.213970
            +v 0.727875 2.487500 -1.239310
            +v 0.745225 2.454690 -1.268850
            +v 0.762222 2.400000 -1.297790
            +v 0.994000 2.400000 -0.994009
            +v 0.980770 2.454690 -0.980779
            +v 0.982824 2.487500 -0.982833
            +v 0.996219 2.498440 -0.996228
            +v 1.017010 2.487500 -1.017020
            +v 1.041250 2.454690 -1.041260
            +v 1.065000 2.400000 -1.065010
            +v 1.211260 2.400000 -0.711416
            +v 1.195140 2.454690 -0.701947
            +v 1.197640 2.487500 -0.703418
            +v 1.213960 2.498440 -0.713004
            +v 1.239300 2.487500 -0.727884
            +v 1.268840 2.454690 -0.745234
            +v 1.297780 2.400000 -0.762231
            +v 1.350740 2.400000 -0.375935
            +v 1.332760 2.454690 -0.370931
            +v 1.335550 2.487500 -0.371708
            +v 1.353760 2.498440 -0.376774
            +v 1.382010 2.487500 -0.384637
            +v 1.414950 2.454690 -0.393805
            +v 1.447220 2.400000 -0.402787
            +v 1.566710 2.137850 0.436024
            +v 1.623840 2.137850 -0.000008
            +v 1.679490 1.877780 0.467414
            +v 1.740740 1.877780 -0.000007
            +v 1.778880 1.621880 0.495075
            +v 1.843750 1.621870 -0.000006
            +v 1.858160 1.372220 0.517142
            +v 1.925930 1.372220 -0.000005
            +v 1.910650 1.130900 0.531750
            +v 1.980320 1.130900 -0.000004
            +v 1.929630 0.900002 0.537034
            +v 2.000000 0.900000 -0.000003
            +v 1.404920 2.137850 0.825145
            +v 1.506060 1.877780 0.884547
            +v 1.595190 1.621880 0.936892
            +v 1.666280 1.372220 0.978651
            +v 1.713350 1.130900 1.006300
            +v 1.730370 0.900004 1.016300
            +v 1.152930 2.137850 1.152920
            +v 1.235930 1.877780 1.235920
            +v 1.309060 1.621870 1.309050
            +v 1.367410 1.372230 1.367400
            +v 1.406030 1.130910 1.406030
            +v 1.420000 0.900005 1.420000
            +v 0.825153 2.137860 1.404910
            +v 0.884554 1.877790 1.506050
            +v 0.936898 1.621890 1.595180
            +v 0.978656 1.372230 1.666270
            +v 1.006300 1.130910 1.713350
            +v 1.016300 0.900006 1.730370
            +v 0.436032 2.137860 1.566700
            +v 0.467421 1.877790 1.679480
            +v 0.495081 1.621880 1.778870
            +v 0.517147 1.372230 1.858150
            +v 0.531754 1.130910 1.910650
            +v 0.537037 0.900007 1.929630
            +v 0.000000 2.137860 1.623830
            +v 0.000000 1.877790 1.740730
            +v 0.000000 1.621880 1.843740
            +v 0.000000 1.372230 1.925920
            +v 0.000000 1.130910 1.980320
            +v 0.000000 0.900007 2.000000
            +v -0.436032 2.137860 1.566700
            +v -0.467421 1.877790 1.679480
            +v -0.495081 1.621890 1.778870
            +v -0.517147 1.372230 1.858150
            +v -0.531754 1.130910 1.910650
            +v -0.537037 0.900007 1.929630
            +v -0.825153 2.137860 1.404910
            +v -0.884554 1.877790 1.506050
            +v -0.936898 1.621890 1.595180
            +v -0.978656 1.372230 1.666270
            +v -1.006300 1.130910 1.713350
            +v -1.016300 0.900006 1.730370
            +v -1.152930 2.137850 1.152920
            +v -1.235930 1.877780 1.235920
            +v -1.309060 1.621870 1.309050
            +v -1.367410 1.372230 1.367400
            +v -1.406030 1.130910 1.406030
            +v -1.420000 0.900005 1.420000
            +v -1.404920 2.137850 0.825145
            +v -1.506060 1.877780 0.884547
            +v -1.595190 1.621880 0.936892
            +v -1.666280 1.372220 0.978651
            +v -1.713350 1.130900 1.006300
            +v -1.730370 0.900004 1.016300
            +v -1.566710 2.137850 0.436024
            +v -1.679490 1.877780 0.467414
            +v -1.778880 1.621870 0.495075
            +v -1.858160 1.372220 0.517142
            +v -1.910650 1.130900 0.531750
            +v -1.929630 0.900002 0.537034
            +v -1.623840 2.137850 -0.000008
            +v -1.740740 1.877780 -0.000007
            +v -1.843750 1.621870 -0.000006
            +v -1.925930 1.372220 -0.000005
            +v -1.980320 1.130900 -0.000004
            +v -2.000000 0.900000 -0.000003
            +v -1.566710 2.137850 -0.436040
            +v -1.679490 1.877780 -0.467428
            +v -1.778880 1.621880 -0.495087
            +v -1.858160 1.372220 -0.517152
            +v -1.910650 1.130900 -0.531758
            +v -1.929630 0.899998 -0.537040
            +v -1.404920 2.137850 -0.825161
            +v -1.506060 1.877780 -0.884561
            +v -1.595190 1.621880 -0.936904
            +v -1.666280 1.372220 -0.978661
            +v -1.713350 1.130900 -1.006300
            +v -1.730370 0.899996 -1.016300
            +v -1.152930 2.137850 -1.152940
            +v -1.235930 1.877780 -1.235940
            +v -1.309060 1.621870 -1.309070
            +v -1.367410 1.372220 -1.367420
            +v -1.406030 1.130890 -1.406030
            +v -1.420000 0.899995 -1.420000
            +v -0.825153 2.137840 -1.404930
            +v -0.884554 1.877770 -1.506070
            +v -0.936898 1.621870 -1.595200
            +v -0.978656 1.372210 -1.666290
            +v -1.006300 1.130890 -1.713350
            +v -1.016300 0.899994 -1.730370
            +v -0.436032 2.137840 -1.566720
            +v -0.467421 1.877770 -1.679500
            +v -0.495081 1.621860 -1.778890
            +v -0.517147 1.372210 -1.858170
            +v -0.531754 1.130890 -1.910650
            +v -0.537037 0.899993 -1.929630
            +v 0.000000 2.137840 -1.623850
            +v 0.000000 1.877770 -1.740750
            +v 0.000000 1.621860 -1.843760
            +v 0.000000 1.372210 -1.925940
            +v 0.000000 1.130890 -1.980320
            +v 0.000000 0.899993 -2.000000
            +v 0.436032 2.137840 -1.566720
            +v 0.467421 1.877770 -1.679500
            +v 0.495081 1.621870 -1.778890
            +v 0.517147 1.372210 -1.858170
            +v 0.531754 1.130890 -1.910650
            +v 0.537037 0.899993 -1.929630
            +v 0.825153 2.137840 -1.404930
            +v 0.884554 1.877770 -1.506070
            +v 0.936898 1.621870 -1.595200
            +v 0.978656 1.372210 -1.666290
            +v 1.006300 1.130890 -1.713350
            +v 1.016300 0.899994 -1.730370
            +v 1.152930 2.137850 -1.152940
            +v 1.235930 1.877780 -1.235940
            +v 1.309060 1.621870 -1.309070
            +v 1.367410 1.372220 -1.367420
            +v 1.406030 1.130890 -1.406030
            +v 1.420000 0.899995 -1.420000
            +v 1.404920 2.137850 -0.825161
            +v 1.506060 1.877780 -0.884561
            +v 1.595190 1.621880 -0.936904
            +v 1.666280 1.372220 -0.978661
            +v 1.713350 1.130900 -1.006300
            +v 1.730370 0.899996 -1.016300
            +v 1.566710 2.137850 -0.436040
            +v 1.679490 1.877780 -0.467428
            +v 1.778880 1.621870 -0.495087
            +v 1.858160 1.372220 -0.517152
            +v 1.910650 1.130900 -0.531758
            +v 1.929630 0.899998 -0.537040
            +v 1.893900 0.693405 0.527089
            +v 1.962960 0.693403 -0.000002
            +v 1.804560 0.522224 0.502227
            +v 1.870370 0.522222 -0.000002
            +v 1.688430 0.384377 0.469906
            +v 1.750000 0.384375 -0.000001
            +v 1.572290 0.277780 0.437585
            +v 1.629630 0.277778 -0.000001
            +v 1.482960 0.200349 0.412722
            +v 1.537040 0.200347 -0.000001
            +v 1.447220 0.150001 0.402777
            +v 1.500000 0.150000 -0.000001
            +v 1.698330 0.693407 0.997473
            +v 1.618220 0.522225 0.950423
            +v 1.514070 0.384378 0.889258
            +v 1.409930 0.277781 0.828092
            +v 1.329820 0.200350 0.781042
            +v 1.297780 0.150003 0.762221
            +v 1.393700 0.693408 1.393700
            +v 1.327960 0.522227 1.327960
            +v 1.242500 0.384380 1.242500
            +v 1.157040 0.277782 1.157040
            +v 1.091300 0.200351 1.091300
            +v 1.065000 0.150004 1.065000
            +v 0.997476 0.693409 1.698330
            +v 0.950425 0.522228 1.618220
            +v 0.889259 0.384381 1.514070
            +v 0.828093 0.277783 1.409930
            +v 0.781043 0.200352 1.329820
            +v 0.762222 0.150005 1.297780
            +v 0.527092 0.693410 1.893900
            +v 0.502229 0.522229 1.804560
            +v 0.469907 0.384381 1.688430
            +v 0.437586 0.277784 1.572290
            +v 0.412723 0.200352 1.482960
            +v 0.402778 0.150005 1.447220
            +v 0.000000 0.693410 1.962960
            +v 0.000000 0.522229 1.870370
            +v 0.000000 0.384381 1.750000
            +v 0.000000 0.277784 1.629630
            +v 0.000000 0.200353 1.537040
            +v 0.000000 0.150006 1.500000
            +v -0.527092 0.693410 1.893900
            +v -0.502229 0.522229 1.804560
            +v -0.469907 0.384381 1.688430
            +v -0.437586 0.277784 1.572290
            +v -0.412723 0.200352 1.482960
            +v -0.402778 0.150005 1.447220
            +v -0.997476 0.693409 1.698330
            +v -0.950425 0.522228 1.618220
            +v -0.889259 0.384381 1.514070
            +v -0.828093 0.277783 1.409930
            +v -0.781043 0.200352 1.329820
            +v -0.762222 0.150005 1.297780
            +v -1.393700 0.693408 1.393700
            +v -1.327960 0.522227 1.327960
            +v -1.242500 0.384380 1.242500
            +v -1.157040 0.277782 1.157040
            +v -1.091300 0.200351 1.091300
            +v -1.065000 0.150004 1.065000
            +v -1.698330 0.693407 0.997473
            +v -1.618220 0.522225 0.950423
            +v -1.514070 0.384378 0.889258
            +v -1.409930 0.277781 0.828092
            +v -1.329820 0.200350 0.781042
            +v -1.297780 0.150003 0.762221
            +v -1.893900 0.693405 0.527089
            +v -1.804560 0.522224 0.502227
            +v -1.688430 0.384377 0.469906
            +v -1.572290 0.277780 0.437585
            +v -1.482960 0.200349 0.412722
            +v -1.447220 0.150001 0.402777
            +v -1.962960 0.693403 -0.000002
            +v -1.870370 0.522222 -0.000002
            +v -1.750000 0.384375 -0.000001
            +v -1.629630 0.277778 -0.000001
            +v -1.537040 0.200347 -0.000001
            +v -1.500000 0.150000 -0.000001
            +v -1.893900 0.693401 -0.527095
            +v -1.804560 0.522220 -0.502231
            +v -1.688430 0.384373 -0.469908
            +v -1.572290 0.277776 -0.437587
            +v -1.482960 0.200345 -0.412724
            +v -1.447220 0.149999 -0.402779
            +v -1.698330 0.693399 -0.997479
            +v -1.618220 0.522218 -0.950427
            +v -1.514070 0.384372 -0.889260
            +v -1.409930 0.277775 -0.828094
            +v -1.329820 0.200344 -0.781044
            +v -1.297780 0.149997 -0.762223
            +v -1.393700 0.693398 -1.393700
            +v -1.327960 0.522217 -1.327960
            +v -1.242500 0.384370 -1.242500
            +v -1.157040 0.277774 -1.157040
            +v -1.091300 0.200343 -1.091300
            +v -1.065000 0.149996 -1.065000
            +v -0.997476 0.693397 -1.698330
            +v -0.950425 0.522216 -1.618220
            +v -0.889259 0.384369 -1.514070
            +v -0.828093 0.277773 -1.409930
            +v -0.781043 0.200342 -1.329820
            +v -0.762222 0.149995 -1.297780
            +v -0.527092 0.693396 -1.893900
            +v -0.502229 0.522215 -1.804560
            +v -0.469907 0.384369 -1.688430
            +v -0.437586 0.277772 -1.572290
            +v -0.412723 0.200342 -1.482960
            +v -0.402778 0.149995 -1.447220
            +v 0.000000 0.693396 -1.962960
            +v 0.000000 0.522215 -1.870370
            +v 0.000000 0.384369 -1.750000
            +v 0.000000 0.277772 -1.629630
            +v 0.000000 0.200341 -1.537040
            +v 0.000000 0.149994 -1.500000
            +v 0.527092 0.693396 -1.893900
            +v 0.502229 0.522215 -1.804560
            +v 0.469907 0.384369 -1.688430
            +v 0.437586 0.277772 -1.572290
            +v 0.412723 0.200342 -1.482960
            +v 0.402778 0.149995 -1.447220
            +v 0.997476 0.693397 -1.698330
            +v 0.950425 0.522216 -1.618220
            +v 0.889259 0.384369 -1.514070
            +v 0.828093 0.277773 -1.409930
            +v 0.781043 0.200342 -1.329820
            +v 0.762222 0.149995 -1.297780
            +v 1.393700 0.693398 -1.393700
            +v 1.327960 0.522217 -1.327960
            +v 1.242500 0.384370 -1.242500
            +v 1.157040 0.277774 -1.157040
            +v 1.091300 0.200343 -1.091300
            +v 1.065000 0.149996 -1.065000
            +v 1.698330 0.693399 -0.997479
            +v 1.618220 0.522218 -0.950427
            +v 1.514070 0.384372 -0.889260
            +v 1.409930 0.277775 -0.828094
            +v 1.329820 0.200344 -0.781044
            +v 1.297780 0.149997 -0.762223
            +v 1.893900 0.693401 -0.527095
            +v 1.804560 0.522220 -0.502231
            +v 1.688430 0.384373 -0.469908
            +v 1.572290 0.277776 -0.437587
            +v 1.482960 0.200345 -0.412724
            +v 1.447220 0.149999 -0.402779
            +v 1.022220 0.022222 -0.000000
            +v 0.986255 0.022221 -0.274486
            +v 1.284370 0.046875 -0.000000
            +v 1.239180 0.046874 -0.344878
            +v 1.427780 0.077778 -0.000000
            +v 1.377540 0.077777 -0.383385
            +v 1.487850 0.112847 -0.000000
            +v 1.435500 0.112846 -0.399515
            +v 0.884412 0.022220 -0.519440
            +v 1.111220 0.046873 -0.652653
            +v 1.235290 0.077775 -0.725523
            +v 1.287260 0.112844 -0.756047
            +v 0.725778 0.022219 -0.725778
            +v 0.911906 0.046872 -0.911906
            +v 1.013720 0.077774 -1.013720
            +v 1.056370 0.112843 -1.056370
            +v 0.519440 0.022219 -0.884412
            +v 0.652653 0.046871 -1.111220
            +v 0.725523 0.077774 -1.235290
            +v 0.756047 0.112842 -1.287260
            +v 0.274486 0.022219 -0.986255
            +v 0.344878 0.046871 -1.239180
            +v 0.383385 0.077773 -1.377540
            +v 0.399515 0.112842 -1.435500
            +v 0.000000 0.022218 -1.022220
            +v 0.000000 0.046871 -1.284370
            +v 0.000000 0.077773 -1.427780
            +v 0.000000 0.112842 -1.487850
            +v -0.274486 0.022219 -0.986255
            +v -0.344878 0.046871 -1.239180
            +v -0.383385 0.077773 -1.377540
            +v -0.399515 0.112842 -1.435500
            +v -0.519440 0.022219 -0.884412
            +v -0.652653 0.046871 -1.111220
            +v -0.725523 0.077774 -1.235290
            +v -0.756047 0.112842 -1.287260
            +v -0.725778 0.022219 -0.725778
            +v -0.911906 0.046872 -0.911906
            +v -1.013720 0.077774 -1.013720
            +v -1.056370 0.112843 -1.056370
            +v -0.884412 0.022220 -0.519440
            +v -1.111220 0.046873 -0.652653
            +v -1.235290 0.077775 -0.725523
            +v -1.287260 0.112844 -0.756047
            +v -0.986255 0.022221 -0.274486
            +v -1.239180 0.046874 -0.344878
            +v -1.377540 0.077777 -0.383385
            +v -1.435500 0.112846 -0.399515
            +v -1.022220 0.022222 -0.000000
            +v -1.284370 0.046875 -0.000000
            +v -1.427780 0.077778 -0.000000
            +v -1.487850 0.112847 -0.000000
            +v -0.986255 0.022223 0.274486
            +v -1.239180 0.046876 0.344878
            +v -1.377540 0.077779 0.383385
            +v -1.435500 0.112848 0.399515
            +v -0.884412 0.022224 0.519440
            +v -1.111220 0.046877 0.652653
            +v -1.235290 0.077781 0.725523
            +v -1.287260 0.112850 0.756047
            +v -0.725778 0.022225 0.725778
            +v -0.911906 0.046878 0.911906
            +v -1.013720 0.077782 1.013720
            +v -1.056370 0.112851 1.056370
            +v -0.519440 0.022225 0.884412
            +v -0.652653 0.046879 1.111220
            +v -0.725523 0.077782 1.235290
            +v -0.756047 0.112852 1.287260
            +v -0.274486 0.022225 0.986255
            +v -0.344878 0.046879 1.239180
            +v -0.383385 0.077783 1.377540
            +v -0.399515 0.112852 1.435500
            +v 0.000000 0.022226 1.022220
            +v 0.000000 0.046879 1.284370
            +v 0.000000 0.077783 1.427780
            +v 0.000000 0.112852 1.487850
            +v 0.274486 0.022225 0.986255
            +v 0.344878 0.046879 1.239180
            +v 0.383385 0.077783 1.377540
            +v 0.399515 0.112852 1.435500
            +v 0.519440 0.022225 0.884412
            +v 0.652653 0.046879 1.111220
            +v 0.725523 0.077782 1.235290
            +v 0.756047 0.112852 1.287260
            +v 0.725778 0.022225 0.725778
            +v 0.911906 0.046878 0.911906
            +v 1.013720 0.077782 1.013720
            +v 1.056370 0.112851 1.056370
            +v 0.884412 0.022224 0.519440
            +v 1.111220 0.046877 0.652653
            +v 1.235290 0.077781 0.725523
            +v 1.287260 0.112850 0.756047
            +v 0.986255 0.022223 0.274486
            +v 1.239180 0.046876 0.344878
            +v 1.377540 0.077779 0.383385
            +v 1.435500 0.112848 0.399515
            +v 0.192963 2.700000 0.053694
            +v 0.200000 2.700000 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.173037 2.700000 0.101620
            +v 0.148234 2.785420 0.087096
            +v 0.142000 2.700000 0.141990
            +v 0.121672 2.785420 0.121662
            +v 0.101630 2.700000 0.173027
            +v 0.087106 2.785420 0.148224
            +v 0.053704 2.700000 0.192953
            +v 0.046045 2.785420 0.165269
            +v 0.000000 2.700000 0.199990
            +v 0.000000 2.785420 0.171286
            +v -0.053704 2.700000 0.192953
            +v -0.046045 2.785420 0.165269
            +v -0.101630 2.700000 0.173027
            +v -0.087106 2.785420 0.148224
            +v -0.142000 2.700000 0.141990
            +v -0.121672 2.785420 0.121662
            +v -0.173037 2.700000 0.101620
            +v -0.148234 2.785420 0.087096
            +v -0.192963 2.700000 0.053694
            +v -0.165279 2.785420 0.046035
            +v -0.200000 2.700000 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.192963 2.700000 -0.053714
            +v -0.165279 2.785420 -0.046055
            +v -0.173037 2.700000 -0.101640
            +v -0.148234 2.785420 -0.087116
            +v -0.142000 2.700000 -0.142010
            +v -0.121672 2.785420 -0.121682
            +v -0.101630 2.700000 -0.173047
            +v -0.087106 2.785420 -0.148244
            +v -0.053704 2.700000 -0.192973
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 2.700000 -0.200010
            +v 0.000000 2.785420 -0.171306
            +v 0.053704 2.700000 -0.192973
            +v 0.046045 2.785420 -0.165289
            +v 0.101630 2.700000 -0.173047
            +v 0.087106 2.785420 -0.148244
            +v 0.142000 2.700000 -0.142010
            +v 0.121672 2.785420 -0.121682
            +v 0.173037 2.700000 -0.101640
            +v 0.148234 2.785420 -0.087116
            +v 0.192963 2.700000 -0.053714
            +v 0.165279 2.785420 -0.046055
            +v 0.338579 2.636110 0.094221
            +v 0.350926 2.636110 -0.000009
            +v 0.553875 2.588890 0.154140
            +v 0.574074 2.588890 -0.000009
            +v 0.795972 2.550000 0.221519
            +v 0.825000 2.550000 -0.000009
            +v 1.021990 2.511110 0.284422
            +v 1.059260 2.511110 -0.000009
            +v 1.189040 2.463890 0.330915
            +v 1.232410 2.463890 -0.000009
            +v 1.254260 2.400000 0.349065
            +v 1.300000 2.400000 -0.000008
            +v 0.303616 2.636110 0.178312
            +v 0.496680 2.588890 0.291705
            +v 0.713778 2.550000 0.419213
            +v 0.916455 2.511110 0.538252
            +v 1.066260 2.463890 0.626237
            +v 1.124740 2.400000 0.660584
            +v 0.249157 2.636110 0.249147
            +v 0.407593 2.588890 0.407583
            +v 0.585750 2.550000 0.585741
            +v 0.752074 2.511110 0.752065
            +v 0.875009 2.463890 0.875000
            +v 0.923000 2.400000 0.922991
            +v 0.178322 2.636110 0.303606
            +v 0.291715 2.588890 0.496670
            +v 0.419222 2.550000 0.713769
            +v 0.538261 2.511110 0.916446
            +v 0.626246 2.463890 1.066250
            +v 0.660593 2.400000 1.124730
            +v 0.094230 2.636110 0.338569
            +v 0.154150 2.588890 0.553865
            +v 0.221528 2.550000 0.795963
            +v 0.284431 2.511110 1.021980
            +v 0.330924 2.463890 1.189030
            +v 0.349074 2.400000 1.254250
            +v 0.000000 2.636110 0.350916
            +v 0.000000 2.588890 0.574064
            +v 0.000000 2.550000 0.824991
            +v 0.000000 2.511110 1.059250
            +v 0.000000 2.463890 1.232400
            +v 0.000000 2.400000 1.299990
            +v -0.094230 2.636110 0.338569
            +v -0.154150 2.588890 0.553865
            +v -0.221528 2.550000 0.795963
            +v -0.284431 2.511110 1.021980
            +v -0.330924 2.463890 1.189030
            +v -0.349074 2.400000 1.254250
            +v -0.178322 2.636110 0.303606
            +v -0.291715 2.588890 0.496670
            +v -0.419222 2.550000 0.713769
            +v -0.538261 2.511110 0.916446
            +v -0.626246 2.463890 1.066250
            +v -0.660593 2.400000 1.124730
            +v -0.249157 2.636110 0.249147
            +v -0.407593 2.588890 0.407583
            +v -0.585750 2.550000 0.585741
            +v -0.752074 2.511110 0.752065
            +v -0.875009 2.463890 0.875000
            +v -0.923000 2.400000 0.922991
            +v -0.303616 2.636110 0.178312
            +v -0.496680 2.588890 0.291705
            +v -0.713778 2.550000 0.419213
            +v -0.916455 2.511110 0.538252
            +v -1.066260 2.463890 0.626237
            +v -1.124740 2.400000 0.660584
            +v -0.338579 2.636110 0.094221
            +v -0.553875 2.588890 0.154140
            +v -0.795972 2.550000 0.221519
            +v -1.021990 2.511110 0.284422
            +v -1.189040 2.463890 0.330915
            +v -1.254260 2.400000 0.349065
            +v -0.350926 2.636110 -0.000009
            +v -0.574074 2.588890 -0.000009
            +v -0.825000 2.550000 -0.000009
            +v -1.059260 2.511110 -0.000009
            +v -1.232410 2.463890 -0.000009
            +v -1.300000 2.400000 -0.000008
            +v -0.338579 2.636110 -0.094239
            +v -0.553875 2.588890 -0.154160
            +v -0.795972 2.550000 -0.221537
            +v -1.021990 2.511110 -0.284440
            +v -1.189040 2.463890 -0.330933
            +v -1.254260 2.400000 -0.349083
            +v -0.303616 2.636110 -0.178332
            +v -0.496680 2.588890 -0.291725
            +v -0.713778 2.550000 -0.419231
            +v -0.916455 2.511110 -0.538270
            +v -1.066260 2.463890 -0.626255
            +v -1.124740 2.400000 -0.660602
            +v -0.249157 2.636110 -0.249167
            +v -0.407593 2.588890 -0.407603
            +v -0.585750 2.550000 -0.585759
            +v -0.752074 2.511110 -0.752083
            +v -0.875009 2.463890 -0.875018
            +v -0.923000 2.400000 -0.923009
            +v -0.178322 2.636110 -0.303626
            +v -0.291715 2.588890 -0.496690
            +v -0.419222 2.550000 -0.713787
            +v -0.538261 2.511110 -0.916464
            +v -0.626246 2.463890 -1.066270
            +v -0.660593 2.400000 -1.124750
            +v -0.094230 2.636110 -0.338589
            +v -0.154150 2.588890 -0.553885
            +v -0.221528 2.550000 -0.795981
            +v -0.284431 2.511110 -1.022000
            +v -0.330924 2.463890 -1.189050
            +v -0.349074 2.400000 -1.254270
            +v 0.000000 2.636110 -0.350936
            +v 0.000000 2.588890 -0.574084
            +v 0.000000 2.550000 -0.825009
            +v 0.000000 2.511110 -1.059270
            +v 0.000000 2.463890 -1.232420
            +v 0.000000 2.400000 -1.300010
            +v 0.094230 2.636110 -0.338589
            +v 0.154150 2.588890 -0.553885
            +v 0.221528 2.550000 -0.795981
            +v 0.284431 2.511110 -1.022000
            +v 0.330924 2.463890 -1.189050
            +v 0.349074 2.400000 -1.254270
            +v 0.178322 2.636110 -0.303626
            +v 0.291715 2.588890 -0.496690
            +v 0.419222 2.550000 -0.713787
            +v 0.538261 2.511110 -0.916464
            +v 0.626246 2.463890 -1.066270
            +v 0.660593 2.400000 -1.124750
            +v 0.249157 2.636110 -0.249167
            +v 0.407593 2.588890 -0.407603
            +v 0.585750 2.550000 -0.585759
            +v 0.752074 2.511110 -0.752083
            +v 0.875009 2.463890 -0.875018
            +v 0.923000 2.400000 -0.923009
            +v 0.303616 2.636110 -0.178332
            +v 0.496680 2.588890 -0.291725
            +v 0.713778 2.550000 -0.419231
            +v 0.916455 2.511110 -0.538270
            +v 1.066260 2.463890 -0.626255
            +v 1.124740 2.400000 -0.660602
            +v 0.338579 2.636110 -0.094239
            +v 0.553875 2.588890 -0.154160
            +v 0.795972 2.550000 -0.221537
            +v 1.021990 2.511110 -0.284440
            +v 1.189040 2.463890 -0.330933
            +v 1.254260 2.400000 -0.349083
            +v -1.924540 2.023960 -0.000007
            +v -1.600000 2.025000 -0.000007
            +v -1.927040 2.040550 0.124992
            +v -1.592590 2.041670 0.124992
            +v -2.196300 2.016670 -0.000007
            +v -2.206450 2.032720 0.124992
            +v -2.428240 2.011460 0.124993
            +v -2.412500 1.996870 -0.000007
            +v -2.589850 1.970060 0.124993
            +v -2.570370 1.958330 -0.000007
            +v -2.688700 1.901810 0.124993
            +v -2.667130 1.894790 -0.000007
            +v -2.722220 1.800000 0.124993
            +v -2.700000 1.800000 -0.000006
            +v -1.933300 2.082020 0.199992
            +v -1.574070 2.083330 0.199992
            +v -2.231820 2.072840 0.199992
            +v -2.467590 2.047920 0.199992
            +v -2.638550 1.999380 0.199993
            +v -2.742630 1.919370 0.199993
            +v -2.777780 1.800000 0.199993
            +v -1.941440 2.135940 0.224992
            +v -1.550000 2.137500 0.224992
            +v -2.264810 2.125000 0.224992
            +v -2.518750 2.095310 0.224992
            +v -2.701850 2.037500 0.224992
            +v -2.812730 1.942190 0.224993
            +v -2.850000 1.800000 0.224993
            +v -1.949570 2.189850 0.199992
            +v -1.525930 2.191670 0.199992
            +v -2.297810 2.177160 0.199992
            +v -2.569910 2.142710 0.199992
            +v -2.765160 2.075620 0.199992
            +v -2.882840 1.965010 0.199993
            +v -2.922220 1.800000 0.199993
            +v -1.955830 2.231330 0.124992
            +v -1.507410 2.233330 0.124992
            +v -2.323180 2.217280 0.124992
            +v -2.609260 2.179170 0.124992
            +v -2.813850 2.104940 0.124992
            +v -2.936760 1.982560 0.124993
            +v -2.977780 1.800000 0.124993
            +v -1.958330 2.247920 -0.000008
            +v -1.500000 2.250000 -0.000008
            +v -2.333330 2.233330 -0.000008
            +v -2.625000 2.193750 -0.000008
            +v -2.833330 2.116670 -0.000007
            +v -2.958330 1.989580 -0.000007
            +v -3.000000 1.800000 -0.000006
            +v -1.507410 2.233330 -0.125008
            +v -1.955830 2.231330 -0.125008
            +v -2.323180 2.217280 -0.125008
            +v -2.609260 2.179170 -0.125008
            +v -2.813850 2.104940 -0.125008
            +v -2.936760 1.982560 -0.125007
            +v -2.977780 1.800000 -0.125007
            +v -1.525930 2.191670 -0.200008
            +v -1.949570 2.189850 -0.200008
            +v -2.297810 2.177160 -0.200008
            +v -2.569910 2.142710 -0.200008
            +v -2.765160 2.075620 -0.200008
            +v -2.882840 1.965010 -0.200007
            +v -2.922220 1.800000 -0.200007
            +v -1.550000 2.137500 -0.225008
            +v -1.941440 2.135940 -0.225008
            +v -2.264810 2.125000 -0.225008
            +v -2.518750 2.095310 -0.225008
            +v -2.701850 2.037500 -0.225008
            +v -2.812730 1.942190 -0.225007
            +v -2.850000 1.800000 -0.225007
            +v -1.574070 2.083330 -0.200008
            +v -1.933300 2.082020 -0.200008
            +v -2.231820 2.072840 -0.200008
            +v -2.467590 2.047920 -0.200008
            +v -2.638550 1.999380 -0.200007
            +v -2.742630 1.919370 -0.200007
            +v -2.777780 1.800000 -0.200007
            +v -1.592590 2.041670 -0.125008
            +v -1.927040 2.040550 -0.125008
            +v -2.206450 2.032720 -0.125008
            +v -2.428240 2.011460 -0.125007
            +v -2.589850 1.970060 -0.125007
            +v -2.688700 1.901810 -0.125007
            +v -2.722220 1.800000 -0.125007
            +v -2.704180 1.663980 0.124994
            +v -2.682870 1.670830 -0.000006
            +v -2.648290 1.505350 0.124994
            +v -2.629630 1.516670 -0.000005
            +v -2.551850 1.335760 0.124995
            +v -2.537500 1.350000 -0.000005
            +v -2.412210 1.166870 0.124996
            +v -2.403700 1.183330 -0.000004
            +v -2.226680 1.010330 0.124996
            +v -2.225460 1.029170 -0.000004
            +v -1.992590 0.877778 0.124997
            +v -2.000000 0.900000 -0.000003
            +v -2.757470 1.646840 0.199994
            +v -2.694920 1.477060 0.199995
            +v -2.587730 1.300170 0.199995
            +v -2.433470 1.125720 0.199996
            +v -2.229720 0.963228 0.199996
            +v -1.974070 0.822223 0.199997
            +v -2.826740 1.624570 0.224994
            +v -2.755560 1.440280 0.224995
            +v -2.634370 1.253910 0.224995
            +v -2.461110 1.072220 0.224996
            +v -2.233680 0.901998 0.224997
            +v -1.950000 0.750001 0.224997
            +v -2.896000 1.602290 0.199994
            +v -2.816190 1.403500 0.199995
            +v -2.681020 1.207640 0.199996
            +v -2.488750 1.018720 0.199996
            +v -2.237640 0.840767 0.199997
            +v -1.925930 0.677779 0.199997
            +v -2.949290 1.585150 0.124994
            +v -2.862830 1.375210 0.124995
            +v -2.716900 1.172050 0.124996
            +v -2.510010 0.977573 0.124996
            +v -2.240680 0.793666 0.124997
            +v -1.907410 0.622222 0.124998
            +v -2.970600 1.578300 -0.000006
            +v -2.881480 1.363890 -0.000005
            +v -2.731250 1.157810 -0.000004
            +v -2.518520 0.961111 -0.000003
            +v -2.241900 0.774826 -0.000003
            +v -1.900000 0.600000 -0.000002
            +v -2.949290 1.585150 -0.125006
            +v -2.862830 1.375210 -0.125005
            +v -2.716900 1.172050 -0.125004
            +v -2.510010 0.977572 -0.125004
            +v -2.240680 0.793666 -0.125003
            +v -1.907410 0.622222 -0.125002
            +v -2.896000 1.602290 -0.200006
            +v -2.816190 1.403500 -0.200005
            +v -2.681020 1.207640 -0.200004
            +v -2.488750 1.018720 -0.200004
            +v -2.237640 0.840765 -0.200003
            +v -1.925930 0.677777 -0.200003
            +v -2.826740 1.624570 -0.225006
            +v -2.755560 1.440280 -0.225005
            +v -2.634370 1.253910 -0.225005
            +v -2.461110 1.072220 -0.225004
            +v -2.233680 0.901996 -0.225003
            +v -1.950000 0.749999 -0.225003
            +v -2.757470 1.646840 -0.200006
            +v -2.694920 1.477060 -0.200005
            +v -2.587730 1.300170 -0.200005
            +v -2.433470 1.125720 -0.200004
            +v -2.229720 0.963226 -0.200004
            +v -1.974070 0.822221 -0.200003
            +v -2.704180 1.663980 -0.125006
            +v -2.648290 1.505350 -0.125006
            +v -2.551850 1.335760 -0.125005
            +v -2.412210 1.166870 -0.125004
            +v -2.226680 1.010330 -0.125004
            +v -1.992590 0.877778 -0.125003
            +v 1.700000 1.425000 -0.000005
            +v 1.700000 1.363890 0.274995
            +v 2.072380 1.425210 0.262341
            +v 2.058800 1.476390 -0.000005
            +v 2.290120 1.572020 0.230704
            +v 2.270370 1.611110 -0.000006
            +v 2.409720 1.773610 0.189576
            +v 2.387500 1.800000 -0.000006
            +v 2.487650 1.999280 0.148450
            +v 2.462960 2.013890 -0.000007
            +v 2.580400 2.218310 0.116813
            +v 2.549540 2.223610 -0.000008
            +v 2.700000 2.400000 -0.000008
            +v 2.744440 2.400000 0.104158
            +v 1.700000 1.211110 0.439996
            +v 2.106330 1.297250 0.419748
            +v 2.339510 1.474280 0.369131
            +v 2.465280 1.707640 0.303327
            +v 2.549380 1.962760 0.237524
            +v 2.657560 2.205070 0.186906
            +v 2.855560 2.400000 0.166658
            +v 1.700000 1.012500 0.494996
            +v 2.150460 1.130900 0.472218
            +v 2.403700 1.347220 0.415273
            +v 2.537500 1.621870 0.341244
            +v 2.629630 1.915280 0.267215
            +v 2.757870 2.187850 0.210270
            +v 3.000000 2.400000 0.187491
            +v 1.700000 0.813891 0.439997
            +v 2.194600 0.964560 0.419749
            +v 2.467900 1.220160 0.369132
            +v 2.609720 1.536110 0.303327
            +v 2.709880 1.867800 0.237524
            +v 2.858180 2.170630 0.186906
            +v 3.144440 2.400000 0.166658
            +v 1.700000 0.661112 0.274998
            +v 2.228550 0.836601 0.262343
            +v 2.517280 1.122430 0.230706
            +v 2.665280 1.470140 0.189578
            +v 2.771600 1.831280 0.148450
            +v 2.935340 2.157380 0.116813
            +v 3.255560 2.400000 0.104158
            +v 1.700000 0.600000 -0.000002
            +v 2.242130 0.785417 -0.000003
            +v 2.537040 1.083330 -0.000004
            +v 2.687500 1.443750 -0.000005
            +v 2.796300 1.816670 -0.000006
            +v 2.966200 2.152080 -0.000008
            +v 3.300000 2.400000 -0.000008
            +v 1.700000 0.661110 -0.275002
            +v 2.228550 0.836599 -0.262349
            +v 2.517280 1.122430 -0.230714
            +v 2.665280 1.470140 -0.189588
            +v 2.771600 1.831280 -0.148464
            +v 2.935340 2.157380 -0.116829
            +v 3.255560 2.400000 -0.104176
            +v 1.700000 0.813887 -0.440003
            +v 2.194600 0.964556 -0.419757
            +v 2.467900 1.220160 -0.369141
            +v 2.609720 1.536110 -0.303339
            +v 2.709880 1.867800 -0.237538
            +v 2.858180 2.170630 -0.186922
            +v 3.144440 2.400000 -0.166676
            +v 1.700000 1.012500 -0.495004
            +v 2.150460 1.130900 -0.472226
            +v 2.403700 1.347220 -0.415283
            +v 2.537500 1.621870 -0.341256
            +v 2.629630 1.915280 -0.267229
            +v 2.757870 2.187850 -0.210286
            +v 3.000000 2.400000 -0.187509
            +v 1.700000 1.211110 -0.440004
            +v 2.106330 1.297250 -0.419758
            +v 2.339510 1.474280 -0.369141
            +v 2.465280 1.707640 -0.303339
            +v 2.549380 1.962760 -0.237538
            +v 2.657560 2.205070 -0.186922
            +v 2.855560 2.400000 -0.166676
            +v 1.700000 1.363890 -0.275005
            +v 2.072380 1.425210 -0.262351
            +v 2.290120 1.572020 -0.230716
            +v 2.409720 1.773610 -0.189590
            +v 2.487650 1.999280 -0.148464
            +v 2.580400 2.218310 -0.116829
            +v 2.744440 2.400000 -0.104176
            +v 2.749070 2.431250 -0.000009
            +v 2.796410 2.431930 0.101023
            +v 2.792590 2.450000 -0.000009
            +v 2.839780 2.451230 0.092969
            +v 2.825000 2.456250 -0.000009
            +v 2.869680 2.457810 0.082022
            +v 2.881210 2.451540 0.070207
            +v 2.840740 2.450000 -0.000009
            +v 2.869490 2.432310 0.059549
            +v 2.834260 2.431250 -0.000009
            +v 2.829630 2.400000 0.052074
            +v 2.800000 2.400000 -0.000008
            +v 2.914740 2.433610 0.161565
            +v 2.957750 2.454320 0.148139
            +v 2.981370 2.461720 0.129158
            +v 2.982370 2.455400 0.107398
            +v 2.957560 2.434960 0.085639
            +v 2.903700 2.400000 0.066658
            +v 3.068580 2.435810 0.181675
            +v 3.111110 2.458330 0.165963
            +v 3.126560 2.466800 0.142960
            +v 3.113890 2.460420 0.115269
            +v 3.072050 2.438410 0.085495
            +v 3.000000 2.400000 0.056241
            +v 3.222410 2.438000 0.161411
            +v 3.264470 2.462350 0.146905
            +v 3.271760 2.471870 0.124991
            +v 3.245400 2.465430 0.097522
            +v 3.186540 2.441860 0.066349
            +v 3.096300 2.400000 0.033324
            +v 3.340750 2.439690 0.100830
            +v 3.382440 2.465430 0.091426
            +v 3.383450 2.475780 0.076814
            +v 3.346570 2.469290 0.057861
            +v 3.274610 2.444510 0.035437
            +v 3.170370 2.400000 0.010408
            +v 3.388080 2.440360 -0.000009
            +v 3.429630 2.466670 -0.000009
            +v 3.428130 2.477340 -0.000009
            +v 3.387040 2.470830 -0.000009
            +v 3.309840 2.445570 -0.000009
            +v 3.200000 2.400000 -0.000008
            +v 3.340750 2.439690 -0.101089
            +v 3.382440 2.465430 -0.093373
            +v 3.383450 2.475780 -0.083342
            +v 3.346570 2.469290 -0.073312
            +v 3.274610 2.444510 -0.065595
            +v 3.170370 2.400000 -0.062509
            +v 3.222410 2.438000 -0.161737
            +v 3.264470 2.462350 -0.149392
            +v 3.271760 2.471870 -0.133342
            +v 3.245400 2.465430 -0.117293
            +v 3.186540 2.441860 -0.104947
            +v 3.096300 2.400000 -0.100009
            +v 3.068580 2.435810 -0.181953
            +v 3.111110 2.458330 -0.168065
            +v 3.126560 2.466800 -0.150009
            +v 3.113890 2.460420 -0.131953
            +v 3.072050 2.438410 -0.118065
            +v 3.000000 2.400000 -0.112509
            +v 2.914740 2.433610 -0.161737
            +v 2.957750 2.454320 -0.149392
            +v 2.981370 2.461720 -0.133342
            +v 2.982370 2.455400 -0.117293
            +v 2.957560 2.434960 -0.104947
            +v 2.903700 2.400000 -0.100009
            +v 2.796410 2.431930 -0.101089
            +v 2.839780 2.451230 -0.093373
            +v 2.869680 2.457810 -0.083342
            +v 2.881210 2.451540 -0.073312
            +v 2.869490 2.432310 -0.065595
            +v 2.829630 2.400000 -0.062509
            +v 0.278704 3.127080 -0.000011
            +v 0.000000 3.150000 -0.000011
            +v 0.268946 3.127080 0.075067
            +v 0.241285 3.127080 0.141920
            +v 0.198140 3.127080 0.198129
            +v 0.141931 3.127080 0.241274
            +v 0.075078 3.127080 0.268935
            +v 0.000000 3.127080 0.278693
            +v -0.075078 3.127080 0.268935
            +v -0.141931 3.127080 0.241274
            +v -0.198140 3.127080 0.198129
            +v -0.241285 3.127080 0.141920
            +v -0.268946 3.127080 0.075067
            +v -0.278704 3.127080 -0.000011
            +v -0.268946 3.127080 -0.075089
            +v -0.241285 3.127080 -0.141942
            +v -0.198140 3.127080 -0.198151
            +v -0.141931 3.127080 -0.241296
            +v -0.075078 3.127080 -0.268957
            +v 0.000000 3.127080 -0.278715
            +v 0.075078 3.127080 -0.268957
            +v 0.141931 3.127080 -0.241296
            +v 0.198140 3.127080 -0.198151
            +v 0.241285 3.127080 -0.141942
            +v 0.268946 3.127080 -0.075089
            +v 0.350254 3.066670 0.097760
            +v 0.362963 3.066670 -0.000011
            +v 0.313617 2.981250 0.087518
            +v 0.325000 2.981250 -0.000011
            +v 0.228728 2.883330 0.063793
            +v 0.237037 2.883330 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.314228 3.066670 0.184824
            +v 0.281352 2.981250 0.165470
            +v 0.205180 2.883330 0.120636
            +v 0.148234 2.785420 0.087096
            +v 0.258037 3.066670 0.258027
            +v 0.231031 2.981250 0.231020
            +v 0.168463 2.883330 0.168452
            +v 0.121672 2.785420 0.121662
            +v 0.184834 3.066670 0.314218
            +v 0.165481 2.981250 0.281341
            +v 0.120647 2.883330 0.205169
            +v 0.087106 2.785420 0.148224
            +v 0.097771 3.066670 0.350244
            +v 0.087529 2.981250 0.313606
            +v 0.063803 2.883330 0.228717
            +v 0.046045 2.785420 0.165269
            +v 0.000000 3.066670 0.362953
            +v 0.000000 2.981250 0.324989
            +v 0.000000 2.883330 0.237026
            +v 0.000000 2.785420 0.171286
            +v -0.097771 3.066670 0.350244
            +v -0.087529 2.981250 0.313606
            +v -0.063803 2.883330 0.228717
            +v -0.046045 2.785420 0.165269
            +v -0.184834 3.066670 0.314218
            +v -0.165481 2.981250 0.281341
            +v -0.120647 2.883330 0.205169
            +v -0.087106 2.785420 0.148224
            +v -0.258037 3.066670 0.258027
            +v -0.231031 2.981250 0.231020
            +v -0.168463 2.883330 0.168452
            +v -0.121672 2.785420 0.121662
            +v -0.314228 3.066670 0.184824
            +v -0.281352 2.981250 0.165470
            +v -0.205180 2.883330 0.120636
            +v -0.148234 2.785420 0.087096
            +v -0.350254 3.066670 0.097760
            +v -0.313617 2.981250 0.087518
            +v -0.228728 2.883330 0.063793
            +v -0.165279 2.785420 0.046035
            +v -0.362963 3.066670 -0.000011
            +v -0.325000 2.981250 -0.000011
            +v -0.237037 2.883330 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.350254 3.066670 -0.097782
            +v -0.313617 2.981250 -0.087540
            +v -0.228728 2.883330 -0.063813
            +v -0.165279 2.785420 -0.046055
            +v -0.314228 3.066670 -0.184844
            +v -0.281352 2.981250 -0.165492
            +v -0.205180 2.883330 -0.120658
            +v -0.148234 2.785420 -0.087116
            +v -0.258037 3.066670 -0.258047
            +v -0.231031 2.981250 -0.231042
            +v -0.168463 2.883330 -0.168474
            +v -0.121672 2.785420 -0.121682
            +v -0.184834 3.066670 -0.314238
            +v -0.165481 2.981250 -0.281363
            +v -0.120647 2.883330 -0.205191
            +v -0.087106 2.785420 -0.148244
            +v -0.097771 3.066670 -0.350264
            +v -0.087529 2.981250 -0.313628
            +v -0.063803 2.883330 -0.228739
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 3.066670 -0.362973
            +v 0.000000 2.981250 -0.325011
            +v 0.000000 2.883330 -0.237048
            +v 0.000000 2.785420 -0.171306
            +v 0.097771 3.066670 -0.350264
            +v 0.087529 2.981250 -0.313628
            +v 0.063803 2.883330 -0.228739
            +v 0.046045 2.785420 -0.165289
            +v 0.184834 3.066670 -0.314238
            +v 0.165481 2.981250 -0.281363
            +v 0.120647 2.883330 -0.205191
            +v 0.087106 2.785420 -0.148244
            +v 0.258037 3.066670 -0.258047
            +v 0.231031 2.981250 -0.231042
            +v 0.168463 2.883330 -0.168474
            +v 0.121672 2.785420 -0.121682
            +v 0.314228 3.066670 -0.184844
            +v 0.281352 2.981250 -0.165492
            +v 0.205180 2.883330 -0.120658
            +v 0.148234 2.785420 -0.087116
            +v 0.350254 3.066670 -0.097782
            +v 0.313617 2.981250 -0.087540
            +v 0.228728 2.883330 -0.063813
            +v 0.165279 2.785420 -0.046055
            +vn 0.025666 -0.999664 0.000000
            +vn 0.000000 -1.000000 0.000000
            +vn 0.024781 -0.999664 -0.006623
            +vn 0.022156 -0.999664 -0.012787
            +vn 0.018067 -0.999664 -0.018067
            +vn 0.012787 -0.999664 -0.022126
            +vn 0.006623 -0.999664 -0.024751
            +vn 0.000000 -0.999664 -0.025666
            +vn -0.006623 -0.999664 -0.024751
            +vn -0.012787 -0.999664 -0.022126
            +vn -0.018067 -0.999664 -0.018067
            +vn -0.022156 -0.999664 -0.012787
            +vn -0.024781 -0.999664 -0.006623
            +vn -0.025666 -0.999664 0.000000
            +vn -0.024781 -0.999664 0.006623
            +vn -0.022156 -0.999664 0.012787
            +vn -0.018067 -0.999664 0.018067
            +vn -0.012787 -0.999664 0.022156
            +vn -0.006623 -0.999664 0.024781
            +vn 0.000000 -0.999664 0.025666
            +vn 0.006623 -0.999664 0.024781
            +vn 0.012787 -0.999664 0.022156
            +vn 0.018067 -0.999664 0.018067
            +vn 0.022156 -0.999664 0.012787
            +vn 0.024781 -0.999664 0.006623
            +vn -0.946562 -0.322459 0.000000
            +vn -0.913999 -0.322947 -0.245491
            +vn -0.958617 -0.122227 -0.257057
            +vn -0.992523 -0.122013 0.000000
            +vn -0.832057 0.554674 0.000000
            +vn -0.803217 0.555376 -0.215308
            +vn -0.048616 0.998810 0.000000
            +vn -0.046205 0.998840 -0.012726
            +vn 0.525376 0.839106 0.140843
            +vn 0.544267 0.838893 0.000000
            +vn 0.756340 0.621845 0.202918
            +vn 0.783471 0.621387 0.000000
            +vn 0.850551 0.473769 0.228217
            +vn 0.880886 0.473281 0.000000
            +vn -0.818842 -0.323435 -0.474166
            +vn -0.859004 -0.122410 -0.497085
            +vn -0.719657 0.555559 -0.416425
            +vn -0.041749 0.998810 -0.024415
            +vn 0.470107 0.839625 0.272011
            +vn 0.677236 0.622608 0.391980
            +vn 0.761803 0.474471 0.440962
            +vn -0.669027 -0.323679 -0.669027
            +vn -0.701773 -0.122440 -0.701773
            +vn -0.587878 0.555650 -0.587878
            +vn -0.034272 0.998810 -0.034272
            +vn 0.383831 0.839808 0.383831
            +vn 0.553148 0.622913 0.553148
            +vn 0.622303 0.474776 0.622303
            +vn -0.474166 -0.323435 -0.818842
            +vn -0.497085 -0.122410 -0.859004
            +vn -0.416425 0.555528 -0.719657
            +vn -0.024415 0.998810 -0.041749
            +vn 0.272011 0.839625 0.470077
            +vn 0.392010 0.622608 0.677236
            +vn 0.440962 0.474502 0.761803
            +vn -0.245460 -0.322977 -0.913999
            +vn -0.257057 -0.122257 -0.958617
            +vn -0.215339 0.555193 -0.803308
            +vn -0.012726 0.998840 -0.046236
            +vn 0.140873 0.839076 0.525437
            +vn 0.202918 0.621906 0.756310
            +vn 0.228217 0.473769 0.850551
            +vn 0.000000 -0.322489 -0.946562
            +vn 0.000000 -0.122044 -0.992523
            +vn 0.000000 0.554491 -0.832179
            +vn 0.000000 0.998779 -0.048799
            +vn 0.000000 0.838893 0.544267
            +vn 0.000000 0.621387 0.783471
            +vn 0.000000 0.473281 0.880886
            +vn 0.245460 -0.322977 -0.913999
            +vn 0.257057 -0.122257 -0.958617
            +vn 0.215339 0.555193 -0.803308
            +vn 0.012726 0.998840 -0.046236
            +vn -0.140873 0.839076 0.525437
            +vn -0.202918 0.621906 0.756310
            +vn -0.228217 0.473769 0.850551
            +vn 0.474166 -0.323435 -0.818842
            +vn 0.497085 -0.122410 -0.859004
            +vn 0.416425 0.555528 -0.719657
            +vn 0.024415 0.998810 -0.041749
            +vn -0.272011 0.839625 0.470077
            +vn -0.392010 0.622608 0.677236
            +vn -0.440962 0.474502 0.761803
            +vn 0.669027 -0.323679 -0.669027
            +vn 0.701773 -0.122440 -0.701773
            +vn 0.587878 0.555650 -0.587878
            +vn 0.034272 0.998810 -0.034272
            +vn -0.383831 0.839808 0.383831
            +vn -0.553148 0.622913 0.553148
            +vn -0.622303 0.474776 0.622303
            +vn 0.818842 -0.323435 -0.474166
            +vn 0.859004 -0.122410 -0.497085
            +vn 0.719657 0.555559 -0.416425
            +vn 0.041749 0.998810 -0.024415
            +vn -0.470107 0.839625 0.272011
            +vn -0.677236 0.622608 0.391980
            +vn -0.761803 0.474471 0.440962
            +vn 0.913999 -0.322947 -0.245491
            +vn 0.958617 -0.122227 -0.257057
            +vn 0.803217 0.555376 -0.215308
            +vn 0.046205 0.998840 -0.012726
            +vn -0.525376 0.839106 0.140843
            +vn -0.756340 0.621845 0.202918
            +vn -0.850551 0.473769 0.228217
            +vn 0.946562 -0.322459 0.000000
            +vn 0.992523 -0.122013 0.000000
            +vn 0.832057 0.554674 0.000000
            +vn 0.048616 0.998810 0.000000
            +vn -0.544267 0.838893 0.000000
            +vn -0.783471 0.621387 0.000000
            +vn -0.880886 0.473281 0.000000
            +vn 0.913999 -0.322947 0.245491
            +vn 0.958617 -0.122227 0.257057
            +vn 0.803217 0.555376 0.215308
            +vn 0.046205 0.998840 0.012726
            +vn -0.525376 0.839106 -0.140843
            +vn -0.756340 0.621845 -0.202918
            +vn -0.850551 0.473769 -0.228217
            +vn 0.818842 -0.323435 0.474166
            +vn 0.859004 -0.122410 0.497085
            +vn 0.719657 0.555559 0.416425
            +vn 0.041749 0.998810 0.024415
            +vn -0.470107 0.839625 -0.272011
            +vn -0.677236 0.622608 -0.391980
            +vn -0.761803 0.474471 -0.440962
            +vn 0.669027 -0.323679 0.669027
            +vn 0.701773 -0.122440 0.701773
            +vn 0.587878 0.555650 0.587878
            +vn 0.034272 0.998810 0.034272
            +vn -0.383831 0.839808 -0.383831
            +vn -0.553148 0.622913 -0.553148
            +vn -0.622303 0.474776 -0.622303
            +vn 0.474166 -0.323435 0.818842
            +vn 0.497085 -0.122410 0.859004
            +vn 0.416425 0.555559 0.719657
            +vn 0.024415 0.998810 0.041749
            +vn -0.272011 0.839625 -0.470107
            +vn -0.391980 0.622608 -0.677236
            +vn -0.440962 0.474471 -0.761803
            +vn 0.245460 -0.322977 0.913999
            +vn 0.257027 -0.122257 0.958617
            +vn 0.215369 0.555193 0.803308
            +vn 0.012726 0.998840 0.046236
            +vn -0.140873 0.839045 -0.525498
            +vn -0.202918 0.621845 -0.756371
            +vn -0.228187 0.473769 -0.850551
            +vn 0.000000 -0.322459 0.946562
            +vn 0.000000 -0.122013 0.992523
            +vn 0.000000 0.554674 0.832057
            +vn 0.000000 0.998810 0.048616
            +vn 0.000000 0.838893 -0.544267
            +vn 0.000000 0.621387 -0.783471
            +vn 0.000000 0.473281 -0.880886
            +vn -0.245460 -0.322977 0.913999
            +vn -0.257027 -0.122257 0.958617
            +vn -0.215369 0.555193 0.803308
            +vn -0.012726 0.998840 0.046236
            +vn 0.140873 0.839045 -0.525498
            +vn 0.202918 0.621845 -0.756371
            +vn 0.228187 0.473769 -0.850551
            +vn -0.474166 -0.323435 0.818842
            +vn -0.497085 -0.122410 0.859004
            +vn -0.416425 0.555559 0.719657
            +vn -0.024415 0.998810 0.041749
            +vn 0.272011 0.839625 -0.470107
            +vn 0.391980 0.622608 -0.677236
            +vn 0.440962 0.474471 -0.761803
            +vn -0.669027 -0.323679 0.669027
            +vn -0.701773 -0.122440 0.701773
            +vn -0.587878 0.555650 0.587878
            +vn -0.034272 0.998810 0.034272
            +vn 0.383831 0.839808 -0.383831
            +vn 0.553148 0.622913 -0.553148
            +vn 0.622303 0.474776 -0.622303
            +vn -0.818842 -0.323435 0.474166
            +vn -0.859004 -0.122410 0.497085
            +vn -0.719657 0.555559 0.416425
            +vn -0.041749 0.998810 0.024415
            +vn 0.470107 0.839625 -0.272011
            +vn 0.677236 0.622608 -0.391980
            +vn 0.761803 0.474471 -0.440962
            +vn -0.913999 -0.322947 0.245491
            +vn -0.958617 -0.122227 0.257057
            +vn -0.803217 0.555376 0.215308
            +vn -0.046205 0.998840 0.012726
            +vn 0.525376 0.839106 -0.140843
            +vn 0.756340 0.621845 -0.202918
            +vn 0.850551 0.473769 -0.228217
            +vn 0.877041 0.418744 0.235298
            +vn 0.908292 0.418256 0.000000
            +vn 0.888668 0.391644 0.238441
            +vn 0.920286 0.391156 0.000000
            +vn 0.907315 0.342753 0.243446
            +vn 0.939543 0.342357 0.000000
            +vn 0.931028 0.265908 0.249855
            +vn 0.964080 0.265542 0.000000
            +vn 0.954558 0.152104 0.256172
            +vn 0.988372 0.151891 0.000000
            +vn 0.964782 -0.045717 0.258980
            +vn 0.998932 -0.045656 0.000000
            +vn 0.785638 0.419416 0.454756
            +vn 0.796075 0.392285 0.460799
            +vn 0.812830 0.343333 0.470504
            +vn 0.834162 0.266366 0.482864
            +vn 0.855312 0.152409 0.495132
            +vn 0.864498 -0.045808 0.500504
            +vn 0.641804 0.419691 0.641804
            +vn 0.650349 0.392529 0.650349
            +vn 0.664052 0.343577 0.664052
            +vn 0.681509 0.266579 0.681509
            +vn 0.698813 0.152501 0.698813
            +vn 0.706351 -0.045869 0.706351
            +vn 0.454756 0.419416 0.785638
            +vn 0.460799 0.392285 0.796075
            +vn 0.470504 0.343333 0.812830
            +vn 0.482864 0.266396 0.834162
            +vn 0.495132 0.152409 0.855312
            +vn 0.500504 -0.045808 0.864498
            +vn 0.235298 0.418744 0.877041
            +vn 0.238441 0.391644 0.888668
            +vn 0.243446 0.342753 0.907315
            +vn 0.249825 0.265908 0.931028
            +vn 0.256172 0.152135 0.954558
            +vn 0.258980 -0.045717 0.964782
            +vn 0.000000 0.418256 0.908292
            +vn 0.000000 0.391156 0.920286
            +vn 0.000000 0.342357 0.939543
            +vn 0.000000 0.265572 0.964080
            +vn 0.000000 0.151921 0.988372
            +vn 0.000000 -0.045656 0.998932
            +vn -0.235298 0.418744 0.877041
            +vn -0.238441 0.391644 0.888668
            +vn -0.243446 0.342753 0.907315
            +vn -0.249825 0.265908 0.931028
            +vn -0.256172 0.152135 0.954558
            +vn -0.258980 -0.045717 0.964782
            +vn -0.454756 0.419416 0.785638
            +vn -0.460799 0.392285 0.796075
            +vn -0.470504 0.343333 0.812830
            +vn -0.482864 0.266396 0.834162
            +vn -0.495132 0.152409 0.855312
            +vn -0.500504 -0.045808 0.864498
            +vn -0.641804 0.419691 0.641804
            +vn -0.650349 0.392529 0.650349
            +vn -0.664052 0.343577 0.664052
            +vn -0.681509 0.266579 0.681509
            +vn -0.698813 0.152501 0.698813
            +vn -0.706351 -0.045869 0.706351
            +vn -0.785638 0.419416 0.454756
            +vn -0.796075 0.392285 0.460799
            +vn -0.812830 0.343333 0.470504
            +vn -0.834162 0.266366 0.482864
            +vn -0.855312 0.152409 0.495132
            +vn -0.864498 -0.045808 0.500504
            +vn -0.877041 0.418744 0.235298
            +vn -0.888668 0.391644 0.238441
            +vn -0.907315 0.342753 0.243446
            +vn -0.931028 0.265908 0.249825
            +vn -0.954558 0.152104 0.256172
            +vn -0.964782 -0.045717 0.258980
            +vn -0.908292 0.418256 0.000000
            +vn -0.920286 0.391156 0.000000
            +vn -0.939543 0.342357 0.000000
            +vn -0.964080 0.265542 0.000000
            +vn -0.988372 0.151891 0.000000
            +vn -0.998932 -0.045656 0.000000
            +vn -0.877041 0.418744 -0.235298
            +vn -0.888668 0.391644 -0.238441
            +vn -0.907315 0.342753 -0.243446
            +vn -0.931028 0.265877 -0.249855
            +vn -0.954558 0.152104 -0.256172
            +vn -0.964782 -0.045717 -0.258980
            +vn -0.785638 0.419416 -0.454756
            +vn -0.796075 0.392285 -0.460799
            +vn -0.812830 0.343333 -0.470504
            +vn -0.834162 0.266366 -0.482864
            +vn -0.855312 0.152379 -0.495132
            +vn -0.864498 -0.045808 -0.500504
            +vn -0.641804 0.419691 -0.641804
            +vn -0.650349 0.392529 -0.650349
            +vn -0.664052 0.343547 -0.664052
            +vn -0.681509 0.266549 -0.681509
            +vn -0.698813 0.152470 -0.698813
            +vn -0.706351 -0.045869 -0.706351
            +vn -0.454756 0.419416 -0.785638
            +vn -0.460768 0.392285 -0.796075
            +vn -0.470504 0.343333 -0.812830
            +vn -0.482864 0.266366 -0.834162
            +vn -0.495132 0.152379 -0.855312
            +vn -0.500504 -0.045808 -0.864498
            +vn -0.235298 0.418744 -0.877041
            +vn -0.238441 0.391644 -0.888668
            +vn -0.243446 0.342753 -0.907315
            +vn -0.249855 0.265877 -0.931059
            +vn -0.256172 0.152074 -0.954558
            +vn -0.258980 -0.045717 -0.964782
            +vn 0.000000 0.418256 -0.908292
            +vn 0.000000 0.391156 -0.920286
            +vn 0.000000 0.342357 -0.939543
            +vn 0.000000 0.265511 -0.964080
            +vn 0.000000 0.151891 -0.988372
            +vn 0.000000 -0.045656 -0.998932
            +vn 0.235298 0.418744 -0.877041
            +vn 0.238441 0.391644 -0.888668
            +vn 0.243446 0.342753 -0.907315
            +vn 0.249855 0.265877 -0.931059
            +vn 0.256172 0.152074 -0.954558
            +vn 0.258980 -0.045717 -0.964782
            +vn 0.454756 0.419416 -0.785638
            +vn 0.460768 0.392285 -0.796075
            +vn 0.470504 0.343333 -0.812830
            +vn 0.482864 0.266366 -0.834162
            +vn 0.495132 0.152379 -0.855312
            +vn 0.500504 -0.045808 -0.864498
            +vn 0.641804 0.419691 -0.641804
            +vn 0.650349 0.392529 -0.650349
            +vn 0.664052 0.343547 -0.664052
            +vn 0.681509 0.266549 -0.681509
            +vn 0.698813 0.152470 -0.698813
            +vn 0.706351 -0.045869 -0.706351
            +vn 0.785638 0.419416 -0.454756
            +vn 0.796075 0.392285 -0.460799
            +vn 0.812830 0.343333 -0.470504
            +vn 0.834162 0.266366 -0.482864
            +vn 0.855312 0.152379 -0.495132
            +vn 0.864498 -0.045808 -0.500504
            +vn 0.877041 0.418744 -0.235298
            +vn 0.888668 0.391644 -0.238441
            +vn 0.907315 0.342753 -0.243446
            +vn 0.931028 0.265908 -0.249825
            +vn 0.954558 0.152104 -0.256172
            +vn 0.964782 -0.045717 -0.258980
            +vn 0.912839 -0.326609 0.245003
            +vn 0.945250 -0.326273 0.000000
            +vn 0.795892 -0.566485 0.213538
            +vn 0.824396 -0.565996 0.000000
            +vn 0.687399 -0.702445 0.184393
            +vn 0.712180 -0.701987 0.000000
            +vn 0.630146 -0.757805 0.169012
            +vn 0.652974 -0.757347 0.000000
            +vn 0.698752 -0.690329 0.187445
            +vn 0.724021 -0.689749 0.000000
            +vn 0.855861 -0.463454 0.229530
            +vn 0.886380 -0.462905 0.000000
            +vn 0.817774 -0.327158 0.473434
            +vn 0.712729 -0.567248 0.412549
            +vn 0.615375 -0.703146 0.356151
            +vn 0.564043 -0.758446 0.326456
            +vn 0.625660 -0.690939 0.362102
            +vn 0.766625 -0.464125 0.443678
            +vn 0.668111 -0.327403 0.668111
            +vn 0.582171 -0.567522 0.582171
            +vn 0.502579 -0.703421 0.502579
            +vn 0.460646 -0.758660 0.460646
            +vn 0.510971 -0.691183 0.510971
            +vn 0.626209 -0.464370 0.626209
            +vn 0.473434 -0.327158 0.817774
            +vn 0.412549 -0.567248 0.712729
            +vn 0.356151 -0.703146 0.615375
            +vn 0.326456 -0.758446 0.564043
            +vn 0.362102 -0.690939 0.625660
            +vn 0.443678 -0.464125 0.766625
            +vn 0.245003 -0.326609 0.912839
            +vn 0.213538 -0.566485 0.795892
            +vn 0.184393 -0.702445 0.687399
            +vn 0.169012 -0.757805 0.630146
            +vn 0.187414 -0.690329 0.698752
            +vn 0.229530 -0.463454 0.855831
            +vn 0.000000 -0.326273 0.945250
            +vn 0.000000 -0.565996 0.824396
            +vn 0.000000 -0.701987 0.712180
            +vn 0.000000 -0.757347 0.652974
            +vn 0.000000 -0.689749 0.724021
            +vn 0.000000 -0.462905 0.886380
            +vn -0.245003 -0.326609 0.912839
            +vn -0.213538 -0.566485 0.795892
            +vn -0.184393 -0.702445 0.687399
            +vn -0.169012 -0.757805 0.630146
            +vn -0.187414 -0.690329 0.698752
            +vn -0.229530 -0.463454 0.855831
            +vn -0.473434 -0.327158 0.817774
            +vn -0.412549 -0.567248 0.712729
            +vn -0.356151 -0.703146 0.615375
            +vn -0.326456 -0.758446 0.564043
            +vn -0.362102 -0.690939 0.625660
            +vn -0.443678 -0.464125 0.766625
            +vn -0.668111 -0.327403 0.668111
            +vn -0.582171 -0.567522 0.582171
            +vn -0.502579 -0.703421 0.502579
            +vn -0.460646 -0.758660 0.460646
            +vn -0.510971 -0.691183 0.510971
            +vn -0.626209 -0.464370 0.626209
            +vn -0.817774 -0.327158 0.473434
            +vn -0.712729 -0.567248 0.412549
            +vn -0.615375 -0.703146 0.356151
            +vn -0.564043 -0.758446 0.326456
            +vn -0.625660 -0.690939 0.362102
            +vn -0.766625 -0.464125 0.443678
            +vn -0.912839 -0.326609 0.245003
            +vn -0.795892 -0.566485 0.213538
            +vn -0.687399 -0.702445 0.184393
            +vn -0.630146 -0.757805 0.169012
            +vn -0.698752 -0.690329 0.187445
            +vn -0.855861 -0.463454 0.229530
            +vn -0.945250 -0.326273 0.000000
            +vn -0.824396 -0.565996 0.000000
            +vn -0.712180 -0.701987 0.000000
            +vn -0.652974 -0.757347 0.000000
            +vn -0.724021 -0.689749 0.000000
            +vn -0.886380 -0.462905 0.000000
            +vn -0.912839 -0.326609 -0.245003
            +vn -0.795892 -0.566485 -0.213538
            +vn -0.687399 -0.702445 -0.184393
            +vn -0.630146 -0.757805 -0.169012
            +vn -0.698752 -0.690329 -0.187414
            +vn -0.855831 -0.463454 -0.229530
            +vn -0.817774 -0.327158 -0.473434
            +vn -0.712729 -0.567248 -0.412549
            +vn -0.615375 -0.703146 -0.356151
            +vn -0.564043 -0.758446 -0.326456
            +vn -0.625660 -0.690939 -0.362102
            +vn -0.766625 -0.464125 -0.443678
            +vn -0.668111 -0.327403 -0.668111
            +vn -0.582171 -0.567522 -0.582171
            +vn -0.502579 -0.703421 -0.502579
            +vn -0.460646 -0.758660 -0.460646
            +vn -0.510971 -0.691183 -0.510971
            +vn -0.626209 -0.464370 -0.626209
            +vn -0.473434 -0.327158 -0.817774
            +vn -0.412549 -0.567248 -0.712729
            +vn -0.356151 -0.703146 -0.615375
            +vn -0.326456 -0.758446 -0.564043
            +vn -0.362102 -0.690939 -0.625660
            +vn -0.443678 -0.464125 -0.766625
            +vn -0.245003 -0.326609 -0.912839
            +vn -0.213538 -0.566485 -0.795892
            +vn -0.184393 -0.702445 -0.687399
            +vn -0.169012 -0.757805 -0.630146
            +vn -0.187414 -0.690329 -0.698752
            +vn -0.229530 -0.463454 -0.855831
            +vn 0.000000 -0.326273 -0.945250
            +vn 0.000000 -0.565996 -0.824396
            +vn 0.000000 -0.701987 -0.712149
            +vn 0.000000 -0.757347 -0.652974
            +vn 0.000000 -0.689749 -0.724021
            +vn 0.000000 -0.462905 -0.886380
            +vn 0.245003 -0.326609 -0.912839
            +vn 0.213538 -0.566485 -0.795892
            +vn 0.184393 -0.702445 -0.687399
            +vn 0.169012 -0.757805 -0.630146
            +vn 0.187414 -0.690329 -0.698752
            +vn 0.229530 -0.463454 -0.855831
            +vn 0.473434 -0.327158 -0.817774
            +vn 0.412549 -0.567248 -0.712729
            +vn 0.356151 -0.703146 -0.615375
            +vn 0.326456 -0.758446 -0.564043
            +vn 0.362102 -0.690939 -0.625660
            +vn 0.443678 -0.464125 -0.766625
            +vn 0.668111 -0.327403 -0.668111
            +vn 0.582171 -0.567522 -0.582171
            +vn 0.502579 -0.703421 -0.502579
            +vn 0.460646 -0.758660 -0.460646
            +vn 0.510971 -0.691183 -0.510971
            +vn 0.626209 -0.464370 -0.626209
            +vn 0.817774 -0.327158 -0.473434
            +vn 0.712729 -0.567248 -0.412549
            +vn 0.615375 -0.703146 -0.356151
            +vn 0.564043 -0.758446 -0.326456
            +vn 0.625660 -0.690939 -0.362102
            +vn 0.766625 -0.464125 -0.443678
            +vn 0.912839 -0.326609 -0.245003
            +vn 0.795892 -0.566485 -0.213538
            +vn 0.687399 -0.702445 -0.184393
            +vn 0.630146 -0.757805 -0.169012
            +vn 0.698752 -0.690329 -0.187414
            +vn 0.855831 -0.463454 -0.229530
            +vn 0.068667 -0.997620 0.000000
            +vn 0.066256 -0.997620 -0.017731
            +vn 0.157170 -0.987548 0.000000
            +vn 0.151677 -0.987579 -0.040620
            +vn 0.373150 -0.927763 0.000000
            +vn 0.360149 -0.927885 -0.096469
            +vn 0.789148 -0.614154 0.000000
            +vn 0.762017 -0.614399 -0.204474
            +vn 0.059236 -0.997650 -0.034242
            +vn 0.135624 -0.987640 -0.078463
            +vn 0.322153 -0.928129 -0.186346
            +vn 0.682333 -0.615131 -0.394971
            +vn 0.048341 -0.997650 -0.048341
            +vn 0.110691 -0.987640 -0.110691
            +vn 0.262947 -0.928251 -0.262947
            +vn 0.557329 -0.615375 -0.557329
            +vn 0.034272 -0.997650 -0.059236
            +vn 0.078463 -0.987640 -0.135624
            +vn 0.186377 -0.928129 -0.322153
            +vn 0.394971 -0.615131 -0.682333
            +vn 0.017731 -0.997620 -0.066256
            +vn 0.040620 -0.987579 -0.151677
            +vn 0.096469 -0.927885 -0.360118
            +vn 0.204505 -0.614399 -0.762017
            +vn 0.000000 -0.997620 -0.068667
            +vn 0.000000 -0.987548 -0.157170
            +vn 0.000000 -0.927763 -0.373150
            +vn 0.000000 -0.614154 -0.789148
            +vn -0.017731 -0.997620 -0.066256
            +vn -0.040620 -0.987579 -0.151677
            +vn -0.096469 -0.927885 -0.360118
            +vn -0.204505 -0.614399 -0.762017
            +vn -0.034272 -0.997650 -0.059236
            +vn -0.078463 -0.987640 -0.135624
            +vn -0.186377 -0.928129 -0.322153
            +vn -0.394971 -0.615131 -0.682333
            +vn -0.048341 -0.997650 -0.048341
            +vn -0.110691 -0.987640 -0.110691
            +vn -0.262947 -0.928251 -0.262947
            +vn -0.557329 -0.615375 -0.557329
            +vn -0.059236 -0.997650 -0.034242
            +vn -0.135624 -0.987640 -0.078463
            +vn -0.322153 -0.928129 -0.186346
            +vn -0.682333 -0.615131 -0.394971
            +vn -0.066256 -0.997620 -0.017731
            +vn -0.151677 -0.987579 -0.040620
            +vn -0.360149 -0.927885 -0.096469
            +vn -0.762017 -0.614399 -0.204474
            +vn -0.068667 -0.997620 0.000000
            +vn -0.157170 -0.987548 0.000000
            +vn -0.373150 -0.927763 0.000000
            +vn -0.789148 -0.614154 0.000000
            +vn -0.066256 -0.997620 0.017731
            +vn -0.151677 -0.987579 0.040620
            +vn -0.360118 -0.927885 0.096469
            +vn -0.762017 -0.614399 0.204505
            +vn -0.059236 -0.997650 0.034272
            +vn -0.135624 -0.987640 0.078463
            +vn -0.322153 -0.928129 0.186377
            +vn -0.682333 -0.615131 0.394971
            +vn -0.048341 -0.997650 0.048341
            +vn -0.110691 -0.987640 0.110691
            +vn -0.262947 -0.928251 0.262947
            +vn -0.557329 -0.615375 0.557329
            +vn -0.034272 -0.997650 0.059236
            +vn -0.078463 -0.987640 0.135624
            +vn -0.186377 -0.928129 0.322153
            +vn -0.394971 -0.615131 0.682333
            +vn -0.017731 -0.997620 0.066256
            +vn -0.040620 -0.987579 0.151677
            +vn -0.096469 -0.927885 0.360149
            +vn -0.204474 -0.614399 0.762017
            +vn 0.000000 -0.997620 0.068667
            +vn 0.000000 -0.987548 0.157170
            +vn 0.000000 -0.927763 0.373150
            +vn 0.000000 -0.614154 0.789148
            +vn 0.017731 -0.997620 0.066256
            +vn 0.040620 -0.987579 0.151677
            +vn 0.096469 -0.927885 0.360149
            +vn 0.204474 -0.614399 0.762017
            +vn 0.034272 -0.997650 0.059236
            +vn 0.078463 -0.987640 0.135624
            +vn 0.186377 -0.928129 0.322153
            +vn 0.394971 -0.615131 0.682333
            +vn 0.048341 -0.997650 0.048341
            +vn 0.110691 -0.987640 0.110691
            +vn 0.262947 -0.928251 0.262947
            +vn 0.557329 -0.615375 0.557329
            +vn 0.059236 -0.997650 0.034272
            +vn 0.135624 -0.987640 0.078463
            +vn 0.322153 -0.928129 0.186377
            +vn 0.682333 -0.615101 0.394971
            +vn 0.066256 -0.997620 0.017731
            +vn 0.151677 -0.987579 0.040620
            +vn 0.360118 -0.927885 0.096469
            +vn 0.762017 -0.614399 0.204505
            +vn 0.692129 0.697470 0.185583
            +vn 0.717063 0.696982 0.000000
            +vn 0.915586 0.318766 0.245064
            +vn 0.947905 0.318522 0.000000
            +vn 0.620045 0.697653 0.358837
            +vn 0.820429 0.318979 0.474410
            +vn 0.506546 0.697684 0.506546
            +vn 0.670125 0.319041 0.670125
            +vn 0.358837 0.697653 0.620045
            +vn 0.474410 0.318979 0.820429
            +vn 0.185583 0.697470 0.692129
            +vn 0.245064 0.318766 0.915586
            +vn 0.000000 0.696982 0.717063
            +vn 0.000000 0.318522 0.947905
            +vn -0.185583 0.697470 0.692129
            +vn -0.245064 0.318766 0.915586
            +vn -0.358837 0.697653 0.620045
            +vn -0.474410 0.318979 0.820429
            +vn -0.506546 0.697684 0.506546
            +vn -0.670125 0.319041 0.670125
            +vn -0.620045 0.697653 0.358837
            +vn -0.820429 0.318979 0.474410
            +vn -0.692129 0.697470 0.185583
            +vn -0.915586 0.318766 0.245064
            +vn -0.717063 0.696982 0.000000
            +vn -0.947905 0.318522 0.000000
            +vn -0.692129 0.697470 -0.185583
            +vn -0.915586 0.318766 -0.245064
            +vn -0.620045 0.697653 -0.358837
            +vn -0.820429 0.318979 -0.474410
            +vn -0.506546 0.697684 -0.506546
            +vn -0.670125 0.319041 -0.670125
            +vn -0.358837 0.697653 -0.620045
            +vn -0.474410 0.318979 -0.820429
            +vn -0.185583 0.697470 -0.692129
            +vn -0.245064 0.318766 -0.915586
            +vn 0.000000 0.696982 -0.717063
            +vn 0.000000 0.318522 -0.947905
            +vn 0.185583 0.697470 -0.692129
            +vn 0.245064 0.318766 -0.915586
            +vn 0.358837 0.697653 -0.620045
            +vn 0.474410 0.318979 -0.820429
            +vn 0.506546 0.697684 -0.506546
            +vn 0.670125 0.319041 -0.670125
            +vn 0.620045 0.697653 -0.358837
            +vn 0.820429 0.318979 -0.474410
            +vn 0.692129 0.697470 -0.185583
            +vn 0.915586 0.318766 -0.245064
            +vn 0.282083 0.956389 0.075686
            +vn 0.292520 0.956236 0.000000
            +vn 0.171606 0.984069 0.046022
            +vn 0.177953 0.984008 0.000000
            +vn 0.153264 0.987304 0.041078
            +vn 0.158879 0.987274 0.000000
            +vn 0.210059 0.976043 0.056276
            +vn 0.217719 0.975982 0.000000
            +vn 0.487197 0.863460 0.130558
            +vn 0.504715 0.863277 0.000000
            +vn 0.662801 0.727226 0.178198
            +vn 0.686911 0.726707 0.000000
            +vn 0.252388 0.956511 0.146092
            +vn 0.153508 0.984130 0.088839
            +vn 0.137059 0.987365 0.079318
            +vn 0.187872 0.976135 0.108676
            +vn 0.435926 0.863887 0.252205
            +vn 0.593310 0.727866 0.343730
            +vn 0.206091 0.956572 0.206091
            +vn 0.125340 0.984161 0.125340
            +vn 0.111911 0.987396 0.111911
            +vn 0.153356 0.976196 0.153356
            +vn 0.355907 0.864071 0.355907
            +vn 0.484664 0.728111 0.484664
            +vn 0.146092 0.956511 0.252388
            +vn 0.088839 0.984130 0.153508
            +vn 0.079318 0.987365 0.137059
            +vn 0.108676 0.976135 0.187872
            +vn 0.252205 0.863887 0.435926
            +vn 0.343730 0.727866 0.593310
            +vn 0.075686 0.956389 0.282083
            +vn 0.046022 0.984069 0.171606
            +vn 0.041078 0.987304 0.153264
            +vn 0.056276 0.976043 0.210059
            +vn 0.130558 0.863460 0.487197
            +vn 0.178198 0.727226 0.662801
            +vn 0.000000 0.956236 0.292520
            +vn 0.000000 0.984008 0.177953
            +vn 0.000000 0.987274 0.158879
            +vn 0.000000 0.975982 0.217719
            +vn 0.000000 0.863277 0.504715
            +vn 0.000000 0.726707 0.686911
            +vn -0.075686 0.956389 0.282083
            +vn -0.046022 0.984069 0.171606
            +vn -0.041078 0.987304 0.153264
            +vn -0.056276 0.976043 0.210059
            +vn -0.130558 0.863460 0.487197
            +vn -0.178198 0.727226 0.662801
            +vn -0.146092 0.956511 0.252388
            +vn -0.088839 0.984130 0.153508
            +vn -0.079318 0.987365 0.137059
            +vn -0.108676 0.976135 0.187872
            +vn -0.252205 0.863887 0.435926
            +vn -0.343730 0.727866 0.593310
            +vn -0.206091 0.956572 0.206091
            +vn -0.125340 0.984161 0.125340
            +vn -0.111911 0.987396 0.111911
            +vn -0.153356 0.976196 0.153356
            +vn -0.355907 0.864071 0.355907
            +vn -0.484664 0.728111 0.484664
            +vn -0.252388 0.956511 0.146092
            +vn -0.153508 0.984130 0.088839
            +vn -0.137059 0.987365 0.079318
            +vn -0.187872 0.976135 0.108676
            +vn -0.435926 0.863887 0.252205
            +vn -0.593310 0.727866 0.343730
            +vn -0.282083 0.956389 0.075686
            +vn -0.171606 0.984069 0.046022
            +vn -0.153264 0.987304 0.041078
            +vn -0.210059 0.976043 0.056276
            +vn -0.487197 0.863460 0.130558
            +vn -0.662801 0.727226 0.178198
            +vn -0.292520 0.956236 0.000000
            +vn -0.177953 0.984008 0.000000
            +vn -0.158879 0.987274 0.000000
            +vn -0.217719 0.975982 0.000000
            +vn -0.504715 0.863277 0.000000
            +vn -0.686911 0.726707 0.000000
            +vn -0.282083 0.956389 -0.075686
            +vn -0.171606 0.984069 -0.046022
            +vn -0.153264 0.987304 -0.041078
            +vn -0.210059 0.976043 -0.056276
            +vn -0.487197 0.863460 -0.130558
            +vn -0.662801 0.727226 -0.178198
            +vn -0.252388 0.956511 -0.146092
            +vn -0.153508 0.984130 -0.088839
            +vn -0.137059 0.987365 -0.079318
            +vn -0.187872 0.976135 -0.108676
            +vn -0.435926 0.863887 -0.252205
            +vn -0.593310 0.727866 -0.343730
            +vn -0.206091 0.956572 -0.206091
            +vn -0.125340 0.984161 -0.125340
            +vn -0.111911 0.987396 -0.111911
            +vn -0.153356 0.976196 -0.153356
            +vn -0.355907 0.864071 -0.355907
            +vn -0.484664 0.728111 -0.484664
            +vn -0.146092 0.956511 -0.252388
            +vn -0.088839 0.984130 -0.153508
            +vn -0.079318 0.987365 -0.137059
            +vn -0.108676 0.976135 -0.187872
            +vn -0.252205 0.863887 -0.435926
            +vn -0.343730 0.727866 -0.593310
            +vn -0.075686 0.956389 -0.282083
            +vn -0.046022 0.984069 -0.171606
            +vn -0.041078 0.987304 -0.153264
            +vn -0.056276 0.976043 -0.210059
            +vn -0.130558 0.863460 -0.487197
            +vn -0.178198 0.727226 -0.662801
            +vn 0.000000 0.956236 -0.292520
            +vn 0.000000 0.984008 -0.177953
            +vn 0.000000 0.987274 -0.158879
            +vn 0.000000 0.975982 -0.217719
            +vn 0.000000 0.863277 -0.504715
            +vn 0.000000 0.726707 -0.686911
            +vn 0.075686 0.956389 -0.282083
            +vn 0.046022 0.984069 -0.171606
            +vn 0.041078 0.987304 -0.153264
            +vn 0.056276 0.976043 -0.210059
            +vn 0.130558 0.863460 -0.487197
            +vn 0.178198 0.727226 -0.662801
            +vn 0.146092 0.956511 -0.252388
            +vn 0.088839 0.984130 -0.153508
            +vn 0.079318 0.987365 -0.137059
            +vn 0.108676 0.976135 -0.187872
            +vn 0.252205 0.863887 -0.435926
            +vn 0.343730 0.727866 -0.593310
            +vn 0.206091 0.956572 -0.206091
            +vn 0.125340 0.984161 -0.125340
            +vn 0.111911 0.987396 -0.111911
            +vn 0.153356 0.976196 -0.153356
            +vn 0.355907 0.864071 -0.355907
            +vn 0.484664 0.728111 -0.484664
            +vn 0.252388 0.956511 -0.146092
            +vn 0.153508 0.984130 -0.088839
            +vn 0.137059 0.987365 -0.079318
            +vn 0.187872 0.976135 -0.108676
            +vn 0.435926 0.863887 -0.252205
            +vn 0.593310 0.727866 -0.343730
            +vn 0.282083 0.956389 -0.075686
            +vn 0.171606 0.984069 -0.046022
            +vn 0.153264 0.987304 -0.041078
            +vn 0.210059 0.976043 -0.056276
            +vn 0.487197 0.863460 -0.130558
            +vn 0.662801 0.727226 -0.178198
            +vn 0.015290 -0.999878 0.000000
            +vn 0.003296 -0.999969 0.000000
            +vn 0.015168 -0.949339 0.313852
            +vn 0.003265 -0.944395 0.328715
            +vn 0.058870 -0.998260 0.000000
            +vn 0.058046 -0.947630 0.314005
            +vn 0.158361 -0.934690 0.318155
            +vn 0.159764 -0.987152 0.000000
            +vn 0.373943 -0.860958 0.344798
            +vn 0.391583 -0.920103 0.000000
            +vn 0.726829 -0.553880 0.406049
            +vn 0.784570 -0.620014 0.000000
            +vn 0.908139 -0.082766 0.410321
            +vn 0.994995 -0.099796 0.000000
            +vn 0.011902 -0.679403 0.733634
            +vn 0.002380 -0.636219 0.771477
            +vn 0.046449 -0.674398 0.736869
            +vn 0.125980 -0.648946 0.750298
            +vn 0.270089 -0.562120 0.781671
            +vn 0.460067 -0.316263 0.829615
            +vn 0.563036 -0.041200 0.825373
            +vn 0.000153 0.004242 0.999969
            +vn -0.000519 0.113254 0.993561
            +vn 0.003510 0.014008 0.999878
            +vn 0.005921 0.035951 0.999329
            +vn -0.007813 0.058840 0.998230
            +vn -0.046510 0.041536 0.998047
            +vn -0.039155 0.003113 0.999207
            +vn -0.014161 0.682394 0.730796
            +vn -0.003204 0.727744 0.685812
            +vn -0.055361 0.680074 0.731010
            +vn -0.150029 0.655660 0.739952
            +vn -0.322520 0.565203 0.759239
            +vn -0.537645 0.315806 0.781762
            +vn -0.611530 0.029939 0.790613
            +vn -0.020569 0.949400 0.313334
            +vn -0.004273 0.954772 0.297281
            +vn -0.082705 0.944945 0.316507
            +vn -0.229591 0.914548 0.332926
            +vn -0.502335 0.785943 0.360454
            +vn -0.810633 0.443220 0.382611
            +vn -0.921232 0.039705 0.386944
            +vn -0.021851 0.999756 0.000000
            +vn -0.004517 0.999969 0.000000
            +vn -0.087649 0.996124 0.000000
            +vn -0.246223 0.969207 0.000000
            +vn -0.549211 0.835658 0.000000
            +vn -0.881039 0.472976 0.000000
            +vn -0.999115 0.041444 0.000000
            +vn -0.004273 0.954772 -0.297281
            +vn -0.020569 0.949400 -0.313334
            +vn -0.082705 0.944945 -0.316507
            +vn -0.229591 0.914548 -0.332926
            +vn -0.502335 0.785943 -0.360454
            +vn -0.810633 0.443220 -0.382611
            +vn -0.921232 0.039705 -0.386944
            +vn -0.003204 0.727744 -0.685812
            +vn -0.014161 0.682394 -0.730796
            +vn -0.055361 0.680074 -0.731010
            +vn -0.150029 0.655660 -0.739952
            +vn -0.322520 0.565203 -0.759239
            +vn -0.537645 0.315806 -0.781762
            +vn -0.611530 0.029939 -0.790613
            +vn -0.000519 0.113254 -0.993561
            +vn 0.000153 0.004242 -0.999969
            +vn 0.003510 0.014008 -0.999878
            +vn 0.005921 0.035951 -0.999329
            +vn -0.007813 0.058809 -0.998230
            +vn -0.046510 0.041536 -0.998047
            +vn -0.039155 0.003113 -0.999207
            +vn 0.002380 -0.636219 -0.771477
            +vn 0.011902 -0.679403 -0.733634
            +vn 0.046449 -0.674398 -0.736869
            +vn 0.125980 -0.648946 -0.750298
            +vn 0.270089 -0.562151 -0.781671
            +vn 0.460067 -0.316263 -0.829615
            +vn 0.563036 -0.041231 -0.825373
            +vn 0.003265 -0.944395 -0.328715
            +vn 0.015168 -0.949339 -0.313852
            +vn 0.058046 -0.947630 -0.314005
            +vn 0.158361 -0.934690 -0.318155
            +vn 0.373943 -0.860958 -0.344798
            +vn 0.726829 -0.553880 -0.406049
            +vn 0.908139 -0.082766 -0.410321
            +vn 0.890500 0.214759 0.401044
            +vn 0.972930 0.231025 0.000000
            +vn 0.836634 0.384075 0.390515
            +vn 0.912503 0.408979 0.000000
            +vn 0.765191 0.530198 0.365123
            +vn 0.828791 0.559496 0.000000
            +vn 0.671041 0.663228 0.331339
            +vn 0.718955 0.695029 0.000000
            +vn 0.549455 0.776238 0.309000
            +vn 0.580859 0.813990 0.000000
            +vn 0.461165 0.821528 0.335215
            +vn 0.497085 0.867672 0.000000
            +vn 0.559679 0.139714 0.816828
            +vn 0.528581 0.255501 0.809473
            +vn 0.494888 0.359783 0.790948
            +vn 0.445143 0.467879 0.763451
            +vn 0.376049 0.559984 0.738212
            +vn 0.287332 0.527940 0.799188
            +vn -0.024537 -0.005737 0.999664
            +vn -0.020844 -0.012207 0.999695
            +vn -0.014466 -0.014466 0.999786
            +vn -0.009796 -0.013276 0.999847
            +vn -0.014771 -0.013886 0.999786
            +vn -0.101779 -0.196661 0.975158
            +vn -0.585437 -0.154668 0.795801
            +vn -0.538499 -0.291696 0.790490
            +vn -0.487228 -0.408918 0.771599
            +vn -0.428327 -0.511948 0.744560
            +vn -0.360820 -0.584735 0.726524
            +vn -0.357311 -0.691549 0.627735
            +vn -0.889126 -0.238868 0.390332
            +vn -0.807001 -0.448500 0.384075
            +vn -0.700980 -0.613392 0.363750
            +vn -0.590442 -0.733757 0.336009
            +vn -0.486190 -0.814966 0.315256
            +vn -0.440138 -0.855586 0.272439
            +vn -0.965453 -0.260506 0.000000
            +vn -0.872097 -0.489273 0.000000
            +vn -0.748253 -0.663381 0.000000
            +vn -0.621784 -0.783166 0.000000
            +vn -0.507614 -0.861568 0.000000
            +vn -0.456954 -0.889462 0.000000
            +vn -0.889126 -0.238868 -0.390332
            +vn -0.807001 -0.448531 -0.384075
            +vn -0.700980 -0.613392 -0.363750
            +vn -0.590442 -0.733757 -0.336009
            +vn -0.486190 -0.814966 -0.315256
            +vn -0.440138 -0.855586 -0.272439
            +vn -0.585437 -0.154668 -0.795801
            +vn -0.538499 -0.291696 -0.790490
            +vn -0.487228 -0.408918 -0.771599
            +vn -0.428327 -0.511948 -0.744560
            +vn -0.360820 -0.584735 -0.726524
            +vn -0.357311 -0.691549 -0.627705
            +vn -0.024537 -0.005737 -0.999664
            +vn -0.020844 -0.012238 -0.999695
            +vn -0.014466 -0.014466 -0.999786
            +vn -0.009766 -0.013276 -0.999847
            +vn -0.014771 -0.013916 -0.999786
            +vn -0.101779 -0.196661 -0.975158
            +vn 0.559679 0.139714 -0.816828
            +vn 0.528581 0.255501 -0.809473
            +vn 0.494888 0.359783 -0.790948
            +vn 0.445143 0.467879 -0.763451
            +vn 0.376049 0.559984 -0.738212
            +vn 0.287332 0.527940 -0.799188
            +vn 0.890500 0.214759 -0.401044
            +vn 0.836634 0.384075 -0.390515
            +vn 0.765191 0.530198 -0.365123
            +vn 0.671041 0.663228 -0.331339
            +vn 0.549455 0.776238 -0.309000
            +vn 0.461165 0.821528 -0.335215
            +vn -0.149937 0.988678 0.000000
            +vn -0.137028 0.872402 0.469131
            +vn -0.297769 0.840358 0.452895
            +vn -0.350505 0.936552 0.000000
            +vn -0.617512 0.663961 0.421613
            +vn -0.715506 0.698569 0.000000
            +vn -0.801324 0.450209 0.393872
            +vn -0.900845 0.434065 0.000000
            +vn -0.828028 0.379803 0.412397
            +vn -0.929289 0.369274 0.000000
            +vn -0.729179 0.503464 0.463393
            +vn -0.857875 0.513810 0.000000
            +vn -0.663076 0.748527 0.000000
            +vn -0.531449 0.686514 0.496170
            +vn -0.066713 0.491440 0.868313
            +vn -0.117893 0.503159 0.856105
            +vn -0.254341 0.474349 0.842769
            +vn -0.411115 0.399182 0.819483
            +vn -0.459395 0.346446 0.817835
            +vn -0.385876 0.395734 0.833338
            +vn -0.270669 0.487838 0.829890
            +vn 0.062716 -0.043458 0.997070
            +vn 0.135929 -0.002472 0.990692
            +vn 0.247963 0.095187 0.964049
            +vn 0.209296 0.170660 0.962828
            +vn 0.096194 0.178625 0.979186
            +vn 0.009552 0.154332 0.987945
            +vn -0.000122 0.151952 0.988372
            +vn 0.202582 -0.542894 0.814966
            +vn 0.360088 -0.479232 0.800378
            +vn 0.611988 -0.282235 0.738762
            +vn 0.679220 -0.106754 0.726096
            +vn 0.583911 -0.078524 0.807978
            +vn 0.402722 -0.205237 0.891995
            +vn 0.279519 -0.338694 0.898404
            +vn 0.294107 -0.855037 0.427015
            +vn 0.488418 -0.768700 0.412915
            +vn 0.784570 -0.501511 0.364544
            +vn 0.893918 -0.279611 0.350291
            +vn 0.861415 -0.285287 0.420179
            +vn 0.679373 -0.540422 0.496323
            +vn 0.458357 -0.754540 0.469588
            +vn 0.320780 -0.947142 0.000000
            +vn 0.525101 -0.851009 0.000000
            +vn 0.827570 -0.561327 0.000000
            +vn 0.943419 -0.331523 0.000000
            +vn 0.933561 -0.358409 0.000000
            +vn 0.756340 -0.654134 0.000000
            +vn 0.491928 -0.870602 0.000092
            +vn 0.294107 -0.855037 -0.427015
            +vn 0.488418 -0.768700 -0.412915
            +vn 0.784570 -0.501511 -0.364544
            +vn 0.893918 -0.279611 -0.350291
            +vn 0.861385 -0.285287 -0.420179
            +vn 0.679373 -0.540422 -0.496323
            +vn 0.457839 -0.755608 -0.468368
            +vn 0.202582 -0.542894 -0.814966
            +vn 0.360088 -0.479232 -0.800378
            +vn 0.611988 -0.282235 -0.738762
            +vn 0.679220 -0.106754 -0.726096
            +vn 0.583911 -0.078524 -0.807978
            +vn 0.402722 -0.205237 -0.891995
            +vn 0.279153 -0.342235 -0.897153
            +vn 0.062716 -0.043458 -0.997070
            +vn 0.135929 -0.002472 -0.990692
            +vn 0.247963 0.095187 -0.964049
            +vn 0.209296 0.170629 -0.962828
            +vn 0.096194 0.178625 -0.979186
            +vn 0.009552 0.154332 -0.987945
            +vn -0.000458 0.149358 -0.988769
            +vn -0.066713 0.491440 -0.868313
            +vn -0.117893 0.503159 -0.856105
            +vn -0.254341 0.474319 -0.842769
            +vn -0.411115 0.399182 -0.819514
            +vn -0.459395 0.346446 -0.817835
            +vn -0.385876 0.395734 -0.833338
            +vn -0.271035 0.487136 -0.830164
            +vn -0.137028 0.872402 -0.469131
            +vn -0.297769 0.840358 -0.452895
            +vn -0.617512 0.663961 -0.421613
            +vn -0.801324 0.450209 -0.393872
            +vn -0.828028 0.379803 -0.412397
            +vn -0.729209 0.503464 -0.463393
            +vn -0.531541 0.686453 -0.496200
            +vn -0.480697 0.876858 0.000000
            +vn -0.394635 0.815363 0.423536
            +vn -0.320750 0.947142 0.000092
            +vn -0.255287 0.921964 0.291086
            +vn 0.002686 0.999969 -0.000732
            +vn -0.007172 0.999939 -0.007599
            +vn 0.366832 0.704398 -0.607624
            +vn 0.853236 0.521226 -0.016388
            +vn 0.567492 -0.154088 -0.808802
            +vn 0.803766 -0.594409 -0.024964
            +vn 0.580920 -0.584490 -0.566424
            +vn 0.673757 -0.738639 -0.020966
            +vn -0.206824 0.638203 0.741539
            +vn -0.129490 0.862056 0.489944
            +vn -0.034486 0.999023 0.026704
            +vn 0.041597 0.871334 -0.488876
            +vn 0.103488 0.553880 -0.826136
            +vn 0.189642 0.174200 -0.966247
            +vn 0.020112 0.322611 0.946287
            +vn 0.021943 0.748894 0.662282
            +vn -0.025697 0.995392 0.092166
            +vn -0.056551 0.931608 -0.358989
            +vn -0.070711 0.782006 -0.619190
            +vn -0.066408 0.651509 -0.755699
            +vn 0.281747 -0.174993 0.943388
            +vn 0.303903 0.444136 0.842830
            +vn 0.035279 0.983856 0.175329
            +vn -0.109928 0.953551 -0.280435
            +vn -0.149571 0.847682 -0.508927
            +vn -0.145634 0.777520 -0.611744
            +vn 0.467238 -0.683218 0.561144
            +vn 0.699515 0.004364 0.714560
            +vn 0.354900 0.892758 0.277444
            +vn -0.174383 0.969054 -0.174596
            +vn -0.252998 0.894314 -0.368938
            +vn -0.191443 0.807947 -0.557237
            +vn 0.495346 -0.868679 0.001587
            +vn 0.933897 -0.357311 0.011017
            +vn 0.704215 0.709830 0.013337
            +vn -0.205634 0.978576 -0.006623
            +vn -0.322367 0.945708 -0.041169
            +vn -0.314951 0.916288 -0.247322
            +vn 0.459120 -0.703757 -0.542100
            +vn 0.693655 -0.096530 -0.713767
            +vn 0.408673 0.848415 -0.336344
            +vn -0.198248 0.963439 0.180151
            +vn -0.306833 0.888516 0.341075
            +vn -0.335978 0.808863 0.482498
            +vn 0.277047 -0.215796 -0.936277
            +vn 0.306192 0.349864 -0.885311
            +vn 0.056246 0.971099 -0.231819
            +vn -0.146733 0.912168 0.382611
            +vn -0.202612 0.700797 0.683950
            +vn -0.159368 0.444777 0.881314
            +vn 0.016907 0.300088 -0.953734
            +vn 0.019349 0.701865 -0.712027
            +vn -0.023713 0.995361 -0.093081
            +vn -0.047395 0.829371 0.556658
            +vn -0.015259 0.386608 0.922086
            +vn 0.080721 0.001404 0.996704
            +vn -0.209967 0.632160 -0.745811
            +vn -0.137394 0.849117 -0.509995
            +vn -0.023438 0.999695 -0.004883
            +vn 0.120426 0.724540 0.678579
            +vn 0.260750 0.006531 0.965361
            +vn 0.341502 -0.385510 0.857143
            +vn -0.395489 0.814814 -0.423841
            +vn -0.257942 0.920621 -0.293039
            +vn 0.005005 0.999908 0.011628
            +vn 0.466628 0.599811 0.649983
            +vn 0.621937 -0.400861 0.672628
            +vn 0.584826 -0.661397 0.469558
            +vn 0.363842 0.931455 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.351451 0.931516 0.093509
            +vn 0.314432 0.931791 0.181280
            +vn 0.256386 0.931913 0.256386
            +vn 0.181280 0.931791 0.314432
            +vn 0.093509 0.931516 0.351451
            +vn 0.000000 0.931455 0.363842
            +vn -0.093509 0.931516 0.351451
            +vn -0.181280 0.931791 0.314432
            +vn -0.256386 0.931913 0.256386
            +vn -0.314432 0.931791 0.181280
            +vn -0.351451 0.931516 0.093509
            +vn -0.363842 0.931455 0.000000
            +vn -0.351451 0.931516 -0.093509
            +vn -0.314432 0.931791 -0.181280
            +vn -0.256417 0.931913 -0.256417
            +vn -0.181280 0.931791 -0.314432
            +vn -0.093509 0.931516 -0.351451
            +vn 0.000000 0.931455 -0.363842
            +vn 0.093509 0.931516 -0.351451
            +vn 0.181280 0.931791 -0.314432
            +vn 0.256417 0.931913 -0.256417
            +vn 0.314432 0.931791 -0.181280
            +vn 0.351451 0.931516 -0.093509
            +vn 0.935423 0.249763 0.250160
            +vn 0.968261 0.249916 0.000000
            +vn 0.813959 -0.538713 0.217322
            +vn 0.842860 -0.538102 0.000000
            +vn 0.759484 -0.618030 0.202887
            +vn 0.786767 -0.617206 0.000000
            +vn 0.801569 -0.558184 0.214148
            +vn 0.830195 -0.557421 0.000000
            +vn 0.838404 0.249825 0.484359
            +vn 0.729026 -0.539720 0.420881
            +vn 0.680013 -0.619098 0.392712
            +vn 0.717765 -0.559343 0.414594
            +vn 0.684652 0.249886 0.684652
            +vn 0.595050 -0.540147 0.595050
            +vn 0.555040 -0.619526 0.555040
            +vn 0.585894 -0.559862 0.585894
            +vn 0.484359 0.249825 0.838404
            +vn 0.420881 -0.539720 0.729026
            +vn 0.392712 -0.619098 0.680013
            +vn 0.414594 -0.559343 0.717765
            +vn 0.250160 0.249763 0.935423
            +vn 0.217322 -0.538713 0.813959
            +vn 0.202887 -0.618030 0.759514
            +vn 0.214148 -0.558184 0.801569
            +vn 0.000000 0.249916 0.968261
            +vn 0.000000 -0.538102 0.842860
            +vn 0.000000 -0.617206 0.786767
            +vn 0.000000 -0.557421 0.830195
            +vn -0.250160 0.249763 0.935423
            +vn -0.217322 -0.538713 0.813959
            +vn -0.202887 -0.618030 0.759514
            +vn -0.214148 -0.558184 0.801569
            +vn -0.484359 0.249825 0.838404
            +vn -0.420881 -0.539720 0.729026
            +vn -0.392712 -0.619098 0.680013
            +vn -0.414594 -0.559343 0.717765
            +vn -0.684652 0.249886 0.684652
            +vn -0.595050 -0.540147 0.595050
            +vn -0.555040 -0.619526 0.555040
            +vn -0.585894 -0.559862 0.585894
            +vn -0.838404 0.249825 0.484359
            +vn -0.729026 -0.539720 0.420881
            +vn -0.680013 -0.619098 0.392712
            +vn -0.717765 -0.559343 0.414594
            +vn -0.935423 0.249763 0.250160
            +vn -0.813959 -0.538713 0.217322
            +vn -0.759484 -0.618030 0.202887
            +vn -0.801569 -0.558184 0.214148
            +vn -0.968261 0.249916 0.000000
            +vn -0.842860 -0.538102 0.000000
            +vn -0.786767 -0.617206 0.000000
            +vn -0.830195 -0.557421 0.000000
            +vn -0.935423 0.249763 -0.250160
            +vn -0.813959 -0.538713 -0.217322
            +vn -0.759484 -0.618030 -0.202887
            +vn -0.801569 -0.558184 -0.214148
            +vn -0.838404 0.249825 -0.484359
            +vn -0.729026 -0.539720 -0.420881
            +vn -0.680013 -0.619098 -0.392712
            +vn -0.717765 -0.559343 -0.414594
            +vn -0.684652 0.249886 -0.684652
            +vn -0.595050 -0.540147 -0.595050
            +vn -0.555040 -0.619526 -0.555040
            +vn -0.585864 -0.559862 -0.585894
            +vn -0.484359 0.249825 -0.838404
            +vn -0.420881 -0.539720 -0.729026
            +vn -0.392712 -0.619098 -0.680013
            +vn -0.414594 -0.559343 -0.717765
            +vn -0.250160 0.249763 -0.935423
            +vn -0.217322 -0.538713 -0.813959
            +vn -0.202887 -0.618030 -0.759484
            +vn -0.214148 -0.558214 -0.801569
            +vn 0.000000 0.249916 -0.968261
            +vn 0.000000 -0.538102 -0.842860
            +vn 0.000000 -0.617206 -0.786767
            +vn 0.000000 -0.557421 -0.830195
            +vn 0.250160 0.249763 -0.935423
            +vn 0.217322 -0.538713 -0.813959
            +vn 0.202887 -0.618030 -0.759484
            +vn 0.214148 -0.558214 -0.801569
            +vn 0.484359 0.249825 -0.838404
            +vn 0.420881 -0.539720 -0.729026
            +vn 0.392712 -0.619098 -0.680013
            +vn 0.414594 -0.559343 -0.717765
            +vn 0.684652 0.249886 -0.684652
            +vn 0.595050 -0.540147 -0.595050
            +vn 0.555040 -0.619526 -0.555040
            +vn 0.585864 -0.559862 -0.585894
            +vn 0.838404 0.249825 -0.484359
            +vn 0.729026 -0.539720 -0.420881
            +vn 0.680013 -0.619098 -0.392712
            +vn 0.717765 -0.559343 -0.414594
            +vn 0.935423 0.249763 -0.250160
            +vn 0.813959 -0.538713 -0.217322
            +vn 0.759484 -0.618030 -0.202887
            +vn 0.801569 -0.558184 -0.214148
            +s 1
            +f 1//1 2//2 3//3
            +f 3//3 2//2 4//4
            +f 4//4 2//2 5//5
            +f 5//5 2//2 6//6
            +f 6//6 2//2 7//7
            +f 7//7 2//2 8//8
            +f 8//8 2//2 9//9
            +f 9//9 2//2 10//10
            +f 10//10 2//2 11//11
            +f 11//11 2//2 12//12
            +f 12//12 2//2 13//13
            +f 13//13 2//2 14//14
            +f 14//14 2//2 15//15
            +f 15//15 2//2 16//16
            +f 16//16 2//2 17//17
            +f 17//17 2//2 18//18
            +f 18//18 2//2 19//19
            +f 19//19 2//2 20//20
            +f 20//20 2//2 21//21
            +f 21//21 2//2 22//22
            +f 22//22 2//2 23//23
            +f 23//23 2//2 24//24
            +f 24//24 2//2 25//25
            +f 2//2 1//1 25//25
            +f 26//26 27//27 28//28
            +f 28//28 29//29 26//26
            +f 29//29 28//28 30//30
            +f 31//31 30//30 28//28
            +f 30//30 31//31 32//32
            +f 33//33 32//32 31//31
            +f 34//34 35//35 33//33
            +f 32//32 33//33 35//35
            +f 36//36 37//37 34//34
            +f 35//35 34//34 37//37
            +f 38//38 39//39 36//36
            +f 37//37 36//36 39//39
            +f 27//27 40//40 41//41
            +f 41//41 28//28 27//27
            +f 28//28 41//41 31//31
            +f 42//42 31//31 41//41
            +f 31//31 42//42 33//33
            +f 43//43 33//33 42//42
            +f 44//44 34//34 43//43
            +f 33//33 43//43 34//34
            +f 45//45 36//36 44//44
            +f 34//34 44//44 36//36
            +f 46//46 38//38 45//45
            +f 36//36 45//45 38//38
            +f 40//40 47//47 48//48
            +f 48//48 41//41 40//40
            +f 41//41 48//48 42//42
            +f 49//49 42//42 48//48
            +f 42//42 49//49 43//43
            +f 50//50 43//43 49//49
            +f 51//51 44//44 50//50
            +f 43//43 50//50 44//44
            +f 52//52 45//45 51//51
            +f 44//44 51//51 45//45
            +f 53//53 46//46 52//52
            +f 45//45 52//52 46//46
            +f 47//47 54//54 48//48
            +f 55//55 48//48 54//54
            +f 48//48 55//55 49//49
            +f 56//56 49//49 55//55
            +f 49//49 56//56 57//57
            +f 57//57 50//50 49//49
            +f 58//58 51//51 50//50
            +f 50//50 57//57 58//58
            +f 59//59 52//52 51//51
            +f 51//51 58//58 59//59
            +f 60//60 53//53 52//52
            +f 52//52 59//59 60//60
            +f 54//54 61//61 55//55
            +f 62//62 55//55 61//61
            +f 55//55 62//62 63//63
            +f 63//63 56//56 55//55
            +f 56//56 63//63 64//64
            +f 64//64 57//57 56//56
            +f 65//65 58//58 57//57
            +f 57//57 64//64 65//65
            +f 66//66 59//59 58//58
            +f 58//58 65//65 66//66
            +f 67//67 60//60 59//59
            +f 59//59 66//66 67//67
            +f 61//61 68//68 62//62
            +f 69//69 62//62 68//68
            +f 62//62 69//69 70//70
            +f 70//70 63//63 62//62
            +f 63//63 70//70 71//71
            +f 71//71 64//64 63//63
            +f 72//72 65//65 64//64
            +f 64//64 71//71 72//72
            +f 73//73 66//66 65//65
            +f 65//65 72//72 73//73
            +f 74//74 67//67 66//66
            +f 66//66 73//73 74//74
            +f 68//68 75//75 76//76
            +f 76//76 69//69 68//68
            +f 69//69 76//76 70//70
            +f 77//77 70//70 76//76
            +f 70//70 77//77 71//71
            +f 78//78 71//71 77//77
            +f 79//79 72//72 78//78
            +f 71//71 78//78 72//72
            +f 80//80 73//73 79//79
            +f 72//72 79//79 73//73
            +f 81//81 74//74 80//80
            +f 73//73 80//80 74//74
            +f 75//75 82//82 83//83
            +f 83//83 76//76 75//75
            +f 76//76 83//83 77//77
            +f 84//84 77//77 83//83
            +f 77//77 84//84 78//78
            +f 85//85 78//78 84//84
            +f 86//86 79//79 85//85
            +f 78//78 85//85 79//79
            +f 87//87 80//80 86//86
            +f 79//79 86//86 80//80
            +f 88//88 81//81 87//87
            +f 80//80 87//87 81//81
            +f 82//82 89//89 90//90
            +f 90//90 83//83 82//82
            +f 83//83 90//90 91//91
            +f 91//91 84//84 83//83
            +f 84//84 91//91 85//85
            +f 92//92 85//85 91//91
            +f 93//93 86//86 92//92
            +f 85//85 92//92 86//86
            +f 94//94 87//87 93//93
            +f 86//86 93//93 87//87
            +f 95//95 88//88 94//94
            +f 87//87 94//94 88//88
            +f 89//89 96//96 90//90
            +f 97//97 90//90 96//96
            +f 90//90 97//97 98//98
            +f 98//98 91//91 90//90
            +f 91//91 98//98 99//99
            +f 99//99 92//92 91//91
            +f 100//100 93//93 92//92
            +f 92//92 99//99 100//100
            +f 101//101 94//94 93//93
            +f 93//93 100//100 101//101
            +f 102//102 95//95 94//94
            +f 94//94 101//101 102//102
            +f 96//96 103//103 97//97
            +f 104//104 97//97 103//103
            +f 97//97 104//104 105//105
            +f 105//105 98//98 97//97
            +f 98//98 105//105 106//106
            +f 106//106 99//99 98//98
            +f 107//107 100//100 99//99
            +f 99//99 106//106 107//107
            +f 108//108 101//101 100//100
            +f 100//100 107//107 108//108
            +f 109//109 102//102 101//101
            +f 101//101 108//108 109//109
            +f 103//103 110//110 104//104
            +f 111//111 104//104 110//110
            +f 104//104 111//111 112//112
            +f 112//112 105//105 104//104
            +f 105//105 112//112 113//113
            +f 113//113 106//106 105//105
            +f 114//114 107//107 106//106
            +f 106//106 113//113 114//114
            +f 115//115 108//108 107//107
            +f 107//107 114//114 115//115
            +f 116//116 109//109 108//108
            +f 108//108 115//115 116//116
            +f 110//110 117//117 118//118
            +f 118//118 111//111 110//110
            +f 111//111 118//118 119//119
            +f 119//119 112//112 111//111
            +f 112//112 119//119 113//113
            +f 120//120 113//113 119//119
            +f 121//121 114//114 120//120
            +f 113//113 120//120 114//114
            +f 122//122 115//115 121//121
            +f 114//114 121//121 115//115
            +f 123//123 116//116 122//122
            +f 115//115 122//122 116//116
            +f 117//117 124//124 125//125
            +f 125//125 118//118 117//117
            +f 118//118 125//125 119//119
            +f 126//126 119//119 125//125
            +f 119//119 126//126 120//120
            +f 127//127 120//120 126//126
            +f 128//128 121//121 127//127
            +f 120//120 127//127 121//121
            +f 129//129 122//122 128//128
            +f 121//121 128//128 122//122
            +f 130//130 123//123 129//129
            +f 122//122 129//129 123//123
            +f 124//124 131//131 132//132
            +f 132//132 125//125 124//124
            +f 125//125 132//132 133//133
            +f 133//133 126//126 125//125
            +f 126//126 133//133 127//127
            +f 134//134 127//127 133//133
            +f 135//135 128//128 134//134
            +f 127//127 134//134 128//128
            +f 136//136 129//129 135//135
            +f 128//128 135//135 129//129
            +f 137//137 130//130 136//136
            +f 129//129 136//136 130//130
            +f 131//131 138//138 132//132
            +f 139//139 132//132 138//138
            +f 132//132 139//139 140//140
            +f 140//140 133//133 132//132
            +f 133//133 140//140 141//141
            +f 141//141 134//134 133//133
            +f 142//142 135//135 134//134
            +f 134//134 141//141 142//142
            +f 143//143 136//136 135//135
            +f 135//135 142//142 143//143
            +f 144//144 137//137 136//136
            +f 136//136 143//143 144//144
            +f 138//138 145//145 139//139
            +f 146//146 139//139 145//145
            +f 139//139 146//146 147//147
            +f 147//147 140//140 139//139
            +f 140//140 147//147 148//148
            +f 148//148 141//141 140//140
            +f 149//149 142//142 141//141
            +f 141//141 148//148 149//149
            +f 150//150 143//143 142//142
            +f 142//142 149//149 150//150
            +f 151//151 144//144 143//143
            +f 143//143 150//150 151//151
            +f 145//145 152//152 146//146
            +f 153//153 146//146 152//152
            +f 146//146 153//153 154//154
            +f 154//154 147//147 146//146
            +f 147//147 154//154 155//155
            +f 155//155 148//148 147//147
            +f 156//156 149//149 148//148
            +f 148//148 155//155 156//156
            +f 157//157 150//150 149//149
            +f 149//149 156//156 157//157
            +f 158//158 151//151 150//150
            +f 150//150 157//157 158//158
            +f 152//152 159//159 160//160
            +f 160//160 153//153 152//152
            +f 153//153 160//160 154//154
            +f 161//161 154//154 160//160
            +f 154//154 161//161 155//155
            +f 162//162 155//155 161//161
            +f 163//163 156//156 162//162
            +f 155//155 162//162 156//156
            +f 164//164 157//157 163//163
            +f 156//156 163//163 157//157
            +f 165//165 158//158 164//164
            +f 157//157 164//164 158//158
            +f 159//159 166//166 167//167
            +f 167//167 160//160 159//159
            +f 160//160 167//167 161//161
            +f 168//168 161//161 167//167
            +f 161//161 168//168 162//162
            +f 169//169 162//162 168//168
            +f 170//170 163//163 169//169
            +f 162//162 169//169 163//163
            +f 171//171 164//164 170//170
            +f 163//163 170//170 164//164
            +f 172//172 165//165 171//171
            +f 164//164 171//171 165//165
            +f 166//166 173//173 174//174
            +f 174//174 167//167 166//166
            +f 167//167 174//174 168//168
            +f 175//175 168//168 174//174
            +f 168//168 175//175 169//169
            +f 176//176 169//169 175//175
            +f 177//177 170//170 176//176
            +f 169//169 176//176 170//170
            +f 178//178 171//171 177//177
            +f 170//170 177//177 171//171
            +f 179//179 172//172 178//178
            +f 171//171 178//178 172//172
            +f 173//173 180//180 174//174
            +f 181//181 174//174 180//180
            +f 174//174 181//181 175//175
            +f 182//182 175//175 181//181
            +f 175//175 182//182 183//183
            +f 183//183 176//176 175//175
            +f 184//184 177//177 176//176
            +f 176//176 183//183 184//184
            +f 185//185 178//178 177//177
            +f 177//177 184//184 185//185
            +f 186//186 179//179 178//178
            +f 178//178 185//185 186//186
            +f 180//180 187//187 181//181
            +f 188//188 181//181 187//187
            +f 181//181 188//188 189//189
            +f 189//189 182//182 181//181
            +f 182//182 189//189 190//190
            +f 190//190 183//183 182//182
            +f 191//191 184//184 183//183
            +f 183//183 190//190 191//191
            +f 192//192 185//185 184//184
            +f 184//184 191//191 192//192
            +f 193//193 186//186 185//185
            +f 185//185 192//192 193//193
            +f 187//187 26//26 188//188
            +f 29//29 188//188 26//26
            +f 188//188 29//29 189//189
            +f 30//30 189//189 29//29
            +f 189//189 30//30 32//32
            +f 32//32 190//190 189//189
            +f 35//35 191//191 190//190
            +f 190//190 32//32 35//35
            +f 37//37 192//192 191//191
            +f 191//191 35//35 37//37
            +f 39//39 193//193 192//192
            +f 192//192 37//37 39//39
            +f 194//194 195//195 38//38
            +f 39//39 38//38 195//195
            +f 196//196 197//197 194//194
            +f 195//195 194//194 197//197
            +f 198//198 199//199 196//196
            +f 197//197 196//196 199//199
            +f 200//200 201//201 198//198
            +f 199//199 198//198 201//201
            +f 202//202 203//203 200//200
            +f 201//201 200//200 203//203
            +f 204//204 205//205 202//202
            +f 203//203 202//202 205//205
            +f 206//206 194//194 46//46
            +f 38//38 46//46 194//194
            +f 207//207 196//196 206//206
            +f 194//194 206//206 196//196
            +f 208//208 198//198 207//207
            +f 196//196 207//207 198//198
            +f 209//209 200//200 208//208
            +f 198//198 208//208 200//200
            +f 210//210 202//202 209//209
            +f 200//200 209//209 202//202
            +f 211//211 204//204 210//210
            +f 202//202 210//210 204//204
            +f 212//212 206//206 53//53
            +f 46//46 53//53 206//206
            +f 213//213 207//207 212//212
            +f 206//206 212//212 207//207
            +f 214//214 208//208 213//213
            +f 207//207 213//213 208//208
            +f 215//215 209//209 214//214
            +f 208//208 214//214 209//209
            +f 216//216 210//210 215//215
            +f 209//209 215//215 210//210
            +f 217//217 211//211 216//216
            +f 210//210 216//216 211//211
            +f 218//218 212//212 53//53
            +f 53//53 60//60 218//218
            +f 219//219 213//213 212//212
            +f 212//212 218//218 219//219
            +f 220//220 214//214 213//213
            +f 213//213 219//219 220//220
            +f 221//221 215//215 214//214
            +f 214//214 220//220 221//221
            +f 222//222 216//216 215//215
            +f 215//215 221//221 222//222
            +f 223//223 217//217 216//216
            +f 216//216 222//222 223//223
            +f 224//224 218//218 60//60
            +f 60//60 67//67 224//224
            +f 225//225 219//219 218//218
            +f 218//218 224//224 225//225
            +f 226//226 220//220 219//219
            +f 219//219 225//225 226//226
            +f 227//227 221//221 220//220
            +f 220//220 226//226 227//227
            +f 228//228 222//222 221//221
            +f 221//221 227//227 228//228
            +f 229//229 223//223 222//222
            +f 222//222 228//228 229//229
            +f 230//230 224//224 67//67
            +f 67//67 74//74 230//230
            +f 231//231 225//225 224//224
            +f 224//224 230//230 231//231
            +f 232//232 226//226 225//225
            +f 225//225 231//231 232//232
            +f 233//233 227//227 226//226
            +f 226//226 232//232 233//233
            +f 234//234 228//228 227//227
            +f 227//227 233//233 234//234
            +f 235//235 229//229 228//228
            +f 228//228 234//234 235//235
            +f 236//236 230//230 81//81
            +f 74//74 81//81 230//230
            +f 237//237 231//231 236//236
            +f 230//230 236//236 231//231
            +f 238//238 232//232 237//237
            +f 231//231 237//237 232//232
            +f 239//239 233//233 238//238
            +f 232//232 238//238 233//233
            +f 240//240 234//234 239//239
            +f 233//233 239//239 234//234
            +f 241//241 235//235 240//240
            +f 234//234 240//240 235//235
            +f 242//242 236//236 88//88
            +f 81//81 88//88 236//236
            +f 243//243 237//237 242//242
            +f 236//236 242//242 237//237
            +f 244//244 238//238 243//243
            +f 237//237 243//243 238//238
            +f 245//245 239//239 244//244
            +f 238//238 244//244 239//239
            +f 246//246 240//240 245//245
            +f 239//239 245//245 240//240
            +f 247//247 241//241 246//246
            +f 240//240 246//246 241//241
            +f 248//248 242//242 95//95
            +f 88//88 95//95 242//242
            +f 249//249 243//243 248//248
            +f 242//242 248//248 243//243
            +f 250//250 244//244 249//249
            +f 243//243 249//249 244//244
            +f 251//251 245//245 250//250
            +f 244//244 250//250 245//245
            +f 252//252 246//246 251//251
            +f 245//245 251//251 246//246
            +f 253//253 247//247 252//252
            +f 246//246 252//252 247//247
            +f 254//254 248//248 95//95
            +f 95//95 102//102 254//254
            +f 255//255 249//249 248//248
            +f 248//248 254//254 255//255
            +f 256//256 250//250 249//249
            +f 249//249 255//255 256//256
            +f 257//257 251//251 250//250
            +f 250//250 256//256 257//257
            +f 258//258 252//252 251//251
            +f 251//251 257//257 258//258
            +f 259//259 253//253 252//252
            +f 252//252 258//258 259//259
            +f 260//260 254//254 102//102
            +f 102//102 109//109 260//260
            +f 261//261 255//255 254//254
            +f 254//254 260//260 261//261
            +f 262//262 256//256 255//255
            +f 255//255 261//261 262//262
            +f 263//263 257//257 256//256
            +f 256//256 262//262 263//263
            +f 264//264 258//258 257//257
            +f 257//257 263//263 264//264
            +f 265//265 259//259 258//258
            +f 258//258 264//264 265//265
            +f 266//266 260//260 109//109
            +f 109//109 116//116 266//266
            +f 267//267 261//261 260//260
            +f 260//260 266//266 267//267
            +f 268//268 262//262 261//261
            +f 261//261 267//267 268//268
            +f 269//269 263//263 262//262
            +f 262//262 268//268 269//269
            +f 270//270 264//264 263//263
            +f 263//263 269//269 270//270
            +f 271//271 265//265 264//264
            +f 264//264 270//270 271//271
            +f 272//272 266//266 123//123
            +f 116//116 123//123 266//266
            +f 273//273 267//267 272//272
            +f 266//266 272//272 267//267
            +f 274//274 268//268 273//273
            +f 267//267 273//273 268//268
            +f 275//275 269//269 274//274
            +f 268//268 274//274 269//269
            +f 276//276 270//270 275//275
            +f 269//269 275//275 270//270
            +f 277//277 271//271 276//276
            +f 270//270 276//276 271//271
            +f 278//278 272//272 130//130
            +f 123//123 130//130 272//272
            +f 279//279 273//273 278//278
            +f 272//272 278//278 273//273
            +f 280//280 274//274 279//279
            +f 273//273 279//279 274//274
            +f 281//281 275//275 280//280
            +f 274//274 280//280 275//275
            +f 282//282 276//276 281//281
            +f 275//275 281//281 276//276
            +f 283//283 277//277 282//282
            +f 276//276 282//282 277//277
            +f 284//284 278//278 137//137
            +f 130//130 137//137 278//278
            +f 285//285 279//279 284//284
            +f 278//278 284//284 279//279
            +f 286//286 280//280 285//285
            +f 279//279 285//285 280//280
            +f 287//287 281//281 286//286
            +f 280//280 286//286 281//281
            +f 288//288 282//282 287//287
            +f 281//281 287//287 282//282
            +f 289//289 283//283 288//288
            +f 282//282 288//288 283//283
            +f 290//290 284//284 137//137
            +f 137//137 144//144 290//290
            +f 291//291 285//285 284//284
            +f 284//284 290//290 291//291
            +f 292//292 286//286 285//285
            +f 285//285 291//291 292//292
            +f 293//293 287//287 286//286
            +f 286//286 292//292 293//293
            +f 294//294 288//288 287//287
            +f 287//287 293//293 294//294
            +f 295//295 289//289 288//288
            +f 288//288 294//294 295//295
            +f 296//296 290//290 144//144
            +f 144//144 151//151 296//296
            +f 297//297 291//291 290//290
            +f 290//290 296//296 297//297
            +f 298//298 292//292 291//291
            +f 291//291 297//297 298//298
            +f 299//299 293//293 292//292
            +f 292//292 298//298 299//299
            +f 300//300 294//294 293//293
            +f 293//293 299//299 300//300
            +f 301//301 295//295 294//294
            +f 294//294 300//300 301//301
            +f 302//302 296//296 151//151
            +f 151//151 158//158 302//302
            +f 303//303 297//297 296//296
            +f 296//296 302//302 303//303
            +f 304//304 298//298 297//297
            +f 297//297 303//303 304//304
            +f 305//305 299//299 298//298
            +f 298//298 304//304 305//305
            +f 306//306 300//300 299//299
            +f 299//299 305//305 306//306
            +f 307//307 301//301 300//300
            +f 300//300 306//306 307//307
            +f 308//308 302//302 165//165
            +f 158//158 165//165 302//302
            +f 309//309 303//303 308//308
            +f 302//302 308//308 303//303
            +f 310//310 304//304 309//309
            +f 303//303 309//309 304//304
            +f 311//311 305//305 310//310
            +f 304//304 310//310 305//305
            +f 312//312 306//306 311//311
            +f 305//305 311//311 306//306
            +f 313//313 307//307 312//312
            +f 306//306 312//312 307//307
            +f 314//314 308//308 172//172
            +f 165//165 172//172 308//308
            +f 315//315 309//309 314//314
            +f 308//308 314//314 309//309
            +f 316//316 310//310 315//315
            +f 309//309 315//315 310//310
            +f 317//317 311//311 316//316
            +f 310//310 316//316 311//311
            +f 318//318 312//312 317//317
            +f 311//311 317//317 312//312
            +f 319//319 313//313 318//318
            +f 312//312 318//318 313//313
            +f 320//320 314//314 179//179
            +f 172//172 179//179 314//314
            +f 321//321 315//315 320//320
            +f 314//314 320//320 315//315
            +f 322//322 316//316 321//321
            +f 315//315 321//321 316//316
            +f 323//323 317//317 322//322
            +f 316//316 322//322 317//317
            +f 324//324 318//318 323//323
            +f 317//317 323//323 318//318
            +f 325//325 319//319 324//324
            +f 318//318 324//324 319//319
            +f 326//326 320//320 179//179
            +f 179//179 186//186 326//326
            +f 327//327 321//321 320//320
            +f 320//320 326//326 327//327
            +f 328//328 322//322 321//321
            +f 321//321 327//327 328//328
            +f 329//329 323//323 322//322
            +f 322//322 328//328 329//329
            +f 330//330 324//324 323//323
            +f 323//323 329//329 330//330
            +f 331//331 325//325 324//324
            +f 324//324 330//330 331//331
            +f 332//332 326//326 186//186
            +f 186//186 193//193 332//332
            +f 333//333 327//327 326//326
            +f 326//326 332//332 333//333
            +f 334//334 328//328 327//327
            +f 327//327 333//333 334//334
            +f 335//335 329//329 328//328
            +f 328//328 334//334 335//335
            +f 336//336 330//330 329//329
            +f 329//329 335//335 336//336
            +f 337//337 331//331 330//330
            +f 330//330 336//336 337//337
            +f 195//195 332//332 193//193
            +f 193//193 39//39 195//195
            +f 197//197 333//333 332//332
            +f 332//332 195//195 197//197
            +f 199//199 334//334 333//333
            +f 333//333 197//197 199//199
            +f 201//201 335//335 334//334
            +f 334//334 199//199 201//201
            +f 203//203 336//336 335//335
            +f 335//335 201//201 203//203
            +f 205//205 337//337 336//336
            +f 336//336 203//203 205//205
            +f 338//338 339//339 205//205
            +f 205//205 204//204 338//338
            +f 340//340 341//341 339//339
            +f 339//339 338//338 340//340
            +f 342//342 343//343 341//341
            +f 341//341 340//340 342//342
            +f 344//344 345//345 343//343
            +f 343//343 342//342 344//344
            +f 346//346 347//347 345//345
            +f 345//345 344//344 346//346
            +f 348//348 349//349 347//347
            +f 347//347 346//346 348//348
            +f 350//350 338//338 204//204
            +f 204//204 211//211 350//350
            +f 351//351 340//340 338//338
            +f 338//338 350//350 351//351
            +f 352//352 342//342 340//340
            +f 340//340 351//351 352//352
            +f 353//353 344//344 342//342
            +f 342//342 352//352 353//353
            +f 354//354 346//346 344//344
            +f 344//344 353//353 354//354
            +f 355//355 348//348 346//346
            +f 346//346 354//354 355//355
            +f 356//356 350//350 211//211
            +f 211//211 217//217 356//356
            +f 357//357 351//351 350//350
            +f 350//350 356//356 357//357
            +f 358//358 352//352 351//351
            +f 351//351 357//357 358//358
            +f 359//359 353//353 352//352
            +f 352//352 358//358 359//359
            +f 360//360 354//354 353//353
            +f 353//353 359//359 360//360
            +f 361//361 355//355 354//354
            +f 354//354 360//360 361//361
            +f 362//362 356//356 223//223
            +f 217//217 223//223 356//356
            +f 363//363 357//357 362//362
            +f 356//356 362//362 357//357
            +f 364//364 358//358 363//363
            +f 357//357 363//363 358//358
            +f 365//365 359//359 364//364
            +f 358//358 364//364 359//359
            +f 366//366 360//360 365//365
            +f 359//359 365//365 360//360
            +f 367//367 361//361 366//366
            +f 360//360 366//366 361//361
            +f 368//368 362//362 229//229
            +f 223//223 229//229 362//362
            +f 369//369 363//363 368//368
            +f 362//362 368//368 363//363
            +f 370//370 364//364 369//369
            +f 363//363 369//369 364//364
            +f 371//371 365//365 370//370
            +f 364//364 370//370 365//365
            +f 372//372 366//366 371//371
            +f 365//365 371//371 366//366
            +f 373//373 367//367 372//372
            +f 366//366 372//372 367//367
            +f 374//374 368//368 235//235
            +f 229//229 235//235 368//368
            +f 375//375 369//369 374//374
            +f 368//368 374//374 369//369
            +f 376//376 370//370 375//375
            +f 369//369 375//375 370//370
            +f 377//377 371//371 376//376
            +f 370//370 376//376 371//371
            +f 378//378 372//372 377//377
            +f 371//371 377//377 372//372
            +f 379//379 373//373 378//378
            +f 372//372 378//378 373//373
            +f 380//380 374//374 235//235
            +f 235//235 241//241 380//380
            +f 381//381 375//375 374//374
            +f 374//374 380//380 381//381
            +f 382//382 376//376 375//375
            +f 375//375 381//381 382//382
            +f 383//383 377//377 376//376
            +f 376//376 382//382 383//383
            +f 384//384 378//378 377//377
            +f 377//377 383//383 384//384
            +f 385//385 379//379 378//378
            +f 378//378 384//384 385//385
            +f 386//386 380//380 241//241
            +f 241//241 247//247 386//386
            +f 387//387 381//381 380//380
            +f 380//380 386//386 387//387
            +f 388//388 382//382 381//381
            +f 381//381 387//387 388//388
            +f 389//389 383//383 382//382
            +f 382//382 388//388 389//389
            +f 390//390 384//384 383//383
            +f 383//383 389//389 390//390
            +f 391//391 385//385 384//384
            +f 384//384 390//390 391//391
            +f 392//392 386//386 247//247
            +f 247//247 253//253 392//392
            +f 393//393 387//387 386//386
            +f 386//386 392//392 393//393
            +f 394//394 388//388 387//387
            +f 387//387 393//393 394//394
            +f 395//395 389//389 388//388
            +f 388//388 394//394 395//395
            +f 396//396 390//390 389//389
            +f 389//389 395//395 396//396
            +f 397//397 391//391 390//390
            +f 390//390 396//396 397//397
            +f 398//398 392//392 259//259
            +f 253//253 259//259 392//392
            +f 399//399 393//393 398//398
            +f 392//392 398//398 393//393
            +f 400//400 394//394 399//399
            +f 393//393 399//399 394//394
            +f 401//401 395//395 400//400
            +f 394//394 400//400 395//395
            +f 402//402 396//396 401//401
            +f 395//395 401//401 396//396
            +f 403//403 397//397 402//402
            +f 396//396 402//402 397//397
            +f 404//404 398//398 265//265
            +f 259//259 265//265 398//398
            +f 405//405 399//399 404//404
            +f 398//398 404//404 399//399
            +f 406//406 400//400 405//405
            +f 399//399 405//405 400//400
            +f 407//407 401//401 406//406
            +f 400//400 406//406 401//401
            +f 408//408 402//402 407//407
            +f 401//401 407//407 402//402
            +f 409//409 403//403 408//408
            +f 402//402 408//408 403//403
            +f 410//410 404//404 271//271
            +f 265//265 271//271 404//404
            +f 411//411 405//405 410//410
            +f 404//404 410//410 405//405
            +f 412//412 406//406 411//411
            +f 405//405 411//411 406//406
            +f 413//413 407//407 412//412
            +f 406//406 412//412 407//407
            +f 414//414 408//408 413//413
            +f 407//407 413//413 408//408
            +f 415//415 409//409 414//414
            +f 408//408 414//414 409//409
            +f 416//416 410//410 271//271
            +f 271//271 277//277 416//416
            +f 417//417 411//411 410//410
            +f 410//410 416//416 417//417
            +f 418//418 412//412 411//411
            +f 411//411 417//417 418//418
            +f 419//419 413//413 412//412
            +f 412//412 418//418 419//419
            +f 420//420 414//414 413//413
            +f 413//413 419//419 420//420
            +f 421//421 415//415 414//414
            +f 414//414 420//420 421//421
            +f 422//422 416//416 277//277
            +f 277//277 283//283 422//422
            +f 423//423 417//417 416//416
            +f 416//416 422//422 423//423
            +f 424//424 418//418 417//417
            +f 417//417 423//423 424//424
            +f 425//425 419//419 418//418
            +f 418//418 424//424 425//425
            +f 426//426 420//420 419//419
            +f 419//419 425//425 426//426
            +f 427//427 421//421 420//420
            +f 420//420 426//426 427//427
            +f 428//428 422//422 283//283
            +f 283//283 289//289 428//428
            +f 429//429 423//423 422//422
            +f 422//422 428//428 429//429
            +f 430//430 424//424 423//423
            +f 423//423 429//429 430//430
            +f 431//431 425//425 424//424
            +f 424//424 430//430 431//431
            +f 432//432 426//426 425//425
            +f 425//425 431//431 432//432
            +f 433//433 427//427 426//426
            +f 426//426 432//432 433//433
            +f 434//434 428//428 295//295
            +f 289//289 295//295 428//428
            +f 435//435 429//429 434//434
            +f 428//428 434//434 429//429
            +f 436//436 430//430 435//435
            +f 429//429 435//435 430//430
            +f 437//437 431//431 436//436
            +f 430//430 436//436 431//431
            +f 438//438 432//432 437//437
            +f 431//431 437//437 432//432
            +f 439//439 433//433 438//438
            +f 432//432 438//438 433//433
            +f 440//440 434//434 301//301
            +f 295//295 301//301 434//434
            +f 441//441 435//435 440//440
            +f 434//434 440//440 435//435
            +f 442//442 436//436 441//441
            +f 435//435 441//441 436//436
            +f 443//443 437//437 442//442
            +f 436//436 442//442 437//437
            +f 444//444 438//438 443//443
            +f 437//437 443//443 438//438
            +f 445//445 439//439 444//444
            +f 438//438 444//444 439//439
            +f 446//446 440//440 307//307
            +f 301//301 307//307 440//440
            +f 447//447 441//441 446//446
            +f 440//440 446//446 441//441
            +f 448//448 442//442 447//447
            +f 441//441 447//447 442//442
            +f 449//449 443//443 448//448
            +f 442//442 448//448 443//443
            +f 450//450 444//444 449//449
            +f 443//443 449//449 444//444
            +f 451//451 445//445 450//450
            +f 444//444 450//450 445//445
            +f 452//452 446//446 307//307
            +f 307//307 313//313 452//452
            +f 453//453 447//447 446//446
            +f 446//446 452//452 453//453
            +f 454//454 448//448 447//447
            +f 447//447 453//453 454//454
            +f 455//455 449//449 448//448
            +f 448//448 454//454 455//455
            +f 456//456 450//450 449//449
            +f 449//449 455//455 456//456
            +f 457//457 451//451 450//450
            +f 450//450 456//456 457//457
            +f 458//458 452//452 313//313
            +f 313//313 319//319 458//458
            +f 459//459 453//453 452//452
            +f 452//452 458//458 459//459
            +f 460//460 454//454 453//453
            +f 453//453 459//459 460//460
            +f 461//461 455//455 454//454
            +f 454//454 460//460 461//461
            +f 462//462 456//456 455//455
            +f 455//455 461//461 462//462
            +f 463//463 457//457 456//456
            +f 456//456 462//462 463//463
            +f 464//464 458//458 319//319
            +f 319//319 325//325 464//464
            +f 465//465 459//459 458//458
            +f 458//458 464//464 465//465
            +f 466//466 460//460 459//459
            +f 459//459 465//465 466//466
            +f 467//467 461//461 460//460
            +f 460//460 466//466 467//467
            +f 468//468 462//462 461//461
            +f 461//461 467//467 468//468
            +f 469//469 463//463 462//462
            +f 462//462 468//468 469//469
            +f 470//470 464//464 331//331
            +f 325//325 331//331 464//464
            +f 471//471 465//465 470//470
            +f 464//464 470//470 465//465
            +f 472//472 466//466 471//471
            +f 465//465 471//471 466//466
            +f 473//473 467//467 472//472
            +f 466//466 472//472 467//467
            +f 474//474 468//468 473//473
            +f 467//467 473//473 468//468
            +f 475//475 469//469 474//474
            +f 468//468 474//474 469//469
            +f 476//476 470//470 337//337
            +f 331//331 337//337 470//470
            +f 477//477 471//471 476//476
            +f 470//470 476//476 471//471
            +f 478//478 472//472 477//477
            +f 471//471 477//477 472//472
            +f 479//479 473//473 478//478
            +f 472//472 478//478 473//473
            +f 480//480 474//474 479//479
            +f 473//473 479//479 474//474
            +f 481//481 475//475 480//480
            +f 474//474 480//480 475//475
            +f 339//339 476//476 205//205
            +f 337//337 205//205 476//476
            +f 341//341 477//477 339//339
            +f 476//476 339//339 477//477
            +f 343//343 478//478 341//341
            +f 477//477 341//341 478//478
            +f 345//345 479//479 343//343
            +f 478//478 343//343 479//479
            +f 347//347 480//480 345//345
            +f 479//479 345//345 480//480
            +f 349//349 481//481 347//347
            +f 480//480 347//347 481//481
            +f 1//1 3//3 482//482
            +f 483//483 482//482 3//3
            +f 482//482 483//483 484//484
            +f 485//485 484//484 483//483
            +f 484//484 485//485 486//486
            +f 487//487 486//486 485//485
            +f 486//486 487//487 488//488
            +f 489//489 488//488 487//487
            +f 488//488 489//489 349//349
            +f 481//481 349//349 489//489
            +f 3//3 4//4 483//483
            +f 490//490 483//483 4//4
            +f 483//483 490//490 485//485
            +f 491//491 485//485 490//490
            +f 485//485 491//491 487//487
            +f 492//492 487//487 491//491
            +f 487//487 492//492 489//489
            +f 493//493 489//489 492//492
            +f 489//489 493//493 481//481
            +f 475//475 481//481 493//493
            +f 4//4 5//5 490//490
            +f 494//494 490//490 5//5
            +f 490//490 494//494 491//491
            +f 495//495 491//491 494//494
            +f 491//491 495//495 492//492
            +f 496//496 492//492 495//495
            +f 492//492 496//496 493//493
            +f 497//497 493//493 496//496
            +f 493//493 497//497 475//475
            +f 469//469 475//475 497//497
            +f 5//5 6//6 498//498
            +f 498//498 494//494 5//5
            +f 494//494 498//498 499//499
            +f 499//499 495//495 494//494
            +f 495//495 499//499 500//500
            +f 500//500 496//496 495//495
            +f 496//496 500//500 501//501
            +f 501//501 497//497 496//496
            +f 497//497 501//501 463//463
            +f 463//463 469//469 497//497
            +f 6//6 7//7 502//502
            +f 502//502 498//498 6//6
            +f 498//498 502//502 503//503
            +f 503//503 499//499 498//498
            +f 499//499 503//503 504//504
            +f 504//504 500//500 499//499
            +f 500//500 504//504 505//505
            +f 505//505 501//501 500//500
            +f 501//501 505//505 457//457
            +f 457//457 463//463 501//501
            +f 7//7 8//8 506//506
            +f 506//506 502//502 7//7
            +f 502//502 506//506 507//507
            +f 507//507 503//503 502//502
            +f 503//503 507//507 508//508
            +f 508//508 504//504 503//503
            +f 504//504 508//508 509//509
            +f 509//509 505//505 504//504
            +f 505//505 509//509 451//451
            +f 451//451 457//457 505//505
            +f 8//8 9//9 506//506
            +f 510//510 506//506 9//9
            +f 506//506 510//510 507//507
            +f 511//511 507//507 510//510
            +f 507//507 511//511 508//508
            +f 512//512 508//508 511//511
            +f 508//508 512//512 509//509
            +f 513//513 509//509 512//512
            +f 509//509 513//513 451//451
            +f 445//445 451//451 513//513
            +f 9//9 10//10 510//510
            +f 514//514 510//510 10//10
            +f 510//510 514//514 511//511
            +f 515//515 511//511 514//514
            +f 511//511 515//515 512//512
            +f 516//516 512//512 515//515
            +f 512//512 516//516 513//513
            +f 517//517 513//513 516//516
            +f 513//513 517//517 445//445
            +f 439//439 445//445 517//517
            +f 10//10 11//11 514//514
            +f 518//518 514//514 11//11
            +f 514//514 518//518 515//515
            +f 519//519 515//515 518//518
            +f 515//515 519//519 516//516
            +f 520//520 516//516 519//519
            +f 516//516 520//520 517//517
            +f 521//521 517//517 520//520
            +f 517//517 521//521 439//439
            +f 433//433 439//439 521//521
            +f 11//11 12//12 522//522
            +f 522//522 518//518 11//11
            +f 518//518 522//522 523//523
            +f 523//523 519//519 518//518
            +f 519//519 523//523 524//524
            +f 524//524 520//520 519//519
            +f 520//520 524//524 525//525
            +f 525//525 521//521 520//520
            +f 521//521 525//525 427//427
            +f 427//427 433//433 521//521
            +f 12//12 13//13 526//526
            +f 526//526 522//522 12//12
            +f 522//522 526//526 527//527
            +f 527//527 523//523 522//522
            +f 523//523 527//527 528//528
            +f 528//528 524//524 523//523
            +f 524//524 528//528 529//529
            +f 529//529 525//525 524//524
            +f 525//525 529//529 421//421
            +f 421//421 427//427 525//525
            +f 13//13 14//14 530//530
            +f 530//530 526//526 13//13
            +f 526//526 530//530 531//531
            +f 531//531 527//527 526//526
            +f 527//527 531//531 532//532
            +f 532//532 528//528 527//527
            +f 528//528 532//532 533//533
            +f 533//533 529//529 528//528
            +f 529//529 533//533 415//415
            +f 415//415 421//421 529//529
            +f 14//14 15//15 530//530
            +f 534//534 530//530 15//15
            +f 530//530 534//534 531//531
            +f 535//535 531//531 534//534
            +f 531//531 535//535 532//532
            +f 536//536 532//532 535//535
            +f 532//532 536//536 533//533
            +f 537//537 533//533 536//536
            +f 533//533 537//537 415//415
            +f 409//409 415//415 537//537
            +f 15//15 16//16 534//534
            +f 538//538 534//534 16//16
            +f 534//534 538//538 535//535
            +f 539//539 535//535 538//538
            +f 535//535 539//539 536//536
            +f 540//540 536//536 539//539
            +f 536//536 540//540 537//537
            +f 541//541 537//537 540//540
            +f 537//537 541//541 409//409
            +f 403//403 409//409 541//541
            +f 16//16 17//17 538//538
            +f 542//542 538//538 17//17
            +f 538//538 542//542 539//539
            +f 543//543 539//539 542//542
            +f 539//539 543//543 540//540
            +f 544//544 540//540 543//543
            +f 540//540 544//544 541//541
            +f 545//545 541//541 544//544
            +f 541//541 545//545 403//403
            +f 397//397 403//403 545//545
            +f 17//17 18//18 546//546
            +f 546//546 542//542 17//17
            +f 542//542 546//546 547//547
            +f 547//547 543//543 542//542
            +f 543//543 547//547 548//548
            +f 548//548 544//544 543//543
            +f 544//544 548//548 549//549
            +f 549//549 545//545 544//544
            +f 545//545 549//549 391//391
            +f 391//391 397//397 545//545
            +f 18//18 19//19 550//550
            +f 550//550 546//546 18//18
            +f 546//546 550//550 551//551
            +f 551//551 547//547 546//546
            +f 547//547 551//551 552//552
            +f 552//552 548//548 547//547
            +f 548//548 552//552 553//553
            +f 553//553 549//549 548//548
            +f 549//549 553//553 385//385
            +f 385//385 391//391 549//549
            +f 19//19 20//20 554//554
            +f 554//554 550//550 19//19
            +f 550//550 554//554 555//555
            +f 555//555 551//551 550//550
            +f 551//551 555//555 556//556
            +f 556//556 552//552 551//551
            +f 552//552 556//556 557//557
            +f 557//557 553//553 552//552
            +f 553//553 557//557 379//379
            +f 379//379 385//385 553//553
            +f 20//20 21//21 554//554
            +f 558//558 554//554 21//21
            +f 554//554 558//558 555//555
            +f 559//559 555//555 558//558
            +f 555//555 559//559 556//556
            +f 560//560 556//556 559//559
            +f 556//556 560//560 557//557
            +f 561//561 557//557 560//560
            +f 557//557 561//561 379//379
            +f 373//373 379//379 561//561
            +f 21//21 22//22 558//558
            +f 562//562 558//558 22//22
            +f 558//558 562//562 559//559
            +f 563//563 559//559 562//562
            +f 559//559 563//563 560//560
            +f 564//564 560//560 563//563
            +f 560//560 564//564 561//561
            +f 565//565 561//561 564//564
            +f 561//561 565//565 373//373
            +f 367//367 373//373 565//565
            +f 22//22 23//23 562//562
            +f 566//566 562//562 23//23
            +f 562//562 566//566 563//563
            +f 567//567 563//563 566//566
            +f 563//563 567//567 564//564
            +f 568//568 564//564 567//567
            +f 564//564 568//568 565//565
            +f 569//569 565//565 568//568
            +f 565//565 569//569 367//367
            +f 361//361 367//367 569//569
            +f 23//23 24//24 570//570
            +f 570//570 566//566 23//23
            +f 566//566 570//570 571//571
            +f 571//571 567//567 566//566
            +f 567//567 571//571 572//572
            +f 572//572 568//568 567//567
            +f 568//568 572//572 573//573
            +f 573//573 569//569 568//568
            +f 569//569 573//573 355//355
            +f 355//355 361//361 569//569
            +f 24//24 25//25 574//574
            +f 574//574 570//570 24//24
            +f 570//570 574//574 575//575
            +f 575//575 571//571 570//570
            +f 571//571 575//575 576//576
            +f 576//576 572//572 571//571
            +f 572//572 576//576 577//577
            +f 577//577 573//573 572//572
            +f 573//573 577//577 348//348
            +f 348//348 355//355 573//573
            +f 25//25 1//1 482//482
            +f 482//482 574//574 25//25
            +f 574//574 482//482 484//484
            +f 484//484 575//575 574//574
            +f 575//575 484//484 486//486
            +f 486//486 576//576 575//575
            +f 576//576 486//486 488//488
            +f 488//488 577//577 576//576
            +f 577//577 488//488 349//349
            +f 349//349 348//348 577//577
            +f 578//578 579//579 580//580
            +f 581//581 580//580 579//579
            +f 582//582 578//578 583//583
            +f 580//580 583//583 578//578
            +f 584//584 582//582 585//585
            +f 583//583 585//585 582//582
            +f 586//586 584//584 585//585
            +f 585//585 587//587 586//586
            +f 588//588 586//586 587//587
            +f 587//587 589//589 588//588
            +f 590//590 588//588 589//589
            +f 589//589 591//591 590//590
            +f 592//592 590//590 593//593
            +f 591//591 593//593 590//590
            +f 594//594 592//592 595//595
            +f 593//593 595//595 592//592
            +f 596//596 594//594 597//597
            +f 595//595 597//597 594//594
            +f 598//598 596//596 597//597
            +f 597//597 599//599 598//598
            +f 600//600 598//598 599//599
            +f 599//599 601//601 600//600
            +f 602//602 600//600 601//601
            +f 601//601 603//603 602//602
            +f 604//604 602//602 605//605
            +f 603//603 605//605 602//602
            +f 606//606 604//604 607//607
            +f 605//605 607//607 604//604
            +f 608//608 606//606 609//609
            +f 607//607 609//609 606//606
            +f 610//610 608//608 609//609
            +f 609//609 611//611 610//610
            +f 612//612 610//610 611//611
            +f 611//611 613//613 612//612
            +f 614//614 612//612 613//613
            +f 613//613 615//615 614//614
            +f 616//616 614//614 617//617
            +f 615//615 617//617 614//614
            +f 618//618 616//616 619//619
            +f 617//617 619//619 616//616
            +f 620//620 618//618 621//621
            +f 619//619 621//621 618//618
            +f 622//622 620//620 621//621
            +f 621//621 623//623 622//622
            +f 624//624 622//622 623//623
            +f 623//623 625//625 624//624
            +f 579//579 624//624 625//625
            +f 625//625 581//581 579//579
            +f 626//626 627//627 578//578
            +f 579//579 578//578 627//627
            +f 628//628 629//629 626//626
            +f 627//627 626//626 629//629
            +f 630//630 631//631 628//628
            +f 629//629 628//628 631//631
            +f 632//632 633//633 630//630
            +f 631//631 630//630 633//633
            +f 634//634 635//635 632//632
            +f 633//633 632//632 635//635
            +f 636//636 637//637 634//634
            +f 635//635 634//634 637//637
            +f 638//638 626//626 582//582
            +f 578//578 582//582 626//626
            +f 639//639 628//628 638//638
            +f 626//626 638//638 628//628
            +f 640//640 630//630 639//639
            +f 628//628 639//639 630//630
            +f 641//641 632//632 640//640
            +f 630//630 640//640 632//632
            +f 642//642 634//634 641//641
            +f 632//632 641//641 634//634
            +f 643//643 636//636 642//642
            +f 634//634 642//642 636//636
            +f 644//644 638//638 584//584
            +f 582//582 584//584 638//638
            +f 645//645 639//639 644//644
            +f 638//638 644//644 639//639
            +f 646//646 640//640 645//645
            +f 639//639 645//645 640//640
            +f 647//647 641//641 646//646
            +f 640//640 646//646 641//641
            +f 648//648 642//642 647//647
            +f 641//641 647//647 642//642
            +f 649//649 643//643 648//648
            +f 642//642 648//648 643//643
            +f 650//650 644//644 584//584
            +f 584//584 586//586 650//650
            +f 651//651 645//645 644//644
            +f 644//644 650//650 651//651
            +f 652//652 646//646 645//645
            +f 645//645 651//651 652//652
            +f 653//653 647//647 646//646
            +f 646//646 652//652 653//653
            +f 654//654 648//648 647//647
            +f 647//647 653//653 654//654
            +f 655//655 649//649 648//648
            +f 648//648 654//654 655//655
            +f 656//656 650//650 586//586
            +f 586//586 588//588 656//656
            +f 657//657 651//651 650//650
            +f 650//650 656//656 657//657
            +f 658//658 652//652 651//651
            +f 651//651 657//657 658//658
            +f 659//659 653//653 652//652
            +f 652//652 658//658 659//659
            +f 660//660 654//654 653//653
            +f 653//653 659//659 660//660
            +f 661//661 655//655 654//654
            +f 654//654 660//660 661//661
            +f 662//662 656//656 588//588
            +f 588//588 590//590 662//662
            +f 663//663 657//657 656//656
            +f 656//656 662//662 663//663
            +f 664//664 658//658 657//657
            +f 657//657 663//663 664//664
            +f 665//665 659//659 658//658
            +f 658//658 664//664 665//665
            +f 666//666 660//660 659//659
            +f 659//659 665//665 666//666
            +f 667//667 661//661 660//660
            +f 660//660 666//666 667//667
            +f 668//668 662//662 592//592
            +f 590//590 592//592 662//662
            +f 669//669 663//663 668//668
            +f 662//662 668//668 663//663
            +f 670//670 664//664 669//669
            +f 663//663 669//669 664//664
            +f 671//671 665//665 670//670
            +f 664//664 670//670 665//665
            +f 672//672 666//666 671//671
            +f 665//665 671//671 666//666
            +f 673//673 667//667 672//672
            +f 666//666 672//672 667//667
            +f 674//674 668//668 594//594
            +f 592//592 594//594 668//668
            +f 675//675 669//669 674//674
            +f 668//668 674//674 669//669
            +f 676//676 670//670 675//675
            +f 669//669 675//675 670//670
            +f 677//677 671//671 676//676
            +f 670//670 676//676 671//671
            +f 678//678 672//672 677//677
            +f 671//671 677//677 672//672
            +f 679//679 673//673 678//678
            +f 672//672 678//678 673//673
            +f 680//680 674//674 596//596
            +f 594//594 596//596 674//674
            +f 681//681 675//675 680//680
            +f 674//674 680//680 675//675
            +f 682//682 676//676 681//681
            +f 675//675 681//681 676//676
            +f 683//683 677//677 682//682
            +f 676//676 682//682 677//677
            +f 684//684 678//678 683//683
            +f 677//677 683//683 678//678
            +f 685//685 679//679 684//684
            +f 678//678 684//684 679//679
            +f 686//686 680//680 596//596
            +f 596//596 598//598 686//686
            +f 687//687 681//681 680//680
            +f 680//680 686//686 687//687
            +f 688//688 682//682 681//681
            +f 681//681 687//687 688//688
            +f 689//689 683//683 682//682
            +f 682//682 688//688 689//689
            +f 690//690 684//684 683//683
            +f 683//683 689//689 690//690
            +f 691//691 685//685 684//684
            +f 684//684 690//690 691//691
            +f 692//692 686//686 598//598
            +f 598//598 600//600 692//692
            +f 693//693 687//687 686//686
            +f 686//686 692//692 693//693
            +f 694//694 688//688 687//687
            +f 687//687 693//693 694//694
            +f 695//695 689//689 688//688
            +f 688//688 694//694 695//695
            +f 696//696 690//690 689//689
            +f 689//689 695//695 696//696
            +f 697//697 691//691 690//690
            +f 690//690 696//696 697//697
            +f 698//698 692//692 600//600
            +f 600//600 602//602 698//698
            +f 699//699 693//693 692//692
            +f 692//692 698//698 699//699
            +f 700//700 694//694 693//693
            +f 693//693 699//699 700//700
            +f 701//701 695//695 694//694
            +f 694//694 700//700 701//701
            +f 702//702 696//696 695//695
            +f 695//695 701//701 702//702
            +f 703//703 697//697 696//696
            +f 696//696 702//702 703//703
            +f 704//704 698//698 604//604
            +f 602//602 604//604 698//698
            +f 705//705 699//699 704//704
            +f 698//698 704//704 699//699
            +f 706//706 700//700 705//705
            +f 699//699 705//705 700//700
            +f 707//707 701//701 706//706
            +f 700//700 706//706 701//701
            +f 708//708 702//702 707//707
            +f 701//701 707//707 702//702
            +f 709//709 703//703 708//708
            +f 702//702 708//708 703//703
            +f 710//710 704//704 606//606
            +f 604//604 606//606 704//704
            +f 711//711 705//705 710//710
            +f 704//704 710//710 705//705
            +f 712//712 706//706 711//711
            +f 705//705 711//711 706//706
            +f 713//713 707//707 712//712
            +f 706//706 712//712 707//707
            +f 714//714 708//708 713//713
            +f 707//707 713//713 708//708
            +f 715//715 709//709 714//714
            +f 708//708 714//714 709//709
            +f 716//716 710//710 608//608
            +f 606//606 608//608 710//710
            +f 717//717 711//711 716//716
            +f 710//710 716//716 711//711
            +f 718//718 712//712 717//717
            +f 711//711 717//717 712//712
            +f 719//719 713//713 718//718
            +f 712//712 718//718 713//713
            +f 720//720 714//714 719//719
            +f 713//713 719//719 714//714
            +f 721//721 715//715 720//720
            +f 714//714 720//720 715//715
            +f 722//722 716//716 608//608
            +f 608//608 610//610 722//722
            +f 723//723 717//717 716//716
            +f 716//716 722//722 723//723
            +f 724//724 718//718 717//717
            +f 717//717 723//723 724//724
            +f 725//725 719//719 718//718
            +f 718//718 724//724 725//725
            +f 726//726 720//720 719//719
            +f 719//719 725//725 726//726
            +f 727//727 721//721 720//720
            +f 720//720 726//726 727//727
            +f 728//728 722//722 610//610
            +f 610//610 612//612 728//728
            +f 729//729 723//723 722//722
            +f 722//722 728//728 729//729
            +f 730//730 724//724 723//723
            +f 723//723 729//729 730//730
            +f 731//731 725//725 724//724
            +f 724//724 730//730 731//731
            +f 732//732 726//726 725//725
            +f 725//725 731//731 732//732
            +f 733//733 727//727 726//726
            +f 726//726 732//732 733//733
            +f 734//734 728//728 612//612
            +f 612//612 614//614 734//734
            +f 735//735 729//729 728//728
            +f 728//728 734//734 735//735
            +f 736//736 730//730 729//729
            +f 729//729 735//735 736//736
            +f 737//737 731//731 730//730
            +f 730//730 736//736 737//737
            +f 738//738 732//732 731//731
            +f 731//731 737//737 738//738
            +f 739//739 733//733 732//732
            +f 732//732 738//738 739//739
            +f 740//740 734//734 616//616
            +f 614//614 616//616 734//734
            +f 741//741 735//735 740//740
            +f 734//734 740//740 735//735
            +f 742//742 736//736 741//741
            +f 735//735 741//741 736//736
            +f 743//743 737//737 742//742
            +f 736//736 742//742 737//737
            +f 744//744 738//738 743//743
            +f 737//737 743//743 738//738
            +f 745//745 739//739 744//744
            +f 738//738 744//744 739//739
            +f 746//746 740//740 618//618
            +f 616//616 618//618 740//740
            +f 747//747 741//741 746//746
            +f 740//740 746//746 741//741
            +f 748//748 742//742 747//747
            +f 741//741 747//747 742//742
            +f 749//749 743//743 748//748
            +f 742//742 748//748 743//743
            +f 750//750 744//744 749//749
            +f 743//743 749//749 744//744
            +f 751//751 745//745 750//750
            +f 744//744 750//750 745//745
            +f 752//752 746//746 620//620
            +f 618//618 620//620 746//746
            +f 753//753 747//747 752//752
            +f 746//746 752//752 747//747
            +f 754//754 748//748 753//753
            +f 747//747 753//753 748//748
            +f 755//755 749//749 754//754
            +f 748//748 754//754 749//749
            +f 756//756 750//750 755//755
            +f 749//749 755//755 750//750
            +f 757//757 751//751 756//756
            +f 750//750 756//756 751//751
            +f 758//758 752//752 620//620
            +f 620//620 622//622 758//758
            +f 759//759 753//753 752//752
            +f 752//752 758//758 759//759
            +f 760//760 754//754 753//753
            +f 753//753 759//759 760//760
            +f 761//761 755//755 754//754
            +f 754//754 760//760 761//761
            +f 762//762 756//756 755//755
            +f 755//755 761//761 762//762
            +f 763//763 757//757 756//756
            +f 756//756 762//762 763//763
            +f 764//764 758//758 622//622
            +f 622//622 624//624 764//764
            +f 765//765 759//759 758//758
            +f 758//758 764//764 765//765
            +f 766//766 760//760 759//759
            +f 759//759 765//765 766//766
            +f 767//767 761//761 760//760
            +f 760//760 766//766 767//767
            +f 768//768 762//762 761//761
            +f 761//761 767//767 768//768
            +f 769//769 763//763 762//762
            +f 762//762 768//768 769//769
            +f 627//627 764//764 624//624
            +f 624//624 579//579 627//627
            +f 629//629 765//765 764//764
            +f 764//764 627//627 629//629
            +f 631//631 766//766 765//765
            +f 765//765 629//629 631//631
            +f 633//633 767//767 766//766
            +f 766//766 631//631 633//633
            +f 635//635 768//768 767//767
            +f 767//767 633//633 635//635
            +f 637//637 769//769 768//768
            +f 768//768 635//635 637//637
            +f 770//770 771//771 772//772
            +f 773//773 772//772 771//771
            +f 774//774 770//770 775//775
            +f 772//772 775//775 770//770
            +f 776//776 777//777 774//774
            +f 774//774 775//775 776//776
            +f 778//778 779//779 776//776
            +f 777//777 776//776 779//779
            +f 780//780 781//781 778//778
            +f 779//779 778//778 781//781
            +f 782//782 783//783 780//780
            +f 781//781 780//780 783//783
            +f 772//772 773//773 784//784
            +f 785//785 784//784 773//773
            +f 775//775 772//772 786//786
            +f 784//784 786//786 772//772
            +f 776//776 775//775 787//787
            +f 786//786 787//787 775//775
            +f 788//788 778//778 776//776
            +f 776//776 787//787 788//788
            +f 789//789 780//780 788//788
            +f 778//778 788//788 780//780
            +f 790//790 782//782 789//789
            +f 780//780 789//789 782//782
            +f 784//784 785//785 791//791
            +f 792//792 791//791 785//785
            +f 786//786 784//784 793//793
            +f 791//791 793//793 784//784
            +f 787//787 786//786 794//794
            +f 793//793 794//794 786//786
            +f 795//795 788//788 787//787
            +f 787//787 794//794 795//795
            +f 796//796 789//789 795//795
            +f 788//788 795//795 789//789
            +f 797//797 790//790 796//796
            +f 789//789 796//796 790//790
            +f 791//791 792//792 798//798
            +f 799//799 798//798 792//792
            +f 793//793 791//791 800//800
            +f 798//798 800//800 791//791
            +f 794//794 793//793 801//801
            +f 800//800 801//801 793//793
            +f 802//802 795//795 794//794
            +f 794//794 801//801 802//802
            +f 803//803 796//796 802//802
            +f 795//795 802//802 796//796
            +f 804//804 797//797 803//803
            +f 796//796 803//803 797//797
            +f 798//798 799//799 805//805
            +f 806//806 805//805 799//799
            +f 800//800 798//798 807//807
            +f 805//805 807//807 798//798
            +f 801//801 800//800 808//808
            +f 807//807 808//808 800//800
            +f 809//809 802//802 801//801
            +f 801//801 808//808 809//809
            +f 810//810 803//803 809//809
            +f 802//802 809//809 803//803
            +f 811//811 804//804 810//810
            +f 803//803 810//810 804//804
            +f 805//805 806//806 812//812
            +f 813//813 812//812 806//806
            +f 807//807 805//805 814//814
            +f 812//812 814//814 805//805
            +f 815//815 808//808 814//814
            +f 807//807 814//814 808//808
            +f 816//816 809//809 815//815
            +f 808//808 815//815 809//809
            +f 817//817 810//810 816//816
            +f 809//809 816//816 810//810
            +f 818//818 811//811 817//817
            +f 810//810 817//817 811//811
            +f 819//819 820//820 812//812
            +f 812//812 813//813 819//819
            +f 820//820 821//821 814//814
            +f 814//814 812//812 820//820
            +f 822//822 815//815 814//814
            +f 814//814 821//821 822//822
            +f 823//823 816//816 815//815
            +f 815//815 822//822 823//823
            +f 824//824 817//817 816//816
            +f 816//816 823//823 824//824
            +f 825//825 818//818 817//817
            +f 817//817 824//824 825//825
            +f 826//826 827//827 820//820
            +f 820//820 819//819 826//826
            +f 827//827 828//828 821//821
            +f 821//821 820//820 827//827
            +f 828//828 829//829 822//822
            +f 822//822 821//821 828//828
            +f 830//830 823//823 829//829
            +f 822//822 829//829 823//823
            +f 831//831 824//824 823//823
            +f 823//823 830//830 831//831
            +f 832//832 825//825 824//824
            +f 824//824 831//831 832//832
            +f 833//833 834//834 827//827
            +f 827//827 826//826 833//833
            +f 834//834 835//835 828//828
            +f 828//828 827//827 834//834
            +f 835//835 836//836 829//829
            +f 829//829 828//828 835//835
            +f 837//837 830//830 836//836
            +f 829//829 836//836 830//830
            +f 838//838 831//831 830//830
            +f 830//830 837//837 838//838
            +f 839//839 832//832 831//831
            +f 831//831 838//838 839//839
            +f 840//840 841//841 834//834
            +f 834//834 833//833 840//840
            +f 841//841 842//842 835//835
            +f 835//835 834//834 841//841
            +f 842//842 843//843 836//836
            +f 836//836 835//835 842//842
            +f 844//844 837//837 843//843
            +f 836//836 843//843 837//837
            +f 845//845 838//838 837//837
            +f 837//837 844//844 845//845
            +f 846//846 839//839 838//838
            +f 838//838 845//845 846//846
            +f 847//847 848//848 841//841
            +f 841//841 840//840 847//847
            +f 848//848 849//849 842//842
            +f 842//842 841//841 848//848
            +f 849//849 850//850 843//843
            +f 843//843 842//842 849//849
            +f 851//851 844//844 850//850
            +f 843//843 850//850 844//844
            +f 852//852 845//845 844//844
            +f 844//844 851//851 852//852
            +f 853//853 846//846 845//845
            +f 845//845 852//852 853//853
            +f 771//771 770//770 848//848
            +f 848//848 847//847 771//771
            +f 770//770 774//774 849//849
            +f 849//849 848//848 770//770
            +f 777//777 850//850 774//774
            +f 849//849 774//774 850//850
            +f 779//779 851//851 850//850
            +f 850//850 777//777 779//779
            +f 781//781 852//852 851//851
            +f 851//851 779//779 781//781
            +f 783//783 853//853 852//852
            +f 852//852 781//781 783//783
            +f 854//854 855//855 782//782
            +f 783//783 782//782 855//855
            +f 856//856 857//857 855//855
            +f 855//855 854//854 856//856
            +f 858//858 859//859 857//857
            +f 857//857 856//856 858//858
            +f 860//860 861//861 859//859
            +f 859//859 858//858 860//860
            +f 862//862 863//863 861//861
            +f 861//861 860//860 862//862
            +f 864//864 865//865 863//863
            +f 863//863 862//862 864//864
            +f 866//866 854//854 782//782
            +f 782//782 790//790 866//866
            +f 867//867 856//856 854//854
            +f 854//854 866//866 867//867
            +f 868//868 858//858 856//856
            +f 856//856 867//867 868//868
            +f 869//869 860//860 858//858
            +f 858//858 868//868 869//869
            +f 870//870 862//862 860//860
            +f 860//860 869//869 870//870
            +f 871//871 864//864 870//870
            +f 862//862 870//870 864//864
            +f 872//872 866//866 790//790
            +f 790//790 797//797 872//872
            +f 873//873 867//867 866//866
            +f 866//866 872//872 873//873
            +f 874//874 868//868 867//867
            +f 867//867 873//873 874//874
            +f 875//875 869//869 874//874
            +f 868//868 874//874 869//869
            +f 876//876 870//870 875//875
            +f 869//869 875//875 870//870
            +f 877//877 871//871 876//876
            +f 870//870 876//876 871//871
            +f 878//878 872//872 797//797
            +f 797//797 804//804 878//878
            +f 879//879 873//873 872//872
            +f 872//872 878//878 879//879
            +f 880//880 874//874 873//873
            +f 873//873 879//879 880//880
            +f 881//881 875//875 880//880
            +f 874//874 880//880 875//875
            +f 882//882 876//876 881//881
            +f 875//875 881//881 876//876
            +f 883//883 877//877 882//882
            +f 876//876 882//882 877//877
            +f 884//884 878//878 804//804
            +f 804//804 811//811 884//884
            +f 885//885 879//879 878//878
            +f 878//878 884//884 885//885
            +f 886//886 880//880 879//879
            +f 879//879 885//885 886//886
            +f 887//887 881//881 880//880
            +f 880//880 886//886 887//887
            +f 888//888 882//882 881//881
            +f 881//881 887//887 888//888
            +f 889//889 883//883 888//888
            +f 882//882 888//888 883//883
            +f 890//890 884//884 811//811
            +f 811//811 818//818 890//890
            +f 891//891 885//885 884//884
            +f 884//884 890//890 891//891
            +f 892//892 886//886 885//885
            +f 885//885 891//891 892//892
            +f 893//893 887//887 886//886
            +f 886//886 892//892 893//893
            +f 894//894 888//888 887//887
            +f 887//887 893//893 894//894
            +f 895//895 889//889 888//888
            +f 888//888 894//894 895//895
            +f 896//896 890//890 825//825
            +f 818//818 825//825 890//890
            +f 897//897 891//891 896//896
            +f 890//890 896//896 891//891
            +f 898//898 892//892 897//897
            +f 891//891 897//897 892//892
            +f 899//899 893//893 898//898
            +f 892//892 898//898 893//893
            +f 900//900 894//894 899//899
            +f 893//893 899//899 894//894
            +f 901//901 895//895 900//900
            +f 894//894 900//900 895//895
            +f 902//902 896//896 832//832
            +f 825//825 832//832 896//896
            +f 903//903 897//897 902//902
            +f 896//896 902//902 897//897
            +f 904//904 898//898 903//903
            +f 897//897 903//903 898//898
            +f 905//905 899//899 904//904
            +f 898//898 904//904 899//899
            +f 906//906 900//900 905//905
            +f 899//899 905//905 900//900
            +f 907//907 901//901 900//900
            +f 900//900 906//906 907//907
            +f 908//908 902//902 839//839
            +f 832//832 839//839 902//902
            +f 909//909 903//903 908//908
            +f 902//902 908//908 903//903
            +f 910//910 904//904 909//909
            +f 903//903 909//909 904//904
            +f 911//911 905//905 904//904
            +f 904//904 910//910 911//911
            +f 912//912 906//906 905//905
            +f 905//905 911//911 912//912
            +f 913//913 907//907 906//906
            +f 906//906 912//912 913//913
            +f 914//914 908//908 846//846
            +f 839//839 846//846 908//908
            +f 915//915 909//909 914//914
            +f 908//908 914//914 909//909
            +f 916//916 910//910 915//915
            +f 909//909 915//915 910//910
            +f 917//917 911//911 910//910
            +f 910//910 916//916 917//917
            +f 918//918 912//912 911//911
            +f 911//911 917//917 918//918
            +f 919//919 913//913 912//912
            +f 912//912 918//918 919//919
            +f 920//920 914//914 853//853
            +f 846//846 853//853 914//914
            +f 921//921 915//915 920//920
            +f 914//914 920//920 915//915
            +f 922//922 916//916 921//921
            +f 915//915 921//921 916//916
            +f 923//923 917//917 922//922
            +f 916//916 922//922 917//917
            +f 924//924 918//918 923//923
            +f 917//917 923//923 918//918
            +f 925//925 919//919 918//918
            +f 918//918 924//924 925//925
            +f 855//855 920//920 853//853
            +f 853//853 783//783 855//855
            +f 857//857 921//921 855//855
            +f 920//920 855//855 921//921
            +f 859//859 922//922 857//857
            +f 921//921 857//857 922//922
            +f 861//861 923//923 859//859
            +f 922//922 859//859 923//923
            +f 863//863 924//924 861//861
            +f 923//923 861//861 924//924
            +f 865//865 925//925 863//863
            +f 924//924 863//863 925//925
            +f 926//926 927//927 928//928
            +f 928//928 929//929 926//926
            +f 929//929 928//928 930//930
            +f 930//930 931//931 929//929
            +f 931//931 930//930 932//932
            +f 932//932 933//933 931//931
            +f 933//933 932//932 934//934
            +f 934//934 935//935 933//933
            +f 935//935 934//934 936//936
            +f 936//936 937//937 935//935
            +f 937//937 936//936 938//938
            +f 939//939 938//938 936//936
            +f 940//940 941//941 927//927
            +f 928//928 927//927 941//941
            +f 928//928 941//941 942//942
            +f 942//942 930//930 928//928
            +f 930//930 942//942 943//943
            +f 943//943 932//932 930//930
            +f 932//932 943//943 944//944
            +f 944//944 934//934 932//932
            +f 934//934 944//944 936//936
            +f 945//945 936//936 944//944
            +f 936//936 945//945 939//939
            +f 946//946 939//939 945//945
            +f 947//947 948//948 940//940
            +f 941//941 940//940 948//948
            +f 941//941 948//948 949//949
            +f 949//949 942//942 941//941
            +f 942//942 949//949 943//943
            +f 950//950 943//943 949//949
            +f 943//943 950//950 944//944
            +f 951//951 944//944 950//950
            +f 944//944 951//951 945//945
            +f 952//952 945//945 951//951
            +f 945//945 952//952 946//946
            +f 953//953 946//946 952//952
            +f 954//954 955//955 947//947
            +f 948//948 947//947 955//955
            +f 948//948 955//955 956//956
            +f 956//956 949//949 948//948
            +f 949//949 956//956 950//950
            +f 957//957 950//950 956//956
            +f 950//950 957//957 951//951
            +f 958//958 951//951 957//957
            +f 951//951 958//958 952//952
            +f 959//959 952//952 958//958
            +f 952//952 959//959 953//953
            +f 960//960 953//953 959//959
            +f 954//954 961//961 962//962
            +f 962//962 955//955 954//954
            +f 955//955 962//962 956//956
            +f 963//963 956//956 962//962
            +f 956//956 963//963 957//957
            +f 964//964 957//957 963//963
            +f 957//957 964//964 958//958
            +f 965//965 958//958 964//964
            +f 958//958 965//965 959//959
            +f 966//966 959//959 965//965
            +f 959//959 966//966 960//960
            +f 967//967 960//960 966//966
            +f 961//961 968//968 962//962
            +f 969//969 962//962 968//968
            +f 962//962 969//969 963//963
            +f 970//970 963//963 969//969
            +f 963//963 970//970 964//964
            +f 971//971 964//964 970//970
            +f 964//964 971//971 965//965
            +f 972//972 965//965 971//971
            +f 965//965 972//972 966//966
            +f 973//973 966//966 972//972
            +f 966//966 973//973 967//967
            +f 974//974 967//967 973//973
            +f 968//968 975//975 976//976
            +f 976//976 969//969 968//968
            +f 969//969 976//976 977//977
            +f 977//977 970//970 969//969
            +f 970//970 977//977 978//978
            +f 978//978 971//971 970//970
            +f 971//971 978//978 979//979
            +f 979//979 972//972 971//971
            +f 972//972 979//979 980//980
            +f 980//980 973//973 972//972
            +f 973//973 980//980 981//981
            +f 981//981 974//974 973//973
            +f 975//975 982//982 976//976
            +f 983//983 976//976 982//982
            +f 976//976 983//983 984//984
            +f 984//984 977//977 976//976
            +f 977//977 984//984 985//985
            +f 985//985 978//978 977//977
            +f 978//978 985//985 986//986
            +f 986//986 979//979 978//978
            +f 979//979 986//986 987//987
            +f 987//987 980//980 979//979
            +f 980//980 987//987 988//988
            +f 988//988 981//981 980//980
            +f 983//983 982//982 989//989
            +f 989//989 990//990 983//983
            +f 983//983 990//990 984//984
            +f 991//991 984//984 990//990
            +f 984//984 991//991 992//992
            +f 992//992 985//985 984//984
            +f 985//985 992//992 993//993
            +f 993//993 986//986 985//985
            +f 986//986 993//993 994//994
            +f 994//994 987//987 986//986
            +f 987//987 994//994 995//995
            +f 995//995 988//988 987//987
            +f 990//990 989//989 996//996
            +f 996//996 997//997 990//990
            +f 990//990 997//997 991//991
            +f 998//998 991//991 997//997
            +f 991//991 998//998 999//999
            +f 999//999 992//992 991//991
            +f 992//992 999//999 1000//1000
            +f 1000//1000 993//993 992//992
            +f 993//993 1000//1000 1001//1001
            +f 1001//1001 994//994 993//993
            +f 994//994 1001//1001 1002//1002
            +f 1002//1002 995//995 994//994
            +f 997//997 996//996 1003//1003
            +f 1003//1003 1004//1004 997//997
            +f 997//997 1004//1004 998//998
            +f 1005//1005 998//998 1004//1004
            +f 998//998 1005//1005 999//999
            +f 1006//1006 999//999 1005//1005
            +f 999//999 1006//1006 1000//1000
            +f 1007//1007 1000//1000 1006//1006
            +f 1000//1000 1007//1007 1008//1008
            +f 1008//1008 1001//1001 1000//1000
            +f 1001//1001 1008//1008 1009//1009
            +f 1009//1009 1002//1002 1001//1001
            +f 1003//1003 926//926 1004//1004
            +f 929//929 1004//1004 926//926
            +f 1004//1004 929//929 1005//1005
            +f 931//931 1005//1005 929//929
            +f 1005//1005 931//931 1006//1006
            +f 933//933 1006//1006 931//931
            +f 1006//1006 933//933 1007//1007
            +f 935//935 1007//1007 933//933
            +f 1007//1007 935//935 1008//1008
            +f 937//937 1008//1008 935//935
            +f 1008//1008 937//937 938//938
            +f 938//938 1009//1009 1008//1008
            +f 938//938 939//939 1010//1010
            +f 1011//1011 1010//1010 939//939
            +f 1010//1010 1011//1011 1012//1012
            +f 1013//1013 1012//1012 1011//1011
            +f 1012//1012 1013//1013 1014//1014
            +f 1015//1015 1014//1014 1013//1013
            +f 1016//1016 1017//1017 1014//1014
            +f 1014//1014 1015//1015 1016//1016
            +f 1018//1018 1019//1019 1017//1017
            +f 1017//1017 1016//1016 1018//1018
            +f 1020//1020 1021//1021 1019//1019
            +f 1019//1019 1018//1018 1020//1020
            +f 939//939 946//946 1011//1011
            +f 1022//1022 1011//1011 946//946
            +f 1011//1011 1022//1022 1013//1013
            +f 1023//1023 1013//1013 1022//1022
            +f 1013//1013 1023//1023 1015//1015
            +f 1024//1024 1015//1015 1023//1023
            +f 1025//1025 1016//1016 1015//1015
            +f 1015//1015 1024//1024 1025//1025
            +f 1026//1026 1018//1018 1016//1016
            +f 1016//1016 1025//1025 1026//1026
            +f 1027//1027 1020//1020 1018//1018
            +f 1018//1018 1026//1026 1027//1027
            +f 946//946 953//953 1022//1022
            +f 1028//1028 1022//1022 953//953
            +f 1022//1022 1028//1028 1023//1023
            +f 1029//1029 1023//1023 1028//1028
            +f 1023//1023 1029//1029 1024//1024
            +f 1030//1030 1024//1024 1029//1029
            +f 1031//1031 1025//1025 1024//1024
            +f 1024//1024 1030//1030 1031//1031
            +f 1032//1032 1026//1026 1025//1025
            +f 1025//1025 1031//1031 1032//1032
            +f 1033//1033 1027//1027 1026//1026
            +f 1026//1026 1032//1032 1033//1033
            +f 953//953 960//960 1028//1028
            +f 1034//1034 1028//1028 960//960
            +f 1028//1028 1034//1034 1029//1029
            +f 1035//1035 1029//1029 1034//1034
            +f 1029//1029 1035//1035 1030//1030
            +f 1036//1036 1030//1030 1035//1035
            +f 1037//1037 1031//1031 1030//1030
            +f 1030//1030 1036//1036 1037//1037
            +f 1038//1038 1032//1032 1031//1031
            +f 1031//1031 1037//1037 1038//1038
            +f 1039//1039 1033//1033 1032//1032
            +f 1032//1032 1038//1038 1039//1039
            +f 960//960 967//967 1034//1034
            +f 1040//1040 1034//1034 967//967
            +f 1034//1034 1040//1040 1035//1035
            +f 1041//1041 1035//1035 1040//1040
            +f 1035//1035 1041//1041 1036//1036
            +f 1042//1042 1036//1036 1041//1041
            +f 1043//1043 1037//1037 1036//1036
            +f 1036//1036 1042//1042 1043//1043
            +f 1044//1044 1038//1038 1037//1037
            +f 1037//1037 1043//1043 1044//1044
            +f 1045//1045 1039//1039 1038//1038
            +f 1038//1038 1044//1044 1045//1045
            +f 967//967 974//974 1040//1040
            +f 1046//1046 1040//1040 974//974
            +f 1040//1040 1046//1046 1041//1041
            +f 1047//1047 1041//1041 1046//1046
            +f 1041//1041 1047//1047 1042//1042
            +f 1048//1048 1042//1042 1047//1047
            +f 1049//1049 1043//1043 1042//1042
            +f 1042//1042 1048//1048 1049//1049
            +f 1050//1050 1044//1044 1043//1043
            +f 1043//1043 1049//1049 1050//1050
            +f 1051//1051 1045//1045 1044//1044
            +f 1044//1044 1050//1050 1051//1051
            +f 974//974 981//981 1052//1052
            +f 1052//1052 1046//1046 974//974
            +f 1046//1046 1052//1052 1053//1053
            +f 1053//1053 1047//1047 1046//1046
            +f 1047//1047 1053//1053 1054//1054
            +f 1054//1054 1048//1048 1047//1047
            +f 1055//1055 1049//1049 1054//1054
            +f 1048//1048 1054//1054 1049//1049
            +f 1056//1056 1050//1050 1055//1055
            +f 1049//1049 1055//1055 1050//1050
            +f 1057//1057 1051//1051 1056//1056
            +f 1050//1050 1056//1056 1051//1051
            +f 981//981 988//988 1058//1058
            +f 1058//1058 1052//1052 981//981
            +f 1052//1052 1058//1058 1059//1059
            +f 1059//1059 1053//1053 1052//1052
            +f 1053//1053 1059//1059 1060//1060
            +f 1060//1060 1054//1054 1053//1053
            +f 1061//1061 1055//1055 1060//1060
            +f 1054//1054 1060//1060 1055//1055
            +f 1062//1062 1056//1056 1061//1061
            +f 1055//1055 1061//1061 1056//1056
            +f 1063//1063 1057//1057 1062//1062
            +f 1056//1056 1062//1062 1057//1057
            +f 988//988 995//995 1064//1064
            +f 1064//1064 1058//1058 988//988
            +f 1058//1058 1064//1064 1065//1065
            +f 1065//1065 1059//1059 1058//1058
            +f 1059//1059 1065//1065 1066//1066
            +f 1066//1066 1060//1060 1059//1059
            +f 1067//1067 1061//1061 1066//1066
            +f 1060//1060 1066//1066 1061//1061
            +f 1068//1068 1062//1062 1067//1067
            +f 1061//1061 1067//1067 1062//1062
            +f 1069//1069 1063//1063 1068//1068
            +f 1062//1062 1068//1068 1063//1063
            +f 995//995 1002//1002 1070//1070
            +f 1070//1070 1064//1064 995//995
            +f 1064//1064 1070//1070 1071//1071
            +f 1071//1071 1065//1065 1064//1064
            +f 1065//1065 1071//1071 1072//1072
            +f 1072//1072 1066//1066 1065//1065
            +f 1073//1073 1067//1067 1072//1072
            +f 1066//1066 1072//1072 1067//1067
            +f 1074//1074 1068//1068 1073//1073
            +f 1067//1067 1073//1073 1068//1068
            +f 1075//1075 1069//1069 1074//1074
            +f 1068//1068 1074//1074 1069//1069
            +f 1002//1002 1009//1009 1076//1076
            +f 1076//1076 1070//1070 1002//1002
            +f 1070//1070 1076//1076 1077//1077
            +f 1077//1077 1071//1071 1070//1070
            +f 1071//1071 1077//1077 1078//1078
            +f 1078//1078 1072//1072 1071//1071
            +f 1079//1079 1073//1073 1078//1078
            +f 1072//1072 1078//1078 1073//1073
            +f 1080//1080 1074//1074 1079//1079
            +f 1073//1073 1079//1079 1074//1074
            +f 1081//1081 1075//1075 1080//1080
            +f 1074//1074 1080//1080 1075//1075
            +f 1009//1009 938//938 1010//1010
            +f 1010//1010 1076//1076 1009//1009
            +f 1076//1076 1010//1010 1012//1012
            +f 1012//1012 1077//1077 1076//1076
            +f 1077//1077 1012//1012 1014//1014
            +f 1014//1014 1078//1078 1077//1077
            +f 1017//1017 1079//1079 1014//1014
            +f 1078//1078 1014//1014 1079//1079
            +f 1019//1019 1080//1080 1017//1017
            +f 1079//1079 1017//1017 1080//1080
            +f 1021//1021 1081//1081 1019//1019
            +f 1080//1080 1019//1019 1081//1081
            +f 1082//1082 1083//1083 1084//1084
            +f 1084//1084 1083//1083 1085//1085
            +f 1085//1085 1083//1083 1086//1086
            +f 1086//1086 1083//1083 1087//1087
            +f 1087//1087 1083//1083 1088//1088
            +f 1088//1088 1083//1083 1089//1089
            +f 1089//1089 1083//1083 1090//1090
            +f 1090//1090 1083//1083 1091//1091
            +f 1091//1091 1083//1083 1092//1092
            +f 1092//1092 1083//1083 1093//1093
            +f 1093//1093 1083//1083 1094//1094
            +f 1094//1094 1083//1083 1095//1095
            +f 1095//1095 1083//1083 1096//1096
            +f 1096//1096 1083//1083 1097//1097
            +f 1097//1097 1083//1083 1098//1098
            +f 1098//1098 1083//1083 1099//1099
            +f 1099//1099 1083//1083 1100//1100
            +f 1100//1100 1083//1083 1101//1101
            +f 1101//1101 1083//1083 1102//1102
            +f 1102//1102 1083//1083 1103//1103
            +f 1103//1103 1083//1083 1104//1104
            +f 1104//1104 1083//1083 1105//1105
            +f 1105//1105 1083//1083 1106//1106
            +f 1106//1106 1083//1083 1082//1082
            +f 1107//1107 1108//1108 1084//1084
            +f 1082//1082 1084//1084 1108//1108
            +f 1109//1109 1110//1110 1108//1108
            +f 1108//1108 1107//1107 1109//1109
            +f 1111//1111 1112//1112 1110//1110
            +f 1110//1110 1109//1109 1111//1111
            +f 1113//1113 1114//1114 1112//1112
            +f 1112//1112 1111//1111 1113//1113
            +f 1115//1115 1107//1107 1085//1085
            +f 1084//1084 1085//1085 1107//1107
            +f 1116//1116 1109//1109 1107//1107
            +f 1107//1107 1115//1115 1116//1116
            +f 1117//1117 1111//1111 1109//1109
            +f 1109//1109 1116//1116 1117//1117
            +f 1118//1118 1113//1113 1111//1111
            +f 1111//1111 1117//1117 1118//1118
            +f 1119//1119 1115//1115 1086//1086
            +f 1085//1085 1086//1086 1115//1115
            +f 1120//1120 1116//1116 1115//1115
            +f 1115//1115 1119//1119 1120//1120
            +f 1121//1121 1117//1117 1116//1116
            +f 1116//1116 1120//1120 1121//1121
            +f 1122//1122 1118//1118 1117//1117
            +f 1117//1117 1121//1121 1122//1122
            +f 1123//1123 1119//1119 1086//1086
            +f 1086//1086 1087//1087 1123//1123
            +f 1124//1124 1120//1120 1123//1123
            +f 1119//1119 1123//1123 1120//1120
            +f 1125//1125 1121//1121 1124//1124
            +f 1120//1120 1124//1124 1121//1121
            +f 1126//1126 1122//1122 1125//1125
            +f 1121//1121 1125//1125 1122//1122
            +f 1127//1127 1123//1123 1087//1087
            +f 1087//1087 1088//1088 1127//1127
            +f 1128//1128 1124//1124 1127//1127
            +f 1123//1123 1127//1127 1124//1124
            +f 1129//1129 1125//1125 1128//1128
            +f 1124//1124 1128//1128 1125//1125
            +f 1130//1130 1126//1126 1129//1129
            +f 1125//1125 1129//1129 1126//1126
            +f 1131//1131 1127//1127 1088//1088
            +f 1088//1088 1089//1089 1131//1131
            +f 1132//1132 1128//1128 1131//1131
            +f 1127//1127 1131//1131 1128//1128
            +f 1133//1133 1129//1129 1132//1132
            +f 1128//1128 1132//1132 1129//1129
            +f 1134//1134 1130//1130 1133//1133
            +f 1129//1129 1133//1133 1130//1130
            +f 1135//1135 1131//1131 1090//1090
            +f 1089//1089 1090//1090 1131//1131
            +f 1136//1136 1132//1132 1131//1131
            +f 1131//1131 1135//1135 1136//1136
            +f 1137//1137 1133//1133 1132//1132
            +f 1132//1132 1136//1136 1137//1137
            +f 1138//1138 1134//1134 1133//1133
            +f 1133//1133 1137//1137 1138//1138
            +f 1139//1139 1135//1135 1091//1091
            +f 1090//1090 1091//1091 1135//1135
            +f 1140//1140 1136//1136 1135//1135
            +f 1135//1135 1139//1139 1140//1140
            +f 1141//1141 1137//1137 1136//1136
            +f 1136//1136 1140//1140 1141//1141
            +f 1142//1142 1138//1138 1137//1137
            +f 1137//1137 1141//1141 1142//1142
            +f 1143//1143 1139//1139 1092//1092
            +f 1091//1091 1092//1092 1139//1139
            +f 1144//1144 1140//1140 1139//1139
            +f 1139//1139 1143//1143 1144//1144
            +f 1145//1145 1141//1141 1140//1140
            +f 1140//1140 1144//1144 1145//1145
            +f 1146//1146 1142//1142 1141//1141
            +f 1141//1141 1145//1145 1146//1146
            +f 1147//1147 1143//1143 1092//1092
            +f 1092//1092 1093//1093 1147//1147
            +f 1148//1148 1144//1144 1147//1147
            +f 1143//1143 1147//1147 1144//1144
            +f 1149//1149 1145//1145 1148//1148
            +f 1144//1144 1148//1148 1145//1145
            +f 1150//1150 1146//1146 1149//1149
            +f 1145//1145 1149//1149 1146//1146
            +f 1151//1151 1147//1147 1093//1093
            +f 1093//1093 1094//1094 1151//1151
            +f 1152//1152 1148//1148 1151//1151
            +f 1147//1147 1151//1151 1148//1148
            +f 1153//1153 1149//1149 1152//1152
            +f 1148//1148 1152//1152 1149//1149
            +f 1154//1154 1150//1150 1153//1153
            +f 1149//1149 1153//1153 1150//1150
            +f 1155//1155 1151//1151 1094//1094
            +f 1094//1094 1095//1095 1155//1155
            +f 1156//1156 1152//1152 1155//1155
            +f 1151//1151 1155//1155 1152//1152
            +f 1157//1157 1153//1153 1156//1156
            +f 1152//1152 1156//1156 1153//1153
            +f 1158//1158 1154//1154 1157//1157
            +f 1153//1153 1157//1157 1154//1154
            +f 1159//1159 1155//1155 1096//1096
            +f 1095//1095 1096//1096 1155//1155
            +f 1160//1160 1156//1156 1155//1155
            +f 1155//1155 1159//1159 1160//1160
            +f 1161//1161 1157//1157 1156//1156
            +f 1156//1156 1160//1160 1161//1161
            +f 1162//1162 1158//1158 1157//1157
            +f 1157//1157 1161//1161 1162//1162
            +f 1163//1163 1159//1159 1097//1097
            +f 1096//1096 1097//1097 1159//1159
            +f 1164//1164 1160//1160 1159//1159
            +f 1159//1159 1163//1163 1164//1164
            +f 1165//1165 1161//1161 1160//1160
            +f 1160//1160 1164//1164 1165//1165
            +f 1166//1166 1162//1162 1161//1161
            +f 1161//1161 1165//1165 1166//1166
            +f 1167//1167 1163//1163 1098//1098
            +f 1097//1097 1098//1098 1163//1163
            +f 1168//1168 1164//1164 1163//1163
            +f 1163//1163 1167//1167 1168//1168
            +f 1169//1169 1165//1165 1164//1164
            +f 1164//1164 1168//1168 1169//1169
            +f 1170//1170 1166//1166 1165//1165
            +f 1165//1165 1169//1169 1170//1170
            +f 1171//1171 1167//1167 1098//1098
            +f 1098//1098 1099//1099 1171//1171
            +f 1172//1172 1168//1168 1171//1171
            +f 1167//1167 1171//1171 1168//1168
            +f 1173//1173 1169//1169 1172//1172
            +f 1168//1168 1172//1172 1169//1169
            +f 1174//1174 1170//1170 1173//1173
            +f 1169//1169 1173//1173 1170//1170
            +f 1175//1175 1171//1171 1099//1099
            +f 1099//1099 1100//1100 1175//1175
            +f 1176//1176 1172//1172 1175//1175
            +f 1171//1171 1175//1175 1172//1172
            +f 1177//1177 1173//1173 1176//1176
            +f 1172//1172 1176//1176 1173//1173
            +f 1178//1178 1174//1174 1177//1177
            +f 1173//1173 1177//1177 1174//1174
            +f 1179//1179 1175//1175 1100//1100
            +f 1100//1100 1101//1101 1179//1179
            +f 1180//1180 1176//1176 1179//1179
            +f 1175//1175 1179//1179 1176//1176
            +f 1181//1181 1177//1177 1180//1180
            +f 1176//1176 1180//1180 1177//1177
            +f 1182//1182 1178//1178 1181//1181
            +f 1177//1177 1181//1181 1178//1178
            +f 1183//1183 1179//1179 1102//1102
            +f 1101//1101 1102//1102 1179//1179
            +f 1184//1184 1180//1180 1179//1179
            +f 1179//1179 1183//1183 1184//1184
            +f 1185//1185 1181//1181 1180//1180
            +f 1180//1180 1184//1184 1185//1185
            +f 1186//1186 1182//1182 1181//1181
            +f 1181//1181 1185//1185 1186//1186
            +f 1187//1187 1183//1183 1103//1103
            +f 1102//1102 1103//1103 1183//1183
            +f 1188//1188 1184//1184 1183//1183
            +f 1183//1183 1187//1187 1188//1188
            +f 1189//1189 1185//1185 1184//1184
            +f 1184//1184 1188//1188 1189//1189
            +f 1190//1190 1186//1186 1185//1185
            +f 1185//1185 1189//1189 1190//1190
            +f 1191//1191 1187//1187 1104//1104
            +f 1103//1103 1104//1104 1187//1187
            +f 1192//1192 1188//1188 1187//1187
            +f 1187//1187 1191//1191 1192//1192
            +f 1193//1193 1189//1189 1188//1188
            +f 1188//1188 1192//1192 1193//1193
            +f 1194//1194 1190//1190 1189//1189
            +f 1189//1189 1193//1193 1194//1194
            +f 1195//1195 1191//1191 1104//1104
            +f 1104//1104 1105//1105 1195//1195
            +f 1196//1196 1192//1192 1195//1195
            +f 1191//1191 1195//1195 1192//1192
            +f 1197//1197 1193//1193 1196//1196
            +f 1192//1192 1196//1196 1193//1193
            +f 1198//1198 1194//1194 1197//1197
            +f 1193//1193 1197//1197 1194//1194
            +f 1199//1199 1195//1195 1105//1105
            +f 1105//1105 1106//1106 1199//1199
            +f 1200//1200 1196//1196 1199//1199
            +f 1195//1195 1199//1199 1196//1196
            +f 1201//1201 1197//1197 1200//1200
            +f 1196//1196 1200//1200 1197//1197
            +f 1202//1202 1198//1198 1201//1201
            +f 1197//1197 1201//1201 1198//1198
            +f 1108//1108 1199//1199 1106//1106
            +f 1106//1106 1082//1082 1108//1108
            +f 1110//1110 1200//1200 1108//1108
            +f 1199//1199 1108//1108 1200//1200
            +f 1112//1112 1201//1201 1110//1110
            +f 1200//1200 1110//1110 1201//1201
            +f 1114//1114 1202//1202 1112//1112
            +f 1201//1201 1112//1112 1202//1202
            diff --git a/dist/hi/reference/assets/test.txt b/dist/hi/reference/assets/test.txt
            new file mode 100644
            index 0000000000..9dc2445af3
            --- /dev/null
            +++ b/dist/hi/reference/assets/test.txt
            @@ -0,0 +1,6 @@
            +I am a cat
            +I like apples
            +I have three feet
            +I like my nose
            +I smell like butter
            +I talk like an orange
            \ No newline at end of file
            diff --git a/dist/hi/reference/assets/transformation-matrix.png b/dist/hi/reference/assets/transformation-matrix.png
            new file mode 100644
            index 0000000000..0d42542922
            Binary files /dev/null and b/dist/hi/reference/assets/transformation-matrix.png differ
            diff --git a/dist/hi/reference/data.json b/dist/hi/reference/data.json
            new file mode 100644
            index 0000000000..16f3ad430e
            --- /dev/null
            +++ b/dist/hi/reference/data.json
            @@ -0,0 +1,30598 @@
            +{
            +    "project": {
            +        "name": "p5",
            +        "description": "[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)",
            +        "version": "1.4.1",
            +        "url": "https://github.com/processing/p5.js#readme"
            +    },
            +    "files": {
            +        "src/accessibility/color_namer.js": {
            +            "name": "src/accessibility/color_namer.js",
            +            "modules": {
            +                "Environment": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/describe.js": {
            +            "name": "src/accessibility/describe.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/gridOutput.js": {
            +            "name": "src/accessibility/gridOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/outputs.js": {
            +            "name": "src/accessibility/outputs.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/textOutput.js": {
            +            "name": "src/accessibility/textOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/color_conversion.js": {
            +            "name": "src/color/color_conversion.js",
            +            "modules": {
            +                "Color Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/creating_reading.js": {
            +            "name": "src/color/creating_reading.js",
            +            "modules": {
            +                "Creating & Reading": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/p5.Color.js": {
            +            "name": "src/color/p5.Color.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/setting.js": {
            +            "name": "src/color/setting.js",
            +            "modules": {
            +                "Setting": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/fes_core.js": {
            +            "name": "src/core/friendly_errors/fes_core.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/file_errors.js": {
            +            "name": "src/core/friendly_errors/file_errors.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/sketch_reader.js": {
            +            "name": "src/core/friendly_errors/sketch_reader.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/stacktrace.js": {
            +            "name": "src/core/friendly_errors/stacktrace.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/validate_params.js": {
            +            "name": "src/core/friendly_errors/validate_params.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/2d_primitives.js": {
            +            "name": "src/core/shape/2d_primitives.js",
            +            "modules": {
            +                "2D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/attributes.js": {
            +            "name": "src/core/shape/attributes.js",
            +            "modules": {
            +                "Attributes": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/curves.js": {
            +            "name": "src/core/shape/curves.js",
            +            "modules": {
            +                "Curves": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/vertex.js": {
            +            "name": "src/core/shape/vertex.js",
            +            "modules": {
            +                "Vertex": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/constants.js": {
            +            "name": "src/core/constants.js",
            +            "modules": {
            +                "Constants": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/environment.js": {
            +            "name": "src/core/environment.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/helpers.js": {
            +            "name": "src/core/helpers.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/init.js": {
            +            "name": "src/core/init.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/internationalization.js": {
            +            "name": "src/core/internationalization.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/legacy.js": {
            +            "name": "src/core/legacy.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/main.js": {
            +            "name": "src/core/main.js",
            +            "modules": {
            +                "Structure": 1
            +            },
            +            "classes": {
            +                "p5": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Element.js": {
            +            "name": "src/core/p5.Element.js",
            +            "modules": {
            +                "DOM": 1
            +            },
            +            "classes": {
            +                "p5.Element": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Graphics.js": {
            +            "name": "src/core/p5.Graphics.js",
            +            "modules": {
            +                "Rendering": 1
            +            },
            +            "classes": {
            +                "p5.Graphics": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer.js": {
            +            "name": "src/core/p5.Renderer.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer2D.js": {
            +            "name": "src/core/p5.Renderer2D.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/reference.js": {
            +            "name": "src/core/reference.js",
            +            "modules": {
            +                "Foundation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/rendering.js": {
            +            "name": "src/core/rendering.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shim.js": {
            +            "name": "src/core/shim.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/structure.js": {
            +            "name": "src/core/structure.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/transform.js": {
            +            "name": "src/core/transform.js",
            +            "modules": {
            +                "Transform": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/local_storage.js": {
            +            "name": "src/data/local_storage.js",
            +            "modules": {
            +                "LocalStorage": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/p5.TypedDict.js": {
            +            "name": "src/data/p5.TypedDict.js",
            +            "modules": {
            +                "Dictionary": 1
            +            },
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/dom/dom.js": {
            +            "name": "src/dom/dom.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/acceleration.js": {
            +            "name": "src/events/acceleration.js",
            +            "modules": {
            +                "Acceleration": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/keyboard.js": {
            +            "name": "src/events/keyboard.js",
            +            "modules": {
            +                "Keyboard": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/mouse.js": {
            +            "name": "src/events/mouse.js",
            +            "modules": {
            +                "Mouse": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/touch.js": {
            +            "name": "src/events/touch.js",
            +            "modules": {
            +                "Touch": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/filters.js": {
            +            "name": "src/image/filters.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/image.js": {
            +            "name": "src/image/image.js",
            +            "modules": {
            +                "Image": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/loading_displaying.js": {
            +            "name": "src/image/loading_displaying.js",
            +            "modules": {
            +                "Loading & Displaying": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/p5.Image.js": {
            +            "name": "src/image/p5.Image.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/pixels.js": {
            +            "name": "src/image/pixels.js",
            +            "modules": {
            +                "Pixels": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/files.js": {
            +            "name": "src/io/files.js",
            +            "modules": {
            +                "Input": 1,
            +                "Output": 1
            +            },
            +            "classes": {
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/p5.Table.js": {
            +            "name": "src/io/p5.Table.js",
            +            "modules": {
            +                "Table": 1
            +            },
            +            "classes": {
            +                "p5.Table": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.TableRow.js": {
            +            "name": "src/io/p5.TableRow.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.XML.js": {
            +            "name": "src/io/p5.XML.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/calculation.js": {
            +            "name": "src/math/calculation.js",
            +            "modules": {
            +                "Calculation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/math.js": {
            +            "name": "src/math/math.js",
            +            "modules": {
            +                "Vector": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/noise.js": {
            +            "name": "src/math/noise.js",
            +            "modules": {
            +                "Noise": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/p5.Vector.js": {
            +            "name": "src/math/p5.Vector.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/random.js": {
            +            "name": "src/math/random.js",
            +            "modules": {
            +                "Random": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/trigonometry.js": {
            +            "name": "src/math/trigonometry.js",
            +            "modules": {
            +                "Trigonometry": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/attributes.js": {
            +            "name": "src/typography/attributes.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/loading_displaying.js": {
            +            "name": "src/typography/loading_displaying.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/p5.Font.js": {
            +            "name": "src/typography/p5.Font.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/utilities/array_functions.js": {
            +            "name": "src/utilities/array_functions.js",
            +            "modules": {
            +                "Array Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/conversion.js": {
            +            "name": "src/utilities/conversion.js",
            +            "modules": {
            +                "Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/string_functions.js": {
            +            "name": "src/utilities/string_functions.js",
            +            "modules": {
            +                "String Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/time_date.js": {
            +            "name": "src/utilities/time_date.js",
            +            "modules": {
            +                "Time & Date": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/3d_primitives.js": {
            +            "name": "src/webgl/3d_primitives.js",
            +            "modules": {
            +                "3D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/interaction.js": {
            +            "name": "src/webgl/interaction.js",
            +            "modules": {
            +                "Interaction": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/light.js": {
            +            "name": "src/webgl/light.js",
            +            "modules": {
            +                "Lights": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/loading.js": {
            +            "name": "src/webgl/loading.js",
            +            "modules": {
            +                "3D Models": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/material.js": {
            +            "name": "src/webgl/material.js",
            +            "modules": {
            +                "Material": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Camera.js": {
            +            "name": "src/webgl/p5.Camera.js",
            +            "modules": {
            +                "Camera": 1
            +            },
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Geometry.js": {
            +            "name": "src/webgl/p5.Geometry.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Matrix.js": {
            +            "name": "src/webgl/p5.Matrix.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Matrix": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RenderBuffer.js": {
            +            "name": "src/webgl/p5.RenderBuffer.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Immediate.js": {
            +            "name": "src/webgl/p5.RendererGL.Immediate.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Retained.js": {
            +            "name": "src/webgl/p5.RendererGL.Retained.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.js": {
            +            "name": "src/webgl/p5.RendererGL.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.RendererGL": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Shader.js": {
            +            "name": "src/webgl/p5.Shader.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Shader": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Texture.js": {
            +            "name": "src/webgl/p5.Texture.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/text.js": {
            +            "name": "src/webgl/text.js",
            +            "modules": {},
            +            "classes": {
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.js": {
            +            "name": "lib/addons/p5.sound.js",
            +            "modules": {
            +                "p5.sound": 1
            +            },
            +            "classes": {
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.min.js": {
            +            "name": "lib/addons/p5.sound.min.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        }
            +    },
            +    "modules": {
            +        "Environment": {
            +            "name": "Environment",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Environment",
            +            "file": "src/accessibility/color_namer.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Color": {
            +            "name": "Color",
            +            "submodules": {
            +                "Color Conversion": 1,
            +                "Creating & Reading": 1,
            +                "Setting": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/color/p5.Color.js",
            +            "line": 14
            +        },
            +        "Color Conversion": {
            +            "name": "Color Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/color_conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Creating & Reading": {
            +            "name": "Creating & Reading",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ],
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"
            +        },
            +        "Setting": {
            +            "name": "Setting",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/setting.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Shape": {
            +            "name": "Shape",
            +            "submodules": {
            +                "2D Primitives": 1,
            +                "Curves": 1,
            +                "Vertex": 1,
            +                "3D Primitives": 1,
            +                "3D Models": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1,
            +                "p5.Matrix": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/p5.Matrix.js",
            +            "line": 19
            +        },
            +        "2D Primitives": {
            +            "name": "2D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Attributes": {
            +            "name": "Attributes",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/core/shape/attributes.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Curves": {
            +            "name": "Curves",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/curves.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vertex": {
            +            "name": "Vertex",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Constants": {
            +            "name": "Constants",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Constants",
            +            "file": "src/core/constants.js",
            +            "line": 1
            +        },
            +        "Structure": {
            +            "name": "Structure",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "IO",
            +            "file": "src/core/main.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ]
            +        },
            +        "DOM": {
            +            "name": "DOM",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Element": 1,
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "DOM",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n",
            +            "requires": [
            +                "p5"
            +            ]
            +        },
            +        "Rendering": {
            +            "name": "Rendering",
            +            "submodules": {
            +                "undefined": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.RendererGL": 1,
            +                "p5.Graphics": 1,
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Rendering",
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 603,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"
            +        },
            +        "Foundation": {
            +            "name": "Foundation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {},
            +            "module": "Foundation",
            +            "file": "src/core/reference.js",
            +            "line": 1
            +        },
            +        "Transform": {
            +            "name": "Transform",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Transform",
            +            "file": "src/core/transform.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Data": {
            +            "name": "Data",
            +            "submodules": {
            +                "LocalStorage": 1,
            +                "Dictionary": 1,
            +                "Array Functions": 1,
            +                "Conversion": 1,
            +                "String Functions": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.TypedDict": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410
            +        },
            +        "LocalStorage": {
            +            "name": "LocalStorage",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/local_storage.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for working with local storage"
            +            ]
            +        },
            +        "Dictionary": {
            +            "name": "Dictionary",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."
            +            ],
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"
            +        },
            +        "Events": {
            +            "name": "Events",
            +            "submodules": {
            +                "Acceleration": 1,
            +                "Keyboard": 1,
            +                "Mouse": 1,
            +                "Touch": 1
            +            },
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "Acceleration": {
            +            "name": "Acceleration",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/acceleration.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Keyboard": {
            +            "name": "Keyboard",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/keyboard.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Mouse": {
            +            "name": "Mouse",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/mouse.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Touch": {
            +            "name": "Touch",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/touch.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Image": {
            +            "name": "Image",
            +            "submodules": {
            +                "Pixels": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Image",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"
            +        },
            +        "Loading & Displaying": {
            +            "name": "Loading & Displaying",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"
            +        },
            +        "Pixels": {
            +            "name": "Pixels",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Image",
            +            "namespace": "",
            +            "file": "src/image/pixels.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "IO": {
            +            "name": "IO",
            +            "submodules": {
            +                "Structure": 1,
            +                "Input": 1,
            +                "Output": 1,
            +                "Table": 1,
            +                "Time & Date": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1,
            +                "p5.Table": 1,
            +                "p5.TableRow": 1,
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/io/p5.XML.js",
            +            "line": 9
            +        },
            +        "Input": {
            +            "name": "Input",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"
            +        },
            +        "Output": {
            +            "name": "Output",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"
            +        },
            +        "Table": {
            +            "name": "Table",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Table": 1,
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"
            +        },
            +        "Math": {
            +            "name": "Math",
            +            "submodules": {
            +                "Calculation": 1,
            +                "Vector": 1,
            +                "Noise": 1,
            +                "Random": 1,
            +                "Trigonometry": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10
            +        },
            +        "Calculation": {
            +            "name": "Calculation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/calculation.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vector": {
            +            "name": "Vector",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"
            +        },
            +        "Noise": {
            +            "name": "Noise",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/noise.js",
            +            "line": 14,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Random": {
            +            "name": "Random",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/random.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Trigonometry": {
            +            "name": "Trigonometry",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/trigonometry.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Typography": {
            +            "name": "Typography",
            +            "submodules": {
            +                "Attributes": 1,
            +                "Loading & Displaying": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13
            +        },
            +        "Array Functions": {
            +            "name": "Array Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/array_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Conversion": {
            +            "name": "Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "String Functions": {
            +            "name": "String Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/string_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Time & Date": {
            +            "name": "Time & Date",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/utilities/time_date.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Primitives": {
            +            "name": "3D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ],
            +            "description": "<p>p5 Geometry class</p>\n"
            +        },
            +        "3D": {
            +            "name": "3D",
            +            "submodules": {
            +                "Interaction": 1,
            +                "Lights": 1,
            +                "Material": 1,
            +                "Camera": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1,
            +                "p5.Shader": 1,
            +                "p5.Texture": 1,
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/text.js",
            +            "line": 260
            +        },
            +        "Interaction": {
            +            "name": "Interaction",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/interaction.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Lights": {
            +            "name": "Lights",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/light.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Models": {
            +            "name": "3D Models",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/loading.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ]
            +        },
            +        "Material": {
            +            "name": "Material",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Shader": 1,
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Texture.js",
            +            "line": 12,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the p5.Shader class</p>\n"
            +        },
            +        "Camera": {
            +            "name": "Camera",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.sound": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {},
            +            "module": "p5.sound",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>",
            +            "tag": "main",
            +            "itemtype": "main"
            +        }
            +    },
            +    "classes": {
            +        "p5": {
            +            "name": "p5",
            +            "shortname": "p5",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/core/main.js",
            +            "line": 13,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>element to attach canvas to</p>\n",
            +                    "type": "HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a p5 instance",
            +                "type": "P5"
            +            }
            +        },
            +        "p5.Color": {
            +            "name": "p5.Color",
            +            "shortname": "p5.Color",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Element": {
            +            "name": "p5.Element",
            +            "shortname": "p5.Element",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/core/p5.Element.js",
            +            "line": 9,
            +            "description": "<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Graphics": {
            +            "name": "p5.Graphics",
            +            "shortname": "p5.Graphics",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 10,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>the renderer to use, either P2D or WEBGL</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Renderer": {
            +            "name": "p5.Renderer",
            +            "shortname": "p5.Renderer",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 10,
            +            "description": "<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isMainCanvas",
            +                    "description": "<p>whether we're using it as main canvas</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "JSON": {
            +            "name": "JSON",
            +            "shortname": "JSON",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "console": {
            +            "name": "console",
            +            "shortname": "console",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "p5.TypedDict": {
            +            "name": "p5.TypedDict",
            +            "shortname": "p5.TypedDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 82,
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.StringDict": {
            +            "name": "p5.StringDict",
            +            "shortname": "p5.StringDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 394,
            +            "description": "<p>A simple Dictionary class for Strings.</p>\n",
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.NumberDict": {
            +            "name": "p5.NumberDict",
            +            "shortname": "p5.NumberDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "description": "<p>A simple Dictionary class for Numbers.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.MediaElement": {
            +            "name": "p5.MediaElement",
            +            "shortname": "p5.MediaElement",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 2377,
            +            "description": "<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.File": {
            +            "name": "p5.File",
            +            "shortname": "p5.File",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>File that is wrapped</p>\n",
            +                    "type": "File"
            +                }
            +            ]
            +        },
            +        "p5.Image": {
            +            "name": "p5.Image",
            +            "shortname": "p5.Image",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Image",
            +            "submodule": "Image",
            +            "namespace": "",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"
            +            ],
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ]
            +        },
            +        "p5.PrintWriter": {
            +            "name": "p5.PrintWriter",
            +            "shortname": "p5.PrintWriter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Table": {
            +            "name": "p5.Table",
            +            "shortname": "p5.Table",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.Table.js",
            +            "line": 33,
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "rows",
            +                    "description": "<p>An array of p5.TableRow objects</p>\n",
            +                    "type": "p5.TableRow[]",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TableRow": {
            +            "name": "p5.TableRow",
            +            "shortname": "p5.TableRow",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "description": "<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>comma separated values (csv) by default</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.XML": {
            +            "name": "p5.XML",
            +            "shortname": "p5.XML",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Input",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed"
            +        },
            +        "p5.Vector": {
            +            "name": "p5.Vector",
            +            "shortname": "p5.Vector",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "2 white ellipses. One center-left the other bottom right and off canvas"
            +        },
            +        "p5.Font": {
            +            "name": "p5.Font",
            +            "shortname": "p5.Font",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "description": "<p>Base class for font handling</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Camera": {
            +            "name": "p5.Camera",
            +            "shortname": "p5.Camera",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Camera",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n",
            +            "params": [
            +                {
            +                    "name": "rendererGL",
            +                    "description": "<p>instance of WebGL renderer</p>\n",
            +                    "type": "RendererGL"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes."
            +        },
            +        "p5.Geometry": {
            +            "name": "p5.Geometry",
            +            "shortname": "p5.Geometry",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Shape",
            +            "submodule": "3D Primitives",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "description": "<p>p5 Geometry class</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of vertices along the x-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of vertices along the y-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call upon object instantiation.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Shader": {
            +            "name": "p5.Shader",
            +            "shortname": "p5.Shader",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Material",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 11,
            +            "description": "<p>Shader class for WEBGL Mode</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n",
            +                    "type": "p5.RendererGL"
            +                },
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader (as a string)</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader (as a string)</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "shortname": "p5.sound",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": ""
            +        },
            +        "p5.SoundFile": {
            +            "name": "p5.SoundFile",
            +            "shortname": "p5.SoundFile",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1405,
            +            "description": "<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoadingCallback",
            +                    "description": "<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"
            +            ]
            +        },
            +        "p5.Amplitude": {
            +            "name": "p5.Amplitude",
            +            "shortname": "p5.Amplitude",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3022,
            +            "description": "<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.FFT": {
            +            "name": "p5.FFT",
            +            "shortname": "p5.FFT",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3347,
            +            "description": "<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Oscillator": {
            +            "name": "p5.Oscillator",
            +            "shortname": "p5.Oscillator",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4060,
            +            "description": "<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>frequency defaults to 440Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"
            +            ]
            +        },
            +        "p5.SinOsc": {
            +            "name": "p5.SinOsc",
            +            "shortname": "p5.SinOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4602,
            +            "description": "<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TriOsc": {
            +            "name": "p5.TriOsc",
            +            "shortname": "p5.TriOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4629,
            +            "description": "<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SawOsc": {
            +            "name": "p5.SawOsc",
            +            "shortname": "p5.SawOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4656,
            +            "description": "<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SqrOsc": {
            +            "name": "p5.SqrOsc",
            +            "shortname": "p5.SqrOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4683,
            +            "description": "<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Envelope": {
            +            "name": "p5.Envelope",
            +            "shortname": "p5.Envelope",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4721,
            +            "description": "<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Noise": {
            +            "name": "p5.Noise",
            +            "shortname": "p5.Noise",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5620,
            +            "description": "<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.Pulse": {
            +            "name": "p5.Pulse",
            +            "shortname": "p5.Pulse",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5779,
            +            "description": "<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in oscillations per second (Hz)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioIn": {
            +            "name": "p5.AudioIn",
            +            "shortname": "p5.AudioIn",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6015,
            +            "description": "<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Effect": {
            +            "name": "p5.Effect",
            +            "shortname": "p5.Effect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6423,
            +            "description": "<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "ac",
            +                    "description": "<p>Reference to the audio context of the p5 object</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "input",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "output",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "_drywet",
            +                    "description": "<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "wet",
            +                    "description": "<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Filter": {
            +            "name": "p5.Filter",
            +            "shortname": "p5.Filter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6628,
            +            "description": "<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.LowPass": {
            +            "name": "p5.LowPass",
            +            "shortname": "p5.LowPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6914,
            +            "description": "<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.HighPass": {
            +            "name": "p5.HighPass",
            +            "shortname": "p5.HighPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6938,
            +            "description": "<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.BandPass": {
            +            "name": "p5.BandPass",
            +            "shortname": "p5.BandPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6962,
            +            "description": "<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.EQ": {
            +            "name": "p5.EQ",
            +            "shortname": "p5.EQ",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7105,
            +            "description": "<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect",
            +            "params": [
            +                {
            +                    "name": "_eqsize",
            +                    "description": "<p>Constructor will accept 3 or 8, defaults to 3</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "p5.EQ object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Panner3D": {
            +            "name": "p5.Panner3D",
            +            "shortname": "p5.Panner3D",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7602,
            +            "description": "<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Delay": {
            +            "name": "p5.Delay",
            +            "shortname": "p5.Delay",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7926,
            +            "description": "<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Reverb": {
            +            "name": "p5.Reverb",
            +            "shortname": "p5.Reverb",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8308,
            +            "description": "<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Convolver": {
            +            "name": "p5.Convolver",
            +            "shortname": "p5.Convolver",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8549,
            +            "description": "<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when loading succeeds</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Phrase": {
            +            "name": "p5.Phrase",
            +            "shortname": "p5.Phrase",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9103,
            +            "description": "<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>Name so that you can access the Phrase.</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Part": {
            +            "name": "p5.Part",
            +            "shortname": "p5.Part",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9185,
            +            "description": "<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "steps",
            +                    "description": "<p>Steps in the part</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tatums",
            +                    "description": "<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Score": {
            +            "name": "p5.Score",
            +            "shortname": "p5.Score",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9493,
            +            "description": "<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "parts",
            +                    "description": "<p>One or multiple parts, to be played in sequence.</p>\n",
            +                    "type": "p5.Part",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ]
            +        },
            +        "p5.SoundLoop": {
            +            "name": "p5.SoundLoop",
            +            "shortname": "p5.SoundLoop",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9673,
            +            "description": "<p>SoundLoop</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>this function will be called on each iteration of theloop</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "interval",
            +                    "description": "<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n",
            +                    "type": "Number|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Compressor": {
            +            "name": "p5.Compressor",
            +            "shortname": "p5.Compressor",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10036,
            +            "description": "<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect"
            +        },
            +        "p5.PeakDetect": {
            +            "name": "p5.PeakDetect",
            +            "shortname": "p5.PeakDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10312,
            +            "description": "<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq1",
            +                    "description": "<p>lowFrequency - defaults to 20Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "freq2",
            +                    "description": "<p>highFrequency - defaults to 20000 Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "framesPerPeak",
            +                    "description": "<p>Defaults to 20.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.SoundRecorder": {
            +            "name": "p5.SoundRecorder",
            +            "shortname": "p5.SoundRecorder",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10559,
            +            "description": "<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"
            +            ]
            +        },
            +        "p5.Distortion": {
            +            "name": "p5.Distortion",
            +            "shortname": "p5.Distortion",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10816,
            +            "description": "<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ]
            +        },
            +        "p5.Gain": {
            +            "name": "p5.Gain",
            +            "shortname": "p5.Gain",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10973,
            +            "description": "<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioVoice": {
            +            "name": "p5.AudioVoice",
            +            "shortname": "p5.AudioVoice",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11149,
            +            "description": "<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.MonoSynth": {
            +            "name": "p5.MonoSynth",
            +            "shortname": "p5.MonoSynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11247,
            +            "description": "<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.OnsetDetect": {
            +            "name": "p5.OnsetDetect",
            +            "shortname": "p5.OnsetDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11624,
            +            "description": "<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freqLow",
            +                    "description": "<p>Low frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "freqHigh",
            +                    "description": "<p>High frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Function to call when an onset is detected</p>\n",
            +                    "type": "Function"
            +                }
            +            ]
            +        },
            +        "p5.PolySynth": {
            +            "name": "p5.PolySynth",
            +            "shortname": "p5.PolySynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "synthVoice",
            +                    "description": "<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "maxVoices",
            +                    "description": "<p>Number of voices, defaults to 8;</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ]
            +        }
            +    },
            +    "elements": {},
            +    "classitems": [
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 18,
            +            "description": "<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describe",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the canvas</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 114,
            +            "description": "<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describeElement",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 10,
            +            "description": "<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "textOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 88,
            +            "description": "<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "gridOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 8,
            +            "description": "<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 19,
            +            "description": "<p>Convert an HSBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 45,
            +            "description": "<p>Convert an HSBA array to RGBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 100,
            +            "description": "<p>Convert an HSLA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 123,
            +            "description": "<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 187,
            +            "description": "<p>Convert an RGBA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 226,
            +            "description": "<p>Convert an RGBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 16,
            +            "description": "<p>Extracts the alpha value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "alpha",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the alpha value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 43,
            +            "description": "<p>Extracts the blue value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "blue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the blue value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 69,
            +            "description": "<p>Extracts the HSB brightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "brightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the brightness value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 113,
            +            "description": "<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n",
            +            "itemtype": "method",
            +            "name": "color",
            +            "return": {
            +                "description": "resulting color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "overloads": [
            +                {
            +                    "line": 113,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "resulting color",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 257,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 269,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 282,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 297,
            +            "description": "<p>Extracts the green value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "green",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the green value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 325,
            +            "description": "<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n",
            +            "itemtype": "method",
            +            "name": "hue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the hue",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 359,
            +            "description": "<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerpColor",
            +            "params": [
            +                {
            +                    "name": "c1",
            +                    "description": "<p>interpolate from this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "c2",
            +                    "description": "<p>interpolate to this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "interpolated color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 449,
            +            "description": "<p>Extracts the HSL lightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "lightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the lightness",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 478,
            +            "description": "<p>Extracts the red value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "red",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the red value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 517,
            +            "description": "<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n",
            +            "itemtype": "method",
            +            "name": "saturation",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the saturation value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 51,
            +            "description": "<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "params": [
            +                {
            +                    "name": "format",
            +                    "description": "<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the formatted string",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 254,
            +            "description": "<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRed",
            +            "params": [
            +                {
            +                    "name": "red",
            +                    "description": "<p>the new red value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 281,
            +            "description": "<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setGreen",
            +            "params": [
            +                {
            +                    "name": "green",
            +                    "description": "<p>the new green value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 304,
            +            "description": "<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBlue",
            +            "params": [
            +                {
            +                    "name": "blue",
            +                    "description": "<p>the new blue value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 327,
            +            "description": "<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAlpha",
            +            "params": [
            +                {
            +                    "name": "alpha",
            +                    "description": "<p>the new alpha value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 396,
            +            "description": "<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 427,
            +            "description": "<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 446,
            +            "description": "<p>CSS named colors.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 600,
            +            "description": "<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 613,
            +            "description": "<p>Full color string patterns. The capture groups are necessary.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 960,
            +            "description": "<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 13,
            +            "description": "<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n",
            +            "itemtype": "method",
            +            "name": "background",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "colorstring",
            +                            "description": "<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 140,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>specifies a value between white and black</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 147,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current color\n                       mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 159,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 166,
            +                    "params": [
            +                        {
            +                            "name": "image",
            +                            "description": "<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 179,
            +            "description": "<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"
            +            ],
            +            "params": [
            +                {
            +                    "name": "r",
            +                    "description": "<p>normalized red val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "g",
            +                    "description": "<p>normalized green val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>normalized blue val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>normalized alpha val.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 229,
            +            "description": "<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n",
            +            "itemtype": "method",
            +            "name": "colorMode",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 229,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>range for all values</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 306,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max1",
            +                            "description": "<p>range for the red or hue depending on the\n                             current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max2",
            +                            "description": "<p>range for the green or saturation depending\n                             on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max3",
            +                            "description": "<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "maxA",
            +                            "description": "<p>range for the alpha</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 350,
            +            "description": "<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n",
            +            "itemtype": "method",
            +            "name": "fill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 350,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 475,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 488,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 495,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the fill color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 507,
            +            "description": "<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noFill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 547,
            +            "description": "<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noStroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 585,
            +            "description": "<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n",
            +            "itemtype": "method",
            +            "name": "stroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 585,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 722,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 728,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 735,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 742,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the stroke color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 755,
            +            "description": "<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n",
            +            "itemtype": "method",
            +            "name": "erase",
            +            "params": [
            +                {
            +                    "name": "strengthFill",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "strengthStroke",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 836,
            +            "description": "<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "noErase",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis is the main file for the Friendly Error System (FES)",
            +                "containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters",
            +                "(2) _friendlyFileLoadError",
            +                "(3) _friendlyError",
            +                "(4) helpForMisusedAtTopLevelCode",
            +                "or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this",
            +                "there's also a file stacktrace.js",
            +                "which contains the code\nto parse the error stack",
            +                "borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions",
            +                "including the call\nsequence of each function",
            +                "please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 915,
            +            "description": "<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n",
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/file_errors.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/sketch_reader.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/stacktrace.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/validate_params.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 16,
            +            "description": "<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 102,
            +            "description": "<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n",
            +            "itemtype": "method",
            +            "name": "arc",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>angle to start the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>angle to stop the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "mode",
            +                    "description": "<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detail",
            +                    "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 235,
            +            "description": "<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipse",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 235,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the ellipse.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 261,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detail",
            +                            "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 277,
            +            "description": "<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n",
            +            "itemtype": "method",
            +            "name": "circle",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>diameter of the circle.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 340,
            +            "description": "<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "line",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 340,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 404,
            +            "description": "<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "point",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 404,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z-coordinate (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 455,
            +                    "params": [
            +                        {
            +                            "name": "coordinate_vector",
            +                            "description": "<p>the coordinate vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 483,
            +            "description": "<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "quad",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 483,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>the x-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>the y-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>the x-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>the y-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>the z-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>the z-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 556,
            +            "description": "<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "rect",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 556,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the rectangle.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tl",
            +                            "description": "<p>optional radius of top-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tr",
            +                            "description": "<p>optional radius of top-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "br",
            +                            "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "bl",
            +                            "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 608,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 623,
            +            "description": "<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "square",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "s",
            +                    "description": "<p>side size of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "tl",
            +                    "description": "<p>optional radius of top-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tr",
            +                    "description": "<p>optional radius of top-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "br",
            +                    "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bl",
            +                    "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 713,
            +            "description": "<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n",
            +            "itemtype": "method",
            +            "name": "triangle",
            +            "params": [
            +                {
            +                    "name": "x1",
            +                    "description": "<p>x-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y1",
            +                    "description": "<p>y-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>x-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>y-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x3",
            +                    "description": "<p>x-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y3",
            +                    "description": "<p>y-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 12,
            +            "description": "<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipseMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 81,
            +            "description": "<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "noSmooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses to left & right of center, black background",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 115,
            +            "description": "<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "rectMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 184,
            +            "description": "<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses one left one right of center. On black.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 219,
            +            "description": "<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeCap",
            +            "params": [
            +                {
            +                    "name": "cap",
            +                    "description": "<p>either ROUND, SQUARE or PROJECT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 259,
            +            "description": "<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeJoin",
            +            "params": [
            +                {
            +                    "name": "join",
            +                    "description": "<p>either MITER, BEVEL, ROUND</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 331,
            +            "description": "<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeWeight",
            +            "params": [
            +                {
            +                    "name": "weight",
            +                    "description": "<p>the weight of the stroke (in pixels)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"
            +            ],
            +            "alt": "3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 13,
            +            "description": "<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezier",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 62,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 92,
            +            "description": "<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierDetail",
            +            "params": [
            +                {
            +                    "name": "detail",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape with a low level of bezier detail",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 130,
            +            "description": "<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierPoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value of the Bezier at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "10 points plotted on a given bezier at equal distances.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 185,
            +            "description": "<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 264,
            +            "description": "<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curve",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 264,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 332,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 358,
            +            "description": "<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveDetail",
            +            "params": [
            +                {
            +                    "name": "resolution",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white arch shape with a low level of curve detail.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 398,
            +            "description": "<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTightness",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>amount of deformation from the original vertices</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Line shaped like right-facing arrow,points move with mouse-x and warp shape.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 444,
            +            "description": "<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "curvePoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point of the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "bezier value at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 493,
            +            "description": "<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second conrol point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "right curving line mid-right of canvas with 7 short lines radiating from it.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 20,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 67,
            +            "description": "<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginShape",
            +            "params": [
            +                {
            +                    "name": "kind",
            +                    "description": "<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 293,
            +            "description": "<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 375,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 415,
            +            "description": "<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Upside-down u-shape line, mid canvas. left point extends beyond canvas view.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 415,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 460,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 524,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "endContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 583,
            +            "description": "<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n",
            +            "itemtype": "method",
            +            "name": "endShape",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>use CLOSE to close the shape</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Triangle line shape with smallest interior angle on bottom and upside-down L.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 668,
            +            "description": "<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "quadraticVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 668,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "<p>x-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "<p>y-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 733,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cz",
            +                            "description": "<p>z-coordinate for the control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 826,
            +            "description": "<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "vertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 826,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 957,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 965,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "u",
            +                            "description": "<p>the vertex's texture u-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vertex's texture v-coordinate</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1003,
            +            "description": "<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n",
            +            "itemtype": "method",
            +            "name": "normal",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 1003,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>A p5.Vector representing the vertex normal.</p>\n",
            +                            "type": "Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1040,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The x component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The y component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The z component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 9,
            +            "description": "<p>Version of this p5.js.</p>\n",
            +            "itemtype": "property",
            +            "name": "VERSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 18,
            +            "description": "<p>The default, two-dimensional renderer.</p>\n",
            +            "itemtype": "property",
            +            "name": "P2D",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 24,
            +            "description": "<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n",
            +            "itemtype": "property",
            +            "name": "WEBGL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 33,
            +            "itemtype": "property",
            +            "name": "ARROW",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 38,
            +            "itemtype": "property",
            +            "name": "CROSS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 43,
            +            "itemtype": "property",
            +            "name": "HAND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 48,
            +            "itemtype": "property",
            +            "name": "MOVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 53,
            +            "itemtype": "property",
            +            "name": "TEXT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 58,
            +            "itemtype": "property",
            +            "name": "WAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 66,
            +            "description": "<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HALF_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white quarter-circle with curve toward bottom right of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 84,
            +            "description": "<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"
            +            ],
            +            "alt": "white half-circle with curve toward bottom of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 102,
            +            "description": "<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "QUARTER_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"
            +            ],
            +            "alt": "white eighth-circle rotated about 40 degrees with curve bottom right canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 120,
            +            "description": "<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TAU",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 138,
            +            "description": "<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TWO_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 156,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n",
            +            "itemtype": "property",
            +            "name": "DEGREES",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 170,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n",
            +            "itemtype": "property",
            +            "name": "RADIANS",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 188,
            +            "itemtype": "property",
            +            "name": "CORNER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 193,
            +            "itemtype": "property",
            +            "name": "CORNERS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 198,
            +            "itemtype": "property",
            +            "name": "RADIUS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 203,
            +            "itemtype": "property",
            +            "name": "RIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 208,
            +            "itemtype": "property",
            +            "name": "LEFT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 213,
            +            "itemtype": "property",
            +            "name": "CENTER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 218,
            +            "itemtype": "property",
            +            "name": "TOP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 223,
            +            "itemtype": "property",
            +            "name": "BOTTOM",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 228,
            +            "itemtype": "property",
            +            "name": "BASELINE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "alphabetic",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 234,
            +            "itemtype": "property",
            +            "name": "POINTS",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0000",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 240,
            +            "itemtype": "property",
            +            "name": "LINES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0001",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 246,
            +            "itemtype": "property",
            +            "name": "LINE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0003",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 252,
            +            "itemtype": "property",
            +            "name": "LINE_LOOP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0002",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 258,
            +            "itemtype": "property",
            +            "name": "TRIANGLES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0004",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 264,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_FAN",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0006",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 270,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0005",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 276,
            +            "itemtype": "property",
            +            "name": "QUADS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 281,
            +            "itemtype": "property",
            +            "name": "QUAD_STRIP",
            +            "type": "String",
            +            "final": 1,
            +            "default": "quad_strip",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 287,
            +            "itemtype": "property",
            +            "name": "TESS",
            +            "type": "String",
            +            "final": 1,
            +            "default": "tess",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 293,
            +            "itemtype": "property",
            +            "name": "CLOSE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 298,
            +            "itemtype": "property",
            +            "name": "OPEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 303,
            +            "itemtype": "property",
            +            "name": "CHORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 308,
            +            "itemtype": "property",
            +            "name": "PIE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 313,
            +            "itemtype": "property",
            +            "name": "PROJECT",
            +            "type": "String",
            +            "final": 1,
            +            "default": "square",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 319,
            +            "itemtype": "property",
            +            "name": "SQUARE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "butt",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 325,
            +            "itemtype": "property",
            +            "name": "ROUND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 330,
            +            "itemtype": "property",
            +            "name": "BEVEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 335,
            +            "itemtype": "property",
            +            "name": "MITER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 342,
            +            "itemtype": "property",
            +            "name": "RGB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 347,
            +            "description": "<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HSB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 356,
            +            "itemtype": "property",
            +            "name": "HSL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 363,
            +            "description": "<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n",
            +            "itemtype": "property",
            +            "name": "AUTO",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 373,
            +            "itemtype": "property",
            +            "name": "ALT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 379,
            +            "itemtype": "property",
            +            "name": "BACKSPACE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 384,
            +            "itemtype": "property",
            +            "name": "CONTROL",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 389,
            +            "itemtype": "property",
            +            "name": "DELETE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 394,
            +            "itemtype": "property",
            +            "name": "DOWN_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 399,
            +            "itemtype": "property",
            +            "name": "ENTER",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 404,
            +            "itemtype": "property",
            +            "name": "ESCAPE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 409,
            +            "itemtype": "property",
            +            "name": "LEFT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 414,
            +            "itemtype": "property",
            +            "name": "OPTION",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 419,
            +            "itemtype": "property",
            +            "name": "RETURN",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 424,
            +            "itemtype": "property",
            +            "name": "RIGHT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 429,
            +            "itemtype": "property",
            +            "name": "SHIFT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 434,
            +            "itemtype": "property",
            +            "name": "TAB",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 439,
            +            "itemtype": "property",
            +            "name": "UP_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 446,
            +            "itemtype": "property",
            +            "name": "BLEND",
            +            "type": "String",
            +            "final": 1,
            +            "default": "source-over",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 452,
            +            "itemtype": "property",
            +            "name": "REMOVE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "destination-out",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 458,
            +            "itemtype": "property",
            +            "name": "ADD",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighter",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 466,
            +            "itemtype": "property",
            +            "name": "DARKEST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 471,
            +            "itemtype": "property",
            +            "name": "LIGHTEST",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighten",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 477,
            +            "itemtype": "property",
            +            "name": "DIFFERENCE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 482,
            +            "itemtype": "property",
            +            "name": "SUBTRACT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 487,
            +            "itemtype": "property",
            +            "name": "EXCLUSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 492,
            +            "itemtype": "property",
            +            "name": "MULTIPLY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 497,
            +            "itemtype": "property",
            +            "name": "SCREEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 502,
            +            "itemtype": "property",
            +            "name": "REPLACE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "copy",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 508,
            +            "itemtype": "property",
            +            "name": "OVERLAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 513,
            +            "itemtype": "property",
            +            "name": "HARD_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 518,
            +            "itemtype": "property",
            +            "name": "SOFT_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 523,
            +            "itemtype": "property",
            +            "name": "DODGE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-dodge",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 529,
            +            "itemtype": "property",
            +            "name": "BURN",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-burn",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 537,
            +            "itemtype": "property",
            +            "name": "THRESHOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 542,
            +            "itemtype": "property",
            +            "name": "GRAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 547,
            +            "itemtype": "property",
            +            "name": "OPAQUE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 552,
            +            "itemtype": "property",
            +            "name": "INVERT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 557,
            +            "itemtype": "property",
            +            "name": "POSTERIZE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 562,
            +            "itemtype": "property",
            +            "name": "DILATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 567,
            +            "itemtype": "property",
            +            "name": "ERODE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 572,
            +            "itemtype": "property",
            +            "name": "BLUR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 579,
            +            "itemtype": "property",
            +            "name": "NORMAL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 584,
            +            "itemtype": "property",
            +            "name": "ITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 589,
            +            "itemtype": "property",
            +            "name": "BOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 594,
            +            "itemtype": "property",
            +            "name": "BOLDITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 599,
            +            "itemtype": "property",
            +            "name": "CHAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 604,
            +            "itemtype": "property",
            +            "name": "WORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 616,
            +            "itemtype": "property",
            +            "name": "LINEAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 621,
            +            "itemtype": "property",
            +            "name": "QUADRATIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 626,
            +            "itemtype": "property",
            +            "name": "BEZIER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 631,
            +            "itemtype": "property",
            +            "name": "CURVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 638,
            +            "itemtype": "property",
            +            "name": "STROKE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 643,
            +            "itemtype": "property",
            +            "name": "FILL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 648,
            +            "itemtype": "property",
            +            "name": "TEXTURE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 653,
            +            "itemtype": "property",
            +            "name": "IMMEDIATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 661,
            +            "itemtype": "property",
            +            "name": "IMAGE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 669,
            +            "itemtype": "property",
            +            "name": "NEAREST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 674,
            +            "itemtype": "property",
            +            "name": "REPEAT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 679,
            +            "itemtype": "property",
            +            "name": "CLAMP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 684,
            +            "itemtype": "property",
            +            "name": "MIRROR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 691,
            +            "itemtype": "property",
            +            "name": "LANDSCAPE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 696,
            +            "itemtype": "property",
            +            "name": "PORTRAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 706,
            +            "itemtype": "property",
            +            "name": "GRID",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 712,
            +            "itemtype": "property",
            +            "name": "AXES",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 718,
            +            "itemtype": "property",
            +            "name": "LABEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 723,
            +            "itemtype": "property",
            +            "name": "FALLBACK",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 20,
            +            "description": "<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "contents",
            +                    "description": "<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"
            +            ],
            +            "alt": "default grey canvas",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 52,
            +            "description": "<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n",
            +            "itemtype": "property",
            +            "name": "frameCount",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "numbers rapidly counting upward with frame count set to 30.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 79,
            +            "description": "<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n",
            +            "itemtype": "property",
            +            "name": "deltaTime",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 129,
            +            "description": "<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "focused",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "green 50×50 ellipse at top left. Red X covers canvas when page focus changes",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 160,
            +            "description": "<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n",
            +            "itemtype": "method",
            +            "name": "cursor",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n",
            +                    "type": "String|Constant"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>the horizontal active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>the vertical active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 228,
            +            "description": "<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n",
            +            "itemtype": "method",
            +            "name": "frameRate",
            +            "chainable": 1,
            +            "example": [
            +                "\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "blue rect moves left to right, followed by red rect moving faster. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 228,
            +                    "params": [
            +                        {
            +                            "name": "fps",
            +                            "description": "<p>number of frames to be displayed every second</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 288,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current frameRate",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 331,
            +            "description": "<p>Hides the cursor from view.</p>\n",
            +            "itemtype": "method",
            +            "name": "noCursor",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "cursor becomes 10×10 white ellipse the moves with mouse x and y.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 354,
            +            "description": "<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 372,
            +            "description": "<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 390,
            +            "description": "<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 405,
            +            "description": "<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 421,
            +            "description": "<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n",
            +            "itemtype": "method",
            +            "name": "windowResized",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional Event callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 476,
            +            "description": "<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 488,
            +            "description": "<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 500,
            +            "description": "<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n",
            +            "itemtype": "method",
            +            "name": "fullscreen",
            +            "params": [
            +                {
            +                    "name": "val",
            +                    "description": "<p>whether the sketch should be in fullscreen mode\nor not</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "current fullscreen state",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 550,
            +            "description": "<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "pixelDensity",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 550,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>whether or how much the sketch should scale</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 586,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current pixel density of the sketch",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 605,
            +            "description": "<p>Returns the pixel density of the current display the sketch is running on.</p>\n",
            +            "itemtype": "method",
            +            "name": "displayDensity",
            +            "return": {
            +                "description": "current pixel density of the display",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 660,
            +            "description": "<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURL",
            +            "return": {
            +                "description": "url",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "current url (http://p5js.org/reference/#/p5/getURL) moves right to left.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 691,
            +            "description": "<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLPath",
            +            "return": {
            +                "description": "path components",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 713,
            +            "description": "<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLParams",
            +            "return": {
            +                "description": "URL params",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/helpers.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 30,
            +            "description": "<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 126,
            +            "description": "<p>Set up our translation function, with loaded languages</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 171,
            +            "description": "<p>Returns a list of languages we have translations loaded for</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 178,
            +            "description": "<p>Returns the current language selected for translation</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 185,
            +            "description": "<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/legacy.js",
            +            "line": 1,
            +            "requires": [
            +                "core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name",
            +                "in others",
            +                "they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 42,
            +            "description": "<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "preload",
            +            "example": [
            +                "\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 83,
            +            "description": "<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setup",
            +            "example": [
            +                "\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 114,
            +            "description": "<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "draw",
            +            "example": [
            +                "\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 415,
            +            "description": "<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 693,
            +            "description": "<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "disableFriendlyErrors",
            +            "type": "Boolean",
            +            "example": [
            +                "\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 21,
            +            "description": "<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "elt",
            +            "readonly": "",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 47,
            +            "description": "<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "parent",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 47,
            +                    "params": [
            +                        {
            +                            "name": "parent",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n",
            +                            "type": "String|p5.Element|Object"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 93,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 114,
            +            "description": "<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n",
            +            "itemtype": "method",
            +            "name": "id",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 114,
            +                    "params": [
            +                        {
            +                            "name": "id",
            +                            "description": "<p>ID of the element</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the id of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 154,
            +            "description": "<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "class",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 154,
            +                    "params": [
            +                        {
            +                            "name": "class",
            +                            "description": "<p>class to add</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the class of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 189,
            +            "description": "<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 246,
            +            "description": "<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 292,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 354,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 403,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 454,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 510,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 551,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOut",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 592,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 639,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 678,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 725,
            +            "description": "<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 763,
            +            "description": "<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragLeave",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 827,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 70,
            +            "description": "<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 122,
            +            "description": "<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image\na multi-colored circle moving back and forth over a scrolling background.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 99,
            +            "description": "<p>Resize our canvas element.</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 415,
            +            "description": "<p>Helper function to check font type (system or otf)</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 467,
            +            "description": "<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 7,
            +            "description": "<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 402,
            +            "description": "<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 7,
            +            "description": "<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n",
            +            "itemtype": "property",
            +            "name": "let",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 34,
            +            "description": "<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n",
            +            "itemtype": "property",
            +            "name": "const",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"
            +            ],
            +            "alt": "These examples do not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 87,
            +            "description": "<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n",
            +            "itemtype": "property",
            +            "name": "===",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 115,
            +            "description": "<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>",
            +            "itemtype": "property",
            +            "name": ">",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 137,
            +            "description": "<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": ">=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 158,
            +            "description": "<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 179,
            +            "description": "<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 200,
            +            "description": "<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n",
            +            "itemtype": "property",
            +            "name": "if-else",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 231,
            +            "description": "<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n",
            +            "itemtype": "property",
            +            "name": "function",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 267,
            +            "description": "<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "return",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 288,
            +            "description": "<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n",
            +            "itemtype": "property",
            +            "name": "boolean",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 309,
            +            "description": "<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n",
            +            "itemtype": "property",
            +            "name": "string",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 331,
            +            "description": "<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n",
            +            "itemtype": "property",
            +            "name": "number",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 351,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n",
            +            "itemtype": "property",
            +            "name": "object",
            +            "example": [
            +                "\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 379,
            +            "description": "<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n",
            +            "itemtype": "property",
            +            "name": "class",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 408,
            +            "description": "<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n",
            +            "itemtype": "property",
            +            "name": "for",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 448,
            +            "description": "<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n",
            +            "itemtype": "property",
            +            "name": "while",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 490,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "stringify",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>:Javascript object that you would like to convert to JSON</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "JSON",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 512,
            +            "description": "<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "message",
            +                    "description": "<p>:Message that you would like to print to the console</p>\n",
            +                    "type": "String|Expression|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "console",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 15,
            +            "description": "<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Renderer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Black line extending from top-left of canvas to bottom right.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 125,
            +            "description": "<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "resizeCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "noRedraw",
            +                    "description": "<p>don't redraw the canvas immediately</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "No image displayed.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 183,
            +            "description": "<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n",
            +            "itemtype": "method",
            +            "name": "noCanvas",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 204,
            +            "description": "<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "createGraphics",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "offscreen graphics buffer",
            +                "type": "p5.Graphics"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 grey squares alternating light and dark grey. White quarter circle mid-left.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 243,
            +            "description": "<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n",
            +            "itemtype": "method",
            +            "name": "blendMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"
            +            ],
            +            "alt": "translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 326,
            +            "description": "<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n",
            +            "itemtype": "property",
            +            "name": "drawingContext",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white ellipse with shadow blur effect around edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 18,
            +            "description": "<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 39,
            +            "description": "<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 10,
            +            "description": "<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 83,
            +            "description": "<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "example": [
            +                "\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 134,
            +            "description": "<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "example": [
            +                "\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 192,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "push",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 290,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "pop",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 391,
            +            "description": "<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n",
            +            "itemtype": "method",
            +            "name": "redraw",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>Redraw for n-times. The default value is 1.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black line on far left of canvas\nblack line on far left of canvas",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 497,
            +            "description": "<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "p5",
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a function containing a p5.js sketch</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>ID or pointer to HTML DOM node to contain sketch in</p>\n",
            +                    "type": "String|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"
            +            ],
            +            "alt": "white rectangle on black background",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 11,
            +            "description": "<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n",
            +            "itemtype": "method",
            +            "name": "applyMatrix",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n",
            +                    "type": "Number|Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "f",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 168,
            +            "description": "<p>Replaces the current matrix with the identity matrix.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetMatrix",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"
            +            ],
            +            "alt": "A rotated rectangle in the center with another at the top left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 193,
            +            "description": "<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "axis",
            +                    "description": "<p>(in 3d) the axis to rotate around</p>\n",
            +                    "type": "p5.Vector|Number[]",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 232,
            +            "description": "<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the x axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 268,
            +            "description": "<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the y axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 304,
            +            "description": "<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateZ",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the z axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 342,
            +            "description": "<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 342,
            +                    "params": [
            +                        {
            +                            "name": "s",
            +                            "description": "<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n",
            +                            "type": "Number|p5.Vector|Number[]"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>percent to scale the object in the y-axis</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>percent to scale the object in the z-axis (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 386,
            +                    "params": [
            +                        {
            +                            "name": "scales",
            +                            "description": "<p>per-axis percents to scale the object</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 416,
            +            "description": "<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at top middle.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 455,
            +            "description": "<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at middle bottom.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 494,
            +            "description": "<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "translate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 494,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>left/right translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>up/down translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>forward/backward translation (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>the vector to translate by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 10,
            +            "description": "<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n",
            +            "itemtype": "method",
            +            "name": "storeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"
            +            ],
            +            "alt": "When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 101,
            +            "description": "<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "getItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>name that you wish to use to store in local storage</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Value of stored item",
            +                "type": "Number|Object|String|Boolean|p5.Color|p5.Vector"
            +            },
            +            "example": [
            +                "\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"
            +            ],
            +            "alt": "If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 177,
            +            "description": "<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearStorage",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 205,
            +            "description": "<p>Removes an item that was stored with storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "removeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 14,
            +            "description": "<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createStringDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.StringDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 14,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                },
            +                {
            +                    "line": 37,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 48,
            +            "description": "<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createNumberDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.NumberDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 48,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 101,
            +            "description": "<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the number of key-value pairs in the Dictionary",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 122,
            +            "description": "<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasKey",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>that you want to look up</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether that key exists in Dictionary",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 144,
            +            "description": "<p>Returns the value stored at the given key.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>key you want to access</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value stored at that key",
            +                "type": "Number|String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 170,
            +            "description": "<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 197,
            +            "description": "<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 208,
            +            "description": "<p>Creates a new key-value pair in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "create",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 208,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 226,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>key/value pair</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 244,
            +            "description": "<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 265,
            +            "description": "<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>for the pair to remove</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 294,
            +            "description": "<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 318,
            +            "description": "<p>Converts the Dictionary into a CSV file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 356,
            +            "description": "<p>Converts the Dictionary into a JSON file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 387,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 425,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 432,
            +            "description": "<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to add to</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to add to the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 459,
            +            "description": "<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to subtract from</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to subtract from the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 482,
            +            "description": "<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to multiply</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to multiply the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 509,
            +            "description": "<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to divide</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to divide the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 536,
            +            "description": "<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 560,
            +            "description": "<p>Return the lowest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 580,
            +            "description": "<p>Return the highest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 600,
            +            "description": "<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 622,
            +            "description": "<p>Return the lowest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 642,
            +            "description": "<p>Return the highest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 21,
            +            "description": "<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "select",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of element to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Element\">p5.Element</a> containing node found",
            +                "type": "p5.Element|null"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 68,
            +            "description": "<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "selectAll",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of elements to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found",
            +                "type": "p5.Element[]"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 127,
            +            "description": "<p>Helper function for select and selectAll</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 142,
            +            "description": "<p>Helper function for getElement and getElements.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 176,
            +            "description": "<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeElements",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 204,
            +            "description": "<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "changed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 271,
            +            "description": "<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "input",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 309,
            +            "description": "<p>Helpers for create methods.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 322,
            +            "description": "<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createDiv",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 341,
            +            "description": "<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createP",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 361,
            +            "description": "<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSpan",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 379,
            +            "description": "<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImg",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>src path or url for image</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 396,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "crossOrigin",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 426,
            +            "description": "<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n",
            +            "itemtype": "method",
            +            "name": "createA",
            +            "params": [
            +                {
            +                    "name": "href",
            +                    "description": "<p>url of page to link to</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner html of link element to display</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "target",
            +                    "description": "<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 450,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 452,
            +            "description": "<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSlider",
            +            "params": [
            +                {
            +                    "name": "min",
            +                    "description": "<p>minimum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "max",
            +                    "description": "<p>maximum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>default value of the slider</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "step",
            +                    "description": "<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 507,
            +            "description": "<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n",
            +            "itemtype": "method",
            +            "name": "createButton",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed on the button</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the button</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 541,
            +            "description": "<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n",
            +            "itemtype": "method",
            +            "name": "createCheckbox",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed after checkbox</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the checkbox; checked is true, unchecked is false</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 622,
            +            "description": "<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createSelect",
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "multiple",
            +                            "description": "<p>true if dropdown should support multiple selections</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 673,
            +                    "params": [
            +                        {
            +                            "name": "existing",
            +                            "description": "<p>DOM select element</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 770,
            +            "description": "<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createRadio",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 770,
            +                    "params": [
            +                        {
            +                            "name": "containerElement",
            +                            "description": "<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "name",
            +                            "description": "<p>A name parameter for each Input Element.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 832,
            +                    "params": [
            +                        {
            +                            "name": "name",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 837,
            +                    "params": [],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 978,
            +            "description": "<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n",
            +            "itemtype": "method",
            +            "name": "createColorPicker",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>default color of element</p>\n",
            +                    "type": "String|p5.Color",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1066,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n",
            +            "itemtype": "method",
            +            "name": "createInput",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1066,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>default value of the input box</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "type",
            +                            "description": "<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1104,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "createFileInput",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function for when a file is loaded</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "multiple",
            +                    "description": "<p>optional, to allow multiple files to be selected</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1164,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1211,
            +            "description": "<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVideo",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n",
            +                    "type": "String|String[]"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1257,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1259,
            +            "description": "<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createAudio",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n",
            +                    "type": "String|String[]",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1296,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1298,
            +            "itemtype": "property",
            +            "name": "VIDEO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1304,
            +            "itemtype": "property",
            +            "name": "AUDIO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1341,
            +            "description": "<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCapture",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n",
            +                    "type": "String|Constant|Object"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be called once\n                                  stream has loaded</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1478,
            +            "description": "<p>Creates element with given tag in the DOM with given content.</p>\n",
            +            "itemtype": "method",
            +            "name": "createElement",
            +            "params": [
            +                {
            +                    "name": "tag",
            +                    "description": "<p>tag for the new element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "content",
            +                    "description": "<p>html content to be inserted into the element</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1504,
            +            "description": "<p>Adds specified class to the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "addClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to add</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1529,
            +            "description": "<p>Removes specified class from the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1560,
            +            "description": "<p>Checks if specified class already set to element</p>\n",
            +            "itemtype": "method",
            +            "name": "hasClass",
            +            "return": {
            +                "description": "a boolean value if element has specified class",
            +                "type": "Boolean"
            +            },
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name of class to check</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1589,
            +            "description": "<p>Toggles element class</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleClass",
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name to toggle</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1622,
            +            "description": "<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "child",
            +            "return": {
            +                "description": "an array of child nodes",
            +                "type": "Node[]"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1622,
            +                    "params": [],
            +                    "return": {
            +                        "description": "an array of child nodes",
            +                        "type": "Node[]"
            +                    }
            +                },
            +                {
            +                    "line": 1650,
            +                    "params": [
            +                        {
            +                            "name": "child",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n",
            +                            "type": "String|p5.Element",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1675,
            +            "description": "<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n",
            +            "itemtype": "method",
            +            "name": "center",
            +            "params": [
            +                {
            +                    "name": "align",
            +                    "description": "<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1726,
            +            "description": "<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "html",
            +            "return": {
            +                "description": "the inner HTML of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1726,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the inner HTML of the element",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1747,
            +                    "params": [
            +                        {
            +                            "name": "html",
            +                            "description": "<p>the HTML to be placed inside the element</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "append",
            +                            "description": "<p>whether to append HTML to existing</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1765,
            +            "description": "<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n",
            +            "itemtype": "method",
            +            "name": "position",
            +            "return": {
            +                "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1765,
            +                    "params": [],
            +                    "return": {
            +                        "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 1798,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "positionType",
            +                            "description": "<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1885,
            +            "description": "<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n",
            +            "itemtype": "method",
            +            "name": "style",
            +            "return": {
            +                "description": "value of property",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1885,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "<p>property to be set</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "value of property",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1923,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to property</p>\n",
            +                            "type": "String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1,
            +                    "return": {
            +                        "description": "current value of property, if no value is given as second argument",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1980,
            +            "description": "<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n",
            +            "itemtype": "method",
            +            "name": "attribute",
            +            "return": {
            +                "description": "value of attribute",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1980,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of attribute",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1995,
            +                    "params": [
            +                        {
            +                            "name": "attr",
            +                            "description": "<p>attribute to set</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to attribute</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2024,
            +            "description": "<p>Removes an attribute on the specified element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeAttribute",
            +            "params": [
            +                {
            +                    "name": "attr",
            +                    "description": "<p>attribute to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2069,
            +            "description": "<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "value",
            +            "return": {
            +                "description": "value of the element",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2069,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of the element",
            +                        "type": "String|Number"
            +                    }
            +                },
            +                {
            +                    "line": 2099,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2115,
            +            "description": "<p>Shows the current element. Essentially, setting display:block for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "show",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2133,
            +            "description": "<p>Hides the current element. Essentially, setting display:none for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "hide",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2149,
            +            "description": "<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the width and height of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2149,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the width and height of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 2173,
            +                    "params": [
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2230,
            +            "description": "<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2268,
            +            "description": "<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n",
            +            "itemtype": "method",
            +            "name": "drop",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to receive loaded file, called for each file dropped.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>callback triggered once when files are dropped with the drop event.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"
            +            ],
            +            "alt": "Canvas turns into whatever image is dragged/dropped onto it.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2400,
            +            "description": "<p>Path to the media element source.</p>\n",
            +            "itemtype": "property",
            +            "name": "src",
            +            "return": {
            +                "description": "src",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2466,
            +            "description": "<p>Play an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2530,
            +            "description": "<p>Stops an HTML5 media element (sets current time to zero).</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2594,
            +            "description": "<p>Pauses an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2656,
            +            "description": "<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2712,
            +            "description": "<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2778,
            +            "description": "<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n",
            +            "itemtype": "method",
            +            "name": "autoplay",
            +            "params": [
            +                {
            +                    "name": "shouldAutoplay",
            +                    "description": "<p>whether the element should autoplay</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2845,
            +            "description": "<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n",
            +            "itemtype": "method",
            +            "name": "volume",
            +            "return": {
            +                "description": "current volume",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2845,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current volume",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2918,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>volume between 0.0 and 1.0</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2931,
            +            "description": "<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n",
            +            "itemtype": "method",
            +            "name": "speed",
            +            "return": {
            +                "description": "current playback speed of the element",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2931,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current playback speed of the element",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3003,
            +                    "params": [
            +                        {
            +                            "name": "speed",
            +                            "description": "<p>speed multiplier for element playback</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3020,
            +            "description": "<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n",
            +            "itemtype": "method",
            +            "name": "time",
            +            "return": {
            +                "description": "current time (in seconds)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 3020,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current time (in seconds)",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3065,
            +                    "params": [
            +                        {
            +                            "name": "time",
            +                            "description": "<p>time to jump to (in seconds)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3079,
            +            "description": "<p>Returns the duration of the HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "duration",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3201,
            +            "description": "<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3232,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3234,
            +            "description": "<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "audioNode",
            +                    "description": "<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n",
            +                    "type": "AudioNode|Object"
            +                }
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3283,
            +            "description": "<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3298,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3300,
            +            "description": "<p>Show the default MediaElement controls, as determined by the web browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "showControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3331,
            +            "description": "<p>Hide the default mediaElement controls.</p>\n",
            +            "itemtype": "method",
            +            "name": "hideControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3360,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3371,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3434,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3476,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3542,
            +            "description": "<p>Underlying File object. All normal File methods can be called on this.</p>\n",
            +            "itemtype": "property",
            +            "name": "file",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3554,
            +            "description": "<p>File type (image, text, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "type",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3560,
            +            "description": "<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "subtype",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3566,
            +            "description": "<p>File name</p>\n",
            +            "itemtype": "property",
            +            "name": "name",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3572,
            +            "description": "<p>File size</p>\n",
            +            "itemtype": "property",
            +            "name": "size",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3579,
            +            "description": "<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n",
            +            "itemtype": "property",
            +            "name": "data",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 11,
            +            "description": "<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n",
            +            "itemtype": "property",
            +            "name": "deviceOrientation",
            +            "type": "Constant",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 23,
            +            "description": "<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 46,
            +            "description": "<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 69,
            +            "description": "<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 94,
            +            "description": "<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 104,
            +            "description": "<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 114,
            +            "description": "<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 135,
            +            "description": "<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 168,
            +            "description": "<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 201,
            +            "description": "<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "rotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 239,
            +            "description": "<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 285,
            +            "description": "<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 330,
            +            "description": "<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 389,
            +            "description": "<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n",
            +            "itemtype": "property",
            +            "name": "turnAxis",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 428,
            +            "description": "<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMoveThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 471,
            +            "description": "<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n",
            +            "itemtype": "method",
            +            "name": "setShakeThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 515,
            +            "description": "<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceMoved",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 546,
            +            "description": "<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceTurned",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 604,
            +            "description": "<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceShaken",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device shakes",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 10,
            +            "description": "<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect that turns black on keypress.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 36,
            +            "description": "<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n",
            +            "itemtype": "property",
            +            "name": "key",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"
            +            ],
            +            "alt": "canvas displays any key value that is pressed in pink font.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 64,
            +            "description": "<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyCode",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"
            +            ],
            +            "alt": "Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 103,
            +            "description": "<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyPressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 190,
            +            "description": "<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when pressed again",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 243,
            +            "description": "<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyTyped",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when 'a' key typed and black when 'b' pressed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 298,
            +            "description": "<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 308,
            +            "description": "<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyIsDown",
            +            "params": [
            +                {
            +                    "name": "code",
            +                    "description": "<p>The key to check for.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether key is down or not",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 12,
            +            "description": "<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"
            +            ],
            +            "alt": "box moves left and right according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 43,
            +            "description": "<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "box moves up and down according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 80,
            +            "description": "<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal black line moves left and right with mouse x-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 106,
            +            "description": "<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black line moves up and down with mouse y-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 132,
            +            "description": "<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "line trail is created from cursor movements. faster movement make longer line.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 164,
            +            "description": "<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect center, fuchsia background. rect flickers on mouse movement",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 195,
            +            "description": "<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 233,
            +            "description": "<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 271,
            +            "description": "<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 311,
            +            "description": "<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 351,
            +            "description": "<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseButton",
            +            "type": "Constant",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 389,
            +            "description": "<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 481,
            +            "description": "<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 535,
            +            "description": "<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseDragged",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 615,
            +            "description": "<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 696,
            +            "description": "<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 772,
            +            "description": "<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 841,
            +            "description": "<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 926,
            +            "description": "<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional WheelEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect moves up and down with vertical scroll. fuchsia background",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 979,
            +            "description": "<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n",
            +            "itemtype": "method",
            +            "name": "requestPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3D scene moves according to mouse mouse movement in a first person perspective",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 1025,
            +            "description": "<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n",
            +            "itemtype": "method",
            +            "name": "exitPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "cursor gets locked / unlocked on mouse-click",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 10,
            +            "description": "<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n",
            +            "itemtype": "property",
            +            "name": "touches",
            +            "type": "Object[]",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Number of touches currently registered are displayed on the canvas",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 71,
            +            "description": "<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch event.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 151,
            +            "description": "<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns lighter with touch until white. resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 223,
            +            "description": "<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/image/filters.js",
            +            "line": 3,
            +            "description": "<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n",
            +            "class": "p5",
            +            "module": "Events"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 8,
            +            "description": "<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 15,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImage",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width in pixels</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height in pixels</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 94,
            +            "description": "<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveCanvas",
            +            "example": [
            +                "\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed\n no image displayed\n no image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 94,
            +                    "params": [
            +                        {
            +                            "name": "selectedCanvas",
            +                            "description": "<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n",
            +                            "type": "p5.Element|HTMLCanvasElement"
            +                        },
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "<p>'jpg' or 'png'</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 413,
            +            "description": "<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveFrames",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'jpg' or 'png'</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Duration in seconds to save the frames for.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "framerate",
            +                    "description": "<p>Framerate to save the frames in.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n",
            +                    "type": "Function(Array)",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"
            +            ],
            +            "alt": "canvas background goes from light to dark with mouse x.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 18,
            +            "description": "<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadImage",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path of the image to be loaded</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n",
            +                    "type": "function(p5.Image)",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "failureCallback",
            +                    "description": "<p>called with event error if\n                               the image fails to load.</p>\n",
            +                    "type": "Function(Event)",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 162,
            +            "description": "<p>Helper function for loading GIF-based images</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 301,
            +            "description": "<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n",
            +            "itemtype": "method",
            +            "name": "image",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 301,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "<p>the image to display</p>\n",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "width",
            +                            "description": "<p>the width to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "height",
            +                            "description": "<p>the height to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 388,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dWidth",
            +                            "description": "<p>the width of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dHeight",
            +                            "description": "<p>the height of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sWidth",
            +                            "description": "<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "sHeight",
            +                            "description": "<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 471,
            +            "description": "<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n",
            +            "itemtype": "method",
            +            "name": "tint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 471,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 542,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 553,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 559,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the tint color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 569,
            +            "description": "<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n",
            +            "itemtype": "method",
            +            "name": "noTint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of bricks, left image with blue tint",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 633,
            +            "description": "<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n",
            +            "itemtype": "method",
            +            "name": "imageMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, or CENTER</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 9,
            +            "description": "<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 88,
            +            "description": "<p>Image width.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains in top and horizontal lines in corresponding colors in bottom.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 115,
            +            "description": "<p>Image height.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains on right and vertical lines in corresponding colors on left.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 152,
            +            "description": "<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 222,
            +            "description": "<p>Helper function for animating GIF-based images with time</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 253,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 261,
            +            "description": "<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 296,
            +            "description": "<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 296,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 338,
            +                    "params": []
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 346,
            +            "description": "<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with 50×50 green rect in front",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 346,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 383,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 387,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 400,
            +            "description": "<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"
            +            ],
            +            "alt": "2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 437,
            +            "description": "<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n",
            +            "itemtype": "method",
            +            "name": "resize",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>the resized image width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>the resized image height</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. zoomed in",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 548,
            +            "description": "<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains and smaller image on top of bricks at top left",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 548,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 588,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 603,
            +            "description": "<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mask",
            +            "params": [
            +                {
            +                    "name": "srcImage",
            +                    "description": "<p>source image</p>\n",
            +                    "type": "p5.Image"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 665,
            +            "description": "<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains left one in color, right in black and white",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 738,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 738,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 815,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 859,
            +            "description": "<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>give your file a name</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'png' or 'jpg'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 900,
            +            "description": "<p>Starts an animated GIF over at the beginning state.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 941,
            +            "description": "<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "getCurrentFrame",
            +            "return": {
            +                "description": "The index for the currently displaying frame in animated GIF",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 972,
            +            "description": "<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "setFrame",
            +            "params": [
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index for the frame that should be displayed</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1017,
            +            "description": "<p>Returns the number of frames in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "numFrames",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1052,
            +            "description": "<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1089,
            +            "description": "<p>Pauses an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1125,
            +            "description": "<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n",
            +            "itemtype": "method",
            +            "name": "delay",
            +            "params": [
            +                {
            +                    "name": "d",
            +                    "description": "<p>the amount in milliseconds to delay between switching frames</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index of the frame that should have the new delay value {optional}</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 12,
            +            "description": "<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"
            +            ],
            +            "alt": "top half of canvas pink, bottom grey",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 80,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 80,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 152,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 173,
            +            "description": "<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 173,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 215,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 307,
            +            "description": "<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 481,
            +            "description": "<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 551,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 555,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 566,
            +            "description": "<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 602,
            +            "description": "<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 674,
            +            "description": "<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 20,
            +            "description": "<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadJSON",
            +            "return": {
            +                "description": "JSON data",
            +                "type": "Object|Array"
            +            },
            +            "example": [
            +                "\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 20,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "jsonpOptions",
            +                            "description": "<p>options object for jsonp related settings</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\" or \"jsonp\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "JSON data",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 104,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 112,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 183,
            +            "description": "<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadStrings",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 303,
            +            "description": "<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadTable",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "header",
            +                    "description": "<p>\"header\" to indicate table has header row</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Table\">Table</a> object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 583,
            +            "description": "<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadXML",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "XML object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 693,
            +            "description": "<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadBytes",
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if there\n                                   is an error</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an object whose 'bytes' property will be the loaded buffer",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 752,
            +            "description": "<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n",
            +            "itemtype": "method",
            +            "name": "httpGet",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 752,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 806,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 814,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 829,
            +            "description": "<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpPost",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 896,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 904,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 919,
            +            "description": "<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpDo",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 919,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "method",
            +                            "description": "<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 990,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "options",
            +                            "description": "<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1155,
            +            "itemtype": "method",
            +            "name": "createWriter",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the file to be created</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.PrintWriter"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1210,
            +            "description": "<p>Writes data to the PrintWriter stream</p>\n",
            +            "itemtype": "method",
            +            "name": "write",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be written by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1269,
            +            "description": "<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be printed by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1310,
            +            "description": "<p>Clears the data already written to the PrintWriter object</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1344,
            +            "description": "<p>Closes the PrintWriter</p>\n",
            +            "itemtype": "method",
            +            "name": "close",
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1393,
            +            "description": "<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "objectOrFilename",
            +                    "description": "<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n",
            +                    "type": "Object|String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n",
            +                    "type": "Boolean|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"
            +            ],
            +            "alt": "An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1535,
            +            "description": "<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "params": [
            +                {
            +                    "name": "json",
            +                    "description": "",
            +                    "type": "Array|Object"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "optimize",
            +                    "description": "<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1592,
            +            "description": "<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveStrings",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>string array to be written</p>\n",
            +                    "type": "String[]"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>filename for output</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>the filename's extension</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isCRLF",
            +                    "description": "<p>if true, change line-break to CRLF</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1656,
            +            "description": "<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "params": [
            +                {
            +                    "name": "Table",
            +                    "description": "<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n",
            +                    "type": "p5.Table"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>the filename to which the Table should be saved</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 9,
            +            "description": "<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 43,
            +            "description": "<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n",
            +            "itemtype": "property",
            +            "name": "columns",
            +            "type": "String[]",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 77,
            +            "description": "<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n",
            +            "itemtype": "property",
            +            "name": "rows",
            +            "type": "p5.TableRow[]",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 85,
            +            "description": "<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n",
            +            "itemtype": "method",
            +            "name": "addRow",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row to be added to the table</p>\n",
            +                    "type": "p5.TableRow",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the row that was added",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 148,
            +            "description": "<p>Removes a row from the table object.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeRow",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID number of the row to remove</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 195,
            +            "description": "<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRow",
            +            "params": [
            +                {
            +                    "name": "rowID",
            +                    "description": "<p>ID number of the row to get</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 240,
            +            "description": "<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRows",
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 288,
            +            "description": "<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRow",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 352,
            +            "description": "<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRows",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 420,
            +            "description": "<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRow",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String|RegExp"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "TableRow object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 478,
            +            "description": "<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRows",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 545,
            +            "description": "<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>String or Number of the column to return</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of column values",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 597,
            +            "description": "<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearRows",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 638,
            +            "description": "<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n",
            +            "itemtype": "method",
            +            "name": "addColumn",
            +            "params": [
            +                {
            +                    "name": "title",
            +                    "description": "<p>title of the given column</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 688,
            +            "description": "<p>Returns the total number of columns in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumnCount",
            +            "return": {
            +                "description": "Number of columns in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 724,
            +            "description": "<p>Returns the total number of rows in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRowCount",
            +            "return": {
            +                "description": "Number of rows in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 760,
            +            "description": "<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeTokens",
            +            "params": [
            +                {
            +                    "name": "chars",
            +                    "description": "<p>String listing characters to be removed</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 832,
            +            "description": "<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 896,
            +            "description": "<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 960,
            +            "description": "<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1009,
            +            "description": "<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1055,
            +            "description": "<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1100,
            +            "description": "<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1146,
            +            "description": "<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1190,
            +            "description": "<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1242,
            +            "description": "<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getObject",
            +            "params": [
            +                {
            +                    "name": "headerColumn",
            +                    "description": "<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1305,
            +            "description": "<p>Retrieves all table data and returns it as a multidimensional array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getArray",
            +            "return": {
            +                "description": "",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 40,
            +            "description": "<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 102,
            +            "description": "<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a Float</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 146,
            +            "description": "<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a String</p>\n",
            +                    "type": "String|Number|Boolean|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 191,
            +            "description": "<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 239,
            +            "description": "<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "Float Floating point number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 295,
            +            "description": "<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 62,
            +            "description": "<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "getParent",
            +            "return": {
            +                "description": "element parent",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 100,
            +            "description": "<p>Gets the element's full name, which is returned as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "getName",
            +            "return": {
            +                "description": "the name of the node",
            +                "type": "String"
            +            },
            +            "example": [
            +                "&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 135,
            +            "description": "<p>Sets the element's name, which is specified as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "setName",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>new name of the node</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 181,
            +            "description": "<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasChildren",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 217,
            +            "description": "<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "listChildren",
            +            "return": {
            +                "description": "names of the children of the element",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 258,
            +            "description": "<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChildren",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "children of the element",
            +                "type": "p5.XML[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 314,
            +            "description": "<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 374,
            +            "description": "<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "addChild",
            +            "params": [
            +                {
            +                    "name": "node",
            +                    "description": "<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n",
            +                    "type": "p5.XML"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 426,
            +            "description": "<p>Removes the element specified by name or index.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 498,
            +            "description": "<p>Counts the specified element's number of attributes, returned as an Number.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAttributeCount",
            +            "return": {
            +                "description": "",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 534,
            +            "description": "<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n",
            +            "itemtype": "method",
            +            "name": "listAttributes",
            +            "return": {
            +                "description": "an array of strings containing the names of attributes",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 577,
            +            "description": "<p>Checks whether or not an element has the specified attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasAttribute",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>attribute to be checked</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "true if attribute found else false",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 622,
            +            "description": "<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 669,
            +            "description": "<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 716,
            +            "description": "<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttribute",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value of the attribute</p>\n",
            +                    "type": "Number|String|Boolean"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 757,
            +            "description": "<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getContent",
            +            "params": [
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>value returned if no content is found</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 798,
            +            "description": "<p>Sets the element's content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setContent",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>the new content</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 839,
            +            "description": "<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n",
            +            "itemtype": "method",
            +            "name": "serialize",
            +            "return": {
            +                "description": "Serialized string of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 10,
            +            "description": "<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n",
            +            "itemtype": "method",
            +            "name": "abs",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to compute</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "absolute value of given number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 33,
            +            "description": "<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n",
            +            "itemtype": "method",
            +            "name": "ceil",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round up</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded up number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 72,
            +            "description": "<p>Constrains a value between a minimum and maximum value.</p>\n",
            +            "itemtype": "method",
            +            "name": "constrain",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to constrain</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "low",
            +                    "description": "<p>minimum limit</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "high",
            +                    "description": "<p>maximum limit</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "constrained number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"
            +            ],
            +            "alt": "2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 116,
            +            "description": "<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "distance between the two points",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"
            +            ],
            +            "alt": "2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 116,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 161,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 182,
            +            "description": "<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n",
            +            "itemtype": "method",
            +            "name": "exp",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>exponent to raise</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "e^n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. e^n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 231,
            +            "description": "<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n",
            +            "itemtype": "method",
            +            "name": "floor",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round down</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded down number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 269,
            +            "description": "<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "params": [
            +                {
            +                    "name": "start",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "lerped value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"
            +            ],
            +            "alt": "5 points horizontally staggered mid-canvas. mid 3 are grey, outer black",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 316,
            +            "description": "<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number greater than 0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "natural logarithm of n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. natural logarithm of n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 371,
            +            "description": "<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "magnitude of vector from (0,0) to (a,b)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"
            +            ],
            +            "alt": "4 lines of different length radiate from top left of canvas.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 409,
            +            "description": "<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n",
            +            "itemtype": "method",
            +            "name": "map",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the incoming value to be converted</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start1",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop1",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start2",
            +                    "description": "<p>lower bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop2",
            +                    "description": "<p>upper bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "withinBounds",
            +                    "description": "<p>constrain the value to the newly mapped range</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "remapped number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"
            +            ],
            +            "alt": "10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 464,
            +            "description": "<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "max",
            +            "return": {
            +                "description": "maximum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 464,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "maximum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 499,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 512,
            +            "description": "<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "min",
            +            "return": {
            +                "description": "minimum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "minimum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 560,
            +            "description": "<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n",
            +            "itemtype": "method",
            +            "name": "norm",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>incoming value to be normalized</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "normalized number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves with mouse. 0 shown left & 100 right and updating values center",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 612,
            +            "description": "<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n",
            +            "itemtype": "method",
            +            "name": "pow",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>base of the exponential expression</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>power by which to raise the base</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "n^e",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"
            +            ],
            +            "alt": "small to large ellipses radiating from top left of canvas",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 646,
            +            "description": "<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n",
            +            "itemtype": "method",
            +            "name": "round",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decimals",
            +                    "description": "<p>number of decimal places to round to, default is 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 701,
            +            "description": "<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sq",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to square</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "squared number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squared values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 745,
            +            "description": "<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n",
            +            "itemtype": "method",
            +            "name": "sqrt",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>non-negative number to square root</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "square root of number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squareroot values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 832,
            +            "description": "<p>Calculates the fractional part of a number.</p>\n",
            +            "itemtype": "method",
            +            "name": "fract",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>Number whose fractional part needs to be found out</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "fractional part of x, i.e, {x}",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"
            +            ],
            +            "alt": "first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/math.js",
            +            "line": 10,
            +            "description": "<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVector",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"
            +            ],
            +            "alt": "draws a line from center of canvas to mouse pointer position.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 36,
            +            "description": "<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n",
            +            "itemtype": "method",
            +            "name": "noise",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate in noise space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Perlin noise value (between 0 and 1) at specified\n                     coordinates",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 178,
            +            "description": "<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseDetail",
            +            "params": [
            +                {
            +                    "name": "lod",
            +                    "description": "<p>number of octaves to be used by the noise</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "falloff",
            +                    "description": "<p>falloff factor for each octave</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "2 vertical grey smokey patterns affected my mouse x-position and noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 243,
            +            "description": "<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical grey lines drawing in pattern affected by noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 69,
            +            "description": "<p>The x component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "x",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 74,
            +            "description": "<p>The y component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "y",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 79,
            +            "description": "<p>The z component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "z",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 86,
            +            "description": "<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 136,
            +            "description": "<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 195,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to set</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 219,
            +            "description": "<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "return": {
            +                "description": "the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 248,
            +            "description": "<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 248,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to be added</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 325,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to add</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2059,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 372,
            +            "description": "<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "rem",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 372,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 401,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>divisor vector</p>\n",
            +                            "type": "p5.Vector | Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2085,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2091,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 461,
            +            "description": "<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 461,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to subtract</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 538,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to subtract</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2110,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 562,
            +            "description": "<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 562,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to multiply with the vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 655,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to multiply with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to multiply with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to multiply with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 663,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to multiply with the components of the vector</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 669,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to multiply with the components of the original vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2139,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2148,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2156,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2164,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 754,
            +            "description": "<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 754,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to divide the vector by</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 847,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to divide with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to divide with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to divide with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 855,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to divide the components of the vector by</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 861,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to divide the components of the original vector by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2218,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2227,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2235,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2243,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 959,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "return": {
            +                "description": "magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 959,
            +                    "params": [],
            +                    "return": {
            +                        "description": "magnitude of the vector",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2343,
            +                    "params": [
            +                        {
            +                            "name": "vecT",
            +                            "description": "<p>the vector to return the magnitude of</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the magnitude of vecT",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1007,
            +            "description": "<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n",
            +            "itemtype": "method",
            +            "name": "magSq",
            +            "return": {
            +                "description": "squared magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1061,
            +            "description": "<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "dot",
            +            "return": {
            +                "description": "the dot product",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1061,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2270,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1103,
            +            "description": "<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "cross",
            +            "return": {
            +                "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1103,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2284,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the cross product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1145,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "the distance",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1145,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2299,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1217,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "return": {
            +                "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1217,
            +                    "params": [],
            +                    "return": {
            +                        "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2360,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vector to normalize</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "v normalized to a length of 1",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1287,
            +            "description": "<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "limit",
            +            "params": [
            +                {
            +                    "name": "max",
            +                    "description": "<p>the maximum magnitude for the vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1345,
            +            "description": "<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMag",
            +            "params": [
            +                {
            +                    "name": "len",
            +                    "description": "<p>the new length for this vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1401,
            +            "description": "<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "heading",
            +            "return": {
            +                "description": "the angle of rotation",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1473,
            +            "description": "<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "setHeading",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1498,
            +            "description": "<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1498,
            +                    "params": [
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>the angle of rotation</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2191,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1567,
            +            "description": "<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleBetween",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "return": {
            +                "description": "the angle between (in radians)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1647,
            +            "description": "<p>Linear interpolate the vector to another vector</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1647,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1720,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2314,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the lerped value",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1736,
            +            "description": "<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n",
            +            "itemtype": "method",
            +            "name": "reflect",
            +            "params": [
            +                {
            +                    "name": "surfaceNormal",
            +                    "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1791,
            +            "description": "<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n",
            +            "itemtype": "method",
            +            "name": "array",
            +            "return": {
            +                "description": "an Array with the 3 values",
            +                "type": "Number[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1823,
            +            "description": "<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +            "itemtype": "method",
            +            "name": "equals",
            +            "return": {
            +                "description": "whether the vectors are equals",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1823,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "whether the vectors are equals",
            +                        "type": "Boolean"
            +                    }
            +                },
            +                {
            +                    "line": 1853,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to compare</p>\n",
            +                            "type": "p5.Vector|Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Boolean"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1878,
            +            "description": "<p>Make a new 2D vector from an angle</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngle",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1929,
            +            "description": "<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngles",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "theta",
            +                    "description": "<p>the polar angle, in radians (zero is up)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "phi",
            +                    "description": "<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1978,
            +            "description": "<p>Make a new 2D unit vector from a random angle</p>\n",
            +            "itemtype": "method",
            +            "name": "random2D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2031,
            +            "description": "<p>Make a new random 3D unit vector.</p>\n",
            +            "itemtype": "method",
            +            "name": "random3D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2135,
            +            "description": "<p>Multiplies a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2187,
            +            "description": "<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2214,
            +            "description": "<p>Divides a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2267,
            +            "description": "<p>Calculates the dot product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2281,
            +            "description": "<p>Calculates the cross product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2295,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2310,
            +            "description": "<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2339,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2357,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 37,
            +            "description": "<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "many vertical lines drawn in white, black or grey.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 66,
            +            "description": "<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n",
            +            "itemtype": "method",
            +            "name": "random",
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"
            +            ],
            +            "alt": "100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random",
            +            "overloads": [
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "min",
            +                            "description": "<p>the lower bound (inclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>the upper bound (exclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 119,
            +                    "params": [
            +                        {
            +                            "name": "choices",
            +                            "description": "<p>the array to choose from</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random element from the array",
            +                        "type": "*"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 153,
            +            "description": "<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomGaussian",
            +            "params": [
            +                {
            +                    "name": "mean",
            +                    "description": "<p>the mean</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sd",
            +                    "description": "<p>the standard deviation</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 18,
            +            "description": "<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "acos",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc cosine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc cosine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 53,
            +            "description": "<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "asin",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc sine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc sine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 88,
            +            "description": "<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc tangent is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 123,
            +            "description": "<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan2",
            +            "params": [
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given point",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60 by 10 rect at center of canvas rotates with mouse movements",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 159,
            +            "description": "<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "cos",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the cosine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines form wave patterns, extend-down on left and right side",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 186,
            +            "description": "<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sin",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the sine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines extend down and up from center to form wave pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 213,
            +            "description": "<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n",
            +            "itemtype": "method",
            +            "name": "tan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"
            +            ],
            +            "alt": "vertical black lines end down and up from center to form spike pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 239,
            +            "description": "<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "degrees",
            +            "params": [
            +                {
            +                    "name": "radians",
            +                    "description": "<p>the radians value to convert to degrees</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 262,
            +            "description": "<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "radians",
            +            "params": [
            +                {
            +                    "name": "degrees",
            +                    "description": "<p>the degree value to convert to radians</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 285,
            +            "description": "<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either RADIANS or DEGREES</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"
            +            ],
            +            "alt": "40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 11,
            +            "description": "<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAlign",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"
            +            ],
            +            "alt": "Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "horizAlign",
            +                            "description": "<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "vertAlign",
            +                            "description": "<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n",
            +                            "type": "Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 72,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 81,
            +            "description": "<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "textLeading",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"
            +            ],
            +            "alt": "A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 81,
            +                    "params": [
            +                        {
            +                            "name": "leading",
            +                            "description": "<p>the size in pixels for spacing between lines</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 109,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 118,
            +            "description": "<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "textSize",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 118,
            +                    "params": [
            +                        {
            +                            "name": "theSize",
            +                            "description": "<p>the size of the letters in units of pixels</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 141,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 150,
            +            "description": "<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n",
            +            "itemtype": "method",
            +            "name": "textStyle",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 150,
            +                    "params": [
            +                        {
            +                            "name": "theStyle",
            +                            "description": "<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 178,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 187,
            +            "description": "<p>Calculates and returns the width of any character or text string.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWidth",
            +            "params": [
            +                {
            +                    "name": "theText",
            +                    "description": "<p>the String of characters to measure</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the calculated width",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"
            +            ],
            +            "alt": "Letter P and p5.js are displayed with vertical lines at end.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 222,
            +            "description": "<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAscent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 251,
            +            "description": "<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textDescent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 280,
            +            "description": "<p>Helper function to measure ascent and descent.</p>\n",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 287,
            +            "description": "<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWrap",
            +            "params": [
            +                {
            +                    "name": "wrapStyle",
            +                    "description": "<p>text wrapping style, either WORD or CHAR</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "return": {
            +                "description": "wrapStyle",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 16,
            +            "description": "<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadFont",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "onError",
            +                    "description": "<p>function to be executed if\n                                   an error occurs</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Font\">p5.Font</a> object",
            +                "type": "p5.Font"
            +            },
            +            "example": [
            +                "\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"
            +            ],
            +            "alt": "p5*js in p5's theme dark pink\np5*js in p5's theme dark pink",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 140,
            +            "description": "<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "text",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the alphanumeric\n                                            symbols to be displayed</p>\n",
            +                    "type": "String|Object|Array|Number|Boolean"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 231,
            +            "description": "<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n",
            +            "itemtype": "method",
            +            "name": "textFont",
            +            "return": {
            +                "description": "the current font / p5 Object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 231,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the current font / p5 Object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "font",
            +                            "description": "<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n",
            +                            "type": "Object|String"
            +                        },
            +                        {
            +                            "name": "size",
            +                            "description": "<p>the font size to use</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 24,
            +            "description": "<p>Underlying opentype font implementation</p>\n",
            +            "itemtype": "property",
            +            "name": "font",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 31,
            +            "description": "<p>Returns a tight bounding box for the given text string using this\nfont</p>\n",
            +            "itemtype": "method",
            +            "name": "textBounds",
            +            "params": [
            +                {
            +                    "name": "line",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional) Default is 12.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a rectangle object with properties: x, y, w, h",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "words Lorem ipsum dol go off canvas and contained by white bounding box",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 175,
            +            "description": "<p>Computes an array of points following the path for specified text</p>\n",
            +            "itemtype": "method",
            +            "name": "textToPoints",
            +            "params": [
            +                {
            +                    "name": "txt",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an array of points, each with x, y, alpha (the path angle)",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 10,
            +            "description": "<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n",
            +            "itemtype": "method",
            +            "name": "append",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to append</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>to be added to the Array</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "return": {
            +                "description": "the array that was appended to",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 35,
            +            "description": "<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "arrayCopy",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions",
            +            "overloads": [
            +                {
            +                    "line": 35,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>the source Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "srcPosition",
            +                            "description": "<p>starting position in the source Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "<p>the destination Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dstPosition",
            +                            "description": "<p>starting position in the destination Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "<p>number of Array elements to be copied</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 73,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 112,
            +            "description": "<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n",
            +            "itemtype": "method",
            +            "name": "concat",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first Array to concatenate</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second Array to concatenate</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "concatenated array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 141,
            +            "description": "<p>Reverses the order of an array, maps to Array.reverse()</p>\n",
            +            "itemtype": "method",
            +            "name": "reverse",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to reverse</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "the reversed list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 161,
            +            "description": "<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n",
            +            "itemtype": "method",
            +            "name": "shorten",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to shorten</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "shortened Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 185,
            +            "description": "<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "shuffle",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to shuffle</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "bool",
            +                    "description": "<p>modify passed array</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "shuffled Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 227,
            +            "description": "<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n",
            +            "itemtype": "method",
            +            "name": "sort",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to sort</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of elements to sort, starting from 0</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the sorted list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 273,
            +            "description": "<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n",
            +            "itemtype": "method",
            +            "name": "splice",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to splice into</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to be spliced in</p>\n",
            +                    "type": "Any"
            +                },
            +                {
            +                    "name": "position",
            +                    "description": "<p>in the array from which to insert data</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 308,
            +            "description": "<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n",
            +            "itemtype": "method",
            +            "name": "subset",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to extract from</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>position to begin</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of values to extract</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of extracted elements",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 10,
            +            "description": "<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "float",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>float string to parse</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "floating point representation of string",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "alt": "20 by 20 white ellipse in the center of the canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 44,
            +            "description": "<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "int",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 44,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "<p>the radix to convert to (default: 10)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 88,
            +            "description": "<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "str",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 114,
            +            "description": "<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n",
            +            "itemtype": "method",
            +            "name": "boolean",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "boolean representation of value",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 146,
            +            "description": "<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "byte",
            +            "return": {
            +                "description": "byte representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 146,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "byte representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 168,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of byte representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 182,
            +            "description": "<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "char",
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 182,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 201,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 216,
            +            "description": "<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unchar",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 216,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 232,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 245,
            +            "description": "<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "hex",
            +            "return": {
            +                "description": "hexadecimal string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 245,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 265,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>array of values to parse</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 295,
            +            "description": "<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unhex",
            +            "return": {
            +                "description": "integer representation of hexadecimal value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 295,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of hexadecimal value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representations of hexadecimal value",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 15,
            +            "description": "<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n",
            +            "itemtype": "method",
            +            "name": "join",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>array of Strings to be joined</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>String to be placed between each item</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "joined String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"hello world!\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 43,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "match",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"p5js*\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 83,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "matchAll",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "2d Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 130,
            +            "description": "<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nf",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" middle top, -1321.00\" middle bottom canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 237,
            +            "description": "<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfc",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 237,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                                 decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 311,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfp",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 352,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 373,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfs",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" top middle and \"-1321.00\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 373,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 430,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 451,
            +            "description": "<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n",
            +            "itemtype": "method",
            +            "name": "split",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>the String used to separate the data</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 484,
            +            "description": "<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n",
            +            "itemtype": "method",
            +            "name": "splitTokens",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>list of individual Strings that will be used as\n                         separators</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 537,
            +            "description": "<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "return": {
            +                "description": "a trimmed String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"No new lines here\" displayed center canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 537,
            +                    "params": [
            +                        {
            +                            "name": "str",
            +                            "description": "<p>a String to be trimmed</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "a trimmed String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 557,
            +                    "params": [
            +                        {
            +                            "name": "strs",
            +                            "description": "<p>an Array of Strings to be trimmed</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "an Array of trimmed Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 10,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n",
            +            "itemtype": "method",
            +            "name": "day",
            +            "return": {
            +                "description": "the current day",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current day is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 31,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n",
            +            "itemtype": "method",
            +            "name": "hour",
            +            "return": {
            +                "description": "the current hour",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current hour is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 52,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "minute",
            +            "return": {
            +                "description": "the current minute",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current minute is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 73,
            +            "description": "<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n",
            +            "itemtype": "method",
            +            "name": "millis",
            +            "return": {
            +                "description": "the number of milliseconds since starting the sketch",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"
            +            ],
            +            "alt": "number of milliseconds since sketch has started displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 100,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n",
            +            "itemtype": "method",
            +            "name": "month",
            +            "return": {
            +                "description": "the current month",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current month is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 122,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "second",
            +            "return": {
            +                "description": "the current second",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current second is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 143,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n",
            +            "itemtype": "method",
            +            "name": "year",
            +            "return": {
            +                "description": "the current year",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current year is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 13,
            +            "description": "<p>Draw a plane with given a width and height</p>\n",
            +            "itemtype": "method",
            +            "name": "plane",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 97,
            +            "description": "<p>Draw a box with given width, height and depth</p>\n",
            +            "itemtype": "method",
            +            "name": "box",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "Height",
            +                    "description": "<p>height of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "depth",
            +                    "description": "<p>depth of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 215,
            +            "description": "<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "sphere",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of circle</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>optional number of subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>optional number of subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 419,
            +            "description": "<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cylinder",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cylinder</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottomCap",
            +                    "description": "<p>whether to draw the bottom of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "topCap",
            +                    "description": "<p>whether to draw the top of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 554,
            +            "description": "<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cone",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the bottom surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cone</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cap",
            +                    "description": "<p>whether to draw the base of the cone</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 669,
            +            "description": "<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipsoid",
            +            "params": [
            +                {
            +                    "name": "radiusx",
            +                    "description": "<p>x-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusy",
            +                    "description": "<p>y-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusz",
            +                    "description": "<p>z-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 804,
            +            "description": "<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n",
            +            "itemtype": "method",
            +            "name": "torus",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the whole ring</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tubeRadius",
            +                    "description": "<p>radius of the tube</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 11,
            +            "description": "<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n",
            +            "itemtype": "method",
            +            "name": "orbitControl",
            +            "params": [
            +                {
            +                    "name": "sensitivityX",
            +                    "description": "<p>sensitivity to mouse movement along X axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityY",
            +                    "description": "<p>sensitivity to mouse movement along Y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityZ",
            +                    "description": "<p>sensitivity to scroll movement along Z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Camera orbits around a box when mouse is hold-clicked & then moved.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 145,
            +            "description": "<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n",
            +            "itemtype": "method",
            +            "name": "debugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction",
            +            "overloads": [
            +                {
            +                    "line": 145,
            +                    "params": []
            +                },
            +                {
            +                    "line": 278,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either GRID or AXES</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 283,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "gridSize",
            +                            "description": "<p>size of one side of the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "<p>number of divisions in the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "<p>X axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "<p>Y axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "<p>Z axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "<p>size of axes icon</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 302,
            +                    "params": [
            +                        {
            +                            "name": "gridSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 353,
            +            "description": "<p>Turns off debugMode() in a 3D sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noDebugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 11,
            +            "description": "<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "evenly distributed light across a sphere\nevenly distributed light across a rotating sphere",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>the alpha value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 51,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 57,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 64,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 92,
            +            "description": "<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularColor",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "different specular light sources from top and bottom of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 92,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 145,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 151,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 158,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 177,
            +            "description": "<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "directionalLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "light source on canvas changeable with mouse position",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 177,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 210,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis direction</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 220,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 227,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 280,
            +            "description": "<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "pointLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "spot light on canvas changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 322,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 331,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 341,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 387,
            +            "description": "<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "lights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "the light is partially ambient and partially directional",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 425,
            +            "description": "<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n",
            +            "itemtype": "method",
            +            "name": "lightFalloff",
            +            "params": [
            +                {
            +                    "name": "constant",
            +                    "description": "<p>constant value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "linear",
            +                    "description": "<p>linear value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "quadratic",
            +                    "description": "<p>quadratic value for determining falloff</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two spheres with different falloff values show different intensity of light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 519,
            +            "description": "<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "spotLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Spot light on a sphere which changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 519,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "<p>x axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "<p>y axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "<p>z axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>optional parameter for angle. Defaults to PI/3</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "<p>optional parameter for concentration. Defaults to 100</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 571,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 580,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 590,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 600,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 610,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 634,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 859,
            +            "description": "<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Three white spheres. Each appears as a different\ncolor due to lighting.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 12,
            +            "description": "<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadModel",
            +            "return": {
            +                "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                "type": "p5.Geometry"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d teapot with red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models",
            +            "overloads": [
            +                {
            +                    "line": 12,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>Path of the model to be loaded</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "normalize",
            +                            "description": "<p>If true, scale the model to a\n                                     standardized size when loading</p>\n",
            +                            "type": "Boolean"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "<p>called with event error if\n                                        the model fails to load.</p>\n",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                },
            +                {
            +                    "line": 96,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 179,
            +            "description": "<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 290,
            +            "description": "<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 317,
            +            "description": "<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 344,
            +            "description": "<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 356,
            +            "description": "<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 444,
            +            "description": "<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 588,
            +            "description": "<p>Render a 3d model to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "model",
            +            "params": [
            +                {
            +                    "name": "model",
            +                    "description": "<p>Loaded 3d model to be rendered</p>\n",
            +                    "type": "p5.Geometry"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d octahedron.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 12,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadShader",
            +            "params": [
            +                {
            +                    "name": "vertFilename",
            +                    "description": "<p>path to file containing vertex shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragFilename",
            +                    "description": "<p>path to file containing fragment shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shader files.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 111,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "createShader",
            +            "params": [
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shaders.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 184,
            +            "description": "<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "shader",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "s",
            +                    "description": "<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n",
            +                    "type": "p5.Shader"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 282,
            +            "description": "<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "resetShader",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 368,
            +            "description": "<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "texture",
            +            "params": [
            +                {
            +                    "name": "tex",
            +                    "description": "<p>image to use as texture</p>\n",
            +                    "type": "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using normalized coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 511,
            +            "description": "<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n",
            +            "itemtype": "method",
            +            "name": "textureMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either IMAGE or NORMAL</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using image coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 587,
            +            "description": "<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n",
            +            "itemtype": "method",
            +            "name": "textureWrap",
            +            "params": [
            +                {
            +                    "name": "wrapX",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "wrapY",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "an image of the rocky mountains repeated in mirrored tiles",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 659,
            +            "description": "<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 697,
            +            "description": "<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 697,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 757,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 777,
            +            "description": "<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n",
            +            "itemtype": "method",
            +            "name": "emissiveMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 777,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 809,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 829,
            +            "description": "<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "torus with specular material",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 870,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 882,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 902,
            +            "description": "<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "shininess",
            +            "params": [
            +                {
            +                    "name": "shine",
            +                    "description": "<p>Degree of Shininess.\n                      Defaults to 1.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Shininess on Camera changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 13,
            +            "description": "<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>camera position value on x axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>camera position value on y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>camera position value on z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerX",
            +                    "description": "<p>x coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerY",
            +                    "description": "<p>y coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerZ",
            +                    "description": "<p>z coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upX",
            +                    "description": "<p>x component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upY",
            +                    "description": "<p>y component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upZ",
            +                    "description": "<p>z component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 115,
            +            "description": "<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "params": [
            +                {
            +                    "name": "fovy",
            +                    "description": "<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "aspect",
            +                    "description": "<p>camera frustum aspect ratio</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>frustum near plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>frustum far plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 176,
            +            "description": "<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 236,
            +            "description": "<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 303,
            +            "description": "<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCamera",
            +            "return": {
            +                "description": "The newly created camera object.",
            +                "type": "p5.Camera"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"
            +            ],
            +            "alt": "An example that creates a camera and moves it around the box.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 444,
            +            "description": "<p>camera position value on x axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 472,
            +            "description": "<p>camera position value on y axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 499,
            +            "description": "<p>camera position value on z axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 526,
            +            "description": "<p>x coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 554,
            +            "description": "<p>y coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 582,
            +            "description": "<p>z coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 610,
            +            "description": "<p>x component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 633,
            +            "description": "<p>y component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 656,
            +            "description": "<p>z component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 683,
            +            "description": "<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 801,
            +            "description": "<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 897,
            +            "description": "<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1040,
            +            "description": "<p>Panning rotates the camera view to the left and right.</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1098,
            +            "description": "<p>Tilting rotates the camera view up and down.</p>\n",
            +            "itemtype": "method",
            +            "name": "tilt",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view tilts up and down across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1156,
            +            "description": "<p>Reorients the camera to look at a position in world space.</p>\n",
            +            "itemtype": "method",
            +            "name": "lookAt",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view of rotating 3D cubes changes to look at a new random\npoint every second .",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1223,
            +            "description": "<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1386,
            +            "description": "<p>Move camera along its local axes while maintaining current camera orientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "move",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>amount to move along camera's left-right axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>amount to move along camera's up-down axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>amount to move along camera's forward-backward axis</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1458,
            +            "description": "<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "setPosition",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera position changes as the user presses keys, altering view of a 3D box",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1723,
            +            "description": "<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n",
            +            "itemtype": "method",
            +            "name": "setCamera",
            +            "params": [
            +                {
            +                    "name": "cam",
            +                    "description": "<p>p5.Camera object</p>\n",
            +                    "type": "p5.Camera"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Canvas switches between two camera views, each showing a series of spinning\n3D boxes.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 71,
            +            "description": "<p>computes faces for geometry objects based on the vertices.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeFaces",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 114,
            +            "description": "<p>computes smooth normals per vertex as an average of each\nface.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 153,
            +            "description": "<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n",
            +            "itemtype": "method",
            +            "name": "averageNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 174,
            +            "description": "<p>Averages pole normals.  Used in spherical primitives</p>\n",
            +            "itemtype": "method",
            +            "name": "averagePoleNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 267,
            +            "description": "<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 334,
            +            "description": "<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttributes",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a rotating cube with smoother edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "overloads": [
            +                {
            +                    "line": 334,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "<p>Name of attribute</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>New value of named attribute</p>\n",
            +                            "type": "Boolean"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 473,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>object with key-value pairs</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 306,
            +            "description": "<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n",
            +            "itemtype": "method",
            +            "name": "setUniform",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "uniformName",
            +                    "description": "<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "data",
            +                    "description": "<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n",
            +                    "type": "Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5.Shader",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1,
            +            "class": "p5.sound",
            +            "module": "3D"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 52,
            +            "description": "<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n",
            +            "class": "p5.sound",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 159,
            +            "description": "<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>",
            +            "itemtype": "method",
            +            "name": "getAudioContext",
            +            "return": {
            +                "description": "AudioContext for this sketch",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 198,
            +            "description": "<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>",
            +            "params": [
            +                {
            +                    "name": "element(s)",
            +                    "description": "<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n",
            +                    "type": "Element|Array",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback to invoke when the AudioContext\n                              has started</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that resolves when\n                                     the AudioContext state is 'running'",
            +                "type": "Promise"
            +            },
            +            "itemtype": "method",
            +            "name": "userStartAudio",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 401,
            +            "description": "<p>This module has shims</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 536,
            +            "description": "<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 726,
            +            "description": "<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOutputVolume",
            +            "return": {
            +                "description": "Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 738,
            +            "description": "<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>",
            +            "itemtype": "method",
            +            "name": "outputVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 782,
            +            "description": "<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n",
            +            "itemtype": "property",
            +            "name": "soundOut",
            +            "type": "Object",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 807,
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 811,
            +            "description": "<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "samplerate samples per second",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 825,
            +            "description": "<p>Returns the closest MIDI note value for\na given frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "freqToMidi",
            +            "params": [
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "MIDI note value",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 841,
            +            "description": "<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n",
            +            "itemtype": "method",
            +            "name": "midiToFreq",
            +            "params": [
            +                {
            +                    "name": "midiNote",
            +                    "description": "<p>The number of a MIDI note</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency value of the given MIDI note",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 925,
            +            "description": "<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n",
            +            "itemtype": "method",
            +            "name": "soundFormats",
            +            "params": [
            +                {
            +                    "name": "formats",
            +                    "description": "<p>i.e. 'mp3', 'wav', 'ogg'</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1040,
            +            "description": "<p>Used by Osc and Envelope to chain signal math</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1145,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveSound",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile that you wish to save</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1662,
            +            "description": "<p>Returns true if the sound file finished loading successfully.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLoaded",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1679,
            +            "description": "<p>Play the p5.SoundFile</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule playback to start (in seconds from now).</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) amplitude (volume)\n                                    of playback</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueStart",
            +                    "description": "<p>(optional) cue start time in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) duration of playback in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1787,
            +            "description": "<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "playMode",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>'restart' or 'sustain' or 'untilDone'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1847,
            +            "description": "<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                             seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1905,
            +            "description": "<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) playback volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueLoopStart",
            +                    "description": "<p>(optional) startTime in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) loop duration in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1950,
            +            "description": "<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "setLoop",
            +            "params": [
            +                {
            +                    "name": "Boolean",
            +                    "description": "<p>set looping to true or false</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1976,
            +            "description": "<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1997,
            +            "description": "<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPlaying",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2011,
            +            "description": "<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPaused",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2025,
            +            "description": "<p>Stop soundfile playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            in seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2087,
            +            "description": "<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panValue",
            +                    "description": "<p>Set the stereo panner</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                                seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2131,
            +            "description": "<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2146,
            +            "description": "<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "rate",
            +            "params": [
            +                {
            +                    "name": "playbackRate",
            +                    "description": "<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2239,
            +            "description": "<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "setVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2276,
            +            "description": "<p>Returns the duration of a sound file in seconds.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "The duration of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2293,
            +            "description": "<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n",
            +            "itemtype": "method",
            +            "name": "currentTime",
            +            "return": {
            +                "description": "currentTime of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2308,
            +            "description": "<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n",
            +            "itemtype": "method",
            +            "name": "jump",
            +            "params": [
            +                {
            +                    "name": "cueTime",
            +                    "description": "<p>cueTime of the soundFile in seconds.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>duration in seconds.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2340,
            +            "description": "<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n",
            +            "itemtype": "method",
            +            "name": "channels",
            +            "return": {
            +                "description": "[channels]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2354,
            +            "description": "<p>Return the sample rate of the sound file.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "[sampleRate]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2367,
            +            "description": "<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n",
            +            "itemtype": "method",
            +            "name": "frames",
            +            "return": {
            +                "description": "[sampleCount]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2381,
            +            "description": "<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPeaks",
            +            "params": [
            +                {
            +                    "name": "length",
            +                    "description": "<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of peaks.",
            +                "type": "Float32Array"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2443,
            +            "description": "<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n",
            +            "itemtype": "method",
            +            "name": "reverseBuffer",
            +            "example": [
            +                "\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2497,
            +            "description": "<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2565,
            +            "description": "<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>Audio object that accepts an input</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2590,
            +            "description": "<p>Disconnects the output of this p5sound object.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2604,
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2612,
            +            "description": "<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n",
            +            "itemtype": "method",
            +            "name": "setPath",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to audio file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2630,
            +            "description": "<p>Replace the current Audio Buffer with a new Buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBuffer",
            +            "params": [
            +                {
            +                    "name": "buf",
            +                    "description": "<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2719,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2790,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2817,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2850,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2882,
            +            "description": "<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBlob",
            +            "return": {
            +                "description": "A file-like data object",
            +                "type": "Blob"
            +            },
            +            "example": [
            +                "\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2946,
            +            "description": "<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadSound",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoading",
            +                    "description": "<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a p5.SoundFile",
            +                "type": "SoundFile"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3117,
            +            "description": "<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "snd",
            +                    "description": "<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n",
            +                    "type": "SoundObject|undefined",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n",
            +                    "type": "Number|undefined",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3209,
            +            "description": "<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "channel",
            +                    "description": "<p>Optionally return only channel 0 (left) or 1 (right)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Amplitude as a number between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3264,
            +            "description": "<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleNormalize",
            +            "params": [
            +                {
            +                    "name": "boolean",
            +                    "description": "<p>set normalize to true (1) or false (0)</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3293,
            +            "description": "<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "set",
            +                    "description": "<p>smoothing from 0.0 <= 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3476,
            +            "description": "<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "source",
            +                    "description": "<p>p5.sound object (or web audio API source node)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3501,
            +            "description": "<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n",
            +            "itemtype": "method",
            +            "name": "waveform",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "precision",
            +                    "description": "<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3553,
            +            "description": "<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "analyze",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "scale",
            +                    "description": "<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3650,
            +            "description": "<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getEnergy",
            +            "params": [
            +                {
            +                    "name": "frequency1",
            +                    "description": "<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "frequency2",
            +                    "description": "<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Energy   Energy (volume/amplitude) from\n                            0 and 255.",
            +                "type": "Number"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3739,
            +            "description": "<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getCentroid",
            +            "return": {
            +                "description": "Spectral Centroid Frequency  of the spectral centroid in Hz.",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3826,
            +            "description": "<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3854,
            +            "description": "<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "linAverages",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Number of returned frequency groups</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "linearAverages   Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3889,
            +            "description": "<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "logAverages",
            +            "params": [
            +                {
            +                    "name": "octaveBands",
            +                    "description": "<p>Array of Octave Bands objects for grouping</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "logAverages    Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3925,
            +            "description": "<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOctaveBands",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Specifies the 1/N type of generated octave bands</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fCtr0",
            +                    "description": "<p>Minimum central frequency for the lowest band</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "octaveBands   Array of octave band objects with their bounds",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4168,
            +            "description": "<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>startTime in seconds from now.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>frequency in Hz.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4218,
            +            "description": "<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>Time, in seconds from now.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4238,
            +            "description": "<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)",
            +                "type": "AudioParam"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4271,
            +            "description": "<p>Returns the value of output gain</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmp",
            +            "return": {
            +                "description": "Amplitude value between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4285,
            +            "description": "<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "Frequency",
            +                    "description": "<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Ramp time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen\n                                 at x seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency",
            +                "type": "AudioParam"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4360,
            +            "description": "<p>Returns the value of frequency of oscillator</p>\n",
            +            "itemtype": "method",
            +            "name": "getFreq",
            +            "return": {
            +                "description": "Frequency of oscillator in Hertz",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4373,
            +            "description": "<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4386,
            +            "description": "<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "getType",
            +            "return": {
            +                "description": "type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4399,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4420,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4444,
            +            "description": "<p>Pan between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panning",
            +                    "description": "<p>Number between -1 and 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4460,
            +            "description": "<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "panPosition of oscillator , between Left (-1) and Right (1)",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4494,
            +            "description": "<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "phase",
            +            "params": [
            +                {
            +                    "name": "phase",
            +                    "description": "<p>float between 0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4522,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4543,
            +            "description": "<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with multiplied output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4563,
            +            "description": "<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4767,
            +            "description": "<p>Time until envelope reaches attackLevel</p>\n",
            +            "itemtype": "property",
            +            "name": "attackTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4772,
            +            "description": "<p>Level once attack is complete.</p>\n",
            +            "itemtype": "property",
            +            "name": "attackLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4778,
            +            "description": "<p>Time until envelope reaches decayLevel.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4784,
            +            "description": "<p>Level after decay. The envelope will sustain here until it is released.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4790,
            +            "description": "<p>Duration of the release portion of the envelope.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4796,
            +            "description": "<p>Level at the end of the release.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4833,
            +            "description": "<p>Reset the envelope with a series of time/value pairs.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "attackLevel",
            +                    "description": "<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayLevel",
            +                    "description": "<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Release Time (in seconds)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseLevel",
            +                    "description": "<p>Amplitude</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4895,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4964,
            +            "description": "<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRange",
            +            "params": [
            +                {
            +                    "name": "aLevel",
            +                    "description": "<p>attack level (defaults to 1)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rLevel",
            +                    "description": "<p>release level (defaults to 0)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5037,
            +            "description": "<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "inputs",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5055,
            +            "description": "<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n",
            +            "itemtype": "method",
            +            "name": "setExp",
            +            "params": [
            +                {
            +                    "name": "isExp",
            +                    "description": "<p>true is exponential, false is linear</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5078,
            +            "description": "<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5148,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5256,
            +            "description": "<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5350,
            +            "description": "<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n",
            +            "itemtype": "method",
            +            "name": "ramp",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>When to trigger the ramp</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v",
            +                    "description": "<p>Target value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v2",
            +                    "description": "<p>Second target value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5460,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5479,
            +            "description": "<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5498,
            +            "description": "<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5657,
            +            "description": "<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'white', 'pink' or 'brown'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Noise",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5871,
            +            "description": "<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n",
            +            "itemtype": "method",
            +            "name": "width",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Pulse",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6066,
            +            "itemtype": "property",
            +            "name": "input",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6070,
            +            "itemtype": "property",
            +            "name": "output",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6075,
            +            "itemtype": "property",
            +            "name": "stream",
            +            "type": "MediaStream|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6080,
            +            "itemtype": "property",
            +            "name": "mediaStream",
            +            "type": "MediaStreamAudioSourceNode|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6085,
            +            "itemtype": "property",
            +            "name": "currentSource",
            +            "type": "Number|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6090,
            +            "description": "<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n",
            +            "itemtype": "property",
            +            "name": "enabled",
            +            "type": "Boolean",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6098,
            +            "description": "<p>Input amplitude, connect to it by default but not to master out</p>\n",
            +            "itemtype": "property",
            +            "name": "amplitude",
            +            "type": "p5.Amplitude",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6114,
            +            "description": "<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call on\n                                  success.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6171,
            +            "description": "<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6191,
            +            "description": "<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>An object that accepts audio input,\n                        such as an FFT</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6216,
            +            "description": "<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6234,
            +            "description": "<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Volume level (between 0.0 and 1.0)",
            +                "type": "Number"
            +            },
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6257,
            +            "description": "<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>ramp time (optional)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6280,
            +            "description": "<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n",
            +            "itemtype": "method",
            +            "name": "getSources",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>This optional callback receives the error\n                                   message as its argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6340,
            +            "description": "<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "setSource",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>position of input source in the array</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6462,
            +            "description": "<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6478,
            +            "description": "<p>Set the output volume of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts until rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tFromNow",
            +                    "description": "<p>schedule this event to happen in tFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6502,
            +            "description": "<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n",
            +            "itemtype": "method",
            +            "name": "chain",
            +            "params": [
            +                {
            +                    "name": "arguments",
            +                    "description": "<p>Chain together multiple sound objects</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6525,
            +            "description": "<p>Adjust the dry/wet value.</p>\n",
            +            "itemtype": "method",
            +            "name": "drywet",
            +            "params": [
            +                {
            +                    "name": "fade",
            +                    "description": "<p>The desired drywet value (0 - 1.0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6542,
            +            "description": "<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6557,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6719,
            +            "description": "<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "biquadFilter",
            +            "type": "DelayNode",
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6742,
            +            "description": "<p>Filter an audio signal according to a set\nof filter parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6760,
            +            "description": "<p>Set the frequency and the resonance of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance (Q) from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6781,
            +            "description": "<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Filter Frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value  Returns the current frequency value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6811,
            +            "description": "<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "res",
            +            "params": [
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value Returns the current res value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6838,
            +            "description": "<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n",
            +            "itemtype": "method",
            +            "name": "gain",
            +            "params": [
            +                {
            +                    "name": "gain",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns the current or updated gain value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6864,
            +            "description": "<p>Toggle function. Switches between the specified type and allpass</p>\n",
            +            "itemtype": "method",
            +            "name": "toggle",
            +            "return": {
            +                "description": "[Toggle value]",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6884,
            +            "description": "<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "t",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7198,
            +            "description": "<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n",
            +            "itemtype": "property",
            +            "name": "bands",
            +            "type": "Array",
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7239,
            +            "description": "<p>Process an input by connecting it to the EQ</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Audio source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7629,
            +            "description": "<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n",
            +            "itemtype": "property",
            +            "name": "panner",
            +            "type": "AudioNode",
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7654,
            +            "description": "<p>Connect an audio sorce</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Input source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7668,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7687,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7694,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7701,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7753,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "orient",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7772,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7779,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7786,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7838,
            +            "description": "<p>Set the rolloff factor and max distance</p>\n",
            +            "itemtype": "method",
            +            "name": "setFalloff",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7852,
            +            "description": "<p>Maxium distance between the source and the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "maxDist",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7869,
            +            "description": "<p>How quickly the volume is reduced as the source moves away from the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "rollof",
            +            "params": [
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7989,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "leftDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7999,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "rightDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8049,
            +            "description": "<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "lowPass",
            +                    "description": "<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8094,
            +            "description": "<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n",
            +            "itemtype": "method",
            +            "name": "delayTime",
            +            "params": [
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8116,
            +            "description": "<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n",
            +            "itemtype": "method",
            +            "name": "feedback",
            +            "params": [
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "return": {
            +                "description": "Feedback value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8148,
            +            "description": "<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "cutoffFreq",
            +                    "description": "<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8170,
            +            "description": "<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'pingPong' (1) or 'default' (0)</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8223,
            +            "description": "<p>Set the output level of the delay effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8234,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8242,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8409,
            +            "description": "<p>Connect a source to the reverb, and assign reverb parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8446,
            +            "description": "<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8482,
            +            "description": "<p>Set the output level of the reverb effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8493,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8501,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8621,
            +            "description": "<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "convolverNode",
            +            "type": "ConvolverNode",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8645,
            +            "description": "<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n",
            +            "itemtype": "property",
            +            "name": "impulses",
            +            "type": "Array",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8737,
            +            "description": "<p>Connect a source to the convolver.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8786,
            +            "description": "<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n",
            +            "itemtype": "method",
            +            "name": "addImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8808,
            +            "description": "<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8831,
            +            "description": "<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleImpulse",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8885,
            +            "description": "<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n",
            +            "itemtype": "method",
            +            "name": "createConvolver",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Convolver"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9084,
            +            "description": "<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9173,
            +            "description": "<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n",
            +            "itemtype": "property",
            +            "name": "sequence",
            +            "type": "Array",
            +            "class": "p5.Phrase",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9263,
            +            "description": "<p>Set the tempo of this part, in Beats Per Minute.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9278,
            +            "description": "<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBPM",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9291,
            +            "description": "<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9311,
            +            "description": "<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9333,
            +            "description": "<p>Tell the part to stop looping.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9349,
            +            "description": "<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9363,
            +            "description": "<p>Pause the part. Playback will resume\nfrom the current step.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9379,
            +            "description": "<p>Add a p5.Phrase to this Part.</p>\n",
            +            "itemtype": "method",
            +            "name": "addPhrase",
            +            "params": [
            +                {
            +                    "name": "phrase",
            +                    "description": "<p>reference to a p5.Phrase</p>\n",
            +                    "type": "p5.Phrase"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9406,
            +            "description": "<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n",
            +            "itemtype": "method",
            +            "name": "removePhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9424,
            +            "description": "<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9442,
            +            "description": "<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n",
            +            "itemtype": "method",
            +            "name": "replaceSequence",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9473,
            +            "description": "<p>Set the function that will be called at every step. This will clear the previous function.</p>\n",
            +            "itemtype": "method",
            +            "name": "onStep",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9542,
            +            "description": "<p>Start playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9555,
            +            "description": "<p>Stop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9569,
            +            "description": "<p>Pause playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9581,
            +            "description": "<p>Loop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9594,
            +            "description": "<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9628,
            +            "description": "<p>Set the tempo for all parts in the score</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9729,
            +            "description": "<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n",
            +            "itemtype": "property",
            +            "name": "bpm",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9750,
            +            "description": "<p>number of quarter notes in a measure (defaults to 4)</p>\n",
            +            "itemtype": "property",
            +            "name": "timeSignature",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9770,
            +            "description": "<p>length of the loops interval</p>\n",
            +            "itemtype": "property",
            +            "name": "interval",
            +            "type": "Number|String",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9787,
            +            "description": "<p>how many times the callback has been called so far</p>\n",
            +            "itemtype": "property",
            +            "name": "iterations",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9800,
            +            "description": "<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n",
            +            "itemtype": "property",
            +            "name": "musicalTimeMode",
            +            "type": "Boolean",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9808,
            +            "description": "<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9816,
            +            "description": "<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n",
            +            "itemtype": "property",
            +            "name": "maxIterations",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9826,
            +            "description": "<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9841,
            +            "description": "<p>Start the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a starting time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9860,
            +            "description": "<p>Stop the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a stopping time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9878,
            +            "description": "<p>Pause the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a pausing time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9896,
            +            "description": "<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n",
            +            "itemtype": "method",
            +            "name": "syncedStart",
            +            "params": [
            +                {
            +                    "name": "otherLoop",
            +                    "description": "<p>a p5.SoundLoop to sync with</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Start the loops in sync after timeFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10068,
            +            "description": "<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n",
            +            "itemtype": "property",
            +            "name": "compressor",
            +            "type": "AudioNode",
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10084,
            +            "description": "<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Sound source to be connected</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10112,
            +            "description": "<p>Set the paramters of a compressor.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10152,
            +            "description": "<p>Get current attack or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "attack",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10178,
            +            "description": "<p>Get current knee or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "knee",
            +            "params": [
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10204,
            +            "description": "<p>Get current ratio or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "ratio",
            +            "params": [
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10228,
            +            "description": "<p>Get current threshold or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "threshold",
            +            "params": [
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10252,
            +            "description": "<p>Get current release or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "release",
            +            "params": [
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10277,
            +            "description": "<p>Return the current reduction value</p>\n",
            +            "itemtype": "method",
            +            "name": "reduction",
            +            "return": {
            +                "description": "Value of the amount of gain reduction that is applied to the signal",
            +                "type": "Number"
            +            },
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10419,
            +            "description": "<p>isDetected is set to true when a peak is detected.</p>\n",
            +            "itemtype": "attribute",
            +            "name": "isDetected",
            +            "type": "Boolean",
            +            "default": "false",
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10432,
            +            "description": "<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n",
            +            "itemtype": "method",
            +            "name": "update",
            +            "params": [
            +                {
            +                    "name": "fftObject",
            +                    "description": "<p>A p5.FFT object</p>\n",
            +                    "type": "p5.FFT"
            +                }
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10470,
            +            "description": "<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onPeak",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "val",
            +                    "description": "<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10676,
            +            "description": "<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10703,
            +            "description": "<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n",
            +            "itemtype": "method",
            +            "name": "record",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that will be\n                              called once the recording completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10739,
            +            "description": "<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10864,
            +            "description": "<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "WaveShaperNode",
            +            "type": "AudioNode",
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10883,
            +            "description": "<p>Process a sound source, optionally specify amount and oversample values.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10900,
            +            "description": "<p>Set the amount and oversample of the waveshaper distortion.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10923,
            +            "description": "<p>Return the distortion amount, typically between 0-1.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmount",
            +            "return": {
            +                "description": "Unbounded distortion amount.\n                 Normal values range from 0-1.",
            +                "type": "Number"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10937,
            +            "description": "<p>Return the oversampling.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOversample",
            +            "return": {
            +                "description": "Oversample can either be 'none', '2x', or '4x'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11055,
            +            "description": "<p>Connect a source to the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11070,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11084,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11098,
            +            "description": "<p>Set the output level of the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11181,
            +            "description": "<p>Connect to p5 objects or Web Audio Nodes</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11194,
            +            "description": "<p>Disconnect from soundOut</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11322,
            +            "description": "<p>Getters and Setters</p>\n",
            +            "itemtype": "property",
            +            "name": "attack",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11328,
            +            "itemtype": "property",
            +            "name": "decay",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11333,
            +            "itemtype": "property",
            +            "name": "sustain",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11338,
            +            "itemtype": "property",
            +            "name": "release",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11379,
            +            "description": "<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11431,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11478,
            +            "description": "<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11516,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11544,
            +            "description": "<p>MonoSynth amp</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>desired volume</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Time to reach new volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "new volume value",
            +                "type": "Number"
            +            },
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11564,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11578,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11592,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11742,
            +            "description": "<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n",
            +            "itemtype": "property",
            +            "name": "notes",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11755,
            +            "description": "<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n",
            +            "itemtype": "property",
            +            "name": "polyvalue",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11761,
            +            "description": "<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n",
            +            "itemtype": "property",
            +            "name": "AudioVoice",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11800,
            +            "description": "<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11849,
            +            "description": "<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteADSR",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>Midi note on which ADSR should be set.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11881,
            +            "description": "<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11909,
            +            "description": "<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteAttack",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)/</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12021,
            +            "description": "<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteRelease",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12105,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12119,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12133,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        }
            +    ],
            +    "warnings": [
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:120"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:216"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:316"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:457"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:1001"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:223"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:248"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/validate_params.js:336"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:219"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:259"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:185"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:264"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:358"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:398"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:493"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:67"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:293"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:460"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:524"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:583"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:668"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:733"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:826"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:84"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:120"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:138"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:79"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:129"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:160"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:228"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:372"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:390"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:405"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:421"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:500"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:550"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:586"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:660"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:691"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:713"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:42"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:47"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:154"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:189"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:246"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:292"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:403"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:454"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:510"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:551"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:639"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:678"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:725"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:763"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:70"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:7"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:34"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:87"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:137"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:158"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:179"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:200"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:267"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:309"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:379"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:408"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:448"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:490"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:326"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:134"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:192"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:290"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:391"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:497"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:193"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:232"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:304"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:342"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:416"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:455"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:494"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:101"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1560"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1622"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1726"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1765"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1885"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2778"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:23"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:46"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:69"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:135"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:201"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:285"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:330"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:428"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:515"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:546"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:604"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:64"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:103"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:308"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:106"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:132"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:164"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:233"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:271"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:615"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:696"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:772"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:841"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:926"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:979"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:1025"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:71"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:151"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:94"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:413"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:18"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:301"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:569"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:88"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:152"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:261"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:296"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:346"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:400"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:437"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:548"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:665"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:738"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:900"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:941"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:972"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1017"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1052"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1089"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:173"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:307"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:566"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:602"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:674"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:583"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1393"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:85"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:148"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:240"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:352"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:545"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:597"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:638"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:896"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:960"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1009"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1055"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1242"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1305"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:40"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:191"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:295"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.XML.js:9"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:33"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:72"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:116"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:182"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:269"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:316"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:371"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:409"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:464"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:560"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:612"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:646"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:701"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:745"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/math.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:178"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/p5.Vector.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:37"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:153"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:123"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:159"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:186"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:213"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:285"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:320"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:335"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:350"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:118"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:150"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:187"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:16"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:140"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/p5.Font.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/conversion.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:237"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:373"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:451"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:537"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:73"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:143"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/3d_primitives.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:353"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:177"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:280"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:387"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:425"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:519"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:588"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:12"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:282"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:587"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:659"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:697"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:777"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:829"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:902"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:176"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:236"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:357"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:444"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:472"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:499"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:526"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:554"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:582"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:610"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:683"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:801"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:897"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1040"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1098"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1156"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1386"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1458"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1723"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:334"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:644"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:749"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Shader.js:306"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:115"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:158"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:191"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:236"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:250"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:456"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:471"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:556"
            +        },
            +        {
            +            "message": "replacing incorrect tag: params with param",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2882"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4360"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4386"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4460"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:6280"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:8116"
            +        },
            +        {
            +            "message": "Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.",
            +            "line": " src/color/color_conversion.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:19"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to RGBA.",
            +            "line": " src/color/color_conversion.js:45"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to HSBA.",
            +            "line": " src/color/color_conversion.js:100"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.",
            +            "line": " src/color/color_conversion.js:123"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSBA.",
            +            "line": " src/color/color_conversion.js:187"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:226"
            +        },
            +        {
            +            "message": "Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.",
            +            "line": " src/color/p5.Color.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.",
            +            "line": " src/color/p5.Color.js:427"
            +        },
            +        {
            +            "message": "Missing item type\nCSS named colors.",
            +            "line": " src/color/p5.Color.js:446"
            +        },
            +        {
            +            "message": "Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.",
            +            "line": " src/color/p5.Color.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nFull color string patterns. The capture groups are necessary.",
            +            "line": " src/color/p5.Color.js:613"
            +        },
            +        {
            +            "message": "Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.",
            +            "line": " src/color/p5.Color.js:750"
            +        },
            +        {
            +            "message": "Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.",
            +            "line": " src/color/p5.Color.js:960"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/fes_core.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.",
            +            "line": " src/core/friendly_errors/fes_core.js:915"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/file_errors.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/sketch_reader.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/stacktrace.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nGiven an Error object, extract the most information from it.",
            +            "line": " src/core/friendly_errors/stacktrace.js:34"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/validate_params.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).",
            +            "line": " src/core/shape/2d_primitives.js:16"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current framerate.",
            +            "line": " src/core/environment.js:305"
            +        },
            +        {
            +            "message": "Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.",
            +            "line": " src/core/environment.js:315"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/helpers.js:1"
            +        },
            +        {
            +            "message": "Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing",
            +            "line": " src/core/init.js:4"
            +        },
            +        {
            +            "message": "Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.",
            +            "line": " src/core/internationalization.js:30"
            +        },
            +        {
            +            "message": "Missing item type\nSet up our translation function, with loaded languages",
            +            "line": " src/core/internationalization.js:126"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a list of languages we have translations loaded for",
            +            "line": " src/core/internationalization.js:171"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current language selected for translation",
            +            "line": " src/core/internationalization.js:178"
            +        },
            +        {
            +            "message": "Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.",
            +            "line": " src/core/internationalization.js:185"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/legacy.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/core/p5.Element.js:827"
            +        },
            +        {
            +            "message": "Missing item type\nResize our canvas element.",
            +            "line": " src/core/p5.Renderer.js:99"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to check font type (system or otf)",
            +            "line": " src/core/p5.Renderer.js:415"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178",
            +            "line": " src/core/p5.Renderer.js:467"
            +        },
            +        {
            +            "message": "Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer",
            +            "line": " src/core/p5.Renderer2D.js:7"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.",
            +            "line": " src/core/p5.Renderer2D.js:402"
            +        },
            +        {
            +            "message": "Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.",
            +            "line": " src/core/shim.js:18"
            +        },
            +        {
            +            "message": "Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign",
            +            "line": " src/core/shim.js:39"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()",
            +            "line": " src/data/p5.TypedDict.js:197"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:387"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:425"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:536"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for select and selectAll",
            +            "line": " src/dom/dom.js:127"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for getElement and getElements.",
            +            "line": " src/dom/dom.js:142"
            +        },
            +        {
            +            "message": "Missing item type\nHelpers for create methods.",
            +            "line": " src/dom/dom.js:309"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:450"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1164"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1257"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1296"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3232"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3298"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3360"
            +        },
            +        {
            +            "message": "Missing item type\n_updatePAccelerations updates the pAcceleration values",
            +            "line": " src/events/acceleration.js:124"
            +        },
            +        {
            +            "message": "Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.",
            +            "line": " src/events/keyboard.js:298"
            +        },
            +        {
            +            "message": "Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.",
            +            "line": " src/events/keyboard.js:384"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.",
            +            "line": " src/image/filters.js:3"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the pixel buffer for a canvas",
            +            "line": " src/image/filters.js:24"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.",
            +            "line": " src/image/filters.js:60"
            +        },
            +        {
            +            "message": "Missing item type\nModifies pixels RGBA values to values contained in the data object.",
            +            "line": " src/image/filters.js:81"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData",
            +            "line": " src/image/filters.js:101"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a blank ImageData object.",
            +            "line": " src/image/filters.js:121"
            +        },
            +        {
            +            "message": "Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.",
            +            "line": " src/image/filters.js:136"
            +        },
            +        {
            +            "message": "Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:189"
            +        },
            +        {
            +            "message": "Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:223"
            +        },
            +        {
            +            "message": "Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.",
            +            "line": " src/image/filters.js:246"
            +        },
            +        {
            +            "message": "Missing item type\nSets each pixel to its inverse value. No parameter is used.",
            +            "line": " src/image/filters.js:262"
            +        },
            +        {
            +            "message": "Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation",
            +            "line": " src/image/filters.js:277"
            +        },
            +        {
            +            "message": "Missing item type\nreduces the bright areas in an image",
            +            "line": " src/image/filters.js:309"
            +        },
            +        {
            +            "message": "Missing item type\nincreases the bright areas in an image",
            +            "line": " src/image/filters.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.",
            +            "line": " src/image/image.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for loading GIF-based images",
            +            "line": " src/image/loading_displaying.js:162"
            +        },
            +        {
            +            "message": "Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.",
            +            "line": " src/image/loading_displaying.js:597"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.",
            +            "line": " src/image/p5.Image.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for animating GIF-based images with time",
            +            "line": " src/image/p5.Image.js:222"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/image/p5.Image.js:253"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.",
            +            "line": " src/io/files.js:1789"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.",
            +            "line": " src/io/files.js:1857"
            +        },
            +        {
            +            "message": "Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.",
            +            "line": " src/io/files.js:1890"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.",
            +            "line": " src/io/files.js:1902"
            +        },
            +        {
            +            "message": "Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "line": " src/io/p5.Table.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nMultiplies a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2135"
            +        },
            +        {
            +            "message": "Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2187"
            +        },
            +        {
            +            "message": "Missing item type\nDivides a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2214"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the dot product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2267"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the cross product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2281"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).",
            +            "line": " src/math/p5.Vector.js:2295"
            +        },
            +        {
            +            "message": "Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.",
            +            "line": " src/math/p5.Vector.js:2310"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)",
            +            "line": " src/math/p5.Vector.js:2339"
            +        },
            +        {
            +            "message": "Missing item type\nNormalize the vector to length 1 (make it a unit vector).",
            +            "line": " src/math/p5.Vector.js:2357"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to measure ascent and descent.",
            +            "line": " src/typography/attributes.js:280"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.",
            +            "line": " src/typography/p5.Font.js:273"
            +        },
            +        {
            +            "message": "Missing item type\nReturns an opentype path for the supplied string and position.",
            +            "line": " src/typography/p5.Font.js:288"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/3d_primitives.js:301"
            +        },
            +        {
            +            "message": "Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.",
            +            "line": " src/webgl/3d_primitives.js:955"
            +        },
            +        {
            +            "message": "Missing item type\nDraw a line given two points",
            +            "line": " src/webgl/3d_primitives.js:1393"
            +        },
            +        {
            +            "message": "Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1",
            +            "line": " src/webgl/loading.js:179"
            +        },
            +        {
            +            "message": "Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.",
            +            "line": " src/webgl/loading.js:290"
            +        },
            +        {
            +            "message": "Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.",
            +            "line": " src/webgl/loading.js:317"
            +        },
            +        {
            +            "message": "Missing item type\nThis function matches the `query` at the provided `offset`",
            +            "line": " src/webgl/loading.js:344"
            +        },
            +        {
            +            "message": "Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.",
            +            "line": " src/webgl/loading.js:356"
            +        },
            +        {
            +            "message": "Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`",
            +            "line": " src/webgl/loading.js:444"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:947"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:978"
            +        },
            +        {
            +            "message": "Missing item type\nCreate a 2D array for establishing stroke connections",
            +            "line": " src/webgl/p5.Geometry.js:212"
            +        },
            +        {
            +            "message": "Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU",
            +            "line": " src/webgl/p5.Geometry.js:233"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/p5.Matrix.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPRIVATE",
            +            "line": " src/webgl/p5.Matrix.js:722"
            +        },
            +        {
            +            "message": "Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.",
            +            "line": " src/webgl/p5.RenderBuffer.js:12"
            +        },
            +        {
            +            "message": "Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nEnd shape drawing and render vertices to screen.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:129"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:169"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:248"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:268"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:302"
            +        },
            +        {
            +            "message": "Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:59"
            +        },
            +        {
            +            "message": "Missing item type\nDraws buffers given a geometry key ID",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:110"
            +        },
            +        {
            +            "message": "Missing item type\nmodel view, projection, & normal\nmatrices",
            +            "line": " src/webgl/p5.RendererGL.js:117"
            +        },
            +        {
            +            "message": "Missing item type\n[background description]",
            +            "line": " src/webgl/p5.RendererGL.js:586"
            +        },
            +        {
            +            "message": "Missing item type\n[resize description]",
            +            "line": " src/webgl/p5.RendererGL.js:860"
            +        },
            +        {
            +            "message": "Missing item type\nclears color and depth buffers\nwith r,g,b,a",
            +            "line": " src/webgl/p5.RendererGL.js:890"
            +        },
            +        {
            +            "message": "Missing item type\n[translate description]",
            +            "line": " src/webgl/p5.RendererGL.js:924"
            +        },
            +        {
            +            "message": "Missing item type\nScales the Model View Matrix by a vector",
            +            "line": " src/webgl/p5.RendererGL.js:943"
            +        },
            +        {
            +            "message": "Missing item type\nturn a two dimensional array into one dimensional array",
            +            "line": " src/webgl/p5.RendererGL.js:1366"
            +        },
            +        {
            +            "message": "Missing item type\nturn a p5.Vector Array into a one dimensional number array",
            +            "line": " src/webgl/p5.RendererGL.js:1403"
            +        },
            +        {
            +            "message": "Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.",
            +            "line": " src/webgl/p5.RendererGL.js:1421"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:1"
            +        },
            +        {
            +            "message": "Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/",
            +            "line": " lib/addons/p5.sound.js:52"
            +        },
            +        {
            +            "message": "Missing item type\nThis module has shims",
            +            "line": " lib/addons/p5.sound.js:401"
            +        },
            +        {
            +            "message": "Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats",
            +            "line": " lib/addons/p5.sound.js:536"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:807"
            +        },
            +        {
            +            "message": "Missing item type\nUsed by Osc and Envelope to chain signal math",
            +            "line": " lib/addons/p5.sound.js:1040"
            +        },
            +        {
            +            "message": "Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.",
            +            "line": " lib/addons/p5.sound.js:1542"
            +        },
            +        {
            +            "message": "Missing item type\nStop playback on all of this soundfile's sources.",
            +            "line": " lib/addons/p5.sound.js:2056"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:2604"
            +        },
            +        {
            +            "message": "Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade",
            +            "line": " lib/addons/p5.sound.js:6455"
            +        },
            +        {
            +            "message": "Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter",
            +            "line": " lib/addons/p5.sound.js:6462"
            +        },
            +        {
            +            "message": "Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ",
            +            "line": " lib/addons/p5.sound.js:7009"
            +        },
            +        {
            +            "message": "Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.",
            +            "line": " lib/addons/p5.sound.js:8508"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.",
            +            "line": " lib/addons/p5.sound.js:8659"
            +        },
            +        {
            +            "message": "Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string",
            +            "line": " lib/addons/p5.sound.js:9808"
            +        },
            +        {
            +            "message": "Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached",
            +            "line": " lib/addons/p5.sound.js:9826"
            +        },
            +        {
            +            "message": "Missing item type\ncallback invoked when the recording is over",
            +            "line": " lib/addons/p5.sound.js:10660"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release",
            +            "line": " lib/addons/p5.sound.js:11995"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.min.js:1"
            +        }
            +    ],
            +    "consts": {
            +        "LABEL": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "FALLBACK": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "RGB": [
            +            "p5.colorMode"
            +        ],
            +        "HSB": [
            +            "p5.colorMode"
            +        ],
            +        "HSL": [
            +            "p5.colorMode"
            +        ],
            +        "CHORD": [
            +            "p5.arc"
            +        ],
            +        "PIE": [
            +            "p5.arc"
            +        ],
            +        "OPEN": [
            +            "p5.arc"
            +        ],
            +        "CENTER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode",
            +            "p5.textAlign"
            +        ],
            +        "RADIUS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode"
            +        ],
            +        "CORNER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "CORNERS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "ROUND": [
            +            "p5.strokeCap",
            +            "p5.strokeJoin"
            +        ],
            +        "SQUARE": [
            +            "p5.strokeCap"
            +        ],
            +        "PROJECT": [
            +            "p5.strokeCap"
            +        ],
            +        "MITER": [
            +            "p5.strokeJoin"
            +        ],
            +        "BEVEL": [
            +            "p5.strokeJoin"
            +        ],
            +        "POINTS": [
            +            "p5.beginShape"
            +        ],
            +        "LINES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_FAN": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "QUADS": [
            +            "p5.beginShape"
            +        ],
            +        "QUAD_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "TESS": [
            +            "p5.beginShape"
            +        ],
            +        "CLOSE": [
            +            "p5.endShape"
            +        ],
            +        "ARROW": [
            +            "p5.cursor"
            +        ],
            +        "CROSS": [
            +            "p5.cursor"
            +        ],
            +        "HAND": [
            +            "p5.cursor"
            +        ],
            +        "MOVE": [
            +            "p5.cursor"
            +        ],
            +        "TEXT": [
            +            "p5.cursor"
            +        ],
            +        "P2D": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "WEBGL": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "BLEND": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DARKEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "LIGHTEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DIFFERENCE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "MULTIPLY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "EXCLUSION": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SCREEN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REPLACE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "OVERLAY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "HARD_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SOFT_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DODGE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "BURN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "ADD": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REMOVE": [
            +            "p5.blendMode"
            +        ],
            +        "SUBTRACT": [
            +            "p5.blendMode"
            +        ],
            +        "VIDEO": [
            +            "p5.createCapture"
            +        ],
            +        "AUDIO": [
            +            "p5.createCapture"
            +        ],
            +        "THRESHOLD": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "GRAY": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "OPAQUE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "INVERT": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "POSTERIZE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "ERODE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "DILATE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "BLUR": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "NORMAL": [
            +            "p5.Image.blend",
            +            "p5.blend",
            +            "p5.textStyle",
            +            "p5.textureMode"
            +        ],
            +        "RADIANS": [
            +            "p5.angleMode"
            +        ],
            +        "DEGREES": [
            +            "p5.angleMode"
            +        ],
            +        "LEFT": [
            +            "p5.textAlign"
            +        ],
            +        "RIGHT": [
            +            "p5.textAlign"
            +        ],
            +        "TOP": [
            +            "p5.textAlign"
            +        ],
            +        "BOTTOM": [
            +            "p5.textAlign"
            +        ],
            +        "BASELINE": [
            +            "p5.textAlign"
            +        ],
            +        "ITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "BOLD": [
            +            "p5.textStyle"
            +        ],
            +        "BOLDITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "WORD": [
            +            "p5.textWrap"
            +        ],
            +        "CHAR": [
            +            "p5.textWrap"
            +        ],
            +        "IMAGE": [
            +            "p5.textureMode"
            +        ],
            +        "CLAMP": [
            +            "p5.textureWrap"
            +        ],
            +        "REPEAT": [
            +            "p5.textureWrap"
            +        ],
            +        "MIRROR": [
            +            "p5.textureWrap"
            +        ]
            +    }
            +}
            \ No newline at end of file
            diff --git a/dist/hi/reference/data.min.json b/dist/hi/reference/data.min.json
            new file mode 100644
            index 0000000000..b719e76314
            --- /dev/null
            +++ b/dist/hi/reference/data.min.json
            @@ -0,0 +1 @@
            +{"project":{"name":"p5","description":"[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)","version":"1.4.1","url":"https://github.com/processing/p5.js#readme"},"files":{"src/accessibility/color_namer.js":{"name":"src/accessibility/color_namer.js","modules":{"Environment":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/describe.js":{"name":"src/accessibility/describe.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/gridOutput.js":{"name":"src/accessibility/gridOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/outputs.js":{"name":"src/accessibility/outputs.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/textOutput.js":{"name":"src/accessibility/textOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/color_conversion.js":{"name":"src/color/color_conversion.js","modules":{"Color Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/creating_reading.js":{"name":"src/color/creating_reading.js","modules":{"Creating & Reading":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/p5.Color.js":{"name":"src/color/p5.Color.js","modules":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{}},"src/color/setting.js":{"name":"src/color/setting.js","modules":{"Setting":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/fes_core.js":{"name":"src/core/friendly_errors/fes_core.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/file_errors.js":{"name":"src/core/friendly_errors/file_errors.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/sketch_reader.js":{"name":"src/core/friendly_errors/sketch_reader.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/stacktrace.js":{"name":"src/core/friendly_errors/stacktrace.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/validate_params.js":{"name":"src/core/friendly_errors/validate_params.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/2d_primitives.js":{"name":"src/core/shape/2d_primitives.js","modules":{"2D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/attributes.js":{"name":"src/core/shape/attributes.js","modules":{"Attributes":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/curves.js":{"name":"src/core/shape/curves.js","modules":{"Curves":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/vertex.js":{"name":"src/core/shape/vertex.js","modules":{"Vertex":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/constants.js":{"name":"src/core/constants.js","modules":{"Constants":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/environment.js":{"name":"src/core/environment.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/helpers.js":{"name":"src/core/helpers.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/init.js":{"name":"src/core/init.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/internationalization.js":{"name":"src/core/internationalization.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/legacy.js":{"name":"src/core/legacy.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/main.js":{"name":"src/core/main.js","modules":{"Structure":1},"classes":{"p5":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Element.js":{"name":"src/core/p5.Element.js","modules":{"DOM":1},"classes":{"p5.Element":1},"fors":{"p5.Element":1},"namespaces":{}},"src/core/p5.Graphics.js":{"name":"src/core/p5.Graphics.js","modules":{"Rendering":1},"classes":{"p5.Graphics":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer.js":{"name":"src/core/p5.Renderer.js","modules":{},"classes":{"p5.Renderer":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer2D.js":{"name":"src/core/p5.Renderer2D.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/reference.js":{"name":"src/core/reference.js","modules":{"Foundation":1},"classes":{},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{}},"src/core/rendering.js":{"name":"src/core/rendering.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shim.js":{"name":"src/core/shim.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/structure.js":{"name":"src/core/structure.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/transform.js":{"name":"src/core/transform.js","modules":{"Transform":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/local_storage.js":{"name":"src/data/local_storage.js","modules":{"LocalStorage":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/p5.TypedDict.js":{"name":"src/data/p5.TypedDict.js","modules":{"Dictionary":1},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"namespaces":{}},"src/dom/dom.js":{"name":"src/dom/dom.js","modules":{},"classes":{"p5.MediaElement":1,"p5.File":1},"fors":{"p5":1,"p5.Element":1},"namespaces":{}},"src/events/acceleration.js":{"name":"src/events/acceleration.js","modules":{"Acceleration":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/keyboard.js":{"name":"src/events/keyboard.js","modules":{"Keyboard":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/mouse.js":{"name":"src/events/mouse.js","modules":{"Mouse":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/touch.js":{"name":"src/events/touch.js","modules":{"Touch":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/filters.js":{"name":"src/image/filters.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/image/image.js":{"name":"src/image/image.js","modules":{"Image":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/loading_displaying.js":{"name":"src/image/loading_displaying.js","modules":{"Loading & Displaying":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/p5.Image.js":{"name":"src/image/p5.Image.js","modules":{},"classes":{"p5.Image":1},"fors":{},"namespaces":{}},"src/image/pixels.js":{"name":"src/image/pixels.js","modules":{"Pixels":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/io/files.js":{"name":"src/io/files.js","modules":{"Input":1,"Output":1},"classes":{"p5.PrintWriter":1},"fors":{"p5":1},"namespaces":{}},"src/io/p5.Table.js":{"name":"src/io/p5.Table.js","modules":{"Table":1},"classes":{"p5.Table":1},"fors":{},"namespaces":{}},"src/io/p5.TableRow.js":{"name":"src/io/p5.TableRow.js","modules":{},"classes":{"p5.TableRow":1},"fors":{},"namespaces":{}},"src/io/p5.XML.js":{"name":"src/io/p5.XML.js","modules":{},"classes":{"p5.XML":1},"fors":{},"namespaces":{}},"src/math/calculation.js":{"name":"src/math/calculation.js","modules":{"Calculation":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/math.js":{"name":"src/math/math.js","modules":{"Vector":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/noise.js":{"name":"src/math/noise.js","modules":{"Noise":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/p5.Vector.js":{"name":"src/math/p5.Vector.js","modules":{},"classes":{"p5.Vector":1},"fors":{},"namespaces":{}},"src/math/random.js":{"name":"src/math/random.js","modules":{"Random":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/trigonometry.js":{"name":"src/math/trigonometry.js","modules":{"Trigonometry":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/attributes.js":{"name":"src/typography/attributes.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/loading_displaying.js":{"name":"src/typography/loading_displaying.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/p5.Font.js":{"name":"src/typography/p5.Font.js","modules":{},"classes":{"p5.Font":1},"fors":{},"namespaces":{}},"src/utilities/array_functions.js":{"name":"src/utilities/array_functions.js","modules":{"Array Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/conversion.js":{"name":"src/utilities/conversion.js","modules":{"Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/string_functions.js":{"name":"src/utilities/string_functions.js","modules":{"String Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/time_date.js":{"name":"src/utilities/time_date.js","modules":{"Time & Date":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/3d_primitives.js":{"name":"src/webgl/3d_primitives.js","modules":{"3D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/interaction.js":{"name":"src/webgl/interaction.js","modules":{"Interaction":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/light.js":{"name":"src/webgl/light.js","modules":{"Lights":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/loading.js":{"name":"src/webgl/loading.js","modules":{"3D Models":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/material.js":{"name":"src/webgl/material.js","modules":{"Material":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Camera.js":{"name":"src/webgl/p5.Camera.js","modules":{"Camera":1},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{}},"src/webgl/p5.Geometry.js":{"name":"src/webgl/p5.Geometry.js","modules":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Matrix.js":{"name":"src/webgl/p5.Matrix.js","modules":{},"classes":{"p5.Matrix":1},"fors":{},"namespaces":{}},"src/webgl/p5.RenderBuffer.js":{"name":"src/webgl/p5.RenderBuffer.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Immediate.js":{"name":"src/webgl/p5.RendererGL.Immediate.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Retained.js":{"name":"src/webgl/p5.RendererGL.Retained.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.js":{"name":"src/webgl/p5.RendererGL.js","modules":{},"classes":{"p5.RendererGL":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Shader.js":{"name":"src/webgl/p5.Shader.js","modules":{},"classes":{"p5.Shader":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Texture.js":{"name":"src/webgl/p5.Texture.js","modules":{},"classes":{"p5.Texture":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/text.js":{"name":"src/webgl/text.js","modules":{},"classes":{"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{},"namespaces":{}},"lib/addons/p5.sound.js":{"name":"lib/addons/p5.sound.js","modules":{"p5.sound":1},"classes":{"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{}},"lib/addons/p5.sound.min.js":{"name":"lib/addons/p5.sound.min.js","modules":{},"classes":{},"fors":{},"namespaces":{}}},"modules":{"Environment":{"name":"Environment","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Environment","file":"src/accessibility/color_namer.js","line":1,"requires":["core"]},"Color":{"name":"Color","submodules":{"Color Conversion":1,"Creating & Reading":1,"Setting":1},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{},"file":"src/color/p5.Color.js","line":14},"Color Conversion":{"name":"Color Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/color_conversion.js","line":1,"requires":["core"]},"Creating & Reading":{"name":"Creating & Reading","submodules":{},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/p5.Color.js","line":14,"requires":["core","constants"],"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"},"Setting":{"name":"Setting","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/setting.js","line":1,"requires":["core","constants"]},"Shape":{"name":"Shape","submodules":{"2D Primitives":1,"Curves":1,"Vertex":1,"3D Primitives":1,"3D Models":1},"elements":{},"classes":{"p5.Geometry":1,"p5.Matrix":1},"fors":{"p5":1},"namespaces":{},"file":"src/webgl/p5.Matrix.js","line":19},"2D Primitives":{"name":"2D Primitives","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/2d_primitives.js","line":1,"requires":["core","constants"]},"Attributes":{"name":"Attributes","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/core/shape/attributes.js","line":1,"requires":["core","constants"]},"Curves":{"name":"Curves","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/curves.js","line":1,"requires":["core"]},"Vertex":{"name":"Vertex","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/vertex.js","line":1,"requires":["core","constants"]},"Constants":{"name":"Constants","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Constants","file":"src/core/constants.js","line":1},"Structure":{"name":"Structure","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"IO","file":"src/core/main.js","line":1,"requires":["constants"]},"DOM":{"name":"DOM","submodules":{},"elements":{},"classes":{"p5.Element":1,"p5.MediaElement":1,"p5.File":1},"fors":{"p5.Element":1,"p5":1},"namespaces":{},"module":"DOM","file":"src/dom/dom.js","line":3533,"description":"<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n","requires":["p5"]},"Rendering":{"name":"Rendering","submodules":{"undefined":1},"elements":{},"classes":{"p5.RendererGL":1,"p5.Graphics":1,"p5.Renderer":1},"fors":{"p5":1},"namespaces":{},"module":"Rendering","file":"src/webgl/p5.RendererGL.js","line":603,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"},"Foundation":{"name":"Foundation","submodules":{},"elements":{},"classes":{"JSON":1,"console":1},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{},"module":"Foundation","file":"src/core/reference.js","line":1},"Transform":{"name":"Transform","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Transform","file":"src/core/transform.js","line":1,"requires":["core","constants"]},"Data":{"name":"Data","submodules":{"LocalStorage":1,"Dictionary":1,"Array Functions":1,"Conversion":1,"String Functions":1},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5":1,"p5.TypedDict":1},"namespaces":{},"file":"src/data/p5.TypedDict.js","line":410},"LocalStorage":{"name":"LocalStorage","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/local_storage.js","line":1,"requires":["core\n\nThis module defines the p5 methods for working with local storage"]},"Dictionary":{"name":"Dictionary","submodules":{},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"requires":["core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."],"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"},"Events":{"name":"Events","submodules":{"Acceleration":1,"Keyboard":1,"Mouse":1,"Touch":1},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"Acceleration":{"name":"Acceleration","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/acceleration.js","line":1,"requires":["core"]},"Keyboard":{"name":"Keyboard","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/keyboard.js","line":1,"requires":["core"]},"Mouse":{"name":"Mouse","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/mouse.js","line":1,"requires":["core","constants"]},"Touch":{"name":"Touch","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/touch.js","line":1,"requires":["core"]},"Image":{"name":"Image","submodules":{"Pixels":1},"elements":{},"classes":{"p5.Image":1},"fors":{"p5":1},"namespaces":{},"module":"Image","file":"src/image/p5.Image.js","line":21,"requires":["core"],"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"},"Loading & Displaying":{"name":"Loading & Displaying","submodules":{},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/typography/p5.Font.js","line":13,"requires":["core"],"description":"<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"},"Pixels":{"name":"Pixels","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Image","namespace":"","file":"src/image/pixels.js","line":1,"requires":["core"]},"IO":{"name":"IO","submodules":{"Structure":1,"Input":1,"Output":1,"Table":1,"Time & Date":1},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1,"p5.Table":1,"p5.TableRow":1,"p5.XML":1},"fors":{"p5":1},"namespaces":{},"file":"src/io/p5.XML.js","line":9},"Input":{"name":"Input","submodules":{},"elements":{},"classes":{"p5.XML":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.XML.js","line":9,"requires":["core"],"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"},"Output":{"name":"Output","submodules":{},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/files.js","line":1200,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"},"Table":{"name":"Table","submodules":{},"elements":{},"classes":{"p5.Table":1,"p5.TableRow":1},"fors":{},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.TableRow.js","line":9,"requires":["core"],"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"},"Math":{"name":"Math","submodules":{"Calculation":1,"Vector":1,"Noise":1,"Random":1,"Trigonometry":1},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"namespaces":{},"file":"src/math/p5.Vector.js","line":10},"Calculation":{"name":"Calculation","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/calculation.js","line":1,"requires":["core"]},"Vector":{"name":"Vector","submodules":{},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/p5.Vector.js","line":10,"requires":["core"],"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"},"Noise":{"name":"Noise","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/noise.js","line":14,"requires":["core"]},"Random":{"name":"Random","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/random.js","line":1,"requires":["core"]},"Trigonometry":{"name":"Trigonometry","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/trigonometry.js","line":1,"requires":["core","constants"]},"Typography":{"name":"Typography","submodules":{"Attributes":1,"Loading & Displaying":1},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"namespaces":{},"file":"src/typography/p5.Font.js","line":13},"Array Functions":{"name":"Array Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/array_functions.js","line":1,"requires":["core"]},"Conversion":{"name":"Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/conversion.js","line":1,"requires":["core"]},"String Functions":{"name":"String Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/string_functions.js","line":1,"requires":["core"]},"Time & Date":{"name":"Time & Date","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/utilities/time_date.js","line":1,"requires":["core"]},"3D Primitives":{"name":"3D Primitives","submodules":{},"elements":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"requires":["core","p5.Geometry"],"description":"<p>p5 Geometry class</p>\n"},"3D":{"name":"3D","submodules":{"Interaction":1,"Lights":1,"Material":1,"Camera":1},"elements":{},"classes":{"p5.Camera":1,"p5.Shader":1,"p5.Texture":1,"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{},"file":"src/webgl/text.js","line":260},"Interaction":{"name":"Interaction","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/interaction.js","line":1,"requires":["core"]},"Lights":{"name":"Lights","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/light.js","line":1,"requires":["core"]},"3D Models":{"name":"3D Models","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/loading.js","line":1,"requires":["core","p5.Geometry"]},"Material":{"name":"Material","submodules":{},"elements":{},"classes":{"p5.Shader":1,"p5.Texture":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Texture.js","line":12,"requires":["core"],"description":"<p>This module defines the p5.Shader class</p>\n"},"Camera":{"name":"Camera","submodules":{},"elements":{},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"requires":["core"],"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"},"p5.sound":{"name":"p5.sound","submodules":{},"elements":{},"classes":{"p5.sound":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{},"module":"p5.sound","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>","tag":"main","itemtype":"main"}},"classes":{"p5":{"name":"p5","shortname":"p5","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/core/main.js","line":13,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n","is_constructor":1,"params":[{"name":"sketch","description":"<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n","type":"Function"},{"name":"node","description":"<p>element to attach canvas to</p>\n","type":"HTMLElement","optional":true}],"return":{"description":"a p5 instance","type":"P5"}},"p5.Color":{"name":"p5.Color","shortname":"p5.Color","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Color","submodule":"Creating & Reading","namespace":"","file":"src/color/p5.Color.js","line":14,"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n","is_constructor":1},"p5.Element":{"name":"p5.Element","shortname":"p5.Element","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/core/p5.Element.js","line":9,"description":"<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Graphics":{"name":"p5.Graphics","shortname":"p5.Graphics","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Graphics.js","line":10,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"},{"name":"renderer","description":"<p>the renderer to use, either P2D or WEBGL</p>\n","type":"Constant"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Renderer":{"name":"p5.Renderer","shortname":"p5.Renderer","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Renderer.js","line":10,"description":"<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true},{"name":"isMainCanvas","description":"<p>whether we're using it as main canvas</p>\n","type":"Boolean","optional":true}]},"JSON":{"name":"JSON","shortname":"JSON","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"console":{"name":"console","shortname":"console","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"p5.TypedDict":{"name":"p5.TypedDict","shortname":"p5.TypedDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":82,"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n","is_constructor":1},"p5.StringDict":{"name":"p5.StringDict","shortname":"p5.StringDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":394,"description":"<p>A simple Dictionary class for Strings.</p>\n","extends":"p5.TypedDict"},"p5.NumberDict":{"name":"p5.NumberDict","shortname":"p5.NumberDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"description":"<p>A simple Dictionary class for Numbers.</p>\n","is_constructor":1,"extends":"p5.TypedDict"},"p5.MediaElement":{"name":"p5.MediaElement","shortname":"p5.MediaElement","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":2377,"description":"<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"}]},"p5.File":{"name":"p5.File","shortname":"p5.File","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":3533,"description":"<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n","is_constructor":1,"params":[{"name":"file","description":"<p>File that is wrapped</p>\n","type":"File"}]},"p5.Image":{"name":"p5.Image","shortname":"p5.Image","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Image","submodule":"Image","namespace":"","file":"src/image/p5.Image.js","line":21,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n","example":["\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"],"is_constructor":1,"params":[{"name":"width","description":"","type":"Number"},{"name":"height","description":"","type":"Number"}]},"p5.PrintWriter":{"name":"p5.PrintWriter","shortname":"p5.PrintWriter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/io/files.js","line":1200,"params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"","type":"String","optional":true}]},"p5.Table":{"name":"p5.Table","shortname":"p5.Table","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.Table.js","line":33,"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n","is_constructor":1,"params":[{"name":"rows","description":"<p>An array of p5.TableRow objects</p>\n","type":"p5.TableRow[]","optional":true}]},"p5.TableRow":{"name":"p5.TableRow","shortname":"p5.TableRow","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.TableRow.js","line":9,"description":"<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n","is_constructor":1,"params":[{"name":"str","description":"<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n","type":"String","optional":true},{"name":"separator","description":"<p>comma separated values (csv) by default</p>\n","type":"String","optional":true}]},"p5.XML":{"name":"p5.XML","shortname":"p5.XML","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Input","namespace":"","file":"src/io/p5.XML.js","line":9,"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n","is_constructor":1,"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed"},"p5.Vector":{"name":"p5.Vector","shortname":"p5.Vector","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Math","submodule":"Vector","namespace":"","file":"src/math/p5.Vector.js","line":10,"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n","is_constructor":1,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"],"alt":"2 white ellipses. One center-left the other bottom right and off canvas"},"p5.Font":{"name":"p5.Font","shortname":"p5.Font","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Typography","submodule":"Loading & Displaying","namespace":"","file":"src/typography/p5.Font.js","line":13,"description":"<p>Base class for font handling</p>\n","is_constructor":1,"params":[{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Camera":{"name":"p5.Camera","shortname":"p5.Camera","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Camera","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n","params":[{"name":"rendererGL","description":"<p>instance of WebGL renderer</p>\n","type":"RendererGL"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes."},"p5.Geometry":{"name":"p5.Geometry","shortname":"p5.Geometry","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Shape","submodule":"3D Primitives","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"description":"<p>p5 Geometry class</p>\n","is_constructor":1,"params":[{"name":"detailX","description":"<p>number of vertices along the x-axis.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of vertices along the y-axis.</p>\n","type":"Integer","optional":true},{"name":"callback","description":"<p>function to call upon object instantiation.</p>\n","type":"Function","optional":true}]},"p5.Shader":{"name":"p5.Shader","shortname":"p5.Shader","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Material","namespace":"","file":"src/webgl/p5.Shader.js","line":11,"description":"<p>Shader class for WEBGL Mode</p>\n","is_constructor":1,"params":[{"name":"renderer","description":"<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n","type":"p5.RendererGL"},{"name":"vertSrc","description":"<p>source code for the vertex shader (as a string)</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader (as a string)</p>\n","type":"String"}]},"p5.sound":{"name":"p5.sound","shortname":"p5.sound","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":""},"p5.SoundFile":{"name":"p5.SoundFile","shortname":"p5.SoundFile","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":1405,"description":"<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true},{"name":"whileLoadingCallback","description":"<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"]},"p5.Amplitude":{"name":"p5.Amplitude","shortname":"p5.Amplitude","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3022,"description":"<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n","is_constructor":1,"params":[{"name":"smoothing","description":"<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"]},"p5.FFT":{"name":"p5.FFT","shortname":"p5.FFT","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3347,"description":"<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>","is_constructor":1,"params":[{"name":"smoothing","description":"<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n","type":"Number","optional":true},{"name":"bins","description":"<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"]},"p5.Oscillator":{"name":"p5.Oscillator","shortname":"p5.Oscillator","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4060,"description":"<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>","is_constructor":1,"params":[{"name":"freq","description":"<p>frequency defaults to 440Hz</p>\n","type":"Number","optional":true},{"name":"type","description":"<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"]},"p5.SinOsc":{"name":"p5.SinOsc","shortname":"p5.SinOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4602,"description":"<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.TriOsc":{"name":"p5.TriOsc","shortname":"p5.TriOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4629,"description":"<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SawOsc":{"name":"p5.SawOsc","shortname":"p5.SawOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4656,"description":"<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SqrOsc":{"name":"p5.SqrOsc","shortname":"p5.SqrOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4683,"description":"<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.Envelope":{"name":"p5.Envelope","shortname":"p5.Envelope","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4721,"description":"<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>","is_constructor":1,"example":["\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"]},"p5.Noise":{"name":"p5.Noise","shortname":"p5.Noise","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5620,"description":"<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"type","description":"<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n","type":"String"}]},"p5.Pulse":{"name":"p5.Pulse","shortname":"p5.Pulse","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5779,"description":"<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"freq","description":"<p>Frequency in oscillations per second (Hz)</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"]},"p5.AudioIn":{"name":"p5.AudioIn","shortname":"p5.AudioIn","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6015,"description":"<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>","is_constructor":1,"params":[{"name":"errorCallback","description":"<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"]},"p5.Effect":{"name":"p5.Effect","shortname":"p5.Effect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6423,"description":"<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n","is_constructor":1,"params":[{"name":"ac","description":"<p>Reference to the audio context of the p5 object</p>\n","type":"Object","optional":true},{"name":"input","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"output","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"_drywet","description":"<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n","type":"Object","optional":true},{"name":"wet","description":"<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n","type":"AudioNode","optional":true}]},"p5.Filter":{"name":"p5.Filter","shortname":"p5.Filter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6628,"description":"<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"type","description":"<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"]},"p5.LowPass":{"name":"p5.LowPass","shortname":"p5.LowPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6914,"description":"<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.HighPass":{"name":"p5.HighPass","shortname":"p5.HighPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6938,"description":"<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.BandPass":{"name":"p5.BandPass","shortname":"p5.BandPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6962,"description":"<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.EQ":{"name":"p5.EQ","shortname":"p5.EQ","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7105,"description":"<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect","params":[{"name":"_eqsize","description":"<p>Constructor will accept 3 or 8, defaults to 3</p>\n","type":"Number","optional":true}],"return":{"description":"p5.EQ object","type":"Object"},"example":["\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"]},"p5.Panner3D":{"name":"p5.Panner3D","shortname":"p5.Panner3D","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7602,"description":"<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n","is_constructor":1},"p5.Delay":{"name":"p5.Delay","shortname":"p5.Delay","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7926,"description":"<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"]},"p5.Reverb":{"name":"p5.Reverb","shortname":"p5.Reverb","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8308,"description":"<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"]},"p5.Convolver":{"name":"p5.Convolver","shortname":"p5.Convolver","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8549,"description":"<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>","extends":"p5.Effect","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call when loading succeeds</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"]},"p5.Phrase":{"name":"p5.Phrase","shortname":"p5.Phrase","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9103,"description":"<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>","is_constructor":1,"params":[{"name":"name","description":"<p>Name so that you can access the Phrase.</p>\n","type":"String"},{"name":"callback","description":"<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n","type":"Function"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"example":["\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"]},"p5.Part":{"name":"p5.Part","shortname":"p5.Part","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9185,"description":"<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>","is_constructor":1,"params":[{"name":"steps","description":"<p>Steps in the part</p>\n","type":"Number","optional":true},{"name":"tatums","description":"<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"]},"p5.Score":{"name":"p5.Score","shortname":"p5.Score","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9493,"description":"<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n","is_constructor":1,"params":[{"name":"parts","description":"<p>One or multiple parts, to be played in sequence.</p>\n","type":"p5.Part","optional":true,"multiple":true}]},"p5.SoundLoop":{"name":"p5.SoundLoop","shortname":"p5.SoundLoop","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9673,"description":"<p>SoundLoop</p>\n","is_constructor":1,"params":[{"name":"callback","description":"<p>this function will be called on each iteration of theloop</p>\n","type":"Function"},{"name":"interval","description":"<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n","type":"Number|String","optional":true}],"example":["\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"]},"p5.Compressor":{"name":"p5.Compressor","shortname":"p5.Compressor","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10036,"description":"<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect"},"p5.PeakDetect":{"name":"p5.PeakDetect","shortname":"p5.PeakDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10312,"description":"<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>","is_constructor":1,"params":[{"name":"freq1","description":"<p>lowFrequency - defaults to 20Hz</p>\n","type":"Number","optional":true},{"name":"freq2","description":"<p>highFrequency - defaults to 20000 Hz</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n","type":"Number","optional":true},{"name":"framesPerPeak","description":"<p>Defaults to 20.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"]},"p5.SoundRecorder":{"name":"p5.SoundRecorder","shortname":"p5.SoundRecorder","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10559,"description":"<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>","is_constructor":1,"example":["\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"]},"p5.Distortion":{"name":"p5.Distortion","shortname":"p5.Distortion","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10816,"description":"<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}]},"p5.Gain":{"name":"p5.Gain","shortname":"p5.Gain","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10973,"description":"<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n","is_constructor":1,"example":["\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"]},"p5.AudioVoice":{"name":"p5.AudioVoice","shortname":"p5.AudioVoice","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11149,"description":"<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n","is_constructor":1},"p5.MonoSynth":{"name":"p5.MonoSynth","shortname":"p5.MonoSynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11247,"description":"<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n","is_constructor":1,"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"]},"p5.OnsetDetect":{"name":"p5.OnsetDetect","shortname":"p5.OnsetDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11624,"description":"<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n","is_constructor":1,"params":[{"name":"freqLow","description":"<p>Low frequency</p>\n","type":"Number"},{"name":"freqHigh","description":"<p>High frequency</p>\n","type":"Number"},{"name":"threshold","description":"<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n","type":"Number"},{"name":"callback","description":"<p>Function to call when an onset is detected</p>\n","type":"Function"}]},"p5.PolySynth":{"name":"p5.PolySynth","shortname":"p5.PolySynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n","is_constructor":1,"params":[{"name":"synthVoice","description":"<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n","type":"Number","optional":true},{"name":"maxVoices","description":"<p>Number of voices, defaults to 8;</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"]}},"elements":{},"classitems":[{"file":"src/accessibility/describe.js","line":18,"description":"<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n","itemtype":"method","name":"describe","params":[{"name":"text","description":"<p>description of the canvas</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/describe.js","line":114,"description":"<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n","itemtype":"method","name":"describeElement","params":[{"name":"name","description":"<p>name of the element</p>\n","type":"String"},{"name":"text","description":"<p>description of the element</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":10,"description":"<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"textOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":88,"description":"<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"gridOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/color/color_conversion.js","line":8,"description":"<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":19,"description":"<p>Convert an HSBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":45,"description":"<p>Convert an HSBA array to RGBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":100,"description":"<p>Convert an HSLA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":123,"description":"<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":187,"description":"<p>Convert an RGBA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":226,"description":"<p>Convert an RGBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/creating_reading.js","line":16,"description":"<p>Extracts the alpha value from a color or pixel array.</p>\n","itemtype":"method","name":"alpha","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the alpha value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":43,"description":"<p>Extracts the blue value from a color or pixel array.</p>\n","itemtype":"method","name":"blue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the blue value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":69,"description":"<p>Extracts the HSB brightness value from a color or pixel array.</p>\n","itemtype":"method","name":"brightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the brightness value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":113,"description":"<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n","itemtype":"method","name":"color","return":{"description":"resulting color","type":"p5.Color"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading","overloads":[{"line":113,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"return":{"description":"resulting color","type":"p5.Color"}},{"line":257,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"return":{"description":"","type":"p5.Color"}},{"line":269,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"return":{"description":"","type":"p5.Color"}},{"line":275,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"return":{"description":"","type":"p5.Color"}},{"line":282,"params":[{"name":"color","description":"","type":"p5.Color"}],"return":{"description":"","type":"p5.Color"}}]},{"file":"src/color/creating_reading.js","line":297,"description":"<p>Extracts the green value from a color or pixel array.</p>\n","itemtype":"method","name":"green","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the green value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":325,"description":"<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n","itemtype":"method","name":"hue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the hue","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":359,"description":"<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n","itemtype":"method","name":"lerpColor","params":[{"name":"c1","description":"<p>interpolate from this color</p>\n","type":"p5.Color"},{"name":"c2","description":"<p>interpolate to this color</p>\n","type":"p5.Color"},{"name":"amt","description":"<p>number between 0 and 1</p>\n","type":"Number"}],"return":{"description":"interpolated color","type":"p5.Color"},"example":["\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":449,"description":"<p>Extracts the HSL lightness value from a color or pixel array.</p>\n","itemtype":"method","name":"lightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the lightness","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":478,"description":"<p>Extracts the red value from a color or pixel array.</p>\n","itemtype":"method","name":"red","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the red value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":517,"description":"<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n","itemtype":"method","name":"saturation","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the saturation value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":51,"description":"<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n","itemtype":"method","name":"toString","params":[{"name":"format","description":"<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n","type":"String","optional":true}],"return":{"description":"the formatted string","type":"String"},"example":["\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":254,"description":"<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setRed","params":[{"name":"red","description":"<p>the new red value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":281,"description":"<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setGreen","params":[{"name":"green","description":"<p>the new green value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":304,"description":"<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setBlue","params":[{"name":"blue","description":"<p>the new blue value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":327,"description":"<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setAlpha","params":[{"name":"alpha","description":"<p>the new alpha value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":396,"description":"<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":427,"description":"<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":446,"description":"<p>CSS named colors.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":600,"description":"<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":613,"description":"<p>Full color string patterns. The capture groups are necessary.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":960,"description":"<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/setting.js","line":13,"description":"<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n","itemtype":"method","name":"background","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":13,"params":[{"name":"color","description":"<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n","type":"p5.Color"}],"chainable":1},{"line":130,"params":[{"name":"colorstring","description":"<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n","type":"String"},{"name":"a","description":"<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":140,"params":[{"name":"gray","description":"<p>specifies a value between white and black</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":147,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current color\n                       mode)</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":159,"params":[{"name":"values","description":"<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":166,"params":[{"name":"image","description":"<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n","type":"p5.Image"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":179,"description":"<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n","itemtype":"method","name":"clear","chainable":1,"example":["\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"],"params":[{"name":"r","description":"<p>normalized red val.</p>\n","type":"Number"},{"name":"g","description":"<p>normalized green val.</p>\n","type":"Number"},{"name":"b","description":"<p>normalized blue val.</p>\n","type":"Number"},{"name":"a","description":"<p>normalized alpha val.</p>\n","type":"Number"}],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":229,"description":"<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n","itemtype":"method","name":"colorMode","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":229,"params":[{"name":"mode","description":"<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n","type":"Constant"},{"name":"max","description":"<p>range for all values</p>\n","type":"Number","optional":true}],"chainable":1},{"line":306,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"max1","description":"<p>range for the red or hue depending on the\n                             current color mode</p>\n","type":"Number"},{"name":"max2","description":"<p>range for the green or saturation depending\n                             on the current color mode</p>\n","type":"Number"},{"name":"max3","description":"<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n","type":"Number"},{"name":"maxA","description":"<p>range for the alpha</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":350,"description":"<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n","itemtype":"method","name":"fill","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":350,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":475,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":481,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":488,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":495,"params":[{"name":"color","description":"<p>the fill color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":507,"description":"<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noFill","chainable":1,"example":["\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":547,"description":"<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noStroke","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":585,"description":"<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n","itemtype":"method","name":"stroke","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":585,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":722,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":728,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":735,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":742,"params":[{"name":"color","description":"<p>the stroke color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":755,"description":"<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n","itemtype":"method","name":"erase","params":[{"name":"strengthFill","description":"<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true},{"name":"strengthStroke","description":"<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":836,"description":"<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n","itemtype":"method","name":"noErase","chainable":1,"example":["\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/core/friendly_errors/fes_core.js","line":1,"requires":["core\n\nThis is the main file for the Friendly Error System (FES)","containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters","(2) _friendlyFileLoadError","(3) _friendlyError","(4) helpForMisusedAtTopLevelCode","or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this","there's also a file stacktrace.js","which contains the code\nto parse the error stack","borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions","including the call\nsequence of each function","please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/fes_core.js","line":915,"description":"<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n","class":"p5","module":"Color"},{"file":"src/core/friendly_errors/file_errors.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/sketch_reader.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/stacktrace.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/validate_params.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/shape/2d_primitives.js","line":16,"description":"<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n","class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":102,"description":"<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n","itemtype":"method","name":"arc","params":[{"name":"x","description":"<p>x-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"w","description":"<p>width of the arc's ellipse by default</p>\n","type":"Number"},{"name":"h","description":"<p>height of the arc's ellipse by default</p>\n","type":"Number"},{"name":"start","description":"<p>angle to start the arc, specified in radians</p>\n","type":"Number"},{"name":"stop","description":"<p>angle to stop the arc, specified in radians</p>\n","type":"Number"},{"name":"mode","description":"<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n","type":"Constant","optional":true},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":235,"description":"<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n","itemtype":"method","name":"ellipse","chainable":1,"example":["\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":235,"params":[{"name":"x","description":"<p>x-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the ellipse.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the ellipse.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":261,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}]}]},{"file":"src/core/shape/2d_primitives.js","line":277,"description":"<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n","itemtype":"method","name":"circle","params":[{"name":"x","description":"<p>x-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"d","description":"<p>diameter of the circle.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":340,"description":"<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n","itemtype":"method","name":"line","chainable":1,"example":["\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":340,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"}],"chainable":1},{"line":379,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":404,"description":"<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n","itemtype":"method","name":"point","chainable":1,"example":["\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":404,"params":[{"name":"x","description":"<p>the x-coordinate</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate</p>\n","type":"Number"},{"name":"z","description":"<p>the z-coordinate (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":455,"params":[{"name":"coordinate_vector","description":"<p>the coordinate vector</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":483,"description":"<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n","itemtype":"method","name":"quad","chainable":1,"example":["\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":483,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>the x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>the y-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"<p>the x-coordinate of the fourth point</p>\n","type":"Number"},{"name":"y4","description":"<p>the y-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction</p>\n","type":"Integer","optional":true}],"chainable":1},{"line":512,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>the z-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>the z-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"","type":"Integer","optional":true},{"name":"detailY","description":"","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":556,"description":"<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"rect","chainable":1,"example":["\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":556,"params":[{"name":"x","description":"<p>x-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the rectangle.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the rectangle.</p>\n","type":"Number","optional":true},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":608,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction (for WebGL mode)</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction (for WebGL mode)</p>\n","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":623,"description":"<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"square","params":[{"name":"x","description":"<p>x-coordinate of the square.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the square.</p>\n","type":"Number"},{"name":"s","description":"<p>side size of the square.</p>\n","type":"Number"},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":713,"description":"<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n","itemtype":"method","name":"triangle","params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate of the third point</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/attributes.js","line":12,"description":"<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"ellipseMode","params":[{"name":"mode","description":"<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"],"alt":"60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":81,"description":"<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"noSmooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses to left & right of center, black background","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":115,"description":"<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"rectMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"],"alt":"50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":184,"description":"<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"smooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses one left one right of center. On black.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":219,"description":"<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeCap","params":[{"name":"cap","description":"<p>either ROUND, SQUARE or PROJECT</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"],"alt":"3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":259,"description":"<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeJoin","params":[{"name":"join","description":"<p>either MITER, BEVEL, ROUND</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"],"alt":"Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":331,"description":"<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n","itemtype":"method","name":"strokeWeight","params":[{"name":"weight","description":"<p>the weight of the stroke (in pixels)</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"],"alt":"3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/curves.js","line":13,"description":"<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n","itemtype":"method","name":"bezier","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"],"alt":"stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":13,"params":[{"name":"x1","description":"<p>x-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the second anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1},{"line":62,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":92,"description":"<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n","itemtype":"method","name":"bezierDetail","params":[{"name":"detail","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"],"alt":"stretched black s-shape with a low level of bezier detail","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":130,"description":"<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n","itemtype":"method","name":"bezierPoint","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the value of the Bezier at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"],"alt":"10 points plotted on a given bezier at equal distances.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":185,"description":"<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n","itemtype":"method","name":"bezierTangent","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":264,"description":"<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n","itemtype":"method","name":"curve","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"],"alt":"horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":264,"params":[{"name":"x1","description":"<p>x-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the ending control point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1},{"line":332,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":358,"description":"<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n","itemtype":"method","name":"curveDetail","params":[{"name":"resolution","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"],"alt":"white arch shape with a low level of curve detail.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":398,"description":"<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n","itemtype":"method","name":"curveTightness","params":[{"name":"amount","description":"<p>amount of deformation from the original vertices</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"],"alt":"Line shaped like right-facing arrow,points move with mouse-x and warp shape.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":444,"description":"<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n","itemtype":"method","name":"curvePoint","params":[{"name":"a","description":"<p>coordinate of first control point of the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"bezier value at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"],"class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":493,"description":"<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n","itemtype":"method","name":"curveTangent","params":[{"name":"a","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second conrol point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"right curving line mid-right of canvas with 7 short lines radiating from it.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/vertex.js","line":20,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"beginContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":67,"description":"<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"beginShape","params":[{"name":"kind","description":"<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":293,"description":"<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"bezierVertex","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"],"alt":"crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":293,"params":[{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":375,"params":[{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":415,"description":"<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n","itemtype":"method","name":"curveVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"],"alt":"Upside-down u-shape line, mid canvas. left point extends beyond canvas view.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":415,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":460,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":524,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"endContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":583,"description":"<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n","itemtype":"method","name":"endShape","params":[{"name":"mode","description":"<p>use CLOSE to close the shape</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"],"alt":"Triangle line shape with smallest interior angle on bottom and upside-down L.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":668,"description":"<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"quadraticVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"],"alt":"arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":668,"params":[{"name":"cx","description":"<p>x-coordinate for the control point</p>\n","type":"Number"},{"name":"cy","description":"<p>y-coordinate for the control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":733,"params":[{"name":"cx","description":"","type":"Number"},{"name":"cy","description":"","type":"Number"},{"name":"cz","description":"<p>z-coordinate for the control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":826,"description":"<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n","itemtype":"method","name":"vertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"],"alt":"4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":826,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":957,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n","type":"Number"}],"chainable":1},{"line":965,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true},{"name":"u","description":"<p>the vertex's texture u-coordinate</p>\n","type":"Number"},{"name":"v","description":"<p>the vertex's texture v-coordinate</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":1003,"description":"<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n","itemtype":"method","name":"normal","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":1003,"params":[{"name":"vector","description":"<p>A p5.Vector representing the vertex normal.</p>\n","type":"Vector"}],"chainable":1},{"line":1040,"params":[{"name":"x","description":"<p>The x component of the vertex normal.</p>\n","type":"Number"},{"name":"y","description":"<p>The y component of the vertex normal.</p>\n","type":"Number"},{"name":"z","description":"<p>The z component of the vertex normal.</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/constants.js","line":9,"description":"<p>Version of this p5.js.</p>\n","itemtype":"property","name":"VERSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":18,"description":"<p>The default, two-dimensional renderer.</p>\n","itemtype":"property","name":"P2D","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":24,"description":"<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n","itemtype":"property","name":"WEBGL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":33,"itemtype":"property","name":"ARROW","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":38,"itemtype":"property","name":"CROSS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":43,"itemtype":"property","name":"HAND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":48,"itemtype":"property","name":"MOVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":53,"itemtype":"property","name":"TEXT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":58,"itemtype":"property","name":"WAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":66,"description":"<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"HALF_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"],"alt":"80×80 white quarter-circle with curve toward bottom right of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":84,"description":"<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"],"alt":"white half-circle with curve toward bottom of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":102,"description":"<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"QUARTER_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"],"alt":"white eighth-circle rotated about 40 degrees with curve bottom right canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":120,"description":"<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TAU","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":138,"description":"<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TWO_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":156,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n","itemtype":"property","name":"DEGREES","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":170,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n","itemtype":"property","name":"RADIANS","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":188,"itemtype":"property","name":"CORNER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":193,"itemtype":"property","name":"CORNERS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":198,"itemtype":"property","name":"RADIUS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":203,"itemtype":"property","name":"RIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":208,"itemtype":"property","name":"LEFT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":213,"itemtype":"property","name":"CENTER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":218,"itemtype":"property","name":"TOP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":223,"itemtype":"property","name":"BOTTOM","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":228,"itemtype":"property","name":"BASELINE","type":"String","final":1,"default":"alphabetic","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":234,"itemtype":"property","name":"POINTS","type":"Number","final":1,"default":"0x0000","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":240,"itemtype":"property","name":"LINES","type":"Number","final":1,"default":"0x0001","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":246,"itemtype":"property","name":"LINE_STRIP","type":"Number","final":1,"default":"0x0003","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":252,"itemtype":"property","name":"LINE_LOOP","type":"Number","final":1,"default":"0x0002","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":258,"itemtype":"property","name":"TRIANGLES","type":"Number","final":1,"default":"0x0004","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":264,"itemtype":"property","name":"TRIANGLE_FAN","type":"Number","final":1,"default":"0x0006","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":270,"itemtype":"property","name":"TRIANGLE_STRIP","type":"Number","final":1,"default":"0x0005","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":276,"itemtype":"property","name":"QUADS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":281,"itemtype":"property","name":"QUAD_STRIP","type":"String","final":1,"default":"quad_strip","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":287,"itemtype":"property","name":"TESS","type":"String","final":1,"default":"tess","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":293,"itemtype":"property","name":"CLOSE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":298,"itemtype":"property","name":"OPEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":303,"itemtype":"property","name":"CHORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":308,"itemtype":"property","name":"PIE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":313,"itemtype":"property","name":"PROJECT","type":"String","final":1,"default":"square","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":319,"itemtype":"property","name":"SQUARE","type":"String","final":1,"default":"butt","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":325,"itemtype":"property","name":"ROUND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":330,"itemtype":"property","name":"BEVEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":335,"itemtype":"property","name":"MITER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":342,"itemtype":"property","name":"RGB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":347,"description":"<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n","itemtype":"property","name":"HSB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":356,"itemtype":"property","name":"HSL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":363,"description":"<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n","itemtype":"property","name":"AUTO","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":373,"itemtype":"property","name":"ALT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":379,"itemtype":"property","name":"BACKSPACE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":384,"itemtype":"property","name":"CONTROL","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":389,"itemtype":"property","name":"DELETE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":394,"itemtype":"property","name":"DOWN_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":399,"itemtype":"property","name":"ENTER","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":404,"itemtype":"property","name":"ESCAPE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":409,"itemtype":"property","name":"LEFT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":414,"itemtype":"property","name":"OPTION","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":419,"itemtype":"property","name":"RETURN","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":424,"itemtype":"property","name":"RIGHT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":429,"itemtype":"property","name":"SHIFT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":434,"itemtype":"property","name":"TAB","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":439,"itemtype":"property","name":"UP_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":446,"itemtype":"property","name":"BLEND","type":"String","final":1,"default":"source-over","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":452,"itemtype":"property","name":"REMOVE","type":"String","final":1,"default":"destination-out","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":458,"itemtype":"property","name":"ADD","type":"String","final":1,"default":"lighter","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":466,"itemtype":"property","name":"DARKEST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":471,"itemtype":"property","name":"LIGHTEST","type":"String","final":1,"default":"lighten","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":477,"itemtype":"property","name":"DIFFERENCE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":482,"itemtype":"property","name":"SUBTRACT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":487,"itemtype":"property","name":"EXCLUSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":492,"itemtype":"property","name":"MULTIPLY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":497,"itemtype":"property","name":"SCREEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":502,"itemtype":"property","name":"REPLACE","type":"String","final":1,"default":"copy","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":508,"itemtype":"property","name":"OVERLAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":513,"itemtype":"property","name":"HARD_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":518,"itemtype":"property","name":"SOFT_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":523,"itemtype":"property","name":"DODGE","type":"String","final":1,"default":"color-dodge","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":529,"itemtype":"property","name":"BURN","type":"String","final":1,"default":"color-burn","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":537,"itemtype":"property","name":"THRESHOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":542,"itemtype":"property","name":"GRAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":547,"itemtype":"property","name":"OPAQUE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":552,"itemtype":"property","name":"INVERT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":557,"itemtype":"property","name":"POSTERIZE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":562,"itemtype":"property","name":"DILATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":567,"itemtype":"property","name":"ERODE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":572,"itemtype":"property","name":"BLUR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":579,"itemtype":"property","name":"NORMAL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":584,"itemtype":"property","name":"ITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":589,"itemtype":"property","name":"BOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":594,"itemtype":"property","name":"BOLDITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":599,"itemtype":"property","name":"CHAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":604,"itemtype":"property","name":"WORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":616,"itemtype":"property","name":"LINEAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":621,"itemtype":"property","name":"QUADRATIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":626,"itemtype":"property","name":"BEZIER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":631,"itemtype":"property","name":"CURVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":638,"itemtype":"property","name":"STROKE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":643,"itemtype":"property","name":"FILL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":648,"itemtype":"property","name":"TEXTURE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":653,"itemtype":"property","name":"IMMEDIATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":661,"itemtype":"property","name":"IMAGE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":669,"itemtype":"property","name":"NEAREST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":674,"itemtype":"property","name":"REPEAT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":679,"itemtype":"property","name":"CLAMP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":684,"itemtype":"property","name":"MIRROR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":691,"itemtype":"property","name":"LANDSCAPE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":696,"itemtype":"property","name":"PORTRAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":706,"itemtype":"property","name":"GRID","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":712,"itemtype":"property","name":"AXES","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":718,"itemtype":"property","name":"LABEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":723,"itemtype":"property","name":"FALLBACK","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/environment.js","line":20,"description":"<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n","itemtype":"method","name":"print","params":[{"name":"contents","description":"<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n","type":"Any"}],"example":["\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"],"alt":"default grey canvas","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":52,"description":"<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n","itemtype":"property","name":"frameCount","type":"Integer","readonly":"","example":["\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"],"alt":"numbers rapidly counting upward with frame count set to 30.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":79,"description":"<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n","itemtype":"property","name":"deltaTime","type":"Integer","readonly":"","example":["\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":129,"description":"<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n","itemtype":"property","name":"focused","type":"Boolean","readonly":"","example":["\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"],"alt":"green 50×50 ellipse at top left. Red X covers canvas when page focus changes","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":160,"description":"<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n","itemtype":"method","name":"cursor","params":[{"name":"type","description":"<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n","type":"String|Constant"},{"name":"x","description":"<p>the horizontal active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the vertical active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"],"alt":"canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":228,"description":"<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n","itemtype":"method","name":"frameRate","chainable":1,"example":["\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"blue rect moves left to right, followed by red rect moving faster. Loops.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":228,"params":[{"name":"fps","description":"<p>number of frames to be displayed every second</p>\n","type":"Number"}],"chainable":1},{"line":288,"params":[],"return":{"description":"current frameRate","type":"Number"}}]},{"file":"src/core/environment.js","line":331,"description":"<p>Hides the cursor from view.</p>\n","itemtype":"method","name":"noCursor","example":["\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"],"alt":"cursor becomes 10×10 white ellipse the moves with mouse x and y.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":354,"description":"<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":372,"description":"<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":390,"description":"<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n","itemtype":"property","name":"windowWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":405,"description":"<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n","itemtype":"property","name":"windowHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":421,"description":"<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n","itemtype":"method","name":"windowResized","params":[{"name":"event","description":"<p>optional Event callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":476,"description":"<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":488,"description":"<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":500,"description":"<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n","itemtype":"method","name":"fullscreen","params":[{"name":"val","description":"<p>whether the sketch should be in fullscreen mode\nor not</p>\n","type":"Boolean","optional":true}],"return":{"description":"current fullscreen state","type":"Boolean"},"example":["\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":550,"description":"<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n","itemtype":"method","name":"pixelDensity","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":550,"params":[{"name":"val","description":"<p>whether or how much the sketch should scale</p>\n","type":"Number"}],"chainable":1},{"line":586,"params":[],"return":{"description":"current pixel density of the sketch","type":"Number"}}]},{"file":"src/core/environment.js","line":605,"description":"<p>Returns the pixel density of the current display the sketch is running on.</p>\n","itemtype":"method","name":"displayDensity","return":{"description":"current pixel density of the display","type":"Number"},"example":["\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":660,"description":"<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURL","return":{"description":"url","type":"String"},"example":["\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"],"alt":"current url (http://p5js.org/reference/#/p5/getURL) moves right to left.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":691,"description":"<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLPath","return":{"description":"path components","type":"String[]"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":713,"description":"<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLParams","return":{"description":"URL params","type":"Object"},"example":["\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/helpers.js","line":1,"requires":["constants"],"class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":30,"description":"<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":126,"description":"<p>Set up our translation function, with loaded languages</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":171,"description":"<p>Returns a list of languages we have translations loaded for</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":178,"description":"<p>Returns the current language selected for translation</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":185,"description":"<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/legacy.js","line":1,"requires":["core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name","in others","they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."],"class":"p5","module":"Environment"},{"file":"src/core/main.js","line":42,"description":"<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n","itemtype":"method","name":"preload","example":["\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":83,"description":"<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n","itemtype":"method","name":"setup","example":["\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":114,"description":"<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n","itemtype":"method","name":"draw","example":["\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":415,"description":"<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":693,"description":"<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n","itemtype":"property","name":"disableFriendlyErrors","type":"Boolean","example":["\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"],"class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/p5.Element.js","line":21,"description":"<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"],"itemtype":"property","name":"elt","readonly":"","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":47,"description":"<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"parent","chainable":1,"example":["\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":47,"params":[{"name":"parent","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n","type":"String|p5.Element|Object"}],"chainable":1},{"line":93,"params":[],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/core/p5.Element.js","line":114,"description":"<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n","itemtype":"method","name":"id","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":114,"params":[{"name":"id","description":"<p>ID of the element</p>\n","type":"String"}],"chainable":1},{"line":139,"params":[],"return":{"description":"the id of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":154,"description":"<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n","itemtype":"method","name":"class","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":154,"params":[{"name":"class","description":"<p>class to add</p>\n","type":"String"}],"chainable":1},{"line":176,"params":[],"return":{"description":"the class of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":189,"description":"<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":246,"description":"<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"return":{"description":"","type":"p5.Element"},"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":292,"description":"<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":354,"description":"<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":403,"description":"<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":454,"description":"<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":510,"description":"<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOver","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":551,"description":"<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOut","params":[{"name":"fxn","description":"<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":592,"description":"<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"fxn","description":"<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":639,"description":"<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"fxn","description":"<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":678,"description":"<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"fxn","description":"<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":725,"description":"<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragOver","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":763,"description":"<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragLeave","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":827,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Graphics.js","line":70,"description":"<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n","itemtype":"method","name":"reset","example":["\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"],"alt":"A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Graphics.js","line":122,"description":"<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"],"alt":"no image\na multi-colored circle moving back and forth over a scrolling background.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":99,"description":"<p>Resize our canvas element.</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":415,"description":"<p>Helper function to check font type (system or otf)</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":467,"description":"<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":7,"description":"<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":402,"description":"<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/reference.js","line":7,"description":"<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n","itemtype":"property","name":"let","example":["\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":34,"description":"<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n","itemtype":"property","name":"const","example":["\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"],"alt":"These examples do not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":87,"description":"<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n","itemtype":"property","name":"===","example":["\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":115,"description":"<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>","itemtype":"property","name":">","example":["\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":137,"description":"<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":">=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":158,"description":"<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<","example":["\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":179,"description":"<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":200,"description":"<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n","itemtype":"property","name":"if-else","example":["\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":231,"description":"<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n","itemtype":"property","name":"function","example":["\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":267,"description":"<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n","itemtype":"property","name":"return","example":["\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":288,"description":"<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n","itemtype":"property","name":"boolean","example":["\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":309,"description":"<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n","itemtype":"property","name":"string","example":["\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":331,"description":"<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n","itemtype":"property","name":"number","example":["\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":351,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n","itemtype":"property","name":"object","example":["\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":379,"description":"<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n","itemtype":"property","name":"class","example":["\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":408,"description":"<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n","itemtype":"property","name":"for","example":["\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":448,"description":"<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n","itemtype":"property","name":"while","example":["\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":490,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n","itemtype":"method","name":"stringify","static":1,"params":[{"name":"object","description":"<p>:Javascript object that you would like to convert to JSON</p>\n","type":"Object"}],"example":["\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"JSON","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":512,"description":"<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n","itemtype":"method","name":"log","static":1,"params":[{"name":"message","description":"<p>:Message that you would like to print to the console</p>\n","type":"String|Expression|Object"}],"example":["\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"console","module":"Foundation","submodule":"Foundation"},{"file":"src/core/rendering.js","line":15,"description":"<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"createCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL</p>\n","type":"Constant","optional":true}],"return":{"description":"","type":"p5.Renderer"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"],"alt":"Black line extending from top-left of canvas to bottom right.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":125,"description":"<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n","itemtype":"method","name":"resizeCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"noRedraw","description":"<p>don't redraw the canvas immediately</p>\n","type":"Boolean","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"No image displayed.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":183,"description":"<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n","itemtype":"method","name":"noCanvas","example":["\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":204,"description":"<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n","itemtype":"method","name":"createGraphics","params":[{"name":"w","description":"<p>width of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"h","description":"<p>height of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n","type":"Constant","optional":true}],"return":{"description":"offscreen graphics buffer","type":"p5.Graphics"},"example":["\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"4 grey squares alternating light and dark grey. White quarter circle mid-left.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":243,"description":"<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n","itemtype":"method","name":"blendMode","params":[{"name":"mode","description":"<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"],"alt":"translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":326,"description":"<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n","itemtype":"property","name":"drawingContext","example":["\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"white ellipse with shadow blur effect around edges","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/shim.js","line":18,"description":"<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/shim.js","line":39,"description":"<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n","class":"p5","module":"Rendering"},{"file":"src/core/structure.js","line":10,"description":"<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"noLoop","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"],"alt":"113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":83,"description":"<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"loop","example":["\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"],"alt":"horizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":134,"description":"<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n","itemtype":"method","name":"isLooping","example":["\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"],"alt":"Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":192,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"push","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":290,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"pop","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":391,"description":"<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n","itemtype":"method","name":"redraw","params":[{"name":"n","description":"<p>Redraw for n-times. The default value is 1.</p>\n","type":"Integer","optional":true}],"example":["\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"],"alt":"black line on far left of canvas\nblack line on far left of canvas","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":497,"description":"<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n","itemtype":"method","name":"p5","params":[{"name":"sketch","description":"<p>a function containing a p5.js sketch</p>\n","type":"Object"},{"name":"node","description":"<p>ID or pointer to HTML DOM node to contain sketch in</p>\n","type":"String|Object"}],"example":["\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"],"alt":"white rectangle on black background","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/transform.js","line":11,"description":"<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n","itemtype":"method","name":"applyMatrix","params":[{"name":"a","description":"<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n","type":"Number|Array"},{"name":"b","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"c","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"d","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"e","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"f","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":168,"description":"<p>Replaces the current matrix with the identity matrix.</p>\n","itemtype":"method","name":"resetMatrix","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"],"alt":"A rotated rectangle in the center with another at the top left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":193,"description":"<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"rotate","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"},{"name":"axis","description":"<p>(in 3d) the axis to rotate around</p>\n","type":"p5.Vector|Number[]","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":232,"description":"<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateX","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the x axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":268,"description":"<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateY","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the y axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":304,"description":"<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateZ","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the z axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":342,"description":"<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"scale","chainable":1,"example":["\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":342,"params":[{"name":"s","description":"<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n","type":"Number|p5.Vector|Number[]"},{"name":"y","description":"<p>percent to scale the object in the y-axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>percent to scale the object in the z-axis (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":386,"params":[{"name":"scales","description":"<p>per-axis percents to scale the object</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/core/transform.js","line":416,"description":"<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearX","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at top middle.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":455,"description":"<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearY","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at middle bottom.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":494,"description":"<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"translate","chainable":1,"example":["\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"],"alt":"white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":494,"params":[{"name":"x","description":"<p>left/right translation</p>\n","type":"Number"},{"name":"y","description":"<p>up/down translation</p>\n","type":"Number"},{"name":"z","description":"<p>forward/backward translation (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":547,"params":[{"name":"vector","description":"<p>the vector to translate by</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/data/local_storage.js","line":10,"description":"<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n","itemtype":"method","name":"storeItem","params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String|Number|Object|Boolean|p5.Color|p5.Vector"}],"example":["\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"],"alt":"When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":101,"description":"<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n","itemtype":"method","name":"getItem","params":[{"name":"key","description":"<p>name that you wish to use to store in local storage</p>\n","type":"String"}],"return":{"description":"Value of stored item","type":"Number|Object|String|Boolean|p5.Color|p5.Vector"},"example":["\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"],"alt":"If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":177,"description":"<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n","itemtype":"method","name":"clearStorage","example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":205,"description":"<p>Removes an item that was stored with storeItem()</p>\n","itemtype":"method","name":"removeItem","params":[{"name":"key","description":"","type":"String"}],"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/p5.TypedDict.js","line":14,"description":"<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n","itemtype":"method","name":"createStringDict","return":{"description":"","type":"p5.StringDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":14,"params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String"}],"return":{"description":"","type":"p5.StringDict"}},{"line":37,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.StringDict"}}]},{"file":"src/data/p5.TypedDict.js","line":48,"description":"<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n","itemtype":"method","name":"createNumberDict","return":{"description":"","type":"p5.NumberDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":48,"params":[{"name":"key","description":"","type":"Number"},{"name":"value","description":"","type":"Number"}],"return":{"description":"","type":"p5.NumberDict"}},{"line":71,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.NumberDict"}}]},{"file":"src/data/p5.TypedDict.js","line":101,"description":"<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n","itemtype":"method","name":"size","return":{"description":"the number of key-value pairs in the Dictionary","type":"Integer"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":122,"description":"<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n","itemtype":"method","name":"hasKey","params":[{"name":"key","description":"<p>that you want to look up</p>\n","type":"Number|String"}],"return":{"description":"whether that key exists in Dictionary","type":"Boolean"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":144,"description":"<p>Returns the value stored at the given key.</p>\n","itemtype":"method","name":"get","params":[{"name":"the","description":"<p>key you want to access</p>\n","type":"Number|String"}],"return":{"description":"the value stored at that key","type":"Number|String"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":170,"description":"<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n","itemtype":"method","name":"set","params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":197,"description":"<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":208,"description":"<p>Creates a new key-value pair in the Dictionary.</p>\n","itemtype":"method","name":"create","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary","overloads":[{"line":208,"params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}]},{"line":226,"params":[{"name":"obj","description":"<p>key/value pair</p>\n","type":"Object"}]}]},{"file":"src/data/p5.TypedDict.js","line":244,"description":"<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n","itemtype":"method","name":"clear","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":265,"description":"<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n","itemtype":"method","name":"remove","params":[{"name":"key","description":"<p>for the pair to remove</p>\n","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":294,"description":"<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n","itemtype":"method","name":"print","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":318,"description":"<p>Converts the Dictionary into a CSV file for local download.</p>\n","itemtype":"method","name":"saveTable","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":356,"description":"<p>Converts the Dictionary into a JSON file for local download.</p>\n","itemtype":"method","name":"saveJSON","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":387,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":425,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":432,"description":"<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"add","params":[{"name":"Key","description":"<p>for the value you wish to add to</p>\n","type":"Number"},{"name":"Number","description":"<p>to add to the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":459,"description":"<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"sub","params":[{"name":"Key","description":"<p>for the value you wish to subtract from</p>\n","type":"Number"},{"name":"Number","description":"<p>to subtract from the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":482,"description":"<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"mult","params":[{"name":"Key","description":"<p>for value you wish to multiply</p>\n","type":"Number"},{"name":"Amount","description":"<p>to multiply the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":509,"description":"<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"div","params":[{"name":"Key","description":"<p>for value you wish to divide</p>\n","type":"Number"},{"name":"Amount","description":"<p>to divide the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":536,"description":"<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":560,"description":"<p>Return the lowest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"minValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":580,"description":"<p>Return the highest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"maxValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":600,"description":"<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":622,"description":"<p>Return the lowest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"minKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":642,"description":"<p>Return the highest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"maxKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/dom/dom.js","line":21,"description":"<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n","itemtype":"method","name":"select","params":[{"name":"selectors","description":"<p>CSS selector string of element to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"<a href=\"#/p5.Element\">p5.Element</a> containing node found","type":"p5.Element|null"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":68,"description":"<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n","itemtype":"method","name":"selectAll","params":[{"name":"selectors","description":"<p>CSS selector string of elements to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found","type":"p5.Element[]"},"example":["\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":127,"description":"<p>Helper function for select and selectAll</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":142,"description":"<p>Helper function for getElement and getElements.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":176,"description":"<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n","itemtype":"method","name":"removeElements","example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":204,"description":"<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n","itemtype":"method","name":"changed","params":[{"name":"fxn","description":"<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"],"alt":"dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":271,"description":"<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n","itemtype":"method","name":"input","params":[{"name":"fxn","description":"<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"alt":"no display.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":309,"description":"<p>Helpers for create methods.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":322,"description":"<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createDiv","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":341,"description":"<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n","itemtype":"method","name":"createP","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":361,"description":"<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createSpan","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":379,"description":"<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n","itemtype":"method","name":"createImg","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":379,"params":[{"name":"src","description":"<p>src path or url for image</p>\n","type":"String"},{"name":"alt","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":396,"params":[{"name":"src","description":"","type":"String"},{"name":"alt","description":"","type":"String"},{"name":"crossOrigin","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n","type":"String"},{"name":"successCallback","description":"<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":426,"description":"<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n","itemtype":"method","name":"createA","params":[{"name":"href","description":"<p>url of page to link to</p>\n","type":"String"},{"name":"html","description":"<p>inner html of link element to display</p>\n","type":"String"},{"name":"target","description":"<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":450,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":452,"description":"<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n","itemtype":"method","name":"createSlider","params":[{"name":"min","description":"<p>minimum value of the slider</p>\n","type":"Number"},{"name":"max","description":"<p>maximum value of the slider</p>\n","type":"Number"},{"name":"value","description":"<p>default value of the slider</p>\n","type":"Number","optional":true},{"name":"step","description":"<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n","type":"Number","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":507,"description":"<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n","itemtype":"method","name":"createButton","params":[{"name":"label","description":"<p>label displayed on the button</p>\n","type":"String"},{"name":"value","description":"<p>value of the button</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":541,"description":"<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n","itemtype":"method","name":"createCheckbox","params":[{"name":"label","description":"<p>label displayed after checkbox</p>\n","type":"String","optional":true},{"name":"value","description":"<p>value of the checkbox; checked is true, unchecked is false</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":622,"description":"<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n","itemtype":"method","name":"createSelect","return":{"description":"","type":"p5.Element"},"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":622,"params":[{"name":"multiple","description":"<p>true if dropdown should support multiple selections</p>\n","type":"Boolean","optional":true}],"return":{"description":"","type":"p5.Element"}},{"line":673,"params":[{"name":"existing","description":"<p>DOM select element</p>\n","type":"Object"}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":770,"description":"<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n","itemtype":"method","name":"createRadio","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":770,"params":[{"name":"containerElement","description":"<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n","type":"Object"},{"name":"name","description":"<p>A name parameter for each Input Element.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":832,"params":[{"name":"name","description":"","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":837,"params":[],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":978,"description":"<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n","itemtype":"method","name":"createColorPicker","params":[{"name":"value","description":"<p>default color of element</p>\n","type":"String|p5.Color","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1066,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n","itemtype":"method","name":"createInput","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":1066,"params":[{"name":"value","description":"<p>default value of the input box</p>\n","type":"String"},{"name":"type","description":"<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":1091,"params":[{"name":"value","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":1104,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n","itemtype":"method","name":"createFileInput","params":[{"name":"callback","description":"<p>callback function for when a file is loaded</p>\n","type":"Function"},{"name":"multiple","description":"<p>optional, to allow multiple files to be selected</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element","type":"p5.Element"},"example":["\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1164,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1211,"description":"<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n","itemtype":"method","name":"createVideo","params":[{"name":"src","description":"<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n","type":"String|String[]"},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1257,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1259,"description":"<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n","itemtype":"method","name":"createAudio","params":[{"name":"src","description":"<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n","type":"String|String[]","optional":true},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1296,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1298,"itemtype":"property","name":"VIDEO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1304,"itemtype":"property","name":"AUDIO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1341,"description":"<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n","itemtype":"method","name":"createCapture","params":[{"name":"type","description":"<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n","type":"String|Constant|Object"},{"name":"callback","description":"<p>function to be called once\n                                  stream has loaded</p>\n","type":"Function","optional":true}],"return":{"description":"capture video <a href=\"#/p5.Element\">p5.Element</a>","type":"p5.Element"},"example":["\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1478,"description":"<p>Creates element with given tag in the DOM with given content.</p>\n","itemtype":"method","name":"createElement","params":[{"name":"tag","description":"<p>tag for the new element</p>\n","type":"String"},{"name":"content","description":"<p>html content to be inserted into the element</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1504,"description":"<p>Adds specified class to the element.</p>\n","itemtype":"method","name":"addClass","params":[{"name":"class","description":"<p>name of class to add</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1529,"description":"<p>Removes specified class from the element.</p>\n","itemtype":"method","name":"removeClass","params":[{"name":"class","description":"<p>name of class to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1560,"description":"<p>Checks if specified class already set to element</p>\n","itemtype":"method","name":"hasClass","return":{"description":"a boolean value if element has specified class","type":"Boolean"},"params":[{"name":"c","description":"<p>class name of class to check</p>\n","type":"String"}],"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1589,"description":"<p>Toggles element class</p>\n","itemtype":"method","name":"toggleClass","params":[{"name":"c","description":"<p>class name to toggle</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1622,"description":"<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n","itemtype":"method","name":"child","return":{"description":"an array of child nodes","type":"Node[]"},"example":["\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1622,"params":[],"return":{"description":"an array of child nodes","type":"Node[]"}},{"line":1650,"params":[{"name":"child","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n","type":"String|p5.Element","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1675,"description":"<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n","itemtype":"method","name":"center","params":[{"name":"align","description":"<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n","type":"String","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1726,"description":"<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n","itemtype":"method","name":"html","return":{"description":"the inner HTML of the element","type":"String"},"example":["\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1726,"params":[],"return":{"description":"the inner HTML of the element","type":"String"}},{"line":1747,"params":[{"name":"html","description":"<p>the HTML to be placed inside the element</p>\n","type":"String","optional":true},{"name":"append","description":"<p>whether to append HTML to existing</p>\n","type":"Boolean","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1765,"description":"<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n","itemtype":"method","name":"position","return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"},"example":["\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1765,"params":[],"return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"}},{"line":1798,"params":[{"name":"x","description":"<p>x-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"positionType","description":"<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n","type":"String","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1885,"description":"<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n","itemtype":"method","name":"style","return":{"description":"value of property","type":"String"},"example":["\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1885,"params":[{"name":"property","description":"<p>property to be set</p>\n","type":"String"}],"return":{"description":"value of property","type":"String"}},{"line":1923,"params":[{"name":"property","description":"","type":"String"},{"name":"value","description":"<p>value to assign to property</p>\n","type":"String|p5.Color"}],"chainable":1,"return":{"description":"current value of property, if no value is given as second argument","type":"String"}}]},{"file":"src/dom/dom.js","line":1980,"description":"<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n","itemtype":"method","name":"attribute","return":{"description":"value of attribute","type":"String"},"example":["\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1980,"params":[],"return":{"description":"value of attribute","type":"String"}},{"line":1995,"params":[{"name":"attr","description":"<p>attribute to set</p>\n","type":"String"},{"name":"value","description":"<p>value to assign to attribute</p>\n","type":"String"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2024,"description":"<p>Removes an attribute on the specified element.</p>\n","itemtype":"method","name":"removeAttribute","params":[{"name":"attr","description":"<p>attribute to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2069,"description":"<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n","itemtype":"method","name":"value","return":{"description":"value of the element","type":"String|Number"},"example":["\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2069,"params":[],"return":{"description":"value of the element","type":"String|Number"}},{"line":2099,"params":[{"name":"value","description":"","type":"String|Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2115,"description":"<p>Shows the current element. Essentially, setting display:block for the style.</p>\n","itemtype":"method","name":"show","chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2133,"description":"<p>Hides the current element. Essentially, setting display:none for the style.</p>\n","itemtype":"method","name":"hide","chainable":1,"example":["\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2149,"description":"<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n","itemtype":"method","name":"size","return":{"description":"the width and height of the element in an object","type":"Object"},"example":["\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2149,"params":[],"return":{"description":"the width and height of the element in an object","type":"Object"}},{"line":2173,"params":[{"name":"w","description":"<p>width of the element, either AUTO, or a number</p>\n","type":"Number|Constant"},{"name":"h","description":"<p>height of the element, either AUTO, or a number</p>\n","type":"Number|Constant","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":2230,"description":"<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2268,"description":"<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n","itemtype":"method","name":"drop","params":[{"name":"callback","description":"<p>callback to receive loaded file, called for each file dropped.</p>\n","type":"Function"},{"name":"fxn","description":"<p>callback triggered once when files are dropped with the drop event.</p>\n","type":"Function","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"],"alt":"Canvas turns into whatever image is dragged/dropped onto it.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2400,"description":"<p>Path to the media element source.</p>\n","itemtype":"property","name":"src","return":{"description":"src","type":"String"},"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2466,"description":"<p>Play an HTML5 media element.</p>\n","itemtype":"method","name":"play","chainable":1,"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2530,"description":"<p>Stops an HTML5 media element (sets current time to zero).</p>\n","itemtype":"method","name":"stop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2594,"description":"<p>Pauses an HTML5 media element.</p>\n","itemtype":"method","name":"pause","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2656,"description":"<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n","itemtype":"method","name":"loop","chainable":1,"example":["\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2712,"description":"<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n","itemtype":"method","name":"noLoop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2778,"description":"<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n","itemtype":"method","name":"autoplay","params":[{"name":"shouldAutoplay","description":"<p>whether the element should autoplay</p>\n","type":"Boolean"}],"chainable":1,"example":["\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"],"alt":"An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2845,"description":"<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n","itemtype":"method","name":"volume","return":{"description":"current volume","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2845,"params":[],"return":{"description":"current volume","type":"Number"}},{"line":2918,"params":[{"name":"val","description":"<p>volume between 0.0 and 1.0</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2931,"description":"<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n","itemtype":"method","name":"speed","return":{"description":"current playback speed of the element","type":"Number"},"example":["\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2931,"params":[],"return":{"description":"current playback speed of the element","type":"Number"}},{"line":3003,"params":[{"name":"speed","description":"<p>speed multiplier for element playback</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3020,"description":"<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n","itemtype":"method","name":"time","return":{"description":"current time (in seconds)","type":"Number"},"example":["\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":3020,"params":[],"return":{"description":"current time (in seconds)","type":"Number"}},{"line":3065,"params":[{"name":"time","description":"<p>time to jump to (in seconds)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3079,"description":"<p>Returns the duration of the HTML5 media element.</p>\n","itemtype":"method","name":"duration","return":{"description":"duration","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3201,"description":"<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n","type":"Function"}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3232,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3234,"description":"<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n","itemtype":"method","name":"connect","params":[{"name":"audioNode","description":"<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n","type":"AudioNode|Object"}],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3283,"description":"<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n","itemtype":"method","name":"disconnect","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3298,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3300,"description":"<p>Show the default MediaElement controls, as determined by the web browser.</p>\n","itemtype":"method","name":"showControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3331,"description":"<p>Hide the default mediaElement controls.</p>\n","itemtype":"method","name":"hideControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3360,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3371,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3434,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3476,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3542,"description":"<p>Underlying File object. All normal File methods can be called on this.</p>\n","itemtype":"property","name":"file","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3554,"description":"<p>File type (image, text, etc.)</p>\n","itemtype":"property","name":"type","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3560,"description":"<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n","itemtype":"property","name":"subtype","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3566,"description":"<p>File name</p>\n","itemtype":"property","name":"name","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3572,"description":"<p>File size</p>\n","itemtype":"property","name":"size","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3579,"description":"<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n","itemtype":"property","name":"data","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/events/acceleration.js","line":11,"description":"<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n","itemtype":"property","name":"deviceOrientation","type":"Constant","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":23,"description":"<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":46,"description":"<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":69,"description":"<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationZ","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":94,"description":"<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":104,"description":"<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":114,"description":"<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":135,"description":"<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationX","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":168,"description":"<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":201,"description":"<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"itemtype":"property","name":"rotationZ","type":"Number","readonly":"","alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":239,"description":"<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":285,"description":"<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":330,"description":"<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":389,"description":"<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n","itemtype":"property","name":"turnAxis","type":"String","readonly":"","example":["\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":428,"description":"<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n","itemtype":"method","name":"setMoveThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":471,"description":"<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n","itemtype":"method","name":"setShakeThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":515,"description":"<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n","itemtype":"method","name":"deviceMoved","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":546,"description":"<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n","itemtype":"method","name":"deviceTurned","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":604,"description":"<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n","itemtype":"method","name":"deviceShaken","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device shakes","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/keyboard.js","line":10,"description":"<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n","itemtype":"property","name":"keyIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white rect that turns black on keypress.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":36,"description":"<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n","itemtype":"property","name":"key","type":"String","readonly":"","example":["\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"],"alt":"canvas displays any key value that is pressed in pink font.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":64,"description":"<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n","itemtype":"property","name":"keyCode","type":"Integer","readonly":"","example":["\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"],"alt":"Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":103,"description":"<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyPressed","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":190,"description":"<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyReleased","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when pressed again","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":243,"description":"<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"keyTyped","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"],"alt":"black rect center. turns white when 'a' key typed and black when 'b' pressed","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":298,"description":"<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":308,"description":"<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n","itemtype":"method","name":"keyIsDown","params":[{"name":"code","description":"<p>The key to check for.</p>\n","type":"Number"}],"return":{"description":"whether key is down or not","type":"Boolean"},"example":["\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"],"alt":"50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/mouse.js","line":12,"description":"<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedX","type":"Number","readonly":"","example":["\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"],"alt":"box moves left and right according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":43,"description":"<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedY","type":"Number","readonly":"","example":["\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"box moves up and down according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":80,"description":"<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"],"alt":"horizontal black line moves left and right with mouse x-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":106,"description":"<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"],"alt":"vertical black line moves up and down with mouse y-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":132,"description":"<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"],"alt":"line trail is created from cursor movements. faster movement make longer line.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":164,"description":"<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"],"alt":"60×60 black rect center, fuchsia background. rect flickers on mouse movement","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":195,"description":"<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":233,"description":"<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":271,"description":"<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":311,"description":"<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":351,"description":"<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n","itemtype":"property","name":"mouseButton","type":"Constant","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"],"alt":"50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":389,"description":"<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n","itemtype":"property","name":"mouseIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":481,"description":"<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":535,"description":"<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseDragged","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":615,"description":"<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":696,"description":"<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":772,"description":"<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":841,"description":"<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":926,"description":"<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"event","description":"<p>optional WheelEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"],"alt":"black 50×50 rect moves up and down with vertical scroll. fuchsia background","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":979,"description":"<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n","itemtype":"method","name":"requestPointerLock","example":["\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"],"alt":"3D scene moves according to mouse mouse movement in a first person perspective","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":1025,"description":"<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n","itemtype":"method","name":"exitPointerLock","example":["\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"],"alt":"cursor gets locked / unlocked on mouse-click","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/touch.js","line":10,"description":"<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n","itemtype":"property","name":"touches","type":"Object[]","readonly":"","example":["\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"],"alt":"Number of touches currently registered are displayed on the canvas","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":71,"description":"<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch event.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":151,"description":"<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns lighter with touch until white. resets\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":223,"description":"<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/image/filters.js","line":3,"description":"<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n","class":"p5","module":"Events"},{"file":"src/image/image.js","line":8,"description":"<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":15,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n","itemtype":"method","name":"createImage","params":[{"name":"width","description":"<p>width in pixels</p>\n","type":"Integer"},{"name":"height","description":"<p>height in pixels</p>\n","type":"Integer"}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":94,"description":"<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n","itemtype":"method","name":"saveCanvas","example":["\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"],"alt":"no image displayed\n no image displayed\n no image displayed","class":"p5","module":"Image","submodule":"Image","overloads":[{"line":94,"params":[{"name":"selectedCanvas","description":"<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n","type":"p5.Element|HTMLCanvasElement"},{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String","optional":true}]},{"line":136,"params":[{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"","type":"String","optional":true}]}]},{"file":"src/image/image.js","line":413,"description":"<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n","itemtype":"method","name":"saveFrames","params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String"},{"name":"duration","description":"<p>Duration in seconds to save the frames for.</p>\n","type":"Number"},{"name":"framerate","description":"<p>Framerate to save the frames in.</p>\n","type":"Number"},{"name":"callback","description":"<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n","type":"Function(Array)","optional":true}],"example":["\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"],"alt":"canvas background goes from light to dark with mouse x.","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/loading_displaying.js","line":18,"description":"<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n","itemtype":"method","name":"loadImage","params":[{"name":"path","description":"<p>Path of the image to be loaded</p>\n","type":"String"},{"name":"successCallback","description":"<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n","type":"function(p5.Image)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                               the image fails to load.</p>\n","type":"Function(Event)","optional":true}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":162,"description":"<p>Helper function for loading GIF-based images</p>\n","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":301,"description":"<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n","itemtype":"method","name":"image","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":301,"params":[{"name":"img","description":"<p>the image to display</p>\n","type":"p5.Image|p5.Element|p5.Texture"},{"name":"x","description":"<p>the x-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"width","description":"<p>the width to draw the image</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>the height to draw the image</p>\n","type":"Number","optional":true}]},{"line":388,"params":[{"name":"img","description":"","type":"p5.Image|p5.Element|p5.Texture"},{"name":"dx","description":"<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dy","description":"<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dWidth","description":"<p>the width of the destination rectangle</p>\n","type":"Number"},{"name":"dHeight","description":"<p>the height of the destination rectangle</p>\n","type":"Number"},{"name":"sx","description":"<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sy","description":"<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sWidth","description":"<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n","type":"Number","optional":true},{"name":"sHeight","description":"<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n","type":"Number","optional":true}]}]},{"file":"src/image/loading_displaying.js","line":471,"description":"<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n","itemtype":"method","name":"tint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":471,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":542,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}]},{"line":547,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":553,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}]},{"line":559,"params":[{"name":"color","description":"<p>the tint color</p>\n","type":"p5.Color"}]}]},{"file":"src/image/loading_displaying.js","line":569,"description":"<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n","itemtype":"method","name":"noTint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of bricks, left image with blue tint","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":633,"description":"<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n","itemtype":"method","name":"imageMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, or CENTER</p>\n","type":"Constant"}],"example":["\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"],"alt":"small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/p5.Image.js","line":9,"description":"<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":88,"description":"<p>Image width.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"],"alt":"rocky mountains in top and horizontal lines in corresponding colors in bottom.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":115,"description":"<p>Image height.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"],"alt":"rocky mountains on right and vertical lines in corresponding colors on left.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":152,"description":"<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":222,"description":"<p>Helper function for animating GIF-based images with time</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":253,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":261,"description":"<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":296,"description":"<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n","itemtype":"method","name":"updatePixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":296,"params":[{"name":"x","description":"<p>x-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"y","description":"<p>y-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"w","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"h","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"}]},{"line":338,"params":[]}]},{"file":"src/image/p5.Image.js","line":346,"description":"<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"],"alt":"image of rocky mountains with 50×50 green rect in front","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":346,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":383,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":387,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/p5.Image.js","line":400,"description":"<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"a","description":"<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"],"alt":"2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":437,"description":"<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n","itemtype":"method","name":"resize","params":[{"name":"width","description":"<p>the resized image width</p>\n","type":"Number"},{"name":"height","description":"<p>the resized image height</p>\n","type":"Number"}],"example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"],"alt":"image of rocky mountains. zoomed in","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":548,"description":"<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains and smaller image on top of bricks at top left","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":548,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":588,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/p5.Image.js","line":603,"description":"<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n","itemtype":"method","name":"mask","params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"}],"example":["\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":665,"description":"<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"],"alt":"2 images of rocky mountains left one in color, right in black and white","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":738,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":738,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n","type":"Constant"}]},{"line":815,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/p5.Image.js","line":859,"description":"<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n","itemtype":"method","name":"save","params":[{"name":"filename","description":"<p>give your file a name</p>\n","type":"String"},{"name":"extension","description":"<p>'png' or 'jpg'</p>\n","type":"String"}],"example":["\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"],"alt":"image of rocky mountains.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":900,"description":"<p>Starts an animated GIF over at the beginning state.</p>\n","itemtype":"method","name":"reset","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"],"alt":"Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":941,"description":"<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n","itemtype":"method","name":"getCurrentFrame","return":{"description":"The index for the currently displaying frame in animated GIF","type":"Number"},"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"],"alt":"Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":972,"description":"<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n","itemtype":"method","name":"setFrame","params":[{"name":"index","description":"<p>the index for the frame that should be displayed</p>\n","type":"Number"}],"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1017,"description":"<p>Returns the number of frames in an animated GIF</p>\n","itemtype":"method","name":"numFrames","return":{"description":"","type":"Number"},"example":["     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1052,"description":"<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n","itemtype":"method","name":"play","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1089,"description":"<p>Pauses an animated GIF.</p>\n","itemtype":"method","name":"pause","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1125,"description":"<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n","itemtype":"method","name":"delay","params":[{"name":"d","description":"<p>the amount in milliseconds to delay between switching frames</p>\n","type":"Number"},{"name":"index","description":"<p>the index of the frame that should have the new delay value {optional}</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"],"alt":"Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/pixels.js","line":12,"description":"<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"],"alt":"top half of canvas pink, bottom grey","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":80,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":80,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n","type":"Constant"}]},{"line":152,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/pixels.js","line":173,"description":"<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":173,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":215,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/pixels.js","line":307,"description":"<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"],"alt":"black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":481,"description":"<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":481,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":551,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":555,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/pixels.js","line":566,"description":"<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":602,"description":"<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"c","description":"<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"],"alt":"4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":674,"description":"<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n","itemtype":"method","name":"updatePixels","params":[{"name":"x","description":"<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>width of region to update</p>\n","type":"Number","optional":true},{"name":"h","description":"<p>height of region to update</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/io/files.js","line":20,"description":"<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadJSON","return":{"description":"JSON data","type":"Object|Array"},"example":["\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"],"alt":"50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity","class":"p5","module":"IO","submodule":"Input","overloads":[{"line":20,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"jsonpOptions","description":"<p>options object for jsonp related settings</p>\n","type":"Object","optional":true},{"name":"datatype","description":"<p>\"json\" or \"jsonp\"</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"JSON data","type":"Object|Array"}},{"line":104,"params":[{"name":"path","description":"","type":"String"},{"name":"datatype","description":"","type":"String"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}},{"line":112,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}}]},{"file":"src/io/files.js","line":183,"description":"<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadStrings","params":[{"name":"filename","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":303,"description":"<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadTable","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"extension","description":"<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n","type":"String","optional":true},{"name":"header","description":"<p>\"header\" to indicate table has header row</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Table\">Table</a> object containing data","type":"Object"},"example":["\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":583,"description":"<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadXML","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"XML object containing data","type":"Object"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":693,"description":"<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadBytes","params":[{"name":"file","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if there\n                                   is an error</p>\n","type":"Function","optional":true}],"return":{"description":"an object whose 'bytes' property will be the loaded buffer","type":"Object"},"example":["\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":752,"description":"<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n","itemtype":"method","name":"httpGet","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":752,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":806,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":814,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":829,"description":"<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n","itemtype":"method","name":"httpPost","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":829,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":896,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":904,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":919,"description":"<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n","itemtype":"method","name":"httpDo","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":919,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"method","description":"<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n","type":"String","optional":true},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":990,"params":[{"name":"path","description":"","type":"String"},{"name":"options","description":"<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n","type":"Object"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":1155,"itemtype":"method","name":"createWriter","params":[{"name":"name","description":"<p>name of the file to be created</p>\n","type":"String"},{"name":"extension","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.PrintWriter"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1210,"description":"<p>Writes data to the PrintWriter stream</p>\n","itemtype":"method","name":"write","params":[{"name":"data","description":"<p>all data to be written by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1269,"description":"<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n","itemtype":"method","name":"print","params":[{"name":"data","description":"<p>all data to be printed by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1310,"description":"<p>Clears the data already written to the PrintWriter object</p>\n","itemtype":"method","name":"clear","example":["\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1344,"description":"<p>Closes the PrintWriter</p>\n","itemtype":"method","name":"close","example":["\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1393,"description":"<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n","itemtype":"method","name":"save","params":[{"name":"objectOrFilename","description":"<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n","type":"Object|String","optional":true},{"name":"filename","description":"<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n","type":"String","optional":true},{"name":"options","description":"<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n","type":"Boolean|String","optional":true}],"example":["\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"],"alt":"An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1535,"description":"<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveJSON","params":[{"name":"json","description":"","type":"Array|Object"},{"name":"filename","description":"","type":"String"},{"name":"optimize","description":"<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1592,"description":"<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveStrings","params":[{"name":"list","description":"<p>string array to be written</p>\n","type":"String[]"},{"name":"filename","description":"<p>filename for output</p>\n","type":"String"},{"name":"extension","description":"<p>the filename's extension</p>\n","type":"String","optional":true},{"name":"isCRLF","description":"<p>if true, change line-break to CRLF</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1656,"description":"<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveTable","params":[{"name":"Table","description":"<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n","type":"p5.Table"},{"name":"filename","description":"<p>the filename to which the Table should be saved</p>\n","type":"String"},{"name":"options","description":"<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n","type":"String","optional":true}],"example":["\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/p5.Table.js","line":9,"description":"<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":43,"description":"<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n","itemtype":"property","name":"columns","type":"String[]","example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":77,"description":"<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n","itemtype":"property","name":"rows","type":"p5.TableRow[]","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":85,"description":"<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n","itemtype":"method","name":"addRow","params":[{"name":"row","description":"<p>row to be added to the table</p>\n","type":"p5.TableRow","optional":true}],"return":{"description":"the row that was added","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":148,"description":"<p>Removes a row from the table object.</p>\n","itemtype":"method","name":"removeRow","params":[{"name":"id","description":"<p>ID number of the row to remove</p>\n","type":"Integer"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":195,"description":"<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n","itemtype":"method","name":"getRow","params":[{"name":"rowID","description":"<p>ID number of the row to get</p>\n","type":"Integer"}],"return":{"description":"<a href=\"#/p5.TableRow\">p5.TableRow</a> object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":240,"description":"<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n","itemtype":"method","name":"getRows","return":{"description":"Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":288,"description":"<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"findRow","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":352,"description":"<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"findRows","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":420,"description":"<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"matchRow","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String|RegExp"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer"}],"return":{"description":"TableRow object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":478,"description":"<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n","itemtype":"method","name":"matchRows","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer","optional":true}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":545,"description":"<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"getColumn","params":[{"name":"column","description":"<p>String or Number of the column to return</p>\n","type":"String|Number"}],"return":{"description":"Array of column values","type":"Array"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":597,"description":"<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n","itemtype":"method","name":"clearRows","example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":638,"description":"<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n","itemtype":"method","name":"addColumn","params":[{"name":"title","description":"<p>title of the given column</p>\n","type":"String","optional":true}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":688,"description":"<p>Returns the total number of columns in a Table.</p>\n","itemtype":"method","name":"getColumnCount","return":{"description":"Number of columns in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":724,"description":"<p>Returns the total number of rows in a Table.</p>\n","itemtype":"method","name":"getRowCount","return":{"description":"Number of rows in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":760,"description":"<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n","itemtype":"method","name":"removeTokens","params":[{"name":"chars","description":"<p>String listing characters to be removed</p>\n","type":"String"},{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":832,"description":"<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n","itemtype":"method","name":"trim","params":[{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":896,"description":"<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n","itemtype":"method","name":"removeColumn","params":[{"name":"column","description":"<p>columnName (string) or ID (number)</p>\n","type":"String|Integer"}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":960,"description":"<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String|Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1009,"description":"<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1055,"description":"<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String"}],"example":["\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1100,"description":"<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1146,"description":"<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1190,"description":"<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1242,"description":"<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n","itemtype":"method","name":"getObject","params":[{"name":"headerColumn","description":"<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n","type":"String","optional":true}],"return":{"description":"","type":"Object"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1305,"description":"<p>Retrieves all table data and returns it as a multidimensional array.</p>\n","itemtype":"method","name":"getArray","return":{"description":"","type":"Array"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":40,"description":"<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored</p>\n","type":"String|Number"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":102,"description":"<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a Float</p>\n","type":"Number|String"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":146,"description":"<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a String</p>\n","type":"String|Number|Boolean|Object"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":191,"description":"<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":239,"description":"<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"Float Floating point number","type":"Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":295,"description":"<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getString","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"String","type":"String"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.XML.js","line":62,"description":"<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"getParent","return":{"description":"element parent","type":"p5.XML"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":100,"description":"<p>Gets the element's full name, which is returned as a String.</p>\n","itemtype":"method","name":"getName","return":{"description":"the name of the node","type":"String"},"example":["&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":135,"description":"<p>Sets the element's name, which is specified as a String.</p>\n","itemtype":"method","name":"setName","params":[{"name":"the","description":"<p>new name of the node</p>\n","type":"String"}],"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":181,"description":"<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n","itemtype":"method","name":"hasChildren","return":{"description":"","type":"Boolean"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":217,"description":"<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n","itemtype":"method","name":"listChildren","return":{"description":"names of the children of the element","type":"String[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":258,"description":"<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n","itemtype":"method","name":"getChildren","params":[{"name":"name","description":"<p>element name</p>\n","type":"String","optional":true}],"return":{"description":"children of the element","type":"p5.XML[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":314,"description":"<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n","itemtype":"method","name":"getChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"return":{"description":"","type":"p5.XML"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":374,"description":"<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"addChild","params":[{"name":"node","description":"<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n","type":"p5.XML"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":426,"description":"<p>Removes the element specified by name or index.</p>\n","itemtype":"method","name":"removeChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":498,"description":"<p>Counts the specified element's number of attributes, returned as an Number.</p>\n","itemtype":"method","name":"getAttributeCount","return":{"description":"","type":"Integer"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":534,"description":"<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n","itemtype":"method","name":"listAttributes","return":{"description":"an array of strings containing the names of attributes","type":"String[]"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":577,"description":"<p>Checks whether or not an element has the specified attribute.</p>\n","itemtype":"method","name":"hasAttribute","params":[{"name":"the","description":"<p>attribute to be checked</p>\n","type":"String"}],"return":{"description":"true if attribute found else false","type":"Boolean"},"example":["\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":622,"description":"<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"Number"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":669,"description":"<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n","itemtype":"method","name":"getString","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":716,"description":"<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n","itemtype":"method","name":"setAttribute","params":[{"name":"name","description":"<p>the full name of the attribute</p>\n","type":"String"},{"name":"value","description":"<p>the value of the attribute</p>\n","type":"Number|String|Boolean"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":757,"description":"<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n","itemtype":"method","name":"getContent","params":[{"name":"defaultValue","description":"<p>value returned if no content is found</p>\n","type":"String","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":798,"description":"<p>Sets the element's content.</p>\n","itemtype":"method","name":"setContent","params":[{"name":"text","description":"<p>the new content</p>\n","type":"String"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":839,"description":"<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n","itemtype":"method","name":"serialize","return":{"description":"Serialized string of the element","type":"String"},"example":["\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/math/calculation.js","line":10,"description":"<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n","itemtype":"method","name":"abs","params":[{"name":"n","description":"<p>number to compute</p>\n","type":"Number"}],"return":{"description":"absolute value of given number","type":"Number"},"example":["\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":33,"description":"<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n","itemtype":"method","name":"ceil","params":[{"name":"n","description":"<p>number to round up</p>\n","type":"Number"}],"return":{"description":"rounded up number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":72,"description":"<p>Constrains a value between a minimum and maximum value.</p>\n","itemtype":"method","name":"constrain","params":[{"name":"n","description":"<p>number to constrain</p>\n","type":"Number"},{"name":"low","description":"<p>minimum limit</p>\n","type":"Number"},{"name":"high","description":"<p>maximum limit</p>\n","type":"Number"}],"return":{"description":"constrained number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"],"alt":"2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":116,"description":"<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"distance between the two points","type":"Number"},"example":["\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"],"alt":"2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":116,"params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}},{"line":161,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}}]},{"file":"src/math/calculation.js","line":182,"description":"<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n","itemtype":"method","name":"exp","params":[{"name":"n","description":"<p>exponent to raise</p>\n","type":"Number"}],"return":{"description":"e^n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. e^n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":231,"description":"<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n","itemtype":"method","name":"floor","params":[{"name":"n","description":"<p>number to round down</p>\n","type":"Number"}],"return":{"description":"rounded down number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":269,"description":"<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n","itemtype":"method","name":"lerp","params":[{"name":"start","description":"<p>first value</p>\n","type":"Number"},{"name":"stop","description":"<p>second value</p>\n","type":"Number"},{"name":"amt","description":"<p>number</p>\n","type":"Number"}],"return":{"description":"lerped value","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"],"alt":"5 points horizontally staggered mid-canvas. mid 3 are grey, outer black","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":316,"description":"<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n","itemtype":"method","name":"log","params":[{"name":"n","description":"<p>number greater than 0</p>\n","type":"Number"}],"return":{"description":"natural logarithm of n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. natural logarithm of n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":371,"description":"<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n","itemtype":"method","name":"mag","params":[{"name":"a","description":"<p>first value</p>\n","type":"Number"},{"name":"b","description":"<p>second value</p>\n","type":"Number"}],"return":{"description":"magnitude of vector from (0,0) to (a,b)","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"],"alt":"4 lines of different length radiate from top left of canvas.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":409,"description":"<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n","itemtype":"method","name":"map","params":[{"name":"value","description":"<p>the incoming value to be converted</p>\n","type":"Number"},{"name":"start1","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop1","description":"<p>upper bound of the value's current range</p>\n","type":"Number"},{"name":"start2","description":"<p>lower bound of the value's target range</p>\n","type":"Number"},{"name":"stop2","description":"<p>upper bound of the value's target range</p>\n","type":"Number"},{"name":"withinBounds","description":"<p>constrain the value to the newly mapped range</p>\n","type":"Boolean","optional":true}],"return":{"description":"remapped number","type":"Number"},"example":["\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"],"alt":"10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":464,"description":"<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"max","return":{"description":"maximum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":464,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"maximum Number","type":"Number"}},{"line":499,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":512,"description":"<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"min","return":{"description":"minimum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":512,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"minimum Number","type":"Number"}},{"line":547,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":560,"description":"<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n","itemtype":"method","name":"norm","params":[{"name":"value","description":"<p>incoming value to be normalized</p>\n","type":"Number"},{"name":"start","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop","description":"<p>upper bound of the value's current range</p>\n","type":"Number"}],"return":{"description":"normalized number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"],"alt":"ellipse moves with mouse. 0 shown left & 100 right and updating values center","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":612,"description":"<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n","itemtype":"method","name":"pow","params":[{"name":"n","description":"<p>base of the exponential expression</p>\n","type":"Number"},{"name":"e","description":"<p>power by which to raise the base</p>\n","type":"Number"}],"return":{"description":"n^e","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"],"alt":"small to large ellipses radiating from top left of canvas","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":646,"description":"<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n","itemtype":"method","name":"round","params":[{"name":"n","description":"<p>number to round</p>\n","type":"Number"},{"name":"decimals","description":"<p>number of decimal places to round to, default is 0</p>\n","type":"Number","optional":true}],"return":{"description":"rounded number","type":"Integer"},"example":["\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":701,"description":"<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n","itemtype":"method","name":"sq","params":[{"name":"n","description":"<p>number to square</p>\n","type":"Number"}],"return":{"description":"squared number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squared values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":745,"description":"<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n","itemtype":"method","name":"sqrt","params":[{"name":"n","description":"<p>non-negative number to square root</p>\n","type":"Number"}],"return":{"description":"square root of number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squareroot values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":832,"description":"<p>Calculates the fractional part of a number.</p>\n","itemtype":"method","name":"fract","params":[{"name":"num","description":"<p>Number whose fractional part needs to be found out</p>\n","type":"Number"}],"return":{"description":"fractional part of x, i.e, {x}","type":"Number"},"example":["\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"],"alt":"first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/math.js","line":10,"description":"<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n","itemtype":"method","name":"createVector","params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"p5.Vector"},"example":["\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"],"alt":"draws a line from center of canvas to mouse pointer position.","class":"p5","module":"Math","submodule":"Vector"},{"file":"src/math/noise.js","line":36,"description":"<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n","itemtype":"method","name":"noise","params":[{"name":"x","description":"<p>x-coordinate in noise space</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate in noise space</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z-coordinate in noise space</p>\n","type":"Number","optional":true}],"return":{"description":"Perlin noise value (between 0 and 1) at specified\n                     coordinates","type":"Number"},"example":["\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"],"alt":"vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":178,"description":"<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n","itemtype":"method","name":"noiseDetail","params":[{"name":"lod","description":"<p>number of octaves to be used by the noise</p>\n","type":"Number"},{"name":"falloff","description":"<p>falloff factor for each octave</p>\n","type":"Number"}],"example":["\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"],"alt":"2 vertical grey smokey patterns affected my mouse x-position and noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":243,"description":"<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n","itemtype":"method","name":"noiseSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"],"alt":"vertical grey lines drawing in pattern affected by noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/p5.Vector.js","line":69,"description":"<p>The x component of the vector</p>\n","itemtype":"property","name":"x","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":74,"description":"<p>The y component of the vector</p>\n","itemtype":"property","name":"y","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":79,"description":"<p>The z component of the vector</p>\n","itemtype":"property","name":"z","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":86,"description":"<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n","itemtype":"method","name":"toString","return":{"description":"","type":"String"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":136,"description":"<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n","itemtype":"method","name":"set","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":136,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":195,"params":[{"name":"value","description":"<p>the vector to set</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/math/p5.Vector.js","line":219,"description":"<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n","itemtype":"method","name":"copy","return":{"description":"the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":248,"description":"<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"add","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":248,"params":[{"name":"x","description":"<p>the x component of the vector to be added</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to be added</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to be added</p>\n","type":"Number","optional":true}],"chainable":1},{"line":325,"params":[{"name":"value","description":"<p>the vector to add</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2059,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":372,"description":"<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n","itemtype":"method","name":"rem","chainable":1,"example":["\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":372,"params":[{"name":"x","description":"<p>the x component of divisor vector</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of divisor vector</p>\n","type":"Number"},{"name":"z","description":"<p>the z component of divisor vector</p>\n","type":"Number"}],"chainable":1},{"line":401,"params":[{"name":"value","description":"<p>divisor vector</p>\n","type":"p5.Vector | Number[]"}],"chainable":1},{"line":2085,"params":[{"name":"v1","description":"<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1},{"line":2091,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":461,"description":"<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"sub","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":461,"params":[{"name":"x","description":"<p>the x component of the vector to subtract</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to subtract</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to subtract</p>\n","type":"Number","optional":true}],"chainable":1},{"line":538,"params":[{"name":"value","description":"<p>the vector to subtract</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2110,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":562,"description":"<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"mult","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":562,"params":[{"name":"n","description":"<p>The number to multiply with the vector</p>\n","type":"Number"}],"chainable":1},{"line":655,"params":[{"name":"x","description":"<p>The number to multiply with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to multiply with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to multiply with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":663,"params":[{"name":"arr","description":"<p>The array to multiply with the components of the vector</p>\n","type":"Number[]"}],"chainable":1},{"line":669,"params":[{"name":"v","description":"<p>The vector to multiply with the components of the original vector</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2139,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2148,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2156,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2164,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":754,"description":"<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"div","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":754,"params":[{"name":"n","description":"<p>The number to divide the vector by</p>\n","type":"Number"}],"chainable":1},{"line":847,"params":[{"name":"x","description":"<p>The number to divide with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to divide with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to divide with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":855,"params":[{"name":"arr","description":"<p>The array to divide the components of the vector by</p>\n","type":"Number[]"}],"chainable":1},{"line":861,"params":[{"name":"v","description":"<p>The vector to divide the components of the original vector by</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2218,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2227,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2235,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2243,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":959,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","itemtype":"method","name":"mag","return":{"description":"magnitude of the vector","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":959,"params":[],"return":{"description":"magnitude of the vector","type":"Number"}},{"line":2343,"params":[{"name":"vecT","description":"<p>the vector to return the magnitude of</p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the magnitude of vecT","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1007,"description":"<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n","itemtype":"method","name":"magSq","return":{"description":"squared magnitude of the vector","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1061,"description":"<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n","itemtype":"method","name":"dot","return":{"description":"the dot product","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1061,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"the dot product","type":"Number"}},{"line":1091,"params":[{"name":"value","description":"<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"","type":"Number"}},{"line":2270,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the dot product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1103,"description":"<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n","itemtype":"method","name":"cross","return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1103,"params":[{"name":"v","description":"<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n","type":"p5.Vector"}],"return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"}},{"line":2284,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the cross product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1145,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"the distance","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1145,"params":[{"name":"v","description":"<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the distance","type":"Number"}},{"line":2299,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the distance","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1217,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","itemtype":"method","name":"normalize","return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1217,"params":[],"return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2360,"params":[{"name":"v","description":"<p>the vector to normalize</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"v normalized to a length of 1","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1287,"description":"<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n","itemtype":"method","name":"limit","params":[{"name":"max","description":"<p>the maximum magnitude for the vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1345,"description":"<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n","itemtype":"method","name":"setMag","params":[{"name":"len","description":"<p>the new length for this vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1401,"description":"<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"heading","return":{"description":"the angle of rotation","type":"Number"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1473,"description":"<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"setHeading","params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1498,"description":"<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"rotate","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1498,"params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1},{"line":2191,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":1567,"description":"<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"angleBetween","params":[{"name":"value","description":"<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the angle between (in radians)","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1647,"description":"<p>Linear interpolate the vector to another vector</p>\n","itemtype":"method","name":"lerp","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1647,"params":[{"name":"x","description":"<p>the x component</p>\n","type":"Number"},{"name":"y","description":"<p>the y component</p>\n","type":"Number"},{"name":"z","description":"<p>the z component</p>\n","type":"Number"},{"name":"amt","description":"<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n","type":"Number"}],"chainable":1},{"line":1720,"params":[{"name":"v","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"}],"chainable":1},{"line":2314,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the lerped value","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1736,"description":"<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n","itemtype":"method","name":"reflect","params":[{"name":"surfaceNormal","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n","type":"p5.Vector"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1791,"description":"<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n","itemtype":"method","name":"array","return":{"description":"an Array with the 3 values","type":"Number[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1823,"description":"<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","itemtype":"method","name":"equals","return":{"description":"whether the vectors are equals","type":"Boolean"},"example":["\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1823,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"whether the vectors are equals","type":"Boolean"}},{"line":1853,"params":[{"name":"value","description":"<p>the vector to compare</p>\n","type":"p5.Vector|Array"}],"return":{"description":"","type":"Boolean"}}]},{"file":"src/math/p5.Vector.js","line":1878,"description":"<p>Make a new 2D vector from an angle</p>\n","itemtype":"method","name":"fromAngle","static":1,"params":[{"name":"angle","description":"<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1929,"description":"<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n","itemtype":"method","name":"fromAngles","static":1,"params":[{"name":"theta","description":"<p>the polar angle, in radians (zero is up)</p>\n","type":"Number"},{"name":"phi","description":"<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1978,"description":"<p>Make a new 2D unit vector from a random angle</p>\n","itemtype":"method","name":"random2D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2031,"description":"<p>Make a new random 3D unit vector.</p>\n","itemtype":"method","name":"random3D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2135,"description":"<p>Multiplies a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2187,"description":"<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2214,"description":"<p>Divides a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2267,"description":"<p>Calculates the dot product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2281,"description":"<p>Calculates the cross product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2295,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2310,"description":"<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2339,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2357,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/random.js","line":37,"description":"<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n","itemtype":"method","name":"randomSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"],"alt":"many vertical lines drawn in white, black or grey.","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/random.js","line":66,"description":"<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n","itemtype":"method","name":"random","return":{"description":"the random number","type":"Number"},"example":["\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"],"alt":"100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog","class":"p5","module":"Math","submodule":"Random","overloads":[{"line":66,"params":[{"name":"min","description":"<p>the lower bound (inclusive)</p>\n","type":"Number","optional":true},{"name":"max","description":"<p>the upper bound (exclusive)</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"}},{"line":119,"params":[{"name":"choices","description":"<p>the array to choose from</p>\n","type":"Array"}],"return":{"description":"the random element from the array","type":"*"}}]},{"file":"src/math/random.js","line":153,"description":"<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n","itemtype":"method","name":"randomGaussian","params":[{"name":"mean","description":"<p>the mean</p>\n","type":"Number","optional":true},{"name":"sd","description":"<p>the standard deviation</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"},"example":["\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"],"alt":"100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/trigonometry.js","line":18,"description":"<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n","itemtype":"method","name":"acos","params":[{"name":"value","description":"<p>the value whose arc cosine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc cosine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":53,"description":"<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n","itemtype":"method","name":"asin","params":[{"name":"value","description":"<p>the value whose arc sine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc sine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":88,"description":"<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n","itemtype":"method","name":"atan","params":[{"name":"value","description":"<p>the value whose arc tangent is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":123,"description":"<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n","itemtype":"method","name":"atan2","params":[{"name":"y","description":"<p>y-coordinate of the point</p>\n","type":"Number"},{"name":"x","description":"<p>x-coordinate of the point</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given point","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"],"alt":"60 by 10 rect at center of canvas rotates with mouse movements","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":159,"description":"<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"cos","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the cosine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines form wave patterns, extend-down on left and right side","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":186,"description":"<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"sin","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the sine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines extend down and up from center to form wave pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":213,"description":"<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n","itemtype":"method","name":"tan","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the tangent of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"],"alt":"vertical black lines end down and up from center to form spike pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":239,"description":"<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"degrees","params":[{"name":"radians","description":"<p>the radians value to convert to degrees</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":262,"description":"<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"radians","params":[{"name":"degrees","description":"<p>the degree value to convert to radians</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":285,"description":"<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n","itemtype":"method","name":"angleMode","params":[{"name":"mode","description":"<p>either RADIANS or DEGREES</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"],"alt":"40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/typography/attributes.js","line":11,"description":"<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n","itemtype":"method","name":"textAlign","chainable":1,"example":["\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"],"alt":"Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":11,"params":[{"name":"horizAlign","description":"<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n","type":"Constant"},{"name":"vertAlign","description":"<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n","type":"Constant","optional":true}],"chainable":1},{"line":72,"params":[],"return":{"description":"","type":"Object"}}]},{"file":"src/typography/attributes.js","line":81,"description":"<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n","itemtype":"method","name":"textLeading","chainable":1,"example":["\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"],"alt":"A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":81,"params":[{"name":"leading","description":"<p>the size in pixels for spacing between lines</p>\n","type":"Number"}],"chainable":1},{"line":109,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":118,"description":"<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n","itemtype":"method","name":"textSize","chainable":1,"example":["\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"],"alt":"'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":118,"params":[{"name":"theSize","description":"<p>the size of the letters in units of pixels</p>\n","type":"Number"}],"chainable":1},{"line":141,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":150,"description":"<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n","itemtype":"method","name":"textStyle","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"],"alt":"Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":150,"params":[{"name":"theStyle","description":"<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n","type":"Constant"}],"chainable":1},{"line":178,"params":[],"return":{"description":"","type":"String"}}]},{"file":"src/typography/attributes.js","line":187,"description":"<p>Calculates and returns the width of any character or text string.</p>\n","itemtype":"method","name":"textWidth","params":[{"name":"theText","description":"<p>the String of characters to measure</p>\n","type":"String"}],"return":{"description":"the calculated width","type":"Number"},"example":["\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"],"alt":"Letter P and p5.js are displayed with vertical lines at end.","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":222,"description":"<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n","itemtype":"method","name":"textAscent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":251,"description":"<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n","itemtype":"method","name":"textDescent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":280,"description":"<p>Helper function to measure ascent and descent.</p>\n","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":287,"description":"<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n","itemtype":"method","name":"textWrap","params":[{"name":"wrapStyle","description":"<p>text wrapping style, either WORD or CHAR</p>\n","type":"Constant"}],"return":{"description":"wrapStyle","type":"String"},"example":["\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/loading_displaying.js","line":16,"description":"<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n","itemtype":"method","name":"loadFont","params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n","type":"Function","optional":true},{"name":"onError","description":"<p>function to be executed if\n                                   an error occurs</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Font\">p5.Font</a> object","type":"p5.Font"},"example":["\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"],"alt":"p5*js in p5's theme dark pink\np5*js in p5's theme dark pink","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":140,"description":"<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n","itemtype":"method","name":"text","params":[{"name":"str","description":"<p>the alphanumeric\n                                            symbols to be displayed</p>\n","type":"String|Object|Array|Number|Boolean"},{"name":"x","description":"<p>x-coordinate of text</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of text</p>\n","type":"Number"},{"name":"x2","description":"<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true},{"name":"y2","description":"<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"],"alt":"'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":231,"description":"<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n","itemtype":"method","name":"textFont","return":{"description":"the current font / p5 Object","type":"Object"},"example":["\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"],"alt":"word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold","class":"p5","module":"Typography","submodule":"Loading & Displaying","overloads":[{"line":231,"params":[],"return":{"description":"the current font / p5 Object","type":"Object"}},{"line":280,"params":[{"name":"font","description":"<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n","type":"Object|String"},{"name":"size","description":"<p>the font size to use</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/typography/p5.Font.js","line":24,"description":"<p>Underlying opentype font implementation</p>\n","itemtype":"property","name":"font","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":31,"description":"<p>Returns a tight bounding box for the given text string using this\nfont</p>\n","itemtype":"method","name":"textBounds","params":[{"name":"line","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional) Default is 12.</p>\n","type":"Number","optional":true},{"name":"options","description":"<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n","type":"Object","optional":true}],"return":{"description":"a rectangle object with properties: x, y, w, h","type":"Object"},"example":["\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"],"alt":"words Lorem ipsum dol go off canvas and contained by white bounding box","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":175,"description":"<p>Computes an array of points following the path for specified text</p>\n","itemtype":"method","name":"textToPoints","params":[{"name":"txt","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional)</p>\n","type":"Number"},{"name":"options","description":"<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n","type":"Object","optional":true}],"return":{"description":"an array of points, each with x, y, alpha (the path angle)","type":"Array"},"example":["\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"],"class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/utilities/array_functions.js","line":10,"description":"<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n","itemtype":"method","name":"append","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.","params":[{"name":"array","description":"<p>Array to append</p>\n","type":"Array"},{"name":"value","description":"<p>to be added to the Array</p>\n","type":"Any"}],"return":{"description":"the array that was appended to","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":35,"description":"<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n","itemtype":"method","name":"arrayCopy","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.","example":["\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions","overloads":[{"line":35,"params":[{"name":"src","description":"<p>the source Array</p>\n","type":"Array"},{"name":"srcPosition","description":"<p>starting position in the source Array</p>\n","type":"Integer"},{"name":"dst","description":"<p>the destination Array</p>\n","type":"Array"},{"name":"dstPosition","description":"<p>starting position in the destination Array</p>\n","type":"Integer"},{"name":"length","description":"<p>number of Array elements to be copied</p>\n","type":"Integer"}]},{"line":73,"params":[{"name":"src","description":"","type":"Array"},{"name":"dst","description":"","type":"Array"},{"name":"length","description":"","type":"Integer","optional":true}]}]},{"file":"src/utilities/array_functions.js","line":112,"description":"<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n","itemtype":"method","name":"concat","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.","params":[{"name":"a","description":"<p>first Array to concatenate</p>\n","type":"Array"},{"name":"b","description":"<p>second Array to concatenate</p>\n","type":"Array"}],"return":{"description":"concatenated array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":141,"description":"<p>Reverses the order of an array, maps to Array.reverse()</p>\n","itemtype":"method","name":"reverse","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.","params":[{"name":"list","description":"<p>Array to reverse</p>\n","type":"Array"}],"return":{"description":"the reversed list","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":161,"description":"<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n","itemtype":"method","name":"shorten","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.","params":[{"name":"list","description":"<p>Array to shorten</p>\n","type":"Array"}],"return":{"description":"shortened Array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":185,"description":"<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n","itemtype":"method","name":"shuffle","params":[{"name":"array","description":"<p>Array to shuffle</p>\n","type":"Array"},{"name":"bool","description":"<p>modify passed array</p>\n","type":"Boolean","optional":true}],"return":{"description":"shuffled Array","type":"Array"},"example":["\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":227,"description":"<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n","itemtype":"method","name":"sort","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.","params":[{"name":"list","description":"<p>Array to sort</p>\n","type":"Array"},{"name":"count","description":"<p>number of elements to sort, starting from 0</p>\n","type":"Integer","optional":true}],"return":{"description":"the sorted list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":273,"description":"<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n","itemtype":"method","name":"splice","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.","params":[{"name":"list","description":"<p>Array to splice into</p>\n","type":"Array"},{"name":"value","description":"<p>value to be spliced in</p>\n","type":"Any"},{"name":"position","description":"<p>in the array from which to insert data</p>\n","type":"Integer"}],"return":{"description":"the list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":308,"description":"<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n","itemtype":"method","name":"subset","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.","params":[{"name":"list","description":"<p>Array to extract from</p>\n","type":"Array"},{"name":"start","description":"<p>position to begin</p>\n","type":"Integer"},{"name":"count","description":"<p>number of values to extract</p>\n","type":"Integer","optional":true}],"return":{"description":"Array of extracted elements","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/conversion.js","line":10,"description":"<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n","itemtype":"method","name":"float","params":[{"name":"str","description":"<p>float string to parse</p>\n","type":"String"}],"return":{"description":"floating point representation of string","type":"Number"},"example":["\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"],"alt":"20 by 20 white ellipse in the center of the canvas","class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":44,"description":"<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n","itemtype":"method","name":"int","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":44,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"},{"name":"radix","description":"<p>the radix to convert to (default: 10)</p>\n","type":"Integer","optional":true}],"return":{"description":"integer representation of value","type":"Number"}},{"line":66,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"},{"name":"radix","description":"","type":"Integer","optional":true}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":88,"description":"<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n","itemtype":"method","name":"str","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":114,"description":"<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n","itemtype":"method","name":"boolean","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"boolean representation of value","type":"Boolean"},"example":["\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":146,"description":"<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n","itemtype":"method","name":"byte","return":{"description":"byte representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":146,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"}],"return":{"description":"byte representation of value","type":"Number"}},{"line":168,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of byte representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":182,"description":"<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n","itemtype":"method","name":"char","return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":182,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Number"}],"return":{"description":"string representation of value","type":"String"}},{"line":201,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":216,"description":"<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unchar","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":216,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of value","type":"Number"}},{"line":232,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":245,"description":"<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n","itemtype":"method","name":"hex","return":{"description":"hexadecimal string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":245,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"Number"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of value","type":"String"}},{"line":265,"params":[{"name":"ns","description":"<p>array of values to parse</p>\n","type":"Number[]"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":295,"description":"<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unhex","return":{"description":"integer representation of hexadecimal value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":295,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of hexadecimal value","type":"Number"}},{"line":311,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representations of hexadecimal value","type":"Number[]"}}]},{"file":"src/utilities/string_functions.js","line":15,"description":"<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n","itemtype":"method","name":"join","params":[{"name":"list","description":"<p>array of Strings to be joined</p>\n","type":"Array"},{"name":"separator","description":"<p>String to be placed between each item</p>\n","type":"String"}],"return":{"description":"joined String","type":"String"},"example":["\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"],"alt":"\"hello world!\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":43,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n","itemtype":"method","name":"match","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"Array of Strings found","type":"String[]"},"example":["\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"],"alt":"\"p5js*\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":83,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n","itemtype":"method","name":"matchAll","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"2d Array of Strings found","type":"String[]"},"example":["\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":130,"description":"<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nf","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" middle top, -1321.00\" middle bottom canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":130,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"left","description":"<p>number of digits to the left of the\n                               decimal point</p>\n","type":"Integer|String","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":176,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer|String","optional":true},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":237,"description":"<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n","itemtype":"method","name":"nfc","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":237,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"right","description":"<p>number of digits to the right of the\n                                 decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":275,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":311,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n","itemtype":"method","name":"nfp","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":311,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":352,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Number[]"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":373,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nfs","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" top middle and \"-1321.00\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":373,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":430,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":451,"description":"<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n","itemtype":"method","name":"split","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>the String used to separate the data</p>\n","type":"String"}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"],"alt":"\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":484,"description":"<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n","itemtype":"method","name":"splitTokens","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>list of individual Strings that will be used as\n                         separators</p>\n","type":"String","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":537,"description":"<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n","itemtype":"method","name":"trim","return":{"description":"a trimmed String","type":"String"},"example":["\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"],"alt":"\"No new lines here\" displayed center canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":537,"params":[{"name":"str","description":"<p>a String to be trimmed</p>\n","type":"String"}],"return":{"description":"a trimmed String","type":"String"}},{"line":557,"params":[{"name":"strs","description":"<p>an Array of Strings to be trimmed</p>\n","type":"Array"}],"return":{"description":"an Array of trimmed Strings","type":"String[]"}}]},{"file":"src/utilities/time_date.js","line":10,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n","itemtype":"method","name":"day","return":{"description":"the current day","type":"Integer"},"example":["\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"],"alt":"Current day is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":31,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n","itemtype":"method","name":"hour","return":{"description":"the current hour","type":"Integer"},"example":["\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"],"alt":"Current hour is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":52,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n","itemtype":"method","name":"minute","return":{"description":"the current minute","type":"Integer"},"example":["\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current minute is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":73,"description":"<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n","itemtype":"method","name":"millis","return":{"description":"the number of milliseconds since starting the sketch","type":"Number"},"example":["\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"],"alt":"number of milliseconds since sketch has started displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":100,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n","itemtype":"method","name":"month","return":{"description":"the current month","type":"Integer"},"example":["\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current month is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":122,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n","itemtype":"method","name":"second","return":{"description":"the current second","type":"Integer"},"example":["\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"],"alt":"Current second is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":143,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n","itemtype":"method","name":"year","return":{"description":"the current year","type":"Integer"},"example":["\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"],"alt":"Current year is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/webgl/3d_primitives.js","line":13,"description":"<p>Draw a plane with given a width and height</p>\n","itemtype":"method","name":"plane","params":[{"name":"width","description":"<p>width of the plane</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the plane</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"],"alt":"Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.","class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":97,"description":"<p>Draw a box with given width, height and depth</p>\n","itemtype":"method","name":"box","params":[{"name":"width","description":"<p>width of the box</p>\n","type":"Number","optional":true},{"name":"Height","description":"<p>height of the box</p>\n","type":"Number","optional":true},{"name":"depth","description":"<p>depth of the box</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":215,"description":"<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"sphere","params":[{"name":"radius","description":"<p>radius of circle</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>optional number of subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>optional number of subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":419,"description":"<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cylinder","params":[{"name":"radius","description":"<p>radius of the surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cylinder</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n","type":"Integer","optional":true},{"name":"bottomCap","description":"<p>whether to draw the bottom of the cylinder</p>\n","type":"Boolean","optional":true},{"name":"topCap","description":"<p>whether to draw the top of the cylinder</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":554,"description":"<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cone","params":[{"name":"radius","description":"<p>radius of the bottom surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cone</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n","type":"Integer","optional":true},{"name":"cap","description":"<p>whether to draw the base of the cone</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":669,"description":"<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n","itemtype":"method","name":"ellipsoid","params":[{"name":"radiusx","description":"<p>x-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusy","description":"<p>y-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusz","description":"<p>z-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":804,"description":"<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n","itemtype":"method","name":"torus","params":[{"name":"radius","description":"<p>radius of the whole ring</p>\n","type":"Number","optional":true},{"name":"tubeRadius","description":"<p>radius of the tube</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/interaction.js","line":11,"description":"<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n","itemtype":"method","name":"orbitControl","params":[{"name":"sensitivityX","description":"<p>sensitivity to mouse movement along X axis</p>\n","type":"Number","optional":true},{"name":"sensitivityY","description":"<p>sensitivity to mouse movement along Y axis</p>\n","type":"Number","optional":true},{"name":"sensitivityZ","description":"<p>sensitivity to scroll movement along Z axis</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"],"alt":"Camera orbits around a box when mouse is hold-clicked & then moved.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/interaction.js","line":145,"description":"<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n","itemtype":"method","name":"debugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.","class":"p5","module":"3D","submodule":"Interaction","overloads":[{"line":145,"params":[]},{"line":278,"params":[{"name":"mode","description":"<p>either GRID or AXES</p>\n","type":"Constant"}]},{"line":283,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"gridSize","description":"<p>size of one side of the grid</p>\n","type":"Number","optional":true},{"name":"gridDivisions","description":"<p>number of divisions in the grid</p>\n","type":"Number","optional":true},{"name":"xOff","description":"<p>X axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"yOff","description":"<p>Y axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"zOff","description":"<p>Z axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true}]},{"line":293,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"axesSize","description":"<p>size of axes icon</p>\n","type":"Number","optional":true},{"name":"xOff","description":"","type":"Number","optional":true},{"name":"yOff","description":"","type":"Number","optional":true},{"name":"zOff","description":"","type":"Number","optional":true}]},{"line":302,"params":[{"name":"gridSize","description":"","type":"Number","optional":true},{"name":"gridDivisions","description":"","type":"Number","optional":true},{"name":"gridXOff","description":"","type":"Number","optional":true},{"name":"gridYOff","description":"","type":"Number","optional":true},{"name":"gridZOff","description":"","type":"Number","optional":true},{"name":"axesSize","description":"","type":"Number","optional":true},{"name":"axesXOff","description":"","type":"Number","optional":true},{"name":"axesYOff","description":"","type":"Number","optional":true},{"name":"axesZOff","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/interaction.js","line":353,"description":"<p>Turns off debugMode() in a 3D sketch.</p>\n","itemtype":"method","name":"noDebugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/light.js","line":11,"description":"<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n","itemtype":"method","name":"ambientLight","chainable":1,"example":["\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"],"alt":"evenly distributed light across a sphere\nevenly distributed light across a rotating sphere","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":11,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"<p>the alpha value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":51,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":57,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":64,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":71,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":92,"description":"<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n","itemtype":"method","name":"specularColor","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"different specular light sources from top and bottom of canvas","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":92,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"}],"chainable":1},{"line":139,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":145,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"}],"chainable":1},{"line":151,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":158,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":177,"description":"<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n","itemtype":"method","name":"directionalLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"light source on canvas changeable with mouse position","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":177,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"position","description":"<p>the direction of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":210,"params":[{"name":"color","description":"<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"<p>x axis direction</p>\n","type":"Number"},{"name":"y","description":"<p>y axis direction</p>\n","type":"Number"},{"name":"z","description":"<p>z axis direction</p>\n","type":"Number"}],"chainable":1},{"line":220,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1},{"line":227,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1}]},{"file":"src/webgl/light.js","line":280,"description":"<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n","itemtype":"method","name":"pointLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"spot light on canvas changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":280,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"}],"chainable":1},{"line":322,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":331,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1},{"line":341,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1}]},{"file":"src/webgl/light.js","line":387,"description":"<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n","itemtype":"method","name":"lights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"the light is partially ambient and partially directional","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":425,"description":"<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n","itemtype":"method","name":"lightFalloff","params":[{"name":"constant","description":"<p>constant value for determining falloff</p>\n","type":"Number"},{"name":"linear","description":"<p>linear value for determining falloff</p>\n","type":"Number"},{"name":"quadratic","description":"<p>quadratic value for determining falloff</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"],"alt":"Two spheres with different falloff values show different intensity of light","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":519,"description":"<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n","itemtype":"method","name":"spotLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Spot light on a sphere which changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":519,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"},{"name":"rx","description":"<p>x axis direction of light</p>\n","type":"Number"},{"name":"ry","description":"<p>y axis direction of light</p>\n","type":"Number"},{"name":"rz","description":"<p>z axis direction of light</p>\n","type":"Number"},{"name":"angle","description":"<p>optional parameter for angle. Defaults to PI/3</p>\n","type":"Number","optional":true},{"name":"conc","description":"<p>optional parameter for concentration. Defaults to 100</p>\n","type":"Number","optional":true}],"chainable":1},{"line":571,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"},{"name":"direction","description":"<p>the direction of the light</p>\n","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":580,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":590,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":600,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":610,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":622,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":634,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/light.js","line":859,"description":"<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n","itemtype":"method","name":"noLights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"],"alt":"Three white spheres. Each appears as a different\ncolor due to lighting.","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/loading.js","line":12,"description":"<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n","itemtype":"method","name":"loadModel","return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"},"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>","\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d teapot with red, green and blue gradient.","class":"p5","module":"Shape","submodule":"3D Models","overloads":[{"line":12,"params":[{"name":"path","description":"<p>Path of the model to be loaded</p>\n","type":"String"},{"name":"normalize","description":"<p>If true, scale the model to a\n                                     standardized size when loading</p>\n","type":"Boolean"},{"name":"successCallback","description":"<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                                        the model fails to load.</p>\n","type":"Function(Event)","optional":true},{"name":"fileType","description":"<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}},{"line":96,"params":[{"name":"path","description":"","type":"String"},{"name":"successCallback","description":"","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"","type":"Function(Event)","optional":true},{"name":"fileType","description":"","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}}]},{"file":"src/webgl/loading.js","line":179,"description":"<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":290,"description":"<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":317,"description":"<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":344,"description":"<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":356,"description":"<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":444,"description":"<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":588,"description":"<p>Render a 3d model to the screen.</p>\n","itemtype":"method","name":"model","params":[{"name":"model","description":"<p>Loaded 3d model to be rendered</p>\n","type":"p5.Geometry"}],"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d octahedron.","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/material.js","line":12,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"loadShader","params":[{"name":"vertFilename","description":"<p>path to file containing vertex shader\nsource code</p>\n","type":"String"},{"name":"fragFilename","description":"<p>path to file containing fragment shader\nsource code</p>\n","type":"String"},{"name":"callback","description":"<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n","type":"Function","optional":true}],"return":{"description":"a shader object created from the provided\nvertex and fragment shader files.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":111,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"createShader","params":[{"name":"vertSrc","description":"<p>source code for the vertex shader</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader</p>\n","type":"String"}],"return":{"description":"a shader object created from the provided\nvertex and fragment shaders.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":184,"description":"<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"shader","chainable":1,"params":[{"name":"s","description":"<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n","type":"p5.Shader"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":282,"description":"<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n","itemtype":"method","name":"resetShader","chainable":1,"example":["\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"],"alt":"Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":368,"description":"<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"texture","params":[{"name":"tex","description":"<p>image to use as texture</p>\n","type":"p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"}],"chainable":1,"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>","\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>","\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using normalized coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":511,"description":"<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n","itemtype":"method","name":"textureMode","params":[{"name":"mode","description":"<p>either IMAGE or NORMAL</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using image coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":587,"description":"<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n","itemtype":"method","name":"textureWrap","params":[{"name":"wrapX","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant"},{"name":"wrapY","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"],"alt":"an image of the rocky mountains repeated in mirrored tiles","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":659,"description":"<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"normalMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Red, green and blue gradient.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":697,"description":"<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"ambientMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":697,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":757,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":777,"description":"<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n","itemtype":"method","name":"emissiveMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":777,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true},{"name":"a","description":"<p>opacity</p>\n","type":"Number","optional":true}],"chainable":1},{"line":809,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":829,"description":"<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"specularMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"],"alt":"torus with specular material","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":829,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":870,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":882,"params":[{"name":"color","description":"<p>color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":902,"description":"<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n","itemtype":"method","name":"shininess","params":[{"name":"shine","description":"<p>Degree of Shininess.\n                      Defaults to 1.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"],"alt":"Shininess on Camera changes position with mouse","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/p5.Camera.js","line":13,"description":"<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n","itemtype":"method","name":"camera","is_constructor":1,"params":[{"name":"x","description":"<p>camera position value on x axis</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>camera position value on y axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>camera position value on z axis</p>\n","type":"Number","optional":true},{"name":"centerX","description":"<p>x coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerY","description":"<p>y coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerZ","description":"<p>z coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"upX","description":"<p>x component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upY","description":"<p>y component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upZ","description":"<p>z component of direction 'up' from camera</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":115,"description":"<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n","itemtype":"method","name":"perspective","params":[{"name":"fovy","description":"<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n","type":"Number","optional":true},{"name":"aspect","description":"<p>camera frustum aspect ratio</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>frustum near plane length</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>frustum far plane length</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":176,"description":"<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n","itemtype":"method","name":"ortho","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":236,"description":"<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n","itemtype":"method","name":"frustum","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":303,"description":"<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n","itemtype":"method","name":"createCamera","return":{"description":"The newly created camera object.","type":"p5.Camera"},"example":["\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"],"alt":"An example that creates a camera and moves it around the box.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":444,"description":"<p>camera position value on x axis</p>\n","itemtype":"property","name":"eyeX","type":"Number","readonly":"","example":["\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":472,"description":"<p>camera position value on y axis</p>\n","itemtype":"property","name":"eyeY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":499,"description":"<p>camera position value on z axis</p>\n","itemtype":"property","name":"eyeZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":526,"description":"<p>x coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":554,"description":"<p>y coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":582,"description":"<p>z coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":610,"description":"<p>x component of direction 'up' from camera</p>\n","itemtype":"property","name":"upX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":633,"description":"<p>y component of direction 'up' from camera</p>\n","itemtype":"property","name":"upY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":656,"description":"<p>z component of direction 'up' from camera</p>\n","itemtype":"property","name":"upZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":683,"description":"<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"perspective","example":["\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":801,"description":"<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"ortho","example":["\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":897,"description":"<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"frustum","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1040,"description":"<p>Panning rotates the camera view to the left and right.</p>\n","itemtype":"method","name":"pan","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1098,"description":"<p>Tilting rotates the camera view up and down.</p>\n","itemtype":"method","name":"tilt","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view tilts up and down across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1156,"description":"<p>Reorients the camera to look at a position in world space.</p>\n","itemtype":"method","name":"lookAt","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view of rotating 3D cubes changes to look at a new random\npoint every second .","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1223,"description":"<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"camera","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1386,"description":"<p>Move camera along its local axes while maintaining current camera orientation.</p>\n","itemtype":"method","name":"move","params":[{"name":"x","description":"<p>amount to move along camera's left-right axis</p>\n","type":"Number"},{"name":"y","description":"<p>amount to move along camera's up-down axis</p>\n","type":"Number"},{"name":"z","description":"<p>amount to move along camera's forward-backward axis</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"],"alt":"camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1458,"description":"<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n","itemtype":"method","name":"setPosition","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"],"alt":"camera position changes as the user presses keys, altering view of a 3D box","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1723,"description":"<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n","itemtype":"method","name":"setCamera","params":[{"name":"cam","description":"<p>p5.Camera object</p>\n","type":"p5.Camera"}],"example":["\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"Canvas switches between two camera views, each showing a series of spinning\n3D boxes.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Geometry.js","line":71,"description":"<p>computes faces for geometry objects based on the vertices.</p>\n","itemtype":"method","name":"computeFaces","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":114,"description":"<p>computes smooth normals per vertex as an average of each\nface.</p>\n","itemtype":"method","name":"computeNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":153,"description":"<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n","itemtype":"method","name":"averageNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":174,"description":"<p>Averages pole normals.  Used in spherical primitives</p>\n","itemtype":"method","name":"averagePoleNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":267,"description":"<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n","itemtype":"method","name":"normalize","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.RendererGL.js","line":334,"description":"<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n","itemtype":"method","name":"setAttributes","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"],"alt":"a rotating cube with smoother edges","class":"p5","module":"Rendering","submodule":"Rendering","overloads":[{"line":334,"params":[{"name":"key","description":"<p>Name of attribute</p>\n","type":"String"},{"name":"value","description":"<p>New value of named attribute</p>\n","type":"Boolean"}]},{"line":473,"params":[{"name":"obj","description":"<p>object with key-value pairs</p>\n","type":"Object"}]}]},{"file":"src/webgl/p5.Shader.js","line":306,"description":"<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n","itemtype":"method","name":"setUniform","chainable":1,"params":[{"name":"uniformName","description":"<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n","type":"String"},{"name":"data","description":"<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n","type":"Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5.Shader","module":"3D","submodule":"Material"},{"file":"lib/addons/p5.sound.js","line":1,"class":"p5.sound","module":"3D"},{"file":"lib/addons/p5.sound.js","line":52,"description":"<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n","class":"p5.sound","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":159,"description":"<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>","itemtype":"method","name":"getAudioContext","return":{"description":"AudioContext for this sketch","type":"Object"},"example":["\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":198,"description":"<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>","params":[{"name":"element(s)","description":"<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n","type":"Element|Array","optional":true},{"name":"callback","description":"<p>Callback to invoke when the AudioContext\n                              has started</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that resolves when\n                                     the AudioContext state is 'running'","type":"Promise"},"itemtype":"method","name":"userStartAudio","example":["\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":401,"description":"<p>This module has shims</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":536,"description":"<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":726,"description":"<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n","itemtype":"method","name":"getOutputVolume","return":{"description":"Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":738,"description":"<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>","itemtype":"method","name":"outputVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":782,"description":"<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n","itemtype":"property","name":"soundOut","type":"Object","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":807,"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":811,"description":"<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"samplerate samples per second","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":825,"description":"<p>Returns the closest MIDI note value for\na given frequency.</p>\n","itemtype":"method","name":"freqToMidi","params":[{"name":"frequency","description":"<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n","type":"Number"}],"return":{"description":"MIDI note value","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":841,"description":"<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n","itemtype":"method","name":"midiToFreq","params":[{"name":"midiNote","description":"<p>The number of a MIDI note</p>\n","type":"Number"}],"return":{"description":"Frequency value of the given MIDI note","type":"Number"},"example":["\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":925,"description":"<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n","itemtype":"method","name":"soundFormats","params":[{"name":"formats","description":"<p>i.e. 'mp3', 'wav', 'ogg'</p>\n","type":"String","optional":true,"multiple":true}],"example":["\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1040,"description":"<p>Used by Osc and Envelope to chain signal math</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1145,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n","itemtype":"method","name":"saveSound","params":[{"name":"soundFile","description":"<p>p5.SoundFile that you wish to save</p>\n","type":"p5.SoundFile"},{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1662,"description":"<p>Returns true if the sound file finished loading successfully.</p>\n","itemtype":"method","name":"isLoaded","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1679,"description":"<p>Play the p5.SoundFile</p>\n","itemtype":"method","name":"play","params":[{"name":"startTime","description":"<p>(optional) schedule playback to start (in seconds from now).</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) amplitude (volume)\n                                    of playback</p>\n","type":"Number","optional":true},{"name":"cueStart","description":"<p>(optional) cue start time in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) duration of playback in seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1787,"description":"<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n","itemtype":"method","name":"playMode","params":[{"name":"str","description":"<p>'restart' or 'sustain' or 'untilDone'</p>\n","type":"String"}],"example":["\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1847,"description":"<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n","itemtype":"method","name":"pause","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                             seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1905,"description":"<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n","itemtype":"method","name":"loop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            seconds from now</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) playback volume</p>\n","type":"Number","optional":true},{"name":"cueLoopStart","description":"<p>(optional) startTime in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) loop duration in seconds</p>\n","type":"Number","optional":true}],"example":["\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1950,"description":"<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n","itemtype":"method","name":"setLoop","params":[{"name":"Boolean","description":"<p>set looping to true or false</p>\n","type":"Boolean"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1976,"description":"<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n","itemtype":"method","name":"isLooping","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1997,"description":"<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n","itemtype":"method","name":"isPlaying","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2011,"description":"<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n","itemtype":"method","name":"isPaused","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2025,"description":"<p>Stop soundfile playback.</p>\n","itemtype":"method","name":"stop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            in seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2087,"description":"<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n","itemtype":"method","name":"pan","params":[{"name":"panValue","description":"<p>Set the stereo panner</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                                seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2131,"description":"<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n","itemtype":"method","name":"getPan","return":{"description":"Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2146,"description":"<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n","itemtype":"method","name":"rate","params":[{"name":"playbackRate","description":"<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2239,"description":"<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n","itemtype":"method","name":"setVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2276,"description":"<p>Returns the duration of a sound file in seconds.</p>\n","itemtype":"method","name":"duration","return":{"description":"The duration of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2293,"description":"<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n","itemtype":"method","name":"currentTime","return":{"description":"currentTime of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2308,"description":"<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n","itemtype":"method","name":"jump","params":[{"name":"cueTime","description":"<p>cueTime of the soundFile in seconds.</p>\n","type":"Number"},{"name":"duration","description":"<p>duration in seconds.</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2340,"description":"<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n","itemtype":"method","name":"channels","return":{"description":"[channels]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2354,"description":"<p>Return the sample rate of the sound file.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"[sampleRate]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2367,"description":"<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n","itemtype":"method","name":"frames","return":{"description":"[sampleCount]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2381,"description":"<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n","itemtype":"method","name":"getPeaks","params":[{"name":"length","description":"<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n","type":"Number","optional":true}],"return":{"description":"Array of peaks.","type":"Float32Array"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2443,"description":"<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n","itemtype":"method","name":"reverseBuffer","example":["\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2497,"description":"<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended.</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2565,"description":"<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n","itemtype":"method","name":"connect","params":[{"name":"object","description":"<p>Audio object that accepts an input</p>\n","type":"Object","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2590,"description":"<p>Disconnects the output of this p5sound object.</p>\n","itemtype":"method","name":"disconnect","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2604,"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2612,"description":"<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n","itemtype":"method","name":"setPath","params":[{"name":"path","description":"<p>path to audio file</p>\n","type":"String"},{"name":"callback","description":"<p>Callback</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2630,"description":"<p>Replace the current Audio Buffer with a new Buffer.</p>\n","itemtype":"method","name":"setBuffer","params":[{"name":"buf","description":"<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n","type":"Array"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2719,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2790,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2817,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2850,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n","itemtype":"method","name":"save","params":[{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String","optional":true}],"example":["\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2882,"description":"<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n","itemtype":"method","name":"getBlob","return":{"description":"A file-like data object","type":"Blob"},"example":["\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2946,"description":"<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n","itemtype":"method","name":"loadSound","params":[{"name":"path","description":"<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n","type":"Function","optional":true},{"name":"whileLoading","description":"<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a p5.SoundFile","type":"SoundFile"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3117,"description":"<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n","itemtype":"method","name":"setInput","params":[{"name":"snd","description":"<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n","type":"SoundObject|undefined","optional":true},{"name":"smoothing","description":"<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n","type":"Number|undefined","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3209,"description":"<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n","itemtype":"method","name":"getLevel","params":[{"name":"channel","description":"<p>Optionally return only channel 0 (left) or 1 (right)</p>\n","type":"Number","optional":true}],"return":{"description":"Amplitude as a number between 0.0 and 1.0","type":"Number"},"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3264,"description":"<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n","itemtype":"method","name":"toggleNormalize","params":[{"name":"boolean","description":"<p>set normalize to true (1) or false (0)</p>\n","type":"Boolean","optional":true}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3293,"description":"<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"set","description":"<p>smoothing from 0.0 <= 1</p>\n","type":"Number"}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3476,"description":"<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"source","description":"<p>p5.sound object (or web audio API source node)</p>\n","type":"Object","optional":true}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3501,"description":"<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n","itemtype":"method","name":"waveform","params":[{"name":"bins","description":"<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"precision","description":"<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n","type":"String","optional":true}],"return":{"description":"Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3553,"description":"<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n","itemtype":"method","name":"analyze","params":[{"name":"bins","description":"<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"scale","description":"<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n","type":"Number","optional":true}],"return":{"description":"spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.","type":"Array"},"example":["\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3650,"description":"<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n","itemtype":"method","name":"getEnergy","params":[{"name":"frequency1","description":"<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n","type":"Number|String"},{"name":"frequency2","description":"<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n","type":"Number","optional":true}],"return":{"description":"Energy   Energy (volume/amplitude) from\n                            0 and 255.","type":"Number"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3739,"description":"<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n","itemtype":"method","name":"getCentroid","return":{"description":"Spectral Centroid Frequency  of the spectral centroid in Hz.","type":"Number"},"example":["\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3826,"description":"<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"smoothing","description":"<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n","type":"Number"}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3854,"description":"<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"linAverages","params":[{"name":"N","description":"<p>Number of returned frequency groups</p>\n","type":"Number"}],"return":{"description":"linearAverages   Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3889,"description":"<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"logAverages","params":[{"name":"octaveBands","description":"<p>Array of Octave Bands objects for grouping</p>\n","type":"Array"}],"return":{"description":"logAverages    Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3925,"description":"<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n","itemtype":"method","name":"getOctaveBands","params":[{"name":"N","description":"<p>Specifies the 1/N type of generated octave bands</p>\n","type":"Number"},{"name":"fCtr0","description":"<p>Minimum central frequency for the lowest band</p>\n","type":"Number"}],"return":{"description":"octaveBands   Array of octave band objects with their bounds","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4168,"description":"<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>startTime in seconds from now.</p>\n","type":"Number","optional":true},{"name":"frequency","description":"<p>frequency in Hz.</p>\n","type":"Number","optional":true}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4218,"description":"<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n","itemtype":"method","name":"stop","params":[{"name":"secondsFromNow","description":"<p>Time, in seconds from now.</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4238,"description":"<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)","type":"AudioParam"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4271,"description":"<p>Returns the value of output gain</p>\n","itemtype":"method","name":"getAmp","return":{"description":"Amplitude value between 0.0 and 1.0","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4285,"description":"<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n","itemtype":"method","name":"freq","params":[{"name":"Frequency","description":"<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Ramp time (in seconds)</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen\n                                 at x seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency","type":"AudioParam"},"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4360,"description":"<p>Returns the value of frequency of oscillator</p>\n","itemtype":"method","name":"getFreq","return":{"description":"Frequency of oscillator in Hertz","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4373,"description":"<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","type":"String"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4386,"description":"<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"getType","return":{"description":"type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.","type":"String"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4399,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4420,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4444,"description":"<p>Pan between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"pan","params":[{"name":"panning","description":"<p>Number between -1 and 1</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4460,"description":"<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"getPan","return":{"description":"panPosition of oscillator , between Left (-1) and Right (1)","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4494,"description":"<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n","itemtype":"method","name":"phase","params":[{"name":"phase","description":"<p>float between 0.0 and 1.0</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4522,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4543,"description":"<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with multiplied output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4563,"description":"<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4767,"description":"<p>Time until envelope reaches attackLevel</p>\n","itemtype":"property","name":"attackTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4772,"description":"<p>Level once attack is complete.</p>\n","itemtype":"property","name":"attackLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4778,"description":"<p>Time until envelope reaches decayLevel.</p>\n","itemtype":"property","name":"decayTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4784,"description":"<p>Level after decay. The envelope will sustain here until it is released.</p>\n","itemtype":"property","name":"decayLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4790,"description":"<p>Duration of the release portion of the envelope.</p>\n","itemtype":"property","name":"releaseTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4796,"description":"<p>Level at the end of the release.</p>\n","itemtype":"property","name":"releaseLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4833,"description":"<p>Reset the envelope with a series of time/value pairs.</p>\n","itemtype":"method","name":"set","params":[{"name":"attackTime","description":"<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n","type":"Number"},{"name":"attackLevel","description":"<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time</p>\n","type":"Number"},{"name":"decayLevel","description":"<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n","type":"Number"},{"name":"releaseTime","description":"<p>Release Time (in seconds)</p>\n","type":"Number"},{"name":"releaseLevel","description":"<p>Amplitude</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4895,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4964,"description":"<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n","itemtype":"method","name":"setRange","params":[{"name":"aLevel","description":"<p>attack level (defaults to 1)</p>\n","type":"Number"},{"name":"rLevel","description":"<p>release level (defaults to 0)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5037,"description":"<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"inputs","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object","optional":true,"multiple":true}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5055,"description":"<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n","itemtype":"method","name":"setExp","params":[{"name":"isExp","description":"<p>true is exponential, false is linear</p>\n","type":"Boolean"}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5078,"description":"<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>","itemtype":"method","name":"play","params":[{"name":"unit","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object"},{"name":"startTime","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5148,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n","itemtype":"method","name":"triggerAttack","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5256,"description":"<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"triggerRelease","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5350,"description":"<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n","itemtype":"method","name":"ramp","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>When to trigger the ramp</p>\n","type":"Number"},{"name":"v","description":"<p>Target value</p>\n","type":"Number"},{"name":"v2","description":"<p>Second target value</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5460,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5479,"description":"<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5498,"description":"<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5657,"description":"<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'white', 'pink' or 'brown'</p>\n","type":"String","optional":true}],"class":"p5.Noise","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5871,"description":"<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n","itemtype":"method","name":"width","params":[{"name":"width","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.Pulse","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6066,"itemtype":"property","name":"input","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6070,"itemtype":"property","name":"output","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6075,"itemtype":"property","name":"stream","type":"MediaStream|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6080,"itemtype":"property","name":"mediaStream","type":"MediaStreamAudioSourceNode|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6085,"itemtype":"property","name":"currentSource","type":"Number|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6090,"description":"<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n","itemtype":"property","name":"enabled","type":"Boolean","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6098,"description":"<p>Input amplitude, connect to it by default but not to master out</p>\n","itemtype":"property","name":"amplitude","type":"p5.Amplitude","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6114,"description":"<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n","itemtype":"method","name":"start","params":[{"name":"successCallback","description":"<p>Name of a function to call on\n                                  success.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n","type":"Function","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6171,"description":"<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n","itemtype":"method","name":"stop","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6191,"description":"<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>An object that accepts audio input,\n                        such as an FFT</p>\n","type":"Object","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6216,"description":"<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6234,"description":"<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n","itemtype":"method","name":"getLevel","params":[{"name":"smoothing","description":"<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n","type":"Number","optional":true}],"return":{"description":"Volume level (between 0.0 and 1.0)","type":"Number"},"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6257,"description":"<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0</p>\n","type":"Number"},{"name":"time","description":"<p>ramp time (optional)</p>\n","type":"Number","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6280,"description":"<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n","itemtype":"method","name":"getSources","params":[{"name":"successCallback","description":"<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>This optional callback receives the error\n                                   message as its argument.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method","type":"Promise"},"example":["\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6340,"description":"<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n","itemtype":"method","name":"setSource","params":[{"name":"num","description":"<p>position of input source in the array</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6462,"description":"<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6478,"description":"<p>Set the output volume of the filter.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number","optional":true},{"name":"rampTime","description":"<p>create a fade that lasts until rampTime</p>\n","type":"Number","optional":true},{"name":"tFromNow","description":"<p>schedule this event to happen in tFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6502,"description":"<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n","itemtype":"method","name":"chain","params":[{"name":"arguments","description":"<p>Chain together multiple sound objects</p>\n","type":"Object","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6525,"description":"<p>Adjust the dry/wet value.</p>\n","itemtype":"method","name":"drywet","params":[{"name":"fade","description":"<p>The desired drywet value (0 - 1.0)</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6542,"description":"<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6557,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6719,"description":"<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n","itemtype":"property","name":"biquadFilter","type":"DelayNode","class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6742,"description":"<p>Filter an audio signal according to a set\nof filter parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6760,"description":"<p>Set the frequency and the resonance of the filter.</p>\n","itemtype":"method","name":"set","params":[{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance (Q) from 0.001 to 1000</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6781,"description":"<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n","itemtype":"method","name":"freq","params":[{"name":"freq","description":"<p>Filter Frequency</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value  Returns the current frequency value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6811,"description":"<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n","itemtype":"method","name":"res","params":[{"name":"res","description":"<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value Returns the current res value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6838,"description":"<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n","itemtype":"method","name":"gain","params":[{"name":"gain","description":"","type":"Number"}],"return":{"description":"Returns the current or updated gain value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6864,"description":"<p>Toggle function. Switches between the specified type and allpass</p>\n","itemtype":"method","name":"toggle","return":{"description":"[Toggle value]","type":"Boolean"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6884,"description":"<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n","itemtype":"method","name":"setType","params":[{"name":"t","description":"","type":"String"}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7198,"description":"<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n","itemtype":"property","name":"bands","type":"Array","class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7239,"description":"<p>Process an input by connecting it to the EQ</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Audio source</p>\n","type":"Object"}],"class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7629,"description":"<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n","itemtype":"property","name":"panner","type":"AudioNode","class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7654,"description":"<p>Connect an audio sorce</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Input source</p>\n","type":"Object"}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7668,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"set","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7687,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7694,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7701,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7753,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"orient","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7772,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7779,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7786,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7838,"description":"<p>Set the rolloff factor and max distance</p>\n","itemtype":"method","name":"setFalloff","params":[{"name":"maxDistance","description":"","type":"Number","optional":true},{"name":"rolloffFactor","description":"","type":"Number","optional":true}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7852,"description":"<p>Maxium distance between the source and the listener</p>\n","itemtype":"method","name":"maxDist","params":[{"name":"maxDistance","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7869,"description":"<p>How quickly the volume is reduced as the source moves away from the listener</p>\n","itemtype":"method","name":"rollof","params":[{"name":"rolloffFactor","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7989,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"leftDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7999,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"rightDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8049,"description":"<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"delayTime","description":"<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n","type":"Number","optional":true},{"name":"feedback","description":"<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n","type":"Number","optional":true},{"name":"lowPass","description":"<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8094,"description":"<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n","itemtype":"method","name":"delayTime","params":[{"name":"delayTime","description":"<p>Time (in seconds) of the delay</p>\n","type":"Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8116,"description":"<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n","itemtype":"method","name":"feedback","params":[{"name":"feedback","description":"<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n","type":"Number|Object"}],"return":{"description":"Feedback value","type":"Number"},"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8148,"description":"<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n","itemtype":"method","name":"filter","params":[{"name":"cutoffFreq","description":"<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n","type":"Number|Object"},{"name":"res","description":"<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n","type":"Number|Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8170,"description":"<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'pingPong' (1) or 'default' (0)</p>\n","type":"String|Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8223,"description":"<p>Set the output level of the delay effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8234,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8242,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8409,"description":"<p>Connect a source to the reverb, and assign reverb parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"},{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8446,"description":"<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n","itemtype":"method","name":"set","params":[{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8482,"description":"<p>Set the output level of the reverb effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8493,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8501,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8621,"description":"<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n","itemtype":"property","name":"convolverNode","type":"ConvolverNode","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8645,"description":"<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n","itemtype":"property","name":"impulses","type":"Array","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8737,"description":"<p>Connect a source to the convolver.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8786,"description":"<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n","itemtype":"method","name":"addImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8808,"description":"<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n","itemtype":"method","name":"resetImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8831,"description":"<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n","itemtype":"method","name":"toggleImpulse","params":[{"name":"id","description":"<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n","type":"String|Number"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8885,"description":"<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n","itemtype":"method","name":"createConvolver","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true}],"return":{"description":"","type":"p5.Convolver"},"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9084,"description":"<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9173,"description":"<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n","itemtype":"property","name":"sequence","type":"Array","class":"p5.Phrase","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9263,"description":"<p>Set the tempo of this part, in Beats Per Minute.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9278,"description":"<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n","itemtype":"method","name":"getBPM","return":{"description":"","type":"Number"},"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9291,"description":"<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9311,"description":"<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"loop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9333,"description":"<p>Tell the part to stop looping.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9349,"description":"<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n","itemtype":"method","name":"stop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9363,"description":"<p>Pause the part. Playback will resume\nfrom the current step.</p>\n","itemtype":"method","name":"pause","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9379,"description":"<p>Add a p5.Phrase to this Part.</p>\n","itemtype":"method","name":"addPhrase","params":[{"name":"phrase","description":"<p>reference to a p5.Phrase</p>\n","type":"p5.Phrase"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9406,"description":"<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n","itemtype":"method","name":"removePhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9424,"description":"<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n","itemtype":"method","name":"getPhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9442,"description":"<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n","itemtype":"method","name":"replaceSequence","params":[{"name":"phraseName","description":"","type":"String"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9473,"description":"<p>Set the function that will be called at every step. This will clear the previous function.</p>\n","itemtype":"method","name":"onStep","params":[{"name":"callback","description":"<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n","type":"Function"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9542,"description":"<p>Start playback of the score.</p>\n","itemtype":"method","name":"start","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9555,"description":"<p>Stop playback of the score.</p>\n","itemtype":"method","name":"stop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9569,"description":"<p>Pause playback of the score.</p>\n","itemtype":"method","name":"pause","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9581,"description":"<p>Loop playback of the score.</p>\n","itemtype":"method","name":"loop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9594,"description":"<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9628,"description":"<p>Set the tempo for all parts in the score</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9729,"description":"<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n","itemtype":"property","name":"bpm","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9750,"description":"<p>number of quarter notes in a measure (defaults to 4)</p>\n","itemtype":"property","name":"timeSignature","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9770,"description":"<p>length of the loops interval</p>\n","itemtype":"property","name":"interval","type":"Number|String","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9787,"description":"<p>how many times the callback has been called so far</p>\n","itemtype":"property","name":"iterations","type":"Number","readonly":"","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9800,"description":"<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n","itemtype":"property","name":"musicalTimeMode","type":"Boolean","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9808,"description":"<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9816,"description":"<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n","itemtype":"property","name":"maxIterations","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9826,"description":"<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9841,"description":"<p>Start the loop</p>\n","itemtype":"method","name":"start","params":[{"name":"timeFromNow","description":"<p>schedule a starting time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9860,"description":"<p>Stop the loop</p>\n","itemtype":"method","name":"stop","params":[{"name":"timeFromNow","description":"<p>schedule a stopping time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9878,"description":"<p>Pause the loop</p>\n","itemtype":"method","name":"pause","params":[{"name":"timeFromNow","description":"<p>schedule a pausing time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9896,"description":"<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n","itemtype":"method","name":"syncedStart","params":[{"name":"otherLoop","description":"<p>a p5.SoundLoop to sync with</p>\n","type":"Object"},{"name":"timeFromNow","description":"<p>Start the loops in sync after timeFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10068,"description":"<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n","itemtype":"property","name":"compressor","type":"AudioNode","class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10084,"description":"<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Sound source to be connected</p>\n","type":"Object"},{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number","optional":true},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10112,"description":"<p>Set the paramters of a compressor.</p>\n","itemtype":"method","name":"set","params":[{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number"},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number"},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number"},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10152,"description":"<p>Get current attack or set value w/ time ramp</p>\n","itemtype":"method","name":"attack","params":[{"name":"attack","description":"<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10178,"description":"<p>Get current knee or set value w/ time ramp</p>\n","itemtype":"method","name":"knee","params":[{"name":"knee","description":"<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10204,"description":"<p>Get current ratio or set value w/ time ramp</p>\n","itemtype":"method","name":"ratio","params":[{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10228,"description":"<p>Get current threshold or set value w/ time ramp</p>\n","itemtype":"method","name":"threshold","params":[{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10252,"description":"<p>Get current release or set value w/ time ramp</p>\n","itemtype":"method","name":"release","params":[{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10277,"description":"<p>Return the current reduction value</p>\n","itemtype":"method","name":"reduction","return":{"description":"Value of the amount of gain reduction that is applied to the signal","type":"Number"},"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10419,"description":"<p>isDetected is set to true when a peak is detected.</p>\n","itemtype":"attribute","name":"isDetected","type":"Boolean","default":"false","class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10432,"description":"<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n","itemtype":"method","name":"update","params":[{"name":"fftObject","description":"<p>A p5.FFT object</p>\n","type":"p5.FFT"}],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10470,"description":"<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n","itemtype":"method","name":"onPeak","params":[{"name":"callback","description":"<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n","type":"Function"},{"name":"val","description":"<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n","type":"Object","optional":true}],"example":["\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10676,"description":"<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"unit","description":"<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n","type":"Object","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10703,"description":"<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n","itemtype":"method","name":"record","params":[{"name":"soundFile","description":"<p>p5.SoundFile</p>\n","type":"p5.SoundFile"},{"name":"duration","description":"<p>Time (in seconds)</p>\n","type":"Number","optional":true},{"name":"callback","description":"<p>The name of a function that will be\n                              called once the recording completes</p>\n","type":"Function","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10739,"description":"<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n","itemtype":"method","name":"stop","class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10864,"description":"<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n","itemtype":"property","name":"WaveShaperNode","type":"AudioNode","class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10883,"description":"<p>Process a sound source, optionally specify amount and oversample values.</p>\n","itemtype":"method","name":"process","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10900,"description":"<p>Set the amount and oversample of the waveshaper distortion.</p>\n","itemtype":"method","name":"set","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10923,"description":"<p>Return the distortion amount, typically between 0-1.</p>\n","itemtype":"method","name":"getAmount","return":{"description":"Unbounded distortion amount.\n                 Normal values range from 0-1.","type":"Number"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10937,"description":"<p>Return the oversampling.</p>\n","itemtype":"method","name":"getOversample","return":{"description":"Oversample can either be 'none', '2x', or '4x'.","type":"String"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11055,"description":"<p>Connect a source to the gain node.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11070,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11084,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11098,"description":"<p>Set the output level of the gain node.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11181,"description":"<p>Connect to p5 objects or Web Audio Nodes</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11194,"description":"<p>Disconnect from soundOut</p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11322,"description":"<p>Getters and Setters</p>\n","itemtype":"property","name":"attack","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11328,"itemtype":"property","name":"decay","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11333,"itemtype":"property","name":"sustain","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11338,"itemtype":"property","name":"release","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11379,"description":"<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11431,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true}],"itemtype":"method","name":"triggerAttack","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11478,"description":"<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","params":[{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"itemtype":"method","name":"triggerRelease","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11516,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11544,"description":"<p>MonoSynth amp</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>desired volume</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Time to reach new volume</p>\n","type":"Number","optional":true}],"return":{"description":"new volume value","type":"Number"},"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11564,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11578,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11592,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11742,"description":"<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n","itemtype":"property","name":"notes","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11755,"description":"<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n","itemtype":"property","name":"polyvalue","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11761,"description":"<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n","itemtype":"property","name":"AudioVoice","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11800,"description":"<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11849,"description":"<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n","itemtype":"method","name":"noteADSR","params":[{"name":"note","description":"<p>Midi note on which ADSR should be set.</p>\n","type":"Number","optional":true},{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11881,"description":"<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11909,"description":"<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","itemtype":"method","name":"noteAttack","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)/</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12021,"description":"<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"noteRelease","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12105,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12119,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12133,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"}],"warnings":[{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:120"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:216"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:316"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:457"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:1001"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:223"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:248"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/validate_params.js:336"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:12"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:81"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:115"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:184"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:219"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:259"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:331"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:13"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:92"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:130"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:185"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:264"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:358"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:398"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:493"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:20"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:67"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:293"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:415"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:460"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:524"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:583"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:668"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:733"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:826"},{"message":"unknown tag: alt","line":" src/core/constants.js:66"},{"message":"unknown tag: alt","line":" src/core/constants.js:84"},{"message":"unknown tag: alt","line":" src/core/constants.js:102"},{"message":"unknown tag: alt","line":" src/core/constants.js:120"},{"message":"unknown tag: alt","line":" src/core/constants.js:138"},{"message":"unknown tag: alt","line":" src/core/environment.js:20"},{"message":"unknown tag: alt","line":" src/core/environment.js:52"},{"message":"unknown tag: alt","line":" src/core/environment.js:79"},{"message":"unknown tag: alt","line":" src/core/environment.js:129"},{"message":"unknown tag: alt","line":" src/core/environment.js:160"},{"message":"unknown tag: alt","line":" src/core/environment.js:228"},{"message":"unknown tag: alt","line":" src/core/environment.js:331"},{"message":"unknown tag: alt","line":" src/core/environment.js:354"},{"message":"unknown tag: alt","line":" src/core/environment.js:372"},{"message":"unknown tag: alt","line":" src/core/environment.js:390"},{"message":"unknown tag: alt","line":" src/core/environment.js:405"},{"message":"unknown tag: alt","line":" src/core/environment.js:421"},{"message":"unknown tag: alt","line":" src/core/environment.js:500"},{"message":"unknown tag: alt","line":" src/core/environment.js:550"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:586"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:660"},{"message":"unknown tag: alt","line":" src/core/environment.js:691"},{"message":"unknown tag: alt","line":" src/core/environment.js:713"},{"message":"replacing incorrect tag: function with method","line":" src/core/internationalization.js:105"},{"message":"replacing incorrect tag: returns with return","line":" src/core/internationalization.js:105"},{"message":"unknown tag: alt","line":" src/core/main.js:42"},{"message":"unknown tag: alt","line":" src/core/main.js:83"},{"message":"unknown tag: alt","line":" src/core/main.js:114"},{"message":"unknown tag: alt","line":" src/core/main.js:415"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:47"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:114"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:154"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:189"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:246"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:292"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:354"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:403"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:454"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:510"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:551"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:592"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:639"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:678"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:725"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:763"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:70"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:122"},{"message":"unknown tag: alt","line":" src/core/reference.js:7"},{"message":"unknown tag: alt","line":" src/core/reference.js:34"},{"message":"unknown tag: alt","line":" src/core/reference.js:87"},{"message":"unknown tag: alt","line":" src/core/reference.js:115"},{"message":"unknown tag: alt","line":" src/core/reference.js:137"},{"message":"unknown tag: alt","line":" src/core/reference.js:158"},{"message":"unknown tag: alt","line":" src/core/reference.js:179"},{"message":"unknown tag: alt","line":" src/core/reference.js:200"},{"message":"unknown tag: alt","line":" src/core/reference.js:231"},{"message":"unknown tag: alt","line":" src/core/reference.js:267"},{"message":"unknown tag: alt","line":" src/core/reference.js:288"},{"message":"unknown tag: alt","line":" src/core/reference.js:309"},{"message":"unknown tag: alt","line":" src/core/reference.js:331"},{"message":"unknown tag: alt","line":" src/core/reference.js:351"},{"message":"unknown tag: alt","line":" src/core/reference.js:379"},{"message":"unknown tag: alt","line":" src/core/reference.js:408"},{"message":"unknown tag: alt","line":" src/core/reference.js:448"},{"message":"unknown tag: alt","line":" src/core/reference.js:490"},{"message":"unknown tag: alt","line":" src/core/reference.js:512"},{"message":"unknown tag: alt","line":" src/core/rendering.js:15"},{"message":"unknown tag: alt","line":" src/core/rendering.js:125"},{"message":"unknown tag: alt","line":" src/core/rendering.js:183"},{"message":"unknown tag: alt","line":" src/core/rendering.js:204"},{"message":"unknown tag: alt","line":" src/core/rendering.js:243"},{"message":"unknown tag: alt","line":" src/core/rendering.js:326"},{"message":"unknown tag: alt","line":" src/core/structure.js:10"},{"message":"unknown tag: alt","line":" src/core/structure.js:83"},{"message":"unknown tag: alt","line":" src/core/structure.js:134"},{"message":"unknown tag: alt","line":" src/core/structure.js:192"},{"message":"unknown tag: alt","line":" src/core/structure.js:290"},{"message":"unknown tag: alt","line":" src/core/structure.js:391"},{"message":"unknown tag: alt","line":" src/core/structure.js:497"},{"message":"unknown tag: alt","line":" src/core/transform.js:11"},{"message":"unknown tag: alt","line":" src/core/transform.js:168"},{"message":"unknown tag: alt","line":" src/core/transform.js:193"},{"message":"unknown tag: alt","line":" src/core/transform.js:232"},{"message":"unknown tag: alt","line":" src/core/transform.js:268"},{"message":"unknown tag: alt","line":" src/core/transform.js:304"},{"message":"unknown tag: alt","line":" src/core/transform.js:342"},{"message":"unknown tag: alt","line":" src/core/transform.js:416"},{"message":"unknown tag: alt","line":" src/core/transform.js:455"},{"message":"unknown tag: alt","line":" src/core/transform.js:494"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:10"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:101"},{"message":"unknown tag: alt","line":" src/dom/dom.js:204"},{"message":"unknown tag: alt","line":" src/dom/dom.js:271"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1560"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1622"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1726"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1765"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1885"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2268"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2778"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:23"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:46"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:69"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:135"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:168"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:201"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:239"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:285"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:330"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:389"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:428"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:471"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:515"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:546"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:604"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:10"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:36"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:64"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:103"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:190"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:243"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:308"},{"message":"unknown tag: alt","line":" src/events/mouse.js:12"},{"message":"unknown tag: alt","line":" src/events/mouse.js:43"},{"message":"unknown tag: alt","line":" src/events/mouse.js:80"},{"message":"unknown tag: alt","line":" src/events/mouse.js:106"},{"message":"unknown tag: alt","line":" src/events/mouse.js:132"},{"message":"unknown tag: alt","line":" src/events/mouse.js:164"},{"message":"unknown tag: alt","line":" src/events/mouse.js:195"},{"message":"unknown tag: alt","line":" src/events/mouse.js:233"},{"message":"unknown tag: alt","line":" src/events/mouse.js:271"},{"message":"unknown tag: alt","line":" src/events/mouse.js:311"},{"message":"unknown tag: alt","line":" src/events/mouse.js:351"},{"message":"unknown tag: alt","line":" src/events/mouse.js:389"},{"message":"unknown tag: alt","line":" src/events/mouse.js:481"},{"message":"unknown tag: alt","line":" src/events/mouse.js:535"},{"message":"unknown tag: alt","line":" src/events/mouse.js:615"},{"message":"unknown tag: alt","line":" src/events/mouse.js:696"},{"message":"unknown tag: alt","line":" src/events/mouse.js:772"},{"message":"unknown tag: alt","line":" src/events/mouse.js:841"},{"message":"unknown tag: alt","line":" src/events/mouse.js:926"},{"message":"unknown tag: alt","line":" src/events/mouse.js:979"},{"message":"unknown tag: alt","line":" src/events/mouse.js:1025"},{"message":"unknown tag: alt","line":" src/events/touch.js:10"},{"message":"unknown tag: alt","line":" src/events/touch.js:71"},{"message":"unknown tag: alt","line":" src/events/touch.js:151"},{"message":"unknown tag: alt","line":" src/events/touch.js:223"},{"message":"unknown tag: alt","line":" src/image/image.js:15"},{"message":"unknown tag: alt","line":" src/image/image.js:94"},{"message":"unknown tag: alt","line":" src/image/image.js:413"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:18"},{"message":"replacing incorrect tag: returns with return","line":" src/image/loading_displaying.js:284"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:301"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:471"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:569"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:633"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:88"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:115"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:152"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:261"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:296"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:346"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:400"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:437"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:548"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:603"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:665"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:738"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:859"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:900"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:941"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:972"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1017"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1052"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1089"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1125"},{"message":"unknown tag: alt","line":" src/image/pixels.js:12"},{"message":"unknown tag: alt","line":" src/image/pixels.js:80"},{"message":"unknown tag: alt","line":" src/image/pixels.js:173"},{"message":"unknown tag: alt","line":" src/image/pixels.js:307"},{"message":"unknown tag: alt","line":" src/image/pixels.js:481"},{"message":"unknown tag: alt","line":" src/image/pixels.js:566"},{"message":"unknown tag: alt","line":" src/image/pixels.js:602"},{"message":"unknown tag: alt","line":" src/image/pixels.js:674"},{"message":"unknown tag: alt","line":" src/io/files.js:20"},{"message":"unknown tag: alt","line":" src/io/files.js:183"},{"message":"unknown tag: alt","line":" src/io/files.js:303"},{"message":"unknown tag: alt","line":" src/io/files.js:583"},{"message":"replacing incorrect tag: returns with return","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:1393"},{"message":"unknown tag: alt","line":" src/io/files.js:1535"},{"message":"unknown tag: alt","line":" src/io/files.js:1592"},{"message":"unknown tag: alt","line":" src/io/files.js:1656"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:85"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:148"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:195"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:240"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:288"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:352"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:545"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:597"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:638"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:896"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:960"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1009"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1055"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1100"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1146"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1190"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1242"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1305"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:40"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:102"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:146"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:191"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:239"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:295"},{"message":"unknown tag: alt","line":" src/io/p5.XML.js:9"},{"message":"unknown tag: alt","line":" src/math/calculation.js:10"},{"message":"unknown tag: alt","line":" src/math/calculation.js:33"},{"message":"unknown tag: alt","line":" src/math/calculation.js:72"},{"message":"unknown tag: alt","line":" src/math/calculation.js:116"},{"message":"unknown tag: alt","line":" src/math/calculation.js:182"},{"message":"unknown tag: alt","line":" src/math/calculation.js:231"},{"message":"unknown tag: alt","line":" src/math/calculation.js:269"},{"message":"unknown tag: alt","line":" src/math/calculation.js:316"},{"message":"unknown tag: alt","line":" src/math/calculation.js:371"},{"message":"unknown tag: alt","line":" src/math/calculation.js:409"},{"message":"unknown tag: alt","line":" src/math/calculation.js:464"},{"message":"unknown tag: alt","line":" src/math/calculation.js:512"},{"message":"unknown tag: alt","line":" src/math/calculation.js:560"},{"message":"unknown tag: alt","line":" src/math/calculation.js:612"},{"message":"unknown tag: alt","line":" src/math/calculation.js:646"},{"message":"unknown tag: alt","line":" src/math/calculation.js:701"},{"message":"unknown tag: alt","line":" src/math/calculation.js:745"},{"message":"replacing incorrect tag: returns with return","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/math.js:10"},{"message":"unknown tag: alt","line":" src/math/noise.js:36"},{"message":"unknown tag: alt","line":" src/math/noise.js:178"},{"message":"unknown tag: alt","line":" src/math/noise.js:243"},{"message":"unknown tag: alt","line":" src/math/p5.Vector.js:10"},{"message":"unknown tag: alt","line":" src/math/random.js:37"},{"message":"unknown tag: alt","line":" src/math/random.js:66"},{"message":"unknown tag: alt","line":" src/math/random.js:153"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:123"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:159"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:186"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:213"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:285"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:320"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:335"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:350"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:11"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:81"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:118"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:150"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:187"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:16"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:140"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:231"},{"message":"unknown tag: alt","line":" src/typography/p5.Font.js:31"},{"message":"unknown tag: alt","line":" src/utilities/conversion.js:10"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:15"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:43"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:130"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:237"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:311"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:373"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:451"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:537"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:10"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:31"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:52"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:73"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:100"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:122"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:143"},{"message":"unknown tag: alt","line":" src/webgl/3d_primitives.js:13"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:11"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:353"},{"message":"unknown tag: alt","line":" src/webgl/light.js:11"},{"message":"unknown tag: alt","line":" src/webgl/light.js:92"},{"message":"unknown tag: alt","line":" src/webgl/light.js:177"},{"message":"unknown tag: alt","line":" src/webgl/light.js:280"},{"message":"unknown tag: alt","line":" src/webgl/light.js:387"},{"message":"unknown tag: alt","line":" src/webgl/light.js:425"},{"message":"unknown tag: alt","line":" src/webgl/light.js:519"},{"message":"unknown tag: alt","line":" src/webgl/light.js:859"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:588"},{"message":"unknown tag: alt","line":" src/webgl/material.js:12"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:184"},{"message":"unknown tag: alt","line":" src/webgl/material.js:282"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:587"},{"message":"unknown tag: alt","line":" src/webgl/material.js:659"},{"message":"unknown tag: alt","line":" src/webgl/material.js:697"},{"message":"unknown tag: alt","line":" src/webgl/material.js:777"},{"message":"unknown tag: alt","line":" src/webgl/material.js:829"},{"message":"unknown tag: alt","line":" src/webgl/material.js:902"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:13"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:115"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:176"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:236"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:303"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:357"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:444"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:472"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:499"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:526"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:554"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:582"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:610"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:633"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:656"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:683"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:801"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:897"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1040"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1098"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1156"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1386"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1458"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1723"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:334"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:603"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:644"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:749"},{"message":"unknown tag: alt","line":" src/webgl/p5.Shader.js:306"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:115"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:158"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:191"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:203"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:236"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:250"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:456"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:471"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:556"},{"message":"replacing incorrect tag: params with param","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2882"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4271"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4360"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4386"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4460"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:6280"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:8116"},{"message":"Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.","line":" src/color/color_conversion.js:8"},{"message":"Missing item type\nConvert an HSBA array to HSLA.","line":" src/color/color_conversion.js:19"},{"message":"Missing item type\nConvert an HSBA array to RGBA.","line":" src/color/color_conversion.js:45"},{"message":"Missing item type\nConvert an HSLA array to HSBA.","line":" src/color/color_conversion.js:100"},{"message":"Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.","line":" src/color/color_conversion.js:123"},{"message":"Missing item type\nConvert an RGBA array to HSBA.","line":" src/color/color_conversion.js:187"},{"message":"Missing item type\nConvert an RGBA array to HSLA.","line":" src/color/color_conversion.js:226"},{"message":"Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.","line":" src/color/p5.Color.js:396"},{"message":"Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.","line":" src/color/p5.Color.js:427"},{"message":"Missing item type\nCSS named colors.","line":" src/color/p5.Color.js:446"},{"message":"Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.","line":" src/color/p5.Color.js:600"},{"message":"Missing item type\nFull color string patterns. The capture groups are necessary.","line":" src/color/p5.Color.js:613"},{"message":"Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.","line":" src/color/p5.Color.js:750"},{"message":"Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.","line":" src/color/p5.Color.js:960"},{"message":"Missing item type","line":" src/core/friendly_errors/fes_core.js:1"},{"message":"Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.","line":" src/core/friendly_errors/fes_core.js:915"},{"message":"Missing item type","line":" src/core/friendly_errors/file_errors.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/sketch_reader.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/stacktrace.js:1"},{"message":"Missing item type\nGiven an Error object, extract the most information from it.","line":" src/core/friendly_errors/stacktrace.js:34"},{"message":"Missing item type","line":" src/core/friendly_errors/validate_params.js:1"},{"message":"Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).","line":" src/core/shape/2d_primitives.js:16"},{"message":"Missing item type\nReturns the current framerate.","line":" src/core/environment.js:305"},{"message":"Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.","line":" src/core/environment.js:315"},{"message":"Missing item type","line":" src/core/helpers.js:1"},{"message":"Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing","line":" src/core/init.js:4"},{"message":"Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.","line":" src/core/internationalization.js:30"},{"message":"Missing item type\nSet up our translation function, with loaded languages","line":" src/core/internationalization.js:126"},{"message":"Missing item type\nReturns a list of languages we have translations loaded for","line":" src/core/internationalization.js:171"},{"message":"Missing item type\nReturns the current language selected for translation","line":" src/core/internationalization.js:178"},{"message":"Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.","line":" src/core/internationalization.js:185"},{"message":"Missing item type","line":" src/core/legacy.js:1"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/core/p5.Element.js:827"},{"message":"Missing item type\nResize our canvas element.","line":" src/core/p5.Renderer.js:99"},{"message":"Missing item type\nHelper function to check font type (system or otf)","line":" src/core/p5.Renderer.js:415"},{"message":"Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178","line":" src/core/p5.Renderer.js:467"},{"message":"Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer","line":" src/core/p5.Renderer2D.js:7"},{"message":"Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.","line":" src/core/p5.Renderer2D.js:402"},{"message":"Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.","line":" src/core/shim.js:18"},{"message":"Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign","line":" src/core/shim.js:39"},{"message":"Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()","line":" src/data/p5.TypedDict.js:197"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:387"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:425"},{"message":"Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:536"},{"message":"Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:600"},{"message":"Missing item type\nHelper function for select and selectAll","line":" src/dom/dom.js:127"},{"message":"Missing item type\nHelper function for getElement and getElements.","line":" src/dom/dom.js:142"},{"message":"Missing item type\nHelpers for create methods.","line":" src/dom/dom.js:309"},{"message":"Missing item type","line":" src/dom/dom.js:450"},{"message":"Missing item type","line":" src/dom/dom.js:1164"},{"message":"Missing item type","line":" src/dom/dom.js:1257"},{"message":"Missing item type","line":" src/dom/dom.js:1296"},{"message":"Missing item type","line":" src/dom/dom.js:3232"},{"message":"Missing item type","line":" src/dom/dom.js:3298"},{"message":"Missing item type","line":" src/dom/dom.js:3360"},{"message":"Missing item type\n_updatePAccelerations updates the pAcceleration values","line":" src/events/acceleration.js:124"},{"message":"Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.","line":" src/events/keyboard.js:298"},{"message":"Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.","line":" src/events/keyboard.js:384"},{"message":"Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.","line":" src/image/filters.js:3"},{"message":"Missing item type\nReturns the pixel buffer for a canvas","line":" src/image/filters.js:24"},{"message":"Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.","line":" src/image/filters.js:60"},{"message":"Missing item type\nModifies pixels RGBA values to values contained in the data object.","line":" src/image/filters.js:81"},{"message":"Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData","line":" src/image/filters.js:101"},{"message":"Missing item type\nReturns a blank ImageData object.","line":" src/image/filters.js:121"},{"message":"Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.","line":" src/image/filters.js:136"},{"message":"Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:189"},{"message":"Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:223"},{"message":"Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.","line":" src/image/filters.js:246"},{"message":"Missing item type\nSets each pixel to its inverse value. No parameter is used.","line":" src/image/filters.js:262"},{"message":"Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation","line":" src/image/filters.js:277"},{"message":"Missing item type\nreduces the bright areas in an image","line":" src/image/filters.js:309"},{"message":"Missing item type\nincreases the bright areas in an image","line":" src/image/filters.js:396"},{"message":"Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.","line":" src/image/image.js:8"},{"message":"Missing item type\nHelper function for loading GIF-based images","line":" src/image/loading_displaying.js:162"},{"message":"Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height","line":" src/image/loading_displaying.js:284"},{"message":"Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.","line":" src/image/loading_displaying.js:597"},{"message":"Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.","line":" src/image/p5.Image.js:9"},{"message":"Missing item type\nHelper function for animating GIF-based images with time","line":" src/image/p5.Image.js:222"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/image/p5.Image.js:253"},{"message":"Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.","line":" src/io/files.js:1789"},{"message":"Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.","line":" src/io/files.js:1857"},{"message":"Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.","line":" src/io/files.js:1890"},{"message":"Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.","line":" src/io/files.js:1902"},{"message":"Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","line":" src/io/p5.Table.js:9"},{"message":"Missing item type\nMultiplies a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2135"},{"message":"Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.","line":" src/math/p5.Vector.js:2187"},{"message":"Missing item type\nDivides a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2214"},{"message":"Missing item type\nCalculates the dot product of two vectors.","line":" src/math/p5.Vector.js:2267"},{"message":"Missing item type\nCalculates the cross product of two vectors.","line":" src/math/p5.Vector.js:2281"},{"message":"Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).","line":" src/math/p5.Vector.js:2295"},{"message":"Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.","line":" src/math/p5.Vector.js:2310"},{"message":"Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)","line":" src/math/p5.Vector.js:2339"},{"message":"Missing item type\nNormalize the vector to length 1 (make it a unit vector).","line":" src/math/p5.Vector.js:2357"},{"message":"Missing item type\nHelper function to measure ascent and descent.","line":" src/typography/attributes.js:280"},{"message":"Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.","line":" src/typography/p5.Font.js:273"},{"message":"Missing item type\nReturns an opentype path for the supplied string and position.","line":" src/typography/p5.Font.js:288"},{"message":"Missing item type","line":" src/webgl/3d_primitives.js:301"},{"message":"Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.","line":" src/webgl/3d_primitives.js:955"},{"message":"Missing item type\nDraw a line given two points","line":" src/webgl/3d_primitives.js:1393"},{"message":"Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1","line":" src/webgl/loading.js:179"},{"message":"Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.","line":" src/webgl/loading.js:290"},{"message":"Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.","line":" src/webgl/loading.js:317"},{"message":"Missing item type\nThis function matches the `query` at the provided `offset`","line":" src/webgl/loading.js:344"},{"message":"Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.","line":" src/webgl/loading.js:356"},{"message":"Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`","line":" src/webgl/loading.js:444"},{"message":"Missing item type","line":" src/webgl/material.js:947"},{"message":"Missing item type","line":" src/webgl/material.js:978"},{"message":"Missing item type\nCreate a 2D array for establishing stroke connections","line":" src/webgl/p5.Geometry.js:212"},{"message":"Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU","line":" src/webgl/p5.Geometry.js:233"},{"message":"Missing item type","line":" src/webgl/p5.Matrix.js:1"},{"message":"Missing item type\nPRIVATE","line":" src/webgl/p5.Matrix.js:722"},{"message":"Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.","line":" src/webgl/p5.RenderBuffer.js:12"},{"message":"Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.","line":" src/webgl/p5.RendererGL.Immediate.js:1"},{"message":"Missing item type\nEnd shape drawing and render vertices to screen.","line":" src/webgl/p5.RendererGL.Immediate.js:129"},{"message":"Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:169"},{"message":"Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:248"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:268"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:302"},{"message":"Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.","line":" src/webgl/p5.RendererGL.Retained.js:59"},{"message":"Missing item type\nDraws buffers given a geometry key ID","line":" src/webgl/p5.RendererGL.Retained.js:110"},{"message":"Missing item type\nmodel view, projection, & normal\nmatrices","line":" src/webgl/p5.RendererGL.js:117"},{"message":"Missing item type\n[background description]","line":" src/webgl/p5.RendererGL.js:586"},{"message":"Missing item type\n[resize description]","line":" src/webgl/p5.RendererGL.js:860"},{"message":"Missing item type\nclears color and depth buffers\nwith r,g,b,a","line":" src/webgl/p5.RendererGL.js:890"},{"message":"Missing item type\n[translate description]","line":" src/webgl/p5.RendererGL.js:924"},{"message":"Missing item type\nScales the Model View Matrix by a vector","line":" src/webgl/p5.RendererGL.js:943"},{"message":"Missing item type\nturn a two dimensional array into one dimensional array","line":" src/webgl/p5.RendererGL.js:1366"},{"message":"Missing item type\nturn a p5.Vector Array into a one dimensional number array","line":" src/webgl/p5.RendererGL.js:1403"},{"message":"Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.","line":" src/webgl/p5.RendererGL.js:1421"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:1"},{"message":"Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/","line":" lib/addons/p5.sound.js:52"},{"message":"Missing item type\nThis module has shims","line":" lib/addons/p5.sound.js:401"},{"message":"Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats","line":" lib/addons/p5.sound.js:536"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:807"},{"message":"Missing item type\nUsed by Osc and Envelope to chain signal math","line":" lib/addons/p5.sound.js:1040"},{"message":"Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.","line":" lib/addons/p5.sound.js:1542"},{"message":"Missing item type\nStop playback on all of this soundfile's sources.","line":" lib/addons/p5.sound.js:2056"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:2604"},{"message":"Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade","line":" lib/addons/p5.sound.js:6455"},{"message":"Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter","line":" lib/addons/p5.sound.js:6462"},{"message":"Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ","line":" lib/addons/p5.sound.js:7009"},{"message":"Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.","line":" lib/addons/p5.sound.js:8508"},{"message":"Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.","line":" lib/addons/p5.sound.js:8659"},{"message":"Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string","line":" lib/addons/p5.sound.js:9808"},{"message":"Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached","line":" lib/addons/p5.sound.js:9826"},{"message":"Missing item type\ncallback invoked when the recording is over","line":" lib/addons/p5.sound.js:10660"},{"message":"Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release","line":" lib/addons/p5.sound.js:11995"},{"message":"Missing item type","line":" lib/addons/p5.sound.min.js:1"}],"consts":{"LABEL":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"FALLBACK":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"RGB":["p5.colorMode"],"HSB":["p5.colorMode"],"HSL":["p5.colorMode"],"CHORD":["p5.arc"],"PIE":["p5.arc"],"OPEN":["p5.arc"],"CENTER":["p5.ellipseMode","p5.rectMode","p5.imageMode","p5.textAlign"],"RADIUS":["p5.ellipseMode","p5.rectMode"],"CORNER":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"CORNERS":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"ROUND":["p5.strokeCap","p5.strokeJoin"],"SQUARE":["p5.strokeCap"],"PROJECT":["p5.strokeCap"],"MITER":["p5.strokeJoin"],"BEVEL":["p5.strokeJoin"],"POINTS":["p5.beginShape"],"LINES":["p5.beginShape"],"TRIANGLES":["p5.beginShape"],"TRIANGLE_FAN":["p5.beginShape"],"TRIANGLE_STRIP":["p5.beginShape"],"QUADS":["p5.beginShape"],"QUAD_STRIP":["p5.beginShape"],"TESS":["p5.beginShape"],"CLOSE":["p5.endShape"],"ARROW":["p5.cursor"],"CROSS":["p5.cursor"],"HAND":["p5.cursor"],"MOVE":["p5.cursor"],"TEXT":["p5.cursor"],"P2D":["p5.createCanvas","p5.createGraphics"],"WEBGL":["p5.createCanvas","p5.createGraphics"],"BLEND":["p5.blendMode","p5.Image.blend","p5.blend"],"DARKEST":["p5.blendMode","p5.Image.blend","p5.blend"],"LIGHTEST":["p5.blendMode","p5.Image.blend","p5.blend"],"DIFFERENCE":["p5.blendMode","p5.Image.blend","p5.blend"],"MULTIPLY":["p5.blendMode","p5.Image.blend","p5.blend"],"EXCLUSION":["p5.blendMode","p5.Image.blend","p5.blend"],"SCREEN":["p5.blendMode","p5.Image.blend","p5.blend"],"REPLACE":["p5.blendMode","p5.Image.blend","p5.blend"],"OVERLAY":["p5.blendMode","p5.Image.blend","p5.blend"],"HARD_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"SOFT_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"DODGE":["p5.blendMode","p5.Image.blend","p5.blend"],"BURN":["p5.blendMode","p5.Image.blend","p5.blend"],"ADD":["p5.blendMode","p5.Image.blend","p5.blend"],"REMOVE":["p5.blendMode"],"SUBTRACT":["p5.blendMode"],"VIDEO":["p5.createCapture"],"AUDIO":["p5.createCapture"],"THRESHOLD":["p5.Image.filter","p5.filter"],"GRAY":["p5.Image.filter","p5.filter"],"OPAQUE":["p5.Image.filter","p5.filter"],"INVERT":["p5.Image.filter","p5.filter"],"POSTERIZE":["p5.Image.filter","p5.filter"],"ERODE":["p5.Image.filter","p5.filter"],"DILATE":["p5.Image.filter","p5.filter"],"BLUR":["p5.Image.filter","p5.filter"],"NORMAL":["p5.Image.blend","p5.blend","p5.textStyle","p5.textureMode"],"RADIANS":["p5.angleMode"],"DEGREES":["p5.angleMode"],"LEFT":["p5.textAlign"],"RIGHT":["p5.textAlign"],"TOP":["p5.textAlign"],"BOTTOM":["p5.textAlign"],"BASELINE":["p5.textAlign"],"ITALIC":["p5.textStyle"],"BOLD":["p5.textStyle"],"BOLDITALIC":["p5.textStyle"],"WORD":["p5.textWrap"],"CHAR":["p5.textWrap"],"IMAGE":["p5.textureMode"],"CLAMP":["p5.textureWrap"],"REPEAT":["p5.textureWrap"],"MIRROR":["p5.textureWrap"]}}
            \ No newline at end of file
            diff --git a/dist/hi/reference/index.html b/dist/hi/reference/index.html
            new file mode 100644
            index 0000000000..87f437537d
            --- /dev/null
            +++ b/dist/hi/reference/index.html
            @@ -0,0 +1,294 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">reference | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="reference-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Reference</h1>
            +
            +      <div id="search" class="search-wrapper" role="search"></div>
            +      <div id="collection-list-nav"></div>
            +
            +          <!--class="container-fluid"-->
            +      <div id="list" tabindex="2" class="list-wrapper allItems-collection"></div>
            +      <div id="item" tabindex="1" class="item-wrapper apidocs"></div>
            +      <div id="file" class="file-wrapper"></div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  <script src='/assets/js/p5.min.js?v=fbf148'></script>
            +  <script src='/assets/js/p5.sound.min.js?v=53b7c5'></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
            +  <script src="/assets/js/vendor/require.min.js"></script>
            +  <script src="/assets/js/render.js?v=56ab24"></script>
            +  <script src="/assets/js/reference.js?v=c69268"></script>
            +
            +  <script>
            +
            +    var translations;
            +
            +    $(document).ready(function() {
            +      var routes = window.location.pathname.split('/');
            +      var lang = routes[1];
            +      if (langs.indexOf(lang) != -1) {
            +        $.getJSON('/assets/reference/'+lang+'.json', function(data) {
            +          translations = data;
            +
            +          window.addEventListener('reference-rendered', function() {
            +            console.log("rendered");
            +            updateLanguage();
            +          }, false);
            +        });
            +      }
            +    });
            +
            +    function removePlaceholder() {
            +      $('#search input').attr('placeholder', '');
            +    }
            +
            +    function updateLanguage() {
            +      if (translations) {
            +        // reference title
            +        $('h1').html(translations['h1']);
            +        $('#search input').attr('placeholder', translations['reference-search']);
            +        $('#search input').on('focus', removePlaceholder);
            +        $('#search input').focusout(function () {
            +          $('#search input').attr('placeholder', translations['reference-search']);
            +        })
            +        $('#search input').attr('title', translations['reference-search']);
            +        // reference description
            +        $('#reference-description1').html(translations['reference-description1']);
            +        $('#reference-description2').html(translations['reference-description2']);
            +        $('#reference-description3').html(translations['reference-description3']);
            +        $('#reference-description4').html(translations['reference-description4']);
            +        // reference contribute
            +        $('#reference-contribute1').html(translations['reference-contribute1']);
            +        $('#reference-contribute2').html(translations['reference-contribute2']);
            +        // reference error
            +        $('#reference-error1').html(translations['reference-error1']);
            +        $('#reference-error2').html(translations['reference-error2']);
            +        $('#reference-error3').html(translations['reference-error3']);
            +        $('#reference-error4').html(translations['reference-error4']);
            +        $('#reference-error5').html(translations['reference-error5']);
            +        // reference texts
            +        $('#reference-example').html(translations['reference-example']);
            +        $('#reference-description').html(translations['reference-description'])
            +        $('#reference-extends').html(translations['reference-extends']);
            +        $('#reference-parameters').html(translations['reference-parameters']);
            +        $('#reference-syntax').html(translations['reference-syntax']);
            +        $('#reference-returns').html(translations['reference-returns']);
            +        $('.group-name, .subgroup-name').each(function() {
            +          $(this).text(translations[$(this).text()]);
            +        });
            +        var routes = window.location.hash.split('/');
            +        var obj = routes[1];
            +        var name = routes[2];
            +
            +        // class page
            +        if (routes.length == 2) {
            +          var entry = translations[obj];
            +          for (var k in entry) {
            +            if (k == 'description') {
            +              $('.description-text').html('');
            +              entry.description.forEach(function (p) {
            +                $('.description-text').append('<p>' + p + '</p>');
            +              });
            +            }
            +            else if (k == 'params') {
            +              $('.params').find('ul').children('li').each(function () {
            +                var paramname = $(this).children('.paramname').text();
            +                $(this).children('.paramtype').text(entry.params[paramname]);
            +              });
            +            }
            +            else if (k == 'returns') {
            +              $('.returns').text(entry.returns);
            +            }
            +            // fields and methods sections
            +            else {
            +              // field
            +              $("[aria-labelledby='reference-fields']").children('li').each(function (i) {
            +                var fieldName = $(this).children('.paramname').children('a').text();
            +                let descr = '';
            +                var paragraphs = entry[fieldName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +              // method
            +              $("[aria-labelledby='reference-methods']").children('li').each(function (i) {
            +                var method = $(this).children('.paramname').children('a').text();
            +                // removes the brackets
            +                var methodName = method.substring(0, method.length - 2);
            +                let descr = '';
            +                var paragraphs = entry[methodName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +            }
            +          }
            +        }
            +
            +        // method/field page
            +        if (routes.length == 3) {
            +          if (translations[obj] && translations[obj][name]) {
            +            var entry = translations[obj][name];
            +
            +            $('.description-text').html('');
            +            entry.description.forEach(function (p) {
            +              $('.description-text').append('<p>' + p + '</p>');
            +            });
            +            $('.returns').html(entry.returns);
            +            $('.params').find('ul').children('li').each(function () {
            +              var paramname = $(this).children('.paramname').text();
            +              $(this).children('.paramtype').html(entry.params[paramname]);
            +            });
            +          }
            +        }
            +      }
            +    }
            +    </script>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="reference-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/reference/staticStrings.json b/dist/hi/reference/staticStrings.json
            new file mode 100644
            index 0000000000..4ba85d3402
            --- /dev/null
            +++ b/dist/hi/reference/staticStrings.json
            @@ -0,0 +1,16 @@
            +{
            +  "h1": "Reference",
            +  "reference-search": "Search reference",
            +  "reference-description1": "Can't find what you're looking for? You may want to check out",
            +  "reference-description3": "You can also download an offline version of the reference.",
            +  "reference-contribute2": "Please let us know.",
            +  "reference-error1": "Notice any errors or typos?",
            +  "reference-error3": "Please feel free to edit ",
            +  "reference-error5": "and issue a pull request!",
            +  "reference-example": "Example",
            +  "reference-description": "Description",
            +  "reference-extends": "Extends",
            +  "reference-parameters": "Parameters",
            +  "reference-syntax": "Syntax",
            +  "reference-returns": "Returns"
            +}
            diff --git a/dist/hi/showcase/featuring/casey-louise.html b/dist/hi/showcase/featuring/casey-louise.html
            new file mode 100644
            index 0000000000..3623deb5c2
            --- /dev/null
            +++ b/dist/hi/showcase/featuring/casey-louise.html
            @@ -0,0 +1,240 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>p5.js Shaders</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <div class="glitch-embed-wrap" style="height: 420px; width: 100%;">
            +        <iframe src="https://glitch.com/embed/#!/embed/shader-on-vertex?path=&previewSize=100"
            +          title="A Glitch project showing how to apply shaders to a vertex shape in p5.js."
            +          style="height: 100%; width: 100%; border: 0;">
            +        </iframe>
            +      </div>
            +    </section>
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Casey Conchinha <span class="note">(he/him)</span></p>
            +        <p>Louise Lessél <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From New York, New York</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class='links' aria-labelledby="resources">
            +          <li><a href="https://bit.ly/p5shaders" target="_blank">p5.js Shaders guide</a></li>
            +          <li><a href="https://bit.ly/p5shadersexamples" target="_blank">Glitch collection of p5.js shader examples</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>Casey: I'm a student at NYU ITP who's interested in computer graphics and interactive spaces, physical and digital.</p>
            +        <p class='project-a'>Louise: I'm a student at NYU ITP who's interested in computer graphics and interactive spaces based on sensor technologies.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>Casey: I started learning p5.js in 2018 in my first semester at ITP, though I had been dabbling in<a href="https://processing.org/"
            +            target="_blank">Processing</a> since 2012. I was introduced to Processing by my friend Pedro while I was studying graphic design, and it blew my mind. The idea of making my own tools for creating graphics and interactive art piqued my interest, but once I actually tried it, I was hooked. The first project I can remember was an eye that followed you around the screen, and it was sad when you left it alone.</p>
            +        <p class='project-a'>Louise: I initially learned p5.js to make a website I was creating more playful. I’m a C# programmer, so this was a good segway into JavaScript for me.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>Casey: I was putting off learning shaders for a long time, and I was also curious if I could use them in p5.js. Then I heard about a grant for open source, storytelling, and learning resource projects at ITP called<a href="https://www.itpxstory.com/"
            +            target="_blank">xStory</a>. Since I wasn't finding much in the way of p5.js + shader documentation, I decided to figure out how they're implemented in p5.js and create a resource for others to learn. When I told Louise about the project, she was immediately excited about learning and teaching shaders in p5.js. She's been great about making sure the project is a learning resource and not just a collection of examples.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>Casey: Does <a href="https://thecodingtrain.com/"
            +            target="_blank">Shiffman</a> count as a feature? I also love having the ability to share my programs on the web so that people don't have to install special software or come to NYC to see my work.</p>
            +        <p class='project-a'>
            +          Louise: My favorite feature is <code><a href="https://p5js.org/reference/#/p5/push" target="_blank">push()</a></code> and <code><a href="https://p5js.org/reference/#/p5/pop" target="_blank">pop()</a></code> for transformation of the coordinate system to make generative visuals.
            +        </p>
            +
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>Casey: The beginning of the project (figuring out how things work) was us reaching out to amazing people, asking questions, and asking for permission to use their examples in our project.<a
            +            href="https://github.com/aferriss/p5jsShaderExamples"
            +            target="_blank">Adam Ferriss' GitHub repo</a> really laid the groundwork for us in understanding how shaders work in p5.js and provided a framework of approachable examples for us to build on. For some specific p5.js-related issues we were having, we reached out to <a
            +            href="http://www.katehollenbach.com/" target="_blank">Kate
            +            Hollenbach</a> and <a href="https://stalgiagrigg.name/"
            +            target="_blank">Stalgia Grigg</a> (who worked on the <a
            +            href="https://github.com/processing/p5.js/issues?q=is%3Aissue+is%3Aopen+webgl+label%3Aarea%3Awebgl"
            +            target="_blank">WebGL implementation in p5.js</a>), and they were super helpful.
            +        </p>
            +        <p class='project-a'>Louise: The learning curve was pretty steep for getting shaders into p5. Luckily, there were some very well-documented examples on GitHub by Adam Ferriss. Our aim was to do so in a way that a complete beginner can understand how to implement it, so it was as much a technical challenge as it was a challenge in teaching code to strangers and beginners. Here we drew inspiration from the way the<a
            +            href="https://openframeworks.cc/ofBook/chapters/foreword.html"
            +            target="_blank">openFrameworks book</a> is written. A fun "hey, it’s not hard and you can do it too" approach is what we believe in.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out the <a href="https://github.com/ITP-xStory"
            +            target="_blank">xStory GitHub</a> to explore our peers' amazing grant projects!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'>Casey: <a href="https://cargocollective.com/kcconch"
            +            target="_blank">cargocollective.com/kcconch</a>, <a href="https://github.com/kcconch"
            +            target="_blank">@kcconch</a> (GitHub)</p>
            +        <p class='project-a'>Louise: <a href="http://www.louiselessel.com/" target="_blank">louiselessel.com</a>, <a
            +            href="https://github.com/louiselessel" target="_blank">@louiselessel</a> (GitHub)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/showcase/featuring/daein-chung.html b/dist/hi/showcase/featuring/daein-chung.html
            new file mode 100644
            index 0000000000..4870e50580
            --- /dev/null
            +++ b/dist/hi/showcase/featuring/daein-chung.html
            @@ -0,0 +1,225 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Chillin'</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only' id="info">Project Info</h2>
            +      <img src="../../../assets/img/showcase/daein-chung/daein-chung_chillin.png" alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device.
            +        At the top, there is a text input box to enter a message and download your own poster.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Dae In Chung <span class="note">(he/him)</span></p>
            +        <p class="creator-from">From Baltimore, Maryland</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class="links">
            +          <li><a href="https://exp.paperdove.com/chillin/" target="_blank">View Chillin'</a></li>
            +          <li><a href="https://github.com/cdaein/exp/tree/gh-pages/chillin"
            +              target="_blank">Code for Chillin' on GitHub</a></li>
            +          <li><a href="https://paperdove.com/work/2019-chillin/" target="_blank">More info in Dae In Chung's Portfolio</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I am a graphic designer and a faculty member at Maryland Institute College of Art, where I mainly teach coding (with p5.js and Processing, of course) and motion graphics.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I have been using <a href="https://processing.org/"
            +            target="_blank">Processing</a> for some time, and when p5.js came along, I started using it without a second thought because it was easy to convert existing Processing code and share projects online.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>This summer, I gave myself a challenge of making typographic posters with coding, and this is one of the posters I made. I didn’t know until very recently that I could use motion sensor data with p5.js. I was also watching<a
            +            href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6bLh3T_4wtrmVHOrOEM1ig_"
            +            target="_blank">Dan Shiffman’s matter.js tutorial videos</a>, so I thought why not combine the two and practice what I was learning?
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>There are many things I love about p5.js such as the online community and beginner friendliness. What I really like right now is the<a href="https://editor.p5js.org/"
            +            target="_blank">online editor</a>, with which I can not only work online for myself but also share URLs quickly in the present mode. For this project in particular, I had to do a lot of testing on my phone, and it was much easier and quicker than committing to GitHub.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>I had some troubles with handling font, alpha channel and z-depth in <a
            +            href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5"
            +            target="_blank">WebGL</a> mode. I am still not happy with all my decisions. But in general, it was helpful to search the forum and not to forget to break down problems into smaller ones and iterate little by little. Also, I had issues with rendering out video files directly out of p5.js. Screen recording was not an option because of intermittent frame rate drops (my laptop is pretty slow). After doing some research, I decided to learn some basics of <a href="https://electronjs.org/"
            +            target="_blank">Electron</a> and build a tool for myself.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>As mentioned above, if you want to render out frames and video files out of p5.js sketches, check out my<a
            +            href="https://github.com/cdaein/p5js-electron-canvas-saver-boilerplate" target="_blank">Canvas Saver
            +            boilerplate</a> and let me know what you think.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/cdaein/" target="_blank">@cdaein</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/showcase/featuring/moon-xin.html b/dist/hi/showcase/featuring/moon-xin.html
            new file mode 100644
            index 0000000000..eeb549b4ab
            --- /dev/null
            +++ b/dist/hi/showcase/featuring/moon-xin.html
            @@ -0,0 +1,232 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Moving Responsive Posters</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png"
            +        alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Moon Jang <span class="note">(she/her)</span></p>
            +        <p>Xin Xin <span class="note">(they/them)</span></p>
            +        <p class="creator-from">From Athens, Georgia</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Posters By</h3>
            +        <ul class="links">
            +          <li><a href="https://editor.p5js.org/avezray/present/JTjhOdGRB" target="_blank">Avery Ray</a></li>
            +          <li><a href="https://editor.p5js.org/carcarw/present/DyKJHUtCN" target="_blank">Carlee Wooddell</a></li>
            +          <li><a href="https://editor.p5js.org/mdh54215/present/h5wp4EYen" target="_blank">Mia Hofmann</a></li>
            +          <li><a href="https://editor.p5js.org/katiehuang1998@gmail.com/present/1GhSDw-Og" target="_blank">Katie
            +              Huang</a></li>
            +          <li><a href="https://editor.p5js.org/borderrider@gmail.com/present/Lg_pSPRHF" target="_blank">Lila
            +              Mitchell</a></li>
            +          <li><a href="https://editor.p5js.org/wallacekd/present/GqWZOYUSN" target="_blank">Kathryn Wallace</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>Moon: I'm a graphic designer, visual artist, and design educator. This summer, I taught a graphic design course in the University of Georgia Cortona program in Italy, introducing some basics of p5.js. This fall, I am planning to teach and to study digital platforms at UGA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>My former colleague, <a href="https://xin-xin.info/" target="_blank">Xin
            +            Xin</a>, invited me to <a href="https://medium.com/processing-foundation/pcd/home"
            +            target="_blank">Processing Community Day</a> in <a
            +            href="https://day.processing.org/pcd-la.html"
            +            target="_blank">LA in January 2019</a>. They helped me with the tools and logics of p5.js. It was an excellent teaching and learning experience.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>We followed basic tutorials, <a href="https://thecodingtrain.com/"
            +            target="_blank">Daniel's videos on YouTube</a>, and <a
            +            href="https://p5js.org/reference/"
            +            target="_blank">Reference on the p5.js website</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>My favorite function is related to <a
            +            href="https://p5js.org/reference/#group-Typography"
            +            target="_blank">type</a> and <a
            +            href="https://p5js.org/reference/#group-Transform"
            +            target="_blank">transformation</a>: <code><a href="https://p5js.org/reference/#/p5/rotate" target="_blank">rotate()</a></code>. I was able to use and to teach this tool to visualize various ideas about time in motion.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>It was challenging for me, a beginner, to understand the overall structure of p5.js and how code works in general. I had to repeat the p5.js basics a couple of times, and then I drew a chart to memorize and to teach the way I understood the p5.js structure and code with strong constraints I set up. It was an excellent teaching and learning experience.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out the <a href="http://www.brokennature.org/"
            +            target="_blank">Design Triennale</a> in Milan, Italy.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="http://www.moonjang.com/" target="_blank">moonjang.com</a>
            +          <br><a href="https://www.instagram.com/borderrider/" target="_blank">@borderrider</a> (Instagram)
            +        </p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/showcase/featuring/phuong-ngo.html b/dist/hi/showcase/featuring/phuong-ngo.html
            new file mode 100644
            index 0000000000..a7f4894dd5
            --- /dev/null
            +++ b/dist/hi/showcase/featuring/phuong-ngo.html
            @@ -0,0 +1,232 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Airi Flies</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" alt="A screenshot of a poster of Airi Flies, a game to help Airi fly by saying pew.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Phuong Ngo <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From Kyiv, Ukraine</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://www.yonaymoris.me/AiriFlies/" target="_blank">Play Airi Flies!</a></li>
            +          <li><a href="https://github.com/yonaymoris/AiriFlies" target="_blank">Code for AiriFlies on GitHub</a>
            +          </li>
            +          <li><a href="https://www.yonaymoris.me/projects/airiflies"
            +              target="_blank">More info in Phuong Ngo's portfolio</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I'm a creative coder and designer, a <a href="https://schoolofma.org/"
            +            target="_blank">School of Machines, Making & Make-Believe</a> diversity scholarship recipient, and just a curious creature.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I was taking a course at the School of Machines in Berlin this summer called! "<a href="https://schoolofma.org/bots.html"
            +            target="_blank">Bots and Machine Learning</a>," mainly taught by <a
            +            href="https://1023.io/" target="_blank">Yining Shi</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>I used p5.js to work on the visual part of the game. The animation sprites for Airi and the ghosts were drawn on an iPad app called<a href="https://rizer.co/pixaki/"
            +            target="_blank">Pixaki</a> and then integrated into <a
            +            href="http://molleindustria.github.io/p5.play/"
            +            target="_blank">p5.play</a> code. I mainly used examples at p5.play as a reference.</p>
            +        <p class='project-a'>For the endless scrolling background, I found a <a
            +            href="https://editor.p5js.org/chjno/sketches/ByZlypKWM"
            +            target="_blank">p5 sketch by chjno</a>. I set a condition so whenever the word "pew" or a mouse click was detected, the scrolling speed would change to make an illusion of Airi flying up. When the user does not do anything, the scrolling speed is negative, which makes it look like Airi is falling down.
            +        </p>
            +        <p class='project-a'>For sound recognition, I used <a
            +            href="https://teachablemachine.withgoogle.com/io19" target="_blank">Google's Teachable Machine
            +            2</a> (currently, there is a beta version not available in public yet, but it will be very soon!). I added around 120 samples of my classmates saying the word "pew" with different intonations and 80 samples of background noise to train it. Then I integrated the model into the game with <a href="https://ml5js.org/" target="_blank">ml5.js</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>I really love how easily you can create, manipulate, and delete HTML blocks and classes with the<a href="https://p5js.org/reference/"
            +            target="_blank">p5.js
            +            library</a> via <code><a href="https://p5js.org/reference/#/p5/createDiv" target="_blank">createDiv()</a></code>,
            +          <code><a href="https://p5js.org/reference/#/p5.Element/addClass" target="_blank">addClass()</a></code> etc. But my most favorite function is <code><a href="https://p5js.org/reference/#/p5/draw" target="_blank">draw()</a></code>, since this is where you create magic.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>There were a lot of challenges simply because p5.js was something new to me. I did not work much with JavaScript in general before. Reading documentation and searching for similar examples helped a lot.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out <a href="https://schoolofma.org/programs"
            +            target="_blank">School of Machines' courses</a>! They try hard to connect the most creative people in the world and they do it well so far. ❤️
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://www.yonaymoris.me/" target="_blank">yonaymoris.me</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/showcase/featuring/qianqian-ye.html b/dist/hi/showcase/featuring/qianqian-ye.html
            new file mode 100644
            index 0000000000..550bc4a109
            --- /dev/null
            +++ b/dist/hi/showcase/featuring/qianqian-ye.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Qtv</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" alt="A guest talk video (Guest Talk #1) on Qtv by Qianqian Ye, featuring Kaikai and Cheng Xu.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Qianqian Ye <span class="note">(she/her)</span></p>
            +        <p class="creator-from">Los Angeles, California</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Resources</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://bit.ly/2XVzPAv" target="_blank">Qtv YouTube</a></li>
            +          <li><a href="https://www.instagram.com/q_tv_/" target="_blank">Qtv Instagram</a></li>
            +          <li><a href="https://space.bilibili.com/442343394" target="_blank">Qtv Bilibili</a></li>
            +          <li><a href='https://v.douyin.com/sopAGk/' target='_blank'>@Q_tv TikTok</a></li>
            +          <li><a href="https://medium.com/processing-foundation/interview-with-2019-fellow-qianqian-ye-799c0115c295"
            +              target="_blank">Processing Foundation interview with Qianqian Ye</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I am a Chinese artist and designer based in Los Angeles.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>My partner introduced me to p5.js, which I learned mainly by watching free online video tutorials. My first p5.js project was drawing some shapes with different colors.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>This project started with an idea of teaching my mom, who lives in China and doesn’t speak English, to code with p5.js. This project was difficult on multiple levels, and I wanted to start by identifying the main reasons why it’s more challenging for someone like my mother to learn to code—primarily due to the lack of free creative coding education resources. Most of the free resources to learn creative coding are unavailable in China. The p5.js tutorials on YouTube as well as the p5.js Twitter and Instagram accounts are inaccessible in China because of internet censorship.</p>
            +        <p class='project-a'>I learned a lot from YouTube videos such as the <a href="https://thecodingtrain.com/"
            +            target="_blank">Coding Train</a>, but the more I watched coding tutorials online, the more I realized how difficult it is to find other womxn and people of color teaching coding, especially in Mandarin. I wanted to help other Chinese womxn relate to creative coding.</p>
            +        <p class='project-a'>I am working on opening up the video channels to other Chinese creatives who want to contribute to the educational resource together, like interviews and guest tutorials. If you are interested in teaching/talking about creative coding in Mandarin, HMU!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>The <a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a> is my favorite feature. It makes web-based creative coding seamless.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>Learning to code in a second language was difficult and the lack of community made this process even harder. I hope to speak from my experience as a beginner and someone who once felt like an outsider to the creative coding and video tutorial world.</p>
            +        <p class='project-a'>I spend a lot of time researching the latest technology for my videos. In the end, I decided on using my phone to record and iMovie to edit. I hope to encourage others that it doesn’t take a lot of expensive gears to get started making instructional videos.</p>
            +        <p class='project-a'>Another issue I came across was my own fear of putting myself online. I first had to get over my anxiety of making mistakes in the videos or receiving negative comments online. Often womxn and people of color are targets for online harassment. I’m hoping to help set an example for other womxn and people of color that it’s ok to put yourselves online and strengthen your communities by sharing your knowledge. Eventually, we will be able to stop online harassment by creating strong diverse communities.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>I am very excited about <a href="http://tinytechzines.org/"
            +            target="_blank">Tiny Tech Zines</a> in LA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="http://www.qianqian-ye.com/" target="_blank">qianqian-ye.com</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/showcase/featuring/roni-cantor.html b/dist/hi/showcase/featuring/roni-cantor.html
            new file mode 100644
            index 0000000000..c9fc583678
            --- /dev/null
            +++ b/dist/hi/showcase/featuring/roni-cantor.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Programmed Plotter Drawings</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img class='half-image' src="../../../assets/img/showcase/roni-cantor/roni-cantor_plotter-turquoise.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a turquoise gel pen.">
            +      <img class='half-image' src="../../../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a white gel pen.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Roni Cantor <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From Toronto, Canada</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class="links" aria-labelledby="resources">
            +          <li><a href="https://editor.p5js.org/ronicantor/sketches/eq2bIhmh2"
            +              target="_blank">Example sketch in p5.js Web Editor</a></li>
            +          <li><a href="https://drive.google.com/file/d/1UJy6q5cDl6Hg79O9mX1ZN7NFp0NXSYCs/view?usp=sharing"
            +              target="_blank">AxiDraw V3 demo video</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I just graduated from Ryerson University's New Media program. Coming from 4 years of coding and making robots, I decided to take a break and play with some more traditional forms of art—while still coding and playing with robots.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I first started using p5.js at <a href="https://itp.nyu.edu/camp2019/"
            +            target="_blank">NYU ITP Camp</a>! After using <a
            +            href="https://processing.org/" target="_blank">Processing</a> for many years, I wanted to try something new.
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>I used p5.js in this project to generate the sine wave and lerp (linear interpolation) formulas and display the visuals in the<a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a>. I then used a feature in my code that exported my programmed graphic into an<a
            +            href="https://developer.mozilla.org/en-US/docs/Web/SVG"
            +            target="_blank">SVG</a> file. I needed an SVG file to give to the plotter—an <a
            +            href="https://shop.evilmadscientist.com/productsmenu/846" target="_blank">AxiDraw
            +            V3</a>—so that it understood where to draw the lines that I programmed. I sent this information to the plotter with a program called<a href="https://inkscape.org/"
            +            target="_blank">Inkscape</a>!</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>
            +          <code><a href="https://p5js.org/reference/#/p5/lerp" target="_blank">lerp()</a></code> because lines are fun and "lerp" is a fun word to say!
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>It was my first time using p5.js, Inkscape, and a plotter! I really benefited from the people around me who had used p5 before, as well as online guides and forums.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/gandyworks/"
            +            target="_blank">@gandyworks</a> on Instagram—super cool analog plotter stuff.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://ronicantor.com/" target="_blank">ronicantor.com</a>
            +          <br><a href="https://www.instagram.com/roni.cantor/"
            +            target="_blank">@roni.cantor</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/showcase/index.html b/dist/hi/showcase/index.html
            new file mode 100644
            index 0000000000..9d5e8afa01
            --- /dev/null
            +++ b/dist/hi/showcase/index.html
            @@ -0,0 +1,245 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main  id="content" class="column-span">
            +    <section class="showcase-intro">
            +      <h1>Showcase</h1>
            +      
            +      <p>Introducing Showcase, created by <a href="https://ashleykang.dev" target="_blank">Ashley Kang</a>
            +       in 2019 and currently curated by <a href="https://katiechan.cargo.site/" target="_blank">Katie Chan</a>.
            +      We're celebrating how people are using p5.js to make creative work, learning, and open source more interesting and inclusive. Together, we make community. During Summer 2019, we asked a few creators to share more about how they've used p5.js through different projects and pieces.</p>
            +      <p>The Summer 2020 Showcase is now open for submissions, nominate someone's p5.js work or your own to be featured here!</p>
            +
            +      <span id="nominate" class="nominate"><a href="https://forms.gle/ETP7kjAocBcfGTuj8" target="_blank">Nominate a Project</a></span>
            +    </section>
            +
            +    <section class="showcase-featured">
            +      <h2 class="featuring">Featuring</h2>
            +
            +      <div class="left-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/roni-cantor.html">Programmed Plotter Drawings</a></h3>
            +          <p class="credit">Roni Cantor</p>
            +          <a href="./featuring/roni-cantor.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg" 
            +            alt="A drawing of a sine wave lerp plotted on black paper using an AxiDraw V3 and a white gel pen.">
            +          </a>
            +          <p class="description">Sine waves and lerps generated in p5.js, exported as SVG, and drawn with a plotter and pens.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5/lerp">lerp()</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/daein-chung.html">Chillin'</a></h3>
            +          <p class="credit">Dae In Chung</p>
            +          <a href="./featuring/daein-chung.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/daein-chung/daein-chung_chillin.png" 
            +              alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device. 
            +              At the top, there is a text input box to enter a message and download your own poster">
            +          </a>
            +          <p class="description">An interactive typographic poster that uses a mobile device's motion sensor with p5.js.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://brm.io/matter-js/">matter.js</a></li>
            +            <li><a class="tag" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">p5 WebGL</a></li>
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5.Camera">p5.Camera</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/casey-louise.html">p5.js Shaders</a></h3>
            +          <p class="credit">Casey Conchinha, Louise Lessél</p>
            +          <a href="./featuring/casey-louise.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/casey-louise/casey-louise_p5js-shaders.png" 
            +              alt="A screenshot of the Introduction page of the p5.js Shaders guide website">
            +          </a>
            +          <p class="description">A resource for learning the what, why, and how of using shaders in p5.js.</p>
            +          <ul class="project-tags">
            +         </ul>
            +        </div>
            +      </div>
            +
            +      <div class="right-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/phuong-ngo.html">Airi Flies</a></h3>
            +          <p class="credit">Phuong Ngo</p>
            +          <a href="./featuring/phuong-ngo.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" 
            +              alt="A screenshot of the instructions and scoreboard for the online game Airi Flies">
            +          </a>
            +          <p class="description">In this game developed with p5.play, help Airi fly by saying PEW. Created to encourage people to get out of their comfort zone and feel more confident about themselves regardless of what they do and how they look or sound.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="http://molleindustria.github.io/p5.play/">p5.play</a></li>
            +            <li><a class="tag" href="https://ml5js.org/">ml5.js</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +          <h3 class="title"><a href="./featuring/qianqian-ye.html">Qtv</a></h3>
            +          <p class="credit">Qianqian Ye</p>
            +          <a href="./featuring/qianqian-ye.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" 
            +              alt="A screenshot of a Qtv video (Guest Talk #1) featuring Chinese womxn designers and artists Kaikai and Cheng Xu">
            +          </a>
            +          <p class="description">A video channel with 1-minute videos in Mandarin about creative coding, art, and technology, including p5.js tutorials for beginners. Available on YouTube, Instagram, Bilibili, and TikTok.</p>
            +          <ul class="project-tags">
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/moon-xin.html">Moving Responsive Posters</a></h3>
            +          <p class="credit">Moon Jang, Xin Xin, and students</p>
            +          <a href="./featuring/moon-xin.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png" 
            +              alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right">
            +          </a>
            +          <p class="description">Browser-based moving posters that use graphical systems, transformation methods, and p5.js to address the connotations of a word less than 8 letters. Designed by students for a graphic design course (Visual Narrative Systems) at the University of Georgia.</p>
            +          <ul class="project-tags">
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/rect">rect()</a></li>
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/translate">translate()</a></li>
            +          </ul>
            +        </div>
            +      </div>
            +    </section>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/hi/teach/index.html b/dist/hi/teach/index.html
            new file mode 100644
            index 0000000000..34b753d615
            --- /dev/null
            +++ b/dist/hi/teach/index.html
            @@ -0,0 +1,856 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="hi">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">teach | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/hi/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="teach-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/hi/">सभी</a></li>
            +        <li><a href="https://editor.p5js.org">एडीटर</a></li>
            +        <li><a href="/hi/download/">डाउनलोड</a></li>
            +        <li><a href="/hi/download/support.html">दान दिजिये</a></li>
            +        <li><a href="/hi/get-started/">आरंभ करें</a></li>
            +        <li><a href="/hi/reference/">संदर्भ</a></li>
            +        <li><a href="/hi/libraries/">लाइब्रिरी</a></li>
            +        <li><a href="/hi/learn/">सीखिए</a></li>
            +        <li><a href="/hi/teach/">सिखाना</a></li>
            +        <li><a href="/hi/examples/">उदाहरण</a></li>
            +        <li><a href="/hi/books/">पुस्तकें</a></li>
            +        <li><a href="/hi/community/">समुदाय</a></li>
            +        <li><a href="https://showcase.p5js.org">प्रदर्शन</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">फोरम</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            + <main id="content" class="column-span">
            +  	<section class= "teach-intro">
            +      <h1>सिखाना</h1>
            +
            +	      <p>प्रत्येक शिक्षण के अपने विशिष्ट लक्ष्य, संदेश, शर्तें और वातावरण होते हैं।p5 कार्यशालाओं, कक्षाओं और सामग्रियों का दस्तावेज़ीकरण और साझा करके, हम दुनिया भर में p5.js शिक्षार्थी और शिक्षक समुदायों को बेहतर ढंग से जोड़ने की उम्मीद करते हैं।<a href="" onclick= "window.open('https://docs.google.com/forms/d/e/1FAIpQLSei8yHX2BROMnMQeZT_tsSXJOH13TPRG6CB4GVHH1oL1hzkZg/viewform?usp=sf_link', '_blank')">साझा करें या अनुशंसा करें</a> आपके अपने शिक्षण अनुभव भी!</p>
            +						
            +    </section>
            +
            +	<section>
            +
            +		<div id="resources"></div>
            +			<h2 class = "heading">p5 शिक्षण संसाधन</h2> 
            +			
            +			<div class="search-filter"><input type="checkbox"><label> Search Filter &#x2192;</label></div>
            +
            +     		<!-- search-results -->
            +
            +     		<div class="filter-panel">
            +
            +							
            +				<ul class="filters" id="filters">
            +
            +					<li><p class = "filter-title">&#x1F33A; Diversity & Inclusion : </p></li>
            +					<li><input type="checkbox" id="gender" value="gender"><label for="gender">Gender</label></li>
            +					<li><input type="checkbox" id="race-ethnicity" value="race-ethnicity"><label for="race-ethnicity">Race & Ethnicity</label></li>
            +					<li><input type="checkbox" id="language" value="language"><label for="language">Language</label></li>
            +					<li><input type="checkbox" id="neuro-type" value="neuro-type"><label for="neuro-type">Neuro-Type</label></li>
            +					<li><input type="checkbox" id="ability" value="ability"><label for="ability">Ability</label></li>
            +					<li><input type="checkbox" id="class" value="class"><label for="class">Class</label></li>
            +					<li><input type="checkbox" id="religion" value="religion"><label for="religion">Religion</label></li>
            +					<li><input type="checkbox" id="subculture" value="subculture"><label for="subculture">(Sub-)Culture</label></li>
            +					<li><input type="checkbox" id="political-opinion" value="political-opinion"><label for="political-opinion">Political Opinion</label></li>
            +					<li><input type="checkbox" id="age" value="age"><label for="age">Age</label></li>
            +					<li><input type="checkbox" id="skill-level" value="skill-level"><label for="skill-level">Skill Level</label></li>
            +					<li><input type="checkbox" id="occupation" value="occupation"><label for="occupation">Occupation</label></li>
            +					<li><input type="checkbox" id="noCodeSnobs" value="noCodeSnobs"><label for="noCodeSnobs">#noCodeSnobs</label></li>
            +					<li><input type="checkbox" id="newKidLove" value="newKidLove"><label for="newKidLove">#newKidLove</label></li>
            +					<li><input type="checkbox" id="unassumeCore" value="unassumeCore"><label for="unassumeCore">#unassumeCore</label></li>
            +					<li><input type="checkbox" id="BlackLivesMatter" value="BlackLivesMatter"><label for="BlackLivesMatter">#BlackLivesMatter</label></li>
            +							
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CD; Venue : </p></li>
            +
            +					<li><input type="checkbox" id="africa" value="africa"><label for="africa">Africa</label></li>
            +					<li><input type="checkbox" id="asia" value="asia"><label for="asia">Asia</label></li>
            +					<li><input type="checkbox" id="europe" value="europe"><label for="europe">Europe</label></li>
            +					<li><input type="checkbox" id="north-america" value="north-america"><label for="north-america">North America</label></li>
            +					<li><input type="checkbox" id="oceania" value="oceania"><label for="oceania">Oceania</label></li>
            +					<li><input type="checkbox" id="south-america" value="south-america"><label for="south-america">South America</label></li>
            +					<li><input type="checkbox" id="virtual-online" value="virtual-online"><label for="virtual-online">Virtual-Online  &#x1F310;</label></li>
            +
            +
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4C5; Year : </p></li>
            +					<li><input type="checkbox" id="2014" value="2014"><label for="2014">~2014</label></li>
            +					<li><input type="checkbox" id="2015" value="2015"><label for="2015">2015</label></li>
            +					<li><input type="checkbox" id="2016" value="2016"><label for="2016">2016</label></li>
            +					<li><input type="checkbox" id="2017" value="2017"><label for="2017">2017</label></li>
            +					<li><input type="checkbox" id="2018" value="2018"><label for="2018">2018</label></li>
            +					<li><input type="checkbox" id="2019" value="2019"><label for="2019">2019</label></li>
            +					<li><input type="checkbox" id="2020" value="2020"><label for="2020">2020</label></li>
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CA; Level of Difficulty : </p></li>
            +					<li><input type="checkbox" id="elementary" value="elementary"><label for="elementary">Elementary</label></li>
            +					<li><input type="checkbox" id="intermediate" value="intermediate"><label for="intermediate">Intermediate</label></li>
            +					<li><input type="checkbox" id="advanced" value="advanced"><label for="advanced">Advanced</label></li>
            +				 </ul>
            +
            +						  <br>
            +								
            +
            +			</div>
            +												
            +			<div class = "results-wrapper">
            +
            +						
            +				<div class="results" id="search-results">
            +					<ul>
            +				  		<li class="case-list" data-category="2019 europe gender race-ethnicity age skill-level BlackLivesMatter advanced"><a href="#case1" class="caseBtn" >"p5.js à l'Ubuntu Party!", Basile Pesin</a></li>
            +
            +				  		 <li class="case-list" data-category="2020 asia age skill-level occupation elementary advanced"><a href="#case2" class="caseBtn">"Making The Thing that Makes the Thing: Exploring Generative Art &#x0026; Design with p5.js", Priti Pandurangan &#x0026; Ajith Ranka</a></li>
            +
            +						  <li class="case-list" data-category="2016 2019 2020 elementary intermediate advanced north-america gender race-ethnicity language neuro-type ability subculture occupation north-america"><a href="#case3" class="caseBtn">CC Fest (Creative Coding Festival), Saber</a></li>
            +
            +						  <li class="case-list" data-category="2018 virtual-online south-america gender race-ethnicity language neuro-type religion subculture age noCodeSnobs newKidLove unassumeCore elementary intermediate advanced"><a href="#case4" class="caseBtn" >"Taller Introducci&#x00F3;n a la Programaci&#x00F3;n Creativa con p5.js", Aar&#x00F3;n Montoya-Moraga</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america gender race-ethnicity class subculture age skill-level elementary"><a href="#case5" class="caseBtn" >"Introduction to Generative Drawing", Adam Herst</a></li>
            +
            +						  <li class="case-list" data-category="2020 asia virtual-online gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation elementary"><a href="#case6" class="caseBtn" >Open Lecture "Creative Coding: 2020", Shunsuke Takawo</a></li>
            +
            +
            +						  <li class="case-list" data-category="2020 asia gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation intermediate"><a href="#case7" class="caseBtn" >"Creative Coding for Static Graphics", Shunsuke Takawo</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america virtual-online race-ethnicity language subculture skill-level"><a href="#case8" class="caseBtn" >"Generative Typography", Dae In Chung</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity language age skill-level occupation noCodeSnobs new unassumeCore BlackLivesMatter elementary intermediate"><a href="#case9" class="caseBtn" >"Machine Learning for the Web", Yining Shi</a></li>
            +
            +
            +						  <li class="case-list" data-category="europe virtual-online gender elementary"><a href="#case10" class="caseBtn" >"Introduction to p5.js and JavaScript", Nico Reski</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity skill-level occupation"><a href="#case11" class="caseBtn">"Digital Weaving &#x0026; Physical Computing Workshop Series", Qianqian Ye &#x0026; Evelyn Masso</a></li>
            +
            +						  <li class="case-list" data-category="2015 2020 north-america asia gender race-ethnicity language neuro-type ability class skill-level"><a href="#case12" class="caseBtn">"Signing Coders", Taeyoon Choi</a></li>
            +	    			</ul>
            +						<br>
            +				</div> 
            +			</div>
            +						
            +
            +						
            +
            +		<!--modal box section-->
            +		
            +			<!--modal boxes-->
            +
            +			<div id="caseModals" class="modal">
            +
            +				<!--modal box #1-->
            +
            +				  <div class="modal-content" id="case1"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>p5.js à l'Ubuntu Party!</span></li>
            +				        	<li class = "case"><p class="lead-name">Basile Pesin</p></li>
            +
            +				          	<li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date<p><a href="https://ubuntu-paris.org/">2020 Ubuntu Party, </a>Cité des Sciences et de l'Industrie, Paris, France</p></li> 
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Any age, including children and parents, young and older adults.
            +				            </p></li>		         
            +
            +				            <li class = "clear"></li>  				
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To introduce a new public to programming through fun and compelling examples.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Method: in-person workshop, 1 hour per session, with different participant each times. The students were using (Ubuntu) machines with the p5.js web editor. I was teaching using a video projector as well as a board.</p><p>Materials: The exercises I gave where accessible through p5.js web-editor links available in<a href = "https://vertmo.github.io/ubuntu-party-p5/">GitHub</a>.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Age</label><label>Skill Level</label><label>#BlackLivesMatter</label>
            +				            </li>
            +		             
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				<!--modal box #2-->
            +	
            +				  <div class="modal-content" id="case2"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Making The Thing that Makes the Thing: Exploring Generative Art & Design with p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Priti Pandurangan & Ajith Ranka</p></li>
            +				        	
            +				        	<li class = "clear"></li>
            +             				<li class = "clear"></li>
            +             				<li class = "case"><img src="https://drive.google.com/uc?id=1udID-B1qADY7QxDkYkAh6ZYX7D8BfrnD" alt="A group of participants collaborating to create some designs using the p5.js web editor on their laptops."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date<p>&#x1F4CD; National Institute of Design, Bangalore</p><p>&#x1F4C5; 2020 February 8, 2:30-4:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Priti: Intermediate & Ajith: Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To explore generative art &#x0026; design and recreate some classical works with p5.js.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: In-person, collaborative, hands-on workshop.</p><p>Materials: <a href="https://musingswithcode.studio/generative-design-workshop">course page </a> linking to sketches on the p5 editor, <a href="https://musingswithcode.studio/generative-design-workshop/explainers">interactive reference guide </a>to p5 basics</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Skill Level</label><label>Occupation</label></li>			    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +				  <!--modal box #3-->
            +	
            +				  <div class="modal-content" id="case3"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>CC Fest (Creative Coding Festival)</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Saber</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Love p5.js. It has meant so much to me, my students, and this community."</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; New York, Los Angeles, San Francisco, Virtual-Online &#x1F310;</p><p>&#x1F4C5; Twice a year in NYC for four years; once a year in LA for three years; once a year in SF for two years; now virtual</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To build a teacher and student community around p5 for middle and high school.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>A half-day of workshop led by volunteer teachers. We saw lots of different methods and materials. Most used some sort of slides or documentation, some live coding using an editor, with work time for participant to remix.</p><p>&#x1F517; <a href="https://http://ccfest.rocks/lessons">CC Fest Lessons page</a> for teaching materials</p><p>&#x1F4F8; <a href="http://ccfest.rocks/pictures">More photos</a></li>
            +
            +              				<!--<li class = "case"><iframe src="http://ccfest.rocks/pictures" height= "200" alt="Pictures of CC Fest"></iframe></li>-->
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>(Sub-)Culture</label><label>Occupation</label></li>	
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #4-->
            +	
            +				  <div class="modal-content" id="case4"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Taller Introducción a la Programación Creativa con p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Aarón Montoya-Moraga</p></li>
            +
            +				        	<li class = "case"><p class = speech>"p5.js is my happy place &#x1F495; "</p></li>
            +
            +				        	<li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://miro.medium.com/max/1000/1*OIn_NKGuKyto9-_h6CAmmw.jpeg" alt="A group of 20 people sitting on a large shared table with their laptops looking at a projected screen."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD;  PlusCode Media Arts Festival, Buenos Aires, Argentina & Virtual-Online  &#x1F310;</p><p>&#x1F4C5; 2018 November 14, 3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>I had around 16 students in the workshop, and a team including 3 people from the PlusCode festival, and one person at the venue.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary, Intermediate, Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Introduction to beginners and artists of graphic web programming and open source, using p5.js, in Spanish :)</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>I used the material on this <a href="https://github.com/montoyamoraga/workshop-p5js-pluscode-2018">GitHub repo</a>, we used the p5.js web editor, we had a three hour long workshop</p><p>&#x1F517; <a href="https://medium.com/processing-foundation/code-electronic-art-festival-2018-argentina-803d3ca8092c">+CODE electronic art festival 2018, Argentina</a>, Medium</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Religion</label><label>(Sub-)Culture</label><label>Age</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label></li>
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				  <!--modal box #5-->
            +	
            +				  <div class="modal-content" id="case5"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to Generative Drawing</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Adam Herst</p></li>
            +
            +				        	<li class = "case"><p class = speech>"My greatest source of uncertainty in developing the workshop was whether it was trying to teach art to programmers or to teach programming to artists."</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; <a href="https://interaccess.org/studio">Inter/Access</a> (artist-run centre), Toronto, Ontario, Canada</p><p>In-person with a self-paced workbook for remote work</p><p>&#x1F4C5; 2020 February 12, 7PM-9PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>15 artists
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To introduce p5.js to artists with little or no programming experience and to suggest one way an analogue practice can migrate to a digital form.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD;Method & Materials</p><p>A printed workbook with activities that used the p5.js web editor to show how translate an physical drawing into a digital drawing.</p><p>&#x1F517;<a href="https://interaccess.org/event/2019/processing-community-day-generative-drawing">Processing Community Day 2019: Generative Drawing at Inter/Access</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Letter PDF</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Booklet PDF</a></p></li>		
            +
            +				    		<li class = "clear"></li>
            +				        	<li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Class</label><label>(Sub-)Culture</label><label>Age</label><label>Skill Level</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #6-->
            +	
            +				  <div class="modal-content" id="case6"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Open Lecture, Creative Coding: 2020</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I love p5.js because it's so easy to read and write code in p5.js. Coding in your everyday life!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				          	<li class = "clear"></li>	
            +				          	<li class = "case"><img src="https://lh3.googleusercontent.com/pw/ACtC-3eYswa6tJH5pvfvvAAfXQJO71ncsdgpwDBvbPAL-qcwnLkkpuoAVpggOb2-LYSLqo0Htd8cgnv5i8yLJg6Wh7J_rW2MMy6y8XZRznRByjj2mGJHf8XFmDI-8W6mH7urrEQC2tyUMF1HWaamLTNBqmIyeQ=w1560-h878-no?authuser=0" alt="A table on which there is a laptop, some sheets of papers, colorful pens and two automatic machines drawing something with a pen on a sheet."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Kyoto University of Art and Design, Kyoto, Japan & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2020 March 16-18, 1-7 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Students of Kyoto University of Art and Design, and anyone.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Making code as a tool for artistic expression.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/Day1-1-p5.js-i15dvmUETr4ef1xnydzru">Syllabus</a><p>&#x1F517; <a href="https://youtu.be/aS5CvADPdk0">Day 1</a>, <a href="https://youtu.be/ZCO-8CubifI">Day 2</a>, <a href="https://youtu.be/nbcckC5iwIcsyllabus">Day 3</a>, YouTube</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Religion</label><label>(Sub-)Culture</label><label>Political Opinion</label><label>Age</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #7-->
            +	
            +				  <div class="modal-content" id="case7"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Creative Coding for Static Graphics</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Coding in p5.js is a lot of fun. If you haven't started yet, I encourage you to give it a try!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://uc6d9323e0272069edcf30e9c501.previews.dropboxusercontent.com/p/thumb/AA5dvRUhxkQ9wLU6mHcrEmLvXnV7gbapPG2PvVf5K8K9ktlC59RCtvbSCP7YfEgPcFtnsgQekujWSD8iEfc6UT2pouzLdZUElblXhh9wg_b2UKDU-OO1u8VaiuC91g73tQX9S9mTHIgvm4h_Jw9-P4F6-iyjqBz57CvFWhilM5CpNbiPIjVRX6NsMkSYA3IexYreShT6Bt2hOWnorsocCsaafJiAd3cZbplWnGiuZmCn5R7BJ4u770YRjqX-AKh6AaoOb3kZHwBBnPQSU7zxiHqZbrWirjwLprw5D5UKW4bMI6We85Yn8cDPlJ6CktIqwpepAhdRi7scaxLxGnpIE4XjnoxK6T1jHkWZXGkvPplV1qlvrC7qz2jTY1_cULKcAcV8F-I-xvAL5I0n3rRHCZqr/p.jpeg?fv_content=true&size_mode=5" alt=""></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; FabCafe MTRL, Tokyo, Japan</p><p>&#x1F4C5; 2019 September 15, 4-7 PM </p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Anyone who wants to try coding in p5.js.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To code from the graphic design's perspective.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/--A6IUdC5pD_0QfbWt1PQ5u~PiAg-Fk8qxFWjaJWeH1cAc8FT0">Syllabus & Material</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Religion</label><label>(Sub-)Culture</label><label>Political Opinion</label><label>Age</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #8-->
            +	
            +				  <div class="modal-content" id="case8"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Generative Typography</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Dae In Chung</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://drive.google.com/uc?id=1TqcLurMLFioe8EcoJGtdK9_gs9bZ5odW" alt="A image with black background displaying the letter 'b' in 5 different styles along with a menu with various styling options to choose."></li>
            +
            +            	            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Baltimore, Maryland, USA & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2019 January 21 - May 08, every Wednesday, 4-10 PM</p></li>  
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>14 undergrads and grad students who had little to no experience in coding.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Experiment with typographic forms and structures through computation.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: online/offline lectures and critiques.</p><p>Materials: p5js online editor, Github, youtube tutorials.</p><p>&#x1F517; <a href="https://drive.google.com/drive/folders/15aFXijbqworOoLpc0fD283YOgi7UIHMA?usp=sharing">Works of participants</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Race & Ethnicity</label><label>Language</label><label>(Sub-)Culture</label><label>Skill Level</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +
            +				  <!--modal box #9-->
            +	
            +				  <div class="modal-content" id="case9"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Machine Learning for the Web</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Yining Shi</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://drive.google.com/uc?id=1pO3s4lraBwtLcZoCIeHGVncuwtzHqN6o" alt="A group of 16 people sitting around tables with their laptops, mobile phones and some other accessories, facing towards a large television screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; ITP, NYU, 370 Jay St, Brooklyn, NY 11201, USA</p><p>&#x1F4C5;2019 March 09 - October 12, every Tuesday, 6:30-9:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Students at Interactive Telecommunications Program, New York University. 16 people.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary, Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>The goal of this class is to learn and understand common machine learning techniques and apply them to generate creative outputs in the browser using ml5.js and p5.js.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>This class is a mix of lectures, coding sessions, group discussions, and presentations. I used<a href="https://github.com/yining1023/machine-learning-for-the-web">GitHub</a> to host class syllabus and all the coding materials, Google Slides for lectures and p5.js Web Editor for live coding sessions. Every week, there were one-on-one office hours to talk about any difficulties of coming up with an idea for the homework or any coding changes.</p><p>Methods: online/offline lectures and critiques.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Age</label><label>Skill Level</label><label>Occupation</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label><label>#BlackLivesMatter</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #10-->
            +	
            +				  <div class="modal-content" id="case10"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to p5.js and JavaScript</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Nico Reski</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date<p>&#x1F4CD; Currently available as self-study at own pace with accompanying slides, linked below.</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Beginner, Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Introduce learners (potentially with no coding experiences at all) to the very basics of p5.js (and JavaScript), in order to encourage creative coding and enable them to pursue own projects in a safe environment.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>p5.js source code (for the introductory project), JavaScript source code (illustrating some basic JavaScript functionalities), accompanying slides in .pdf format, all hosted publicly on GitHub.</p><p>&#x1F517; <a href="https://reski.nicoversity.com/ws_cc_p5js_introduction.html">Overview</a> of the workshop and its contents (including all links to the material hosted on GitHub) on my academic webpage.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #11-->
            +	
            +				  <div class="modal-content" id="case11"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Digital Weaving & Physical Computing Workshop Series</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Qianqian Ye & Evelyn Masso</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +				            <li class = "case"><img src="https://drive.google.com/uc?id=1QXtrew8S2YQ-_6R0H1FhwiEJj9_LLcpU" alt="This image is divided in two parts. The left part shows a group of 15 women sitting on chairs with their laptops and looking at a presentor who is explaining a code on a projected screen. The right part of the image shows a person learning weaving using a physical pattern and a weaving tool."></li>
            +
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Womens Center for Creative Work (WCCW), Los Angeles, CA, US</p><p>&#x1F4C5; 2019 October 19 - November 02, every Saturday 3-6 PM</p></li>  		
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>15 women and non-binary artists, designer, makers, programers. </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary
            +				            </p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Over the course of three workshops, we will draw and create patterns using p5.js, an open-source graphical library; we will learn and apply computational concepts to transform patterns and finally, we will bring a weaving to life with electronic microcontrollers.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: small team session</p><p>Materials: slides, p5.js web editor, pen and paper to draw pattern, physical pattern weaving tool.</p><p>&#x1F517; <a href="https://docs.google.com/presentation/d/1gJ67aKVGydSNoeUraS7U_QevcnOuxnSFQ_4640Qlifo/edit?usp=sharing">Workshop Slide #1</a>, <a href="https://docs.google.com/presentation/d/1nuje9-j_o5HbCoxXR_EJhAYmSEjTQOkAHmBsuKRlwwA/edit?usp=sharing">Workshop Slide #2</a></p><p>&#x1F517; <a href="https://womenscenterforcreativework.com/events/digital-weaving-physical-computing/">Workshop Information</a> on WCCW website.</p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +  				  <!--modal box #12-->
            +	
            +				  <div class="modal-content" id="case12"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Signing Coders</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Taeyoon Choi</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I'm working on a new series of coding class for Disabled students in South Korea. I'm researching about the pedagogy and translation. I plan to hold workshops in December 2020. The project is supported by the Open Society Foundation Human Rights Initiative and Korea Disability Arts & Culture Center."</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><img src="http://taeyoonchoi.com/wp-content/uploads/2016/04/day1-7852-768x512.jpg" alt="Two volunteers explaining concepts using a white board and a screen to a bunch of deaf and hard of hearing students, each student facing a computer screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD;  WRIC, New York City, USA & Seoul Museum of Art, Seoul, South Korea.</p><p>5 Sessions, each 2~3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Deaf and Hard of Hearing students age 10~50 who live in NYC.
            +				            </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To help Deaf and Hard of Hearing students learn about computer programming through playful exercises. To make ASL tutorial of basic coding concepts.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>We used p5.js Web editor and code examples on the website. We also used dice, playing cards and various paper tools to help students learn about coding concepts.</p><p>&#x1F517; <a href="http://taeyoonchoi.com/soft-care/signing-coders/">Syllabus & Material</a></p><p>&#x1F4F8; <a href="http://taeyoonchoi.com/soft-care/signing-coders/signing-coders-1/">More photos</a></p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Skill Level</label></li>
            +				         
            +
            +
            +				            </ul>
            +				        
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +			</div> <!--modal boxes end-->
            +
            +			
            +			
            +
            +	</section>
            +
            +
            +	<!--modal-->
            +
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">आभार सूची</h2>
            +      <p>
            +        p5.js <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> द्वारा बनाया गया था और सहयोगियों के एक समुदाय द्वारा विकसित किया गया है| इस्का समरथ करन वले थे <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> और <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>पहचान और ग्राफिक डिजाइन करने वाले थे <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>Identity and graphic design by <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/hi/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +<!--jquery script-->
            +
            +<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
            +<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
            +<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
            +
            +
            +<!--filter search-->
            +
            +
            +<script>
            +    $("#filters :checkbox").click(function() {
            +
            +       var re = new RegExp($("#filters :checkbox:checked").map(function() {
            +                              return this.value;
            +                           }).get().join("|") ); //.join("|")
            +       $(".case-list").each(function() {
            +          var $this = $(this);
            +          $this[re.source!="" && re.test($this.attr("data-category")) ? "fadeIn" : "hide"]();
            +       });
            +    });
            +</script>
            +
            +
            +<!--modal box-->
            +
            +
            +<script>
            +$(document).on('click','.caseBtn',function(){
            +	var openModal =  $(this).attr('href');
            +	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +	
            +	$('#caseModals').fadeIn();
            +	$(openModal).fadeIn();
            +  return false;
            +});
            +
            +$("body" ).on( "click",".close", function() {
            +  	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +});
            +
            +</script>
            +
            +<!--search accordion menu-->
            +
            +<script>
            +
            +
            +var acc = document.getElementsByClassName("search-filter");
            +var i;
            +
            +for (i = 0; i < acc.length; i++) {
            +  acc[i].addEventListener("click", function() {
            +    this.classList.toggle("active");
            +    var panel = this.nextElementSibling;
            +    if (panel.style.maxHeight) {
            +      panel.style.maxHeight = null;
            +    } else {
            +      panel.style.maxHeight = panel.scrollHeight + "px";
            +    } 
            +
            +  });
            +}
            +</script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/hi/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/index.html b/dist/index.html
            new file mode 100644
            index 0000000000..2029c1cf7b
            --- /dev/null
            +++ b/dist/index.html
            @@ -0,0 +1,177 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">home | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/assets/img/favicon.ico">
            +    <link rel="icon" href="/assets/img/favicon.ico">
            +
            +
            +    <script src="/assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<div id="home-page">
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content" class="home">
            +      <form id="search" method="get" action="https://www.google.com/search">
            +        <input type="hidden" name="as_sitesearch" value="p5js.org">
            +        <input id="search_button" type="submit" aria-label="Search" class='sr-only'>
            +        <input tabindex="2" id='search_field' type="text" size="20" placeholder="Search p5js.org" name="q">
            +        <label class="sr-only" for="search_field">Search p5js.org</label>
            +      </form>
            +
            +      <h1>Hello!</h1>
            +      <p style="margin-top:1em">p5.js is a JavaScript library for creative coding, with a focus on making coding accessible and inclusive for artists, designers, educators, beginners, and anyone else! p5.js is free and open-source because we believe software, and the tools to learn it, should be accessible to everyone.</p>
            +      <p>Using the metaphor of a sketch, p5.js has a full set of drawing functionality. However, you’re not limited to your drawing canvas. You can think of your whole browser page as your sketch, including HTML5 objects for text, input, video, webcam, and sound.</p>
            +      <p><a href="https://discord.gg/SHQ8dH25r9">Join the p5.js Discord!</a></p>
            +      <a href="https://editor.p5js.org"><span class='button_box'>Start creating with the p5 Editor!</span></a>
            +
            +      <h2>Community</h2>
            +      <p>We are a community of, and in solidarity with, people from every gender identity and expression, sexual orientation, race, ethnicity, language, neuro-type, size, disability, class, religion, culture, subculture, political opinion, age, skill level, occupation, and background. We acknowledge that not everyone has the time, financial means, or capacity to actively participate, but we recognize and encourage involvement of all kinds. We facilitate and foster access and empowerment. We are all learners.</p>
            +      <p>p5.js is an interpretation of <a href="https://processing.org"
            +          target="_blank">Processing</a> for today’s web. We hold events and operate with support from the <a href="https://processingfoundation.org"
            +          target="_blank">Processing Foundation</a>.</p>
            +      <p>Learn more about <a href="community/">our community</a>.</p>
            +
            +      <h2>Get Started</h2>
            +      <p>Make your first sketch in the <a href="https://editor.p5js.org" target="_blank">p5.js
            +          Editor</a>. Learn more about sketching with p5.js on the <a
            +          href="get-started/">Get Started page</a> and everything you can do in the <a
            +          href="reference/">Reference</a>.</p>
            +
            +      <h2>Get Involved</h2>
            +      <p>There are many ways to contribute to p5.js:</p>
            +      <h2 id="involvement-options" class="sr-only">Involvement Options</h2>
            +      <ul aria-labelledby="involvement-options" class="list_view bullets">
            +        <li><a href="/teach">Teach a workshop or class.</a></li>
            +        <li><a href="https://day.processing.org" target="_blank">Organize a meet-up.</a></li>
            +        <li><a href="https://github.com/processing/p5.js/tree/main/contributor_docs"
            +            target="_blank">Contribute to the codebase.</a></li>
            +      </ul>
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +  </div> <!-- end column-span -->
            +
            +
            +  <p class="clearfix">&nbsp;</p>
            +
            +  <object tabindex=-1 type="image/svg+xml" data="assets/img/thick-asterisk-alone.svg" id="asterisk-design-element"
            +    aria-hidden="true">*</object>
            +</div> <!-- end home-page -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/books/index.html b/dist/ko/books/index.html
            new file mode 100644
            index 0000000000..3e2ecffddd
            --- /dev/null
            +++ b/dist/ko/books/index.html
            @@ -0,0 +1,302 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">books | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="books-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>출판물</h1>
            +      <br>
            +
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/gettingstarted.jpg" alt="book cover getting started with p5.js">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Getting Started with p5.js (p5.js 시작하기)</h2>
            +
            +          <p>Lauren McCarthy, Casey Reas, Ben Fry 저. 삽화: 최태윤.</p>
            +          <p>
            +            2015년 10월 Maker Media 출판. 
            +            246 페이지. 
            +            페이퍼백.
            +          </p>
            +
            +          <p>p5.js의 리드 개발자와 프로세싱의 창립자들이 저술한 이 책은, 자바스크립트와 HTML을 통해 오늘날 웹아 보다 창의적으로 사용될 수 있는 가능성을 소개합니다.</p>
            +
            +          <p><a href="http://shop.oreilly.com/product/0636920032076.do" target="_blank">O'Reilly에서 인쇄물/e북 주문하기</a></p>
            +          <p><a href="http://www.amazon.com/Make-Interactive-Graphics-JavaScript-Processing/dp/1457186772" target="_blank">아마존에서 주문하기</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/gettingstarted-es.jpg" alt="book cover Introducción a p5.js">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Introduction to p5.js (스페인어 에디션)</h2>
            +
            +          <p>Lauren McCarthy, Casey Reas, Ben Fry 저. <br> 번역: Aarón Montoya-Moraga. 삽화: 최태윤.</p>
            +          <p>
            +            2018년 Processing Foundation, Inc. 출판. 
            +            246 페이지. 
            +            소프트커버.
            +          </p>
            +
            +          <p>p5.js의 리드 개발자와 프로세싱의 창립자들이 저술한 이 책은, 자바스크립트와 HTML을 통해 오늘날 웹이 보다 창의적으로 사용될 수 있는 가능성을 소개합니다.</p>
            +
            +          <p><a href="https://processingfoundation.press/product/introduccion-a-p5-js/" target="_blank">Processing Foundation Press에서 PDF 주문하기</a></p>
            +          <p><a href="https://www.amazon.com/Introducci%C3%B3n-p5-js-Spanish-Lauren-McCarthy/dp/0999881302/" target="_blank">아마존에서 인쇄물 주문하기</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/generative_design.jpg" alt="book cover generative design">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Generative Design(제너레이티브 디자인)</h2>
            +
            +          <p>Benedikt Gross, Hartmut Bohnacker, Julia Laub, Claudius Lazzeroni 저.</p>
            +          <p>
            +            2018년 10월 30일 Princeton Architectural Press 출판; 별쇄본. 
            +            255 페이지. 
            +            페이퍼백.
            +          </p>
            +
            +          <p>p5.js의 자바스크립트와 같은 간단한 언어를 통해, 예술가들과 창작자들은 인터랙티브 타이포그래피와 섬유로부터, 3D 프린팅 가구, 그리고 복잡하고 우아한 인포그래픽 등에 이르는 모든 것을 만들 수 있습니다.</p>
            +
            +          <p><a href="https://www.papress.com/html/product.details.dna?isbn=9781616897581" target="_blank">Princeton Architectural Press에서 주문하기</a></p>
            +          <p><a href="https://www.amazon.com/Generative-Design-Visualize-Program-JavaScript/dp/1616897589" target="_blank">아마존에서 주문하기</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/generative_gestaltung.jpg" alt="book cover Generative Gestaltung">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Generative Gestaltung (제너레이티브 디자인 독일어 에디션)</h2>
            +
            +          <p>Benedikt Gross, Hartmut Bohnacker, Julia Laub and Claudius Lazzeroni.</p>
            +          <p>
            +            2018년 1월 Schmidt Hermann Verlag 출판. 
            +            256 페이지.
            +            하드커버.
            +          </p>
            +
            +          <p>p5.js의 자바스크립트와 같은 간단한 언어를 통해, 예술가들과 창작자들은 인터랙티브 타이포그래피와 섬유로부터, 3D 프린팅 가구, 그리고 복잡하고 우아한 인포그래픽 등에 이르는 모든 것을 만들 수 있습니다.</p>
            +
            +          <p><a href="https://typografie.de/produkt/generative-gestaltung-creative-coding-im-web/" target="_blank">Verlag Hermann Schmidt에서 주문하기</a></p>
            +          <p><a href="https://www.amazon.com/Generative-Gestaltung/dp/3874399028" target="_blank">아마존에서 주문하기</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/learn_javascript.jpg" alt="book cover learn javascript">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Learn JavaScript with p5.js <br> (p5.js로 자바스크립트 배우기)</h2>
            +
            +          <p>Engin Arslan 저.</p>
            +          <p>
            +            2018년 Apress 출판. 
            +            217 페이지.
            +            페이퍼백.
            +          </p>
            +
            +          <p>널리 사용되는 자바스크립트와 그 프로그래밍 라이브러리인 p5.js을 통해 아주 매력적이고 시각적인 방식으로 코딩에 입문하세요. 이 책에서 습득할 수 있는 기술은 수많은 산업계에서도 호환되는 것이며, 웹 어플리케이션, 로봇 프로그래밍, 제너레이티브 아트를 제작하는 데에도 쓰입니다.</p>
            +
            +          <p><a href="https://www.apress.com/gp/book/9781484234259" target="_blank">Apress에서 주문하기</a></p>
            +          <p><a href="https://www.amazon.com/Learn-JavaScript-p5-js-Coding-Learners/dp/1484234251" target="_blank">아마존에서 주문하기</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/aesthetic-programming.jpg" alt="book cover learn javascript">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Aesthetic Programming: A Handbook of Software Studies (미학적 프로그래밍: 소프트웨어학을 위한 핸드북)</h2>
            +
            +          <p>Winnie Soon, Geoff Cox 저. </p>
            +          <p>
            +            2020년 Open Humanities Press 출판. 
            +            298 페이지. 
            +            하드커버.
            +          </p>
            +
            +          <p>이 책은 p5.js 기반의 미학적 프로그래밍과 그 성찰적 실천을 소개합니다. 현존하는 기술적 대상과 패러다임을 이해하고 질문하며, 또  보다 넓은 생태-사회-기술 체제를 다시-프로그래밍 하는 가능성으로서의 프로그래밍 교육을 제시합니다.</p>
            +
            +          <p><a href="http://openhumanitiespress.org/books/download/Soon-Cox_2020_Aesthetic-Programming.pdf" target="_blank">PDF 파일 다운로드 (무료)</a></p>
            +          <p><a href="https://www.barnesandnoble.com/w/aesthetic-programming-winnie-soon/1138820949" target="_blank">Barnes & Noble에서 주문하기</a></p>
            +
            +        </div>
            +      </div>
            +      <br>
            +      <div style='clear:both; height: 2em'></div>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="books-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/community/contributors-conference-2015.html b/dist/ko/community/contributors-conference-2015.html
            new file mode 100644
            index 0000000000..7a177938b6
            --- /dev/null
            +++ b/dist/ko/community/contributors-conference-2015.html
            @@ -0,0 +1,286 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>2015년 공헌자 컨퍼런스</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>5월 25-31일</h2>
            +
            +      <p>약 30여명의 참여자들이 <a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a>에 모여, p5.js의 프로그래밍 코드와 문서화 작업을 진전시키고, 커뮤니티를 확장하는 방안에 대해 논의하였습니다. 멀리서는 홍콩, 그리고 시애틀, 로스 엔젤레스, 보스턴, 뉴욕 등지에서 찾아온 참여자들이 함께하였습니다. 대부분의 참여자들이 크리에이티브 기술, 인터랙션 디자인, 그리고 뉴미디어 아트 분야의 전문 종사자였고, 카네기 멜론 미술 및 건축 대학교 출신의 학부생 및 대학원생도 6명 정도 포함하였습니다.
            +      </p>
            +      </div>
            +
            +      <img src="../../assets/img/community/2015_1.jpg" alt='다양한 배경 출신의 참여자들이 미소를 지으며 손으로 p5 사인을 만드는 모습"'/>
            +      <img src="../../assets/img/community/2015_3.jpg" alt='노트북으로 p5.js 커뮤니티 성명서를 발표하고 있는 여성"'/>
            +      <img src="../../assets/img/community/2015_4.jpg" alt='마이크에 대고 열정적으로 말하고 있는 여성과 그를 쳐다보는 남성 협력자 두 명"'/>
            +      <img src="../../assets/img/community/2015_5.jpg" alt='미소를 띄우며 발표를 경청하는 참여자들 모습"'/>
            +      <img src="../../assets/img/community/2015_6.jpg" alt='마이크에 대고 3명의 여학생들을 향해 p5.js를 설명하는 여성"'/>
            +      <img src="../../assets/img/community/2015_7.jpg" alt='여학생 한명이 마이크에 대고 발표하는 동안, 포스트잇이 붙은 화이트보드를 둘러앉은 참여자들의 모습"'/>
            +      <img src="../../assets/img/community/2015_8.jpg" alt='책상에 둘러앉아 서로의 노트북을 보며 코드를 비교하는 참여자들의 모습"'/>
            +      <img src="../../assets/img/community/2015_9.jpg" alt='프로그래밍에 대한 노트가 적힌 여러가지 색의 포스트잇이 화이트보드에 붙어있는 모습"'/>
            +      <img src="../../assets/img/community/2015_10.jpg" alt='한 교실에서 다양한 기술 능력의 가치를 존중하는 것에 대해 발표하는 여성과 그의 파워포인트를 바라보는 참여자들의 모습"'/>
            +      <img src="../../assets/img/community/2015_11.jpg" alt='대강당 무대 위 단상에서 발표하는 여성과 무대에 앉아있는 세명의 참여자들, 그리고 무대 위 스크린상의 스카이프 화면을 통해 보이는 또다른 세명의 원격 참여자들"'/>
            +      <img src="../../assets/img/community/2015_12.jpg" alt='노트북으로 작업하는 참여자들이 있는 교실 전경"'/>
            +      <img src="../../assets/img/community/2015_13.jpg" alt='둥그렇게 앉아 토론하는 5명의 사람들"'/>
            +      <img src="../../assets/img/community/2015_14.jpg" alt='노트북과 함께 둥그렇게 앉아 자신의 필기를 공유하는 5명의 사람들"'/>
            +      <img src="../../assets/img/community/2015_15.jpg" alt='교실에서 참여자들을 향해 마이크로 발표하는 남성"'/>
            +      <img src="../../assets/img/community/2015_2.jpg" alt='잔디 위에서 뛰놀고, 웃으며, 손을 하늘 위로 들어올리는 참여자들의 모습"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/80913365@N04/albums/72157653238862069/with/17613092994/" target="_blank">사진 촬영: 최태윤(Taeyoon Choi)</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>참여자</h2>
            +      <p>
            +        <a href='http://huah.net/jason/' target='_blank'>Jason Alderman</a>,
            +        <a href='http://sepans.com/' target='_blank'>Sepand Ansari</a>,
            +        <a href='http://tegabrain.com' target='_blank'>Tega Brain</a>,
            +        <a href='https://medium.com/@emchenNYC/' target='_blank'>Emily Chen</a>,
            +        <a href='http://andrescolubri.net/' target='_blank'>Andres Colubri</a>,
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>,
            +        <a href='http://guydebree.com/' target='_blank'>Guy de Bree</a>,
            +        <a href='http://www.cjdecarteret.com/' target='_blank'>Christine de Carteret</a>,
            +        <a href='http://xystudio.cc/' target='_blank'>Xy Feng</a>,
            +        <a href='http://www.sarahgp.com/' target='_blank'>Sarah Groff-Palermo</a>,
            +        <a href='http://www.crhallberg.com/' target='_blank'>Chris Hallberg</a>,
            +        <a href='http://valhead.com/' target='_blank'>Val Head</a>,
            +        <a href='http://johannahedva.com' target='_blank'>Johanna Hedva</a>,
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>,
            +        <a href='http://web.media.mit.edu/~jacobsj/' target='_blank'>Jennifer Jacobs</a>,
            +        <a href='http://www.epicjefferson.com/' target='_blank'>Epic Jefferson</a>,
            +        <a href='http://michellepartogi.com' target='_blank'>Michelle Partogi</a>,
            +        <a href='http://lav.io/' target='_blank'>Sam Lavigne</a>,
            +        <a href='http://flong.com' target='_blank'>Golan Levin</a>,
            +        <a href='http://www.liuchangitp.com/' target='_blank'>Cici Liu</a>,
            +        <a href='http://www.mayaman.cc/' target='_blank'>Maya Man</a>,
            +        <a href='http://lauren-mccarthy.com' target='_blank'>Lauren McCarthy</a>,
            +        <a href='http://www.workergnome.com/' target='_blank'>David Newbury</a>,
            +        <a href='http://molleindustria.org/' target='_blank'>Paolo Pedercini</a>,
            +        <a href='http://luisaph.com' target='_blank'>Luisa Pereira</a>,
            +        <a href='http://mileshiroo.info/' target='_blank'>Miles Peyton</a>,
            +        <a href='http://carolinerecord.com/' target='_blank'>Caroline Record</a>,
            +        <a href='http://b2renger.github.io/' target='_blank'>Berenger Recoules</a>,
            +        <a href='https://pibloginthesky.wordpress.com/' target='_blank'>Stephanie Pi</a>,
            +        <a href='http://jasonsigal.cc' target='_blank'>Jason Sigal</a>,
            +        <a href='http://studioindefinit.com/' target='_blank'>Kevin Siwoff</a>,
            +        <a href='http://charlottestiles.com/' target='_blank'>Charlotte Stiles</a>
            +      </p>
            +      </div>
            +
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>다양성</h2>
            +        <p>기술 개발 문제 외에도 중요하게 다루어졌던 컨퍼런스 주제는 커뮤니티, 확장, 다양성이었습니다. 컨퍼런스는 패널—<a href="http://studioforcreativeinquiry.org/events/diversity-seven-voices-on-race-gender-ability-class-for-floss-and-the-internet" target="_blank">다양성: 인종, 젠더, 능력에 대한 7가지의 목소리, FLOSS와 인터넷을 위한 수업</a>과 함께 시작하였습니다. 패널 진행은  <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>
            +        과 <a  href="http://lauren-mccarthy.com" target="_blank">Lauren McCarthy</a>가 맡았으며, 2015년 5월 25일 화요일 카네기 멜론 대학교 Kresge Auditorium 에서 열렸습니다. 연사는 <a href="http://www.mayaman.cc/" target='_blank'>Maya Man</a>, <a href="http://reas.com/" target='_blank'>Casey
            +        Reas</a>, <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>, <a href="https://pibloginthesky.wordpress.com/" target='_blank'>Stephanie Pi</a>,
            +        <a href="http://phoenixperry.com/" target='_blank'>Phoenix Perry</a>, <a href="http://taeyoonchoi.com/" target='_blank'>Taeyoon Choi</a>,
            +        <a href="http://ablersite.org/" target='_blank'>Sara Hendren</a>, <a href="http://www.epicjefferson.com/" target='_blank'>Epic Jefferson</a>,
            +        과 <a href="http://chandlermcwilliams.com/" target='_blank'>Chandler McWilliams</a>였습니다.
            +        <img class="alignleft size-full wp-image-8423" src="http://studioforcreativeinquiry.org/wp-content/uploads/2015/05/diversity_640.jpg" alt="diversity_640"/>
            +        </p>
            +        <iframe src="https://player.vimeo.com/video/129140298?color=ffffff&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +        
            +        <table style="margin-top: 10px; background-color: #ffffff; border-collapse: collapse; border: 0px; width: 720px;">
            +        <tbody>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129151416?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Casey Reas</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129151418?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Johanna Hedva</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129160951?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Stephanie Pi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129163155?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Phoenix Perry</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129173628?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Taeyoon Choi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129177689?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Sara Hendren</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129183825?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Epic Jefferson</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129187909?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Chandler McWilliams</td>
            +        </tr>
            +        </tbody>
            +        </table>
            +        <iframe src="https://player.vimeo.com/video/129192014?color=ffffff&amp;title=1&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +      </div>
            +
            +
            +<!--       <div class="contributors-subsection">
            +      <h3>Documentation</h3>
            +      <p><a href='https://medium.com/@tchoi8/diversity-at-sfpc-d494d7390375' target=_blank>Diversity at SFPC
            +      (talk by Taeyoon Choi at “Diversity: Seven Voices on Race, Gender, Ability &amp; Class for FLOSS and
            +      the Internet”)</a></p>
            +      </div> -->
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>지원</h2>
            +
            +      <p>공헌자 컨퍼러스는 카네기 멜론 대학교의 <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> 에서 열렸습니다. 이 곳은 예술, 과학, 기술, 그리고 문화의 교차점에서, 비정형적, 반-학제적 및 간-기관적 연구를 진행하는 학술랩입니다.</p>
            +
            +      <p>이 행사는  <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      의 기금과  <a href="https://tisch.nyu.edu/itp" target="_blank">NYU Interactive Telecommunications Program</a>
            +      (ITP), <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href="http://theartificial.nl/" target="_blank">TheArtificial</a>, <a href="http://bocoup.com/" target="_blank">Bocoup</a>, <a href="http://tinysubversions.com/" target="_blank">Darius Kazemi</a>, 과 <a href="http://www.du.edu/ahss/edp/" target="_blank">Emergent Digital Practices | University of Denver</a><br><b>의 지원 덕분에 가능했습니다. 감사합니다!</b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../../assets/img/community/nea.jpg' alt=""></a></div>
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:18%' src='../../assets/img/community/studio.png' alt=""/></a>
            +      <a class='nounderline' href='http://itp.nyu.edu/itp/' target=_blank ><img style='width:18%' src='../../assets/img/community/itp.png' alt=""/></a>
            +      <a class='nounderline' href='http://www.du.edu/ahss/edp/' target=_blank ><img style='width:18%' src='../../assets/img/community/edp.png' alt=""/></a>
            +      <a class='nounderline' href='http://bocoup.com/' target=_blank ><img style='width:18%' src='../../assets/img/community/bocoup.png' alt=""/></a>
            +      <a class='nounderline' href='http://theartificial.nl/' target=_blank ><img style='width:18%' src='../../assets/img/community/theartificial.png' alt=""/></a>
            +
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/community/contributors-conference-2019.html b/dist/ko/community/contributors-conference-2019.html
            new file mode 100644
            index 0000000000..8a03bb7b6c
            --- /dev/null
            +++ b/dist/ko/community/contributors-conference-2019.html
            @@ -0,0 +1,307 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>2019년 공헌자 컨퍼런스</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>8월 13-18일</h2>
            +
            +      <p>다학제적 배경을 지닌 35명의 참여자들이 <a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a>에 모여 p5.js의 프로그래밍 환경과 그 현주소를 탐색하고, 코드 및 문서 개발, 그리고 커뮤니티 확장 방법에 대해 논의하였습니다. 참여자들은 크리에이티브 기술, 인터랙션 디자인, 뉴미디어 아트를 아우르는 다양한 분야의 종사자들로 구성되었으며, 컨퍼런스에서의 논의는 이러한 다학제적인 시각을 바탕으로 진행되었습니다. 참여자 그룹은 접근성, 퍼포먼스 속 음악과 코딩, 크리에이티브 기술 지형, 그리고 국제화를 포함한 여러 주제에 초점을 두었습니다.
            +      </p>
            +      </div>
            +      
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/YkfG7Ggpi_o" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/At1newHnZpA" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <p><a href="https://www.youtube.com/channel/UCzMs9qg50AW2LEpLDzHT5NA" target="_blank">비디오 촬영: 치안치안 예(Qianqian Ye)</a></p><br>
            +
            +      <img src="../../assets/img/community/2019_1.jpg" alt='단상 위에서 한 그룹을 향해 발표를 하는 남성"'/>
            +      <img src="../../assets/img/community/2019_2.jpg" alt='긴 테이블에 앉아 점심을 먹으며 토론하는 참여자들"'/>
            +      <img src="../../assets/img/community/2019_4.jpg" alt='교실에서 노트북으로 작업하는 참여자들의 모습"'/>
            +      <img src="../../assets/img/community/2019_5.jpg" alt='어두운 교실에서 미팅을 하는 참여자들"'/>
            +      <img src="../../assets/img/community/2019_6.jpg" alt='여러 참여자들이 모인 교실에서 발표를 하는 여성"'/>
            +      <img src="../../assets/img/community/2019_7.jpg" alt='많은 이들이 모여있는 교실에서 대화를 나누는 참가자들"'/>
            +      <img src="../../assets/img/community/2019_8.jpg" alt='한 교실에서 동료 참여자를 향해 마이크에 대고 말하는 여성"'/>
            +      <img src="../../assets/img/community/2019_9.jpg" alt='데이터 익명화의 문제점에 대한 글이 투사된 스크린과 그 앞 단상에서 말하는 참여자"'/>
            +      <img src="../../assets/img/community/2019_10.jpg" alt='"p5.js는 접근성을 향상을 위한 기능 외에는 향후 새로운 기능을 추가하지 않습니다"라고 적힌 텍스트 앞에 서서, 동료 참여자를 향해 마이크에 대고 말하는 사람"'/>
            +      <img src="../../assets/img/community/2019_11.jpg" alt='동료 참여자를 향해 마이크에 대고 말하는 여성"'/>
            +      <img src="../../assets/img/community/2019_12.jpg" alt='동료 참여자를 향해 마이크에 대고 말하는 남성"'/>
            +      <img src="../../assets/img/community/2019_13.jpg" alt='교실 속, 경청 중인 발표자들을 향해 앉아있는 참여자들"'/>
            +      <img src="../../assets/img/community/2019_15.jpg" alt='"신성한 경계"라 적힌 스크린을 뒤로하고, 동료 참여자를 향해 마이크에 대고 말하는 여성"'/>
            +      <img src="../../assets/img/community/2019_16.jpg" alt='3D 렌더링된 사람 이미지를 보여주는 패널에 경청하는 참여자들 전경"'/>
            +      <img src="../../assets/img/community/2019_17.jpg" alt='노트북과 함께 테이블에 둘러앉아 TV 스크린 상의 코드를 살펴보는 참여자들"'/>
            +      <img src="../../assets/img/community/2019_18.jpg" alt='등신 크기의 테디 베어 옆에 앉아 노트북으로 작업하는 여성"'/>
            +      <img src="../../assets/img/community/2019_19.jpg" alt='밖에 나와 미소를 짓는 참여자들"'/>
            +      <img src="../../assets/img/community/2019_20.jpg" alt='동그랗게 모여 서서 대화를 나누는 4명의 참여자들"'/>
            +      <img src="../../assets/img/community/2019_21.jpg" alt='밖에 나와 앉아 함께 점심을 먹는 참여자들"'/>
            +      <img src="../../assets/img/community/2019_22.jpg" alt='거대한 U자형 테이블에 둘러앉아 교실 앞쪽을 쳐다보는 참여자들"'/>
            +      <img src="../../assets/img/community/2019_23.jpg" alt='교실 앞에 앉아 마이크에 대고 활력적으로 말하는 남성"'/>
            +      <img src="../../assets/img/community/campfire.jpg" alt='LCD 모니터로 만들어진 캠프파이어에 둘러앉은 사람들"'/>
            +      <img src="../../assets/img/community/2019_24.jpg" alt='하늘 향해 손을 들고 활기차게 미소짓는 모습이 담긴 참여자 단체 사진"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/creativeinquiry/albums/72157710545834046/" target="_blank">사진 촬영: 재클린 존슨(Jacquelyn Johnson)</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>참여자</h2>
            +      <p>
            +        <a href='https://americanartist.us/biocv' target='_blank'>American Artist</a>, 
            +        <a href='https://www.omayeli.com/' target='_blank'>Omayeli Arenyeka</a>, 
            +        <a href='http://www.sinabahram.com/' target='_blank'>Sina Bahram</a>, 
            +        <a href='https://aatishb.com/' target='_blank'>Aatish Bhatia</a>, 
            +        <a href='https://natalie.computer/' target='_blank'>Natalie Braginsky</a>, 
            +        <a href='https://jonchambers.net/' target='_blank'>Jon Chambers</a>, 
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>, 
            +        <a href='https://www.linkedin.com/in/aren-davey-bb3496103/' target='_blank'>Aren Davey</a>, 
            +        <a href='https://teddavis.org/' target='_blank'>Ted Davis</a>, 
            +        <a href='http://l05.is/' target='_blank'>Carlos Garcia</a>, 
            +        <a href='http://stalgiagrigg.name/' target='_blank'>Stalgia Grigg</a>, 
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>, 
            +        <a href='http://www.shawnemichaelainholloway.com/' target='_blank'>shawné michaelain holloway</a>, 
            +        <a href='http://www.takinglifeseriously.com/index.html' target='_blank'>Claire Kearney-Volpe</a>, 
            +        <a href='https://www.sonalee.me/' target='_blank'>Sona Lee</a>, 
            +        <a href='https://designerken.be/designing' target='_blank'>Kenneth Lim</a>, 
            +        <a href='https://www.outofambit.com/' target='_blank'>Evelyn Masso</a>, 
            +        <a href='http://lauren-mccarthy.com/' target='_blank'>Lauren McCarthy</a>, 
            +        <a href='https://laja.me/' target='_blank'>LaJuné McMillian</a>, 
            +        <a href='https://www.decontextualize.com/' target='_blank'>Allison Parrish</a>, 
            +        <a href='http://www.luisapereira.net/' target='_blank'>Luisa Pereira</a>, 
            +        <a href='https://guillemontecinos.cl/' target='_blank'>Guillermo Montecinos</a>, 
            +        <a href='http://montoyamoraga.io/' target='_blank'>Aarón Montoya-Moraga</a>,
            +        <a href='http://lm-m.com/' target='_blank'>Luis Morales-Navarro</a>, 
            +        Shefali Nayak, 
            +        <a href='http://everest-pipkin.com/' target='_blank'>Everest Pipkin</a>, 
            +        <a href='http://oross.net/' target='_blank'>Olivia Ross</a>, 
            +        <a href='https://dorothysantos.com/' target='_blank'>Dorothy R. Santos</a>, 
            +        <a href='https://www.yashengshe.com/' target='_blank'>Yasheng She</a>, 
            +        <a href='https://junshern.github.io/' target='_blank'>Jun Shern Chan</a>, 
            +        <a href='https://cassietarakajian.com/' target='_blank'>Cassie Tarakajian</a>, 
            +        <a href='https://www.laurenvalley.com/' target='_blank'>Lauren Valley</a>, 
            +        <a href='https://xin-xin.info' target='_blank'>Xin Xin</a>, 
            +        <a href='https://ayxx.me/' target='_blank'>Alex Yixuan Xu</a>, 
            +        <a href='http://www.qianqian-ye.com/' target='_blank'>Qianqian Ye</a>
            +      </p>
            +      </div>
            +
            +
            +      <div class="outputs-subsection">
            +      <h2 id='outputs'>결과물</h2>
            +      <ul aria-labelledby='outputs' class='list_view bullets'>
            +        <!-- arts -->
            +        <li>가상 공간에서의 블랙니스(Blackness)와 젠더를 다룬 패널, 아메리칸 아티스트(American Artist)가 진행하고 shawné michaelain holloway와 LaJuné McMillian이 함께함.</li>
            +        <li>새로운 설치 예술 작품. 제작: Stalgia Grigg, LaJuné McMillian, Aatish Bhatia, 그리고 Jon Chambers.</li>
            +        <!-- landscape -->
            +        <li>A prototype of a  <a href="https://github.com/aparrish/nb5js-proof-of-concept" target="_blank">p5.js를 위한 노트북 인터페이스</a> 의 프로토타입. 제작: 앨리슨 패리쉬(Allison Parrish)</li>
            +        <li>p5 에디터를 위한 p5.js 라이브러리 시스템 디자인. 제작: 캐시 타라카지안(Cassie Tarakajian)과 루카 다마스코(Luca Damasco)</li>
            +        <li>p5와 다른 라이브러리 연결을 위한 프로토타입들. 제작: 알렉스 이쑤안 쑤(Alex Yixuan Xu)와 로렌 밸리(Lauren Valley)</li>
            +
            +        <!-- global -->
            +        <li><a href="https://docs.google.com/document/d/1NPSVTWlTxWv8_rWLr8j91Qf8CcJA5ns8I8zFjCCmwuk/edit#heading=h.ea0uhs87h6fk" target="_blank">p5.js의 전세계 공헌자를 위한 툴킷</a> 제작: Aarón Montoya-Moraga, Kenneth Lim, Guillermo Montecinos, Qianqian Ye, Dorothy R. Santos, 그리고 Yasheng She.</li>
            +
            +        <!-- access -->
            +        <li><a href="https://docs.google.com/presentation/d/19xxc2zWWdFMAQjT6tRdN5ZU13vAKSwM7jojaC2U4F6Q/edit" target="_blank">비폭력적 크리이에티브 코드 작성법. </a>올리비아 로스(Olivia Ross) 진행 잡지.</li>
            +        <li>p5.js 웹사이트의 접근성에 대한 점검. 스크린 리더 접근성 향상 기능을 비롯하여, 홈, 다운로드, 시작하기, 레퍼런스 페이지 등을 업데이트. 기여: Claire Kearney-Volpe, Sina Bahram, Kate Hollenbach, Olivia Ross, Luis Morales-Navarro, Lauren McCarthy, 그리고 Evelyn Masso</li>
            +
            +        <!-- music performance -->
            +        <li><a href="https://github.com/aahdee/p5grid">p5grid</a>. p5.js를 위한 아주 유연한 삼각형, 사각형, 육각형, 그리고 팔각형 묶음 구현. 제작: 아렌 데이비(Aren Davey)</li>
            +        <li><a href="https://github.com/L05/p5.multiplayer">p5.multiplayer</a>. 복수의 클라이언트를 특정 호스트 페이지에 연결하는 멀티디바이스 및 멀티플레이어 게임을 위한 템플릿 파일. 제작: L05</li>
            +        <li>Experiments using <a href="https://teddavis.org/p5live/">P5LIVE</a>를 이용한 실험들. softCompile 및 OSC 인터페이스 초기 단계 구현과 더불어 MIDI 셋업에 연결한 데모. p5.js 협업 라이브 코딩 VJ 환경 구현. 제작: 테드 데이비스(Ted Davis)</li>
            +        <li>협업 퍼포먼스. 제작: Luisa Pereira, Jun Shern Chan, Shefali Nayak, Sona Lee, Ted Davis, 그리고 Carlos Garcia.</li>
            +        <li>퍼포먼스. 제작: 나탈리 브래긴스키(Natalie Braginsky)</li>
            +  
            +        <!-- workshops -->
            +        <li>에베레스트 핍킨(Everest Pipkin)과 존 챔버스(Jon Chambers)가 진행한 워크숍</li>
            +
            +        <!-- closing -->
            +        <li>클로징 캠프파이어. 진행: 골렌 레빈(Golan Levin)</li>
            +        
            +      </ul>
            +      </div>
            +
            +      <div class="contributors-subsection">
            +      <h2>지원</h2>
            +
            +      <p>공헌자 컨퍼러스는 카네기 멜론 대학교의 <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> 에서 열렸습니다. 이 곳은 예술, 과학, 기술, 그리고 문화의 교차점에서, 비정형적, 반-학제적 및 간-기관적 연구를 진행하는 학술랩입니다.</p>
            +
            +      <p>이 행사는  <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      의 기금과  <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href='https://www.mozilla.org/en-US/moss/' target=_blank>Mozilla Foundation</a>, <a href='https://www.du.edu/ahss/opensourcearts/' target=_blank>Clinic for Open Source Arts (COSA) at the University of Denver</a>, <a href='http://idm.engineering.nyu.edu/' target=_blank>NYU Tandon IDM</a>, <a href='https://tisch.nyu.edu/itp' target=_blank> NYU ITP</a>, <a href='http://thebaselschoolofdesign.ch/' target=_blank>FHNW Academy of Art and Design</a>, <a href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank>DePaul University College of Computing and Digital Media</a>, 과 <a href='http://amt.parsons.edu/' target=_blank>Parsons School of Art, Media, and Technology at the New School</a>.
            +      <br><b>의 지원 덕분에 가능했습니다. 감사합니다!</b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../../assets/img/community/nea.jpg' alt=""></a></div>
            +      
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:20%' src='../../assets/img/community/studio.png' alt=""/></a>
            +      
            +      <a class='nounderline' href='http://thebaselschoolofdesign.ch/' target=_blank ><img style='width:70%' src='../../assets/img/community/HGK.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://foundation.processing.org' target=_blank ><img style='width:14%' src='../../assets/img/community/processing-foundation.png' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='https://www.du.edu/ahss/opensourcearts/' target=_blank ><img style='width:22%' src='../../assets/img/community/COSA.png' alt=""/></a>
            +
            +      <a class='nounderline' href='http://idm.engineering.nyu.edu/' target=_blank ><img style='width:50%' src='../../assets/img/community/IDM.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://amt.parsons.edu/' target=_blank ><img style='width:22%' src='../../assets/img/community/Parsons.jpg' alt=""/></a>
            +
            +      <a class='nounderline' href='https://tisch.nyu.edu/itp' target=_blank ><img style='width:14%' src='../../assets/img/community/itp.png' alt=""/></a>
            +
            +      <a class='nounderline' href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank ><img style='width:50%' src='../../assets/img/community/depaul.png' alt=""/></a>
            +
            +      
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/community/developer-docs.html b/dist/ko/community/developer-docs.html
            new file mode 100644
            index 0000000000..942cb194cf
            --- /dev/null
            +++ b/dist/ko/community/developer-docs.html
            @@ -0,0 +1,141 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<link rel="stylesheet" href="https://unpkg.com/docsify/lib/themes/buble.css">
            +
            +<div id="community-page">
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <div id="app"></div>
            +      <script>
            +        window.$docsify = {
            +          auto2top: true,
            +          executeScript: true,
            +          loadSidebar: 'sidebar.md',
            +          autoHeader: true,
            +          loadNavbar: 'navbar.md',
            +          mergeNavbar: true,
            +          subMaxLevel: 2,
            +          themeColor: '#ed225d',
            +          basePath:
            +          'https://raw.githubusercontent.com/processing/p5.js/master/contributor_docs/',
            +          logo: '../assets/img/p5js.svg',
            +          name: 'p5.js Developer Docs',
            +          repo: 'https://github.com/processing/p5.js',
            +        }
            +      </script>
            +      <script src="https://unpkg.com/docsify/lib/docsify.min.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/community/index.html b/dist/ko/community/index.html
            new file mode 100644
            index 0000000000..5f3a64fddf
            --- /dev/null
            +++ b/dist/ko/community/index.html
            @@ -0,0 +1,234 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content">
            +      <h1>커뮤니티</h1>
            +      <div class="community-statement">
            +        <h2 class="community-title">p5.js 커뮤니티 성명서 </h2>
            +        <p>p5.js는 기술을 재료삼아 예술과 디자인을 창작하는 커뮤니티입니다.
            +        </p>
            +
            +        <p>우리는 다양한 성 정체성, 젠더 표현, 성적 지향, 인종, 민족, 언어, 사회, 규모, 능력, 계급, 종교, 문화, 하위 문화, 정치 성향, 나이, 기술적 숙련도, 직업, 배경에 속한 사람들의 공동체이자 연대입니다. 모든 사람이 우리 커뮤니티에 시간과 에너지를 할애할 수 있는 게 아니라는 걸 인지하고 있습니다. 그만큼 우리는 여러분의 참여를 환영하고 독려하며, 접근성을 향상하기 위해 늘 노력합니다. 우리 모두는 언제나 배우는 자들입니다.
            +        </p>
            +
            +        <p>우리가 좋아하는 해시태그는 #noCodeSnobs(우리는 효율성보다 커뮤니티를 우선시합니다), #newKidLove(우리는 모두 한 때 입문자였으니깐요!), #unassumeCore(우리는 상대가 무엇을 알고 있는지에 대해 섣불리 가정하지 않습니다), and #BlackLivesMatter (말할 필요도 없이 중요한 사실이지요!) 입니다.
            +        </p>
            +
            +        <h3 id="in-practice">실천:</h3>
            +        <ul aria-labelledby="in-practice" class="bullets list_view">
            +          <li>우리는 '고고한' 개발자가 아닙니다. 상대가 이미 어떠한 것을 알고 있을거라 섣불리 가정하거나, 모든 사람이 반드시 알아야 할 지식이 있다고 생각하지 않습니다.  </li>
            +          <li>피드백이 필요한 경우, 언제든 적극적으로 응합니다. </li>
            +          <li>우리는 입문자를 환영하며 타인의 학습을 우선순위에 둡니다. 또, 우리는 모든 업무를 수행할 때 초심자 시절의 열정을 잃지 않습니다. 우리 커뮤니티에 있어 입문자는 숙련자만큼이나 중요한 가치를 더하는 존재입니다.  </li>
            +          <li>우리는 언제나 모든 형태의 기여, 공헌, 참여를 적극적으로 인정하고 인증하고자 합니다. </li>
            +          <li>우리는 언제나 기꺼이 도움과 안내를 제공합니다. </li>
            +        </ul>
            +
            +        <h3 id="in-conflict">갈등이 발생할 경우:</h3>
            +        <ul aria-labelledby="in-conflict" class="bullets list_view">
            +          <li>서로의 생각에 귀 기울입니다. </li>
            +          <li>명확한 의사소통을 하되, 타인의 감정을 생각합니다.</li>
            +          <li>우리가 잘못한 경우에는 그 잘못을 인정하고, 용서를 구하며, 행동에 대한 책임을 집니다. </li>
            +          <li>더 나은 우리 자신과 커뮤니티를 향해 지속적으로 노력합니다. </li>
            +          <li>서로 존중하며 개방된 자세를 유지합니다.  </li>
            +          <li>모든 사람의 의견을 존중하고 경청합니다. </li>
            +          <li>사려깊고 친절한 태도로 소통합니다. </li>
            +        </ul>
            +
            +        <h3 id="in-future">미래에 우리는: </h3>
            +        <ul aria-labelledby="in-future" class="bullets list_view">
            +          <li>지금이 바로 미래입니다.</li>
            +        </ul>
            +        <br>
            +        <h3 id="notes" class='sr-only'>유의사항</h3>
            +        <p>Please also visit our  <a href="https://github.com/processing/p5.js/blob/main/CODE_OF_CONDUCT.md#p5js-code-of-conduct">p5.js 행동 강령</a>을 참고하세요. p5.js 커뮤니티 성명서는 <a href="https://creativecommons.org/licenses/by-sa/4.0/">크리에이티브 커먼즈 라이선스(CC)</a>에 따라 라이선스가 부여됩니다. 크레딧과 함께 자유로이 공유하고 응용할 수 있습니다.</p>
            +      </div>
            +
            +      <h2 id="contribute">기여하기</h2>
            +      <p>우리 커뮤니티는 다양한 방법으로 도움을 줄 수 있는 열정가 분들을 항시 찾고 있습니다. </p>
            +
            +      <p><b>개발: </b> <a href="https://github.com/processing/p5.js" target="blank_">GitHub</a>는 코드, 버그와 에러, 개발 이슈 등이 문서화되며, 관련 논의가 진행되는 곳입니다. p5.js 개발에 기여하려면 <a href="https://p5js.org/contributor-docs" target="blank_"> 개발 튜토리얼 </a> 을 참고하거나,  <a href="../libraries/#create-your-own"> 라이브러리를 제작해보세요. </a></p>
            +
            +      <p><b>문서화: </b>문서화 작업은 너무나도 소중하지요! 현재 도움이 필요한 부분으로는 <a href="https://github.com/processing/p5.js-website/blob/main/contributor_docs/Adding_examples.md" target="blank_">예제 이전하기</a>,<a href="https://p5js.org/contributor-docs/#/inline_documentation" target="blank_"> 문서 추가하기</a>, 그리고 튜토리얼 제작이 있습니다.</p>
            +
            +      <p><b>가르치기: </b> 워크샵이나 수업을 통해 친구, 협업자에게 p5.js를 가르치는 것도 좋은 기여 방법입니다. 트위터에서 @p5xjs를 태그해주시면 여러분의 프로젝트를 공유할게요.</p>
            +
            +      <p><b>창작하기: </b> p5.js는 사용자들에게 영감을 줄 수 있는 프로젝트를 웹사이트 첫 페이지에 게재합니다. 디자이너, 예술가, 개발자, 프로그래머, 그 누구의 작업도 좋습니다! 여러분이 만든 창의적인 프로젝트를 다음의 메일 주소로 제출해보세요: <a href="mailto:hello@p5js.org">hello@p5js.org</a>.</p>
            +
            +      <p><b>함께하기: </b> p5.js는 예술가들이 만든 무료 오픈 소스입니다. <a href="https://processingfoundation.org/support">프로세싱 재단</a> 기부를 통해 p5.js를 후원해주세요!</p>
            +
            +
            +      <h2>p5.js 공헌자 컨퍼런스</h2>
            +      <p>대부분의 커뮤니티 활동은 온라인에서 진행되지만, 오프라인에서도 일어난답니다! 그동안 두 차례의 공헌자 컨퍼런스가 있었는데요, 미국 피츠버그 소재 카네기 멜론 대학교(Carnegie Mellon University)의 <a href="http://studioforcreativeinquiry.org">Frank-Ratchye STUDIO for Creative Inquiry</a> 에서 진행된 것이 그 중 하나입니다. 예술가, 디자이너, 개발자, 교육자들이 모여 p5.js의 개선 방향에 대해 논의하였습니다.
            +      </p>
            +      <h2 id="conferences" class="sr-only">Past Conferences</h2>
            +      <ul aria-labelledby="conferences" class="list_view bullets">
            +        <li><a href="contributors-conference-2019.html">2019년 공헌자 컨퍼런스</a></li>
            +        <li><a href="contributors-conference-2015.html">2015년 공헌자 컨퍼런스</a></li>
            +      </ul>
            +
            +      <img src="../../assets/img/community/2015_12.jpg" alt='노트북으로 작업하는 참여자들이 있는 교실 전경"'/>
            +
            +      <h2>소식지 받기</h2>
            +      <div class="email-octopus-form-wrapper">
            +        <p class="email-octopus-success-message"></p>
            +        <p class="email-octopus-error-message"></p>
            +        <form method="post" action="https://emailoctopus.com/lists/537b6ec8-d123-11e6-8561-06ead731d453/members/external-add" class="email-octopus-form">
            +          <p>프로세싱 재단의 정기 소식을 수신하려면 이메일 주소를 입력하세요.</p>
            +          <div class="email-octopus-form-row">
            +            <input type="email" name="emailAddress" placeholder="email" class="email-octopus-email-address">
            +            <button type="submit">subscribe</button>
            +          </div>
            +          <div class="email-octopus-form-row-hp" aria-hidden="true">
            +            <input type="text" name="hp537b6ec8-d123-11e6-8561-06ead731d453" tabindex="-1">
            +          </div>
            +          <div class="email-octopus-form-row-subscribe">
            +            <input type="hidden" name="successRedirectUrl" class="email-octopus-success-redirect-url" value="">
            +          </div>
            +        </form>
            +      </div>
            +      <script src="https://emailoctopus.com/bundles/emailoctopuslist/js/formEmbed.js"></script>
            +      <br><br>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/copyright.html b/dist/ko/copyright.html
            new file mode 100644
            index 0000000000..512dc3f35a
            --- /dev/null
            +++ b/dist/ko/copyright.html
            @@ -0,0 +1,154 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">copyright | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>저작권</h1>
            +      <p>p5.js 라이브러리는 무료 소프트웨어입니다.<a href="https://github.com/processing/p5.js/blob/main/license.txt">GNU Lesser General 
            +      Public License</a> 자유 소프트웨어 재단(Free Software Foundation)의 조항(version 2.1.)에 따라 재배포 및 수정할 수 있습니다.</p>
            +      <p>p5.js의 레퍼런스는 <a href='http://creativecommons.org/licenses/by-nc-sa/4.0/'>Creative Commons</a> 라이선스에 속하며, 크레딧 인용시 비영리 목적을 위해 재사용할 수 있습니다.</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/download/index.html b/dist/ko/download/index.html
            new file mode 100644
            index 0000000000..c72d5c5ace
            --- /dev/null
            +++ b/dist/ko/download/index.html
            @@ -0,0 +1,272 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>다운로드</h1>
            +
            +      <h2 class='sr-only'>Introduction</h2>
            +      <p>안녕하세요! 이 페이지는 온라인에서 바로 사용가능한 웹에디터와 각종 다운로드 링크를 소개합니다. 입문자에게 꼭 필요한 자료부터 숙련된 개발자를 위한 리소스 모두를 포괄합니다.</p>
            +
            +      <!-- EDITOR -->
            +      <div class="link_group">
            +        <h2>에디터</h2>
            +        <p>아래의 링크는 온라인 p5.js 에디터로 연결됩니다.</p>
            +
            +        <a class='support_link' href="https://editor.p5js.org" target="_blank">
            +          <div class="download_box">
            +
            +            <span class="download_name">p5.js 에디터</span>
            +            <p>별도 설치가 필요없는 p5.js 웹에디터로 지금 바로 코딩을 시작해보세요!</p>
            +
            +          </div>
            +        </a>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- COMPLETE LIBRARY -->
            +      <div class="link_group">
            +        <h2>모든 라이브러리</h2>
            +        <p>아래의 링크는 p5.js 라이브러리 파일, p5.sound, 그리고 예제 프로젝트를 포함합니다.  <a href="/ko/get-started/">시작하기</a>에서 p5.js 프로젝트 설정 방법을 알아보세요.</p>
            +
            +        <a  class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.zip">
            +          <div class="download_box">
            +
            +            <span class="download_name">모든 라이브러리</span>
            +            <p>포함 사항:
            +              <br>p5.js, p5.sound.js, 예시 프로젝트 1개
            +            <br>Version  <span id="p5_version"></span> (<span id="p5_date"></span>)
            +            </p>
            +
            +          </div>
            +        </a>
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- SINGLE FILES -->
            +      <div class="link_group">
            +
            +        <h2 id="single-files">개별 라이브러리</h2>
            +        <p>개별 라이브러리 파일입니다. </p>
            +        <ul aria-labelledby="single-files">
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.js</span>
            +                <p>개별 라이브러리: 
            +                  <br>개별 파일</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.min.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.min.js</span>
            +                <p>개별 라이브러리: 
            +                  <br>압축 버전</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://cdnjs.com/libraries/p5.js" target="_blank">
            +              <div class="download_box half_box last_box">
            +                <span class="download_name">CDN</span>
            +                <p>링크: 
            +                  <br>정적 호스팅 파일</p>
            +              </div>
            +            </a>
            +          </li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +
            +      </div>
            +
            +      <!-- Github resources -->
            +      <div class="link_group">
            +        <h2 id="etc">Github 리소스</h2>
            +        <ul aria-labelledby="etc" id='etc_list' class="list_view bullets">
            +          <li><a href="https://github.com/processing/p5.js/releases">이전 버전 (구버전 및 업데이트 기록)</a></li>
            +          <li><a href="https://github.com/processing/p5.js">코드 저장소 (GitHub)</a></li>
            +          <li><a href="https://github.com/processing/p5.js/issues">이슈, 버그, 에러 보고하기</a></li>
            +          <li><a href="https://github.com/processing/p5.js/blob/main/contributor_docs/supported_browsers.md">지원 브라우저 </a></li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +    </main>
            +
            +    <script>
            +      $.getJSON('/download/version.json', function(data) {
            +        $('#p5_version').text(data.version);
            +        $('#p5_date').text(data.date);
            +        $('.p5_link').each(function() {
            +          var link = $(this).attr('href').replace('[p5_version]', data.version);
            +          $(this).attr('href', link);
            +        });
            +        $('.editor_version').text(data.editor_version);
            +        $('.editor_link').each(function() {
            +          var link = $(this).attr('href').replace('[editor_version]', data.editor_version);
            +          $(this).attr('href', link);
            +        });
            +      });
            +      $('.support_link').on('click', function (e) {
            +        if ($(this).hasClass('p5_link')) {
            +          e.preventDefault();
            +          window.location = $(this).attr('href');
            +          setTimeout( function() { window.location = 'support.html'; }, 10000);
            +        } else {
            +          setTimeout( function() { window.location = 'support.html'; }, 1000);
            +        }
            +
            +      });
            +
            +    </script>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/download/support.html b/dist/ko/download/support.html
            new file mode 100644
            index 0000000000..f49c4b267d
            --- /dev/null
            +++ b/dist/ko/download/support.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>p5.js를 후원해주세요!</h1>
            +
            +      <p>여러분의 도움이 필요합니다! p5.js는 무상의 오픈소스 소프트웨어입니다. 우리는 누구에게나 열려있고 포용적인 커뮤니티를 지향하며, 여러분도 p5.js를 지원하는 프로세싱 재단(<a href="https://processingfoundation.org/support/">Processing Foundation</a>)에 후원을 통해 이에 동참할 수 있습니다. 여러분의 소중한 후원금은 p5.js 소프트웨어 개발과 더불어 코드 예제 및 튜토리얼을 비롯한 교육 자료 제작에 쓰입니다. 또한, 다음과 같은 커뮤니티 활동을 위해서도 쓰입니다 :  <a href="https://processingfoundation.org/fellowships">펠로우십</a>, <a href="https://processingfoundation.org/advocacy">커뮤니티 행사.</a></p>
            +      <script src="https://donorbox.org/widget.js" paypalExpress="true"></script><iframe allowpaymentrequest="" height="900" name="donorbox" src="https://donorbox.org/embed/support-the-processing-foundation?hide_donation_meter=true" style="max-width: 500px; min-width: 250px; max-height:none!important; margin-top: 1em" ></iframe>
            +      
            +      <p><a href="https://processingfoundation.org">프로세싱 재단</a>은 10여년 간의 프로세싱 소프트웨어(Processing Software) 개발 활동을 거쳐 2012년에 설립되었습니다. 프로세싱 재단의 사명은 시각 예술계에서의 소프트웨어 리터러시 및 기술 관련 분야에서의 시각적 리터러시를 증진하고, 나아가 이 두 분야에 대한 보다 많은 사람들의 접근성을 향상하는 데에 있습니다. 우리는 다양한 이해 관계와 배경을 가진 사람들, 특히 코딩 학습 툴이나 자원에 대한 접근성이 없는 이들의 크리에이티브 코딩 교육을 돕는 것을 목표로 삼습니다.</p>
            +
            +      <div id="slideshow">
            +        <div>
            +          <img src="../../assets/img/download/p5js-5939.jpg" alt="support-17-alt">
            +          <p>미국 피츠버그 CMU STUDIO for Creative Inquiry에서 진행된 p5.js 공헌자 컨퍼런스 (이미지 저작권: 최태윤)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/saskia-project.jpg" alt="support-18-alt">
            +          <p>프로세싱 재단 펠로우 Saskia Freeke이 런던에서 주관한 Liberation x Processing workshops (이미지 저작권: Code Liberation Foundation)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/LearningToTeach45-small.jpg" alt="support-19-alt">
            +          <p>SPFC와 함께한 Learning to Teach, Teaching to Learn 컨퍼런스 (이미지 저작권: Kira Simon-Kennedy)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/Cassie_CodeMiami0.png" alt="support-20-alt">
            +          <p>프로세싱 재단 펠로우 Cassie Tarakajian가 Code Art Miami에서 진행한 워크숍 (이미지 저작권: Christian Arévalo Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders2.jpg" alt="support-21-alt">
            +          <p>Signing Coders p5.js workshop에서의 최태윤과 미국 수어(ASL) 해설자 (이미지 저작권: 최태윤)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/gsoc_kickoff.jpg" alt="support-22-alt">
            +          <p>구글 썸머 오브 코드(Google Summer of Code) 킥오프 행사 (이미지 저작권: 최태윤)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/Cassie_CodeMiami5.png" alt="support-23-alt">
            +          <p>프로세싱 재단 펠로우 Cassie Tarakajian가 Code Art Miami에서 진행한 워크숍 (이미지 저작권: Christian Arévalo Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders0.jpg" alt="support-24-alt">
            +          <p>최태윤의 수어 기반 p5.js workshop에서 진행을 돕는 Luisa Pereira와 송예슬 (이미지 저작권: 최태윤)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/conf2.jpg" alt="support-25-alt">
            +          <p>미국 피츠버그 CMU STUDIO for Creative Inquiry에서 진행된 p5.js 공헌자 컨퍼런스 (이미지 저작권: 최태윤)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/digitalcitizens-panel3.png" alt="support-26-alt">
            +          <p>프로세싱 재단 펠로우 Digital Citizens Lab가 International Center of Photography에서 주최한 STEM 교육 패널 (이미지 저작권: International Center of Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/aaron.jpg" alt="support-27-alt">
            +          <p>칠레 산티아고에서 Aarón Montoya-Moraga가 진행한 p5.js workshop (이미지 저작권: Aarón Montoya-Moraga.)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders3.jpg" alt="support-28-alt">
            +          <p>최태윤의 수어 기반 p5.js workshop에서 진행을 돕는 Claire Kearney-Volpe (이미지 저작권: 최태윤)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/diygirls1.jpg" alt="support-29-alt">
            +          <p>프로세싱 재단 펠로우 DIY Girls가 미국 로스 엔젤레스(Los Angeles)에서 진행한 크리에이티브 코딩 프로그램 (이미지 저작권: DIY Girls)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/digitalcitizens7.jpg" alt="support-30-alt">
            +          <p>프로세싱 재단 펠로우 Digital Citizens Lab</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/p5-coast2coast.jpg" alt="support-31-alt">
            +          <p>UCLA DMA와 NYU ITP 간의 동서-해안 p5.js 모임</p>
            +        </div>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<script src="../../assets/js/slideshow.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/examples/index.html b/dist/ko/examples/index.html
            new file mode 100644
            index 0000000000..c10239ae9f
            --- /dev/null
            +++ b/dist/ko/examples/index.html
            @@ -0,0 +1,3381 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">examples | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="examples-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>예제</h1>
            +
            +      <div class="column_0 column">
            +      
            +        <h3 name='structure' class='anchor'>구조</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="structure-comments-and-statements
            .html"
            +            
            +                data-en='Comments/Statements
            '
            +            
            +                data-es='Comments and Statements
            '
            +            
            +                data-hi='निर्देशांक
            '
            +            
            +                data-ko='스테이트멘트와 코멘트
            '
            +            
            +                data-zh-Hans='Comments and Statements
            '
            +            
            +          >Comments/Statements
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-coordinates
            .html"
            +            
            +                data-en='Coordinates
            '
            +            
            +                data-es='Coordenadas
            '
            +            
            +                data-hi='चौड़ाई और ऊंचाई
            '
            +            
            +                data-ko='좌표
            '
            +            
            +                data-zh-Hans='坐标
            '
            +            
            +          >Coordinates
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-width-and-height
            .html"
            +            
            +                data-en='Width/Height
            '
            +            
            +                data-es='width y height
            '
            +            
            +                data-hi='सेटअप और ड्रा
            '
            +            
            +                data-ko='너비와 높이
            '
            +            
            +                data-zh-Hans='Width 和 Height
            '
            +            
            +          >Width/Height
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-setup-and-draw
            .html"
            +            
            +                data-en='Setup/Draw
            '
            +            
            +                data-es='Setup y Draw
            '
            +            
            +                data-hi='और ड्रा
            '
            +            
            +                data-ko='설정하고 그리기
            '
            +            
            +                data-zh-Hans='Setup 与 Draw
            '
            +            
            +          >Setup/Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-no-loop
            .html"
            +            
            +                data-en='No Loop
            '
            +            
            +                data-es='No Loop
            '
            +            
            +                data-hi='लूप
            '
            +            
            +                data-ko='루프 중단
            '
            +            
            +                data-zh-Hans='No Loop
            '
            +            
            +          >No Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-loop
            .html"
            +            
            +                data-en='Loop
            '
            +            
            +                data-es='Bucle
            '
            +            
            +                data-hi='रेड्रा
            '
            +            
            +                data-ko='루프
            '
            +            
            +                data-zh-Hans='Loop
            '
            +            
            +          >Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-redraw
            .html"
            +            
            +                data-en='Redraw
            '
            +            
            +                data-es='Redraw
            '
            +            
            +                data-hi='कार्य
            '
            +            
            +                data-ko='다시 그리기
            '
            +            
            +                data-zh-Hans='Redraw
            '
            +            
            +          >Redraw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-functions
            .html"
            +            
            +                data-en='Functions
            '
            +            
            +                data-es='Funciones
            '
            +            
            +                data-hi='रिकर्सन
            '
            +            
            +                data-ko='그 외 함수들
            '
            +            
            +                data-zh-Hans='函数
            '
            +            
            +          >Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-recursion
            .html"
            +            
            +                data-en='Recursion
            '
            +            
            +                data-es='Recursión
            '
            +            
            +                data-hi='ग्राफिक्स बनाएं
            '
            +            
            +                data-ko='재귀 함수
            '
            +            
            +                data-zh-Hans='递归
            '
            +            
            +          >Recursion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-create-graphics
            .html"
            +            
            +                data-en='Create Graphics
            '
            +            
            +                data-es='createGraphics
            '
            +            
            +                data-ko='그래픽 만들기
            '
            +            
            +                data-zh-Hans='Create Graphics
            '
            +            
            +          >Create Graphics
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='form' class='anchor'>도형</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="form-points-and-lines
            .html"
            +            
            +                data-en='Points/Lines
            '
            +            
            +                data-es='Puntos y líneas
            '
            +            
            +                data-hi='अंक और रेखाएं
            '
            +            
            +                data-ko='점과 선
            '
            +            
            +                data-zh-Hans='Points 与 Lines
            '
            +            
            +          >Points/Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-shape-primitives
            .html"
            +            
            +                data-en='Shape Primitives
            '
            +            
            +                data-es='Figuras primitivas
            '
            +            
            +                data-hi='शेप प्रिमिटिव्स
            '
            +            
            +                data-ko='기본 조형
            '
            +            
            +                data-zh-Hans='基本形状
            '
            +            
            +          >Shape Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-pie-chart
            .html"
            +            
            +                data-en='Pie Chart
            '
            +            
            +                data-es='Gráfico de sectores
            '
            +            
            +                data-hi='पाई चार्ट
            '
            +            
            +                data-ko='파이형 차트
            '
            +            
            +                data-zh-Hans='饼状图
            '
            +            
            +          >Pie Chart
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-regular-polygon
            .html"
            +            
            +                data-en='Regular Polygon
            '
            +            
            +                data-es='Polígono regular
            '
            +            
            +                data-hi='नियमित बहुभुज
            '
            +            
            +                data-ko='정다각형
            '
            +            
            +                data-zh-Hans='正多边形
            '
            +            
            +          >Regular Polygon
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-star
            .html"
            +            
            +                data-en='Star
            '
            +            
            +                data-es='Estrella
            '
            +            
            +                data-hi='स्टार
            '
            +            
            +                data-ko='별모양
            '
            +            
            +                data-zh-Hans='Star
            '
            +            
            +          >Star
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-triangle-strip
            .html"
            +            
            +                data-en='Triangle Strip
            '
            +            
            +                data-es='Tira de triángulos
            '
            +            
            +                data-hi='त्रिभुज पट्टी
            '
            +            
            +                data-ko='삼각형 고리
            '
            +            
            +                data-zh-Hans='Triangle Strip
            '
            +            
            +          >Triangle Strip
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-bezier
            .html"
            +            
            +                data-en='Bezier
            '
            +            
            +                data-es='Bezier
            '
            +            
            +                data-hi='बेज़ियर
            '
            +            
            +                data-ko='베지어 곡선
            '
            +            
            +                data-zh-Hans='Bezier
            '
            +            
            +          >Bezier
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-3d-primitives
            .html"
            +            
            +                data-en='3D Primitives
            '
            +            
            +                data-es='Primitivas 3D
            '
            +            
            +                data-hi='३डी प्रिमिटिव्स
            '
            +            
            +                data-ko='3D 기본 조형
            '
            +            
            +                data-zh-Hans='基本 3D 形状
            '
            +            
            +          >3D Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-trig-wheels-and-pie-chart
            .html"
            +            
            +                data-en='Trig Wheels/Pie Chart
            '
            +            
            +                data-es='Trig Wheels and Pie Chart
            '
            +            
            +                data-ko='단위원과 파이 차트
            '
            +            
            +                data-zh-Hans='Trig Wheels and Pie Chart
            '
            +            
            +          >Trig Wheels/Pie Chart
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='data' class='anchor'>데이터</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="data-variables
            .html"
            +            
            +                data-en='Variables
            '
            +            
            +                data-es='Variables
            '
            +            
            +                data-hi='चर
            '
            +            
            +                data-ko='변수
            '
            +            
            +                data-zh-Hans='变量
            '
            +            
            +          >Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-true-and-false
            .html"
            +            
            +                data-en='True/False
            '
            +            
            +                data-es='True y False
            '
            +            
            +                data-hi='सही और गलत
            '
            +            
            +                data-ko='참과 거짓
            '
            +            
            +                data-zh-Hans='True 和 False
            '
            +            
            +          >True/False
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-variable-scope
            .html"
            +            
            +                data-en='Variable Scope
            '
            +            
            +                data-es='Alcance de variabless
            '
            +            
            +                data-hi='परिवर्तनीय दायरा
            '
            +            
            +                data-ko='변수 범위
            '
            +            
            +                data-zh-Hans='变量范围
            '
            +            
            +          >Variable Scope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-numbers
            .html"
            +            
            +                data-en='Numbers
            '
            +            
            +                data-es='Números
            '
            +            
            +                data-hi='नंबर
            '
            +            
            +                data-ko='숫자값
            '
            +            
            +                data-zh-Hans='Numbers
            '
            +            
            +          >Numbers
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='arrays' class='anchor'>배열</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="arrays-array
            .html"
            +            
            +                data-en='Array
            '
            +            
            +                data-es='Arreglo
            '
            +            
            +                data-hi='ऐरे
            '
            +            
            +                data-ko='배열
            '
            +            
            +                data-zh-Hans='数组
            '
            +            
            +          >Array
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-2d
            .html"
            +            
            +                data-en='Array 2D
            '
            +            
            +                data-es='Arreglo 2D
            '
            +            
            +                data-hi='ऐरे 2D
            '
            +            
            +                data-ko='2D 배열
            '
            +            
            +                data-zh-Hans='2D 数组
            '
            +            
            +          >Array 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-objects
            .html"
            +            
            +                data-en='Array Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='ऐरे ऑब्जेक्ट्स
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='数组对象
            '
            +            
            +          >Array Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-walk-over-2darray
            .html"
            +            
            +                data-en='Walk Over 2dArray
            '
            +            
            +                data-es='Walk Over 2dArray
            '
            +            
            +                data-ko='Walk Over 2dArray
            '
            +            
            +                data-zh-Hans='Walk Over 2dArray
            '
            +            
            +          >Walk Over 2dArray
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='control' class='anchor'>컨트롤</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="control-iteration
            .html"
            +            
            +                data-en='Iteration
            '
            +            
            +                data-es='Iteración
            '
            +            
            +                data-hi='पुनरावृत्ति
            '
            +            
            +                data-ko='for 반복문
            '
            +            
            +                data-zh-Hans='迭代
            '
            +            
            +          >Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-embedded-iteration
            .html"
            +            
            +                data-en='Embedded Iteration
            '
            +            
            +                data-es='Iteración anidada
            '
            +            
            +                data-hi='एंबेडेड इटरेशन
            '
            +            
            +                data-ko='for 내장 반복문
            '
            +            
            +                data-zh-Hans='嵌入式迭代
            '
            +            
            +          >Embedded Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-1
            .html"
            +            
            +                data-en='Conditionals 1
            '
            +            
            +                data-es='Condicionales 1
            '
            +            
            +                data-hi='सशर्त 1
            '
            +            
            +                data-ko='조건문 1
            '
            +            
            +                data-zh-Hans='条件 1
            '
            +            
            +          >Conditionals 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-2
            .html"
            +            
            +                data-en='Conditionals 2
            '
            +            
            +                data-es='Condicionales 2
            '
            +            
            +                data-hi='सशर्त 2
            '
            +            
            +                data-ko='조건문 2
            '
            +            
            +                data-zh-Hans='条件 2
            '
            +            
            +          >Conditionals 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators
            .html"
            +            
            +                data-en='Logical Operators
            '
            +            
            +                data-es='Operadores lógicos
            '
            +            
            +                data-hi='लॉजिकल ऑपरेटर्स
            '
            +            
            +                data-ko='논리적 연산자
            '
            +            
            +                data-zh-Hans='逻辑操作符
            '
            +            
            +          >Logical Operators
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators-2
            .html"
            +            
            +                data-en='Logical Operators 2
            '
            +            
            +                data-es='Logical Operators 2
            '
            +            
            +                data-ko='Logical Operators 2
            '
            +            
            +                data-zh-Hans='Logical Operators 2
            '
            +            
            +          >Logical Operators 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditional-shapes
            .html"
            +            
            +                data-en='Conditional Shapes
            '
            +            
            +                data-es='Conditional Shapes
            '
            +            
            +                data-ko='Conditional Shapes
            '
            +            
            +                data-zh-Hans='Conditional Shapes
            '
            +            
            +          >Conditional Shapes
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='image' class='anchor'>이미지</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="image-load-and-display-image
            .html"
            +            
            +                data-en='Load/Display Image
            '
            +            
            +                data-es='Cargar y mostrar imagen
            '
            +            
            +                data-hi='लोड और डिस्प्ले इमेज
            '
            +            
            +                data-ko='이미지 불러오기 및 보이기
            '
            +            
            +                data-zh-Hans='加载(Load)和显示(Display)图像
            '
            +            
            +          >Load/Display Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-background-image
            .html"
            +            
            +                data-en='Background Image
            '
            +            
            +                data-es='Imagen de fondo
            '
            +            
            +                data-hi='पृष्ठभूमि छवि
            '
            +            
            +                data-ko='배경 이미지
            '
            +            
            +                data-zh-Hans='背景图像
            '
            +            
            +          >Background Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-transparency
            .html"
            +            
            +                data-en='Transparency
            '
            +            
            +                data-es='Transparencia
            '
            +            
            +                data-hi='पारदर्शिता
            '
            +            
            +                data-ko='투명도
            '
            +            
            +                data-zh-Hans='透明度
            '
            +            
            +          >Transparency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-alpha-mask
            .html"
            +            
            +                data-en='Alpha Mask
            '
            +            
            +                data-es='Alpha Mask
            '
            +            
            +                data-hi='अल्फा मास्क
            '
            +            
            +                data-ko='알파 마스크
            '
            +            
            +                data-zh-Hans='透明度遮罩 (Alpha Mask)
            '
            +            
            +          >Alpha Mask
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-create-image
            .html"
            +            
            +                data-en='Create Image
            '
            +            
            +                data-es='Crear una imagen
            '
            +            
            +                data-hi='इमेज बनाएं
            '
            +            
            +                data-ko='이미지 만들기
            '
            +            
            +                data-zh-Hans='创建图像
            '
            +            
            +          >Create Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-pointillism
            .html"
            +            
            +                data-en='Pointillism
            '
            +            
            +                data-es='Puntillismo
            '
            +            
            +                data-hi='पॉइंटिलिज्म
            '
            +            
            +                data-ko='점묘법
            '
            +            
            +                data-zh-Hans='点画(Pointillism)
            '
            +            
            +          >Pointillism
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-blur
            .html"
            +            
            +                data-en='Blur
            '
            +            
            +                data-es='Blur
            '
            +            
            +                data-ko='Blur
            '
            +            
            +                data-zh-Hans='Blur
            '
            +            
            +          >Blur
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-edge-detection
            .html"
            +            
            +                data-en='Edge Detection
            '
            +            
            +                data-es='Edge Detection
            '
            +            
            +                data-ko='Edge Detection
            '
            +            
            +                data-zh-Hans='Edge Detection
            '
            +            
            +          >Edge Detection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brightness
            '
            +            
            +                data-ko='Brightness
            '
            +            
            +                data-zh-Hans='Brightness
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-convolution
            .html"
            +            
            +                data-en='Convolution
            '
            +            
            +                data-es='Convolution
            '
            +            
            +                data-ko='Convolution
            '
            +            
            +                data-zh-Hans='Convolution
            '
            +            
            +          >Convolution
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-copy-method
            .html"
            +            
            +                data-en='Copy() method
            '
            +            
            +                data-es='Método copy()
            '
            +            
            +                data-ko='Copy() method
            '
            +            
            +                data-zh-Hans='Copy() 函数
            '
            +            
            +          >Copy() method
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='color' class='anchor'>색상</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="color-hue
            .html"
            +            
            +                data-en='Hue
            '
            +            
            +                data-es='Tinte
            '
            +            
            +                data-hi='ह्यू
            '
            +            
            +                data-ko='색조
            '
            +            
            +                data-zh-Hans='色调
            '
            +            
            +          >Hue
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-saturation
            .html"
            +            
            +                data-en='Saturation
            '
            +            
            +                data-es='Saturación
            '
            +            
            +                data-hi='संतृप्ति
            '
            +            
            +                data-ko='채도
            '
            +            
            +                data-zh-Hans='饱和度
            '
            +            
            +          >Saturation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brillo
            '
            +            
            +                data-hi='चमक
            '
            +            
            +                data-ko='밝기
            '
            +            
            +                data-zh-Hans='亮度
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-color-variables
            .html"
            +            
            +                data-en='Color Variables
            '
            +            
            +                data-es='Variables de color
            '
            +            
            +                data-hi='रंग चर
            '
            +            
            +                data-ko='색상 변수
            '
            +            
            +                data-zh-Hans='颜色变量
            '
            +            
            +          >Color Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-relativity
            .html"
            +            
            +                data-en='Relativity
            '
            +            
            +                data-es='Relatividad
            '
            +            
            +                data-hi='सापेक्षता
            '
            +            
            +                data-ko='상대성
            '
            +            
            +                data-zh-Hans='相对性
            '
            +            
            +          >Relativity
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-linear-gradient
            .html"
            +            
            +                data-en='Linear Gradient
            '
            +            
            +                data-es='Gradiente linear
            '
            +            
            +                data-hi='रैखिक ढाल
            '
            +            
            +                data-ko='선형 그래디언트
            '
            +            
            +                data-zh-Hans='线性渐变
            '
            +            
            +          >Linear Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-radial-gradient
            .html"
            +            
            +                data-en='Radial Gradient
            '
            +            
            +                data-es='Gradiente radial
            '
            +            
            +                data-hi='रेडियल ग्रेडिएंट
            '
            +            
            +                data-ko='방사형 그래디언트
            '
            +            
            +                data-zh-Hans='径向渐变
            '
            +            
            +          >Radial Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-lerp-color
            .html"
            +            
            +                data-en='Lerp Color
            '
            +            
            +                data-es='Interpolación de color
            '
            +            
            +                data-hi='Lerp Color
            '
            +            
            +                data-ko='선형 보간(lerp) 색상
            '
            +            
            +                data-zh-Hans='插值颜色
            '
            +            
            +          >Lerp Color
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='math' class='anchor'>수학</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="math-increment-decrement
            .html"
            +            
            +                data-en='Increment Decrement
            '
            +            
            +                data-es='Incremento y decremento
            '
            +            
            +                data-hi='वेतन वृद्धि
            '
            +            
            +                data-ko='증가와 감소
            '
            +            
            +                data-zh-Hans='增量/减量
            '
            +            
            +          >Increment Decrement
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-operator-precedence
            .html"
            +            
            +                data-en='Operator Precedence
            '
            +            
            +                data-es='Precedencia de operadores
            '
            +            
            +                data-hi='ऑपरेटर वरीयता
            '
            +            
            +                data-ko='연산자 우선 순위
            '
            +            
            +                data-zh-Hans='操作符优先级
            '
            +            
            +          >Operator Precedence
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-1d
            .html"
            +            
            +                data-en='Distance 1D
            '
            +            
            +                data-es='Distancia 1D
            '
            +            
            +                data-hi='दूरी 1डी
            '
            +            
            +                data-ko='1D 거리
            '
            +            
            +                data-zh-Hans='一维间距
            '
            +            
            +          >Distance 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-2d
            .html"
            +            
            +                data-en='Distance 2D
            '
            +            
            +                data-es='Distancia 2D
            '
            +            
            +                data-hi='दूरी 2डी
            '
            +            
            +                data-ko='2D 거리
            '
            +            
            +                data-zh-Hans='二维间距
            '
            +            
            +          >Distance 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine
            .html"
            +            
            +                data-en='Sine
            '
            +            
            +                data-es='Seno
            '
            +            
            +                data-hi='साइन
            '
            +            
            +                data-ko='사인
            '
            +            
            +                data-zh-Hans='正弦
            '
            +            
            +          >Sine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-cosine
            .html"
            +            
            +                data-en='Sine Cosine
            '
            +            
            +                data-es='Seno y coseno
            '
            +            
            +                data-hi='साइन कोसाइन
            '
            +            
            +                data-ko='사인 코사인
            '
            +            
            +                data-zh-Hans='正弦余弦
            '
            +            
            +          >Sine Cosine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-wave
            .html"
            +            
            +                data-en='Sine Wave
            '
            +            
            +                data-es='Onda sinusoidal
            '
            +            
            +                data-hi='साइन वेव
            '
            +            
            +                data-ko='사인파
            '
            +            
            +                data-zh-Hans='正弦波
            '
            +            
            +          >Sine Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-additive-wave
            .html"
            +            
            +                data-en='Additive Wave
            '
            +            
            +                data-es='Onda aditiva
            '
            +            
            +                data-hi='Additive Wave
            '
            +            
            +                data-ko='파형 추가
            '
            +            
            +                data-zh-Hans='加性波
            '
            +            
            +          >Additive Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-polartocartesian
            .html"
            +            
            +                data-en='PolarToCartesian
            '
            +            
            +                data-es='Polar a cartesiano
            '
            +            
            +                data-hi='PolarToCartesian
            '
            +            
            +                data-ko='극좌표를 직교 좌표로
            '
            +            
            +                data-zh-Hans='PolarToCartesian
            '
            +            
            +          >PolarToCartesian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-arctangent
            .html"
            +            
            +                data-en='Arctangent
            '
            +            
            +                data-es='Arcotangente
            '
            +            
            +                data-hi='आर्कटिक
            '
            +            
            +                data-ko='아크탄젠트
            '
            +            
            +                data-zh-Hans='反正切
            '
            +            
            +          >Arctangent
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-linear-interpolation
            .html"
            +            
            +                data-en='Linear Interpolation
            '
            +            
            +                data-es='Interpolación Lineal
            '
            +            
            +                data-hi='रैखिक इंटरपोलेशन
            '
            +            
            +                data-ko='선형 보간법
            '
            +            
            +                data-zh-Hans='线性插值
            '
            +            
            +          >Linear Interpolation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-double-random
            .html"
            +            
            +                data-en='Double Random
            '
            +            
            +                data-es='Doble aleatorio
            '
            +            
            +                data-hi='डबल रैंडम
            '
            +            
            +                data-ko='이중 랜덤
            '
            +            
            +                data-zh-Hans='双重随机
            '
            +            
            +          >Double Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random
            .html"
            +            
            +                data-en='Random
            '
            +            
            +                data-es='Aleatorio
            '
            +            
            +                data-hi='रैंडम
            '
            +            
            +                data-ko='랜덤
            '
            +            
            +                data-zh-Hans='随机
            '
            +            
            +          >Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise1d
            .html"
            +            
            +                data-en='Noise1D
            '
            +            
            +                data-es='Ruido 1D
            '
            +            
            +                data-hi='Noise1D
            '
            +            
            +                data-ko='1D 노이즈
            '
            +            
            +                data-zh-Hans='一维噪声 (Noise1D)
            '
            +            
            +          >Noise1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise-wave
            .html"
            +            
            +                data-en='Noise Wave
            '
            +            
            +                data-es='Onda de ruido
            '
            +            
            +                data-hi='शोर लहर
            '
            +            
            +                data-ko='노이즈 파형
            '
            +            
            +                data-zh-Hans='噪声波
            '
            +            
            +          >Noise Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise2d
            .html"
            +            
            +                data-en='Noise2D
            '
            +            
            +                data-es='Ruido 2D
            '
            +            
            +                data-hi='Noise2D
            '
            +            
            +                data-ko='2D 노이즈
            '
            +            
            +                data-zh-Hans='二维噪声 (Noise2D)
            '
            +            
            +          >Noise2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise3d
            .html"
            +            
            +                data-en='Noise3D
            '
            +            
            +                data-es='Ruido 3D
            '
            +            
            +                data-hi='Noise3D
            '
            +            
            +                data-ko='3D 노이즈
            '
            +            
            +                data-zh-Hans='三维噪声 (Noise3D)
            '
            +            
            +          >Noise3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-chords
            .html"
            +            
            +                data-en='Random Chords
            '
            +            
            +                data-es='Cuerdas Aleatorias
            '
            +            
            +                data-hi='रैंडम कॉर्ड्स
            '
            +            
            +                data-ko='랜덤 선들
            '
            +            
            +                data-zh-Hans='随机弦
            '
            +            
            +          >Random Chords
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-gaussian
            .html"
            +            
            +                data-en='Random Gaussian
            '
            +            
            +                data-es='Mapear
            '
            +            
            +                data-hi='नक्शा
            '
            +            
            +                data-ko='매핑(map)
            '
            +            
            +                data-zh-Hans='映射 (Map)
            '
            +            
            +          >Random Gaussian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-map
            .html"
            +            
            +                data-en='Map
            '
            +            
            +                data-es='Ecuaciones Paramétricas
            '
            +            
            +                data-hi='पैरामीट्रिक समीकरण
            '
            +            
            +                data-ko='매개변수 방정식
            '
            +            
            +                data-zh-Hans='参数方程
            '
            +            
            +          >Map
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-graphing-2d-equations
            .html"
            +            
            +                data-en='Graphing 2D Equations
            '
            +            
            +                data-es='Graphing 2D Equations
            '
            +            
            +                data-ko='Graphing 2D Equations
            '
            +            
            +                data-zh-Hans='Graphing 2D Equations
            '
            +            
            +          >Graphing 2D Equations
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-parametric-equations
            .html"
            +            
            +                data-en='Parametric Equations
            '
            +            
            +                data-es='Parametric Equations
            '
            +            
            +                data-ko='Parametric Equations
            '
            +            
            +                data-zh-Hans='Parametric Equations
            '
            +            
            +          >Parametric Equations
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_1 column">
            +        
            +      
            +        <h3 name='simulate' class='anchor'>시뮬레이션</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="simulate-forces
            .html"
            +            
            +                data-en='Forces
            '
            +            
            +                data-es='Fuerzas
            '
            +            
            +                data-hi='बल
            '
            +            
            +                data-ko='힘
            '
            +            
            +                data-zh-Hans='Forces
            '
            +            
            +          >Forces
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particle-system
            .html"
            +            
            +                data-en='Particle System
            '
            +            
            +                data-es='Sistema de partículas
            '
            +            
            +                data-hi='कण प्रणाली
            '
            +            
            +                data-ko='파티클 시스템
            '
            +            
            +                data-zh-Hans='Particle System
            '
            +            
            +          >Particle System
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-wolfram-ca
            .html"
            +            
            +                data-en='Wolfram CA
            '
            +            
            +                data-es='Wolfram CA
            '
            +            
            +                data-hi='वोल्फ्राम सीए
            '
            +            
            +                data-ko='울프램 셀룰러 오토마타
            '
            +            
            +                data-zh-Hans='Wolfram CA
            '
            +            
            +          >Wolfram CA
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-game-of-life
            .html"
            +            
            +                data-en='Game of Life
            '
            +            
            +                data-es='Juego de la vida
            '
            +            
            +                data-hi='Game of Life
            '
            +            
            +                data-ko='라이프 게임
            '
            +            
            +                data-zh-Hans='Game of Life
            '
            +            
            +          >Game of Life
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-multiple-particle-systems
            .html"
            +            
            +                data-en='Multiple Particle Systems
            '
            +            
            +                data-es='Múltiples sistemas de partículas
            '
            +            
            +                data-hi='मल्टीपल पार्टिकल सिस्टम
            '
            +            
            +                data-ko='멀티플 파티클 시스템
            '
            +            
            +                data-zh-Hans='Multiple Particle Systems
            '
            +            
            +          >Multiple Particle Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spirograph
            .html"
            +            
            +                data-en='Spirograph
            '
            +            
            +                data-es='Espirógrafo
            '
            +            
            +                data-hi='स्पाइरोग्राफ
            '
            +            
            +                data-ko='스피로그래프
            '
            +            
            +                data-zh-Hans='Spirograph
            '
            +            
            +          >Spirograph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-l-systems
            .html"
            +            
            +                data-en='L-Systems
            '
            +            
            +                data-es='Sístemas-L
            '
            +            
            +                data-hi='एल-सिस्टम्स
            '
            +            
            +                data-ko='L-시스템
            '
            +            
            +                data-zh-Hans='L-Systems
            '
            +            
            +          >L-Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spring
            .html"
            +            
            +                data-en='Spring
            '
            +            
            +                data-es='Resorte
            '
            +            
            +                data-hi='वसंत
            '
            +            
            +                data-ko='용수철
            '
            +            
            +                data-zh-Hans='Spring
            '
            +            
            +          >Spring
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-springs
            .html"
            +            
            +                data-en='Springs
            '
            +            
            +                data-es='Resortes
            '
            +            
            +                data-hi='स्प्रिंग्स
            '
            +            
            +                data-ko='용수철들
            '
            +            
            +                data-zh-Hans='Springs
            '
            +            
            +          >Springs
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-soft-body
            .html"
            +            
            +                data-en='Soft Body
            '
            +            
            +                data-es='Cuerpo blando
            '
            +            
            +                data-hi='शीतल शरीर
            '
            +            
            +                data-ko='소프트 바디
            '
            +            
            +                data-zh-Hans='Soft Body
            '
            +            
            +          >Soft Body
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-smokeparticles
            .html"
            +            
            +                data-en='SmokeParticles
            '
            +            
            +                data-es='Partículas de humo
            '
            +            
            +                data-hi='स्मोकपार्टिकल्स
            '
            +            
            +                data-ko='연기 파티클
            '
            +            
            +                data-zh-Hans='SmokeParticles
            '
            +            
            +          >SmokeParticles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Movimiento browniano
            '
            +            
            +                data-hi='ब्राउनियन मोशन
            '
            +            
            +                data-ko='브라운 운동
            '
            +            
            +                data-zh-Hans='Brownian Motion
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-chain
            .html"
            +            
            +                data-en='Chain
            '
            +            
            +                data-es='Cadena
            '
            +            
            +                data-hi='चैन
            '
            +            
            +                data-ko='사슬
            '
            +            
            +                data-zh-Hans='Chain
            '
            +            
            +          >Chain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-snowflakes
            .html"
            +            
            +                data-en='Snowflakes
            '
            +            
            +                data-es='Copos de Nieve
            '
            +            
            +                data-hi='स्नोफ्लेक्स
            '
            +            
            +                data-ko='눈송이 파티클
            '
            +            
            +                data-zh-Hans='Snowflakes
            '
            +            
            +          >Snowflakes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-penrose-tiles
            .html"
            +            
            +                data-en='Penrose Tiles
            '
            +            
            +                data-es='Baldosas de Penrose
            '
            +            
            +                data-hi='पेनरोज़ टाइलें
            '
            +            
            +                data-ko='펜로즈 타일
            '
            +            
            +                data-zh-Hans='Penrose Tiles
            '
            +            
            +          >Penrose Tiles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-recursive-tree
            .html"
            +            
            +                data-en='Recursive Tree
            '
            +            
            +                data-es='Árbol Recursivo
            '
            +            
            +                data-hi='रिकर्सिव ट्री
            '
            +            
            +                data-ko='재귀 나무
            '
            +            
            +                data-zh-Hans='Recursive Tree
            '
            +            
            +          >Recursive Tree
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-the-mandelbrot-set
            .html"
            +            
            +                data-en='The Mandelbrot Set
            '
            +            
            +                data-es='El Conjunto de Mandelbrot
            '
            +            
            +                data-hi='मंडेलब्रॉट सेत
            '
            +            
            +                data-ko='망델브로 집합
            '
            +            
            +                data-zh-Hans='The Mandelbrot Set
            '
            +            
            +          >The Mandelbrot Set
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-koch-curve
            .html"
            +            
            +                data-en='Koch Curve
            '
            +            
            +                data-es='Curva Koch
            '
            +            
            +                data-hi='कोच कर्व
            '
            +            
            +                data-ko='코흐 곡선
            '
            +            
            +                data-zh-Hans='Koch Curve
            '
            +            
            +          >Koch Curve
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-bubble-sort
            .html"
            +            
            +                data-en='Bubble Sort
            '
            +            
            +                data-es='Ordenamiento de Burbuja
            '
            +            
            +                data-hi='बबल सॉर्ट
            '
            +            
            +                data-ko='버블 정렬
            '
            +            
            +                data-zh-Hans='Bubble Sort
            '
            +            
            +          >Bubble Sort
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-stepping-feet-illusion
            .html"
            +            
            +                data-en='Stepping Feet Illusion
            '
            +            
            +                data-es='Ilusión de los Pasos
            '
            +            
            +                data-hi='स्टेपिंग फीट इल्यूजन
            '
            +            
            +                data-ko='걷는발 착시효과
            '
            +            
            +                data-zh-Hans='Stepping Feet Illusion
            '
            +            
            +          >Stepping Feet Illusion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particles
            .html"
            +            
            +                data-en='Particles
            '
            +            
            +                data-es='Partículas
            '
            +            
            +                data-hi='कण
            '
            +            
            +                data-ko='파티클
            '
            +            
            +                data-zh-Hans='Particles
            '
            +            
            +          >Particles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-quicksort
            .html"
            +            
            +                data-en='Quicksort
            '
            +            
            +                data-es='Quicksort
            '
            +            
            +                data-ko='Quicksort
            '
            +            
            +                data-zh-Hans='Quicksort
            '
            +            
            +          >Quicksort
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='interaction' class='anchor'>인터랙션</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="interaction-tickle
            .html"
            +            
            +                data-en='Tickle
            '
            +            
            +                data-es='Cosquillas
            '
            +            
            +                data-hi='टिकल 
            '
            +            
            +                data-ko='간질간질
            '
            +            
            +                data-zh-Hans='Tickle
            '
            +            
            +          >Tickle
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-weight-line
            .html"
            +            
            +                data-en='Weight Line
            '
            +            
            +                data-es='Weight Line
            '
            +            
            +                data-hi='फॉलो 1
            '
            +            
            +                data-ko='Weight Line
            '
            +            
            +                data-zh-Hans='Weight Line
            '
            +            
            +          >Weight Line
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-1
            .html"
            +            
            +                data-en='Follow 1
            '
            +            
            +                data-es='Seguir 1
            '
            +            
            +                data-hi='फॉलो 2
            '
            +            
            +                data-ko='따라다니기 1
            '
            +            
            +                data-zh-Hans='跟随 1
            '
            +            
            +          >Follow 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-2
            .html"
            +            
            +                data-en='Follow 2
            '
            +            
            +                data-es='Seguir 2
            '
            +            
            +                data-hi='फॉलो 3
            '
            +            
            +                data-ko='따라다니기 2
            '
            +            
            +                data-zh-Hans='跟随 2
            '
            +            
            +          >Follow 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-3
            .html"
            +            
            +                data-en='Follow 3
            '
            +            
            +                data-es='Seguir 3
            '
            +            
            +                data-hi='सांप का खेल
            '
            +            
            +                data-ko='따라다니기 3
            '
            +            
            +                data-zh-Hans='跟随 3
            '
            +            
            +          >Follow 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-snake-game
            .html"
            +            
            +                data-en='Snake game
            '
            +            
            +                data-es='Juego de Serpiente
            '
            +            
            +                data-hi='वेवमेकर
            '
            +            
            +                data-ko='스네이크 게임
            '
            +            
            +                data-zh-Hans='贪吃蛇
            '
            +            
            +          >Snake game
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-wavemaker
            .html"
            +            
            +                data-en='Wavemaker
            '
            +            
            +                data-es='Wavemaker
            '
            +            
            +                data-hi='रीच 1
            '
            +            
            +                data-ko='파도 만들기
            '
            +            
            +                data-zh-Hans='造波器
            '
            +            
            +          >Wavemaker
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-1
            .html"
            +            
            +                data-en='Reach 1
            '
            +            
            +                data-es='Alcanzar 1
            '
            +            
            +                data-hi='रीच 2
            '
            +            
            +                data-ko='팔닿기 1
            '
            +            
            +                data-zh-Hans='延伸 1
            '
            +            
            +          >Reach 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-2
            .html"
            +            
            +                data-en='Reach 2
            '
            +            
            +                data-es='Alcanzar 2
            '
            +            
            +                data-hi='पहुंच ३
            '
            +            
            +                data-ko='팔닿기 2
            '
            +            
            +                data-zh-Hans='延伸 2
            '
            +            
            +          >Reach 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-3
            .html"
            +            
            +                data-en='Reach 3
            '
            +            
            +                data-es='Alcanzar 3
            '
            +            
            +                data-hi='Arduino सेंसर डेटा WebJack के माध्यम से
            '
            +            
            +                data-ko='팔닿기 3
            '
            +            
            +                data-zh-Hans='延伸 3
            '
            +            
            +          >Reach 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-arduino-sensor-data-via-webjack
            .html"
            +            
            +                data-en='Arduino sensor data via WebJack
            '
            +            
            +                data-es='Datos de un sensor Arduino vía WebJack
            '
            +            
            +                data-hi='बहुरूपदर्शक
            '
            +            
            +                data-ko='웹잭과 아두이노 센서 데이터
            '
            +            
            +                data-zh-Hans='通过 WebJack 读取 Arduino 传感器数据
            '
            +            
            +          >Arduino sensor data via WebJack
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-kaleidoscope
            .html"
            +            
            +                data-en='Kaleidoscope
            '
            +            
            +                data-es='Caleidoscopio
            '
            +            
            +                data-ko='만화경
            '
            +            
            +                data-zh-Hans='万花筒
            '
            +            
            +          >Kaleidoscope
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='objects' class='anchor'>객체</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="objects-objects
            .html"
            +            
            +                data-en='Objects
            '
            +            
            +                data-es='Objetos
            '
            +            
            +                data-hi='वस्तु
            '
            +            
            +                data-ko='객체
            '
            +            
            +                data-zh-Hans='物件 (Objects)
            '
            +            
            +          >Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-multiple-objects
            .html"
            +            
            +                data-en='Multiple Objects
            '
            +            
            +                data-es='Múltiples objetos
            '
            +            
            +                data-hi='वस्तुओं का नाम दें
            '
            +            
            +                data-ko='복수 객체
            '
            +            
            +                data-zh-Hans='多个物件
            '
            +            
            +          >Multiple Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-array-of-objects
            .html"
            +            
            +                data-en='Array of Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='वस्तुओं की सरणी
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='物件数组
            '
            +            
            +          >Array of Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-objects-2
            .html"
            +            
            +                data-en='Objects 2
            '
            +            
            +                data-es='Objetos 2
            '
            +            
            +                data-hi='वस्तु 2
            '
            +            
            +                data-ko='객체 2
            '
            +            
            +                data-zh-Hans='物件 2
            '
            +            
            +          >Objects 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-inheritance
            .html"
            +            
            +                data-en='Inheritance
            '
            +            
            +                data-es='Herencia
            '
            +            
            +                data-hi='वंशानुक्रम
            '
            +            
            +                data-ko='상속
            '
            +            
            +                data-zh-Hans='继承 (Inheritance)
            '
            +            
            +          >Inheritance
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-composite-objects
            .html"
            +            
            +                data-en='Composite Objects
            '
            +            
            +                data-es='Objetos Compuestos
            '
            +            
            +                data-hi='समग्र वस्तु
            '
            +            
            +                data-ko='합성 객체
            '
            +            
            +                data-zh-Hans='复合物件
            '
            +            
            +          >Composite Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-car-instances
            .html"
            +            
            +                data-en='Car Instances
            '
            +            
            +                data-es='Car Instances
            '
            +            
            +                data-ko='Car Instances
            '
            +            
            +                data-zh-Hans='Car Instances
            '
            +            
            +          >Car Instances
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='lights' class='anchor'>조명</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="lights-directional
            .html"
            +            
            +                data-en='Directional
            '
            +            
            +                data-es='Direccional
            '
            +            
            +                data-hi='दिशात्मक
            '
            +            
            +                data-ko='디렉셔널 라이트
            '
            +            
            +                data-zh-Hans='定向光
            '
            +            
            +          >Directional
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="lights-mixture
            .html"
            +            
            +                data-en='Mixture
            '
            +            
            +                data-es='Mezcla
            '
            +            
            +                data-hi='मिश्रण
            '
            +            
            +                data-ko='혼합 라이트
            '
            +            
            +                data-zh-Hans='混合光
            '
            +            
            +          >Mixture
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='motion' class='anchor'>모션</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="motion-non-orthogonal-reflection
            .html"
            +            
            +                data-en='Non Orthogonal Reflection
            '
            +            
            +                data-es='Reflejo no ortogonal
            '
            +            
            +                data-hi='नॉन ऑर्थोगोनल रिफ्लेक्शन
            '
            +            
            +                data-ko='비직각 반사
            '
            +            
            +                data-zh-Hans='Non Orthogonal Reflection
            '
            +            
            +          >Non Orthogonal Reflection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-linear
            .html"
            +            
            +                data-en='Linear
            '
            +            
            +                data-es='Lineal
            '
            +            
            +                data-hi='रैखिक
            '
            +            
            +                data-ko='선형
            '
            +            
            +                data-zh-Hans='Linear
            '
            +            
            +          >Linear
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bounce
            .html"
            +            
            +                data-en='Bounce
            '
            +            
            +                data-es='Rebote
            '
            +            
            +                data-hi='उछाल
            '
            +            
            +                data-ko='바운스
            '
            +            
            +                data-zh-Hans='Bounce
            '
            +            
            +          >Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bouncy-bubbles
            .html"
            +            
            +                data-en='Bouncy Bubbles
            '
            +            
            +                data-es='Burbujas Saltarinas
            '
            +            
            +                data-hi='उछाल वाले बुलबुले
            '
            +            
            +                data-ko='버블 바운스
            '
            +            
            +                data-zh-Hans='Bouncy Bubbles
            '
            +            
            +          >Bouncy Bubbles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Transformar
            '
            +            
            +                data-hi='मॉर्फ
            '
            +            
            +                data-ko='변형(morph)
            '
            +            
            +                data-zh-Hans='Morph
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-morph
            .html"
            +            
            +                data-en='Morph
            '
            +            
            +                data-es='Moviéndose por Curvas
            '
            +            
            +                data-hi='मूविंग ऑन कर्व्स
            '
            +            
            +                data-ko='곡선 위 움직이기
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Morph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-circle-collision
            .html"
            +            
            +                data-en='Circle Collision
            '
            +            
            +                data-es='Circle Collision
            '
            +            
            +                data-ko='Circle Collision
            '
            +            
            +                data-zh-Hans='Circle Collision
            '
            +            
            +          >Circle Collision
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-moving-on-curves
            .html"
            +            
            +                data-en='Moving On Curves
            '
            +            
            +                data-es='Moving On Curves
            '
            +            
            +                data-ko='Moving On Curves
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Moving On Curves
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='instance_mode' class='anchor'>인스턴스 모드</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="instance-mode-instantiation
            .html"
            +            
            +                data-en='Instantiation
            '
            +            
            +                data-es='Instaciación
            '
            +            
            +                data-hi='इंस्टेंटेशन
            '
            +            
            +                data-ko='인스턴스화
            '
            +            
            +                data-zh-Hans='创建实例
            '
            +            
            +          >Instantiation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="instance-mode-instance-container
            .html"
            +            
            +                data-en='Instance Container
            '
            +            
            +                data-es='Contenedor de instancia
            '
            +            
            +                data-hi='इंस्टेंस कंटेनर
            '
            +            
            +                data-ko='인스턴스 컨테이너
            '
            +            
            +                data-zh-Hans='实例容器
            '
            +            
            +          >Instance Container
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='dom' class='anchor'>DOM</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="dom-input-and-button
            .html"
            +            
            +                data-en='Input/Button
            '
            +            
            +                data-es='Entrada y botón
            '
            +            
            +                data-hi='इनपुट और बटन
            '
            +            
            +                data-ko='입력과 버튼
            '
            +            
            +                data-zh-Hans='Input and Button
            '
            +            
            +          >Input/Button
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-slider
            .html"
            +            
            +                data-en='Slider
            '
            +            
            +                data-es='Barra deslizante
            '
            +            
            +                data-hi='स्लाइडर
            '
            +            
            +                data-ko='슬라이더
            '
            +            
            +                data-zh-Hans='Slider
            '
            +            
            +          >Slider
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-modifying-the-dom
            .html"
            +            
            +                data-en='Modifying the DOM
            '
            +            
            +                data-es='Modificar el DOM
            '
            +            
            +                data-hi='डोम को संशोधित करना
            '
            +            
            +                data-ko='DOM 변경
            '
            +            
            +                data-zh-Hans='Modifying the DOM
            '
            +            
            +          >Modifying the DOM
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video
            .html"
            +            
            +                data-en='Video
            '
            +            
            +                data-es='Video
            '
            +            
            +                data-hi='वीडियो
            '
            +            
            +                data-ko='비디오
            '
            +            
            +                data-zh-Hans='Video
            '
            +            
            +          >Video
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-canvas
            .html"
            +            
            +                data-en='Video Canvas
            '
            +            
            +                data-es='Lienzo y video
            '
            +            
            +                data-hi='वीडियो कैनवास
            '
            +            
            +                data-ko='비디오 캔버스
            '
            +            
            +                data-zh-Hans='Video Canvas
            '
            +            
            +          >Video Canvas
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-pixels
            .html"
            +            
            +                data-en='Video Pixels
            '
            +            
            +                data-es='Pixeles de video
            '
            +            
            +                data-hi='वीडियो पिक्सल
            '
            +            
            +                data-ko='비디오 픽셀
            '
            +            
            +                data-zh-Hans='Video Pixels
            '
            +            
            +          >Video Pixels
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-capture
            .html"
            +            
            +                data-en='Video Capture
            '
            +            
            +                data-es='Captura de video
            '
            +            
            +                data-hi='वीडियो कैप्चर
            '
            +            
            +                data-ko='실시간 비디오
            '
            +            
            +                data-zh-Hans='Video Capture
            '
            +            
            +          >Video Capture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-drop
            .html"
            +            
            +                data-en='Drop
            '
            +            
            +                data-es='Arrojar
            '
            +            
            +                data-hi='छोड़ देना
            '
            +            
            +                data-ko='드롭 기능
            '
            +            
            +                data-zh-Hans='Drop
            '
            +            
            +          >Drop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-dom-form-elements
            .html"
            +            
            +                data-en='DOM Form Elements
            '
            +            
            +                data-es='DOM Form Elements
            '
            +            
            +                data-ko='DOM Form Elements
            '
            +            
            +                data-zh-Hans='DOM Form Elements
            '
            +            
            +          >DOM Form Elements
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='drawing' class='anchor'>드로잉</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="drawing-continuous-lines
            .html"
            +            
            +                data-en='Continuous Lines
            '
            +            
            +                data-es='Líneas continuas
            '
            +            
            +                data-hi='सतत रेखा 
            '
            +            
            +                data-ko='연속된 선
            '
            +            
            +                data-zh-Hans='Líneas continuas
            '
            +            
            +          >Continuous Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-patterns
            .html"
            +            
            +                data-en='Patterns
            '
            +            
            +                data-es='Patrones
            '
            +            
            +                data-hi='पैटर्न
            '
            +            
            +                data-ko='패턴
            '
            +            
            +                data-zh-Hans='Patrones
            '
            +            
            +          >Patterns
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-pulses
            .html"
            +            
            +                data-en='Pulses
            '
            +            
            +                data-es='Pulsos
            '
            +            
            +                data-hi='दालें
            '
            +            
            +                data-ko='율동
            '
            +            
            +                data-zh-Hans='Pulsos
            '
            +            
            +          >Pulses
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='transform' class='anchor'>변형</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="transform-translate
            .html"
            +            
            +                data-en='Translate
            '
            +            
            +                data-es='Translate
            '
            +            
            +                data-hi='अनुवाद
            '
            +            
            +                data-ko='위치 이동(Translate)
            '
            +            
            +                data-zh-Hans='Translate
            '
            +            
            +          >Translate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-scale
            .html"
            +            
            +                data-en='Scale
            '
            +            
            +                data-es='Escalar
            '
            +            
            +                data-hi='स्केल
            '
            +            
            +                data-ko='크기 조정(Scale)
            '
            +            
            +                data-zh-Hans='Scale
            '
            +            
            +          >Scale
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-rotate
            .html"
            +            
            +                data-en='Rotate
            '
            +            
            +                data-es='Rotate
            '
            +            
            +                data-hi='घुमाएँ
            '
            +            
            +                data-ko='회전(Rotate)
            '
            +            
            +                data-zh-Hans='Rotate
            '
            +            
            +          >Rotate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-arm
            .html"
            +            
            +                data-en='Arm
            '
            +            
            +                data-es='Brazo
            '
            +            
            +                data-hi='आर्म
            '
            +            
            +                data-ko='팔모양
            '
            +            
            +                data-zh-Hans='Arm
            '
            +            
            +          >Arm
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_2 column">
            +        
            +      
            +        <h3 name='typography' class='anchor'>타이포그래피</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="typography-letters
            .html"
            +            
            +                data-en='Letters
            '
            +            
            +                data-es='Letters
            '
            +            
            +                data-hi='पत्र
            '
            +            
            +                data-ko='글자
            '
            +            
            +                data-zh-Hans='Letters
            '
            +            
            +          >Letters
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-words
            .html"
            +            
            +                data-en='Words
            '
            +            
            +                data-es='Words
            '
            +            
            +                data-hi='शब्द
            '
            +            
            +                data-ko='단어
            '
            +            
            +                data-zh-Hans='Words
            '
            +            
            +          >Words
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-text-rotation
            .html"
            +            
            +                data-en='Text Rotation
            '
            +            
            +                data-es='Text Rotation
            '
            +            
            +                data-ko='텍스트 회전
            '
            +            
            +                data-zh-Hans='Text Rotation
            '
            +            
            +          >Text Rotation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='3d' class='anchor'>3D</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="3d-geometries
            .html"
            +            
            +                data-en='Geometries
            '
            +            
            +                data-es='Geometrías
            '
            +            
            +                data-hi='ज्यामिति
            '
            +            
            +                data-ko='기하
            '
            +            
            +                data-zh-Hans='Geometries
            '
            +            
            +          >Geometries
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-sine-cosine-in-3d
            .html"
            +            
            +                data-en='Sine Cosine in 3D
            '
            +            
            +                data-es='Seno Coseno en 3D
            '
            +            
            +                data-hi='3D में साइन कोसाइन
            '
            +            
            +                data-ko='3D속 사인 코사인
            '
            +            
            +                data-zh-Hans='Sine Cosine in 3D
            '
            +            
            +          >Sine Cosine in 3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-multiple-lights
            .html"
            +            
            +                data-en='Multiple Lights
            '
            +            
            +                data-es='Múltiples luces
            '
            +            
            +                data-hi='मल्टीपल लाइट्स
            '
            +            
            +                data-ko='복수의 조명들
            '
            +            
            +                data-zh-Hans='Multiple Lights
            '
            +            
            +          >Multiple Lights
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-materials
            .html"
            +            
            +                data-en='Materials
            '
            +            
            +                data-es='Materiales
            '
            +            
            +                data-hi='सामग्री
            '
            +            
            +                data-ko='재질(Materials)
            '
            +            
            +                data-zh-Hans='Materials
            '
            +            
            +          >Materials
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-textures
            .html"
            +            
            +                data-en='Textures
            '
            +            
            +                data-es='Texturas
            '
            +            
            +                data-hi='बनावट
            '
            +            
            +                data-ko='텍스처
            '
            +            
            +                data-zh-Hans='Textures
            '
            +            
            +          >Textures
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-ray-casting
            .html"
            +            
            +                data-en='Ray Casting
            '
            +            
            +                data-es='Ray Casting
            '
            +            
            +                data-hi='रे कास्टिंग
            '
            +            
            +                data-ko='레이 캐스팅
            '
            +            
            +                data-zh-Hans='Ray Casting
            '
            +            
            +          >Ray Casting
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-orbit-control
            .html"
            +            
            +                data-en='Orbit Control
            '
            +            
            +                data-es='Control de órbita
            '
            +            
            +                data-hi='कक्षा नियंत्रण
            '
            +            
            +                data-ko='궤도 제어
            '
            +            
            +                data-zh-Hans='Orbit Control
            '
            +            
            +          >Orbit Control
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-basic-shader
            .html"
            +            
            +                data-en='Basic Shader
            '
            +            
            +                data-es='Basic Shader
            '
            +            
            +                data-hi='बेसिक शेडर
            '
            +            
            +                data-ko='셰이더 기초
            '
            +            
            +                data-zh-Hans='Basic Shader
            '
            +            
            +          >Basic Shader
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-as-a-texture
            .html"
            +            
            +                data-en='Shader as a Texture
            '
            +            
            +                data-es='Shader as a Texture
            '
            +            
            +                data-hi='शेडर एक बनावट के रूप में
            '
            +            
            +                data-ko='셰이더로 텍스처 만들기
            '
            +            
            +                data-zh-Hans='Shader as a Texture
            '
            +            
            +          >Shader as a Texture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-passing-shader-uniforms
            .html"
            +            
            +                data-en='Passing Shader Uniforms
            '
            +            
            +                data-es='Passing Shader Uniforms
            '
            +            
            +                data-hi='पासिंग शेडर यूनिफॉर्म
            '
            +            
            +                data-ko='셰이더 유니폼
            '
            +            
            +                data-zh-Hans='Passing Shader Uniforms
            '
            +            
            +          >Passing Shader Uniforms
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-using-webcam
            .html"
            +            
            +                data-en='Shader Using Webcam
            '
            +            
            +                data-es='Shader Using Webcam
            '
            +            
            +                data-hi='Shader वेबकैम का उपयोग कर रहा है
            '
            +            
            +                data-ko='웹캠을 사용한 셰이더
            '
            +            
            +                data-zh-Hans='Shader Using Webcam
            '
            +            
            +          >Shader Using Webcam
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='input' class='anchor'>입력</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="input-clock
            .html"
            +            
            +                data-en='Clock
            '
            +            
            +                data-es='Clock
            '
            +            
            +                data-hi='घड़ी
            '
            +            
            +                data-ko='시계
            '
            +            
            +                data-zh-Hans='Clock
            '
            +            
            +          >Clock
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-constrain
            .html"
            +            
            +                data-en='Constrain
            '
            +            
            +                data-es='Constrain
            '
            +            
            +                data-hi='बाधा
            '
            +            
            +                data-ko='제한
            '
            +            
            +                data-zh-Hans='Constrain
            '
            +            
            +          >Constrain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-easing
            .html"
            +            
            +                data-en='Easing
            '
            +            
            +                data-es='Easing
            '
            +            
            +                data-hi='आसान
            '
            +            
            +                data-ko='이징(Easing)
            '
            +            
            +                data-zh-Hans='Easing
            '
            +            
            +          >Easing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-keyboard
            .html"
            +            
            +                data-en='Keyboard
            '
            +            
            +                data-es='Keyboard
            '
            +            
            +                data-hi='कीबोर्ड
            '
            +            
            +                data-ko='키보드
            '
            +            
            +                data-zh-Hans='Keyboard
            '
            +            
            +          >Keyboard
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-milliseconds
            .html"
            +            
            +                data-en='Milliseconds
            '
            +            
            +                data-es='Mouse 1D
            '
            +            
            +                data-hi='माउस 1D
            '
            +            
            +                data-ko='1D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 1D
            '
            +            
            +          >Milliseconds
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-1d
            .html"
            +            
            +                data-en='Mouse 1D
            '
            +            
            +                data-es='Mouse 2D
            '
            +            
            +                data-hi='माउस 2D
            '
            +            
            +                data-ko='2D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 2D
            '
            +            
            +          >Mouse 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-2d
            .html"
            +            
            +                data-en='Mouse 2D
            '
            +            
            +                data-es='Mouse Press
            '
            +            
            +                data-hi='माउस प्रेस
            '
            +            
            +                data-ko='마우스 버튼
            '
            +            
            +                data-zh-Hans='Mouse Press
            '
            +            
            +          >Mouse 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-functions
            .html"
            +            
            +                data-en='Mouse Functions
            '
            +            
            +                data-es='Mouse Functions
            '
            +            
            +                data-hi='माउस फंक्शन्स
            '
            +            
            +                data-ko='마우스 함수
            '
            +            
            +                data-zh-Hans='Mouse Functions
            '
            +            
            +          >Mouse Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-signals
            .html"
            +            
            +                data-en='Mouse Signals
            '
            +            
            +                data-es='Mouse Signals
            '
            +            
            +                data-hi='माउस सिग्नल
            '
            +            
            +                data-ko='마우스 신호
            '
            +            
            +                data-zh-Hans='Mouse Signals
            '
            +            
            +          >Mouse Signals
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-press
            .html"
            +            
            +                data-en='Mouse Press
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-hi='भंडारण इनपुट
            '
            +            
            +                data-ko='입력값 저장
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Mouse Press
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-rollover
            .html"
            +            
            +                data-en='Rollover
            '
            +            
            +                data-es='Rollover
            '
            +            
            +                data-ko='롤오버 (Rollover)
            '
            +            
            +                data-zh-Hans='Rollover
            '
            +            
            +          >Rollover
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-storing-input
            .html"
            +            
            +                data-en='Storing Input
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-ko='Storing Input
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Storing Input
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='advanced_data' class='anchor'>고급 데이터</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-json
            .html"
            +            
            +                data-en='Load Saved JSON
            '
            +            
            +                data-es='Load Saved JSON
            '
            +            
            +                data-hi='लोड सेव किया गया JSON
            '
            +            
            +                data-ko='저장된 JSON 불러오기
            '
            +            
            +                data-zh-Hans='Load Saved JSON
            '
            +            
            +          >Load Saved JSON
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-table
            .html"
            +            
            +                data-en='Load Saved Table
            '
            +            
            +                data-es='Load Saved Table
            '
            +            
            +                data-ko='Load Saved Table
            '
            +            
            +                data-zh-Hans='Load Saved Table
            '
            +            
            +          >Load Saved Table
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='sound' class='anchor'>사운드</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="sound-load-and-play-sound
            .html"
            +            
            +                data-en='Load/Play Sound
            '
            +            
            +                data-es='Cargar y reproducir sonido
            '
            +            
            +                data-hi='लोड और प्ले साउंड
            '
            +            
            +                data-ko='사운드 불러오기/재생
            '
            +            
            +                data-zh-Hans='Load and Play Sound
            '
            +            
            +          >Load/Play Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-preload-soundfile
            .html"
            +            
            +                data-en='Preload SoundFile
            '
            +            
            +                data-es='Precargar archivo de sonido
            '
            +            
            +                data-hi='प्रीलोड साउंडफाइल
            '
            +            
            +                data-ko='사운드 파일 미리 불러오기
            '
            +            
            +                data-zh-Hans='Preload SoundFile
            '
            +            
            +          >Preload SoundFile
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-soundformats
            .html"
            +            
            +                data-en='soundFormats
            '
            +            
            +                data-es='Formatos de sonido
            '
            +            
            +                data-hi='ध्वनि प्रारूप
            '
            +            
            +                data-ko='사운드 파일 형식
            '
            +            
            +                data-zh-Hans='soundFormats
            '
            +            
            +          >soundFormats
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-play-mode
            .html"
            +            
            +                data-en='Play Mode
            '
            +            
            +                data-es='Modo de reproducción
            '
            +            
            +                data-hi='प्ले मोड
            '
            +            
            +                data-ko='재생 모드
            '
            +            
            +                data-zh-Hans='Play Mode
            '
            +            
            +          >Play Mode
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-pan-sound
            .html"
            +            
            +                data-en='Pan Sound
            '
            +            
            +                data-es='Paneo
            '
            +            
            +                data-hi='पैन साउंड
            '
            +            
            +                data-ko='사운드 패닝
            '
            +            
            +                data-zh-Hans='Pan Sound
            '
            +            
            +          >Pan Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-sound-effect
            .html"
            +            
            +                data-en='Sound Effect
            '
            +            
            +                data-es='Efecto de sonido
            '
            +            
            +                data-hi='ध्वनि प्रभाव
            '
            +            
            +                data-ko='사운드 효과
            '
            +            
            +                data-zh-Hans='Sound Effect
            '
            +            
            +          >Sound Effect
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-playback-rate
            .html"
            +            
            +                data-en='Playback Rate
            '
            +            
            +                data-es='Tasa de reproducción
            '
            +            
            +                data-hi='प्लेबैक दर
            '
            +            
            +                data-ko='재생 속도
            '
            +            
            +                data-zh-Hans='Playback Rate
            '
            +            
            +          >Playback Rate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-measuring-amplitude
            .html"
            +            
            +                data-en='Measuring Amplitude
            '
            +            
            +                data-es=' Midiendo la amplitud
            '
            +            
            +                data-hi='मापने वाला आयाम
            '
            +            
            +                data-ko='진폭 측정
            '
            +            
            +                data-zh-Hans='Measuring Amplitude
            '
            +            
            +          >Measuring Amplitude
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-noise-drum-envelope
            .html"
            +            
            +                data-en='Noise Drum Envelope
            '
            +            
            +                data-es='Tambor con envolvente y ruido
            '
            +            
            +                data-hi='शोर ड्रम लिफाफा
            '
            +            
            +                data-ko='노이즈 드럼 엔벨로프
            '
            +            
            +                data-zh-Hans='Noise Drum Envelope
            '
            +            
            +          >Noise Drum Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-note-envelope
            .html"
            +            
            +                data-en='Note Envelope
            '
            +            
            +                data-es=' Envolvente de nota
            '
            +            
            +                data-hi='नोट लिफाफा
            '
            +            
            +                data-ko='음계 엔벨로프
            '
            +            
            +                data-zh-Hans='Note Envelope
            '
            +            
            +          >Note Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-oscillator-frequency
            .html"
            +            
            +                data-en='Oscillator Frequency
            '
            +            
            +                data-es='Frecuencia de oscilador
            '
            +            
            +                data-hi='थरथरानवाला आवृत्ति
            '
            +            
            +                data-ko='오실레이터 주파수
            '
            +            
            +                data-zh-Hans='Oscillator Frequency
            '
            +            
            +          >Oscillator Frequency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-input
            .html"
            +            
            +                data-en='Mic Input
            '
            +            
            +                data-es='Entrada de micrófono
            '
            +            
            +                data-hi='Mic Input
            '
            +            
            +                data-ko='마이크 입력
            '
            +            
            +                data-zh-Hans='Mic Input
            '
            +            
            +          >Mic Input
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-spectrum
            .html"
            +            
            +                data-en='Frequency Spectrum
            '
            +            
            +                data-es='Espectro de frecuencia
            '
            +            
            +                data-hi='फ्रीक्वेंसी स्पेक्ट्रम Spec
            '
            +            
            +                data-ko='주파수 스펙트럼
            '
            +            
            +                data-zh-Hans='Frequency Spectrum
            '
            +            
            +          >Frequency Spectrum
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-threshold
            .html"
            +            
            +                data-en='Mic Threshold
            '
            +            
            +                data-es='Umbral de micrófono
            '
            +            
            +                data-hi='माइक थ्रेशोल्ड
            '
            +            
            +                data-ko='마이크 임계값
            '
            +            
            +                data-zh-Hans='Mic Threshold
            '
            +            
            +          >Mic Threshold
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-lowpass
            .html"
            +            
            +                data-en='Filter LowPass
            '
            +            
            +                data-es=' Filtro pasabajos
            '
            +            
            +                data-hi='फ़िल्टर लोपास
            '
            +            
            +                data-ko='로우패스 필터
            '
            +            
            +                data-zh-Hans='Filter LowPass
            '
            +            
            +          >Filter LowPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-bandpass
            .html"
            +            
            +                data-en='Filter BandPass
            '
            +            
            +                data-es=' Filtro pasabanda
            '
            +            
            +                data-hi='फ़िल्टर बैंडपास
            '
            +            
            +                data-ko='밴드패스 필터
            '
            +            
            +                data-zh-Hans='Filter BandPass
            '
            +            
            +          >Filter BandPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-delay
            .html"
            +            
            +                data-en='Delay
            '
            +            
            +                data-es=' Delay
            '
            +            
            +                data-hi='देरी
            '
            +            
            +                data-ko='딜레이 필터
            '
            +            
            +                data-zh-Hans='Delay
            '
            +            
            +          >Delay
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-reverb
            .html"
            +            
            +                data-en='Reverb
            '
            +            
            +                data-es=' Reverb
            '
            +            
            +                data-hi='रेवरब
            '
            +            
            +                data-ko='리버브
            '
            +            
            +                data-zh-Hans='Reverb
            '
            +            
            +          >Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-convolution-reverb
            .html"
            +            
            +                data-en='Convolution Reverb
            '
            +            
            +                data-es=' Reverb de convolución
            '
            +            
            +                data-hi='कनवल्शन रेवरब
            '
            +            
            +                data-ko='컨볼루션 리버브
            '
            +            
            +                data-zh-Hans='Convolution Reverb
            '
            +            
            +          >Convolution Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-record-save-audio
            .html"
            +            
            +                data-en='Record Save Audio
            '
            +            
            +                data-es=' Graba y almacena audio
            '
            +            
            +                data-hi='रिकॉर्ड ऑडियो सहेजें
            '
            +            
            +                data-ko='오디오 녹음/저장
            '
            +            
            +                data-zh-Hans='Record Save Audio
            '
            +            
            +          >Record Save Audio
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-modulation
            .html"
            +            
            +                data-en='Frequency Modulation
            '
            +            
            +                data-es='Modulación en frecuencia
            '
            +            
            +                data-hi='फ़्रीक्वेंसी मॉडुलन
            '
            +            
            +                data-ko='주파수 변조(FM)
            '
            +            
            +                data-zh-Hans='Frequency Modulation
            '
            +            
            +          >Frequency Modulation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-amplitude-modulation
            .html"
            +            
            +                data-en='Amplitude Modulation
            '
            +            
            +                data-es='Modulación en amplitud
            '
            +            
            +                data-hi='आयाम मॉडुलन
            '
            +            
            +                data-ko='진폭 변조(AM)
            '
            +            
            +                data-zh-Hans='Amplitude Modulation
            '
            +            
            +          >Amplitude Modulation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='mobile' class='anchor'>모바일</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-ball-bounce
            .html"
            +            
            +                data-en='Acceleration Ball Bounce
            '
            +            
            +                data-es='Pelota rebote aceleración
            '
            +            
            +                data-hi='एक्सेलेरेशन बॉल बाउंस
            '
            +            
            +                data-ko='가속도와 바운스
            '
            +            
            +                data-zh-Hans='Acceleration Ball Bounce
            '
            +            
            +          >Acceleration Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-simple-draw
            .html"
            +            
            +                data-en='Simple Draw
            '
            +            
            +                data-es='Dibujo simple
            '
            +            
            +                data-hi='सिंपल ड्रा
            '
            +            
            +                data-ko='간단한 드로잉
            '
            +            
            +                data-zh-Hans='Simple Draw
            '
            +            
            +          >Simple Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-color
            .html"
            +            
            +                data-en='Acceleration Color
            '
            +            
            +                data-es='Aceleración y color
            '
            +            
            +                data-hi='त्वरण रंग
            '
            +            
            +                data-ko='가속도 색상
            '
            +            
            +                data-zh-Hans='Acceleration Color
            '
            +            
            +          >Acceleration Color
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-shake-ball-bounce
            .html"
            +            
            +                data-en='Shake Ball Bounce
            '
            +            
            +                data-es='Pelota rebote agitar
            '
            +            
            +                data-hi='शेक बॉल बाउंस
            '
            +            
            +                data-ko='흔들기와 바운스
            '
            +            
            +                data-zh-Hans='Shake Ball Bounce
            '
            +            
            +          >Shake Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-tilted-3d-box
            .html"
            +            
            +                data-en='Tilted 3D Box
            '
            +            
            +                data-es='Caja 3D
            '
            +            
            +                data-hi='झुका हुआ 3D बॉक्स
            '
            +            
            +                data-ko='기울어진 3D상자
            '
            +            
            +                data-zh-Hans='Tilted 3D Box
            '
            +            
            +          >Tilted 3D Box
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='hello_p5' class='anchor'>안녕 p5</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="hello-p5-simple-shapes
            .html"
            +            
            +                data-en='Simple Shapes
            '
            +            
            +                data-es='Figuras simples
            '
            +            
            +                data-hi='सरल आकार
            '
            +            
            +                data-ko='간단한 도형들
            '
            +            
            +                data-zh-Hans='Simple Shapes
            '
            +            
            +          >Simple Shapes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-1
            .html"
            +            
            +                data-en='Interactivity 1
            '
            +            
            +                data-es='Interactividad 1
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 1
            '
            +            
            +                data-ko='인터랙티비티 1
            '
            +            
            +                data-zh-Hans='Interactivity 1
            '
            +            
            +          >Interactivity 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-2
            .html"
            +            
            +                data-en='Interactivity 2
            '
            +            
            +                data-es='Interactividad 2
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 2
            '
            +            
            +                data-ko='인터랙티비티 2
            '
            +            
            +                data-zh-Hans='Interactivity 2
            '
            +            
            +          >Interactivity 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-animation
            .html"
            +            
            +                data-en='Animation
            '
            +            
            +                data-es='Animación
            '
            +            
            +                data-hi='एनिमेशन
            '
            +            
            +                data-ko='애니메이션
            '
            +            
            +                data-zh-Hans='Animation
            '
            +            
            +          >Animation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-weather
            .html"
            +            
            +                data-en='Weather
            '
            +            
            +                data-es='Clima
            '
            +            
            +                data-hi='मौसम
            '
            +            
            +                data-ko='날씨
            '
            +            
            +                data-zh-Hans='Weather
            '
            +            
            +          >Weather
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-drawing
            .html"
            +            
            +                data-en='Drawing
            '
            +            
            +                data-es='Dibujar
            '
            +            
            +                data-hi='ड्राइंग
            '
            +            
            +                data-ko='드로잉
            '
            +            
            +                data-zh-Hans='Drawing
            '
            +            
            +          >Drawing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-song
            .html"
            +            
            +                data-en='Song
            '
            +            
            +                data-es='Canción
            '
            +            
            +                data-hi='गीत
            '
            +            
            +                data-ko='노래
            '
            +            
            +                data-zh-Hans='Song
            '
            +            
            +          >Song
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +      </div>
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/get-started/index.html b/dist/ko/get-started/index.html
            new file mode 100644
            index 0000000000..599ca6e512
            --- /dev/null
            +++ b/dist/ko/get-started/index.html
            @@ -0,0 +1,343 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">get started | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="get-started-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>시작하기</h1>
            +
            +      <p>p5.js 프로젝트를 에디터에 설정하고 나의 첫 스케치를 만드는 방법을 소개합니다. 가장 쉬운 방법은 인터넷에서 <a href="https://editor.p5js.org" target="_blank">p5.js 웹에디터</a>를 바로 사용하는 것입니다. 웹에디터를 켜고  <a href="#sketch">나의 첫 스케치</a>로 내려가 코드 작성법을 확인하세요. p5.js를 데스크탑 에디터에서 사용하는 방법은 여기서 확인하세요: <a href="#settingUp">데스크탑에 다운받기</a>.
            +      </p>
            +
            +
            +
            +      <h2 class="start-element" id="sketch">나의 첫 스케치</h2>
            +
            +      <div class="info">
            +        <h3 class="sr-only">타원과 코드 스니펫</h3>
            +        <p>기존 프로세싱 사용자라면 다음의 페이지를 읽어보세요: <a href='https://github.com/processing/p5.js/wiki/Processing-transition'>프로세싱 스케치를 p5.js로 변환하기 튜토리얼</a> 에디터에 다음을 입력하세요:</p>
            +
            +<pre id="first-sketch1"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch1" class="copy_button">Copy</button>
            +        </div>
            +        <p>After <code class="language-javascript">background(220);</code>위의 코드를 설명하자면 다음과 같습니다: "좌측 상단 모서리로부터 아래로 50px, 오른쪽으로 50px 떨어진 점을 중심으로 타원을 그린다. 타원의 너비와 높이는 모두 80px로 한다." <code class="language-javascript">ellipse(50,50,80,80);</code>.</p>
            +
            +        <p>스케치를 저장한 뒤 브라우저를 새로고침하면, 입력한 코드에 문제가 없는 한, 다음과 같은 화면을 볼 수 있습니다:</p>
            +        <h3 class="sr-only">타원과 코드 스니펫</h3>
            +
            +<pre id="first-sketch2"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +  ellipse(50,50,80,80);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch2" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">주의: 스크린 리더를 사용하는 경우, p5 웹에디터에서 접근성 모드 출력(Accessible Outputs)을 활성화해야 합니다. 별도의 에디터를 사용하는 경우, 접근성 라이브러리를 html 파일에 추가해야 합니다. 자세한 설명은 다음 링크를 참조하세요: </p>
            +        <p>스크린 리더에서 p5를 사용하는 방법</p>
            +        <h3 class="sr-only">스크린리더 사용자를 위한 참고 사항</h3>
            +        <p>If you are using a screen reader, you must turn on the accessible outputs in the p5 online editor, outside the editor you must add the accessibility library in your html. To learn more visit&#32;<a href="../learn/p5-screen-reader.html" target="_blank">접근성 라이브러리란?.</a>
            +        </p>
            +        <p>캔버스에 폭과 높이가 50인 타원이 x 80, y 80의 위치에 그려져있다</p>
            +
            +        <img src="../../assets/img/get-started/first-sketch.png" alt='코드를 잘못 입력할 경우 화면에 아무것도 나타나지 않을 수 있습니다. 예제 코드를 정확히 따라 썼는지 확인해 보세요. 숫자는 (괄호) 안에 포함하고, 각 숫자는 쉼표(,)로 구분해야 하며, 각 라인은 세미 콜론(;)으로 끝나야 합니다'/>
            +
            +        <p>프로그래밍 언어를 처음 접할 때 겪는 어려움 중 하나는 바로 까다로운 문법입니다. 브라우저는 우리가 표현하려는 게 무엇인지 스스로 파악할 정도로 똑똑하지 않으며, 각 요소의 위치와 구두법에 매우 민감하답니다. 처음에는 이런 문법이 낯설게 느껴지겠지만, 연습을 통해 점차 익숙해질 것입니다. 몇몇 브라우저는 코드 내 오류를 확인할 수 있는 자바 스크립트 '콘솔'을 제공합니다. 크롬(Chrome)의 경우, 보기 > 개발자 > 자바 스크립트 콘솔을 클릭하여 '콘솔'을 활성화할 수 있습니다.</p>
            +
            +        <p>이제 한층 더 재밌는 스케치를 만들어볼까요! 지난 예제의 코드를 에디터에서 삭제하고 아래의 코드를 입력해 보세요:</p>
            +
            +        <h3 class="sr-only">인터랙션과 코드 스니펫</h3>
            +        <p>이제 프로그램은 폭 640px, 높이 480px의 캔버스를 생성하고, 마우스 커서 위치에서 흰 원을 그리기 시작합니다. 마우스 버튼을 누르고 있을 때는 원의 색이 검정색으로 바뀝니다. 마우스 위치에 대한 설명은 나중에 더 하기로 하고, 지금은 마우스를 움직이고 클릭하며 스케치의 변화를 살펴보세요.</p>
            +
            +<pre id="first-sketch3"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  if (mouseIsPressed) {
            +    fill(0);
            +  } else {
            +    fill(255);
            +  }
            +  ellipse(mouseX, mouseY, 80, 80);
            +}
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch3" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">캔버스 위의 마우스 궤적을 따라 여러 개의 원이 그려집니다:
            +        </p>
            +
            +        <img src="../../assets/img/get-started/first-sketch2.png" alt='캔버스 위의 마우스 궤적을 따라 여러 개의 원이 그려집니다.'/>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="next">다음 단계</h2>
            +
            +      <div class='info'>
            +        <ul class="list_view">
            +          <li>더 많은 정보는 <a href="../learn/">배우기</a>와 <a href="../examples">예제</a>에서 확인할 수 있습니다.</li>
            +
            +          <li>또, <a href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6Zy51Q-x9tMWIv9cueOFTFA">코딩 트레인(The Coding Train)</a>과 <a href="https://www.kadenze.com/courses/introduction-to-programming-for-the-visual-arts-with-p5-js/info">Kadenze</a>의 비디오 튜토리얼을 참고하세요.</li>
            +
            +          <li>p5.js의 모든 함수 및 메소드, 그 외 문서는 <a href="../reference/">레퍼런스</a>에서 확인하세요. </li>
            +          <li>스크린 리더와 함께 p5를 사용하고 싶다면 다음을 확인하세요: <a href="../learn/p5-screen-reader.html">스크린 리더 기반 p5 튜토리얼</a>.</li>
            +          <li>프로세싱을 p5.js로 전환하는 방법과 둘 간의 차이점이 궁금하다면, <a href='https://github.com/processing/p5.js/wiki/Processing-transition'>프로세싱 스케치를 p5.js로 변환하기 튜토리얼</a>을 읽어보세요.</li>
            +
            +        </ul>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="settingUp">데스크탑 에디터에 p5.js 설정하기</h2>
            +
            +      <div class="info">
            +        <p>여러분이 사용하는 그 어떠한 
            +          <a href='http://en.wikipedia.org/wiki/Source_code_editor' target="_blank">
            +            코드 에디터</a>
            +            에서든 p5.js를 쓸 수 있습니다. 아래에 
            +            <a href="http://www.sublimetext.com/2" target="_blank"> Sublime Text 2</a>
            +             에디터를 설정하는 방법이 있습니다. 추천하는 또다른 에디터: <a href='http://brackets.io/' target=_blank>Brackets</a> , <a href='https://atom.io/' target=_blank>Atom</a>.  p5 웹에디터는 스크린 리더 기능을 제공합니다. 웹에디터를 사용하지 않는 스크린 리더라면 다음의 데스크탑 에디터를 고려해보세요:  <a href="https://notepad-plus-plus.org/">Notepad++</a>  나 
            +            <a href="https://www.eclipse.org/ide/" target="_blank">Eclipse</a>.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="download">다운로드 & 파일 설정</h3>
            +
            +      <div class="info">
            +        <p>The easiest way to start is by using the empty example that comes with the 
            +          <a href="../download/">p5.js complete</a>
            +          파일을 다운받아 시작하는 것이 가장 쉽고 간편합니다.
            +        </p>
            +
            +        <p>
            +          다운로드 후에는 로컬 서버를 설정해야 합니다. 
            +          <a href="https://github.com/processing/p5.js/wiki/Local-server" target="_blank">로컬 서버 설정 방법</a>
            +          을 참고하세요. 다운로드 폴더를 사용하여 인터넷 브라우저에서 다음과같이 로컬 서버를 실행하세요. 
            +          <code>http://localhost:{당신의-포트(port)-넘버}/empty-example</code>
            +        </p>
            +
            +        <p>다운로드 파일 중, index.html 파일에는 p5.js 링크가 적혀있습니다. 로딩 시간을 단축하려면 해당 p5.js 링크를 그 간략 버전인 p5.min.js로 아래와 같이 변경하면 됩니다. </p>
            +
            +        <pre id="markup1"><code class="language-markup">&lt;script src="../p5.min.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_script" class="copy_button">Copy</button>
            +        </div>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="hosted">호스팅된 p5.js 라이브러리 사용하기</h3>
            +      <div class="info">
            +        <p>p5.js 파일의 온라인 링크를 직접 입력하는 방법도 있습니다. p5.js의 모든 버전은 CDN(Content Delivery Network)에 저장되어 있으며, 버전 히스토리는 여기서 확인할 수 있습니다: 
            +          <a target="_blank" href="https://cdn.jsdelivr.net/npm/p5/lib/">
            +            p5.js CDN</a>. 링크를 다음과 같이 변경해보세요:
            +        </p>
            +
            +        <pre id="cdn-link" class='p5-replace'><code class="language-markup">&lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_link" class="copy_button">Copy</button>
            +        </div>
            +        <p>아래는 HTML 페이지 샘플입니다:</p>
            +
            +        <pre id="sample-html" class='p5-replace'><code class="language-markup">
            +&lt;html&gt;
            +  &lt;head&gt;
            +    &lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script&gt;
            +    &lt;script src="sketch.js">&lt;/script&gt;
            +  &lt;/head&gt;
            +  &lt;body&gt;
            +    &lt;main&gt;
            +    &lt;/main&gt;
            +  &lt;/body&gt;
            +&lt;/html&gt;
            +        </code></pre>
            +      <div class="edit_space">
            +          <button id="copy_p5_html" class="copy_button">Copy</button>
            +      </div>
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="environment">개발 환경</h3>
            +      <div class="info">
            +        <p>
            +          먼저, Sublime Text 2 에디터 프로그램을 실행하세요. File 메뉴를 열고 Open을 클릭한 후, html 파일과 js 파일이 위치한 폴더를 선택하세요. 해당 폴더의 이름과 더불어 포함된 파일 리스트가 좌측 사이드바에 보일 것입니다.
            +        </p>
            +
            +        <p>
            +          sketch.js 파일을 선택하면, 우측 편집 영역에서 파일이 열립니다. 
            +          <img src="../../assets/img/get-started/sublime2.png" alt='Sublime 에디터에서 p5 템플릿 코드를 편집 중인 화면"'/>
            +        </p>
            +
            +        <p>
            +          index.html 파일을 브라우저에서 열어볼까요? 파일 관리 시스템에서 index.html 파일을 더블 클릭하거나 브라우저 주소창에 다음을 입력하세요: <code>file:///나의/html/경로</code>
            +           (또는, 로컬 서버 사용시,  <code>http://localhost:{당신의-포트(port)-넘버}/empty-example</code>
            +          )
            +           
            +        </p>
            +      </div>
            +
            +      <div>본 튜토리얼의 일부는 로렌 맥카시(Lauren McCarthy), 캐시 리스(Casey Reas), 벤 프라이(Ben Fry), 오라일리(O'Reilly) 저 Getting Started with p5.js 에서 발췌하였습니다. / Make 2015. Copyright </div>
            +
            +      <script>
            +        $.getJSON('../download/version.json', function(data) {
            +          $('.p5-replace').each(function() {
            +            var html = $(this).html().replace('[p5_version]', data.version);
            +            $(this).html(html);
            +          });
            +        });
            +      </script>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +</div><!-- end id="get-started-page"  -->
            +<script src="/../../assets/js/get-started.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/index.html b/dist/ko/index.html
            new file mode 100644
            index 0000000000..dfd4c4119e
            --- /dev/null
            +++ b/dist/ko/index.html
            @@ -0,0 +1,177 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">home | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<div id="home-page">
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content" class="home">
            +      <form id="search" method="get" action="https://www.google.com/search">
            +        <input type="hidden" name="as_sitesearch" value="p5js.org">
            +        <input id="search_button" type="submit" aria-label="Search" class='sr-only'>
            +        <input tabindex="2" id='search_field' type="text" size="20" placeholder="Search p5js.org" name="q">
            +        <label class="sr-only" for="search_field">Search p5js.org</label>
            +      </form>
            +
            +      <h1>안녕하세요!</h1>
            +      <p style="margin-top:1em">p5.js는 크리에이티브 코딩을 위한 자바스크립트 라이브러리로, 예술가, 디자이너, 교육자, 입문자, 그리고 모두에게 접근성 높고 포용적인 언어를 지향합니다! p5.js는 무료 오픈 소스로 제공됩니다. 소프트웨어와 그 학습 도구가 모두에게 열려있어야 된다고 믿기 때문입니다.</p>
            +      <p>p5.js는 마치 스케치북과도 같으며 다양한 드로잉 기능을 제공합니다. p5.js를 이용하면 인터넷 브라우저 전체를 스케치북 삼아 그릴 수 있을 뿐 아니라, 텍스트, 입력, 비디오, 웹캠, 그리고 사운드 등을 비롯한 각종 HTML 요소를 사용할 수 있습니다.</p>
            +      <p><a href="https://discord.gg/SHQ8dH25r9">Join the p5.js Discord!</a></p>
            +      <a href="https://editor.p5js.org"><span class='button_box'>p5 에디터로 프로젝트 시작하기</span></a>
            +
            +      <h2>커뮤니티</h2>
            +      <p>우리는 다양한 성 정체성, 젠더 표현, 성적 지향, 인종, 민족, 언어, 사회, 규모, 능력, 계급, 종교, 문화, 하위 문화, 정치 성향, 나이, 기술적 숙련도, 직업 등의 배경을 가진 사람들의 공동체이자 연대입니다. 모든 사람이 우리 커뮤니티에 시간과 에너지를 쓸 수 있는 게 아닌 만큼, 우리는 여러분의 참여를 환영하고 독려하며, 또 접근성을 향상하기 위해 늘 노력합니다. 우리 모두는 언제나 배우는 자들입니다.</p>
            +      <p>p5.js는 프로세싱 <a href="https://processing.org"
            +          target="_blank">Processing</a> 을 오늘날의 웹에 맞게 해석한 것입니다. p5의 행사와 모임은 프로세싱 재단 <a href="https://processingfoundation.org"
            +          target="_blank">Processing Foundation</a> 의 지원을 받아 개최됩니다.</p>
            +      <p>Learn more about <a href="community/">커뮤니티</a>에 대해 더 알아보세요.</p>
            +
            +      <h2>시작하기</h2>
            +      <p>온라인 에디터인 <a href="https://editor.p5js.org" target="_blank">p5.js
            +          Editor</a>에서 나만의 첫 스케치를 그려보세요! <a
            +          href="get-started/">시작하기</a>에서 p5 스케치에 대해 알아보고, <a
            +          href="reference/">레퍼런스</a>로 더욱 많은 기능을 확인해보세요.</p>
            +
            +      <h2>기여하기</h2>
            +      <p>p5.js와 커뮤니티에 기여할 수 있는 방법은 다양합니다:</p>
            +      <h2 id="involvement-options" class="sr-only">기여 방법</h2>
            +      <ul aria-labelledby="involvement-options" class="list_view bullets">
            +        <li><a href="/ko/teach">p5 워크숍 또는 수업 운영하기</a></li>
            +        <li><a href="https://day.processing.org" target="_blank">행사 또는 모임 주관하기</a></li>
            +        <li><a href="https://github.com/processing/p5.js/tree/main/contributor_docs"
            +            target="_blank">코딩 개발로 기여하기</a></li>
            +      </ul>
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +  </div> <!-- end column-span -->
            +
            +
            +  <p class="clearfix">&nbsp;</p>
            +
            +  <object tabindex=-1 type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element"
            +    aria-hidden="true">*</object>
            +</div> <!-- end home-page -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/basics.html b/dist/ko/learn/basics.html
            new file mode 100644
            index 0000000000..b5c6cb1495
            --- /dev/null
            +++ b/dist/ko/learn/basics.html
            @@ -0,0 +1,348 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +<style>
            +img {
            +  width: 50%;
            +}
            +</style>
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Basics of Drawing</h1>
            +
            +      <h2>Introduction</h2>
            +      <p>
            +      Today we are going to be learning how to write computer code using a tool called <a href='http://p5js.org' target=_blank>p5</a>. Code is a set of instructions for the computer, telling it something to do. In our case, we will tell it to make a scene with shapes and colors.
            +      </p>
            +
            +
            +      <h2>First Sketch</h2>
            +      <p>
            +      When you open p5, your first sketch will look like this. There are two parts: setup and draw. Inside the curly brackets after setup and draw we will add code to create a drawing.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +
            +}
            +      </script>
            +
            +      <h2>background(red, green, blue)</h2>
            +      <p>
            +      background() sets the background color of your drawing. You give it three numbers that represent the amount of red, green, and blue you want mixed into the background. The numbers range from 0-255.
            +      <span class='try'>Try changing the numbers inside the parentheses to see what happens.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +
            +      <h2>createCanvas(width, height)</h2>
            +      <p>
            +      createCanvas() sets the size of the drawing canvas. By default it is 100x100. You give it two numbers that represent the width and the height that you want your canvas to be.
            +      <span class='try'>Try making your canvas different sizes by changing the width and height.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100)
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +      <h2>line(x1, y1, x2, y2)</h2>
            +      <p>
            +      line() draws a line on your canvas. You give it four numbers – the x and y position of one end, and the x and y position of the other end.<br>
            +      <img src='../../assets/learn/basics/line.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 200, 255)
            +  line(10, 10, 200, 200)
            +}
            +      </script>
            +
            +      <h2>rect(x, y, width, height)</h2>
            +      <p>
            +      rect() draws a rectangle on your canvas. You give it four numbers – the x position, the y position, the width, and the height. For a rectangle, you give it the x,y position of the top left corner.<br>
            +      <img src='../../assets/learn/basics/rect.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(55, 100, 255)
            +  rect(10, 10, 50, 200)
            +}
            +      </script>
            +
            +      <h2>ellipse(x, y, width, height)</h2>
            +      <p>
            +      To draw a shape, think of your canvas like a piece of graph paper. However, square (0, 0) is in the top left.
            +      <br>
            +      <img src='../../assets/learn/basics/graph.svg'>
            +      ellipse() draws an ellipse on your canvas. You give it four numbers – the x position, the y position, the width, and the height.<br>
            +      <img src='../../assets/learn/basics/ellipse.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 0, 255)
            +  ellipse(150, 150, 100, 200)
            +}
            +      </script>
            +
            +      <h2>fill(red, green, blue)</h2>
            +      <p>You can set the color of your shapes by using fill(). You give it three numbers – the red, green, and blue mixture you want, just like background.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>stroke(red, green, blue)</h2>
            +      <p>You can set the outline color of your shapes by using stroke(). You give it three numbers – the red, green, and blue mixture you want, just like fill() and background().
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  stroke(0, 150, 0)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>strokeWeight(weight)</h2>
            +      <p>You can set the thickness of the outline for your shapes by using strokeWeight(). The default stroke weight is 1.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  strokeWeight(10)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>mouseX, mouseY</h2>
            +      <p>mouseX and mouseY can be used to get the current position of your mouse. They are called <b>variables</b>. You can replace a number in your code with mouseX or mouseY and that number will change as you move your mouse.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +      <h2>random(max)</h2>
            +      <p>random() will choose a random number for you, anywhere from 0 - max.</p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(random(255), random(255), random(255))
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +
            +      <h2>Links</h2>
            +      <p><a href='http://p5js.org/reference' target=_blank>Reference</a> – available p5.js variables and functions<br>
            +      <a href='http://p5js.org/examples' target=_blank>Examples</a> – more complicated code examples</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/color.html b/dist/ko/learn/color.html
            new file mode 100644
            index 0000000000..2c3763c5aa
            --- /dev/null
            +++ b/dist/ko/learn/color.html
            @@ -0,0 +1,293 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">이 튜토리얼은 다니엘 쉬프만(Daniel Shiffman) 저, 모건 카우프만(Morgan Kaufmann) 출판 도서 Learning Processing에서 발췌하였습니다 © 2008 Elsevier Inc. 또한, 발췌본은 켈리 장(Kelly Chang)에 의해 p5로 옮겨졌습니다. 오류를 발견하거나 의견을 남기고 싶다면 <a href="https://github.com/processing/p5.js/issues">언제든 알려주세요.</a>
            +
            +      </div>
            +
            +      <h1>색상</h1>
            +
            +      <p>
            +      디지털 세상에서 색상에 대해 이야기할 땐, 아주 정밀한 표현이 필요합니다. 아쉽게도, "푸른빛의 초록색 원을 만들 수 있어?" 와 같은 표현은 통하지 않습니다. 이 곳에서의 색상은 언제나 숫자와 범위값에 의해 정의됩니다. 간단한 예시로 시작해볼까요. 검정색, 하얀색, 또는 회색 음영. 0은 검정색을, 255은 하얀색을, 그리고 그 사이에 존재하는 50, 87, 162, 209와 같은 다른 숫자들은 흑과 백 사이의 회색 음영을 뜻합니다.
            +      </p>
            +
            +      <img src="../../assets/learn/color/grayscale.svg">
            +
            +      <p>
            +      도형을 그리기에 앞서 선그리기<a href="/ko/reference/#/p5/stroke"> stroke()</a> 와 면채우기<a href="/ko/reference/#/p5/fill">fill()</a> 함수를 사용하면 색상을 지정할 수 있습니다. 또, 배경<a href="/ko/reference/#/p5/background">background()</a> 함수를 통해 윈도우창의 배경색을 지정할 수 있습니다. 한 번 예시를 볼까요.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        background(255);    // 배경색을 하얀색으로 정하기 
            + stroke(0);          // 윤곽선(stroke)색을 검정색으로 정하기 
            + fill(150);          // 면(fill)색을 회색으로 정하기 
            + rect(50,50,75,100); // 사각형 그리기
            +      </code></pre>
            +
            +      <p>
            +      선그리기(Stroke)나 면채우기(fill)는 다음의 함수를 통해 제거할 수 있습니다: <a href="/ko/reference/#/p5/noStroke">noStroke()</a> 과<a href="/ko/reference/#/p5/noFill">noFill()</a>. 본능적으로 우리는 "stroke(0)" 를 통해 윤곽선을 제거할 수 있을 거라 생각하지만, 코딩 언어의 세계에서 0은 "아무것도 없음"이 아니라, 검정색을 지칭합니다. <b>noStroke()</b> 과 <b>noFill()</b>를 사용하면 선도 색상도, 아무것도 보이지 않을 거에요!
            +      </p>
            +
            +      <p>또한, 두개의 도형을 그릴 때 p5.js는 가장 마지막 줄에 지정된 stroke와 fill을 반영합니다. 코드를 위에서부터 아래로 읽고 수행하기 때문이지요.</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +  background(150);
            +  stroke(0);
            +  line(0, 0, 100, 100);
            +  stroke(255);
            +  noFill();
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <h2>RGB 색상</h2>
            +
            +      <p>
            +      어린 시절 손가락으로 물감을 섞어본 기억이 있나요? 세가지의 "원색"을 사용하면, 그 어떠한 색상도 만들어 낼 수 있었지요. 여러가지 물감을 섞다보면 진흙빛의 갈색이 탄생하기도 합니다. 물감을 더할 수록 색이 어두워지고요. 디지털 색상들 역시 삼원색을 섞는 원리를 바탕으로 만들어졌지만, 물감과는 또다르게 작동합니다. 먼저, 디지털 색상에서의 삼원색은 빨강(red), 초록(green), 파랑(blue) (일명, "RGB" 색상)을 뜻합니다. 또, 화면상 보이는 색상은 기본적으로 물감이 아닌 빛의 조합입니다. 따라서, 색상이 조합되는 방식이 다른 것이지요.
            +      </p>
            +
            +      <img src="../../assets/learn/color/rgb.jpg">
            +      <p>
            +        <ul class="list_view">
            +          <li>빨강 + 초록 = 노랑</li>
            +          <li>빨강 + 파랑 = 보라</li>
            +          <li>초록 + 파랑 = 청록</li>
            +          <li>빨강 + 초록 + 파랑 = 하양</li>
            +          <li>무채색 = 검정</li>
            +        </ul>
            +      </p>
            +
            +      <p>이는 디지털 색상을 밝은 빛으로서 가정하는 데에서 비롯된 것인데, 색상 범위를 조정하여 원하는 색을 만들 수 있습니다. 예를 들어, 빨강색에 초록색, 파랑색을 더하면 회색이 됩니다. 그리고 약간의 빨강색에 약간의 파랑색을 더하면 어두운 보라색이 됩니다. RGB 색상을 더 많이 프로그래밍하고 실험할수록, 손가락으로 물감을 휘젔던 색상 본능만큼 디지털 색상에 따른 본능 역시 커질 것입니다. 한편, 우리는 "빨강색 적당하게 쓰고 여기에 약간의 파란색을 섞어줘"라는 식으로도 말할 수 없습니다. 반드시 정확한 양을 지정해야합니다. 회색 음영과 마찬가지로, 각각의 색상 요소는 0(색상 0가지)부터 255(최대한 많은 색상 수)에 이르는 범위 내에서 표현됩니다. 그리고 R, G, B의 순서에 따라 정렬됩니다. 이번엔 좀 더 일반적인 색상에 대해 알아볼까요</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  noStroke();
            +
            +  // Bright red
            +  fill(255,0,0);
            +  ellipse(20,20,16,16);
            +
            +  // Dark red
            +  fill(127,0,0);
            +  ellipse(40,20,16,16);
            +
            +  // Pink (pale red)
            +  fill(255,200,200);
            +  ellipse(60,20,16,16);
            +}
            +      </script>
            +
            +
            +
            +      <h2>색상 투명도</h2>
            +
            +      <p>R, G, B값에 더해, 각 색상을 구성하는 네 번째 요소가 있습니다. 일명 "알파(alpha)값"인데요, 알파는 색상의 투명도를 말하고, 한 도형 위에 다른 도형을 얹을시 겹치는 지점을 보이게 할 때 유용하겠지요? 한 이미지에 대한 여러 알파값들을 통칭 "알파 채널(alpha channel)"이라 부르기도 합니다.</p>
            +      <p>픽셀은 그 자체로는 투명하지 않아요. 다만, 여러가지 색상을 섞어 마치 투명해보이는 듯한 착시현상을 만드는 것이지요. 이처럼 p5.js는 한 색상값과 다른 색상값들 간의 비율차를 이용하여 마치 이들이 섞인것처럼 보이게 만든답니다. (만약 여러분이 "장밋빛" 안경을 프로그래밍하고자 했다면 바로 이 지점부터 이해하고 넘어가면 되겠지요?)</p>
            +
            +      <p>알파값은 0부터 255 사이 조정가능합니다. 0은 완전히 투명한 상태(즉, 0% 투명도)이고 255는 완전히 불투명한 상태(즉, 100% 투명도)입니다.</p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +  createCanvas(100, 100);
            +  fill(0,0,255);
            +  rect(0,0,50,100);
            +
            +  // 255 means 100% opacity.
            +  fill(255,0,0,255);
            +  rect(0,0,100,20);
            +
            +  // 75% opacity.
            +  fill(255,0,0,191);
            +  rect(0,25,100,20);
            +
            +  // 55% opacity.
            +  fill(255,0,0,127);
            +  rect(0,50,100,20);
            +
            +  // 25% opacity.
            +  fill(255,0,0,63);
            +  rect(0,75,100,20);
            +
            +      </script>
            +
            +      <h2>색상 조정 범위</h2>
            +
            +      <p>
            +       p5.js에서 다룰 수 있는 색채는 0부터 255까지에 이르는 RGB뿐만이 아닙니다. 사실 우리가 원하는대로 그 범위를 조정할 수도 있지요! 예를 들어, 색상 범위를 마치 퍼센티지처럼 0부터 100으로 설정할 수도 있습니다. 색상 범위 커스터마이징은 다음의 간단한 함수를 통해 가능합니다:<a href="/ko/reference/#/p5/colorMode">colorMode()</a>.
            +      </p>
            +
            +      <pre><code>
            +      colorMode(RGB,100);
            +      </code></pre>
            +
            +      <p>위의 함수는: "난 RGB색상에 대해 조정하고싶고, 그 색상 범위는 0부터 100으로 설정하고 싶어"라고 말하는 것입니다.</p>
            +
            +      <p>조금 더 복잡하긴 하지만, 아래와 같은 방법을 통해 R, G, B 각 색상별로도 조정 범위를 설정할 수 있습니다:</p>
            +
            +      <pre><code>
            +      colorMode(RGB,100,500,10,255);
            +      </code></pre>
            +
            +      <p>위의 내용은 "빨강(R)은 0부터 100까지, 초록(G)은 0부터 500가지, 파랑(B)은 0부터 10까지, 그리고 투명도는 0부터 255까지 설정하고 싶어"라고 말하는 것이지요.</p>
            +
            +      <p>여러분은 사실상 RGB값 설정만으로도 프로그래밍에 필요한 모든 색상을 누릴 수 있을텐데요, 마지막으로 RGB 외에 조정할 수 있는 색상 요소인 HSB(색조 Hue, 채도 Saturation, 밝기 Brightness)를 소개합니다</p>
            +
            +      <img src="../../assets/learn/color/hsb.png">
            +      <ul class="list_view">
            +        <li><b>색조 Hue</b>—색상의 종류, 기본 범위 0부터 360까지</li>
            +        <li><b>채도 Saturation</b>—색상의 생생함 정도, 기본 범위 0부터 100까지</li>
            +        <li><b>밝기 Brightness</b>—(당연히) 색상의 밝은 정도, 기본 범위 0부터 100까지</li>
            +      </ul>
            +
            +      <p>이 <a href="/ko/reference/#/p5/colorMode">colorMode()</a> 함수를 이용하여 HSB값 범위 또한 설정할 수 있습니다. 어떤 사람들은 색조(Hue)를 0부터 360까지 설정하거나(위의 사진처럼 360도의 둥근 색상띠가 생각나지요), 채도와 밝기는 0부터 100까지 설정(0-100% 퍼센티지와 유비되지요)하는 것을 선호하기도 합니다.</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/coordinate-system-and-shapes.html b/dist/ko/learn/coordinate-system-and-shapes.html
            new file mode 100644
            index 0000000000..5f1dbf8af5
            --- /dev/null
            +++ b/dist/ko/learn/coordinate-system-and-shapes.html
            @@ -0,0 +1,279 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      이 튜토리얼은 다니엘 쉬프만(Daniel Shiffman)저, 모건 카우프만(Morgan Kaufmann) 출판 도서 <em>Learning Processing</em> 에서 발췌하였습니다.by © 2008 Elsevier Inc. All rights reserved. 또한 발췌본은 알렉스 이쑤안 쑤(Alex Yixuan Xu)에 의해 p5로 옮겨졌습니다. 오류를 발견하거나 의견을 남기고 싶다면 <a href="https://github.com/processing/processing-docs/issues?state=open">언제든 알려주세요</a>.</div>
            +
            +      <h1>좌표와 도형</h1>
            +      <p>p5로 프로그래밍을 시작하기 전에, 먼저 중학교 2학년 시절의 우리를 떠올리며 연습장에 선 하나를 그려볼까요? 두 개의 점을 그린 뒤 그 사이를 연결하면 하나의 선분이 탄생합니다. 연습장 위 이 두개의 점과 둘간을 연결하는 선. 바로 여기가 우리의 시작점입니다.</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-01.png" alt="">
            +
            +      <p>여기 점A(1,0)과 점B(4,5) 사이의 선 하나가 보입니다. 만약 똑같은 선을 친구가 그릴 수 있게하려면 "1콤마 0에서 시작하는 점에서부터 4콤마 5를 향해 선을 그려죠"라고 말하겠지요. 이제 그 친구가 컴퓨터라고 가정해볼까요? 우리의 컴퓨터 친구도 똑같은 선을 그리게 하려면 위와 동일한 문장을 입력하면 됩니다. 좀 더 구체적인 형식을 갖춰 컴퓨터 친구에게 말을 건네볼까요?</p>
            +
            +      <pre><code class="language-javascript">
            +        line(1,0,4,5);
            +      </code></pre>
            +
            +      <p>코딩 문법에 대해 익숙하지 않더라도 위 문장의 뜻을 어느정도 감잡을 수 있습니다. 우리는 일명 "함수"라 불리는 명령문을 통해 컴퓨터와 대화하는 셈입니다. 여기서 "line"은 선을 그리는 함수입니다. 여기에 더해, 우리는 이 함수 내에서 구체적인 인수(argument)를 지시할 수 있습니다. 예를 들어, 점 A (1,0)부터 점 B (4,5)까지라는 인수를 함수 괄호 안에 포함 시킨 것이지요. 코드 한 줄을 하나의 문장으로 본다면, 함수는 동사(verb)이고 인수는 목적어(object)인 셈입니다. 단, 코드는 문장과 달리 마침표가 아니라 "세미콜론(;)"으로 끝나는 점 주의하세요!</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-02.png" alt="">
            +
            +      <p>컴퓨터 화면은 그저 좀 더 멋진 모양새를 갖춘 연습장과도 같습니다. 화면상의 각 픽셀은 x값(가로)과 y값(세로)이라는 두개의 숫자가 합쳐진, 하나의 좌표값과도 같습니다. 그리고 이 좌표로 화면이라는 공간 내의 위치를 정하지요. 이제 우리는 이 픽셀 좌표값에 모양과 색상을 더하면 됩니다.</p>
            +
            +      <p>한가지 주의사항! 우리가 중학교 2학년 때 배운 "직교 좌표계"는 (0,0)을 중심에 두고, y축을 그 중심에서 위로, 그리고 x축을 중심으로부터 오른쪽을 향해 뻗어나갑니다(양수일 경우엔 이러하고, 음수일 경우 각각 아래와 왼쪽을 향하지요.) 하지만, 컴퓨터 화면 속 픽셀 좌표계에서의 y축은 그 반대로 적용됩니다. 픽셀 좌표계의 (0,0)은 화면상 좌측 최상단에 위치하고, y값이 증가할 수록 아래를 향해 내려옵니다. x값은 그대로 오른쪽을 향해 증가합니다.</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-03.svg" alt="">
            +
            +      <h2>간단한 도형</h2>
            +      <p>여러분이 앞으로 마주할 p5 기반 프로그래밍 예제들은 본질적으로 시각적이고 조형적입니다. 다음 예제들의 핵심은 모양을 그리고 픽셀을 설정하는 데에 있습니다. 4개의 기본 도형을 살펴보며 시작해볼까요!</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-04.png" alt="">
            +
            +      <p>위의 모양들을 그리기 위해 필요한 위치와 크기(그 다음, 색상까지도) 정보가 무엇일지 고민해볼까요. 아래의 도식들을 보면, 우리는 먼저 너비 100 픽셀 그리고 높이 100 픽셀에 해당하는 창을 만듭니다.</p>
            +
            +      <p>점그리기를 뜻하는 <a href="/reference/#/p5/point">point()</a> 함수는 우리가 그릴 수 있는 가장 쉬운 모양이자, 좋은 시작점이 됩니다. 점을 그리기 위해 우리는 x와 y 좌표값만 정하면 되지요.</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  point(40, 50); // point(x, y)
            +}
            +</script>
            +
            +      <p>선그리기를 뜻하는 <a href="/reference/#/p5/line">line()</a> 함수 역시 아주 어렵진 않습니다. 선을 그리기 위해 우리는 (x1,y1)과 (x2,y2)라는 두개의 좌표값만 필요합니다:</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  line(10, 20, 50, 20); // line(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>사각형 그리기 함수인 <a href="/reference/#/p5/rect">rect()</a>의 경우 약간 복잡합니다. p5에서 사각형은 그것이 그려지기 시작하는 상단 좌측의 좌표값과 더불어 너비(width)와 높이(height)를 정하는 숫자들이 필요합니다.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  rect(10, 20, 40, 30); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>사각형을 그리는 또 다른 방법으로, 중앙값, 너비(width), 높이값(height) 설정하기가 있습니다. 이 경우, 먼저 상단의 setup() 함수에 센터 <a href="/reference/#/p5/CENTER">CENTER</a> 모드를 불러오고, 그 뒤에 사각형의 중앙값, 너비, 높이값을 지정해야 합니다. p5는 대문자와 소문자 구분에 민감하니 주의하세요!</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(30, 20, 40, 20); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>마지막으로, 점 두 개 만으로 사각형을 그리는 방법도 있습니다. 바로, 상단 좌측 코너와 하단 우측 코너의 좌표를 지정하는 것이지요. 여기서 우리가 setup() 함수에 포함시킬 모드는 코너 <a href="/reference/#/p5/CORNERS">CORNERS</a> 입니다. 그 결과물은 위의 예제와 동일합니다.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CORNERS);
            +}
            +function draw(){
            +  rect(10, 10, 50, 30); // rect(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>사각형 그리기에 익숙해졌다면, 타원그리기 <a href="/reference/#/p5/ellipse">ellipse()</a> 는 식은죽 먹기지요. 타원을 그리는 원리는 <a href="/reference/#/p5/rect">rect()</a> 와 거의 동일하나, 다만 동일한 좌표값을 가진 사각형의 경계선 안쪽에 그려진다는 점에서 차이가 있습니다. <a href="/reference/#/p5/ellipse">ellipse()</a> 함수의 기본 모드 설정은 센터 <a href="/reference/#/p5/CENTER">CENTER</a>에 해당합니다. 코너 <a href="/reference/#/p5/CORNER">CORNER</a> 모드로 그리기 위해선 별도 설정이 필요합니다.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CENTER);
            +}
            +function draw(){
            +  ellipse(30, 30, 40, 60); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNER);
            +}
            +function draw(){
            +  ellipse(10, 10, 30, 50); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNERS);
            +}
            +function draw(){
            +  ellipse(10, 10, 40, 50); // ellipse(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>자, 이제 좀 더 완성도있는 그림을 그려볼까요! 아래의 코드는 200x200 픽셀 크기의 캔버스 위에 여러개의 도형을 그립니다. createCanvas() 함수를 사용하여 캔버스의 너비(width)와 높이(height)를 설정할 수 있습니다.</p>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(200, 200);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(100,100,20,100);
            +  ellipse(100,70,60,60);
            +  ellipse(81,70,16,32);
            +  ellipse(119,70,16,32);
            +  line(90,150,80,160);
            +  line(110,150,120,160);
            +}
            +</script>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/curves.html b/dist/ko/learn/curves.html
            new file mode 100644
            index 0000000000..ba907a7686
            --- /dev/null
            +++ b/dist/ko/learn/curves.html
            @@ -0,0 +1,328 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by J David Eisenberg and ported by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +      This work is licensed under a <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"> Creative Commons Attribution-NonCommercial-ShareAlinke 4.0 International License.</a>
            +
            +      </div>
            +
            +      <h1>Curves</h1>
            +
            +      <p>
            +      This short tutorial introduces you to the three types of curves in p5.js: arcs, spline curves, and Bézier curves.
            +      </p>
            +
            +      <h2> Arcs </h2>
            +
            +      <p>
            +      Arcs are the simplest curves to draw, it is defined an arc as a section of an ellipse. You call the function with these parameters:
            +      </p>
            +
            +      <p>
            +      arc (x, y, w, h, start, stop, [mode])
            +      </p>
            +
            +      <p>
            +      The first four parameters (x,y,w,h) define the boundary box for your arc and the next two (start, stop), are the start and stop angles for the arc. These angles are given in radians
            +      and are measured clockwise with zero degrees pointing east and PI radians equals 180°.
            +      </p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +          createCanvas(150,200);
            +          background(150);
            +          stroke(0);
            +          arc(35, 35, 50, 50, 0, PI / 2.0); // lower quarter circle
            +          arc(105, 35, 50, 50, -PI, 0, CHORD);  // upper half of circle
            +          arc(175, 35, 50, 50, -PI / 6, PI / 6, PIE); // 60 degrees
            +          noFill();
            +          arc(105, 105, 100, 50, PI / 2, 3 * PI / 2, OPEN); // 180 degrees
            +        }
            +      </script>
            +
            +      <h2>Spline Curves</h2>
            +
            +      <p>
            +      Arcs are fine, but they’re plain. The next function, curve(), lets you draw curves that aren’t necessarily part of an arc. This function draws what is technically called a Rom-Catmull Spline.
            +      To draw the curve, you must specify the (x, y) coordinates of the points where the curve starts and ends. You must also specify two control points which determine the direction and amount of curvature.
            +      The first two and last two parameters are the control points of the curve.
            +      A call to curve() uses these parameters:
            +      </p>
            +
            +      <p>
            +      curve (cpx1, cpy1, x1, y1, x2, y2, cpx2, cpy2);
            +      </p>
            +
            +      <p>
            +      How do the control points affect the way the curve looks?
            +      </p>
            +
            +      <p>
            +        The tangent to the curve at the start point is parallel to the line between control point one and the end of the curve. The tangent to the curve at the end point is parallel to the line between the start point and control point 2.
            +      </p>
            +
            +      <p>
            +      The following diagram shows a curve and the points can be dragged to show how the control point affects the curve:
            +      </p>
            +
            +      <!-- iframe for the curve and dragging points -->
            +      <iframe src="../../assets/learn/curves/curve_ex/embed.html" width="350" height="350">
            +      </iframe>
            +
            +
            +      <h2>Continuous Spline Curves</h2>
            +
            +      <p>
            +      In isolation, a single curve() is not particularly appealing. To draw a continuous curve through several points, you are better off using the curveVertex() function.
            +      You can only use this function when you are creating a shape with the beginShape() and endShape() functions.In common usage, people use the first point of the curve
            +      as the first control point and the last point of the curve as the last control point.
            +      </p>
            +
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      let coords = [40, 40, 80, 60, 100, 100, 60, 120, 50, 150];
            +
            +      function setup() {
            +        createCanvas(150, 200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        curveVertex(40,40);
            +        curveVertex(40,40);
            +        curveVertex(80,60);
            +        curveVertex(100,100);
            +        curveVertex(60,120);
            +        curveVertex(50,150);
            +        curveVertex(50,150);
            +        endShape();
            +
            +         for (let i = 0; i < coords.length; i+= 2){
            +          ellipse(coords[i], coords[i+1], 10, 10);
            +         }
            +      }
            +      </script>
            +
            +      <h2>Bézier Curves</h2>
            +
            +      <p>
            +        Though better than arcs, spline curves don’t seem to have those graceful, swooping curves that say “art.” For those, you need to draw Bézier curves with the bezier() function.
            +        As with spline curves, the bezier() function has eight parameters, but the order is different. The first two and last two parameters are the start and end points while middle 
            +        four points are the control points.
            +      </p>
            +
            +      <p> bezier(x1, y1, cpx1, cpy1, cpx2, cpy2, x2, y2); </p>
            +
            +      <!-- iframe of Bezier example -->
            +      <iframe src="../../assets/learn/curves/bezier/embed.html" width="400" height="400">
            +      </iframe>
            +
            +      <p>
            +      While it is difficult to visualize how the control points affect a curve(), it is slightly easier to see how the control points affect Bézier curves.
            +      Imagine two poles and several rubber bands. The poles connect the control points to the endpoints of the curve. A rubber band connects the tops of the poles.
            +      Two more rubber bands connect the midpoints of the poles to the midpoint of the first rubber band. One more rubber band connects their midpoints.
            +      The center of that last rubber band is tied to the curve. This diagram helps to explain, the points can be moved to change the curve.
            +    </p>
            +
            +      <!-- image of bezier with lines -->
            +      <img src="../../assets/learn/curves/bezier_with_lines/bezier_with_lines.png" style="width:150px;">
            +
            +      <h2> Continuous Bézier Curves</h2>
            +
            +      <p>
            +      Just as curveVertex() allows you to make continuous spline curves, bezierVertex() lets you make continuous Bézier curves.
            +      Again, you must be within a beginShape() / endShape() sequence. You must use vertex(startX, startY) to specify the starting anchor point of the curve.
            +      Subsequent points are specified with a call to:
            +      </P>
            +
            +      <p>bezierVertex(cpx1, cpy1, cpx2, cpy2, x, y);</P>
            +
            +      <p>
            +      Here is a continuous Bézier curve, but it doesn’t join smoothly. In order to make two curves A and B smoothly continuous, the last control point of A,
            +      the last point of A, and the first control point of B have to be on a straight line.
            +      </P>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +        createCanvas(150,200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        vertex(30, 70); // first point
            +        bezierVertex(25, 25, 100, 50, 50, 100);
            +        bezierVertex(50, 140, 75, 140, 120, 120); // if first 2 numbers are changed to 20, 130 it becomes continuous
            +        endShape();
            +
            +        ellipse(25, 25, 5, 5);
            +        ellipse(100, 50, 5, 5);
            +        ellipse(50, 140, 5, 5);//change to (20, 130, 5, 5) to reflect control point
            +        ellipse(75, 140, 5, 5);
            +      }
            +      </script>
            +
            +      <h2>Summary</h2>
            +        <p>
            +          <ul class="list_view">
            +            <li>Use arc() when you need a segment of a circle or an ellipse. You can’t make continuous arcs or use them as part of a shape.</li>
            +            <li>Use curve() when you need a small curve between two points. Use curveVertex() to make a continuous series of curves as part of a shape.</li>
            +            <li>Use bezier() when you need long, smooth curves. Use bezierVertex() to make a continuous series of Bézier curves as part of a shape.</li>
            +          </ul>
            +        </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/debugging.html b/dist/ko/learn/debugging.html
            new file mode 100644
            index 0000000000..88a71cd444
            --- /dev/null
            +++ b/dist/ko/learn/debugging.html
            @@ -0,0 +1,319 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +        This tutorial was made by the Education Working Group, during the p5.js contributor conference at the Frank-Ratchye Studio for Creative Inquiry, Carnegie Mellon University in May of 2015. The contributors to this tutorial include <a href="http://huah.net/jason/">Jason Alderman</a>, <a href="http://tegabrain.com/">Tega Brain</a>, <a href="http://taeyoonchoi.com/">Taeyoon Choi</a> and <a href="http://luisaph.com/">Luisa Pereira</a>.
            +      </div>
            +      <img src="../../assets/learn/debugging/0-0.jpg" alt="" />
            +
            +      <p>
            +        This is a field guide for debugging for everyone—whether you are beginning to code or whether you have been coding for a long time, this guide breaks down the mysterious process of solving problems.
            +      </p>
            +
            +      <h3 class="start-element tutorial-btn" id="introduction">0. Debugging is a Creative Act</h3>
            +      <div class="info">
            +        <p>At all levels, programmers encounter bugs and will often spend more time debugging than actually programming the application. You can expect to spend a lot of time doing this and so it is important to develop good strategies for identifying and working through bugs as you learn to program in p5.js.</p>
            +        <p>
            +          A bug is a gap between what you think your system is doing, and what it is actually doing. <a target="_blank"
            +          href="https://vimeo.com/channels/debugging" >Clay Shirky aptly describes </a>a bug as "the moment when there is both a technical problem with your code as well as a problem with your mental picture of what is happening in your code." </p>
            +          <img src="../../assets/learn/debugging/0-1.jpg" alt="" />
            +        </p>
            +
            +        <p>You think you are telling the computer one thing, but it is doing something else. It may also be crashing or throwing errors. In order to close the gap, you must investigate. </p>
            +        <p>When you are working on a project, you may play many different roles. You are an architect when designing and planning your program, an engineer when you are developing it. Then you will be an explorer, discovering the problems and errors and testing it in all the situations in which it needs to run. You are trying to find out where it might break. Finally, when debugging you are a detective, trying to figure out how and why things broke.</p>
            +        <img class="small" src="../../assets/learn/debugging/0-3.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-4.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-5.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-6.png" alt="" />
            +
            +        <p>So how can you become a good detective and debug your program? Here are the ten steps that can help you become a good code sleuth. </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="Change Perspectives">1. Change Perspectives.</h3>
            +      <div class="info">
            +        <p>Don't panic.</p>
            +        <p>When you encounter a bug that you do not know how to solve, stop, pause and take a deep breath. Stand up, say hi to the dog, take a walk or if it's late go get some sleep. When you are frustrated, tired and upset, you are not in a good frame of mind to learn or solve a  problem.</p>
            +        <p>To find your errors you will need to change perspectives and become the detective. The goal is to find out what the program IS doing, rather than why it's not doing what it's supposed to. We need to get the computer to show us what it's doing.</p>
            +        <p>The clues are in the values of variables and flow of program.</p>
            +        <img class="small_center" src="../../assets/learn/debugging/1-0.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="problem">2. Observe the problem </h3>
            +      <div class="info">
            +        <p>Walk someone through the issue even if they themselves do not know how to program. If no one is around, draft an email explaining what you have done and breaking down what the problem is.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-1.png" alt="" />
            +        <p>You probably won't need to actually send this email as often the act of writing it will help you to locate and identify what you need to do next. Some programmers have even been known to explain their problem to a friendly inanimate object like a rubber ducky.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-2.png" alt="" />
            +        <p>
            +          This is also a good time to add comments to your code that tell you exactly what each of your functions is doing.
            +          Some coders also print out their code (or a section of it) and go through it line by line, tracing the path of variables and making notes.
            +        </p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-3.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="start">3. Before you start... </h3>
            +      <div class="info">
            +        <p>Before doing anything,  save a copy of your code that you can go back to.  While debugging you are likely to introduce other problems, break things or accidentally delete good work.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/3-1.png" alt="" />
            +        <p>You don't want to make bigger bugs in the process of debugging.</p>
            +        <img class="small_center" src="../../assets/learn/debugging/3-2.png" alt="" />
            +        <p>If you make a mistake or your problem gets more worse, you can always UNDO or revert back to your saved file.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/3-3.jpg" alt="" />
            +        <p>You can try version control such as <a href="http://github.com">GitHub</a>.</p>
            +        <img src="../../assets/learn/debugging/3-4.png" alt="" />
            +        <p>Write a list of what you are trying, so you can keep track of what still needs to be checked. Be  methodical, it will save you a lot of time in the long run.</p>
            +        <p>
            +          Only ever change one thing at a time.
            +          <img class="med_right" src="../../assets/learn/debugging/3-5.jpg" alt="" />
            +          As you debug, you will be turning parts of your code on and off.
            +          Every time you make a change, test your program. If you make multiple changes before testing, you will not know which change has what effect and are likely to break things further.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="basics">4. Check the basics </h3>
            +      <div class="info">
            +        <p>Many bugs end up being very basic mistakes, equivalent to forgetting to plug in the power cord. These mistakes are so obvious they are often invisible. Check the dumb stuff like...</p>
            +        <ul class="list_view">
            +          <li>Are you editing the file that you are actually running (and not, for example, editing the local file, and looking at a different file on the server)?</li>
            +          <li>Are all of your external files where you think they are?</li>
            +          <li>Are your file dependencies correct?</li>
            +          <li>Are there any typos in your paths?</li>
            +          <li>Check your server? etc.</li>
            +        </ul>
            +        <img src="../../assets/learn/debugging/4-1.png" alt="" />
            +        <img src="../../assets/learn/debugging/4-2.png" alt="" />
            +        <img src="../../assets/learn/debugging/4-3.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="blackboxes">5. Black boxes</h3>
            +      <div class="info">
            +        <p>A black box describes any part of your system you do not understand the inner workings of. For example, a library or perhaps a function that you have not written for yourself. Systematically take out each black box one-by-one and run your program. This will help to see if these parts of the program contain the error.</p>
            +        <img class="med_left" src="../../assets/learn/debugging/5-1.jpg" alt="" />
            +        <img class="med_right" src="../../assets/learn/debugging/5-2.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="reporting">6. Add error reporting</h3>
            +      <div class="info">
            +        <p>
            +          <img class="med_right" src="../../assets/learn/debugging/6-1.png" alt="" />
            +          Error reporting is how your program tells you what it is doing.
            +          p5.js comes with some built-in error reporting that will tell you if you have made specific syntax errors.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in your own error reporting using the console.log() function.
            +          <img class="med_right" src="../../assets/learn/debugging/6-2.png" alt="" />
            +          To check your program flow, add in console.log() statements to the parts of your code.
            +          Then when you look at your console you can see the order that things happen and where you encounter problems.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in console.log()s to print out values of variables so that you can see what they are doing.
            +          <img class="med_center" src="../../assets/learn/debugging/6-3.jpg" alt="" />
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="help">7. Search for more help </h3>
            +      <div class="info">
            +        <p>So none of this works? There are many places you can look online to get more help.</p>
            +        <ul class="list_view">
            +          <li>Do a Google search, if you have had this problem chances are many other people will have too.</li>
            +          <li>Search the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> using the p5.js tag.</li>
            +          <li>Search development forums like <a href="http://stackoverflow.com/">Stack Overflow</a>.</li>
            +        </ul>
            +        <p> More general javascript resources:</p>
            +        <ul class="list_view">
            +          <li>First chapter of Bocoup's and Rebecca Murphey's interactive textbook, <a href="http://jqfundamentals.com/chapter/javascript-basics">jQuery Fundamentals</a>.</li>
            +          <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">  Mozilla's JavaScript Guide</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference ">JavaScript Reference </a>(this is really helpful for finding all of the built-in methods for, say a String).</li>
            +        </ul>
            +        <img class="med_center" src="../../assets/learn/debugging/7-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="people">8. Ask people </h3>
            +      <div class="info">
            +        <p>
            +          Still not working?
            +          <img class="med_right" src="../../assets/learn/debugging/8-0.jpg" alt="" />
            +          You can also ask people for help! They might be delighted to help you.
            +        </p>
            +        <p>
            +          Send that email you wrote at the start.<br>
            +          Post to the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> succinctly articulating your problem and what you want to know. <br>
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="prevent">9. Good coding practices and how to prevent bugs!</h3>
            +      <div class="info">
            +        <ul class="list_view">
            +          <li>Do not optimize prematurely. Clear code is more important than high-performing code as you're building your program.</li>
            +          <li>Do not abstract prematurely. You don't need to make functions for things you think you're going to use multiple times...until you actually have to use it more than once.</li>
            +          <li>
            +            Start with pseudocode as comments, then add code underneath each step.<br>
            +            Put console.log()s in your code as you develop (and test frequently—so if something changes, you know what you did since the last time you tested).<br>
            +          </li>
            +        </ul>
            +        <p>ALSO: start with small problems! Do one thing at a time. It's ok to make smaller sketches to test one thing (draw a star! check twitter!) and then voltron them together into a bigger sketch (draw a star that turns red when you have a notification on twitter!)</p>
            +        <img class="med_center" src="../../assets/learn/debugging/9-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="resources">10. More resources </h3>
            +      <div class="info">
            +        <p>
            +          This guide has been inspired by several other fantastic resources on debugging when coding. Some of these are here:
            +        </p>
            +          <ul class="list_view">
            +            <li>Matt Gemmel, <a href="http://mattgemmell.com/what-have-you-tried/">What have you tried?</a></li>
            +            <li>Clay Shirky, <a href="https://vimeo.com/channels/debugging">A brief introduction to debugging</a></li>
            +            <li>Eric Steven Raymond, <a href="http://www.catb.org/esr/faqs/smart-questions.html"> How to ask questions the smart way</a></li>
            +            <li>ITP Residents, <a href="https://docs.google.com/presentation/d/1RXzITwS4otVKnYkuNu2w7CrpYy35WBO2HUlmkSc2p8g/edit?copiedFromTrash#slide=id.g2ffb36b3_0_44">10 Tips for Debugging</a></li>
            +            <li>Rurouni Jones, <a href="http://rurounijones.github.io/blog/2009/03/17/how-to-ask-for-help-on-irc//">How to ask for help on IRC</a></li>
            +          </ul>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/index.html b/dist/ko/learn/index.html
            new file mode 100644
            index 0000000000..b38c470c10
            --- /dev/null
            +++ b/dist/ko/learn/index.html
            @@ -0,0 +1,490 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>배우기</h1>
            +
            +      <p>깊이있고 순차적인 설명과 튜토리얼을 주제별로 제공합니다. p5.js 함수를 종류별로 알고싶다면 
            +        <a href="/ko/examples">예제
            +        </a>를 클릭하세요.
            +      </p>
            +
            +      
            +        <h2 class="tutorial-title">p5.js 소개</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="/ko/get-started/">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>시작하기</h3>
            +                </a>
            +              </div>
            +              <p>p5.js에 오신 것을 환영합니다. <br> 이 페이지는 p5.js 프로젝트 설정을 위한 기본 내용을 다룹니다. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js-overview">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js 주요 기능</h3>
            +                </a>
            +              </div>
            +              <p>p5.js 주요 기능에 대한 개괄 설명을 확인하세요. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Processing-transition">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js와 프로세싱</h3>
            +                </a>
            +              </div>
            +              <p>p5와 프로세싱 간의 주요 차이점, 그리고 변환 방법을 알아보세요. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Local-server">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>로컬 서버 사용하기</h3>
            +                </a>
            +              </div>
            +              <p>맥 OSX, 윈도우, 리눅스 상에서 로컬 서버 설정하기 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js 위키</h3>
            +                </a>
            +              </div>
            +              <p>커뮤니티의 기여로 제작된 레퍼런스와 튜토리얼 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="p5-screen-reader.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5와 스크린 리더</h3>
            +                </a>
            +              </div>
            +              <p>스크린 리더를 위한 p5 설정 방법을 알아보세요. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">p5.js에 연결하기</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>node.js와 socket.io</h3>
            +                </a>
            +              </div>
            +              <p>p5.js로 node.js 서버 사용하기, socket.io로 연결, 통신하기 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">프로그래밍 주제</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Beyond-the-canvas">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>캔버스 너머서</h3>
            +                </a>
            +              </div>
            +              <p>페이지상 캔버스 너머의 요소들 만들고 조작하기 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>3D/WebGL</h3>
            +                </a>
            +              </div>
            +              <p>WebGL 모드 기반의 고급 그래픽 개발하기 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="color.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>색상</h3>
            +                </a>
            +              </div>
            +              <p>디지털 색상 소개 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="coordinate-system-and-shapes.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>좌표와 도형</h3>
            +                </a>
            +              </div>
            +              <p>좌표계를 활용하여 간단한 도형 그리기 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="curves.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>곡선</h3>
            +                </a>
            +              </div>
            +              <p>p5.js상의 곡선 3가지 소개: 아치형 곡선, 스플라인 곡선, 베지어 곡선 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="interactivity.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>인터랙션</h3>
            +                </a>
            +              </div>
            +              <p>마우스 및 키보드 인터랙션 소개 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="program-flow.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>프로그램 흐름</h3>
            +                </a>
            +              </div>
            +              <p>p5.js에서 프로그램 플로우 조정하는 법 소개 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">더 나은 개발자 되기</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="debugging.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>디버깅</h3>
            +                </a>
            +              </div>
            +              <p>모두를 위한 디버깅 필드 가이드 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>ps.js 성능 최적화</h3>
            +                </a>
            +              </div>
            +              <p>더 빠르고 부드러운 코딩을 위한 최적화 팁 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tdd.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>유닛 테스팅 및 테스트 기반 개발</h3>
            +                </a>
            +              </div>
            +              <p>설치로 인한 고통에서 벗어나세요. 유닛 테스팅이란 무엇이고 어떻게 사용하는가? 제작: 앤디 티몬스(Andy Timmons) </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">커뮤니티에 함께하기</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>개발</h3>
            +                </a>
            +              </div>
            +              <p>개발 기여 시작하기 및 둘러보기 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://www.luisapereira.net/teaching/materials/processing-foundation">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5 들여다보기</h3>
            +                </a>
            +              </div>
            +              <p>p5.js 개발용 파일 구조 및 도구에 대한 친절한 소개. 제작: 루이자 페레이라(Luisa Pereira) </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tutorial-guide.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>튜토리얼 만들기</h3>
            +                </a>
            +              </div>
            +              <p>프로그래밍 튜토리얼 제작 가이드. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>라이브러리 만들기</h3>
            +                </a>
            +              </div>
            +              <p>p5.js 추가 라이브러리 만들기 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/interactivity.html b/dist/ko/learn/interactivity.html
            new file mode 100644
            index 0000000000..733c038ad7
            --- /dev/null
            +++ b/dist/ko/learn/interactivity.html
            @@ -0,0 +1,959 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This is based on the Interactivity chapter from the second edition of<em>
            +      <a href="https://processing.org/handbook/">Processing: A Programming Handbook for Visual Designers and Artists</a></em>, published by MIT Press. Copyright 2013 MIT Press. This tutorial was originally written for Processing version 2.0+ but has been ported and updated here for P5 by Alex Yixuan Xu. If you see any errors or have comments, please
            +      <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Interactivity</h1>
            +
            +      <p>The screen forms a bridge between our bodies and the realm of circuits and electricity inside computers. We control elements on screen through a variety of devices such as touch pads, trackballs, and joysticks, but the keyboard and mouse remain the most common input devices for desktop computers. The computer mouse dates back to the late 1960s, when Douglas Engelbart presented the device as an element of the oN-Line System (NLS), one of the first computer systems with a video display. The mouse concept was further developed at the Xerox Palo Alto Research Center (PARC), but its introduction with the Apple Macintosh in 1984 was the catalyst for its current ubiquity. The design of the mouse has gone through many revisions in the last forty years, but its function has remained the same. In Engelbart's original patent application in 1970 he referred to the mouse as an "X-Y position indicator," and this still accurately, but dryly, defines its contemporary use.</p>
            +
            +      <p>The physical mouse object is used to control the position of the cursor on screen and to select interface elements. The cursor position is read by computer programs as two numbers, the x-coordinate and the y-coordinate. These numbers can be used to control attributes of elements on screen. If these coordinates are collected and analyzed, they can be used to extract higher-level information such as the speed and direction of the mouse. This data can in turn be used for gesture and pattern recognition.</p>
            +
            +      <p>Keyboards are typically used to input characters for composing documents, email, and instant messages, but the keyboard has potential for use beyond its original intent. The migration of the keyboard from typewriter to computer expanded its function to enable launching software, moving through the menus of software applications, and navigating 3D environments in games. When writing your own software, you have the freedom to use the keyboard data any way you wish. For example, basic information such as the speed and rhythm of the fingers can be determined by the rate at which keys are pressed. This information could control the speed of an event or the quality of motion. It's also possible to ignore the characters printed on the keyboard itself and use the location of each key relative to the keyboard grid as a numeric position.</p>
            +
            +      <p>The modern computer keyboard is a direct descendant of the typewriter. The position of the keys on an English-language keyboard is inherited from early typewriters. This layout is called QWERTY because of the order of the top row of letter keys. It was developed for typewriters to put physical distance between frequently typed letter pairs, helping reduce the likelihood of the typebars colliding and jamming as they hit the ribbon. This more than one-hundred-year-old mechanical legacy still affects how we write software today.</p>
            +
            +      <h2>Mouse Data</h2>
            +
            +      <p>The variables <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> (note the capital X and Y) store the x-coordinate and y-coordinate of the cursor relative to the origin in the upper-left corner of the display window. To see the actual values produced while moving the mouse, run this program to print the values to the screen:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text("X: "+mouseX, 0, height/4);
            +  text("Y: "+mouseY, 0, height/2);
            +}
            +      </script>
            +
            +      <p>When a program starts, the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> values are 0. If the cursor moves into the display window, the values are set to the current position of the cursor. If the cursor is at the left, the mouseX value is 0 and the value increases as the cursor moves to the right. If the cursor is at the top, the mouseY value is 0 and the value increases as the cursor moves down. If mouseX and mouseY are used in programs without a <a href="/reference/#/p5/draw"> draw()</a> or if <a href="/reference/#/p5/noLoop">noLoop()</a> is run in <a href="/reference/#/p5/setup">setup()</a>, the values will always be 0.</p>
            +
            +      <p>The mouse position is most commonly used to control the location of visual elements on screen. More interesting relations are created when the visual elements relate differently to the mouse values, rather than simply mimicking the current position. Adding and subtracting values from the mouse position creates relationships that remain constant, while multiplying and dividing these values creates changing visual relationships between the mouse position and the elements on the screen. In the first of the following examples, the circle is directly mapped to the cursor, in the second, numbers are added and subtracted from the cursor position to create offsets, and in the third, multiplication and division are used to scale the offsets.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);    // Top circle
            +  ellipse(mouseX+20, 50, 33, 33); // Middle circle
            +  ellipse(mouseX-20, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);   // Top circle
            +  ellipse(mouseX/2, 50, 33, 33); // Middle circle
            +  ellipse(mouseX*2, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <p>To invert the value of the mouse, subtract the mouseX value from the width of the window and subtract the mouseY value from the height of the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  let x = mouseX;
            +  let y = mouseY;
            +  let ix = width - mouseX;  // Inverse X
            +  let iy = height - mouseY; // Inverse Y
            +  background(126);
            +  fill(255, 150);
            +  ellipse(x, height/2, y, y);
            +  fill(0, 159);
            +  ellipse(ix, height/2, iy, iy);
            +}
            +      </script>
            +
            +      <p>The variables <a href="/reference/#/p5/pmouseX">pmouseX</a> and <a href="/reference/#/p5/pmouseY">pmouseY</a> store the mouse values from the previous frame. If the mouse does not move, the values will be the same, but if the mouse is moving quickly there can be large differences between the values. To see the difference, run the following program and alternate moving the mouse slowly and quickly. Watch the values print to the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text(pmouseX - mouseX, 0, height/4);
            +}
            +      </script>
            +
            +      <p>Draw a line from the previous mouse position to the current position to show the changing position in one frame and reveal the speed and direction of the mouse. When the mouse is not moving, a point is drawn, but quick mouse movements create long lines.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(8);
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, mouseY, pmouseX, pmouseY);
            +}
            +      </script>
            +
            +      <p>Use the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables with an if structure to allow the cursor to select regions of the screen. The following examples demonstrate the cursor making a selection between different areas of the display window. The first divides the screen into halves, and the second divides the screen into thirds.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 50) {
            +    rect(0, 0, 50, 100);  // Left
            +  }
            +  else {
            +    rect(50, 0, 50, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 33) {
            +    rect(0, 0, 33, 100);  // Left
            +  }
            +  else if (mouseX < 66) {
            +    rect(33, 0, 33, 100); // Middle
            +  }
            +  else {
            +    rect(66, 0, 33, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <p>Use the logical operator &amp;&amp; with an if structure to select a rectangular region of the screen. As demonstrated in the following example, when a relational expression is made to test each edge of a rectangle (left, right, top, bottom) and these are concatenated with a logical AND, the entire relational expression is true only when the cursor is inside the rectangle.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX > 40) && (mouseX < 80) && (mouseY > 20) && (mouseY < 80)){
            +    fill(255);
            +  }
            +  else {
            +    fill(0);
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>This code asks, "Is the cursor to the right of the left edge and is the cursor to the left of the right edge and is the cursor beyond the top edge and is the cursor above the bottom?" The code for the next example asks a set of similar questions and combines them with the keyword else to determine which one of the defined areas contains the cursor.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX <= 50) && (mouseY <= 50)) {
            +    rect(0, 0, 50, 50);   // Upper-left
            +  }
            +  else if ((mouseX <= 50) && (mouseY > 50)) {
            +    rect(0, 50, 50, 50);  // Lower-left
            +  }
            +  else if ((mouseX > 50) && (mouseY <= 50)) {
            +    rect(50, 0, 50, 50);  // Upper-right
            +  }
            +  else {
            +    rect(50, 50, 50, 50); // Lower-right
            +  }
            +}
            +      </script>
            +
            +      <h2>Mouse buttons</h2>
            +      <p>Computer mice and other related input devices typically have between one and three buttons; p5 can detect when these buttons are pressed with the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> and <a href="/reference/#/p5/mouseButton">mouseButton</a> variables. Used with the button status, the cursor position enables the mouse to perform different actions. For example, a button press when the mouse is over an icon can select it, so the icon can be moved to a different location on screen. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true if any mouse button is pressed and false if no mouse button is pressed. The variable <a href="/reference/#/p5/mouseButton">mouseButton</a> is LEFT, CENTER, or RIGHT depending on the mouse button most recently pressed. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable reverts to false as soon as the button is released, but the <a href="/reference/#/p5/mouseButton">mouseButton</a> variable retains its value until a different button is pressed. These variables can be used independently or in combination to control the software. Run these programs to see how the software responds to your fingers.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(0);   // Black
            +  }
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseButton == LEFT) {
            +    fill(0);   // Black
            +  }
            +  else if (mouseButton == RIGHT) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(126); // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    if (mouseButton == LEFT) {
            +      fill(0);   // Black
            +    }
            +    else if (mouseButton == RIGHT) {
            +      fill(255); // White
            +    }
            +  }
            +  else {
            +    fill(126);   // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>Not all mice have multiple buttons, and if software is distributed widely, the interaction should not rely on detecting which button is pressed.</p>
            +
            +      <h2>Keyboard data</h2>
            +
            +      <p>p5 registers the most recently pressed key and whether a key is currently pressed. The boolean variable <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> is true if a key is pressed and is false if not. Include this variable in the test of an if structure to allow lines of code to run only if a key is pressed. The <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable remains true while the key is held down and becomes false only when the key is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) {  // If the key is pressed,
            +    line(20, 20, 80, 80);      // draw a line;
            +  }
            +  else {                       // Otherwise,
            +    rect(40, 40, 20, 20);      // draw a rectangle.
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 20;
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) { // If the key is pressed,
            +    x++;                      // add 1 to x.
            +  }
            +  line(x, 20, x-60, 80);
            +}
            +      </script>
            +      <!-- made changes about the key variable not guaranteed to be case sensitive in p5 -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable stores a single alphanumeric character. Specifically, it holds the most recently pressed key. However, it is not guaranteed to be case sensitive. To get the proper capitalization, it is best to use it within <a href="/reference/#/p5/keyTyped">keyTyped()</a>. For non-ASCII keys, use the <a href="/reference/#/p5/keyCode">keyCode</a> variable. The key can be displayed on screen with the <a href="/reference/#/p5/text">text()</a> function (p. 150).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  textSize(60);
            +  fill(255);
            +}
            +function draw() {
            +  background(0);
            +  text(key, 20, 75); // Draw at coordinate (20,75)
            +}
            +      </script>
            +
            +      <!-- no differences in "" and '' in p5, made changes -->
            +      <!-- <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. The single quotes signify A as the data type char (p. 144). The expression key == "A" will cause an error because the double quotes signify the A as a String, and it's not possible to compare a String with a char. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyPressed">keyPressed</a> variable to ascertain that the key pressed is the uppercase A.</p> -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. Note the use of double quotation marks or single quotation marks has no influence on the program as long as you are consistent. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable to ascertain that the key pressed is the uppercase A.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +  stroke(255);
            +}
            +function draw() {
            +  background(0);
            +  // If the 'A' key is pressed, draw a line
            +  if ((keyIsPressed == true) && (key == 'A')) {
            +    line(50, 25, 50, 75);
            +  }
            +  else { // Otherwise, draw an ellipse
            +    ellipse(50, 50, 50, 50);
            +  }
            +}
            +      </script>
            +
            +      <p>The previous example works with an uppercase A, but not if the lowercase letter is pressed. To check for both uppercase and lowercase letters, extend the relational expression with a logical OR, the || relational operator. Line 9 in the previous program would be changed to:</p>
            +      <pre><code class="language-javascript">
            +        if ((keyIsPressed == true) &amp;&amp; ((key == 'a') || (key == 'A'))) {
            +      </code></pre>
            +
            +      <!-- changes made -->
            +      <h2>Coded keys</h2>
            +      <p>Because each character has a numeric value as defined by the <a href="https://www.w3schools.com/charsets/ref_html_ascii.asp">ASCII table</a>, the value of the <a href="/reference/#/p5/keyCode">keyCode</a> variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script>
            +
            +      <!--made changes to original content here -->
            +<!--       <p>Because each character has a numeric value as defined by the ASCII table (p. 605), the value of the key variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +      <h2>Coded keys</h2>
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script> -->
            +
            +      <h2>Events</h2>
            +      <p>A category of functions called events alter the normal flow of a program when an action such as a key press or mouse movement takes place. An event is a polite interruption of the normal flow of a program. Key presses and mouse movements are stored until the end of <a href="/reference/#/p5/draw">draw()</a>, where they can take action that won't disturb drawing that's currently in progress. The code inside an event function is run once each time the corresponding event occurs. For example, if a mouse button is pressed, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function will run once and will not run again until the button is pressed again. This allows data produced by the mouse and keyboard to be read independently from what is happening in the rest of the program.</p>
            +
            +      <h2>Mouse events</h2>
            +      <!-- added mouseClicked() mouseOver() mouseOut() doubleClicked()-->
            +      <p>The mouse event functions are <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, <a href="/reference/#/p5/mouseDragged">mouseDragged()</a>, <a href="/reference/#/p5/mouseOver">mouseOver()</a>, and <a href="/reference/#/p5/mouseOut">mouseOut()</a>:</p>
            +
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block is run one time when the mouse is moved while a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>The <a href="/reference/#/p5/mousePressed">mousePressed()</a> function works differently than the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable. The value of the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true until the mouse button is released. It can therefore be used within <a href="/reference/#/p5/draw">draw()</a> to have a line of code run while the mouse is pressed. In contrast, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function only runs once when a button is pressed. This makes it useful when a mouse click is used to trigger an action, such as clearing the screen. In the following example, the background value becomes lighter each time a mouse button is pressed. Run the example on your computer to see the change in response to your finger.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mousePressed() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>The following example is the same as the one above, but the gray variable is set in the <a href="/reference/#/p5/mouseReleased">mouseReleased()</a> event function, which is called once every time a button is released. This difference can be seen only by running the program and clicking the mouse button. Keep the mouse button pressed for a long time and notice that the background value changes only when the button is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseReleased() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <!-- mouseClicked() example added-->
            +      <p>Similarly, the gray variable is set in the <a href="/reference/#/p5/mouseClicked">mouseClicked()</a> event function, which is called once after a mouse button has been pressed and then released. Browsers handle clicks differently, so this function is only guaranteed to be run when the left mouse button is clicked. To handle other mouse buttons being pressed or released, use <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>. </p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseClicked() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>It is generally not a good idea to draw inside an event function, but it can be done under certain conditions. Before drawing inside these functions, it's important to think about the flow of the program. In this example, squares are drawn inside <a href="/reference/#/p5/mousePressed">mousePressed()</a> and they remain on screen because there is no <a href="/reference/#/p5/background">background()</a> inside <a href="/reference/#/p5/draw">draw()</a>. But if <a href="/reference/#/p5/background">background()</a> is used, visual elements drawn within one of the mouse event functions will appear on screen for only a single frame, or, by default, 1/60th of a second. In fact, you'll notice this example has nothing at all inside <a href="/reference/#/p5/draw">draw()</a>, but it needs to be there to force P5 to keep listening for the events. If a <a href="/reference/#/p5/background">background()</a> function were run inside <a href="/reference/#/p5/draw">draw()</a>, the rectangles would flash onto the screen and disappear.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  fill(0, 102);
            +  background(204); // Draw once to give a little color
            +}
            +function draw() {
            +} // Empty draw() keeps the program running
            +function mousePressed() {
            +  rect(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <p>The code inside the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> and <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> event functions are run when there is a change in the mouse position. The code in the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> block is run at the end of each frame when the mouse moves and no button is pressed. The code in the <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> block does the same when the mouse button is pressed. If the mouse stays in the same position from frame to frame, the code inside these functions does not run. In this example, the gray circle follows the mouse when the button is not pressed, and the black circle follows the mouse when a mouse button is pressed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let dragX, dragY, moveX, moveY;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  fill(0);
            +  ellipse(dragX, dragY, 33, 33); // Black circle
            +  fill(153);
            +  ellipse(moveX, moveY, 33, 33); // Gray circle
            +}
            +function mouseMoved() {   // Move gray circle
            +  moveX = mouseX;
            +  moveY = mouseY;
            +}
            +function mouseDragged() { // Move black circle
            +  dragX = mouseX;
            +  dragY = mouseY;
            +}
            +      </script>
            +
            +      <!-- examples added for mouseOut() and mouseOver() -->
            +      <p>The <a href="/reference/#/p5/mouseOver">.mouseOver()</a> function is called once after every time a mouse moves onto the element. In this example, the diameter of the ellipse increase by 10 every time the mouse moves onto the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOver(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/mouseOut">.mouseOut()</a> function is called once after every time a mouse moves off the element. Similar to the above example, the diameter of the ellipse increase by 10 every time the mouse moves out of the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOut(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <h2>Wheel Events</h2>
            +      <p>The <a href="/reference/#/p5/mouseWheel">.mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners. The function accepts a callback function as argument which will be executed when the wheel event is triggered on the element. The <a href="/reference/#/p5/deltaY">event.deltaY</a> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <a href="/reference/#/p5/deltaX">event.deltaX</a> does the same as <a href="/reference/#/p5/deltaY">event.deltaY</a> except it reads the horizontal wheel scroll of the mouse wheel. On OS X with "natural" scrolling enabled, the <a href="/reference/#/p5/deltaY">event.deltaY</a> values are reversed.</p>
            +      <p>In this example, an event listener is attached to the canvas element, and function changeSize() would run when scrolling is performed on canvas. By using the <a href="/reference/#/p5/deltaY">event.deltaY</a> variable, scrolling up on canvas would increase the diameter of the ellipse and scrolling down would decrease the diameter. If scrolling is performed anywhere in any direction, the background is going to be darker.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseWheel(changeSize); // attach listener for activity on canvas only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with mousewheel movement anywhere on screen
            +function mouseWheel() {
            +  g = g + 10;
            +}
            +
            +// this function fires with mousewheel movement over canvas only
            +function changeSize(event) {
            +  if (event.deltaY > 0) {
            +    d = d + 10;
            +  }
            +  else {
            +    d = d - 10;
            +  }
            +}
            +      </script>
            +
            +      <h2>Key events</h2>
            +      <!-- keyTyped() added -->
            +      <p>Each key press is registered through the keyboard event functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyPressed">keyTyped()</a> and <a href="/reference/#/p5/keyReleased">keyReleased()</a>:</p>
            +      
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block is run one time when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is run one time when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is run one time when any key is released</li>
            +      </ul>
            +
            +      <p>Each time a key is pressed, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block is run once. Within this block, it's possible to test which key has been pressed and to use this value for any purpose. If a key is held down for an extended time, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block might run many times in a rapid succession because most operating systems will take over and repeatedly call the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. The amount of time it takes to start repeating and the rate of repetitions will be different from computer to computer, depending on the keyboard preference settings. In this example, the value of the boolean variable drawT is set from false to true when the T key is pressed; this causes the lines of code to render the rectangles in <a href="/reference/#/p5/draw">draw()</a> to start running.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +      </script>
            +
            +      <!-- added this information to distinguish keyPressed() and keyTyped() -->
            +      <p>When ASCII keys are pressed, the character is stored in the <a href="https://p5js.org/reference/#/p5/key">key </a>variable. However, this variable does not distinguish between uppercase and lowercase when used with the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. For this reason, it is recommended to use <a href="/reference/#/p5/keyTyped">keyTyped()</a>. When used with the <a href="/reference/#/p5/key">key</a> variable this function will recognize case. </p>
            +
            +      <p>Each time a key is released, the code inside the <a href="/reference/#/p5/keyReleased">keyReleased()</a> block is run once. The following example builds on the previous code; each time the key is released the boolean variable drawT is set back to false to stop the shape from displaying within <a href="/reference/#/p5/draw">draw()</a>.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +function keyReleased() {
            +  drawT = false;
            +}
            +      </script>
            +
            +      <h2>Event flow</h2>
            +      <p>As discussed previously, programs written with <a href="/reference/#/p5/draw">draw()</a> display frames to the screen sixty frames each second. The <a href="/reference/#/p5/frameRate">frameRate()</a> function is used to set a limit on the number of frames that will display each second, and the <a href="/reference/#/p5/noLoop">noLoop()</a> function can be used to stop draw() from looping. The additional functions <a href="/reference/#/p5/loop">loop()</a> and <a href="/reference/#/p5/redraw">redraw()</a> provide more options when used in combination with the mouse and keyboard event functions. If a program has been paused with <a href="/reference/#/p5/noLoop">noLoop()</a>, running <a href="/reference/#/p5/loop">loop()</a> resumes its action. Because the event functions are the only elements that continue to run when a program is paused with noLoop(), the loop() function can be used within these events to continue running the code in draw(). The following example runs the draw() function for about two seconds each time a mouse button is pressed and then pauses the program after that time has elapsed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let frame = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  if (frame > 120) {              // If 120 frames since the mouse
            +    noLoop();                     // was pressed, stop the program
            +    background(0);                // and turn the background black.
            +  }
            +  else {                          // Otherwise, set the background
            +    background(204);              // to light gray and draw lines
            +    line(mouseX, 0, mouseX, 100); // at the mouse position
            +    line(0, mouseY, 100, mouseY);
            +    frame++;
            +  }
            +}
            +function mousePressed() {
            +  frame = 0;
            +  loop();
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/redraw">redraw()</a> function runs the code in draw() one time and then halts the execution. It's helpful when the display needn't be updated continuously. The following example runs the code in draw() once each time a mouse button is pressed.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, 0, mouseX, 100);
            +  line(0, mouseY, 100, mouseY);
            +}
            +function mousePressed() {
            +  redraw(); // Run the code in draw one time
            +}
            +      </script>
            +
            +      <!-- event listener and callback functions explained??? -->
            +      <!-- This should probably be explained in a another tutorial more in-depth -->
            + <!--      Functions like mousePressed(), mouseClicked(), mouseReleased(), mouseMoved(), mouseOver(), and mouseOut() can be used as event listeners. They can be attached to certain elements</p>
            +      <p>Function|Boolean: function to be fired when mouse is pressed over the element. if false is passed instead, the previously firing function will no longer fire.</p>
            +      <p>In this example</p>
            +       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +-->
            +      <h2>Cursor icon</h2>
            +      <p>The cursor can be hidden with the <a href="/reference/#/p5/noCursor">noCursor()</a> function and can be set to appear as a different icon or image with the <a href="/reference/#/p5/cursor">cursor()</a> function. When the noCursor() function is run, the cursor icon disappears as it moves into the display window. To give feedback about the location of the cursor within the software, a custom cursor can be drawn and controlled with the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(7);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  ellipse(mouseX, mouseY, 10, 10);
            +}
            +      </script>
            +
            +      <p>If <a href="/reference/#/p5/noCursor">noCursor()</a> is run, the cursor will be hidden while the program is running until the <a href="/reference/#/p5/cursor">cursor()</a> function is run to reveal it.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor();
            +  }
            +  else {
            +    noCursor();
            +  }
            +}
            +      </script>
            +
            +      <p>Add a parameter to the cursor() function to change it to another icon or image. Either load and use image, or use the self-descriptive options are ARROW, CROSS, HAND, MOVE, TEXT, and WAIT.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor(HAND);  // Draw cursor as hand
            +  }
            +  else {
            +    cursor(CROSS); // Draw cursor as cross
            +  }
            +  line(mouseX, 0, mouseX, height);
            +  line(0, mouseY, height, mouseY);
            +}
            +      </script>
            +      <p>These cursor icons are part of your computer's operating system and will appear different on different machines.</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div>
            +  <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/p5-screen-reader.html b/dist/ko/learn/p5-screen-reader.html
            new file mode 100644
            index 0000000000..7e082bcf35
            --- /dev/null
            +++ b/dist/ko/learn/p5-screen-reader.html
            @@ -0,0 +1,604 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Using p5 with a screen reader</h1>
            +
            +      <p>
            +        This page introduces some of the screen reader friendly features of the p5js web editor, it provides an overview of accessible outputs, and examples and tutorials on how to get started with p5 when using a screen reader.
            +      </p>
            +      <p>
            +        p5.js is a library that starts with the original goal of Processing –to make to make coding accessible for artists, designers, educators, and beginners– and reinterprets it for the web using the metaphor of a software sketchbook with a set of drawing functionality. With p5.js we are able to draw in the canvas. The canvas is perhaps the most inaccessible element in HTML. The reason for this is simple: the canvas behaves just like a physical canvas, once you put paint on it, it covers up what’s behind it, making it hard to understand how the pixels comprise shapes and elements. Within the p5.js web editor it is possible to access the content of the canvas using a screen reader through text, a spatial table, and sound outputs.
            +      </p>
            +
            +
            +      <h2>What is the p5.js Web Editor</h2>
            +      <p>
            +        The p5.js web editor is a essentially a web page where you can type code in p5.js and run the code to view the output. It allows us to code in and for the browser. The web editor has features that make it screen reader friendly. You can access the <a href="http://editor.p5js.org/">p5 web editor here.</a>
            +      </p>
            +
            +      <h2>Pairings</h2>
            +      <p>
            +        Please note - the p5.accessibility library is currently not supported on MacOS.
            +      </p>
            +      <p>
            +        Using the p5.js web editor with a screen reader works better when you have one of the following screen reader/browser/operating system pairings:
            +      </p>
            +        <ul class="list_view">
            +          <li>NVDA and Firefox</li>
            +          <li>JAWS and Chrome</li>
            +        </ul>
            +
            +      <h2>Outputs</h2>
            +      <p>
            +        With a screen reader we can access the content of the canvas through the following outputs:
            +      </p>
            +
            +      <h3>Plain Text Output</h3>
            +      <p>
            +        This output describes the visual content present on the canvas in plain text.
            +      </p>
            +
            +      <h3>Table Output</h3>
            +      <p>
            +        The table output laids out the content of the canvas in the form of a table based on the spatial location of each element.
            +
            +      </p>
            +
            +      <h3>Sound Output</h3>
            +      <p>
            +        This mode explains the movement of the objects present in the canvas. Top to bottom movement is represented by a decrease in frequency and left to right through panning.
            +      </p>
            +
            +      <h2>How to select an output:</h2>
            +      <p>
            +        In the p5.js web editor there are two ways to select the accessible outputs that we want to make available.
            +      </p>
            +      <ol>
            +        <li>
            +          When we press the “play sketch, button” accessible to screen readers the “plain-text output” will automatically be available.
            +        </li>
            +        <li>
            +          If we want to access other outputs we should do the following:
            +          <ul class="list_view">
            +            <li>
            +              First, stop the sketch by pressing the “stop sketch, button” and go to “Settings”.
            +            </li>
            +            <li>
            +              Within settings we must find the “Accessibility” tab.
            +            </li>
            +            <li>
            +              In the “Accessibility” tab and under the “Accessible text-based canvas” section we can choose our preferred outputs.
            +            </li>
            +          </ul>
            +        </li>
            +      </ol>
            +      <p>
            +        Within “Settings” and under the “Accessibility” tab it is also possible to activate a lint warning sound that should make debugging easier. In “Settings” and under the  “General Settings” tab we can increase the size of the font and select a high contrast theme. After choosing our settings we can close the “Settings” window and go back to coding and playing our sketch.
            +      </p>
            +      <p>
            +        It is possible to add these accessible outputs to p5 sketches outside of the p5.js web editor by including the p5.accessibility.js library. <a  target="_blank" href="https://github.com/processing/p5.accessibility">You can learn more about the library here.</a>
            +      </p>
            +
            +      <h3>Keyboard Shortcuts</h3>
            +      <p>
            +        There are also ways to turn on the accessible outputs using keyboard shortcuts. Once we are on the code editor area we can use the following shortcuts (we have listed the shortcuts  for Windows computers, if you are using Mac OS please use the command key instead of control):
            +      </p>
            +      <ul class="list_view">
            +        <li>
            +          Shift + Control +1 - Turns on ALL the accessible output options, including audio
            +        </li>
            +        <li>
            +          Shift + Control +2 - Turns off ALL the accessible output options
            +        </li>
            +        <li>
            +          Control + Enter - This is used to run a sketch. If you already have accessibility options turned on, they will show up as well
            +        </li>
            +        <li>
            +          Shift + Control + Enter - This is used to stop a sketch.
            +        </li>
            +      </ul>
            +      <p>
            +        The full list of shortcuts is also available in the p5 web editor, under Keyboard Shortcuts in the Help and Feedback section of the menu
            +      </p>
            +
            +      <h1>Lessons</h1>
            +      <h2>Lesson 1: Hello World</h2>
            +      <p>
            +        In this section we go through some basic functions in p5 and look at how the screen reader will read the output.
            +
            +        There are two main functions we will use in our programs. The setup() function runs once, and is typically used for initialization, or for creating a program that does not need a loop running code repeatedly. The draw() function runs over and over again, and is used to perform a certain action repeatedly and for animation.
            +        Now we can open the editor: alpha.p5js.org and look for the code edit area. If you notice, there’s some code there already. Whenever you open the editor by default it will create a setup() function and a draw() function. However, for our first "Hello World" program we will take a step back and delete everything. Once we have a blank editor, we create a setup() block and add one line:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(200,200);
            +        }
            +      </code></pre>
            +
            +    <p>
            +      The createCanvas() function creates a canvas for us  to draw  or display the output. The canvas is the space on which the output is “drawn” or displayed. The code above creates a canvas of width and height 200 pixels. Since there is no movement, we will take a look only at the text and table outputs.
            +    </p>
            +    <h3>Text output for Lesson 1</h3>
            +    <p>
            +      Your output is a 200 by 200 white canvas containing the following 0 object
            +    </p>
            +    <h3>Table output for Lesson 1</h3>
            +    <p>
            +      white canvas is 200 by 200 of area 40000 contains 0 objects
            +    </p>
            +    <p>
            +      As expected, the outputs do not have any details apart from that of the canvas. Now, let’s move on to the next lesson where we add some basic shapes.
            +    </p>
            +
            +      <h2>Lesson 2: Basic Shapes</h2>
            +      <p>
            +        In this example, we will draw an ellipse on the top left, and a rectangle on the bottom right of the canvas of size 500 by 500 pixels. First, let's create the canvas and draw a shape in the setup function. Feel free to copy the code to the editor and run it.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        This code creates a canvas of 500 by 500 pixels and then draws an ellipse. The first 2 numbers we pass to the ellipse indicate where the center of the ellipse will be on the canvas. In this case, that is 50 and 50 pixels. The next 2 numbers indicate the width and height of the ellipse. In this case, they are both 20 pixels, implying we want to draw a circle. It is important to note that the top left corner of the canvas is point 0,0 pixels and the bottom right corner of the canvas is point 500,500 pixels.
            +      </p>
            +      <p>
            +        Now, we can also type this code a bit differently. We can create the canvas in the setup() function and draw the shape in the draw() function.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +        }
            +        function draw() {
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        In the previous case, the ellipse is drawn ONCE in setup and never again. But, in this case, the ellipse is drawn again and again in the canvas. Since, the numbers passed to the ellipse are the same each time, it doesn’t make a difference. However, if we wanted to change it’s position each time and make it move, then we would have to do it in draw.
            +      </p>
            +      <p>
            +        NOTE: remember, that everything in the canvas is drawn one over the other.
            +      </p>
            +      <p>
            +        In this case the output will be following:
            +      </p>
            +
            +      <h3>Text output for Lesson 2</h3>
            +      <p>
            +        The overview for the text output contains “Your output is a 500 by 500 white canvas containing the following 1 object:”.
            +      </p>
            +      <p>
            +        This description is followed by a list of elements where the shape, color, position, and area of each element are described (in this case: “white ellipse at top left covering 0.13% of the canvas” ). Each element can be selected to get more details. A table of elements is also provided. In this table, shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”).
            +      </p>
            +      <h3>Table output for Lesson 2</h3>
            +      <p>
            +        The overview for the table output contains “white canvas is 500 by 500 of area 250000 Contains 1 objects - 1 ellipse”
            +      </p>
            +      <p>
            +        This is followed by a table that describes the content spatially. It is a 10 by 10 table structure where each element is placed on a cell of the table depending on its position. Within each cell an element the color and type of shape of that element are available (example: “white ellipse”). These descriptions can be selected individually to get more details. A list of elements where shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”) is also available.
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rk4uO1bJX">basic shapes example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Lesson 3: Color</h2>
            +      <p>
            +        In these examples, we  look at different ways to add color to our sketch
            +        First, let’s look at ‘background()’. We can use this function to add a background color to the canvas. Copy the below code to try it out.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +      </code></pre>
            +      <p>
            +        Here, we have given the color in RGB format. In this format we can describe colors by saying how much, Red, Green and Blue the color has. RGB values must be integers between 0 and 255 with 0 being no color, and 255 highest amount of a certain color. The outputs will now contain “Red (255,0,0) canvas”.
            +      </p>
            +      <p>
            +        Now we can give color to our shapes using the function, fill().
            +      </p>
            +      <p>
            +        Copy the below code to try it out:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +
            +        function draw() {
            +          fill(200,50,8);
            +          ellipse(50,50,20,20);
            +          fill(20,250,8);
            +          ellipse(250,250,20,20);
            +          fill(20,150,250);
            +          ellipse(450,450,20,20);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now, in the plain text and grid output, we will notice that each shape is prepended with the color of the shape.
            +      </p>
            +
            +      <h3>Text output for Lesson 3</h3>
            +      <p>
            +        In the text output the overview is as follows
            +        “Your output is a 500 by 500 red(255,0,0) canvas containing the following 3 objects”
            +      </p>
            +      <p>
            +        After this we see the list of objects, with their color name and the RGB value. For example -  “crimson(200, 50, 8) ellipse at top left covering 0.13% of the canvas” Each object contains a link that when selected provides more details.
            +      </p>
            +
            +      <h3>Grid output for Lesson 3</h3>
            +      <p>
            +        The overview is as follows “red(255,0,0) canvas is 500 by 500 of area 250000 contains 3 0bjects - 3 ellipse”
            +      </p>
            +      <p>
            +        And in the table, we will find the objects in the grids corresponding to their location. “crimson(200,50,8) ellipse” and “green(20,250,8) ellipse”
            +      </p>
            +
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rJ-OSs-k7">color example on the p5 editor</a>
            +      </p>
            +
            +      <p>
            +        Instead of using Red, Green and Blue values, we can also pass just one value from 0 to 255. This is known as grayscale. It means that Red, Green and Blue will take the same value and the result will be between black and white. 0 being black, and 255 white.
            +      </p>
            +
            +      <h2>Lesson 4: Text</h2>
            +      <p>
            +        With p5, it is also possible to draw text on the canvas!
            +        We can add text to the canvas using the text() function. This function requires us input three values inside the parentheses: the text we want to display written between quotation marks, followed by the x and y position in pixels to display the text in the canvas.
            +      </p>
            +      <p>
            +        Copy and try out the below code.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(200);
            +        }
            +
            +        function draw() {
            +          fill(255,0,0);
            +          text("hello world!", 50,50)
            +        }
            +      </code></pre>
            +      <p>
            +        Note that fill() also affects text() and that the text we want to write has to be written between quotation marks. Now, let’s go through the output to see what it says.
            +      </p>
            +
            +      <h3>Text output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows  :
            +        “Your output is a 500 by 500 grey(200,200,200) canvas containing the following 1 object”
            +      </p>
            +      <p>
            +        Then there is a list of the objects. (For example - “hello world!” (red(255,0,0)) at top left of the canvas
            +      </p>
            +
            +      <h3>Grid output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows:
            +        “grey(200,200,200) canvas is 500 by 500 of area 250000 contains 1 object - 1 text”
            +      </p>
            +      <p>
            +        And in the table you will see the actual text and it’s color in the appropriate location (example - “hello world! (red(255,0,0))”
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/r1BFz3Zkm">text example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Exercise: Bar Graph</h2>
            +      <p>
            +        Now that we have covered how to draw basic shapes and write text on the canvas, let’s look at how we can create a bar chart with them.
            +      </p>
            +      <p>
            +        Using rectangles and some numbers, we can create bar graphs. Since we expect the entire sketch to be static, we can do the whole thing in the setup function
            +      </p>
            +      <p>
            +        Let’s start with a sample dataset that we want to depict.
            +      </p>
            +      <p>Animals in the park:</p>
            +      <ul class="list_view">
            +        <li>Dogs - 260</li>
            +        <li>Cats - 300</li>
            +        <li>Hamsters -100</li>
            +        <li>Rabbits - 50</li>
            +        <li>Spiders - 10</li>
            +      </ul>
            +
            +      <p>
            +        First we create a canvas:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        createCanvas(500,500);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now we can add some rectangles that represent each animal type. Notice that we will be adding comments in our code. Comments are lines in our code that are not executed and can be notes to ourselves. They start with // in the beginning of the line. We will create 5 rectangles, one for each animal type.
            +      </p>
            +
            +      <p>
            +        Remember that when we draw a rectangle, the first 2 values indicate the top left of the rectangle. If we want our bar graph to start on the left of our canvas, we need to calculate the numbers based on that. If we decide to make each bar with 50 pixels height, and to make the width represent the number of animals, for our first rectangle that represents the number of dogs the width would be 260 because there are 260 dogs. Then the values for this rectangle would be (0,0,260,50).
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	//We will use the fill() function to add color to the first bar of our chart.
            +        fill(255,0,0);
            +        //In this case our color is 255 red, 0 green, 0 blue.
            +        	rect(0, 0, 260, 50);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now let’s add the corresponding text:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	//Remember that the function text() requires the text, and the x, and y values for its position
            +        }
            +      </code></pre>
            +      <p>
            +        And voila! We just added the first bar on our graph chart.
            +      </p>
            +
            +      <h3>Text output for Bar Graph 1</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 2 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now lets add rectangles to represent 300 cats, 100 hamsters, 50 rabbits, and 10 spiders. Remember that the values for the function rect() in our case should be: rect(0, y position, number of animals, 50).
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	rect(0, 100, 300, 50); // here the second value, y position, is 100 so that we can draw the second bar under the first bar.
            +        	text('Cats - 300', 0, 175);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        The text output would be:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 2</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(red(255, 0, 0)) at top left</li>
            +      </ul>
            +      <p>
            +        Now we can add different colors to each bar:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	fill(0,255,0);
            +        	rect(0, 100, 300, 50);
            +        	text('Cats - 300', 0, 175);
            +        	fill(0,0,255);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	fill(200,100,0);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	fill(0,200,200);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +      <p>
            +        Our bar graph is ready! Here is the output:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 3</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>green(0, 255, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(green(0, 255, 0)) at top left</li>
            +        <li>blue( 0, 0, 255) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(blue( 0, 0, 255)) at top left</li>
            +        <li>orange(200, 100, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(orange(200, 100, 0)) at top left</li>
            +        <li>cyan( 0, 200, 200) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(cyan( 0, 200, 200)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now that we created a graph together you should be able to do it by yourself and share the results with your friends!
            +      </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/program-flow.html b/dist/ko/learn/program-flow.html
            new file mode 100644
            index 0000000000..cea80b92ed
            --- /dev/null
            +++ b/dist/ko/learn/program-flow.html
            @@ -0,0 +1,580 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This tutorial is written by Alex Yixuan Xu with reference to <em>Getting Started With p5.js</em> by Lauren McCarthy, Casey Reas, and Ben Fry. Copyright 2016 Maker Media, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">MDN JavaScript documentation</a> and <a href="https://www.w3schools.com/js">W3Schools JavaScript tutorials</a>. If you see any errors or have comments, please <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Program Flow</h1>
            +      <!-- TOPICS -->
            +      <!-- Branching: if/else -->
            +      <!-- Loops: for/while loop -->
            +      <!-- noLoop(), loop() and redraw() -->
            +      <!-- Asynchronicity in p5.js: intro to loadImage(), preload(), callbacks -->
            +      <!-- Loading JSON & APIs -->
            +      <!-- Functions and Callbacks: list of functions -->
            +      <!-- Interactivity and Event Listeners: list of event listeners such as mousePressed() -->
            +
            +
            +
            +      <!-- https://docs.microsoft.com/en-us/scripting/javascript/controlling-program-flow-javascript -->
            +      <p>This tutorial outlines some various techniques for controlling the sequence and timing of events in your code, which is known as program flow.</p>
            +
            +      <!-- if/else stuff -->
            +      <h2>Branching</h2>
            +      <!-- https://www.w3schools.com/js/js_if_else.asp -->
            +      <p>We can use conditional statements to control the program flow. Conditional statements perform different actions based on tests for different conditions. JavaScript has the following conditional statements:</p>
            +      <ul class="list_view">
            +        <li>Use <em>if</em> to specify a block of code to be executed, if a specified condition is true</li>
            +        <li>Use <em>else</em> to specify a block of code to be executed, if the same condition is false</li>
            +        <li>Use <em>else if</em> to specify a new condition to test, if the first condition is false</li>
            +      </ul>
            +      <p>In the following example, change the value for variable i to change the color of the rectangle. If i equals to 0, the condition for the <em>if</em> statement is satisfied, and the filling color is red. In this case, the program continues to draw the rectangle skipping the <em>else if</em> and <em>else</em> statements. If i equals to 1, the condition for the <em>if</em> statement is not satisfied, and the program moves on to check the condition for the <em>else if</em> statement. Since <em>else if</em> condition is satisfied, the filling color is green. If neither the <em>if</em> nor the <em>else if</em> conditions are satisfied, the program runs the <em>else</em> statement, and the filling color is blue.</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0; // change the value of i to see the change
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  background(200);
            +  if (i==0){
            +    fill(255, 0, 0);
            +  }
            +  else if (i==1){
            +    fill(0, 255, 0);
            +  }
            +  else{
            +    fill(0, 0, 255);
            +  }
            +  rect(width/2, height/2, 50, 50);
            +}
            +      </script>
            +
            +      <!-- for loop and while loop -->
            +      <h2>Loops</h2>
            +      <p>Loops can execute a block of code repeatedly. p5 supports several different kinds of loops in JavaScript:</p>
            +      <ul class="list_view">
            +        <li>for - loops through a block of code a specified number of times</li>
            +        <li>for/in - loops through the properties of an object</li>
            +        <li>while - loops through a block of code while a specified condition is true</li>
            +        <li>do/while - also loops through a block of code while a specified condition is true</li>
            +      </ul>
            +
            +      <p>The <em>for</em> loop sets up a variable (usually i or x) that is then incrementally changed for each loop. It has the following structure:</p>
            +      <pre><code class="language-javascript">
            +        for (statement 1; statement 2; statement 3) {
            +            code block to be executed
            +        }
            +      </code></pre>
            +      <ul class="list_view">
            +        <li>Statement 1 is executed (one time) before the execution of the code block. It sets the starting value for the variable</li>
            +        <li>Statement 2 defines the condition that must be true for the code block to be executed.</li>
            +        <li>Statement 3 is executed every time  after the code block has finished running if statement 2 evaluated to be true.</li>
            +      </ul>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  for (let i=0; i<5; i++){
            +    text(i, i*10, height/2);
            +  }
            +}
            +      </script>
            +      <p>In this example, variable i is initially set to 0. Every time the <em>for</em> loop runs, i is displayed on the screen and 1 is added to i. Note the <em>for</em> loop will only run until i equals to 4 because after this the condition that i be less than 5 will be false.</p>
            +
            +      <p>The <em>for/in</em> statement loops through the properties of an object:</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let person = {fname:"John", lname:"Doe", age:25};
            +let myText = "";
            +function setup(){
            +  let x;
            +  for (x in person) {
            +      myText += person[x];
            +      myText += " ";
            +  }
            +  text(myText, 0, height/2);
            +}
            +      </script>
            +      <p>In this example, as the <em>for</em> loop cycles through each property of the person object, the property value is added to myText string.</p>
            +
            +      <p>The while loop cycles through a block of code as long as its specified condition is true.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  while (i<5){
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +}
            +      </script>
            +      <p>This example gives the same result as the <em>for</em> loop example above. Sometimes <em>while</em> loops and <em>for</em> loops can be used interchangeably.</p>
            +
            +      <p>The <em>do/while</em> loop is a variant of the <em>while</em> loop. This loop will execute the code block once, before checking if the condition is true, it will then repeat the loop as long as the condition is true.</p>
            +      <!-- Is there an example particular to do/while? -->
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  do {
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +  while (i < 5);
            +}
            +      </script>
            +
            +
            +      <!-- this is particular to p5 -->
            +      <h2>noLoop(), loop() and redraw()</h2>
            +      <p>The <a href="/reference/#/p5/draw">draw()</a> function in p5 runs as a loop. The code inside the draw() function runs continuously from top to bottom until the program is stopped. The draw() loop may be stopped by calling <a href="/reference/#/p5/noLoop">noLoop()</a>, and can then be resumed with <a href="/reference/#/p5/loop">loop()</a>. If using <a href="/reference/#/p5/noLoop">noLoop()</a> in <a href="/reference/#/p5/setup">setup()</a>, it should be the last line inside the block.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(200);
            +  ellipse(x, height/2, 20, 20);
            +  x ++;
            +}
            +function mousePressed() {
            +  loop();
            +}
            +function mouseReleased() {
            +  noLoop();
            +}
            +        </script>
            +        <p>In this example, <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a>, so the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. Since <a href="/reference/#/p5/loop">loop()</a> is placed in <a href="/reference/#/p5/mousePressed">mousePressed()</a>, the draw() block will resume looping when mouse is pressed. When mouse is released, <a href="/reference/#/p5/noLoop">noLoop()</a> is called again and hence the draw() loop stops.</p>
            +
            +        <p>The function <a href="/reference/#/p5/redraw">redraw()</a> executes the code within <a href="/reference/#/p5/draw">draw()</a> one time. This functions allows the program to update the display window only when necessary, such as when an event registered by <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/keyPressed">keyPressed()</a> occurs. In structuring a program, it only makes sense to call <a href="/reference/#/p5/redraw">redraw()</a> within events such as <a href="/reference/#/p5/mousePressed">mousePressed()</a> outside of the draw() loop. The redraw() function does not work properly when called inside draw(). In addition, you can set the number of loops through draw by adding a single argument (an integer) to the redraw() function.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +   createCanvas(100, 100);
            +   noLoop();
            + }
            +function draw() {
            +   background(200);
            +   ellipse(x, height/2, 20, 20);
            +   x ++;
            + }
            +function mousePressed() {
            +   redraw();
            + }
            +      </script>
            +      <p>This example is similar to the previous one, where <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a> and the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. However, when mouse is pressed, <a href="/reference/#/p5/redraw">redraw()</a> is called and <a href="/reference/#/p5/draw">draw()</a> will only loop once. To make smooth animations, it is easier to work with noLoop() and loop().</p>
            +
            +
            +      <h2>Asynchronicity in p5.js</h2>
            +      <p>In JavaScript, events may occur concurrently with the main program flow. This is considered as asynchronicity in programming. In p5, for example, when we use <a href="/reference/#/p5/loadImage">loadImage()</a> in <a href="/reference/#/p5/setup">setup()</a>, the browser begins the process of loading the image but skip onto the next line before it is finised loading. The following example demonstrates such asynchronicity.</p>
            +        <pre><code class="language-javascript">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +    </code></pre>
            +    <iframe src="/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.html" width="150" height="150"></iframe>
            +      <!-- what's the file location??????????????????? -->
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p>When you run this program, you'll notice that the drawing canvas is grey with no image displayed. This is because <a href="/reference/#/p5/loadImage">loadImage()</a> begins to load the image, but does not have time to finish this task before the program continues on through the rest of <a href="/reference/#/p5/setup">setup()</a> and on to <a href="/reference/#/p5/draw">draw()</a>. Even with the <a href="/reference/#/p5/noLoop">noLoop()</a> function that stops p5.js from continuously executing the code within draw(). The <a href="/reference/#/p5/image">image()</a> function is unable to display the image as it is not properly loaded.</p>
            +
            +      <h2>Introduction to Preload</h2>
            +      <p>To help with this issue of asynchronicity, p5.js has the <a href="/reference/#/p5/preload">preload()</a> function. Unlike <a href="/reference/#/p5/setup">setup()</a>, preload() forces the program to wait until everything has loaded before moving on. It is best to only make load calls in preload(), and do all other setup in setup().</p>
            +      <pre><code class="language-javascript">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.html" width="150" height="150"></iframe>
            +
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p><a href="/reference/#/p5/preload">preload()</a> ensures that the image has been loaded before running the other code. </p>
            +
            +
            +
            +      <h2>Loading with a Callback</h2>
            +      <p>An alternative to <a href="/reference/#/p5/preload">preload()</a> is to use a <em>callback function</em>. A callback function is a function that is passed as an argument to a second function, and that runs after the second function has completed. The following example illustrates this technique.</p>
            +      <pre><code class="language-javascript">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.html" width="150" height="150"></iframe>
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </script> -->
            +      <p>In this example, the second argument in <a href="/reference/#/p5/loadImage">loadImage()</a> is the function we want to run after the load is complete. Once the image has loaded, this callback function, drawImage(), is automatically called. It has one argument which contains the image that was just loaded. There is no need to create a global variable to hold the image. The image is passed directly into the callback function, as the parameter name chosen in the function definition.</p>
            +
            +
            +
            +      <h2>Loading JSON & APIs</h2>
            +      <!-- page 187 -->
            +      <p>The JSON (JavaScript Object Notation) format is a common system for storing data. Like HTML and XML formats, the elements have labels associated with them. One way to load JSON file is to use <a href="/reference/#/p5/loadJSON">loadJSON()</a> function in <a href="/reference/#/p5/preload">preload()</a>.</p>
            +      <!-- example where loadJSON() in preload() -->
            +      <p>The following request at https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson returns data of recent earthquakes in the world from USGS.</p>
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let earthquakes;
            +function preload(){
            +  earthquakes = loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson');
            +}
            +function setup(){
            +  createCanvas(200, 100);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +
            +      <p>Alternatively, <a href="/reference/#/p5/loadJSON">loadJSON()</a> can also take a callback. To use data from an API, you may need a callback function as, like with an image, the data takes time to load. API (Application Programming Interface) requests are commands that request data from a service. A lot of APIs will return data in JSON format. Some need you to authenticate with the API to use it (e.g. register as a developer and get keys). You can’t always use <a href="/reference/#/p5/preload">preload()</a> when getting data from APIs because the data might change while you sketch is running and you will want your program to respond accordingly.</p>
            +
            +      <p><a href="/reference/#/p5/loadJSON">loadJSON()</a> can be used in a few ways: </p>
            +      <ul class="list_view">
            +        <li>loadJSON(path)</li>
            +        <li>loadJSON(path, callback)</li>
            +        <li>loadJSON(path, callback, datatype)</li>
            +        <li>loadJSON(path, callback, errorCallback)</li>
            +        <li>loadJSON(path, datatype, callback, errorCallback)</li>
            +        <li>loadJSON(path, jsonpOptions, datatype, callback, errorCallback)</li>
            +      </ul>
            +      <p>
            +        where:
            +      </p>
            +      <ul class="list_view">
            +        <li>path - String: name of the file or url to load</li>
            +        <li>jsonpOptions - Object: options object for jsonp related settings</li>
            +        <li>datatype - String: "json" or "jsonp"</li>
            +        <li>callback - Function: function to be executed after loadJSON() completes, data is passed in as first argument</li>
            +        <li>errorCallback - Function: function to be executed if there is an error, response is passed in as first argument</li>
            +      </ul>
            +      <!-- example where loadJSON() takes a callback -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(200, 100);
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +      <p>In this example, the <a href="/reference/#/p5/loadJSON">loadJSON()</a> function is placed in <a href="/reference/#/p5/setup">setup()</a> and takes a custom callback function showEarthquake(). This means when the program finishes loading the JSON file from the USGS earthquakes API, the function showEarthQuake() is called. The place and magnitude of the most recent earthquake listed by the API is stored in local variables within showEarthquake and are then displayed on the screen.</p>
            +
            +      <p>Sometimes we use <a href="/reference/#/p5/setInterval">setInterval()</a> to control the frequency of requests made to the API. setInterval() can also take a callback function. If you call setInterval() in <a href="/reference/#/p5/setup">setup()</a>, it will run repeatedly for the duration of the program at the interval set.</p>
            +      <!-- example setInterval() is used -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let i=1; // counter variable to keep track of the interval
            +function setup() {
            +  createCanvas(200, 100);
            +  getEarthquake();
            +  setInterval(getEarthquake, 5000); // get data every 5 seconds
            +}
            +function getEarthquake(){
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  background(255);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text("Data grabbed "+i, 0, height/3);
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +  i++;
            +}
            +      </script>
            +      <p>In this example, the earthquake data is grabbed from the API every 5 seconds and is displayed on the screen.</p>
            +
            +
            +
            +
            +      <!-- list the functions that accept callbacks? Is this section necessary?-->
            +      <h2>More Callback Functions</h2>
            +      <p>In addition to the <a href="/reference/#/p5/loadImage">loadImage()</a>, <a href="/reference/#/p5/loadJSON">loadJSON()</a> and <a href="/reference/#/p5/setInterval">setInterval()</a>, there are other functions in p5 that accept callbacks. Typically, functions that involve loading data of some kind accept callbacks, or should be put in <a href="/reference/#/p5/preload">preload()</a>. For example:</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/loadFont">loadFont()</a></li>
            +        <li><a href="/reference/#/p5/loadSound">loadSound()</a></li>
            +        <li><a href="/reference/#/p5/loadStrings">loadStrings()</a></li>
            +        <li><a href="/reference/#/p5/loadTable">loadTable()</a></li>
            +        <li><a href="/reference/#/p5/loadXML">loadXML()</a></li>
            +        <li><a href="/reference/#/p5/loadBytes">loadBytes()</a></li>
            +        <li><a href="/reference/#/p5/loadModel">loadModel()</a></li>
            +      </ul>
            +
            +      <p>DOM functionality makes it easy to interact with other HTML5 objects, including text, hyperlink, image, input, video, audio, and webcam. Some DOM creation methods also accept callbacks: </p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/createImg">createImg()</a></li>
            +        <li><a href="/reference/#/p5/createFileInput">createFileInput()</a></li>
            +        <li><a href="/reference/#/p5/createVideo">createVideo()</a></li>
            +        <li><a href="/reference/#/p5/createAudio">createAudio()</a></li>
            +        <li><a href="/reference/#/p5/createCapture">createCapture()</a></li>
            +      </ul>
            +
            +
            +      <h2>Interactivity and Event Listeners</h2>
            +      <p>Callback functions are functions that can be passed as an argument into another function and be executed after the first function is complete. An event listener or handler is a type of callback. It is called whenever an event occurs such as when the mouse is pressed, or a key is pressed etc.</p>
            +      <p>Mouse functions like <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, etc. can be used as event listeners. They can be attached to certain elements in a sketch.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseWheel">mouseWheel()</a> - Code inside this block is run once when mouse wheel is scrolled over the element</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>In this example, a canvas element is created and an event listener <a href="/reference/#/p5/mousePressed">mousePressed()</a> is attached. Function changeGrey() will only run when the mouse is pressed over the canvas, and will will change the background color to a random grey. If the mouse is pressed anywhere, even outside of the canvas, the diameter of the ellipse will increase by 10 pixels. The custom function changeGray(), in this instance, is placed within the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function and is to be triggered when mouse is pressed over the canvas element. If the mouse is not pressed, false is passed and changeGrey() will not run.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +
            +      <p>The above mouse functions can be attached to an element like the canvas or can be used without specifying an element. The keyboard functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyReleased">keyReleased()</a>, <a href="/reference/#/p5/keyTyped">keyTyped()</a>, and mouse function <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> cannot be attached to a specific element.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block runs once when the mouse is moved and the mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block runs once when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is runs once when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is runs once when any key is released</li>
            +      </ul>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/tdd.html b/dist/ko/learn/tdd.html
            new file mode 100644
            index 0000000000..2dc17c0479
            --- /dev/null
            +++ b/dist/ko/learn/tdd.html
            @@ -0,0 +1,660 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Unit Testing and Test Driven Development</h1>
            +      <div class="attribution">
            +        This tutorial was written by <a href='https://github.com/andrewjtimmons'>Andy Timmons</a>.
            +      </div>
            +
            +      <h2>Overview</h2>
            +      <p>
            +        This tutorial will walk you through setting up your development environment to run unit tests against your code. Unit testing is a method of applying tests to the classes and functions in your code. It can catch bugs, help you collaborate with others, and code faster. Test driven development is a method of writing your tests before you write code so you have all of your tests when you finish.
            +      </p>
            +      <p>
            +        This tutorial is intended for people who:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>Have written p5.js sketches before.</li>
            +          <li>Are comfortable using javascript <a href='http://p5js.org/examples/structure-functions.html'>functions.</a></li>
            +          <li>Can run basic terminal commands.  If you are not familiar using a terminal here is a <a href='http://lifehacker.com/5633909/who-needs-a-mouse-learn-to-use-the-command-line-for-almost-anything'>good tutorial for getting comfortable.</a></li>
            +        </ul>
            +
            +      <h2> Why unit test?</h2>
            +      <p>
            +        In late 1998 NASA launched the Mars Climate Orbiter in collaboration with Lockheed Martin. This robotic space probe cost 193 million dollars and took one year to arrive and establish its orbit around Mars. Minutes later it crashed into Mars and exploded. NASA later determined it was a software error. The Lockheed Martin navigation code gave measurements in English units like feet, and the NASA code expected the measurements to be in metric units like meters. The difference between the two caused the crash. [<a href='https://en.wikipedia.org/wiki/Mars_Climate_Orbiter'>Citation</a>]
            +      </p>
            +      <p>
            +        Unit testing could have prevented this error and while you might not be launching spaceships (but by all means please try), unit testing can prevent a lot of headaches from the outset of your project to install day. It can help you:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>improve your design and reduce bugs</li>
            +          <li>collaborate with others</li>
            +          <li>finish your project faster</li>
            +        </ul>
            +
            +      <h2>Setting up for unit testing</h2>
            +      <p>
            +        Installing node:
            +      </p>
            +        <ol>
            +          <li>First you must install node. If you already have node installed this assumes you are using version 4 or higher.  Node is a open source runtime environment for building server side applications.  Don’t worry if that sentence didn’t make sense.  You don’t have to understand all there is to know about node to do this tutorial.  If you are curious to learn more you can read the <a href='https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io'>p5.js node tutorial.</a></li>
            +          <li>On Mac, Linux, Windows:  Go to <a href='https://nodejs.org/en/'>https://nodejs.org/en/</a> and download the installer.  Open the installer and follow the directions.</li>
            +          <li>
            +            Once the installer finishes open a terminal and run the following command to verify it installed correctly.  You should see something like "v6.6.0" or some other numbers that indicate the version you installed.<br />
            +            <pre><code class="language-javascript">
            +            node -v
            +            </code></pre>
            +          </li>
            +        </ol>
            +      <p>
            +        Update npm, the Node Package Manager.  Npm is a program that allows you to install software libraries that are compatible with node.  In your open terminal run the command:
            +        <pre><code class="language-javascript">
            +          sudo npm install npm@latest -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the chai assertion library.  This is what you will use to build your tests.  In the terminal window run the command:
            +        <pre><code class="language-javascript">
            +          npm install chai -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the mocha test running library.  Mocha drives your chai tests.  Much like a person drives a car.  In the terminal window run:
            +        <pre><code class="language-javascript">
            +          npm install mocha -g
            +        </code></pre>
            +      </p>
            +
            +      <h2>A sketch without tests</h2>
            +      <p>
            +        Your goal today is to make a sketch with a square whose fill color loops over every RGB color.
            +      </p>
            +      <p>
            +        Let’s set up the project. This is what it would look like without any unit tests.
            +      </p>
            +        <ol>
            +          <li>Make a folder called color_unit_test and open it</li>
            +          <li>
            +            Make a file called index.html and type the following code.  While you can just copy/paste it, typing it out will help you understand what it is doing better.  It is worth the time!<br />
            +            <pre><code class="language-javascript">
            +              &lt;!DOCTYPE html&gt;
            +              &lt;html&gt;
            +              &lt;head&gt;
            +                &lt;meta charset="UTF-8"&gt;
            +                &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
            +                &lt;script src="https://cdn.jsdelivr.net/npm/p5@0.4.20/lib/p5.js"&gt;&lt;/script&gt;
            +                &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +                &lt;style&gt; body {padding: 0; margin: 0;} &lt;/style&gt;
            +              &lt;/head&gt;
            +              &lt;body&gt;
            +              &lt;/body&gt;
            +              &lt;/html&gt;
            +            </code></pre>
            +          </li>
            +          <li>
            +            make a file called sketch.js and put in the following code<br />
            +            <pre><code class="language-javascript">
            +              // This is for a unit test tutorial.
            +              // it should create a rectangle and allow you to iterate over
            +              // every single color.
            +              //
            +              // colorValueIncrease sets the amount the color changes on each
            +              // draw loop. Values greater than 255 will break the sketch.
            +              // fillColor will be the color of the rectangle.
            +              // colorIncreaser will become an instance of our ColorIncreaser class.
            +
            +              let colorValueIncrease = 1;
            +              let fillColor;
            +              let colorIncreaser;
            +
            +              function setup() {
            +                createCanvas(500, 500);
            +                background(0);
            +                fillColor = color(0, 0, 0, 255);
            +                noStroke();
            +              }
            +
            +              function draw() {
            +                fill(fillColor);
            +                rect(0, 0, 500, 500);
            +
            +                // increment the red value
            +                fillColor.levels[0] += colorValueIncrease;
            +                // If the red value is maxed out increment the green value
            +                // and reset the red value.
            +                if (fillColor.levels[0] > 255) {
            +                  fillColor.levels[0] = 0;
            +                  fillColor.levels[1] += colorValueIncrease;
            +                }
            +                // If the green value is maxed out increment the blue value
            +                // and reset the green value.
            +                if (fillColor.levels[1] > 255) {
            +                  fillColor.levels[1] = 0;
            +                  fillColor.levels[2] += colorValueIncrease;
            +                }
            +                // If the blue value is maxed out reset the green value.
            +                if (fillColor.levels[2] > 255) {
            +                  fillColor.levels[2] = 0;
            +                }
            +              }
            +            </code></pre>
            +          </li>
            +          <li>
            +           Open the index.html file in your browser (you don’t need to run a local server in this case). You should see a black box become red and then black again. This is the basis of looping over all the RGB colors. The problem you face is that there are 256 values for red, green, and blue, which means there are over 16 million combinations of colors! You can make this faster. However, making this faster will cause flashing lights which might give some people headaches or seizures. Please only increase this value if you do not have issues with flashing lights. The rest of the tutorial should be fine.  In the sketch.js file change the<pre><code class="language-javascript">let colorValueIncrease = 33;</code></pre> and reload the page. However this still doesn’t guarantee this is working properly. You don’t have time to watch all the colors change nor can you tell yourself if it is iterating through the millions of colors. Change the colorValueIncrease variable back to 1 before you move on.
            +          </li>
            +          <li>
            +            At 30 draw loops per second it would take over six days to loop through all of the colors. You certainly don’t have time to do that once, and would never be able to check and see if it worked every time you updated our code. What if you accidentally change something in our draw loop that breaks the code right before install?  You wouldn’t know until it was live and everyone saw your sketch break.
            +          </li>
            +        </ol>
            +
            +      <h2>Your first unit tests</h2>
            +      <p>
            +        Unit testing can help us out here. The majority of the time spent in this program is the actual drawing of the pixels. Adding 1 and checking a few if statements is very fast if you don’t need to draw the actual pixels. So you can check if the color values increase as expected without having to actually watch them all increase on your screen.
            +      </p>
            +      <p>
            +        In the folder called color_unit_test that you already created, make a new folder called test.  Open the test folder and make a file called test.js.  Type this code into test.js
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +
            +
            +          // Create the variable you are going to test
            +          let p5js = 'awesome';
            +
            +
            +          // describe lets you comment on what this block of code is for.
            +          describe('these are my first tests for p5js', function() {
            +
            +
            +            // it() lets you comment on what an individual test is about.
            +            it('should be a string', function(done) {
            +              // expect is the actual test.  This test checks if the var is a string.
            +              expect(p5js).to.be.a('string');
            +              // done tells the program the test is complete.
            +              done();
            +            });
            +
            +
            +            it('should be equal to awesome', function(done) {
            +              // This expect tests the value of the string.
            +              expect(p5js).to.equal('awesome');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your command line and <a href='http://ss64.com/bash/cd.html'>cd</a> into the main directory of our sketch called color_unit_test.  Type the command
            +        <pre><code class="language-javascript">mocha</code></pre>
            +      </p>
            +      <p>
            +        into the command line and watch your first test run!  You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              ✓ should be a string
            +              ✓ should be equal to awesome
            +            2 passing (14ms)
            +        </code></pre>
            +      </p>
            +      <p>
            +        Let's look at what happens when tests fail. Change line 6 in test.js from:
            +        <pre><code class="language-javascript">let p5js = 'awesome';</code></pre>
            +      </p>
            +      <p>
            +        to
            +        <pre><code class="language-javascript">let p5js = 42;</code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your terminal and run the mocha command again. You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              1) should be a string
            +              2) should be equal to awesome
            +
            +            0 passing (18ms)
            +            2 failing
            +
            +            1) these are my first tests for p5js should be a string:
            +               AssertionError: expected 42 to be a string
            +                at Context.<anonymous> (test/test.js:14:24)
            +
            +            2) these are my first tests for p5js should be equal to awesome:
            +               AssertionError: expected 42 to equal 'awesome'
            +                at Context.<anonymous> (test/test.js:21:21)
            +        </code></pre>
            +      </p>
            +      <p>
            +        What is nice about these errors is:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>They tell you the name of the test that you put in the describe() and it() functions</li>
            +          <li>They tell you what they expected with AssertionError: expected 42 to be a string</li>
            +          <li>They tell you what file and line of code had the problem test/test.js:14:24</li>
            +        </ul>
            +      <p>
            +        Now that you know the basics of unit testing you are ready to write some tests against your code and refactor your sketch!
            +      </p>
            +
            +      <h2>Test Driven Development</h2>
            +      <p>
            +        You are going to use Test Driven Development for the rest of this tutorial.  The idea is you write your unit tests first, run them and watch them fail, and then add code to sketch.js to make the tests pass.  This way you ensure your code is working as you expect every step of the way and that new code doesn’t break old code.  Your goal is to create a ColorIncreaser class that:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>takes in an integer as the value to increase each time called colorValueIncrease.</li>
            +          <li>takes in an instance of the <a href='http://p5js.org/reference/#/p5/color'>p5 color class.</a></li>
            +          <li>has a function to increase the values in the color by the value in colorValueIncreases.</li>
            +        </ul>
            +      <p>
            +        Delete everything in test.js and replace it with this
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +          // Import our ColorIncreaser class.
            +          const ColorIncreaser = require('../sketch');
            +
            +          describe('ColorIncreaser tests', function() {
            +            // Will hold the reference to the ColorIncreaser class
            +            let colorIncreaser;
            +
            +            // beforeEach is a special function that is similar to the setup function in
            +            // p5.js.  The major difference it that this function runs before each it()
            +            // test you create instead of running just once before the draw loop
            +            // beforeEach lets you setup the objects you want to test in an easy fashion.
            +            beforeEach(function() {
            +                colorIncreaser = new ColorIncreaser();
            +            });
            +
            +            it('should be an object', function(done) {
            +              expect(colorIncreaser).to.be.a('object');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command in your terminal and watch your new test fail!  The crux of the error is “TypeError: ColorIncreaser is not a constructor”.  This makes sense because you have not created a ColorIncreaser class in our sketch yet. <br />
            +
            +        Go to the bottom of your sketch.js file, below the closing bracket } for the draw function, and add this:
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor() {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +            }
            +          }
            +
            +          module.exports = ColorIncreaser;
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  The function line will be our color increasing object.  The module.exports line is what allows our test.js file to import our ColorIncreaser with the line you already added that looks like this:
            +        <pre><code class="language-javascript">
            +           const ColorIncreaser = require('../sketch');
            +        </code></pre>
            +      </p>
            +      <p>
            +        If you go back to your terminal and run mocha your test should pass.<br />
            +
            +        Now get your ColorIncreaser function to actually do something.  Start by storing the colorValueIncrease as a variable in your class.  Before you change the code in sketch.js you have to write your tests.  Change the beforeEach function in test.js to look like this
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        and add a new it() test below it like this
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command and you will get the pivotal line:<br />
            +        AssertionError: expected undefined to equal 1<br />
            +        because you have not added this to your class yet. You need to add that value to get this to work. Add this line to the setup function in sketch.js under noStroke();
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +        </code></pre>
            +        and change the ColorIncreaser function to look like this
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser() {
            +            constructor(colorValueIncrease) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +            }
            +          }
            +        </code></pre>
            +        Let’s run the mocha test again.  It should pass!
            +      </p>
            +
            +      <h2>Testing when your object is composed of other objects</h2>
            +      <p>
            +        Now you need to add an instance of the p5 color class to our ColorIncreaser. However, for your tests, you don’t want to use an actual instance of the color() class because you don’t want to test external dependencies given by another library.You just want to make sure that your increment function works. So you are going to create what is called a mock of the p5 color class so you can test without worrying about the implementation of code you didn’t write.
            +      </p>
            +      <p>
            +        The original way of incrementing colors just used the color.levels and changed the red, green and blue values at index [0], [1], and [2].  You can see this in the draw function in sketch.js.  The implementation of color just stores those values in a javascript array so you can mock it out very easily.  Put this code in test.js below the const ColorIncreaser = require… line and above the describe line
            +        <pre><code class="language-javascript">
            +          function mockColor(red, green, blue, alpha) {
            +              // Mock of the color class from p5
            +              this.levels = [];
            +              this.levels[0] = red;
            +              this.levels[1] = green;
            +              this.levels[2] = blue;
            +              this.levels[3] = alpha;
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Update your beforeEach() function
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              let fillColor = new mockColor(0, 0, 0, 255);
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And update the it('should initialize without mutation', function block
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[3]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And run the tests!  Failure!   TypeError: Cannot read property 'levels' of undefined<br />
            +        You have to update the ColorIncreaser class to take in a fillColor variable.  It is an easy fix.  In sketch.js change the colorIncreaser line in setup() to look like this
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +        </code></pre>
            +      </p>
            +      <p>
            +        and update the ColorValueIncreaser function
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor(colorValueIncrease, fillColor) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +              this.fillColor = fillColor;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Run the tests again and they should pass!
            +      </p>
            +      <p>
            +        Now you have all the initialized variables you need to make the class work.  This provides the scaffold on which you will build your method to increase the color value and iterate over every color.
            +      </p>
            +
            +      <h2>Testing class methods</h2>
            +      <p>
            +        You are going to make a class method called increaseFillColor. It will basically run the code that is currently in our draw loop, but use the values stored in our ColorIncreaser class to do it.
            +      </p>
            +      <p>
            +        As covered before there are 256 values for red, green and blue giving 16,777,216 color combinations. While that might seem overwhelming you can test it easily because you know what values should be present in red, green and blue after each time you call our increaseFillColor function. For example if you start with the color black with the rgb levels 0,0,0 and you call increaseFillColor once you know you should now have the values 1,0,0.  So you are going to add tests in test.js for calling increaseFillColor 255, 65535 and 16777215 times.
            +        <pre><code class="language-javascript">
            +          it('should have rgb values 255, 0, 0 after calling increaseFillColor 255 times', function(done) {
            +            //it is 256^1 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 255; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 0 after calling increaseFillColor 65535 times', function(done) {
            +            //it is 256^2 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 65535; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 255 after calling increaseFillColor 16777215 times', function(done) {
            +            //it is 256^3 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 16777215; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And when you run mocha the tests will fail because that function does not exist!  Let’s add a skeleton function in sketch.js inside the ColorIncreaser class below the constructor function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Now when you run mocha the tests fail for a different reason.  It finds the function, but it doesn’t do what you expect it to.  Let’s change the function in sketch.js to look like what is inside the draw function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +
            +            this.fillColor.levels[0] += this.colorValueIncrease
            +            this.numColorsSoFar += 1
            +
            +
            +            if (this.fillColor.levels[0] > 255) {
            +              this.fillColor.levels[0] = 0
            +              this.fillColor.levels[1] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[1] > 255) {
            +              this.fillColor.levels[1] = 0
            +              this.fillColor.levels[2] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[2] > 255) {
            +              this.fillColor.levels[2] = 0;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        And now your tests pass!  Hooray!<br />
            +        Now you just need to get the draw function set up.  Replace the draw function in sketch.js with this:
            +        <pre><code class="language-javascript">
            +          function draw() {
            +            fill(colorIncreaser.fillColor);
            +            rect(0, 0, 500, 500);
            +            colorIncreaser.increaseFillColor()
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        All tests should pass now and you can expect your code to behave as you want!  As a bonus when you change the code in the future the tests will let you know that it still works as intended!<br />
            +        Congratulations, you made it to the end! Unit tests and Test Driven Development are powerful ways to build code that you know works just as you expect. <br />
            +        You can continue to build on your skills by
            +      </p>
            +        <ul class="bullet-list">
            +          <li>adding tests to your own sketches and projects</li>
            +          <li>Reading up on the tools we’ve used here:</li>
            +          <ul class="bullet-list">
            +            <li><a href='http://www.agiledata.org/essays/tdd.html'>Test Driven Development and Unit tests</a></li>
            +            <li><a href='https://www.npmjs.com/'>Node Package Manager (NPM)</a></li>
            +            <li><a href='http://chaijs.com/'>Chai</a></li>
            +            <li><a href='https://mochajs.org/'>Mocha</a></li>
            +            <li><a href='https://en.wikipedia.org/wiki/Mock_object'>Mock Objects</a></li>
            +          </ul>
            +        </ul>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/test-tutorial.html b/dist/ko/learn/test-tutorial.html
            new file mode 100644
            index 0000000000..893106834b
            --- /dev/null
            +++ b/dist/ko/learn/test-tutorial.html
            @@ -0,0 +1,178 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>test tutorial title</h1>
            +
            +      <p>Blah blah blah. Here is some formatted code:</p>
            +
            +      <pre><code class="language-javascript">
            +      var note = "this is formatted code!";
            +      </code></pre>
            +
            +      <p>Blah blah blah. Here is an iframe embedded:</p>
            +
            +      <iframe src="../../assets/learn/test-tutorial/embed.html" width="600" height="400"></iframe>
            +
            +      <p>Blah blah blah. Here is p5-widget embedded:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +
            +function draw() {
            +  background(255, 0, 200);
            +}
            +</script>
            +
            +      <p>The end!</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/transformations.html b/dist/ko/learn/transformations.html
            new file mode 100644
            index 0000000000..6fc3de69af
            --- /dev/null
            +++ b/dist/ko/learn/transformations.html
            @@ -0,0 +1,615 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by Gene Kogan. It was ported to P5 by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +
            +      </div>
            +
            +      <h1>Transformations</h1>
            +
            +      <p>
            +      The p5.js canvas works like a piece of graph paper. When you want to draw something, you specify its coordinates on the graph. For example, we can draw a 40x40 pixel rectangle at the point (30, 30).
            +      </p>
            +
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      If you want to move your rectangle 50 pixels to the right and 50 pixels down, you can add that to the x and y-coordinates of the rectangle and run rect(80, 80, 40, 40). But there is another way to do this:
            +      move the graph paper itself. If you move the graph paper 50 pixels right and 50 pixels down, you will get exactly the same visual result. Moving the coordinate system is called translation, and can be done using the translate() function.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	translate(50, 50);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      As far as the rectangle is concerned, it hasn't moved at all. Its upper left corner is still at (30, 70). When you use transformations, the things you draw never change position; the coordinate system itself does. We will see how this can be useful in the next section.
            +    </p>
            +      <h2>push() and pop()</h2>
            +
            +      <p>
            +      Sometimes, a sketch will involve multiple translations to draw the same thing in different locations. If we want to draw the same rectangle in three separate locations -- say at (25, 25), (50, 75), and (75, 100) -- we can use push() and pop() to
            +      keep track of and revert our translations as we go. The function pop() undoes all translations made following the previous push(). push() and pop() also track and revert style and,  color changes -- fill(), stroke(), etc -- in the same way. Thus all translations
            +      and style/color commands made between a single push() and pop() apply only to the operations made between them. Take a look at the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw() {
            +	background(240);
            +
            +	push();
            +  	translate(25, 25);
            +	fill(255, 0, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(75, 100);
            +	fill(0, 255, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(50, 75);
            +	fill(0, 0, 255);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +}
            +      </script>
            +
            +      <p>
            +      The first triangle in red is drawn at (0, 0) after the coordinate system has been translated to the right and down by 25 pixels each. After the first pop() is called, the first translation is undone and the coordinate (0, 0) reverts back to the top-left corner of the canvas.
            +      We call push() and translate(75, 100), now moving the the canvas 75 pixels right and 100 pixels done, and then draw the green rectangle. The second pop() undoes that translation as well. Finally, the blue triangle is done after making the same operation, this time translating 50 pixels right and 75 pixels down.
            +    </p>
            +
            +      <h2>What's the Advantage</h2>
            +
            +      <p>In the last sketch, we could have achieved the same visual output by simply drawing the rectangles at those exact points. Or we could have used translate() without the push() and pop() blocks by undoing each translation manually, e.g. translate(-25, -25) to undo the first translation of (25, 25).</p>
            +      <p>For simple shapes like rectangles, it is easier to not use translations, but rather to specify the points manually. But when we begin to draw more complex shapes, translations become advantageous. Let's take a look at an example where translate(), push(), and pop() are really useful.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +	for (var x = 5; x < 150; x = x+25){
            +		for (var y = 5; y < 200; y = y+25){
            +			push();
            +			translate(x, y);
            +	  		drawHouse();
            +			pop();
            +		}
            +	}
            +}
            +
            +function drawHouse() {
            +	triangle(7.5, 0, 0, 7.5, 15, 7.5);
            +	rect(0, 7.5, 15, 12.5);
            +	rect(6, 15, 5, 5);
            +}
            +      </script>
            +
            +      <p>
            +      In this example, we draw a grid of houses. Instead of having to keep track of the coordinates for every vertex of every house, we simply have one function, drawHouse() which draws a house relative to the point (0, 0). We then create a loop which will translate to the correct point before drawing each house.
            +      </p>
            +
            +      <p>
            +      Using the transformations command allows us to use a single drawing function irrespective of where we intend to draw it on the canvas, while push() and pop() allow us to reserve transformations only to the relevant code blocks.
            +      </p>
            +
            +      <h2>Rotation</h2>
            +
            +      <p>
            +      In addition to translating the grid, you can also rotate it with the rotate() function. This function takes one argument, the angle of rotation. It then rotates the canvas around the origin point (0, 0). It's as though you have a piece of graph paper, place your finger on the point (0, 0), and then rotate the paper around your finger.
            +      </p>
            +
            +      <p>Angle is measured clockwise with zero being at 3 o'clock. In p5.js, all the functions having to do with angles take radians. A single rotation or a full circle has 360° or 2π radians. Here is a diagram of how p5.js measures angles in degrees (black) and radians (red).</p>
            +
            +      <img src="../../assets/learn/transformations/angles.png" style="width:150px;">
            +
            +      <p>Since most people think in degrees, p5.js has a built-in radians() function which takes a number of degrees as its argument and converts it to radians for you. It also has a degrees() function that converts radians to degrees. Take a look at the following example which rotates the canvas by an angle measurement set by the mouseX position.
            +      The red square is drawn before rotation, and the green one after rotation.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw() {
            +	var deg = mouseX;
            +	var rad = radians(deg);
            +
            +	background(240);
            +
            +	// the red rectangle is drawn before the rotation so
            +	// it will stay in place
            +	fill(255, 0, 0);
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 50);
            +
            +	fill(0, 255, 0);
            +	text("rotate "+floor(deg)+" degrees", 50, 25);
            +
            +	// rotation is done here. all subsequent drawing
            +	// is done post-rotation
            +	rotate(rad);
            +
            +	// draw the grid
            +	drawGrid();
            +
            +	// the green rectangle and grid is drawn after rotating the canvas
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 500);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +    fill(120);
            +	for (var x=-2*width; x < 2*width; x+=40) {
            +		line(x, -2*height, x, 2*height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-2*height; y < 2*height; y+=40) {
            +		line(-2*width, y, 2*width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <h2> Rotating in place</h2>
            +
            +      <p>In the last example, the green square goes off the screen as we rotate the canvas more. Sometimes we want to be able to rotate a shape in place, rather than around the top-left corner of the screen. We can do this by combining translate() and rotate() together. Recall that translate() moves the origin (0,0) to another place in the canvas and that rotate() rotates the canvas around the origin.
            +        Thus if we want to draw a shape in the middle of the screen and then rotate it in place, we should first translate the canvas to the point we want to draw the shape, then rotate, then draw the shape at (0, 0). Take a look at the following example.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +        <p>If you want the rectangle to rotate around its own center point rather than by its corner, we can use the command rectMode(CENTER) to set p5.js to interpret the coordinates of rectangles to refer to the center of the rectangle rather than the top-left corner. The following example is the same as the previous one but with centered coordinates.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +	rectMode(CENTER);	// now the first two arguments of a rect are its center point, not corner
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +      <p>Here is a program that generates a wheel of colors by using rotation, and draws a strip every 25 frames.</p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	background(240);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	// the modulo operator % calculates the remainder.
            +	// example: 24 % 25 = 24, 25 % 25 = 0, 26 % 25 = 1, etc.
            +	// thus this if statement will evaluate True every 25 frames.
            +	if (frameCount % 25 == 0) {
            +		fill(random(255), random(255), random(255));
            +		push();
            +		translate(75, 100);
            +		rotate(radians(frameCount));
            +		rect(0, 0, 100, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +        <h2>Rotational Symmetry</h2>
            +
            +        <p>
            +        Let's take a look at a more complicated example where we can use translate and rotate together to create interesting symmetries around the center of the canvas. Let's first build it by drawing 8 squares which are evenly distributed along a circle around the center of the canvas. What we do is we first translate to the center of the screen, translating the canvas by (width/2, height/2).
            +        We then rotate the canvas to the 8 angles evenly distributed between 0 and 2π radians. We then draw a circle 50 pixels away from the center, after each of these rotations.
            +        </p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		rect(50, 0, 10, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +      <p>
            +        Look at the line rect(50, 0, 10, 10). Recall that you can draw a shape in the same place by translating to it first and then drawing it at (0, 0). So we can do another another translation after we've rotated, to translate along the right-pointing line after it's been rotated. So we can replace the statement rect(50, 0, 10, 10) with the following two: translate(50, 0) and rect(0, 0, 10, 10).
            +        By doing so, we bring the pivot point or origin of the canvas to each of the eight rectangles we just drew.
            +      </p>
            +
            +      <p>
            +        This is convenient because now we can do something even more interesting. Instead of simply drawing a rectangle at each of those points, let's create another loop which will draw six smaller squares evenly distributed around a small circle around each of these new pivot points. See the following.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		translate(50, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			rect(15, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <p>
            +        Now that we have achieved an interesting geometry, we can embellish this program by making a variable for the first translation amount and for the x-position of the rectangle, and modulating them in interesting ways. In the following example, we'll modulate those two values using Perlin noise. If you haven't used Perlin noise before, take a look at the tutorial on Perlin noise.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		var tx = 100 * noise(0.01*frameCount);
            +		translate(tx, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			var rx = 30 * noise(0.01*frameCount + 10);
            +			rect(rx, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +      <p>Now we're getting somewhere! Let's take the previous example and make the following additions to it to make it even more interesting.</p>
            +
            +      <p>
            +        <ul class="list_view">
            +          <li>Extra rotation variables so the whole circle rotates with perlin noise</li>
            +          <li>Red + Blue = Purple</li>
            +          <li>Additional noisy in-place rotation of the drawn shapes</li>
            +          <li>Noisy modulation of the size of the shapes being drawn</li>
            +        </ul>
            +      </p>4
            +
            +      <p>All the noisy variables will be calculated at the top of the draw loop for better organization. Looks cool, right?!</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +	fill(0, 50);
            +	stroke(255, 50);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var ang1 = TWO_PI * noise(0.01*frameCount + 10);
            +	var ang2 = TWO_PI * noise(0.01*frameCount + 20);
            +	var ang3 = TWO_PI * noise(0.01*frameCount + 30);
            +	var rx = 30 * noise(0.01*frameCount + 40);
            +	var tx = 100 * noise(0.01*frameCount + 50);
            +	var size1 = 100 * noise(0.01*frameCount + 60);
            +	var size2 = 20 * noise(0.01*frameCount + 60);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(ang1 + TWO_PI * i / 8);
            +		translate(tx, 0);
            +		rect(0, 0, size1, size1);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(ang2 + TWO_PI * j / 6);
            +			translate(rx, 0);
            +			rotate(ang3);
            +			rect(rx, 0, size2, size2);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <h2>Scaling</h2>
            +
            +      <p>
            +        There is one more function which transforms the coordinate system, and that is scale(). Scale changes the size of the grid by multiplying the coordinate system. See the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var scaleAmount = mouseX / 100;
            +  	scale(scaleAmount);
            +
            +	drawGrid();
            +  	fill(255, 255, 0);
            +  	rect(20, 20, 50, 50);
            +}
            +
            +function drawGrid() {
            +	fill(0);
            +	stroke(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/trigonometry.html b/dist/ko/learn/trigonometry.html
            new file mode 100644
            index 0000000000..bf2f26b6be
            --- /dev/null
            +++ b/dist/ko/learn/trigonometry.html
            @@ -0,0 +1,189 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <h2>Trigonometry Primer</h2>
            +      <p>(learning to love triangles)</p>
            +      <div class="attribution">
            +        This tutorial was written during the first p5.js developers conference by Tega Brain.
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="pythagoras">Pythagoras Theorum</h3>
            +      <div class="info">
            +        <p>Trigonometry is a branch of geometry that is fundamental to all graphics programming.  It provides useful equations that enable you to figure out distances between points and how curves and circles can be described in Cartesian coordinates. Remember Cartesian coordinates are points described by x and y values. Trigonmetry also enables you to do things like move shapes in circular motion or oscillate values smoothly back and forth between two extremes.</p>
            +
            +
            +        <p>The right angled triangle is one of the most important parts of trigonometry and Pythagoras was a guy who got pretty famous for figuring out a theorem that relates the length of each of its sides. Pythagora figured out that in every right hand triangle, if you square each of the two shortest sides, their sum equals the square of the longest side.</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/pythagoras1.jpg" />
            +
            +        <p>Right angled triangles are special also because each of their angles has a specific relationship to the ratio between the length of two of their sides. This is what sine, cosine and tangent functions describe. Sin cos and tan are known as trigonometric functions and they give us the relationship between the ratio of two of the triangle’s sides and one of the angles of the triangle. You may recall the acronym: SOH-CAH-TOA that helps you remember how sinθ, cosθ and tanθ relate to the ratio of which of the triangle’s sides.</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/hypotenuse.jpg" />
            +        
            +        <p>This is all pretty great, because is means that with just a couple of pieces of information about a right angled triangle, like knowing two of its side lengths or maybe knowing one of its angle and a side length, you can use Pythagora’s theorem in combination with the sin, cos and tan equations to figure out everything else.</p>
            +
            +        <p>These triangles are also helpful as they help us to map and understand the x and y coordinates of points along curves and circles. Notice how in the drawing below you can see how any point on a circle will have a relationship to a right angled triangle. This relationship means that a point on a circle can be understood in two ways. Firstly, as we have seen a point can be described by Cartesian coordinates which are of course, by x and y co-ordinates, but it can also be described using polar coordinates. Polar coodinates are an angle and a distance from the origin (the radius of the circle).</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/polar.jpg" />
            +      </div>
            +        
            +      <h3 class = "start-element tutorial-btn" id="Polar Coordinates">Polar Coordinates</h3>
            +      <div class="info">
            +        <p>Polar coordinates describe a point using an angle and a distance from the origin. This is useful when you are coding something like an analog clock. When drawing a clock, you would need to place each hand at a particular angle, for example, 3pm is at zero degrees and midday is at 90 degrees. Each hand would be coded as a line drawn onto a screen, that connects two points. So these hand would connect the origin to the x,y coordinates that is at the position of the time. Putting anything on a screen always requires you to describe it in terms of x and y.</p>
            +        
            +        <p>So how do we convert between polar coordinates and x-y coordinates?</p>
            +        
            +        <p>The relationship between polar coordinates and x,y coordinates can be calculated using a unit circle. This is a circle that has a radius of 1 unit which is useful because it means the hypotenuse in your right angled triange is always 1.</p>
            +
            +        <iframe src="../../assets/learn/trigonometry/unitCircle/embed.html" width="600" height="400"></iframe>
            +
            +
            +      </div>
            +      
            +      <h3 class="start-element tutorial-btn" id="sin">Using Sin and Cosine</h3>
            +      <div class="info">
            +        <iframe src="../../assets/learn/trigonometry/sincoscurves/embed.html" width="800" height="750"></iframe>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/learn/tutorial-guide.html b/dist/ko/learn/tutorial-guide.html
            new file mode 100644
            index 0000000000..fb7ea70baf
            --- /dev/null
            +++ b/dist/ko/learn/tutorial-guide.html
            @@ -0,0 +1,262 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>p5.js 튜토리얼 기여를 위한 가이드</h1>
            +      <div class="attribution">
            +        이 튜토리얼은 테가 브레인(Tega Brain)이 제작하였습니다.
            +      </div>
            +      <p>
            +        p5.js 튜토리얼은 이에 열정을 느끼는 교육자와 모든 분들께 열려있습니다. p5.js 프로젝트는 보다 다양한 사람들을 위한 크리에이티브 코딩 및 오픈 소스 개발을 추구하며, 모든 개발 과정을 공개하는 것을 하나의 즐거운 과정으로 여깁니다. 현재까지 제작된 튜토리얼은 p5 학습, 프로그래밍 기술, 오픈소스 프로젝트 공헌 방법 등에 대한 내용을 다룹니다.
            +      </p>
            +      <p>
            +        새로운 튜토리얼을 제안하거나, 튜토리얼 준비 및 기여에 대한 가이드라인 제작을 환영합니다.
            +      </p>
            +
            +      <h2>커뮤니티 기여 시작하기:</h2>
            +      <ul class="list_view">
            +        <li>
            +          우선, 제안하려는 튜토리얼이 현재 진행 중인 내용들과 겹치는 지의 여부를 이 <a href="https://docs.google.com/spreadsheets/d/1sh3IwcCUY4Bm8N4fRZw6CwSDdQmmXgY_awjVj-UC8mo/edit#gid=0">스프레드시트</a>
            +          에서 확인하세요. 만약 제안하고자 하는 튜토리얼 주제가 현재 진행 중인 것이라면, 해당 주제의 마무리 작업 또는 p5.js 웹사이트상의 공개 작업에 참여할 수 있고 관련해서는 아래의 이메일로 연락주시면 감사하겠습니다. 
            +        </li>
            +        <li>
            +          제안하려는 튜토리얼이 스프레드시트 리스트에 포함되지 않는다면, 튜토리얼에 대한 간략한 설명을 education@p5js.org로 보내주세요.
            +        </li>
            +      </ul>
            +      <h2>p5.js 튜토리얼 온라인 공개 준비하기:</h2>
            +      <p>
            +        튜토리얼을 p5.js 웹사이트상 공개할 준비가 되었다면, 다음의 단계를 따라주세요.
            +      </p>
            +      <p>
            +        튜토리얼 콘텐츠를 이 <a href="https://github.com/mayaman/p5js-website/blob/master/src/templates/pages/learn/test-tutorial.hbs">기본 구조</a>
            +        에 따라 tutorial-name.hbs 파일로 변환해주세요. 콘텐츠에는 아래와 같은 헤더(header)가 반드시 포함되어야 합니다:
            +      </p>
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-1.png" alt="Screenshot">
            +
            +      <p>
            +        튜토리얼을 포함한 폴더는 p5js 웹사이트 상 'tutorials' 폴더에 배치됩니다. index.hbs 파일은 <a href="/ko/learn/">p5.js 튜토리얼 랜딩 페이지</a>
            +        에 해당하며, test-tutorial.hbs 파일은 테스트 튜토리얼입니다.
            +      </p>
            +      <p>
            +        모든 콘텐츠는 페이지상
            +       
            +        &lt;section &gt; &lt;/section&gt;
            +        태그에 포함되어야하며, &lt;h1&gt; 와 &lt;h2&gt; 태그, 그리고 &lt;p&gt; 문단 태그로서 문서 형식이 정의되어야 합니다. 형식 예시는 다음의 페이지에서 확인해보세요:  <a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs">테스트 튜토리얼</a></p>
            +      <p>
            +        튜토리얼이 이미지 파일을 포함할 경우, p5 웹사이트의 에셋(assets) 폴더에 배치됩니다. 파일 경로는 아래와 같이 src/assets/learn/test-tutorial/images에 해당합니다.
            +      </p>
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-2.png" alt="Screenshot">
            +      <p>
            +        페이지의 HTML에 형식을 맞추기 위해 다음의 태그를 사용하세요:
            +      </p>
            +       
            +        <pre><code class="language-javascript">
            +&lt;pre&gt;&lt;code class="language-javascript"&gt;
            +Your code here!
            +&lt;/code>&lt;/pre&gt;
            +
            +</code></pre>
            +
            +      <h2>웹페이지에 p5.js 스케치 올리기(embedding)</h2>
            +      <p>
            +        p5.js를 사용한다는 것은 튜토리얼 설명을 위해 예제에 각종 애니메이션, 인터랙션, 그리고 수정 기능을 포함할 수 있음을 뜻합니다. 이 경우, 튜토리얼 예제는 p5.js 스케치의 형태로 준비되어야하며, 튜토리얼 페이지상 다음의 두가지 방식으로 임베드될 수 있습니다.
            +      </p>
            +
            +      <ol>
            +        <li>
            +          만약 튜토리얼 예제가 p5.js 웹페이지의<a href="http://p5js.org/reference/#/p5/ellipse">레퍼런스</a>와 같이 코드를 수정할 수 있는 형태라면, p5js 위젯을 사용하여 HTML 페이지에 임베드할 수 있습니다.<a href="https://toolness.github.io/p5.js-widget/">이 가이드</a>를 따라 위젯으로 p5js를 임베드하는 방법에 대해 알아보세요. 가이드는<a href="https://github.com/toolness">Toolness</a>가 작성하였습니다. 이러한 사례에 해당하는 튜토리얼이 작동하는 모습은 <a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs">테스트 튜토리얼 페이지</a>에서 확인할 수 있습니다.</li>
            +        <li>
            +          튜토리얼 예제가 애니메이션 그리고/또는 인터랙션을 포함하나 코드 수정 기능을 포함하지 않는다면, 다음과 같이 iframe을 사용하여 p5.js 스케치를 페이지상 임베드할 수 있습니다.
            +        </li>
            +      </ol>
            +
            +      <h2>iframe을 사용하여 p5 스케치 임베드하기</h2>
            +
            +      <p>
            +        iframe은 한 페이지상 다른 페이지를 보기 위해 만드는 창문틀과도 같습니다. 이 창문틀을 따라 페이지상의 다른 내용들로부터 구분되는 셈이지요. 이 경우, p5.js 스케치를 포함한 index.html를 보여주는 창문틀의 역할을 합니다. 
            +      </p>
            +      <img src="https://github.com/tegacodes/p5.js-education/raw/master/images/iframe-2.jpg" alt="tutorialFileStructure" width="600">
            +
            +      <p>
            +        스크린샷에 보이듯, p5 웹사이트 /src/assets/learn 폴더에 스케치의 이름을 딴 별도의 폴더를 새로이 생성하여 여러분의 튜토리얼용 p5 스케치를 올리세요. 이 경로를 통해 iframe에서 보여줄 모든 이미지와 p5 스케치가 저장됩니다.
            +      </p>
            +
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-3.png" alt="Screenshot">
            +
            +<p>여러분의 p5 예제를 포함한 폴더의 하위에는 sketch.js 파일과 embed.html 파일이 반드시 있어야 합니다.</p>
            +<img src="../../assets/learn/tutorial-guide/images/screenshot-4.png" alt="Screenshot">
            +
            +<p>embed.html 파일이 웹사이트의 p5 라이브러리와도 일치하는지를 확인하세요. 만약, 여러분의 파일 구조가 위와 같다면 p5.js 라이브러리 경로는 "../../../js/p5.min.js" 일것 입니다.</p>
            +<p>그리고나면, 튜토리얼 콘텐츠를 담고 있는 .hbs 파일상 p5js index 파일을 iframe의 형태로 임베드할 수 있습니다. iframe 임베드를 위한 코드는 다음과 같습니다: </p>
            +  <pre><code class="language-javascript">
            +&lt;iframe src="http://p5js.org/assets/learn/tes-tutorial/embed.html" width="600" height="400"&gt;
            +&lt;/iframe&gt;
            +</code></pre>
            +
            +<p>iframe 서식 바꾸기:  </p>
            +  <pre><code class="language-javascript">
            +&lt;style&gt; iframe{ border: none; } &lt;/style&gt;
            +</code></pre>
            +
            +<p>iframe을 이용한 무제 스케치 작동 확인하기: </p>
            +<a href="http://staging.p5js.org/assets/learn/test-tutorial/embed.html">http://staging.p5js.org/assets/learn/test-tutorial/embed.html</a>
            +
            +<p>위의 스케치가 p5 site에 임베드된 모습:  </p>
            +<a href="http://staging.p5js.org/learn/test-tutorial.html">http://staging.p5js.org/learn/test-tutorial.html</a>
            +
            +<p>한가지 주의해야할 점은, iframe의 사이즈는 반드시 직접 조정해야된다는 것입니다. 특히, 튜토리얼 콘텐츠의 크기가 규격화된 경우 그러합니다.</p>
            +
            +<p>또한, p5.js 라이브러리 파일 연결 링크는 튜토리얼 콘텐츠가 포함되어있는 .eps 페이지가 아닌, 스케치를 렌더링하는 별도의 html 페이지에 위치합니다. (이 경우, 해당 html 페이지의 명칭은 embed.html입니다.)</p>
            +
            +<p>p5.js 스케치를 임베드하는 방법에 대해 더 알고 싶다면 다음의 링크를 확인하세요: <a href="https://github.com/processing/p5.js/wiki/Embedding-p5.js">링크</a></p>
            +<h2>마무리하기</h2>
            +<p>앞서 언급된 메일을 통해 튜토리얼 콘텐츠 확인을 마쳤다면, p5.js-website repository를 Fork 하세요. 그리고 상기된 방법에 따라 콘텐츠를 준비하고 풀 리퀘스트(pull request)를 하여, 여러분의 기여 내용이 웹사이트에 공개될 수 있도록 하세요!</p>
            +
            +    <p>감사합니다!</p>
            +
            +  </main>
            +
            +  
            +  <footer>
            +    <h2 class="sr-only">크레딧</h2>
            +    <p>
            +      p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +    </p>
            +  </footer>
            +
            +</div> <!-- end column-span -->
            +
            +
            +<!-- outside of column for footer to go across both -->
            +
            +<p class="clearfix"> &nbsp; </p>
            +
            +<object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +</object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/libraries/index.html b/dist/ko/libraries/index.html
            new file mode 100644
            index 0000000000..a3f99834df
            --- /dev/null
            +++ b/dist/ko/libraries/index.html
            @@ -0,0 +1,932 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">libraries | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="libraries-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>라이브러리</h1>
            +
            +      <h2>라이브러리 이용하기</h2>
            +
            +      <p>라이브러리란 p5.js의 핵심 기능을 확장하거나 추가하는 자바스크립트 코드를 말합니다. 라이브러리에는 크게 두 종류가 있습니다. 주요 라이브러리인 <a
            +          href="/ko/reference/#/libraries/p5.sound">p5.sound</a>의 경우 p5.js 자체 배포물인 반면, 커뮤니티 라이브러리는 커뮤니티 공헌자에 의해 개발, 소유, 유지됩니다.</p>
            +
            +      <p>스케치에 라이브러리를 사용하려면 우선 스케치에 p5.js 링크를 걸고, 그 다음 HTML 파일에 라이브러리 링크를 걸면 됩니다. 링크가 걸린 HTML 파일은 이렇게 보입니다:</p>
            +      <pre><code class="language-markup">&lt;!doctype html&gt;
            +&lt;html>
            +&lt;head>
            +  &lt;script src="p5.js"&gt;&lt;/script&gt;
            +  &lt;script src="p5.sound.js"&gt;&lt;/script&gt;
            +  &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +&lt;/head&gt;
            +&lt;body&gt;
            +&lt;/body&gt;
            +&lt;/html&gt;
            +      </code></pre>
            +
            +      <h2>나만의 라이브러리 만들기</h2>
            +
            +      <p>p5.js는 여러분만의 라이브러리 제작을 환영합니다! 라이브러리 제작에 대해 더 알고 싶다면 
            +        <a href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +          라이브러리 튜토리얼</a>
            +        을 확인해보세요. 제작한 라이브러리를 이 페이지에 추가하고 싶다면 
            +        <a href="https://docs.google.com/forms/d/e/1FAIpQLSdWWb95cfvosaIFI7msA7XC5zOEVsNruaA5klN1jH95ESJVcw/viewform"
            +          target="_blank">이 문서를 제출하세요!</a></p>
            +
            +      
            +      
            +      <h2 class="tutorial-title">주요 라이브러리</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="/ko/reference/#/libraries/p5.sound" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.sound.jpg">
            +              <h3>p5.sound</h3>
            +            </a>
            +          </div>
            +          <p>p5.sound는 p5에 웹 오디오 기능(오디오 입력, 재생, 분석 합성 등)을 추가합니다.  제작: 
            +            <a href="https://www.jasonsigal.cc/"
            +              target="_blank">Jason Sigal</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/processing/p5.accessibility" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.accessibility.jpg">
            +              <h3>p5.accessibility</h3>
            +            </a>
            +          </div>
            +          <p>p5.accessibility는 p5 캔버스에 대한 맹인 또는 시각 장애인의 접근성을 향상합니다.  
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +      
            +      <h2 class="tutorial-title">커뮤니티 라이브러리</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/asciiart" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/asciiart.jpg">
            +              <h3>asciiart</h3>
            +            </a>
            +          </div>
            +          <p>p5.asciiart는 p5.js를 아스키(ASCII) 아트로 쉽고 간단하게 변환합니다. 한마디로, p5.js를 위한 아스키 아트 컨버터입니다.  제작: 
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://itpnyu.github.io/p5ble-website/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.ble.jpg">
            +              <h3>p5.ble</h3>
            +            </a>
            +          </div>
            +          <p>p5.ble은 BLE 기기와 p5 스케치를 연결합니다.  제작: 
            +            <a href="https://1023.io"
            +              target="_blank">Yining Shi</a>, <a href="https://www.jingwen-zhu.com/"
            +              target="_blank">Jingwen Zhu</a>, <a href="https://tigoe.com/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/sarahgp/p5bots" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.bots.jpg">
            +              <h3>p5.bots</h3>
            +            </a>
            +          </div>
            +          <p>p5.bots를 통해 브라우저, 아두이노, 마이크로프로세서 간의 인터랙션을 만들 수 있습니다. 센서 데이터로 스케치를 만들거나, 스케치에서 LED나 모터를 작동해보세요!  제작: 
            +            <a href="http://www.sarahgp.com"
            +              target="_blank">Sarah Groff-Palermo</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Lartu/p5.clickable" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.clickable.jpg">
            +              <h3>p5.clickable</h3>
            +            </a>
            +          </div>
            +          <p>사용이 편리한, 이벤트 기반 p5.js 버튼 라이브러리입니다. 제작: 
            +            <a href="https://www.lartu.net"
            +              target="_blank">Martín del Río</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/p5.cmyk.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.cmyk.js.jpg">
            +              <h3>p5.cmyk.js</h3>
            +            </a>
            +          </div>
            +          <p>CMYK 색상 모드. 제작: 
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.collide2D" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.collide2D.jpg">
            +              <h3>p5.collide2D</h3>
            +            </a>
            +          </div>
            +          <p>p5.collide2D는 p5.js로 만든 2D 도형들 간의 충돌을 감지합니다.  제작: 
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.npmjs.com/package/p5.createloop" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.createloop.jpg">
            +              <h3>p5.createloop</h3>
            +            </a>
            +          </div>
            +          <p>노이즈와 GIF 기반의 반복 애니메이션을 단 한 줄의 코드로 만들어보세요.  제작: 
            +            <a href="https://www.piratesjustar.com/"
            +              target="_blank">Peter Hayman</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Smilebags/p5.dimensions.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.dimensions.jpg">
            +              <h3>p5.dimensions</h3>
            +            </a>
            +          </div>
            +          <p>p5.dimensions은 p5.js의 벡터 기능을 확장하여 n차원에서 작동하도록 합니다.  제작: 
            +            <a href="https://github.com/Smilebags"
            +              target="_blank">Smilebags</a>, <a href="https://github.com/max0410"
            +              target="_blank">Max Segal</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/freshfork/p5.EasyCam" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.EasyCam.jpg">
            +              <h3>p5.EasyCam</h3>
            +            </a>
            +          </div>
            +          <p>패닝, 줌, 회전이 가능한 간단한 3D 카메라 컨트롤. Thomas Diewald가 핵심적으로 기여하였습니다.  제작: 
            +            <a href="https://jwilliamdunn.com"
            +              target="_blank">jWilliam Dunn</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/loneboarder/p5.experience.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.experience.jpg">
            +              <h3>p5.experience</h3>
            +            </a>
            +          </div>
            +          <p>확장형 p5.js 라이브러리로, 캔버스 기반 웹 어플리케이션 제작을 위한 이벤트리스닝 기능을 추가할 수 있습니다.  제작: 
            +            <a href="https://github.com/loneboarder"
            +              target="_blank">Felix Meichelböck</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-func" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.func.jpg">
            +              <h3>p5.func</h3>
            +            </a>
            +          </div>
            +          <p>p5.func은 시간, 빈도, 그리고 공간 기능 생성을 위한 새로운 객체 및 기능을 제공합니다.  제작: 
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.geolocation" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.geolocation.jpg">
            +              <h3>p5.geolocation</h3>
            +            </a>
            +          </div>
            +          <p>p5.geolocation은 사용자 위치를 획득, 관찰, 계산, 지오펜싱(geo-fencing)하기 위한 기술을 제공합니다.  제작: 
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://charlie-roberts.com/gibber/p5-gibber/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.gibber.jpg">
            +              <h3>p5.gibber</h3>
            +            </a>
            +          </div>
            +          <p>p5.gibber는 음악 시퀀싱 및 오디오 합성 기능을 빠른 속도로 제공합니다.  제작: 
            +            <a href="https://charlie-roberts.com"
            +              target="_blank">Charlie Roberts</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jagracar/grafica.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/grafica.js.jpg">
            +              <h3>grafica.js</h3>
            +            </a>
            +          </div>
            +          <p>grafica.js는 p5.js 스케치상 변형이 쉬운 2D 플롯을 추가합니다.  제작: 
            +            <a href="https://jagracar.com/p5jsSketches.php"
            +              target="_blank">Javier Graciá Carpio</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bitcraftlab/p5.gui" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.gui.jpg">
            +              <h3>p5.gui</h3>
            +            </a>
            +          </div>
            +          <p>p5.gui는 p5.js 스케치를 위한 그래픽 유저 인터페이스를 생성합니다.  제작: 
            +            <a href="https://www.bitcraftlab.com/"
            +              target="_blank">Martin Schneider</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.localmessage" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.localmessage.jpg">
            +              <h3>p5.localmessage</h3>
            +            </a>
            +          </div>
            +          <p>p5.localmessage는 멀티윈도우 스케칭을 위한 스케치 간 로컬 메시지 전송 기능 및 인터페이스를 제공합니다.  제작: 
            +            <a href="https://benmoren.com"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/marching" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/marching.jpg">
            +              <h3>marching</h3>
            +            </a>
            +          </div>
            +          <p>래스터에서 벡터로의 변환, 등면. 제작: 
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/cvalenzuela/Mappa" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/mappa.jpg">
            +              <h3>mappa</h3>
            +            </a>
            +          </div>
            +          <p>Mappa는 정적 맵, 타일 맵, 지오 데이터 활용을 위한 툴을 제공합니다. 지리 정보 기반의 시각적 재현물을 제작할 때 용이합니다.  제작: 
            +            <a href="https://github.com/cvalenzuela/"
            +              target="_blank">Cristóbal Valenzuela</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://ml5js.org/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/ml5.js.jpg">
            +              <h3>ml5.js</h3>
            +            </a>
            +          </div>
            +          <p>ml5.js는 Tensorflow.js를 기반으로하며, 머신러닝 알고리즘 및 모델에 대한 브라우저상의 접근성을 높입니다.  제작: 
            +            <a href="https://ml5js.org/"
            +              target="_blank">NYU ITP/IMA and contributors</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="http://p5play.molleindustria.org" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.play.jpg">
            +              <h3>p5.play</h3>
            +            </a>
            +          </div>
            +          <p>p5.play는 게임과 같은 어플리케이션 제작을 위한 스프라이트(sprite), 애니메이션, 인풋, 충돌 기능을 제공합니다.  제작: 
            +            <a href="https://www.molleindustria.org/"
            +              target="_blank">Paolo Pedercini</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bobcgausa/cook-js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.particle.jpg">
            +              <h3>p5.particle</h3>
            +            </a>
            +          </div>
            +          <p>파티클은 사용자가 직접 제작한 구조나 기능, 또는 JSON 인풋 데이터를 사용하여 시각적 효과를 만드는 데에 쓰입니다.  제작: 
            +            <a href="http://professorcook.org/"
            +              target="_blank">Robert Cook</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://antiboredom.github.io/p5.riso" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.Riso.jpg">
            +              <h3>p5.Riso</h3>
            +            </a>
            +          </div>
            +          <p>p5.Riso는 석판화와 같은 파일을 생성하는 라이브러리입니다. 스케치를 다양한 색상의 판화처럼 만들어줍니다.  제작: 
            +            <a href="https://lav.io/"
            +              target="_blank">Sam Lavigne</a>, <a href="https://tegabrain.com/"
            +              target="_blank">Tega Brain</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://rednoise.org/rita" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/rita.js.jpg">
            +              <h3>rita.js</h3>
            +            </a>
            +          </div>
            +          <p>RiTa.js는 제너레이티브 문학을 위한 자연어 처리 객체를 제공합니다.  제작: 
            +            <a href="https://rednoise.org/daniel"
            +              target="_blank">Daniel C. Howe</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://codeforartists.com/RotatingKnobMaker" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/Rotating_knobs.jpg">
            +              <h3>Rotating knobs</h3>
            +            </a>
            +          </div>
            +          <p>Make knobs you can rotate with custom graphics and return value ranges. 제작: 
            +            <a href="https://codeforartists.com"
            +              target="_blank">Miles DeCoster</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/mveteanu/p5.SceneManager" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.scenemanager.jpg">
            +              <h3>p5.scenemanager</h3>
            +            </a>
            +          </div>
            +          <p>p5.SceneManager는 스케치를 여러 단계의 씬들로 구성할 수 있도록 합니다. 각각의 씬은 메인 스케치에 포함된 일부 스케치와도 같습니다.  제작: 
            +            <a href="https://github.com/mveteanu/"
            +              target="_blank">Marian Veteanu</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bohnacker/p5js-screenPosition" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.screenPosition.jpg">
            +              <h3>p5.screenPosition</h3>
            +            </a>
            +          </div>
            +          <p>프로세싱의 screenX 및 screenY 기능을 p5js에 적용합니다. 제작: 
            +            <a href="https://hartmut-bohnacker.de/"
            +              target="_blank">Hartmut Bohnacker</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/generative-light/p5.scribble.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.scribble.jpg">
            +              <h3>p5.scribble</h3>
            +            </a>
            +          </div>
            +          <p>2D 기본 조형을 손그림으로 표현합니다. 제작: Janneck Wullschleger, 프로세싱 라이브러리 포트 기반  제작: 
            +            <a href="https://github.com/gicentre/handy"
            +              target="_blank">handy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/vanevery/p5.serialport" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.serial.jpg">
            +              <h3>p5.serial</h3>
            +            </a>
            +          </div>
            +          <p>p5.serial는 시리얼 (RS-232)와 p5 웹 에디터를 지원하는 기기상에서의 직렬 통신을 구현합니다.  제작: 
            +            <a href="https://www.walking-productions.com/notslop/abou/"
            +              target="_blank">Shawn Van Every</a>, <a href="https://kaganjd.github.io/portfolio/"
            +              target="_blank">Jen Kagan</a>, <a href="https://tigoe.net/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/pfe1223/Shape5js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/Shape5.jpg">
            +              <h3>Shape5</h3>
            +            </a>
            +          </div>
            +          <p>Shape5는 코딩을 처음 배우는 초등학생을 위한 2D 기본 조형 라이브러리입니다. 제작: 
            +            <a href="https://github.com/pfe1223"
            +              target="_blank">Patrick Ester</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/gaba5/p5.shape.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.shape.js.jpg">
            +              <h3>p5.shape.js</h3>
            +            </a>
            +          </div>
            +          <p>p5.js 프레임워크에 더 많은 기본 도형을 추가하고자 제작된 라이브러리입니다. 제작: 
            +            <a href="https://github.com/gaba5"
            +              target="_blank">Sebastien Lorentz</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-speech/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.speech.jpg">
            +              <h3>p5.speech</h3>
            +            </a>
            +          </div>
            +          <p>p5.speech는 웹 스피치 및 스피치 인식 API에 대한 접근 권한을 제공하여, 음성을 인식하고 출력할 수 있는 스케치를 쉽게 만들 수 있게 합니다.  제작: 
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/eltapir/p5.start2d.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.start2d.js.jpg">
            +              <h3>p5.start2d.js</h3>
            +            </a>
            +          </div>
            +          <p>픽셀, 밀리미터, 센티미터 또는 인치 단위의 정적인 2D 아트를 만들기 위한 p5 확장 라이브러리입니다.  제작: 
            +            <a href="https://github.com/eltapir"
            +              target="_blank">Kris HEYSE</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/linux-man/p5.tiledmap" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.tiledmap.jpg">
            +              <h3>p5.tiledmap</h3>
            +            </a>
            +          </div>
            +          <p>p5.tiledmap은 스케치에 지도를 넣기 위한 드로잉 및 도움 기능을 제공합니다.  제작: 
            +            <a href="https://softlab.pt/"
            +              target="_blank">Caldas Lopes</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/L05/p5.touchgui" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.touchgui.jpg">
            +              <h3>p5.touchgui</h3>
            +            </a>
            +          </div>
            +          <p>p5.js를 위한 멀티터치 및 마우스 그래픽 유저 인터페이스(GUI) 라이브러리  제작: 
            +            <a href="https://L05.is"
            +              target="_blank">Carlos L05 Garcia</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.tramontana.xyz" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/tramontana.jpg">
            +              <h3>tramontana</h3>
            +            </a>
            +          </div>
            +          <p>Tramontana는 인터랙티브 환경 및 공간을 생성하거나, 공간 속 스케일 기능을 프로토타이핑하기 위한 여러가지 기기(iOS, Android, tramontana Board, ...)를 쉽게 쓸 수 있도록 하는 플랫폼입니다.  제작: 
            +            <a href="https://www.pierdr.com"
            +              target="_blank">Pierluigi Dalla Rosa</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/vida" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/vida.jpg">
            +              <h3>vida</h3>
            +            </a>
            +          </div>
            +          <p>Vida는 카메라(또는 비디오) 기반의 모션 감지 및 얼룩(blob) 트래킹 기능을 더하는 p5js 라이브러리입니다.  제작: 
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Dozed12/p5.voronoi" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.voronoi.jpg">
            +              <h3>p5.voronoi</h3>
            +            </a>
            +          </div>
            +          <p>p5.voronoi는 p5.js 스케치상 보로노이 다이어그램을 그리고 활용할 수 있는 툴을 제공합니다.  제작: 
            +            <a href="https://github.com/Dozed12"
            +              target="_blank">Francisco Moreira</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://p5xr.org/#/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.xr.jpg">
            +              <h3>p5.xr</h3>
            +            </a>
            +          </div>
            +          <p>p5로 VR 및 AR 스케치를 작성하기위한 라이브러리. 제작: 
            +            <a href="https://www.stalgiagrigg.name/"
            +              target="_blank">Stalgia Grigg</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/FreddieRa/p5.3D" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.3D.jpg">
            +              <h3>p5.3D</h3>
            +            </a>
            +          </div>
            +          <p>WebGL로 3D 텍스트 및 이미지를 쓸 수 있습니다.  제작: 
            +            <a href="https://freddierawlins.wixsite.com/site"
            +              target="_blank">Freddie Rawlins</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/reference/assets/Bold.ttf b/dist/ko/reference/assets/Bold.ttf
            new file mode 100644
            index 0000000000..50d81bdad5
            Binary files /dev/null and b/dist/ko/reference/assets/Bold.ttf differ
            diff --git a/dist/ko/reference/assets/Damscray.mp3 b/dist/ko/reference/assets/Damscray.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/ko/reference/assets/Damscray.mp3 differ
            diff --git a/dist/ko/reference/assets/Damscray.ogg b/dist/ko/reference/assets/Damscray.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/ko/reference/assets/Damscray.ogg differ
            diff --git a/dist/ko/reference/assets/Damscray_-_Dancing_Tiger_01.ogg b/dist/ko/reference/assets/Damscray_-_Dancing_Tiger_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/ko/reference/assets/Damscray_-_Dancing_Tiger_01.ogg differ
            diff --git a/dist/ko/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 b/dist/ko/reference/assets/Damscray_-_Dancing_Tiger_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/ko/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 differ
            diff --git a/dist/ko/reference/assets/Damscray_01.mp3 b/dist/ko/reference/assets/Damscray_01.mp3
            new file mode 100644
            index 0000000000..9653a67bb6
            Binary files /dev/null and b/dist/ko/reference/assets/Damscray_01.mp3 differ
            diff --git a/dist/ko/reference/assets/Damscray_01.ogg b/dist/ko/reference/assets/Damscray_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/ko/reference/assets/Damscray_01.ogg differ
            diff --git a/dist/ko/reference/assets/Damscray_02.mp3 b/dist/ko/reference/assets/Damscray_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/ko/reference/assets/Damscray_02.mp3 differ
            diff --git a/dist/ko/reference/assets/Damscray_02.ogg b/dist/ko/reference/assets/Damscray_02.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/ko/reference/assets/Damscray_02.ogg differ
            diff --git a/dist/ko/reference/assets/Damscray_DancingTiger.mp3 b/dist/ko/reference/assets/Damscray_DancingTiger.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/ko/reference/assets/Damscray_DancingTiger.mp3 differ
            diff --git a/dist/ko/reference/assets/Italic.ttf b/dist/ko/reference/assets/Italic.ttf
            new file mode 100644
            index 0000000000..e5a1a86e63
            Binary files /dev/null and b/dist/ko/reference/assets/Italic.ttf differ
            diff --git a/dist/ko/reference/assets/Regular.otf b/dist/ko/reference/assets/Regular.otf
            new file mode 100644
            index 0000000000..38941ae72f
            Binary files /dev/null and b/dist/ko/reference/assets/Regular.otf differ
            diff --git a/dist/ko/reference/assets/arnott-wallace-eye-loop-forever.gif b/dist/ko/reference/assets/arnott-wallace-eye-loop-forever.gif
            new file mode 100644
            index 0000000000..992757bbaf
            Binary files /dev/null and b/dist/ko/reference/assets/arnott-wallace-eye-loop-forever.gif differ
            diff --git a/dist/ko/reference/assets/arnott-wallace-wink-loop-once.gif b/dist/ko/reference/assets/arnott-wallace-wink-loop-once.gif
            new file mode 100644
            index 0000000000..94f2015ff3
            Binary files /dev/null and b/dist/ko/reference/assets/arnott-wallace-wink-loop-once.gif differ
            diff --git a/dist/ko/reference/assets/beat.mp3 b/dist/ko/reference/assets/beat.mp3
            new file mode 100644
            index 0000000000..3e5802604c
            Binary files /dev/null and b/dist/ko/reference/assets/beat.mp3 differ
            diff --git a/dist/ko/reference/assets/beat.ogg b/dist/ko/reference/assets/beat.ogg
            new file mode 100644
            index 0000000000..c13f86a41f
            Binary files /dev/null and b/dist/ko/reference/assets/beat.ogg differ
            diff --git a/dist/ko/reference/assets/beatbox.mp3 b/dist/ko/reference/assets/beatbox.mp3
            new file mode 100644
            index 0000000000..23fb92eb71
            Binary files /dev/null and b/dist/ko/reference/assets/beatbox.mp3 differ
            diff --git a/dist/ko/reference/assets/beatbox.ogg b/dist/ko/reference/assets/beatbox.ogg
            new file mode 100644
            index 0000000000..b2593a6340
            Binary files /dev/null and b/dist/ko/reference/assets/beatbox.ogg differ
            diff --git a/dist/ko/reference/assets/blobs.csv b/dist/ko/reference/assets/blobs.csv
            new file mode 100644
            index 0000000000..2b7f05d1a0
            --- /dev/null
            +++ b/dist/ko/reference/assets/blobs.csv
            @@ -0,0 +1,3 @@
            +ID,Name,Flavor,Shape,Color
            +Blob1,Blobby,Sweet,Blob,Pink
            +Blob2,Saddy,Savory,Blob,Blue
            \ No newline at end of file
            diff --git a/dist/ko/reference/assets/bricks.jpg b/dist/ko/reference/assets/bricks.jpg
            new file mode 100644
            index 0000000000..231161d752
            Binary files /dev/null and b/dist/ko/reference/assets/bricks.jpg differ
            diff --git a/dist/ko/reference/assets/bricks_third.jpg b/dist/ko/reference/assets/bricks_third.jpg
            new file mode 100644
            index 0000000000..2fdb075996
            Binary files /dev/null and b/dist/ko/reference/assets/bricks_third.jpg differ
            diff --git a/dist/ko/reference/assets/bx-spring.mp3 b/dist/ko/reference/assets/bx-spring.mp3
            new file mode 100644
            index 0000000000..4a955ab7fa
            Binary files /dev/null and b/dist/ko/reference/assets/bx-spring.mp3 differ
            diff --git a/dist/ko/reference/assets/bx-spring.ogg b/dist/ko/reference/assets/bx-spring.ogg
            new file mode 100644
            index 0000000000..b01abee927
            Binary files /dev/null and b/dist/ko/reference/assets/bx-spring.ogg differ
            diff --git a/dist/ko/reference/assets/concrete-tunnel.mp3 b/dist/ko/reference/assets/concrete-tunnel.mp3
            new file mode 100644
            index 0000000000..1bfbd4f8f8
            Binary files /dev/null and b/dist/ko/reference/assets/concrete-tunnel.mp3 differ
            diff --git a/dist/ko/reference/assets/concrete-tunnel.ogg b/dist/ko/reference/assets/concrete-tunnel.ogg
            new file mode 100644
            index 0000000000..be5f66b72c
            Binary files /dev/null and b/dist/ko/reference/assets/concrete-tunnel.ogg differ
            diff --git a/dist/ko/reference/assets/doorbell.mp3 b/dist/ko/reference/assets/doorbell.mp3
            new file mode 100644
            index 0000000000..44b6367916
            Binary files /dev/null and b/dist/ko/reference/assets/doorbell.mp3 differ
            diff --git a/dist/ko/reference/assets/doorbell.ogg b/dist/ko/reference/assets/doorbell.ogg
            new file mode 100644
            index 0000000000..e816288c97
            Binary files /dev/null and b/dist/ko/reference/assets/doorbell.ogg differ
            diff --git a/dist/ko/reference/assets/drawImage.png b/dist/ko/reference/assets/drawImage.png
            new file mode 100644
            index 0000000000..1a7aa5d1d8
            Binary files /dev/null and b/dist/ko/reference/assets/drawImage.png differ
            diff --git a/dist/ko/reference/assets/drum.mp3 b/dist/ko/reference/assets/drum.mp3
            new file mode 100644
            index 0000000000..9cd8727617
            Binary files /dev/null and b/dist/ko/reference/assets/drum.mp3 differ
            diff --git a/dist/ko/reference/assets/drum.ogg b/dist/ko/reference/assets/drum.ogg
            new file mode 100644
            index 0000000000..5061a1b319
            Binary files /dev/null and b/dist/ko/reference/assets/drum.ogg differ
            diff --git a/dist/ko/reference/assets/favicon.ico b/dist/ko/reference/assets/favicon.ico
            new file mode 100644
            index 0000000000..33ad9806c8
            Binary files /dev/null and b/dist/ko/reference/assets/favicon.ico differ
            diff --git a/dist/ko/reference/assets/fingers.mov b/dist/ko/reference/assets/fingers.mov
            new file mode 100644
            index 0000000000..a9cbbbe3ea
            Binary files /dev/null and b/dist/ko/reference/assets/fingers.mov differ
            diff --git a/dist/ko/reference/assets/gradient.png b/dist/ko/reference/assets/gradient.png
            new file mode 100644
            index 0000000000..5245af69cd
            Binary files /dev/null and b/dist/ko/reference/assets/gradient.png differ
            diff --git a/dist/ko/reference/assets/inconsolata.otf b/dist/ko/reference/assets/inconsolata.otf
            new file mode 100644
            index 0000000000..e7e1fa0cd7
            Binary files /dev/null and b/dist/ko/reference/assets/inconsolata.otf differ
            diff --git a/dist/ko/reference/assets/index.html b/dist/ko/reference/assets/index.html
            new file mode 100644
            index 0000000000..487fe15b2a
            --- /dev/null
            +++ b/dist/ko/reference/assets/index.html
            @@ -0,0 +1,10 @@
            +<!doctype html>
            +<html>
            +    <head>
            +        <title>Redirector</title>
            +        <meta http-equiv="refresh" content="0;url=../">
            +    </head>
            +    <body>
            +        <a href="../">Click here to redirect</a>
            +    </body>
            +</html>
            diff --git a/dist/ko/reference/assets/laDefense.jpg b/dist/ko/reference/assets/laDefense.jpg
            new file mode 100644
            index 0000000000..3b8fdfe4b8
            Binary files /dev/null and b/dist/ko/reference/assets/laDefense.jpg differ
            diff --git a/dist/ko/reference/assets/large-dark-plate.mp3 b/dist/ko/reference/assets/large-dark-plate.mp3
            new file mode 100644
            index 0000000000..b9a15cbed7
            Binary files /dev/null and b/dist/ko/reference/assets/large-dark-plate.mp3 differ
            diff --git a/dist/ko/reference/assets/large-dark-plate.ogg b/dist/ko/reference/assets/large-dark-plate.ogg
            new file mode 100644
            index 0000000000..40115377e5
            Binary files /dev/null and b/dist/ko/reference/assets/large-dark-plate.ogg differ
            diff --git a/dist/ko/reference/assets/lucky_dragons.mp3 b/dist/ko/reference/assets/lucky_dragons.mp3
            new file mode 100644
            index 0000000000..c54c70c01a
            Binary files /dev/null and b/dist/ko/reference/assets/lucky_dragons.mp3 differ
            diff --git a/dist/ko/reference/assets/lucky_dragons.ogg b/dist/ko/reference/assets/lucky_dragons.ogg
            new file mode 100644
            index 0000000000..1e5b9e7abc
            Binary files /dev/null and b/dist/ko/reference/assets/lucky_dragons.ogg differ
            diff --git a/dist/ko/reference/assets/mammals.csv b/dist/ko/reference/assets/mammals.csv
            new file mode 100644
            index 0000000000..549984e37e
            --- /dev/null
            +++ b/dist/ko/reference/assets/mammals.csv
            @@ -0,0 +1,4 @@
            +id,species,name
            +0,Capra hircus,Goat
            +1,Panthera pardus,Leopard
            +2,Equus zebra,Zebra
            \ No newline at end of file
            diff --git a/dist/ko/reference/assets/mammals.xml b/dist/ko/reference/assets/mammals.xml
            new file mode 100644
            index 0000000000..752da754bf
            --- /dev/null
            +++ b/dist/ko/reference/assets/mammals.xml
            @@ -0,0 +1,6 @@
            +<?xml version="1.0"?>
            +<mammals>
            +  <animal id="0" species="Capra hircus">Goat</animal>
            +  <animal id="1" species="Panthera pardus">Leopard</animal>
            +  <animal id="2" species="Equus zebra">Zebra</animal>
            +</mammals>
            \ No newline at end of file
            diff --git a/dist/ko/reference/assets/mask.png b/dist/ko/reference/assets/mask.png
            new file mode 100644
            index 0000000000..a6737489b9
            Binary files /dev/null and b/dist/ko/reference/assets/mask.png differ
            diff --git a/dist/ko/reference/assets/mask2.png b/dist/ko/reference/assets/mask2.png
            new file mode 100644
            index 0000000000..2fb4aea99b
            Binary files /dev/null and b/dist/ko/reference/assets/mask2.png differ
            diff --git a/dist/ko/reference/assets/moonwalk.jpg b/dist/ko/reference/assets/moonwalk.jpg
            new file mode 100644
            index 0000000000..c418e6f573
            Binary files /dev/null and b/dist/ko/reference/assets/moonwalk.jpg differ
            diff --git a/dist/ko/reference/assets/nancy-liang-wind-loop-forever.gif b/dist/ko/reference/assets/nancy-liang-wind-loop-forever.gif
            new file mode 100644
            index 0000000000..a946253ede
            Binary files /dev/null and b/dist/ko/reference/assets/nancy-liang-wind-loop-forever.gif differ
            diff --git a/dist/ko/reference/assets/octahedron.obj b/dist/ko/reference/assets/octahedron.obj
            new file mode 100644
            index 0000000000..fed774d32a
            --- /dev/null
            +++ b/dist/ko/reference/assets/octahedron.obj
            @@ -0,0 +1,15 @@
            +v 0.000000E+00 0.000000E+00 40.0000
            +v 22.5000 22.5000 0.000000E+00
            +v 22.5000 -22.5000 0.000000E+00
            +v -22.5000 -22.5000 0.000000E+00
            +v -22.5000 22.5000 0.000000E+00
            +v 0.000000E+00 0.000000E+00 -40.0000
            +
            +f     1 2 3
            +f     1 3 4
            +f     1 4 5
            +f     1 5 2
            +f     6 5 4
            +f     6 4 3
            +f     6 3 2
            +f     6 2 5
            diff --git a/dist/ko/reference/assets/rockies.jpg b/dist/ko/reference/assets/rockies.jpg
            new file mode 100644
            index 0000000000..9bc0e4a372
            Binary files /dev/null and b/dist/ko/reference/assets/rockies.jpg differ
            diff --git a/dist/ko/reference/assets/rockies128.jpg b/dist/ko/reference/assets/rockies128.jpg
            new file mode 100644
            index 0000000000..bf55d812b2
            Binary files /dev/null and b/dist/ko/reference/assets/rockies128.jpg differ
            diff --git a/dist/ko/reference/assets/shader-gradient.frag b/dist/ko/reference/assets/shader-gradient.frag
            new file mode 100644
            index 0000000000..09a0cdc64b
            --- /dev/null
            +++ b/dist/ko/reference/assets/shader-gradient.frag
            @@ -0,0 +1,22 @@
            +// Code adopted from "Creating a Gradient Color in Fragment Shader"
            +// by Bahadır on stackoverflow.com
            +// https://stackoverflow.com/questions/47376499/creating-a-gradient-color-in-fragment-shader
            +
            +
            +precision highp float; varying vec2 vPos;
            +uniform vec2 offset;
            +uniform vec3 colorCenter;
            +uniform vec3 colorBackground;
            +
            +void main() {
            +
            +  vec2 st = vPos.xy + offset.xy;
            +
            +  // color1 = vec3(1.0,0.55,0);
            +  // color2 = vec3(0.226,0.000,0.615);
            +
            +  float mixValue = distance(st,vec2(0,1));
            +  vec3 color = mix(colorCenter,colorBackground,mixValue);
            +
            +  gl_FragColor = vec4(color,mixValue);
            +}
            \ No newline at end of file
            diff --git a/dist/ko/reference/assets/shader.frag b/dist/ko/reference/assets/shader.frag
            new file mode 100644
            index 0000000000..d3d76eb77a
            --- /dev/null
            +++ b/dist/ko/reference/assets/shader.frag
            @@ -0,0 +1,16 @@
            +precision highp float; varying vec2 vPos;
            +uniform vec2 p;
            +uniform float r;
            +const int I = 500;
            +void main() {
            +  vec2 c = p + vPos * r, z = c;
            +  float n = 0.0;
            +  for (int i = I; i > 0; i --) {
            +    if(z.x*z.x+z.y*z.y > 4.0) {
            +      n = float(i)/float(I);
            +      break;
            +    }
            +    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;
            +  }
            +  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);
            +}
            diff --git a/dist/ko/reference/assets/shader.vert b/dist/ko/reference/assets/shader.vert
            new file mode 100644
            index 0000000000..ea310c6770
            --- /dev/null
            +++ b/dist/ko/reference/assets/shader.vert
            @@ -0,0 +1,3 @@
            +precision highp float; varying vec2 vPos;
            +attribute vec3 aPosition;
            +void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }
            diff --git a/dist/ko/reference/assets/small-plate.mp3 b/dist/ko/reference/assets/small-plate.mp3
            new file mode 100644
            index 0000000000..656e154a5f
            Binary files /dev/null and b/dist/ko/reference/assets/small-plate.mp3 differ
            diff --git a/dist/ko/reference/assets/small-plate.ogg b/dist/ko/reference/assets/small-plate.ogg
            new file mode 100644
            index 0000000000..7b70d3349d
            Binary files /dev/null and b/dist/ko/reference/assets/small-plate.ogg differ
            diff --git a/dist/ko/reference/assets/small.mp4 b/dist/ko/reference/assets/small.mp4
            new file mode 100644
            index 0000000000..1fc478842f
            Binary files /dev/null and b/dist/ko/reference/assets/small.mp4 differ
            diff --git a/dist/ko/reference/assets/small.ogv b/dist/ko/reference/assets/small.ogv
            new file mode 100644
            index 0000000000..2b35a41aa4
            Binary files /dev/null and b/dist/ko/reference/assets/small.ogv differ
            diff --git a/dist/ko/reference/assets/small.webm b/dist/ko/reference/assets/small.webm
            new file mode 100644
            index 0000000000..da946da529
            Binary files /dev/null and b/dist/ko/reference/assets/small.webm differ
            diff --git a/dist/ko/reference/assets/studio-b.mp3 b/dist/ko/reference/assets/studio-b.mp3
            new file mode 100644
            index 0000000000..cbc792bfc9
            Binary files /dev/null and b/dist/ko/reference/assets/studio-b.mp3 differ
            diff --git a/dist/ko/reference/assets/studio-b.ogg b/dist/ko/reference/assets/studio-b.ogg
            new file mode 100644
            index 0000000000..cd68db07e6
            Binary files /dev/null and b/dist/ko/reference/assets/studio-b.ogg differ
            diff --git a/dist/ko/reference/assets/teapot.obj b/dist/ko/reference/assets/teapot.obj
            new file mode 100644
            index 0000000000..cedb196a4e
            --- /dev/null
            +++ b/dist/ko/reference/assets/teapot.obj
            @@ -0,0 +1,4663 @@
            +# Blender v2.61 (sub 0) OBJ File: ''
            +# www.blender.org
            +v 0.605903 0.005903 -0.000000
            +v 0.000000 0.000000 0.000000
            +v 0.584584 0.005902 -0.162696
            +v 0.524218 0.005902 -0.307888
            +v 0.430191 0.005901 -0.430191
            +v 0.307888 0.005901 -0.524218
            +v 0.162696 0.005901 -0.584584
            +v 0.000000 0.005901 -0.605903
            +v -0.162696 0.005901 -0.584584
            +v -0.307888 0.005901 -0.524218
            +v -0.430191 0.005901 -0.430191
            +v -0.524218 0.005902 -0.307888
            +v -0.584584 0.005902 -0.162696
            +v -0.605903 0.005903 -0.000000
            +v -0.584584 0.005904 0.162696
            +v -0.524218 0.005904 0.307888
            +v -0.430191 0.005905 0.430191
            +v -0.307888 0.005905 0.524218
            +v -0.162696 0.005905 0.584584
            +v 0.000000 0.005905 0.605903
            +v 0.162696 0.005905 0.584584
            +v 0.307888 0.005905 0.524218
            +v 0.430191 0.005905 0.430191
            +v 0.524218 0.005904 0.307888
            +v 0.584584 0.005904 0.162696
            +v 1.400000 2.400000 -0.000008
            +v 1.350740 2.400000 0.375917
            +v 1.332760 2.454690 0.370913
            +v 1.381370 2.454690 -0.000009
            +v 1.384260 2.487500 -0.000009
            +v 1.335550 2.487500 0.371690
            +v 1.403120 2.498440 -0.000009
            +v 1.353760 2.498440 0.376756
            +v 1.382010 2.487500 0.384619
            +v 1.432410 2.487500 -0.000009
            +v 1.414950 2.454690 0.393787
            +v 1.466550 2.454690 -0.000009
            +v 1.447220 2.400000 0.402769
            +v 1.500000 2.400000 -0.000008
            +v 1.211260 2.400000 0.711398
            +v 1.195140 2.454690 0.701929
            +v 1.197640 2.487500 0.703400
            +v 1.213960 2.498440 0.712986
            +v 1.239300 2.487500 0.727866
            +v 1.268840 2.454690 0.745216
            +v 1.297780 2.400000 0.762213
            +v 0.994000 2.400000 0.993991
            +v 0.980770 2.454690 0.980761
            +v 0.982824 2.487500 0.982815
            +v 0.996219 2.498440 0.996210
            +v 1.017010 2.487500 1.017000
            +v 1.041250 2.454690 1.041240
            +v 1.065000 2.400000 1.064990
            +v 0.711407 2.400000 1.211250
            +v 0.701938 2.454690 1.195130
            +v 0.703409 2.487500 1.197630
            +v 0.712995 2.498440 1.213950
            +v 0.727875 2.487500 1.239290
            +v 0.745225 2.454690 1.268830
            +v 0.762222 2.400000 1.297770
            +v 0.375926 2.400010 1.350730
            +v 0.370922 2.454690 1.332750
            +v 0.371699 2.487500 1.335540
            +v 0.376765 2.498450 1.353750
            +v 0.384628 2.487500 1.382000
            +v 0.393796 2.454700 1.414940
            +v 0.402778 2.400010 1.447210
            +v 0.000000 2.400010 1.399990
            +v 0.000000 2.454690 1.381360
            +v 0.000000 2.487500 1.384250
            +v 0.000000 2.498450 1.403110
            +v 0.000000 2.487510 1.432400
            +v 0.000000 2.454700 1.466540
            +v 0.000000 2.400010 1.499990
            +v -0.375926 2.400010 1.350730
            +v -0.370922 2.454690 1.332750
            +v -0.371699 2.487500 1.335540
            +v -0.376765 2.498450 1.353750
            +v -0.384628 2.487500 1.382000
            +v -0.393796 2.454700 1.414940
            +v -0.402778 2.400010 1.447210
            +v -0.711407 2.400000 1.211250
            +v -0.701938 2.454690 1.195130
            +v -0.703409 2.487500 1.197630
            +v -0.712995 2.498440 1.213950
            +v -0.727875 2.487500 1.239290
            +v -0.745225 2.454690 1.268830
            +v -0.762222 2.400000 1.297770
            +v -0.994000 2.400000 0.993991
            +v -0.980770 2.454690 0.980761
            +v -0.982824 2.487500 0.982815
            +v -0.996219 2.498440 0.996210
            +v -1.017010 2.487500 1.017000
            +v -1.041250 2.454690 1.041240
            +v -1.065000 2.400000 1.064990
            +v -1.211260 2.400000 0.711398
            +v -1.195140 2.454690 0.701929
            +v -1.197640 2.487500 0.703400
            +v -1.213960 2.498440 0.712986
            +v -1.239300 2.487500 0.727866
            +v -1.268840 2.454690 0.745216
            +v -1.297780 2.400000 0.762213
            +v -1.350740 2.400000 0.375917
            +v -1.332760 2.454690 0.370913
            +v -1.335550 2.487500 0.371690
            +v -1.353760 2.498440 0.376756
            +v -1.382010 2.487500 0.384619
            +v -1.414950 2.454690 0.393787
            +v -1.447220 2.400000 0.402769
            +v -1.400000 2.400000 -0.000008
            +v -1.381370 2.454690 -0.000009
            +v -1.384260 2.487500 -0.000009
            +v -1.403120 2.498440 -0.000009
            +v -1.432410 2.487500 -0.000009
            +v -1.466550 2.454690 -0.000009
            +v -1.500000 2.400000 -0.000008
            +v -1.350740 2.400000 -0.375935
            +v -1.332760 2.454690 -0.370931
            +v -1.335550 2.487500 -0.371708
            +v -1.353760 2.498440 -0.376774
            +v -1.382010 2.487500 -0.384637
            +v -1.414950 2.454690 -0.393805
            +v -1.447220 2.400000 -0.402787
            +v -1.211260 2.400000 -0.711416
            +v -1.195140 2.454690 -0.701947
            +v -1.197640 2.487500 -0.703418
            +v -1.213960 2.498440 -0.713004
            +v -1.239300 2.487500 -0.727884
            +v -1.268840 2.454690 -0.745234
            +v -1.297780 2.400000 -0.762231
            +v -0.994000 2.400000 -0.994009
            +v -0.980770 2.454690 -0.980779
            +v -0.982824 2.487500 -0.982833
            +v -0.996219 2.498440 -0.996228
            +v -1.017010 2.487500 -1.017020
            +v -1.041250 2.454690 -1.041260
            +v -1.065000 2.400000 -1.065010
            +v -0.711407 2.400000 -1.211270
            +v -0.701938 2.454690 -1.195150
            +v -0.703409 2.487500 -1.197650
            +v -0.712995 2.498440 -1.213970
            +v -0.727875 2.487500 -1.239310
            +v -0.745225 2.454690 -1.268850
            +v -0.762222 2.400000 -1.297790
            +v -0.375926 2.400000 -1.350750
            +v -0.370922 2.454680 -1.332770
            +v -0.371699 2.487490 -1.335560
            +v -0.376765 2.498440 -1.353770
            +v -0.384628 2.487490 -1.382020
            +v -0.393796 2.454680 -1.414960
            +v -0.402778 2.399990 -1.447230
            +v 0.000000 2.399990 -1.400010
            +v 0.000000 2.454680 -1.381380
            +v 0.000000 2.487490 -1.384270
            +v 0.000000 2.498430 -1.403130
            +v 0.000000 2.487490 -1.432420
            +v 0.000000 2.454680 -1.466560
            +v 0.000000 2.399990 -1.500010
            +v 0.375926 2.400000 -1.350750
            +v 0.370922 2.454680 -1.332770
            +v 0.371699 2.487490 -1.335560
            +v 0.376765 2.498440 -1.353770
            +v 0.384628 2.487490 -1.382020
            +v 0.393796 2.454680 -1.414960
            +v 0.402778 2.399990 -1.447230
            +v 0.711407 2.400000 -1.211270
            +v 0.701938 2.454690 -1.195150
            +v 0.703409 2.487500 -1.197650
            +v 0.712995 2.498440 -1.213970
            +v 0.727875 2.487500 -1.239310
            +v 0.745225 2.454690 -1.268850
            +v 0.762222 2.400000 -1.297790
            +v 0.994000 2.400000 -0.994009
            +v 0.980770 2.454690 -0.980779
            +v 0.982824 2.487500 -0.982833
            +v 0.996219 2.498440 -0.996228
            +v 1.017010 2.487500 -1.017020
            +v 1.041250 2.454690 -1.041260
            +v 1.065000 2.400000 -1.065010
            +v 1.211260 2.400000 -0.711416
            +v 1.195140 2.454690 -0.701947
            +v 1.197640 2.487500 -0.703418
            +v 1.213960 2.498440 -0.713004
            +v 1.239300 2.487500 -0.727884
            +v 1.268840 2.454690 -0.745234
            +v 1.297780 2.400000 -0.762231
            +v 1.350740 2.400000 -0.375935
            +v 1.332760 2.454690 -0.370931
            +v 1.335550 2.487500 -0.371708
            +v 1.353760 2.498440 -0.376774
            +v 1.382010 2.487500 -0.384637
            +v 1.414950 2.454690 -0.393805
            +v 1.447220 2.400000 -0.402787
            +v 1.566710 2.137850 0.436024
            +v 1.623840 2.137850 -0.000008
            +v 1.679490 1.877780 0.467414
            +v 1.740740 1.877780 -0.000007
            +v 1.778880 1.621880 0.495075
            +v 1.843750 1.621870 -0.000006
            +v 1.858160 1.372220 0.517142
            +v 1.925930 1.372220 -0.000005
            +v 1.910650 1.130900 0.531750
            +v 1.980320 1.130900 -0.000004
            +v 1.929630 0.900002 0.537034
            +v 2.000000 0.900000 -0.000003
            +v 1.404920 2.137850 0.825145
            +v 1.506060 1.877780 0.884547
            +v 1.595190 1.621880 0.936892
            +v 1.666280 1.372220 0.978651
            +v 1.713350 1.130900 1.006300
            +v 1.730370 0.900004 1.016300
            +v 1.152930 2.137850 1.152920
            +v 1.235930 1.877780 1.235920
            +v 1.309060 1.621870 1.309050
            +v 1.367410 1.372230 1.367400
            +v 1.406030 1.130910 1.406030
            +v 1.420000 0.900005 1.420000
            +v 0.825153 2.137860 1.404910
            +v 0.884554 1.877790 1.506050
            +v 0.936898 1.621890 1.595180
            +v 0.978656 1.372230 1.666270
            +v 1.006300 1.130910 1.713350
            +v 1.016300 0.900006 1.730370
            +v 0.436032 2.137860 1.566700
            +v 0.467421 1.877790 1.679480
            +v 0.495081 1.621880 1.778870
            +v 0.517147 1.372230 1.858150
            +v 0.531754 1.130910 1.910650
            +v 0.537037 0.900007 1.929630
            +v 0.000000 2.137860 1.623830
            +v 0.000000 1.877790 1.740730
            +v 0.000000 1.621880 1.843740
            +v 0.000000 1.372230 1.925920
            +v 0.000000 1.130910 1.980320
            +v 0.000000 0.900007 2.000000
            +v -0.436032 2.137860 1.566700
            +v -0.467421 1.877790 1.679480
            +v -0.495081 1.621890 1.778870
            +v -0.517147 1.372230 1.858150
            +v -0.531754 1.130910 1.910650
            +v -0.537037 0.900007 1.929630
            +v -0.825153 2.137860 1.404910
            +v -0.884554 1.877790 1.506050
            +v -0.936898 1.621890 1.595180
            +v -0.978656 1.372230 1.666270
            +v -1.006300 1.130910 1.713350
            +v -1.016300 0.900006 1.730370
            +v -1.152930 2.137850 1.152920
            +v -1.235930 1.877780 1.235920
            +v -1.309060 1.621870 1.309050
            +v -1.367410 1.372230 1.367400
            +v -1.406030 1.130910 1.406030
            +v -1.420000 0.900005 1.420000
            +v -1.404920 2.137850 0.825145
            +v -1.506060 1.877780 0.884547
            +v -1.595190 1.621880 0.936892
            +v -1.666280 1.372220 0.978651
            +v -1.713350 1.130900 1.006300
            +v -1.730370 0.900004 1.016300
            +v -1.566710 2.137850 0.436024
            +v -1.679490 1.877780 0.467414
            +v -1.778880 1.621870 0.495075
            +v -1.858160 1.372220 0.517142
            +v -1.910650 1.130900 0.531750
            +v -1.929630 0.900002 0.537034
            +v -1.623840 2.137850 -0.000008
            +v -1.740740 1.877780 -0.000007
            +v -1.843750 1.621870 -0.000006
            +v -1.925930 1.372220 -0.000005
            +v -1.980320 1.130900 -0.000004
            +v -2.000000 0.900000 -0.000003
            +v -1.566710 2.137850 -0.436040
            +v -1.679490 1.877780 -0.467428
            +v -1.778880 1.621880 -0.495087
            +v -1.858160 1.372220 -0.517152
            +v -1.910650 1.130900 -0.531758
            +v -1.929630 0.899998 -0.537040
            +v -1.404920 2.137850 -0.825161
            +v -1.506060 1.877780 -0.884561
            +v -1.595190 1.621880 -0.936904
            +v -1.666280 1.372220 -0.978661
            +v -1.713350 1.130900 -1.006300
            +v -1.730370 0.899996 -1.016300
            +v -1.152930 2.137850 -1.152940
            +v -1.235930 1.877780 -1.235940
            +v -1.309060 1.621870 -1.309070
            +v -1.367410 1.372220 -1.367420
            +v -1.406030 1.130890 -1.406030
            +v -1.420000 0.899995 -1.420000
            +v -0.825153 2.137840 -1.404930
            +v -0.884554 1.877770 -1.506070
            +v -0.936898 1.621870 -1.595200
            +v -0.978656 1.372210 -1.666290
            +v -1.006300 1.130890 -1.713350
            +v -1.016300 0.899994 -1.730370
            +v -0.436032 2.137840 -1.566720
            +v -0.467421 1.877770 -1.679500
            +v -0.495081 1.621860 -1.778890
            +v -0.517147 1.372210 -1.858170
            +v -0.531754 1.130890 -1.910650
            +v -0.537037 0.899993 -1.929630
            +v 0.000000 2.137840 -1.623850
            +v 0.000000 1.877770 -1.740750
            +v 0.000000 1.621860 -1.843760
            +v 0.000000 1.372210 -1.925940
            +v 0.000000 1.130890 -1.980320
            +v 0.000000 0.899993 -2.000000
            +v 0.436032 2.137840 -1.566720
            +v 0.467421 1.877770 -1.679500
            +v 0.495081 1.621870 -1.778890
            +v 0.517147 1.372210 -1.858170
            +v 0.531754 1.130890 -1.910650
            +v 0.537037 0.899993 -1.929630
            +v 0.825153 2.137840 -1.404930
            +v 0.884554 1.877770 -1.506070
            +v 0.936898 1.621870 -1.595200
            +v 0.978656 1.372210 -1.666290
            +v 1.006300 1.130890 -1.713350
            +v 1.016300 0.899994 -1.730370
            +v 1.152930 2.137850 -1.152940
            +v 1.235930 1.877780 -1.235940
            +v 1.309060 1.621870 -1.309070
            +v 1.367410 1.372220 -1.367420
            +v 1.406030 1.130890 -1.406030
            +v 1.420000 0.899995 -1.420000
            +v 1.404920 2.137850 -0.825161
            +v 1.506060 1.877780 -0.884561
            +v 1.595190 1.621880 -0.936904
            +v 1.666280 1.372220 -0.978661
            +v 1.713350 1.130900 -1.006300
            +v 1.730370 0.899996 -1.016300
            +v 1.566710 2.137850 -0.436040
            +v 1.679490 1.877780 -0.467428
            +v 1.778880 1.621870 -0.495087
            +v 1.858160 1.372220 -0.517152
            +v 1.910650 1.130900 -0.531758
            +v 1.929630 0.899998 -0.537040
            +v 1.893900 0.693405 0.527089
            +v 1.962960 0.693403 -0.000002
            +v 1.804560 0.522224 0.502227
            +v 1.870370 0.522222 -0.000002
            +v 1.688430 0.384377 0.469906
            +v 1.750000 0.384375 -0.000001
            +v 1.572290 0.277780 0.437585
            +v 1.629630 0.277778 -0.000001
            +v 1.482960 0.200349 0.412722
            +v 1.537040 0.200347 -0.000001
            +v 1.447220 0.150001 0.402777
            +v 1.500000 0.150000 -0.000001
            +v 1.698330 0.693407 0.997473
            +v 1.618220 0.522225 0.950423
            +v 1.514070 0.384378 0.889258
            +v 1.409930 0.277781 0.828092
            +v 1.329820 0.200350 0.781042
            +v 1.297780 0.150003 0.762221
            +v 1.393700 0.693408 1.393700
            +v 1.327960 0.522227 1.327960
            +v 1.242500 0.384380 1.242500
            +v 1.157040 0.277782 1.157040
            +v 1.091300 0.200351 1.091300
            +v 1.065000 0.150004 1.065000
            +v 0.997476 0.693409 1.698330
            +v 0.950425 0.522228 1.618220
            +v 0.889259 0.384381 1.514070
            +v 0.828093 0.277783 1.409930
            +v 0.781043 0.200352 1.329820
            +v 0.762222 0.150005 1.297780
            +v 0.527092 0.693410 1.893900
            +v 0.502229 0.522229 1.804560
            +v 0.469907 0.384381 1.688430
            +v 0.437586 0.277784 1.572290
            +v 0.412723 0.200352 1.482960
            +v 0.402778 0.150005 1.447220
            +v 0.000000 0.693410 1.962960
            +v 0.000000 0.522229 1.870370
            +v 0.000000 0.384381 1.750000
            +v 0.000000 0.277784 1.629630
            +v 0.000000 0.200353 1.537040
            +v 0.000000 0.150006 1.500000
            +v -0.527092 0.693410 1.893900
            +v -0.502229 0.522229 1.804560
            +v -0.469907 0.384381 1.688430
            +v -0.437586 0.277784 1.572290
            +v -0.412723 0.200352 1.482960
            +v -0.402778 0.150005 1.447220
            +v -0.997476 0.693409 1.698330
            +v -0.950425 0.522228 1.618220
            +v -0.889259 0.384381 1.514070
            +v -0.828093 0.277783 1.409930
            +v -0.781043 0.200352 1.329820
            +v -0.762222 0.150005 1.297780
            +v -1.393700 0.693408 1.393700
            +v -1.327960 0.522227 1.327960
            +v -1.242500 0.384380 1.242500
            +v -1.157040 0.277782 1.157040
            +v -1.091300 0.200351 1.091300
            +v -1.065000 0.150004 1.065000
            +v -1.698330 0.693407 0.997473
            +v -1.618220 0.522225 0.950423
            +v -1.514070 0.384378 0.889258
            +v -1.409930 0.277781 0.828092
            +v -1.329820 0.200350 0.781042
            +v -1.297780 0.150003 0.762221
            +v -1.893900 0.693405 0.527089
            +v -1.804560 0.522224 0.502227
            +v -1.688430 0.384377 0.469906
            +v -1.572290 0.277780 0.437585
            +v -1.482960 0.200349 0.412722
            +v -1.447220 0.150001 0.402777
            +v -1.962960 0.693403 -0.000002
            +v -1.870370 0.522222 -0.000002
            +v -1.750000 0.384375 -0.000001
            +v -1.629630 0.277778 -0.000001
            +v -1.537040 0.200347 -0.000001
            +v -1.500000 0.150000 -0.000001
            +v -1.893900 0.693401 -0.527095
            +v -1.804560 0.522220 -0.502231
            +v -1.688430 0.384373 -0.469908
            +v -1.572290 0.277776 -0.437587
            +v -1.482960 0.200345 -0.412724
            +v -1.447220 0.149999 -0.402779
            +v -1.698330 0.693399 -0.997479
            +v -1.618220 0.522218 -0.950427
            +v -1.514070 0.384372 -0.889260
            +v -1.409930 0.277775 -0.828094
            +v -1.329820 0.200344 -0.781044
            +v -1.297780 0.149997 -0.762223
            +v -1.393700 0.693398 -1.393700
            +v -1.327960 0.522217 -1.327960
            +v -1.242500 0.384370 -1.242500
            +v -1.157040 0.277774 -1.157040
            +v -1.091300 0.200343 -1.091300
            +v -1.065000 0.149996 -1.065000
            +v -0.997476 0.693397 -1.698330
            +v -0.950425 0.522216 -1.618220
            +v -0.889259 0.384369 -1.514070
            +v -0.828093 0.277773 -1.409930
            +v -0.781043 0.200342 -1.329820
            +v -0.762222 0.149995 -1.297780
            +v -0.527092 0.693396 -1.893900
            +v -0.502229 0.522215 -1.804560
            +v -0.469907 0.384369 -1.688430
            +v -0.437586 0.277772 -1.572290
            +v -0.412723 0.200342 -1.482960
            +v -0.402778 0.149995 -1.447220
            +v 0.000000 0.693396 -1.962960
            +v 0.000000 0.522215 -1.870370
            +v 0.000000 0.384369 -1.750000
            +v 0.000000 0.277772 -1.629630
            +v 0.000000 0.200341 -1.537040
            +v 0.000000 0.149994 -1.500000
            +v 0.527092 0.693396 -1.893900
            +v 0.502229 0.522215 -1.804560
            +v 0.469907 0.384369 -1.688430
            +v 0.437586 0.277772 -1.572290
            +v 0.412723 0.200342 -1.482960
            +v 0.402778 0.149995 -1.447220
            +v 0.997476 0.693397 -1.698330
            +v 0.950425 0.522216 -1.618220
            +v 0.889259 0.384369 -1.514070
            +v 0.828093 0.277773 -1.409930
            +v 0.781043 0.200342 -1.329820
            +v 0.762222 0.149995 -1.297780
            +v 1.393700 0.693398 -1.393700
            +v 1.327960 0.522217 -1.327960
            +v 1.242500 0.384370 -1.242500
            +v 1.157040 0.277774 -1.157040
            +v 1.091300 0.200343 -1.091300
            +v 1.065000 0.149996 -1.065000
            +v 1.698330 0.693399 -0.997479
            +v 1.618220 0.522218 -0.950427
            +v 1.514070 0.384372 -0.889260
            +v 1.409930 0.277775 -0.828094
            +v 1.329820 0.200344 -0.781044
            +v 1.297780 0.149997 -0.762223
            +v 1.893900 0.693401 -0.527095
            +v 1.804560 0.522220 -0.502231
            +v 1.688430 0.384373 -0.469908
            +v 1.572290 0.277776 -0.437587
            +v 1.482960 0.200345 -0.412724
            +v 1.447220 0.149999 -0.402779
            +v 1.022220 0.022222 -0.000000
            +v 0.986255 0.022221 -0.274486
            +v 1.284370 0.046875 -0.000000
            +v 1.239180 0.046874 -0.344878
            +v 1.427780 0.077778 -0.000000
            +v 1.377540 0.077777 -0.383385
            +v 1.487850 0.112847 -0.000000
            +v 1.435500 0.112846 -0.399515
            +v 0.884412 0.022220 -0.519440
            +v 1.111220 0.046873 -0.652653
            +v 1.235290 0.077775 -0.725523
            +v 1.287260 0.112844 -0.756047
            +v 0.725778 0.022219 -0.725778
            +v 0.911906 0.046872 -0.911906
            +v 1.013720 0.077774 -1.013720
            +v 1.056370 0.112843 -1.056370
            +v 0.519440 0.022219 -0.884412
            +v 0.652653 0.046871 -1.111220
            +v 0.725523 0.077774 -1.235290
            +v 0.756047 0.112842 -1.287260
            +v 0.274486 0.022219 -0.986255
            +v 0.344878 0.046871 -1.239180
            +v 0.383385 0.077773 -1.377540
            +v 0.399515 0.112842 -1.435500
            +v 0.000000 0.022218 -1.022220
            +v 0.000000 0.046871 -1.284370
            +v 0.000000 0.077773 -1.427780
            +v 0.000000 0.112842 -1.487850
            +v -0.274486 0.022219 -0.986255
            +v -0.344878 0.046871 -1.239180
            +v -0.383385 0.077773 -1.377540
            +v -0.399515 0.112842 -1.435500
            +v -0.519440 0.022219 -0.884412
            +v -0.652653 0.046871 -1.111220
            +v -0.725523 0.077774 -1.235290
            +v -0.756047 0.112842 -1.287260
            +v -0.725778 0.022219 -0.725778
            +v -0.911906 0.046872 -0.911906
            +v -1.013720 0.077774 -1.013720
            +v -1.056370 0.112843 -1.056370
            +v -0.884412 0.022220 -0.519440
            +v -1.111220 0.046873 -0.652653
            +v -1.235290 0.077775 -0.725523
            +v -1.287260 0.112844 -0.756047
            +v -0.986255 0.022221 -0.274486
            +v -1.239180 0.046874 -0.344878
            +v -1.377540 0.077777 -0.383385
            +v -1.435500 0.112846 -0.399515
            +v -1.022220 0.022222 -0.000000
            +v -1.284370 0.046875 -0.000000
            +v -1.427780 0.077778 -0.000000
            +v -1.487850 0.112847 -0.000000
            +v -0.986255 0.022223 0.274486
            +v -1.239180 0.046876 0.344878
            +v -1.377540 0.077779 0.383385
            +v -1.435500 0.112848 0.399515
            +v -0.884412 0.022224 0.519440
            +v -1.111220 0.046877 0.652653
            +v -1.235290 0.077781 0.725523
            +v -1.287260 0.112850 0.756047
            +v -0.725778 0.022225 0.725778
            +v -0.911906 0.046878 0.911906
            +v -1.013720 0.077782 1.013720
            +v -1.056370 0.112851 1.056370
            +v -0.519440 0.022225 0.884412
            +v -0.652653 0.046879 1.111220
            +v -0.725523 0.077782 1.235290
            +v -0.756047 0.112852 1.287260
            +v -0.274486 0.022225 0.986255
            +v -0.344878 0.046879 1.239180
            +v -0.383385 0.077783 1.377540
            +v -0.399515 0.112852 1.435500
            +v 0.000000 0.022226 1.022220
            +v 0.000000 0.046879 1.284370
            +v 0.000000 0.077783 1.427780
            +v 0.000000 0.112852 1.487850
            +v 0.274486 0.022225 0.986255
            +v 0.344878 0.046879 1.239180
            +v 0.383385 0.077783 1.377540
            +v 0.399515 0.112852 1.435500
            +v 0.519440 0.022225 0.884412
            +v 0.652653 0.046879 1.111220
            +v 0.725523 0.077782 1.235290
            +v 0.756047 0.112852 1.287260
            +v 0.725778 0.022225 0.725778
            +v 0.911906 0.046878 0.911906
            +v 1.013720 0.077782 1.013720
            +v 1.056370 0.112851 1.056370
            +v 0.884412 0.022224 0.519440
            +v 1.111220 0.046877 0.652653
            +v 1.235290 0.077781 0.725523
            +v 1.287260 0.112850 0.756047
            +v 0.986255 0.022223 0.274486
            +v 1.239180 0.046876 0.344878
            +v 1.377540 0.077779 0.383385
            +v 1.435500 0.112848 0.399515
            +v 0.192963 2.700000 0.053694
            +v 0.200000 2.700000 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.173037 2.700000 0.101620
            +v 0.148234 2.785420 0.087096
            +v 0.142000 2.700000 0.141990
            +v 0.121672 2.785420 0.121662
            +v 0.101630 2.700000 0.173027
            +v 0.087106 2.785420 0.148224
            +v 0.053704 2.700000 0.192953
            +v 0.046045 2.785420 0.165269
            +v 0.000000 2.700000 0.199990
            +v 0.000000 2.785420 0.171286
            +v -0.053704 2.700000 0.192953
            +v -0.046045 2.785420 0.165269
            +v -0.101630 2.700000 0.173027
            +v -0.087106 2.785420 0.148224
            +v -0.142000 2.700000 0.141990
            +v -0.121672 2.785420 0.121662
            +v -0.173037 2.700000 0.101620
            +v -0.148234 2.785420 0.087096
            +v -0.192963 2.700000 0.053694
            +v -0.165279 2.785420 0.046035
            +v -0.200000 2.700000 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.192963 2.700000 -0.053714
            +v -0.165279 2.785420 -0.046055
            +v -0.173037 2.700000 -0.101640
            +v -0.148234 2.785420 -0.087116
            +v -0.142000 2.700000 -0.142010
            +v -0.121672 2.785420 -0.121682
            +v -0.101630 2.700000 -0.173047
            +v -0.087106 2.785420 -0.148244
            +v -0.053704 2.700000 -0.192973
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 2.700000 -0.200010
            +v 0.000000 2.785420 -0.171306
            +v 0.053704 2.700000 -0.192973
            +v 0.046045 2.785420 -0.165289
            +v 0.101630 2.700000 -0.173047
            +v 0.087106 2.785420 -0.148244
            +v 0.142000 2.700000 -0.142010
            +v 0.121672 2.785420 -0.121682
            +v 0.173037 2.700000 -0.101640
            +v 0.148234 2.785420 -0.087116
            +v 0.192963 2.700000 -0.053714
            +v 0.165279 2.785420 -0.046055
            +v 0.338579 2.636110 0.094221
            +v 0.350926 2.636110 -0.000009
            +v 0.553875 2.588890 0.154140
            +v 0.574074 2.588890 -0.000009
            +v 0.795972 2.550000 0.221519
            +v 0.825000 2.550000 -0.000009
            +v 1.021990 2.511110 0.284422
            +v 1.059260 2.511110 -0.000009
            +v 1.189040 2.463890 0.330915
            +v 1.232410 2.463890 -0.000009
            +v 1.254260 2.400000 0.349065
            +v 1.300000 2.400000 -0.000008
            +v 0.303616 2.636110 0.178312
            +v 0.496680 2.588890 0.291705
            +v 0.713778 2.550000 0.419213
            +v 0.916455 2.511110 0.538252
            +v 1.066260 2.463890 0.626237
            +v 1.124740 2.400000 0.660584
            +v 0.249157 2.636110 0.249147
            +v 0.407593 2.588890 0.407583
            +v 0.585750 2.550000 0.585741
            +v 0.752074 2.511110 0.752065
            +v 0.875009 2.463890 0.875000
            +v 0.923000 2.400000 0.922991
            +v 0.178322 2.636110 0.303606
            +v 0.291715 2.588890 0.496670
            +v 0.419222 2.550000 0.713769
            +v 0.538261 2.511110 0.916446
            +v 0.626246 2.463890 1.066250
            +v 0.660593 2.400000 1.124730
            +v 0.094230 2.636110 0.338569
            +v 0.154150 2.588890 0.553865
            +v 0.221528 2.550000 0.795963
            +v 0.284431 2.511110 1.021980
            +v 0.330924 2.463890 1.189030
            +v 0.349074 2.400000 1.254250
            +v 0.000000 2.636110 0.350916
            +v 0.000000 2.588890 0.574064
            +v 0.000000 2.550000 0.824991
            +v 0.000000 2.511110 1.059250
            +v 0.000000 2.463890 1.232400
            +v 0.000000 2.400000 1.299990
            +v -0.094230 2.636110 0.338569
            +v -0.154150 2.588890 0.553865
            +v -0.221528 2.550000 0.795963
            +v -0.284431 2.511110 1.021980
            +v -0.330924 2.463890 1.189030
            +v -0.349074 2.400000 1.254250
            +v -0.178322 2.636110 0.303606
            +v -0.291715 2.588890 0.496670
            +v -0.419222 2.550000 0.713769
            +v -0.538261 2.511110 0.916446
            +v -0.626246 2.463890 1.066250
            +v -0.660593 2.400000 1.124730
            +v -0.249157 2.636110 0.249147
            +v -0.407593 2.588890 0.407583
            +v -0.585750 2.550000 0.585741
            +v -0.752074 2.511110 0.752065
            +v -0.875009 2.463890 0.875000
            +v -0.923000 2.400000 0.922991
            +v -0.303616 2.636110 0.178312
            +v -0.496680 2.588890 0.291705
            +v -0.713778 2.550000 0.419213
            +v -0.916455 2.511110 0.538252
            +v -1.066260 2.463890 0.626237
            +v -1.124740 2.400000 0.660584
            +v -0.338579 2.636110 0.094221
            +v -0.553875 2.588890 0.154140
            +v -0.795972 2.550000 0.221519
            +v -1.021990 2.511110 0.284422
            +v -1.189040 2.463890 0.330915
            +v -1.254260 2.400000 0.349065
            +v -0.350926 2.636110 -0.000009
            +v -0.574074 2.588890 -0.000009
            +v -0.825000 2.550000 -0.000009
            +v -1.059260 2.511110 -0.000009
            +v -1.232410 2.463890 -0.000009
            +v -1.300000 2.400000 -0.000008
            +v -0.338579 2.636110 -0.094239
            +v -0.553875 2.588890 -0.154160
            +v -0.795972 2.550000 -0.221537
            +v -1.021990 2.511110 -0.284440
            +v -1.189040 2.463890 -0.330933
            +v -1.254260 2.400000 -0.349083
            +v -0.303616 2.636110 -0.178332
            +v -0.496680 2.588890 -0.291725
            +v -0.713778 2.550000 -0.419231
            +v -0.916455 2.511110 -0.538270
            +v -1.066260 2.463890 -0.626255
            +v -1.124740 2.400000 -0.660602
            +v -0.249157 2.636110 -0.249167
            +v -0.407593 2.588890 -0.407603
            +v -0.585750 2.550000 -0.585759
            +v -0.752074 2.511110 -0.752083
            +v -0.875009 2.463890 -0.875018
            +v -0.923000 2.400000 -0.923009
            +v -0.178322 2.636110 -0.303626
            +v -0.291715 2.588890 -0.496690
            +v -0.419222 2.550000 -0.713787
            +v -0.538261 2.511110 -0.916464
            +v -0.626246 2.463890 -1.066270
            +v -0.660593 2.400000 -1.124750
            +v -0.094230 2.636110 -0.338589
            +v -0.154150 2.588890 -0.553885
            +v -0.221528 2.550000 -0.795981
            +v -0.284431 2.511110 -1.022000
            +v -0.330924 2.463890 -1.189050
            +v -0.349074 2.400000 -1.254270
            +v 0.000000 2.636110 -0.350936
            +v 0.000000 2.588890 -0.574084
            +v 0.000000 2.550000 -0.825009
            +v 0.000000 2.511110 -1.059270
            +v 0.000000 2.463890 -1.232420
            +v 0.000000 2.400000 -1.300010
            +v 0.094230 2.636110 -0.338589
            +v 0.154150 2.588890 -0.553885
            +v 0.221528 2.550000 -0.795981
            +v 0.284431 2.511110 -1.022000
            +v 0.330924 2.463890 -1.189050
            +v 0.349074 2.400000 -1.254270
            +v 0.178322 2.636110 -0.303626
            +v 0.291715 2.588890 -0.496690
            +v 0.419222 2.550000 -0.713787
            +v 0.538261 2.511110 -0.916464
            +v 0.626246 2.463890 -1.066270
            +v 0.660593 2.400000 -1.124750
            +v 0.249157 2.636110 -0.249167
            +v 0.407593 2.588890 -0.407603
            +v 0.585750 2.550000 -0.585759
            +v 0.752074 2.511110 -0.752083
            +v 0.875009 2.463890 -0.875018
            +v 0.923000 2.400000 -0.923009
            +v 0.303616 2.636110 -0.178332
            +v 0.496680 2.588890 -0.291725
            +v 0.713778 2.550000 -0.419231
            +v 0.916455 2.511110 -0.538270
            +v 1.066260 2.463890 -0.626255
            +v 1.124740 2.400000 -0.660602
            +v 0.338579 2.636110 -0.094239
            +v 0.553875 2.588890 -0.154160
            +v 0.795972 2.550000 -0.221537
            +v 1.021990 2.511110 -0.284440
            +v 1.189040 2.463890 -0.330933
            +v 1.254260 2.400000 -0.349083
            +v -1.924540 2.023960 -0.000007
            +v -1.600000 2.025000 -0.000007
            +v -1.927040 2.040550 0.124992
            +v -1.592590 2.041670 0.124992
            +v -2.196300 2.016670 -0.000007
            +v -2.206450 2.032720 0.124992
            +v -2.428240 2.011460 0.124993
            +v -2.412500 1.996870 -0.000007
            +v -2.589850 1.970060 0.124993
            +v -2.570370 1.958330 -0.000007
            +v -2.688700 1.901810 0.124993
            +v -2.667130 1.894790 -0.000007
            +v -2.722220 1.800000 0.124993
            +v -2.700000 1.800000 -0.000006
            +v -1.933300 2.082020 0.199992
            +v -1.574070 2.083330 0.199992
            +v -2.231820 2.072840 0.199992
            +v -2.467590 2.047920 0.199992
            +v -2.638550 1.999380 0.199993
            +v -2.742630 1.919370 0.199993
            +v -2.777780 1.800000 0.199993
            +v -1.941440 2.135940 0.224992
            +v -1.550000 2.137500 0.224992
            +v -2.264810 2.125000 0.224992
            +v -2.518750 2.095310 0.224992
            +v -2.701850 2.037500 0.224992
            +v -2.812730 1.942190 0.224993
            +v -2.850000 1.800000 0.224993
            +v -1.949570 2.189850 0.199992
            +v -1.525930 2.191670 0.199992
            +v -2.297810 2.177160 0.199992
            +v -2.569910 2.142710 0.199992
            +v -2.765160 2.075620 0.199992
            +v -2.882840 1.965010 0.199993
            +v -2.922220 1.800000 0.199993
            +v -1.955830 2.231330 0.124992
            +v -1.507410 2.233330 0.124992
            +v -2.323180 2.217280 0.124992
            +v -2.609260 2.179170 0.124992
            +v -2.813850 2.104940 0.124992
            +v -2.936760 1.982560 0.124993
            +v -2.977780 1.800000 0.124993
            +v -1.958330 2.247920 -0.000008
            +v -1.500000 2.250000 -0.000008
            +v -2.333330 2.233330 -0.000008
            +v -2.625000 2.193750 -0.000008
            +v -2.833330 2.116670 -0.000007
            +v -2.958330 1.989580 -0.000007
            +v -3.000000 1.800000 -0.000006
            +v -1.507410 2.233330 -0.125008
            +v -1.955830 2.231330 -0.125008
            +v -2.323180 2.217280 -0.125008
            +v -2.609260 2.179170 -0.125008
            +v -2.813850 2.104940 -0.125008
            +v -2.936760 1.982560 -0.125007
            +v -2.977780 1.800000 -0.125007
            +v -1.525930 2.191670 -0.200008
            +v -1.949570 2.189850 -0.200008
            +v -2.297810 2.177160 -0.200008
            +v -2.569910 2.142710 -0.200008
            +v -2.765160 2.075620 -0.200008
            +v -2.882840 1.965010 -0.200007
            +v -2.922220 1.800000 -0.200007
            +v -1.550000 2.137500 -0.225008
            +v -1.941440 2.135940 -0.225008
            +v -2.264810 2.125000 -0.225008
            +v -2.518750 2.095310 -0.225008
            +v -2.701850 2.037500 -0.225008
            +v -2.812730 1.942190 -0.225007
            +v -2.850000 1.800000 -0.225007
            +v -1.574070 2.083330 -0.200008
            +v -1.933300 2.082020 -0.200008
            +v -2.231820 2.072840 -0.200008
            +v -2.467590 2.047920 -0.200008
            +v -2.638550 1.999380 -0.200007
            +v -2.742630 1.919370 -0.200007
            +v -2.777780 1.800000 -0.200007
            +v -1.592590 2.041670 -0.125008
            +v -1.927040 2.040550 -0.125008
            +v -2.206450 2.032720 -0.125008
            +v -2.428240 2.011460 -0.125007
            +v -2.589850 1.970060 -0.125007
            +v -2.688700 1.901810 -0.125007
            +v -2.722220 1.800000 -0.125007
            +v -2.704180 1.663980 0.124994
            +v -2.682870 1.670830 -0.000006
            +v -2.648290 1.505350 0.124994
            +v -2.629630 1.516670 -0.000005
            +v -2.551850 1.335760 0.124995
            +v -2.537500 1.350000 -0.000005
            +v -2.412210 1.166870 0.124996
            +v -2.403700 1.183330 -0.000004
            +v -2.226680 1.010330 0.124996
            +v -2.225460 1.029170 -0.000004
            +v -1.992590 0.877778 0.124997
            +v -2.000000 0.900000 -0.000003
            +v -2.757470 1.646840 0.199994
            +v -2.694920 1.477060 0.199995
            +v -2.587730 1.300170 0.199995
            +v -2.433470 1.125720 0.199996
            +v -2.229720 0.963228 0.199996
            +v -1.974070 0.822223 0.199997
            +v -2.826740 1.624570 0.224994
            +v -2.755560 1.440280 0.224995
            +v -2.634370 1.253910 0.224995
            +v -2.461110 1.072220 0.224996
            +v -2.233680 0.901998 0.224997
            +v -1.950000 0.750001 0.224997
            +v -2.896000 1.602290 0.199994
            +v -2.816190 1.403500 0.199995
            +v -2.681020 1.207640 0.199996
            +v -2.488750 1.018720 0.199996
            +v -2.237640 0.840767 0.199997
            +v -1.925930 0.677779 0.199997
            +v -2.949290 1.585150 0.124994
            +v -2.862830 1.375210 0.124995
            +v -2.716900 1.172050 0.124996
            +v -2.510010 0.977573 0.124996
            +v -2.240680 0.793666 0.124997
            +v -1.907410 0.622222 0.124998
            +v -2.970600 1.578300 -0.000006
            +v -2.881480 1.363890 -0.000005
            +v -2.731250 1.157810 -0.000004
            +v -2.518520 0.961111 -0.000003
            +v -2.241900 0.774826 -0.000003
            +v -1.900000 0.600000 -0.000002
            +v -2.949290 1.585150 -0.125006
            +v -2.862830 1.375210 -0.125005
            +v -2.716900 1.172050 -0.125004
            +v -2.510010 0.977572 -0.125004
            +v -2.240680 0.793666 -0.125003
            +v -1.907410 0.622222 -0.125002
            +v -2.896000 1.602290 -0.200006
            +v -2.816190 1.403500 -0.200005
            +v -2.681020 1.207640 -0.200004
            +v -2.488750 1.018720 -0.200004
            +v -2.237640 0.840765 -0.200003
            +v -1.925930 0.677777 -0.200003
            +v -2.826740 1.624570 -0.225006
            +v -2.755560 1.440280 -0.225005
            +v -2.634370 1.253910 -0.225005
            +v -2.461110 1.072220 -0.225004
            +v -2.233680 0.901996 -0.225003
            +v -1.950000 0.749999 -0.225003
            +v -2.757470 1.646840 -0.200006
            +v -2.694920 1.477060 -0.200005
            +v -2.587730 1.300170 -0.200005
            +v -2.433470 1.125720 -0.200004
            +v -2.229720 0.963226 -0.200004
            +v -1.974070 0.822221 -0.200003
            +v -2.704180 1.663980 -0.125006
            +v -2.648290 1.505350 -0.125006
            +v -2.551850 1.335760 -0.125005
            +v -2.412210 1.166870 -0.125004
            +v -2.226680 1.010330 -0.125004
            +v -1.992590 0.877778 -0.125003
            +v 1.700000 1.425000 -0.000005
            +v 1.700000 1.363890 0.274995
            +v 2.072380 1.425210 0.262341
            +v 2.058800 1.476390 -0.000005
            +v 2.290120 1.572020 0.230704
            +v 2.270370 1.611110 -0.000006
            +v 2.409720 1.773610 0.189576
            +v 2.387500 1.800000 -0.000006
            +v 2.487650 1.999280 0.148450
            +v 2.462960 2.013890 -0.000007
            +v 2.580400 2.218310 0.116813
            +v 2.549540 2.223610 -0.000008
            +v 2.700000 2.400000 -0.000008
            +v 2.744440 2.400000 0.104158
            +v 1.700000 1.211110 0.439996
            +v 2.106330 1.297250 0.419748
            +v 2.339510 1.474280 0.369131
            +v 2.465280 1.707640 0.303327
            +v 2.549380 1.962760 0.237524
            +v 2.657560 2.205070 0.186906
            +v 2.855560 2.400000 0.166658
            +v 1.700000 1.012500 0.494996
            +v 2.150460 1.130900 0.472218
            +v 2.403700 1.347220 0.415273
            +v 2.537500 1.621870 0.341244
            +v 2.629630 1.915280 0.267215
            +v 2.757870 2.187850 0.210270
            +v 3.000000 2.400000 0.187491
            +v 1.700000 0.813891 0.439997
            +v 2.194600 0.964560 0.419749
            +v 2.467900 1.220160 0.369132
            +v 2.609720 1.536110 0.303327
            +v 2.709880 1.867800 0.237524
            +v 2.858180 2.170630 0.186906
            +v 3.144440 2.400000 0.166658
            +v 1.700000 0.661112 0.274998
            +v 2.228550 0.836601 0.262343
            +v 2.517280 1.122430 0.230706
            +v 2.665280 1.470140 0.189578
            +v 2.771600 1.831280 0.148450
            +v 2.935340 2.157380 0.116813
            +v 3.255560 2.400000 0.104158
            +v 1.700000 0.600000 -0.000002
            +v 2.242130 0.785417 -0.000003
            +v 2.537040 1.083330 -0.000004
            +v 2.687500 1.443750 -0.000005
            +v 2.796300 1.816670 -0.000006
            +v 2.966200 2.152080 -0.000008
            +v 3.300000 2.400000 -0.000008
            +v 1.700000 0.661110 -0.275002
            +v 2.228550 0.836599 -0.262349
            +v 2.517280 1.122430 -0.230714
            +v 2.665280 1.470140 -0.189588
            +v 2.771600 1.831280 -0.148464
            +v 2.935340 2.157380 -0.116829
            +v 3.255560 2.400000 -0.104176
            +v 1.700000 0.813887 -0.440003
            +v 2.194600 0.964556 -0.419757
            +v 2.467900 1.220160 -0.369141
            +v 2.609720 1.536110 -0.303339
            +v 2.709880 1.867800 -0.237538
            +v 2.858180 2.170630 -0.186922
            +v 3.144440 2.400000 -0.166676
            +v 1.700000 1.012500 -0.495004
            +v 2.150460 1.130900 -0.472226
            +v 2.403700 1.347220 -0.415283
            +v 2.537500 1.621870 -0.341256
            +v 2.629630 1.915280 -0.267229
            +v 2.757870 2.187850 -0.210286
            +v 3.000000 2.400000 -0.187509
            +v 1.700000 1.211110 -0.440004
            +v 2.106330 1.297250 -0.419758
            +v 2.339510 1.474280 -0.369141
            +v 2.465280 1.707640 -0.303339
            +v 2.549380 1.962760 -0.237538
            +v 2.657560 2.205070 -0.186922
            +v 2.855560 2.400000 -0.166676
            +v 1.700000 1.363890 -0.275005
            +v 2.072380 1.425210 -0.262351
            +v 2.290120 1.572020 -0.230716
            +v 2.409720 1.773610 -0.189590
            +v 2.487650 1.999280 -0.148464
            +v 2.580400 2.218310 -0.116829
            +v 2.744440 2.400000 -0.104176
            +v 2.749070 2.431250 -0.000009
            +v 2.796410 2.431930 0.101023
            +v 2.792590 2.450000 -0.000009
            +v 2.839780 2.451230 0.092969
            +v 2.825000 2.456250 -0.000009
            +v 2.869680 2.457810 0.082022
            +v 2.881210 2.451540 0.070207
            +v 2.840740 2.450000 -0.000009
            +v 2.869490 2.432310 0.059549
            +v 2.834260 2.431250 -0.000009
            +v 2.829630 2.400000 0.052074
            +v 2.800000 2.400000 -0.000008
            +v 2.914740 2.433610 0.161565
            +v 2.957750 2.454320 0.148139
            +v 2.981370 2.461720 0.129158
            +v 2.982370 2.455400 0.107398
            +v 2.957560 2.434960 0.085639
            +v 2.903700 2.400000 0.066658
            +v 3.068580 2.435810 0.181675
            +v 3.111110 2.458330 0.165963
            +v 3.126560 2.466800 0.142960
            +v 3.113890 2.460420 0.115269
            +v 3.072050 2.438410 0.085495
            +v 3.000000 2.400000 0.056241
            +v 3.222410 2.438000 0.161411
            +v 3.264470 2.462350 0.146905
            +v 3.271760 2.471870 0.124991
            +v 3.245400 2.465430 0.097522
            +v 3.186540 2.441860 0.066349
            +v 3.096300 2.400000 0.033324
            +v 3.340750 2.439690 0.100830
            +v 3.382440 2.465430 0.091426
            +v 3.383450 2.475780 0.076814
            +v 3.346570 2.469290 0.057861
            +v 3.274610 2.444510 0.035437
            +v 3.170370 2.400000 0.010408
            +v 3.388080 2.440360 -0.000009
            +v 3.429630 2.466670 -0.000009
            +v 3.428130 2.477340 -0.000009
            +v 3.387040 2.470830 -0.000009
            +v 3.309840 2.445570 -0.000009
            +v 3.200000 2.400000 -0.000008
            +v 3.340750 2.439690 -0.101089
            +v 3.382440 2.465430 -0.093373
            +v 3.383450 2.475780 -0.083342
            +v 3.346570 2.469290 -0.073312
            +v 3.274610 2.444510 -0.065595
            +v 3.170370 2.400000 -0.062509
            +v 3.222410 2.438000 -0.161737
            +v 3.264470 2.462350 -0.149392
            +v 3.271760 2.471870 -0.133342
            +v 3.245400 2.465430 -0.117293
            +v 3.186540 2.441860 -0.104947
            +v 3.096300 2.400000 -0.100009
            +v 3.068580 2.435810 -0.181953
            +v 3.111110 2.458330 -0.168065
            +v 3.126560 2.466800 -0.150009
            +v 3.113890 2.460420 -0.131953
            +v 3.072050 2.438410 -0.118065
            +v 3.000000 2.400000 -0.112509
            +v 2.914740 2.433610 -0.161737
            +v 2.957750 2.454320 -0.149392
            +v 2.981370 2.461720 -0.133342
            +v 2.982370 2.455400 -0.117293
            +v 2.957560 2.434960 -0.104947
            +v 2.903700 2.400000 -0.100009
            +v 2.796410 2.431930 -0.101089
            +v 2.839780 2.451230 -0.093373
            +v 2.869680 2.457810 -0.083342
            +v 2.881210 2.451540 -0.073312
            +v 2.869490 2.432310 -0.065595
            +v 2.829630 2.400000 -0.062509
            +v 0.278704 3.127080 -0.000011
            +v 0.000000 3.150000 -0.000011
            +v 0.268946 3.127080 0.075067
            +v 0.241285 3.127080 0.141920
            +v 0.198140 3.127080 0.198129
            +v 0.141931 3.127080 0.241274
            +v 0.075078 3.127080 0.268935
            +v 0.000000 3.127080 0.278693
            +v -0.075078 3.127080 0.268935
            +v -0.141931 3.127080 0.241274
            +v -0.198140 3.127080 0.198129
            +v -0.241285 3.127080 0.141920
            +v -0.268946 3.127080 0.075067
            +v -0.278704 3.127080 -0.000011
            +v -0.268946 3.127080 -0.075089
            +v -0.241285 3.127080 -0.141942
            +v -0.198140 3.127080 -0.198151
            +v -0.141931 3.127080 -0.241296
            +v -0.075078 3.127080 -0.268957
            +v 0.000000 3.127080 -0.278715
            +v 0.075078 3.127080 -0.268957
            +v 0.141931 3.127080 -0.241296
            +v 0.198140 3.127080 -0.198151
            +v 0.241285 3.127080 -0.141942
            +v 0.268946 3.127080 -0.075089
            +v 0.350254 3.066670 0.097760
            +v 0.362963 3.066670 -0.000011
            +v 0.313617 2.981250 0.087518
            +v 0.325000 2.981250 -0.000011
            +v 0.228728 2.883330 0.063793
            +v 0.237037 2.883330 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.314228 3.066670 0.184824
            +v 0.281352 2.981250 0.165470
            +v 0.205180 2.883330 0.120636
            +v 0.148234 2.785420 0.087096
            +v 0.258037 3.066670 0.258027
            +v 0.231031 2.981250 0.231020
            +v 0.168463 2.883330 0.168452
            +v 0.121672 2.785420 0.121662
            +v 0.184834 3.066670 0.314218
            +v 0.165481 2.981250 0.281341
            +v 0.120647 2.883330 0.205169
            +v 0.087106 2.785420 0.148224
            +v 0.097771 3.066670 0.350244
            +v 0.087529 2.981250 0.313606
            +v 0.063803 2.883330 0.228717
            +v 0.046045 2.785420 0.165269
            +v 0.000000 3.066670 0.362953
            +v 0.000000 2.981250 0.324989
            +v 0.000000 2.883330 0.237026
            +v 0.000000 2.785420 0.171286
            +v -0.097771 3.066670 0.350244
            +v -0.087529 2.981250 0.313606
            +v -0.063803 2.883330 0.228717
            +v -0.046045 2.785420 0.165269
            +v -0.184834 3.066670 0.314218
            +v -0.165481 2.981250 0.281341
            +v -0.120647 2.883330 0.205169
            +v -0.087106 2.785420 0.148224
            +v -0.258037 3.066670 0.258027
            +v -0.231031 2.981250 0.231020
            +v -0.168463 2.883330 0.168452
            +v -0.121672 2.785420 0.121662
            +v -0.314228 3.066670 0.184824
            +v -0.281352 2.981250 0.165470
            +v -0.205180 2.883330 0.120636
            +v -0.148234 2.785420 0.087096
            +v -0.350254 3.066670 0.097760
            +v -0.313617 2.981250 0.087518
            +v -0.228728 2.883330 0.063793
            +v -0.165279 2.785420 0.046035
            +v -0.362963 3.066670 -0.000011
            +v -0.325000 2.981250 -0.000011
            +v -0.237037 2.883330 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.350254 3.066670 -0.097782
            +v -0.313617 2.981250 -0.087540
            +v -0.228728 2.883330 -0.063813
            +v -0.165279 2.785420 -0.046055
            +v -0.314228 3.066670 -0.184844
            +v -0.281352 2.981250 -0.165492
            +v -0.205180 2.883330 -0.120658
            +v -0.148234 2.785420 -0.087116
            +v -0.258037 3.066670 -0.258047
            +v -0.231031 2.981250 -0.231042
            +v -0.168463 2.883330 -0.168474
            +v -0.121672 2.785420 -0.121682
            +v -0.184834 3.066670 -0.314238
            +v -0.165481 2.981250 -0.281363
            +v -0.120647 2.883330 -0.205191
            +v -0.087106 2.785420 -0.148244
            +v -0.097771 3.066670 -0.350264
            +v -0.087529 2.981250 -0.313628
            +v -0.063803 2.883330 -0.228739
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 3.066670 -0.362973
            +v 0.000000 2.981250 -0.325011
            +v 0.000000 2.883330 -0.237048
            +v 0.000000 2.785420 -0.171306
            +v 0.097771 3.066670 -0.350264
            +v 0.087529 2.981250 -0.313628
            +v 0.063803 2.883330 -0.228739
            +v 0.046045 2.785420 -0.165289
            +v 0.184834 3.066670 -0.314238
            +v 0.165481 2.981250 -0.281363
            +v 0.120647 2.883330 -0.205191
            +v 0.087106 2.785420 -0.148244
            +v 0.258037 3.066670 -0.258047
            +v 0.231031 2.981250 -0.231042
            +v 0.168463 2.883330 -0.168474
            +v 0.121672 2.785420 -0.121682
            +v 0.314228 3.066670 -0.184844
            +v 0.281352 2.981250 -0.165492
            +v 0.205180 2.883330 -0.120658
            +v 0.148234 2.785420 -0.087116
            +v 0.350254 3.066670 -0.097782
            +v 0.313617 2.981250 -0.087540
            +v 0.228728 2.883330 -0.063813
            +v 0.165279 2.785420 -0.046055
            +vn 0.025666 -0.999664 0.000000
            +vn 0.000000 -1.000000 0.000000
            +vn 0.024781 -0.999664 -0.006623
            +vn 0.022156 -0.999664 -0.012787
            +vn 0.018067 -0.999664 -0.018067
            +vn 0.012787 -0.999664 -0.022126
            +vn 0.006623 -0.999664 -0.024751
            +vn 0.000000 -0.999664 -0.025666
            +vn -0.006623 -0.999664 -0.024751
            +vn -0.012787 -0.999664 -0.022126
            +vn -0.018067 -0.999664 -0.018067
            +vn -0.022156 -0.999664 -0.012787
            +vn -0.024781 -0.999664 -0.006623
            +vn -0.025666 -0.999664 0.000000
            +vn -0.024781 -0.999664 0.006623
            +vn -0.022156 -0.999664 0.012787
            +vn -0.018067 -0.999664 0.018067
            +vn -0.012787 -0.999664 0.022156
            +vn -0.006623 -0.999664 0.024781
            +vn 0.000000 -0.999664 0.025666
            +vn 0.006623 -0.999664 0.024781
            +vn 0.012787 -0.999664 0.022156
            +vn 0.018067 -0.999664 0.018067
            +vn 0.022156 -0.999664 0.012787
            +vn 0.024781 -0.999664 0.006623
            +vn -0.946562 -0.322459 0.000000
            +vn -0.913999 -0.322947 -0.245491
            +vn -0.958617 -0.122227 -0.257057
            +vn -0.992523 -0.122013 0.000000
            +vn -0.832057 0.554674 0.000000
            +vn -0.803217 0.555376 -0.215308
            +vn -0.048616 0.998810 0.000000
            +vn -0.046205 0.998840 -0.012726
            +vn 0.525376 0.839106 0.140843
            +vn 0.544267 0.838893 0.000000
            +vn 0.756340 0.621845 0.202918
            +vn 0.783471 0.621387 0.000000
            +vn 0.850551 0.473769 0.228217
            +vn 0.880886 0.473281 0.000000
            +vn -0.818842 -0.323435 -0.474166
            +vn -0.859004 -0.122410 -0.497085
            +vn -0.719657 0.555559 -0.416425
            +vn -0.041749 0.998810 -0.024415
            +vn 0.470107 0.839625 0.272011
            +vn 0.677236 0.622608 0.391980
            +vn 0.761803 0.474471 0.440962
            +vn -0.669027 -0.323679 -0.669027
            +vn -0.701773 -0.122440 -0.701773
            +vn -0.587878 0.555650 -0.587878
            +vn -0.034272 0.998810 -0.034272
            +vn 0.383831 0.839808 0.383831
            +vn 0.553148 0.622913 0.553148
            +vn 0.622303 0.474776 0.622303
            +vn -0.474166 -0.323435 -0.818842
            +vn -0.497085 -0.122410 -0.859004
            +vn -0.416425 0.555528 -0.719657
            +vn -0.024415 0.998810 -0.041749
            +vn 0.272011 0.839625 0.470077
            +vn 0.392010 0.622608 0.677236
            +vn 0.440962 0.474502 0.761803
            +vn -0.245460 -0.322977 -0.913999
            +vn -0.257057 -0.122257 -0.958617
            +vn -0.215339 0.555193 -0.803308
            +vn -0.012726 0.998840 -0.046236
            +vn 0.140873 0.839076 0.525437
            +vn 0.202918 0.621906 0.756310
            +vn 0.228217 0.473769 0.850551
            +vn 0.000000 -0.322489 -0.946562
            +vn 0.000000 -0.122044 -0.992523
            +vn 0.000000 0.554491 -0.832179
            +vn 0.000000 0.998779 -0.048799
            +vn 0.000000 0.838893 0.544267
            +vn 0.000000 0.621387 0.783471
            +vn 0.000000 0.473281 0.880886
            +vn 0.245460 -0.322977 -0.913999
            +vn 0.257057 -0.122257 -0.958617
            +vn 0.215339 0.555193 -0.803308
            +vn 0.012726 0.998840 -0.046236
            +vn -0.140873 0.839076 0.525437
            +vn -0.202918 0.621906 0.756310
            +vn -0.228217 0.473769 0.850551
            +vn 0.474166 -0.323435 -0.818842
            +vn 0.497085 -0.122410 -0.859004
            +vn 0.416425 0.555528 -0.719657
            +vn 0.024415 0.998810 -0.041749
            +vn -0.272011 0.839625 0.470077
            +vn -0.392010 0.622608 0.677236
            +vn -0.440962 0.474502 0.761803
            +vn 0.669027 -0.323679 -0.669027
            +vn 0.701773 -0.122440 -0.701773
            +vn 0.587878 0.555650 -0.587878
            +vn 0.034272 0.998810 -0.034272
            +vn -0.383831 0.839808 0.383831
            +vn -0.553148 0.622913 0.553148
            +vn -0.622303 0.474776 0.622303
            +vn 0.818842 -0.323435 -0.474166
            +vn 0.859004 -0.122410 -0.497085
            +vn 0.719657 0.555559 -0.416425
            +vn 0.041749 0.998810 -0.024415
            +vn -0.470107 0.839625 0.272011
            +vn -0.677236 0.622608 0.391980
            +vn -0.761803 0.474471 0.440962
            +vn 0.913999 -0.322947 -0.245491
            +vn 0.958617 -0.122227 -0.257057
            +vn 0.803217 0.555376 -0.215308
            +vn 0.046205 0.998840 -0.012726
            +vn -0.525376 0.839106 0.140843
            +vn -0.756340 0.621845 0.202918
            +vn -0.850551 0.473769 0.228217
            +vn 0.946562 -0.322459 0.000000
            +vn 0.992523 -0.122013 0.000000
            +vn 0.832057 0.554674 0.000000
            +vn 0.048616 0.998810 0.000000
            +vn -0.544267 0.838893 0.000000
            +vn -0.783471 0.621387 0.000000
            +vn -0.880886 0.473281 0.000000
            +vn 0.913999 -0.322947 0.245491
            +vn 0.958617 -0.122227 0.257057
            +vn 0.803217 0.555376 0.215308
            +vn 0.046205 0.998840 0.012726
            +vn -0.525376 0.839106 -0.140843
            +vn -0.756340 0.621845 -0.202918
            +vn -0.850551 0.473769 -0.228217
            +vn 0.818842 -0.323435 0.474166
            +vn 0.859004 -0.122410 0.497085
            +vn 0.719657 0.555559 0.416425
            +vn 0.041749 0.998810 0.024415
            +vn -0.470107 0.839625 -0.272011
            +vn -0.677236 0.622608 -0.391980
            +vn -0.761803 0.474471 -0.440962
            +vn 0.669027 -0.323679 0.669027
            +vn 0.701773 -0.122440 0.701773
            +vn 0.587878 0.555650 0.587878
            +vn 0.034272 0.998810 0.034272
            +vn -0.383831 0.839808 -0.383831
            +vn -0.553148 0.622913 -0.553148
            +vn -0.622303 0.474776 -0.622303
            +vn 0.474166 -0.323435 0.818842
            +vn 0.497085 -0.122410 0.859004
            +vn 0.416425 0.555559 0.719657
            +vn 0.024415 0.998810 0.041749
            +vn -0.272011 0.839625 -0.470107
            +vn -0.391980 0.622608 -0.677236
            +vn -0.440962 0.474471 -0.761803
            +vn 0.245460 -0.322977 0.913999
            +vn 0.257027 -0.122257 0.958617
            +vn 0.215369 0.555193 0.803308
            +vn 0.012726 0.998840 0.046236
            +vn -0.140873 0.839045 -0.525498
            +vn -0.202918 0.621845 -0.756371
            +vn -0.228187 0.473769 -0.850551
            +vn 0.000000 -0.322459 0.946562
            +vn 0.000000 -0.122013 0.992523
            +vn 0.000000 0.554674 0.832057
            +vn 0.000000 0.998810 0.048616
            +vn 0.000000 0.838893 -0.544267
            +vn 0.000000 0.621387 -0.783471
            +vn 0.000000 0.473281 -0.880886
            +vn -0.245460 -0.322977 0.913999
            +vn -0.257027 -0.122257 0.958617
            +vn -0.215369 0.555193 0.803308
            +vn -0.012726 0.998840 0.046236
            +vn 0.140873 0.839045 -0.525498
            +vn 0.202918 0.621845 -0.756371
            +vn 0.228187 0.473769 -0.850551
            +vn -0.474166 -0.323435 0.818842
            +vn -0.497085 -0.122410 0.859004
            +vn -0.416425 0.555559 0.719657
            +vn -0.024415 0.998810 0.041749
            +vn 0.272011 0.839625 -0.470107
            +vn 0.391980 0.622608 -0.677236
            +vn 0.440962 0.474471 -0.761803
            +vn -0.669027 -0.323679 0.669027
            +vn -0.701773 -0.122440 0.701773
            +vn -0.587878 0.555650 0.587878
            +vn -0.034272 0.998810 0.034272
            +vn 0.383831 0.839808 -0.383831
            +vn 0.553148 0.622913 -0.553148
            +vn 0.622303 0.474776 -0.622303
            +vn -0.818842 -0.323435 0.474166
            +vn -0.859004 -0.122410 0.497085
            +vn -0.719657 0.555559 0.416425
            +vn -0.041749 0.998810 0.024415
            +vn 0.470107 0.839625 -0.272011
            +vn 0.677236 0.622608 -0.391980
            +vn 0.761803 0.474471 -0.440962
            +vn -0.913999 -0.322947 0.245491
            +vn -0.958617 -0.122227 0.257057
            +vn -0.803217 0.555376 0.215308
            +vn -0.046205 0.998840 0.012726
            +vn 0.525376 0.839106 -0.140843
            +vn 0.756340 0.621845 -0.202918
            +vn 0.850551 0.473769 -0.228217
            +vn 0.877041 0.418744 0.235298
            +vn 0.908292 0.418256 0.000000
            +vn 0.888668 0.391644 0.238441
            +vn 0.920286 0.391156 0.000000
            +vn 0.907315 0.342753 0.243446
            +vn 0.939543 0.342357 0.000000
            +vn 0.931028 0.265908 0.249855
            +vn 0.964080 0.265542 0.000000
            +vn 0.954558 0.152104 0.256172
            +vn 0.988372 0.151891 0.000000
            +vn 0.964782 -0.045717 0.258980
            +vn 0.998932 -0.045656 0.000000
            +vn 0.785638 0.419416 0.454756
            +vn 0.796075 0.392285 0.460799
            +vn 0.812830 0.343333 0.470504
            +vn 0.834162 0.266366 0.482864
            +vn 0.855312 0.152409 0.495132
            +vn 0.864498 -0.045808 0.500504
            +vn 0.641804 0.419691 0.641804
            +vn 0.650349 0.392529 0.650349
            +vn 0.664052 0.343577 0.664052
            +vn 0.681509 0.266579 0.681509
            +vn 0.698813 0.152501 0.698813
            +vn 0.706351 -0.045869 0.706351
            +vn 0.454756 0.419416 0.785638
            +vn 0.460799 0.392285 0.796075
            +vn 0.470504 0.343333 0.812830
            +vn 0.482864 0.266396 0.834162
            +vn 0.495132 0.152409 0.855312
            +vn 0.500504 -0.045808 0.864498
            +vn 0.235298 0.418744 0.877041
            +vn 0.238441 0.391644 0.888668
            +vn 0.243446 0.342753 0.907315
            +vn 0.249825 0.265908 0.931028
            +vn 0.256172 0.152135 0.954558
            +vn 0.258980 -0.045717 0.964782
            +vn 0.000000 0.418256 0.908292
            +vn 0.000000 0.391156 0.920286
            +vn 0.000000 0.342357 0.939543
            +vn 0.000000 0.265572 0.964080
            +vn 0.000000 0.151921 0.988372
            +vn 0.000000 -0.045656 0.998932
            +vn -0.235298 0.418744 0.877041
            +vn -0.238441 0.391644 0.888668
            +vn -0.243446 0.342753 0.907315
            +vn -0.249825 0.265908 0.931028
            +vn -0.256172 0.152135 0.954558
            +vn -0.258980 -0.045717 0.964782
            +vn -0.454756 0.419416 0.785638
            +vn -0.460799 0.392285 0.796075
            +vn -0.470504 0.343333 0.812830
            +vn -0.482864 0.266396 0.834162
            +vn -0.495132 0.152409 0.855312
            +vn -0.500504 -0.045808 0.864498
            +vn -0.641804 0.419691 0.641804
            +vn -0.650349 0.392529 0.650349
            +vn -0.664052 0.343577 0.664052
            +vn -0.681509 0.266579 0.681509
            +vn -0.698813 0.152501 0.698813
            +vn -0.706351 -0.045869 0.706351
            +vn -0.785638 0.419416 0.454756
            +vn -0.796075 0.392285 0.460799
            +vn -0.812830 0.343333 0.470504
            +vn -0.834162 0.266366 0.482864
            +vn -0.855312 0.152409 0.495132
            +vn -0.864498 -0.045808 0.500504
            +vn -0.877041 0.418744 0.235298
            +vn -0.888668 0.391644 0.238441
            +vn -0.907315 0.342753 0.243446
            +vn -0.931028 0.265908 0.249825
            +vn -0.954558 0.152104 0.256172
            +vn -0.964782 -0.045717 0.258980
            +vn -0.908292 0.418256 0.000000
            +vn -0.920286 0.391156 0.000000
            +vn -0.939543 0.342357 0.000000
            +vn -0.964080 0.265542 0.000000
            +vn -0.988372 0.151891 0.000000
            +vn -0.998932 -0.045656 0.000000
            +vn -0.877041 0.418744 -0.235298
            +vn -0.888668 0.391644 -0.238441
            +vn -0.907315 0.342753 -0.243446
            +vn -0.931028 0.265877 -0.249855
            +vn -0.954558 0.152104 -0.256172
            +vn -0.964782 -0.045717 -0.258980
            +vn -0.785638 0.419416 -0.454756
            +vn -0.796075 0.392285 -0.460799
            +vn -0.812830 0.343333 -0.470504
            +vn -0.834162 0.266366 -0.482864
            +vn -0.855312 0.152379 -0.495132
            +vn -0.864498 -0.045808 -0.500504
            +vn -0.641804 0.419691 -0.641804
            +vn -0.650349 0.392529 -0.650349
            +vn -0.664052 0.343547 -0.664052
            +vn -0.681509 0.266549 -0.681509
            +vn -0.698813 0.152470 -0.698813
            +vn -0.706351 -0.045869 -0.706351
            +vn -0.454756 0.419416 -0.785638
            +vn -0.460768 0.392285 -0.796075
            +vn -0.470504 0.343333 -0.812830
            +vn -0.482864 0.266366 -0.834162
            +vn -0.495132 0.152379 -0.855312
            +vn -0.500504 -0.045808 -0.864498
            +vn -0.235298 0.418744 -0.877041
            +vn -0.238441 0.391644 -0.888668
            +vn -0.243446 0.342753 -0.907315
            +vn -0.249855 0.265877 -0.931059
            +vn -0.256172 0.152074 -0.954558
            +vn -0.258980 -0.045717 -0.964782
            +vn 0.000000 0.418256 -0.908292
            +vn 0.000000 0.391156 -0.920286
            +vn 0.000000 0.342357 -0.939543
            +vn 0.000000 0.265511 -0.964080
            +vn 0.000000 0.151891 -0.988372
            +vn 0.000000 -0.045656 -0.998932
            +vn 0.235298 0.418744 -0.877041
            +vn 0.238441 0.391644 -0.888668
            +vn 0.243446 0.342753 -0.907315
            +vn 0.249855 0.265877 -0.931059
            +vn 0.256172 0.152074 -0.954558
            +vn 0.258980 -0.045717 -0.964782
            +vn 0.454756 0.419416 -0.785638
            +vn 0.460768 0.392285 -0.796075
            +vn 0.470504 0.343333 -0.812830
            +vn 0.482864 0.266366 -0.834162
            +vn 0.495132 0.152379 -0.855312
            +vn 0.500504 -0.045808 -0.864498
            +vn 0.641804 0.419691 -0.641804
            +vn 0.650349 0.392529 -0.650349
            +vn 0.664052 0.343547 -0.664052
            +vn 0.681509 0.266549 -0.681509
            +vn 0.698813 0.152470 -0.698813
            +vn 0.706351 -0.045869 -0.706351
            +vn 0.785638 0.419416 -0.454756
            +vn 0.796075 0.392285 -0.460799
            +vn 0.812830 0.343333 -0.470504
            +vn 0.834162 0.266366 -0.482864
            +vn 0.855312 0.152379 -0.495132
            +vn 0.864498 -0.045808 -0.500504
            +vn 0.877041 0.418744 -0.235298
            +vn 0.888668 0.391644 -0.238441
            +vn 0.907315 0.342753 -0.243446
            +vn 0.931028 0.265908 -0.249825
            +vn 0.954558 0.152104 -0.256172
            +vn 0.964782 -0.045717 -0.258980
            +vn 0.912839 -0.326609 0.245003
            +vn 0.945250 -0.326273 0.000000
            +vn 0.795892 -0.566485 0.213538
            +vn 0.824396 -0.565996 0.000000
            +vn 0.687399 -0.702445 0.184393
            +vn 0.712180 -0.701987 0.000000
            +vn 0.630146 -0.757805 0.169012
            +vn 0.652974 -0.757347 0.000000
            +vn 0.698752 -0.690329 0.187445
            +vn 0.724021 -0.689749 0.000000
            +vn 0.855861 -0.463454 0.229530
            +vn 0.886380 -0.462905 0.000000
            +vn 0.817774 -0.327158 0.473434
            +vn 0.712729 -0.567248 0.412549
            +vn 0.615375 -0.703146 0.356151
            +vn 0.564043 -0.758446 0.326456
            +vn 0.625660 -0.690939 0.362102
            +vn 0.766625 -0.464125 0.443678
            +vn 0.668111 -0.327403 0.668111
            +vn 0.582171 -0.567522 0.582171
            +vn 0.502579 -0.703421 0.502579
            +vn 0.460646 -0.758660 0.460646
            +vn 0.510971 -0.691183 0.510971
            +vn 0.626209 -0.464370 0.626209
            +vn 0.473434 -0.327158 0.817774
            +vn 0.412549 -0.567248 0.712729
            +vn 0.356151 -0.703146 0.615375
            +vn 0.326456 -0.758446 0.564043
            +vn 0.362102 -0.690939 0.625660
            +vn 0.443678 -0.464125 0.766625
            +vn 0.245003 -0.326609 0.912839
            +vn 0.213538 -0.566485 0.795892
            +vn 0.184393 -0.702445 0.687399
            +vn 0.169012 -0.757805 0.630146
            +vn 0.187414 -0.690329 0.698752
            +vn 0.229530 -0.463454 0.855831
            +vn 0.000000 -0.326273 0.945250
            +vn 0.000000 -0.565996 0.824396
            +vn 0.000000 -0.701987 0.712180
            +vn 0.000000 -0.757347 0.652974
            +vn 0.000000 -0.689749 0.724021
            +vn 0.000000 -0.462905 0.886380
            +vn -0.245003 -0.326609 0.912839
            +vn -0.213538 -0.566485 0.795892
            +vn -0.184393 -0.702445 0.687399
            +vn -0.169012 -0.757805 0.630146
            +vn -0.187414 -0.690329 0.698752
            +vn -0.229530 -0.463454 0.855831
            +vn -0.473434 -0.327158 0.817774
            +vn -0.412549 -0.567248 0.712729
            +vn -0.356151 -0.703146 0.615375
            +vn -0.326456 -0.758446 0.564043
            +vn -0.362102 -0.690939 0.625660
            +vn -0.443678 -0.464125 0.766625
            +vn -0.668111 -0.327403 0.668111
            +vn -0.582171 -0.567522 0.582171
            +vn -0.502579 -0.703421 0.502579
            +vn -0.460646 -0.758660 0.460646
            +vn -0.510971 -0.691183 0.510971
            +vn -0.626209 -0.464370 0.626209
            +vn -0.817774 -0.327158 0.473434
            +vn -0.712729 -0.567248 0.412549
            +vn -0.615375 -0.703146 0.356151
            +vn -0.564043 -0.758446 0.326456
            +vn -0.625660 -0.690939 0.362102
            +vn -0.766625 -0.464125 0.443678
            +vn -0.912839 -0.326609 0.245003
            +vn -0.795892 -0.566485 0.213538
            +vn -0.687399 -0.702445 0.184393
            +vn -0.630146 -0.757805 0.169012
            +vn -0.698752 -0.690329 0.187445
            +vn -0.855861 -0.463454 0.229530
            +vn -0.945250 -0.326273 0.000000
            +vn -0.824396 -0.565996 0.000000
            +vn -0.712180 -0.701987 0.000000
            +vn -0.652974 -0.757347 0.000000
            +vn -0.724021 -0.689749 0.000000
            +vn -0.886380 -0.462905 0.000000
            +vn -0.912839 -0.326609 -0.245003
            +vn -0.795892 -0.566485 -0.213538
            +vn -0.687399 -0.702445 -0.184393
            +vn -0.630146 -0.757805 -0.169012
            +vn -0.698752 -0.690329 -0.187414
            +vn -0.855831 -0.463454 -0.229530
            +vn -0.817774 -0.327158 -0.473434
            +vn -0.712729 -0.567248 -0.412549
            +vn -0.615375 -0.703146 -0.356151
            +vn -0.564043 -0.758446 -0.326456
            +vn -0.625660 -0.690939 -0.362102
            +vn -0.766625 -0.464125 -0.443678
            +vn -0.668111 -0.327403 -0.668111
            +vn -0.582171 -0.567522 -0.582171
            +vn -0.502579 -0.703421 -0.502579
            +vn -0.460646 -0.758660 -0.460646
            +vn -0.510971 -0.691183 -0.510971
            +vn -0.626209 -0.464370 -0.626209
            +vn -0.473434 -0.327158 -0.817774
            +vn -0.412549 -0.567248 -0.712729
            +vn -0.356151 -0.703146 -0.615375
            +vn -0.326456 -0.758446 -0.564043
            +vn -0.362102 -0.690939 -0.625660
            +vn -0.443678 -0.464125 -0.766625
            +vn -0.245003 -0.326609 -0.912839
            +vn -0.213538 -0.566485 -0.795892
            +vn -0.184393 -0.702445 -0.687399
            +vn -0.169012 -0.757805 -0.630146
            +vn -0.187414 -0.690329 -0.698752
            +vn -0.229530 -0.463454 -0.855831
            +vn 0.000000 -0.326273 -0.945250
            +vn 0.000000 -0.565996 -0.824396
            +vn 0.000000 -0.701987 -0.712149
            +vn 0.000000 -0.757347 -0.652974
            +vn 0.000000 -0.689749 -0.724021
            +vn 0.000000 -0.462905 -0.886380
            +vn 0.245003 -0.326609 -0.912839
            +vn 0.213538 -0.566485 -0.795892
            +vn 0.184393 -0.702445 -0.687399
            +vn 0.169012 -0.757805 -0.630146
            +vn 0.187414 -0.690329 -0.698752
            +vn 0.229530 -0.463454 -0.855831
            +vn 0.473434 -0.327158 -0.817774
            +vn 0.412549 -0.567248 -0.712729
            +vn 0.356151 -0.703146 -0.615375
            +vn 0.326456 -0.758446 -0.564043
            +vn 0.362102 -0.690939 -0.625660
            +vn 0.443678 -0.464125 -0.766625
            +vn 0.668111 -0.327403 -0.668111
            +vn 0.582171 -0.567522 -0.582171
            +vn 0.502579 -0.703421 -0.502579
            +vn 0.460646 -0.758660 -0.460646
            +vn 0.510971 -0.691183 -0.510971
            +vn 0.626209 -0.464370 -0.626209
            +vn 0.817774 -0.327158 -0.473434
            +vn 0.712729 -0.567248 -0.412549
            +vn 0.615375 -0.703146 -0.356151
            +vn 0.564043 -0.758446 -0.326456
            +vn 0.625660 -0.690939 -0.362102
            +vn 0.766625 -0.464125 -0.443678
            +vn 0.912839 -0.326609 -0.245003
            +vn 0.795892 -0.566485 -0.213538
            +vn 0.687399 -0.702445 -0.184393
            +vn 0.630146 -0.757805 -0.169012
            +vn 0.698752 -0.690329 -0.187414
            +vn 0.855831 -0.463454 -0.229530
            +vn 0.068667 -0.997620 0.000000
            +vn 0.066256 -0.997620 -0.017731
            +vn 0.157170 -0.987548 0.000000
            +vn 0.151677 -0.987579 -0.040620
            +vn 0.373150 -0.927763 0.000000
            +vn 0.360149 -0.927885 -0.096469
            +vn 0.789148 -0.614154 0.000000
            +vn 0.762017 -0.614399 -0.204474
            +vn 0.059236 -0.997650 -0.034242
            +vn 0.135624 -0.987640 -0.078463
            +vn 0.322153 -0.928129 -0.186346
            +vn 0.682333 -0.615131 -0.394971
            +vn 0.048341 -0.997650 -0.048341
            +vn 0.110691 -0.987640 -0.110691
            +vn 0.262947 -0.928251 -0.262947
            +vn 0.557329 -0.615375 -0.557329
            +vn 0.034272 -0.997650 -0.059236
            +vn 0.078463 -0.987640 -0.135624
            +vn 0.186377 -0.928129 -0.322153
            +vn 0.394971 -0.615131 -0.682333
            +vn 0.017731 -0.997620 -0.066256
            +vn 0.040620 -0.987579 -0.151677
            +vn 0.096469 -0.927885 -0.360118
            +vn 0.204505 -0.614399 -0.762017
            +vn 0.000000 -0.997620 -0.068667
            +vn 0.000000 -0.987548 -0.157170
            +vn 0.000000 -0.927763 -0.373150
            +vn 0.000000 -0.614154 -0.789148
            +vn -0.017731 -0.997620 -0.066256
            +vn -0.040620 -0.987579 -0.151677
            +vn -0.096469 -0.927885 -0.360118
            +vn -0.204505 -0.614399 -0.762017
            +vn -0.034272 -0.997650 -0.059236
            +vn -0.078463 -0.987640 -0.135624
            +vn -0.186377 -0.928129 -0.322153
            +vn -0.394971 -0.615131 -0.682333
            +vn -0.048341 -0.997650 -0.048341
            +vn -0.110691 -0.987640 -0.110691
            +vn -0.262947 -0.928251 -0.262947
            +vn -0.557329 -0.615375 -0.557329
            +vn -0.059236 -0.997650 -0.034242
            +vn -0.135624 -0.987640 -0.078463
            +vn -0.322153 -0.928129 -0.186346
            +vn -0.682333 -0.615131 -0.394971
            +vn -0.066256 -0.997620 -0.017731
            +vn -0.151677 -0.987579 -0.040620
            +vn -0.360149 -0.927885 -0.096469
            +vn -0.762017 -0.614399 -0.204474
            +vn -0.068667 -0.997620 0.000000
            +vn -0.157170 -0.987548 0.000000
            +vn -0.373150 -0.927763 0.000000
            +vn -0.789148 -0.614154 0.000000
            +vn -0.066256 -0.997620 0.017731
            +vn -0.151677 -0.987579 0.040620
            +vn -0.360118 -0.927885 0.096469
            +vn -0.762017 -0.614399 0.204505
            +vn -0.059236 -0.997650 0.034272
            +vn -0.135624 -0.987640 0.078463
            +vn -0.322153 -0.928129 0.186377
            +vn -0.682333 -0.615131 0.394971
            +vn -0.048341 -0.997650 0.048341
            +vn -0.110691 -0.987640 0.110691
            +vn -0.262947 -0.928251 0.262947
            +vn -0.557329 -0.615375 0.557329
            +vn -0.034272 -0.997650 0.059236
            +vn -0.078463 -0.987640 0.135624
            +vn -0.186377 -0.928129 0.322153
            +vn -0.394971 -0.615131 0.682333
            +vn -0.017731 -0.997620 0.066256
            +vn -0.040620 -0.987579 0.151677
            +vn -0.096469 -0.927885 0.360149
            +vn -0.204474 -0.614399 0.762017
            +vn 0.000000 -0.997620 0.068667
            +vn 0.000000 -0.987548 0.157170
            +vn 0.000000 -0.927763 0.373150
            +vn 0.000000 -0.614154 0.789148
            +vn 0.017731 -0.997620 0.066256
            +vn 0.040620 -0.987579 0.151677
            +vn 0.096469 -0.927885 0.360149
            +vn 0.204474 -0.614399 0.762017
            +vn 0.034272 -0.997650 0.059236
            +vn 0.078463 -0.987640 0.135624
            +vn 0.186377 -0.928129 0.322153
            +vn 0.394971 -0.615131 0.682333
            +vn 0.048341 -0.997650 0.048341
            +vn 0.110691 -0.987640 0.110691
            +vn 0.262947 -0.928251 0.262947
            +vn 0.557329 -0.615375 0.557329
            +vn 0.059236 -0.997650 0.034272
            +vn 0.135624 -0.987640 0.078463
            +vn 0.322153 -0.928129 0.186377
            +vn 0.682333 -0.615101 0.394971
            +vn 0.066256 -0.997620 0.017731
            +vn 0.151677 -0.987579 0.040620
            +vn 0.360118 -0.927885 0.096469
            +vn 0.762017 -0.614399 0.204505
            +vn 0.692129 0.697470 0.185583
            +vn 0.717063 0.696982 0.000000
            +vn 0.915586 0.318766 0.245064
            +vn 0.947905 0.318522 0.000000
            +vn 0.620045 0.697653 0.358837
            +vn 0.820429 0.318979 0.474410
            +vn 0.506546 0.697684 0.506546
            +vn 0.670125 0.319041 0.670125
            +vn 0.358837 0.697653 0.620045
            +vn 0.474410 0.318979 0.820429
            +vn 0.185583 0.697470 0.692129
            +vn 0.245064 0.318766 0.915586
            +vn 0.000000 0.696982 0.717063
            +vn 0.000000 0.318522 0.947905
            +vn -0.185583 0.697470 0.692129
            +vn -0.245064 0.318766 0.915586
            +vn -0.358837 0.697653 0.620045
            +vn -0.474410 0.318979 0.820429
            +vn -0.506546 0.697684 0.506546
            +vn -0.670125 0.319041 0.670125
            +vn -0.620045 0.697653 0.358837
            +vn -0.820429 0.318979 0.474410
            +vn -0.692129 0.697470 0.185583
            +vn -0.915586 0.318766 0.245064
            +vn -0.717063 0.696982 0.000000
            +vn -0.947905 0.318522 0.000000
            +vn -0.692129 0.697470 -0.185583
            +vn -0.915586 0.318766 -0.245064
            +vn -0.620045 0.697653 -0.358837
            +vn -0.820429 0.318979 -0.474410
            +vn -0.506546 0.697684 -0.506546
            +vn -0.670125 0.319041 -0.670125
            +vn -0.358837 0.697653 -0.620045
            +vn -0.474410 0.318979 -0.820429
            +vn -0.185583 0.697470 -0.692129
            +vn -0.245064 0.318766 -0.915586
            +vn 0.000000 0.696982 -0.717063
            +vn 0.000000 0.318522 -0.947905
            +vn 0.185583 0.697470 -0.692129
            +vn 0.245064 0.318766 -0.915586
            +vn 0.358837 0.697653 -0.620045
            +vn 0.474410 0.318979 -0.820429
            +vn 0.506546 0.697684 -0.506546
            +vn 0.670125 0.319041 -0.670125
            +vn 0.620045 0.697653 -0.358837
            +vn 0.820429 0.318979 -0.474410
            +vn 0.692129 0.697470 -0.185583
            +vn 0.915586 0.318766 -0.245064
            +vn 0.282083 0.956389 0.075686
            +vn 0.292520 0.956236 0.000000
            +vn 0.171606 0.984069 0.046022
            +vn 0.177953 0.984008 0.000000
            +vn 0.153264 0.987304 0.041078
            +vn 0.158879 0.987274 0.000000
            +vn 0.210059 0.976043 0.056276
            +vn 0.217719 0.975982 0.000000
            +vn 0.487197 0.863460 0.130558
            +vn 0.504715 0.863277 0.000000
            +vn 0.662801 0.727226 0.178198
            +vn 0.686911 0.726707 0.000000
            +vn 0.252388 0.956511 0.146092
            +vn 0.153508 0.984130 0.088839
            +vn 0.137059 0.987365 0.079318
            +vn 0.187872 0.976135 0.108676
            +vn 0.435926 0.863887 0.252205
            +vn 0.593310 0.727866 0.343730
            +vn 0.206091 0.956572 0.206091
            +vn 0.125340 0.984161 0.125340
            +vn 0.111911 0.987396 0.111911
            +vn 0.153356 0.976196 0.153356
            +vn 0.355907 0.864071 0.355907
            +vn 0.484664 0.728111 0.484664
            +vn 0.146092 0.956511 0.252388
            +vn 0.088839 0.984130 0.153508
            +vn 0.079318 0.987365 0.137059
            +vn 0.108676 0.976135 0.187872
            +vn 0.252205 0.863887 0.435926
            +vn 0.343730 0.727866 0.593310
            +vn 0.075686 0.956389 0.282083
            +vn 0.046022 0.984069 0.171606
            +vn 0.041078 0.987304 0.153264
            +vn 0.056276 0.976043 0.210059
            +vn 0.130558 0.863460 0.487197
            +vn 0.178198 0.727226 0.662801
            +vn 0.000000 0.956236 0.292520
            +vn 0.000000 0.984008 0.177953
            +vn 0.000000 0.987274 0.158879
            +vn 0.000000 0.975982 0.217719
            +vn 0.000000 0.863277 0.504715
            +vn 0.000000 0.726707 0.686911
            +vn -0.075686 0.956389 0.282083
            +vn -0.046022 0.984069 0.171606
            +vn -0.041078 0.987304 0.153264
            +vn -0.056276 0.976043 0.210059
            +vn -0.130558 0.863460 0.487197
            +vn -0.178198 0.727226 0.662801
            +vn -0.146092 0.956511 0.252388
            +vn -0.088839 0.984130 0.153508
            +vn -0.079318 0.987365 0.137059
            +vn -0.108676 0.976135 0.187872
            +vn -0.252205 0.863887 0.435926
            +vn -0.343730 0.727866 0.593310
            +vn -0.206091 0.956572 0.206091
            +vn -0.125340 0.984161 0.125340
            +vn -0.111911 0.987396 0.111911
            +vn -0.153356 0.976196 0.153356
            +vn -0.355907 0.864071 0.355907
            +vn -0.484664 0.728111 0.484664
            +vn -0.252388 0.956511 0.146092
            +vn -0.153508 0.984130 0.088839
            +vn -0.137059 0.987365 0.079318
            +vn -0.187872 0.976135 0.108676
            +vn -0.435926 0.863887 0.252205
            +vn -0.593310 0.727866 0.343730
            +vn -0.282083 0.956389 0.075686
            +vn -0.171606 0.984069 0.046022
            +vn -0.153264 0.987304 0.041078
            +vn -0.210059 0.976043 0.056276
            +vn -0.487197 0.863460 0.130558
            +vn -0.662801 0.727226 0.178198
            +vn -0.292520 0.956236 0.000000
            +vn -0.177953 0.984008 0.000000
            +vn -0.158879 0.987274 0.000000
            +vn -0.217719 0.975982 0.000000
            +vn -0.504715 0.863277 0.000000
            +vn -0.686911 0.726707 0.000000
            +vn -0.282083 0.956389 -0.075686
            +vn -0.171606 0.984069 -0.046022
            +vn -0.153264 0.987304 -0.041078
            +vn -0.210059 0.976043 -0.056276
            +vn -0.487197 0.863460 -0.130558
            +vn -0.662801 0.727226 -0.178198
            +vn -0.252388 0.956511 -0.146092
            +vn -0.153508 0.984130 -0.088839
            +vn -0.137059 0.987365 -0.079318
            +vn -0.187872 0.976135 -0.108676
            +vn -0.435926 0.863887 -0.252205
            +vn -0.593310 0.727866 -0.343730
            +vn -0.206091 0.956572 -0.206091
            +vn -0.125340 0.984161 -0.125340
            +vn -0.111911 0.987396 -0.111911
            +vn -0.153356 0.976196 -0.153356
            +vn -0.355907 0.864071 -0.355907
            +vn -0.484664 0.728111 -0.484664
            +vn -0.146092 0.956511 -0.252388
            +vn -0.088839 0.984130 -0.153508
            +vn -0.079318 0.987365 -0.137059
            +vn -0.108676 0.976135 -0.187872
            +vn -0.252205 0.863887 -0.435926
            +vn -0.343730 0.727866 -0.593310
            +vn -0.075686 0.956389 -0.282083
            +vn -0.046022 0.984069 -0.171606
            +vn -0.041078 0.987304 -0.153264
            +vn -0.056276 0.976043 -0.210059
            +vn -0.130558 0.863460 -0.487197
            +vn -0.178198 0.727226 -0.662801
            +vn 0.000000 0.956236 -0.292520
            +vn 0.000000 0.984008 -0.177953
            +vn 0.000000 0.987274 -0.158879
            +vn 0.000000 0.975982 -0.217719
            +vn 0.000000 0.863277 -0.504715
            +vn 0.000000 0.726707 -0.686911
            +vn 0.075686 0.956389 -0.282083
            +vn 0.046022 0.984069 -0.171606
            +vn 0.041078 0.987304 -0.153264
            +vn 0.056276 0.976043 -0.210059
            +vn 0.130558 0.863460 -0.487197
            +vn 0.178198 0.727226 -0.662801
            +vn 0.146092 0.956511 -0.252388
            +vn 0.088839 0.984130 -0.153508
            +vn 0.079318 0.987365 -0.137059
            +vn 0.108676 0.976135 -0.187872
            +vn 0.252205 0.863887 -0.435926
            +vn 0.343730 0.727866 -0.593310
            +vn 0.206091 0.956572 -0.206091
            +vn 0.125340 0.984161 -0.125340
            +vn 0.111911 0.987396 -0.111911
            +vn 0.153356 0.976196 -0.153356
            +vn 0.355907 0.864071 -0.355907
            +vn 0.484664 0.728111 -0.484664
            +vn 0.252388 0.956511 -0.146092
            +vn 0.153508 0.984130 -0.088839
            +vn 0.137059 0.987365 -0.079318
            +vn 0.187872 0.976135 -0.108676
            +vn 0.435926 0.863887 -0.252205
            +vn 0.593310 0.727866 -0.343730
            +vn 0.282083 0.956389 -0.075686
            +vn 0.171606 0.984069 -0.046022
            +vn 0.153264 0.987304 -0.041078
            +vn 0.210059 0.976043 -0.056276
            +vn 0.487197 0.863460 -0.130558
            +vn 0.662801 0.727226 -0.178198
            +vn 0.015290 -0.999878 0.000000
            +vn 0.003296 -0.999969 0.000000
            +vn 0.015168 -0.949339 0.313852
            +vn 0.003265 -0.944395 0.328715
            +vn 0.058870 -0.998260 0.000000
            +vn 0.058046 -0.947630 0.314005
            +vn 0.158361 -0.934690 0.318155
            +vn 0.159764 -0.987152 0.000000
            +vn 0.373943 -0.860958 0.344798
            +vn 0.391583 -0.920103 0.000000
            +vn 0.726829 -0.553880 0.406049
            +vn 0.784570 -0.620014 0.000000
            +vn 0.908139 -0.082766 0.410321
            +vn 0.994995 -0.099796 0.000000
            +vn 0.011902 -0.679403 0.733634
            +vn 0.002380 -0.636219 0.771477
            +vn 0.046449 -0.674398 0.736869
            +vn 0.125980 -0.648946 0.750298
            +vn 0.270089 -0.562120 0.781671
            +vn 0.460067 -0.316263 0.829615
            +vn 0.563036 -0.041200 0.825373
            +vn 0.000153 0.004242 0.999969
            +vn -0.000519 0.113254 0.993561
            +vn 0.003510 0.014008 0.999878
            +vn 0.005921 0.035951 0.999329
            +vn -0.007813 0.058840 0.998230
            +vn -0.046510 0.041536 0.998047
            +vn -0.039155 0.003113 0.999207
            +vn -0.014161 0.682394 0.730796
            +vn -0.003204 0.727744 0.685812
            +vn -0.055361 0.680074 0.731010
            +vn -0.150029 0.655660 0.739952
            +vn -0.322520 0.565203 0.759239
            +vn -0.537645 0.315806 0.781762
            +vn -0.611530 0.029939 0.790613
            +vn -0.020569 0.949400 0.313334
            +vn -0.004273 0.954772 0.297281
            +vn -0.082705 0.944945 0.316507
            +vn -0.229591 0.914548 0.332926
            +vn -0.502335 0.785943 0.360454
            +vn -0.810633 0.443220 0.382611
            +vn -0.921232 0.039705 0.386944
            +vn -0.021851 0.999756 0.000000
            +vn -0.004517 0.999969 0.000000
            +vn -0.087649 0.996124 0.000000
            +vn -0.246223 0.969207 0.000000
            +vn -0.549211 0.835658 0.000000
            +vn -0.881039 0.472976 0.000000
            +vn -0.999115 0.041444 0.000000
            +vn -0.004273 0.954772 -0.297281
            +vn -0.020569 0.949400 -0.313334
            +vn -0.082705 0.944945 -0.316507
            +vn -0.229591 0.914548 -0.332926
            +vn -0.502335 0.785943 -0.360454
            +vn -0.810633 0.443220 -0.382611
            +vn -0.921232 0.039705 -0.386944
            +vn -0.003204 0.727744 -0.685812
            +vn -0.014161 0.682394 -0.730796
            +vn -0.055361 0.680074 -0.731010
            +vn -0.150029 0.655660 -0.739952
            +vn -0.322520 0.565203 -0.759239
            +vn -0.537645 0.315806 -0.781762
            +vn -0.611530 0.029939 -0.790613
            +vn -0.000519 0.113254 -0.993561
            +vn 0.000153 0.004242 -0.999969
            +vn 0.003510 0.014008 -0.999878
            +vn 0.005921 0.035951 -0.999329
            +vn -0.007813 0.058809 -0.998230
            +vn -0.046510 0.041536 -0.998047
            +vn -0.039155 0.003113 -0.999207
            +vn 0.002380 -0.636219 -0.771477
            +vn 0.011902 -0.679403 -0.733634
            +vn 0.046449 -0.674398 -0.736869
            +vn 0.125980 -0.648946 -0.750298
            +vn 0.270089 -0.562151 -0.781671
            +vn 0.460067 -0.316263 -0.829615
            +vn 0.563036 -0.041231 -0.825373
            +vn 0.003265 -0.944395 -0.328715
            +vn 0.015168 -0.949339 -0.313852
            +vn 0.058046 -0.947630 -0.314005
            +vn 0.158361 -0.934690 -0.318155
            +vn 0.373943 -0.860958 -0.344798
            +vn 0.726829 -0.553880 -0.406049
            +vn 0.908139 -0.082766 -0.410321
            +vn 0.890500 0.214759 0.401044
            +vn 0.972930 0.231025 0.000000
            +vn 0.836634 0.384075 0.390515
            +vn 0.912503 0.408979 0.000000
            +vn 0.765191 0.530198 0.365123
            +vn 0.828791 0.559496 0.000000
            +vn 0.671041 0.663228 0.331339
            +vn 0.718955 0.695029 0.000000
            +vn 0.549455 0.776238 0.309000
            +vn 0.580859 0.813990 0.000000
            +vn 0.461165 0.821528 0.335215
            +vn 0.497085 0.867672 0.000000
            +vn 0.559679 0.139714 0.816828
            +vn 0.528581 0.255501 0.809473
            +vn 0.494888 0.359783 0.790948
            +vn 0.445143 0.467879 0.763451
            +vn 0.376049 0.559984 0.738212
            +vn 0.287332 0.527940 0.799188
            +vn -0.024537 -0.005737 0.999664
            +vn -0.020844 -0.012207 0.999695
            +vn -0.014466 -0.014466 0.999786
            +vn -0.009796 -0.013276 0.999847
            +vn -0.014771 -0.013886 0.999786
            +vn -0.101779 -0.196661 0.975158
            +vn -0.585437 -0.154668 0.795801
            +vn -0.538499 -0.291696 0.790490
            +vn -0.487228 -0.408918 0.771599
            +vn -0.428327 -0.511948 0.744560
            +vn -0.360820 -0.584735 0.726524
            +vn -0.357311 -0.691549 0.627735
            +vn -0.889126 -0.238868 0.390332
            +vn -0.807001 -0.448500 0.384075
            +vn -0.700980 -0.613392 0.363750
            +vn -0.590442 -0.733757 0.336009
            +vn -0.486190 -0.814966 0.315256
            +vn -0.440138 -0.855586 0.272439
            +vn -0.965453 -0.260506 0.000000
            +vn -0.872097 -0.489273 0.000000
            +vn -0.748253 -0.663381 0.000000
            +vn -0.621784 -0.783166 0.000000
            +vn -0.507614 -0.861568 0.000000
            +vn -0.456954 -0.889462 0.000000
            +vn -0.889126 -0.238868 -0.390332
            +vn -0.807001 -0.448531 -0.384075
            +vn -0.700980 -0.613392 -0.363750
            +vn -0.590442 -0.733757 -0.336009
            +vn -0.486190 -0.814966 -0.315256
            +vn -0.440138 -0.855586 -0.272439
            +vn -0.585437 -0.154668 -0.795801
            +vn -0.538499 -0.291696 -0.790490
            +vn -0.487228 -0.408918 -0.771599
            +vn -0.428327 -0.511948 -0.744560
            +vn -0.360820 -0.584735 -0.726524
            +vn -0.357311 -0.691549 -0.627705
            +vn -0.024537 -0.005737 -0.999664
            +vn -0.020844 -0.012238 -0.999695
            +vn -0.014466 -0.014466 -0.999786
            +vn -0.009766 -0.013276 -0.999847
            +vn -0.014771 -0.013916 -0.999786
            +vn -0.101779 -0.196661 -0.975158
            +vn 0.559679 0.139714 -0.816828
            +vn 0.528581 0.255501 -0.809473
            +vn 0.494888 0.359783 -0.790948
            +vn 0.445143 0.467879 -0.763451
            +vn 0.376049 0.559984 -0.738212
            +vn 0.287332 0.527940 -0.799188
            +vn 0.890500 0.214759 -0.401044
            +vn 0.836634 0.384075 -0.390515
            +vn 0.765191 0.530198 -0.365123
            +vn 0.671041 0.663228 -0.331339
            +vn 0.549455 0.776238 -0.309000
            +vn 0.461165 0.821528 -0.335215
            +vn -0.149937 0.988678 0.000000
            +vn -0.137028 0.872402 0.469131
            +vn -0.297769 0.840358 0.452895
            +vn -0.350505 0.936552 0.000000
            +vn -0.617512 0.663961 0.421613
            +vn -0.715506 0.698569 0.000000
            +vn -0.801324 0.450209 0.393872
            +vn -0.900845 0.434065 0.000000
            +vn -0.828028 0.379803 0.412397
            +vn -0.929289 0.369274 0.000000
            +vn -0.729179 0.503464 0.463393
            +vn -0.857875 0.513810 0.000000
            +vn -0.663076 0.748527 0.000000
            +vn -0.531449 0.686514 0.496170
            +vn -0.066713 0.491440 0.868313
            +vn -0.117893 0.503159 0.856105
            +vn -0.254341 0.474349 0.842769
            +vn -0.411115 0.399182 0.819483
            +vn -0.459395 0.346446 0.817835
            +vn -0.385876 0.395734 0.833338
            +vn -0.270669 0.487838 0.829890
            +vn 0.062716 -0.043458 0.997070
            +vn 0.135929 -0.002472 0.990692
            +vn 0.247963 0.095187 0.964049
            +vn 0.209296 0.170660 0.962828
            +vn 0.096194 0.178625 0.979186
            +vn 0.009552 0.154332 0.987945
            +vn -0.000122 0.151952 0.988372
            +vn 0.202582 -0.542894 0.814966
            +vn 0.360088 -0.479232 0.800378
            +vn 0.611988 -0.282235 0.738762
            +vn 0.679220 -0.106754 0.726096
            +vn 0.583911 -0.078524 0.807978
            +vn 0.402722 -0.205237 0.891995
            +vn 0.279519 -0.338694 0.898404
            +vn 0.294107 -0.855037 0.427015
            +vn 0.488418 -0.768700 0.412915
            +vn 0.784570 -0.501511 0.364544
            +vn 0.893918 -0.279611 0.350291
            +vn 0.861415 -0.285287 0.420179
            +vn 0.679373 -0.540422 0.496323
            +vn 0.458357 -0.754540 0.469588
            +vn 0.320780 -0.947142 0.000000
            +vn 0.525101 -0.851009 0.000000
            +vn 0.827570 -0.561327 0.000000
            +vn 0.943419 -0.331523 0.000000
            +vn 0.933561 -0.358409 0.000000
            +vn 0.756340 -0.654134 0.000000
            +vn 0.491928 -0.870602 0.000092
            +vn 0.294107 -0.855037 -0.427015
            +vn 0.488418 -0.768700 -0.412915
            +vn 0.784570 -0.501511 -0.364544
            +vn 0.893918 -0.279611 -0.350291
            +vn 0.861385 -0.285287 -0.420179
            +vn 0.679373 -0.540422 -0.496323
            +vn 0.457839 -0.755608 -0.468368
            +vn 0.202582 -0.542894 -0.814966
            +vn 0.360088 -0.479232 -0.800378
            +vn 0.611988 -0.282235 -0.738762
            +vn 0.679220 -0.106754 -0.726096
            +vn 0.583911 -0.078524 -0.807978
            +vn 0.402722 -0.205237 -0.891995
            +vn 0.279153 -0.342235 -0.897153
            +vn 0.062716 -0.043458 -0.997070
            +vn 0.135929 -0.002472 -0.990692
            +vn 0.247963 0.095187 -0.964049
            +vn 0.209296 0.170629 -0.962828
            +vn 0.096194 0.178625 -0.979186
            +vn 0.009552 0.154332 -0.987945
            +vn -0.000458 0.149358 -0.988769
            +vn -0.066713 0.491440 -0.868313
            +vn -0.117893 0.503159 -0.856105
            +vn -0.254341 0.474319 -0.842769
            +vn -0.411115 0.399182 -0.819514
            +vn -0.459395 0.346446 -0.817835
            +vn -0.385876 0.395734 -0.833338
            +vn -0.271035 0.487136 -0.830164
            +vn -0.137028 0.872402 -0.469131
            +vn -0.297769 0.840358 -0.452895
            +vn -0.617512 0.663961 -0.421613
            +vn -0.801324 0.450209 -0.393872
            +vn -0.828028 0.379803 -0.412397
            +vn -0.729209 0.503464 -0.463393
            +vn -0.531541 0.686453 -0.496200
            +vn -0.480697 0.876858 0.000000
            +vn -0.394635 0.815363 0.423536
            +vn -0.320750 0.947142 0.000092
            +vn -0.255287 0.921964 0.291086
            +vn 0.002686 0.999969 -0.000732
            +vn -0.007172 0.999939 -0.007599
            +vn 0.366832 0.704398 -0.607624
            +vn 0.853236 0.521226 -0.016388
            +vn 0.567492 -0.154088 -0.808802
            +vn 0.803766 -0.594409 -0.024964
            +vn 0.580920 -0.584490 -0.566424
            +vn 0.673757 -0.738639 -0.020966
            +vn -0.206824 0.638203 0.741539
            +vn -0.129490 0.862056 0.489944
            +vn -0.034486 0.999023 0.026704
            +vn 0.041597 0.871334 -0.488876
            +vn 0.103488 0.553880 -0.826136
            +vn 0.189642 0.174200 -0.966247
            +vn 0.020112 0.322611 0.946287
            +vn 0.021943 0.748894 0.662282
            +vn -0.025697 0.995392 0.092166
            +vn -0.056551 0.931608 -0.358989
            +vn -0.070711 0.782006 -0.619190
            +vn -0.066408 0.651509 -0.755699
            +vn 0.281747 -0.174993 0.943388
            +vn 0.303903 0.444136 0.842830
            +vn 0.035279 0.983856 0.175329
            +vn -0.109928 0.953551 -0.280435
            +vn -0.149571 0.847682 -0.508927
            +vn -0.145634 0.777520 -0.611744
            +vn 0.467238 -0.683218 0.561144
            +vn 0.699515 0.004364 0.714560
            +vn 0.354900 0.892758 0.277444
            +vn -0.174383 0.969054 -0.174596
            +vn -0.252998 0.894314 -0.368938
            +vn -0.191443 0.807947 -0.557237
            +vn 0.495346 -0.868679 0.001587
            +vn 0.933897 -0.357311 0.011017
            +vn 0.704215 0.709830 0.013337
            +vn -0.205634 0.978576 -0.006623
            +vn -0.322367 0.945708 -0.041169
            +vn -0.314951 0.916288 -0.247322
            +vn 0.459120 -0.703757 -0.542100
            +vn 0.693655 -0.096530 -0.713767
            +vn 0.408673 0.848415 -0.336344
            +vn -0.198248 0.963439 0.180151
            +vn -0.306833 0.888516 0.341075
            +vn -0.335978 0.808863 0.482498
            +vn 0.277047 -0.215796 -0.936277
            +vn 0.306192 0.349864 -0.885311
            +vn 0.056246 0.971099 -0.231819
            +vn -0.146733 0.912168 0.382611
            +vn -0.202612 0.700797 0.683950
            +vn -0.159368 0.444777 0.881314
            +vn 0.016907 0.300088 -0.953734
            +vn 0.019349 0.701865 -0.712027
            +vn -0.023713 0.995361 -0.093081
            +vn -0.047395 0.829371 0.556658
            +vn -0.015259 0.386608 0.922086
            +vn 0.080721 0.001404 0.996704
            +vn -0.209967 0.632160 -0.745811
            +vn -0.137394 0.849117 -0.509995
            +vn -0.023438 0.999695 -0.004883
            +vn 0.120426 0.724540 0.678579
            +vn 0.260750 0.006531 0.965361
            +vn 0.341502 -0.385510 0.857143
            +vn -0.395489 0.814814 -0.423841
            +vn -0.257942 0.920621 -0.293039
            +vn 0.005005 0.999908 0.011628
            +vn 0.466628 0.599811 0.649983
            +vn 0.621937 -0.400861 0.672628
            +vn 0.584826 -0.661397 0.469558
            +vn 0.363842 0.931455 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.351451 0.931516 0.093509
            +vn 0.314432 0.931791 0.181280
            +vn 0.256386 0.931913 0.256386
            +vn 0.181280 0.931791 0.314432
            +vn 0.093509 0.931516 0.351451
            +vn 0.000000 0.931455 0.363842
            +vn -0.093509 0.931516 0.351451
            +vn -0.181280 0.931791 0.314432
            +vn -0.256386 0.931913 0.256386
            +vn -0.314432 0.931791 0.181280
            +vn -0.351451 0.931516 0.093509
            +vn -0.363842 0.931455 0.000000
            +vn -0.351451 0.931516 -0.093509
            +vn -0.314432 0.931791 -0.181280
            +vn -0.256417 0.931913 -0.256417
            +vn -0.181280 0.931791 -0.314432
            +vn -0.093509 0.931516 -0.351451
            +vn 0.000000 0.931455 -0.363842
            +vn 0.093509 0.931516 -0.351451
            +vn 0.181280 0.931791 -0.314432
            +vn 0.256417 0.931913 -0.256417
            +vn 0.314432 0.931791 -0.181280
            +vn 0.351451 0.931516 -0.093509
            +vn 0.935423 0.249763 0.250160
            +vn 0.968261 0.249916 0.000000
            +vn 0.813959 -0.538713 0.217322
            +vn 0.842860 -0.538102 0.000000
            +vn 0.759484 -0.618030 0.202887
            +vn 0.786767 -0.617206 0.000000
            +vn 0.801569 -0.558184 0.214148
            +vn 0.830195 -0.557421 0.000000
            +vn 0.838404 0.249825 0.484359
            +vn 0.729026 -0.539720 0.420881
            +vn 0.680013 -0.619098 0.392712
            +vn 0.717765 -0.559343 0.414594
            +vn 0.684652 0.249886 0.684652
            +vn 0.595050 -0.540147 0.595050
            +vn 0.555040 -0.619526 0.555040
            +vn 0.585894 -0.559862 0.585894
            +vn 0.484359 0.249825 0.838404
            +vn 0.420881 -0.539720 0.729026
            +vn 0.392712 -0.619098 0.680013
            +vn 0.414594 -0.559343 0.717765
            +vn 0.250160 0.249763 0.935423
            +vn 0.217322 -0.538713 0.813959
            +vn 0.202887 -0.618030 0.759514
            +vn 0.214148 -0.558184 0.801569
            +vn 0.000000 0.249916 0.968261
            +vn 0.000000 -0.538102 0.842860
            +vn 0.000000 -0.617206 0.786767
            +vn 0.000000 -0.557421 0.830195
            +vn -0.250160 0.249763 0.935423
            +vn -0.217322 -0.538713 0.813959
            +vn -0.202887 -0.618030 0.759514
            +vn -0.214148 -0.558184 0.801569
            +vn -0.484359 0.249825 0.838404
            +vn -0.420881 -0.539720 0.729026
            +vn -0.392712 -0.619098 0.680013
            +vn -0.414594 -0.559343 0.717765
            +vn -0.684652 0.249886 0.684652
            +vn -0.595050 -0.540147 0.595050
            +vn -0.555040 -0.619526 0.555040
            +vn -0.585894 -0.559862 0.585894
            +vn -0.838404 0.249825 0.484359
            +vn -0.729026 -0.539720 0.420881
            +vn -0.680013 -0.619098 0.392712
            +vn -0.717765 -0.559343 0.414594
            +vn -0.935423 0.249763 0.250160
            +vn -0.813959 -0.538713 0.217322
            +vn -0.759484 -0.618030 0.202887
            +vn -0.801569 -0.558184 0.214148
            +vn -0.968261 0.249916 0.000000
            +vn -0.842860 -0.538102 0.000000
            +vn -0.786767 -0.617206 0.000000
            +vn -0.830195 -0.557421 0.000000
            +vn -0.935423 0.249763 -0.250160
            +vn -0.813959 -0.538713 -0.217322
            +vn -0.759484 -0.618030 -0.202887
            +vn -0.801569 -0.558184 -0.214148
            +vn -0.838404 0.249825 -0.484359
            +vn -0.729026 -0.539720 -0.420881
            +vn -0.680013 -0.619098 -0.392712
            +vn -0.717765 -0.559343 -0.414594
            +vn -0.684652 0.249886 -0.684652
            +vn -0.595050 -0.540147 -0.595050
            +vn -0.555040 -0.619526 -0.555040
            +vn -0.585864 -0.559862 -0.585894
            +vn -0.484359 0.249825 -0.838404
            +vn -0.420881 -0.539720 -0.729026
            +vn -0.392712 -0.619098 -0.680013
            +vn -0.414594 -0.559343 -0.717765
            +vn -0.250160 0.249763 -0.935423
            +vn -0.217322 -0.538713 -0.813959
            +vn -0.202887 -0.618030 -0.759484
            +vn -0.214148 -0.558214 -0.801569
            +vn 0.000000 0.249916 -0.968261
            +vn 0.000000 -0.538102 -0.842860
            +vn 0.000000 -0.617206 -0.786767
            +vn 0.000000 -0.557421 -0.830195
            +vn 0.250160 0.249763 -0.935423
            +vn 0.217322 -0.538713 -0.813959
            +vn 0.202887 -0.618030 -0.759484
            +vn 0.214148 -0.558214 -0.801569
            +vn 0.484359 0.249825 -0.838404
            +vn 0.420881 -0.539720 -0.729026
            +vn 0.392712 -0.619098 -0.680013
            +vn 0.414594 -0.559343 -0.717765
            +vn 0.684652 0.249886 -0.684652
            +vn 0.595050 -0.540147 -0.595050
            +vn 0.555040 -0.619526 -0.555040
            +vn 0.585864 -0.559862 -0.585894
            +vn 0.838404 0.249825 -0.484359
            +vn 0.729026 -0.539720 -0.420881
            +vn 0.680013 -0.619098 -0.392712
            +vn 0.717765 -0.559343 -0.414594
            +vn 0.935423 0.249763 -0.250160
            +vn 0.813959 -0.538713 -0.217322
            +vn 0.759484 -0.618030 -0.202887
            +vn 0.801569 -0.558184 -0.214148
            +s 1
            +f 1//1 2//2 3//3
            +f 3//3 2//2 4//4
            +f 4//4 2//2 5//5
            +f 5//5 2//2 6//6
            +f 6//6 2//2 7//7
            +f 7//7 2//2 8//8
            +f 8//8 2//2 9//9
            +f 9//9 2//2 10//10
            +f 10//10 2//2 11//11
            +f 11//11 2//2 12//12
            +f 12//12 2//2 13//13
            +f 13//13 2//2 14//14
            +f 14//14 2//2 15//15
            +f 15//15 2//2 16//16
            +f 16//16 2//2 17//17
            +f 17//17 2//2 18//18
            +f 18//18 2//2 19//19
            +f 19//19 2//2 20//20
            +f 20//20 2//2 21//21
            +f 21//21 2//2 22//22
            +f 22//22 2//2 23//23
            +f 23//23 2//2 24//24
            +f 24//24 2//2 25//25
            +f 2//2 1//1 25//25
            +f 26//26 27//27 28//28
            +f 28//28 29//29 26//26
            +f 29//29 28//28 30//30
            +f 31//31 30//30 28//28
            +f 30//30 31//31 32//32
            +f 33//33 32//32 31//31
            +f 34//34 35//35 33//33
            +f 32//32 33//33 35//35
            +f 36//36 37//37 34//34
            +f 35//35 34//34 37//37
            +f 38//38 39//39 36//36
            +f 37//37 36//36 39//39
            +f 27//27 40//40 41//41
            +f 41//41 28//28 27//27
            +f 28//28 41//41 31//31
            +f 42//42 31//31 41//41
            +f 31//31 42//42 33//33
            +f 43//43 33//33 42//42
            +f 44//44 34//34 43//43
            +f 33//33 43//43 34//34
            +f 45//45 36//36 44//44
            +f 34//34 44//44 36//36
            +f 46//46 38//38 45//45
            +f 36//36 45//45 38//38
            +f 40//40 47//47 48//48
            +f 48//48 41//41 40//40
            +f 41//41 48//48 42//42
            +f 49//49 42//42 48//48
            +f 42//42 49//49 43//43
            +f 50//50 43//43 49//49
            +f 51//51 44//44 50//50
            +f 43//43 50//50 44//44
            +f 52//52 45//45 51//51
            +f 44//44 51//51 45//45
            +f 53//53 46//46 52//52
            +f 45//45 52//52 46//46
            +f 47//47 54//54 48//48
            +f 55//55 48//48 54//54
            +f 48//48 55//55 49//49
            +f 56//56 49//49 55//55
            +f 49//49 56//56 57//57
            +f 57//57 50//50 49//49
            +f 58//58 51//51 50//50
            +f 50//50 57//57 58//58
            +f 59//59 52//52 51//51
            +f 51//51 58//58 59//59
            +f 60//60 53//53 52//52
            +f 52//52 59//59 60//60
            +f 54//54 61//61 55//55
            +f 62//62 55//55 61//61
            +f 55//55 62//62 63//63
            +f 63//63 56//56 55//55
            +f 56//56 63//63 64//64
            +f 64//64 57//57 56//56
            +f 65//65 58//58 57//57
            +f 57//57 64//64 65//65
            +f 66//66 59//59 58//58
            +f 58//58 65//65 66//66
            +f 67//67 60//60 59//59
            +f 59//59 66//66 67//67
            +f 61//61 68//68 62//62
            +f 69//69 62//62 68//68
            +f 62//62 69//69 70//70
            +f 70//70 63//63 62//62
            +f 63//63 70//70 71//71
            +f 71//71 64//64 63//63
            +f 72//72 65//65 64//64
            +f 64//64 71//71 72//72
            +f 73//73 66//66 65//65
            +f 65//65 72//72 73//73
            +f 74//74 67//67 66//66
            +f 66//66 73//73 74//74
            +f 68//68 75//75 76//76
            +f 76//76 69//69 68//68
            +f 69//69 76//76 70//70
            +f 77//77 70//70 76//76
            +f 70//70 77//77 71//71
            +f 78//78 71//71 77//77
            +f 79//79 72//72 78//78
            +f 71//71 78//78 72//72
            +f 80//80 73//73 79//79
            +f 72//72 79//79 73//73
            +f 81//81 74//74 80//80
            +f 73//73 80//80 74//74
            +f 75//75 82//82 83//83
            +f 83//83 76//76 75//75
            +f 76//76 83//83 77//77
            +f 84//84 77//77 83//83
            +f 77//77 84//84 78//78
            +f 85//85 78//78 84//84
            +f 86//86 79//79 85//85
            +f 78//78 85//85 79//79
            +f 87//87 80//80 86//86
            +f 79//79 86//86 80//80
            +f 88//88 81//81 87//87
            +f 80//80 87//87 81//81
            +f 82//82 89//89 90//90
            +f 90//90 83//83 82//82
            +f 83//83 90//90 91//91
            +f 91//91 84//84 83//83
            +f 84//84 91//91 85//85
            +f 92//92 85//85 91//91
            +f 93//93 86//86 92//92
            +f 85//85 92//92 86//86
            +f 94//94 87//87 93//93
            +f 86//86 93//93 87//87
            +f 95//95 88//88 94//94
            +f 87//87 94//94 88//88
            +f 89//89 96//96 90//90
            +f 97//97 90//90 96//96
            +f 90//90 97//97 98//98
            +f 98//98 91//91 90//90
            +f 91//91 98//98 99//99
            +f 99//99 92//92 91//91
            +f 100//100 93//93 92//92
            +f 92//92 99//99 100//100
            +f 101//101 94//94 93//93
            +f 93//93 100//100 101//101
            +f 102//102 95//95 94//94
            +f 94//94 101//101 102//102
            +f 96//96 103//103 97//97
            +f 104//104 97//97 103//103
            +f 97//97 104//104 105//105
            +f 105//105 98//98 97//97
            +f 98//98 105//105 106//106
            +f 106//106 99//99 98//98
            +f 107//107 100//100 99//99
            +f 99//99 106//106 107//107
            +f 108//108 101//101 100//100
            +f 100//100 107//107 108//108
            +f 109//109 102//102 101//101
            +f 101//101 108//108 109//109
            +f 103//103 110//110 104//104
            +f 111//111 104//104 110//110
            +f 104//104 111//111 112//112
            +f 112//112 105//105 104//104
            +f 105//105 112//112 113//113
            +f 113//113 106//106 105//105
            +f 114//114 107//107 106//106
            +f 106//106 113//113 114//114
            +f 115//115 108//108 107//107
            +f 107//107 114//114 115//115
            +f 116//116 109//109 108//108
            +f 108//108 115//115 116//116
            +f 110//110 117//117 118//118
            +f 118//118 111//111 110//110
            +f 111//111 118//118 119//119
            +f 119//119 112//112 111//111
            +f 112//112 119//119 113//113
            +f 120//120 113//113 119//119
            +f 121//121 114//114 120//120
            +f 113//113 120//120 114//114
            +f 122//122 115//115 121//121
            +f 114//114 121//121 115//115
            +f 123//123 116//116 122//122
            +f 115//115 122//122 116//116
            +f 117//117 124//124 125//125
            +f 125//125 118//118 117//117
            +f 118//118 125//125 119//119
            +f 126//126 119//119 125//125
            +f 119//119 126//126 120//120
            +f 127//127 120//120 126//126
            +f 128//128 121//121 127//127
            +f 120//120 127//127 121//121
            +f 129//129 122//122 128//128
            +f 121//121 128//128 122//122
            +f 130//130 123//123 129//129
            +f 122//122 129//129 123//123
            +f 124//124 131//131 132//132
            +f 132//132 125//125 124//124
            +f 125//125 132//132 133//133
            +f 133//133 126//126 125//125
            +f 126//126 133//133 127//127
            +f 134//134 127//127 133//133
            +f 135//135 128//128 134//134
            +f 127//127 134//134 128//128
            +f 136//136 129//129 135//135
            +f 128//128 135//135 129//129
            +f 137//137 130//130 136//136
            +f 129//129 136//136 130//130
            +f 131//131 138//138 132//132
            +f 139//139 132//132 138//138
            +f 132//132 139//139 140//140
            +f 140//140 133//133 132//132
            +f 133//133 140//140 141//141
            +f 141//141 134//134 133//133
            +f 142//142 135//135 134//134
            +f 134//134 141//141 142//142
            +f 143//143 136//136 135//135
            +f 135//135 142//142 143//143
            +f 144//144 137//137 136//136
            +f 136//136 143//143 144//144
            +f 138//138 145//145 139//139
            +f 146//146 139//139 145//145
            +f 139//139 146//146 147//147
            +f 147//147 140//140 139//139
            +f 140//140 147//147 148//148
            +f 148//148 141//141 140//140
            +f 149//149 142//142 141//141
            +f 141//141 148//148 149//149
            +f 150//150 143//143 142//142
            +f 142//142 149//149 150//150
            +f 151//151 144//144 143//143
            +f 143//143 150//150 151//151
            +f 145//145 152//152 146//146
            +f 153//153 146//146 152//152
            +f 146//146 153//153 154//154
            +f 154//154 147//147 146//146
            +f 147//147 154//154 155//155
            +f 155//155 148//148 147//147
            +f 156//156 149//149 148//148
            +f 148//148 155//155 156//156
            +f 157//157 150//150 149//149
            +f 149//149 156//156 157//157
            +f 158//158 151//151 150//150
            +f 150//150 157//157 158//158
            +f 152//152 159//159 160//160
            +f 160//160 153//153 152//152
            +f 153//153 160//160 154//154
            +f 161//161 154//154 160//160
            +f 154//154 161//161 155//155
            +f 162//162 155//155 161//161
            +f 163//163 156//156 162//162
            +f 155//155 162//162 156//156
            +f 164//164 157//157 163//163
            +f 156//156 163//163 157//157
            +f 165//165 158//158 164//164
            +f 157//157 164//164 158//158
            +f 159//159 166//166 167//167
            +f 167//167 160//160 159//159
            +f 160//160 167//167 161//161
            +f 168//168 161//161 167//167
            +f 161//161 168//168 162//162
            +f 169//169 162//162 168//168
            +f 170//170 163//163 169//169
            +f 162//162 169//169 163//163
            +f 171//171 164//164 170//170
            +f 163//163 170//170 164//164
            +f 172//172 165//165 171//171
            +f 164//164 171//171 165//165
            +f 166//166 173//173 174//174
            +f 174//174 167//167 166//166
            +f 167//167 174//174 168//168
            +f 175//175 168//168 174//174
            +f 168//168 175//175 169//169
            +f 176//176 169//169 175//175
            +f 177//177 170//170 176//176
            +f 169//169 176//176 170//170
            +f 178//178 171//171 177//177
            +f 170//170 177//177 171//171
            +f 179//179 172//172 178//178
            +f 171//171 178//178 172//172
            +f 173//173 180//180 174//174
            +f 181//181 174//174 180//180
            +f 174//174 181//181 175//175
            +f 182//182 175//175 181//181
            +f 175//175 182//182 183//183
            +f 183//183 176//176 175//175
            +f 184//184 177//177 176//176
            +f 176//176 183//183 184//184
            +f 185//185 178//178 177//177
            +f 177//177 184//184 185//185
            +f 186//186 179//179 178//178
            +f 178//178 185//185 186//186
            +f 180//180 187//187 181//181
            +f 188//188 181//181 187//187
            +f 181//181 188//188 189//189
            +f 189//189 182//182 181//181
            +f 182//182 189//189 190//190
            +f 190//190 183//183 182//182
            +f 191//191 184//184 183//183
            +f 183//183 190//190 191//191
            +f 192//192 185//185 184//184
            +f 184//184 191//191 192//192
            +f 193//193 186//186 185//185
            +f 185//185 192//192 193//193
            +f 187//187 26//26 188//188
            +f 29//29 188//188 26//26
            +f 188//188 29//29 189//189
            +f 30//30 189//189 29//29
            +f 189//189 30//30 32//32
            +f 32//32 190//190 189//189
            +f 35//35 191//191 190//190
            +f 190//190 32//32 35//35
            +f 37//37 192//192 191//191
            +f 191//191 35//35 37//37
            +f 39//39 193//193 192//192
            +f 192//192 37//37 39//39
            +f 194//194 195//195 38//38
            +f 39//39 38//38 195//195
            +f 196//196 197//197 194//194
            +f 195//195 194//194 197//197
            +f 198//198 199//199 196//196
            +f 197//197 196//196 199//199
            +f 200//200 201//201 198//198
            +f 199//199 198//198 201//201
            +f 202//202 203//203 200//200
            +f 201//201 200//200 203//203
            +f 204//204 205//205 202//202
            +f 203//203 202//202 205//205
            +f 206//206 194//194 46//46
            +f 38//38 46//46 194//194
            +f 207//207 196//196 206//206
            +f 194//194 206//206 196//196
            +f 208//208 198//198 207//207
            +f 196//196 207//207 198//198
            +f 209//209 200//200 208//208
            +f 198//198 208//208 200//200
            +f 210//210 202//202 209//209
            +f 200//200 209//209 202//202
            +f 211//211 204//204 210//210
            +f 202//202 210//210 204//204
            +f 212//212 206//206 53//53
            +f 46//46 53//53 206//206
            +f 213//213 207//207 212//212
            +f 206//206 212//212 207//207
            +f 214//214 208//208 213//213
            +f 207//207 213//213 208//208
            +f 215//215 209//209 214//214
            +f 208//208 214//214 209//209
            +f 216//216 210//210 215//215
            +f 209//209 215//215 210//210
            +f 217//217 211//211 216//216
            +f 210//210 216//216 211//211
            +f 218//218 212//212 53//53
            +f 53//53 60//60 218//218
            +f 219//219 213//213 212//212
            +f 212//212 218//218 219//219
            +f 220//220 214//214 213//213
            +f 213//213 219//219 220//220
            +f 221//221 215//215 214//214
            +f 214//214 220//220 221//221
            +f 222//222 216//216 215//215
            +f 215//215 221//221 222//222
            +f 223//223 217//217 216//216
            +f 216//216 222//222 223//223
            +f 224//224 218//218 60//60
            +f 60//60 67//67 224//224
            +f 225//225 219//219 218//218
            +f 218//218 224//224 225//225
            +f 226//226 220//220 219//219
            +f 219//219 225//225 226//226
            +f 227//227 221//221 220//220
            +f 220//220 226//226 227//227
            +f 228//228 222//222 221//221
            +f 221//221 227//227 228//228
            +f 229//229 223//223 222//222
            +f 222//222 228//228 229//229
            +f 230//230 224//224 67//67
            +f 67//67 74//74 230//230
            +f 231//231 225//225 224//224
            +f 224//224 230//230 231//231
            +f 232//232 226//226 225//225
            +f 225//225 231//231 232//232
            +f 233//233 227//227 226//226
            +f 226//226 232//232 233//233
            +f 234//234 228//228 227//227
            +f 227//227 233//233 234//234
            +f 235//235 229//229 228//228
            +f 228//228 234//234 235//235
            +f 236//236 230//230 81//81
            +f 74//74 81//81 230//230
            +f 237//237 231//231 236//236
            +f 230//230 236//236 231//231
            +f 238//238 232//232 237//237
            +f 231//231 237//237 232//232
            +f 239//239 233//233 238//238
            +f 232//232 238//238 233//233
            +f 240//240 234//234 239//239
            +f 233//233 239//239 234//234
            +f 241//241 235//235 240//240
            +f 234//234 240//240 235//235
            +f 242//242 236//236 88//88
            +f 81//81 88//88 236//236
            +f 243//243 237//237 242//242
            +f 236//236 242//242 237//237
            +f 244//244 238//238 243//243
            +f 237//237 243//243 238//238
            +f 245//245 239//239 244//244
            +f 238//238 244//244 239//239
            +f 246//246 240//240 245//245
            +f 239//239 245//245 240//240
            +f 247//247 241//241 246//246
            +f 240//240 246//246 241//241
            +f 248//248 242//242 95//95
            +f 88//88 95//95 242//242
            +f 249//249 243//243 248//248
            +f 242//242 248//248 243//243
            +f 250//250 244//244 249//249
            +f 243//243 249//249 244//244
            +f 251//251 245//245 250//250
            +f 244//244 250//250 245//245
            +f 252//252 246//246 251//251
            +f 245//245 251//251 246//246
            +f 253//253 247//247 252//252
            +f 246//246 252//252 247//247
            +f 254//254 248//248 95//95
            +f 95//95 102//102 254//254
            +f 255//255 249//249 248//248
            +f 248//248 254//254 255//255
            +f 256//256 250//250 249//249
            +f 249//249 255//255 256//256
            +f 257//257 251//251 250//250
            +f 250//250 256//256 257//257
            +f 258//258 252//252 251//251
            +f 251//251 257//257 258//258
            +f 259//259 253//253 252//252
            +f 252//252 258//258 259//259
            +f 260//260 254//254 102//102
            +f 102//102 109//109 260//260
            +f 261//261 255//255 254//254
            +f 254//254 260//260 261//261
            +f 262//262 256//256 255//255
            +f 255//255 261//261 262//262
            +f 263//263 257//257 256//256
            +f 256//256 262//262 263//263
            +f 264//264 258//258 257//257
            +f 257//257 263//263 264//264
            +f 265//265 259//259 258//258
            +f 258//258 264//264 265//265
            +f 266//266 260//260 109//109
            +f 109//109 116//116 266//266
            +f 267//267 261//261 260//260
            +f 260//260 266//266 267//267
            +f 268//268 262//262 261//261
            +f 261//261 267//267 268//268
            +f 269//269 263//263 262//262
            +f 262//262 268//268 269//269
            +f 270//270 264//264 263//263
            +f 263//263 269//269 270//270
            +f 271//271 265//265 264//264
            +f 264//264 270//270 271//271
            +f 272//272 266//266 123//123
            +f 116//116 123//123 266//266
            +f 273//273 267//267 272//272
            +f 266//266 272//272 267//267
            +f 274//274 268//268 273//273
            +f 267//267 273//273 268//268
            +f 275//275 269//269 274//274
            +f 268//268 274//274 269//269
            +f 276//276 270//270 275//275
            +f 269//269 275//275 270//270
            +f 277//277 271//271 276//276
            +f 270//270 276//276 271//271
            +f 278//278 272//272 130//130
            +f 123//123 130//130 272//272
            +f 279//279 273//273 278//278
            +f 272//272 278//278 273//273
            +f 280//280 274//274 279//279
            +f 273//273 279//279 274//274
            +f 281//281 275//275 280//280
            +f 274//274 280//280 275//275
            +f 282//282 276//276 281//281
            +f 275//275 281//281 276//276
            +f 283//283 277//277 282//282
            +f 276//276 282//282 277//277
            +f 284//284 278//278 137//137
            +f 130//130 137//137 278//278
            +f 285//285 279//279 284//284
            +f 278//278 284//284 279//279
            +f 286//286 280//280 285//285
            +f 279//279 285//285 280//280
            +f 287//287 281//281 286//286
            +f 280//280 286//286 281//281
            +f 288//288 282//282 287//287
            +f 281//281 287//287 282//282
            +f 289//289 283//283 288//288
            +f 282//282 288//288 283//283
            +f 290//290 284//284 137//137
            +f 137//137 144//144 290//290
            +f 291//291 285//285 284//284
            +f 284//284 290//290 291//291
            +f 292//292 286//286 285//285
            +f 285//285 291//291 292//292
            +f 293//293 287//287 286//286
            +f 286//286 292//292 293//293
            +f 294//294 288//288 287//287
            +f 287//287 293//293 294//294
            +f 295//295 289//289 288//288
            +f 288//288 294//294 295//295
            +f 296//296 290//290 144//144
            +f 144//144 151//151 296//296
            +f 297//297 291//291 290//290
            +f 290//290 296//296 297//297
            +f 298//298 292//292 291//291
            +f 291//291 297//297 298//298
            +f 299//299 293//293 292//292
            +f 292//292 298//298 299//299
            +f 300//300 294//294 293//293
            +f 293//293 299//299 300//300
            +f 301//301 295//295 294//294
            +f 294//294 300//300 301//301
            +f 302//302 296//296 151//151
            +f 151//151 158//158 302//302
            +f 303//303 297//297 296//296
            +f 296//296 302//302 303//303
            +f 304//304 298//298 297//297
            +f 297//297 303//303 304//304
            +f 305//305 299//299 298//298
            +f 298//298 304//304 305//305
            +f 306//306 300//300 299//299
            +f 299//299 305//305 306//306
            +f 307//307 301//301 300//300
            +f 300//300 306//306 307//307
            +f 308//308 302//302 165//165
            +f 158//158 165//165 302//302
            +f 309//309 303//303 308//308
            +f 302//302 308//308 303//303
            +f 310//310 304//304 309//309
            +f 303//303 309//309 304//304
            +f 311//311 305//305 310//310
            +f 304//304 310//310 305//305
            +f 312//312 306//306 311//311
            +f 305//305 311//311 306//306
            +f 313//313 307//307 312//312
            +f 306//306 312//312 307//307
            +f 314//314 308//308 172//172
            +f 165//165 172//172 308//308
            +f 315//315 309//309 314//314
            +f 308//308 314//314 309//309
            +f 316//316 310//310 315//315
            +f 309//309 315//315 310//310
            +f 317//317 311//311 316//316
            +f 310//310 316//316 311//311
            +f 318//318 312//312 317//317
            +f 311//311 317//317 312//312
            +f 319//319 313//313 318//318
            +f 312//312 318//318 313//313
            +f 320//320 314//314 179//179
            +f 172//172 179//179 314//314
            +f 321//321 315//315 320//320
            +f 314//314 320//320 315//315
            +f 322//322 316//316 321//321
            +f 315//315 321//321 316//316
            +f 323//323 317//317 322//322
            +f 316//316 322//322 317//317
            +f 324//324 318//318 323//323
            +f 317//317 323//323 318//318
            +f 325//325 319//319 324//324
            +f 318//318 324//324 319//319
            +f 326//326 320//320 179//179
            +f 179//179 186//186 326//326
            +f 327//327 321//321 320//320
            +f 320//320 326//326 327//327
            +f 328//328 322//322 321//321
            +f 321//321 327//327 328//328
            +f 329//329 323//323 322//322
            +f 322//322 328//328 329//329
            +f 330//330 324//324 323//323
            +f 323//323 329//329 330//330
            +f 331//331 325//325 324//324
            +f 324//324 330//330 331//331
            +f 332//332 326//326 186//186
            +f 186//186 193//193 332//332
            +f 333//333 327//327 326//326
            +f 326//326 332//332 333//333
            +f 334//334 328//328 327//327
            +f 327//327 333//333 334//334
            +f 335//335 329//329 328//328
            +f 328//328 334//334 335//335
            +f 336//336 330//330 329//329
            +f 329//329 335//335 336//336
            +f 337//337 331//331 330//330
            +f 330//330 336//336 337//337
            +f 195//195 332//332 193//193
            +f 193//193 39//39 195//195
            +f 197//197 333//333 332//332
            +f 332//332 195//195 197//197
            +f 199//199 334//334 333//333
            +f 333//333 197//197 199//199
            +f 201//201 335//335 334//334
            +f 334//334 199//199 201//201
            +f 203//203 336//336 335//335
            +f 335//335 201//201 203//203
            +f 205//205 337//337 336//336
            +f 336//336 203//203 205//205
            +f 338//338 339//339 205//205
            +f 205//205 204//204 338//338
            +f 340//340 341//341 339//339
            +f 339//339 338//338 340//340
            +f 342//342 343//343 341//341
            +f 341//341 340//340 342//342
            +f 344//344 345//345 343//343
            +f 343//343 342//342 344//344
            +f 346//346 347//347 345//345
            +f 345//345 344//344 346//346
            +f 348//348 349//349 347//347
            +f 347//347 346//346 348//348
            +f 350//350 338//338 204//204
            +f 204//204 211//211 350//350
            +f 351//351 340//340 338//338
            +f 338//338 350//350 351//351
            +f 352//352 342//342 340//340
            +f 340//340 351//351 352//352
            +f 353//353 344//344 342//342
            +f 342//342 352//352 353//353
            +f 354//354 346//346 344//344
            +f 344//344 353//353 354//354
            +f 355//355 348//348 346//346
            +f 346//346 354//354 355//355
            +f 356//356 350//350 211//211
            +f 211//211 217//217 356//356
            +f 357//357 351//351 350//350
            +f 350//350 356//356 357//357
            +f 358//358 352//352 351//351
            +f 351//351 357//357 358//358
            +f 359//359 353//353 352//352
            +f 352//352 358//358 359//359
            +f 360//360 354//354 353//353
            +f 353//353 359//359 360//360
            +f 361//361 355//355 354//354
            +f 354//354 360//360 361//361
            +f 362//362 356//356 223//223
            +f 217//217 223//223 356//356
            +f 363//363 357//357 362//362
            +f 356//356 362//362 357//357
            +f 364//364 358//358 363//363
            +f 357//357 363//363 358//358
            +f 365//365 359//359 364//364
            +f 358//358 364//364 359//359
            +f 366//366 360//360 365//365
            +f 359//359 365//365 360//360
            +f 367//367 361//361 366//366
            +f 360//360 366//366 361//361
            +f 368//368 362//362 229//229
            +f 223//223 229//229 362//362
            +f 369//369 363//363 368//368
            +f 362//362 368//368 363//363
            +f 370//370 364//364 369//369
            +f 363//363 369//369 364//364
            +f 371//371 365//365 370//370
            +f 364//364 370//370 365//365
            +f 372//372 366//366 371//371
            +f 365//365 371//371 366//366
            +f 373//373 367//367 372//372
            +f 366//366 372//372 367//367
            +f 374//374 368//368 235//235
            +f 229//229 235//235 368//368
            +f 375//375 369//369 374//374
            +f 368//368 374//374 369//369
            +f 376//376 370//370 375//375
            +f 369//369 375//375 370//370
            +f 377//377 371//371 376//376
            +f 370//370 376//376 371//371
            +f 378//378 372//372 377//377
            +f 371//371 377//377 372//372
            +f 379//379 373//373 378//378
            +f 372//372 378//378 373//373
            +f 380//380 374//374 235//235
            +f 235//235 241//241 380//380
            +f 381//381 375//375 374//374
            +f 374//374 380//380 381//381
            +f 382//382 376//376 375//375
            +f 375//375 381//381 382//382
            +f 383//383 377//377 376//376
            +f 376//376 382//382 383//383
            +f 384//384 378//378 377//377
            +f 377//377 383//383 384//384
            +f 385//385 379//379 378//378
            +f 378//378 384//384 385//385
            +f 386//386 380//380 241//241
            +f 241//241 247//247 386//386
            +f 387//387 381//381 380//380
            +f 380//380 386//386 387//387
            +f 388//388 382//382 381//381
            +f 381//381 387//387 388//388
            +f 389//389 383//383 382//382
            +f 382//382 388//388 389//389
            +f 390//390 384//384 383//383
            +f 383//383 389//389 390//390
            +f 391//391 385//385 384//384
            +f 384//384 390//390 391//391
            +f 392//392 386//386 247//247
            +f 247//247 253//253 392//392
            +f 393//393 387//387 386//386
            +f 386//386 392//392 393//393
            +f 394//394 388//388 387//387
            +f 387//387 393//393 394//394
            +f 395//395 389//389 388//388
            +f 388//388 394//394 395//395
            +f 396//396 390//390 389//389
            +f 389//389 395//395 396//396
            +f 397//397 391//391 390//390
            +f 390//390 396//396 397//397
            +f 398//398 392//392 259//259
            +f 253//253 259//259 392//392
            +f 399//399 393//393 398//398
            +f 392//392 398//398 393//393
            +f 400//400 394//394 399//399
            +f 393//393 399//399 394//394
            +f 401//401 395//395 400//400
            +f 394//394 400//400 395//395
            +f 402//402 396//396 401//401
            +f 395//395 401//401 396//396
            +f 403//403 397//397 402//402
            +f 396//396 402//402 397//397
            +f 404//404 398//398 265//265
            +f 259//259 265//265 398//398
            +f 405//405 399//399 404//404
            +f 398//398 404//404 399//399
            +f 406//406 400//400 405//405
            +f 399//399 405//405 400//400
            +f 407//407 401//401 406//406
            +f 400//400 406//406 401//401
            +f 408//408 402//402 407//407
            +f 401//401 407//407 402//402
            +f 409//409 403//403 408//408
            +f 402//402 408//408 403//403
            +f 410//410 404//404 271//271
            +f 265//265 271//271 404//404
            +f 411//411 405//405 410//410
            +f 404//404 410//410 405//405
            +f 412//412 406//406 411//411
            +f 405//405 411//411 406//406
            +f 413//413 407//407 412//412
            +f 406//406 412//412 407//407
            +f 414//414 408//408 413//413
            +f 407//407 413//413 408//408
            +f 415//415 409//409 414//414
            +f 408//408 414//414 409//409
            +f 416//416 410//410 271//271
            +f 271//271 277//277 416//416
            +f 417//417 411//411 410//410
            +f 410//410 416//416 417//417
            +f 418//418 412//412 411//411
            +f 411//411 417//417 418//418
            +f 419//419 413//413 412//412
            +f 412//412 418//418 419//419
            +f 420//420 414//414 413//413
            +f 413//413 419//419 420//420
            +f 421//421 415//415 414//414
            +f 414//414 420//420 421//421
            +f 422//422 416//416 277//277
            +f 277//277 283//283 422//422
            +f 423//423 417//417 416//416
            +f 416//416 422//422 423//423
            +f 424//424 418//418 417//417
            +f 417//417 423//423 424//424
            +f 425//425 419//419 418//418
            +f 418//418 424//424 425//425
            +f 426//426 420//420 419//419
            +f 419//419 425//425 426//426
            +f 427//427 421//421 420//420
            +f 420//420 426//426 427//427
            +f 428//428 422//422 283//283
            +f 283//283 289//289 428//428
            +f 429//429 423//423 422//422
            +f 422//422 428//428 429//429
            +f 430//430 424//424 423//423
            +f 423//423 429//429 430//430
            +f 431//431 425//425 424//424
            +f 424//424 430//430 431//431
            +f 432//432 426//426 425//425
            +f 425//425 431//431 432//432
            +f 433//433 427//427 426//426
            +f 426//426 432//432 433//433
            +f 434//434 428//428 295//295
            +f 289//289 295//295 428//428
            +f 435//435 429//429 434//434
            +f 428//428 434//434 429//429
            +f 436//436 430//430 435//435
            +f 429//429 435//435 430//430
            +f 437//437 431//431 436//436
            +f 430//430 436//436 431//431
            +f 438//438 432//432 437//437
            +f 431//431 437//437 432//432
            +f 439//439 433//433 438//438
            +f 432//432 438//438 433//433
            +f 440//440 434//434 301//301
            +f 295//295 301//301 434//434
            +f 441//441 435//435 440//440
            +f 434//434 440//440 435//435
            +f 442//442 436//436 441//441
            +f 435//435 441//441 436//436
            +f 443//443 437//437 442//442
            +f 436//436 442//442 437//437
            +f 444//444 438//438 443//443
            +f 437//437 443//443 438//438
            +f 445//445 439//439 444//444
            +f 438//438 444//444 439//439
            +f 446//446 440//440 307//307
            +f 301//301 307//307 440//440
            +f 447//447 441//441 446//446
            +f 440//440 446//446 441//441
            +f 448//448 442//442 447//447
            +f 441//441 447//447 442//442
            +f 449//449 443//443 448//448
            +f 442//442 448//448 443//443
            +f 450//450 444//444 449//449
            +f 443//443 449//449 444//444
            +f 451//451 445//445 450//450
            +f 444//444 450//450 445//445
            +f 452//452 446//446 307//307
            +f 307//307 313//313 452//452
            +f 453//453 447//447 446//446
            +f 446//446 452//452 453//453
            +f 454//454 448//448 447//447
            +f 447//447 453//453 454//454
            +f 455//455 449//449 448//448
            +f 448//448 454//454 455//455
            +f 456//456 450//450 449//449
            +f 449//449 455//455 456//456
            +f 457//457 451//451 450//450
            +f 450//450 456//456 457//457
            +f 458//458 452//452 313//313
            +f 313//313 319//319 458//458
            +f 459//459 453//453 452//452
            +f 452//452 458//458 459//459
            +f 460//460 454//454 453//453
            +f 453//453 459//459 460//460
            +f 461//461 455//455 454//454
            +f 454//454 460//460 461//461
            +f 462//462 456//456 455//455
            +f 455//455 461//461 462//462
            +f 463//463 457//457 456//456
            +f 456//456 462//462 463//463
            +f 464//464 458//458 319//319
            +f 319//319 325//325 464//464
            +f 465//465 459//459 458//458
            +f 458//458 464//464 465//465
            +f 466//466 460//460 459//459
            +f 459//459 465//465 466//466
            +f 467//467 461//461 460//460
            +f 460//460 466//466 467//467
            +f 468//468 462//462 461//461
            +f 461//461 467//467 468//468
            +f 469//469 463//463 462//462
            +f 462//462 468//468 469//469
            +f 470//470 464//464 331//331
            +f 325//325 331//331 464//464
            +f 471//471 465//465 470//470
            +f 464//464 470//470 465//465
            +f 472//472 466//466 471//471
            +f 465//465 471//471 466//466
            +f 473//473 467//467 472//472
            +f 466//466 472//472 467//467
            +f 474//474 468//468 473//473
            +f 467//467 473//473 468//468
            +f 475//475 469//469 474//474
            +f 468//468 474//474 469//469
            +f 476//476 470//470 337//337
            +f 331//331 337//337 470//470
            +f 477//477 471//471 476//476
            +f 470//470 476//476 471//471
            +f 478//478 472//472 477//477
            +f 471//471 477//477 472//472
            +f 479//479 473//473 478//478
            +f 472//472 478//478 473//473
            +f 480//480 474//474 479//479
            +f 473//473 479//479 474//474
            +f 481//481 475//475 480//480
            +f 474//474 480//480 475//475
            +f 339//339 476//476 205//205
            +f 337//337 205//205 476//476
            +f 341//341 477//477 339//339
            +f 476//476 339//339 477//477
            +f 343//343 478//478 341//341
            +f 477//477 341//341 478//478
            +f 345//345 479//479 343//343
            +f 478//478 343//343 479//479
            +f 347//347 480//480 345//345
            +f 479//479 345//345 480//480
            +f 349//349 481//481 347//347
            +f 480//480 347//347 481//481
            +f 1//1 3//3 482//482
            +f 483//483 482//482 3//3
            +f 482//482 483//483 484//484
            +f 485//485 484//484 483//483
            +f 484//484 485//485 486//486
            +f 487//487 486//486 485//485
            +f 486//486 487//487 488//488
            +f 489//489 488//488 487//487
            +f 488//488 489//489 349//349
            +f 481//481 349//349 489//489
            +f 3//3 4//4 483//483
            +f 490//490 483//483 4//4
            +f 483//483 490//490 485//485
            +f 491//491 485//485 490//490
            +f 485//485 491//491 487//487
            +f 492//492 487//487 491//491
            +f 487//487 492//492 489//489
            +f 493//493 489//489 492//492
            +f 489//489 493//493 481//481
            +f 475//475 481//481 493//493
            +f 4//4 5//5 490//490
            +f 494//494 490//490 5//5
            +f 490//490 494//494 491//491
            +f 495//495 491//491 494//494
            +f 491//491 495//495 492//492
            +f 496//496 492//492 495//495
            +f 492//492 496//496 493//493
            +f 497//497 493//493 496//496
            +f 493//493 497//497 475//475
            +f 469//469 475//475 497//497
            +f 5//5 6//6 498//498
            +f 498//498 494//494 5//5
            +f 494//494 498//498 499//499
            +f 499//499 495//495 494//494
            +f 495//495 499//499 500//500
            +f 500//500 496//496 495//495
            +f 496//496 500//500 501//501
            +f 501//501 497//497 496//496
            +f 497//497 501//501 463//463
            +f 463//463 469//469 497//497
            +f 6//6 7//7 502//502
            +f 502//502 498//498 6//6
            +f 498//498 502//502 503//503
            +f 503//503 499//499 498//498
            +f 499//499 503//503 504//504
            +f 504//504 500//500 499//499
            +f 500//500 504//504 505//505
            +f 505//505 501//501 500//500
            +f 501//501 505//505 457//457
            +f 457//457 463//463 501//501
            +f 7//7 8//8 506//506
            +f 506//506 502//502 7//7
            +f 502//502 506//506 507//507
            +f 507//507 503//503 502//502
            +f 503//503 507//507 508//508
            +f 508//508 504//504 503//503
            +f 504//504 508//508 509//509
            +f 509//509 505//505 504//504
            +f 505//505 509//509 451//451
            +f 451//451 457//457 505//505
            +f 8//8 9//9 506//506
            +f 510//510 506//506 9//9
            +f 506//506 510//510 507//507
            +f 511//511 507//507 510//510
            +f 507//507 511//511 508//508
            +f 512//512 508//508 511//511
            +f 508//508 512//512 509//509
            +f 513//513 509//509 512//512
            +f 509//509 513//513 451//451
            +f 445//445 451//451 513//513
            +f 9//9 10//10 510//510
            +f 514//514 510//510 10//10
            +f 510//510 514//514 511//511
            +f 515//515 511//511 514//514
            +f 511//511 515//515 512//512
            +f 516//516 512//512 515//515
            +f 512//512 516//516 513//513
            +f 517//517 513//513 516//516
            +f 513//513 517//517 445//445
            +f 439//439 445//445 517//517
            +f 10//10 11//11 514//514
            +f 518//518 514//514 11//11
            +f 514//514 518//518 515//515
            +f 519//519 515//515 518//518
            +f 515//515 519//519 516//516
            +f 520//520 516//516 519//519
            +f 516//516 520//520 517//517
            +f 521//521 517//517 520//520
            +f 517//517 521//521 439//439
            +f 433//433 439//439 521//521
            +f 11//11 12//12 522//522
            +f 522//522 518//518 11//11
            +f 518//518 522//522 523//523
            +f 523//523 519//519 518//518
            +f 519//519 523//523 524//524
            +f 524//524 520//520 519//519
            +f 520//520 524//524 525//525
            +f 525//525 521//521 520//520
            +f 521//521 525//525 427//427
            +f 427//427 433//433 521//521
            +f 12//12 13//13 526//526
            +f 526//526 522//522 12//12
            +f 522//522 526//526 527//527
            +f 527//527 523//523 522//522
            +f 523//523 527//527 528//528
            +f 528//528 524//524 523//523
            +f 524//524 528//528 529//529
            +f 529//529 525//525 524//524
            +f 525//525 529//529 421//421
            +f 421//421 427//427 525//525
            +f 13//13 14//14 530//530
            +f 530//530 526//526 13//13
            +f 526//526 530//530 531//531
            +f 531//531 527//527 526//526
            +f 527//527 531//531 532//532
            +f 532//532 528//528 527//527
            +f 528//528 532//532 533//533
            +f 533//533 529//529 528//528
            +f 529//529 533//533 415//415
            +f 415//415 421//421 529//529
            +f 14//14 15//15 530//530
            +f 534//534 530//530 15//15
            +f 530//530 534//534 531//531
            +f 535//535 531//531 534//534
            +f 531//531 535//535 532//532
            +f 536//536 532//532 535//535
            +f 532//532 536//536 533//533
            +f 537//537 533//533 536//536
            +f 533//533 537//537 415//415
            +f 409//409 415//415 537//537
            +f 15//15 16//16 534//534
            +f 538//538 534//534 16//16
            +f 534//534 538//538 535//535
            +f 539//539 535//535 538//538
            +f 535//535 539//539 536//536
            +f 540//540 536//536 539//539
            +f 536//536 540//540 537//537
            +f 541//541 537//537 540//540
            +f 537//537 541//541 409//409
            +f 403//403 409//409 541//541
            +f 16//16 17//17 538//538
            +f 542//542 538//538 17//17
            +f 538//538 542//542 539//539
            +f 543//543 539//539 542//542
            +f 539//539 543//543 540//540
            +f 544//544 540//540 543//543
            +f 540//540 544//544 541//541
            +f 545//545 541//541 544//544
            +f 541//541 545//545 403//403
            +f 397//397 403//403 545//545
            +f 17//17 18//18 546//546
            +f 546//546 542//542 17//17
            +f 542//542 546//546 547//547
            +f 547//547 543//543 542//542
            +f 543//543 547//547 548//548
            +f 548//548 544//544 543//543
            +f 544//544 548//548 549//549
            +f 549//549 545//545 544//544
            +f 545//545 549//549 391//391
            +f 391//391 397//397 545//545
            +f 18//18 19//19 550//550
            +f 550//550 546//546 18//18
            +f 546//546 550//550 551//551
            +f 551//551 547//547 546//546
            +f 547//547 551//551 552//552
            +f 552//552 548//548 547//547
            +f 548//548 552//552 553//553
            +f 553//553 549//549 548//548
            +f 549//549 553//553 385//385
            +f 385//385 391//391 549//549
            +f 19//19 20//20 554//554
            +f 554//554 550//550 19//19
            +f 550//550 554//554 555//555
            +f 555//555 551//551 550//550
            +f 551//551 555//555 556//556
            +f 556//556 552//552 551//551
            +f 552//552 556//556 557//557
            +f 557//557 553//553 552//552
            +f 553//553 557//557 379//379
            +f 379//379 385//385 553//553
            +f 20//20 21//21 554//554
            +f 558//558 554//554 21//21
            +f 554//554 558//558 555//555
            +f 559//559 555//555 558//558
            +f 555//555 559//559 556//556
            +f 560//560 556//556 559//559
            +f 556//556 560//560 557//557
            +f 561//561 557//557 560//560
            +f 557//557 561//561 379//379
            +f 373//373 379//379 561//561
            +f 21//21 22//22 558//558
            +f 562//562 558//558 22//22
            +f 558//558 562//562 559//559
            +f 563//563 559//559 562//562
            +f 559//559 563//563 560//560
            +f 564//564 560//560 563//563
            +f 560//560 564//564 561//561
            +f 565//565 561//561 564//564
            +f 561//561 565//565 373//373
            +f 367//367 373//373 565//565
            +f 22//22 23//23 562//562
            +f 566//566 562//562 23//23
            +f 562//562 566//566 563//563
            +f 567//567 563//563 566//566
            +f 563//563 567//567 564//564
            +f 568//568 564//564 567//567
            +f 564//564 568//568 565//565
            +f 569//569 565//565 568//568
            +f 565//565 569//569 367//367
            +f 361//361 367//367 569//569
            +f 23//23 24//24 570//570
            +f 570//570 566//566 23//23
            +f 566//566 570//570 571//571
            +f 571//571 567//567 566//566
            +f 567//567 571//571 572//572
            +f 572//572 568//568 567//567
            +f 568//568 572//572 573//573
            +f 573//573 569//569 568//568
            +f 569//569 573//573 355//355
            +f 355//355 361//361 569//569
            +f 24//24 25//25 574//574
            +f 574//574 570//570 24//24
            +f 570//570 574//574 575//575
            +f 575//575 571//571 570//570
            +f 571//571 575//575 576//576
            +f 576//576 572//572 571//571
            +f 572//572 576//576 577//577
            +f 577//577 573//573 572//572
            +f 573//573 577//577 348//348
            +f 348//348 355//355 573//573
            +f 25//25 1//1 482//482
            +f 482//482 574//574 25//25
            +f 574//574 482//482 484//484
            +f 484//484 575//575 574//574
            +f 575//575 484//484 486//486
            +f 486//486 576//576 575//575
            +f 576//576 486//486 488//488
            +f 488//488 577//577 576//576
            +f 577//577 488//488 349//349
            +f 349//349 348//348 577//577
            +f 578//578 579//579 580//580
            +f 581//581 580//580 579//579
            +f 582//582 578//578 583//583
            +f 580//580 583//583 578//578
            +f 584//584 582//582 585//585
            +f 583//583 585//585 582//582
            +f 586//586 584//584 585//585
            +f 585//585 587//587 586//586
            +f 588//588 586//586 587//587
            +f 587//587 589//589 588//588
            +f 590//590 588//588 589//589
            +f 589//589 591//591 590//590
            +f 592//592 590//590 593//593
            +f 591//591 593//593 590//590
            +f 594//594 592//592 595//595
            +f 593//593 595//595 592//592
            +f 596//596 594//594 597//597
            +f 595//595 597//597 594//594
            +f 598//598 596//596 597//597
            +f 597//597 599//599 598//598
            +f 600//600 598//598 599//599
            +f 599//599 601//601 600//600
            +f 602//602 600//600 601//601
            +f 601//601 603//603 602//602
            +f 604//604 602//602 605//605
            +f 603//603 605//605 602//602
            +f 606//606 604//604 607//607
            +f 605//605 607//607 604//604
            +f 608//608 606//606 609//609
            +f 607//607 609//609 606//606
            +f 610//610 608//608 609//609
            +f 609//609 611//611 610//610
            +f 612//612 610//610 611//611
            +f 611//611 613//613 612//612
            +f 614//614 612//612 613//613
            +f 613//613 615//615 614//614
            +f 616//616 614//614 617//617
            +f 615//615 617//617 614//614
            +f 618//618 616//616 619//619
            +f 617//617 619//619 616//616
            +f 620//620 618//618 621//621
            +f 619//619 621//621 618//618
            +f 622//622 620//620 621//621
            +f 621//621 623//623 622//622
            +f 624//624 622//622 623//623
            +f 623//623 625//625 624//624
            +f 579//579 624//624 625//625
            +f 625//625 581//581 579//579
            +f 626//626 627//627 578//578
            +f 579//579 578//578 627//627
            +f 628//628 629//629 626//626
            +f 627//627 626//626 629//629
            +f 630//630 631//631 628//628
            +f 629//629 628//628 631//631
            +f 632//632 633//633 630//630
            +f 631//631 630//630 633//633
            +f 634//634 635//635 632//632
            +f 633//633 632//632 635//635
            +f 636//636 637//637 634//634
            +f 635//635 634//634 637//637
            +f 638//638 626//626 582//582
            +f 578//578 582//582 626//626
            +f 639//639 628//628 638//638
            +f 626//626 638//638 628//628
            +f 640//640 630//630 639//639
            +f 628//628 639//639 630//630
            +f 641//641 632//632 640//640
            +f 630//630 640//640 632//632
            +f 642//642 634//634 641//641
            +f 632//632 641//641 634//634
            +f 643//643 636//636 642//642
            +f 634//634 642//642 636//636
            +f 644//644 638//638 584//584
            +f 582//582 584//584 638//638
            +f 645//645 639//639 644//644
            +f 638//638 644//644 639//639
            +f 646//646 640//640 645//645
            +f 639//639 645//645 640//640
            +f 647//647 641//641 646//646
            +f 640//640 646//646 641//641
            +f 648//648 642//642 647//647
            +f 641//641 647//647 642//642
            +f 649//649 643//643 648//648
            +f 642//642 648//648 643//643
            +f 650//650 644//644 584//584
            +f 584//584 586//586 650//650
            +f 651//651 645//645 644//644
            +f 644//644 650//650 651//651
            +f 652//652 646//646 645//645
            +f 645//645 651//651 652//652
            +f 653//653 647//647 646//646
            +f 646//646 652//652 653//653
            +f 654//654 648//648 647//647
            +f 647//647 653//653 654//654
            +f 655//655 649//649 648//648
            +f 648//648 654//654 655//655
            +f 656//656 650//650 586//586
            +f 586//586 588//588 656//656
            +f 657//657 651//651 650//650
            +f 650//650 656//656 657//657
            +f 658//658 652//652 651//651
            +f 651//651 657//657 658//658
            +f 659//659 653//653 652//652
            +f 652//652 658//658 659//659
            +f 660//660 654//654 653//653
            +f 653//653 659//659 660//660
            +f 661//661 655//655 654//654
            +f 654//654 660//660 661//661
            +f 662//662 656//656 588//588
            +f 588//588 590//590 662//662
            +f 663//663 657//657 656//656
            +f 656//656 662//662 663//663
            +f 664//664 658//658 657//657
            +f 657//657 663//663 664//664
            +f 665//665 659//659 658//658
            +f 658//658 664//664 665//665
            +f 666//666 660//660 659//659
            +f 659//659 665//665 666//666
            +f 667//667 661//661 660//660
            +f 660//660 666//666 667//667
            +f 668//668 662//662 592//592
            +f 590//590 592//592 662//662
            +f 669//669 663//663 668//668
            +f 662//662 668//668 663//663
            +f 670//670 664//664 669//669
            +f 663//663 669//669 664//664
            +f 671//671 665//665 670//670
            +f 664//664 670//670 665//665
            +f 672//672 666//666 671//671
            +f 665//665 671//671 666//666
            +f 673//673 667//667 672//672
            +f 666//666 672//672 667//667
            +f 674//674 668//668 594//594
            +f 592//592 594//594 668//668
            +f 675//675 669//669 674//674
            +f 668//668 674//674 669//669
            +f 676//676 670//670 675//675
            +f 669//669 675//675 670//670
            +f 677//677 671//671 676//676
            +f 670//670 676//676 671//671
            +f 678//678 672//672 677//677
            +f 671//671 677//677 672//672
            +f 679//679 673//673 678//678
            +f 672//672 678//678 673//673
            +f 680//680 674//674 596//596
            +f 594//594 596//596 674//674
            +f 681//681 675//675 680//680
            +f 674//674 680//680 675//675
            +f 682//682 676//676 681//681
            +f 675//675 681//681 676//676
            +f 683//683 677//677 682//682
            +f 676//676 682//682 677//677
            +f 684//684 678//678 683//683
            +f 677//677 683//683 678//678
            +f 685//685 679//679 684//684
            +f 678//678 684//684 679//679
            +f 686//686 680//680 596//596
            +f 596//596 598//598 686//686
            +f 687//687 681//681 680//680
            +f 680//680 686//686 687//687
            +f 688//688 682//682 681//681
            +f 681//681 687//687 688//688
            +f 689//689 683//683 682//682
            +f 682//682 688//688 689//689
            +f 690//690 684//684 683//683
            +f 683//683 689//689 690//690
            +f 691//691 685//685 684//684
            +f 684//684 690//690 691//691
            +f 692//692 686//686 598//598
            +f 598//598 600//600 692//692
            +f 693//693 687//687 686//686
            +f 686//686 692//692 693//693
            +f 694//694 688//688 687//687
            +f 687//687 693//693 694//694
            +f 695//695 689//689 688//688
            +f 688//688 694//694 695//695
            +f 696//696 690//690 689//689
            +f 689//689 695//695 696//696
            +f 697//697 691//691 690//690
            +f 690//690 696//696 697//697
            +f 698//698 692//692 600//600
            +f 600//600 602//602 698//698
            +f 699//699 693//693 692//692
            +f 692//692 698//698 699//699
            +f 700//700 694//694 693//693
            +f 693//693 699//699 700//700
            +f 701//701 695//695 694//694
            +f 694//694 700//700 701//701
            +f 702//702 696//696 695//695
            +f 695//695 701//701 702//702
            +f 703//703 697//697 696//696
            +f 696//696 702//702 703//703
            +f 704//704 698//698 604//604
            +f 602//602 604//604 698//698
            +f 705//705 699//699 704//704
            +f 698//698 704//704 699//699
            +f 706//706 700//700 705//705
            +f 699//699 705//705 700//700
            +f 707//707 701//701 706//706
            +f 700//700 706//706 701//701
            +f 708//708 702//702 707//707
            +f 701//701 707//707 702//702
            +f 709//709 703//703 708//708
            +f 702//702 708//708 703//703
            +f 710//710 704//704 606//606
            +f 604//604 606//606 704//704
            +f 711//711 705//705 710//710
            +f 704//704 710//710 705//705
            +f 712//712 706//706 711//711
            +f 705//705 711//711 706//706
            +f 713//713 707//707 712//712
            +f 706//706 712//712 707//707
            +f 714//714 708//708 713//713
            +f 707//707 713//713 708//708
            +f 715//715 709//709 714//714
            +f 708//708 714//714 709//709
            +f 716//716 710//710 608//608
            +f 606//606 608//608 710//710
            +f 717//717 711//711 716//716
            +f 710//710 716//716 711//711
            +f 718//718 712//712 717//717
            +f 711//711 717//717 712//712
            +f 719//719 713//713 718//718
            +f 712//712 718//718 713//713
            +f 720//720 714//714 719//719
            +f 713//713 719//719 714//714
            +f 721//721 715//715 720//720
            +f 714//714 720//720 715//715
            +f 722//722 716//716 608//608
            +f 608//608 610//610 722//722
            +f 723//723 717//717 716//716
            +f 716//716 722//722 723//723
            +f 724//724 718//718 717//717
            +f 717//717 723//723 724//724
            +f 725//725 719//719 718//718
            +f 718//718 724//724 725//725
            +f 726//726 720//720 719//719
            +f 719//719 725//725 726//726
            +f 727//727 721//721 720//720
            +f 720//720 726//726 727//727
            +f 728//728 722//722 610//610
            +f 610//610 612//612 728//728
            +f 729//729 723//723 722//722
            +f 722//722 728//728 729//729
            +f 730//730 724//724 723//723
            +f 723//723 729//729 730//730
            +f 731//731 725//725 724//724
            +f 724//724 730//730 731//731
            +f 732//732 726//726 725//725
            +f 725//725 731//731 732//732
            +f 733//733 727//727 726//726
            +f 726//726 732//732 733//733
            +f 734//734 728//728 612//612
            +f 612//612 614//614 734//734
            +f 735//735 729//729 728//728
            +f 728//728 734//734 735//735
            +f 736//736 730//730 729//729
            +f 729//729 735//735 736//736
            +f 737//737 731//731 730//730
            +f 730//730 736//736 737//737
            +f 738//738 732//732 731//731
            +f 731//731 737//737 738//738
            +f 739//739 733//733 732//732
            +f 732//732 738//738 739//739
            +f 740//740 734//734 616//616
            +f 614//614 616//616 734//734
            +f 741//741 735//735 740//740
            +f 734//734 740//740 735//735
            +f 742//742 736//736 741//741
            +f 735//735 741//741 736//736
            +f 743//743 737//737 742//742
            +f 736//736 742//742 737//737
            +f 744//744 738//738 743//743
            +f 737//737 743//743 738//738
            +f 745//745 739//739 744//744
            +f 738//738 744//744 739//739
            +f 746//746 740//740 618//618
            +f 616//616 618//618 740//740
            +f 747//747 741//741 746//746
            +f 740//740 746//746 741//741
            +f 748//748 742//742 747//747
            +f 741//741 747//747 742//742
            +f 749//749 743//743 748//748
            +f 742//742 748//748 743//743
            +f 750//750 744//744 749//749
            +f 743//743 749//749 744//744
            +f 751//751 745//745 750//750
            +f 744//744 750//750 745//745
            +f 752//752 746//746 620//620
            +f 618//618 620//620 746//746
            +f 753//753 747//747 752//752
            +f 746//746 752//752 747//747
            +f 754//754 748//748 753//753
            +f 747//747 753//753 748//748
            +f 755//755 749//749 754//754
            +f 748//748 754//754 749//749
            +f 756//756 750//750 755//755
            +f 749//749 755//755 750//750
            +f 757//757 751//751 756//756
            +f 750//750 756//756 751//751
            +f 758//758 752//752 620//620
            +f 620//620 622//622 758//758
            +f 759//759 753//753 752//752
            +f 752//752 758//758 759//759
            +f 760//760 754//754 753//753
            +f 753//753 759//759 760//760
            +f 761//761 755//755 754//754
            +f 754//754 760//760 761//761
            +f 762//762 756//756 755//755
            +f 755//755 761//761 762//762
            +f 763//763 757//757 756//756
            +f 756//756 762//762 763//763
            +f 764//764 758//758 622//622
            +f 622//622 624//624 764//764
            +f 765//765 759//759 758//758
            +f 758//758 764//764 765//765
            +f 766//766 760//760 759//759
            +f 759//759 765//765 766//766
            +f 767//767 761//761 760//760
            +f 760//760 766//766 767//767
            +f 768//768 762//762 761//761
            +f 761//761 767//767 768//768
            +f 769//769 763//763 762//762
            +f 762//762 768//768 769//769
            +f 627//627 764//764 624//624
            +f 624//624 579//579 627//627
            +f 629//629 765//765 764//764
            +f 764//764 627//627 629//629
            +f 631//631 766//766 765//765
            +f 765//765 629//629 631//631
            +f 633//633 767//767 766//766
            +f 766//766 631//631 633//633
            +f 635//635 768//768 767//767
            +f 767//767 633//633 635//635
            +f 637//637 769//769 768//768
            +f 768//768 635//635 637//637
            +f 770//770 771//771 772//772
            +f 773//773 772//772 771//771
            +f 774//774 770//770 775//775
            +f 772//772 775//775 770//770
            +f 776//776 777//777 774//774
            +f 774//774 775//775 776//776
            +f 778//778 779//779 776//776
            +f 777//777 776//776 779//779
            +f 780//780 781//781 778//778
            +f 779//779 778//778 781//781
            +f 782//782 783//783 780//780
            +f 781//781 780//780 783//783
            +f 772//772 773//773 784//784
            +f 785//785 784//784 773//773
            +f 775//775 772//772 786//786
            +f 784//784 786//786 772//772
            +f 776//776 775//775 787//787
            +f 786//786 787//787 775//775
            +f 788//788 778//778 776//776
            +f 776//776 787//787 788//788
            +f 789//789 780//780 788//788
            +f 778//778 788//788 780//780
            +f 790//790 782//782 789//789
            +f 780//780 789//789 782//782
            +f 784//784 785//785 791//791
            +f 792//792 791//791 785//785
            +f 786//786 784//784 793//793
            +f 791//791 793//793 784//784
            +f 787//787 786//786 794//794
            +f 793//793 794//794 786//786
            +f 795//795 788//788 787//787
            +f 787//787 794//794 795//795
            +f 796//796 789//789 795//795
            +f 788//788 795//795 789//789
            +f 797//797 790//790 796//796
            +f 789//789 796//796 790//790
            +f 791//791 792//792 798//798
            +f 799//799 798//798 792//792
            +f 793//793 791//791 800//800
            +f 798//798 800//800 791//791
            +f 794//794 793//793 801//801
            +f 800//800 801//801 793//793
            +f 802//802 795//795 794//794
            +f 794//794 801//801 802//802
            +f 803//803 796//796 802//802
            +f 795//795 802//802 796//796
            +f 804//804 797//797 803//803
            +f 796//796 803//803 797//797
            +f 798//798 799//799 805//805
            +f 806//806 805//805 799//799
            +f 800//800 798//798 807//807
            +f 805//805 807//807 798//798
            +f 801//801 800//800 808//808
            +f 807//807 808//808 800//800
            +f 809//809 802//802 801//801
            +f 801//801 808//808 809//809
            +f 810//810 803//803 809//809
            +f 802//802 809//809 803//803
            +f 811//811 804//804 810//810
            +f 803//803 810//810 804//804
            +f 805//805 806//806 812//812
            +f 813//813 812//812 806//806
            +f 807//807 805//805 814//814
            +f 812//812 814//814 805//805
            +f 815//815 808//808 814//814
            +f 807//807 814//814 808//808
            +f 816//816 809//809 815//815
            +f 808//808 815//815 809//809
            +f 817//817 810//810 816//816
            +f 809//809 816//816 810//810
            +f 818//818 811//811 817//817
            +f 810//810 817//817 811//811
            +f 819//819 820//820 812//812
            +f 812//812 813//813 819//819
            +f 820//820 821//821 814//814
            +f 814//814 812//812 820//820
            +f 822//822 815//815 814//814
            +f 814//814 821//821 822//822
            +f 823//823 816//816 815//815
            +f 815//815 822//822 823//823
            +f 824//824 817//817 816//816
            +f 816//816 823//823 824//824
            +f 825//825 818//818 817//817
            +f 817//817 824//824 825//825
            +f 826//826 827//827 820//820
            +f 820//820 819//819 826//826
            +f 827//827 828//828 821//821
            +f 821//821 820//820 827//827
            +f 828//828 829//829 822//822
            +f 822//822 821//821 828//828
            +f 830//830 823//823 829//829
            +f 822//822 829//829 823//823
            +f 831//831 824//824 823//823
            +f 823//823 830//830 831//831
            +f 832//832 825//825 824//824
            +f 824//824 831//831 832//832
            +f 833//833 834//834 827//827
            +f 827//827 826//826 833//833
            +f 834//834 835//835 828//828
            +f 828//828 827//827 834//834
            +f 835//835 836//836 829//829
            +f 829//829 828//828 835//835
            +f 837//837 830//830 836//836
            +f 829//829 836//836 830//830
            +f 838//838 831//831 830//830
            +f 830//830 837//837 838//838
            +f 839//839 832//832 831//831
            +f 831//831 838//838 839//839
            +f 840//840 841//841 834//834
            +f 834//834 833//833 840//840
            +f 841//841 842//842 835//835
            +f 835//835 834//834 841//841
            +f 842//842 843//843 836//836
            +f 836//836 835//835 842//842
            +f 844//844 837//837 843//843
            +f 836//836 843//843 837//837
            +f 845//845 838//838 837//837
            +f 837//837 844//844 845//845
            +f 846//846 839//839 838//838
            +f 838//838 845//845 846//846
            +f 847//847 848//848 841//841
            +f 841//841 840//840 847//847
            +f 848//848 849//849 842//842
            +f 842//842 841//841 848//848
            +f 849//849 850//850 843//843
            +f 843//843 842//842 849//849
            +f 851//851 844//844 850//850
            +f 843//843 850//850 844//844
            +f 852//852 845//845 844//844
            +f 844//844 851//851 852//852
            +f 853//853 846//846 845//845
            +f 845//845 852//852 853//853
            +f 771//771 770//770 848//848
            +f 848//848 847//847 771//771
            +f 770//770 774//774 849//849
            +f 849//849 848//848 770//770
            +f 777//777 850//850 774//774
            +f 849//849 774//774 850//850
            +f 779//779 851//851 850//850
            +f 850//850 777//777 779//779
            +f 781//781 852//852 851//851
            +f 851//851 779//779 781//781
            +f 783//783 853//853 852//852
            +f 852//852 781//781 783//783
            +f 854//854 855//855 782//782
            +f 783//783 782//782 855//855
            +f 856//856 857//857 855//855
            +f 855//855 854//854 856//856
            +f 858//858 859//859 857//857
            +f 857//857 856//856 858//858
            +f 860//860 861//861 859//859
            +f 859//859 858//858 860//860
            +f 862//862 863//863 861//861
            +f 861//861 860//860 862//862
            +f 864//864 865//865 863//863
            +f 863//863 862//862 864//864
            +f 866//866 854//854 782//782
            +f 782//782 790//790 866//866
            +f 867//867 856//856 854//854
            +f 854//854 866//866 867//867
            +f 868//868 858//858 856//856
            +f 856//856 867//867 868//868
            +f 869//869 860//860 858//858
            +f 858//858 868//868 869//869
            +f 870//870 862//862 860//860
            +f 860//860 869//869 870//870
            +f 871//871 864//864 870//870
            +f 862//862 870//870 864//864
            +f 872//872 866//866 790//790
            +f 790//790 797//797 872//872
            +f 873//873 867//867 866//866
            +f 866//866 872//872 873//873
            +f 874//874 868//868 867//867
            +f 867//867 873//873 874//874
            +f 875//875 869//869 874//874
            +f 868//868 874//874 869//869
            +f 876//876 870//870 875//875
            +f 869//869 875//875 870//870
            +f 877//877 871//871 876//876
            +f 870//870 876//876 871//871
            +f 878//878 872//872 797//797
            +f 797//797 804//804 878//878
            +f 879//879 873//873 872//872
            +f 872//872 878//878 879//879
            +f 880//880 874//874 873//873
            +f 873//873 879//879 880//880
            +f 881//881 875//875 880//880
            +f 874//874 880//880 875//875
            +f 882//882 876//876 881//881
            +f 875//875 881//881 876//876
            +f 883//883 877//877 882//882
            +f 876//876 882//882 877//877
            +f 884//884 878//878 804//804
            +f 804//804 811//811 884//884
            +f 885//885 879//879 878//878
            +f 878//878 884//884 885//885
            +f 886//886 880//880 879//879
            +f 879//879 885//885 886//886
            +f 887//887 881//881 880//880
            +f 880//880 886//886 887//887
            +f 888//888 882//882 881//881
            +f 881//881 887//887 888//888
            +f 889//889 883//883 888//888
            +f 882//882 888//888 883//883
            +f 890//890 884//884 811//811
            +f 811//811 818//818 890//890
            +f 891//891 885//885 884//884
            +f 884//884 890//890 891//891
            +f 892//892 886//886 885//885
            +f 885//885 891//891 892//892
            +f 893//893 887//887 886//886
            +f 886//886 892//892 893//893
            +f 894//894 888//888 887//887
            +f 887//887 893//893 894//894
            +f 895//895 889//889 888//888
            +f 888//888 894//894 895//895
            +f 896//896 890//890 825//825
            +f 818//818 825//825 890//890
            +f 897//897 891//891 896//896
            +f 890//890 896//896 891//891
            +f 898//898 892//892 897//897
            +f 891//891 897//897 892//892
            +f 899//899 893//893 898//898
            +f 892//892 898//898 893//893
            +f 900//900 894//894 899//899
            +f 893//893 899//899 894//894
            +f 901//901 895//895 900//900
            +f 894//894 900//900 895//895
            +f 902//902 896//896 832//832
            +f 825//825 832//832 896//896
            +f 903//903 897//897 902//902
            +f 896//896 902//902 897//897
            +f 904//904 898//898 903//903
            +f 897//897 903//903 898//898
            +f 905//905 899//899 904//904
            +f 898//898 904//904 899//899
            +f 906//906 900//900 905//905
            +f 899//899 905//905 900//900
            +f 907//907 901//901 900//900
            +f 900//900 906//906 907//907
            +f 908//908 902//902 839//839
            +f 832//832 839//839 902//902
            +f 909//909 903//903 908//908
            +f 902//902 908//908 903//903
            +f 910//910 904//904 909//909
            +f 903//903 909//909 904//904
            +f 911//911 905//905 904//904
            +f 904//904 910//910 911//911
            +f 912//912 906//906 905//905
            +f 905//905 911//911 912//912
            +f 913//913 907//907 906//906
            +f 906//906 912//912 913//913
            +f 914//914 908//908 846//846
            +f 839//839 846//846 908//908
            +f 915//915 909//909 914//914
            +f 908//908 914//914 909//909
            +f 916//916 910//910 915//915
            +f 909//909 915//915 910//910
            +f 917//917 911//911 910//910
            +f 910//910 916//916 917//917
            +f 918//918 912//912 911//911
            +f 911//911 917//917 918//918
            +f 919//919 913//913 912//912
            +f 912//912 918//918 919//919
            +f 920//920 914//914 853//853
            +f 846//846 853//853 914//914
            +f 921//921 915//915 920//920
            +f 914//914 920//920 915//915
            +f 922//922 916//916 921//921
            +f 915//915 921//921 916//916
            +f 923//923 917//917 922//922
            +f 916//916 922//922 917//917
            +f 924//924 918//918 923//923
            +f 917//917 923//923 918//918
            +f 925//925 919//919 918//918
            +f 918//918 924//924 925//925
            +f 855//855 920//920 853//853
            +f 853//853 783//783 855//855
            +f 857//857 921//921 855//855
            +f 920//920 855//855 921//921
            +f 859//859 922//922 857//857
            +f 921//921 857//857 922//922
            +f 861//861 923//923 859//859
            +f 922//922 859//859 923//923
            +f 863//863 924//924 861//861
            +f 923//923 861//861 924//924
            +f 865//865 925//925 863//863
            +f 924//924 863//863 925//925
            +f 926//926 927//927 928//928
            +f 928//928 929//929 926//926
            +f 929//929 928//928 930//930
            +f 930//930 931//931 929//929
            +f 931//931 930//930 932//932
            +f 932//932 933//933 931//931
            +f 933//933 932//932 934//934
            +f 934//934 935//935 933//933
            +f 935//935 934//934 936//936
            +f 936//936 937//937 935//935
            +f 937//937 936//936 938//938
            +f 939//939 938//938 936//936
            +f 940//940 941//941 927//927
            +f 928//928 927//927 941//941
            +f 928//928 941//941 942//942
            +f 942//942 930//930 928//928
            +f 930//930 942//942 943//943
            +f 943//943 932//932 930//930
            +f 932//932 943//943 944//944
            +f 944//944 934//934 932//932
            +f 934//934 944//944 936//936
            +f 945//945 936//936 944//944
            +f 936//936 945//945 939//939
            +f 946//946 939//939 945//945
            +f 947//947 948//948 940//940
            +f 941//941 940//940 948//948
            +f 941//941 948//948 949//949
            +f 949//949 942//942 941//941
            +f 942//942 949//949 943//943
            +f 950//950 943//943 949//949
            +f 943//943 950//950 944//944
            +f 951//951 944//944 950//950
            +f 944//944 951//951 945//945
            +f 952//952 945//945 951//951
            +f 945//945 952//952 946//946
            +f 953//953 946//946 952//952
            +f 954//954 955//955 947//947
            +f 948//948 947//947 955//955
            +f 948//948 955//955 956//956
            +f 956//956 949//949 948//948
            +f 949//949 956//956 950//950
            +f 957//957 950//950 956//956
            +f 950//950 957//957 951//951
            +f 958//958 951//951 957//957
            +f 951//951 958//958 952//952
            +f 959//959 952//952 958//958
            +f 952//952 959//959 953//953
            +f 960//960 953//953 959//959
            +f 954//954 961//961 962//962
            +f 962//962 955//955 954//954
            +f 955//955 962//962 956//956
            +f 963//963 956//956 962//962
            +f 956//956 963//963 957//957
            +f 964//964 957//957 963//963
            +f 957//957 964//964 958//958
            +f 965//965 958//958 964//964
            +f 958//958 965//965 959//959
            +f 966//966 959//959 965//965
            +f 959//959 966//966 960//960
            +f 967//967 960//960 966//966
            +f 961//961 968//968 962//962
            +f 969//969 962//962 968//968
            +f 962//962 969//969 963//963
            +f 970//970 963//963 969//969
            +f 963//963 970//970 964//964
            +f 971//971 964//964 970//970
            +f 964//964 971//971 965//965
            +f 972//972 965//965 971//971
            +f 965//965 972//972 966//966
            +f 973//973 966//966 972//972
            +f 966//966 973//973 967//967
            +f 974//974 967//967 973//973
            +f 968//968 975//975 976//976
            +f 976//976 969//969 968//968
            +f 969//969 976//976 977//977
            +f 977//977 970//970 969//969
            +f 970//970 977//977 978//978
            +f 978//978 971//971 970//970
            +f 971//971 978//978 979//979
            +f 979//979 972//972 971//971
            +f 972//972 979//979 980//980
            +f 980//980 973//973 972//972
            +f 973//973 980//980 981//981
            +f 981//981 974//974 973//973
            +f 975//975 982//982 976//976
            +f 983//983 976//976 982//982
            +f 976//976 983//983 984//984
            +f 984//984 977//977 976//976
            +f 977//977 984//984 985//985
            +f 985//985 978//978 977//977
            +f 978//978 985//985 986//986
            +f 986//986 979//979 978//978
            +f 979//979 986//986 987//987
            +f 987//987 980//980 979//979
            +f 980//980 987//987 988//988
            +f 988//988 981//981 980//980
            +f 983//983 982//982 989//989
            +f 989//989 990//990 983//983
            +f 983//983 990//990 984//984
            +f 991//991 984//984 990//990
            +f 984//984 991//991 992//992
            +f 992//992 985//985 984//984
            +f 985//985 992//992 993//993
            +f 993//993 986//986 985//985
            +f 986//986 993//993 994//994
            +f 994//994 987//987 986//986
            +f 987//987 994//994 995//995
            +f 995//995 988//988 987//987
            +f 990//990 989//989 996//996
            +f 996//996 997//997 990//990
            +f 990//990 997//997 991//991
            +f 998//998 991//991 997//997
            +f 991//991 998//998 999//999
            +f 999//999 992//992 991//991
            +f 992//992 999//999 1000//1000
            +f 1000//1000 993//993 992//992
            +f 993//993 1000//1000 1001//1001
            +f 1001//1001 994//994 993//993
            +f 994//994 1001//1001 1002//1002
            +f 1002//1002 995//995 994//994
            +f 997//997 996//996 1003//1003
            +f 1003//1003 1004//1004 997//997
            +f 997//997 1004//1004 998//998
            +f 1005//1005 998//998 1004//1004
            +f 998//998 1005//1005 999//999
            +f 1006//1006 999//999 1005//1005
            +f 999//999 1006//1006 1000//1000
            +f 1007//1007 1000//1000 1006//1006
            +f 1000//1000 1007//1007 1008//1008
            +f 1008//1008 1001//1001 1000//1000
            +f 1001//1001 1008//1008 1009//1009
            +f 1009//1009 1002//1002 1001//1001
            +f 1003//1003 926//926 1004//1004
            +f 929//929 1004//1004 926//926
            +f 1004//1004 929//929 1005//1005
            +f 931//931 1005//1005 929//929
            +f 1005//1005 931//931 1006//1006
            +f 933//933 1006//1006 931//931
            +f 1006//1006 933//933 1007//1007
            +f 935//935 1007//1007 933//933
            +f 1007//1007 935//935 1008//1008
            +f 937//937 1008//1008 935//935
            +f 1008//1008 937//937 938//938
            +f 938//938 1009//1009 1008//1008
            +f 938//938 939//939 1010//1010
            +f 1011//1011 1010//1010 939//939
            +f 1010//1010 1011//1011 1012//1012
            +f 1013//1013 1012//1012 1011//1011
            +f 1012//1012 1013//1013 1014//1014
            +f 1015//1015 1014//1014 1013//1013
            +f 1016//1016 1017//1017 1014//1014
            +f 1014//1014 1015//1015 1016//1016
            +f 1018//1018 1019//1019 1017//1017
            +f 1017//1017 1016//1016 1018//1018
            +f 1020//1020 1021//1021 1019//1019
            +f 1019//1019 1018//1018 1020//1020
            +f 939//939 946//946 1011//1011
            +f 1022//1022 1011//1011 946//946
            +f 1011//1011 1022//1022 1013//1013
            +f 1023//1023 1013//1013 1022//1022
            +f 1013//1013 1023//1023 1015//1015
            +f 1024//1024 1015//1015 1023//1023
            +f 1025//1025 1016//1016 1015//1015
            +f 1015//1015 1024//1024 1025//1025
            +f 1026//1026 1018//1018 1016//1016
            +f 1016//1016 1025//1025 1026//1026
            +f 1027//1027 1020//1020 1018//1018
            +f 1018//1018 1026//1026 1027//1027
            +f 946//946 953//953 1022//1022
            +f 1028//1028 1022//1022 953//953
            +f 1022//1022 1028//1028 1023//1023
            +f 1029//1029 1023//1023 1028//1028
            +f 1023//1023 1029//1029 1024//1024
            +f 1030//1030 1024//1024 1029//1029
            +f 1031//1031 1025//1025 1024//1024
            +f 1024//1024 1030//1030 1031//1031
            +f 1032//1032 1026//1026 1025//1025
            +f 1025//1025 1031//1031 1032//1032
            +f 1033//1033 1027//1027 1026//1026
            +f 1026//1026 1032//1032 1033//1033
            +f 953//953 960//960 1028//1028
            +f 1034//1034 1028//1028 960//960
            +f 1028//1028 1034//1034 1029//1029
            +f 1035//1035 1029//1029 1034//1034
            +f 1029//1029 1035//1035 1030//1030
            +f 1036//1036 1030//1030 1035//1035
            +f 1037//1037 1031//1031 1030//1030
            +f 1030//1030 1036//1036 1037//1037
            +f 1038//1038 1032//1032 1031//1031
            +f 1031//1031 1037//1037 1038//1038
            +f 1039//1039 1033//1033 1032//1032
            +f 1032//1032 1038//1038 1039//1039
            +f 960//960 967//967 1034//1034
            +f 1040//1040 1034//1034 967//967
            +f 1034//1034 1040//1040 1035//1035
            +f 1041//1041 1035//1035 1040//1040
            +f 1035//1035 1041//1041 1036//1036
            +f 1042//1042 1036//1036 1041//1041
            +f 1043//1043 1037//1037 1036//1036
            +f 1036//1036 1042//1042 1043//1043
            +f 1044//1044 1038//1038 1037//1037
            +f 1037//1037 1043//1043 1044//1044
            +f 1045//1045 1039//1039 1038//1038
            +f 1038//1038 1044//1044 1045//1045
            +f 967//967 974//974 1040//1040
            +f 1046//1046 1040//1040 974//974
            +f 1040//1040 1046//1046 1041//1041
            +f 1047//1047 1041//1041 1046//1046
            +f 1041//1041 1047//1047 1042//1042
            +f 1048//1048 1042//1042 1047//1047
            +f 1049//1049 1043//1043 1042//1042
            +f 1042//1042 1048//1048 1049//1049
            +f 1050//1050 1044//1044 1043//1043
            +f 1043//1043 1049//1049 1050//1050
            +f 1051//1051 1045//1045 1044//1044
            +f 1044//1044 1050//1050 1051//1051
            +f 974//974 981//981 1052//1052
            +f 1052//1052 1046//1046 974//974
            +f 1046//1046 1052//1052 1053//1053
            +f 1053//1053 1047//1047 1046//1046
            +f 1047//1047 1053//1053 1054//1054
            +f 1054//1054 1048//1048 1047//1047
            +f 1055//1055 1049//1049 1054//1054
            +f 1048//1048 1054//1054 1049//1049
            +f 1056//1056 1050//1050 1055//1055
            +f 1049//1049 1055//1055 1050//1050
            +f 1057//1057 1051//1051 1056//1056
            +f 1050//1050 1056//1056 1051//1051
            +f 981//981 988//988 1058//1058
            +f 1058//1058 1052//1052 981//981
            +f 1052//1052 1058//1058 1059//1059
            +f 1059//1059 1053//1053 1052//1052
            +f 1053//1053 1059//1059 1060//1060
            +f 1060//1060 1054//1054 1053//1053
            +f 1061//1061 1055//1055 1060//1060
            +f 1054//1054 1060//1060 1055//1055
            +f 1062//1062 1056//1056 1061//1061
            +f 1055//1055 1061//1061 1056//1056
            +f 1063//1063 1057//1057 1062//1062
            +f 1056//1056 1062//1062 1057//1057
            +f 988//988 995//995 1064//1064
            +f 1064//1064 1058//1058 988//988
            +f 1058//1058 1064//1064 1065//1065
            +f 1065//1065 1059//1059 1058//1058
            +f 1059//1059 1065//1065 1066//1066
            +f 1066//1066 1060//1060 1059//1059
            +f 1067//1067 1061//1061 1066//1066
            +f 1060//1060 1066//1066 1061//1061
            +f 1068//1068 1062//1062 1067//1067
            +f 1061//1061 1067//1067 1062//1062
            +f 1069//1069 1063//1063 1068//1068
            +f 1062//1062 1068//1068 1063//1063
            +f 995//995 1002//1002 1070//1070
            +f 1070//1070 1064//1064 995//995
            +f 1064//1064 1070//1070 1071//1071
            +f 1071//1071 1065//1065 1064//1064
            +f 1065//1065 1071//1071 1072//1072
            +f 1072//1072 1066//1066 1065//1065
            +f 1073//1073 1067//1067 1072//1072
            +f 1066//1066 1072//1072 1067//1067
            +f 1074//1074 1068//1068 1073//1073
            +f 1067//1067 1073//1073 1068//1068
            +f 1075//1075 1069//1069 1074//1074
            +f 1068//1068 1074//1074 1069//1069
            +f 1002//1002 1009//1009 1076//1076
            +f 1076//1076 1070//1070 1002//1002
            +f 1070//1070 1076//1076 1077//1077
            +f 1077//1077 1071//1071 1070//1070
            +f 1071//1071 1077//1077 1078//1078
            +f 1078//1078 1072//1072 1071//1071
            +f 1079//1079 1073//1073 1078//1078
            +f 1072//1072 1078//1078 1073//1073
            +f 1080//1080 1074//1074 1079//1079
            +f 1073//1073 1079//1079 1074//1074
            +f 1081//1081 1075//1075 1080//1080
            +f 1074//1074 1080//1080 1075//1075
            +f 1009//1009 938//938 1010//1010
            +f 1010//1010 1076//1076 1009//1009
            +f 1076//1076 1010//1010 1012//1012
            +f 1012//1012 1077//1077 1076//1076
            +f 1077//1077 1012//1012 1014//1014
            +f 1014//1014 1078//1078 1077//1077
            +f 1017//1017 1079//1079 1014//1014
            +f 1078//1078 1014//1014 1079//1079
            +f 1019//1019 1080//1080 1017//1017
            +f 1079//1079 1017//1017 1080//1080
            +f 1021//1021 1081//1081 1019//1019
            +f 1080//1080 1019//1019 1081//1081
            +f 1082//1082 1083//1083 1084//1084
            +f 1084//1084 1083//1083 1085//1085
            +f 1085//1085 1083//1083 1086//1086
            +f 1086//1086 1083//1083 1087//1087
            +f 1087//1087 1083//1083 1088//1088
            +f 1088//1088 1083//1083 1089//1089
            +f 1089//1089 1083//1083 1090//1090
            +f 1090//1090 1083//1083 1091//1091
            +f 1091//1091 1083//1083 1092//1092
            +f 1092//1092 1083//1083 1093//1093
            +f 1093//1093 1083//1083 1094//1094
            +f 1094//1094 1083//1083 1095//1095
            +f 1095//1095 1083//1083 1096//1096
            +f 1096//1096 1083//1083 1097//1097
            +f 1097//1097 1083//1083 1098//1098
            +f 1098//1098 1083//1083 1099//1099
            +f 1099//1099 1083//1083 1100//1100
            +f 1100//1100 1083//1083 1101//1101
            +f 1101//1101 1083//1083 1102//1102
            +f 1102//1102 1083//1083 1103//1103
            +f 1103//1103 1083//1083 1104//1104
            +f 1104//1104 1083//1083 1105//1105
            +f 1105//1105 1083//1083 1106//1106
            +f 1106//1106 1083//1083 1082//1082
            +f 1107//1107 1108//1108 1084//1084
            +f 1082//1082 1084//1084 1108//1108
            +f 1109//1109 1110//1110 1108//1108
            +f 1108//1108 1107//1107 1109//1109
            +f 1111//1111 1112//1112 1110//1110
            +f 1110//1110 1109//1109 1111//1111
            +f 1113//1113 1114//1114 1112//1112
            +f 1112//1112 1111//1111 1113//1113
            +f 1115//1115 1107//1107 1085//1085
            +f 1084//1084 1085//1085 1107//1107
            +f 1116//1116 1109//1109 1107//1107
            +f 1107//1107 1115//1115 1116//1116
            +f 1117//1117 1111//1111 1109//1109
            +f 1109//1109 1116//1116 1117//1117
            +f 1118//1118 1113//1113 1111//1111
            +f 1111//1111 1117//1117 1118//1118
            +f 1119//1119 1115//1115 1086//1086
            +f 1085//1085 1086//1086 1115//1115
            +f 1120//1120 1116//1116 1115//1115
            +f 1115//1115 1119//1119 1120//1120
            +f 1121//1121 1117//1117 1116//1116
            +f 1116//1116 1120//1120 1121//1121
            +f 1122//1122 1118//1118 1117//1117
            +f 1117//1117 1121//1121 1122//1122
            +f 1123//1123 1119//1119 1086//1086
            +f 1086//1086 1087//1087 1123//1123
            +f 1124//1124 1120//1120 1123//1123
            +f 1119//1119 1123//1123 1120//1120
            +f 1125//1125 1121//1121 1124//1124
            +f 1120//1120 1124//1124 1121//1121
            +f 1126//1126 1122//1122 1125//1125
            +f 1121//1121 1125//1125 1122//1122
            +f 1127//1127 1123//1123 1087//1087
            +f 1087//1087 1088//1088 1127//1127
            +f 1128//1128 1124//1124 1127//1127
            +f 1123//1123 1127//1127 1124//1124
            +f 1129//1129 1125//1125 1128//1128
            +f 1124//1124 1128//1128 1125//1125
            +f 1130//1130 1126//1126 1129//1129
            +f 1125//1125 1129//1129 1126//1126
            +f 1131//1131 1127//1127 1088//1088
            +f 1088//1088 1089//1089 1131//1131
            +f 1132//1132 1128//1128 1131//1131
            +f 1127//1127 1131//1131 1128//1128
            +f 1133//1133 1129//1129 1132//1132
            +f 1128//1128 1132//1132 1129//1129
            +f 1134//1134 1130//1130 1133//1133
            +f 1129//1129 1133//1133 1130//1130
            +f 1135//1135 1131//1131 1090//1090
            +f 1089//1089 1090//1090 1131//1131
            +f 1136//1136 1132//1132 1131//1131
            +f 1131//1131 1135//1135 1136//1136
            +f 1137//1137 1133//1133 1132//1132
            +f 1132//1132 1136//1136 1137//1137
            +f 1138//1138 1134//1134 1133//1133
            +f 1133//1133 1137//1137 1138//1138
            +f 1139//1139 1135//1135 1091//1091
            +f 1090//1090 1091//1091 1135//1135
            +f 1140//1140 1136//1136 1135//1135
            +f 1135//1135 1139//1139 1140//1140
            +f 1141//1141 1137//1137 1136//1136
            +f 1136//1136 1140//1140 1141//1141
            +f 1142//1142 1138//1138 1137//1137
            +f 1137//1137 1141//1141 1142//1142
            +f 1143//1143 1139//1139 1092//1092
            +f 1091//1091 1092//1092 1139//1139
            +f 1144//1144 1140//1140 1139//1139
            +f 1139//1139 1143//1143 1144//1144
            +f 1145//1145 1141//1141 1140//1140
            +f 1140//1140 1144//1144 1145//1145
            +f 1146//1146 1142//1142 1141//1141
            +f 1141//1141 1145//1145 1146//1146
            +f 1147//1147 1143//1143 1092//1092
            +f 1092//1092 1093//1093 1147//1147
            +f 1148//1148 1144//1144 1147//1147
            +f 1143//1143 1147//1147 1144//1144
            +f 1149//1149 1145//1145 1148//1148
            +f 1144//1144 1148//1148 1145//1145
            +f 1150//1150 1146//1146 1149//1149
            +f 1145//1145 1149//1149 1146//1146
            +f 1151//1151 1147//1147 1093//1093
            +f 1093//1093 1094//1094 1151//1151
            +f 1152//1152 1148//1148 1151//1151
            +f 1147//1147 1151//1151 1148//1148
            +f 1153//1153 1149//1149 1152//1152
            +f 1148//1148 1152//1152 1149//1149
            +f 1154//1154 1150//1150 1153//1153
            +f 1149//1149 1153//1153 1150//1150
            +f 1155//1155 1151//1151 1094//1094
            +f 1094//1094 1095//1095 1155//1155
            +f 1156//1156 1152//1152 1155//1155
            +f 1151//1151 1155//1155 1152//1152
            +f 1157//1157 1153//1153 1156//1156
            +f 1152//1152 1156//1156 1153//1153
            +f 1158//1158 1154//1154 1157//1157
            +f 1153//1153 1157//1157 1154//1154
            +f 1159//1159 1155//1155 1096//1096
            +f 1095//1095 1096//1096 1155//1155
            +f 1160//1160 1156//1156 1155//1155
            +f 1155//1155 1159//1159 1160//1160
            +f 1161//1161 1157//1157 1156//1156
            +f 1156//1156 1160//1160 1161//1161
            +f 1162//1162 1158//1158 1157//1157
            +f 1157//1157 1161//1161 1162//1162
            +f 1163//1163 1159//1159 1097//1097
            +f 1096//1096 1097//1097 1159//1159
            +f 1164//1164 1160//1160 1159//1159
            +f 1159//1159 1163//1163 1164//1164
            +f 1165//1165 1161//1161 1160//1160
            +f 1160//1160 1164//1164 1165//1165
            +f 1166//1166 1162//1162 1161//1161
            +f 1161//1161 1165//1165 1166//1166
            +f 1167//1167 1163//1163 1098//1098
            +f 1097//1097 1098//1098 1163//1163
            +f 1168//1168 1164//1164 1163//1163
            +f 1163//1163 1167//1167 1168//1168
            +f 1169//1169 1165//1165 1164//1164
            +f 1164//1164 1168//1168 1169//1169
            +f 1170//1170 1166//1166 1165//1165
            +f 1165//1165 1169//1169 1170//1170
            +f 1171//1171 1167//1167 1098//1098
            +f 1098//1098 1099//1099 1171//1171
            +f 1172//1172 1168//1168 1171//1171
            +f 1167//1167 1171//1171 1168//1168
            +f 1173//1173 1169//1169 1172//1172
            +f 1168//1168 1172//1172 1169//1169
            +f 1174//1174 1170//1170 1173//1173
            +f 1169//1169 1173//1173 1170//1170
            +f 1175//1175 1171//1171 1099//1099
            +f 1099//1099 1100//1100 1175//1175
            +f 1176//1176 1172//1172 1175//1175
            +f 1171//1171 1175//1175 1172//1172
            +f 1177//1177 1173//1173 1176//1176
            +f 1172//1172 1176//1176 1173//1173
            +f 1178//1178 1174//1174 1177//1177
            +f 1173//1173 1177//1177 1174//1174
            +f 1179//1179 1175//1175 1100//1100
            +f 1100//1100 1101//1101 1179//1179
            +f 1180//1180 1176//1176 1179//1179
            +f 1175//1175 1179//1179 1176//1176
            +f 1181//1181 1177//1177 1180//1180
            +f 1176//1176 1180//1180 1177//1177
            +f 1182//1182 1178//1178 1181//1181
            +f 1177//1177 1181//1181 1178//1178
            +f 1183//1183 1179//1179 1102//1102
            +f 1101//1101 1102//1102 1179//1179
            +f 1184//1184 1180//1180 1179//1179
            +f 1179//1179 1183//1183 1184//1184
            +f 1185//1185 1181//1181 1180//1180
            +f 1180//1180 1184//1184 1185//1185
            +f 1186//1186 1182//1182 1181//1181
            +f 1181//1181 1185//1185 1186//1186
            +f 1187//1187 1183//1183 1103//1103
            +f 1102//1102 1103//1103 1183//1183
            +f 1188//1188 1184//1184 1183//1183
            +f 1183//1183 1187//1187 1188//1188
            +f 1189//1189 1185//1185 1184//1184
            +f 1184//1184 1188//1188 1189//1189
            +f 1190//1190 1186//1186 1185//1185
            +f 1185//1185 1189//1189 1190//1190
            +f 1191//1191 1187//1187 1104//1104
            +f 1103//1103 1104//1104 1187//1187
            +f 1192//1192 1188//1188 1187//1187
            +f 1187//1187 1191//1191 1192//1192
            +f 1193//1193 1189//1189 1188//1188
            +f 1188//1188 1192//1192 1193//1193
            +f 1194//1194 1190//1190 1189//1189
            +f 1189//1189 1193//1193 1194//1194
            +f 1195//1195 1191//1191 1104//1104
            +f 1104//1104 1105//1105 1195//1195
            +f 1196//1196 1192//1192 1195//1195
            +f 1191//1191 1195//1195 1192//1192
            +f 1197//1197 1193//1193 1196//1196
            +f 1192//1192 1196//1196 1193//1193
            +f 1198//1198 1194//1194 1197//1197
            +f 1193//1193 1197//1197 1194//1194
            +f 1199//1199 1195//1195 1105//1105
            +f 1105//1105 1106//1106 1199//1199
            +f 1200//1200 1196//1196 1199//1199
            +f 1195//1195 1199//1199 1196//1196
            +f 1201//1201 1197//1197 1200//1200
            +f 1196//1196 1200//1200 1197//1197
            +f 1202//1202 1198//1198 1201//1201
            +f 1197//1197 1201//1201 1198//1198
            +f 1108//1108 1199//1199 1106//1106
            +f 1106//1106 1082//1082 1108//1108
            +f 1110//1110 1200//1200 1108//1108
            +f 1199//1199 1108//1108 1200//1200
            +f 1112//1112 1201//1201 1110//1110
            +f 1200//1200 1110//1110 1201//1201
            +f 1114//1114 1202//1202 1112//1112
            +f 1201//1201 1112//1112 1202//1202
            diff --git a/dist/ko/reference/assets/test.txt b/dist/ko/reference/assets/test.txt
            new file mode 100644
            index 0000000000..9dc2445af3
            --- /dev/null
            +++ b/dist/ko/reference/assets/test.txt
            @@ -0,0 +1,6 @@
            +I am a cat
            +I like apples
            +I have three feet
            +I like my nose
            +I smell like butter
            +I talk like an orange
            \ No newline at end of file
            diff --git a/dist/ko/reference/assets/transformation-matrix.png b/dist/ko/reference/assets/transformation-matrix.png
            new file mode 100644
            index 0000000000..0d42542922
            Binary files /dev/null and b/dist/ko/reference/assets/transformation-matrix.png differ
            diff --git a/dist/ko/reference/data.json b/dist/ko/reference/data.json
            new file mode 100644
            index 0000000000..16f3ad430e
            --- /dev/null
            +++ b/dist/ko/reference/data.json
            @@ -0,0 +1,30598 @@
            +{
            +    "project": {
            +        "name": "p5",
            +        "description": "[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)",
            +        "version": "1.4.1",
            +        "url": "https://github.com/processing/p5.js#readme"
            +    },
            +    "files": {
            +        "src/accessibility/color_namer.js": {
            +            "name": "src/accessibility/color_namer.js",
            +            "modules": {
            +                "Environment": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/describe.js": {
            +            "name": "src/accessibility/describe.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/gridOutput.js": {
            +            "name": "src/accessibility/gridOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/outputs.js": {
            +            "name": "src/accessibility/outputs.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/textOutput.js": {
            +            "name": "src/accessibility/textOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/color_conversion.js": {
            +            "name": "src/color/color_conversion.js",
            +            "modules": {
            +                "Color Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/creating_reading.js": {
            +            "name": "src/color/creating_reading.js",
            +            "modules": {
            +                "Creating & Reading": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/p5.Color.js": {
            +            "name": "src/color/p5.Color.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/setting.js": {
            +            "name": "src/color/setting.js",
            +            "modules": {
            +                "Setting": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/fes_core.js": {
            +            "name": "src/core/friendly_errors/fes_core.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/file_errors.js": {
            +            "name": "src/core/friendly_errors/file_errors.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/sketch_reader.js": {
            +            "name": "src/core/friendly_errors/sketch_reader.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/stacktrace.js": {
            +            "name": "src/core/friendly_errors/stacktrace.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/validate_params.js": {
            +            "name": "src/core/friendly_errors/validate_params.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/2d_primitives.js": {
            +            "name": "src/core/shape/2d_primitives.js",
            +            "modules": {
            +                "2D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/attributes.js": {
            +            "name": "src/core/shape/attributes.js",
            +            "modules": {
            +                "Attributes": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/curves.js": {
            +            "name": "src/core/shape/curves.js",
            +            "modules": {
            +                "Curves": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/vertex.js": {
            +            "name": "src/core/shape/vertex.js",
            +            "modules": {
            +                "Vertex": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/constants.js": {
            +            "name": "src/core/constants.js",
            +            "modules": {
            +                "Constants": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/environment.js": {
            +            "name": "src/core/environment.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/helpers.js": {
            +            "name": "src/core/helpers.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/init.js": {
            +            "name": "src/core/init.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/internationalization.js": {
            +            "name": "src/core/internationalization.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/legacy.js": {
            +            "name": "src/core/legacy.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/main.js": {
            +            "name": "src/core/main.js",
            +            "modules": {
            +                "Structure": 1
            +            },
            +            "classes": {
            +                "p5": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Element.js": {
            +            "name": "src/core/p5.Element.js",
            +            "modules": {
            +                "DOM": 1
            +            },
            +            "classes": {
            +                "p5.Element": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Graphics.js": {
            +            "name": "src/core/p5.Graphics.js",
            +            "modules": {
            +                "Rendering": 1
            +            },
            +            "classes": {
            +                "p5.Graphics": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer.js": {
            +            "name": "src/core/p5.Renderer.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer2D.js": {
            +            "name": "src/core/p5.Renderer2D.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/reference.js": {
            +            "name": "src/core/reference.js",
            +            "modules": {
            +                "Foundation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/rendering.js": {
            +            "name": "src/core/rendering.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shim.js": {
            +            "name": "src/core/shim.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/structure.js": {
            +            "name": "src/core/structure.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/transform.js": {
            +            "name": "src/core/transform.js",
            +            "modules": {
            +                "Transform": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/local_storage.js": {
            +            "name": "src/data/local_storage.js",
            +            "modules": {
            +                "LocalStorage": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/p5.TypedDict.js": {
            +            "name": "src/data/p5.TypedDict.js",
            +            "modules": {
            +                "Dictionary": 1
            +            },
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/dom/dom.js": {
            +            "name": "src/dom/dom.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/acceleration.js": {
            +            "name": "src/events/acceleration.js",
            +            "modules": {
            +                "Acceleration": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/keyboard.js": {
            +            "name": "src/events/keyboard.js",
            +            "modules": {
            +                "Keyboard": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/mouse.js": {
            +            "name": "src/events/mouse.js",
            +            "modules": {
            +                "Mouse": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/touch.js": {
            +            "name": "src/events/touch.js",
            +            "modules": {
            +                "Touch": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/filters.js": {
            +            "name": "src/image/filters.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/image.js": {
            +            "name": "src/image/image.js",
            +            "modules": {
            +                "Image": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/loading_displaying.js": {
            +            "name": "src/image/loading_displaying.js",
            +            "modules": {
            +                "Loading & Displaying": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/p5.Image.js": {
            +            "name": "src/image/p5.Image.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/pixels.js": {
            +            "name": "src/image/pixels.js",
            +            "modules": {
            +                "Pixels": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/files.js": {
            +            "name": "src/io/files.js",
            +            "modules": {
            +                "Input": 1,
            +                "Output": 1
            +            },
            +            "classes": {
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/p5.Table.js": {
            +            "name": "src/io/p5.Table.js",
            +            "modules": {
            +                "Table": 1
            +            },
            +            "classes": {
            +                "p5.Table": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.TableRow.js": {
            +            "name": "src/io/p5.TableRow.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.XML.js": {
            +            "name": "src/io/p5.XML.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/calculation.js": {
            +            "name": "src/math/calculation.js",
            +            "modules": {
            +                "Calculation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/math.js": {
            +            "name": "src/math/math.js",
            +            "modules": {
            +                "Vector": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/noise.js": {
            +            "name": "src/math/noise.js",
            +            "modules": {
            +                "Noise": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/p5.Vector.js": {
            +            "name": "src/math/p5.Vector.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/random.js": {
            +            "name": "src/math/random.js",
            +            "modules": {
            +                "Random": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/trigonometry.js": {
            +            "name": "src/math/trigonometry.js",
            +            "modules": {
            +                "Trigonometry": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/attributes.js": {
            +            "name": "src/typography/attributes.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/loading_displaying.js": {
            +            "name": "src/typography/loading_displaying.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/p5.Font.js": {
            +            "name": "src/typography/p5.Font.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/utilities/array_functions.js": {
            +            "name": "src/utilities/array_functions.js",
            +            "modules": {
            +                "Array Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/conversion.js": {
            +            "name": "src/utilities/conversion.js",
            +            "modules": {
            +                "Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/string_functions.js": {
            +            "name": "src/utilities/string_functions.js",
            +            "modules": {
            +                "String Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/time_date.js": {
            +            "name": "src/utilities/time_date.js",
            +            "modules": {
            +                "Time & Date": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/3d_primitives.js": {
            +            "name": "src/webgl/3d_primitives.js",
            +            "modules": {
            +                "3D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/interaction.js": {
            +            "name": "src/webgl/interaction.js",
            +            "modules": {
            +                "Interaction": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/light.js": {
            +            "name": "src/webgl/light.js",
            +            "modules": {
            +                "Lights": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/loading.js": {
            +            "name": "src/webgl/loading.js",
            +            "modules": {
            +                "3D Models": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/material.js": {
            +            "name": "src/webgl/material.js",
            +            "modules": {
            +                "Material": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Camera.js": {
            +            "name": "src/webgl/p5.Camera.js",
            +            "modules": {
            +                "Camera": 1
            +            },
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Geometry.js": {
            +            "name": "src/webgl/p5.Geometry.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Matrix.js": {
            +            "name": "src/webgl/p5.Matrix.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Matrix": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RenderBuffer.js": {
            +            "name": "src/webgl/p5.RenderBuffer.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Immediate.js": {
            +            "name": "src/webgl/p5.RendererGL.Immediate.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Retained.js": {
            +            "name": "src/webgl/p5.RendererGL.Retained.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.js": {
            +            "name": "src/webgl/p5.RendererGL.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.RendererGL": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Shader.js": {
            +            "name": "src/webgl/p5.Shader.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Shader": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Texture.js": {
            +            "name": "src/webgl/p5.Texture.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/text.js": {
            +            "name": "src/webgl/text.js",
            +            "modules": {},
            +            "classes": {
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.js": {
            +            "name": "lib/addons/p5.sound.js",
            +            "modules": {
            +                "p5.sound": 1
            +            },
            +            "classes": {
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.min.js": {
            +            "name": "lib/addons/p5.sound.min.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        }
            +    },
            +    "modules": {
            +        "Environment": {
            +            "name": "Environment",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Environment",
            +            "file": "src/accessibility/color_namer.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Color": {
            +            "name": "Color",
            +            "submodules": {
            +                "Color Conversion": 1,
            +                "Creating & Reading": 1,
            +                "Setting": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/color/p5.Color.js",
            +            "line": 14
            +        },
            +        "Color Conversion": {
            +            "name": "Color Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/color_conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Creating & Reading": {
            +            "name": "Creating & Reading",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ],
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"
            +        },
            +        "Setting": {
            +            "name": "Setting",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/setting.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Shape": {
            +            "name": "Shape",
            +            "submodules": {
            +                "2D Primitives": 1,
            +                "Curves": 1,
            +                "Vertex": 1,
            +                "3D Primitives": 1,
            +                "3D Models": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1,
            +                "p5.Matrix": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/p5.Matrix.js",
            +            "line": 19
            +        },
            +        "2D Primitives": {
            +            "name": "2D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Attributes": {
            +            "name": "Attributes",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/core/shape/attributes.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Curves": {
            +            "name": "Curves",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/curves.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vertex": {
            +            "name": "Vertex",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Constants": {
            +            "name": "Constants",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Constants",
            +            "file": "src/core/constants.js",
            +            "line": 1
            +        },
            +        "Structure": {
            +            "name": "Structure",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "IO",
            +            "file": "src/core/main.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ]
            +        },
            +        "DOM": {
            +            "name": "DOM",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Element": 1,
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "DOM",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n",
            +            "requires": [
            +                "p5"
            +            ]
            +        },
            +        "Rendering": {
            +            "name": "Rendering",
            +            "submodules": {
            +                "undefined": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.RendererGL": 1,
            +                "p5.Graphics": 1,
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Rendering",
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 603,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"
            +        },
            +        "Foundation": {
            +            "name": "Foundation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {},
            +            "module": "Foundation",
            +            "file": "src/core/reference.js",
            +            "line": 1
            +        },
            +        "Transform": {
            +            "name": "Transform",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Transform",
            +            "file": "src/core/transform.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Data": {
            +            "name": "Data",
            +            "submodules": {
            +                "LocalStorage": 1,
            +                "Dictionary": 1,
            +                "Array Functions": 1,
            +                "Conversion": 1,
            +                "String Functions": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.TypedDict": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410
            +        },
            +        "LocalStorage": {
            +            "name": "LocalStorage",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/local_storage.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for working with local storage"
            +            ]
            +        },
            +        "Dictionary": {
            +            "name": "Dictionary",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."
            +            ],
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"
            +        },
            +        "Events": {
            +            "name": "Events",
            +            "submodules": {
            +                "Acceleration": 1,
            +                "Keyboard": 1,
            +                "Mouse": 1,
            +                "Touch": 1
            +            },
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "Acceleration": {
            +            "name": "Acceleration",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/acceleration.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Keyboard": {
            +            "name": "Keyboard",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/keyboard.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Mouse": {
            +            "name": "Mouse",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/mouse.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Touch": {
            +            "name": "Touch",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/touch.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Image": {
            +            "name": "Image",
            +            "submodules": {
            +                "Pixels": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Image",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"
            +        },
            +        "Loading & Displaying": {
            +            "name": "Loading & Displaying",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"
            +        },
            +        "Pixels": {
            +            "name": "Pixels",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Image",
            +            "namespace": "",
            +            "file": "src/image/pixels.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "IO": {
            +            "name": "IO",
            +            "submodules": {
            +                "Structure": 1,
            +                "Input": 1,
            +                "Output": 1,
            +                "Table": 1,
            +                "Time & Date": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1,
            +                "p5.Table": 1,
            +                "p5.TableRow": 1,
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/io/p5.XML.js",
            +            "line": 9
            +        },
            +        "Input": {
            +            "name": "Input",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"
            +        },
            +        "Output": {
            +            "name": "Output",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"
            +        },
            +        "Table": {
            +            "name": "Table",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Table": 1,
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"
            +        },
            +        "Math": {
            +            "name": "Math",
            +            "submodules": {
            +                "Calculation": 1,
            +                "Vector": 1,
            +                "Noise": 1,
            +                "Random": 1,
            +                "Trigonometry": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10
            +        },
            +        "Calculation": {
            +            "name": "Calculation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/calculation.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vector": {
            +            "name": "Vector",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"
            +        },
            +        "Noise": {
            +            "name": "Noise",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/noise.js",
            +            "line": 14,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Random": {
            +            "name": "Random",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/random.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Trigonometry": {
            +            "name": "Trigonometry",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/trigonometry.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Typography": {
            +            "name": "Typography",
            +            "submodules": {
            +                "Attributes": 1,
            +                "Loading & Displaying": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13
            +        },
            +        "Array Functions": {
            +            "name": "Array Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/array_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Conversion": {
            +            "name": "Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "String Functions": {
            +            "name": "String Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/string_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Time & Date": {
            +            "name": "Time & Date",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/utilities/time_date.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Primitives": {
            +            "name": "3D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ],
            +            "description": "<p>p5 Geometry class</p>\n"
            +        },
            +        "3D": {
            +            "name": "3D",
            +            "submodules": {
            +                "Interaction": 1,
            +                "Lights": 1,
            +                "Material": 1,
            +                "Camera": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1,
            +                "p5.Shader": 1,
            +                "p5.Texture": 1,
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/text.js",
            +            "line": 260
            +        },
            +        "Interaction": {
            +            "name": "Interaction",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/interaction.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Lights": {
            +            "name": "Lights",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/light.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Models": {
            +            "name": "3D Models",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/loading.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ]
            +        },
            +        "Material": {
            +            "name": "Material",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Shader": 1,
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Texture.js",
            +            "line": 12,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the p5.Shader class</p>\n"
            +        },
            +        "Camera": {
            +            "name": "Camera",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.sound": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {},
            +            "module": "p5.sound",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>",
            +            "tag": "main",
            +            "itemtype": "main"
            +        }
            +    },
            +    "classes": {
            +        "p5": {
            +            "name": "p5",
            +            "shortname": "p5",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/core/main.js",
            +            "line": 13,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>element to attach canvas to</p>\n",
            +                    "type": "HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a p5 instance",
            +                "type": "P5"
            +            }
            +        },
            +        "p5.Color": {
            +            "name": "p5.Color",
            +            "shortname": "p5.Color",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Element": {
            +            "name": "p5.Element",
            +            "shortname": "p5.Element",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/core/p5.Element.js",
            +            "line": 9,
            +            "description": "<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Graphics": {
            +            "name": "p5.Graphics",
            +            "shortname": "p5.Graphics",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 10,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>the renderer to use, either P2D or WEBGL</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Renderer": {
            +            "name": "p5.Renderer",
            +            "shortname": "p5.Renderer",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 10,
            +            "description": "<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isMainCanvas",
            +                    "description": "<p>whether we're using it as main canvas</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "JSON": {
            +            "name": "JSON",
            +            "shortname": "JSON",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "console": {
            +            "name": "console",
            +            "shortname": "console",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "p5.TypedDict": {
            +            "name": "p5.TypedDict",
            +            "shortname": "p5.TypedDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 82,
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.StringDict": {
            +            "name": "p5.StringDict",
            +            "shortname": "p5.StringDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 394,
            +            "description": "<p>A simple Dictionary class for Strings.</p>\n",
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.NumberDict": {
            +            "name": "p5.NumberDict",
            +            "shortname": "p5.NumberDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "description": "<p>A simple Dictionary class for Numbers.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.MediaElement": {
            +            "name": "p5.MediaElement",
            +            "shortname": "p5.MediaElement",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 2377,
            +            "description": "<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.File": {
            +            "name": "p5.File",
            +            "shortname": "p5.File",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>File that is wrapped</p>\n",
            +                    "type": "File"
            +                }
            +            ]
            +        },
            +        "p5.Image": {
            +            "name": "p5.Image",
            +            "shortname": "p5.Image",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Image",
            +            "submodule": "Image",
            +            "namespace": "",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"
            +            ],
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ]
            +        },
            +        "p5.PrintWriter": {
            +            "name": "p5.PrintWriter",
            +            "shortname": "p5.PrintWriter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Table": {
            +            "name": "p5.Table",
            +            "shortname": "p5.Table",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.Table.js",
            +            "line": 33,
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "rows",
            +                    "description": "<p>An array of p5.TableRow objects</p>\n",
            +                    "type": "p5.TableRow[]",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TableRow": {
            +            "name": "p5.TableRow",
            +            "shortname": "p5.TableRow",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "description": "<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>comma separated values (csv) by default</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.XML": {
            +            "name": "p5.XML",
            +            "shortname": "p5.XML",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Input",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed"
            +        },
            +        "p5.Vector": {
            +            "name": "p5.Vector",
            +            "shortname": "p5.Vector",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "2 white ellipses. One center-left the other bottom right and off canvas"
            +        },
            +        "p5.Font": {
            +            "name": "p5.Font",
            +            "shortname": "p5.Font",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "description": "<p>Base class for font handling</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Camera": {
            +            "name": "p5.Camera",
            +            "shortname": "p5.Camera",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Camera",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n",
            +            "params": [
            +                {
            +                    "name": "rendererGL",
            +                    "description": "<p>instance of WebGL renderer</p>\n",
            +                    "type": "RendererGL"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes."
            +        },
            +        "p5.Geometry": {
            +            "name": "p5.Geometry",
            +            "shortname": "p5.Geometry",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Shape",
            +            "submodule": "3D Primitives",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "description": "<p>p5 Geometry class</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of vertices along the x-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of vertices along the y-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call upon object instantiation.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Shader": {
            +            "name": "p5.Shader",
            +            "shortname": "p5.Shader",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Material",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 11,
            +            "description": "<p>Shader class for WEBGL Mode</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n",
            +                    "type": "p5.RendererGL"
            +                },
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader (as a string)</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader (as a string)</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "shortname": "p5.sound",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": ""
            +        },
            +        "p5.SoundFile": {
            +            "name": "p5.SoundFile",
            +            "shortname": "p5.SoundFile",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1405,
            +            "description": "<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoadingCallback",
            +                    "description": "<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"
            +            ]
            +        },
            +        "p5.Amplitude": {
            +            "name": "p5.Amplitude",
            +            "shortname": "p5.Amplitude",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3022,
            +            "description": "<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.FFT": {
            +            "name": "p5.FFT",
            +            "shortname": "p5.FFT",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3347,
            +            "description": "<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Oscillator": {
            +            "name": "p5.Oscillator",
            +            "shortname": "p5.Oscillator",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4060,
            +            "description": "<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>frequency defaults to 440Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"
            +            ]
            +        },
            +        "p5.SinOsc": {
            +            "name": "p5.SinOsc",
            +            "shortname": "p5.SinOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4602,
            +            "description": "<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TriOsc": {
            +            "name": "p5.TriOsc",
            +            "shortname": "p5.TriOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4629,
            +            "description": "<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SawOsc": {
            +            "name": "p5.SawOsc",
            +            "shortname": "p5.SawOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4656,
            +            "description": "<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SqrOsc": {
            +            "name": "p5.SqrOsc",
            +            "shortname": "p5.SqrOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4683,
            +            "description": "<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Envelope": {
            +            "name": "p5.Envelope",
            +            "shortname": "p5.Envelope",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4721,
            +            "description": "<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Noise": {
            +            "name": "p5.Noise",
            +            "shortname": "p5.Noise",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5620,
            +            "description": "<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.Pulse": {
            +            "name": "p5.Pulse",
            +            "shortname": "p5.Pulse",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5779,
            +            "description": "<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in oscillations per second (Hz)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioIn": {
            +            "name": "p5.AudioIn",
            +            "shortname": "p5.AudioIn",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6015,
            +            "description": "<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Effect": {
            +            "name": "p5.Effect",
            +            "shortname": "p5.Effect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6423,
            +            "description": "<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "ac",
            +                    "description": "<p>Reference to the audio context of the p5 object</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "input",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "output",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "_drywet",
            +                    "description": "<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "wet",
            +                    "description": "<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Filter": {
            +            "name": "p5.Filter",
            +            "shortname": "p5.Filter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6628,
            +            "description": "<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.LowPass": {
            +            "name": "p5.LowPass",
            +            "shortname": "p5.LowPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6914,
            +            "description": "<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.HighPass": {
            +            "name": "p5.HighPass",
            +            "shortname": "p5.HighPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6938,
            +            "description": "<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.BandPass": {
            +            "name": "p5.BandPass",
            +            "shortname": "p5.BandPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6962,
            +            "description": "<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.EQ": {
            +            "name": "p5.EQ",
            +            "shortname": "p5.EQ",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7105,
            +            "description": "<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect",
            +            "params": [
            +                {
            +                    "name": "_eqsize",
            +                    "description": "<p>Constructor will accept 3 or 8, defaults to 3</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "p5.EQ object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Panner3D": {
            +            "name": "p5.Panner3D",
            +            "shortname": "p5.Panner3D",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7602,
            +            "description": "<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Delay": {
            +            "name": "p5.Delay",
            +            "shortname": "p5.Delay",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7926,
            +            "description": "<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Reverb": {
            +            "name": "p5.Reverb",
            +            "shortname": "p5.Reverb",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8308,
            +            "description": "<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Convolver": {
            +            "name": "p5.Convolver",
            +            "shortname": "p5.Convolver",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8549,
            +            "description": "<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when loading succeeds</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Phrase": {
            +            "name": "p5.Phrase",
            +            "shortname": "p5.Phrase",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9103,
            +            "description": "<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>Name so that you can access the Phrase.</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Part": {
            +            "name": "p5.Part",
            +            "shortname": "p5.Part",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9185,
            +            "description": "<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "steps",
            +                    "description": "<p>Steps in the part</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tatums",
            +                    "description": "<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Score": {
            +            "name": "p5.Score",
            +            "shortname": "p5.Score",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9493,
            +            "description": "<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "parts",
            +                    "description": "<p>One or multiple parts, to be played in sequence.</p>\n",
            +                    "type": "p5.Part",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ]
            +        },
            +        "p5.SoundLoop": {
            +            "name": "p5.SoundLoop",
            +            "shortname": "p5.SoundLoop",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9673,
            +            "description": "<p>SoundLoop</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>this function will be called on each iteration of theloop</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "interval",
            +                    "description": "<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n",
            +                    "type": "Number|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Compressor": {
            +            "name": "p5.Compressor",
            +            "shortname": "p5.Compressor",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10036,
            +            "description": "<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect"
            +        },
            +        "p5.PeakDetect": {
            +            "name": "p5.PeakDetect",
            +            "shortname": "p5.PeakDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10312,
            +            "description": "<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq1",
            +                    "description": "<p>lowFrequency - defaults to 20Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "freq2",
            +                    "description": "<p>highFrequency - defaults to 20000 Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "framesPerPeak",
            +                    "description": "<p>Defaults to 20.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.SoundRecorder": {
            +            "name": "p5.SoundRecorder",
            +            "shortname": "p5.SoundRecorder",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10559,
            +            "description": "<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"
            +            ]
            +        },
            +        "p5.Distortion": {
            +            "name": "p5.Distortion",
            +            "shortname": "p5.Distortion",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10816,
            +            "description": "<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ]
            +        },
            +        "p5.Gain": {
            +            "name": "p5.Gain",
            +            "shortname": "p5.Gain",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10973,
            +            "description": "<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioVoice": {
            +            "name": "p5.AudioVoice",
            +            "shortname": "p5.AudioVoice",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11149,
            +            "description": "<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.MonoSynth": {
            +            "name": "p5.MonoSynth",
            +            "shortname": "p5.MonoSynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11247,
            +            "description": "<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.OnsetDetect": {
            +            "name": "p5.OnsetDetect",
            +            "shortname": "p5.OnsetDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11624,
            +            "description": "<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freqLow",
            +                    "description": "<p>Low frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "freqHigh",
            +                    "description": "<p>High frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Function to call when an onset is detected</p>\n",
            +                    "type": "Function"
            +                }
            +            ]
            +        },
            +        "p5.PolySynth": {
            +            "name": "p5.PolySynth",
            +            "shortname": "p5.PolySynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "synthVoice",
            +                    "description": "<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "maxVoices",
            +                    "description": "<p>Number of voices, defaults to 8;</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ]
            +        }
            +    },
            +    "elements": {},
            +    "classitems": [
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 18,
            +            "description": "<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describe",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the canvas</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 114,
            +            "description": "<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describeElement",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 10,
            +            "description": "<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "textOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 88,
            +            "description": "<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "gridOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 8,
            +            "description": "<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 19,
            +            "description": "<p>Convert an HSBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 45,
            +            "description": "<p>Convert an HSBA array to RGBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 100,
            +            "description": "<p>Convert an HSLA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 123,
            +            "description": "<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 187,
            +            "description": "<p>Convert an RGBA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 226,
            +            "description": "<p>Convert an RGBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 16,
            +            "description": "<p>Extracts the alpha value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "alpha",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the alpha value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 43,
            +            "description": "<p>Extracts the blue value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "blue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the blue value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 69,
            +            "description": "<p>Extracts the HSB brightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "brightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the brightness value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 113,
            +            "description": "<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n",
            +            "itemtype": "method",
            +            "name": "color",
            +            "return": {
            +                "description": "resulting color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "overloads": [
            +                {
            +                    "line": 113,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "resulting color",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 257,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 269,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 282,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 297,
            +            "description": "<p>Extracts the green value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "green",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the green value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 325,
            +            "description": "<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n",
            +            "itemtype": "method",
            +            "name": "hue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the hue",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 359,
            +            "description": "<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerpColor",
            +            "params": [
            +                {
            +                    "name": "c1",
            +                    "description": "<p>interpolate from this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "c2",
            +                    "description": "<p>interpolate to this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "interpolated color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 449,
            +            "description": "<p>Extracts the HSL lightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "lightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the lightness",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 478,
            +            "description": "<p>Extracts the red value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "red",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the red value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 517,
            +            "description": "<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n",
            +            "itemtype": "method",
            +            "name": "saturation",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the saturation value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 51,
            +            "description": "<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "params": [
            +                {
            +                    "name": "format",
            +                    "description": "<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the formatted string",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 254,
            +            "description": "<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRed",
            +            "params": [
            +                {
            +                    "name": "red",
            +                    "description": "<p>the new red value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 281,
            +            "description": "<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setGreen",
            +            "params": [
            +                {
            +                    "name": "green",
            +                    "description": "<p>the new green value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 304,
            +            "description": "<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBlue",
            +            "params": [
            +                {
            +                    "name": "blue",
            +                    "description": "<p>the new blue value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 327,
            +            "description": "<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAlpha",
            +            "params": [
            +                {
            +                    "name": "alpha",
            +                    "description": "<p>the new alpha value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 396,
            +            "description": "<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 427,
            +            "description": "<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 446,
            +            "description": "<p>CSS named colors.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 600,
            +            "description": "<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 613,
            +            "description": "<p>Full color string patterns. The capture groups are necessary.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 960,
            +            "description": "<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 13,
            +            "description": "<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n",
            +            "itemtype": "method",
            +            "name": "background",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "colorstring",
            +                            "description": "<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 140,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>specifies a value between white and black</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 147,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current color\n                       mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 159,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 166,
            +                    "params": [
            +                        {
            +                            "name": "image",
            +                            "description": "<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 179,
            +            "description": "<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"
            +            ],
            +            "params": [
            +                {
            +                    "name": "r",
            +                    "description": "<p>normalized red val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "g",
            +                    "description": "<p>normalized green val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>normalized blue val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>normalized alpha val.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 229,
            +            "description": "<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n",
            +            "itemtype": "method",
            +            "name": "colorMode",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 229,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>range for all values</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 306,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max1",
            +                            "description": "<p>range for the red or hue depending on the\n                             current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max2",
            +                            "description": "<p>range for the green or saturation depending\n                             on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max3",
            +                            "description": "<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "maxA",
            +                            "description": "<p>range for the alpha</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 350,
            +            "description": "<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n",
            +            "itemtype": "method",
            +            "name": "fill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 350,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 475,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 488,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 495,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the fill color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 507,
            +            "description": "<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noFill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 547,
            +            "description": "<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noStroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 585,
            +            "description": "<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n",
            +            "itemtype": "method",
            +            "name": "stroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 585,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 722,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 728,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 735,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 742,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the stroke color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 755,
            +            "description": "<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n",
            +            "itemtype": "method",
            +            "name": "erase",
            +            "params": [
            +                {
            +                    "name": "strengthFill",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "strengthStroke",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 836,
            +            "description": "<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "noErase",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis is the main file for the Friendly Error System (FES)",
            +                "containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters",
            +                "(2) _friendlyFileLoadError",
            +                "(3) _friendlyError",
            +                "(4) helpForMisusedAtTopLevelCode",
            +                "or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this",
            +                "there's also a file stacktrace.js",
            +                "which contains the code\nto parse the error stack",
            +                "borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions",
            +                "including the call\nsequence of each function",
            +                "please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 915,
            +            "description": "<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n",
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/file_errors.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/sketch_reader.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/stacktrace.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/validate_params.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 16,
            +            "description": "<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 102,
            +            "description": "<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n",
            +            "itemtype": "method",
            +            "name": "arc",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>angle to start the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>angle to stop the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "mode",
            +                    "description": "<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detail",
            +                    "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 235,
            +            "description": "<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipse",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 235,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the ellipse.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 261,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detail",
            +                            "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 277,
            +            "description": "<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n",
            +            "itemtype": "method",
            +            "name": "circle",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>diameter of the circle.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 340,
            +            "description": "<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "line",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 340,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 404,
            +            "description": "<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "point",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 404,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z-coordinate (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 455,
            +                    "params": [
            +                        {
            +                            "name": "coordinate_vector",
            +                            "description": "<p>the coordinate vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 483,
            +            "description": "<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "quad",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 483,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>the x-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>the y-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>the x-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>the y-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>the z-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>the z-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 556,
            +            "description": "<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "rect",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 556,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the rectangle.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tl",
            +                            "description": "<p>optional radius of top-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tr",
            +                            "description": "<p>optional radius of top-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "br",
            +                            "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "bl",
            +                            "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 608,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 623,
            +            "description": "<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "square",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "s",
            +                    "description": "<p>side size of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "tl",
            +                    "description": "<p>optional radius of top-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tr",
            +                    "description": "<p>optional radius of top-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "br",
            +                    "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bl",
            +                    "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 713,
            +            "description": "<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n",
            +            "itemtype": "method",
            +            "name": "triangle",
            +            "params": [
            +                {
            +                    "name": "x1",
            +                    "description": "<p>x-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y1",
            +                    "description": "<p>y-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>x-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>y-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x3",
            +                    "description": "<p>x-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y3",
            +                    "description": "<p>y-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 12,
            +            "description": "<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipseMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 81,
            +            "description": "<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "noSmooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses to left & right of center, black background",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 115,
            +            "description": "<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "rectMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 184,
            +            "description": "<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses one left one right of center. On black.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 219,
            +            "description": "<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeCap",
            +            "params": [
            +                {
            +                    "name": "cap",
            +                    "description": "<p>either ROUND, SQUARE or PROJECT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 259,
            +            "description": "<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeJoin",
            +            "params": [
            +                {
            +                    "name": "join",
            +                    "description": "<p>either MITER, BEVEL, ROUND</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 331,
            +            "description": "<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeWeight",
            +            "params": [
            +                {
            +                    "name": "weight",
            +                    "description": "<p>the weight of the stroke (in pixels)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"
            +            ],
            +            "alt": "3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 13,
            +            "description": "<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezier",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 62,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 92,
            +            "description": "<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierDetail",
            +            "params": [
            +                {
            +                    "name": "detail",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape with a low level of bezier detail",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 130,
            +            "description": "<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierPoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value of the Bezier at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "10 points plotted on a given bezier at equal distances.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 185,
            +            "description": "<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 264,
            +            "description": "<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curve",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 264,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 332,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 358,
            +            "description": "<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveDetail",
            +            "params": [
            +                {
            +                    "name": "resolution",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white arch shape with a low level of curve detail.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 398,
            +            "description": "<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTightness",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>amount of deformation from the original vertices</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Line shaped like right-facing arrow,points move with mouse-x and warp shape.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 444,
            +            "description": "<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "curvePoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point of the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "bezier value at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 493,
            +            "description": "<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second conrol point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "right curving line mid-right of canvas with 7 short lines radiating from it.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 20,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 67,
            +            "description": "<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginShape",
            +            "params": [
            +                {
            +                    "name": "kind",
            +                    "description": "<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 293,
            +            "description": "<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 375,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 415,
            +            "description": "<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Upside-down u-shape line, mid canvas. left point extends beyond canvas view.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 415,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 460,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 524,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "endContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 583,
            +            "description": "<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n",
            +            "itemtype": "method",
            +            "name": "endShape",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>use CLOSE to close the shape</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Triangle line shape with smallest interior angle on bottom and upside-down L.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 668,
            +            "description": "<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "quadraticVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 668,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "<p>x-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "<p>y-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 733,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cz",
            +                            "description": "<p>z-coordinate for the control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 826,
            +            "description": "<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "vertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 826,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 957,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 965,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "u",
            +                            "description": "<p>the vertex's texture u-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vertex's texture v-coordinate</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1003,
            +            "description": "<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n",
            +            "itemtype": "method",
            +            "name": "normal",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 1003,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>A p5.Vector representing the vertex normal.</p>\n",
            +                            "type": "Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1040,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The x component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The y component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The z component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 9,
            +            "description": "<p>Version of this p5.js.</p>\n",
            +            "itemtype": "property",
            +            "name": "VERSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 18,
            +            "description": "<p>The default, two-dimensional renderer.</p>\n",
            +            "itemtype": "property",
            +            "name": "P2D",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 24,
            +            "description": "<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n",
            +            "itemtype": "property",
            +            "name": "WEBGL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 33,
            +            "itemtype": "property",
            +            "name": "ARROW",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 38,
            +            "itemtype": "property",
            +            "name": "CROSS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 43,
            +            "itemtype": "property",
            +            "name": "HAND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 48,
            +            "itemtype": "property",
            +            "name": "MOVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 53,
            +            "itemtype": "property",
            +            "name": "TEXT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 58,
            +            "itemtype": "property",
            +            "name": "WAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 66,
            +            "description": "<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HALF_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white quarter-circle with curve toward bottom right of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 84,
            +            "description": "<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"
            +            ],
            +            "alt": "white half-circle with curve toward bottom of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 102,
            +            "description": "<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "QUARTER_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"
            +            ],
            +            "alt": "white eighth-circle rotated about 40 degrees with curve bottom right canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 120,
            +            "description": "<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TAU",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 138,
            +            "description": "<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TWO_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 156,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n",
            +            "itemtype": "property",
            +            "name": "DEGREES",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 170,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n",
            +            "itemtype": "property",
            +            "name": "RADIANS",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 188,
            +            "itemtype": "property",
            +            "name": "CORNER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 193,
            +            "itemtype": "property",
            +            "name": "CORNERS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 198,
            +            "itemtype": "property",
            +            "name": "RADIUS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 203,
            +            "itemtype": "property",
            +            "name": "RIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 208,
            +            "itemtype": "property",
            +            "name": "LEFT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 213,
            +            "itemtype": "property",
            +            "name": "CENTER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 218,
            +            "itemtype": "property",
            +            "name": "TOP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 223,
            +            "itemtype": "property",
            +            "name": "BOTTOM",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 228,
            +            "itemtype": "property",
            +            "name": "BASELINE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "alphabetic",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 234,
            +            "itemtype": "property",
            +            "name": "POINTS",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0000",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 240,
            +            "itemtype": "property",
            +            "name": "LINES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0001",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 246,
            +            "itemtype": "property",
            +            "name": "LINE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0003",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 252,
            +            "itemtype": "property",
            +            "name": "LINE_LOOP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0002",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 258,
            +            "itemtype": "property",
            +            "name": "TRIANGLES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0004",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 264,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_FAN",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0006",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 270,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0005",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 276,
            +            "itemtype": "property",
            +            "name": "QUADS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 281,
            +            "itemtype": "property",
            +            "name": "QUAD_STRIP",
            +            "type": "String",
            +            "final": 1,
            +            "default": "quad_strip",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 287,
            +            "itemtype": "property",
            +            "name": "TESS",
            +            "type": "String",
            +            "final": 1,
            +            "default": "tess",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 293,
            +            "itemtype": "property",
            +            "name": "CLOSE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 298,
            +            "itemtype": "property",
            +            "name": "OPEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 303,
            +            "itemtype": "property",
            +            "name": "CHORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 308,
            +            "itemtype": "property",
            +            "name": "PIE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 313,
            +            "itemtype": "property",
            +            "name": "PROJECT",
            +            "type": "String",
            +            "final": 1,
            +            "default": "square",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 319,
            +            "itemtype": "property",
            +            "name": "SQUARE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "butt",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 325,
            +            "itemtype": "property",
            +            "name": "ROUND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 330,
            +            "itemtype": "property",
            +            "name": "BEVEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 335,
            +            "itemtype": "property",
            +            "name": "MITER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 342,
            +            "itemtype": "property",
            +            "name": "RGB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 347,
            +            "description": "<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HSB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 356,
            +            "itemtype": "property",
            +            "name": "HSL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 363,
            +            "description": "<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n",
            +            "itemtype": "property",
            +            "name": "AUTO",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 373,
            +            "itemtype": "property",
            +            "name": "ALT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 379,
            +            "itemtype": "property",
            +            "name": "BACKSPACE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 384,
            +            "itemtype": "property",
            +            "name": "CONTROL",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 389,
            +            "itemtype": "property",
            +            "name": "DELETE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 394,
            +            "itemtype": "property",
            +            "name": "DOWN_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 399,
            +            "itemtype": "property",
            +            "name": "ENTER",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 404,
            +            "itemtype": "property",
            +            "name": "ESCAPE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 409,
            +            "itemtype": "property",
            +            "name": "LEFT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 414,
            +            "itemtype": "property",
            +            "name": "OPTION",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 419,
            +            "itemtype": "property",
            +            "name": "RETURN",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 424,
            +            "itemtype": "property",
            +            "name": "RIGHT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 429,
            +            "itemtype": "property",
            +            "name": "SHIFT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 434,
            +            "itemtype": "property",
            +            "name": "TAB",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 439,
            +            "itemtype": "property",
            +            "name": "UP_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 446,
            +            "itemtype": "property",
            +            "name": "BLEND",
            +            "type": "String",
            +            "final": 1,
            +            "default": "source-over",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 452,
            +            "itemtype": "property",
            +            "name": "REMOVE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "destination-out",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 458,
            +            "itemtype": "property",
            +            "name": "ADD",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighter",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 466,
            +            "itemtype": "property",
            +            "name": "DARKEST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 471,
            +            "itemtype": "property",
            +            "name": "LIGHTEST",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighten",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 477,
            +            "itemtype": "property",
            +            "name": "DIFFERENCE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 482,
            +            "itemtype": "property",
            +            "name": "SUBTRACT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 487,
            +            "itemtype": "property",
            +            "name": "EXCLUSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 492,
            +            "itemtype": "property",
            +            "name": "MULTIPLY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 497,
            +            "itemtype": "property",
            +            "name": "SCREEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 502,
            +            "itemtype": "property",
            +            "name": "REPLACE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "copy",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 508,
            +            "itemtype": "property",
            +            "name": "OVERLAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 513,
            +            "itemtype": "property",
            +            "name": "HARD_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 518,
            +            "itemtype": "property",
            +            "name": "SOFT_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 523,
            +            "itemtype": "property",
            +            "name": "DODGE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-dodge",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 529,
            +            "itemtype": "property",
            +            "name": "BURN",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-burn",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 537,
            +            "itemtype": "property",
            +            "name": "THRESHOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 542,
            +            "itemtype": "property",
            +            "name": "GRAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 547,
            +            "itemtype": "property",
            +            "name": "OPAQUE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 552,
            +            "itemtype": "property",
            +            "name": "INVERT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 557,
            +            "itemtype": "property",
            +            "name": "POSTERIZE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 562,
            +            "itemtype": "property",
            +            "name": "DILATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 567,
            +            "itemtype": "property",
            +            "name": "ERODE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 572,
            +            "itemtype": "property",
            +            "name": "BLUR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 579,
            +            "itemtype": "property",
            +            "name": "NORMAL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 584,
            +            "itemtype": "property",
            +            "name": "ITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 589,
            +            "itemtype": "property",
            +            "name": "BOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 594,
            +            "itemtype": "property",
            +            "name": "BOLDITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 599,
            +            "itemtype": "property",
            +            "name": "CHAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 604,
            +            "itemtype": "property",
            +            "name": "WORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 616,
            +            "itemtype": "property",
            +            "name": "LINEAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 621,
            +            "itemtype": "property",
            +            "name": "QUADRATIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 626,
            +            "itemtype": "property",
            +            "name": "BEZIER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 631,
            +            "itemtype": "property",
            +            "name": "CURVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 638,
            +            "itemtype": "property",
            +            "name": "STROKE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 643,
            +            "itemtype": "property",
            +            "name": "FILL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 648,
            +            "itemtype": "property",
            +            "name": "TEXTURE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 653,
            +            "itemtype": "property",
            +            "name": "IMMEDIATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 661,
            +            "itemtype": "property",
            +            "name": "IMAGE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 669,
            +            "itemtype": "property",
            +            "name": "NEAREST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 674,
            +            "itemtype": "property",
            +            "name": "REPEAT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 679,
            +            "itemtype": "property",
            +            "name": "CLAMP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 684,
            +            "itemtype": "property",
            +            "name": "MIRROR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 691,
            +            "itemtype": "property",
            +            "name": "LANDSCAPE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 696,
            +            "itemtype": "property",
            +            "name": "PORTRAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 706,
            +            "itemtype": "property",
            +            "name": "GRID",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 712,
            +            "itemtype": "property",
            +            "name": "AXES",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 718,
            +            "itemtype": "property",
            +            "name": "LABEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 723,
            +            "itemtype": "property",
            +            "name": "FALLBACK",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 20,
            +            "description": "<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "contents",
            +                    "description": "<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"
            +            ],
            +            "alt": "default grey canvas",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 52,
            +            "description": "<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n",
            +            "itemtype": "property",
            +            "name": "frameCount",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "numbers rapidly counting upward with frame count set to 30.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 79,
            +            "description": "<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n",
            +            "itemtype": "property",
            +            "name": "deltaTime",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 129,
            +            "description": "<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "focused",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "green 50×50 ellipse at top left. Red X covers canvas when page focus changes",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 160,
            +            "description": "<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n",
            +            "itemtype": "method",
            +            "name": "cursor",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n",
            +                    "type": "String|Constant"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>the horizontal active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>the vertical active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 228,
            +            "description": "<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n",
            +            "itemtype": "method",
            +            "name": "frameRate",
            +            "chainable": 1,
            +            "example": [
            +                "\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "blue rect moves left to right, followed by red rect moving faster. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 228,
            +                    "params": [
            +                        {
            +                            "name": "fps",
            +                            "description": "<p>number of frames to be displayed every second</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 288,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current frameRate",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 331,
            +            "description": "<p>Hides the cursor from view.</p>\n",
            +            "itemtype": "method",
            +            "name": "noCursor",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "cursor becomes 10×10 white ellipse the moves with mouse x and y.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 354,
            +            "description": "<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 372,
            +            "description": "<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 390,
            +            "description": "<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 405,
            +            "description": "<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 421,
            +            "description": "<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n",
            +            "itemtype": "method",
            +            "name": "windowResized",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional Event callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 476,
            +            "description": "<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 488,
            +            "description": "<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 500,
            +            "description": "<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n",
            +            "itemtype": "method",
            +            "name": "fullscreen",
            +            "params": [
            +                {
            +                    "name": "val",
            +                    "description": "<p>whether the sketch should be in fullscreen mode\nor not</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "current fullscreen state",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 550,
            +            "description": "<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "pixelDensity",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 550,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>whether or how much the sketch should scale</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 586,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current pixel density of the sketch",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 605,
            +            "description": "<p>Returns the pixel density of the current display the sketch is running on.</p>\n",
            +            "itemtype": "method",
            +            "name": "displayDensity",
            +            "return": {
            +                "description": "current pixel density of the display",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 660,
            +            "description": "<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURL",
            +            "return": {
            +                "description": "url",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "current url (http://p5js.org/reference/#/p5/getURL) moves right to left.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 691,
            +            "description": "<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLPath",
            +            "return": {
            +                "description": "path components",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 713,
            +            "description": "<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLParams",
            +            "return": {
            +                "description": "URL params",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/helpers.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 30,
            +            "description": "<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 126,
            +            "description": "<p>Set up our translation function, with loaded languages</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 171,
            +            "description": "<p>Returns a list of languages we have translations loaded for</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 178,
            +            "description": "<p>Returns the current language selected for translation</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 185,
            +            "description": "<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/legacy.js",
            +            "line": 1,
            +            "requires": [
            +                "core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name",
            +                "in others",
            +                "they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 42,
            +            "description": "<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "preload",
            +            "example": [
            +                "\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 83,
            +            "description": "<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setup",
            +            "example": [
            +                "\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 114,
            +            "description": "<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "draw",
            +            "example": [
            +                "\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 415,
            +            "description": "<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 693,
            +            "description": "<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "disableFriendlyErrors",
            +            "type": "Boolean",
            +            "example": [
            +                "\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 21,
            +            "description": "<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "elt",
            +            "readonly": "",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 47,
            +            "description": "<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "parent",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 47,
            +                    "params": [
            +                        {
            +                            "name": "parent",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n",
            +                            "type": "String|p5.Element|Object"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 93,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 114,
            +            "description": "<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n",
            +            "itemtype": "method",
            +            "name": "id",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 114,
            +                    "params": [
            +                        {
            +                            "name": "id",
            +                            "description": "<p>ID of the element</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the id of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 154,
            +            "description": "<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "class",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 154,
            +                    "params": [
            +                        {
            +                            "name": "class",
            +                            "description": "<p>class to add</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the class of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 189,
            +            "description": "<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 246,
            +            "description": "<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 292,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 354,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 403,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 454,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 510,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 551,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOut",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 592,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 639,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 678,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 725,
            +            "description": "<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 763,
            +            "description": "<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragLeave",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 827,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 70,
            +            "description": "<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 122,
            +            "description": "<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image\na multi-colored circle moving back and forth over a scrolling background.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 99,
            +            "description": "<p>Resize our canvas element.</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 415,
            +            "description": "<p>Helper function to check font type (system or otf)</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 467,
            +            "description": "<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 7,
            +            "description": "<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 402,
            +            "description": "<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 7,
            +            "description": "<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n",
            +            "itemtype": "property",
            +            "name": "let",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 34,
            +            "description": "<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n",
            +            "itemtype": "property",
            +            "name": "const",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"
            +            ],
            +            "alt": "These examples do not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 87,
            +            "description": "<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n",
            +            "itemtype": "property",
            +            "name": "===",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 115,
            +            "description": "<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>",
            +            "itemtype": "property",
            +            "name": ">",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 137,
            +            "description": "<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": ">=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 158,
            +            "description": "<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 179,
            +            "description": "<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 200,
            +            "description": "<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n",
            +            "itemtype": "property",
            +            "name": "if-else",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 231,
            +            "description": "<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n",
            +            "itemtype": "property",
            +            "name": "function",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 267,
            +            "description": "<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "return",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 288,
            +            "description": "<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n",
            +            "itemtype": "property",
            +            "name": "boolean",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 309,
            +            "description": "<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n",
            +            "itemtype": "property",
            +            "name": "string",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 331,
            +            "description": "<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n",
            +            "itemtype": "property",
            +            "name": "number",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 351,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n",
            +            "itemtype": "property",
            +            "name": "object",
            +            "example": [
            +                "\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 379,
            +            "description": "<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n",
            +            "itemtype": "property",
            +            "name": "class",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 408,
            +            "description": "<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n",
            +            "itemtype": "property",
            +            "name": "for",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 448,
            +            "description": "<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n",
            +            "itemtype": "property",
            +            "name": "while",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 490,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "stringify",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>:Javascript object that you would like to convert to JSON</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "JSON",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 512,
            +            "description": "<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "message",
            +                    "description": "<p>:Message that you would like to print to the console</p>\n",
            +                    "type": "String|Expression|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "console",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 15,
            +            "description": "<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Renderer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Black line extending from top-left of canvas to bottom right.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 125,
            +            "description": "<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "resizeCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "noRedraw",
            +                    "description": "<p>don't redraw the canvas immediately</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "No image displayed.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 183,
            +            "description": "<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n",
            +            "itemtype": "method",
            +            "name": "noCanvas",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 204,
            +            "description": "<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "createGraphics",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "offscreen graphics buffer",
            +                "type": "p5.Graphics"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 grey squares alternating light and dark grey. White quarter circle mid-left.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 243,
            +            "description": "<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n",
            +            "itemtype": "method",
            +            "name": "blendMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"
            +            ],
            +            "alt": "translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 326,
            +            "description": "<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n",
            +            "itemtype": "property",
            +            "name": "drawingContext",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white ellipse with shadow blur effect around edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 18,
            +            "description": "<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 39,
            +            "description": "<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 10,
            +            "description": "<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 83,
            +            "description": "<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "example": [
            +                "\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 134,
            +            "description": "<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "example": [
            +                "\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 192,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "push",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 290,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "pop",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 391,
            +            "description": "<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n",
            +            "itemtype": "method",
            +            "name": "redraw",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>Redraw for n-times. The default value is 1.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black line on far left of canvas\nblack line on far left of canvas",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 497,
            +            "description": "<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "p5",
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a function containing a p5.js sketch</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>ID or pointer to HTML DOM node to contain sketch in</p>\n",
            +                    "type": "String|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"
            +            ],
            +            "alt": "white rectangle on black background",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 11,
            +            "description": "<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n",
            +            "itemtype": "method",
            +            "name": "applyMatrix",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n",
            +                    "type": "Number|Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "f",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 168,
            +            "description": "<p>Replaces the current matrix with the identity matrix.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetMatrix",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"
            +            ],
            +            "alt": "A rotated rectangle in the center with another at the top left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 193,
            +            "description": "<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "axis",
            +                    "description": "<p>(in 3d) the axis to rotate around</p>\n",
            +                    "type": "p5.Vector|Number[]",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 232,
            +            "description": "<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the x axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 268,
            +            "description": "<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the y axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 304,
            +            "description": "<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateZ",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the z axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 342,
            +            "description": "<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 342,
            +                    "params": [
            +                        {
            +                            "name": "s",
            +                            "description": "<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n",
            +                            "type": "Number|p5.Vector|Number[]"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>percent to scale the object in the y-axis</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>percent to scale the object in the z-axis (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 386,
            +                    "params": [
            +                        {
            +                            "name": "scales",
            +                            "description": "<p>per-axis percents to scale the object</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 416,
            +            "description": "<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at top middle.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 455,
            +            "description": "<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at middle bottom.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 494,
            +            "description": "<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "translate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 494,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>left/right translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>up/down translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>forward/backward translation (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>the vector to translate by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 10,
            +            "description": "<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n",
            +            "itemtype": "method",
            +            "name": "storeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"
            +            ],
            +            "alt": "When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 101,
            +            "description": "<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "getItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>name that you wish to use to store in local storage</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Value of stored item",
            +                "type": "Number|Object|String|Boolean|p5.Color|p5.Vector"
            +            },
            +            "example": [
            +                "\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"
            +            ],
            +            "alt": "If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 177,
            +            "description": "<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearStorage",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 205,
            +            "description": "<p>Removes an item that was stored with storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "removeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 14,
            +            "description": "<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createStringDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.StringDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 14,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                },
            +                {
            +                    "line": 37,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 48,
            +            "description": "<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createNumberDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.NumberDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 48,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 101,
            +            "description": "<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the number of key-value pairs in the Dictionary",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 122,
            +            "description": "<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasKey",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>that you want to look up</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether that key exists in Dictionary",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 144,
            +            "description": "<p>Returns the value stored at the given key.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>key you want to access</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value stored at that key",
            +                "type": "Number|String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 170,
            +            "description": "<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 197,
            +            "description": "<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 208,
            +            "description": "<p>Creates a new key-value pair in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "create",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 208,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 226,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>key/value pair</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 244,
            +            "description": "<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 265,
            +            "description": "<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>for the pair to remove</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 294,
            +            "description": "<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 318,
            +            "description": "<p>Converts the Dictionary into a CSV file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 356,
            +            "description": "<p>Converts the Dictionary into a JSON file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 387,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 425,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 432,
            +            "description": "<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to add to</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to add to the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 459,
            +            "description": "<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to subtract from</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to subtract from the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 482,
            +            "description": "<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to multiply</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to multiply the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 509,
            +            "description": "<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to divide</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to divide the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 536,
            +            "description": "<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 560,
            +            "description": "<p>Return the lowest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 580,
            +            "description": "<p>Return the highest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 600,
            +            "description": "<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 622,
            +            "description": "<p>Return the lowest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 642,
            +            "description": "<p>Return the highest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 21,
            +            "description": "<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "select",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of element to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Element\">p5.Element</a> containing node found",
            +                "type": "p5.Element|null"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 68,
            +            "description": "<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "selectAll",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of elements to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found",
            +                "type": "p5.Element[]"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 127,
            +            "description": "<p>Helper function for select and selectAll</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 142,
            +            "description": "<p>Helper function for getElement and getElements.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 176,
            +            "description": "<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeElements",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 204,
            +            "description": "<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "changed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 271,
            +            "description": "<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "input",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 309,
            +            "description": "<p>Helpers for create methods.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 322,
            +            "description": "<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createDiv",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 341,
            +            "description": "<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createP",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 361,
            +            "description": "<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSpan",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 379,
            +            "description": "<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImg",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>src path or url for image</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 396,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "crossOrigin",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 426,
            +            "description": "<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n",
            +            "itemtype": "method",
            +            "name": "createA",
            +            "params": [
            +                {
            +                    "name": "href",
            +                    "description": "<p>url of page to link to</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner html of link element to display</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "target",
            +                    "description": "<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 450,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 452,
            +            "description": "<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSlider",
            +            "params": [
            +                {
            +                    "name": "min",
            +                    "description": "<p>minimum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "max",
            +                    "description": "<p>maximum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>default value of the slider</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "step",
            +                    "description": "<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 507,
            +            "description": "<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n",
            +            "itemtype": "method",
            +            "name": "createButton",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed on the button</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the button</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 541,
            +            "description": "<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n",
            +            "itemtype": "method",
            +            "name": "createCheckbox",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed after checkbox</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the checkbox; checked is true, unchecked is false</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 622,
            +            "description": "<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createSelect",
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "multiple",
            +                            "description": "<p>true if dropdown should support multiple selections</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 673,
            +                    "params": [
            +                        {
            +                            "name": "existing",
            +                            "description": "<p>DOM select element</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 770,
            +            "description": "<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createRadio",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 770,
            +                    "params": [
            +                        {
            +                            "name": "containerElement",
            +                            "description": "<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "name",
            +                            "description": "<p>A name parameter for each Input Element.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 832,
            +                    "params": [
            +                        {
            +                            "name": "name",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 837,
            +                    "params": [],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 978,
            +            "description": "<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n",
            +            "itemtype": "method",
            +            "name": "createColorPicker",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>default color of element</p>\n",
            +                    "type": "String|p5.Color",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1066,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n",
            +            "itemtype": "method",
            +            "name": "createInput",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1066,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>default value of the input box</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "type",
            +                            "description": "<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1104,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "createFileInput",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function for when a file is loaded</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "multiple",
            +                    "description": "<p>optional, to allow multiple files to be selected</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1164,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1211,
            +            "description": "<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVideo",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n",
            +                    "type": "String|String[]"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1257,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1259,
            +            "description": "<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createAudio",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n",
            +                    "type": "String|String[]",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1296,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1298,
            +            "itemtype": "property",
            +            "name": "VIDEO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1304,
            +            "itemtype": "property",
            +            "name": "AUDIO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1341,
            +            "description": "<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCapture",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n",
            +                    "type": "String|Constant|Object"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be called once\n                                  stream has loaded</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1478,
            +            "description": "<p>Creates element with given tag in the DOM with given content.</p>\n",
            +            "itemtype": "method",
            +            "name": "createElement",
            +            "params": [
            +                {
            +                    "name": "tag",
            +                    "description": "<p>tag for the new element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "content",
            +                    "description": "<p>html content to be inserted into the element</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1504,
            +            "description": "<p>Adds specified class to the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "addClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to add</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1529,
            +            "description": "<p>Removes specified class from the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1560,
            +            "description": "<p>Checks if specified class already set to element</p>\n",
            +            "itemtype": "method",
            +            "name": "hasClass",
            +            "return": {
            +                "description": "a boolean value if element has specified class",
            +                "type": "Boolean"
            +            },
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name of class to check</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1589,
            +            "description": "<p>Toggles element class</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleClass",
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name to toggle</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1622,
            +            "description": "<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "child",
            +            "return": {
            +                "description": "an array of child nodes",
            +                "type": "Node[]"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1622,
            +                    "params": [],
            +                    "return": {
            +                        "description": "an array of child nodes",
            +                        "type": "Node[]"
            +                    }
            +                },
            +                {
            +                    "line": 1650,
            +                    "params": [
            +                        {
            +                            "name": "child",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n",
            +                            "type": "String|p5.Element",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1675,
            +            "description": "<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n",
            +            "itemtype": "method",
            +            "name": "center",
            +            "params": [
            +                {
            +                    "name": "align",
            +                    "description": "<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1726,
            +            "description": "<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "html",
            +            "return": {
            +                "description": "the inner HTML of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1726,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the inner HTML of the element",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1747,
            +                    "params": [
            +                        {
            +                            "name": "html",
            +                            "description": "<p>the HTML to be placed inside the element</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "append",
            +                            "description": "<p>whether to append HTML to existing</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1765,
            +            "description": "<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n",
            +            "itemtype": "method",
            +            "name": "position",
            +            "return": {
            +                "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1765,
            +                    "params": [],
            +                    "return": {
            +                        "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 1798,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "positionType",
            +                            "description": "<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1885,
            +            "description": "<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n",
            +            "itemtype": "method",
            +            "name": "style",
            +            "return": {
            +                "description": "value of property",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1885,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "<p>property to be set</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "value of property",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1923,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to property</p>\n",
            +                            "type": "String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1,
            +                    "return": {
            +                        "description": "current value of property, if no value is given as second argument",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1980,
            +            "description": "<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n",
            +            "itemtype": "method",
            +            "name": "attribute",
            +            "return": {
            +                "description": "value of attribute",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1980,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of attribute",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1995,
            +                    "params": [
            +                        {
            +                            "name": "attr",
            +                            "description": "<p>attribute to set</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to attribute</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2024,
            +            "description": "<p>Removes an attribute on the specified element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeAttribute",
            +            "params": [
            +                {
            +                    "name": "attr",
            +                    "description": "<p>attribute to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2069,
            +            "description": "<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "value",
            +            "return": {
            +                "description": "value of the element",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2069,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of the element",
            +                        "type": "String|Number"
            +                    }
            +                },
            +                {
            +                    "line": 2099,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2115,
            +            "description": "<p>Shows the current element. Essentially, setting display:block for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "show",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2133,
            +            "description": "<p>Hides the current element. Essentially, setting display:none for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "hide",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2149,
            +            "description": "<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the width and height of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2149,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the width and height of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 2173,
            +                    "params": [
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2230,
            +            "description": "<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2268,
            +            "description": "<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n",
            +            "itemtype": "method",
            +            "name": "drop",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to receive loaded file, called for each file dropped.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>callback triggered once when files are dropped with the drop event.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"
            +            ],
            +            "alt": "Canvas turns into whatever image is dragged/dropped onto it.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2400,
            +            "description": "<p>Path to the media element source.</p>\n",
            +            "itemtype": "property",
            +            "name": "src",
            +            "return": {
            +                "description": "src",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2466,
            +            "description": "<p>Play an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2530,
            +            "description": "<p>Stops an HTML5 media element (sets current time to zero).</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2594,
            +            "description": "<p>Pauses an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2656,
            +            "description": "<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2712,
            +            "description": "<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2778,
            +            "description": "<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n",
            +            "itemtype": "method",
            +            "name": "autoplay",
            +            "params": [
            +                {
            +                    "name": "shouldAutoplay",
            +                    "description": "<p>whether the element should autoplay</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2845,
            +            "description": "<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n",
            +            "itemtype": "method",
            +            "name": "volume",
            +            "return": {
            +                "description": "current volume",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2845,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current volume",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2918,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>volume between 0.0 and 1.0</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2931,
            +            "description": "<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n",
            +            "itemtype": "method",
            +            "name": "speed",
            +            "return": {
            +                "description": "current playback speed of the element",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2931,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current playback speed of the element",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3003,
            +                    "params": [
            +                        {
            +                            "name": "speed",
            +                            "description": "<p>speed multiplier for element playback</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3020,
            +            "description": "<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n",
            +            "itemtype": "method",
            +            "name": "time",
            +            "return": {
            +                "description": "current time (in seconds)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 3020,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current time (in seconds)",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3065,
            +                    "params": [
            +                        {
            +                            "name": "time",
            +                            "description": "<p>time to jump to (in seconds)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3079,
            +            "description": "<p>Returns the duration of the HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "duration",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3201,
            +            "description": "<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3232,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3234,
            +            "description": "<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "audioNode",
            +                    "description": "<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n",
            +                    "type": "AudioNode|Object"
            +                }
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3283,
            +            "description": "<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3298,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3300,
            +            "description": "<p>Show the default MediaElement controls, as determined by the web browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "showControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3331,
            +            "description": "<p>Hide the default mediaElement controls.</p>\n",
            +            "itemtype": "method",
            +            "name": "hideControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3360,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3371,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3434,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3476,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3542,
            +            "description": "<p>Underlying File object. All normal File methods can be called on this.</p>\n",
            +            "itemtype": "property",
            +            "name": "file",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3554,
            +            "description": "<p>File type (image, text, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "type",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3560,
            +            "description": "<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "subtype",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3566,
            +            "description": "<p>File name</p>\n",
            +            "itemtype": "property",
            +            "name": "name",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3572,
            +            "description": "<p>File size</p>\n",
            +            "itemtype": "property",
            +            "name": "size",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3579,
            +            "description": "<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n",
            +            "itemtype": "property",
            +            "name": "data",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 11,
            +            "description": "<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n",
            +            "itemtype": "property",
            +            "name": "deviceOrientation",
            +            "type": "Constant",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 23,
            +            "description": "<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 46,
            +            "description": "<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 69,
            +            "description": "<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 94,
            +            "description": "<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 104,
            +            "description": "<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 114,
            +            "description": "<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 135,
            +            "description": "<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 168,
            +            "description": "<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 201,
            +            "description": "<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "rotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 239,
            +            "description": "<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 285,
            +            "description": "<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 330,
            +            "description": "<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 389,
            +            "description": "<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n",
            +            "itemtype": "property",
            +            "name": "turnAxis",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 428,
            +            "description": "<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMoveThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 471,
            +            "description": "<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n",
            +            "itemtype": "method",
            +            "name": "setShakeThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 515,
            +            "description": "<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceMoved",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 546,
            +            "description": "<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceTurned",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 604,
            +            "description": "<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceShaken",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device shakes",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 10,
            +            "description": "<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect that turns black on keypress.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 36,
            +            "description": "<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n",
            +            "itemtype": "property",
            +            "name": "key",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"
            +            ],
            +            "alt": "canvas displays any key value that is pressed in pink font.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 64,
            +            "description": "<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyCode",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"
            +            ],
            +            "alt": "Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 103,
            +            "description": "<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyPressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 190,
            +            "description": "<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when pressed again",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 243,
            +            "description": "<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyTyped",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when 'a' key typed and black when 'b' pressed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 298,
            +            "description": "<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 308,
            +            "description": "<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyIsDown",
            +            "params": [
            +                {
            +                    "name": "code",
            +                    "description": "<p>The key to check for.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether key is down or not",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 12,
            +            "description": "<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"
            +            ],
            +            "alt": "box moves left and right according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 43,
            +            "description": "<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "box moves up and down according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 80,
            +            "description": "<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal black line moves left and right with mouse x-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 106,
            +            "description": "<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black line moves up and down with mouse y-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 132,
            +            "description": "<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "line trail is created from cursor movements. faster movement make longer line.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 164,
            +            "description": "<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect center, fuchsia background. rect flickers on mouse movement",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 195,
            +            "description": "<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 233,
            +            "description": "<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 271,
            +            "description": "<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 311,
            +            "description": "<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 351,
            +            "description": "<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseButton",
            +            "type": "Constant",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 389,
            +            "description": "<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 481,
            +            "description": "<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 535,
            +            "description": "<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseDragged",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 615,
            +            "description": "<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 696,
            +            "description": "<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 772,
            +            "description": "<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 841,
            +            "description": "<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 926,
            +            "description": "<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional WheelEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect moves up and down with vertical scroll. fuchsia background",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 979,
            +            "description": "<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n",
            +            "itemtype": "method",
            +            "name": "requestPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3D scene moves according to mouse mouse movement in a first person perspective",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 1025,
            +            "description": "<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n",
            +            "itemtype": "method",
            +            "name": "exitPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "cursor gets locked / unlocked on mouse-click",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 10,
            +            "description": "<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n",
            +            "itemtype": "property",
            +            "name": "touches",
            +            "type": "Object[]",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Number of touches currently registered are displayed on the canvas",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 71,
            +            "description": "<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch event.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 151,
            +            "description": "<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns lighter with touch until white. resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 223,
            +            "description": "<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/image/filters.js",
            +            "line": 3,
            +            "description": "<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n",
            +            "class": "p5",
            +            "module": "Events"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 8,
            +            "description": "<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 15,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImage",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width in pixels</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height in pixels</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 94,
            +            "description": "<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveCanvas",
            +            "example": [
            +                "\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed\n no image displayed\n no image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 94,
            +                    "params": [
            +                        {
            +                            "name": "selectedCanvas",
            +                            "description": "<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n",
            +                            "type": "p5.Element|HTMLCanvasElement"
            +                        },
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "<p>'jpg' or 'png'</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 413,
            +            "description": "<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveFrames",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'jpg' or 'png'</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Duration in seconds to save the frames for.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "framerate",
            +                    "description": "<p>Framerate to save the frames in.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n",
            +                    "type": "Function(Array)",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"
            +            ],
            +            "alt": "canvas background goes from light to dark with mouse x.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 18,
            +            "description": "<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadImage",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path of the image to be loaded</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n",
            +                    "type": "function(p5.Image)",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "failureCallback",
            +                    "description": "<p>called with event error if\n                               the image fails to load.</p>\n",
            +                    "type": "Function(Event)",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 162,
            +            "description": "<p>Helper function for loading GIF-based images</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 301,
            +            "description": "<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n",
            +            "itemtype": "method",
            +            "name": "image",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 301,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "<p>the image to display</p>\n",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "width",
            +                            "description": "<p>the width to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "height",
            +                            "description": "<p>the height to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 388,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dWidth",
            +                            "description": "<p>the width of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dHeight",
            +                            "description": "<p>the height of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sWidth",
            +                            "description": "<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "sHeight",
            +                            "description": "<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 471,
            +            "description": "<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n",
            +            "itemtype": "method",
            +            "name": "tint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 471,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 542,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 553,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 559,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the tint color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 569,
            +            "description": "<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n",
            +            "itemtype": "method",
            +            "name": "noTint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of bricks, left image with blue tint",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 633,
            +            "description": "<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n",
            +            "itemtype": "method",
            +            "name": "imageMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, or CENTER</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 9,
            +            "description": "<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 88,
            +            "description": "<p>Image width.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains in top and horizontal lines in corresponding colors in bottom.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 115,
            +            "description": "<p>Image height.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains on right and vertical lines in corresponding colors on left.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 152,
            +            "description": "<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 222,
            +            "description": "<p>Helper function for animating GIF-based images with time</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 253,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 261,
            +            "description": "<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 296,
            +            "description": "<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 296,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 338,
            +                    "params": []
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 346,
            +            "description": "<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with 50×50 green rect in front",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 346,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 383,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 387,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 400,
            +            "description": "<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"
            +            ],
            +            "alt": "2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 437,
            +            "description": "<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n",
            +            "itemtype": "method",
            +            "name": "resize",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>the resized image width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>the resized image height</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. zoomed in",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 548,
            +            "description": "<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains and smaller image on top of bricks at top left",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 548,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 588,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 603,
            +            "description": "<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mask",
            +            "params": [
            +                {
            +                    "name": "srcImage",
            +                    "description": "<p>source image</p>\n",
            +                    "type": "p5.Image"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 665,
            +            "description": "<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains left one in color, right in black and white",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 738,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 738,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 815,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 859,
            +            "description": "<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>give your file a name</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'png' or 'jpg'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 900,
            +            "description": "<p>Starts an animated GIF over at the beginning state.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 941,
            +            "description": "<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "getCurrentFrame",
            +            "return": {
            +                "description": "The index for the currently displaying frame in animated GIF",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 972,
            +            "description": "<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "setFrame",
            +            "params": [
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index for the frame that should be displayed</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1017,
            +            "description": "<p>Returns the number of frames in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "numFrames",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1052,
            +            "description": "<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1089,
            +            "description": "<p>Pauses an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1125,
            +            "description": "<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n",
            +            "itemtype": "method",
            +            "name": "delay",
            +            "params": [
            +                {
            +                    "name": "d",
            +                    "description": "<p>the amount in milliseconds to delay between switching frames</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index of the frame that should have the new delay value {optional}</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 12,
            +            "description": "<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"
            +            ],
            +            "alt": "top half of canvas pink, bottom grey",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 80,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 80,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 152,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 173,
            +            "description": "<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 173,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 215,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 307,
            +            "description": "<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 481,
            +            "description": "<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 551,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 555,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 566,
            +            "description": "<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 602,
            +            "description": "<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 674,
            +            "description": "<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 20,
            +            "description": "<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadJSON",
            +            "return": {
            +                "description": "JSON data",
            +                "type": "Object|Array"
            +            },
            +            "example": [
            +                "\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 20,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "jsonpOptions",
            +                            "description": "<p>options object for jsonp related settings</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\" or \"jsonp\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "JSON data",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 104,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 112,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 183,
            +            "description": "<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadStrings",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 303,
            +            "description": "<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadTable",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "header",
            +                    "description": "<p>\"header\" to indicate table has header row</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Table\">Table</a> object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 583,
            +            "description": "<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadXML",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "XML object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 693,
            +            "description": "<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadBytes",
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if there\n                                   is an error</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an object whose 'bytes' property will be the loaded buffer",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 752,
            +            "description": "<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n",
            +            "itemtype": "method",
            +            "name": "httpGet",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 752,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 806,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 814,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 829,
            +            "description": "<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpPost",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 896,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 904,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 919,
            +            "description": "<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpDo",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 919,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "method",
            +                            "description": "<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 990,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "options",
            +                            "description": "<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1155,
            +            "itemtype": "method",
            +            "name": "createWriter",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the file to be created</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.PrintWriter"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1210,
            +            "description": "<p>Writes data to the PrintWriter stream</p>\n",
            +            "itemtype": "method",
            +            "name": "write",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be written by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1269,
            +            "description": "<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be printed by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1310,
            +            "description": "<p>Clears the data already written to the PrintWriter object</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1344,
            +            "description": "<p>Closes the PrintWriter</p>\n",
            +            "itemtype": "method",
            +            "name": "close",
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1393,
            +            "description": "<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "objectOrFilename",
            +                    "description": "<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n",
            +                    "type": "Object|String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n",
            +                    "type": "Boolean|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"
            +            ],
            +            "alt": "An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1535,
            +            "description": "<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "params": [
            +                {
            +                    "name": "json",
            +                    "description": "",
            +                    "type": "Array|Object"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "optimize",
            +                    "description": "<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1592,
            +            "description": "<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveStrings",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>string array to be written</p>\n",
            +                    "type": "String[]"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>filename for output</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>the filename's extension</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isCRLF",
            +                    "description": "<p>if true, change line-break to CRLF</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1656,
            +            "description": "<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "params": [
            +                {
            +                    "name": "Table",
            +                    "description": "<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n",
            +                    "type": "p5.Table"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>the filename to which the Table should be saved</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 9,
            +            "description": "<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 43,
            +            "description": "<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n",
            +            "itemtype": "property",
            +            "name": "columns",
            +            "type": "String[]",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 77,
            +            "description": "<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n",
            +            "itemtype": "property",
            +            "name": "rows",
            +            "type": "p5.TableRow[]",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 85,
            +            "description": "<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n",
            +            "itemtype": "method",
            +            "name": "addRow",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row to be added to the table</p>\n",
            +                    "type": "p5.TableRow",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the row that was added",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 148,
            +            "description": "<p>Removes a row from the table object.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeRow",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID number of the row to remove</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 195,
            +            "description": "<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRow",
            +            "params": [
            +                {
            +                    "name": "rowID",
            +                    "description": "<p>ID number of the row to get</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 240,
            +            "description": "<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRows",
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 288,
            +            "description": "<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRow",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 352,
            +            "description": "<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRows",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 420,
            +            "description": "<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRow",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String|RegExp"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "TableRow object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 478,
            +            "description": "<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRows",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 545,
            +            "description": "<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>String or Number of the column to return</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of column values",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 597,
            +            "description": "<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearRows",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 638,
            +            "description": "<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n",
            +            "itemtype": "method",
            +            "name": "addColumn",
            +            "params": [
            +                {
            +                    "name": "title",
            +                    "description": "<p>title of the given column</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 688,
            +            "description": "<p>Returns the total number of columns in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumnCount",
            +            "return": {
            +                "description": "Number of columns in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 724,
            +            "description": "<p>Returns the total number of rows in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRowCount",
            +            "return": {
            +                "description": "Number of rows in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 760,
            +            "description": "<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeTokens",
            +            "params": [
            +                {
            +                    "name": "chars",
            +                    "description": "<p>String listing characters to be removed</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 832,
            +            "description": "<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 896,
            +            "description": "<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 960,
            +            "description": "<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1009,
            +            "description": "<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1055,
            +            "description": "<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1100,
            +            "description": "<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1146,
            +            "description": "<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1190,
            +            "description": "<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1242,
            +            "description": "<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getObject",
            +            "params": [
            +                {
            +                    "name": "headerColumn",
            +                    "description": "<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1305,
            +            "description": "<p>Retrieves all table data and returns it as a multidimensional array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getArray",
            +            "return": {
            +                "description": "",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 40,
            +            "description": "<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 102,
            +            "description": "<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a Float</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 146,
            +            "description": "<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a String</p>\n",
            +                    "type": "String|Number|Boolean|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 191,
            +            "description": "<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 239,
            +            "description": "<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "Float Floating point number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 295,
            +            "description": "<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 62,
            +            "description": "<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "getParent",
            +            "return": {
            +                "description": "element parent",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 100,
            +            "description": "<p>Gets the element's full name, which is returned as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "getName",
            +            "return": {
            +                "description": "the name of the node",
            +                "type": "String"
            +            },
            +            "example": [
            +                "&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 135,
            +            "description": "<p>Sets the element's name, which is specified as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "setName",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>new name of the node</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 181,
            +            "description": "<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasChildren",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 217,
            +            "description": "<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "listChildren",
            +            "return": {
            +                "description": "names of the children of the element",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 258,
            +            "description": "<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChildren",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "children of the element",
            +                "type": "p5.XML[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 314,
            +            "description": "<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 374,
            +            "description": "<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "addChild",
            +            "params": [
            +                {
            +                    "name": "node",
            +                    "description": "<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n",
            +                    "type": "p5.XML"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 426,
            +            "description": "<p>Removes the element specified by name or index.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 498,
            +            "description": "<p>Counts the specified element's number of attributes, returned as an Number.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAttributeCount",
            +            "return": {
            +                "description": "",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 534,
            +            "description": "<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n",
            +            "itemtype": "method",
            +            "name": "listAttributes",
            +            "return": {
            +                "description": "an array of strings containing the names of attributes",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 577,
            +            "description": "<p>Checks whether or not an element has the specified attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasAttribute",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>attribute to be checked</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "true if attribute found else false",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 622,
            +            "description": "<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 669,
            +            "description": "<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 716,
            +            "description": "<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttribute",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value of the attribute</p>\n",
            +                    "type": "Number|String|Boolean"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 757,
            +            "description": "<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getContent",
            +            "params": [
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>value returned if no content is found</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 798,
            +            "description": "<p>Sets the element's content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setContent",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>the new content</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 839,
            +            "description": "<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n",
            +            "itemtype": "method",
            +            "name": "serialize",
            +            "return": {
            +                "description": "Serialized string of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 10,
            +            "description": "<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n",
            +            "itemtype": "method",
            +            "name": "abs",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to compute</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "absolute value of given number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 33,
            +            "description": "<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n",
            +            "itemtype": "method",
            +            "name": "ceil",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round up</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded up number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 72,
            +            "description": "<p>Constrains a value between a minimum and maximum value.</p>\n",
            +            "itemtype": "method",
            +            "name": "constrain",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to constrain</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "low",
            +                    "description": "<p>minimum limit</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "high",
            +                    "description": "<p>maximum limit</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "constrained number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"
            +            ],
            +            "alt": "2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 116,
            +            "description": "<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "distance between the two points",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"
            +            ],
            +            "alt": "2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 116,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 161,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 182,
            +            "description": "<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n",
            +            "itemtype": "method",
            +            "name": "exp",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>exponent to raise</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "e^n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. e^n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 231,
            +            "description": "<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n",
            +            "itemtype": "method",
            +            "name": "floor",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round down</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded down number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 269,
            +            "description": "<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "params": [
            +                {
            +                    "name": "start",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "lerped value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"
            +            ],
            +            "alt": "5 points horizontally staggered mid-canvas. mid 3 are grey, outer black",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 316,
            +            "description": "<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number greater than 0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "natural logarithm of n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. natural logarithm of n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 371,
            +            "description": "<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "magnitude of vector from (0,0) to (a,b)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"
            +            ],
            +            "alt": "4 lines of different length radiate from top left of canvas.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 409,
            +            "description": "<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n",
            +            "itemtype": "method",
            +            "name": "map",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the incoming value to be converted</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start1",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop1",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start2",
            +                    "description": "<p>lower bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop2",
            +                    "description": "<p>upper bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "withinBounds",
            +                    "description": "<p>constrain the value to the newly mapped range</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "remapped number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"
            +            ],
            +            "alt": "10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 464,
            +            "description": "<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "max",
            +            "return": {
            +                "description": "maximum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 464,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "maximum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 499,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 512,
            +            "description": "<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "min",
            +            "return": {
            +                "description": "minimum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "minimum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 560,
            +            "description": "<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n",
            +            "itemtype": "method",
            +            "name": "norm",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>incoming value to be normalized</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "normalized number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves with mouse. 0 shown left & 100 right and updating values center",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 612,
            +            "description": "<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n",
            +            "itemtype": "method",
            +            "name": "pow",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>base of the exponential expression</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>power by which to raise the base</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "n^e",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"
            +            ],
            +            "alt": "small to large ellipses radiating from top left of canvas",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 646,
            +            "description": "<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n",
            +            "itemtype": "method",
            +            "name": "round",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decimals",
            +                    "description": "<p>number of decimal places to round to, default is 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 701,
            +            "description": "<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sq",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to square</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "squared number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squared values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 745,
            +            "description": "<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n",
            +            "itemtype": "method",
            +            "name": "sqrt",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>non-negative number to square root</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "square root of number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squareroot values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 832,
            +            "description": "<p>Calculates the fractional part of a number.</p>\n",
            +            "itemtype": "method",
            +            "name": "fract",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>Number whose fractional part needs to be found out</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "fractional part of x, i.e, {x}",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"
            +            ],
            +            "alt": "first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/math.js",
            +            "line": 10,
            +            "description": "<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVector",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"
            +            ],
            +            "alt": "draws a line from center of canvas to mouse pointer position.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 36,
            +            "description": "<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n",
            +            "itemtype": "method",
            +            "name": "noise",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate in noise space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Perlin noise value (between 0 and 1) at specified\n                     coordinates",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 178,
            +            "description": "<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseDetail",
            +            "params": [
            +                {
            +                    "name": "lod",
            +                    "description": "<p>number of octaves to be used by the noise</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "falloff",
            +                    "description": "<p>falloff factor for each octave</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "2 vertical grey smokey patterns affected my mouse x-position and noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 243,
            +            "description": "<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical grey lines drawing in pattern affected by noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 69,
            +            "description": "<p>The x component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "x",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 74,
            +            "description": "<p>The y component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "y",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 79,
            +            "description": "<p>The z component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "z",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 86,
            +            "description": "<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 136,
            +            "description": "<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 195,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to set</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 219,
            +            "description": "<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "return": {
            +                "description": "the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 248,
            +            "description": "<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 248,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to be added</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 325,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to add</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2059,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 372,
            +            "description": "<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "rem",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 372,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 401,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>divisor vector</p>\n",
            +                            "type": "p5.Vector | Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2085,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2091,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 461,
            +            "description": "<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 461,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to subtract</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 538,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to subtract</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2110,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 562,
            +            "description": "<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 562,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to multiply with the vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 655,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to multiply with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to multiply with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to multiply with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 663,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to multiply with the components of the vector</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 669,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to multiply with the components of the original vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2139,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2148,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2156,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2164,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 754,
            +            "description": "<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 754,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to divide the vector by</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 847,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to divide with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to divide with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to divide with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 855,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to divide the components of the vector by</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 861,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to divide the components of the original vector by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2218,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2227,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2235,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2243,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 959,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "return": {
            +                "description": "magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 959,
            +                    "params": [],
            +                    "return": {
            +                        "description": "magnitude of the vector",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2343,
            +                    "params": [
            +                        {
            +                            "name": "vecT",
            +                            "description": "<p>the vector to return the magnitude of</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the magnitude of vecT",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1007,
            +            "description": "<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n",
            +            "itemtype": "method",
            +            "name": "magSq",
            +            "return": {
            +                "description": "squared magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1061,
            +            "description": "<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "dot",
            +            "return": {
            +                "description": "the dot product",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1061,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2270,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1103,
            +            "description": "<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "cross",
            +            "return": {
            +                "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1103,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2284,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the cross product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1145,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "the distance",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1145,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2299,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1217,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "return": {
            +                "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1217,
            +                    "params": [],
            +                    "return": {
            +                        "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2360,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vector to normalize</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "v normalized to a length of 1",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1287,
            +            "description": "<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "limit",
            +            "params": [
            +                {
            +                    "name": "max",
            +                    "description": "<p>the maximum magnitude for the vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1345,
            +            "description": "<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMag",
            +            "params": [
            +                {
            +                    "name": "len",
            +                    "description": "<p>the new length for this vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1401,
            +            "description": "<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "heading",
            +            "return": {
            +                "description": "the angle of rotation",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1473,
            +            "description": "<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "setHeading",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1498,
            +            "description": "<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1498,
            +                    "params": [
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>the angle of rotation</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2191,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1567,
            +            "description": "<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleBetween",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "return": {
            +                "description": "the angle between (in radians)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1647,
            +            "description": "<p>Linear interpolate the vector to another vector</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1647,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1720,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2314,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the lerped value",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1736,
            +            "description": "<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n",
            +            "itemtype": "method",
            +            "name": "reflect",
            +            "params": [
            +                {
            +                    "name": "surfaceNormal",
            +                    "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1791,
            +            "description": "<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n",
            +            "itemtype": "method",
            +            "name": "array",
            +            "return": {
            +                "description": "an Array with the 3 values",
            +                "type": "Number[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1823,
            +            "description": "<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +            "itemtype": "method",
            +            "name": "equals",
            +            "return": {
            +                "description": "whether the vectors are equals",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1823,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "whether the vectors are equals",
            +                        "type": "Boolean"
            +                    }
            +                },
            +                {
            +                    "line": 1853,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to compare</p>\n",
            +                            "type": "p5.Vector|Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Boolean"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1878,
            +            "description": "<p>Make a new 2D vector from an angle</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngle",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1929,
            +            "description": "<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngles",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "theta",
            +                    "description": "<p>the polar angle, in radians (zero is up)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "phi",
            +                    "description": "<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1978,
            +            "description": "<p>Make a new 2D unit vector from a random angle</p>\n",
            +            "itemtype": "method",
            +            "name": "random2D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2031,
            +            "description": "<p>Make a new random 3D unit vector.</p>\n",
            +            "itemtype": "method",
            +            "name": "random3D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2135,
            +            "description": "<p>Multiplies a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2187,
            +            "description": "<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2214,
            +            "description": "<p>Divides a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2267,
            +            "description": "<p>Calculates the dot product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2281,
            +            "description": "<p>Calculates the cross product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2295,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2310,
            +            "description": "<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2339,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2357,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 37,
            +            "description": "<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "many vertical lines drawn in white, black or grey.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 66,
            +            "description": "<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n",
            +            "itemtype": "method",
            +            "name": "random",
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"
            +            ],
            +            "alt": "100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random",
            +            "overloads": [
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "min",
            +                            "description": "<p>the lower bound (inclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>the upper bound (exclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 119,
            +                    "params": [
            +                        {
            +                            "name": "choices",
            +                            "description": "<p>the array to choose from</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random element from the array",
            +                        "type": "*"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 153,
            +            "description": "<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomGaussian",
            +            "params": [
            +                {
            +                    "name": "mean",
            +                    "description": "<p>the mean</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sd",
            +                    "description": "<p>the standard deviation</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 18,
            +            "description": "<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "acos",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc cosine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc cosine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 53,
            +            "description": "<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "asin",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc sine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc sine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 88,
            +            "description": "<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc tangent is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 123,
            +            "description": "<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan2",
            +            "params": [
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given point",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60 by 10 rect at center of canvas rotates with mouse movements",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 159,
            +            "description": "<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "cos",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the cosine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines form wave patterns, extend-down on left and right side",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 186,
            +            "description": "<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sin",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the sine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines extend down and up from center to form wave pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 213,
            +            "description": "<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n",
            +            "itemtype": "method",
            +            "name": "tan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"
            +            ],
            +            "alt": "vertical black lines end down and up from center to form spike pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 239,
            +            "description": "<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "degrees",
            +            "params": [
            +                {
            +                    "name": "radians",
            +                    "description": "<p>the radians value to convert to degrees</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 262,
            +            "description": "<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "radians",
            +            "params": [
            +                {
            +                    "name": "degrees",
            +                    "description": "<p>the degree value to convert to radians</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 285,
            +            "description": "<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either RADIANS or DEGREES</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"
            +            ],
            +            "alt": "40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 11,
            +            "description": "<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAlign",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"
            +            ],
            +            "alt": "Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "horizAlign",
            +                            "description": "<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "vertAlign",
            +                            "description": "<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n",
            +                            "type": "Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 72,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 81,
            +            "description": "<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "textLeading",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"
            +            ],
            +            "alt": "A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 81,
            +                    "params": [
            +                        {
            +                            "name": "leading",
            +                            "description": "<p>the size in pixels for spacing between lines</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 109,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 118,
            +            "description": "<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "textSize",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 118,
            +                    "params": [
            +                        {
            +                            "name": "theSize",
            +                            "description": "<p>the size of the letters in units of pixels</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 141,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 150,
            +            "description": "<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n",
            +            "itemtype": "method",
            +            "name": "textStyle",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 150,
            +                    "params": [
            +                        {
            +                            "name": "theStyle",
            +                            "description": "<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 178,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 187,
            +            "description": "<p>Calculates and returns the width of any character or text string.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWidth",
            +            "params": [
            +                {
            +                    "name": "theText",
            +                    "description": "<p>the String of characters to measure</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the calculated width",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"
            +            ],
            +            "alt": "Letter P and p5.js are displayed with vertical lines at end.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 222,
            +            "description": "<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAscent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 251,
            +            "description": "<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textDescent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 280,
            +            "description": "<p>Helper function to measure ascent and descent.</p>\n",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 287,
            +            "description": "<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWrap",
            +            "params": [
            +                {
            +                    "name": "wrapStyle",
            +                    "description": "<p>text wrapping style, either WORD or CHAR</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "return": {
            +                "description": "wrapStyle",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 16,
            +            "description": "<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadFont",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "onError",
            +                    "description": "<p>function to be executed if\n                                   an error occurs</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Font\">p5.Font</a> object",
            +                "type": "p5.Font"
            +            },
            +            "example": [
            +                "\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"
            +            ],
            +            "alt": "p5*js in p5's theme dark pink\np5*js in p5's theme dark pink",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 140,
            +            "description": "<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "text",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the alphanumeric\n                                            symbols to be displayed</p>\n",
            +                    "type": "String|Object|Array|Number|Boolean"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 231,
            +            "description": "<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n",
            +            "itemtype": "method",
            +            "name": "textFont",
            +            "return": {
            +                "description": "the current font / p5 Object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 231,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the current font / p5 Object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "font",
            +                            "description": "<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n",
            +                            "type": "Object|String"
            +                        },
            +                        {
            +                            "name": "size",
            +                            "description": "<p>the font size to use</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 24,
            +            "description": "<p>Underlying opentype font implementation</p>\n",
            +            "itemtype": "property",
            +            "name": "font",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 31,
            +            "description": "<p>Returns a tight bounding box for the given text string using this\nfont</p>\n",
            +            "itemtype": "method",
            +            "name": "textBounds",
            +            "params": [
            +                {
            +                    "name": "line",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional) Default is 12.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a rectangle object with properties: x, y, w, h",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "words Lorem ipsum dol go off canvas and contained by white bounding box",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 175,
            +            "description": "<p>Computes an array of points following the path for specified text</p>\n",
            +            "itemtype": "method",
            +            "name": "textToPoints",
            +            "params": [
            +                {
            +                    "name": "txt",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an array of points, each with x, y, alpha (the path angle)",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 10,
            +            "description": "<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n",
            +            "itemtype": "method",
            +            "name": "append",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to append</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>to be added to the Array</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "return": {
            +                "description": "the array that was appended to",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 35,
            +            "description": "<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "arrayCopy",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions",
            +            "overloads": [
            +                {
            +                    "line": 35,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>the source Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "srcPosition",
            +                            "description": "<p>starting position in the source Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "<p>the destination Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dstPosition",
            +                            "description": "<p>starting position in the destination Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "<p>number of Array elements to be copied</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 73,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 112,
            +            "description": "<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n",
            +            "itemtype": "method",
            +            "name": "concat",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first Array to concatenate</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second Array to concatenate</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "concatenated array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 141,
            +            "description": "<p>Reverses the order of an array, maps to Array.reverse()</p>\n",
            +            "itemtype": "method",
            +            "name": "reverse",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to reverse</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "the reversed list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 161,
            +            "description": "<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n",
            +            "itemtype": "method",
            +            "name": "shorten",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to shorten</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "shortened Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 185,
            +            "description": "<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "shuffle",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to shuffle</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "bool",
            +                    "description": "<p>modify passed array</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "shuffled Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 227,
            +            "description": "<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n",
            +            "itemtype": "method",
            +            "name": "sort",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to sort</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of elements to sort, starting from 0</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the sorted list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 273,
            +            "description": "<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n",
            +            "itemtype": "method",
            +            "name": "splice",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to splice into</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to be spliced in</p>\n",
            +                    "type": "Any"
            +                },
            +                {
            +                    "name": "position",
            +                    "description": "<p>in the array from which to insert data</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 308,
            +            "description": "<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n",
            +            "itemtype": "method",
            +            "name": "subset",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to extract from</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>position to begin</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of values to extract</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of extracted elements",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 10,
            +            "description": "<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "float",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>float string to parse</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "floating point representation of string",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "alt": "20 by 20 white ellipse in the center of the canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 44,
            +            "description": "<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "int",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 44,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "<p>the radix to convert to (default: 10)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 88,
            +            "description": "<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "str",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 114,
            +            "description": "<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n",
            +            "itemtype": "method",
            +            "name": "boolean",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "boolean representation of value",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 146,
            +            "description": "<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "byte",
            +            "return": {
            +                "description": "byte representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 146,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "byte representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 168,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of byte representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 182,
            +            "description": "<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "char",
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 182,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 201,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 216,
            +            "description": "<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unchar",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 216,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 232,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 245,
            +            "description": "<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "hex",
            +            "return": {
            +                "description": "hexadecimal string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 245,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 265,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>array of values to parse</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 295,
            +            "description": "<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unhex",
            +            "return": {
            +                "description": "integer representation of hexadecimal value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 295,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of hexadecimal value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representations of hexadecimal value",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 15,
            +            "description": "<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n",
            +            "itemtype": "method",
            +            "name": "join",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>array of Strings to be joined</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>String to be placed between each item</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "joined String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"hello world!\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 43,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "match",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"p5js*\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 83,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "matchAll",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "2d Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 130,
            +            "description": "<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nf",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" middle top, -1321.00\" middle bottom canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 237,
            +            "description": "<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfc",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 237,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                                 decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 311,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfp",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 352,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 373,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfs",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" top middle and \"-1321.00\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 373,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 430,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 451,
            +            "description": "<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n",
            +            "itemtype": "method",
            +            "name": "split",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>the String used to separate the data</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 484,
            +            "description": "<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n",
            +            "itemtype": "method",
            +            "name": "splitTokens",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>list of individual Strings that will be used as\n                         separators</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 537,
            +            "description": "<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "return": {
            +                "description": "a trimmed String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"No new lines here\" displayed center canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 537,
            +                    "params": [
            +                        {
            +                            "name": "str",
            +                            "description": "<p>a String to be trimmed</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "a trimmed String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 557,
            +                    "params": [
            +                        {
            +                            "name": "strs",
            +                            "description": "<p>an Array of Strings to be trimmed</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "an Array of trimmed Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 10,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n",
            +            "itemtype": "method",
            +            "name": "day",
            +            "return": {
            +                "description": "the current day",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current day is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 31,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n",
            +            "itemtype": "method",
            +            "name": "hour",
            +            "return": {
            +                "description": "the current hour",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current hour is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 52,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "minute",
            +            "return": {
            +                "description": "the current minute",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current minute is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 73,
            +            "description": "<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n",
            +            "itemtype": "method",
            +            "name": "millis",
            +            "return": {
            +                "description": "the number of milliseconds since starting the sketch",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"
            +            ],
            +            "alt": "number of milliseconds since sketch has started displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 100,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n",
            +            "itemtype": "method",
            +            "name": "month",
            +            "return": {
            +                "description": "the current month",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current month is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 122,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "second",
            +            "return": {
            +                "description": "the current second",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current second is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 143,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n",
            +            "itemtype": "method",
            +            "name": "year",
            +            "return": {
            +                "description": "the current year",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current year is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 13,
            +            "description": "<p>Draw a plane with given a width and height</p>\n",
            +            "itemtype": "method",
            +            "name": "plane",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 97,
            +            "description": "<p>Draw a box with given width, height and depth</p>\n",
            +            "itemtype": "method",
            +            "name": "box",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "Height",
            +                    "description": "<p>height of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "depth",
            +                    "description": "<p>depth of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 215,
            +            "description": "<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "sphere",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of circle</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>optional number of subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>optional number of subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 419,
            +            "description": "<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cylinder",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cylinder</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottomCap",
            +                    "description": "<p>whether to draw the bottom of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "topCap",
            +                    "description": "<p>whether to draw the top of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 554,
            +            "description": "<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cone",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the bottom surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cone</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cap",
            +                    "description": "<p>whether to draw the base of the cone</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 669,
            +            "description": "<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipsoid",
            +            "params": [
            +                {
            +                    "name": "radiusx",
            +                    "description": "<p>x-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusy",
            +                    "description": "<p>y-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusz",
            +                    "description": "<p>z-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 804,
            +            "description": "<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n",
            +            "itemtype": "method",
            +            "name": "torus",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the whole ring</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tubeRadius",
            +                    "description": "<p>radius of the tube</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 11,
            +            "description": "<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n",
            +            "itemtype": "method",
            +            "name": "orbitControl",
            +            "params": [
            +                {
            +                    "name": "sensitivityX",
            +                    "description": "<p>sensitivity to mouse movement along X axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityY",
            +                    "description": "<p>sensitivity to mouse movement along Y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityZ",
            +                    "description": "<p>sensitivity to scroll movement along Z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Camera orbits around a box when mouse is hold-clicked & then moved.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 145,
            +            "description": "<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n",
            +            "itemtype": "method",
            +            "name": "debugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction",
            +            "overloads": [
            +                {
            +                    "line": 145,
            +                    "params": []
            +                },
            +                {
            +                    "line": 278,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either GRID or AXES</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 283,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "gridSize",
            +                            "description": "<p>size of one side of the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "<p>number of divisions in the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "<p>X axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "<p>Y axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "<p>Z axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "<p>size of axes icon</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 302,
            +                    "params": [
            +                        {
            +                            "name": "gridSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 353,
            +            "description": "<p>Turns off debugMode() in a 3D sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noDebugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 11,
            +            "description": "<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "evenly distributed light across a sphere\nevenly distributed light across a rotating sphere",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>the alpha value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 51,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 57,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 64,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 92,
            +            "description": "<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularColor",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "different specular light sources from top and bottom of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 92,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 145,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 151,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 158,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 177,
            +            "description": "<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "directionalLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "light source on canvas changeable with mouse position",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 177,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 210,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis direction</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 220,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 227,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 280,
            +            "description": "<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "pointLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "spot light on canvas changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 322,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 331,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 341,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 387,
            +            "description": "<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "lights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "the light is partially ambient and partially directional",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 425,
            +            "description": "<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n",
            +            "itemtype": "method",
            +            "name": "lightFalloff",
            +            "params": [
            +                {
            +                    "name": "constant",
            +                    "description": "<p>constant value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "linear",
            +                    "description": "<p>linear value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "quadratic",
            +                    "description": "<p>quadratic value for determining falloff</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two spheres with different falloff values show different intensity of light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 519,
            +            "description": "<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "spotLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Spot light on a sphere which changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 519,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "<p>x axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "<p>y axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "<p>z axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>optional parameter for angle. Defaults to PI/3</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "<p>optional parameter for concentration. Defaults to 100</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 571,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 580,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 590,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 600,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 610,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 634,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 859,
            +            "description": "<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Three white spheres. Each appears as a different\ncolor due to lighting.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 12,
            +            "description": "<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadModel",
            +            "return": {
            +                "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                "type": "p5.Geometry"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d teapot with red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models",
            +            "overloads": [
            +                {
            +                    "line": 12,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>Path of the model to be loaded</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "normalize",
            +                            "description": "<p>If true, scale the model to a\n                                     standardized size when loading</p>\n",
            +                            "type": "Boolean"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "<p>called with event error if\n                                        the model fails to load.</p>\n",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                },
            +                {
            +                    "line": 96,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 179,
            +            "description": "<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 290,
            +            "description": "<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 317,
            +            "description": "<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 344,
            +            "description": "<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 356,
            +            "description": "<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 444,
            +            "description": "<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 588,
            +            "description": "<p>Render a 3d model to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "model",
            +            "params": [
            +                {
            +                    "name": "model",
            +                    "description": "<p>Loaded 3d model to be rendered</p>\n",
            +                    "type": "p5.Geometry"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d octahedron.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 12,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadShader",
            +            "params": [
            +                {
            +                    "name": "vertFilename",
            +                    "description": "<p>path to file containing vertex shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragFilename",
            +                    "description": "<p>path to file containing fragment shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shader files.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 111,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "createShader",
            +            "params": [
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shaders.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 184,
            +            "description": "<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "shader",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "s",
            +                    "description": "<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n",
            +                    "type": "p5.Shader"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 282,
            +            "description": "<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "resetShader",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 368,
            +            "description": "<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "texture",
            +            "params": [
            +                {
            +                    "name": "tex",
            +                    "description": "<p>image to use as texture</p>\n",
            +                    "type": "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using normalized coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 511,
            +            "description": "<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n",
            +            "itemtype": "method",
            +            "name": "textureMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either IMAGE or NORMAL</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using image coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 587,
            +            "description": "<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n",
            +            "itemtype": "method",
            +            "name": "textureWrap",
            +            "params": [
            +                {
            +                    "name": "wrapX",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "wrapY",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "an image of the rocky mountains repeated in mirrored tiles",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 659,
            +            "description": "<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 697,
            +            "description": "<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 697,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 757,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 777,
            +            "description": "<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n",
            +            "itemtype": "method",
            +            "name": "emissiveMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 777,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 809,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 829,
            +            "description": "<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "torus with specular material",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 870,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 882,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 902,
            +            "description": "<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "shininess",
            +            "params": [
            +                {
            +                    "name": "shine",
            +                    "description": "<p>Degree of Shininess.\n                      Defaults to 1.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Shininess on Camera changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 13,
            +            "description": "<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>camera position value on x axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>camera position value on y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>camera position value on z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerX",
            +                    "description": "<p>x coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerY",
            +                    "description": "<p>y coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerZ",
            +                    "description": "<p>z coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upX",
            +                    "description": "<p>x component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upY",
            +                    "description": "<p>y component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upZ",
            +                    "description": "<p>z component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 115,
            +            "description": "<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "params": [
            +                {
            +                    "name": "fovy",
            +                    "description": "<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "aspect",
            +                    "description": "<p>camera frustum aspect ratio</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>frustum near plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>frustum far plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 176,
            +            "description": "<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 236,
            +            "description": "<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 303,
            +            "description": "<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCamera",
            +            "return": {
            +                "description": "The newly created camera object.",
            +                "type": "p5.Camera"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"
            +            ],
            +            "alt": "An example that creates a camera and moves it around the box.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 444,
            +            "description": "<p>camera position value on x axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 472,
            +            "description": "<p>camera position value on y axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 499,
            +            "description": "<p>camera position value on z axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 526,
            +            "description": "<p>x coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 554,
            +            "description": "<p>y coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 582,
            +            "description": "<p>z coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 610,
            +            "description": "<p>x component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 633,
            +            "description": "<p>y component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 656,
            +            "description": "<p>z component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 683,
            +            "description": "<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 801,
            +            "description": "<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 897,
            +            "description": "<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1040,
            +            "description": "<p>Panning rotates the camera view to the left and right.</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1098,
            +            "description": "<p>Tilting rotates the camera view up and down.</p>\n",
            +            "itemtype": "method",
            +            "name": "tilt",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view tilts up and down across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1156,
            +            "description": "<p>Reorients the camera to look at a position in world space.</p>\n",
            +            "itemtype": "method",
            +            "name": "lookAt",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view of rotating 3D cubes changes to look at a new random\npoint every second .",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1223,
            +            "description": "<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1386,
            +            "description": "<p>Move camera along its local axes while maintaining current camera orientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "move",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>amount to move along camera's left-right axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>amount to move along camera's up-down axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>amount to move along camera's forward-backward axis</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1458,
            +            "description": "<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "setPosition",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera position changes as the user presses keys, altering view of a 3D box",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1723,
            +            "description": "<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n",
            +            "itemtype": "method",
            +            "name": "setCamera",
            +            "params": [
            +                {
            +                    "name": "cam",
            +                    "description": "<p>p5.Camera object</p>\n",
            +                    "type": "p5.Camera"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Canvas switches between two camera views, each showing a series of spinning\n3D boxes.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 71,
            +            "description": "<p>computes faces for geometry objects based on the vertices.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeFaces",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 114,
            +            "description": "<p>computes smooth normals per vertex as an average of each\nface.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 153,
            +            "description": "<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n",
            +            "itemtype": "method",
            +            "name": "averageNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 174,
            +            "description": "<p>Averages pole normals.  Used in spherical primitives</p>\n",
            +            "itemtype": "method",
            +            "name": "averagePoleNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 267,
            +            "description": "<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 334,
            +            "description": "<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttributes",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a rotating cube with smoother edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "overloads": [
            +                {
            +                    "line": 334,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "<p>Name of attribute</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>New value of named attribute</p>\n",
            +                            "type": "Boolean"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 473,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>object with key-value pairs</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 306,
            +            "description": "<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n",
            +            "itemtype": "method",
            +            "name": "setUniform",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "uniformName",
            +                    "description": "<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "data",
            +                    "description": "<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n",
            +                    "type": "Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5.Shader",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1,
            +            "class": "p5.sound",
            +            "module": "3D"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 52,
            +            "description": "<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n",
            +            "class": "p5.sound",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 159,
            +            "description": "<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>",
            +            "itemtype": "method",
            +            "name": "getAudioContext",
            +            "return": {
            +                "description": "AudioContext for this sketch",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 198,
            +            "description": "<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>",
            +            "params": [
            +                {
            +                    "name": "element(s)",
            +                    "description": "<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n",
            +                    "type": "Element|Array",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback to invoke when the AudioContext\n                              has started</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that resolves when\n                                     the AudioContext state is 'running'",
            +                "type": "Promise"
            +            },
            +            "itemtype": "method",
            +            "name": "userStartAudio",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 401,
            +            "description": "<p>This module has shims</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 536,
            +            "description": "<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 726,
            +            "description": "<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOutputVolume",
            +            "return": {
            +                "description": "Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 738,
            +            "description": "<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>",
            +            "itemtype": "method",
            +            "name": "outputVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 782,
            +            "description": "<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n",
            +            "itemtype": "property",
            +            "name": "soundOut",
            +            "type": "Object",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 807,
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 811,
            +            "description": "<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "samplerate samples per second",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 825,
            +            "description": "<p>Returns the closest MIDI note value for\na given frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "freqToMidi",
            +            "params": [
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "MIDI note value",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 841,
            +            "description": "<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n",
            +            "itemtype": "method",
            +            "name": "midiToFreq",
            +            "params": [
            +                {
            +                    "name": "midiNote",
            +                    "description": "<p>The number of a MIDI note</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency value of the given MIDI note",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 925,
            +            "description": "<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n",
            +            "itemtype": "method",
            +            "name": "soundFormats",
            +            "params": [
            +                {
            +                    "name": "formats",
            +                    "description": "<p>i.e. 'mp3', 'wav', 'ogg'</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1040,
            +            "description": "<p>Used by Osc and Envelope to chain signal math</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1145,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveSound",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile that you wish to save</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1662,
            +            "description": "<p>Returns true if the sound file finished loading successfully.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLoaded",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1679,
            +            "description": "<p>Play the p5.SoundFile</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule playback to start (in seconds from now).</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) amplitude (volume)\n                                    of playback</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueStart",
            +                    "description": "<p>(optional) cue start time in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) duration of playback in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1787,
            +            "description": "<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "playMode",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>'restart' or 'sustain' or 'untilDone'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1847,
            +            "description": "<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                             seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1905,
            +            "description": "<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) playback volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueLoopStart",
            +                    "description": "<p>(optional) startTime in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) loop duration in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1950,
            +            "description": "<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "setLoop",
            +            "params": [
            +                {
            +                    "name": "Boolean",
            +                    "description": "<p>set looping to true or false</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1976,
            +            "description": "<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1997,
            +            "description": "<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPlaying",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2011,
            +            "description": "<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPaused",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2025,
            +            "description": "<p>Stop soundfile playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            in seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2087,
            +            "description": "<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panValue",
            +                    "description": "<p>Set the stereo panner</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                                seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2131,
            +            "description": "<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2146,
            +            "description": "<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "rate",
            +            "params": [
            +                {
            +                    "name": "playbackRate",
            +                    "description": "<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2239,
            +            "description": "<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "setVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2276,
            +            "description": "<p>Returns the duration of a sound file in seconds.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "The duration of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2293,
            +            "description": "<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n",
            +            "itemtype": "method",
            +            "name": "currentTime",
            +            "return": {
            +                "description": "currentTime of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2308,
            +            "description": "<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n",
            +            "itemtype": "method",
            +            "name": "jump",
            +            "params": [
            +                {
            +                    "name": "cueTime",
            +                    "description": "<p>cueTime of the soundFile in seconds.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>duration in seconds.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2340,
            +            "description": "<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n",
            +            "itemtype": "method",
            +            "name": "channels",
            +            "return": {
            +                "description": "[channels]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2354,
            +            "description": "<p>Return the sample rate of the sound file.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "[sampleRate]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2367,
            +            "description": "<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n",
            +            "itemtype": "method",
            +            "name": "frames",
            +            "return": {
            +                "description": "[sampleCount]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2381,
            +            "description": "<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPeaks",
            +            "params": [
            +                {
            +                    "name": "length",
            +                    "description": "<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of peaks.",
            +                "type": "Float32Array"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2443,
            +            "description": "<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n",
            +            "itemtype": "method",
            +            "name": "reverseBuffer",
            +            "example": [
            +                "\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2497,
            +            "description": "<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2565,
            +            "description": "<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>Audio object that accepts an input</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2590,
            +            "description": "<p>Disconnects the output of this p5sound object.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2604,
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2612,
            +            "description": "<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n",
            +            "itemtype": "method",
            +            "name": "setPath",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to audio file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2630,
            +            "description": "<p>Replace the current Audio Buffer with a new Buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBuffer",
            +            "params": [
            +                {
            +                    "name": "buf",
            +                    "description": "<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2719,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2790,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2817,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2850,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2882,
            +            "description": "<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBlob",
            +            "return": {
            +                "description": "A file-like data object",
            +                "type": "Blob"
            +            },
            +            "example": [
            +                "\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2946,
            +            "description": "<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadSound",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoading",
            +                    "description": "<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a p5.SoundFile",
            +                "type": "SoundFile"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3117,
            +            "description": "<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "snd",
            +                    "description": "<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n",
            +                    "type": "SoundObject|undefined",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n",
            +                    "type": "Number|undefined",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3209,
            +            "description": "<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "channel",
            +                    "description": "<p>Optionally return only channel 0 (left) or 1 (right)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Amplitude as a number between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3264,
            +            "description": "<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleNormalize",
            +            "params": [
            +                {
            +                    "name": "boolean",
            +                    "description": "<p>set normalize to true (1) or false (0)</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3293,
            +            "description": "<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "set",
            +                    "description": "<p>smoothing from 0.0 <= 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3476,
            +            "description": "<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "source",
            +                    "description": "<p>p5.sound object (or web audio API source node)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3501,
            +            "description": "<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n",
            +            "itemtype": "method",
            +            "name": "waveform",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "precision",
            +                    "description": "<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3553,
            +            "description": "<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "analyze",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "scale",
            +                    "description": "<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3650,
            +            "description": "<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getEnergy",
            +            "params": [
            +                {
            +                    "name": "frequency1",
            +                    "description": "<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "frequency2",
            +                    "description": "<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Energy   Energy (volume/amplitude) from\n                            0 and 255.",
            +                "type": "Number"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3739,
            +            "description": "<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getCentroid",
            +            "return": {
            +                "description": "Spectral Centroid Frequency  of the spectral centroid in Hz.",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3826,
            +            "description": "<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3854,
            +            "description": "<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "linAverages",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Number of returned frequency groups</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "linearAverages   Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3889,
            +            "description": "<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "logAverages",
            +            "params": [
            +                {
            +                    "name": "octaveBands",
            +                    "description": "<p>Array of Octave Bands objects for grouping</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "logAverages    Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3925,
            +            "description": "<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOctaveBands",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Specifies the 1/N type of generated octave bands</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fCtr0",
            +                    "description": "<p>Minimum central frequency for the lowest band</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "octaveBands   Array of octave band objects with their bounds",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4168,
            +            "description": "<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>startTime in seconds from now.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>frequency in Hz.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4218,
            +            "description": "<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>Time, in seconds from now.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4238,
            +            "description": "<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)",
            +                "type": "AudioParam"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4271,
            +            "description": "<p>Returns the value of output gain</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmp",
            +            "return": {
            +                "description": "Amplitude value between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4285,
            +            "description": "<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "Frequency",
            +                    "description": "<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Ramp time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen\n                                 at x seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency",
            +                "type": "AudioParam"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4360,
            +            "description": "<p>Returns the value of frequency of oscillator</p>\n",
            +            "itemtype": "method",
            +            "name": "getFreq",
            +            "return": {
            +                "description": "Frequency of oscillator in Hertz",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4373,
            +            "description": "<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4386,
            +            "description": "<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "getType",
            +            "return": {
            +                "description": "type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4399,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4420,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4444,
            +            "description": "<p>Pan between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panning",
            +                    "description": "<p>Number between -1 and 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4460,
            +            "description": "<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "panPosition of oscillator , between Left (-1) and Right (1)",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4494,
            +            "description": "<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "phase",
            +            "params": [
            +                {
            +                    "name": "phase",
            +                    "description": "<p>float between 0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4522,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4543,
            +            "description": "<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with multiplied output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4563,
            +            "description": "<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4767,
            +            "description": "<p>Time until envelope reaches attackLevel</p>\n",
            +            "itemtype": "property",
            +            "name": "attackTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4772,
            +            "description": "<p>Level once attack is complete.</p>\n",
            +            "itemtype": "property",
            +            "name": "attackLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4778,
            +            "description": "<p>Time until envelope reaches decayLevel.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4784,
            +            "description": "<p>Level after decay. The envelope will sustain here until it is released.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4790,
            +            "description": "<p>Duration of the release portion of the envelope.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4796,
            +            "description": "<p>Level at the end of the release.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4833,
            +            "description": "<p>Reset the envelope with a series of time/value pairs.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "attackLevel",
            +                    "description": "<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayLevel",
            +                    "description": "<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Release Time (in seconds)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseLevel",
            +                    "description": "<p>Amplitude</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4895,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4964,
            +            "description": "<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRange",
            +            "params": [
            +                {
            +                    "name": "aLevel",
            +                    "description": "<p>attack level (defaults to 1)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rLevel",
            +                    "description": "<p>release level (defaults to 0)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5037,
            +            "description": "<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "inputs",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5055,
            +            "description": "<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n",
            +            "itemtype": "method",
            +            "name": "setExp",
            +            "params": [
            +                {
            +                    "name": "isExp",
            +                    "description": "<p>true is exponential, false is linear</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5078,
            +            "description": "<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5148,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5256,
            +            "description": "<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5350,
            +            "description": "<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n",
            +            "itemtype": "method",
            +            "name": "ramp",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>When to trigger the ramp</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v",
            +                    "description": "<p>Target value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v2",
            +                    "description": "<p>Second target value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5460,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5479,
            +            "description": "<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5498,
            +            "description": "<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5657,
            +            "description": "<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'white', 'pink' or 'brown'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Noise",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5871,
            +            "description": "<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n",
            +            "itemtype": "method",
            +            "name": "width",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Pulse",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6066,
            +            "itemtype": "property",
            +            "name": "input",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6070,
            +            "itemtype": "property",
            +            "name": "output",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6075,
            +            "itemtype": "property",
            +            "name": "stream",
            +            "type": "MediaStream|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6080,
            +            "itemtype": "property",
            +            "name": "mediaStream",
            +            "type": "MediaStreamAudioSourceNode|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6085,
            +            "itemtype": "property",
            +            "name": "currentSource",
            +            "type": "Number|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6090,
            +            "description": "<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n",
            +            "itemtype": "property",
            +            "name": "enabled",
            +            "type": "Boolean",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6098,
            +            "description": "<p>Input amplitude, connect to it by default but not to master out</p>\n",
            +            "itemtype": "property",
            +            "name": "amplitude",
            +            "type": "p5.Amplitude",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6114,
            +            "description": "<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call on\n                                  success.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6171,
            +            "description": "<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6191,
            +            "description": "<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>An object that accepts audio input,\n                        such as an FFT</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6216,
            +            "description": "<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6234,
            +            "description": "<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Volume level (between 0.0 and 1.0)",
            +                "type": "Number"
            +            },
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6257,
            +            "description": "<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>ramp time (optional)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6280,
            +            "description": "<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n",
            +            "itemtype": "method",
            +            "name": "getSources",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>This optional callback receives the error\n                                   message as its argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6340,
            +            "description": "<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "setSource",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>position of input source in the array</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6462,
            +            "description": "<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6478,
            +            "description": "<p>Set the output volume of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts until rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tFromNow",
            +                    "description": "<p>schedule this event to happen in tFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6502,
            +            "description": "<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n",
            +            "itemtype": "method",
            +            "name": "chain",
            +            "params": [
            +                {
            +                    "name": "arguments",
            +                    "description": "<p>Chain together multiple sound objects</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6525,
            +            "description": "<p>Adjust the dry/wet value.</p>\n",
            +            "itemtype": "method",
            +            "name": "drywet",
            +            "params": [
            +                {
            +                    "name": "fade",
            +                    "description": "<p>The desired drywet value (0 - 1.0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6542,
            +            "description": "<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6557,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6719,
            +            "description": "<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "biquadFilter",
            +            "type": "DelayNode",
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6742,
            +            "description": "<p>Filter an audio signal according to a set\nof filter parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6760,
            +            "description": "<p>Set the frequency and the resonance of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance (Q) from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6781,
            +            "description": "<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Filter Frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value  Returns the current frequency value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6811,
            +            "description": "<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "res",
            +            "params": [
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value Returns the current res value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6838,
            +            "description": "<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n",
            +            "itemtype": "method",
            +            "name": "gain",
            +            "params": [
            +                {
            +                    "name": "gain",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns the current or updated gain value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6864,
            +            "description": "<p>Toggle function. Switches between the specified type and allpass</p>\n",
            +            "itemtype": "method",
            +            "name": "toggle",
            +            "return": {
            +                "description": "[Toggle value]",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6884,
            +            "description": "<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "t",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7198,
            +            "description": "<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n",
            +            "itemtype": "property",
            +            "name": "bands",
            +            "type": "Array",
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7239,
            +            "description": "<p>Process an input by connecting it to the EQ</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Audio source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7629,
            +            "description": "<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n",
            +            "itemtype": "property",
            +            "name": "panner",
            +            "type": "AudioNode",
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7654,
            +            "description": "<p>Connect an audio sorce</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Input source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7668,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7687,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7694,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7701,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7753,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "orient",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7772,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7779,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7786,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7838,
            +            "description": "<p>Set the rolloff factor and max distance</p>\n",
            +            "itemtype": "method",
            +            "name": "setFalloff",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7852,
            +            "description": "<p>Maxium distance between the source and the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "maxDist",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7869,
            +            "description": "<p>How quickly the volume is reduced as the source moves away from the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "rollof",
            +            "params": [
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7989,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "leftDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7999,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "rightDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8049,
            +            "description": "<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "lowPass",
            +                    "description": "<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8094,
            +            "description": "<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n",
            +            "itemtype": "method",
            +            "name": "delayTime",
            +            "params": [
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8116,
            +            "description": "<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n",
            +            "itemtype": "method",
            +            "name": "feedback",
            +            "params": [
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "return": {
            +                "description": "Feedback value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8148,
            +            "description": "<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "cutoffFreq",
            +                    "description": "<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8170,
            +            "description": "<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'pingPong' (1) or 'default' (0)</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8223,
            +            "description": "<p>Set the output level of the delay effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8234,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8242,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8409,
            +            "description": "<p>Connect a source to the reverb, and assign reverb parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8446,
            +            "description": "<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8482,
            +            "description": "<p>Set the output level of the reverb effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8493,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8501,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8621,
            +            "description": "<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "convolverNode",
            +            "type": "ConvolverNode",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8645,
            +            "description": "<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n",
            +            "itemtype": "property",
            +            "name": "impulses",
            +            "type": "Array",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8737,
            +            "description": "<p>Connect a source to the convolver.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8786,
            +            "description": "<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n",
            +            "itemtype": "method",
            +            "name": "addImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8808,
            +            "description": "<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8831,
            +            "description": "<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleImpulse",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8885,
            +            "description": "<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n",
            +            "itemtype": "method",
            +            "name": "createConvolver",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Convolver"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9084,
            +            "description": "<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9173,
            +            "description": "<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n",
            +            "itemtype": "property",
            +            "name": "sequence",
            +            "type": "Array",
            +            "class": "p5.Phrase",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9263,
            +            "description": "<p>Set the tempo of this part, in Beats Per Minute.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9278,
            +            "description": "<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBPM",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9291,
            +            "description": "<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9311,
            +            "description": "<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9333,
            +            "description": "<p>Tell the part to stop looping.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9349,
            +            "description": "<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9363,
            +            "description": "<p>Pause the part. Playback will resume\nfrom the current step.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9379,
            +            "description": "<p>Add a p5.Phrase to this Part.</p>\n",
            +            "itemtype": "method",
            +            "name": "addPhrase",
            +            "params": [
            +                {
            +                    "name": "phrase",
            +                    "description": "<p>reference to a p5.Phrase</p>\n",
            +                    "type": "p5.Phrase"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9406,
            +            "description": "<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n",
            +            "itemtype": "method",
            +            "name": "removePhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9424,
            +            "description": "<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9442,
            +            "description": "<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n",
            +            "itemtype": "method",
            +            "name": "replaceSequence",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9473,
            +            "description": "<p>Set the function that will be called at every step. This will clear the previous function.</p>\n",
            +            "itemtype": "method",
            +            "name": "onStep",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9542,
            +            "description": "<p>Start playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9555,
            +            "description": "<p>Stop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9569,
            +            "description": "<p>Pause playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9581,
            +            "description": "<p>Loop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9594,
            +            "description": "<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9628,
            +            "description": "<p>Set the tempo for all parts in the score</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9729,
            +            "description": "<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n",
            +            "itemtype": "property",
            +            "name": "bpm",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9750,
            +            "description": "<p>number of quarter notes in a measure (defaults to 4)</p>\n",
            +            "itemtype": "property",
            +            "name": "timeSignature",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9770,
            +            "description": "<p>length of the loops interval</p>\n",
            +            "itemtype": "property",
            +            "name": "interval",
            +            "type": "Number|String",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9787,
            +            "description": "<p>how many times the callback has been called so far</p>\n",
            +            "itemtype": "property",
            +            "name": "iterations",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9800,
            +            "description": "<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n",
            +            "itemtype": "property",
            +            "name": "musicalTimeMode",
            +            "type": "Boolean",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9808,
            +            "description": "<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9816,
            +            "description": "<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n",
            +            "itemtype": "property",
            +            "name": "maxIterations",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9826,
            +            "description": "<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9841,
            +            "description": "<p>Start the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a starting time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9860,
            +            "description": "<p>Stop the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a stopping time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9878,
            +            "description": "<p>Pause the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a pausing time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9896,
            +            "description": "<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n",
            +            "itemtype": "method",
            +            "name": "syncedStart",
            +            "params": [
            +                {
            +                    "name": "otherLoop",
            +                    "description": "<p>a p5.SoundLoop to sync with</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Start the loops in sync after timeFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10068,
            +            "description": "<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n",
            +            "itemtype": "property",
            +            "name": "compressor",
            +            "type": "AudioNode",
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10084,
            +            "description": "<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Sound source to be connected</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10112,
            +            "description": "<p>Set the paramters of a compressor.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10152,
            +            "description": "<p>Get current attack or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "attack",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10178,
            +            "description": "<p>Get current knee or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "knee",
            +            "params": [
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10204,
            +            "description": "<p>Get current ratio or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "ratio",
            +            "params": [
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10228,
            +            "description": "<p>Get current threshold or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "threshold",
            +            "params": [
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10252,
            +            "description": "<p>Get current release or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "release",
            +            "params": [
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10277,
            +            "description": "<p>Return the current reduction value</p>\n",
            +            "itemtype": "method",
            +            "name": "reduction",
            +            "return": {
            +                "description": "Value of the amount of gain reduction that is applied to the signal",
            +                "type": "Number"
            +            },
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10419,
            +            "description": "<p>isDetected is set to true when a peak is detected.</p>\n",
            +            "itemtype": "attribute",
            +            "name": "isDetected",
            +            "type": "Boolean",
            +            "default": "false",
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10432,
            +            "description": "<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n",
            +            "itemtype": "method",
            +            "name": "update",
            +            "params": [
            +                {
            +                    "name": "fftObject",
            +                    "description": "<p>A p5.FFT object</p>\n",
            +                    "type": "p5.FFT"
            +                }
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10470,
            +            "description": "<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onPeak",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "val",
            +                    "description": "<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10676,
            +            "description": "<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10703,
            +            "description": "<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n",
            +            "itemtype": "method",
            +            "name": "record",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that will be\n                              called once the recording completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10739,
            +            "description": "<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10864,
            +            "description": "<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "WaveShaperNode",
            +            "type": "AudioNode",
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10883,
            +            "description": "<p>Process a sound source, optionally specify amount and oversample values.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10900,
            +            "description": "<p>Set the amount and oversample of the waveshaper distortion.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10923,
            +            "description": "<p>Return the distortion amount, typically between 0-1.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmount",
            +            "return": {
            +                "description": "Unbounded distortion amount.\n                 Normal values range from 0-1.",
            +                "type": "Number"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10937,
            +            "description": "<p>Return the oversampling.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOversample",
            +            "return": {
            +                "description": "Oversample can either be 'none', '2x', or '4x'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11055,
            +            "description": "<p>Connect a source to the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11070,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11084,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11098,
            +            "description": "<p>Set the output level of the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11181,
            +            "description": "<p>Connect to p5 objects or Web Audio Nodes</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11194,
            +            "description": "<p>Disconnect from soundOut</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11322,
            +            "description": "<p>Getters and Setters</p>\n",
            +            "itemtype": "property",
            +            "name": "attack",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11328,
            +            "itemtype": "property",
            +            "name": "decay",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11333,
            +            "itemtype": "property",
            +            "name": "sustain",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11338,
            +            "itemtype": "property",
            +            "name": "release",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11379,
            +            "description": "<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11431,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11478,
            +            "description": "<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11516,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11544,
            +            "description": "<p>MonoSynth amp</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>desired volume</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Time to reach new volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "new volume value",
            +                "type": "Number"
            +            },
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11564,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11578,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11592,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11742,
            +            "description": "<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n",
            +            "itemtype": "property",
            +            "name": "notes",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11755,
            +            "description": "<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n",
            +            "itemtype": "property",
            +            "name": "polyvalue",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11761,
            +            "description": "<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n",
            +            "itemtype": "property",
            +            "name": "AudioVoice",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11800,
            +            "description": "<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11849,
            +            "description": "<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteADSR",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>Midi note on which ADSR should be set.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11881,
            +            "description": "<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11909,
            +            "description": "<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteAttack",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)/</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12021,
            +            "description": "<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteRelease",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12105,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12119,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12133,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        }
            +    ],
            +    "warnings": [
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:120"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:216"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:316"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:457"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:1001"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:223"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:248"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/validate_params.js:336"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:219"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:259"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:185"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:264"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:358"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:398"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:493"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:67"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:293"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:460"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:524"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:583"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:668"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:733"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:826"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:84"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:120"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:138"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:79"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:129"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:160"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:228"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:372"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:390"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:405"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:421"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:500"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:550"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:586"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:660"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:691"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:713"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:42"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:47"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:154"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:189"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:246"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:292"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:403"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:454"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:510"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:551"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:639"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:678"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:725"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:763"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:70"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:7"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:34"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:87"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:137"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:158"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:179"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:200"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:267"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:309"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:379"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:408"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:448"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:490"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:326"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:134"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:192"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:290"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:391"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:497"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:193"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:232"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:304"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:342"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:416"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:455"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:494"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:101"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1560"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1622"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1726"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1765"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1885"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2778"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:23"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:46"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:69"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:135"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:201"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:285"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:330"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:428"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:515"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:546"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:604"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:64"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:103"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:308"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:106"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:132"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:164"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:233"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:271"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:615"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:696"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:772"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:841"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:926"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:979"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:1025"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:71"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:151"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:94"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:413"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:18"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:301"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:569"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:88"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:152"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:261"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:296"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:346"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:400"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:437"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:548"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:665"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:738"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:900"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:941"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:972"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1017"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1052"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1089"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:173"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:307"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:566"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:602"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:674"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:583"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1393"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:85"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:148"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:240"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:352"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:545"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:597"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:638"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:896"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:960"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1009"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1055"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1242"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1305"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:40"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:191"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:295"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.XML.js:9"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:33"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:72"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:116"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:182"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:269"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:316"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:371"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:409"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:464"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:560"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:612"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:646"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:701"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:745"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/math.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:178"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/p5.Vector.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:37"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:153"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:123"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:159"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:186"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:213"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:285"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:320"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:335"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:350"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:118"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:150"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:187"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:16"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:140"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/p5.Font.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/conversion.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:237"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:373"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:451"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:537"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:73"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:143"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/3d_primitives.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:353"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:177"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:280"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:387"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:425"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:519"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:588"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:12"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:282"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:587"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:659"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:697"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:777"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:829"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:902"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:176"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:236"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:357"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:444"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:472"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:499"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:526"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:554"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:582"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:610"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:683"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:801"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:897"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1040"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1098"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1156"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1386"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1458"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1723"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:334"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:644"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:749"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Shader.js:306"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:115"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:158"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:191"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:236"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:250"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:456"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:471"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:556"
            +        },
            +        {
            +            "message": "replacing incorrect tag: params with param",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2882"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4360"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4386"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4460"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:6280"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:8116"
            +        },
            +        {
            +            "message": "Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.",
            +            "line": " src/color/color_conversion.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:19"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to RGBA.",
            +            "line": " src/color/color_conversion.js:45"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to HSBA.",
            +            "line": " src/color/color_conversion.js:100"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.",
            +            "line": " src/color/color_conversion.js:123"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSBA.",
            +            "line": " src/color/color_conversion.js:187"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:226"
            +        },
            +        {
            +            "message": "Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.",
            +            "line": " src/color/p5.Color.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.",
            +            "line": " src/color/p5.Color.js:427"
            +        },
            +        {
            +            "message": "Missing item type\nCSS named colors.",
            +            "line": " src/color/p5.Color.js:446"
            +        },
            +        {
            +            "message": "Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.",
            +            "line": " src/color/p5.Color.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nFull color string patterns. The capture groups are necessary.",
            +            "line": " src/color/p5.Color.js:613"
            +        },
            +        {
            +            "message": "Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.",
            +            "line": " src/color/p5.Color.js:750"
            +        },
            +        {
            +            "message": "Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.",
            +            "line": " src/color/p5.Color.js:960"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/fes_core.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.",
            +            "line": " src/core/friendly_errors/fes_core.js:915"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/file_errors.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/sketch_reader.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/stacktrace.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nGiven an Error object, extract the most information from it.",
            +            "line": " src/core/friendly_errors/stacktrace.js:34"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/validate_params.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).",
            +            "line": " src/core/shape/2d_primitives.js:16"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current framerate.",
            +            "line": " src/core/environment.js:305"
            +        },
            +        {
            +            "message": "Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.",
            +            "line": " src/core/environment.js:315"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/helpers.js:1"
            +        },
            +        {
            +            "message": "Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing",
            +            "line": " src/core/init.js:4"
            +        },
            +        {
            +            "message": "Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.",
            +            "line": " src/core/internationalization.js:30"
            +        },
            +        {
            +            "message": "Missing item type\nSet up our translation function, with loaded languages",
            +            "line": " src/core/internationalization.js:126"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a list of languages we have translations loaded for",
            +            "line": " src/core/internationalization.js:171"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current language selected for translation",
            +            "line": " src/core/internationalization.js:178"
            +        },
            +        {
            +            "message": "Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.",
            +            "line": " src/core/internationalization.js:185"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/legacy.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/core/p5.Element.js:827"
            +        },
            +        {
            +            "message": "Missing item type\nResize our canvas element.",
            +            "line": " src/core/p5.Renderer.js:99"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to check font type (system or otf)",
            +            "line": " src/core/p5.Renderer.js:415"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178",
            +            "line": " src/core/p5.Renderer.js:467"
            +        },
            +        {
            +            "message": "Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer",
            +            "line": " src/core/p5.Renderer2D.js:7"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.",
            +            "line": " src/core/p5.Renderer2D.js:402"
            +        },
            +        {
            +            "message": "Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.",
            +            "line": " src/core/shim.js:18"
            +        },
            +        {
            +            "message": "Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign",
            +            "line": " src/core/shim.js:39"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()",
            +            "line": " src/data/p5.TypedDict.js:197"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:387"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:425"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:536"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for select and selectAll",
            +            "line": " src/dom/dom.js:127"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for getElement and getElements.",
            +            "line": " src/dom/dom.js:142"
            +        },
            +        {
            +            "message": "Missing item type\nHelpers for create methods.",
            +            "line": " src/dom/dom.js:309"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:450"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1164"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1257"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1296"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3232"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3298"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3360"
            +        },
            +        {
            +            "message": "Missing item type\n_updatePAccelerations updates the pAcceleration values",
            +            "line": " src/events/acceleration.js:124"
            +        },
            +        {
            +            "message": "Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.",
            +            "line": " src/events/keyboard.js:298"
            +        },
            +        {
            +            "message": "Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.",
            +            "line": " src/events/keyboard.js:384"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.",
            +            "line": " src/image/filters.js:3"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the pixel buffer for a canvas",
            +            "line": " src/image/filters.js:24"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.",
            +            "line": " src/image/filters.js:60"
            +        },
            +        {
            +            "message": "Missing item type\nModifies pixels RGBA values to values contained in the data object.",
            +            "line": " src/image/filters.js:81"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData",
            +            "line": " src/image/filters.js:101"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a blank ImageData object.",
            +            "line": " src/image/filters.js:121"
            +        },
            +        {
            +            "message": "Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.",
            +            "line": " src/image/filters.js:136"
            +        },
            +        {
            +            "message": "Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:189"
            +        },
            +        {
            +            "message": "Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:223"
            +        },
            +        {
            +            "message": "Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.",
            +            "line": " src/image/filters.js:246"
            +        },
            +        {
            +            "message": "Missing item type\nSets each pixel to its inverse value. No parameter is used.",
            +            "line": " src/image/filters.js:262"
            +        },
            +        {
            +            "message": "Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation",
            +            "line": " src/image/filters.js:277"
            +        },
            +        {
            +            "message": "Missing item type\nreduces the bright areas in an image",
            +            "line": " src/image/filters.js:309"
            +        },
            +        {
            +            "message": "Missing item type\nincreases the bright areas in an image",
            +            "line": " src/image/filters.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.",
            +            "line": " src/image/image.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for loading GIF-based images",
            +            "line": " src/image/loading_displaying.js:162"
            +        },
            +        {
            +            "message": "Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.",
            +            "line": " src/image/loading_displaying.js:597"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.",
            +            "line": " src/image/p5.Image.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for animating GIF-based images with time",
            +            "line": " src/image/p5.Image.js:222"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/image/p5.Image.js:253"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.",
            +            "line": " src/io/files.js:1789"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.",
            +            "line": " src/io/files.js:1857"
            +        },
            +        {
            +            "message": "Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.",
            +            "line": " src/io/files.js:1890"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.",
            +            "line": " src/io/files.js:1902"
            +        },
            +        {
            +            "message": "Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "line": " src/io/p5.Table.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nMultiplies a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2135"
            +        },
            +        {
            +            "message": "Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2187"
            +        },
            +        {
            +            "message": "Missing item type\nDivides a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2214"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the dot product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2267"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the cross product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2281"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).",
            +            "line": " src/math/p5.Vector.js:2295"
            +        },
            +        {
            +            "message": "Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.",
            +            "line": " src/math/p5.Vector.js:2310"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)",
            +            "line": " src/math/p5.Vector.js:2339"
            +        },
            +        {
            +            "message": "Missing item type\nNormalize the vector to length 1 (make it a unit vector).",
            +            "line": " src/math/p5.Vector.js:2357"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to measure ascent and descent.",
            +            "line": " src/typography/attributes.js:280"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.",
            +            "line": " src/typography/p5.Font.js:273"
            +        },
            +        {
            +            "message": "Missing item type\nReturns an opentype path for the supplied string and position.",
            +            "line": " src/typography/p5.Font.js:288"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/3d_primitives.js:301"
            +        },
            +        {
            +            "message": "Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.",
            +            "line": " src/webgl/3d_primitives.js:955"
            +        },
            +        {
            +            "message": "Missing item type\nDraw a line given two points",
            +            "line": " src/webgl/3d_primitives.js:1393"
            +        },
            +        {
            +            "message": "Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1",
            +            "line": " src/webgl/loading.js:179"
            +        },
            +        {
            +            "message": "Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.",
            +            "line": " src/webgl/loading.js:290"
            +        },
            +        {
            +            "message": "Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.",
            +            "line": " src/webgl/loading.js:317"
            +        },
            +        {
            +            "message": "Missing item type\nThis function matches the `query` at the provided `offset`",
            +            "line": " src/webgl/loading.js:344"
            +        },
            +        {
            +            "message": "Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.",
            +            "line": " src/webgl/loading.js:356"
            +        },
            +        {
            +            "message": "Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`",
            +            "line": " src/webgl/loading.js:444"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:947"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:978"
            +        },
            +        {
            +            "message": "Missing item type\nCreate a 2D array for establishing stroke connections",
            +            "line": " src/webgl/p5.Geometry.js:212"
            +        },
            +        {
            +            "message": "Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU",
            +            "line": " src/webgl/p5.Geometry.js:233"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/p5.Matrix.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPRIVATE",
            +            "line": " src/webgl/p5.Matrix.js:722"
            +        },
            +        {
            +            "message": "Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.",
            +            "line": " src/webgl/p5.RenderBuffer.js:12"
            +        },
            +        {
            +            "message": "Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nEnd shape drawing and render vertices to screen.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:129"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:169"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:248"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:268"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:302"
            +        },
            +        {
            +            "message": "Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:59"
            +        },
            +        {
            +            "message": "Missing item type\nDraws buffers given a geometry key ID",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:110"
            +        },
            +        {
            +            "message": "Missing item type\nmodel view, projection, & normal\nmatrices",
            +            "line": " src/webgl/p5.RendererGL.js:117"
            +        },
            +        {
            +            "message": "Missing item type\n[background description]",
            +            "line": " src/webgl/p5.RendererGL.js:586"
            +        },
            +        {
            +            "message": "Missing item type\n[resize description]",
            +            "line": " src/webgl/p5.RendererGL.js:860"
            +        },
            +        {
            +            "message": "Missing item type\nclears color and depth buffers\nwith r,g,b,a",
            +            "line": " src/webgl/p5.RendererGL.js:890"
            +        },
            +        {
            +            "message": "Missing item type\n[translate description]",
            +            "line": " src/webgl/p5.RendererGL.js:924"
            +        },
            +        {
            +            "message": "Missing item type\nScales the Model View Matrix by a vector",
            +            "line": " src/webgl/p5.RendererGL.js:943"
            +        },
            +        {
            +            "message": "Missing item type\nturn a two dimensional array into one dimensional array",
            +            "line": " src/webgl/p5.RendererGL.js:1366"
            +        },
            +        {
            +            "message": "Missing item type\nturn a p5.Vector Array into a one dimensional number array",
            +            "line": " src/webgl/p5.RendererGL.js:1403"
            +        },
            +        {
            +            "message": "Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.",
            +            "line": " src/webgl/p5.RendererGL.js:1421"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:1"
            +        },
            +        {
            +            "message": "Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/",
            +            "line": " lib/addons/p5.sound.js:52"
            +        },
            +        {
            +            "message": "Missing item type\nThis module has shims",
            +            "line": " lib/addons/p5.sound.js:401"
            +        },
            +        {
            +            "message": "Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats",
            +            "line": " lib/addons/p5.sound.js:536"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:807"
            +        },
            +        {
            +            "message": "Missing item type\nUsed by Osc and Envelope to chain signal math",
            +            "line": " lib/addons/p5.sound.js:1040"
            +        },
            +        {
            +            "message": "Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.",
            +            "line": " lib/addons/p5.sound.js:1542"
            +        },
            +        {
            +            "message": "Missing item type\nStop playback on all of this soundfile's sources.",
            +            "line": " lib/addons/p5.sound.js:2056"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:2604"
            +        },
            +        {
            +            "message": "Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade",
            +            "line": " lib/addons/p5.sound.js:6455"
            +        },
            +        {
            +            "message": "Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter",
            +            "line": " lib/addons/p5.sound.js:6462"
            +        },
            +        {
            +            "message": "Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ",
            +            "line": " lib/addons/p5.sound.js:7009"
            +        },
            +        {
            +            "message": "Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.",
            +            "line": " lib/addons/p5.sound.js:8508"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.",
            +            "line": " lib/addons/p5.sound.js:8659"
            +        },
            +        {
            +            "message": "Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string",
            +            "line": " lib/addons/p5.sound.js:9808"
            +        },
            +        {
            +            "message": "Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached",
            +            "line": " lib/addons/p5.sound.js:9826"
            +        },
            +        {
            +            "message": "Missing item type\ncallback invoked when the recording is over",
            +            "line": " lib/addons/p5.sound.js:10660"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release",
            +            "line": " lib/addons/p5.sound.js:11995"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.min.js:1"
            +        }
            +    ],
            +    "consts": {
            +        "LABEL": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "FALLBACK": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "RGB": [
            +            "p5.colorMode"
            +        ],
            +        "HSB": [
            +            "p5.colorMode"
            +        ],
            +        "HSL": [
            +            "p5.colorMode"
            +        ],
            +        "CHORD": [
            +            "p5.arc"
            +        ],
            +        "PIE": [
            +            "p5.arc"
            +        ],
            +        "OPEN": [
            +            "p5.arc"
            +        ],
            +        "CENTER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode",
            +            "p5.textAlign"
            +        ],
            +        "RADIUS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode"
            +        ],
            +        "CORNER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "CORNERS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "ROUND": [
            +            "p5.strokeCap",
            +            "p5.strokeJoin"
            +        ],
            +        "SQUARE": [
            +            "p5.strokeCap"
            +        ],
            +        "PROJECT": [
            +            "p5.strokeCap"
            +        ],
            +        "MITER": [
            +            "p5.strokeJoin"
            +        ],
            +        "BEVEL": [
            +            "p5.strokeJoin"
            +        ],
            +        "POINTS": [
            +            "p5.beginShape"
            +        ],
            +        "LINES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_FAN": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "QUADS": [
            +            "p5.beginShape"
            +        ],
            +        "QUAD_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "TESS": [
            +            "p5.beginShape"
            +        ],
            +        "CLOSE": [
            +            "p5.endShape"
            +        ],
            +        "ARROW": [
            +            "p5.cursor"
            +        ],
            +        "CROSS": [
            +            "p5.cursor"
            +        ],
            +        "HAND": [
            +            "p5.cursor"
            +        ],
            +        "MOVE": [
            +            "p5.cursor"
            +        ],
            +        "TEXT": [
            +            "p5.cursor"
            +        ],
            +        "P2D": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "WEBGL": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "BLEND": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DARKEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "LIGHTEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DIFFERENCE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "MULTIPLY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "EXCLUSION": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SCREEN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REPLACE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "OVERLAY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "HARD_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SOFT_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DODGE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "BURN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "ADD": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REMOVE": [
            +            "p5.blendMode"
            +        ],
            +        "SUBTRACT": [
            +            "p5.blendMode"
            +        ],
            +        "VIDEO": [
            +            "p5.createCapture"
            +        ],
            +        "AUDIO": [
            +            "p5.createCapture"
            +        ],
            +        "THRESHOLD": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "GRAY": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "OPAQUE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "INVERT": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "POSTERIZE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "ERODE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "DILATE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "BLUR": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "NORMAL": [
            +            "p5.Image.blend",
            +            "p5.blend",
            +            "p5.textStyle",
            +            "p5.textureMode"
            +        ],
            +        "RADIANS": [
            +            "p5.angleMode"
            +        ],
            +        "DEGREES": [
            +            "p5.angleMode"
            +        ],
            +        "LEFT": [
            +            "p5.textAlign"
            +        ],
            +        "RIGHT": [
            +            "p5.textAlign"
            +        ],
            +        "TOP": [
            +            "p5.textAlign"
            +        ],
            +        "BOTTOM": [
            +            "p5.textAlign"
            +        ],
            +        "BASELINE": [
            +            "p5.textAlign"
            +        ],
            +        "ITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "BOLD": [
            +            "p5.textStyle"
            +        ],
            +        "BOLDITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "WORD": [
            +            "p5.textWrap"
            +        ],
            +        "CHAR": [
            +            "p5.textWrap"
            +        ],
            +        "IMAGE": [
            +            "p5.textureMode"
            +        ],
            +        "CLAMP": [
            +            "p5.textureWrap"
            +        ],
            +        "REPEAT": [
            +            "p5.textureWrap"
            +        ],
            +        "MIRROR": [
            +            "p5.textureWrap"
            +        ]
            +    }
            +}
            \ No newline at end of file
            diff --git a/dist/ko/reference/data.min.json b/dist/ko/reference/data.min.json
            new file mode 100644
            index 0000000000..b719e76314
            --- /dev/null
            +++ b/dist/ko/reference/data.min.json
            @@ -0,0 +1 @@
            +{"project":{"name":"p5","description":"[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)","version":"1.4.1","url":"https://github.com/processing/p5.js#readme"},"files":{"src/accessibility/color_namer.js":{"name":"src/accessibility/color_namer.js","modules":{"Environment":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/describe.js":{"name":"src/accessibility/describe.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/gridOutput.js":{"name":"src/accessibility/gridOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/outputs.js":{"name":"src/accessibility/outputs.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/textOutput.js":{"name":"src/accessibility/textOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/color_conversion.js":{"name":"src/color/color_conversion.js","modules":{"Color Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/creating_reading.js":{"name":"src/color/creating_reading.js","modules":{"Creating & Reading":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/p5.Color.js":{"name":"src/color/p5.Color.js","modules":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{}},"src/color/setting.js":{"name":"src/color/setting.js","modules":{"Setting":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/fes_core.js":{"name":"src/core/friendly_errors/fes_core.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/file_errors.js":{"name":"src/core/friendly_errors/file_errors.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/sketch_reader.js":{"name":"src/core/friendly_errors/sketch_reader.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/stacktrace.js":{"name":"src/core/friendly_errors/stacktrace.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/validate_params.js":{"name":"src/core/friendly_errors/validate_params.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/2d_primitives.js":{"name":"src/core/shape/2d_primitives.js","modules":{"2D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/attributes.js":{"name":"src/core/shape/attributes.js","modules":{"Attributes":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/curves.js":{"name":"src/core/shape/curves.js","modules":{"Curves":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/vertex.js":{"name":"src/core/shape/vertex.js","modules":{"Vertex":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/constants.js":{"name":"src/core/constants.js","modules":{"Constants":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/environment.js":{"name":"src/core/environment.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/helpers.js":{"name":"src/core/helpers.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/init.js":{"name":"src/core/init.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/internationalization.js":{"name":"src/core/internationalization.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/legacy.js":{"name":"src/core/legacy.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/main.js":{"name":"src/core/main.js","modules":{"Structure":1},"classes":{"p5":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Element.js":{"name":"src/core/p5.Element.js","modules":{"DOM":1},"classes":{"p5.Element":1},"fors":{"p5.Element":1},"namespaces":{}},"src/core/p5.Graphics.js":{"name":"src/core/p5.Graphics.js","modules":{"Rendering":1},"classes":{"p5.Graphics":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer.js":{"name":"src/core/p5.Renderer.js","modules":{},"classes":{"p5.Renderer":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer2D.js":{"name":"src/core/p5.Renderer2D.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/reference.js":{"name":"src/core/reference.js","modules":{"Foundation":1},"classes":{},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{}},"src/core/rendering.js":{"name":"src/core/rendering.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shim.js":{"name":"src/core/shim.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/structure.js":{"name":"src/core/structure.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/transform.js":{"name":"src/core/transform.js","modules":{"Transform":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/local_storage.js":{"name":"src/data/local_storage.js","modules":{"LocalStorage":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/p5.TypedDict.js":{"name":"src/data/p5.TypedDict.js","modules":{"Dictionary":1},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"namespaces":{}},"src/dom/dom.js":{"name":"src/dom/dom.js","modules":{},"classes":{"p5.MediaElement":1,"p5.File":1},"fors":{"p5":1,"p5.Element":1},"namespaces":{}},"src/events/acceleration.js":{"name":"src/events/acceleration.js","modules":{"Acceleration":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/keyboard.js":{"name":"src/events/keyboard.js","modules":{"Keyboard":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/mouse.js":{"name":"src/events/mouse.js","modules":{"Mouse":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/touch.js":{"name":"src/events/touch.js","modules":{"Touch":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/filters.js":{"name":"src/image/filters.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/image/image.js":{"name":"src/image/image.js","modules":{"Image":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/loading_displaying.js":{"name":"src/image/loading_displaying.js","modules":{"Loading & Displaying":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/p5.Image.js":{"name":"src/image/p5.Image.js","modules":{},"classes":{"p5.Image":1},"fors":{},"namespaces":{}},"src/image/pixels.js":{"name":"src/image/pixels.js","modules":{"Pixels":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/io/files.js":{"name":"src/io/files.js","modules":{"Input":1,"Output":1},"classes":{"p5.PrintWriter":1},"fors":{"p5":1},"namespaces":{}},"src/io/p5.Table.js":{"name":"src/io/p5.Table.js","modules":{"Table":1},"classes":{"p5.Table":1},"fors":{},"namespaces":{}},"src/io/p5.TableRow.js":{"name":"src/io/p5.TableRow.js","modules":{},"classes":{"p5.TableRow":1},"fors":{},"namespaces":{}},"src/io/p5.XML.js":{"name":"src/io/p5.XML.js","modules":{},"classes":{"p5.XML":1},"fors":{},"namespaces":{}},"src/math/calculation.js":{"name":"src/math/calculation.js","modules":{"Calculation":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/math.js":{"name":"src/math/math.js","modules":{"Vector":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/noise.js":{"name":"src/math/noise.js","modules":{"Noise":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/p5.Vector.js":{"name":"src/math/p5.Vector.js","modules":{},"classes":{"p5.Vector":1},"fors":{},"namespaces":{}},"src/math/random.js":{"name":"src/math/random.js","modules":{"Random":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/trigonometry.js":{"name":"src/math/trigonometry.js","modules":{"Trigonometry":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/attributes.js":{"name":"src/typography/attributes.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/loading_displaying.js":{"name":"src/typography/loading_displaying.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/p5.Font.js":{"name":"src/typography/p5.Font.js","modules":{},"classes":{"p5.Font":1},"fors":{},"namespaces":{}},"src/utilities/array_functions.js":{"name":"src/utilities/array_functions.js","modules":{"Array Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/conversion.js":{"name":"src/utilities/conversion.js","modules":{"Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/string_functions.js":{"name":"src/utilities/string_functions.js","modules":{"String Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/time_date.js":{"name":"src/utilities/time_date.js","modules":{"Time & Date":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/3d_primitives.js":{"name":"src/webgl/3d_primitives.js","modules":{"3D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/interaction.js":{"name":"src/webgl/interaction.js","modules":{"Interaction":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/light.js":{"name":"src/webgl/light.js","modules":{"Lights":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/loading.js":{"name":"src/webgl/loading.js","modules":{"3D Models":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/material.js":{"name":"src/webgl/material.js","modules":{"Material":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Camera.js":{"name":"src/webgl/p5.Camera.js","modules":{"Camera":1},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{}},"src/webgl/p5.Geometry.js":{"name":"src/webgl/p5.Geometry.js","modules":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Matrix.js":{"name":"src/webgl/p5.Matrix.js","modules":{},"classes":{"p5.Matrix":1},"fors":{},"namespaces":{}},"src/webgl/p5.RenderBuffer.js":{"name":"src/webgl/p5.RenderBuffer.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Immediate.js":{"name":"src/webgl/p5.RendererGL.Immediate.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Retained.js":{"name":"src/webgl/p5.RendererGL.Retained.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.js":{"name":"src/webgl/p5.RendererGL.js","modules":{},"classes":{"p5.RendererGL":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Shader.js":{"name":"src/webgl/p5.Shader.js","modules":{},"classes":{"p5.Shader":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Texture.js":{"name":"src/webgl/p5.Texture.js","modules":{},"classes":{"p5.Texture":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/text.js":{"name":"src/webgl/text.js","modules":{},"classes":{"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{},"namespaces":{}},"lib/addons/p5.sound.js":{"name":"lib/addons/p5.sound.js","modules":{"p5.sound":1},"classes":{"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{}},"lib/addons/p5.sound.min.js":{"name":"lib/addons/p5.sound.min.js","modules":{},"classes":{},"fors":{},"namespaces":{}}},"modules":{"Environment":{"name":"Environment","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Environment","file":"src/accessibility/color_namer.js","line":1,"requires":["core"]},"Color":{"name":"Color","submodules":{"Color Conversion":1,"Creating & Reading":1,"Setting":1},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{},"file":"src/color/p5.Color.js","line":14},"Color Conversion":{"name":"Color Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/color_conversion.js","line":1,"requires":["core"]},"Creating & Reading":{"name":"Creating & Reading","submodules":{},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/p5.Color.js","line":14,"requires":["core","constants"],"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"},"Setting":{"name":"Setting","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/setting.js","line":1,"requires":["core","constants"]},"Shape":{"name":"Shape","submodules":{"2D Primitives":1,"Curves":1,"Vertex":1,"3D Primitives":1,"3D Models":1},"elements":{},"classes":{"p5.Geometry":1,"p5.Matrix":1},"fors":{"p5":1},"namespaces":{},"file":"src/webgl/p5.Matrix.js","line":19},"2D Primitives":{"name":"2D Primitives","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/2d_primitives.js","line":1,"requires":["core","constants"]},"Attributes":{"name":"Attributes","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/core/shape/attributes.js","line":1,"requires":["core","constants"]},"Curves":{"name":"Curves","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/curves.js","line":1,"requires":["core"]},"Vertex":{"name":"Vertex","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/vertex.js","line":1,"requires":["core","constants"]},"Constants":{"name":"Constants","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Constants","file":"src/core/constants.js","line":1},"Structure":{"name":"Structure","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"IO","file":"src/core/main.js","line":1,"requires":["constants"]},"DOM":{"name":"DOM","submodules":{},"elements":{},"classes":{"p5.Element":1,"p5.MediaElement":1,"p5.File":1},"fors":{"p5.Element":1,"p5":1},"namespaces":{},"module":"DOM","file":"src/dom/dom.js","line":3533,"description":"<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n","requires":["p5"]},"Rendering":{"name":"Rendering","submodules":{"undefined":1},"elements":{},"classes":{"p5.RendererGL":1,"p5.Graphics":1,"p5.Renderer":1},"fors":{"p5":1},"namespaces":{},"module":"Rendering","file":"src/webgl/p5.RendererGL.js","line":603,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"},"Foundation":{"name":"Foundation","submodules":{},"elements":{},"classes":{"JSON":1,"console":1},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{},"module":"Foundation","file":"src/core/reference.js","line":1},"Transform":{"name":"Transform","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Transform","file":"src/core/transform.js","line":1,"requires":["core","constants"]},"Data":{"name":"Data","submodules":{"LocalStorage":1,"Dictionary":1,"Array Functions":1,"Conversion":1,"String Functions":1},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5":1,"p5.TypedDict":1},"namespaces":{},"file":"src/data/p5.TypedDict.js","line":410},"LocalStorage":{"name":"LocalStorage","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/local_storage.js","line":1,"requires":["core\n\nThis module defines the p5 methods for working with local storage"]},"Dictionary":{"name":"Dictionary","submodules":{},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"requires":["core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."],"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"},"Events":{"name":"Events","submodules":{"Acceleration":1,"Keyboard":1,"Mouse":1,"Touch":1},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"Acceleration":{"name":"Acceleration","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/acceleration.js","line":1,"requires":["core"]},"Keyboard":{"name":"Keyboard","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/keyboard.js","line":1,"requires":["core"]},"Mouse":{"name":"Mouse","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/mouse.js","line":1,"requires":["core","constants"]},"Touch":{"name":"Touch","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/touch.js","line":1,"requires":["core"]},"Image":{"name":"Image","submodules":{"Pixels":1},"elements":{},"classes":{"p5.Image":1},"fors":{"p5":1},"namespaces":{},"module":"Image","file":"src/image/p5.Image.js","line":21,"requires":["core"],"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"},"Loading & Displaying":{"name":"Loading & Displaying","submodules":{},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/typography/p5.Font.js","line":13,"requires":["core"],"description":"<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"},"Pixels":{"name":"Pixels","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Image","namespace":"","file":"src/image/pixels.js","line":1,"requires":["core"]},"IO":{"name":"IO","submodules":{"Structure":1,"Input":1,"Output":1,"Table":1,"Time & Date":1},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1,"p5.Table":1,"p5.TableRow":1,"p5.XML":1},"fors":{"p5":1},"namespaces":{},"file":"src/io/p5.XML.js","line":9},"Input":{"name":"Input","submodules":{},"elements":{},"classes":{"p5.XML":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.XML.js","line":9,"requires":["core"],"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"},"Output":{"name":"Output","submodules":{},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/files.js","line":1200,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"},"Table":{"name":"Table","submodules":{},"elements":{},"classes":{"p5.Table":1,"p5.TableRow":1},"fors":{},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.TableRow.js","line":9,"requires":["core"],"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"},"Math":{"name":"Math","submodules":{"Calculation":1,"Vector":1,"Noise":1,"Random":1,"Trigonometry":1},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"namespaces":{},"file":"src/math/p5.Vector.js","line":10},"Calculation":{"name":"Calculation","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/calculation.js","line":1,"requires":["core"]},"Vector":{"name":"Vector","submodules":{},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/p5.Vector.js","line":10,"requires":["core"],"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"},"Noise":{"name":"Noise","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/noise.js","line":14,"requires":["core"]},"Random":{"name":"Random","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/random.js","line":1,"requires":["core"]},"Trigonometry":{"name":"Trigonometry","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/trigonometry.js","line":1,"requires":["core","constants"]},"Typography":{"name":"Typography","submodules":{"Attributes":1,"Loading & Displaying":1},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"namespaces":{},"file":"src/typography/p5.Font.js","line":13},"Array Functions":{"name":"Array Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/array_functions.js","line":1,"requires":["core"]},"Conversion":{"name":"Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/conversion.js","line":1,"requires":["core"]},"String Functions":{"name":"String Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/string_functions.js","line":1,"requires":["core"]},"Time & Date":{"name":"Time & Date","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/utilities/time_date.js","line":1,"requires":["core"]},"3D Primitives":{"name":"3D Primitives","submodules":{},"elements":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"requires":["core","p5.Geometry"],"description":"<p>p5 Geometry class</p>\n"},"3D":{"name":"3D","submodules":{"Interaction":1,"Lights":1,"Material":1,"Camera":1},"elements":{},"classes":{"p5.Camera":1,"p5.Shader":1,"p5.Texture":1,"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{},"file":"src/webgl/text.js","line":260},"Interaction":{"name":"Interaction","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/interaction.js","line":1,"requires":["core"]},"Lights":{"name":"Lights","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/light.js","line":1,"requires":["core"]},"3D Models":{"name":"3D Models","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/loading.js","line":1,"requires":["core","p5.Geometry"]},"Material":{"name":"Material","submodules":{},"elements":{},"classes":{"p5.Shader":1,"p5.Texture":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Texture.js","line":12,"requires":["core"],"description":"<p>This module defines the p5.Shader class</p>\n"},"Camera":{"name":"Camera","submodules":{},"elements":{},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"requires":["core"],"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"},"p5.sound":{"name":"p5.sound","submodules":{},"elements":{},"classes":{"p5.sound":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{},"module":"p5.sound","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>","tag":"main","itemtype":"main"}},"classes":{"p5":{"name":"p5","shortname":"p5","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/core/main.js","line":13,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n","is_constructor":1,"params":[{"name":"sketch","description":"<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n","type":"Function"},{"name":"node","description":"<p>element to attach canvas to</p>\n","type":"HTMLElement","optional":true}],"return":{"description":"a p5 instance","type":"P5"}},"p5.Color":{"name":"p5.Color","shortname":"p5.Color","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Color","submodule":"Creating & Reading","namespace":"","file":"src/color/p5.Color.js","line":14,"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n","is_constructor":1},"p5.Element":{"name":"p5.Element","shortname":"p5.Element","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/core/p5.Element.js","line":9,"description":"<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Graphics":{"name":"p5.Graphics","shortname":"p5.Graphics","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Graphics.js","line":10,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"},{"name":"renderer","description":"<p>the renderer to use, either P2D or WEBGL</p>\n","type":"Constant"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Renderer":{"name":"p5.Renderer","shortname":"p5.Renderer","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Renderer.js","line":10,"description":"<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true},{"name":"isMainCanvas","description":"<p>whether we're using it as main canvas</p>\n","type":"Boolean","optional":true}]},"JSON":{"name":"JSON","shortname":"JSON","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"console":{"name":"console","shortname":"console","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"p5.TypedDict":{"name":"p5.TypedDict","shortname":"p5.TypedDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":82,"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n","is_constructor":1},"p5.StringDict":{"name":"p5.StringDict","shortname":"p5.StringDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":394,"description":"<p>A simple Dictionary class for Strings.</p>\n","extends":"p5.TypedDict"},"p5.NumberDict":{"name":"p5.NumberDict","shortname":"p5.NumberDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"description":"<p>A simple Dictionary class for Numbers.</p>\n","is_constructor":1,"extends":"p5.TypedDict"},"p5.MediaElement":{"name":"p5.MediaElement","shortname":"p5.MediaElement","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":2377,"description":"<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"}]},"p5.File":{"name":"p5.File","shortname":"p5.File","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":3533,"description":"<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n","is_constructor":1,"params":[{"name":"file","description":"<p>File that is wrapped</p>\n","type":"File"}]},"p5.Image":{"name":"p5.Image","shortname":"p5.Image","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Image","submodule":"Image","namespace":"","file":"src/image/p5.Image.js","line":21,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n","example":["\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"],"is_constructor":1,"params":[{"name":"width","description":"","type":"Number"},{"name":"height","description":"","type":"Number"}]},"p5.PrintWriter":{"name":"p5.PrintWriter","shortname":"p5.PrintWriter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/io/files.js","line":1200,"params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"","type":"String","optional":true}]},"p5.Table":{"name":"p5.Table","shortname":"p5.Table","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.Table.js","line":33,"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n","is_constructor":1,"params":[{"name":"rows","description":"<p>An array of p5.TableRow objects</p>\n","type":"p5.TableRow[]","optional":true}]},"p5.TableRow":{"name":"p5.TableRow","shortname":"p5.TableRow","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.TableRow.js","line":9,"description":"<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n","is_constructor":1,"params":[{"name":"str","description":"<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n","type":"String","optional":true},{"name":"separator","description":"<p>comma separated values (csv) by default</p>\n","type":"String","optional":true}]},"p5.XML":{"name":"p5.XML","shortname":"p5.XML","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Input","namespace":"","file":"src/io/p5.XML.js","line":9,"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n","is_constructor":1,"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed"},"p5.Vector":{"name":"p5.Vector","shortname":"p5.Vector","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Math","submodule":"Vector","namespace":"","file":"src/math/p5.Vector.js","line":10,"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n","is_constructor":1,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"],"alt":"2 white ellipses. One center-left the other bottom right and off canvas"},"p5.Font":{"name":"p5.Font","shortname":"p5.Font","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Typography","submodule":"Loading & Displaying","namespace":"","file":"src/typography/p5.Font.js","line":13,"description":"<p>Base class for font handling</p>\n","is_constructor":1,"params":[{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Camera":{"name":"p5.Camera","shortname":"p5.Camera","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Camera","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n","params":[{"name":"rendererGL","description":"<p>instance of WebGL renderer</p>\n","type":"RendererGL"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes."},"p5.Geometry":{"name":"p5.Geometry","shortname":"p5.Geometry","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Shape","submodule":"3D Primitives","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"description":"<p>p5 Geometry class</p>\n","is_constructor":1,"params":[{"name":"detailX","description":"<p>number of vertices along the x-axis.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of vertices along the y-axis.</p>\n","type":"Integer","optional":true},{"name":"callback","description":"<p>function to call upon object instantiation.</p>\n","type":"Function","optional":true}]},"p5.Shader":{"name":"p5.Shader","shortname":"p5.Shader","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Material","namespace":"","file":"src/webgl/p5.Shader.js","line":11,"description":"<p>Shader class for WEBGL Mode</p>\n","is_constructor":1,"params":[{"name":"renderer","description":"<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n","type":"p5.RendererGL"},{"name":"vertSrc","description":"<p>source code for the vertex shader (as a string)</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader (as a string)</p>\n","type":"String"}]},"p5.sound":{"name":"p5.sound","shortname":"p5.sound","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":""},"p5.SoundFile":{"name":"p5.SoundFile","shortname":"p5.SoundFile","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":1405,"description":"<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true},{"name":"whileLoadingCallback","description":"<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"]},"p5.Amplitude":{"name":"p5.Amplitude","shortname":"p5.Amplitude","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3022,"description":"<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n","is_constructor":1,"params":[{"name":"smoothing","description":"<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"]},"p5.FFT":{"name":"p5.FFT","shortname":"p5.FFT","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3347,"description":"<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>","is_constructor":1,"params":[{"name":"smoothing","description":"<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n","type":"Number","optional":true},{"name":"bins","description":"<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"]},"p5.Oscillator":{"name":"p5.Oscillator","shortname":"p5.Oscillator","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4060,"description":"<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>","is_constructor":1,"params":[{"name":"freq","description":"<p>frequency defaults to 440Hz</p>\n","type":"Number","optional":true},{"name":"type","description":"<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"]},"p5.SinOsc":{"name":"p5.SinOsc","shortname":"p5.SinOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4602,"description":"<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.TriOsc":{"name":"p5.TriOsc","shortname":"p5.TriOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4629,"description":"<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SawOsc":{"name":"p5.SawOsc","shortname":"p5.SawOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4656,"description":"<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SqrOsc":{"name":"p5.SqrOsc","shortname":"p5.SqrOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4683,"description":"<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.Envelope":{"name":"p5.Envelope","shortname":"p5.Envelope","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4721,"description":"<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>","is_constructor":1,"example":["\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"]},"p5.Noise":{"name":"p5.Noise","shortname":"p5.Noise","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5620,"description":"<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"type","description":"<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n","type":"String"}]},"p5.Pulse":{"name":"p5.Pulse","shortname":"p5.Pulse","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5779,"description":"<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"freq","description":"<p>Frequency in oscillations per second (Hz)</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"]},"p5.AudioIn":{"name":"p5.AudioIn","shortname":"p5.AudioIn","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6015,"description":"<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>","is_constructor":1,"params":[{"name":"errorCallback","description":"<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"]},"p5.Effect":{"name":"p5.Effect","shortname":"p5.Effect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6423,"description":"<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n","is_constructor":1,"params":[{"name":"ac","description":"<p>Reference to the audio context of the p5 object</p>\n","type":"Object","optional":true},{"name":"input","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"output","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"_drywet","description":"<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n","type":"Object","optional":true},{"name":"wet","description":"<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n","type":"AudioNode","optional":true}]},"p5.Filter":{"name":"p5.Filter","shortname":"p5.Filter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6628,"description":"<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"type","description":"<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"]},"p5.LowPass":{"name":"p5.LowPass","shortname":"p5.LowPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6914,"description":"<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.HighPass":{"name":"p5.HighPass","shortname":"p5.HighPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6938,"description":"<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.BandPass":{"name":"p5.BandPass","shortname":"p5.BandPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6962,"description":"<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.EQ":{"name":"p5.EQ","shortname":"p5.EQ","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7105,"description":"<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect","params":[{"name":"_eqsize","description":"<p>Constructor will accept 3 or 8, defaults to 3</p>\n","type":"Number","optional":true}],"return":{"description":"p5.EQ object","type":"Object"},"example":["\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"]},"p5.Panner3D":{"name":"p5.Panner3D","shortname":"p5.Panner3D","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7602,"description":"<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n","is_constructor":1},"p5.Delay":{"name":"p5.Delay","shortname":"p5.Delay","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7926,"description":"<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"]},"p5.Reverb":{"name":"p5.Reverb","shortname":"p5.Reverb","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8308,"description":"<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"]},"p5.Convolver":{"name":"p5.Convolver","shortname":"p5.Convolver","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8549,"description":"<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>","extends":"p5.Effect","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call when loading succeeds</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"]},"p5.Phrase":{"name":"p5.Phrase","shortname":"p5.Phrase","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9103,"description":"<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>","is_constructor":1,"params":[{"name":"name","description":"<p>Name so that you can access the Phrase.</p>\n","type":"String"},{"name":"callback","description":"<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n","type":"Function"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"example":["\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"]},"p5.Part":{"name":"p5.Part","shortname":"p5.Part","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9185,"description":"<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>","is_constructor":1,"params":[{"name":"steps","description":"<p>Steps in the part</p>\n","type":"Number","optional":true},{"name":"tatums","description":"<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"]},"p5.Score":{"name":"p5.Score","shortname":"p5.Score","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9493,"description":"<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n","is_constructor":1,"params":[{"name":"parts","description":"<p>One or multiple parts, to be played in sequence.</p>\n","type":"p5.Part","optional":true,"multiple":true}]},"p5.SoundLoop":{"name":"p5.SoundLoop","shortname":"p5.SoundLoop","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9673,"description":"<p>SoundLoop</p>\n","is_constructor":1,"params":[{"name":"callback","description":"<p>this function will be called on each iteration of theloop</p>\n","type":"Function"},{"name":"interval","description":"<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n","type":"Number|String","optional":true}],"example":["\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"]},"p5.Compressor":{"name":"p5.Compressor","shortname":"p5.Compressor","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10036,"description":"<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect"},"p5.PeakDetect":{"name":"p5.PeakDetect","shortname":"p5.PeakDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10312,"description":"<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>","is_constructor":1,"params":[{"name":"freq1","description":"<p>lowFrequency - defaults to 20Hz</p>\n","type":"Number","optional":true},{"name":"freq2","description":"<p>highFrequency - defaults to 20000 Hz</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n","type":"Number","optional":true},{"name":"framesPerPeak","description":"<p>Defaults to 20.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"]},"p5.SoundRecorder":{"name":"p5.SoundRecorder","shortname":"p5.SoundRecorder","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10559,"description":"<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>","is_constructor":1,"example":["\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"]},"p5.Distortion":{"name":"p5.Distortion","shortname":"p5.Distortion","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10816,"description":"<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}]},"p5.Gain":{"name":"p5.Gain","shortname":"p5.Gain","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10973,"description":"<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n","is_constructor":1,"example":["\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"]},"p5.AudioVoice":{"name":"p5.AudioVoice","shortname":"p5.AudioVoice","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11149,"description":"<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n","is_constructor":1},"p5.MonoSynth":{"name":"p5.MonoSynth","shortname":"p5.MonoSynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11247,"description":"<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n","is_constructor":1,"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"]},"p5.OnsetDetect":{"name":"p5.OnsetDetect","shortname":"p5.OnsetDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11624,"description":"<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n","is_constructor":1,"params":[{"name":"freqLow","description":"<p>Low frequency</p>\n","type":"Number"},{"name":"freqHigh","description":"<p>High frequency</p>\n","type":"Number"},{"name":"threshold","description":"<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n","type":"Number"},{"name":"callback","description":"<p>Function to call when an onset is detected</p>\n","type":"Function"}]},"p5.PolySynth":{"name":"p5.PolySynth","shortname":"p5.PolySynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n","is_constructor":1,"params":[{"name":"synthVoice","description":"<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n","type":"Number","optional":true},{"name":"maxVoices","description":"<p>Number of voices, defaults to 8;</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"]}},"elements":{},"classitems":[{"file":"src/accessibility/describe.js","line":18,"description":"<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n","itemtype":"method","name":"describe","params":[{"name":"text","description":"<p>description of the canvas</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/describe.js","line":114,"description":"<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n","itemtype":"method","name":"describeElement","params":[{"name":"name","description":"<p>name of the element</p>\n","type":"String"},{"name":"text","description":"<p>description of the element</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":10,"description":"<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"textOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":88,"description":"<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"gridOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/color/color_conversion.js","line":8,"description":"<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":19,"description":"<p>Convert an HSBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":45,"description":"<p>Convert an HSBA array to RGBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":100,"description":"<p>Convert an HSLA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":123,"description":"<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":187,"description":"<p>Convert an RGBA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":226,"description":"<p>Convert an RGBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/creating_reading.js","line":16,"description":"<p>Extracts the alpha value from a color or pixel array.</p>\n","itemtype":"method","name":"alpha","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the alpha value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":43,"description":"<p>Extracts the blue value from a color or pixel array.</p>\n","itemtype":"method","name":"blue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the blue value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":69,"description":"<p>Extracts the HSB brightness value from a color or pixel array.</p>\n","itemtype":"method","name":"brightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the brightness value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":113,"description":"<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n","itemtype":"method","name":"color","return":{"description":"resulting color","type":"p5.Color"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading","overloads":[{"line":113,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"return":{"description":"resulting color","type":"p5.Color"}},{"line":257,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"return":{"description":"","type":"p5.Color"}},{"line":269,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"return":{"description":"","type":"p5.Color"}},{"line":275,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"return":{"description":"","type":"p5.Color"}},{"line":282,"params":[{"name":"color","description":"","type":"p5.Color"}],"return":{"description":"","type":"p5.Color"}}]},{"file":"src/color/creating_reading.js","line":297,"description":"<p>Extracts the green value from a color or pixel array.</p>\n","itemtype":"method","name":"green","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the green value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":325,"description":"<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n","itemtype":"method","name":"hue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the hue","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":359,"description":"<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n","itemtype":"method","name":"lerpColor","params":[{"name":"c1","description":"<p>interpolate from this color</p>\n","type":"p5.Color"},{"name":"c2","description":"<p>interpolate to this color</p>\n","type":"p5.Color"},{"name":"amt","description":"<p>number between 0 and 1</p>\n","type":"Number"}],"return":{"description":"interpolated color","type":"p5.Color"},"example":["\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":449,"description":"<p>Extracts the HSL lightness value from a color or pixel array.</p>\n","itemtype":"method","name":"lightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the lightness","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":478,"description":"<p>Extracts the red value from a color or pixel array.</p>\n","itemtype":"method","name":"red","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the red value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":517,"description":"<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n","itemtype":"method","name":"saturation","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the saturation value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":51,"description":"<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n","itemtype":"method","name":"toString","params":[{"name":"format","description":"<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n","type":"String","optional":true}],"return":{"description":"the formatted string","type":"String"},"example":["\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":254,"description":"<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setRed","params":[{"name":"red","description":"<p>the new red value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":281,"description":"<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setGreen","params":[{"name":"green","description":"<p>the new green value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":304,"description":"<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setBlue","params":[{"name":"blue","description":"<p>the new blue value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":327,"description":"<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setAlpha","params":[{"name":"alpha","description":"<p>the new alpha value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":396,"description":"<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":427,"description":"<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":446,"description":"<p>CSS named colors.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":600,"description":"<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":613,"description":"<p>Full color string patterns. The capture groups are necessary.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":960,"description":"<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/setting.js","line":13,"description":"<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n","itemtype":"method","name":"background","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":13,"params":[{"name":"color","description":"<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n","type":"p5.Color"}],"chainable":1},{"line":130,"params":[{"name":"colorstring","description":"<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n","type":"String"},{"name":"a","description":"<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":140,"params":[{"name":"gray","description":"<p>specifies a value between white and black</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":147,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current color\n                       mode)</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":159,"params":[{"name":"values","description":"<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":166,"params":[{"name":"image","description":"<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n","type":"p5.Image"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":179,"description":"<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n","itemtype":"method","name":"clear","chainable":1,"example":["\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"],"params":[{"name":"r","description":"<p>normalized red val.</p>\n","type":"Number"},{"name":"g","description":"<p>normalized green val.</p>\n","type":"Number"},{"name":"b","description":"<p>normalized blue val.</p>\n","type":"Number"},{"name":"a","description":"<p>normalized alpha val.</p>\n","type":"Number"}],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":229,"description":"<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n","itemtype":"method","name":"colorMode","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":229,"params":[{"name":"mode","description":"<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n","type":"Constant"},{"name":"max","description":"<p>range for all values</p>\n","type":"Number","optional":true}],"chainable":1},{"line":306,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"max1","description":"<p>range for the red or hue depending on the\n                             current color mode</p>\n","type":"Number"},{"name":"max2","description":"<p>range for the green or saturation depending\n                             on the current color mode</p>\n","type":"Number"},{"name":"max3","description":"<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n","type":"Number"},{"name":"maxA","description":"<p>range for the alpha</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":350,"description":"<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n","itemtype":"method","name":"fill","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":350,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":475,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":481,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":488,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":495,"params":[{"name":"color","description":"<p>the fill color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":507,"description":"<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noFill","chainable":1,"example":["\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":547,"description":"<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noStroke","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":585,"description":"<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n","itemtype":"method","name":"stroke","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":585,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":722,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":728,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":735,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":742,"params":[{"name":"color","description":"<p>the stroke color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":755,"description":"<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n","itemtype":"method","name":"erase","params":[{"name":"strengthFill","description":"<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true},{"name":"strengthStroke","description":"<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":836,"description":"<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n","itemtype":"method","name":"noErase","chainable":1,"example":["\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/core/friendly_errors/fes_core.js","line":1,"requires":["core\n\nThis is the main file for the Friendly Error System (FES)","containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters","(2) _friendlyFileLoadError","(3) _friendlyError","(4) helpForMisusedAtTopLevelCode","or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this","there's also a file stacktrace.js","which contains the code\nto parse the error stack","borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions","including the call\nsequence of each function","please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/fes_core.js","line":915,"description":"<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n","class":"p5","module":"Color"},{"file":"src/core/friendly_errors/file_errors.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/sketch_reader.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/stacktrace.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/validate_params.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/shape/2d_primitives.js","line":16,"description":"<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n","class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":102,"description":"<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n","itemtype":"method","name":"arc","params":[{"name":"x","description":"<p>x-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"w","description":"<p>width of the arc's ellipse by default</p>\n","type":"Number"},{"name":"h","description":"<p>height of the arc's ellipse by default</p>\n","type":"Number"},{"name":"start","description":"<p>angle to start the arc, specified in radians</p>\n","type":"Number"},{"name":"stop","description":"<p>angle to stop the arc, specified in radians</p>\n","type":"Number"},{"name":"mode","description":"<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n","type":"Constant","optional":true},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":235,"description":"<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n","itemtype":"method","name":"ellipse","chainable":1,"example":["\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":235,"params":[{"name":"x","description":"<p>x-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the ellipse.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the ellipse.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":261,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}]}]},{"file":"src/core/shape/2d_primitives.js","line":277,"description":"<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n","itemtype":"method","name":"circle","params":[{"name":"x","description":"<p>x-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"d","description":"<p>diameter of the circle.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":340,"description":"<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n","itemtype":"method","name":"line","chainable":1,"example":["\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":340,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"}],"chainable":1},{"line":379,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":404,"description":"<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n","itemtype":"method","name":"point","chainable":1,"example":["\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":404,"params":[{"name":"x","description":"<p>the x-coordinate</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate</p>\n","type":"Number"},{"name":"z","description":"<p>the z-coordinate (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":455,"params":[{"name":"coordinate_vector","description":"<p>the coordinate vector</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":483,"description":"<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n","itemtype":"method","name":"quad","chainable":1,"example":["\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":483,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>the x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>the y-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"<p>the x-coordinate of the fourth point</p>\n","type":"Number"},{"name":"y4","description":"<p>the y-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction</p>\n","type":"Integer","optional":true}],"chainable":1},{"line":512,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>the z-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>the z-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"","type":"Integer","optional":true},{"name":"detailY","description":"","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":556,"description":"<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"rect","chainable":1,"example":["\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":556,"params":[{"name":"x","description":"<p>x-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the rectangle.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the rectangle.</p>\n","type":"Number","optional":true},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":608,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction (for WebGL mode)</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction (for WebGL mode)</p>\n","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":623,"description":"<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"square","params":[{"name":"x","description":"<p>x-coordinate of the square.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the square.</p>\n","type":"Number"},{"name":"s","description":"<p>side size of the square.</p>\n","type":"Number"},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":713,"description":"<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n","itemtype":"method","name":"triangle","params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate of the third point</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/attributes.js","line":12,"description":"<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"ellipseMode","params":[{"name":"mode","description":"<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"],"alt":"60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":81,"description":"<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"noSmooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses to left & right of center, black background","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":115,"description":"<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"rectMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"],"alt":"50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":184,"description":"<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"smooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses one left one right of center. On black.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":219,"description":"<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeCap","params":[{"name":"cap","description":"<p>either ROUND, SQUARE or PROJECT</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"],"alt":"3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":259,"description":"<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeJoin","params":[{"name":"join","description":"<p>either MITER, BEVEL, ROUND</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"],"alt":"Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":331,"description":"<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n","itemtype":"method","name":"strokeWeight","params":[{"name":"weight","description":"<p>the weight of the stroke (in pixels)</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"],"alt":"3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/curves.js","line":13,"description":"<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n","itemtype":"method","name":"bezier","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"],"alt":"stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":13,"params":[{"name":"x1","description":"<p>x-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the second anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1},{"line":62,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":92,"description":"<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n","itemtype":"method","name":"bezierDetail","params":[{"name":"detail","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"],"alt":"stretched black s-shape with a low level of bezier detail","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":130,"description":"<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n","itemtype":"method","name":"bezierPoint","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the value of the Bezier at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"],"alt":"10 points plotted on a given bezier at equal distances.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":185,"description":"<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n","itemtype":"method","name":"bezierTangent","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":264,"description":"<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n","itemtype":"method","name":"curve","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"],"alt":"horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":264,"params":[{"name":"x1","description":"<p>x-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the ending control point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1},{"line":332,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":358,"description":"<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n","itemtype":"method","name":"curveDetail","params":[{"name":"resolution","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"],"alt":"white arch shape with a low level of curve detail.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":398,"description":"<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n","itemtype":"method","name":"curveTightness","params":[{"name":"amount","description":"<p>amount of deformation from the original vertices</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"],"alt":"Line shaped like right-facing arrow,points move with mouse-x and warp shape.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":444,"description":"<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n","itemtype":"method","name":"curvePoint","params":[{"name":"a","description":"<p>coordinate of first control point of the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"bezier value at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"],"class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":493,"description":"<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n","itemtype":"method","name":"curveTangent","params":[{"name":"a","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second conrol point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"right curving line mid-right of canvas with 7 short lines radiating from it.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/vertex.js","line":20,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"beginContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":67,"description":"<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"beginShape","params":[{"name":"kind","description":"<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":293,"description":"<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"bezierVertex","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"],"alt":"crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":293,"params":[{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":375,"params":[{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":415,"description":"<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n","itemtype":"method","name":"curveVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"],"alt":"Upside-down u-shape line, mid canvas. left point extends beyond canvas view.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":415,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":460,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":524,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"endContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":583,"description":"<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n","itemtype":"method","name":"endShape","params":[{"name":"mode","description":"<p>use CLOSE to close the shape</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"],"alt":"Triangle line shape with smallest interior angle on bottom and upside-down L.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":668,"description":"<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"quadraticVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"],"alt":"arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":668,"params":[{"name":"cx","description":"<p>x-coordinate for the control point</p>\n","type":"Number"},{"name":"cy","description":"<p>y-coordinate for the control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":733,"params":[{"name":"cx","description":"","type":"Number"},{"name":"cy","description":"","type":"Number"},{"name":"cz","description":"<p>z-coordinate for the control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":826,"description":"<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n","itemtype":"method","name":"vertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"],"alt":"4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":826,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":957,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n","type":"Number"}],"chainable":1},{"line":965,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true},{"name":"u","description":"<p>the vertex's texture u-coordinate</p>\n","type":"Number"},{"name":"v","description":"<p>the vertex's texture v-coordinate</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":1003,"description":"<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n","itemtype":"method","name":"normal","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":1003,"params":[{"name":"vector","description":"<p>A p5.Vector representing the vertex normal.</p>\n","type":"Vector"}],"chainable":1},{"line":1040,"params":[{"name":"x","description":"<p>The x component of the vertex normal.</p>\n","type":"Number"},{"name":"y","description":"<p>The y component of the vertex normal.</p>\n","type":"Number"},{"name":"z","description":"<p>The z component of the vertex normal.</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/constants.js","line":9,"description":"<p>Version of this p5.js.</p>\n","itemtype":"property","name":"VERSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":18,"description":"<p>The default, two-dimensional renderer.</p>\n","itemtype":"property","name":"P2D","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":24,"description":"<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n","itemtype":"property","name":"WEBGL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":33,"itemtype":"property","name":"ARROW","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":38,"itemtype":"property","name":"CROSS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":43,"itemtype":"property","name":"HAND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":48,"itemtype":"property","name":"MOVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":53,"itemtype":"property","name":"TEXT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":58,"itemtype":"property","name":"WAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":66,"description":"<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"HALF_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"],"alt":"80×80 white quarter-circle with curve toward bottom right of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":84,"description":"<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"],"alt":"white half-circle with curve toward bottom of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":102,"description":"<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"QUARTER_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"],"alt":"white eighth-circle rotated about 40 degrees with curve bottom right canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":120,"description":"<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TAU","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":138,"description":"<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TWO_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":156,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n","itemtype":"property","name":"DEGREES","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":170,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n","itemtype":"property","name":"RADIANS","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":188,"itemtype":"property","name":"CORNER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":193,"itemtype":"property","name":"CORNERS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":198,"itemtype":"property","name":"RADIUS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":203,"itemtype":"property","name":"RIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":208,"itemtype":"property","name":"LEFT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":213,"itemtype":"property","name":"CENTER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":218,"itemtype":"property","name":"TOP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":223,"itemtype":"property","name":"BOTTOM","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":228,"itemtype":"property","name":"BASELINE","type":"String","final":1,"default":"alphabetic","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":234,"itemtype":"property","name":"POINTS","type":"Number","final":1,"default":"0x0000","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":240,"itemtype":"property","name":"LINES","type":"Number","final":1,"default":"0x0001","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":246,"itemtype":"property","name":"LINE_STRIP","type":"Number","final":1,"default":"0x0003","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":252,"itemtype":"property","name":"LINE_LOOP","type":"Number","final":1,"default":"0x0002","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":258,"itemtype":"property","name":"TRIANGLES","type":"Number","final":1,"default":"0x0004","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":264,"itemtype":"property","name":"TRIANGLE_FAN","type":"Number","final":1,"default":"0x0006","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":270,"itemtype":"property","name":"TRIANGLE_STRIP","type":"Number","final":1,"default":"0x0005","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":276,"itemtype":"property","name":"QUADS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":281,"itemtype":"property","name":"QUAD_STRIP","type":"String","final":1,"default":"quad_strip","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":287,"itemtype":"property","name":"TESS","type":"String","final":1,"default":"tess","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":293,"itemtype":"property","name":"CLOSE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":298,"itemtype":"property","name":"OPEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":303,"itemtype":"property","name":"CHORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":308,"itemtype":"property","name":"PIE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":313,"itemtype":"property","name":"PROJECT","type":"String","final":1,"default":"square","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":319,"itemtype":"property","name":"SQUARE","type":"String","final":1,"default":"butt","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":325,"itemtype":"property","name":"ROUND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":330,"itemtype":"property","name":"BEVEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":335,"itemtype":"property","name":"MITER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":342,"itemtype":"property","name":"RGB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":347,"description":"<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n","itemtype":"property","name":"HSB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":356,"itemtype":"property","name":"HSL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":363,"description":"<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n","itemtype":"property","name":"AUTO","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":373,"itemtype":"property","name":"ALT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":379,"itemtype":"property","name":"BACKSPACE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":384,"itemtype":"property","name":"CONTROL","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":389,"itemtype":"property","name":"DELETE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":394,"itemtype":"property","name":"DOWN_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":399,"itemtype":"property","name":"ENTER","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":404,"itemtype":"property","name":"ESCAPE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":409,"itemtype":"property","name":"LEFT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":414,"itemtype":"property","name":"OPTION","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":419,"itemtype":"property","name":"RETURN","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":424,"itemtype":"property","name":"RIGHT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":429,"itemtype":"property","name":"SHIFT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":434,"itemtype":"property","name":"TAB","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":439,"itemtype":"property","name":"UP_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":446,"itemtype":"property","name":"BLEND","type":"String","final":1,"default":"source-over","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":452,"itemtype":"property","name":"REMOVE","type":"String","final":1,"default":"destination-out","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":458,"itemtype":"property","name":"ADD","type":"String","final":1,"default":"lighter","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":466,"itemtype":"property","name":"DARKEST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":471,"itemtype":"property","name":"LIGHTEST","type":"String","final":1,"default":"lighten","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":477,"itemtype":"property","name":"DIFFERENCE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":482,"itemtype":"property","name":"SUBTRACT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":487,"itemtype":"property","name":"EXCLUSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":492,"itemtype":"property","name":"MULTIPLY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":497,"itemtype":"property","name":"SCREEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":502,"itemtype":"property","name":"REPLACE","type":"String","final":1,"default":"copy","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":508,"itemtype":"property","name":"OVERLAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":513,"itemtype":"property","name":"HARD_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":518,"itemtype":"property","name":"SOFT_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":523,"itemtype":"property","name":"DODGE","type":"String","final":1,"default":"color-dodge","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":529,"itemtype":"property","name":"BURN","type":"String","final":1,"default":"color-burn","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":537,"itemtype":"property","name":"THRESHOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":542,"itemtype":"property","name":"GRAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":547,"itemtype":"property","name":"OPAQUE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":552,"itemtype":"property","name":"INVERT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":557,"itemtype":"property","name":"POSTERIZE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":562,"itemtype":"property","name":"DILATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":567,"itemtype":"property","name":"ERODE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":572,"itemtype":"property","name":"BLUR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":579,"itemtype":"property","name":"NORMAL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":584,"itemtype":"property","name":"ITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":589,"itemtype":"property","name":"BOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":594,"itemtype":"property","name":"BOLDITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":599,"itemtype":"property","name":"CHAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":604,"itemtype":"property","name":"WORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":616,"itemtype":"property","name":"LINEAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":621,"itemtype":"property","name":"QUADRATIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":626,"itemtype":"property","name":"BEZIER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":631,"itemtype":"property","name":"CURVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":638,"itemtype":"property","name":"STROKE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":643,"itemtype":"property","name":"FILL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":648,"itemtype":"property","name":"TEXTURE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":653,"itemtype":"property","name":"IMMEDIATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":661,"itemtype":"property","name":"IMAGE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":669,"itemtype":"property","name":"NEAREST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":674,"itemtype":"property","name":"REPEAT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":679,"itemtype":"property","name":"CLAMP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":684,"itemtype":"property","name":"MIRROR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":691,"itemtype":"property","name":"LANDSCAPE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":696,"itemtype":"property","name":"PORTRAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":706,"itemtype":"property","name":"GRID","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":712,"itemtype":"property","name":"AXES","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":718,"itemtype":"property","name":"LABEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":723,"itemtype":"property","name":"FALLBACK","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/environment.js","line":20,"description":"<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n","itemtype":"method","name":"print","params":[{"name":"contents","description":"<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n","type":"Any"}],"example":["\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"],"alt":"default grey canvas","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":52,"description":"<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n","itemtype":"property","name":"frameCount","type":"Integer","readonly":"","example":["\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"],"alt":"numbers rapidly counting upward with frame count set to 30.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":79,"description":"<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n","itemtype":"property","name":"deltaTime","type":"Integer","readonly":"","example":["\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":129,"description":"<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n","itemtype":"property","name":"focused","type":"Boolean","readonly":"","example":["\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"],"alt":"green 50×50 ellipse at top left. Red X covers canvas when page focus changes","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":160,"description":"<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n","itemtype":"method","name":"cursor","params":[{"name":"type","description":"<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n","type":"String|Constant"},{"name":"x","description":"<p>the horizontal active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the vertical active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"],"alt":"canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":228,"description":"<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n","itemtype":"method","name":"frameRate","chainable":1,"example":["\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"blue rect moves left to right, followed by red rect moving faster. Loops.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":228,"params":[{"name":"fps","description":"<p>number of frames to be displayed every second</p>\n","type":"Number"}],"chainable":1},{"line":288,"params":[],"return":{"description":"current frameRate","type":"Number"}}]},{"file":"src/core/environment.js","line":331,"description":"<p>Hides the cursor from view.</p>\n","itemtype":"method","name":"noCursor","example":["\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"],"alt":"cursor becomes 10×10 white ellipse the moves with mouse x and y.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":354,"description":"<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":372,"description":"<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":390,"description":"<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n","itemtype":"property","name":"windowWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":405,"description":"<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n","itemtype":"property","name":"windowHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":421,"description":"<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n","itemtype":"method","name":"windowResized","params":[{"name":"event","description":"<p>optional Event callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":476,"description":"<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":488,"description":"<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":500,"description":"<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n","itemtype":"method","name":"fullscreen","params":[{"name":"val","description":"<p>whether the sketch should be in fullscreen mode\nor not</p>\n","type":"Boolean","optional":true}],"return":{"description":"current fullscreen state","type":"Boolean"},"example":["\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":550,"description":"<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n","itemtype":"method","name":"pixelDensity","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":550,"params":[{"name":"val","description":"<p>whether or how much the sketch should scale</p>\n","type":"Number"}],"chainable":1},{"line":586,"params":[],"return":{"description":"current pixel density of the sketch","type":"Number"}}]},{"file":"src/core/environment.js","line":605,"description":"<p>Returns the pixel density of the current display the sketch is running on.</p>\n","itemtype":"method","name":"displayDensity","return":{"description":"current pixel density of the display","type":"Number"},"example":["\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":660,"description":"<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURL","return":{"description":"url","type":"String"},"example":["\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"],"alt":"current url (http://p5js.org/reference/#/p5/getURL) moves right to left.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":691,"description":"<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLPath","return":{"description":"path components","type":"String[]"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":713,"description":"<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLParams","return":{"description":"URL params","type":"Object"},"example":["\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/helpers.js","line":1,"requires":["constants"],"class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":30,"description":"<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":126,"description":"<p>Set up our translation function, with loaded languages</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":171,"description":"<p>Returns a list of languages we have translations loaded for</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":178,"description":"<p>Returns the current language selected for translation</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":185,"description":"<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/legacy.js","line":1,"requires":["core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name","in others","they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."],"class":"p5","module":"Environment"},{"file":"src/core/main.js","line":42,"description":"<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n","itemtype":"method","name":"preload","example":["\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":83,"description":"<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n","itemtype":"method","name":"setup","example":["\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":114,"description":"<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n","itemtype":"method","name":"draw","example":["\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":415,"description":"<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":693,"description":"<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n","itemtype":"property","name":"disableFriendlyErrors","type":"Boolean","example":["\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"],"class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/p5.Element.js","line":21,"description":"<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"],"itemtype":"property","name":"elt","readonly":"","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":47,"description":"<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"parent","chainable":1,"example":["\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":47,"params":[{"name":"parent","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n","type":"String|p5.Element|Object"}],"chainable":1},{"line":93,"params":[],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/core/p5.Element.js","line":114,"description":"<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n","itemtype":"method","name":"id","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":114,"params":[{"name":"id","description":"<p>ID of the element</p>\n","type":"String"}],"chainable":1},{"line":139,"params":[],"return":{"description":"the id of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":154,"description":"<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n","itemtype":"method","name":"class","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":154,"params":[{"name":"class","description":"<p>class to add</p>\n","type":"String"}],"chainable":1},{"line":176,"params":[],"return":{"description":"the class of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":189,"description":"<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":246,"description":"<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"return":{"description":"","type":"p5.Element"},"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":292,"description":"<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":354,"description":"<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":403,"description":"<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":454,"description":"<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":510,"description":"<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOver","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":551,"description":"<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOut","params":[{"name":"fxn","description":"<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":592,"description":"<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"fxn","description":"<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":639,"description":"<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"fxn","description":"<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":678,"description":"<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"fxn","description":"<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":725,"description":"<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragOver","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":763,"description":"<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragLeave","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":827,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Graphics.js","line":70,"description":"<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n","itemtype":"method","name":"reset","example":["\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"],"alt":"A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Graphics.js","line":122,"description":"<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"],"alt":"no image\na multi-colored circle moving back and forth over a scrolling background.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":99,"description":"<p>Resize our canvas element.</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":415,"description":"<p>Helper function to check font type (system or otf)</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":467,"description":"<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":7,"description":"<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":402,"description":"<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/reference.js","line":7,"description":"<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n","itemtype":"property","name":"let","example":["\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":34,"description":"<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n","itemtype":"property","name":"const","example":["\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"],"alt":"These examples do not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":87,"description":"<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n","itemtype":"property","name":"===","example":["\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":115,"description":"<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>","itemtype":"property","name":">","example":["\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":137,"description":"<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":">=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":158,"description":"<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<","example":["\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":179,"description":"<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":200,"description":"<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n","itemtype":"property","name":"if-else","example":["\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":231,"description":"<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n","itemtype":"property","name":"function","example":["\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":267,"description":"<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n","itemtype":"property","name":"return","example":["\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":288,"description":"<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n","itemtype":"property","name":"boolean","example":["\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":309,"description":"<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n","itemtype":"property","name":"string","example":["\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":331,"description":"<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n","itemtype":"property","name":"number","example":["\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":351,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n","itemtype":"property","name":"object","example":["\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":379,"description":"<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n","itemtype":"property","name":"class","example":["\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":408,"description":"<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n","itemtype":"property","name":"for","example":["\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":448,"description":"<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n","itemtype":"property","name":"while","example":["\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":490,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n","itemtype":"method","name":"stringify","static":1,"params":[{"name":"object","description":"<p>:Javascript object that you would like to convert to JSON</p>\n","type":"Object"}],"example":["\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"JSON","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":512,"description":"<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n","itemtype":"method","name":"log","static":1,"params":[{"name":"message","description":"<p>:Message that you would like to print to the console</p>\n","type":"String|Expression|Object"}],"example":["\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"console","module":"Foundation","submodule":"Foundation"},{"file":"src/core/rendering.js","line":15,"description":"<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"createCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL</p>\n","type":"Constant","optional":true}],"return":{"description":"","type":"p5.Renderer"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"],"alt":"Black line extending from top-left of canvas to bottom right.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":125,"description":"<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n","itemtype":"method","name":"resizeCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"noRedraw","description":"<p>don't redraw the canvas immediately</p>\n","type":"Boolean","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"No image displayed.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":183,"description":"<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n","itemtype":"method","name":"noCanvas","example":["\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":204,"description":"<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n","itemtype":"method","name":"createGraphics","params":[{"name":"w","description":"<p>width of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"h","description":"<p>height of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n","type":"Constant","optional":true}],"return":{"description":"offscreen graphics buffer","type":"p5.Graphics"},"example":["\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"4 grey squares alternating light and dark grey. White quarter circle mid-left.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":243,"description":"<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n","itemtype":"method","name":"blendMode","params":[{"name":"mode","description":"<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"],"alt":"translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":326,"description":"<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n","itemtype":"property","name":"drawingContext","example":["\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"white ellipse with shadow blur effect around edges","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/shim.js","line":18,"description":"<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/shim.js","line":39,"description":"<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n","class":"p5","module":"Rendering"},{"file":"src/core/structure.js","line":10,"description":"<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"noLoop","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"],"alt":"113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":83,"description":"<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"loop","example":["\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"],"alt":"horizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":134,"description":"<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n","itemtype":"method","name":"isLooping","example":["\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"],"alt":"Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":192,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"push","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":290,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"pop","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":391,"description":"<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n","itemtype":"method","name":"redraw","params":[{"name":"n","description":"<p>Redraw for n-times. The default value is 1.</p>\n","type":"Integer","optional":true}],"example":["\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"],"alt":"black line on far left of canvas\nblack line on far left of canvas","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":497,"description":"<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n","itemtype":"method","name":"p5","params":[{"name":"sketch","description":"<p>a function containing a p5.js sketch</p>\n","type":"Object"},{"name":"node","description":"<p>ID or pointer to HTML DOM node to contain sketch in</p>\n","type":"String|Object"}],"example":["\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"],"alt":"white rectangle on black background","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/transform.js","line":11,"description":"<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n","itemtype":"method","name":"applyMatrix","params":[{"name":"a","description":"<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n","type":"Number|Array"},{"name":"b","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"c","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"d","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"e","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"f","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":168,"description":"<p>Replaces the current matrix with the identity matrix.</p>\n","itemtype":"method","name":"resetMatrix","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"],"alt":"A rotated rectangle in the center with another at the top left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":193,"description":"<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"rotate","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"},{"name":"axis","description":"<p>(in 3d) the axis to rotate around</p>\n","type":"p5.Vector|Number[]","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":232,"description":"<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateX","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the x axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":268,"description":"<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateY","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the y axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":304,"description":"<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateZ","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the z axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":342,"description":"<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"scale","chainable":1,"example":["\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":342,"params":[{"name":"s","description":"<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n","type":"Number|p5.Vector|Number[]"},{"name":"y","description":"<p>percent to scale the object in the y-axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>percent to scale the object in the z-axis (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":386,"params":[{"name":"scales","description":"<p>per-axis percents to scale the object</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/core/transform.js","line":416,"description":"<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearX","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at top middle.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":455,"description":"<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearY","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at middle bottom.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":494,"description":"<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"translate","chainable":1,"example":["\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"],"alt":"white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":494,"params":[{"name":"x","description":"<p>left/right translation</p>\n","type":"Number"},{"name":"y","description":"<p>up/down translation</p>\n","type":"Number"},{"name":"z","description":"<p>forward/backward translation (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":547,"params":[{"name":"vector","description":"<p>the vector to translate by</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/data/local_storage.js","line":10,"description":"<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n","itemtype":"method","name":"storeItem","params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String|Number|Object|Boolean|p5.Color|p5.Vector"}],"example":["\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"],"alt":"When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":101,"description":"<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n","itemtype":"method","name":"getItem","params":[{"name":"key","description":"<p>name that you wish to use to store in local storage</p>\n","type":"String"}],"return":{"description":"Value of stored item","type":"Number|Object|String|Boolean|p5.Color|p5.Vector"},"example":["\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"],"alt":"If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":177,"description":"<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n","itemtype":"method","name":"clearStorage","example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":205,"description":"<p>Removes an item that was stored with storeItem()</p>\n","itemtype":"method","name":"removeItem","params":[{"name":"key","description":"","type":"String"}],"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/p5.TypedDict.js","line":14,"description":"<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n","itemtype":"method","name":"createStringDict","return":{"description":"","type":"p5.StringDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":14,"params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String"}],"return":{"description":"","type":"p5.StringDict"}},{"line":37,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.StringDict"}}]},{"file":"src/data/p5.TypedDict.js","line":48,"description":"<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n","itemtype":"method","name":"createNumberDict","return":{"description":"","type":"p5.NumberDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":48,"params":[{"name":"key","description":"","type":"Number"},{"name":"value","description":"","type":"Number"}],"return":{"description":"","type":"p5.NumberDict"}},{"line":71,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.NumberDict"}}]},{"file":"src/data/p5.TypedDict.js","line":101,"description":"<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n","itemtype":"method","name":"size","return":{"description":"the number of key-value pairs in the Dictionary","type":"Integer"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":122,"description":"<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n","itemtype":"method","name":"hasKey","params":[{"name":"key","description":"<p>that you want to look up</p>\n","type":"Number|String"}],"return":{"description":"whether that key exists in Dictionary","type":"Boolean"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":144,"description":"<p>Returns the value stored at the given key.</p>\n","itemtype":"method","name":"get","params":[{"name":"the","description":"<p>key you want to access</p>\n","type":"Number|String"}],"return":{"description":"the value stored at that key","type":"Number|String"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":170,"description":"<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n","itemtype":"method","name":"set","params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":197,"description":"<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":208,"description":"<p>Creates a new key-value pair in the Dictionary.</p>\n","itemtype":"method","name":"create","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary","overloads":[{"line":208,"params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}]},{"line":226,"params":[{"name":"obj","description":"<p>key/value pair</p>\n","type":"Object"}]}]},{"file":"src/data/p5.TypedDict.js","line":244,"description":"<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n","itemtype":"method","name":"clear","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":265,"description":"<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n","itemtype":"method","name":"remove","params":[{"name":"key","description":"<p>for the pair to remove</p>\n","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":294,"description":"<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n","itemtype":"method","name":"print","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":318,"description":"<p>Converts the Dictionary into a CSV file for local download.</p>\n","itemtype":"method","name":"saveTable","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":356,"description":"<p>Converts the Dictionary into a JSON file for local download.</p>\n","itemtype":"method","name":"saveJSON","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":387,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":425,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":432,"description":"<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"add","params":[{"name":"Key","description":"<p>for the value you wish to add to</p>\n","type":"Number"},{"name":"Number","description":"<p>to add to the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":459,"description":"<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"sub","params":[{"name":"Key","description":"<p>for the value you wish to subtract from</p>\n","type":"Number"},{"name":"Number","description":"<p>to subtract from the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":482,"description":"<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"mult","params":[{"name":"Key","description":"<p>for value you wish to multiply</p>\n","type":"Number"},{"name":"Amount","description":"<p>to multiply the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":509,"description":"<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"div","params":[{"name":"Key","description":"<p>for value you wish to divide</p>\n","type":"Number"},{"name":"Amount","description":"<p>to divide the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":536,"description":"<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":560,"description":"<p>Return the lowest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"minValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":580,"description":"<p>Return the highest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"maxValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":600,"description":"<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":622,"description":"<p>Return the lowest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"minKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":642,"description":"<p>Return the highest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"maxKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/dom/dom.js","line":21,"description":"<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n","itemtype":"method","name":"select","params":[{"name":"selectors","description":"<p>CSS selector string of element to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"<a href=\"#/p5.Element\">p5.Element</a> containing node found","type":"p5.Element|null"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":68,"description":"<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n","itemtype":"method","name":"selectAll","params":[{"name":"selectors","description":"<p>CSS selector string of elements to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found","type":"p5.Element[]"},"example":["\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":127,"description":"<p>Helper function for select and selectAll</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":142,"description":"<p>Helper function for getElement and getElements.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":176,"description":"<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n","itemtype":"method","name":"removeElements","example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":204,"description":"<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n","itemtype":"method","name":"changed","params":[{"name":"fxn","description":"<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"],"alt":"dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":271,"description":"<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n","itemtype":"method","name":"input","params":[{"name":"fxn","description":"<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"alt":"no display.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":309,"description":"<p>Helpers for create methods.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":322,"description":"<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createDiv","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":341,"description":"<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n","itemtype":"method","name":"createP","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":361,"description":"<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createSpan","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":379,"description":"<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n","itemtype":"method","name":"createImg","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":379,"params":[{"name":"src","description":"<p>src path or url for image</p>\n","type":"String"},{"name":"alt","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":396,"params":[{"name":"src","description":"","type":"String"},{"name":"alt","description":"","type":"String"},{"name":"crossOrigin","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n","type":"String"},{"name":"successCallback","description":"<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":426,"description":"<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n","itemtype":"method","name":"createA","params":[{"name":"href","description":"<p>url of page to link to</p>\n","type":"String"},{"name":"html","description":"<p>inner html of link element to display</p>\n","type":"String"},{"name":"target","description":"<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":450,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":452,"description":"<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n","itemtype":"method","name":"createSlider","params":[{"name":"min","description":"<p>minimum value of the slider</p>\n","type":"Number"},{"name":"max","description":"<p>maximum value of the slider</p>\n","type":"Number"},{"name":"value","description":"<p>default value of the slider</p>\n","type":"Number","optional":true},{"name":"step","description":"<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n","type":"Number","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":507,"description":"<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n","itemtype":"method","name":"createButton","params":[{"name":"label","description":"<p>label displayed on the button</p>\n","type":"String"},{"name":"value","description":"<p>value of the button</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":541,"description":"<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n","itemtype":"method","name":"createCheckbox","params":[{"name":"label","description":"<p>label displayed after checkbox</p>\n","type":"String","optional":true},{"name":"value","description":"<p>value of the checkbox; checked is true, unchecked is false</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":622,"description":"<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n","itemtype":"method","name":"createSelect","return":{"description":"","type":"p5.Element"},"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":622,"params":[{"name":"multiple","description":"<p>true if dropdown should support multiple selections</p>\n","type":"Boolean","optional":true}],"return":{"description":"","type":"p5.Element"}},{"line":673,"params":[{"name":"existing","description":"<p>DOM select element</p>\n","type":"Object"}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":770,"description":"<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n","itemtype":"method","name":"createRadio","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":770,"params":[{"name":"containerElement","description":"<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n","type":"Object"},{"name":"name","description":"<p>A name parameter for each Input Element.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":832,"params":[{"name":"name","description":"","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":837,"params":[],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":978,"description":"<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n","itemtype":"method","name":"createColorPicker","params":[{"name":"value","description":"<p>default color of element</p>\n","type":"String|p5.Color","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1066,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n","itemtype":"method","name":"createInput","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":1066,"params":[{"name":"value","description":"<p>default value of the input box</p>\n","type":"String"},{"name":"type","description":"<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":1091,"params":[{"name":"value","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":1104,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n","itemtype":"method","name":"createFileInput","params":[{"name":"callback","description":"<p>callback function for when a file is loaded</p>\n","type":"Function"},{"name":"multiple","description":"<p>optional, to allow multiple files to be selected</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element","type":"p5.Element"},"example":["\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1164,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1211,"description":"<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n","itemtype":"method","name":"createVideo","params":[{"name":"src","description":"<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n","type":"String|String[]"},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1257,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1259,"description":"<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n","itemtype":"method","name":"createAudio","params":[{"name":"src","description":"<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n","type":"String|String[]","optional":true},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1296,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1298,"itemtype":"property","name":"VIDEO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1304,"itemtype":"property","name":"AUDIO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1341,"description":"<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n","itemtype":"method","name":"createCapture","params":[{"name":"type","description":"<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n","type":"String|Constant|Object"},{"name":"callback","description":"<p>function to be called once\n                                  stream has loaded</p>\n","type":"Function","optional":true}],"return":{"description":"capture video <a href=\"#/p5.Element\">p5.Element</a>","type":"p5.Element"},"example":["\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1478,"description":"<p>Creates element with given tag in the DOM with given content.</p>\n","itemtype":"method","name":"createElement","params":[{"name":"tag","description":"<p>tag for the new element</p>\n","type":"String"},{"name":"content","description":"<p>html content to be inserted into the element</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1504,"description":"<p>Adds specified class to the element.</p>\n","itemtype":"method","name":"addClass","params":[{"name":"class","description":"<p>name of class to add</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1529,"description":"<p>Removes specified class from the element.</p>\n","itemtype":"method","name":"removeClass","params":[{"name":"class","description":"<p>name of class to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1560,"description":"<p>Checks if specified class already set to element</p>\n","itemtype":"method","name":"hasClass","return":{"description":"a boolean value if element has specified class","type":"Boolean"},"params":[{"name":"c","description":"<p>class name of class to check</p>\n","type":"String"}],"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1589,"description":"<p>Toggles element class</p>\n","itemtype":"method","name":"toggleClass","params":[{"name":"c","description":"<p>class name to toggle</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1622,"description":"<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n","itemtype":"method","name":"child","return":{"description":"an array of child nodes","type":"Node[]"},"example":["\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1622,"params":[],"return":{"description":"an array of child nodes","type":"Node[]"}},{"line":1650,"params":[{"name":"child","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n","type":"String|p5.Element","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1675,"description":"<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n","itemtype":"method","name":"center","params":[{"name":"align","description":"<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n","type":"String","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1726,"description":"<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n","itemtype":"method","name":"html","return":{"description":"the inner HTML of the element","type":"String"},"example":["\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1726,"params":[],"return":{"description":"the inner HTML of the element","type":"String"}},{"line":1747,"params":[{"name":"html","description":"<p>the HTML to be placed inside the element</p>\n","type":"String","optional":true},{"name":"append","description":"<p>whether to append HTML to existing</p>\n","type":"Boolean","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1765,"description":"<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n","itemtype":"method","name":"position","return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"},"example":["\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1765,"params":[],"return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"}},{"line":1798,"params":[{"name":"x","description":"<p>x-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"positionType","description":"<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n","type":"String","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1885,"description":"<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n","itemtype":"method","name":"style","return":{"description":"value of property","type":"String"},"example":["\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1885,"params":[{"name":"property","description":"<p>property to be set</p>\n","type":"String"}],"return":{"description":"value of property","type":"String"}},{"line":1923,"params":[{"name":"property","description":"","type":"String"},{"name":"value","description":"<p>value to assign to property</p>\n","type":"String|p5.Color"}],"chainable":1,"return":{"description":"current value of property, if no value is given as second argument","type":"String"}}]},{"file":"src/dom/dom.js","line":1980,"description":"<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n","itemtype":"method","name":"attribute","return":{"description":"value of attribute","type":"String"},"example":["\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1980,"params":[],"return":{"description":"value of attribute","type":"String"}},{"line":1995,"params":[{"name":"attr","description":"<p>attribute to set</p>\n","type":"String"},{"name":"value","description":"<p>value to assign to attribute</p>\n","type":"String"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2024,"description":"<p>Removes an attribute on the specified element.</p>\n","itemtype":"method","name":"removeAttribute","params":[{"name":"attr","description":"<p>attribute to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2069,"description":"<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n","itemtype":"method","name":"value","return":{"description":"value of the element","type":"String|Number"},"example":["\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2069,"params":[],"return":{"description":"value of the element","type":"String|Number"}},{"line":2099,"params":[{"name":"value","description":"","type":"String|Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2115,"description":"<p>Shows the current element. Essentially, setting display:block for the style.</p>\n","itemtype":"method","name":"show","chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2133,"description":"<p>Hides the current element. Essentially, setting display:none for the style.</p>\n","itemtype":"method","name":"hide","chainable":1,"example":["\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2149,"description":"<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n","itemtype":"method","name":"size","return":{"description":"the width and height of the element in an object","type":"Object"},"example":["\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2149,"params":[],"return":{"description":"the width and height of the element in an object","type":"Object"}},{"line":2173,"params":[{"name":"w","description":"<p>width of the element, either AUTO, or a number</p>\n","type":"Number|Constant"},{"name":"h","description":"<p>height of the element, either AUTO, or a number</p>\n","type":"Number|Constant","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":2230,"description":"<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2268,"description":"<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n","itemtype":"method","name":"drop","params":[{"name":"callback","description":"<p>callback to receive loaded file, called for each file dropped.</p>\n","type":"Function"},{"name":"fxn","description":"<p>callback triggered once when files are dropped with the drop event.</p>\n","type":"Function","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"],"alt":"Canvas turns into whatever image is dragged/dropped onto it.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2400,"description":"<p>Path to the media element source.</p>\n","itemtype":"property","name":"src","return":{"description":"src","type":"String"},"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2466,"description":"<p>Play an HTML5 media element.</p>\n","itemtype":"method","name":"play","chainable":1,"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2530,"description":"<p>Stops an HTML5 media element (sets current time to zero).</p>\n","itemtype":"method","name":"stop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2594,"description":"<p>Pauses an HTML5 media element.</p>\n","itemtype":"method","name":"pause","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2656,"description":"<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n","itemtype":"method","name":"loop","chainable":1,"example":["\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2712,"description":"<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n","itemtype":"method","name":"noLoop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2778,"description":"<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n","itemtype":"method","name":"autoplay","params":[{"name":"shouldAutoplay","description":"<p>whether the element should autoplay</p>\n","type":"Boolean"}],"chainable":1,"example":["\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"],"alt":"An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2845,"description":"<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n","itemtype":"method","name":"volume","return":{"description":"current volume","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2845,"params":[],"return":{"description":"current volume","type":"Number"}},{"line":2918,"params":[{"name":"val","description":"<p>volume between 0.0 and 1.0</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2931,"description":"<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n","itemtype":"method","name":"speed","return":{"description":"current playback speed of the element","type":"Number"},"example":["\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2931,"params":[],"return":{"description":"current playback speed of the element","type":"Number"}},{"line":3003,"params":[{"name":"speed","description":"<p>speed multiplier for element playback</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3020,"description":"<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n","itemtype":"method","name":"time","return":{"description":"current time (in seconds)","type":"Number"},"example":["\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":3020,"params":[],"return":{"description":"current time (in seconds)","type":"Number"}},{"line":3065,"params":[{"name":"time","description":"<p>time to jump to (in seconds)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3079,"description":"<p>Returns the duration of the HTML5 media element.</p>\n","itemtype":"method","name":"duration","return":{"description":"duration","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3201,"description":"<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n","type":"Function"}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3232,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3234,"description":"<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n","itemtype":"method","name":"connect","params":[{"name":"audioNode","description":"<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n","type":"AudioNode|Object"}],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3283,"description":"<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n","itemtype":"method","name":"disconnect","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3298,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3300,"description":"<p>Show the default MediaElement controls, as determined by the web browser.</p>\n","itemtype":"method","name":"showControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3331,"description":"<p>Hide the default mediaElement controls.</p>\n","itemtype":"method","name":"hideControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3360,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3371,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3434,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3476,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3542,"description":"<p>Underlying File object. All normal File methods can be called on this.</p>\n","itemtype":"property","name":"file","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3554,"description":"<p>File type (image, text, etc.)</p>\n","itemtype":"property","name":"type","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3560,"description":"<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n","itemtype":"property","name":"subtype","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3566,"description":"<p>File name</p>\n","itemtype":"property","name":"name","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3572,"description":"<p>File size</p>\n","itemtype":"property","name":"size","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3579,"description":"<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n","itemtype":"property","name":"data","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/events/acceleration.js","line":11,"description":"<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n","itemtype":"property","name":"deviceOrientation","type":"Constant","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":23,"description":"<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":46,"description":"<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":69,"description":"<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationZ","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":94,"description":"<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":104,"description":"<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":114,"description":"<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":135,"description":"<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationX","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":168,"description":"<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":201,"description":"<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"itemtype":"property","name":"rotationZ","type":"Number","readonly":"","alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":239,"description":"<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":285,"description":"<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":330,"description":"<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":389,"description":"<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n","itemtype":"property","name":"turnAxis","type":"String","readonly":"","example":["\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":428,"description":"<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n","itemtype":"method","name":"setMoveThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":471,"description":"<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n","itemtype":"method","name":"setShakeThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":515,"description":"<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n","itemtype":"method","name":"deviceMoved","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":546,"description":"<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n","itemtype":"method","name":"deviceTurned","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":604,"description":"<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n","itemtype":"method","name":"deviceShaken","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device shakes","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/keyboard.js","line":10,"description":"<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n","itemtype":"property","name":"keyIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white rect that turns black on keypress.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":36,"description":"<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n","itemtype":"property","name":"key","type":"String","readonly":"","example":["\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"],"alt":"canvas displays any key value that is pressed in pink font.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":64,"description":"<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n","itemtype":"property","name":"keyCode","type":"Integer","readonly":"","example":["\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"],"alt":"Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":103,"description":"<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyPressed","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":190,"description":"<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyReleased","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when pressed again","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":243,"description":"<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"keyTyped","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"],"alt":"black rect center. turns white when 'a' key typed and black when 'b' pressed","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":298,"description":"<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":308,"description":"<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n","itemtype":"method","name":"keyIsDown","params":[{"name":"code","description":"<p>The key to check for.</p>\n","type":"Number"}],"return":{"description":"whether key is down or not","type":"Boolean"},"example":["\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"],"alt":"50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/mouse.js","line":12,"description":"<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedX","type":"Number","readonly":"","example":["\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"],"alt":"box moves left and right according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":43,"description":"<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedY","type":"Number","readonly":"","example":["\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"box moves up and down according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":80,"description":"<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"],"alt":"horizontal black line moves left and right with mouse x-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":106,"description":"<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"],"alt":"vertical black line moves up and down with mouse y-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":132,"description":"<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"],"alt":"line trail is created from cursor movements. faster movement make longer line.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":164,"description":"<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"],"alt":"60×60 black rect center, fuchsia background. rect flickers on mouse movement","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":195,"description":"<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":233,"description":"<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":271,"description":"<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":311,"description":"<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":351,"description":"<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n","itemtype":"property","name":"mouseButton","type":"Constant","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"],"alt":"50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":389,"description":"<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n","itemtype":"property","name":"mouseIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":481,"description":"<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":535,"description":"<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseDragged","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":615,"description":"<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":696,"description":"<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":772,"description":"<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":841,"description":"<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":926,"description":"<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"event","description":"<p>optional WheelEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"],"alt":"black 50×50 rect moves up and down with vertical scroll. fuchsia background","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":979,"description":"<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n","itemtype":"method","name":"requestPointerLock","example":["\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"],"alt":"3D scene moves according to mouse mouse movement in a first person perspective","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":1025,"description":"<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n","itemtype":"method","name":"exitPointerLock","example":["\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"],"alt":"cursor gets locked / unlocked on mouse-click","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/touch.js","line":10,"description":"<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n","itemtype":"property","name":"touches","type":"Object[]","readonly":"","example":["\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"],"alt":"Number of touches currently registered are displayed on the canvas","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":71,"description":"<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch event.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":151,"description":"<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns lighter with touch until white. resets\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":223,"description":"<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/image/filters.js","line":3,"description":"<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n","class":"p5","module":"Events"},{"file":"src/image/image.js","line":8,"description":"<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":15,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n","itemtype":"method","name":"createImage","params":[{"name":"width","description":"<p>width in pixels</p>\n","type":"Integer"},{"name":"height","description":"<p>height in pixels</p>\n","type":"Integer"}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":94,"description":"<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n","itemtype":"method","name":"saveCanvas","example":["\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"],"alt":"no image displayed\n no image displayed\n no image displayed","class":"p5","module":"Image","submodule":"Image","overloads":[{"line":94,"params":[{"name":"selectedCanvas","description":"<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n","type":"p5.Element|HTMLCanvasElement"},{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String","optional":true}]},{"line":136,"params":[{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"","type":"String","optional":true}]}]},{"file":"src/image/image.js","line":413,"description":"<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n","itemtype":"method","name":"saveFrames","params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String"},{"name":"duration","description":"<p>Duration in seconds to save the frames for.</p>\n","type":"Number"},{"name":"framerate","description":"<p>Framerate to save the frames in.</p>\n","type":"Number"},{"name":"callback","description":"<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n","type":"Function(Array)","optional":true}],"example":["\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"],"alt":"canvas background goes from light to dark with mouse x.","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/loading_displaying.js","line":18,"description":"<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n","itemtype":"method","name":"loadImage","params":[{"name":"path","description":"<p>Path of the image to be loaded</p>\n","type":"String"},{"name":"successCallback","description":"<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n","type":"function(p5.Image)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                               the image fails to load.</p>\n","type":"Function(Event)","optional":true}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":162,"description":"<p>Helper function for loading GIF-based images</p>\n","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":301,"description":"<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n","itemtype":"method","name":"image","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":301,"params":[{"name":"img","description":"<p>the image to display</p>\n","type":"p5.Image|p5.Element|p5.Texture"},{"name":"x","description":"<p>the x-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"width","description":"<p>the width to draw the image</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>the height to draw the image</p>\n","type":"Number","optional":true}]},{"line":388,"params":[{"name":"img","description":"","type":"p5.Image|p5.Element|p5.Texture"},{"name":"dx","description":"<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dy","description":"<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dWidth","description":"<p>the width of the destination rectangle</p>\n","type":"Number"},{"name":"dHeight","description":"<p>the height of the destination rectangle</p>\n","type":"Number"},{"name":"sx","description":"<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sy","description":"<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sWidth","description":"<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n","type":"Number","optional":true},{"name":"sHeight","description":"<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n","type":"Number","optional":true}]}]},{"file":"src/image/loading_displaying.js","line":471,"description":"<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n","itemtype":"method","name":"tint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":471,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":542,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}]},{"line":547,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":553,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}]},{"line":559,"params":[{"name":"color","description":"<p>the tint color</p>\n","type":"p5.Color"}]}]},{"file":"src/image/loading_displaying.js","line":569,"description":"<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n","itemtype":"method","name":"noTint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of bricks, left image with blue tint","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":633,"description":"<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n","itemtype":"method","name":"imageMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, or CENTER</p>\n","type":"Constant"}],"example":["\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"],"alt":"small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/p5.Image.js","line":9,"description":"<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":88,"description":"<p>Image width.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"],"alt":"rocky mountains in top and horizontal lines in corresponding colors in bottom.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":115,"description":"<p>Image height.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"],"alt":"rocky mountains on right and vertical lines in corresponding colors on left.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":152,"description":"<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":222,"description":"<p>Helper function for animating GIF-based images with time</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":253,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":261,"description":"<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":296,"description":"<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n","itemtype":"method","name":"updatePixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":296,"params":[{"name":"x","description":"<p>x-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"y","description":"<p>y-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"w","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"h","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"}]},{"line":338,"params":[]}]},{"file":"src/image/p5.Image.js","line":346,"description":"<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"],"alt":"image of rocky mountains with 50×50 green rect in front","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":346,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":383,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":387,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/p5.Image.js","line":400,"description":"<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"a","description":"<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"],"alt":"2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":437,"description":"<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n","itemtype":"method","name":"resize","params":[{"name":"width","description":"<p>the resized image width</p>\n","type":"Number"},{"name":"height","description":"<p>the resized image height</p>\n","type":"Number"}],"example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"],"alt":"image of rocky mountains. zoomed in","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":548,"description":"<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains and smaller image on top of bricks at top left","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":548,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":588,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/p5.Image.js","line":603,"description":"<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n","itemtype":"method","name":"mask","params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"}],"example":["\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":665,"description":"<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"],"alt":"2 images of rocky mountains left one in color, right in black and white","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":738,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":738,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n","type":"Constant"}]},{"line":815,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/p5.Image.js","line":859,"description":"<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n","itemtype":"method","name":"save","params":[{"name":"filename","description":"<p>give your file a name</p>\n","type":"String"},{"name":"extension","description":"<p>'png' or 'jpg'</p>\n","type":"String"}],"example":["\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"],"alt":"image of rocky mountains.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":900,"description":"<p>Starts an animated GIF over at the beginning state.</p>\n","itemtype":"method","name":"reset","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"],"alt":"Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":941,"description":"<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n","itemtype":"method","name":"getCurrentFrame","return":{"description":"The index for the currently displaying frame in animated GIF","type":"Number"},"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"],"alt":"Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":972,"description":"<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n","itemtype":"method","name":"setFrame","params":[{"name":"index","description":"<p>the index for the frame that should be displayed</p>\n","type":"Number"}],"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1017,"description":"<p>Returns the number of frames in an animated GIF</p>\n","itemtype":"method","name":"numFrames","return":{"description":"","type":"Number"},"example":["     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1052,"description":"<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n","itemtype":"method","name":"play","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1089,"description":"<p>Pauses an animated GIF.</p>\n","itemtype":"method","name":"pause","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1125,"description":"<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n","itemtype":"method","name":"delay","params":[{"name":"d","description":"<p>the amount in milliseconds to delay between switching frames</p>\n","type":"Number"},{"name":"index","description":"<p>the index of the frame that should have the new delay value {optional}</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"],"alt":"Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/pixels.js","line":12,"description":"<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"],"alt":"top half of canvas pink, bottom grey","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":80,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":80,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n","type":"Constant"}]},{"line":152,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/pixels.js","line":173,"description":"<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":173,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":215,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/pixels.js","line":307,"description":"<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"],"alt":"black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":481,"description":"<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":481,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":551,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":555,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/pixels.js","line":566,"description":"<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":602,"description":"<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"c","description":"<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"],"alt":"4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":674,"description":"<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n","itemtype":"method","name":"updatePixels","params":[{"name":"x","description":"<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>width of region to update</p>\n","type":"Number","optional":true},{"name":"h","description":"<p>height of region to update</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/io/files.js","line":20,"description":"<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadJSON","return":{"description":"JSON data","type":"Object|Array"},"example":["\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"],"alt":"50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity","class":"p5","module":"IO","submodule":"Input","overloads":[{"line":20,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"jsonpOptions","description":"<p>options object for jsonp related settings</p>\n","type":"Object","optional":true},{"name":"datatype","description":"<p>\"json\" or \"jsonp\"</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"JSON data","type":"Object|Array"}},{"line":104,"params":[{"name":"path","description":"","type":"String"},{"name":"datatype","description":"","type":"String"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}},{"line":112,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}}]},{"file":"src/io/files.js","line":183,"description":"<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadStrings","params":[{"name":"filename","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":303,"description":"<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadTable","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"extension","description":"<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n","type":"String","optional":true},{"name":"header","description":"<p>\"header\" to indicate table has header row</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Table\">Table</a> object containing data","type":"Object"},"example":["\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":583,"description":"<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadXML","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"XML object containing data","type":"Object"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":693,"description":"<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadBytes","params":[{"name":"file","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if there\n                                   is an error</p>\n","type":"Function","optional":true}],"return":{"description":"an object whose 'bytes' property will be the loaded buffer","type":"Object"},"example":["\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":752,"description":"<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n","itemtype":"method","name":"httpGet","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":752,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":806,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":814,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":829,"description":"<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n","itemtype":"method","name":"httpPost","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":829,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":896,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":904,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":919,"description":"<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n","itemtype":"method","name":"httpDo","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":919,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"method","description":"<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n","type":"String","optional":true},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":990,"params":[{"name":"path","description":"","type":"String"},{"name":"options","description":"<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n","type":"Object"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":1155,"itemtype":"method","name":"createWriter","params":[{"name":"name","description":"<p>name of the file to be created</p>\n","type":"String"},{"name":"extension","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.PrintWriter"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1210,"description":"<p>Writes data to the PrintWriter stream</p>\n","itemtype":"method","name":"write","params":[{"name":"data","description":"<p>all data to be written by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1269,"description":"<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n","itemtype":"method","name":"print","params":[{"name":"data","description":"<p>all data to be printed by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1310,"description":"<p>Clears the data already written to the PrintWriter object</p>\n","itemtype":"method","name":"clear","example":["\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1344,"description":"<p>Closes the PrintWriter</p>\n","itemtype":"method","name":"close","example":["\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1393,"description":"<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n","itemtype":"method","name":"save","params":[{"name":"objectOrFilename","description":"<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n","type":"Object|String","optional":true},{"name":"filename","description":"<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n","type":"String","optional":true},{"name":"options","description":"<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n","type":"Boolean|String","optional":true}],"example":["\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"],"alt":"An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1535,"description":"<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveJSON","params":[{"name":"json","description":"","type":"Array|Object"},{"name":"filename","description":"","type":"String"},{"name":"optimize","description":"<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1592,"description":"<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveStrings","params":[{"name":"list","description":"<p>string array to be written</p>\n","type":"String[]"},{"name":"filename","description":"<p>filename for output</p>\n","type":"String"},{"name":"extension","description":"<p>the filename's extension</p>\n","type":"String","optional":true},{"name":"isCRLF","description":"<p>if true, change line-break to CRLF</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1656,"description":"<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveTable","params":[{"name":"Table","description":"<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n","type":"p5.Table"},{"name":"filename","description":"<p>the filename to which the Table should be saved</p>\n","type":"String"},{"name":"options","description":"<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n","type":"String","optional":true}],"example":["\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/p5.Table.js","line":9,"description":"<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":43,"description":"<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n","itemtype":"property","name":"columns","type":"String[]","example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":77,"description":"<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n","itemtype":"property","name":"rows","type":"p5.TableRow[]","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":85,"description":"<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n","itemtype":"method","name":"addRow","params":[{"name":"row","description":"<p>row to be added to the table</p>\n","type":"p5.TableRow","optional":true}],"return":{"description":"the row that was added","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":148,"description":"<p>Removes a row from the table object.</p>\n","itemtype":"method","name":"removeRow","params":[{"name":"id","description":"<p>ID number of the row to remove</p>\n","type":"Integer"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":195,"description":"<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n","itemtype":"method","name":"getRow","params":[{"name":"rowID","description":"<p>ID number of the row to get</p>\n","type":"Integer"}],"return":{"description":"<a href=\"#/p5.TableRow\">p5.TableRow</a> object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":240,"description":"<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n","itemtype":"method","name":"getRows","return":{"description":"Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":288,"description":"<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"findRow","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":352,"description":"<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"findRows","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":420,"description":"<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"matchRow","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String|RegExp"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer"}],"return":{"description":"TableRow object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":478,"description":"<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n","itemtype":"method","name":"matchRows","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer","optional":true}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":545,"description":"<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"getColumn","params":[{"name":"column","description":"<p>String or Number of the column to return</p>\n","type":"String|Number"}],"return":{"description":"Array of column values","type":"Array"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":597,"description":"<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n","itemtype":"method","name":"clearRows","example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":638,"description":"<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n","itemtype":"method","name":"addColumn","params":[{"name":"title","description":"<p>title of the given column</p>\n","type":"String","optional":true}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":688,"description":"<p>Returns the total number of columns in a Table.</p>\n","itemtype":"method","name":"getColumnCount","return":{"description":"Number of columns in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":724,"description":"<p>Returns the total number of rows in a Table.</p>\n","itemtype":"method","name":"getRowCount","return":{"description":"Number of rows in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":760,"description":"<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n","itemtype":"method","name":"removeTokens","params":[{"name":"chars","description":"<p>String listing characters to be removed</p>\n","type":"String"},{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":832,"description":"<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n","itemtype":"method","name":"trim","params":[{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":896,"description":"<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n","itemtype":"method","name":"removeColumn","params":[{"name":"column","description":"<p>columnName (string) or ID (number)</p>\n","type":"String|Integer"}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":960,"description":"<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String|Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1009,"description":"<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1055,"description":"<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String"}],"example":["\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1100,"description":"<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1146,"description":"<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1190,"description":"<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1242,"description":"<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n","itemtype":"method","name":"getObject","params":[{"name":"headerColumn","description":"<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n","type":"String","optional":true}],"return":{"description":"","type":"Object"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1305,"description":"<p>Retrieves all table data and returns it as a multidimensional array.</p>\n","itemtype":"method","name":"getArray","return":{"description":"","type":"Array"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":40,"description":"<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored</p>\n","type":"String|Number"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":102,"description":"<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a Float</p>\n","type":"Number|String"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":146,"description":"<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a String</p>\n","type":"String|Number|Boolean|Object"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":191,"description":"<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":239,"description":"<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"Float Floating point number","type":"Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":295,"description":"<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getString","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"String","type":"String"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.XML.js","line":62,"description":"<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"getParent","return":{"description":"element parent","type":"p5.XML"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":100,"description":"<p>Gets the element's full name, which is returned as a String.</p>\n","itemtype":"method","name":"getName","return":{"description":"the name of the node","type":"String"},"example":["&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":135,"description":"<p>Sets the element's name, which is specified as a String.</p>\n","itemtype":"method","name":"setName","params":[{"name":"the","description":"<p>new name of the node</p>\n","type":"String"}],"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":181,"description":"<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n","itemtype":"method","name":"hasChildren","return":{"description":"","type":"Boolean"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":217,"description":"<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n","itemtype":"method","name":"listChildren","return":{"description":"names of the children of the element","type":"String[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":258,"description":"<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n","itemtype":"method","name":"getChildren","params":[{"name":"name","description":"<p>element name</p>\n","type":"String","optional":true}],"return":{"description":"children of the element","type":"p5.XML[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":314,"description":"<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n","itemtype":"method","name":"getChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"return":{"description":"","type":"p5.XML"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":374,"description":"<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"addChild","params":[{"name":"node","description":"<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n","type":"p5.XML"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":426,"description":"<p>Removes the element specified by name or index.</p>\n","itemtype":"method","name":"removeChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":498,"description":"<p>Counts the specified element's number of attributes, returned as an Number.</p>\n","itemtype":"method","name":"getAttributeCount","return":{"description":"","type":"Integer"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":534,"description":"<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n","itemtype":"method","name":"listAttributes","return":{"description":"an array of strings containing the names of attributes","type":"String[]"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":577,"description":"<p>Checks whether or not an element has the specified attribute.</p>\n","itemtype":"method","name":"hasAttribute","params":[{"name":"the","description":"<p>attribute to be checked</p>\n","type":"String"}],"return":{"description":"true if attribute found else false","type":"Boolean"},"example":["\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":622,"description":"<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"Number"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":669,"description":"<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n","itemtype":"method","name":"getString","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":716,"description":"<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n","itemtype":"method","name":"setAttribute","params":[{"name":"name","description":"<p>the full name of the attribute</p>\n","type":"String"},{"name":"value","description":"<p>the value of the attribute</p>\n","type":"Number|String|Boolean"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":757,"description":"<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n","itemtype":"method","name":"getContent","params":[{"name":"defaultValue","description":"<p>value returned if no content is found</p>\n","type":"String","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":798,"description":"<p>Sets the element's content.</p>\n","itemtype":"method","name":"setContent","params":[{"name":"text","description":"<p>the new content</p>\n","type":"String"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":839,"description":"<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n","itemtype":"method","name":"serialize","return":{"description":"Serialized string of the element","type":"String"},"example":["\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/math/calculation.js","line":10,"description":"<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n","itemtype":"method","name":"abs","params":[{"name":"n","description":"<p>number to compute</p>\n","type":"Number"}],"return":{"description":"absolute value of given number","type":"Number"},"example":["\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":33,"description":"<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n","itemtype":"method","name":"ceil","params":[{"name":"n","description":"<p>number to round up</p>\n","type":"Number"}],"return":{"description":"rounded up number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":72,"description":"<p>Constrains a value between a minimum and maximum value.</p>\n","itemtype":"method","name":"constrain","params":[{"name":"n","description":"<p>number to constrain</p>\n","type":"Number"},{"name":"low","description":"<p>minimum limit</p>\n","type":"Number"},{"name":"high","description":"<p>maximum limit</p>\n","type":"Number"}],"return":{"description":"constrained number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"],"alt":"2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":116,"description":"<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"distance between the two points","type":"Number"},"example":["\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"],"alt":"2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":116,"params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}},{"line":161,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}}]},{"file":"src/math/calculation.js","line":182,"description":"<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n","itemtype":"method","name":"exp","params":[{"name":"n","description":"<p>exponent to raise</p>\n","type":"Number"}],"return":{"description":"e^n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. e^n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":231,"description":"<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n","itemtype":"method","name":"floor","params":[{"name":"n","description":"<p>number to round down</p>\n","type":"Number"}],"return":{"description":"rounded down number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":269,"description":"<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n","itemtype":"method","name":"lerp","params":[{"name":"start","description":"<p>first value</p>\n","type":"Number"},{"name":"stop","description":"<p>second value</p>\n","type":"Number"},{"name":"amt","description":"<p>number</p>\n","type":"Number"}],"return":{"description":"lerped value","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"],"alt":"5 points horizontally staggered mid-canvas. mid 3 are grey, outer black","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":316,"description":"<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n","itemtype":"method","name":"log","params":[{"name":"n","description":"<p>number greater than 0</p>\n","type":"Number"}],"return":{"description":"natural logarithm of n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. natural logarithm of n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":371,"description":"<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n","itemtype":"method","name":"mag","params":[{"name":"a","description":"<p>first value</p>\n","type":"Number"},{"name":"b","description":"<p>second value</p>\n","type":"Number"}],"return":{"description":"magnitude of vector from (0,0) to (a,b)","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"],"alt":"4 lines of different length radiate from top left of canvas.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":409,"description":"<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n","itemtype":"method","name":"map","params":[{"name":"value","description":"<p>the incoming value to be converted</p>\n","type":"Number"},{"name":"start1","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop1","description":"<p>upper bound of the value's current range</p>\n","type":"Number"},{"name":"start2","description":"<p>lower bound of the value's target range</p>\n","type":"Number"},{"name":"stop2","description":"<p>upper bound of the value's target range</p>\n","type":"Number"},{"name":"withinBounds","description":"<p>constrain the value to the newly mapped range</p>\n","type":"Boolean","optional":true}],"return":{"description":"remapped number","type":"Number"},"example":["\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"],"alt":"10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":464,"description":"<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"max","return":{"description":"maximum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":464,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"maximum Number","type":"Number"}},{"line":499,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":512,"description":"<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"min","return":{"description":"minimum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":512,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"minimum Number","type":"Number"}},{"line":547,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":560,"description":"<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n","itemtype":"method","name":"norm","params":[{"name":"value","description":"<p>incoming value to be normalized</p>\n","type":"Number"},{"name":"start","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop","description":"<p>upper bound of the value's current range</p>\n","type":"Number"}],"return":{"description":"normalized number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"],"alt":"ellipse moves with mouse. 0 shown left & 100 right and updating values center","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":612,"description":"<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n","itemtype":"method","name":"pow","params":[{"name":"n","description":"<p>base of the exponential expression</p>\n","type":"Number"},{"name":"e","description":"<p>power by which to raise the base</p>\n","type":"Number"}],"return":{"description":"n^e","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"],"alt":"small to large ellipses radiating from top left of canvas","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":646,"description":"<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n","itemtype":"method","name":"round","params":[{"name":"n","description":"<p>number to round</p>\n","type":"Number"},{"name":"decimals","description":"<p>number of decimal places to round to, default is 0</p>\n","type":"Number","optional":true}],"return":{"description":"rounded number","type":"Integer"},"example":["\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":701,"description":"<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n","itemtype":"method","name":"sq","params":[{"name":"n","description":"<p>number to square</p>\n","type":"Number"}],"return":{"description":"squared number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squared values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":745,"description":"<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n","itemtype":"method","name":"sqrt","params":[{"name":"n","description":"<p>non-negative number to square root</p>\n","type":"Number"}],"return":{"description":"square root of number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squareroot values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":832,"description":"<p>Calculates the fractional part of a number.</p>\n","itemtype":"method","name":"fract","params":[{"name":"num","description":"<p>Number whose fractional part needs to be found out</p>\n","type":"Number"}],"return":{"description":"fractional part of x, i.e, {x}","type":"Number"},"example":["\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"],"alt":"first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/math.js","line":10,"description":"<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n","itemtype":"method","name":"createVector","params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"p5.Vector"},"example":["\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"],"alt":"draws a line from center of canvas to mouse pointer position.","class":"p5","module":"Math","submodule":"Vector"},{"file":"src/math/noise.js","line":36,"description":"<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n","itemtype":"method","name":"noise","params":[{"name":"x","description":"<p>x-coordinate in noise space</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate in noise space</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z-coordinate in noise space</p>\n","type":"Number","optional":true}],"return":{"description":"Perlin noise value (between 0 and 1) at specified\n                     coordinates","type":"Number"},"example":["\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"],"alt":"vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":178,"description":"<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n","itemtype":"method","name":"noiseDetail","params":[{"name":"lod","description":"<p>number of octaves to be used by the noise</p>\n","type":"Number"},{"name":"falloff","description":"<p>falloff factor for each octave</p>\n","type":"Number"}],"example":["\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"],"alt":"2 vertical grey smokey patterns affected my mouse x-position and noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":243,"description":"<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n","itemtype":"method","name":"noiseSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"],"alt":"vertical grey lines drawing in pattern affected by noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/p5.Vector.js","line":69,"description":"<p>The x component of the vector</p>\n","itemtype":"property","name":"x","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":74,"description":"<p>The y component of the vector</p>\n","itemtype":"property","name":"y","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":79,"description":"<p>The z component of the vector</p>\n","itemtype":"property","name":"z","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":86,"description":"<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n","itemtype":"method","name":"toString","return":{"description":"","type":"String"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":136,"description":"<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n","itemtype":"method","name":"set","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":136,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":195,"params":[{"name":"value","description":"<p>the vector to set</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/math/p5.Vector.js","line":219,"description":"<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n","itemtype":"method","name":"copy","return":{"description":"the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":248,"description":"<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"add","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":248,"params":[{"name":"x","description":"<p>the x component of the vector to be added</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to be added</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to be added</p>\n","type":"Number","optional":true}],"chainable":1},{"line":325,"params":[{"name":"value","description":"<p>the vector to add</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2059,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":372,"description":"<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n","itemtype":"method","name":"rem","chainable":1,"example":["\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":372,"params":[{"name":"x","description":"<p>the x component of divisor vector</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of divisor vector</p>\n","type":"Number"},{"name":"z","description":"<p>the z component of divisor vector</p>\n","type":"Number"}],"chainable":1},{"line":401,"params":[{"name":"value","description":"<p>divisor vector</p>\n","type":"p5.Vector | Number[]"}],"chainable":1},{"line":2085,"params":[{"name":"v1","description":"<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1},{"line":2091,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":461,"description":"<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"sub","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":461,"params":[{"name":"x","description":"<p>the x component of the vector to subtract</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to subtract</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to subtract</p>\n","type":"Number","optional":true}],"chainable":1},{"line":538,"params":[{"name":"value","description":"<p>the vector to subtract</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2110,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":562,"description":"<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"mult","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":562,"params":[{"name":"n","description":"<p>The number to multiply with the vector</p>\n","type":"Number"}],"chainable":1},{"line":655,"params":[{"name":"x","description":"<p>The number to multiply with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to multiply with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to multiply with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":663,"params":[{"name":"arr","description":"<p>The array to multiply with the components of the vector</p>\n","type":"Number[]"}],"chainable":1},{"line":669,"params":[{"name":"v","description":"<p>The vector to multiply with the components of the original vector</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2139,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2148,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2156,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2164,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":754,"description":"<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"div","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":754,"params":[{"name":"n","description":"<p>The number to divide the vector by</p>\n","type":"Number"}],"chainable":1},{"line":847,"params":[{"name":"x","description":"<p>The number to divide with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to divide with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to divide with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":855,"params":[{"name":"arr","description":"<p>The array to divide the components of the vector by</p>\n","type":"Number[]"}],"chainable":1},{"line":861,"params":[{"name":"v","description":"<p>The vector to divide the components of the original vector by</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2218,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2227,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2235,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2243,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":959,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","itemtype":"method","name":"mag","return":{"description":"magnitude of the vector","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":959,"params":[],"return":{"description":"magnitude of the vector","type":"Number"}},{"line":2343,"params":[{"name":"vecT","description":"<p>the vector to return the magnitude of</p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the magnitude of vecT","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1007,"description":"<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n","itemtype":"method","name":"magSq","return":{"description":"squared magnitude of the vector","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1061,"description":"<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n","itemtype":"method","name":"dot","return":{"description":"the dot product","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1061,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"the dot product","type":"Number"}},{"line":1091,"params":[{"name":"value","description":"<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"","type":"Number"}},{"line":2270,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the dot product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1103,"description":"<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n","itemtype":"method","name":"cross","return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1103,"params":[{"name":"v","description":"<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n","type":"p5.Vector"}],"return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"}},{"line":2284,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the cross product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1145,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"the distance","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1145,"params":[{"name":"v","description":"<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the distance","type":"Number"}},{"line":2299,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the distance","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1217,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","itemtype":"method","name":"normalize","return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1217,"params":[],"return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2360,"params":[{"name":"v","description":"<p>the vector to normalize</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"v normalized to a length of 1","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1287,"description":"<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n","itemtype":"method","name":"limit","params":[{"name":"max","description":"<p>the maximum magnitude for the vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1345,"description":"<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n","itemtype":"method","name":"setMag","params":[{"name":"len","description":"<p>the new length for this vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1401,"description":"<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"heading","return":{"description":"the angle of rotation","type":"Number"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1473,"description":"<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"setHeading","params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1498,"description":"<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"rotate","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1498,"params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1},{"line":2191,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":1567,"description":"<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"angleBetween","params":[{"name":"value","description":"<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the angle between (in radians)","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1647,"description":"<p>Linear interpolate the vector to another vector</p>\n","itemtype":"method","name":"lerp","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1647,"params":[{"name":"x","description":"<p>the x component</p>\n","type":"Number"},{"name":"y","description":"<p>the y component</p>\n","type":"Number"},{"name":"z","description":"<p>the z component</p>\n","type":"Number"},{"name":"amt","description":"<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n","type":"Number"}],"chainable":1},{"line":1720,"params":[{"name":"v","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"}],"chainable":1},{"line":2314,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the lerped value","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1736,"description":"<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n","itemtype":"method","name":"reflect","params":[{"name":"surfaceNormal","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n","type":"p5.Vector"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1791,"description":"<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n","itemtype":"method","name":"array","return":{"description":"an Array with the 3 values","type":"Number[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1823,"description":"<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","itemtype":"method","name":"equals","return":{"description":"whether the vectors are equals","type":"Boolean"},"example":["\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1823,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"whether the vectors are equals","type":"Boolean"}},{"line":1853,"params":[{"name":"value","description":"<p>the vector to compare</p>\n","type":"p5.Vector|Array"}],"return":{"description":"","type":"Boolean"}}]},{"file":"src/math/p5.Vector.js","line":1878,"description":"<p>Make a new 2D vector from an angle</p>\n","itemtype":"method","name":"fromAngle","static":1,"params":[{"name":"angle","description":"<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1929,"description":"<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n","itemtype":"method","name":"fromAngles","static":1,"params":[{"name":"theta","description":"<p>the polar angle, in radians (zero is up)</p>\n","type":"Number"},{"name":"phi","description":"<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1978,"description":"<p>Make a new 2D unit vector from a random angle</p>\n","itemtype":"method","name":"random2D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2031,"description":"<p>Make a new random 3D unit vector.</p>\n","itemtype":"method","name":"random3D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2135,"description":"<p>Multiplies a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2187,"description":"<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2214,"description":"<p>Divides a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2267,"description":"<p>Calculates the dot product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2281,"description":"<p>Calculates the cross product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2295,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2310,"description":"<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2339,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2357,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/random.js","line":37,"description":"<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n","itemtype":"method","name":"randomSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"],"alt":"many vertical lines drawn in white, black or grey.","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/random.js","line":66,"description":"<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n","itemtype":"method","name":"random","return":{"description":"the random number","type":"Number"},"example":["\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"],"alt":"100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog","class":"p5","module":"Math","submodule":"Random","overloads":[{"line":66,"params":[{"name":"min","description":"<p>the lower bound (inclusive)</p>\n","type":"Number","optional":true},{"name":"max","description":"<p>the upper bound (exclusive)</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"}},{"line":119,"params":[{"name":"choices","description":"<p>the array to choose from</p>\n","type":"Array"}],"return":{"description":"the random element from the array","type":"*"}}]},{"file":"src/math/random.js","line":153,"description":"<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n","itemtype":"method","name":"randomGaussian","params":[{"name":"mean","description":"<p>the mean</p>\n","type":"Number","optional":true},{"name":"sd","description":"<p>the standard deviation</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"},"example":["\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"],"alt":"100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/trigonometry.js","line":18,"description":"<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n","itemtype":"method","name":"acos","params":[{"name":"value","description":"<p>the value whose arc cosine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc cosine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":53,"description":"<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n","itemtype":"method","name":"asin","params":[{"name":"value","description":"<p>the value whose arc sine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc sine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":88,"description":"<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n","itemtype":"method","name":"atan","params":[{"name":"value","description":"<p>the value whose arc tangent is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":123,"description":"<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n","itemtype":"method","name":"atan2","params":[{"name":"y","description":"<p>y-coordinate of the point</p>\n","type":"Number"},{"name":"x","description":"<p>x-coordinate of the point</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given point","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"],"alt":"60 by 10 rect at center of canvas rotates with mouse movements","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":159,"description":"<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"cos","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the cosine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines form wave patterns, extend-down on left and right side","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":186,"description":"<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"sin","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the sine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines extend down and up from center to form wave pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":213,"description":"<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n","itemtype":"method","name":"tan","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the tangent of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"],"alt":"vertical black lines end down and up from center to form spike pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":239,"description":"<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"degrees","params":[{"name":"radians","description":"<p>the radians value to convert to degrees</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":262,"description":"<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"radians","params":[{"name":"degrees","description":"<p>the degree value to convert to radians</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":285,"description":"<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n","itemtype":"method","name":"angleMode","params":[{"name":"mode","description":"<p>either RADIANS or DEGREES</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"],"alt":"40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/typography/attributes.js","line":11,"description":"<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n","itemtype":"method","name":"textAlign","chainable":1,"example":["\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"],"alt":"Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":11,"params":[{"name":"horizAlign","description":"<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n","type":"Constant"},{"name":"vertAlign","description":"<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n","type":"Constant","optional":true}],"chainable":1},{"line":72,"params":[],"return":{"description":"","type":"Object"}}]},{"file":"src/typography/attributes.js","line":81,"description":"<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n","itemtype":"method","name":"textLeading","chainable":1,"example":["\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"],"alt":"A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":81,"params":[{"name":"leading","description":"<p>the size in pixels for spacing between lines</p>\n","type":"Number"}],"chainable":1},{"line":109,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":118,"description":"<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n","itemtype":"method","name":"textSize","chainable":1,"example":["\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"],"alt":"'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":118,"params":[{"name":"theSize","description":"<p>the size of the letters in units of pixels</p>\n","type":"Number"}],"chainable":1},{"line":141,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":150,"description":"<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n","itemtype":"method","name":"textStyle","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"],"alt":"Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":150,"params":[{"name":"theStyle","description":"<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n","type":"Constant"}],"chainable":1},{"line":178,"params":[],"return":{"description":"","type":"String"}}]},{"file":"src/typography/attributes.js","line":187,"description":"<p>Calculates and returns the width of any character or text string.</p>\n","itemtype":"method","name":"textWidth","params":[{"name":"theText","description":"<p>the String of characters to measure</p>\n","type":"String"}],"return":{"description":"the calculated width","type":"Number"},"example":["\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"],"alt":"Letter P and p5.js are displayed with vertical lines at end.","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":222,"description":"<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n","itemtype":"method","name":"textAscent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":251,"description":"<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n","itemtype":"method","name":"textDescent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":280,"description":"<p>Helper function to measure ascent and descent.</p>\n","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":287,"description":"<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n","itemtype":"method","name":"textWrap","params":[{"name":"wrapStyle","description":"<p>text wrapping style, either WORD or CHAR</p>\n","type":"Constant"}],"return":{"description":"wrapStyle","type":"String"},"example":["\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/loading_displaying.js","line":16,"description":"<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n","itemtype":"method","name":"loadFont","params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n","type":"Function","optional":true},{"name":"onError","description":"<p>function to be executed if\n                                   an error occurs</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Font\">p5.Font</a> object","type":"p5.Font"},"example":["\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"],"alt":"p5*js in p5's theme dark pink\np5*js in p5's theme dark pink","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":140,"description":"<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n","itemtype":"method","name":"text","params":[{"name":"str","description":"<p>the alphanumeric\n                                            symbols to be displayed</p>\n","type":"String|Object|Array|Number|Boolean"},{"name":"x","description":"<p>x-coordinate of text</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of text</p>\n","type":"Number"},{"name":"x2","description":"<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true},{"name":"y2","description":"<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"],"alt":"'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":231,"description":"<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n","itemtype":"method","name":"textFont","return":{"description":"the current font / p5 Object","type":"Object"},"example":["\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"],"alt":"word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold","class":"p5","module":"Typography","submodule":"Loading & Displaying","overloads":[{"line":231,"params":[],"return":{"description":"the current font / p5 Object","type":"Object"}},{"line":280,"params":[{"name":"font","description":"<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n","type":"Object|String"},{"name":"size","description":"<p>the font size to use</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/typography/p5.Font.js","line":24,"description":"<p>Underlying opentype font implementation</p>\n","itemtype":"property","name":"font","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":31,"description":"<p>Returns a tight bounding box for the given text string using this\nfont</p>\n","itemtype":"method","name":"textBounds","params":[{"name":"line","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional) Default is 12.</p>\n","type":"Number","optional":true},{"name":"options","description":"<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n","type":"Object","optional":true}],"return":{"description":"a rectangle object with properties: x, y, w, h","type":"Object"},"example":["\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"],"alt":"words Lorem ipsum dol go off canvas and contained by white bounding box","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":175,"description":"<p>Computes an array of points following the path for specified text</p>\n","itemtype":"method","name":"textToPoints","params":[{"name":"txt","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional)</p>\n","type":"Number"},{"name":"options","description":"<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n","type":"Object","optional":true}],"return":{"description":"an array of points, each with x, y, alpha (the path angle)","type":"Array"},"example":["\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"],"class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/utilities/array_functions.js","line":10,"description":"<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n","itemtype":"method","name":"append","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.","params":[{"name":"array","description":"<p>Array to append</p>\n","type":"Array"},{"name":"value","description":"<p>to be added to the Array</p>\n","type":"Any"}],"return":{"description":"the array that was appended to","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":35,"description":"<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n","itemtype":"method","name":"arrayCopy","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.","example":["\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions","overloads":[{"line":35,"params":[{"name":"src","description":"<p>the source Array</p>\n","type":"Array"},{"name":"srcPosition","description":"<p>starting position in the source Array</p>\n","type":"Integer"},{"name":"dst","description":"<p>the destination Array</p>\n","type":"Array"},{"name":"dstPosition","description":"<p>starting position in the destination Array</p>\n","type":"Integer"},{"name":"length","description":"<p>number of Array elements to be copied</p>\n","type":"Integer"}]},{"line":73,"params":[{"name":"src","description":"","type":"Array"},{"name":"dst","description":"","type":"Array"},{"name":"length","description":"","type":"Integer","optional":true}]}]},{"file":"src/utilities/array_functions.js","line":112,"description":"<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n","itemtype":"method","name":"concat","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.","params":[{"name":"a","description":"<p>first Array to concatenate</p>\n","type":"Array"},{"name":"b","description":"<p>second Array to concatenate</p>\n","type":"Array"}],"return":{"description":"concatenated array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":141,"description":"<p>Reverses the order of an array, maps to Array.reverse()</p>\n","itemtype":"method","name":"reverse","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.","params":[{"name":"list","description":"<p>Array to reverse</p>\n","type":"Array"}],"return":{"description":"the reversed list","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":161,"description":"<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n","itemtype":"method","name":"shorten","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.","params":[{"name":"list","description":"<p>Array to shorten</p>\n","type":"Array"}],"return":{"description":"shortened Array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":185,"description":"<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n","itemtype":"method","name":"shuffle","params":[{"name":"array","description":"<p>Array to shuffle</p>\n","type":"Array"},{"name":"bool","description":"<p>modify passed array</p>\n","type":"Boolean","optional":true}],"return":{"description":"shuffled Array","type":"Array"},"example":["\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":227,"description":"<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n","itemtype":"method","name":"sort","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.","params":[{"name":"list","description":"<p>Array to sort</p>\n","type":"Array"},{"name":"count","description":"<p>number of elements to sort, starting from 0</p>\n","type":"Integer","optional":true}],"return":{"description":"the sorted list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":273,"description":"<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n","itemtype":"method","name":"splice","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.","params":[{"name":"list","description":"<p>Array to splice into</p>\n","type":"Array"},{"name":"value","description":"<p>value to be spliced in</p>\n","type":"Any"},{"name":"position","description":"<p>in the array from which to insert data</p>\n","type":"Integer"}],"return":{"description":"the list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":308,"description":"<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n","itemtype":"method","name":"subset","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.","params":[{"name":"list","description":"<p>Array to extract from</p>\n","type":"Array"},{"name":"start","description":"<p>position to begin</p>\n","type":"Integer"},{"name":"count","description":"<p>number of values to extract</p>\n","type":"Integer","optional":true}],"return":{"description":"Array of extracted elements","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/conversion.js","line":10,"description":"<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n","itemtype":"method","name":"float","params":[{"name":"str","description":"<p>float string to parse</p>\n","type":"String"}],"return":{"description":"floating point representation of string","type":"Number"},"example":["\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"],"alt":"20 by 20 white ellipse in the center of the canvas","class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":44,"description":"<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n","itemtype":"method","name":"int","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":44,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"},{"name":"radix","description":"<p>the radix to convert to (default: 10)</p>\n","type":"Integer","optional":true}],"return":{"description":"integer representation of value","type":"Number"}},{"line":66,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"},{"name":"radix","description":"","type":"Integer","optional":true}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":88,"description":"<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n","itemtype":"method","name":"str","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":114,"description":"<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n","itemtype":"method","name":"boolean","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"boolean representation of value","type":"Boolean"},"example":["\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":146,"description":"<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n","itemtype":"method","name":"byte","return":{"description":"byte representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":146,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"}],"return":{"description":"byte representation of value","type":"Number"}},{"line":168,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of byte representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":182,"description":"<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n","itemtype":"method","name":"char","return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":182,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Number"}],"return":{"description":"string representation of value","type":"String"}},{"line":201,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":216,"description":"<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unchar","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":216,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of value","type":"Number"}},{"line":232,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":245,"description":"<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n","itemtype":"method","name":"hex","return":{"description":"hexadecimal string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":245,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"Number"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of value","type":"String"}},{"line":265,"params":[{"name":"ns","description":"<p>array of values to parse</p>\n","type":"Number[]"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":295,"description":"<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unhex","return":{"description":"integer representation of hexadecimal value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":295,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of hexadecimal value","type":"Number"}},{"line":311,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representations of hexadecimal value","type":"Number[]"}}]},{"file":"src/utilities/string_functions.js","line":15,"description":"<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n","itemtype":"method","name":"join","params":[{"name":"list","description":"<p>array of Strings to be joined</p>\n","type":"Array"},{"name":"separator","description":"<p>String to be placed between each item</p>\n","type":"String"}],"return":{"description":"joined String","type":"String"},"example":["\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"],"alt":"\"hello world!\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":43,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n","itemtype":"method","name":"match","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"Array of Strings found","type":"String[]"},"example":["\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"],"alt":"\"p5js*\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":83,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n","itemtype":"method","name":"matchAll","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"2d Array of Strings found","type":"String[]"},"example":["\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":130,"description":"<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nf","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" middle top, -1321.00\" middle bottom canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":130,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"left","description":"<p>number of digits to the left of the\n                               decimal point</p>\n","type":"Integer|String","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":176,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer|String","optional":true},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":237,"description":"<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n","itemtype":"method","name":"nfc","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":237,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"right","description":"<p>number of digits to the right of the\n                                 decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":275,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":311,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n","itemtype":"method","name":"nfp","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":311,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":352,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Number[]"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":373,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nfs","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" top middle and \"-1321.00\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":373,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":430,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":451,"description":"<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n","itemtype":"method","name":"split","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>the String used to separate the data</p>\n","type":"String"}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"],"alt":"\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":484,"description":"<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n","itemtype":"method","name":"splitTokens","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>list of individual Strings that will be used as\n                         separators</p>\n","type":"String","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":537,"description":"<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n","itemtype":"method","name":"trim","return":{"description":"a trimmed String","type":"String"},"example":["\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"],"alt":"\"No new lines here\" displayed center canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":537,"params":[{"name":"str","description":"<p>a String to be trimmed</p>\n","type":"String"}],"return":{"description":"a trimmed String","type":"String"}},{"line":557,"params":[{"name":"strs","description":"<p>an Array of Strings to be trimmed</p>\n","type":"Array"}],"return":{"description":"an Array of trimmed Strings","type":"String[]"}}]},{"file":"src/utilities/time_date.js","line":10,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n","itemtype":"method","name":"day","return":{"description":"the current day","type":"Integer"},"example":["\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"],"alt":"Current day is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":31,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n","itemtype":"method","name":"hour","return":{"description":"the current hour","type":"Integer"},"example":["\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"],"alt":"Current hour is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":52,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n","itemtype":"method","name":"minute","return":{"description":"the current minute","type":"Integer"},"example":["\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current minute is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":73,"description":"<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n","itemtype":"method","name":"millis","return":{"description":"the number of milliseconds since starting the sketch","type":"Number"},"example":["\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"],"alt":"number of milliseconds since sketch has started displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":100,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n","itemtype":"method","name":"month","return":{"description":"the current month","type":"Integer"},"example":["\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current month is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":122,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n","itemtype":"method","name":"second","return":{"description":"the current second","type":"Integer"},"example":["\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"],"alt":"Current second is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":143,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n","itemtype":"method","name":"year","return":{"description":"the current year","type":"Integer"},"example":["\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"],"alt":"Current year is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/webgl/3d_primitives.js","line":13,"description":"<p>Draw a plane with given a width and height</p>\n","itemtype":"method","name":"plane","params":[{"name":"width","description":"<p>width of the plane</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the plane</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"],"alt":"Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.","class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":97,"description":"<p>Draw a box with given width, height and depth</p>\n","itemtype":"method","name":"box","params":[{"name":"width","description":"<p>width of the box</p>\n","type":"Number","optional":true},{"name":"Height","description":"<p>height of the box</p>\n","type":"Number","optional":true},{"name":"depth","description":"<p>depth of the box</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":215,"description":"<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"sphere","params":[{"name":"radius","description":"<p>radius of circle</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>optional number of subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>optional number of subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":419,"description":"<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cylinder","params":[{"name":"radius","description":"<p>radius of the surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cylinder</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n","type":"Integer","optional":true},{"name":"bottomCap","description":"<p>whether to draw the bottom of the cylinder</p>\n","type":"Boolean","optional":true},{"name":"topCap","description":"<p>whether to draw the top of the cylinder</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":554,"description":"<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cone","params":[{"name":"radius","description":"<p>radius of the bottom surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cone</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n","type":"Integer","optional":true},{"name":"cap","description":"<p>whether to draw the base of the cone</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":669,"description":"<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n","itemtype":"method","name":"ellipsoid","params":[{"name":"radiusx","description":"<p>x-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusy","description":"<p>y-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusz","description":"<p>z-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":804,"description":"<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n","itemtype":"method","name":"torus","params":[{"name":"radius","description":"<p>radius of the whole ring</p>\n","type":"Number","optional":true},{"name":"tubeRadius","description":"<p>radius of the tube</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/interaction.js","line":11,"description":"<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n","itemtype":"method","name":"orbitControl","params":[{"name":"sensitivityX","description":"<p>sensitivity to mouse movement along X axis</p>\n","type":"Number","optional":true},{"name":"sensitivityY","description":"<p>sensitivity to mouse movement along Y axis</p>\n","type":"Number","optional":true},{"name":"sensitivityZ","description":"<p>sensitivity to scroll movement along Z axis</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"],"alt":"Camera orbits around a box when mouse is hold-clicked & then moved.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/interaction.js","line":145,"description":"<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n","itemtype":"method","name":"debugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.","class":"p5","module":"3D","submodule":"Interaction","overloads":[{"line":145,"params":[]},{"line":278,"params":[{"name":"mode","description":"<p>either GRID or AXES</p>\n","type":"Constant"}]},{"line":283,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"gridSize","description":"<p>size of one side of the grid</p>\n","type":"Number","optional":true},{"name":"gridDivisions","description":"<p>number of divisions in the grid</p>\n","type":"Number","optional":true},{"name":"xOff","description":"<p>X axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"yOff","description":"<p>Y axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"zOff","description":"<p>Z axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true}]},{"line":293,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"axesSize","description":"<p>size of axes icon</p>\n","type":"Number","optional":true},{"name":"xOff","description":"","type":"Number","optional":true},{"name":"yOff","description":"","type":"Number","optional":true},{"name":"zOff","description":"","type":"Number","optional":true}]},{"line":302,"params":[{"name":"gridSize","description":"","type":"Number","optional":true},{"name":"gridDivisions","description":"","type":"Number","optional":true},{"name":"gridXOff","description":"","type":"Number","optional":true},{"name":"gridYOff","description":"","type":"Number","optional":true},{"name":"gridZOff","description":"","type":"Number","optional":true},{"name":"axesSize","description":"","type":"Number","optional":true},{"name":"axesXOff","description":"","type":"Number","optional":true},{"name":"axesYOff","description":"","type":"Number","optional":true},{"name":"axesZOff","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/interaction.js","line":353,"description":"<p>Turns off debugMode() in a 3D sketch.</p>\n","itemtype":"method","name":"noDebugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/light.js","line":11,"description":"<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n","itemtype":"method","name":"ambientLight","chainable":1,"example":["\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"],"alt":"evenly distributed light across a sphere\nevenly distributed light across a rotating sphere","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":11,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"<p>the alpha value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":51,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":57,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":64,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":71,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":92,"description":"<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n","itemtype":"method","name":"specularColor","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"different specular light sources from top and bottom of canvas","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":92,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"}],"chainable":1},{"line":139,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":145,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"}],"chainable":1},{"line":151,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":158,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":177,"description":"<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n","itemtype":"method","name":"directionalLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"light source on canvas changeable with mouse position","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":177,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"position","description":"<p>the direction of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":210,"params":[{"name":"color","description":"<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"<p>x axis direction</p>\n","type":"Number"},{"name":"y","description":"<p>y axis direction</p>\n","type":"Number"},{"name":"z","description":"<p>z axis direction</p>\n","type":"Number"}],"chainable":1},{"line":220,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1},{"line":227,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1}]},{"file":"src/webgl/light.js","line":280,"description":"<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n","itemtype":"method","name":"pointLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"spot light on canvas changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":280,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"}],"chainable":1},{"line":322,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":331,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1},{"line":341,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1}]},{"file":"src/webgl/light.js","line":387,"description":"<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n","itemtype":"method","name":"lights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"the light is partially ambient and partially directional","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":425,"description":"<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n","itemtype":"method","name":"lightFalloff","params":[{"name":"constant","description":"<p>constant value for determining falloff</p>\n","type":"Number"},{"name":"linear","description":"<p>linear value for determining falloff</p>\n","type":"Number"},{"name":"quadratic","description":"<p>quadratic value for determining falloff</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"],"alt":"Two spheres with different falloff values show different intensity of light","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":519,"description":"<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n","itemtype":"method","name":"spotLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Spot light on a sphere which changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":519,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"},{"name":"rx","description":"<p>x axis direction of light</p>\n","type":"Number"},{"name":"ry","description":"<p>y axis direction of light</p>\n","type":"Number"},{"name":"rz","description":"<p>z axis direction of light</p>\n","type":"Number"},{"name":"angle","description":"<p>optional parameter for angle. Defaults to PI/3</p>\n","type":"Number","optional":true},{"name":"conc","description":"<p>optional parameter for concentration. Defaults to 100</p>\n","type":"Number","optional":true}],"chainable":1},{"line":571,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"},{"name":"direction","description":"<p>the direction of the light</p>\n","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":580,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":590,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":600,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":610,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":622,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":634,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/light.js","line":859,"description":"<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n","itemtype":"method","name":"noLights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"],"alt":"Three white spheres. Each appears as a different\ncolor due to lighting.","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/loading.js","line":12,"description":"<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n","itemtype":"method","name":"loadModel","return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"},"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>","\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d teapot with red, green and blue gradient.","class":"p5","module":"Shape","submodule":"3D Models","overloads":[{"line":12,"params":[{"name":"path","description":"<p>Path of the model to be loaded</p>\n","type":"String"},{"name":"normalize","description":"<p>If true, scale the model to a\n                                     standardized size when loading</p>\n","type":"Boolean"},{"name":"successCallback","description":"<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                                        the model fails to load.</p>\n","type":"Function(Event)","optional":true},{"name":"fileType","description":"<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}},{"line":96,"params":[{"name":"path","description":"","type":"String"},{"name":"successCallback","description":"","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"","type":"Function(Event)","optional":true},{"name":"fileType","description":"","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}}]},{"file":"src/webgl/loading.js","line":179,"description":"<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":290,"description":"<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":317,"description":"<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":344,"description":"<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":356,"description":"<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":444,"description":"<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":588,"description":"<p>Render a 3d model to the screen.</p>\n","itemtype":"method","name":"model","params":[{"name":"model","description":"<p>Loaded 3d model to be rendered</p>\n","type":"p5.Geometry"}],"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d octahedron.","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/material.js","line":12,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"loadShader","params":[{"name":"vertFilename","description":"<p>path to file containing vertex shader\nsource code</p>\n","type":"String"},{"name":"fragFilename","description":"<p>path to file containing fragment shader\nsource code</p>\n","type":"String"},{"name":"callback","description":"<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n","type":"Function","optional":true}],"return":{"description":"a shader object created from the provided\nvertex and fragment shader files.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":111,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"createShader","params":[{"name":"vertSrc","description":"<p>source code for the vertex shader</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader</p>\n","type":"String"}],"return":{"description":"a shader object created from the provided\nvertex and fragment shaders.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":184,"description":"<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"shader","chainable":1,"params":[{"name":"s","description":"<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n","type":"p5.Shader"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":282,"description":"<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n","itemtype":"method","name":"resetShader","chainable":1,"example":["\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"],"alt":"Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":368,"description":"<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"texture","params":[{"name":"tex","description":"<p>image to use as texture</p>\n","type":"p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"}],"chainable":1,"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>","\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>","\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using normalized coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":511,"description":"<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n","itemtype":"method","name":"textureMode","params":[{"name":"mode","description":"<p>either IMAGE or NORMAL</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using image coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":587,"description":"<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n","itemtype":"method","name":"textureWrap","params":[{"name":"wrapX","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant"},{"name":"wrapY","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"],"alt":"an image of the rocky mountains repeated in mirrored tiles","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":659,"description":"<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"normalMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Red, green and blue gradient.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":697,"description":"<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"ambientMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":697,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":757,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":777,"description":"<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n","itemtype":"method","name":"emissiveMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":777,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true},{"name":"a","description":"<p>opacity</p>\n","type":"Number","optional":true}],"chainable":1},{"line":809,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":829,"description":"<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"specularMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"],"alt":"torus with specular material","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":829,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":870,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":882,"params":[{"name":"color","description":"<p>color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":902,"description":"<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n","itemtype":"method","name":"shininess","params":[{"name":"shine","description":"<p>Degree of Shininess.\n                      Defaults to 1.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"],"alt":"Shininess on Camera changes position with mouse","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/p5.Camera.js","line":13,"description":"<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n","itemtype":"method","name":"camera","is_constructor":1,"params":[{"name":"x","description":"<p>camera position value on x axis</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>camera position value on y axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>camera position value on z axis</p>\n","type":"Number","optional":true},{"name":"centerX","description":"<p>x coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerY","description":"<p>y coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerZ","description":"<p>z coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"upX","description":"<p>x component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upY","description":"<p>y component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upZ","description":"<p>z component of direction 'up' from camera</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":115,"description":"<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n","itemtype":"method","name":"perspective","params":[{"name":"fovy","description":"<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n","type":"Number","optional":true},{"name":"aspect","description":"<p>camera frustum aspect ratio</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>frustum near plane length</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>frustum far plane length</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":176,"description":"<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n","itemtype":"method","name":"ortho","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":236,"description":"<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n","itemtype":"method","name":"frustum","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":303,"description":"<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n","itemtype":"method","name":"createCamera","return":{"description":"The newly created camera object.","type":"p5.Camera"},"example":["\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"],"alt":"An example that creates a camera and moves it around the box.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":444,"description":"<p>camera position value on x axis</p>\n","itemtype":"property","name":"eyeX","type":"Number","readonly":"","example":["\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":472,"description":"<p>camera position value on y axis</p>\n","itemtype":"property","name":"eyeY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":499,"description":"<p>camera position value on z axis</p>\n","itemtype":"property","name":"eyeZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":526,"description":"<p>x coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":554,"description":"<p>y coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":582,"description":"<p>z coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":610,"description":"<p>x component of direction 'up' from camera</p>\n","itemtype":"property","name":"upX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":633,"description":"<p>y component of direction 'up' from camera</p>\n","itemtype":"property","name":"upY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":656,"description":"<p>z component of direction 'up' from camera</p>\n","itemtype":"property","name":"upZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":683,"description":"<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"perspective","example":["\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":801,"description":"<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"ortho","example":["\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":897,"description":"<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"frustum","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1040,"description":"<p>Panning rotates the camera view to the left and right.</p>\n","itemtype":"method","name":"pan","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1098,"description":"<p>Tilting rotates the camera view up and down.</p>\n","itemtype":"method","name":"tilt","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view tilts up and down across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1156,"description":"<p>Reorients the camera to look at a position in world space.</p>\n","itemtype":"method","name":"lookAt","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view of rotating 3D cubes changes to look at a new random\npoint every second .","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1223,"description":"<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"camera","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1386,"description":"<p>Move camera along its local axes while maintaining current camera orientation.</p>\n","itemtype":"method","name":"move","params":[{"name":"x","description":"<p>amount to move along camera's left-right axis</p>\n","type":"Number"},{"name":"y","description":"<p>amount to move along camera's up-down axis</p>\n","type":"Number"},{"name":"z","description":"<p>amount to move along camera's forward-backward axis</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"],"alt":"camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1458,"description":"<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n","itemtype":"method","name":"setPosition","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"],"alt":"camera position changes as the user presses keys, altering view of a 3D box","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1723,"description":"<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n","itemtype":"method","name":"setCamera","params":[{"name":"cam","description":"<p>p5.Camera object</p>\n","type":"p5.Camera"}],"example":["\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"Canvas switches between two camera views, each showing a series of spinning\n3D boxes.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Geometry.js","line":71,"description":"<p>computes faces for geometry objects based on the vertices.</p>\n","itemtype":"method","name":"computeFaces","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":114,"description":"<p>computes smooth normals per vertex as an average of each\nface.</p>\n","itemtype":"method","name":"computeNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":153,"description":"<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n","itemtype":"method","name":"averageNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":174,"description":"<p>Averages pole normals.  Used in spherical primitives</p>\n","itemtype":"method","name":"averagePoleNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":267,"description":"<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n","itemtype":"method","name":"normalize","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.RendererGL.js","line":334,"description":"<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n","itemtype":"method","name":"setAttributes","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"],"alt":"a rotating cube with smoother edges","class":"p5","module":"Rendering","submodule":"Rendering","overloads":[{"line":334,"params":[{"name":"key","description":"<p>Name of attribute</p>\n","type":"String"},{"name":"value","description":"<p>New value of named attribute</p>\n","type":"Boolean"}]},{"line":473,"params":[{"name":"obj","description":"<p>object with key-value pairs</p>\n","type":"Object"}]}]},{"file":"src/webgl/p5.Shader.js","line":306,"description":"<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n","itemtype":"method","name":"setUniform","chainable":1,"params":[{"name":"uniformName","description":"<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n","type":"String"},{"name":"data","description":"<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n","type":"Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5.Shader","module":"3D","submodule":"Material"},{"file":"lib/addons/p5.sound.js","line":1,"class":"p5.sound","module":"3D"},{"file":"lib/addons/p5.sound.js","line":52,"description":"<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n","class":"p5.sound","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":159,"description":"<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>","itemtype":"method","name":"getAudioContext","return":{"description":"AudioContext for this sketch","type":"Object"},"example":["\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":198,"description":"<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>","params":[{"name":"element(s)","description":"<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n","type":"Element|Array","optional":true},{"name":"callback","description":"<p>Callback to invoke when the AudioContext\n                              has started</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that resolves when\n                                     the AudioContext state is 'running'","type":"Promise"},"itemtype":"method","name":"userStartAudio","example":["\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":401,"description":"<p>This module has shims</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":536,"description":"<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":726,"description":"<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n","itemtype":"method","name":"getOutputVolume","return":{"description":"Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":738,"description":"<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>","itemtype":"method","name":"outputVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":782,"description":"<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n","itemtype":"property","name":"soundOut","type":"Object","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":807,"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":811,"description":"<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"samplerate samples per second","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":825,"description":"<p>Returns the closest MIDI note value for\na given frequency.</p>\n","itemtype":"method","name":"freqToMidi","params":[{"name":"frequency","description":"<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n","type":"Number"}],"return":{"description":"MIDI note value","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":841,"description":"<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n","itemtype":"method","name":"midiToFreq","params":[{"name":"midiNote","description":"<p>The number of a MIDI note</p>\n","type":"Number"}],"return":{"description":"Frequency value of the given MIDI note","type":"Number"},"example":["\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":925,"description":"<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n","itemtype":"method","name":"soundFormats","params":[{"name":"formats","description":"<p>i.e. 'mp3', 'wav', 'ogg'</p>\n","type":"String","optional":true,"multiple":true}],"example":["\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1040,"description":"<p>Used by Osc and Envelope to chain signal math</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1145,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n","itemtype":"method","name":"saveSound","params":[{"name":"soundFile","description":"<p>p5.SoundFile that you wish to save</p>\n","type":"p5.SoundFile"},{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1662,"description":"<p>Returns true if the sound file finished loading successfully.</p>\n","itemtype":"method","name":"isLoaded","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1679,"description":"<p>Play the p5.SoundFile</p>\n","itemtype":"method","name":"play","params":[{"name":"startTime","description":"<p>(optional) schedule playback to start (in seconds from now).</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) amplitude (volume)\n                                    of playback</p>\n","type":"Number","optional":true},{"name":"cueStart","description":"<p>(optional) cue start time in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) duration of playback in seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1787,"description":"<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n","itemtype":"method","name":"playMode","params":[{"name":"str","description":"<p>'restart' or 'sustain' or 'untilDone'</p>\n","type":"String"}],"example":["\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1847,"description":"<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n","itemtype":"method","name":"pause","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                             seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1905,"description":"<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n","itemtype":"method","name":"loop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            seconds from now</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) playback volume</p>\n","type":"Number","optional":true},{"name":"cueLoopStart","description":"<p>(optional) startTime in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) loop duration in seconds</p>\n","type":"Number","optional":true}],"example":["\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1950,"description":"<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n","itemtype":"method","name":"setLoop","params":[{"name":"Boolean","description":"<p>set looping to true or false</p>\n","type":"Boolean"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1976,"description":"<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n","itemtype":"method","name":"isLooping","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1997,"description":"<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n","itemtype":"method","name":"isPlaying","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2011,"description":"<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n","itemtype":"method","name":"isPaused","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2025,"description":"<p>Stop soundfile playback.</p>\n","itemtype":"method","name":"stop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            in seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2087,"description":"<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n","itemtype":"method","name":"pan","params":[{"name":"panValue","description":"<p>Set the stereo panner</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                                seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2131,"description":"<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n","itemtype":"method","name":"getPan","return":{"description":"Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2146,"description":"<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n","itemtype":"method","name":"rate","params":[{"name":"playbackRate","description":"<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2239,"description":"<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n","itemtype":"method","name":"setVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2276,"description":"<p>Returns the duration of a sound file in seconds.</p>\n","itemtype":"method","name":"duration","return":{"description":"The duration of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2293,"description":"<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n","itemtype":"method","name":"currentTime","return":{"description":"currentTime of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2308,"description":"<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n","itemtype":"method","name":"jump","params":[{"name":"cueTime","description":"<p>cueTime of the soundFile in seconds.</p>\n","type":"Number"},{"name":"duration","description":"<p>duration in seconds.</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2340,"description":"<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n","itemtype":"method","name":"channels","return":{"description":"[channels]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2354,"description":"<p>Return the sample rate of the sound file.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"[sampleRate]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2367,"description":"<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n","itemtype":"method","name":"frames","return":{"description":"[sampleCount]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2381,"description":"<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n","itemtype":"method","name":"getPeaks","params":[{"name":"length","description":"<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n","type":"Number","optional":true}],"return":{"description":"Array of peaks.","type":"Float32Array"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2443,"description":"<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n","itemtype":"method","name":"reverseBuffer","example":["\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2497,"description":"<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended.</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2565,"description":"<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n","itemtype":"method","name":"connect","params":[{"name":"object","description":"<p>Audio object that accepts an input</p>\n","type":"Object","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2590,"description":"<p>Disconnects the output of this p5sound object.</p>\n","itemtype":"method","name":"disconnect","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2604,"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2612,"description":"<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n","itemtype":"method","name":"setPath","params":[{"name":"path","description":"<p>path to audio file</p>\n","type":"String"},{"name":"callback","description":"<p>Callback</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2630,"description":"<p>Replace the current Audio Buffer with a new Buffer.</p>\n","itemtype":"method","name":"setBuffer","params":[{"name":"buf","description":"<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n","type":"Array"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2719,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2790,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2817,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2850,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n","itemtype":"method","name":"save","params":[{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String","optional":true}],"example":["\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2882,"description":"<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n","itemtype":"method","name":"getBlob","return":{"description":"A file-like data object","type":"Blob"},"example":["\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2946,"description":"<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n","itemtype":"method","name":"loadSound","params":[{"name":"path","description":"<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n","type":"Function","optional":true},{"name":"whileLoading","description":"<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a p5.SoundFile","type":"SoundFile"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3117,"description":"<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n","itemtype":"method","name":"setInput","params":[{"name":"snd","description":"<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n","type":"SoundObject|undefined","optional":true},{"name":"smoothing","description":"<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n","type":"Number|undefined","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3209,"description":"<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n","itemtype":"method","name":"getLevel","params":[{"name":"channel","description":"<p>Optionally return only channel 0 (left) or 1 (right)</p>\n","type":"Number","optional":true}],"return":{"description":"Amplitude as a number between 0.0 and 1.0","type":"Number"},"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3264,"description":"<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n","itemtype":"method","name":"toggleNormalize","params":[{"name":"boolean","description":"<p>set normalize to true (1) or false (0)</p>\n","type":"Boolean","optional":true}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3293,"description":"<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"set","description":"<p>smoothing from 0.0 <= 1</p>\n","type":"Number"}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3476,"description":"<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"source","description":"<p>p5.sound object (or web audio API source node)</p>\n","type":"Object","optional":true}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3501,"description":"<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n","itemtype":"method","name":"waveform","params":[{"name":"bins","description":"<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"precision","description":"<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n","type":"String","optional":true}],"return":{"description":"Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3553,"description":"<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n","itemtype":"method","name":"analyze","params":[{"name":"bins","description":"<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"scale","description":"<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n","type":"Number","optional":true}],"return":{"description":"spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.","type":"Array"},"example":["\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3650,"description":"<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n","itemtype":"method","name":"getEnergy","params":[{"name":"frequency1","description":"<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n","type":"Number|String"},{"name":"frequency2","description":"<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n","type":"Number","optional":true}],"return":{"description":"Energy   Energy (volume/amplitude) from\n                            0 and 255.","type":"Number"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3739,"description":"<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n","itemtype":"method","name":"getCentroid","return":{"description":"Spectral Centroid Frequency  of the spectral centroid in Hz.","type":"Number"},"example":["\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3826,"description":"<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"smoothing","description":"<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n","type":"Number"}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3854,"description":"<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"linAverages","params":[{"name":"N","description":"<p>Number of returned frequency groups</p>\n","type":"Number"}],"return":{"description":"linearAverages   Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3889,"description":"<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"logAverages","params":[{"name":"octaveBands","description":"<p>Array of Octave Bands objects for grouping</p>\n","type":"Array"}],"return":{"description":"logAverages    Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3925,"description":"<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n","itemtype":"method","name":"getOctaveBands","params":[{"name":"N","description":"<p>Specifies the 1/N type of generated octave bands</p>\n","type":"Number"},{"name":"fCtr0","description":"<p>Minimum central frequency for the lowest band</p>\n","type":"Number"}],"return":{"description":"octaveBands   Array of octave band objects with their bounds","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4168,"description":"<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>startTime in seconds from now.</p>\n","type":"Number","optional":true},{"name":"frequency","description":"<p>frequency in Hz.</p>\n","type":"Number","optional":true}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4218,"description":"<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n","itemtype":"method","name":"stop","params":[{"name":"secondsFromNow","description":"<p>Time, in seconds from now.</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4238,"description":"<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)","type":"AudioParam"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4271,"description":"<p>Returns the value of output gain</p>\n","itemtype":"method","name":"getAmp","return":{"description":"Amplitude value between 0.0 and 1.0","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4285,"description":"<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n","itemtype":"method","name":"freq","params":[{"name":"Frequency","description":"<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Ramp time (in seconds)</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen\n                                 at x seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency","type":"AudioParam"},"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4360,"description":"<p>Returns the value of frequency of oscillator</p>\n","itemtype":"method","name":"getFreq","return":{"description":"Frequency of oscillator in Hertz","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4373,"description":"<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","type":"String"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4386,"description":"<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"getType","return":{"description":"type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.","type":"String"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4399,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4420,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4444,"description":"<p>Pan between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"pan","params":[{"name":"panning","description":"<p>Number between -1 and 1</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4460,"description":"<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"getPan","return":{"description":"panPosition of oscillator , between Left (-1) and Right (1)","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4494,"description":"<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n","itemtype":"method","name":"phase","params":[{"name":"phase","description":"<p>float between 0.0 and 1.0</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4522,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4543,"description":"<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with multiplied output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4563,"description":"<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4767,"description":"<p>Time until envelope reaches attackLevel</p>\n","itemtype":"property","name":"attackTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4772,"description":"<p>Level once attack is complete.</p>\n","itemtype":"property","name":"attackLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4778,"description":"<p>Time until envelope reaches decayLevel.</p>\n","itemtype":"property","name":"decayTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4784,"description":"<p>Level after decay. The envelope will sustain here until it is released.</p>\n","itemtype":"property","name":"decayLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4790,"description":"<p>Duration of the release portion of the envelope.</p>\n","itemtype":"property","name":"releaseTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4796,"description":"<p>Level at the end of the release.</p>\n","itemtype":"property","name":"releaseLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4833,"description":"<p>Reset the envelope with a series of time/value pairs.</p>\n","itemtype":"method","name":"set","params":[{"name":"attackTime","description":"<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n","type":"Number"},{"name":"attackLevel","description":"<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time</p>\n","type":"Number"},{"name":"decayLevel","description":"<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n","type":"Number"},{"name":"releaseTime","description":"<p>Release Time (in seconds)</p>\n","type":"Number"},{"name":"releaseLevel","description":"<p>Amplitude</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4895,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4964,"description":"<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n","itemtype":"method","name":"setRange","params":[{"name":"aLevel","description":"<p>attack level (defaults to 1)</p>\n","type":"Number"},{"name":"rLevel","description":"<p>release level (defaults to 0)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5037,"description":"<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"inputs","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object","optional":true,"multiple":true}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5055,"description":"<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n","itemtype":"method","name":"setExp","params":[{"name":"isExp","description":"<p>true is exponential, false is linear</p>\n","type":"Boolean"}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5078,"description":"<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>","itemtype":"method","name":"play","params":[{"name":"unit","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object"},{"name":"startTime","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5148,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n","itemtype":"method","name":"triggerAttack","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5256,"description":"<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"triggerRelease","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5350,"description":"<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n","itemtype":"method","name":"ramp","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>When to trigger the ramp</p>\n","type":"Number"},{"name":"v","description":"<p>Target value</p>\n","type":"Number"},{"name":"v2","description":"<p>Second target value</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5460,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5479,"description":"<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5498,"description":"<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5657,"description":"<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'white', 'pink' or 'brown'</p>\n","type":"String","optional":true}],"class":"p5.Noise","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5871,"description":"<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n","itemtype":"method","name":"width","params":[{"name":"width","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.Pulse","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6066,"itemtype":"property","name":"input","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6070,"itemtype":"property","name":"output","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6075,"itemtype":"property","name":"stream","type":"MediaStream|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6080,"itemtype":"property","name":"mediaStream","type":"MediaStreamAudioSourceNode|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6085,"itemtype":"property","name":"currentSource","type":"Number|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6090,"description":"<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n","itemtype":"property","name":"enabled","type":"Boolean","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6098,"description":"<p>Input amplitude, connect to it by default but not to master out</p>\n","itemtype":"property","name":"amplitude","type":"p5.Amplitude","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6114,"description":"<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n","itemtype":"method","name":"start","params":[{"name":"successCallback","description":"<p>Name of a function to call on\n                                  success.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n","type":"Function","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6171,"description":"<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n","itemtype":"method","name":"stop","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6191,"description":"<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>An object that accepts audio input,\n                        such as an FFT</p>\n","type":"Object","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6216,"description":"<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6234,"description":"<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n","itemtype":"method","name":"getLevel","params":[{"name":"smoothing","description":"<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n","type":"Number","optional":true}],"return":{"description":"Volume level (between 0.0 and 1.0)","type":"Number"},"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6257,"description":"<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0</p>\n","type":"Number"},{"name":"time","description":"<p>ramp time (optional)</p>\n","type":"Number","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6280,"description":"<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n","itemtype":"method","name":"getSources","params":[{"name":"successCallback","description":"<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>This optional callback receives the error\n                                   message as its argument.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method","type":"Promise"},"example":["\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6340,"description":"<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n","itemtype":"method","name":"setSource","params":[{"name":"num","description":"<p>position of input source in the array</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6462,"description":"<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6478,"description":"<p>Set the output volume of the filter.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number","optional":true},{"name":"rampTime","description":"<p>create a fade that lasts until rampTime</p>\n","type":"Number","optional":true},{"name":"tFromNow","description":"<p>schedule this event to happen in tFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6502,"description":"<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n","itemtype":"method","name":"chain","params":[{"name":"arguments","description":"<p>Chain together multiple sound objects</p>\n","type":"Object","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6525,"description":"<p>Adjust the dry/wet value.</p>\n","itemtype":"method","name":"drywet","params":[{"name":"fade","description":"<p>The desired drywet value (0 - 1.0)</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6542,"description":"<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6557,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6719,"description":"<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n","itemtype":"property","name":"biquadFilter","type":"DelayNode","class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6742,"description":"<p>Filter an audio signal according to a set\nof filter parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6760,"description":"<p>Set the frequency and the resonance of the filter.</p>\n","itemtype":"method","name":"set","params":[{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance (Q) from 0.001 to 1000</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6781,"description":"<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n","itemtype":"method","name":"freq","params":[{"name":"freq","description":"<p>Filter Frequency</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value  Returns the current frequency value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6811,"description":"<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n","itemtype":"method","name":"res","params":[{"name":"res","description":"<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value Returns the current res value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6838,"description":"<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n","itemtype":"method","name":"gain","params":[{"name":"gain","description":"","type":"Number"}],"return":{"description":"Returns the current or updated gain value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6864,"description":"<p>Toggle function. Switches between the specified type and allpass</p>\n","itemtype":"method","name":"toggle","return":{"description":"[Toggle value]","type":"Boolean"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6884,"description":"<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n","itemtype":"method","name":"setType","params":[{"name":"t","description":"","type":"String"}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7198,"description":"<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n","itemtype":"property","name":"bands","type":"Array","class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7239,"description":"<p>Process an input by connecting it to the EQ</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Audio source</p>\n","type":"Object"}],"class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7629,"description":"<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n","itemtype":"property","name":"panner","type":"AudioNode","class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7654,"description":"<p>Connect an audio sorce</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Input source</p>\n","type":"Object"}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7668,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"set","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7687,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7694,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7701,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7753,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"orient","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7772,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7779,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7786,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7838,"description":"<p>Set the rolloff factor and max distance</p>\n","itemtype":"method","name":"setFalloff","params":[{"name":"maxDistance","description":"","type":"Number","optional":true},{"name":"rolloffFactor","description":"","type":"Number","optional":true}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7852,"description":"<p>Maxium distance between the source and the listener</p>\n","itemtype":"method","name":"maxDist","params":[{"name":"maxDistance","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7869,"description":"<p>How quickly the volume is reduced as the source moves away from the listener</p>\n","itemtype":"method","name":"rollof","params":[{"name":"rolloffFactor","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7989,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"leftDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7999,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"rightDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8049,"description":"<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"delayTime","description":"<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n","type":"Number","optional":true},{"name":"feedback","description":"<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n","type":"Number","optional":true},{"name":"lowPass","description":"<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8094,"description":"<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n","itemtype":"method","name":"delayTime","params":[{"name":"delayTime","description":"<p>Time (in seconds) of the delay</p>\n","type":"Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8116,"description":"<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n","itemtype":"method","name":"feedback","params":[{"name":"feedback","description":"<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n","type":"Number|Object"}],"return":{"description":"Feedback value","type":"Number"},"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8148,"description":"<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n","itemtype":"method","name":"filter","params":[{"name":"cutoffFreq","description":"<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n","type":"Number|Object"},{"name":"res","description":"<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n","type":"Number|Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8170,"description":"<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'pingPong' (1) or 'default' (0)</p>\n","type":"String|Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8223,"description":"<p>Set the output level of the delay effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8234,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8242,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8409,"description":"<p>Connect a source to the reverb, and assign reverb parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"},{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8446,"description":"<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n","itemtype":"method","name":"set","params":[{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8482,"description":"<p>Set the output level of the reverb effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8493,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8501,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8621,"description":"<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n","itemtype":"property","name":"convolverNode","type":"ConvolverNode","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8645,"description":"<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n","itemtype":"property","name":"impulses","type":"Array","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8737,"description":"<p>Connect a source to the convolver.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8786,"description":"<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n","itemtype":"method","name":"addImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8808,"description":"<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n","itemtype":"method","name":"resetImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8831,"description":"<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n","itemtype":"method","name":"toggleImpulse","params":[{"name":"id","description":"<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n","type":"String|Number"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8885,"description":"<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n","itemtype":"method","name":"createConvolver","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true}],"return":{"description":"","type":"p5.Convolver"},"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9084,"description":"<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9173,"description":"<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n","itemtype":"property","name":"sequence","type":"Array","class":"p5.Phrase","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9263,"description":"<p>Set the tempo of this part, in Beats Per Minute.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9278,"description":"<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n","itemtype":"method","name":"getBPM","return":{"description":"","type":"Number"},"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9291,"description":"<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9311,"description":"<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"loop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9333,"description":"<p>Tell the part to stop looping.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9349,"description":"<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n","itemtype":"method","name":"stop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9363,"description":"<p>Pause the part. Playback will resume\nfrom the current step.</p>\n","itemtype":"method","name":"pause","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9379,"description":"<p>Add a p5.Phrase to this Part.</p>\n","itemtype":"method","name":"addPhrase","params":[{"name":"phrase","description":"<p>reference to a p5.Phrase</p>\n","type":"p5.Phrase"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9406,"description":"<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n","itemtype":"method","name":"removePhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9424,"description":"<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n","itemtype":"method","name":"getPhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9442,"description":"<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n","itemtype":"method","name":"replaceSequence","params":[{"name":"phraseName","description":"","type":"String"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9473,"description":"<p>Set the function that will be called at every step. This will clear the previous function.</p>\n","itemtype":"method","name":"onStep","params":[{"name":"callback","description":"<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n","type":"Function"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9542,"description":"<p>Start playback of the score.</p>\n","itemtype":"method","name":"start","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9555,"description":"<p>Stop playback of the score.</p>\n","itemtype":"method","name":"stop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9569,"description":"<p>Pause playback of the score.</p>\n","itemtype":"method","name":"pause","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9581,"description":"<p>Loop playback of the score.</p>\n","itemtype":"method","name":"loop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9594,"description":"<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9628,"description":"<p>Set the tempo for all parts in the score</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9729,"description":"<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n","itemtype":"property","name":"bpm","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9750,"description":"<p>number of quarter notes in a measure (defaults to 4)</p>\n","itemtype":"property","name":"timeSignature","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9770,"description":"<p>length of the loops interval</p>\n","itemtype":"property","name":"interval","type":"Number|String","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9787,"description":"<p>how many times the callback has been called so far</p>\n","itemtype":"property","name":"iterations","type":"Number","readonly":"","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9800,"description":"<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n","itemtype":"property","name":"musicalTimeMode","type":"Boolean","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9808,"description":"<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9816,"description":"<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n","itemtype":"property","name":"maxIterations","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9826,"description":"<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9841,"description":"<p>Start the loop</p>\n","itemtype":"method","name":"start","params":[{"name":"timeFromNow","description":"<p>schedule a starting time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9860,"description":"<p>Stop the loop</p>\n","itemtype":"method","name":"stop","params":[{"name":"timeFromNow","description":"<p>schedule a stopping time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9878,"description":"<p>Pause the loop</p>\n","itemtype":"method","name":"pause","params":[{"name":"timeFromNow","description":"<p>schedule a pausing time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9896,"description":"<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n","itemtype":"method","name":"syncedStart","params":[{"name":"otherLoop","description":"<p>a p5.SoundLoop to sync with</p>\n","type":"Object"},{"name":"timeFromNow","description":"<p>Start the loops in sync after timeFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10068,"description":"<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n","itemtype":"property","name":"compressor","type":"AudioNode","class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10084,"description":"<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Sound source to be connected</p>\n","type":"Object"},{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number","optional":true},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10112,"description":"<p>Set the paramters of a compressor.</p>\n","itemtype":"method","name":"set","params":[{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number"},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number"},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number"},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10152,"description":"<p>Get current attack or set value w/ time ramp</p>\n","itemtype":"method","name":"attack","params":[{"name":"attack","description":"<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10178,"description":"<p>Get current knee or set value w/ time ramp</p>\n","itemtype":"method","name":"knee","params":[{"name":"knee","description":"<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10204,"description":"<p>Get current ratio or set value w/ time ramp</p>\n","itemtype":"method","name":"ratio","params":[{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10228,"description":"<p>Get current threshold or set value w/ time ramp</p>\n","itemtype":"method","name":"threshold","params":[{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10252,"description":"<p>Get current release or set value w/ time ramp</p>\n","itemtype":"method","name":"release","params":[{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10277,"description":"<p>Return the current reduction value</p>\n","itemtype":"method","name":"reduction","return":{"description":"Value of the amount of gain reduction that is applied to the signal","type":"Number"},"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10419,"description":"<p>isDetected is set to true when a peak is detected.</p>\n","itemtype":"attribute","name":"isDetected","type":"Boolean","default":"false","class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10432,"description":"<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n","itemtype":"method","name":"update","params":[{"name":"fftObject","description":"<p>A p5.FFT object</p>\n","type":"p5.FFT"}],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10470,"description":"<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n","itemtype":"method","name":"onPeak","params":[{"name":"callback","description":"<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n","type":"Function"},{"name":"val","description":"<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n","type":"Object","optional":true}],"example":["\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10676,"description":"<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"unit","description":"<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n","type":"Object","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10703,"description":"<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n","itemtype":"method","name":"record","params":[{"name":"soundFile","description":"<p>p5.SoundFile</p>\n","type":"p5.SoundFile"},{"name":"duration","description":"<p>Time (in seconds)</p>\n","type":"Number","optional":true},{"name":"callback","description":"<p>The name of a function that will be\n                              called once the recording completes</p>\n","type":"Function","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10739,"description":"<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n","itemtype":"method","name":"stop","class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10864,"description":"<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n","itemtype":"property","name":"WaveShaperNode","type":"AudioNode","class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10883,"description":"<p>Process a sound source, optionally specify amount and oversample values.</p>\n","itemtype":"method","name":"process","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10900,"description":"<p>Set the amount and oversample of the waveshaper distortion.</p>\n","itemtype":"method","name":"set","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10923,"description":"<p>Return the distortion amount, typically between 0-1.</p>\n","itemtype":"method","name":"getAmount","return":{"description":"Unbounded distortion amount.\n                 Normal values range from 0-1.","type":"Number"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10937,"description":"<p>Return the oversampling.</p>\n","itemtype":"method","name":"getOversample","return":{"description":"Oversample can either be 'none', '2x', or '4x'.","type":"String"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11055,"description":"<p>Connect a source to the gain node.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11070,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11084,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11098,"description":"<p>Set the output level of the gain node.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11181,"description":"<p>Connect to p5 objects or Web Audio Nodes</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11194,"description":"<p>Disconnect from soundOut</p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11322,"description":"<p>Getters and Setters</p>\n","itemtype":"property","name":"attack","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11328,"itemtype":"property","name":"decay","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11333,"itemtype":"property","name":"sustain","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11338,"itemtype":"property","name":"release","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11379,"description":"<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11431,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true}],"itemtype":"method","name":"triggerAttack","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11478,"description":"<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","params":[{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"itemtype":"method","name":"triggerRelease","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11516,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11544,"description":"<p>MonoSynth amp</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>desired volume</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Time to reach new volume</p>\n","type":"Number","optional":true}],"return":{"description":"new volume value","type":"Number"},"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11564,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11578,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11592,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11742,"description":"<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n","itemtype":"property","name":"notes","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11755,"description":"<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n","itemtype":"property","name":"polyvalue","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11761,"description":"<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n","itemtype":"property","name":"AudioVoice","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11800,"description":"<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11849,"description":"<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n","itemtype":"method","name":"noteADSR","params":[{"name":"note","description":"<p>Midi note on which ADSR should be set.</p>\n","type":"Number","optional":true},{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11881,"description":"<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11909,"description":"<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","itemtype":"method","name":"noteAttack","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)/</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12021,"description":"<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"noteRelease","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12105,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12119,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12133,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"}],"warnings":[{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:120"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:216"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:316"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:457"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:1001"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:223"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:248"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/validate_params.js:336"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:12"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:81"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:115"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:184"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:219"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:259"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:331"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:13"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:92"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:130"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:185"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:264"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:358"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:398"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:493"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:20"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:67"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:293"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:415"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:460"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:524"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:583"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:668"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:733"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:826"},{"message":"unknown tag: alt","line":" src/core/constants.js:66"},{"message":"unknown tag: alt","line":" src/core/constants.js:84"},{"message":"unknown tag: alt","line":" src/core/constants.js:102"},{"message":"unknown tag: alt","line":" src/core/constants.js:120"},{"message":"unknown tag: alt","line":" src/core/constants.js:138"},{"message":"unknown tag: alt","line":" src/core/environment.js:20"},{"message":"unknown tag: alt","line":" src/core/environment.js:52"},{"message":"unknown tag: alt","line":" src/core/environment.js:79"},{"message":"unknown tag: alt","line":" src/core/environment.js:129"},{"message":"unknown tag: alt","line":" src/core/environment.js:160"},{"message":"unknown tag: alt","line":" src/core/environment.js:228"},{"message":"unknown tag: alt","line":" src/core/environment.js:331"},{"message":"unknown tag: alt","line":" src/core/environment.js:354"},{"message":"unknown tag: alt","line":" src/core/environment.js:372"},{"message":"unknown tag: alt","line":" src/core/environment.js:390"},{"message":"unknown tag: alt","line":" src/core/environment.js:405"},{"message":"unknown tag: alt","line":" src/core/environment.js:421"},{"message":"unknown tag: alt","line":" src/core/environment.js:500"},{"message":"unknown tag: alt","line":" src/core/environment.js:550"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:586"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:660"},{"message":"unknown tag: alt","line":" src/core/environment.js:691"},{"message":"unknown tag: alt","line":" src/core/environment.js:713"},{"message":"replacing incorrect tag: function with method","line":" src/core/internationalization.js:105"},{"message":"replacing incorrect tag: returns with return","line":" src/core/internationalization.js:105"},{"message":"unknown tag: alt","line":" src/core/main.js:42"},{"message":"unknown tag: alt","line":" src/core/main.js:83"},{"message":"unknown tag: alt","line":" src/core/main.js:114"},{"message":"unknown tag: alt","line":" src/core/main.js:415"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:47"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:114"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:154"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:189"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:246"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:292"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:354"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:403"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:454"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:510"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:551"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:592"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:639"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:678"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:725"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:763"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:70"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:122"},{"message":"unknown tag: alt","line":" src/core/reference.js:7"},{"message":"unknown tag: alt","line":" src/core/reference.js:34"},{"message":"unknown tag: alt","line":" src/core/reference.js:87"},{"message":"unknown tag: alt","line":" src/core/reference.js:115"},{"message":"unknown tag: alt","line":" src/core/reference.js:137"},{"message":"unknown tag: alt","line":" src/core/reference.js:158"},{"message":"unknown tag: alt","line":" src/core/reference.js:179"},{"message":"unknown tag: alt","line":" src/core/reference.js:200"},{"message":"unknown tag: alt","line":" src/core/reference.js:231"},{"message":"unknown tag: alt","line":" src/core/reference.js:267"},{"message":"unknown tag: alt","line":" src/core/reference.js:288"},{"message":"unknown tag: alt","line":" src/core/reference.js:309"},{"message":"unknown tag: alt","line":" src/core/reference.js:331"},{"message":"unknown tag: alt","line":" src/core/reference.js:351"},{"message":"unknown tag: alt","line":" src/core/reference.js:379"},{"message":"unknown tag: alt","line":" src/core/reference.js:408"},{"message":"unknown tag: alt","line":" src/core/reference.js:448"},{"message":"unknown tag: alt","line":" src/core/reference.js:490"},{"message":"unknown tag: alt","line":" src/core/reference.js:512"},{"message":"unknown tag: alt","line":" src/core/rendering.js:15"},{"message":"unknown tag: alt","line":" src/core/rendering.js:125"},{"message":"unknown tag: alt","line":" src/core/rendering.js:183"},{"message":"unknown tag: alt","line":" src/core/rendering.js:204"},{"message":"unknown tag: alt","line":" src/core/rendering.js:243"},{"message":"unknown tag: alt","line":" src/core/rendering.js:326"},{"message":"unknown tag: alt","line":" src/core/structure.js:10"},{"message":"unknown tag: alt","line":" src/core/structure.js:83"},{"message":"unknown tag: alt","line":" src/core/structure.js:134"},{"message":"unknown tag: alt","line":" src/core/structure.js:192"},{"message":"unknown tag: alt","line":" src/core/structure.js:290"},{"message":"unknown tag: alt","line":" src/core/structure.js:391"},{"message":"unknown tag: alt","line":" src/core/structure.js:497"},{"message":"unknown tag: alt","line":" src/core/transform.js:11"},{"message":"unknown tag: alt","line":" src/core/transform.js:168"},{"message":"unknown tag: alt","line":" src/core/transform.js:193"},{"message":"unknown tag: alt","line":" src/core/transform.js:232"},{"message":"unknown tag: alt","line":" src/core/transform.js:268"},{"message":"unknown tag: alt","line":" src/core/transform.js:304"},{"message":"unknown tag: alt","line":" src/core/transform.js:342"},{"message":"unknown tag: alt","line":" src/core/transform.js:416"},{"message":"unknown tag: alt","line":" src/core/transform.js:455"},{"message":"unknown tag: alt","line":" src/core/transform.js:494"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:10"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:101"},{"message":"unknown tag: alt","line":" src/dom/dom.js:204"},{"message":"unknown tag: alt","line":" src/dom/dom.js:271"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1560"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1622"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1726"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1765"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1885"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2268"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2778"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:23"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:46"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:69"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:135"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:168"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:201"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:239"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:285"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:330"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:389"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:428"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:471"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:515"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:546"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:604"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:10"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:36"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:64"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:103"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:190"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:243"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:308"},{"message":"unknown tag: alt","line":" src/events/mouse.js:12"},{"message":"unknown tag: alt","line":" src/events/mouse.js:43"},{"message":"unknown tag: alt","line":" src/events/mouse.js:80"},{"message":"unknown tag: alt","line":" src/events/mouse.js:106"},{"message":"unknown tag: alt","line":" src/events/mouse.js:132"},{"message":"unknown tag: alt","line":" src/events/mouse.js:164"},{"message":"unknown tag: alt","line":" src/events/mouse.js:195"},{"message":"unknown tag: alt","line":" src/events/mouse.js:233"},{"message":"unknown tag: alt","line":" src/events/mouse.js:271"},{"message":"unknown tag: alt","line":" src/events/mouse.js:311"},{"message":"unknown tag: alt","line":" src/events/mouse.js:351"},{"message":"unknown tag: alt","line":" src/events/mouse.js:389"},{"message":"unknown tag: alt","line":" src/events/mouse.js:481"},{"message":"unknown tag: alt","line":" src/events/mouse.js:535"},{"message":"unknown tag: alt","line":" src/events/mouse.js:615"},{"message":"unknown tag: alt","line":" src/events/mouse.js:696"},{"message":"unknown tag: alt","line":" src/events/mouse.js:772"},{"message":"unknown tag: alt","line":" src/events/mouse.js:841"},{"message":"unknown tag: alt","line":" src/events/mouse.js:926"},{"message":"unknown tag: alt","line":" src/events/mouse.js:979"},{"message":"unknown tag: alt","line":" src/events/mouse.js:1025"},{"message":"unknown tag: alt","line":" src/events/touch.js:10"},{"message":"unknown tag: alt","line":" src/events/touch.js:71"},{"message":"unknown tag: alt","line":" src/events/touch.js:151"},{"message":"unknown tag: alt","line":" src/events/touch.js:223"},{"message":"unknown tag: alt","line":" src/image/image.js:15"},{"message":"unknown tag: alt","line":" src/image/image.js:94"},{"message":"unknown tag: alt","line":" src/image/image.js:413"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:18"},{"message":"replacing incorrect tag: returns with return","line":" src/image/loading_displaying.js:284"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:301"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:471"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:569"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:633"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:88"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:115"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:152"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:261"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:296"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:346"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:400"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:437"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:548"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:603"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:665"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:738"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:859"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:900"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:941"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:972"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1017"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1052"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1089"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1125"},{"message":"unknown tag: alt","line":" src/image/pixels.js:12"},{"message":"unknown tag: alt","line":" src/image/pixels.js:80"},{"message":"unknown tag: alt","line":" src/image/pixels.js:173"},{"message":"unknown tag: alt","line":" src/image/pixels.js:307"},{"message":"unknown tag: alt","line":" src/image/pixels.js:481"},{"message":"unknown tag: alt","line":" src/image/pixels.js:566"},{"message":"unknown tag: alt","line":" src/image/pixels.js:602"},{"message":"unknown tag: alt","line":" src/image/pixels.js:674"},{"message":"unknown tag: alt","line":" src/io/files.js:20"},{"message":"unknown tag: alt","line":" src/io/files.js:183"},{"message":"unknown tag: alt","line":" src/io/files.js:303"},{"message":"unknown tag: alt","line":" src/io/files.js:583"},{"message":"replacing incorrect tag: returns with return","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:1393"},{"message":"unknown tag: alt","line":" src/io/files.js:1535"},{"message":"unknown tag: alt","line":" src/io/files.js:1592"},{"message":"unknown tag: alt","line":" src/io/files.js:1656"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:85"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:148"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:195"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:240"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:288"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:352"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:545"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:597"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:638"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:896"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:960"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1009"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1055"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1100"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1146"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1190"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1242"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1305"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:40"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:102"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:146"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:191"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:239"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:295"},{"message":"unknown tag: alt","line":" src/io/p5.XML.js:9"},{"message":"unknown tag: alt","line":" src/math/calculation.js:10"},{"message":"unknown tag: alt","line":" src/math/calculation.js:33"},{"message":"unknown tag: alt","line":" src/math/calculation.js:72"},{"message":"unknown tag: alt","line":" src/math/calculation.js:116"},{"message":"unknown tag: alt","line":" src/math/calculation.js:182"},{"message":"unknown tag: alt","line":" src/math/calculation.js:231"},{"message":"unknown tag: alt","line":" src/math/calculation.js:269"},{"message":"unknown tag: alt","line":" src/math/calculation.js:316"},{"message":"unknown tag: alt","line":" src/math/calculation.js:371"},{"message":"unknown tag: alt","line":" src/math/calculation.js:409"},{"message":"unknown tag: alt","line":" src/math/calculation.js:464"},{"message":"unknown tag: alt","line":" src/math/calculation.js:512"},{"message":"unknown tag: alt","line":" src/math/calculation.js:560"},{"message":"unknown tag: alt","line":" src/math/calculation.js:612"},{"message":"unknown tag: alt","line":" src/math/calculation.js:646"},{"message":"unknown tag: alt","line":" src/math/calculation.js:701"},{"message":"unknown tag: alt","line":" src/math/calculation.js:745"},{"message":"replacing incorrect tag: returns with return","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/math.js:10"},{"message":"unknown tag: alt","line":" src/math/noise.js:36"},{"message":"unknown tag: alt","line":" src/math/noise.js:178"},{"message":"unknown tag: alt","line":" src/math/noise.js:243"},{"message":"unknown tag: alt","line":" src/math/p5.Vector.js:10"},{"message":"unknown tag: alt","line":" src/math/random.js:37"},{"message":"unknown tag: alt","line":" src/math/random.js:66"},{"message":"unknown tag: alt","line":" src/math/random.js:153"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:123"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:159"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:186"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:213"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:285"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:320"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:335"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:350"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:11"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:81"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:118"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:150"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:187"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:16"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:140"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:231"},{"message":"unknown tag: alt","line":" src/typography/p5.Font.js:31"},{"message":"unknown tag: alt","line":" src/utilities/conversion.js:10"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:15"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:43"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:130"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:237"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:311"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:373"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:451"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:537"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:10"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:31"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:52"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:73"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:100"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:122"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:143"},{"message":"unknown tag: alt","line":" src/webgl/3d_primitives.js:13"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:11"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:353"},{"message":"unknown tag: alt","line":" src/webgl/light.js:11"},{"message":"unknown tag: alt","line":" src/webgl/light.js:92"},{"message":"unknown tag: alt","line":" src/webgl/light.js:177"},{"message":"unknown tag: alt","line":" src/webgl/light.js:280"},{"message":"unknown tag: alt","line":" src/webgl/light.js:387"},{"message":"unknown tag: alt","line":" src/webgl/light.js:425"},{"message":"unknown tag: alt","line":" src/webgl/light.js:519"},{"message":"unknown tag: alt","line":" src/webgl/light.js:859"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:588"},{"message":"unknown tag: alt","line":" src/webgl/material.js:12"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:184"},{"message":"unknown tag: alt","line":" src/webgl/material.js:282"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:587"},{"message":"unknown tag: alt","line":" src/webgl/material.js:659"},{"message":"unknown tag: alt","line":" src/webgl/material.js:697"},{"message":"unknown tag: alt","line":" src/webgl/material.js:777"},{"message":"unknown tag: alt","line":" src/webgl/material.js:829"},{"message":"unknown tag: alt","line":" src/webgl/material.js:902"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:13"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:115"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:176"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:236"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:303"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:357"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:444"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:472"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:499"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:526"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:554"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:582"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:610"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:633"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:656"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:683"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:801"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:897"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1040"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1098"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1156"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1386"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1458"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1723"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:334"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:603"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:644"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:749"},{"message":"unknown tag: alt","line":" src/webgl/p5.Shader.js:306"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:115"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:158"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:191"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:203"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:236"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:250"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:456"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:471"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:556"},{"message":"replacing incorrect tag: params with param","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2882"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4271"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4360"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4386"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4460"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:6280"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:8116"},{"message":"Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.","line":" src/color/color_conversion.js:8"},{"message":"Missing item type\nConvert an HSBA array to HSLA.","line":" src/color/color_conversion.js:19"},{"message":"Missing item type\nConvert an HSBA array to RGBA.","line":" src/color/color_conversion.js:45"},{"message":"Missing item type\nConvert an HSLA array to HSBA.","line":" src/color/color_conversion.js:100"},{"message":"Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.","line":" src/color/color_conversion.js:123"},{"message":"Missing item type\nConvert an RGBA array to HSBA.","line":" src/color/color_conversion.js:187"},{"message":"Missing item type\nConvert an RGBA array to HSLA.","line":" src/color/color_conversion.js:226"},{"message":"Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.","line":" src/color/p5.Color.js:396"},{"message":"Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.","line":" src/color/p5.Color.js:427"},{"message":"Missing item type\nCSS named colors.","line":" src/color/p5.Color.js:446"},{"message":"Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.","line":" src/color/p5.Color.js:600"},{"message":"Missing item type\nFull color string patterns. The capture groups are necessary.","line":" src/color/p5.Color.js:613"},{"message":"Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.","line":" src/color/p5.Color.js:750"},{"message":"Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.","line":" src/color/p5.Color.js:960"},{"message":"Missing item type","line":" src/core/friendly_errors/fes_core.js:1"},{"message":"Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.","line":" src/core/friendly_errors/fes_core.js:915"},{"message":"Missing item type","line":" src/core/friendly_errors/file_errors.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/sketch_reader.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/stacktrace.js:1"},{"message":"Missing item type\nGiven an Error object, extract the most information from it.","line":" src/core/friendly_errors/stacktrace.js:34"},{"message":"Missing item type","line":" src/core/friendly_errors/validate_params.js:1"},{"message":"Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).","line":" src/core/shape/2d_primitives.js:16"},{"message":"Missing item type\nReturns the current framerate.","line":" src/core/environment.js:305"},{"message":"Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.","line":" src/core/environment.js:315"},{"message":"Missing item type","line":" src/core/helpers.js:1"},{"message":"Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing","line":" src/core/init.js:4"},{"message":"Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.","line":" src/core/internationalization.js:30"},{"message":"Missing item type\nSet up our translation function, with loaded languages","line":" src/core/internationalization.js:126"},{"message":"Missing item type\nReturns a list of languages we have translations loaded for","line":" src/core/internationalization.js:171"},{"message":"Missing item type\nReturns the current language selected for translation","line":" src/core/internationalization.js:178"},{"message":"Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.","line":" src/core/internationalization.js:185"},{"message":"Missing item type","line":" src/core/legacy.js:1"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/core/p5.Element.js:827"},{"message":"Missing item type\nResize our canvas element.","line":" src/core/p5.Renderer.js:99"},{"message":"Missing item type\nHelper function to check font type (system or otf)","line":" src/core/p5.Renderer.js:415"},{"message":"Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178","line":" src/core/p5.Renderer.js:467"},{"message":"Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer","line":" src/core/p5.Renderer2D.js:7"},{"message":"Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.","line":" src/core/p5.Renderer2D.js:402"},{"message":"Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.","line":" src/core/shim.js:18"},{"message":"Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign","line":" src/core/shim.js:39"},{"message":"Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()","line":" src/data/p5.TypedDict.js:197"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:387"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:425"},{"message":"Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:536"},{"message":"Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:600"},{"message":"Missing item type\nHelper function for select and selectAll","line":" src/dom/dom.js:127"},{"message":"Missing item type\nHelper function for getElement and getElements.","line":" src/dom/dom.js:142"},{"message":"Missing item type\nHelpers for create methods.","line":" src/dom/dom.js:309"},{"message":"Missing item type","line":" src/dom/dom.js:450"},{"message":"Missing item type","line":" src/dom/dom.js:1164"},{"message":"Missing item type","line":" src/dom/dom.js:1257"},{"message":"Missing item type","line":" src/dom/dom.js:1296"},{"message":"Missing item type","line":" src/dom/dom.js:3232"},{"message":"Missing item type","line":" src/dom/dom.js:3298"},{"message":"Missing item type","line":" src/dom/dom.js:3360"},{"message":"Missing item type\n_updatePAccelerations updates the pAcceleration values","line":" src/events/acceleration.js:124"},{"message":"Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.","line":" src/events/keyboard.js:298"},{"message":"Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.","line":" src/events/keyboard.js:384"},{"message":"Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.","line":" src/image/filters.js:3"},{"message":"Missing item type\nReturns the pixel buffer for a canvas","line":" src/image/filters.js:24"},{"message":"Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.","line":" src/image/filters.js:60"},{"message":"Missing item type\nModifies pixels RGBA values to values contained in the data object.","line":" src/image/filters.js:81"},{"message":"Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData","line":" src/image/filters.js:101"},{"message":"Missing item type\nReturns a blank ImageData object.","line":" src/image/filters.js:121"},{"message":"Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.","line":" src/image/filters.js:136"},{"message":"Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:189"},{"message":"Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:223"},{"message":"Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.","line":" src/image/filters.js:246"},{"message":"Missing item type\nSets each pixel to its inverse value. No parameter is used.","line":" src/image/filters.js:262"},{"message":"Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation","line":" src/image/filters.js:277"},{"message":"Missing item type\nreduces the bright areas in an image","line":" src/image/filters.js:309"},{"message":"Missing item type\nincreases the bright areas in an image","line":" src/image/filters.js:396"},{"message":"Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.","line":" src/image/image.js:8"},{"message":"Missing item type\nHelper function for loading GIF-based images","line":" src/image/loading_displaying.js:162"},{"message":"Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height","line":" src/image/loading_displaying.js:284"},{"message":"Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.","line":" src/image/loading_displaying.js:597"},{"message":"Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.","line":" src/image/p5.Image.js:9"},{"message":"Missing item type\nHelper function for animating GIF-based images with time","line":" src/image/p5.Image.js:222"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/image/p5.Image.js:253"},{"message":"Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.","line":" src/io/files.js:1789"},{"message":"Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.","line":" src/io/files.js:1857"},{"message":"Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.","line":" src/io/files.js:1890"},{"message":"Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.","line":" src/io/files.js:1902"},{"message":"Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","line":" src/io/p5.Table.js:9"},{"message":"Missing item type\nMultiplies a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2135"},{"message":"Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.","line":" src/math/p5.Vector.js:2187"},{"message":"Missing item type\nDivides a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2214"},{"message":"Missing item type\nCalculates the dot product of two vectors.","line":" src/math/p5.Vector.js:2267"},{"message":"Missing item type\nCalculates the cross product of two vectors.","line":" src/math/p5.Vector.js:2281"},{"message":"Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).","line":" src/math/p5.Vector.js:2295"},{"message":"Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.","line":" src/math/p5.Vector.js:2310"},{"message":"Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)","line":" src/math/p5.Vector.js:2339"},{"message":"Missing item type\nNormalize the vector to length 1 (make it a unit vector).","line":" src/math/p5.Vector.js:2357"},{"message":"Missing item type\nHelper function to measure ascent and descent.","line":" src/typography/attributes.js:280"},{"message":"Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.","line":" src/typography/p5.Font.js:273"},{"message":"Missing item type\nReturns an opentype path for the supplied string and position.","line":" src/typography/p5.Font.js:288"},{"message":"Missing item type","line":" src/webgl/3d_primitives.js:301"},{"message":"Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.","line":" src/webgl/3d_primitives.js:955"},{"message":"Missing item type\nDraw a line given two points","line":" src/webgl/3d_primitives.js:1393"},{"message":"Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1","line":" src/webgl/loading.js:179"},{"message":"Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.","line":" src/webgl/loading.js:290"},{"message":"Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.","line":" src/webgl/loading.js:317"},{"message":"Missing item type\nThis function matches the `query` at the provided `offset`","line":" src/webgl/loading.js:344"},{"message":"Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.","line":" src/webgl/loading.js:356"},{"message":"Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`","line":" src/webgl/loading.js:444"},{"message":"Missing item type","line":" src/webgl/material.js:947"},{"message":"Missing item type","line":" src/webgl/material.js:978"},{"message":"Missing item type\nCreate a 2D array for establishing stroke connections","line":" src/webgl/p5.Geometry.js:212"},{"message":"Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU","line":" src/webgl/p5.Geometry.js:233"},{"message":"Missing item type","line":" src/webgl/p5.Matrix.js:1"},{"message":"Missing item type\nPRIVATE","line":" src/webgl/p5.Matrix.js:722"},{"message":"Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.","line":" src/webgl/p5.RenderBuffer.js:12"},{"message":"Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.","line":" src/webgl/p5.RendererGL.Immediate.js:1"},{"message":"Missing item type\nEnd shape drawing and render vertices to screen.","line":" src/webgl/p5.RendererGL.Immediate.js:129"},{"message":"Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:169"},{"message":"Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:248"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:268"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:302"},{"message":"Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.","line":" src/webgl/p5.RendererGL.Retained.js:59"},{"message":"Missing item type\nDraws buffers given a geometry key ID","line":" src/webgl/p5.RendererGL.Retained.js:110"},{"message":"Missing item type\nmodel view, projection, & normal\nmatrices","line":" src/webgl/p5.RendererGL.js:117"},{"message":"Missing item type\n[background description]","line":" src/webgl/p5.RendererGL.js:586"},{"message":"Missing item type\n[resize description]","line":" src/webgl/p5.RendererGL.js:860"},{"message":"Missing item type\nclears color and depth buffers\nwith r,g,b,a","line":" src/webgl/p5.RendererGL.js:890"},{"message":"Missing item type\n[translate description]","line":" src/webgl/p5.RendererGL.js:924"},{"message":"Missing item type\nScales the Model View Matrix by a vector","line":" src/webgl/p5.RendererGL.js:943"},{"message":"Missing item type\nturn a two dimensional array into one dimensional array","line":" src/webgl/p5.RendererGL.js:1366"},{"message":"Missing item type\nturn a p5.Vector Array into a one dimensional number array","line":" src/webgl/p5.RendererGL.js:1403"},{"message":"Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.","line":" src/webgl/p5.RendererGL.js:1421"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:1"},{"message":"Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/","line":" lib/addons/p5.sound.js:52"},{"message":"Missing item type\nThis module has shims","line":" lib/addons/p5.sound.js:401"},{"message":"Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats","line":" lib/addons/p5.sound.js:536"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:807"},{"message":"Missing item type\nUsed by Osc and Envelope to chain signal math","line":" lib/addons/p5.sound.js:1040"},{"message":"Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.","line":" lib/addons/p5.sound.js:1542"},{"message":"Missing item type\nStop playback on all of this soundfile's sources.","line":" lib/addons/p5.sound.js:2056"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:2604"},{"message":"Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade","line":" lib/addons/p5.sound.js:6455"},{"message":"Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter","line":" lib/addons/p5.sound.js:6462"},{"message":"Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ","line":" lib/addons/p5.sound.js:7009"},{"message":"Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.","line":" lib/addons/p5.sound.js:8508"},{"message":"Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.","line":" lib/addons/p5.sound.js:8659"},{"message":"Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string","line":" lib/addons/p5.sound.js:9808"},{"message":"Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached","line":" lib/addons/p5.sound.js:9826"},{"message":"Missing item type\ncallback invoked when the recording is over","line":" lib/addons/p5.sound.js:10660"},{"message":"Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release","line":" lib/addons/p5.sound.js:11995"},{"message":"Missing item type","line":" lib/addons/p5.sound.min.js:1"}],"consts":{"LABEL":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"FALLBACK":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"RGB":["p5.colorMode"],"HSB":["p5.colorMode"],"HSL":["p5.colorMode"],"CHORD":["p5.arc"],"PIE":["p5.arc"],"OPEN":["p5.arc"],"CENTER":["p5.ellipseMode","p5.rectMode","p5.imageMode","p5.textAlign"],"RADIUS":["p5.ellipseMode","p5.rectMode"],"CORNER":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"CORNERS":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"ROUND":["p5.strokeCap","p5.strokeJoin"],"SQUARE":["p5.strokeCap"],"PROJECT":["p5.strokeCap"],"MITER":["p5.strokeJoin"],"BEVEL":["p5.strokeJoin"],"POINTS":["p5.beginShape"],"LINES":["p5.beginShape"],"TRIANGLES":["p5.beginShape"],"TRIANGLE_FAN":["p5.beginShape"],"TRIANGLE_STRIP":["p5.beginShape"],"QUADS":["p5.beginShape"],"QUAD_STRIP":["p5.beginShape"],"TESS":["p5.beginShape"],"CLOSE":["p5.endShape"],"ARROW":["p5.cursor"],"CROSS":["p5.cursor"],"HAND":["p5.cursor"],"MOVE":["p5.cursor"],"TEXT":["p5.cursor"],"P2D":["p5.createCanvas","p5.createGraphics"],"WEBGL":["p5.createCanvas","p5.createGraphics"],"BLEND":["p5.blendMode","p5.Image.blend","p5.blend"],"DARKEST":["p5.blendMode","p5.Image.blend","p5.blend"],"LIGHTEST":["p5.blendMode","p5.Image.blend","p5.blend"],"DIFFERENCE":["p5.blendMode","p5.Image.blend","p5.blend"],"MULTIPLY":["p5.blendMode","p5.Image.blend","p5.blend"],"EXCLUSION":["p5.blendMode","p5.Image.blend","p5.blend"],"SCREEN":["p5.blendMode","p5.Image.blend","p5.blend"],"REPLACE":["p5.blendMode","p5.Image.blend","p5.blend"],"OVERLAY":["p5.blendMode","p5.Image.blend","p5.blend"],"HARD_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"SOFT_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"DODGE":["p5.blendMode","p5.Image.blend","p5.blend"],"BURN":["p5.blendMode","p5.Image.blend","p5.blend"],"ADD":["p5.blendMode","p5.Image.blend","p5.blend"],"REMOVE":["p5.blendMode"],"SUBTRACT":["p5.blendMode"],"VIDEO":["p5.createCapture"],"AUDIO":["p5.createCapture"],"THRESHOLD":["p5.Image.filter","p5.filter"],"GRAY":["p5.Image.filter","p5.filter"],"OPAQUE":["p5.Image.filter","p5.filter"],"INVERT":["p5.Image.filter","p5.filter"],"POSTERIZE":["p5.Image.filter","p5.filter"],"ERODE":["p5.Image.filter","p5.filter"],"DILATE":["p5.Image.filter","p5.filter"],"BLUR":["p5.Image.filter","p5.filter"],"NORMAL":["p5.Image.blend","p5.blend","p5.textStyle","p5.textureMode"],"RADIANS":["p5.angleMode"],"DEGREES":["p5.angleMode"],"LEFT":["p5.textAlign"],"RIGHT":["p5.textAlign"],"TOP":["p5.textAlign"],"BOTTOM":["p5.textAlign"],"BASELINE":["p5.textAlign"],"ITALIC":["p5.textStyle"],"BOLD":["p5.textStyle"],"BOLDITALIC":["p5.textStyle"],"WORD":["p5.textWrap"],"CHAR":["p5.textWrap"],"IMAGE":["p5.textureMode"],"CLAMP":["p5.textureWrap"],"REPEAT":["p5.textureWrap"],"MIRROR":["p5.textureWrap"]}}
            \ No newline at end of file
            diff --git a/dist/ko/reference/index.html b/dist/ko/reference/index.html
            new file mode 100644
            index 0000000000..cababd4dcc
            --- /dev/null
            +++ b/dist/ko/reference/index.html
            @@ -0,0 +1,294 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">reference | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="reference-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Reference</h1>
            +
            +      <div id="search" class="search-wrapper" role="search"></div>
            +      <div id="collection-list-nav"></div>
            +
            +          <!--class="container-fluid"-->
            +      <div id="list" tabindex="2" class="list-wrapper allItems-collection"></div>
            +      <div id="item" tabindex="1" class="item-wrapper apidocs"></div>
            +      <div id="file" class="file-wrapper"></div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  <script src='/assets/js/p5.min.js?v=fbf148'></script>
            +  <script src='/assets/js/p5.sound.min.js?v=53b7c5'></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
            +  <script src="/assets/js/vendor/require.min.js"></script>
            +  <script src="/assets/js/render.js?v=56ab24"></script>
            +  <script src="/assets/js/reference.js?v=c69268"></script>
            +
            +  <script>
            +
            +    var translations;
            +
            +    $(document).ready(function() {
            +      var routes = window.location.pathname.split('/');
            +      var lang = routes[1];
            +      if (langs.indexOf(lang) != -1) {
            +        $.getJSON('/assets/reference/'+lang+'.json', function(data) {
            +          translations = data;
            +
            +          window.addEventListener('reference-rendered', function() {
            +            console.log("rendered");
            +            updateLanguage();
            +          }, false);
            +        });
            +      }
            +    });
            +
            +    function removePlaceholder() {
            +      $('#search input').attr('placeholder', '');
            +    }
            +
            +    function updateLanguage() {
            +      if (translations) {
            +        // reference title
            +        $('h1').html(translations['h1']);
            +        $('#search input').attr('placeholder', translations['reference-search']);
            +        $('#search input').on('focus', removePlaceholder);
            +        $('#search input').focusout(function () {
            +          $('#search input').attr('placeholder', translations['reference-search']);
            +        })
            +        $('#search input').attr('title', translations['reference-search']);
            +        // reference description
            +        $('#reference-description1').html(translations['reference-description1']);
            +        $('#reference-description2').html(translations['reference-description2']);
            +        $('#reference-description3').html(translations['reference-description3']);
            +        $('#reference-description4').html(translations['reference-description4']);
            +        // reference contribute
            +        $('#reference-contribute1').html(translations['reference-contribute1']);
            +        $('#reference-contribute2').html(translations['reference-contribute2']);
            +        // reference error
            +        $('#reference-error1').html(translations['reference-error1']);
            +        $('#reference-error2').html(translations['reference-error2']);
            +        $('#reference-error3').html(translations['reference-error3']);
            +        $('#reference-error4').html(translations['reference-error4']);
            +        $('#reference-error5').html(translations['reference-error5']);
            +        // reference texts
            +        $('#reference-example').html(translations['reference-example']);
            +        $('#reference-description').html(translations['reference-description'])
            +        $('#reference-extends').html(translations['reference-extends']);
            +        $('#reference-parameters').html(translations['reference-parameters']);
            +        $('#reference-syntax').html(translations['reference-syntax']);
            +        $('#reference-returns').html(translations['reference-returns']);
            +        $('.group-name, .subgroup-name').each(function() {
            +          $(this).text(translations[$(this).text()]);
            +        });
            +        var routes = window.location.hash.split('/');
            +        var obj = routes[1];
            +        var name = routes[2];
            +
            +        // class page
            +        if (routes.length == 2) {
            +          var entry = translations[obj];
            +          for (var k in entry) {
            +            if (k == 'description') {
            +              $('.description-text').html('');
            +              entry.description.forEach(function (p) {
            +                $('.description-text').append('<p>' + p + '</p>');
            +              });
            +            }
            +            else if (k == 'params') {
            +              $('.params').find('ul').children('li').each(function () {
            +                var paramname = $(this).children('.paramname').text();
            +                $(this).children('.paramtype').text(entry.params[paramname]);
            +              });
            +            }
            +            else if (k == 'returns') {
            +              $('.returns').text(entry.returns);
            +            }
            +            // fields and methods sections
            +            else {
            +              // field
            +              $("[aria-labelledby='reference-fields']").children('li').each(function (i) {
            +                var fieldName = $(this).children('.paramname').children('a').text();
            +                let descr = '';
            +                var paragraphs = entry[fieldName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +              // method
            +              $("[aria-labelledby='reference-methods']").children('li').each(function (i) {
            +                var method = $(this).children('.paramname').children('a').text();
            +                // removes the brackets
            +                var methodName = method.substring(0, method.length - 2);
            +                let descr = '';
            +                var paragraphs = entry[methodName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +            }
            +          }
            +        }
            +
            +        // method/field page
            +        if (routes.length == 3) {
            +          if (translations[obj] && translations[obj][name]) {
            +            var entry = translations[obj][name];
            +
            +            $('.description-text').html('');
            +            entry.description.forEach(function (p) {
            +              $('.description-text').append('<p>' + p + '</p>');
            +            });
            +            $('.returns').html(entry.returns);
            +            $('.params').find('ul').children('li').each(function () {
            +              var paramname = $(this).children('.paramname').text();
            +              $(this).children('.paramtype').html(entry.params[paramname]);
            +            });
            +          }
            +        }
            +      }
            +    }
            +    </script>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="reference-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/reference/staticStrings.json b/dist/ko/reference/staticStrings.json
            new file mode 100644
            index 0000000000..4ba85d3402
            --- /dev/null
            +++ b/dist/ko/reference/staticStrings.json
            @@ -0,0 +1,16 @@
            +{
            +  "h1": "Reference",
            +  "reference-search": "Search reference",
            +  "reference-description1": "Can't find what you're looking for? You may want to check out",
            +  "reference-description3": "You can also download an offline version of the reference.",
            +  "reference-contribute2": "Please let us know.",
            +  "reference-error1": "Notice any errors or typos?",
            +  "reference-error3": "Please feel free to edit ",
            +  "reference-error5": "and issue a pull request!",
            +  "reference-example": "Example",
            +  "reference-description": "Description",
            +  "reference-extends": "Extends",
            +  "reference-parameters": "Parameters",
            +  "reference-syntax": "Syntax",
            +  "reference-returns": "Returns"
            +}
            diff --git a/dist/ko/showcase/featuring/casey-louise.html b/dist/ko/showcase/featuring/casey-louise.html
            new file mode 100644
            index 0000000000..03b9c57db6
            --- /dev/null
            +++ b/dist/ko/showcase/featuring/casey-louise.html
            @@ -0,0 +1,240 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>p5.js 셰이더(Shaders)</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <div class="glitch-embed-wrap" style="height: 420px; width: 100%;">
            +        <iframe src="https://glitch.com/embed/#!/embed/shader-on-vertex?path=&previewSize=100"
            +          title="A Glitch project showing how to apply shaders to a vertex shape in p5.js."
            +          style="height: 100%; width: 100%; border: 0;">
            +        </iframe>
            +      </div>
            +    </section>
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Casey Conchinha <span class="note">(he/him)</span></p>
            +        <p>Louise Lessél <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From New York, New York</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class='links' aria-labelledby="resources">
            +          <li><a href="https://bit.ly/p5shaders" target="_blank">p5.js Shaders guide</a></li>
            +          <li><a href="https://bit.ly/p5shadersexamples" target="_blank">Glitch collection of p5.js shader examples</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>Casey: I'm a student at NYU ITP who's interested in computer graphics and interactive spaces, physical and digital.</p>
            +        <p class='project-a'>Louise: I'm a student at NYU ITP who's interested in computer graphics and interactive spaces based on sensor technologies.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>Casey: I started learning p5.js in 2018 in my first semester at ITP, though I had been dabbling in <a href="https://processing.org/"
            +            target="_blank">Processing</a> since 2012. I was introduced to Processing by my friend Pedro while I was studying graphic design, and it blew my mind. The idea of making my own tools for creating graphics and interactive art piqued my interest, but once I actually tried it, I was hooked. The first project I can remember was an eye that followed you around the screen, and it was sad when you left it alone.</p>
            +        <p class='project-a'>Louise: I initially learned p5.js to make a website I was creating more playful. I’m a C# programmer, so this was a good segway into JavaScript for me.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>Casey: I was putting off learning shaders for a long time, and I was also curious if I could use them in p5.js. Then I heard about a grant for open source, storytelling, and learning resource projects at ITP called <a href="https://www.itpxstory.com/"
            +            target="_blank">xStory</a>. Since I wasn't finding much in the way of p5.js + shader documentation, I decided to figure out how they're implemented in p5.js and create a resource for others to learn. When I told Louise about the project, she was immediately excited about learning and teaching shaders in p5.js. She's been great about making sure the project is a learning resource and not just a collection of examples.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>Casey: Does <a href="https://thecodingtrain.com/"
            +            target="_blank">Shiffman</a> count as a feature? I also love having the ability to share my programs on the web so that people don't have to install special software or come to NYC to see my work.</p>
            +        <p class='project-a'>
            +          Louise: My favorite feature is <code><a href="https://p5js.org/reference/#/p5/push" target="_blank">push()</a></code> and <code><a href="https://p5js.org/reference/#/p5/pop" target="_blank">pop()</a></code> for transformation of the coordinate system to make generative visuals.
            +        </p>
            +
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>Casey: The beginning of the project (figuring out how things work) was us reaching out to amazing people, asking questions, and asking for permission to use their examples in our project. <a
            +            href="https://github.com/aferriss/p5jsShaderExamples"
            +            target="_blank">Adam Ferriss' GitHub repo</a> really laid the groundwork for us in understanding how shaders work in p5.js and provided a framework of approachable examples for us to build on. For some specific p5.js-related issues we were having, we reached out to <a
            +            href="http://www.katehollenbach.com/" target="_blank">Kate
            +            Hollenbach</a> and <a href="https://stalgiagrigg.name/"
            +            target="_blank">Stalgia Grigg</a> (who worked on the <a
            +            href="https://github.com/processing/p5.js/issues?q=is%3Aissue+is%3Aopen+webgl+label%3Aarea%3Awebgl"
            +            target="_blank">WebGL implementation in p5.js</a>), and they were super helpful.
            +        </p>
            +        <p class='project-a'>Louise: The learning curve was pretty steep for getting shaders into p5. Luckily, there were some very well-documented examples on GitHub by Adam Ferriss. Our aim was to do so in a way that a complete beginner can understand how to implement it, so it was as much a technical challenge as it was a challenge in teaching code to strangers and beginners. Here we drew inspiration from the way the <a
            +            href="https://openframeworks.cc/ofBook/chapters/foreword.html"
            +            target="_blank">openFrameworks book</a> is written. A fun "hey, it’s not hard and you can do it too" approach is what we believe in.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out the <a href="https://github.com/ITP-xStory"
            +            target="_blank">xStory GitHub</a> to explore our peers' amazing grant projects!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'>Casey: <a href="https://cargocollective.com/kcconch"
            +            target="_blank">cargocollective.com/kcconch</a>, <a href="https://github.com/kcconch"
            +            target="_blank">@kcconch</a> (GitHub)</p>
            +        <p class='project-a'>Louise: <a href="http://www.louiselessel.com/" target="_blank">louiselessel.com</a>, <a
            +            href="https://github.com/louiselessel" target="_blank">@louiselessel</a> (GitHub)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/showcase/featuring/daein-chung.html b/dist/ko/showcase/featuring/daein-chung.html
            new file mode 100644
            index 0000000000..775b9d291c
            --- /dev/null
            +++ b/dist/ko/showcase/featuring/daein-chung.html
            @@ -0,0 +1,225 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Chillin'</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only' id="info">Project Info</h2>
            +      <img src="../../../assets/img/showcase/daein-chung/daein-chung_chillin.png" alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device.
            +        At the top, there is a text input box to enter a message and download your own poster.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Dae In Chung <span class="note">(he/him)</span></p>
            +        <p class="creator-from">From Baltimore, Maryland</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class="links">
            +          <li><a href="https://exp.paperdove.com/chillin/" target="_blank">View Chillin'</a></li>
            +          <li><a href="https://github.com/cdaein/exp/tree/gh-pages/chillin"
            +              target="_blank">Code for Chillin' on GitHub</a></li>
            +          <li><a href="https://paperdove.com/work/2019-chillin/" target="_blank">More info in Dae In Chung's Portfolio</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I am a graphic designer and a faculty member at Maryland Institute College of Art, where I mainly teach coding (with p5.js and Processing, of course) and motion graphics.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I have been using <a href="https://processing.org/"
            +            target="_blank">Processing</a> for some time, and when p5.js came along, I started using it without a second thought because it was easy to convert existing Processing code and share projects online.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>This summer, I gave myself a challenge of making typographic posters with coding, and this is one of the posters I made. I didn’t know until very recently that I could use motion sensor data with p5.js. I was also watching <a
            +            href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6bLh3T_4wtrmVHOrOEM1ig_"
            +            target="_blank">Dan Shiffman’s matter.js tutorial videos</a>, so I thought why not combine the two and practice what I was learning?
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>There are many things I love about p5.js such as the online community and beginner friendliness. What I really like right now is the <a href="https://editor.p5js.org/"
            +            target="_blank">online editor</a>, with which I can not only work online for myself but also share URLs quickly in the present mode. For this project in particular, I had to do a lot of testing on my phone, and it was much easier and quicker than committing to GitHub.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>I had some troubles with handling font, alpha channel and z-depth in <a
            +            href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5"
            +            target="_blank">WebGL</a> mode. I am still not happy with all my decisions. But in general, it was helpful to search the forum and not to forget to break down problems into smaller ones and iterate little by little. Also, I had issues with rendering out video files directly out of p5.js. Screen recording was not an option because of intermittent frame rate drops (my laptop is pretty slow). After doing some research, I decided to learn some basics of <a href="https://electronjs.org/"
            +            target="_blank">Electron</a> and build a tool for myself.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>As mentioned above, if you want to render out frames and video files out of p5.js sketches, check out my <a
            +            href="https://github.com/cdaein/p5js-electron-canvas-saver-boilerplate" target="_blank">Canvas Saver
            +            boilerplate</a> and let me know what you think.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/cdaein/" target="_blank">@cdaein</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/showcase/featuring/moon-xin.html b/dist/ko/showcase/featuring/moon-xin.html
            new file mode 100644
            index 0000000000..20d39eb090
            --- /dev/null
            +++ b/dist/ko/showcase/featuring/moon-xin.html
            @@ -0,0 +1,232 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>움직이는 반응형 포스터(Moving Responsive Posters)</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png"
            +        alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Moon Jang <span class="note">(she/her)</span></p>
            +        <p>Xin Xin <span class="note">(they/them)</span></p>
            +        <p class="creator-from">From Athens, Georgia</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Posters By</h3>
            +        <ul class="links">
            +          <li><a href="https://editor.p5js.org/avezray/present/JTjhOdGRB" target="_blank">Avery Ray</a></li>
            +          <li><a href="https://editor.p5js.org/carcarw/present/DyKJHUtCN" target="_blank">Carlee Wooddell</a></li>
            +          <li><a href="https://editor.p5js.org/mdh54215/present/h5wp4EYen" target="_blank">Mia Hofmann</a></li>
            +          <li><a href="https://editor.p5js.org/katiehuang1998@gmail.com/present/1GhSDw-Og" target="_blank">Katie
            +              Huang</a></li>
            +          <li><a href="https://editor.p5js.org/borderrider@gmail.com/present/Lg_pSPRHF" target="_blank">Lila
            +              Mitchell</a></li>
            +          <li><a href="https://editor.p5js.org/wallacekd/present/GqWZOYUSN" target="_blank">Kathryn Wallace</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>Moon: I'm a graphic designer, visual artist, and design educator. This summer, I taught a graphic design course in the University of Georgia Cortona program in Italy, introducing some basics of p5.js. This fall, I am planning to teach and to study digital platforms at UGA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>My former colleague, <a href="https://xin-xin.info/" target="_blank">Xin
            +            Xin</a>, invited me to <a href="https://medium.com/processing-foundation/pcd/home"
            +            target="_blank">Processing Community Day</a> in <a
            +            href="https://day.processing.org/pcd-la.html"
            +            target="_blank">LA in January 2019</a>. They helped me with the tools and logics of p5.js. It was an excellent teaching and learning experience.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>We followed basic tutorials, <a href="https://thecodingtrain.com/"
            +            target="_blank">Daniel's videos on YouTube</a>, and <a
            +            href="https://p5js.org/reference/"
            +            target="_blank">Reference on the p5.js website</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>My favorite function is related to <a
            +            href="https://p5js.org/reference/#group-Typography"
            +            target="_blank">type</a> and <a
            +            href="https://p5js.org/reference/#group-Transform"
            +            target="_blank">transformation</a>: <code><a href="https://p5js.org/reference/#/p5/rotate" target="_blank">rotate()</a></code>. I was able to use and to teach this tool to visualize various ideas about time in motion.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>It was challenging for me, a beginner, to understand the overall structure of p5.js and how code works in general. I had to repeat the p5.js basics a couple of times, and then I drew a chart to memorize and to teach the way I understood the p5.js structure and code with strong constraints I set up. It was an excellent teaching and learning experience.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out the <a href="http://www.brokennature.org/"
            +            target="_blank">Design Triennale</a> in Milan, Italy.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="http://www.moonjang.com/" target="_blank">moonjang.com</a>
            +          <br><a href="https://www.instagram.com/borderrider/" target="_blank">@borderrider</a> (Instagram)
            +        </p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/showcase/featuring/phuong-ngo.html b/dist/ko/showcase/featuring/phuong-ngo.html
            new file mode 100644
            index 0000000000..090a370d5f
            --- /dev/null
            +++ b/dist/ko/showcase/featuring/phuong-ngo.html
            @@ -0,0 +1,232 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>날아라 아이리(Airi Flies)</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" alt="A screenshot of a poster of Airi Flies, a game to help Airi fly by saying pew.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Phuong Ngo <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From Kyiv, Ukraine</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://www.yonaymoris.me/AiriFlies/" target="_blank">Play Airi Flies!</a></li>
            +          <li><a href="https://github.com/yonaymoris/AiriFlies" target="_blank">Code for AiriFlies on GitHub</a>
            +          </li>
            +          <li><a href="https://www.yonaymoris.me/projects/airiflies"
            +              target="_blank">More info in Phuong Ngo's portfolio</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I'm a creative coder and designer, a <a href="https://schoolofma.org/"
            +            target="_blank">School of Machines, Making & Make-Believe</a> diversity scholarship recipient, and just a curious creature.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I was taking a course at the School of Machines in Berlin this summer called! "<a href="https://schoolofma.org/bots.html"
            +            target="_blank">Bots and Machine Learning</a>," mainly taught by <a
            +            href="https://1023.io/" target="_blank">Yining Shi</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>I used p5.js to work on the visual part of the game. The animation sprites for Airi and the ghosts were drawn on an iPad app called <a href="https://rizer.co/pixaki/"
            +            target="_blank">Pixaki</a> and then integrated into <a
            +            href="http://molleindustria.github.io/p5.play/"
            +            target="_blank">p5.play</a> code. I mainly used examples at p5.play as a reference.</p>
            +        <p class='project-a'>For the endless scrolling background, I found a <a
            +            href="https://editor.p5js.org/chjno/sketches/ByZlypKWM"
            +            target="_blank">p5 sketch by chjno</a>. I set a condition so whenever the word "pew" or a mouse click was detected, the scrolling speed would change to make an illusion of Airi flying up. When the user does not do anything, the scrolling speed is negative, which makes it look like Airi is falling down.
            +        </p>
            +        <p class='project-a'>For sound recognition, I used <a
            +            href="https://teachablemachine.withgoogle.com/io19" target="_blank">Google's Teachable Machine
            +            2</a> (currently, there is a beta version not available in public yet, but it will be very soon!). I added around 120 samples of my classmates saying the word "pew" with different intonations and 80 samples of background noise to train it. Then I integrated the model into the game with <a href="https://ml5js.org/" target="_blank">ml5.js</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>I really love how easily you can create, manipulate, and delete HTML blocks and classes with the <a href="https://p5js.org/reference/"
            +            target="_blank">p5.js
            +            library</a> via <code><a href="https://p5js.org/reference/#/p5/createDiv" target="_blank">createDiv()</a></code>,
            +          <code><a href="https://p5js.org/reference/#/p5.Element/addClass" target="_blank">addClass()</a></code> etc. But my most favorite function is <code><a href="https://p5js.org/reference/#/p5/draw" target="_blank">draw()</a></code>, since this is where you create magic.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>There were a lot of challenges simply because p5.js was something new to me. I did not work much with JavaScript in general before. Reading documentation and searching for similar examples helped a lot.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out <a href="https://schoolofma.org/programs"
            +            target="_blank">School of Machines' courses</a>! They try hard to connect the most creative people in the world and they do it well so far. ❤️
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://www.yonaymoris.me/" target="_blank">yonaymoris.me</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/showcase/featuring/qianqian-ye.html b/dist/ko/showcase/featuring/qianqian-ye.html
            new file mode 100644
            index 0000000000..668191ce1e
            --- /dev/null
            +++ b/dist/ko/showcase/featuring/qianqian-ye.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Qtv</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" alt="A guest talk video (Guest Talk #1) on Qtv by Qianqian Ye, featuring Kaikai and Cheng Xu.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Qianqian Ye <span class="note">(she/her)</span></p>
            +        <p class="creator-from">Los Angeles, California</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Resources</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://bit.ly/2XVzPAv" target="_blank">Qtv YouTube</a></li>
            +          <li><a href="https://www.instagram.com/q_tv_/" target="_blank">Qtv Instagram</a></li>
            +          <li><a href="https://space.bilibili.com/442343394" target="_blank">Qtv Bilibili</a></li>
            +          <li><a href='https://v.douyin.com/sopAGk/' target='_blank'>@Q_tv TikTok</a></li>
            +          <li><a href="https://medium.com/processing-foundation/interview-with-2019-fellow-qianqian-ye-799c0115c295"
            +              target="_blank">Processing Foundation interview with Qianqian Ye</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I am a Chinese artist and designer based in Los Angeles.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>My partner introduced me to p5.js, which I learned mainly by watching free online video tutorials. My first p5.js project was drawing some shapes with different colors.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>This project started with an idea of teaching my mom, who lives in China and doesn’t speak English, to code with p5.js. This project was difficult on multiple levels, and I wanted to start by identifying the main reasons why it’s more challenging for someone like my mother to learn to code—primarily due to the lack of free creative coding education resources. Most of the free resources to learn creative coding are unavailable in China. The p5.js tutorials on YouTube as well as the p5.js Twitter and Instagram accounts are inaccessible in China because of internet censorship.</p>
            +        <p class='project-a'>I learned a lot from YouTube videos such as the <a href="https://thecodingtrain.com/"
            +            target="_blank">Coding Train</a>, but the more I watched coding tutorials online, the more I realized how difficult it is to find other womxn and people of color teaching coding, especially in Mandarin. I wanted to help other Chinese womxn relate to creative coding.</p>
            +        <p class='project-a'>I am working on opening up the video channels to other Chinese creatives who want to contribute to the educational resource together, like interviews and guest tutorials. If you are interested in teaching/talking about creative coding in Mandarin, HMU!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>The <a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a> is my favorite feature. It makes web-based creative coding seamless.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>Learning to code in a second language was difficult and the lack of community made this process even harder. I hope to speak from my experience as a beginner and someone who once felt like an outsider to the creative coding and video tutorial world.</p>
            +        <p class='project-a'>I spend a lot of time researching the latest technology for my videos. In the end, I decided on using my phone to record and iMovie to edit. I hope to encourage others that it doesn’t take a lot of expensive gears to get started making instructional videos.</p>
            +        <p class='project-a'>Another issue I came across was my own fear of putting myself online. I first had to get over my anxiety of making mistakes in the videos or receiving negative comments online. Often womxn and people of color are targets for online harassment. I’m hoping to help set an example for other womxn and people of color that it’s ok to put yourselves online and strengthen your communities by sharing your knowledge. Eventually, we will be able to stop online harassment by creating strong diverse communities.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>I am very excited about <a href="http://tinytechzines.org/"
            +            target="_blank">Tiny Tech Zines</a> in LA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="http://www.qianqian-ye.com/" target="_blank">qianqian-ye.com</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/showcase/featuring/roni-cantor.html b/dist/ko/showcase/featuring/roni-cantor.html
            new file mode 100644
            index 0000000000..18f49485f3
            --- /dev/null
            +++ b/dist/ko/showcase/featuring/roni-cantor.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>각도기 드로잉 프로그램(Programmed Plotter Drawings)</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img class='half-image' src="../../../assets/img/showcase/roni-cantor/roni-cantor_plotter-turquoise.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a turquoise gel pen.">
            +      <img class='half-image' src="../../../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a white gel pen.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Roni Cantor <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From Toronto, Canada</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class="links" aria-labelledby="resources">
            +          <li><a href="https://editor.p5js.org/ronicantor/sketches/eq2bIhmh2"
            +              target="_blank">Example sketch in p5.js Web Editor</a></li>
            +          <li><a href="https://drive.google.com/file/d/1UJy6q5cDl6Hg79O9mX1ZN7NFp0NXSYCs/view?usp=sharing"
            +              target="_blank">AxiDraw V3 demo video</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I just graduated from Ryerson University's New Media program. Coming from 4 years of coding and making robots, I decided to take a break and play with some more traditional forms of art—while still coding and playing with robots.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I first started using p5.js at <a href="https://itp.nyu.edu/camp2019/"
            +            target="_blank">NYU ITP Camp</a>! After using <a
            +            href="https://processing.org/" target="_blank">Processing</a> for many years, I wanted to try something new.
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>I used p5.js in this project to generate the sine wave and lerp (linear interpolation) formulas and display the visuals in the <a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a>. I then used a feature in my code that exported my programmed graphic into an <a
            +            href="https://developer.mozilla.org/en-US/docs/Web/SVG"
            +            target="_blank">SVG</a> file. I needed an SVG file to give to the plotter—an <a
            +            href="https://shop.evilmadscientist.com/productsmenu/846" target="_blank">AxiDraw
            +            V3</a>—so that it understood where to draw the lines that I programmed. I sent this information to the plotter with a program called <a href="https://inkscape.org/"
            +            target="_blank">Inkscape</a>!</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>
            +          <code><a href="https://p5js.org/reference/#/p5/lerp" target="_blank">lerp()</a></code> because lines are fun and "lerp" is a fun word to say!
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>It was my first time using p5.js, Inkscape, and a plotter! I really benefited from the people around me who had used p5 before, as well as online guides and forums.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/gandyworks/"
            +            target="_blank">@gandyworks</a> on Instagram—super cool analog plotter stuff.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://ronicantor.com/" target="_blank">ronicantor.com</a>
            +          <br><a href="https://www.instagram.com/roni.cantor/"
            +            target="_blank">@roni.cantor</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/showcase/index.html b/dist/ko/showcase/index.html
            new file mode 100644
            index 0000000000..28ba122f46
            --- /dev/null
            +++ b/dist/ko/showcase/index.html
            @@ -0,0 +1,245 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main  id="content" class="column-span">
            +    <section class="showcase-intro">
            +      <h1>쇼케이스</h1>
            +      
            +      <p>쇼케이스는 2019년 강예은 <a href="https://ashleykang.dev" target="_blank">Ashley Kang</a>
            +      이 제작, 기획하였으며, 2020년에는 코니 리우 <a href="https://katiechan.cargo.site/" target="_blank">Katie Chan</a>.
            +      가 새로운 기획을 선보입니다. 쇼케이스는 p5.js를 보다 흥미진진하고 포용적으로 만든 창작물, 학습물, 오픈 소스 사례들을 기쁘게 소개합니다. 이렇게 우리는 함께 커뮤니티를 만들어 나가는게 아닐까요?:) 2019년 여름, 우리는 p5.js 기반의 다양한 프로젝트들을 소개한 바 있습니다.</p>
            +      <p>현재 2020년 여름 쇼케이스를 모집중입니다. 아래의 버튼을 눌러 자신 또는 타인의 p5.js 작업을 추천해주세요!</p>
            +
            +      <span id="nominate" class="nominate"><a href="https://forms.gle/ETP7kjAocBcfGTuj8" target="_blank">프로젝트 추천하기</a></span>
            +    </section>
            +
            +    <section class="showcase-featured">
            +      <h2 class="featuring">선정 프로젝트</h2>
            +
            +      <div class="left-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/roni-cantor.html">각도기 드로잉 프로그램(Programmed Plotter Drawings)</a></h3>
            +          <p class="credit">Roni Cantor</p>
            +          <a href="./featuring/roni-cantor.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg" 
            +            alt="A drawing of a sine wave lerp plotted on black paper using an AxiDraw V3 and a white gel pen.">
            +          </a>
            +          <p class="description">p5.js로 제작한 사인파(Sine wave)와 선형 보간(lerp)으로, 실물 각도기와 펜과 연결되어 드로잉하고, SVG 파일로 내보내기 가능.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5/lerp">lerp()</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/daein-chung.html">Chillin'</a></h3>
            +          <p class="credit">정대인(Dae In Chung)</p>
            +          <a href="./featuring/daein-chung.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/daein-chung/daein-chung_chillin.png" 
            +              alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device. 
            +              At the top, there is a text input box to enter a message and download your own poster">
            +          </a>
            +          <p class="description">모바일 기기의 모션 센서와 p5.js를 활용한 인터랙티브 타이포그래픽 포스터</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://brm.io/matter-js/">matter.js</a></li>
            +            <li><a class="tag" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">p5 WebGL</a></li>
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5.Camera">p5.Camera</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/casey-louise.html">p5.js 셰이더(Shaders)</a></h3>
            +          <p class="credit">캐시 콘치나(Casey Conchinha), 루이스 레셀(Louise Lessél)</p>
            +          <a href="./featuring/casey-louise.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/casey-louise/casey-louise_p5js-shaders.png" 
            +              alt="A screenshot of the Introduction page of the p5.js Shaders guide website">
            +          </a>
            +          <p class="description">셰이더(Shaders)란 무엇이고, 이를 p5.js에서 왜, 그리고 어떻게 사용하는지 배울 수 있는 자료.</p>
            +          <ul class="project-tags">
            +         </ul>
            +        </div>
            +      </div>
            +
            +      <div class="right-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/phuong-ngo.html">날아라 아이리(Airi Flies)</a></h3>
            +          <p class="credit">Phuong Ngo</p>
            +          <a href="./featuring/phuong-ngo.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" 
            +              alt="A screenshot of the instructions and scoreboard for the online game Airi Flies">
            +          </a>
            +          <p class="description">p5.play로 제작된 게임으로, PEW라고 말해 아이리(Airi)가 날 수 있도록 돕는다. 사용자들이 자신의 안전 지대를 벗어난 곳에서도 행동, 외모, 발언에 상관없이 자신감을 갖게하고자 하는 취지에서 제작.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="http://molleindustria.github.io/p5.play/">p5.play</a></li>
            +            <li><a class="tag" href="https://ml5js.org/">ml5.js</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +          <h3 class="title"><a href="./featuring/qianqian-ye.html">Qtv</a></h3>
            +          <p class="credit">치안치안 예(Qianqian Ye)</p>
            +          <a href="./featuring/qianqian-ye.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" 
            +              alt="A screenshot of a Qtv video (Guest Talk #1) featuring Chinese womxn designers and artists Kaikai and Cheng Xu">
            +          </a>
            +          <p class="description">입문자를 위한 p5.js 튜토리얼을 포함하여, 코딩, 예술, 그리고 기술에 대해 다루는 1분 길이의 중국어 영상 채널들. 유투브, 인스타그램, 비리비리(Bilibili), 틱톡(TikTok)에서 확인 가능.</p>
            +          <ul class="project-tags">
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/moon-xin.html">움직이는 반응형 포스터(Moving Responsive Posters)</a></h3>
            +          <p class="credit">장문(Moon Jang), 씬 씬(Xin Xin), 그리고 학생들</p>
            +          <a href="./featuring/moon-xin.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png" 
            +              alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right">
            +          </a>
            +          <p class="description">브라우저 기반의 움직이는 포스터로, 그래픽 시스템과 변형 메소드, 그리고 p5.js를 사용하여 8자 미만 단어가 내포하는 바를 표현. 조지아 대학교(University of Georgia)의 그래픽 디자인 과정인 'Visual Narrative Systems'의 수강생들이 디자인.</p>
            +          <ul class="project-tags">
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/rect">rect()</a></li>
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/translate">translate()</a></li>
            +          </ul>
            +        </div>
            +      </div>
            +    </section>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/ko/teach/index.html b/dist/ko/teach/index.html
            new file mode 100644
            index 0000000000..018fea8a91
            --- /dev/null
            +++ b/dist/ko/teach/index.html
            @@ -0,0 +1,856 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="ko">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">teach | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">건너뛰기</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">언어 설정</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/ko/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="teach-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">사이트 둘러보기</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/ko/">홈</a></li>
            +        <li><a href="https://editor.p5js.org">에디터</a></li>
            +        <li><a href="/ko/download/">다운로드</a></li>
            +        <li><a href="/ko/download/support.html">후원하기</a></li>
            +        <li><a href="/ko/get-started/">시작하기</a></li>
            +        <li><a href="/ko/reference/">레퍼런스</a></li>
            +        <li><a href="/ko/libraries/">라이브러리</a></li>
            +        <li><a href="/ko/learn/">배우기</a></li>
            +        <li><a href="/ko/teach/">가르치기</a></li>
            +        <li><a href="/ko/examples/">예제</a></li>
            +        <li><a href="/ko/books/">출판물</a></li>
            +        <li><a href="/ko/community/">커뮤니티</a></li>
            +        <li><a href="https://showcase.p5js.org">쇼케이스</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">포럼</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            + <main id="content" class="column-span">
            +  	<section class= "teach-intro">
            +      <h1>가르치기</h1>
            +
            +	      <p>모든 교육은 고유의 목표, 메시지, 조건, 환경을 담습니다. 이 페이지는 p5.js 워크숍, 강의, 교보재 아카이브를 통해 전세계 p5 교육자 및 학습자들을 연결합니다. 여러분의 p5 교육 경험을 <a href="" onclick= "window.open('https://docs.google.com/forms/d/e/1FAIpQLSei8yHX2BROMnMQeZT_tsSXJOH13TPRG6CB4GVHH1oL1hzkZg/viewform?usp=sf_link', '_blank')">이 링크에서 공유 또는 추천</a> 하세요!</p>
            +						
            +    </section>
            +
            +	<section>
            +
            +		<div id="resources"></div>
            +			<h2 class = "heading">p5 교육 자료</h2> 
            +			
            +			<div class="search-filter"><input type="checkbox"><label> 검색 필터 &#x2192;</label></div>
            +
            +     		<!-- search-results -->
            +
            +     		<div class="filter-panel">
            +
            +							
            +				<ul class="filters" id="filters">
            +
            +					<li><p class = "filter-title">&#x1F33A; 다양성 & 포용 : </p></li>
            +					<li><input type="checkbox" id="gender" value="gender"><label for="gender">젠더</label></li>
            +					<li><input type="checkbox" id="race-ethnicity" value="race-ethnicity"><label for="race-ethnicity">인종 & 민족</label></li>
            +					<li><input type="checkbox" id="language" value="language"><label for="language">언어</label></li>
            +					<li><input type="checkbox" id="neuro-type" value="neuro-type"><label for="neuro-type">뉴로타입</label></li>
            +					<li><input type="checkbox" id="ability" value="ability"><label for="ability">장애</label></li>
            +					<li><input type="checkbox" id="class" value="class"><label for="class">계급</label></li>
            +					<li><input type="checkbox" id="religion" value="religion"><label for="religion">종교</label></li>
            +					<li><input type="checkbox" id="subculture" value="subculture"><label for="subculture">(하위-)문화</label></li>
            +					<li><input type="checkbox" id="political-opinion" value="political-opinion"><label for="political-opinion">정치적 견해</label></li>
            +					<li><input type="checkbox" id="age" value="age"><label for="age">나이</label></li>
            +					<li><input type="checkbox" id="skill-level" value="skill-level"><label for="skill-level">기술적 숙련도</label></li>
            +					<li><input type="checkbox" id="occupation" value="occupation"><label for="occupation">직업</label></li>
            +					<li><input type="checkbox" id="noCodeSnobs" value="noCodeSnobs"><label for="noCodeSnobs">#noCodeSnobs</label></li>
            +					<li><input type="checkbox" id="newKidLove" value="newKidLove"><label for="newKidLove">#newKidLove</label></li>
            +					<li><input type="checkbox" id="unassumeCore" value="unassumeCore"><label for="unassumeCore">#unassumeCore</label></li>
            +					<li><input type="checkbox" id="BlackLivesMatter" value="BlackLivesMatter"><label for="BlackLivesMatter">#BlackLivesMatter</label></li>
            +							
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CD; 장소 : </p></li>
            +
            +					<li><input type="checkbox" id="africa" value="africa"><label for="africa">아프리카</label></li>
            +					<li><input type="checkbox" id="asia" value="asia"><label for="asia">아시아</label></li>
            +					<li><input type="checkbox" id="europe" value="europe"><label for="europe">유럽</label></li>
            +					<li><input type="checkbox" id="north-america" value="north-america"><label for="north-america">북미</label></li>
            +					<li><input type="checkbox" id="oceania" value="oceania"><label for="oceania">오세아니아</label></li>
            +					<li><input type="checkbox" id="south-america" value="south-america"><label for="south-america">남미</label></li>
            +					<li><input type="checkbox" id="virtual-online" value="virtual-online"><label for="virtual-online">가상-온라인  &#x1F310;</label></li>
            +
            +
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4C5; 년도 : </p></li>
            +					<li><input type="checkbox" id="2014" value="2014"><label for="2014">~2014</label></li>
            +					<li><input type="checkbox" id="2015" value="2015"><label for="2015">2015</label></li>
            +					<li><input type="checkbox" id="2016" value="2016"><label for="2016">2016</label></li>
            +					<li><input type="checkbox" id="2017" value="2017"><label for="2017">2017</label></li>
            +					<li><input type="checkbox" id="2018" value="2018"><label for="2018">2018</label></li>
            +					<li><input type="checkbox" id="2019" value="2019"><label for="2019">2019</label></li>
            +					<li><input type="checkbox" id="2020" value="2020"><label for="2020">2020</label></li>
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CA; 난이도 : </p></li>
            +					<li><input type="checkbox" id="elementary" value="elementary"><label for="elementary">초급</label></li>
            +					<li><input type="checkbox" id="intermediate" value="intermediate"><label for="intermediate">중급</label></li>
            +					<li><input type="checkbox" id="advanced" value="advanced"><label for="advanced">고급</label></li>
            +				 </ul>
            +
            +						  <br>
            +								
            +
            +			</div>
            +												
            +			<div class = "results-wrapper">
            +
            +						
            +				<div class="results" id="search-results">
            +					<ul>
            +				  		<li class="case-list" data-category="2019 europe gender race-ethnicity age skill-level BlackLivesMatter advanced"><a href="#case1" class="caseBtn" >"p5.js à l'Ubuntu Party!", Basile Pesin</a></li>
            +
            +				  		 <li class="case-list" data-category="2020 asia age skill-level occupation elementary advanced"><a href="#case2" class="caseBtn">"Making The Thing that Makes the Thing: Exploring Generative Art &#x0026; Design with p5.js", Priti Pandurangan &#x0026; Ajith Ranka</a></li>
            +
            +						  <li class="case-list" data-category="2016 2019 2020 elementary intermediate advanced north-america gender race-ethnicity language neuro-type ability subculture occupation north-america"><a href="#case3" class="caseBtn">CC Fest (Creative Coding Festival), Saber</a></li>
            +
            +						  <li class="case-list" data-category="2018 virtual-online south-america gender race-ethnicity language neuro-type religion subculture age noCodeSnobs newKidLove unassumeCore elementary intermediate advanced"><a href="#case4" class="caseBtn" >"Taller Introducci&#x00F3;n a la Programaci&#x00F3;n Creativa con p5.js", Aar&#x00F3;n Montoya-Moraga</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america gender race-ethnicity class subculture age skill-level elementary"><a href="#case5" class="caseBtn" >"Introduction to Generative Drawing", Adam Herst</a></li>
            +
            +						  <li class="case-list" data-category="2020 asia virtual-online gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation elementary"><a href="#case6" class="caseBtn" >Open Lecture "Creative Coding: 2020", Shunsuke Takawo</a></li>
            +
            +
            +						  <li class="case-list" data-category="2020 asia gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation intermediate"><a href="#case7" class="caseBtn" >"Creative Coding for Static Graphics", Shunsuke Takawo</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america virtual-online race-ethnicity language subculture skill-level"><a href="#case8" class="caseBtn" >"Generative Typography", Dae In Chung</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity language age skill-level occupation noCodeSnobs new unassumeCore BlackLivesMatter elementary intermediate"><a href="#case9" class="caseBtn" >"Machine Learning for the Web", Yining Shi</a></li>
            +
            +
            +						  <li class="case-list" data-category="europe virtual-online gender elementary"><a href="#case10" class="caseBtn" >"Introduction to p5.js and JavaScript", Nico Reski</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity skill-level occupation"><a href="#case11" class="caseBtn">"Digital Weaving &#x0026; Physical Computing Workshop Series", Qianqian Ye &#x0026; Evelyn Masso</a></li>
            +
            +						  <li class="case-list" data-category="2015 2020 north-america asia gender race-ethnicity language neuro-type ability class skill-level"><a href="#case12" class="caseBtn">"Signing Coders", Taeyoon Choi</a></li>
            +	    			</ul>
            +						<br>
            +				</div> 
            +			</div>
            +						
            +
            +						
            +
            +		<!--modal box section-->
            +		
            +			<!--modal boxes-->
            +
            +			<div id="caseModals" class="modal">
            +
            +				<!--modal box #1-->
            +
            +				  <div class="modal-content" id="case1"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>p5.js à l'Ubuntu Party!</span></li>
            +				        	<li class = "case"><p class="lead-name">Basile Pesin</p></li>
            +
            +				          	<li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">장소 & 일시<p><a href="https://ubuntu-paris.org/">2020 우분투 행사(Ubuntu Party), </a>Cité des Sciences et de l'Industrie, Paris, France</p></li> 
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>Any age, including children and parents, young and older adults.
            +				            </p></li>		         
            +
            +				            <li class = "clear"></li>  				
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>To introduce a new public to programming through fun and compelling examples. </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>Method: in-person workshop, 1 hour per session, with different participant each times. The students were using (Ubuntu) machines with the p5.js web editor. I was teaching using a video projector as well as a board.</p><p>Materials: The exercises I gave where accessible through p5.js web-editor links available in <a href = "https://vertmo.github.io/ubuntu-party-p5/">GitHub</a>.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label><label>인종 & 민족</label><label>나이</label><label>기술적 숙련도</label><label>#BlackLivesMatter</label>
            +				            </li>
            +		             
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				<!--modal box #2-->
            +	
            +				  <div class="modal-content" id="case2"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Making The Thing that Makes the Thing: Exploring Generative Art & Design with p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Priti Pandurangan & Ajith Ranka</p></li>
            +				        	
            +				        	<li class = "clear"></li>
            +             				<li class = "clear"></li>
            +             				<li class = "case"><img src="https://drive.google.com/uc?id=1udID-B1qADY7QxDkYkAh6ZYX7D8BfrnD" alt="A group of participants collaborating to create some designs using the p5.js web editor on their laptops."></li>
            +
            +				            <li class = "case"><p class = "subtitle">장소 & 일시<p>&#x1F4CD; National Institute of Design, Bangalore</p><p>&#x1F4C5; 2020 February 8, 2:30-4:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Priti: Intermediate & Ajith: Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>To explore generative art &#x0026; design and recreate some classical works with p5.js. </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>Methods: In-person, collaborative, hands-on workshop.</p><p>Materials: <a href="https://musingswithcode.studio/generative-design-workshop">course page </a> linking to sketches on the p5 editor, <a href="https://musingswithcode.studio/generative-design-workshop/explainers">interactive reference guide </a>to p5 basics</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label><label>기술적 숙련도</label><label>직업</label></li>			    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +				  <!--modal box #3-->
            +	
            +				  <div class="modal-content" id="case3"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>CC Fest (Creative Coding Festival)</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Saber</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Love p5.js. It has meant so much to me, my students, and this community."</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">장소 & 일시</p><p>&#x1F4CD; New York, Los Angeles, San Francisco, Virtual-Online &#x1F310;</p><p>&#x1F4C5; Twice a year in NYC for four years; once a year in LA for three years; once a year in SF for two years; now virtual</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>To build a teacher and student community around p5 for middle and high school.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>A half-day of workshop led by volunteer teachers. We saw lots of different methods and materials. Most used some sort of slides or documentation, some live coding using an editor, with work time for participant to remix.</p><p>&#x1F517; <a href="https://http://ccfest.rocks/lessons">CC Fest Lessons page</a> for teaching materials</p><p>&#x1F4F8; <a href="http://ccfest.rocks/pictures">More photos</a></li>
            +
            +              				<!--<li class = "case"><iframe src="http://ccfest.rocks/pictures" height= "200" alt="Pictures of CC Fest"></iframe></li>-->
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label><label>인종 & 민족</label><label>언어</label><label>뉴로타입</label><label>장애</label><label>(하위-)문화</label><label>직업</label></li>	
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #4-->
            +	
            +				  <div class="modal-content" id="case4"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Taller Introducción a la Programación Creativa con p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Aarón Montoya-Moraga</p></li>
            +
            +				        	<li class = "case"><p class = speech>"p5.js is my happy place &#x1F495; "</p></li>
            +
            +				        	<li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://miro.medium.com/max/1000/1*OIn_NKGuKyto9-_h6CAmmw.jpeg" alt="A group of 20 people sitting on a large shared table with their laptops looking at a projected screen."></li>
            +
            +				            <li class = "case"><p class = "subtitle">장소 & 일시</p><p>&#x1F4CD;  PlusCode Media Arts Festival, Buenos Aires, Argentina & Virtual-Online  &#x1F310;</p><p>&#x1F4C5; 2018 November 14, 3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>I had around 16 students in the workshop, and a team including 3 people from the PlusCode festival, and one person at the venue.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Elementary, Intermediate, Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>Introduction to beginners and artists of graphic web programming and open source, using p5.js, in Spanish :)</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>I used the material on this <a href="https://github.com/montoyamoraga/workshop-p5js-pluscode-2018">GitHub repo</a>, we used the p5.js web editor, we had a three hour long workshop</p><p>&#x1F517; <a href="https://medium.com/processing-foundation/code-electronic-art-festival-2018-argentina-803d3ca8092c">+CODE electronic art festival 2018, Argentina</a>, Medium</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label><label>인종 & 민족</label><label>언어</label><label>뉴로타입</label><label>종교</label><label>(하위-)문화</label><label>나이</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label></li>
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				  <!--modal box #5-->
            +	
            +				  <div class="modal-content" id="case5"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to Generative Drawing</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Adam Herst</p></li>
            +
            +				        	<li class = "case"><p class = speech>"My greatest source of uncertainty in developing the workshop was whether it was trying to teach art to programmers or to teach programming to artists."</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">장소 & 일시</p><p>&#x1F4CD; <a href="https://interaccess.org/studio">Inter/Access</a> (artist-run centre), Toronto, Ontario, Canada</p><p>In-person with a self-paced workbook for remote work</p><p>&#x1F4C5; 2020 February 12, 7PM-9PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>15 artists
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>To introduce p5.js to artists with little or no programming experience and to suggest one way an analogue practice can migrate to a digital form.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD;방법 & 교보재</p><p>A printed workbook with activities that used the p5.js web editor to show how translate an physical drawing into a digital drawing.</p><p>&#x1F517;<a href="https://interaccess.org/event/2019/processing-community-day-generative-drawing">Processing Community Day 2019: Generative Drawing at Inter/Access</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Letter PDF</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Booklet PDF</a></p></li>		
            +
            +				    		<li class = "clear"></li>
            +				        	<li class = "case"><label>젠더</label><label>인종 & 민족</label><label>계급</label><label>(하위-)문화</label><label>나이</label><label>기술적 숙련도</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #6-->
            +	
            +				  <div class="modal-content" id="case6"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Open Lecture, Creative Coding: 2020</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I love p5.js because it's so easy to read and write code in p5.js. Coding in your everyday life!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				          	<li class = "clear"></li>	
            +				          	<li class = "case"><img src="https://lh3.googleusercontent.com/pw/ACtC-3eYswa6tJH5pvfvvAAfXQJO71ncsdgpwDBvbPAL-qcwnLkkpuoAVpggOb2-LYSLqo0Htd8cgnv5i8yLJg6Wh7J_rW2MMy6y8XZRznRByjj2mGJHf8XFmDI-8W6mH7urrEQC2tyUMF1HWaamLTNBqmIyeQ=w1560-h878-no?authuser=0" alt="A table on which there is a laptop, some sheets of papers, colorful pens and two automatic machines drawing something with a pen on a sheet."></li>
            +
            +				            <li class = "case"><p class = "subtitle">장소 & 일시</p><p>&#x1F4CD; Kyoto University of Art and Design, Kyoto, Japan & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2020 March 16-18, 1-7 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>Students of Kyoto University of Art and Design, and anyone.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>Making code as a tool for artistic expression.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/Day1-1-p5.js-i15dvmUETr4ef1xnydzru">Syllabus</a><p>&#x1F517; <a href="https://youtu.be/aS5CvADPdk0">Day 1</a>, <a href="https://youtu.be/ZCO-8CubifI">Day 2</a>, <a href="https://youtu.be/nbcckC5iwIcsyllabus">Day 3</a>, YouTube</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label><label>인종 & 민족</label><label>언어</label><label>뉴로타입</label><label>장애</label><label>계급</label><label>종교</label><label>(하위-)문화</label><label>정치적 견해</label><label>나이</label><label>기술적 숙련도</label><label>직업</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #7-->
            +	
            +				  <div class="modal-content" id="case7"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Creative Coding for Static Graphics</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Coding in p5.js is a lot of fun. If you haven't started yet, I encourage you to give it a try!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://uc6d9323e0272069edcf30e9c501.previews.dropboxusercontent.com/p/thumb/AA5dvRUhxkQ9wLU6mHcrEmLvXnV7gbapPG2PvVf5K8K9ktlC59RCtvbSCP7YfEgPcFtnsgQekujWSD8iEfc6UT2pouzLdZUElblXhh9wg_b2UKDU-OO1u8VaiuC91g73tQX9S9mTHIgvm4h_Jw9-P4F6-iyjqBz57CvFWhilM5CpNbiPIjVRX6NsMkSYA3IexYreShT6Bt2hOWnorsocCsaafJiAd3cZbplWnGiuZmCn5R7BJ4u770YRjqX-AKh6AaoOb3kZHwBBnPQSU7zxiHqZbrWirjwLprw5D5UKW4bMI6We85Yn8cDPlJ6CktIqwpepAhdRi7scaxLxGnpIE4XjnoxK6T1jHkWZXGkvPplV1qlvrC7qz2jTY1_cULKcAcV8F-I-xvAL5I0n3rRHCZqr/p.jpeg?fv_content=true&size_mode=5" alt=""></li>
            +
            +				            <li class = "case"><p class = "subtitle">장소 & 일시</p><p>&#x1F4CD; FabCafe MTRL, Tokyo, Japan</p><p>&#x1F4C5; 2019 September 15, 4-7 PM </p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>Anyone who wants to try coding in p5.js.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>To code from the graphic design's perspective.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/--A6IUdC5pD_0QfbWt1PQ5u~PiAg-Fk8qxFWjaJWeH1cAc8FT0">Syllabus & Material</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label><label>인종 & 민족</label><label>언어</label><label>뉴로타입</label><label>장애</label><label>계급</label><label>종교</label><label>(하위-)문화</label><label>정치적 견해</label><label>나이</label><label>기술적 숙련도</label><label>직업</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #8-->
            +	
            +				  <div class="modal-content" id="case8"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Generative Typography</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Dae In Chung</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://drive.google.com/uc?id=1TqcLurMLFioe8EcoJGtdK9_gs9bZ5odW" alt="A image with black background displaying the letter 'b' in 5 different styles along with a menu with various styling options to choose."></li>
            +
            +            	            <li class = "case"><p class = "subtitle">장소 & 일시</p><p>&#x1F4CD; Baltimore, Maryland, USA & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2019 January 21 - May 08, every Wednesday, 4-10 PM</p></li>  
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>14 undergrads and grad students who had little to no experience in coding.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>Experiment with typographic forms and structures through computation.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>Methods: online/offline lectures and critiques.</p><p>Materials: p5js online editor, Github, youtube tutorials.</p><p>&#x1F517; <a href="https://drive.google.com/drive/folders/15aFXijbqworOoLpc0fD283YOgi7UIHMA?usp=sharing">Works of participants</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>인종 & 민족</label><label>언어</label><label>(하위-)문화</label><label>기술적 숙련도</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +
            +				  <!--modal box #9-->
            +	
            +				  <div class="modal-content" id="case9"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Machine Learning for the Web</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Yining Shi</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://drive.google.com/uc?id=1pO3s4lraBwtLcZoCIeHGVncuwtzHqN6o" alt="A group of 16 people sitting around tables with their laptops, mobile phones and some other accessories, facing towards a large television screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">장소 & 일시</p><p>&#x1F4CD; ITP, NYU, 370 Jay St, Brooklyn, NY 11201, USA</p><p>&#x1F4C5;2019 March 09 - October 12, every Tuesday, 6:30-9:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>Students at Interactive Telecommunications Program, New York University. 16 people.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Elementary, Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>The goal of this class is to learn and understand common machine learning techniques and apply them to generate creative outputs in the browser using ml5.js and p5.js.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>This class is a mix of lectures, coding sessions, group discussions, and presentations. I used <a href="https://github.com/yining1023/machine-learning-for-the-web">GitHub</a> to host class syllabus and all the coding materials, Google Slides for lectures and p5.js Web Editor for live coding sessions. Every week, there were one-on-one office hours to talk about any difficulties of coming up with an idea for the homework or any coding changes.</p><p>Methods: online/offline lectures and critiques.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label><label>인종 & 민족</label><label>언어</label><label>나이</label><label>기술적 숙련도</label><label>직업</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label><label>#BlackLivesMatter</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #10-->
            +	
            +				  <div class="modal-content" id="case10"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to p5.js and JavaScript</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Nico Reski</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +              			    <li class = "case"><p class = "subtitle">장소 & 일시<p>&#x1F4CD; Currently available as self-study at own pace with accompanying slides, linked below.</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Beginner, Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>Introduce learners (potentially with no coding experiences at all) to the very basics of p5.js (and JavaScript), in order to encourage creative coding and enable them to pursue own projects in a safe environment.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>p5.js source code (for the introductory project), JavaScript source code (illustrating some basic JavaScript functionalities), accompanying slides in .pdf format, all hosted publicly on GitHub. </p><p>&#x1F517; <a href="https://reski.nicoversity.com/ws_cc_p5js_introduction.html">Overview</a> of the workshop and its contents (including all links to the material hosted on GitHub) on my academic webpage.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #11-->
            +	
            +				  <div class="modal-content" id="case11"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Digital Weaving & Physical Computing Workshop Series</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Qianqian Ye & Evelyn Masso</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +				            <li class = "case"><img src="https://drive.google.com/uc?id=1QXtrew8S2YQ-_6R0H1FhwiEJj9_LLcpU" alt="This image is divided in two parts. The left part shows a group of 15 women sitting on chairs with their laptops and looking at a presentor who is explaining a code on a projected screen. The right part of the image shows a person learning weaving using a physical pattern and a weaving tool."></li>
            +
            +
            +              			    <li class = "case"><p class = "subtitle">장소 & 일시</p><p>&#x1F4CD; Womens Center for Creative Work (WCCW), Los Angeles, CA, US</p><p>&#x1F4C5; 2019 October 19 - November 02, every Saturday 3-6 PM</p></li>  		
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>15 women and non-binary artists, designer, makers, programers. </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Elementary
            +				            </p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>Over the course of three workshops, we will draw and create patterns using p5.js, an open-source graphical library; we will learn and apply computational concepts to transform patterns and finally, we will bring a weaving to life with electronic microcontrollers.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>Methods: small team session</p><p>Materials: slides, p5.js web editor, pen and paper to draw pattern, physical pattern weaving tool.</p><p>&#x1F517; <a href="https://docs.google.com/presentation/d/1gJ67aKVGydSNoeUraS7U_QevcnOuxnSFQ_4640Qlifo/edit?usp=sharing">Workshop Slide #1</a>, <a href="https://docs.google.com/presentation/d/1nuje9-j_o5HbCoxXR_EJhAYmSEjTQOkAHmBsuKRlwwA/edit?usp=sharing">Workshop Slide #2</a></p><p>&#x1F517; <a href="https://womenscenterforcreativework.com/events/digital-weaving-physical-computing/">Workshop Information</a> on WCCW website.</p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label><label>인종 & 민족</label><label>기술적 숙련도</label><label>직업</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +  				  <!--modal box #12-->
            +	
            +				  <div class="modal-content" id="case12"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Signing Coders</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Taeyoon Choi</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I'm working on a new series of coding class for Disabled students in South Korea. I'm researching about the pedagogy and translation. I plan to hold workshops in December 2020. The project is supported by the Open Society Foundation Human Rights Initiative and Korea Disability Arts & Culture Center."</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><img src="http://taeyoonchoi.com/wp-content/uploads/2016/04/day1-7852-768x512.jpg" alt="Two volunteers explaining concepts using a white board and a screen to a bunch of deaf and hard of hearing students, each student facing a computer screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">장소 & 일시</p><p>&#x1F4CD;  WRIC, New York City, USA & Seoul Museum of Art, Seoul, South Korea.</p><p>5 Sessions, each 2~3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">참여자</p><p>Deaf and Hard of Hearing students age 10~50 who live in NYC.
            +				            </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">난이도</p><p>Elementary</p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">목표</p><p>To help Deaf and Hard of Hearing students learn about computer programming through playful exercises. To make ASL tutorial of basic coding concepts.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; 방법 & 교보재</p><p>We used p5.js Web editor and code examples on the website. We also used dice, playing cards and various paper tools to help students learn about coding concepts.</p><p>&#x1F517; <a href="http://taeyoonchoi.com/soft-care/signing-coders/">Syllabus & Material</a></p><p>&#x1F4F8; <a href="http://taeyoonchoi.com/soft-care/signing-coders/signing-coders-1/">More photos</a></p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>젠더</label><label>인종 & 민족</label><label>언어</label><label>뉴로타입</label><label>장애</label><label>계급</label><label>기술적 숙련도</label></li>
            +				         
            +
            +
            +				            </ul>
            +				        
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +			</div> <!--modal boxes end-->
            +
            +			
            +			
            +
            +	</section>
            +
            +
            +	<!--modal-->
            +
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">크레딧</h2>
            +      <p>
            +        p5.js는 현재 치안치안 예<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & 에블린 마소<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> 가 리드하고, 로렌 맥카시 <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a> 가 창안하였습니다. p5.js는 프로세싱 재단 <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> 과 <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a> 의 지원으로, 협력자 커뮤니티와 함께 개발되었습니다. 아이덴티티 및 그래픽 디자인: 제럴 존슨 <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/ko/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +<!--jquery script-->
            +
            +<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
            +<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
            +<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
            +
            +
            +<!--filter search-->
            +
            +
            +<script>
            +    $("#filters :checkbox").click(function() {
            +
            +       var re = new RegExp($("#filters :checkbox:checked").map(function() {
            +                              return this.value;
            +                           }).get().join("|") ); //.join("|")
            +       $(".case-list").each(function() {
            +          var $this = $(this);
            +          $this[re.source!="" && re.test($this.attr("data-category")) ? "fadeIn" : "hide"]();
            +       });
            +    });
            +</script>
            +
            +
            +<!--modal box-->
            +
            +
            +<script>
            +$(document).on('click','.caseBtn',function(){
            +	var openModal =  $(this).attr('href');
            +	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +	
            +	$('#caseModals').fadeIn();
            +	$(openModal).fadeIn();
            +  return false;
            +});
            +
            +$("body" ).on( "click",".close", function() {
            +  	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +});
            +
            +</script>
            +
            +<!--search accordion menu-->
            +
            +<script>
            +
            +
            +var acc = document.getElementsByClassName("search-filter");
            +var i;
            +
            +for (i = 0; i < acc.length; i++) {
            +  acc[i].addEventListener("click", function() {
            +    this.classList.toggle("active");
            +    var panel = this.nextElementSibling;
            +    if (panel.style.maxHeight) {
            +      panel.style.maxHeight = null;
            +    } else {
            +      panel.style.maxHeight = panel.scrollHeight + "px";
            +    } 
            +
            +  });
            +}
            +</script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/ko/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/basics.html b/dist/learn/basics.html
            new file mode 100644
            index 0000000000..276ff77d3f
            --- /dev/null
            +++ b/dist/learn/basics.html
            @@ -0,0 +1,348 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +<style>
            +img {
            +  width: 50%;
            +}
            +</style>
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Basics of Drawing</h1>
            +
            +      <h2>Introduction</h2>
            +      <p>
            +      Today we are going to be learning how to write computer code using a tool called <a href='http://p5js.org' target=_blank>p5</a>. Code is a set of instructions for the computer, telling it something to do. In our case, we will tell it to make a scene with shapes and colors.
            +      </p>
            +
            +
            +      <h2>First Sketch</h2>
            +      <p>
            +      When you open p5, your first sketch will look like this. There are two parts: setup and draw. Inside the curly brackets after setup and draw we will add code to create a drawing.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +
            +}
            +      </script>
            +
            +      <h2>background(red, green, blue)</h2>
            +      <p>
            +      background() sets the background color of your drawing. You give it three numbers that represent the amount of red, green, and blue you want mixed into the background. The numbers range from 0-255.
            +      <span class='try'>Try changing the numbers inside the parentheses to see what happens.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +
            +      <h2>createCanvas(width, height)</h2>
            +      <p>
            +      createCanvas() sets the size of the drawing canvas. By default it is 100x100. You give it two numbers that represent the width and the height that you want your canvas to be.
            +      <span class='try'>Try making your canvas different sizes by changing the width and height.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100)
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +      <h2>line(x1, y1, x2, y2)</h2>
            +      <p>
            +      line() draws a line on your canvas. You give it four numbers – the x and y position of one end, and the x and y position of the other end.<br>
            +      <img src='../assets/learn/basics/line.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 200, 255)
            +  line(10, 10, 200, 200)
            +}
            +      </script>
            +
            +      <h2>rect(x, y, width, height)</h2>
            +      <p>
            +      rect() draws a rectangle on your canvas. You give it four numbers – the x position, the y position, the width, and the height. For a rectangle, you give it the x,y position of the top left corner.<br>
            +      <img src='../assets/learn/basics/rect.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(55, 100, 255)
            +  rect(10, 10, 50, 200)
            +}
            +      </script>
            +
            +      <h2>ellipse(x, y, width, height)</h2>
            +      <p>
            +      To draw a shape, think of your canvas like a piece of graph paper. However, square (0, 0) is in the top left.
            +      <br>
            +      <img src='../assets/learn/basics/graph.svg'>
            +      ellipse() draws an ellipse on your canvas. You give it four numbers – the x position, the y position, the width, and the height.<br>
            +      <img src='../assets/learn/basics/ellipse.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 0, 255)
            +  ellipse(150, 150, 100, 200)
            +}
            +      </script>
            +
            +      <h2>fill(red, green, blue)</h2>
            +      <p>You can set the color of your shapes by using fill(). You give it three numbers – the red, green, and blue mixture you want, just like background.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>stroke(red, green, blue)</h2>
            +      <p>You can set the outline color of your shapes by using stroke(). You give it three numbers – the red, green, and blue mixture you want, just like fill() and background().
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  stroke(0, 150, 0)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>strokeWeight(weight)</h2>
            +      <p>You can set the thickness of the outline for your shapes by using strokeWeight(). The default stroke weight is 1.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  strokeWeight(10)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>mouseX, mouseY</h2>
            +      <p>mouseX and mouseY can be used to get the current position of your mouse. They are called <b>variables</b>. You can replace a number in your code with mouseX or mouseY and that number will change as you move your mouse.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +      <h2>random(max)</h2>
            +      <p>random() will choose a random number for you, anywhere from 0 - max.</p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(random(255), random(255), random(255))
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +
            +      <h2>Links</h2>
            +      <p><a href='http://p5js.org/reference' target=_blank>Reference</a> – available p5.js variables and functions<br>
            +      <a href='http://p5js.org/examples' target=_blank>Examples</a> – more complicated code examples</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/color.html b/dist/learn/color.html
            new file mode 100644
            index 0000000000..7d8c4cd7e4
            --- /dev/null
            +++ b/dist/learn/color.html
            @@ -0,0 +1,293 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">This tutorial is from the book Learning Processing by Daniel Shiffman, published by Morgan Kaufmann, © 2008 Elsevier Inc. All rights reserved. It was ported to P5 by Kelly Chang. If you find any errors or have comments,<a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +
            +      </div>
            +
            +      <h1>Color</h1>
            +
            +      <p>
            +      In the digital world, when we want to talk about a color, precision is required. Saying "Hey, can you make that circle bluish-green?" will not do. Color, rather, is defined as a range of numbers. Let's start with the simplest case: black & white or grayscale. 0 means black, 255 means white. In between, every other number—50, 87, 162, 209, and so on—is a shade of gray ranging from black to white.
            +      </p>
            +
            +      <img src="../assets/learn/color/grayscale.svg">
            +
            +      <p>
            +      By adding the <a href="/reference/#/p5/stroke"> stroke()</a> and <a href="/reference/#/p5/fill">fill()</a> functions before something is drawn, we can set the color of any given shape. There is also the function <a href="/reference/#/p5/background">background()</a>, which sets a background color for the window. Here's an example.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        background(255);    // Setting the background to white
            + stroke(0);          // Setting the outline (stroke) to black
            + fill(150);          // Setting the interior of a shape (fill) to grey
            + rect(50,50,75,100); // Drawing the rectangle
            +      </code></pre>
            +
            +      <p>
            +      Stroke or fill can be eliminated with the functions: <a href="/reference/#/p5/noStroke">noStroke()</a> and <a href="/reference/#/p5/noFill">noFill()</a>. Our instinct might be to say "stroke(0)" for no outline, however, it is important to remember that 0 is not "nothing", but rather denotes the color black. Also, remember not to eliminate both—with<b>noStroke()</b> and <b>noFill()</b>, nothing will appear!
            +      </p>
            +
            +      <p>In addition, if we draw two shapes, p5.js will always use the most recently specified stroke and fill, reading the code from top to bottom.</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +  background(150);
            +  stroke(0);
            +  line(0, 0, 100, 100);
            +  stroke(255);
            +  noFill();
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <h2>RGB Color</h2>
            +
            +      <p>
            +      Remember finger painting? By mixing three "primary" colors, any color could be generated. Swirling all colors together resulted in a muddy brown. The more paint you added, the darker it got. Digital colors are also constructed by mixing three primary colors, but it works differently from paint. First, the primaries are different: red, green, and blue (i.e., "RGB" color). And with color on the screen, you are mixing light, not paint, so the mixing rules are different as well.
            +      </p>
            +
            +      <img src="../assets/learn/color/rgb.jpg">
            +      <p>
            +        <ul class="list_view">
            +          <li>Red + Green = Yellow</li>
            +          <li>Red + Blue = Purple</li>
            +          <li>Green + Blue = Cyan (blue-green)</li>
            +          <li>Red + Green + Blue = White</li>
            +          <li>No colors = Black</li>
            +        </ul>
            +      </p>
            +
            +      <p>This assumes that the colors are all as bright as possible, but of course, you have a range of color available, so some red plus some green plus some blue equals gray, and a bit of red plus a bit of blue equals dark purple. While this may take some getting used to, the more you program and experiment with RGB color, the more it will become instinctive, much like swirling colors with your fingers. And of course you can't say "Mix some red with a bit of blue," you have to provide an exact amount. As with grayscale, the individual color elements are expressed as ranges from 0 (none of that color) to 255 (as much as possible), and they are listed in the order R, G, and B. You will get the hang of RGB color mixing through experimentation, but next we will cover some code using some common colors.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  noStroke();
            +
            +  // Bright red
            +  fill(255,0,0);
            +  ellipse(20,20,16,16);
            +
            +  // Dark red
            +  fill(127,0,0);
            +  ellipse(40,20,16,16);
            +
            +  // Pink (pale red)
            +  fill(255,200,200);
            +  ellipse(60,20,16,16);
            +}
            +      </script>
            +
            +
            +
            +      <h2>Color Transparency</h2>
            +
            +      <p>In addition to the red, green, and blue components of each color, there is an additional optional fourth component, referred to as the color's "alpha". Alpha means transparency and is particularly useful when you want to draw elements that appear partially see-through on top of one another. The alpha values for an image are sometimes referred to collectively as the "alpha channel" of an image.</p>
            +      <p>It is important to realize that pixels are not literally transparent, this is simply a convenient illusion that is accomplished by blending colors. Behind the scenes, p5.js takes the color numbers and adds a percentage of one to a percentage of another, creating the optical perception of blending. (If you are interested in programming "rose-colored" glasses, this is where you would begin.)</p>
            +
            +      <p>Alpha values also range from 0 to 255, with 0 being completely transparent (i.e., 0% opaque) and 255 completely opaque (i.e., 100% opaque).</p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +  createCanvas(100, 100);
            +  fill(0,0,255);
            +  rect(0,0,50,100);
            +
            +  // 255 means 100% opacity.
            +  fill(255,0,0,255);
            +  rect(0,0,100,20);
            +
            +  // 75% opacity.
            +  fill(255,0,0,191);
            +  rect(0,25,100,20);
            +
            +  // 55% opacity.
            +  fill(255,0,0,127);
            +  rect(0,50,100,20);
            +
            +  // 25% opacity.
            +  fill(255,0,0,63);
            +  rect(0,75,100,20);
            +
            +      </script>
            +
            +      <h2>Custom Color Ranges</h2>
            +
            +      <p>
            +      RGB color with ranges of 0 to 255 is not the only way you can handle color in p5.js, in fact, it allows us to think about color any way we like. For example, you might prefer to think of color as ranging from 0 to 100 (like a percentage). You can do this by specifying a custom<a href="/reference/#/p5/colorMode">colorMode()</a>.
            +      </p>
            +
            +      <pre><code>
            +      colorMode(RGB,100);
            +      </code></pre>
            +
            +      <p>The above function says: "OK, we want to think about color in terms of red, green, and blue. The range of RGB values will be from 0 to 100."</p>
            +
            +      <p>Although it is rarely convenient to do so, you can also have different ranges for each color component:</p>
            +
            +      <pre><code>
            +      colorMode(RGB,100,500,10,255);
            +      </code></pre>
            +
            +      <p>Now we are saying "Red values go from 0 to 100, green from 0 to 500, blue from 0 to 10, and alpha from 0 to 255."</p>
            +
            +      <p>Finally, while you will likely only need RGB color for all of your programming needs, you can also specify colors in the HSB (hue, saturation, and brightness) mode. Without getting into too much detail, HSB color works as follows:</p>
            +
            +      <img src="../assets/learn/color/hsb.png">
            +      <ul class="list_view">
            +        <li><b>Hue</b>—The color type, ranges from 0 to 360 by default.</li>
            +        <li><b>Saturation</b>—The vibrancy of the color, 0 to 100 by default.</li>
            +        <li><b>Brightness</b>—The, well, brightness of the color, 0 to 100 by default.</li>
            +      </ul>
            +
            +      <p>With <a href="/reference/#/p5/colorMode">colorMode()</a> you can set your own ranges for these values. Some prefer a range of 0-360 for hue (think of 360 degrees on a color wheel) and 0-100 for saturation and brightness (think of 0-100%).</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/coordinate-system-and-shapes.html b/dist/learn/coordinate-system-and-shapes.html
            new file mode 100644
            index 0000000000..30fe36ece6
            --- /dev/null
            +++ b/dist/learn/coordinate-system-and-shapes.html
            @@ -0,0 +1,279 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This tutorial is from the book <em>Learning Processing</em> by Daniel Shiffman, published by Morgan Kaufmann, © 2008 Elsevier Inc. All rights reserved. It was ported to p5.js by Alex Yixuan Xu. If you find any errors or have comments, please <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.</div>
            +
            +      <h1>Coordinate System and Shapes</h1>
            +      <p>Before we begin programming with p5, we must first channel our eighth grade selves, pull out a piece of graph paper, and draw a line. The shortest distance between two points is a good old fashioned line, and this is where we begin, with two points on that graph paper.</p>
            +      <img src="../assets/learn/coordinate-system-and-shapes/images/drawing-01.png" alt="">
            +
            +      <p>The above figure shows a line between point A (1,0) and point B (4,5). If you wanted to direct a friend of yours to draw that same line, you would give them a shout and say "draw a line from the point one-zero to the point four-five, please." Well, for the moment, imagine your friend was a computer and you wanted to instruct this digital pal to display that same line on its screen. The same command applies (only this time you can skip the pleasantries and you will be required to employ a precise formatting). Here, the instruction will look like this:</p>
            +
            +      <pre><code class="language-javascript">
            +        line(1,0,4,5);
            +      </code></pre>
            +
            +      <p>Even without having studied the syntax of writing code, the above statement should make a fair amount of sense. We are providing a command (which we will refer to as a "function") for the machine to follow entitled "line." In addition, we are specifying some arguments for how that line should be drawn, from point A (1,0) to point B (4,5). If you think of that line of code as a sentence, the function is a verb and the arguments are the objects of the sentence. The code sentence also ends with a semicolon instead of a period.</p>
            +      <img src="../assets/learn/coordinate-system-and-shapes/images/drawing-02.png" alt="">
            +
            +      <p>The key here is to realize that the computer screen is nothing more than a fancier piece of graph paper. Each pixel of the screen is a coordinate - two numbers, an "x" (horizontal) and a "y" (vertical) - that determines the location of a point in space. And it is our job to specify what shapes and colors should appear at these pixel coordinates.</p>
            +
            +      <p>Nevertheless, there is a catch here. The graph paper from eighth grade ("Cartesian coordinate system") placed (0,0) in the center with the y-axis pointing up and the x-axis pointing to the right (in the positive direction, negative down and to the left). The coordinate system for pixels in a computer window, however, is reversed along the y-axis. (0,0) can be found at the top left with the positive direction to the right horizontally and down vertically.</p>
            +      <img src="../assets/learn/coordinate-system-and-shapes/images/drawing-03.svg" alt="">
            +
            +      <h2>Simple Shapes</h2>
            +      <p>The vast majority of p5 programming examples are visual in nature. These examples, at their core, involve drawing shapes and setting pixels. Let's begin by looking at four primitive shapes.</p>
            +      <img src="../assets/learn/coordinate-system-and-shapes/images/drawing-04.png" alt="">
            +
            +      <p>For each shape, we will ask ourselves what information is required to specify the location and size (and later color) of that shape and learn how p5 expects to receive that information. In each of the diagrams below, we'll assume a window with a width of 100 pixels and height of 100 pixels.</p>
            +
            +      <p>A <a href="/reference/#/p5/point">point()</a> is the easiest of the shapes and a good place to start. To draw a point, we only need an x and y coordinate.</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  point(40, 50); // point(x, y)
            +}
            +</script>
            +
            +      <p>A <a href="/reference/#/p5/line">line()</a> isn't terribly difficult either and simply requires two points: (x1,y1) and (x2,y2):</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  line(10, 20, 50, 20); // line(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>Once we arrive at drawing a <a href="/reference/#/p5/rect">rect()</a>, things become a bit more complicated. In p5, a rectangle is specified by the coordinate for the top left corner of the rectangle, as well as its width and height.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  rect(10, 20, 40, 30); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>A second way to draw a rectangle involves specifying the centerpoint, along with width and height. If we prefer this method, we first indicate that we want to use the<a href="/reference/#/p5/CENTER">CENTER</a> mode before the instruction for the rectangle itself. Note that p5 is case-sensitive.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(30, 20, 40, 20); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>Finally, we can also draw a rectangle with two points (the top left corner and the bottom right corner). The mode here is<a href="/reference/#/p5/CORNERS">CORNERS</a>. Note this example gives the same result on screen as the example above.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CORNERS);
            +}
            +function draw(){
            +  rect(10, 10, 50, 30); // rect(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>Once we have become comfortable with the concept of drawing a rectangle, an <a href="/reference/#/p5/ellipse">ellipse()</a> is a snap. In fact, it is identical to <a href="/reference/#/p5/rect">rect()</a> with the difference being that an ellipse is drawn where the bounding box of the rectangle would be. The default mode for <a href="/reference/#/p5/ellipse">ellipse()</a> is <a href="/reference/#/p5/CENTER">CENTER</a>, rather than <a href="/reference/#/p5/CORNER">CORNER</a>.</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CENTER);
            +}
            +function draw(){
            +  ellipse(30, 30, 40, 60); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNER);
            +}
            +function draw(){
            +  ellipse(10, 10, 30, 50); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNERS);
            +}
            +function draw(){
            +  ellipse(10, 10, 40, 50); // ellipse(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>Now let's look at what some code with shapes in more complete form, with canvas dimensions of 200 by 200. Note the use of the createCanvas() function to specify the width and height of the canvas.</p>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(200, 200);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(100,100,20,100);
            +  ellipse(100,70,60,60);
            +  ellipse(81,70,16,32);
            +  ellipse(119,70,16,32);
            +  line(90,150,80,160);
            +  line(110,150,120,160);
            +}
            +</script>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/curves.html b/dist/learn/curves.html
            new file mode 100644
            index 0000000000..d8d7a0e581
            --- /dev/null
            +++ b/dist/learn/curves.html
            @@ -0,0 +1,328 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by J David Eisenberg and ported by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +      This work is licensed under a <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"> Creative Commons Attribution-NonCommercial-ShareAlinke 4.0 International License.</a>
            +
            +      </div>
            +
            +      <h1>Curves</h1>
            +
            +      <p>
            +      This short tutorial introduces you to the three types of curves in p5.js: arcs, spline curves, and Bézier curves.
            +      </p>
            +
            +      <h2> Arcs </h2>
            +
            +      <p>
            +      Arcs are the simplest curves to draw, it is defined an arc as a section of an ellipse. You call the function with these parameters:
            +      </p>
            +
            +      <p>
            +      arc (x, y, w, h, start, stop, [mode])
            +      </p>
            +
            +      <p>
            +      The first four parameters (x,y,w,h) define the boundary box for your arc and the next two (start, stop), are the start and stop angles for the arc. These angles are given in radians
            +      and are measured clockwise with zero degrees pointing east and PI radians equals 180°.
            +      </p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +          createCanvas(150,200);
            +          background(150);
            +          stroke(0);
            +          arc(35, 35, 50, 50, 0, PI / 2.0); // lower quarter circle
            +          arc(105, 35, 50, 50, -PI, 0, CHORD);  // upper half of circle
            +          arc(175, 35, 50, 50, -PI / 6, PI / 6, PIE); // 60 degrees
            +          noFill();
            +          arc(105, 105, 100, 50, PI / 2, 3 * PI / 2, OPEN); // 180 degrees
            +        }
            +      </script>
            +
            +      <h2>Spline Curves</h2>
            +
            +      <p>
            +      Arcs are fine, but they’re plain. The next function, curve(), lets you draw curves that aren’t necessarily part of an arc. This function draws what is technically called a Rom-Catmull Spline.
            +      To draw the curve, you must specify the (x, y) coordinates of the points where the curve starts and ends. You must also specify two control points which determine the direction and amount of curvature.
            +      The first two and last two parameters are the control points of the curve.
            +      A call to curve() uses these parameters:
            +      </p>
            +
            +      <p>
            +      curve (cpx1, cpy1, x1, y1, x2, y2, cpx2, cpy2);
            +      </p>
            +
            +      <p>
            +      How do the control points affect the way the curve looks?
            +      </p>
            +
            +      <p>
            +        The tangent to the curve at the start point is parallel to the line between control point one and the end of the curve. The tangent to the curve at the end point is parallel to the line between the start point and control point 2.
            +      </p>
            +
            +      <p>
            +      The following diagram shows a curve and the points can be dragged to show how the control point affects the curve:
            +      </p>
            +
            +      <!-- iframe for the curve and dragging points -->
            +      <iframe src="../assets/learn/curves/curve_ex/embed.html" width="350" height="350">
            +      </iframe>
            +
            +
            +      <h2>Continuous Spline Curves</h2>
            +
            +      <p>
            +      In isolation, a single curve() is not particularly appealing. To draw a continuous curve through several points, you are better off using the curveVertex() function.
            +      You can only use this function when you are creating a shape with the beginShape() and endShape() functions.In common usage, people use the first point of the curve
            +      as the first control point and the last point of the curve as the last control point.
            +      </p>
            +
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      let coords = [40, 40, 80, 60, 100, 100, 60, 120, 50, 150];
            +
            +      function setup() {
            +        createCanvas(150, 200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        curveVertex(40,40);
            +        curveVertex(40,40);
            +        curveVertex(80,60);
            +        curveVertex(100,100);
            +        curveVertex(60,120);
            +        curveVertex(50,150);
            +        curveVertex(50,150);
            +        endShape();
            +
            +         for (let i = 0; i < coords.length; i+= 2){
            +          ellipse(coords[i], coords[i+1], 10, 10);
            +         }
            +      }
            +      </script>
            +
            +      <h2>Bézier Curves</h2>
            +
            +      <p>
            +        Though better than arcs, spline curves don’t seem to have those graceful, swooping curves that say “art.” For those, you need to draw Bézier curves with the bezier() function.
            +        As with spline curves, the bezier() function has eight parameters, but the order is different. The first two and last two parameters are the start and end points while middle 
            +        four points are the control points.
            +      </p>
            +
            +      <p> bezier(x1, y1, cpx1, cpy1, cpx2, cpy2, x2, y2); </p>
            +
            +      <!-- iframe of Bezier example -->
            +      <iframe src="../assets/learn/curves/bezier/embed.html" width="400" height="400">
            +      </iframe>
            +
            +      <p>
            +      While it is difficult to visualize how the control points affect a curve(), it is slightly easier to see how the control points affect Bézier curves.
            +      Imagine two poles and several rubber bands. The poles connect the control points to the endpoints of the curve. A rubber band connects the tops of the poles.
            +      Two more rubber bands connect the midpoints of the poles to the midpoint of the first rubber band. One more rubber band connects their midpoints.
            +      The center of that last rubber band is tied to the curve. This diagram helps to explain, the points can be moved to change the curve.
            +    </p>
            +
            +      <!-- image of bezier with lines -->
            +      <img src="../assets/learn/curves/bezier_with_lines/bezier_with_lines.png" style="width:150px;">
            +
            +      <h2> Continuous Bézier Curves</h2>
            +
            +      <p>
            +      Just as curveVertex() allows you to make continuous spline curves, bezierVertex() lets you make continuous Bézier curves.
            +      Again, you must be within a beginShape() / endShape() sequence. You must use vertex(startX, startY) to specify the starting anchor point of the curve.
            +      Subsequent points are specified with a call to:
            +      </P>
            +
            +      <p>bezierVertex(cpx1, cpy1, cpx2, cpy2, x, y);</P>
            +
            +      <p>
            +      Here is a continuous Bézier curve, but it doesn’t join smoothly. In order to make two curves A and B smoothly continuous, the last control point of A,
            +      the last point of A, and the first control point of B have to be on a straight line.
            +      </P>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +        createCanvas(150,200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        vertex(30, 70); // first point
            +        bezierVertex(25, 25, 100, 50, 50, 100);
            +        bezierVertex(50, 140, 75, 140, 120, 120); // if first 2 numbers are changed to 20, 130 it becomes continuous
            +        endShape();
            +
            +        ellipse(25, 25, 5, 5);
            +        ellipse(100, 50, 5, 5);
            +        ellipse(50, 140, 5, 5);//change to (20, 130, 5, 5) to reflect control point
            +        ellipse(75, 140, 5, 5);
            +      }
            +      </script>
            +
            +      <h2>Summary</h2>
            +        <p>
            +          <ul class="list_view">
            +            <li>Use arc() when you need a segment of a circle or an ellipse. You can’t make continuous arcs or use them as part of a shape.</li>
            +            <li>Use curve() when you need a small curve between two points. Use curveVertex() to make a continuous series of curves as part of a shape.</li>
            +            <li>Use bezier() when you need long, smooth curves. Use bezierVertex() to make a continuous series of Bézier curves as part of a shape.</li>
            +          </ul>
            +        </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/debugging.html b/dist/learn/debugging.html
            new file mode 100644
            index 0000000000..21221713be
            --- /dev/null
            +++ b/dist/learn/debugging.html
            @@ -0,0 +1,319 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +        This tutorial was made by the Education Working Group, during the p5.js contributor conference at the Frank-Ratchye Studio for Creative Inquiry, Carnegie Mellon University in May of 2015. The contributors to this tutorial include <a href="http://huah.net/jason/">Jason Alderman</a>, <a href="http://tegabrain.com/">Tega Brain</a>, <a href="http://taeyoonchoi.com/">Taeyoon Choi</a> and <a href="http://luisaph.com/">Luisa Pereira</a>.
            +      </div>
            +      <img src="../assets/learn/debugging/0-0.jpg" alt="" />
            +
            +      <p>
            +        This is a field guide for debugging for everyone—whether you are beginning to code or whether you have been coding for a long time, this guide breaks down the mysterious process of solving problems.
            +      </p>
            +
            +      <h3 class="start-element tutorial-btn" id="introduction">0. Debugging is a Creative Act</h3>
            +      <div class="info">
            +        <p>At all levels, programmers encounter bugs and will often spend more time debugging than actually programming the application. You can expect to spend a lot of time doing this and so it is important to develop good strategies for identifying and working through bugs as you learn to program in p5.js.</p>
            +        <p>
            +          A bug is a gap between what you think your system is doing, and what it is actually doing. <a target="_blank"
            +          href="https://vimeo.com/channels/debugging" >Clay Shirky aptly describes </a>a bug as "the moment when there is both a technical problem with your code as well as a problem with your mental picture of what is happening in your code." </p>
            +          <img src="../assets/learn/debugging/0-1.jpg" alt="" />
            +        </p>
            +
            +        <p>You think you are telling the computer one thing, but it is doing something else. It may also be crashing or throwing errors. In order to close the gap, you must investigate. </p>
            +        <p>When you are working on a project, you may play many different roles. You are an architect when designing and planning your program, an engineer when you are developing it. Then you will be an explorer, discovering the problems and errors and testing it in all the situations in which it needs to run. You are trying to find out where it might break. Finally, when debugging you are a detective, trying to figure out how and why things broke.</p>
            +        <img class="small" src="../assets/learn/debugging/0-3.png" alt="" />
            +        <img class="small" src="../assets/learn/debugging/0-4.png" alt="" />
            +        <img class="small" src="../assets/learn/debugging/0-5.png" alt="" />
            +        <img class="small" src="../assets/learn/debugging/0-6.png" alt="" />
            +
            +        <p>So how can you become a good detective and debug your program? Here are the ten steps that can help you become a good code sleuth. </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="Change Perspectives">1. Change Perspectives.</h3>
            +      <div class="info">
            +        <p>Don't panic.</p>
            +        <p>When you encounter a bug that you do not know how to solve, stop, pause and take a deep breath. Stand up, say hi to the dog, take a walk or if it's late go get some sleep. When you are frustrated, tired and upset, you are not in a good frame of mind to learn or solve a  problem.</p>
            +        <p>To find your errors you will need to change perspectives and become the detective. The goal is to find out what the program IS doing, rather than why it's not doing what it's supposed to. We need to get the computer to show us what it's doing.</p>
            +        <p>The clues are in the values of variables and flow of program.</p>
            +        <img class="small_center" src="../assets/learn/debugging/1-0.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="problem">2. Observe the problem </h3>
            +      <div class="info">
            +        <p>Walk someone through the issue even if they themselves do not know how to program. If no one is around, draft an email explaining what you have done and breaking down what the problem is.</p>
            +        <img class="med_center" src="../assets/learn/debugging/2-1.png" alt="" />
            +        <p>You probably won't need to actually send this email as often the act of writing it will help you to locate and identify what you need to do next. Some programmers have even been known to explain their problem to a friendly inanimate object like a rubber ducky.</p>
            +        <img class="med_center" src="../assets/learn/debugging/2-2.png" alt="" />
            +        <p>
            +          This is also a good time to add comments to your code that tell you exactly what each of your functions is doing.
            +          Some coders also print out their code (or a section of it) and go through it line by line, tracing the path of variables and making notes.
            +        </p>
            +        <img class="med_center" src="../assets/learn/debugging/2-3.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="start">3. Before you start... </h3>
            +      <div class="info">
            +        <p>Before doing anything,  save a copy of your code that you can go back to.  While debugging you are likely to introduce other problems, break things or accidentally delete good work.</p>
            +        <img class="med_center" src="../assets/learn/debugging/3-1.png" alt="" />
            +        <p>You don't want to make bigger bugs in the process of debugging.</p>
            +        <img class="small_center" src="../assets/learn/debugging/3-2.png" alt="" />
            +        <p>If you make a mistake or your problem gets more worse, you can always UNDO or revert back to your saved file.</p>
            +        <img class="med_center" src="../assets/learn/debugging/3-3.jpg" alt="" />
            +        <p>You can try version control such as <a href="http://github.com">GitHub</a>.</p>
            +        <img src="../assets/learn/debugging/3-4.png" alt="" />
            +        <p>Write a list of what you are trying, so you can keep track of what still needs to be checked. Be  methodical, it will save you a lot of time in the long run.</p>
            +        <p>
            +          Only ever change one thing at a time.
            +          <img class="med_right" src="../assets/learn/debugging/3-5.jpg" alt="" />
            +          As you debug, you will be turning parts of your code on and off.
            +          Every time you make a change, test your program. If you make multiple changes before testing, you will not know which change has what effect and are likely to break things further.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="basics">4. Check the basics </h3>
            +      <div class="info">
            +        <p>Many bugs end up being very basic mistakes, equivalent to forgetting to plug in the power cord. These mistakes are so obvious they are often invisible. Check the dumb stuff like...</p>
            +        <ul class="list_view">
            +          <li>Are you editing the file that you are actually running (and not, for example, editing the local file, and looking at a different file on the server)?</li>
            +          <li>Are all of your external files where you think they are?</li>
            +          <li>Are your file dependencies correct?</li>
            +          <li>Are there any typos in your paths?</li>
            +          <li>Check your server? etc.</li>
            +        </ul>
            +        <img src="../assets/learn/debugging/4-1.png" alt="" />
            +        <img src="../assets/learn/debugging/4-2.png" alt="" />
            +        <img src="../assets/learn/debugging/4-3.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="blackboxes">5. Black boxes</h3>
            +      <div class="info">
            +        <p>A black box describes any part of your system you do not understand the inner workings of. For example, a library or perhaps a function that you have not written for yourself. Systematically take out each black box one-by-one and run your program. This will help to see if these parts of the program contain the error.</p>
            +        <img class="med_left" src="../assets/learn/debugging/5-1.jpg" alt="" />
            +        <img class="med_right" src="../assets/learn/debugging/5-2.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="reporting">6. Add error reporting</h3>
            +      <div class="info">
            +        <p>
            +          <img class="med_right" src="../assets/learn/debugging/6-1.png" alt="" />
            +          Error reporting is how your program tells you what it is doing.
            +          p5.js comes with some built-in error reporting that will tell you if you have made specific syntax errors.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in your own error reporting using the console.log() function.
            +          <img class="med_right" src="../assets/learn/debugging/6-2.png" alt="" />
            +          To check your program flow, add in console.log() statements to the parts of your code.
            +          Then when you look at your console you can see the order that things happen and where you encounter problems.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in console.log()s to print out values of variables so that you can see what they are doing.
            +          <img class="med_center" src="../assets/learn/debugging/6-3.jpg" alt="" />
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="help">7. Search for more help </h3>
            +      <div class="info">
            +        <p>So none of this works? There are many places you can look online to get more help.</p>
            +        <ul class="list_view">
            +          <li>Do a Google search, if you have had this problem chances are many other people will have too.</li>
            +          <li>Search the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> using the p5.js tag.</li>
            +          <li>Search development forums like <a href="http://stackoverflow.com/">Stack Overflow</a>.</li>
            +        </ul>
            +        <p> More general javascript resources:</p>
            +        <ul class="list_view">
            +          <li>First chapter of Bocoup's and Rebecca Murphey's interactive textbook, <a href="http://jqfundamentals.com/chapter/javascript-basics">jQuery Fundamentals</a>.</li>
            +          <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">  Mozilla's JavaScript Guide</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference ">JavaScript Reference </a>(this is really helpful for finding all of the built-in methods for, say a String).</li>
            +        </ul>
            +        <img class="med_center" src="../assets/learn/debugging/7-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="people">8. Ask people </h3>
            +      <div class="info">
            +        <p>
            +          Still not working?
            +          <img class="med_right" src="../assets/learn/debugging/8-0.jpg" alt="" />
            +          You can also ask people for help! They might be delighted to help you.
            +        </p>
            +        <p>
            +          Send that email you wrote at the start.<br>
            +          Post to the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> succinctly articulating your problem and what you want to know. <br>
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="prevent">9. Good coding practices and how to prevent bugs!</h3>
            +      <div class="info">
            +        <ul class="list_view">
            +          <li>Do not optimize prematurely. Clear code is more important than high-performing code as you're building your program.</li>
            +          <li>Do not abstract prematurely. You don't need to make functions for things you think you're going to use multiple times...until you actually have to use it more than once.</li>
            +          <li>
            +            Start with pseudocode as comments, then add code underneath each step.<br>
            +            Put console.log()s in your code as you develop (and test frequently—so if something changes, you know what you did since the last time you tested).<br>
            +          </li>
            +        </ul>
            +        <p>ALSO: start with small problems! Do one thing at a time. It's ok to make smaller sketches to test one thing (draw a star! check twitter!) and then voltron them together into a bigger sketch (draw a star that turns red when you have a notification on twitter!)</p>
            +        <img class="med_center" src="../assets/learn/debugging/9-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="resources">10. More resources </h3>
            +      <div class="info">
            +        <p>
            +          This guide has been inspired by several other fantastic resources on debugging when coding. Some of these are here:
            +        </p>
            +          <ul class="list_view">
            +            <li>Matt Gemmel, <a href="http://mattgemmell.com/what-have-you-tried/">What have you tried?</a></li>
            +            <li>Clay Shirky, <a href="https://vimeo.com/channels/debugging">A brief introduction to debugging</a></li>
            +            <li>Eric Steven Raymond, <a href="http://www.catb.org/esr/faqs/smart-questions.html"> How to ask questions the smart way</a></li>
            +            <li>ITP Residents, <a href="https://docs.google.com/presentation/d/1RXzITwS4otVKnYkuNu2w7CrpYy35WBO2HUlmkSc2p8g/edit?copiedFromTrash#slide=id.g2ffb36b3_0_44">10 Tips for Debugging</a></li>
            +            <li>Rurouni Jones, <a href="http://rurounijones.github.io/blog/2009/03/17/how-to-ask-for-help-on-irc//">How to ask for help on IRC</a></li>
            +          </ul>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/index.html b/dist/learn/index.html
            new file mode 100644
            index 0000000000..854d8c196d
            --- /dev/null
            +++ b/dist/learn/index.html
            @@ -0,0 +1,490 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>Learn</h1>
            +
            +      <p>These tutorials provide more in-depth or step-by-step overviews of particular topics. Check out the
            +        <a href="/examples">examples page
            +        </a>to explore short demonstrations of various p5.js topics.
            +      </p>
            +
            +      
            +        <h2 class="tutorial-title">Introduction to p5.js</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="/get-started/">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Getting Started</h3>
            +                </a>
            +              </div>
            +              <p>Welcome to p5.js! <br> This introduction covers the basics of setting up a p5.js project. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js-overview">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js overview</h3>
            +                </a>
            +              </div>
            +              <p>An overview of the main features of p5.js. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Processing-transition">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js and Processing</h3>
            +                </a>
            +              </div>
            +              <p>The main differences between the two, and how to convert from one to the other. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Local-server">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Using a local server</h3>
            +                </a>
            +              </div>
            +              <p>How to set up a local server on Mac OSX, Windows, or Linux. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js wiki</h3>
            +                </a>
            +              </div>
            +              <p>Additonal documentation and tutorials contributed by the community </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="p5-screen-reader.html">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5 with a screen reader</h3>
            +                </a>
            +              </div>
            +              <p>Setting up p5 so that it can be used easily with a screen reader. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">Connecting p5.js</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>node.js and socket.io</h3>
            +                </a>
            +              </div>
            +              <p>Using a node.js server with p5.js, communication via socket.io. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">Programming topics</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Beyond-the-canvas">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Beyond the canvas</h3>
            +                </a>
            +              </div>
            +              <p>Creating and manipulating elements on the page beyond the canvas. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>3D/WebGL</h3>
            +                </a>
            +              </div>
            +              <p>Developing advanced graphics applications in p5.js using WEBGL mode. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="color.html">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Color</h3>
            +                </a>
            +              </div>
            +              <p>An introduction to digital color. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="coordinate-system-and-shapes.html">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Coordinate System and Shapes</h3>
            +                </a>
            +              </div>
            +              <p>Drawing simple shapes and using the coordinate system. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="curves.html">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Curves</h3>
            +                </a>
            +              </div>
            +              <p>An introduction to the three types of curves in p5.js: arcs, spline curves, and Bézier curves. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="interactivity.html">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Interactivity</h3>
            +                </a>
            +              </div>
            +              <p>Introduction to interactivity with the mouse and keyboard. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="program-flow.html">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Program Flow</h3>
            +                </a>
            +              </div>
            +              <p>Introduction to controlling program flow in p5.js. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">Becoming a better programmer</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="debugging.html">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Debugging</h3>
            +                </a>
            +              </div>
            +              <p>Field guide to debugging for everyone. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Optimizing p5.js code for performance</h3>
            +                </a>
            +              </div>
            +              <p>A tutorial of tips and tricks for optimizing your code to make it run faster and smoother. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tdd.html">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Unit testing and test driven development</h3>
            +                </a>
            +              </div>
            +              <p>Save yourself from agony on install day. What is unit testing and how to use it? By Andy Timmons. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">Contributing to the community</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Development</h3>
            +                </a>
            +              </div>
            +              <p>Getting started and overview for contributing to development. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://www.luisapereira.net/teaching/materials/processing-foundation">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Looking inside p5</h3>
            +                </a>
            +              </div>
            +              <p>A friendly intro to the file structure and tools for p5.js development, by Luisa Pereira. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tutorial-guide.html">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Writing a tutorial</h3>
            +                </a>
            +              </div>
            +              <p>A guide to writing a p5.js programming tutorial. </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +                  <img alt="" src="../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>Creating libraries</h3>
            +                </a>
            +              </div>
            +              <p>Creating p5.js addon libraries. </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/interactivity.html b/dist/learn/interactivity.html
            new file mode 100644
            index 0000000000..7f40376d3e
            --- /dev/null
            +++ b/dist/learn/interactivity.html
            @@ -0,0 +1,959 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This is based on the Interactivity chapter from the second edition of<em>
            +      <a href="https://processing.org/handbook/">Processing: A Programming Handbook for Visual Designers and Artists</a></em>, published by MIT Press. Copyright 2013 MIT Press. This tutorial was originally written for Processing version 2.0+ but has been ported and updated here for P5 by Alex Yixuan Xu. If you see any errors or have comments, please
            +      <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Interactivity</h1>
            +
            +      <p>The screen forms a bridge between our bodies and the realm of circuits and electricity inside computers. We control elements on screen through a variety of devices such as touch pads, trackballs, and joysticks, but the keyboard and mouse remain the most common input devices for desktop computers. The computer mouse dates back to the late 1960s, when Douglas Engelbart presented the device as an element of the oN-Line System (NLS), one of the first computer systems with a video display. The mouse concept was further developed at the Xerox Palo Alto Research Center (PARC), but its introduction with the Apple Macintosh in 1984 was the catalyst for its current ubiquity. The design of the mouse has gone through many revisions in the last forty years, but its function has remained the same. In Engelbart's original patent application in 1970 he referred to the mouse as an "X-Y position indicator," and this still accurately, but dryly, defines its contemporary use.</p>
            +
            +      <p>The physical mouse object is used to control the position of the cursor on screen and to select interface elements. The cursor position is read by computer programs as two numbers, the x-coordinate and the y-coordinate. These numbers can be used to control attributes of elements on screen. If these coordinates are collected and analyzed, they can be used to extract higher-level information such as the speed and direction of the mouse. This data can in turn be used for gesture and pattern recognition.</p>
            +
            +      <p>Keyboards are typically used to input characters for composing documents, email, and instant messages, but the keyboard has potential for use beyond its original intent. The migration of the keyboard from typewriter to computer expanded its function to enable launching software, moving through the menus of software applications, and navigating 3D environments in games. When writing your own software, you have the freedom to use the keyboard data any way you wish. For example, basic information such as the speed and rhythm of the fingers can be determined by the rate at which keys are pressed. This information could control the speed of an event or the quality of motion. It's also possible to ignore the characters printed on the keyboard itself and use the location of each key relative to the keyboard grid as a numeric position.</p>
            +
            +      <p>The modern computer keyboard is a direct descendant of the typewriter. The position of the keys on an English-language keyboard is inherited from early typewriters. This layout is called QWERTY because of the order of the top row of letter keys. It was developed for typewriters to put physical distance between frequently typed letter pairs, helping reduce the likelihood of the typebars colliding and jamming as they hit the ribbon. This more than one-hundred-year-old mechanical legacy still affects how we write software today.</p>
            +
            +      <h2>Mouse Data</h2>
            +
            +      <p>The variables <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> (note the capital X and Y) store the x-coordinate and y-coordinate of the cursor relative to the origin in the upper-left corner of the display window. To see the actual values produced while moving the mouse, run this program to print the values to the screen:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text("X: "+mouseX, 0, height/4);
            +  text("Y: "+mouseY, 0, height/2);
            +}
            +      </script>
            +
            +      <p>When a program starts, the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> values are 0. If the cursor moves into the display window, the values are set to the current position of the cursor. If the cursor is at the left, the mouseX value is 0 and the value increases as the cursor moves to the right. If the cursor is at the top, the mouseY value is 0 and the value increases as the cursor moves down. If mouseX and mouseY are used in programs without a <a href="/reference/#/p5/draw"> draw()</a> or if <a href="/reference/#/p5/noLoop">noLoop()</a> is run in <a href="/reference/#/p5/setup">setup()</a>, the values will always be 0.</p>
            +
            +      <p>The mouse position is most commonly used to control the location of visual elements on screen. More interesting relations are created when the visual elements relate differently to the mouse values, rather than simply mimicking the current position. Adding and subtracting values from the mouse position creates relationships that remain constant, while multiplying and dividing these values creates changing visual relationships between the mouse position and the elements on the screen. In the first of the following examples, the circle is directly mapped to the cursor, in the second, numbers are added and subtracted from the cursor position to create offsets, and in the third, multiplication and division are used to scale the offsets.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);    // Top circle
            +  ellipse(mouseX+20, 50, 33, 33); // Middle circle
            +  ellipse(mouseX-20, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);   // Top circle
            +  ellipse(mouseX/2, 50, 33, 33); // Middle circle
            +  ellipse(mouseX*2, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <p>To invert the value of the mouse, subtract the mouseX value from the width of the window and subtract the mouseY value from the height of the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  let x = mouseX;
            +  let y = mouseY;
            +  let ix = width - mouseX;  // Inverse X
            +  let iy = height - mouseY; // Inverse Y
            +  background(126);
            +  fill(255, 150);
            +  ellipse(x, height/2, y, y);
            +  fill(0, 159);
            +  ellipse(ix, height/2, iy, iy);
            +}
            +      </script>
            +
            +      <p>The variables <a href="/reference/#/p5/pmouseX">pmouseX</a> and <a href="/reference/#/p5/pmouseY">pmouseY</a> store the mouse values from the previous frame. If the mouse does not move, the values will be the same, but if the mouse is moving quickly there can be large differences between the values. To see the difference, run the following program and alternate moving the mouse slowly and quickly. Watch the values print to the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text(pmouseX - mouseX, 0, height/4);
            +}
            +      </script>
            +
            +      <p>Draw a line from the previous mouse position to the current position to show the changing position in one frame and reveal the speed and direction of the mouse. When the mouse is not moving, a point is drawn, but quick mouse movements create long lines.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(8);
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, mouseY, pmouseX, pmouseY);
            +}
            +      </script>
            +
            +      <p>Use the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables with an if structure to allow the cursor to select regions of the screen. The following examples demonstrate the cursor making a selection between different areas of the display window. The first divides the screen into halves, and the second divides the screen into thirds.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 50) {
            +    rect(0, 0, 50, 100);  // Left
            +  }
            +  else {
            +    rect(50, 0, 50, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 33) {
            +    rect(0, 0, 33, 100);  // Left
            +  }
            +  else if (mouseX < 66) {
            +    rect(33, 0, 33, 100); // Middle
            +  }
            +  else {
            +    rect(66, 0, 33, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <p>Use the logical operator &amp;&amp; with an if structure to select a rectangular region of the screen. As demonstrated in the following example, when a relational expression is made to test each edge of a rectangle (left, right, top, bottom) and these are concatenated with a logical AND, the entire relational expression is true only when the cursor is inside the rectangle.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX > 40) && (mouseX < 80) && (mouseY > 20) && (mouseY < 80)){
            +    fill(255);
            +  }
            +  else {
            +    fill(0);
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>This code asks, "Is the cursor to the right of the left edge and is the cursor to the left of the right edge and is the cursor beyond the top edge and is the cursor above the bottom?" The code for the next example asks a set of similar questions and combines them with the keyword else to determine which one of the defined areas contains the cursor.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX <= 50) && (mouseY <= 50)) {
            +    rect(0, 0, 50, 50);   // Upper-left
            +  }
            +  else if ((mouseX <= 50) && (mouseY > 50)) {
            +    rect(0, 50, 50, 50);  // Lower-left
            +  }
            +  else if ((mouseX > 50) && (mouseY <= 50)) {
            +    rect(50, 0, 50, 50);  // Upper-right
            +  }
            +  else {
            +    rect(50, 50, 50, 50); // Lower-right
            +  }
            +}
            +      </script>
            +
            +      <h2>Mouse buttons</h2>
            +      <p>Computer mice and other related input devices typically have between one and three buttons; p5 can detect when these buttons are pressed with the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> and <a href="/reference/#/p5/mouseButton">mouseButton</a> variables. Used with the button status, the cursor position enables the mouse to perform different actions. For example, a button press when the mouse is over an icon can select it, so the icon can be moved to a different location on screen. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true if any mouse button is pressed and false if no mouse button is pressed. The variable <a href="/reference/#/p5/mouseButton">mouseButton</a> is LEFT, CENTER, or RIGHT depending on the mouse button most recently pressed. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable reverts to false as soon as the button is released, but the <a href="/reference/#/p5/mouseButton">mouseButton</a> variable retains its value until a different button is pressed. These variables can be used independently or in combination to control the software. Run these programs to see how the software responds to your fingers.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(0);   // Black
            +  }
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseButton == LEFT) {
            +    fill(0);   // Black
            +  }
            +  else if (mouseButton == RIGHT) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(126); // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    if (mouseButton == LEFT) {
            +      fill(0);   // Black
            +    }
            +    else if (mouseButton == RIGHT) {
            +      fill(255); // White
            +    }
            +  }
            +  else {
            +    fill(126);   // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>Not all mice have multiple buttons, and if software is distributed widely, the interaction should not rely on detecting which button is pressed.</p>
            +
            +      <h2>Keyboard data</h2>
            +
            +      <p>p5 registers the most recently pressed key and whether a key is currently pressed. The boolean variable <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> is true if a key is pressed and is false if not. Include this variable in the test of an if structure to allow lines of code to run only if a key is pressed. The <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable remains true while the key is held down and becomes false only when the key is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) {  // If the key is pressed,
            +    line(20, 20, 80, 80);      // draw a line;
            +  }
            +  else {                       // Otherwise,
            +    rect(40, 40, 20, 20);      // draw a rectangle.
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 20;
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) { // If the key is pressed,
            +    x++;                      // add 1 to x.
            +  }
            +  line(x, 20, x-60, 80);
            +}
            +      </script>
            +      <!-- made changes about the key variable not guaranteed to be case sensitive in p5 -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable stores a single alphanumeric character. Specifically, it holds the most recently pressed key. However, it is not guaranteed to be case sensitive. To get the proper capitalization, it is best to use it within <a href="/reference/#/p5/keyTyped">keyTyped()</a>. For non-ASCII keys, use the <a href="/reference/#/p5/keyCode">keyCode</a> variable. The key can be displayed on screen with the <a href="/reference/#/p5/text">text()</a> function (p. 150).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  textSize(60);
            +  fill(255);
            +}
            +function draw() {
            +  background(0);
            +  text(key, 20, 75); // Draw at coordinate (20,75)
            +}
            +      </script>
            +
            +      <!-- no differences in "" and '' in p5, made changes -->
            +      <!-- <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. The single quotes signify A as the data type char (p. 144). The expression key == "A" will cause an error because the double quotes signify the A as a String, and it's not possible to compare a String with a char. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyPressed">keyPressed</a> variable to ascertain that the key pressed is the uppercase A.</p> -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. Note the use of double quotation marks or single quotation marks has no influence on the program as long as you are consistent. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable to ascertain that the key pressed is the uppercase A.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +  stroke(255);
            +}
            +function draw() {
            +  background(0);
            +  // If the 'A' key is pressed, draw a line
            +  if ((keyIsPressed == true) && (key == 'A')) {
            +    line(50, 25, 50, 75);
            +  }
            +  else { // Otherwise, draw an ellipse
            +    ellipse(50, 50, 50, 50);
            +  }
            +}
            +      </script>
            +
            +      <p>The previous example works with an uppercase A, but not if the lowercase letter is pressed. To check for both uppercase and lowercase letters, extend the relational expression with a logical OR, the || relational operator. Line 9 in the previous program would be changed to:</p>
            +      <pre><code class="language-javascript">
            +        if ((keyIsPressed == true) &amp;&amp; ((key == 'a') || (key == 'A'))) {
            +      </code></pre>
            +
            +      <!-- changes made -->
            +      <h2>Coded keys</h2>
            +      <p>Because each character has a numeric value as defined by the <a href="https://www.w3schools.com/charsets/ref_html_ascii.asp">ASCII table</a>, the value of the <a href="/reference/#/p5/keyCode">keyCode</a> variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script>
            +
            +      <!--made changes to original content here -->
            +<!--       <p>Because each character has a numeric value as defined by the ASCII table (p. 605), the value of the key variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +      <h2>Coded keys</h2>
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script> -->
            +
            +      <h2>Events</h2>
            +      <p>A category of functions called events alter the normal flow of a program when an action such as a key press or mouse movement takes place. An event is a polite interruption of the normal flow of a program. Key presses and mouse movements are stored until the end of <a href="/reference/#/p5/draw">draw()</a>, where they can take action that won't disturb drawing that's currently in progress. The code inside an event function is run once each time the corresponding event occurs. For example, if a mouse button is pressed, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function will run once and will not run again until the button is pressed again. This allows data produced by the mouse and keyboard to be read independently from what is happening in the rest of the program.</p>
            +
            +      <h2>Mouse events</h2>
            +      <!-- added mouseClicked() mouseOver() mouseOut() doubleClicked()-->
            +      <p>The mouse event functions are <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, <a href="/reference/#/p5/mouseDragged">mouseDragged()</a>, <a href="/reference/#/p5/mouseOver">mouseOver()</a>, and <a href="/reference/#/p5/mouseOut">mouseOut()</a>:</p>
            +
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block is run one time when the mouse is moved while a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>The <a href="/reference/#/p5/mousePressed">mousePressed()</a> function works differently than the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable. The value of the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true until the mouse button is released. It can therefore be used within <a href="/reference/#/p5/draw">draw()</a> to have a line of code run while the mouse is pressed. In contrast, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function only runs once when a button is pressed. This makes it useful when a mouse click is used to trigger an action, such as clearing the screen. In the following example, the background value becomes lighter each time a mouse button is pressed. Run the example on your computer to see the change in response to your finger.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mousePressed() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>The following example is the same as the one above, but the gray variable is set in the <a href="/reference/#/p5/mouseReleased">mouseReleased()</a> event function, which is called once every time a button is released. This difference can be seen only by running the program and clicking the mouse button. Keep the mouse button pressed for a long time and notice that the background value changes only when the button is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseReleased() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <!-- mouseClicked() example added-->
            +      <p>Similarly, the gray variable is set in the <a href="/reference/#/p5/mouseClicked">mouseClicked()</a> event function, which is called once after a mouse button has been pressed and then released. Browsers handle clicks differently, so this function is only guaranteed to be run when the left mouse button is clicked. To handle other mouse buttons being pressed or released, use <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>. </p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseClicked() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>It is generally not a good idea to draw inside an event function, but it can be done under certain conditions. Before drawing inside these functions, it's important to think about the flow of the program. In this example, squares are drawn inside <a href="/reference/#/p5/mousePressed">mousePressed()</a> and they remain on screen because there is no <a href="/reference/#/p5/background">background()</a> inside <a href="/reference/#/p5/draw">draw()</a>. But if <a href="/reference/#/p5/background">background()</a> is used, visual elements drawn within one of the mouse event functions will appear on screen for only a single frame, or, by default, 1/60th of a second. In fact, you'll notice this example has nothing at all inside <a href="/reference/#/p5/draw">draw()</a>, but it needs to be there to force P5 to keep listening for the events. If a <a href="/reference/#/p5/background">background()</a> function were run inside <a href="/reference/#/p5/draw">draw()</a>, the rectangles would flash onto the screen and disappear.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  fill(0, 102);
            +  background(204); // Draw once to give a little color
            +}
            +function draw() {
            +} // Empty draw() keeps the program running
            +function mousePressed() {
            +  rect(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <p>The code inside the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> and <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> event functions are run when there is a change in the mouse position. The code in the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> block is run at the end of each frame when the mouse moves and no button is pressed. The code in the <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> block does the same when the mouse button is pressed. If the mouse stays in the same position from frame to frame, the code inside these functions does not run. In this example, the gray circle follows the mouse when the button is not pressed, and the black circle follows the mouse when a mouse button is pressed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let dragX, dragY, moveX, moveY;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  fill(0);
            +  ellipse(dragX, dragY, 33, 33); // Black circle
            +  fill(153);
            +  ellipse(moveX, moveY, 33, 33); // Gray circle
            +}
            +function mouseMoved() {   // Move gray circle
            +  moveX = mouseX;
            +  moveY = mouseY;
            +}
            +function mouseDragged() { // Move black circle
            +  dragX = mouseX;
            +  dragY = mouseY;
            +}
            +      </script>
            +
            +      <!-- examples added for mouseOut() and mouseOver() -->
            +      <p>The <a href="/reference/#/p5/mouseOver">.mouseOver()</a> function is called once after every time a mouse moves onto the element. In this example, the diameter of the ellipse increase by 10 every time the mouse moves onto the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOver(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/mouseOut">.mouseOut()</a> function is called once after every time a mouse moves off the element. Similar to the above example, the diameter of the ellipse increase by 10 every time the mouse moves out of the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOut(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <h2>Wheel Events</h2>
            +      <p>The <a href="/reference/#/p5/mouseWheel">.mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners. The function accepts a callback function as argument which will be executed when the wheel event is triggered on the element. The <a href="/reference/#/p5/deltaY">event.deltaY</a> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <a href="/reference/#/p5/deltaX">event.deltaX</a> does the same as <a href="/reference/#/p5/deltaY">event.deltaY</a> except it reads the horizontal wheel scroll of the mouse wheel. On OS X with "natural" scrolling enabled, the <a href="/reference/#/p5/deltaY">event.deltaY</a> values are reversed.</p>
            +      <p>In this example, an event listener is attached to the canvas element, and function changeSize() would run when scrolling is performed on canvas. By using the <a href="/reference/#/p5/deltaY">event.deltaY</a> variable, scrolling up on canvas would increase the diameter of the ellipse and scrolling down would decrease the diameter. If scrolling is performed anywhere in any direction, the background is going to be darker.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseWheel(changeSize); // attach listener for activity on canvas only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with mousewheel movement anywhere on screen
            +function mouseWheel() {
            +  g = g + 10;
            +}
            +
            +// this function fires with mousewheel movement over canvas only
            +function changeSize(event) {
            +  if (event.deltaY > 0) {
            +    d = d + 10;
            +  }
            +  else {
            +    d = d - 10;
            +  }
            +}
            +      </script>
            +
            +      <h2>Key events</h2>
            +      <!-- keyTyped() added -->
            +      <p>Each key press is registered through the keyboard event functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyPressed">keyTyped()</a> and <a href="/reference/#/p5/keyReleased">keyReleased()</a>:</p>
            +      
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block is run one time when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is run one time when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is run one time when any key is released</li>
            +      </ul>
            +
            +      <p>Each time a key is pressed, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block is run once. Within this block, it's possible to test which key has been pressed and to use this value for any purpose. If a key is held down for an extended time, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block might run many times in a rapid succession because most operating systems will take over and repeatedly call the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. The amount of time it takes to start repeating and the rate of repetitions will be different from computer to computer, depending on the keyboard preference settings. In this example, the value of the boolean variable drawT is set from false to true when the T key is pressed; this causes the lines of code to render the rectangles in <a href="/reference/#/p5/draw">draw()</a> to start running.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +      </script>
            +
            +      <!-- added this information to distinguish keyPressed() and keyTyped() -->
            +      <p>When ASCII keys are pressed, the character is stored in the <a href="https://p5js.org/reference/#/p5/key">key </a>variable. However, this variable does not distinguish between uppercase and lowercase when used with the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. For this reason, it is recommended to use <a href="/reference/#/p5/keyTyped">keyTyped()</a>. When used with the <a href="/reference/#/p5/key">key</a> variable this function will recognize case. </p>
            +
            +      <p>Each time a key is released, the code inside the <a href="/reference/#/p5/keyReleased">keyReleased()</a> block is run once. The following example builds on the previous code; each time the key is released the boolean variable drawT is set back to false to stop the shape from displaying within <a href="/reference/#/p5/draw">draw()</a>.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +function keyReleased() {
            +  drawT = false;
            +}
            +      </script>
            +
            +      <h2>Event flow</h2>
            +      <p>As discussed previously, programs written with <a href="/reference/#/p5/draw">draw()</a> display frames to the screen sixty frames each second. The <a href="/reference/#/p5/frameRate">frameRate()</a> function is used to set a limit on the number of frames that will display each second, and the <a href="/reference/#/p5/noLoop">noLoop()</a> function can be used to stop draw() from looping. The additional functions <a href="/reference/#/p5/loop">loop()</a> and <a href="/reference/#/p5/redraw">redraw()</a> provide more options when used in combination with the mouse and keyboard event functions. If a program has been paused with <a href="/reference/#/p5/noLoop">noLoop()</a>, running <a href="/reference/#/p5/loop">loop()</a> resumes its action. Because the event functions are the only elements that continue to run when a program is paused with noLoop(), the loop() function can be used within these events to continue running the code in draw(). The following example runs the draw() function for about two seconds each time a mouse button is pressed and then pauses the program after that time has elapsed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let frame = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  if (frame > 120) {              // If 120 frames since the mouse
            +    noLoop();                     // was pressed, stop the program
            +    background(0);                // and turn the background black.
            +  }
            +  else {                          // Otherwise, set the background
            +    background(204);              // to light gray and draw lines
            +    line(mouseX, 0, mouseX, 100); // at the mouse position
            +    line(0, mouseY, 100, mouseY);
            +    frame++;
            +  }
            +}
            +function mousePressed() {
            +  frame = 0;
            +  loop();
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/redraw">redraw()</a> function runs the code in draw() one time and then halts the execution. It's helpful when the display needn't be updated continuously. The following example runs the code in draw() once each time a mouse button is pressed.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, 0, mouseX, 100);
            +  line(0, mouseY, 100, mouseY);
            +}
            +function mousePressed() {
            +  redraw(); // Run the code in draw one time
            +}
            +      </script>
            +
            +      <!-- event listener and callback functions explained??? -->
            +      <!-- This should probably be explained in a another tutorial more in-depth -->
            + <!--      Functions like mousePressed(), mouseClicked(), mouseReleased(), mouseMoved(), mouseOver(), and mouseOut() can be used as event listeners. They can be attached to certain elements</p>
            +      <p>Function|Boolean: function to be fired when mouse is pressed over the element. if false is passed instead, the previously firing function will no longer fire.</p>
            +      <p>In this example</p>
            +       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +-->
            +      <h2>Cursor icon</h2>
            +      <p>The cursor can be hidden with the <a href="/reference/#/p5/noCursor">noCursor()</a> function and can be set to appear as a different icon or image with the <a href="/reference/#/p5/cursor">cursor()</a> function. When the noCursor() function is run, the cursor icon disappears as it moves into the display window. To give feedback about the location of the cursor within the software, a custom cursor can be drawn and controlled with the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(7);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  ellipse(mouseX, mouseY, 10, 10);
            +}
            +      </script>
            +
            +      <p>If <a href="/reference/#/p5/noCursor">noCursor()</a> is run, the cursor will be hidden while the program is running until the <a href="/reference/#/p5/cursor">cursor()</a> function is run to reveal it.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor();
            +  }
            +  else {
            +    noCursor();
            +  }
            +}
            +      </script>
            +
            +      <p>Add a parameter to the cursor() function to change it to another icon or image. Either load and use image, or use the self-descriptive options are ARROW, CROSS, HAND, MOVE, TEXT, and WAIT.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor(HAND);  // Draw cursor as hand
            +  }
            +  else {
            +    cursor(CROSS); // Draw cursor as cross
            +  }
            +  line(mouseX, 0, mouseX, height);
            +  line(0, mouseY, height, mouseY);
            +}
            +      </script>
            +      <p>These cursor icons are part of your computer's operating system and will appear different on different machines.</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div>
            +  <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/p5-screen-reader.html b/dist/learn/p5-screen-reader.html
            new file mode 100644
            index 0000000000..055ae18c4d
            --- /dev/null
            +++ b/dist/learn/p5-screen-reader.html
            @@ -0,0 +1,604 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Using p5 with a screen reader</h1>
            +
            +      <p>
            +        This page introduces some of the screen reader friendly features of the p5js web editor, it provides an overview of accessible outputs, and examples and tutorials on how to get started with p5 when using a screen reader.
            +      </p>
            +      <p>
            +        p5.js is a library that starts with the original goal of Processing –to make to make coding accessible for artists, designers, educators, and beginners– and reinterprets it for the web using the metaphor of a software sketchbook with a set of drawing functionality. With p5.js we are able to draw in the canvas. The canvas is perhaps the most inaccessible element in HTML. The reason for this is simple: the canvas behaves just like a physical canvas, once you put paint on it, it covers up what’s behind it, making it hard to understand how the pixels comprise shapes and elements. Within the p5.js web editor it is possible to access the content of the canvas using a screen reader through text, a spatial table, and sound outputs.
            +      </p>
            +
            +
            +      <h2>What is the p5.js Web Editor</h2>
            +      <p>
            +        The p5.js web editor is a essentially a web page where you can type code in p5.js and run the code to view the output. It allows us to code in and for the browser. The web editor has features that make it screen reader friendly. You can access the <a href="http://editor.p5js.org/">p5 web editor here.</a>
            +      </p>
            +
            +      <h2>Pairings</h2>
            +      <p>
            +        Please note - the p5.accessibility library is currently not supported on MacOS.
            +      </p>
            +      <p>
            +        Using the p5.js web editor with a screen reader works better when you have one of the following screen reader/browser/operating system pairings:
            +      </p>
            +        <ul class="list_view">
            +          <li>NVDA and Firefox</li>
            +          <li>JAWS and Chrome</li>
            +        </ul>
            +
            +      <h2>Outputs</h2>
            +      <p>
            +        With a screen reader we can access the content of the canvas through the following outputs:
            +      </p>
            +
            +      <h3>Plain Text Output</h3>
            +      <p>
            +        This output describes the visual content present on the canvas in plain text.
            +      </p>
            +
            +      <h3>Table Output</h3>
            +      <p>
            +        The table output laids out the content of the canvas in the form of a table based on the spatial location of each element.
            +
            +      </p>
            +
            +      <h3>Sound Output</h3>
            +      <p>
            +        This mode explains the movement of the objects present in the canvas. Top to bottom movement is represented by a decrease in frequency and left to right through panning.
            +      </p>
            +
            +      <h2>How to select an output:</h2>
            +      <p>
            +        In the p5.js web editor there are two ways to select the accessible outputs that we want to make available.
            +      </p>
            +      <ol>
            +        <li>
            +          When we press the “play sketch, button” accessible to screen readers the “plain-text output” will automatically be available.
            +        </li>
            +        <li>
            +          If we want to access other outputs we should do the following:
            +          <ul class="list_view">
            +            <li>
            +              First, stop the sketch by pressing the “stop sketch, button” and go to “Settings”.
            +            </li>
            +            <li>
            +              Within settings we must find the “Accessibility” tab.
            +            </li>
            +            <li>
            +              In the “Accessibility” tab and under the “Accessible text-based canvas” section we can choose our preferred outputs.
            +            </li>
            +          </ul>
            +        </li>
            +      </ol>
            +      <p>
            +        Within “Settings” and under the “Accessibility” tab it is also possible to activate a lint warning sound that should make debugging easier. In “Settings” and under the  “General Settings” tab we can increase the size of the font and select a high contrast theme. After choosing our settings we can close the “Settings” window and go back to coding and playing our sketch.
            +      </p>
            +      <p>
            +        It is possible to add these accessible outputs to p5 sketches outside of the p5.js web editor by including the p5.accessibility.js library. <a  target="_blank" href="https://github.com/processing/p5.accessibility">You can learn more about the library here.</a>
            +      </p>
            +
            +      <h3>Keyboard Shortcuts</h3>
            +      <p>
            +        There are also ways to turn on the accessible outputs using keyboard shortcuts. Once we are on the code editor area we can use the following shortcuts (we have listed the shortcuts  for Windows computers, if you are using Mac OS please use the command key instead of control):
            +      </p>
            +      <ul class="list_view">
            +        <li>
            +          Shift + Control +1 - Turns on ALL the accessible output options, including audio
            +        </li>
            +        <li>
            +          Shift + Control +2 - Turns off ALL the accessible output options
            +        </li>
            +        <li>
            +          Control + Enter - This is used to run a sketch. If you already have accessibility options turned on, they will show up as well
            +        </li>
            +        <li>
            +          Shift + Control + Enter - This is used to stop a sketch.
            +        </li>
            +      </ul>
            +      <p>
            +        The full list of shortcuts is also available in the p5 web editor, under Keyboard Shortcuts in the Help and Feedback section of the menu
            +      </p>
            +
            +      <h1>Lessons</h1>
            +      <h2>Lesson 1: Hello World</h2>
            +      <p>
            +        In this section we go through some basic functions in p5 and look at how the screen reader will read the output.
            +
            +        There are two main functions we will use in our programs. The setup() function runs once, and is typically used for initialization, or for creating a program that does not need a loop running code repeatedly. The draw() function runs over and over again, and is used to perform a certain action repeatedly and for animation.
            +        Now we can open the editor: alpha.p5js.org and look for the code edit area. If you notice, there’s some code there already. Whenever you open the editor by default it will create a setup() function and a draw() function. However, for our first "Hello World" program we will take a step back and delete everything. Once we have a blank editor, we create a setup() block and add one line:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(200,200);
            +        }
            +      </code></pre>
            +
            +    <p>
            +      The createCanvas() function creates a canvas for us  to draw  or display the output. The canvas is the space on which the output is “drawn” or displayed. The code above creates a canvas of width and height 200 pixels. Since there is no movement, we will take a look only at the text and table outputs.
            +    </p>
            +    <h3>Text output for Lesson 1</h3>
            +    <p>
            +      Your output is a 200 by 200 white canvas containing the following 0 object
            +    </p>
            +    <h3>Table output for Lesson 1</h3>
            +    <p>
            +      white canvas is 200 by 200 of area 40000 contains 0 objects
            +    </p>
            +    <p>
            +      As expected, the outputs do not have any details apart from that of the canvas. Now, let’s move on to the next lesson where we add some basic shapes.
            +    </p>
            +
            +      <h2>Lesson 2: Basic Shapes</h2>
            +      <p>
            +        In this example, we will draw an ellipse on the top left, and a rectangle on the bottom right of the canvas of size 500 by 500 pixels. First, let's create the canvas and draw a shape in the setup function. Feel free to copy the code to the editor and run it.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        This code creates a canvas of 500 by 500 pixels and then draws an ellipse. The first 2 numbers we pass to the ellipse indicate where the center of the ellipse will be on the canvas. In this case, that is 50 and 50 pixels. The next 2 numbers indicate the width and height of the ellipse. In this case, they are both 20 pixels, implying we want to draw a circle. It is important to note that the top left corner of the canvas is point 0,0 pixels and the bottom right corner of the canvas is point 500,500 pixels.
            +      </p>
            +      <p>
            +        Now, we can also type this code a bit differently. We can create the canvas in the setup() function and draw the shape in the draw() function.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +        }
            +        function draw() {
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        In the previous case, the ellipse is drawn ONCE in setup and never again. But, in this case, the ellipse is drawn again and again in the canvas. Since, the numbers passed to the ellipse are the same each time, it doesn’t make a difference. However, if we wanted to change it’s position each time and make it move, then we would have to do it in draw.
            +      </p>
            +      <p>
            +        NOTE: remember, that everything in the canvas is drawn one over the other.
            +      </p>
            +      <p>
            +        In this case the output will be following:
            +      </p>
            +
            +      <h3>Text output for Lesson 2</h3>
            +      <p>
            +        The overview for the text output contains “Your output is a 500 by 500 white canvas containing the following 1 object:”.
            +      </p>
            +      <p>
            +        This description is followed by a list of elements where the shape, color, position, and area of each element are described (in this case: “white ellipse at top left covering 0.13% of the canvas” ). Each element can be selected to get more details. A table of elements is also provided. In this table, shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”).
            +      </p>
            +      <h3>Table output for Lesson 2</h3>
            +      <p>
            +        The overview for the table output contains “white canvas is 500 by 500 of area 250000 Contains 1 objects - 1 ellipse”
            +      </p>
            +      <p>
            +        This is followed by a table that describes the content spatially. It is a 10 by 10 table structure where each element is placed on a cell of the table depending on its position. Within each cell an element the color and type of shape of that element are available (example: “white ellipse”). These descriptions can be selected individually to get more details. A list of elements where shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”) is also available.
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rk4uO1bJX">basic shapes example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Lesson 3: Color</h2>
            +      <p>
            +        In these examples, we  look at different ways to add color to our sketch
            +        First, let’s look at ‘background()’. We can use this function to add a background color to the canvas. Copy the below code to try it out.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +      </code></pre>
            +      <p>
            +        Here, we have given the color in RGB format. In this format we can describe colors by saying how much, Red, Green and Blue the color has. RGB values must be integers between 0 and 255 with 0 being no color, and 255 highest amount of a certain color. The outputs will now contain “Red (255,0,0) canvas”.
            +      </p>
            +      <p>
            +        Now we can give color to our shapes using the function, fill().
            +      </p>
            +      <p>
            +        Copy the below code to try it out:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +
            +        function draw() {
            +          fill(200,50,8);
            +          ellipse(50,50,20,20);
            +          fill(20,250,8);
            +          ellipse(250,250,20,20);
            +          fill(20,150,250);
            +          ellipse(450,450,20,20);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now, in the plain text and grid output, we will notice that each shape is prepended with the color of the shape.
            +      </p>
            +
            +      <h3>Text output for Lesson 3</h3>
            +      <p>
            +        In the text output the overview is as follows
            +        “Your output is a 500 by 500 red(255,0,0) canvas containing the following 3 objects”
            +      </p>
            +      <p>
            +        After this we see the list of objects, with their color name and the RGB value. For example -  “crimson(200, 50, 8) ellipse at top left covering 0.13% of the canvas” Each object contains a link that when selected provides more details.
            +      </p>
            +
            +      <h3>Grid output for Lesson 3</h3>
            +      <p>
            +        The overview is as follows “red(255,0,0) canvas is 500 by 500 of area 250000 contains 3 0bjects - 3 ellipse”
            +      </p>
            +      <p>
            +        And in the table, we will find the objects in the grids corresponding to their location. “crimson(200,50,8) ellipse” and “green(20,250,8) ellipse”
            +      </p>
            +
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rJ-OSs-k7">color example on the p5 editor</a>
            +      </p>
            +
            +      <p>
            +        Instead of using Red, Green and Blue values, we can also pass just one value from 0 to 255. This is known as grayscale. It means that Red, Green and Blue will take the same value and the result will be between black and white. 0 being black, and 255 white.
            +      </p>
            +
            +      <h2>Lesson 4: Text</h2>
            +      <p>
            +        With p5, it is also possible to draw text on the canvas!
            +        We can add text to the canvas using the text() function. This function requires us input three values inside the parentheses: the text we want to display written between quotation marks, followed by the x and y position in pixels to display the text in the canvas.
            +      </p>
            +      <p>
            +        Copy and try out the below code.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(200);
            +        }
            +
            +        function draw() {
            +          fill(255,0,0);
            +          text("hello world!", 50,50)
            +        }
            +      </code></pre>
            +      <p>
            +        Note that fill() also affects text() and that the text we want to write has to be written between quotation marks. Now, let’s go through the output to see what it says.
            +      </p>
            +
            +      <h3>Text output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows  :
            +        “Your output is a 500 by 500 grey(200,200,200) canvas containing the following 1 object”
            +      </p>
            +      <p>
            +        Then there is a list of the objects. (For example - “hello world!” (red(255,0,0)) at top left of the canvas
            +      </p>
            +
            +      <h3>Grid output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows:
            +        “grey(200,200,200) canvas is 500 by 500 of area 250000 contains 1 object - 1 text”
            +      </p>
            +      <p>
            +        And in the table you will see the actual text and it’s color in the appropriate location (example - “hello world! (red(255,0,0))”
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/r1BFz3Zkm">text example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Exercise: Bar Graph</h2>
            +      <p>
            +        Now that we have covered how to draw basic shapes and write text on the canvas, let’s look at how we can create a bar chart with them.
            +      </p>
            +      <p>
            +        Using rectangles and some numbers, we can create bar graphs. Since we expect the entire sketch to be static, we can do the whole thing in the setup function
            +      </p>
            +      <p>
            +        Let’s start with a sample dataset that we want to depict.
            +      </p>
            +      <p>Animals in the park:</p>
            +      <ul class="list_view">
            +        <li>Dogs - 260</li>
            +        <li>Cats - 300</li>
            +        <li>Hamsters -100</li>
            +        <li>Rabbits - 50</li>
            +        <li>Spiders - 10</li>
            +      </ul>
            +
            +      <p>
            +        First we create a canvas:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        createCanvas(500,500);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now we can add some rectangles that represent each animal type. Notice that we will be adding comments in our code. Comments are lines in our code that are not executed and can be notes to ourselves. They start with // in the beginning of the line. We will create 5 rectangles, one for each animal type.
            +      </p>
            +
            +      <p>
            +        Remember that when we draw a rectangle, the first 2 values indicate the top left of the rectangle. If we want our bar graph to start on the left of our canvas, we need to calculate the numbers based on that. If we decide to make each bar with 50 pixels height, and to make the width represent the number of animals, for our first rectangle that represents the number of dogs the width would be 260 because there are 260 dogs. Then the values for this rectangle would be (0,0,260,50).
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	//We will use the fill() function to add color to the first bar of our chart.
            +        fill(255,0,0);
            +        //In this case our color is 255 red, 0 green, 0 blue.
            +        	rect(0, 0, 260, 50);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now let’s add the corresponding text:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	//Remember that the function text() requires the text, and the x, and y values for its position
            +        }
            +      </code></pre>
            +      <p>
            +        And voila! We just added the first bar on our graph chart.
            +      </p>
            +
            +      <h3>Text output for Bar Graph 1</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 2 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now lets add rectangles to represent 300 cats, 100 hamsters, 50 rabbits, and 10 spiders. Remember that the values for the function rect() in our case should be: rect(0, y position, number of animals, 50).
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	rect(0, 100, 300, 50); // here the second value, y position, is 100 so that we can draw the second bar under the first bar.
            +        	text('Cats - 300', 0, 175);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        The text output would be:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 2</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(red(255, 0, 0)) at top left</li>
            +      </ul>
            +      <p>
            +        Now we can add different colors to each bar:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	fill(0,255,0);
            +        	rect(0, 100, 300, 50);
            +        	text('Cats - 300', 0, 175);
            +        	fill(0,0,255);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	fill(200,100,0);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	fill(0,200,200);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +      <p>
            +        Our bar graph is ready! Here is the output:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 3</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>green(0, 255, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(green(0, 255, 0)) at top left</li>
            +        <li>blue( 0, 0, 255) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(blue( 0, 0, 255)) at top left</li>
            +        <li>orange(200, 100, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(orange(200, 100, 0)) at top left</li>
            +        <li>cyan( 0, 200, 200) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(cyan( 0, 200, 200)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now that we created a graph together you should be able to do it by yourself and share the results with your friends!
            +      </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/program-flow.html b/dist/learn/program-flow.html
            new file mode 100644
            index 0000000000..eb81ae6238
            --- /dev/null
            +++ b/dist/learn/program-flow.html
            @@ -0,0 +1,580 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This tutorial is written by Alex Yixuan Xu with reference to <em>Getting Started With p5.js</em> by Lauren McCarthy, Casey Reas, and Ben Fry. Copyright 2016 Maker Media, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">MDN JavaScript documentation</a> and <a href="https://www.w3schools.com/js">W3Schools JavaScript tutorials</a>. If you see any errors or have comments, please <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Program Flow</h1>
            +      <!-- TOPICS -->
            +      <!-- Branching: if/else -->
            +      <!-- Loops: for/while loop -->
            +      <!-- noLoop(), loop() and redraw() -->
            +      <!-- Asynchronicity in p5.js: intro to loadImage(), preload(), callbacks -->
            +      <!-- Loading JSON & APIs -->
            +      <!-- Functions and Callbacks: list of functions -->
            +      <!-- Interactivity and Event Listeners: list of event listeners such as mousePressed() -->
            +
            +
            +
            +      <!-- https://docs.microsoft.com/en-us/scripting/javascript/controlling-program-flow-javascript -->
            +      <p>This tutorial outlines some various techniques for controlling the sequence and timing of events in your code, which is known as program flow.</p>
            +
            +      <!-- if/else stuff -->
            +      <h2>Branching</h2>
            +      <!-- https://www.w3schools.com/js/js_if_else.asp -->
            +      <p>We can use conditional statements to control the program flow. Conditional statements perform different actions based on tests for different conditions. JavaScript has the following conditional statements:</p>
            +      <ul class="list_view">
            +        <li>Use <em>if</em> to specify a block of code to be executed, if a specified condition is true</li>
            +        <li>Use <em>else</em> to specify a block of code to be executed, if the same condition is false</li>
            +        <li>Use <em>else if</em> to specify a new condition to test, if the first condition is false</li>
            +      </ul>
            +      <p>In the following example, change the value for variable i to change the color of the rectangle. If i equals to 0, the condition for the <em>if</em> statement is satisfied, and the filling color is red. In this case, the program continues to draw the rectangle skipping the <em>else if</em> and <em>else</em> statements. If i equals to 1, the condition for the <em>if</em> statement is not satisfied, and the program moves on to check the condition for the <em>else if</em> statement. Since <em>else if</em> condition is satisfied, the filling color is green. If neither the <em>if</em> nor the <em>else if</em> conditions are satisfied, the program runs the <em>else</em> statement, and the filling color is blue.</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0; // change the value of i to see the change
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  background(200);
            +  if (i==0){
            +    fill(255, 0, 0);
            +  }
            +  else if (i==1){
            +    fill(0, 255, 0);
            +  }
            +  else{
            +    fill(0, 0, 255);
            +  }
            +  rect(width/2, height/2, 50, 50);
            +}
            +      </script>
            +
            +      <!-- for loop and while loop -->
            +      <h2>Loops</h2>
            +      <p>Loops can execute a block of code repeatedly. p5 supports several different kinds of loops in JavaScript:</p>
            +      <ul class="list_view">
            +        <li>for - loops through a block of code a specified number of times</li>
            +        <li>for/in - loops through the properties of an object</li>
            +        <li>while - loops through a block of code while a specified condition is true</li>
            +        <li>do/while - also loops through a block of code while a specified condition is true</li>
            +      </ul>
            +
            +      <p>The <em>for</em> loop sets up a variable (usually i or x) that is then incrementally changed for each loop. It has the following structure:</p>
            +      <pre><code class="language-javascript">
            +        for (statement 1; statement 2; statement 3) {
            +            code block to be executed
            +        }
            +      </code></pre>
            +      <ul class="list_view">
            +        <li>Statement 1 is executed (one time) before the execution of the code block. It sets the starting value for the variable</li>
            +        <li>Statement 2 defines the condition that must be true for the code block to be executed.</li>
            +        <li>Statement 3 is executed every time  after the code block has finished running if statement 2 evaluated to be true.</li>
            +      </ul>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  for (let i=0; i<5; i++){
            +    text(i, i*10, height/2);
            +  }
            +}
            +      </script>
            +      <p>In this example, variable i is initially set to 0. Every time the <em>for</em> loop runs, i is displayed on the screen and 1 is added to i. Note the <em>for</em> loop will only run until i equals to 4 because after this the condition that i be less than 5 will be false.</p>
            +
            +      <p>The <em>for/in</em> statement loops through the properties of an object:</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let person = {fname:"John", lname:"Doe", age:25};
            +let myText = "";
            +function setup(){
            +  let x;
            +  for (x in person) {
            +      myText += person[x];
            +      myText += " ";
            +  }
            +  text(myText, 0, height/2);
            +}
            +      </script>
            +      <p>In this example, as the <em>for</em> loop cycles through each property of the person object, the property value is added to myText string.</p>
            +
            +      <p>The while loop cycles through a block of code as long as its specified condition is true.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  while (i<5){
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +}
            +      </script>
            +      <p>This example gives the same result as the <em>for</em> loop example above. Sometimes <em>while</em> loops and <em>for</em> loops can be used interchangeably.</p>
            +
            +      <p>The <em>do/while</em> loop is a variant of the <em>while</em> loop. This loop will execute the code block once, before checking if the condition is true, it will then repeat the loop as long as the condition is true.</p>
            +      <!-- Is there an example particular to do/while? -->
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  do {
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +  while (i < 5);
            +}
            +      </script>
            +
            +
            +      <!-- this is particular to p5 -->
            +      <h2>noLoop(), loop() and redraw()</h2>
            +      <p>The <a href="/reference/#/p5/draw">draw()</a> function in p5 runs as a loop. The code inside the draw() function runs continuously from top to bottom until the program is stopped. The draw() loop may be stopped by calling <a href="/reference/#/p5/noLoop">noLoop()</a>, and can then be resumed with <a href="/reference/#/p5/loop">loop()</a>. If using <a href="/reference/#/p5/noLoop">noLoop()</a> in <a href="/reference/#/p5/setup">setup()</a>, it should be the last line inside the block.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(200);
            +  ellipse(x, height/2, 20, 20);
            +  x ++;
            +}
            +function mousePressed() {
            +  loop();
            +}
            +function mouseReleased() {
            +  noLoop();
            +}
            +        </script>
            +        <p>In this example, <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a>, so the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. Since <a href="/reference/#/p5/loop">loop()</a> is placed in <a href="/reference/#/p5/mousePressed">mousePressed()</a>, the draw() block will resume looping when mouse is pressed. When mouse is released, <a href="/reference/#/p5/noLoop">noLoop()</a> is called again and hence the draw() loop stops.</p>
            +
            +        <p>The function <a href="/reference/#/p5/redraw">redraw()</a> executes the code within <a href="/reference/#/p5/draw">draw()</a> one time. This functions allows the program to update the display window only when necessary, such as when an event registered by <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/keyPressed">keyPressed()</a> occurs. In structuring a program, it only makes sense to call <a href="/reference/#/p5/redraw">redraw()</a> within events such as <a href="/reference/#/p5/mousePressed">mousePressed()</a> outside of the draw() loop. The redraw() function does not work properly when called inside draw(). In addition, you can set the number of loops through draw by adding a single argument (an integer) to the redraw() function.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +   createCanvas(100, 100);
            +   noLoop();
            + }
            +function draw() {
            +   background(200);
            +   ellipse(x, height/2, 20, 20);
            +   x ++;
            + }
            +function mousePressed() {
            +   redraw();
            + }
            +      </script>
            +      <p>This example is similar to the previous one, where <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a> and the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. However, when mouse is pressed, <a href="/reference/#/p5/redraw">redraw()</a> is called and <a href="/reference/#/p5/draw">draw()</a> will only loop once. To make smooth animations, it is easier to work with noLoop() and loop().</p>
            +
            +
            +      <h2>Asynchronicity in p5.js</h2>
            +      <p>In JavaScript, events may occur concurrently with the main program flow. This is considered as asynchronicity in programming. In p5, for example, when we use <a href="/reference/#/p5/loadImage">loadImage()</a> in <a href="/reference/#/p5/setup">setup()</a>, the browser begins the process of loading the image but skip onto the next line before it is finised loading. The following example demonstrates such asynchronicity.</p>
            +        <pre><code class="language-javascript">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +    </code></pre>
            +    <iframe src="/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.html" width="150" height="150"></iframe>
            +      <!-- what's the file location??????????????????? -->
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p>When you run this program, you'll notice that the drawing canvas is grey with no image displayed. This is because <a href="/reference/#/p5/loadImage">loadImage()</a> begins to load the image, but does not have time to finish this task before the program continues on through the rest of <a href="/reference/#/p5/setup">setup()</a> and on to <a href="/reference/#/p5/draw">draw()</a>. Even with the <a href="/reference/#/p5/noLoop">noLoop()</a> function that stops p5.js from continuously executing the code within draw(). The <a href="/reference/#/p5/image">image()</a> function is unable to display the image as it is not properly loaded.</p>
            +
            +      <h2>Introduction to Preload</h2>
            +      <p>To help with this issue of asynchronicity, p5.js has the <a href="/reference/#/p5/preload">preload()</a> function. Unlike <a href="/reference/#/p5/setup">setup()</a>, preload() forces the program to wait until everything has loaded before moving on. It is best to only make load calls in preload(), and do all other setup in setup().</p>
            +      <pre><code class="language-javascript">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.html" width="150" height="150"></iframe>
            +
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p><a href="/reference/#/p5/preload">preload()</a> ensures that the image has been loaded before running the other code. </p>
            +
            +
            +
            +      <h2>Loading with a Callback</h2>
            +      <p>An alternative to <a href="/reference/#/p5/preload">preload()</a> is to use a <em>callback function</em>. A callback function is a function that is passed as an argument to a second function, and that runs after the second function has completed. The following example illustrates this technique.</p>
            +      <pre><code class="language-javascript">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.html" width="150" height="150"></iframe>
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </script> -->
            +      <p>In this example, the second argument in <a href="/reference/#/p5/loadImage">loadImage()</a> is the function we want to run after the load is complete. Once the image has loaded, this callback function, drawImage(), is automatically called. It has one argument which contains the image that was just loaded. There is no need to create a global variable to hold the image. The image is passed directly into the callback function, as the parameter name chosen in the function definition.</p>
            +
            +
            +
            +      <h2>Loading JSON & APIs</h2>
            +      <!-- page 187 -->
            +      <p>The JSON (JavaScript Object Notation) format is a common system for storing data. Like HTML and XML formats, the elements have labels associated with them. One way to load JSON file is to use <a href="/reference/#/p5/loadJSON">loadJSON()</a> function in <a href="/reference/#/p5/preload">preload()</a>.</p>
            +      <!-- example where loadJSON() in preload() -->
            +      <p>The following request at https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson returns data of recent earthquakes in the world from USGS.</p>
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let earthquakes;
            +function preload(){
            +  earthquakes = loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson');
            +}
            +function setup(){
            +  createCanvas(200, 100);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +
            +      <p>Alternatively, <a href="/reference/#/p5/loadJSON">loadJSON()</a> can also take a callback. To use data from an API, you may need a callback function as, like with an image, the data takes time to load. API (Application Programming Interface) requests are commands that request data from a service. A lot of APIs will return data in JSON format. Some need you to authenticate with the API to use it (e.g. register as a developer and get keys). You can’t always use <a href="/reference/#/p5/preload">preload()</a> when getting data from APIs because the data might change while you sketch is running and you will want your program to respond accordingly.</p>
            +
            +      <p><a href="/reference/#/p5/loadJSON">loadJSON()</a> can be used in a few ways: </p>
            +      <ul class="list_view">
            +        <li>loadJSON(path)</li>
            +        <li>loadJSON(path, callback)</li>
            +        <li>loadJSON(path, callback, datatype)</li>
            +        <li>loadJSON(path, callback, errorCallback)</li>
            +        <li>loadJSON(path, datatype, callback, errorCallback)</li>
            +        <li>loadJSON(path, jsonpOptions, datatype, callback, errorCallback)</li>
            +      </ul>
            +      <p>
            +        where:
            +      </p>
            +      <ul class="list_view">
            +        <li>path - String: name of the file or url to load</li>
            +        <li>jsonpOptions - Object: options object for jsonp related settings</li>
            +        <li>datatype - String: "json" or "jsonp"</li>
            +        <li>callback - Function: function to be executed after loadJSON() completes, data is passed in as first argument</li>
            +        <li>errorCallback - Function: function to be executed if there is an error, response is passed in as first argument</li>
            +      </ul>
            +      <!-- example where loadJSON() takes a callback -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(200, 100);
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +      <p>In this example, the <a href="/reference/#/p5/loadJSON">loadJSON()</a> function is placed in <a href="/reference/#/p5/setup">setup()</a> and takes a custom callback function showEarthquake(). This means when the program finishes loading the JSON file from the USGS earthquakes API, the function showEarthQuake() is called. The place and magnitude of the most recent earthquake listed by the API is stored in local variables within showEarthquake and are then displayed on the screen.</p>
            +
            +      <p>Sometimes we use <a href="/reference/#/p5/setInterval">setInterval()</a> to control the frequency of requests made to the API. setInterval() can also take a callback function. If you call setInterval() in <a href="/reference/#/p5/setup">setup()</a>, it will run repeatedly for the duration of the program at the interval set.</p>
            +      <!-- example setInterval() is used -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let i=1; // counter variable to keep track of the interval
            +function setup() {
            +  createCanvas(200, 100);
            +  getEarthquake();
            +  setInterval(getEarthquake, 5000); // get data every 5 seconds
            +}
            +function getEarthquake(){
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  background(255);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text("Data grabbed "+i, 0, height/3);
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +  i++;
            +}
            +      </script>
            +      <p>In this example, the earthquake data is grabbed from the API every 5 seconds and is displayed on the screen.</p>
            +
            +
            +
            +
            +      <!-- list the functions that accept callbacks? Is this section necessary?-->
            +      <h2>More Callback Functions</h2>
            +      <p>In addition to the <a href="/reference/#/p5/loadImage">loadImage()</a>, <a href="/reference/#/p5/loadJSON">loadJSON()</a> and <a href="/reference/#/p5/setInterval">setInterval()</a>, there are other functions in p5 that accept callbacks. Typically, functions that involve loading data of some kind accept callbacks, or should be put in <a href="/reference/#/p5/preload">preload()</a>. For example:</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/loadFont">loadFont()</a></li>
            +        <li><a href="/reference/#/p5/loadSound">loadSound()</a></li>
            +        <li><a href="/reference/#/p5/loadStrings">loadStrings()</a></li>
            +        <li><a href="/reference/#/p5/loadTable">loadTable()</a></li>
            +        <li><a href="/reference/#/p5/loadXML">loadXML()</a></li>
            +        <li><a href="/reference/#/p5/loadBytes">loadBytes()</a></li>
            +        <li><a href="/reference/#/p5/loadModel">loadModel()</a></li>
            +      </ul>
            +
            +      <p>DOM functionality makes it easy to interact with other HTML5 objects, including text, hyperlink, image, input, video, audio, and webcam. Some DOM creation methods also accept callbacks: </p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/createImg">createImg()</a></li>
            +        <li><a href="/reference/#/p5/createFileInput">createFileInput()</a></li>
            +        <li><a href="/reference/#/p5/createVideo">createVideo()</a></li>
            +        <li><a href="/reference/#/p5/createAudio">createAudio()</a></li>
            +        <li><a href="/reference/#/p5/createCapture">createCapture()</a></li>
            +      </ul>
            +
            +
            +      <h2>Interactivity and Event Listeners</h2>
            +      <p>Callback functions are functions that can be passed as an argument into another function and be executed after the first function is complete. An event listener or handler is a type of callback. It is called whenever an event occurs such as when the mouse is pressed, or a key is pressed etc.</p>
            +      <p>Mouse functions like <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, etc. can be used as event listeners. They can be attached to certain elements in a sketch.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseWheel">mouseWheel()</a> - Code inside this block is run once when mouse wheel is scrolled over the element</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>In this example, a canvas element is created and an event listener <a href="/reference/#/p5/mousePressed">mousePressed()</a> is attached. Function changeGrey() will only run when the mouse is pressed over the canvas, and will will change the background color to a random grey. If the mouse is pressed anywhere, even outside of the canvas, the diameter of the ellipse will increase by 10 pixels. The custom function changeGray(), in this instance, is placed within the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function and is to be triggered when mouse is pressed over the canvas element. If the mouse is not pressed, false is passed and changeGrey() will not run.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +
            +      <p>The above mouse functions can be attached to an element like the canvas or can be used without specifying an element. The keyboard functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyReleased">keyReleased()</a>, <a href="/reference/#/p5/keyTyped">keyTyped()</a>, and mouse function <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> cannot be attached to a specific element.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block runs once when the mouse is moved and the mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block runs once when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is runs once when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is runs once when any key is released</li>
            +      </ul>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/tdd.html b/dist/learn/tdd.html
            new file mode 100644
            index 0000000000..325108207e
            --- /dev/null
            +++ b/dist/learn/tdd.html
            @@ -0,0 +1,660 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Unit Testing and Test Driven Development</h1>
            +      <div class="attribution">
            +        This tutorial was written by <a href='https://github.com/andrewjtimmons'>Andy Timmons</a>.
            +      </div>
            +
            +      <h2>Overview</h2>
            +      <p>
            +        This tutorial will walk you through setting up your development environment to run unit tests against your code. Unit testing is a method of applying tests to the classes and functions in your code. It can catch bugs, help you collaborate with others, and code faster. Test driven development is a method of writing your tests before you write code so you have all of your tests when you finish.
            +      </p>
            +      <p>
            +        This tutorial is intended for people who:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>Have written p5.js sketches before.</li>
            +          <li>Are comfortable using javascript <a href='http://p5js.org/examples/structure-functions.html'>functions.</a></li>
            +          <li>Can run basic terminal commands.  If you are not familiar using a terminal here is a <a href='http://lifehacker.com/5633909/who-needs-a-mouse-learn-to-use-the-command-line-for-almost-anything'>good tutorial for getting comfortable.</a></li>
            +        </ul>
            +
            +      <h2> Why unit test?</h2>
            +      <p>
            +        In late 1998 NASA launched the Mars Climate Orbiter in collaboration with Lockheed Martin. This robotic space probe cost 193 million dollars and took one year to arrive and establish its orbit around Mars. Minutes later it crashed into Mars and exploded. NASA later determined it was a software error. The Lockheed Martin navigation code gave measurements in English units like feet, and the NASA code expected the measurements to be in metric units like meters. The difference between the two caused the crash. [<a href='https://en.wikipedia.org/wiki/Mars_Climate_Orbiter'>Citation</a>]
            +      </p>
            +      <p>
            +        Unit testing could have prevented this error and while you might not be launching spaceships (but by all means please try), unit testing can prevent a lot of headaches from the outset of your project to install day. It can help you:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>improve your design and reduce bugs</li>
            +          <li>collaborate with others</li>
            +          <li>finish your project faster</li>
            +        </ul>
            +
            +      <h2>Setting up for unit testing</h2>
            +      <p>
            +        Installing node:
            +      </p>
            +        <ol>
            +          <li>First you must install node. If you already have node installed this assumes you are using version 4 or higher.  Node is a open source runtime environment for building server side applications.  Don’t worry if that sentence didn’t make sense.  You don’t have to understand all there is to know about node to do this tutorial.  If you are curious to learn more you can read the <a href='https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io'>p5.js node tutorial.</a></li>
            +          <li>On Mac, Linux, Windows:  Go to <a href='https://nodejs.org/en/'>https://nodejs.org/en/</a> and download the installer.  Open the installer and follow the directions.</li>
            +          <li>
            +            Once the installer finishes open a terminal and run the following command to verify it installed correctly.  You should see something like "v6.6.0" or some other numbers that indicate the version you installed.<br />
            +            <pre><code class="language-javascript">
            +            node -v
            +            </code></pre>
            +          </li>
            +        </ol>
            +      <p>
            +        Update npm, the Node Package Manager.  Npm is a program that allows you to install software libraries that are compatible with node.  In your open terminal run the command:
            +        <pre><code class="language-javascript">
            +          sudo npm install npm@latest -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the chai assertion library.  This is what you will use to build your tests.  In the terminal window run the command:
            +        <pre><code class="language-javascript">
            +          npm install chai -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the mocha test running library.  Mocha drives your chai tests.  Much like a person drives a car.  In the terminal window run:
            +        <pre><code class="language-javascript">
            +          npm install mocha -g
            +        </code></pre>
            +      </p>
            +
            +      <h2>A sketch without tests</h2>
            +      <p>
            +        Your goal today is to make a sketch with a square whose fill color loops over every RGB color.
            +      </p>
            +      <p>
            +        Let’s set up the project. This is what it would look like without any unit tests.
            +      </p>
            +        <ol>
            +          <li>Make a folder called color_unit_test and open it</li>
            +          <li>
            +            Make a file called index.html and type the following code.  While you can just copy/paste it, typing it out will help you understand what it is doing better.  It is worth the time!<br />
            +            <pre><code class="language-javascript">
            +              &lt;!DOCTYPE html&gt;
            +              &lt;html&gt;
            +              &lt;head&gt;
            +                &lt;meta charset="UTF-8"&gt;
            +                &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
            +                &lt;script src="https://cdn.jsdelivr.net/npm/p5@0.4.20/lib/p5.js"&gt;&lt;/script&gt;
            +                &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +                &lt;style&gt; body {padding: 0; margin: 0;} &lt;/style&gt;
            +              &lt;/head&gt;
            +              &lt;body&gt;
            +              &lt;/body&gt;
            +              &lt;/html&gt;
            +            </code></pre>
            +          </li>
            +          <li>
            +            make a file called sketch.js and put in the following code<br />
            +            <pre><code class="language-javascript">
            +              // This is for a unit test tutorial.
            +              // it should create a rectangle and allow you to iterate over
            +              // every single color.
            +              //
            +              // colorValueIncrease sets the amount the color changes on each
            +              // draw loop. Values greater than 255 will break the sketch.
            +              // fillColor will be the color of the rectangle.
            +              // colorIncreaser will become an instance of our ColorIncreaser class.
            +
            +              let colorValueIncrease = 1;
            +              let fillColor;
            +              let colorIncreaser;
            +
            +              function setup() {
            +                createCanvas(500, 500);
            +                background(0);
            +                fillColor = color(0, 0, 0, 255);
            +                noStroke();
            +              }
            +
            +              function draw() {
            +                fill(fillColor);
            +                rect(0, 0, 500, 500);
            +
            +                // increment the red value
            +                fillColor.levels[0] += colorValueIncrease;
            +                // If the red value is maxed out increment the green value
            +                // and reset the red value.
            +                if (fillColor.levels[0] > 255) {
            +                  fillColor.levels[0] = 0;
            +                  fillColor.levels[1] += colorValueIncrease;
            +                }
            +                // If the green value is maxed out increment the blue value
            +                // and reset the green value.
            +                if (fillColor.levels[1] > 255) {
            +                  fillColor.levels[1] = 0;
            +                  fillColor.levels[2] += colorValueIncrease;
            +                }
            +                // If the blue value is maxed out reset the green value.
            +                if (fillColor.levels[2] > 255) {
            +                  fillColor.levels[2] = 0;
            +                }
            +              }
            +            </code></pre>
            +          </li>
            +          <li>
            +           Open the index.html file in your browser (you don’t need to run a local server in this case). You should see a black box become red and then black again. This is the basis of looping over all the RGB colors. The problem you face is that there are 256 values for red, green, and blue, which means there are over 16 million combinations of colors! You can make this faster. However, making this faster will cause flashing lights which might give some people headaches or seizures. Please only increase this value if you do not have issues with flashing lights. The rest of the tutorial should be fine.  In the sketch.js file change the<pre><code class="language-javascript">let colorValueIncrease = 33;</code></pre> and reload the page. However this still doesn’t guarantee this is working properly. You don’t have time to watch all the colors change nor can you tell yourself if it is iterating through the millions of colors. Change the colorValueIncrease variable back to 1 before you move on.
            +          </li>
            +          <li>
            +            At 30 draw loops per second it would take over six days to loop through all of the colors. You certainly don’t have time to do that once, and would never be able to check and see if it worked every time you updated our code. What if you accidentally change something in our draw loop that breaks the code right before install?  You wouldn’t know until it was live and everyone saw your sketch break.
            +          </li>
            +        </ol>
            +
            +      <h2>Your first unit tests</h2>
            +      <p>
            +        Unit testing can help us out here. The majority of the time spent in this program is the actual drawing of the pixels. Adding 1 and checking a few if statements is very fast if you don’t need to draw the actual pixels. So you can check if the color values increase as expected without having to actually watch them all increase on your screen.
            +      </p>
            +      <p>
            +        In the folder called color_unit_test that you already created, make a new folder called test.  Open the test folder and make a file called test.js.  Type this code into test.js
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +
            +
            +          // Create the variable you are going to test
            +          let p5js = 'awesome';
            +
            +
            +          // describe lets you comment on what this block of code is for.
            +          describe('these are my first tests for p5js', function() {
            +
            +
            +            // it() lets you comment on what an individual test is about.
            +            it('should be a string', function(done) {
            +              // expect is the actual test.  This test checks if the var is a string.
            +              expect(p5js).to.be.a('string');
            +              // done tells the program the test is complete.
            +              done();
            +            });
            +
            +
            +            it('should be equal to awesome', function(done) {
            +              // This expect tests the value of the string.
            +              expect(p5js).to.equal('awesome');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your command line and <a href='http://ss64.com/bash/cd.html'>cd</a> into the main directory of our sketch called color_unit_test.  Type the command
            +        <pre><code class="language-javascript">mocha</code></pre>
            +      </p>
            +      <p>
            +        into the command line and watch your first test run!  You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              ✓ should be a string
            +              ✓ should be equal to awesome
            +            2 passing (14ms)
            +        </code></pre>
            +      </p>
            +      <p>
            +        Let's look at what happens when tests fail. Change line 6 in test.js from:
            +        <pre><code class="language-javascript">let p5js = 'awesome';</code></pre>
            +      </p>
            +      <p>
            +        to
            +        <pre><code class="language-javascript">let p5js = 42;</code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your terminal and run the mocha command again. You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              1) should be a string
            +              2) should be equal to awesome
            +
            +            0 passing (18ms)
            +            2 failing
            +
            +            1) these are my first tests for p5js should be a string:
            +               AssertionError: expected 42 to be a string
            +                at Context.<anonymous> (test/test.js:14:24)
            +
            +            2) these are my first tests for p5js should be equal to awesome:
            +               AssertionError: expected 42 to equal 'awesome'
            +                at Context.<anonymous> (test/test.js:21:21)
            +        </code></pre>
            +      </p>
            +      <p>
            +        What is nice about these errors is:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>They tell you the name of the test that you put in the describe() and it() functions</li>
            +          <li>They tell you what they expected with AssertionError: expected 42 to be a string</li>
            +          <li>They tell you what file and line of code had the problem test/test.js:14:24</li>
            +        </ul>
            +      <p>
            +        Now that you know the basics of unit testing you are ready to write some tests against your code and refactor your sketch!
            +      </p>
            +
            +      <h2>Test Driven Development</h2>
            +      <p>
            +        You are going to use Test Driven Development for the rest of this tutorial.  The idea is you write your unit tests first, run them and watch them fail, and then add code to sketch.js to make the tests pass.  This way you ensure your code is working as you expect every step of the way and that new code doesn’t break old code.  Your goal is to create a ColorIncreaser class that:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>takes in an integer as the value to increase each time called colorValueIncrease.</li>
            +          <li>takes in an instance of the <a href='http://p5js.org/reference/#/p5/color'>p5 color class.</a></li>
            +          <li>has a function to increase the values in the color by the value in colorValueIncreases.</li>
            +        </ul>
            +      <p>
            +        Delete everything in test.js and replace it with this
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +          // Import our ColorIncreaser class.
            +          const ColorIncreaser = require('../sketch');
            +
            +          describe('ColorIncreaser tests', function() {
            +            // Will hold the reference to the ColorIncreaser class
            +            let colorIncreaser;
            +
            +            // beforeEach is a special function that is similar to the setup function in
            +            // p5.js.  The major difference it that this function runs before each it()
            +            // test you create instead of running just once before the draw loop
            +            // beforeEach lets you setup the objects you want to test in an easy fashion.
            +            beforeEach(function() {
            +                colorIncreaser = new ColorIncreaser();
            +            });
            +
            +            it('should be an object', function(done) {
            +              expect(colorIncreaser).to.be.a('object');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command in your terminal and watch your new test fail!  The crux of the error is “TypeError: ColorIncreaser is not a constructor”.  This makes sense because you have not created a ColorIncreaser class in our sketch yet. <br />
            +
            +        Go to the bottom of your sketch.js file, below the closing bracket } for the draw function, and add this:
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor() {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +            }
            +          }
            +
            +          module.exports = ColorIncreaser;
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  The function line will be our color increasing object.  The module.exports line is what allows our test.js file to import our ColorIncreaser with the line you already added that looks like this:
            +        <pre><code class="language-javascript">
            +           const ColorIncreaser = require('../sketch');
            +        </code></pre>
            +      </p>
            +      <p>
            +        If you go back to your terminal and run mocha your test should pass.<br />
            +
            +        Now get your ColorIncreaser function to actually do something.  Start by storing the colorValueIncrease as a variable in your class.  Before you change the code in sketch.js you have to write your tests.  Change the beforeEach function in test.js to look like this
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        and add a new it() test below it like this
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command and you will get the pivotal line:<br />
            +        AssertionError: expected undefined to equal 1<br />
            +        because you have not added this to your class yet. You need to add that value to get this to work. Add this line to the setup function in sketch.js under noStroke();
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +        </code></pre>
            +        and change the ColorIncreaser function to look like this
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser() {
            +            constructor(colorValueIncrease) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +            }
            +          }
            +        </code></pre>
            +        Let’s run the mocha test again.  It should pass!
            +      </p>
            +
            +      <h2>Testing when your object is composed of other objects</h2>
            +      <p>
            +        Now you need to add an instance of the p5 color class to our ColorIncreaser. However, for your tests, you don’t want to use an actual instance of the color() class because you don’t want to test external dependencies given by another library.You just want to make sure that your increment function works. So you are going to create what is called a mock of the p5 color class so you can test without worrying about the implementation of code you didn’t write.
            +      </p>
            +      <p>
            +        The original way of incrementing colors just used the color.levels and changed the red, green and blue values at index [0], [1], and [2].  You can see this in the draw function in sketch.js.  The implementation of color just stores those values in a javascript array so you can mock it out very easily.  Put this code in test.js below the const ColorIncreaser = require… line and above the describe line
            +        <pre><code class="language-javascript">
            +          function mockColor(red, green, blue, alpha) {
            +              // Mock of the color class from p5
            +              this.levels = [];
            +              this.levels[0] = red;
            +              this.levels[1] = green;
            +              this.levels[2] = blue;
            +              this.levels[3] = alpha;
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Update your beforeEach() function
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              let fillColor = new mockColor(0, 0, 0, 255);
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And update the it('should initialize without mutation', function block
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[3]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And run the tests!  Failure!   TypeError: Cannot read property 'levels' of undefined<br />
            +        You have to update the ColorIncreaser class to take in a fillColor variable.  It is an easy fix.  In sketch.js change the colorIncreaser line in setup() to look like this
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +        </code></pre>
            +      </p>
            +      <p>
            +        and update the ColorValueIncreaser function
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor(colorValueIncrease, fillColor) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +              this.fillColor = fillColor;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Run the tests again and they should pass!
            +      </p>
            +      <p>
            +        Now you have all the initialized variables you need to make the class work.  This provides the scaffold on which you will build your method to increase the color value and iterate over every color.
            +      </p>
            +
            +      <h2>Testing class methods</h2>
            +      <p>
            +        You are going to make a class method called increaseFillColor. It will basically run the code that is currently in our draw loop, but use the values stored in our ColorIncreaser class to do it.
            +      </p>
            +      <p>
            +        As covered before there are 256 values for red, green and blue giving 16,777,216 color combinations. While that might seem overwhelming you can test it easily because you know what values should be present in red, green and blue after each time you call our increaseFillColor function. For example if you start with the color black with the rgb levels 0,0,0 and you call increaseFillColor once you know you should now have the values 1,0,0.  So you are going to add tests in test.js for calling increaseFillColor 255, 65535 and 16777215 times.
            +        <pre><code class="language-javascript">
            +          it('should have rgb values 255, 0, 0 after calling increaseFillColor 255 times', function(done) {
            +            //it is 256^1 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 255; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 0 after calling increaseFillColor 65535 times', function(done) {
            +            //it is 256^2 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 65535; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 255 after calling increaseFillColor 16777215 times', function(done) {
            +            //it is 256^3 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 16777215; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And when you run mocha the tests will fail because that function does not exist!  Let’s add a skeleton function in sketch.js inside the ColorIncreaser class below the constructor function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Now when you run mocha the tests fail for a different reason.  It finds the function, but it doesn’t do what you expect it to.  Let’s change the function in sketch.js to look like what is inside the draw function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +
            +            this.fillColor.levels[0] += this.colorValueIncrease
            +            this.numColorsSoFar += 1
            +
            +
            +            if (this.fillColor.levels[0] > 255) {
            +              this.fillColor.levels[0] = 0
            +              this.fillColor.levels[1] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[1] > 255) {
            +              this.fillColor.levels[1] = 0
            +              this.fillColor.levels[2] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[2] > 255) {
            +              this.fillColor.levels[2] = 0;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        And now your tests pass!  Hooray!<br />
            +        Now you just need to get the draw function set up.  Replace the draw function in sketch.js with this:
            +        <pre><code class="language-javascript">
            +          function draw() {
            +            fill(colorIncreaser.fillColor);
            +            rect(0, 0, 500, 500);
            +            colorIncreaser.increaseFillColor()
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        All tests should pass now and you can expect your code to behave as you want!  As a bonus when you change the code in the future the tests will let you know that it still works as intended!<br />
            +        Congratulations, you made it to the end! Unit tests and Test Driven Development are powerful ways to build code that you know works just as you expect. <br />
            +        You can continue to build on your skills by
            +      </p>
            +        <ul class="bullet-list">
            +          <li>adding tests to your own sketches and projects</li>
            +          <li>Reading up on the tools we’ve used here:</li>
            +          <ul class="bullet-list">
            +            <li><a href='http://www.agiledata.org/essays/tdd.html'>Test Driven Development and Unit tests</a></li>
            +            <li><a href='https://www.npmjs.com/'>Node Package Manager (NPM)</a></li>
            +            <li><a href='http://chaijs.com/'>Chai</a></li>
            +            <li><a href='https://mochajs.org/'>Mocha</a></li>
            +            <li><a href='https://en.wikipedia.org/wiki/Mock_object'>Mock Objects</a></li>
            +          </ul>
            +        </ul>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/test-tutorial.html b/dist/learn/test-tutorial.html
            new file mode 100644
            index 0000000000..b65cd9ba8b
            --- /dev/null
            +++ b/dist/learn/test-tutorial.html
            @@ -0,0 +1,178 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>test tutorial title</h1>
            +
            +      <p>Blah blah blah. Here is some formatted code:</p>
            +
            +      <pre><code class="language-javascript">
            +      var note = "this is formatted code!";
            +      </code></pre>
            +
            +      <p>Blah blah blah. Here is an iframe embedded:</p>
            +
            +      <iframe src="../assets/learn/test-tutorial/embed.html" width="600" height="400"></iframe>
            +
            +      <p>Blah blah blah. Here is p5-widget embedded:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +
            +function draw() {
            +  background(255, 0, 200);
            +}
            +</script>
            +
            +      <p>The end!</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/transformations.html b/dist/learn/transformations.html
            new file mode 100644
            index 0000000000..6ae38439e6
            --- /dev/null
            +++ b/dist/learn/transformations.html
            @@ -0,0 +1,615 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by Gene Kogan. It was ported to P5 by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +
            +      </div>
            +
            +      <h1>Transformations</h1>
            +
            +      <p>
            +      The p5.js canvas works like a piece of graph paper. When you want to draw something, you specify its coordinates on the graph. For example, we can draw a 40x40 pixel rectangle at the point (30, 30).
            +      </p>
            +
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      If you want to move your rectangle 50 pixels to the right and 50 pixels down, you can add that to the x and y-coordinates of the rectangle and run rect(80, 80, 40, 40). But there is another way to do this:
            +      move the graph paper itself. If you move the graph paper 50 pixels right and 50 pixels down, you will get exactly the same visual result. Moving the coordinate system is called translation, and can be done using the translate() function.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	translate(50, 50);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      As far as the rectangle is concerned, it hasn't moved at all. Its upper left corner is still at (30, 70). When you use transformations, the things you draw never change position; the coordinate system itself does. We will see how this can be useful in the next section.
            +    </p>
            +      <h2>push() and pop()</h2>
            +
            +      <p>
            +      Sometimes, a sketch will involve multiple translations to draw the same thing in different locations. If we want to draw the same rectangle in three separate locations -- say at (25, 25), (50, 75), and (75, 100) -- we can use push() and pop() to
            +      keep track of and revert our translations as we go. The function pop() undoes all translations made following the previous push(). push() and pop() also track and revert style and,  color changes -- fill(), stroke(), etc -- in the same way. Thus all translations
            +      and style/color commands made between a single push() and pop() apply only to the operations made between them. Take a look at the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw() {
            +	background(240);
            +
            +	push();
            +  	translate(25, 25);
            +	fill(255, 0, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(75, 100);
            +	fill(0, 255, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(50, 75);
            +	fill(0, 0, 255);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +}
            +      </script>
            +
            +      <p>
            +      The first triangle in red is drawn at (0, 0) after the coordinate system has been translated to the right and down by 25 pixels each. After the first pop() is called, the first translation is undone and the coordinate (0, 0) reverts back to the top-left corner of the canvas.
            +      We call push() and translate(75, 100), now moving the the canvas 75 pixels right and 100 pixels done, and then draw the green rectangle. The second pop() undoes that translation as well. Finally, the blue triangle is done after making the same operation, this time translating 50 pixels right and 75 pixels down.
            +    </p>
            +
            +      <h2>What's the Advantage</h2>
            +
            +      <p>In the last sketch, we could have achieved the same visual output by simply drawing the rectangles at those exact points. Or we could have used translate() without the push() and pop() blocks by undoing each translation manually, e.g. translate(-25, -25) to undo the first translation of (25, 25).</p>
            +      <p>For simple shapes like rectangles, it is easier to not use translations, but rather to specify the points manually. But when we begin to draw more complex shapes, translations become advantageous. Let's take a look at an example where translate(), push(), and pop() are really useful.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +	for (var x = 5; x < 150; x = x+25){
            +		for (var y = 5; y < 200; y = y+25){
            +			push();
            +			translate(x, y);
            +	  		drawHouse();
            +			pop();
            +		}
            +	}
            +}
            +
            +function drawHouse() {
            +	triangle(7.5, 0, 0, 7.5, 15, 7.5);
            +	rect(0, 7.5, 15, 12.5);
            +	rect(6, 15, 5, 5);
            +}
            +      </script>
            +
            +      <p>
            +      In this example, we draw a grid of houses. Instead of having to keep track of the coordinates for every vertex of every house, we simply have one function, drawHouse() which draws a house relative to the point (0, 0). We then create a loop which will translate to the correct point before drawing each house.
            +      </p>
            +
            +      <p>
            +      Using the transformations command allows us to use a single drawing function irrespective of where we intend to draw it on the canvas, while push() and pop() allow us to reserve transformations only to the relevant code blocks.
            +      </p>
            +
            +      <h2>Rotation</h2>
            +
            +      <p>
            +      In addition to translating the grid, you can also rotate it with the rotate() function. This function takes one argument, the angle of rotation. It then rotates the canvas around the origin point (0, 0). It's as though you have a piece of graph paper, place your finger on the point (0, 0), and then rotate the paper around your finger.
            +      </p>
            +
            +      <p>Angle is measured clockwise with zero being at 3 o'clock. In p5.js, all the functions having to do with angles take radians. A single rotation or a full circle has 360° or 2π radians. Here is a diagram of how p5.js measures angles in degrees (black) and radians (red).</p>
            +
            +      <img src="../assets/learn/transformations/angles.png" style="width:150px;">
            +
            +      <p>Since most people think in degrees, p5.js has a built-in radians() function which takes a number of degrees as its argument and converts it to radians for you. It also has a degrees() function that converts radians to degrees. Take a look at the following example which rotates the canvas by an angle measurement set by the mouseX position.
            +      The red square is drawn before rotation, and the green one after rotation.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw() {
            +	var deg = mouseX;
            +	var rad = radians(deg);
            +
            +	background(240);
            +
            +	// the red rectangle is drawn before the rotation so
            +	// it will stay in place
            +	fill(255, 0, 0);
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 50);
            +
            +	fill(0, 255, 0);
            +	text("rotate "+floor(deg)+" degrees", 50, 25);
            +
            +	// rotation is done here. all subsequent drawing
            +	// is done post-rotation
            +	rotate(rad);
            +
            +	// draw the grid
            +	drawGrid();
            +
            +	// the green rectangle and grid is drawn after rotating the canvas
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 500);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +    fill(120);
            +	for (var x=-2*width; x < 2*width; x+=40) {
            +		line(x, -2*height, x, 2*height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-2*height; y < 2*height; y+=40) {
            +		line(-2*width, y, 2*width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <h2> Rotating in place</h2>
            +
            +      <p>In the last example, the green square goes off the screen as we rotate the canvas more. Sometimes we want to be able to rotate a shape in place, rather than around the top-left corner of the screen. We can do this by combining translate() and rotate() together. Recall that translate() moves the origin (0,0) to another place in the canvas and that rotate() rotates the canvas around the origin.
            +        Thus if we want to draw a shape in the middle of the screen and then rotate it in place, we should first translate the canvas to the point we want to draw the shape, then rotate, then draw the shape at (0, 0). Take a look at the following example.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +        <p>If you want the rectangle to rotate around its own center point rather than by its corner, we can use the command rectMode(CENTER) to set p5.js to interpret the coordinates of rectangles to refer to the center of the rectangle rather than the top-left corner. The following example is the same as the previous one but with centered coordinates.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +	rectMode(CENTER);	// now the first two arguments of a rect are its center point, not corner
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +      <p>Here is a program that generates a wheel of colors by using rotation, and draws a strip every 25 frames.</p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	background(240);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	// the modulo operator % calculates the remainder.
            +	// example: 24 % 25 = 24, 25 % 25 = 0, 26 % 25 = 1, etc.
            +	// thus this if statement will evaluate True every 25 frames.
            +	if (frameCount % 25 == 0) {
            +		fill(random(255), random(255), random(255));
            +		push();
            +		translate(75, 100);
            +		rotate(radians(frameCount));
            +		rect(0, 0, 100, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +        <h2>Rotational Symmetry</h2>
            +
            +        <p>
            +        Let's take a look at a more complicated example where we can use translate and rotate together to create interesting symmetries around the center of the canvas. Let's first build it by drawing 8 squares which are evenly distributed along a circle around the center of the canvas. What we do is we first translate to the center of the screen, translating the canvas by (width/2, height/2).
            +        We then rotate the canvas to the 8 angles evenly distributed between 0 and 2π radians. We then draw a circle 50 pixels away from the center, after each of these rotations.
            +        </p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		rect(50, 0, 10, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +      <p>
            +        Look at the line rect(50, 0, 10, 10). Recall that you can draw a shape in the same place by translating to it first and then drawing it at (0, 0). So we can do another another translation after we've rotated, to translate along the right-pointing line after it's been rotated. So we can replace the statement rect(50, 0, 10, 10) with the following two: translate(50, 0) and rect(0, 0, 10, 10).
            +        By doing so, we bring the pivot point or origin of the canvas to each of the eight rectangles we just drew.
            +      </p>
            +
            +      <p>
            +        This is convenient because now we can do something even more interesting. Instead of simply drawing a rectangle at each of those points, let's create another loop which will draw six smaller squares evenly distributed around a small circle around each of these new pivot points. See the following.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		translate(50, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			rect(15, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <p>
            +        Now that we have achieved an interesting geometry, we can embellish this program by making a variable for the first translation amount and for the x-position of the rectangle, and modulating them in interesting ways. In the following example, we'll modulate those two values using Perlin noise. If you haven't used Perlin noise before, take a look at the tutorial on Perlin noise.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		var tx = 100 * noise(0.01*frameCount);
            +		translate(tx, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			var rx = 30 * noise(0.01*frameCount + 10);
            +			rect(rx, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +      <p>Now we're getting somewhere! Let's take the previous example and make the following additions to it to make it even more interesting.</p>
            +
            +      <p>
            +        <ul class="list_view">
            +          <li>Extra rotation variables so the whole circle rotates with perlin noise</li>
            +          <li>Red + Blue = Purple</li>
            +          <li>Additional noisy in-place rotation of the drawn shapes</li>
            +          <li>Noisy modulation of the size of the shapes being drawn</li>
            +        </ul>
            +      </p>4
            +
            +      <p>All the noisy variables will be calculated at the top of the draw loop for better organization. Looks cool, right?!</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +	fill(0, 50);
            +	stroke(255, 50);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var ang1 = TWO_PI * noise(0.01*frameCount + 10);
            +	var ang2 = TWO_PI * noise(0.01*frameCount + 20);
            +	var ang3 = TWO_PI * noise(0.01*frameCount + 30);
            +	var rx = 30 * noise(0.01*frameCount + 40);
            +	var tx = 100 * noise(0.01*frameCount + 50);
            +	var size1 = 100 * noise(0.01*frameCount + 60);
            +	var size2 = 20 * noise(0.01*frameCount + 60);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(ang1 + TWO_PI * i / 8);
            +		translate(tx, 0);
            +		rect(0, 0, size1, size1);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(ang2 + TWO_PI * j / 6);
            +			translate(rx, 0);
            +			rotate(ang3);
            +			rect(rx, 0, size2, size2);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <h2>Scaling</h2>
            +
            +      <p>
            +        There is one more function which transforms the coordinate system, and that is scale(). Scale changes the size of the grid by multiplying the coordinate system. See the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var scaleAmount = mouseX / 100;
            +  	scale(scaleAmount);
            +
            +	drawGrid();
            +  	fill(255, 255, 0);
            +  	rect(20, 20, 50, 50);
            +}
            +
            +function drawGrid() {
            +	fill(0);
            +	stroke(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/trigonometry.html b/dist/learn/trigonometry.html
            new file mode 100644
            index 0000000000..0bb4004b6b
            --- /dev/null
            +++ b/dist/learn/trigonometry.html
            @@ -0,0 +1,189 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <h2>Trigonometry Primer</h2>
            +      <p>(learning to love triangles)</p>
            +      <div class="attribution">
            +        This tutorial was written during the first p5.js developers conference by Tega Brain.
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="pythagoras">Pythagoras Theorum</h3>
            +      <div class="info">
            +        <p>Trigonometry is a branch of geometry that is fundamental to all graphics programming.  It provides useful equations that enable you to figure out distances between points and how curves and circles can be described in Cartesian coordinates. Remember Cartesian coordinates are points described by x and y values. Trigonmetry also enables you to do things like move shapes in circular motion or oscillate values smoothly back and forth between two extremes.</p>
            +
            +
            +        <p>The right angled triangle is one of the most important parts of trigonometry and Pythagoras was a guy who got pretty famous for figuring out a theorem that relates the length of each of its sides. Pythagora figured out that in every right hand triangle, if you square each of the two shortest sides, their sum equals the square of the longest side.</p>
            +        <img class="image" src="../assets/learn/trigonometry/images/pythagoras1.jpg" />
            +
            +        <p>Right angled triangles are special also because each of their angles has a specific relationship to the ratio between the length of two of their sides. This is what sine, cosine and tangent functions describe. Sin cos and tan are known as trigonometric functions and they give us the relationship between the ratio of two of the triangle’s sides and one of the angles of the triangle. You may recall the acronym: SOH-CAH-TOA that helps you remember how sinθ, cosθ and tanθ relate to the ratio of which of the triangle’s sides.</p>
            +        <img class="image" src="../assets/learn/trigonometry/images/hypotenuse.jpg" />
            +        
            +        <p>This is all pretty great, because is means that with just a couple of pieces of information about a right angled triangle, like knowing two of its side lengths or maybe knowing one of its angle and a side length, you can use Pythagora’s theorem in combination with the sin, cos and tan equations to figure out everything else.</p>
            +
            +        <p>These triangles are also helpful as they help us to map and understand the x and y coordinates of points along curves and circles. Notice how in the drawing below you can see how any point on a circle will have a relationship to a right angled triangle. This relationship means that a point on a circle can be understood in two ways. Firstly, as we have seen a point can be described by Cartesian coordinates which are of course, by x and y co-ordinates, but it can also be described using polar coordinates. Polar coodinates are an angle and a distance from the origin (the radius of the circle).</p>
            +        <img class="image" src="../assets/learn/trigonometry/images/polar.jpg" />
            +      </div>
            +        
            +      <h3 class = "start-element tutorial-btn" id="Polar Coordinates">Polar Coordinates</h3>
            +      <div class="info">
            +        <p>Polar coordinates describe a point using an angle and a distance from the origin. This is useful when you are coding something like an analog clock. When drawing a clock, you would need to place each hand at a particular angle, for example, 3pm is at zero degrees and midday is at 90 degrees. Each hand would be coded as a line drawn onto a screen, that connects two points. So these hand would connect the origin to the x,y coordinates that is at the position of the time. Putting anything on a screen always requires you to describe it in terms of x and y.</p>
            +        
            +        <p>So how do we convert between polar coordinates and x-y coordinates?</p>
            +        
            +        <p>The relationship between polar coordinates and x,y coordinates can be calculated using a unit circle. This is a circle that has a radius of 1 unit which is useful because it means the hypotenuse in your right angled triange is always 1.</p>
            +
            +        <iframe src="../assets/learn/trigonometry/unitCircle/embed.html" width="600" height="400"></iframe>
            +
            +
            +      </div>
            +      
            +      <h3 class="start-element tutorial-btn" id="sin">Using Sin and Cosine</h3>
            +      <div class="info">
            +        <iframe src="../assets/learn/trigonometry/sincoscurves/embed.html" width="800" height="750"></iframe>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/learn/tutorial-guide.html b/dist/learn/tutorial-guide.html
            new file mode 100644
            index 0000000000..e1cc4408a0
            --- /dev/null
            +++ b/dist/learn/tutorial-guide.html
            @@ -0,0 +1,262 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Guide to contributing p5.js tutorials</h1>
            +      <div class="attribution">
            +        This tutorial was written by Tega Brain.
            +      </div>
            +      <p>
            +        We invite educators, contributors and general enthusiasts to contribute p5js tutorials. The p5js project makes creative coding and open source development more accessible to a diverse community and we are excited to publish tutorials on all aspects of the development process. Our learning materials so far include guides on learning p5, programming technique and how to contribute to an open source project.
            +      </p>
            +      <p>
            +        We welcome new written tutorial contributions and this guide outlines the steps of how to propose, prepare and contribute.
            +      </p>
            +
            +      <h2>How to get started:</h2>
            +      <ul class="list_view">
            +        <li>
            +          Check that your proposed topic has not already been covered. There is <a href="https://docs.google.com/spreadsheets/d/1sh3IwcCUY4Bm8N4fRZw6CwSDdQmmXgY_awjVj-UC8mo/edit#gid=0">a working spreadsheet here</a>
            +          that outlines in progress tutorials. If your topic is listed as in progress, perhaps you can add to work being done and contribute to preparing existing work for publication so please reach out to us.
            +        </li>
            +        <li>
            +          If your topic is not already covered and is not listed as in progress, please write a few sentences on what you propose to cover and email us this description at education@p5js.org.
            +        </li>
            +      </ul>
            +      <h2>How to prepare a p5js tutorial for publication online:</h2>
            +      <p>
            +        When your tutorial is ready for publication, please follow these steps to prepare your content for the p5js website.
            +      </p>
            +      <p>
            +        Prepare the content of your tutorial as a tutorial-name.hbs file with <a href="https://github.com/mayaman/p5js-website/blob/master/src/templates/pages/learn/test-tutorial.hbs">this basic structure</a>
            +        . As is shown in this file, it must contain a header as shown below:
            +      </p>
            +      <img src="../assets/learn/tutorial-guide/images/screenshot-1.png" alt="Screenshot">
            +
            +      <p>
            +        The folder containing your tutorial will be placed in the 'tutorials' folder of the p5js site. The file called index.hbs is the<a href="/learn/">p5.js tutorials landing page,</a>
            +         and the test-tutorial.hbs file is the test tutorial.
            +      </p>
            +      <p>
            +        All content should go in the:
            +       
            +        &lt;section &gt; &lt;/section&gt;
            +        tags on the page, with formatting defined by the &lt;h1&gt; and &lt;h2&gt; tags, the &lt;p&gt; paragraph tags as is done shown on the<a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs">test tutorial page.</a></p>
            +      <p>
            +        If your tutorial contains images, they are to be placed in the assets folder of the p5 site, in the location src/assets/learn/test-tutorial/images as shown below.
            +      </p>
            +      <img src="../assets/learn/tutorial-guide/images/screenshot-2.png" alt="Screenshot">
            +      <p>
            +        To correctly format code in the html of the page use the tag:
            +      </p>
            +       
            +        <pre><code class="language-javascript">
            +&lt;pre&gt;&lt;code class="language-javascript"&gt;
            +Your code here!
            +&lt;/code>&lt;/pre&gt;
            +
            +</code></pre>
            +
            +      <h2>Embedding p5.js sketches</h2>
            +      <p>
            +        Using p5js means you can illustrate your tutorial with animated, interactive or editable code examples to demonstrate programming concepts. Your examples should be prepared as p5.js sketches and can be embedded into the tutorial in two ways.
            +      </p>
            +
            +      <ol>
            +        <li>
            +          If the example is to be editable like in <a href="http://p5js.org/reference/#/p5/ellipse">the reference pages</a> of the p5js site, the p5 sketch should be embedded into the html page using the p5js widget. Follow <a href="https://toolness.github.io/p5.js-widget/">this guide </a>on how to embed p5js sketches using the widget written by <a href="https://github.com/toolness">Toolness</a>. You can also explore this in action on the<a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs"> test tutorial page</a>.</li>
            +        <li>
            +          If the example is to be animated and/or interactive but not editable. The p5.js sketch should be embedded into the page as an iframe as described below.
            +        </li>
            +      </ol>
            +
            +      <h2>Embed a p5 sketch using an iframe</h2>
            +
            +      <p>
            +        An iframe is like creating a window through which you can explore another page, sandboxed from the rest of your page. In this case it will be a window to the index.html containing your p5.js sketch.
            +      </p>
            +      <img src="https://github.com/tegacodes/p5.js-education/raw/master/images/iframe-2.jpg" alt="tutorialFileStructure" width="600">
            +
            +      <p>
            +        Put your p5 sketches in the /src/assets/learn folder of the site, in a folder labelled with the name of your sketch as shown in the screenshot. This is where all the images and p5 sketches linked by iframe should be stored.
            +      </p>
            +
            +      <img src="../assets/learn/tutorial-guide/images/screenshot-3.png" alt="Screenshot">
            +
            +<p>In the subfolders containing your p5 examples there should be a sketch.js file and the embed.html file for the sketch.</p>
            +<img src="../assets/learn/tutorial-guide/images/screenshot-4.png" alt="Screenshot">
            +
            +<p>Make sure your embed.html file has the correct paths to the p5 libraries of the site. If your file structure is the same as above, the path to the p5.js library should be "../../../js/p5.min.js".</p>
            +<p>You can then embed the p5js index files as iframes in the .hbs file that contains your tutorial content. The embed code for the iframe would then be:</p>
            +  <pre><code class="language-javascript">
            +&lt;iframe src="http://p5js.org/assets/learn/tes-tutorial/embed.html" width="600" height="400"&gt;
            +&lt;/iframe&gt;
            +</code></pre>
            +
            +<p>Styling for the iframe (this could directly into the post or in a stylesheet):</p>
            +  <pre><code class="language-javascript">
            +&lt;style&gt; iframe{ border: none; } &lt;/style&gt;
            +</code></pre>
            +
            +<p>Here you can find the naked sketch running: </p>
            +<a href="http://staging.p5js.org/assets/learn/test-tutorial/embed.html">http://staging.p5js.org/assets/learn/test-tutorial/embed.html</a>
            +
            +<p>And here it is embedded in the p5 site using the code below:  </p>
            +<a href="http://staging.p5js.org/learn/test-tutorial.html">http://staging.p5js.org/learn/test-tutorial.html</a>
            +
            +<p>One thing to note is that you need to manually set the size of the iframe, so it works best if things are a standard size.</p>
            +
            +<p>Also note that the links to the p5.js library files do not happen from the .eps page with all the tutorial content. Instead they will be located in the html page that is rendering your sketch (in this case, called embed.html).</p>
            +
            +<p>More information on embedding p5.js sketches can be found <a href="https://github.com/processing/p5.js/wiki/Embedding-p5.js">here.</a></p>
            +<h2>Finishing up</h2>
            +<p>Once your have finished writing your tutorial and your content has been given the thumbs up. Fork the p5.js website repository, prepare your content as described above and then issue a pull request to the p5.js website repository so we can publish your contribution!</p>
            +
            +    <p>Thank you!</p>
            +
            +  </main>
            +
            +  
            +  <footer>
            +    <h2 class="sr-only">Credits</h2>
            +    <p>
            +      p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +    </p>
            +  </footer>
            +
            +</div> <!-- end column-span -->
            +
            +
            +<!-- outside of column for footer to go across both -->
            +
            +<p class="clearfix"> &nbsp; </p>
            +
            +<object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +</object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/libraries/index.html b/dist/libraries/index.html
            new file mode 100644
            index 0000000000..33571bdfdc
            --- /dev/null
            +++ b/dist/libraries/index.html
            @@ -0,0 +1,932 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">libraries | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="libraries-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>Libraries</h1>
            +
            +      <h2>Using a library</h2>
            +
            +      <p>A p5.js library can be any JavaScript code that extends or adds to the p5.js core functionality. There are two categories of libraries. Core libraries (<a
            +          href="/reference/#/libraries/p5.sound">p5.sound</a>) are part of the p5.js distribution, while contributed libraries are developed, owned, and maintained by members of the p5.js community.</p>
            +
            +      <p>To include a library in your sketch, link it into your HTML file, after you have linked in p5.js. An example HTML file might look like this:</p>
            +      <pre><code class="language-markup">&lt;!doctype html&gt;
            +&lt;html>
            +&lt;head>
            +  &lt;script src="p5.js"&gt;&lt;/script&gt;
            +  &lt;script src="p5.sound.js"&gt;&lt;/script&gt;
            +  &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +&lt;/head&gt;
            +&lt;body&gt;
            +&lt;/body&gt;
            +&lt;/html&gt;
            +      </code></pre>
            +
            +      <h2>Create Your Own</h2>
            +
            +      <p>p5.js welcomes libraries contributed by others! Check out the
            +        <a href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +          libraries tutorial</a>
            +        for more specifics about how to create one.
            +        <a href="https://docs.google.com/forms/d/e/1FAIpQLSdWWb95cfvosaIFI7msA7XC5zOEVsNruaA5klN1jH95ESJVcw/viewform"
            +          target="_blank">If you have created a library and would like to have it included on this page, submit this form!</a></p>
            +
            +      
            +      
            +      <h2 class="tutorial-title">Core Libraries</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="/reference/#/libraries/p5.sound" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.sound.jpg">
            +              <h3>p5.sound</h3>
            +            </a>
            +          </div>
            +          <p>p5.sound extends p5 with Web Audio functionality including audio input, playback, analysis and synthesis. Created by:
            +            <a href="https://www.jasonsigal.cc/"
            +              target="_blank">Jason Sigal</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/processing/p5.accessibility" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.accessibility.jpg">
            +              <h3>p5.accessibility</h3>
            +            </a>
            +          </div>
            +          <p>p5.accessibility makes the p5 canvas more accessible to people who are blind and visually impaired. 
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +      
            +      <h2 class="tutorial-title">Community Libraries</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/asciiart" target="_blank">
            +              <img alt="" src="../assets/img/libraries/asciiart.jpg">
            +              <h3>asciiart</h3>
            +            </a>
            +          </div>
            +          <p>p5.asciiart is a simple and easy to use image - to - ASCII art converter for p5js. Created by:
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://itpnyu.github.io/p5ble-website/" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.ble.jpg">
            +              <h3>p5.ble</h3>
            +            </a>
            +          </div>
            +          <p>A Javascript library that enables communication between BLE devices and p5 sketches. Created by:
            +            <a href="https://1023.io"
            +              target="_blank">Yining Shi</a>, <a href="https://www.jingwen-zhu.com/"
            +              target="_blank">Jingwen Zhu</a>, <a href="https://tigoe.com/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/sarahgp/p5bots" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.bots.jpg">
            +              <h3>p5.bots</h3>
            +            </a>
            +          </div>
            +          <p>With p5.bots you can interact with your Arduino (or other microprocessor) from within the browser. Use sensor data to drive a sketch; use a sketch to drive LEDs, motors, and more! Created by:
            +            <a href="http://www.sarahgp.com"
            +              target="_blank">Sarah Groff-Palermo</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Lartu/p5.clickable" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.clickable.jpg">
            +              <h3>p5.clickable</h3>
            +            </a>
            +          </div>
            +          <p>Event driven, easy-to-use button library for p5.js. Created by:
            +            <a href="https://www.lartu.net"
            +              target="_blank">Martín del Río</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/p5.cmyk.js" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.cmyk.js.jpg">
            +              <h3>p5.cmyk.js</h3>
            +            </a>
            +          </div>
            +          <p>CMYK ColorSpace Created by:
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.collide2D" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.collide2D.jpg">
            +              <h3>p5.collide2D</h3>
            +            </a>
            +          </div>
            +          <p>p5.collide2D provides tools for calculating collision detection for 2D geometry with p5.js. Created by:
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.npmjs.com/package/p5.createloop" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.createloop.jpg">
            +              <h3>p5.createloop</h3>
            +            </a>
            +          </div>
            +          <p>Create animation loops with noise and GIF exports in one line of code. Created by:
            +            <a href="https://www.piratesjustar.com/"
            +              target="_blank">Peter Hayman</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Smilebags/p5.dimensions.js" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.dimensions.jpg">
            +              <h3>p5.dimensions</h3>
            +            </a>
            +          </div>
            +          <p>p5.dimensions extends p5.js' vector functions to work in any number of dimensions. Created by:
            +            <a href="https://github.com/Smilebags"
            +              target="_blank">Smilebags</a>, <a href="https://github.com/max0410"
            +              target="_blank">Max Segal</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/freshfork/p5.EasyCam" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.EasyCam.jpg">
            +              <h3>p5.EasyCam</h3>
            +            </a>
            +          </div>
            +          <p>Simple 3D camera control with inertial pan, zoom, and rotate. Major contributions by Thomas Diewald. Created by:
            +            <a href="https://jwilliamdunn.com"
            +              target="_blank">jWilliam Dunn</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/loneboarder/p5.experience.js" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.experience.jpg">
            +              <h3>p5.experience</h3>
            +            </a>
            +          </div>
            +          <p>Extensive library for p5.js that adds additional event-listening functionality for creating canvas-based web applications. Created by:
            +            <a href="https://github.com/loneboarder"
            +              target="_blank">Felix Meichelböck</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-func" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.func.jpg">
            +              <h3>p5.func</h3>
            +            </a>
            +          </div>
            +          <p>p5.func is a p5 extension that provides new objects and utilities for function generation in the time, frequency, and spatial domains. Created by:
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.geolocation" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.geolocation.jpg">
            +              <h3>p5.geolocation</h3>
            +            </a>
            +          </div>
            +          <p>p5.geolocation provides techniques for acquiring, watching, calculating, and geofencing user locations for p5.js. Created by:
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://charlie-roberts.com/gibber/p5-gibber/" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.gibber.jpg">
            +              <h3>p5.gibber</h3>
            +            </a>
            +          </div>
            +          <p>p5.gibber provides rapid music sequencing and audio synthesis capabilities. Created by:
            +            <a href="https://charlie-roberts.com"
            +              target="_blank">Charlie Roberts</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jagracar/grafica.js" target="_blank">
            +              <img alt="" src="../assets/img/libraries/grafica.js.jpg">
            +              <h3>grafica.js</h3>
            +            </a>
            +          </div>
            +          <p>grafica.js lets you add simple but highly configurable 2D plots to your p5.js sketches. Created by:
            +            <a href="https://jagracar.com/p5jsSketches.php"
            +              target="_blank">Javier Graciá Carpio</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bitcraftlab/p5.gui" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.gui.jpg">
            +              <h3>p5.gui</h3>
            +            </a>
            +          </div>
            +          <p>p5.gui generates a graphical user interface for your p5.js sketches. Created by:
            +            <a href="https://www.bitcraftlab.com/"
            +              target="_blank">Martin Schneider</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.localmessage" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.localmessage.jpg">
            +              <h3>p5.localmessage</h3>
            +            </a>
            +          </div>
            +          <p>p5.localmessage provides a simple interface to send messages locally from one sketch to another for easy multi-window sketching! Created by:
            +            <a href="https://benmoren.com"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/marching" target="_blank">
            +              <img alt="" src="../assets/img/libraries/marching.jpg">
            +              <h3>marching</h3>
            +            </a>
            +          </div>
            +          <p>Raster to vector conversion, isosurfaces. Created by:
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/cvalenzuela/Mappa" target="_blank">
            +              <img alt="" src="../assets/img/libraries/mappa.jpg">
            +              <h3>mappa</h3>
            +            </a>
            +          </div>
            +          <p>Mappa provides a set of tools for working with static maps, tile maps, and geo-data. Useful when building geolocation-based visual representations. Created by:
            +            <a href="https://github.com/cvalenzuela/"
            +              target="_blank">Cristóbal Valenzuela</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://ml5js.org/" target="_blank">
            +              <img alt="" src="../assets/img/libraries/ml5.js.jpg">
            +              <h3>ml5.js</h3>
            +            </a>
            +          </div>
            +          <p>ml5.js builds on Tensorflow.js and provides friendly access to machine learning algorithms and models in the browser. Created by:
            +            <a href="https://ml5js.org/"
            +              target="_blank">NYU ITP/IMA and contributors</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="http://p5play.molleindustria.org" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.play.jpg">
            +              <h3>p5.play</h3>
            +            </a>
            +          </div>
            +          <p>p5.play provides sprites, animations, input and collision functions for games and gamelike applications. Created by:
            +            <a href="https://www.molleindustria.org/"
            +              target="_blank">Paolo Pedercini</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bobcgausa/cook-js" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.particle.jpg">
            +              <h3>p5.particle</h3>
            +            </a>
            +          </div>
            +          <p>The Particle and Fountain objects can be used to create data-driven effects that are defined through user structures or JSON input and user-draw functions. Created by:
            +            <a href="http://professorcook.org/"
            +              target="_blank">Robert Cook</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://antiboredom.github.io/p5.riso" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.Riso.jpg">
            +              <h3>p5.Riso</h3>
            +            </a>
            +          </div>
            +          <p>p5.Riso is a library for generating files suitable for Risograph printing. It helps turn your sketches into multi-color prints. Created by:
            +            <a href="https://lav.io/"
            +              target="_blank">Sam Lavigne</a>, <a href="https://tegabrain.com/"
            +              target="_blank">Tega Brain</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://rednoise.org/rita" target="_blank">
            +              <img alt="" src="../assets/img/libraries/rita.js.jpg">
            +              <h3>rita.js</h3>
            +            </a>
            +          </div>
            +          <p>RiTa.js provides a set of natural language processing objects for generative literature. Created by:
            +            <a href="https://rednoise.org/daniel"
            +              target="_blank">Daniel C. Howe</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://codeforartists.com/RotatingKnobMaker" target="_blank">
            +              <img alt="" src="../assets/img/libraries/Rotating_knobs.jpg">
            +              <h3>Rotating knobs</h3>
            +            </a>
            +          </div>
            +          <p>Make knobs you can rotate with custom graphics and return value ranges. Created by:
            +            <a href="https://codeforartists.com"
            +              target="_blank">Miles DeCoster</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/mveteanu/p5.SceneManager" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.scenemanager.jpg">
            +              <h3>p5.scenemanager</h3>
            +            </a>
            +          </div>
            +          <p>p5.SceneManager helps you create sketches with multiple states / scenes. Each scene is a like a sketch within the main sketch. Created by:
            +            <a href="https://github.com/mveteanu/"
            +              target="_blank">Marian Veteanu</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bohnacker/p5js-screenPosition" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.screenPosition.jpg">
            +              <h3>p5.screenPosition</h3>
            +            </a>
            +          </div>
            +          <p>Adds the screenX and screenY functionality from Processing to P5js. Created by:
            +            <a href="https://hartmut-bohnacker.de/"
            +              target="_blank">Hartmut Bohnacker</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/generative-light/p5.scribble.js" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.scribble.jpg">
            +              <h3>p5.scribble</h3>
            +            </a>
            +          </div>
            +          <p>Draw 2D primitives in a sketchy look. Created by Janneck Wullschleger, based on a port of the original Processing library Created by:
            +            <a href="https://github.com/gicentre/handy"
            +              target="_blank">handy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/vanevery/p5.serialport" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.serial.jpg">
            +              <h3>p5.serial</h3>
            +            </a>
            +          </div>
            +          <p>p5.serial enables serial communication between devices that support serial (RS-232) and p5 sketches running in the browser. Created by:
            +            <a href="https://www.walking-productions.com/notslop/abou/"
            +              target="_blank">Shawn Van Every</a>, <a href="https://kaganjd.github.io/portfolio/"
            +              target="_blank">Jen Kagan</a>, <a href="https://tigoe.net/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/pfe1223/Shape5js" target="_blank">
            +              <img alt="" src="../assets/img/libraries/Shape5.jpg">
            +              <h3>Shape5</h3>
            +            </a>
            +          </div>
            +          <p>Shape5 is a 2D primative library for elementary students who are learning to code for the first time. Created by:
            +            <a href="https://github.com/pfe1223"
            +              target="_blank">Patrick Ester</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/gaba5/p5.shape.js" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.shape.js.jpg">
            +              <h3>p5.shape.js</h3>
            +            </a>
            +          </div>
            +          <p>A library built to add more simple shapes to the p5.js framework. Created by:
            +            <a href="https://github.com/gaba5"
            +              target="_blank">Sebastien Lorentz</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-speech/" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.speech.jpg">
            +              <h3>p5.speech</h3>
            +            </a>
            +          </div>
            +          <p>p5.speech provides simple, clear access to the Web Speech and Speech Recognition APIs, allowing for the easy creation of sketches that can talk and listen. Created by:
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/eltapir/p5.start2d.js" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.start2d.js.jpg">
            +              <h3>p5.start2d.js</h3>
            +            </a>
            +          </div>
            +          <p>p5 extension for 2D static art using px, mm, cm or inches Created by:
            +            <a href="https://github.com/eltapir"
            +              target="_blank">Kris HEYSE</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/linux-man/p5.tiledmap" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.tiledmap.jpg">
            +              <h3>p5.tiledmap</h3>
            +            </a>
            +          </div>
            +          <p>p5.tiledmap provides drawing and helper functions to include maps in your sketches. Created by:
            +            <a href="https://softlab.pt/"
            +              target="_blank">Caldas Lopes</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/L05/p5.touchgui" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.touchgui.jpg">
            +              <h3>p5.touchgui</h3>
            +            </a>
            +          </div>
            +          <p>A multi-touch and mouse GUI Library for p5.js. Created by:
            +            <a href="https://L05.is"
            +              target="_blank">Carlos L05 Garcia</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.tramontana.xyz" target="_blank">
            +              <img alt="" src="../assets/img/libraries/tramontana.jpg">
            +              <h3>tramontana</h3>
            +            </a>
            +          </div>
            +          <p>Tramontana is a platform for easily use many devices (iOS, Android, tramontana Board, ...) to create interactive environments, interactive spaces or just prototype experiences at scale and in space. Created by:
            +            <a href="https://www.pierdr.com"
            +              target="_blank">Pierluigi Dalla Rosa</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/vida" target="_blank">
            +              <img alt="" src="../assets/img/libraries/vida.jpg">
            +              <h3>vida</h3>
            +            </a>
            +          </div>
            +          <p>Vida is a simple library that adds camera (or video) based motion detection and blob tracking functionality to p5js. Created by:
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Dozed12/p5.voronoi" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.voronoi.jpg">
            +              <h3>p5.voronoi</h3>
            +            </a>
            +          </div>
            +          <p>p5.voronoi provides a set of tools to draw and utilize voronoi diagrams in your p5.js sketches. Created by:
            +            <a href="https://github.com/Dozed12"
            +              target="_blank">Francisco Moreira</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://p5xr.org/#/" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.xr.jpg">
            +              <h3>p5.xr</h3>
            +            </a>
            +          </div>
            +          <p>A library for creating VR and AR sketches with p5. Created by:
            +            <a href="https://www.stalgiagrigg.name/"
            +              target="_blank">Stalgia Grigg</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/FreddieRa/p5.3D" target="_blank">
            +              <img alt="" src="../assets/img/libraries/p5.3D.jpg">
            +              <h3>p5.3D</h3>
            +            </a>
            +          </div>
            +          <p>3D Text and Images in WebGL. Created by:
            +            <a href="https://freddierawlins.wixsite.com/site"
            +              target="_blank">Freddie Rawlins</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/offline-reference/p5-reference.zip b/dist/offline-reference/p5-reference.zip
            new file mode 100644
            index 0000000000..998eb2af4c
            Binary files /dev/null and b/dist/offline-reference/p5-reference.zip differ
            diff --git a/dist/reference/assets/Bold.ttf b/dist/reference/assets/Bold.ttf
            new file mode 100644
            index 0000000000..50d81bdad5
            Binary files /dev/null and b/dist/reference/assets/Bold.ttf differ
            diff --git a/dist/reference/assets/Damscray.mp3 b/dist/reference/assets/Damscray.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/reference/assets/Damscray.mp3 differ
            diff --git a/dist/reference/assets/Damscray.ogg b/dist/reference/assets/Damscray.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/reference/assets/Damscray.ogg differ
            diff --git a/dist/reference/assets/Damscray_-_Dancing_Tiger_01.ogg b/dist/reference/assets/Damscray_-_Dancing_Tiger_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/reference/assets/Damscray_-_Dancing_Tiger_01.ogg differ
            diff --git a/dist/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 b/dist/reference/assets/Damscray_-_Dancing_Tiger_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 differ
            diff --git a/dist/reference/assets/Damscray_01.mp3 b/dist/reference/assets/Damscray_01.mp3
            new file mode 100644
            index 0000000000..9653a67bb6
            Binary files /dev/null and b/dist/reference/assets/Damscray_01.mp3 differ
            diff --git a/dist/reference/assets/Damscray_01.ogg b/dist/reference/assets/Damscray_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/reference/assets/Damscray_01.ogg differ
            diff --git a/dist/reference/assets/Damscray_02.mp3 b/dist/reference/assets/Damscray_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/reference/assets/Damscray_02.mp3 differ
            diff --git a/dist/reference/assets/Damscray_02.ogg b/dist/reference/assets/Damscray_02.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/reference/assets/Damscray_02.ogg differ
            diff --git a/dist/reference/assets/Damscray_DancingTiger.mp3 b/dist/reference/assets/Damscray_DancingTiger.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/reference/assets/Damscray_DancingTiger.mp3 differ
            diff --git a/dist/reference/assets/Italic.ttf b/dist/reference/assets/Italic.ttf
            new file mode 100644
            index 0000000000..e5a1a86e63
            Binary files /dev/null and b/dist/reference/assets/Italic.ttf differ
            diff --git a/dist/reference/assets/Regular.otf b/dist/reference/assets/Regular.otf
            new file mode 100644
            index 0000000000..38941ae72f
            Binary files /dev/null and b/dist/reference/assets/Regular.otf differ
            diff --git a/dist/reference/assets/arnott-wallace-eye-loop-forever.gif b/dist/reference/assets/arnott-wallace-eye-loop-forever.gif
            new file mode 100644
            index 0000000000..992757bbaf
            Binary files /dev/null and b/dist/reference/assets/arnott-wallace-eye-loop-forever.gif differ
            diff --git a/dist/reference/assets/arnott-wallace-wink-loop-once.gif b/dist/reference/assets/arnott-wallace-wink-loop-once.gif
            new file mode 100644
            index 0000000000..94f2015ff3
            Binary files /dev/null and b/dist/reference/assets/arnott-wallace-wink-loop-once.gif differ
            diff --git a/dist/reference/assets/beat.mp3 b/dist/reference/assets/beat.mp3
            new file mode 100644
            index 0000000000..3e5802604c
            Binary files /dev/null and b/dist/reference/assets/beat.mp3 differ
            diff --git a/dist/reference/assets/beat.ogg b/dist/reference/assets/beat.ogg
            new file mode 100644
            index 0000000000..c13f86a41f
            Binary files /dev/null and b/dist/reference/assets/beat.ogg differ
            diff --git a/dist/reference/assets/beatbox.mp3 b/dist/reference/assets/beatbox.mp3
            new file mode 100644
            index 0000000000..23fb92eb71
            Binary files /dev/null and b/dist/reference/assets/beatbox.mp3 differ
            diff --git a/dist/reference/assets/beatbox.ogg b/dist/reference/assets/beatbox.ogg
            new file mode 100644
            index 0000000000..b2593a6340
            Binary files /dev/null and b/dist/reference/assets/beatbox.ogg differ
            diff --git a/dist/reference/assets/blobs.csv b/dist/reference/assets/blobs.csv
            new file mode 100644
            index 0000000000..2b7f05d1a0
            --- /dev/null
            +++ b/dist/reference/assets/blobs.csv
            @@ -0,0 +1,3 @@
            +ID,Name,Flavor,Shape,Color
            +Blob1,Blobby,Sweet,Blob,Pink
            +Blob2,Saddy,Savory,Blob,Blue
            \ No newline at end of file
            diff --git a/dist/reference/assets/bricks.jpg b/dist/reference/assets/bricks.jpg
            new file mode 100644
            index 0000000000..231161d752
            Binary files /dev/null and b/dist/reference/assets/bricks.jpg differ
            diff --git a/dist/reference/assets/bricks_third.jpg b/dist/reference/assets/bricks_third.jpg
            new file mode 100644
            index 0000000000..2fdb075996
            Binary files /dev/null and b/dist/reference/assets/bricks_third.jpg differ
            diff --git a/dist/reference/assets/bx-spring.mp3 b/dist/reference/assets/bx-spring.mp3
            new file mode 100644
            index 0000000000..4a955ab7fa
            Binary files /dev/null and b/dist/reference/assets/bx-spring.mp3 differ
            diff --git a/dist/reference/assets/bx-spring.ogg b/dist/reference/assets/bx-spring.ogg
            new file mode 100644
            index 0000000000..b01abee927
            Binary files /dev/null and b/dist/reference/assets/bx-spring.ogg differ
            diff --git a/dist/reference/assets/concrete-tunnel.mp3 b/dist/reference/assets/concrete-tunnel.mp3
            new file mode 100644
            index 0000000000..1bfbd4f8f8
            Binary files /dev/null and b/dist/reference/assets/concrete-tunnel.mp3 differ
            diff --git a/dist/reference/assets/concrete-tunnel.ogg b/dist/reference/assets/concrete-tunnel.ogg
            new file mode 100644
            index 0000000000..be5f66b72c
            Binary files /dev/null and b/dist/reference/assets/concrete-tunnel.ogg differ
            diff --git a/dist/reference/assets/doorbell.mp3 b/dist/reference/assets/doorbell.mp3
            new file mode 100644
            index 0000000000..44b6367916
            Binary files /dev/null and b/dist/reference/assets/doorbell.mp3 differ
            diff --git a/dist/reference/assets/doorbell.ogg b/dist/reference/assets/doorbell.ogg
            new file mode 100644
            index 0000000000..e816288c97
            Binary files /dev/null and b/dist/reference/assets/doorbell.ogg differ
            diff --git a/dist/reference/assets/drawImage.png b/dist/reference/assets/drawImage.png
            new file mode 100644
            index 0000000000..1a7aa5d1d8
            Binary files /dev/null and b/dist/reference/assets/drawImage.png differ
            diff --git a/dist/reference/assets/drum.mp3 b/dist/reference/assets/drum.mp3
            new file mode 100644
            index 0000000000..9cd8727617
            Binary files /dev/null and b/dist/reference/assets/drum.mp3 differ
            diff --git a/dist/reference/assets/drum.ogg b/dist/reference/assets/drum.ogg
            new file mode 100644
            index 0000000000..5061a1b319
            Binary files /dev/null and b/dist/reference/assets/drum.ogg differ
            diff --git a/dist/reference/assets/favicon.ico b/dist/reference/assets/favicon.ico
            new file mode 100644
            index 0000000000..33ad9806c8
            Binary files /dev/null and b/dist/reference/assets/favicon.ico differ
            diff --git a/dist/reference/assets/fingers.mov b/dist/reference/assets/fingers.mov
            new file mode 100644
            index 0000000000..a9cbbbe3ea
            Binary files /dev/null and b/dist/reference/assets/fingers.mov differ
            diff --git a/dist/reference/assets/gradient.png b/dist/reference/assets/gradient.png
            new file mode 100644
            index 0000000000..5245af69cd
            Binary files /dev/null and b/dist/reference/assets/gradient.png differ
            diff --git a/dist/reference/assets/inconsolata.otf b/dist/reference/assets/inconsolata.otf
            new file mode 100644
            index 0000000000..e7e1fa0cd7
            Binary files /dev/null and b/dist/reference/assets/inconsolata.otf differ
            diff --git a/dist/reference/assets/index.html b/dist/reference/assets/index.html
            new file mode 100644
            index 0000000000..487fe15b2a
            --- /dev/null
            +++ b/dist/reference/assets/index.html
            @@ -0,0 +1,10 @@
            +<!doctype html>
            +<html>
            +    <head>
            +        <title>Redirector</title>
            +        <meta http-equiv="refresh" content="0;url=../">
            +    </head>
            +    <body>
            +        <a href="../">Click here to redirect</a>
            +    </body>
            +</html>
            diff --git a/dist/reference/assets/laDefense.jpg b/dist/reference/assets/laDefense.jpg
            new file mode 100644
            index 0000000000..3b8fdfe4b8
            Binary files /dev/null and b/dist/reference/assets/laDefense.jpg differ
            diff --git a/dist/reference/assets/large-dark-plate.mp3 b/dist/reference/assets/large-dark-plate.mp3
            new file mode 100644
            index 0000000000..b9a15cbed7
            Binary files /dev/null and b/dist/reference/assets/large-dark-plate.mp3 differ
            diff --git a/dist/reference/assets/large-dark-plate.ogg b/dist/reference/assets/large-dark-plate.ogg
            new file mode 100644
            index 0000000000..40115377e5
            Binary files /dev/null and b/dist/reference/assets/large-dark-plate.ogg differ
            diff --git a/dist/reference/assets/lucky_dragons.mp3 b/dist/reference/assets/lucky_dragons.mp3
            new file mode 100644
            index 0000000000..c54c70c01a
            Binary files /dev/null and b/dist/reference/assets/lucky_dragons.mp3 differ
            diff --git a/dist/reference/assets/lucky_dragons.ogg b/dist/reference/assets/lucky_dragons.ogg
            new file mode 100644
            index 0000000000..1e5b9e7abc
            Binary files /dev/null and b/dist/reference/assets/lucky_dragons.ogg differ
            diff --git a/dist/reference/assets/mammals.csv b/dist/reference/assets/mammals.csv
            new file mode 100644
            index 0000000000..549984e37e
            --- /dev/null
            +++ b/dist/reference/assets/mammals.csv
            @@ -0,0 +1,4 @@
            +id,species,name
            +0,Capra hircus,Goat
            +1,Panthera pardus,Leopard
            +2,Equus zebra,Zebra
            \ No newline at end of file
            diff --git a/dist/reference/assets/mammals.xml b/dist/reference/assets/mammals.xml
            new file mode 100644
            index 0000000000..752da754bf
            --- /dev/null
            +++ b/dist/reference/assets/mammals.xml
            @@ -0,0 +1,6 @@
            +<?xml version="1.0"?>
            +<mammals>
            +  <animal id="0" species="Capra hircus">Goat</animal>
            +  <animal id="1" species="Panthera pardus">Leopard</animal>
            +  <animal id="2" species="Equus zebra">Zebra</animal>
            +</mammals>
            \ No newline at end of file
            diff --git a/dist/reference/assets/mask.png b/dist/reference/assets/mask.png
            new file mode 100644
            index 0000000000..a6737489b9
            Binary files /dev/null and b/dist/reference/assets/mask.png differ
            diff --git a/dist/reference/assets/mask2.png b/dist/reference/assets/mask2.png
            new file mode 100644
            index 0000000000..2fb4aea99b
            Binary files /dev/null and b/dist/reference/assets/mask2.png differ
            diff --git a/dist/reference/assets/moonwalk.jpg b/dist/reference/assets/moonwalk.jpg
            new file mode 100644
            index 0000000000..c418e6f573
            Binary files /dev/null and b/dist/reference/assets/moonwalk.jpg differ
            diff --git a/dist/reference/assets/nancy-liang-wind-loop-forever.gif b/dist/reference/assets/nancy-liang-wind-loop-forever.gif
            new file mode 100644
            index 0000000000..a946253ede
            Binary files /dev/null and b/dist/reference/assets/nancy-liang-wind-loop-forever.gif differ
            diff --git a/dist/reference/assets/octahedron.obj b/dist/reference/assets/octahedron.obj
            new file mode 100644
            index 0000000000..fed774d32a
            --- /dev/null
            +++ b/dist/reference/assets/octahedron.obj
            @@ -0,0 +1,15 @@
            +v 0.000000E+00 0.000000E+00 40.0000
            +v 22.5000 22.5000 0.000000E+00
            +v 22.5000 -22.5000 0.000000E+00
            +v -22.5000 -22.5000 0.000000E+00
            +v -22.5000 22.5000 0.000000E+00
            +v 0.000000E+00 0.000000E+00 -40.0000
            +
            +f     1 2 3
            +f     1 3 4
            +f     1 4 5
            +f     1 5 2
            +f     6 5 4
            +f     6 4 3
            +f     6 3 2
            +f     6 2 5
            diff --git a/dist/reference/assets/rockies.jpg b/dist/reference/assets/rockies.jpg
            new file mode 100644
            index 0000000000..9bc0e4a372
            Binary files /dev/null and b/dist/reference/assets/rockies.jpg differ
            diff --git a/dist/reference/assets/rockies128.jpg b/dist/reference/assets/rockies128.jpg
            new file mode 100644
            index 0000000000..bf55d812b2
            Binary files /dev/null and b/dist/reference/assets/rockies128.jpg differ
            diff --git a/dist/reference/assets/shader-gradient.frag b/dist/reference/assets/shader-gradient.frag
            new file mode 100644
            index 0000000000..09a0cdc64b
            --- /dev/null
            +++ b/dist/reference/assets/shader-gradient.frag
            @@ -0,0 +1,22 @@
            +// Code adopted from "Creating a Gradient Color in Fragment Shader"
            +// by Bahadır on stackoverflow.com
            +// https://stackoverflow.com/questions/47376499/creating-a-gradient-color-in-fragment-shader
            +
            +
            +precision highp float; varying vec2 vPos;
            +uniform vec2 offset;
            +uniform vec3 colorCenter;
            +uniform vec3 colorBackground;
            +
            +void main() {
            +
            +  vec2 st = vPos.xy + offset.xy;
            +
            +  // color1 = vec3(1.0,0.55,0);
            +  // color2 = vec3(0.226,0.000,0.615);
            +
            +  float mixValue = distance(st,vec2(0,1));
            +  vec3 color = mix(colorCenter,colorBackground,mixValue);
            +
            +  gl_FragColor = vec4(color,mixValue);
            +}
            \ No newline at end of file
            diff --git a/dist/reference/assets/shader.frag b/dist/reference/assets/shader.frag
            new file mode 100644
            index 0000000000..d3d76eb77a
            --- /dev/null
            +++ b/dist/reference/assets/shader.frag
            @@ -0,0 +1,16 @@
            +precision highp float; varying vec2 vPos;
            +uniform vec2 p;
            +uniform float r;
            +const int I = 500;
            +void main() {
            +  vec2 c = p + vPos * r, z = c;
            +  float n = 0.0;
            +  for (int i = I; i > 0; i --) {
            +    if(z.x*z.x+z.y*z.y > 4.0) {
            +      n = float(i)/float(I);
            +      break;
            +    }
            +    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;
            +  }
            +  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);
            +}
            diff --git a/dist/reference/assets/shader.vert b/dist/reference/assets/shader.vert
            new file mode 100644
            index 0000000000..ea310c6770
            --- /dev/null
            +++ b/dist/reference/assets/shader.vert
            @@ -0,0 +1,3 @@
            +precision highp float; varying vec2 vPos;
            +attribute vec3 aPosition;
            +void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }
            diff --git a/dist/reference/assets/small-plate.mp3 b/dist/reference/assets/small-plate.mp3
            new file mode 100644
            index 0000000000..656e154a5f
            Binary files /dev/null and b/dist/reference/assets/small-plate.mp3 differ
            diff --git a/dist/reference/assets/small-plate.ogg b/dist/reference/assets/small-plate.ogg
            new file mode 100644
            index 0000000000..7b70d3349d
            Binary files /dev/null and b/dist/reference/assets/small-plate.ogg differ
            diff --git a/dist/reference/assets/small.mp4 b/dist/reference/assets/small.mp4
            new file mode 100644
            index 0000000000..1fc478842f
            Binary files /dev/null and b/dist/reference/assets/small.mp4 differ
            diff --git a/dist/reference/assets/small.ogv b/dist/reference/assets/small.ogv
            new file mode 100644
            index 0000000000..2b35a41aa4
            Binary files /dev/null and b/dist/reference/assets/small.ogv differ
            diff --git a/dist/reference/assets/small.webm b/dist/reference/assets/small.webm
            new file mode 100644
            index 0000000000..da946da529
            Binary files /dev/null and b/dist/reference/assets/small.webm differ
            diff --git a/dist/reference/assets/studio-b.mp3 b/dist/reference/assets/studio-b.mp3
            new file mode 100644
            index 0000000000..cbc792bfc9
            Binary files /dev/null and b/dist/reference/assets/studio-b.mp3 differ
            diff --git a/dist/reference/assets/studio-b.ogg b/dist/reference/assets/studio-b.ogg
            new file mode 100644
            index 0000000000..cd68db07e6
            Binary files /dev/null and b/dist/reference/assets/studio-b.ogg differ
            diff --git a/dist/reference/assets/teapot.obj b/dist/reference/assets/teapot.obj
            new file mode 100644
            index 0000000000..cedb196a4e
            --- /dev/null
            +++ b/dist/reference/assets/teapot.obj
            @@ -0,0 +1,4663 @@
            +# Blender v2.61 (sub 0) OBJ File: ''
            +# www.blender.org
            +v 0.605903 0.005903 -0.000000
            +v 0.000000 0.000000 0.000000
            +v 0.584584 0.005902 -0.162696
            +v 0.524218 0.005902 -0.307888
            +v 0.430191 0.005901 -0.430191
            +v 0.307888 0.005901 -0.524218
            +v 0.162696 0.005901 -0.584584
            +v 0.000000 0.005901 -0.605903
            +v -0.162696 0.005901 -0.584584
            +v -0.307888 0.005901 -0.524218
            +v -0.430191 0.005901 -0.430191
            +v -0.524218 0.005902 -0.307888
            +v -0.584584 0.005902 -0.162696
            +v -0.605903 0.005903 -0.000000
            +v -0.584584 0.005904 0.162696
            +v -0.524218 0.005904 0.307888
            +v -0.430191 0.005905 0.430191
            +v -0.307888 0.005905 0.524218
            +v -0.162696 0.005905 0.584584
            +v 0.000000 0.005905 0.605903
            +v 0.162696 0.005905 0.584584
            +v 0.307888 0.005905 0.524218
            +v 0.430191 0.005905 0.430191
            +v 0.524218 0.005904 0.307888
            +v 0.584584 0.005904 0.162696
            +v 1.400000 2.400000 -0.000008
            +v 1.350740 2.400000 0.375917
            +v 1.332760 2.454690 0.370913
            +v 1.381370 2.454690 -0.000009
            +v 1.384260 2.487500 -0.000009
            +v 1.335550 2.487500 0.371690
            +v 1.403120 2.498440 -0.000009
            +v 1.353760 2.498440 0.376756
            +v 1.382010 2.487500 0.384619
            +v 1.432410 2.487500 -0.000009
            +v 1.414950 2.454690 0.393787
            +v 1.466550 2.454690 -0.000009
            +v 1.447220 2.400000 0.402769
            +v 1.500000 2.400000 -0.000008
            +v 1.211260 2.400000 0.711398
            +v 1.195140 2.454690 0.701929
            +v 1.197640 2.487500 0.703400
            +v 1.213960 2.498440 0.712986
            +v 1.239300 2.487500 0.727866
            +v 1.268840 2.454690 0.745216
            +v 1.297780 2.400000 0.762213
            +v 0.994000 2.400000 0.993991
            +v 0.980770 2.454690 0.980761
            +v 0.982824 2.487500 0.982815
            +v 0.996219 2.498440 0.996210
            +v 1.017010 2.487500 1.017000
            +v 1.041250 2.454690 1.041240
            +v 1.065000 2.400000 1.064990
            +v 0.711407 2.400000 1.211250
            +v 0.701938 2.454690 1.195130
            +v 0.703409 2.487500 1.197630
            +v 0.712995 2.498440 1.213950
            +v 0.727875 2.487500 1.239290
            +v 0.745225 2.454690 1.268830
            +v 0.762222 2.400000 1.297770
            +v 0.375926 2.400010 1.350730
            +v 0.370922 2.454690 1.332750
            +v 0.371699 2.487500 1.335540
            +v 0.376765 2.498450 1.353750
            +v 0.384628 2.487500 1.382000
            +v 0.393796 2.454700 1.414940
            +v 0.402778 2.400010 1.447210
            +v 0.000000 2.400010 1.399990
            +v 0.000000 2.454690 1.381360
            +v 0.000000 2.487500 1.384250
            +v 0.000000 2.498450 1.403110
            +v 0.000000 2.487510 1.432400
            +v 0.000000 2.454700 1.466540
            +v 0.000000 2.400010 1.499990
            +v -0.375926 2.400010 1.350730
            +v -0.370922 2.454690 1.332750
            +v -0.371699 2.487500 1.335540
            +v -0.376765 2.498450 1.353750
            +v -0.384628 2.487500 1.382000
            +v -0.393796 2.454700 1.414940
            +v -0.402778 2.400010 1.447210
            +v -0.711407 2.400000 1.211250
            +v -0.701938 2.454690 1.195130
            +v -0.703409 2.487500 1.197630
            +v -0.712995 2.498440 1.213950
            +v -0.727875 2.487500 1.239290
            +v -0.745225 2.454690 1.268830
            +v -0.762222 2.400000 1.297770
            +v -0.994000 2.400000 0.993991
            +v -0.980770 2.454690 0.980761
            +v -0.982824 2.487500 0.982815
            +v -0.996219 2.498440 0.996210
            +v -1.017010 2.487500 1.017000
            +v -1.041250 2.454690 1.041240
            +v -1.065000 2.400000 1.064990
            +v -1.211260 2.400000 0.711398
            +v -1.195140 2.454690 0.701929
            +v -1.197640 2.487500 0.703400
            +v -1.213960 2.498440 0.712986
            +v -1.239300 2.487500 0.727866
            +v -1.268840 2.454690 0.745216
            +v -1.297780 2.400000 0.762213
            +v -1.350740 2.400000 0.375917
            +v -1.332760 2.454690 0.370913
            +v -1.335550 2.487500 0.371690
            +v -1.353760 2.498440 0.376756
            +v -1.382010 2.487500 0.384619
            +v -1.414950 2.454690 0.393787
            +v -1.447220 2.400000 0.402769
            +v -1.400000 2.400000 -0.000008
            +v -1.381370 2.454690 -0.000009
            +v -1.384260 2.487500 -0.000009
            +v -1.403120 2.498440 -0.000009
            +v -1.432410 2.487500 -0.000009
            +v -1.466550 2.454690 -0.000009
            +v -1.500000 2.400000 -0.000008
            +v -1.350740 2.400000 -0.375935
            +v -1.332760 2.454690 -0.370931
            +v -1.335550 2.487500 -0.371708
            +v -1.353760 2.498440 -0.376774
            +v -1.382010 2.487500 -0.384637
            +v -1.414950 2.454690 -0.393805
            +v -1.447220 2.400000 -0.402787
            +v -1.211260 2.400000 -0.711416
            +v -1.195140 2.454690 -0.701947
            +v -1.197640 2.487500 -0.703418
            +v -1.213960 2.498440 -0.713004
            +v -1.239300 2.487500 -0.727884
            +v -1.268840 2.454690 -0.745234
            +v -1.297780 2.400000 -0.762231
            +v -0.994000 2.400000 -0.994009
            +v -0.980770 2.454690 -0.980779
            +v -0.982824 2.487500 -0.982833
            +v -0.996219 2.498440 -0.996228
            +v -1.017010 2.487500 -1.017020
            +v -1.041250 2.454690 -1.041260
            +v -1.065000 2.400000 -1.065010
            +v -0.711407 2.400000 -1.211270
            +v -0.701938 2.454690 -1.195150
            +v -0.703409 2.487500 -1.197650
            +v -0.712995 2.498440 -1.213970
            +v -0.727875 2.487500 -1.239310
            +v -0.745225 2.454690 -1.268850
            +v -0.762222 2.400000 -1.297790
            +v -0.375926 2.400000 -1.350750
            +v -0.370922 2.454680 -1.332770
            +v -0.371699 2.487490 -1.335560
            +v -0.376765 2.498440 -1.353770
            +v -0.384628 2.487490 -1.382020
            +v -0.393796 2.454680 -1.414960
            +v -0.402778 2.399990 -1.447230
            +v 0.000000 2.399990 -1.400010
            +v 0.000000 2.454680 -1.381380
            +v 0.000000 2.487490 -1.384270
            +v 0.000000 2.498430 -1.403130
            +v 0.000000 2.487490 -1.432420
            +v 0.000000 2.454680 -1.466560
            +v 0.000000 2.399990 -1.500010
            +v 0.375926 2.400000 -1.350750
            +v 0.370922 2.454680 -1.332770
            +v 0.371699 2.487490 -1.335560
            +v 0.376765 2.498440 -1.353770
            +v 0.384628 2.487490 -1.382020
            +v 0.393796 2.454680 -1.414960
            +v 0.402778 2.399990 -1.447230
            +v 0.711407 2.400000 -1.211270
            +v 0.701938 2.454690 -1.195150
            +v 0.703409 2.487500 -1.197650
            +v 0.712995 2.498440 -1.213970
            +v 0.727875 2.487500 -1.239310
            +v 0.745225 2.454690 -1.268850
            +v 0.762222 2.400000 -1.297790
            +v 0.994000 2.400000 -0.994009
            +v 0.980770 2.454690 -0.980779
            +v 0.982824 2.487500 -0.982833
            +v 0.996219 2.498440 -0.996228
            +v 1.017010 2.487500 -1.017020
            +v 1.041250 2.454690 -1.041260
            +v 1.065000 2.400000 -1.065010
            +v 1.211260 2.400000 -0.711416
            +v 1.195140 2.454690 -0.701947
            +v 1.197640 2.487500 -0.703418
            +v 1.213960 2.498440 -0.713004
            +v 1.239300 2.487500 -0.727884
            +v 1.268840 2.454690 -0.745234
            +v 1.297780 2.400000 -0.762231
            +v 1.350740 2.400000 -0.375935
            +v 1.332760 2.454690 -0.370931
            +v 1.335550 2.487500 -0.371708
            +v 1.353760 2.498440 -0.376774
            +v 1.382010 2.487500 -0.384637
            +v 1.414950 2.454690 -0.393805
            +v 1.447220 2.400000 -0.402787
            +v 1.566710 2.137850 0.436024
            +v 1.623840 2.137850 -0.000008
            +v 1.679490 1.877780 0.467414
            +v 1.740740 1.877780 -0.000007
            +v 1.778880 1.621880 0.495075
            +v 1.843750 1.621870 -0.000006
            +v 1.858160 1.372220 0.517142
            +v 1.925930 1.372220 -0.000005
            +v 1.910650 1.130900 0.531750
            +v 1.980320 1.130900 -0.000004
            +v 1.929630 0.900002 0.537034
            +v 2.000000 0.900000 -0.000003
            +v 1.404920 2.137850 0.825145
            +v 1.506060 1.877780 0.884547
            +v 1.595190 1.621880 0.936892
            +v 1.666280 1.372220 0.978651
            +v 1.713350 1.130900 1.006300
            +v 1.730370 0.900004 1.016300
            +v 1.152930 2.137850 1.152920
            +v 1.235930 1.877780 1.235920
            +v 1.309060 1.621870 1.309050
            +v 1.367410 1.372230 1.367400
            +v 1.406030 1.130910 1.406030
            +v 1.420000 0.900005 1.420000
            +v 0.825153 2.137860 1.404910
            +v 0.884554 1.877790 1.506050
            +v 0.936898 1.621890 1.595180
            +v 0.978656 1.372230 1.666270
            +v 1.006300 1.130910 1.713350
            +v 1.016300 0.900006 1.730370
            +v 0.436032 2.137860 1.566700
            +v 0.467421 1.877790 1.679480
            +v 0.495081 1.621880 1.778870
            +v 0.517147 1.372230 1.858150
            +v 0.531754 1.130910 1.910650
            +v 0.537037 0.900007 1.929630
            +v 0.000000 2.137860 1.623830
            +v 0.000000 1.877790 1.740730
            +v 0.000000 1.621880 1.843740
            +v 0.000000 1.372230 1.925920
            +v 0.000000 1.130910 1.980320
            +v 0.000000 0.900007 2.000000
            +v -0.436032 2.137860 1.566700
            +v -0.467421 1.877790 1.679480
            +v -0.495081 1.621890 1.778870
            +v -0.517147 1.372230 1.858150
            +v -0.531754 1.130910 1.910650
            +v -0.537037 0.900007 1.929630
            +v -0.825153 2.137860 1.404910
            +v -0.884554 1.877790 1.506050
            +v -0.936898 1.621890 1.595180
            +v -0.978656 1.372230 1.666270
            +v -1.006300 1.130910 1.713350
            +v -1.016300 0.900006 1.730370
            +v -1.152930 2.137850 1.152920
            +v -1.235930 1.877780 1.235920
            +v -1.309060 1.621870 1.309050
            +v -1.367410 1.372230 1.367400
            +v -1.406030 1.130910 1.406030
            +v -1.420000 0.900005 1.420000
            +v -1.404920 2.137850 0.825145
            +v -1.506060 1.877780 0.884547
            +v -1.595190 1.621880 0.936892
            +v -1.666280 1.372220 0.978651
            +v -1.713350 1.130900 1.006300
            +v -1.730370 0.900004 1.016300
            +v -1.566710 2.137850 0.436024
            +v -1.679490 1.877780 0.467414
            +v -1.778880 1.621870 0.495075
            +v -1.858160 1.372220 0.517142
            +v -1.910650 1.130900 0.531750
            +v -1.929630 0.900002 0.537034
            +v -1.623840 2.137850 -0.000008
            +v -1.740740 1.877780 -0.000007
            +v -1.843750 1.621870 -0.000006
            +v -1.925930 1.372220 -0.000005
            +v -1.980320 1.130900 -0.000004
            +v -2.000000 0.900000 -0.000003
            +v -1.566710 2.137850 -0.436040
            +v -1.679490 1.877780 -0.467428
            +v -1.778880 1.621880 -0.495087
            +v -1.858160 1.372220 -0.517152
            +v -1.910650 1.130900 -0.531758
            +v -1.929630 0.899998 -0.537040
            +v -1.404920 2.137850 -0.825161
            +v -1.506060 1.877780 -0.884561
            +v -1.595190 1.621880 -0.936904
            +v -1.666280 1.372220 -0.978661
            +v -1.713350 1.130900 -1.006300
            +v -1.730370 0.899996 -1.016300
            +v -1.152930 2.137850 -1.152940
            +v -1.235930 1.877780 -1.235940
            +v -1.309060 1.621870 -1.309070
            +v -1.367410 1.372220 -1.367420
            +v -1.406030 1.130890 -1.406030
            +v -1.420000 0.899995 -1.420000
            +v -0.825153 2.137840 -1.404930
            +v -0.884554 1.877770 -1.506070
            +v -0.936898 1.621870 -1.595200
            +v -0.978656 1.372210 -1.666290
            +v -1.006300 1.130890 -1.713350
            +v -1.016300 0.899994 -1.730370
            +v -0.436032 2.137840 -1.566720
            +v -0.467421 1.877770 -1.679500
            +v -0.495081 1.621860 -1.778890
            +v -0.517147 1.372210 -1.858170
            +v -0.531754 1.130890 -1.910650
            +v -0.537037 0.899993 -1.929630
            +v 0.000000 2.137840 -1.623850
            +v 0.000000 1.877770 -1.740750
            +v 0.000000 1.621860 -1.843760
            +v 0.000000 1.372210 -1.925940
            +v 0.000000 1.130890 -1.980320
            +v 0.000000 0.899993 -2.000000
            +v 0.436032 2.137840 -1.566720
            +v 0.467421 1.877770 -1.679500
            +v 0.495081 1.621870 -1.778890
            +v 0.517147 1.372210 -1.858170
            +v 0.531754 1.130890 -1.910650
            +v 0.537037 0.899993 -1.929630
            +v 0.825153 2.137840 -1.404930
            +v 0.884554 1.877770 -1.506070
            +v 0.936898 1.621870 -1.595200
            +v 0.978656 1.372210 -1.666290
            +v 1.006300 1.130890 -1.713350
            +v 1.016300 0.899994 -1.730370
            +v 1.152930 2.137850 -1.152940
            +v 1.235930 1.877780 -1.235940
            +v 1.309060 1.621870 -1.309070
            +v 1.367410 1.372220 -1.367420
            +v 1.406030 1.130890 -1.406030
            +v 1.420000 0.899995 -1.420000
            +v 1.404920 2.137850 -0.825161
            +v 1.506060 1.877780 -0.884561
            +v 1.595190 1.621880 -0.936904
            +v 1.666280 1.372220 -0.978661
            +v 1.713350 1.130900 -1.006300
            +v 1.730370 0.899996 -1.016300
            +v 1.566710 2.137850 -0.436040
            +v 1.679490 1.877780 -0.467428
            +v 1.778880 1.621870 -0.495087
            +v 1.858160 1.372220 -0.517152
            +v 1.910650 1.130900 -0.531758
            +v 1.929630 0.899998 -0.537040
            +v 1.893900 0.693405 0.527089
            +v 1.962960 0.693403 -0.000002
            +v 1.804560 0.522224 0.502227
            +v 1.870370 0.522222 -0.000002
            +v 1.688430 0.384377 0.469906
            +v 1.750000 0.384375 -0.000001
            +v 1.572290 0.277780 0.437585
            +v 1.629630 0.277778 -0.000001
            +v 1.482960 0.200349 0.412722
            +v 1.537040 0.200347 -0.000001
            +v 1.447220 0.150001 0.402777
            +v 1.500000 0.150000 -0.000001
            +v 1.698330 0.693407 0.997473
            +v 1.618220 0.522225 0.950423
            +v 1.514070 0.384378 0.889258
            +v 1.409930 0.277781 0.828092
            +v 1.329820 0.200350 0.781042
            +v 1.297780 0.150003 0.762221
            +v 1.393700 0.693408 1.393700
            +v 1.327960 0.522227 1.327960
            +v 1.242500 0.384380 1.242500
            +v 1.157040 0.277782 1.157040
            +v 1.091300 0.200351 1.091300
            +v 1.065000 0.150004 1.065000
            +v 0.997476 0.693409 1.698330
            +v 0.950425 0.522228 1.618220
            +v 0.889259 0.384381 1.514070
            +v 0.828093 0.277783 1.409930
            +v 0.781043 0.200352 1.329820
            +v 0.762222 0.150005 1.297780
            +v 0.527092 0.693410 1.893900
            +v 0.502229 0.522229 1.804560
            +v 0.469907 0.384381 1.688430
            +v 0.437586 0.277784 1.572290
            +v 0.412723 0.200352 1.482960
            +v 0.402778 0.150005 1.447220
            +v 0.000000 0.693410 1.962960
            +v 0.000000 0.522229 1.870370
            +v 0.000000 0.384381 1.750000
            +v 0.000000 0.277784 1.629630
            +v 0.000000 0.200353 1.537040
            +v 0.000000 0.150006 1.500000
            +v -0.527092 0.693410 1.893900
            +v -0.502229 0.522229 1.804560
            +v -0.469907 0.384381 1.688430
            +v -0.437586 0.277784 1.572290
            +v -0.412723 0.200352 1.482960
            +v -0.402778 0.150005 1.447220
            +v -0.997476 0.693409 1.698330
            +v -0.950425 0.522228 1.618220
            +v -0.889259 0.384381 1.514070
            +v -0.828093 0.277783 1.409930
            +v -0.781043 0.200352 1.329820
            +v -0.762222 0.150005 1.297780
            +v -1.393700 0.693408 1.393700
            +v -1.327960 0.522227 1.327960
            +v -1.242500 0.384380 1.242500
            +v -1.157040 0.277782 1.157040
            +v -1.091300 0.200351 1.091300
            +v -1.065000 0.150004 1.065000
            +v -1.698330 0.693407 0.997473
            +v -1.618220 0.522225 0.950423
            +v -1.514070 0.384378 0.889258
            +v -1.409930 0.277781 0.828092
            +v -1.329820 0.200350 0.781042
            +v -1.297780 0.150003 0.762221
            +v -1.893900 0.693405 0.527089
            +v -1.804560 0.522224 0.502227
            +v -1.688430 0.384377 0.469906
            +v -1.572290 0.277780 0.437585
            +v -1.482960 0.200349 0.412722
            +v -1.447220 0.150001 0.402777
            +v -1.962960 0.693403 -0.000002
            +v -1.870370 0.522222 -0.000002
            +v -1.750000 0.384375 -0.000001
            +v -1.629630 0.277778 -0.000001
            +v -1.537040 0.200347 -0.000001
            +v -1.500000 0.150000 -0.000001
            +v -1.893900 0.693401 -0.527095
            +v -1.804560 0.522220 -0.502231
            +v -1.688430 0.384373 -0.469908
            +v -1.572290 0.277776 -0.437587
            +v -1.482960 0.200345 -0.412724
            +v -1.447220 0.149999 -0.402779
            +v -1.698330 0.693399 -0.997479
            +v -1.618220 0.522218 -0.950427
            +v -1.514070 0.384372 -0.889260
            +v -1.409930 0.277775 -0.828094
            +v -1.329820 0.200344 -0.781044
            +v -1.297780 0.149997 -0.762223
            +v -1.393700 0.693398 -1.393700
            +v -1.327960 0.522217 -1.327960
            +v -1.242500 0.384370 -1.242500
            +v -1.157040 0.277774 -1.157040
            +v -1.091300 0.200343 -1.091300
            +v -1.065000 0.149996 -1.065000
            +v -0.997476 0.693397 -1.698330
            +v -0.950425 0.522216 -1.618220
            +v -0.889259 0.384369 -1.514070
            +v -0.828093 0.277773 -1.409930
            +v -0.781043 0.200342 -1.329820
            +v -0.762222 0.149995 -1.297780
            +v -0.527092 0.693396 -1.893900
            +v -0.502229 0.522215 -1.804560
            +v -0.469907 0.384369 -1.688430
            +v -0.437586 0.277772 -1.572290
            +v -0.412723 0.200342 -1.482960
            +v -0.402778 0.149995 -1.447220
            +v 0.000000 0.693396 -1.962960
            +v 0.000000 0.522215 -1.870370
            +v 0.000000 0.384369 -1.750000
            +v 0.000000 0.277772 -1.629630
            +v 0.000000 0.200341 -1.537040
            +v 0.000000 0.149994 -1.500000
            +v 0.527092 0.693396 -1.893900
            +v 0.502229 0.522215 -1.804560
            +v 0.469907 0.384369 -1.688430
            +v 0.437586 0.277772 -1.572290
            +v 0.412723 0.200342 -1.482960
            +v 0.402778 0.149995 -1.447220
            +v 0.997476 0.693397 -1.698330
            +v 0.950425 0.522216 -1.618220
            +v 0.889259 0.384369 -1.514070
            +v 0.828093 0.277773 -1.409930
            +v 0.781043 0.200342 -1.329820
            +v 0.762222 0.149995 -1.297780
            +v 1.393700 0.693398 -1.393700
            +v 1.327960 0.522217 -1.327960
            +v 1.242500 0.384370 -1.242500
            +v 1.157040 0.277774 -1.157040
            +v 1.091300 0.200343 -1.091300
            +v 1.065000 0.149996 -1.065000
            +v 1.698330 0.693399 -0.997479
            +v 1.618220 0.522218 -0.950427
            +v 1.514070 0.384372 -0.889260
            +v 1.409930 0.277775 -0.828094
            +v 1.329820 0.200344 -0.781044
            +v 1.297780 0.149997 -0.762223
            +v 1.893900 0.693401 -0.527095
            +v 1.804560 0.522220 -0.502231
            +v 1.688430 0.384373 -0.469908
            +v 1.572290 0.277776 -0.437587
            +v 1.482960 0.200345 -0.412724
            +v 1.447220 0.149999 -0.402779
            +v 1.022220 0.022222 -0.000000
            +v 0.986255 0.022221 -0.274486
            +v 1.284370 0.046875 -0.000000
            +v 1.239180 0.046874 -0.344878
            +v 1.427780 0.077778 -0.000000
            +v 1.377540 0.077777 -0.383385
            +v 1.487850 0.112847 -0.000000
            +v 1.435500 0.112846 -0.399515
            +v 0.884412 0.022220 -0.519440
            +v 1.111220 0.046873 -0.652653
            +v 1.235290 0.077775 -0.725523
            +v 1.287260 0.112844 -0.756047
            +v 0.725778 0.022219 -0.725778
            +v 0.911906 0.046872 -0.911906
            +v 1.013720 0.077774 -1.013720
            +v 1.056370 0.112843 -1.056370
            +v 0.519440 0.022219 -0.884412
            +v 0.652653 0.046871 -1.111220
            +v 0.725523 0.077774 -1.235290
            +v 0.756047 0.112842 -1.287260
            +v 0.274486 0.022219 -0.986255
            +v 0.344878 0.046871 -1.239180
            +v 0.383385 0.077773 -1.377540
            +v 0.399515 0.112842 -1.435500
            +v 0.000000 0.022218 -1.022220
            +v 0.000000 0.046871 -1.284370
            +v 0.000000 0.077773 -1.427780
            +v 0.000000 0.112842 -1.487850
            +v -0.274486 0.022219 -0.986255
            +v -0.344878 0.046871 -1.239180
            +v -0.383385 0.077773 -1.377540
            +v -0.399515 0.112842 -1.435500
            +v -0.519440 0.022219 -0.884412
            +v -0.652653 0.046871 -1.111220
            +v -0.725523 0.077774 -1.235290
            +v -0.756047 0.112842 -1.287260
            +v -0.725778 0.022219 -0.725778
            +v -0.911906 0.046872 -0.911906
            +v -1.013720 0.077774 -1.013720
            +v -1.056370 0.112843 -1.056370
            +v -0.884412 0.022220 -0.519440
            +v -1.111220 0.046873 -0.652653
            +v -1.235290 0.077775 -0.725523
            +v -1.287260 0.112844 -0.756047
            +v -0.986255 0.022221 -0.274486
            +v -1.239180 0.046874 -0.344878
            +v -1.377540 0.077777 -0.383385
            +v -1.435500 0.112846 -0.399515
            +v -1.022220 0.022222 -0.000000
            +v -1.284370 0.046875 -0.000000
            +v -1.427780 0.077778 -0.000000
            +v -1.487850 0.112847 -0.000000
            +v -0.986255 0.022223 0.274486
            +v -1.239180 0.046876 0.344878
            +v -1.377540 0.077779 0.383385
            +v -1.435500 0.112848 0.399515
            +v -0.884412 0.022224 0.519440
            +v -1.111220 0.046877 0.652653
            +v -1.235290 0.077781 0.725523
            +v -1.287260 0.112850 0.756047
            +v -0.725778 0.022225 0.725778
            +v -0.911906 0.046878 0.911906
            +v -1.013720 0.077782 1.013720
            +v -1.056370 0.112851 1.056370
            +v -0.519440 0.022225 0.884412
            +v -0.652653 0.046879 1.111220
            +v -0.725523 0.077782 1.235290
            +v -0.756047 0.112852 1.287260
            +v -0.274486 0.022225 0.986255
            +v -0.344878 0.046879 1.239180
            +v -0.383385 0.077783 1.377540
            +v -0.399515 0.112852 1.435500
            +v 0.000000 0.022226 1.022220
            +v 0.000000 0.046879 1.284370
            +v 0.000000 0.077783 1.427780
            +v 0.000000 0.112852 1.487850
            +v 0.274486 0.022225 0.986255
            +v 0.344878 0.046879 1.239180
            +v 0.383385 0.077783 1.377540
            +v 0.399515 0.112852 1.435500
            +v 0.519440 0.022225 0.884412
            +v 0.652653 0.046879 1.111220
            +v 0.725523 0.077782 1.235290
            +v 0.756047 0.112852 1.287260
            +v 0.725778 0.022225 0.725778
            +v 0.911906 0.046878 0.911906
            +v 1.013720 0.077782 1.013720
            +v 1.056370 0.112851 1.056370
            +v 0.884412 0.022224 0.519440
            +v 1.111220 0.046877 0.652653
            +v 1.235290 0.077781 0.725523
            +v 1.287260 0.112850 0.756047
            +v 0.986255 0.022223 0.274486
            +v 1.239180 0.046876 0.344878
            +v 1.377540 0.077779 0.383385
            +v 1.435500 0.112848 0.399515
            +v 0.192963 2.700000 0.053694
            +v 0.200000 2.700000 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.173037 2.700000 0.101620
            +v 0.148234 2.785420 0.087096
            +v 0.142000 2.700000 0.141990
            +v 0.121672 2.785420 0.121662
            +v 0.101630 2.700000 0.173027
            +v 0.087106 2.785420 0.148224
            +v 0.053704 2.700000 0.192953
            +v 0.046045 2.785420 0.165269
            +v 0.000000 2.700000 0.199990
            +v 0.000000 2.785420 0.171286
            +v -0.053704 2.700000 0.192953
            +v -0.046045 2.785420 0.165269
            +v -0.101630 2.700000 0.173027
            +v -0.087106 2.785420 0.148224
            +v -0.142000 2.700000 0.141990
            +v -0.121672 2.785420 0.121662
            +v -0.173037 2.700000 0.101620
            +v -0.148234 2.785420 0.087096
            +v -0.192963 2.700000 0.053694
            +v -0.165279 2.785420 0.046035
            +v -0.200000 2.700000 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.192963 2.700000 -0.053714
            +v -0.165279 2.785420 -0.046055
            +v -0.173037 2.700000 -0.101640
            +v -0.148234 2.785420 -0.087116
            +v -0.142000 2.700000 -0.142010
            +v -0.121672 2.785420 -0.121682
            +v -0.101630 2.700000 -0.173047
            +v -0.087106 2.785420 -0.148244
            +v -0.053704 2.700000 -0.192973
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 2.700000 -0.200010
            +v 0.000000 2.785420 -0.171306
            +v 0.053704 2.700000 -0.192973
            +v 0.046045 2.785420 -0.165289
            +v 0.101630 2.700000 -0.173047
            +v 0.087106 2.785420 -0.148244
            +v 0.142000 2.700000 -0.142010
            +v 0.121672 2.785420 -0.121682
            +v 0.173037 2.700000 -0.101640
            +v 0.148234 2.785420 -0.087116
            +v 0.192963 2.700000 -0.053714
            +v 0.165279 2.785420 -0.046055
            +v 0.338579 2.636110 0.094221
            +v 0.350926 2.636110 -0.000009
            +v 0.553875 2.588890 0.154140
            +v 0.574074 2.588890 -0.000009
            +v 0.795972 2.550000 0.221519
            +v 0.825000 2.550000 -0.000009
            +v 1.021990 2.511110 0.284422
            +v 1.059260 2.511110 -0.000009
            +v 1.189040 2.463890 0.330915
            +v 1.232410 2.463890 -0.000009
            +v 1.254260 2.400000 0.349065
            +v 1.300000 2.400000 -0.000008
            +v 0.303616 2.636110 0.178312
            +v 0.496680 2.588890 0.291705
            +v 0.713778 2.550000 0.419213
            +v 0.916455 2.511110 0.538252
            +v 1.066260 2.463890 0.626237
            +v 1.124740 2.400000 0.660584
            +v 0.249157 2.636110 0.249147
            +v 0.407593 2.588890 0.407583
            +v 0.585750 2.550000 0.585741
            +v 0.752074 2.511110 0.752065
            +v 0.875009 2.463890 0.875000
            +v 0.923000 2.400000 0.922991
            +v 0.178322 2.636110 0.303606
            +v 0.291715 2.588890 0.496670
            +v 0.419222 2.550000 0.713769
            +v 0.538261 2.511110 0.916446
            +v 0.626246 2.463890 1.066250
            +v 0.660593 2.400000 1.124730
            +v 0.094230 2.636110 0.338569
            +v 0.154150 2.588890 0.553865
            +v 0.221528 2.550000 0.795963
            +v 0.284431 2.511110 1.021980
            +v 0.330924 2.463890 1.189030
            +v 0.349074 2.400000 1.254250
            +v 0.000000 2.636110 0.350916
            +v 0.000000 2.588890 0.574064
            +v 0.000000 2.550000 0.824991
            +v 0.000000 2.511110 1.059250
            +v 0.000000 2.463890 1.232400
            +v 0.000000 2.400000 1.299990
            +v -0.094230 2.636110 0.338569
            +v -0.154150 2.588890 0.553865
            +v -0.221528 2.550000 0.795963
            +v -0.284431 2.511110 1.021980
            +v -0.330924 2.463890 1.189030
            +v -0.349074 2.400000 1.254250
            +v -0.178322 2.636110 0.303606
            +v -0.291715 2.588890 0.496670
            +v -0.419222 2.550000 0.713769
            +v -0.538261 2.511110 0.916446
            +v -0.626246 2.463890 1.066250
            +v -0.660593 2.400000 1.124730
            +v -0.249157 2.636110 0.249147
            +v -0.407593 2.588890 0.407583
            +v -0.585750 2.550000 0.585741
            +v -0.752074 2.511110 0.752065
            +v -0.875009 2.463890 0.875000
            +v -0.923000 2.400000 0.922991
            +v -0.303616 2.636110 0.178312
            +v -0.496680 2.588890 0.291705
            +v -0.713778 2.550000 0.419213
            +v -0.916455 2.511110 0.538252
            +v -1.066260 2.463890 0.626237
            +v -1.124740 2.400000 0.660584
            +v -0.338579 2.636110 0.094221
            +v -0.553875 2.588890 0.154140
            +v -0.795972 2.550000 0.221519
            +v -1.021990 2.511110 0.284422
            +v -1.189040 2.463890 0.330915
            +v -1.254260 2.400000 0.349065
            +v -0.350926 2.636110 -0.000009
            +v -0.574074 2.588890 -0.000009
            +v -0.825000 2.550000 -0.000009
            +v -1.059260 2.511110 -0.000009
            +v -1.232410 2.463890 -0.000009
            +v -1.300000 2.400000 -0.000008
            +v -0.338579 2.636110 -0.094239
            +v -0.553875 2.588890 -0.154160
            +v -0.795972 2.550000 -0.221537
            +v -1.021990 2.511110 -0.284440
            +v -1.189040 2.463890 -0.330933
            +v -1.254260 2.400000 -0.349083
            +v -0.303616 2.636110 -0.178332
            +v -0.496680 2.588890 -0.291725
            +v -0.713778 2.550000 -0.419231
            +v -0.916455 2.511110 -0.538270
            +v -1.066260 2.463890 -0.626255
            +v -1.124740 2.400000 -0.660602
            +v -0.249157 2.636110 -0.249167
            +v -0.407593 2.588890 -0.407603
            +v -0.585750 2.550000 -0.585759
            +v -0.752074 2.511110 -0.752083
            +v -0.875009 2.463890 -0.875018
            +v -0.923000 2.400000 -0.923009
            +v -0.178322 2.636110 -0.303626
            +v -0.291715 2.588890 -0.496690
            +v -0.419222 2.550000 -0.713787
            +v -0.538261 2.511110 -0.916464
            +v -0.626246 2.463890 -1.066270
            +v -0.660593 2.400000 -1.124750
            +v -0.094230 2.636110 -0.338589
            +v -0.154150 2.588890 -0.553885
            +v -0.221528 2.550000 -0.795981
            +v -0.284431 2.511110 -1.022000
            +v -0.330924 2.463890 -1.189050
            +v -0.349074 2.400000 -1.254270
            +v 0.000000 2.636110 -0.350936
            +v 0.000000 2.588890 -0.574084
            +v 0.000000 2.550000 -0.825009
            +v 0.000000 2.511110 -1.059270
            +v 0.000000 2.463890 -1.232420
            +v 0.000000 2.400000 -1.300010
            +v 0.094230 2.636110 -0.338589
            +v 0.154150 2.588890 -0.553885
            +v 0.221528 2.550000 -0.795981
            +v 0.284431 2.511110 -1.022000
            +v 0.330924 2.463890 -1.189050
            +v 0.349074 2.400000 -1.254270
            +v 0.178322 2.636110 -0.303626
            +v 0.291715 2.588890 -0.496690
            +v 0.419222 2.550000 -0.713787
            +v 0.538261 2.511110 -0.916464
            +v 0.626246 2.463890 -1.066270
            +v 0.660593 2.400000 -1.124750
            +v 0.249157 2.636110 -0.249167
            +v 0.407593 2.588890 -0.407603
            +v 0.585750 2.550000 -0.585759
            +v 0.752074 2.511110 -0.752083
            +v 0.875009 2.463890 -0.875018
            +v 0.923000 2.400000 -0.923009
            +v 0.303616 2.636110 -0.178332
            +v 0.496680 2.588890 -0.291725
            +v 0.713778 2.550000 -0.419231
            +v 0.916455 2.511110 -0.538270
            +v 1.066260 2.463890 -0.626255
            +v 1.124740 2.400000 -0.660602
            +v 0.338579 2.636110 -0.094239
            +v 0.553875 2.588890 -0.154160
            +v 0.795972 2.550000 -0.221537
            +v 1.021990 2.511110 -0.284440
            +v 1.189040 2.463890 -0.330933
            +v 1.254260 2.400000 -0.349083
            +v -1.924540 2.023960 -0.000007
            +v -1.600000 2.025000 -0.000007
            +v -1.927040 2.040550 0.124992
            +v -1.592590 2.041670 0.124992
            +v -2.196300 2.016670 -0.000007
            +v -2.206450 2.032720 0.124992
            +v -2.428240 2.011460 0.124993
            +v -2.412500 1.996870 -0.000007
            +v -2.589850 1.970060 0.124993
            +v -2.570370 1.958330 -0.000007
            +v -2.688700 1.901810 0.124993
            +v -2.667130 1.894790 -0.000007
            +v -2.722220 1.800000 0.124993
            +v -2.700000 1.800000 -0.000006
            +v -1.933300 2.082020 0.199992
            +v -1.574070 2.083330 0.199992
            +v -2.231820 2.072840 0.199992
            +v -2.467590 2.047920 0.199992
            +v -2.638550 1.999380 0.199993
            +v -2.742630 1.919370 0.199993
            +v -2.777780 1.800000 0.199993
            +v -1.941440 2.135940 0.224992
            +v -1.550000 2.137500 0.224992
            +v -2.264810 2.125000 0.224992
            +v -2.518750 2.095310 0.224992
            +v -2.701850 2.037500 0.224992
            +v -2.812730 1.942190 0.224993
            +v -2.850000 1.800000 0.224993
            +v -1.949570 2.189850 0.199992
            +v -1.525930 2.191670 0.199992
            +v -2.297810 2.177160 0.199992
            +v -2.569910 2.142710 0.199992
            +v -2.765160 2.075620 0.199992
            +v -2.882840 1.965010 0.199993
            +v -2.922220 1.800000 0.199993
            +v -1.955830 2.231330 0.124992
            +v -1.507410 2.233330 0.124992
            +v -2.323180 2.217280 0.124992
            +v -2.609260 2.179170 0.124992
            +v -2.813850 2.104940 0.124992
            +v -2.936760 1.982560 0.124993
            +v -2.977780 1.800000 0.124993
            +v -1.958330 2.247920 -0.000008
            +v -1.500000 2.250000 -0.000008
            +v -2.333330 2.233330 -0.000008
            +v -2.625000 2.193750 -0.000008
            +v -2.833330 2.116670 -0.000007
            +v -2.958330 1.989580 -0.000007
            +v -3.000000 1.800000 -0.000006
            +v -1.507410 2.233330 -0.125008
            +v -1.955830 2.231330 -0.125008
            +v -2.323180 2.217280 -0.125008
            +v -2.609260 2.179170 -0.125008
            +v -2.813850 2.104940 -0.125008
            +v -2.936760 1.982560 -0.125007
            +v -2.977780 1.800000 -0.125007
            +v -1.525930 2.191670 -0.200008
            +v -1.949570 2.189850 -0.200008
            +v -2.297810 2.177160 -0.200008
            +v -2.569910 2.142710 -0.200008
            +v -2.765160 2.075620 -0.200008
            +v -2.882840 1.965010 -0.200007
            +v -2.922220 1.800000 -0.200007
            +v -1.550000 2.137500 -0.225008
            +v -1.941440 2.135940 -0.225008
            +v -2.264810 2.125000 -0.225008
            +v -2.518750 2.095310 -0.225008
            +v -2.701850 2.037500 -0.225008
            +v -2.812730 1.942190 -0.225007
            +v -2.850000 1.800000 -0.225007
            +v -1.574070 2.083330 -0.200008
            +v -1.933300 2.082020 -0.200008
            +v -2.231820 2.072840 -0.200008
            +v -2.467590 2.047920 -0.200008
            +v -2.638550 1.999380 -0.200007
            +v -2.742630 1.919370 -0.200007
            +v -2.777780 1.800000 -0.200007
            +v -1.592590 2.041670 -0.125008
            +v -1.927040 2.040550 -0.125008
            +v -2.206450 2.032720 -0.125008
            +v -2.428240 2.011460 -0.125007
            +v -2.589850 1.970060 -0.125007
            +v -2.688700 1.901810 -0.125007
            +v -2.722220 1.800000 -0.125007
            +v -2.704180 1.663980 0.124994
            +v -2.682870 1.670830 -0.000006
            +v -2.648290 1.505350 0.124994
            +v -2.629630 1.516670 -0.000005
            +v -2.551850 1.335760 0.124995
            +v -2.537500 1.350000 -0.000005
            +v -2.412210 1.166870 0.124996
            +v -2.403700 1.183330 -0.000004
            +v -2.226680 1.010330 0.124996
            +v -2.225460 1.029170 -0.000004
            +v -1.992590 0.877778 0.124997
            +v -2.000000 0.900000 -0.000003
            +v -2.757470 1.646840 0.199994
            +v -2.694920 1.477060 0.199995
            +v -2.587730 1.300170 0.199995
            +v -2.433470 1.125720 0.199996
            +v -2.229720 0.963228 0.199996
            +v -1.974070 0.822223 0.199997
            +v -2.826740 1.624570 0.224994
            +v -2.755560 1.440280 0.224995
            +v -2.634370 1.253910 0.224995
            +v -2.461110 1.072220 0.224996
            +v -2.233680 0.901998 0.224997
            +v -1.950000 0.750001 0.224997
            +v -2.896000 1.602290 0.199994
            +v -2.816190 1.403500 0.199995
            +v -2.681020 1.207640 0.199996
            +v -2.488750 1.018720 0.199996
            +v -2.237640 0.840767 0.199997
            +v -1.925930 0.677779 0.199997
            +v -2.949290 1.585150 0.124994
            +v -2.862830 1.375210 0.124995
            +v -2.716900 1.172050 0.124996
            +v -2.510010 0.977573 0.124996
            +v -2.240680 0.793666 0.124997
            +v -1.907410 0.622222 0.124998
            +v -2.970600 1.578300 -0.000006
            +v -2.881480 1.363890 -0.000005
            +v -2.731250 1.157810 -0.000004
            +v -2.518520 0.961111 -0.000003
            +v -2.241900 0.774826 -0.000003
            +v -1.900000 0.600000 -0.000002
            +v -2.949290 1.585150 -0.125006
            +v -2.862830 1.375210 -0.125005
            +v -2.716900 1.172050 -0.125004
            +v -2.510010 0.977572 -0.125004
            +v -2.240680 0.793666 -0.125003
            +v -1.907410 0.622222 -0.125002
            +v -2.896000 1.602290 -0.200006
            +v -2.816190 1.403500 -0.200005
            +v -2.681020 1.207640 -0.200004
            +v -2.488750 1.018720 -0.200004
            +v -2.237640 0.840765 -0.200003
            +v -1.925930 0.677777 -0.200003
            +v -2.826740 1.624570 -0.225006
            +v -2.755560 1.440280 -0.225005
            +v -2.634370 1.253910 -0.225005
            +v -2.461110 1.072220 -0.225004
            +v -2.233680 0.901996 -0.225003
            +v -1.950000 0.749999 -0.225003
            +v -2.757470 1.646840 -0.200006
            +v -2.694920 1.477060 -0.200005
            +v -2.587730 1.300170 -0.200005
            +v -2.433470 1.125720 -0.200004
            +v -2.229720 0.963226 -0.200004
            +v -1.974070 0.822221 -0.200003
            +v -2.704180 1.663980 -0.125006
            +v -2.648290 1.505350 -0.125006
            +v -2.551850 1.335760 -0.125005
            +v -2.412210 1.166870 -0.125004
            +v -2.226680 1.010330 -0.125004
            +v -1.992590 0.877778 -0.125003
            +v 1.700000 1.425000 -0.000005
            +v 1.700000 1.363890 0.274995
            +v 2.072380 1.425210 0.262341
            +v 2.058800 1.476390 -0.000005
            +v 2.290120 1.572020 0.230704
            +v 2.270370 1.611110 -0.000006
            +v 2.409720 1.773610 0.189576
            +v 2.387500 1.800000 -0.000006
            +v 2.487650 1.999280 0.148450
            +v 2.462960 2.013890 -0.000007
            +v 2.580400 2.218310 0.116813
            +v 2.549540 2.223610 -0.000008
            +v 2.700000 2.400000 -0.000008
            +v 2.744440 2.400000 0.104158
            +v 1.700000 1.211110 0.439996
            +v 2.106330 1.297250 0.419748
            +v 2.339510 1.474280 0.369131
            +v 2.465280 1.707640 0.303327
            +v 2.549380 1.962760 0.237524
            +v 2.657560 2.205070 0.186906
            +v 2.855560 2.400000 0.166658
            +v 1.700000 1.012500 0.494996
            +v 2.150460 1.130900 0.472218
            +v 2.403700 1.347220 0.415273
            +v 2.537500 1.621870 0.341244
            +v 2.629630 1.915280 0.267215
            +v 2.757870 2.187850 0.210270
            +v 3.000000 2.400000 0.187491
            +v 1.700000 0.813891 0.439997
            +v 2.194600 0.964560 0.419749
            +v 2.467900 1.220160 0.369132
            +v 2.609720 1.536110 0.303327
            +v 2.709880 1.867800 0.237524
            +v 2.858180 2.170630 0.186906
            +v 3.144440 2.400000 0.166658
            +v 1.700000 0.661112 0.274998
            +v 2.228550 0.836601 0.262343
            +v 2.517280 1.122430 0.230706
            +v 2.665280 1.470140 0.189578
            +v 2.771600 1.831280 0.148450
            +v 2.935340 2.157380 0.116813
            +v 3.255560 2.400000 0.104158
            +v 1.700000 0.600000 -0.000002
            +v 2.242130 0.785417 -0.000003
            +v 2.537040 1.083330 -0.000004
            +v 2.687500 1.443750 -0.000005
            +v 2.796300 1.816670 -0.000006
            +v 2.966200 2.152080 -0.000008
            +v 3.300000 2.400000 -0.000008
            +v 1.700000 0.661110 -0.275002
            +v 2.228550 0.836599 -0.262349
            +v 2.517280 1.122430 -0.230714
            +v 2.665280 1.470140 -0.189588
            +v 2.771600 1.831280 -0.148464
            +v 2.935340 2.157380 -0.116829
            +v 3.255560 2.400000 -0.104176
            +v 1.700000 0.813887 -0.440003
            +v 2.194600 0.964556 -0.419757
            +v 2.467900 1.220160 -0.369141
            +v 2.609720 1.536110 -0.303339
            +v 2.709880 1.867800 -0.237538
            +v 2.858180 2.170630 -0.186922
            +v 3.144440 2.400000 -0.166676
            +v 1.700000 1.012500 -0.495004
            +v 2.150460 1.130900 -0.472226
            +v 2.403700 1.347220 -0.415283
            +v 2.537500 1.621870 -0.341256
            +v 2.629630 1.915280 -0.267229
            +v 2.757870 2.187850 -0.210286
            +v 3.000000 2.400000 -0.187509
            +v 1.700000 1.211110 -0.440004
            +v 2.106330 1.297250 -0.419758
            +v 2.339510 1.474280 -0.369141
            +v 2.465280 1.707640 -0.303339
            +v 2.549380 1.962760 -0.237538
            +v 2.657560 2.205070 -0.186922
            +v 2.855560 2.400000 -0.166676
            +v 1.700000 1.363890 -0.275005
            +v 2.072380 1.425210 -0.262351
            +v 2.290120 1.572020 -0.230716
            +v 2.409720 1.773610 -0.189590
            +v 2.487650 1.999280 -0.148464
            +v 2.580400 2.218310 -0.116829
            +v 2.744440 2.400000 -0.104176
            +v 2.749070 2.431250 -0.000009
            +v 2.796410 2.431930 0.101023
            +v 2.792590 2.450000 -0.000009
            +v 2.839780 2.451230 0.092969
            +v 2.825000 2.456250 -0.000009
            +v 2.869680 2.457810 0.082022
            +v 2.881210 2.451540 0.070207
            +v 2.840740 2.450000 -0.000009
            +v 2.869490 2.432310 0.059549
            +v 2.834260 2.431250 -0.000009
            +v 2.829630 2.400000 0.052074
            +v 2.800000 2.400000 -0.000008
            +v 2.914740 2.433610 0.161565
            +v 2.957750 2.454320 0.148139
            +v 2.981370 2.461720 0.129158
            +v 2.982370 2.455400 0.107398
            +v 2.957560 2.434960 0.085639
            +v 2.903700 2.400000 0.066658
            +v 3.068580 2.435810 0.181675
            +v 3.111110 2.458330 0.165963
            +v 3.126560 2.466800 0.142960
            +v 3.113890 2.460420 0.115269
            +v 3.072050 2.438410 0.085495
            +v 3.000000 2.400000 0.056241
            +v 3.222410 2.438000 0.161411
            +v 3.264470 2.462350 0.146905
            +v 3.271760 2.471870 0.124991
            +v 3.245400 2.465430 0.097522
            +v 3.186540 2.441860 0.066349
            +v 3.096300 2.400000 0.033324
            +v 3.340750 2.439690 0.100830
            +v 3.382440 2.465430 0.091426
            +v 3.383450 2.475780 0.076814
            +v 3.346570 2.469290 0.057861
            +v 3.274610 2.444510 0.035437
            +v 3.170370 2.400000 0.010408
            +v 3.388080 2.440360 -0.000009
            +v 3.429630 2.466670 -0.000009
            +v 3.428130 2.477340 -0.000009
            +v 3.387040 2.470830 -0.000009
            +v 3.309840 2.445570 -0.000009
            +v 3.200000 2.400000 -0.000008
            +v 3.340750 2.439690 -0.101089
            +v 3.382440 2.465430 -0.093373
            +v 3.383450 2.475780 -0.083342
            +v 3.346570 2.469290 -0.073312
            +v 3.274610 2.444510 -0.065595
            +v 3.170370 2.400000 -0.062509
            +v 3.222410 2.438000 -0.161737
            +v 3.264470 2.462350 -0.149392
            +v 3.271760 2.471870 -0.133342
            +v 3.245400 2.465430 -0.117293
            +v 3.186540 2.441860 -0.104947
            +v 3.096300 2.400000 -0.100009
            +v 3.068580 2.435810 -0.181953
            +v 3.111110 2.458330 -0.168065
            +v 3.126560 2.466800 -0.150009
            +v 3.113890 2.460420 -0.131953
            +v 3.072050 2.438410 -0.118065
            +v 3.000000 2.400000 -0.112509
            +v 2.914740 2.433610 -0.161737
            +v 2.957750 2.454320 -0.149392
            +v 2.981370 2.461720 -0.133342
            +v 2.982370 2.455400 -0.117293
            +v 2.957560 2.434960 -0.104947
            +v 2.903700 2.400000 -0.100009
            +v 2.796410 2.431930 -0.101089
            +v 2.839780 2.451230 -0.093373
            +v 2.869680 2.457810 -0.083342
            +v 2.881210 2.451540 -0.073312
            +v 2.869490 2.432310 -0.065595
            +v 2.829630 2.400000 -0.062509
            +v 0.278704 3.127080 -0.000011
            +v 0.000000 3.150000 -0.000011
            +v 0.268946 3.127080 0.075067
            +v 0.241285 3.127080 0.141920
            +v 0.198140 3.127080 0.198129
            +v 0.141931 3.127080 0.241274
            +v 0.075078 3.127080 0.268935
            +v 0.000000 3.127080 0.278693
            +v -0.075078 3.127080 0.268935
            +v -0.141931 3.127080 0.241274
            +v -0.198140 3.127080 0.198129
            +v -0.241285 3.127080 0.141920
            +v -0.268946 3.127080 0.075067
            +v -0.278704 3.127080 -0.000011
            +v -0.268946 3.127080 -0.075089
            +v -0.241285 3.127080 -0.141942
            +v -0.198140 3.127080 -0.198151
            +v -0.141931 3.127080 -0.241296
            +v -0.075078 3.127080 -0.268957
            +v 0.000000 3.127080 -0.278715
            +v 0.075078 3.127080 -0.268957
            +v 0.141931 3.127080 -0.241296
            +v 0.198140 3.127080 -0.198151
            +v 0.241285 3.127080 -0.141942
            +v 0.268946 3.127080 -0.075089
            +v 0.350254 3.066670 0.097760
            +v 0.362963 3.066670 -0.000011
            +v 0.313617 2.981250 0.087518
            +v 0.325000 2.981250 -0.000011
            +v 0.228728 2.883330 0.063793
            +v 0.237037 2.883330 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.314228 3.066670 0.184824
            +v 0.281352 2.981250 0.165470
            +v 0.205180 2.883330 0.120636
            +v 0.148234 2.785420 0.087096
            +v 0.258037 3.066670 0.258027
            +v 0.231031 2.981250 0.231020
            +v 0.168463 2.883330 0.168452
            +v 0.121672 2.785420 0.121662
            +v 0.184834 3.066670 0.314218
            +v 0.165481 2.981250 0.281341
            +v 0.120647 2.883330 0.205169
            +v 0.087106 2.785420 0.148224
            +v 0.097771 3.066670 0.350244
            +v 0.087529 2.981250 0.313606
            +v 0.063803 2.883330 0.228717
            +v 0.046045 2.785420 0.165269
            +v 0.000000 3.066670 0.362953
            +v 0.000000 2.981250 0.324989
            +v 0.000000 2.883330 0.237026
            +v 0.000000 2.785420 0.171286
            +v -0.097771 3.066670 0.350244
            +v -0.087529 2.981250 0.313606
            +v -0.063803 2.883330 0.228717
            +v -0.046045 2.785420 0.165269
            +v -0.184834 3.066670 0.314218
            +v -0.165481 2.981250 0.281341
            +v -0.120647 2.883330 0.205169
            +v -0.087106 2.785420 0.148224
            +v -0.258037 3.066670 0.258027
            +v -0.231031 2.981250 0.231020
            +v -0.168463 2.883330 0.168452
            +v -0.121672 2.785420 0.121662
            +v -0.314228 3.066670 0.184824
            +v -0.281352 2.981250 0.165470
            +v -0.205180 2.883330 0.120636
            +v -0.148234 2.785420 0.087096
            +v -0.350254 3.066670 0.097760
            +v -0.313617 2.981250 0.087518
            +v -0.228728 2.883330 0.063793
            +v -0.165279 2.785420 0.046035
            +v -0.362963 3.066670 -0.000011
            +v -0.325000 2.981250 -0.000011
            +v -0.237037 2.883330 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.350254 3.066670 -0.097782
            +v -0.313617 2.981250 -0.087540
            +v -0.228728 2.883330 -0.063813
            +v -0.165279 2.785420 -0.046055
            +v -0.314228 3.066670 -0.184844
            +v -0.281352 2.981250 -0.165492
            +v -0.205180 2.883330 -0.120658
            +v -0.148234 2.785420 -0.087116
            +v -0.258037 3.066670 -0.258047
            +v -0.231031 2.981250 -0.231042
            +v -0.168463 2.883330 -0.168474
            +v -0.121672 2.785420 -0.121682
            +v -0.184834 3.066670 -0.314238
            +v -0.165481 2.981250 -0.281363
            +v -0.120647 2.883330 -0.205191
            +v -0.087106 2.785420 -0.148244
            +v -0.097771 3.066670 -0.350264
            +v -0.087529 2.981250 -0.313628
            +v -0.063803 2.883330 -0.228739
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 3.066670 -0.362973
            +v 0.000000 2.981250 -0.325011
            +v 0.000000 2.883330 -0.237048
            +v 0.000000 2.785420 -0.171306
            +v 0.097771 3.066670 -0.350264
            +v 0.087529 2.981250 -0.313628
            +v 0.063803 2.883330 -0.228739
            +v 0.046045 2.785420 -0.165289
            +v 0.184834 3.066670 -0.314238
            +v 0.165481 2.981250 -0.281363
            +v 0.120647 2.883330 -0.205191
            +v 0.087106 2.785420 -0.148244
            +v 0.258037 3.066670 -0.258047
            +v 0.231031 2.981250 -0.231042
            +v 0.168463 2.883330 -0.168474
            +v 0.121672 2.785420 -0.121682
            +v 0.314228 3.066670 -0.184844
            +v 0.281352 2.981250 -0.165492
            +v 0.205180 2.883330 -0.120658
            +v 0.148234 2.785420 -0.087116
            +v 0.350254 3.066670 -0.097782
            +v 0.313617 2.981250 -0.087540
            +v 0.228728 2.883330 -0.063813
            +v 0.165279 2.785420 -0.046055
            +vn 0.025666 -0.999664 0.000000
            +vn 0.000000 -1.000000 0.000000
            +vn 0.024781 -0.999664 -0.006623
            +vn 0.022156 -0.999664 -0.012787
            +vn 0.018067 -0.999664 -0.018067
            +vn 0.012787 -0.999664 -0.022126
            +vn 0.006623 -0.999664 -0.024751
            +vn 0.000000 -0.999664 -0.025666
            +vn -0.006623 -0.999664 -0.024751
            +vn -0.012787 -0.999664 -0.022126
            +vn -0.018067 -0.999664 -0.018067
            +vn -0.022156 -0.999664 -0.012787
            +vn -0.024781 -0.999664 -0.006623
            +vn -0.025666 -0.999664 0.000000
            +vn -0.024781 -0.999664 0.006623
            +vn -0.022156 -0.999664 0.012787
            +vn -0.018067 -0.999664 0.018067
            +vn -0.012787 -0.999664 0.022156
            +vn -0.006623 -0.999664 0.024781
            +vn 0.000000 -0.999664 0.025666
            +vn 0.006623 -0.999664 0.024781
            +vn 0.012787 -0.999664 0.022156
            +vn 0.018067 -0.999664 0.018067
            +vn 0.022156 -0.999664 0.012787
            +vn 0.024781 -0.999664 0.006623
            +vn -0.946562 -0.322459 0.000000
            +vn -0.913999 -0.322947 -0.245491
            +vn -0.958617 -0.122227 -0.257057
            +vn -0.992523 -0.122013 0.000000
            +vn -0.832057 0.554674 0.000000
            +vn -0.803217 0.555376 -0.215308
            +vn -0.048616 0.998810 0.000000
            +vn -0.046205 0.998840 -0.012726
            +vn 0.525376 0.839106 0.140843
            +vn 0.544267 0.838893 0.000000
            +vn 0.756340 0.621845 0.202918
            +vn 0.783471 0.621387 0.000000
            +vn 0.850551 0.473769 0.228217
            +vn 0.880886 0.473281 0.000000
            +vn -0.818842 -0.323435 -0.474166
            +vn -0.859004 -0.122410 -0.497085
            +vn -0.719657 0.555559 -0.416425
            +vn -0.041749 0.998810 -0.024415
            +vn 0.470107 0.839625 0.272011
            +vn 0.677236 0.622608 0.391980
            +vn 0.761803 0.474471 0.440962
            +vn -0.669027 -0.323679 -0.669027
            +vn -0.701773 -0.122440 -0.701773
            +vn -0.587878 0.555650 -0.587878
            +vn -0.034272 0.998810 -0.034272
            +vn 0.383831 0.839808 0.383831
            +vn 0.553148 0.622913 0.553148
            +vn 0.622303 0.474776 0.622303
            +vn -0.474166 -0.323435 -0.818842
            +vn -0.497085 -0.122410 -0.859004
            +vn -0.416425 0.555528 -0.719657
            +vn -0.024415 0.998810 -0.041749
            +vn 0.272011 0.839625 0.470077
            +vn 0.392010 0.622608 0.677236
            +vn 0.440962 0.474502 0.761803
            +vn -0.245460 -0.322977 -0.913999
            +vn -0.257057 -0.122257 -0.958617
            +vn -0.215339 0.555193 -0.803308
            +vn -0.012726 0.998840 -0.046236
            +vn 0.140873 0.839076 0.525437
            +vn 0.202918 0.621906 0.756310
            +vn 0.228217 0.473769 0.850551
            +vn 0.000000 -0.322489 -0.946562
            +vn 0.000000 -0.122044 -0.992523
            +vn 0.000000 0.554491 -0.832179
            +vn 0.000000 0.998779 -0.048799
            +vn 0.000000 0.838893 0.544267
            +vn 0.000000 0.621387 0.783471
            +vn 0.000000 0.473281 0.880886
            +vn 0.245460 -0.322977 -0.913999
            +vn 0.257057 -0.122257 -0.958617
            +vn 0.215339 0.555193 -0.803308
            +vn 0.012726 0.998840 -0.046236
            +vn -0.140873 0.839076 0.525437
            +vn -0.202918 0.621906 0.756310
            +vn -0.228217 0.473769 0.850551
            +vn 0.474166 -0.323435 -0.818842
            +vn 0.497085 -0.122410 -0.859004
            +vn 0.416425 0.555528 -0.719657
            +vn 0.024415 0.998810 -0.041749
            +vn -0.272011 0.839625 0.470077
            +vn -0.392010 0.622608 0.677236
            +vn -0.440962 0.474502 0.761803
            +vn 0.669027 -0.323679 -0.669027
            +vn 0.701773 -0.122440 -0.701773
            +vn 0.587878 0.555650 -0.587878
            +vn 0.034272 0.998810 -0.034272
            +vn -0.383831 0.839808 0.383831
            +vn -0.553148 0.622913 0.553148
            +vn -0.622303 0.474776 0.622303
            +vn 0.818842 -0.323435 -0.474166
            +vn 0.859004 -0.122410 -0.497085
            +vn 0.719657 0.555559 -0.416425
            +vn 0.041749 0.998810 -0.024415
            +vn -0.470107 0.839625 0.272011
            +vn -0.677236 0.622608 0.391980
            +vn -0.761803 0.474471 0.440962
            +vn 0.913999 -0.322947 -0.245491
            +vn 0.958617 -0.122227 -0.257057
            +vn 0.803217 0.555376 -0.215308
            +vn 0.046205 0.998840 -0.012726
            +vn -0.525376 0.839106 0.140843
            +vn -0.756340 0.621845 0.202918
            +vn -0.850551 0.473769 0.228217
            +vn 0.946562 -0.322459 0.000000
            +vn 0.992523 -0.122013 0.000000
            +vn 0.832057 0.554674 0.000000
            +vn 0.048616 0.998810 0.000000
            +vn -0.544267 0.838893 0.000000
            +vn -0.783471 0.621387 0.000000
            +vn -0.880886 0.473281 0.000000
            +vn 0.913999 -0.322947 0.245491
            +vn 0.958617 -0.122227 0.257057
            +vn 0.803217 0.555376 0.215308
            +vn 0.046205 0.998840 0.012726
            +vn -0.525376 0.839106 -0.140843
            +vn -0.756340 0.621845 -0.202918
            +vn -0.850551 0.473769 -0.228217
            +vn 0.818842 -0.323435 0.474166
            +vn 0.859004 -0.122410 0.497085
            +vn 0.719657 0.555559 0.416425
            +vn 0.041749 0.998810 0.024415
            +vn -0.470107 0.839625 -0.272011
            +vn -0.677236 0.622608 -0.391980
            +vn -0.761803 0.474471 -0.440962
            +vn 0.669027 -0.323679 0.669027
            +vn 0.701773 -0.122440 0.701773
            +vn 0.587878 0.555650 0.587878
            +vn 0.034272 0.998810 0.034272
            +vn -0.383831 0.839808 -0.383831
            +vn -0.553148 0.622913 -0.553148
            +vn -0.622303 0.474776 -0.622303
            +vn 0.474166 -0.323435 0.818842
            +vn 0.497085 -0.122410 0.859004
            +vn 0.416425 0.555559 0.719657
            +vn 0.024415 0.998810 0.041749
            +vn -0.272011 0.839625 -0.470107
            +vn -0.391980 0.622608 -0.677236
            +vn -0.440962 0.474471 -0.761803
            +vn 0.245460 -0.322977 0.913999
            +vn 0.257027 -0.122257 0.958617
            +vn 0.215369 0.555193 0.803308
            +vn 0.012726 0.998840 0.046236
            +vn -0.140873 0.839045 -0.525498
            +vn -0.202918 0.621845 -0.756371
            +vn -0.228187 0.473769 -0.850551
            +vn 0.000000 -0.322459 0.946562
            +vn 0.000000 -0.122013 0.992523
            +vn 0.000000 0.554674 0.832057
            +vn 0.000000 0.998810 0.048616
            +vn 0.000000 0.838893 -0.544267
            +vn 0.000000 0.621387 -0.783471
            +vn 0.000000 0.473281 -0.880886
            +vn -0.245460 -0.322977 0.913999
            +vn -0.257027 -0.122257 0.958617
            +vn -0.215369 0.555193 0.803308
            +vn -0.012726 0.998840 0.046236
            +vn 0.140873 0.839045 -0.525498
            +vn 0.202918 0.621845 -0.756371
            +vn 0.228187 0.473769 -0.850551
            +vn -0.474166 -0.323435 0.818842
            +vn -0.497085 -0.122410 0.859004
            +vn -0.416425 0.555559 0.719657
            +vn -0.024415 0.998810 0.041749
            +vn 0.272011 0.839625 -0.470107
            +vn 0.391980 0.622608 -0.677236
            +vn 0.440962 0.474471 -0.761803
            +vn -0.669027 -0.323679 0.669027
            +vn -0.701773 -0.122440 0.701773
            +vn -0.587878 0.555650 0.587878
            +vn -0.034272 0.998810 0.034272
            +vn 0.383831 0.839808 -0.383831
            +vn 0.553148 0.622913 -0.553148
            +vn 0.622303 0.474776 -0.622303
            +vn -0.818842 -0.323435 0.474166
            +vn -0.859004 -0.122410 0.497085
            +vn -0.719657 0.555559 0.416425
            +vn -0.041749 0.998810 0.024415
            +vn 0.470107 0.839625 -0.272011
            +vn 0.677236 0.622608 -0.391980
            +vn 0.761803 0.474471 -0.440962
            +vn -0.913999 -0.322947 0.245491
            +vn -0.958617 -0.122227 0.257057
            +vn -0.803217 0.555376 0.215308
            +vn -0.046205 0.998840 0.012726
            +vn 0.525376 0.839106 -0.140843
            +vn 0.756340 0.621845 -0.202918
            +vn 0.850551 0.473769 -0.228217
            +vn 0.877041 0.418744 0.235298
            +vn 0.908292 0.418256 0.000000
            +vn 0.888668 0.391644 0.238441
            +vn 0.920286 0.391156 0.000000
            +vn 0.907315 0.342753 0.243446
            +vn 0.939543 0.342357 0.000000
            +vn 0.931028 0.265908 0.249855
            +vn 0.964080 0.265542 0.000000
            +vn 0.954558 0.152104 0.256172
            +vn 0.988372 0.151891 0.000000
            +vn 0.964782 -0.045717 0.258980
            +vn 0.998932 -0.045656 0.000000
            +vn 0.785638 0.419416 0.454756
            +vn 0.796075 0.392285 0.460799
            +vn 0.812830 0.343333 0.470504
            +vn 0.834162 0.266366 0.482864
            +vn 0.855312 0.152409 0.495132
            +vn 0.864498 -0.045808 0.500504
            +vn 0.641804 0.419691 0.641804
            +vn 0.650349 0.392529 0.650349
            +vn 0.664052 0.343577 0.664052
            +vn 0.681509 0.266579 0.681509
            +vn 0.698813 0.152501 0.698813
            +vn 0.706351 -0.045869 0.706351
            +vn 0.454756 0.419416 0.785638
            +vn 0.460799 0.392285 0.796075
            +vn 0.470504 0.343333 0.812830
            +vn 0.482864 0.266396 0.834162
            +vn 0.495132 0.152409 0.855312
            +vn 0.500504 -0.045808 0.864498
            +vn 0.235298 0.418744 0.877041
            +vn 0.238441 0.391644 0.888668
            +vn 0.243446 0.342753 0.907315
            +vn 0.249825 0.265908 0.931028
            +vn 0.256172 0.152135 0.954558
            +vn 0.258980 -0.045717 0.964782
            +vn 0.000000 0.418256 0.908292
            +vn 0.000000 0.391156 0.920286
            +vn 0.000000 0.342357 0.939543
            +vn 0.000000 0.265572 0.964080
            +vn 0.000000 0.151921 0.988372
            +vn 0.000000 -0.045656 0.998932
            +vn -0.235298 0.418744 0.877041
            +vn -0.238441 0.391644 0.888668
            +vn -0.243446 0.342753 0.907315
            +vn -0.249825 0.265908 0.931028
            +vn -0.256172 0.152135 0.954558
            +vn -0.258980 -0.045717 0.964782
            +vn -0.454756 0.419416 0.785638
            +vn -0.460799 0.392285 0.796075
            +vn -0.470504 0.343333 0.812830
            +vn -0.482864 0.266396 0.834162
            +vn -0.495132 0.152409 0.855312
            +vn -0.500504 -0.045808 0.864498
            +vn -0.641804 0.419691 0.641804
            +vn -0.650349 0.392529 0.650349
            +vn -0.664052 0.343577 0.664052
            +vn -0.681509 0.266579 0.681509
            +vn -0.698813 0.152501 0.698813
            +vn -0.706351 -0.045869 0.706351
            +vn -0.785638 0.419416 0.454756
            +vn -0.796075 0.392285 0.460799
            +vn -0.812830 0.343333 0.470504
            +vn -0.834162 0.266366 0.482864
            +vn -0.855312 0.152409 0.495132
            +vn -0.864498 -0.045808 0.500504
            +vn -0.877041 0.418744 0.235298
            +vn -0.888668 0.391644 0.238441
            +vn -0.907315 0.342753 0.243446
            +vn -0.931028 0.265908 0.249825
            +vn -0.954558 0.152104 0.256172
            +vn -0.964782 -0.045717 0.258980
            +vn -0.908292 0.418256 0.000000
            +vn -0.920286 0.391156 0.000000
            +vn -0.939543 0.342357 0.000000
            +vn -0.964080 0.265542 0.000000
            +vn -0.988372 0.151891 0.000000
            +vn -0.998932 -0.045656 0.000000
            +vn -0.877041 0.418744 -0.235298
            +vn -0.888668 0.391644 -0.238441
            +vn -0.907315 0.342753 -0.243446
            +vn -0.931028 0.265877 -0.249855
            +vn -0.954558 0.152104 -0.256172
            +vn -0.964782 -0.045717 -0.258980
            +vn -0.785638 0.419416 -0.454756
            +vn -0.796075 0.392285 -0.460799
            +vn -0.812830 0.343333 -0.470504
            +vn -0.834162 0.266366 -0.482864
            +vn -0.855312 0.152379 -0.495132
            +vn -0.864498 -0.045808 -0.500504
            +vn -0.641804 0.419691 -0.641804
            +vn -0.650349 0.392529 -0.650349
            +vn -0.664052 0.343547 -0.664052
            +vn -0.681509 0.266549 -0.681509
            +vn -0.698813 0.152470 -0.698813
            +vn -0.706351 -0.045869 -0.706351
            +vn -0.454756 0.419416 -0.785638
            +vn -0.460768 0.392285 -0.796075
            +vn -0.470504 0.343333 -0.812830
            +vn -0.482864 0.266366 -0.834162
            +vn -0.495132 0.152379 -0.855312
            +vn -0.500504 -0.045808 -0.864498
            +vn -0.235298 0.418744 -0.877041
            +vn -0.238441 0.391644 -0.888668
            +vn -0.243446 0.342753 -0.907315
            +vn -0.249855 0.265877 -0.931059
            +vn -0.256172 0.152074 -0.954558
            +vn -0.258980 -0.045717 -0.964782
            +vn 0.000000 0.418256 -0.908292
            +vn 0.000000 0.391156 -0.920286
            +vn 0.000000 0.342357 -0.939543
            +vn 0.000000 0.265511 -0.964080
            +vn 0.000000 0.151891 -0.988372
            +vn 0.000000 -0.045656 -0.998932
            +vn 0.235298 0.418744 -0.877041
            +vn 0.238441 0.391644 -0.888668
            +vn 0.243446 0.342753 -0.907315
            +vn 0.249855 0.265877 -0.931059
            +vn 0.256172 0.152074 -0.954558
            +vn 0.258980 -0.045717 -0.964782
            +vn 0.454756 0.419416 -0.785638
            +vn 0.460768 0.392285 -0.796075
            +vn 0.470504 0.343333 -0.812830
            +vn 0.482864 0.266366 -0.834162
            +vn 0.495132 0.152379 -0.855312
            +vn 0.500504 -0.045808 -0.864498
            +vn 0.641804 0.419691 -0.641804
            +vn 0.650349 0.392529 -0.650349
            +vn 0.664052 0.343547 -0.664052
            +vn 0.681509 0.266549 -0.681509
            +vn 0.698813 0.152470 -0.698813
            +vn 0.706351 -0.045869 -0.706351
            +vn 0.785638 0.419416 -0.454756
            +vn 0.796075 0.392285 -0.460799
            +vn 0.812830 0.343333 -0.470504
            +vn 0.834162 0.266366 -0.482864
            +vn 0.855312 0.152379 -0.495132
            +vn 0.864498 -0.045808 -0.500504
            +vn 0.877041 0.418744 -0.235298
            +vn 0.888668 0.391644 -0.238441
            +vn 0.907315 0.342753 -0.243446
            +vn 0.931028 0.265908 -0.249825
            +vn 0.954558 0.152104 -0.256172
            +vn 0.964782 -0.045717 -0.258980
            +vn 0.912839 -0.326609 0.245003
            +vn 0.945250 -0.326273 0.000000
            +vn 0.795892 -0.566485 0.213538
            +vn 0.824396 -0.565996 0.000000
            +vn 0.687399 -0.702445 0.184393
            +vn 0.712180 -0.701987 0.000000
            +vn 0.630146 -0.757805 0.169012
            +vn 0.652974 -0.757347 0.000000
            +vn 0.698752 -0.690329 0.187445
            +vn 0.724021 -0.689749 0.000000
            +vn 0.855861 -0.463454 0.229530
            +vn 0.886380 -0.462905 0.000000
            +vn 0.817774 -0.327158 0.473434
            +vn 0.712729 -0.567248 0.412549
            +vn 0.615375 -0.703146 0.356151
            +vn 0.564043 -0.758446 0.326456
            +vn 0.625660 -0.690939 0.362102
            +vn 0.766625 -0.464125 0.443678
            +vn 0.668111 -0.327403 0.668111
            +vn 0.582171 -0.567522 0.582171
            +vn 0.502579 -0.703421 0.502579
            +vn 0.460646 -0.758660 0.460646
            +vn 0.510971 -0.691183 0.510971
            +vn 0.626209 -0.464370 0.626209
            +vn 0.473434 -0.327158 0.817774
            +vn 0.412549 -0.567248 0.712729
            +vn 0.356151 -0.703146 0.615375
            +vn 0.326456 -0.758446 0.564043
            +vn 0.362102 -0.690939 0.625660
            +vn 0.443678 -0.464125 0.766625
            +vn 0.245003 -0.326609 0.912839
            +vn 0.213538 -0.566485 0.795892
            +vn 0.184393 -0.702445 0.687399
            +vn 0.169012 -0.757805 0.630146
            +vn 0.187414 -0.690329 0.698752
            +vn 0.229530 -0.463454 0.855831
            +vn 0.000000 -0.326273 0.945250
            +vn 0.000000 -0.565996 0.824396
            +vn 0.000000 -0.701987 0.712180
            +vn 0.000000 -0.757347 0.652974
            +vn 0.000000 -0.689749 0.724021
            +vn 0.000000 -0.462905 0.886380
            +vn -0.245003 -0.326609 0.912839
            +vn -0.213538 -0.566485 0.795892
            +vn -0.184393 -0.702445 0.687399
            +vn -0.169012 -0.757805 0.630146
            +vn -0.187414 -0.690329 0.698752
            +vn -0.229530 -0.463454 0.855831
            +vn -0.473434 -0.327158 0.817774
            +vn -0.412549 -0.567248 0.712729
            +vn -0.356151 -0.703146 0.615375
            +vn -0.326456 -0.758446 0.564043
            +vn -0.362102 -0.690939 0.625660
            +vn -0.443678 -0.464125 0.766625
            +vn -0.668111 -0.327403 0.668111
            +vn -0.582171 -0.567522 0.582171
            +vn -0.502579 -0.703421 0.502579
            +vn -0.460646 -0.758660 0.460646
            +vn -0.510971 -0.691183 0.510971
            +vn -0.626209 -0.464370 0.626209
            +vn -0.817774 -0.327158 0.473434
            +vn -0.712729 -0.567248 0.412549
            +vn -0.615375 -0.703146 0.356151
            +vn -0.564043 -0.758446 0.326456
            +vn -0.625660 -0.690939 0.362102
            +vn -0.766625 -0.464125 0.443678
            +vn -0.912839 -0.326609 0.245003
            +vn -0.795892 -0.566485 0.213538
            +vn -0.687399 -0.702445 0.184393
            +vn -0.630146 -0.757805 0.169012
            +vn -0.698752 -0.690329 0.187445
            +vn -0.855861 -0.463454 0.229530
            +vn -0.945250 -0.326273 0.000000
            +vn -0.824396 -0.565996 0.000000
            +vn -0.712180 -0.701987 0.000000
            +vn -0.652974 -0.757347 0.000000
            +vn -0.724021 -0.689749 0.000000
            +vn -0.886380 -0.462905 0.000000
            +vn -0.912839 -0.326609 -0.245003
            +vn -0.795892 -0.566485 -0.213538
            +vn -0.687399 -0.702445 -0.184393
            +vn -0.630146 -0.757805 -0.169012
            +vn -0.698752 -0.690329 -0.187414
            +vn -0.855831 -0.463454 -0.229530
            +vn -0.817774 -0.327158 -0.473434
            +vn -0.712729 -0.567248 -0.412549
            +vn -0.615375 -0.703146 -0.356151
            +vn -0.564043 -0.758446 -0.326456
            +vn -0.625660 -0.690939 -0.362102
            +vn -0.766625 -0.464125 -0.443678
            +vn -0.668111 -0.327403 -0.668111
            +vn -0.582171 -0.567522 -0.582171
            +vn -0.502579 -0.703421 -0.502579
            +vn -0.460646 -0.758660 -0.460646
            +vn -0.510971 -0.691183 -0.510971
            +vn -0.626209 -0.464370 -0.626209
            +vn -0.473434 -0.327158 -0.817774
            +vn -0.412549 -0.567248 -0.712729
            +vn -0.356151 -0.703146 -0.615375
            +vn -0.326456 -0.758446 -0.564043
            +vn -0.362102 -0.690939 -0.625660
            +vn -0.443678 -0.464125 -0.766625
            +vn -0.245003 -0.326609 -0.912839
            +vn -0.213538 -0.566485 -0.795892
            +vn -0.184393 -0.702445 -0.687399
            +vn -0.169012 -0.757805 -0.630146
            +vn -0.187414 -0.690329 -0.698752
            +vn -0.229530 -0.463454 -0.855831
            +vn 0.000000 -0.326273 -0.945250
            +vn 0.000000 -0.565996 -0.824396
            +vn 0.000000 -0.701987 -0.712149
            +vn 0.000000 -0.757347 -0.652974
            +vn 0.000000 -0.689749 -0.724021
            +vn 0.000000 -0.462905 -0.886380
            +vn 0.245003 -0.326609 -0.912839
            +vn 0.213538 -0.566485 -0.795892
            +vn 0.184393 -0.702445 -0.687399
            +vn 0.169012 -0.757805 -0.630146
            +vn 0.187414 -0.690329 -0.698752
            +vn 0.229530 -0.463454 -0.855831
            +vn 0.473434 -0.327158 -0.817774
            +vn 0.412549 -0.567248 -0.712729
            +vn 0.356151 -0.703146 -0.615375
            +vn 0.326456 -0.758446 -0.564043
            +vn 0.362102 -0.690939 -0.625660
            +vn 0.443678 -0.464125 -0.766625
            +vn 0.668111 -0.327403 -0.668111
            +vn 0.582171 -0.567522 -0.582171
            +vn 0.502579 -0.703421 -0.502579
            +vn 0.460646 -0.758660 -0.460646
            +vn 0.510971 -0.691183 -0.510971
            +vn 0.626209 -0.464370 -0.626209
            +vn 0.817774 -0.327158 -0.473434
            +vn 0.712729 -0.567248 -0.412549
            +vn 0.615375 -0.703146 -0.356151
            +vn 0.564043 -0.758446 -0.326456
            +vn 0.625660 -0.690939 -0.362102
            +vn 0.766625 -0.464125 -0.443678
            +vn 0.912839 -0.326609 -0.245003
            +vn 0.795892 -0.566485 -0.213538
            +vn 0.687399 -0.702445 -0.184393
            +vn 0.630146 -0.757805 -0.169012
            +vn 0.698752 -0.690329 -0.187414
            +vn 0.855831 -0.463454 -0.229530
            +vn 0.068667 -0.997620 0.000000
            +vn 0.066256 -0.997620 -0.017731
            +vn 0.157170 -0.987548 0.000000
            +vn 0.151677 -0.987579 -0.040620
            +vn 0.373150 -0.927763 0.000000
            +vn 0.360149 -0.927885 -0.096469
            +vn 0.789148 -0.614154 0.000000
            +vn 0.762017 -0.614399 -0.204474
            +vn 0.059236 -0.997650 -0.034242
            +vn 0.135624 -0.987640 -0.078463
            +vn 0.322153 -0.928129 -0.186346
            +vn 0.682333 -0.615131 -0.394971
            +vn 0.048341 -0.997650 -0.048341
            +vn 0.110691 -0.987640 -0.110691
            +vn 0.262947 -0.928251 -0.262947
            +vn 0.557329 -0.615375 -0.557329
            +vn 0.034272 -0.997650 -0.059236
            +vn 0.078463 -0.987640 -0.135624
            +vn 0.186377 -0.928129 -0.322153
            +vn 0.394971 -0.615131 -0.682333
            +vn 0.017731 -0.997620 -0.066256
            +vn 0.040620 -0.987579 -0.151677
            +vn 0.096469 -0.927885 -0.360118
            +vn 0.204505 -0.614399 -0.762017
            +vn 0.000000 -0.997620 -0.068667
            +vn 0.000000 -0.987548 -0.157170
            +vn 0.000000 -0.927763 -0.373150
            +vn 0.000000 -0.614154 -0.789148
            +vn -0.017731 -0.997620 -0.066256
            +vn -0.040620 -0.987579 -0.151677
            +vn -0.096469 -0.927885 -0.360118
            +vn -0.204505 -0.614399 -0.762017
            +vn -0.034272 -0.997650 -0.059236
            +vn -0.078463 -0.987640 -0.135624
            +vn -0.186377 -0.928129 -0.322153
            +vn -0.394971 -0.615131 -0.682333
            +vn -0.048341 -0.997650 -0.048341
            +vn -0.110691 -0.987640 -0.110691
            +vn -0.262947 -0.928251 -0.262947
            +vn -0.557329 -0.615375 -0.557329
            +vn -0.059236 -0.997650 -0.034242
            +vn -0.135624 -0.987640 -0.078463
            +vn -0.322153 -0.928129 -0.186346
            +vn -0.682333 -0.615131 -0.394971
            +vn -0.066256 -0.997620 -0.017731
            +vn -0.151677 -0.987579 -0.040620
            +vn -0.360149 -0.927885 -0.096469
            +vn -0.762017 -0.614399 -0.204474
            +vn -0.068667 -0.997620 0.000000
            +vn -0.157170 -0.987548 0.000000
            +vn -0.373150 -0.927763 0.000000
            +vn -0.789148 -0.614154 0.000000
            +vn -0.066256 -0.997620 0.017731
            +vn -0.151677 -0.987579 0.040620
            +vn -0.360118 -0.927885 0.096469
            +vn -0.762017 -0.614399 0.204505
            +vn -0.059236 -0.997650 0.034272
            +vn -0.135624 -0.987640 0.078463
            +vn -0.322153 -0.928129 0.186377
            +vn -0.682333 -0.615131 0.394971
            +vn -0.048341 -0.997650 0.048341
            +vn -0.110691 -0.987640 0.110691
            +vn -0.262947 -0.928251 0.262947
            +vn -0.557329 -0.615375 0.557329
            +vn -0.034272 -0.997650 0.059236
            +vn -0.078463 -0.987640 0.135624
            +vn -0.186377 -0.928129 0.322153
            +vn -0.394971 -0.615131 0.682333
            +vn -0.017731 -0.997620 0.066256
            +vn -0.040620 -0.987579 0.151677
            +vn -0.096469 -0.927885 0.360149
            +vn -0.204474 -0.614399 0.762017
            +vn 0.000000 -0.997620 0.068667
            +vn 0.000000 -0.987548 0.157170
            +vn 0.000000 -0.927763 0.373150
            +vn 0.000000 -0.614154 0.789148
            +vn 0.017731 -0.997620 0.066256
            +vn 0.040620 -0.987579 0.151677
            +vn 0.096469 -0.927885 0.360149
            +vn 0.204474 -0.614399 0.762017
            +vn 0.034272 -0.997650 0.059236
            +vn 0.078463 -0.987640 0.135624
            +vn 0.186377 -0.928129 0.322153
            +vn 0.394971 -0.615131 0.682333
            +vn 0.048341 -0.997650 0.048341
            +vn 0.110691 -0.987640 0.110691
            +vn 0.262947 -0.928251 0.262947
            +vn 0.557329 -0.615375 0.557329
            +vn 0.059236 -0.997650 0.034272
            +vn 0.135624 -0.987640 0.078463
            +vn 0.322153 -0.928129 0.186377
            +vn 0.682333 -0.615101 0.394971
            +vn 0.066256 -0.997620 0.017731
            +vn 0.151677 -0.987579 0.040620
            +vn 0.360118 -0.927885 0.096469
            +vn 0.762017 -0.614399 0.204505
            +vn 0.692129 0.697470 0.185583
            +vn 0.717063 0.696982 0.000000
            +vn 0.915586 0.318766 0.245064
            +vn 0.947905 0.318522 0.000000
            +vn 0.620045 0.697653 0.358837
            +vn 0.820429 0.318979 0.474410
            +vn 0.506546 0.697684 0.506546
            +vn 0.670125 0.319041 0.670125
            +vn 0.358837 0.697653 0.620045
            +vn 0.474410 0.318979 0.820429
            +vn 0.185583 0.697470 0.692129
            +vn 0.245064 0.318766 0.915586
            +vn 0.000000 0.696982 0.717063
            +vn 0.000000 0.318522 0.947905
            +vn -0.185583 0.697470 0.692129
            +vn -0.245064 0.318766 0.915586
            +vn -0.358837 0.697653 0.620045
            +vn -0.474410 0.318979 0.820429
            +vn -0.506546 0.697684 0.506546
            +vn -0.670125 0.319041 0.670125
            +vn -0.620045 0.697653 0.358837
            +vn -0.820429 0.318979 0.474410
            +vn -0.692129 0.697470 0.185583
            +vn -0.915586 0.318766 0.245064
            +vn -0.717063 0.696982 0.000000
            +vn -0.947905 0.318522 0.000000
            +vn -0.692129 0.697470 -0.185583
            +vn -0.915586 0.318766 -0.245064
            +vn -0.620045 0.697653 -0.358837
            +vn -0.820429 0.318979 -0.474410
            +vn -0.506546 0.697684 -0.506546
            +vn -0.670125 0.319041 -0.670125
            +vn -0.358837 0.697653 -0.620045
            +vn -0.474410 0.318979 -0.820429
            +vn -0.185583 0.697470 -0.692129
            +vn -0.245064 0.318766 -0.915586
            +vn 0.000000 0.696982 -0.717063
            +vn 0.000000 0.318522 -0.947905
            +vn 0.185583 0.697470 -0.692129
            +vn 0.245064 0.318766 -0.915586
            +vn 0.358837 0.697653 -0.620045
            +vn 0.474410 0.318979 -0.820429
            +vn 0.506546 0.697684 -0.506546
            +vn 0.670125 0.319041 -0.670125
            +vn 0.620045 0.697653 -0.358837
            +vn 0.820429 0.318979 -0.474410
            +vn 0.692129 0.697470 -0.185583
            +vn 0.915586 0.318766 -0.245064
            +vn 0.282083 0.956389 0.075686
            +vn 0.292520 0.956236 0.000000
            +vn 0.171606 0.984069 0.046022
            +vn 0.177953 0.984008 0.000000
            +vn 0.153264 0.987304 0.041078
            +vn 0.158879 0.987274 0.000000
            +vn 0.210059 0.976043 0.056276
            +vn 0.217719 0.975982 0.000000
            +vn 0.487197 0.863460 0.130558
            +vn 0.504715 0.863277 0.000000
            +vn 0.662801 0.727226 0.178198
            +vn 0.686911 0.726707 0.000000
            +vn 0.252388 0.956511 0.146092
            +vn 0.153508 0.984130 0.088839
            +vn 0.137059 0.987365 0.079318
            +vn 0.187872 0.976135 0.108676
            +vn 0.435926 0.863887 0.252205
            +vn 0.593310 0.727866 0.343730
            +vn 0.206091 0.956572 0.206091
            +vn 0.125340 0.984161 0.125340
            +vn 0.111911 0.987396 0.111911
            +vn 0.153356 0.976196 0.153356
            +vn 0.355907 0.864071 0.355907
            +vn 0.484664 0.728111 0.484664
            +vn 0.146092 0.956511 0.252388
            +vn 0.088839 0.984130 0.153508
            +vn 0.079318 0.987365 0.137059
            +vn 0.108676 0.976135 0.187872
            +vn 0.252205 0.863887 0.435926
            +vn 0.343730 0.727866 0.593310
            +vn 0.075686 0.956389 0.282083
            +vn 0.046022 0.984069 0.171606
            +vn 0.041078 0.987304 0.153264
            +vn 0.056276 0.976043 0.210059
            +vn 0.130558 0.863460 0.487197
            +vn 0.178198 0.727226 0.662801
            +vn 0.000000 0.956236 0.292520
            +vn 0.000000 0.984008 0.177953
            +vn 0.000000 0.987274 0.158879
            +vn 0.000000 0.975982 0.217719
            +vn 0.000000 0.863277 0.504715
            +vn 0.000000 0.726707 0.686911
            +vn -0.075686 0.956389 0.282083
            +vn -0.046022 0.984069 0.171606
            +vn -0.041078 0.987304 0.153264
            +vn -0.056276 0.976043 0.210059
            +vn -0.130558 0.863460 0.487197
            +vn -0.178198 0.727226 0.662801
            +vn -0.146092 0.956511 0.252388
            +vn -0.088839 0.984130 0.153508
            +vn -0.079318 0.987365 0.137059
            +vn -0.108676 0.976135 0.187872
            +vn -0.252205 0.863887 0.435926
            +vn -0.343730 0.727866 0.593310
            +vn -0.206091 0.956572 0.206091
            +vn -0.125340 0.984161 0.125340
            +vn -0.111911 0.987396 0.111911
            +vn -0.153356 0.976196 0.153356
            +vn -0.355907 0.864071 0.355907
            +vn -0.484664 0.728111 0.484664
            +vn -0.252388 0.956511 0.146092
            +vn -0.153508 0.984130 0.088839
            +vn -0.137059 0.987365 0.079318
            +vn -0.187872 0.976135 0.108676
            +vn -0.435926 0.863887 0.252205
            +vn -0.593310 0.727866 0.343730
            +vn -0.282083 0.956389 0.075686
            +vn -0.171606 0.984069 0.046022
            +vn -0.153264 0.987304 0.041078
            +vn -0.210059 0.976043 0.056276
            +vn -0.487197 0.863460 0.130558
            +vn -0.662801 0.727226 0.178198
            +vn -0.292520 0.956236 0.000000
            +vn -0.177953 0.984008 0.000000
            +vn -0.158879 0.987274 0.000000
            +vn -0.217719 0.975982 0.000000
            +vn -0.504715 0.863277 0.000000
            +vn -0.686911 0.726707 0.000000
            +vn -0.282083 0.956389 -0.075686
            +vn -0.171606 0.984069 -0.046022
            +vn -0.153264 0.987304 -0.041078
            +vn -0.210059 0.976043 -0.056276
            +vn -0.487197 0.863460 -0.130558
            +vn -0.662801 0.727226 -0.178198
            +vn -0.252388 0.956511 -0.146092
            +vn -0.153508 0.984130 -0.088839
            +vn -0.137059 0.987365 -0.079318
            +vn -0.187872 0.976135 -0.108676
            +vn -0.435926 0.863887 -0.252205
            +vn -0.593310 0.727866 -0.343730
            +vn -0.206091 0.956572 -0.206091
            +vn -0.125340 0.984161 -0.125340
            +vn -0.111911 0.987396 -0.111911
            +vn -0.153356 0.976196 -0.153356
            +vn -0.355907 0.864071 -0.355907
            +vn -0.484664 0.728111 -0.484664
            +vn -0.146092 0.956511 -0.252388
            +vn -0.088839 0.984130 -0.153508
            +vn -0.079318 0.987365 -0.137059
            +vn -0.108676 0.976135 -0.187872
            +vn -0.252205 0.863887 -0.435926
            +vn -0.343730 0.727866 -0.593310
            +vn -0.075686 0.956389 -0.282083
            +vn -0.046022 0.984069 -0.171606
            +vn -0.041078 0.987304 -0.153264
            +vn -0.056276 0.976043 -0.210059
            +vn -0.130558 0.863460 -0.487197
            +vn -0.178198 0.727226 -0.662801
            +vn 0.000000 0.956236 -0.292520
            +vn 0.000000 0.984008 -0.177953
            +vn 0.000000 0.987274 -0.158879
            +vn 0.000000 0.975982 -0.217719
            +vn 0.000000 0.863277 -0.504715
            +vn 0.000000 0.726707 -0.686911
            +vn 0.075686 0.956389 -0.282083
            +vn 0.046022 0.984069 -0.171606
            +vn 0.041078 0.987304 -0.153264
            +vn 0.056276 0.976043 -0.210059
            +vn 0.130558 0.863460 -0.487197
            +vn 0.178198 0.727226 -0.662801
            +vn 0.146092 0.956511 -0.252388
            +vn 0.088839 0.984130 -0.153508
            +vn 0.079318 0.987365 -0.137059
            +vn 0.108676 0.976135 -0.187872
            +vn 0.252205 0.863887 -0.435926
            +vn 0.343730 0.727866 -0.593310
            +vn 0.206091 0.956572 -0.206091
            +vn 0.125340 0.984161 -0.125340
            +vn 0.111911 0.987396 -0.111911
            +vn 0.153356 0.976196 -0.153356
            +vn 0.355907 0.864071 -0.355907
            +vn 0.484664 0.728111 -0.484664
            +vn 0.252388 0.956511 -0.146092
            +vn 0.153508 0.984130 -0.088839
            +vn 0.137059 0.987365 -0.079318
            +vn 0.187872 0.976135 -0.108676
            +vn 0.435926 0.863887 -0.252205
            +vn 0.593310 0.727866 -0.343730
            +vn 0.282083 0.956389 -0.075686
            +vn 0.171606 0.984069 -0.046022
            +vn 0.153264 0.987304 -0.041078
            +vn 0.210059 0.976043 -0.056276
            +vn 0.487197 0.863460 -0.130558
            +vn 0.662801 0.727226 -0.178198
            +vn 0.015290 -0.999878 0.000000
            +vn 0.003296 -0.999969 0.000000
            +vn 0.015168 -0.949339 0.313852
            +vn 0.003265 -0.944395 0.328715
            +vn 0.058870 -0.998260 0.000000
            +vn 0.058046 -0.947630 0.314005
            +vn 0.158361 -0.934690 0.318155
            +vn 0.159764 -0.987152 0.000000
            +vn 0.373943 -0.860958 0.344798
            +vn 0.391583 -0.920103 0.000000
            +vn 0.726829 -0.553880 0.406049
            +vn 0.784570 -0.620014 0.000000
            +vn 0.908139 -0.082766 0.410321
            +vn 0.994995 -0.099796 0.000000
            +vn 0.011902 -0.679403 0.733634
            +vn 0.002380 -0.636219 0.771477
            +vn 0.046449 -0.674398 0.736869
            +vn 0.125980 -0.648946 0.750298
            +vn 0.270089 -0.562120 0.781671
            +vn 0.460067 -0.316263 0.829615
            +vn 0.563036 -0.041200 0.825373
            +vn 0.000153 0.004242 0.999969
            +vn -0.000519 0.113254 0.993561
            +vn 0.003510 0.014008 0.999878
            +vn 0.005921 0.035951 0.999329
            +vn -0.007813 0.058840 0.998230
            +vn -0.046510 0.041536 0.998047
            +vn -0.039155 0.003113 0.999207
            +vn -0.014161 0.682394 0.730796
            +vn -0.003204 0.727744 0.685812
            +vn -0.055361 0.680074 0.731010
            +vn -0.150029 0.655660 0.739952
            +vn -0.322520 0.565203 0.759239
            +vn -0.537645 0.315806 0.781762
            +vn -0.611530 0.029939 0.790613
            +vn -0.020569 0.949400 0.313334
            +vn -0.004273 0.954772 0.297281
            +vn -0.082705 0.944945 0.316507
            +vn -0.229591 0.914548 0.332926
            +vn -0.502335 0.785943 0.360454
            +vn -0.810633 0.443220 0.382611
            +vn -0.921232 0.039705 0.386944
            +vn -0.021851 0.999756 0.000000
            +vn -0.004517 0.999969 0.000000
            +vn -0.087649 0.996124 0.000000
            +vn -0.246223 0.969207 0.000000
            +vn -0.549211 0.835658 0.000000
            +vn -0.881039 0.472976 0.000000
            +vn -0.999115 0.041444 0.000000
            +vn -0.004273 0.954772 -0.297281
            +vn -0.020569 0.949400 -0.313334
            +vn -0.082705 0.944945 -0.316507
            +vn -0.229591 0.914548 -0.332926
            +vn -0.502335 0.785943 -0.360454
            +vn -0.810633 0.443220 -0.382611
            +vn -0.921232 0.039705 -0.386944
            +vn -0.003204 0.727744 -0.685812
            +vn -0.014161 0.682394 -0.730796
            +vn -0.055361 0.680074 -0.731010
            +vn -0.150029 0.655660 -0.739952
            +vn -0.322520 0.565203 -0.759239
            +vn -0.537645 0.315806 -0.781762
            +vn -0.611530 0.029939 -0.790613
            +vn -0.000519 0.113254 -0.993561
            +vn 0.000153 0.004242 -0.999969
            +vn 0.003510 0.014008 -0.999878
            +vn 0.005921 0.035951 -0.999329
            +vn -0.007813 0.058809 -0.998230
            +vn -0.046510 0.041536 -0.998047
            +vn -0.039155 0.003113 -0.999207
            +vn 0.002380 -0.636219 -0.771477
            +vn 0.011902 -0.679403 -0.733634
            +vn 0.046449 -0.674398 -0.736869
            +vn 0.125980 -0.648946 -0.750298
            +vn 0.270089 -0.562151 -0.781671
            +vn 0.460067 -0.316263 -0.829615
            +vn 0.563036 -0.041231 -0.825373
            +vn 0.003265 -0.944395 -0.328715
            +vn 0.015168 -0.949339 -0.313852
            +vn 0.058046 -0.947630 -0.314005
            +vn 0.158361 -0.934690 -0.318155
            +vn 0.373943 -0.860958 -0.344798
            +vn 0.726829 -0.553880 -0.406049
            +vn 0.908139 -0.082766 -0.410321
            +vn 0.890500 0.214759 0.401044
            +vn 0.972930 0.231025 0.000000
            +vn 0.836634 0.384075 0.390515
            +vn 0.912503 0.408979 0.000000
            +vn 0.765191 0.530198 0.365123
            +vn 0.828791 0.559496 0.000000
            +vn 0.671041 0.663228 0.331339
            +vn 0.718955 0.695029 0.000000
            +vn 0.549455 0.776238 0.309000
            +vn 0.580859 0.813990 0.000000
            +vn 0.461165 0.821528 0.335215
            +vn 0.497085 0.867672 0.000000
            +vn 0.559679 0.139714 0.816828
            +vn 0.528581 0.255501 0.809473
            +vn 0.494888 0.359783 0.790948
            +vn 0.445143 0.467879 0.763451
            +vn 0.376049 0.559984 0.738212
            +vn 0.287332 0.527940 0.799188
            +vn -0.024537 -0.005737 0.999664
            +vn -0.020844 -0.012207 0.999695
            +vn -0.014466 -0.014466 0.999786
            +vn -0.009796 -0.013276 0.999847
            +vn -0.014771 -0.013886 0.999786
            +vn -0.101779 -0.196661 0.975158
            +vn -0.585437 -0.154668 0.795801
            +vn -0.538499 -0.291696 0.790490
            +vn -0.487228 -0.408918 0.771599
            +vn -0.428327 -0.511948 0.744560
            +vn -0.360820 -0.584735 0.726524
            +vn -0.357311 -0.691549 0.627735
            +vn -0.889126 -0.238868 0.390332
            +vn -0.807001 -0.448500 0.384075
            +vn -0.700980 -0.613392 0.363750
            +vn -0.590442 -0.733757 0.336009
            +vn -0.486190 -0.814966 0.315256
            +vn -0.440138 -0.855586 0.272439
            +vn -0.965453 -0.260506 0.000000
            +vn -0.872097 -0.489273 0.000000
            +vn -0.748253 -0.663381 0.000000
            +vn -0.621784 -0.783166 0.000000
            +vn -0.507614 -0.861568 0.000000
            +vn -0.456954 -0.889462 0.000000
            +vn -0.889126 -0.238868 -0.390332
            +vn -0.807001 -0.448531 -0.384075
            +vn -0.700980 -0.613392 -0.363750
            +vn -0.590442 -0.733757 -0.336009
            +vn -0.486190 -0.814966 -0.315256
            +vn -0.440138 -0.855586 -0.272439
            +vn -0.585437 -0.154668 -0.795801
            +vn -0.538499 -0.291696 -0.790490
            +vn -0.487228 -0.408918 -0.771599
            +vn -0.428327 -0.511948 -0.744560
            +vn -0.360820 -0.584735 -0.726524
            +vn -0.357311 -0.691549 -0.627705
            +vn -0.024537 -0.005737 -0.999664
            +vn -0.020844 -0.012238 -0.999695
            +vn -0.014466 -0.014466 -0.999786
            +vn -0.009766 -0.013276 -0.999847
            +vn -0.014771 -0.013916 -0.999786
            +vn -0.101779 -0.196661 -0.975158
            +vn 0.559679 0.139714 -0.816828
            +vn 0.528581 0.255501 -0.809473
            +vn 0.494888 0.359783 -0.790948
            +vn 0.445143 0.467879 -0.763451
            +vn 0.376049 0.559984 -0.738212
            +vn 0.287332 0.527940 -0.799188
            +vn 0.890500 0.214759 -0.401044
            +vn 0.836634 0.384075 -0.390515
            +vn 0.765191 0.530198 -0.365123
            +vn 0.671041 0.663228 -0.331339
            +vn 0.549455 0.776238 -0.309000
            +vn 0.461165 0.821528 -0.335215
            +vn -0.149937 0.988678 0.000000
            +vn -0.137028 0.872402 0.469131
            +vn -0.297769 0.840358 0.452895
            +vn -0.350505 0.936552 0.000000
            +vn -0.617512 0.663961 0.421613
            +vn -0.715506 0.698569 0.000000
            +vn -0.801324 0.450209 0.393872
            +vn -0.900845 0.434065 0.000000
            +vn -0.828028 0.379803 0.412397
            +vn -0.929289 0.369274 0.000000
            +vn -0.729179 0.503464 0.463393
            +vn -0.857875 0.513810 0.000000
            +vn -0.663076 0.748527 0.000000
            +vn -0.531449 0.686514 0.496170
            +vn -0.066713 0.491440 0.868313
            +vn -0.117893 0.503159 0.856105
            +vn -0.254341 0.474349 0.842769
            +vn -0.411115 0.399182 0.819483
            +vn -0.459395 0.346446 0.817835
            +vn -0.385876 0.395734 0.833338
            +vn -0.270669 0.487838 0.829890
            +vn 0.062716 -0.043458 0.997070
            +vn 0.135929 -0.002472 0.990692
            +vn 0.247963 0.095187 0.964049
            +vn 0.209296 0.170660 0.962828
            +vn 0.096194 0.178625 0.979186
            +vn 0.009552 0.154332 0.987945
            +vn -0.000122 0.151952 0.988372
            +vn 0.202582 -0.542894 0.814966
            +vn 0.360088 -0.479232 0.800378
            +vn 0.611988 -0.282235 0.738762
            +vn 0.679220 -0.106754 0.726096
            +vn 0.583911 -0.078524 0.807978
            +vn 0.402722 -0.205237 0.891995
            +vn 0.279519 -0.338694 0.898404
            +vn 0.294107 -0.855037 0.427015
            +vn 0.488418 -0.768700 0.412915
            +vn 0.784570 -0.501511 0.364544
            +vn 0.893918 -0.279611 0.350291
            +vn 0.861415 -0.285287 0.420179
            +vn 0.679373 -0.540422 0.496323
            +vn 0.458357 -0.754540 0.469588
            +vn 0.320780 -0.947142 0.000000
            +vn 0.525101 -0.851009 0.000000
            +vn 0.827570 -0.561327 0.000000
            +vn 0.943419 -0.331523 0.000000
            +vn 0.933561 -0.358409 0.000000
            +vn 0.756340 -0.654134 0.000000
            +vn 0.491928 -0.870602 0.000092
            +vn 0.294107 -0.855037 -0.427015
            +vn 0.488418 -0.768700 -0.412915
            +vn 0.784570 -0.501511 -0.364544
            +vn 0.893918 -0.279611 -0.350291
            +vn 0.861385 -0.285287 -0.420179
            +vn 0.679373 -0.540422 -0.496323
            +vn 0.457839 -0.755608 -0.468368
            +vn 0.202582 -0.542894 -0.814966
            +vn 0.360088 -0.479232 -0.800378
            +vn 0.611988 -0.282235 -0.738762
            +vn 0.679220 -0.106754 -0.726096
            +vn 0.583911 -0.078524 -0.807978
            +vn 0.402722 -0.205237 -0.891995
            +vn 0.279153 -0.342235 -0.897153
            +vn 0.062716 -0.043458 -0.997070
            +vn 0.135929 -0.002472 -0.990692
            +vn 0.247963 0.095187 -0.964049
            +vn 0.209296 0.170629 -0.962828
            +vn 0.096194 0.178625 -0.979186
            +vn 0.009552 0.154332 -0.987945
            +vn -0.000458 0.149358 -0.988769
            +vn -0.066713 0.491440 -0.868313
            +vn -0.117893 0.503159 -0.856105
            +vn -0.254341 0.474319 -0.842769
            +vn -0.411115 0.399182 -0.819514
            +vn -0.459395 0.346446 -0.817835
            +vn -0.385876 0.395734 -0.833338
            +vn -0.271035 0.487136 -0.830164
            +vn -0.137028 0.872402 -0.469131
            +vn -0.297769 0.840358 -0.452895
            +vn -0.617512 0.663961 -0.421613
            +vn -0.801324 0.450209 -0.393872
            +vn -0.828028 0.379803 -0.412397
            +vn -0.729209 0.503464 -0.463393
            +vn -0.531541 0.686453 -0.496200
            +vn -0.480697 0.876858 0.000000
            +vn -0.394635 0.815363 0.423536
            +vn -0.320750 0.947142 0.000092
            +vn -0.255287 0.921964 0.291086
            +vn 0.002686 0.999969 -0.000732
            +vn -0.007172 0.999939 -0.007599
            +vn 0.366832 0.704398 -0.607624
            +vn 0.853236 0.521226 -0.016388
            +vn 0.567492 -0.154088 -0.808802
            +vn 0.803766 -0.594409 -0.024964
            +vn 0.580920 -0.584490 -0.566424
            +vn 0.673757 -0.738639 -0.020966
            +vn -0.206824 0.638203 0.741539
            +vn -0.129490 0.862056 0.489944
            +vn -0.034486 0.999023 0.026704
            +vn 0.041597 0.871334 -0.488876
            +vn 0.103488 0.553880 -0.826136
            +vn 0.189642 0.174200 -0.966247
            +vn 0.020112 0.322611 0.946287
            +vn 0.021943 0.748894 0.662282
            +vn -0.025697 0.995392 0.092166
            +vn -0.056551 0.931608 -0.358989
            +vn -0.070711 0.782006 -0.619190
            +vn -0.066408 0.651509 -0.755699
            +vn 0.281747 -0.174993 0.943388
            +vn 0.303903 0.444136 0.842830
            +vn 0.035279 0.983856 0.175329
            +vn -0.109928 0.953551 -0.280435
            +vn -0.149571 0.847682 -0.508927
            +vn -0.145634 0.777520 -0.611744
            +vn 0.467238 -0.683218 0.561144
            +vn 0.699515 0.004364 0.714560
            +vn 0.354900 0.892758 0.277444
            +vn -0.174383 0.969054 -0.174596
            +vn -0.252998 0.894314 -0.368938
            +vn -0.191443 0.807947 -0.557237
            +vn 0.495346 -0.868679 0.001587
            +vn 0.933897 -0.357311 0.011017
            +vn 0.704215 0.709830 0.013337
            +vn -0.205634 0.978576 -0.006623
            +vn -0.322367 0.945708 -0.041169
            +vn -0.314951 0.916288 -0.247322
            +vn 0.459120 -0.703757 -0.542100
            +vn 0.693655 -0.096530 -0.713767
            +vn 0.408673 0.848415 -0.336344
            +vn -0.198248 0.963439 0.180151
            +vn -0.306833 0.888516 0.341075
            +vn -0.335978 0.808863 0.482498
            +vn 0.277047 -0.215796 -0.936277
            +vn 0.306192 0.349864 -0.885311
            +vn 0.056246 0.971099 -0.231819
            +vn -0.146733 0.912168 0.382611
            +vn -0.202612 0.700797 0.683950
            +vn -0.159368 0.444777 0.881314
            +vn 0.016907 0.300088 -0.953734
            +vn 0.019349 0.701865 -0.712027
            +vn -0.023713 0.995361 -0.093081
            +vn -0.047395 0.829371 0.556658
            +vn -0.015259 0.386608 0.922086
            +vn 0.080721 0.001404 0.996704
            +vn -0.209967 0.632160 -0.745811
            +vn -0.137394 0.849117 -0.509995
            +vn -0.023438 0.999695 -0.004883
            +vn 0.120426 0.724540 0.678579
            +vn 0.260750 0.006531 0.965361
            +vn 0.341502 -0.385510 0.857143
            +vn -0.395489 0.814814 -0.423841
            +vn -0.257942 0.920621 -0.293039
            +vn 0.005005 0.999908 0.011628
            +vn 0.466628 0.599811 0.649983
            +vn 0.621937 -0.400861 0.672628
            +vn 0.584826 -0.661397 0.469558
            +vn 0.363842 0.931455 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.351451 0.931516 0.093509
            +vn 0.314432 0.931791 0.181280
            +vn 0.256386 0.931913 0.256386
            +vn 0.181280 0.931791 0.314432
            +vn 0.093509 0.931516 0.351451
            +vn 0.000000 0.931455 0.363842
            +vn -0.093509 0.931516 0.351451
            +vn -0.181280 0.931791 0.314432
            +vn -0.256386 0.931913 0.256386
            +vn -0.314432 0.931791 0.181280
            +vn -0.351451 0.931516 0.093509
            +vn -0.363842 0.931455 0.000000
            +vn -0.351451 0.931516 -0.093509
            +vn -0.314432 0.931791 -0.181280
            +vn -0.256417 0.931913 -0.256417
            +vn -0.181280 0.931791 -0.314432
            +vn -0.093509 0.931516 -0.351451
            +vn 0.000000 0.931455 -0.363842
            +vn 0.093509 0.931516 -0.351451
            +vn 0.181280 0.931791 -0.314432
            +vn 0.256417 0.931913 -0.256417
            +vn 0.314432 0.931791 -0.181280
            +vn 0.351451 0.931516 -0.093509
            +vn 0.935423 0.249763 0.250160
            +vn 0.968261 0.249916 0.000000
            +vn 0.813959 -0.538713 0.217322
            +vn 0.842860 -0.538102 0.000000
            +vn 0.759484 -0.618030 0.202887
            +vn 0.786767 -0.617206 0.000000
            +vn 0.801569 -0.558184 0.214148
            +vn 0.830195 -0.557421 0.000000
            +vn 0.838404 0.249825 0.484359
            +vn 0.729026 -0.539720 0.420881
            +vn 0.680013 -0.619098 0.392712
            +vn 0.717765 -0.559343 0.414594
            +vn 0.684652 0.249886 0.684652
            +vn 0.595050 -0.540147 0.595050
            +vn 0.555040 -0.619526 0.555040
            +vn 0.585894 -0.559862 0.585894
            +vn 0.484359 0.249825 0.838404
            +vn 0.420881 -0.539720 0.729026
            +vn 0.392712 -0.619098 0.680013
            +vn 0.414594 -0.559343 0.717765
            +vn 0.250160 0.249763 0.935423
            +vn 0.217322 -0.538713 0.813959
            +vn 0.202887 -0.618030 0.759514
            +vn 0.214148 -0.558184 0.801569
            +vn 0.000000 0.249916 0.968261
            +vn 0.000000 -0.538102 0.842860
            +vn 0.000000 -0.617206 0.786767
            +vn 0.000000 -0.557421 0.830195
            +vn -0.250160 0.249763 0.935423
            +vn -0.217322 -0.538713 0.813959
            +vn -0.202887 -0.618030 0.759514
            +vn -0.214148 -0.558184 0.801569
            +vn -0.484359 0.249825 0.838404
            +vn -0.420881 -0.539720 0.729026
            +vn -0.392712 -0.619098 0.680013
            +vn -0.414594 -0.559343 0.717765
            +vn -0.684652 0.249886 0.684652
            +vn -0.595050 -0.540147 0.595050
            +vn -0.555040 -0.619526 0.555040
            +vn -0.585894 -0.559862 0.585894
            +vn -0.838404 0.249825 0.484359
            +vn -0.729026 -0.539720 0.420881
            +vn -0.680013 -0.619098 0.392712
            +vn -0.717765 -0.559343 0.414594
            +vn -0.935423 0.249763 0.250160
            +vn -0.813959 -0.538713 0.217322
            +vn -0.759484 -0.618030 0.202887
            +vn -0.801569 -0.558184 0.214148
            +vn -0.968261 0.249916 0.000000
            +vn -0.842860 -0.538102 0.000000
            +vn -0.786767 -0.617206 0.000000
            +vn -0.830195 -0.557421 0.000000
            +vn -0.935423 0.249763 -0.250160
            +vn -0.813959 -0.538713 -0.217322
            +vn -0.759484 -0.618030 -0.202887
            +vn -0.801569 -0.558184 -0.214148
            +vn -0.838404 0.249825 -0.484359
            +vn -0.729026 -0.539720 -0.420881
            +vn -0.680013 -0.619098 -0.392712
            +vn -0.717765 -0.559343 -0.414594
            +vn -0.684652 0.249886 -0.684652
            +vn -0.595050 -0.540147 -0.595050
            +vn -0.555040 -0.619526 -0.555040
            +vn -0.585864 -0.559862 -0.585894
            +vn -0.484359 0.249825 -0.838404
            +vn -0.420881 -0.539720 -0.729026
            +vn -0.392712 -0.619098 -0.680013
            +vn -0.414594 -0.559343 -0.717765
            +vn -0.250160 0.249763 -0.935423
            +vn -0.217322 -0.538713 -0.813959
            +vn -0.202887 -0.618030 -0.759484
            +vn -0.214148 -0.558214 -0.801569
            +vn 0.000000 0.249916 -0.968261
            +vn 0.000000 -0.538102 -0.842860
            +vn 0.000000 -0.617206 -0.786767
            +vn 0.000000 -0.557421 -0.830195
            +vn 0.250160 0.249763 -0.935423
            +vn 0.217322 -0.538713 -0.813959
            +vn 0.202887 -0.618030 -0.759484
            +vn 0.214148 -0.558214 -0.801569
            +vn 0.484359 0.249825 -0.838404
            +vn 0.420881 -0.539720 -0.729026
            +vn 0.392712 -0.619098 -0.680013
            +vn 0.414594 -0.559343 -0.717765
            +vn 0.684652 0.249886 -0.684652
            +vn 0.595050 -0.540147 -0.595050
            +vn 0.555040 -0.619526 -0.555040
            +vn 0.585864 -0.559862 -0.585894
            +vn 0.838404 0.249825 -0.484359
            +vn 0.729026 -0.539720 -0.420881
            +vn 0.680013 -0.619098 -0.392712
            +vn 0.717765 -0.559343 -0.414594
            +vn 0.935423 0.249763 -0.250160
            +vn 0.813959 -0.538713 -0.217322
            +vn 0.759484 -0.618030 -0.202887
            +vn 0.801569 -0.558184 -0.214148
            +s 1
            +f 1//1 2//2 3//3
            +f 3//3 2//2 4//4
            +f 4//4 2//2 5//5
            +f 5//5 2//2 6//6
            +f 6//6 2//2 7//7
            +f 7//7 2//2 8//8
            +f 8//8 2//2 9//9
            +f 9//9 2//2 10//10
            +f 10//10 2//2 11//11
            +f 11//11 2//2 12//12
            +f 12//12 2//2 13//13
            +f 13//13 2//2 14//14
            +f 14//14 2//2 15//15
            +f 15//15 2//2 16//16
            +f 16//16 2//2 17//17
            +f 17//17 2//2 18//18
            +f 18//18 2//2 19//19
            +f 19//19 2//2 20//20
            +f 20//20 2//2 21//21
            +f 21//21 2//2 22//22
            +f 22//22 2//2 23//23
            +f 23//23 2//2 24//24
            +f 24//24 2//2 25//25
            +f 2//2 1//1 25//25
            +f 26//26 27//27 28//28
            +f 28//28 29//29 26//26
            +f 29//29 28//28 30//30
            +f 31//31 30//30 28//28
            +f 30//30 31//31 32//32
            +f 33//33 32//32 31//31
            +f 34//34 35//35 33//33
            +f 32//32 33//33 35//35
            +f 36//36 37//37 34//34
            +f 35//35 34//34 37//37
            +f 38//38 39//39 36//36
            +f 37//37 36//36 39//39
            +f 27//27 40//40 41//41
            +f 41//41 28//28 27//27
            +f 28//28 41//41 31//31
            +f 42//42 31//31 41//41
            +f 31//31 42//42 33//33
            +f 43//43 33//33 42//42
            +f 44//44 34//34 43//43
            +f 33//33 43//43 34//34
            +f 45//45 36//36 44//44
            +f 34//34 44//44 36//36
            +f 46//46 38//38 45//45
            +f 36//36 45//45 38//38
            +f 40//40 47//47 48//48
            +f 48//48 41//41 40//40
            +f 41//41 48//48 42//42
            +f 49//49 42//42 48//48
            +f 42//42 49//49 43//43
            +f 50//50 43//43 49//49
            +f 51//51 44//44 50//50
            +f 43//43 50//50 44//44
            +f 52//52 45//45 51//51
            +f 44//44 51//51 45//45
            +f 53//53 46//46 52//52
            +f 45//45 52//52 46//46
            +f 47//47 54//54 48//48
            +f 55//55 48//48 54//54
            +f 48//48 55//55 49//49
            +f 56//56 49//49 55//55
            +f 49//49 56//56 57//57
            +f 57//57 50//50 49//49
            +f 58//58 51//51 50//50
            +f 50//50 57//57 58//58
            +f 59//59 52//52 51//51
            +f 51//51 58//58 59//59
            +f 60//60 53//53 52//52
            +f 52//52 59//59 60//60
            +f 54//54 61//61 55//55
            +f 62//62 55//55 61//61
            +f 55//55 62//62 63//63
            +f 63//63 56//56 55//55
            +f 56//56 63//63 64//64
            +f 64//64 57//57 56//56
            +f 65//65 58//58 57//57
            +f 57//57 64//64 65//65
            +f 66//66 59//59 58//58
            +f 58//58 65//65 66//66
            +f 67//67 60//60 59//59
            +f 59//59 66//66 67//67
            +f 61//61 68//68 62//62
            +f 69//69 62//62 68//68
            +f 62//62 69//69 70//70
            +f 70//70 63//63 62//62
            +f 63//63 70//70 71//71
            +f 71//71 64//64 63//63
            +f 72//72 65//65 64//64
            +f 64//64 71//71 72//72
            +f 73//73 66//66 65//65
            +f 65//65 72//72 73//73
            +f 74//74 67//67 66//66
            +f 66//66 73//73 74//74
            +f 68//68 75//75 76//76
            +f 76//76 69//69 68//68
            +f 69//69 76//76 70//70
            +f 77//77 70//70 76//76
            +f 70//70 77//77 71//71
            +f 78//78 71//71 77//77
            +f 79//79 72//72 78//78
            +f 71//71 78//78 72//72
            +f 80//80 73//73 79//79
            +f 72//72 79//79 73//73
            +f 81//81 74//74 80//80
            +f 73//73 80//80 74//74
            +f 75//75 82//82 83//83
            +f 83//83 76//76 75//75
            +f 76//76 83//83 77//77
            +f 84//84 77//77 83//83
            +f 77//77 84//84 78//78
            +f 85//85 78//78 84//84
            +f 86//86 79//79 85//85
            +f 78//78 85//85 79//79
            +f 87//87 80//80 86//86
            +f 79//79 86//86 80//80
            +f 88//88 81//81 87//87
            +f 80//80 87//87 81//81
            +f 82//82 89//89 90//90
            +f 90//90 83//83 82//82
            +f 83//83 90//90 91//91
            +f 91//91 84//84 83//83
            +f 84//84 91//91 85//85
            +f 92//92 85//85 91//91
            +f 93//93 86//86 92//92
            +f 85//85 92//92 86//86
            +f 94//94 87//87 93//93
            +f 86//86 93//93 87//87
            +f 95//95 88//88 94//94
            +f 87//87 94//94 88//88
            +f 89//89 96//96 90//90
            +f 97//97 90//90 96//96
            +f 90//90 97//97 98//98
            +f 98//98 91//91 90//90
            +f 91//91 98//98 99//99
            +f 99//99 92//92 91//91
            +f 100//100 93//93 92//92
            +f 92//92 99//99 100//100
            +f 101//101 94//94 93//93
            +f 93//93 100//100 101//101
            +f 102//102 95//95 94//94
            +f 94//94 101//101 102//102
            +f 96//96 103//103 97//97
            +f 104//104 97//97 103//103
            +f 97//97 104//104 105//105
            +f 105//105 98//98 97//97
            +f 98//98 105//105 106//106
            +f 106//106 99//99 98//98
            +f 107//107 100//100 99//99
            +f 99//99 106//106 107//107
            +f 108//108 101//101 100//100
            +f 100//100 107//107 108//108
            +f 109//109 102//102 101//101
            +f 101//101 108//108 109//109
            +f 103//103 110//110 104//104
            +f 111//111 104//104 110//110
            +f 104//104 111//111 112//112
            +f 112//112 105//105 104//104
            +f 105//105 112//112 113//113
            +f 113//113 106//106 105//105
            +f 114//114 107//107 106//106
            +f 106//106 113//113 114//114
            +f 115//115 108//108 107//107
            +f 107//107 114//114 115//115
            +f 116//116 109//109 108//108
            +f 108//108 115//115 116//116
            +f 110//110 117//117 118//118
            +f 118//118 111//111 110//110
            +f 111//111 118//118 119//119
            +f 119//119 112//112 111//111
            +f 112//112 119//119 113//113
            +f 120//120 113//113 119//119
            +f 121//121 114//114 120//120
            +f 113//113 120//120 114//114
            +f 122//122 115//115 121//121
            +f 114//114 121//121 115//115
            +f 123//123 116//116 122//122
            +f 115//115 122//122 116//116
            +f 117//117 124//124 125//125
            +f 125//125 118//118 117//117
            +f 118//118 125//125 119//119
            +f 126//126 119//119 125//125
            +f 119//119 126//126 120//120
            +f 127//127 120//120 126//126
            +f 128//128 121//121 127//127
            +f 120//120 127//127 121//121
            +f 129//129 122//122 128//128
            +f 121//121 128//128 122//122
            +f 130//130 123//123 129//129
            +f 122//122 129//129 123//123
            +f 124//124 131//131 132//132
            +f 132//132 125//125 124//124
            +f 125//125 132//132 133//133
            +f 133//133 126//126 125//125
            +f 126//126 133//133 127//127
            +f 134//134 127//127 133//133
            +f 135//135 128//128 134//134
            +f 127//127 134//134 128//128
            +f 136//136 129//129 135//135
            +f 128//128 135//135 129//129
            +f 137//137 130//130 136//136
            +f 129//129 136//136 130//130
            +f 131//131 138//138 132//132
            +f 139//139 132//132 138//138
            +f 132//132 139//139 140//140
            +f 140//140 133//133 132//132
            +f 133//133 140//140 141//141
            +f 141//141 134//134 133//133
            +f 142//142 135//135 134//134
            +f 134//134 141//141 142//142
            +f 143//143 136//136 135//135
            +f 135//135 142//142 143//143
            +f 144//144 137//137 136//136
            +f 136//136 143//143 144//144
            +f 138//138 145//145 139//139
            +f 146//146 139//139 145//145
            +f 139//139 146//146 147//147
            +f 147//147 140//140 139//139
            +f 140//140 147//147 148//148
            +f 148//148 141//141 140//140
            +f 149//149 142//142 141//141
            +f 141//141 148//148 149//149
            +f 150//150 143//143 142//142
            +f 142//142 149//149 150//150
            +f 151//151 144//144 143//143
            +f 143//143 150//150 151//151
            +f 145//145 152//152 146//146
            +f 153//153 146//146 152//152
            +f 146//146 153//153 154//154
            +f 154//154 147//147 146//146
            +f 147//147 154//154 155//155
            +f 155//155 148//148 147//147
            +f 156//156 149//149 148//148
            +f 148//148 155//155 156//156
            +f 157//157 150//150 149//149
            +f 149//149 156//156 157//157
            +f 158//158 151//151 150//150
            +f 150//150 157//157 158//158
            +f 152//152 159//159 160//160
            +f 160//160 153//153 152//152
            +f 153//153 160//160 154//154
            +f 161//161 154//154 160//160
            +f 154//154 161//161 155//155
            +f 162//162 155//155 161//161
            +f 163//163 156//156 162//162
            +f 155//155 162//162 156//156
            +f 164//164 157//157 163//163
            +f 156//156 163//163 157//157
            +f 165//165 158//158 164//164
            +f 157//157 164//164 158//158
            +f 159//159 166//166 167//167
            +f 167//167 160//160 159//159
            +f 160//160 167//167 161//161
            +f 168//168 161//161 167//167
            +f 161//161 168//168 162//162
            +f 169//169 162//162 168//168
            +f 170//170 163//163 169//169
            +f 162//162 169//169 163//163
            +f 171//171 164//164 170//170
            +f 163//163 170//170 164//164
            +f 172//172 165//165 171//171
            +f 164//164 171//171 165//165
            +f 166//166 173//173 174//174
            +f 174//174 167//167 166//166
            +f 167//167 174//174 168//168
            +f 175//175 168//168 174//174
            +f 168//168 175//175 169//169
            +f 176//176 169//169 175//175
            +f 177//177 170//170 176//176
            +f 169//169 176//176 170//170
            +f 178//178 171//171 177//177
            +f 170//170 177//177 171//171
            +f 179//179 172//172 178//178
            +f 171//171 178//178 172//172
            +f 173//173 180//180 174//174
            +f 181//181 174//174 180//180
            +f 174//174 181//181 175//175
            +f 182//182 175//175 181//181
            +f 175//175 182//182 183//183
            +f 183//183 176//176 175//175
            +f 184//184 177//177 176//176
            +f 176//176 183//183 184//184
            +f 185//185 178//178 177//177
            +f 177//177 184//184 185//185
            +f 186//186 179//179 178//178
            +f 178//178 185//185 186//186
            +f 180//180 187//187 181//181
            +f 188//188 181//181 187//187
            +f 181//181 188//188 189//189
            +f 189//189 182//182 181//181
            +f 182//182 189//189 190//190
            +f 190//190 183//183 182//182
            +f 191//191 184//184 183//183
            +f 183//183 190//190 191//191
            +f 192//192 185//185 184//184
            +f 184//184 191//191 192//192
            +f 193//193 186//186 185//185
            +f 185//185 192//192 193//193
            +f 187//187 26//26 188//188
            +f 29//29 188//188 26//26
            +f 188//188 29//29 189//189
            +f 30//30 189//189 29//29
            +f 189//189 30//30 32//32
            +f 32//32 190//190 189//189
            +f 35//35 191//191 190//190
            +f 190//190 32//32 35//35
            +f 37//37 192//192 191//191
            +f 191//191 35//35 37//37
            +f 39//39 193//193 192//192
            +f 192//192 37//37 39//39
            +f 194//194 195//195 38//38
            +f 39//39 38//38 195//195
            +f 196//196 197//197 194//194
            +f 195//195 194//194 197//197
            +f 198//198 199//199 196//196
            +f 197//197 196//196 199//199
            +f 200//200 201//201 198//198
            +f 199//199 198//198 201//201
            +f 202//202 203//203 200//200
            +f 201//201 200//200 203//203
            +f 204//204 205//205 202//202
            +f 203//203 202//202 205//205
            +f 206//206 194//194 46//46
            +f 38//38 46//46 194//194
            +f 207//207 196//196 206//206
            +f 194//194 206//206 196//196
            +f 208//208 198//198 207//207
            +f 196//196 207//207 198//198
            +f 209//209 200//200 208//208
            +f 198//198 208//208 200//200
            +f 210//210 202//202 209//209
            +f 200//200 209//209 202//202
            +f 211//211 204//204 210//210
            +f 202//202 210//210 204//204
            +f 212//212 206//206 53//53
            +f 46//46 53//53 206//206
            +f 213//213 207//207 212//212
            +f 206//206 212//212 207//207
            +f 214//214 208//208 213//213
            +f 207//207 213//213 208//208
            +f 215//215 209//209 214//214
            +f 208//208 214//214 209//209
            +f 216//216 210//210 215//215
            +f 209//209 215//215 210//210
            +f 217//217 211//211 216//216
            +f 210//210 216//216 211//211
            +f 218//218 212//212 53//53
            +f 53//53 60//60 218//218
            +f 219//219 213//213 212//212
            +f 212//212 218//218 219//219
            +f 220//220 214//214 213//213
            +f 213//213 219//219 220//220
            +f 221//221 215//215 214//214
            +f 214//214 220//220 221//221
            +f 222//222 216//216 215//215
            +f 215//215 221//221 222//222
            +f 223//223 217//217 216//216
            +f 216//216 222//222 223//223
            +f 224//224 218//218 60//60
            +f 60//60 67//67 224//224
            +f 225//225 219//219 218//218
            +f 218//218 224//224 225//225
            +f 226//226 220//220 219//219
            +f 219//219 225//225 226//226
            +f 227//227 221//221 220//220
            +f 220//220 226//226 227//227
            +f 228//228 222//222 221//221
            +f 221//221 227//227 228//228
            +f 229//229 223//223 222//222
            +f 222//222 228//228 229//229
            +f 230//230 224//224 67//67
            +f 67//67 74//74 230//230
            +f 231//231 225//225 224//224
            +f 224//224 230//230 231//231
            +f 232//232 226//226 225//225
            +f 225//225 231//231 232//232
            +f 233//233 227//227 226//226
            +f 226//226 232//232 233//233
            +f 234//234 228//228 227//227
            +f 227//227 233//233 234//234
            +f 235//235 229//229 228//228
            +f 228//228 234//234 235//235
            +f 236//236 230//230 81//81
            +f 74//74 81//81 230//230
            +f 237//237 231//231 236//236
            +f 230//230 236//236 231//231
            +f 238//238 232//232 237//237
            +f 231//231 237//237 232//232
            +f 239//239 233//233 238//238
            +f 232//232 238//238 233//233
            +f 240//240 234//234 239//239
            +f 233//233 239//239 234//234
            +f 241//241 235//235 240//240
            +f 234//234 240//240 235//235
            +f 242//242 236//236 88//88
            +f 81//81 88//88 236//236
            +f 243//243 237//237 242//242
            +f 236//236 242//242 237//237
            +f 244//244 238//238 243//243
            +f 237//237 243//243 238//238
            +f 245//245 239//239 244//244
            +f 238//238 244//244 239//239
            +f 246//246 240//240 245//245
            +f 239//239 245//245 240//240
            +f 247//247 241//241 246//246
            +f 240//240 246//246 241//241
            +f 248//248 242//242 95//95
            +f 88//88 95//95 242//242
            +f 249//249 243//243 248//248
            +f 242//242 248//248 243//243
            +f 250//250 244//244 249//249
            +f 243//243 249//249 244//244
            +f 251//251 245//245 250//250
            +f 244//244 250//250 245//245
            +f 252//252 246//246 251//251
            +f 245//245 251//251 246//246
            +f 253//253 247//247 252//252
            +f 246//246 252//252 247//247
            +f 254//254 248//248 95//95
            +f 95//95 102//102 254//254
            +f 255//255 249//249 248//248
            +f 248//248 254//254 255//255
            +f 256//256 250//250 249//249
            +f 249//249 255//255 256//256
            +f 257//257 251//251 250//250
            +f 250//250 256//256 257//257
            +f 258//258 252//252 251//251
            +f 251//251 257//257 258//258
            +f 259//259 253//253 252//252
            +f 252//252 258//258 259//259
            +f 260//260 254//254 102//102
            +f 102//102 109//109 260//260
            +f 261//261 255//255 254//254
            +f 254//254 260//260 261//261
            +f 262//262 256//256 255//255
            +f 255//255 261//261 262//262
            +f 263//263 257//257 256//256
            +f 256//256 262//262 263//263
            +f 264//264 258//258 257//257
            +f 257//257 263//263 264//264
            +f 265//265 259//259 258//258
            +f 258//258 264//264 265//265
            +f 266//266 260//260 109//109
            +f 109//109 116//116 266//266
            +f 267//267 261//261 260//260
            +f 260//260 266//266 267//267
            +f 268//268 262//262 261//261
            +f 261//261 267//267 268//268
            +f 269//269 263//263 262//262
            +f 262//262 268//268 269//269
            +f 270//270 264//264 263//263
            +f 263//263 269//269 270//270
            +f 271//271 265//265 264//264
            +f 264//264 270//270 271//271
            +f 272//272 266//266 123//123
            +f 116//116 123//123 266//266
            +f 273//273 267//267 272//272
            +f 266//266 272//272 267//267
            +f 274//274 268//268 273//273
            +f 267//267 273//273 268//268
            +f 275//275 269//269 274//274
            +f 268//268 274//274 269//269
            +f 276//276 270//270 275//275
            +f 269//269 275//275 270//270
            +f 277//277 271//271 276//276
            +f 270//270 276//276 271//271
            +f 278//278 272//272 130//130
            +f 123//123 130//130 272//272
            +f 279//279 273//273 278//278
            +f 272//272 278//278 273//273
            +f 280//280 274//274 279//279
            +f 273//273 279//279 274//274
            +f 281//281 275//275 280//280
            +f 274//274 280//280 275//275
            +f 282//282 276//276 281//281
            +f 275//275 281//281 276//276
            +f 283//283 277//277 282//282
            +f 276//276 282//282 277//277
            +f 284//284 278//278 137//137
            +f 130//130 137//137 278//278
            +f 285//285 279//279 284//284
            +f 278//278 284//284 279//279
            +f 286//286 280//280 285//285
            +f 279//279 285//285 280//280
            +f 287//287 281//281 286//286
            +f 280//280 286//286 281//281
            +f 288//288 282//282 287//287
            +f 281//281 287//287 282//282
            +f 289//289 283//283 288//288
            +f 282//282 288//288 283//283
            +f 290//290 284//284 137//137
            +f 137//137 144//144 290//290
            +f 291//291 285//285 284//284
            +f 284//284 290//290 291//291
            +f 292//292 286//286 285//285
            +f 285//285 291//291 292//292
            +f 293//293 287//287 286//286
            +f 286//286 292//292 293//293
            +f 294//294 288//288 287//287
            +f 287//287 293//293 294//294
            +f 295//295 289//289 288//288
            +f 288//288 294//294 295//295
            +f 296//296 290//290 144//144
            +f 144//144 151//151 296//296
            +f 297//297 291//291 290//290
            +f 290//290 296//296 297//297
            +f 298//298 292//292 291//291
            +f 291//291 297//297 298//298
            +f 299//299 293//293 292//292
            +f 292//292 298//298 299//299
            +f 300//300 294//294 293//293
            +f 293//293 299//299 300//300
            +f 301//301 295//295 294//294
            +f 294//294 300//300 301//301
            +f 302//302 296//296 151//151
            +f 151//151 158//158 302//302
            +f 303//303 297//297 296//296
            +f 296//296 302//302 303//303
            +f 304//304 298//298 297//297
            +f 297//297 303//303 304//304
            +f 305//305 299//299 298//298
            +f 298//298 304//304 305//305
            +f 306//306 300//300 299//299
            +f 299//299 305//305 306//306
            +f 307//307 301//301 300//300
            +f 300//300 306//306 307//307
            +f 308//308 302//302 165//165
            +f 158//158 165//165 302//302
            +f 309//309 303//303 308//308
            +f 302//302 308//308 303//303
            +f 310//310 304//304 309//309
            +f 303//303 309//309 304//304
            +f 311//311 305//305 310//310
            +f 304//304 310//310 305//305
            +f 312//312 306//306 311//311
            +f 305//305 311//311 306//306
            +f 313//313 307//307 312//312
            +f 306//306 312//312 307//307
            +f 314//314 308//308 172//172
            +f 165//165 172//172 308//308
            +f 315//315 309//309 314//314
            +f 308//308 314//314 309//309
            +f 316//316 310//310 315//315
            +f 309//309 315//315 310//310
            +f 317//317 311//311 316//316
            +f 310//310 316//316 311//311
            +f 318//318 312//312 317//317
            +f 311//311 317//317 312//312
            +f 319//319 313//313 318//318
            +f 312//312 318//318 313//313
            +f 320//320 314//314 179//179
            +f 172//172 179//179 314//314
            +f 321//321 315//315 320//320
            +f 314//314 320//320 315//315
            +f 322//322 316//316 321//321
            +f 315//315 321//321 316//316
            +f 323//323 317//317 322//322
            +f 316//316 322//322 317//317
            +f 324//324 318//318 323//323
            +f 317//317 323//323 318//318
            +f 325//325 319//319 324//324
            +f 318//318 324//324 319//319
            +f 326//326 320//320 179//179
            +f 179//179 186//186 326//326
            +f 327//327 321//321 320//320
            +f 320//320 326//326 327//327
            +f 328//328 322//322 321//321
            +f 321//321 327//327 328//328
            +f 329//329 323//323 322//322
            +f 322//322 328//328 329//329
            +f 330//330 324//324 323//323
            +f 323//323 329//329 330//330
            +f 331//331 325//325 324//324
            +f 324//324 330//330 331//331
            +f 332//332 326//326 186//186
            +f 186//186 193//193 332//332
            +f 333//333 327//327 326//326
            +f 326//326 332//332 333//333
            +f 334//334 328//328 327//327
            +f 327//327 333//333 334//334
            +f 335//335 329//329 328//328
            +f 328//328 334//334 335//335
            +f 336//336 330//330 329//329
            +f 329//329 335//335 336//336
            +f 337//337 331//331 330//330
            +f 330//330 336//336 337//337
            +f 195//195 332//332 193//193
            +f 193//193 39//39 195//195
            +f 197//197 333//333 332//332
            +f 332//332 195//195 197//197
            +f 199//199 334//334 333//333
            +f 333//333 197//197 199//199
            +f 201//201 335//335 334//334
            +f 334//334 199//199 201//201
            +f 203//203 336//336 335//335
            +f 335//335 201//201 203//203
            +f 205//205 337//337 336//336
            +f 336//336 203//203 205//205
            +f 338//338 339//339 205//205
            +f 205//205 204//204 338//338
            +f 340//340 341//341 339//339
            +f 339//339 338//338 340//340
            +f 342//342 343//343 341//341
            +f 341//341 340//340 342//342
            +f 344//344 345//345 343//343
            +f 343//343 342//342 344//344
            +f 346//346 347//347 345//345
            +f 345//345 344//344 346//346
            +f 348//348 349//349 347//347
            +f 347//347 346//346 348//348
            +f 350//350 338//338 204//204
            +f 204//204 211//211 350//350
            +f 351//351 340//340 338//338
            +f 338//338 350//350 351//351
            +f 352//352 342//342 340//340
            +f 340//340 351//351 352//352
            +f 353//353 344//344 342//342
            +f 342//342 352//352 353//353
            +f 354//354 346//346 344//344
            +f 344//344 353//353 354//354
            +f 355//355 348//348 346//346
            +f 346//346 354//354 355//355
            +f 356//356 350//350 211//211
            +f 211//211 217//217 356//356
            +f 357//357 351//351 350//350
            +f 350//350 356//356 357//357
            +f 358//358 352//352 351//351
            +f 351//351 357//357 358//358
            +f 359//359 353//353 352//352
            +f 352//352 358//358 359//359
            +f 360//360 354//354 353//353
            +f 353//353 359//359 360//360
            +f 361//361 355//355 354//354
            +f 354//354 360//360 361//361
            +f 362//362 356//356 223//223
            +f 217//217 223//223 356//356
            +f 363//363 357//357 362//362
            +f 356//356 362//362 357//357
            +f 364//364 358//358 363//363
            +f 357//357 363//363 358//358
            +f 365//365 359//359 364//364
            +f 358//358 364//364 359//359
            +f 366//366 360//360 365//365
            +f 359//359 365//365 360//360
            +f 367//367 361//361 366//366
            +f 360//360 366//366 361//361
            +f 368//368 362//362 229//229
            +f 223//223 229//229 362//362
            +f 369//369 363//363 368//368
            +f 362//362 368//368 363//363
            +f 370//370 364//364 369//369
            +f 363//363 369//369 364//364
            +f 371//371 365//365 370//370
            +f 364//364 370//370 365//365
            +f 372//372 366//366 371//371
            +f 365//365 371//371 366//366
            +f 373//373 367//367 372//372
            +f 366//366 372//372 367//367
            +f 374//374 368//368 235//235
            +f 229//229 235//235 368//368
            +f 375//375 369//369 374//374
            +f 368//368 374//374 369//369
            +f 376//376 370//370 375//375
            +f 369//369 375//375 370//370
            +f 377//377 371//371 376//376
            +f 370//370 376//376 371//371
            +f 378//378 372//372 377//377
            +f 371//371 377//377 372//372
            +f 379//379 373//373 378//378
            +f 372//372 378//378 373//373
            +f 380//380 374//374 235//235
            +f 235//235 241//241 380//380
            +f 381//381 375//375 374//374
            +f 374//374 380//380 381//381
            +f 382//382 376//376 375//375
            +f 375//375 381//381 382//382
            +f 383//383 377//377 376//376
            +f 376//376 382//382 383//383
            +f 384//384 378//378 377//377
            +f 377//377 383//383 384//384
            +f 385//385 379//379 378//378
            +f 378//378 384//384 385//385
            +f 386//386 380//380 241//241
            +f 241//241 247//247 386//386
            +f 387//387 381//381 380//380
            +f 380//380 386//386 387//387
            +f 388//388 382//382 381//381
            +f 381//381 387//387 388//388
            +f 389//389 383//383 382//382
            +f 382//382 388//388 389//389
            +f 390//390 384//384 383//383
            +f 383//383 389//389 390//390
            +f 391//391 385//385 384//384
            +f 384//384 390//390 391//391
            +f 392//392 386//386 247//247
            +f 247//247 253//253 392//392
            +f 393//393 387//387 386//386
            +f 386//386 392//392 393//393
            +f 394//394 388//388 387//387
            +f 387//387 393//393 394//394
            +f 395//395 389//389 388//388
            +f 388//388 394//394 395//395
            +f 396//396 390//390 389//389
            +f 389//389 395//395 396//396
            +f 397//397 391//391 390//390
            +f 390//390 396//396 397//397
            +f 398//398 392//392 259//259
            +f 253//253 259//259 392//392
            +f 399//399 393//393 398//398
            +f 392//392 398//398 393//393
            +f 400//400 394//394 399//399
            +f 393//393 399//399 394//394
            +f 401//401 395//395 400//400
            +f 394//394 400//400 395//395
            +f 402//402 396//396 401//401
            +f 395//395 401//401 396//396
            +f 403//403 397//397 402//402
            +f 396//396 402//402 397//397
            +f 404//404 398//398 265//265
            +f 259//259 265//265 398//398
            +f 405//405 399//399 404//404
            +f 398//398 404//404 399//399
            +f 406//406 400//400 405//405
            +f 399//399 405//405 400//400
            +f 407//407 401//401 406//406
            +f 400//400 406//406 401//401
            +f 408//408 402//402 407//407
            +f 401//401 407//407 402//402
            +f 409//409 403//403 408//408
            +f 402//402 408//408 403//403
            +f 410//410 404//404 271//271
            +f 265//265 271//271 404//404
            +f 411//411 405//405 410//410
            +f 404//404 410//410 405//405
            +f 412//412 406//406 411//411
            +f 405//405 411//411 406//406
            +f 413//413 407//407 412//412
            +f 406//406 412//412 407//407
            +f 414//414 408//408 413//413
            +f 407//407 413//413 408//408
            +f 415//415 409//409 414//414
            +f 408//408 414//414 409//409
            +f 416//416 410//410 271//271
            +f 271//271 277//277 416//416
            +f 417//417 411//411 410//410
            +f 410//410 416//416 417//417
            +f 418//418 412//412 411//411
            +f 411//411 417//417 418//418
            +f 419//419 413//413 412//412
            +f 412//412 418//418 419//419
            +f 420//420 414//414 413//413
            +f 413//413 419//419 420//420
            +f 421//421 415//415 414//414
            +f 414//414 420//420 421//421
            +f 422//422 416//416 277//277
            +f 277//277 283//283 422//422
            +f 423//423 417//417 416//416
            +f 416//416 422//422 423//423
            +f 424//424 418//418 417//417
            +f 417//417 423//423 424//424
            +f 425//425 419//419 418//418
            +f 418//418 424//424 425//425
            +f 426//426 420//420 419//419
            +f 419//419 425//425 426//426
            +f 427//427 421//421 420//420
            +f 420//420 426//426 427//427
            +f 428//428 422//422 283//283
            +f 283//283 289//289 428//428
            +f 429//429 423//423 422//422
            +f 422//422 428//428 429//429
            +f 430//430 424//424 423//423
            +f 423//423 429//429 430//430
            +f 431//431 425//425 424//424
            +f 424//424 430//430 431//431
            +f 432//432 426//426 425//425
            +f 425//425 431//431 432//432
            +f 433//433 427//427 426//426
            +f 426//426 432//432 433//433
            +f 434//434 428//428 295//295
            +f 289//289 295//295 428//428
            +f 435//435 429//429 434//434
            +f 428//428 434//434 429//429
            +f 436//436 430//430 435//435
            +f 429//429 435//435 430//430
            +f 437//437 431//431 436//436
            +f 430//430 436//436 431//431
            +f 438//438 432//432 437//437
            +f 431//431 437//437 432//432
            +f 439//439 433//433 438//438
            +f 432//432 438//438 433//433
            +f 440//440 434//434 301//301
            +f 295//295 301//301 434//434
            +f 441//441 435//435 440//440
            +f 434//434 440//440 435//435
            +f 442//442 436//436 441//441
            +f 435//435 441//441 436//436
            +f 443//443 437//437 442//442
            +f 436//436 442//442 437//437
            +f 444//444 438//438 443//443
            +f 437//437 443//443 438//438
            +f 445//445 439//439 444//444
            +f 438//438 444//444 439//439
            +f 446//446 440//440 307//307
            +f 301//301 307//307 440//440
            +f 447//447 441//441 446//446
            +f 440//440 446//446 441//441
            +f 448//448 442//442 447//447
            +f 441//441 447//447 442//442
            +f 449//449 443//443 448//448
            +f 442//442 448//448 443//443
            +f 450//450 444//444 449//449
            +f 443//443 449//449 444//444
            +f 451//451 445//445 450//450
            +f 444//444 450//450 445//445
            +f 452//452 446//446 307//307
            +f 307//307 313//313 452//452
            +f 453//453 447//447 446//446
            +f 446//446 452//452 453//453
            +f 454//454 448//448 447//447
            +f 447//447 453//453 454//454
            +f 455//455 449//449 448//448
            +f 448//448 454//454 455//455
            +f 456//456 450//450 449//449
            +f 449//449 455//455 456//456
            +f 457//457 451//451 450//450
            +f 450//450 456//456 457//457
            +f 458//458 452//452 313//313
            +f 313//313 319//319 458//458
            +f 459//459 453//453 452//452
            +f 452//452 458//458 459//459
            +f 460//460 454//454 453//453
            +f 453//453 459//459 460//460
            +f 461//461 455//455 454//454
            +f 454//454 460//460 461//461
            +f 462//462 456//456 455//455
            +f 455//455 461//461 462//462
            +f 463//463 457//457 456//456
            +f 456//456 462//462 463//463
            +f 464//464 458//458 319//319
            +f 319//319 325//325 464//464
            +f 465//465 459//459 458//458
            +f 458//458 464//464 465//465
            +f 466//466 460//460 459//459
            +f 459//459 465//465 466//466
            +f 467//467 461//461 460//460
            +f 460//460 466//466 467//467
            +f 468//468 462//462 461//461
            +f 461//461 467//467 468//468
            +f 469//469 463//463 462//462
            +f 462//462 468//468 469//469
            +f 470//470 464//464 331//331
            +f 325//325 331//331 464//464
            +f 471//471 465//465 470//470
            +f 464//464 470//470 465//465
            +f 472//472 466//466 471//471
            +f 465//465 471//471 466//466
            +f 473//473 467//467 472//472
            +f 466//466 472//472 467//467
            +f 474//474 468//468 473//473
            +f 467//467 473//473 468//468
            +f 475//475 469//469 474//474
            +f 468//468 474//474 469//469
            +f 476//476 470//470 337//337
            +f 331//331 337//337 470//470
            +f 477//477 471//471 476//476
            +f 470//470 476//476 471//471
            +f 478//478 472//472 477//477
            +f 471//471 477//477 472//472
            +f 479//479 473//473 478//478
            +f 472//472 478//478 473//473
            +f 480//480 474//474 479//479
            +f 473//473 479//479 474//474
            +f 481//481 475//475 480//480
            +f 474//474 480//480 475//475
            +f 339//339 476//476 205//205
            +f 337//337 205//205 476//476
            +f 341//341 477//477 339//339
            +f 476//476 339//339 477//477
            +f 343//343 478//478 341//341
            +f 477//477 341//341 478//478
            +f 345//345 479//479 343//343
            +f 478//478 343//343 479//479
            +f 347//347 480//480 345//345
            +f 479//479 345//345 480//480
            +f 349//349 481//481 347//347
            +f 480//480 347//347 481//481
            +f 1//1 3//3 482//482
            +f 483//483 482//482 3//3
            +f 482//482 483//483 484//484
            +f 485//485 484//484 483//483
            +f 484//484 485//485 486//486
            +f 487//487 486//486 485//485
            +f 486//486 487//487 488//488
            +f 489//489 488//488 487//487
            +f 488//488 489//489 349//349
            +f 481//481 349//349 489//489
            +f 3//3 4//4 483//483
            +f 490//490 483//483 4//4
            +f 483//483 490//490 485//485
            +f 491//491 485//485 490//490
            +f 485//485 491//491 487//487
            +f 492//492 487//487 491//491
            +f 487//487 492//492 489//489
            +f 493//493 489//489 492//492
            +f 489//489 493//493 481//481
            +f 475//475 481//481 493//493
            +f 4//4 5//5 490//490
            +f 494//494 490//490 5//5
            +f 490//490 494//494 491//491
            +f 495//495 491//491 494//494
            +f 491//491 495//495 492//492
            +f 496//496 492//492 495//495
            +f 492//492 496//496 493//493
            +f 497//497 493//493 496//496
            +f 493//493 497//497 475//475
            +f 469//469 475//475 497//497
            +f 5//5 6//6 498//498
            +f 498//498 494//494 5//5
            +f 494//494 498//498 499//499
            +f 499//499 495//495 494//494
            +f 495//495 499//499 500//500
            +f 500//500 496//496 495//495
            +f 496//496 500//500 501//501
            +f 501//501 497//497 496//496
            +f 497//497 501//501 463//463
            +f 463//463 469//469 497//497
            +f 6//6 7//7 502//502
            +f 502//502 498//498 6//6
            +f 498//498 502//502 503//503
            +f 503//503 499//499 498//498
            +f 499//499 503//503 504//504
            +f 504//504 500//500 499//499
            +f 500//500 504//504 505//505
            +f 505//505 501//501 500//500
            +f 501//501 505//505 457//457
            +f 457//457 463//463 501//501
            +f 7//7 8//8 506//506
            +f 506//506 502//502 7//7
            +f 502//502 506//506 507//507
            +f 507//507 503//503 502//502
            +f 503//503 507//507 508//508
            +f 508//508 504//504 503//503
            +f 504//504 508//508 509//509
            +f 509//509 505//505 504//504
            +f 505//505 509//509 451//451
            +f 451//451 457//457 505//505
            +f 8//8 9//9 506//506
            +f 510//510 506//506 9//9
            +f 506//506 510//510 507//507
            +f 511//511 507//507 510//510
            +f 507//507 511//511 508//508
            +f 512//512 508//508 511//511
            +f 508//508 512//512 509//509
            +f 513//513 509//509 512//512
            +f 509//509 513//513 451//451
            +f 445//445 451//451 513//513
            +f 9//9 10//10 510//510
            +f 514//514 510//510 10//10
            +f 510//510 514//514 511//511
            +f 515//515 511//511 514//514
            +f 511//511 515//515 512//512
            +f 516//516 512//512 515//515
            +f 512//512 516//516 513//513
            +f 517//517 513//513 516//516
            +f 513//513 517//517 445//445
            +f 439//439 445//445 517//517
            +f 10//10 11//11 514//514
            +f 518//518 514//514 11//11
            +f 514//514 518//518 515//515
            +f 519//519 515//515 518//518
            +f 515//515 519//519 516//516
            +f 520//520 516//516 519//519
            +f 516//516 520//520 517//517
            +f 521//521 517//517 520//520
            +f 517//517 521//521 439//439
            +f 433//433 439//439 521//521
            +f 11//11 12//12 522//522
            +f 522//522 518//518 11//11
            +f 518//518 522//522 523//523
            +f 523//523 519//519 518//518
            +f 519//519 523//523 524//524
            +f 524//524 520//520 519//519
            +f 520//520 524//524 525//525
            +f 525//525 521//521 520//520
            +f 521//521 525//525 427//427
            +f 427//427 433//433 521//521
            +f 12//12 13//13 526//526
            +f 526//526 522//522 12//12
            +f 522//522 526//526 527//527
            +f 527//527 523//523 522//522
            +f 523//523 527//527 528//528
            +f 528//528 524//524 523//523
            +f 524//524 528//528 529//529
            +f 529//529 525//525 524//524
            +f 525//525 529//529 421//421
            +f 421//421 427//427 525//525
            +f 13//13 14//14 530//530
            +f 530//530 526//526 13//13
            +f 526//526 530//530 531//531
            +f 531//531 527//527 526//526
            +f 527//527 531//531 532//532
            +f 532//532 528//528 527//527
            +f 528//528 532//532 533//533
            +f 533//533 529//529 528//528
            +f 529//529 533//533 415//415
            +f 415//415 421//421 529//529
            +f 14//14 15//15 530//530
            +f 534//534 530//530 15//15
            +f 530//530 534//534 531//531
            +f 535//535 531//531 534//534
            +f 531//531 535//535 532//532
            +f 536//536 532//532 535//535
            +f 532//532 536//536 533//533
            +f 537//537 533//533 536//536
            +f 533//533 537//537 415//415
            +f 409//409 415//415 537//537
            +f 15//15 16//16 534//534
            +f 538//538 534//534 16//16
            +f 534//534 538//538 535//535
            +f 539//539 535//535 538//538
            +f 535//535 539//539 536//536
            +f 540//540 536//536 539//539
            +f 536//536 540//540 537//537
            +f 541//541 537//537 540//540
            +f 537//537 541//541 409//409
            +f 403//403 409//409 541//541
            +f 16//16 17//17 538//538
            +f 542//542 538//538 17//17
            +f 538//538 542//542 539//539
            +f 543//543 539//539 542//542
            +f 539//539 543//543 540//540
            +f 544//544 540//540 543//543
            +f 540//540 544//544 541//541
            +f 545//545 541//541 544//544
            +f 541//541 545//545 403//403
            +f 397//397 403//403 545//545
            +f 17//17 18//18 546//546
            +f 546//546 542//542 17//17
            +f 542//542 546//546 547//547
            +f 547//547 543//543 542//542
            +f 543//543 547//547 548//548
            +f 548//548 544//544 543//543
            +f 544//544 548//548 549//549
            +f 549//549 545//545 544//544
            +f 545//545 549//549 391//391
            +f 391//391 397//397 545//545
            +f 18//18 19//19 550//550
            +f 550//550 546//546 18//18
            +f 546//546 550//550 551//551
            +f 551//551 547//547 546//546
            +f 547//547 551//551 552//552
            +f 552//552 548//548 547//547
            +f 548//548 552//552 553//553
            +f 553//553 549//549 548//548
            +f 549//549 553//553 385//385
            +f 385//385 391//391 549//549
            +f 19//19 20//20 554//554
            +f 554//554 550//550 19//19
            +f 550//550 554//554 555//555
            +f 555//555 551//551 550//550
            +f 551//551 555//555 556//556
            +f 556//556 552//552 551//551
            +f 552//552 556//556 557//557
            +f 557//557 553//553 552//552
            +f 553//553 557//557 379//379
            +f 379//379 385//385 553//553
            +f 20//20 21//21 554//554
            +f 558//558 554//554 21//21
            +f 554//554 558//558 555//555
            +f 559//559 555//555 558//558
            +f 555//555 559//559 556//556
            +f 560//560 556//556 559//559
            +f 556//556 560//560 557//557
            +f 561//561 557//557 560//560
            +f 557//557 561//561 379//379
            +f 373//373 379//379 561//561
            +f 21//21 22//22 558//558
            +f 562//562 558//558 22//22
            +f 558//558 562//562 559//559
            +f 563//563 559//559 562//562
            +f 559//559 563//563 560//560
            +f 564//564 560//560 563//563
            +f 560//560 564//564 561//561
            +f 565//565 561//561 564//564
            +f 561//561 565//565 373//373
            +f 367//367 373//373 565//565
            +f 22//22 23//23 562//562
            +f 566//566 562//562 23//23
            +f 562//562 566//566 563//563
            +f 567//567 563//563 566//566
            +f 563//563 567//567 564//564
            +f 568//568 564//564 567//567
            +f 564//564 568//568 565//565
            +f 569//569 565//565 568//568
            +f 565//565 569//569 367//367
            +f 361//361 367//367 569//569
            +f 23//23 24//24 570//570
            +f 570//570 566//566 23//23
            +f 566//566 570//570 571//571
            +f 571//571 567//567 566//566
            +f 567//567 571//571 572//572
            +f 572//572 568//568 567//567
            +f 568//568 572//572 573//573
            +f 573//573 569//569 568//568
            +f 569//569 573//573 355//355
            +f 355//355 361//361 569//569
            +f 24//24 25//25 574//574
            +f 574//574 570//570 24//24
            +f 570//570 574//574 575//575
            +f 575//575 571//571 570//570
            +f 571//571 575//575 576//576
            +f 576//576 572//572 571//571
            +f 572//572 576//576 577//577
            +f 577//577 573//573 572//572
            +f 573//573 577//577 348//348
            +f 348//348 355//355 573//573
            +f 25//25 1//1 482//482
            +f 482//482 574//574 25//25
            +f 574//574 482//482 484//484
            +f 484//484 575//575 574//574
            +f 575//575 484//484 486//486
            +f 486//486 576//576 575//575
            +f 576//576 486//486 488//488
            +f 488//488 577//577 576//576
            +f 577//577 488//488 349//349
            +f 349//349 348//348 577//577
            +f 578//578 579//579 580//580
            +f 581//581 580//580 579//579
            +f 582//582 578//578 583//583
            +f 580//580 583//583 578//578
            +f 584//584 582//582 585//585
            +f 583//583 585//585 582//582
            +f 586//586 584//584 585//585
            +f 585//585 587//587 586//586
            +f 588//588 586//586 587//587
            +f 587//587 589//589 588//588
            +f 590//590 588//588 589//589
            +f 589//589 591//591 590//590
            +f 592//592 590//590 593//593
            +f 591//591 593//593 590//590
            +f 594//594 592//592 595//595
            +f 593//593 595//595 592//592
            +f 596//596 594//594 597//597
            +f 595//595 597//597 594//594
            +f 598//598 596//596 597//597
            +f 597//597 599//599 598//598
            +f 600//600 598//598 599//599
            +f 599//599 601//601 600//600
            +f 602//602 600//600 601//601
            +f 601//601 603//603 602//602
            +f 604//604 602//602 605//605
            +f 603//603 605//605 602//602
            +f 606//606 604//604 607//607
            +f 605//605 607//607 604//604
            +f 608//608 606//606 609//609
            +f 607//607 609//609 606//606
            +f 610//610 608//608 609//609
            +f 609//609 611//611 610//610
            +f 612//612 610//610 611//611
            +f 611//611 613//613 612//612
            +f 614//614 612//612 613//613
            +f 613//613 615//615 614//614
            +f 616//616 614//614 617//617
            +f 615//615 617//617 614//614
            +f 618//618 616//616 619//619
            +f 617//617 619//619 616//616
            +f 620//620 618//618 621//621
            +f 619//619 621//621 618//618
            +f 622//622 620//620 621//621
            +f 621//621 623//623 622//622
            +f 624//624 622//622 623//623
            +f 623//623 625//625 624//624
            +f 579//579 624//624 625//625
            +f 625//625 581//581 579//579
            +f 626//626 627//627 578//578
            +f 579//579 578//578 627//627
            +f 628//628 629//629 626//626
            +f 627//627 626//626 629//629
            +f 630//630 631//631 628//628
            +f 629//629 628//628 631//631
            +f 632//632 633//633 630//630
            +f 631//631 630//630 633//633
            +f 634//634 635//635 632//632
            +f 633//633 632//632 635//635
            +f 636//636 637//637 634//634
            +f 635//635 634//634 637//637
            +f 638//638 626//626 582//582
            +f 578//578 582//582 626//626
            +f 639//639 628//628 638//638
            +f 626//626 638//638 628//628
            +f 640//640 630//630 639//639
            +f 628//628 639//639 630//630
            +f 641//641 632//632 640//640
            +f 630//630 640//640 632//632
            +f 642//642 634//634 641//641
            +f 632//632 641//641 634//634
            +f 643//643 636//636 642//642
            +f 634//634 642//642 636//636
            +f 644//644 638//638 584//584
            +f 582//582 584//584 638//638
            +f 645//645 639//639 644//644
            +f 638//638 644//644 639//639
            +f 646//646 640//640 645//645
            +f 639//639 645//645 640//640
            +f 647//647 641//641 646//646
            +f 640//640 646//646 641//641
            +f 648//648 642//642 647//647
            +f 641//641 647//647 642//642
            +f 649//649 643//643 648//648
            +f 642//642 648//648 643//643
            +f 650//650 644//644 584//584
            +f 584//584 586//586 650//650
            +f 651//651 645//645 644//644
            +f 644//644 650//650 651//651
            +f 652//652 646//646 645//645
            +f 645//645 651//651 652//652
            +f 653//653 647//647 646//646
            +f 646//646 652//652 653//653
            +f 654//654 648//648 647//647
            +f 647//647 653//653 654//654
            +f 655//655 649//649 648//648
            +f 648//648 654//654 655//655
            +f 656//656 650//650 586//586
            +f 586//586 588//588 656//656
            +f 657//657 651//651 650//650
            +f 650//650 656//656 657//657
            +f 658//658 652//652 651//651
            +f 651//651 657//657 658//658
            +f 659//659 653//653 652//652
            +f 652//652 658//658 659//659
            +f 660//660 654//654 653//653
            +f 653//653 659//659 660//660
            +f 661//661 655//655 654//654
            +f 654//654 660//660 661//661
            +f 662//662 656//656 588//588
            +f 588//588 590//590 662//662
            +f 663//663 657//657 656//656
            +f 656//656 662//662 663//663
            +f 664//664 658//658 657//657
            +f 657//657 663//663 664//664
            +f 665//665 659//659 658//658
            +f 658//658 664//664 665//665
            +f 666//666 660//660 659//659
            +f 659//659 665//665 666//666
            +f 667//667 661//661 660//660
            +f 660//660 666//666 667//667
            +f 668//668 662//662 592//592
            +f 590//590 592//592 662//662
            +f 669//669 663//663 668//668
            +f 662//662 668//668 663//663
            +f 670//670 664//664 669//669
            +f 663//663 669//669 664//664
            +f 671//671 665//665 670//670
            +f 664//664 670//670 665//665
            +f 672//672 666//666 671//671
            +f 665//665 671//671 666//666
            +f 673//673 667//667 672//672
            +f 666//666 672//672 667//667
            +f 674//674 668//668 594//594
            +f 592//592 594//594 668//668
            +f 675//675 669//669 674//674
            +f 668//668 674//674 669//669
            +f 676//676 670//670 675//675
            +f 669//669 675//675 670//670
            +f 677//677 671//671 676//676
            +f 670//670 676//676 671//671
            +f 678//678 672//672 677//677
            +f 671//671 677//677 672//672
            +f 679//679 673//673 678//678
            +f 672//672 678//678 673//673
            +f 680//680 674//674 596//596
            +f 594//594 596//596 674//674
            +f 681//681 675//675 680//680
            +f 674//674 680//680 675//675
            +f 682//682 676//676 681//681
            +f 675//675 681//681 676//676
            +f 683//683 677//677 682//682
            +f 676//676 682//682 677//677
            +f 684//684 678//678 683//683
            +f 677//677 683//683 678//678
            +f 685//685 679//679 684//684
            +f 678//678 684//684 679//679
            +f 686//686 680//680 596//596
            +f 596//596 598//598 686//686
            +f 687//687 681//681 680//680
            +f 680//680 686//686 687//687
            +f 688//688 682//682 681//681
            +f 681//681 687//687 688//688
            +f 689//689 683//683 682//682
            +f 682//682 688//688 689//689
            +f 690//690 684//684 683//683
            +f 683//683 689//689 690//690
            +f 691//691 685//685 684//684
            +f 684//684 690//690 691//691
            +f 692//692 686//686 598//598
            +f 598//598 600//600 692//692
            +f 693//693 687//687 686//686
            +f 686//686 692//692 693//693
            +f 694//694 688//688 687//687
            +f 687//687 693//693 694//694
            +f 695//695 689//689 688//688
            +f 688//688 694//694 695//695
            +f 696//696 690//690 689//689
            +f 689//689 695//695 696//696
            +f 697//697 691//691 690//690
            +f 690//690 696//696 697//697
            +f 698//698 692//692 600//600
            +f 600//600 602//602 698//698
            +f 699//699 693//693 692//692
            +f 692//692 698//698 699//699
            +f 700//700 694//694 693//693
            +f 693//693 699//699 700//700
            +f 701//701 695//695 694//694
            +f 694//694 700//700 701//701
            +f 702//702 696//696 695//695
            +f 695//695 701//701 702//702
            +f 703//703 697//697 696//696
            +f 696//696 702//702 703//703
            +f 704//704 698//698 604//604
            +f 602//602 604//604 698//698
            +f 705//705 699//699 704//704
            +f 698//698 704//704 699//699
            +f 706//706 700//700 705//705
            +f 699//699 705//705 700//700
            +f 707//707 701//701 706//706
            +f 700//700 706//706 701//701
            +f 708//708 702//702 707//707
            +f 701//701 707//707 702//702
            +f 709//709 703//703 708//708
            +f 702//702 708//708 703//703
            +f 710//710 704//704 606//606
            +f 604//604 606//606 704//704
            +f 711//711 705//705 710//710
            +f 704//704 710//710 705//705
            +f 712//712 706//706 711//711
            +f 705//705 711//711 706//706
            +f 713//713 707//707 712//712
            +f 706//706 712//712 707//707
            +f 714//714 708//708 713//713
            +f 707//707 713//713 708//708
            +f 715//715 709//709 714//714
            +f 708//708 714//714 709//709
            +f 716//716 710//710 608//608
            +f 606//606 608//608 710//710
            +f 717//717 711//711 716//716
            +f 710//710 716//716 711//711
            +f 718//718 712//712 717//717
            +f 711//711 717//717 712//712
            +f 719//719 713//713 718//718
            +f 712//712 718//718 713//713
            +f 720//720 714//714 719//719
            +f 713//713 719//719 714//714
            +f 721//721 715//715 720//720
            +f 714//714 720//720 715//715
            +f 722//722 716//716 608//608
            +f 608//608 610//610 722//722
            +f 723//723 717//717 716//716
            +f 716//716 722//722 723//723
            +f 724//724 718//718 717//717
            +f 717//717 723//723 724//724
            +f 725//725 719//719 718//718
            +f 718//718 724//724 725//725
            +f 726//726 720//720 719//719
            +f 719//719 725//725 726//726
            +f 727//727 721//721 720//720
            +f 720//720 726//726 727//727
            +f 728//728 722//722 610//610
            +f 610//610 612//612 728//728
            +f 729//729 723//723 722//722
            +f 722//722 728//728 729//729
            +f 730//730 724//724 723//723
            +f 723//723 729//729 730//730
            +f 731//731 725//725 724//724
            +f 724//724 730//730 731//731
            +f 732//732 726//726 725//725
            +f 725//725 731//731 732//732
            +f 733//733 727//727 726//726
            +f 726//726 732//732 733//733
            +f 734//734 728//728 612//612
            +f 612//612 614//614 734//734
            +f 735//735 729//729 728//728
            +f 728//728 734//734 735//735
            +f 736//736 730//730 729//729
            +f 729//729 735//735 736//736
            +f 737//737 731//731 730//730
            +f 730//730 736//736 737//737
            +f 738//738 732//732 731//731
            +f 731//731 737//737 738//738
            +f 739//739 733//733 732//732
            +f 732//732 738//738 739//739
            +f 740//740 734//734 616//616
            +f 614//614 616//616 734//734
            +f 741//741 735//735 740//740
            +f 734//734 740//740 735//735
            +f 742//742 736//736 741//741
            +f 735//735 741//741 736//736
            +f 743//743 737//737 742//742
            +f 736//736 742//742 737//737
            +f 744//744 738//738 743//743
            +f 737//737 743//743 738//738
            +f 745//745 739//739 744//744
            +f 738//738 744//744 739//739
            +f 746//746 740//740 618//618
            +f 616//616 618//618 740//740
            +f 747//747 741//741 746//746
            +f 740//740 746//746 741//741
            +f 748//748 742//742 747//747
            +f 741//741 747//747 742//742
            +f 749//749 743//743 748//748
            +f 742//742 748//748 743//743
            +f 750//750 744//744 749//749
            +f 743//743 749//749 744//744
            +f 751//751 745//745 750//750
            +f 744//744 750//750 745//745
            +f 752//752 746//746 620//620
            +f 618//618 620//620 746//746
            +f 753//753 747//747 752//752
            +f 746//746 752//752 747//747
            +f 754//754 748//748 753//753
            +f 747//747 753//753 748//748
            +f 755//755 749//749 754//754
            +f 748//748 754//754 749//749
            +f 756//756 750//750 755//755
            +f 749//749 755//755 750//750
            +f 757//757 751//751 756//756
            +f 750//750 756//756 751//751
            +f 758//758 752//752 620//620
            +f 620//620 622//622 758//758
            +f 759//759 753//753 752//752
            +f 752//752 758//758 759//759
            +f 760//760 754//754 753//753
            +f 753//753 759//759 760//760
            +f 761//761 755//755 754//754
            +f 754//754 760//760 761//761
            +f 762//762 756//756 755//755
            +f 755//755 761//761 762//762
            +f 763//763 757//757 756//756
            +f 756//756 762//762 763//763
            +f 764//764 758//758 622//622
            +f 622//622 624//624 764//764
            +f 765//765 759//759 758//758
            +f 758//758 764//764 765//765
            +f 766//766 760//760 759//759
            +f 759//759 765//765 766//766
            +f 767//767 761//761 760//760
            +f 760//760 766//766 767//767
            +f 768//768 762//762 761//761
            +f 761//761 767//767 768//768
            +f 769//769 763//763 762//762
            +f 762//762 768//768 769//769
            +f 627//627 764//764 624//624
            +f 624//624 579//579 627//627
            +f 629//629 765//765 764//764
            +f 764//764 627//627 629//629
            +f 631//631 766//766 765//765
            +f 765//765 629//629 631//631
            +f 633//633 767//767 766//766
            +f 766//766 631//631 633//633
            +f 635//635 768//768 767//767
            +f 767//767 633//633 635//635
            +f 637//637 769//769 768//768
            +f 768//768 635//635 637//637
            +f 770//770 771//771 772//772
            +f 773//773 772//772 771//771
            +f 774//774 770//770 775//775
            +f 772//772 775//775 770//770
            +f 776//776 777//777 774//774
            +f 774//774 775//775 776//776
            +f 778//778 779//779 776//776
            +f 777//777 776//776 779//779
            +f 780//780 781//781 778//778
            +f 779//779 778//778 781//781
            +f 782//782 783//783 780//780
            +f 781//781 780//780 783//783
            +f 772//772 773//773 784//784
            +f 785//785 784//784 773//773
            +f 775//775 772//772 786//786
            +f 784//784 786//786 772//772
            +f 776//776 775//775 787//787
            +f 786//786 787//787 775//775
            +f 788//788 778//778 776//776
            +f 776//776 787//787 788//788
            +f 789//789 780//780 788//788
            +f 778//778 788//788 780//780
            +f 790//790 782//782 789//789
            +f 780//780 789//789 782//782
            +f 784//784 785//785 791//791
            +f 792//792 791//791 785//785
            +f 786//786 784//784 793//793
            +f 791//791 793//793 784//784
            +f 787//787 786//786 794//794
            +f 793//793 794//794 786//786
            +f 795//795 788//788 787//787
            +f 787//787 794//794 795//795
            +f 796//796 789//789 795//795
            +f 788//788 795//795 789//789
            +f 797//797 790//790 796//796
            +f 789//789 796//796 790//790
            +f 791//791 792//792 798//798
            +f 799//799 798//798 792//792
            +f 793//793 791//791 800//800
            +f 798//798 800//800 791//791
            +f 794//794 793//793 801//801
            +f 800//800 801//801 793//793
            +f 802//802 795//795 794//794
            +f 794//794 801//801 802//802
            +f 803//803 796//796 802//802
            +f 795//795 802//802 796//796
            +f 804//804 797//797 803//803
            +f 796//796 803//803 797//797
            +f 798//798 799//799 805//805
            +f 806//806 805//805 799//799
            +f 800//800 798//798 807//807
            +f 805//805 807//807 798//798
            +f 801//801 800//800 808//808
            +f 807//807 808//808 800//800
            +f 809//809 802//802 801//801
            +f 801//801 808//808 809//809
            +f 810//810 803//803 809//809
            +f 802//802 809//809 803//803
            +f 811//811 804//804 810//810
            +f 803//803 810//810 804//804
            +f 805//805 806//806 812//812
            +f 813//813 812//812 806//806
            +f 807//807 805//805 814//814
            +f 812//812 814//814 805//805
            +f 815//815 808//808 814//814
            +f 807//807 814//814 808//808
            +f 816//816 809//809 815//815
            +f 808//808 815//815 809//809
            +f 817//817 810//810 816//816
            +f 809//809 816//816 810//810
            +f 818//818 811//811 817//817
            +f 810//810 817//817 811//811
            +f 819//819 820//820 812//812
            +f 812//812 813//813 819//819
            +f 820//820 821//821 814//814
            +f 814//814 812//812 820//820
            +f 822//822 815//815 814//814
            +f 814//814 821//821 822//822
            +f 823//823 816//816 815//815
            +f 815//815 822//822 823//823
            +f 824//824 817//817 816//816
            +f 816//816 823//823 824//824
            +f 825//825 818//818 817//817
            +f 817//817 824//824 825//825
            +f 826//826 827//827 820//820
            +f 820//820 819//819 826//826
            +f 827//827 828//828 821//821
            +f 821//821 820//820 827//827
            +f 828//828 829//829 822//822
            +f 822//822 821//821 828//828
            +f 830//830 823//823 829//829
            +f 822//822 829//829 823//823
            +f 831//831 824//824 823//823
            +f 823//823 830//830 831//831
            +f 832//832 825//825 824//824
            +f 824//824 831//831 832//832
            +f 833//833 834//834 827//827
            +f 827//827 826//826 833//833
            +f 834//834 835//835 828//828
            +f 828//828 827//827 834//834
            +f 835//835 836//836 829//829
            +f 829//829 828//828 835//835
            +f 837//837 830//830 836//836
            +f 829//829 836//836 830//830
            +f 838//838 831//831 830//830
            +f 830//830 837//837 838//838
            +f 839//839 832//832 831//831
            +f 831//831 838//838 839//839
            +f 840//840 841//841 834//834
            +f 834//834 833//833 840//840
            +f 841//841 842//842 835//835
            +f 835//835 834//834 841//841
            +f 842//842 843//843 836//836
            +f 836//836 835//835 842//842
            +f 844//844 837//837 843//843
            +f 836//836 843//843 837//837
            +f 845//845 838//838 837//837
            +f 837//837 844//844 845//845
            +f 846//846 839//839 838//838
            +f 838//838 845//845 846//846
            +f 847//847 848//848 841//841
            +f 841//841 840//840 847//847
            +f 848//848 849//849 842//842
            +f 842//842 841//841 848//848
            +f 849//849 850//850 843//843
            +f 843//843 842//842 849//849
            +f 851//851 844//844 850//850
            +f 843//843 850//850 844//844
            +f 852//852 845//845 844//844
            +f 844//844 851//851 852//852
            +f 853//853 846//846 845//845
            +f 845//845 852//852 853//853
            +f 771//771 770//770 848//848
            +f 848//848 847//847 771//771
            +f 770//770 774//774 849//849
            +f 849//849 848//848 770//770
            +f 777//777 850//850 774//774
            +f 849//849 774//774 850//850
            +f 779//779 851//851 850//850
            +f 850//850 777//777 779//779
            +f 781//781 852//852 851//851
            +f 851//851 779//779 781//781
            +f 783//783 853//853 852//852
            +f 852//852 781//781 783//783
            +f 854//854 855//855 782//782
            +f 783//783 782//782 855//855
            +f 856//856 857//857 855//855
            +f 855//855 854//854 856//856
            +f 858//858 859//859 857//857
            +f 857//857 856//856 858//858
            +f 860//860 861//861 859//859
            +f 859//859 858//858 860//860
            +f 862//862 863//863 861//861
            +f 861//861 860//860 862//862
            +f 864//864 865//865 863//863
            +f 863//863 862//862 864//864
            +f 866//866 854//854 782//782
            +f 782//782 790//790 866//866
            +f 867//867 856//856 854//854
            +f 854//854 866//866 867//867
            +f 868//868 858//858 856//856
            +f 856//856 867//867 868//868
            +f 869//869 860//860 858//858
            +f 858//858 868//868 869//869
            +f 870//870 862//862 860//860
            +f 860//860 869//869 870//870
            +f 871//871 864//864 870//870
            +f 862//862 870//870 864//864
            +f 872//872 866//866 790//790
            +f 790//790 797//797 872//872
            +f 873//873 867//867 866//866
            +f 866//866 872//872 873//873
            +f 874//874 868//868 867//867
            +f 867//867 873//873 874//874
            +f 875//875 869//869 874//874
            +f 868//868 874//874 869//869
            +f 876//876 870//870 875//875
            +f 869//869 875//875 870//870
            +f 877//877 871//871 876//876
            +f 870//870 876//876 871//871
            +f 878//878 872//872 797//797
            +f 797//797 804//804 878//878
            +f 879//879 873//873 872//872
            +f 872//872 878//878 879//879
            +f 880//880 874//874 873//873
            +f 873//873 879//879 880//880
            +f 881//881 875//875 880//880
            +f 874//874 880//880 875//875
            +f 882//882 876//876 881//881
            +f 875//875 881//881 876//876
            +f 883//883 877//877 882//882
            +f 876//876 882//882 877//877
            +f 884//884 878//878 804//804
            +f 804//804 811//811 884//884
            +f 885//885 879//879 878//878
            +f 878//878 884//884 885//885
            +f 886//886 880//880 879//879
            +f 879//879 885//885 886//886
            +f 887//887 881//881 880//880
            +f 880//880 886//886 887//887
            +f 888//888 882//882 881//881
            +f 881//881 887//887 888//888
            +f 889//889 883//883 888//888
            +f 882//882 888//888 883//883
            +f 890//890 884//884 811//811
            +f 811//811 818//818 890//890
            +f 891//891 885//885 884//884
            +f 884//884 890//890 891//891
            +f 892//892 886//886 885//885
            +f 885//885 891//891 892//892
            +f 893//893 887//887 886//886
            +f 886//886 892//892 893//893
            +f 894//894 888//888 887//887
            +f 887//887 893//893 894//894
            +f 895//895 889//889 888//888
            +f 888//888 894//894 895//895
            +f 896//896 890//890 825//825
            +f 818//818 825//825 890//890
            +f 897//897 891//891 896//896
            +f 890//890 896//896 891//891
            +f 898//898 892//892 897//897
            +f 891//891 897//897 892//892
            +f 899//899 893//893 898//898
            +f 892//892 898//898 893//893
            +f 900//900 894//894 899//899
            +f 893//893 899//899 894//894
            +f 901//901 895//895 900//900
            +f 894//894 900//900 895//895
            +f 902//902 896//896 832//832
            +f 825//825 832//832 896//896
            +f 903//903 897//897 902//902
            +f 896//896 902//902 897//897
            +f 904//904 898//898 903//903
            +f 897//897 903//903 898//898
            +f 905//905 899//899 904//904
            +f 898//898 904//904 899//899
            +f 906//906 900//900 905//905
            +f 899//899 905//905 900//900
            +f 907//907 901//901 900//900
            +f 900//900 906//906 907//907
            +f 908//908 902//902 839//839
            +f 832//832 839//839 902//902
            +f 909//909 903//903 908//908
            +f 902//902 908//908 903//903
            +f 910//910 904//904 909//909
            +f 903//903 909//909 904//904
            +f 911//911 905//905 904//904
            +f 904//904 910//910 911//911
            +f 912//912 906//906 905//905
            +f 905//905 911//911 912//912
            +f 913//913 907//907 906//906
            +f 906//906 912//912 913//913
            +f 914//914 908//908 846//846
            +f 839//839 846//846 908//908
            +f 915//915 909//909 914//914
            +f 908//908 914//914 909//909
            +f 916//916 910//910 915//915
            +f 909//909 915//915 910//910
            +f 917//917 911//911 910//910
            +f 910//910 916//916 917//917
            +f 918//918 912//912 911//911
            +f 911//911 917//917 918//918
            +f 919//919 913//913 912//912
            +f 912//912 918//918 919//919
            +f 920//920 914//914 853//853
            +f 846//846 853//853 914//914
            +f 921//921 915//915 920//920
            +f 914//914 920//920 915//915
            +f 922//922 916//916 921//921
            +f 915//915 921//921 916//916
            +f 923//923 917//917 922//922
            +f 916//916 922//922 917//917
            +f 924//924 918//918 923//923
            +f 917//917 923//923 918//918
            +f 925//925 919//919 918//918
            +f 918//918 924//924 925//925
            +f 855//855 920//920 853//853
            +f 853//853 783//783 855//855
            +f 857//857 921//921 855//855
            +f 920//920 855//855 921//921
            +f 859//859 922//922 857//857
            +f 921//921 857//857 922//922
            +f 861//861 923//923 859//859
            +f 922//922 859//859 923//923
            +f 863//863 924//924 861//861
            +f 923//923 861//861 924//924
            +f 865//865 925//925 863//863
            +f 924//924 863//863 925//925
            +f 926//926 927//927 928//928
            +f 928//928 929//929 926//926
            +f 929//929 928//928 930//930
            +f 930//930 931//931 929//929
            +f 931//931 930//930 932//932
            +f 932//932 933//933 931//931
            +f 933//933 932//932 934//934
            +f 934//934 935//935 933//933
            +f 935//935 934//934 936//936
            +f 936//936 937//937 935//935
            +f 937//937 936//936 938//938
            +f 939//939 938//938 936//936
            +f 940//940 941//941 927//927
            +f 928//928 927//927 941//941
            +f 928//928 941//941 942//942
            +f 942//942 930//930 928//928
            +f 930//930 942//942 943//943
            +f 943//943 932//932 930//930
            +f 932//932 943//943 944//944
            +f 944//944 934//934 932//932
            +f 934//934 944//944 936//936
            +f 945//945 936//936 944//944
            +f 936//936 945//945 939//939
            +f 946//946 939//939 945//945
            +f 947//947 948//948 940//940
            +f 941//941 940//940 948//948
            +f 941//941 948//948 949//949
            +f 949//949 942//942 941//941
            +f 942//942 949//949 943//943
            +f 950//950 943//943 949//949
            +f 943//943 950//950 944//944
            +f 951//951 944//944 950//950
            +f 944//944 951//951 945//945
            +f 952//952 945//945 951//951
            +f 945//945 952//952 946//946
            +f 953//953 946//946 952//952
            +f 954//954 955//955 947//947
            +f 948//948 947//947 955//955
            +f 948//948 955//955 956//956
            +f 956//956 949//949 948//948
            +f 949//949 956//956 950//950
            +f 957//957 950//950 956//956
            +f 950//950 957//957 951//951
            +f 958//958 951//951 957//957
            +f 951//951 958//958 952//952
            +f 959//959 952//952 958//958
            +f 952//952 959//959 953//953
            +f 960//960 953//953 959//959
            +f 954//954 961//961 962//962
            +f 962//962 955//955 954//954
            +f 955//955 962//962 956//956
            +f 963//963 956//956 962//962
            +f 956//956 963//963 957//957
            +f 964//964 957//957 963//963
            +f 957//957 964//964 958//958
            +f 965//965 958//958 964//964
            +f 958//958 965//965 959//959
            +f 966//966 959//959 965//965
            +f 959//959 966//966 960//960
            +f 967//967 960//960 966//966
            +f 961//961 968//968 962//962
            +f 969//969 962//962 968//968
            +f 962//962 969//969 963//963
            +f 970//970 963//963 969//969
            +f 963//963 970//970 964//964
            +f 971//971 964//964 970//970
            +f 964//964 971//971 965//965
            +f 972//972 965//965 971//971
            +f 965//965 972//972 966//966
            +f 973//973 966//966 972//972
            +f 966//966 973//973 967//967
            +f 974//974 967//967 973//973
            +f 968//968 975//975 976//976
            +f 976//976 969//969 968//968
            +f 969//969 976//976 977//977
            +f 977//977 970//970 969//969
            +f 970//970 977//977 978//978
            +f 978//978 971//971 970//970
            +f 971//971 978//978 979//979
            +f 979//979 972//972 971//971
            +f 972//972 979//979 980//980
            +f 980//980 973//973 972//972
            +f 973//973 980//980 981//981
            +f 981//981 974//974 973//973
            +f 975//975 982//982 976//976
            +f 983//983 976//976 982//982
            +f 976//976 983//983 984//984
            +f 984//984 977//977 976//976
            +f 977//977 984//984 985//985
            +f 985//985 978//978 977//977
            +f 978//978 985//985 986//986
            +f 986//986 979//979 978//978
            +f 979//979 986//986 987//987
            +f 987//987 980//980 979//979
            +f 980//980 987//987 988//988
            +f 988//988 981//981 980//980
            +f 983//983 982//982 989//989
            +f 989//989 990//990 983//983
            +f 983//983 990//990 984//984
            +f 991//991 984//984 990//990
            +f 984//984 991//991 992//992
            +f 992//992 985//985 984//984
            +f 985//985 992//992 993//993
            +f 993//993 986//986 985//985
            +f 986//986 993//993 994//994
            +f 994//994 987//987 986//986
            +f 987//987 994//994 995//995
            +f 995//995 988//988 987//987
            +f 990//990 989//989 996//996
            +f 996//996 997//997 990//990
            +f 990//990 997//997 991//991
            +f 998//998 991//991 997//997
            +f 991//991 998//998 999//999
            +f 999//999 992//992 991//991
            +f 992//992 999//999 1000//1000
            +f 1000//1000 993//993 992//992
            +f 993//993 1000//1000 1001//1001
            +f 1001//1001 994//994 993//993
            +f 994//994 1001//1001 1002//1002
            +f 1002//1002 995//995 994//994
            +f 997//997 996//996 1003//1003
            +f 1003//1003 1004//1004 997//997
            +f 997//997 1004//1004 998//998
            +f 1005//1005 998//998 1004//1004
            +f 998//998 1005//1005 999//999
            +f 1006//1006 999//999 1005//1005
            +f 999//999 1006//1006 1000//1000
            +f 1007//1007 1000//1000 1006//1006
            +f 1000//1000 1007//1007 1008//1008
            +f 1008//1008 1001//1001 1000//1000
            +f 1001//1001 1008//1008 1009//1009
            +f 1009//1009 1002//1002 1001//1001
            +f 1003//1003 926//926 1004//1004
            +f 929//929 1004//1004 926//926
            +f 1004//1004 929//929 1005//1005
            +f 931//931 1005//1005 929//929
            +f 1005//1005 931//931 1006//1006
            +f 933//933 1006//1006 931//931
            +f 1006//1006 933//933 1007//1007
            +f 935//935 1007//1007 933//933
            +f 1007//1007 935//935 1008//1008
            +f 937//937 1008//1008 935//935
            +f 1008//1008 937//937 938//938
            +f 938//938 1009//1009 1008//1008
            +f 938//938 939//939 1010//1010
            +f 1011//1011 1010//1010 939//939
            +f 1010//1010 1011//1011 1012//1012
            +f 1013//1013 1012//1012 1011//1011
            +f 1012//1012 1013//1013 1014//1014
            +f 1015//1015 1014//1014 1013//1013
            +f 1016//1016 1017//1017 1014//1014
            +f 1014//1014 1015//1015 1016//1016
            +f 1018//1018 1019//1019 1017//1017
            +f 1017//1017 1016//1016 1018//1018
            +f 1020//1020 1021//1021 1019//1019
            +f 1019//1019 1018//1018 1020//1020
            +f 939//939 946//946 1011//1011
            +f 1022//1022 1011//1011 946//946
            +f 1011//1011 1022//1022 1013//1013
            +f 1023//1023 1013//1013 1022//1022
            +f 1013//1013 1023//1023 1015//1015
            +f 1024//1024 1015//1015 1023//1023
            +f 1025//1025 1016//1016 1015//1015
            +f 1015//1015 1024//1024 1025//1025
            +f 1026//1026 1018//1018 1016//1016
            +f 1016//1016 1025//1025 1026//1026
            +f 1027//1027 1020//1020 1018//1018
            +f 1018//1018 1026//1026 1027//1027
            +f 946//946 953//953 1022//1022
            +f 1028//1028 1022//1022 953//953
            +f 1022//1022 1028//1028 1023//1023
            +f 1029//1029 1023//1023 1028//1028
            +f 1023//1023 1029//1029 1024//1024
            +f 1030//1030 1024//1024 1029//1029
            +f 1031//1031 1025//1025 1024//1024
            +f 1024//1024 1030//1030 1031//1031
            +f 1032//1032 1026//1026 1025//1025
            +f 1025//1025 1031//1031 1032//1032
            +f 1033//1033 1027//1027 1026//1026
            +f 1026//1026 1032//1032 1033//1033
            +f 953//953 960//960 1028//1028
            +f 1034//1034 1028//1028 960//960
            +f 1028//1028 1034//1034 1029//1029
            +f 1035//1035 1029//1029 1034//1034
            +f 1029//1029 1035//1035 1030//1030
            +f 1036//1036 1030//1030 1035//1035
            +f 1037//1037 1031//1031 1030//1030
            +f 1030//1030 1036//1036 1037//1037
            +f 1038//1038 1032//1032 1031//1031
            +f 1031//1031 1037//1037 1038//1038
            +f 1039//1039 1033//1033 1032//1032
            +f 1032//1032 1038//1038 1039//1039
            +f 960//960 967//967 1034//1034
            +f 1040//1040 1034//1034 967//967
            +f 1034//1034 1040//1040 1035//1035
            +f 1041//1041 1035//1035 1040//1040
            +f 1035//1035 1041//1041 1036//1036
            +f 1042//1042 1036//1036 1041//1041
            +f 1043//1043 1037//1037 1036//1036
            +f 1036//1036 1042//1042 1043//1043
            +f 1044//1044 1038//1038 1037//1037
            +f 1037//1037 1043//1043 1044//1044
            +f 1045//1045 1039//1039 1038//1038
            +f 1038//1038 1044//1044 1045//1045
            +f 967//967 974//974 1040//1040
            +f 1046//1046 1040//1040 974//974
            +f 1040//1040 1046//1046 1041//1041
            +f 1047//1047 1041//1041 1046//1046
            +f 1041//1041 1047//1047 1042//1042
            +f 1048//1048 1042//1042 1047//1047
            +f 1049//1049 1043//1043 1042//1042
            +f 1042//1042 1048//1048 1049//1049
            +f 1050//1050 1044//1044 1043//1043
            +f 1043//1043 1049//1049 1050//1050
            +f 1051//1051 1045//1045 1044//1044
            +f 1044//1044 1050//1050 1051//1051
            +f 974//974 981//981 1052//1052
            +f 1052//1052 1046//1046 974//974
            +f 1046//1046 1052//1052 1053//1053
            +f 1053//1053 1047//1047 1046//1046
            +f 1047//1047 1053//1053 1054//1054
            +f 1054//1054 1048//1048 1047//1047
            +f 1055//1055 1049//1049 1054//1054
            +f 1048//1048 1054//1054 1049//1049
            +f 1056//1056 1050//1050 1055//1055
            +f 1049//1049 1055//1055 1050//1050
            +f 1057//1057 1051//1051 1056//1056
            +f 1050//1050 1056//1056 1051//1051
            +f 981//981 988//988 1058//1058
            +f 1058//1058 1052//1052 981//981
            +f 1052//1052 1058//1058 1059//1059
            +f 1059//1059 1053//1053 1052//1052
            +f 1053//1053 1059//1059 1060//1060
            +f 1060//1060 1054//1054 1053//1053
            +f 1061//1061 1055//1055 1060//1060
            +f 1054//1054 1060//1060 1055//1055
            +f 1062//1062 1056//1056 1061//1061
            +f 1055//1055 1061//1061 1056//1056
            +f 1063//1063 1057//1057 1062//1062
            +f 1056//1056 1062//1062 1057//1057
            +f 988//988 995//995 1064//1064
            +f 1064//1064 1058//1058 988//988
            +f 1058//1058 1064//1064 1065//1065
            +f 1065//1065 1059//1059 1058//1058
            +f 1059//1059 1065//1065 1066//1066
            +f 1066//1066 1060//1060 1059//1059
            +f 1067//1067 1061//1061 1066//1066
            +f 1060//1060 1066//1066 1061//1061
            +f 1068//1068 1062//1062 1067//1067
            +f 1061//1061 1067//1067 1062//1062
            +f 1069//1069 1063//1063 1068//1068
            +f 1062//1062 1068//1068 1063//1063
            +f 995//995 1002//1002 1070//1070
            +f 1070//1070 1064//1064 995//995
            +f 1064//1064 1070//1070 1071//1071
            +f 1071//1071 1065//1065 1064//1064
            +f 1065//1065 1071//1071 1072//1072
            +f 1072//1072 1066//1066 1065//1065
            +f 1073//1073 1067//1067 1072//1072
            +f 1066//1066 1072//1072 1067//1067
            +f 1074//1074 1068//1068 1073//1073
            +f 1067//1067 1073//1073 1068//1068
            +f 1075//1075 1069//1069 1074//1074
            +f 1068//1068 1074//1074 1069//1069
            +f 1002//1002 1009//1009 1076//1076
            +f 1076//1076 1070//1070 1002//1002
            +f 1070//1070 1076//1076 1077//1077
            +f 1077//1077 1071//1071 1070//1070
            +f 1071//1071 1077//1077 1078//1078
            +f 1078//1078 1072//1072 1071//1071
            +f 1079//1079 1073//1073 1078//1078
            +f 1072//1072 1078//1078 1073//1073
            +f 1080//1080 1074//1074 1079//1079
            +f 1073//1073 1079//1079 1074//1074
            +f 1081//1081 1075//1075 1080//1080
            +f 1074//1074 1080//1080 1075//1075
            +f 1009//1009 938//938 1010//1010
            +f 1010//1010 1076//1076 1009//1009
            +f 1076//1076 1010//1010 1012//1012
            +f 1012//1012 1077//1077 1076//1076
            +f 1077//1077 1012//1012 1014//1014
            +f 1014//1014 1078//1078 1077//1077
            +f 1017//1017 1079//1079 1014//1014
            +f 1078//1078 1014//1014 1079//1079
            +f 1019//1019 1080//1080 1017//1017
            +f 1079//1079 1017//1017 1080//1080
            +f 1021//1021 1081//1081 1019//1019
            +f 1080//1080 1019//1019 1081//1081
            +f 1082//1082 1083//1083 1084//1084
            +f 1084//1084 1083//1083 1085//1085
            +f 1085//1085 1083//1083 1086//1086
            +f 1086//1086 1083//1083 1087//1087
            +f 1087//1087 1083//1083 1088//1088
            +f 1088//1088 1083//1083 1089//1089
            +f 1089//1089 1083//1083 1090//1090
            +f 1090//1090 1083//1083 1091//1091
            +f 1091//1091 1083//1083 1092//1092
            +f 1092//1092 1083//1083 1093//1093
            +f 1093//1093 1083//1083 1094//1094
            +f 1094//1094 1083//1083 1095//1095
            +f 1095//1095 1083//1083 1096//1096
            +f 1096//1096 1083//1083 1097//1097
            +f 1097//1097 1083//1083 1098//1098
            +f 1098//1098 1083//1083 1099//1099
            +f 1099//1099 1083//1083 1100//1100
            +f 1100//1100 1083//1083 1101//1101
            +f 1101//1101 1083//1083 1102//1102
            +f 1102//1102 1083//1083 1103//1103
            +f 1103//1103 1083//1083 1104//1104
            +f 1104//1104 1083//1083 1105//1105
            +f 1105//1105 1083//1083 1106//1106
            +f 1106//1106 1083//1083 1082//1082
            +f 1107//1107 1108//1108 1084//1084
            +f 1082//1082 1084//1084 1108//1108
            +f 1109//1109 1110//1110 1108//1108
            +f 1108//1108 1107//1107 1109//1109
            +f 1111//1111 1112//1112 1110//1110
            +f 1110//1110 1109//1109 1111//1111
            +f 1113//1113 1114//1114 1112//1112
            +f 1112//1112 1111//1111 1113//1113
            +f 1115//1115 1107//1107 1085//1085
            +f 1084//1084 1085//1085 1107//1107
            +f 1116//1116 1109//1109 1107//1107
            +f 1107//1107 1115//1115 1116//1116
            +f 1117//1117 1111//1111 1109//1109
            +f 1109//1109 1116//1116 1117//1117
            +f 1118//1118 1113//1113 1111//1111
            +f 1111//1111 1117//1117 1118//1118
            +f 1119//1119 1115//1115 1086//1086
            +f 1085//1085 1086//1086 1115//1115
            +f 1120//1120 1116//1116 1115//1115
            +f 1115//1115 1119//1119 1120//1120
            +f 1121//1121 1117//1117 1116//1116
            +f 1116//1116 1120//1120 1121//1121
            +f 1122//1122 1118//1118 1117//1117
            +f 1117//1117 1121//1121 1122//1122
            +f 1123//1123 1119//1119 1086//1086
            +f 1086//1086 1087//1087 1123//1123
            +f 1124//1124 1120//1120 1123//1123
            +f 1119//1119 1123//1123 1120//1120
            +f 1125//1125 1121//1121 1124//1124
            +f 1120//1120 1124//1124 1121//1121
            +f 1126//1126 1122//1122 1125//1125
            +f 1121//1121 1125//1125 1122//1122
            +f 1127//1127 1123//1123 1087//1087
            +f 1087//1087 1088//1088 1127//1127
            +f 1128//1128 1124//1124 1127//1127
            +f 1123//1123 1127//1127 1124//1124
            +f 1129//1129 1125//1125 1128//1128
            +f 1124//1124 1128//1128 1125//1125
            +f 1130//1130 1126//1126 1129//1129
            +f 1125//1125 1129//1129 1126//1126
            +f 1131//1131 1127//1127 1088//1088
            +f 1088//1088 1089//1089 1131//1131
            +f 1132//1132 1128//1128 1131//1131
            +f 1127//1127 1131//1131 1128//1128
            +f 1133//1133 1129//1129 1132//1132
            +f 1128//1128 1132//1132 1129//1129
            +f 1134//1134 1130//1130 1133//1133
            +f 1129//1129 1133//1133 1130//1130
            +f 1135//1135 1131//1131 1090//1090
            +f 1089//1089 1090//1090 1131//1131
            +f 1136//1136 1132//1132 1131//1131
            +f 1131//1131 1135//1135 1136//1136
            +f 1137//1137 1133//1133 1132//1132
            +f 1132//1132 1136//1136 1137//1137
            +f 1138//1138 1134//1134 1133//1133
            +f 1133//1133 1137//1137 1138//1138
            +f 1139//1139 1135//1135 1091//1091
            +f 1090//1090 1091//1091 1135//1135
            +f 1140//1140 1136//1136 1135//1135
            +f 1135//1135 1139//1139 1140//1140
            +f 1141//1141 1137//1137 1136//1136
            +f 1136//1136 1140//1140 1141//1141
            +f 1142//1142 1138//1138 1137//1137
            +f 1137//1137 1141//1141 1142//1142
            +f 1143//1143 1139//1139 1092//1092
            +f 1091//1091 1092//1092 1139//1139
            +f 1144//1144 1140//1140 1139//1139
            +f 1139//1139 1143//1143 1144//1144
            +f 1145//1145 1141//1141 1140//1140
            +f 1140//1140 1144//1144 1145//1145
            +f 1146//1146 1142//1142 1141//1141
            +f 1141//1141 1145//1145 1146//1146
            +f 1147//1147 1143//1143 1092//1092
            +f 1092//1092 1093//1093 1147//1147
            +f 1148//1148 1144//1144 1147//1147
            +f 1143//1143 1147//1147 1144//1144
            +f 1149//1149 1145//1145 1148//1148
            +f 1144//1144 1148//1148 1145//1145
            +f 1150//1150 1146//1146 1149//1149
            +f 1145//1145 1149//1149 1146//1146
            +f 1151//1151 1147//1147 1093//1093
            +f 1093//1093 1094//1094 1151//1151
            +f 1152//1152 1148//1148 1151//1151
            +f 1147//1147 1151//1151 1148//1148
            +f 1153//1153 1149//1149 1152//1152
            +f 1148//1148 1152//1152 1149//1149
            +f 1154//1154 1150//1150 1153//1153
            +f 1149//1149 1153//1153 1150//1150
            +f 1155//1155 1151//1151 1094//1094
            +f 1094//1094 1095//1095 1155//1155
            +f 1156//1156 1152//1152 1155//1155
            +f 1151//1151 1155//1155 1152//1152
            +f 1157//1157 1153//1153 1156//1156
            +f 1152//1152 1156//1156 1153//1153
            +f 1158//1158 1154//1154 1157//1157
            +f 1153//1153 1157//1157 1154//1154
            +f 1159//1159 1155//1155 1096//1096
            +f 1095//1095 1096//1096 1155//1155
            +f 1160//1160 1156//1156 1155//1155
            +f 1155//1155 1159//1159 1160//1160
            +f 1161//1161 1157//1157 1156//1156
            +f 1156//1156 1160//1160 1161//1161
            +f 1162//1162 1158//1158 1157//1157
            +f 1157//1157 1161//1161 1162//1162
            +f 1163//1163 1159//1159 1097//1097
            +f 1096//1096 1097//1097 1159//1159
            +f 1164//1164 1160//1160 1159//1159
            +f 1159//1159 1163//1163 1164//1164
            +f 1165//1165 1161//1161 1160//1160
            +f 1160//1160 1164//1164 1165//1165
            +f 1166//1166 1162//1162 1161//1161
            +f 1161//1161 1165//1165 1166//1166
            +f 1167//1167 1163//1163 1098//1098
            +f 1097//1097 1098//1098 1163//1163
            +f 1168//1168 1164//1164 1163//1163
            +f 1163//1163 1167//1167 1168//1168
            +f 1169//1169 1165//1165 1164//1164
            +f 1164//1164 1168//1168 1169//1169
            +f 1170//1170 1166//1166 1165//1165
            +f 1165//1165 1169//1169 1170//1170
            +f 1171//1171 1167//1167 1098//1098
            +f 1098//1098 1099//1099 1171//1171
            +f 1172//1172 1168//1168 1171//1171
            +f 1167//1167 1171//1171 1168//1168
            +f 1173//1173 1169//1169 1172//1172
            +f 1168//1168 1172//1172 1169//1169
            +f 1174//1174 1170//1170 1173//1173
            +f 1169//1169 1173//1173 1170//1170
            +f 1175//1175 1171//1171 1099//1099
            +f 1099//1099 1100//1100 1175//1175
            +f 1176//1176 1172//1172 1175//1175
            +f 1171//1171 1175//1175 1172//1172
            +f 1177//1177 1173//1173 1176//1176
            +f 1172//1172 1176//1176 1173//1173
            +f 1178//1178 1174//1174 1177//1177
            +f 1173//1173 1177//1177 1174//1174
            +f 1179//1179 1175//1175 1100//1100
            +f 1100//1100 1101//1101 1179//1179
            +f 1180//1180 1176//1176 1179//1179
            +f 1175//1175 1179//1179 1176//1176
            +f 1181//1181 1177//1177 1180//1180
            +f 1176//1176 1180//1180 1177//1177
            +f 1182//1182 1178//1178 1181//1181
            +f 1177//1177 1181//1181 1178//1178
            +f 1183//1183 1179//1179 1102//1102
            +f 1101//1101 1102//1102 1179//1179
            +f 1184//1184 1180//1180 1179//1179
            +f 1179//1179 1183//1183 1184//1184
            +f 1185//1185 1181//1181 1180//1180
            +f 1180//1180 1184//1184 1185//1185
            +f 1186//1186 1182//1182 1181//1181
            +f 1181//1181 1185//1185 1186//1186
            +f 1187//1187 1183//1183 1103//1103
            +f 1102//1102 1103//1103 1183//1183
            +f 1188//1188 1184//1184 1183//1183
            +f 1183//1183 1187//1187 1188//1188
            +f 1189//1189 1185//1185 1184//1184
            +f 1184//1184 1188//1188 1189//1189
            +f 1190//1190 1186//1186 1185//1185
            +f 1185//1185 1189//1189 1190//1190
            +f 1191//1191 1187//1187 1104//1104
            +f 1103//1103 1104//1104 1187//1187
            +f 1192//1192 1188//1188 1187//1187
            +f 1187//1187 1191//1191 1192//1192
            +f 1193//1193 1189//1189 1188//1188
            +f 1188//1188 1192//1192 1193//1193
            +f 1194//1194 1190//1190 1189//1189
            +f 1189//1189 1193//1193 1194//1194
            +f 1195//1195 1191//1191 1104//1104
            +f 1104//1104 1105//1105 1195//1195
            +f 1196//1196 1192//1192 1195//1195
            +f 1191//1191 1195//1195 1192//1192
            +f 1197//1197 1193//1193 1196//1196
            +f 1192//1192 1196//1196 1193//1193
            +f 1198//1198 1194//1194 1197//1197
            +f 1193//1193 1197//1197 1194//1194
            +f 1199//1199 1195//1195 1105//1105
            +f 1105//1105 1106//1106 1199//1199
            +f 1200//1200 1196//1196 1199//1199
            +f 1195//1195 1199//1199 1196//1196
            +f 1201//1201 1197//1197 1200//1200
            +f 1196//1196 1200//1200 1197//1197
            +f 1202//1202 1198//1198 1201//1201
            +f 1197//1197 1201//1201 1198//1198
            +f 1108//1108 1199//1199 1106//1106
            +f 1106//1106 1082//1082 1108//1108
            +f 1110//1110 1200//1200 1108//1108
            +f 1199//1199 1108//1108 1200//1200
            +f 1112//1112 1201//1201 1110//1110
            +f 1200//1200 1110//1110 1201//1201
            +f 1114//1114 1202//1202 1112//1112
            +f 1201//1201 1112//1112 1202//1202
            diff --git a/dist/reference/assets/test.txt b/dist/reference/assets/test.txt
            new file mode 100644
            index 0000000000..9dc2445af3
            --- /dev/null
            +++ b/dist/reference/assets/test.txt
            @@ -0,0 +1,6 @@
            +I am a cat
            +I like apples
            +I have three feet
            +I like my nose
            +I smell like butter
            +I talk like an orange
            \ No newline at end of file
            diff --git a/dist/reference/assets/transformation-matrix.png b/dist/reference/assets/transformation-matrix.png
            new file mode 100644
            index 0000000000..0d42542922
            Binary files /dev/null and b/dist/reference/assets/transformation-matrix.png differ
            diff --git a/dist/reference/data.json b/dist/reference/data.json
            new file mode 100644
            index 0000000000..16f3ad430e
            --- /dev/null
            +++ b/dist/reference/data.json
            @@ -0,0 +1,30598 @@
            +{
            +    "project": {
            +        "name": "p5",
            +        "description": "[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)",
            +        "version": "1.4.1",
            +        "url": "https://github.com/processing/p5.js#readme"
            +    },
            +    "files": {
            +        "src/accessibility/color_namer.js": {
            +            "name": "src/accessibility/color_namer.js",
            +            "modules": {
            +                "Environment": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/describe.js": {
            +            "name": "src/accessibility/describe.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/gridOutput.js": {
            +            "name": "src/accessibility/gridOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/outputs.js": {
            +            "name": "src/accessibility/outputs.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/textOutput.js": {
            +            "name": "src/accessibility/textOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/color_conversion.js": {
            +            "name": "src/color/color_conversion.js",
            +            "modules": {
            +                "Color Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/creating_reading.js": {
            +            "name": "src/color/creating_reading.js",
            +            "modules": {
            +                "Creating & Reading": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/p5.Color.js": {
            +            "name": "src/color/p5.Color.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/setting.js": {
            +            "name": "src/color/setting.js",
            +            "modules": {
            +                "Setting": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/fes_core.js": {
            +            "name": "src/core/friendly_errors/fes_core.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/file_errors.js": {
            +            "name": "src/core/friendly_errors/file_errors.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/sketch_reader.js": {
            +            "name": "src/core/friendly_errors/sketch_reader.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/stacktrace.js": {
            +            "name": "src/core/friendly_errors/stacktrace.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/validate_params.js": {
            +            "name": "src/core/friendly_errors/validate_params.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/2d_primitives.js": {
            +            "name": "src/core/shape/2d_primitives.js",
            +            "modules": {
            +                "2D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/attributes.js": {
            +            "name": "src/core/shape/attributes.js",
            +            "modules": {
            +                "Attributes": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/curves.js": {
            +            "name": "src/core/shape/curves.js",
            +            "modules": {
            +                "Curves": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/vertex.js": {
            +            "name": "src/core/shape/vertex.js",
            +            "modules": {
            +                "Vertex": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/constants.js": {
            +            "name": "src/core/constants.js",
            +            "modules": {
            +                "Constants": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/environment.js": {
            +            "name": "src/core/environment.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/helpers.js": {
            +            "name": "src/core/helpers.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/init.js": {
            +            "name": "src/core/init.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/internationalization.js": {
            +            "name": "src/core/internationalization.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/legacy.js": {
            +            "name": "src/core/legacy.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/main.js": {
            +            "name": "src/core/main.js",
            +            "modules": {
            +                "Structure": 1
            +            },
            +            "classes": {
            +                "p5": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Element.js": {
            +            "name": "src/core/p5.Element.js",
            +            "modules": {
            +                "DOM": 1
            +            },
            +            "classes": {
            +                "p5.Element": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Graphics.js": {
            +            "name": "src/core/p5.Graphics.js",
            +            "modules": {
            +                "Rendering": 1
            +            },
            +            "classes": {
            +                "p5.Graphics": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer.js": {
            +            "name": "src/core/p5.Renderer.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer2D.js": {
            +            "name": "src/core/p5.Renderer2D.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/reference.js": {
            +            "name": "src/core/reference.js",
            +            "modules": {
            +                "Foundation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/rendering.js": {
            +            "name": "src/core/rendering.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shim.js": {
            +            "name": "src/core/shim.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/structure.js": {
            +            "name": "src/core/structure.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/transform.js": {
            +            "name": "src/core/transform.js",
            +            "modules": {
            +                "Transform": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/local_storage.js": {
            +            "name": "src/data/local_storage.js",
            +            "modules": {
            +                "LocalStorage": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/p5.TypedDict.js": {
            +            "name": "src/data/p5.TypedDict.js",
            +            "modules": {
            +                "Dictionary": 1
            +            },
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/dom/dom.js": {
            +            "name": "src/dom/dom.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/acceleration.js": {
            +            "name": "src/events/acceleration.js",
            +            "modules": {
            +                "Acceleration": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/keyboard.js": {
            +            "name": "src/events/keyboard.js",
            +            "modules": {
            +                "Keyboard": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/mouse.js": {
            +            "name": "src/events/mouse.js",
            +            "modules": {
            +                "Mouse": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/touch.js": {
            +            "name": "src/events/touch.js",
            +            "modules": {
            +                "Touch": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/filters.js": {
            +            "name": "src/image/filters.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/image.js": {
            +            "name": "src/image/image.js",
            +            "modules": {
            +                "Image": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/loading_displaying.js": {
            +            "name": "src/image/loading_displaying.js",
            +            "modules": {
            +                "Loading & Displaying": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/p5.Image.js": {
            +            "name": "src/image/p5.Image.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/pixels.js": {
            +            "name": "src/image/pixels.js",
            +            "modules": {
            +                "Pixels": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/files.js": {
            +            "name": "src/io/files.js",
            +            "modules": {
            +                "Input": 1,
            +                "Output": 1
            +            },
            +            "classes": {
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/p5.Table.js": {
            +            "name": "src/io/p5.Table.js",
            +            "modules": {
            +                "Table": 1
            +            },
            +            "classes": {
            +                "p5.Table": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.TableRow.js": {
            +            "name": "src/io/p5.TableRow.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.XML.js": {
            +            "name": "src/io/p5.XML.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/calculation.js": {
            +            "name": "src/math/calculation.js",
            +            "modules": {
            +                "Calculation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/math.js": {
            +            "name": "src/math/math.js",
            +            "modules": {
            +                "Vector": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/noise.js": {
            +            "name": "src/math/noise.js",
            +            "modules": {
            +                "Noise": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/p5.Vector.js": {
            +            "name": "src/math/p5.Vector.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/random.js": {
            +            "name": "src/math/random.js",
            +            "modules": {
            +                "Random": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/trigonometry.js": {
            +            "name": "src/math/trigonometry.js",
            +            "modules": {
            +                "Trigonometry": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/attributes.js": {
            +            "name": "src/typography/attributes.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/loading_displaying.js": {
            +            "name": "src/typography/loading_displaying.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/p5.Font.js": {
            +            "name": "src/typography/p5.Font.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/utilities/array_functions.js": {
            +            "name": "src/utilities/array_functions.js",
            +            "modules": {
            +                "Array Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/conversion.js": {
            +            "name": "src/utilities/conversion.js",
            +            "modules": {
            +                "Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/string_functions.js": {
            +            "name": "src/utilities/string_functions.js",
            +            "modules": {
            +                "String Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/time_date.js": {
            +            "name": "src/utilities/time_date.js",
            +            "modules": {
            +                "Time & Date": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/3d_primitives.js": {
            +            "name": "src/webgl/3d_primitives.js",
            +            "modules": {
            +                "3D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/interaction.js": {
            +            "name": "src/webgl/interaction.js",
            +            "modules": {
            +                "Interaction": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/light.js": {
            +            "name": "src/webgl/light.js",
            +            "modules": {
            +                "Lights": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/loading.js": {
            +            "name": "src/webgl/loading.js",
            +            "modules": {
            +                "3D Models": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/material.js": {
            +            "name": "src/webgl/material.js",
            +            "modules": {
            +                "Material": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Camera.js": {
            +            "name": "src/webgl/p5.Camera.js",
            +            "modules": {
            +                "Camera": 1
            +            },
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Geometry.js": {
            +            "name": "src/webgl/p5.Geometry.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Matrix.js": {
            +            "name": "src/webgl/p5.Matrix.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Matrix": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RenderBuffer.js": {
            +            "name": "src/webgl/p5.RenderBuffer.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Immediate.js": {
            +            "name": "src/webgl/p5.RendererGL.Immediate.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Retained.js": {
            +            "name": "src/webgl/p5.RendererGL.Retained.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.js": {
            +            "name": "src/webgl/p5.RendererGL.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.RendererGL": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Shader.js": {
            +            "name": "src/webgl/p5.Shader.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Shader": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Texture.js": {
            +            "name": "src/webgl/p5.Texture.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/text.js": {
            +            "name": "src/webgl/text.js",
            +            "modules": {},
            +            "classes": {
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.js": {
            +            "name": "lib/addons/p5.sound.js",
            +            "modules": {
            +                "p5.sound": 1
            +            },
            +            "classes": {
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.min.js": {
            +            "name": "lib/addons/p5.sound.min.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        }
            +    },
            +    "modules": {
            +        "Environment": {
            +            "name": "Environment",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Environment",
            +            "file": "src/accessibility/color_namer.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Color": {
            +            "name": "Color",
            +            "submodules": {
            +                "Color Conversion": 1,
            +                "Creating & Reading": 1,
            +                "Setting": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/color/p5.Color.js",
            +            "line": 14
            +        },
            +        "Color Conversion": {
            +            "name": "Color Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/color_conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Creating & Reading": {
            +            "name": "Creating & Reading",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ],
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"
            +        },
            +        "Setting": {
            +            "name": "Setting",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/setting.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Shape": {
            +            "name": "Shape",
            +            "submodules": {
            +                "2D Primitives": 1,
            +                "Curves": 1,
            +                "Vertex": 1,
            +                "3D Primitives": 1,
            +                "3D Models": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1,
            +                "p5.Matrix": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/p5.Matrix.js",
            +            "line": 19
            +        },
            +        "2D Primitives": {
            +            "name": "2D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Attributes": {
            +            "name": "Attributes",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/core/shape/attributes.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Curves": {
            +            "name": "Curves",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/curves.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vertex": {
            +            "name": "Vertex",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Constants": {
            +            "name": "Constants",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Constants",
            +            "file": "src/core/constants.js",
            +            "line": 1
            +        },
            +        "Structure": {
            +            "name": "Structure",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "IO",
            +            "file": "src/core/main.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ]
            +        },
            +        "DOM": {
            +            "name": "DOM",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Element": 1,
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "DOM",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n",
            +            "requires": [
            +                "p5"
            +            ]
            +        },
            +        "Rendering": {
            +            "name": "Rendering",
            +            "submodules": {
            +                "undefined": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.RendererGL": 1,
            +                "p5.Graphics": 1,
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Rendering",
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 603,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"
            +        },
            +        "Foundation": {
            +            "name": "Foundation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {},
            +            "module": "Foundation",
            +            "file": "src/core/reference.js",
            +            "line": 1
            +        },
            +        "Transform": {
            +            "name": "Transform",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Transform",
            +            "file": "src/core/transform.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Data": {
            +            "name": "Data",
            +            "submodules": {
            +                "LocalStorage": 1,
            +                "Dictionary": 1,
            +                "Array Functions": 1,
            +                "Conversion": 1,
            +                "String Functions": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.TypedDict": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410
            +        },
            +        "LocalStorage": {
            +            "name": "LocalStorage",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/local_storage.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for working with local storage"
            +            ]
            +        },
            +        "Dictionary": {
            +            "name": "Dictionary",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."
            +            ],
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"
            +        },
            +        "Events": {
            +            "name": "Events",
            +            "submodules": {
            +                "Acceleration": 1,
            +                "Keyboard": 1,
            +                "Mouse": 1,
            +                "Touch": 1
            +            },
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "Acceleration": {
            +            "name": "Acceleration",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/acceleration.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Keyboard": {
            +            "name": "Keyboard",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/keyboard.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Mouse": {
            +            "name": "Mouse",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/mouse.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Touch": {
            +            "name": "Touch",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/touch.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Image": {
            +            "name": "Image",
            +            "submodules": {
            +                "Pixels": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Image",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"
            +        },
            +        "Loading & Displaying": {
            +            "name": "Loading & Displaying",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"
            +        },
            +        "Pixels": {
            +            "name": "Pixels",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Image",
            +            "namespace": "",
            +            "file": "src/image/pixels.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "IO": {
            +            "name": "IO",
            +            "submodules": {
            +                "Structure": 1,
            +                "Input": 1,
            +                "Output": 1,
            +                "Table": 1,
            +                "Time & Date": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1,
            +                "p5.Table": 1,
            +                "p5.TableRow": 1,
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/io/p5.XML.js",
            +            "line": 9
            +        },
            +        "Input": {
            +            "name": "Input",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"
            +        },
            +        "Output": {
            +            "name": "Output",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"
            +        },
            +        "Table": {
            +            "name": "Table",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Table": 1,
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"
            +        },
            +        "Math": {
            +            "name": "Math",
            +            "submodules": {
            +                "Calculation": 1,
            +                "Vector": 1,
            +                "Noise": 1,
            +                "Random": 1,
            +                "Trigonometry": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10
            +        },
            +        "Calculation": {
            +            "name": "Calculation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/calculation.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vector": {
            +            "name": "Vector",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"
            +        },
            +        "Noise": {
            +            "name": "Noise",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/noise.js",
            +            "line": 14,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Random": {
            +            "name": "Random",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/random.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Trigonometry": {
            +            "name": "Trigonometry",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/trigonometry.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Typography": {
            +            "name": "Typography",
            +            "submodules": {
            +                "Attributes": 1,
            +                "Loading & Displaying": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13
            +        },
            +        "Array Functions": {
            +            "name": "Array Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/array_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Conversion": {
            +            "name": "Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "String Functions": {
            +            "name": "String Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/string_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Time & Date": {
            +            "name": "Time & Date",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/utilities/time_date.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Primitives": {
            +            "name": "3D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ],
            +            "description": "<p>p5 Geometry class</p>\n"
            +        },
            +        "3D": {
            +            "name": "3D",
            +            "submodules": {
            +                "Interaction": 1,
            +                "Lights": 1,
            +                "Material": 1,
            +                "Camera": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1,
            +                "p5.Shader": 1,
            +                "p5.Texture": 1,
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/text.js",
            +            "line": 260
            +        },
            +        "Interaction": {
            +            "name": "Interaction",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/interaction.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Lights": {
            +            "name": "Lights",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/light.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Models": {
            +            "name": "3D Models",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/loading.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ]
            +        },
            +        "Material": {
            +            "name": "Material",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Shader": 1,
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Texture.js",
            +            "line": 12,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the p5.Shader class</p>\n"
            +        },
            +        "Camera": {
            +            "name": "Camera",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.sound": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {},
            +            "module": "p5.sound",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>",
            +            "tag": "main",
            +            "itemtype": "main"
            +        }
            +    },
            +    "classes": {
            +        "p5": {
            +            "name": "p5",
            +            "shortname": "p5",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/core/main.js",
            +            "line": 13,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>element to attach canvas to</p>\n",
            +                    "type": "HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a p5 instance",
            +                "type": "P5"
            +            }
            +        },
            +        "p5.Color": {
            +            "name": "p5.Color",
            +            "shortname": "p5.Color",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Element": {
            +            "name": "p5.Element",
            +            "shortname": "p5.Element",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/core/p5.Element.js",
            +            "line": 9,
            +            "description": "<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Graphics": {
            +            "name": "p5.Graphics",
            +            "shortname": "p5.Graphics",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 10,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>the renderer to use, either P2D or WEBGL</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Renderer": {
            +            "name": "p5.Renderer",
            +            "shortname": "p5.Renderer",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 10,
            +            "description": "<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isMainCanvas",
            +                    "description": "<p>whether we're using it as main canvas</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "JSON": {
            +            "name": "JSON",
            +            "shortname": "JSON",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "console": {
            +            "name": "console",
            +            "shortname": "console",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "p5.TypedDict": {
            +            "name": "p5.TypedDict",
            +            "shortname": "p5.TypedDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 82,
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.StringDict": {
            +            "name": "p5.StringDict",
            +            "shortname": "p5.StringDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 394,
            +            "description": "<p>A simple Dictionary class for Strings.</p>\n",
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.NumberDict": {
            +            "name": "p5.NumberDict",
            +            "shortname": "p5.NumberDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "description": "<p>A simple Dictionary class for Numbers.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.MediaElement": {
            +            "name": "p5.MediaElement",
            +            "shortname": "p5.MediaElement",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 2377,
            +            "description": "<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.File": {
            +            "name": "p5.File",
            +            "shortname": "p5.File",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>File that is wrapped</p>\n",
            +                    "type": "File"
            +                }
            +            ]
            +        },
            +        "p5.Image": {
            +            "name": "p5.Image",
            +            "shortname": "p5.Image",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Image",
            +            "submodule": "Image",
            +            "namespace": "",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"
            +            ],
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ]
            +        },
            +        "p5.PrintWriter": {
            +            "name": "p5.PrintWriter",
            +            "shortname": "p5.PrintWriter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Table": {
            +            "name": "p5.Table",
            +            "shortname": "p5.Table",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.Table.js",
            +            "line": 33,
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "rows",
            +                    "description": "<p>An array of p5.TableRow objects</p>\n",
            +                    "type": "p5.TableRow[]",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TableRow": {
            +            "name": "p5.TableRow",
            +            "shortname": "p5.TableRow",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "description": "<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>comma separated values (csv) by default</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.XML": {
            +            "name": "p5.XML",
            +            "shortname": "p5.XML",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Input",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed"
            +        },
            +        "p5.Vector": {
            +            "name": "p5.Vector",
            +            "shortname": "p5.Vector",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "2 white ellipses. One center-left the other bottom right and off canvas"
            +        },
            +        "p5.Font": {
            +            "name": "p5.Font",
            +            "shortname": "p5.Font",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "description": "<p>Base class for font handling</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Camera": {
            +            "name": "p5.Camera",
            +            "shortname": "p5.Camera",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Camera",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n",
            +            "params": [
            +                {
            +                    "name": "rendererGL",
            +                    "description": "<p>instance of WebGL renderer</p>\n",
            +                    "type": "RendererGL"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes."
            +        },
            +        "p5.Geometry": {
            +            "name": "p5.Geometry",
            +            "shortname": "p5.Geometry",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Shape",
            +            "submodule": "3D Primitives",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "description": "<p>p5 Geometry class</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of vertices along the x-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of vertices along the y-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call upon object instantiation.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Shader": {
            +            "name": "p5.Shader",
            +            "shortname": "p5.Shader",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Material",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 11,
            +            "description": "<p>Shader class for WEBGL Mode</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n",
            +                    "type": "p5.RendererGL"
            +                },
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader (as a string)</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader (as a string)</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "shortname": "p5.sound",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": ""
            +        },
            +        "p5.SoundFile": {
            +            "name": "p5.SoundFile",
            +            "shortname": "p5.SoundFile",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1405,
            +            "description": "<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoadingCallback",
            +                    "description": "<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"
            +            ]
            +        },
            +        "p5.Amplitude": {
            +            "name": "p5.Amplitude",
            +            "shortname": "p5.Amplitude",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3022,
            +            "description": "<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.FFT": {
            +            "name": "p5.FFT",
            +            "shortname": "p5.FFT",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3347,
            +            "description": "<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Oscillator": {
            +            "name": "p5.Oscillator",
            +            "shortname": "p5.Oscillator",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4060,
            +            "description": "<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>frequency defaults to 440Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"
            +            ]
            +        },
            +        "p5.SinOsc": {
            +            "name": "p5.SinOsc",
            +            "shortname": "p5.SinOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4602,
            +            "description": "<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TriOsc": {
            +            "name": "p5.TriOsc",
            +            "shortname": "p5.TriOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4629,
            +            "description": "<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SawOsc": {
            +            "name": "p5.SawOsc",
            +            "shortname": "p5.SawOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4656,
            +            "description": "<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SqrOsc": {
            +            "name": "p5.SqrOsc",
            +            "shortname": "p5.SqrOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4683,
            +            "description": "<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Envelope": {
            +            "name": "p5.Envelope",
            +            "shortname": "p5.Envelope",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4721,
            +            "description": "<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Noise": {
            +            "name": "p5.Noise",
            +            "shortname": "p5.Noise",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5620,
            +            "description": "<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.Pulse": {
            +            "name": "p5.Pulse",
            +            "shortname": "p5.Pulse",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5779,
            +            "description": "<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in oscillations per second (Hz)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioIn": {
            +            "name": "p5.AudioIn",
            +            "shortname": "p5.AudioIn",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6015,
            +            "description": "<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Effect": {
            +            "name": "p5.Effect",
            +            "shortname": "p5.Effect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6423,
            +            "description": "<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "ac",
            +                    "description": "<p>Reference to the audio context of the p5 object</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "input",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "output",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "_drywet",
            +                    "description": "<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "wet",
            +                    "description": "<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Filter": {
            +            "name": "p5.Filter",
            +            "shortname": "p5.Filter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6628,
            +            "description": "<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.LowPass": {
            +            "name": "p5.LowPass",
            +            "shortname": "p5.LowPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6914,
            +            "description": "<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.HighPass": {
            +            "name": "p5.HighPass",
            +            "shortname": "p5.HighPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6938,
            +            "description": "<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.BandPass": {
            +            "name": "p5.BandPass",
            +            "shortname": "p5.BandPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6962,
            +            "description": "<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.EQ": {
            +            "name": "p5.EQ",
            +            "shortname": "p5.EQ",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7105,
            +            "description": "<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect",
            +            "params": [
            +                {
            +                    "name": "_eqsize",
            +                    "description": "<p>Constructor will accept 3 or 8, defaults to 3</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "p5.EQ object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Panner3D": {
            +            "name": "p5.Panner3D",
            +            "shortname": "p5.Panner3D",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7602,
            +            "description": "<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Delay": {
            +            "name": "p5.Delay",
            +            "shortname": "p5.Delay",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7926,
            +            "description": "<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Reverb": {
            +            "name": "p5.Reverb",
            +            "shortname": "p5.Reverb",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8308,
            +            "description": "<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Convolver": {
            +            "name": "p5.Convolver",
            +            "shortname": "p5.Convolver",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8549,
            +            "description": "<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when loading succeeds</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Phrase": {
            +            "name": "p5.Phrase",
            +            "shortname": "p5.Phrase",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9103,
            +            "description": "<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>Name so that you can access the Phrase.</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Part": {
            +            "name": "p5.Part",
            +            "shortname": "p5.Part",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9185,
            +            "description": "<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "steps",
            +                    "description": "<p>Steps in the part</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tatums",
            +                    "description": "<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Score": {
            +            "name": "p5.Score",
            +            "shortname": "p5.Score",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9493,
            +            "description": "<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "parts",
            +                    "description": "<p>One or multiple parts, to be played in sequence.</p>\n",
            +                    "type": "p5.Part",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ]
            +        },
            +        "p5.SoundLoop": {
            +            "name": "p5.SoundLoop",
            +            "shortname": "p5.SoundLoop",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9673,
            +            "description": "<p>SoundLoop</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>this function will be called on each iteration of theloop</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "interval",
            +                    "description": "<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n",
            +                    "type": "Number|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Compressor": {
            +            "name": "p5.Compressor",
            +            "shortname": "p5.Compressor",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10036,
            +            "description": "<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect"
            +        },
            +        "p5.PeakDetect": {
            +            "name": "p5.PeakDetect",
            +            "shortname": "p5.PeakDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10312,
            +            "description": "<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq1",
            +                    "description": "<p>lowFrequency - defaults to 20Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "freq2",
            +                    "description": "<p>highFrequency - defaults to 20000 Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "framesPerPeak",
            +                    "description": "<p>Defaults to 20.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.SoundRecorder": {
            +            "name": "p5.SoundRecorder",
            +            "shortname": "p5.SoundRecorder",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10559,
            +            "description": "<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"
            +            ]
            +        },
            +        "p5.Distortion": {
            +            "name": "p5.Distortion",
            +            "shortname": "p5.Distortion",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10816,
            +            "description": "<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ]
            +        },
            +        "p5.Gain": {
            +            "name": "p5.Gain",
            +            "shortname": "p5.Gain",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10973,
            +            "description": "<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioVoice": {
            +            "name": "p5.AudioVoice",
            +            "shortname": "p5.AudioVoice",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11149,
            +            "description": "<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.MonoSynth": {
            +            "name": "p5.MonoSynth",
            +            "shortname": "p5.MonoSynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11247,
            +            "description": "<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.OnsetDetect": {
            +            "name": "p5.OnsetDetect",
            +            "shortname": "p5.OnsetDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11624,
            +            "description": "<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freqLow",
            +                    "description": "<p>Low frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "freqHigh",
            +                    "description": "<p>High frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Function to call when an onset is detected</p>\n",
            +                    "type": "Function"
            +                }
            +            ]
            +        },
            +        "p5.PolySynth": {
            +            "name": "p5.PolySynth",
            +            "shortname": "p5.PolySynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "synthVoice",
            +                    "description": "<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "maxVoices",
            +                    "description": "<p>Number of voices, defaults to 8;</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ]
            +        }
            +    },
            +    "elements": {},
            +    "classitems": [
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 18,
            +            "description": "<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describe",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the canvas</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 114,
            +            "description": "<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describeElement",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 10,
            +            "description": "<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "textOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 88,
            +            "description": "<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "gridOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 8,
            +            "description": "<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 19,
            +            "description": "<p>Convert an HSBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 45,
            +            "description": "<p>Convert an HSBA array to RGBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 100,
            +            "description": "<p>Convert an HSLA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 123,
            +            "description": "<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 187,
            +            "description": "<p>Convert an RGBA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 226,
            +            "description": "<p>Convert an RGBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 16,
            +            "description": "<p>Extracts the alpha value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "alpha",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the alpha value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 43,
            +            "description": "<p>Extracts the blue value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "blue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the blue value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 69,
            +            "description": "<p>Extracts the HSB brightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "brightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the brightness value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 113,
            +            "description": "<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n",
            +            "itemtype": "method",
            +            "name": "color",
            +            "return": {
            +                "description": "resulting color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "overloads": [
            +                {
            +                    "line": 113,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "resulting color",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 257,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 269,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 282,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 297,
            +            "description": "<p>Extracts the green value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "green",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the green value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 325,
            +            "description": "<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n",
            +            "itemtype": "method",
            +            "name": "hue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the hue",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 359,
            +            "description": "<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerpColor",
            +            "params": [
            +                {
            +                    "name": "c1",
            +                    "description": "<p>interpolate from this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "c2",
            +                    "description": "<p>interpolate to this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "interpolated color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 449,
            +            "description": "<p>Extracts the HSL lightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "lightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the lightness",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 478,
            +            "description": "<p>Extracts the red value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "red",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the red value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 517,
            +            "description": "<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n",
            +            "itemtype": "method",
            +            "name": "saturation",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the saturation value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 51,
            +            "description": "<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "params": [
            +                {
            +                    "name": "format",
            +                    "description": "<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the formatted string",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 254,
            +            "description": "<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRed",
            +            "params": [
            +                {
            +                    "name": "red",
            +                    "description": "<p>the new red value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 281,
            +            "description": "<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setGreen",
            +            "params": [
            +                {
            +                    "name": "green",
            +                    "description": "<p>the new green value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 304,
            +            "description": "<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBlue",
            +            "params": [
            +                {
            +                    "name": "blue",
            +                    "description": "<p>the new blue value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 327,
            +            "description": "<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAlpha",
            +            "params": [
            +                {
            +                    "name": "alpha",
            +                    "description": "<p>the new alpha value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 396,
            +            "description": "<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 427,
            +            "description": "<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 446,
            +            "description": "<p>CSS named colors.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 600,
            +            "description": "<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 613,
            +            "description": "<p>Full color string patterns. The capture groups are necessary.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 960,
            +            "description": "<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 13,
            +            "description": "<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n",
            +            "itemtype": "method",
            +            "name": "background",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "colorstring",
            +                            "description": "<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 140,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>specifies a value between white and black</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 147,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current color\n                       mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 159,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 166,
            +                    "params": [
            +                        {
            +                            "name": "image",
            +                            "description": "<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 179,
            +            "description": "<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"
            +            ],
            +            "params": [
            +                {
            +                    "name": "r",
            +                    "description": "<p>normalized red val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "g",
            +                    "description": "<p>normalized green val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>normalized blue val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>normalized alpha val.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 229,
            +            "description": "<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n",
            +            "itemtype": "method",
            +            "name": "colorMode",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 229,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>range for all values</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 306,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max1",
            +                            "description": "<p>range for the red or hue depending on the\n                             current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max2",
            +                            "description": "<p>range for the green or saturation depending\n                             on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max3",
            +                            "description": "<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "maxA",
            +                            "description": "<p>range for the alpha</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 350,
            +            "description": "<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n",
            +            "itemtype": "method",
            +            "name": "fill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 350,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 475,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 488,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 495,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the fill color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 507,
            +            "description": "<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noFill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 547,
            +            "description": "<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noStroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 585,
            +            "description": "<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n",
            +            "itemtype": "method",
            +            "name": "stroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 585,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 722,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 728,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 735,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 742,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the stroke color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 755,
            +            "description": "<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n",
            +            "itemtype": "method",
            +            "name": "erase",
            +            "params": [
            +                {
            +                    "name": "strengthFill",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "strengthStroke",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 836,
            +            "description": "<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "noErase",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis is the main file for the Friendly Error System (FES)",
            +                "containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters",
            +                "(2) _friendlyFileLoadError",
            +                "(3) _friendlyError",
            +                "(4) helpForMisusedAtTopLevelCode",
            +                "or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this",
            +                "there's also a file stacktrace.js",
            +                "which contains the code\nto parse the error stack",
            +                "borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions",
            +                "including the call\nsequence of each function",
            +                "please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 915,
            +            "description": "<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n",
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/file_errors.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/sketch_reader.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/stacktrace.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/validate_params.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 16,
            +            "description": "<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 102,
            +            "description": "<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n",
            +            "itemtype": "method",
            +            "name": "arc",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>angle to start the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>angle to stop the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "mode",
            +                    "description": "<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detail",
            +                    "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 235,
            +            "description": "<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipse",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 235,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the ellipse.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 261,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detail",
            +                            "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 277,
            +            "description": "<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n",
            +            "itemtype": "method",
            +            "name": "circle",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>diameter of the circle.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 340,
            +            "description": "<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "line",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 340,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 404,
            +            "description": "<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "point",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 404,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z-coordinate (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 455,
            +                    "params": [
            +                        {
            +                            "name": "coordinate_vector",
            +                            "description": "<p>the coordinate vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 483,
            +            "description": "<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "quad",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 483,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>the x-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>the y-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>the x-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>the y-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>the z-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>the z-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 556,
            +            "description": "<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "rect",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 556,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the rectangle.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tl",
            +                            "description": "<p>optional radius of top-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tr",
            +                            "description": "<p>optional radius of top-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "br",
            +                            "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "bl",
            +                            "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 608,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 623,
            +            "description": "<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "square",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "s",
            +                    "description": "<p>side size of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "tl",
            +                    "description": "<p>optional radius of top-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tr",
            +                    "description": "<p>optional radius of top-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "br",
            +                    "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bl",
            +                    "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 713,
            +            "description": "<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n",
            +            "itemtype": "method",
            +            "name": "triangle",
            +            "params": [
            +                {
            +                    "name": "x1",
            +                    "description": "<p>x-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y1",
            +                    "description": "<p>y-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>x-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>y-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x3",
            +                    "description": "<p>x-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y3",
            +                    "description": "<p>y-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 12,
            +            "description": "<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipseMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 81,
            +            "description": "<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "noSmooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses to left & right of center, black background",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 115,
            +            "description": "<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "rectMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 184,
            +            "description": "<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses one left one right of center. On black.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 219,
            +            "description": "<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeCap",
            +            "params": [
            +                {
            +                    "name": "cap",
            +                    "description": "<p>either ROUND, SQUARE or PROJECT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 259,
            +            "description": "<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeJoin",
            +            "params": [
            +                {
            +                    "name": "join",
            +                    "description": "<p>either MITER, BEVEL, ROUND</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 331,
            +            "description": "<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeWeight",
            +            "params": [
            +                {
            +                    "name": "weight",
            +                    "description": "<p>the weight of the stroke (in pixels)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"
            +            ],
            +            "alt": "3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 13,
            +            "description": "<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezier",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 62,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 92,
            +            "description": "<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierDetail",
            +            "params": [
            +                {
            +                    "name": "detail",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape with a low level of bezier detail",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 130,
            +            "description": "<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierPoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value of the Bezier at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "10 points plotted on a given bezier at equal distances.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 185,
            +            "description": "<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 264,
            +            "description": "<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curve",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 264,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 332,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 358,
            +            "description": "<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveDetail",
            +            "params": [
            +                {
            +                    "name": "resolution",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white arch shape with a low level of curve detail.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 398,
            +            "description": "<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTightness",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>amount of deformation from the original vertices</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Line shaped like right-facing arrow,points move with mouse-x and warp shape.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 444,
            +            "description": "<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "curvePoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point of the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "bezier value at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 493,
            +            "description": "<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second conrol point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "right curving line mid-right of canvas with 7 short lines radiating from it.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 20,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 67,
            +            "description": "<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginShape",
            +            "params": [
            +                {
            +                    "name": "kind",
            +                    "description": "<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 293,
            +            "description": "<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 375,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 415,
            +            "description": "<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Upside-down u-shape line, mid canvas. left point extends beyond canvas view.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 415,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 460,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 524,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "endContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 583,
            +            "description": "<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n",
            +            "itemtype": "method",
            +            "name": "endShape",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>use CLOSE to close the shape</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Triangle line shape with smallest interior angle on bottom and upside-down L.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 668,
            +            "description": "<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "quadraticVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 668,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "<p>x-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "<p>y-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 733,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cz",
            +                            "description": "<p>z-coordinate for the control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 826,
            +            "description": "<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "vertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 826,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 957,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 965,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "u",
            +                            "description": "<p>the vertex's texture u-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vertex's texture v-coordinate</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1003,
            +            "description": "<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n",
            +            "itemtype": "method",
            +            "name": "normal",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 1003,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>A p5.Vector representing the vertex normal.</p>\n",
            +                            "type": "Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1040,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The x component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The y component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The z component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 9,
            +            "description": "<p>Version of this p5.js.</p>\n",
            +            "itemtype": "property",
            +            "name": "VERSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 18,
            +            "description": "<p>The default, two-dimensional renderer.</p>\n",
            +            "itemtype": "property",
            +            "name": "P2D",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 24,
            +            "description": "<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n",
            +            "itemtype": "property",
            +            "name": "WEBGL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 33,
            +            "itemtype": "property",
            +            "name": "ARROW",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 38,
            +            "itemtype": "property",
            +            "name": "CROSS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 43,
            +            "itemtype": "property",
            +            "name": "HAND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 48,
            +            "itemtype": "property",
            +            "name": "MOVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 53,
            +            "itemtype": "property",
            +            "name": "TEXT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 58,
            +            "itemtype": "property",
            +            "name": "WAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 66,
            +            "description": "<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HALF_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white quarter-circle with curve toward bottom right of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 84,
            +            "description": "<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"
            +            ],
            +            "alt": "white half-circle with curve toward bottom of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 102,
            +            "description": "<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "QUARTER_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"
            +            ],
            +            "alt": "white eighth-circle rotated about 40 degrees with curve bottom right canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 120,
            +            "description": "<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TAU",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 138,
            +            "description": "<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TWO_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 156,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n",
            +            "itemtype": "property",
            +            "name": "DEGREES",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 170,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n",
            +            "itemtype": "property",
            +            "name": "RADIANS",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 188,
            +            "itemtype": "property",
            +            "name": "CORNER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 193,
            +            "itemtype": "property",
            +            "name": "CORNERS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 198,
            +            "itemtype": "property",
            +            "name": "RADIUS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 203,
            +            "itemtype": "property",
            +            "name": "RIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 208,
            +            "itemtype": "property",
            +            "name": "LEFT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 213,
            +            "itemtype": "property",
            +            "name": "CENTER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 218,
            +            "itemtype": "property",
            +            "name": "TOP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 223,
            +            "itemtype": "property",
            +            "name": "BOTTOM",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 228,
            +            "itemtype": "property",
            +            "name": "BASELINE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "alphabetic",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 234,
            +            "itemtype": "property",
            +            "name": "POINTS",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0000",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 240,
            +            "itemtype": "property",
            +            "name": "LINES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0001",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 246,
            +            "itemtype": "property",
            +            "name": "LINE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0003",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 252,
            +            "itemtype": "property",
            +            "name": "LINE_LOOP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0002",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 258,
            +            "itemtype": "property",
            +            "name": "TRIANGLES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0004",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 264,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_FAN",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0006",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 270,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0005",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 276,
            +            "itemtype": "property",
            +            "name": "QUADS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 281,
            +            "itemtype": "property",
            +            "name": "QUAD_STRIP",
            +            "type": "String",
            +            "final": 1,
            +            "default": "quad_strip",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 287,
            +            "itemtype": "property",
            +            "name": "TESS",
            +            "type": "String",
            +            "final": 1,
            +            "default": "tess",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 293,
            +            "itemtype": "property",
            +            "name": "CLOSE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 298,
            +            "itemtype": "property",
            +            "name": "OPEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 303,
            +            "itemtype": "property",
            +            "name": "CHORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 308,
            +            "itemtype": "property",
            +            "name": "PIE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 313,
            +            "itemtype": "property",
            +            "name": "PROJECT",
            +            "type": "String",
            +            "final": 1,
            +            "default": "square",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 319,
            +            "itemtype": "property",
            +            "name": "SQUARE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "butt",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 325,
            +            "itemtype": "property",
            +            "name": "ROUND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 330,
            +            "itemtype": "property",
            +            "name": "BEVEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 335,
            +            "itemtype": "property",
            +            "name": "MITER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 342,
            +            "itemtype": "property",
            +            "name": "RGB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 347,
            +            "description": "<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HSB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 356,
            +            "itemtype": "property",
            +            "name": "HSL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 363,
            +            "description": "<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n",
            +            "itemtype": "property",
            +            "name": "AUTO",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 373,
            +            "itemtype": "property",
            +            "name": "ALT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 379,
            +            "itemtype": "property",
            +            "name": "BACKSPACE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 384,
            +            "itemtype": "property",
            +            "name": "CONTROL",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 389,
            +            "itemtype": "property",
            +            "name": "DELETE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 394,
            +            "itemtype": "property",
            +            "name": "DOWN_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 399,
            +            "itemtype": "property",
            +            "name": "ENTER",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 404,
            +            "itemtype": "property",
            +            "name": "ESCAPE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 409,
            +            "itemtype": "property",
            +            "name": "LEFT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 414,
            +            "itemtype": "property",
            +            "name": "OPTION",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 419,
            +            "itemtype": "property",
            +            "name": "RETURN",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 424,
            +            "itemtype": "property",
            +            "name": "RIGHT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 429,
            +            "itemtype": "property",
            +            "name": "SHIFT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 434,
            +            "itemtype": "property",
            +            "name": "TAB",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 439,
            +            "itemtype": "property",
            +            "name": "UP_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 446,
            +            "itemtype": "property",
            +            "name": "BLEND",
            +            "type": "String",
            +            "final": 1,
            +            "default": "source-over",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 452,
            +            "itemtype": "property",
            +            "name": "REMOVE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "destination-out",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 458,
            +            "itemtype": "property",
            +            "name": "ADD",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighter",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 466,
            +            "itemtype": "property",
            +            "name": "DARKEST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 471,
            +            "itemtype": "property",
            +            "name": "LIGHTEST",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighten",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 477,
            +            "itemtype": "property",
            +            "name": "DIFFERENCE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 482,
            +            "itemtype": "property",
            +            "name": "SUBTRACT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 487,
            +            "itemtype": "property",
            +            "name": "EXCLUSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 492,
            +            "itemtype": "property",
            +            "name": "MULTIPLY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 497,
            +            "itemtype": "property",
            +            "name": "SCREEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 502,
            +            "itemtype": "property",
            +            "name": "REPLACE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "copy",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 508,
            +            "itemtype": "property",
            +            "name": "OVERLAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 513,
            +            "itemtype": "property",
            +            "name": "HARD_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 518,
            +            "itemtype": "property",
            +            "name": "SOFT_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 523,
            +            "itemtype": "property",
            +            "name": "DODGE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-dodge",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 529,
            +            "itemtype": "property",
            +            "name": "BURN",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-burn",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 537,
            +            "itemtype": "property",
            +            "name": "THRESHOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 542,
            +            "itemtype": "property",
            +            "name": "GRAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 547,
            +            "itemtype": "property",
            +            "name": "OPAQUE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 552,
            +            "itemtype": "property",
            +            "name": "INVERT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 557,
            +            "itemtype": "property",
            +            "name": "POSTERIZE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 562,
            +            "itemtype": "property",
            +            "name": "DILATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 567,
            +            "itemtype": "property",
            +            "name": "ERODE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 572,
            +            "itemtype": "property",
            +            "name": "BLUR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 579,
            +            "itemtype": "property",
            +            "name": "NORMAL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 584,
            +            "itemtype": "property",
            +            "name": "ITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 589,
            +            "itemtype": "property",
            +            "name": "BOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 594,
            +            "itemtype": "property",
            +            "name": "BOLDITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 599,
            +            "itemtype": "property",
            +            "name": "CHAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 604,
            +            "itemtype": "property",
            +            "name": "WORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 616,
            +            "itemtype": "property",
            +            "name": "LINEAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 621,
            +            "itemtype": "property",
            +            "name": "QUADRATIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 626,
            +            "itemtype": "property",
            +            "name": "BEZIER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 631,
            +            "itemtype": "property",
            +            "name": "CURVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 638,
            +            "itemtype": "property",
            +            "name": "STROKE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 643,
            +            "itemtype": "property",
            +            "name": "FILL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 648,
            +            "itemtype": "property",
            +            "name": "TEXTURE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 653,
            +            "itemtype": "property",
            +            "name": "IMMEDIATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 661,
            +            "itemtype": "property",
            +            "name": "IMAGE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 669,
            +            "itemtype": "property",
            +            "name": "NEAREST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 674,
            +            "itemtype": "property",
            +            "name": "REPEAT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 679,
            +            "itemtype": "property",
            +            "name": "CLAMP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 684,
            +            "itemtype": "property",
            +            "name": "MIRROR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 691,
            +            "itemtype": "property",
            +            "name": "LANDSCAPE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 696,
            +            "itemtype": "property",
            +            "name": "PORTRAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 706,
            +            "itemtype": "property",
            +            "name": "GRID",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 712,
            +            "itemtype": "property",
            +            "name": "AXES",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 718,
            +            "itemtype": "property",
            +            "name": "LABEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 723,
            +            "itemtype": "property",
            +            "name": "FALLBACK",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 20,
            +            "description": "<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "contents",
            +                    "description": "<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"
            +            ],
            +            "alt": "default grey canvas",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 52,
            +            "description": "<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n",
            +            "itemtype": "property",
            +            "name": "frameCount",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "numbers rapidly counting upward with frame count set to 30.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 79,
            +            "description": "<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n",
            +            "itemtype": "property",
            +            "name": "deltaTime",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 129,
            +            "description": "<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "focused",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "green 50×50 ellipse at top left. Red X covers canvas when page focus changes",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 160,
            +            "description": "<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n",
            +            "itemtype": "method",
            +            "name": "cursor",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n",
            +                    "type": "String|Constant"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>the horizontal active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>the vertical active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 228,
            +            "description": "<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n",
            +            "itemtype": "method",
            +            "name": "frameRate",
            +            "chainable": 1,
            +            "example": [
            +                "\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "blue rect moves left to right, followed by red rect moving faster. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 228,
            +                    "params": [
            +                        {
            +                            "name": "fps",
            +                            "description": "<p>number of frames to be displayed every second</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 288,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current frameRate",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 331,
            +            "description": "<p>Hides the cursor from view.</p>\n",
            +            "itemtype": "method",
            +            "name": "noCursor",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "cursor becomes 10×10 white ellipse the moves with mouse x and y.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 354,
            +            "description": "<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 372,
            +            "description": "<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 390,
            +            "description": "<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 405,
            +            "description": "<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 421,
            +            "description": "<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n",
            +            "itemtype": "method",
            +            "name": "windowResized",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional Event callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 476,
            +            "description": "<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 488,
            +            "description": "<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 500,
            +            "description": "<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n",
            +            "itemtype": "method",
            +            "name": "fullscreen",
            +            "params": [
            +                {
            +                    "name": "val",
            +                    "description": "<p>whether the sketch should be in fullscreen mode\nor not</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "current fullscreen state",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 550,
            +            "description": "<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "pixelDensity",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 550,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>whether or how much the sketch should scale</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 586,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current pixel density of the sketch",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 605,
            +            "description": "<p>Returns the pixel density of the current display the sketch is running on.</p>\n",
            +            "itemtype": "method",
            +            "name": "displayDensity",
            +            "return": {
            +                "description": "current pixel density of the display",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 660,
            +            "description": "<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURL",
            +            "return": {
            +                "description": "url",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "current url (http://p5js.org/reference/#/p5/getURL) moves right to left.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 691,
            +            "description": "<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLPath",
            +            "return": {
            +                "description": "path components",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 713,
            +            "description": "<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLParams",
            +            "return": {
            +                "description": "URL params",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/helpers.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 30,
            +            "description": "<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 126,
            +            "description": "<p>Set up our translation function, with loaded languages</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 171,
            +            "description": "<p>Returns a list of languages we have translations loaded for</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 178,
            +            "description": "<p>Returns the current language selected for translation</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 185,
            +            "description": "<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/legacy.js",
            +            "line": 1,
            +            "requires": [
            +                "core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name",
            +                "in others",
            +                "they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 42,
            +            "description": "<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "preload",
            +            "example": [
            +                "\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 83,
            +            "description": "<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setup",
            +            "example": [
            +                "\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 114,
            +            "description": "<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "draw",
            +            "example": [
            +                "\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 415,
            +            "description": "<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 693,
            +            "description": "<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "disableFriendlyErrors",
            +            "type": "Boolean",
            +            "example": [
            +                "\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 21,
            +            "description": "<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "elt",
            +            "readonly": "",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 47,
            +            "description": "<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "parent",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 47,
            +                    "params": [
            +                        {
            +                            "name": "parent",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n",
            +                            "type": "String|p5.Element|Object"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 93,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 114,
            +            "description": "<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n",
            +            "itemtype": "method",
            +            "name": "id",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 114,
            +                    "params": [
            +                        {
            +                            "name": "id",
            +                            "description": "<p>ID of the element</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the id of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 154,
            +            "description": "<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "class",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 154,
            +                    "params": [
            +                        {
            +                            "name": "class",
            +                            "description": "<p>class to add</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the class of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 189,
            +            "description": "<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 246,
            +            "description": "<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 292,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 354,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 403,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 454,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 510,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 551,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOut",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 592,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 639,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 678,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 725,
            +            "description": "<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 763,
            +            "description": "<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragLeave",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 827,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 70,
            +            "description": "<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 122,
            +            "description": "<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image\na multi-colored circle moving back and forth over a scrolling background.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 99,
            +            "description": "<p>Resize our canvas element.</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 415,
            +            "description": "<p>Helper function to check font type (system or otf)</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 467,
            +            "description": "<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 7,
            +            "description": "<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 402,
            +            "description": "<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 7,
            +            "description": "<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n",
            +            "itemtype": "property",
            +            "name": "let",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 34,
            +            "description": "<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n",
            +            "itemtype": "property",
            +            "name": "const",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"
            +            ],
            +            "alt": "These examples do not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 87,
            +            "description": "<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n",
            +            "itemtype": "property",
            +            "name": "===",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 115,
            +            "description": "<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>",
            +            "itemtype": "property",
            +            "name": ">",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 137,
            +            "description": "<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": ">=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 158,
            +            "description": "<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 179,
            +            "description": "<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 200,
            +            "description": "<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n",
            +            "itemtype": "property",
            +            "name": "if-else",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 231,
            +            "description": "<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n",
            +            "itemtype": "property",
            +            "name": "function",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 267,
            +            "description": "<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "return",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 288,
            +            "description": "<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n",
            +            "itemtype": "property",
            +            "name": "boolean",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 309,
            +            "description": "<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n",
            +            "itemtype": "property",
            +            "name": "string",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 331,
            +            "description": "<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n",
            +            "itemtype": "property",
            +            "name": "number",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 351,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n",
            +            "itemtype": "property",
            +            "name": "object",
            +            "example": [
            +                "\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 379,
            +            "description": "<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n",
            +            "itemtype": "property",
            +            "name": "class",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 408,
            +            "description": "<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n",
            +            "itemtype": "property",
            +            "name": "for",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 448,
            +            "description": "<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n",
            +            "itemtype": "property",
            +            "name": "while",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 490,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "stringify",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>:Javascript object that you would like to convert to JSON</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "JSON",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 512,
            +            "description": "<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "message",
            +                    "description": "<p>:Message that you would like to print to the console</p>\n",
            +                    "type": "String|Expression|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "console",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 15,
            +            "description": "<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Renderer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Black line extending from top-left of canvas to bottom right.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 125,
            +            "description": "<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "resizeCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "noRedraw",
            +                    "description": "<p>don't redraw the canvas immediately</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "No image displayed.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 183,
            +            "description": "<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n",
            +            "itemtype": "method",
            +            "name": "noCanvas",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 204,
            +            "description": "<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "createGraphics",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "offscreen graphics buffer",
            +                "type": "p5.Graphics"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 grey squares alternating light and dark grey. White quarter circle mid-left.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 243,
            +            "description": "<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n",
            +            "itemtype": "method",
            +            "name": "blendMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"
            +            ],
            +            "alt": "translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 326,
            +            "description": "<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n",
            +            "itemtype": "property",
            +            "name": "drawingContext",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white ellipse with shadow blur effect around edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 18,
            +            "description": "<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 39,
            +            "description": "<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 10,
            +            "description": "<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 83,
            +            "description": "<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "example": [
            +                "\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 134,
            +            "description": "<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "example": [
            +                "\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 192,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "push",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 290,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "pop",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 391,
            +            "description": "<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n",
            +            "itemtype": "method",
            +            "name": "redraw",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>Redraw for n-times. The default value is 1.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black line on far left of canvas\nblack line on far left of canvas",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 497,
            +            "description": "<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "p5",
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a function containing a p5.js sketch</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>ID or pointer to HTML DOM node to contain sketch in</p>\n",
            +                    "type": "String|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"
            +            ],
            +            "alt": "white rectangle on black background",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 11,
            +            "description": "<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n",
            +            "itemtype": "method",
            +            "name": "applyMatrix",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n",
            +                    "type": "Number|Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "f",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 168,
            +            "description": "<p>Replaces the current matrix with the identity matrix.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetMatrix",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"
            +            ],
            +            "alt": "A rotated rectangle in the center with another at the top left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 193,
            +            "description": "<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "axis",
            +                    "description": "<p>(in 3d) the axis to rotate around</p>\n",
            +                    "type": "p5.Vector|Number[]",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 232,
            +            "description": "<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the x axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 268,
            +            "description": "<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the y axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 304,
            +            "description": "<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateZ",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the z axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 342,
            +            "description": "<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 342,
            +                    "params": [
            +                        {
            +                            "name": "s",
            +                            "description": "<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n",
            +                            "type": "Number|p5.Vector|Number[]"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>percent to scale the object in the y-axis</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>percent to scale the object in the z-axis (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 386,
            +                    "params": [
            +                        {
            +                            "name": "scales",
            +                            "description": "<p>per-axis percents to scale the object</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 416,
            +            "description": "<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at top middle.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 455,
            +            "description": "<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at middle bottom.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 494,
            +            "description": "<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "translate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 494,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>left/right translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>up/down translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>forward/backward translation (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>the vector to translate by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 10,
            +            "description": "<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n",
            +            "itemtype": "method",
            +            "name": "storeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"
            +            ],
            +            "alt": "When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 101,
            +            "description": "<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "getItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>name that you wish to use to store in local storage</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Value of stored item",
            +                "type": "Number|Object|String|Boolean|p5.Color|p5.Vector"
            +            },
            +            "example": [
            +                "\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"
            +            ],
            +            "alt": "If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 177,
            +            "description": "<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearStorage",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 205,
            +            "description": "<p>Removes an item that was stored with storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "removeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 14,
            +            "description": "<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createStringDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.StringDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 14,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                },
            +                {
            +                    "line": 37,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 48,
            +            "description": "<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createNumberDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.NumberDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 48,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 101,
            +            "description": "<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the number of key-value pairs in the Dictionary",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 122,
            +            "description": "<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasKey",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>that you want to look up</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether that key exists in Dictionary",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 144,
            +            "description": "<p>Returns the value stored at the given key.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>key you want to access</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value stored at that key",
            +                "type": "Number|String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 170,
            +            "description": "<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 197,
            +            "description": "<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 208,
            +            "description": "<p>Creates a new key-value pair in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "create",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 208,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 226,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>key/value pair</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 244,
            +            "description": "<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 265,
            +            "description": "<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>for the pair to remove</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 294,
            +            "description": "<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 318,
            +            "description": "<p>Converts the Dictionary into a CSV file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 356,
            +            "description": "<p>Converts the Dictionary into a JSON file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 387,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 425,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 432,
            +            "description": "<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to add to</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to add to the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 459,
            +            "description": "<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to subtract from</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to subtract from the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 482,
            +            "description": "<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to multiply</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to multiply the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 509,
            +            "description": "<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to divide</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to divide the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 536,
            +            "description": "<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 560,
            +            "description": "<p>Return the lowest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 580,
            +            "description": "<p>Return the highest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 600,
            +            "description": "<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 622,
            +            "description": "<p>Return the lowest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 642,
            +            "description": "<p>Return the highest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 21,
            +            "description": "<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "select",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of element to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Element\">p5.Element</a> containing node found",
            +                "type": "p5.Element|null"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 68,
            +            "description": "<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "selectAll",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of elements to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found",
            +                "type": "p5.Element[]"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 127,
            +            "description": "<p>Helper function for select and selectAll</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 142,
            +            "description": "<p>Helper function for getElement and getElements.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 176,
            +            "description": "<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeElements",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 204,
            +            "description": "<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "changed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 271,
            +            "description": "<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "input",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 309,
            +            "description": "<p>Helpers for create methods.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 322,
            +            "description": "<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createDiv",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 341,
            +            "description": "<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createP",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 361,
            +            "description": "<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSpan",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 379,
            +            "description": "<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImg",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>src path or url for image</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 396,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "crossOrigin",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 426,
            +            "description": "<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n",
            +            "itemtype": "method",
            +            "name": "createA",
            +            "params": [
            +                {
            +                    "name": "href",
            +                    "description": "<p>url of page to link to</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner html of link element to display</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "target",
            +                    "description": "<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 450,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 452,
            +            "description": "<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSlider",
            +            "params": [
            +                {
            +                    "name": "min",
            +                    "description": "<p>minimum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "max",
            +                    "description": "<p>maximum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>default value of the slider</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "step",
            +                    "description": "<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 507,
            +            "description": "<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n",
            +            "itemtype": "method",
            +            "name": "createButton",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed on the button</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the button</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 541,
            +            "description": "<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n",
            +            "itemtype": "method",
            +            "name": "createCheckbox",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed after checkbox</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the checkbox; checked is true, unchecked is false</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 622,
            +            "description": "<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createSelect",
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "multiple",
            +                            "description": "<p>true if dropdown should support multiple selections</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 673,
            +                    "params": [
            +                        {
            +                            "name": "existing",
            +                            "description": "<p>DOM select element</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 770,
            +            "description": "<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createRadio",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 770,
            +                    "params": [
            +                        {
            +                            "name": "containerElement",
            +                            "description": "<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "name",
            +                            "description": "<p>A name parameter for each Input Element.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 832,
            +                    "params": [
            +                        {
            +                            "name": "name",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 837,
            +                    "params": [],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 978,
            +            "description": "<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n",
            +            "itemtype": "method",
            +            "name": "createColorPicker",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>default color of element</p>\n",
            +                    "type": "String|p5.Color",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1066,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n",
            +            "itemtype": "method",
            +            "name": "createInput",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1066,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>default value of the input box</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "type",
            +                            "description": "<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1104,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "createFileInput",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function for when a file is loaded</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "multiple",
            +                    "description": "<p>optional, to allow multiple files to be selected</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1164,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1211,
            +            "description": "<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVideo",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n",
            +                    "type": "String|String[]"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1257,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1259,
            +            "description": "<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createAudio",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n",
            +                    "type": "String|String[]",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1296,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1298,
            +            "itemtype": "property",
            +            "name": "VIDEO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1304,
            +            "itemtype": "property",
            +            "name": "AUDIO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1341,
            +            "description": "<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCapture",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n",
            +                    "type": "String|Constant|Object"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be called once\n                                  stream has loaded</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1478,
            +            "description": "<p>Creates element with given tag in the DOM with given content.</p>\n",
            +            "itemtype": "method",
            +            "name": "createElement",
            +            "params": [
            +                {
            +                    "name": "tag",
            +                    "description": "<p>tag for the new element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "content",
            +                    "description": "<p>html content to be inserted into the element</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1504,
            +            "description": "<p>Adds specified class to the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "addClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to add</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1529,
            +            "description": "<p>Removes specified class from the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1560,
            +            "description": "<p>Checks if specified class already set to element</p>\n",
            +            "itemtype": "method",
            +            "name": "hasClass",
            +            "return": {
            +                "description": "a boolean value if element has specified class",
            +                "type": "Boolean"
            +            },
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name of class to check</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1589,
            +            "description": "<p>Toggles element class</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleClass",
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name to toggle</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1622,
            +            "description": "<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "child",
            +            "return": {
            +                "description": "an array of child nodes",
            +                "type": "Node[]"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1622,
            +                    "params": [],
            +                    "return": {
            +                        "description": "an array of child nodes",
            +                        "type": "Node[]"
            +                    }
            +                },
            +                {
            +                    "line": 1650,
            +                    "params": [
            +                        {
            +                            "name": "child",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n",
            +                            "type": "String|p5.Element",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1675,
            +            "description": "<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n",
            +            "itemtype": "method",
            +            "name": "center",
            +            "params": [
            +                {
            +                    "name": "align",
            +                    "description": "<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1726,
            +            "description": "<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "html",
            +            "return": {
            +                "description": "the inner HTML of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1726,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the inner HTML of the element",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1747,
            +                    "params": [
            +                        {
            +                            "name": "html",
            +                            "description": "<p>the HTML to be placed inside the element</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "append",
            +                            "description": "<p>whether to append HTML to existing</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1765,
            +            "description": "<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n",
            +            "itemtype": "method",
            +            "name": "position",
            +            "return": {
            +                "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1765,
            +                    "params": [],
            +                    "return": {
            +                        "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 1798,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "positionType",
            +                            "description": "<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1885,
            +            "description": "<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n",
            +            "itemtype": "method",
            +            "name": "style",
            +            "return": {
            +                "description": "value of property",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1885,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "<p>property to be set</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "value of property",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1923,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to property</p>\n",
            +                            "type": "String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1,
            +                    "return": {
            +                        "description": "current value of property, if no value is given as second argument",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1980,
            +            "description": "<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n",
            +            "itemtype": "method",
            +            "name": "attribute",
            +            "return": {
            +                "description": "value of attribute",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1980,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of attribute",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1995,
            +                    "params": [
            +                        {
            +                            "name": "attr",
            +                            "description": "<p>attribute to set</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to attribute</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2024,
            +            "description": "<p>Removes an attribute on the specified element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeAttribute",
            +            "params": [
            +                {
            +                    "name": "attr",
            +                    "description": "<p>attribute to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2069,
            +            "description": "<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "value",
            +            "return": {
            +                "description": "value of the element",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2069,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of the element",
            +                        "type": "String|Number"
            +                    }
            +                },
            +                {
            +                    "line": 2099,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2115,
            +            "description": "<p>Shows the current element. Essentially, setting display:block for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "show",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2133,
            +            "description": "<p>Hides the current element. Essentially, setting display:none for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "hide",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2149,
            +            "description": "<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the width and height of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2149,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the width and height of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 2173,
            +                    "params": [
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2230,
            +            "description": "<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2268,
            +            "description": "<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n",
            +            "itemtype": "method",
            +            "name": "drop",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to receive loaded file, called for each file dropped.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>callback triggered once when files are dropped with the drop event.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"
            +            ],
            +            "alt": "Canvas turns into whatever image is dragged/dropped onto it.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2400,
            +            "description": "<p>Path to the media element source.</p>\n",
            +            "itemtype": "property",
            +            "name": "src",
            +            "return": {
            +                "description": "src",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2466,
            +            "description": "<p>Play an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2530,
            +            "description": "<p>Stops an HTML5 media element (sets current time to zero).</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2594,
            +            "description": "<p>Pauses an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2656,
            +            "description": "<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2712,
            +            "description": "<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2778,
            +            "description": "<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n",
            +            "itemtype": "method",
            +            "name": "autoplay",
            +            "params": [
            +                {
            +                    "name": "shouldAutoplay",
            +                    "description": "<p>whether the element should autoplay</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2845,
            +            "description": "<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n",
            +            "itemtype": "method",
            +            "name": "volume",
            +            "return": {
            +                "description": "current volume",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2845,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current volume",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2918,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>volume between 0.0 and 1.0</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2931,
            +            "description": "<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n",
            +            "itemtype": "method",
            +            "name": "speed",
            +            "return": {
            +                "description": "current playback speed of the element",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2931,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current playback speed of the element",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3003,
            +                    "params": [
            +                        {
            +                            "name": "speed",
            +                            "description": "<p>speed multiplier for element playback</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3020,
            +            "description": "<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n",
            +            "itemtype": "method",
            +            "name": "time",
            +            "return": {
            +                "description": "current time (in seconds)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 3020,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current time (in seconds)",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3065,
            +                    "params": [
            +                        {
            +                            "name": "time",
            +                            "description": "<p>time to jump to (in seconds)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3079,
            +            "description": "<p>Returns the duration of the HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "duration",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3201,
            +            "description": "<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3232,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3234,
            +            "description": "<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "audioNode",
            +                    "description": "<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n",
            +                    "type": "AudioNode|Object"
            +                }
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3283,
            +            "description": "<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3298,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3300,
            +            "description": "<p>Show the default MediaElement controls, as determined by the web browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "showControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3331,
            +            "description": "<p>Hide the default mediaElement controls.</p>\n",
            +            "itemtype": "method",
            +            "name": "hideControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3360,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3371,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3434,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3476,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3542,
            +            "description": "<p>Underlying File object. All normal File methods can be called on this.</p>\n",
            +            "itemtype": "property",
            +            "name": "file",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3554,
            +            "description": "<p>File type (image, text, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "type",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3560,
            +            "description": "<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "subtype",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3566,
            +            "description": "<p>File name</p>\n",
            +            "itemtype": "property",
            +            "name": "name",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3572,
            +            "description": "<p>File size</p>\n",
            +            "itemtype": "property",
            +            "name": "size",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3579,
            +            "description": "<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n",
            +            "itemtype": "property",
            +            "name": "data",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 11,
            +            "description": "<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n",
            +            "itemtype": "property",
            +            "name": "deviceOrientation",
            +            "type": "Constant",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 23,
            +            "description": "<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 46,
            +            "description": "<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 69,
            +            "description": "<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 94,
            +            "description": "<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 104,
            +            "description": "<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 114,
            +            "description": "<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 135,
            +            "description": "<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 168,
            +            "description": "<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 201,
            +            "description": "<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "rotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 239,
            +            "description": "<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 285,
            +            "description": "<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 330,
            +            "description": "<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 389,
            +            "description": "<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n",
            +            "itemtype": "property",
            +            "name": "turnAxis",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 428,
            +            "description": "<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMoveThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 471,
            +            "description": "<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n",
            +            "itemtype": "method",
            +            "name": "setShakeThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 515,
            +            "description": "<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceMoved",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 546,
            +            "description": "<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceTurned",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 604,
            +            "description": "<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceShaken",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device shakes",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 10,
            +            "description": "<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect that turns black on keypress.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 36,
            +            "description": "<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n",
            +            "itemtype": "property",
            +            "name": "key",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"
            +            ],
            +            "alt": "canvas displays any key value that is pressed in pink font.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 64,
            +            "description": "<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyCode",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"
            +            ],
            +            "alt": "Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 103,
            +            "description": "<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyPressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 190,
            +            "description": "<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when pressed again",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 243,
            +            "description": "<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyTyped",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when 'a' key typed and black when 'b' pressed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 298,
            +            "description": "<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 308,
            +            "description": "<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyIsDown",
            +            "params": [
            +                {
            +                    "name": "code",
            +                    "description": "<p>The key to check for.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether key is down or not",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 12,
            +            "description": "<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"
            +            ],
            +            "alt": "box moves left and right according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 43,
            +            "description": "<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "box moves up and down according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 80,
            +            "description": "<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal black line moves left and right with mouse x-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 106,
            +            "description": "<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black line moves up and down with mouse y-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 132,
            +            "description": "<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "line trail is created from cursor movements. faster movement make longer line.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 164,
            +            "description": "<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect center, fuchsia background. rect flickers on mouse movement",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 195,
            +            "description": "<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 233,
            +            "description": "<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 271,
            +            "description": "<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 311,
            +            "description": "<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 351,
            +            "description": "<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseButton",
            +            "type": "Constant",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 389,
            +            "description": "<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 481,
            +            "description": "<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 535,
            +            "description": "<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseDragged",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 615,
            +            "description": "<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 696,
            +            "description": "<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 772,
            +            "description": "<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 841,
            +            "description": "<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 926,
            +            "description": "<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional WheelEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect moves up and down with vertical scroll. fuchsia background",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 979,
            +            "description": "<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n",
            +            "itemtype": "method",
            +            "name": "requestPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3D scene moves according to mouse mouse movement in a first person perspective",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 1025,
            +            "description": "<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n",
            +            "itemtype": "method",
            +            "name": "exitPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "cursor gets locked / unlocked on mouse-click",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 10,
            +            "description": "<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n",
            +            "itemtype": "property",
            +            "name": "touches",
            +            "type": "Object[]",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Number of touches currently registered are displayed on the canvas",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 71,
            +            "description": "<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch event.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 151,
            +            "description": "<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns lighter with touch until white. resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 223,
            +            "description": "<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/image/filters.js",
            +            "line": 3,
            +            "description": "<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n",
            +            "class": "p5",
            +            "module": "Events"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 8,
            +            "description": "<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 15,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImage",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width in pixels</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height in pixels</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 94,
            +            "description": "<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveCanvas",
            +            "example": [
            +                "\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed\n no image displayed\n no image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 94,
            +                    "params": [
            +                        {
            +                            "name": "selectedCanvas",
            +                            "description": "<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n",
            +                            "type": "p5.Element|HTMLCanvasElement"
            +                        },
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "<p>'jpg' or 'png'</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 413,
            +            "description": "<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveFrames",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'jpg' or 'png'</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Duration in seconds to save the frames for.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "framerate",
            +                    "description": "<p>Framerate to save the frames in.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n",
            +                    "type": "Function(Array)",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"
            +            ],
            +            "alt": "canvas background goes from light to dark with mouse x.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 18,
            +            "description": "<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadImage",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path of the image to be loaded</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n",
            +                    "type": "function(p5.Image)",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "failureCallback",
            +                    "description": "<p>called with event error if\n                               the image fails to load.</p>\n",
            +                    "type": "Function(Event)",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 162,
            +            "description": "<p>Helper function for loading GIF-based images</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 301,
            +            "description": "<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n",
            +            "itemtype": "method",
            +            "name": "image",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 301,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "<p>the image to display</p>\n",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "width",
            +                            "description": "<p>the width to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "height",
            +                            "description": "<p>the height to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 388,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dWidth",
            +                            "description": "<p>the width of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dHeight",
            +                            "description": "<p>the height of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sWidth",
            +                            "description": "<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "sHeight",
            +                            "description": "<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 471,
            +            "description": "<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n",
            +            "itemtype": "method",
            +            "name": "tint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 471,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 542,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 553,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 559,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the tint color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 569,
            +            "description": "<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n",
            +            "itemtype": "method",
            +            "name": "noTint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of bricks, left image with blue tint",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 633,
            +            "description": "<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n",
            +            "itemtype": "method",
            +            "name": "imageMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, or CENTER</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 9,
            +            "description": "<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 88,
            +            "description": "<p>Image width.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains in top and horizontal lines in corresponding colors in bottom.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 115,
            +            "description": "<p>Image height.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains on right and vertical lines in corresponding colors on left.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 152,
            +            "description": "<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 222,
            +            "description": "<p>Helper function for animating GIF-based images with time</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 253,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 261,
            +            "description": "<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 296,
            +            "description": "<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 296,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 338,
            +                    "params": []
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 346,
            +            "description": "<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with 50×50 green rect in front",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 346,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 383,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 387,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 400,
            +            "description": "<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"
            +            ],
            +            "alt": "2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 437,
            +            "description": "<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n",
            +            "itemtype": "method",
            +            "name": "resize",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>the resized image width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>the resized image height</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. zoomed in",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 548,
            +            "description": "<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains and smaller image on top of bricks at top left",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 548,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 588,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 603,
            +            "description": "<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mask",
            +            "params": [
            +                {
            +                    "name": "srcImage",
            +                    "description": "<p>source image</p>\n",
            +                    "type": "p5.Image"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 665,
            +            "description": "<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains left one in color, right in black and white",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 738,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 738,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 815,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 859,
            +            "description": "<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>give your file a name</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'png' or 'jpg'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 900,
            +            "description": "<p>Starts an animated GIF over at the beginning state.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 941,
            +            "description": "<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "getCurrentFrame",
            +            "return": {
            +                "description": "The index for the currently displaying frame in animated GIF",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 972,
            +            "description": "<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "setFrame",
            +            "params": [
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index for the frame that should be displayed</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1017,
            +            "description": "<p>Returns the number of frames in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "numFrames",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1052,
            +            "description": "<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1089,
            +            "description": "<p>Pauses an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1125,
            +            "description": "<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n",
            +            "itemtype": "method",
            +            "name": "delay",
            +            "params": [
            +                {
            +                    "name": "d",
            +                    "description": "<p>the amount in milliseconds to delay between switching frames</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index of the frame that should have the new delay value {optional}</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 12,
            +            "description": "<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"
            +            ],
            +            "alt": "top half of canvas pink, bottom grey",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 80,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 80,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 152,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 173,
            +            "description": "<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 173,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 215,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 307,
            +            "description": "<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 481,
            +            "description": "<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 551,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 555,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 566,
            +            "description": "<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 602,
            +            "description": "<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 674,
            +            "description": "<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 20,
            +            "description": "<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadJSON",
            +            "return": {
            +                "description": "JSON data",
            +                "type": "Object|Array"
            +            },
            +            "example": [
            +                "\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 20,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "jsonpOptions",
            +                            "description": "<p>options object for jsonp related settings</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\" or \"jsonp\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "JSON data",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 104,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 112,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 183,
            +            "description": "<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadStrings",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 303,
            +            "description": "<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadTable",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "header",
            +                    "description": "<p>\"header\" to indicate table has header row</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Table\">Table</a> object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 583,
            +            "description": "<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadXML",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "XML object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 693,
            +            "description": "<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadBytes",
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if there\n                                   is an error</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an object whose 'bytes' property will be the loaded buffer",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 752,
            +            "description": "<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n",
            +            "itemtype": "method",
            +            "name": "httpGet",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 752,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 806,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 814,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 829,
            +            "description": "<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpPost",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 896,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 904,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 919,
            +            "description": "<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpDo",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 919,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "method",
            +                            "description": "<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 990,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "options",
            +                            "description": "<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1155,
            +            "itemtype": "method",
            +            "name": "createWriter",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the file to be created</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.PrintWriter"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1210,
            +            "description": "<p>Writes data to the PrintWriter stream</p>\n",
            +            "itemtype": "method",
            +            "name": "write",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be written by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1269,
            +            "description": "<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be printed by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1310,
            +            "description": "<p>Clears the data already written to the PrintWriter object</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1344,
            +            "description": "<p>Closes the PrintWriter</p>\n",
            +            "itemtype": "method",
            +            "name": "close",
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1393,
            +            "description": "<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "objectOrFilename",
            +                    "description": "<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n",
            +                    "type": "Object|String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n",
            +                    "type": "Boolean|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"
            +            ],
            +            "alt": "An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1535,
            +            "description": "<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "params": [
            +                {
            +                    "name": "json",
            +                    "description": "",
            +                    "type": "Array|Object"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "optimize",
            +                    "description": "<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1592,
            +            "description": "<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveStrings",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>string array to be written</p>\n",
            +                    "type": "String[]"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>filename for output</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>the filename's extension</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isCRLF",
            +                    "description": "<p>if true, change line-break to CRLF</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1656,
            +            "description": "<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "params": [
            +                {
            +                    "name": "Table",
            +                    "description": "<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n",
            +                    "type": "p5.Table"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>the filename to which the Table should be saved</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 9,
            +            "description": "<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 43,
            +            "description": "<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n",
            +            "itemtype": "property",
            +            "name": "columns",
            +            "type": "String[]",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 77,
            +            "description": "<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n",
            +            "itemtype": "property",
            +            "name": "rows",
            +            "type": "p5.TableRow[]",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 85,
            +            "description": "<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n",
            +            "itemtype": "method",
            +            "name": "addRow",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row to be added to the table</p>\n",
            +                    "type": "p5.TableRow",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the row that was added",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 148,
            +            "description": "<p>Removes a row from the table object.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeRow",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID number of the row to remove</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 195,
            +            "description": "<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRow",
            +            "params": [
            +                {
            +                    "name": "rowID",
            +                    "description": "<p>ID number of the row to get</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 240,
            +            "description": "<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRows",
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 288,
            +            "description": "<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRow",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 352,
            +            "description": "<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRows",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 420,
            +            "description": "<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRow",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String|RegExp"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "TableRow object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 478,
            +            "description": "<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRows",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 545,
            +            "description": "<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>String or Number of the column to return</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of column values",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 597,
            +            "description": "<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearRows",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 638,
            +            "description": "<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n",
            +            "itemtype": "method",
            +            "name": "addColumn",
            +            "params": [
            +                {
            +                    "name": "title",
            +                    "description": "<p>title of the given column</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 688,
            +            "description": "<p>Returns the total number of columns in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumnCount",
            +            "return": {
            +                "description": "Number of columns in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 724,
            +            "description": "<p>Returns the total number of rows in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRowCount",
            +            "return": {
            +                "description": "Number of rows in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 760,
            +            "description": "<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeTokens",
            +            "params": [
            +                {
            +                    "name": "chars",
            +                    "description": "<p>String listing characters to be removed</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 832,
            +            "description": "<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 896,
            +            "description": "<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 960,
            +            "description": "<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1009,
            +            "description": "<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1055,
            +            "description": "<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1100,
            +            "description": "<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1146,
            +            "description": "<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1190,
            +            "description": "<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1242,
            +            "description": "<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getObject",
            +            "params": [
            +                {
            +                    "name": "headerColumn",
            +                    "description": "<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1305,
            +            "description": "<p>Retrieves all table data and returns it as a multidimensional array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getArray",
            +            "return": {
            +                "description": "",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 40,
            +            "description": "<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 102,
            +            "description": "<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a Float</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 146,
            +            "description": "<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a String</p>\n",
            +                    "type": "String|Number|Boolean|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 191,
            +            "description": "<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 239,
            +            "description": "<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "Float Floating point number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 295,
            +            "description": "<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 62,
            +            "description": "<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "getParent",
            +            "return": {
            +                "description": "element parent",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 100,
            +            "description": "<p>Gets the element's full name, which is returned as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "getName",
            +            "return": {
            +                "description": "the name of the node",
            +                "type": "String"
            +            },
            +            "example": [
            +                "&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 135,
            +            "description": "<p>Sets the element's name, which is specified as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "setName",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>new name of the node</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 181,
            +            "description": "<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasChildren",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 217,
            +            "description": "<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "listChildren",
            +            "return": {
            +                "description": "names of the children of the element",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 258,
            +            "description": "<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChildren",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "children of the element",
            +                "type": "p5.XML[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 314,
            +            "description": "<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 374,
            +            "description": "<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "addChild",
            +            "params": [
            +                {
            +                    "name": "node",
            +                    "description": "<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n",
            +                    "type": "p5.XML"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 426,
            +            "description": "<p>Removes the element specified by name or index.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 498,
            +            "description": "<p>Counts the specified element's number of attributes, returned as an Number.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAttributeCount",
            +            "return": {
            +                "description": "",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 534,
            +            "description": "<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n",
            +            "itemtype": "method",
            +            "name": "listAttributes",
            +            "return": {
            +                "description": "an array of strings containing the names of attributes",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 577,
            +            "description": "<p>Checks whether or not an element has the specified attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasAttribute",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>attribute to be checked</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "true if attribute found else false",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 622,
            +            "description": "<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 669,
            +            "description": "<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 716,
            +            "description": "<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttribute",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value of the attribute</p>\n",
            +                    "type": "Number|String|Boolean"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 757,
            +            "description": "<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getContent",
            +            "params": [
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>value returned if no content is found</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 798,
            +            "description": "<p>Sets the element's content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setContent",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>the new content</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 839,
            +            "description": "<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n",
            +            "itemtype": "method",
            +            "name": "serialize",
            +            "return": {
            +                "description": "Serialized string of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 10,
            +            "description": "<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n",
            +            "itemtype": "method",
            +            "name": "abs",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to compute</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "absolute value of given number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 33,
            +            "description": "<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n",
            +            "itemtype": "method",
            +            "name": "ceil",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round up</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded up number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 72,
            +            "description": "<p>Constrains a value between a minimum and maximum value.</p>\n",
            +            "itemtype": "method",
            +            "name": "constrain",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to constrain</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "low",
            +                    "description": "<p>minimum limit</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "high",
            +                    "description": "<p>maximum limit</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "constrained number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"
            +            ],
            +            "alt": "2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 116,
            +            "description": "<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "distance between the two points",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"
            +            ],
            +            "alt": "2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 116,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 161,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 182,
            +            "description": "<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n",
            +            "itemtype": "method",
            +            "name": "exp",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>exponent to raise</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "e^n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. e^n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 231,
            +            "description": "<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n",
            +            "itemtype": "method",
            +            "name": "floor",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round down</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded down number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 269,
            +            "description": "<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "params": [
            +                {
            +                    "name": "start",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "lerped value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"
            +            ],
            +            "alt": "5 points horizontally staggered mid-canvas. mid 3 are grey, outer black",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 316,
            +            "description": "<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number greater than 0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "natural logarithm of n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. natural logarithm of n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 371,
            +            "description": "<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "magnitude of vector from (0,0) to (a,b)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"
            +            ],
            +            "alt": "4 lines of different length radiate from top left of canvas.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 409,
            +            "description": "<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n",
            +            "itemtype": "method",
            +            "name": "map",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the incoming value to be converted</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start1",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop1",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start2",
            +                    "description": "<p>lower bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop2",
            +                    "description": "<p>upper bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "withinBounds",
            +                    "description": "<p>constrain the value to the newly mapped range</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "remapped number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"
            +            ],
            +            "alt": "10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 464,
            +            "description": "<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "max",
            +            "return": {
            +                "description": "maximum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 464,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "maximum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 499,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 512,
            +            "description": "<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "min",
            +            "return": {
            +                "description": "minimum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "minimum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 560,
            +            "description": "<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n",
            +            "itemtype": "method",
            +            "name": "norm",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>incoming value to be normalized</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "normalized number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves with mouse. 0 shown left & 100 right and updating values center",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 612,
            +            "description": "<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n",
            +            "itemtype": "method",
            +            "name": "pow",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>base of the exponential expression</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>power by which to raise the base</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "n^e",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"
            +            ],
            +            "alt": "small to large ellipses radiating from top left of canvas",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 646,
            +            "description": "<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n",
            +            "itemtype": "method",
            +            "name": "round",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decimals",
            +                    "description": "<p>number of decimal places to round to, default is 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 701,
            +            "description": "<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sq",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to square</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "squared number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squared values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 745,
            +            "description": "<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n",
            +            "itemtype": "method",
            +            "name": "sqrt",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>non-negative number to square root</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "square root of number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squareroot values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 832,
            +            "description": "<p>Calculates the fractional part of a number.</p>\n",
            +            "itemtype": "method",
            +            "name": "fract",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>Number whose fractional part needs to be found out</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "fractional part of x, i.e, {x}",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"
            +            ],
            +            "alt": "first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/math.js",
            +            "line": 10,
            +            "description": "<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVector",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"
            +            ],
            +            "alt": "draws a line from center of canvas to mouse pointer position.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 36,
            +            "description": "<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n",
            +            "itemtype": "method",
            +            "name": "noise",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate in noise space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Perlin noise value (between 0 and 1) at specified\n                     coordinates",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 178,
            +            "description": "<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseDetail",
            +            "params": [
            +                {
            +                    "name": "lod",
            +                    "description": "<p>number of octaves to be used by the noise</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "falloff",
            +                    "description": "<p>falloff factor for each octave</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "2 vertical grey smokey patterns affected my mouse x-position and noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 243,
            +            "description": "<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical grey lines drawing in pattern affected by noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 69,
            +            "description": "<p>The x component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "x",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 74,
            +            "description": "<p>The y component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "y",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 79,
            +            "description": "<p>The z component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "z",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 86,
            +            "description": "<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 136,
            +            "description": "<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 195,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to set</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 219,
            +            "description": "<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "return": {
            +                "description": "the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 248,
            +            "description": "<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 248,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to be added</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 325,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to add</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2059,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 372,
            +            "description": "<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "rem",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 372,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 401,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>divisor vector</p>\n",
            +                            "type": "p5.Vector | Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2085,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2091,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 461,
            +            "description": "<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 461,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to subtract</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 538,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to subtract</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2110,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 562,
            +            "description": "<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 562,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to multiply with the vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 655,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to multiply with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to multiply with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to multiply with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 663,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to multiply with the components of the vector</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 669,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to multiply with the components of the original vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2139,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2148,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2156,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2164,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 754,
            +            "description": "<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 754,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to divide the vector by</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 847,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to divide with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to divide with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to divide with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 855,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to divide the components of the vector by</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 861,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to divide the components of the original vector by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2218,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2227,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2235,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2243,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 959,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "return": {
            +                "description": "magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 959,
            +                    "params": [],
            +                    "return": {
            +                        "description": "magnitude of the vector",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2343,
            +                    "params": [
            +                        {
            +                            "name": "vecT",
            +                            "description": "<p>the vector to return the magnitude of</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the magnitude of vecT",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1007,
            +            "description": "<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n",
            +            "itemtype": "method",
            +            "name": "magSq",
            +            "return": {
            +                "description": "squared magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1061,
            +            "description": "<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "dot",
            +            "return": {
            +                "description": "the dot product",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1061,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2270,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1103,
            +            "description": "<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "cross",
            +            "return": {
            +                "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1103,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2284,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the cross product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1145,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "the distance",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1145,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2299,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1217,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "return": {
            +                "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1217,
            +                    "params": [],
            +                    "return": {
            +                        "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2360,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vector to normalize</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "v normalized to a length of 1",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1287,
            +            "description": "<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "limit",
            +            "params": [
            +                {
            +                    "name": "max",
            +                    "description": "<p>the maximum magnitude for the vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1345,
            +            "description": "<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMag",
            +            "params": [
            +                {
            +                    "name": "len",
            +                    "description": "<p>the new length for this vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1401,
            +            "description": "<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "heading",
            +            "return": {
            +                "description": "the angle of rotation",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1473,
            +            "description": "<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "setHeading",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1498,
            +            "description": "<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1498,
            +                    "params": [
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>the angle of rotation</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2191,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1567,
            +            "description": "<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleBetween",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "return": {
            +                "description": "the angle between (in radians)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1647,
            +            "description": "<p>Linear interpolate the vector to another vector</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1647,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1720,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2314,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the lerped value",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1736,
            +            "description": "<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n",
            +            "itemtype": "method",
            +            "name": "reflect",
            +            "params": [
            +                {
            +                    "name": "surfaceNormal",
            +                    "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1791,
            +            "description": "<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n",
            +            "itemtype": "method",
            +            "name": "array",
            +            "return": {
            +                "description": "an Array with the 3 values",
            +                "type": "Number[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1823,
            +            "description": "<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +            "itemtype": "method",
            +            "name": "equals",
            +            "return": {
            +                "description": "whether the vectors are equals",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1823,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "whether the vectors are equals",
            +                        "type": "Boolean"
            +                    }
            +                },
            +                {
            +                    "line": 1853,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to compare</p>\n",
            +                            "type": "p5.Vector|Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Boolean"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1878,
            +            "description": "<p>Make a new 2D vector from an angle</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngle",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1929,
            +            "description": "<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngles",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "theta",
            +                    "description": "<p>the polar angle, in radians (zero is up)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "phi",
            +                    "description": "<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1978,
            +            "description": "<p>Make a new 2D unit vector from a random angle</p>\n",
            +            "itemtype": "method",
            +            "name": "random2D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2031,
            +            "description": "<p>Make a new random 3D unit vector.</p>\n",
            +            "itemtype": "method",
            +            "name": "random3D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2135,
            +            "description": "<p>Multiplies a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2187,
            +            "description": "<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2214,
            +            "description": "<p>Divides a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2267,
            +            "description": "<p>Calculates the dot product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2281,
            +            "description": "<p>Calculates the cross product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2295,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2310,
            +            "description": "<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2339,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2357,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 37,
            +            "description": "<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "many vertical lines drawn in white, black or grey.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 66,
            +            "description": "<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n",
            +            "itemtype": "method",
            +            "name": "random",
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"
            +            ],
            +            "alt": "100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random",
            +            "overloads": [
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "min",
            +                            "description": "<p>the lower bound (inclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>the upper bound (exclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 119,
            +                    "params": [
            +                        {
            +                            "name": "choices",
            +                            "description": "<p>the array to choose from</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random element from the array",
            +                        "type": "*"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 153,
            +            "description": "<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomGaussian",
            +            "params": [
            +                {
            +                    "name": "mean",
            +                    "description": "<p>the mean</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sd",
            +                    "description": "<p>the standard deviation</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 18,
            +            "description": "<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "acos",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc cosine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc cosine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 53,
            +            "description": "<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "asin",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc sine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc sine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 88,
            +            "description": "<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc tangent is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 123,
            +            "description": "<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan2",
            +            "params": [
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given point",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60 by 10 rect at center of canvas rotates with mouse movements",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 159,
            +            "description": "<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "cos",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the cosine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines form wave patterns, extend-down on left and right side",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 186,
            +            "description": "<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sin",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the sine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines extend down and up from center to form wave pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 213,
            +            "description": "<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n",
            +            "itemtype": "method",
            +            "name": "tan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"
            +            ],
            +            "alt": "vertical black lines end down and up from center to form spike pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 239,
            +            "description": "<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "degrees",
            +            "params": [
            +                {
            +                    "name": "radians",
            +                    "description": "<p>the radians value to convert to degrees</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 262,
            +            "description": "<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "radians",
            +            "params": [
            +                {
            +                    "name": "degrees",
            +                    "description": "<p>the degree value to convert to radians</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 285,
            +            "description": "<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either RADIANS or DEGREES</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"
            +            ],
            +            "alt": "40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 11,
            +            "description": "<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAlign",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"
            +            ],
            +            "alt": "Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "horizAlign",
            +                            "description": "<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "vertAlign",
            +                            "description": "<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n",
            +                            "type": "Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 72,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 81,
            +            "description": "<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "textLeading",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"
            +            ],
            +            "alt": "A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 81,
            +                    "params": [
            +                        {
            +                            "name": "leading",
            +                            "description": "<p>the size in pixels for spacing between lines</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 109,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 118,
            +            "description": "<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "textSize",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 118,
            +                    "params": [
            +                        {
            +                            "name": "theSize",
            +                            "description": "<p>the size of the letters in units of pixels</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 141,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 150,
            +            "description": "<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n",
            +            "itemtype": "method",
            +            "name": "textStyle",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 150,
            +                    "params": [
            +                        {
            +                            "name": "theStyle",
            +                            "description": "<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 178,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 187,
            +            "description": "<p>Calculates and returns the width of any character or text string.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWidth",
            +            "params": [
            +                {
            +                    "name": "theText",
            +                    "description": "<p>the String of characters to measure</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the calculated width",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"
            +            ],
            +            "alt": "Letter P and p5.js are displayed with vertical lines at end.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 222,
            +            "description": "<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAscent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 251,
            +            "description": "<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textDescent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 280,
            +            "description": "<p>Helper function to measure ascent and descent.</p>\n",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 287,
            +            "description": "<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWrap",
            +            "params": [
            +                {
            +                    "name": "wrapStyle",
            +                    "description": "<p>text wrapping style, either WORD or CHAR</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "return": {
            +                "description": "wrapStyle",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 16,
            +            "description": "<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadFont",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "onError",
            +                    "description": "<p>function to be executed if\n                                   an error occurs</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Font\">p5.Font</a> object",
            +                "type": "p5.Font"
            +            },
            +            "example": [
            +                "\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"
            +            ],
            +            "alt": "p5*js in p5's theme dark pink\np5*js in p5's theme dark pink",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 140,
            +            "description": "<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "text",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the alphanumeric\n                                            symbols to be displayed</p>\n",
            +                    "type": "String|Object|Array|Number|Boolean"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 231,
            +            "description": "<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n",
            +            "itemtype": "method",
            +            "name": "textFont",
            +            "return": {
            +                "description": "the current font / p5 Object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 231,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the current font / p5 Object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "font",
            +                            "description": "<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n",
            +                            "type": "Object|String"
            +                        },
            +                        {
            +                            "name": "size",
            +                            "description": "<p>the font size to use</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 24,
            +            "description": "<p>Underlying opentype font implementation</p>\n",
            +            "itemtype": "property",
            +            "name": "font",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 31,
            +            "description": "<p>Returns a tight bounding box for the given text string using this\nfont</p>\n",
            +            "itemtype": "method",
            +            "name": "textBounds",
            +            "params": [
            +                {
            +                    "name": "line",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional) Default is 12.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a rectangle object with properties: x, y, w, h",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "words Lorem ipsum dol go off canvas and contained by white bounding box",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 175,
            +            "description": "<p>Computes an array of points following the path for specified text</p>\n",
            +            "itemtype": "method",
            +            "name": "textToPoints",
            +            "params": [
            +                {
            +                    "name": "txt",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an array of points, each with x, y, alpha (the path angle)",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 10,
            +            "description": "<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n",
            +            "itemtype": "method",
            +            "name": "append",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to append</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>to be added to the Array</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "return": {
            +                "description": "the array that was appended to",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 35,
            +            "description": "<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "arrayCopy",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions",
            +            "overloads": [
            +                {
            +                    "line": 35,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>the source Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "srcPosition",
            +                            "description": "<p>starting position in the source Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "<p>the destination Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dstPosition",
            +                            "description": "<p>starting position in the destination Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "<p>number of Array elements to be copied</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 73,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 112,
            +            "description": "<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n",
            +            "itemtype": "method",
            +            "name": "concat",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first Array to concatenate</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second Array to concatenate</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "concatenated array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 141,
            +            "description": "<p>Reverses the order of an array, maps to Array.reverse()</p>\n",
            +            "itemtype": "method",
            +            "name": "reverse",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to reverse</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "the reversed list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 161,
            +            "description": "<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n",
            +            "itemtype": "method",
            +            "name": "shorten",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to shorten</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "shortened Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 185,
            +            "description": "<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "shuffle",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to shuffle</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "bool",
            +                    "description": "<p>modify passed array</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "shuffled Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 227,
            +            "description": "<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n",
            +            "itemtype": "method",
            +            "name": "sort",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to sort</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of elements to sort, starting from 0</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the sorted list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 273,
            +            "description": "<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n",
            +            "itemtype": "method",
            +            "name": "splice",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to splice into</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to be spliced in</p>\n",
            +                    "type": "Any"
            +                },
            +                {
            +                    "name": "position",
            +                    "description": "<p>in the array from which to insert data</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 308,
            +            "description": "<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n",
            +            "itemtype": "method",
            +            "name": "subset",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to extract from</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>position to begin</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of values to extract</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of extracted elements",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 10,
            +            "description": "<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "float",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>float string to parse</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "floating point representation of string",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "alt": "20 by 20 white ellipse in the center of the canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 44,
            +            "description": "<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "int",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 44,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "<p>the radix to convert to (default: 10)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 88,
            +            "description": "<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "str",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 114,
            +            "description": "<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n",
            +            "itemtype": "method",
            +            "name": "boolean",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "boolean representation of value",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 146,
            +            "description": "<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "byte",
            +            "return": {
            +                "description": "byte representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 146,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "byte representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 168,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of byte representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 182,
            +            "description": "<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "char",
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 182,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 201,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 216,
            +            "description": "<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unchar",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 216,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 232,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 245,
            +            "description": "<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "hex",
            +            "return": {
            +                "description": "hexadecimal string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 245,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 265,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>array of values to parse</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 295,
            +            "description": "<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unhex",
            +            "return": {
            +                "description": "integer representation of hexadecimal value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 295,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of hexadecimal value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representations of hexadecimal value",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 15,
            +            "description": "<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n",
            +            "itemtype": "method",
            +            "name": "join",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>array of Strings to be joined</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>String to be placed between each item</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "joined String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"hello world!\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 43,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "match",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"p5js*\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 83,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "matchAll",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "2d Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 130,
            +            "description": "<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nf",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" middle top, -1321.00\" middle bottom canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 237,
            +            "description": "<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfc",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 237,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                                 decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 311,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfp",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 352,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 373,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfs",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" top middle and \"-1321.00\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 373,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 430,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 451,
            +            "description": "<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n",
            +            "itemtype": "method",
            +            "name": "split",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>the String used to separate the data</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 484,
            +            "description": "<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n",
            +            "itemtype": "method",
            +            "name": "splitTokens",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>list of individual Strings that will be used as\n                         separators</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 537,
            +            "description": "<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "return": {
            +                "description": "a trimmed String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"No new lines here\" displayed center canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 537,
            +                    "params": [
            +                        {
            +                            "name": "str",
            +                            "description": "<p>a String to be trimmed</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "a trimmed String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 557,
            +                    "params": [
            +                        {
            +                            "name": "strs",
            +                            "description": "<p>an Array of Strings to be trimmed</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "an Array of trimmed Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 10,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n",
            +            "itemtype": "method",
            +            "name": "day",
            +            "return": {
            +                "description": "the current day",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current day is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 31,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n",
            +            "itemtype": "method",
            +            "name": "hour",
            +            "return": {
            +                "description": "the current hour",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current hour is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 52,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "minute",
            +            "return": {
            +                "description": "the current minute",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current minute is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 73,
            +            "description": "<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n",
            +            "itemtype": "method",
            +            "name": "millis",
            +            "return": {
            +                "description": "the number of milliseconds since starting the sketch",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"
            +            ],
            +            "alt": "number of milliseconds since sketch has started displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 100,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n",
            +            "itemtype": "method",
            +            "name": "month",
            +            "return": {
            +                "description": "the current month",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current month is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 122,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "second",
            +            "return": {
            +                "description": "the current second",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current second is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 143,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n",
            +            "itemtype": "method",
            +            "name": "year",
            +            "return": {
            +                "description": "the current year",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current year is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 13,
            +            "description": "<p>Draw a plane with given a width and height</p>\n",
            +            "itemtype": "method",
            +            "name": "plane",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 97,
            +            "description": "<p>Draw a box with given width, height and depth</p>\n",
            +            "itemtype": "method",
            +            "name": "box",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "Height",
            +                    "description": "<p>height of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "depth",
            +                    "description": "<p>depth of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 215,
            +            "description": "<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "sphere",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of circle</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>optional number of subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>optional number of subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 419,
            +            "description": "<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cylinder",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cylinder</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottomCap",
            +                    "description": "<p>whether to draw the bottom of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "topCap",
            +                    "description": "<p>whether to draw the top of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 554,
            +            "description": "<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cone",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the bottom surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cone</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cap",
            +                    "description": "<p>whether to draw the base of the cone</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 669,
            +            "description": "<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipsoid",
            +            "params": [
            +                {
            +                    "name": "radiusx",
            +                    "description": "<p>x-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusy",
            +                    "description": "<p>y-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusz",
            +                    "description": "<p>z-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 804,
            +            "description": "<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n",
            +            "itemtype": "method",
            +            "name": "torus",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the whole ring</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tubeRadius",
            +                    "description": "<p>radius of the tube</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 11,
            +            "description": "<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n",
            +            "itemtype": "method",
            +            "name": "orbitControl",
            +            "params": [
            +                {
            +                    "name": "sensitivityX",
            +                    "description": "<p>sensitivity to mouse movement along X axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityY",
            +                    "description": "<p>sensitivity to mouse movement along Y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityZ",
            +                    "description": "<p>sensitivity to scroll movement along Z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Camera orbits around a box when mouse is hold-clicked & then moved.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 145,
            +            "description": "<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n",
            +            "itemtype": "method",
            +            "name": "debugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction",
            +            "overloads": [
            +                {
            +                    "line": 145,
            +                    "params": []
            +                },
            +                {
            +                    "line": 278,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either GRID or AXES</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 283,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "gridSize",
            +                            "description": "<p>size of one side of the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "<p>number of divisions in the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "<p>X axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "<p>Y axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "<p>Z axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "<p>size of axes icon</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 302,
            +                    "params": [
            +                        {
            +                            "name": "gridSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 353,
            +            "description": "<p>Turns off debugMode() in a 3D sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noDebugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 11,
            +            "description": "<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "evenly distributed light across a sphere\nevenly distributed light across a rotating sphere",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>the alpha value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 51,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 57,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 64,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 92,
            +            "description": "<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularColor",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "different specular light sources from top and bottom of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 92,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 145,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 151,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 158,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 177,
            +            "description": "<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "directionalLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "light source on canvas changeable with mouse position",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 177,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 210,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis direction</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 220,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 227,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 280,
            +            "description": "<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "pointLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "spot light on canvas changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 322,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 331,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 341,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 387,
            +            "description": "<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "lights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "the light is partially ambient and partially directional",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 425,
            +            "description": "<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n",
            +            "itemtype": "method",
            +            "name": "lightFalloff",
            +            "params": [
            +                {
            +                    "name": "constant",
            +                    "description": "<p>constant value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "linear",
            +                    "description": "<p>linear value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "quadratic",
            +                    "description": "<p>quadratic value for determining falloff</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two spheres with different falloff values show different intensity of light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 519,
            +            "description": "<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "spotLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Spot light on a sphere which changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 519,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "<p>x axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "<p>y axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "<p>z axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>optional parameter for angle. Defaults to PI/3</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "<p>optional parameter for concentration. Defaults to 100</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 571,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 580,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 590,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 600,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 610,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 634,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 859,
            +            "description": "<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Three white spheres. Each appears as a different\ncolor due to lighting.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 12,
            +            "description": "<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadModel",
            +            "return": {
            +                "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                "type": "p5.Geometry"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d teapot with red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models",
            +            "overloads": [
            +                {
            +                    "line": 12,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>Path of the model to be loaded</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "normalize",
            +                            "description": "<p>If true, scale the model to a\n                                     standardized size when loading</p>\n",
            +                            "type": "Boolean"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "<p>called with event error if\n                                        the model fails to load.</p>\n",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                },
            +                {
            +                    "line": 96,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 179,
            +            "description": "<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 290,
            +            "description": "<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 317,
            +            "description": "<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 344,
            +            "description": "<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 356,
            +            "description": "<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 444,
            +            "description": "<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 588,
            +            "description": "<p>Render a 3d model to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "model",
            +            "params": [
            +                {
            +                    "name": "model",
            +                    "description": "<p>Loaded 3d model to be rendered</p>\n",
            +                    "type": "p5.Geometry"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d octahedron.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 12,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadShader",
            +            "params": [
            +                {
            +                    "name": "vertFilename",
            +                    "description": "<p>path to file containing vertex shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragFilename",
            +                    "description": "<p>path to file containing fragment shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shader files.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 111,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "createShader",
            +            "params": [
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shaders.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 184,
            +            "description": "<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "shader",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "s",
            +                    "description": "<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n",
            +                    "type": "p5.Shader"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 282,
            +            "description": "<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "resetShader",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 368,
            +            "description": "<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "texture",
            +            "params": [
            +                {
            +                    "name": "tex",
            +                    "description": "<p>image to use as texture</p>\n",
            +                    "type": "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using normalized coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 511,
            +            "description": "<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n",
            +            "itemtype": "method",
            +            "name": "textureMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either IMAGE or NORMAL</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using image coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 587,
            +            "description": "<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n",
            +            "itemtype": "method",
            +            "name": "textureWrap",
            +            "params": [
            +                {
            +                    "name": "wrapX",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "wrapY",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "an image of the rocky mountains repeated in mirrored tiles",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 659,
            +            "description": "<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 697,
            +            "description": "<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 697,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 757,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 777,
            +            "description": "<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n",
            +            "itemtype": "method",
            +            "name": "emissiveMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 777,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 809,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 829,
            +            "description": "<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "torus with specular material",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 870,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 882,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 902,
            +            "description": "<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "shininess",
            +            "params": [
            +                {
            +                    "name": "shine",
            +                    "description": "<p>Degree of Shininess.\n                      Defaults to 1.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Shininess on Camera changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 13,
            +            "description": "<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>camera position value on x axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>camera position value on y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>camera position value on z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerX",
            +                    "description": "<p>x coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerY",
            +                    "description": "<p>y coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerZ",
            +                    "description": "<p>z coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upX",
            +                    "description": "<p>x component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upY",
            +                    "description": "<p>y component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upZ",
            +                    "description": "<p>z component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 115,
            +            "description": "<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "params": [
            +                {
            +                    "name": "fovy",
            +                    "description": "<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "aspect",
            +                    "description": "<p>camera frustum aspect ratio</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>frustum near plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>frustum far plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 176,
            +            "description": "<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 236,
            +            "description": "<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 303,
            +            "description": "<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCamera",
            +            "return": {
            +                "description": "The newly created camera object.",
            +                "type": "p5.Camera"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"
            +            ],
            +            "alt": "An example that creates a camera and moves it around the box.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 444,
            +            "description": "<p>camera position value on x axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 472,
            +            "description": "<p>camera position value on y axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 499,
            +            "description": "<p>camera position value on z axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 526,
            +            "description": "<p>x coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 554,
            +            "description": "<p>y coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 582,
            +            "description": "<p>z coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 610,
            +            "description": "<p>x component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 633,
            +            "description": "<p>y component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 656,
            +            "description": "<p>z component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 683,
            +            "description": "<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 801,
            +            "description": "<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 897,
            +            "description": "<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1040,
            +            "description": "<p>Panning rotates the camera view to the left and right.</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1098,
            +            "description": "<p>Tilting rotates the camera view up and down.</p>\n",
            +            "itemtype": "method",
            +            "name": "tilt",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view tilts up and down across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1156,
            +            "description": "<p>Reorients the camera to look at a position in world space.</p>\n",
            +            "itemtype": "method",
            +            "name": "lookAt",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view of rotating 3D cubes changes to look at a new random\npoint every second .",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1223,
            +            "description": "<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1386,
            +            "description": "<p>Move camera along its local axes while maintaining current camera orientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "move",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>amount to move along camera's left-right axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>amount to move along camera's up-down axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>amount to move along camera's forward-backward axis</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1458,
            +            "description": "<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "setPosition",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera position changes as the user presses keys, altering view of a 3D box",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1723,
            +            "description": "<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n",
            +            "itemtype": "method",
            +            "name": "setCamera",
            +            "params": [
            +                {
            +                    "name": "cam",
            +                    "description": "<p>p5.Camera object</p>\n",
            +                    "type": "p5.Camera"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Canvas switches between two camera views, each showing a series of spinning\n3D boxes.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 71,
            +            "description": "<p>computes faces for geometry objects based on the vertices.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeFaces",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 114,
            +            "description": "<p>computes smooth normals per vertex as an average of each\nface.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 153,
            +            "description": "<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n",
            +            "itemtype": "method",
            +            "name": "averageNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 174,
            +            "description": "<p>Averages pole normals.  Used in spherical primitives</p>\n",
            +            "itemtype": "method",
            +            "name": "averagePoleNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 267,
            +            "description": "<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 334,
            +            "description": "<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttributes",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a rotating cube with smoother edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "overloads": [
            +                {
            +                    "line": 334,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "<p>Name of attribute</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>New value of named attribute</p>\n",
            +                            "type": "Boolean"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 473,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>object with key-value pairs</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 306,
            +            "description": "<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n",
            +            "itemtype": "method",
            +            "name": "setUniform",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "uniformName",
            +                    "description": "<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "data",
            +                    "description": "<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n",
            +                    "type": "Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5.Shader",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1,
            +            "class": "p5.sound",
            +            "module": "3D"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 52,
            +            "description": "<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n",
            +            "class": "p5.sound",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 159,
            +            "description": "<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>",
            +            "itemtype": "method",
            +            "name": "getAudioContext",
            +            "return": {
            +                "description": "AudioContext for this sketch",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 198,
            +            "description": "<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>",
            +            "params": [
            +                {
            +                    "name": "element(s)",
            +                    "description": "<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n",
            +                    "type": "Element|Array",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback to invoke when the AudioContext\n                              has started</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that resolves when\n                                     the AudioContext state is 'running'",
            +                "type": "Promise"
            +            },
            +            "itemtype": "method",
            +            "name": "userStartAudio",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 401,
            +            "description": "<p>This module has shims</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 536,
            +            "description": "<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 726,
            +            "description": "<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOutputVolume",
            +            "return": {
            +                "description": "Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 738,
            +            "description": "<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>",
            +            "itemtype": "method",
            +            "name": "outputVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 782,
            +            "description": "<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n",
            +            "itemtype": "property",
            +            "name": "soundOut",
            +            "type": "Object",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 807,
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 811,
            +            "description": "<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "samplerate samples per second",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 825,
            +            "description": "<p>Returns the closest MIDI note value for\na given frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "freqToMidi",
            +            "params": [
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "MIDI note value",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 841,
            +            "description": "<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n",
            +            "itemtype": "method",
            +            "name": "midiToFreq",
            +            "params": [
            +                {
            +                    "name": "midiNote",
            +                    "description": "<p>The number of a MIDI note</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency value of the given MIDI note",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 925,
            +            "description": "<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n",
            +            "itemtype": "method",
            +            "name": "soundFormats",
            +            "params": [
            +                {
            +                    "name": "formats",
            +                    "description": "<p>i.e. 'mp3', 'wav', 'ogg'</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1040,
            +            "description": "<p>Used by Osc and Envelope to chain signal math</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1145,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveSound",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile that you wish to save</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1662,
            +            "description": "<p>Returns true if the sound file finished loading successfully.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLoaded",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1679,
            +            "description": "<p>Play the p5.SoundFile</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule playback to start (in seconds from now).</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) amplitude (volume)\n                                    of playback</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueStart",
            +                    "description": "<p>(optional) cue start time in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) duration of playback in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1787,
            +            "description": "<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "playMode",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>'restart' or 'sustain' or 'untilDone'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1847,
            +            "description": "<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                             seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1905,
            +            "description": "<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) playback volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueLoopStart",
            +                    "description": "<p>(optional) startTime in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) loop duration in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1950,
            +            "description": "<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "setLoop",
            +            "params": [
            +                {
            +                    "name": "Boolean",
            +                    "description": "<p>set looping to true or false</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1976,
            +            "description": "<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1997,
            +            "description": "<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPlaying",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2011,
            +            "description": "<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPaused",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2025,
            +            "description": "<p>Stop soundfile playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            in seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2087,
            +            "description": "<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panValue",
            +                    "description": "<p>Set the stereo panner</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                                seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2131,
            +            "description": "<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2146,
            +            "description": "<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "rate",
            +            "params": [
            +                {
            +                    "name": "playbackRate",
            +                    "description": "<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2239,
            +            "description": "<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "setVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2276,
            +            "description": "<p>Returns the duration of a sound file in seconds.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "The duration of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2293,
            +            "description": "<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n",
            +            "itemtype": "method",
            +            "name": "currentTime",
            +            "return": {
            +                "description": "currentTime of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2308,
            +            "description": "<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n",
            +            "itemtype": "method",
            +            "name": "jump",
            +            "params": [
            +                {
            +                    "name": "cueTime",
            +                    "description": "<p>cueTime of the soundFile in seconds.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>duration in seconds.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2340,
            +            "description": "<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n",
            +            "itemtype": "method",
            +            "name": "channels",
            +            "return": {
            +                "description": "[channels]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2354,
            +            "description": "<p>Return the sample rate of the sound file.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "[sampleRate]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2367,
            +            "description": "<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n",
            +            "itemtype": "method",
            +            "name": "frames",
            +            "return": {
            +                "description": "[sampleCount]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2381,
            +            "description": "<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPeaks",
            +            "params": [
            +                {
            +                    "name": "length",
            +                    "description": "<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of peaks.",
            +                "type": "Float32Array"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2443,
            +            "description": "<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n",
            +            "itemtype": "method",
            +            "name": "reverseBuffer",
            +            "example": [
            +                "\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2497,
            +            "description": "<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2565,
            +            "description": "<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>Audio object that accepts an input</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2590,
            +            "description": "<p>Disconnects the output of this p5sound object.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2604,
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2612,
            +            "description": "<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n",
            +            "itemtype": "method",
            +            "name": "setPath",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to audio file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2630,
            +            "description": "<p>Replace the current Audio Buffer with a new Buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBuffer",
            +            "params": [
            +                {
            +                    "name": "buf",
            +                    "description": "<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2719,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2790,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2817,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2850,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2882,
            +            "description": "<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBlob",
            +            "return": {
            +                "description": "A file-like data object",
            +                "type": "Blob"
            +            },
            +            "example": [
            +                "\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2946,
            +            "description": "<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadSound",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoading",
            +                    "description": "<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a p5.SoundFile",
            +                "type": "SoundFile"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3117,
            +            "description": "<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "snd",
            +                    "description": "<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n",
            +                    "type": "SoundObject|undefined",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n",
            +                    "type": "Number|undefined",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3209,
            +            "description": "<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "channel",
            +                    "description": "<p>Optionally return only channel 0 (left) or 1 (right)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Amplitude as a number between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3264,
            +            "description": "<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleNormalize",
            +            "params": [
            +                {
            +                    "name": "boolean",
            +                    "description": "<p>set normalize to true (1) or false (0)</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3293,
            +            "description": "<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "set",
            +                    "description": "<p>smoothing from 0.0 <= 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3476,
            +            "description": "<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "source",
            +                    "description": "<p>p5.sound object (or web audio API source node)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3501,
            +            "description": "<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n",
            +            "itemtype": "method",
            +            "name": "waveform",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "precision",
            +                    "description": "<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3553,
            +            "description": "<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "analyze",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "scale",
            +                    "description": "<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3650,
            +            "description": "<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getEnergy",
            +            "params": [
            +                {
            +                    "name": "frequency1",
            +                    "description": "<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "frequency2",
            +                    "description": "<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Energy   Energy (volume/amplitude) from\n                            0 and 255.",
            +                "type": "Number"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3739,
            +            "description": "<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getCentroid",
            +            "return": {
            +                "description": "Spectral Centroid Frequency  of the spectral centroid in Hz.",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3826,
            +            "description": "<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3854,
            +            "description": "<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "linAverages",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Number of returned frequency groups</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "linearAverages   Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3889,
            +            "description": "<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "logAverages",
            +            "params": [
            +                {
            +                    "name": "octaveBands",
            +                    "description": "<p>Array of Octave Bands objects for grouping</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "logAverages    Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3925,
            +            "description": "<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOctaveBands",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Specifies the 1/N type of generated octave bands</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fCtr0",
            +                    "description": "<p>Minimum central frequency for the lowest band</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "octaveBands   Array of octave band objects with their bounds",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4168,
            +            "description": "<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>startTime in seconds from now.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>frequency in Hz.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4218,
            +            "description": "<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>Time, in seconds from now.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4238,
            +            "description": "<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)",
            +                "type": "AudioParam"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4271,
            +            "description": "<p>Returns the value of output gain</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmp",
            +            "return": {
            +                "description": "Amplitude value between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4285,
            +            "description": "<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "Frequency",
            +                    "description": "<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Ramp time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen\n                                 at x seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency",
            +                "type": "AudioParam"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4360,
            +            "description": "<p>Returns the value of frequency of oscillator</p>\n",
            +            "itemtype": "method",
            +            "name": "getFreq",
            +            "return": {
            +                "description": "Frequency of oscillator in Hertz",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4373,
            +            "description": "<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4386,
            +            "description": "<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "getType",
            +            "return": {
            +                "description": "type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4399,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4420,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4444,
            +            "description": "<p>Pan between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panning",
            +                    "description": "<p>Number between -1 and 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4460,
            +            "description": "<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "panPosition of oscillator , between Left (-1) and Right (1)",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4494,
            +            "description": "<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "phase",
            +            "params": [
            +                {
            +                    "name": "phase",
            +                    "description": "<p>float between 0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4522,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4543,
            +            "description": "<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with multiplied output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4563,
            +            "description": "<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4767,
            +            "description": "<p>Time until envelope reaches attackLevel</p>\n",
            +            "itemtype": "property",
            +            "name": "attackTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4772,
            +            "description": "<p>Level once attack is complete.</p>\n",
            +            "itemtype": "property",
            +            "name": "attackLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4778,
            +            "description": "<p>Time until envelope reaches decayLevel.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4784,
            +            "description": "<p>Level after decay. The envelope will sustain here until it is released.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4790,
            +            "description": "<p>Duration of the release portion of the envelope.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4796,
            +            "description": "<p>Level at the end of the release.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4833,
            +            "description": "<p>Reset the envelope with a series of time/value pairs.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "attackLevel",
            +                    "description": "<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayLevel",
            +                    "description": "<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Release Time (in seconds)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseLevel",
            +                    "description": "<p>Amplitude</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4895,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4964,
            +            "description": "<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRange",
            +            "params": [
            +                {
            +                    "name": "aLevel",
            +                    "description": "<p>attack level (defaults to 1)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rLevel",
            +                    "description": "<p>release level (defaults to 0)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5037,
            +            "description": "<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "inputs",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5055,
            +            "description": "<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n",
            +            "itemtype": "method",
            +            "name": "setExp",
            +            "params": [
            +                {
            +                    "name": "isExp",
            +                    "description": "<p>true is exponential, false is linear</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5078,
            +            "description": "<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5148,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5256,
            +            "description": "<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5350,
            +            "description": "<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n",
            +            "itemtype": "method",
            +            "name": "ramp",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>When to trigger the ramp</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v",
            +                    "description": "<p>Target value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v2",
            +                    "description": "<p>Second target value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5460,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5479,
            +            "description": "<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5498,
            +            "description": "<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5657,
            +            "description": "<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'white', 'pink' or 'brown'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Noise",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5871,
            +            "description": "<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n",
            +            "itemtype": "method",
            +            "name": "width",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Pulse",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6066,
            +            "itemtype": "property",
            +            "name": "input",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6070,
            +            "itemtype": "property",
            +            "name": "output",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6075,
            +            "itemtype": "property",
            +            "name": "stream",
            +            "type": "MediaStream|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6080,
            +            "itemtype": "property",
            +            "name": "mediaStream",
            +            "type": "MediaStreamAudioSourceNode|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6085,
            +            "itemtype": "property",
            +            "name": "currentSource",
            +            "type": "Number|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6090,
            +            "description": "<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n",
            +            "itemtype": "property",
            +            "name": "enabled",
            +            "type": "Boolean",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6098,
            +            "description": "<p>Input amplitude, connect to it by default but not to master out</p>\n",
            +            "itemtype": "property",
            +            "name": "amplitude",
            +            "type": "p5.Amplitude",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6114,
            +            "description": "<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call on\n                                  success.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6171,
            +            "description": "<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6191,
            +            "description": "<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>An object that accepts audio input,\n                        such as an FFT</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6216,
            +            "description": "<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6234,
            +            "description": "<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Volume level (between 0.0 and 1.0)",
            +                "type": "Number"
            +            },
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6257,
            +            "description": "<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>ramp time (optional)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6280,
            +            "description": "<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n",
            +            "itemtype": "method",
            +            "name": "getSources",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>This optional callback receives the error\n                                   message as its argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6340,
            +            "description": "<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "setSource",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>position of input source in the array</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6462,
            +            "description": "<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6478,
            +            "description": "<p>Set the output volume of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts until rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tFromNow",
            +                    "description": "<p>schedule this event to happen in tFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6502,
            +            "description": "<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n",
            +            "itemtype": "method",
            +            "name": "chain",
            +            "params": [
            +                {
            +                    "name": "arguments",
            +                    "description": "<p>Chain together multiple sound objects</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6525,
            +            "description": "<p>Adjust the dry/wet value.</p>\n",
            +            "itemtype": "method",
            +            "name": "drywet",
            +            "params": [
            +                {
            +                    "name": "fade",
            +                    "description": "<p>The desired drywet value (0 - 1.0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6542,
            +            "description": "<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6557,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6719,
            +            "description": "<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "biquadFilter",
            +            "type": "DelayNode",
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6742,
            +            "description": "<p>Filter an audio signal according to a set\nof filter parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6760,
            +            "description": "<p>Set the frequency and the resonance of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance (Q) from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6781,
            +            "description": "<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Filter Frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value  Returns the current frequency value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6811,
            +            "description": "<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "res",
            +            "params": [
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value Returns the current res value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6838,
            +            "description": "<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n",
            +            "itemtype": "method",
            +            "name": "gain",
            +            "params": [
            +                {
            +                    "name": "gain",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns the current or updated gain value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6864,
            +            "description": "<p>Toggle function. Switches between the specified type and allpass</p>\n",
            +            "itemtype": "method",
            +            "name": "toggle",
            +            "return": {
            +                "description": "[Toggle value]",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6884,
            +            "description": "<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "t",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7198,
            +            "description": "<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n",
            +            "itemtype": "property",
            +            "name": "bands",
            +            "type": "Array",
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7239,
            +            "description": "<p>Process an input by connecting it to the EQ</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Audio source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7629,
            +            "description": "<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n",
            +            "itemtype": "property",
            +            "name": "panner",
            +            "type": "AudioNode",
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7654,
            +            "description": "<p>Connect an audio sorce</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Input source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7668,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7687,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7694,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7701,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7753,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "orient",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7772,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7779,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7786,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7838,
            +            "description": "<p>Set the rolloff factor and max distance</p>\n",
            +            "itemtype": "method",
            +            "name": "setFalloff",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7852,
            +            "description": "<p>Maxium distance between the source and the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "maxDist",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7869,
            +            "description": "<p>How quickly the volume is reduced as the source moves away from the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "rollof",
            +            "params": [
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7989,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "leftDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7999,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "rightDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8049,
            +            "description": "<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "lowPass",
            +                    "description": "<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8094,
            +            "description": "<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n",
            +            "itemtype": "method",
            +            "name": "delayTime",
            +            "params": [
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8116,
            +            "description": "<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n",
            +            "itemtype": "method",
            +            "name": "feedback",
            +            "params": [
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "return": {
            +                "description": "Feedback value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8148,
            +            "description": "<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "cutoffFreq",
            +                    "description": "<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8170,
            +            "description": "<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'pingPong' (1) or 'default' (0)</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8223,
            +            "description": "<p>Set the output level of the delay effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8234,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8242,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8409,
            +            "description": "<p>Connect a source to the reverb, and assign reverb parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8446,
            +            "description": "<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8482,
            +            "description": "<p>Set the output level of the reverb effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8493,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8501,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8621,
            +            "description": "<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "convolverNode",
            +            "type": "ConvolverNode",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8645,
            +            "description": "<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n",
            +            "itemtype": "property",
            +            "name": "impulses",
            +            "type": "Array",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8737,
            +            "description": "<p>Connect a source to the convolver.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8786,
            +            "description": "<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n",
            +            "itemtype": "method",
            +            "name": "addImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8808,
            +            "description": "<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8831,
            +            "description": "<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleImpulse",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8885,
            +            "description": "<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n",
            +            "itemtype": "method",
            +            "name": "createConvolver",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Convolver"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9084,
            +            "description": "<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9173,
            +            "description": "<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n",
            +            "itemtype": "property",
            +            "name": "sequence",
            +            "type": "Array",
            +            "class": "p5.Phrase",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9263,
            +            "description": "<p>Set the tempo of this part, in Beats Per Minute.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9278,
            +            "description": "<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBPM",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9291,
            +            "description": "<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9311,
            +            "description": "<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9333,
            +            "description": "<p>Tell the part to stop looping.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9349,
            +            "description": "<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9363,
            +            "description": "<p>Pause the part. Playback will resume\nfrom the current step.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9379,
            +            "description": "<p>Add a p5.Phrase to this Part.</p>\n",
            +            "itemtype": "method",
            +            "name": "addPhrase",
            +            "params": [
            +                {
            +                    "name": "phrase",
            +                    "description": "<p>reference to a p5.Phrase</p>\n",
            +                    "type": "p5.Phrase"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9406,
            +            "description": "<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n",
            +            "itemtype": "method",
            +            "name": "removePhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9424,
            +            "description": "<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9442,
            +            "description": "<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n",
            +            "itemtype": "method",
            +            "name": "replaceSequence",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9473,
            +            "description": "<p>Set the function that will be called at every step. This will clear the previous function.</p>\n",
            +            "itemtype": "method",
            +            "name": "onStep",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9542,
            +            "description": "<p>Start playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9555,
            +            "description": "<p>Stop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9569,
            +            "description": "<p>Pause playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9581,
            +            "description": "<p>Loop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9594,
            +            "description": "<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9628,
            +            "description": "<p>Set the tempo for all parts in the score</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9729,
            +            "description": "<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n",
            +            "itemtype": "property",
            +            "name": "bpm",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9750,
            +            "description": "<p>number of quarter notes in a measure (defaults to 4)</p>\n",
            +            "itemtype": "property",
            +            "name": "timeSignature",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9770,
            +            "description": "<p>length of the loops interval</p>\n",
            +            "itemtype": "property",
            +            "name": "interval",
            +            "type": "Number|String",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9787,
            +            "description": "<p>how many times the callback has been called so far</p>\n",
            +            "itemtype": "property",
            +            "name": "iterations",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9800,
            +            "description": "<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n",
            +            "itemtype": "property",
            +            "name": "musicalTimeMode",
            +            "type": "Boolean",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9808,
            +            "description": "<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9816,
            +            "description": "<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n",
            +            "itemtype": "property",
            +            "name": "maxIterations",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9826,
            +            "description": "<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9841,
            +            "description": "<p>Start the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a starting time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9860,
            +            "description": "<p>Stop the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a stopping time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9878,
            +            "description": "<p>Pause the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a pausing time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9896,
            +            "description": "<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n",
            +            "itemtype": "method",
            +            "name": "syncedStart",
            +            "params": [
            +                {
            +                    "name": "otherLoop",
            +                    "description": "<p>a p5.SoundLoop to sync with</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Start the loops in sync after timeFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10068,
            +            "description": "<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n",
            +            "itemtype": "property",
            +            "name": "compressor",
            +            "type": "AudioNode",
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10084,
            +            "description": "<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Sound source to be connected</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10112,
            +            "description": "<p>Set the paramters of a compressor.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10152,
            +            "description": "<p>Get current attack or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "attack",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10178,
            +            "description": "<p>Get current knee or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "knee",
            +            "params": [
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10204,
            +            "description": "<p>Get current ratio or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "ratio",
            +            "params": [
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10228,
            +            "description": "<p>Get current threshold or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "threshold",
            +            "params": [
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10252,
            +            "description": "<p>Get current release or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "release",
            +            "params": [
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10277,
            +            "description": "<p>Return the current reduction value</p>\n",
            +            "itemtype": "method",
            +            "name": "reduction",
            +            "return": {
            +                "description": "Value of the amount of gain reduction that is applied to the signal",
            +                "type": "Number"
            +            },
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10419,
            +            "description": "<p>isDetected is set to true when a peak is detected.</p>\n",
            +            "itemtype": "attribute",
            +            "name": "isDetected",
            +            "type": "Boolean",
            +            "default": "false",
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10432,
            +            "description": "<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n",
            +            "itemtype": "method",
            +            "name": "update",
            +            "params": [
            +                {
            +                    "name": "fftObject",
            +                    "description": "<p>A p5.FFT object</p>\n",
            +                    "type": "p5.FFT"
            +                }
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10470,
            +            "description": "<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onPeak",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "val",
            +                    "description": "<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10676,
            +            "description": "<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10703,
            +            "description": "<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n",
            +            "itemtype": "method",
            +            "name": "record",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that will be\n                              called once the recording completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10739,
            +            "description": "<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10864,
            +            "description": "<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "WaveShaperNode",
            +            "type": "AudioNode",
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10883,
            +            "description": "<p>Process a sound source, optionally specify amount and oversample values.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10900,
            +            "description": "<p>Set the amount and oversample of the waveshaper distortion.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10923,
            +            "description": "<p>Return the distortion amount, typically between 0-1.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmount",
            +            "return": {
            +                "description": "Unbounded distortion amount.\n                 Normal values range from 0-1.",
            +                "type": "Number"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10937,
            +            "description": "<p>Return the oversampling.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOversample",
            +            "return": {
            +                "description": "Oversample can either be 'none', '2x', or '4x'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11055,
            +            "description": "<p>Connect a source to the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11070,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11084,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11098,
            +            "description": "<p>Set the output level of the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11181,
            +            "description": "<p>Connect to p5 objects or Web Audio Nodes</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11194,
            +            "description": "<p>Disconnect from soundOut</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11322,
            +            "description": "<p>Getters and Setters</p>\n",
            +            "itemtype": "property",
            +            "name": "attack",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11328,
            +            "itemtype": "property",
            +            "name": "decay",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11333,
            +            "itemtype": "property",
            +            "name": "sustain",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11338,
            +            "itemtype": "property",
            +            "name": "release",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11379,
            +            "description": "<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11431,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11478,
            +            "description": "<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11516,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11544,
            +            "description": "<p>MonoSynth amp</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>desired volume</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Time to reach new volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "new volume value",
            +                "type": "Number"
            +            },
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11564,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11578,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11592,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11742,
            +            "description": "<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n",
            +            "itemtype": "property",
            +            "name": "notes",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11755,
            +            "description": "<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n",
            +            "itemtype": "property",
            +            "name": "polyvalue",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11761,
            +            "description": "<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n",
            +            "itemtype": "property",
            +            "name": "AudioVoice",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11800,
            +            "description": "<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11849,
            +            "description": "<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteADSR",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>Midi note on which ADSR should be set.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11881,
            +            "description": "<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11909,
            +            "description": "<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteAttack",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)/</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12021,
            +            "description": "<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteRelease",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12105,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12119,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12133,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        }
            +    ],
            +    "warnings": [
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:120"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:216"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:316"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:457"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:1001"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:223"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:248"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/validate_params.js:336"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:219"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:259"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:185"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:264"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:358"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:398"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:493"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:67"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:293"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:460"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:524"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:583"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:668"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:733"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:826"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:84"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:120"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:138"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:79"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:129"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:160"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:228"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:372"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:390"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:405"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:421"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:500"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:550"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:586"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:660"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:691"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:713"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:42"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:47"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:154"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:189"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:246"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:292"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:403"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:454"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:510"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:551"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:639"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:678"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:725"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:763"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:70"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:7"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:34"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:87"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:137"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:158"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:179"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:200"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:267"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:309"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:379"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:408"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:448"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:490"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:326"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:134"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:192"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:290"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:391"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:497"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:193"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:232"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:304"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:342"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:416"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:455"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:494"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:101"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1560"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1622"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1726"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1765"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1885"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2778"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:23"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:46"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:69"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:135"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:201"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:285"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:330"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:428"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:515"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:546"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:604"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:64"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:103"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:308"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:106"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:132"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:164"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:233"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:271"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:615"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:696"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:772"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:841"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:926"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:979"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:1025"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:71"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:151"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:94"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:413"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:18"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:301"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:569"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:88"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:152"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:261"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:296"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:346"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:400"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:437"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:548"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:665"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:738"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:900"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:941"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:972"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1017"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1052"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1089"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:173"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:307"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:566"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:602"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:674"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:583"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1393"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:85"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:148"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:240"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:352"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:545"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:597"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:638"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:896"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:960"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1009"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1055"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1242"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1305"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:40"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:191"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:295"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.XML.js:9"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:33"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:72"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:116"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:182"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:269"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:316"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:371"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:409"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:464"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:560"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:612"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:646"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:701"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:745"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/math.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:178"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/p5.Vector.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:37"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:153"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:123"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:159"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:186"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:213"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:285"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:320"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:335"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:350"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:118"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:150"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:187"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:16"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:140"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/p5.Font.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/conversion.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:237"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:373"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:451"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:537"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:73"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:143"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/3d_primitives.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:353"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:177"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:280"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:387"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:425"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:519"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:588"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:12"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:282"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:587"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:659"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:697"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:777"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:829"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:902"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:176"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:236"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:357"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:444"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:472"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:499"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:526"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:554"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:582"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:610"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:683"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:801"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:897"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1040"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1098"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1156"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1386"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1458"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1723"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:334"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:644"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:749"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Shader.js:306"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:115"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:158"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:191"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:236"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:250"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:456"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:471"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:556"
            +        },
            +        {
            +            "message": "replacing incorrect tag: params with param",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2882"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4360"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4386"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4460"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:6280"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:8116"
            +        },
            +        {
            +            "message": "Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.",
            +            "line": " src/color/color_conversion.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:19"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to RGBA.",
            +            "line": " src/color/color_conversion.js:45"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to HSBA.",
            +            "line": " src/color/color_conversion.js:100"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.",
            +            "line": " src/color/color_conversion.js:123"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSBA.",
            +            "line": " src/color/color_conversion.js:187"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:226"
            +        },
            +        {
            +            "message": "Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.",
            +            "line": " src/color/p5.Color.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.",
            +            "line": " src/color/p5.Color.js:427"
            +        },
            +        {
            +            "message": "Missing item type\nCSS named colors.",
            +            "line": " src/color/p5.Color.js:446"
            +        },
            +        {
            +            "message": "Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.",
            +            "line": " src/color/p5.Color.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nFull color string patterns. The capture groups are necessary.",
            +            "line": " src/color/p5.Color.js:613"
            +        },
            +        {
            +            "message": "Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.",
            +            "line": " src/color/p5.Color.js:750"
            +        },
            +        {
            +            "message": "Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.",
            +            "line": " src/color/p5.Color.js:960"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/fes_core.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.",
            +            "line": " src/core/friendly_errors/fes_core.js:915"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/file_errors.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/sketch_reader.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/stacktrace.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nGiven an Error object, extract the most information from it.",
            +            "line": " src/core/friendly_errors/stacktrace.js:34"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/validate_params.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).",
            +            "line": " src/core/shape/2d_primitives.js:16"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current framerate.",
            +            "line": " src/core/environment.js:305"
            +        },
            +        {
            +            "message": "Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.",
            +            "line": " src/core/environment.js:315"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/helpers.js:1"
            +        },
            +        {
            +            "message": "Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing",
            +            "line": " src/core/init.js:4"
            +        },
            +        {
            +            "message": "Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.",
            +            "line": " src/core/internationalization.js:30"
            +        },
            +        {
            +            "message": "Missing item type\nSet up our translation function, with loaded languages",
            +            "line": " src/core/internationalization.js:126"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a list of languages we have translations loaded for",
            +            "line": " src/core/internationalization.js:171"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current language selected for translation",
            +            "line": " src/core/internationalization.js:178"
            +        },
            +        {
            +            "message": "Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.",
            +            "line": " src/core/internationalization.js:185"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/legacy.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/core/p5.Element.js:827"
            +        },
            +        {
            +            "message": "Missing item type\nResize our canvas element.",
            +            "line": " src/core/p5.Renderer.js:99"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to check font type (system or otf)",
            +            "line": " src/core/p5.Renderer.js:415"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178",
            +            "line": " src/core/p5.Renderer.js:467"
            +        },
            +        {
            +            "message": "Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer",
            +            "line": " src/core/p5.Renderer2D.js:7"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.",
            +            "line": " src/core/p5.Renderer2D.js:402"
            +        },
            +        {
            +            "message": "Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.",
            +            "line": " src/core/shim.js:18"
            +        },
            +        {
            +            "message": "Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign",
            +            "line": " src/core/shim.js:39"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()",
            +            "line": " src/data/p5.TypedDict.js:197"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:387"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:425"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:536"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for select and selectAll",
            +            "line": " src/dom/dom.js:127"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for getElement and getElements.",
            +            "line": " src/dom/dom.js:142"
            +        },
            +        {
            +            "message": "Missing item type\nHelpers for create methods.",
            +            "line": " src/dom/dom.js:309"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:450"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1164"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1257"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1296"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3232"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3298"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3360"
            +        },
            +        {
            +            "message": "Missing item type\n_updatePAccelerations updates the pAcceleration values",
            +            "line": " src/events/acceleration.js:124"
            +        },
            +        {
            +            "message": "Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.",
            +            "line": " src/events/keyboard.js:298"
            +        },
            +        {
            +            "message": "Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.",
            +            "line": " src/events/keyboard.js:384"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.",
            +            "line": " src/image/filters.js:3"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the pixel buffer for a canvas",
            +            "line": " src/image/filters.js:24"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.",
            +            "line": " src/image/filters.js:60"
            +        },
            +        {
            +            "message": "Missing item type\nModifies pixels RGBA values to values contained in the data object.",
            +            "line": " src/image/filters.js:81"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData",
            +            "line": " src/image/filters.js:101"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a blank ImageData object.",
            +            "line": " src/image/filters.js:121"
            +        },
            +        {
            +            "message": "Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.",
            +            "line": " src/image/filters.js:136"
            +        },
            +        {
            +            "message": "Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:189"
            +        },
            +        {
            +            "message": "Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:223"
            +        },
            +        {
            +            "message": "Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.",
            +            "line": " src/image/filters.js:246"
            +        },
            +        {
            +            "message": "Missing item type\nSets each pixel to its inverse value. No parameter is used.",
            +            "line": " src/image/filters.js:262"
            +        },
            +        {
            +            "message": "Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation",
            +            "line": " src/image/filters.js:277"
            +        },
            +        {
            +            "message": "Missing item type\nreduces the bright areas in an image",
            +            "line": " src/image/filters.js:309"
            +        },
            +        {
            +            "message": "Missing item type\nincreases the bright areas in an image",
            +            "line": " src/image/filters.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.",
            +            "line": " src/image/image.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for loading GIF-based images",
            +            "line": " src/image/loading_displaying.js:162"
            +        },
            +        {
            +            "message": "Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.",
            +            "line": " src/image/loading_displaying.js:597"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.",
            +            "line": " src/image/p5.Image.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for animating GIF-based images with time",
            +            "line": " src/image/p5.Image.js:222"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/image/p5.Image.js:253"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.",
            +            "line": " src/io/files.js:1789"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.",
            +            "line": " src/io/files.js:1857"
            +        },
            +        {
            +            "message": "Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.",
            +            "line": " src/io/files.js:1890"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.",
            +            "line": " src/io/files.js:1902"
            +        },
            +        {
            +            "message": "Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "line": " src/io/p5.Table.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nMultiplies a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2135"
            +        },
            +        {
            +            "message": "Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2187"
            +        },
            +        {
            +            "message": "Missing item type\nDivides a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2214"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the dot product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2267"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the cross product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2281"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).",
            +            "line": " src/math/p5.Vector.js:2295"
            +        },
            +        {
            +            "message": "Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.",
            +            "line": " src/math/p5.Vector.js:2310"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)",
            +            "line": " src/math/p5.Vector.js:2339"
            +        },
            +        {
            +            "message": "Missing item type\nNormalize the vector to length 1 (make it a unit vector).",
            +            "line": " src/math/p5.Vector.js:2357"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to measure ascent and descent.",
            +            "line": " src/typography/attributes.js:280"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.",
            +            "line": " src/typography/p5.Font.js:273"
            +        },
            +        {
            +            "message": "Missing item type\nReturns an opentype path for the supplied string and position.",
            +            "line": " src/typography/p5.Font.js:288"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/3d_primitives.js:301"
            +        },
            +        {
            +            "message": "Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.",
            +            "line": " src/webgl/3d_primitives.js:955"
            +        },
            +        {
            +            "message": "Missing item type\nDraw a line given two points",
            +            "line": " src/webgl/3d_primitives.js:1393"
            +        },
            +        {
            +            "message": "Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1",
            +            "line": " src/webgl/loading.js:179"
            +        },
            +        {
            +            "message": "Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.",
            +            "line": " src/webgl/loading.js:290"
            +        },
            +        {
            +            "message": "Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.",
            +            "line": " src/webgl/loading.js:317"
            +        },
            +        {
            +            "message": "Missing item type\nThis function matches the `query` at the provided `offset`",
            +            "line": " src/webgl/loading.js:344"
            +        },
            +        {
            +            "message": "Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.",
            +            "line": " src/webgl/loading.js:356"
            +        },
            +        {
            +            "message": "Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`",
            +            "line": " src/webgl/loading.js:444"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:947"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:978"
            +        },
            +        {
            +            "message": "Missing item type\nCreate a 2D array for establishing stroke connections",
            +            "line": " src/webgl/p5.Geometry.js:212"
            +        },
            +        {
            +            "message": "Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU",
            +            "line": " src/webgl/p5.Geometry.js:233"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/p5.Matrix.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPRIVATE",
            +            "line": " src/webgl/p5.Matrix.js:722"
            +        },
            +        {
            +            "message": "Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.",
            +            "line": " src/webgl/p5.RenderBuffer.js:12"
            +        },
            +        {
            +            "message": "Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nEnd shape drawing and render vertices to screen.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:129"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:169"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:248"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:268"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:302"
            +        },
            +        {
            +            "message": "Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:59"
            +        },
            +        {
            +            "message": "Missing item type\nDraws buffers given a geometry key ID",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:110"
            +        },
            +        {
            +            "message": "Missing item type\nmodel view, projection, & normal\nmatrices",
            +            "line": " src/webgl/p5.RendererGL.js:117"
            +        },
            +        {
            +            "message": "Missing item type\n[background description]",
            +            "line": " src/webgl/p5.RendererGL.js:586"
            +        },
            +        {
            +            "message": "Missing item type\n[resize description]",
            +            "line": " src/webgl/p5.RendererGL.js:860"
            +        },
            +        {
            +            "message": "Missing item type\nclears color and depth buffers\nwith r,g,b,a",
            +            "line": " src/webgl/p5.RendererGL.js:890"
            +        },
            +        {
            +            "message": "Missing item type\n[translate description]",
            +            "line": " src/webgl/p5.RendererGL.js:924"
            +        },
            +        {
            +            "message": "Missing item type\nScales the Model View Matrix by a vector",
            +            "line": " src/webgl/p5.RendererGL.js:943"
            +        },
            +        {
            +            "message": "Missing item type\nturn a two dimensional array into one dimensional array",
            +            "line": " src/webgl/p5.RendererGL.js:1366"
            +        },
            +        {
            +            "message": "Missing item type\nturn a p5.Vector Array into a one dimensional number array",
            +            "line": " src/webgl/p5.RendererGL.js:1403"
            +        },
            +        {
            +            "message": "Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.",
            +            "line": " src/webgl/p5.RendererGL.js:1421"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:1"
            +        },
            +        {
            +            "message": "Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/",
            +            "line": " lib/addons/p5.sound.js:52"
            +        },
            +        {
            +            "message": "Missing item type\nThis module has shims",
            +            "line": " lib/addons/p5.sound.js:401"
            +        },
            +        {
            +            "message": "Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats",
            +            "line": " lib/addons/p5.sound.js:536"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:807"
            +        },
            +        {
            +            "message": "Missing item type\nUsed by Osc and Envelope to chain signal math",
            +            "line": " lib/addons/p5.sound.js:1040"
            +        },
            +        {
            +            "message": "Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.",
            +            "line": " lib/addons/p5.sound.js:1542"
            +        },
            +        {
            +            "message": "Missing item type\nStop playback on all of this soundfile's sources.",
            +            "line": " lib/addons/p5.sound.js:2056"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:2604"
            +        },
            +        {
            +            "message": "Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade",
            +            "line": " lib/addons/p5.sound.js:6455"
            +        },
            +        {
            +            "message": "Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter",
            +            "line": " lib/addons/p5.sound.js:6462"
            +        },
            +        {
            +            "message": "Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ",
            +            "line": " lib/addons/p5.sound.js:7009"
            +        },
            +        {
            +            "message": "Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.",
            +            "line": " lib/addons/p5.sound.js:8508"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.",
            +            "line": " lib/addons/p5.sound.js:8659"
            +        },
            +        {
            +            "message": "Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string",
            +            "line": " lib/addons/p5.sound.js:9808"
            +        },
            +        {
            +            "message": "Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached",
            +            "line": " lib/addons/p5.sound.js:9826"
            +        },
            +        {
            +            "message": "Missing item type\ncallback invoked when the recording is over",
            +            "line": " lib/addons/p5.sound.js:10660"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release",
            +            "line": " lib/addons/p5.sound.js:11995"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.min.js:1"
            +        }
            +    ],
            +    "consts": {
            +        "LABEL": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "FALLBACK": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "RGB": [
            +            "p5.colorMode"
            +        ],
            +        "HSB": [
            +            "p5.colorMode"
            +        ],
            +        "HSL": [
            +            "p5.colorMode"
            +        ],
            +        "CHORD": [
            +            "p5.arc"
            +        ],
            +        "PIE": [
            +            "p5.arc"
            +        ],
            +        "OPEN": [
            +            "p5.arc"
            +        ],
            +        "CENTER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode",
            +            "p5.textAlign"
            +        ],
            +        "RADIUS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode"
            +        ],
            +        "CORNER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "CORNERS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "ROUND": [
            +            "p5.strokeCap",
            +            "p5.strokeJoin"
            +        ],
            +        "SQUARE": [
            +            "p5.strokeCap"
            +        ],
            +        "PROJECT": [
            +            "p5.strokeCap"
            +        ],
            +        "MITER": [
            +            "p5.strokeJoin"
            +        ],
            +        "BEVEL": [
            +            "p5.strokeJoin"
            +        ],
            +        "POINTS": [
            +            "p5.beginShape"
            +        ],
            +        "LINES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_FAN": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "QUADS": [
            +            "p5.beginShape"
            +        ],
            +        "QUAD_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "TESS": [
            +            "p5.beginShape"
            +        ],
            +        "CLOSE": [
            +            "p5.endShape"
            +        ],
            +        "ARROW": [
            +            "p5.cursor"
            +        ],
            +        "CROSS": [
            +            "p5.cursor"
            +        ],
            +        "HAND": [
            +            "p5.cursor"
            +        ],
            +        "MOVE": [
            +            "p5.cursor"
            +        ],
            +        "TEXT": [
            +            "p5.cursor"
            +        ],
            +        "P2D": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "WEBGL": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "BLEND": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DARKEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "LIGHTEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DIFFERENCE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "MULTIPLY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "EXCLUSION": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SCREEN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REPLACE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "OVERLAY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "HARD_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SOFT_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DODGE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "BURN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "ADD": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REMOVE": [
            +            "p5.blendMode"
            +        ],
            +        "SUBTRACT": [
            +            "p5.blendMode"
            +        ],
            +        "VIDEO": [
            +            "p5.createCapture"
            +        ],
            +        "AUDIO": [
            +            "p5.createCapture"
            +        ],
            +        "THRESHOLD": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "GRAY": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "OPAQUE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "INVERT": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "POSTERIZE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "ERODE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "DILATE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "BLUR": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "NORMAL": [
            +            "p5.Image.blend",
            +            "p5.blend",
            +            "p5.textStyle",
            +            "p5.textureMode"
            +        ],
            +        "RADIANS": [
            +            "p5.angleMode"
            +        ],
            +        "DEGREES": [
            +            "p5.angleMode"
            +        ],
            +        "LEFT": [
            +            "p5.textAlign"
            +        ],
            +        "RIGHT": [
            +            "p5.textAlign"
            +        ],
            +        "TOP": [
            +            "p5.textAlign"
            +        ],
            +        "BOTTOM": [
            +            "p5.textAlign"
            +        ],
            +        "BASELINE": [
            +            "p5.textAlign"
            +        ],
            +        "ITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "BOLD": [
            +            "p5.textStyle"
            +        ],
            +        "BOLDITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "WORD": [
            +            "p5.textWrap"
            +        ],
            +        "CHAR": [
            +            "p5.textWrap"
            +        ],
            +        "IMAGE": [
            +            "p5.textureMode"
            +        ],
            +        "CLAMP": [
            +            "p5.textureWrap"
            +        ],
            +        "REPEAT": [
            +            "p5.textureWrap"
            +        ],
            +        "MIRROR": [
            +            "p5.textureWrap"
            +        ]
            +    }
            +}
            \ No newline at end of file
            diff --git a/dist/reference/data.min.json b/dist/reference/data.min.json
            new file mode 100644
            index 0000000000..b719e76314
            --- /dev/null
            +++ b/dist/reference/data.min.json
            @@ -0,0 +1 @@
            +{"project":{"name":"p5","description":"[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)","version":"1.4.1","url":"https://github.com/processing/p5.js#readme"},"files":{"src/accessibility/color_namer.js":{"name":"src/accessibility/color_namer.js","modules":{"Environment":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/describe.js":{"name":"src/accessibility/describe.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/gridOutput.js":{"name":"src/accessibility/gridOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/outputs.js":{"name":"src/accessibility/outputs.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/textOutput.js":{"name":"src/accessibility/textOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/color_conversion.js":{"name":"src/color/color_conversion.js","modules":{"Color Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/creating_reading.js":{"name":"src/color/creating_reading.js","modules":{"Creating & Reading":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/p5.Color.js":{"name":"src/color/p5.Color.js","modules":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{}},"src/color/setting.js":{"name":"src/color/setting.js","modules":{"Setting":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/fes_core.js":{"name":"src/core/friendly_errors/fes_core.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/file_errors.js":{"name":"src/core/friendly_errors/file_errors.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/sketch_reader.js":{"name":"src/core/friendly_errors/sketch_reader.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/stacktrace.js":{"name":"src/core/friendly_errors/stacktrace.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/validate_params.js":{"name":"src/core/friendly_errors/validate_params.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/2d_primitives.js":{"name":"src/core/shape/2d_primitives.js","modules":{"2D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/attributes.js":{"name":"src/core/shape/attributes.js","modules":{"Attributes":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/curves.js":{"name":"src/core/shape/curves.js","modules":{"Curves":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/vertex.js":{"name":"src/core/shape/vertex.js","modules":{"Vertex":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/constants.js":{"name":"src/core/constants.js","modules":{"Constants":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/environment.js":{"name":"src/core/environment.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/helpers.js":{"name":"src/core/helpers.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/init.js":{"name":"src/core/init.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/internationalization.js":{"name":"src/core/internationalization.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/legacy.js":{"name":"src/core/legacy.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/main.js":{"name":"src/core/main.js","modules":{"Structure":1},"classes":{"p5":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Element.js":{"name":"src/core/p5.Element.js","modules":{"DOM":1},"classes":{"p5.Element":1},"fors":{"p5.Element":1},"namespaces":{}},"src/core/p5.Graphics.js":{"name":"src/core/p5.Graphics.js","modules":{"Rendering":1},"classes":{"p5.Graphics":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer.js":{"name":"src/core/p5.Renderer.js","modules":{},"classes":{"p5.Renderer":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer2D.js":{"name":"src/core/p5.Renderer2D.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/reference.js":{"name":"src/core/reference.js","modules":{"Foundation":1},"classes":{},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{}},"src/core/rendering.js":{"name":"src/core/rendering.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shim.js":{"name":"src/core/shim.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/structure.js":{"name":"src/core/structure.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/transform.js":{"name":"src/core/transform.js","modules":{"Transform":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/local_storage.js":{"name":"src/data/local_storage.js","modules":{"LocalStorage":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/p5.TypedDict.js":{"name":"src/data/p5.TypedDict.js","modules":{"Dictionary":1},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"namespaces":{}},"src/dom/dom.js":{"name":"src/dom/dom.js","modules":{},"classes":{"p5.MediaElement":1,"p5.File":1},"fors":{"p5":1,"p5.Element":1},"namespaces":{}},"src/events/acceleration.js":{"name":"src/events/acceleration.js","modules":{"Acceleration":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/keyboard.js":{"name":"src/events/keyboard.js","modules":{"Keyboard":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/mouse.js":{"name":"src/events/mouse.js","modules":{"Mouse":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/touch.js":{"name":"src/events/touch.js","modules":{"Touch":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/filters.js":{"name":"src/image/filters.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/image/image.js":{"name":"src/image/image.js","modules":{"Image":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/loading_displaying.js":{"name":"src/image/loading_displaying.js","modules":{"Loading & Displaying":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/p5.Image.js":{"name":"src/image/p5.Image.js","modules":{},"classes":{"p5.Image":1},"fors":{},"namespaces":{}},"src/image/pixels.js":{"name":"src/image/pixels.js","modules":{"Pixels":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/io/files.js":{"name":"src/io/files.js","modules":{"Input":1,"Output":1},"classes":{"p5.PrintWriter":1},"fors":{"p5":1},"namespaces":{}},"src/io/p5.Table.js":{"name":"src/io/p5.Table.js","modules":{"Table":1},"classes":{"p5.Table":1},"fors":{},"namespaces":{}},"src/io/p5.TableRow.js":{"name":"src/io/p5.TableRow.js","modules":{},"classes":{"p5.TableRow":1},"fors":{},"namespaces":{}},"src/io/p5.XML.js":{"name":"src/io/p5.XML.js","modules":{},"classes":{"p5.XML":1},"fors":{},"namespaces":{}},"src/math/calculation.js":{"name":"src/math/calculation.js","modules":{"Calculation":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/math.js":{"name":"src/math/math.js","modules":{"Vector":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/noise.js":{"name":"src/math/noise.js","modules":{"Noise":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/p5.Vector.js":{"name":"src/math/p5.Vector.js","modules":{},"classes":{"p5.Vector":1},"fors":{},"namespaces":{}},"src/math/random.js":{"name":"src/math/random.js","modules":{"Random":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/trigonometry.js":{"name":"src/math/trigonometry.js","modules":{"Trigonometry":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/attributes.js":{"name":"src/typography/attributes.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/loading_displaying.js":{"name":"src/typography/loading_displaying.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/p5.Font.js":{"name":"src/typography/p5.Font.js","modules":{},"classes":{"p5.Font":1},"fors":{},"namespaces":{}},"src/utilities/array_functions.js":{"name":"src/utilities/array_functions.js","modules":{"Array Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/conversion.js":{"name":"src/utilities/conversion.js","modules":{"Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/string_functions.js":{"name":"src/utilities/string_functions.js","modules":{"String Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/time_date.js":{"name":"src/utilities/time_date.js","modules":{"Time & Date":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/3d_primitives.js":{"name":"src/webgl/3d_primitives.js","modules":{"3D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/interaction.js":{"name":"src/webgl/interaction.js","modules":{"Interaction":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/light.js":{"name":"src/webgl/light.js","modules":{"Lights":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/loading.js":{"name":"src/webgl/loading.js","modules":{"3D Models":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/material.js":{"name":"src/webgl/material.js","modules":{"Material":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Camera.js":{"name":"src/webgl/p5.Camera.js","modules":{"Camera":1},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{}},"src/webgl/p5.Geometry.js":{"name":"src/webgl/p5.Geometry.js","modules":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Matrix.js":{"name":"src/webgl/p5.Matrix.js","modules":{},"classes":{"p5.Matrix":1},"fors":{},"namespaces":{}},"src/webgl/p5.RenderBuffer.js":{"name":"src/webgl/p5.RenderBuffer.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Immediate.js":{"name":"src/webgl/p5.RendererGL.Immediate.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Retained.js":{"name":"src/webgl/p5.RendererGL.Retained.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.js":{"name":"src/webgl/p5.RendererGL.js","modules":{},"classes":{"p5.RendererGL":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Shader.js":{"name":"src/webgl/p5.Shader.js","modules":{},"classes":{"p5.Shader":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Texture.js":{"name":"src/webgl/p5.Texture.js","modules":{},"classes":{"p5.Texture":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/text.js":{"name":"src/webgl/text.js","modules":{},"classes":{"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{},"namespaces":{}},"lib/addons/p5.sound.js":{"name":"lib/addons/p5.sound.js","modules":{"p5.sound":1},"classes":{"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{}},"lib/addons/p5.sound.min.js":{"name":"lib/addons/p5.sound.min.js","modules":{},"classes":{},"fors":{},"namespaces":{}}},"modules":{"Environment":{"name":"Environment","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Environment","file":"src/accessibility/color_namer.js","line":1,"requires":["core"]},"Color":{"name":"Color","submodules":{"Color Conversion":1,"Creating & Reading":1,"Setting":1},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{},"file":"src/color/p5.Color.js","line":14},"Color Conversion":{"name":"Color Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/color_conversion.js","line":1,"requires":["core"]},"Creating & Reading":{"name":"Creating & Reading","submodules":{},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/p5.Color.js","line":14,"requires":["core","constants"],"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"},"Setting":{"name":"Setting","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/setting.js","line":1,"requires":["core","constants"]},"Shape":{"name":"Shape","submodules":{"2D Primitives":1,"Curves":1,"Vertex":1,"3D Primitives":1,"3D Models":1},"elements":{},"classes":{"p5.Geometry":1,"p5.Matrix":1},"fors":{"p5":1},"namespaces":{},"file":"src/webgl/p5.Matrix.js","line":19},"2D Primitives":{"name":"2D Primitives","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/2d_primitives.js","line":1,"requires":["core","constants"]},"Attributes":{"name":"Attributes","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/core/shape/attributes.js","line":1,"requires":["core","constants"]},"Curves":{"name":"Curves","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/curves.js","line":1,"requires":["core"]},"Vertex":{"name":"Vertex","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/vertex.js","line":1,"requires":["core","constants"]},"Constants":{"name":"Constants","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Constants","file":"src/core/constants.js","line":1},"Structure":{"name":"Structure","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"IO","file":"src/core/main.js","line":1,"requires":["constants"]},"DOM":{"name":"DOM","submodules":{},"elements":{},"classes":{"p5.Element":1,"p5.MediaElement":1,"p5.File":1},"fors":{"p5.Element":1,"p5":1},"namespaces":{},"module":"DOM","file":"src/dom/dom.js","line":3533,"description":"<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n","requires":["p5"]},"Rendering":{"name":"Rendering","submodules":{"undefined":1},"elements":{},"classes":{"p5.RendererGL":1,"p5.Graphics":1,"p5.Renderer":1},"fors":{"p5":1},"namespaces":{},"module":"Rendering","file":"src/webgl/p5.RendererGL.js","line":603,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"},"Foundation":{"name":"Foundation","submodules":{},"elements":{},"classes":{"JSON":1,"console":1},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{},"module":"Foundation","file":"src/core/reference.js","line":1},"Transform":{"name":"Transform","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Transform","file":"src/core/transform.js","line":1,"requires":["core","constants"]},"Data":{"name":"Data","submodules":{"LocalStorage":1,"Dictionary":1,"Array Functions":1,"Conversion":1,"String Functions":1},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5":1,"p5.TypedDict":1},"namespaces":{},"file":"src/data/p5.TypedDict.js","line":410},"LocalStorage":{"name":"LocalStorage","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/local_storage.js","line":1,"requires":["core\n\nThis module defines the p5 methods for working with local storage"]},"Dictionary":{"name":"Dictionary","submodules":{},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"requires":["core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."],"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"},"Events":{"name":"Events","submodules":{"Acceleration":1,"Keyboard":1,"Mouse":1,"Touch":1},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"Acceleration":{"name":"Acceleration","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/acceleration.js","line":1,"requires":["core"]},"Keyboard":{"name":"Keyboard","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/keyboard.js","line":1,"requires":["core"]},"Mouse":{"name":"Mouse","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/mouse.js","line":1,"requires":["core","constants"]},"Touch":{"name":"Touch","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/touch.js","line":1,"requires":["core"]},"Image":{"name":"Image","submodules":{"Pixels":1},"elements":{},"classes":{"p5.Image":1},"fors":{"p5":1},"namespaces":{},"module":"Image","file":"src/image/p5.Image.js","line":21,"requires":["core"],"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"},"Loading & Displaying":{"name":"Loading & Displaying","submodules":{},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/typography/p5.Font.js","line":13,"requires":["core"],"description":"<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"},"Pixels":{"name":"Pixels","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Image","namespace":"","file":"src/image/pixels.js","line":1,"requires":["core"]},"IO":{"name":"IO","submodules":{"Structure":1,"Input":1,"Output":1,"Table":1,"Time & Date":1},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1,"p5.Table":1,"p5.TableRow":1,"p5.XML":1},"fors":{"p5":1},"namespaces":{},"file":"src/io/p5.XML.js","line":9},"Input":{"name":"Input","submodules":{},"elements":{},"classes":{"p5.XML":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.XML.js","line":9,"requires":["core"],"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"},"Output":{"name":"Output","submodules":{},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/files.js","line":1200,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"},"Table":{"name":"Table","submodules":{},"elements":{},"classes":{"p5.Table":1,"p5.TableRow":1},"fors":{},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.TableRow.js","line":9,"requires":["core"],"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"},"Math":{"name":"Math","submodules":{"Calculation":1,"Vector":1,"Noise":1,"Random":1,"Trigonometry":1},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"namespaces":{},"file":"src/math/p5.Vector.js","line":10},"Calculation":{"name":"Calculation","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/calculation.js","line":1,"requires":["core"]},"Vector":{"name":"Vector","submodules":{},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/p5.Vector.js","line":10,"requires":["core"],"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"},"Noise":{"name":"Noise","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/noise.js","line":14,"requires":["core"]},"Random":{"name":"Random","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/random.js","line":1,"requires":["core"]},"Trigonometry":{"name":"Trigonometry","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/trigonometry.js","line":1,"requires":["core","constants"]},"Typography":{"name":"Typography","submodules":{"Attributes":1,"Loading & Displaying":1},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"namespaces":{},"file":"src/typography/p5.Font.js","line":13},"Array Functions":{"name":"Array Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/array_functions.js","line":1,"requires":["core"]},"Conversion":{"name":"Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/conversion.js","line":1,"requires":["core"]},"String Functions":{"name":"String Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/string_functions.js","line":1,"requires":["core"]},"Time & Date":{"name":"Time & Date","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/utilities/time_date.js","line":1,"requires":["core"]},"3D Primitives":{"name":"3D Primitives","submodules":{},"elements":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"requires":["core","p5.Geometry"],"description":"<p>p5 Geometry class</p>\n"},"3D":{"name":"3D","submodules":{"Interaction":1,"Lights":1,"Material":1,"Camera":1},"elements":{},"classes":{"p5.Camera":1,"p5.Shader":1,"p5.Texture":1,"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{},"file":"src/webgl/text.js","line":260},"Interaction":{"name":"Interaction","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/interaction.js","line":1,"requires":["core"]},"Lights":{"name":"Lights","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/light.js","line":1,"requires":["core"]},"3D Models":{"name":"3D Models","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/loading.js","line":1,"requires":["core","p5.Geometry"]},"Material":{"name":"Material","submodules":{},"elements":{},"classes":{"p5.Shader":1,"p5.Texture":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Texture.js","line":12,"requires":["core"],"description":"<p>This module defines the p5.Shader class</p>\n"},"Camera":{"name":"Camera","submodules":{},"elements":{},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"requires":["core"],"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"},"p5.sound":{"name":"p5.sound","submodules":{},"elements":{},"classes":{"p5.sound":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{},"module":"p5.sound","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>","tag":"main","itemtype":"main"}},"classes":{"p5":{"name":"p5","shortname":"p5","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/core/main.js","line":13,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n","is_constructor":1,"params":[{"name":"sketch","description":"<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n","type":"Function"},{"name":"node","description":"<p>element to attach canvas to</p>\n","type":"HTMLElement","optional":true}],"return":{"description":"a p5 instance","type":"P5"}},"p5.Color":{"name":"p5.Color","shortname":"p5.Color","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Color","submodule":"Creating & Reading","namespace":"","file":"src/color/p5.Color.js","line":14,"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n","is_constructor":1},"p5.Element":{"name":"p5.Element","shortname":"p5.Element","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/core/p5.Element.js","line":9,"description":"<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Graphics":{"name":"p5.Graphics","shortname":"p5.Graphics","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Graphics.js","line":10,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"},{"name":"renderer","description":"<p>the renderer to use, either P2D or WEBGL</p>\n","type":"Constant"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Renderer":{"name":"p5.Renderer","shortname":"p5.Renderer","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Renderer.js","line":10,"description":"<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true},{"name":"isMainCanvas","description":"<p>whether we're using it as main canvas</p>\n","type":"Boolean","optional":true}]},"JSON":{"name":"JSON","shortname":"JSON","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"console":{"name":"console","shortname":"console","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"p5.TypedDict":{"name":"p5.TypedDict","shortname":"p5.TypedDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":82,"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n","is_constructor":1},"p5.StringDict":{"name":"p5.StringDict","shortname":"p5.StringDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":394,"description":"<p>A simple Dictionary class for Strings.</p>\n","extends":"p5.TypedDict"},"p5.NumberDict":{"name":"p5.NumberDict","shortname":"p5.NumberDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"description":"<p>A simple Dictionary class for Numbers.</p>\n","is_constructor":1,"extends":"p5.TypedDict"},"p5.MediaElement":{"name":"p5.MediaElement","shortname":"p5.MediaElement","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":2377,"description":"<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"}]},"p5.File":{"name":"p5.File","shortname":"p5.File","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":3533,"description":"<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n","is_constructor":1,"params":[{"name":"file","description":"<p>File that is wrapped</p>\n","type":"File"}]},"p5.Image":{"name":"p5.Image","shortname":"p5.Image","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Image","submodule":"Image","namespace":"","file":"src/image/p5.Image.js","line":21,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n","example":["\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"],"is_constructor":1,"params":[{"name":"width","description":"","type":"Number"},{"name":"height","description":"","type":"Number"}]},"p5.PrintWriter":{"name":"p5.PrintWriter","shortname":"p5.PrintWriter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/io/files.js","line":1200,"params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"","type":"String","optional":true}]},"p5.Table":{"name":"p5.Table","shortname":"p5.Table","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.Table.js","line":33,"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n","is_constructor":1,"params":[{"name":"rows","description":"<p>An array of p5.TableRow objects</p>\n","type":"p5.TableRow[]","optional":true}]},"p5.TableRow":{"name":"p5.TableRow","shortname":"p5.TableRow","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.TableRow.js","line":9,"description":"<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n","is_constructor":1,"params":[{"name":"str","description":"<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n","type":"String","optional":true},{"name":"separator","description":"<p>comma separated values (csv) by default</p>\n","type":"String","optional":true}]},"p5.XML":{"name":"p5.XML","shortname":"p5.XML","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Input","namespace":"","file":"src/io/p5.XML.js","line":9,"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n","is_constructor":1,"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed"},"p5.Vector":{"name":"p5.Vector","shortname":"p5.Vector","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Math","submodule":"Vector","namespace":"","file":"src/math/p5.Vector.js","line":10,"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n","is_constructor":1,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"],"alt":"2 white ellipses. One center-left the other bottom right and off canvas"},"p5.Font":{"name":"p5.Font","shortname":"p5.Font","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Typography","submodule":"Loading & Displaying","namespace":"","file":"src/typography/p5.Font.js","line":13,"description":"<p>Base class for font handling</p>\n","is_constructor":1,"params":[{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Camera":{"name":"p5.Camera","shortname":"p5.Camera","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Camera","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n","params":[{"name":"rendererGL","description":"<p>instance of WebGL renderer</p>\n","type":"RendererGL"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes."},"p5.Geometry":{"name":"p5.Geometry","shortname":"p5.Geometry","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Shape","submodule":"3D Primitives","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"description":"<p>p5 Geometry class</p>\n","is_constructor":1,"params":[{"name":"detailX","description":"<p>number of vertices along the x-axis.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of vertices along the y-axis.</p>\n","type":"Integer","optional":true},{"name":"callback","description":"<p>function to call upon object instantiation.</p>\n","type":"Function","optional":true}]},"p5.Shader":{"name":"p5.Shader","shortname":"p5.Shader","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Material","namespace":"","file":"src/webgl/p5.Shader.js","line":11,"description":"<p>Shader class for WEBGL Mode</p>\n","is_constructor":1,"params":[{"name":"renderer","description":"<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n","type":"p5.RendererGL"},{"name":"vertSrc","description":"<p>source code for the vertex shader (as a string)</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader (as a string)</p>\n","type":"String"}]},"p5.sound":{"name":"p5.sound","shortname":"p5.sound","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":""},"p5.SoundFile":{"name":"p5.SoundFile","shortname":"p5.SoundFile","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":1405,"description":"<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true},{"name":"whileLoadingCallback","description":"<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"]},"p5.Amplitude":{"name":"p5.Amplitude","shortname":"p5.Amplitude","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3022,"description":"<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n","is_constructor":1,"params":[{"name":"smoothing","description":"<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"]},"p5.FFT":{"name":"p5.FFT","shortname":"p5.FFT","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3347,"description":"<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>","is_constructor":1,"params":[{"name":"smoothing","description":"<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n","type":"Number","optional":true},{"name":"bins","description":"<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"]},"p5.Oscillator":{"name":"p5.Oscillator","shortname":"p5.Oscillator","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4060,"description":"<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>","is_constructor":1,"params":[{"name":"freq","description":"<p>frequency defaults to 440Hz</p>\n","type":"Number","optional":true},{"name":"type","description":"<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"]},"p5.SinOsc":{"name":"p5.SinOsc","shortname":"p5.SinOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4602,"description":"<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.TriOsc":{"name":"p5.TriOsc","shortname":"p5.TriOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4629,"description":"<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SawOsc":{"name":"p5.SawOsc","shortname":"p5.SawOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4656,"description":"<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SqrOsc":{"name":"p5.SqrOsc","shortname":"p5.SqrOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4683,"description":"<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.Envelope":{"name":"p5.Envelope","shortname":"p5.Envelope","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4721,"description":"<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>","is_constructor":1,"example":["\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"]},"p5.Noise":{"name":"p5.Noise","shortname":"p5.Noise","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5620,"description":"<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"type","description":"<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n","type":"String"}]},"p5.Pulse":{"name":"p5.Pulse","shortname":"p5.Pulse","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5779,"description":"<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"freq","description":"<p>Frequency in oscillations per second (Hz)</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"]},"p5.AudioIn":{"name":"p5.AudioIn","shortname":"p5.AudioIn","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6015,"description":"<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>","is_constructor":1,"params":[{"name":"errorCallback","description":"<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"]},"p5.Effect":{"name":"p5.Effect","shortname":"p5.Effect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6423,"description":"<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n","is_constructor":1,"params":[{"name":"ac","description":"<p>Reference to the audio context of the p5 object</p>\n","type":"Object","optional":true},{"name":"input","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"output","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"_drywet","description":"<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n","type":"Object","optional":true},{"name":"wet","description":"<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n","type":"AudioNode","optional":true}]},"p5.Filter":{"name":"p5.Filter","shortname":"p5.Filter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6628,"description":"<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"type","description":"<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"]},"p5.LowPass":{"name":"p5.LowPass","shortname":"p5.LowPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6914,"description":"<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.HighPass":{"name":"p5.HighPass","shortname":"p5.HighPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6938,"description":"<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.BandPass":{"name":"p5.BandPass","shortname":"p5.BandPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6962,"description":"<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.EQ":{"name":"p5.EQ","shortname":"p5.EQ","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7105,"description":"<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect","params":[{"name":"_eqsize","description":"<p>Constructor will accept 3 or 8, defaults to 3</p>\n","type":"Number","optional":true}],"return":{"description":"p5.EQ object","type":"Object"},"example":["\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"]},"p5.Panner3D":{"name":"p5.Panner3D","shortname":"p5.Panner3D","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7602,"description":"<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n","is_constructor":1},"p5.Delay":{"name":"p5.Delay","shortname":"p5.Delay","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7926,"description":"<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"]},"p5.Reverb":{"name":"p5.Reverb","shortname":"p5.Reverb","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8308,"description":"<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"]},"p5.Convolver":{"name":"p5.Convolver","shortname":"p5.Convolver","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8549,"description":"<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>","extends":"p5.Effect","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call when loading succeeds</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"]},"p5.Phrase":{"name":"p5.Phrase","shortname":"p5.Phrase","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9103,"description":"<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>","is_constructor":1,"params":[{"name":"name","description":"<p>Name so that you can access the Phrase.</p>\n","type":"String"},{"name":"callback","description":"<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n","type":"Function"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"example":["\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"]},"p5.Part":{"name":"p5.Part","shortname":"p5.Part","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9185,"description":"<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>","is_constructor":1,"params":[{"name":"steps","description":"<p>Steps in the part</p>\n","type":"Number","optional":true},{"name":"tatums","description":"<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"]},"p5.Score":{"name":"p5.Score","shortname":"p5.Score","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9493,"description":"<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n","is_constructor":1,"params":[{"name":"parts","description":"<p>One or multiple parts, to be played in sequence.</p>\n","type":"p5.Part","optional":true,"multiple":true}]},"p5.SoundLoop":{"name":"p5.SoundLoop","shortname":"p5.SoundLoop","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9673,"description":"<p>SoundLoop</p>\n","is_constructor":1,"params":[{"name":"callback","description":"<p>this function will be called on each iteration of theloop</p>\n","type":"Function"},{"name":"interval","description":"<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n","type":"Number|String","optional":true}],"example":["\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"]},"p5.Compressor":{"name":"p5.Compressor","shortname":"p5.Compressor","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10036,"description":"<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect"},"p5.PeakDetect":{"name":"p5.PeakDetect","shortname":"p5.PeakDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10312,"description":"<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>","is_constructor":1,"params":[{"name":"freq1","description":"<p>lowFrequency - defaults to 20Hz</p>\n","type":"Number","optional":true},{"name":"freq2","description":"<p>highFrequency - defaults to 20000 Hz</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n","type":"Number","optional":true},{"name":"framesPerPeak","description":"<p>Defaults to 20.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"]},"p5.SoundRecorder":{"name":"p5.SoundRecorder","shortname":"p5.SoundRecorder","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10559,"description":"<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>","is_constructor":1,"example":["\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"]},"p5.Distortion":{"name":"p5.Distortion","shortname":"p5.Distortion","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10816,"description":"<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}]},"p5.Gain":{"name":"p5.Gain","shortname":"p5.Gain","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10973,"description":"<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n","is_constructor":1,"example":["\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"]},"p5.AudioVoice":{"name":"p5.AudioVoice","shortname":"p5.AudioVoice","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11149,"description":"<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n","is_constructor":1},"p5.MonoSynth":{"name":"p5.MonoSynth","shortname":"p5.MonoSynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11247,"description":"<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n","is_constructor":1,"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"]},"p5.OnsetDetect":{"name":"p5.OnsetDetect","shortname":"p5.OnsetDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11624,"description":"<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n","is_constructor":1,"params":[{"name":"freqLow","description":"<p>Low frequency</p>\n","type":"Number"},{"name":"freqHigh","description":"<p>High frequency</p>\n","type":"Number"},{"name":"threshold","description":"<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n","type":"Number"},{"name":"callback","description":"<p>Function to call when an onset is detected</p>\n","type":"Function"}]},"p5.PolySynth":{"name":"p5.PolySynth","shortname":"p5.PolySynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n","is_constructor":1,"params":[{"name":"synthVoice","description":"<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n","type":"Number","optional":true},{"name":"maxVoices","description":"<p>Number of voices, defaults to 8;</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"]}},"elements":{},"classitems":[{"file":"src/accessibility/describe.js","line":18,"description":"<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n","itemtype":"method","name":"describe","params":[{"name":"text","description":"<p>description of the canvas</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/describe.js","line":114,"description":"<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n","itemtype":"method","name":"describeElement","params":[{"name":"name","description":"<p>name of the element</p>\n","type":"String"},{"name":"text","description":"<p>description of the element</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":10,"description":"<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"textOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":88,"description":"<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"gridOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/color/color_conversion.js","line":8,"description":"<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":19,"description":"<p>Convert an HSBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":45,"description":"<p>Convert an HSBA array to RGBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":100,"description":"<p>Convert an HSLA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":123,"description":"<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":187,"description":"<p>Convert an RGBA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":226,"description":"<p>Convert an RGBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/creating_reading.js","line":16,"description":"<p>Extracts the alpha value from a color or pixel array.</p>\n","itemtype":"method","name":"alpha","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the alpha value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":43,"description":"<p>Extracts the blue value from a color or pixel array.</p>\n","itemtype":"method","name":"blue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the blue value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":69,"description":"<p>Extracts the HSB brightness value from a color or pixel array.</p>\n","itemtype":"method","name":"brightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the brightness value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":113,"description":"<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n","itemtype":"method","name":"color","return":{"description":"resulting color","type":"p5.Color"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading","overloads":[{"line":113,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"return":{"description":"resulting color","type":"p5.Color"}},{"line":257,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"return":{"description":"","type":"p5.Color"}},{"line":269,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"return":{"description":"","type":"p5.Color"}},{"line":275,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"return":{"description":"","type":"p5.Color"}},{"line":282,"params":[{"name":"color","description":"","type":"p5.Color"}],"return":{"description":"","type":"p5.Color"}}]},{"file":"src/color/creating_reading.js","line":297,"description":"<p>Extracts the green value from a color or pixel array.</p>\n","itemtype":"method","name":"green","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the green value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":325,"description":"<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n","itemtype":"method","name":"hue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the hue","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":359,"description":"<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n","itemtype":"method","name":"lerpColor","params":[{"name":"c1","description":"<p>interpolate from this color</p>\n","type":"p5.Color"},{"name":"c2","description":"<p>interpolate to this color</p>\n","type":"p5.Color"},{"name":"amt","description":"<p>number between 0 and 1</p>\n","type":"Number"}],"return":{"description":"interpolated color","type":"p5.Color"},"example":["\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":449,"description":"<p>Extracts the HSL lightness value from a color or pixel array.</p>\n","itemtype":"method","name":"lightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the lightness","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":478,"description":"<p>Extracts the red value from a color or pixel array.</p>\n","itemtype":"method","name":"red","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the red value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":517,"description":"<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n","itemtype":"method","name":"saturation","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the saturation value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":51,"description":"<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n","itemtype":"method","name":"toString","params":[{"name":"format","description":"<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n","type":"String","optional":true}],"return":{"description":"the formatted string","type":"String"},"example":["\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":254,"description":"<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setRed","params":[{"name":"red","description":"<p>the new red value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":281,"description":"<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setGreen","params":[{"name":"green","description":"<p>the new green value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":304,"description":"<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setBlue","params":[{"name":"blue","description":"<p>the new blue value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":327,"description":"<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setAlpha","params":[{"name":"alpha","description":"<p>the new alpha value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":396,"description":"<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":427,"description":"<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":446,"description":"<p>CSS named colors.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":600,"description":"<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":613,"description":"<p>Full color string patterns. The capture groups are necessary.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":960,"description":"<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/setting.js","line":13,"description":"<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n","itemtype":"method","name":"background","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":13,"params":[{"name":"color","description":"<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n","type":"p5.Color"}],"chainable":1},{"line":130,"params":[{"name":"colorstring","description":"<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n","type":"String"},{"name":"a","description":"<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":140,"params":[{"name":"gray","description":"<p>specifies a value between white and black</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":147,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current color\n                       mode)</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":159,"params":[{"name":"values","description":"<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":166,"params":[{"name":"image","description":"<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n","type":"p5.Image"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":179,"description":"<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n","itemtype":"method","name":"clear","chainable":1,"example":["\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"],"params":[{"name":"r","description":"<p>normalized red val.</p>\n","type":"Number"},{"name":"g","description":"<p>normalized green val.</p>\n","type":"Number"},{"name":"b","description":"<p>normalized blue val.</p>\n","type":"Number"},{"name":"a","description":"<p>normalized alpha val.</p>\n","type":"Number"}],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":229,"description":"<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n","itemtype":"method","name":"colorMode","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":229,"params":[{"name":"mode","description":"<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n","type":"Constant"},{"name":"max","description":"<p>range for all values</p>\n","type":"Number","optional":true}],"chainable":1},{"line":306,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"max1","description":"<p>range for the red or hue depending on the\n                             current color mode</p>\n","type":"Number"},{"name":"max2","description":"<p>range for the green or saturation depending\n                             on the current color mode</p>\n","type":"Number"},{"name":"max3","description":"<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n","type":"Number"},{"name":"maxA","description":"<p>range for the alpha</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":350,"description":"<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n","itemtype":"method","name":"fill","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":350,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":475,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":481,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":488,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":495,"params":[{"name":"color","description":"<p>the fill color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":507,"description":"<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noFill","chainable":1,"example":["\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":547,"description":"<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noStroke","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":585,"description":"<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n","itemtype":"method","name":"stroke","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":585,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":722,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":728,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":735,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":742,"params":[{"name":"color","description":"<p>the stroke color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":755,"description":"<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n","itemtype":"method","name":"erase","params":[{"name":"strengthFill","description":"<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true},{"name":"strengthStroke","description":"<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":836,"description":"<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n","itemtype":"method","name":"noErase","chainable":1,"example":["\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/core/friendly_errors/fes_core.js","line":1,"requires":["core\n\nThis is the main file for the Friendly Error System (FES)","containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters","(2) _friendlyFileLoadError","(3) _friendlyError","(4) helpForMisusedAtTopLevelCode","or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this","there's also a file stacktrace.js","which contains the code\nto parse the error stack","borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions","including the call\nsequence of each function","please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/fes_core.js","line":915,"description":"<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n","class":"p5","module":"Color"},{"file":"src/core/friendly_errors/file_errors.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/sketch_reader.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/stacktrace.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/validate_params.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/shape/2d_primitives.js","line":16,"description":"<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n","class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":102,"description":"<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n","itemtype":"method","name":"arc","params":[{"name":"x","description":"<p>x-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"w","description":"<p>width of the arc's ellipse by default</p>\n","type":"Number"},{"name":"h","description":"<p>height of the arc's ellipse by default</p>\n","type":"Number"},{"name":"start","description":"<p>angle to start the arc, specified in radians</p>\n","type":"Number"},{"name":"stop","description":"<p>angle to stop the arc, specified in radians</p>\n","type":"Number"},{"name":"mode","description":"<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n","type":"Constant","optional":true},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":235,"description":"<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n","itemtype":"method","name":"ellipse","chainable":1,"example":["\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":235,"params":[{"name":"x","description":"<p>x-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the ellipse.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the ellipse.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":261,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}]}]},{"file":"src/core/shape/2d_primitives.js","line":277,"description":"<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n","itemtype":"method","name":"circle","params":[{"name":"x","description":"<p>x-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"d","description":"<p>diameter of the circle.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":340,"description":"<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n","itemtype":"method","name":"line","chainable":1,"example":["\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":340,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"}],"chainable":1},{"line":379,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":404,"description":"<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n","itemtype":"method","name":"point","chainable":1,"example":["\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":404,"params":[{"name":"x","description":"<p>the x-coordinate</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate</p>\n","type":"Number"},{"name":"z","description":"<p>the z-coordinate (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":455,"params":[{"name":"coordinate_vector","description":"<p>the coordinate vector</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":483,"description":"<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n","itemtype":"method","name":"quad","chainable":1,"example":["\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":483,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>the x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>the y-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"<p>the x-coordinate of the fourth point</p>\n","type":"Number"},{"name":"y4","description":"<p>the y-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction</p>\n","type":"Integer","optional":true}],"chainable":1},{"line":512,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>the z-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>the z-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"","type":"Integer","optional":true},{"name":"detailY","description":"","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":556,"description":"<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"rect","chainable":1,"example":["\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":556,"params":[{"name":"x","description":"<p>x-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the rectangle.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the rectangle.</p>\n","type":"Number","optional":true},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":608,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction (for WebGL mode)</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction (for WebGL mode)</p>\n","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":623,"description":"<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"square","params":[{"name":"x","description":"<p>x-coordinate of the square.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the square.</p>\n","type":"Number"},{"name":"s","description":"<p>side size of the square.</p>\n","type":"Number"},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":713,"description":"<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n","itemtype":"method","name":"triangle","params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate of the third point</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/attributes.js","line":12,"description":"<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"ellipseMode","params":[{"name":"mode","description":"<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"],"alt":"60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":81,"description":"<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"noSmooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses to left & right of center, black background","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":115,"description":"<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"rectMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"],"alt":"50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":184,"description":"<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"smooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses one left one right of center. On black.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":219,"description":"<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeCap","params":[{"name":"cap","description":"<p>either ROUND, SQUARE or PROJECT</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"],"alt":"3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":259,"description":"<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeJoin","params":[{"name":"join","description":"<p>either MITER, BEVEL, ROUND</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"],"alt":"Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":331,"description":"<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n","itemtype":"method","name":"strokeWeight","params":[{"name":"weight","description":"<p>the weight of the stroke (in pixels)</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"],"alt":"3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/curves.js","line":13,"description":"<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n","itemtype":"method","name":"bezier","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"],"alt":"stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":13,"params":[{"name":"x1","description":"<p>x-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the second anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1},{"line":62,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":92,"description":"<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n","itemtype":"method","name":"bezierDetail","params":[{"name":"detail","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"],"alt":"stretched black s-shape with a low level of bezier detail","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":130,"description":"<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n","itemtype":"method","name":"bezierPoint","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the value of the Bezier at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"],"alt":"10 points plotted on a given bezier at equal distances.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":185,"description":"<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n","itemtype":"method","name":"bezierTangent","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":264,"description":"<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n","itemtype":"method","name":"curve","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"],"alt":"horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":264,"params":[{"name":"x1","description":"<p>x-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the ending control point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1},{"line":332,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":358,"description":"<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n","itemtype":"method","name":"curveDetail","params":[{"name":"resolution","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"],"alt":"white arch shape with a low level of curve detail.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":398,"description":"<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n","itemtype":"method","name":"curveTightness","params":[{"name":"amount","description":"<p>amount of deformation from the original vertices</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"],"alt":"Line shaped like right-facing arrow,points move with mouse-x and warp shape.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":444,"description":"<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n","itemtype":"method","name":"curvePoint","params":[{"name":"a","description":"<p>coordinate of first control point of the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"bezier value at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"],"class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":493,"description":"<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n","itemtype":"method","name":"curveTangent","params":[{"name":"a","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second conrol point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"right curving line mid-right of canvas with 7 short lines radiating from it.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/vertex.js","line":20,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"beginContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":67,"description":"<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"beginShape","params":[{"name":"kind","description":"<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":293,"description":"<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"bezierVertex","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"],"alt":"crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":293,"params":[{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":375,"params":[{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":415,"description":"<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n","itemtype":"method","name":"curveVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"],"alt":"Upside-down u-shape line, mid canvas. left point extends beyond canvas view.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":415,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":460,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":524,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"endContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":583,"description":"<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n","itemtype":"method","name":"endShape","params":[{"name":"mode","description":"<p>use CLOSE to close the shape</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"],"alt":"Triangle line shape with smallest interior angle on bottom and upside-down L.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":668,"description":"<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"quadraticVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"],"alt":"arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":668,"params":[{"name":"cx","description":"<p>x-coordinate for the control point</p>\n","type":"Number"},{"name":"cy","description":"<p>y-coordinate for the control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":733,"params":[{"name":"cx","description":"","type":"Number"},{"name":"cy","description":"","type":"Number"},{"name":"cz","description":"<p>z-coordinate for the control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":826,"description":"<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n","itemtype":"method","name":"vertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"],"alt":"4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":826,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":957,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n","type":"Number"}],"chainable":1},{"line":965,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true},{"name":"u","description":"<p>the vertex's texture u-coordinate</p>\n","type":"Number"},{"name":"v","description":"<p>the vertex's texture v-coordinate</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":1003,"description":"<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n","itemtype":"method","name":"normal","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":1003,"params":[{"name":"vector","description":"<p>A p5.Vector representing the vertex normal.</p>\n","type":"Vector"}],"chainable":1},{"line":1040,"params":[{"name":"x","description":"<p>The x component of the vertex normal.</p>\n","type":"Number"},{"name":"y","description":"<p>The y component of the vertex normal.</p>\n","type":"Number"},{"name":"z","description":"<p>The z component of the vertex normal.</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/constants.js","line":9,"description":"<p>Version of this p5.js.</p>\n","itemtype":"property","name":"VERSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":18,"description":"<p>The default, two-dimensional renderer.</p>\n","itemtype":"property","name":"P2D","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":24,"description":"<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n","itemtype":"property","name":"WEBGL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":33,"itemtype":"property","name":"ARROW","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":38,"itemtype":"property","name":"CROSS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":43,"itemtype":"property","name":"HAND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":48,"itemtype":"property","name":"MOVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":53,"itemtype":"property","name":"TEXT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":58,"itemtype":"property","name":"WAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":66,"description":"<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"HALF_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"],"alt":"80×80 white quarter-circle with curve toward bottom right of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":84,"description":"<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"],"alt":"white half-circle with curve toward bottom of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":102,"description":"<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"QUARTER_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"],"alt":"white eighth-circle rotated about 40 degrees with curve bottom right canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":120,"description":"<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TAU","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":138,"description":"<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TWO_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":156,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n","itemtype":"property","name":"DEGREES","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":170,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n","itemtype":"property","name":"RADIANS","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":188,"itemtype":"property","name":"CORNER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":193,"itemtype":"property","name":"CORNERS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":198,"itemtype":"property","name":"RADIUS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":203,"itemtype":"property","name":"RIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":208,"itemtype":"property","name":"LEFT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":213,"itemtype":"property","name":"CENTER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":218,"itemtype":"property","name":"TOP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":223,"itemtype":"property","name":"BOTTOM","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":228,"itemtype":"property","name":"BASELINE","type":"String","final":1,"default":"alphabetic","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":234,"itemtype":"property","name":"POINTS","type":"Number","final":1,"default":"0x0000","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":240,"itemtype":"property","name":"LINES","type":"Number","final":1,"default":"0x0001","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":246,"itemtype":"property","name":"LINE_STRIP","type":"Number","final":1,"default":"0x0003","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":252,"itemtype":"property","name":"LINE_LOOP","type":"Number","final":1,"default":"0x0002","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":258,"itemtype":"property","name":"TRIANGLES","type":"Number","final":1,"default":"0x0004","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":264,"itemtype":"property","name":"TRIANGLE_FAN","type":"Number","final":1,"default":"0x0006","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":270,"itemtype":"property","name":"TRIANGLE_STRIP","type":"Number","final":1,"default":"0x0005","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":276,"itemtype":"property","name":"QUADS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":281,"itemtype":"property","name":"QUAD_STRIP","type":"String","final":1,"default":"quad_strip","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":287,"itemtype":"property","name":"TESS","type":"String","final":1,"default":"tess","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":293,"itemtype":"property","name":"CLOSE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":298,"itemtype":"property","name":"OPEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":303,"itemtype":"property","name":"CHORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":308,"itemtype":"property","name":"PIE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":313,"itemtype":"property","name":"PROJECT","type":"String","final":1,"default":"square","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":319,"itemtype":"property","name":"SQUARE","type":"String","final":1,"default":"butt","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":325,"itemtype":"property","name":"ROUND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":330,"itemtype":"property","name":"BEVEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":335,"itemtype":"property","name":"MITER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":342,"itemtype":"property","name":"RGB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":347,"description":"<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n","itemtype":"property","name":"HSB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":356,"itemtype":"property","name":"HSL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":363,"description":"<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n","itemtype":"property","name":"AUTO","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":373,"itemtype":"property","name":"ALT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":379,"itemtype":"property","name":"BACKSPACE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":384,"itemtype":"property","name":"CONTROL","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":389,"itemtype":"property","name":"DELETE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":394,"itemtype":"property","name":"DOWN_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":399,"itemtype":"property","name":"ENTER","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":404,"itemtype":"property","name":"ESCAPE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":409,"itemtype":"property","name":"LEFT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":414,"itemtype":"property","name":"OPTION","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":419,"itemtype":"property","name":"RETURN","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":424,"itemtype":"property","name":"RIGHT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":429,"itemtype":"property","name":"SHIFT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":434,"itemtype":"property","name":"TAB","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":439,"itemtype":"property","name":"UP_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":446,"itemtype":"property","name":"BLEND","type":"String","final":1,"default":"source-over","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":452,"itemtype":"property","name":"REMOVE","type":"String","final":1,"default":"destination-out","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":458,"itemtype":"property","name":"ADD","type":"String","final":1,"default":"lighter","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":466,"itemtype":"property","name":"DARKEST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":471,"itemtype":"property","name":"LIGHTEST","type":"String","final":1,"default":"lighten","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":477,"itemtype":"property","name":"DIFFERENCE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":482,"itemtype":"property","name":"SUBTRACT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":487,"itemtype":"property","name":"EXCLUSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":492,"itemtype":"property","name":"MULTIPLY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":497,"itemtype":"property","name":"SCREEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":502,"itemtype":"property","name":"REPLACE","type":"String","final":1,"default":"copy","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":508,"itemtype":"property","name":"OVERLAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":513,"itemtype":"property","name":"HARD_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":518,"itemtype":"property","name":"SOFT_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":523,"itemtype":"property","name":"DODGE","type":"String","final":1,"default":"color-dodge","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":529,"itemtype":"property","name":"BURN","type":"String","final":1,"default":"color-burn","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":537,"itemtype":"property","name":"THRESHOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":542,"itemtype":"property","name":"GRAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":547,"itemtype":"property","name":"OPAQUE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":552,"itemtype":"property","name":"INVERT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":557,"itemtype":"property","name":"POSTERIZE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":562,"itemtype":"property","name":"DILATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":567,"itemtype":"property","name":"ERODE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":572,"itemtype":"property","name":"BLUR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":579,"itemtype":"property","name":"NORMAL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":584,"itemtype":"property","name":"ITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":589,"itemtype":"property","name":"BOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":594,"itemtype":"property","name":"BOLDITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":599,"itemtype":"property","name":"CHAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":604,"itemtype":"property","name":"WORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":616,"itemtype":"property","name":"LINEAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":621,"itemtype":"property","name":"QUADRATIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":626,"itemtype":"property","name":"BEZIER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":631,"itemtype":"property","name":"CURVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":638,"itemtype":"property","name":"STROKE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":643,"itemtype":"property","name":"FILL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":648,"itemtype":"property","name":"TEXTURE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":653,"itemtype":"property","name":"IMMEDIATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":661,"itemtype":"property","name":"IMAGE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":669,"itemtype":"property","name":"NEAREST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":674,"itemtype":"property","name":"REPEAT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":679,"itemtype":"property","name":"CLAMP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":684,"itemtype":"property","name":"MIRROR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":691,"itemtype":"property","name":"LANDSCAPE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":696,"itemtype":"property","name":"PORTRAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":706,"itemtype":"property","name":"GRID","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":712,"itemtype":"property","name":"AXES","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":718,"itemtype":"property","name":"LABEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":723,"itemtype":"property","name":"FALLBACK","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/environment.js","line":20,"description":"<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n","itemtype":"method","name":"print","params":[{"name":"contents","description":"<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n","type":"Any"}],"example":["\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"],"alt":"default grey canvas","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":52,"description":"<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n","itemtype":"property","name":"frameCount","type":"Integer","readonly":"","example":["\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"],"alt":"numbers rapidly counting upward with frame count set to 30.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":79,"description":"<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n","itemtype":"property","name":"deltaTime","type":"Integer","readonly":"","example":["\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":129,"description":"<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n","itemtype":"property","name":"focused","type":"Boolean","readonly":"","example":["\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"],"alt":"green 50×50 ellipse at top left. Red X covers canvas when page focus changes","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":160,"description":"<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n","itemtype":"method","name":"cursor","params":[{"name":"type","description":"<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n","type":"String|Constant"},{"name":"x","description":"<p>the horizontal active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the vertical active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"],"alt":"canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":228,"description":"<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n","itemtype":"method","name":"frameRate","chainable":1,"example":["\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"blue rect moves left to right, followed by red rect moving faster. Loops.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":228,"params":[{"name":"fps","description":"<p>number of frames to be displayed every second</p>\n","type":"Number"}],"chainable":1},{"line":288,"params":[],"return":{"description":"current frameRate","type":"Number"}}]},{"file":"src/core/environment.js","line":331,"description":"<p>Hides the cursor from view.</p>\n","itemtype":"method","name":"noCursor","example":["\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"],"alt":"cursor becomes 10×10 white ellipse the moves with mouse x and y.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":354,"description":"<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":372,"description":"<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":390,"description":"<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n","itemtype":"property","name":"windowWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":405,"description":"<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n","itemtype":"property","name":"windowHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":421,"description":"<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n","itemtype":"method","name":"windowResized","params":[{"name":"event","description":"<p>optional Event callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":476,"description":"<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":488,"description":"<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":500,"description":"<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n","itemtype":"method","name":"fullscreen","params":[{"name":"val","description":"<p>whether the sketch should be in fullscreen mode\nor not</p>\n","type":"Boolean","optional":true}],"return":{"description":"current fullscreen state","type":"Boolean"},"example":["\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":550,"description":"<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n","itemtype":"method","name":"pixelDensity","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":550,"params":[{"name":"val","description":"<p>whether or how much the sketch should scale</p>\n","type":"Number"}],"chainable":1},{"line":586,"params":[],"return":{"description":"current pixel density of the sketch","type":"Number"}}]},{"file":"src/core/environment.js","line":605,"description":"<p>Returns the pixel density of the current display the sketch is running on.</p>\n","itemtype":"method","name":"displayDensity","return":{"description":"current pixel density of the display","type":"Number"},"example":["\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":660,"description":"<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURL","return":{"description":"url","type":"String"},"example":["\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"],"alt":"current url (http://p5js.org/reference/#/p5/getURL) moves right to left.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":691,"description":"<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLPath","return":{"description":"path components","type":"String[]"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":713,"description":"<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLParams","return":{"description":"URL params","type":"Object"},"example":["\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/helpers.js","line":1,"requires":["constants"],"class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":30,"description":"<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":126,"description":"<p>Set up our translation function, with loaded languages</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":171,"description":"<p>Returns a list of languages we have translations loaded for</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":178,"description":"<p>Returns the current language selected for translation</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":185,"description":"<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/legacy.js","line":1,"requires":["core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name","in others","they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."],"class":"p5","module":"Environment"},{"file":"src/core/main.js","line":42,"description":"<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n","itemtype":"method","name":"preload","example":["\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":83,"description":"<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n","itemtype":"method","name":"setup","example":["\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":114,"description":"<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n","itemtype":"method","name":"draw","example":["\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":415,"description":"<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":693,"description":"<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n","itemtype":"property","name":"disableFriendlyErrors","type":"Boolean","example":["\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"],"class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/p5.Element.js","line":21,"description":"<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"],"itemtype":"property","name":"elt","readonly":"","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":47,"description":"<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"parent","chainable":1,"example":["\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":47,"params":[{"name":"parent","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n","type":"String|p5.Element|Object"}],"chainable":1},{"line":93,"params":[],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/core/p5.Element.js","line":114,"description":"<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n","itemtype":"method","name":"id","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":114,"params":[{"name":"id","description":"<p>ID of the element</p>\n","type":"String"}],"chainable":1},{"line":139,"params":[],"return":{"description":"the id of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":154,"description":"<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n","itemtype":"method","name":"class","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":154,"params":[{"name":"class","description":"<p>class to add</p>\n","type":"String"}],"chainable":1},{"line":176,"params":[],"return":{"description":"the class of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":189,"description":"<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":246,"description":"<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"return":{"description":"","type":"p5.Element"},"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":292,"description":"<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":354,"description":"<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":403,"description":"<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":454,"description":"<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":510,"description":"<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOver","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":551,"description":"<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOut","params":[{"name":"fxn","description":"<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":592,"description":"<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"fxn","description":"<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":639,"description":"<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"fxn","description":"<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":678,"description":"<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"fxn","description":"<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":725,"description":"<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragOver","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":763,"description":"<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragLeave","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":827,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Graphics.js","line":70,"description":"<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n","itemtype":"method","name":"reset","example":["\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"],"alt":"A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Graphics.js","line":122,"description":"<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"],"alt":"no image\na multi-colored circle moving back and forth over a scrolling background.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":99,"description":"<p>Resize our canvas element.</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":415,"description":"<p>Helper function to check font type (system or otf)</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":467,"description":"<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":7,"description":"<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":402,"description":"<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/reference.js","line":7,"description":"<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n","itemtype":"property","name":"let","example":["\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":34,"description":"<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n","itemtype":"property","name":"const","example":["\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"],"alt":"These examples do not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":87,"description":"<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n","itemtype":"property","name":"===","example":["\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":115,"description":"<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>","itemtype":"property","name":">","example":["\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":137,"description":"<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":">=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":158,"description":"<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<","example":["\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":179,"description":"<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":200,"description":"<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n","itemtype":"property","name":"if-else","example":["\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":231,"description":"<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n","itemtype":"property","name":"function","example":["\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":267,"description":"<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n","itemtype":"property","name":"return","example":["\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":288,"description":"<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n","itemtype":"property","name":"boolean","example":["\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":309,"description":"<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n","itemtype":"property","name":"string","example":["\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":331,"description":"<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n","itemtype":"property","name":"number","example":["\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":351,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n","itemtype":"property","name":"object","example":["\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":379,"description":"<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n","itemtype":"property","name":"class","example":["\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":408,"description":"<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n","itemtype":"property","name":"for","example":["\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":448,"description":"<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n","itemtype":"property","name":"while","example":["\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":490,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n","itemtype":"method","name":"stringify","static":1,"params":[{"name":"object","description":"<p>:Javascript object that you would like to convert to JSON</p>\n","type":"Object"}],"example":["\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"JSON","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":512,"description":"<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n","itemtype":"method","name":"log","static":1,"params":[{"name":"message","description":"<p>:Message that you would like to print to the console</p>\n","type":"String|Expression|Object"}],"example":["\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"console","module":"Foundation","submodule":"Foundation"},{"file":"src/core/rendering.js","line":15,"description":"<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"createCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL</p>\n","type":"Constant","optional":true}],"return":{"description":"","type":"p5.Renderer"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"],"alt":"Black line extending from top-left of canvas to bottom right.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":125,"description":"<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n","itemtype":"method","name":"resizeCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"noRedraw","description":"<p>don't redraw the canvas immediately</p>\n","type":"Boolean","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"No image displayed.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":183,"description":"<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n","itemtype":"method","name":"noCanvas","example":["\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":204,"description":"<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n","itemtype":"method","name":"createGraphics","params":[{"name":"w","description":"<p>width of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"h","description":"<p>height of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n","type":"Constant","optional":true}],"return":{"description":"offscreen graphics buffer","type":"p5.Graphics"},"example":["\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"4 grey squares alternating light and dark grey. White quarter circle mid-left.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":243,"description":"<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n","itemtype":"method","name":"blendMode","params":[{"name":"mode","description":"<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"],"alt":"translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":326,"description":"<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n","itemtype":"property","name":"drawingContext","example":["\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"white ellipse with shadow blur effect around edges","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/shim.js","line":18,"description":"<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/shim.js","line":39,"description":"<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n","class":"p5","module":"Rendering"},{"file":"src/core/structure.js","line":10,"description":"<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"noLoop","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"],"alt":"113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":83,"description":"<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"loop","example":["\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"],"alt":"horizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":134,"description":"<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n","itemtype":"method","name":"isLooping","example":["\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"],"alt":"Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":192,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"push","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":290,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"pop","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":391,"description":"<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n","itemtype":"method","name":"redraw","params":[{"name":"n","description":"<p>Redraw for n-times. The default value is 1.</p>\n","type":"Integer","optional":true}],"example":["\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"],"alt":"black line on far left of canvas\nblack line on far left of canvas","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":497,"description":"<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n","itemtype":"method","name":"p5","params":[{"name":"sketch","description":"<p>a function containing a p5.js sketch</p>\n","type":"Object"},{"name":"node","description":"<p>ID or pointer to HTML DOM node to contain sketch in</p>\n","type":"String|Object"}],"example":["\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"],"alt":"white rectangle on black background","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/transform.js","line":11,"description":"<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n","itemtype":"method","name":"applyMatrix","params":[{"name":"a","description":"<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n","type":"Number|Array"},{"name":"b","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"c","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"d","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"e","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"f","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":168,"description":"<p>Replaces the current matrix with the identity matrix.</p>\n","itemtype":"method","name":"resetMatrix","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"],"alt":"A rotated rectangle in the center with another at the top left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":193,"description":"<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"rotate","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"},{"name":"axis","description":"<p>(in 3d) the axis to rotate around</p>\n","type":"p5.Vector|Number[]","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":232,"description":"<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateX","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the x axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":268,"description":"<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateY","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the y axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":304,"description":"<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateZ","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the z axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":342,"description":"<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"scale","chainable":1,"example":["\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":342,"params":[{"name":"s","description":"<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n","type":"Number|p5.Vector|Number[]"},{"name":"y","description":"<p>percent to scale the object in the y-axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>percent to scale the object in the z-axis (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":386,"params":[{"name":"scales","description":"<p>per-axis percents to scale the object</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/core/transform.js","line":416,"description":"<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearX","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at top middle.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":455,"description":"<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearY","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at middle bottom.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":494,"description":"<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"translate","chainable":1,"example":["\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"],"alt":"white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":494,"params":[{"name":"x","description":"<p>left/right translation</p>\n","type":"Number"},{"name":"y","description":"<p>up/down translation</p>\n","type":"Number"},{"name":"z","description":"<p>forward/backward translation (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":547,"params":[{"name":"vector","description":"<p>the vector to translate by</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/data/local_storage.js","line":10,"description":"<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n","itemtype":"method","name":"storeItem","params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String|Number|Object|Boolean|p5.Color|p5.Vector"}],"example":["\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"],"alt":"When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":101,"description":"<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n","itemtype":"method","name":"getItem","params":[{"name":"key","description":"<p>name that you wish to use to store in local storage</p>\n","type":"String"}],"return":{"description":"Value of stored item","type":"Number|Object|String|Boolean|p5.Color|p5.Vector"},"example":["\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"],"alt":"If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":177,"description":"<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n","itemtype":"method","name":"clearStorage","example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":205,"description":"<p>Removes an item that was stored with storeItem()</p>\n","itemtype":"method","name":"removeItem","params":[{"name":"key","description":"","type":"String"}],"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/p5.TypedDict.js","line":14,"description":"<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n","itemtype":"method","name":"createStringDict","return":{"description":"","type":"p5.StringDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":14,"params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String"}],"return":{"description":"","type":"p5.StringDict"}},{"line":37,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.StringDict"}}]},{"file":"src/data/p5.TypedDict.js","line":48,"description":"<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n","itemtype":"method","name":"createNumberDict","return":{"description":"","type":"p5.NumberDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":48,"params":[{"name":"key","description":"","type":"Number"},{"name":"value","description":"","type":"Number"}],"return":{"description":"","type":"p5.NumberDict"}},{"line":71,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.NumberDict"}}]},{"file":"src/data/p5.TypedDict.js","line":101,"description":"<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n","itemtype":"method","name":"size","return":{"description":"the number of key-value pairs in the Dictionary","type":"Integer"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":122,"description":"<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n","itemtype":"method","name":"hasKey","params":[{"name":"key","description":"<p>that you want to look up</p>\n","type":"Number|String"}],"return":{"description":"whether that key exists in Dictionary","type":"Boolean"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":144,"description":"<p>Returns the value stored at the given key.</p>\n","itemtype":"method","name":"get","params":[{"name":"the","description":"<p>key you want to access</p>\n","type":"Number|String"}],"return":{"description":"the value stored at that key","type":"Number|String"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":170,"description":"<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n","itemtype":"method","name":"set","params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":197,"description":"<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":208,"description":"<p>Creates a new key-value pair in the Dictionary.</p>\n","itemtype":"method","name":"create","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary","overloads":[{"line":208,"params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}]},{"line":226,"params":[{"name":"obj","description":"<p>key/value pair</p>\n","type":"Object"}]}]},{"file":"src/data/p5.TypedDict.js","line":244,"description":"<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n","itemtype":"method","name":"clear","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":265,"description":"<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n","itemtype":"method","name":"remove","params":[{"name":"key","description":"<p>for the pair to remove</p>\n","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":294,"description":"<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n","itemtype":"method","name":"print","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":318,"description":"<p>Converts the Dictionary into a CSV file for local download.</p>\n","itemtype":"method","name":"saveTable","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":356,"description":"<p>Converts the Dictionary into a JSON file for local download.</p>\n","itemtype":"method","name":"saveJSON","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":387,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":425,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":432,"description":"<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"add","params":[{"name":"Key","description":"<p>for the value you wish to add to</p>\n","type":"Number"},{"name":"Number","description":"<p>to add to the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":459,"description":"<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"sub","params":[{"name":"Key","description":"<p>for the value you wish to subtract from</p>\n","type":"Number"},{"name":"Number","description":"<p>to subtract from the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":482,"description":"<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"mult","params":[{"name":"Key","description":"<p>for value you wish to multiply</p>\n","type":"Number"},{"name":"Amount","description":"<p>to multiply the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":509,"description":"<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"div","params":[{"name":"Key","description":"<p>for value you wish to divide</p>\n","type":"Number"},{"name":"Amount","description":"<p>to divide the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":536,"description":"<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":560,"description":"<p>Return the lowest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"minValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":580,"description":"<p>Return the highest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"maxValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":600,"description":"<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":622,"description":"<p>Return the lowest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"minKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":642,"description":"<p>Return the highest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"maxKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/dom/dom.js","line":21,"description":"<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n","itemtype":"method","name":"select","params":[{"name":"selectors","description":"<p>CSS selector string of element to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"<a href=\"#/p5.Element\">p5.Element</a> containing node found","type":"p5.Element|null"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":68,"description":"<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n","itemtype":"method","name":"selectAll","params":[{"name":"selectors","description":"<p>CSS selector string of elements to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found","type":"p5.Element[]"},"example":["\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":127,"description":"<p>Helper function for select and selectAll</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":142,"description":"<p>Helper function for getElement and getElements.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":176,"description":"<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n","itemtype":"method","name":"removeElements","example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":204,"description":"<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n","itemtype":"method","name":"changed","params":[{"name":"fxn","description":"<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"],"alt":"dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":271,"description":"<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n","itemtype":"method","name":"input","params":[{"name":"fxn","description":"<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"alt":"no display.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":309,"description":"<p>Helpers for create methods.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":322,"description":"<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createDiv","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":341,"description":"<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n","itemtype":"method","name":"createP","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":361,"description":"<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createSpan","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":379,"description":"<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n","itemtype":"method","name":"createImg","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":379,"params":[{"name":"src","description":"<p>src path or url for image</p>\n","type":"String"},{"name":"alt","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":396,"params":[{"name":"src","description":"","type":"String"},{"name":"alt","description":"","type":"String"},{"name":"crossOrigin","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n","type":"String"},{"name":"successCallback","description":"<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":426,"description":"<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n","itemtype":"method","name":"createA","params":[{"name":"href","description":"<p>url of page to link to</p>\n","type":"String"},{"name":"html","description":"<p>inner html of link element to display</p>\n","type":"String"},{"name":"target","description":"<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":450,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":452,"description":"<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n","itemtype":"method","name":"createSlider","params":[{"name":"min","description":"<p>minimum value of the slider</p>\n","type":"Number"},{"name":"max","description":"<p>maximum value of the slider</p>\n","type":"Number"},{"name":"value","description":"<p>default value of the slider</p>\n","type":"Number","optional":true},{"name":"step","description":"<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n","type":"Number","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":507,"description":"<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n","itemtype":"method","name":"createButton","params":[{"name":"label","description":"<p>label displayed on the button</p>\n","type":"String"},{"name":"value","description":"<p>value of the button</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":541,"description":"<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n","itemtype":"method","name":"createCheckbox","params":[{"name":"label","description":"<p>label displayed after checkbox</p>\n","type":"String","optional":true},{"name":"value","description":"<p>value of the checkbox; checked is true, unchecked is false</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":622,"description":"<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n","itemtype":"method","name":"createSelect","return":{"description":"","type":"p5.Element"},"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":622,"params":[{"name":"multiple","description":"<p>true if dropdown should support multiple selections</p>\n","type":"Boolean","optional":true}],"return":{"description":"","type":"p5.Element"}},{"line":673,"params":[{"name":"existing","description":"<p>DOM select element</p>\n","type":"Object"}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":770,"description":"<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n","itemtype":"method","name":"createRadio","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":770,"params":[{"name":"containerElement","description":"<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n","type":"Object"},{"name":"name","description":"<p>A name parameter for each Input Element.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":832,"params":[{"name":"name","description":"","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":837,"params":[],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":978,"description":"<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n","itemtype":"method","name":"createColorPicker","params":[{"name":"value","description":"<p>default color of element</p>\n","type":"String|p5.Color","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1066,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n","itemtype":"method","name":"createInput","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":1066,"params":[{"name":"value","description":"<p>default value of the input box</p>\n","type":"String"},{"name":"type","description":"<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":1091,"params":[{"name":"value","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":1104,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n","itemtype":"method","name":"createFileInput","params":[{"name":"callback","description":"<p>callback function for when a file is loaded</p>\n","type":"Function"},{"name":"multiple","description":"<p>optional, to allow multiple files to be selected</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element","type":"p5.Element"},"example":["\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1164,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1211,"description":"<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n","itemtype":"method","name":"createVideo","params":[{"name":"src","description":"<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n","type":"String|String[]"},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1257,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1259,"description":"<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n","itemtype":"method","name":"createAudio","params":[{"name":"src","description":"<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n","type":"String|String[]","optional":true},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1296,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1298,"itemtype":"property","name":"VIDEO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1304,"itemtype":"property","name":"AUDIO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1341,"description":"<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n","itemtype":"method","name":"createCapture","params":[{"name":"type","description":"<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n","type":"String|Constant|Object"},{"name":"callback","description":"<p>function to be called once\n                                  stream has loaded</p>\n","type":"Function","optional":true}],"return":{"description":"capture video <a href=\"#/p5.Element\">p5.Element</a>","type":"p5.Element"},"example":["\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1478,"description":"<p>Creates element with given tag in the DOM with given content.</p>\n","itemtype":"method","name":"createElement","params":[{"name":"tag","description":"<p>tag for the new element</p>\n","type":"String"},{"name":"content","description":"<p>html content to be inserted into the element</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1504,"description":"<p>Adds specified class to the element.</p>\n","itemtype":"method","name":"addClass","params":[{"name":"class","description":"<p>name of class to add</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1529,"description":"<p>Removes specified class from the element.</p>\n","itemtype":"method","name":"removeClass","params":[{"name":"class","description":"<p>name of class to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1560,"description":"<p>Checks if specified class already set to element</p>\n","itemtype":"method","name":"hasClass","return":{"description":"a boolean value if element has specified class","type":"Boolean"},"params":[{"name":"c","description":"<p>class name of class to check</p>\n","type":"String"}],"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1589,"description":"<p>Toggles element class</p>\n","itemtype":"method","name":"toggleClass","params":[{"name":"c","description":"<p>class name to toggle</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1622,"description":"<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n","itemtype":"method","name":"child","return":{"description":"an array of child nodes","type":"Node[]"},"example":["\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1622,"params":[],"return":{"description":"an array of child nodes","type":"Node[]"}},{"line":1650,"params":[{"name":"child","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n","type":"String|p5.Element","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1675,"description":"<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n","itemtype":"method","name":"center","params":[{"name":"align","description":"<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n","type":"String","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1726,"description":"<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n","itemtype":"method","name":"html","return":{"description":"the inner HTML of the element","type":"String"},"example":["\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1726,"params":[],"return":{"description":"the inner HTML of the element","type":"String"}},{"line":1747,"params":[{"name":"html","description":"<p>the HTML to be placed inside the element</p>\n","type":"String","optional":true},{"name":"append","description":"<p>whether to append HTML to existing</p>\n","type":"Boolean","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1765,"description":"<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n","itemtype":"method","name":"position","return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"},"example":["\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1765,"params":[],"return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"}},{"line":1798,"params":[{"name":"x","description":"<p>x-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"positionType","description":"<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n","type":"String","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1885,"description":"<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n","itemtype":"method","name":"style","return":{"description":"value of property","type":"String"},"example":["\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1885,"params":[{"name":"property","description":"<p>property to be set</p>\n","type":"String"}],"return":{"description":"value of property","type":"String"}},{"line":1923,"params":[{"name":"property","description":"","type":"String"},{"name":"value","description":"<p>value to assign to property</p>\n","type":"String|p5.Color"}],"chainable":1,"return":{"description":"current value of property, if no value is given as second argument","type":"String"}}]},{"file":"src/dom/dom.js","line":1980,"description":"<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n","itemtype":"method","name":"attribute","return":{"description":"value of attribute","type":"String"},"example":["\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1980,"params":[],"return":{"description":"value of attribute","type":"String"}},{"line":1995,"params":[{"name":"attr","description":"<p>attribute to set</p>\n","type":"String"},{"name":"value","description":"<p>value to assign to attribute</p>\n","type":"String"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2024,"description":"<p>Removes an attribute on the specified element.</p>\n","itemtype":"method","name":"removeAttribute","params":[{"name":"attr","description":"<p>attribute to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2069,"description":"<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n","itemtype":"method","name":"value","return":{"description":"value of the element","type":"String|Number"},"example":["\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2069,"params":[],"return":{"description":"value of the element","type":"String|Number"}},{"line":2099,"params":[{"name":"value","description":"","type":"String|Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2115,"description":"<p>Shows the current element. Essentially, setting display:block for the style.</p>\n","itemtype":"method","name":"show","chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2133,"description":"<p>Hides the current element. Essentially, setting display:none for the style.</p>\n","itemtype":"method","name":"hide","chainable":1,"example":["\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2149,"description":"<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n","itemtype":"method","name":"size","return":{"description":"the width and height of the element in an object","type":"Object"},"example":["\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2149,"params":[],"return":{"description":"the width and height of the element in an object","type":"Object"}},{"line":2173,"params":[{"name":"w","description":"<p>width of the element, either AUTO, or a number</p>\n","type":"Number|Constant"},{"name":"h","description":"<p>height of the element, either AUTO, or a number</p>\n","type":"Number|Constant","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":2230,"description":"<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2268,"description":"<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n","itemtype":"method","name":"drop","params":[{"name":"callback","description":"<p>callback to receive loaded file, called for each file dropped.</p>\n","type":"Function"},{"name":"fxn","description":"<p>callback triggered once when files are dropped with the drop event.</p>\n","type":"Function","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"],"alt":"Canvas turns into whatever image is dragged/dropped onto it.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2400,"description":"<p>Path to the media element source.</p>\n","itemtype":"property","name":"src","return":{"description":"src","type":"String"},"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2466,"description":"<p>Play an HTML5 media element.</p>\n","itemtype":"method","name":"play","chainable":1,"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2530,"description":"<p>Stops an HTML5 media element (sets current time to zero).</p>\n","itemtype":"method","name":"stop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2594,"description":"<p>Pauses an HTML5 media element.</p>\n","itemtype":"method","name":"pause","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2656,"description":"<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n","itemtype":"method","name":"loop","chainable":1,"example":["\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2712,"description":"<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n","itemtype":"method","name":"noLoop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2778,"description":"<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n","itemtype":"method","name":"autoplay","params":[{"name":"shouldAutoplay","description":"<p>whether the element should autoplay</p>\n","type":"Boolean"}],"chainable":1,"example":["\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"],"alt":"An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2845,"description":"<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n","itemtype":"method","name":"volume","return":{"description":"current volume","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2845,"params":[],"return":{"description":"current volume","type":"Number"}},{"line":2918,"params":[{"name":"val","description":"<p>volume between 0.0 and 1.0</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2931,"description":"<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n","itemtype":"method","name":"speed","return":{"description":"current playback speed of the element","type":"Number"},"example":["\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2931,"params":[],"return":{"description":"current playback speed of the element","type":"Number"}},{"line":3003,"params":[{"name":"speed","description":"<p>speed multiplier for element playback</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3020,"description":"<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n","itemtype":"method","name":"time","return":{"description":"current time (in seconds)","type":"Number"},"example":["\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":3020,"params":[],"return":{"description":"current time (in seconds)","type":"Number"}},{"line":3065,"params":[{"name":"time","description":"<p>time to jump to (in seconds)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3079,"description":"<p>Returns the duration of the HTML5 media element.</p>\n","itemtype":"method","name":"duration","return":{"description":"duration","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3201,"description":"<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n","type":"Function"}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3232,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3234,"description":"<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n","itemtype":"method","name":"connect","params":[{"name":"audioNode","description":"<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n","type":"AudioNode|Object"}],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3283,"description":"<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n","itemtype":"method","name":"disconnect","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3298,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3300,"description":"<p>Show the default MediaElement controls, as determined by the web browser.</p>\n","itemtype":"method","name":"showControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3331,"description":"<p>Hide the default mediaElement controls.</p>\n","itemtype":"method","name":"hideControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3360,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3371,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3434,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3476,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3542,"description":"<p>Underlying File object. All normal File methods can be called on this.</p>\n","itemtype":"property","name":"file","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3554,"description":"<p>File type (image, text, etc.)</p>\n","itemtype":"property","name":"type","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3560,"description":"<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n","itemtype":"property","name":"subtype","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3566,"description":"<p>File name</p>\n","itemtype":"property","name":"name","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3572,"description":"<p>File size</p>\n","itemtype":"property","name":"size","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3579,"description":"<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n","itemtype":"property","name":"data","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/events/acceleration.js","line":11,"description":"<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n","itemtype":"property","name":"deviceOrientation","type":"Constant","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":23,"description":"<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":46,"description":"<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":69,"description":"<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationZ","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":94,"description":"<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":104,"description":"<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":114,"description":"<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":135,"description":"<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationX","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":168,"description":"<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":201,"description":"<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"itemtype":"property","name":"rotationZ","type":"Number","readonly":"","alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":239,"description":"<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":285,"description":"<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":330,"description":"<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":389,"description":"<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n","itemtype":"property","name":"turnAxis","type":"String","readonly":"","example":["\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":428,"description":"<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n","itemtype":"method","name":"setMoveThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":471,"description":"<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n","itemtype":"method","name":"setShakeThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":515,"description":"<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n","itemtype":"method","name":"deviceMoved","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":546,"description":"<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n","itemtype":"method","name":"deviceTurned","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":604,"description":"<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n","itemtype":"method","name":"deviceShaken","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device shakes","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/keyboard.js","line":10,"description":"<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n","itemtype":"property","name":"keyIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white rect that turns black on keypress.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":36,"description":"<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n","itemtype":"property","name":"key","type":"String","readonly":"","example":["\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"],"alt":"canvas displays any key value that is pressed in pink font.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":64,"description":"<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n","itemtype":"property","name":"keyCode","type":"Integer","readonly":"","example":["\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"],"alt":"Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":103,"description":"<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyPressed","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":190,"description":"<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyReleased","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when pressed again","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":243,"description":"<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"keyTyped","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"],"alt":"black rect center. turns white when 'a' key typed and black when 'b' pressed","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":298,"description":"<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":308,"description":"<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n","itemtype":"method","name":"keyIsDown","params":[{"name":"code","description":"<p>The key to check for.</p>\n","type":"Number"}],"return":{"description":"whether key is down or not","type":"Boolean"},"example":["\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"],"alt":"50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/mouse.js","line":12,"description":"<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedX","type":"Number","readonly":"","example":["\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"],"alt":"box moves left and right according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":43,"description":"<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedY","type":"Number","readonly":"","example":["\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"box moves up and down according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":80,"description":"<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"],"alt":"horizontal black line moves left and right with mouse x-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":106,"description":"<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"],"alt":"vertical black line moves up and down with mouse y-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":132,"description":"<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"],"alt":"line trail is created from cursor movements. faster movement make longer line.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":164,"description":"<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"],"alt":"60×60 black rect center, fuchsia background. rect flickers on mouse movement","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":195,"description":"<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":233,"description":"<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":271,"description":"<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":311,"description":"<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":351,"description":"<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n","itemtype":"property","name":"mouseButton","type":"Constant","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"],"alt":"50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":389,"description":"<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n","itemtype":"property","name":"mouseIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":481,"description":"<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":535,"description":"<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseDragged","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":615,"description":"<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":696,"description":"<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":772,"description":"<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":841,"description":"<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":926,"description":"<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"event","description":"<p>optional WheelEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"],"alt":"black 50×50 rect moves up and down with vertical scroll. fuchsia background","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":979,"description":"<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n","itemtype":"method","name":"requestPointerLock","example":["\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"],"alt":"3D scene moves according to mouse mouse movement in a first person perspective","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":1025,"description":"<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n","itemtype":"method","name":"exitPointerLock","example":["\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"],"alt":"cursor gets locked / unlocked on mouse-click","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/touch.js","line":10,"description":"<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n","itemtype":"property","name":"touches","type":"Object[]","readonly":"","example":["\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"],"alt":"Number of touches currently registered are displayed on the canvas","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":71,"description":"<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch event.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":151,"description":"<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns lighter with touch until white. resets\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":223,"description":"<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/image/filters.js","line":3,"description":"<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n","class":"p5","module":"Events"},{"file":"src/image/image.js","line":8,"description":"<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":15,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n","itemtype":"method","name":"createImage","params":[{"name":"width","description":"<p>width in pixels</p>\n","type":"Integer"},{"name":"height","description":"<p>height in pixels</p>\n","type":"Integer"}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":94,"description":"<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n","itemtype":"method","name":"saveCanvas","example":["\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"],"alt":"no image displayed\n no image displayed\n no image displayed","class":"p5","module":"Image","submodule":"Image","overloads":[{"line":94,"params":[{"name":"selectedCanvas","description":"<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n","type":"p5.Element|HTMLCanvasElement"},{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String","optional":true}]},{"line":136,"params":[{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"","type":"String","optional":true}]}]},{"file":"src/image/image.js","line":413,"description":"<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n","itemtype":"method","name":"saveFrames","params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String"},{"name":"duration","description":"<p>Duration in seconds to save the frames for.</p>\n","type":"Number"},{"name":"framerate","description":"<p>Framerate to save the frames in.</p>\n","type":"Number"},{"name":"callback","description":"<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n","type":"Function(Array)","optional":true}],"example":["\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"],"alt":"canvas background goes from light to dark with mouse x.","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/loading_displaying.js","line":18,"description":"<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n","itemtype":"method","name":"loadImage","params":[{"name":"path","description":"<p>Path of the image to be loaded</p>\n","type":"String"},{"name":"successCallback","description":"<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n","type":"function(p5.Image)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                               the image fails to load.</p>\n","type":"Function(Event)","optional":true}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":162,"description":"<p>Helper function for loading GIF-based images</p>\n","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":301,"description":"<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n","itemtype":"method","name":"image","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":301,"params":[{"name":"img","description":"<p>the image to display</p>\n","type":"p5.Image|p5.Element|p5.Texture"},{"name":"x","description":"<p>the x-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"width","description":"<p>the width to draw the image</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>the height to draw the image</p>\n","type":"Number","optional":true}]},{"line":388,"params":[{"name":"img","description":"","type":"p5.Image|p5.Element|p5.Texture"},{"name":"dx","description":"<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dy","description":"<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dWidth","description":"<p>the width of the destination rectangle</p>\n","type":"Number"},{"name":"dHeight","description":"<p>the height of the destination rectangle</p>\n","type":"Number"},{"name":"sx","description":"<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sy","description":"<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sWidth","description":"<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n","type":"Number","optional":true},{"name":"sHeight","description":"<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n","type":"Number","optional":true}]}]},{"file":"src/image/loading_displaying.js","line":471,"description":"<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n","itemtype":"method","name":"tint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":471,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":542,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}]},{"line":547,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":553,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}]},{"line":559,"params":[{"name":"color","description":"<p>the tint color</p>\n","type":"p5.Color"}]}]},{"file":"src/image/loading_displaying.js","line":569,"description":"<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n","itemtype":"method","name":"noTint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of bricks, left image with blue tint","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":633,"description":"<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n","itemtype":"method","name":"imageMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, or CENTER</p>\n","type":"Constant"}],"example":["\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"],"alt":"small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/p5.Image.js","line":9,"description":"<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":88,"description":"<p>Image width.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"],"alt":"rocky mountains in top and horizontal lines in corresponding colors in bottom.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":115,"description":"<p>Image height.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"],"alt":"rocky mountains on right and vertical lines in corresponding colors on left.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":152,"description":"<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":222,"description":"<p>Helper function for animating GIF-based images with time</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":253,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":261,"description":"<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":296,"description":"<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n","itemtype":"method","name":"updatePixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":296,"params":[{"name":"x","description":"<p>x-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"y","description":"<p>y-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"w","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"h","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"}]},{"line":338,"params":[]}]},{"file":"src/image/p5.Image.js","line":346,"description":"<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"],"alt":"image of rocky mountains with 50×50 green rect in front","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":346,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":383,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":387,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/p5.Image.js","line":400,"description":"<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"a","description":"<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"],"alt":"2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":437,"description":"<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n","itemtype":"method","name":"resize","params":[{"name":"width","description":"<p>the resized image width</p>\n","type":"Number"},{"name":"height","description":"<p>the resized image height</p>\n","type":"Number"}],"example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"],"alt":"image of rocky mountains. zoomed in","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":548,"description":"<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains and smaller image on top of bricks at top left","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":548,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":588,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/p5.Image.js","line":603,"description":"<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n","itemtype":"method","name":"mask","params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"}],"example":["\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":665,"description":"<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"],"alt":"2 images of rocky mountains left one in color, right in black and white","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":738,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":738,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n","type":"Constant"}]},{"line":815,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/p5.Image.js","line":859,"description":"<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n","itemtype":"method","name":"save","params":[{"name":"filename","description":"<p>give your file a name</p>\n","type":"String"},{"name":"extension","description":"<p>'png' or 'jpg'</p>\n","type":"String"}],"example":["\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"],"alt":"image of rocky mountains.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":900,"description":"<p>Starts an animated GIF over at the beginning state.</p>\n","itemtype":"method","name":"reset","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"],"alt":"Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":941,"description":"<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n","itemtype":"method","name":"getCurrentFrame","return":{"description":"The index for the currently displaying frame in animated GIF","type":"Number"},"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"],"alt":"Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":972,"description":"<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n","itemtype":"method","name":"setFrame","params":[{"name":"index","description":"<p>the index for the frame that should be displayed</p>\n","type":"Number"}],"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1017,"description":"<p>Returns the number of frames in an animated GIF</p>\n","itemtype":"method","name":"numFrames","return":{"description":"","type":"Number"},"example":["     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1052,"description":"<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n","itemtype":"method","name":"play","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1089,"description":"<p>Pauses an animated GIF.</p>\n","itemtype":"method","name":"pause","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1125,"description":"<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n","itemtype":"method","name":"delay","params":[{"name":"d","description":"<p>the amount in milliseconds to delay between switching frames</p>\n","type":"Number"},{"name":"index","description":"<p>the index of the frame that should have the new delay value {optional}</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"],"alt":"Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/pixels.js","line":12,"description":"<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"],"alt":"top half of canvas pink, bottom grey","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":80,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":80,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n","type":"Constant"}]},{"line":152,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/pixels.js","line":173,"description":"<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":173,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":215,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/pixels.js","line":307,"description":"<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"],"alt":"black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":481,"description":"<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":481,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":551,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":555,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/pixels.js","line":566,"description":"<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":602,"description":"<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"c","description":"<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"],"alt":"4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":674,"description":"<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n","itemtype":"method","name":"updatePixels","params":[{"name":"x","description":"<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>width of region to update</p>\n","type":"Number","optional":true},{"name":"h","description":"<p>height of region to update</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/io/files.js","line":20,"description":"<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadJSON","return":{"description":"JSON data","type":"Object|Array"},"example":["\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"],"alt":"50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity","class":"p5","module":"IO","submodule":"Input","overloads":[{"line":20,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"jsonpOptions","description":"<p>options object for jsonp related settings</p>\n","type":"Object","optional":true},{"name":"datatype","description":"<p>\"json\" or \"jsonp\"</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"JSON data","type":"Object|Array"}},{"line":104,"params":[{"name":"path","description":"","type":"String"},{"name":"datatype","description":"","type":"String"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}},{"line":112,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}}]},{"file":"src/io/files.js","line":183,"description":"<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadStrings","params":[{"name":"filename","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":303,"description":"<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadTable","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"extension","description":"<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n","type":"String","optional":true},{"name":"header","description":"<p>\"header\" to indicate table has header row</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Table\">Table</a> object containing data","type":"Object"},"example":["\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":583,"description":"<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadXML","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"XML object containing data","type":"Object"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":693,"description":"<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadBytes","params":[{"name":"file","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if there\n                                   is an error</p>\n","type":"Function","optional":true}],"return":{"description":"an object whose 'bytes' property will be the loaded buffer","type":"Object"},"example":["\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":752,"description":"<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n","itemtype":"method","name":"httpGet","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":752,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":806,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":814,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":829,"description":"<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n","itemtype":"method","name":"httpPost","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":829,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":896,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":904,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":919,"description":"<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n","itemtype":"method","name":"httpDo","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":919,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"method","description":"<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n","type":"String","optional":true},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":990,"params":[{"name":"path","description":"","type":"String"},{"name":"options","description":"<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n","type":"Object"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":1155,"itemtype":"method","name":"createWriter","params":[{"name":"name","description":"<p>name of the file to be created</p>\n","type":"String"},{"name":"extension","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.PrintWriter"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1210,"description":"<p>Writes data to the PrintWriter stream</p>\n","itemtype":"method","name":"write","params":[{"name":"data","description":"<p>all data to be written by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1269,"description":"<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n","itemtype":"method","name":"print","params":[{"name":"data","description":"<p>all data to be printed by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1310,"description":"<p>Clears the data already written to the PrintWriter object</p>\n","itemtype":"method","name":"clear","example":["\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1344,"description":"<p>Closes the PrintWriter</p>\n","itemtype":"method","name":"close","example":["\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1393,"description":"<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n","itemtype":"method","name":"save","params":[{"name":"objectOrFilename","description":"<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n","type":"Object|String","optional":true},{"name":"filename","description":"<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n","type":"String","optional":true},{"name":"options","description":"<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n","type":"Boolean|String","optional":true}],"example":["\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"],"alt":"An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1535,"description":"<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveJSON","params":[{"name":"json","description":"","type":"Array|Object"},{"name":"filename","description":"","type":"String"},{"name":"optimize","description":"<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1592,"description":"<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveStrings","params":[{"name":"list","description":"<p>string array to be written</p>\n","type":"String[]"},{"name":"filename","description":"<p>filename for output</p>\n","type":"String"},{"name":"extension","description":"<p>the filename's extension</p>\n","type":"String","optional":true},{"name":"isCRLF","description":"<p>if true, change line-break to CRLF</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1656,"description":"<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveTable","params":[{"name":"Table","description":"<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n","type":"p5.Table"},{"name":"filename","description":"<p>the filename to which the Table should be saved</p>\n","type":"String"},{"name":"options","description":"<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n","type":"String","optional":true}],"example":["\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/p5.Table.js","line":9,"description":"<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":43,"description":"<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n","itemtype":"property","name":"columns","type":"String[]","example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":77,"description":"<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n","itemtype":"property","name":"rows","type":"p5.TableRow[]","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":85,"description":"<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n","itemtype":"method","name":"addRow","params":[{"name":"row","description":"<p>row to be added to the table</p>\n","type":"p5.TableRow","optional":true}],"return":{"description":"the row that was added","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":148,"description":"<p>Removes a row from the table object.</p>\n","itemtype":"method","name":"removeRow","params":[{"name":"id","description":"<p>ID number of the row to remove</p>\n","type":"Integer"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":195,"description":"<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n","itemtype":"method","name":"getRow","params":[{"name":"rowID","description":"<p>ID number of the row to get</p>\n","type":"Integer"}],"return":{"description":"<a href=\"#/p5.TableRow\">p5.TableRow</a> object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":240,"description":"<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n","itemtype":"method","name":"getRows","return":{"description":"Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":288,"description":"<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"findRow","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":352,"description":"<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"findRows","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":420,"description":"<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"matchRow","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String|RegExp"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer"}],"return":{"description":"TableRow object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":478,"description":"<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n","itemtype":"method","name":"matchRows","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer","optional":true}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":545,"description":"<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"getColumn","params":[{"name":"column","description":"<p>String or Number of the column to return</p>\n","type":"String|Number"}],"return":{"description":"Array of column values","type":"Array"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":597,"description":"<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n","itemtype":"method","name":"clearRows","example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":638,"description":"<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n","itemtype":"method","name":"addColumn","params":[{"name":"title","description":"<p>title of the given column</p>\n","type":"String","optional":true}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":688,"description":"<p>Returns the total number of columns in a Table.</p>\n","itemtype":"method","name":"getColumnCount","return":{"description":"Number of columns in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":724,"description":"<p>Returns the total number of rows in a Table.</p>\n","itemtype":"method","name":"getRowCount","return":{"description":"Number of rows in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":760,"description":"<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n","itemtype":"method","name":"removeTokens","params":[{"name":"chars","description":"<p>String listing characters to be removed</p>\n","type":"String"},{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":832,"description":"<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n","itemtype":"method","name":"trim","params":[{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":896,"description":"<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n","itemtype":"method","name":"removeColumn","params":[{"name":"column","description":"<p>columnName (string) or ID (number)</p>\n","type":"String|Integer"}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":960,"description":"<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String|Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1009,"description":"<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1055,"description":"<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String"}],"example":["\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1100,"description":"<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1146,"description":"<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1190,"description":"<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1242,"description":"<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n","itemtype":"method","name":"getObject","params":[{"name":"headerColumn","description":"<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n","type":"String","optional":true}],"return":{"description":"","type":"Object"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1305,"description":"<p>Retrieves all table data and returns it as a multidimensional array.</p>\n","itemtype":"method","name":"getArray","return":{"description":"","type":"Array"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":40,"description":"<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored</p>\n","type":"String|Number"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":102,"description":"<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a Float</p>\n","type":"Number|String"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":146,"description":"<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a String</p>\n","type":"String|Number|Boolean|Object"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":191,"description":"<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":239,"description":"<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"Float Floating point number","type":"Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":295,"description":"<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getString","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"String","type":"String"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.XML.js","line":62,"description":"<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"getParent","return":{"description":"element parent","type":"p5.XML"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":100,"description":"<p>Gets the element's full name, which is returned as a String.</p>\n","itemtype":"method","name":"getName","return":{"description":"the name of the node","type":"String"},"example":["&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":135,"description":"<p>Sets the element's name, which is specified as a String.</p>\n","itemtype":"method","name":"setName","params":[{"name":"the","description":"<p>new name of the node</p>\n","type":"String"}],"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":181,"description":"<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n","itemtype":"method","name":"hasChildren","return":{"description":"","type":"Boolean"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":217,"description":"<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n","itemtype":"method","name":"listChildren","return":{"description":"names of the children of the element","type":"String[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":258,"description":"<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n","itemtype":"method","name":"getChildren","params":[{"name":"name","description":"<p>element name</p>\n","type":"String","optional":true}],"return":{"description":"children of the element","type":"p5.XML[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":314,"description":"<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n","itemtype":"method","name":"getChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"return":{"description":"","type":"p5.XML"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":374,"description":"<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"addChild","params":[{"name":"node","description":"<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n","type":"p5.XML"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":426,"description":"<p>Removes the element specified by name or index.</p>\n","itemtype":"method","name":"removeChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":498,"description":"<p>Counts the specified element's number of attributes, returned as an Number.</p>\n","itemtype":"method","name":"getAttributeCount","return":{"description":"","type":"Integer"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":534,"description":"<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n","itemtype":"method","name":"listAttributes","return":{"description":"an array of strings containing the names of attributes","type":"String[]"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":577,"description":"<p>Checks whether or not an element has the specified attribute.</p>\n","itemtype":"method","name":"hasAttribute","params":[{"name":"the","description":"<p>attribute to be checked</p>\n","type":"String"}],"return":{"description":"true if attribute found else false","type":"Boolean"},"example":["\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":622,"description":"<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"Number"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":669,"description":"<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n","itemtype":"method","name":"getString","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":716,"description":"<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n","itemtype":"method","name":"setAttribute","params":[{"name":"name","description":"<p>the full name of the attribute</p>\n","type":"String"},{"name":"value","description":"<p>the value of the attribute</p>\n","type":"Number|String|Boolean"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":757,"description":"<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n","itemtype":"method","name":"getContent","params":[{"name":"defaultValue","description":"<p>value returned if no content is found</p>\n","type":"String","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":798,"description":"<p>Sets the element's content.</p>\n","itemtype":"method","name":"setContent","params":[{"name":"text","description":"<p>the new content</p>\n","type":"String"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":839,"description":"<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n","itemtype":"method","name":"serialize","return":{"description":"Serialized string of the element","type":"String"},"example":["\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/math/calculation.js","line":10,"description":"<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n","itemtype":"method","name":"abs","params":[{"name":"n","description":"<p>number to compute</p>\n","type":"Number"}],"return":{"description":"absolute value of given number","type":"Number"},"example":["\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":33,"description":"<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n","itemtype":"method","name":"ceil","params":[{"name":"n","description":"<p>number to round up</p>\n","type":"Number"}],"return":{"description":"rounded up number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":72,"description":"<p>Constrains a value between a minimum and maximum value.</p>\n","itemtype":"method","name":"constrain","params":[{"name":"n","description":"<p>number to constrain</p>\n","type":"Number"},{"name":"low","description":"<p>minimum limit</p>\n","type":"Number"},{"name":"high","description":"<p>maximum limit</p>\n","type":"Number"}],"return":{"description":"constrained number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"],"alt":"2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":116,"description":"<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"distance between the two points","type":"Number"},"example":["\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"],"alt":"2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":116,"params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}},{"line":161,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}}]},{"file":"src/math/calculation.js","line":182,"description":"<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n","itemtype":"method","name":"exp","params":[{"name":"n","description":"<p>exponent to raise</p>\n","type":"Number"}],"return":{"description":"e^n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. e^n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":231,"description":"<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n","itemtype":"method","name":"floor","params":[{"name":"n","description":"<p>number to round down</p>\n","type":"Number"}],"return":{"description":"rounded down number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":269,"description":"<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n","itemtype":"method","name":"lerp","params":[{"name":"start","description":"<p>first value</p>\n","type":"Number"},{"name":"stop","description":"<p>second value</p>\n","type":"Number"},{"name":"amt","description":"<p>number</p>\n","type":"Number"}],"return":{"description":"lerped value","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"],"alt":"5 points horizontally staggered mid-canvas. mid 3 are grey, outer black","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":316,"description":"<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n","itemtype":"method","name":"log","params":[{"name":"n","description":"<p>number greater than 0</p>\n","type":"Number"}],"return":{"description":"natural logarithm of n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. natural logarithm of n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":371,"description":"<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n","itemtype":"method","name":"mag","params":[{"name":"a","description":"<p>first value</p>\n","type":"Number"},{"name":"b","description":"<p>second value</p>\n","type":"Number"}],"return":{"description":"magnitude of vector from (0,0) to (a,b)","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"],"alt":"4 lines of different length radiate from top left of canvas.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":409,"description":"<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n","itemtype":"method","name":"map","params":[{"name":"value","description":"<p>the incoming value to be converted</p>\n","type":"Number"},{"name":"start1","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop1","description":"<p>upper bound of the value's current range</p>\n","type":"Number"},{"name":"start2","description":"<p>lower bound of the value's target range</p>\n","type":"Number"},{"name":"stop2","description":"<p>upper bound of the value's target range</p>\n","type":"Number"},{"name":"withinBounds","description":"<p>constrain the value to the newly mapped range</p>\n","type":"Boolean","optional":true}],"return":{"description":"remapped number","type":"Number"},"example":["\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"],"alt":"10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":464,"description":"<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"max","return":{"description":"maximum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":464,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"maximum Number","type":"Number"}},{"line":499,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":512,"description":"<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"min","return":{"description":"minimum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":512,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"minimum Number","type":"Number"}},{"line":547,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":560,"description":"<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n","itemtype":"method","name":"norm","params":[{"name":"value","description":"<p>incoming value to be normalized</p>\n","type":"Number"},{"name":"start","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop","description":"<p>upper bound of the value's current range</p>\n","type":"Number"}],"return":{"description":"normalized number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"],"alt":"ellipse moves with mouse. 0 shown left & 100 right and updating values center","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":612,"description":"<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n","itemtype":"method","name":"pow","params":[{"name":"n","description":"<p>base of the exponential expression</p>\n","type":"Number"},{"name":"e","description":"<p>power by which to raise the base</p>\n","type":"Number"}],"return":{"description":"n^e","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"],"alt":"small to large ellipses radiating from top left of canvas","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":646,"description":"<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n","itemtype":"method","name":"round","params":[{"name":"n","description":"<p>number to round</p>\n","type":"Number"},{"name":"decimals","description":"<p>number of decimal places to round to, default is 0</p>\n","type":"Number","optional":true}],"return":{"description":"rounded number","type":"Integer"},"example":["\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":701,"description":"<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n","itemtype":"method","name":"sq","params":[{"name":"n","description":"<p>number to square</p>\n","type":"Number"}],"return":{"description":"squared number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squared values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":745,"description":"<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n","itemtype":"method","name":"sqrt","params":[{"name":"n","description":"<p>non-negative number to square root</p>\n","type":"Number"}],"return":{"description":"square root of number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squareroot values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":832,"description":"<p>Calculates the fractional part of a number.</p>\n","itemtype":"method","name":"fract","params":[{"name":"num","description":"<p>Number whose fractional part needs to be found out</p>\n","type":"Number"}],"return":{"description":"fractional part of x, i.e, {x}","type":"Number"},"example":["\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"],"alt":"first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/math.js","line":10,"description":"<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n","itemtype":"method","name":"createVector","params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"p5.Vector"},"example":["\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"],"alt":"draws a line from center of canvas to mouse pointer position.","class":"p5","module":"Math","submodule":"Vector"},{"file":"src/math/noise.js","line":36,"description":"<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n","itemtype":"method","name":"noise","params":[{"name":"x","description":"<p>x-coordinate in noise space</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate in noise space</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z-coordinate in noise space</p>\n","type":"Number","optional":true}],"return":{"description":"Perlin noise value (between 0 and 1) at specified\n                     coordinates","type":"Number"},"example":["\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"],"alt":"vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":178,"description":"<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n","itemtype":"method","name":"noiseDetail","params":[{"name":"lod","description":"<p>number of octaves to be used by the noise</p>\n","type":"Number"},{"name":"falloff","description":"<p>falloff factor for each octave</p>\n","type":"Number"}],"example":["\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"],"alt":"2 vertical grey smokey patterns affected my mouse x-position and noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":243,"description":"<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n","itemtype":"method","name":"noiseSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"],"alt":"vertical grey lines drawing in pattern affected by noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/p5.Vector.js","line":69,"description":"<p>The x component of the vector</p>\n","itemtype":"property","name":"x","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":74,"description":"<p>The y component of the vector</p>\n","itemtype":"property","name":"y","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":79,"description":"<p>The z component of the vector</p>\n","itemtype":"property","name":"z","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":86,"description":"<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n","itemtype":"method","name":"toString","return":{"description":"","type":"String"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":136,"description":"<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n","itemtype":"method","name":"set","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":136,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":195,"params":[{"name":"value","description":"<p>the vector to set</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/math/p5.Vector.js","line":219,"description":"<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n","itemtype":"method","name":"copy","return":{"description":"the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":248,"description":"<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"add","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":248,"params":[{"name":"x","description":"<p>the x component of the vector to be added</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to be added</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to be added</p>\n","type":"Number","optional":true}],"chainable":1},{"line":325,"params":[{"name":"value","description":"<p>the vector to add</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2059,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":372,"description":"<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n","itemtype":"method","name":"rem","chainable":1,"example":["\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":372,"params":[{"name":"x","description":"<p>the x component of divisor vector</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of divisor vector</p>\n","type":"Number"},{"name":"z","description":"<p>the z component of divisor vector</p>\n","type":"Number"}],"chainable":1},{"line":401,"params":[{"name":"value","description":"<p>divisor vector</p>\n","type":"p5.Vector | Number[]"}],"chainable":1},{"line":2085,"params":[{"name":"v1","description":"<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1},{"line":2091,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":461,"description":"<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"sub","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":461,"params":[{"name":"x","description":"<p>the x component of the vector to subtract</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to subtract</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to subtract</p>\n","type":"Number","optional":true}],"chainable":1},{"line":538,"params":[{"name":"value","description":"<p>the vector to subtract</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2110,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":562,"description":"<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"mult","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":562,"params":[{"name":"n","description":"<p>The number to multiply with the vector</p>\n","type":"Number"}],"chainable":1},{"line":655,"params":[{"name":"x","description":"<p>The number to multiply with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to multiply with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to multiply with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":663,"params":[{"name":"arr","description":"<p>The array to multiply with the components of the vector</p>\n","type":"Number[]"}],"chainable":1},{"line":669,"params":[{"name":"v","description":"<p>The vector to multiply with the components of the original vector</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2139,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2148,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2156,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2164,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":754,"description":"<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"div","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":754,"params":[{"name":"n","description":"<p>The number to divide the vector by</p>\n","type":"Number"}],"chainable":1},{"line":847,"params":[{"name":"x","description":"<p>The number to divide with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to divide with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to divide with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":855,"params":[{"name":"arr","description":"<p>The array to divide the components of the vector by</p>\n","type":"Number[]"}],"chainable":1},{"line":861,"params":[{"name":"v","description":"<p>The vector to divide the components of the original vector by</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2218,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2227,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2235,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2243,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":959,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","itemtype":"method","name":"mag","return":{"description":"magnitude of the vector","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":959,"params":[],"return":{"description":"magnitude of the vector","type":"Number"}},{"line":2343,"params":[{"name":"vecT","description":"<p>the vector to return the magnitude of</p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the magnitude of vecT","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1007,"description":"<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n","itemtype":"method","name":"magSq","return":{"description":"squared magnitude of the vector","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1061,"description":"<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n","itemtype":"method","name":"dot","return":{"description":"the dot product","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1061,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"the dot product","type":"Number"}},{"line":1091,"params":[{"name":"value","description":"<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"","type":"Number"}},{"line":2270,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the dot product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1103,"description":"<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n","itemtype":"method","name":"cross","return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1103,"params":[{"name":"v","description":"<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n","type":"p5.Vector"}],"return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"}},{"line":2284,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the cross product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1145,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"the distance","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1145,"params":[{"name":"v","description":"<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the distance","type":"Number"}},{"line":2299,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the distance","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1217,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","itemtype":"method","name":"normalize","return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1217,"params":[],"return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2360,"params":[{"name":"v","description":"<p>the vector to normalize</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"v normalized to a length of 1","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1287,"description":"<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n","itemtype":"method","name":"limit","params":[{"name":"max","description":"<p>the maximum magnitude for the vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1345,"description":"<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n","itemtype":"method","name":"setMag","params":[{"name":"len","description":"<p>the new length for this vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1401,"description":"<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"heading","return":{"description":"the angle of rotation","type":"Number"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1473,"description":"<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"setHeading","params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1498,"description":"<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"rotate","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1498,"params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1},{"line":2191,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":1567,"description":"<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"angleBetween","params":[{"name":"value","description":"<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the angle between (in radians)","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1647,"description":"<p>Linear interpolate the vector to another vector</p>\n","itemtype":"method","name":"lerp","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1647,"params":[{"name":"x","description":"<p>the x component</p>\n","type":"Number"},{"name":"y","description":"<p>the y component</p>\n","type":"Number"},{"name":"z","description":"<p>the z component</p>\n","type":"Number"},{"name":"amt","description":"<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n","type":"Number"}],"chainable":1},{"line":1720,"params":[{"name":"v","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"}],"chainable":1},{"line":2314,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the lerped value","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1736,"description":"<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n","itemtype":"method","name":"reflect","params":[{"name":"surfaceNormal","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n","type":"p5.Vector"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1791,"description":"<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n","itemtype":"method","name":"array","return":{"description":"an Array with the 3 values","type":"Number[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1823,"description":"<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","itemtype":"method","name":"equals","return":{"description":"whether the vectors are equals","type":"Boolean"},"example":["\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1823,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"whether the vectors are equals","type":"Boolean"}},{"line":1853,"params":[{"name":"value","description":"<p>the vector to compare</p>\n","type":"p5.Vector|Array"}],"return":{"description":"","type":"Boolean"}}]},{"file":"src/math/p5.Vector.js","line":1878,"description":"<p>Make a new 2D vector from an angle</p>\n","itemtype":"method","name":"fromAngle","static":1,"params":[{"name":"angle","description":"<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1929,"description":"<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n","itemtype":"method","name":"fromAngles","static":1,"params":[{"name":"theta","description":"<p>the polar angle, in radians (zero is up)</p>\n","type":"Number"},{"name":"phi","description":"<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1978,"description":"<p>Make a new 2D unit vector from a random angle</p>\n","itemtype":"method","name":"random2D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2031,"description":"<p>Make a new random 3D unit vector.</p>\n","itemtype":"method","name":"random3D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2135,"description":"<p>Multiplies a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2187,"description":"<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2214,"description":"<p>Divides a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2267,"description":"<p>Calculates the dot product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2281,"description":"<p>Calculates the cross product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2295,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2310,"description":"<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2339,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2357,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/random.js","line":37,"description":"<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n","itemtype":"method","name":"randomSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"],"alt":"many vertical lines drawn in white, black or grey.","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/random.js","line":66,"description":"<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n","itemtype":"method","name":"random","return":{"description":"the random number","type":"Number"},"example":["\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"],"alt":"100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog","class":"p5","module":"Math","submodule":"Random","overloads":[{"line":66,"params":[{"name":"min","description":"<p>the lower bound (inclusive)</p>\n","type":"Number","optional":true},{"name":"max","description":"<p>the upper bound (exclusive)</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"}},{"line":119,"params":[{"name":"choices","description":"<p>the array to choose from</p>\n","type":"Array"}],"return":{"description":"the random element from the array","type":"*"}}]},{"file":"src/math/random.js","line":153,"description":"<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n","itemtype":"method","name":"randomGaussian","params":[{"name":"mean","description":"<p>the mean</p>\n","type":"Number","optional":true},{"name":"sd","description":"<p>the standard deviation</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"},"example":["\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"],"alt":"100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/trigonometry.js","line":18,"description":"<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n","itemtype":"method","name":"acos","params":[{"name":"value","description":"<p>the value whose arc cosine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc cosine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":53,"description":"<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n","itemtype":"method","name":"asin","params":[{"name":"value","description":"<p>the value whose arc sine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc sine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":88,"description":"<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n","itemtype":"method","name":"atan","params":[{"name":"value","description":"<p>the value whose arc tangent is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":123,"description":"<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n","itemtype":"method","name":"atan2","params":[{"name":"y","description":"<p>y-coordinate of the point</p>\n","type":"Number"},{"name":"x","description":"<p>x-coordinate of the point</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given point","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"],"alt":"60 by 10 rect at center of canvas rotates with mouse movements","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":159,"description":"<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"cos","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the cosine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines form wave patterns, extend-down on left and right side","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":186,"description":"<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"sin","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the sine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines extend down and up from center to form wave pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":213,"description":"<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n","itemtype":"method","name":"tan","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the tangent of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"],"alt":"vertical black lines end down and up from center to form spike pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":239,"description":"<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"degrees","params":[{"name":"radians","description":"<p>the radians value to convert to degrees</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":262,"description":"<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"radians","params":[{"name":"degrees","description":"<p>the degree value to convert to radians</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":285,"description":"<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n","itemtype":"method","name":"angleMode","params":[{"name":"mode","description":"<p>either RADIANS or DEGREES</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"],"alt":"40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/typography/attributes.js","line":11,"description":"<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n","itemtype":"method","name":"textAlign","chainable":1,"example":["\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"],"alt":"Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":11,"params":[{"name":"horizAlign","description":"<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n","type":"Constant"},{"name":"vertAlign","description":"<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n","type":"Constant","optional":true}],"chainable":1},{"line":72,"params":[],"return":{"description":"","type":"Object"}}]},{"file":"src/typography/attributes.js","line":81,"description":"<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n","itemtype":"method","name":"textLeading","chainable":1,"example":["\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"],"alt":"A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":81,"params":[{"name":"leading","description":"<p>the size in pixels for spacing between lines</p>\n","type":"Number"}],"chainable":1},{"line":109,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":118,"description":"<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n","itemtype":"method","name":"textSize","chainable":1,"example":["\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"],"alt":"'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":118,"params":[{"name":"theSize","description":"<p>the size of the letters in units of pixels</p>\n","type":"Number"}],"chainable":1},{"line":141,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":150,"description":"<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n","itemtype":"method","name":"textStyle","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"],"alt":"Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":150,"params":[{"name":"theStyle","description":"<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n","type":"Constant"}],"chainable":1},{"line":178,"params":[],"return":{"description":"","type":"String"}}]},{"file":"src/typography/attributes.js","line":187,"description":"<p>Calculates and returns the width of any character or text string.</p>\n","itemtype":"method","name":"textWidth","params":[{"name":"theText","description":"<p>the String of characters to measure</p>\n","type":"String"}],"return":{"description":"the calculated width","type":"Number"},"example":["\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"],"alt":"Letter P and p5.js are displayed with vertical lines at end.","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":222,"description":"<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n","itemtype":"method","name":"textAscent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":251,"description":"<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n","itemtype":"method","name":"textDescent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":280,"description":"<p>Helper function to measure ascent and descent.</p>\n","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":287,"description":"<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n","itemtype":"method","name":"textWrap","params":[{"name":"wrapStyle","description":"<p>text wrapping style, either WORD or CHAR</p>\n","type":"Constant"}],"return":{"description":"wrapStyle","type":"String"},"example":["\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/loading_displaying.js","line":16,"description":"<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n","itemtype":"method","name":"loadFont","params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n","type":"Function","optional":true},{"name":"onError","description":"<p>function to be executed if\n                                   an error occurs</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Font\">p5.Font</a> object","type":"p5.Font"},"example":["\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"],"alt":"p5*js in p5's theme dark pink\np5*js in p5's theme dark pink","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":140,"description":"<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n","itemtype":"method","name":"text","params":[{"name":"str","description":"<p>the alphanumeric\n                                            symbols to be displayed</p>\n","type":"String|Object|Array|Number|Boolean"},{"name":"x","description":"<p>x-coordinate of text</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of text</p>\n","type":"Number"},{"name":"x2","description":"<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true},{"name":"y2","description":"<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"],"alt":"'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":231,"description":"<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n","itemtype":"method","name":"textFont","return":{"description":"the current font / p5 Object","type":"Object"},"example":["\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"],"alt":"word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold","class":"p5","module":"Typography","submodule":"Loading & Displaying","overloads":[{"line":231,"params":[],"return":{"description":"the current font / p5 Object","type":"Object"}},{"line":280,"params":[{"name":"font","description":"<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n","type":"Object|String"},{"name":"size","description":"<p>the font size to use</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/typography/p5.Font.js","line":24,"description":"<p>Underlying opentype font implementation</p>\n","itemtype":"property","name":"font","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":31,"description":"<p>Returns a tight bounding box for the given text string using this\nfont</p>\n","itemtype":"method","name":"textBounds","params":[{"name":"line","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional) Default is 12.</p>\n","type":"Number","optional":true},{"name":"options","description":"<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n","type":"Object","optional":true}],"return":{"description":"a rectangle object with properties: x, y, w, h","type":"Object"},"example":["\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"],"alt":"words Lorem ipsum dol go off canvas and contained by white bounding box","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":175,"description":"<p>Computes an array of points following the path for specified text</p>\n","itemtype":"method","name":"textToPoints","params":[{"name":"txt","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional)</p>\n","type":"Number"},{"name":"options","description":"<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n","type":"Object","optional":true}],"return":{"description":"an array of points, each with x, y, alpha (the path angle)","type":"Array"},"example":["\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"],"class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/utilities/array_functions.js","line":10,"description":"<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n","itemtype":"method","name":"append","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.","params":[{"name":"array","description":"<p>Array to append</p>\n","type":"Array"},{"name":"value","description":"<p>to be added to the Array</p>\n","type":"Any"}],"return":{"description":"the array that was appended to","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":35,"description":"<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n","itemtype":"method","name":"arrayCopy","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.","example":["\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions","overloads":[{"line":35,"params":[{"name":"src","description":"<p>the source Array</p>\n","type":"Array"},{"name":"srcPosition","description":"<p>starting position in the source Array</p>\n","type":"Integer"},{"name":"dst","description":"<p>the destination Array</p>\n","type":"Array"},{"name":"dstPosition","description":"<p>starting position in the destination Array</p>\n","type":"Integer"},{"name":"length","description":"<p>number of Array elements to be copied</p>\n","type":"Integer"}]},{"line":73,"params":[{"name":"src","description":"","type":"Array"},{"name":"dst","description":"","type":"Array"},{"name":"length","description":"","type":"Integer","optional":true}]}]},{"file":"src/utilities/array_functions.js","line":112,"description":"<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n","itemtype":"method","name":"concat","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.","params":[{"name":"a","description":"<p>first Array to concatenate</p>\n","type":"Array"},{"name":"b","description":"<p>second Array to concatenate</p>\n","type":"Array"}],"return":{"description":"concatenated array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":141,"description":"<p>Reverses the order of an array, maps to Array.reverse()</p>\n","itemtype":"method","name":"reverse","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.","params":[{"name":"list","description":"<p>Array to reverse</p>\n","type":"Array"}],"return":{"description":"the reversed list","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":161,"description":"<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n","itemtype":"method","name":"shorten","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.","params":[{"name":"list","description":"<p>Array to shorten</p>\n","type":"Array"}],"return":{"description":"shortened Array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":185,"description":"<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n","itemtype":"method","name":"shuffle","params":[{"name":"array","description":"<p>Array to shuffle</p>\n","type":"Array"},{"name":"bool","description":"<p>modify passed array</p>\n","type":"Boolean","optional":true}],"return":{"description":"shuffled Array","type":"Array"},"example":["\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":227,"description":"<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n","itemtype":"method","name":"sort","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.","params":[{"name":"list","description":"<p>Array to sort</p>\n","type":"Array"},{"name":"count","description":"<p>number of elements to sort, starting from 0</p>\n","type":"Integer","optional":true}],"return":{"description":"the sorted list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":273,"description":"<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n","itemtype":"method","name":"splice","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.","params":[{"name":"list","description":"<p>Array to splice into</p>\n","type":"Array"},{"name":"value","description":"<p>value to be spliced in</p>\n","type":"Any"},{"name":"position","description":"<p>in the array from which to insert data</p>\n","type":"Integer"}],"return":{"description":"the list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":308,"description":"<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n","itemtype":"method","name":"subset","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.","params":[{"name":"list","description":"<p>Array to extract from</p>\n","type":"Array"},{"name":"start","description":"<p>position to begin</p>\n","type":"Integer"},{"name":"count","description":"<p>number of values to extract</p>\n","type":"Integer","optional":true}],"return":{"description":"Array of extracted elements","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/conversion.js","line":10,"description":"<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n","itemtype":"method","name":"float","params":[{"name":"str","description":"<p>float string to parse</p>\n","type":"String"}],"return":{"description":"floating point representation of string","type":"Number"},"example":["\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"],"alt":"20 by 20 white ellipse in the center of the canvas","class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":44,"description":"<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n","itemtype":"method","name":"int","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":44,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"},{"name":"radix","description":"<p>the radix to convert to (default: 10)</p>\n","type":"Integer","optional":true}],"return":{"description":"integer representation of value","type":"Number"}},{"line":66,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"},{"name":"radix","description":"","type":"Integer","optional":true}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":88,"description":"<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n","itemtype":"method","name":"str","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":114,"description":"<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n","itemtype":"method","name":"boolean","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"boolean representation of value","type":"Boolean"},"example":["\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":146,"description":"<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n","itemtype":"method","name":"byte","return":{"description":"byte representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":146,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"}],"return":{"description":"byte representation of value","type":"Number"}},{"line":168,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of byte representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":182,"description":"<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n","itemtype":"method","name":"char","return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":182,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Number"}],"return":{"description":"string representation of value","type":"String"}},{"line":201,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":216,"description":"<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unchar","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":216,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of value","type":"Number"}},{"line":232,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":245,"description":"<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n","itemtype":"method","name":"hex","return":{"description":"hexadecimal string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":245,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"Number"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of value","type":"String"}},{"line":265,"params":[{"name":"ns","description":"<p>array of values to parse</p>\n","type":"Number[]"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":295,"description":"<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unhex","return":{"description":"integer representation of hexadecimal value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":295,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of hexadecimal value","type":"Number"}},{"line":311,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representations of hexadecimal value","type":"Number[]"}}]},{"file":"src/utilities/string_functions.js","line":15,"description":"<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n","itemtype":"method","name":"join","params":[{"name":"list","description":"<p>array of Strings to be joined</p>\n","type":"Array"},{"name":"separator","description":"<p>String to be placed between each item</p>\n","type":"String"}],"return":{"description":"joined String","type":"String"},"example":["\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"],"alt":"\"hello world!\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":43,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n","itemtype":"method","name":"match","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"Array of Strings found","type":"String[]"},"example":["\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"],"alt":"\"p5js*\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":83,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n","itemtype":"method","name":"matchAll","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"2d Array of Strings found","type":"String[]"},"example":["\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":130,"description":"<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nf","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" middle top, -1321.00\" middle bottom canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":130,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"left","description":"<p>number of digits to the left of the\n                               decimal point</p>\n","type":"Integer|String","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":176,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer|String","optional":true},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":237,"description":"<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n","itemtype":"method","name":"nfc","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":237,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"right","description":"<p>number of digits to the right of the\n                                 decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":275,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":311,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n","itemtype":"method","name":"nfp","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":311,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":352,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Number[]"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":373,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nfs","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" top middle and \"-1321.00\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":373,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":430,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":451,"description":"<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n","itemtype":"method","name":"split","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>the String used to separate the data</p>\n","type":"String"}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"],"alt":"\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":484,"description":"<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n","itemtype":"method","name":"splitTokens","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>list of individual Strings that will be used as\n                         separators</p>\n","type":"String","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":537,"description":"<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n","itemtype":"method","name":"trim","return":{"description":"a trimmed String","type":"String"},"example":["\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"],"alt":"\"No new lines here\" displayed center canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":537,"params":[{"name":"str","description":"<p>a String to be trimmed</p>\n","type":"String"}],"return":{"description":"a trimmed String","type":"String"}},{"line":557,"params":[{"name":"strs","description":"<p>an Array of Strings to be trimmed</p>\n","type":"Array"}],"return":{"description":"an Array of trimmed Strings","type":"String[]"}}]},{"file":"src/utilities/time_date.js","line":10,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n","itemtype":"method","name":"day","return":{"description":"the current day","type":"Integer"},"example":["\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"],"alt":"Current day is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":31,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n","itemtype":"method","name":"hour","return":{"description":"the current hour","type":"Integer"},"example":["\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"],"alt":"Current hour is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":52,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n","itemtype":"method","name":"minute","return":{"description":"the current minute","type":"Integer"},"example":["\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current minute is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":73,"description":"<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n","itemtype":"method","name":"millis","return":{"description":"the number of milliseconds since starting the sketch","type":"Number"},"example":["\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"],"alt":"number of milliseconds since sketch has started displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":100,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n","itemtype":"method","name":"month","return":{"description":"the current month","type":"Integer"},"example":["\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current month is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":122,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n","itemtype":"method","name":"second","return":{"description":"the current second","type":"Integer"},"example":["\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"],"alt":"Current second is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":143,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n","itemtype":"method","name":"year","return":{"description":"the current year","type":"Integer"},"example":["\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"],"alt":"Current year is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/webgl/3d_primitives.js","line":13,"description":"<p>Draw a plane with given a width and height</p>\n","itemtype":"method","name":"plane","params":[{"name":"width","description":"<p>width of the plane</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the plane</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"],"alt":"Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.","class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":97,"description":"<p>Draw a box with given width, height and depth</p>\n","itemtype":"method","name":"box","params":[{"name":"width","description":"<p>width of the box</p>\n","type":"Number","optional":true},{"name":"Height","description":"<p>height of the box</p>\n","type":"Number","optional":true},{"name":"depth","description":"<p>depth of the box</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":215,"description":"<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"sphere","params":[{"name":"radius","description":"<p>radius of circle</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>optional number of subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>optional number of subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":419,"description":"<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cylinder","params":[{"name":"radius","description":"<p>radius of the surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cylinder</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n","type":"Integer","optional":true},{"name":"bottomCap","description":"<p>whether to draw the bottom of the cylinder</p>\n","type":"Boolean","optional":true},{"name":"topCap","description":"<p>whether to draw the top of the cylinder</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":554,"description":"<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cone","params":[{"name":"radius","description":"<p>radius of the bottom surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cone</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n","type":"Integer","optional":true},{"name":"cap","description":"<p>whether to draw the base of the cone</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":669,"description":"<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n","itemtype":"method","name":"ellipsoid","params":[{"name":"radiusx","description":"<p>x-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusy","description":"<p>y-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusz","description":"<p>z-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":804,"description":"<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n","itemtype":"method","name":"torus","params":[{"name":"radius","description":"<p>radius of the whole ring</p>\n","type":"Number","optional":true},{"name":"tubeRadius","description":"<p>radius of the tube</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/interaction.js","line":11,"description":"<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n","itemtype":"method","name":"orbitControl","params":[{"name":"sensitivityX","description":"<p>sensitivity to mouse movement along X axis</p>\n","type":"Number","optional":true},{"name":"sensitivityY","description":"<p>sensitivity to mouse movement along Y axis</p>\n","type":"Number","optional":true},{"name":"sensitivityZ","description":"<p>sensitivity to scroll movement along Z axis</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"],"alt":"Camera orbits around a box when mouse is hold-clicked & then moved.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/interaction.js","line":145,"description":"<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n","itemtype":"method","name":"debugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.","class":"p5","module":"3D","submodule":"Interaction","overloads":[{"line":145,"params":[]},{"line":278,"params":[{"name":"mode","description":"<p>either GRID or AXES</p>\n","type":"Constant"}]},{"line":283,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"gridSize","description":"<p>size of one side of the grid</p>\n","type":"Number","optional":true},{"name":"gridDivisions","description":"<p>number of divisions in the grid</p>\n","type":"Number","optional":true},{"name":"xOff","description":"<p>X axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"yOff","description":"<p>Y axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"zOff","description":"<p>Z axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true}]},{"line":293,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"axesSize","description":"<p>size of axes icon</p>\n","type":"Number","optional":true},{"name":"xOff","description":"","type":"Number","optional":true},{"name":"yOff","description":"","type":"Number","optional":true},{"name":"zOff","description":"","type":"Number","optional":true}]},{"line":302,"params":[{"name":"gridSize","description":"","type":"Number","optional":true},{"name":"gridDivisions","description":"","type":"Number","optional":true},{"name":"gridXOff","description":"","type":"Number","optional":true},{"name":"gridYOff","description":"","type":"Number","optional":true},{"name":"gridZOff","description":"","type":"Number","optional":true},{"name":"axesSize","description":"","type":"Number","optional":true},{"name":"axesXOff","description":"","type":"Number","optional":true},{"name":"axesYOff","description":"","type":"Number","optional":true},{"name":"axesZOff","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/interaction.js","line":353,"description":"<p>Turns off debugMode() in a 3D sketch.</p>\n","itemtype":"method","name":"noDebugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/light.js","line":11,"description":"<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n","itemtype":"method","name":"ambientLight","chainable":1,"example":["\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"],"alt":"evenly distributed light across a sphere\nevenly distributed light across a rotating sphere","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":11,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"<p>the alpha value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":51,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":57,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":64,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":71,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":92,"description":"<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n","itemtype":"method","name":"specularColor","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"different specular light sources from top and bottom of canvas","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":92,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"}],"chainable":1},{"line":139,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":145,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"}],"chainable":1},{"line":151,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":158,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":177,"description":"<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n","itemtype":"method","name":"directionalLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"light source on canvas changeable with mouse position","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":177,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"position","description":"<p>the direction of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":210,"params":[{"name":"color","description":"<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"<p>x axis direction</p>\n","type":"Number"},{"name":"y","description":"<p>y axis direction</p>\n","type":"Number"},{"name":"z","description":"<p>z axis direction</p>\n","type":"Number"}],"chainable":1},{"line":220,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1},{"line":227,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1}]},{"file":"src/webgl/light.js","line":280,"description":"<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n","itemtype":"method","name":"pointLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"spot light on canvas changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":280,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"}],"chainable":1},{"line":322,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":331,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1},{"line":341,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1}]},{"file":"src/webgl/light.js","line":387,"description":"<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n","itemtype":"method","name":"lights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"the light is partially ambient and partially directional","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":425,"description":"<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n","itemtype":"method","name":"lightFalloff","params":[{"name":"constant","description":"<p>constant value for determining falloff</p>\n","type":"Number"},{"name":"linear","description":"<p>linear value for determining falloff</p>\n","type":"Number"},{"name":"quadratic","description":"<p>quadratic value for determining falloff</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"],"alt":"Two spheres with different falloff values show different intensity of light","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":519,"description":"<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n","itemtype":"method","name":"spotLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Spot light on a sphere which changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":519,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"},{"name":"rx","description":"<p>x axis direction of light</p>\n","type":"Number"},{"name":"ry","description":"<p>y axis direction of light</p>\n","type":"Number"},{"name":"rz","description":"<p>z axis direction of light</p>\n","type":"Number"},{"name":"angle","description":"<p>optional parameter for angle. Defaults to PI/3</p>\n","type":"Number","optional":true},{"name":"conc","description":"<p>optional parameter for concentration. Defaults to 100</p>\n","type":"Number","optional":true}],"chainable":1},{"line":571,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"},{"name":"direction","description":"<p>the direction of the light</p>\n","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":580,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":590,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":600,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":610,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":622,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":634,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/light.js","line":859,"description":"<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n","itemtype":"method","name":"noLights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"],"alt":"Three white spheres. Each appears as a different\ncolor due to lighting.","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/loading.js","line":12,"description":"<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n","itemtype":"method","name":"loadModel","return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"},"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>","\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d teapot with red, green and blue gradient.","class":"p5","module":"Shape","submodule":"3D Models","overloads":[{"line":12,"params":[{"name":"path","description":"<p>Path of the model to be loaded</p>\n","type":"String"},{"name":"normalize","description":"<p>If true, scale the model to a\n                                     standardized size when loading</p>\n","type":"Boolean"},{"name":"successCallback","description":"<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                                        the model fails to load.</p>\n","type":"Function(Event)","optional":true},{"name":"fileType","description":"<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}},{"line":96,"params":[{"name":"path","description":"","type":"String"},{"name":"successCallback","description":"","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"","type":"Function(Event)","optional":true},{"name":"fileType","description":"","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}}]},{"file":"src/webgl/loading.js","line":179,"description":"<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":290,"description":"<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":317,"description":"<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":344,"description":"<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":356,"description":"<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":444,"description":"<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":588,"description":"<p>Render a 3d model to the screen.</p>\n","itemtype":"method","name":"model","params":[{"name":"model","description":"<p>Loaded 3d model to be rendered</p>\n","type":"p5.Geometry"}],"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d octahedron.","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/material.js","line":12,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"loadShader","params":[{"name":"vertFilename","description":"<p>path to file containing vertex shader\nsource code</p>\n","type":"String"},{"name":"fragFilename","description":"<p>path to file containing fragment shader\nsource code</p>\n","type":"String"},{"name":"callback","description":"<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n","type":"Function","optional":true}],"return":{"description":"a shader object created from the provided\nvertex and fragment shader files.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":111,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"createShader","params":[{"name":"vertSrc","description":"<p>source code for the vertex shader</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader</p>\n","type":"String"}],"return":{"description":"a shader object created from the provided\nvertex and fragment shaders.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":184,"description":"<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"shader","chainable":1,"params":[{"name":"s","description":"<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n","type":"p5.Shader"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":282,"description":"<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n","itemtype":"method","name":"resetShader","chainable":1,"example":["\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"],"alt":"Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":368,"description":"<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"texture","params":[{"name":"tex","description":"<p>image to use as texture</p>\n","type":"p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"}],"chainable":1,"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>","\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>","\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using normalized coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":511,"description":"<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n","itemtype":"method","name":"textureMode","params":[{"name":"mode","description":"<p>either IMAGE or NORMAL</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using image coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":587,"description":"<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n","itemtype":"method","name":"textureWrap","params":[{"name":"wrapX","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant"},{"name":"wrapY","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"],"alt":"an image of the rocky mountains repeated in mirrored tiles","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":659,"description":"<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"normalMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Red, green and blue gradient.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":697,"description":"<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"ambientMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":697,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":757,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":777,"description":"<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n","itemtype":"method","name":"emissiveMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":777,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true},{"name":"a","description":"<p>opacity</p>\n","type":"Number","optional":true}],"chainable":1},{"line":809,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":829,"description":"<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"specularMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"],"alt":"torus with specular material","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":829,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":870,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":882,"params":[{"name":"color","description":"<p>color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":902,"description":"<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n","itemtype":"method","name":"shininess","params":[{"name":"shine","description":"<p>Degree of Shininess.\n                      Defaults to 1.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"],"alt":"Shininess on Camera changes position with mouse","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/p5.Camera.js","line":13,"description":"<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n","itemtype":"method","name":"camera","is_constructor":1,"params":[{"name":"x","description":"<p>camera position value on x axis</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>camera position value on y axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>camera position value on z axis</p>\n","type":"Number","optional":true},{"name":"centerX","description":"<p>x coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerY","description":"<p>y coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerZ","description":"<p>z coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"upX","description":"<p>x component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upY","description":"<p>y component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upZ","description":"<p>z component of direction 'up' from camera</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":115,"description":"<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n","itemtype":"method","name":"perspective","params":[{"name":"fovy","description":"<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n","type":"Number","optional":true},{"name":"aspect","description":"<p>camera frustum aspect ratio</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>frustum near plane length</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>frustum far plane length</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":176,"description":"<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n","itemtype":"method","name":"ortho","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":236,"description":"<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n","itemtype":"method","name":"frustum","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":303,"description":"<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n","itemtype":"method","name":"createCamera","return":{"description":"The newly created camera object.","type":"p5.Camera"},"example":["\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"],"alt":"An example that creates a camera and moves it around the box.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":444,"description":"<p>camera position value on x axis</p>\n","itemtype":"property","name":"eyeX","type":"Number","readonly":"","example":["\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":472,"description":"<p>camera position value on y axis</p>\n","itemtype":"property","name":"eyeY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":499,"description":"<p>camera position value on z axis</p>\n","itemtype":"property","name":"eyeZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":526,"description":"<p>x coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":554,"description":"<p>y coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":582,"description":"<p>z coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":610,"description":"<p>x component of direction 'up' from camera</p>\n","itemtype":"property","name":"upX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":633,"description":"<p>y component of direction 'up' from camera</p>\n","itemtype":"property","name":"upY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":656,"description":"<p>z component of direction 'up' from camera</p>\n","itemtype":"property","name":"upZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":683,"description":"<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"perspective","example":["\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":801,"description":"<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"ortho","example":["\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":897,"description":"<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"frustum","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1040,"description":"<p>Panning rotates the camera view to the left and right.</p>\n","itemtype":"method","name":"pan","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1098,"description":"<p>Tilting rotates the camera view up and down.</p>\n","itemtype":"method","name":"tilt","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view tilts up and down across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1156,"description":"<p>Reorients the camera to look at a position in world space.</p>\n","itemtype":"method","name":"lookAt","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view of rotating 3D cubes changes to look at a new random\npoint every second .","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1223,"description":"<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"camera","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1386,"description":"<p>Move camera along its local axes while maintaining current camera orientation.</p>\n","itemtype":"method","name":"move","params":[{"name":"x","description":"<p>amount to move along camera's left-right axis</p>\n","type":"Number"},{"name":"y","description":"<p>amount to move along camera's up-down axis</p>\n","type":"Number"},{"name":"z","description":"<p>amount to move along camera's forward-backward axis</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"],"alt":"camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1458,"description":"<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n","itemtype":"method","name":"setPosition","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"],"alt":"camera position changes as the user presses keys, altering view of a 3D box","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1723,"description":"<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n","itemtype":"method","name":"setCamera","params":[{"name":"cam","description":"<p>p5.Camera object</p>\n","type":"p5.Camera"}],"example":["\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"Canvas switches between two camera views, each showing a series of spinning\n3D boxes.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Geometry.js","line":71,"description":"<p>computes faces for geometry objects based on the vertices.</p>\n","itemtype":"method","name":"computeFaces","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":114,"description":"<p>computes smooth normals per vertex as an average of each\nface.</p>\n","itemtype":"method","name":"computeNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":153,"description":"<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n","itemtype":"method","name":"averageNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":174,"description":"<p>Averages pole normals.  Used in spherical primitives</p>\n","itemtype":"method","name":"averagePoleNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":267,"description":"<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n","itemtype":"method","name":"normalize","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.RendererGL.js","line":334,"description":"<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n","itemtype":"method","name":"setAttributes","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"],"alt":"a rotating cube with smoother edges","class":"p5","module":"Rendering","submodule":"Rendering","overloads":[{"line":334,"params":[{"name":"key","description":"<p>Name of attribute</p>\n","type":"String"},{"name":"value","description":"<p>New value of named attribute</p>\n","type":"Boolean"}]},{"line":473,"params":[{"name":"obj","description":"<p>object with key-value pairs</p>\n","type":"Object"}]}]},{"file":"src/webgl/p5.Shader.js","line":306,"description":"<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n","itemtype":"method","name":"setUniform","chainable":1,"params":[{"name":"uniformName","description":"<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n","type":"String"},{"name":"data","description":"<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n","type":"Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5.Shader","module":"3D","submodule":"Material"},{"file":"lib/addons/p5.sound.js","line":1,"class":"p5.sound","module":"3D"},{"file":"lib/addons/p5.sound.js","line":52,"description":"<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n","class":"p5.sound","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":159,"description":"<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>","itemtype":"method","name":"getAudioContext","return":{"description":"AudioContext for this sketch","type":"Object"},"example":["\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":198,"description":"<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>","params":[{"name":"element(s)","description":"<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n","type":"Element|Array","optional":true},{"name":"callback","description":"<p>Callback to invoke when the AudioContext\n                              has started</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that resolves when\n                                     the AudioContext state is 'running'","type":"Promise"},"itemtype":"method","name":"userStartAudio","example":["\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":401,"description":"<p>This module has shims</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":536,"description":"<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":726,"description":"<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n","itemtype":"method","name":"getOutputVolume","return":{"description":"Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":738,"description":"<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>","itemtype":"method","name":"outputVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":782,"description":"<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n","itemtype":"property","name":"soundOut","type":"Object","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":807,"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":811,"description":"<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"samplerate samples per second","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":825,"description":"<p>Returns the closest MIDI note value for\na given frequency.</p>\n","itemtype":"method","name":"freqToMidi","params":[{"name":"frequency","description":"<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n","type":"Number"}],"return":{"description":"MIDI note value","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":841,"description":"<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n","itemtype":"method","name":"midiToFreq","params":[{"name":"midiNote","description":"<p>The number of a MIDI note</p>\n","type":"Number"}],"return":{"description":"Frequency value of the given MIDI note","type":"Number"},"example":["\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":925,"description":"<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n","itemtype":"method","name":"soundFormats","params":[{"name":"formats","description":"<p>i.e. 'mp3', 'wav', 'ogg'</p>\n","type":"String","optional":true,"multiple":true}],"example":["\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1040,"description":"<p>Used by Osc and Envelope to chain signal math</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1145,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n","itemtype":"method","name":"saveSound","params":[{"name":"soundFile","description":"<p>p5.SoundFile that you wish to save</p>\n","type":"p5.SoundFile"},{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1662,"description":"<p>Returns true if the sound file finished loading successfully.</p>\n","itemtype":"method","name":"isLoaded","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1679,"description":"<p>Play the p5.SoundFile</p>\n","itemtype":"method","name":"play","params":[{"name":"startTime","description":"<p>(optional) schedule playback to start (in seconds from now).</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) amplitude (volume)\n                                    of playback</p>\n","type":"Number","optional":true},{"name":"cueStart","description":"<p>(optional) cue start time in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) duration of playback in seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1787,"description":"<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n","itemtype":"method","name":"playMode","params":[{"name":"str","description":"<p>'restart' or 'sustain' or 'untilDone'</p>\n","type":"String"}],"example":["\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1847,"description":"<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n","itemtype":"method","name":"pause","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                             seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1905,"description":"<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n","itemtype":"method","name":"loop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            seconds from now</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) playback volume</p>\n","type":"Number","optional":true},{"name":"cueLoopStart","description":"<p>(optional) startTime in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) loop duration in seconds</p>\n","type":"Number","optional":true}],"example":["\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1950,"description":"<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n","itemtype":"method","name":"setLoop","params":[{"name":"Boolean","description":"<p>set looping to true or false</p>\n","type":"Boolean"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1976,"description":"<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n","itemtype":"method","name":"isLooping","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1997,"description":"<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n","itemtype":"method","name":"isPlaying","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2011,"description":"<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n","itemtype":"method","name":"isPaused","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2025,"description":"<p>Stop soundfile playback.</p>\n","itemtype":"method","name":"stop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            in seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2087,"description":"<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n","itemtype":"method","name":"pan","params":[{"name":"panValue","description":"<p>Set the stereo panner</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                                seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2131,"description":"<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n","itemtype":"method","name":"getPan","return":{"description":"Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2146,"description":"<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n","itemtype":"method","name":"rate","params":[{"name":"playbackRate","description":"<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2239,"description":"<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n","itemtype":"method","name":"setVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2276,"description":"<p>Returns the duration of a sound file in seconds.</p>\n","itemtype":"method","name":"duration","return":{"description":"The duration of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2293,"description":"<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n","itemtype":"method","name":"currentTime","return":{"description":"currentTime of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2308,"description":"<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n","itemtype":"method","name":"jump","params":[{"name":"cueTime","description":"<p>cueTime of the soundFile in seconds.</p>\n","type":"Number"},{"name":"duration","description":"<p>duration in seconds.</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2340,"description":"<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n","itemtype":"method","name":"channels","return":{"description":"[channels]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2354,"description":"<p>Return the sample rate of the sound file.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"[sampleRate]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2367,"description":"<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n","itemtype":"method","name":"frames","return":{"description":"[sampleCount]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2381,"description":"<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n","itemtype":"method","name":"getPeaks","params":[{"name":"length","description":"<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n","type":"Number","optional":true}],"return":{"description":"Array of peaks.","type":"Float32Array"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2443,"description":"<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n","itemtype":"method","name":"reverseBuffer","example":["\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2497,"description":"<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended.</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2565,"description":"<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n","itemtype":"method","name":"connect","params":[{"name":"object","description":"<p>Audio object that accepts an input</p>\n","type":"Object","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2590,"description":"<p>Disconnects the output of this p5sound object.</p>\n","itemtype":"method","name":"disconnect","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2604,"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2612,"description":"<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n","itemtype":"method","name":"setPath","params":[{"name":"path","description":"<p>path to audio file</p>\n","type":"String"},{"name":"callback","description":"<p>Callback</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2630,"description":"<p>Replace the current Audio Buffer with a new Buffer.</p>\n","itemtype":"method","name":"setBuffer","params":[{"name":"buf","description":"<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n","type":"Array"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2719,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2790,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2817,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2850,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n","itemtype":"method","name":"save","params":[{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String","optional":true}],"example":["\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2882,"description":"<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n","itemtype":"method","name":"getBlob","return":{"description":"A file-like data object","type":"Blob"},"example":["\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2946,"description":"<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n","itemtype":"method","name":"loadSound","params":[{"name":"path","description":"<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n","type":"Function","optional":true},{"name":"whileLoading","description":"<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a p5.SoundFile","type":"SoundFile"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3117,"description":"<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n","itemtype":"method","name":"setInput","params":[{"name":"snd","description":"<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n","type":"SoundObject|undefined","optional":true},{"name":"smoothing","description":"<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n","type":"Number|undefined","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3209,"description":"<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n","itemtype":"method","name":"getLevel","params":[{"name":"channel","description":"<p>Optionally return only channel 0 (left) or 1 (right)</p>\n","type":"Number","optional":true}],"return":{"description":"Amplitude as a number between 0.0 and 1.0","type":"Number"},"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3264,"description":"<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n","itemtype":"method","name":"toggleNormalize","params":[{"name":"boolean","description":"<p>set normalize to true (1) or false (0)</p>\n","type":"Boolean","optional":true}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3293,"description":"<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"set","description":"<p>smoothing from 0.0 <= 1</p>\n","type":"Number"}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3476,"description":"<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"source","description":"<p>p5.sound object (or web audio API source node)</p>\n","type":"Object","optional":true}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3501,"description":"<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n","itemtype":"method","name":"waveform","params":[{"name":"bins","description":"<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"precision","description":"<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n","type":"String","optional":true}],"return":{"description":"Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3553,"description":"<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n","itemtype":"method","name":"analyze","params":[{"name":"bins","description":"<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"scale","description":"<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n","type":"Number","optional":true}],"return":{"description":"spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.","type":"Array"},"example":["\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3650,"description":"<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n","itemtype":"method","name":"getEnergy","params":[{"name":"frequency1","description":"<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n","type":"Number|String"},{"name":"frequency2","description":"<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n","type":"Number","optional":true}],"return":{"description":"Energy   Energy (volume/amplitude) from\n                            0 and 255.","type":"Number"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3739,"description":"<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n","itemtype":"method","name":"getCentroid","return":{"description":"Spectral Centroid Frequency  of the spectral centroid in Hz.","type":"Number"},"example":["\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3826,"description":"<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"smoothing","description":"<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n","type":"Number"}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3854,"description":"<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"linAverages","params":[{"name":"N","description":"<p>Number of returned frequency groups</p>\n","type":"Number"}],"return":{"description":"linearAverages   Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3889,"description":"<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"logAverages","params":[{"name":"octaveBands","description":"<p>Array of Octave Bands objects for grouping</p>\n","type":"Array"}],"return":{"description":"logAverages    Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3925,"description":"<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n","itemtype":"method","name":"getOctaveBands","params":[{"name":"N","description":"<p>Specifies the 1/N type of generated octave bands</p>\n","type":"Number"},{"name":"fCtr0","description":"<p>Minimum central frequency for the lowest band</p>\n","type":"Number"}],"return":{"description":"octaveBands   Array of octave band objects with their bounds","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4168,"description":"<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>startTime in seconds from now.</p>\n","type":"Number","optional":true},{"name":"frequency","description":"<p>frequency in Hz.</p>\n","type":"Number","optional":true}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4218,"description":"<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n","itemtype":"method","name":"stop","params":[{"name":"secondsFromNow","description":"<p>Time, in seconds from now.</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4238,"description":"<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)","type":"AudioParam"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4271,"description":"<p>Returns the value of output gain</p>\n","itemtype":"method","name":"getAmp","return":{"description":"Amplitude value between 0.0 and 1.0","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4285,"description":"<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n","itemtype":"method","name":"freq","params":[{"name":"Frequency","description":"<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Ramp time (in seconds)</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen\n                                 at x seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency","type":"AudioParam"},"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4360,"description":"<p>Returns the value of frequency of oscillator</p>\n","itemtype":"method","name":"getFreq","return":{"description":"Frequency of oscillator in Hertz","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4373,"description":"<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","type":"String"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4386,"description":"<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"getType","return":{"description":"type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.","type":"String"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4399,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4420,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4444,"description":"<p>Pan between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"pan","params":[{"name":"panning","description":"<p>Number between -1 and 1</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4460,"description":"<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"getPan","return":{"description":"panPosition of oscillator , between Left (-1) and Right (1)","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4494,"description":"<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n","itemtype":"method","name":"phase","params":[{"name":"phase","description":"<p>float between 0.0 and 1.0</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4522,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4543,"description":"<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with multiplied output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4563,"description":"<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4767,"description":"<p>Time until envelope reaches attackLevel</p>\n","itemtype":"property","name":"attackTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4772,"description":"<p>Level once attack is complete.</p>\n","itemtype":"property","name":"attackLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4778,"description":"<p>Time until envelope reaches decayLevel.</p>\n","itemtype":"property","name":"decayTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4784,"description":"<p>Level after decay. The envelope will sustain here until it is released.</p>\n","itemtype":"property","name":"decayLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4790,"description":"<p>Duration of the release portion of the envelope.</p>\n","itemtype":"property","name":"releaseTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4796,"description":"<p>Level at the end of the release.</p>\n","itemtype":"property","name":"releaseLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4833,"description":"<p>Reset the envelope with a series of time/value pairs.</p>\n","itemtype":"method","name":"set","params":[{"name":"attackTime","description":"<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n","type":"Number"},{"name":"attackLevel","description":"<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time</p>\n","type":"Number"},{"name":"decayLevel","description":"<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n","type":"Number"},{"name":"releaseTime","description":"<p>Release Time (in seconds)</p>\n","type":"Number"},{"name":"releaseLevel","description":"<p>Amplitude</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4895,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4964,"description":"<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n","itemtype":"method","name":"setRange","params":[{"name":"aLevel","description":"<p>attack level (defaults to 1)</p>\n","type":"Number"},{"name":"rLevel","description":"<p>release level (defaults to 0)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5037,"description":"<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"inputs","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object","optional":true,"multiple":true}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5055,"description":"<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n","itemtype":"method","name":"setExp","params":[{"name":"isExp","description":"<p>true is exponential, false is linear</p>\n","type":"Boolean"}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5078,"description":"<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>","itemtype":"method","name":"play","params":[{"name":"unit","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object"},{"name":"startTime","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5148,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n","itemtype":"method","name":"triggerAttack","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5256,"description":"<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"triggerRelease","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5350,"description":"<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n","itemtype":"method","name":"ramp","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>When to trigger the ramp</p>\n","type":"Number"},{"name":"v","description":"<p>Target value</p>\n","type":"Number"},{"name":"v2","description":"<p>Second target value</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5460,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5479,"description":"<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5498,"description":"<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5657,"description":"<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'white', 'pink' or 'brown'</p>\n","type":"String","optional":true}],"class":"p5.Noise","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5871,"description":"<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n","itemtype":"method","name":"width","params":[{"name":"width","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.Pulse","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6066,"itemtype":"property","name":"input","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6070,"itemtype":"property","name":"output","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6075,"itemtype":"property","name":"stream","type":"MediaStream|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6080,"itemtype":"property","name":"mediaStream","type":"MediaStreamAudioSourceNode|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6085,"itemtype":"property","name":"currentSource","type":"Number|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6090,"description":"<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n","itemtype":"property","name":"enabled","type":"Boolean","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6098,"description":"<p>Input amplitude, connect to it by default but not to master out</p>\n","itemtype":"property","name":"amplitude","type":"p5.Amplitude","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6114,"description":"<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n","itemtype":"method","name":"start","params":[{"name":"successCallback","description":"<p>Name of a function to call on\n                                  success.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n","type":"Function","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6171,"description":"<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n","itemtype":"method","name":"stop","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6191,"description":"<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>An object that accepts audio input,\n                        such as an FFT</p>\n","type":"Object","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6216,"description":"<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6234,"description":"<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n","itemtype":"method","name":"getLevel","params":[{"name":"smoothing","description":"<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n","type":"Number","optional":true}],"return":{"description":"Volume level (between 0.0 and 1.0)","type":"Number"},"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6257,"description":"<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0</p>\n","type":"Number"},{"name":"time","description":"<p>ramp time (optional)</p>\n","type":"Number","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6280,"description":"<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n","itemtype":"method","name":"getSources","params":[{"name":"successCallback","description":"<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>This optional callback receives the error\n                                   message as its argument.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method","type":"Promise"},"example":["\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6340,"description":"<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n","itemtype":"method","name":"setSource","params":[{"name":"num","description":"<p>position of input source in the array</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6462,"description":"<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6478,"description":"<p>Set the output volume of the filter.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number","optional":true},{"name":"rampTime","description":"<p>create a fade that lasts until rampTime</p>\n","type":"Number","optional":true},{"name":"tFromNow","description":"<p>schedule this event to happen in tFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6502,"description":"<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n","itemtype":"method","name":"chain","params":[{"name":"arguments","description":"<p>Chain together multiple sound objects</p>\n","type":"Object","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6525,"description":"<p>Adjust the dry/wet value.</p>\n","itemtype":"method","name":"drywet","params":[{"name":"fade","description":"<p>The desired drywet value (0 - 1.0)</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6542,"description":"<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6557,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6719,"description":"<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n","itemtype":"property","name":"biquadFilter","type":"DelayNode","class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6742,"description":"<p>Filter an audio signal according to a set\nof filter parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6760,"description":"<p>Set the frequency and the resonance of the filter.</p>\n","itemtype":"method","name":"set","params":[{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance (Q) from 0.001 to 1000</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6781,"description":"<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n","itemtype":"method","name":"freq","params":[{"name":"freq","description":"<p>Filter Frequency</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value  Returns the current frequency value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6811,"description":"<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n","itemtype":"method","name":"res","params":[{"name":"res","description":"<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value Returns the current res value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6838,"description":"<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n","itemtype":"method","name":"gain","params":[{"name":"gain","description":"","type":"Number"}],"return":{"description":"Returns the current or updated gain value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6864,"description":"<p>Toggle function. Switches between the specified type and allpass</p>\n","itemtype":"method","name":"toggle","return":{"description":"[Toggle value]","type":"Boolean"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6884,"description":"<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n","itemtype":"method","name":"setType","params":[{"name":"t","description":"","type":"String"}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7198,"description":"<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n","itemtype":"property","name":"bands","type":"Array","class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7239,"description":"<p>Process an input by connecting it to the EQ</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Audio source</p>\n","type":"Object"}],"class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7629,"description":"<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n","itemtype":"property","name":"panner","type":"AudioNode","class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7654,"description":"<p>Connect an audio sorce</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Input source</p>\n","type":"Object"}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7668,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"set","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7687,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7694,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7701,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7753,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"orient","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7772,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7779,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7786,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7838,"description":"<p>Set the rolloff factor and max distance</p>\n","itemtype":"method","name":"setFalloff","params":[{"name":"maxDistance","description":"","type":"Number","optional":true},{"name":"rolloffFactor","description":"","type":"Number","optional":true}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7852,"description":"<p>Maxium distance between the source and the listener</p>\n","itemtype":"method","name":"maxDist","params":[{"name":"maxDistance","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7869,"description":"<p>How quickly the volume is reduced as the source moves away from the listener</p>\n","itemtype":"method","name":"rollof","params":[{"name":"rolloffFactor","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7989,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"leftDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7999,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"rightDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8049,"description":"<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"delayTime","description":"<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n","type":"Number","optional":true},{"name":"feedback","description":"<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n","type":"Number","optional":true},{"name":"lowPass","description":"<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8094,"description":"<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n","itemtype":"method","name":"delayTime","params":[{"name":"delayTime","description":"<p>Time (in seconds) of the delay</p>\n","type":"Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8116,"description":"<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n","itemtype":"method","name":"feedback","params":[{"name":"feedback","description":"<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n","type":"Number|Object"}],"return":{"description":"Feedback value","type":"Number"},"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8148,"description":"<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n","itemtype":"method","name":"filter","params":[{"name":"cutoffFreq","description":"<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n","type":"Number|Object"},{"name":"res","description":"<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n","type":"Number|Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8170,"description":"<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'pingPong' (1) or 'default' (0)</p>\n","type":"String|Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8223,"description":"<p>Set the output level of the delay effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8234,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8242,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8409,"description":"<p>Connect a source to the reverb, and assign reverb parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"},{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8446,"description":"<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n","itemtype":"method","name":"set","params":[{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8482,"description":"<p>Set the output level of the reverb effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8493,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8501,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8621,"description":"<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n","itemtype":"property","name":"convolverNode","type":"ConvolverNode","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8645,"description":"<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n","itemtype":"property","name":"impulses","type":"Array","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8737,"description":"<p>Connect a source to the convolver.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8786,"description":"<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n","itemtype":"method","name":"addImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8808,"description":"<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n","itemtype":"method","name":"resetImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8831,"description":"<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n","itemtype":"method","name":"toggleImpulse","params":[{"name":"id","description":"<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n","type":"String|Number"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8885,"description":"<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n","itemtype":"method","name":"createConvolver","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true}],"return":{"description":"","type":"p5.Convolver"},"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9084,"description":"<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9173,"description":"<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n","itemtype":"property","name":"sequence","type":"Array","class":"p5.Phrase","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9263,"description":"<p>Set the tempo of this part, in Beats Per Minute.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9278,"description":"<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n","itemtype":"method","name":"getBPM","return":{"description":"","type":"Number"},"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9291,"description":"<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9311,"description":"<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"loop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9333,"description":"<p>Tell the part to stop looping.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9349,"description":"<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n","itemtype":"method","name":"stop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9363,"description":"<p>Pause the part. Playback will resume\nfrom the current step.</p>\n","itemtype":"method","name":"pause","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9379,"description":"<p>Add a p5.Phrase to this Part.</p>\n","itemtype":"method","name":"addPhrase","params":[{"name":"phrase","description":"<p>reference to a p5.Phrase</p>\n","type":"p5.Phrase"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9406,"description":"<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n","itemtype":"method","name":"removePhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9424,"description":"<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n","itemtype":"method","name":"getPhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9442,"description":"<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n","itemtype":"method","name":"replaceSequence","params":[{"name":"phraseName","description":"","type":"String"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9473,"description":"<p>Set the function that will be called at every step. This will clear the previous function.</p>\n","itemtype":"method","name":"onStep","params":[{"name":"callback","description":"<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n","type":"Function"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9542,"description":"<p>Start playback of the score.</p>\n","itemtype":"method","name":"start","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9555,"description":"<p>Stop playback of the score.</p>\n","itemtype":"method","name":"stop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9569,"description":"<p>Pause playback of the score.</p>\n","itemtype":"method","name":"pause","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9581,"description":"<p>Loop playback of the score.</p>\n","itemtype":"method","name":"loop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9594,"description":"<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9628,"description":"<p>Set the tempo for all parts in the score</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9729,"description":"<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n","itemtype":"property","name":"bpm","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9750,"description":"<p>number of quarter notes in a measure (defaults to 4)</p>\n","itemtype":"property","name":"timeSignature","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9770,"description":"<p>length of the loops interval</p>\n","itemtype":"property","name":"interval","type":"Number|String","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9787,"description":"<p>how many times the callback has been called so far</p>\n","itemtype":"property","name":"iterations","type":"Number","readonly":"","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9800,"description":"<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n","itemtype":"property","name":"musicalTimeMode","type":"Boolean","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9808,"description":"<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9816,"description":"<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n","itemtype":"property","name":"maxIterations","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9826,"description":"<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9841,"description":"<p>Start the loop</p>\n","itemtype":"method","name":"start","params":[{"name":"timeFromNow","description":"<p>schedule a starting time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9860,"description":"<p>Stop the loop</p>\n","itemtype":"method","name":"stop","params":[{"name":"timeFromNow","description":"<p>schedule a stopping time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9878,"description":"<p>Pause the loop</p>\n","itemtype":"method","name":"pause","params":[{"name":"timeFromNow","description":"<p>schedule a pausing time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9896,"description":"<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n","itemtype":"method","name":"syncedStart","params":[{"name":"otherLoop","description":"<p>a p5.SoundLoop to sync with</p>\n","type":"Object"},{"name":"timeFromNow","description":"<p>Start the loops in sync after timeFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10068,"description":"<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n","itemtype":"property","name":"compressor","type":"AudioNode","class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10084,"description":"<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Sound source to be connected</p>\n","type":"Object"},{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number","optional":true},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10112,"description":"<p>Set the paramters of a compressor.</p>\n","itemtype":"method","name":"set","params":[{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number"},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number"},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number"},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10152,"description":"<p>Get current attack or set value w/ time ramp</p>\n","itemtype":"method","name":"attack","params":[{"name":"attack","description":"<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10178,"description":"<p>Get current knee or set value w/ time ramp</p>\n","itemtype":"method","name":"knee","params":[{"name":"knee","description":"<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10204,"description":"<p>Get current ratio or set value w/ time ramp</p>\n","itemtype":"method","name":"ratio","params":[{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10228,"description":"<p>Get current threshold or set value w/ time ramp</p>\n","itemtype":"method","name":"threshold","params":[{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10252,"description":"<p>Get current release or set value w/ time ramp</p>\n","itemtype":"method","name":"release","params":[{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10277,"description":"<p>Return the current reduction value</p>\n","itemtype":"method","name":"reduction","return":{"description":"Value of the amount of gain reduction that is applied to the signal","type":"Number"},"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10419,"description":"<p>isDetected is set to true when a peak is detected.</p>\n","itemtype":"attribute","name":"isDetected","type":"Boolean","default":"false","class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10432,"description":"<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n","itemtype":"method","name":"update","params":[{"name":"fftObject","description":"<p>A p5.FFT object</p>\n","type":"p5.FFT"}],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10470,"description":"<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n","itemtype":"method","name":"onPeak","params":[{"name":"callback","description":"<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n","type":"Function"},{"name":"val","description":"<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n","type":"Object","optional":true}],"example":["\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10676,"description":"<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"unit","description":"<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n","type":"Object","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10703,"description":"<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n","itemtype":"method","name":"record","params":[{"name":"soundFile","description":"<p>p5.SoundFile</p>\n","type":"p5.SoundFile"},{"name":"duration","description":"<p>Time (in seconds)</p>\n","type":"Number","optional":true},{"name":"callback","description":"<p>The name of a function that will be\n                              called once the recording completes</p>\n","type":"Function","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10739,"description":"<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n","itemtype":"method","name":"stop","class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10864,"description":"<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n","itemtype":"property","name":"WaveShaperNode","type":"AudioNode","class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10883,"description":"<p>Process a sound source, optionally specify amount and oversample values.</p>\n","itemtype":"method","name":"process","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10900,"description":"<p>Set the amount and oversample of the waveshaper distortion.</p>\n","itemtype":"method","name":"set","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10923,"description":"<p>Return the distortion amount, typically between 0-1.</p>\n","itemtype":"method","name":"getAmount","return":{"description":"Unbounded distortion amount.\n                 Normal values range from 0-1.","type":"Number"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10937,"description":"<p>Return the oversampling.</p>\n","itemtype":"method","name":"getOversample","return":{"description":"Oversample can either be 'none', '2x', or '4x'.","type":"String"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11055,"description":"<p>Connect a source to the gain node.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11070,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11084,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11098,"description":"<p>Set the output level of the gain node.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11181,"description":"<p>Connect to p5 objects or Web Audio Nodes</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11194,"description":"<p>Disconnect from soundOut</p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11322,"description":"<p>Getters and Setters</p>\n","itemtype":"property","name":"attack","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11328,"itemtype":"property","name":"decay","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11333,"itemtype":"property","name":"sustain","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11338,"itemtype":"property","name":"release","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11379,"description":"<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11431,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true}],"itemtype":"method","name":"triggerAttack","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11478,"description":"<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","params":[{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"itemtype":"method","name":"triggerRelease","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11516,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11544,"description":"<p>MonoSynth amp</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>desired volume</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Time to reach new volume</p>\n","type":"Number","optional":true}],"return":{"description":"new volume value","type":"Number"},"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11564,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11578,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11592,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11742,"description":"<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n","itemtype":"property","name":"notes","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11755,"description":"<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n","itemtype":"property","name":"polyvalue","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11761,"description":"<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n","itemtype":"property","name":"AudioVoice","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11800,"description":"<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11849,"description":"<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n","itemtype":"method","name":"noteADSR","params":[{"name":"note","description":"<p>Midi note on which ADSR should be set.</p>\n","type":"Number","optional":true},{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11881,"description":"<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11909,"description":"<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","itemtype":"method","name":"noteAttack","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)/</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12021,"description":"<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"noteRelease","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12105,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12119,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12133,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"}],"warnings":[{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:120"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:216"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:316"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:457"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:1001"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:223"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:248"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/validate_params.js:336"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:12"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:81"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:115"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:184"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:219"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:259"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:331"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:13"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:92"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:130"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:185"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:264"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:358"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:398"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:493"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:20"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:67"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:293"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:415"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:460"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:524"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:583"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:668"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:733"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:826"},{"message":"unknown tag: alt","line":" src/core/constants.js:66"},{"message":"unknown tag: alt","line":" src/core/constants.js:84"},{"message":"unknown tag: alt","line":" src/core/constants.js:102"},{"message":"unknown tag: alt","line":" src/core/constants.js:120"},{"message":"unknown tag: alt","line":" src/core/constants.js:138"},{"message":"unknown tag: alt","line":" src/core/environment.js:20"},{"message":"unknown tag: alt","line":" src/core/environment.js:52"},{"message":"unknown tag: alt","line":" src/core/environment.js:79"},{"message":"unknown tag: alt","line":" src/core/environment.js:129"},{"message":"unknown tag: alt","line":" src/core/environment.js:160"},{"message":"unknown tag: alt","line":" src/core/environment.js:228"},{"message":"unknown tag: alt","line":" src/core/environment.js:331"},{"message":"unknown tag: alt","line":" src/core/environment.js:354"},{"message":"unknown tag: alt","line":" src/core/environment.js:372"},{"message":"unknown tag: alt","line":" src/core/environment.js:390"},{"message":"unknown tag: alt","line":" src/core/environment.js:405"},{"message":"unknown tag: alt","line":" src/core/environment.js:421"},{"message":"unknown tag: alt","line":" src/core/environment.js:500"},{"message":"unknown tag: alt","line":" src/core/environment.js:550"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:586"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:660"},{"message":"unknown tag: alt","line":" src/core/environment.js:691"},{"message":"unknown tag: alt","line":" src/core/environment.js:713"},{"message":"replacing incorrect tag: function with method","line":" src/core/internationalization.js:105"},{"message":"replacing incorrect tag: returns with return","line":" src/core/internationalization.js:105"},{"message":"unknown tag: alt","line":" src/core/main.js:42"},{"message":"unknown tag: alt","line":" src/core/main.js:83"},{"message":"unknown tag: alt","line":" src/core/main.js:114"},{"message":"unknown tag: alt","line":" src/core/main.js:415"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:47"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:114"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:154"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:189"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:246"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:292"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:354"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:403"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:454"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:510"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:551"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:592"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:639"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:678"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:725"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:763"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:70"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:122"},{"message":"unknown tag: alt","line":" src/core/reference.js:7"},{"message":"unknown tag: alt","line":" src/core/reference.js:34"},{"message":"unknown tag: alt","line":" src/core/reference.js:87"},{"message":"unknown tag: alt","line":" src/core/reference.js:115"},{"message":"unknown tag: alt","line":" src/core/reference.js:137"},{"message":"unknown tag: alt","line":" src/core/reference.js:158"},{"message":"unknown tag: alt","line":" src/core/reference.js:179"},{"message":"unknown tag: alt","line":" src/core/reference.js:200"},{"message":"unknown tag: alt","line":" src/core/reference.js:231"},{"message":"unknown tag: alt","line":" src/core/reference.js:267"},{"message":"unknown tag: alt","line":" src/core/reference.js:288"},{"message":"unknown tag: alt","line":" src/core/reference.js:309"},{"message":"unknown tag: alt","line":" src/core/reference.js:331"},{"message":"unknown tag: alt","line":" src/core/reference.js:351"},{"message":"unknown tag: alt","line":" src/core/reference.js:379"},{"message":"unknown tag: alt","line":" src/core/reference.js:408"},{"message":"unknown tag: alt","line":" src/core/reference.js:448"},{"message":"unknown tag: alt","line":" src/core/reference.js:490"},{"message":"unknown tag: alt","line":" src/core/reference.js:512"},{"message":"unknown tag: alt","line":" src/core/rendering.js:15"},{"message":"unknown tag: alt","line":" src/core/rendering.js:125"},{"message":"unknown tag: alt","line":" src/core/rendering.js:183"},{"message":"unknown tag: alt","line":" src/core/rendering.js:204"},{"message":"unknown tag: alt","line":" src/core/rendering.js:243"},{"message":"unknown tag: alt","line":" src/core/rendering.js:326"},{"message":"unknown tag: alt","line":" src/core/structure.js:10"},{"message":"unknown tag: alt","line":" src/core/structure.js:83"},{"message":"unknown tag: alt","line":" src/core/structure.js:134"},{"message":"unknown tag: alt","line":" src/core/structure.js:192"},{"message":"unknown tag: alt","line":" src/core/structure.js:290"},{"message":"unknown tag: alt","line":" src/core/structure.js:391"},{"message":"unknown tag: alt","line":" src/core/structure.js:497"},{"message":"unknown tag: alt","line":" src/core/transform.js:11"},{"message":"unknown tag: alt","line":" src/core/transform.js:168"},{"message":"unknown tag: alt","line":" src/core/transform.js:193"},{"message":"unknown tag: alt","line":" src/core/transform.js:232"},{"message":"unknown tag: alt","line":" src/core/transform.js:268"},{"message":"unknown tag: alt","line":" src/core/transform.js:304"},{"message":"unknown tag: alt","line":" src/core/transform.js:342"},{"message":"unknown tag: alt","line":" src/core/transform.js:416"},{"message":"unknown tag: alt","line":" src/core/transform.js:455"},{"message":"unknown tag: alt","line":" src/core/transform.js:494"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:10"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:101"},{"message":"unknown tag: alt","line":" src/dom/dom.js:204"},{"message":"unknown tag: alt","line":" src/dom/dom.js:271"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1560"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1622"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1726"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1765"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1885"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2268"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2778"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:23"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:46"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:69"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:135"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:168"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:201"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:239"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:285"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:330"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:389"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:428"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:471"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:515"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:546"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:604"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:10"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:36"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:64"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:103"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:190"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:243"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:308"},{"message":"unknown tag: alt","line":" src/events/mouse.js:12"},{"message":"unknown tag: alt","line":" src/events/mouse.js:43"},{"message":"unknown tag: alt","line":" src/events/mouse.js:80"},{"message":"unknown tag: alt","line":" src/events/mouse.js:106"},{"message":"unknown tag: alt","line":" src/events/mouse.js:132"},{"message":"unknown tag: alt","line":" src/events/mouse.js:164"},{"message":"unknown tag: alt","line":" src/events/mouse.js:195"},{"message":"unknown tag: alt","line":" src/events/mouse.js:233"},{"message":"unknown tag: alt","line":" src/events/mouse.js:271"},{"message":"unknown tag: alt","line":" src/events/mouse.js:311"},{"message":"unknown tag: alt","line":" src/events/mouse.js:351"},{"message":"unknown tag: alt","line":" src/events/mouse.js:389"},{"message":"unknown tag: alt","line":" src/events/mouse.js:481"},{"message":"unknown tag: alt","line":" src/events/mouse.js:535"},{"message":"unknown tag: alt","line":" src/events/mouse.js:615"},{"message":"unknown tag: alt","line":" src/events/mouse.js:696"},{"message":"unknown tag: alt","line":" src/events/mouse.js:772"},{"message":"unknown tag: alt","line":" src/events/mouse.js:841"},{"message":"unknown tag: alt","line":" src/events/mouse.js:926"},{"message":"unknown tag: alt","line":" src/events/mouse.js:979"},{"message":"unknown tag: alt","line":" src/events/mouse.js:1025"},{"message":"unknown tag: alt","line":" src/events/touch.js:10"},{"message":"unknown tag: alt","line":" src/events/touch.js:71"},{"message":"unknown tag: alt","line":" src/events/touch.js:151"},{"message":"unknown tag: alt","line":" src/events/touch.js:223"},{"message":"unknown tag: alt","line":" src/image/image.js:15"},{"message":"unknown tag: alt","line":" src/image/image.js:94"},{"message":"unknown tag: alt","line":" src/image/image.js:413"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:18"},{"message":"replacing incorrect tag: returns with return","line":" src/image/loading_displaying.js:284"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:301"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:471"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:569"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:633"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:88"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:115"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:152"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:261"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:296"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:346"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:400"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:437"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:548"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:603"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:665"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:738"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:859"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:900"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:941"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:972"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1017"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1052"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1089"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1125"},{"message":"unknown tag: alt","line":" src/image/pixels.js:12"},{"message":"unknown tag: alt","line":" src/image/pixels.js:80"},{"message":"unknown tag: alt","line":" src/image/pixels.js:173"},{"message":"unknown tag: alt","line":" src/image/pixels.js:307"},{"message":"unknown tag: alt","line":" src/image/pixels.js:481"},{"message":"unknown tag: alt","line":" src/image/pixels.js:566"},{"message":"unknown tag: alt","line":" src/image/pixels.js:602"},{"message":"unknown tag: alt","line":" src/image/pixels.js:674"},{"message":"unknown tag: alt","line":" src/io/files.js:20"},{"message":"unknown tag: alt","line":" src/io/files.js:183"},{"message":"unknown tag: alt","line":" src/io/files.js:303"},{"message":"unknown tag: alt","line":" src/io/files.js:583"},{"message":"replacing incorrect tag: returns with return","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:1393"},{"message":"unknown tag: alt","line":" src/io/files.js:1535"},{"message":"unknown tag: alt","line":" src/io/files.js:1592"},{"message":"unknown tag: alt","line":" src/io/files.js:1656"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:85"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:148"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:195"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:240"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:288"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:352"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:545"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:597"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:638"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:896"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:960"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1009"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1055"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1100"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1146"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1190"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1242"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1305"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:40"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:102"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:146"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:191"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:239"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:295"},{"message":"unknown tag: alt","line":" src/io/p5.XML.js:9"},{"message":"unknown tag: alt","line":" src/math/calculation.js:10"},{"message":"unknown tag: alt","line":" src/math/calculation.js:33"},{"message":"unknown tag: alt","line":" src/math/calculation.js:72"},{"message":"unknown tag: alt","line":" src/math/calculation.js:116"},{"message":"unknown tag: alt","line":" src/math/calculation.js:182"},{"message":"unknown tag: alt","line":" src/math/calculation.js:231"},{"message":"unknown tag: alt","line":" src/math/calculation.js:269"},{"message":"unknown tag: alt","line":" src/math/calculation.js:316"},{"message":"unknown tag: alt","line":" src/math/calculation.js:371"},{"message":"unknown tag: alt","line":" src/math/calculation.js:409"},{"message":"unknown tag: alt","line":" src/math/calculation.js:464"},{"message":"unknown tag: alt","line":" src/math/calculation.js:512"},{"message":"unknown tag: alt","line":" src/math/calculation.js:560"},{"message":"unknown tag: alt","line":" src/math/calculation.js:612"},{"message":"unknown tag: alt","line":" src/math/calculation.js:646"},{"message":"unknown tag: alt","line":" src/math/calculation.js:701"},{"message":"unknown tag: alt","line":" src/math/calculation.js:745"},{"message":"replacing incorrect tag: returns with return","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/math.js:10"},{"message":"unknown tag: alt","line":" src/math/noise.js:36"},{"message":"unknown tag: alt","line":" src/math/noise.js:178"},{"message":"unknown tag: alt","line":" src/math/noise.js:243"},{"message":"unknown tag: alt","line":" src/math/p5.Vector.js:10"},{"message":"unknown tag: alt","line":" src/math/random.js:37"},{"message":"unknown tag: alt","line":" src/math/random.js:66"},{"message":"unknown tag: alt","line":" src/math/random.js:153"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:123"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:159"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:186"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:213"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:285"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:320"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:335"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:350"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:11"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:81"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:118"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:150"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:187"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:16"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:140"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:231"},{"message":"unknown tag: alt","line":" src/typography/p5.Font.js:31"},{"message":"unknown tag: alt","line":" src/utilities/conversion.js:10"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:15"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:43"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:130"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:237"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:311"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:373"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:451"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:537"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:10"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:31"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:52"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:73"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:100"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:122"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:143"},{"message":"unknown tag: alt","line":" src/webgl/3d_primitives.js:13"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:11"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:353"},{"message":"unknown tag: alt","line":" src/webgl/light.js:11"},{"message":"unknown tag: alt","line":" src/webgl/light.js:92"},{"message":"unknown tag: alt","line":" src/webgl/light.js:177"},{"message":"unknown tag: alt","line":" src/webgl/light.js:280"},{"message":"unknown tag: alt","line":" src/webgl/light.js:387"},{"message":"unknown tag: alt","line":" src/webgl/light.js:425"},{"message":"unknown tag: alt","line":" src/webgl/light.js:519"},{"message":"unknown tag: alt","line":" src/webgl/light.js:859"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:588"},{"message":"unknown tag: alt","line":" src/webgl/material.js:12"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:184"},{"message":"unknown tag: alt","line":" src/webgl/material.js:282"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:587"},{"message":"unknown tag: alt","line":" src/webgl/material.js:659"},{"message":"unknown tag: alt","line":" src/webgl/material.js:697"},{"message":"unknown tag: alt","line":" src/webgl/material.js:777"},{"message":"unknown tag: alt","line":" src/webgl/material.js:829"},{"message":"unknown tag: alt","line":" src/webgl/material.js:902"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:13"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:115"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:176"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:236"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:303"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:357"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:444"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:472"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:499"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:526"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:554"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:582"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:610"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:633"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:656"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:683"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:801"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:897"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1040"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1098"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1156"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1386"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1458"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1723"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:334"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:603"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:644"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:749"},{"message":"unknown tag: alt","line":" src/webgl/p5.Shader.js:306"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:115"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:158"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:191"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:203"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:236"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:250"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:456"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:471"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:556"},{"message":"replacing incorrect tag: params with param","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2882"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4271"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4360"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4386"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4460"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:6280"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:8116"},{"message":"Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.","line":" src/color/color_conversion.js:8"},{"message":"Missing item type\nConvert an HSBA array to HSLA.","line":" src/color/color_conversion.js:19"},{"message":"Missing item type\nConvert an HSBA array to RGBA.","line":" src/color/color_conversion.js:45"},{"message":"Missing item type\nConvert an HSLA array to HSBA.","line":" src/color/color_conversion.js:100"},{"message":"Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.","line":" src/color/color_conversion.js:123"},{"message":"Missing item type\nConvert an RGBA array to HSBA.","line":" src/color/color_conversion.js:187"},{"message":"Missing item type\nConvert an RGBA array to HSLA.","line":" src/color/color_conversion.js:226"},{"message":"Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.","line":" src/color/p5.Color.js:396"},{"message":"Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.","line":" src/color/p5.Color.js:427"},{"message":"Missing item type\nCSS named colors.","line":" src/color/p5.Color.js:446"},{"message":"Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.","line":" src/color/p5.Color.js:600"},{"message":"Missing item type\nFull color string patterns. The capture groups are necessary.","line":" src/color/p5.Color.js:613"},{"message":"Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.","line":" src/color/p5.Color.js:750"},{"message":"Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.","line":" src/color/p5.Color.js:960"},{"message":"Missing item type","line":" src/core/friendly_errors/fes_core.js:1"},{"message":"Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.","line":" src/core/friendly_errors/fes_core.js:915"},{"message":"Missing item type","line":" src/core/friendly_errors/file_errors.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/sketch_reader.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/stacktrace.js:1"},{"message":"Missing item type\nGiven an Error object, extract the most information from it.","line":" src/core/friendly_errors/stacktrace.js:34"},{"message":"Missing item type","line":" src/core/friendly_errors/validate_params.js:1"},{"message":"Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).","line":" src/core/shape/2d_primitives.js:16"},{"message":"Missing item type\nReturns the current framerate.","line":" src/core/environment.js:305"},{"message":"Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.","line":" src/core/environment.js:315"},{"message":"Missing item type","line":" src/core/helpers.js:1"},{"message":"Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing","line":" src/core/init.js:4"},{"message":"Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.","line":" src/core/internationalization.js:30"},{"message":"Missing item type\nSet up our translation function, with loaded languages","line":" src/core/internationalization.js:126"},{"message":"Missing item type\nReturns a list of languages we have translations loaded for","line":" src/core/internationalization.js:171"},{"message":"Missing item type\nReturns the current language selected for translation","line":" src/core/internationalization.js:178"},{"message":"Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.","line":" src/core/internationalization.js:185"},{"message":"Missing item type","line":" src/core/legacy.js:1"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/core/p5.Element.js:827"},{"message":"Missing item type\nResize our canvas element.","line":" src/core/p5.Renderer.js:99"},{"message":"Missing item type\nHelper function to check font type (system or otf)","line":" src/core/p5.Renderer.js:415"},{"message":"Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178","line":" src/core/p5.Renderer.js:467"},{"message":"Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer","line":" src/core/p5.Renderer2D.js:7"},{"message":"Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.","line":" src/core/p5.Renderer2D.js:402"},{"message":"Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.","line":" src/core/shim.js:18"},{"message":"Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign","line":" src/core/shim.js:39"},{"message":"Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()","line":" src/data/p5.TypedDict.js:197"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:387"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:425"},{"message":"Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:536"},{"message":"Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:600"},{"message":"Missing item type\nHelper function for select and selectAll","line":" src/dom/dom.js:127"},{"message":"Missing item type\nHelper function for getElement and getElements.","line":" src/dom/dom.js:142"},{"message":"Missing item type\nHelpers for create methods.","line":" src/dom/dom.js:309"},{"message":"Missing item type","line":" src/dom/dom.js:450"},{"message":"Missing item type","line":" src/dom/dom.js:1164"},{"message":"Missing item type","line":" src/dom/dom.js:1257"},{"message":"Missing item type","line":" src/dom/dom.js:1296"},{"message":"Missing item type","line":" src/dom/dom.js:3232"},{"message":"Missing item type","line":" src/dom/dom.js:3298"},{"message":"Missing item type","line":" src/dom/dom.js:3360"},{"message":"Missing item type\n_updatePAccelerations updates the pAcceleration values","line":" src/events/acceleration.js:124"},{"message":"Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.","line":" src/events/keyboard.js:298"},{"message":"Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.","line":" src/events/keyboard.js:384"},{"message":"Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.","line":" src/image/filters.js:3"},{"message":"Missing item type\nReturns the pixel buffer for a canvas","line":" src/image/filters.js:24"},{"message":"Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.","line":" src/image/filters.js:60"},{"message":"Missing item type\nModifies pixels RGBA values to values contained in the data object.","line":" src/image/filters.js:81"},{"message":"Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData","line":" src/image/filters.js:101"},{"message":"Missing item type\nReturns a blank ImageData object.","line":" src/image/filters.js:121"},{"message":"Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.","line":" src/image/filters.js:136"},{"message":"Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:189"},{"message":"Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:223"},{"message":"Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.","line":" src/image/filters.js:246"},{"message":"Missing item type\nSets each pixel to its inverse value. No parameter is used.","line":" src/image/filters.js:262"},{"message":"Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation","line":" src/image/filters.js:277"},{"message":"Missing item type\nreduces the bright areas in an image","line":" src/image/filters.js:309"},{"message":"Missing item type\nincreases the bright areas in an image","line":" src/image/filters.js:396"},{"message":"Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.","line":" src/image/image.js:8"},{"message":"Missing item type\nHelper function for loading GIF-based images","line":" src/image/loading_displaying.js:162"},{"message":"Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height","line":" src/image/loading_displaying.js:284"},{"message":"Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.","line":" src/image/loading_displaying.js:597"},{"message":"Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.","line":" src/image/p5.Image.js:9"},{"message":"Missing item type\nHelper function for animating GIF-based images with time","line":" src/image/p5.Image.js:222"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/image/p5.Image.js:253"},{"message":"Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.","line":" src/io/files.js:1789"},{"message":"Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.","line":" src/io/files.js:1857"},{"message":"Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.","line":" src/io/files.js:1890"},{"message":"Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.","line":" src/io/files.js:1902"},{"message":"Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","line":" src/io/p5.Table.js:9"},{"message":"Missing item type\nMultiplies a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2135"},{"message":"Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.","line":" src/math/p5.Vector.js:2187"},{"message":"Missing item type\nDivides a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2214"},{"message":"Missing item type\nCalculates the dot product of two vectors.","line":" src/math/p5.Vector.js:2267"},{"message":"Missing item type\nCalculates the cross product of two vectors.","line":" src/math/p5.Vector.js:2281"},{"message":"Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).","line":" src/math/p5.Vector.js:2295"},{"message":"Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.","line":" src/math/p5.Vector.js:2310"},{"message":"Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)","line":" src/math/p5.Vector.js:2339"},{"message":"Missing item type\nNormalize the vector to length 1 (make it a unit vector).","line":" src/math/p5.Vector.js:2357"},{"message":"Missing item type\nHelper function to measure ascent and descent.","line":" src/typography/attributes.js:280"},{"message":"Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.","line":" src/typography/p5.Font.js:273"},{"message":"Missing item type\nReturns an opentype path for the supplied string and position.","line":" src/typography/p5.Font.js:288"},{"message":"Missing item type","line":" src/webgl/3d_primitives.js:301"},{"message":"Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.","line":" src/webgl/3d_primitives.js:955"},{"message":"Missing item type\nDraw a line given two points","line":" src/webgl/3d_primitives.js:1393"},{"message":"Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1","line":" src/webgl/loading.js:179"},{"message":"Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.","line":" src/webgl/loading.js:290"},{"message":"Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.","line":" src/webgl/loading.js:317"},{"message":"Missing item type\nThis function matches the `query` at the provided `offset`","line":" src/webgl/loading.js:344"},{"message":"Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.","line":" src/webgl/loading.js:356"},{"message":"Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`","line":" src/webgl/loading.js:444"},{"message":"Missing item type","line":" src/webgl/material.js:947"},{"message":"Missing item type","line":" src/webgl/material.js:978"},{"message":"Missing item type\nCreate a 2D array for establishing stroke connections","line":" src/webgl/p5.Geometry.js:212"},{"message":"Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU","line":" src/webgl/p5.Geometry.js:233"},{"message":"Missing item type","line":" src/webgl/p5.Matrix.js:1"},{"message":"Missing item type\nPRIVATE","line":" src/webgl/p5.Matrix.js:722"},{"message":"Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.","line":" src/webgl/p5.RenderBuffer.js:12"},{"message":"Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.","line":" src/webgl/p5.RendererGL.Immediate.js:1"},{"message":"Missing item type\nEnd shape drawing and render vertices to screen.","line":" src/webgl/p5.RendererGL.Immediate.js:129"},{"message":"Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:169"},{"message":"Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:248"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:268"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:302"},{"message":"Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.","line":" src/webgl/p5.RendererGL.Retained.js:59"},{"message":"Missing item type\nDraws buffers given a geometry key ID","line":" src/webgl/p5.RendererGL.Retained.js:110"},{"message":"Missing item type\nmodel view, projection, & normal\nmatrices","line":" src/webgl/p5.RendererGL.js:117"},{"message":"Missing item type\n[background description]","line":" src/webgl/p5.RendererGL.js:586"},{"message":"Missing item type\n[resize description]","line":" src/webgl/p5.RendererGL.js:860"},{"message":"Missing item type\nclears color and depth buffers\nwith r,g,b,a","line":" src/webgl/p5.RendererGL.js:890"},{"message":"Missing item type\n[translate description]","line":" src/webgl/p5.RendererGL.js:924"},{"message":"Missing item type\nScales the Model View Matrix by a vector","line":" src/webgl/p5.RendererGL.js:943"},{"message":"Missing item type\nturn a two dimensional array into one dimensional array","line":" src/webgl/p5.RendererGL.js:1366"},{"message":"Missing item type\nturn a p5.Vector Array into a one dimensional number array","line":" src/webgl/p5.RendererGL.js:1403"},{"message":"Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.","line":" src/webgl/p5.RendererGL.js:1421"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:1"},{"message":"Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/","line":" lib/addons/p5.sound.js:52"},{"message":"Missing item type\nThis module has shims","line":" lib/addons/p5.sound.js:401"},{"message":"Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats","line":" lib/addons/p5.sound.js:536"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:807"},{"message":"Missing item type\nUsed by Osc and Envelope to chain signal math","line":" lib/addons/p5.sound.js:1040"},{"message":"Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.","line":" lib/addons/p5.sound.js:1542"},{"message":"Missing item type\nStop playback on all of this soundfile's sources.","line":" lib/addons/p5.sound.js:2056"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:2604"},{"message":"Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade","line":" lib/addons/p5.sound.js:6455"},{"message":"Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter","line":" lib/addons/p5.sound.js:6462"},{"message":"Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ","line":" lib/addons/p5.sound.js:7009"},{"message":"Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.","line":" lib/addons/p5.sound.js:8508"},{"message":"Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.","line":" lib/addons/p5.sound.js:8659"},{"message":"Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string","line":" lib/addons/p5.sound.js:9808"},{"message":"Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached","line":" lib/addons/p5.sound.js:9826"},{"message":"Missing item type\ncallback invoked when the recording is over","line":" lib/addons/p5.sound.js:10660"},{"message":"Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release","line":" lib/addons/p5.sound.js:11995"},{"message":"Missing item type","line":" lib/addons/p5.sound.min.js:1"}],"consts":{"LABEL":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"FALLBACK":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"RGB":["p5.colorMode"],"HSB":["p5.colorMode"],"HSL":["p5.colorMode"],"CHORD":["p5.arc"],"PIE":["p5.arc"],"OPEN":["p5.arc"],"CENTER":["p5.ellipseMode","p5.rectMode","p5.imageMode","p5.textAlign"],"RADIUS":["p5.ellipseMode","p5.rectMode"],"CORNER":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"CORNERS":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"ROUND":["p5.strokeCap","p5.strokeJoin"],"SQUARE":["p5.strokeCap"],"PROJECT":["p5.strokeCap"],"MITER":["p5.strokeJoin"],"BEVEL":["p5.strokeJoin"],"POINTS":["p5.beginShape"],"LINES":["p5.beginShape"],"TRIANGLES":["p5.beginShape"],"TRIANGLE_FAN":["p5.beginShape"],"TRIANGLE_STRIP":["p5.beginShape"],"QUADS":["p5.beginShape"],"QUAD_STRIP":["p5.beginShape"],"TESS":["p5.beginShape"],"CLOSE":["p5.endShape"],"ARROW":["p5.cursor"],"CROSS":["p5.cursor"],"HAND":["p5.cursor"],"MOVE":["p5.cursor"],"TEXT":["p5.cursor"],"P2D":["p5.createCanvas","p5.createGraphics"],"WEBGL":["p5.createCanvas","p5.createGraphics"],"BLEND":["p5.blendMode","p5.Image.blend","p5.blend"],"DARKEST":["p5.blendMode","p5.Image.blend","p5.blend"],"LIGHTEST":["p5.blendMode","p5.Image.blend","p5.blend"],"DIFFERENCE":["p5.blendMode","p5.Image.blend","p5.blend"],"MULTIPLY":["p5.blendMode","p5.Image.blend","p5.blend"],"EXCLUSION":["p5.blendMode","p5.Image.blend","p5.blend"],"SCREEN":["p5.blendMode","p5.Image.blend","p5.blend"],"REPLACE":["p5.blendMode","p5.Image.blend","p5.blend"],"OVERLAY":["p5.blendMode","p5.Image.blend","p5.blend"],"HARD_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"SOFT_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"DODGE":["p5.blendMode","p5.Image.blend","p5.blend"],"BURN":["p5.blendMode","p5.Image.blend","p5.blend"],"ADD":["p5.blendMode","p5.Image.blend","p5.blend"],"REMOVE":["p5.blendMode"],"SUBTRACT":["p5.blendMode"],"VIDEO":["p5.createCapture"],"AUDIO":["p5.createCapture"],"THRESHOLD":["p5.Image.filter","p5.filter"],"GRAY":["p5.Image.filter","p5.filter"],"OPAQUE":["p5.Image.filter","p5.filter"],"INVERT":["p5.Image.filter","p5.filter"],"POSTERIZE":["p5.Image.filter","p5.filter"],"ERODE":["p5.Image.filter","p5.filter"],"DILATE":["p5.Image.filter","p5.filter"],"BLUR":["p5.Image.filter","p5.filter"],"NORMAL":["p5.Image.blend","p5.blend","p5.textStyle","p5.textureMode"],"RADIANS":["p5.angleMode"],"DEGREES":["p5.angleMode"],"LEFT":["p5.textAlign"],"RIGHT":["p5.textAlign"],"TOP":["p5.textAlign"],"BOTTOM":["p5.textAlign"],"BASELINE":["p5.textAlign"],"ITALIC":["p5.textStyle"],"BOLD":["p5.textStyle"],"BOLDITALIC":["p5.textStyle"],"WORD":["p5.textWrap"],"CHAR":["p5.textWrap"],"IMAGE":["p5.textureMode"],"CLAMP":["p5.textureWrap"],"REPEAT":["p5.textureWrap"],"MIRROR":["p5.textureWrap"]}}
            \ No newline at end of file
            diff --git a/dist/reference/index.html b/dist/reference/index.html
            new file mode 100644
            index 0000000000..6b3f453004
            --- /dev/null
            +++ b/dist/reference/index.html
            @@ -0,0 +1,294 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">reference | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="reference-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Reference</h1>
            +
            +      <div id="search" class="search-wrapper" role="search"></div>
            +      <div id="collection-list-nav"></div>
            +
            +          <!--class="container-fluid"-->
            +      <div id="list" tabindex="2" class="list-wrapper allItems-collection"></div>
            +      <div id="item" tabindex="1" class="item-wrapper apidocs"></div>
            +      <div id="file" class="file-wrapper"></div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  <script src='/assets/js/p5.min.js?v=fbf148'></script>
            +  <script src='/assets/js/p5.sound.min.js?v=53b7c5'></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
            +  <script src="/assets/js/vendor/require.min.js"></script>
            +  <script src="/assets/js/render.js?v=56ab24"></script>
            +  <script src="/assets/js/reference.js?v=c69268"></script>
            +
            +  <script>
            +
            +    var translations;
            +
            +    $(document).ready(function() {
            +      var routes = window.location.pathname.split('/');
            +      var lang = routes[1];
            +      if (langs.indexOf(lang) != -1) {
            +        $.getJSON('/assets/reference/'+lang+'.json', function(data) {
            +          translations = data;
            +
            +          window.addEventListener('reference-rendered', function() {
            +            console.log("rendered");
            +            updateLanguage();
            +          }, false);
            +        });
            +      }
            +    });
            +
            +    function removePlaceholder() {
            +      $('#search input').attr('placeholder', '');
            +    }
            +
            +    function updateLanguage() {
            +      if (translations) {
            +        // reference title
            +        $('h1').html(translations['h1']);
            +        $('#search input').attr('placeholder', translations['reference-search']);
            +        $('#search input').on('focus', removePlaceholder);
            +        $('#search input').focusout(function () {
            +          $('#search input').attr('placeholder', translations['reference-search']);
            +        })
            +        $('#search input').attr('title', translations['reference-search']);
            +        // reference description
            +        $('#reference-description1').html(translations['reference-description1']);
            +        $('#reference-description2').html(translations['reference-description2']);
            +        $('#reference-description3').html(translations['reference-description3']);
            +        $('#reference-description4').html(translations['reference-description4']);
            +        // reference contribute
            +        $('#reference-contribute1').html(translations['reference-contribute1']);
            +        $('#reference-contribute2').html(translations['reference-contribute2']);
            +        // reference error
            +        $('#reference-error1').html(translations['reference-error1']);
            +        $('#reference-error2').html(translations['reference-error2']);
            +        $('#reference-error3').html(translations['reference-error3']);
            +        $('#reference-error4').html(translations['reference-error4']);
            +        $('#reference-error5').html(translations['reference-error5']);
            +        // reference texts
            +        $('#reference-example').html(translations['reference-example']);
            +        $('#reference-description').html(translations['reference-description'])
            +        $('#reference-extends').html(translations['reference-extends']);
            +        $('#reference-parameters').html(translations['reference-parameters']);
            +        $('#reference-syntax').html(translations['reference-syntax']);
            +        $('#reference-returns').html(translations['reference-returns']);
            +        $('.group-name, .subgroup-name').each(function() {
            +          $(this).text(translations[$(this).text()]);
            +        });
            +        var routes = window.location.hash.split('/');
            +        var obj = routes[1];
            +        var name = routes[2];
            +
            +        // class page
            +        if (routes.length == 2) {
            +          var entry = translations[obj];
            +          for (var k in entry) {
            +            if (k == 'description') {
            +              $('.description-text').html('');
            +              entry.description.forEach(function (p) {
            +                $('.description-text').append('<p>' + p + '</p>');
            +              });
            +            }
            +            else if (k == 'params') {
            +              $('.params').find('ul').children('li').each(function () {
            +                var paramname = $(this).children('.paramname').text();
            +                $(this).children('.paramtype').text(entry.params[paramname]);
            +              });
            +            }
            +            else if (k == 'returns') {
            +              $('.returns').text(entry.returns);
            +            }
            +            // fields and methods sections
            +            else {
            +              // field
            +              $("[aria-labelledby='reference-fields']").children('li').each(function (i) {
            +                var fieldName = $(this).children('.paramname').children('a').text();
            +                let descr = '';
            +                var paragraphs = entry[fieldName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +              // method
            +              $("[aria-labelledby='reference-methods']").children('li').each(function (i) {
            +                var method = $(this).children('.paramname').children('a').text();
            +                // removes the brackets
            +                var methodName = method.substring(0, method.length - 2);
            +                let descr = '';
            +                var paragraphs = entry[methodName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +            }
            +          }
            +        }
            +
            +        // method/field page
            +        if (routes.length == 3) {
            +          if (translations[obj] && translations[obj][name]) {
            +            var entry = translations[obj][name];
            +
            +            $('.description-text').html('');
            +            entry.description.forEach(function (p) {
            +              $('.description-text').append('<p>' + p + '</p>');
            +            });
            +            $('.returns').html(entry.returns);
            +            $('.params').find('ul').children('li').each(function () {
            +              var paramname = $(this).children('.paramname').text();
            +              $(this).children('.paramtype').html(entry.params[paramname]);
            +            });
            +          }
            +        }
            +      }
            +    }
            +    </script>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="reference-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/reference/staticStrings.json b/dist/reference/staticStrings.json
            new file mode 100644
            index 0000000000..4ba85d3402
            --- /dev/null
            +++ b/dist/reference/staticStrings.json
            @@ -0,0 +1,16 @@
            +{
            +  "h1": "Reference",
            +  "reference-search": "Search reference",
            +  "reference-description1": "Can't find what you're looking for? You may want to check out",
            +  "reference-description3": "You can also download an offline version of the reference.",
            +  "reference-contribute2": "Please let us know.",
            +  "reference-error1": "Notice any errors or typos?",
            +  "reference-error3": "Please feel free to edit ",
            +  "reference-error5": "and issue a pull request!",
            +  "reference-example": "Example",
            +  "reference-description": "Description",
            +  "reference-extends": "Extends",
            +  "reference-parameters": "Parameters",
            +  "reference-syntax": "Syntax",
            +  "reference-returns": "Returns"
            +}
            diff --git a/dist/showcase/featuring/casey-louise.html b/dist/showcase/featuring/casey-louise.html
            new file mode 100644
            index 0000000000..63f276e9d5
            --- /dev/null
            +++ b/dist/showcase/featuring/casey-louise.html
            @@ -0,0 +1,240 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>p5.js Shaders</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <div class="glitch-embed-wrap" style="height: 420px; width: 100%;">
            +        <iframe src="https://glitch.com/embed/#!/embed/shader-on-vertex?path=&previewSize=100"
            +          title="A Glitch project showing how to apply shaders to a vertex shape in p5.js."
            +          style="height: 100%; width: 100%; border: 0;">
            +        </iframe>
            +      </div>
            +    </section>
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Casey Conchinha <span class="note">(he/him)</span></p>
            +        <p>Louise Lessél <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From New York, New York</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class='links' aria-labelledby="resources">
            +          <li><a href="https://bit.ly/p5shaders" target="_blank">p5.js Shaders guide</a></li>
            +          <li><a href="https://bit.ly/p5shadersexamples" target="_blank">Glitch collection of p5.js shader examples</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>Casey: I'm a student at NYU ITP who's interested in computer graphics and interactive spaces, physical and digital.</p>
            +        <p class='project-a'>Louise: I'm a student at NYU ITP who's interested in computer graphics and interactive spaces based on sensor technologies.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>Casey: I started learning p5.js in 2018 in my first semester at ITP, though I had been dabbling in<a href="https://processing.org/"
            +            target="_blank">Processing</a> since 2012. I was introduced to Processing by my friend Pedro while I was studying graphic design, and it blew my mind. The idea of making my own tools for creating graphics and interactive art piqued my interest, but once I actually tried it, I was hooked. The first project I can remember was an eye that followed you around the screen, and it was sad when you left it alone.</p>
            +        <p class='project-a'>Louise: I initially learned p5.js to make a website I was creating more playful. I’m a C# programmer, so this was a good segway into JavaScript for me.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>Casey: I was putting off learning shaders for a long time, and I was also curious if I could use them in p5.js. Then I heard about a grant for open source, storytelling, and learning resource projects at ITP called<a href="https://www.itpxstory.com/"
            +            target="_blank">xStory</a>. Since I wasn't finding much in the way of p5.js + shader documentation, I decided to figure out how they're implemented in p5.js and create a resource for others to learn. When I told Louise about the project, she was immediately excited about learning and teaching shaders in p5.js. She's been great about making sure the project is a learning resource and not just a collection of examples.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>Casey: Does <a href="https://thecodingtrain.com/"
            +            target="_blank">Shiffman</a> count as a feature? I also love having the ability to share my programs on the web so that people don't have to install special software or come to NYC to see my work.</p>
            +        <p class='project-a'>
            +          Louise: My favorite feature is <code><a href="https://p5js.org/reference/#/p5/push" target="_blank">push()</a></code> and <code><a href="https://p5js.org/reference/#/p5/pop" target="_blank">pop()</a></code> for transformation of the coordinate system to make generative visuals.
            +        </p>
            +
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>Casey: The beginning of the project (figuring out how things work) was us reaching out to amazing people, asking questions, and asking for permission to use their examples in our project.<a
            +            href="https://github.com/aferriss/p5jsShaderExamples"
            +            target="_blank">Adam Ferriss' GitHub repo</a> really laid the groundwork for us in understanding how shaders work in p5.js and provided a framework of approachable examples for us to build on. For some specific p5.js-related issues we were having, we reached out to <a
            +            href="http://www.katehollenbach.com/" target="_blank">Kate
            +            Hollenbach</a> and <a href="https://stalgiagrigg.name/"
            +            target="_blank">Stalgia Grigg</a> (who worked on the <a
            +            href="https://github.com/processing/p5.js/issues?q=is%3Aissue+is%3Aopen+webgl+label%3Aarea%3Awebgl"
            +            target="_blank">WebGL implementation in p5.js</a>), and they were super helpful.
            +        </p>
            +        <p class='project-a'>Louise: The learning curve was pretty steep for getting shaders into p5. Luckily, there were some very well-documented examples on GitHub by Adam Ferriss. Our aim was to do so in a way that a complete beginner can understand how to implement it, so it was as much a technical challenge as it was a challenge in teaching code to strangers and beginners. Here we drew inspiration from the way the<a
            +            href="https://openframeworks.cc/ofBook/chapters/foreword.html"
            +            target="_blank">openFrameworks book</a> is written. A fun "hey, it’s not hard and you can do it too" approach is what we believe in.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out the <a href="https://github.com/ITP-xStory"
            +            target="_blank">xStory GitHub</a> to explore our peers' amazing grant projects!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'>Casey: <a href="https://cargocollective.com/kcconch"
            +            target="_blank">cargocollective.com/kcconch</a>, <a href="https://github.com/kcconch"
            +            target="_blank">@kcconch</a> (GitHub)</p>
            +        <p class='project-a'>Louise: <a href="http://www.louiselessel.com/" target="_blank">louiselessel.com</a>, <a
            +            href="https://github.com/louiselessel" target="_blank">@louiselessel</a> (GitHub)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/showcase/featuring/daein-chung.html b/dist/showcase/featuring/daein-chung.html
            new file mode 100644
            index 0000000000..214ccc8d82
            --- /dev/null
            +++ b/dist/showcase/featuring/daein-chung.html
            @@ -0,0 +1,225 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Chillin'</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only' id="info">Project Info</h2>
            +      <img src="../../assets/img/showcase/daein-chung/daein-chung_chillin.png" alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device.
            +        At the top, there is a text input box to enter a message and download your own poster.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Dae In Chung <span class="note">(he/him)</span></p>
            +        <p class="creator-from">From Baltimore, Maryland</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class="links">
            +          <li><a href="https://exp.paperdove.com/chillin/" target="_blank">View Chillin'</a></li>
            +          <li><a href="https://github.com/cdaein/exp/tree/gh-pages/chillin"
            +              target="_blank">Code for Chillin' on GitHub</a></li>
            +          <li><a href="https://paperdove.com/work/2019-chillin/" target="_blank">More info in Dae In Chung's Portfolio</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I am a graphic designer and a faculty member at Maryland Institute College of Art, where I mainly teach coding (with p5.js and Processing, of course) and motion graphics.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I have been using <a href="https://processing.org/"
            +            target="_blank">Processing</a> for some time, and when p5.js came along, I started using it without a second thought because it was easy to convert existing Processing code and share projects online.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>This summer, I gave myself a challenge of making typographic posters with coding, and this is one of the posters I made. I didn’t know until very recently that I could use motion sensor data with p5.js. I was also watching<a
            +            href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6bLh3T_4wtrmVHOrOEM1ig_"
            +            target="_blank">Dan Shiffman’s matter.js tutorial videos</a>, so I thought why not combine the two and practice what I was learning?
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>There are many things I love about p5.js such as the online community and beginner friendliness. What I really like right now is the<a href="https://editor.p5js.org/"
            +            target="_blank">online editor</a>, with which I can not only work online for myself but also share URLs quickly in the present mode. For this project in particular, I had to do a lot of testing on my phone, and it was much easier and quicker than committing to GitHub.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>I had some troubles with handling font, alpha channel and z-depth in <a
            +            href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5"
            +            target="_blank">WebGL</a> mode. I am still not happy with all my decisions. But in general, it was helpful to search the forum and not to forget to break down problems into smaller ones and iterate little by little. Also, I had issues with rendering out video files directly out of p5.js. Screen recording was not an option because of intermittent frame rate drops (my laptop is pretty slow). After doing some research, I decided to learn some basics of <a href="https://electronjs.org/"
            +            target="_blank">Electron</a> and build a tool for myself.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>As mentioned above, if you want to render out frames and video files out of p5.js sketches, check out my<a
            +            href="https://github.com/cdaein/p5js-electron-canvas-saver-boilerplate" target="_blank">Canvas Saver
            +            boilerplate</a> and let me know what you think.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/cdaein/" target="_blank">@cdaein</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/showcase/featuring/moon-xin.html b/dist/showcase/featuring/moon-xin.html
            new file mode 100644
            index 0000000000..4741c2a07f
            --- /dev/null
            +++ b/dist/showcase/featuring/moon-xin.html
            @@ -0,0 +1,232 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Moving Responsive Posters</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png"
            +        alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Moon Jang <span class="note">(she/her)</span></p>
            +        <p>Xin Xin <span class="note">(they/them)</span></p>
            +        <p class="creator-from">From Athens, Georgia</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Posters By</h3>
            +        <ul class="links">
            +          <li><a href="https://editor.p5js.org/avezray/present/JTjhOdGRB" target="_blank">Avery Ray</a></li>
            +          <li><a href="https://editor.p5js.org/carcarw/present/DyKJHUtCN" target="_blank">Carlee Wooddell</a></li>
            +          <li><a href="https://editor.p5js.org/mdh54215/present/h5wp4EYen" target="_blank">Mia Hofmann</a></li>
            +          <li><a href="https://editor.p5js.org/katiehuang1998@gmail.com/present/1GhSDw-Og" target="_blank">Katie
            +              Huang</a></li>
            +          <li><a href="https://editor.p5js.org/borderrider@gmail.com/present/Lg_pSPRHF" target="_blank">Lila
            +              Mitchell</a></li>
            +          <li><a href="https://editor.p5js.org/wallacekd/present/GqWZOYUSN" target="_blank">Kathryn Wallace</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>Moon: I'm a graphic designer, visual artist, and design educator. This summer, I taught a graphic design course in the University of Georgia Cortona program in Italy, introducing some basics of p5.js. This fall, I am planning to teach and to study digital platforms at UGA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>My former colleague, <a href="https://xin-xin.info/" target="_blank">Xin
            +            Xin</a>, invited me to <a href="https://medium.com/processing-foundation/pcd/home"
            +            target="_blank">Processing Community Day</a> in <a
            +            href="https://day.processing.org/pcd-la.html"
            +            target="_blank">LA in January 2019</a>. They helped me with the tools and logics of p5.js. It was an excellent teaching and learning experience.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>We followed basic tutorials, <a href="https://thecodingtrain.com/"
            +            target="_blank">Daniel's videos on YouTube</a>, and <a
            +            href="https://p5js.org/reference/"
            +            target="_blank">Reference on the p5.js website</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>My favorite function is related to <a
            +            href="https://p5js.org/reference/#group-Typography"
            +            target="_blank">type</a> and <a
            +            href="https://p5js.org/reference/#group-Transform"
            +            target="_blank">transformation</a>: <code><a href="https://p5js.org/reference/#/p5/rotate" target="_blank">rotate()</a></code>. I was able to use and to teach this tool to visualize various ideas about time in motion.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>It was challenging for me, a beginner, to understand the overall structure of p5.js and how code works in general. I had to repeat the p5.js basics a couple of times, and then I drew a chart to memorize and to teach the way I understood the p5.js structure and code with strong constraints I set up. It was an excellent teaching and learning experience.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out the <a href="http://www.brokennature.org/"
            +            target="_blank">Design Triennale</a> in Milan, Italy.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="http://www.moonjang.com/" target="_blank">moonjang.com</a>
            +          <br><a href="https://www.instagram.com/borderrider/" target="_blank">@borderrider</a> (Instagram)
            +        </p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/showcase/featuring/phuong-ngo.html b/dist/showcase/featuring/phuong-ngo.html
            new file mode 100644
            index 0000000000..3eb40f10be
            --- /dev/null
            +++ b/dist/showcase/featuring/phuong-ngo.html
            @@ -0,0 +1,232 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Airi Flies</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" alt="A screenshot of a poster of Airi Flies, a game to help Airi fly by saying pew.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Phuong Ngo <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From Kyiv, Ukraine</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://www.yonaymoris.me/AiriFlies/" target="_blank">Play Airi Flies!</a></li>
            +          <li><a href="https://github.com/yonaymoris/AiriFlies" target="_blank">Code for AiriFlies on GitHub</a>
            +          </li>
            +          <li><a href="https://www.yonaymoris.me/projects/airiflies"
            +              target="_blank">More info in Phuong Ngo's portfolio</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I'm a creative coder and designer, a <a href="https://schoolofma.org/"
            +            target="_blank">School of Machines, Making & Make-Believe</a> diversity scholarship recipient, and just a curious creature.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I was taking a course at the School of Machines in Berlin this summer called! "<a href="https://schoolofma.org/bots.html"
            +            target="_blank">Bots and Machine Learning</a>," mainly taught by <a
            +            href="https://1023.io/" target="_blank">Yining Shi</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>I used p5.js to work on the visual part of the game. The animation sprites for Airi and the ghosts were drawn on an iPad app called<a href="https://rizer.co/pixaki/"
            +            target="_blank">Pixaki</a> and then integrated into <a
            +            href="http://molleindustria.github.io/p5.play/"
            +            target="_blank">p5.play</a> code. I mainly used examples at p5.play as a reference.</p>
            +        <p class='project-a'>For the endless scrolling background, I found a <a
            +            href="https://editor.p5js.org/chjno/sketches/ByZlypKWM"
            +            target="_blank">p5 sketch by chjno</a>. I set a condition so whenever the word "pew" or a mouse click was detected, the scrolling speed would change to make an illusion of Airi flying up. When the user does not do anything, the scrolling speed is negative, which makes it look like Airi is falling down.
            +        </p>
            +        <p class='project-a'>For sound recognition, I used <a
            +            href="https://teachablemachine.withgoogle.com/io19" target="_blank">Google's Teachable Machine
            +            2</a> (currently, there is a beta version not available in public yet, but it will be very soon!). I added around 120 samples of my classmates saying the word "pew" with different intonations and 80 samples of background noise to train it. Then I integrated the model into the game with <a href="https://ml5js.org/" target="_blank">ml5.js</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>I really love how easily you can create, manipulate, and delete HTML blocks and classes with the<a href="https://p5js.org/reference/"
            +            target="_blank">p5.js
            +            library</a> via <code><a href="https://p5js.org/reference/#/p5/createDiv" target="_blank">createDiv()</a></code>,
            +          <code><a href="https://p5js.org/reference/#/p5.Element/addClass" target="_blank">addClass()</a></code> etc. But my most favorite function is <code><a href="https://p5js.org/reference/#/p5/draw" target="_blank">draw()</a></code>, since this is where you create magic.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>There were a lot of challenges simply because p5.js was something new to me. I did not work much with JavaScript in general before. Reading documentation and searching for similar examples helped a lot.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out <a href="https://schoolofma.org/programs"
            +            target="_blank">School of Machines' courses</a>! They try hard to connect the most creative people in the world and they do it well so far. ❤️
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://www.yonaymoris.me/" target="_blank">yonaymoris.me</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/showcase/featuring/qianqian-ye.html b/dist/showcase/featuring/qianqian-ye.html
            new file mode 100644
            index 0000000000..085f1b886a
            --- /dev/null
            +++ b/dist/showcase/featuring/qianqian-ye.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Qtv</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" alt="A guest talk video (Guest Talk #1) on Qtv by Qianqian Ye, featuring Kaikai and Cheng Xu.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Qianqian Ye <span class="note">(she/her)</span></p>
            +        <p class="creator-from">Los Angeles, California</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Resources</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://bit.ly/2XVzPAv" target="_blank">Qtv YouTube</a></li>
            +          <li><a href="https://www.instagram.com/q_tv_/" target="_blank">Qtv Instagram</a></li>
            +          <li><a href="https://space.bilibili.com/442343394" target="_blank">Qtv Bilibili</a></li>
            +          <li><a href='https://v.douyin.com/sopAGk/' target='_blank'>@Q_tv TikTok</a></li>
            +          <li><a href="https://medium.com/processing-foundation/interview-with-2019-fellow-qianqian-ye-799c0115c295"
            +              target="_blank">Processing Foundation interview with Qianqian Ye</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I am a Chinese artist and designer based in Los Angeles.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>My partner introduced me to p5.js, which I learned mainly by watching free online video tutorials. My first p5.js project was drawing some shapes with different colors.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>This project started with an idea of teaching my mom, who lives in China and doesn’t speak English, to code with p5.js. This project was difficult on multiple levels, and I wanted to start by identifying the main reasons why it’s more challenging for someone like my mother to learn to code—primarily due to the lack of free creative coding education resources. Most of the free resources to learn creative coding are unavailable in China. The p5.js tutorials on YouTube as well as the p5.js Twitter and Instagram accounts are inaccessible in China because of internet censorship.</p>
            +        <p class='project-a'>I learned a lot from YouTube videos such as the <a href="https://thecodingtrain.com/"
            +            target="_blank">Coding Train</a>, but the more I watched coding tutorials online, the more I realized how difficult it is to find other womxn and people of color teaching coding, especially in Mandarin. I wanted to help other Chinese womxn relate to creative coding.</p>
            +        <p class='project-a'>I am working on opening up the video channels to other Chinese creatives who want to contribute to the educational resource together, like interviews and guest tutorials. If you are interested in teaching/talking about creative coding in Mandarin, HMU!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>The <a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a> is my favorite feature. It makes web-based creative coding seamless.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>Learning to code in a second language was difficult and the lack of community made this process even harder. I hope to speak from my experience as a beginner and someone who once felt like an outsider to the creative coding and video tutorial world.</p>
            +        <p class='project-a'>I spend a lot of time researching the latest technology for my videos. In the end, I decided on using my phone to record and iMovie to edit. I hope to encourage others that it doesn’t take a lot of expensive gears to get started making instructional videos.</p>
            +        <p class='project-a'>Another issue I came across was my own fear of putting myself online. I first had to get over my anxiety of making mistakes in the videos or receiving negative comments online. Often womxn and people of color are targets for online harassment. I’m hoping to help set an example for other womxn and people of color that it’s ok to put yourselves online and strengthen your communities by sharing your knowledge. Eventually, we will be able to stop online harassment by creating strong diverse communities.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>I am very excited about <a href="http://tinytechzines.org/"
            +            target="_blank">Tiny Tech Zines</a> in LA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="http://www.qianqian-ye.com/" target="_blank">qianqian-ye.com</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/showcase/featuring/roni-cantor.html b/dist/showcase/featuring/roni-cantor.html
            new file mode 100644
            index 0000000000..7ab83c4e46
            --- /dev/null
            +++ b/dist/showcase/featuring/roni-cantor.html
            @@ -0,0 +1,221 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Programmed Plotter Drawings</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img class='half-image' src="../../assets/img/showcase/roni-cantor/roni-cantor_plotter-turquoise.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a turquoise gel pen.">
            +      <img class='half-image' src="../../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a white gel pen.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Roni Cantor <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From Toronto, Canada</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class="links" aria-labelledby="resources">
            +          <li><a href="https://editor.p5js.org/ronicantor/sketches/eq2bIhmh2"
            +              target="_blank">Example sketch in p5.js Web Editor</a></li>
            +          <li><a href="https://drive.google.com/file/d/1UJy6q5cDl6Hg79O9mX1ZN7NFp0NXSYCs/view?usp=sharing"
            +              target="_blank">AxiDraw V3 demo video</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I just graduated from Ryerson University's New Media program. Coming from 4 years of coding and making robots, I decided to take a break and play with some more traditional forms of art—while still coding and playing with robots.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I first started using p5.js at <a href="https://itp.nyu.edu/camp2019/"
            +            target="_blank">NYU ITP Camp</a>! After using <a
            +            href="https://processing.org/" target="_blank">Processing</a> for many years, I wanted to try something new.
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>I used p5.js in this project to generate the sine wave and lerp (linear interpolation) formulas and display the visuals in the<a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a>. I then used a feature in my code that exported my programmed graphic into an<a
            +            href="https://developer.mozilla.org/en-US/docs/Web/SVG"
            +            target="_blank">SVG</a> file. I needed an SVG file to give to the plotter—an <a
            +            href="https://shop.evilmadscientist.com/productsmenu/846" target="_blank">AxiDraw
            +            V3</a>—so that it understood where to draw the lines that I programmed. I sent this information to the plotter with a program called<a href="https://inkscape.org/"
            +            target="_blank">Inkscape</a>!</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>
            +          <code><a href="https://p5js.org/reference/#/p5/lerp" target="_blank">lerp()</a></code> because lines are fun and "lerp" is a fun word to say!
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>It was my first time using p5.js, Inkscape, and a plotter! I really benefited from the people around me who had used p5 before, as well as online guides and forums.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/gandyworks/"
            +            target="_blank">@gandyworks</a> on Instagram—super cool analog plotter stuff.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://ronicantor.com/" target="_blank">ronicantor.com</a>
            +          <br><a href="https://www.instagram.com/roni.cantor/"
            +            target="_blank">@roni.cantor</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/showcase/index.html b/dist/showcase/index.html
            new file mode 100644
            index 0000000000..67700a4a5b
            --- /dev/null
            +++ b/dist/showcase/index.html
            @@ -0,0 +1,245 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main  id="content" class="column-span">
            +    <section class="showcase-intro">
            +      <h1>Showcase</h1>
            +      
            +      <p>Introducing Showcase, created by <a href="https://ashleykang.dev" target="_blank">Ashley Kang</a>
            +       in 2019 and currently curated by <a href="https://katiechan.cargo.site/" target="_blank">Katie Chan</a>.
            +      We're celebrating how people are using p5.js to make creative work, learning, and open source more interesting and inclusive. Together, we make community. During Summer 2019, we asked a few creators to share more about how they've used p5.js through different projects and pieces.</p>
            +      <p>The Summer 2021 Showcase: The Love Ethic is now open for submissions, nominate someone's p5.js work or your own to be featured here! If Google is not available in your region, please email chankati@usc.edu to submit!</p>
            +
            +      <span id="nominate" class="nominate"><a href="https://forms.gle/ETP7kjAocBcfGTuj8" target="_blank">Nominate a Project</a></span>
            +    </section>
            +
            +    <section class="showcase-featured">
            +      <h2 class="featuring">Featuring</h2>
            +
            +      <div class="left-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/roni-cantor.html">Programmed Plotter Drawings</a></h3>
            +          <p class="credit">Roni Cantor</p>
            +          <a href="./featuring/roni-cantor.html" class="no-arrow-link">
            +            <img src="../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg" 
            +            alt="A drawing of a sine wave lerp plotted on black paper using an AxiDraw V3 and a white gel pen.">
            +          </a>
            +          <p class="description">Sine waves and lerps generated in p5.js, exported as SVG, and drawn with a plotter and pens.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5/lerp">lerp()</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/daein-chung.html">Chillin'</a></h3>
            +          <p class="credit">Dae In Chung</p>
            +          <a href="./featuring/daein-chung.html" class="no-arrow-link">
            +            <img src="../assets/img/showcase/daein-chung/daein-chung_chillin.png" 
            +              alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device. 
            +              At the top, there is a text input box to enter a message and download your own poster">
            +          </a>
            +          <p class="description">An interactive typographic poster that uses a mobile device's motion sensor with p5.js.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://brm.io/matter-js/">matter.js</a></li>
            +            <li><a class="tag" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">p5 WebGL</a></li>
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5.Camera">p5.Camera</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/casey-louise.html">p5.js Shaders</a></h3>
            +          <p class="credit">Casey Conchinha, Louise Lessél</p>
            +          <a href="./featuring/casey-louise.html" class="no-arrow-link">
            +            <img src="../assets/img/showcase/casey-louise/casey-louise_p5js-shaders.png" 
            +              alt="A screenshot of the Introduction page of the p5.js Shaders guide website">
            +          </a>
            +          <p class="description">A resource for learning the what, why, and how of using shaders in p5.js.</p>
            +          <ul class="project-tags">
            +         </ul>
            +        </div>
            +      </div>
            +
            +      <div class="right-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/phuong-ngo.html">Airi Flies</a></h3>
            +          <p class="credit">Phuong Ngo</p>
            +          <a href="./featuring/phuong-ngo.html" class="no-arrow-link">
            +            <img src="../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" 
            +              alt="A screenshot of the instructions and scoreboard for the online game Airi Flies">
            +          </a>
            +          <p class="description">In this game developed with p5.play, help Airi fly by saying PEW. Created to encourage people to get out of their comfort zone and feel more confident about themselves regardless of what they do and how they look or sound.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="http://molleindustria.github.io/p5.play/">p5.play</a></li>
            +            <li><a class="tag" href="https://ml5js.org/">ml5.js</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +          <h3 class="title"><a href="./featuring/qianqian-ye.html">Qtv</a></h3>
            +          <p class="credit">Qianqian Ye</p>
            +          <a href="./featuring/qianqian-ye.html" class="no-arrow-link">
            +            <img src="../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" 
            +              alt="A screenshot of a Qtv video (Guest Talk #1) featuring Chinese womxn designers and artists Kaikai and Cheng Xu">
            +          </a>
            +          <p class="description">A video channel with 1-minute videos in Mandarin about creative coding, art, and technology, including p5.js tutorials for beginners. Available on YouTube, Instagram, Bilibili, and TikTok.</p>
            +          <ul class="project-tags">
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/moon-xin.html">Moving Responsive Posters</a></h3>
            +          <p class="credit">Moon Jang, Xin Xin, and students</p>
            +          <a href="./featuring/moon-xin.html" class="no-arrow-link">
            +            <img src="../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png" 
            +              alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right">
            +          </a>
            +          <p class="description">Browser-based moving posters that use graphical systems, transformation methods, and p5.js to address the connotations of a word less than 8 letters. Designed by students for a graphic design course (Visual Narrative Systems) at the University of Georgia.</p>
            +          <ul class="project-tags">
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/rect">rect()</a></li>
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/translate">translate()</a></li>
            +          </ul>
            +        </div>
            +      </div>
            +    </section>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/teach/index.html b/dist/teach/index.html
            new file mode 100644
            index 0000000000..209b448d73
            --- /dev/null
            +++ b/dist/teach/index.html
            @@ -0,0 +1,856 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="en">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">teach | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">Skip to content</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">Language Settings</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="teach-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">Site Navigation</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/">Home</a></li>
            +        <li><a href="https://editor.p5js.org">Editor</a></li>
            +        <li><a href="/download/">Download</a></li>
            +        <li><a href="/download/support.html">Donate</a></li>
            +        <li><a href="/get-started/">Get Started</a></li>
            +        <li><a href="/reference/">Reference</a></li>
            +        <li><a href="/libraries/">Libraries</a></li>
            +        <li><a href="/learn/">Learn</a></li>
            +        <li><a href="/teach/">Teach</a></li>
            +        <li><a href="/examples/">Examples</a></li>
            +        <li><a href="/books/">Books</a></li>
            +        <li><a href="/community/">Community</a></li>
            +        <li><a href="https://showcase.p5js.org">Showcase</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">Forum</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            + <main id="content" class="column-span">
            +  	<section class= "teach-intro">
            +      <h1>Teach</h1>
            +
            +	      <p>Every teaching has its own unique goals, messages, conditions, and environments.By documenting and sharing p5 workshops, classes, and materials, we hope to better connect the p5.js learner and educator communities around the world.<a href="" onclick= "window.open('https://docs.google.com/forms/d/e/1FAIpQLSei8yHX2BROMnMQeZT_tsSXJOH13TPRG6CB4GVHH1oL1hzkZg/viewform?usp=sf_link', '_blank')">Share or recommend</a> your own teaching experiences, too!</p>
            +						
            +    </section>
            +
            +	<section>
            +
            +		<div id="resources"></div>
            +			<h2 class = "heading">p5 Teaching Resources</h2> 
            +			
            +			<div class="search-filter"><input type="checkbox"><label> Search Filter &#x2192;</label></div>
            +
            +     		<!-- search-results -->
            +
            +     		<div class="filter-panel">
            +
            +							
            +				<ul class="filters" id="filters">
            +
            +					<li><p class = "filter-title">&#x1F33A; Diversity & Inclusion : </p></li>
            +					<li><input type="checkbox" id="gender" value="gender"><label for="gender">Gender</label></li>
            +					<li><input type="checkbox" id="race-ethnicity" value="race-ethnicity"><label for="race-ethnicity">Race & Ethnicity</label></li>
            +					<li><input type="checkbox" id="language" value="language"><label for="language">Language</label></li>
            +					<li><input type="checkbox" id="neuro-type" value="neuro-type"><label for="neuro-type">Neuro-Type</label></li>
            +					<li><input type="checkbox" id="ability" value="ability"><label for="ability">Ability</label></li>
            +					<li><input type="checkbox" id="class" value="class"><label for="class">Class</label></li>
            +					<li><input type="checkbox" id="religion" value="religion"><label for="religion">Religion</label></li>
            +					<li><input type="checkbox" id="subculture" value="subculture"><label for="subculture">(Sub-)Culture</label></li>
            +					<li><input type="checkbox" id="political-opinion" value="political-opinion"><label for="political-opinion">Political Opinion</label></li>
            +					<li><input type="checkbox" id="age" value="age"><label for="age">Age</label></li>
            +					<li><input type="checkbox" id="skill-level" value="skill-level"><label for="skill-level">Skill Level</label></li>
            +					<li><input type="checkbox" id="occupation" value="occupation"><label for="occupation">Occupation</label></li>
            +					<li><input type="checkbox" id="noCodeSnobs" value="noCodeSnobs"><label for="noCodeSnobs">#noCodeSnobs</label></li>
            +					<li><input type="checkbox" id="newKidLove" value="newKidLove"><label for="newKidLove">#newKidLove</label></li>
            +					<li><input type="checkbox" id="unassumeCore" value="unassumeCore"><label for="unassumeCore">#unassumeCore</label></li>
            +					<li><input type="checkbox" id="BlackLivesMatter" value="BlackLivesMatter"><label for="BlackLivesMatter">#BlackLivesMatter</label></li>
            +							
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CD; Venue : </p></li>
            +
            +					<li><input type="checkbox" id="africa" value="africa"><label for="africa">Africa</label></li>
            +					<li><input type="checkbox" id="asia" value="asia"><label for="asia">Asia</label></li>
            +					<li><input type="checkbox" id="europe" value="europe"><label for="europe">Europe</label></li>
            +					<li><input type="checkbox" id="north-america" value="north-america"><label for="north-america">North America</label></li>
            +					<li><input type="checkbox" id="oceania" value="oceania"><label for="oceania">Oceania</label></li>
            +					<li><input type="checkbox" id="south-america" value="south-america"><label for="south-america">South America</label></li>
            +					<li><input type="checkbox" id="virtual-online" value="virtual-online"><label for="virtual-online">Virtual-Online  &#x1F310;</label></li>
            +
            +
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4C5; Year : </p></li>
            +					<li><input type="checkbox" id="2014" value="2014"><label for="2014">~2014</label></li>
            +					<li><input type="checkbox" id="2015" value="2015"><label for="2015">2015</label></li>
            +					<li><input type="checkbox" id="2016" value="2016"><label for="2016">2016</label></li>
            +					<li><input type="checkbox" id="2017" value="2017"><label for="2017">2017</label></li>
            +					<li><input type="checkbox" id="2018" value="2018"><label for="2018">2018</label></li>
            +					<li><input type="checkbox" id="2019" value="2019"><label for="2019">2019</label></li>
            +					<li><input type="checkbox" id="2020" value="2020"><label for="2020">2020</label></li>
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CA; Level of Difficulty : </p></li>
            +					<li><input type="checkbox" id="elementary" value="elementary"><label for="elementary">Elementary</label></li>
            +					<li><input type="checkbox" id="intermediate" value="intermediate"><label for="intermediate">Intermediate</label></li>
            +					<li><input type="checkbox" id="advanced" value="advanced"><label for="advanced">Advanced</label></li>
            +				 </ul>
            +
            +						  <br>
            +								
            +
            +			</div>
            +												
            +			<div class = "results-wrapper">
            +
            +						
            +				<div class="results" id="search-results">
            +					<ul>
            +				  		<li class="case-list" data-category="2019 europe gender race-ethnicity age skill-level BlackLivesMatter advanced"><a href="#case1" class="caseBtn" >"p5.js à l'Ubuntu Party!", Basile Pesin</a></li>
            +
            +				  		 <li class="case-list" data-category="2020 asia age skill-level occupation elementary advanced"><a href="#case2" class="caseBtn">"Making The Thing that Makes the Thing: Exploring Generative Art &#x0026; Design with p5.js", Priti Pandurangan &#x0026; Ajith Ranka</a></li>
            +
            +						  <li class="case-list" data-category="2016 2019 2020 elementary intermediate advanced north-america gender race-ethnicity language neuro-type ability subculture occupation north-america"><a href="#case3" class="caseBtn">CC Fest (Creative Coding Festival), Saber</a></li>
            +
            +						  <li class="case-list" data-category="2018 virtual-online south-america gender race-ethnicity language neuro-type religion subculture age noCodeSnobs newKidLove unassumeCore elementary intermediate advanced"><a href="#case4" class="caseBtn" >"Taller Introducci&#x00F3;n a la Programaci&#x00F3;n Creativa con p5.js", Aar&#x00F3;n Montoya-Moraga</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america gender race-ethnicity class subculture age skill-level elementary"><a href="#case5" class="caseBtn" >"Introduction to Generative Drawing", Adam Herst</a></li>
            +
            +						  <li class="case-list" data-category="2020 asia virtual-online gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation elementary"><a href="#case6" class="caseBtn" >Open Lecture "Creative Coding: 2020", Shunsuke Takawo</a></li>
            +
            +
            +						  <li class="case-list" data-category="2020 asia gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation intermediate"><a href="#case7" class="caseBtn" >"Creative Coding for Static Graphics", Shunsuke Takawo</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america virtual-online race-ethnicity language subculture skill-level"><a href="#case8" class="caseBtn" >"Generative Typography", Dae In Chung</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity language age skill-level occupation noCodeSnobs new unassumeCore BlackLivesMatter elementary intermediate"><a href="#case9" class="caseBtn" >"Machine Learning for the Web", Yining Shi</a></li>
            +
            +
            +						  <li class="case-list" data-category="europe virtual-online gender elementary"><a href="#case10" class="caseBtn" >"Introduction to p5.js and JavaScript", Nico Reski</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity skill-level occupation"><a href="#case11" class="caseBtn">"Digital Weaving &#x0026; Physical Computing Workshop Series", Qianqian Ye &#x0026; Evelyn Masso</a></li>
            +
            +						  <li class="case-list" data-category="2015 2020 north-america asia gender race-ethnicity language neuro-type ability class skill-level"><a href="#case12" class="caseBtn">"Signing Coders", Taeyoon Choi</a></li>
            +	    			</ul>
            +						<br>
            +				</div> 
            +			</div>
            +						
            +
            +						
            +
            +		<!--modal box section-->
            +		
            +			<!--modal boxes-->
            +
            +			<div id="caseModals" class="modal">
            +
            +				<!--modal box #1-->
            +
            +				  <div class="modal-content" id="case1"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>p5.js à l'Ubuntu Party!</span></li>
            +				        	<li class = "case"><p class="lead-name">Basile Pesin</p></li>
            +
            +				          	<li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date<p><a href="https://ubuntu-paris.org/">2020 Ubuntu Party </a>Cité des Sciences et de l'Industrie, Paris, France</p></li> 
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Any age, including children and parents, young and older adults.
            +				            </p></li>		         
            +
            +				            <li class = "clear"></li>  				
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To introduce a new public to programming through fun and compelling examples.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Method: in-person workshop, 1 hour per session, with different participant each times. The students were using (Ubuntu) machines with the p5.js web editor. I was teaching using a video projector as well as a board.</p><p>Materials: The exercises I gave where accessible through p5.js web-editor links available in<a href = "https://vertmo.github.io/ubuntu-party-p5/">GitHub</a>.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Age</label><label>Skill Level</label><label>#BlackLivesMatter</label>
            +				            </li>
            +		             
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				<!--modal box #2-->
            +	
            +				  <div class="modal-content" id="case2"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Making The Thing that Makes the Thing: Exploring Generative Art & Design with p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Priti Pandurangan & Ajith Ranka</p></li>
            +				        	
            +				        	<li class = "clear"></li>
            +             				<li class = "clear"></li>
            +             				<li class = "case"><img src="https://drive.google.com/uc?id=1udID-B1qADY7QxDkYkAh6ZYX7D8BfrnD" alt="A group of participants collaborating to create some designs using the p5.js web editor on their laptops."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date<p>&#x1F4CD; National Institute of Design, Bangalore</p><p>&#x1F4C5; 2020 February 8, 2:30-4:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Priti: Intermediate & Ajith: Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To explore generative art &#x0026; design and recreate some classical works with p5.js.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: In-person, collaborative, hands-on workshop.</p><p>Materials: <a href="https://musingswithcode.studio/generative-design-workshop">course page </a> linking to sketches on the p5 editor, <a href="https://musingswithcode.studio/generative-design-workshop/explainers">interactive reference guide </a>to p5 basics</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Skill Level</label><label>Occupation</label></li>			    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +				  <!--modal box #3-->
            +	
            +				  <div class="modal-content" id="case3"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>CC Fest (Creative Coding Festival)</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Saber</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Love p5.js. It has meant so much to me, my students, and this community."</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; New York, Los Angeles, San Francisco, Virtual-Online &#x1F310;</p><p>&#x1F4C5; Twice a year in NYC for four years; once a year in LA for three years; once a year in SF for two years; now virtual</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To build a teacher and student community around p5 for middle and high school.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>A half-day of workshop led by volunteer teachers. We saw lots of different methods and materials. Most used some sort of slides or documentation, some live coding using an editor, with work time for participant to remix.</p><p>&#x1F517; <a href="https://http://ccfest.rocks/lessons">CC Fest Lessons page</a> for teaching materials</p><p>&#x1F4F8; <a href="http://ccfest.rocks/pictures">More photos</a></li>
            +
            +              				<!--<li class = "case"><iframe src="http://ccfest.rocks/pictures" height= "200" alt="Pictures of CC Fest"></iframe></li>-->
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>(Sub-)Culture</label><label>Occupation</label></li>	
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #4-->
            +	
            +				  <div class="modal-content" id="case4"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Taller Introducción a la Programación Creativa con p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Aarón Montoya-Moraga</p></li>
            +
            +				        	<li class = "case"><p class = speech>"p5.js is my happy place &#x1F495; "</p></li>
            +
            +				        	<li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://miro.medium.com/max/1000/1*OIn_NKGuKyto9-_h6CAmmw.jpeg" alt="A group of 20 people sitting on a large shared table with their laptops looking at a projected screen."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD;  PlusCode Media Arts Festival, Buenos Aires, Argentina & Virtual-Online  &#x1F310;</p><p>&#x1F4C5; 2018 November 14, 3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>I had around 16 students in the workshop, and a team including 3 people from the PlusCode festival, and one person at the venue.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary, Intermediate, Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Introduction to beginners and artists of graphic web programming and open source, using p5.js, in Spanish :)</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>I used the material on this <a href="https://github.com/montoyamoraga/workshop-p5js-pluscode-2018">GitHub repo</a>, we used the p5.js web editor, we had a three hour long workshop</p><p>&#x1F517; <a href="https://medium.com/processing-foundation/code-electronic-art-festival-2018-argentina-803d3ca8092c">+CODE electronic art festival 2018, Argentina</a>, Medium</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Religion</label><label>(Sub-)Culture</label><label>Age</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label></li>
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				  <!--modal box #5-->
            +	
            +				  <div class="modal-content" id="case5"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to Generative Drawing</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Adam Herst</p></li>
            +
            +				        	<li class = "case"><p class = speech>"My greatest source of uncertainty in developing the workshop was whether it was trying to teach art to programmers or to teach programming to artists."</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; <a href="https://interaccess.org/studio">Inter/Access</a> (artist-run centre), Toronto, Ontario, Canada</p><p>In-person with a self-paced workbook for remote work</p><p>&#x1F4C5; 2020 February 12, 7PM-9PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>15 artists
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To introduce p5.js to artists with little or no programming experience and to suggest one way an analogue practice can migrate to a digital form.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD;Method & Materials</p><p>A printed workbook with activities that used the p5.js web editor to show how translate an physical drawing into a digital drawing.</p><p>&#x1F517;<a href="https://interaccess.org/event/2019/processing-community-day-generative-drawing">Processing Community Day 2019: Generative Drawing at Inter/Access</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Letter PDF</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Booklet PDF</a></p></li>		
            +
            +				    		<li class = "clear"></li>
            +				        	<li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Class</label><label>(Sub-)Culture</label><label>Age</label><label>Skill Level</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #6-->
            +	
            +				  <div class="modal-content" id="case6"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Open Lecture, Creative Coding: 2020</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I love p5.js because it's so easy to read and write code in p5.js. Coding in your everyday life!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				          	<li class = "clear"></li>	
            +				          	<li class = "case"><img src="https://lh3.googleusercontent.com/pw/ACtC-3eYswa6tJH5pvfvvAAfXQJO71ncsdgpwDBvbPAL-qcwnLkkpuoAVpggOb2-LYSLqo0Htd8cgnv5i8yLJg6Wh7J_rW2MMy6y8XZRznRByjj2mGJHf8XFmDI-8W6mH7urrEQC2tyUMF1HWaamLTNBqmIyeQ=w1560-h878-no?authuser=0" alt="A table on which there is a laptop, some sheets of papers, colorful pens and two automatic machines drawing something with a pen on a sheet."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Kyoto University of Art and Design, Kyoto, Japan & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2020 March 16-18, 1-7 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Students of Kyoto University of Art and Design, and anyone.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Making code as a tool for artistic expression.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/Day1-1-p5.js-i15dvmUETr4ef1xnydzru">Syllabus</a><p>&#x1F517; <a href="https://youtu.be/aS5CvADPdk0">Day 1</a>, <a href="https://youtu.be/ZCO-8CubifI">Day 2</a>, <a href="https://youtu.be/nbcckC5iwIcsyllabus">Day 3</a>, YouTube</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Religion</label><label>(Sub-)Culture</label><label>Political Opinion</label><label>Age</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #7-->
            +	
            +				  <div class="modal-content" id="case7"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Creative Coding for Static Graphics</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Coding in p5.js is a lot of fun. If you haven't started yet, I encourage you to give it a try!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://uc6d9323e0272069edcf30e9c501.previews.dropboxusercontent.com/p/thumb/AA5dvRUhxkQ9wLU6mHcrEmLvXnV7gbapPG2PvVf5K8K9ktlC59RCtvbSCP7YfEgPcFtnsgQekujWSD8iEfc6UT2pouzLdZUElblXhh9wg_b2UKDU-OO1u8VaiuC91g73tQX9S9mTHIgvm4h_Jw9-P4F6-iyjqBz57CvFWhilM5CpNbiPIjVRX6NsMkSYA3IexYreShT6Bt2hOWnorsocCsaafJiAd3cZbplWnGiuZmCn5R7BJ4u770YRjqX-AKh6AaoOb3kZHwBBnPQSU7zxiHqZbrWirjwLprw5D5UKW4bMI6We85Yn8cDPlJ6CktIqwpepAhdRi7scaxLxGnpIE4XjnoxK6T1jHkWZXGkvPplV1qlvrC7qz2jTY1_cULKcAcV8F-I-xvAL5I0n3rRHCZqr/p.jpeg?fv_content=true&size_mode=5" alt=""></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; FabCafe MTRL, Tokyo, Japan</p><p>&#x1F4C5; 2019 September 15, 4-7 PM </p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Anyone who wants to try coding in p5.js.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To code from the graphic design's perspective.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/--A6IUdC5pD_0QfbWt1PQ5u~PiAg-Fk8qxFWjaJWeH1cAc8FT0">Syllabus & Material</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Religion</label><label>(Sub-)Culture</label><label>Political Opinion</label><label>Age</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #8-->
            +	
            +				  <div class="modal-content" id="case8"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Generative Typography</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Dae In Chung</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://drive.google.com/uc?id=1TqcLurMLFioe8EcoJGtdK9_gs9bZ5odW" alt="A image with black background displaying the letter 'b' in 5 different styles along with a menu with various styling options to choose."></li>
            +
            +            	            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Baltimore, Maryland, USA & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2019 January 21 - May 08, every Wednesday, 4-10 PM</p></li>  
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>14 undergrads and grad students who had little to no experience in coding.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Experiment with typographic forms and structures through computation.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: online/offline lectures and critiques.</p><p>Materials: p5js online editor, Github, youtube tutorials.</p><p>&#x1F517; <a href="https://drive.google.com/drive/folders/15aFXijbqworOoLpc0fD283YOgi7UIHMA?usp=sharing">Works of participants</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Race & Ethnicity</label><label>Language</label><label>(Sub-)Culture</label><label>Skill Level</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +
            +				  <!--modal box #9-->
            +	
            +				  <div class="modal-content" id="case9"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Machine Learning for the Web</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Yining Shi</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://drive.google.com/uc?id=1pO3s4lraBwtLcZoCIeHGVncuwtzHqN6o" alt="A group of 16 people sitting around tables with their laptops, mobile phones and some other accessories, facing towards a large television screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; ITP, NYU, 370 Jay St, Brooklyn, NY 11201, USA</p><p>&#x1F4C5;2019 March 09 - October 12, every Tuesday, 6:30-9:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Students at Interactive Telecommunications Program, New York University. 16 people.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary, Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>The goal of this class is to learn and understand common machine learning techniques and apply them to generate creative outputs in the browser using ml5.js and p5.js.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>This class is a mix of lectures, coding sessions, group discussions, and presentations. I used<a href="https://github.com/yining1023/machine-learning-for-the-web">GitHub</a> to host class syllabus and all the coding materials, Google Slides for lectures and p5.js Web Editor for live coding sessions. Every week, there were one-on-one office hours to talk about any difficulties of coming up with an idea for the homework or any coding changes.</p><p>Methods: online/offline lectures and critiques.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Age</label><label>Skill Level</label><label>Occupation</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label><label>#BlackLivesMatter</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #10-->
            +	
            +				  <div class="modal-content" id="case10"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to p5.js and JavaScript</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Nico Reski</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date<p>&#x1F4CD; Currently available as self-study at own pace with accompanying slides, linked below.</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Beginner, Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Introduce learners (potentially with no coding experiences at all) to the very basics of p5.js (and JavaScript), in order to encourage creative coding and enable them to pursue own projects in a safe environment.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>p5.js source code (for the introductory project), JavaScript source code (illustrating some basic JavaScript functionalities), accompanying slides in .pdf format, all hosted publicly on GitHub.</p><p>&#x1F517; <a href="https://reski.nicoversity.com/ws_cc_p5js_introduction.html">Overview</a> of the workshop and its contents (including all links to the material hosted on GitHub) on my academic webpage.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #11-->
            +	
            +				  <div class="modal-content" id="case11"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Digital Weaving & Physical Computing Workshop Series</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Qianqian Ye & Evelyn Masso</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +				            <li class = "case"><img src="https://drive.google.com/uc?id=1QXtrew8S2YQ-_6R0H1FhwiEJj9_LLcpU" alt="This image is divided in two parts. The left part shows a group of 15 women sitting on chairs with their laptops and looking at a presentor who is explaining a code on a projected screen. The right part of the image shows a person learning weaving using a physical pattern and a weaving tool."></li>
            +
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Womens Center for Creative Work (WCCW), Los Angeles, CA, US</p><p>&#x1F4C5; 2019 October 19 - November 02, every Saturday 3-6 PM</p></li>  		
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>15 women and non-binary artists, designer, makers, programers. </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary
            +				            </p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Over the course of three workshops, we will draw and create patterns using p5.js, an open-source graphical library; we will learn and apply computational concepts to transform patterns and finally, we will bring a weaving to life with electronic microcontrollers.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: small team session</p><p>Materials: slides, p5.js web editor, pen and paper to draw pattern, physical pattern weaving tool.</p><p>&#x1F517; <a href="https://docs.google.com/presentation/d/1gJ67aKVGydSNoeUraS7U_QevcnOuxnSFQ_4640Qlifo/edit?usp=sharing">Workshop Slide #1</a>, <a href="https://docs.google.com/presentation/d/1nuje9-j_o5HbCoxXR_EJhAYmSEjTQOkAHmBsuKRlwwA/edit?usp=sharing">Workshop Slide #2</a></p><p>&#x1F517; <a href="https://womenscenterforcreativework.com/events/digital-weaving-physical-computing/">Workshop Information</a> on WCCW website.</p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +  				  <!--modal box #12-->
            +	
            +				  <div class="modal-content" id="case12"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Signing Coders</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Taeyoon Choi</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I'm working on a new series of coding class for Disabled students in South Korea. I'm researching about the pedagogy and translation. I plan to hold workshops in December 2020. The project is supported by the Open Society Foundation Human Rights Initiative and Korea Disability Arts & Culture Center."</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><img src="http://taeyoonchoi.com/wp-content/uploads/2016/04/day1-7852-768x512.jpg" alt="Two volunteers explaining concepts using a white board and a screen to a bunch of deaf and hard of hearing students, each student facing a computer screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD;  WRIC, New York City, USA & Seoul Museum of Art, Seoul, South Korea.</p><p>5 Sessions, each 2~3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Deaf and Hard of Hearing students age 10~50 who live in NYC.
            +				            </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To help Deaf and Hard of Hearing students learn about computer programming through playful exercises. To make ASL tutorial of basic coding concepts.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>We used p5.js Web editor and code examples on the website. We also used dice, playing cards and various paper tools to help students learn about coding concepts.</p><p>&#x1F517; <a href="http://taeyoonchoi.com/soft-care/signing-coders/">Syllabus & Material</a></p><p>&#x1F4F8; <a href="http://taeyoonchoi.com/soft-care/signing-coders/signing-coders-1/">More photos</a></p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Skill Level</label></li>
            +				         
            +
            +
            +				            </ul>
            +				        
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +			</div> <!--modal boxes end-->
            +
            +			
            +			
            +
            +	</section>
            +
            +
            +	<!--modal-->
            +
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">Credits</h2>
            +      <p>
            +        p5.js is currently led by <a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a> & <a href='http://www.outofambit.com/' target="_blank">evelyn masso</a> and was created by <a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>. p5.js is developed by a community of collaborators, with support from the <a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a> and <a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>Identity and graphic design by <a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>. <a href="/copyright.html">&copy; Info</a>.
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +<!--jquery script-->
            +
            +<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
            +<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
            +<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
            +
            +
            +<!--filter search-->
            +
            +
            +<script>
            +    $("#filters :checkbox").click(function() {
            +
            +       var re = new RegExp($("#filters :checkbox:checked").map(function() {
            +                              return this.value;
            +                           }).get().join("|") ); //.join("|")
            +       $(".case-list").each(function() {
            +          var $this = $(this);
            +          $this[re.source!="" && re.test($this.attr("data-category")) ? "fadeIn" : "hide"]();
            +       });
            +    });
            +</script>
            +
            +
            +<!--modal box-->
            +
            +
            +<script>
            +$(document).on('click','.caseBtn',function(){
            +	var openModal =  $(this).attr('href');
            +	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +	
            +	$('#caseModals').fadeIn();
            +	$(openModal).fadeIn();
            +  return false;
            +});
            +
            +$("body" ).on( "click",".close", function() {
            +  	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +});
            +
            +</script>
            +
            +<!--search accordion menu-->
            +
            +<script>
            +
            +
            +var acc = document.getElementsByClassName("search-filter");
            +var i;
            +
            +for (i = 0; i < acc.length; i++) {
            +  acc[i].addEventListener("click", function() {
            +    this.classList.toggle("active");
            +    var panel = this.nextElementSibling;
            +    if (panel.style.maxHeight) {
            +      panel.style.maxHeight = null;
            +    } else {
            +      panel.style.maxHeight = panel.scrollHeight + "px";
            +    } 
            +
            +  });
            +}
            +</script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/books/index.html b/dist/zh-Hans/books/index.html
            new file mode 100644
            index 0000000000..703ada0697
            --- /dev/null
            +++ b/dist/zh-Hans/books/index.html
            @@ -0,0 +1,303 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">books | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="books-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>书籍</h1>
            +      <br>
            +
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/gettingstarted.jpg" alt="book cover getting started with p5.js">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Getting Started with p5.js</h2>
            +
            +          <p>Lauren McCarthy, Casey Reas, and Ben Fry.  Illustrations by Taeyoon Choi.</p>
            +          <p>
            +            Published October 2015, Maker Media. 
            +            246 pages. 
            +            Paperback.
            +          </p>
            +
            +          <p>Written by the lead p5.js developer and the founders of Processing, this book provides an introduction to the creative possibilities of today's Web, using JavaScript and HTML.</p>
            +
            +          <p><a href="http://shop.oreilly.com/product/0636920032076.do" target="_blank">Order Print/Ebook from O'Reilly</a></p>
            +          <p><a href="http://www.amazon.com/Make-Interactive-Graphics-JavaScript-Processing/dp/1457186772" target="_blank">Order from Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/gettingstarted-es.jpg" alt="book cover Introducción a p5.js">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Introduction to p5.js (Spanish Edition)</h2>
            +
            +          <p>Lauren McCarthy, Casey Reas, and Ben Fry. Translated by Aarón Montoya-Moraga. Illustrations by Taeyoon Choi.</p>
            +          <p>
            +            Published 2018, Processing Foundation, Inc. 
            +            246 pages. 
            +            Soft cover.
            +          </p>
            +
            +          <p>Written by the lead p5.js developer and the founders of Processing, this book provides an introduction to the creative possibilities of today's Web, using JavaScript and HTML.</p>
            +
            +          <p><a href="https://processingfoundation.press/product/introduccion-a-p5-js/" target="_blank">Order the PDF from The Processing Foundation Press</a></p>
            +          <p><a href="https://www.amazon.com/Introducci%C3%B3n-p5-js-Spanish-Lauren-McCarthy/dp/0999881302/" target="_blank">Order the physical version from Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/generative_design.jpg" alt="book cover generative design">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Generative Design</h2>
            +
            +          <p>Benedikt Gross, Hartmut Bohnacker, Julia Laub and Claudius Lazzeroni.</p>
            +          <p>
            +            Published October 30, 2018, Princeton Architectural Press; Reprint edition. 
            +            255 pages. 
            +            Paperback.
            +          </p>
            +
            +          <p>By using simple languages such as JavaScript in p5.js, artists and makers can create everything from interactive typography and textiles to 3D-printed furniture to complex and elegant infographics.</p>
            +
            +          <p><a href="https://www.papress.com/html/product.details.dna?isbn=9781616897581" target="_blank">Order from Princeton Architectural Press</a></p>
            +          <p><a href="https://www.amazon.com/Generative-Design-Visualize-Program-JavaScript/dp/1616897589" target="_blank">Order from Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/generative_gestaltung.jpg" alt="book cover Generative Gestaltung">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Generative Gestaltung (German Edition)</h2>
            +
            +          <p>Benedikt Gross, Hartmut Bohnacker, Julia Laub and Claudius Lazzeroni.</p>
            +          <p>
            +            Published March 1, 2018, Schmidt Hermann Verlag. 
            +            256 pages. 
            +            Hardcover.
            +          </p>
            +
            +          <p>By using simple languages such as JavaScript in p5.js, artists and makers can create everything from interactive typography and textiles to 3D-printed furniture to complex and elegant infographics.</p>
            +
            +          <p><a href="https://typografie.de/produkt/generative-gestaltung-creative-coding-im-web/" target="_blank">Order from Verlag Hermann Schmidt</a></p>
            +          <p><a href="https://www.amazon.com/Generative-Gestaltung/dp/3874399028" target="_blank">Order from Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/learn_javascript.jpg" alt="book cover learn javascript">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Learn JavaScript with p5.js</h2>
            +
            +          <p>Engin Arslan.</p>
            +          <p>
            +            Published 2018, Apress. 
            +            217 pages. 
            +            Paperback.
            +          </p>
            +
            +          <p>Learn coding from scratch in a highly engaging and visual manner using the vastly popular JavaScript with the programming library p5.js. The skills you will acquire from this book are highly transferable to a myriad of industries and can be used towards building web applications, programmable robots, or generative art.</p>
            +
            +          <p><a href="https://www.apress.com/gp/book/9781484234259" target="_blank">Order from Apress</a></p>
            +          <p><a href="https://www.amazon.com/Learn-JavaScript-p5-js-Coding-Learners/dp/1484234251" target="_blank">Order from Amazon</a></p>
            +
            +        </div>
            +      </div>
            +
            +      <div style='clear:both; height: 2em'></div>
            +
            +      <div>
            +        <div class="narrow-left-column">
            +          <img src="../../assets/img/books/aesthetic-programming.jpg" alt="book cover learn javascript">
            +        </div>
            +
            +        <div class="wide-right-column book">
            +          <h2>Aesthetic Programming: A Handbook of Software Studies</h2>
            +
            +          <p>Winnie Soon, Geoff Cox. </p>
            +          <p>
            +            Published  2020, Open Humanities Press. 
            +            298 pages. 
            +            Hardcover.
            +          </p>
            +
            +          <p>Using p5.js, this book introduces and demonstrates the reflexive practice  of aesthetic programming, engaging with learning to program as a way to  understand and question existing technological objects and paradigms,  and to explore the  potential for reprogramming wider eco-socio-technical systems.</p>
            +
            +          <p><a href="http://openhumanitiespress.org/books/download/Soon-Cox_2020_Aesthetic-Programming.pdf" target="_blank">Download the PDF (FREE)</a></p>
            +          <p><a href="https://www.barnesandnoble.com/w/aesthetic-programming-winnie-soon/1138820949" target="_blank">Order from Barnes & Noble</a></p>
            +
            +        </div>
            +      </div>
            +      <br>
            +      <div style='clear:both; height: 2em'></div>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="books-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/community/contributors-conference-2015.html b/dist/zh-Hans/community/contributors-conference-2015.html
            new file mode 100644
            index 0000000000..4e34abb2f2
            --- /dev/null
            +++ b/dist/zh-Hans/community/contributors-conference-2015.html
            @@ -0,0 +1,287 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>贡献者会议 2015</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>5月25日至31日</h2>
            +
            +      <p>30个来自各种不同背景的参与者聚集在一起并花了一个星期在<a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a>提善 p5.js 编程环境的源代码、参考文献及社区外展工具。参与者来自香港、西雅图、洛杉矶、波士顿及纽约,多数都是在创意科技、互动设计及新媒体艺术的职业专家但另外也包括了数位来自 Carnegie Mellon’s Schools of Art and Architecture 的大学本科和研究生。
            +      </p>
            +      </div>
            +
            +      <img src="../../assets/img/community/2015_1.jpg" alt='来自不同背景的参与者微笑着并用他们的双手做一个代表 p5 的标志"'/>
            +      <img src="../../assets/img/community/2015_3.jpg" alt='一位女士使用她的手提电脑呈现 p5.js 社群宣言"'/>
            +      <img src="../../assets/img/community/2015_4.jpg" alt='一位女士有声有色的对着一个麦克风演说,同时两位男性合作者在旁观"'/>
            +      <img src="../../assets/img/community/2015_5.jpg" alt='参与者们专注地对着课室前方微笑"'/>
            +      <img src="../../assets/img/community/2015_6.jpg" alt='一位女士使用麦克风对着三位女性学生阅读关于 p5.js 的资料"'/>
            +      <img src="../../assets/img/community/2015_7.jpg" alt='参与者们围着一个贴了多个便利贴的白板而坐,同时一位女性学生对着一个麦克风进行演说"'/>
            +      <img src="../../assets/img/community/2015_8.jpg" alt='参与者们围着一张桌子坐着并看着对方的手提电脑,对比代码"'/>
            +      <img src="../../assets/img/community/2015_9.jpg" alt='贴着不同颜色便利贴的白板,便利贴上写着关于编程的笔记"'/>
            +      <img src="../../assets/img/community/2015_10.jpg" alt='一位女士对着麦克风演说着关于重视不同的技能,同时一群使用着手提电脑的参与者在一个课室内观看她的幻灯片"'/>
            +      <img src="../../assets/img/community/2015_11.jpg" alt='一位女士在一个讲堂内的讲台上演说,同时三位参与者坐在舞台上而另三位参与者使用视屏通话呈现在舞台幕布上"'/>
            +      <img src="../../assets/img/community/2015_12.jpg" alt='参与者在课室内使用他们的手提电脑工作的顶视图"'/>
            +      <img src="../../assets/img/community/2015_13.jpg" alt='五个人围着圈子进行讨论"'/>
            +      <img src="../../assets/img/community/2015_14.jpg" alt='五个人围着圈子并使用他们的手提电脑交换笔记"'/>
            +      <img src="../../assets/img/community/2015_15.jpg" alt='在课室内的一位男士使用麦克风对着一群参与者进行演说"'/>
            +      <img src="../../assets/img/community/2015_2.jpg" alt='参与者们在草坪上跳跃、微笑以及高举双手"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/80913365@N04/albums/72157653238862069/with/17613092994/" target="_blank">摄影师为 Taeyoon Choi</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>参与者</h2>
            +      <p>
            +        <a href='http://huah.net/jason/' target='_blank'>Jason Alderman</a>,
            +        <a href='http://sepans.com/' target='_blank'>Sepand Ansari</a>,
            +        <a href='http://tegabrain.com' target='_blank'>Tega Brain</a>,
            +        <a href='https://medium.com/@emchenNYC/' target='_blank'>Emily Chen</a>,
            +        <a href='http://andrescolubri.net/' target='_blank'>Andres Colubri</a>,
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>,
            +        <a href='http://guydebree.com/' target='_blank'>Guy de Bree</a>,
            +        <a href='http://www.cjdecarteret.com/' target='_blank'>Christine de Carteret</a>,
            +        <a href='http://xystudio.cc/' target='_blank'>Xy Feng</a>,
            +        <a href='http://www.sarahgp.com/' target='_blank'>Sarah Groff-Palermo</a>,
            +        <a href='http://www.crhallberg.com/' target='_blank'>Chris Hallberg</a>,
            +        <a href='http://valhead.com/' target='_blank'>Val Head</a>,
            +        <a href='http://johannahedva.com' target='_blank'>Johanna Hedva</a>,
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>,
            +        <a href='http://web.media.mit.edu/~jacobsj/' target='_blank'>Jennifer Jacobs</a>,
            +        <a href='http://www.epicjefferson.com/' target='_blank'>Epic Jefferson</a>,
            +        <a href='http://michellepartogi.com' target='_blank'>Michelle Partogi</a>,
            +        <a href='http://lav.io/' target='_blank'>Sam Lavigne</a>,
            +        <a href='http://flong.com' target='_blank'>Golan Levin</a>,
            +        <a href='http://www.liuchangitp.com/' target='_blank'>Cici Liu</a>,
            +        <a href='http://www.mayaman.cc/' target='_blank'>Maya Man</a>,
            +        <a href='http://lauren-mccarthy.com' target='_blank'>Lauren McCarthy</a>,
            +        <a href='http://www.workergnome.com/' target='_blank'>David Newbury</a>,
            +        <a href='http://molleindustria.org/' target='_blank'>Paolo Pedercini</a>,
            +        <a href='http://luisaph.com' target='_blank'>Luisa Pereira</a>,
            +        <a href='http://mileshiroo.info/' target='_blank'>Miles Peyton</a>,
            +        <a href='http://carolinerecord.com/' target='_blank'>Caroline Record</a>,
            +        <a href='http://b2renger.github.io/' target='_blank'>Berenger Recoules</a>,
            +        <a href='https://pibloginthesky.wordpress.com/' target='_blank'>Stephanie Pi</a>,
            +        <a href='http://jasonsigal.cc' target='_blank'>Jason Sigal</a>,
            +        <a href='http://studioindefinit.com/' target='_blank'>Kevin Siwoff</a>,
            +        <a href='http://charlottestiles.com/' target='_blank'>Charlotte Stiles</a>
            +      </p>
            +      </div>
            +
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>多元平等</h2>
            +        <p>在技术开发的同时,这次会议的另外一个主要焦点为推广、社群及多元平等。会议由一个小组会议开始—<a href="http://studioforcreativeinquiry.org/events/diversity-seven-voices-on-race-gender-ability-class-for-floss-and-the-internet" target="_blank">Diversity: Seven Voices on Race, Gender, Ability &amp; Class for FLOSS and the Internet</a>(多元平等:七个在种族、性别、能力及阶级的声音,给 FLOSS(免费与开源软件)及互联网)。举办者为 <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>
            +        及 <a  href="http://lauren-mccarthy.com" target="_blank">Lauren McCarthy</a>,该小组会议发生于2015年5月25日(星期二),地点在 Carnegie Mellon University 的 Kresge Auditorium。演说者包括 <a href="http://www.mayaman.cc/" target='_blank'>Maya Man</a>, <a href="http://reas.com/" target='_blank'>Casey
            +        Reas</a>, <a href="http://johannahedva.com/" target='_blank'>Johanna Hedva</a>, <a href="https://pibloginthesky.wordpress.com/" target='_blank'>Stephanie Pi</a>,
            +        <a href="http://phoenixperry.com/" target='_blank'>Phoenix Perry</a>, <a href="http://taeyoonchoi.com/" target='_blank'>Taeyoon Choi</a>,
            +        <a href="http://ablersite.org/" target='_blank'>Sara Hendren</a>, <a href="http://www.epicjefferson.com/" target='_blank'>Epic Jefferson</a>,
            +        及 <a href="http://chandlermcwilliams.com/" target='_blank'>Chandler McWilliams</a>。
            +        <img class="alignleft size-full wp-image-8423" src="http://studioforcreativeinquiry.org/wp-content/uploads/2015/05/diversity_640.jpg" alt="diversity_640"/>
            +        </p>
            +        <iframe src="https://player.vimeo.com/video/129140298?color=ffffff&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +        
            +        <table style="margin-top: 10px; background-color: #ffffff; border-collapse: collapse; border: 0px; width: 720px;">
            +        <tbody>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129151416?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Casey Reas</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129151418?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Johanna Hedva</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129160951?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Stephanie Pi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129163155?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Phoenix Perry</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129173628?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Taeyoon Choi</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129177689?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Sara Hendren</td>
            +        </tr>
            +        <tr>
            +        <td><iframe src="https://player.vimeo.com/video/129183825?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Epic Jefferson</td>
            +        <td></td>
            +        <td><iframe src="https://player.vimeo.com/video/129187909?color=ffffff&amp;title=0&amp;byline=0&amp;portrait=0" width="350" height="197" allowfullscreen="allowfullscreen"></iframe>Chandler McWilliams</td>
            +        </tr>
            +        </tbody>
            +        </table>
            +        <iframe src="https://player.vimeo.com/video/129192014?color=ffffff&amp;title=1&amp;byline=0&amp;portrait=0" width="720" height="405" allowfullscreen="allowfullscreen"></iframe>
            +      </div>
            +
            +
            +<!--       <div class="contributors-subsection">
            +      <h3>Documentation</h3>
            +      <p><a href='https://medium.com/@tchoi8/diversity-at-sfpc-d494d7390375' target=_blank>Diversity at SFPC
            +      (talk by Taeyoon Choi at “Diversity: Seven Voices on Race, Gender, Ability &amp; Class for FLOSS and
            +      the Internet”)</a></p>
            +      </div> -->
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>支持</h2>
            +
            +      <p>我们的贡献者会议地点位于 <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> 在 Carnegie Mellon University 内,并为一个给非典型、抗学科及跨学院研究的学术实验室,研究重点为艺术、科技及文化的交接。</p>
            +
            +      <p>这项活动资金来自于 <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      所提供的资助及来自以下赞助者的慷慨支持: <a href="https://tisch.nyu.edu/itp" target="_blank">NYU Interactive Telecommunications Program</a>
            +      (ITP), <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href="http://theartificial.nl/" target="_blank">TheArtificial</a>, <a href="http://bocoup.com/" target="_blank">Bocoup</a>, <a href="http://tinysubversions.com/" target="_blank">Darius Kazemi</a>, 及 <a href="http://www.du.edu/ahss/edp/" target="_blank">Emergent Digital Practices | University of Denver</a><br><b>谢谢!</b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../../assets/img/community/nea.jpg' alt=""></a></div>
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:18%' src='../../assets/img/community/studio.png' alt=""/></a>
            +      <a class='nounderline' href='http://itp.nyu.edu/itp/' target=_blank ><img style='width:18%' src='../../assets/img/community/itp.png' alt=""/></a>
            +      <a class='nounderline' href='http://www.du.edu/ahss/edp/' target=_blank ><img style='width:18%' src='../../assets/img/community/edp.png' alt=""/></a>
            +      <a class='nounderline' href='http://bocoup.com/' target=_blank ><img style='width:18%' src='../../assets/img/community/bocoup.png' alt=""/></a>
            +      <a class='nounderline' href='http://theartificial.nl/' target=_blank ><img style='width:18%' src='../../assets/img/community/theartificial.png' alt=""/></a>
            +
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/community/contributors-conference-2019.html b/dist/zh-Hans/community/contributors-conference-2019.html
            new file mode 100644
            index 0000000000..c3e4355d42
            --- /dev/null
            +++ b/dist/zh-Hans/community/contributors-conference-2019.html
            @@ -0,0 +1,308 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>贡献者会议 2019</h1>
            +
            +
            +      <div class="contributors-subsection">
            +      <h2>Frank-Ratchye STUDIO for Creative Inquiry<br>Carnegie Mellon University<br>8月13日至18日</h2>
            +
            +      <p>一群35位来自不同身份背景的参与者聚集在 <a href='http://studioforcreativeinquiry.org' target=_blank >Frank-Ratchye
            +      STUDIO for Creative Inquiry</a> 以进展源代码、参考文献及社群扩展工具并同时探索现时 p5.js 编程环境的状况。这次的会议专注于通过多学科的角度促进对话,并包括了来自各种不同身份背景的参与者所代表,其中有来自创意科技、互动设计及新媒体艺术的参与者。参与者被分成多个工作小组,其主题为:辅助、表演内的音乐及代码、创意科技景观及国际化。
            +      </p>
            +      </div>
            +      
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/YkfG7Ggpi_o" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <div class="videoWrapper">
            +        <iframe src="https://www.youtube.com/embed/At1newHnZpA" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
            +      </div>
            +
            +      <p><a href="https://www.youtube.com/channel/UCzMs9qg50AW2LEpLDzHT5NA" target="_blank">视屏由 Qianqian Ye 所制作</a></p><br>
            +
            +      <img src="../../assets/img/community/2019_1.jpg" alt='一位男士在大学讲台上向满座的课堂作演讲"'/>
            +      <img src="../../assets/img/community/2019_2.jpg" alt='参与者们围着长桌一边吃午餐一边进行讨论"'/>
            +      <img src="../../assets/img/community/2019_4.jpg" alt='课室内的参与者们在他们的手提电脑上工作"'/>
            +      <img src="../../assets/img/community/2019_5.jpg" alt='参与者们在一个阴暗的课室内开会"'/>
            +      <img src="../../assets/img/community/2019_6.jpg" alt='一位女士对着课室内来自不同背景的参与者们演讲"'/>
            +      <img src="../../assets/img/community/2019_7.jpg" alt='参与者们在一个忙碌的课室内交谈"'/>
            +      <img src="../../assets/img/community/2019_8.jpg" alt='一位女士使用麦克风对着课室内的参与者们演讲"'/>
            +      <img src="../../assets/img/community/2019_9.jpg" alt='一位参与者坐在满是关于匿名数据问题的文字投影前,在讲台上演讲"'/>
            +      <img src="../../assets/img/community/2019_10.jpg" alt='一位拿着麦克风的参与者坐在关于 p5.js 除了能增加易接近性之外的功能不会再添正新功能的文字前,对着其他参与者演讲"'/>
            +      <img src="../../assets/img/community/2019_11.jpg" alt='一位女士使用麦克风对着其他参与者们演讲"'/>
            +      <img src="../../assets/img/community/2019_12.jpg" alt='一位男士使用麦克风对着其他参与者们演讲"'/>
            +      <img src="../../assets/img/community/2019_13.jpg" alt='参与者们坐在课室内专注地在聆听演说"'/>
            +      <img src="../../assets/img/community/2019_15.jpg" alt='一位女士使用麦克风背对着 “sacred boundaries” 文字,对着其他参与者们演讲"'/>
            +      <img src="../../assets/img/community/2019_16.jpg" alt='俯视参与者们聆听着坐在一个 3D 渲染的人模型前的小组讲坛"'/>
            +      <img src="../../assets/img/community/2019_17.jpg" alt='参与者们围着桌子坐着并在查看一个荧幕上的代码"'/>
            +      <img src="../../assets/img/community/2019_18.jpg" alt='坐在真人大小的泰迪熊旁边的一位女士在她的手提电脑上工作"'/>
            +      <img src="../../assets/img/community/2019_19.jpg" alt='站在户外的参与者们微笑着"'/>
            +      <img src="../../assets/img/community/2019_20.jpg" alt='四位参与者围成一个圈子交谈"'/>
            +      <img src="../../assets/img/community/2019_21.jpg" alt='参与者们坐在户外一起享用午餐"'/>
            +      <img src="../../assets/img/community/2019_22.jpg" alt='参与者们围着一个 U 形的桌子坐着并对着课室的前方"'/>
            +      <img src="../../assets/img/community/2019_23.jpg" alt='一位男士坐在课室的前方使用麦克风有声有色地进行演讲"'/>
            +      <img src="../../assets/img/community/campfire.jpg" alt='一群人围着由四个 LCD 萤幕组成的营火坐着"'/>
            +      <img src="../../assets/img/community/2019_24.jpg" alt='参与者们微笑着并举着双手的团体照"'/>
            +
            +      <p><a href="https://www.flickr.com/photos/creativeinquiry/albums/72157710545834046/" target="_blank">摄影师为 Jacquelyn Johnson</a></p>
            +
            +      <div class="contributors-subsection">
            +      <h2>参与者</h2>
            +      <p>
            +        <a href='https://americanartist.us/biocv' target='_blank'>American Artist</a>, 
            +        <a href='https://www.omayeli.com/' target='_blank'>Omayeli Arenyeka</a>, 
            +        <a href='http://www.sinabahram.com/' target='_blank'>Sina Bahram</a>, 
            +        <a href='https://aatishb.com/' target='_blank'>Aatish Bhatia</a>, 
            +        <a href='https://natalie.computer/' target='_blank'>Natalie Braginsky</a>, 
            +        <a href='https://jonchambers.net/' target='_blank'>Jon Chambers</a>, 
            +        <a href='https://twitter.com/lucapodular' target='_blank'>Luca Damasco</a>, 
            +        <a href='https://www.linkedin.com/in/aren-davey-bb3496103/' target='_blank'>Aren Davey</a>, 
            +        <a href='https://teddavis.org/' target='_blank'>Ted Davis</a>, 
            +        <a href='http://l05.is/' target='_blank'>Carlos Garcia</a>, 
            +        <a href='http://stalgiagrigg.name/' target='_blank'>Stalgia Grigg</a>, 
            +        <a href='http://www.katehollenbach.com/' target='_blank'>Kate Hollenbach</a>, 
            +        <a href='http://www.shawnemichaelainholloway.com/' target='_blank'>shawné michaelain holloway</a>, 
            +        <a href='http://www.takinglifeseriously.com/index.html' target='_blank'>Claire Kearney-Volpe</a>, 
            +        <a href='https://www.sonalee.me/' target='_blank'>Sona Lee</a>, 
            +        <a href='https://designerken.be/designing' target='_blank'>Kenneth Lim</a>, 
            +        <a href='https://www.outofambit.com/' target='_blank'>Evelyn Masso</a>, 
            +        <a href='http://lauren-mccarthy.com/' target='_blank'>Lauren McCarthy</a>, 
            +        <a href='https://laja.me/' target='_blank'>LaJuné McMillian</a>, 
            +        <a href='https://www.decontextualize.com/' target='_blank'>Allison Parrish</a>, 
            +        <a href='http://www.luisapereira.net/' target='_blank'>Luisa Pereira</a>, 
            +        <a href='https://guillemontecinos.cl/' target='_blank'>Guillermo Montecinos</a>, 
            +        <a href='http://montoyamoraga.io/' target='_blank'>Aarón Montoya-Moraga</a>,
            +        <a href='http://lm-m.com/' target='_blank'>Luis Morales-Navarro</a>, 
            +        Shefali Nayak, 
            +        <a href='http://everest-pipkin.com/' target='_blank'>Everest Pipkin</a>, 
            +        <a href='http://oross.net/' target='_blank'>Olivia Ross</a>, 
            +        <a href='https://dorothysantos.com/' target='_blank'>Dorothy R. Santos</a>, 
            +        <a href='https://www.yashengshe.com/' target='_blank'>Yasheng She</a>, 
            +        <a href='https://junshern.github.io/' target='_blank'>Jun Shern Chan</a>, 
            +        <a href='https://cassietarakajian.com/' target='_blank'>Cassie Tarakajian</a>, 
            +        <a href='https://www.laurenvalley.com/' target='_blank'>Lauren Valley</a>, 
            +        <a href='https://xin-xin.info' target='_blank'>Xin Xin</a>, 
            +        <a href='https://ayxx.me/' target='_blank'>Alex Yixuan Xu</a>, 
            +        <a href='http://www.qianqian-ye.com/' target='_blank'>Qianqian Ye</a>
            +      </p>
            +      </div>
            +
            +
            +      <div class="outputs-subsection">
            +      <h2 id='outputs'>成果</h2>
            +      <ul aria-labelledby='outputs' class='list_view bullets'>
            +        <!-- arts -->
            +        <li>一个由 American Artist 带领的小组,主题为 Blackness and Gender in Virtual Space,同时参与者有 shawné michaelain holloway 及 LaJuné McMillian。</li>
            +        <li>Stalgia Grigg、LaJuné McMillian、Aatish Bhatia 及 Jon Chambers 所制作的新艺术装置。</li>
            +        <!-- landscape -->
            +        <li>一个 <a href="https://github.com/aparrish/nb5js-proof-of-concept" target="_blank"> p5.js 笔记界面</a> 的样板。作者为 Allison Parrish。</li>
            +        <li>p5 编辑器的 p5.js 附加程式库系统设计。作者为 Cassie Tarakajian 及 Luca Damasco。</li>
            +        <li>连接 p5 及其他程式库的原型。作者为 Alex Yixuan Xu 及 Lauren Valley。</li>
            +
            +        <!-- global -->
            +        <li><a href="https://docs.google.com/document/d/1NPSVTWlTxWv8_rWLr8j91Qf8CcJA5ns8I8zFjCCmwuk/edit#heading=h.ea0uhs87h6fk" target="_blank">p5.js 全球贡献者工具包。</a> 作者为 Aarón Montoya-Moraga、Kenneth Lim、Guillermo Montecinos、Qianqian Ye、Dorothy R. Santos 及 Yasheng She.</li>
            +
            +        <!-- access -->
            +        <li><a href="https://docs.google.com/presentation/d/19xxc2zWWdFMAQjT6tRdN5ZU13vAKSwM7jojaC2U4F6Q/edit" target="_blank">如何编写非暴力创意代码。</a>一个由 Olivia Ross 所带领的小型杂志。</li>
            +        <li>p5.js 网站的整修以加强其可用性。其包括了屏幕阅读其可用性的进展以及改善主页、下载、入门及参考文献页面。贡献者包括 Claire Kearney-Volpe、Sina Bahram、Kate Hollenbach、Olivia Ross、Luis Morales-Navarro、Lauren McCarthy 及 Evelyn Masso。</li>
            +
            +        <!-- music performance -->
            +        <li><a href="https://github.com/aahdee/p5grid">p5grid</a>。一个高度灵活的三角形、正方形、六边形及八边形格框 p5.js 附加程式库。作者为 Aren Davey。</li>
            +        <li><a href="https://github.com/L05/p5.multiplayer">p5.multiplayer</a>。一系列用于制作多设备、多人游戏的模版文件,多个客户端可同时连接至同一个服侍页面作者为 L05。</li>
            +        <li>使用  <a href="https://teddavis.org/p5live/">P5LIVE</a> 制作的实验,用于测试 softCompile、OSC 界面功能并在 MIDI 设置演示加入了连接性功能。这是个 p5.js 合作性实时编码视屏骑师环境!作者为 Ted Davis。</li>
            +        <li>由 Luisa Pereira、Jun Shern Chan、Shefali Nayak、Sona Lee、Ted Davis 及 Carlos Garcia 所带来的合作性表演。</li>
            +        <li>由 Natalie Braginsky 所带来的表演。</li>
            +  
            +        <!-- workshops -->
            +        <li>由 Everest Pipkin 及 Jon Chambers 带领的研讨会。</li>
            +
            +        <!-- closing -->
            +        <li>由 Golan Levin 带领的闭幕营火会。</li>
            +        
            +      </ul>
            +      </div>
            +
            +      <div class="contributors-subsection">
            +      <h2>支持</h2>
            +
            +      <p>我们的贡献者会议地点位于 <a href='http://studioforcreativeinquiry.org'>Frank-Ratchye STUDIO for Creative Inquiry</a> 在 Carnegie Mellon University 内,并为一个给非典型、抗学科及跨学院研究的学术实验室,研究重点为艺术、科技及文化的交接。</p>
            +
            +      <p>这项活动资金来自于 <a href="http://arts.gov/" target="_blank">National Endowment for the Arts</a>,
            +      所提供的资助及来自以下赞助者的慷慨支持: <a href='http://foundation.processing.org' target=_blank>Processing Foundation</a>, <a href='https://www.mozilla.org/en-US/moss/' target=_blank>Mozilla Foundation</a>, <a href='https://www.du.edu/ahss/opensourcearts/' target=_blank>Clinic for Open Source Arts (COSA) at the University of Denver</a>, <a href='http://idm.engineering.nyu.edu/' target=_blank>NYU Tandon IDM</a>, <a href='https://tisch.nyu.edu/itp' target=_blank> NYU ITP</a>, <a href='http://thebaselschoolofdesign.ch/' target=_blank>FHNW Academy of Art and Design</a>, <a href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank>DePaul University College of Computing and Digital Media</a>, 及 <a href='http://amt.parsons.edu/' target=_blank>Parsons School of Art, Media, and Technology at the New School</a>.
            +      <br><b>谢谢!</b></p>
            +
            +      <div style='width:100%; position: relative; text-align:center'><a class='nounderline' href='http://arts.gov/' target=_blank ><img style='width:38%; padding-bottom:20px' src='../../assets/img/community/nea.jpg' alt=""></a></div>
            +      
            +      <a class='nounderline' href='http://studioforcreativeinquiry.org' target=_blank ><img style='width:20%' src='../../assets/img/community/studio.png' alt=""/></a>
            +      
            +      <a class='nounderline' href='http://thebaselschoolofdesign.ch/' target=_blank ><img style='width:70%' src='../../assets/img/community/HGK.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://foundation.processing.org' target=_blank ><img style='width:14%' src='../../assets/img/community/processing-foundation.png' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='https://www.du.edu/ahss/opensourcearts/' target=_blank ><img style='width:22%' src='../../assets/img/community/COSA.png' alt=""/></a>
            +
            +      <a class='nounderline' href='http://idm.engineering.nyu.edu/' target=_blank ><img style='width:50%' src='../../assets/img/community/IDM.jpg' alt=""/></a>
            +
            +
            +      <a class='nounderline' href='http://amt.parsons.edu/' target=_blank ><img style='width:22%' src='../../assets/img/community/Parsons.jpg' alt=""/></a>
            +
            +      <a class='nounderline' href='https://tisch.nyu.edu/itp' target=_blank ><img style='width:14%' src='../../assets/img/community/itp.png' alt=""/></a>
            +
            +      <a class='nounderline' href='https://www.cdm.depaul.edu/Pages/default.aspx' target=_blank ><img style='width:50%' src='../../assets/img/community/depaul.png' alt=""/></a>
            +
            +      
            +      <p class="clearfix"> &nbsp;</p>
            +      </div>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/community/developer-docs.html b/dist/zh-Hans/community/developer-docs.html
            new file mode 100644
            index 0000000000..596e05593b
            --- /dev/null
            +++ b/dist/zh-Hans/community/developer-docs.html
            @@ -0,0 +1,142 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<link rel="stylesheet" href="https://unpkg.com/docsify/lib/themes/buble.css">
            +
            +<div id="community-page">
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <div id="app"></div>
            +      <script>
            +        window.$docsify = {
            +          auto2top: true,
            +          executeScript: true,
            +          loadSidebar: 'sidebar.md',
            +          autoHeader: true,
            +          loadNavbar: 'navbar.md',
            +          mergeNavbar: true,
            +          subMaxLevel: 2,
            +          themeColor: '#ed225d',
            +          basePath:
            +          'https://raw.githubusercontent.com/processing/p5.js/master/contributor_docs/',
            +          logo: '../assets/img/p5js.svg',
            +          name: 'p5.js Developer Docs',
            +          repo: 'https://github.com/processing/p5.js',
            +        }
            +      </script>
            +      <script src="https://unpkg.com/docsify/lib/docsify.min.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/community/index.html b/dist/zh-Hans/community/index.html
            new file mode 100644
            index 0000000000..9e6bf55938
            --- /dev/null
            +++ b/dist/zh-Hans/community/index.html
            @@ -0,0 +1,235 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">community | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="community-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content">
            +      <h1>社群</h1>
            +      <div class="community-statement">
            +        <h2 class="community-title">p5.js 社群宣言 </h2>
            +        <p>p5.js 是个对探索使用科技创作艺术及设计感兴趣的社群。
            +        </p>
            +
            +        <p>我们声援及支持所有人,不论他们来自不同性别认同、性取向、种族、国籍、语言、神经型、大小、能力、阶级、宗教、文化、次文化、政治观点、年龄、技能等级、职业或背景。我们了解并不是所有人都有多余的时间、金钱或能力以活跃的参与社群活动但我们同时认可及鼓励各种参与方式。我们致力于促进障碍消除及培养能力。我们都是学习者。
            +        </p>
            +
            +        <p>我们喜欢以下井号标签:#noCodeSnobs(因为我们重视社群多过效率)、#newKidLove(因为我们都曾经刚起步)、#unassumeCore(因为我们不假设预有知识)及 #BlackLivesMatter(因为当然)。
            +        </p>
            +
            +        <h3 id="in-practice">实践:</h3>
            +        <ul aria-labelledby="in-practice" class="bullets list_view">
            +          <li>我们不假设预有知识也不隐射有些东西是所有人都应该知道的。 </li>
            +          <li>我们坚持积极的回应反馈请求,不论它们有多复杂。 </li>
            +          <li>我们欢迎新人并且优先考虑其他人的学习。我们致力于将如新人的热情带入我们的工作,因为我们相信新人和专家对我们来说都一样重要。 </li>
            +          <li>我们积极的承认及验证各种不同的贡献。 </li>
            +          <li>我们永远都愿意给予帮助或指导。 </li>
            +        </ul>
            +
            +        <h3 id="in-conflict">在起冲突时:</h3>
            +        <ul aria-labelledby="in-conflict" class="bullets list_view">
            +          <li>我们聆听。</li>
            +          <li>我们清楚地表达自己同时理解其他人的感受。</li>
            +          <li>如果错在我们,我们承认错误、道歉及为我们的举止负责任。</li>
            +          <li>我们会一直寻求方法以改善我们自己及我们的社群。</li>
            +          <li>我们致力于在我们的社群内保持尊敬及开放性。 </li>
            +          <li>我们让所有人都感到他们的意见都有被聆听。</li>
            +          <li>在我们的互动中,我们保持细心及友善。</li>
            +        </ul>
            +
            +        <h3 id="in-future">在未来:</h3>
            +        <ul aria-labelledby="in-future" class="bullets list_view">
            +          <li>未来就是现在。</li>
            +        </ul>
            +        <br>
            +        <h3 id="notes" class='sr-only'>Notes</h3>
            +        <p>Please also see our  <a href="https://github.com/processing/p5.js/blob/main/CODE_OF_CONDUCT.md#p5js-code-of-conduct">p5.js Code of Conduct</a>。此宣言可根据 <a href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons license</a> 条款下使用。请随意分享及更改并注明出处。</p>
            +      </div>
            +
            +      <h2 id="contribute">贡献</h2>
            +      <p>我们的社群都会一直需要各种不同的帮助。</p>
            +
            +      <p><b>开发。</b> <a href="https://github.com/processing/p5.js" target="blank_">GitHub</a>是源代码被储存、议题被记录及关于代码的谈论发生的主要地方。请参考 <a href="https://p5js.org/contributor-docs" target="blank_">开发教程 </a> 以开始开发代码或 <a href="../libraries/#create-your-own"> 制作您的附加程式库。 </a></p>
            +
            +      <p><b>文献。</b>所有人都喜欢参考文献。我们需要帮助<a href="https://github.com/processing/p5.js-website/blob/main/contributor_docs/Adding_examples.md" target="blank_">移植范例</a>、<a href="https://p5js.org/contributor-docs/#/inline_documentation" target="blank_">添加参考文献</a>及制作教程。</p>
            +
            +      <p><b>教学。</b>教导研讨会、课程、朋友或合作者!在 Twitter 上标记 @p5xjs,我们将尽所能分享您的成果。</p>
            +
            +      <p><b>制作。</b>p5.js 在寻找设计师、艺术家、代码编程师等以将您具创意及惊人的作业展示在主页上,同时您的作业也能启发其他人。请将您的作业呈交至<a href="mailto:hello@p5js.org">hello@p5js.org</a>。</p>
            +
            +      <p><b>捐献。</b>p5.js 是个免费且开源的软件,由一群艺术家所制作。您可捐赠给<a href="https://processingfoundation.org/support">Processing Foundation</a>以帮助支持 p5.js 的开发工作。</p>
            +
            +
            +      <h2>p5.js 贡献者会议</h2>
            +      <p>虽然我们大多数的工作都在网上进行,我们仍然会在现实中聚集。我们已在<a href="http://studioforcreativeinquiry.org">Frank-Ratchye STUDIO for Creative Inquiry</a>  Pittsburgh, PA 的 Carnegie Mellon University 举办了两次贡献者会议。这会议聚集了多位艺术家、设计师、软件开发员及教育家以推进 p5.js 的发展。
            +      </p>
            +      <h2 id="conferences" class="sr-only">Past Conferences</h2>
            +      <ul aria-labelledby="conferences" class="list_view bullets">
            +        <li><a href="contributors-conference-2019.html">贡献者会议 2019</a></li>
            +        <li><a href="contributors-conference-2015.html">贡献者会议 2015</a></li>
            +      </ul>
            +
            +      <img src="../../assets/img/community/2015_12.jpg" alt='参与者在课室内使用他们的手提电脑工作的顶视图"'/>
            +
            +      <h2>邮件列表</h2>
            +      <div class="email-octopus-form-wrapper">
            +        <p class="email-octopus-success-message"></p>
            +        <p class="email-octopus-error-message"></p>
            +        <form method="post" action="https://emailoctopus.com/lists/537b6ec8-d123-11e6-8561-06ead731d453/members/external-add" class="email-octopus-form">
            +          <p>请输入您的电子邮件地址以接收偶尔来自 Processing Foundation 的更新消息。</p>
            +          <div class="email-octopus-form-row">
            +            <input type="email" name="emailAddress" placeholder="email" class="email-octopus-email-address">
            +            <button type="submit">subscribe</button>
            +          </div>
            +          <div class="email-octopus-form-row-hp" aria-hidden="true">
            +            <input type="text" name="hp537b6ec8-d123-11e6-8561-06ead731d453" tabindex="-1">
            +          </div>
            +          <div class="email-octopus-form-row-subscribe">
            +            <input type="hidden" name="successRedirectUrl" class="email-octopus-success-redirect-url" value="">
            +          </div>
            +        </form>
            +      </div>
            +      <script src="https://emailoctopus.com/bundles/emailoctopuslist/js/formEmbed.js"></script>
            +      <br><br>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/copyright.html b/dist/zh-Hans/copyright.html
            new file mode 100644
            index 0000000000..3abf183f0c
            --- /dev/null
            +++ b/dist/zh-Hans/copyright.html
            @@ -0,0 +1,155 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">copyright | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>版权信息</h1>
            +      <p>p5.js 编程库是个免费开源的软件;您可以在 Free Software Foundation 的<a href="https://github.com/processing/p5.js/blob/main/license.txt">GNU Lesser General 
            +      Public License</a> 2.1版条款下分布及/或修改该软件。</p>
            +      <p>参考文献是在<a href='http://creativecommons.org/licenses/by-nc-sa/4.0/'>Creative Commons</a>许可下允许任何人重用该文献只要该用处为非商业化及原作者有被归功。</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/download/index.html b/dist/zh-Hans/download/index.html
            new file mode 100644
            index 0000000000..4c61ac7e8f
            --- /dev/null
            +++ b/dist/zh-Hans/download/index.html
            @@ -0,0 +1,273 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>下载</h1>
            +
            +      <h2 class='sr-only'>Introduction</h2>
            +      <p>欢迎!虽然此页面的标题为“下载”,此页面其实包括了一系列可以用来下载程式库或在网上开始使用程式库的链接。我们在这里尝试将初学者最可能需要的链接摆在第一位,而较有经验的使用者能在此页面下方找到其他有用的链接。</p>
            +
            +      <!-- EDITOR -->
            +      <div class="link_group">
            +        <h2>编辑器</h2>
            +        <p>此链接将开启 p5.js 编辑器网页已让您能直接开始使用 p5.js。</p>
            +
            +        <a class='support_link' href="https://editor.p5js.org" target="_blank">
            +          <div class="download_box">
            +
            +            <span class="download_name">p5.js 编辑器</span>
            +            <p>使用 p5.js Editor 开始编写程式,不需要任何另外的设置!</p>
            +
            +          </div>
            +        </a>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- COMPLETE LIBRARY -->
            +      <div class="link_group">
            +        <h2>完整程式库</h2>
            +        <p>这是个包含 p5.js 程式库、p5.sound 附加程式库及范例项目的下载文件。它并不包含编辑器。请参考 <a href="/zh-Hans/get-started/">入门</a>以了解如何设置一个 p5.js 项目。</p>
            +
            +        <a  class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.zip">
            +          <div class="download_box">
            +
            +            <span class="download_name">p5.js 完整版</span>
            +            <p>包含
            +              <br>p5.js、p5.sound.js 及空白范例
            +            <br>版本 <span id="p5_version"></span> (<span id="p5_date"></span>)
            +            </p>
            +
            +          </div>
            +        </a>
            +        <div class="spacer"></div>
            +      </div>
            +
            +      <!-- SINGLE FILES -->
            +      <div class="link_group">
            +
            +        <h2 id="single-files">单一文件</h2>
            +        <p>这些是 p5.js 程式库文件的下载网址或网上链接。它们并不包括任何其他文件。</p>
            +        <ul aria-labelledby="single-files">
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.js</span>
            +                <p>单一文件:
            +                  <br>易读版本</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://github.com/processing/p5.js/releases/download/v[p5_version]/p5.min.js">
            +              <div class="download_box half_box">
            +                <span class="download_name">p5.min.js</span>
            +                <p>单一文件:
            +                  <br>极简化版本</p>
            +              </div>
            +            </a>
            +          </li>
            +
            +          <li>
            +            <a class='support_link p5_link' href="https://cdnjs.com/libraries/p5.js" target="_blank">
            +              <div class="download_box half_box last_box">
            +                <span class="download_name">CDN</span>
            +                <p>链接:
            +                  <br>静态链接文件</p>
            +              </div>
            +            </a>
            +          </li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +
            +      </div>
            +
            +      <!-- Github resources -->
            +      <div class="link_group">
            +        <h2 id="etc">Github 资源</h2>
            +        <ul aria-labelledby="etc" id='etc_list' class="list_view bullets">
            +          <li><a href="https://github.com/processing/p5.js/releases">旧版本/更新日志</a></li>
            +          <li><a href="https://github.com/processing/p5.js">程式代码库(GitHub)</a></li>
            +          <li><a href="https://github.com/processing/p5.js/issues">报告问题、缺陷及错误</a></li>
            +          <li><a href="https://github.com/processing/p5.js/blob/main/contributor_docs/supported_browsers.md">浏览器支持</a></li>
            +        </ul>
            +
            +        <div class="spacer"></div>
            +      </div>
            +
            +    </main>
            +
            +    <script>
            +      $.getJSON('/download/version.json', function(data) {
            +        $('#p5_version').text(data.version);
            +        $('#p5_date').text(data.date);
            +        $('.p5_link').each(function() {
            +          var link = $(this).attr('href').replace('[p5_version]', data.version);
            +          $(this).attr('href', link);
            +        });
            +        $('.editor_version').text(data.editor_version);
            +        $('.editor_link').each(function() {
            +          var link = $(this).attr('href').replace('[editor_version]', data.editor_version);
            +          $(this).attr('href', link);
            +        });
            +      });
            +      $('.support_link').on('click', function (e) {
            +        if ($(this).hasClass('p5_link')) {
            +          e.preventDefault();
            +          window.location = $(this).attr('href');
            +          setTimeout( function() { window.location = 'support.html'; }, 10000);
            +        } else {
            +          setTimeout( function() { window.location = 'support.html'; }, 1000);
            +        }
            +
            +      });
            +
            +    </script>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/download/support.html b/dist/zh-Hans/download/support.html
            new file mode 100644
            index 0000000000..4dbc5f1cd2
            --- /dev/null
            +++ b/dist/zh-Hans/download/support.html
            @@ -0,0 +1,222 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">download | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="download-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>支持 p5.js!</h1>
            +
            +      <p>我们需要您的帮助!p5.js 是免费的开源软件。我们希望使我们的社区尽可能的开放和包容。您可以通过向支持 p5.js 的组织<a href="https://processingfoundation.org/support/">Processing Foundation</a>捐款来支持这项工作。您的捐款可以支持 p5.js 的软件开发、制作范例代码及教程之类的教育资源、 <a href="https://processingfoundation.org/fellowships">奖学金</a>及<a href="https://processingfoundation.org/advocacy">社群活动。</a></p>
            +      <script src="https://donorbox.org/widget.js" paypalExpress="true"></script><iframe allowpaymentrequest="" height="900" name="donorbox" src="https://donorbox.org/embed/support-the-processing-foundation?hide_donation_meter=true" style="max-width: 500px; min-width: 250px; max-height:none!important; margin-top: 1em" ></iframe>
            +      
            +      <p><a href="https://processingfoundation.org">Processing Foundation</a>在原本的 Processing 软件多过十年的工作后成立于 2012 年。Processing Foundation 原旨为提升视觉艺术界的软件素养及提升科技界的视觉素养 — 并让这些领域更加接近不同的社群。我们的目标是赋予来自不同兴趣及背景的人学习编程与用编程制作创意作品的权利,尤其是那些可能无法得到这些工具及资源的人。</p>
            +
            +      <div id="slideshow">
            +        <div>
            +          <img src="../../assets/img/download/p5js-5939.jpg" alt="support-17-alt">
            +          <p>p5.js 贡献者会议在匹兹堡的 CMU STUDIO for Creative Inquiry 举行(图像由:Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/saskia-project.jpg" alt="support-18-alt">
            +          <p>Processing Fellow Saskia Freeke 在伦敦组织的 Code Liberation x Processing (代码解放 x Processing)研讨会(图像由:Code Liberation Foundation)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/LearningToTeach45-small.jpg" alt="support-19-alt">
            +          <p>SFPC主持的 “学习如何教导,教导如何学习” 会议(图像由Kira Simon-Kennedy)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/Cassie_CodeMiami0.png" alt="support-20-alt">
            +          <p>Processing Foundation Fellow Cassie Tarakajian 在 Code Art Miami 组织的研讨会(图像由:Christian Arévalo Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders2.jpg" alt="support-21-alt">
            +          <p>Taeyoon Choi 及 ASL(美式手语)翻译员在 Signing Coders p5.js(p5.js 手语编程员)研讨会(图像由:Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/gsoc_kickoff.jpg" alt="support-22-alt">
            +          <p>Google Summer of Code(Google 夏日程式码大赛)开幕(图像由:Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/Cassie_CodeMiami5.png" alt="support-23-alt">
            +          <p>Processing Foundation Fellow Cassie Tarakajian 在 Code Art Miami 组织的研讨会(图像由:Christian Arévalo Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders0.jpg" alt="support-24-alt">
            +          <p>Luisa Pereira 及 Yeseul Song 帮助举办一个手语为主的 p5.js 研讨会,由 Taeyoon Choi 带领(图像由:Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/conf2.jpg" alt="support-25-alt">
            +          <p>p5.js 贡献者会议在匹兹堡的 CMU STUDIO for Creative Inquiry 举行(图像由:Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/digitalcitizens-panel3.png" alt="support-26-alt">
            +          <p>Processing Fellow Digital Citizens Lab 在 International Center of Photography 所主持的 STEM(科学、科技、工程、数学)教学小组(图像由:International Center of Photography)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/aaron.jpg" alt="support-27-alt">
            +          <p>在智利圣地亚哥的 p5.js 研讨会的参与者,由 Aarón Montoya-Moraga 带领(图像由:Aarón Montoya-Moraga)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/signingcoders3.jpg" alt="support-28-alt">
            +          <p>Claire Kearney-Volpe 帮助举办一个手语为主的 p5.js 研讨会,由 Taeyoon Choi 带领(图像由:Taeyoon Choi)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/diygirls1.jpg" alt="support-29-alt">
            +          <p>Processing Foundation Fellow DIY Girls 在洛杉矶举办的创意编程课程(图像由:DIY Girls)</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/digitalcitizens7.jpg" alt="support-30-alt">
            +          <p>Processing Fellow Digital Citizens Lab</p>
            +        </div>
            +        <div>
            +          <img src="../../assets/img/download/p5-coast2coast.jpg" alt="support-31-alt">
            +          <p>UCLA DMA 及 NYU ITP 的 p5.js 聚会</p>
            +        </div>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<script src="../../assets/js/slideshow.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/examples/index.html b/dist/zh-Hans/examples/index.html
            new file mode 100644
            index 0000000000..7d014ed945
            --- /dev/null
            +++ b/dist/zh-Hans/examples/index.html
            @@ -0,0 +1,3382 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">examples | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="examples-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>范例</h1>
            +
            +      <div class="column_0 column">
            +      
            +        <h3 name='structure' class='anchor'>结构</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="structure-comments-and-statements
            .html"
            +            
            +                data-en='Comments/Statements
            '
            +            
            +                data-es='Comments and Statements
            '
            +            
            +                data-hi='निर्देशांक
            '
            +            
            +                data-ko='스테이트멘트와 코멘트
            '
            +            
            +                data-zh-Hans='Comments and Statements
            '
            +            
            +          >Comments/Statements
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-coordinates
            .html"
            +            
            +                data-en='Coordinates
            '
            +            
            +                data-es='Coordenadas
            '
            +            
            +                data-hi='चौड़ाई और ऊंचाई
            '
            +            
            +                data-ko='좌표
            '
            +            
            +                data-zh-Hans='坐标
            '
            +            
            +          >Coordinates
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-width-and-height
            .html"
            +            
            +                data-en='Width/Height
            '
            +            
            +                data-es='width y height
            '
            +            
            +                data-hi='सेटअप और ड्रा
            '
            +            
            +                data-ko='너비와 높이
            '
            +            
            +                data-zh-Hans='Width 和 Height
            '
            +            
            +          >Width/Height
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-setup-and-draw
            .html"
            +            
            +                data-en='Setup/Draw
            '
            +            
            +                data-es='Setup y Draw
            '
            +            
            +                data-hi='और ड्रा
            '
            +            
            +                data-ko='설정하고 그리기
            '
            +            
            +                data-zh-Hans='Setup 与 Draw
            '
            +            
            +          >Setup/Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-no-loop
            .html"
            +            
            +                data-en='No Loop
            '
            +            
            +                data-es='No Loop
            '
            +            
            +                data-hi='लूप
            '
            +            
            +                data-ko='루프 중단
            '
            +            
            +                data-zh-Hans='No Loop
            '
            +            
            +          >No Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-loop
            .html"
            +            
            +                data-en='Loop
            '
            +            
            +                data-es='Bucle
            '
            +            
            +                data-hi='रेड्रा
            '
            +            
            +                data-ko='루프
            '
            +            
            +                data-zh-Hans='Loop
            '
            +            
            +          >Loop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-redraw
            .html"
            +            
            +                data-en='Redraw
            '
            +            
            +                data-es='Redraw
            '
            +            
            +                data-hi='कार्य
            '
            +            
            +                data-ko='다시 그리기
            '
            +            
            +                data-zh-Hans='Redraw
            '
            +            
            +          >Redraw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-functions
            .html"
            +            
            +                data-en='Functions
            '
            +            
            +                data-es='Funciones
            '
            +            
            +                data-hi='रिकर्सन
            '
            +            
            +                data-ko='그 외 함수들
            '
            +            
            +                data-zh-Hans='函数
            '
            +            
            +          >Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-recursion
            .html"
            +            
            +                data-en='Recursion
            '
            +            
            +                data-es='Recursión
            '
            +            
            +                data-hi='ग्राफिक्स बनाएं
            '
            +            
            +                data-ko='재귀 함수
            '
            +            
            +                data-zh-Hans='递归
            '
            +            
            +          >Recursion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="structure-create-graphics
            .html"
            +            
            +                data-en='Create Graphics
            '
            +            
            +                data-es='createGraphics
            '
            +            
            +                data-ko='그래픽 만들기
            '
            +            
            +                data-zh-Hans='Create Graphics
            '
            +            
            +          >Create Graphics
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='form' class='anchor'>形状</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="form-points-and-lines
            .html"
            +            
            +                data-en='Points/Lines
            '
            +            
            +                data-es='Puntos y líneas
            '
            +            
            +                data-hi='अंक और रेखाएं
            '
            +            
            +                data-ko='점과 선
            '
            +            
            +                data-zh-Hans='Points 与 Lines
            '
            +            
            +          >Points/Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-shape-primitives
            .html"
            +            
            +                data-en='Shape Primitives
            '
            +            
            +                data-es='Figuras primitivas
            '
            +            
            +                data-hi='शेप प्रिमिटिव्स
            '
            +            
            +                data-ko='기본 조형
            '
            +            
            +                data-zh-Hans='基本形状
            '
            +            
            +          >Shape Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-pie-chart
            .html"
            +            
            +                data-en='Pie Chart
            '
            +            
            +                data-es='Gráfico de sectores
            '
            +            
            +                data-hi='पाई चार्ट
            '
            +            
            +                data-ko='파이형 차트
            '
            +            
            +                data-zh-Hans='饼状图
            '
            +            
            +          >Pie Chart
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-regular-polygon
            .html"
            +            
            +                data-en='Regular Polygon
            '
            +            
            +                data-es='Polígono regular
            '
            +            
            +                data-hi='नियमित बहुभुज
            '
            +            
            +                data-ko='정다각형
            '
            +            
            +                data-zh-Hans='正多边形
            '
            +            
            +          >Regular Polygon
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-star
            .html"
            +            
            +                data-en='Star
            '
            +            
            +                data-es='Estrella
            '
            +            
            +                data-hi='स्टार
            '
            +            
            +                data-ko='별모양
            '
            +            
            +                data-zh-Hans='Star
            '
            +            
            +          >Star
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-triangle-strip
            .html"
            +            
            +                data-en='Triangle Strip
            '
            +            
            +                data-es='Tira de triángulos
            '
            +            
            +                data-hi='त्रिभुज पट्टी
            '
            +            
            +                data-ko='삼각형 고리
            '
            +            
            +                data-zh-Hans='Triangle Strip
            '
            +            
            +          >Triangle Strip
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-bezier
            .html"
            +            
            +                data-en='Bezier
            '
            +            
            +                data-es='Bezier
            '
            +            
            +                data-hi='बेज़ियर
            '
            +            
            +                data-ko='베지어 곡선
            '
            +            
            +                data-zh-Hans='Bezier
            '
            +            
            +          >Bezier
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-3d-primitives
            .html"
            +            
            +                data-en='3D Primitives
            '
            +            
            +                data-es='Primitivas 3D
            '
            +            
            +                data-hi='३डी प्रिमिटिव्स
            '
            +            
            +                data-ko='3D 기본 조형
            '
            +            
            +                data-zh-Hans='基本 3D 形状
            '
            +            
            +          >3D Primitives
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="form-trig-wheels-and-pie-chart
            .html"
            +            
            +                data-en='Trig Wheels/Pie Chart
            '
            +            
            +                data-es='Trig Wheels and Pie Chart
            '
            +            
            +                data-ko='단위원과 파이 차트
            '
            +            
            +                data-zh-Hans='Trig Wheels and Pie Chart
            '
            +            
            +          >Trig Wheels/Pie Chart
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='data' class='anchor'>资料</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="data-variables
            .html"
            +            
            +                data-en='Variables
            '
            +            
            +                data-es='Variables
            '
            +            
            +                data-hi='चर
            '
            +            
            +                data-ko='변수
            '
            +            
            +                data-zh-Hans='变量
            '
            +            
            +          >Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-true-and-false
            .html"
            +            
            +                data-en='True/False
            '
            +            
            +                data-es='True y False
            '
            +            
            +                data-hi='सही और गलत
            '
            +            
            +                data-ko='참과 거짓
            '
            +            
            +                data-zh-Hans='True 和 False
            '
            +            
            +          >True/False
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-variable-scope
            .html"
            +            
            +                data-en='Variable Scope
            '
            +            
            +                data-es='Alcance de variabless
            '
            +            
            +                data-hi='परिवर्तनीय दायरा
            '
            +            
            +                data-ko='변수 범위
            '
            +            
            +                data-zh-Hans='变量范围
            '
            +            
            +          >Variable Scope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="data-numbers
            .html"
            +            
            +                data-en='Numbers
            '
            +            
            +                data-es='Números
            '
            +            
            +                data-hi='नंबर
            '
            +            
            +                data-ko='숫자값
            '
            +            
            +                data-zh-Hans='Numbers
            '
            +            
            +          >Numbers
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='arrays' class='anchor'>数组</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="arrays-array
            .html"
            +            
            +                data-en='Array
            '
            +            
            +                data-es='Arreglo
            '
            +            
            +                data-hi='ऐरे
            '
            +            
            +                data-ko='배열
            '
            +            
            +                data-zh-Hans='数组
            '
            +            
            +          >Array
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-2d
            .html"
            +            
            +                data-en='Array 2D
            '
            +            
            +                data-es='Arreglo 2D
            '
            +            
            +                data-hi='ऐरे 2D
            '
            +            
            +                data-ko='2D 배열
            '
            +            
            +                data-zh-Hans='2D 数组
            '
            +            
            +          >Array 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-array-objects
            .html"
            +            
            +                data-en='Array Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='ऐरे ऑब्जेक्ट्स
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='数组对象
            '
            +            
            +          >Array Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="arrays-walk-over-2darray
            .html"
            +            
            +                data-en='Walk Over 2dArray
            '
            +            
            +                data-es='Walk Over 2dArray
            '
            +            
            +                data-ko='Walk Over 2dArray
            '
            +            
            +                data-zh-Hans='Walk Over 2dArray
            '
            +            
            +          >Walk Over 2dArray
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='control' class='anchor'>控制</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="control-iteration
            .html"
            +            
            +                data-en='Iteration
            '
            +            
            +                data-es='Iteración
            '
            +            
            +                data-hi='पुनरावृत्ति
            '
            +            
            +                data-ko='for 반복문
            '
            +            
            +                data-zh-Hans='迭代
            '
            +            
            +          >Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-embedded-iteration
            .html"
            +            
            +                data-en='Embedded Iteration
            '
            +            
            +                data-es='Iteración anidada
            '
            +            
            +                data-hi='एंबेडेड इटरेशन
            '
            +            
            +                data-ko='for 내장 반복문
            '
            +            
            +                data-zh-Hans='嵌入式迭代
            '
            +            
            +          >Embedded Iteration
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-1
            .html"
            +            
            +                data-en='Conditionals 1
            '
            +            
            +                data-es='Condicionales 1
            '
            +            
            +                data-hi='सशर्त 1
            '
            +            
            +                data-ko='조건문 1
            '
            +            
            +                data-zh-Hans='条件 1
            '
            +            
            +          >Conditionals 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditionals-2
            .html"
            +            
            +                data-en='Conditionals 2
            '
            +            
            +                data-es='Condicionales 2
            '
            +            
            +                data-hi='सशर्त 2
            '
            +            
            +                data-ko='조건문 2
            '
            +            
            +                data-zh-Hans='条件 2
            '
            +            
            +          >Conditionals 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators
            .html"
            +            
            +                data-en='Logical Operators
            '
            +            
            +                data-es='Operadores lógicos
            '
            +            
            +                data-hi='लॉजिकल ऑपरेटर्स
            '
            +            
            +                data-ko='논리적 연산자
            '
            +            
            +                data-zh-Hans='逻辑操作符
            '
            +            
            +          >Logical Operators
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-logical-operators-2
            .html"
            +            
            +                data-en='Logical Operators 2
            '
            +            
            +                data-es='Logical Operators 2
            '
            +            
            +                data-ko='Logical Operators 2
            '
            +            
            +                data-zh-Hans='Logical Operators 2
            '
            +            
            +          >Logical Operators 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="control-conditional-shapes
            .html"
            +            
            +                data-en='Conditional Shapes
            '
            +            
            +                data-es='Conditional Shapes
            '
            +            
            +                data-ko='Conditional Shapes
            '
            +            
            +                data-zh-Hans='Conditional Shapes
            '
            +            
            +          >Conditional Shapes
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='image' class='anchor'>图像</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="image-load-and-display-image
            .html"
            +            
            +                data-en='Load/Display Image
            '
            +            
            +                data-es='Cargar y mostrar imagen
            '
            +            
            +                data-hi='लोड और डिस्प्ले इमेज
            '
            +            
            +                data-ko='이미지 불러오기 및 보이기
            '
            +            
            +                data-zh-Hans='加载(Load)和显示(Display)图像
            '
            +            
            +          >Load/Display Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-background-image
            .html"
            +            
            +                data-en='Background Image
            '
            +            
            +                data-es='Imagen de fondo
            '
            +            
            +                data-hi='पृष्ठभूमि छवि
            '
            +            
            +                data-ko='배경 이미지
            '
            +            
            +                data-zh-Hans='背景图像
            '
            +            
            +          >Background Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-transparency
            .html"
            +            
            +                data-en='Transparency
            '
            +            
            +                data-es='Transparencia
            '
            +            
            +                data-hi='पारदर्शिता
            '
            +            
            +                data-ko='투명도
            '
            +            
            +                data-zh-Hans='透明度
            '
            +            
            +          >Transparency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-alpha-mask
            .html"
            +            
            +                data-en='Alpha Mask
            '
            +            
            +                data-es='Alpha Mask
            '
            +            
            +                data-hi='अल्फा मास्क
            '
            +            
            +                data-ko='알파 마스크
            '
            +            
            +                data-zh-Hans='透明度遮罩 (Alpha Mask)
            '
            +            
            +          >Alpha Mask
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-create-image
            .html"
            +            
            +                data-en='Create Image
            '
            +            
            +                data-es='Crear una imagen
            '
            +            
            +                data-hi='इमेज बनाएं
            '
            +            
            +                data-ko='이미지 만들기
            '
            +            
            +                data-zh-Hans='创建图像
            '
            +            
            +          >Create Image
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-pointillism
            .html"
            +            
            +                data-en='Pointillism
            '
            +            
            +                data-es='Puntillismo
            '
            +            
            +                data-hi='पॉइंटिलिज्म
            '
            +            
            +                data-ko='점묘법
            '
            +            
            +                data-zh-Hans='点画(Pointillism)
            '
            +            
            +          >Pointillism
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-blur
            .html"
            +            
            +                data-en='Blur
            '
            +            
            +                data-es='Blur
            '
            +            
            +                data-ko='Blur
            '
            +            
            +                data-zh-Hans='Blur
            '
            +            
            +          >Blur
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-edge-detection
            .html"
            +            
            +                data-en='Edge Detection
            '
            +            
            +                data-es='Edge Detection
            '
            +            
            +                data-ko='Edge Detection
            '
            +            
            +                data-zh-Hans='Edge Detection
            '
            +            
            +          >Edge Detection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brightness
            '
            +            
            +                data-ko='Brightness
            '
            +            
            +                data-zh-Hans='Brightness
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-convolution
            .html"
            +            
            +                data-en='Convolution
            '
            +            
            +                data-es='Convolution
            '
            +            
            +                data-ko='Convolution
            '
            +            
            +                data-zh-Hans='Convolution
            '
            +            
            +          >Convolution
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="image-copy-method
            .html"
            +            
            +                data-en='Copy() method
            '
            +            
            +                data-es='Método copy()
            '
            +            
            +                data-ko='Copy() method
            '
            +            
            +                data-zh-Hans='Copy() 函数
            '
            +            
            +          >Copy() method
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='color' class='anchor'>颜色</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="color-hue
            .html"
            +            
            +                data-en='Hue
            '
            +            
            +                data-es='Tinte
            '
            +            
            +                data-hi='ह्यू
            '
            +            
            +                data-ko='색조
            '
            +            
            +                data-zh-Hans='色调
            '
            +            
            +          >Hue
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-saturation
            .html"
            +            
            +                data-en='Saturation
            '
            +            
            +                data-es='Saturación
            '
            +            
            +                data-hi='संतृप्ति
            '
            +            
            +                data-ko='채도
            '
            +            
            +                data-zh-Hans='饱和度
            '
            +            
            +          >Saturation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-brightness
            .html"
            +            
            +                data-en='Brightness
            '
            +            
            +                data-es='Brillo
            '
            +            
            +                data-hi='चमक
            '
            +            
            +                data-ko='밝기
            '
            +            
            +                data-zh-Hans='亮度
            '
            +            
            +          >Brightness
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-color-variables
            .html"
            +            
            +                data-en='Color Variables
            '
            +            
            +                data-es='Variables de color
            '
            +            
            +                data-hi='रंग चर
            '
            +            
            +                data-ko='색상 변수
            '
            +            
            +                data-zh-Hans='颜色变量
            '
            +            
            +          >Color Variables
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-relativity
            .html"
            +            
            +                data-en='Relativity
            '
            +            
            +                data-es='Relatividad
            '
            +            
            +                data-hi='सापेक्षता
            '
            +            
            +                data-ko='상대성
            '
            +            
            +                data-zh-Hans='相对性
            '
            +            
            +          >Relativity
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-linear-gradient
            .html"
            +            
            +                data-en='Linear Gradient
            '
            +            
            +                data-es='Gradiente linear
            '
            +            
            +                data-hi='रैखिक ढाल
            '
            +            
            +                data-ko='선형 그래디언트
            '
            +            
            +                data-zh-Hans='线性渐变
            '
            +            
            +          >Linear Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-radial-gradient
            .html"
            +            
            +                data-en='Radial Gradient
            '
            +            
            +                data-es='Gradiente radial
            '
            +            
            +                data-hi='रेडियल ग्रेडिएंट
            '
            +            
            +                data-ko='방사형 그래디언트
            '
            +            
            +                data-zh-Hans='径向渐变
            '
            +            
            +          >Radial Gradient
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="color-lerp-color
            .html"
            +            
            +                data-en='Lerp Color
            '
            +            
            +                data-es='Interpolación de color
            '
            +            
            +                data-hi='Lerp Color
            '
            +            
            +                data-ko='선형 보간(lerp) 색상
            '
            +            
            +                data-zh-Hans='插值颜色
            '
            +            
            +          >Lerp Color
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='math' class='anchor'>数学</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="math-increment-decrement
            .html"
            +            
            +                data-en='Increment Decrement
            '
            +            
            +                data-es='Incremento y decremento
            '
            +            
            +                data-hi='वेतन वृद्धि
            '
            +            
            +                data-ko='증가와 감소
            '
            +            
            +                data-zh-Hans='增量/减量
            '
            +            
            +          >Increment Decrement
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-operator-precedence
            .html"
            +            
            +                data-en='Operator Precedence
            '
            +            
            +                data-es='Precedencia de operadores
            '
            +            
            +                data-hi='ऑपरेटर वरीयता
            '
            +            
            +                data-ko='연산자 우선 순위
            '
            +            
            +                data-zh-Hans='操作符优先级
            '
            +            
            +          >Operator Precedence
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-1d
            .html"
            +            
            +                data-en='Distance 1D
            '
            +            
            +                data-es='Distancia 1D
            '
            +            
            +                data-hi='दूरी 1डी
            '
            +            
            +                data-ko='1D 거리
            '
            +            
            +                data-zh-Hans='一维间距
            '
            +            
            +          >Distance 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-distance-2d
            .html"
            +            
            +                data-en='Distance 2D
            '
            +            
            +                data-es='Distancia 2D
            '
            +            
            +                data-hi='दूरी 2डी
            '
            +            
            +                data-ko='2D 거리
            '
            +            
            +                data-zh-Hans='二维间距
            '
            +            
            +          >Distance 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine
            .html"
            +            
            +                data-en='Sine
            '
            +            
            +                data-es='Seno
            '
            +            
            +                data-hi='साइन
            '
            +            
            +                data-ko='사인
            '
            +            
            +                data-zh-Hans='正弦
            '
            +            
            +          >Sine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-cosine
            .html"
            +            
            +                data-en='Sine Cosine
            '
            +            
            +                data-es='Seno y coseno
            '
            +            
            +                data-hi='साइन कोसाइन
            '
            +            
            +                data-ko='사인 코사인
            '
            +            
            +                data-zh-Hans='正弦余弦
            '
            +            
            +          >Sine Cosine
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-sine-wave
            .html"
            +            
            +                data-en='Sine Wave
            '
            +            
            +                data-es='Onda sinusoidal
            '
            +            
            +                data-hi='साइन वेव
            '
            +            
            +                data-ko='사인파
            '
            +            
            +                data-zh-Hans='正弦波
            '
            +            
            +          >Sine Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-additive-wave
            .html"
            +            
            +                data-en='Additive Wave
            '
            +            
            +                data-es='Onda aditiva
            '
            +            
            +                data-hi='Additive Wave
            '
            +            
            +                data-ko='파형 추가
            '
            +            
            +                data-zh-Hans='加性波
            '
            +            
            +          >Additive Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-polartocartesian
            .html"
            +            
            +                data-en='PolarToCartesian
            '
            +            
            +                data-es='Polar a cartesiano
            '
            +            
            +                data-hi='PolarToCartesian
            '
            +            
            +                data-ko='극좌표를 직교 좌표로
            '
            +            
            +                data-zh-Hans='PolarToCartesian
            '
            +            
            +          >PolarToCartesian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-arctangent
            .html"
            +            
            +                data-en='Arctangent
            '
            +            
            +                data-es='Arcotangente
            '
            +            
            +                data-hi='आर्कटिक
            '
            +            
            +                data-ko='아크탄젠트
            '
            +            
            +                data-zh-Hans='反正切
            '
            +            
            +          >Arctangent
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-linear-interpolation
            .html"
            +            
            +                data-en='Linear Interpolation
            '
            +            
            +                data-es='Interpolación Lineal
            '
            +            
            +                data-hi='रैखिक इंटरपोलेशन
            '
            +            
            +                data-ko='선형 보간법
            '
            +            
            +                data-zh-Hans='线性插值
            '
            +            
            +          >Linear Interpolation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-double-random
            .html"
            +            
            +                data-en='Double Random
            '
            +            
            +                data-es='Doble aleatorio
            '
            +            
            +                data-hi='डबल रैंडम
            '
            +            
            +                data-ko='이중 랜덤
            '
            +            
            +                data-zh-Hans='双重随机
            '
            +            
            +          >Double Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random
            .html"
            +            
            +                data-en='Random
            '
            +            
            +                data-es='Aleatorio
            '
            +            
            +                data-hi='रैंडम
            '
            +            
            +                data-ko='랜덤
            '
            +            
            +                data-zh-Hans='随机
            '
            +            
            +          >Random
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise1d
            .html"
            +            
            +                data-en='Noise1D
            '
            +            
            +                data-es='Ruido 1D
            '
            +            
            +                data-hi='Noise1D
            '
            +            
            +                data-ko='1D 노이즈
            '
            +            
            +                data-zh-Hans='一维噪声 (Noise1D)
            '
            +            
            +          >Noise1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise-wave
            .html"
            +            
            +                data-en='Noise Wave
            '
            +            
            +                data-es='Onda de ruido
            '
            +            
            +                data-hi='शोर लहर
            '
            +            
            +                data-ko='노이즈 파형
            '
            +            
            +                data-zh-Hans='噪声波
            '
            +            
            +          >Noise Wave
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise2d
            .html"
            +            
            +                data-en='Noise2D
            '
            +            
            +                data-es='Ruido 2D
            '
            +            
            +                data-hi='Noise2D
            '
            +            
            +                data-ko='2D 노이즈
            '
            +            
            +                data-zh-Hans='二维噪声 (Noise2D)
            '
            +            
            +          >Noise2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-noise3d
            .html"
            +            
            +                data-en='Noise3D
            '
            +            
            +                data-es='Ruido 3D
            '
            +            
            +                data-hi='Noise3D
            '
            +            
            +                data-ko='3D 노이즈
            '
            +            
            +                data-zh-Hans='三维噪声 (Noise3D)
            '
            +            
            +          >Noise3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-chords
            .html"
            +            
            +                data-en='Random Chords
            '
            +            
            +                data-es='Cuerdas Aleatorias
            '
            +            
            +                data-hi='रैंडम कॉर्ड्स
            '
            +            
            +                data-ko='랜덤 선들
            '
            +            
            +                data-zh-Hans='随机弦
            '
            +            
            +          >Random Chords
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-random-gaussian
            .html"
            +            
            +                data-en='Random Gaussian
            '
            +            
            +                data-es='Mapear
            '
            +            
            +                data-hi='नक्शा
            '
            +            
            +                data-ko='매핑(map)
            '
            +            
            +                data-zh-Hans='映射 (Map)
            '
            +            
            +          >Random Gaussian
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-map
            .html"
            +            
            +                data-en='Map
            '
            +            
            +                data-es='Ecuaciones Paramétricas
            '
            +            
            +                data-hi='पैरामीट्रिक समीकरण
            '
            +            
            +                data-ko='매개변수 방정식
            '
            +            
            +                data-zh-Hans='参数方程
            '
            +            
            +          >Map
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-graphing-2d-equations
            .html"
            +            
            +                data-en='Graphing 2D Equations
            '
            +            
            +                data-es='Graphing 2D Equations
            '
            +            
            +                data-ko='Graphing 2D Equations
            '
            +            
            +                data-zh-Hans='Graphing 2D Equations
            '
            +            
            +          >Graphing 2D Equations
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="math-parametric-equations
            .html"
            +            
            +                data-en='Parametric Equations
            '
            +            
            +                data-es='Parametric Equations
            '
            +            
            +                data-ko='Parametric Equations
            '
            +            
            +                data-zh-Hans='Parametric Equations
            '
            +            
            +          >Parametric Equations
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_1 column">
            +        
            +      
            +        <h3 name='simulate' class='anchor'>模拟</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="simulate-forces
            .html"
            +            
            +                data-en='Forces
            '
            +            
            +                data-es='Fuerzas
            '
            +            
            +                data-hi='बल
            '
            +            
            +                data-ko='힘
            '
            +            
            +                data-zh-Hans='Forces
            '
            +            
            +          >Forces
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particle-system
            .html"
            +            
            +                data-en='Particle System
            '
            +            
            +                data-es='Sistema de partículas
            '
            +            
            +                data-hi='कण प्रणाली
            '
            +            
            +                data-ko='파티클 시스템
            '
            +            
            +                data-zh-Hans='Particle System
            '
            +            
            +          >Particle System
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-wolfram-ca
            .html"
            +            
            +                data-en='Wolfram CA
            '
            +            
            +                data-es='Wolfram CA
            '
            +            
            +                data-hi='वोल्फ्राम सीए
            '
            +            
            +                data-ko='울프램 셀룰러 오토마타
            '
            +            
            +                data-zh-Hans='Wolfram CA
            '
            +            
            +          >Wolfram CA
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-game-of-life
            .html"
            +            
            +                data-en='Game of Life
            '
            +            
            +                data-es='Juego de la vida
            '
            +            
            +                data-hi='Game of Life
            '
            +            
            +                data-ko='라이프 게임
            '
            +            
            +                data-zh-Hans='Game of Life
            '
            +            
            +          >Game of Life
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-multiple-particle-systems
            .html"
            +            
            +                data-en='Multiple Particle Systems
            '
            +            
            +                data-es='Múltiples sistemas de partículas
            '
            +            
            +                data-hi='मल्टीपल पार्टिकल सिस्टम
            '
            +            
            +                data-ko='멀티플 파티클 시스템
            '
            +            
            +                data-zh-Hans='Multiple Particle Systems
            '
            +            
            +          >Multiple Particle Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spirograph
            .html"
            +            
            +                data-en='Spirograph
            '
            +            
            +                data-es='Espirógrafo
            '
            +            
            +                data-hi='स्पाइरोग्राफ
            '
            +            
            +                data-ko='스피로그래프
            '
            +            
            +                data-zh-Hans='Spirograph
            '
            +            
            +          >Spirograph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-l-systems
            .html"
            +            
            +                data-en='L-Systems
            '
            +            
            +                data-es='Sístemas-L
            '
            +            
            +                data-hi='एल-सिस्टम्स
            '
            +            
            +                data-ko='L-시스템
            '
            +            
            +                data-zh-Hans='L-Systems
            '
            +            
            +          >L-Systems
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-spring
            .html"
            +            
            +                data-en='Spring
            '
            +            
            +                data-es='Resorte
            '
            +            
            +                data-hi='वसंत
            '
            +            
            +                data-ko='용수철
            '
            +            
            +                data-zh-Hans='Spring
            '
            +            
            +          >Spring
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-springs
            .html"
            +            
            +                data-en='Springs
            '
            +            
            +                data-es='Resortes
            '
            +            
            +                data-hi='स्प्रिंग्स
            '
            +            
            +                data-ko='용수철들
            '
            +            
            +                data-zh-Hans='Springs
            '
            +            
            +          >Springs
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-soft-body
            .html"
            +            
            +                data-en='Soft Body
            '
            +            
            +                data-es='Cuerpo blando
            '
            +            
            +                data-hi='शीतल शरीर
            '
            +            
            +                data-ko='소프트 바디
            '
            +            
            +                data-zh-Hans='Soft Body
            '
            +            
            +          >Soft Body
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-smokeparticles
            .html"
            +            
            +                data-en='SmokeParticles
            '
            +            
            +                data-es='Partículas de humo
            '
            +            
            +                data-hi='स्मोकपार्टिकल्स
            '
            +            
            +                data-ko='연기 파티클
            '
            +            
            +                data-zh-Hans='SmokeParticles
            '
            +            
            +          >SmokeParticles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Movimiento browniano
            '
            +            
            +                data-hi='ब्राउनियन मोशन
            '
            +            
            +                data-ko='브라운 운동
            '
            +            
            +                data-zh-Hans='Brownian Motion
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-chain
            .html"
            +            
            +                data-en='Chain
            '
            +            
            +                data-es='Cadena
            '
            +            
            +                data-hi='चैन
            '
            +            
            +                data-ko='사슬
            '
            +            
            +                data-zh-Hans='Chain
            '
            +            
            +          >Chain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-snowflakes
            .html"
            +            
            +                data-en='Snowflakes
            '
            +            
            +                data-es='Copos de Nieve
            '
            +            
            +                data-hi='स्नोफ्लेक्स
            '
            +            
            +                data-ko='눈송이 파티클
            '
            +            
            +                data-zh-Hans='Snowflakes
            '
            +            
            +          >Snowflakes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-penrose-tiles
            .html"
            +            
            +                data-en='Penrose Tiles
            '
            +            
            +                data-es='Baldosas de Penrose
            '
            +            
            +                data-hi='पेनरोज़ टाइलें
            '
            +            
            +                data-ko='펜로즈 타일
            '
            +            
            +                data-zh-Hans='Penrose Tiles
            '
            +            
            +          >Penrose Tiles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-recursive-tree
            .html"
            +            
            +                data-en='Recursive Tree
            '
            +            
            +                data-es='Árbol Recursivo
            '
            +            
            +                data-hi='रिकर्सिव ट्री
            '
            +            
            +                data-ko='재귀 나무
            '
            +            
            +                data-zh-Hans='Recursive Tree
            '
            +            
            +          >Recursive Tree
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-the-mandelbrot-set
            .html"
            +            
            +                data-en='The Mandelbrot Set
            '
            +            
            +                data-es='El Conjunto de Mandelbrot
            '
            +            
            +                data-hi='मंडेलब्रॉट सेत
            '
            +            
            +                data-ko='망델브로 집합
            '
            +            
            +                data-zh-Hans='The Mandelbrot Set
            '
            +            
            +          >The Mandelbrot Set
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-koch-curve
            .html"
            +            
            +                data-en='Koch Curve
            '
            +            
            +                data-es='Curva Koch
            '
            +            
            +                data-hi='कोच कर्व
            '
            +            
            +                data-ko='코흐 곡선
            '
            +            
            +                data-zh-Hans='Koch Curve
            '
            +            
            +          >Koch Curve
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-bubble-sort
            .html"
            +            
            +                data-en='Bubble Sort
            '
            +            
            +                data-es='Ordenamiento de Burbuja
            '
            +            
            +                data-hi='बबल सॉर्ट
            '
            +            
            +                data-ko='버블 정렬
            '
            +            
            +                data-zh-Hans='Bubble Sort
            '
            +            
            +          >Bubble Sort
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-stepping-feet-illusion
            .html"
            +            
            +                data-en='Stepping Feet Illusion
            '
            +            
            +                data-es='Ilusión de los Pasos
            '
            +            
            +                data-hi='स्टेपिंग फीट इल्यूजन
            '
            +            
            +                data-ko='걷는발 착시효과
            '
            +            
            +                data-zh-Hans='Stepping Feet Illusion
            '
            +            
            +          >Stepping Feet Illusion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-particles
            .html"
            +            
            +                data-en='Particles
            '
            +            
            +                data-es='Partículas
            '
            +            
            +                data-hi='कण
            '
            +            
            +                data-ko='파티클
            '
            +            
            +                data-zh-Hans='Particles
            '
            +            
            +          >Particles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="simulate-quicksort
            .html"
            +            
            +                data-en='Quicksort
            '
            +            
            +                data-es='Quicksort
            '
            +            
            +                data-ko='Quicksort
            '
            +            
            +                data-zh-Hans='Quicksort
            '
            +            
            +          >Quicksort
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='interaction' class='anchor'>互动</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="interaction-tickle
            .html"
            +            
            +                data-en='Tickle
            '
            +            
            +                data-es='Cosquillas
            '
            +            
            +                data-hi='टिकल 
            '
            +            
            +                data-ko='간질간질
            '
            +            
            +                data-zh-Hans='Tickle
            '
            +            
            +          >Tickle
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-weight-line
            .html"
            +            
            +                data-en='Weight Line
            '
            +            
            +                data-es='Weight Line
            '
            +            
            +                data-hi='फॉलो 1
            '
            +            
            +                data-ko='Weight Line
            '
            +            
            +                data-zh-Hans='Weight Line
            '
            +            
            +          >Weight Line
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-1
            .html"
            +            
            +                data-en='Follow 1
            '
            +            
            +                data-es='Seguir 1
            '
            +            
            +                data-hi='फॉलो 2
            '
            +            
            +                data-ko='따라다니기 1
            '
            +            
            +                data-zh-Hans='跟随 1
            '
            +            
            +          >Follow 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-2
            .html"
            +            
            +                data-en='Follow 2
            '
            +            
            +                data-es='Seguir 2
            '
            +            
            +                data-hi='फॉलो 3
            '
            +            
            +                data-ko='따라다니기 2
            '
            +            
            +                data-zh-Hans='跟随 2
            '
            +            
            +          >Follow 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-follow-3
            .html"
            +            
            +                data-en='Follow 3
            '
            +            
            +                data-es='Seguir 3
            '
            +            
            +                data-hi='सांप का खेल
            '
            +            
            +                data-ko='따라다니기 3
            '
            +            
            +                data-zh-Hans='跟随 3
            '
            +            
            +          >Follow 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-snake-game
            .html"
            +            
            +                data-en='Snake game
            '
            +            
            +                data-es='Juego de Serpiente
            '
            +            
            +                data-hi='वेवमेकर
            '
            +            
            +                data-ko='스네이크 게임
            '
            +            
            +                data-zh-Hans='贪吃蛇
            '
            +            
            +          >Snake game
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-wavemaker
            .html"
            +            
            +                data-en='Wavemaker
            '
            +            
            +                data-es='Wavemaker
            '
            +            
            +                data-hi='रीच 1
            '
            +            
            +                data-ko='파도 만들기
            '
            +            
            +                data-zh-Hans='造波器
            '
            +            
            +          >Wavemaker
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-1
            .html"
            +            
            +                data-en='Reach 1
            '
            +            
            +                data-es='Alcanzar 1
            '
            +            
            +                data-hi='रीच 2
            '
            +            
            +                data-ko='팔닿기 1
            '
            +            
            +                data-zh-Hans='延伸 1
            '
            +            
            +          >Reach 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-2
            .html"
            +            
            +                data-en='Reach 2
            '
            +            
            +                data-es='Alcanzar 2
            '
            +            
            +                data-hi='पहुंच ३
            '
            +            
            +                data-ko='팔닿기 2
            '
            +            
            +                data-zh-Hans='延伸 2
            '
            +            
            +          >Reach 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-reach-3
            .html"
            +            
            +                data-en='Reach 3
            '
            +            
            +                data-es='Alcanzar 3
            '
            +            
            +                data-hi='Arduino सेंसर डेटा WebJack के माध्यम से
            '
            +            
            +                data-ko='팔닿기 3
            '
            +            
            +                data-zh-Hans='延伸 3
            '
            +            
            +          >Reach 3
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-arduino-sensor-data-via-webjack
            .html"
            +            
            +                data-en='Arduino sensor data via WebJack
            '
            +            
            +                data-es='Datos de un sensor Arduino vía WebJack
            '
            +            
            +                data-hi='बहुरूपदर्शक
            '
            +            
            +                data-ko='웹잭과 아두이노 센서 데이터
            '
            +            
            +                data-zh-Hans='通过 WebJack 读取 Arduino 传感器数据
            '
            +            
            +          >Arduino sensor data via WebJack
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="interaction-kaleidoscope
            .html"
            +            
            +                data-en='Kaleidoscope
            '
            +            
            +                data-es='Caleidoscopio
            '
            +            
            +                data-ko='만화경
            '
            +            
            +                data-zh-Hans='万花筒
            '
            +            
            +          >Kaleidoscope
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='objects' class='anchor'>物件</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="objects-objects
            .html"
            +            
            +                data-en='Objects
            '
            +            
            +                data-es='Objetos
            '
            +            
            +                data-hi='वस्तु
            '
            +            
            +                data-ko='객체
            '
            +            
            +                data-zh-Hans='物件 (Objects)
            '
            +            
            +          >Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-multiple-objects
            .html"
            +            
            +                data-en='Multiple Objects
            '
            +            
            +                data-es='Múltiples objetos
            '
            +            
            +                data-hi='वस्तुओं का नाम दें
            '
            +            
            +                data-ko='복수 객체
            '
            +            
            +                data-zh-Hans='多个物件
            '
            +            
            +          >Multiple Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-array-of-objects
            .html"
            +            
            +                data-en='Array of Objects
            '
            +            
            +                data-es='Arreglo de objetos
            '
            +            
            +                data-hi='वस्तुओं की सरणी
            '
            +            
            +                data-ko='객체 배열
            '
            +            
            +                data-zh-Hans='物件数组
            '
            +            
            +          >Array of Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-objects-2
            .html"
            +            
            +                data-en='Objects 2
            '
            +            
            +                data-es='Objetos 2
            '
            +            
            +                data-hi='वस्तु 2
            '
            +            
            +                data-ko='객체 2
            '
            +            
            +                data-zh-Hans='物件 2
            '
            +            
            +          >Objects 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-inheritance
            .html"
            +            
            +                data-en='Inheritance
            '
            +            
            +                data-es='Herencia
            '
            +            
            +                data-hi='वंशानुक्रम
            '
            +            
            +                data-ko='상속
            '
            +            
            +                data-zh-Hans='继承 (Inheritance)
            '
            +            
            +          >Inheritance
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-composite-objects
            .html"
            +            
            +                data-en='Composite Objects
            '
            +            
            +                data-es='Objetos Compuestos
            '
            +            
            +                data-hi='समग्र वस्तु
            '
            +            
            +                data-ko='합성 객체
            '
            +            
            +                data-zh-Hans='复合物件
            '
            +            
            +          >Composite Objects
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="objects-car-instances
            .html"
            +            
            +                data-en='Car Instances
            '
            +            
            +                data-es='Car Instances
            '
            +            
            +                data-ko='Car Instances
            '
            +            
            +                data-zh-Hans='Car Instances
            '
            +            
            +          >Car Instances
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='lights' class='anchor'>灯光</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="lights-directional
            .html"
            +            
            +                data-en='Directional
            '
            +            
            +                data-es='Direccional
            '
            +            
            +                data-hi='दिशात्मक
            '
            +            
            +                data-ko='디렉셔널 라이트
            '
            +            
            +                data-zh-Hans='定向光
            '
            +            
            +          >Directional
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="lights-mixture
            .html"
            +            
            +                data-en='Mixture
            '
            +            
            +                data-es='Mezcla
            '
            +            
            +                data-hi='मिश्रण
            '
            +            
            +                data-ko='혼합 라이트
            '
            +            
            +                data-zh-Hans='混合光
            '
            +            
            +          >Mixture
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='motion' class='anchor'>Motion</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="motion-non-orthogonal-reflection
            .html"
            +            
            +                data-en='Non Orthogonal Reflection
            '
            +            
            +                data-es='Reflejo no ortogonal
            '
            +            
            +                data-hi='नॉन ऑर्थोगोनल रिफ्लेक्शन
            '
            +            
            +                data-ko='비직각 반사
            '
            +            
            +                data-zh-Hans='Non Orthogonal Reflection
            '
            +            
            +          >Non Orthogonal Reflection
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-linear
            .html"
            +            
            +                data-en='Linear
            '
            +            
            +                data-es='Lineal
            '
            +            
            +                data-hi='रैखिक
            '
            +            
            +                data-ko='선형
            '
            +            
            +                data-zh-Hans='Linear
            '
            +            
            +          >Linear
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bounce
            .html"
            +            
            +                data-en='Bounce
            '
            +            
            +                data-es='Rebote
            '
            +            
            +                data-hi='उछाल
            '
            +            
            +                data-ko='바운스
            '
            +            
            +                data-zh-Hans='Bounce
            '
            +            
            +          >Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-bouncy-bubbles
            .html"
            +            
            +                data-en='Bouncy Bubbles
            '
            +            
            +                data-es='Burbujas Saltarinas
            '
            +            
            +                data-hi='उछाल वाले बुलबुले
            '
            +            
            +                data-ko='버블 바운스
            '
            +            
            +                data-zh-Hans='Bouncy Bubbles
            '
            +            
            +          >Bouncy Bubbles
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-brownian-motion
            .html"
            +            
            +                data-en='Brownian Motion
            '
            +            
            +                data-es='Transformar
            '
            +            
            +                data-hi='मॉर्फ
            '
            +            
            +                data-ko='변형(morph)
            '
            +            
            +                data-zh-Hans='Morph
            '
            +            
            +          >Brownian Motion
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-morph
            .html"
            +            
            +                data-en='Morph
            '
            +            
            +                data-es='Moviéndose por Curvas
            '
            +            
            +                data-hi='मूविंग ऑन कर्व्स
            '
            +            
            +                data-ko='곡선 위 움직이기
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Morph
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-circle-collision
            .html"
            +            
            +                data-en='Circle Collision
            '
            +            
            +                data-es='Circle Collision
            '
            +            
            +                data-ko='Circle Collision
            '
            +            
            +                data-zh-Hans='Circle Collision
            '
            +            
            +          >Circle Collision
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="motion-moving-on-curves
            .html"
            +            
            +                data-en='Moving On Curves
            '
            +            
            +                data-es='Moving On Curves
            '
            +            
            +                data-ko='Moving On Curves
            '
            +            
            +                data-zh-Hans='Moving On Curves
            '
            +            
            +          >Moving On Curves
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='instance_mode' class='anchor'>实例模式</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="instance-mode-instantiation
            .html"
            +            
            +                data-en='Instantiation
            '
            +            
            +                data-es='Instaciación
            '
            +            
            +                data-hi='इंस्टेंटेशन
            '
            +            
            +                data-ko='인스턴스화
            '
            +            
            +                data-zh-Hans='创建实例
            '
            +            
            +          >Instantiation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="instance-mode-instance-container
            .html"
            +            
            +                data-en='Instance Container
            '
            +            
            +                data-es='Contenedor de instancia
            '
            +            
            +                data-hi='इंस्टेंस कंटेनर
            '
            +            
            +                data-ko='인스턴스 컨테이너
            '
            +            
            +                data-zh-Hans='实例容器
            '
            +            
            +          >Instance Container
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='dom' class='anchor'>DOM</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="dom-input-and-button
            .html"
            +            
            +                data-en='Input/Button
            '
            +            
            +                data-es='Entrada y botón
            '
            +            
            +                data-hi='इनपुट और बटन
            '
            +            
            +                data-ko='입력과 버튼
            '
            +            
            +                data-zh-Hans='Input and Button
            '
            +            
            +          >Input/Button
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-slider
            .html"
            +            
            +                data-en='Slider
            '
            +            
            +                data-es='Barra deslizante
            '
            +            
            +                data-hi='स्लाइडर
            '
            +            
            +                data-ko='슬라이더
            '
            +            
            +                data-zh-Hans='Slider
            '
            +            
            +          >Slider
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-modifying-the-dom
            .html"
            +            
            +                data-en='Modifying the DOM
            '
            +            
            +                data-es='Modificar el DOM
            '
            +            
            +                data-hi='डोम को संशोधित करना
            '
            +            
            +                data-ko='DOM 변경
            '
            +            
            +                data-zh-Hans='Modifying the DOM
            '
            +            
            +          >Modifying the DOM
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video
            .html"
            +            
            +                data-en='Video
            '
            +            
            +                data-es='Video
            '
            +            
            +                data-hi='वीडियो
            '
            +            
            +                data-ko='비디오
            '
            +            
            +                data-zh-Hans='Video
            '
            +            
            +          >Video
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-canvas
            .html"
            +            
            +                data-en='Video Canvas
            '
            +            
            +                data-es='Lienzo y video
            '
            +            
            +                data-hi='वीडियो कैनवास
            '
            +            
            +                data-ko='비디오 캔버스
            '
            +            
            +                data-zh-Hans='Video Canvas
            '
            +            
            +          >Video Canvas
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-pixels
            .html"
            +            
            +                data-en='Video Pixels
            '
            +            
            +                data-es='Pixeles de video
            '
            +            
            +                data-hi='वीडियो पिक्सल
            '
            +            
            +                data-ko='비디오 픽셀
            '
            +            
            +                data-zh-Hans='Video Pixels
            '
            +            
            +          >Video Pixels
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-video-capture
            .html"
            +            
            +                data-en='Video Capture
            '
            +            
            +                data-es='Captura de video
            '
            +            
            +                data-hi='वीडियो कैप्चर
            '
            +            
            +                data-ko='실시간 비디오
            '
            +            
            +                data-zh-Hans='Video Capture
            '
            +            
            +          >Video Capture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-drop
            .html"
            +            
            +                data-en='Drop
            '
            +            
            +                data-es='Arrojar
            '
            +            
            +                data-hi='छोड़ देना
            '
            +            
            +                data-ko='드롭 기능
            '
            +            
            +                data-zh-Hans='Drop
            '
            +            
            +          >Drop
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="dom-dom-form-elements
            .html"
            +            
            +                data-en='DOM Form Elements
            '
            +            
            +                data-es='DOM Form Elements
            '
            +            
            +                data-ko='DOM Form Elements
            '
            +            
            +                data-zh-Hans='DOM Form Elements
            '
            +            
            +          >DOM Form Elements
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='drawing' class='anchor'>Drawing</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="drawing-continuous-lines
            .html"
            +            
            +                data-en='Continuous Lines
            '
            +            
            +                data-es='Líneas continuas
            '
            +            
            +                data-hi='सतत रेखा 
            '
            +            
            +                data-ko='연속된 선
            '
            +            
            +                data-zh-Hans='Líneas continuas
            '
            +            
            +          >Continuous Lines
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-patterns
            .html"
            +            
            +                data-en='Patterns
            '
            +            
            +                data-es='Patrones
            '
            +            
            +                data-hi='पैटर्न
            '
            +            
            +                data-ko='패턴
            '
            +            
            +                data-zh-Hans='Patrones
            '
            +            
            +          >Patterns
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="drawing-pulses
            .html"
            +            
            +                data-en='Pulses
            '
            +            
            +                data-es='Pulsos
            '
            +            
            +                data-hi='दालें
            '
            +            
            +                data-ko='율동
            '
            +            
            +                data-zh-Hans='Pulsos
            '
            +            
            +          >Pulses
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='transform' class='anchor'>Transform</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="transform-translate
            .html"
            +            
            +                data-en='Translate
            '
            +            
            +                data-es='Translate
            '
            +            
            +                data-hi='अनुवाद
            '
            +            
            +                data-ko='위치 이동(Translate)
            '
            +            
            +                data-zh-Hans='Translate
            '
            +            
            +          >Translate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-scale
            .html"
            +            
            +                data-en='Scale
            '
            +            
            +                data-es='Escalar
            '
            +            
            +                data-hi='स्केल
            '
            +            
            +                data-ko='크기 조정(Scale)
            '
            +            
            +                data-zh-Hans='Scale
            '
            +            
            +          >Scale
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-rotate
            .html"
            +            
            +                data-en='Rotate
            '
            +            
            +                data-es='Rotate
            '
            +            
            +                data-hi='घुमाएँ
            '
            +            
            +                data-ko='회전(Rotate)
            '
            +            
            +                data-zh-Hans='Rotate
            '
            +            
            +          >Rotate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="transform-arm
            .html"
            +            
            +                data-en='Arm
            '
            +            
            +                data-es='Brazo
            '
            +            
            +                data-hi='आर्म
            '
            +            
            +                data-ko='팔모양
            '
            +            
            +                data-zh-Hans='Arm
            '
            +            
            +          >Arm
            </a><br>
            +          
            +        
            +        </p>
            +        
            +          </div>
            +          <div class="column_2 column">
            +        
            +      
            +        <h3 name='typography' class='anchor'>Typography</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="typography-letters
            .html"
            +            
            +                data-en='Letters
            '
            +            
            +                data-es='Letters
            '
            +            
            +                data-hi='पत्र
            '
            +            
            +                data-ko='글자
            '
            +            
            +                data-zh-Hans='Letters
            '
            +            
            +          >Letters
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-words
            .html"
            +            
            +                data-en='Words
            '
            +            
            +                data-es='Words
            '
            +            
            +                data-hi='शब्द
            '
            +            
            +                data-ko='단어
            '
            +            
            +                data-zh-Hans='Words
            '
            +            
            +          >Words
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="typography-text-rotation
            .html"
            +            
            +                data-en='Text Rotation
            '
            +            
            +                data-es='Text Rotation
            '
            +            
            +                data-ko='텍스트 회전
            '
            +            
            +                data-zh-Hans='Text Rotation
            '
            +            
            +          >Text Rotation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='3d' class='anchor'>3D</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="3d-geometries
            .html"
            +            
            +                data-en='Geometries
            '
            +            
            +                data-es='Geometrías
            '
            +            
            +                data-hi='ज्यामिति
            '
            +            
            +                data-ko='기하
            '
            +            
            +                data-zh-Hans='Geometries
            '
            +            
            +          >Geometries
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-sine-cosine-in-3d
            .html"
            +            
            +                data-en='Sine Cosine in 3D
            '
            +            
            +                data-es='Seno Coseno en 3D
            '
            +            
            +                data-hi='3D में साइन कोसाइन
            '
            +            
            +                data-ko='3D속 사인 코사인
            '
            +            
            +                data-zh-Hans='Sine Cosine in 3D
            '
            +            
            +          >Sine Cosine in 3D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-multiple-lights
            .html"
            +            
            +                data-en='Multiple Lights
            '
            +            
            +                data-es='Múltiples luces
            '
            +            
            +                data-hi='मल्टीपल लाइट्स
            '
            +            
            +                data-ko='복수의 조명들
            '
            +            
            +                data-zh-Hans='Multiple Lights
            '
            +            
            +          >Multiple Lights
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-materials
            .html"
            +            
            +                data-en='Materials
            '
            +            
            +                data-es='Materiales
            '
            +            
            +                data-hi='सामग्री
            '
            +            
            +                data-ko='재질(Materials)
            '
            +            
            +                data-zh-Hans='Materials
            '
            +            
            +          >Materials
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-textures
            .html"
            +            
            +                data-en='Textures
            '
            +            
            +                data-es='Texturas
            '
            +            
            +                data-hi='बनावट
            '
            +            
            +                data-ko='텍스처
            '
            +            
            +                data-zh-Hans='Textures
            '
            +            
            +          >Textures
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-ray-casting
            .html"
            +            
            +                data-en='Ray Casting
            '
            +            
            +                data-es='Ray Casting
            '
            +            
            +                data-hi='रे कास्टिंग
            '
            +            
            +                data-ko='레이 캐스팅
            '
            +            
            +                data-zh-Hans='Ray Casting
            '
            +            
            +          >Ray Casting
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-orbit-control
            .html"
            +            
            +                data-en='Orbit Control
            '
            +            
            +                data-es='Control de órbita
            '
            +            
            +                data-hi='कक्षा नियंत्रण
            '
            +            
            +                data-ko='궤도 제어
            '
            +            
            +                data-zh-Hans='Orbit Control
            '
            +            
            +          >Orbit Control
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-basic-shader
            .html"
            +            
            +                data-en='Basic Shader
            '
            +            
            +                data-es='Basic Shader
            '
            +            
            +                data-hi='बेसिक शेडर
            '
            +            
            +                data-ko='셰이더 기초
            '
            +            
            +                data-zh-Hans='Basic Shader
            '
            +            
            +          >Basic Shader
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-as-a-texture
            .html"
            +            
            +                data-en='Shader as a Texture
            '
            +            
            +                data-es='Shader as a Texture
            '
            +            
            +                data-hi='शेडर एक बनावट के रूप में
            '
            +            
            +                data-ko='셰이더로 텍스처 만들기
            '
            +            
            +                data-zh-Hans='Shader as a Texture
            '
            +            
            +          >Shader as a Texture
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-passing-shader-uniforms
            .html"
            +            
            +                data-en='Passing Shader Uniforms
            '
            +            
            +                data-es='Passing Shader Uniforms
            '
            +            
            +                data-hi='पासिंग शेडर यूनिफॉर्म
            '
            +            
            +                data-ko='셰이더 유니폼
            '
            +            
            +                data-zh-Hans='Passing Shader Uniforms
            '
            +            
            +          >Passing Shader Uniforms
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="3d-shader-using-webcam
            .html"
            +            
            +                data-en='Shader Using Webcam
            '
            +            
            +                data-es='Shader Using Webcam
            '
            +            
            +                data-hi='Shader वेबकैम का उपयोग कर रहा है
            '
            +            
            +                data-ko='웹캠을 사용한 셰이더
            '
            +            
            +                data-zh-Hans='Shader Using Webcam
            '
            +            
            +          >Shader Using Webcam
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='input' class='anchor'>Input</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="input-clock
            .html"
            +            
            +                data-en='Clock
            '
            +            
            +                data-es='Clock
            '
            +            
            +                data-hi='घड़ी
            '
            +            
            +                data-ko='시계
            '
            +            
            +                data-zh-Hans='Clock
            '
            +            
            +          >Clock
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-constrain
            .html"
            +            
            +                data-en='Constrain
            '
            +            
            +                data-es='Constrain
            '
            +            
            +                data-hi='बाधा
            '
            +            
            +                data-ko='제한
            '
            +            
            +                data-zh-Hans='Constrain
            '
            +            
            +          >Constrain
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-easing
            .html"
            +            
            +                data-en='Easing
            '
            +            
            +                data-es='Easing
            '
            +            
            +                data-hi='आसान
            '
            +            
            +                data-ko='이징(Easing)
            '
            +            
            +                data-zh-Hans='Easing
            '
            +            
            +          >Easing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-keyboard
            .html"
            +            
            +                data-en='Keyboard
            '
            +            
            +                data-es='Keyboard
            '
            +            
            +                data-hi='कीबोर्ड
            '
            +            
            +                data-ko='키보드
            '
            +            
            +                data-zh-Hans='Keyboard
            '
            +            
            +          >Keyboard
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-milliseconds
            .html"
            +            
            +                data-en='Milliseconds
            '
            +            
            +                data-es='Mouse 1D
            '
            +            
            +                data-hi='माउस 1D
            '
            +            
            +                data-ko='1D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 1D
            '
            +            
            +          >Milliseconds
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-1d
            .html"
            +            
            +                data-en='Mouse 1D
            '
            +            
            +                data-es='Mouse 2D
            '
            +            
            +                data-hi='माउस 2D
            '
            +            
            +                data-ko='2D 마우스
            '
            +            
            +                data-zh-Hans='Mouse 2D
            '
            +            
            +          >Mouse 1D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-2d
            .html"
            +            
            +                data-en='Mouse 2D
            '
            +            
            +                data-es='Mouse Press
            '
            +            
            +                data-hi='माउस प्रेस
            '
            +            
            +                data-ko='마우스 버튼
            '
            +            
            +                data-zh-Hans='Mouse Press
            '
            +            
            +          >Mouse 2D
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-functions
            .html"
            +            
            +                data-en='Mouse Functions
            '
            +            
            +                data-es='Mouse Functions
            '
            +            
            +                data-hi='माउस फंक्शन्स
            '
            +            
            +                data-ko='마우스 함수
            '
            +            
            +                data-zh-Hans='Mouse Functions
            '
            +            
            +          >Mouse Functions
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-signals
            .html"
            +            
            +                data-en='Mouse Signals
            '
            +            
            +                data-es='Mouse Signals
            '
            +            
            +                data-hi='माउस सिग्नल
            '
            +            
            +                data-ko='마우스 신호
            '
            +            
            +                data-zh-Hans='Mouse Signals
            '
            +            
            +          >Mouse Signals
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-mouse-press
            .html"
            +            
            +                data-en='Mouse Press
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-hi='भंडारण इनपुट
            '
            +            
            +                data-ko='입력값 저장
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Mouse Press
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-rollover
            .html"
            +            
            +                data-en='Rollover
            '
            +            
            +                data-es='Rollover
            '
            +            
            +                data-ko='롤오버 (Rollover)
            '
            +            
            +                data-zh-Hans='Rollover
            '
            +            
            +          >Rollover
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="input-storing-input
            .html"
            +            
            +                data-en='Storing Input
            '
            +            
            +                data-es='Storing Input
            '
            +            
            +                data-ko='Storing Input
            '
            +            
            +                data-zh-Hans='Storing Input
            '
            +            
            +          >Storing Input
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='advanced_data' class='anchor'>Advanced Data</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-json
            .html"
            +            
            +                data-en='Load Saved JSON
            '
            +            
            +                data-es='Load Saved JSON
            '
            +            
            +                data-hi='लोड सेव किया गया JSON
            '
            +            
            +                data-ko='저장된 JSON 불러오기
            '
            +            
            +                data-zh-Hans='Load Saved JSON
            '
            +            
            +          >Load Saved JSON
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="advanced-data-load-saved-table
            .html"
            +            
            +                data-en='Load Saved Table
            '
            +            
            +                data-es='Load Saved Table
            '
            +            
            +                data-ko='Load Saved Table
            '
            +            
            +                data-zh-Hans='Load Saved Table
            '
            +            
            +          >Load Saved Table
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='sound' class='anchor'>音频</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="sound-load-and-play-sound
            .html"
            +            
            +                data-en='Load/Play Sound
            '
            +            
            +                data-es='Cargar y reproducir sonido
            '
            +            
            +                data-hi='लोड और प्ले साउंड
            '
            +            
            +                data-ko='사운드 불러오기/재생
            '
            +            
            +                data-zh-Hans='Load and Play Sound
            '
            +            
            +          >Load/Play Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-preload-soundfile
            .html"
            +            
            +                data-en='Preload SoundFile
            '
            +            
            +                data-es='Precargar archivo de sonido
            '
            +            
            +                data-hi='प्रीलोड साउंडफाइल
            '
            +            
            +                data-ko='사운드 파일 미리 불러오기
            '
            +            
            +                data-zh-Hans='Preload SoundFile
            '
            +            
            +          >Preload SoundFile
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-soundformats
            .html"
            +            
            +                data-en='soundFormats
            '
            +            
            +                data-es='Formatos de sonido
            '
            +            
            +                data-hi='ध्वनि प्रारूप
            '
            +            
            +                data-ko='사운드 파일 형식
            '
            +            
            +                data-zh-Hans='soundFormats
            '
            +            
            +          >soundFormats
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-play-mode
            .html"
            +            
            +                data-en='Play Mode
            '
            +            
            +                data-es='Modo de reproducción
            '
            +            
            +                data-hi='प्ले मोड
            '
            +            
            +                data-ko='재생 모드
            '
            +            
            +                data-zh-Hans='Play Mode
            '
            +            
            +          >Play Mode
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-pan-sound
            .html"
            +            
            +                data-en='Pan Sound
            '
            +            
            +                data-es='Paneo
            '
            +            
            +                data-hi='पैन साउंड
            '
            +            
            +                data-ko='사운드 패닝
            '
            +            
            +                data-zh-Hans='Pan Sound
            '
            +            
            +          >Pan Sound
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-sound-effect
            .html"
            +            
            +                data-en='Sound Effect
            '
            +            
            +                data-es='Efecto de sonido
            '
            +            
            +                data-hi='ध्वनि प्रभाव
            '
            +            
            +                data-ko='사운드 효과
            '
            +            
            +                data-zh-Hans='Sound Effect
            '
            +            
            +          >Sound Effect
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-playback-rate
            .html"
            +            
            +                data-en='Playback Rate
            '
            +            
            +                data-es='Tasa de reproducción
            '
            +            
            +                data-hi='प्लेबैक दर
            '
            +            
            +                data-ko='재생 속도
            '
            +            
            +                data-zh-Hans='Playback Rate
            '
            +            
            +          >Playback Rate
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-measuring-amplitude
            .html"
            +            
            +                data-en='Measuring Amplitude
            '
            +            
            +                data-es=' Midiendo la amplitud
            '
            +            
            +                data-hi='मापने वाला आयाम
            '
            +            
            +                data-ko='진폭 측정
            '
            +            
            +                data-zh-Hans='Measuring Amplitude
            '
            +            
            +          >Measuring Amplitude
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-noise-drum-envelope
            .html"
            +            
            +                data-en='Noise Drum Envelope
            '
            +            
            +                data-es='Tambor con envolvente y ruido
            '
            +            
            +                data-hi='शोर ड्रम लिफाफा
            '
            +            
            +                data-ko='노이즈 드럼 엔벨로프
            '
            +            
            +                data-zh-Hans='Noise Drum Envelope
            '
            +            
            +          >Noise Drum Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-note-envelope
            .html"
            +            
            +                data-en='Note Envelope
            '
            +            
            +                data-es=' Envolvente de nota
            '
            +            
            +                data-hi='नोट लिफाफा
            '
            +            
            +                data-ko='음계 엔벨로프
            '
            +            
            +                data-zh-Hans='Note Envelope
            '
            +            
            +          >Note Envelope
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-oscillator-frequency
            .html"
            +            
            +                data-en='Oscillator Frequency
            '
            +            
            +                data-es='Frecuencia de oscilador
            '
            +            
            +                data-hi='थरथरानवाला आवृत्ति
            '
            +            
            +                data-ko='오실레이터 주파수
            '
            +            
            +                data-zh-Hans='Oscillator Frequency
            '
            +            
            +          >Oscillator Frequency
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-input
            .html"
            +            
            +                data-en='Mic Input
            '
            +            
            +                data-es='Entrada de micrófono
            '
            +            
            +                data-hi='Mic Input
            '
            +            
            +                data-ko='마이크 입력
            '
            +            
            +                data-zh-Hans='Mic Input
            '
            +            
            +          >Mic Input
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-spectrum
            .html"
            +            
            +                data-en='Frequency Spectrum
            '
            +            
            +                data-es='Espectro de frecuencia
            '
            +            
            +                data-hi='फ्रीक्वेंसी स्पेक्ट्रम Spec
            '
            +            
            +                data-ko='주파수 스펙트럼
            '
            +            
            +                data-zh-Hans='Frequency Spectrum
            '
            +            
            +          >Frequency Spectrum
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-mic-threshold
            .html"
            +            
            +                data-en='Mic Threshold
            '
            +            
            +                data-es='Umbral de micrófono
            '
            +            
            +                data-hi='माइक थ्रेशोल्ड
            '
            +            
            +                data-ko='마이크 임계값
            '
            +            
            +                data-zh-Hans='Mic Threshold
            '
            +            
            +          >Mic Threshold
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-lowpass
            .html"
            +            
            +                data-en='Filter LowPass
            '
            +            
            +                data-es=' Filtro pasabajos
            '
            +            
            +                data-hi='फ़िल्टर लोपास
            '
            +            
            +                data-ko='로우패스 필터
            '
            +            
            +                data-zh-Hans='Filter LowPass
            '
            +            
            +          >Filter LowPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-filter-bandpass
            .html"
            +            
            +                data-en='Filter BandPass
            '
            +            
            +                data-es=' Filtro pasabanda
            '
            +            
            +                data-hi='फ़िल्टर बैंडपास
            '
            +            
            +                data-ko='밴드패스 필터
            '
            +            
            +                data-zh-Hans='Filter BandPass
            '
            +            
            +          >Filter BandPass
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-delay
            .html"
            +            
            +                data-en='Delay
            '
            +            
            +                data-es=' Delay
            '
            +            
            +                data-hi='देरी
            '
            +            
            +                data-ko='딜레이 필터
            '
            +            
            +                data-zh-Hans='Delay
            '
            +            
            +          >Delay
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-reverb
            .html"
            +            
            +                data-en='Reverb
            '
            +            
            +                data-es=' Reverb
            '
            +            
            +                data-hi='रेवरब
            '
            +            
            +                data-ko='리버브
            '
            +            
            +                data-zh-Hans='Reverb
            '
            +            
            +          >Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-convolution-reverb
            .html"
            +            
            +                data-en='Convolution Reverb
            '
            +            
            +                data-es=' Reverb de convolución
            '
            +            
            +                data-hi='कनवल्शन रेवरब
            '
            +            
            +                data-ko='컨볼루션 리버브
            '
            +            
            +                data-zh-Hans='Convolution Reverb
            '
            +            
            +          >Convolution Reverb
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-record-save-audio
            .html"
            +            
            +                data-en='Record Save Audio
            '
            +            
            +                data-es=' Graba y almacena audio
            '
            +            
            +                data-hi='रिकॉर्ड ऑडियो सहेजें
            '
            +            
            +                data-ko='오디오 녹음/저장
            '
            +            
            +                data-zh-Hans='Record Save Audio
            '
            +            
            +          >Record Save Audio
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-frequency-modulation
            .html"
            +            
            +                data-en='Frequency Modulation
            '
            +            
            +                data-es='Modulación en frecuencia
            '
            +            
            +                data-hi='फ़्रीक्वेंसी मॉडुलन
            '
            +            
            +                data-ko='주파수 변조(FM)
            '
            +            
            +                data-zh-Hans='Frequency Modulation
            '
            +            
            +          >Frequency Modulation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="sound-amplitude-modulation
            .html"
            +            
            +                data-en='Amplitude Modulation
            '
            +            
            +                data-es='Modulación en amplitud
            '
            +            
            +                data-hi='आयाम मॉडुलन
            '
            +            
            +                data-ko='진폭 변조(AM)
            '
            +            
            +                data-zh-Hans='Amplitude Modulation
            '
            +            
            +          >Amplitude Modulation
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='mobile' class='anchor'>移动设备</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-ball-bounce
            .html"
            +            
            +                data-en='Acceleration Ball Bounce
            '
            +            
            +                data-es='Pelota rebote aceleración
            '
            +            
            +                data-hi='एक्सेलेरेशन बॉल बाउंस
            '
            +            
            +                data-ko='가속도와 바운스
            '
            +            
            +                data-zh-Hans='Acceleration Ball Bounce
            '
            +            
            +          >Acceleration Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-simple-draw
            .html"
            +            
            +                data-en='Simple Draw
            '
            +            
            +                data-es='Dibujo simple
            '
            +            
            +                data-hi='सिंपल ड्रा
            '
            +            
            +                data-ko='간단한 드로잉
            '
            +            
            +                data-zh-Hans='Simple Draw
            '
            +            
            +          >Simple Draw
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-acceleration-color
            .html"
            +            
            +                data-en='Acceleration Color
            '
            +            
            +                data-es='Aceleración y color
            '
            +            
            +                data-hi='त्वरण रंग
            '
            +            
            +                data-ko='가속도 색상
            '
            +            
            +                data-zh-Hans='Acceleration Color
            '
            +            
            +          >Acceleration Color
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-shake-ball-bounce
            .html"
            +            
            +                data-en='Shake Ball Bounce
            '
            +            
            +                data-es='Pelota rebote agitar
            '
            +            
            +                data-hi='शेक बॉल बाउंस
            '
            +            
            +                data-ko='흔들기와 바운스
            '
            +            
            +                data-zh-Hans='Shake Ball Bounce
            '
            +            
            +          >Shake Ball Bounce
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="mobile-tilted-3d-box
            .html"
            +            
            +                data-en='Tilted 3D Box
            '
            +            
            +                data-es='Caja 3D
            '
            +            
            +                data-hi='झुका हुआ 3D बॉक्स
            '
            +            
            +                data-ko='기울어진 3D상자
            '
            +            
            +                data-zh-Hans='Tilted 3D Box
            '
            +            
            +          >Tilted 3D Box
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +        <h3 name='hello_p5' class='anchor'>Hello p5</h3>
            +        <p>
            +        
            +          <a class='js-lang example-link' href="hello-p5-simple-shapes
            .html"
            +            
            +                data-en='Simple Shapes
            '
            +            
            +                data-es='Figuras simples
            '
            +            
            +                data-hi='सरल आकार
            '
            +            
            +                data-ko='간단한 도형들
            '
            +            
            +                data-zh-Hans='Simple Shapes
            '
            +            
            +          >Simple Shapes
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-1
            .html"
            +            
            +                data-en='Interactivity 1
            '
            +            
            +                data-es='Interactividad 1
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 1
            '
            +            
            +                data-ko='인터랙티비티 1
            '
            +            
            +                data-zh-Hans='Interactivity 1
            '
            +            
            +          >Interactivity 1
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-interactivity-2
            .html"
            +            
            +                data-en='Interactivity 2
            '
            +            
            +                data-es='Interactividad 2
            '
            +            
            +                data-hi='अन्तरक्रियाशीलता 2
            '
            +            
            +                data-ko='인터랙티비티 2
            '
            +            
            +                data-zh-Hans='Interactivity 2
            '
            +            
            +          >Interactivity 2
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-animation
            .html"
            +            
            +                data-en='Animation
            '
            +            
            +                data-es='Animación
            '
            +            
            +                data-hi='एनिमेशन
            '
            +            
            +                data-ko='애니메이션
            '
            +            
            +                data-zh-Hans='Animation
            '
            +            
            +          >Animation
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-flocking
            .html"
            +            
            +                data-en='Flocking
            '
            +            
            +                data-es='Flocking
            '
            +            
            +                data-hi='झुंड
            '
            +            
            +                data-ko='플로킹
            '
            +            
            +                data-zh-Hans='Flocking
            '
            +            
            +          >Flocking
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-weather
            .html"
            +            
            +                data-en='Weather
            '
            +            
            +                data-es='Clima
            '
            +            
            +                data-hi='मौसम
            '
            +            
            +                data-ko='날씨
            '
            +            
            +                data-zh-Hans='Weather
            '
            +            
            +          >Weather
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-drawing
            .html"
            +            
            +                data-en='Drawing
            '
            +            
            +                data-es='Dibujar
            '
            +            
            +                data-hi='ड्राइंग
            '
            +            
            +                data-ko='드로잉
            '
            +            
            +                data-zh-Hans='Drawing
            '
            +            
            +          >Drawing
            </a><br>
            +          
            +        
            +          <a class='js-lang example-link' href="hello-p5-song
            .html"
            +            
            +                data-en='Song
            '
            +            
            +                data-es='Canción
            '
            +            
            +                data-hi='गीत
            '
            +            
            +                data-ko='노래
            '
            +            
            +                data-zh-Hans='Song
            '
            +            
            +          >Song
            </a><br>
            +          
            +        
            +        </p>
            +        
            +      
            +      </div>
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/get-started/index.html b/dist/zh-Hans/get-started/index.html
            new file mode 100644
            index 0000000000..1d4da0b995
            --- /dev/null
            +++ b/dist/zh-Hans/get-started/index.html
            @@ -0,0 +1,344 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">get started | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="get-started-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +
            +      <h1>入门</h1>
            +
            +      <p>This page walks you through setting up a p5.js project and making your first sketch. The easiest way to start is using the  <a href="https://editor.p5js.org" target="_blank">p5.js editor</a>, you can open the web editor and can scroll down to  <a href="#sketch">Your First Sketch</a>. If you would like to work on the the desktop version of p5.js you can scroll down to <a href="#settingUp">downloading instructions</a>.
            +      </p>
            +
            +
            +
            +      <h2 class="start-element" id="sketch">Your First Sketch</h2>
            +
            +      <div class="info">
            +        <h3 class="sr-only">Code snippet with ellipse</h3>
            +        <p>In the <a href='https://editor.p5js.org/'>p5.js web editor</a> you should find the following code:</p>
            +
            +<pre id="first-sketch1"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch1" class="copy_button">Copy</button>
            +        </div>
            +        <p>After the <code class="language-javascript">background(220);</code> include this line of code: <code class="language-javascript">ellipse(50,50,80,80);</code>.</p>
            +
            +        <p>Now your code should be like this: </p>
            +        <h3 class="sr-only">Code snippet with ellipse</h3>
            +
            +<pre id="first-sketch2"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  background(220);
            +  ellipse(50,50,80,80);
            +}
            +
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch2" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">The line you just added draws an ellipse, with its center 50 pixels over from the left and 50 pixels down from the top, with a width and height of 80 pixels.</p>
            +        <p>On the editor press play to display your code in action!</p>
            +        <h3 class="sr-only">Note for screenreader users</h3>
            +        <p>If you are using a screen reader, you must turn on the accessible outputs in the p5 online editor, outside the editor you must add the accessibility library in your html. To learn more visit<a href="../learn/p5-screen-reader.html" target="_blank">using p5 with a screen reader tutorial.</a>
            +        </p>
            +        <p>If you've typed everything correctly, this will appear in the display window:</p>
            +
            +        <img src="../../assets/img/get-started/first-sketch.png" alt='canvas has a circle of width and height 50 at position 80 x and 80 y'/>
            +
            +        <p>If nothing appears, the editor may be having trouble understanding what you’ve typed. If this happens, make sure that you've copied the example code exactly: the numbers should be contained within parentheses and have commas between each of them, the line should end with a semicolon, and ellipse has to be spelled correctly.</p>
            +
            +        <p>One of the most difficult things about getting started with programming is that you have to be very specific about the syntax. The browser isn't always smart enough to know what you mean, and can be quite fussy about the placement of punctuation. You'll get used to it with a little practice. In the bottom left of the editor you will find the console section. Here, you can find messages from the editor with details about any errors it encounters.</p>
            +
            +        <h3 class="sr-only">Code snippet with interaction</h3>
            +        <p>Next, we'll skip ahead to a sketch that's a little more exciting. Modify the last example to try this:</p>
            +
            +<pre id="first-sketch3"><code class="language-javascript">
            +function setup() {
            +  createCanvas(400, 400);
            +}
            +
            +function draw() {
            +  if (mouseIsPressed) {
            +    fill(0);
            +  } else {
            +    fill(255);
            +  }
            +  ellipse(mouseX, mouseY, 80, 80);
            +}
            +</code></pre>
            +        <div class="edit_space">
            +          <button id="copy_sketch3" class="copy_button">Copy</button>
            +        </div>
            +        <p style="margin-top: 1.5em;">This program creates a canvas that is 400 pixels wide and 400 pixels high, and then starts drawing white circles at the position of the mouse. When a mouse button is pressed, the circle color changes to black. Run the code, move the mouse, and click to experience it.
            +        </p>
            +
            +        <img src="../../assets/img/get-started/first-sketch2.png" alt='canvas has multiple circles drawn on it following the path of the mouse'/>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="next">下一步</h2>
            +
            +      <div class='info'>
            +        <ul class="list_view">
            +          <li>Check out the <a href="../learn/">learn page</a> and <a href="../examples">examples page</a> for more.</li>
            +
            +          <li>Watch <a href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6Zy51Q-x9tMWIv9cueOFTFA">The Coding Train</a> and <a href="https://www.kadenze.com/courses/introduction-to-programming-for-the-visual-arts-with-p5-js/info">Kadenze</a> video tutorials.</li>
            +
            +          <li>View the <a href="../reference/"> reference</a> for full documentation. </li>
            +          <li>If you wish to use p5 with a screenreader, check out the <a href="../learn/p5-screen-reader.html">p5 with a screenreader tutorial</a>.</li>
            +          <li>If you have used Processing in the past, read the <a href='https://github.com/processing/p5.js/wiki/Processing-transition'>Processing transition tutorial</a> to learn how to convert from Processing to p5.js, and the main differences between them.</li>
            +
            +        </ul>
            +      </div>
            +
            +      <h2 class="start-element tutorial-btn" id="settingUp">Setting up p5.js with an editor on your own computer</h2>
            +
            +      <div class="info">
            +        <p>您可以使用任何
            +          <a href='https://zh.wikipedia.org/wiki/%E6%BA%90%E4%BB%A3%E7%A0%81%E7%BC%96%E8%BE%91%E5%99%A8' target="_blank">
            +            代码编程器</a>
            +            。以下为设置
            +            <a href="http://www.sublimetext.com/2" target="_blank"> Sublime Text 2</a>
            +            的步骤。其他不错的代码编程器包括<a href='http://brackets.io/' target=_blank>Brackets</a> 和<a href='https://atom.io/' target=_blank>Atom</a>. 如果您使用荧幕阅读器但不使用 p5 Editor,您可考虑使用  <a href="https://notepad-plus-plus.org/">Notepad++</a>  或 
            +            <a href="https://www.eclipse.org/ide/" target="_blank">Eclipse</a>.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="download">Downloading a copy of the p5.js library</h3>
            +
            +      <div class="info">
            +        <p>最简易的起点是使用
            +          <a href="../download/">p5.js 完整版</a>
            +          下载所提供的空白范例。
            +        </p>
            +
            +        <p>
            +          After download, you need to set up a local server. See instructions 
            +          <a href="https://github.com/processing/p5.js/wiki/Local-server" target="_blank">here</a>
            +          . Run your local server within the downloaded folder and on your browser, go to
            +          <code>http://localhost:{your-port-num}/empty-example</code>
            +        </p>
            +
            +        <p>查看 index.html 您可以发现其中有个 p5.js 的链接。如果您想要使用极简化的档案(以加速网页加载的速度),将链接档案名改为 p5.min.js</p>
            +
            +        <pre id="markup1"><code class="language-markup">&lt;script src="../p5.min.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_script" class="copy_button">Copy</button>
            +        </div>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="hosted">Using a hosted version of the p5.js library</h3>
            +      <div class="info">
            +        <p>另外,您也可以选择链接去网络上的 p5.js 文档。所有 p5.js 版本都被上载到多个 CDN (Content Delivery Network) 上,您可在此链接参考所有 p5.js 版本:
            +          <a target="_blank" href="https://cdn.jsdelivr.net/npm/p5/lib/">
            +            p5.js CDN</a>。接下来您只需要将链接改为:
            +        </p>
            +
            +        <pre id="cdn-link" class='p5-replace'><code class="language-markup">&lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script></code></pre>
            +        <div class="edit_space">
            +          <button id="copy_p5_link" class="copy_button">Copy</button>
            +        </div>
            +        <p>一个极简但完整的 HTML 档案如下:</p>
            +
            +        <pre id="sample-html" class='p5-replace'><code class="language-markup">
            +&lt;html&gt;
            +  &lt;head&gt;
            +    &lt;script src="https://cdn.jsdelivr.net/npm/p5@[p5_version]/lib/p5.js">&lt;/script&gt;
            +    &lt;script src="sketch.js">&lt;/script&gt;
            +  &lt;/head&gt;
            +  &lt;body&gt;
            +    &lt;main&gt;
            +    &lt;/main&gt;
            +  &lt;/body&gt;
            +&lt;/html&gt;
            +        </code></pre>
            +      <div class="edit_space">
            +          <button id="copy_p5_html" class="copy_button">Copy</button>
            +      </div>
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="environment">编程环境</h3>
            +      <div class="info">
            +        <p>
            +          开启 Sublime。选择 File 目录项目然后选择 Open... 接着在对话框中选择含有您的 .html 及 .js 档案的文件夹。在窗口左边的文件栏您应该能看到文件夹的名字在最上方而往下都是该文件夹里面所含的档案。
            +        </p>
            +
            +        <p>
            +          点击 sketch.js 档案即会在右边开启该档案,您也能在这时更改该档案。
            +          <img src="../../assets/img/get-started/sublime2.png" alt='p5 starter code opened up in sublime editor."'/>
            +        </p>
            +
            +        <p>
            +          在文件浏览器内双击 index.html 以在您的网页浏览器内开启该档案,或您也可以直接在网页浏览器内的网址栏输入: <code>file:///html文件在硬盘上的位置/</code>
            +           (or  <code>http://localhost:{your-port-num}/empty-example</code>
            +           if you are using a local server)
            +          以查看您的绘图。
            +        </p>
            +      </div>
            +
            +      <div>Parts of this tutorial were adapted from the book, Getting Started with p5.js, by Lauren McCarthy, Casey Reas, and Ben Fry, O'Reilly / Make 2015. Copyright © 2015. All rights reserved. Last modified at the p5.js 2019 Contributors Conference.</div>
            +
            +      <script>
            +        $.getJSON('../download/version.json', function(data) {
            +          $('.p5-replace').each(function() {
            +            var html = $(this).html().replace('[p5_version]', data.version);
            +            $(this).html(html);
            +          });
            +        });
            +      </script>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +</div><!-- end id="get-started-page"  -->
            +<script src="/../../assets/js/get-started.js"></script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/index.html b/dist/zh-Hans/index.html
            new file mode 100644
            index 0000000000..2f4e4a941f
            --- /dev/null
            +++ b/dist/zh-Hans/index.html
            @@ -0,0 +1,178 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">home | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../assets/img/favicon.ico">
            +    <link rel="icon" href="/../assets/img/favicon.ico">
            +
            +
            +    <script src="/../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +<div id="home-page">
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +    <main id="content" class="home">
            +      <form id="search" method="get" action="https://www.google.com/search">
            +        <input type="hidden" name="as_sitesearch" value="p5js.org">
            +        <input id="search_button" type="submit" aria-label="Search" class='sr-only'>
            +        <input tabindex="2" id='search_field' type="text" size="20" placeholder="Search p5js.org" name="q">
            +        <label class="sr-only" for="search_field">Search p5js.org</label>
            +      </form>
            +
            +      <h1>你好!</h1>
            +      <p style="margin-top:1em">p5.js 是个 JavaScript 创意编程程式库,其专注在让编程更易于使用及更加广泛的包容艺术家、设计师、教育家、初学者以及任何其他人!p5.js 是个免费及开源的软件因为我们相信所有人都应该能自由使用软件及用于学习软件的工具。</p>
            +      <p>p5.js 使用绘图的比喻并有一副完整的绘画功能。除此之外,您也不单限于您的绘图画布。您可以将您整个浏览器页面当作您的绘图,这包括了 HTML5 物件如文字、输入框、视屏、摄像头及音频。</p>
            +      <p><a href="https://discord.gg/SHQ8dH25r9">Join the p5.js Discord!</a></p>
            +      <a href="https://editor.p5js.org"><span class='button_box'>使用 p5 编辑器开始创作!</span></a>
            +
            +      <h2>社群</h2>
            +      <p>我们声援及支持所有人,不论他们来自不同性别认同、性取向、种族、国籍、语言、神经型、大小、能力、阶级、宗教、文化、次文化、政治观点、年龄、技能等级、职业或背景。我们了解并不是所有人都有多余的时间、金钱或能力以活跃的参与社群活动但我们同时认可及鼓励各种参与方式。我们致力于促进障碍消除及培养能力。我们都是学习者。</p>
            +      <p>p5.js 是 <a href="https://processing.org"
            +          target="_blank">Processing</a> 于今日的网页的诠释。我们的活动及运作由 <a href="https://processingfoundation.org"
            +          target="_blank">Processing Foundation</a> 所支持。</p>
            +      <p>了解更多关于<a href="community/">我们的社群</a>。</p>
            +
            +      <h2>入门</h2>
            +      <p>使用 <a href="https://editor.p5js.org" target="_blank">p5.js
            +          Editor</a> 制作您的第一个绘图。以了解更多关于如何使用 p5.js 绘图及其各种功能请参考<a
            +          href="get-started/">入门页面</a>及<a
            +          href="reference/">参考文献</a>。</p>
            +
            +      <h2>参与</h2>
            +      <p>我们有各种方式让您贡献给 p5.js:</p>
            +      <h2 id="involvement-options" class="sr-only">参与方式包括</h2>
            +      <ul aria-labelledby="involvement-options" class="list_view bullets">
            +        <li><a href="/zh-Hans/teach">使用 p5.js 教学。</a></li>
            +        <li><a href="https://day.processing.org" target="_blank">举办个聚会。</a></li>
            +        <li><a href="https://github.com/processing/p5.js/tree/main/contributor_docs"
            +            target="_blank">贡献代码。</a></li>
            +      </ul>
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +  </div> <!-- end column-span -->
            +
            +
            +  <p class="clearfix">&nbsp;</p>
            +
            +  <object tabindex=-1 type="image/svg+xml" data="../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element"
            +    aria-hidden="true">*</object>
            +</div> <!-- end home-page -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/basics.html b/dist/zh-Hans/learn/basics.html
            new file mode 100644
            index 0000000000..4233e4642d
            --- /dev/null
            +++ b/dist/zh-Hans/learn/basics.html
            @@ -0,0 +1,349 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +<style>
            +img {
            +  width: 50%;
            +}
            +</style>
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Basics of Drawing</h1>
            +
            +      <h2>Introduction</h2>
            +      <p>
            +      Today we are going to be learning how to write computer code using a tool called <a href='http://p5js.org' target=_blank>p5</a>. Code is a set of instructions for the computer, telling it something to do. In our case, we will tell it to make a scene with shapes and colors.
            +      </p>
            +
            +
            +      <h2>First Sketch</h2>
            +      <p>
            +      When you open p5, your first sketch will look like this. There are two parts: setup and draw. Inside the curly brackets after setup and draw we will add code to create a drawing.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +
            +}
            +      </script>
            +
            +      <h2>background(red, green, blue)</h2>
            +      <p>
            +      background() sets the background color of your drawing. You give it three numbers that represent the amount of red, green, and blue you want mixed into the background. The numbers range from 0-255.
            +      <span class='try'>Try changing the numbers inside the parentheses to see what happens.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +
            +      <h2>createCanvas(width, height)</h2>
            +      <p>
            +      createCanvas() sets the size of the drawing canvas. By default it is 100x100. You give it two numbers that represent the width and the height that you want your canvas to be.
            +      <span class='try'>Try making your canvas different sizes by changing the width and height.</span>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100)
            +}
            +
            +function draw() {
            +  background(255, 0, 0)
            +}
            +      </script>
            +
            +      <h2>line(x1, y1, x2, y2)</h2>
            +      <p>
            +      line() draws a line on your canvas. You give it four numbers – the x and y position of one end, and the x and y position of the other end.<br>
            +      <img src='../../assets/learn/basics/line.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 200, 255)
            +  line(10, 10, 200, 200)
            +}
            +      </script>
            +
            +      <h2>rect(x, y, width, height)</h2>
            +      <p>
            +      rect() draws a rectangle on your canvas. You give it four numbers – the x position, the y position, the width, and the height. For a rectangle, you give it the x,y position of the top left corner.<br>
            +      <img src='../../assets/learn/basics/rect.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(55, 100, 255)
            +  rect(10, 10, 50, 200)
            +}
            +      </script>
            +
            +      <h2>ellipse(x, y, width, height)</h2>
            +      <p>
            +      To draw a shape, think of your canvas like a piece of graph paper. However, square (0, 0) is in the top left.
            +      <br>
            +      <img src='../../assets/learn/basics/graph.svg'>
            +      ellipse() draws an ellipse on your canvas. You give it four numbers – the x position, the y position, the width, and the height.<br>
            +      <img src='../../assets/learn/basics/ellipse.svg'>
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(255, 0, 255)
            +  ellipse(150, 150, 100, 200)
            +}
            +      </script>
            +
            +      <h2>fill(red, green, blue)</h2>
            +      <p>You can set the color of your shapes by using fill(). You give it three numbers – the red, green, and blue mixture you want, just like background.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>stroke(red, green, blue)</h2>
            +      <p>You can set the outline color of your shapes by using stroke(). You give it three numbers – the red, green, and blue mixture you want, just like fill() and background().
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  stroke(0, 150, 0)
            +  fill(255, 0, 0)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>strokeWeight(weight)</h2>
            +      <p>You can set the thickness of the outline for your shapes by using strokeWeight(). The default stroke weight is 1.
            +      </p>
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  strokeWeight(10)
            +  ellipse(150, 150, 50, 50)
            +}
            +      </script>
            +
            +      <h2>mouseX, mouseY</h2>
            +      <p>mouseX and mouseY can be used to get the current position of your mouse. They are called <b>variables</b>. You can replace a number in your code with mouseX or mouseY and that number will change as you move your mouse.
            +      </p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(0, 255, 255)
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +      <h2>random(max)</h2>
            +      <p>random() will choose a random number for you, anywhere from 0 - max.</p>
            +
            +      <script type="text/p5" data-height="400" data-preview-width="300" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(300, 300)
            +}
            +
            +function draw() {
            +  background(random(255), random(255), random(255))
            +  ellipse(mouseX, mouseY, 50, 50)
            +}
            +      </script>
            +
            +
            +      <h2>Links</h2>
            +      <p><a href='http://p5js.org/reference' target=_blank>Reference</a> – available p5.js variables and functions<br>
            +      <a href='http://p5js.org/examples' target=_blank>Examples</a> – more complicated code examples</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/color.html b/dist/zh-Hans/learn/color.html
            new file mode 100644
            index 0000000000..949388a91b
            --- /dev/null
            +++ b/dist/zh-Hans/learn/color.html
            @@ -0,0 +1,294 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">以下教程来自于由 Daniel Shiffman 篇写的《 Learning Processing 》(原文英文),并由 Morgan Kaufmann 出版,© 2008 Elsevier Inc。版权所有。此教程由 Kelly Chang 移植成 P5 代码。如果您发现任何错误或有任何评论,<a href="https://github.com/processing/p5.js/issues">请联络我们。</a>
            +
            +      </div>
            +
            +      <h1>颜色</h1>
            +
            +      <p>
            +      在数码世界中,当我们要介绍一个颜色时,我们需要有一定的精确度。单纯说“嘿,你能把那圆形变成蓝绿色吗?”并不足够。在这,颜色可以被定义为在一个范围内的数字。让我们从最简单的范例开始:黑白色或灰渐色。0 为纯黑色,255 为纯白色。在两者之间任何数字 – 50、87、162、209 等等 – 都是介于黑与白之间的灰色。
            +      </p>
            +
            +      <img src="../../assets/learn/color/grayscale.svg">
            +
            +      <p>
            +      只要在任何东西被画在画布上之前使用 <a href="/zh-Hans/reference/#/p5/stroke"> stroke()</a> 及 <a href="/zh-Hans/reference/#/p5/fill">fill()</a> 函数,我们能设置任何图形的颜色。我们也能使用 <a href="/zh-Hans/reference/#/p5/background">background()</a> 函数来设定窗口的背景颜色。如下范例。
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        background(255);    // 设置背景颜色为白色
            + stroke(0);          // 设置外线颜色为黑色
            + fill(150);          // 设置填充色为灰色
            + rect(50,50,75,100); // 绘制四方形
            +      </code></pre>
            +
            +      <p>
            +      使用 <a href="/zh-Hans/reference/#/p5/noStroke">noStroke()</a> 及 <a href="/zh-Hans/reference/#/p5/noFill">noFill()</a>函数将会分别去除外线色灰填充色。我们直觉上可能会以为“ stroke(0) ”表示没有外线,可是我们必须记得 0 在这并不代表“无”,然而是代表黑色。此外,我们必须记得不要同时去除<b>noStroke()</b> 及 <b>noFill()</b> 不然不会有任何图形出现在画布上!
            +      </p>
            +
            +      <p>以此同时,如果我们绘制两个图形,p5.js 将会使用最近(代码内从上至下)所定义的外线色及填充色值。</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +  background(150);
            +  stroke(0);
            +  line(0, 0, 100, 100);
            +  stroke(255);
            +  noFill();
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <h2>RGB 颜色值</h2>
            +
            +      <p>
            +      您还记得手指绘画吗?选择混合三原色,我们能混合出任何颜色。同时混合所有颜色的结果是个浑浊的褐色。添加越多颜料,给颜色将会变得更暗。数码颜色也是使用三原色的混合来构造新的颜色的,但是它和颜料的混合原理不一样。首先,其原色为:红、绿、蓝(也为 RGB 颜色,Red、Green、Blue)。而当您在混合荧幕上的颜色时,您将混合的是光而不是颜料,因此它的混合原理并不一样。
            +      </p>
            +
            +      <img src="../../assets/learn/color/rgb.jpg">
            +      <p>
            +        <ul class="list_view">
            +          <li>红 + 绿 = 黄</li>
            +          <li>红 + 蓝 = 紫</li>
            +          <li>绿 + 蓝 = 青(蓝绿色)</li>
            +          <li>红 + 绿 + 蓝 = 白</li>
            +          <li>无色 = 黑</li>
            +        </ul>
            +      </p>
            +
            +      <p>这假设所有色颜色都为最亮的亮度,但是您也能同时使用一系列的颜色值,因此一些红加上一些绿再加上一些蓝将等于灰,而一点红加上一点蓝将等于深紫色。虽然这可能需要一点时间来习惯,随着您编程及使用 RGB 颜色值来试验的经验越多,您会对它越熟悉,就如使用您的手指来混合颜色一样。当然您不能单纯说“混合一些红与一点蓝”,您必须提供确切的数值。就如灰渐值,个别颜色的值也是由介于 0(不使用任何该颜色)与 255(完全使用该颜色)之间,而他们的顺序为红(R)、绿(G)及蓝(B)。通过更多的试验您将会对 RGB 颜色更加熟悉,不过接下来我们将介绍一些使用常用颜色的代码。</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  noStroke();
            +
            +  // Bright red
            +  fill(255,0,0);
            +  ellipse(20,20,16,16);
            +
            +  // Dark red
            +  fill(127,0,0);
            +  ellipse(40,20,16,16);
            +
            +  // Pink (pale red)
            +  fill(255,200,200);
            +  ellipse(60,20,16,16);
            +}
            +      </script>
            +
            +
            +
            +      <h2>颜色透明度</h2>
            +
            +      <p>除了个别颜色的红、绿、蓝值之外,我们也能提供多一个可选性的值,此值被称为该颜色的 “alpha” 值。Alpha 代表透明度,当您要绘制多个重叠部分透视的图形时,透明度在这就特别有用。一个图像的 alpha 值有时也会被称为该图像的 “alpha channel”。</p>
            +      <p>我们必须记得像素并不是真的透明的,这单纯是个使用混合颜色所达成的便利错觉。p5.js 在幕后将会使用该颜色的数值再加上一定百分率的另外一个颜色,创作出混合颜色的视觉错觉。(如果您有兴趣编程一个“粉色镜片”,您可以从这开始。)</p>
            +
            +      <p>Alpha 值也是介于 0 与 255 之间,0 代表完全透明而 255 代表完全不透明。</p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +  createCanvas(100, 100);
            +  fill(0,0,255);
            +  rect(0,0,50,100);
            +
            +  // 255 means 100% opacity.
            +  fill(255,0,0,255);
            +  rect(0,0,100,20);
            +
            +  // 75% opacity.
            +  fill(255,0,0,191);
            +  rect(0,25,100,20);
            +
            +  // 55% opacity.
            +  fill(255,0,0,127);
            +  rect(0,50,100,20);
            +
            +  // 25% opacity.
            +  fill(255,0,0,63);
            +  rect(0,75,100,20);
            +
            +      </script>
            +
            +      <h2>自定义颜色值范围</h2>
            +
            +      <p>
            +      介于 0 与 255 之间的 RGB 颜色值并不是 p5.js 唯一定义颜色的方法,事实上,我们能使用多种方法来定义颜色。比如说,您可能比较偏向于使用 0 至 100(如百分比)来定义颜色。为此您可以使用<a href="/zh-Hans/reference/#/p5/colorMode">colorMode()</a>.
            +      </p>
            +
            +      <pre><code>
            +      colorMode(RGB,100);
            +      </code></pre>
            +
            +      <p>以上函数表示:“OK,我们要使用红、绿、蓝值来定义颜色。而他们的值将介于 0 至 100 之间。</p>
            +
            +      <p>虽然一般上这么做不会提供任何便利,您可以为个别颜色值提供不同的数值范围:</p>
            +
            +      <pre><code>
            +      colorMode(RGB,100,500,10,255);
            +      </code></pre>
            +
            +      <p>这时此函数表示:“红色值将会是介于 0 至 100 之间,绿色值将会是介于 0 至 500 之间,蓝色值将会是介于 0 至 10 之间,而 alpha 至将会是介于 0 至 255 之间。</p>
            +
            +      <p>最后,虽然您通常在编程时只需要用到 RGB 色值,您也能使用 HSB(色调、饱和度及亮度)模式来定义颜色。简单来说,HSB 色值使用方法如下:</p>
            +
            +      <img src="../../assets/learn/color/hsb.png">
            +      <ul class="list_view">
            +        <li><b>色调</b>—色调值,默认上介于 0 至 360 之间。</li>
            +        <li><b>饱和度</b>—该颜色的饱和度,默认上介于 0 至 100 之间。</li>
            +        <li><b>亮度</b>—该颜色的亮度,默认上介于 0 至 100 之间。</li>
            +      </ul>
            +
            +      <p>使用函数 <a href="/zh-Hans/reference/#/p5/colorMode">colorMode()</a> 您就能设定您自选的数字范围。有些人会比较偏好使用介于 0 至 360 之间的数值来定义色调(就如色轮的 360 度一样)及 0 至 100 之间的数值来定义饱和度及亮度(介于 0% 至 100%)。</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/coordinate-system-and-shapes.html b/dist/zh-Hans/learn/coordinate-system-and-shapes.html
            new file mode 100644
            index 0000000000..55b4cbf35b
            --- /dev/null
            +++ b/dist/zh-Hans/learn/coordinate-system-and-shapes.html
            @@ -0,0 +1,280 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      以下教程来自于由 Daniel Shiffman 篇写的《 <em>Learning Processing</em> 》(原文英文),并由 Morgan Kaufmann 出版,© 2008 Elsevier Inc。版权所有。此教程由移植成 P5 代码。如果您发现任何错误或有任何评论,<a href="https://github.com/processing/processing-docs/issues?state=open">请联络我们</a>。</div>
            +
            +      <h1>坐标系统及图形</h1>
            +      <p>在我们开始使用 p5 编程前,我们得先回到我们初中二时的记忆,找出一张坐标纸并画一条直线。两点之间最短的距离正是一条直线,我们将使用坐标纸上的直线的两点作为起点。</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-01.png" alt="">
            +
            +      <p>以上图解显示一条介于点 A (1,0) 及点 B (4,5) 的直线。如果您想要指示您的朋友画出一样的直线,您或许会对他说:“请从点一、零开始画一条直线去点四、五”。 那么现在暂时想象您的朋友是个电脑而您想要指示这位数码朋友如何画在荧幕上出一样的直线。这情况下您也能使用一样的指示(只不过现在您可以跳过任何客气话但是必须使用精准的格式来表达)。该指示将会是如下:</p>
            +
            +      <pre><code class="language-javascript">
            +        line(1,0,4,5);
            +      </code></pre>
            +
            +      <p>就算您还没学习过编写程式的语法,以上的语句应该仍然多少都能理解。我们提供电脑一个指令(我们称这指令为 function 或函数)以让其画出直线(line)。此外,我们也提供一些用于定义该直线的参数:从点 A (1,0) 至点 B (4,5)。 如果您假想这行代码为一个句子,这函数就是个动词而参数就是宾语。这代码句子使用分号作为句尾符号而不是句号。</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-02.png" alt="">
            +
            +      <p>这里关键是了解电脑屏幕就只是个比较花俏的坐标纸。荧幕上每一个像素都代表着一个坐标 - 或两个数字:“x”(横向)及 “y”(纵向)- 代表着在空间内一点的位置。而我们的工作就是指定该在这些像素坐标位置出现的图形及颜色。</p>
            +
            +      <p>不过,这里有个需要注意的东西。那张来自初中二的坐标纸(使用笛卡尔坐标系)将 (0,0) 放置在正中央,y 轴由下至上 x 轴由左至右。但是电脑窗口的坐标系在 y 轴的方向是相反的。(0,0) 被定义在左上角并往右边及往下延伸。</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-03.svg" alt="">
            +
            +      <h2>基本图形</h2>
            +      <p>大多数使用 p5 的编程范例一般都会使视觉上的绘图范例。本质上,这些范例都和绘制图形及设定像素有关。我们将从绘制四种基本图形开始。</p>
            +      <img src="../../assets/learn/coordinate-system-and-shapes/images/drawing-04.png" alt="">
            +
            +      <p>针对每个形状,我们需要问我们需要什么资料才可以定义该图形的位置及大小(更之后其颜色)然后再了解 p5 如何接收这些信息。在以下的绘图内,我们将使用一个宽度为 100 像素及高度为 100 像素的画布。</p>
            +
            +      <p>A <a href="/reference/#/p5/point">point()</a> (点)是最简单的图形同时也是个不错的起点。以绘制一个点(point),我们只需要提供 x 及 y 坐标。</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  point(40, 50); // point(x, y)
            +}
            +</script>
            +
            +      <p>A <a href="/reference/#/p5/line">line()</a> (直线)也不会特别困难,我们只需提供两个点 (x1,y1) 及 (x2,y2):</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  line(10, 20, 50, 20); // line(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>当我们想要绘制一个 <a href="/reference/#/p5/rect">rect()</a> (四方形)时,这就会变得比较复杂一点。在 p5 内,一个四方形是由其左上角的坐标点与其宽度及高度来定义的。</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +}
            +function draw(){
            +  rect(10, 20, 40, 30); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>第二个绘制四方形的方法是定义其中心点的位置,然后定义其宽度及高度。如果我们想要使用这方法,我们必须先表示我们要使用 <a href="/reference/#/p5/CENTER">CENTER</a> 模式然后才输入绘制四方形的指示。请注意 p5 有区分大小写字母。</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(30, 20, 40, 20); // rect(x, y, width, height)
            +}
            +</script>
            +
            +      <p>最后我们也能使用两个点来绘制一个四方形(分别定义左上角及右下角)。这模式为 <a href="/reference/#/p5/CORNERS">CORNERS</a>。请注意这范例在荧幕上显示的结果和上方的范例一样。</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CORNERS);
            +}
            +function draw(){
            +  rect(10, 10, 50, 30); // rect(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>当我们对于绘制一个四方形有了不错的掌握时,绘制一个 <a href="/reference/#/p5/ellipse">ellipse()</a> (椭圆形)可是轻而易举。事实上,它和绘制 <a href="/reference/#/p5/rect">rect()</a> (四方形)一样,唯一不同的是椭圆形将会被绘制在所定义的四方形内。<a href="/reference/#/p5/ellipse">ellipse()</a> 的默认模式为 <a href="/reference/#/p5/CENTER">CENTER</a> 而不是 <a href="/reference/#/p5/CORNER">CORNER</a>。</p>
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CENTER);
            +}
            +function draw(){
            +  ellipse(30, 30, 40, 60); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNER);
            +}
            +function draw(){
            +  ellipse(10, 10, 30, 50); // ellipse(x, y, width, height)
            +}
            +</script>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  ellipseMode(CORNERS);
            +}
            +function draw(){
            +  ellipse(10, 10, 40, 50); // ellipse(x1, y1, x2, y2)
            +}
            +</script>
            +
            +      <p>现在让我们来看看一些使用更实际绘图设置的程式代码。我们将使用一个大小为 200 乘 200 的画布大小。请注意我们这里使用的 createCanvas() 函数内所设定的画布高度及宽度。</p>
            +
            +<script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(200, 200);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  rect(100,100,20,100);
            +  ellipse(100,70,60,60);
            +  ellipse(81,70,16,32);
            +  ellipse(119,70,16,32);
            +  line(90,150,80,160);
            +  line(110,150,120,160);
            +}
            +</script>
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/curves.html b/dist/zh-Hans/learn/curves.html
            new file mode 100644
            index 0000000000..0137a1cddc
            --- /dev/null
            +++ b/dist/zh-Hans/learn/curves.html
            @@ -0,0 +1,329 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by J David Eisenberg and ported by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +      This work is licensed under a <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/"> Creative Commons Attribution-NonCommercial-ShareAlinke 4.0 International License.</a>
            +
            +      </div>
            +
            +      <h1>Curves</h1>
            +
            +      <p>
            +      This short tutorial introduces you to the three types of curves in p5.js: arcs, spline curves, and Bézier curves.
            +      </p>
            +
            +      <h2> Arcs </h2>
            +
            +      <p>
            +      Arcs are the simplest curves to draw, it is defined an arc as a section of an ellipse. You call the function with these parameters:
            +      </p>
            +
            +      <p>
            +      arc (x, y, w, h, start, stop, [mode])
            +      </p>
            +
            +      <p>
            +      The first four parameters (x,y,w,h) define the boundary box for your arc and the next two (start, stop), are the start and stop angles for the arc. These angles are given in radians
            +      and are measured clockwise with zero degrees pointing east and PI radians equals 180°.
            +      </p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function draw() {
            +          createCanvas(150,200);
            +          background(150);
            +          stroke(0);
            +          arc(35, 35, 50, 50, 0, PI / 2.0); // lower quarter circle
            +          arc(105, 35, 50, 50, -PI, 0, CHORD);  // upper half of circle
            +          arc(175, 35, 50, 50, -PI / 6, PI / 6, PIE); // 60 degrees
            +          noFill();
            +          arc(105, 105, 100, 50, PI / 2, 3 * PI / 2, OPEN); // 180 degrees
            +        }
            +      </script>
            +
            +      <h2>Spline Curves</h2>
            +
            +      <p>
            +      Arcs are fine, but they’re plain. The next function, curve(), lets you draw curves that aren’t necessarily part of an arc. This function draws what is technically called a Rom-Catmull Spline.
            +      To draw the curve, you must specify the (x, y) coordinates of the points where the curve starts and ends. You must also specify two control points which determine the direction and amount of curvature.
            +      The first two and last two parameters are the control points of the curve.
            +      A call to curve() uses these parameters:
            +      </p>
            +
            +      <p>
            +      curve (cpx1, cpy1, x1, y1, x2, y2, cpx2, cpy2);
            +      </p>
            +
            +      <p>
            +      How do the control points affect the way the curve looks?
            +      </p>
            +
            +      <p>
            +        The tangent to the curve at the start point is parallel to the line between control point one and the end of the curve. The tangent to the curve at the end point is parallel to the line between the start point and control point 2.
            +      </p>
            +
            +      <p>
            +      The following diagram shows a curve and the points can be dragged to show how the control point affects the curve:
            +      </p>
            +
            +      <!-- iframe for the curve and dragging points -->
            +      <iframe src="../../assets/learn/curves/curve_ex/embed.html" width="350" height="350">
            +      </iframe>
            +
            +
            +      <h2>Continuous Spline Curves</h2>
            +
            +      <p>
            +      In isolation, a single curve() is not particularly appealing. To draw a continuous curve through several points, you are better off using the curveVertex() function.
            +      You can only use this function when you are creating a shape with the beginShape() and endShape() functions.In common usage, people use the first point of the curve
            +      as the first control point and the last point of the curve as the last control point.
            +      </p>
            +
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      let coords = [40, 40, 80, 60, 100, 100, 60, 120, 50, 150];
            +
            +      function setup() {
            +        createCanvas(150, 200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        curveVertex(40,40);
            +        curveVertex(40,40);
            +        curveVertex(80,60);
            +        curveVertex(100,100);
            +        curveVertex(60,120);
            +        curveVertex(50,150);
            +        curveVertex(50,150);
            +        endShape();
            +
            +         for (let i = 0; i < coords.length; i+= 2){
            +          ellipse(coords[i], coords[i+1], 10, 10);
            +         }
            +      }
            +      </script>
            +
            +      <h2>Bézier Curves</h2>
            +
            +      <p>
            +        Though better than arcs, spline curves don’t seem to have those graceful, swooping curves that say “art.” For those, you need to draw Bézier curves with the bezier() function.
            +        As with spline curves, the bezier() function has eight parameters, but the order is different. The first two and last two parameters are the start and end points while middle 
            +        four points are the control points.
            +      </p>
            +
            +      <p> bezier(x1, y1, cpx1, cpy1, cpx2, cpy2, x2, y2); </p>
            +
            +      <!-- iframe of Bezier example -->
            +      <iframe src="../../assets/learn/curves/bezier/embed.html" width="400" height="400">
            +      </iframe>
            +
            +      <p>
            +      While it is difficult to visualize how the control points affect a curve(), it is slightly easier to see how the control points affect Bézier curves.
            +      Imagine two poles and several rubber bands. The poles connect the control points to the endpoints of the curve. A rubber band connects the tops of the poles.
            +      Two more rubber bands connect the midpoints of the poles to the midpoint of the first rubber band. One more rubber band connects their midpoints.
            +      The center of that last rubber band is tied to the curve. This diagram helps to explain, the points can be moved to change the curve.
            +    </p>
            +
            +      <!-- image of bezier with lines -->
            +      <img src="../../assets/learn/curves/bezier_with_lines/bezier_with_lines.png" style="width:150px;">
            +
            +      <h2> Continuous Bézier Curves</h2>
            +
            +      <p>
            +      Just as curveVertex() allows you to make continuous spline curves, bezierVertex() lets you make continuous Bézier curves.
            +      Again, you must be within a beginShape() / endShape() sequence. You must use vertex(startX, startY) to specify the starting anchor point of the curve.
            +      Subsequent points are specified with a call to:
            +      </P>
            +
            +      <p>bezierVertex(cpx1, cpy1, cpx2, cpy2, x, y);</P>
            +
            +      <p>
            +      Here is a continuous Bézier curve, but it doesn’t join smoothly. In order to make two curves A and B smoothly continuous, the last control point of A,
            +      the last point of A, and the first control point of B have to be on a straight line.
            +      </P>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +        createCanvas(150,200);
            +      }
            +
            +      function draw() {
            +        background(255);
            +        noFill();
            +        stroke(0);
            +        beginShape();
            +        vertex(30, 70); // first point
            +        bezierVertex(25, 25, 100, 50, 50, 100);
            +        bezierVertex(50, 140, 75, 140, 120, 120); // if first 2 numbers are changed to 20, 130 it becomes continuous
            +        endShape();
            +
            +        ellipse(25, 25, 5, 5);
            +        ellipse(100, 50, 5, 5);
            +        ellipse(50, 140, 5, 5);//change to (20, 130, 5, 5) to reflect control point
            +        ellipse(75, 140, 5, 5);
            +      }
            +      </script>
            +
            +      <h2>Summary</h2>
            +        <p>
            +          <ul class="list_view">
            +            <li>Use arc() when you need a segment of a circle or an ellipse. You can’t make continuous arcs or use them as part of a shape.</li>
            +            <li>Use curve() when you need a small curve between two points. Use curveVertex() to make a continuous series of curves as part of a shape.</li>
            +            <li>Use bezier() when you need long, smooth curves. Use bezierVertex() to make a continuous series of Bézier curves as part of a shape.</li>
            +          </ul>
            +        </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/debugging.html b/dist/zh-Hans/learn/debugging.html
            new file mode 100644
            index 0000000000..a39a226a4a
            --- /dev/null
            +++ b/dist/zh-Hans/learn/debugging.html
            @@ -0,0 +1,320 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +        This tutorial was made by the Education Working Group, during the p5.js contributor conference at the Frank-Ratchye Studio for Creative Inquiry, Carnegie Mellon University in May of 2015. The contributors to this tutorial include <a href="http://huah.net/jason/">Jason Alderman</a>, <a href="http://tegabrain.com/">Tega Brain</a>, <a href="http://taeyoonchoi.com/">Taeyoon Choi</a> and <a href="http://luisaph.com/">Luisa Pereira</a>.
            +      </div>
            +      <img src="../../assets/learn/debugging/0-0.jpg" alt="" />
            +
            +      <p>
            +        This is a field guide for debugging for everyone—whether you are beginning to code or whether you have been coding for a long time, this guide breaks down the mysterious process of solving problems.
            +      </p>
            +
            +      <h3 class="start-element tutorial-btn" id="introduction">0. Debugging is a Creative Act</h3>
            +      <div class="info">
            +        <p>At all levels, programmers encounter bugs and will often spend more time debugging than actually programming the application. You can expect to spend a lot of time doing this and so it is important to develop good strategies for identifying and working through bugs as you learn to program in p5.js.</p>
            +        <p>
            +          A bug is a gap between what you think your system is doing, and what it is actually doing. <a target="_blank"
            +          href="https://vimeo.com/channels/debugging" >Clay Shirky aptly describes </a>a bug as "the moment when there is both a technical problem with your code as well as a problem with your mental picture of what is happening in your code." </p>
            +          <img src="../../assets/learn/debugging/0-1.jpg" alt="" />
            +        </p>
            +
            +        <p>You think you are telling the computer one thing, but it is doing something else. It may also be crashing or throwing errors. In order to close the gap, you must investigate. </p>
            +        <p>When you are working on a project, you may play many different roles. You are an architect when designing and planning your program, an engineer when you are developing it. Then you will be an explorer, discovering the problems and errors and testing it in all the situations in which it needs to run. You are trying to find out where it might break. Finally, when debugging you are a detective, trying to figure out how and why things broke.</p>
            +        <img class="small" src="../../assets/learn/debugging/0-3.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-4.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-5.png" alt="" />
            +        <img class="small" src="../../assets/learn/debugging/0-6.png" alt="" />
            +
            +        <p>So how can you become a good detective and debug your program? Here are the ten steps that can help you become a good code sleuth. </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="Change Perspectives">1. Change Perspectives.</h3>
            +      <div class="info">
            +        <p>Don't panic.</p>
            +        <p>When you encounter a bug that you do not know how to solve, stop, pause and take a deep breath. Stand up, say hi to the dog, take a walk or if it's late go get some sleep. When you are frustrated, tired and upset, you are not in a good frame of mind to learn or solve a  problem.</p>
            +        <p>To find your errors you will need to change perspectives and become the detective. The goal is to find out what the program IS doing, rather than why it's not doing what it's supposed to. We need to get the computer to show us what it's doing.</p>
            +        <p>The clues are in the values of variables and flow of program.</p>
            +        <img class="small_center" src="../../assets/learn/debugging/1-0.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="problem">2. Observe the problem </h3>
            +      <div class="info">
            +        <p>Walk someone through the issue even if they themselves do not know how to program. If no one is around, draft an email explaining what you have done and breaking down what the problem is.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-1.png" alt="" />
            +        <p>You probably won't need to actually send this email as often the act of writing it will help you to locate and identify what you need to do next. Some programmers have even been known to explain their problem to a friendly inanimate object like a rubber ducky.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-2.png" alt="" />
            +        <p>
            +          This is also a good time to add comments to your code that tell you exactly what each of your functions is doing.
            +          Some coders also print out their code (or a section of it) and go through it line by line, tracing the path of variables and making notes.
            +        </p>
            +        <img class="med_center" src="../../assets/learn/debugging/2-3.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="start">3. Before you start... </h3>
            +      <div class="info">
            +        <p>Before doing anything,  save a copy of your code that you can go back to.  While debugging you are likely to introduce other problems, break things or accidentally delete good work.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/3-1.png" alt="" />
            +        <p>You don't want to make bigger bugs in the process of debugging.</p>
            +        <img class="small_center" src="../../assets/learn/debugging/3-2.png" alt="" />
            +        <p>If you make a mistake or your problem gets more worse, you can always UNDO or revert back to your saved file.</p>
            +        <img class="med_center" src="../../assets/learn/debugging/3-3.jpg" alt="" />
            +        <p>You can try version control such as <a href="http://github.com">GitHub</a>.</p>
            +        <img src="../../assets/learn/debugging/3-4.png" alt="" />
            +        <p>Write a list of what you are trying, so you can keep track of what still needs to be checked. Be  methodical, it will save you a lot of time in the long run.</p>
            +        <p>
            +          Only ever change one thing at a time.
            +          <img class="med_right" src="../../assets/learn/debugging/3-5.jpg" alt="" />
            +          As you debug, you will be turning parts of your code on and off.
            +          Every time you make a change, test your program. If you make multiple changes before testing, you will not know which change has what effect and are likely to break things further.
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="basics">4. Check the basics </h3>
            +      <div class="info">
            +        <p>Many bugs end up being very basic mistakes, equivalent to forgetting to plug in the power cord. These mistakes are so obvious they are often invisible. Check the dumb stuff like...</p>
            +        <ul class="list_view">
            +          <li>Are you editing the file that you are actually running (and not, for example, editing the local file, and looking at a different file on the server)?</li>
            +          <li>Are all of your external files where you think they are?</li>
            +          <li>Are your file dependencies correct?</li>
            +          <li>Are there any typos in your paths?</li>
            +          <li>Check your server? etc.</li>
            +        </ul>
            +        <img src="../../assets/learn/debugging/4-1.png" alt="" />
            +        <img src="../../assets/learn/debugging/4-2.png" alt="" />
            +        <img src="../../assets/learn/debugging/4-3.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="blackboxes">5. Black boxes</h3>
            +      <div class="info">
            +        <p>A black box describes any part of your system you do not understand the inner workings of. For example, a library or perhaps a function that you have not written for yourself. Systematically take out each black box one-by-one and run your program. This will help to see if these parts of the program contain the error.</p>
            +        <img class="med_left" src="../../assets/learn/debugging/5-1.jpg" alt="" />
            +        <img class="med_right" src="../../assets/learn/debugging/5-2.png" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="reporting">6. Add error reporting</h3>
            +      <div class="info">
            +        <p>
            +          <img class="med_right" src="../../assets/learn/debugging/6-1.png" alt="" />
            +          Error reporting is how your program tells you what it is doing.
            +          p5.js comes with some built-in error reporting that will tell you if you have made specific syntax errors.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in your own error reporting using the console.log() function.
            +          <img class="med_right" src="../../assets/learn/debugging/6-2.png" alt="" />
            +          To check your program flow, add in console.log() statements to the parts of your code.
            +          Then when you look at your console you can see the order that things happen and where you encounter problems.
            +        </p>
            +
            +        <p>
            +          It is also useful to add in console.log()s to print out values of variables so that you can see what they are doing.
            +          <img class="med_center" src="../../assets/learn/debugging/6-3.jpg" alt="" />
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="help">7. Search for more help </h3>
            +      <div class="info">
            +        <p>So none of this works? There are many places you can look online to get more help.</p>
            +        <ul class="list_view">
            +          <li>Do a Google search, if you have had this problem chances are many other people will have too.</li>
            +          <li>Search the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> using the p5.js tag.</li>
            +          <li>Search development forums like <a href="http://stackoverflow.com/">Stack Overflow</a>.</li>
            +        </ul>
            +        <p> More general javascript resources:</p>
            +        <ul class="list_view">
            +          <li>First chapter of Bocoup's and Rebecca Murphey's interactive textbook, <a href="http://jqfundamentals.com/chapter/javascript-basics">jQuery Fundamentals</a>.</li>
            +          <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">  Mozilla's JavaScript Guide</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference ">JavaScript Reference </a>(this is really helpful for finding all of the built-in methods for, say a String).</li>
            +        </ul>
            +        <img class="med_center" src="../../assets/learn/debugging/7-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="people">8. Ask people </h3>
            +      <div class="info">
            +        <p>
            +          Still not working?
            +          <img class="med_right" src="../../assets/learn/debugging/8-0.jpg" alt="" />
            +          You can also ask people for help! They might be delighted to help you.
            +        </p>
            +        <p>
            +          Send that email you wrote at the start.<br>
            +          Post to the <a href="https://discourse.processing.org/c/p5js">Processing forum</a> succinctly articulating your problem and what you want to know. <br>
            +        </p>
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="prevent">9. Good coding practices and how to prevent bugs!</h3>
            +      <div class="info">
            +        <ul class="list_view">
            +          <li>Do not optimize prematurely. Clear code is more important than high-performing code as you're building your program.</li>
            +          <li>Do not abstract prematurely. You don't need to make functions for things you think you're going to use multiple times...until you actually have to use it more than once.</li>
            +          <li>
            +            Start with pseudocode as comments, then add code underneath each step.<br>
            +            Put console.log()s in your code as you develop (and test frequently—so if something changes, you know what you did since the last time you tested).<br>
            +          </li>
            +        </ul>
            +        <p>ALSO: start with small problems! Do one thing at a time. It's ok to make smaller sketches to test one thing (draw a star! check twitter!) and then voltron them together into a bigger sketch (draw a star that turns red when you have a notification on twitter!)</p>
            +        <img class="med_center" src="../../assets/learn/debugging/9-1.jpg" alt="" />
            +      </div>
            +
            +      <h3 class="start-element tutorial-btn" id="resources">10. More resources </h3>
            +      <div class="info">
            +        <p>
            +          This guide has been inspired by several other fantastic resources on debugging when coding. Some of these are here:
            +        </p>
            +          <ul class="list_view">
            +            <li>Matt Gemmel, <a href="http://mattgemmell.com/what-have-you-tried/">What have you tried?</a></li>
            +            <li>Clay Shirky, <a href="https://vimeo.com/channels/debugging">A brief introduction to debugging</a></li>
            +            <li>Eric Steven Raymond, <a href="http://www.catb.org/esr/faqs/smart-questions.html"> How to ask questions the smart way</a></li>
            +            <li>ITP Residents, <a href="https://docs.google.com/presentation/d/1RXzITwS4otVKnYkuNu2w7CrpYy35WBO2HUlmkSc2p8g/edit?copiedFromTrash#slide=id.g2ffb36b3_0_44">10 Tips for Debugging</a></li>
            +            <li>Rurouni Jones, <a href="http://rurounijones.github.io/blog/2009/03/17/how-to-ask-for-help-on-irc//">How to ask for help on IRC</a></li>
            +          </ul>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/index.html b/dist/zh-Hans/learn/index.html
            new file mode 100644
            index 0000000000..2d3496170d
            --- /dev/null
            +++ b/dist/zh-Hans/learn/index.html
            @@ -0,0 +1,491 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>学习</h1>
            +
            +      <p>以下教程将提供更多深入及详细的步骤,专注于特定的主题。请参考
            +        <a href="/zh-Hans/examples">范例页面
            +        </a>以查看 p5.js 多种功能的简单范例。
            +      </p>
            +
            +      
            +        <h2 class="tutorial-title">p5.js 简介</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="/zh-Hans/get-started/">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>入门简介</h3>
            +                </a>
            +              </div>
            +              <p>欢迎来到 p5.js!<br>这简介将涵盖 p5.js 的基本设置。 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js-overview">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>一览 p5.js</h3>
            +                </a>
            +              </div>
            +              <p>p5.js 主要功能的介绍 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Processing-transition">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js 及 Processing</h3>
            +                </a>
            +              </div>
            +              <p>两者之间的差别及如何将两者之间互相转换。 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Local-server">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>本地伺服器</h3>
            +                </a>
            +              </div>
            +              <p>如何在 Mac OSX、Windows 或 Linux 上设置本地伺服器。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5.js wiki</h3>
            +                </a>
            +              </div>
            +              <p>Additonal documentation and tutorials contributed by the community </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="p5-screen-reader.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>p5 及荧幕阅读器</h3>
            +                </a>
            +              </div>
            +              <p>设置 p5 以让它可以和荧幕阅读器一起使用。(英文内文) </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">链接 p5.js</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>node.js 及 socket.io</h3>
            +                </a>
            +              </div>
            +              <p>链接 node.js 伺服器及 p5.js,通过 socket.io 通讯。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">编程问题</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Beyond-the-canvas">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>画布之外</h3>
            +                </a>
            +              </div>
            +              <p>创建及控制画布以外的元素。 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>3D/WebGL</h3>
            +                </a>
            +              </div>
            +              <p>使用 p5.js WebGL 模式制作高级图形程式。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="color.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>颜色</h3>
            +                </a>
            +              </div>
            +              <p>数码颜色的简介。 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="coordinate-system-and-shapes.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>坐标系统与图形</h3>
            +                </a>
            +              </div>
            +              <p>利用坐标系统绘制简单图形。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="curves.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>曲线</h3>
            +                </a>
            +              </div>
            +              <p>介绍 p5.js 中的三种曲线:弧形,样条曲线和 Bézier 曲线。 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="interactivity.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>互动性</h3>
            +                </a>
            +              </div>
            +              <p>鼠标与键盘的互动简介。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="program-flow.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>程序流程</h3>
            +                </a>
            +              </div>
            +              <p>p5.js 控制程序流程简介。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">成为更好的程式设计师</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="debugging.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>调试</h3>
            +                </a>
            +              </div>
            +              <p>调试程序的简介。 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>优化 p5.js 程式</h3>
            +                </a>
            +              </div>
            +              <p>此教程包含技巧及窍门以进一步优化您的程式,使它执行得更快更顺畅。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tdd.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>单元测试及测试驱动开发</h3>
            +                </a>
            +              </div>
            +              <p>避免安装时不必要的烦恼。什么是单元测试?如何使用单元测试?作者 Andy Timmons。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +        <h2 class="tutorial-title">回馈社群</h2>
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>开发</h3>
            +                </a>
            +              </div>
            +              <p>开发设置简介及一览。 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://www.luisapereira.net/teaching/materials/processing-foundation">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>窥看 p5</h3>
            +                </a>
            +              </div>
            +              <p>一个简单易懂的教程,当中含括了 p5.js 源代码的文件格局及开发工具,作者 Luisa Pereira。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +          
            +            <div class="left-column">
            +            
            +              <div class="label">
            +                <a class="nounderline" href="tutorial-guide.html">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>编写教程</h3>
            +                </a>
            +              </div>
            +              <p>编写 p5.js 教程的指南。 </p>
            +            </div>
            +            
            +          
            +        
            +          
            +            <div class="right-column">
            +             
            +              <div class="label">
            +                <a class="nounderline" href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +                  <img alt="" src="../../assets/img/learn/lib_placeholder.jpg">
            +                  <h3>制作程式库</h3>
            +                </a>
            +              </div>
            +              <p>制作 p5.js 附加程式库。 </p>
            +            </div>
            +          
            +            <div class="spacer"></div>
            +             
            +          
            +        
            +      
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/interactivity.html b/dist/zh-Hans/learn/interactivity.html
            new file mode 100644
            index 0000000000..01fc76123e
            --- /dev/null
            +++ b/dist/zh-Hans/learn/interactivity.html
            @@ -0,0 +1,960 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This is based on the Interactivity chapter from the second edition of<em>
            +      <a href="https://processing.org/handbook/">Processing: A Programming Handbook for Visual Designers and Artists</a></em>, published by MIT Press. Copyright 2013 MIT Press. This tutorial was originally written for Processing version 2.0+ but has been ported and updated here for P5 by Alex Yixuan Xu. If you see any errors or have comments, please
            +      <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Interactivity</h1>
            +
            +      <p>The screen forms a bridge between our bodies and the realm of circuits and electricity inside computers. We control elements on screen through a variety of devices such as touch pads, trackballs, and joysticks, but the keyboard and mouse remain the most common input devices for desktop computers. The computer mouse dates back to the late 1960s, when Douglas Engelbart presented the device as an element of the oN-Line System (NLS), one of the first computer systems with a video display. The mouse concept was further developed at the Xerox Palo Alto Research Center (PARC), but its introduction with the Apple Macintosh in 1984 was the catalyst for its current ubiquity. The design of the mouse has gone through many revisions in the last forty years, but its function has remained the same. In Engelbart's original patent application in 1970 he referred to the mouse as an "X-Y position indicator," and this still accurately, but dryly, defines its contemporary use.</p>
            +
            +      <p>The physical mouse object is used to control the position of the cursor on screen and to select interface elements. The cursor position is read by computer programs as two numbers, the x-coordinate and the y-coordinate. These numbers can be used to control attributes of elements on screen. If these coordinates are collected and analyzed, they can be used to extract higher-level information such as the speed and direction of the mouse. This data can in turn be used for gesture and pattern recognition.</p>
            +
            +      <p>Keyboards are typically used to input characters for composing documents, email, and instant messages, but the keyboard has potential for use beyond its original intent. The migration of the keyboard from typewriter to computer expanded its function to enable launching software, moving through the menus of software applications, and navigating 3D environments in games. When writing your own software, you have the freedom to use the keyboard data any way you wish. For example, basic information such as the speed and rhythm of the fingers can be determined by the rate at which keys are pressed. This information could control the speed of an event or the quality of motion. It's also possible to ignore the characters printed on the keyboard itself and use the location of each key relative to the keyboard grid as a numeric position.</p>
            +
            +      <p>The modern computer keyboard is a direct descendant of the typewriter. The position of the keys on an English-language keyboard is inherited from early typewriters. This layout is called QWERTY because of the order of the top row of letter keys. It was developed for typewriters to put physical distance between frequently typed letter pairs, helping reduce the likelihood of the typebars colliding and jamming as they hit the ribbon. This more than one-hundred-year-old mechanical legacy still affects how we write software today.</p>
            +
            +      <h2>Mouse Data</h2>
            +
            +      <p>The variables <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> (note the capital X and Y) store the x-coordinate and y-coordinate of the cursor relative to the origin in the upper-left corner of the display window. To see the actual values produced while moving the mouse, run this program to print the values to the screen:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text("X: "+mouseX, 0, height/4);
            +  text("Y: "+mouseY, 0, height/2);
            +}
            +      </script>
            +
            +      <p>When a program starts, the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> values are 0. If the cursor moves into the display window, the values are set to the current position of the cursor. If the cursor is at the left, the mouseX value is 0 and the value increases as the cursor moves to the right. If the cursor is at the top, the mouseY value is 0 and the value increases as the cursor moves down. If mouseX and mouseY are used in programs without a <a href="/reference/#/p5/draw"> draw()</a> or if <a href="/reference/#/p5/noLoop">noLoop()</a> is run in <a href="/reference/#/p5/setup">setup()</a>, the values will always be 0.</p>
            +
            +      <p>The mouse position is most commonly used to control the location of visual elements on screen. More interesting relations are created when the visual elements relate differently to the mouse values, rather than simply mimicking the current position. Adding and subtracting values from the mouse position creates relationships that remain constant, while multiplying and dividing these values creates changing visual relationships between the mouse position and the elements on the screen. In the first of the following examples, the circle is directly mapped to the cursor, in the second, numbers are added and subtracted from the cursor position to create offsets, and in the third, multiplication and division are used to scale the offsets.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);    // Top circle
            +  ellipse(mouseX+20, 50, 33, 33); // Middle circle
            +  ellipse(mouseX-20, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(126);
            +  ellipse(mouseX, 16, 33, 33);   // Top circle
            +  ellipse(mouseX/2, 50, 33, 33); // Middle circle
            +  ellipse(mouseX*2, 84, 33, 33); // Bottom circle
            +}
            +      </script>
            +
            +      <p>To invert the value of the mouse, subtract the mouseX value from the width of the window and subtract the mouseY value from the height of the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  let x = mouseX;
            +  let y = mouseY;
            +  let ix = width - mouseX;  // Inverse X
            +  let iy = height - mouseY; // Inverse Y
            +  background(126);
            +  fill(255, 150);
            +  ellipse(x, height/2, y, y);
            +  fill(0, 159);
            +  ellipse(ix, height/2, iy, iy);
            +}
            +      </script>
            +
            +      <p>The variables <a href="/reference/#/p5/pmouseX">pmouseX</a> and <a href="/reference/#/p5/pmouseY">pmouseY</a> store the mouse values from the previous frame. If the mouse does not move, the values will be the same, but if the mouse is moving quickly there can be large differences between the values. To see the difference, run the following program and alternate moving the mouse slowly and quickly. Watch the values print to the screen.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function draw() {
            +  background(255);
            +  frameRate(12);
            +  text(pmouseX - mouseX, 0, height/4);
            +}
            +      </script>
            +
            +      <p>Draw a line from the previous mouse position to the current position to show the changing position in one frame and reveal the speed and direction of the mouse. When the mouse is not moving, a point is drawn, but quick mouse movements create long lines.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(8);
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, mouseY, pmouseX, pmouseY);
            +}
            +      </script>
            +
            +      <p>Use the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables with an if structure to allow the cursor to select regions of the screen. The following examples demonstrate the cursor making a selection between different areas of the display window. The first divides the screen into halves, and the second divides the screen into thirds.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 50) {
            +    rect(0, 0, 50, 100);  // Left
            +  }
            +  else {
            +    rect(50, 0, 50, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseX < 33) {
            +    rect(0, 0, 33, 100);  // Left
            +  }
            +  else if (mouseX < 66) {
            +    rect(33, 0, 33, 100); // Middle
            +  }
            +  else {
            +    rect(66, 0, 33, 100); // Right
            +  }
            +}
            +      </script>
            +
            +      <p>Use the logical operator &amp;&amp; with an if structure to select a rectangular region of the screen. As demonstrated in the following example, when a relational expression is made to test each edge of a rectangle (left, right, top, bottom) and these are concatenated with a logical AND, the entire relational expression is true only when the cursor is inside the rectangle.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX > 40) && (mouseX < 80) && (mouseY > 20) && (mouseY < 80)){
            +    fill(255);
            +  }
            +  else {
            +    fill(0);
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>This code asks, "Is the cursor to the right of the left edge and is the cursor to the left of the right edge and is the cursor beyond the top edge and is the cursor above the bottom?" The code for the next example asks a set of similar questions and combines them with the keyword else to determine which one of the defined areas contains the cursor.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if ((mouseX <= 50) && (mouseY <= 50)) {
            +    rect(0, 0, 50, 50);   // Upper-left
            +  }
            +  else if ((mouseX <= 50) && (mouseY > 50)) {
            +    rect(0, 50, 50, 50);  // Lower-left
            +  }
            +  else if ((mouseX > 50) && (mouseY <= 50)) {
            +    rect(50, 0, 50, 50);  // Upper-right
            +  }
            +  else {
            +    rect(50, 50, 50, 50); // Lower-right
            +  }
            +}
            +      </script>
            +
            +      <h2>Mouse buttons</h2>
            +      <p>Computer mice and other related input devices typically have between one and three buttons; p5 can detect when these buttons are pressed with the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> and <a href="/reference/#/p5/mouseButton">mouseButton</a> variables. Used with the button status, the cursor position enables the mouse to perform different actions. For example, a button press when the mouse is over an icon can select it, so the icon can be moved to a different location on screen. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true if any mouse button is pressed and false if no mouse button is pressed. The variable <a href="/reference/#/p5/mouseButton">mouseButton</a> is LEFT, CENTER, or RIGHT depending on the mouse button most recently pressed. The <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable reverts to false as soon as the button is released, but the <a href="/reference/#/p5/mouseButton">mouseButton</a> variable retains its value until a different button is pressed. These variables can be used independently or in combination to control the software. Run these programs to see how the software responds to your fingers.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(0);   // Black
            +  }
            +  rect(25, 25, 50, 50);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseButton == LEFT) {
            +    fill(0);   // Black
            +  }
            +  else if (mouseButton == RIGHT) {
            +    fill(255); // White
            +  }
            +  else {
            +    fill(126); // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +  fill(0);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    if (mouseButton == LEFT) {
            +      fill(0);   // Black
            +    }
            +    else if (mouseButton == RIGHT) {
            +      fill(255); // White
            +    }
            +  }
            +  else {
            +    fill(126);   // Gray
            +  }
            +  rect(40, 20, 40, 60);
            +}
            +      </script>
            +
            +      <p>Not all mice have multiple buttons, and if software is distributed widely, the interaction should not rely on detecting which button is pressed.</p>
            +
            +      <h2>Keyboard data</h2>
            +
            +      <p>p5 registers the most recently pressed key and whether a key is currently pressed. The boolean variable <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> is true if a key is pressed and is false if not. Include this variable in the test of an if structure to allow lines of code to run only if a key is pressed. The <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable remains true while the key is held down and becomes false only when the key is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) {  // If the key is pressed,
            +    line(20, 20, 80, 80);      // draw a line;
            +  }
            +  else {                       // Otherwise,
            +    rect(40, 40, 20, 20);      // draw a rectangle.
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 20;
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed == true) { // If the key is pressed,
            +    x++;                      // add 1 to x.
            +  }
            +  line(x, 20, x-60, 80);
            +}
            +      </script>
            +      <!-- made changes about the key variable not guaranteed to be case sensitive in p5 -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable stores a single alphanumeric character. Specifically, it holds the most recently pressed key. However, it is not guaranteed to be case sensitive. To get the proper capitalization, it is best to use it within <a href="/reference/#/p5/keyTyped">keyTyped()</a>. For non-ASCII keys, use the <a href="/reference/#/p5/keyCode">keyCode</a> variable. The key can be displayed on screen with the <a href="/reference/#/p5/text">text()</a> function (p. 150).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  textSize(60);
            +  fill(255);
            +}
            +function draw() {
            +  background(0);
            +  text(key, 20, 75); // Draw at coordinate (20,75)
            +}
            +      </script>
            +
            +      <!-- no differences in "" and '' in p5, made changes -->
            +      <!-- <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. The single quotes signify A as the data type char (p. 144). The expression key == "A" will cause an error because the double quotes signify the A as a String, and it's not possible to compare a String with a char. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyPressed">keyPressed</a> variable to ascertain that the key pressed is the uppercase A.</p> -->
            +      <p>The <a href="/reference/#/p5/key">key</a> variable may be used to determine whether a specific key is pressed. The following example uses the expression key=='A' to test if the A key is pressed. Note the use of double quotation marks or single quotation marks has no influence on the program as long as you are consistent. The logical AND symbol, the &amp;&amp; operator, is used to connect the expression with the <a href="/reference/#/p5/keyIsPressed">keyIsPressed</a> variable to ascertain that the key pressed is the uppercase A.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(4);
            +  stroke(255);
            +}
            +function draw() {
            +  background(0);
            +  // If the 'A' key is pressed, draw a line
            +  if ((keyIsPressed == true) && (key == 'A')) {
            +    line(50, 25, 50, 75);
            +  }
            +  else { // Otherwise, draw an ellipse
            +    ellipse(50, 50, 50, 50);
            +  }
            +}
            +      </script>
            +
            +      <p>The previous example works with an uppercase A, but not if the lowercase letter is pressed. To check for both uppercase and lowercase letters, extend the relational expression with a logical OR, the || relational operator. Line 9 in the previous program would be changed to:</p>
            +      <pre><code class="language-javascript">
            +        if ((keyIsPressed == true) &amp;&amp; ((key == 'a') || (key == 'A'))) {
            +      </code></pre>
            +
            +      <!-- changes made -->
            +      <h2>Coded keys</h2>
            +      <p>Because each character has a numeric value as defined by the <a href="https://www.w3schools.com/charsets/ref_html_ascii.asp">ASCII table</a>, the value of the <a href="/reference/#/p5/keyCode">keyCode</a> variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script>
            +
            +      <!--made changes to original content here -->
            +<!--       <p>Because each character has a numeric value as defined by the ASCII table (p. 605), the value of the key variable can be used like any other number to control visual attributes such as the position and color of shape elements. For instance, the ASCII table defines the uppercase A as the number 65, and the digit 1 is defined as 49.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  if (keyIsPressed === true) {
            +    let x = keyCode - 32;
            +    line(x, 0, x, height);
            +  }
            +}
            +      </script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let angle = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  if (keyIsPressed === true) {
            +    if ((keyCode >= 32) && (keyCode <= 126)) {
            +      // If the key is alphanumeric, // use its value as an angle
            +      angle = (keyCode - 32) * 3;
            +    }
            +  }
            +  arc(50, 50, 66, 66, 0, radians(angle));
            +}
            +      </script>
            +      <h2>Coded keys</h2>
            +      <p>In addition to reading key values for numbers, letters, and symbols, p5 can also read the values from other keys including the arrow keys and the Alt, Control, Shift, Backspace, Tab, Enter, Return, Escape, and Delete keys. The variable <a href="/reference/#/p5/keyCode">keyCode</a> stores the BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW. If you're making cross-platform projects, note that the Enter key is commonly used on PCs and UNIX and the Return key is used on Macintosh. Check for both Enter and Return to make sure your program will work for all platforms (see code 12-17).</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let y = 35;
            +function setup() {
            +  createCanvas(100, 100);
            +  stroke(0);
            +}
            +function draw() {
            +  background(204);
            +  line(10, 50, 90, 50);
            +  if (keyCode == UP_ARROW) {
            +    y = 20;
            +  }
            +  else if (keyCode == DOWN_ARROW) {
            +    y = 50;
            +  }
            +  else {
            +    y = 35;
            +  }
            +  rect(25, y, 50, 30);
            +}
            +      </script> -->
            +
            +      <h2>Events</h2>
            +      <p>A category of functions called events alter the normal flow of a program when an action such as a key press or mouse movement takes place. An event is a polite interruption of the normal flow of a program. Key presses and mouse movements are stored until the end of <a href="/reference/#/p5/draw">draw()</a>, where they can take action that won't disturb drawing that's currently in progress. The code inside an event function is run once each time the corresponding event occurs. For example, if a mouse button is pressed, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function will run once and will not run again until the button is pressed again. This allows data produced by the mouse and keyboard to be read independently from what is happening in the rest of the program.</p>
            +
            +      <h2>Mouse events</h2>
            +      <!-- added mouseClicked() mouseOver() mouseOut() doubleClicked()-->
            +      <p>The mouse event functions are <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, <a href="/reference/#/p5/mouseDragged">mouseDragged()</a>, <a href="/reference/#/p5/mouseOver">mouseOver()</a>, and <a href="/reference/#/p5/mouseOut">mouseOut()</a>:</p>
            +
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block is run one time when the mouse is moved while a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>The <a href="/reference/#/p5/mousePressed">mousePressed()</a> function works differently than the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable. The value of the <a href="/reference/#/p5/mouseIsPressed">mouseIsPressed</a> variable is true until the mouse button is released. It can therefore be used within <a href="/reference/#/p5/draw">draw()</a> to have a line of code run while the mouse is pressed. In contrast, the code inside the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function only runs once when a button is pressed. This makes it useful when a mouse click is used to trigger an action, such as clearing the screen. In the following example, the background value becomes lighter each time a mouse button is pressed. Run the example on your computer to see the change in response to your finger.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mousePressed() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>The following example is the same as the one above, but the gray variable is set in the <a href="/reference/#/p5/mouseReleased">mouseReleased()</a> event function, which is called once every time a button is released. This difference can be seen only by running the program and clicking the mouse button. Keep the mouse button pressed for a long time and notice that the background value changes only when the button is released.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseReleased() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <!-- mouseClicked() example added-->
            +      <p>Similarly, the gray variable is set in the <a href="/reference/#/p5/mouseClicked">mouseClicked()</a> event function, which is called once after a mouse button has been pressed and then released. Browsers handle clicks differently, so this function is only guaranteed to be run when the left mouse button is clicked. To handle other mouse buttons being pressed or released, use <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>. </p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let gray = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(gray);
            +}
            +function mouseClicked() {
            +  gray += 20;
            +}
            +      </script>
            +
            +      <p>It is generally not a good idea to draw inside an event function, but it can be done under certain conditions. Before drawing inside these functions, it's important to think about the flow of the program. In this example, squares are drawn inside <a href="/reference/#/p5/mousePressed">mousePressed()</a> and they remain on screen because there is no <a href="/reference/#/p5/background">background()</a> inside <a href="/reference/#/p5/draw">draw()</a>. But if <a href="/reference/#/p5/background">background()</a> is used, visual elements drawn within one of the mouse event functions will appear on screen for only a single frame, or, by default, 1/60th of a second. In fact, you'll notice this example has nothing at all inside <a href="/reference/#/p5/draw">draw()</a>, but it needs to be there to force P5 to keep listening for the events. If a <a href="/reference/#/p5/background">background()</a> function were run inside <a href="/reference/#/p5/draw">draw()</a>, the rectangles would flash onto the screen and disappear.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  fill(0, 102);
            +  background(204); // Draw once to give a little color
            +}
            +function draw() {
            +} // Empty draw() keeps the program running
            +function mousePressed() {
            +  rect(mouseX, mouseY, 33, 33);
            +}
            +      </script>
            +
            +      <p>The code inside the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> and <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> event functions are run when there is a change in the mouse position. The code in the <a href="/reference/#/p5/mouseMoved">mouseMoved()</a> block is run at the end of each frame when the mouse moves and no button is pressed. The code in the <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> block does the same when the mouse button is pressed. If the mouse stays in the same position from frame to frame, the code inside these functions does not run. In this example, the gray circle follows the mouse when the button is not pressed, and the black circle follows the mouse when a mouse button is pressed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let dragX, dragY, moveX, moveY;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  fill(0);
            +  ellipse(dragX, dragY, 33, 33); // Black circle
            +  fill(153);
            +  ellipse(moveX, moveY, 33, 33); // Gray circle
            +}
            +function mouseMoved() {   // Move gray circle
            +  moveX = mouseX;
            +  moveY = mouseY;
            +}
            +function mouseDragged() { // Move black circle
            +  dragX = mouseX;
            +  dragY = mouseY;
            +}
            +      </script>
            +
            +      <!-- examples added for mouseOut() and mouseOver() -->
            +      <p>The <a href="/reference/#/p5/mouseOver">.mouseOver()</a> function is called once after every time a mouse moves onto the element. In this example, the diameter of the ellipse increase by 10 every time the mouse moves onto the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOver(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/mouseOut">.mouseOut()</a> function is called once after every time a mouse moves off the element. Similar to the above example, the diameter of the ellipse increase by 10 every time the mouse moves out of the canvas.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseOut(changeD);
            +  d = 10;
            +}
            +function draw() {
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +function changeD() {
            +  d = d + 10;
            +}
            +      </script>
            +
            +      <h2>Wheel Events</h2>
            +      <p>The <a href="/reference/#/p5/mouseWheel">.mouseWheel()</a> function is called once after every time a mouse wheel is scrolled over the element. This can be used to attach element specific event listeners. The function accepts a callback function as argument which will be executed when the wheel event is triggered on the element. The <a href="/reference/#/p5/deltaY">event.deltaY</a> property returns negative values if the mouse wheel is rotated up or away from the user and positive in the other direction. The <a href="/reference/#/p5/deltaX">event.deltaX</a> does the same as <a href="/reference/#/p5/deltaY">event.deltaY</a> except it reads the horizontal wheel scroll of the mouse wheel. On OS X with "natural" scrolling enabled, the <a href="/reference/#/p5/deltaY">event.deltaY</a> values are reversed.</p>
            +      <p>In this example, an event listener is attached to the canvas element, and function changeSize() would run when scrolling is performed on canvas. By using the <a href="/reference/#/p5/deltaY">event.deltaY</a> variable, scrolling up on canvas would increase the diameter of the ellipse and scrolling down would decrease the diameter. If scrolling is performed anywhere in any direction, the background is going to be darker.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mouseWheel(changeSize); // attach listener for activity on canvas only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with mousewheel movement anywhere on screen
            +function mouseWheel() {
            +  g = g + 10;
            +}
            +
            +// this function fires with mousewheel movement over canvas only
            +function changeSize(event) {
            +  if (event.deltaY > 0) {
            +    d = d + 10;
            +  }
            +  else {
            +    d = d - 10;
            +  }
            +}
            +      </script>
            +
            +      <h2>Key events</h2>
            +      <!-- keyTyped() added -->
            +      <p>Each key press is registered through the keyboard event functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyPressed">keyTyped()</a> and <a href="/reference/#/p5/keyReleased">keyReleased()</a>:</p>
            +      
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block is run one time when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is run one time when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is run one time when any key is released</li>
            +      </ul>
            +
            +      <p>Each time a key is pressed, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block is run once. Within this block, it's possible to test which key has been pressed and to use this value for any purpose. If a key is held down for an extended time, the code inside the <a href="/reference/#/p5/keyPressed">keyPressed()</a> block might run many times in a rapid succession because most operating systems will take over and repeatedly call the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. The amount of time it takes to start repeating and the rate of repetitions will be different from computer to computer, depending on the keyboard preference settings. In this example, the value of the boolean variable drawT is set from false to true when the T key is pressed; this causes the lines of code to render the rectangles in <a href="/reference/#/p5/draw">draw()</a> to start running.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +      </script>
            +
            +      <!-- added this information to distinguish keyPressed() and keyTyped() -->
            +      <p>When ASCII keys are pressed, the character is stored in the <a href="https://p5js.org/reference/#/p5/key">key </a>variable. However, this variable does not distinguish between uppercase and lowercase when used with the <a href="/reference/#/p5/keyPressed">keyPressed()</a> function. For this reason, it is recommended to use <a href="/reference/#/p5/keyTyped">keyTyped()</a>. When used with the <a href="/reference/#/p5/key">key</a> variable this function will recognize case. </p>
            +
            +      <p>Each time a key is released, the code inside the <a href="/reference/#/p5/keyReleased">keyReleased()</a> block is run once. The following example builds on the previous code; each time the key is released the boolean variable drawT is set back to false to stop the shape from displaying within <a href="/reference/#/p5/draw">draw()</a>.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let drawT = false;
            +function setup() {
            +  createCanvas(100, 100);
            +  noStroke();
            +}
            +function draw() {
            +  background(204);
            +  if (drawT == true) {
            +    rect(20, 20, 60, 20);
            +    rect(39, 40, 22, 45);
            +  }
            +}
            +function keyPressed() {
            +  if ((key == 'T') || (key == 't')) {
            +    drawT = true;
            +  }
            +}
            +function keyReleased() {
            +  drawT = false;
            +}
            +      </script>
            +
            +      <h2>Event flow</h2>
            +      <p>As discussed previously, programs written with <a href="/reference/#/p5/draw">draw()</a> display frames to the screen sixty frames each second. The <a href="/reference/#/p5/frameRate">frameRate()</a> function is used to set a limit on the number of frames that will display each second, and the <a href="/reference/#/p5/noLoop">noLoop()</a> function can be used to stop draw() from looping. The additional functions <a href="/reference/#/p5/loop">loop()</a> and <a href="/reference/#/p5/redraw">redraw()</a> provide more options when used in combination with the mouse and keyboard event functions. If a program has been paused with <a href="/reference/#/p5/noLoop">noLoop()</a>, running <a href="/reference/#/p5/loop">loop()</a> resumes its action. Because the event functions are the only elements that continue to run when a program is paused with noLoop(), the loop() function can be used within these events to continue running the code in draw(). The following example runs the draw() function for about two seconds each time a mouse button is pressed and then pauses the program after that time has elapsed.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let frame = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  if (frame > 120) {              // If 120 frames since the mouse
            +    noLoop();                     // was pressed, stop the program
            +    background(0);                // and turn the background black.
            +  }
            +  else {                          // Otherwise, set the background
            +    background(204);              // to light gray and draw lines
            +    line(mouseX, 0, mouseX, 100); // at the mouse position
            +    line(0, mouseY, 100, mouseY);
            +    frame++;
            +  }
            +}
            +function mousePressed() {
            +  frame = 0;
            +  loop();
            +}
            +      </script>
            +
            +      <p>The <a href="/reference/#/p5/redraw">redraw()</a> function runs the code in draw() one time and then halts the execution. It's helpful when the display needn't be updated continuously. The following example runs the code in draw() once each time a mouse button is pressed.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(204);
            +  line(mouseX, 0, mouseX, 100);
            +  line(0, mouseY, 100, mouseY);
            +}
            +function mousePressed() {
            +  redraw(); // Run the code in draw one time
            +}
            +      </script>
            +
            +      <!-- event listener and callback functions explained??? -->
            +      <!-- This should probably be explained in a another tutorial more in-depth -->
            + <!--      Functions like mousePressed(), mouseClicked(), mouseReleased(), mouseMoved(), mouseOver(), and mouseOut() can be used as event listeners. They can be attached to certain elements</p>
            +      <p>Function|Boolean: function to be fired when mouse is pressed over the element. if false is passed instead, the previously firing function will no longer fire.</p>
            +      <p>In this example</p>
            +       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +-->
            +      <h2>Cursor icon</h2>
            +      <p>The cursor can be hidden with the <a href="/reference/#/p5/noCursor">noCursor()</a> function and can be set to appear as a different icon or image with the <a href="/reference/#/p5/cursor">cursor()</a> function. When the noCursor() function is run, the cursor icon disappears as it moves into the display window. To give feedback about the location of the cursor within the software, a custom cursor can be drawn and controlled with the <a href="/reference/#/p5/mouseX">mouseX</a> and <a href="/reference/#/p5/mouseY">mouseY</a> variables.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  strokeWeight(7);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  ellipse(mouseX, mouseY, 10, 10);
            +}
            +      </script>
            +
            +      <p>If <a href="/reference/#/p5/noCursor">noCursor()</a> is run, the cursor will be hidden while the program is running until the <a href="/reference/#/p5/cursor">cursor()</a> function is run to reveal it.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor();
            +  }
            +  else {
            +    noCursor();
            +  }
            +}
            +      </script>
            +
            +      <p>Add a parameter to the cursor() function to change it to another icon or image. Either load and use image, or use the self-descriptive options are ARROW, CROSS, HAND, MOVE, TEXT, and WAIT.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +  noCursor();
            +}
            +function draw() {
            +  background(204);
            +  if (mouseIsPressed == true) {
            +    cursor(HAND);  // Draw cursor as hand
            +  }
            +  else {
            +    cursor(CROSS); // Draw cursor as cross
            +  }
            +  line(mouseX, 0, mouseX, height);
            +  line(0, mouseY, height, mouseY);
            +}
            +      </script>
            +      <p>These cursor icons are part of your computer's operating system and will appear different on different machines.</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div>
            +  <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +<!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/p5-screen-reader.html b/dist/zh-Hans/learn/p5-screen-reader.html
            new file mode 100644
            index 0000000000..c807448332
            --- /dev/null
            +++ b/dist/zh-Hans/learn/p5-screen-reader.html
            @@ -0,0 +1,605 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Using p5 with a screen reader</h1>
            +
            +      <p>
            +        This page introduces some of the screen reader friendly features of the p5js web editor, it provides an overview of accessible outputs, and examples and tutorials on how to get started with p5 when using a screen reader.
            +      </p>
            +      <p>
            +        p5.js is a library that starts with the original goal of Processing –to make to make coding accessible for artists, designers, educators, and beginners– and reinterprets it for the web using the metaphor of a software sketchbook with a set of drawing functionality. With p5.js we are able to draw in the canvas. The canvas is perhaps the most inaccessible element in HTML. The reason for this is simple: the canvas behaves just like a physical canvas, once you put paint on it, it covers up what’s behind it, making it hard to understand how the pixels comprise shapes and elements. Within the p5.js web editor it is possible to access the content of the canvas using a screen reader through text, a spatial table, and sound outputs.
            +      </p>
            +
            +
            +      <h2>What is the p5.js Web Editor</h2>
            +      <p>
            +        The p5.js web editor is a essentially a web page where you can type code in p5.js and run the code to view the output. It allows us to code in and for the browser. The web editor has features that make it screen reader friendly. You can access the <a href="http://editor.p5js.org/">p5 web editor here.</a>
            +      </p>
            +
            +      <h2>Pairings</h2>
            +      <p>
            +        Please note - the p5.accessibility library is currently not supported on MacOS.
            +      </p>
            +      <p>
            +        Using the p5.js web editor with a screen reader works better when you have one of the following screen reader/browser/operating system pairings:
            +      </p>
            +        <ul class="list_view">
            +          <li>NVDA and Firefox</li>
            +          <li>JAWS and Chrome</li>
            +        </ul>
            +
            +      <h2>Outputs</h2>
            +      <p>
            +        With a screen reader we can access the content of the canvas through the following outputs:
            +      </p>
            +
            +      <h3>Plain Text Output</h3>
            +      <p>
            +        This output describes the visual content present on the canvas in plain text.
            +      </p>
            +
            +      <h3>Table Output</h3>
            +      <p>
            +        The table output laids out the content of the canvas in the form of a table based on the spatial location of each element.
            +
            +      </p>
            +
            +      <h3>Sound Output</h3>
            +      <p>
            +        This mode explains the movement of the objects present in the canvas. Top to bottom movement is represented by a decrease in frequency and left to right through panning.
            +      </p>
            +
            +      <h2>How to select an output:</h2>
            +      <p>
            +        In the p5.js web editor there are two ways to select the accessible outputs that we want to make available.
            +      </p>
            +      <ol>
            +        <li>
            +          When we press the “play sketch, button” accessible to screen readers the “plain-text output” will automatically be available.
            +        </li>
            +        <li>
            +          If we want to access other outputs we should do the following:
            +          <ul class="list_view">
            +            <li>
            +              First, stop the sketch by pressing the “stop sketch, button” and go to “Settings”.
            +            </li>
            +            <li>
            +              Within settings we must find the “Accessibility” tab.
            +            </li>
            +            <li>
            +              In the “Accessibility” tab and under the “Accessible text-based canvas” section we can choose our preferred outputs.
            +            </li>
            +          </ul>
            +        </li>
            +      </ol>
            +      <p>
            +        Within “Settings” and under the “Accessibility” tab it is also possible to activate a lint warning sound that should make debugging easier. In “Settings” and under the  “General Settings” tab we can increase the size of the font and select a high contrast theme. After choosing our settings we can close the “Settings” window and go back to coding and playing our sketch.
            +      </p>
            +      <p>
            +        It is possible to add these accessible outputs to p5 sketches outside of the p5.js web editor by including the p5.accessibility.js library. <a  target="_blank" href="https://github.com/processing/p5.accessibility">You can learn more about the library here.</a>
            +      </p>
            +
            +      <h3>Keyboard Shortcuts</h3>
            +      <p>
            +        There are also ways to turn on the accessible outputs using keyboard shortcuts. Once we are on the code editor area we can use the following shortcuts (we have listed the shortcuts  for Windows computers, if you are using Mac OS please use the command key instead of control):
            +      </p>
            +      <ul class="list_view">
            +        <li>
            +          Shift + Control +1 - Turns on ALL the accessible output options, including audio
            +        </li>
            +        <li>
            +          Shift + Control +2 - Turns off ALL the accessible output options
            +        </li>
            +        <li>
            +          Control + Enter - This is used to run a sketch. If you already have accessibility options turned on, they will show up as well
            +        </li>
            +        <li>
            +          Shift + Control + Enter - This is used to stop a sketch.
            +        </li>
            +      </ul>
            +      <p>
            +        The full list of shortcuts is also available in the p5 web editor, under Keyboard Shortcuts in the Help and Feedback section of the menu
            +      </p>
            +
            +      <h1>Lessons</h1>
            +      <h2>Lesson 1: Hello World</h2>
            +      <p>
            +        In this section we go through some basic functions in p5 and look at how the screen reader will read the output.
            +
            +        There are two main functions we will use in our programs. The setup() function runs once, and is typically used for initialization, or for creating a program that does not need a loop running code repeatedly. The draw() function runs over and over again, and is used to perform a certain action repeatedly and for animation.
            +        Now we can open the editor: alpha.p5js.org and look for the code edit area. If you notice, there’s some code there already. Whenever you open the editor by default it will create a setup() function and a draw() function. However, for our first "Hello World" program we will take a step back and delete everything. Once we have a blank editor, we create a setup() block and add one line:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(200,200);
            +        }
            +      </code></pre>
            +
            +    <p>
            +      The createCanvas() function creates a canvas for us  to draw  or display the output. The canvas is the space on which the output is “drawn” or displayed. The code above creates a canvas of width and height 200 pixels. Since there is no movement, we will take a look only at the text and table outputs.
            +    </p>
            +    <h3>Text output for Lesson 1</h3>
            +    <p>
            +      Your output is a 200 by 200 white canvas containing the following 0 object
            +    </p>
            +    <h3>Table output for Lesson 1</h3>
            +    <p>
            +      white canvas is 200 by 200 of area 40000 contains 0 objects
            +    </p>
            +    <p>
            +      As expected, the outputs do not have any details apart from that of the canvas. Now, let’s move on to the next lesson where we add some basic shapes.
            +    </p>
            +
            +      <h2>Lesson 2: Basic Shapes</h2>
            +      <p>
            +        In this example, we will draw an ellipse on the top left, and a rectangle on the bottom right of the canvas of size 500 by 500 pixels. First, let's create the canvas and draw a shape in the setup function. Feel free to copy the code to the editor and run it.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        This code creates a canvas of 500 by 500 pixels and then draws an ellipse. The first 2 numbers we pass to the ellipse indicate where the center of the ellipse will be on the canvas. In this case, that is 50 and 50 pixels. The next 2 numbers indicate the width and height of the ellipse. In this case, they are both 20 pixels, implying we want to draw a circle. It is important to note that the top left corner of the canvas is point 0,0 pixels and the bottom right corner of the canvas is point 500,500 pixels.
            +      </p>
            +      <p>
            +        Now, we can also type this code a bit differently. We can create the canvas in the setup() function and draw the shape in the draw() function.
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +        }
            +        function draw() {
            +          ellipse(50,50,20,20);
            +        }
            +      </code></pre>
            +      <p>
            +        In the previous case, the ellipse is drawn ONCE in setup and never again. But, in this case, the ellipse is drawn again and again in the canvas. Since, the numbers passed to the ellipse are the same each time, it doesn’t make a difference. However, if we wanted to change it’s position each time and make it move, then we would have to do it in draw.
            +      </p>
            +      <p>
            +        NOTE: remember, that everything in the canvas is drawn one over the other.
            +      </p>
            +      <p>
            +        In this case the output will be following:
            +      </p>
            +
            +      <h3>Text output for Lesson 2</h3>
            +      <p>
            +        The overview for the text output contains “Your output is a 500 by 500 white canvas containing the following 1 object:”.
            +      </p>
            +      <p>
            +        This description is followed by a list of elements where the shape, color, position, and area of each element are described (in this case: “white ellipse at top left covering 0.13% of the canvas” ). Each element can be selected to get more details. A table of elements is also provided. In this table, shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”).
            +      </p>
            +      <h3>Table output for Lesson 2</h3>
            +      <p>
            +        The overview for the table output contains “white canvas is 500 by 500 of area 250000 Contains 1 objects - 1 ellipse”
            +      </p>
            +      <p>
            +        This is followed by a table that describes the content spatially. It is a 10 by 10 table structure where each element is placed on a cell of the table depending on its position. Within each cell an element the color and type of shape of that element are available (example: “white ellipse”). These descriptions can be selected individually to get more details. A list of elements where shape, color, location, coordinates and area are described (example: “white ellipse   location=top left    coordinates =50x,50y    area=0.13%”) is also available.
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rk4uO1bJX">basic shapes example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Lesson 3: Color</h2>
            +      <p>
            +        In these examples, we  look at different ways to add color to our sketch
            +        First, let’s look at ‘background()’. We can use this function to add a background color to the canvas. Copy the below code to try it out.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +      </code></pre>
            +      <p>
            +        Here, we have given the color in RGB format. In this format we can describe colors by saying how much, Red, Green and Blue the color has. RGB values must be integers between 0 and 255 with 0 being no color, and 255 highest amount of a certain color. The outputs will now contain “Red (255,0,0) canvas”.
            +      </p>
            +      <p>
            +        Now we can give color to our shapes using the function, fill().
            +      </p>
            +      <p>
            +        Copy the below code to try it out:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(255,0,0);
            +        }
            +
            +        function draw() {
            +          fill(200,50,8);
            +          ellipse(50,50,20,20);
            +          fill(20,250,8);
            +          ellipse(250,250,20,20);
            +          fill(20,150,250);
            +          ellipse(450,450,20,20);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now, in the plain text and grid output, we will notice that each shape is prepended with the color of the shape.
            +      </p>
            +
            +      <h3>Text output for Lesson 3</h3>
            +      <p>
            +        In the text output the overview is as follows
            +        “Your output is a 500 by 500 red(255,0,0) canvas containing the following 3 objects”
            +      </p>
            +      <p>
            +        After this we see the list of objects, with their color name and the RGB value. For example -  “crimson(200, 50, 8) ellipse at top left covering 0.13% of the canvas” Each object contains a link that when selected provides more details.
            +      </p>
            +
            +      <h3>Grid output for Lesson 3</h3>
            +      <p>
            +        The overview is as follows “red(255,0,0) canvas is 500 by 500 of area 250000 contains 3 0bjects - 3 ellipse”
            +      </p>
            +      <p>
            +        And in the table, we will find the objects in the grids corresponding to their location. “crimson(200,50,8) ellipse” and “green(20,250,8) ellipse”
            +      </p>
            +
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/rJ-OSs-k7">color example on the p5 editor</a>
            +      </p>
            +
            +      <p>
            +        Instead of using Red, Green and Blue values, we can also pass just one value from 0 to 255. This is known as grayscale. It means that Red, Green and Blue will take the same value and the result will be between black and white. 0 being black, and 255 white.
            +      </p>
            +
            +      <h2>Lesson 4: Text</h2>
            +      <p>
            +        With p5, it is also possible to draw text on the canvas!
            +        We can add text to the canvas using the text() function. This function requires us input three values inside the parentheses: the text we want to display written between quotation marks, followed by the x and y position in pixels to display the text in the canvas.
            +      </p>
            +      <p>
            +        Copy and try out the below code.
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +          createCanvas(500, 500);
            +          background(200);
            +        }
            +
            +        function draw() {
            +          fill(255,0,0);
            +          text("hello world!", 50,50)
            +        }
            +      </code></pre>
            +      <p>
            +        Note that fill() also affects text() and that the text we want to write has to be written between quotation marks. Now, let’s go through the output to see what it says.
            +      </p>
            +
            +      <h3>Text output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows  :
            +        “Your output is a 500 by 500 grey(200,200,200) canvas containing the following 1 object”
            +      </p>
            +      <p>
            +        Then there is a list of the objects. (For example - “hello world!” (red(255,0,0)) at top left of the canvas
            +      </p>
            +
            +      <h3>Grid output for Lesson 4</h3>
            +      <p>
            +        The overview is as follows:
            +        “grey(200,200,200) canvas is 500 by 500 of area 250000 contains 1 object - 1 text”
            +      </p>
            +      <p>
            +        And in the table you will see the actual text and it’s color in the appropriate location (example - “hello world! (red(255,0,0))”
            +      </p>
            +      <p>
            +        You can try the <a href="http://alpha.editor.p5js.org/mathura/sketches/r1BFz3Zkm">text example on the p5 editor</a>
            +      </p>
            +
            +      <h2>Exercise: Bar Graph</h2>
            +      <p>
            +        Now that we have covered how to draw basic shapes and write text on the canvas, let’s look at how we can create a bar chart with them.
            +      </p>
            +      <p>
            +        Using rectangles and some numbers, we can create bar graphs. Since we expect the entire sketch to be static, we can do the whole thing in the setup function
            +      </p>
            +      <p>
            +        Let’s start with a sample dataset that we want to depict.
            +      </p>
            +      <p>Animals in the park:</p>
            +      <ul class="list_view">
            +        <li>Dogs - 260</li>
            +        <li>Cats - 300</li>
            +        <li>Hamsters -100</li>
            +        <li>Rabbits - 50</li>
            +        <li>Spiders - 10</li>
            +      </ul>
            +
            +      <p>
            +        First we create a canvas:
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        createCanvas(500,500);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now we can add some rectangles that represent each animal type. Notice that we will be adding comments in our code. Comments are lines in our code that are not executed and can be notes to ourselves. They start with // in the beginning of the line. We will create 5 rectangles, one for each animal type.
            +      </p>
            +
            +      <p>
            +        Remember that when we draw a rectangle, the first 2 values indicate the top left of the rectangle. If we want our bar graph to start on the left of our canvas, we need to calculate the numbers based on that. If we decide to make each bar with 50 pixels height, and to make the width represent the number of animals, for our first rectangle that represents the number of dogs the width would be 260 because there are 260 dogs. Then the values for this rectangle would be (0,0,260,50).
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	//We will use the fill() function to add color to the first bar of our chart.
            +        fill(255,0,0);
            +        //In this case our color is 255 red, 0 green, 0 blue.
            +        	rect(0, 0, 260, 50);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        Now let’s add the corresponding text:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	//Remember that the function text() requires the text, and the x, and y values for its position
            +        }
            +      </code></pre>
            +      <p>
            +        And voila! We just added the first bar on our graph chart.
            +      </p>
            +
            +      <h3>Text output for Bar Graph 1</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 2 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now lets add rectangles to represent 300 cats, 100 hamsters, 50 rabbits, and 10 spiders. Remember that the values for the function rect() in our case should be: rect(0, y position, number of animals, 50).
            +      </p>
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	rect(0, 100, 300, 50); // here the second value, y position, is 100 so that we can draw the second bar under the first bar.
            +        	text('Cats - 300', 0, 175);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +
            +      <p>
            +        The text output would be:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 2</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(red(255, 0, 0)) at top left</li>
            +        <li>red(255, 0, 0) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(red(255, 0, 0)) at top left</li>
            +      </ul>
            +      <p>
            +        Now we can add different colors to each bar:
            +      </p>
            +
            +      <pre><code class="language-javascript">
            +        function setup() {
            +        	createCanvas(500, 500);
            +        	fill(255,0,0);
            +        	rect(0, 0, 260, 50);
            +        	text('Dogs - 260', 0, 75);
            +        	fill(0,255,0);
            +        	rect(0, 100, 300, 50);
            +        	text('Cats - 300', 0, 175);
            +        	fill(0,0,255);
            +        	rect(0, 200, 100, 50);
            +        	text('Hamsters - 100', 0, 275);
            +        	fill(200,100,0);
            +        	rect(0, 300, 50, 50);
            +        	text('Rabbits - 50', 0, 375);
            +        	fill(0,200,200);
            +        	rect(0, 400, 10, 50);
            +        	text('Spiders - 10', 0, 475);
            +        }
            +      </code></pre>
            +      <p>
            +        Our bar graph is ready! Here is the output:
            +      </p>
            +
            +      <h3>Text output for Bar Graph 3</h3>
            +      <p>
            +        Your output is a 500 by 500 white canvas containing the following 10 objects:
            +      </p>
            +      <ul class="list_view">
            +        <li>red(255, 0, 0) rect at top left covering 5.20% of the canvas</li>
            +        <li>Dogs-260(red(255, 0, 0)) at top left</li>
            +        <li>green(0, 255, 0) rect at top left covering 6.00% of the canvas</li>
            +        <li>Cats-300(green(0, 255, 0)) at top left</li>
            +        <li>blue( 0, 0, 255) rect at top left covering 2.00% of the canvas</li>
            +        <li>Hamsters-100(blue( 0, 0, 255)) at top left</li>
            +        <li>orange(200, 100, 0) rect at top left covering 1.00% of the canvas</li>
            +        <li>Rabbits-50(orange(200, 100, 0)) at top left</li>
            +        <li>cyan( 0, 200, 200) rect at top left covering 0.20% of the canvas</li>
            +        <li>Spiders-10(cyan( 0, 200, 200)) at top left</li>
            +      </ul>
            +
            +      <p>
            +        Now that we created a graph together you should be able to do it by yourself and share the results with your friends!
            +      </p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/program-flow.html b/dist/zh-Hans/learn/program-flow.html
            new file mode 100644
            index 0000000000..0c18c980be
            --- /dev/null
            +++ b/dist/zh-Hans/learn/program-flow.html
            @@ -0,0 +1,581 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <div class="attribution">
            +      This tutorial is written by Alex Yixuan Xu with reference to <em>Getting Started With p5.js</em> by Lauren McCarthy, Casey Reas, and Ben Fry. Copyright 2016 Maker Media, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide">MDN JavaScript documentation</a> and <a href="https://www.w3schools.com/js">W3Schools JavaScript tutorials</a>. If you see any errors or have comments, please <a href="https://github.com/processing/processing-docs/issues?state=open">let us know</a>.
            +      </div>
            +
            +      <h1>Program Flow</h1>
            +      <!-- TOPICS -->
            +      <!-- Branching: if/else -->
            +      <!-- Loops: for/while loop -->
            +      <!-- noLoop(), loop() and redraw() -->
            +      <!-- Asynchronicity in p5.js: intro to loadImage(), preload(), callbacks -->
            +      <!-- Loading JSON & APIs -->
            +      <!-- Functions and Callbacks: list of functions -->
            +      <!-- Interactivity and Event Listeners: list of event listeners such as mousePressed() -->
            +
            +
            +
            +      <!-- https://docs.microsoft.com/en-us/scripting/javascript/controlling-program-flow-javascript -->
            +      <p>This tutorial outlines some various techniques for controlling the sequence and timing of events in your code, which is known as program flow.</p>
            +
            +      <!-- if/else stuff -->
            +      <h2>Branching</h2>
            +      <!-- https://www.w3schools.com/js/js_if_else.asp -->
            +      <p>We can use conditional statements to control the program flow. Conditional statements perform different actions based on tests for different conditions. JavaScript has the following conditional statements:</p>
            +      <ul class="list_view">
            +        <li>Use <em>if</em> to specify a block of code to be executed, if a specified condition is true</li>
            +        <li>Use <em>else</em> to specify a block of code to be executed, if the same condition is false</li>
            +        <li>Use <em>else if</em> to specify a new condition to test, if the first condition is false</li>
            +      </ul>
            +      <p>In the following example, change the value for variable i to change the color of the rectangle. If i equals to 0, the condition for the <em>if</em> statement is satisfied, and the filling color is red. In this case, the program continues to draw the rectangle skipping the <em>else if</em> and <em>else</em> statements. If i equals to 1, the condition for the <em>if</em> statement is not satisfied, and the program moves on to check the condition for the <em>else if</em> statement. Since <em>else if</em> condition is satisfied, the filling color is green. If neither the <em>if</em> nor the <em>else if</em> conditions are satisfied, the program runs the <em>else</em> statement, and the filling color is blue.</p>
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0; // change the value of i to see the change
            +function setup(){
            +  createCanvas(100, 100);
            +  rectMode(CENTER);
            +}
            +function draw(){
            +  background(200);
            +  if (i==0){
            +    fill(255, 0, 0);
            +  }
            +  else if (i==1){
            +    fill(0, 255, 0);
            +  }
            +  else{
            +    fill(0, 0, 255);
            +  }
            +  rect(width/2, height/2, 50, 50);
            +}
            +      </script>
            +
            +      <!-- for loop and while loop -->
            +      <h2>Loops</h2>
            +      <p>Loops can execute a block of code repeatedly. p5 supports several different kinds of loops in JavaScript:</p>
            +      <ul class="list_view">
            +        <li>for - loops through a block of code a specified number of times</li>
            +        <li>for/in - loops through the properties of an object</li>
            +        <li>while - loops through a block of code while a specified condition is true</li>
            +        <li>do/while - also loops through a block of code while a specified condition is true</li>
            +      </ul>
            +
            +      <p>The <em>for</em> loop sets up a variable (usually i or x) that is then incrementally changed for each loop. It has the following structure:</p>
            +      <pre><code class="language-javascript">
            +        for (statement 1; statement 2; statement 3) {
            +            code block to be executed
            +        }
            +      </code></pre>
            +      <ul class="list_view">
            +        <li>Statement 1 is executed (one time) before the execution of the code block. It sets the starting value for the variable</li>
            +        <li>Statement 2 defines the condition that must be true for the code block to be executed.</li>
            +        <li>Statement 3 is executed every time  after the code block has finished running if statement 2 evaluated to be true.</li>
            +      </ul>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  for (let i=0; i<5; i++){
            +    text(i, i*10, height/2);
            +  }
            +}
            +      </script>
            +      <p>In this example, variable i is initially set to 0. Every time the <em>for</em> loop runs, i is displayed on the screen and 1 is added to i. Note the <em>for</em> loop will only run until i equals to 4 because after this the condition that i be less than 5 will be false.</p>
            +
            +      <p>The <em>for/in</em> statement loops through the properties of an object:</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let person = {fname:"John", lname:"Doe", age:25};
            +let myText = "";
            +function setup(){
            +  let x;
            +  for (x in person) {
            +      myText += person[x];
            +      myText += " ";
            +  }
            +  text(myText, 0, height/2);
            +}
            +      </script>
            +      <p>In this example, as the <em>for</em> loop cycles through each property of the person object, the property value is added to myText string.</p>
            +
            +      <p>The while loop cycles through a block of code as long as its specified condition is true.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  while (i<5){
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +}
            +      </script>
            +      <p>This example gives the same result as the <em>for</em> loop example above. Sometimes <em>while</em> loops and <em>for</em> loops can be used interchangeably.</p>
            +
            +      <p>The <em>do/while</em> loop is a variant of the <em>while</em> loop. This loop will execute the code block once, before checking if the condition is true, it will then repeat the loop as long as the condition is true.</p>
            +      <!-- Is there an example particular to do/while? -->
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let i = 0;
            +function setup(){
            +  do {
            +    text(i, i*10, height/2);
            +    i++;
            +  }
            +  while (i < 5);
            +}
            +      </script>
            +
            +
            +      <!-- this is particular to p5 -->
            +      <h2>noLoop(), loop() and redraw()</h2>
            +      <p>The <a href="/reference/#/p5/draw">draw()</a> function in p5 runs as a loop. The code inside the draw() function runs continuously from top to bottom until the program is stopped. The draw() loop may be stopped by calling <a href="/reference/#/p5/noLoop">noLoop()</a>, and can then be resumed with <a href="/reference/#/p5/loop">loop()</a>. If using <a href="/reference/#/p5/noLoop">noLoop()</a> in <a href="/reference/#/p5/setup">setup()</a>, it should be the last line inside the block.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +function draw() {
            +  background(200);
            +  ellipse(x, height/2, 20, 20);
            +  x ++;
            +}
            +function mousePressed() {
            +  loop();
            +}
            +function mouseReleased() {
            +  noLoop();
            +}
            +        </script>
            +        <p>In this example, <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a>, so the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. Since <a href="/reference/#/p5/loop">loop()</a> is placed in <a href="/reference/#/p5/mousePressed">mousePressed()</a>, the draw() block will resume looping when mouse is pressed. When mouse is released, <a href="/reference/#/p5/noLoop">noLoop()</a> is called again and hence the draw() loop stops.</p>
            +
            +        <p>The function <a href="/reference/#/p5/redraw">redraw()</a> executes the code within <a href="/reference/#/p5/draw">draw()</a> one time. This functions allows the program to update the display window only when necessary, such as when an event registered by <a href="/reference/#/p5/mousePressed">mousePressed()</a> or <a href="/reference/#/p5/keyPressed">keyPressed()</a> occurs. In structuring a program, it only makes sense to call <a href="/reference/#/p5/redraw">redraw()</a> within events such as <a href="/reference/#/p5/mousePressed">mousePressed()</a> outside of the draw() loop. The redraw() function does not work properly when called inside draw(). In addition, you can set the number of loops through draw by adding a single argument (an integer) to the redraw() function.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let x = 0;
            +function setup() {
            +   createCanvas(100, 100);
            +   noLoop();
            + }
            +function draw() {
            +   background(200);
            +   ellipse(x, height/2, 20, 20);
            +   x ++;
            + }
            +function mousePressed() {
            +   redraw();
            + }
            +      </script>
            +      <p>This example is similar to the previous one, where <a href="/reference/#/p5/noLoop">noLoop()</a> is called in <a href="/reference/#/p5/setup">setup()</a> and the code within <a href="/reference/#/p5/draw">draw()</a> will only run once at the start of the program. However, when mouse is pressed, <a href="/reference/#/p5/redraw">redraw()</a> is called and <a href="/reference/#/p5/draw">draw()</a> will only loop once. To make smooth animations, it is easier to work with noLoop() and loop().</p>
            +
            +
            +      <h2>Asynchronicity in p5.js</h2>
            +      <p>In JavaScript, events may occur concurrently with the main program flow. This is considered as asynchronicity in programming. In p5, for example, when we use <a href="/reference/#/p5/loadImage">loadImage()</a> in <a href="/reference/#/p5/setup">setup()</a>, the browser begins the process of loading the image but skip onto the next line before it is finised loading. The following example demonstrates such asynchronicity.</p>
            +        <pre><code class="language-javascript">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +    </code></pre>
            +    <iframe src="/assets/learn/program-flow/loadImage-example-1/loadImage-example-1.html" width="150" height="150"></iframe>
            +      <!-- what's the file location??????????????????? -->
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function setup(){
            +  createCanvas(100, 100);
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p>When you run this program, you'll notice that the drawing canvas is grey with no image displayed. This is because <a href="/reference/#/p5/loadImage">loadImage()</a> begins to load the image, but does not have time to finish this task before the program continues on through the rest of <a href="/reference/#/p5/setup">setup()</a> and on to <a href="/reference/#/p5/draw">draw()</a>. Even with the <a href="/reference/#/p5/noLoop">noLoop()</a> function that stops p5.js from continuously executing the code within draw(). The <a href="/reference/#/p5/image">image()</a> function is unable to display the image as it is not properly loaded.</p>
            +
            +      <h2>Introduction to Preload</h2>
            +      <p>To help with this issue of asynchronicity, p5.js has the <a href="/reference/#/p5/preload">preload()</a> function. Unlike <a href="/reference/#/p5/setup">setup()</a>, preload() forces the program to wait until everything has loaded before moving on. It is best to only make load calls in preload(), and do all other setup in setup().</p>
            +      <pre><code class="language-javascript">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-2/loadImage-example-2.html" width="150" height="150"></iframe>
            +
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let img;
            +function preload(){
            +  img = loadImage("/assets/learn/program-flow/images/clouds.jpg");
            +}
            +
            +function setup(){
            +  createCanvas(100, 100);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +  image(img,0,0);
            +}
            +      </script> -->
            +      <p><a href="/reference/#/p5/preload">preload()</a> ensures that the image has been loaded before running the other code. </p>
            +
            +
            +
            +      <h2>Loading with a Callback</h2>
            +      <p>An alternative to <a href="/reference/#/p5/preload">preload()</a> is to use a <em>callback function</em>. A callback function is a function that is passed as an argument to a second function, and that runs after the second function has completed. The following example illustrates this technique.</p>
            +      <pre><code class="language-javascript">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </code></pre>
            +      <iframe src="/assets/learn/program-flow/loadImage-example-3/loadImage-example-3.html" width="150" height="150"></iframe>
            +<!--       <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +function setup(){
            +  createCanvas(100, 100);
            +  loadImage("/assets/learn/program-flow/images/clouds.jpg", drawImage);
            +  noLoop();
            +}
            +
            +function draw(){
            +  background(200);
            +}
            +
            +function drawImage(img){
            +  image(img, 0, 0);
            +}
            +      </script> -->
            +      <p>In this example, the second argument in <a href="/reference/#/p5/loadImage">loadImage()</a> is the function we want to run after the load is complete. Once the image has loaded, this callback function, drawImage(), is automatically called. It has one argument which contains the image that was just loaded. There is no need to create a global variable to hold the image. The image is passed directly into the callback function, as the parameter name chosen in the function definition.</p>
            +
            +
            +
            +      <h2>Loading JSON & APIs</h2>
            +      <!-- page 187 -->
            +      <p>The JSON (JavaScript Object Notation) format is a common system for storing data. Like HTML and XML formats, the elements have labels associated with them. One way to load JSON file is to use <a href="/reference/#/p5/loadJSON">loadJSON()</a> function in <a href="/reference/#/p5/preload">preload()</a>.</p>
            +      <!-- example where loadJSON() in preload() -->
            +      <p>The following request at https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson returns data of recent earthquakes in the world from USGS.</p>
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let earthquakes;
            +function preload(){
            +  earthquakes = loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson');
            +}
            +function setup(){
            +  createCanvas(200, 100);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +
            +      <p>Alternatively, <a href="/reference/#/p5/loadJSON">loadJSON()</a> can also take a callback. To use data from an API, you may need a callback function as, like with an image, the data takes time to load. API (Application Programming Interface) requests are commands that request data from a service. A lot of APIs will return data in JSON format. Some need you to authenticate with the API to use it (e.g. register as a developer and get keys). You can’t always use <a href="/reference/#/p5/preload">preload()</a> when getting data from APIs because the data might change while you sketch is running and you will want your program to respond accordingly.</p>
            +
            +      <p><a href="/reference/#/p5/loadJSON">loadJSON()</a> can be used in a few ways: </p>
            +      <ul class="list_view">
            +        <li>loadJSON(path)</li>
            +        <li>loadJSON(path, callback)</li>
            +        <li>loadJSON(path, callback, datatype)</li>
            +        <li>loadJSON(path, callback, errorCallback)</li>
            +        <li>loadJSON(path, datatype, callback, errorCallback)</li>
            +        <li>loadJSON(path, jsonpOptions, datatype, callback, errorCallback)</li>
            +      </ul>
            +      <p>
            +        where:
            +      </p>
            +      <ul class="list_view">
            +        <li>path - String: name of the file or url to load</li>
            +        <li>jsonpOptions - Object: options object for jsonp related settings</li>
            +        <li>datatype - String: "json" or "jsonp"</li>
            +        <li>callback - Function: function to be executed after loadJSON() completes, data is passed in as first argument</li>
            +        <li>errorCallback - Function: function to be executed if there is an error, response is passed in as first argument</li>
            +      </ul>
            +      <!-- example where loadJSON() takes a callback -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(200, 100);
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +}
            +      </script>
            +      <p>In this example, the <a href="/reference/#/p5/loadJSON">loadJSON()</a> function is placed in <a href="/reference/#/p5/setup">setup()</a> and takes a custom callback function showEarthquake(). This means when the program finishes loading the JSON file from the USGS earthquakes API, the function showEarthQuake() is called. The place and magnitude of the most recent earthquake listed by the API is stored in local variables within showEarthquake and are then displayed on the screen.</p>
            +
            +      <p>Sometimes we use <a href="/reference/#/p5/setInterval">setInterval()</a> to control the frequency of requests made to the API. setInterval() can also take a callback function. If you call setInterval() in <a href="/reference/#/p5/setup">setup()</a>, it will run repeatedly for the duration of the program at the interval set.</p>
            +      <!-- example setInterval() is used -->
            +      <script type="text/p5" data-autoplay data-preview-width="200" data-p5-version="1.4.1">
            +let i=1; // counter variable to keep track of the interval
            +function setup() {
            +  createCanvas(200, 100);
            +  getEarthquake();
            +  setInterval(getEarthquake, 5000); // get data every 5 seconds
            +}
            +function getEarthquake(){
            +  loadJSON('https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson', showEarthquake);
            +}
            +function showEarthquake(earthquakes){
            +  background(255);
            +  let earthquakeMag = earthquakes.features[0].properties.mag;
            +  let earthquakePlace = earthquakes.features[0].properties.place;
            +  text("Data grabbed "+i, 0, height/3);
            +  text(earthquakePlace, 0, height/2);
            +  text(earthquakeMag, 0, height-height/3);
            +  i++;
            +}
            +      </script>
            +      <p>In this example, the earthquake data is grabbed from the API every 5 seconds and is displayed on the screen.</p>
            +
            +
            +
            +
            +      <!-- list the functions that accept callbacks? Is this section necessary?-->
            +      <h2>More Callback Functions</h2>
            +      <p>In addition to the <a href="/reference/#/p5/loadImage">loadImage()</a>, <a href="/reference/#/p5/loadJSON">loadJSON()</a> and <a href="/reference/#/p5/setInterval">setInterval()</a>, there are other functions in p5 that accept callbacks. Typically, functions that involve loading data of some kind accept callbacks, or should be put in <a href="/reference/#/p5/preload">preload()</a>. For example:</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/loadFont">loadFont()</a></li>
            +        <li><a href="/reference/#/p5/loadSound">loadSound()</a></li>
            +        <li><a href="/reference/#/p5/loadStrings">loadStrings()</a></li>
            +        <li><a href="/reference/#/p5/loadTable">loadTable()</a></li>
            +        <li><a href="/reference/#/p5/loadXML">loadXML()</a></li>
            +        <li><a href="/reference/#/p5/loadBytes">loadBytes()</a></li>
            +        <li><a href="/reference/#/p5/loadModel">loadModel()</a></li>
            +      </ul>
            +
            +      <p>DOM functionality makes it easy to interact with other HTML5 objects, including text, hyperlink, image, input, video, audio, and webcam. Some DOM creation methods also accept callbacks: </p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/createImg">createImg()</a></li>
            +        <li><a href="/reference/#/p5/createFileInput">createFileInput()</a></li>
            +        <li><a href="/reference/#/p5/createVideo">createVideo()</a></li>
            +        <li><a href="/reference/#/p5/createAudio">createAudio()</a></li>
            +        <li><a href="/reference/#/p5/createCapture">createCapture()</a></li>
            +      </ul>
            +
            +
            +      <h2>Interactivity and Event Listeners</h2>
            +      <p>Callback functions are functions that can be passed as an argument into another function and be executed after the first function is complete. An event listener or handler is a type of callback. It is called whenever an event occurs such as when the mouse is pressed, or a key is pressed etc.</p>
            +      <p>Mouse functions like <a href="/reference/#/p5/mousePressed">mousePressed()</a>, <a href="/reference/#/p5/mouseClicked">mouseClicked()</a>, <a href="/reference/#/p5/mouseReleased">mouseReleased()</a>, <a href="/reference/#/p5/mouseMoved">mouseMoved()</a>, etc. can be used as event listeners. They can be attached to certain elements in a sketch.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mousePressed">mousePressed()</a> - Code inside this block is run one time when a mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/mouseReleased">mouseReleased()</a> - Code inside this block is run one time when a mouse button is released</li>
            +        <li><a href="/reference/#/p5/mouseClicked">mouseClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element</li>
            +        <li><a href="/reference/#/p5/doubleClicked">doubleClicked()</a> - Code inside this block is run once after a mouse button is pressed and released over the element twice</li>
            +        <li><a href="/reference/#/p5/mouseWheel">mouseWheel()</a> - Code inside this block is run once when mouse wheel is scrolled over the element</li>
            +        <li><a href="/reference/#/p5/mouseMoved">mouseMoved()</a> - Code inside this block is run one time when the mouse is moved</li>
            +        <li><a href="/reference/#/p5/mouseOver">mouseOver()</a> - Code inside this block is run once after every time a mouse moves onto the element.</li>
            +        <li><a href="/reference/#/p5/mouseOut">mouseOut()</a> - Code inside this block is run once after every time a mouse moves off the element</li>
            +      </ul>
            +
            +      <p>In this example, a canvas element is created and an event listener <a href="/reference/#/p5/mousePressed">mousePressed()</a> is attached. Function changeGrey() will only run when the mouse is pressed over the canvas, and will will change the background color to a random grey. If the mouse is pressed anywhere, even outside of the canvas, the diameter of the ellipse will increase by 10 pixels. The custom function changeGray(), in this instance, is placed within the <a href="/reference/#/p5/mousePressed">mousePressed()</a> function and is to be triggered when mouse is pressed over the canvas element. If the mouse is not pressed, false is passed and changeGrey() will not run.</p>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +let cnv;
            +let d;
            +let g;
            +function setup() {
            +  cnv = createCanvas(100, 100);
            +  cnv.mousePressed(changeGray); // attach listener for canvas click only
            +  d = 10;
            +  g = 100;
            +}
            +
            +function draw() {
            +  background(g);
            +  ellipse(width / 2, height / 2, d, d);
            +}
            +
            +// this function fires with any click anywhere
            +function mousePressed() {
            +  d = d + 10;
            +}
            +
            +// this function fires only when cnv is clicked
            +function changeGray() {
            +  g = random(0, 255);
            +}
            +      </script>
            +
            +      <p>The above mouse functions can be attached to an element like the canvas or can be used without specifying an element. The keyboard functions <a href="/reference/#/p5/keyPressed">keyPressed()</a>, <a href="/reference/#/p5/keyReleased">keyReleased()</a>, <a href="/reference/#/p5/keyTyped">keyTyped()</a>, and mouse function <a href="/reference/#/p5/mouseDragged">mouseDragged()</a> cannot be attached to a specific element.</p>
            +      <ul class="list_view">
            +        <li><a href="/reference/#/p5/mouseDragged">mouseDragged()</a> - Code inside this block runs once when the mouse is moved and the mouse button is pressed</li>
            +        <li><a href="/reference/#/p5/keyPressed">keyPressed()</a> - Code inside this block runs once when any key is pressed</li>
            +        <li><a href="/reference/#/p5/keyTyped">keyTyped()</a> - Code inside this block is runs once when a key is pressed, but action keys such as Ctrl, Shift, and Alt are ignored. The most recent key pressed will be stored in the <a href="/reference/#/p5/key">key</a> variable.</li>
            +        <li><a href="/reference/#/p5/keyReleased">keyReleased()</a> - Code inside this block is runs once when any key is released</li>
            +      </ul>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/tdd.html b/dist/zh-Hans/learn/tdd.html
            new file mode 100644
            index 0000000000..6a6b9b7645
            --- /dev/null
            +++ b/dist/zh-Hans/learn/tdd.html
            @@ -0,0 +1,661 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>Unit Testing and Test Driven Development</h1>
            +      <div class="attribution">
            +        This tutorial was written by <a href='https://github.com/andrewjtimmons'>Andy Timmons</a>.
            +      </div>
            +
            +      <h2>Overview</h2>
            +      <p>
            +        This tutorial will walk you through setting up your development environment to run unit tests against your code. Unit testing is a method of applying tests to the classes and functions in your code. It can catch bugs, help you collaborate with others, and code faster. Test driven development is a method of writing your tests before you write code so you have all of your tests when you finish.
            +      </p>
            +      <p>
            +        This tutorial is intended for people who:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>Have written p5.js sketches before.</li>
            +          <li>Are comfortable using javascript <a href='http://p5js.org/examples/structure-functions.html'>functions.</a></li>
            +          <li>Can run basic terminal commands.  If you are not familiar using a terminal here is a <a href='http://lifehacker.com/5633909/who-needs-a-mouse-learn-to-use-the-command-line-for-almost-anything'>good tutorial for getting comfortable.</a></li>
            +        </ul>
            +
            +      <h2> Why unit test?</h2>
            +      <p>
            +        In late 1998 NASA launched the Mars Climate Orbiter in collaboration with Lockheed Martin. This robotic space probe cost 193 million dollars and took one year to arrive and establish its orbit around Mars. Minutes later it crashed into Mars and exploded. NASA later determined it was a software error. The Lockheed Martin navigation code gave measurements in English units like feet, and the NASA code expected the measurements to be in metric units like meters. The difference between the two caused the crash. [<a href='https://en.wikipedia.org/wiki/Mars_Climate_Orbiter'>Citation</a>]
            +      </p>
            +      <p>
            +        Unit testing could have prevented this error and while you might not be launching spaceships (but by all means please try), unit testing can prevent a lot of headaches from the outset of your project to install day. It can help you:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>improve your design and reduce bugs</li>
            +          <li>collaborate with others</li>
            +          <li>finish your project faster</li>
            +        </ul>
            +
            +      <h2>Setting up for unit testing</h2>
            +      <p>
            +        Installing node:
            +      </p>
            +        <ol>
            +          <li>First you must install node. If you already have node installed this assumes you are using version 4 or higher.  Node is a open source runtime environment for building server side applications.  Don’t worry if that sentence didn’t make sense.  You don’t have to understand all there is to know about node to do this tutorial.  If you are curious to learn more you can read the <a href='https://github.com/processing/p5.js/wiki/p5.js,-node.js,-socket.io'>p5.js node tutorial.</a></li>
            +          <li>On Mac, Linux, Windows:  Go to <a href='https://nodejs.org/en/'>https://nodejs.org/en/</a> and download the installer.  Open the installer and follow the directions.</li>
            +          <li>
            +            Once the installer finishes open a terminal and run the following command to verify it installed correctly.  You should see something like "v6.6.0" or some other numbers that indicate the version you installed.<br />
            +            <pre><code class="language-javascript">
            +            node -v
            +            </code></pre>
            +          </li>
            +        </ol>
            +      <p>
            +        Update npm, the Node Package Manager.  Npm is a program that allows you to install software libraries that are compatible with node.  In your open terminal run the command:
            +        <pre><code class="language-javascript">
            +          sudo npm install npm@latest -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the chai assertion library.  This is what you will use to build your tests.  In the terminal window run the command:
            +        <pre><code class="language-javascript">
            +          npm install chai -g
            +        </code></pre>
            +      </p>
            +      <p>
            +        Use npm to install the mocha test running library.  Mocha drives your chai tests.  Much like a person drives a car.  In the terminal window run:
            +        <pre><code class="language-javascript">
            +          npm install mocha -g
            +        </code></pre>
            +      </p>
            +
            +      <h2>A sketch without tests</h2>
            +      <p>
            +        Your goal today is to make a sketch with a square whose fill color loops over every RGB color.
            +      </p>
            +      <p>
            +        Let’s set up the project. This is what it would look like without any unit tests.
            +      </p>
            +        <ol>
            +          <li>Make a folder called color_unit_test and open it</li>
            +          <li>
            +            Make a file called index.html and type the following code.  While you can just copy/paste it, typing it out will help you understand what it is doing better.  It is worth the time!<br />
            +            <pre><code class="language-javascript">
            +              &lt;!DOCTYPE html&gt;
            +              &lt;html&gt;
            +              &lt;head&gt;
            +                &lt;meta charset="UTF-8"&gt;
            +                &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
            +                &lt;script src="https://cdn.jsdelivr.net/npm/p5@0.4.20/lib/p5.js"&gt;&lt;/script&gt;
            +                &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +                &lt;style&gt; body {padding: 0; margin: 0;} &lt;/style&gt;
            +              &lt;/head&gt;
            +              &lt;body&gt;
            +              &lt;/body&gt;
            +              &lt;/html&gt;
            +            </code></pre>
            +          </li>
            +          <li>
            +            make a file called sketch.js and put in the following code<br />
            +            <pre><code class="language-javascript">
            +              // This is for a unit test tutorial.
            +              // it should create a rectangle and allow you to iterate over
            +              // every single color.
            +              //
            +              // colorValueIncrease sets the amount the color changes on each
            +              // draw loop. Values greater than 255 will break the sketch.
            +              // fillColor will be the color of the rectangle.
            +              // colorIncreaser will become an instance of our ColorIncreaser class.
            +
            +              let colorValueIncrease = 1;
            +              let fillColor;
            +              let colorIncreaser;
            +
            +              function setup() {
            +                createCanvas(500, 500);
            +                background(0);
            +                fillColor = color(0, 0, 0, 255);
            +                noStroke();
            +              }
            +
            +              function draw() {
            +                fill(fillColor);
            +                rect(0, 0, 500, 500);
            +
            +                // increment the red value
            +                fillColor.levels[0] += colorValueIncrease;
            +                // If the red value is maxed out increment the green value
            +                // and reset the red value.
            +                if (fillColor.levels[0] > 255) {
            +                  fillColor.levels[0] = 0;
            +                  fillColor.levels[1] += colorValueIncrease;
            +                }
            +                // If the green value is maxed out increment the blue value
            +                // and reset the green value.
            +                if (fillColor.levels[1] > 255) {
            +                  fillColor.levels[1] = 0;
            +                  fillColor.levels[2] += colorValueIncrease;
            +                }
            +                // If the blue value is maxed out reset the green value.
            +                if (fillColor.levels[2] > 255) {
            +                  fillColor.levels[2] = 0;
            +                }
            +              }
            +            </code></pre>
            +          </li>
            +          <li>
            +           Open the index.html file in your browser (you don’t need to run a local server in this case). You should see a black box become red and then black again. This is the basis of looping over all the RGB colors. The problem you face is that there are 256 values for red, green, and blue, which means there are over 16 million combinations of colors! You can make this faster. However, making this faster will cause flashing lights which might give some people headaches or seizures. Please only increase this value if you do not have issues with flashing lights. The rest of the tutorial should be fine.  In the sketch.js file change the<pre><code class="language-javascript">let colorValueIncrease = 33;</code></pre> and reload the page. However this still doesn’t guarantee this is working properly. You don’t have time to watch all the colors change nor can you tell yourself if it is iterating through the millions of colors. Change the colorValueIncrease variable back to 1 before you move on.
            +          </li>
            +          <li>
            +            At 30 draw loops per second it would take over six days to loop through all of the colors. You certainly don’t have time to do that once, and would never be able to check and see if it worked every time you updated our code. What if you accidentally change something in our draw loop that breaks the code right before install?  You wouldn’t know until it was live and everyone saw your sketch break.
            +          </li>
            +        </ol>
            +
            +      <h2>Your first unit tests</h2>
            +      <p>
            +        Unit testing can help us out here. The majority of the time spent in this program is the actual drawing of the pixels. Adding 1 and checking a few if statements is very fast if you don’t need to draw the actual pixels. So you can check if the color values increase as expected without having to actually watch them all increase on your screen.
            +      </p>
            +      <p>
            +        In the folder called color_unit_test that you already created, make a new folder called test.  Open the test folder and make a file called test.js.  Type this code into test.js
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +
            +
            +          // Create the variable you are going to test
            +          let p5js = 'awesome';
            +
            +
            +          // describe lets you comment on what this block of code is for.
            +          describe('these are my first tests for p5js', function() {
            +
            +
            +            // it() lets you comment on what an individual test is about.
            +            it('should be a string', function(done) {
            +              // expect is the actual test.  This test checks if the var is a string.
            +              expect(p5js).to.be.a('string');
            +              // done tells the program the test is complete.
            +              done();
            +            });
            +
            +
            +            it('should be equal to awesome', function(done) {
            +              // This expect tests the value of the string.
            +              expect(p5js).to.equal('awesome');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your command line and <a href='http://ss64.com/bash/cd.html'>cd</a> into the main directory of our sketch called color_unit_test.  Type the command
            +        <pre><code class="language-javascript">mocha</code></pre>
            +      </p>
            +      <p>
            +        into the command line and watch your first test run!  You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              ✓ should be a string
            +              ✓ should be equal to awesome
            +            2 passing (14ms)
            +        </code></pre>
            +      </p>
            +      <p>
            +        Let's look at what happens when tests fail. Change line 6 in test.js from:
            +        <pre><code class="language-javascript">let p5js = 'awesome';</code></pre>
            +      </p>
            +      <p>
            +        to
            +        <pre><code class="language-javascript">let p5js = 42;</code></pre>
            +      </p>
            +      <p>
            +        Save test.js and go back to your terminal and run the mocha command again. You should see something like:
            +        <pre><code class="language-javascript">
            +          these are my first tests for p5js
            +              1) should be a string
            +              2) should be equal to awesome
            +
            +            0 passing (18ms)
            +            2 failing
            +
            +            1) these are my first tests for p5js should be a string:
            +               AssertionError: expected 42 to be a string
            +                at Context.<anonymous> (test/test.js:14:24)
            +
            +            2) these are my first tests for p5js should be equal to awesome:
            +               AssertionError: expected 42 to equal 'awesome'
            +                at Context.<anonymous> (test/test.js:21:21)
            +        </code></pre>
            +      </p>
            +      <p>
            +        What is nice about these errors is:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>They tell you the name of the test that you put in the describe() and it() functions</li>
            +          <li>They tell you what they expected with AssertionError: expected 42 to be a string</li>
            +          <li>They tell you what file and line of code had the problem test/test.js:14:24</li>
            +        </ul>
            +      <p>
            +        Now that you know the basics of unit testing you are ready to write some tests against your code and refactor your sketch!
            +      </p>
            +
            +      <h2>Test Driven Development</h2>
            +      <p>
            +        You are going to use Test Driven Development for the rest of this tutorial.  The idea is you write your unit tests first, run them and watch them fail, and then add code to sketch.js to make the tests pass.  This way you ensure your code is working as you expect every step of the way and that new code doesn’t break old code.  Your goal is to create a ColorIncreaser class that:
            +      </p>
            +        <ul class="bullet-list">
            +          <li>takes in an integer as the value to increase each time called colorValueIncrease.</li>
            +          <li>takes in an instance of the <a href='http://p5js.org/reference/#/p5/color'>p5 color class.</a></li>
            +          <li>has a function to increase the values in the color by the value in colorValueIncreases.</li>
            +        </ul>
            +      <p>
            +        Delete everything in test.js and replace it with this
            +        <pre><code class="language-javascript">
            +          'use strict';
            +
            +          // Import the expect library.  This is what allows us to check our code.
            +          // You can check out the full documentation at http://chaijs.com/api/bdd/
            +          const expect = require('chai').expect;
            +          // Import our ColorIncreaser class.
            +          const ColorIncreaser = require('../sketch');
            +
            +          describe('ColorIncreaser tests', function() {
            +            // Will hold the reference to the ColorIncreaser class
            +            let colorIncreaser;
            +
            +            // beforeEach is a special function that is similar to the setup function in
            +            // p5.js.  The major difference it that this function runs before each it()
            +            // test you create instead of running just once before the draw loop
            +            // beforeEach lets you setup the objects you want to test in an easy fashion.
            +            beforeEach(function() {
            +                colorIncreaser = new ColorIncreaser();
            +            });
            +
            +            it('should be an object', function(done) {
            +              expect(colorIncreaser).to.be.a('object');
            +              done();
            +            });
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command in your terminal and watch your new test fail!  The crux of the error is “TypeError: ColorIncreaser is not a constructor”.  This makes sense because you have not created a ColorIncreaser class in our sketch yet. <br />
            +
            +        Go to the bottom of your sketch.js file, below the closing bracket } for the draw function, and add this:
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor() {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +            }
            +          }
            +
            +          module.exports = ColorIncreaser;
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  The function line will be our color increasing object.  The module.exports line is what allows our test.js file to import our ColorIncreaser with the line you already added that looks like this:
            +        <pre><code class="language-javascript">
            +           const ColorIncreaser = require('../sketch');
            +        </code></pre>
            +      </p>
            +      <p>
            +        If you go back to your terminal and run mocha your test should pass.<br />
            +
            +        Now get your ColorIncreaser function to actually do something.  Start by storing the colorValueIncrease as a variable in your class.  Before you change the code in sketch.js you have to write your tests.  Change the beforeEach function in test.js to look like this
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        and add a new it() test below it like this
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        Now run the mocha command and you will get the pivotal line:<br />
            +        AssertionError: expected undefined to equal 1<br />
            +        because you have not added this to your class yet. You need to add that value to get this to work. Add this line to the setup function in sketch.js under noStroke();
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease);
            +        </code></pre>
            +        and change the ColorIncreaser function to look like this
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser() {
            +            constructor(colorValueIncrease) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +            }
            +          }
            +        </code></pre>
            +        Let’s run the mocha test again.  It should pass!
            +      </p>
            +
            +      <h2>Testing when your object is composed of other objects</h2>
            +      <p>
            +        Now you need to add an instance of the p5 color class to our ColorIncreaser. However, for your tests, you don’t want to use an actual instance of the color() class because you don’t want to test external dependencies given by another library.You just want to make sure that your increment function works. So you are going to create what is called a mock of the p5 color class so you can test without worrying about the implementation of code you didn’t write.
            +      </p>
            +      <p>
            +        The original way of incrementing colors just used the color.levels and changed the red, green and blue values at index [0], [1], and [2].  You can see this in the draw function in sketch.js.  The implementation of color just stores those values in a javascript array so you can mock it out very easily.  Put this code in test.js below the const ColorIncreaser = require… line and above the describe line
            +        <pre><code class="language-javascript">
            +          function mockColor(red, green, blue, alpha) {
            +              // Mock of the color class from p5
            +              this.levels = [];
            +              this.levels[0] = red;
            +              this.levels[1] = green;
            +              this.levels[2] = blue;
            +              this.levels[3] = alpha;
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Update your beforeEach() function
            +        <pre><code class="language-javascript">
            +          beforeEach(function() {
            +              let colorValueIncrease = 1;
            +              let fillColor = new mockColor(0, 0, 0, 255);
            +              colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And update the it('should initialize without mutation', function block
            +        <pre><code class="language-javascript">
            +          it('should store initial values without mutation', function(done) {
            +            expect(colorIncreaser.colorValueIncrease).to.be.equal(1);
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[3]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And run the tests!  Failure!   TypeError: Cannot read property 'levels' of undefined<br />
            +        You have to update the ColorIncreaser class to take in a fillColor variable.  It is an easy fix.  In sketch.js change the colorIncreaser line in setup() to look like this
            +        <pre><code class="language-javascript">
            +          colorIncreaser = new ColorIncreaser(colorValueIncrease, fillColor);
            +        </code></pre>
            +      </p>
            +      <p>
            +        and update the ColorValueIncreaser function
            +        <pre><code class="language-javascript">
            +          class ColorIncreaser {
            +            constructor(colorValueIncrease, fillColor) {
            +              // Stores a value and a color and allows you to increase the color
            +              // by that value.
            +              this.colorValueIncrease = colorValueIncrease
            +              this.fillColor = fillColor;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Run the tests again and they should pass!
            +      </p>
            +      <p>
            +        Now you have all the initialized variables you need to make the class work.  This provides the scaffold on which you will build your method to increase the color value and iterate over every color.
            +      </p>
            +
            +      <h2>Testing class methods</h2>
            +      <p>
            +        You are going to make a class method called increaseFillColor. It will basically run the code that is currently in our draw loop, but use the values stored in our ColorIncreaser class to do it.
            +      </p>
            +      <p>
            +        As covered before there are 256 values for red, green and blue giving 16,777,216 color combinations. While that might seem overwhelming you can test it easily because you know what values should be present in red, green and blue after each time you call our increaseFillColor function. For example if you start with the color black with the rgb levels 0,0,0 and you call increaseFillColor once you know you should now have the values 1,0,0.  So you are going to add tests in test.js for calling increaseFillColor 255, 65535 and 16777215 times.
            +        <pre><code class="language-javascript">
            +          it('should have rgb values 255, 0, 0 after calling increaseFillColor 255 times', function(done) {
            +            //it is 256^1 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 255; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(0)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 0 after calling increaseFillColor 65535 times', function(done) {
            +            //it is 256^2 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 65535; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(0)
            +            done();
            +          });
            +
            +
            +          it('should have rgb values 255, 255, 255 after calling increaseFillColor 16777215 times', function(done) {
            +            //it is 256^3 - 1 because it starts with the color black
            +            for (let count = 0; count &lt; 16777215; count += 1) {
            +                colorIncreaser.increaseFillColor()
            +            }
            +            expect(colorIncreaser.fillColor.levels[0]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[1]).to.equal(255)
            +            expect(colorIncreaser.fillColor.levels[2]).to.equal(255)
            +            done();
            +          });
            +        </code></pre>
            +      </p>
            +      <p>
            +        And when you run mocha the tests will fail because that function does not exist!  Let’s add a skeleton function in sketch.js inside the ColorIncreaser class below the constructor function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        Save sketch.js.  Now when you run mocha the tests fail for a different reason.  It finds the function, but it doesn’t do what you expect it to.  Let’s change the function in sketch.js to look like what is inside the draw function.
            +        <pre><code class="language-javascript">
            +          increaseFillColor() {
            +            // increase the first color channel by one.  If that channel
            +            // is now > 255 then increment the next color channel.  Repeat for second
            +            // and third channel
            +
            +            this.fillColor.levels[0] += this.colorValueIncrease
            +            this.numColorsSoFar += 1
            +
            +
            +            if (this.fillColor.levels[0] > 255) {
            +              this.fillColor.levels[0] = 0
            +              this.fillColor.levels[1] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[1] > 255) {
            +              this.fillColor.levels[1] = 0
            +              this.fillColor.levels[2] += this.colorValueIncrease
            +            }
            +            if (this.fillColor.levels[2] > 255) {
            +              this.fillColor.levels[2] = 0;
            +            }
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        And now your tests pass!  Hooray!<br />
            +        Now you just need to get the draw function set up.  Replace the draw function in sketch.js with this:
            +        <pre><code class="language-javascript">
            +          function draw() {
            +            fill(colorIncreaser.fillColor);
            +            rect(0, 0, 500, 500);
            +            colorIncreaser.increaseFillColor()
            +          }
            +        </code></pre>
            +      </p>
            +      <p>
            +        All tests should pass now and you can expect your code to behave as you want!  As a bonus when you change the code in the future the tests will let you know that it still works as intended!<br />
            +        Congratulations, you made it to the end! Unit tests and Test Driven Development are powerful ways to build code that you know works just as you expect. <br />
            +        You can continue to build on your skills by
            +      </p>
            +        <ul class="bullet-list">
            +          <li>adding tests to your own sketches and projects</li>
            +          <li>Reading up on the tools we’ve used here:</li>
            +          <ul class="bullet-list">
            +            <li><a href='http://www.agiledata.org/essays/tdd.html'>Test Driven Development and Unit tests</a></li>
            +            <li><a href='https://www.npmjs.com/'>Node Package Manager (NPM)</a></li>
            +            <li><a href='http://chaijs.com/'>Chai</a></li>
            +            <li><a href='https://mochajs.org/'>Mocha</a></li>
            +            <li><a href='https://en.wikipedia.org/wiki/Mock_object'>Mock Objects</a></li>
            +          </ul>
            +        </ul>
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/test-tutorial.html b/dist/zh-Hans/learn/test-tutorial.html
            new file mode 100644
            index 0000000000..b240803cca
            --- /dev/null
            +++ b/dist/zh-Hans/learn/test-tutorial.html
            @@ -0,0 +1,179 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>test tutorial title</h1>
            +
            +      <p>Blah blah blah. Here is some formatted code:</p>
            +
            +      <pre><code class="language-javascript">
            +      var note = "this is formatted code!";
            +      </code></pre>
            +
            +      <p>Blah blah blah. Here is an iframe embedded:</p>
            +
            +      <iframe src="../../assets/learn/test-tutorial/embed.html" width="600" height="400"></iframe>
            +
            +      <p>Blah blah blah. Here is p5-widget embedded:</p>
            +
            +      <!-- this script only needs to get added once even if there are multiple widget instances -->
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-p5-version="1.4.1">
            +function setup() {
            +  createCanvas(100, 100);
            +}
            +
            +function draw() {
            +  background(255, 0, 200);
            +}
            +</script>
            +
            +      <p>The end!</p>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/transformations.html b/dist/zh-Hans/learn/transformations.html
            new file mode 100644
            index 0000000000..e6160e7eac
            --- /dev/null
            +++ b/dist/zh-Hans/learn/transformations.html
            @@ -0,0 +1,616 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <div class="attribution">
            +      This tutorial is written by Gene Kogan. It was ported to P5 by Sally Chen. If you see any errors or have comments, <a href="https://github.com/processing/p5.js/issues"> please let us know.</a>
            +
            +      </div>
            +
            +      <h1>Transformations</h1>
            +
            +      <p>
            +      The p5.js canvas works like a piece of graph paper. When you want to draw something, you specify its coordinates on the graph. For example, we can draw a 40x40 pixel rectangle at the point (30, 30).
            +      </p>
            +
            +      <script src="//toolness.github.io/p5.js-widget/p5-widget.js"></script>
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      If you want to move your rectangle 50 pixels to the right and 50 pixels down, you can add that to the x and y-coordinates of the rectangle and run rect(80, 80, 40, 40). But there is another way to do this:
            +      move the graph paper itself. If you move the graph paper 50 pixels right and 50 pixels down, you will get exactly the same visual result. Moving the coordinate system is called translation, and can be done using the translate() function.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	fill(0);
            +}
            +
            +function draw() {
            +	background(240);
            +	translate(50, 50);
            +	drawGrid();
            +	fill(0);
            +	rect(30, 30, 40, 40);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +	fill(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <p>
            +      As far as the rectangle is concerned, it hasn't moved at all. Its upper left corner is still at (30, 70). When you use transformations, the things you draw never change position; the coordinate system itself does. We will see how this can be useful in the next section.
            +    </p>
            +      <h2>push() and pop()</h2>
            +
            +      <p>
            +      Sometimes, a sketch will involve multiple translations to draw the same thing in different locations. If we want to draw the same rectangle in three separate locations -- say at (25, 25), (50, 75), and (75, 100) -- we can use push() and pop() to
            +      keep track of and revert our translations as we go. The function pop() undoes all translations made following the previous push(). push() and pop() also track and revert style and,  color changes -- fill(), stroke(), etc -- in the same way. Thus all translations
            +      and style/color commands made between a single push() and pop() apply only to the operations made between them. Take a look at the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw() {
            +	background(240);
            +
            +	push();
            +  	translate(25, 25);
            +	fill(255, 0, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(75, 100);
            +	fill(0, 255, 0);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +
            +	push();
            +  	translate(50, 75);
            +	fill(0, 0, 255);
            +  	rect(0, 0, 25, 25);
            +	pop();
            +}
            +      </script>
            +
            +      <p>
            +      The first triangle in red is drawn at (0, 0) after the coordinate system has been translated to the right and down by 25 pixels each. After the first pop() is called, the first translation is undone and the coordinate (0, 0) reverts back to the top-left corner of the canvas.
            +      We call push() and translate(75, 100), now moving the the canvas 75 pixels right and 100 pixels done, and then draw the green rectangle. The second pop() undoes that translation as well. Finally, the blue triangle is done after making the same operation, this time translating 50 pixels right and 75 pixels down.
            +    </p>
            +
            +      <h2>What's the Advantage</h2>
            +
            +      <p>In the last sketch, we could have achieved the same visual output by simply drawing the rectangles at those exact points. Or we could have used translate() without the push() and pop() blocks by undoing each translation manually, e.g. translate(-25, -25) to undo the first translation of (25, 25).</p>
            +      <p>For simple shapes like rectangles, it is easier to not use translations, but rather to specify the points manually. But when we begin to draw more complex shapes, translations become advantageous. Let's take a look at an example where translate(), push(), and pop() are really useful.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +	for (var x = 5; x < 150; x = x+25){
            +		for (var y = 5; y < 200; y = y+25){
            +			push();
            +			translate(x, y);
            +	  		drawHouse();
            +			pop();
            +		}
            +	}
            +}
            +
            +function drawHouse() {
            +	triangle(7.5, 0, 0, 7.5, 15, 7.5);
            +	rect(0, 7.5, 15, 12.5);
            +	rect(6, 15, 5, 5);
            +}
            +      </script>
            +
            +      <p>
            +      In this example, we draw a grid of houses. Instead of having to keep track of the coordinates for every vertex of every house, we simply have one function, drawHouse() which draws a house relative to the point (0, 0). We then create a loop which will translate to the correct point before drawing each house.
            +      </p>
            +
            +      <p>
            +      Using the transformations command allows us to use a single drawing function irrespective of where we intend to draw it on the canvas, while push() and pop() allow us to reserve transformations only to the relevant code blocks.
            +      </p>
            +
            +      <h2>Rotation</h2>
            +
            +      <p>
            +      In addition to translating the grid, you can also rotate it with the rotate() function. This function takes one argument, the angle of rotation. It then rotates the canvas around the origin point (0, 0). It's as though you have a piece of graph paper, place your finger on the point (0, 0), and then rotate the paper around your finger.
            +      </p>
            +
            +      <p>Angle is measured clockwise with zero being at 3 o'clock. In p5.js, all the functions having to do with angles take radians. A single rotation or a full circle has 360° or 2π radians. Here is a diagram of how p5.js measures angles in degrees (black) and radians (red).</p>
            +
            +      <img src="../../assets/learn/transformations/angles.png" style="width:150px;">
            +
            +      <p>Since most people think in degrees, p5.js has a built-in radians() function which takes a number of degrees as its argument and converts it to radians for you. It also has a degrees() function that converts radians to degrees. Take a look at the following example which rotates the canvas by an angle measurement set by the mouseX position.
            +      The red square is drawn before rotation, and the green one after rotation.</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw() {
            +	var deg = mouseX;
            +	var rad = radians(deg);
            +
            +	background(240);
            +
            +	// the red rectangle is drawn before the rotation so
            +	// it will stay in place
            +	fill(255, 0, 0);
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 50);
            +
            +	fill(0, 255, 0);
            +	text("rotate "+floor(deg)+" degrees", 50, 25);
            +
            +	// rotation is done here. all subsequent drawing
            +	// is done post-rotation
            +	rotate(rad);
            +
            +	// draw the grid
            +	drawGrid();
            +
            +	// the green rectangle and grid is drawn after rotating the canvas
            +	rect(50, 50, 50, 50);
            +	line(0, 0, 50, 500);
            +}
            +
            +function drawGrid() {
            +	stroke(200);
            +    fill(120);
            +	for (var x=-2*width; x < 2*width; x+=40) {
            +		line(x, -2*height, x, 2*height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-2*height; y < 2*height; y+=40) {
            +		line(-2*width, y, 2*width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +      <h2> Rotating in place</h2>
            +
            +      <p>In the last example, the green square goes off the screen as we rotate the canvas more. Sometimes we want to be able to rotate a shape in place, rather than around the top-left corner of the screen. We can do this by combining translate() and rotate() together. Recall that translate() moves the origin (0,0) to another place in the canvas and that rotate() rotates the canvas around the origin.
            +        Thus if we want to draw a shape in the middle of the screen and then rotate it in place, we should first translate the canvas to the point we want to draw the shape, then rotate, then draw the shape at (0, 0). Take a look at the following example.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +        <p>If you want the rectangle to rotate around its own center point rather than by its corner, we can use the command rectMode(CENTER) to set p5.js to interpret the coordinates of rectangles to refer to the center of the rectangle rather than the top-left corner. The following example is the same as the previous one but with centered coordinates.</p>
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup(){
            +	createCanvas(150, 200);
            +	rectMode(CENTER);	// now the first two arguments of a rect are its center point, not corner
            +}
            +function draw(){
            +	background(240);
            +
            +	// move the origin to the pivot point
            +	translate(75, 100);
            +
            +	// then rotate the grid around the pivot point by a
            +	// number of degrees equal to the frame count of the sketch
            +	rotate(radians(frameCount));
            +
            +	// and draw the square at the origin
            +	fill(0);
            +	rect(0, 0, 50, 50);
            +}
            +        </script>
            +
            +      <p>Here is a program that generates a wheel of colors by using rotation, and draws a strip every 25 frames.</p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	background(240);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	// the modulo operator % calculates the remainder.
            +	// example: 24 % 25 = 24, 25 % 25 = 0, 26 % 25 = 1, etc.
            +	// thus this if statement will evaluate True every 25 frames.
            +	if (frameCount % 25 == 0) {
            +		fill(random(255), random(255), random(255));
            +		push();
            +		translate(75, 100);
            +		rotate(radians(frameCount));
            +		rect(0, 0, 100, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +        <h2>Rotational Symmetry</h2>
            +
            +        <p>
            +        Let's take a look at a more complicated example where we can use translate and rotate together to create interesting symmetries around the center of the canvas. Let's first build it by drawing 8 squares which are evenly distributed along a circle around the center of the canvas. What we do is we first translate to the center of the screen, translating the canvas by (width/2, height/2).
            +        We then rotate the canvas to the 8 angles evenly distributed between 0 and 2π radians. We then draw a circle 50 pixels away from the center, after each of these rotations.
            +        </p>
            +
            +        <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +        function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		rect(50, 0, 10, 10);
            +		pop();
            +	}
            +}
            +        </script>
            +
            +      <p>
            +        Look at the line rect(50, 0, 10, 10). Recall that you can draw a shape in the same place by translating to it first and then drawing it at (0, 0). So we can do another another translation after we've rotated, to translate along the right-pointing line after it's been rotated. So we can replace the statement rect(50, 0, 10, 10) with the following two: translate(50, 0) and rect(0, 0, 10, 10).
            +        By doing so, we bring the pivot point or origin of the canvas to each of the eight rectangles we just drew.
            +      </p>
            +
            +      <p>
            +        This is convenient because now we can do something even more interesting. Instead of simply drawing a rectangle at each of those points, let's create another loop which will draw six smaller squares evenly distributed around a small circle around each of these new pivot points. See the following.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		translate(50, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			rect(15, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <p>
            +        Now that we have achieved an interesting geometry, we can embellish this program by making a variable for the first translation amount and for the x-position of the rectangle, and modulating them in interesting ways. In the following example, we'll modulate those two values using Perlin noise. If you haven't used Perlin noise before, take a look at the tutorial on Perlin noise.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(TWO_PI * i / 8);
            +		var tx = 100 * noise(0.01*frameCount);
            +		translate(tx, 0);
            +		rect(0, 0, 10, 10);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(TWO_PI * j / 6);
            +			var rx = 30 * noise(0.01*frameCount + 10);
            +			rect(rx, 0, 5, 5);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +      <p>Now we're getting somewhere! Let's take the previous example and make the following additions to it to make it even more interesting.</p>
            +
            +      <p>
            +        <ul class="list_view">
            +          <li>Extra rotation variables so the whole circle rotates with perlin noise</li>
            +          <li>Red + Blue = Purple</li>
            +          <li>Additional noisy in-place rotation of the drawn shapes</li>
            +          <li>Noisy modulation of the size of the shapes being drawn</li>
            +        </ul>
            +      </p>4
            +
            +      <p>All the noisy variables will be calculated at the top of the draw loop for better organization. Looks cool, right?!</p>
            +
            +      <script type="text/p5" data-autoplay data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +	rectMode(CENTER);
            +	fill(0, 50);
            +	stroke(255, 50);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var ang1 = TWO_PI * noise(0.01*frameCount + 10);
            +	var ang2 = TWO_PI * noise(0.01*frameCount + 20);
            +	var ang3 = TWO_PI * noise(0.01*frameCount + 30);
            +	var rx = 30 * noise(0.01*frameCount + 40);
            +	var tx = 100 * noise(0.01*frameCount + 50);
            +	var size1 = 100 * noise(0.01*frameCount + 60);
            +	var size2 = 20 * noise(0.01*frameCount + 60);
            +
            +	translate(width/2, height/2);
            +	for (var i = 0; i < 8; i++) {
            +		push();
            +		rotate(ang1 + TWO_PI * i / 8);
            +		translate(tx, 0);
            +		rect(0, 0, size1, size1);
            +		for (var j = 0; j < 6; j++) {
            +			push();
            +			rotate(ang2 + TWO_PI * j / 6);
            +			translate(rx, 0);
            +			rotate(ang3);
            +			rect(rx, 0, size2, size2);
            +			pop();
            +		}
            +		translate()
            +		pop();
            +	}
            +}
            +      </script>
            +
            +      <h2>Scaling</h2>
            +
            +      <p>
            +        There is one more function which transforms the coordinate system, and that is scale(). Scale changes the size of the grid by multiplying the coordinate system. See the following example.
            +      </p>
            +
            +      <script type="text/p5" data-autoplay  data-p5-version="1.4.1">
            +      function setup() {
            +	createCanvas(150, 200);
            +}
            +
            +function draw(){
            +	background(240);
            +
            +	var scaleAmount = mouseX / 100;
            +  	scale(scaleAmount);
            +
            +	drawGrid();
            +  	fill(255, 255, 0);
            +  	rect(20, 20, 50, 50);
            +}
            +
            +function drawGrid() {
            +	fill(0);
            +	stroke(120);
            +	for (var x=-width; x < width; x+=40) {
            +		line(x, -height, x, height);
            +		text(x, x+1, 12);
            +	}
            +	for (var y=-height; y < height; y+=40) {
            +		line(-width, y, width, y);
            +		text(y, 1, y+12);
            +	}
            +}
            +      </script>
            +
            +
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/trigonometry.html b/dist/zh-Hans/learn/trigonometry.html
            new file mode 100644
            index 0000000000..501df3f28e
            --- /dev/null
            +++ b/dist/zh-Hans/learn/trigonometry.html
            @@ -0,0 +1,190 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +      <h2>Trigonometry Primer</h2>
            +      <p>(learning to love triangles)</p>
            +      <div class="attribution">
            +        This tutorial was written during the first p5.js developers conference by Tega Brain.
            +      </div>
            +      <h3 class="start-element tutorial-btn" id="pythagoras">Pythagoras Theorum</h3>
            +      <div class="info">
            +        <p>Trigonometry is a branch of geometry that is fundamental to all graphics programming.  It provides useful equations that enable you to figure out distances between points and how curves and circles can be described in Cartesian coordinates. Remember Cartesian coordinates are points described by x and y values. Trigonmetry also enables you to do things like move shapes in circular motion or oscillate values smoothly back and forth between two extremes.</p>
            +
            +
            +        <p>The right angled triangle is one of the most important parts of trigonometry and Pythagoras was a guy who got pretty famous for figuring out a theorem that relates the length of each of its sides. Pythagora figured out that in every right hand triangle, if you square each of the two shortest sides, their sum equals the square of the longest side.</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/pythagoras1.jpg" />
            +
            +        <p>Right angled triangles are special also because each of their angles has a specific relationship to the ratio between the length of two of their sides. This is what sine, cosine and tangent functions describe. Sin cos and tan are known as trigonometric functions and they give us the relationship between the ratio of two of the triangle’s sides and one of the angles of the triangle. You may recall the acronym: SOH-CAH-TOA that helps you remember how sinθ, cosθ and tanθ relate to the ratio of which of the triangle’s sides.</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/hypotenuse.jpg" />
            +        
            +        <p>This is all pretty great, because is means that with just a couple of pieces of information about a right angled triangle, like knowing two of its side lengths or maybe knowing one of its angle and a side length, you can use Pythagora’s theorem in combination with the sin, cos and tan equations to figure out everything else.</p>
            +
            +        <p>These triangles are also helpful as they help us to map and understand the x and y coordinates of points along curves and circles. Notice how in the drawing below you can see how any point on a circle will have a relationship to a right angled triangle. This relationship means that a point on a circle can be understood in two ways. Firstly, as we have seen a point can be described by Cartesian coordinates which are of course, by x and y co-ordinates, but it can also be described using polar coordinates. Polar coodinates are an angle and a distance from the origin (the radius of the circle).</p>
            +        <img class="image" src="../../assets/learn/trigonometry/images/polar.jpg" />
            +      </div>
            +        
            +      <h3 class = "start-element tutorial-btn" id="Polar Coordinates">Polar Coordinates</h3>
            +      <div class="info">
            +        <p>Polar coordinates describe a point using an angle and a distance from the origin. This is useful when you are coding something like an analog clock. When drawing a clock, you would need to place each hand at a particular angle, for example, 3pm is at zero degrees and midday is at 90 degrees. Each hand would be coded as a line drawn onto a screen, that connects two points. So these hand would connect the origin to the x,y coordinates that is at the position of the time. Putting anything on a screen always requires you to describe it in terms of x and y.</p>
            +        
            +        <p>So how do we convert between polar coordinates and x-y coordinates?</p>
            +        
            +        <p>The relationship between polar coordinates and x,y coordinates can be calculated using a unit circle. This is a circle that has a radius of 1 unit which is useful because it means the hypotenuse in your right angled triange is always 1.</p>
            +
            +        <iframe src="../../assets/learn/trigonometry/unitCircle/embed.html" width="600" height="400"></iframe>
            +
            +
            +      </div>
            +      
            +      <h3 class="start-element tutorial-btn" id="sin">Using Sin and Cosine</h3>
            +      <div class="info">
            +        <iframe src="../../assets/learn/trigonometry/sincoscurves/embed.html" width="800" height="750"></iframe>
            +      </div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/learn/tutorial-guide.html b/dist/zh-Hans/learn/tutorial-guide.html
            new file mode 100644
            index 0000000000..524bb7bbd5
            --- /dev/null
            +++ b/dist/zh-Hans/learn/tutorial-guide.html
            @@ -0,0 +1,263 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">learn | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="learn-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main >
            +
            +      <h1>p5.js 回馈指南</h1>
            +      <div class="attribution">
            +        教程作者为 Tega Brain。
            +      </div>
            +      <p>
            +        我们欢迎教育家、合作者和一般爱好者开发更多 p5.js 教程。p5.js 旨在让创意编程及开源软件开发更易接近及吸引更多元化的社群,同时我们也很高兴能够公开的发布 p5.js 开发的完整过程及教程。我们现有的教程含括了各种课题如:学习使用 p5.js、编程技巧及如何帮助开发开源项目。
            +      </p>
            +      <p>
            +        我们欢迎任何人提交全新教程,这份指南将包括新教程的提议、准备和提交的所需步骤。
            +      </p>
            +
            +      <h2>如何开始:</h2>
            +      <ul class="list_view">
            +        <li>
            +          先确定您所建议的课题尚未被涵盖,在此链接有<a href="https://docs.google.com/spreadsheets/d/1sh3IwcCUY4Bm8N4fRZw6CwSDdQmmXgY_awjVj-UC8mo/edit#gid=0">一个列表</a>
            +          列出了正在进行中的教程。如果您想开发的课题被列为正在进行中 (in progress),您或许能帮助完成该项目或为现有的项目做预备发布的工作,您只需联络我们。
            +        </li>
            +        <li>
            +          如果您的课题尚未被涵盖及尚未被列为正在进行中,请寄份电子邮件去 education@p5js.org 并简略的讲述您所建议的教程。
            +        </li>
            +      </ul>
            +      <h2>如何准备网上 p5.js 教程:</h2>
            +      <p>
            +        当您以准备发布您的教程,请按着以下步骤准备您的教程给 p5.js 的网页。
            +      </p>
            +      <p>
            +        将您的教程写在一个命名为 tutorial-name.hbs 的文件并跟从<a href="https://github.com/mayaman/p5js-website/blob/master/src/templates/pages/learn/test-tutorial.hbs">这基本结构</a>
            +        。如该文件所示,它必须有以下开端:
            +      </p>
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-1.png" alt="Screenshot">
            +
            +      <p>
            +        您的教程文件夹将被置放在 p5.js 网站一个命名为“tutorials”的文件夹内。index.hbs 是<a href="/zh-Hans/learn/">p5.js 教程的主页</a>
            +        而 test-tutorial.hbs 为空白范例教程。
            +      </p>
            +      <p>
            +        所有内容必须被包含在以下标签内:
            +       
            +        &lt;section &gt; &lt;/section&gt;
            +        内容格式可以使用 &lt;h1&gt;、&lt;h2&gt; 及 &lt;p&gt; 段落标签定义,如<a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs">空白范例教程所示。</a></p>
            +      <p>
            +        如果您的教程包含图像,它们必须被置放在 p5 网站的 asset 文件夹,该文件夹位于 src/assets/learn/test-tutorial/images 如以下所示。
            +      </p>
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-2.png" alt="Screenshot">
            +      <p>
            +        以在 HTML 页面内格式化您的源代码,请使用以下标签:
            +      </p>
            +       
            +        <pre><code class="language-javascript">
            +&lt;pre&gt;&lt;code class="language-javascript"&gt;
            +Your code here!
            +&lt;/code>&lt;/pre&gt;
            +
            +</code></pre>
            +
            +      <h2>嵌入 p5.js 绘图</h2>
            +      <p>
            +        使用 p5.js 的一个好处是您可以制作动画驱动、互动性或可编辑的教程,方便更简易的演示程式设计概念。您的范例必须是 p5.js 绘图而它能用以下两种方式嵌入在您的教程中。
            +      </p>
            +
            +      <ol>
            +        <li>
            +          如果该范例需保持可编辑性,如在 p5.js 网站的<a href="http://p5js.org/reference/#/p5/ellipse">参考文献</a>内,该 p5 绘图必须使用 p5.js 部件以嵌入在 HTML 页面内,请使用<a href="https://toolness.github.io/p5.js-widget/">这指南</a>以了解如何使用该部件嵌入 p5.js 绘图,部件<a href="https://github.com/toolness">Toolness</a>。您也可以在<a href="https://github.com/processing/p5.js-website/blob/main/src/templates/pages/learn/test-tutorial.hbs">空白范例教程内</a>查看使用范例。</li>
            +        <li>
            +          如果该范例必须是动画驱动或互动性的但并不需要是可编辑的,该 p5.js 绘图需使用 iframe 以嵌入在页面内,如以下所示。
            +        </li>
            +      </ol>
            +
            +      <h2>使用 iframe 嵌入 p5 绘图</h2>
            +
            +      <p>
            +        iframe 让您能在原有的页面上开启一个通往另一个页面的窗口,同时该页面并不能直接和原有页面互动。在此例, 原有页面内会被嵌入一个含有您 p5.js 绘图的 index.html 窗口。
            +      </p>
            +      <img src="https://github.com/tegacodes/p5.js-education/raw/master/images/iframe-2.jpg" alt="tutorialFileStructure" width="600">
            +
            +      <p>
            +        在 /src/assets/learn 文件夹内,将您的 p5 绘图置放在一个命名为您的绘图名的文件夹内如以下截图所示。这文件夹是您置放所有 iframe 内将使用的图像及 p5 绘图的地方。
            +      </p>
            +
            +      <img src="../../assets/learn/tutorial-guide/images/screenshot-3.png" alt="Screenshot">
            +
            +<p>在含有您的 p5 范例的子文件夹内应该含有一个 sketch.js 文件及一个 embed.html 文件。</p>
            +<img src="../../assets/learn/tutorial-guide/images/screenshot-4.png" alt="Screenshot">
            +
            +<p>请确保 embed.html 内的 p5 程式库有正确的链接。如果您的文件结构和以上相同,p5.js 程式库的链接将会是 "../../../js/p5.min.js"。</p>
            +<p>这时你可以将 p5.js 绘图文件以 iframe 的方式嵌入在您的教程的 .hbs 文件中。iframe 嵌入代码如下:</p>
            +  <pre><code class="language-javascript">
            +&lt;iframe src="http://p5js.org/assets/learn/tes-tutorial/embed.html" width="600" height="400"&gt;
            +&lt;/iframe&gt;
            +</code></pre>
            +
            +<p>以格式化 iframe,您可以将以下包括在文件内或使用样式表:</p>
            +  <pre><code class="language-javascript">
            +&lt;style&gt; iframe{ border: none; } &lt;/style&gt;
            +</code></pre>
            +
            +<p>在以下链接您可以直接查看绘图:</p>
            +<a href="http://staging.p5js.org/assets/learn/test-tutorial/embed.html">http://staging.p5js.org/assets/learn/test-tutorial/embed.html</a>
            +
            +<p>而在以下您可以查看绘图被嵌入在 p5 网页中:</p>
            +<a href="http://staging.p5js.org/learn/test-tutorial.html">http://staging.p5js.org/learn/test-tutorial.html</a>
            +
            +<p>还有一项您需要注意的是您必须设置 iframe 的大小,以确保其大小不会随着窗口大小而改变。</p>
            +
            +<p>另外,p5.js 程式库的文件链接并不是在 .eps 文件内(如其他教程),而是在您的 HTML 页面内(通常是 embed.html)。</p>
            +
            +<p>更多关于嵌入 p5.js 绘图的信息可在<a href="https://github.com/processing/p5.js/wiki/Embedding-p5.js">以下链接查找。</a></p>
            +<h2>结束</h2>
            +<p>一旦您完成编辑您的教程并且您的教程已经被许可,分叉 p5.js 网站的代码库,如以上所示的步骤准备您的教程然后开启一个 pull request 给 p5.js 网站的代码库以便我们能发布您的教程!</p>
            +
            +    <p>谢谢!</p>
            +
            +  </main>
            +
            +  
            +  <footer>
            +    <h2 class="sr-only">归功于</h2>
            +    <p>
            +      p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +    </p>
            +  </footer>
            +
            +</div> <!-- end column-span -->
            +
            +
            +<!-- outside of column for footer to go across both -->
            +
            +<p class="clearfix"> &nbsp; </p>
            +
            +<object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +</object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/libraries/index.html b/dist/zh-Hans/libraries/index.html
            new file mode 100644
            index 0000000000..3e8d3548b6
            --- /dev/null
            +++ b/dist/zh-Hans/libraries/index.html
            @@ -0,0 +1,933 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">libraries | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="libraries-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content">
            +      <h1>程式库</h1>
            +
            +      <h2>如何使用程式库</h2>
            +
            +      <p>p5.js 程式库可以是任何扩展或延伸 p5.js 核心功能的 JavaScript 代码,它们主要分为两种。核心程式库(<a
            +          href="/zh-Hans/reference/#/libraries/p5.sound">p5.sound</a>)是 p5.js 正式发布组的一部分,而社群贡献程式库是由 p5.js 社群成员持有、开发及维持的。</p>
            +
            +      <p>如果您想在您的绘图内加入任何附加程式库,您只需在 HTML 文件内添加程式库的链接,此链接必须发生在 p5.js 的链接之后。一个 HTML 范例如下:</p>
            +      <pre><code class="language-markup">&lt;!doctype html&gt;
            +&lt;html>
            +&lt;head>
            +  &lt;script src="p5.js"&gt;&lt;/script&gt;
            +  &lt;script src="p5.sound.js"&gt;&lt;/script&gt;
            +  &lt;script src="sketch.js"&gt;&lt;/script&gt;
            +&lt;/head&gt;
            +&lt;body&gt;
            +&lt;/body&gt;
            +&lt;/html&gt;
            +      </code></pre>
            +
            +      <h2>制作附加程式库</h2>
            +
            +      <p>p5.js 欢迎任何人所制作的附加程式库!请参考
            +        <a href="https://github.com/processing/p5.js/blob/main/contributor_docs/creating_libraries.md">
            +          程式库编辑教程(英文页面)</a>
            +        以了解更多关于如何制作附加程式库的步骤。
            +        <a href="https://docs.google.com/forms/d/e/1FAIpQLSdWWb95cfvosaIFI7msA7XC5zOEVsNruaA5klN1jH95ESJVcw/viewform"
            +          target="_blank">如果您编辑了一个附加程式库并且希望将其显示在此页面,请填入这份表格!</a></p>
            +
            +      
            +      
            +      <h2 class="tutorial-title">核心程式库</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="/zh-Hans/reference/#/libraries/p5.sound" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.sound.jpg">
            +              <h3>p5.sound</h3>
            +            </a>
            +          </div>
            +          <p>p5.sound 使用 Web Audio 扩展 p5 的功能,提供音频输入、播放、分析及合成功能。 作者:
            +            <a href="https://www.jasonsigal.cc/"
            +              target="_blank">Jason Sigal</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/processing/p5.accessibility" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.accessibility.jpg">
            +              <h3>p5.accessibility</h3>
            +            </a>
            +          </div>
            +          <p>p5.accessibility 让视力障碍者能够更容易接触 p5 画布。 
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +      
            +      <h2 class="tutorial-title">社群贡献程式库</h2>
            +      
            +      
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/asciiart" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/asciiart.jpg">
            +              <h3>asciiart</h3>
            +            </a>
            +          </div>
            +          <p>p5.asciiart 是个简单易使用的图像 - ASCII 画作转换器。 作者:
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://itpnyu.github.io/p5ble-website/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.ble.jpg">
            +              <h3>p5.ble</h3>
            +            </a>
            +          </div>
            +          <p>一个启用 BLE 装置及 p5 绘图之间的沟通的 Javascript 编程库。 作者:
            +            <a href="https://1023.io"
            +              target="_blank">Yining Shi</a>, <a href="https://www.jingwen-zhu.com/"
            +              target="_blank">Jingwen Zhu</a>, <a href="https://tigoe.com/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/sarahgp/p5bots" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.bots.jpg">
            +              <h3>p5.bots</h3>
            +            </a>
            +          </div>
            +          <p>p5.bots 让您通过网页浏览器和 Arduino(或其他微处理器)互动。您可以使用传感器资料来驱动绘图会使用绘图来驱动 LED、马达等等! 作者:
            +            <a href="http://www.sarahgp.com"
            +              target="_blank">Sarah Groff-Palermo</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Lartu/p5.clickable" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.clickable.jpg">
            +              <h3>p5.clickable</h3>
            +            </a>
            +          </div>
            +          <p>事件驱动、易使用的 p5.js 按钮编程库。 作者:
            +            <a href="https://www.lartu.net"
            +              target="_blank">Martín del Río</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/p5.cmyk.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.cmyk.js.jpg">
            +              <h3>p5.cmyk.js</h3>
            +            </a>
            +          </div>
            +          <p>CMYK 色彩空间。 作者:
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.collide2D" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.collide2D.jpg">
            +              <h3>p5.collide2D</h3>
            +            </a>
            +          </div>
            +          <p>p5.collide2D 提供一系列工具适用于计算在 p5.js 内的 2D 几何形状的碰撞检测。 作者:
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.npmjs.com/package/p5.createloop" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.createloop.jpg">
            +              <h3>p5.createloop</h3>
            +            </a>
            +          </div>
            +          <p>使用一行编码制作运用噪声及 GIF 输出的动画循环。 作者:
            +            <a href="https://www.piratesjustar.com/"
            +              target="_blank">Peter Hayman</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Smilebags/p5.dimensions.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.dimensions.jpg">
            +              <h3>p5.dimensions</h3>
            +            </a>
            +          </div>
            +          <p>p5.dimensions 扩展 p5.js 的向量功能以包括更高维数的计算。 作者:
            +            <a href="https://github.com/Smilebags"
            +              target="_blank">Smilebags</a>, <a href="https://github.com/max0410"
            +              target="_blank">Max Segal</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/freshfork/p5.EasyCam" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.EasyCam.jpg">
            +              <h3>p5.EasyCam</h3>
            +            </a>
            +          </div>
            +          <p>简单的3D摄像机控制,具有惯性平移,缩放和旋转功能。 主要贡献者 Thomas Diewald。 作者:
            +            <a href="https://jwilliamdunn.com"
            +              target="_blank">jWilliam Dunn</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/loneboarder/p5.experience.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.experience.jpg">
            +              <h3>p5.experience</h3>
            +            </a>
            +          </div>
            +          <p>提供 p5.js 附加事件聆听功能并用以制作基于画布的网页应用程序的程式库。 作者:
            +            <a href="https://github.com/loneboarder"
            +              target="_blank">Felix Meichelböck</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-func" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.func.jpg">
            +              <h3>p5.func</h3>
            +            </a>
            +          </div>
            +          <p>p5.func 是个提供新物件及时间、频率和空间函数操作的 p5 扩展程式库。 作者:
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.geolocation" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.geolocation.jpg">
            +              <h3>p5.geolocation</h3>
            +            </a>
            +          </div>
            +          <p>p5.geolocation 提供给 p5.js 获取、观察、计算使用者地理位置及地理围栏的功能。 作者:
            +            <a href="https://www.benmoren.com/"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://charlie-roberts.com/gibber/p5-gibber/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.gibber.jpg">
            +              <h3>p5.gibber</h3>
            +            </a>
            +          </div>
            +          <p>p5.gibber 提供快速音乐排序及音频合成功能。 作者:
            +            <a href="https://charlie-roberts.com"
            +              target="_blank">Charlie Roberts</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jagracar/grafica.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/grafica.js.jpg">
            +              <h3>grafica.js</h3>
            +            </a>
            +          </div>
            +          <p>grafica.js 让您在您的 p5.js 绘图中添加简单但高度可配置的 2D 图表。 作者:
            +            <a href="https://jagracar.com/p5jsSketches.php"
            +              target="_blank">Javier Graciá Carpio</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bitcraftlab/p5.gui" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.gui.jpg">
            +              <h3>p5.gui</h3>
            +            </a>
            +          </div>
            +          <p>p5.gui 提供您的 p5.js 绘图一系列图形用户界面。 作者:
            +            <a href="https://www.bitcraftlab.com/"
            +              target="_blank">Martin Schneider</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bmoren/p5.localmessage" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.localmessage.jpg">
            +              <h3>p5.localmessage</h3>
            +            </a>
            +          </div>
            +          <p>p5.localmessage 提供一个简易的界面以在不同绘图之间传递信息并使同时使用多个视窗制作绘图更容易! 作者:
            +            <a href="https://benmoren.com"
            +              target="_blank">Ben Moren</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/jtnimoy/marching" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/marching.jpg">
            +              <h3>marching</h3>
            +            </a>
            +          </div>
            +          <p>光栅到向量转换,等值面。 作者:
            +            <a href="https://jtnimoy.cc/"
            +              target="_blank">JT Nimoy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/cvalenzuela/Mappa" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/mappa.jpg">
            +              <h3>mappa</h3>
            +            </a>
            +          </div>
            +          <p>Mappa 提供一系列给静态地图、重叠地图及地理数据的工具。特别适用于制作使用地理位置的应用程式。 作者:
            +            <a href="https://github.com/cvalenzuela/"
            +              target="_blank">Cristóbal Valenzuela</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://ml5js.org/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/ml5.js.jpg">
            +              <h3>ml5.js</h3>
            +            </a>
            +          </div>
            +          <p>建在Tensorflow.js的基础之上,ml5.js提供更简单的网页中使用机器学习算法和模型的方法。 作者:
            +            <a href="https://ml5js.org/"
            +              target="_blank">NYU ITP/IMA and contributors</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="http://p5play.molleindustria.org" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.play.jpg">
            +              <h3>p5.play</h3>
            +            </a>
            +          </div>
            +          <p>p5.play 提供图像、动画、输入及碰撞检测功能以方便制作游戏或游戏类程式。 作者:
            +            <a href="https://www.molleindustria.org/"
            +              target="_blank">Paolo Pedercini</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bobcgausa/cook-js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.particle.jpg">
            +              <h3>p5.particle</h3>
            +            </a>
            +          </div>
            +          <p>Particle 及 Fountain 物件可以用以制作数据驱动效果,该数据可来自使用者互动或 JSON 文件。 作者:
            +            <a href="http://professorcook.org/"
            +              target="_blank">Robert Cook</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://antiboredom.github.io/p5.riso" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.Riso.jpg">
            +              <h3>p5.Riso</h3>
            +            </a>
            +          </div>
            +          <p>p5.Riso 是个用来生成适合 Risograph 印刷的文件的程式库。它能帮助您将您的绘图转换成多色印刷。 作者:
            +            <a href="https://lav.io/"
            +              target="_blank">Sam Lavigne</a>, <a href="https://tegabrain.com/"
            +              target="_blank">Tega Brain</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://rednoise.org/rita" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/rita.js.jpg">
            +              <h3>rita.js</h3>
            +            </a>
            +          </div>
            +          <p>RiTa.js 提供语言分析功能并也提供生成文字的功能。 作者:
            +            <a href="https://rednoise.org/daniel"
            +              target="_blank">Daniel C. Howe</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://codeforartists.com/RotatingKnobMaker" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/Rotating_knobs.jpg">
            +              <h3>Rotating knobs</h3>
            +            </a>
            +          </div>
            +          <p>使用自定图形及自定返回值范围,制作您能旋转的旋钮。 作者:
            +            <a href="https://codeforartists.com"
            +              target="_blank">Miles DeCoster</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/mveteanu/p5.SceneManager" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.scenemanager.jpg">
            +              <h3>p5.scenemanager</h3>
            +            </a>
            +          </div>
            +          <p>p5.SceneManager 帮助您制作有多个状态/场景的绘图。各个场景就比如一个在主要绘图内的绘图。 作者:
            +            <a href="https://github.com/mveteanu/"
            +              target="_blank">Marian Veteanu</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/bohnacker/p5js-screenPosition" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.screenPosition.jpg">
            +              <h3>p5.screenPosition</h3>
            +            </a>
            +          </div>
            +          <p>在 p5.js 内添加来自 Processing 的 screenX 及 screenY 功能。 作者:
            +            <a href="https://hartmut-bohnacker.de/"
            +              target="_blank">Hartmut Bohnacker</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/generative-light/p5.scribble.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.scribble.jpg">
            +              <h3>p5.scribble</h3>
            +            </a>
            +          </div>
            +          <p>绘制看起来粗略的 2D 形状。作者为 Janneck Wullschleger,来源自 Processing 原有程式库的代码移植。 作者:
            +            <a href="https://github.com/gicentre/handy"
            +              target="_blank">handy</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/vanevery/p5.serialport" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.serial.jpg">
            +              <h3>p5.serial</h3>
            +            </a>
            +          </div>
            +          <p>p5.serial 让不同设备使用串联通讯 (RS-232) 与在网页浏览器内的 p5 绘图沟通。 作者:
            +            <a href="https://www.walking-productions.com/notslop/abou/"
            +              target="_blank">Shawn Van Every</a>, <a href="https://kaganjd.github.io/portfolio/"
            +              target="_blank">Jen Kagan</a>, <a href="https://tigoe.net/"
            +              target="_blank">Tom Igoe</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/pfe1223/Shape5js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/Shape5.jpg">
            +              <h3>Shape5</h3>
            +            </a>
            +          </div>
            +          <p>Shape5 是个基本的 2D 程式库,用于教导第一次学习使用代码的小学生。 作者:
            +            <a href="https://github.com/pfe1223"
            +              target="_blank">Patrick Ester</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/gaba5/p5.shape.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.shape.js.jpg">
            +              <h3>p5.shape.js</h3>
            +            </a>
            +          </div>
            +          <p>一个为 p5.js 添加更多简单图形的程式库。 作者:
            +            <a href="https://github.com/gaba5"
            +              target="_blank">Sebastien Lorentz</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://idmnyu.github.io/p5.js-speech/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.speech.jpg">
            +              <h3>p5.speech</h3>
            +            </a>
            +          </div>
            +          <p>p5.speech 提供简单易用的 Web Speech 及语音识别的 API,使制作能说能听的绘图更加容易。 作者:
            +            <a href="https://lukedubois.com/"
            +              target="_blank">R. Luke DuBois</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/eltapir/p5.start2d.js" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.start2d.js.jpg">
            +              <h3>p5.start2d.js</h3>
            +            </a>
            +          </div>
            +          <p>使用像素、毫米、厘米或英寸为单位来制作 2D 静态艺术的 p5 附加程式库。 作者:
            +            <a href="https://github.com/eltapir"
            +              target="_blank">Kris HEYSE</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/linux-man/p5.tiledmap" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.tiledmap.jpg">
            +              <h3>p5.tiledmap</h3>
            +            </a>
            +          </div>
            +          <p>p5.tiledmap 提供绘图及便利功能以在您的绘图中加入地图。 作者:
            +            <a href="https://softlab.pt/"
            +              target="_blank">Caldas Lopes</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/L05/p5.touchgui" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.touchgui.jpg">
            +              <h3>p5.touchgui</h3>
            +            </a>
            +          </div>
            +          <p>p5.js 多点触控及鼠标图形用户界面程式库。 作者:
            +            <a href="https://L05.is"
            +              target="_blank">Carlos L05 Garcia</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://www.tramontana.xyz" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/tramontana.jpg">
            +              <h3>tramontana</h3>
            +            </a>
            +          </div>
            +          <p>Tramontana 是个可以用在多种设备上(iOS、Android、tramontana Board等)制作互动环境、互动空间或单纯测试大规模实验的简易平台。 作者:
            +            <a href="https://www.pierdr.com"
            +              target="_blank">Pierluigi Dalla Rosa</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://tetoki.eu/vida" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/vida.jpg">
            +              <h3>vida</h3>
            +            </a>
            +          </div>
            +          <p>Vida 是个添加摄像头(或视屏)运动测试及团块跟踪功能的简单程式库。 作者:
            +            <a href="https://paweljanicki.jp"
            +              target="_blank">Pawel Janicki</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/Dozed12/p5.voronoi" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.voronoi.jpg">
            +              <h3>p5.voronoi</h3>
            +            </a>
            +          </div>
            +          <p>p5.voronoi 提供您的 p5.js 绘图一系列用以绘制及使用 voronoi 图的工具。 作者:
            +            <a href="https://github.com/Dozed12"
            +              target="_blank">Francisco Moreira</a>
            +          </p>
            +        </div>
            +        
            +        
            +        
            +      
            +        <div class="right-column">
            +          
            +          <div class="label">
            +            <a class="nounderline" href="https://p5xr.org/#/" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.xr.jpg">
            +              <h3>p5.xr</h3>
            +            </a>
            +          </div>
            +          <p>一个使用p5创建VR和AR草图的库。 作者:
            +            <a href="https://www.stalgiagrigg.name/"
            +              target="_blank">Stalgia Grigg</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +      
            +      <div class="left-column">
            +        
            +          <div class="label">
            +            <a class="nounderline" href="https://github.com/FreddieRa/p5.3D" target="_blank">
            +              <img alt="" src="../../assets/img/libraries/p5.3D.jpg">
            +              <h3>p5.3D</h3>
            +            </a>
            +          </div>
            +          <p>WebGL 3D 文字及图像。 作者:
            +            <a href="https://freddierawlins.wixsite.com/site"
            +              target="_blank">Freddie Rawlins</a>
            +          </p>
            +        </div>
            +        
            +        <div class="spacer"></div>
            +        
            +        
            +        
            +        
            +
            +
            +    </main>
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="get-started-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/reference/assets/Bold.ttf b/dist/zh-Hans/reference/assets/Bold.ttf
            new file mode 100644
            index 0000000000..50d81bdad5
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Bold.ttf differ
            diff --git a/dist/zh-Hans/reference/assets/Damscray.mp3 b/dist/zh-Hans/reference/assets/Damscray.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Damscray.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/Damscray.ogg b/dist/zh-Hans/reference/assets/Damscray.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Damscray.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/Damscray_-_Dancing_Tiger_01.ogg b/dist/zh-Hans/reference/assets/Damscray_-_Dancing_Tiger_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Damscray_-_Dancing_Tiger_01.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 b/dist/zh-Hans/reference/assets/Damscray_-_Dancing_Tiger_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Damscray_-_Dancing_Tiger_02.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/Damscray_01.mp3 b/dist/zh-Hans/reference/assets/Damscray_01.mp3
            new file mode 100644
            index 0000000000..9653a67bb6
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Damscray_01.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/Damscray_01.ogg b/dist/zh-Hans/reference/assets/Damscray_01.ogg
            new file mode 100644
            index 0000000000..ddb329fc15
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Damscray_01.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/Damscray_02.mp3 b/dist/zh-Hans/reference/assets/Damscray_02.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Damscray_02.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/Damscray_02.ogg b/dist/zh-Hans/reference/assets/Damscray_02.ogg
            new file mode 100644
            index 0000000000..77d530a2df
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Damscray_02.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/Damscray_DancingTiger.mp3 b/dist/zh-Hans/reference/assets/Damscray_DancingTiger.mp3
            new file mode 100644
            index 0000000000..b113049905
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Damscray_DancingTiger.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/Italic.ttf b/dist/zh-Hans/reference/assets/Italic.ttf
            new file mode 100644
            index 0000000000..e5a1a86e63
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Italic.ttf differ
            diff --git a/dist/zh-Hans/reference/assets/Regular.otf b/dist/zh-Hans/reference/assets/Regular.otf
            new file mode 100644
            index 0000000000..38941ae72f
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/Regular.otf differ
            diff --git a/dist/zh-Hans/reference/assets/arnott-wallace-eye-loop-forever.gif b/dist/zh-Hans/reference/assets/arnott-wallace-eye-loop-forever.gif
            new file mode 100644
            index 0000000000..992757bbaf
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/arnott-wallace-eye-loop-forever.gif differ
            diff --git a/dist/zh-Hans/reference/assets/arnott-wallace-wink-loop-once.gif b/dist/zh-Hans/reference/assets/arnott-wallace-wink-loop-once.gif
            new file mode 100644
            index 0000000000..94f2015ff3
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/arnott-wallace-wink-loop-once.gif differ
            diff --git a/dist/zh-Hans/reference/assets/beat.mp3 b/dist/zh-Hans/reference/assets/beat.mp3
            new file mode 100644
            index 0000000000..3e5802604c
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/beat.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/beat.ogg b/dist/zh-Hans/reference/assets/beat.ogg
            new file mode 100644
            index 0000000000..c13f86a41f
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/beat.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/beatbox.mp3 b/dist/zh-Hans/reference/assets/beatbox.mp3
            new file mode 100644
            index 0000000000..23fb92eb71
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/beatbox.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/beatbox.ogg b/dist/zh-Hans/reference/assets/beatbox.ogg
            new file mode 100644
            index 0000000000..b2593a6340
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/beatbox.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/blobs.csv b/dist/zh-Hans/reference/assets/blobs.csv
            new file mode 100644
            index 0000000000..2b7f05d1a0
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/blobs.csv
            @@ -0,0 +1,3 @@
            +ID,Name,Flavor,Shape,Color
            +Blob1,Blobby,Sweet,Blob,Pink
            +Blob2,Saddy,Savory,Blob,Blue
            \ No newline at end of file
            diff --git a/dist/zh-Hans/reference/assets/bricks.jpg b/dist/zh-Hans/reference/assets/bricks.jpg
            new file mode 100644
            index 0000000000..231161d752
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/bricks.jpg differ
            diff --git a/dist/zh-Hans/reference/assets/bricks_third.jpg b/dist/zh-Hans/reference/assets/bricks_third.jpg
            new file mode 100644
            index 0000000000..2fdb075996
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/bricks_third.jpg differ
            diff --git a/dist/zh-Hans/reference/assets/bx-spring.mp3 b/dist/zh-Hans/reference/assets/bx-spring.mp3
            new file mode 100644
            index 0000000000..4a955ab7fa
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/bx-spring.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/bx-spring.ogg b/dist/zh-Hans/reference/assets/bx-spring.ogg
            new file mode 100644
            index 0000000000..b01abee927
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/bx-spring.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/concrete-tunnel.mp3 b/dist/zh-Hans/reference/assets/concrete-tunnel.mp3
            new file mode 100644
            index 0000000000..1bfbd4f8f8
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/concrete-tunnel.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/concrete-tunnel.ogg b/dist/zh-Hans/reference/assets/concrete-tunnel.ogg
            new file mode 100644
            index 0000000000..be5f66b72c
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/concrete-tunnel.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/doorbell.mp3 b/dist/zh-Hans/reference/assets/doorbell.mp3
            new file mode 100644
            index 0000000000..44b6367916
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/doorbell.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/doorbell.ogg b/dist/zh-Hans/reference/assets/doorbell.ogg
            new file mode 100644
            index 0000000000..e816288c97
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/doorbell.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/drawImage.png b/dist/zh-Hans/reference/assets/drawImage.png
            new file mode 100644
            index 0000000000..1a7aa5d1d8
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/drawImage.png differ
            diff --git a/dist/zh-Hans/reference/assets/drum.mp3 b/dist/zh-Hans/reference/assets/drum.mp3
            new file mode 100644
            index 0000000000..9cd8727617
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/drum.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/drum.ogg b/dist/zh-Hans/reference/assets/drum.ogg
            new file mode 100644
            index 0000000000..5061a1b319
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/drum.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/favicon.ico b/dist/zh-Hans/reference/assets/favicon.ico
            new file mode 100644
            index 0000000000..33ad9806c8
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/favicon.ico differ
            diff --git a/dist/zh-Hans/reference/assets/fingers.mov b/dist/zh-Hans/reference/assets/fingers.mov
            new file mode 100644
            index 0000000000..a9cbbbe3ea
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/fingers.mov differ
            diff --git a/dist/zh-Hans/reference/assets/gradient.png b/dist/zh-Hans/reference/assets/gradient.png
            new file mode 100644
            index 0000000000..5245af69cd
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/gradient.png differ
            diff --git a/dist/zh-Hans/reference/assets/inconsolata.otf b/dist/zh-Hans/reference/assets/inconsolata.otf
            new file mode 100644
            index 0000000000..e7e1fa0cd7
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/inconsolata.otf differ
            diff --git a/dist/zh-Hans/reference/assets/index.html b/dist/zh-Hans/reference/assets/index.html
            new file mode 100644
            index 0000000000..487fe15b2a
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/index.html
            @@ -0,0 +1,10 @@
            +<!doctype html>
            +<html>
            +    <head>
            +        <title>Redirector</title>
            +        <meta http-equiv="refresh" content="0;url=../">
            +    </head>
            +    <body>
            +        <a href="../">Click here to redirect</a>
            +    </body>
            +</html>
            diff --git a/dist/zh-Hans/reference/assets/laDefense.jpg b/dist/zh-Hans/reference/assets/laDefense.jpg
            new file mode 100644
            index 0000000000..3b8fdfe4b8
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/laDefense.jpg differ
            diff --git a/dist/zh-Hans/reference/assets/large-dark-plate.mp3 b/dist/zh-Hans/reference/assets/large-dark-plate.mp3
            new file mode 100644
            index 0000000000..b9a15cbed7
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/large-dark-plate.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/large-dark-plate.ogg b/dist/zh-Hans/reference/assets/large-dark-plate.ogg
            new file mode 100644
            index 0000000000..40115377e5
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/large-dark-plate.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/lucky_dragons.mp3 b/dist/zh-Hans/reference/assets/lucky_dragons.mp3
            new file mode 100644
            index 0000000000..c54c70c01a
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/lucky_dragons.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/lucky_dragons.ogg b/dist/zh-Hans/reference/assets/lucky_dragons.ogg
            new file mode 100644
            index 0000000000..1e5b9e7abc
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/lucky_dragons.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/mammals.csv b/dist/zh-Hans/reference/assets/mammals.csv
            new file mode 100644
            index 0000000000..549984e37e
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/mammals.csv
            @@ -0,0 +1,4 @@
            +id,species,name
            +0,Capra hircus,Goat
            +1,Panthera pardus,Leopard
            +2,Equus zebra,Zebra
            \ No newline at end of file
            diff --git a/dist/zh-Hans/reference/assets/mammals.xml b/dist/zh-Hans/reference/assets/mammals.xml
            new file mode 100644
            index 0000000000..752da754bf
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/mammals.xml
            @@ -0,0 +1,6 @@
            +<?xml version="1.0"?>
            +<mammals>
            +  <animal id="0" species="Capra hircus">Goat</animal>
            +  <animal id="1" species="Panthera pardus">Leopard</animal>
            +  <animal id="2" species="Equus zebra">Zebra</animal>
            +</mammals>
            \ No newline at end of file
            diff --git a/dist/zh-Hans/reference/assets/mask.png b/dist/zh-Hans/reference/assets/mask.png
            new file mode 100644
            index 0000000000..a6737489b9
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/mask.png differ
            diff --git a/dist/zh-Hans/reference/assets/mask2.png b/dist/zh-Hans/reference/assets/mask2.png
            new file mode 100644
            index 0000000000..2fb4aea99b
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/mask2.png differ
            diff --git a/dist/zh-Hans/reference/assets/moonwalk.jpg b/dist/zh-Hans/reference/assets/moonwalk.jpg
            new file mode 100644
            index 0000000000..c418e6f573
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/moonwalk.jpg differ
            diff --git a/dist/zh-Hans/reference/assets/nancy-liang-wind-loop-forever.gif b/dist/zh-Hans/reference/assets/nancy-liang-wind-loop-forever.gif
            new file mode 100644
            index 0000000000..a946253ede
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/nancy-liang-wind-loop-forever.gif differ
            diff --git a/dist/zh-Hans/reference/assets/octahedron.obj b/dist/zh-Hans/reference/assets/octahedron.obj
            new file mode 100644
            index 0000000000..fed774d32a
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/octahedron.obj
            @@ -0,0 +1,15 @@
            +v 0.000000E+00 0.000000E+00 40.0000
            +v 22.5000 22.5000 0.000000E+00
            +v 22.5000 -22.5000 0.000000E+00
            +v -22.5000 -22.5000 0.000000E+00
            +v -22.5000 22.5000 0.000000E+00
            +v 0.000000E+00 0.000000E+00 -40.0000
            +
            +f     1 2 3
            +f     1 3 4
            +f     1 4 5
            +f     1 5 2
            +f     6 5 4
            +f     6 4 3
            +f     6 3 2
            +f     6 2 5
            diff --git a/dist/zh-Hans/reference/assets/rockies.jpg b/dist/zh-Hans/reference/assets/rockies.jpg
            new file mode 100644
            index 0000000000..9bc0e4a372
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/rockies.jpg differ
            diff --git a/dist/zh-Hans/reference/assets/rockies128.jpg b/dist/zh-Hans/reference/assets/rockies128.jpg
            new file mode 100644
            index 0000000000..bf55d812b2
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/rockies128.jpg differ
            diff --git a/dist/zh-Hans/reference/assets/shader-gradient.frag b/dist/zh-Hans/reference/assets/shader-gradient.frag
            new file mode 100644
            index 0000000000..09a0cdc64b
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/shader-gradient.frag
            @@ -0,0 +1,22 @@
            +// Code adopted from "Creating a Gradient Color in Fragment Shader"
            +// by Bahadır on stackoverflow.com
            +// https://stackoverflow.com/questions/47376499/creating-a-gradient-color-in-fragment-shader
            +
            +
            +precision highp float; varying vec2 vPos;
            +uniform vec2 offset;
            +uniform vec3 colorCenter;
            +uniform vec3 colorBackground;
            +
            +void main() {
            +
            +  vec2 st = vPos.xy + offset.xy;
            +
            +  // color1 = vec3(1.0,0.55,0);
            +  // color2 = vec3(0.226,0.000,0.615);
            +
            +  float mixValue = distance(st,vec2(0,1));
            +  vec3 color = mix(colorCenter,colorBackground,mixValue);
            +
            +  gl_FragColor = vec4(color,mixValue);
            +}
            \ No newline at end of file
            diff --git a/dist/zh-Hans/reference/assets/shader.frag b/dist/zh-Hans/reference/assets/shader.frag
            new file mode 100644
            index 0000000000..d3d76eb77a
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/shader.frag
            @@ -0,0 +1,16 @@
            +precision highp float; varying vec2 vPos;
            +uniform vec2 p;
            +uniform float r;
            +const int I = 500;
            +void main() {
            +  vec2 c = p + vPos * r, z = c;
            +  float n = 0.0;
            +  for (int i = I; i > 0; i --) {
            +    if(z.x*z.x+z.y*z.y > 4.0) {
            +      n = float(i)/float(I);
            +      break;
            +    }
            +    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;
            +  }
            +  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);
            +}
            diff --git a/dist/zh-Hans/reference/assets/shader.vert b/dist/zh-Hans/reference/assets/shader.vert
            new file mode 100644
            index 0000000000..ea310c6770
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/shader.vert
            @@ -0,0 +1,3 @@
            +precision highp float; varying vec2 vPos;
            +attribute vec3 aPosition;
            +void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }
            diff --git a/dist/zh-Hans/reference/assets/small-plate.mp3 b/dist/zh-Hans/reference/assets/small-plate.mp3
            new file mode 100644
            index 0000000000..656e154a5f
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/small-plate.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/small-plate.ogg b/dist/zh-Hans/reference/assets/small-plate.ogg
            new file mode 100644
            index 0000000000..7b70d3349d
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/small-plate.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/small.mp4 b/dist/zh-Hans/reference/assets/small.mp4
            new file mode 100644
            index 0000000000..1fc478842f
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/small.mp4 differ
            diff --git a/dist/zh-Hans/reference/assets/small.ogv b/dist/zh-Hans/reference/assets/small.ogv
            new file mode 100644
            index 0000000000..2b35a41aa4
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/small.ogv differ
            diff --git a/dist/zh-Hans/reference/assets/small.webm b/dist/zh-Hans/reference/assets/small.webm
            new file mode 100644
            index 0000000000..da946da529
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/small.webm differ
            diff --git a/dist/zh-Hans/reference/assets/studio-b.mp3 b/dist/zh-Hans/reference/assets/studio-b.mp3
            new file mode 100644
            index 0000000000..cbc792bfc9
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/studio-b.mp3 differ
            diff --git a/dist/zh-Hans/reference/assets/studio-b.ogg b/dist/zh-Hans/reference/assets/studio-b.ogg
            new file mode 100644
            index 0000000000..cd68db07e6
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/studio-b.ogg differ
            diff --git a/dist/zh-Hans/reference/assets/teapot.obj b/dist/zh-Hans/reference/assets/teapot.obj
            new file mode 100644
            index 0000000000..cedb196a4e
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/teapot.obj
            @@ -0,0 +1,4663 @@
            +# Blender v2.61 (sub 0) OBJ File: ''
            +# www.blender.org
            +v 0.605903 0.005903 -0.000000
            +v 0.000000 0.000000 0.000000
            +v 0.584584 0.005902 -0.162696
            +v 0.524218 0.005902 -0.307888
            +v 0.430191 0.005901 -0.430191
            +v 0.307888 0.005901 -0.524218
            +v 0.162696 0.005901 -0.584584
            +v 0.000000 0.005901 -0.605903
            +v -0.162696 0.005901 -0.584584
            +v -0.307888 0.005901 -0.524218
            +v -0.430191 0.005901 -0.430191
            +v -0.524218 0.005902 -0.307888
            +v -0.584584 0.005902 -0.162696
            +v -0.605903 0.005903 -0.000000
            +v -0.584584 0.005904 0.162696
            +v -0.524218 0.005904 0.307888
            +v -0.430191 0.005905 0.430191
            +v -0.307888 0.005905 0.524218
            +v -0.162696 0.005905 0.584584
            +v 0.000000 0.005905 0.605903
            +v 0.162696 0.005905 0.584584
            +v 0.307888 0.005905 0.524218
            +v 0.430191 0.005905 0.430191
            +v 0.524218 0.005904 0.307888
            +v 0.584584 0.005904 0.162696
            +v 1.400000 2.400000 -0.000008
            +v 1.350740 2.400000 0.375917
            +v 1.332760 2.454690 0.370913
            +v 1.381370 2.454690 -0.000009
            +v 1.384260 2.487500 -0.000009
            +v 1.335550 2.487500 0.371690
            +v 1.403120 2.498440 -0.000009
            +v 1.353760 2.498440 0.376756
            +v 1.382010 2.487500 0.384619
            +v 1.432410 2.487500 -0.000009
            +v 1.414950 2.454690 0.393787
            +v 1.466550 2.454690 -0.000009
            +v 1.447220 2.400000 0.402769
            +v 1.500000 2.400000 -0.000008
            +v 1.211260 2.400000 0.711398
            +v 1.195140 2.454690 0.701929
            +v 1.197640 2.487500 0.703400
            +v 1.213960 2.498440 0.712986
            +v 1.239300 2.487500 0.727866
            +v 1.268840 2.454690 0.745216
            +v 1.297780 2.400000 0.762213
            +v 0.994000 2.400000 0.993991
            +v 0.980770 2.454690 0.980761
            +v 0.982824 2.487500 0.982815
            +v 0.996219 2.498440 0.996210
            +v 1.017010 2.487500 1.017000
            +v 1.041250 2.454690 1.041240
            +v 1.065000 2.400000 1.064990
            +v 0.711407 2.400000 1.211250
            +v 0.701938 2.454690 1.195130
            +v 0.703409 2.487500 1.197630
            +v 0.712995 2.498440 1.213950
            +v 0.727875 2.487500 1.239290
            +v 0.745225 2.454690 1.268830
            +v 0.762222 2.400000 1.297770
            +v 0.375926 2.400010 1.350730
            +v 0.370922 2.454690 1.332750
            +v 0.371699 2.487500 1.335540
            +v 0.376765 2.498450 1.353750
            +v 0.384628 2.487500 1.382000
            +v 0.393796 2.454700 1.414940
            +v 0.402778 2.400010 1.447210
            +v 0.000000 2.400010 1.399990
            +v 0.000000 2.454690 1.381360
            +v 0.000000 2.487500 1.384250
            +v 0.000000 2.498450 1.403110
            +v 0.000000 2.487510 1.432400
            +v 0.000000 2.454700 1.466540
            +v 0.000000 2.400010 1.499990
            +v -0.375926 2.400010 1.350730
            +v -0.370922 2.454690 1.332750
            +v -0.371699 2.487500 1.335540
            +v -0.376765 2.498450 1.353750
            +v -0.384628 2.487500 1.382000
            +v -0.393796 2.454700 1.414940
            +v -0.402778 2.400010 1.447210
            +v -0.711407 2.400000 1.211250
            +v -0.701938 2.454690 1.195130
            +v -0.703409 2.487500 1.197630
            +v -0.712995 2.498440 1.213950
            +v -0.727875 2.487500 1.239290
            +v -0.745225 2.454690 1.268830
            +v -0.762222 2.400000 1.297770
            +v -0.994000 2.400000 0.993991
            +v -0.980770 2.454690 0.980761
            +v -0.982824 2.487500 0.982815
            +v -0.996219 2.498440 0.996210
            +v -1.017010 2.487500 1.017000
            +v -1.041250 2.454690 1.041240
            +v -1.065000 2.400000 1.064990
            +v -1.211260 2.400000 0.711398
            +v -1.195140 2.454690 0.701929
            +v -1.197640 2.487500 0.703400
            +v -1.213960 2.498440 0.712986
            +v -1.239300 2.487500 0.727866
            +v -1.268840 2.454690 0.745216
            +v -1.297780 2.400000 0.762213
            +v -1.350740 2.400000 0.375917
            +v -1.332760 2.454690 0.370913
            +v -1.335550 2.487500 0.371690
            +v -1.353760 2.498440 0.376756
            +v -1.382010 2.487500 0.384619
            +v -1.414950 2.454690 0.393787
            +v -1.447220 2.400000 0.402769
            +v -1.400000 2.400000 -0.000008
            +v -1.381370 2.454690 -0.000009
            +v -1.384260 2.487500 -0.000009
            +v -1.403120 2.498440 -0.000009
            +v -1.432410 2.487500 -0.000009
            +v -1.466550 2.454690 -0.000009
            +v -1.500000 2.400000 -0.000008
            +v -1.350740 2.400000 -0.375935
            +v -1.332760 2.454690 -0.370931
            +v -1.335550 2.487500 -0.371708
            +v -1.353760 2.498440 -0.376774
            +v -1.382010 2.487500 -0.384637
            +v -1.414950 2.454690 -0.393805
            +v -1.447220 2.400000 -0.402787
            +v -1.211260 2.400000 -0.711416
            +v -1.195140 2.454690 -0.701947
            +v -1.197640 2.487500 -0.703418
            +v -1.213960 2.498440 -0.713004
            +v -1.239300 2.487500 -0.727884
            +v -1.268840 2.454690 -0.745234
            +v -1.297780 2.400000 -0.762231
            +v -0.994000 2.400000 -0.994009
            +v -0.980770 2.454690 -0.980779
            +v -0.982824 2.487500 -0.982833
            +v -0.996219 2.498440 -0.996228
            +v -1.017010 2.487500 -1.017020
            +v -1.041250 2.454690 -1.041260
            +v -1.065000 2.400000 -1.065010
            +v -0.711407 2.400000 -1.211270
            +v -0.701938 2.454690 -1.195150
            +v -0.703409 2.487500 -1.197650
            +v -0.712995 2.498440 -1.213970
            +v -0.727875 2.487500 -1.239310
            +v -0.745225 2.454690 -1.268850
            +v -0.762222 2.400000 -1.297790
            +v -0.375926 2.400000 -1.350750
            +v -0.370922 2.454680 -1.332770
            +v -0.371699 2.487490 -1.335560
            +v -0.376765 2.498440 -1.353770
            +v -0.384628 2.487490 -1.382020
            +v -0.393796 2.454680 -1.414960
            +v -0.402778 2.399990 -1.447230
            +v 0.000000 2.399990 -1.400010
            +v 0.000000 2.454680 -1.381380
            +v 0.000000 2.487490 -1.384270
            +v 0.000000 2.498430 -1.403130
            +v 0.000000 2.487490 -1.432420
            +v 0.000000 2.454680 -1.466560
            +v 0.000000 2.399990 -1.500010
            +v 0.375926 2.400000 -1.350750
            +v 0.370922 2.454680 -1.332770
            +v 0.371699 2.487490 -1.335560
            +v 0.376765 2.498440 -1.353770
            +v 0.384628 2.487490 -1.382020
            +v 0.393796 2.454680 -1.414960
            +v 0.402778 2.399990 -1.447230
            +v 0.711407 2.400000 -1.211270
            +v 0.701938 2.454690 -1.195150
            +v 0.703409 2.487500 -1.197650
            +v 0.712995 2.498440 -1.213970
            +v 0.727875 2.487500 -1.239310
            +v 0.745225 2.454690 -1.268850
            +v 0.762222 2.400000 -1.297790
            +v 0.994000 2.400000 -0.994009
            +v 0.980770 2.454690 -0.980779
            +v 0.982824 2.487500 -0.982833
            +v 0.996219 2.498440 -0.996228
            +v 1.017010 2.487500 -1.017020
            +v 1.041250 2.454690 -1.041260
            +v 1.065000 2.400000 -1.065010
            +v 1.211260 2.400000 -0.711416
            +v 1.195140 2.454690 -0.701947
            +v 1.197640 2.487500 -0.703418
            +v 1.213960 2.498440 -0.713004
            +v 1.239300 2.487500 -0.727884
            +v 1.268840 2.454690 -0.745234
            +v 1.297780 2.400000 -0.762231
            +v 1.350740 2.400000 -0.375935
            +v 1.332760 2.454690 -0.370931
            +v 1.335550 2.487500 -0.371708
            +v 1.353760 2.498440 -0.376774
            +v 1.382010 2.487500 -0.384637
            +v 1.414950 2.454690 -0.393805
            +v 1.447220 2.400000 -0.402787
            +v 1.566710 2.137850 0.436024
            +v 1.623840 2.137850 -0.000008
            +v 1.679490 1.877780 0.467414
            +v 1.740740 1.877780 -0.000007
            +v 1.778880 1.621880 0.495075
            +v 1.843750 1.621870 -0.000006
            +v 1.858160 1.372220 0.517142
            +v 1.925930 1.372220 -0.000005
            +v 1.910650 1.130900 0.531750
            +v 1.980320 1.130900 -0.000004
            +v 1.929630 0.900002 0.537034
            +v 2.000000 0.900000 -0.000003
            +v 1.404920 2.137850 0.825145
            +v 1.506060 1.877780 0.884547
            +v 1.595190 1.621880 0.936892
            +v 1.666280 1.372220 0.978651
            +v 1.713350 1.130900 1.006300
            +v 1.730370 0.900004 1.016300
            +v 1.152930 2.137850 1.152920
            +v 1.235930 1.877780 1.235920
            +v 1.309060 1.621870 1.309050
            +v 1.367410 1.372230 1.367400
            +v 1.406030 1.130910 1.406030
            +v 1.420000 0.900005 1.420000
            +v 0.825153 2.137860 1.404910
            +v 0.884554 1.877790 1.506050
            +v 0.936898 1.621890 1.595180
            +v 0.978656 1.372230 1.666270
            +v 1.006300 1.130910 1.713350
            +v 1.016300 0.900006 1.730370
            +v 0.436032 2.137860 1.566700
            +v 0.467421 1.877790 1.679480
            +v 0.495081 1.621880 1.778870
            +v 0.517147 1.372230 1.858150
            +v 0.531754 1.130910 1.910650
            +v 0.537037 0.900007 1.929630
            +v 0.000000 2.137860 1.623830
            +v 0.000000 1.877790 1.740730
            +v 0.000000 1.621880 1.843740
            +v 0.000000 1.372230 1.925920
            +v 0.000000 1.130910 1.980320
            +v 0.000000 0.900007 2.000000
            +v -0.436032 2.137860 1.566700
            +v -0.467421 1.877790 1.679480
            +v -0.495081 1.621890 1.778870
            +v -0.517147 1.372230 1.858150
            +v -0.531754 1.130910 1.910650
            +v -0.537037 0.900007 1.929630
            +v -0.825153 2.137860 1.404910
            +v -0.884554 1.877790 1.506050
            +v -0.936898 1.621890 1.595180
            +v -0.978656 1.372230 1.666270
            +v -1.006300 1.130910 1.713350
            +v -1.016300 0.900006 1.730370
            +v -1.152930 2.137850 1.152920
            +v -1.235930 1.877780 1.235920
            +v -1.309060 1.621870 1.309050
            +v -1.367410 1.372230 1.367400
            +v -1.406030 1.130910 1.406030
            +v -1.420000 0.900005 1.420000
            +v -1.404920 2.137850 0.825145
            +v -1.506060 1.877780 0.884547
            +v -1.595190 1.621880 0.936892
            +v -1.666280 1.372220 0.978651
            +v -1.713350 1.130900 1.006300
            +v -1.730370 0.900004 1.016300
            +v -1.566710 2.137850 0.436024
            +v -1.679490 1.877780 0.467414
            +v -1.778880 1.621870 0.495075
            +v -1.858160 1.372220 0.517142
            +v -1.910650 1.130900 0.531750
            +v -1.929630 0.900002 0.537034
            +v -1.623840 2.137850 -0.000008
            +v -1.740740 1.877780 -0.000007
            +v -1.843750 1.621870 -0.000006
            +v -1.925930 1.372220 -0.000005
            +v -1.980320 1.130900 -0.000004
            +v -2.000000 0.900000 -0.000003
            +v -1.566710 2.137850 -0.436040
            +v -1.679490 1.877780 -0.467428
            +v -1.778880 1.621880 -0.495087
            +v -1.858160 1.372220 -0.517152
            +v -1.910650 1.130900 -0.531758
            +v -1.929630 0.899998 -0.537040
            +v -1.404920 2.137850 -0.825161
            +v -1.506060 1.877780 -0.884561
            +v -1.595190 1.621880 -0.936904
            +v -1.666280 1.372220 -0.978661
            +v -1.713350 1.130900 -1.006300
            +v -1.730370 0.899996 -1.016300
            +v -1.152930 2.137850 -1.152940
            +v -1.235930 1.877780 -1.235940
            +v -1.309060 1.621870 -1.309070
            +v -1.367410 1.372220 -1.367420
            +v -1.406030 1.130890 -1.406030
            +v -1.420000 0.899995 -1.420000
            +v -0.825153 2.137840 -1.404930
            +v -0.884554 1.877770 -1.506070
            +v -0.936898 1.621870 -1.595200
            +v -0.978656 1.372210 -1.666290
            +v -1.006300 1.130890 -1.713350
            +v -1.016300 0.899994 -1.730370
            +v -0.436032 2.137840 -1.566720
            +v -0.467421 1.877770 -1.679500
            +v -0.495081 1.621860 -1.778890
            +v -0.517147 1.372210 -1.858170
            +v -0.531754 1.130890 -1.910650
            +v -0.537037 0.899993 -1.929630
            +v 0.000000 2.137840 -1.623850
            +v 0.000000 1.877770 -1.740750
            +v 0.000000 1.621860 -1.843760
            +v 0.000000 1.372210 -1.925940
            +v 0.000000 1.130890 -1.980320
            +v 0.000000 0.899993 -2.000000
            +v 0.436032 2.137840 -1.566720
            +v 0.467421 1.877770 -1.679500
            +v 0.495081 1.621870 -1.778890
            +v 0.517147 1.372210 -1.858170
            +v 0.531754 1.130890 -1.910650
            +v 0.537037 0.899993 -1.929630
            +v 0.825153 2.137840 -1.404930
            +v 0.884554 1.877770 -1.506070
            +v 0.936898 1.621870 -1.595200
            +v 0.978656 1.372210 -1.666290
            +v 1.006300 1.130890 -1.713350
            +v 1.016300 0.899994 -1.730370
            +v 1.152930 2.137850 -1.152940
            +v 1.235930 1.877780 -1.235940
            +v 1.309060 1.621870 -1.309070
            +v 1.367410 1.372220 -1.367420
            +v 1.406030 1.130890 -1.406030
            +v 1.420000 0.899995 -1.420000
            +v 1.404920 2.137850 -0.825161
            +v 1.506060 1.877780 -0.884561
            +v 1.595190 1.621880 -0.936904
            +v 1.666280 1.372220 -0.978661
            +v 1.713350 1.130900 -1.006300
            +v 1.730370 0.899996 -1.016300
            +v 1.566710 2.137850 -0.436040
            +v 1.679490 1.877780 -0.467428
            +v 1.778880 1.621870 -0.495087
            +v 1.858160 1.372220 -0.517152
            +v 1.910650 1.130900 -0.531758
            +v 1.929630 0.899998 -0.537040
            +v 1.893900 0.693405 0.527089
            +v 1.962960 0.693403 -0.000002
            +v 1.804560 0.522224 0.502227
            +v 1.870370 0.522222 -0.000002
            +v 1.688430 0.384377 0.469906
            +v 1.750000 0.384375 -0.000001
            +v 1.572290 0.277780 0.437585
            +v 1.629630 0.277778 -0.000001
            +v 1.482960 0.200349 0.412722
            +v 1.537040 0.200347 -0.000001
            +v 1.447220 0.150001 0.402777
            +v 1.500000 0.150000 -0.000001
            +v 1.698330 0.693407 0.997473
            +v 1.618220 0.522225 0.950423
            +v 1.514070 0.384378 0.889258
            +v 1.409930 0.277781 0.828092
            +v 1.329820 0.200350 0.781042
            +v 1.297780 0.150003 0.762221
            +v 1.393700 0.693408 1.393700
            +v 1.327960 0.522227 1.327960
            +v 1.242500 0.384380 1.242500
            +v 1.157040 0.277782 1.157040
            +v 1.091300 0.200351 1.091300
            +v 1.065000 0.150004 1.065000
            +v 0.997476 0.693409 1.698330
            +v 0.950425 0.522228 1.618220
            +v 0.889259 0.384381 1.514070
            +v 0.828093 0.277783 1.409930
            +v 0.781043 0.200352 1.329820
            +v 0.762222 0.150005 1.297780
            +v 0.527092 0.693410 1.893900
            +v 0.502229 0.522229 1.804560
            +v 0.469907 0.384381 1.688430
            +v 0.437586 0.277784 1.572290
            +v 0.412723 0.200352 1.482960
            +v 0.402778 0.150005 1.447220
            +v 0.000000 0.693410 1.962960
            +v 0.000000 0.522229 1.870370
            +v 0.000000 0.384381 1.750000
            +v 0.000000 0.277784 1.629630
            +v 0.000000 0.200353 1.537040
            +v 0.000000 0.150006 1.500000
            +v -0.527092 0.693410 1.893900
            +v -0.502229 0.522229 1.804560
            +v -0.469907 0.384381 1.688430
            +v -0.437586 0.277784 1.572290
            +v -0.412723 0.200352 1.482960
            +v -0.402778 0.150005 1.447220
            +v -0.997476 0.693409 1.698330
            +v -0.950425 0.522228 1.618220
            +v -0.889259 0.384381 1.514070
            +v -0.828093 0.277783 1.409930
            +v -0.781043 0.200352 1.329820
            +v -0.762222 0.150005 1.297780
            +v -1.393700 0.693408 1.393700
            +v -1.327960 0.522227 1.327960
            +v -1.242500 0.384380 1.242500
            +v -1.157040 0.277782 1.157040
            +v -1.091300 0.200351 1.091300
            +v -1.065000 0.150004 1.065000
            +v -1.698330 0.693407 0.997473
            +v -1.618220 0.522225 0.950423
            +v -1.514070 0.384378 0.889258
            +v -1.409930 0.277781 0.828092
            +v -1.329820 0.200350 0.781042
            +v -1.297780 0.150003 0.762221
            +v -1.893900 0.693405 0.527089
            +v -1.804560 0.522224 0.502227
            +v -1.688430 0.384377 0.469906
            +v -1.572290 0.277780 0.437585
            +v -1.482960 0.200349 0.412722
            +v -1.447220 0.150001 0.402777
            +v -1.962960 0.693403 -0.000002
            +v -1.870370 0.522222 -0.000002
            +v -1.750000 0.384375 -0.000001
            +v -1.629630 0.277778 -0.000001
            +v -1.537040 0.200347 -0.000001
            +v -1.500000 0.150000 -0.000001
            +v -1.893900 0.693401 -0.527095
            +v -1.804560 0.522220 -0.502231
            +v -1.688430 0.384373 -0.469908
            +v -1.572290 0.277776 -0.437587
            +v -1.482960 0.200345 -0.412724
            +v -1.447220 0.149999 -0.402779
            +v -1.698330 0.693399 -0.997479
            +v -1.618220 0.522218 -0.950427
            +v -1.514070 0.384372 -0.889260
            +v -1.409930 0.277775 -0.828094
            +v -1.329820 0.200344 -0.781044
            +v -1.297780 0.149997 -0.762223
            +v -1.393700 0.693398 -1.393700
            +v -1.327960 0.522217 -1.327960
            +v -1.242500 0.384370 -1.242500
            +v -1.157040 0.277774 -1.157040
            +v -1.091300 0.200343 -1.091300
            +v -1.065000 0.149996 -1.065000
            +v -0.997476 0.693397 -1.698330
            +v -0.950425 0.522216 -1.618220
            +v -0.889259 0.384369 -1.514070
            +v -0.828093 0.277773 -1.409930
            +v -0.781043 0.200342 -1.329820
            +v -0.762222 0.149995 -1.297780
            +v -0.527092 0.693396 -1.893900
            +v -0.502229 0.522215 -1.804560
            +v -0.469907 0.384369 -1.688430
            +v -0.437586 0.277772 -1.572290
            +v -0.412723 0.200342 -1.482960
            +v -0.402778 0.149995 -1.447220
            +v 0.000000 0.693396 -1.962960
            +v 0.000000 0.522215 -1.870370
            +v 0.000000 0.384369 -1.750000
            +v 0.000000 0.277772 -1.629630
            +v 0.000000 0.200341 -1.537040
            +v 0.000000 0.149994 -1.500000
            +v 0.527092 0.693396 -1.893900
            +v 0.502229 0.522215 -1.804560
            +v 0.469907 0.384369 -1.688430
            +v 0.437586 0.277772 -1.572290
            +v 0.412723 0.200342 -1.482960
            +v 0.402778 0.149995 -1.447220
            +v 0.997476 0.693397 -1.698330
            +v 0.950425 0.522216 -1.618220
            +v 0.889259 0.384369 -1.514070
            +v 0.828093 0.277773 -1.409930
            +v 0.781043 0.200342 -1.329820
            +v 0.762222 0.149995 -1.297780
            +v 1.393700 0.693398 -1.393700
            +v 1.327960 0.522217 -1.327960
            +v 1.242500 0.384370 -1.242500
            +v 1.157040 0.277774 -1.157040
            +v 1.091300 0.200343 -1.091300
            +v 1.065000 0.149996 -1.065000
            +v 1.698330 0.693399 -0.997479
            +v 1.618220 0.522218 -0.950427
            +v 1.514070 0.384372 -0.889260
            +v 1.409930 0.277775 -0.828094
            +v 1.329820 0.200344 -0.781044
            +v 1.297780 0.149997 -0.762223
            +v 1.893900 0.693401 -0.527095
            +v 1.804560 0.522220 -0.502231
            +v 1.688430 0.384373 -0.469908
            +v 1.572290 0.277776 -0.437587
            +v 1.482960 0.200345 -0.412724
            +v 1.447220 0.149999 -0.402779
            +v 1.022220 0.022222 -0.000000
            +v 0.986255 0.022221 -0.274486
            +v 1.284370 0.046875 -0.000000
            +v 1.239180 0.046874 -0.344878
            +v 1.427780 0.077778 -0.000000
            +v 1.377540 0.077777 -0.383385
            +v 1.487850 0.112847 -0.000000
            +v 1.435500 0.112846 -0.399515
            +v 0.884412 0.022220 -0.519440
            +v 1.111220 0.046873 -0.652653
            +v 1.235290 0.077775 -0.725523
            +v 1.287260 0.112844 -0.756047
            +v 0.725778 0.022219 -0.725778
            +v 0.911906 0.046872 -0.911906
            +v 1.013720 0.077774 -1.013720
            +v 1.056370 0.112843 -1.056370
            +v 0.519440 0.022219 -0.884412
            +v 0.652653 0.046871 -1.111220
            +v 0.725523 0.077774 -1.235290
            +v 0.756047 0.112842 -1.287260
            +v 0.274486 0.022219 -0.986255
            +v 0.344878 0.046871 -1.239180
            +v 0.383385 0.077773 -1.377540
            +v 0.399515 0.112842 -1.435500
            +v 0.000000 0.022218 -1.022220
            +v 0.000000 0.046871 -1.284370
            +v 0.000000 0.077773 -1.427780
            +v 0.000000 0.112842 -1.487850
            +v -0.274486 0.022219 -0.986255
            +v -0.344878 0.046871 -1.239180
            +v -0.383385 0.077773 -1.377540
            +v -0.399515 0.112842 -1.435500
            +v -0.519440 0.022219 -0.884412
            +v -0.652653 0.046871 -1.111220
            +v -0.725523 0.077774 -1.235290
            +v -0.756047 0.112842 -1.287260
            +v -0.725778 0.022219 -0.725778
            +v -0.911906 0.046872 -0.911906
            +v -1.013720 0.077774 -1.013720
            +v -1.056370 0.112843 -1.056370
            +v -0.884412 0.022220 -0.519440
            +v -1.111220 0.046873 -0.652653
            +v -1.235290 0.077775 -0.725523
            +v -1.287260 0.112844 -0.756047
            +v -0.986255 0.022221 -0.274486
            +v -1.239180 0.046874 -0.344878
            +v -1.377540 0.077777 -0.383385
            +v -1.435500 0.112846 -0.399515
            +v -1.022220 0.022222 -0.000000
            +v -1.284370 0.046875 -0.000000
            +v -1.427780 0.077778 -0.000000
            +v -1.487850 0.112847 -0.000000
            +v -0.986255 0.022223 0.274486
            +v -1.239180 0.046876 0.344878
            +v -1.377540 0.077779 0.383385
            +v -1.435500 0.112848 0.399515
            +v -0.884412 0.022224 0.519440
            +v -1.111220 0.046877 0.652653
            +v -1.235290 0.077781 0.725523
            +v -1.287260 0.112850 0.756047
            +v -0.725778 0.022225 0.725778
            +v -0.911906 0.046878 0.911906
            +v -1.013720 0.077782 1.013720
            +v -1.056370 0.112851 1.056370
            +v -0.519440 0.022225 0.884412
            +v -0.652653 0.046879 1.111220
            +v -0.725523 0.077782 1.235290
            +v -0.756047 0.112852 1.287260
            +v -0.274486 0.022225 0.986255
            +v -0.344878 0.046879 1.239180
            +v -0.383385 0.077783 1.377540
            +v -0.399515 0.112852 1.435500
            +v 0.000000 0.022226 1.022220
            +v 0.000000 0.046879 1.284370
            +v 0.000000 0.077783 1.427780
            +v 0.000000 0.112852 1.487850
            +v 0.274486 0.022225 0.986255
            +v 0.344878 0.046879 1.239180
            +v 0.383385 0.077783 1.377540
            +v 0.399515 0.112852 1.435500
            +v 0.519440 0.022225 0.884412
            +v 0.652653 0.046879 1.111220
            +v 0.725523 0.077782 1.235290
            +v 0.756047 0.112852 1.287260
            +v 0.725778 0.022225 0.725778
            +v 0.911906 0.046878 0.911906
            +v 1.013720 0.077782 1.013720
            +v 1.056370 0.112851 1.056370
            +v 0.884412 0.022224 0.519440
            +v 1.111220 0.046877 0.652653
            +v 1.235290 0.077781 0.725523
            +v 1.287260 0.112850 0.756047
            +v 0.986255 0.022223 0.274486
            +v 1.239180 0.046876 0.344878
            +v 1.377540 0.077779 0.383385
            +v 1.435500 0.112848 0.399515
            +v 0.192963 2.700000 0.053694
            +v 0.200000 2.700000 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.173037 2.700000 0.101620
            +v 0.148234 2.785420 0.087096
            +v 0.142000 2.700000 0.141990
            +v 0.121672 2.785420 0.121662
            +v 0.101630 2.700000 0.173027
            +v 0.087106 2.785420 0.148224
            +v 0.053704 2.700000 0.192953
            +v 0.046045 2.785420 0.165269
            +v 0.000000 2.700000 0.199990
            +v 0.000000 2.785420 0.171286
            +v -0.053704 2.700000 0.192953
            +v -0.046045 2.785420 0.165269
            +v -0.101630 2.700000 0.173027
            +v -0.087106 2.785420 0.148224
            +v -0.142000 2.700000 0.141990
            +v -0.121672 2.785420 0.121662
            +v -0.173037 2.700000 0.101620
            +v -0.148234 2.785420 0.087096
            +v -0.192963 2.700000 0.053694
            +v -0.165279 2.785420 0.046035
            +v -0.200000 2.700000 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.192963 2.700000 -0.053714
            +v -0.165279 2.785420 -0.046055
            +v -0.173037 2.700000 -0.101640
            +v -0.148234 2.785420 -0.087116
            +v -0.142000 2.700000 -0.142010
            +v -0.121672 2.785420 -0.121682
            +v -0.101630 2.700000 -0.173047
            +v -0.087106 2.785420 -0.148244
            +v -0.053704 2.700000 -0.192973
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 2.700000 -0.200010
            +v 0.000000 2.785420 -0.171306
            +v 0.053704 2.700000 -0.192973
            +v 0.046045 2.785420 -0.165289
            +v 0.101630 2.700000 -0.173047
            +v 0.087106 2.785420 -0.148244
            +v 0.142000 2.700000 -0.142010
            +v 0.121672 2.785420 -0.121682
            +v 0.173037 2.700000 -0.101640
            +v 0.148234 2.785420 -0.087116
            +v 0.192963 2.700000 -0.053714
            +v 0.165279 2.785420 -0.046055
            +v 0.338579 2.636110 0.094221
            +v 0.350926 2.636110 -0.000009
            +v 0.553875 2.588890 0.154140
            +v 0.574074 2.588890 -0.000009
            +v 0.795972 2.550000 0.221519
            +v 0.825000 2.550000 -0.000009
            +v 1.021990 2.511110 0.284422
            +v 1.059260 2.511110 -0.000009
            +v 1.189040 2.463890 0.330915
            +v 1.232410 2.463890 -0.000009
            +v 1.254260 2.400000 0.349065
            +v 1.300000 2.400000 -0.000008
            +v 0.303616 2.636110 0.178312
            +v 0.496680 2.588890 0.291705
            +v 0.713778 2.550000 0.419213
            +v 0.916455 2.511110 0.538252
            +v 1.066260 2.463890 0.626237
            +v 1.124740 2.400000 0.660584
            +v 0.249157 2.636110 0.249147
            +v 0.407593 2.588890 0.407583
            +v 0.585750 2.550000 0.585741
            +v 0.752074 2.511110 0.752065
            +v 0.875009 2.463890 0.875000
            +v 0.923000 2.400000 0.922991
            +v 0.178322 2.636110 0.303606
            +v 0.291715 2.588890 0.496670
            +v 0.419222 2.550000 0.713769
            +v 0.538261 2.511110 0.916446
            +v 0.626246 2.463890 1.066250
            +v 0.660593 2.400000 1.124730
            +v 0.094230 2.636110 0.338569
            +v 0.154150 2.588890 0.553865
            +v 0.221528 2.550000 0.795963
            +v 0.284431 2.511110 1.021980
            +v 0.330924 2.463890 1.189030
            +v 0.349074 2.400000 1.254250
            +v 0.000000 2.636110 0.350916
            +v 0.000000 2.588890 0.574064
            +v 0.000000 2.550000 0.824991
            +v 0.000000 2.511110 1.059250
            +v 0.000000 2.463890 1.232400
            +v 0.000000 2.400000 1.299990
            +v -0.094230 2.636110 0.338569
            +v -0.154150 2.588890 0.553865
            +v -0.221528 2.550000 0.795963
            +v -0.284431 2.511110 1.021980
            +v -0.330924 2.463890 1.189030
            +v -0.349074 2.400000 1.254250
            +v -0.178322 2.636110 0.303606
            +v -0.291715 2.588890 0.496670
            +v -0.419222 2.550000 0.713769
            +v -0.538261 2.511110 0.916446
            +v -0.626246 2.463890 1.066250
            +v -0.660593 2.400000 1.124730
            +v -0.249157 2.636110 0.249147
            +v -0.407593 2.588890 0.407583
            +v -0.585750 2.550000 0.585741
            +v -0.752074 2.511110 0.752065
            +v -0.875009 2.463890 0.875000
            +v -0.923000 2.400000 0.922991
            +v -0.303616 2.636110 0.178312
            +v -0.496680 2.588890 0.291705
            +v -0.713778 2.550000 0.419213
            +v -0.916455 2.511110 0.538252
            +v -1.066260 2.463890 0.626237
            +v -1.124740 2.400000 0.660584
            +v -0.338579 2.636110 0.094221
            +v -0.553875 2.588890 0.154140
            +v -0.795972 2.550000 0.221519
            +v -1.021990 2.511110 0.284422
            +v -1.189040 2.463890 0.330915
            +v -1.254260 2.400000 0.349065
            +v -0.350926 2.636110 -0.000009
            +v -0.574074 2.588890 -0.000009
            +v -0.825000 2.550000 -0.000009
            +v -1.059260 2.511110 -0.000009
            +v -1.232410 2.463890 -0.000009
            +v -1.300000 2.400000 -0.000008
            +v -0.338579 2.636110 -0.094239
            +v -0.553875 2.588890 -0.154160
            +v -0.795972 2.550000 -0.221537
            +v -1.021990 2.511110 -0.284440
            +v -1.189040 2.463890 -0.330933
            +v -1.254260 2.400000 -0.349083
            +v -0.303616 2.636110 -0.178332
            +v -0.496680 2.588890 -0.291725
            +v -0.713778 2.550000 -0.419231
            +v -0.916455 2.511110 -0.538270
            +v -1.066260 2.463890 -0.626255
            +v -1.124740 2.400000 -0.660602
            +v -0.249157 2.636110 -0.249167
            +v -0.407593 2.588890 -0.407603
            +v -0.585750 2.550000 -0.585759
            +v -0.752074 2.511110 -0.752083
            +v -0.875009 2.463890 -0.875018
            +v -0.923000 2.400000 -0.923009
            +v -0.178322 2.636110 -0.303626
            +v -0.291715 2.588890 -0.496690
            +v -0.419222 2.550000 -0.713787
            +v -0.538261 2.511110 -0.916464
            +v -0.626246 2.463890 -1.066270
            +v -0.660593 2.400000 -1.124750
            +v -0.094230 2.636110 -0.338589
            +v -0.154150 2.588890 -0.553885
            +v -0.221528 2.550000 -0.795981
            +v -0.284431 2.511110 -1.022000
            +v -0.330924 2.463890 -1.189050
            +v -0.349074 2.400000 -1.254270
            +v 0.000000 2.636110 -0.350936
            +v 0.000000 2.588890 -0.574084
            +v 0.000000 2.550000 -0.825009
            +v 0.000000 2.511110 -1.059270
            +v 0.000000 2.463890 -1.232420
            +v 0.000000 2.400000 -1.300010
            +v 0.094230 2.636110 -0.338589
            +v 0.154150 2.588890 -0.553885
            +v 0.221528 2.550000 -0.795981
            +v 0.284431 2.511110 -1.022000
            +v 0.330924 2.463890 -1.189050
            +v 0.349074 2.400000 -1.254270
            +v 0.178322 2.636110 -0.303626
            +v 0.291715 2.588890 -0.496690
            +v 0.419222 2.550000 -0.713787
            +v 0.538261 2.511110 -0.916464
            +v 0.626246 2.463890 -1.066270
            +v 0.660593 2.400000 -1.124750
            +v 0.249157 2.636110 -0.249167
            +v 0.407593 2.588890 -0.407603
            +v 0.585750 2.550000 -0.585759
            +v 0.752074 2.511110 -0.752083
            +v 0.875009 2.463890 -0.875018
            +v 0.923000 2.400000 -0.923009
            +v 0.303616 2.636110 -0.178332
            +v 0.496680 2.588890 -0.291725
            +v 0.713778 2.550000 -0.419231
            +v 0.916455 2.511110 -0.538270
            +v 1.066260 2.463890 -0.626255
            +v 1.124740 2.400000 -0.660602
            +v 0.338579 2.636110 -0.094239
            +v 0.553875 2.588890 -0.154160
            +v 0.795972 2.550000 -0.221537
            +v 1.021990 2.511110 -0.284440
            +v 1.189040 2.463890 -0.330933
            +v 1.254260 2.400000 -0.349083
            +v -1.924540 2.023960 -0.000007
            +v -1.600000 2.025000 -0.000007
            +v -1.927040 2.040550 0.124992
            +v -1.592590 2.041670 0.124992
            +v -2.196300 2.016670 -0.000007
            +v -2.206450 2.032720 0.124992
            +v -2.428240 2.011460 0.124993
            +v -2.412500 1.996870 -0.000007
            +v -2.589850 1.970060 0.124993
            +v -2.570370 1.958330 -0.000007
            +v -2.688700 1.901810 0.124993
            +v -2.667130 1.894790 -0.000007
            +v -2.722220 1.800000 0.124993
            +v -2.700000 1.800000 -0.000006
            +v -1.933300 2.082020 0.199992
            +v -1.574070 2.083330 0.199992
            +v -2.231820 2.072840 0.199992
            +v -2.467590 2.047920 0.199992
            +v -2.638550 1.999380 0.199993
            +v -2.742630 1.919370 0.199993
            +v -2.777780 1.800000 0.199993
            +v -1.941440 2.135940 0.224992
            +v -1.550000 2.137500 0.224992
            +v -2.264810 2.125000 0.224992
            +v -2.518750 2.095310 0.224992
            +v -2.701850 2.037500 0.224992
            +v -2.812730 1.942190 0.224993
            +v -2.850000 1.800000 0.224993
            +v -1.949570 2.189850 0.199992
            +v -1.525930 2.191670 0.199992
            +v -2.297810 2.177160 0.199992
            +v -2.569910 2.142710 0.199992
            +v -2.765160 2.075620 0.199992
            +v -2.882840 1.965010 0.199993
            +v -2.922220 1.800000 0.199993
            +v -1.955830 2.231330 0.124992
            +v -1.507410 2.233330 0.124992
            +v -2.323180 2.217280 0.124992
            +v -2.609260 2.179170 0.124992
            +v -2.813850 2.104940 0.124992
            +v -2.936760 1.982560 0.124993
            +v -2.977780 1.800000 0.124993
            +v -1.958330 2.247920 -0.000008
            +v -1.500000 2.250000 -0.000008
            +v -2.333330 2.233330 -0.000008
            +v -2.625000 2.193750 -0.000008
            +v -2.833330 2.116670 -0.000007
            +v -2.958330 1.989580 -0.000007
            +v -3.000000 1.800000 -0.000006
            +v -1.507410 2.233330 -0.125008
            +v -1.955830 2.231330 -0.125008
            +v -2.323180 2.217280 -0.125008
            +v -2.609260 2.179170 -0.125008
            +v -2.813850 2.104940 -0.125008
            +v -2.936760 1.982560 -0.125007
            +v -2.977780 1.800000 -0.125007
            +v -1.525930 2.191670 -0.200008
            +v -1.949570 2.189850 -0.200008
            +v -2.297810 2.177160 -0.200008
            +v -2.569910 2.142710 -0.200008
            +v -2.765160 2.075620 -0.200008
            +v -2.882840 1.965010 -0.200007
            +v -2.922220 1.800000 -0.200007
            +v -1.550000 2.137500 -0.225008
            +v -1.941440 2.135940 -0.225008
            +v -2.264810 2.125000 -0.225008
            +v -2.518750 2.095310 -0.225008
            +v -2.701850 2.037500 -0.225008
            +v -2.812730 1.942190 -0.225007
            +v -2.850000 1.800000 -0.225007
            +v -1.574070 2.083330 -0.200008
            +v -1.933300 2.082020 -0.200008
            +v -2.231820 2.072840 -0.200008
            +v -2.467590 2.047920 -0.200008
            +v -2.638550 1.999380 -0.200007
            +v -2.742630 1.919370 -0.200007
            +v -2.777780 1.800000 -0.200007
            +v -1.592590 2.041670 -0.125008
            +v -1.927040 2.040550 -0.125008
            +v -2.206450 2.032720 -0.125008
            +v -2.428240 2.011460 -0.125007
            +v -2.589850 1.970060 -0.125007
            +v -2.688700 1.901810 -0.125007
            +v -2.722220 1.800000 -0.125007
            +v -2.704180 1.663980 0.124994
            +v -2.682870 1.670830 -0.000006
            +v -2.648290 1.505350 0.124994
            +v -2.629630 1.516670 -0.000005
            +v -2.551850 1.335760 0.124995
            +v -2.537500 1.350000 -0.000005
            +v -2.412210 1.166870 0.124996
            +v -2.403700 1.183330 -0.000004
            +v -2.226680 1.010330 0.124996
            +v -2.225460 1.029170 -0.000004
            +v -1.992590 0.877778 0.124997
            +v -2.000000 0.900000 -0.000003
            +v -2.757470 1.646840 0.199994
            +v -2.694920 1.477060 0.199995
            +v -2.587730 1.300170 0.199995
            +v -2.433470 1.125720 0.199996
            +v -2.229720 0.963228 0.199996
            +v -1.974070 0.822223 0.199997
            +v -2.826740 1.624570 0.224994
            +v -2.755560 1.440280 0.224995
            +v -2.634370 1.253910 0.224995
            +v -2.461110 1.072220 0.224996
            +v -2.233680 0.901998 0.224997
            +v -1.950000 0.750001 0.224997
            +v -2.896000 1.602290 0.199994
            +v -2.816190 1.403500 0.199995
            +v -2.681020 1.207640 0.199996
            +v -2.488750 1.018720 0.199996
            +v -2.237640 0.840767 0.199997
            +v -1.925930 0.677779 0.199997
            +v -2.949290 1.585150 0.124994
            +v -2.862830 1.375210 0.124995
            +v -2.716900 1.172050 0.124996
            +v -2.510010 0.977573 0.124996
            +v -2.240680 0.793666 0.124997
            +v -1.907410 0.622222 0.124998
            +v -2.970600 1.578300 -0.000006
            +v -2.881480 1.363890 -0.000005
            +v -2.731250 1.157810 -0.000004
            +v -2.518520 0.961111 -0.000003
            +v -2.241900 0.774826 -0.000003
            +v -1.900000 0.600000 -0.000002
            +v -2.949290 1.585150 -0.125006
            +v -2.862830 1.375210 -0.125005
            +v -2.716900 1.172050 -0.125004
            +v -2.510010 0.977572 -0.125004
            +v -2.240680 0.793666 -0.125003
            +v -1.907410 0.622222 -0.125002
            +v -2.896000 1.602290 -0.200006
            +v -2.816190 1.403500 -0.200005
            +v -2.681020 1.207640 -0.200004
            +v -2.488750 1.018720 -0.200004
            +v -2.237640 0.840765 -0.200003
            +v -1.925930 0.677777 -0.200003
            +v -2.826740 1.624570 -0.225006
            +v -2.755560 1.440280 -0.225005
            +v -2.634370 1.253910 -0.225005
            +v -2.461110 1.072220 -0.225004
            +v -2.233680 0.901996 -0.225003
            +v -1.950000 0.749999 -0.225003
            +v -2.757470 1.646840 -0.200006
            +v -2.694920 1.477060 -0.200005
            +v -2.587730 1.300170 -0.200005
            +v -2.433470 1.125720 -0.200004
            +v -2.229720 0.963226 -0.200004
            +v -1.974070 0.822221 -0.200003
            +v -2.704180 1.663980 -0.125006
            +v -2.648290 1.505350 -0.125006
            +v -2.551850 1.335760 -0.125005
            +v -2.412210 1.166870 -0.125004
            +v -2.226680 1.010330 -0.125004
            +v -1.992590 0.877778 -0.125003
            +v 1.700000 1.425000 -0.000005
            +v 1.700000 1.363890 0.274995
            +v 2.072380 1.425210 0.262341
            +v 2.058800 1.476390 -0.000005
            +v 2.290120 1.572020 0.230704
            +v 2.270370 1.611110 -0.000006
            +v 2.409720 1.773610 0.189576
            +v 2.387500 1.800000 -0.000006
            +v 2.487650 1.999280 0.148450
            +v 2.462960 2.013890 -0.000007
            +v 2.580400 2.218310 0.116813
            +v 2.549540 2.223610 -0.000008
            +v 2.700000 2.400000 -0.000008
            +v 2.744440 2.400000 0.104158
            +v 1.700000 1.211110 0.439996
            +v 2.106330 1.297250 0.419748
            +v 2.339510 1.474280 0.369131
            +v 2.465280 1.707640 0.303327
            +v 2.549380 1.962760 0.237524
            +v 2.657560 2.205070 0.186906
            +v 2.855560 2.400000 0.166658
            +v 1.700000 1.012500 0.494996
            +v 2.150460 1.130900 0.472218
            +v 2.403700 1.347220 0.415273
            +v 2.537500 1.621870 0.341244
            +v 2.629630 1.915280 0.267215
            +v 2.757870 2.187850 0.210270
            +v 3.000000 2.400000 0.187491
            +v 1.700000 0.813891 0.439997
            +v 2.194600 0.964560 0.419749
            +v 2.467900 1.220160 0.369132
            +v 2.609720 1.536110 0.303327
            +v 2.709880 1.867800 0.237524
            +v 2.858180 2.170630 0.186906
            +v 3.144440 2.400000 0.166658
            +v 1.700000 0.661112 0.274998
            +v 2.228550 0.836601 0.262343
            +v 2.517280 1.122430 0.230706
            +v 2.665280 1.470140 0.189578
            +v 2.771600 1.831280 0.148450
            +v 2.935340 2.157380 0.116813
            +v 3.255560 2.400000 0.104158
            +v 1.700000 0.600000 -0.000002
            +v 2.242130 0.785417 -0.000003
            +v 2.537040 1.083330 -0.000004
            +v 2.687500 1.443750 -0.000005
            +v 2.796300 1.816670 -0.000006
            +v 2.966200 2.152080 -0.000008
            +v 3.300000 2.400000 -0.000008
            +v 1.700000 0.661110 -0.275002
            +v 2.228550 0.836599 -0.262349
            +v 2.517280 1.122430 -0.230714
            +v 2.665280 1.470140 -0.189588
            +v 2.771600 1.831280 -0.148464
            +v 2.935340 2.157380 -0.116829
            +v 3.255560 2.400000 -0.104176
            +v 1.700000 0.813887 -0.440003
            +v 2.194600 0.964556 -0.419757
            +v 2.467900 1.220160 -0.369141
            +v 2.609720 1.536110 -0.303339
            +v 2.709880 1.867800 -0.237538
            +v 2.858180 2.170630 -0.186922
            +v 3.144440 2.400000 -0.166676
            +v 1.700000 1.012500 -0.495004
            +v 2.150460 1.130900 -0.472226
            +v 2.403700 1.347220 -0.415283
            +v 2.537500 1.621870 -0.341256
            +v 2.629630 1.915280 -0.267229
            +v 2.757870 2.187850 -0.210286
            +v 3.000000 2.400000 -0.187509
            +v 1.700000 1.211110 -0.440004
            +v 2.106330 1.297250 -0.419758
            +v 2.339510 1.474280 -0.369141
            +v 2.465280 1.707640 -0.303339
            +v 2.549380 1.962760 -0.237538
            +v 2.657560 2.205070 -0.186922
            +v 2.855560 2.400000 -0.166676
            +v 1.700000 1.363890 -0.275005
            +v 2.072380 1.425210 -0.262351
            +v 2.290120 1.572020 -0.230716
            +v 2.409720 1.773610 -0.189590
            +v 2.487650 1.999280 -0.148464
            +v 2.580400 2.218310 -0.116829
            +v 2.744440 2.400000 -0.104176
            +v 2.749070 2.431250 -0.000009
            +v 2.796410 2.431930 0.101023
            +v 2.792590 2.450000 -0.000009
            +v 2.839780 2.451230 0.092969
            +v 2.825000 2.456250 -0.000009
            +v 2.869680 2.457810 0.082022
            +v 2.881210 2.451540 0.070207
            +v 2.840740 2.450000 -0.000009
            +v 2.869490 2.432310 0.059549
            +v 2.834260 2.431250 -0.000009
            +v 2.829630 2.400000 0.052074
            +v 2.800000 2.400000 -0.000008
            +v 2.914740 2.433610 0.161565
            +v 2.957750 2.454320 0.148139
            +v 2.981370 2.461720 0.129158
            +v 2.982370 2.455400 0.107398
            +v 2.957560 2.434960 0.085639
            +v 2.903700 2.400000 0.066658
            +v 3.068580 2.435810 0.181675
            +v 3.111110 2.458330 0.165963
            +v 3.126560 2.466800 0.142960
            +v 3.113890 2.460420 0.115269
            +v 3.072050 2.438410 0.085495
            +v 3.000000 2.400000 0.056241
            +v 3.222410 2.438000 0.161411
            +v 3.264470 2.462350 0.146905
            +v 3.271760 2.471870 0.124991
            +v 3.245400 2.465430 0.097522
            +v 3.186540 2.441860 0.066349
            +v 3.096300 2.400000 0.033324
            +v 3.340750 2.439690 0.100830
            +v 3.382440 2.465430 0.091426
            +v 3.383450 2.475780 0.076814
            +v 3.346570 2.469290 0.057861
            +v 3.274610 2.444510 0.035437
            +v 3.170370 2.400000 0.010408
            +v 3.388080 2.440360 -0.000009
            +v 3.429630 2.466670 -0.000009
            +v 3.428130 2.477340 -0.000009
            +v 3.387040 2.470830 -0.000009
            +v 3.309840 2.445570 -0.000009
            +v 3.200000 2.400000 -0.000008
            +v 3.340750 2.439690 -0.101089
            +v 3.382440 2.465430 -0.093373
            +v 3.383450 2.475780 -0.083342
            +v 3.346570 2.469290 -0.073312
            +v 3.274610 2.444510 -0.065595
            +v 3.170370 2.400000 -0.062509
            +v 3.222410 2.438000 -0.161737
            +v 3.264470 2.462350 -0.149392
            +v 3.271760 2.471870 -0.133342
            +v 3.245400 2.465430 -0.117293
            +v 3.186540 2.441860 -0.104947
            +v 3.096300 2.400000 -0.100009
            +v 3.068580 2.435810 -0.181953
            +v 3.111110 2.458330 -0.168065
            +v 3.126560 2.466800 -0.150009
            +v 3.113890 2.460420 -0.131953
            +v 3.072050 2.438410 -0.118065
            +v 3.000000 2.400000 -0.112509
            +v 2.914740 2.433610 -0.161737
            +v 2.957750 2.454320 -0.149392
            +v 2.981370 2.461720 -0.133342
            +v 2.982370 2.455400 -0.117293
            +v 2.957560 2.434960 -0.104947
            +v 2.903700 2.400000 -0.100009
            +v 2.796410 2.431930 -0.101089
            +v 2.839780 2.451230 -0.093373
            +v 2.869680 2.457810 -0.083342
            +v 2.881210 2.451540 -0.073312
            +v 2.869490 2.432310 -0.065595
            +v 2.829630 2.400000 -0.062509
            +v 0.278704 3.127080 -0.000011
            +v 0.000000 3.150000 -0.000011
            +v 0.268946 3.127080 0.075067
            +v 0.241285 3.127080 0.141920
            +v 0.198140 3.127080 0.198129
            +v 0.141931 3.127080 0.241274
            +v 0.075078 3.127080 0.268935
            +v 0.000000 3.127080 0.278693
            +v -0.075078 3.127080 0.268935
            +v -0.141931 3.127080 0.241274
            +v -0.198140 3.127080 0.198129
            +v -0.241285 3.127080 0.141920
            +v -0.268946 3.127080 0.075067
            +v -0.278704 3.127080 -0.000011
            +v -0.268946 3.127080 -0.075089
            +v -0.241285 3.127080 -0.141942
            +v -0.198140 3.127080 -0.198151
            +v -0.141931 3.127080 -0.241296
            +v -0.075078 3.127080 -0.268957
            +v 0.000000 3.127080 -0.278715
            +v 0.075078 3.127080 -0.268957
            +v 0.141931 3.127080 -0.241296
            +v 0.198140 3.127080 -0.198151
            +v 0.241285 3.127080 -0.141942
            +v 0.268946 3.127080 -0.075089
            +v 0.350254 3.066670 0.097760
            +v 0.362963 3.066670 -0.000011
            +v 0.313617 2.981250 0.087518
            +v 0.325000 2.981250 -0.000011
            +v 0.228728 2.883330 0.063793
            +v 0.237037 2.883330 -0.000010
            +v 0.165279 2.785420 0.046035
            +v 0.171296 2.785420 -0.000010
            +v 0.314228 3.066670 0.184824
            +v 0.281352 2.981250 0.165470
            +v 0.205180 2.883330 0.120636
            +v 0.148234 2.785420 0.087096
            +v 0.258037 3.066670 0.258027
            +v 0.231031 2.981250 0.231020
            +v 0.168463 2.883330 0.168452
            +v 0.121672 2.785420 0.121662
            +v 0.184834 3.066670 0.314218
            +v 0.165481 2.981250 0.281341
            +v 0.120647 2.883330 0.205169
            +v 0.087106 2.785420 0.148224
            +v 0.097771 3.066670 0.350244
            +v 0.087529 2.981250 0.313606
            +v 0.063803 2.883330 0.228717
            +v 0.046045 2.785420 0.165269
            +v 0.000000 3.066670 0.362953
            +v 0.000000 2.981250 0.324989
            +v 0.000000 2.883330 0.237026
            +v 0.000000 2.785420 0.171286
            +v -0.097771 3.066670 0.350244
            +v -0.087529 2.981250 0.313606
            +v -0.063803 2.883330 0.228717
            +v -0.046045 2.785420 0.165269
            +v -0.184834 3.066670 0.314218
            +v -0.165481 2.981250 0.281341
            +v -0.120647 2.883330 0.205169
            +v -0.087106 2.785420 0.148224
            +v -0.258037 3.066670 0.258027
            +v -0.231031 2.981250 0.231020
            +v -0.168463 2.883330 0.168452
            +v -0.121672 2.785420 0.121662
            +v -0.314228 3.066670 0.184824
            +v -0.281352 2.981250 0.165470
            +v -0.205180 2.883330 0.120636
            +v -0.148234 2.785420 0.087096
            +v -0.350254 3.066670 0.097760
            +v -0.313617 2.981250 0.087518
            +v -0.228728 2.883330 0.063793
            +v -0.165279 2.785420 0.046035
            +v -0.362963 3.066670 -0.000011
            +v -0.325000 2.981250 -0.000011
            +v -0.237037 2.883330 -0.000010
            +v -0.171296 2.785420 -0.000010
            +v -0.350254 3.066670 -0.097782
            +v -0.313617 2.981250 -0.087540
            +v -0.228728 2.883330 -0.063813
            +v -0.165279 2.785420 -0.046055
            +v -0.314228 3.066670 -0.184844
            +v -0.281352 2.981250 -0.165492
            +v -0.205180 2.883330 -0.120658
            +v -0.148234 2.785420 -0.087116
            +v -0.258037 3.066670 -0.258047
            +v -0.231031 2.981250 -0.231042
            +v -0.168463 2.883330 -0.168474
            +v -0.121672 2.785420 -0.121682
            +v -0.184834 3.066670 -0.314238
            +v -0.165481 2.981250 -0.281363
            +v -0.120647 2.883330 -0.205191
            +v -0.087106 2.785420 -0.148244
            +v -0.097771 3.066670 -0.350264
            +v -0.087529 2.981250 -0.313628
            +v -0.063803 2.883330 -0.228739
            +v -0.046045 2.785420 -0.165289
            +v 0.000000 3.066670 -0.362973
            +v 0.000000 2.981250 -0.325011
            +v 0.000000 2.883330 -0.237048
            +v 0.000000 2.785420 -0.171306
            +v 0.097771 3.066670 -0.350264
            +v 0.087529 2.981250 -0.313628
            +v 0.063803 2.883330 -0.228739
            +v 0.046045 2.785420 -0.165289
            +v 0.184834 3.066670 -0.314238
            +v 0.165481 2.981250 -0.281363
            +v 0.120647 2.883330 -0.205191
            +v 0.087106 2.785420 -0.148244
            +v 0.258037 3.066670 -0.258047
            +v 0.231031 2.981250 -0.231042
            +v 0.168463 2.883330 -0.168474
            +v 0.121672 2.785420 -0.121682
            +v 0.314228 3.066670 -0.184844
            +v 0.281352 2.981250 -0.165492
            +v 0.205180 2.883330 -0.120658
            +v 0.148234 2.785420 -0.087116
            +v 0.350254 3.066670 -0.097782
            +v 0.313617 2.981250 -0.087540
            +v 0.228728 2.883330 -0.063813
            +v 0.165279 2.785420 -0.046055
            +vn 0.025666 -0.999664 0.000000
            +vn 0.000000 -1.000000 0.000000
            +vn 0.024781 -0.999664 -0.006623
            +vn 0.022156 -0.999664 -0.012787
            +vn 0.018067 -0.999664 -0.018067
            +vn 0.012787 -0.999664 -0.022126
            +vn 0.006623 -0.999664 -0.024751
            +vn 0.000000 -0.999664 -0.025666
            +vn -0.006623 -0.999664 -0.024751
            +vn -0.012787 -0.999664 -0.022126
            +vn -0.018067 -0.999664 -0.018067
            +vn -0.022156 -0.999664 -0.012787
            +vn -0.024781 -0.999664 -0.006623
            +vn -0.025666 -0.999664 0.000000
            +vn -0.024781 -0.999664 0.006623
            +vn -0.022156 -0.999664 0.012787
            +vn -0.018067 -0.999664 0.018067
            +vn -0.012787 -0.999664 0.022156
            +vn -0.006623 -0.999664 0.024781
            +vn 0.000000 -0.999664 0.025666
            +vn 0.006623 -0.999664 0.024781
            +vn 0.012787 -0.999664 0.022156
            +vn 0.018067 -0.999664 0.018067
            +vn 0.022156 -0.999664 0.012787
            +vn 0.024781 -0.999664 0.006623
            +vn -0.946562 -0.322459 0.000000
            +vn -0.913999 -0.322947 -0.245491
            +vn -0.958617 -0.122227 -0.257057
            +vn -0.992523 -0.122013 0.000000
            +vn -0.832057 0.554674 0.000000
            +vn -0.803217 0.555376 -0.215308
            +vn -0.048616 0.998810 0.000000
            +vn -0.046205 0.998840 -0.012726
            +vn 0.525376 0.839106 0.140843
            +vn 0.544267 0.838893 0.000000
            +vn 0.756340 0.621845 0.202918
            +vn 0.783471 0.621387 0.000000
            +vn 0.850551 0.473769 0.228217
            +vn 0.880886 0.473281 0.000000
            +vn -0.818842 -0.323435 -0.474166
            +vn -0.859004 -0.122410 -0.497085
            +vn -0.719657 0.555559 -0.416425
            +vn -0.041749 0.998810 -0.024415
            +vn 0.470107 0.839625 0.272011
            +vn 0.677236 0.622608 0.391980
            +vn 0.761803 0.474471 0.440962
            +vn -0.669027 -0.323679 -0.669027
            +vn -0.701773 -0.122440 -0.701773
            +vn -0.587878 0.555650 -0.587878
            +vn -0.034272 0.998810 -0.034272
            +vn 0.383831 0.839808 0.383831
            +vn 0.553148 0.622913 0.553148
            +vn 0.622303 0.474776 0.622303
            +vn -0.474166 -0.323435 -0.818842
            +vn -0.497085 -0.122410 -0.859004
            +vn -0.416425 0.555528 -0.719657
            +vn -0.024415 0.998810 -0.041749
            +vn 0.272011 0.839625 0.470077
            +vn 0.392010 0.622608 0.677236
            +vn 0.440962 0.474502 0.761803
            +vn -0.245460 -0.322977 -0.913999
            +vn -0.257057 -0.122257 -0.958617
            +vn -0.215339 0.555193 -0.803308
            +vn -0.012726 0.998840 -0.046236
            +vn 0.140873 0.839076 0.525437
            +vn 0.202918 0.621906 0.756310
            +vn 0.228217 0.473769 0.850551
            +vn 0.000000 -0.322489 -0.946562
            +vn 0.000000 -0.122044 -0.992523
            +vn 0.000000 0.554491 -0.832179
            +vn 0.000000 0.998779 -0.048799
            +vn 0.000000 0.838893 0.544267
            +vn 0.000000 0.621387 0.783471
            +vn 0.000000 0.473281 0.880886
            +vn 0.245460 -0.322977 -0.913999
            +vn 0.257057 -0.122257 -0.958617
            +vn 0.215339 0.555193 -0.803308
            +vn 0.012726 0.998840 -0.046236
            +vn -0.140873 0.839076 0.525437
            +vn -0.202918 0.621906 0.756310
            +vn -0.228217 0.473769 0.850551
            +vn 0.474166 -0.323435 -0.818842
            +vn 0.497085 -0.122410 -0.859004
            +vn 0.416425 0.555528 -0.719657
            +vn 0.024415 0.998810 -0.041749
            +vn -0.272011 0.839625 0.470077
            +vn -0.392010 0.622608 0.677236
            +vn -0.440962 0.474502 0.761803
            +vn 0.669027 -0.323679 -0.669027
            +vn 0.701773 -0.122440 -0.701773
            +vn 0.587878 0.555650 -0.587878
            +vn 0.034272 0.998810 -0.034272
            +vn -0.383831 0.839808 0.383831
            +vn -0.553148 0.622913 0.553148
            +vn -0.622303 0.474776 0.622303
            +vn 0.818842 -0.323435 -0.474166
            +vn 0.859004 -0.122410 -0.497085
            +vn 0.719657 0.555559 -0.416425
            +vn 0.041749 0.998810 -0.024415
            +vn -0.470107 0.839625 0.272011
            +vn -0.677236 0.622608 0.391980
            +vn -0.761803 0.474471 0.440962
            +vn 0.913999 -0.322947 -0.245491
            +vn 0.958617 -0.122227 -0.257057
            +vn 0.803217 0.555376 -0.215308
            +vn 0.046205 0.998840 -0.012726
            +vn -0.525376 0.839106 0.140843
            +vn -0.756340 0.621845 0.202918
            +vn -0.850551 0.473769 0.228217
            +vn 0.946562 -0.322459 0.000000
            +vn 0.992523 -0.122013 0.000000
            +vn 0.832057 0.554674 0.000000
            +vn 0.048616 0.998810 0.000000
            +vn -0.544267 0.838893 0.000000
            +vn -0.783471 0.621387 0.000000
            +vn -0.880886 0.473281 0.000000
            +vn 0.913999 -0.322947 0.245491
            +vn 0.958617 -0.122227 0.257057
            +vn 0.803217 0.555376 0.215308
            +vn 0.046205 0.998840 0.012726
            +vn -0.525376 0.839106 -0.140843
            +vn -0.756340 0.621845 -0.202918
            +vn -0.850551 0.473769 -0.228217
            +vn 0.818842 -0.323435 0.474166
            +vn 0.859004 -0.122410 0.497085
            +vn 0.719657 0.555559 0.416425
            +vn 0.041749 0.998810 0.024415
            +vn -0.470107 0.839625 -0.272011
            +vn -0.677236 0.622608 -0.391980
            +vn -0.761803 0.474471 -0.440962
            +vn 0.669027 -0.323679 0.669027
            +vn 0.701773 -0.122440 0.701773
            +vn 0.587878 0.555650 0.587878
            +vn 0.034272 0.998810 0.034272
            +vn -0.383831 0.839808 -0.383831
            +vn -0.553148 0.622913 -0.553148
            +vn -0.622303 0.474776 -0.622303
            +vn 0.474166 -0.323435 0.818842
            +vn 0.497085 -0.122410 0.859004
            +vn 0.416425 0.555559 0.719657
            +vn 0.024415 0.998810 0.041749
            +vn -0.272011 0.839625 -0.470107
            +vn -0.391980 0.622608 -0.677236
            +vn -0.440962 0.474471 -0.761803
            +vn 0.245460 -0.322977 0.913999
            +vn 0.257027 -0.122257 0.958617
            +vn 0.215369 0.555193 0.803308
            +vn 0.012726 0.998840 0.046236
            +vn -0.140873 0.839045 -0.525498
            +vn -0.202918 0.621845 -0.756371
            +vn -0.228187 0.473769 -0.850551
            +vn 0.000000 -0.322459 0.946562
            +vn 0.000000 -0.122013 0.992523
            +vn 0.000000 0.554674 0.832057
            +vn 0.000000 0.998810 0.048616
            +vn 0.000000 0.838893 -0.544267
            +vn 0.000000 0.621387 -0.783471
            +vn 0.000000 0.473281 -0.880886
            +vn -0.245460 -0.322977 0.913999
            +vn -0.257027 -0.122257 0.958617
            +vn -0.215369 0.555193 0.803308
            +vn -0.012726 0.998840 0.046236
            +vn 0.140873 0.839045 -0.525498
            +vn 0.202918 0.621845 -0.756371
            +vn 0.228187 0.473769 -0.850551
            +vn -0.474166 -0.323435 0.818842
            +vn -0.497085 -0.122410 0.859004
            +vn -0.416425 0.555559 0.719657
            +vn -0.024415 0.998810 0.041749
            +vn 0.272011 0.839625 -0.470107
            +vn 0.391980 0.622608 -0.677236
            +vn 0.440962 0.474471 -0.761803
            +vn -0.669027 -0.323679 0.669027
            +vn -0.701773 -0.122440 0.701773
            +vn -0.587878 0.555650 0.587878
            +vn -0.034272 0.998810 0.034272
            +vn 0.383831 0.839808 -0.383831
            +vn 0.553148 0.622913 -0.553148
            +vn 0.622303 0.474776 -0.622303
            +vn -0.818842 -0.323435 0.474166
            +vn -0.859004 -0.122410 0.497085
            +vn -0.719657 0.555559 0.416425
            +vn -0.041749 0.998810 0.024415
            +vn 0.470107 0.839625 -0.272011
            +vn 0.677236 0.622608 -0.391980
            +vn 0.761803 0.474471 -0.440962
            +vn -0.913999 -0.322947 0.245491
            +vn -0.958617 -0.122227 0.257057
            +vn -0.803217 0.555376 0.215308
            +vn -0.046205 0.998840 0.012726
            +vn 0.525376 0.839106 -0.140843
            +vn 0.756340 0.621845 -0.202918
            +vn 0.850551 0.473769 -0.228217
            +vn 0.877041 0.418744 0.235298
            +vn 0.908292 0.418256 0.000000
            +vn 0.888668 0.391644 0.238441
            +vn 0.920286 0.391156 0.000000
            +vn 0.907315 0.342753 0.243446
            +vn 0.939543 0.342357 0.000000
            +vn 0.931028 0.265908 0.249855
            +vn 0.964080 0.265542 0.000000
            +vn 0.954558 0.152104 0.256172
            +vn 0.988372 0.151891 0.000000
            +vn 0.964782 -0.045717 0.258980
            +vn 0.998932 -0.045656 0.000000
            +vn 0.785638 0.419416 0.454756
            +vn 0.796075 0.392285 0.460799
            +vn 0.812830 0.343333 0.470504
            +vn 0.834162 0.266366 0.482864
            +vn 0.855312 0.152409 0.495132
            +vn 0.864498 -0.045808 0.500504
            +vn 0.641804 0.419691 0.641804
            +vn 0.650349 0.392529 0.650349
            +vn 0.664052 0.343577 0.664052
            +vn 0.681509 0.266579 0.681509
            +vn 0.698813 0.152501 0.698813
            +vn 0.706351 -0.045869 0.706351
            +vn 0.454756 0.419416 0.785638
            +vn 0.460799 0.392285 0.796075
            +vn 0.470504 0.343333 0.812830
            +vn 0.482864 0.266396 0.834162
            +vn 0.495132 0.152409 0.855312
            +vn 0.500504 -0.045808 0.864498
            +vn 0.235298 0.418744 0.877041
            +vn 0.238441 0.391644 0.888668
            +vn 0.243446 0.342753 0.907315
            +vn 0.249825 0.265908 0.931028
            +vn 0.256172 0.152135 0.954558
            +vn 0.258980 -0.045717 0.964782
            +vn 0.000000 0.418256 0.908292
            +vn 0.000000 0.391156 0.920286
            +vn 0.000000 0.342357 0.939543
            +vn 0.000000 0.265572 0.964080
            +vn 0.000000 0.151921 0.988372
            +vn 0.000000 -0.045656 0.998932
            +vn -0.235298 0.418744 0.877041
            +vn -0.238441 0.391644 0.888668
            +vn -0.243446 0.342753 0.907315
            +vn -0.249825 0.265908 0.931028
            +vn -0.256172 0.152135 0.954558
            +vn -0.258980 -0.045717 0.964782
            +vn -0.454756 0.419416 0.785638
            +vn -0.460799 0.392285 0.796075
            +vn -0.470504 0.343333 0.812830
            +vn -0.482864 0.266396 0.834162
            +vn -0.495132 0.152409 0.855312
            +vn -0.500504 -0.045808 0.864498
            +vn -0.641804 0.419691 0.641804
            +vn -0.650349 0.392529 0.650349
            +vn -0.664052 0.343577 0.664052
            +vn -0.681509 0.266579 0.681509
            +vn -0.698813 0.152501 0.698813
            +vn -0.706351 -0.045869 0.706351
            +vn -0.785638 0.419416 0.454756
            +vn -0.796075 0.392285 0.460799
            +vn -0.812830 0.343333 0.470504
            +vn -0.834162 0.266366 0.482864
            +vn -0.855312 0.152409 0.495132
            +vn -0.864498 -0.045808 0.500504
            +vn -0.877041 0.418744 0.235298
            +vn -0.888668 0.391644 0.238441
            +vn -0.907315 0.342753 0.243446
            +vn -0.931028 0.265908 0.249825
            +vn -0.954558 0.152104 0.256172
            +vn -0.964782 -0.045717 0.258980
            +vn -0.908292 0.418256 0.000000
            +vn -0.920286 0.391156 0.000000
            +vn -0.939543 0.342357 0.000000
            +vn -0.964080 0.265542 0.000000
            +vn -0.988372 0.151891 0.000000
            +vn -0.998932 -0.045656 0.000000
            +vn -0.877041 0.418744 -0.235298
            +vn -0.888668 0.391644 -0.238441
            +vn -0.907315 0.342753 -0.243446
            +vn -0.931028 0.265877 -0.249855
            +vn -0.954558 0.152104 -0.256172
            +vn -0.964782 -0.045717 -0.258980
            +vn -0.785638 0.419416 -0.454756
            +vn -0.796075 0.392285 -0.460799
            +vn -0.812830 0.343333 -0.470504
            +vn -0.834162 0.266366 -0.482864
            +vn -0.855312 0.152379 -0.495132
            +vn -0.864498 -0.045808 -0.500504
            +vn -0.641804 0.419691 -0.641804
            +vn -0.650349 0.392529 -0.650349
            +vn -0.664052 0.343547 -0.664052
            +vn -0.681509 0.266549 -0.681509
            +vn -0.698813 0.152470 -0.698813
            +vn -0.706351 -0.045869 -0.706351
            +vn -0.454756 0.419416 -0.785638
            +vn -0.460768 0.392285 -0.796075
            +vn -0.470504 0.343333 -0.812830
            +vn -0.482864 0.266366 -0.834162
            +vn -0.495132 0.152379 -0.855312
            +vn -0.500504 -0.045808 -0.864498
            +vn -0.235298 0.418744 -0.877041
            +vn -0.238441 0.391644 -0.888668
            +vn -0.243446 0.342753 -0.907315
            +vn -0.249855 0.265877 -0.931059
            +vn -0.256172 0.152074 -0.954558
            +vn -0.258980 -0.045717 -0.964782
            +vn 0.000000 0.418256 -0.908292
            +vn 0.000000 0.391156 -0.920286
            +vn 0.000000 0.342357 -0.939543
            +vn 0.000000 0.265511 -0.964080
            +vn 0.000000 0.151891 -0.988372
            +vn 0.000000 -0.045656 -0.998932
            +vn 0.235298 0.418744 -0.877041
            +vn 0.238441 0.391644 -0.888668
            +vn 0.243446 0.342753 -0.907315
            +vn 0.249855 0.265877 -0.931059
            +vn 0.256172 0.152074 -0.954558
            +vn 0.258980 -0.045717 -0.964782
            +vn 0.454756 0.419416 -0.785638
            +vn 0.460768 0.392285 -0.796075
            +vn 0.470504 0.343333 -0.812830
            +vn 0.482864 0.266366 -0.834162
            +vn 0.495132 0.152379 -0.855312
            +vn 0.500504 -0.045808 -0.864498
            +vn 0.641804 0.419691 -0.641804
            +vn 0.650349 0.392529 -0.650349
            +vn 0.664052 0.343547 -0.664052
            +vn 0.681509 0.266549 -0.681509
            +vn 0.698813 0.152470 -0.698813
            +vn 0.706351 -0.045869 -0.706351
            +vn 0.785638 0.419416 -0.454756
            +vn 0.796075 0.392285 -0.460799
            +vn 0.812830 0.343333 -0.470504
            +vn 0.834162 0.266366 -0.482864
            +vn 0.855312 0.152379 -0.495132
            +vn 0.864498 -0.045808 -0.500504
            +vn 0.877041 0.418744 -0.235298
            +vn 0.888668 0.391644 -0.238441
            +vn 0.907315 0.342753 -0.243446
            +vn 0.931028 0.265908 -0.249825
            +vn 0.954558 0.152104 -0.256172
            +vn 0.964782 -0.045717 -0.258980
            +vn 0.912839 -0.326609 0.245003
            +vn 0.945250 -0.326273 0.000000
            +vn 0.795892 -0.566485 0.213538
            +vn 0.824396 -0.565996 0.000000
            +vn 0.687399 -0.702445 0.184393
            +vn 0.712180 -0.701987 0.000000
            +vn 0.630146 -0.757805 0.169012
            +vn 0.652974 -0.757347 0.000000
            +vn 0.698752 -0.690329 0.187445
            +vn 0.724021 -0.689749 0.000000
            +vn 0.855861 -0.463454 0.229530
            +vn 0.886380 -0.462905 0.000000
            +vn 0.817774 -0.327158 0.473434
            +vn 0.712729 -0.567248 0.412549
            +vn 0.615375 -0.703146 0.356151
            +vn 0.564043 -0.758446 0.326456
            +vn 0.625660 -0.690939 0.362102
            +vn 0.766625 -0.464125 0.443678
            +vn 0.668111 -0.327403 0.668111
            +vn 0.582171 -0.567522 0.582171
            +vn 0.502579 -0.703421 0.502579
            +vn 0.460646 -0.758660 0.460646
            +vn 0.510971 -0.691183 0.510971
            +vn 0.626209 -0.464370 0.626209
            +vn 0.473434 -0.327158 0.817774
            +vn 0.412549 -0.567248 0.712729
            +vn 0.356151 -0.703146 0.615375
            +vn 0.326456 -0.758446 0.564043
            +vn 0.362102 -0.690939 0.625660
            +vn 0.443678 -0.464125 0.766625
            +vn 0.245003 -0.326609 0.912839
            +vn 0.213538 -0.566485 0.795892
            +vn 0.184393 -0.702445 0.687399
            +vn 0.169012 -0.757805 0.630146
            +vn 0.187414 -0.690329 0.698752
            +vn 0.229530 -0.463454 0.855831
            +vn 0.000000 -0.326273 0.945250
            +vn 0.000000 -0.565996 0.824396
            +vn 0.000000 -0.701987 0.712180
            +vn 0.000000 -0.757347 0.652974
            +vn 0.000000 -0.689749 0.724021
            +vn 0.000000 -0.462905 0.886380
            +vn -0.245003 -0.326609 0.912839
            +vn -0.213538 -0.566485 0.795892
            +vn -0.184393 -0.702445 0.687399
            +vn -0.169012 -0.757805 0.630146
            +vn -0.187414 -0.690329 0.698752
            +vn -0.229530 -0.463454 0.855831
            +vn -0.473434 -0.327158 0.817774
            +vn -0.412549 -0.567248 0.712729
            +vn -0.356151 -0.703146 0.615375
            +vn -0.326456 -0.758446 0.564043
            +vn -0.362102 -0.690939 0.625660
            +vn -0.443678 -0.464125 0.766625
            +vn -0.668111 -0.327403 0.668111
            +vn -0.582171 -0.567522 0.582171
            +vn -0.502579 -0.703421 0.502579
            +vn -0.460646 -0.758660 0.460646
            +vn -0.510971 -0.691183 0.510971
            +vn -0.626209 -0.464370 0.626209
            +vn -0.817774 -0.327158 0.473434
            +vn -0.712729 -0.567248 0.412549
            +vn -0.615375 -0.703146 0.356151
            +vn -0.564043 -0.758446 0.326456
            +vn -0.625660 -0.690939 0.362102
            +vn -0.766625 -0.464125 0.443678
            +vn -0.912839 -0.326609 0.245003
            +vn -0.795892 -0.566485 0.213538
            +vn -0.687399 -0.702445 0.184393
            +vn -0.630146 -0.757805 0.169012
            +vn -0.698752 -0.690329 0.187445
            +vn -0.855861 -0.463454 0.229530
            +vn -0.945250 -0.326273 0.000000
            +vn -0.824396 -0.565996 0.000000
            +vn -0.712180 -0.701987 0.000000
            +vn -0.652974 -0.757347 0.000000
            +vn -0.724021 -0.689749 0.000000
            +vn -0.886380 -0.462905 0.000000
            +vn -0.912839 -0.326609 -0.245003
            +vn -0.795892 -0.566485 -0.213538
            +vn -0.687399 -0.702445 -0.184393
            +vn -0.630146 -0.757805 -0.169012
            +vn -0.698752 -0.690329 -0.187414
            +vn -0.855831 -0.463454 -0.229530
            +vn -0.817774 -0.327158 -0.473434
            +vn -0.712729 -0.567248 -0.412549
            +vn -0.615375 -0.703146 -0.356151
            +vn -0.564043 -0.758446 -0.326456
            +vn -0.625660 -0.690939 -0.362102
            +vn -0.766625 -0.464125 -0.443678
            +vn -0.668111 -0.327403 -0.668111
            +vn -0.582171 -0.567522 -0.582171
            +vn -0.502579 -0.703421 -0.502579
            +vn -0.460646 -0.758660 -0.460646
            +vn -0.510971 -0.691183 -0.510971
            +vn -0.626209 -0.464370 -0.626209
            +vn -0.473434 -0.327158 -0.817774
            +vn -0.412549 -0.567248 -0.712729
            +vn -0.356151 -0.703146 -0.615375
            +vn -0.326456 -0.758446 -0.564043
            +vn -0.362102 -0.690939 -0.625660
            +vn -0.443678 -0.464125 -0.766625
            +vn -0.245003 -0.326609 -0.912839
            +vn -0.213538 -0.566485 -0.795892
            +vn -0.184393 -0.702445 -0.687399
            +vn -0.169012 -0.757805 -0.630146
            +vn -0.187414 -0.690329 -0.698752
            +vn -0.229530 -0.463454 -0.855831
            +vn 0.000000 -0.326273 -0.945250
            +vn 0.000000 -0.565996 -0.824396
            +vn 0.000000 -0.701987 -0.712149
            +vn 0.000000 -0.757347 -0.652974
            +vn 0.000000 -0.689749 -0.724021
            +vn 0.000000 -0.462905 -0.886380
            +vn 0.245003 -0.326609 -0.912839
            +vn 0.213538 -0.566485 -0.795892
            +vn 0.184393 -0.702445 -0.687399
            +vn 0.169012 -0.757805 -0.630146
            +vn 0.187414 -0.690329 -0.698752
            +vn 0.229530 -0.463454 -0.855831
            +vn 0.473434 -0.327158 -0.817774
            +vn 0.412549 -0.567248 -0.712729
            +vn 0.356151 -0.703146 -0.615375
            +vn 0.326456 -0.758446 -0.564043
            +vn 0.362102 -0.690939 -0.625660
            +vn 0.443678 -0.464125 -0.766625
            +vn 0.668111 -0.327403 -0.668111
            +vn 0.582171 -0.567522 -0.582171
            +vn 0.502579 -0.703421 -0.502579
            +vn 0.460646 -0.758660 -0.460646
            +vn 0.510971 -0.691183 -0.510971
            +vn 0.626209 -0.464370 -0.626209
            +vn 0.817774 -0.327158 -0.473434
            +vn 0.712729 -0.567248 -0.412549
            +vn 0.615375 -0.703146 -0.356151
            +vn 0.564043 -0.758446 -0.326456
            +vn 0.625660 -0.690939 -0.362102
            +vn 0.766625 -0.464125 -0.443678
            +vn 0.912839 -0.326609 -0.245003
            +vn 0.795892 -0.566485 -0.213538
            +vn 0.687399 -0.702445 -0.184393
            +vn 0.630146 -0.757805 -0.169012
            +vn 0.698752 -0.690329 -0.187414
            +vn 0.855831 -0.463454 -0.229530
            +vn 0.068667 -0.997620 0.000000
            +vn 0.066256 -0.997620 -0.017731
            +vn 0.157170 -0.987548 0.000000
            +vn 0.151677 -0.987579 -0.040620
            +vn 0.373150 -0.927763 0.000000
            +vn 0.360149 -0.927885 -0.096469
            +vn 0.789148 -0.614154 0.000000
            +vn 0.762017 -0.614399 -0.204474
            +vn 0.059236 -0.997650 -0.034242
            +vn 0.135624 -0.987640 -0.078463
            +vn 0.322153 -0.928129 -0.186346
            +vn 0.682333 -0.615131 -0.394971
            +vn 0.048341 -0.997650 -0.048341
            +vn 0.110691 -0.987640 -0.110691
            +vn 0.262947 -0.928251 -0.262947
            +vn 0.557329 -0.615375 -0.557329
            +vn 0.034272 -0.997650 -0.059236
            +vn 0.078463 -0.987640 -0.135624
            +vn 0.186377 -0.928129 -0.322153
            +vn 0.394971 -0.615131 -0.682333
            +vn 0.017731 -0.997620 -0.066256
            +vn 0.040620 -0.987579 -0.151677
            +vn 0.096469 -0.927885 -0.360118
            +vn 0.204505 -0.614399 -0.762017
            +vn 0.000000 -0.997620 -0.068667
            +vn 0.000000 -0.987548 -0.157170
            +vn 0.000000 -0.927763 -0.373150
            +vn 0.000000 -0.614154 -0.789148
            +vn -0.017731 -0.997620 -0.066256
            +vn -0.040620 -0.987579 -0.151677
            +vn -0.096469 -0.927885 -0.360118
            +vn -0.204505 -0.614399 -0.762017
            +vn -0.034272 -0.997650 -0.059236
            +vn -0.078463 -0.987640 -0.135624
            +vn -0.186377 -0.928129 -0.322153
            +vn -0.394971 -0.615131 -0.682333
            +vn -0.048341 -0.997650 -0.048341
            +vn -0.110691 -0.987640 -0.110691
            +vn -0.262947 -0.928251 -0.262947
            +vn -0.557329 -0.615375 -0.557329
            +vn -0.059236 -0.997650 -0.034242
            +vn -0.135624 -0.987640 -0.078463
            +vn -0.322153 -0.928129 -0.186346
            +vn -0.682333 -0.615131 -0.394971
            +vn -0.066256 -0.997620 -0.017731
            +vn -0.151677 -0.987579 -0.040620
            +vn -0.360149 -0.927885 -0.096469
            +vn -0.762017 -0.614399 -0.204474
            +vn -0.068667 -0.997620 0.000000
            +vn -0.157170 -0.987548 0.000000
            +vn -0.373150 -0.927763 0.000000
            +vn -0.789148 -0.614154 0.000000
            +vn -0.066256 -0.997620 0.017731
            +vn -0.151677 -0.987579 0.040620
            +vn -0.360118 -0.927885 0.096469
            +vn -0.762017 -0.614399 0.204505
            +vn -0.059236 -0.997650 0.034272
            +vn -0.135624 -0.987640 0.078463
            +vn -0.322153 -0.928129 0.186377
            +vn -0.682333 -0.615131 0.394971
            +vn -0.048341 -0.997650 0.048341
            +vn -0.110691 -0.987640 0.110691
            +vn -0.262947 -0.928251 0.262947
            +vn -0.557329 -0.615375 0.557329
            +vn -0.034272 -0.997650 0.059236
            +vn -0.078463 -0.987640 0.135624
            +vn -0.186377 -0.928129 0.322153
            +vn -0.394971 -0.615131 0.682333
            +vn -0.017731 -0.997620 0.066256
            +vn -0.040620 -0.987579 0.151677
            +vn -0.096469 -0.927885 0.360149
            +vn -0.204474 -0.614399 0.762017
            +vn 0.000000 -0.997620 0.068667
            +vn 0.000000 -0.987548 0.157170
            +vn 0.000000 -0.927763 0.373150
            +vn 0.000000 -0.614154 0.789148
            +vn 0.017731 -0.997620 0.066256
            +vn 0.040620 -0.987579 0.151677
            +vn 0.096469 -0.927885 0.360149
            +vn 0.204474 -0.614399 0.762017
            +vn 0.034272 -0.997650 0.059236
            +vn 0.078463 -0.987640 0.135624
            +vn 0.186377 -0.928129 0.322153
            +vn 0.394971 -0.615131 0.682333
            +vn 0.048341 -0.997650 0.048341
            +vn 0.110691 -0.987640 0.110691
            +vn 0.262947 -0.928251 0.262947
            +vn 0.557329 -0.615375 0.557329
            +vn 0.059236 -0.997650 0.034272
            +vn 0.135624 -0.987640 0.078463
            +vn 0.322153 -0.928129 0.186377
            +vn 0.682333 -0.615101 0.394971
            +vn 0.066256 -0.997620 0.017731
            +vn 0.151677 -0.987579 0.040620
            +vn 0.360118 -0.927885 0.096469
            +vn 0.762017 -0.614399 0.204505
            +vn 0.692129 0.697470 0.185583
            +vn 0.717063 0.696982 0.000000
            +vn 0.915586 0.318766 0.245064
            +vn 0.947905 0.318522 0.000000
            +vn 0.620045 0.697653 0.358837
            +vn 0.820429 0.318979 0.474410
            +vn 0.506546 0.697684 0.506546
            +vn 0.670125 0.319041 0.670125
            +vn 0.358837 0.697653 0.620045
            +vn 0.474410 0.318979 0.820429
            +vn 0.185583 0.697470 0.692129
            +vn 0.245064 0.318766 0.915586
            +vn 0.000000 0.696982 0.717063
            +vn 0.000000 0.318522 0.947905
            +vn -0.185583 0.697470 0.692129
            +vn -0.245064 0.318766 0.915586
            +vn -0.358837 0.697653 0.620045
            +vn -0.474410 0.318979 0.820429
            +vn -0.506546 0.697684 0.506546
            +vn -0.670125 0.319041 0.670125
            +vn -0.620045 0.697653 0.358837
            +vn -0.820429 0.318979 0.474410
            +vn -0.692129 0.697470 0.185583
            +vn -0.915586 0.318766 0.245064
            +vn -0.717063 0.696982 0.000000
            +vn -0.947905 0.318522 0.000000
            +vn -0.692129 0.697470 -0.185583
            +vn -0.915586 0.318766 -0.245064
            +vn -0.620045 0.697653 -0.358837
            +vn -0.820429 0.318979 -0.474410
            +vn -0.506546 0.697684 -0.506546
            +vn -0.670125 0.319041 -0.670125
            +vn -0.358837 0.697653 -0.620045
            +vn -0.474410 0.318979 -0.820429
            +vn -0.185583 0.697470 -0.692129
            +vn -0.245064 0.318766 -0.915586
            +vn 0.000000 0.696982 -0.717063
            +vn 0.000000 0.318522 -0.947905
            +vn 0.185583 0.697470 -0.692129
            +vn 0.245064 0.318766 -0.915586
            +vn 0.358837 0.697653 -0.620045
            +vn 0.474410 0.318979 -0.820429
            +vn 0.506546 0.697684 -0.506546
            +vn 0.670125 0.319041 -0.670125
            +vn 0.620045 0.697653 -0.358837
            +vn 0.820429 0.318979 -0.474410
            +vn 0.692129 0.697470 -0.185583
            +vn 0.915586 0.318766 -0.245064
            +vn 0.282083 0.956389 0.075686
            +vn 0.292520 0.956236 0.000000
            +vn 0.171606 0.984069 0.046022
            +vn 0.177953 0.984008 0.000000
            +vn 0.153264 0.987304 0.041078
            +vn 0.158879 0.987274 0.000000
            +vn 0.210059 0.976043 0.056276
            +vn 0.217719 0.975982 0.000000
            +vn 0.487197 0.863460 0.130558
            +vn 0.504715 0.863277 0.000000
            +vn 0.662801 0.727226 0.178198
            +vn 0.686911 0.726707 0.000000
            +vn 0.252388 0.956511 0.146092
            +vn 0.153508 0.984130 0.088839
            +vn 0.137059 0.987365 0.079318
            +vn 0.187872 0.976135 0.108676
            +vn 0.435926 0.863887 0.252205
            +vn 0.593310 0.727866 0.343730
            +vn 0.206091 0.956572 0.206091
            +vn 0.125340 0.984161 0.125340
            +vn 0.111911 0.987396 0.111911
            +vn 0.153356 0.976196 0.153356
            +vn 0.355907 0.864071 0.355907
            +vn 0.484664 0.728111 0.484664
            +vn 0.146092 0.956511 0.252388
            +vn 0.088839 0.984130 0.153508
            +vn 0.079318 0.987365 0.137059
            +vn 0.108676 0.976135 0.187872
            +vn 0.252205 0.863887 0.435926
            +vn 0.343730 0.727866 0.593310
            +vn 0.075686 0.956389 0.282083
            +vn 0.046022 0.984069 0.171606
            +vn 0.041078 0.987304 0.153264
            +vn 0.056276 0.976043 0.210059
            +vn 0.130558 0.863460 0.487197
            +vn 0.178198 0.727226 0.662801
            +vn 0.000000 0.956236 0.292520
            +vn 0.000000 0.984008 0.177953
            +vn 0.000000 0.987274 0.158879
            +vn 0.000000 0.975982 0.217719
            +vn 0.000000 0.863277 0.504715
            +vn 0.000000 0.726707 0.686911
            +vn -0.075686 0.956389 0.282083
            +vn -0.046022 0.984069 0.171606
            +vn -0.041078 0.987304 0.153264
            +vn -0.056276 0.976043 0.210059
            +vn -0.130558 0.863460 0.487197
            +vn -0.178198 0.727226 0.662801
            +vn -0.146092 0.956511 0.252388
            +vn -0.088839 0.984130 0.153508
            +vn -0.079318 0.987365 0.137059
            +vn -0.108676 0.976135 0.187872
            +vn -0.252205 0.863887 0.435926
            +vn -0.343730 0.727866 0.593310
            +vn -0.206091 0.956572 0.206091
            +vn -0.125340 0.984161 0.125340
            +vn -0.111911 0.987396 0.111911
            +vn -0.153356 0.976196 0.153356
            +vn -0.355907 0.864071 0.355907
            +vn -0.484664 0.728111 0.484664
            +vn -0.252388 0.956511 0.146092
            +vn -0.153508 0.984130 0.088839
            +vn -0.137059 0.987365 0.079318
            +vn -0.187872 0.976135 0.108676
            +vn -0.435926 0.863887 0.252205
            +vn -0.593310 0.727866 0.343730
            +vn -0.282083 0.956389 0.075686
            +vn -0.171606 0.984069 0.046022
            +vn -0.153264 0.987304 0.041078
            +vn -0.210059 0.976043 0.056276
            +vn -0.487197 0.863460 0.130558
            +vn -0.662801 0.727226 0.178198
            +vn -0.292520 0.956236 0.000000
            +vn -0.177953 0.984008 0.000000
            +vn -0.158879 0.987274 0.000000
            +vn -0.217719 0.975982 0.000000
            +vn -0.504715 0.863277 0.000000
            +vn -0.686911 0.726707 0.000000
            +vn -0.282083 0.956389 -0.075686
            +vn -0.171606 0.984069 -0.046022
            +vn -0.153264 0.987304 -0.041078
            +vn -0.210059 0.976043 -0.056276
            +vn -0.487197 0.863460 -0.130558
            +vn -0.662801 0.727226 -0.178198
            +vn -0.252388 0.956511 -0.146092
            +vn -0.153508 0.984130 -0.088839
            +vn -0.137059 0.987365 -0.079318
            +vn -0.187872 0.976135 -0.108676
            +vn -0.435926 0.863887 -0.252205
            +vn -0.593310 0.727866 -0.343730
            +vn -0.206091 0.956572 -0.206091
            +vn -0.125340 0.984161 -0.125340
            +vn -0.111911 0.987396 -0.111911
            +vn -0.153356 0.976196 -0.153356
            +vn -0.355907 0.864071 -0.355907
            +vn -0.484664 0.728111 -0.484664
            +vn -0.146092 0.956511 -0.252388
            +vn -0.088839 0.984130 -0.153508
            +vn -0.079318 0.987365 -0.137059
            +vn -0.108676 0.976135 -0.187872
            +vn -0.252205 0.863887 -0.435926
            +vn -0.343730 0.727866 -0.593310
            +vn -0.075686 0.956389 -0.282083
            +vn -0.046022 0.984069 -0.171606
            +vn -0.041078 0.987304 -0.153264
            +vn -0.056276 0.976043 -0.210059
            +vn -0.130558 0.863460 -0.487197
            +vn -0.178198 0.727226 -0.662801
            +vn 0.000000 0.956236 -0.292520
            +vn 0.000000 0.984008 -0.177953
            +vn 0.000000 0.987274 -0.158879
            +vn 0.000000 0.975982 -0.217719
            +vn 0.000000 0.863277 -0.504715
            +vn 0.000000 0.726707 -0.686911
            +vn 0.075686 0.956389 -0.282083
            +vn 0.046022 0.984069 -0.171606
            +vn 0.041078 0.987304 -0.153264
            +vn 0.056276 0.976043 -0.210059
            +vn 0.130558 0.863460 -0.487197
            +vn 0.178198 0.727226 -0.662801
            +vn 0.146092 0.956511 -0.252388
            +vn 0.088839 0.984130 -0.153508
            +vn 0.079318 0.987365 -0.137059
            +vn 0.108676 0.976135 -0.187872
            +vn 0.252205 0.863887 -0.435926
            +vn 0.343730 0.727866 -0.593310
            +vn 0.206091 0.956572 -0.206091
            +vn 0.125340 0.984161 -0.125340
            +vn 0.111911 0.987396 -0.111911
            +vn 0.153356 0.976196 -0.153356
            +vn 0.355907 0.864071 -0.355907
            +vn 0.484664 0.728111 -0.484664
            +vn 0.252388 0.956511 -0.146092
            +vn 0.153508 0.984130 -0.088839
            +vn 0.137059 0.987365 -0.079318
            +vn 0.187872 0.976135 -0.108676
            +vn 0.435926 0.863887 -0.252205
            +vn 0.593310 0.727866 -0.343730
            +vn 0.282083 0.956389 -0.075686
            +vn 0.171606 0.984069 -0.046022
            +vn 0.153264 0.987304 -0.041078
            +vn 0.210059 0.976043 -0.056276
            +vn 0.487197 0.863460 -0.130558
            +vn 0.662801 0.727226 -0.178198
            +vn 0.015290 -0.999878 0.000000
            +vn 0.003296 -0.999969 0.000000
            +vn 0.015168 -0.949339 0.313852
            +vn 0.003265 -0.944395 0.328715
            +vn 0.058870 -0.998260 0.000000
            +vn 0.058046 -0.947630 0.314005
            +vn 0.158361 -0.934690 0.318155
            +vn 0.159764 -0.987152 0.000000
            +vn 0.373943 -0.860958 0.344798
            +vn 0.391583 -0.920103 0.000000
            +vn 0.726829 -0.553880 0.406049
            +vn 0.784570 -0.620014 0.000000
            +vn 0.908139 -0.082766 0.410321
            +vn 0.994995 -0.099796 0.000000
            +vn 0.011902 -0.679403 0.733634
            +vn 0.002380 -0.636219 0.771477
            +vn 0.046449 -0.674398 0.736869
            +vn 0.125980 -0.648946 0.750298
            +vn 0.270089 -0.562120 0.781671
            +vn 0.460067 -0.316263 0.829615
            +vn 0.563036 -0.041200 0.825373
            +vn 0.000153 0.004242 0.999969
            +vn -0.000519 0.113254 0.993561
            +vn 0.003510 0.014008 0.999878
            +vn 0.005921 0.035951 0.999329
            +vn -0.007813 0.058840 0.998230
            +vn -0.046510 0.041536 0.998047
            +vn -0.039155 0.003113 0.999207
            +vn -0.014161 0.682394 0.730796
            +vn -0.003204 0.727744 0.685812
            +vn -0.055361 0.680074 0.731010
            +vn -0.150029 0.655660 0.739952
            +vn -0.322520 0.565203 0.759239
            +vn -0.537645 0.315806 0.781762
            +vn -0.611530 0.029939 0.790613
            +vn -0.020569 0.949400 0.313334
            +vn -0.004273 0.954772 0.297281
            +vn -0.082705 0.944945 0.316507
            +vn -0.229591 0.914548 0.332926
            +vn -0.502335 0.785943 0.360454
            +vn -0.810633 0.443220 0.382611
            +vn -0.921232 0.039705 0.386944
            +vn -0.021851 0.999756 0.000000
            +vn -0.004517 0.999969 0.000000
            +vn -0.087649 0.996124 0.000000
            +vn -0.246223 0.969207 0.000000
            +vn -0.549211 0.835658 0.000000
            +vn -0.881039 0.472976 0.000000
            +vn -0.999115 0.041444 0.000000
            +vn -0.004273 0.954772 -0.297281
            +vn -0.020569 0.949400 -0.313334
            +vn -0.082705 0.944945 -0.316507
            +vn -0.229591 0.914548 -0.332926
            +vn -0.502335 0.785943 -0.360454
            +vn -0.810633 0.443220 -0.382611
            +vn -0.921232 0.039705 -0.386944
            +vn -0.003204 0.727744 -0.685812
            +vn -0.014161 0.682394 -0.730796
            +vn -0.055361 0.680074 -0.731010
            +vn -0.150029 0.655660 -0.739952
            +vn -0.322520 0.565203 -0.759239
            +vn -0.537645 0.315806 -0.781762
            +vn -0.611530 0.029939 -0.790613
            +vn -0.000519 0.113254 -0.993561
            +vn 0.000153 0.004242 -0.999969
            +vn 0.003510 0.014008 -0.999878
            +vn 0.005921 0.035951 -0.999329
            +vn -0.007813 0.058809 -0.998230
            +vn -0.046510 0.041536 -0.998047
            +vn -0.039155 0.003113 -0.999207
            +vn 0.002380 -0.636219 -0.771477
            +vn 0.011902 -0.679403 -0.733634
            +vn 0.046449 -0.674398 -0.736869
            +vn 0.125980 -0.648946 -0.750298
            +vn 0.270089 -0.562151 -0.781671
            +vn 0.460067 -0.316263 -0.829615
            +vn 0.563036 -0.041231 -0.825373
            +vn 0.003265 -0.944395 -0.328715
            +vn 0.015168 -0.949339 -0.313852
            +vn 0.058046 -0.947630 -0.314005
            +vn 0.158361 -0.934690 -0.318155
            +vn 0.373943 -0.860958 -0.344798
            +vn 0.726829 -0.553880 -0.406049
            +vn 0.908139 -0.082766 -0.410321
            +vn 0.890500 0.214759 0.401044
            +vn 0.972930 0.231025 0.000000
            +vn 0.836634 0.384075 0.390515
            +vn 0.912503 0.408979 0.000000
            +vn 0.765191 0.530198 0.365123
            +vn 0.828791 0.559496 0.000000
            +vn 0.671041 0.663228 0.331339
            +vn 0.718955 0.695029 0.000000
            +vn 0.549455 0.776238 0.309000
            +vn 0.580859 0.813990 0.000000
            +vn 0.461165 0.821528 0.335215
            +vn 0.497085 0.867672 0.000000
            +vn 0.559679 0.139714 0.816828
            +vn 0.528581 0.255501 0.809473
            +vn 0.494888 0.359783 0.790948
            +vn 0.445143 0.467879 0.763451
            +vn 0.376049 0.559984 0.738212
            +vn 0.287332 0.527940 0.799188
            +vn -0.024537 -0.005737 0.999664
            +vn -0.020844 -0.012207 0.999695
            +vn -0.014466 -0.014466 0.999786
            +vn -0.009796 -0.013276 0.999847
            +vn -0.014771 -0.013886 0.999786
            +vn -0.101779 -0.196661 0.975158
            +vn -0.585437 -0.154668 0.795801
            +vn -0.538499 -0.291696 0.790490
            +vn -0.487228 -0.408918 0.771599
            +vn -0.428327 -0.511948 0.744560
            +vn -0.360820 -0.584735 0.726524
            +vn -0.357311 -0.691549 0.627735
            +vn -0.889126 -0.238868 0.390332
            +vn -0.807001 -0.448500 0.384075
            +vn -0.700980 -0.613392 0.363750
            +vn -0.590442 -0.733757 0.336009
            +vn -0.486190 -0.814966 0.315256
            +vn -0.440138 -0.855586 0.272439
            +vn -0.965453 -0.260506 0.000000
            +vn -0.872097 -0.489273 0.000000
            +vn -0.748253 -0.663381 0.000000
            +vn -0.621784 -0.783166 0.000000
            +vn -0.507614 -0.861568 0.000000
            +vn -0.456954 -0.889462 0.000000
            +vn -0.889126 -0.238868 -0.390332
            +vn -0.807001 -0.448531 -0.384075
            +vn -0.700980 -0.613392 -0.363750
            +vn -0.590442 -0.733757 -0.336009
            +vn -0.486190 -0.814966 -0.315256
            +vn -0.440138 -0.855586 -0.272439
            +vn -0.585437 -0.154668 -0.795801
            +vn -0.538499 -0.291696 -0.790490
            +vn -0.487228 -0.408918 -0.771599
            +vn -0.428327 -0.511948 -0.744560
            +vn -0.360820 -0.584735 -0.726524
            +vn -0.357311 -0.691549 -0.627705
            +vn -0.024537 -0.005737 -0.999664
            +vn -0.020844 -0.012238 -0.999695
            +vn -0.014466 -0.014466 -0.999786
            +vn -0.009766 -0.013276 -0.999847
            +vn -0.014771 -0.013916 -0.999786
            +vn -0.101779 -0.196661 -0.975158
            +vn 0.559679 0.139714 -0.816828
            +vn 0.528581 0.255501 -0.809473
            +vn 0.494888 0.359783 -0.790948
            +vn 0.445143 0.467879 -0.763451
            +vn 0.376049 0.559984 -0.738212
            +vn 0.287332 0.527940 -0.799188
            +vn 0.890500 0.214759 -0.401044
            +vn 0.836634 0.384075 -0.390515
            +vn 0.765191 0.530198 -0.365123
            +vn 0.671041 0.663228 -0.331339
            +vn 0.549455 0.776238 -0.309000
            +vn 0.461165 0.821528 -0.335215
            +vn -0.149937 0.988678 0.000000
            +vn -0.137028 0.872402 0.469131
            +vn -0.297769 0.840358 0.452895
            +vn -0.350505 0.936552 0.000000
            +vn -0.617512 0.663961 0.421613
            +vn -0.715506 0.698569 0.000000
            +vn -0.801324 0.450209 0.393872
            +vn -0.900845 0.434065 0.000000
            +vn -0.828028 0.379803 0.412397
            +vn -0.929289 0.369274 0.000000
            +vn -0.729179 0.503464 0.463393
            +vn -0.857875 0.513810 0.000000
            +vn -0.663076 0.748527 0.000000
            +vn -0.531449 0.686514 0.496170
            +vn -0.066713 0.491440 0.868313
            +vn -0.117893 0.503159 0.856105
            +vn -0.254341 0.474349 0.842769
            +vn -0.411115 0.399182 0.819483
            +vn -0.459395 0.346446 0.817835
            +vn -0.385876 0.395734 0.833338
            +vn -0.270669 0.487838 0.829890
            +vn 0.062716 -0.043458 0.997070
            +vn 0.135929 -0.002472 0.990692
            +vn 0.247963 0.095187 0.964049
            +vn 0.209296 0.170660 0.962828
            +vn 0.096194 0.178625 0.979186
            +vn 0.009552 0.154332 0.987945
            +vn -0.000122 0.151952 0.988372
            +vn 0.202582 -0.542894 0.814966
            +vn 0.360088 -0.479232 0.800378
            +vn 0.611988 -0.282235 0.738762
            +vn 0.679220 -0.106754 0.726096
            +vn 0.583911 -0.078524 0.807978
            +vn 0.402722 -0.205237 0.891995
            +vn 0.279519 -0.338694 0.898404
            +vn 0.294107 -0.855037 0.427015
            +vn 0.488418 -0.768700 0.412915
            +vn 0.784570 -0.501511 0.364544
            +vn 0.893918 -0.279611 0.350291
            +vn 0.861415 -0.285287 0.420179
            +vn 0.679373 -0.540422 0.496323
            +vn 0.458357 -0.754540 0.469588
            +vn 0.320780 -0.947142 0.000000
            +vn 0.525101 -0.851009 0.000000
            +vn 0.827570 -0.561327 0.000000
            +vn 0.943419 -0.331523 0.000000
            +vn 0.933561 -0.358409 0.000000
            +vn 0.756340 -0.654134 0.000000
            +vn 0.491928 -0.870602 0.000092
            +vn 0.294107 -0.855037 -0.427015
            +vn 0.488418 -0.768700 -0.412915
            +vn 0.784570 -0.501511 -0.364544
            +vn 0.893918 -0.279611 -0.350291
            +vn 0.861385 -0.285287 -0.420179
            +vn 0.679373 -0.540422 -0.496323
            +vn 0.457839 -0.755608 -0.468368
            +vn 0.202582 -0.542894 -0.814966
            +vn 0.360088 -0.479232 -0.800378
            +vn 0.611988 -0.282235 -0.738762
            +vn 0.679220 -0.106754 -0.726096
            +vn 0.583911 -0.078524 -0.807978
            +vn 0.402722 -0.205237 -0.891995
            +vn 0.279153 -0.342235 -0.897153
            +vn 0.062716 -0.043458 -0.997070
            +vn 0.135929 -0.002472 -0.990692
            +vn 0.247963 0.095187 -0.964049
            +vn 0.209296 0.170629 -0.962828
            +vn 0.096194 0.178625 -0.979186
            +vn 0.009552 0.154332 -0.987945
            +vn -0.000458 0.149358 -0.988769
            +vn -0.066713 0.491440 -0.868313
            +vn -0.117893 0.503159 -0.856105
            +vn -0.254341 0.474319 -0.842769
            +vn -0.411115 0.399182 -0.819514
            +vn -0.459395 0.346446 -0.817835
            +vn -0.385876 0.395734 -0.833338
            +vn -0.271035 0.487136 -0.830164
            +vn -0.137028 0.872402 -0.469131
            +vn -0.297769 0.840358 -0.452895
            +vn -0.617512 0.663961 -0.421613
            +vn -0.801324 0.450209 -0.393872
            +vn -0.828028 0.379803 -0.412397
            +vn -0.729209 0.503464 -0.463393
            +vn -0.531541 0.686453 -0.496200
            +vn -0.480697 0.876858 0.000000
            +vn -0.394635 0.815363 0.423536
            +vn -0.320750 0.947142 0.000092
            +vn -0.255287 0.921964 0.291086
            +vn 0.002686 0.999969 -0.000732
            +vn -0.007172 0.999939 -0.007599
            +vn 0.366832 0.704398 -0.607624
            +vn 0.853236 0.521226 -0.016388
            +vn 0.567492 -0.154088 -0.808802
            +vn 0.803766 -0.594409 -0.024964
            +vn 0.580920 -0.584490 -0.566424
            +vn 0.673757 -0.738639 -0.020966
            +vn -0.206824 0.638203 0.741539
            +vn -0.129490 0.862056 0.489944
            +vn -0.034486 0.999023 0.026704
            +vn 0.041597 0.871334 -0.488876
            +vn 0.103488 0.553880 -0.826136
            +vn 0.189642 0.174200 -0.966247
            +vn 0.020112 0.322611 0.946287
            +vn 0.021943 0.748894 0.662282
            +vn -0.025697 0.995392 0.092166
            +vn -0.056551 0.931608 -0.358989
            +vn -0.070711 0.782006 -0.619190
            +vn -0.066408 0.651509 -0.755699
            +vn 0.281747 -0.174993 0.943388
            +vn 0.303903 0.444136 0.842830
            +vn 0.035279 0.983856 0.175329
            +vn -0.109928 0.953551 -0.280435
            +vn -0.149571 0.847682 -0.508927
            +vn -0.145634 0.777520 -0.611744
            +vn 0.467238 -0.683218 0.561144
            +vn 0.699515 0.004364 0.714560
            +vn 0.354900 0.892758 0.277444
            +vn -0.174383 0.969054 -0.174596
            +vn -0.252998 0.894314 -0.368938
            +vn -0.191443 0.807947 -0.557237
            +vn 0.495346 -0.868679 0.001587
            +vn 0.933897 -0.357311 0.011017
            +vn 0.704215 0.709830 0.013337
            +vn -0.205634 0.978576 -0.006623
            +vn -0.322367 0.945708 -0.041169
            +vn -0.314951 0.916288 -0.247322
            +vn 0.459120 -0.703757 -0.542100
            +vn 0.693655 -0.096530 -0.713767
            +vn 0.408673 0.848415 -0.336344
            +vn -0.198248 0.963439 0.180151
            +vn -0.306833 0.888516 0.341075
            +vn -0.335978 0.808863 0.482498
            +vn 0.277047 -0.215796 -0.936277
            +vn 0.306192 0.349864 -0.885311
            +vn 0.056246 0.971099 -0.231819
            +vn -0.146733 0.912168 0.382611
            +vn -0.202612 0.700797 0.683950
            +vn -0.159368 0.444777 0.881314
            +vn 0.016907 0.300088 -0.953734
            +vn 0.019349 0.701865 -0.712027
            +vn -0.023713 0.995361 -0.093081
            +vn -0.047395 0.829371 0.556658
            +vn -0.015259 0.386608 0.922086
            +vn 0.080721 0.001404 0.996704
            +vn -0.209967 0.632160 -0.745811
            +vn -0.137394 0.849117 -0.509995
            +vn -0.023438 0.999695 -0.004883
            +vn 0.120426 0.724540 0.678579
            +vn 0.260750 0.006531 0.965361
            +vn 0.341502 -0.385510 0.857143
            +vn -0.395489 0.814814 -0.423841
            +vn -0.257942 0.920621 -0.293039
            +vn 0.005005 0.999908 0.011628
            +vn 0.466628 0.599811 0.649983
            +vn 0.621937 -0.400861 0.672628
            +vn 0.584826 -0.661397 0.469558
            +vn 0.363842 0.931455 0.000000
            +vn 0.000000 1.000000 0.000000
            +vn 0.351451 0.931516 0.093509
            +vn 0.314432 0.931791 0.181280
            +vn 0.256386 0.931913 0.256386
            +vn 0.181280 0.931791 0.314432
            +vn 0.093509 0.931516 0.351451
            +vn 0.000000 0.931455 0.363842
            +vn -0.093509 0.931516 0.351451
            +vn -0.181280 0.931791 0.314432
            +vn -0.256386 0.931913 0.256386
            +vn -0.314432 0.931791 0.181280
            +vn -0.351451 0.931516 0.093509
            +vn -0.363842 0.931455 0.000000
            +vn -0.351451 0.931516 -0.093509
            +vn -0.314432 0.931791 -0.181280
            +vn -0.256417 0.931913 -0.256417
            +vn -0.181280 0.931791 -0.314432
            +vn -0.093509 0.931516 -0.351451
            +vn 0.000000 0.931455 -0.363842
            +vn 0.093509 0.931516 -0.351451
            +vn 0.181280 0.931791 -0.314432
            +vn 0.256417 0.931913 -0.256417
            +vn 0.314432 0.931791 -0.181280
            +vn 0.351451 0.931516 -0.093509
            +vn 0.935423 0.249763 0.250160
            +vn 0.968261 0.249916 0.000000
            +vn 0.813959 -0.538713 0.217322
            +vn 0.842860 -0.538102 0.000000
            +vn 0.759484 -0.618030 0.202887
            +vn 0.786767 -0.617206 0.000000
            +vn 0.801569 -0.558184 0.214148
            +vn 0.830195 -0.557421 0.000000
            +vn 0.838404 0.249825 0.484359
            +vn 0.729026 -0.539720 0.420881
            +vn 0.680013 -0.619098 0.392712
            +vn 0.717765 -0.559343 0.414594
            +vn 0.684652 0.249886 0.684652
            +vn 0.595050 -0.540147 0.595050
            +vn 0.555040 -0.619526 0.555040
            +vn 0.585894 -0.559862 0.585894
            +vn 0.484359 0.249825 0.838404
            +vn 0.420881 -0.539720 0.729026
            +vn 0.392712 -0.619098 0.680013
            +vn 0.414594 -0.559343 0.717765
            +vn 0.250160 0.249763 0.935423
            +vn 0.217322 -0.538713 0.813959
            +vn 0.202887 -0.618030 0.759514
            +vn 0.214148 -0.558184 0.801569
            +vn 0.000000 0.249916 0.968261
            +vn 0.000000 -0.538102 0.842860
            +vn 0.000000 -0.617206 0.786767
            +vn 0.000000 -0.557421 0.830195
            +vn -0.250160 0.249763 0.935423
            +vn -0.217322 -0.538713 0.813959
            +vn -0.202887 -0.618030 0.759514
            +vn -0.214148 -0.558184 0.801569
            +vn -0.484359 0.249825 0.838404
            +vn -0.420881 -0.539720 0.729026
            +vn -0.392712 -0.619098 0.680013
            +vn -0.414594 -0.559343 0.717765
            +vn -0.684652 0.249886 0.684652
            +vn -0.595050 -0.540147 0.595050
            +vn -0.555040 -0.619526 0.555040
            +vn -0.585894 -0.559862 0.585894
            +vn -0.838404 0.249825 0.484359
            +vn -0.729026 -0.539720 0.420881
            +vn -0.680013 -0.619098 0.392712
            +vn -0.717765 -0.559343 0.414594
            +vn -0.935423 0.249763 0.250160
            +vn -0.813959 -0.538713 0.217322
            +vn -0.759484 -0.618030 0.202887
            +vn -0.801569 -0.558184 0.214148
            +vn -0.968261 0.249916 0.000000
            +vn -0.842860 -0.538102 0.000000
            +vn -0.786767 -0.617206 0.000000
            +vn -0.830195 -0.557421 0.000000
            +vn -0.935423 0.249763 -0.250160
            +vn -0.813959 -0.538713 -0.217322
            +vn -0.759484 -0.618030 -0.202887
            +vn -0.801569 -0.558184 -0.214148
            +vn -0.838404 0.249825 -0.484359
            +vn -0.729026 -0.539720 -0.420881
            +vn -0.680013 -0.619098 -0.392712
            +vn -0.717765 -0.559343 -0.414594
            +vn -0.684652 0.249886 -0.684652
            +vn -0.595050 -0.540147 -0.595050
            +vn -0.555040 -0.619526 -0.555040
            +vn -0.585864 -0.559862 -0.585894
            +vn -0.484359 0.249825 -0.838404
            +vn -0.420881 -0.539720 -0.729026
            +vn -0.392712 -0.619098 -0.680013
            +vn -0.414594 -0.559343 -0.717765
            +vn -0.250160 0.249763 -0.935423
            +vn -0.217322 -0.538713 -0.813959
            +vn -0.202887 -0.618030 -0.759484
            +vn -0.214148 -0.558214 -0.801569
            +vn 0.000000 0.249916 -0.968261
            +vn 0.000000 -0.538102 -0.842860
            +vn 0.000000 -0.617206 -0.786767
            +vn 0.000000 -0.557421 -0.830195
            +vn 0.250160 0.249763 -0.935423
            +vn 0.217322 -0.538713 -0.813959
            +vn 0.202887 -0.618030 -0.759484
            +vn 0.214148 -0.558214 -0.801569
            +vn 0.484359 0.249825 -0.838404
            +vn 0.420881 -0.539720 -0.729026
            +vn 0.392712 -0.619098 -0.680013
            +vn 0.414594 -0.559343 -0.717765
            +vn 0.684652 0.249886 -0.684652
            +vn 0.595050 -0.540147 -0.595050
            +vn 0.555040 -0.619526 -0.555040
            +vn 0.585864 -0.559862 -0.585894
            +vn 0.838404 0.249825 -0.484359
            +vn 0.729026 -0.539720 -0.420881
            +vn 0.680013 -0.619098 -0.392712
            +vn 0.717765 -0.559343 -0.414594
            +vn 0.935423 0.249763 -0.250160
            +vn 0.813959 -0.538713 -0.217322
            +vn 0.759484 -0.618030 -0.202887
            +vn 0.801569 -0.558184 -0.214148
            +s 1
            +f 1//1 2//2 3//3
            +f 3//3 2//2 4//4
            +f 4//4 2//2 5//5
            +f 5//5 2//2 6//6
            +f 6//6 2//2 7//7
            +f 7//7 2//2 8//8
            +f 8//8 2//2 9//9
            +f 9//9 2//2 10//10
            +f 10//10 2//2 11//11
            +f 11//11 2//2 12//12
            +f 12//12 2//2 13//13
            +f 13//13 2//2 14//14
            +f 14//14 2//2 15//15
            +f 15//15 2//2 16//16
            +f 16//16 2//2 17//17
            +f 17//17 2//2 18//18
            +f 18//18 2//2 19//19
            +f 19//19 2//2 20//20
            +f 20//20 2//2 21//21
            +f 21//21 2//2 22//22
            +f 22//22 2//2 23//23
            +f 23//23 2//2 24//24
            +f 24//24 2//2 25//25
            +f 2//2 1//1 25//25
            +f 26//26 27//27 28//28
            +f 28//28 29//29 26//26
            +f 29//29 28//28 30//30
            +f 31//31 30//30 28//28
            +f 30//30 31//31 32//32
            +f 33//33 32//32 31//31
            +f 34//34 35//35 33//33
            +f 32//32 33//33 35//35
            +f 36//36 37//37 34//34
            +f 35//35 34//34 37//37
            +f 38//38 39//39 36//36
            +f 37//37 36//36 39//39
            +f 27//27 40//40 41//41
            +f 41//41 28//28 27//27
            +f 28//28 41//41 31//31
            +f 42//42 31//31 41//41
            +f 31//31 42//42 33//33
            +f 43//43 33//33 42//42
            +f 44//44 34//34 43//43
            +f 33//33 43//43 34//34
            +f 45//45 36//36 44//44
            +f 34//34 44//44 36//36
            +f 46//46 38//38 45//45
            +f 36//36 45//45 38//38
            +f 40//40 47//47 48//48
            +f 48//48 41//41 40//40
            +f 41//41 48//48 42//42
            +f 49//49 42//42 48//48
            +f 42//42 49//49 43//43
            +f 50//50 43//43 49//49
            +f 51//51 44//44 50//50
            +f 43//43 50//50 44//44
            +f 52//52 45//45 51//51
            +f 44//44 51//51 45//45
            +f 53//53 46//46 52//52
            +f 45//45 52//52 46//46
            +f 47//47 54//54 48//48
            +f 55//55 48//48 54//54
            +f 48//48 55//55 49//49
            +f 56//56 49//49 55//55
            +f 49//49 56//56 57//57
            +f 57//57 50//50 49//49
            +f 58//58 51//51 50//50
            +f 50//50 57//57 58//58
            +f 59//59 52//52 51//51
            +f 51//51 58//58 59//59
            +f 60//60 53//53 52//52
            +f 52//52 59//59 60//60
            +f 54//54 61//61 55//55
            +f 62//62 55//55 61//61
            +f 55//55 62//62 63//63
            +f 63//63 56//56 55//55
            +f 56//56 63//63 64//64
            +f 64//64 57//57 56//56
            +f 65//65 58//58 57//57
            +f 57//57 64//64 65//65
            +f 66//66 59//59 58//58
            +f 58//58 65//65 66//66
            +f 67//67 60//60 59//59
            +f 59//59 66//66 67//67
            +f 61//61 68//68 62//62
            +f 69//69 62//62 68//68
            +f 62//62 69//69 70//70
            +f 70//70 63//63 62//62
            +f 63//63 70//70 71//71
            +f 71//71 64//64 63//63
            +f 72//72 65//65 64//64
            +f 64//64 71//71 72//72
            +f 73//73 66//66 65//65
            +f 65//65 72//72 73//73
            +f 74//74 67//67 66//66
            +f 66//66 73//73 74//74
            +f 68//68 75//75 76//76
            +f 76//76 69//69 68//68
            +f 69//69 76//76 70//70
            +f 77//77 70//70 76//76
            +f 70//70 77//77 71//71
            +f 78//78 71//71 77//77
            +f 79//79 72//72 78//78
            +f 71//71 78//78 72//72
            +f 80//80 73//73 79//79
            +f 72//72 79//79 73//73
            +f 81//81 74//74 80//80
            +f 73//73 80//80 74//74
            +f 75//75 82//82 83//83
            +f 83//83 76//76 75//75
            +f 76//76 83//83 77//77
            +f 84//84 77//77 83//83
            +f 77//77 84//84 78//78
            +f 85//85 78//78 84//84
            +f 86//86 79//79 85//85
            +f 78//78 85//85 79//79
            +f 87//87 80//80 86//86
            +f 79//79 86//86 80//80
            +f 88//88 81//81 87//87
            +f 80//80 87//87 81//81
            +f 82//82 89//89 90//90
            +f 90//90 83//83 82//82
            +f 83//83 90//90 91//91
            +f 91//91 84//84 83//83
            +f 84//84 91//91 85//85
            +f 92//92 85//85 91//91
            +f 93//93 86//86 92//92
            +f 85//85 92//92 86//86
            +f 94//94 87//87 93//93
            +f 86//86 93//93 87//87
            +f 95//95 88//88 94//94
            +f 87//87 94//94 88//88
            +f 89//89 96//96 90//90
            +f 97//97 90//90 96//96
            +f 90//90 97//97 98//98
            +f 98//98 91//91 90//90
            +f 91//91 98//98 99//99
            +f 99//99 92//92 91//91
            +f 100//100 93//93 92//92
            +f 92//92 99//99 100//100
            +f 101//101 94//94 93//93
            +f 93//93 100//100 101//101
            +f 102//102 95//95 94//94
            +f 94//94 101//101 102//102
            +f 96//96 103//103 97//97
            +f 104//104 97//97 103//103
            +f 97//97 104//104 105//105
            +f 105//105 98//98 97//97
            +f 98//98 105//105 106//106
            +f 106//106 99//99 98//98
            +f 107//107 100//100 99//99
            +f 99//99 106//106 107//107
            +f 108//108 101//101 100//100
            +f 100//100 107//107 108//108
            +f 109//109 102//102 101//101
            +f 101//101 108//108 109//109
            +f 103//103 110//110 104//104
            +f 111//111 104//104 110//110
            +f 104//104 111//111 112//112
            +f 112//112 105//105 104//104
            +f 105//105 112//112 113//113
            +f 113//113 106//106 105//105
            +f 114//114 107//107 106//106
            +f 106//106 113//113 114//114
            +f 115//115 108//108 107//107
            +f 107//107 114//114 115//115
            +f 116//116 109//109 108//108
            +f 108//108 115//115 116//116
            +f 110//110 117//117 118//118
            +f 118//118 111//111 110//110
            +f 111//111 118//118 119//119
            +f 119//119 112//112 111//111
            +f 112//112 119//119 113//113
            +f 120//120 113//113 119//119
            +f 121//121 114//114 120//120
            +f 113//113 120//120 114//114
            +f 122//122 115//115 121//121
            +f 114//114 121//121 115//115
            +f 123//123 116//116 122//122
            +f 115//115 122//122 116//116
            +f 117//117 124//124 125//125
            +f 125//125 118//118 117//117
            +f 118//118 125//125 119//119
            +f 126//126 119//119 125//125
            +f 119//119 126//126 120//120
            +f 127//127 120//120 126//126
            +f 128//128 121//121 127//127
            +f 120//120 127//127 121//121
            +f 129//129 122//122 128//128
            +f 121//121 128//128 122//122
            +f 130//130 123//123 129//129
            +f 122//122 129//129 123//123
            +f 124//124 131//131 132//132
            +f 132//132 125//125 124//124
            +f 125//125 132//132 133//133
            +f 133//133 126//126 125//125
            +f 126//126 133//133 127//127
            +f 134//134 127//127 133//133
            +f 135//135 128//128 134//134
            +f 127//127 134//134 128//128
            +f 136//136 129//129 135//135
            +f 128//128 135//135 129//129
            +f 137//137 130//130 136//136
            +f 129//129 136//136 130//130
            +f 131//131 138//138 132//132
            +f 139//139 132//132 138//138
            +f 132//132 139//139 140//140
            +f 140//140 133//133 132//132
            +f 133//133 140//140 141//141
            +f 141//141 134//134 133//133
            +f 142//142 135//135 134//134
            +f 134//134 141//141 142//142
            +f 143//143 136//136 135//135
            +f 135//135 142//142 143//143
            +f 144//144 137//137 136//136
            +f 136//136 143//143 144//144
            +f 138//138 145//145 139//139
            +f 146//146 139//139 145//145
            +f 139//139 146//146 147//147
            +f 147//147 140//140 139//139
            +f 140//140 147//147 148//148
            +f 148//148 141//141 140//140
            +f 149//149 142//142 141//141
            +f 141//141 148//148 149//149
            +f 150//150 143//143 142//142
            +f 142//142 149//149 150//150
            +f 151//151 144//144 143//143
            +f 143//143 150//150 151//151
            +f 145//145 152//152 146//146
            +f 153//153 146//146 152//152
            +f 146//146 153//153 154//154
            +f 154//154 147//147 146//146
            +f 147//147 154//154 155//155
            +f 155//155 148//148 147//147
            +f 156//156 149//149 148//148
            +f 148//148 155//155 156//156
            +f 157//157 150//150 149//149
            +f 149//149 156//156 157//157
            +f 158//158 151//151 150//150
            +f 150//150 157//157 158//158
            +f 152//152 159//159 160//160
            +f 160//160 153//153 152//152
            +f 153//153 160//160 154//154
            +f 161//161 154//154 160//160
            +f 154//154 161//161 155//155
            +f 162//162 155//155 161//161
            +f 163//163 156//156 162//162
            +f 155//155 162//162 156//156
            +f 164//164 157//157 163//163
            +f 156//156 163//163 157//157
            +f 165//165 158//158 164//164
            +f 157//157 164//164 158//158
            +f 159//159 166//166 167//167
            +f 167//167 160//160 159//159
            +f 160//160 167//167 161//161
            +f 168//168 161//161 167//167
            +f 161//161 168//168 162//162
            +f 169//169 162//162 168//168
            +f 170//170 163//163 169//169
            +f 162//162 169//169 163//163
            +f 171//171 164//164 170//170
            +f 163//163 170//170 164//164
            +f 172//172 165//165 171//171
            +f 164//164 171//171 165//165
            +f 166//166 173//173 174//174
            +f 174//174 167//167 166//166
            +f 167//167 174//174 168//168
            +f 175//175 168//168 174//174
            +f 168//168 175//175 169//169
            +f 176//176 169//169 175//175
            +f 177//177 170//170 176//176
            +f 169//169 176//176 170//170
            +f 178//178 171//171 177//177
            +f 170//170 177//177 171//171
            +f 179//179 172//172 178//178
            +f 171//171 178//178 172//172
            +f 173//173 180//180 174//174
            +f 181//181 174//174 180//180
            +f 174//174 181//181 175//175
            +f 182//182 175//175 181//181
            +f 175//175 182//182 183//183
            +f 183//183 176//176 175//175
            +f 184//184 177//177 176//176
            +f 176//176 183//183 184//184
            +f 185//185 178//178 177//177
            +f 177//177 184//184 185//185
            +f 186//186 179//179 178//178
            +f 178//178 185//185 186//186
            +f 180//180 187//187 181//181
            +f 188//188 181//181 187//187
            +f 181//181 188//188 189//189
            +f 189//189 182//182 181//181
            +f 182//182 189//189 190//190
            +f 190//190 183//183 182//182
            +f 191//191 184//184 183//183
            +f 183//183 190//190 191//191
            +f 192//192 185//185 184//184
            +f 184//184 191//191 192//192
            +f 193//193 186//186 185//185
            +f 185//185 192//192 193//193
            +f 187//187 26//26 188//188
            +f 29//29 188//188 26//26
            +f 188//188 29//29 189//189
            +f 30//30 189//189 29//29
            +f 189//189 30//30 32//32
            +f 32//32 190//190 189//189
            +f 35//35 191//191 190//190
            +f 190//190 32//32 35//35
            +f 37//37 192//192 191//191
            +f 191//191 35//35 37//37
            +f 39//39 193//193 192//192
            +f 192//192 37//37 39//39
            +f 194//194 195//195 38//38
            +f 39//39 38//38 195//195
            +f 196//196 197//197 194//194
            +f 195//195 194//194 197//197
            +f 198//198 199//199 196//196
            +f 197//197 196//196 199//199
            +f 200//200 201//201 198//198
            +f 199//199 198//198 201//201
            +f 202//202 203//203 200//200
            +f 201//201 200//200 203//203
            +f 204//204 205//205 202//202
            +f 203//203 202//202 205//205
            +f 206//206 194//194 46//46
            +f 38//38 46//46 194//194
            +f 207//207 196//196 206//206
            +f 194//194 206//206 196//196
            +f 208//208 198//198 207//207
            +f 196//196 207//207 198//198
            +f 209//209 200//200 208//208
            +f 198//198 208//208 200//200
            +f 210//210 202//202 209//209
            +f 200//200 209//209 202//202
            +f 211//211 204//204 210//210
            +f 202//202 210//210 204//204
            +f 212//212 206//206 53//53
            +f 46//46 53//53 206//206
            +f 213//213 207//207 212//212
            +f 206//206 212//212 207//207
            +f 214//214 208//208 213//213
            +f 207//207 213//213 208//208
            +f 215//215 209//209 214//214
            +f 208//208 214//214 209//209
            +f 216//216 210//210 215//215
            +f 209//209 215//215 210//210
            +f 217//217 211//211 216//216
            +f 210//210 216//216 211//211
            +f 218//218 212//212 53//53
            +f 53//53 60//60 218//218
            +f 219//219 213//213 212//212
            +f 212//212 218//218 219//219
            +f 220//220 214//214 213//213
            +f 213//213 219//219 220//220
            +f 221//221 215//215 214//214
            +f 214//214 220//220 221//221
            +f 222//222 216//216 215//215
            +f 215//215 221//221 222//222
            +f 223//223 217//217 216//216
            +f 216//216 222//222 223//223
            +f 224//224 218//218 60//60
            +f 60//60 67//67 224//224
            +f 225//225 219//219 218//218
            +f 218//218 224//224 225//225
            +f 226//226 220//220 219//219
            +f 219//219 225//225 226//226
            +f 227//227 221//221 220//220
            +f 220//220 226//226 227//227
            +f 228//228 222//222 221//221
            +f 221//221 227//227 228//228
            +f 229//229 223//223 222//222
            +f 222//222 228//228 229//229
            +f 230//230 224//224 67//67
            +f 67//67 74//74 230//230
            +f 231//231 225//225 224//224
            +f 224//224 230//230 231//231
            +f 232//232 226//226 225//225
            +f 225//225 231//231 232//232
            +f 233//233 227//227 226//226
            +f 226//226 232//232 233//233
            +f 234//234 228//228 227//227
            +f 227//227 233//233 234//234
            +f 235//235 229//229 228//228
            +f 228//228 234//234 235//235
            +f 236//236 230//230 81//81
            +f 74//74 81//81 230//230
            +f 237//237 231//231 236//236
            +f 230//230 236//236 231//231
            +f 238//238 232//232 237//237
            +f 231//231 237//237 232//232
            +f 239//239 233//233 238//238
            +f 232//232 238//238 233//233
            +f 240//240 234//234 239//239
            +f 233//233 239//239 234//234
            +f 241//241 235//235 240//240
            +f 234//234 240//240 235//235
            +f 242//242 236//236 88//88
            +f 81//81 88//88 236//236
            +f 243//243 237//237 242//242
            +f 236//236 242//242 237//237
            +f 244//244 238//238 243//243
            +f 237//237 243//243 238//238
            +f 245//245 239//239 244//244
            +f 238//238 244//244 239//239
            +f 246//246 240//240 245//245
            +f 239//239 245//245 240//240
            +f 247//247 241//241 246//246
            +f 240//240 246//246 241//241
            +f 248//248 242//242 95//95
            +f 88//88 95//95 242//242
            +f 249//249 243//243 248//248
            +f 242//242 248//248 243//243
            +f 250//250 244//244 249//249
            +f 243//243 249//249 244//244
            +f 251//251 245//245 250//250
            +f 244//244 250//250 245//245
            +f 252//252 246//246 251//251
            +f 245//245 251//251 246//246
            +f 253//253 247//247 252//252
            +f 246//246 252//252 247//247
            +f 254//254 248//248 95//95
            +f 95//95 102//102 254//254
            +f 255//255 249//249 248//248
            +f 248//248 254//254 255//255
            +f 256//256 250//250 249//249
            +f 249//249 255//255 256//256
            +f 257//257 251//251 250//250
            +f 250//250 256//256 257//257
            +f 258//258 252//252 251//251
            +f 251//251 257//257 258//258
            +f 259//259 253//253 252//252
            +f 252//252 258//258 259//259
            +f 260//260 254//254 102//102
            +f 102//102 109//109 260//260
            +f 261//261 255//255 254//254
            +f 254//254 260//260 261//261
            +f 262//262 256//256 255//255
            +f 255//255 261//261 262//262
            +f 263//263 257//257 256//256
            +f 256//256 262//262 263//263
            +f 264//264 258//258 257//257
            +f 257//257 263//263 264//264
            +f 265//265 259//259 258//258
            +f 258//258 264//264 265//265
            +f 266//266 260//260 109//109
            +f 109//109 116//116 266//266
            +f 267//267 261//261 260//260
            +f 260//260 266//266 267//267
            +f 268//268 262//262 261//261
            +f 261//261 267//267 268//268
            +f 269//269 263//263 262//262
            +f 262//262 268//268 269//269
            +f 270//270 264//264 263//263
            +f 263//263 269//269 270//270
            +f 271//271 265//265 264//264
            +f 264//264 270//270 271//271
            +f 272//272 266//266 123//123
            +f 116//116 123//123 266//266
            +f 273//273 267//267 272//272
            +f 266//266 272//272 267//267
            +f 274//274 268//268 273//273
            +f 267//267 273//273 268//268
            +f 275//275 269//269 274//274
            +f 268//268 274//274 269//269
            +f 276//276 270//270 275//275
            +f 269//269 275//275 270//270
            +f 277//277 271//271 276//276
            +f 270//270 276//276 271//271
            +f 278//278 272//272 130//130
            +f 123//123 130//130 272//272
            +f 279//279 273//273 278//278
            +f 272//272 278//278 273//273
            +f 280//280 274//274 279//279
            +f 273//273 279//279 274//274
            +f 281//281 275//275 280//280
            +f 274//274 280//280 275//275
            +f 282//282 276//276 281//281
            +f 275//275 281//281 276//276
            +f 283//283 277//277 282//282
            +f 276//276 282//282 277//277
            +f 284//284 278//278 137//137
            +f 130//130 137//137 278//278
            +f 285//285 279//279 284//284
            +f 278//278 284//284 279//279
            +f 286//286 280//280 285//285
            +f 279//279 285//285 280//280
            +f 287//287 281//281 286//286
            +f 280//280 286//286 281//281
            +f 288//288 282//282 287//287
            +f 281//281 287//287 282//282
            +f 289//289 283//283 288//288
            +f 282//282 288//288 283//283
            +f 290//290 284//284 137//137
            +f 137//137 144//144 290//290
            +f 291//291 285//285 284//284
            +f 284//284 290//290 291//291
            +f 292//292 286//286 285//285
            +f 285//285 291//291 292//292
            +f 293//293 287//287 286//286
            +f 286//286 292//292 293//293
            +f 294//294 288//288 287//287
            +f 287//287 293//293 294//294
            +f 295//295 289//289 288//288
            +f 288//288 294//294 295//295
            +f 296//296 290//290 144//144
            +f 144//144 151//151 296//296
            +f 297//297 291//291 290//290
            +f 290//290 296//296 297//297
            +f 298//298 292//292 291//291
            +f 291//291 297//297 298//298
            +f 299//299 293//293 292//292
            +f 292//292 298//298 299//299
            +f 300//300 294//294 293//293
            +f 293//293 299//299 300//300
            +f 301//301 295//295 294//294
            +f 294//294 300//300 301//301
            +f 302//302 296//296 151//151
            +f 151//151 158//158 302//302
            +f 303//303 297//297 296//296
            +f 296//296 302//302 303//303
            +f 304//304 298//298 297//297
            +f 297//297 303//303 304//304
            +f 305//305 299//299 298//298
            +f 298//298 304//304 305//305
            +f 306//306 300//300 299//299
            +f 299//299 305//305 306//306
            +f 307//307 301//301 300//300
            +f 300//300 306//306 307//307
            +f 308//308 302//302 165//165
            +f 158//158 165//165 302//302
            +f 309//309 303//303 308//308
            +f 302//302 308//308 303//303
            +f 310//310 304//304 309//309
            +f 303//303 309//309 304//304
            +f 311//311 305//305 310//310
            +f 304//304 310//310 305//305
            +f 312//312 306//306 311//311
            +f 305//305 311//311 306//306
            +f 313//313 307//307 312//312
            +f 306//306 312//312 307//307
            +f 314//314 308//308 172//172
            +f 165//165 172//172 308//308
            +f 315//315 309//309 314//314
            +f 308//308 314//314 309//309
            +f 316//316 310//310 315//315
            +f 309//309 315//315 310//310
            +f 317//317 311//311 316//316
            +f 310//310 316//316 311//311
            +f 318//318 312//312 317//317
            +f 311//311 317//317 312//312
            +f 319//319 313//313 318//318
            +f 312//312 318//318 313//313
            +f 320//320 314//314 179//179
            +f 172//172 179//179 314//314
            +f 321//321 315//315 320//320
            +f 314//314 320//320 315//315
            +f 322//322 316//316 321//321
            +f 315//315 321//321 316//316
            +f 323//323 317//317 322//322
            +f 316//316 322//322 317//317
            +f 324//324 318//318 323//323
            +f 317//317 323//323 318//318
            +f 325//325 319//319 324//324
            +f 318//318 324//324 319//319
            +f 326//326 320//320 179//179
            +f 179//179 186//186 326//326
            +f 327//327 321//321 320//320
            +f 320//320 326//326 327//327
            +f 328//328 322//322 321//321
            +f 321//321 327//327 328//328
            +f 329//329 323//323 322//322
            +f 322//322 328//328 329//329
            +f 330//330 324//324 323//323
            +f 323//323 329//329 330//330
            +f 331//331 325//325 324//324
            +f 324//324 330//330 331//331
            +f 332//332 326//326 186//186
            +f 186//186 193//193 332//332
            +f 333//333 327//327 326//326
            +f 326//326 332//332 333//333
            +f 334//334 328//328 327//327
            +f 327//327 333//333 334//334
            +f 335//335 329//329 328//328
            +f 328//328 334//334 335//335
            +f 336//336 330//330 329//329
            +f 329//329 335//335 336//336
            +f 337//337 331//331 330//330
            +f 330//330 336//336 337//337
            +f 195//195 332//332 193//193
            +f 193//193 39//39 195//195
            +f 197//197 333//333 332//332
            +f 332//332 195//195 197//197
            +f 199//199 334//334 333//333
            +f 333//333 197//197 199//199
            +f 201//201 335//335 334//334
            +f 334//334 199//199 201//201
            +f 203//203 336//336 335//335
            +f 335//335 201//201 203//203
            +f 205//205 337//337 336//336
            +f 336//336 203//203 205//205
            +f 338//338 339//339 205//205
            +f 205//205 204//204 338//338
            +f 340//340 341//341 339//339
            +f 339//339 338//338 340//340
            +f 342//342 343//343 341//341
            +f 341//341 340//340 342//342
            +f 344//344 345//345 343//343
            +f 343//343 342//342 344//344
            +f 346//346 347//347 345//345
            +f 345//345 344//344 346//346
            +f 348//348 349//349 347//347
            +f 347//347 346//346 348//348
            +f 350//350 338//338 204//204
            +f 204//204 211//211 350//350
            +f 351//351 340//340 338//338
            +f 338//338 350//350 351//351
            +f 352//352 342//342 340//340
            +f 340//340 351//351 352//352
            +f 353//353 344//344 342//342
            +f 342//342 352//352 353//353
            +f 354//354 346//346 344//344
            +f 344//344 353//353 354//354
            +f 355//355 348//348 346//346
            +f 346//346 354//354 355//355
            +f 356//356 350//350 211//211
            +f 211//211 217//217 356//356
            +f 357//357 351//351 350//350
            +f 350//350 356//356 357//357
            +f 358//358 352//352 351//351
            +f 351//351 357//357 358//358
            +f 359//359 353//353 352//352
            +f 352//352 358//358 359//359
            +f 360//360 354//354 353//353
            +f 353//353 359//359 360//360
            +f 361//361 355//355 354//354
            +f 354//354 360//360 361//361
            +f 362//362 356//356 223//223
            +f 217//217 223//223 356//356
            +f 363//363 357//357 362//362
            +f 356//356 362//362 357//357
            +f 364//364 358//358 363//363
            +f 357//357 363//363 358//358
            +f 365//365 359//359 364//364
            +f 358//358 364//364 359//359
            +f 366//366 360//360 365//365
            +f 359//359 365//365 360//360
            +f 367//367 361//361 366//366
            +f 360//360 366//366 361//361
            +f 368//368 362//362 229//229
            +f 223//223 229//229 362//362
            +f 369//369 363//363 368//368
            +f 362//362 368//368 363//363
            +f 370//370 364//364 369//369
            +f 363//363 369//369 364//364
            +f 371//371 365//365 370//370
            +f 364//364 370//370 365//365
            +f 372//372 366//366 371//371
            +f 365//365 371//371 366//366
            +f 373//373 367//367 372//372
            +f 366//366 372//372 367//367
            +f 374//374 368//368 235//235
            +f 229//229 235//235 368//368
            +f 375//375 369//369 374//374
            +f 368//368 374//374 369//369
            +f 376//376 370//370 375//375
            +f 369//369 375//375 370//370
            +f 377//377 371//371 376//376
            +f 370//370 376//376 371//371
            +f 378//378 372//372 377//377
            +f 371//371 377//377 372//372
            +f 379//379 373//373 378//378
            +f 372//372 378//378 373//373
            +f 380//380 374//374 235//235
            +f 235//235 241//241 380//380
            +f 381//381 375//375 374//374
            +f 374//374 380//380 381//381
            +f 382//382 376//376 375//375
            +f 375//375 381//381 382//382
            +f 383//383 377//377 376//376
            +f 376//376 382//382 383//383
            +f 384//384 378//378 377//377
            +f 377//377 383//383 384//384
            +f 385//385 379//379 378//378
            +f 378//378 384//384 385//385
            +f 386//386 380//380 241//241
            +f 241//241 247//247 386//386
            +f 387//387 381//381 380//380
            +f 380//380 386//386 387//387
            +f 388//388 382//382 381//381
            +f 381//381 387//387 388//388
            +f 389//389 383//383 382//382
            +f 382//382 388//388 389//389
            +f 390//390 384//384 383//383
            +f 383//383 389//389 390//390
            +f 391//391 385//385 384//384
            +f 384//384 390//390 391//391
            +f 392//392 386//386 247//247
            +f 247//247 253//253 392//392
            +f 393//393 387//387 386//386
            +f 386//386 392//392 393//393
            +f 394//394 388//388 387//387
            +f 387//387 393//393 394//394
            +f 395//395 389//389 388//388
            +f 388//388 394//394 395//395
            +f 396//396 390//390 389//389
            +f 389//389 395//395 396//396
            +f 397//397 391//391 390//390
            +f 390//390 396//396 397//397
            +f 398//398 392//392 259//259
            +f 253//253 259//259 392//392
            +f 399//399 393//393 398//398
            +f 392//392 398//398 393//393
            +f 400//400 394//394 399//399
            +f 393//393 399//399 394//394
            +f 401//401 395//395 400//400
            +f 394//394 400//400 395//395
            +f 402//402 396//396 401//401
            +f 395//395 401//401 396//396
            +f 403//403 397//397 402//402
            +f 396//396 402//402 397//397
            +f 404//404 398//398 265//265
            +f 259//259 265//265 398//398
            +f 405//405 399//399 404//404
            +f 398//398 404//404 399//399
            +f 406//406 400//400 405//405
            +f 399//399 405//405 400//400
            +f 407//407 401//401 406//406
            +f 400//400 406//406 401//401
            +f 408//408 402//402 407//407
            +f 401//401 407//407 402//402
            +f 409//409 403//403 408//408
            +f 402//402 408//408 403//403
            +f 410//410 404//404 271//271
            +f 265//265 271//271 404//404
            +f 411//411 405//405 410//410
            +f 404//404 410//410 405//405
            +f 412//412 406//406 411//411
            +f 405//405 411//411 406//406
            +f 413//413 407//407 412//412
            +f 406//406 412//412 407//407
            +f 414//414 408//408 413//413
            +f 407//407 413//413 408//408
            +f 415//415 409//409 414//414
            +f 408//408 414//414 409//409
            +f 416//416 410//410 271//271
            +f 271//271 277//277 416//416
            +f 417//417 411//411 410//410
            +f 410//410 416//416 417//417
            +f 418//418 412//412 411//411
            +f 411//411 417//417 418//418
            +f 419//419 413//413 412//412
            +f 412//412 418//418 419//419
            +f 420//420 414//414 413//413
            +f 413//413 419//419 420//420
            +f 421//421 415//415 414//414
            +f 414//414 420//420 421//421
            +f 422//422 416//416 277//277
            +f 277//277 283//283 422//422
            +f 423//423 417//417 416//416
            +f 416//416 422//422 423//423
            +f 424//424 418//418 417//417
            +f 417//417 423//423 424//424
            +f 425//425 419//419 418//418
            +f 418//418 424//424 425//425
            +f 426//426 420//420 419//419
            +f 419//419 425//425 426//426
            +f 427//427 421//421 420//420
            +f 420//420 426//426 427//427
            +f 428//428 422//422 283//283
            +f 283//283 289//289 428//428
            +f 429//429 423//423 422//422
            +f 422//422 428//428 429//429
            +f 430//430 424//424 423//423
            +f 423//423 429//429 430//430
            +f 431//431 425//425 424//424
            +f 424//424 430//430 431//431
            +f 432//432 426//426 425//425
            +f 425//425 431//431 432//432
            +f 433//433 427//427 426//426
            +f 426//426 432//432 433//433
            +f 434//434 428//428 295//295
            +f 289//289 295//295 428//428
            +f 435//435 429//429 434//434
            +f 428//428 434//434 429//429
            +f 436//436 430//430 435//435
            +f 429//429 435//435 430//430
            +f 437//437 431//431 436//436
            +f 430//430 436//436 431//431
            +f 438//438 432//432 437//437
            +f 431//431 437//437 432//432
            +f 439//439 433//433 438//438
            +f 432//432 438//438 433//433
            +f 440//440 434//434 301//301
            +f 295//295 301//301 434//434
            +f 441//441 435//435 440//440
            +f 434//434 440//440 435//435
            +f 442//442 436//436 441//441
            +f 435//435 441//441 436//436
            +f 443//443 437//437 442//442
            +f 436//436 442//442 437//437
            +f 444//444 438//438 443//443
            +f 437//437 443//443 438//438
            +f 445//445 439//439 444//444
            +f 438//438 444//444 439//439
            +f 446//446 440//440 307//307
            +f 301//301 307//307 440//440
            +f 447//447 441//441 446//446
            +f 440//440 446//446 441//441
            +f 448//448 442//442 447//447
            +f 441//441 447//447 442//442
            +f 449//449 443//443 448//448
            +f 442//442 448//448 443//443
            +f 450//450 444//444 449//449
            +f 443//443 449//449 444//444
            +f 451//451 445//445 450//450
            +f 444//444 450//450 445//445
            +f 452//452 446//446 307//307
            +f 307//307 313//313 452//452
            +f 453//453 447//447 446//446
            +f 446//446 452//452 453//453
            +f 454//454 448//448 447//447
            +f 447//447 453//453 454//454
            +f 455//455 449//449 448//448
            +f 448//448 454//454 455//455
            +f 456//456 450//450 449//449
            +f 449//449 455//455 456//456
            +f 457//457 451//451 450//450
            +f 450//450 456//456 457//457
            +f 458//458 452//452 313//313
            +f 313//313 319//319 458//458
            +f 459//459 453//453 452//452
            +f 452//452 458//458 459//459
            +f 460//460 454//454 453//453
            +f 453//453 459//459 460//460
            +f 461//461 455//455 454//454
            +f 454//454 460//460 461//461
            +f 462//462 456//456 455//455
            +f 455//455 461//461 462//462
            +f 463//463 457//457 456//456
            +f 456//456 462//462 463//463
            +f 464//464 458//458 319//319
            +f 319//319 325//325 464//464
            +f 465//465 459//459 458//458
            +f 458//458 464//464 465//465
            +f 466//466 460//460 459//459
            +f 459//459 465//465 466//466
            +f 467//467 461//461 460//460
            +f 460//460 466//466 467//467
            +f 468//468 462//462 461//461
            +f 461//461 467//467 468//468
            +f 469//469 463//463 462//462
            +f 462//462 468//468 469//469
            +f 470//470 464//464 331//331
            +f 325//325 331//331 464//464
            +f 471//471 465//465 470//470
            +f 464//464 470//470 465//465
            +f 472//472 466//466 471//471
            +f 465//465 471//471 466//466
            +f 473//473 467//467 472//472
            +f 466//466 472//472 467//467
            +f 474//474 468//468 473//473
            +f 467//467 473//473 468//468
            +f 475//475 469//469 474//474
            +f 468//468 474//474 469//469
            +f 476//476 470//470 337//337
            +f 331//331 337//337 470//470
            +f 477//477 471//471 476//476
            +f 470//470 476//476 471//471
            +f 478//478 472//472 477//477
            +f 471//471 477//477 472//472
            +f 479//479 473//473 478//478
            +f 472//472 478//478 473//473
            +f 480//480 474//474 479//479
            +f 473//473 479//479 474//474
            +f 481//481 475//475 480//480
            +f 474//474 480//480 475//475
            +f 339//339 476//476 205//205
            +f 337//337 205//205 476//476
            +f 341//341 477//477 339//339
            +f 476//476 339//339 477//477
            +f 343//343 478//478 341//341
            +f 477//477 341//341 478//478
            +f 345//345 479//479 343//343
            +f 478//478 343//343 479//479
            +f 347//347 480//480 345//345
            +f 479//479 345//345 480//480
            +f 349//349 481//481 347//347
            +f 480//480 347//347 481//481
            +f 1//1 3//3 482//482
            +f 483//483 482//482 3//3
            +f 482//482 483//483 484//484
            +f 485//485 484//484 483//483
            +f 484//484 485//485 486//486
            +f 487//487 486//486 485//485
            +f 486//486 487//487 488//488
            +f 489//489 488//488 487//487
            +f 488//488 489//489 349//349
            +f 481//481 349//349 489//489
            +f 3//3 4//4 483//483
            +f 490//490 483//483 4//4
            +f 483//483 490//490 485//485
            +f 491//491 485//485 490//490
            +f 485//485 491//491 487//487
            +f 492//492 487//487 491//491
            +f 487//487 492//492 489//489
            +f 493//493 489//489 492//492
            +f 489//489 493//493 481//481
            +f 475//475 481//481 493//493
            +f 4//4 5//5 490//490
            +f 494//494 490//490 5//5
            +f 490//490 494//494 491//491
            +f 495//495 491//491 494//494
            +f 491//491 495//495 492//492
            +f 496//496 492//492 495//495
            +f 492//492 496//496 493//493
            +f 497//497 493//493 496//496
            +f 493//493 497//497 475//475
            +f 469//469 475//475 497//497
            +f 5//5 6//6 498//498
            +f 498//498 494//494 5//5
            +f 494//494 498//498 499//499
            +f 499//499 495//495 494//494
            +f 495//495 499//499 500//500
            +f 500//500 496//496 495//495
            +f 496//496 500//500 501//501
            +f 501//501 497//497 496//496
            +f 497//497 501//501 463//463
            +f 463//463 469//469 497//497
            +f 6//6 7//7 502//502
            +f 502//502 498//498 6//6
            +f 498//498 502//502 503//503
            +f 503//503 499//499 498//498
            +f 499//499 503//503 504//504
            +f 504//504 500//500 499//499
            +f 500//500 504//504 505//505
            +f 505//505 501//501 500//500
            +f 501//501 505//505 457//457
            +f 457//457 463//463 501//501
            +f 7//7 8//8 506//506
            +f 506//506 502//502 7//7
            +f 502//502 506//506 507//507
            +f 507//507 503//503 502//502
            +f 503//503 507//507 508//508
            +f 508//508 504//504 503//503
            +f 504//504 508//508 509//509
            +f 509//509 505//505 504//504
            +f 505//505 509//509 451//451
            +f 451//451 457//457 505//505
            +f 8//8 9//9 506//506
            +f 510//510 506//506 9//9
            +f 506//506 510//510 507//507
            +f 511//511 507//507 510//510
            +f 507//507 511//511 508//508
            +f 512//512 508//508 511//511
            +f 508//508 512//512 509//509
            +f 513//513 509//509 512//512
            +f 509//509 513//513 451//451
            +f 445//445 451//451 513//513
            +f 9//9 10//10 510//510
            +f 514//514 510//510 10//10
            +f 510//510 514//514 511//511
            +f 515//515 511//511 514//514
            +f 511//511 515//515 512//512
            +f 516//516 512//512 515//515
            +f 512//512 516//516 513//513
            +f 517//517 513//513 516//516
            +f 513//513 517//517 445//445
            +f 439//439 445//445 517//517
            +f 10//10 11//11 514//514
            +f 518//518 514//514 11//11
            +f 514//514 518//518 515//515
            +f 519//519 515//515 518//518
            +f 515//515 519//519 516//516
            +f 520//520 516//516 519//519
            +f 516//516 520//520 517//517
            +f 521//521 517//517 520//520
            +f 517//517 521//521 439//439
            +f 433//433 439//439 521//521
            +f 11//11 12//12 522//522
            +f 522//522 518//518 11//11
            +f 518//518 522//522 523//523
            +f 523//523 519//519 518//518
            +f 519//519 523//523 524//524
            +f 524//524 520//520 519//519
            +f 520//520 524//524 525//525
            +f 525//525 521//521 520//520
            +f 521//521 525//525 427//427
            +f 427//427 433//433 521//521
            +f 12//12 13//13 526//526
            +f 526//526 522//522 12//12
            +f 522//522 526//526 527//527
            +f 527//527 523//523 522//522
            +f 523//523 527//527 528//528
            +f 528//528 524//524 523//523
            +f 524//524 528//528 529//529
            +f 529//529 525//525 524//524
            +f 525//525 529//529 421//421
            +f 421//421 427//427 525//525
            +f 13//13 14//14 530//530
            +f 530//530 526//526 13//13
            +f 526//526 530//530 531//531
            +f 531//531 527//527 526//526
            +f 527//527 531//531 532//532
            +f 532//532 528//528 527//527
            +f 528//528 532//532 533//533
            +f 533//533 529//529 528//528
            +f 529//529 533//533 415//415
            +f 415//415 421//421 529//529
            +f 14//14 15//15 530//530
            +f 534//534 530//530 15//15
            +f 530//530 534//534 531//531
            +f 535//535 531//531 534//534
            +f 531//531 535//535 532//532
            +f 536//536 532//532 535//535
            +f 532//532 536//536 533//533
            +f 537//537 533//533 536//536
            +f 533//533 537//537 415//415
            +f 409//409 415//415 537//537
            +f 15//15 16//16 534//534
            +f 538//538 534//534 16//16
            +f 534//534 538//538 535//535
            +f 539//539 535//535 538//538
            +f 535//535 539//539 536//536
            +f 540//540 536//536 539//539
            +f 536//536 540//540 537//537
            +f 541//541 537//537 540//540
            +f 537//537 541//541 409//409
            +f 403//403 409//409 541//541
            +f 16//16 17//17 538//538
            +f 542//542 538//538 17//17
            +f 538//538 542//542 539//539
            +f 543//543 539//539 542//542
            +f 539//539 543//543 540//540
            +f 544//544 540//540 543//543
            +f 540//540 544//544 541//541
            +f 545//545 541//541 544//544
            +f 541//541 545//545 403//403
            +f 397//397 403//403 545//545
            +f 17//17 18//18 546//546
            +f 546//546 542//542 17//17
            +f 542//542 546//546 547//547
            +f 547//547 543//543 542//542
            +f 543//543 547//547 548//548
            +f 548//548 544//544 543//543
            +f 544//544 548//548 549//549
            +f 549//549 545//545 544//544
            +f 545//545 549//549 391//391
            +f 391//391 397//397 545//545
            +f 18//18 19//19 550//550
            +f 550//550 546//546 18//18
            +f 546//546 550//550 551//551
            +f 551//551 547//547 546//546
            +f 547//547 551//551 552//552
            +f 552//552 548//548 547//547
            +f 548//548 552//552 553//553
            +f 553//553 549//549 548//548
            +f 549//549 553//553 385//385
            +f 385//385 391//391 549//549
            +f 19//19 20//20 554//554
            +f 554//554 550//550 19//19
            +f 550//550 554//554 555//555
            +f 555//555 551//551 550//550
            +f 551//551 555//555 556//556
            +f 556//556 552//552 551//551
            +f 552//552 556//556 557//557
            +f 557//557 553//553 552//552
            +f 553//553 557//557 379//379
            +f 379//379 385//385 553//553
            +f 20//20 21//21 554//554
            +f 558//558 554//554 21//21
            +f 554//554 558//558 555//555
            +f 559//559 555//555 558//558
            +f 555//555 559//559 556//556
            +f 560//560 556//556 559//559
            +f 556//556 560//560 557//557
            +f 561//561 557//557 560//560
            +f 557//557 561//561 379//379
            +f 373//373 379//379 561//561
            +f 21//21 22//22 558//558
            +f 562//562 558//558 22//22
            +f 558//558 562//562 559//559
            +f 563//563 559//559 562//562
            +f 559//559 563//563 560//560
            +f 564//564 560//560 563//563
            +f 560//560 564//564 561//561
            +f 565//565 561//561 564//564
            +f 561//561 565//565 373//373
            +f 367//367 373//373 565//565
            +f 22//22 23//23 562//562
            +f 566//566 562//562 23//23
            +f 562//562 566//566 563//563
            +f 567//567 563//563 566//566
            +f 563//563 567//567 564//564
            +f 568//568 564//564 567//567
            +f 564//564 568//568 565//565
            +f 569//569 565//565 568//568
            +f 565//565 569//569 367//367
            +f 361//361 367//367 569//569
            +f 23//23 24//24 570//570
            +f 570//570 566//566 23//23
            +f 566//566 570//570 571//571
            +f 571//571 567//567 566//566
            +f 567//567 571//571 572//572
            +f 572//572 568//568 567//567
            +f 568//568 572//572 573//573
            +f 573//573 569//569 568//568
            +f 569//569 573//573 355//355
            +f 355//355 361//361 569//569
            +f 24//24 25//25 574//574
            +f 574//574 570//570 24//24
            +f 570//570 574//574 575//575
            +f 575//575 571//571 570//570
            +f 571//571 575//575 576//576
            +f 576//576 572//572 571//571
            +f 572//572 576//576 577//577
            +f 577//577 573//573 572//572
            +f 573//573 577//577 348//348
            +f 348//348 355//355 573//573
            +f 25//25 1//1 482//482
            +f 482//482 574//574 25//25
            +f 574//574 482//482 484//484
            +f 484//484 575//575 574//574
            +f 575//575 484//484 486//486
            +f 486//486 576//576 575//575
            +f 576//576 486//486 488//488
            +f 488//488 577//577 576//576
            +f 577//577 488//488 349//349
            +f 349//349 348//348 577//577
            +f 578//578 579//579 580//580
            +f 581//581 580//580 579//579
            +f 582//582 578//578 583//583
            +f 580//580 583//583 578//578
            +f 584//584 582//582 585//585
            +f 583//583 585//585 582//582
            +f 586//586 584//584 585//585
            +f 585//585 587//587 586//586
            +f 588//588 586//586 587//587
            +f 587//587 589//589 588//588
            +f 590//590 588//588 589//589
            +f 589//589 591//591 590//590
            +f 592//592 590//590 593//593
            +f 591//591 593//593 590//590
            +f 594//594 592//592 595//595
            +f 593//593 595//595 592//592
            +f 596//596 594//594 597//597
            +f 595//595 597//597 594//594
            +f 598//598 596//596 597//597
            +f 597//597 599//599 598//598
            +f 600//600 598//598 599//599
            +f 599//599 601//601 600//600
            +f 602//602 600//600 601//601
            +f 601//601 603//603 602//602
            +f 604//604 602//602 605//605
            +f 603//603 605//605 602//602
            +f 606//606 604//604 607//607
            +f 605//605 607//607 604//604
            +f 608//608 606//606 609//609
            +f 607//607 609//609 606//606
            +f 610//610 608//608 609//609
            +f 609//609 611//611 610//610
            +f 612//612 610//610 611//611
            +f 611//611 613//613 612//612
            +f 614//614 612//612 613//613
            +f 613//613 615//615 614//614
            +f 616//616 614//614 617//617
            +f 615//615 617//617 614//614
            +f 618//618 616//616 619//619
            +f 617//617 619//619 616//616
            +f 620//620 618//618 621//621
            +f 619//619 621//621 618//618
            +f 622//622 620//620 621//621
            +f 621//621 623//623 622//622
            +f 624//624 622//622 623//623
            +f 623//623 625//625 624//624
            +f 579//579 624//624 625//625
            +f 625//625 581//581 579//579
            +f 626//626 627//627 578//578
            +f 579//579 578//578 627//627
            +f 628//628 629//629 626//626
            +f 627//627 626//626 629//629
            +f 630//630 631//631 628//628
            +f 629//629 628//628 631//631
            +f 632//632 633//633 630//630
            +f 631//631 630//630 633//633
            +f 634//634 635//635 632//632
            +f 633//633 632//632 635//635
            +f 636//636 637//637 634//634
            +f 635//635 634//634 637//637
            +f 638//638 626//626 582//582
            +f 578//578 582//582 626//626
            +f 639//639 628//628 638//638
            +f 626//626 638//638 628//628
            +f 640//640 630//630 639//639
            +f 628//628 639//639 630//630
            +f 641//641 632//632 640//640
            +f 630//630 640//640 632//632
            +f 642//642 634//634 641//641
            +f 632//632 641//641 634//634
            +f 643//643 636//636 642//642
            +f 634//634 642//642 636//636
            +f 644//644 638//638 584//584
            +f 582//582 584//584 638//638
            +f 645//645 639//639 644//644
            +f 638//638 644//644 639//639
            +f 646//646 640//640 645//645
            +f 639//639 645//645 640//640
            +f 647//647 641//641 646//646
            +f 640//640 646//646 641//641
            +f 648//648 642//642 647//647
            +f 641//641 647//647 642//642
            +f 649//649 643//643 648//648
            +f 642//642 648//648 643//643
            +f 650//650 644//644 584//584
            +f 584//584 586//586 650//650
            +f 651//651 645//645 644//644
            +f 644//644 650//650 651//651
            +f 652//652 646//646 645//645
            +f 645//645 651//651 652//652
            +f 653//653 647//647 646//646
            +f 646//646 652//652 653//653
            +f 654//654 648//648 647//647
            +f 647//647 653//653 654//654
            +f 655//655 649//649 648//648
            +f 648//648 654//654 655//655
            +f 656//656 650//650 586//586
            +f 586//586 588//588 656//656
            +f 657//657 651//651 650//650
            +f 650//650 656//656 657//657
            +f 658//658 652//652 651//651
            +f 651//651 657//657 658//658
            +f 659//659 653//653 652//652
            +f 652//652 658//658 659//659
            +f 660//660 654//654 653//653
            +f 653//653 659//659 660//660
            +f 661//661 655//655 654//654
            +f 654//654 660//660 661//661
            +f 662//662 656//656 588//588
            +f 588//588 590//590 662//662
            +f 663//663 657//657 656//656
            +f 656//656 662//662 663//663
            +f 664//664 658//658 657//657
            +f 657//657 663//663 664//664
            +f 665//665 659//659 658//658
            +f 658//658 664//664 665//665
            +f 666//666 660//660 659//659
            +f 659//659 665//665 666//666
            +f 667//667 661//661 660//660
            +f 660//660 666//666 667//667
            +f 668//668 662//662 592//592
            +f 590//590 592//592 662//662
            +f 669//669 663//663 668//668
            +f 662//662 668//668 663//663
            +f 670//670 664//664 669//669
            +f 663//663 669//669 664//664
            +f 671//671 665//665 670//670
            +f 664//664 670//670 665//665
            +f 672//672 666//666 671//671
            +f 665//665 671//671 666//666
            +f 673//673 667//667 672//672
            +f 666//666 672//672 667//667
            +f 674//674 668//668 594//594
            +f 592//592 594//594 668//668
            +f 675//675 669//669 674//674
            +f 668//668 674//674 669//669
            +f 676//676 670//670 675//675
            +f 669//669 675//675 670//670
            +f 677//677 671//671 676//676
            +f 670//670 676//676 671//671
            +f 678//678 672//672 677//677
            +f 671//671 677//677 672//672
            +f 679//679 673//673 678//678
            +f 672//672 678//678 673//673
            +f 680//680 674//674 596//596
            +f 594//594 596//596 674//674
            +f 681//681 675//675 680//680
            +f 674//674 680//680 675//675
            +f 682//682 676//676 681//681
            +f 675//675 681//681 676//676
            +f 683//683 677//677 682//682
            +f 676//676 682//682 677//677
            +f 684//684 678//678 683//683
            +f 677//677 683//683 678//678
            +f 685//685 679//679 684//684
            +f 678//678 684//684 679//679
            +f 686//686 680//680 596//596
            +f 596//596 598//598 686//686
            +f 687//687 681//681 680//680
            +f 680//680 686//686 687//687
            +f 688//688 682//682 681//681
            +f 681//681 687//687 688//688
            +f 689//689 683//683 682//682
            +f 682//682 688//688 689//689
            +f 690//690 684//684 683//683
            +f 683//683 689//689 690//690
            +f 691//691 685//685 684//684
            +f 684//684 690//690 691//691
            +f 692//692 686//686 598//598
            +f 598//598 600//600 692//692
            +f 693//693 687//687 686//686
            +f 686//686 692//692 693//693
            +f 694//694 688//688 687//687
            +f 687//687 693//693 694//694
            +f 695//695 689//689 688//688
            +f 688//688 694//694 695//695
            +f 696//696 690//690 689//689
            +f 689//689 695//695 696//696
            +f 697//697 691//691 690//690
            +f 690//690 696//696 697//697
            +f 698//698 692//692 600//600
            +f 600//600 602//602 698//698
            +f 699//699 693//693 692//692
            +f 692//692 698//698 699//699
            +f 700//700 694//694 693//693
            +f 693//693 699//699 700//700
            +f 701//701 695//695 694//694
            +f 694//694 700//700 701//701
            +f 702//702 696//696 695//695
            +f 695//695 701//701 702//702
            +f 703//703 697//697 696//696
            +f 696//696 702//702 703//703
            +f 704//704 698//698 604//604
            +f 602//602 604//604 698//698
            +f 705//705 699//699 704//704
            +f 698//698 704//704 699//699
            +f 706//706 700//700 705//705
            +f 699//699 705//705 700//700
            +f 707//707 701//701 706//706
            +f 700//700 706//706 701//701
            +f 708//708 702//702 707//707
            +f 701//701 707//707 702//702
            +f 709//709 703//703 708//708
            +f 702//702 708//708 703//703
            +f 710//710 704//704 606//606
            +f 604//604 606//606 704//704
            +f 711//711 705//705 710//710
            +f 704//704 710//710 705//705
            +f 712//712 706//706 711//711
            +f 705//705 711//711 706//706
            +f 713//713 707//707 712//712
            +f 706//706 712//712 707//707
            +f 714//714 708//708 713//713
            +f 707//707 713//713 708//708
            +f 715//715 709//709 714//714
            +f 708//708 714//714 709//709
            +f 716//716 710//710 608//608
            +f 606//606 608//608 710//710
            +f 717//717 711//711 716//716
            +f 710//710 716//716 711//711
            +f 718//718 712//712 717//717
            +f 711//711 717//717 712//712
            +f 719//719 713//713 718//718
            +f 712//712 718//718 713//713
            +f 720//720 714//714 719//719
            +f 713//713 719//719 714//714
            +f 721//721 715//715 720//720
            +f 714//714 720//720 715//715
            +f 722//722 716//716 608//608
            +f 608//608 610//610 722//722
            +f 723//723 717//717 716//716
            +f 716//716 722//722 723//723
            +f 724//724 718//718 717//717
            +f 717//717 723//723 724//724
            +f 725//725 719//719 718//718
            +f 718//718 724//724 725//725
            +f 726//726 720//720 719//719
            +f 719//719 725//725 726//726
            +f 727//727 721//721 720//720
            +f 720//720 726//726 727//727
            +f 728//728 722//722 610//610
            +f 610//610 612//612 728//728
            +f 729//729 723//723 722//722
            +f 722//722 728//728 729//729
            +f 730//730 724//724 723//723
            +f 723//723 729//729 730//730
            +f 731//731 725//725 724//724
            +f 724//724 730//730 731//731
            +f 732//732 726//726 725//725
            +f 725//725 731//731 732//732
            +f 733//733 727//727 726//726
            +f 726//726 732//732 733//733
            +f 734//734 728//728 612//612
            +f 612//612 614//614 734//734
            +f 735//735 729//729 728//728
            +f 728//728 734//734 735//735
            +f 736//736 730//730 729//729
            +f 729//729 735//735 736//736
            +f 737//737 731//731 730//730
            +f 730//730 736//736 737//737
            +f 738//738 732//732 731//731
            +f 731//731 737//737 738//738
            +f 739//739 733//733 732//732
            +f 732//732 738//738 739//739
            +f 740//740 734//734 616//616
            +f 614//614 616//616 734//734
            +f 741//741 735//735 740//740
            +f 734//734 740//740 735//735
            +f 742//742 736//736 741//741
            +f 735//735 741//741 736//736
            +f 743//743 737//737 742//742
            +f 736//736 742//742 737//737
            +f 744//744 738//738 743//743
            +f 737//737 743//743 738//738
            +f 745//745 739//739 744//744
            +f 738//738 744//744 739//739
            +f 746//746 740//740 618//618
            +f 616//616 618//618 740//740
            +f 747//747 741//741 746//746
            +f 740//740 746//746 741//741
            +f 748//748 742//742 747//747
            +f 741//741 747//747 742//742
            +f 749//749 743//743 748//748
            +f 742//742 748//748 743//743
            +f 750//750 744//744 749//749
            +f 743//743 749//749 744//744
            +f 751//751 745//745 750//750
            +f 744//744 750//750 745//745
            +f 752//752 746//746 620//620
            +f 618//618 620//620 746//746
            +f 753//753 747//747 752//752
            +f 746//746 752//752 747//747
            +f 754//754 748//748 753//753
            +f 747//747 753//753 748//748
            +f 755//755 749//749 754//754
            +f 748//748 754//754 749//749
            +f 756//756 750//750 755//755
            +f 749//749 755//755 750//750
            +f 757//757 751//751 756//756
            +f 750//750 756//756 751//751
            +f 758//758 752//752 620//620
            +f 620//620 622//622 758//758
            +f 759//759 753//753 752//752
            +f 752//752 758//758 759//759
            +f 760//760 754//754 753//753
            +f 753//753 759//759 760//760
            +f 761//761 755//755 754//754
            +f 754//754 760//760 761//761
            +f 762//762 756//756 755//755
            +f 755//755 761//761 762//762
            +f 763//763 757//757 756//756
            +f 756//756 762//762 763//763
            +f 764//764 758//758 622//622
            +f 622//622 624//624 764//764
            +f 765//765 759//759 758//758
            +f 758//758 764//764 765//765
            +f 766//766 760//760 759//759
            +f 759//759 765//765 766//766
            +f 767//767 761//761 760//760
            +f 760//760 766//766 767//767
            +f 768//768 762//762 761//761
            +f 761//761 767//767 768//768
            +f 769//769 763//763 762//762
            +f 762//762 768//768 769//769
            +f 627//627 764//764 624//624
            +f 624//624 579//579 627//627
            +f 629//629 765//765 764//764
            +f 764//764 627//627 629//629
            +f 631//631 766//766 765//765
            +f 765//765 629//629 631//631
            +f 633//633 767//767 766//766
            +f 766//766 631//631 633//633
            +f 635//635 768//768 767//767
            +f 767//767 633//633 635//635
            +f 637//637 769//769 768//768
            +f 768//768 635//635 637//637
            +f 770//770 771//771 772//772
            +f 773//773 772//772 771//771
            +f 774//774 770//770 775//775
            +f 772//772 775//775 770//770
            +f 776//776 777//777 774//774
            +f 774//774 775//775 776//776
            +f 778//778 779//779 776//776
            +f 777//777 776//776 779//779
            +f 780//780 781//781 778//778
            +f 779//779 778//778 781//781
            +f 782//782 783//783 780//780
            +f 781//781 780//780 783//783
            +f 772//772 773//773 784//784
            +f 785//785 784//784 773//773
            +f 775//775 772//772 786//786
            +f 784//784 786//786 772//772
            +f 776//776 775//775 787//787
            +f 786//786 787//787 775//775
            +f 788//788 778//778 776//776
            +f 776//776 787//787 788//788
            +f 789//789 780//780 788//788
            +f 778//778 788//788 780//780
            +f 790//790 782//782 789//789
            +f 780//780 789//789 782//782
            +f 784//784 785//785 791//791
            +f 792//792 791//791 785//785
            +f 786//786 784//784 793//793
            +f 791//791 793//793 784//784
            +f 787//787 786//786 794//794
            +f 793//793 794//794 786//786
            +f 795//795 788//788 787//787
            +f 787//787 794//794 795//795
            +f 796//796 789//789 795//795
            +f 788//788 795//795 789//789
            +f 797//797 790//790 796//796
            +f 789//789 796//796 790//790
            +f 791//791 792//792 798//798
            +f 799//799 798//798 792//792
            +f 793//793 791//791 800//800
            +f 798//798 800//800 791//791
            +f 794//794 793//793 801//801
            +f 800//800 801//801 793//793
            +f 802//802 795//795 794//794
            +f 794//794 801//801 802//802
            +f 803//803 796//796 802//802
            +f 795//795 802//802 796//796
            +f 804//804 797//797 803//803
            +f 796//796 803//803 797//797
            +f 798//798 799//799 805//805
            +f 806//806 805//805 799//799
            +f 800//800 798//798 807//807
            +f 805//805 807//807 798//798
            +f 801//801 800//800 808//808
            +f 807//807 808//808 800//800
            +f 809//809 802//802 801//801
            +f 801//801 808//808 809//809
            +f 810//810 803//803 809//809
            +f 802//802 809//809 803//803
            +f 811//811 804//804 810//810
            +f 803//803 810//810 804//804
            +f 805//805 806//806 812//812
            +f 813//813 812//812 806//806
            +f 807//807 805//805 814//814
            +f 812//812 814//814 805//805
            +f 815//815 808//808 814//814
            +f 807//807 814//814 808//808
            +f 816//816 809//809 815//815
            +f 808//808 815//815 809//809
            +f 817//817 810//810 816//816
            +f 809//809 816//816 810//810
            +f 818//818 811//811 817//817
            +f 810//810 817//817 811//811
            +f 819//819 820//820 812//812
            +f 812//812 813//813 819//819
            +f 820//820 821//821 814//814
            +f 814//814 812//812 820//820
            +f 822//822 815//815 814//814
            +f 814//814 821//821 822//822
            +f 823//823 816//816 815//815
            +f 815//815 822//822 823//823
            +f 824//824 817//817 816//816
            +f 816//816 823//823 824//824
            +f 825//825 818//818 817//817
            +f 817//817 824//824 825//825
            +f 826//826 827//827 820//820
            +f 820//820 819//819 826//826
            +f 827//827 828//828 821//821
            +f 821//821 820//820 827//827
            +f 828//828 829//829 822//822
            +f 822//822 821//821 828//828
            +f 830//830 823//823 829//829
            +f 822//822 829//829 823//823
            +f 831//831 824//824 823//823
            +f 823//823 830//830 831//831
            +f 832//832 825//825 824//824
            +f 824//824 831//831 832//832
            +f 833//833 834//834 827//827
            +f 827//827 826//826 833//833
            +f 834//834 835//835 828//828
            +f 828//828 827//827 834//834
            +f 835//835 836//836 829//829
            +f 829//829 828//828 835//835
            +f 837//837 830//830 836//836
            +f 829//829 836//836 830//830
            +f 838//838 831//831 830//830
            +f 830//830 837//837 838//838
            +f 839//839 832//832 831//831
            +f 831//831 838//838 839//839
            +f 840//840 841//841 834//834
            +f 834//834 833//833 840//840
            +f 841//841 842//842 835//835
            +f 835//835 834//834 841//841
            +f 842//842 843//843 836//836
            +f 836//836 835//835 842//842
            +f 844//844 837//837 843//843
            +f 836//836 843//843 837//837
            +f 845//845 838//838 837//837
            +f 837//837 844//844 845//845
            +f 846//846 839//839 838//838
            +f 838//838 845//845 846//846
            +f 847//847 848//848 841//841
            +f 841//841 840//840 847//847
            +f 848//848 849//849 842//842
            +f 842//842 841//841 848//848
            +f 849//849 850//850 843//843
            +f 843//843 842//842 849//849
            +f 851//851 844//844 850//850
            +f 843//843 850//850 844//844
            +f 852//852 845//845 844//844
            +f 844//844 851//851 852//852
            +f 853//853 846//846 845//845
            +f 845//845 852//852 853//853
            +f 771//771 770//770 848//848
            +f 848//848 847//847 771//771
            +f 770//770 774//774 849//849
            +f 849//849 848//848 770//770
            +f 777//777 850//850 774//774
            +f 849//849 774//774 850//850
            +f 779//779 851//851 850//850
            +f 850//850 777//777 779//779
            +f 781//781 852//852 851//851
            +f 851//851 779//779 781//781
            +f 783//783 853//853 852//852
            +f 852//852 781//781 783//783
            +f 854//854 855//855 782//782
            +f 783//783 782//782 855//855
            +f 856//856 857//857 855//855
            +f 855//855 854//854 856//856
            +f 858//858 859//859 857//857
            +f 857//857 856//856 858//858
            +f 860//860 861//861 859//859
            +f 859//859 858//858 860//860
            +f 862//862 863//863 861//861
            +f 861//861 860//860 862//862
            +f 864//864 865//865 863//863
            +f 863//863 862//862 864//864
            +f 866//866 854//854 782//782
            +f 782//782 790//790 866//866
            +f 867//867 856//856 854//854
            +f 854//854 866//866 867//867
            +f 868//868 858//858 856//856
            +f 856//856 867//867 868//868
            +f 869//869 860//860 858//858
            +f 858//858 868//868 869//869
            +f 870//870 862//862 860//860
            +f 860//860 869//869 870//870
            +f 871//871 864//864 870//870
            +f 862//862 870//870 864//864
            +f 872//872 866//866 790//790
            +f 790//790 797//797 872//872
            +f 873//873 867//867 866//866
            +f 866//866 872//872 873//873
            +f 874//874 868//868 867//867
            +f 867//867 873//873 874//874
            +f 875//875 869//869 874//874
            +f 868//868 874//874 869//869
            +f 876//876 870//870 875//875
            +f 869//869 875//875 870//870
            +f 877//877 871//871 876//876
            +f 870//870 876//876 871//871
            +f 878//878 872//872 797//797
            +f 797//797 804//804 878//878
            +f 879//879 873//873 872//872
            +f 872//872 878//878 879//879
            +f 880//880 874//874 873//873
            +f 873//873 879//879 880//880
            +f 881//881 875//875 880//880
            +f 874//874 880//880 875//875
            +f 882//882 876//876 881//881
            +f 875//875 881//881 876//876
            +f 883//883 877//877 882//882
            +f 876//876 882//882 877//877
            +f 884//884 878//878 804//804
            +f 804//804 811//811 884//884
            +f 885//885 879//879 878//878
            +f 878//878 884//884 885//885
            +f 886//886 880//880 879//879
            +f 879//879 885//885 886//886
            +f 887//887 881//881 880//880
            +f 880//880 886//886 887//887
            +f 888//888 882//882 881//881
            +f 881//881 887//887 888//888
            +f 889//889 883//883 888//888
            +f 882//882 888//888 883//883
            +f 890//890 884//884 811//811
            +f 811//811 818//818 890//890
            +f 891//891 885//885 884//884
            +f 884//884 890//890 891//891
            +f 892//892 886//886 885//885
            +f 885//885 891//891 892//892
            +f 893//893 887//887 886//886
            +f 886//886 892//892 893//893
            +f 894//894 888//888 887//887
            +f 887//887 893//893 894//894
            +f 895//895 889//889 888//888
            +f 888//888 894//894 895//895
            +f 896//896 890//890 825//825
            +f 818//818 825//825 890//890
            +f 897//897 891//891 896//896
            +f 890//890 896//896 891//891
            +f 898//898 892//892 897//897
            +f 891//891 897//897 892//892
            +f 899//899 893//893 898//898
            +f 892//892 898//898 893//893
            +f 900//900 894//894 899//899
            +f 893//893 899//899 894//894
            +f 901//901 895//895 900//900
            +f 894//894 900//900 895//895
            +f 902//902 896//896 832//832
            +f 825//825 832//832 896//896
            +f 903//903 897//897 902//902
            +f 896//896 902//902 897//897
            +f 904//904 898//898 903//903
            +f 897//897 903//903 898//898
            +f 905//905 899//899 904//904
            +f 898//898 904//904 899//899
            +f 906//906 900//900 905//905
            +f 899//899 905//905 900//900
            +f 907//907 901//901 900//900
            +f 900//900 906//906 907//907
            +f 908//908 902//902 839//839
            +f 832//832 839//839 902//902
            +f 909//909 903//903 908//908
            +f 902//902 908//908 903//903
            +f 910//910 904//904 909//909
            +f 903//903 909//909 904//904
            +f 911//911 905//905 904//904
            +f 904//904 910//910 911//911
            +f 912//912 906//906 905//905
            +f 905//905 911//911 912//912
            +f 913//913 907//907 906//906
            +f 906//906 912//912 913//913
            +f 914//914 908//908 846//846
            +f 839//839 846//846 908//908
            +f 915//915 909//909 914//914
            +f 908//908 914//914 909//909
            +f 916//916 910//910 915//915
            +f 909//909 915//915 910//910
            +f 917//917 911//911 910//910
            +f 910//910 916//916 917//917
            +f 918//918 912//912 911//911
            +f 911//911 917//917 918//918
            +f 919//919 913//913 912//912
            +f 912//912 918//918 919//919
            +f 920//920 914//914 853//853
            +f 846//846 853//853 914//914
            +f 921//921 915//915 920//920
            +f 914//914 920//920 915//915
            +f 922//922 916//916 921//921
            +f 915//915 921//921 916//916
            +f 923//923 917//917 922//922
            +f 916//916 922//922 917//917
            +f 924//924 918//918 923//923
            +f 917//917 923//923 918//918
            +f 925//925 919//919 918//918
            +f 918//918 924//924 925//925
            +f 855//855 920//920 853//853
            +f 853//853 783//783 855//855
            +f 857//857 921//921 855//855
            +f 920//920 855//855 921//921
            +f 859//859 922//922 857//857
            +f 921//921 857//857 922//922
            +f 861//861 923//923 859//859
            +f 922//922 859//859 923//923
            +f 863//863 924//924 861//861
            +f 923//923 861//861 924//924
            +f 865//865 925//925 863//863
            +f 924//924 863//863 925//925
            +f 926//926 927//927 928//928
            +f 928//928 929//929 926//926
            +f 929//929 928//928 930//930
            +f 930//930 931//931 929//929
            +f 931//931 930//930 932//932
            +f 932//932 933//933 931//931
            +f 933//933 932//932 934//934
            +f 934//934 935//935 933//933
            +f 935//935 934//934 936//936
            +f 936//936 937//937 935//935
            +f 937//937 936//936 938//938
            +f 939//939 938//938 936//936
            +f 940//940 941//941 927//927
            +f 928//928 927//927 941//941
            +f 928//928 941//941 942//942
            +f 942//942 930//930 928//928
            +f 930//930 942//942 943//943
            +f 943//943 932//932 930//930
            +f 932//932 943//943 944//944
            +f 944//944 934//934 932//932
            +f 934//934 944//944 936//936
            +f 945//945 936//936 944//944
            +f 936//936 945//945 939//939
            +f 946//946 939//939 945//945
            +f 947//947 948//948 940//940
            +f 941//941 940//940 948//948
            +f 941//941 948//948 949//949
            +f 949//949 942//942 941//941
            +f 942//942 949//949 943//943
            +f 950//950 943//943 949//949
            +f 943//943 950//950 944//944
            +f 951//951 944//944 950//950
            +f 944//944 951//951 945//945
            +f 952//952 945//945 951//951
            +f 945//945 952//952 946//946
            +f 953//953 946//946 952//952
            +f 954//954 955//955 947//947
            +f 948//948 947//947 955//955
            +f 948//948 955//955 956//956
            +f 956//956 949//949 948//948
            +f 949//949 956//956 950//950
            +f 957//957 950//950 956//956
            +f 950//950 957//957 951//951
            +f 958//958 951//951 957//957
            +f 951//951 958//958 952//952
            +f 959//959 952//952 958//958
            +f 952//952 959//959 953//953
            +f 960//960 953//953 959//959
            +f 954//954 961//961 962//962
            +f 962//962 955//955 954//954
            +f 955//955 962//962 956//956
            +f 963//963 956//956 962//962
            +f 956//956 963//963 957//957
            +f 964//964 957//957 963//963
            +f 957//957 964//964 958//958
            +f 965//965 958//958 964//964
            +f 958//958 965//965 959//959
            +f 966//966 959//959 965//965
            +f 959//959 966//966 960//960
            +f 967//967 960//960 966//966
            +f 961//961 968//968 962//962
            +f 969//969 962//962 968//968
            +f 962//962 969//969 963//963
            +f 970//970 963//963 969//969
            +f 963//963 970//970 964//964
            +f 971//971 964//964 970//970
            +f 964//964 971//971 965//965
            +f 972//972 965//965 971//971
            +f 965//965 972//972 966//966
            +f 973//973 966//966 972//972
            +f 966//966 973//973 967//967
            +f 974//974 967//967 973//973
            +f 968//968 975//975 976//976
            +f 976//976 969//969 968//968
            +f 969//969 976//976 977//977
            +f 977//977 970//970 969//969
            +f 970//970 977//977 978//978
            +f 978//978 971//971 970//970
            +f 971//971 978//978 979//979
            +f 979//979 972//972 971//971
            +f 972//972 979//979 980//980
            +f 980//980 973//973 972//972
            +f 973//973 980//980 981//981
            +f 981//981 974//974 973//973
            +f 975//975 982//982 976//976
            +f 983//983 976//976 982//982
            +f 976//976 983//983 984//984
            +f 984//984 977//977 976//976
            +f 977//977 984//984 985//985
            +f 985//985 978//978 977//977
            +f 978//978 985//985 986//986
            +f 986//986 979//979 978//978
            +f 979//979 986//986 987//987
            +f 987//987 980//980 979//979
            +f 980//980 987//987 988//988
            +f 988//988 981//981 980//980
            +f 983//983 982//982 989//989
            +f 989//989 990//990 983//983
            +f 983//983 990//990 984//984
            +f 991//991 984//984 990//990
            +f 984//984 991//991 992//992
            +f 992//992 985//985 984//984
            +f 985//985 992//992 993//993
            +f 993//993 986//986 985//985
            +f 986//986 993//993 994//994
            +f 994//994 987//987 986//986
            +f 987//987 994//994 995//995
            +f 995//995 988//988 987//987
            +f 990//990 989//989 996//996
            +f 996//996 997//997 990//990
            +f 990//990 997//997 991//991
            +f 998//998 991//991 997//997
            +f 991//991 998//998 999//999
            +f 999//999 992//992 991//991
            +f 992//992 999//999 1000//1000
            +f 1000//1000 993//993 992//992
            +f 993//993 1000//1000 1001//1001
            +f 1001//1001 994//994 993//993
            +f 994//994 1001//1001 1002//1002
            +f 1002//1002 995//995 994//994
            +f 997//997 996//996 1003//1003
            +f 1003//1003 1004//1004 997//997
            +f 997//997 1004//1004 998//998
            +f 1005//1005 998//998 1004//1004
            +f 998//998 1005//1005 999//999
            +f 1006//1006 999//999 1005//1005
            +f 999//999 1006//1006 1000//1000
            +f 1007//1007 1000//1000 1006//1006
            +f 1000//1000 1007//1007 1008//1008
            +f 1008//1008 1001//1001 1000//1000
            +f 1001//1001 1008//1008 1009//1009
            +f 1009//1009 1002//1002 1001//1001
            +f 1003//1003 926//926 1004//1004
            +f 929//929 1004//1004 926//926
            +f 1004//1004 929//929 1005//1005
            +f 931//931 1005//1005 929//929
            +f 1005//1005 931//931 1006//1006
            +f 933//933 1006//1006 931//931
            +f 1006//1006 933//933 1007//1007
            +f 935//935 1007//1007 933//933
            +f 1007//1007 935//935 1008//1008
            +f 937//937 1008//1008 935//935
            +f 1008//1008 937//937 938//938
            +f 938//938 1009//1009 1008//1008
            +f 938//938 939//939 1010//1010
            +f 1011//1011 1010//1010 939//939
            +f 1010//1010 1011//1011 1012//1012
            +f 1013//1013 1012//1012 1011//1011
            +f 1012//1012 1013//1013 1014//1014
            +f 1015//1015 1014//1014 1013//1013
            +f 1016//1016 1017//1017 1014//1014
            +f 1014//1014 1015//1015 1016//1016
            +f 1018//1018 1019//1019 1017//1017
            +f 1017//1017 1016//1016 1018//1018
            +f 1020//1020 1021//1021 1019//1019
            +f 1019//1019 1018//1018 1020//1020
            +f 939//939 946//946 1011//1011
            +f 1022//1022 1011//1011 946//946
            +f 1011//1011 1022//1022 1013//1013
            +f 1023//1023 1013//1013 1022//1022
            +f 1013//1013 1023//1023 1015//1015
            +f 1024//1024 1015//1015 1023//1023
            +f 1025//1025 1016//1016 1015//1015
            +f 1015//1015 1024//1024 1025//1025
            +f 1026//1026 1018//1018 1016//1016
            +f 1016//1016 1025//1025 1026//1026
            +f 1027//1027 1020//1020 1018//1018
            +f 1018//1018 1026//1026 1027//1027
            +f 946//946 953//953 1022//1022
            +f 1028//1028 1022//1022 953//953
            +f 1022//1022 1028//1028 1023//1023
            +f 1029//1029 1023//1023 1028//1028
            +f 1023//1023 1029//1029 1024//1024
            +f 1030//1030 1024//1024 1029//1029
            +f 1031//1031 1025//1025 1024//1024
            +f 1024//1024 1030//1030 1031//1031
            +f 1032//1032 1026//1026 1025//1025
            +f 1025//1025 1031//1031 1032//1032
            +f 1033//1033 1027//1027 1026//1026
            +f 1026//1026 1032//1032 1033//1033
            +f 953//953 960//960 1028//1028
            +f 1034//1034 1028//1028 960//960
            +f 1028//1028 1034//1034 1029//1029
            +f 1035//1035 1029//1029 1034//1034
            +f 1029//1029 1035//1035 1030//1030
            +f 1036//1036 1030//1030 1035//1035
            +f 1037//1037 1031//1031 1030//1030
            +f 1030//1030 1036//1036 1037//1037
            +f 1038//1038 1032//1032 1031//1031
            +f 1031//1031 1037//1037 1038//1038
            +f 1039//1039 1033//1033 1032//1032
            +f 1032//1032 1038//1038 1039//1039
            +f 960//960 967//967 1034//1034
            +f 1040//1040 1034//1034 967//967
            +f 1034//1034 1040//1040 1035//1035
            +f 1041//1041 1035//1035 1040//1040
            +f 1035//1035 1041//1041 1036//1036
            +f 1042//1042 1036//1036 1041//1041
            +f 1043//1043 1037//1037 1036//1036
            +f 1036//1036 1042//1042 1043//1043
            +f 1044//1044 1038//1038 1037//1037
            +f 1037//1037 1043//1043 1044//1044
            +f 1045//1045 1039//1039 1038//1038
            +f 1038//1038 1044//1044 1045//1045
            +f 967//967 974//974 1040//1040
            +f 1046//1046 1040//1040 974//974
            +f 1040//1040 1046//1046 1041//1041
            +f 1047//1047 1041//1041 1046//1046
            +f 1041//1041 1047//1047 1042//1042
            +f 1048//1048 1042//1042 1047//1047
            +f 1049//1049 1043//1043 1042//1042
            +f 1042//1042 1048//1048 1049//1049
            +f 1050//1050 1044//1044 1043//1043
            +f 1043//1043 1049//1049 1050//1050
            +f 1051//1051 1045//1045 1044//1044
            +f 1044//1044 1050//1050 1051//1051
            +f 974//974 981//981 1052//1052
            +f 1052//1052 1046//1046 974//974
            +f 1046//1046 1052//1052 1053//1053
            +f 1053//1053 1047//1047 1046//1046
            +f 1047//1047 1053//1053 1054//1054
            +f 1054//1054 1048//1048 1047//1047
            +f 1055//1055 1049//1049 1054//1054
            +f 1048//1048 1054//1054 1049//1049
            +f 1056//1056 1050//1050 1055//1055
            +f 1049//1049 1055//1055 1050//1050
            +f 1057//1057 1051//1051 1056//1056
            +f 1050//1050 1056//1056 1051//1051
            +f 981//981 988//988 1058//1058
            +f 1058//1058 1052//1052 981//981
            +f 1052//1052 1058//1058 1059//1059
            +f 1059//1059 1053//1053 1052//1052
            +f 1053//1053 1059//1059 1060//1060
            +f 1060//1060 1054//1054 1053//1053
            +f 1061//1061 1055//1055 1060//1060
            +f 1054//1054 1060//1060 1055//1055
            +f 1062//1062 1056//1056 1061//1061
            +f 1055//1055 1061//1061 1056//1056
            +f 1063//1063 1057//1057 1062//1062
            +f 1056//1056 1062//1062 1057//1057
            +f 988//988 995//995 1064//1064
            +f 1064//1064 1058//1058 988//988
            +f 1058//1058 1064//1064 1065//1065
            +f 1065//1065 1059//1059 1058//1058
            +f 1059//1059 1065//1065 1066//1066
            +f 1066//1066 1060//1060 1059//1059
            +f 1067//1067 1061//1061 1066//1066
            +f 1060//1060 1066//1066 1061//1061
            +f 1068//1068 1062//1062 1067//1067
            +f 1061//1061 1067//1067 1062//1062
            +f 1069//1069 1063//1063 1068//1068
            +f 1062//1062 1068//1068 1063//1063
            +f 995//995 1002//1002 1070//1070
            +f 1070//1070 1064//1064 995//995
            +f 1064//1064 1070//1070 1071//1071
            +f 1071//1071 1065//1065 1064//1064
            +f 1065//1065 1071//1071 1072//1072
            +f 1072//1072 1066//1066 1065//1065
            +f 1073//1073 1067//1067 1072//1072
            +f 1066//1066 1072//1072 1067//1067
            +f 1074//1074 1068//1068 1073//1073
            +f 1067//1067 1073//1073 1068//1068
            +f 1075//1075 1069//1069 1074//1074
            +f 1068//1068 1074//1074 1069//1069
            +f 1002//1002 1009//1009 1076//1076
            +f 1076//1076 1070//1070 1002//1002
            +f 1070//1070 1076//1076 1077//1077
            +f 1077//1077 1071//1071 1070//1070
            +f 1071//1071 1077//1077 1078//1078
            +f 1078//1078 1072//1072 1071//1071
            +f 1079//1079 1073//1073 1078//1078
            +f 1072//1072 1078//1078 1073//1073
            +f 1080//1080 1074//1074 1079//1079
            +f 1073//1073 1079//1079 1074//1074
            +f 1081//1081 1075//1075 1080//1080
            +f 1074//1074 1080//1080 1075//1075
            +f 1009//1009 938//938 1010//1010
            +f 1010//1010 1076//1076 1009//1009
            +f 1076//1076 1010//1010 1012//1012
            +f 1012//1012 1077//1077 1076//1076
            +f 1077//1077 1012//1012 1014//1014
            +f 1014//1014 1078//1078 1077//1077
            +f 1017//1017 1079//1079 1014//1014
            +f 1078//1078 1014//1014 1079//1079
            +f 1019//1019 1080//1080 1017//1017
            +f 1079//1079 1017//1017 1080//1080
            +f 1021//1021 1081//1081 1019//1019
            +f 1080//1080 1019//1019 1081//1081
            +f 1082//1082 1083//1083 1084//1084
            +f 1084//1084 1083//1083 1085//1085
            +f 1085//1085 1083//1083 1086//1086
            +f 1086//1086 1083//1083 1087//1087
            +f 1087//1087 1083//1083 1088//1088
            +f 1088//1088 1083//1083 1089//1089
            +f 1089//1089 1083//1083 1090//1090
            +f 1090//1090 1083//1083 1091//1091
            +f 1091//1091 1083//1083 1092//1092
            +f 1092//1092 1083//1083 1093//1093
            +f 1093//1093 1083//1083 1094//1094
            +f 1094//1094 1083//1083 1095//1095
            +f 1095//1095 1083//1083 1096//1096
            +f 1096//1096 1083//1083 1097//1097
            +f 1097//1097 1083//1083 1098//1098
            +f 1098//1098 1083//1083 1099//1099
            +f 1099//1099 1083//1083 1100//1100
            +f 1100//1100 1083//1083 1101//1101
            +f 1101//1101 1083//1083 1102//1102
            +f 1102//1102 1083//1083 1103//1103
            +f 1103//1103 1083//1083 1104//1104
            +f 1104//1104 1083//1083 1105//1105
            +f 1105//1105 1083//1083 1106//1106
            +f 1106//1106 1083//1083 1082//1082
            +f 1107//1107 1108//1108 1084//1084
            +f 1082//1082 1084//1084 1108//1108
            +f 1109//1109 1110//1110 1108//1108
            +f 1108//1108 1107//1107 1109//1109
            +f 1111//1111 1112//1112 1110//1110
            +f 1110//1110 1109//1109 1111//1111
            +f 1113//1113 1114//1114 1112//1112
            +f 1112//1112 1111//1111 1113//1113
            +f 1115//1115 1107//1107 1085//1085
            +f 1084//1084 1085//1085 1107//1107
            +f 1116//1116 1109//1109 1107//1107
            +f 1107//1107 1115//1115 1116//1116
            +f 1117//1117 1111//1111 1109//1109
            +f 1109//1109 1116//1116 1117//1117
            +f 1118//1118 1113//1113 1111//1111
            +f 1111//1111 1117//1117 1118//1118
            +f 1119//1119 1115//1115 1086//1086
            +f 1085//1085 1086//1086 1115//1115
            +f 1120//1120 1116//1116 1115//1115
            +f 1115//1115 1119//1119 1120//1120
            +f 1121//1121 1117//1117 1116//1116
            +f 1116//1116 1120//1120 1121//1121
            +f 1122//1122 1118//1118 1117//1117
            +f 1117//1117 1121//1121 1122//1122
            +f 1123//1123 1119//1119 1086//1086
            +f 1086//1086 1087//1087 1123//1123
            +f 1124//1124 1120//1120 1123//1123
            +f 1119//1119 1123//1123 1120//1120
            +f 1125//1125 1121//1121 1124//1124
            +f 1120//1120 1124//1124 1121//1121
            +f 1126//1126 1122//1122 1125//1125
            +f 1121//1121 1125//1125 1122//1122
            +f 1127//1127 1123//1123 1087//1087
            +f 1087//1087 1088//1088 1127//1127
            +f 1128//1128 1124//1124 1127//1127
            +f 1123//1123 1127//1127 1124//1124
            +f 1129//1129 1125//1125 1128//1128
            +f 1124//1124 1128//1128 1125//1125
            +f 1130//1130 1126//1126 1129//1129
            +f 1125//1125 1129//1129 1126//1126
            +f 1131//1131 1127//1127 1088//1088
            +f 1088//1088 1089//1089 1131//1131
            +f 1132//1132 1128//1128 1131//1131
            +f 1127//1127 1131//1131 1128//1128
            +f 1133//1133 1129//1129 1132//1132
            +f 1128//1128 1132//1132 1129//1129
            +f 1134//1134 1130//1130 1133//1133
            +f 1129//1129 1133//1133 1130//1130
            +f 1135//1135 1131//1131 1090//1090
            +f 1089//1089 1090//1090 1131//1131
            +f 1136//1136 1132//1132 1131//1131
            +f 1131//1131 1135//1135 1136//1136
            +f 1137//1137 1133//1133 1132//1132
            +f 1132//1132 1136//1136 1137//1137
            +f 1138//1138 1134//1134 1133//1133
            +f 1133//1133 1137//1137 1138//1138
            +f 1139//1139 1135//1135 1091//1091
            +f 1090//1090 1091//1091 1135//1135
            +f 1140//1140 1136//1136 1135//1135
            +f 1135//1135 1139//1139 1140//1140
            +f 1141//1141 1137//1137 1136//1136
            +f 1136//1136 1140//1140 1141//1141
            +f 1142//1142 1138//1138 1137//1137
            +f 1137//1137 1141//1141 1142//1142
            +f 1143//1143 1139//1139 1092//1092
            +f 1091//1091 1092//1092 1139//1139
            +f 1144//1144 1140//1140 1139//1139
            +f 1139//1139 1143//1143 1144//1144
            +f 1145//1145 1141//1141 1140//1140
            +f 1140//1140 1144//1144 1145//1145
            +f 1146//1146 1142//1142 1141//1141
            +f 1141//1141 1145//1145 1146//1146
            +f 1147//1147 1143//1143 1092//1092
            +f 1092//1092 1093//1093 1147//1147
            +f 1148//1148 1144//1144 1147//1147
            +f 1143//1143 1147//1147 1144//1144
            +f 1149//1149 1145//1145 1148//1148
            +f 1144//1144 1148//1148 1145//1145
            +f 1150//1150 1146//1146 1149//1149
            +f 1145//1145 1149//1149 1146//1146
            +f 1151//1151 1147//1147 1093//1093
            +f 1093//1093 1094//1094 1151//1151
            +f 1152//1152 1148//1148 1151//1151
            +f 1147//1147 1151//1151 1148//1148
            +f 1153//1153 1149//1149 1152//1152
            +f 1148//1148 1152//1152 1149//1149
            +f 1154//1154 1150//1150 1153//1153
            +f 1149//1149 1153//1153 1150//1150
            +f 1155//1155 1151//1151 1094//1094
            +f 1094//1094 1095//1095 1155//1155
            +f 1156//1156 1152//1152 1155//1155
            +f 1151//1151 1155//1155 1152//1152
            +f 1157//1157 1153//1153 1156//1156
            +f 1152//1152 1156//1156 1153//1153
            +f 1158//1158 1154//1154 1157//1157
            +f 1153//1153 1157//1157 1154//1154
            +f 1159//1159 1155//1155 1096//1096
            +f 1095//1095 1096//1096 1155//1155
            +f 1160//1160 1156//1156 1155//1155
            +f 1155//1155 1159//1159 1160//1160
            +f 1161//1161 1157//1157 1156//1156
            +f 1156//1156 1160//1160 1161//1161
            +f 1162//1162 1158//1158 1157//1157
            +f 1157//1157 1161//1161 1162//1162
            +f 1163//1163 1159//1159 1097//1097
            +f 1096//1096 1097//1097 1159//1159
            +f 1164//1164 1160//1160 1159//1159
            +f 1159//1159 1163//1163 1164//1164
            +f 1165//1165 1161//1161 1160//1160
            +f 1160//1160 1164//1164 1165//1165
            +f 1166//1166 1162//1162 1161//1161
            +f 1161//1161 1165//1165 1166//1166
            +f 1167//1167 1163//1163 1098//1098
            +f 1097//1097 1098//1098 1163//1163
            +f 1168//1168 1164//1164 1163//1163
            +f 1163//1163 1167//1167 1168//1168
            +f 1169//1169 1165//1165 1164//1164
            +f 1164//1164 1168//1168 1169//1169
            +f 1170//1170 1166//1166 1165//1165
            +f 1165//1165 1169//1169 1170//1170
            +f 1171//1171 1167//1167 1098//1098
            +f 1098//1098 1099//1099 1171//1171
            +f 1172//1172 1168//1168 1171//1171
            +f 1167//1167 1171//1171 1168//1168
            +f 1173//1173 1169//1169 1172//1172
            +f 1168//1168 1172//1172 1169//1169
            +f 1174//1174 1170//1170 1173//1173
            +f 1169//1169 1173//1173 1170//1170
            +f 1175//1175 1171//1171 1099//1099
            +f 1099//1099 1100//1100 1175//1175
            +f 1176//1176 1172//1172 1175//1175
            +f 1171//1171 1175//1175 1172//1172
            +f 1177//1177 1173//1173 1176//1176
            +f 1172//1172 1176//1176 1173//1173
            +f 1178//1178 1174//1174 1177//1177
            +f 1173//1173 1177//1177 1174//1174
            +f 1179//1179 1175//1175 1100//1100
            +f 1100//1100 1101//1101 1179//1179
            +f 1180//1180 1176//1176 1179//1179
            +f 1175//1175 1179//1179 1176//1176
            +f 1181//1181 1177//1177 1180//1180
            +f 1176//1176 1180//1180 1177//1177
            +f 1182//1182 1178//1178 1181//1181
            +f 1177//1177 1181//1181 1178//1178
            +f 1183//1183 1179//1179 1102//1102
            +f 1101//1101 1102//1102 1179//1179
            +f 1184//1184 1180//1180 1179//1179
            +f 1179//1179 1183//1183 1184//1184
            +f 1185//1185 1181//1181 1180//1180
            +f 1180//1180 1184//1184 1185//1185
            +f 1186//1186 1182//1182 1181//1181
            +f 1181//1181 1185//1185 1186//1186
            +f 1187//1187 1183//1183 1103//1103
            +f 1102//1102 1103//1103 1183//1183
            +f 1188//1188 1184//1184 1183//1183
            +f 1183//1183 1187//1187 1188//1188
            +f 1189//1189 1185//1185 1184//1184
            +f 1184//1184 1188//1188 1189//1189
            +f 1190//1190 1186//1186 1185//1185
            +f 1185//1185 1189//1189 1190//1190
            +f 1191//1191 1187//1187 1104//1104
            +f 1103//1103 1104//1104 1187//1187
            +f 1192//1192 1188//1188 1187//1187
            +f 1187//1187 1191//1191 1192//1192
            +f 1193//1193 1189//1189 1188//1188
            +f 1188//1188 1192//1192 1193//1193
            +f 1194//1194 1190//1190 1189//1189
            +f 1189//1189 1193//1193 1194//1194
            +f 1195//1195 1191//1191 1104//1104
            +f 1104//1104 1105//1105 1195//1195
            +f 1196//1196 1192//1192 1195//1195
            +f 1191//1191 1195//1195 1192//1192
            +f 1197//1197 1193//1193 1196//1196
            +f 1192//1192 1196//1196 1193//1193
            +f 1198//1198 1194//1194 1197//1197
            +f 1193//1193 1197//1197 1194//1194
            +f 1199//1199 1195//1195 1105//1105
            +f 1105//1105 1106//1106 1199//1199
            +f 1200//1200 1196//1196 1199//1199
            +f 1195//1195 1199//1199 1196//1196
            +f 1201//1201 1197//1197 1200//1200
            +f 1196//1196 1200//1200 1197//1197
            +f 1202//1202 1198//1198 1201//1201
            +f 1197//1197 1201//1201 1198//1198
            +f 1108//1108 1199//1199 1106//1106
            +f 1106//1106 1082//1082 1108//1108
            +f 1110//1110 1200//1200 1108//1108
            +f 1199//1199 1108//1108 1200//1200
            +f 1112//1112 1201//1201 1110//1110
            +f 1200//1200 1110//1110 1201//1201
            +f 1114//1114 1202//1202 1112//1112
            +f 1201//1201 1112//1112 1202//1202
            diff --git a/dist/zh-Hans/reference/assets/test.txt b/dist/zh-Hans/reference/assets/test.txt
            new file mode 100644
            index 0000000000..9dc2445af3
            --- /dev/null
            +++ b/dist/zh-Hans/reference/assets/test.txt
            @@ -0,0 +1,6 @@
            +I am a cat
            +I like apples
            +I have three feet
            +I like my nose
            +I smell like butter
            +I talk like an orange
            \ No newline at end of file
            diff --git a/dist/zh-Hans/reference/assets/transformation-matrix.png b/dist/zh-Hans/reference/assets/transformation-matrix.png
            new file mode 100644
            index 0000000000..0d42542922
            Binary files /dev/null and b/dist/zh-Hans/reference/assets/transformation-matrix.png differ
            diff --git a/dist/zh-Hans/reference/data.json b/dist/zh-Hans/reference/data.json
            new file mode 100644
            index 0000000000..16f3ad430e
            --- /dev/null
            +++ b/dist/zh-Hans/reference/data.json
            @@ -0,0 +1,30598 @@
            +{
            +    "project": {
            +        "name": "p5",
            +        "description": "[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)",
            +        "version": "1.4.1",
            +        "url": "https://github.com/processing/p5.js#readme"
            +    },
            +    "files": {
            +        "src/accessibility/color_namer.js": {
            +            "name": "src/accessibility/color_namer.js",
            +            "modules": {
            +                "Environment": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/describe.js": {
            +            "name": "src/accessibility/describe.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/gridOutput.js": {
            +            "name": "src/accessibility/gridOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/outputs.js": {
            +            "name": "src/accessibility/outputs.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/accessibility/textOutput.js": {
            +            "name": "src/accessibility/textOutput.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/color_conversion.js": {
            +            "name": "src/color/color_conversion.js",
            +            "modules": {
            +                "Color Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/creating_reading.js": {
            +            "name": "src/color/creating_reading.js",
            +            "modules": {
            +                "Creating & Reading": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/p5.Color.js": {
            +            "name": "src/color/p5.Color.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/color/setting.js": {
            +            "name": "src/color/setting.js",
            +            "modules": {
            +                "Setting": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/fes_core.js": {
            +            "name": "src/core/friendly_errors/fes_core.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/file_errors.js": {
            +            "name": "src/core/friendly_errors/file_errors.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/sketch_reader.js": {
            +            "name": "src/core/friendly_errors/sketch_reader.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/stacktrace.js": {
            +            "name": "src/core/friendly_errors/stacktrace.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/friendly_errors/validate_params.js": {
            +            "name": "src/core/friendly_errors/validate_params.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/2d_primitives.js": {
            +            "name": "src/core/shape/2d_primitives.js",
            +            "modules": {
            +                "2D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/attributes.js": {
            +            "name": "src/core/shape/attributes.js",
            +            "modules": {
            +                "Attributes": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/curves.js": {
            +            "name": "src/core/shape/curves.js",
            +            "modules": {
            +                "Curves": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shape/vertex.js": {
            +            "name": "src/core/shape/vertex.js",
            +            "modules": {
            +                "Vertex": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/constants.js": {
            +            "name": "src/core/constants.js",
            +            "modules": {
            +                "Constants": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/environment.js": {
            +            "name": "src/core/environment.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/helpers.js": {
            +            "name": "src/core/helpers.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/init.js": {
            +            "name": "src/core/init.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/internationalization.js": {
            +            "name": "src/core/internationalization.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/legacy.js": {
            +            "name": "src/core/legacy.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/main.js": {
            +            "name": "src/core/main.js",
            +            "modules": {
            +                "Structure": 1
            +            },
            +            "classes": {
            +                "p5": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Element.js": {
            +            "name": "src/core/p5.Element.js",
            +            "modules": {
            +                "DOM": 1
            +            },
            +            "classes": {
            +                "p5.Element": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Graphics.js": {
            +            "name": "src/core/p5.Graphics.js",
            +            "modules": {
            +                "Rendering": 1
            +            },
            +            "classes": {
            +                "p5.Graphics": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer.js": {
            +            "name": "src/core/p5.Renderer.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/p5.Renderer2D.js": {
            +            "name": "src/core/p5.Renderer2D.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/reference.js": {
            +            "name": "src/core/reference.js",
            +            "modules": {
            +                "Foundation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/rendering.js": {
            +            "name": "src/core/rendering.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/shim.js": {
            +            "name": "src/core/shim.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/core/structure.js": {
            +            "name": "src/core/structure.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/core/transform.js": {
            +            "name": "src/core/transform.js",
            +            "modules": {
            +                "Transform": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/local_storage.js": {
            +            "name": "src/data/local_storage.js",
            +            "modules": {
            +                "LocalStorage": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/data/p5.TypedDict.js": {
            +            "name": "src/data/p5.TypedDict.js",
            +            "modules": {
            +                "Dictionary": 1
            +            },
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/dom/dom.js": {
            +            "name": "src/dom/dom.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Element": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/acceleration.js": {
            +            "name": "src/events/acceleration.js",
            +            "modules": {
            +                "Acceleration": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/keyboard.js": {
            +            "name": "src/events/keyboard.js",
            +            "modules": {
            +                "Keyboard": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/mouse.js": {
            +            "name": "src/events/mouse.js",
            +            "modules": {
            +                "Mouse": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/events/touch.js": {
            +            "name": "src/events/touch.js",
            +            "modules": {
            +                "Touch": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/filters.js": {
            +            "name": "src/image/filters.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/image.js": {
            +            "name": "src/image/image.js",
            +            "modules": {
            +                "Image": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/loading_displaying.js": {
            +            "name": "src/image/loading_displaying.js",
            +            "modules": {
            +                "Loading & Displaying": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/image/p5.Image.js": {
            +            "name": "src/image/p5.Image.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/image/pixels.js": {
            +            "name": "src/image/pixels.js",
            +            "modules": {
            +                "Pixels": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/files.js": {
            +            "name": "src/io/files.js",
            +            "modules": {
            +                "Input": 1,
            +                "Output": 1
            +            },
            +            "classes": {
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/io/p5.Table.js": {
            +            "name": "src/io/p5.Table.js",
            +            "modules": {
            +                "Table": 1
            +            },
            +            "classes": {
            +                "p5.Table": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.TableRow.js": {
            +            "name": "src/io/p5.TableRow.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/io/p5.XML.js": {
            +            "name": "src/io/p5.XML.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/calculation.js": {
            +            "name": "src/math/calculation.js",
            +            "modules": {
            +                "Calculation": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/math.js": {
            +            "name": "src/math/math.js",
            +            "modules": {
            +                "Vector": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/noise.js": {
            +            "name": "src/math/noise.js",
            +            "modules": {
            +                "Noise": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/p5.Vector.js": {
            +            "name": "src/math/p5.Vector.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/math/random.js": {
            +            "name": "src/math/random.js",
            +            "modules": {
            +                "Random": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/math/trigonometry.js": {
            +            "name": "src/math/trigonometry.js",
            +            "modules": {
            +                "Trigonometry": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/attributes.js": {
            +            "name": "src/typography/attributes.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/loading_displaying.js": {
            +            "name": "src/typography/loading_displaying.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/typography/p5.Font.js": {
            +            "name": "src/typography/p5.Font.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/utilities/array_functions.js": {
            +            "name": "src/utilities/array_functions.js",
            +            "modules": {
            +                "Array Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/conversion.js": {
            +            "name": "src/utilities/conversion.js",
            +            "modules": {
            +                "Conversion": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/string_functions.js": {
            +            "name": "src/utilities/string_functions.js",
            +            "modules": {
            +                "String Functions": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/utilities/time_date.js": {
            +            "name": "src/utilities/time_date.js",
            +            "modules": {
            +                "Time & Date": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/3d_primitives.js": {
            +            "name": "src/webgl/3d_primitives.js",
            +            "modules": {
            +                "3D Primitives": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/interaction.js": {
            +            "name": "src/webgl/interaction.js",
            +            "modules": {
            +                "Interaction": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/light.js": {
            +            "name": "src/webgl/light.js",
            +            "modules": {
            +                "Lights": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/loading.js": {
            +            "name": "src/webgl/loading.js",
            +            "modules": {
            +                "3D Models": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/material.js": {
            +            "name": "src/webgl/material.js",
            +            "modules": {
            +                "Material": 1
            +            },
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Camera.js": {
            +            "name": "src/webgl/p5.Camera.js",
            +            "modules": {
            +                "Camera": 1
            +            },
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Geometry.js": {
            +            "name": "src/webgl/p5.Geometry.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Matrix.js": {
            +            "name": "src/webgl/p5.Matrix.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Matrix": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RenderBuffer.js": {
            +            "name": "src/webgl/p5.RenderBuffer.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Immediate.js": {
            +            "name": "src/webgl/p5.RendererGL.Immediate.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.Retained.js": {
            +            "name": "src/webgl/p5.RendererGL.Retained.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.RendererGL.js": {
            +            "name": "src/webgl/p5.RendererGL.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.RendererGL": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Shader.js": {
            +            "name": "src/webgl/p5.Shader.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Shader": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/p5.Texture.js": {
            +            "name": "src/webgl/p5.Texture.js",
            +            "modules": {},
            +            "classes": {
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "src/webgl/text.js": {
            +            "name": "src/webgl/text.js",
            +            "modules": {},
            +            "classes": {
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {},
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.js": {
            +            "name": "lib/addons/p5.sound.js",
            +            "modules": {
            +                "p5.sound": 1
            +            },
            +            "classes": {
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "lib/addons/p5.sound.min.js": {
            +            "name": "lib/addons/p5.sound.min.js",
            +            "modules": {},
            +            "classes": {},
            +            "fors": {},
            +            "namespaces": {}
            +        }
            +    },
            +    "modules": {
            +        "Environment": {
            +            "name": "Environment",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Environment",
            +            "file": "src/accessibility/color_namer.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Color": {
            +            "name": "Color",
            +            "submodules": {
            +                "Color Conversion": 1,
            +                "Creating & Reading": 1,
            +                "Setting": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/color/p5.Color.js",
            +            "line": 14
            +        },
            +        "Color Conversion": {
            +            "name": "Color Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/color_conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Creating & Reading": {
            +            "name": "Creating & Reading",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Color": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ],
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"
            +        },
            +        "Setting": {
            +            "name": "Setting",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Color",
            +            "namespace": "",
            +            "file": "src/color/setting.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Shape": {
            +            "name": "Shape",
            +            "submodules": {
            +                "2D Primitives": 1,
            +                "Curves": 1,
            +                "Vertex": 1,
            +                "3D Primitives": 1,
            +                "3D Models": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1,
            +                "p5.Matrix": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/p5.Matrix.js",
            +            "line": 19
            +        },
            +        "2D Primitives": {
            +            "name": "2D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Attributes": {
            +            "name": "Attributes",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/core/shape/attributes.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Curves": {
            +            "name": "Curves",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/curves.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vertex": {
            +            "name": "Vertex",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Constants": {
            +            "name": "Constants",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Constants",
            +            "file": "src/core/constants.js",
            +            "line": 1
            +        },
            +        "Structure": {
            +            "name": "Structure",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "IO",
            +            "file": "src/core/main.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ]
            +        },
            +        "DOM": {
            +            "name": "DOM",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Element": 1,
            +                "p5.MediaElement": 1,
            +                "p5.File": 1
            +            },
            +            "fors": {
            +                "p5.Element": 1,
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "DOM",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n",
            +            "requires": [
            +                "p5"
            +            ]
            +        },
            +        "Rendering": {
            +            "name": "Rendering",
            +            "submodules": {
            +                "undefined": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.RendererGL": 1,
            +                "p5.Graphics": 1,
            +                "p5.Renderer": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Rendering",
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 603,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"
            +        },
            +        "Foundation": {
            +            "name": "Foundation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "JSON": 1,
            +                "console": 1
            +            },
            +            "namespaces": {},
            +            "module": "Foundation",
            +            "file": "src/core/reference.js",
            +            "line": 1
            +        },
            +        "Transform": {
            +            "name": "Transform",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Transform",
            +            "file": "src/core/transform.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Data": {
            +            "name": "Data",
            +            "submodules": {
            +                "LocalStorage": 1,
            +                "Dictionary": 1,
            +                "Array Functions": 1,
            +                "Conversion": 1,
            +                "String Functions": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.TypedDict": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410
            +        },
            +        "LocalStorage": {
            +            "name": "LocalStorage",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/local_storage.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for working with local storage"
            +            ]
            +        },
            +        "Dictionary": {
            +            "name": "Dictionary",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.TypedDict": 1,
            +                "p5.StringDict": 1,
            +                "p5.NumberDict": 1
            +            },
            +            "fors": {
            +                "p5.TypedDict": 1,
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "requires": [
            +                "core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."
            +            ],
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"
            +        },
            +        "Events": {
            +            "name": "Events",
            +            "submodules": {
            +                "Acceleration": 1,
            +                "Keyboard": 1,
            +                "Mouse": 1,
            +                "Touch": 1
            +            },
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {}
            +        },
            +        "Acceleration": {
            +            "name": "Acceleration",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/acceleration.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Keyboard": {
            +            "name": "Keyboard",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/keyboard.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Mouse": {
            +            "name": "Mouse",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/mouse.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Touch": {
            +            "name": "Touch",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Events",
            +            "namespace": "",
            +            "file": "src/events/touch.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Image": {
            +            "name": "Image",
            +            "submodules": {
            +                "Pixels": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Image": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "module": "Image",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"
            +        },
            +        "Loading & Displaying": {
            +            "name": "Loading & Displaying",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Typography",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"
            +        },
            +        "Pixels": {
            +            "name": "Pixels",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Image",
            +            "namespace": "",
            +            "file": "src/image/pixels.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "IO": {
            +            "name": "IO",
            +            "submodules": {
            +                "Structure": 1,
            +                "Input": 1,
            +                "Output": 1,
            +                "Table": 1,
            +                "Time & Date": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1,
            +                "p5.Table": 1,
            +                "p5.TableRow": 1,
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/io/p5.XML.js",
            +            "line": 9
            +        },
            +        "Input": {
            +            "name": "Input",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.XML": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"
            +        },
            +        "Output": {
            +            "name": "Output",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5": 1,
            +                "p5.PrintWriter": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"
            +        },
            +        "Table": {
            +            "name": "Table",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Table": 1,
            +                "p5.TableRow": 1
            +            },
            +            "fors": {},
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"
            +        },
            +        "Math": {
            +            "name": "Math",
            +            "submodules": {
            +                "Calculation": 1,
            +                "Vector": 1,
            +                "Noise": 1,
            +                "Random": 1,
            +                "Trigonometry": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10
            +        },
            +        "Calculation": {
            +            "name": "Calculation",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/calculation.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Vector": {
            +            "name": "Vector",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Vector": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"
            +        },
            +        "Noise": {
            +            "name": "Noise",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/noise.js",
            +            "line": 14,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Random": {
            +            "name": "Random",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/random.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Trigonometry": {
            +            "name": "Trigonometry",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Math",
            +            "namespace": "",
            +            "file": "src/math/trigonometry.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "constants"
            +            ]
            +        },
            +        "Typography": {
            +            "name": "Typography",
            +            "submodules": {
            +                "Attributes": 1,
            +                "Loading & Displaying": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Font": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13
            +        },
            +        "Array Functions": {
            +            "name": "Array Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/array_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Conversion": {
            +            "name": "Conversion",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/conversion.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "String Functions": {
            +            "name": "String Functions",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Data",
            +            "namespace": "",
            +            "file": "src/utilities/string_functions.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Time & Date": {
            +            "name": "Time & Date",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "IO",
            +            "namespace": "",
            +            "file": "src/utilities/time_date.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Primitives": {
            +            "name": "3D Primitives",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Geometry": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ],
            +            "description": "<p>p5 Geometry class</p>\n"
            +        },
            +        "3D": {
            +            "name": "3D",
            +            "submodules": {
            +                "Interaction": 1,
            +                "Lights": 1,
            +                "Material": 1,
            +                "Camera": 1
            +            },
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1,
            +                "p5.Shader": 1,
            +                "p5.Texture": 1,
            +                "ImageInfos": 1,
            +                "FontInfo": 1,
            +                "Cubic": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "namespaces": {},
            +            "file": "src/webgl/text.js",
            +            "line": 260
            +        },
            +        "Interaction": {
            +            "name": "Interaction",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/interaction.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "Lights": {
            +            "name": "Lights",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/light.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ]
            +        },
            +        "3D Models": {
            +            "name": "3D Models",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {},
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "Shape",
            +            "namespace": "",
            +            "file": "src/webgl/loading.js",
            +            "line": 1,
            +            "requires": [
            +                "core",
            +                "p5.Geometry"
            +            ]
            +        },
            +        "Material": {
            +            "name": "Material",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Shader": 1,
            +                "p5.Texture": 1
            +            },
            +            "fors": {
            +                "p5": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Texture.js",
            +            "line": 12,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This module defines the p5.Shader class</p>\n"
            +        },
            +        "Camera": {
            +            "name": "Camera",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.Camera": 1
            +            },
            +            "fors": {
            +                "p5": 1,
            +                "p5.Camera": 1
            +            },
            +            "is_submodule": 1,
            +            "namespaces": {},
            +            "module": "3D",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "requires": [
            +                "core"
            +            ],
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "submodules": {},
            +            "elements": {},
            +            "classes": {
            +                "p5.sound": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.SinOsc": 1,
            +                "p5.TriOsc": 1,
            +                "p5.SawOsc": 1,
            +                "p5.SqrOsc": 1,
            +                "p5.Envelope": 1,
            +                "p5.Noise": 1,
            +                "p5.Pulse": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.Filter": 1,
            +                "p5.LowPass": 1,
            +                "p5.HighPass": 1,
            +                "p5.BandPass": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Phrase": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.PeakDetect": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.OnsetDetect": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "fors": {
            +                "p5.sound": 1,
            +                "p5": 1,
            +                "p5.SoundFile": 1,
            +                "p5.Amplitude": 1,
            +                "p5.FFT": 1,
            +                "p5.Oscillator": 1,
            +                "p5.Envelope": 1,
            +                "p5.AudioIn": 1,
            +                "p5.Effect": 1,
            +                "p5.EQ": 1,
            +                "p5.Panner3D": 1,
            +                "p5.Delay": 1,
            +                "p5.Reverb": 1,
            +                "p5.Convolver": 1,
            +                "p5.Part": 1,
            +                "p5.Score": 1,
            +                "p5.SoundLoop": 1,
            +                "p5.Compressor": 1,
            +                "p5.SoundRecorder": 1,
            +                "p5.Distortion": 1,
            +                "p5.Gain": 1,
            +                "p5.AudioVoice": 1,
            +                "p5.MonoSynth": 1,
            +                "p5.PolySynth": 1
            +            },
            +            "namespaces": {},
            +            "module": "p5.sound",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>",
            +            "tag": "main",
            +            "itemtype": "main"
            +        }
            +    },
            +    "classes": {
            +        "p5": {
            +            "name": "p5",
            +            "shortname": "p5",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/core/main.js",
            +            "line": 13,
            +            "description": "<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>element to attach canvas to</p>\n",
            +                    "type": "HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a p5 instance",
            +                "type": "P5"
            +            }
            +        },
            +        "p5.Color": {
            +            "name": "p5.Color",
            +            "shortname": "p5.Color",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "namespace": "",
            +            "file": "src/color/p5.Color.js",
            +            "line": 14,
            +            "description": "<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Element": {
            +            "name": "p5.Element",
            +            "shortname": "p5.Element",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/core/p5.Element.js",
            +            "line": 9,
            +            "description": "<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Graphics": {
            +            "name": "p5.Graphics",
            +            "shortname": "p5.Graphics",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 10,
            +            "description": "<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>the renderer to use, either P2D or WEBGL</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Renderer": {
            +            "name": "p5.Renderer",
            +            "shortname": "p5.Renderer",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "namespace": "",
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 10,
            +            "description": "<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Element",
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isMainCanvas",
            +                    "description": "<p>whether we're using it as main canvas</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "JSON": {
            +            "name": "JSON",
            +            "shortname": "JSON",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "console": {
            +            "name": "console",
            +            "shortname": "console",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Foundation",
            +            "submodule": "Foundation",
            +            "namespace": ""
            +        },
            +        "p5.TypedDict": {
            +            "name": "p5.TypedDict",
            +            "shortname": "p5.TypedDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 82,
            +            "description": "<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.StringDict": {
            +            "name": "p5.StringDict",
            +            "shortname": "p5.StringDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 394,
            +            "description": "<p>A simple Dictionary class for Strings.</p>\n",
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.NumberDict": {
            +            "name": "p5.NumberDict",
            +            "shortname": "p5.NumberDict",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "namespace": "",
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 410,
            +            "description": "<p>A simple Dictionary class for Numbers.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.TypedDict"
            +        },
            +        "p5.MediaElement": {
            +            "name": "p5.MediaElement",
            +            "shortname": "p5.MediaElement",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 2377,
            +            "description": "<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "elt",
            +                    "description": "<p>DOM node that is wrapped</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.File": {
            +            "name": "p5.File",
            +            "shortname": "p5.File",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "namespace": "",
            +            "file": "src/dom/dom.js",
            +            "line": 3533,
            +            "description": "<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>File that is wrapped</p>\n",
            +                    "type": "File"
            +                }
            +            ]
            +        },
            +        "p5.Image": {
            +            "name": "p5.Image",
            +            "shortname": "p5.Image",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Image",
            +            "submodule": "Image",
            +            "namespace": "",
            +            "file": "src/image/p5.Image.js",
            +            "line": 21,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"
            +            ],
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ]
            +        },
            +        "p5.PrintWriter": {
            +            "name": "p5.PrintWriter",
            +            "shortname": "p5.PrintWriter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Output",
            +            "namespace": "",
            +            "file": "src/io/files.js",
            +            "line": 1200,
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Table": {
            +            "name": "p5.Table",
            +            "shortname": "p5.Table",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.Table.js",
            +            "line": 33,
            +            "description": "<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "rows",
            +                    "description": "<p>An array of p5.TableRow objects</p>\n",
            +                    "type": "p5.TableRow[]",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TableRow": {
            +            "name": "p5.TableRow",
            +            "shortname": "p5.TableRow",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Table",
            +            "namespace": "",
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 9,
            +            "description": "<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>comma separated values (csv) by default</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.XML": {
            +            "name": "p5.XML",
            +            "shortname": "p5.XML",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "IO",
            +            "submodule": "Input",
            +            "namespace": "",
            +            "file": "src/io/p5.XML.js",
            +            "line": 9,
            +            "description": "<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed"
            +        },
            +        "p5.Vector": {
            +            "name": "p5.Vector",
            +            "shortname": "p5.Vector",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "namespace": "",
            +            "file": "src/math/p5.Vector.js",
            +            "line": 10,
            +            "description": "<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "2 white ellipses. One center-left the other bottom right and off canvas"
            +        },
            +        "p5.Font": {
            +            "name": "p5.Font",
            +            "shortname": "p5.Font",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "namespace": "",
            +            "file": "src/typography/p5.Font.js",
            +            "line": 13,
            +            "description": "<p>Base class for font handling</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "pInst",
            +                    "description": "<p>pointer to p5 instance</p>\n",
            +                    "type": "P5",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Camera": {
            +            "name": "p5.Camera",
            +            "shortname": "p5.Camera",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Camera",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 357,
            +            "description": "<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n",
            +            "params": [
            +                {
            +                    "name": "rendererGL",
            +                    "description": "<p>instance of WebGL renderer</p>\n",
            +                    "type": "RendererGL"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes."
            +        },
            +        "p5.Geometry": {
            +            "name": "p5.Geometry",
            +            "shortname": "p5.Geometry",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "Shape",
            +            "submodule": "3D Primitives",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 12,
            +            "description": "<p>p5 Geometry class</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of vertices along the x-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of vertices along the y-axis.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call upon object instantiation.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Shader": {
            +            "name": "p5.Shader",
            +            "shortname": "p5.Shader",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "3D",
            +            "submodule": "Material",
            +            "namespace": "",
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 11,
            +            "description": "<p>Shader class for WEBGL Mode</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n",
            +                    "type": "p5.RendererGL"
            +                },
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader (as a string)</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader (as a string)</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.sound": {
            +            "name": "p5.sound",
            +            "shortname": "p5.sound",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": ""
            +        },
            +        "p5.SoundFile": {
            +            "name": "p5.SoundFile",
            +            "shortname": "p5.SoundFile",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1405,
            +            "description": "<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoadingCallback",
            +                    "description": "<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"
            +            ]
            +        },
            +        "p5.Amplitude": {
            +            "name": "p5.Amplitude",
            +            "shortname": "p5.Amplitude",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3022,
            +            "description": "<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.FFT": {
            +            "name": "p5.FFT",
            +            "shortname": "p5.FFT",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3347,
            +            "description": "<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Oscillator": {
            +            "name": "p5.Oscillator",
            +            "shortname": "p5.Oscillator",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4060,
            +            "description": "<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>frequency defaults to 440Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"
            +            ]
            +        },
            +        "p5.SinOsc": {
            +            "name": "p5.SinOsc",
            +            "shortname": "p5.SinOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4602,
            +            "description": "<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.TriOsc": {
            +            "name": "p5.TriOsc",
            +            "shortname": "p5.TriOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4629,
            +            "description": "<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SawOsc": {
            +            "name": "p5.SawOsc",
            +            "shortname": "p5.SawOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4656,
            +            "description": "<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.SqrOsc": {
            +            "name": "p5.SqrOsc",
            +            "shortname": "p5.SqrOsc",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4683,
            +            "description": "<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Oscillator",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Set the frequency</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Envelope": {
            +            "name": "p5.Envelope",
            +            "shortname": "p5.Envelope",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4721,
            +            "description": "<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Noise": {
            +            "name": "p5.Noise",
            +            "shortname": "p5.Noise",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5620,
            +            "description": "<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n",
            +                    "type": "String"
            +                }
            +            ]
            +        },
            +        "p5.Pulse": {
            +            "name": "p5.Pulse",
            +            "shortname": "p5.Pulse",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5779,
            +            "description": "<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n",
            +            "extends": "p5.Oscillator",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in oscillations per second (Hz)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioIn": {
            +            "name": "p5.AudioIn",
            +            "shortname": "p5.AudioIn",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6015,
            +            "description": "<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Effect": {
            +            "name": "p5.Effect",
            +            "shortname": "p5.Effect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6423,
            +            "description": "<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "ac",
            +                    "description": "<p>Reference to the audio context of the p5 object</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "input",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "output",
            +                    "description": "<p>Gain Node effect wrapper</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "_drywet",
            +                    "description": "<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "wet",
            +                    "description": "<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n",
            +                    "type": "AudioNode",
            +                    "optional": true
            +                }
            +            ]
            +        },
            +        "p5.Filter": {
            +            "name": "p5.Filter",
            +            "shortname": "p5.Filter",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6628,
            +            "description": "<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"
            +            ]
            +        },
            +        "p5.LowPass": {
            +            "name": "p5.LowPass",
            +            "shortname": "p5.LowPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6914,
            +            "description": "<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.HighPass": {
            +            "name": "p5.HighPass",
            +            "shortname": "p5.HighPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6938,
            +            "description": "<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.BandPass": {
            +            "name": "p5.BandPass",
            +            "shortname": "p5.BandPass",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6962,
            +            "description": "<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Filter"
            +        },
            +        "p5.EQ": {
            +            "name": "p5.EQ",
            +            "shortname": "p5.EQ",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7105,
            +            "description": "<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect",
            +            "params": [
            +                {
            +                    "name": "_eqsize",
            +                    "description": "<p>Constructor will accept 3 or 8, defaults to 3</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "p5.EQ object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Panner3D": {
            +            "name": "p5.Panner3D",
            +            "shortname": "p5.Panner3D",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7602,
            +            "description": "<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.Delay": {
            +            "name": "p5.Delay",
            +            "shortname": "p5.Delay",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7926,
            +            "description": "<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Reverb": {
            +            "name": "p5.Reverb",
            +            "shortname": "p5.Reverb",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8308,
            +            "description": "<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Convolver": {
            +            "name": "p5.Convolver",
            +            "shortname": "p5.Convolver",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8549,
            +            "description": "<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when loading succeeds</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Phrase": {
            +            "name": "p5.Phrase",
            +            "shortname": "p5.Phrase",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9103,
            +            "description": "<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>Name so that you can access the Phrase.</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Part": {
            +            "name": "p5.Part",
            +            "shortname": "p5.Part",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9185,
            +            "description": "<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "steps",
            +                    "description": "<p>Steps in the part</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tatums",
            +                    "description": "<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Score": {
            +            "name": "p5.Score",
            +            "shortname": "p5.Score",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9493,
            +            "description": "<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "parts",
            +                    "description": "<p>One or multiple parts, to be played in sequence.</p>\n",
            +                    "type": "p5.Part",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ]
            +        },
            +        "p5.SoundLoop": {
            +            "name": "p5.SoundLoop",
            +            "shortname": "p5.SoundLoop",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9673,
            +            "description": "<p>SoundLoop</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>this function will be called on each iteration of theloop</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "interval",
            +                    "description": "<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n",
            +                    "type": "Number|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.Compressor": {
            +            "name": "p5.Compressor",
            +            "shortname": "p5.Compressor",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10036,
            +            "description": "<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "is_constructor": 1,
            +            "extends": "p5.Effect"
            +        },
            +        "p5.PeakDetect": {
            +            "name": "p5.PeakDetect",
            +            "shortname": "p5.PeakDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10312,
            +            "description": "<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freq1",
            +                    "description": "<p>lowFrequency - defaults to 20Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "freq2",
            +                    "description": "<p>highFrequency - defaults to 20000 Hz</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "framesPerPeak",
            +                    "description": "<p>Defaults to 20.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.SoundRecorder": {
            +            "name": "p5.SoundRecorder",
            +            "shortname": "p5.SoundRecorder",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10559,
            +            "description": "<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"
            +            ]
            +        },
            +        "p5.Distortion": {
            +            "name": "p5.Distortion",
            +            "shortname": "p5.Distortion",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10816,
            +            "description": "<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n",
            +            "extends": "p5.Effect",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ]
            +        },
            +        "p5.Gain": {
            +            "name": "p5.Gain",
            +            "shortname": "p5.Gain",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10973,
            +            "description": "<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.AudioVoice": {
            +            "name": "p5.AudioVoice",
            +            "shortname": "p5.AudioVoice",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11149,
            +            "description": "<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n",
            +            "is_constructor": 1
            +        },
            +        "p5.MonoSynth": {
            +            "name": "p5.MonoSynth",
            +            "shortname": "p5.MonoSynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11247,
            +            "description": "<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n",
            +            "is_constructor": 1,
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"
            +            ]
            +        },
            +        "p5.OnsetDetect": {
            +            "name": "p5.OnsetDetect",
            +            "shortname": "p5.OnsetDetect",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11624,
            +            "description": "<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "freqLow",
            +                    "description": "<p>Low frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "freqHigh",
            +                    "description": "<p>High frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Function to call when an onset is detected</p>\n",
            +                    "type": "Function"
            +                }
            +            ]
            +        },
            +        "p5.PolySynth": {
            +            "name": "p5.PolySynth",
            +            "shortname": "p5.PolySynth",
            +            "classitems": [],
            +            "plugins": [],
            +            "extensions": [],
            +            "plugin_for": [],
            +            "extension_for": [],
            +            "module": "p5.sound",
            +            "submodule": "p5.sound",
            +            "namespace": "",
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11691,
            +            "description": "<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "synthVoice",
            +                    "description": "<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "maxVoices",
            +                    "description": "<p>Number of voices, defaults to 8;</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ]
            +        }
            +    },
            +    "elements": {},
            +    "classitems": [
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 18,
            +            "description": "<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describe",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the canvas</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/describe.js",
            +            "line": 114,
            +            "description": "<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "describeElement",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "text",
            +                    "description": "<p>description of the element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "display",
            +                    "description": "<p>either LABEL or FALLBACK</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 10,
            +            "description": "<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "textOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/accessibility/outputs.js",
            +            "line": 88,
            +            "description": "<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n",
            +            "itemtype": "method",
            +            "name": "gridOutput",
            +            "params": [
            +                {
            +                    "name": "display",
            +                    "description": "<p>either FALLBACK or LABEL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 8,
            +            "description": "<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 19,
            +            "description": "<p>Convert an HSBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 45,
            +            "description": "<p>Convert an HSBA array to RGBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 100,
            +            "description": "<p>Convert an HSLA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 123,
            +            "description": "<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 187,
            +            "description": "<p>Convert an RGBA array to HSBA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/color_conversion.js",
            +            "line": 226,
            +            "description": "<p>Convert an RGBA array to HSLA.</p>\n",
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Color Conversion"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 16,
            +            "description": "<p>Extracts the alpha value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "alpha",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the alpha value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 43,
            +            "description": "<p>Extracts the blue value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "blue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the blue value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 69,
            +            "description": "<p>Extracts the HSB brightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "brightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the brightness value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 113,
            +            "description": "<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n",
            +            "itemtype": "method",
            +            "name": "color",
            +            "return": {
            +                "description": "resulting color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading",
            +            "overloads": [
            +                {
            +                    "line": 113,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "resulting color",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 257,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 269,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                },
            +                {
            +                    "line": 282,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Color"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 297,
            +            "description": "<p>Extracts the green value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "green",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the green value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 325,
            +            "description": "<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n",
            +            "itemtype": "method",
            +            "name": "hue",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the hue",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 359,
            +            "description": "<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerpColor",
            +            "params": [
            +                {
            +                    "name": "c1",
            +                    "description": "<p>interpolate from this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "c2",
            +                    "description": "<p>interpolate to this color</p>\n",
            +                    "type": "p5.Color"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "interpolated color",
            +                "type": "p5.Color"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 449,
            +            "description": "<p>Extracts the HSL lightness value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "lightness",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the lightness",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 478,
            +            "description": "<p>Extracts the red value from a color or pixel array.</p>\n",
            +            "itemtype": "method",
            +            "name": "red",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the red value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/creating_reading.js",
            +            "line": 517,
            +            "description": "<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n",
            +            "itemtype": "method",
            +            "name": "saturation",
            +            "params": [
            +                {
            +                    "name": "color",
            +                    "description": "<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n",
            +                    "type": "p5.Color|Number[]|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the saturation value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 51,
            +            "description": "<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "params": [
            +                {
            +                    "name": "format",
            +                    "description": "<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the formatted string",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 254,
            +            "description": "<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRed",
            +            "params": [
            +                {
            +                    "name": "red",
            +                    "description": "<p>the new red value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 281,
            +            "description": "<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setGreen",
            +            "params": [
            +                {
            +                    "name": "green",
            +                    "description": "<p>the new green value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 304,
            +            "description": "<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBlue",
            +            "params": [
            +                {
            +                    "name": "blue",
            +                    "description": "<p>the new blue value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 327,
            +            "description": "<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAlpha",
            +            "params": [
            +                {
            +                    "name": "alpha",
            +                    "description": "<p>the new alpha value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 396,
            +            "description": "<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 427,
            +            "description": "<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 446,
            +            "description": "<p>CSS named colors.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 600,
            +            "description": "<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 613,
            +            "description": "<p>Full color string patterns. The capture groups are necessary.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/p5.Color.js",
            +            "line": 960,
            +            "description": "<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n",
            +            "class": "p5.Color",
            +            "module": "Color",
            +            "submodule": "Creating & Reading"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 13,
            +            "description": "<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n",
            +            "itemtype": "method",
            +            "name": "background",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "colorstring",
            +                            "description": "<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 140,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>specifies a value between white and black</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 147,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current color\n                       mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value (depending on the current\n                       color mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 159,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 166,
            +                    "params": [
            +                        {
            +                            "name": "image",
            +                            "description": "<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 179,
            +            "description": "<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"
            +            ],
            +            "params": [
            +                {
            +                    "name": "r",
            +                    "description": "<p>normalized red val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "g",
            +                    "description": "<p>normalized green val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>normalized blue val.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>normalized alpha val.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 229,
            +            "description": "<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n",
            +            "itemtype": "method",
            +            "name": "colorMode",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 229,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>range for all values</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 306,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "max1",
            +                            "description": "<p>range for the red or hue depending on the\n                             current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max2",
            +                            "description": "<p>range for the green or saturation depending\n                             on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "max3",
            +                            "description": "<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "maxA",
            +                            "description": "<p>range for the alpha</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 350,
            +            "description": "<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n",
            +            "itemtype": "method",
            +            "name": "fill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 350,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 475,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 488,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 495,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the fill color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 507,
            +            "description": "<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noFill",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 547,
            +            "description": "<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "noStroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 585,
            +            "description": "<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n",
            +            "itemtype": "method",
            +            "name": "stroke",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting",
            +            "overloads": [
            +                {
            +                    "line": 585,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 722,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 728,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 735,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 742,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the stroke color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 755,
            +            "description": "<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n",
            +            "itemtype": "method",
            +            "name": "erase",
            +            "params": [
            +                {
            +                    "name": "strengthFill",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "strengthStroke",
            +                    "description": "<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/color/setting.js",
            +            "line": 836,
            +            "description": "<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "noErase",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Color",
            +            "submodule": "Setting"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 1,
            +            "requires": [
            +                "core\n\nThis is the main file for the Friendly Error System (FES)",
            +                "containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters",
            +                "(2) _friendlyFileLoadError",
            +                "(3) _friendlyError",
            +                "(4) helpForMisusedAtTopLevelCode",
            +                "or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this",
            +                "there's also a file stacktrace.js",
            +                "which contains the code\nto parse the error stack",
            +                "borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions",
            +                "including the call\nsequence of each function",
            +                "please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/fes_core.js",
            +            "line": 915,
            +            "description": "<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n",
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/file_errors.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/sketch_reader.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/stacktrace.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/friendly_errors/validate_params.js",
            +            "line": 1,
            +            "requires": [
            +                "core"
            +            ],
            +            "class": "p5",
            +            "module": "Color"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 16,
            +            "description": "<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 102,
            +            "description": "<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n",
            +            "itemtype": "method",
            +            "name": "arc",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the arc's ellipse</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the arc's ellipse by default</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>angle to start the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>angle to stop the arc, specified in radians</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "mode",
            +                    "description": "<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detail",
            +                    "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 235,
            +            "description": "<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipse",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 235,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the center of ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the ellipse.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the ellipse.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 261,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detail",
            +                            "description": "<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 277,
            +            "description": "<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n",
            +            "itemtype": "method",
            +            "name": "circle",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the centre of the circle.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>diameter of the circle.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 340,
            +            "description": "<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "line",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 340,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 404,
            +            "description": "<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "point",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 404,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z-coordinate (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 455,
            +                    "params": [
            +                        {
            +                            "name": "coordinate_vector",
            +                            "description": "<p>the coordinate vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 483,
            +            "description": "<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "quad",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 483,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>the x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>the y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>the x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>the y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>the x-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>the y-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>the x-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>the y-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>the z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>the z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>the z-coordinate of the third point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>the z-coordinate of the fourth point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 556,
            +            "description": "<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "rect",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives",
            +            "overloads": [
            +                {
            +                    "line": 556,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the rectangle.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the rectangle.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tl",
            +                            "description": "<p>optional radius of top-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "tr",
            +                            "description": "<p>optional radius of top-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "br",
            +                            "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "bl",
            +                            "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 608,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "detailX",
            +                            "description": "<p>number of segments in the x-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "detailY",
            +                            "description": "<p>number of segments in the y-direction (for WebGL mode)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 623,
            +            "description": "<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n",
            +            "itemtype": "method",
            +            "name": "square",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "s",
            +                    "description": "<p>side size of the square.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "tl",
            +                    "description": "<p>optional radius of top-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tr",
            +                    "description": "<p>optional radius of top-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "br",
            +                    "description": "<p>optional radius of bottom-right corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bl",
            +                    "description": "<p>optional radius of bottom-left corner.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/2d_primitives.js",
            +            "line": 713,
            +            "description": "<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n",
            +            "itemtype": "method",
            +            "name": "triangle",
            +            "params": [
            +                {
            +                    "name": "x1",
            +                    "description": "<p>x-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y1",
            +                    "description": "<p>y-coordinate of the first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>x-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>y-coordinate of the second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x3",
            +                    "description": "<p>x-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y3",
            +                    "description": "<p>y-coordinate of the third point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "2D Primitives"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 12,
            +            "description": "<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipseMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 81,
            +            "description": "<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "noSmooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses to left & right of center, black background",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 115,
            +            "description": "<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "rectMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 184,
            +            "description": "<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"
            +            ],
            +            "alt": "2 pixelated 36×36 white ellipses one left one right of center. On black.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 219,
            +            "description": "<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeCap",
            +            "params": [
            +                {
            +                    "name": "cap",
            +                    "description": "<p>either ROUND, SQUARE or PROJECT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 259,
            +            "description": "<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeJoin",
            +            "params": [
            +                {
            +                    "name": "join",
            +                    "description": "<p>either MITER, BEVEL, ROUND</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/attributes.js",
            +            "line": 331,
            +            "description": "<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n",
            +            "itemtype": "method",
            +            "name": "strokeWeight",
            +            "params": [
            +                {
            +                    "name": "weight",
            +                    "description": "<p>the weight of the stroke (in pixels)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"
            +            ],
            +            "alt": "3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 13,
            +            "description": "<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezier",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 13,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 62,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the first anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the second anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 92,
            +            "description": "<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierDetail",
            +            "params": [
            +                {
            +                    "name": "detail",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "stretched black s-shape with a low level of bezier detail",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 130,
            +            "description": "<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierPoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value of the Bezier at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "10 points plotted on a given bezier at equal distances.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 185,
            +            "description": "<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 264,
            +            "description": "<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curve",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"
            +            ],
            +            "alt": "horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves",
            +            "overloads": [
            +                {
            +                    "line": 264,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 332,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate for the beginning control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the ending control point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 358,
            +            "description": "<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveDetail",
            +            "params": [
            +                {
            +                    "name": "resolution",
            +                    "description": "<p>resolution of the curves</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white arch shape with a low level of curve detail.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 398,
            +            "description": "<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTightness",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>amount of deformation from the original vertices</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Line shaped like right-facing arrow,points move with mouse-x and warp shape.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 444,
            +            "description": "<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n",
            +            "itemtype": "method",
            +            "name": "curvePoint",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point of the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "bezier value at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/curves.js",
            +            "line": 493,
            +            "description": "<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveTangent",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>coordinate of first control point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>coordinate of first point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>coordinate of second point on the curve</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>coordinate of second conrol point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "t",
            +                    "description": "<p>value between 0 and 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent at position t",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "right curving line mid-right of canvas with 7 short lines radiating from it.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Curves"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 20,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 67,
            +            "description": "<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "beginShape",
            +            "params": [
            +                {
            +                    "name": "kind",
            +                    "description": "<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 293,
            +            "description": "<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "bezierVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate for the first control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the second control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 375,
            +                    "params": [
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate for the first control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the second control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y4",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z4",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 415,
            +            "description": "<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n",
            +            "itemtype": "method",
            +            "name": "curveVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Upside-down u-shape line, mid canvas. left point extends beyond canvas view.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 415,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 460,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex (for WebGL mode)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 524,
            +            "description": "<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n",
            +            "itemtype": "method",
            +            "name": "endContour",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"
            +            ],
            +            "alt": "white rect and smaller grey rect with red outlines in center of canvas.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 583,
            +            "description": "<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n",
            +            "itemtype": "method",
            +            "name": "endShape",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>use CLOSE to close the shape</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "Triangle line shape with smallest interior angle on bottom and upside-down L.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex"
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 668,
            +            "description": "<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "quadraticVertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"
            +            ],
            +            "alt": "arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 668,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "<p>x-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "<p>y-coordinate for the control point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "<p>x-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "<p>y-coordinate for the anchor point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 733,
            +                    "params": [
            +                        {
            +                            "name": "cx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cy",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "cz",
            +                            "description": "<p>z-coordinate for the control point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z3",
            +                            "description": "<p>z-coordinate for the anchor point (for WebGL mode)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 826,
            +            "description": "<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "vertex",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 826,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the vertex</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 957,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 965,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "u",
            +                            "description": "<p>the vertex's texture u-coordinate</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vertex's texture v-coordinate</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/shape/vertex.js",
            +            "line": 1003,
            +            "description": "<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n",
            +            "itemtype": "method",
            +            "name": "normal",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "Vertex",
            +            "overloads": [
            +                {
            +                    "line": 1003,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>A p5.Vector representing the vertex normal.</p>\n",
            +                            "type": "Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1040,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The x component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The y component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The z component of the vertex normal.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 9,
            +            "description": "<p>Version of this p5.js.</p>\n",
            +            "itemtype": "property",
            +            "name": "VERSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 18,
            +            "description": "<p>The default, two-dimensional renderer.</p>\n",
            +            "itemtype": "property",
            +            "name": "P2D",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 24,
            +            "description": "<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n",
            +            "itemtype": "property",
            +            "name": "WEBGL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 33,
            +            "itemtype": "property",
            +            "name": "ARROW",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 38,
            +            "itemtype": "property",
            +            "name": "CROSS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 43,
            +            "itemtype": "property",
            +            "name": "HAND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 48,
            +            "itemtype": "property",
            +            "name": "MOVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 53,
            +            "itemtype": "property",
            +            "name": "TEXT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 58,
            +            "itemtype": "property",
            +            "name": "WAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 66,
            +            "description": "<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HALF_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white quarter-circle with curve toward bottom right of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 84,
            +            "description": "<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"
            +            ],
            +            "alt": "white half-circle with curve toward bottom of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 102,
            +            "description": "<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "QUARTER_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"
            +            ],
            +            "alt": "white eighth-circle rotated about 40 degrees with curve bottom right canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 120,
            +            "description": "<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TAU",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 138,
            +            "description": "<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "TWO_PI",
            +            "type": "Number",
            +            "final": 1,
            +            "example": [
            +                "\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"
            +            ],
            +            "alt": "80×80 white ellipse shape in center of canvas.",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 156,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n",
            +            "itemtype": "property",
            +            "name": "DEGREES",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 170,
            +            "description": "<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n",
            +            "itemtype": "property",
            +            "name": "RADIANS",
            +            "type": "String",
            +            "final": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 188,
            +            "itemtype": "property",
            +            "name": "CORNER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 193,
            +            "itemtype": "property",
            +            "name": "CORNERS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 198,
            +            "itemtype": "property",
            +            "name": "RADIUS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 203,
            +            "itemtype": "property",
            +            "name": "RIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 208,
            +            "itemtype": "property",
            +            "name": "LEFT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 213,
            +            "itemtype": "property",
            +            "name": "CENTER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 218,
            +            "itemtype": "property",
            +            "name": "TOP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 223,
            +            "itemtype": "property",
            +            "name": "BOTTOM",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 228,
            +            "itemtype": "property",
            +            "name": "BASELINE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "alphabetic",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 234,
            +            "itemtype": "property",
            +            "name": "POINTS",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0000",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 240,
            +            "itemtype": "property",
            +            "name": "LINES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0001",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 246,
            +            "itemtype": "property",
            +            "name": "LINE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0003",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 252,
            +            "itemtype": "property",
            +            "name": "LINE_LOOP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0002",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 258,
            +            "itemtype": "property",
            +            "name": "TRIANGLES",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0004",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 264,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_FAN",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0006",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 270,
            +            "itemtype": "property",
            +            "name": "TRIANGLE_STRIP",
            +            "type": "Number",
            +            "final": 1,
            +            "default": "0x0005",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 276,
            +            "itemtype": "property",
            +            "name": "QUADS",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 281,
            +            "itemtype": "property",
            +            "name": "QUAD_STRIP",
            +            "type": "String",
            +            "final": 1,
            +            "default": "quad_strip",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 287,
            +            "itemtype": "property",
            +            "name": "TESS",
            +            "type": "String",
            +            "final": 1,
            +            "default": "tess",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 293,
            +            "itemtype": "property",
            +            "name": "CLOSE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 298,
            +            "itemtype": "property",
            +            "name": "OPEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 303,
            +            "itemtype": "property",
            +            "name": "CHORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 308,
            +            "itemtype": "property",
            +            "name": "PIE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 313,
            +            "itemtype": "property",
            +            "name": "PROJECT",
            +            "type": "String",
            +            "final": 1,
            +            "default": "square",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 319,
            +            "itemtype": "property",
            +            "name": "SQUARE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "butt",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 325,
            +            "itemtype": "property",
            +            "name": "ROUND",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 330,
            +            "itemtype": "property",
            +            "name": "BEVEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 335,
            +            "itemtype": "property",
            +            "name": "MITER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 342,
            +            "itemtype": "property",
            +            "name": "RGB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 347,
            +            "description": "<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "HSB",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 356,
            +            "itemtype": "property",
            +            "name": "HSL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 363,
            +            "description": "<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n",
            +            "itemtype": "property",
            +            "name": "AUTO",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 373,
            +            "itemtype": "property",
            +            "name": "ALT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 379,
            +            "itemtype": "property",
            +            "name": "BACKSPACE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 384,
            +            "itemtype": "property",
            +            "name": "CONTROL",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 389,
            +            "itemtype": "property",
            +            "name": "DELETE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 394,
            +            "itemtype": "property",
            +            "name": "DOWN_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 399,
            +            "itemtype": "property",
            +            "name": "ENTER",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 404,
            +            "itemtype": "property",
            +            "name": "ESCAPE",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 409,
            +            "itemtype": "property",
            +            "name": "LEFT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 414,
            +            "itemtype": "property",
            +            "name": "OPTION",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 419,
            +            "itemtype": "property",
            +            "name": "RETURN",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 424,
            +            "itemtype": "property",
            +            "name": "RIGHT_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 429,
            +            "itemtype": "property",
            +            "name": "SHIFT",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 434,
            +            "itemtype": "property",
            +            "name": "TAB",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 439,
            +            "itemtype": "property",
            +            "name": "UP_ARROW",
            +            "type": "Number",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 446,
            +            "itemtype": "property",
            +            "name": "BLEND",
            +            "type": "String",
            +            "final": 1,
            +            "default": "source-over",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 452,
            +            "itemtype": "property",
            +            "name": "REMOVE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "destination-out",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 458,
            +            "itemtype": "property",
            +            "name": "ADD",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighter",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 466,
            +            "itemtype": "property",
            +            "name": "DARKEST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 471,
            +            "itemtype": "property",
            +            "name": "LIGHTEST",
            +            "type": "String",
            +            "final": 1,
            +            "default": "lighten",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 477,
            +            "itemtype": "property",
            +            "name": "DIFFERENCE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 482,
            +            "itemtype": "property",
            +            "name": "SUBTRACT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 487,
            +            "itemtype": "property",
            +            "name": "EXCLUSION",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 492,
            +            "itemtype": "property",
            +            "name": "MULTIPLY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 497,
            +            "itemtype": "property",
            +            "name": "SCREEN",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 502,
            +            "itemtype": "property",
            +            "name": "REPLACE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "copy",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 508,
            +            "itemtype": "property",
            +            "name": "OVERLAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 513,
            +            "itemtype": "property",
            +            "name": "HARD_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 518,
            +            "itemtype": "property",
            +            "name": "SOFT_LIGHT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 523,
            +            "itemtype": "property",
            +            "name": "DODGE",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-dodge",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 529,
            +            "itemtype": "property",
            +            "name": "BURN",
            +            "type": "String",
            +            "final": 1,
            +            "default": "color-burn",
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 537,
            +            "itemtype": "property",
            +            "name": "THRESHOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 542,
            +            "itemtype": "property",
            +            "name": "GRAY",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 547,
            +            "itemtype": "property",
            +            "name": "OPAQUE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 552,
            +            "itemtype": "property",
            +            "name": "INVERT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 557,
            +            "itemtype": "property",
            +            "name": "POSTERIZE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 562,
            +            "itemtype": "property",
            +            "name": "DILATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 567,
            +            "itemtype": "property",
            +            "name": "ERODE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 572,
            +            "itemtype": "property",
            +            "name": "BLUR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 579,
            +            "itemtype": "property",
            +            "name": "NORMAL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 584,
            +            "itemtype": "property",
            +            "name": "ITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 589,
            +            "itemtype": "property",
            +            "name": "BOLD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 594,
            +            "itemtype": "property",
            +            "name": "BOLDITALIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 599,
            +            "itemtype": "property",
            +            "name": "CHAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 604,
            +            "itemtype": "property",
            +            "name": "WORD",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 616,
            +            "itemtype": "property",
            +            "name": "LINEAR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 621,
            +            "itemtype": "property",
            +            "name": "QUADRATIC",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 626,
            +            "itemtype": "property",
            +            "name": "BEZIER",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 631,
            +            "itemtype": "property",
            +            "name": "CURVE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 638,
            +            "itemtype": "property",
            +            "name": "STROKE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 643,
            +            "itemtype": "property",
            +            "name": "FILL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 648,
            +            "itemtype": "property",
            +            "name": "TEXTURE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 653,
            +            "itemtype": "property",
            +            "name": "IMMEDIATE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 661,
            +            "itemtype": "property",
            +            "name": "IMAGE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 669,
            +            "itemtype": "property",
            +            "name": "NEAREST",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 674,
            +            "itemtype": "property",
            +            "name": "REPEAT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 679,
            +            "itemtype": "property",
            +            "name": "CLAMP",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 684,
            +            "itemtype": "property",
            +            "name": "MIRROR",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 691,
            +            "itemtype": "property",
            +            "name": "LANDSCAPE",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 696,
            +            "itemtype": "property",
            +            "name": "PORTRAIT",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 706,
            +            "itemtype": "property",
            +            "name": "GRID",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 712,
            +            "itemtype": "property",
            +            "name": "AXES",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 718,
            +            "itemtype": "property",
            +            "name": "LABEL",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/constants.js",
            +            "line": 723,
            +            "itemtype": "property",
            +            "name": "FALLBACK",
            +            "type": "String",
            +            "final": 1,
            +            "class": "p5",
            +            "module": "Constants",
            +            "submodule": "Constants"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 20,
            +            "description": "<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "contents",
            +                    "description": "<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"
            +            ],
            +            "alt": "default grey canvas",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 52,
            +            "description": "<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n",
            +            "itemtype": "property",
            +            "name": "frameCount",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "numbers rapidly counting upward with frame count set to 30.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 79,
            +            "description": "<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n",
            +            "itemtype": "property",
            +            "name": "deltaTime",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 129,
            +            "description": "<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "focused",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "green 50×50 ellipse at top left. Red X covers canvas when page focus changes",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 160,
            +            "description": "<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n",
            +            "itemtype": "method",
            +            "name": "cursor",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n",
            +                    "type": "String|Constant"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>the horizontal active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>the vertical active spot of the cursor (must be less than 32)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 228,
            +            "description": "<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n",
            +            "itemtype": "method",
            +            "name": "frameRate",
            +            "chainable": 1,
            +            "example": [
            +                "\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"
            +            ],
            +            "alt": "blue rect moves left to right, followed by red rect moving faster. Loops.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 228,
            +                    "params": [
            +                        {
            +                            "name": "fps",
            +                            "description": "<p>number of frames to be displayed every second</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 288,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current frameRate",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 331,
            +            "description": "<p>Hides the cursor from view.</p>\n",
            +            "itemtype": "method",
            +            "name": "noCursor",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "cursor becomes 10×10 white ellipse the moves with mouse x and y.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 354,
            +            "description": "<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 372,
            +            "description": "<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n",
            +            "itemtype": "property",
            +            "name": "displayHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 390,
            +            "description": "<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowWidth",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 405,
            +            "description": "<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n",
            +            "itemtype": "property",
            +            "name": "windowHeight",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 421,
            +            "description": "<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n",
            +            "itemtype": "method",
            +            "name": "windowResized",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional Event callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 476,
            +            "description": "<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 488,
            +            "description": "<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 500,
            +            "description": "<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n",
            +            "itemtype": "method",
            +            "name": "fullscreen",
            +            "params": [
            +                {
            +                    "name": "val",
            +                    "description": "<p>whether the sketch should be in fullscreen mode\nor not</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "current fullscreen state",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 550,
            +            "description": "<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "pixelDensity",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment",
            +            "overloads": [
            +                {
            +                    "line": 550,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>whether or how much the sketch should scale</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 586,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current pixel density of the sketch",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 605,
            +            "description": "<p>Returns the pixel density of the current display the sketch is running on.</p>\n",
            +            "itemtype": "method",
            +            "name": "displayDensity",
            +            "return": {
            +                "description": "current pixel density of the display",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white ellipse with black outline in center of canvas.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 660,
            +            "description": "<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURL",
            +            "return": {
            +                "description": "url",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "current url (http://p5js.org/reference/#/p5/getURL) moves right to left.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 691,
            +            "description": "<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLPath",
            +            "return": {
            +                "description": "path components",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/environment.js",
            +            "line": 713,
            +            "description": "<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n",
            +            "itemtype": "method",
            +            "name": "getURLParams",
            +            "return": {
            +                "description": "URL params",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything.",
            +            "class": "p5",
            +            "module": "Environment",
            +            "submodule": "Environment"
            +        },
            +        {
            +            "file": "src/core/helpers.js",
            +            "line": 1,
            +            "requires": [
            +                "constants"
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 30,
            +            "description": "<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 126,
            +            "description": "<p>Set up our translation function, with loaded languages</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 171,
            +            "description": "<p>Returns a list of languages we have translations loaded for</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 178,
            +            "description": "<p>Returns the current language selected for translation</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/internationalization.js",
            +            "line": 185,
            +            "description": "<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n",
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/legacy.js",
            +            "line": 1,
            +            "requires": [
            +                "core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name",
            +                "in others",
            +                "they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."
            +            ],
            +            "class": "p5",
            +            "module": "Environment"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 42,
            +            "description": "<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "preload",
            +            "example": [
            +                "\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 83,
            +            "description": "<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setup",
            +            "example": [
            +                "\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 114,
            +            "description": "<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "draw",
            +            "example": [
            +                "\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 415,
            +            "description": "<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/main.js",
            +            "line": 693,
            +            "description": "<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "disableFriendlyErrors",
            +            "type": "Boolean",
            +            "example": [
            +                "\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 21,
            +            "description": "<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "elt",
            +            "readonly": "",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 47,
            +            "description": "<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "parent",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 47,
            +                    "params": [
            +                        {
            +                            "name": "parent",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n",
            +                            "type": "String|p5.Element|Object"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 93,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 114,
            +            "description": "<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n",
            +            "itemtype": "method",
            +            "name": "id",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 114,
            +                    "params": [
            +                        {
            +                            "name": "id",
            +                            "description": "<p>ID of the element</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the id of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 154,
            +            "description": "<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "class",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 154,
            +                    "params": [
            +                        {
            +                            "name": "class",
            +                            "description": "<p>class to add</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the class of the element",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 189,
            +            "description": "<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 246,
            +            "description": "<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 292,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 354,
            +            "description": "<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 403,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 454,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 510,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 551,
            +            "description": "<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseOut",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 592,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 639,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 678,
            +            "description": "<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 725,
            +            "description": "<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragOver",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 763,
            +            "description": "<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "dragLeave",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "nothing displayed",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Element.js",
            +            "line": 827,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 70,
            +            "description": "<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Graphics.js",
            +            "line": 122,
            +            "description": "<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image\na multi-colored circle moving back and forth over a scrolling background.",
            +            "class": "p5.Graphics",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 99,
            +            "description": "<p>Resize our canvas element.</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 415,
            +            "description": "<p>Helper function to check font type (system or otf)</p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer.js",
            +            "line": 467,
            +            "description": "<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n",
            +            "class": "p5.Renderer",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 7,
            +            "description": "<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/p5.Renderer2D.js",
            +            "line": 402,
            +            "description": "<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 7,
            +            "description": "<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n",
            +            "itemtype": "property",
            +            "name": "let",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 34,
            +            "description": "<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n",
            +            "itemtype": "property",
            +            "name": "const",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"
            +            ],
            +            "alt": "These examples do not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 87,
            +            "description": "<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n",
            +            "itemtype": "property",
            +            "name": "===",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 115,
            +            "description": "<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>",
            +            "itemtype": "property",
            +            "name": ">",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 137,
            +            "description": "<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": ">=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 158,
            +            "description": "<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 179,
            +            "description": "<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n",
            +            "itemtype": "property",
            +            "name": "<=",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 200,
            +            "description": "<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n",
            +            "itemtype": "property",
            +            "name": "if-else",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 231,
            +            "description": "<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n",
            +            "itemtype": "property",
            +            "name": "function",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 267,
            +            "description": "<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "return",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 288,
            +            "description": "<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n",
            +            "itemtype": "property",
            +            "name": "boolean",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 309,
            +            "description": "<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n",
            +            "itemtype": "property",
            +            "name": "string",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 331,
            +            "description": "<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n",
            +            "itemtype": "property",
            +            "name": "number",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 351,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n",
            +            "itemtype": "property",
            +            "name": "object",
            +            "example": [
            +                "\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 379,
            +            "description": "<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n",
            +            "itemtype": "property",
            +            "name": "class",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 408,
            +            "description": "<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n",
            +            "itemtype": "property",
            +            "name": "for",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 448,
            +            "description": "<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n",
            +            "itemtype": "property",
            +            "name": "while",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "p5",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 490,
            +            "description": "<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "stringify",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>:Javascript object that you would like to convert to JSON</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "JSON",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/reference.js",
            +            "line": 512,
            +            "description": "<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "message",
            +                    "description": "<p>:Message that you would like to print to the console</p>\n",
            +                    "type": "String|Expression|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"
            +            ],
            +            "alt": "This example does not render anything",
            +            "class": "console",
            +            "module": "Foundation",
            +            "submodule": "Foundation"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 15,
            +            "description": "<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Renderer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Black line extending from top-left of canvas to bottom right.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 125,
            +            "description": "<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n",
            +            "itemtype": "method",
            +            "name": "resizeCanvas",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the canvas</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "noRedraw",
            +                    "description": "<p>don't redraw the canvas immediately</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"
            +            ],
            +            "alt": "No image displayed.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 183,
            +            "description": "<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n",
            +            "itemtype": "method",
            +            "name": "noCanvas",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 204,
            +            "description": "<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "createGraphics",
            +            "params": [
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of the offscreen graphics buffer</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "renderer",
            +                    "description": "<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "offscreen graphics buffer",
            +                "type": "p5.Graphics"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 grey squares alternating light and dark grey. White quarter circle mid-left.",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 243,
            +            "description": "<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n",
            +            "itemtype": "method",
            +            "name": "blendMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"
            +            ],
            +            "alt": "translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/rendering.js",
            +            "line": 326,
            +            "description": "<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n",
            +            "itemtype": "property",
            +            "name": "drawingContext",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white ellipse with shadow blur effect around edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 18,
            +            "description": "<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/shim.js",
            +            "line": 39,
            +            "description": "<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n",
            +            "class": "p5",
            +            "module": "Rendering"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 10,
            +            "description": "<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 83,
            +            "description": "<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "example": [
            +                "\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal line moves slowly from left. Loops but stops on mouse press.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 134,
            +            "description": "<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "example": [
            +                "\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 192,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "push",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 290,
            +            "description": "<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "pop",
            +            "example": [
            +                "\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"
            +            ],
            +            "alt": "Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 391,
            +            "description": "<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n",
            +            "itemtype": "method",
            +            "name": "redraw",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>Redraw for n-times. The default value is 1.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black line on far left of canvas\nblack line on far left of canvas",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/structure.js",
            +            "line": 497,
            +            "description": "<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "p5",
            +            "params": [
            +                {
            +                    "name": "sketch",
            +                    "description": "<p>a function containing a p5.js sketch</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "node",
            +                    "description": "<p>ID or pointer to HTML DOM node to contain sketch in</p>\n",
            +                    "type": "String|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"
            +            ],
            +            "alt": "white rectangle on black background",
            +            "class": "p5",
            +            "module": "Structure",
            +            "submodule": "Structure"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 11,
            +            "description": "<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n",
            +            "itemtype": "method",
            +            "name": "applyMatrix",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n",
            +                    "type": "Number|Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "d",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "f",
            +                    "description": "<p>numbers which define the 2×3 matrix to be multiplied</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 168,
            +            "description": "<p>Replaces the current matrix with the identity matrix.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetMatrix",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"
            +            ],
            +            "alt": "A rotated rectangle in the center with another at the top left corner",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 193,
            +            "description": "<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "axis",
            +                    "description": "<p>(in 3d) the axis to rotate around</p>\n",
            +                    "type": "p5.Vector|Number[]",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 232,
            +            "description": "<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the x axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 268,
            +            "description": "<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the y axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 304,
            +            "description": "<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n",
            +            "itemtype": "method",
            +            "name": "rotateZ",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3d box rotating around the z axis.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 342,
            +            "description": "<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 342,
            +                    "params": [
            +                        {
            +                            "name": "s",
            +                            "description": "<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n",
            +                            "type": "Number|p5.Vector|Number[]"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>percent to scale the object in the y-axis</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>percent to scale the object in the z-axis (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 386,
            +                    "params": [
            +                        {
            +                            "name": "scales",
            +                            "description": "<p>per-axis percents to scale the object</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 416,
            +            "description": "<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearX",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at top middle.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 455,
            +            "description": "<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n",
            +            "itemtype": "method",
            +            "name": "shearY",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"
            +            ],
            +            "alt": "white irregular quadrilateral with black outline at middle bottom.",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform"
            +        },
            +        {
            +            "file": "src/core/transform.js",
            +            "line": 494,
            +            "description": "<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "translate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas",
            +            "class": "p5",
            +            "module": "Transform",
            +            "submodule": "Transform",
            +            "overloads": [
            +                {
            +                    "line": 494,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>left/right translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>up/down translation</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>forward/backward translation (webgl only)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "vector",
            +                            "description": "<p>the vector to translate by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 10,
            +            "description": "<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n",
            +            "itemtype": "method",
            +            "name": "storeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "String|Number|Object|Boolean|p5.Color|p5.Vector"
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"
            +            ],
            +            "alt": "When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 101,
            +            "description": "<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "getItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>name that you wish to use to store in local storage</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Value of stored item",
            +                "type": "Number|Object|String|Boolean|p5.Color|p5.Vector"
            +            },
            +            "example": [
            +                "\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"
            +            ],
            +            "alt": "If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 177,
            +            "description": "<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearStorage",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/local_storage.js",
            +            "line": 205,
            +            "description": "<p>Removes an item that was stored with storeItem()</p>\n",
            +            "itemtype": "method",
            +            "name": "removeItem",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "LocalStorage"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 14,
            +            "description": "<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createStringDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.StringDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 14,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                },
            +                {
            +                    "line": 37,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.StringDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 48,
            +            "description": "<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n",
            +            "itemtype": "method",
            +            "name": "createNumberDict",
            +            "return": {
            +                "description": "",
            +                "type": "p5.NumberDict"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 48,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "object",
            +                            "description": "<p>object</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.NumberDict"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 101,
            +            "description": "<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the number of key-value pairs in the Dictionary",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 122,
            +            "description": "<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasKey",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>that you want to look up</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether that key exists in Dictionary",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 144,
            +            "description": "<p>Returns the value stored at the given key.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>key you want to access</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the value stored at that key",
            +                "type": "Number|String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 170,
            +            "description": "<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 197,
            +            "description": "<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 208,
            +            "description": "<p>Creates a new key-value pair in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "create",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary",
            +            "overloads": [
            +                {
            +                    "line": 208,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "Number|String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 226,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>key/value pair</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 244,
            +            "description": "<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 265,
            +            "description": "<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "params": [
            +                {
            +                    "name": "key",
            +                    "description": "<p>for the pair to remove</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 294,
            +            "description": "<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 318,
            +            "description": "<p>Converts the Dictionary into a CSV file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 356,
            +            "description": "<p>Converts the Dictionary into a JSON file for local download.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 387,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.TypedDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 425,
            +            "description": "<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 432,
            +            "description": "<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to add to</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to add to the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 459,
            +            "description": "<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for the value you wish to subtract from</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Number",
            +                    "description": "<p>to subtract from the value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 482,
            +            "description": "<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to multiply</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to multiply the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 509,
            +            "description": "<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "params": [
            +                {
            +                    "name": "Key",
            +                    "description": "<p>for value you wish to divide</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "Amount",
            +                    "description": "<p>to divide the value by</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 536,
            +            "description": "<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 560,
            +            "description": "<p>Return the lowest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 580,
            +            "description": "<p>Return the highest number currently stored in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxValue",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 600,
            +            "description": "<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n",
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 622,
            +            "description": "<p>Return the lowest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "minKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/data/p5.TypedDict.js",
            +            "line": 642,
            +            "description": "<p>Return the highest key currently used in the Dictionary.</p>\n",
            +            "itemtype": "method",
            +            "name": "maxKey",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"
            +            ],
            +            "class": "p5.NumberDict",
            +            "module": "Data",
            +            "submodule": "Dictionary"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 21,
            +            "description": "<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "select",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of element to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Element\">p5.Element</a> containing node found",
            +                "type": "p5.Element|null"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 68,
            +            "description": "<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n",
            +            "itemtype": "method",
            +            "name": "selectAll",
            +            "params": [
            +                {
            +                    "name": "selectors",
            +                    "description": "<p>CSS selector string of elements to search for</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "container",
            +                    "description": "<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n",
            +                    "type": "String|p5.Element|HTMLElement",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found",
            +                "type": "p5.Element[]"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 127,
            +            "description": "<p>Helper function for select and selectAll</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 142,
            +            "description": "<p>Helper function for getElement and getElements.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 176,
            +            "description": "<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeElements",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 204,
            +            "description": "<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "changed",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 271,
            +            "description": "<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n",
            +            "itemtype": "method",
            +            "name": "input",
            +            "params": [
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n",
            +                    "type": "Function|Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "alt": "no display.",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 309,
            +            "description": "<p>Helpers for create methods.</p>\n",
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 322,
            +            "description": "<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createDiv",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 341,
            +            "description": "<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createP",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 361,
            +            "description": "<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSpan",
            +            "params": [
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner HTML for element created</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 379,
            +            "description": "<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImg",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 379,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>src path or url for image</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 396,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "alt",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "crossOrigin",
            +                            "description": "<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 426,
            +            "description": "<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n",
            +            "itemtype": "method",
            +            "name": "createA",
            +            "params": [
            +                {
            +                    "name": "href",
            +                    "description": "<p>url of page to link to</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "html",
            +                    "description": "<p>inner html of link element to display</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "target",
            +                    "description": "<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 450,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 452,
            +            "description": "<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n",
            +            "itemtype": "method",
            +            "name": "createSlider",
            +            "params": [
            +                {
            +                    "name": "min",
            +                    "description": "<p>minimum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "max",
            +                    "description": "<p>maximum value of the slider</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>default value of the slider</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "step",
            +                    "description": "<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 507,
            +            "description": "<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n",
            +            "itemtype": "method",
            +            "name": "createButton",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed on the button</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the button</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 541,
            +            "description": "<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n",
            +            "itemtype": "method",
            +            "name": "createCheckbox",
            +            "params": [
            +                {
            +                    "name": "label",
            +                    "description": "<p>label displayed after checkbox</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value of the checkbox; checked is true, unchecked is false</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 622,
            +            "description": "<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createSelect",
            +            "return": {
            +                "description": "",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "multiple",
            +                            "description": "<p>true if dropdown should support multiple selections</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 673,
            +                    "params": [
            +                        {
            +                            "name": "existing",
            +                            "description": "<p>DOM select element</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 770,
            +            "description": "<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n",
            +            "itemtype": "method",
            +            "name": "createRadio",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 770,
            +                    "params": [
            +                        {
            +                            "name": "containerElement",
            +                            "description": "<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "name",
            +                            "description": "<p>A name parameter for each Input Element.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 832,
            +                    "params": [
            +                        {
            +                            "name": "name",
            +                            "description": "",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 837,
            +                    "params": [],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 978,
            +            "description": "<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n",
            +            "itemtype": "method",
            +            "name": "createColorPicker",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>default color of element</p>\n",
            +                    "type": "String|p5.Color",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1066,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n",
            +            "itemtype": "method",
            +            "name": "createInput",
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1066,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>default value of the input box</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "type",
            +                            "description": "<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                        "type": "p5.Element"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "p5.Element"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1104,
            +            "description": "<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "createFileInput",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function for when a file is loaded</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "multiple",
            +                    "description": "<p>optional, to allow multiple files to be selected</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1164,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1211,
            +            "description": "<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVideo",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n",
            +                    "type": "String|String[]"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1257,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1259,
            +            "description": "<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createAudio",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n",
            +                    "type": "String|String[]",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>",
            +                "type": "p5.MediaElement"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1296,
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1298,
            +            "itemtype": "property",
            +            "name": "VIDEO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1304,
            +            "itemtype": "property",
            +            "name": "AUDIO",
            +            "type": "String",
            +            "final": 1,
            +            "category": [
            +                "Constants"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1341,
            +            "description": "<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCapture",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n",
            +                    "type": "String|Constant|Object"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be called once\n                                  stream has loaded</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "capture video <a href=\"#/p5.Element\">p5.Element</a>",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1478,
            +            "description": "<p>Creates element with given tag in the DOM with given content.</p>\n",
            +            "itemtype": "method",
            +            "name": "createElement",
            +            "params": [
            +                {
            +                    "name": "tag",
            +                    "description": "<p>tag for the new element</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "content",
            +                    "description": "<p>html content to be inserted into the element</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node",
            +                "type": "p5.Element"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1504,
            +            "description": "<p>Adds specified class to the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "addClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to add</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1529,
            +            "description": "<p>Removes specified class from the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeClass",
            +            "params": [
            +                {
            +                    "name": "class",
            +                    "description": "<p>name of class to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1560,
            +            "description": "<p>Checks if specified class already set to element</p>\n",
            +            "itemtype": "method",
            +            "name": "hasClass",
            +            "return": {
            +                "description": "a boolean value if element has specified class",
            +                "type": "Boolean"
            +            },
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name of class to check</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1589,
            +            "description": "<p>Toggles element class</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleClass",
            +            "params": [
            +                {
            +                    "name": "c",
            +                    "description": "<p>class name to toggle</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1622,
            +            "description": "<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "child",
            +            "return": {
            +                "description": "an array of child nodes",
            +                "type": "Node[]"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1622,
            +                    "params": [],
            +                    "return": {
            +                        "description": "an array of child nodes",
            +                        "type": "Node[]"
            +                    }
            +                },
            +                {
            +                    "line": 1650,
            +                    "params": [
            +                        {
            +                            "name": "child",
            +                            "description": "<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n",
            +                            "type": "String|p5.Element",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1675,
            +            "description": "<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n",
            +            "itemtype": "method",
            +            "name": "center",
            +            "params": [
            +                {
            +                    "name": "align",
            +                    "description": "<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1726,
            +            "description": "<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "html",
            +            "return": {
            +                "description": "the inner HTML of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1726,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the inner HTML of the element",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1747,
            +                    "params": [
            +                        {
            +                            "name": "html",
            +                            "description": "<p>the HTML to be placed inside the element</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "append",
            +                            "description": "<p>whether to append HTML to existing</p>\n",
            +                            "type": "Boolean",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1765,
            +            "description": "<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n",
            +            "itemtype": "method",
            +            "name": "position",
            +            "return": {
            +                "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1765,
            +                    "params": [],
            +                    "return": {
            +                        "description": "object of form { x: 0, y: 0 } containing the position of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 1798,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-position relative to upper left of window (optional)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "positionType",
            +                            "description": "<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1885,
            +            "description": "<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n",
            +            "itemtype": "method",
            +            "name": "style",
            +            "return": {
            +                "description": "value of property",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1885,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "<p>property to be set</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "value of property",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1923,
            +                    "params": [
            +                        {
            +                            "name": "property",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to property</p>\n",
            +                            "type": "String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1,
            +                    "return": {
            +                        "description": "current value of property, if no value is given as second argument",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 1980,
            +            "description": "<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n",
            +            "itemtype": "method",
            +            "name": "attribute",
            +            "return": {
            +                "description": "value of attribute",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 1980,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of attribute",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 1995,
            +                    "params": [
            +                        {
            +                            "name": "attr",
            +                            "description": "<p>attribute to set</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value to assign to attribute</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2024,
            +            "description": "<p>Removes an attribute on the specified element.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeAttribute",
            +            "params": [
            +                {
            +                    "name": "attr",
            +                    "description": "<p>attribute to remove</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2069,
            +            "description": "<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n",
            +            "itemtype": "method",
            +            "name": "value",
            +            "return": {
            +                "description": "value of the element",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2069,
            +                    "params": [],
            +                    "return": {
            +                        "description": "value of the element",
            +                        "type": "String|Number"
            +                    }
            +                },
            +                {
            +                    "line": 2099,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2115,
            +            "description": "<p>Shows the current element. Essentially, setting display:block for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "show",
            +            "chainable": 1,
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2133,
            +            "description": "<p>Hides the current element. Essentially, setting display:none for the style.</p>\n",
            +            "itemtype": "method",
            +            "name": "hide",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2149,
            +            "description": "<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n",
            +            "itemtype": "method",
            +            "name": "size",
            +            "return": {
            +                "description": "the width and height of the element in an object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2149,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the width and height of the element in an object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 2173,
            +                    "params": [
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the element, either AUTO, or a number</p>\n",
            +                            "type": "Number|Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2230,
            +            "description": "<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n",
            +            "itemtype": "method",
            +            "name": "remove",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"
            +            ],
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2268,
            +            "description": "<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n",
            +            "itemtype": "method",
            +            "name": "drop",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to receive loaded file, called for each file dropped.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "fxn",
            +                    "description": "<p>callback triggered once when files are dropped with the drop event.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"
            +            ],
            +            "alt": "Canvas turns into whatever image is dragged/dropped onto it.",
            +            "class": "p5.Element",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2400,
            +            "description": "<p>Path to the media element source.</p>\n",
            +            "itemtype": "property",
            +            "name": "src",
            +            "return": {
            +                "description": "src",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2466,
            +            "description": "<p>Play an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2530,
            +            "description": "<p>Stops an HTML5 media element (sets current time to zero).</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2594,
            +            "description": "<p>Pauses an HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2656,
            +            "description": "<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2712,
            +            "description": "<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2778,
            +            "description": "<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n",
            +            "itemtype": "method",
            +            "name": "autoplay",
            +            "params": [
            +                {
            +                    "name": "shouldAutoplay",
            +                    "description": "<p>whether the element should autoplay</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2845,
            +            "description": "<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n",
            +            "itemtype": "method",
            +            "name": "volume",
            +            "return": {
            +                "description": "current volume",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2845,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current volume",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2918,
            +                    "params": [
            +                        {
            +                            "name": "val",
            +                            "description": "<p>volume between 0.0 and 1.0</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 2931,
            +            "description": "<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n",
            +            "itemtype": "method",
            +            "name": "speed",
            +            "return": {
            +                "description": "current playback speed of the element",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 2931,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current playback speed of the element",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3003,
            +                    "params": [
            +                        {
            +                            "name": "speed",
            +                            "description": "<p>speed multiplier for element playback</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3020,
            +            "description": "<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n",
            +            "itemtype": "method",
            +            "name": "time",
            +            "return": {
            +                "description": "current time (in seconds)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM",
            +            "overloads": [
            +                {
            +                    "line": 3020,
            +                    "params": [],
            +                    "return": {
            +                        "description": "current time (in seconds)",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 3065,
            +                    "params": [
            +                        {
            +                            "name": "time",
            +                            "description": "<p>time to jump to (in seconds)</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3079,
            +            "description": "<p>Returns the duration of the HTML5 media element.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "duration",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3201,
            +            "description": "<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3232,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3234,
            +            "description": "<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "audioNode",
            +                    "description": "<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n",
            +                    "type": "AudioNode|Object"
            +                }
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3283,
            +            "description": "<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3298,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3300,
            +            "description": "<p>Show the default MediaElement controls, as determined by the web browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "showControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3331,
            +            "description": "<p>Hide the default mediaElement controls.</p>\n",
            +            "itemtype": "method",
            +            "name": "hideControls",
            +            "example": [
            +                "\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3360,
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3371,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3434,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3476,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"
            +            ],
            +            "class": "p5.MediaElement",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3542,
            +            "description": "<p>Underlying File object. All normal File methods can be called on this.</p>\n",
            +            "itemtype": "property",
            +            "name": "file",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3554,
            +            "description": "<p>File type (image, text, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "type",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3560,
            +            "description": "<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n",
            +            "itemtype": "property",
            +            "name": "subtype",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3566,
            +            "description": "<p>File name</p>\n",
            +            "itemtype": "property",
            +            "name": "name",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3572,
            +            "description": "<p>File size</p>\n",
            +            "itemtype": "property",
            +            "name": "size",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/dom/dom.js",
            +            "line": 3579,
            +            "description": "<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n",
            +            "itemtype": "property",
            +            "name": "data",
            +            "class": "p5.File",
            +            "module": "DOM",
            +            "submodule": "DOM"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 11,
            +            "description": "<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n",
            +            "itemtype": "property",
            +            "name": "deviceOrientation",
            +            "type": "Constant",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 23,
            +            "description": "<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 46,
            +            "description": "<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 69,
            +            "description": "<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "accelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Magnitude of device acceleration is displayed as ellipse size",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 94,
            +            "description": "<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 104,
            +            "description": "<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 114,
            +            "description": "<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n",
            +            "itemtype": "property",
            +            "name": "pAccelerationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 135,
            +            "description": "<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 168,
            +            "description": "<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "itemtype": "property",
            +            "name": "rotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 201,
            +            "description": "<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"
            +            ],
            +            "itemtype": "property",
            +            "name": "rotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "alt": "red horizontal line right, green vertical line bottom. black background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 239,
            +            "description": "<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationX",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 285,
            +            "description": "<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationY",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 330,
            +            "description": "<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n",
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"
            +            ],
            +            "alt": "no image to display.",
            +            "itemtype": "property",
            +            "name": "pRotationZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 389,
            +            "description": "<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n",
            +            "itemtype": "property",
            +            "name": "turnAxis",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 428,
            +            "description": "<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMoveThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 471,
            +            "description": "<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n",
            +            "itemtype": "method",
            +            "name": "setShakeThreshold",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The threshold value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 515,
            +            "description": "<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceMoved",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device moves",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 546,
            +            "description": "<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceTurned",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/acceleration.js",
            +            "line": 604,
            +            "description": "<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "deviceShaken",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect in center of canvas. turns white on mobile when device shakes",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Acceleration"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 10,
            +            "description": "<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 white rect that turns black on keypress.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 36,
            +            "description": "<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n",
            +            "itemtype": "property",
            +            "name": "key",
            +            "type": "String",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"
            +            ],
            +            "alt": "canvas displays any key value that is pressed in pink font.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 64,
            +            "description": "<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "keyCode",
            +            "type": "Integer",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"
            +            ],
            +            "alt": "Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 103,
            +            "description": "<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyPressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 190,
            +            "description": "<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when key pressed and black when pressed again",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 243,
            +            "description": "<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyTyped",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional KeyboardEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black rect center. turns white when 'a' key typed and black when 'b' pressed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 298,
            +            "description": "<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/keyboard.js",
            +            "line": 308,
            +            "description": "<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "keyIsDown",
            +            "params": [
            +                {
            +                    "name": "code",
            +                    "description": "<p>The key to check for.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "whether key is down or not",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Keyboard"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 12,
            +            "description": "<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"
            +            ],
            +            "alt": "box moves left and right according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 43,
            +            "description": "<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n",
            +            "itemtype": "property",
            +            "name": "movedY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "box moves up and down according to mouse movement then slowly back towards the center",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 80,
            +            "description": "<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "horizontal black line moves left and right with mouse x-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 106,
            +            "description": "<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black line moves up and down with mouse y-position",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 132,
            +            "description": "<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "line trail is created from cursor movements. faster movement make longer line.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 164,
            +            "description": "<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pmouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect center, fuchsia background. rect flickers on mouse movement",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 195,
            +            "description": "<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 233,
            +            "description": "<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n",
            +            "itemtype": "property",
            +            "name": "winMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 271,
            +            "description": "<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 311,
            +            "description": "<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n",
            +            "itemtype": "property",
            +            "name": "pwinMouseY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 351,
            +            "description": "<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseButton",
            +            "type": "Constant",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 389,
            +            "description": "<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n",
            +            "itemtype": "property",
            +            "name": "mouseIsPressed",
            +            "type": "Boolean",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 481,
            +            "description": "<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 535,
            +            "description": "<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseDragged",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 615,
            +            "description": "<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mousePressed",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 696,
            +            "description": "<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseReleased",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 772,
            +            "description": "<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse click/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 841,
            +            "description": "<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n",
            +            "itemtype": "method",
            +            "name": "doubleClicked",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional MouseEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 926,
            +            "description": "<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n",
            +            "itemtype": "method",
            +            "name": "mouseWheel",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional WheelEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black 50×50 rect moves up and down with vertical scroll. fuchsia background",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 979,
            +            "description": "<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n",
            +            "itemtype": "method",
            +            "name": "requestPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "3D scene moves according to mouse mouse movement in a first person perspective",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/mouse.js",
            +            "line": 1025,
            +            "description": "<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n",
            +            "itemtype": "method",
            +            "name": "exitPointerLock",
            +            "example": [
            +                "\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "cursor gets locked / unlocked on mouse-click",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Mouse"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 10,
            +            "description": "<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n",
            +            "itemtype": "property",
            +            "name": "touches",
            +            "type": "Object[]",
            +            "readonly": "",
            +            "example": [
            +                "\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Number of touches currently registered are displayed on the canvas",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 71,
            +            "description": "<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchStarted",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch event.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 151,
            +            "description": "<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchMoved",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns lighter with touch until white. resets\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/events/touch.js",
            +            "line": 223,
            +            "description": "<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n",
            +            "itemtype": "method",
            +            "name": "touchEnded",
            +            "params": [
            +                {
            +                    "name": "event",
            +                    "description": "<p>optional TouchEvent callback argument.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "50×50 black rect turns white with touch.\nno image displayed",
            +            "class": "p5",
            +            "module": "Events",
            +            "submodule": "Touch"
            +        },
            +        {
            +            "file": "src/image/filters.js",
            +            "line": 3,
            +            "description": "<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n",
            +            "class": "p5",
            +            "module": "Events"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 8,
            +            "description": "<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 15,
            +            "description": "<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n",
            +            "itemtype": "method",
            +            "name": "createImage",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width in pixels</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height in pixels</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 94,
            +            "description": "<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveCanvas",
            +            "example": [
            +                "\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed\n no image displayed\n no image displayed",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 94,
            +                    "params": [
            +                        {
            +                            "name": "selectedCanvas",
            +                            "description": "<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n",
            +                            "type": "p5.Element|HTMLCanvasElement"
            +                        },
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "<p>'jpg' or 'png'</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "filename",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "extension",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/image.js",
            +            "line": 413,
            +            "description": "<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveFrames",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'jpg' or 'png'</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Duration in seconds to save the frames for.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "framerate",
            +                    "description": "<p>Framerate to save the frames in.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n",
            +                    "type": "Function(Array)",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"
            +            ],
            +            "alt": "canvas background goes from light to dark with mouse x.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 18,
            +            "description": "<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadImage",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path of the image to be loaded</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n",
            +                    "type": "function(p5.Image)",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "failureCallback",
            +                    "description": "<p>called with event error if\n                               the image fails to load.</p>\n",
            +                    "type": "Function(Event)",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the <a href=\"#/p5.Image\">p5.Image</a> object",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 162,
            +            "description": "<p>Helper function for loading GIF-based images</p>\n",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 301,
            +            "description": "<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n",
            +            "itemtype": "method",
            +            "name": "image",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 301,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "<p>the image to display</p>\n",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y-coordinate of the top-left corner of the image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "width",
            +                            "description": "<p>the width to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "height",
            +                            "description": "<p>the height to draw the image</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 388,
            +                    "params": [
            +                        {
            +                            "name": "img",
            +                            "description": "",
            +                            "type": "p5.Image|p5.Element|p5.Texture"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dWidth",
            +                            "description": "<p>the width of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "dHeight",
            +                            "description": "<p>the height of the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "sWidth",
            +                            "description": "<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "sHeight",
            +                            "description": "<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 471,
            +            "description": "<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n",
            +            "itemtype": "method",
            +            "name": "tint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 471,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 542,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 553,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 559,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the tint color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 569,
            +            "description": "<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n",
            +            "itemtype": "method",
            +            "name": "noTint",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 side by side images of bricks, left image with blue tint",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/loading_displaying.js",
            +            "line": 633,
            +            "description": "<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n",
            +            "itemtype": "method",
            +            "name": "imageMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either CORNER, CORNERS, or CENTER</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 9,
            +            "description": "<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 88,
            +            "description": "<p>Image width.</p>\n",
            +            "itemtype": "property",
            +            "name": "width",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains in top and horizontal lines in corresponding colors in bottom.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 115,
            +            "description": "<p>Image height.</p>\n",
            +            "itemtype": "property",
            +            "name": "height",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "rocky mountains on right and vertical lines in corresponding colors on left.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 152,
            +            "description": "<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"
            +            ],
            +            "alt": "66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 222,
            +            "description": "<p>Helper function for animating GIF-based images with time</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 253,
            +            "description": "<p>Helper fxn for sharing pixel methods</p>\n",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 261,
            +            "description": "<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 296,
            +            "description": "<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains vertically stacked",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 296,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-offset of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height of the target update area for the\n                             underlying canvas</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 338,
            +                    "params": []
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 346,
            +            "description": "<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with 50×50 green rect in front",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 346,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 383,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 387,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 400,
            +            "description": "<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "a",
            +                    "description": "<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"
            +            ],
            +            "alt": "2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 437,
            +            "description": "<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n",
            +            "itemtype": "method",
            +            "name": "resize",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>the resized image width</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>the resized image height</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. zoomed in",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 548,
            +            "description": "<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains and smaller image on top of bricks at top left",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 548,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 588,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 603,
            +            "description": "<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n",
            +            "itemtype": "method",
            +            "name": "mask",
            +            "params": [
            +                {
            +                    "name": "srcImage",
            +                    "description": "<p>source image</p>\n",
            +                    "type": "p5.Image"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 665,
            +            "description": "<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "2 images of rocky mountains left one in color, right in black and white",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 738,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image",
            +            "overloads": [
            +                {
            +                    "line": 738,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 815,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 859,
            +            "description": "<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>give your file a name</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>'png' or 'jpg'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains.",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 900,
            +            "description": "<p>Starts an animated GIF over at the beginning state.</p>\n",
            +            "itemtype": "method",
            +            "name": "reset",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 941,
            +            "description": "<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "getCurrentFrame",
            +            "return": {
            +                "description": "The index for the currently displaying frame in animated GIF",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"
            +            ],
            +            "alt": "Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 972,
            +            "description": "<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "setFrame",
            +            "params": [
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index for the frame that should be displayed</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1017,
            +            "description": "<p>Returns the number of frames in an animated GIF</p>\n",
            +            "itemtype": "method",
            +            "name": "numFrames",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"
            +            ],
            +            "alt": "A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1052,
            +            "description": "<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1089,
            +            "description": "<p>Pauses an animated GIF.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "example": [
            +                "\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"
            +            ],
            +            "alt": "An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/p5.Image.js",
            +            "line": 1125,
            +            "description": "<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n",
            +            "itemtype": "method",
            +            "name": "delay",
            +            "params": [
            +                {
            +                    "name": "d",
            +                    "description": "<p>the amount in milliseconds to delay between switching frames</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "index",
            +                    "description": "<p>the index of the frame that should have the new delay value {optional}</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"
            +            ],
            +            "alt": "Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower",
            +            "class": "p5.Image",
            +            "module": "Image",
            +            "submodule": "Image"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 12,
            +            "description": "<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n",
            +            "itemtype": "property",
            +            "name": "pixels",
            +            "type": "Number[]",
            +            "example": [
            +                "\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"
            +            ],
            +            "alt": "top half of canvas pink, bottom grey",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 80,
            +            "description": "<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n",
            +            "itemtype": "method",
            +            "name": "blend",
            +            "example": [
            +                "\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 80,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 152,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "blendMode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 173,
            +            "description": "<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "example": [
            +                "\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"
            +            ],
            +            "alt": "image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 173,
            +                    "params": [
            +                        {
            +                            "name": "srcImage",
            +                            "description": "<p>source image</p>\n",
            +                            "type": "p5.Image|p5.Element"
            +                        },
            +                        {
            +                            "name": "sx",
            +                            "description": "<p>X coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "<p>Y coordinate of the source's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "<p>source image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "<p>source image height</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "<p>X coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "<p>Y coordinate of the destination's upper left corner</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "<p>destination image width</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "<p>destination image height</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 215,
            +                    "params": [
            +                        {
            +                            "name": "sx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "sh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dx",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dy",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dw",
            +                            "description": "",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dh",
            +                            "description": "",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 307,
            +            "description": "<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "filterType",
            +                    "description": "<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "filterParam",
            +                    "description": "<p>an optional parameter unique\n                               to each filter, see above</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 481,
            +            "description": "<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "return": {
            +                "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                "type": "p5.Image"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels",
            +            "overloads": [
            +                {
            +                    "line": 481,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y-coordinate of the pixel</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "w",
            +                            "description": "<p>width</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "h",
            +                            "description": "<p>height</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the rectangle <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 551,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the whole <a href=\"#/p5.Image\">p5.Image</a>",
            +                        "type": "p5.Image"
            +                    }
            +                },
            +                {
            +                    "line": 555,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "color of pixel at x,y in array format [R, G, B, A]",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 566,
            +            "description": "<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadPixels",
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 602,
            +            "description": "<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the pixel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "c",
            +                    "description": "<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n",
            +                    "type": "Number|Number[]|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/image/pixels.js",
            +            "line": 674,
            +            "description": "<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n",
            +            "itemtype": "method",
            +            "name": "updatePixels",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "w",
            +                    "description": "<p>width of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "h",
            +                    "description": "<p>height of region to update</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two images of the rocky mountains. one on top, one on bottom of canvas.",
            +            "class": "p5",
            +            "module": "Image",
            +            "submodule": "Pixels"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 20,
            +            "description": "<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadJSON",
            +            "return": {
            +                "description": "JSON data",
            +                "type": "Object|Array"
            +            },
            +            "example": [
            +                "\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"
            +            ],
            +            "alt": "50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 20,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "jsonpOptions",
            +                            "description": "<p>options object for jsonp related settings</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\" or \"jsonp\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "JSON data",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 104,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                },
            +                {
            +                    "line": 112,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object|Array"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 183,
            +            "description": "<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadStrings",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 303,
            +            "description": "<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadTable",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "header",
            +                    "description": "<p>\"header\" to indicate table has header row</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Table\">Table</a> object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 583,
            +            "description": "<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadXML",
            +            "params": [
            +                {
            +                    "name": "filename",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "XML object containing data",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 693,
            +            "description": "<p>This method is suitable for fetching files up to size of 64MB.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadBytes",
            +            "params": [
            +                {
            +                    "name": "file",
            +                    "description": "<p>name of the file or URL to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to be executed if there\n                                   is an error</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an object whose 'bytes' property will be the loaded buffer",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 752,
            +            "description": "<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n",
            +            "itemtype": "method",
            +            "name": "httpGet",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 752,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 806,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 814,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 829,
            +            "description": "<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpPost",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object|Boolean",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 896,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "",
            +                            "type": "Object|Boolean"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 904,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function"
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 919,
            +            "description": "<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n",
            +            "itemtype": "method",
            +            "name": "httpDo",
            +            "return": {
            +                "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Input",
            +            "overloads": [
            +                {
            +                    "line": 919,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>name of the file or url to load</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "method",
            +                            "description": "<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "datatype",
            +                            "description": "<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "data",
            +                            "description": "<p>param data passed sent with request</p>\n",
            +                            "type": "Object",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.",
            +                        "type": "Promise"
            +                    }
            +                },
            +                {
            +                    "line": 990,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "options",
            +                            "description": "<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n",
            +                            "type": "Object"
            +                        },
            +                        {
            +                            "name": "callback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "errorCallback",
            +                            "description": "",
            +                            "type": "Function",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Promise"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1155,
            +            "itemtype": "method",
            +            "name": "createWriter",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>name of the file to be created</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.PrintWriter"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1210,
            +            "description": "<p>Writes data to the PrintWriter stream</p>\n",
            +            "itemtype": "method",
            +            "name": "write",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be written by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1269,
            +            "description": "<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n",
            +            "itemtype": "method",
            +            "name": "print",
            +            "params": [
            +                {
            +                    "name": "data",
            +                    "description": "<p>all data to be printed by the PrintWriter</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1310,
            +            "description": "<p>Clears the data already written to the PrintWriter object</p>\n",
            +            "itemtype": "method",
            +            "name": "clear",
            +            "example": [
            +                "\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1344,
            +            "description": "<p>Closes the PrintWriter</p>\n",
            +            "itemtype": "method",
            +            "name": "close",
            +            "example": [
            +                "\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"
            +            ],
            +            "class": "p5.PrintWriter",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1393,
            +            "description": "<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "objectOrFilename",
            +                    "description": "<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n",
            +                    "type": "Object|String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n",
            +                    "type": "Boolean|String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"
            +            ],
            +            "alt": "An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1535,
            +            "description": "<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveJSON",
            +            "params": [
            +                {
            +                    "name": "json",
            +                    "description": "",
            +                    "type": "Array|Object"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "optimize",
            +                    "description": "<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1592,
            +            "description": "<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveStrings",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>string array to be written</p>\n",
            +                    "type": "String[]"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>filename for output</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "extension",
            +                    "description": "<p>the filename's extension</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "isCRLF",
            +                    "description": "<p>if true, change line-break to CRLF</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/files.js",
            +            "line": 1656,
            +            "description": "<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveTable",
            +            "params": [
            +                {
            +                    "name": "Table",
            +                    "description": "<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n",
            +                    "type": "p5.Table"
            +                },
            +                {
            +                    "name": "filename",
            +                    "description": "<p>the filename to which the Table should be saved</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Output"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 9,
            +            "description": "<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 43,
            +            "description": "<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n",
            +            "itemtype": "property",
            +            "name": "columns",
            +            "type": "String[]",
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 77,
            +            "description": "<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n",
            +            "itemtype": "property",
            +            "name": "rows",
            +            "type": "p5.TableRow[]",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 85,
            +            "description": "<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n",
            +            "itemtype": "method",
            +            "name": "addRow",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row to be added to the table</p>\n",
            +                    "type": "p5.TableRow",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the row that was added",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 148,
            +            "description": "<p>Removes a row from the table object.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeRow",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID number of the row to remove</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 195,
            +            "description": "<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRow",
            +            "params": [
            +                {
            +                    "name": "rowID",
            +                    "description": "<p>ID number of the row to get</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.TableRow\">p5.TableRow</a> object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 240,
            +            "description": "<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRows",
            +            "return": {
            +                "description": "Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 288,
            +            "description": "<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRow",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 352,
            +            "description": "<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "findRows",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>ID number or title of the\n                               column to search</p>\n",
            +                    "type": "Integer|String"
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 420,
            +            "description": "<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRow",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String|RegExp"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "TableRow object",
            +                "type": "p5.TableRow"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 478,
            +            "description": "<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "matchRows",
            +            "params": [
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>The regular expression to match</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>The column ID (number) or\n                                 title (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "An Array of TableRow objects",
            +                "type": "p5.TableRow[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 545,
            +            "description": "<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>String or Number of the column to return</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of column values",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 597,
            +            "description": "<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearRows",
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 638,
            +            "description": "<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n",
            +            "itemtype": "method",
            +            "name": "addColumn",
            +            "params": [
            +                {
            +                    "name": "title",
            +                    "description": "<p>title of the given column</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 688,
            +            "description": "<p>Returns the total number of columns in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getColumnCount",
            +            "return": {
            +                "description": "Number of columns in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 724,
            +            "description": "<p>Returns the total number of rows in a Table.</p>\n",
            +            "itemtype": "method",
            +            "name": "getRowCount",
            +            "return": {
            +                "description": "Number of rows in this table",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 760,
            +            "description": "<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeTokens",
            +            "params": [
            +                {
            +                    "name": "chars",
            +                    "description": "<p>String listing characters to be removed</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 832,
            +            "description": "<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (number)\n                                 or name (string)</p>\n",
            +                    "type": "String|Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"
            +            ],
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 896,
            +            "description": "<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeColumn",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 960,
            +            "description": "<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1009,
            +            "description": "<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1055,
            +            "description": "<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>column ID (Number)\n                              or title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to assign</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1100,
            +            "description": "<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1146,
            +            "description": "<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1190,
            +            "description": "<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "row",
            +                    "description": "<p>row ID</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                  ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1242,
            +            "description": "<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getObject",
            +            "params": [
            +                {
            +                    "name": "headerColumn",
            +                    "description": "<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.Table.js",
            +            "line": 1305,
            +            "description": "<p>Retrieves all table data and returns it as a multidimensional array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getArray",
            +            "return": {
            +                "description": "",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.Table",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 40,
            +            "description": "<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 102,
            +            "description": "<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a Float</p>\n",
            +                    "type": "Number|String"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 146,
            +            "description": "<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "setString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>Column ID (Number)\n                              or Title (String)</p>\n",
            +                    "type": "String|Integer"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>The value to be stored\n                              as a String</p>\n",
            +                    "type": "String|Number|Boolean|Object"
            +                }
            +            ],
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 191,
            +            "description": "<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n",
            +            "itemtype": "method",
            +            "name": "get",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String|Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 239,
            +            "description": "<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "Float Floating point number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.TableRow.js",
            +            "line": 295,
            +            "description": "<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "column",
            +                    "description": "<p>columnName (string) or\n                                 ID (number)</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5.TableRow",
            +            "module": "IO",
            +            "submodule": "Table"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 62,
            +            "description": "<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "getParent",
            +            "return": {
            +                "description": "element parent",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 100,
            +            "description": "<p>Gets the element's full name, which is returned as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "getName",
            +            "return": {
            +                "description": "the name of the node",
            +                "type": "String"
            +            },
            +            "example": [
            +                "&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 135,
            +            "description": "<p>Sets the element's name, which is specified as a String.</p>\n",
            +            "itemtype": "method",
            +            "name": "setName",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>new name of the node</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 181,
            +            "description": "<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasChildren",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 217,
            +            "description": "<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "listChildren",
            +            "return": {
            +                "description": "names of the children of the element",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 258,
            +            "description": "<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChildren",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "children of the element",
            +                "type": "p5.XML[]"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 314,
            +            "description": "<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n",
            +            "itemtype": "method",
            +            "name": "getChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.XML"
            +            },
            +            "example": [
            +                "&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 374,
            +            "description": "<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "addChild",
            +            "params": [
            +                {
            +                    "name": "node",
            +                    "description": "<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n",
            +                    "type": "p5.XML"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 426,
            +            "description": "<p>Removes the element specified by name or index.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeChild",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>element name or index</p>\n",
            +                    "type": "String|Integer"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 498,
            +            "description": "<p>Counts the specified element's number of attributes, returned as an Number.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAttributeCount",
            +            "return": {
            +                "description": "",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 534,
            +            "description": "<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n",
            +            "itemtype": "method",
            +            "name": "listAttributes",
            +            "return": {
            +                "description": "an array of strings containing the names of attributes",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 577,
            +            "description": "<p>Checks whether or not an element has the specified attribute.</p>\n",
            +            "itemtype": "method",
            +            "name": "hasAttribute",
            +            "params": [
            +                {
            +                    "name": "the",
            +                    "description": "<p>attribute to be checked</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "true if attribute found else false",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 622,
            +            "description": "<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getNum",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 669,
            +            "description": "<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getString",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the non-null full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>the default value of the attribute</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 716,
            +            "description": "<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttribute",
            +            "params": [
            +                {
            +                    "name": "name",
            +                    "description": "<p>the full name of the attribute</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value of the attribute</p>\n",
            +                    "type": "Number|String|Boolean"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 757,
            +            "description": "<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "getContent",
            +            "params": [
            +                {
            +                    "name": "defaultValue",
            +                    "description": "<p>value returned if no content is found</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 798,
            +            "description": "<p>Sets the element's content.</p>\n",
            +            "itemtype": "method",
            +            "name": "setContent",
            +            "params": [
            +                {
            +                    "name": "text",
            +                    "description": "<p>the new content</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/io/p5.XML.js",
            +            "line": 839,
            +            "description": "<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n",
            +            "itemtype": "method",
            +            "name": "serialize",
            +            "return": {
            +                "description": "Serialized string of the element",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"
            +            ],
            +            "class": "p5.XML",
            +            "module": "IO",
            +            "submodule": "Input"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 10,
            +            "description": "<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n",
            +            "itemtype": "method",
            +            "name": "abs",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to compute</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "absolute value of given number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"
            +            ],
            +            "alt": "no image displayed",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 33,
            +            "description": "<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n",
            +            "itemtype": "method",
            +            "name": "ceil",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round up</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded up number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 72,
            +            "description": "<p>Constrains a value between a minimum and maximum value.</p>\n",
            +            "itemtype": "method",
            +            "name": "constrain",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to constrain</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "low",
            +                    "description": "<p>minimum limit</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "high",
            +                    "description": "<p>maximum limit</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "constrained number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"
            +            ],
            +            "alt": "2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 116,
            +            "description": "<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "distance between the two points",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"
            +            ],
            +            "alt": "2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 116,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "<p>x-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "<p>y-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "<p>x-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "<p>y-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 161,
            +                    "params": [
            +                        {
            +                            "name": "x1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z1",
            +                            "description": "<p>z-coordinate of the first point</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z2",
            +                            "description": "<p>z-coordinate of the second point</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "distance between the two points",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 182,
            +            "description": "<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n",
            +            "itemtype": "method",
            +            "name": "exp",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>exponent to raise</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "e^n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. e^n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 231,
            +            "description": "<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n",
            +            "itemtype": "method",
            +            "name": "floor",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round down</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded down number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 269,
            +            "description": "<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "params": [
            +                {
            +                    "name": "start",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "amt",
            +                    "description": "<p>number</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "lerped value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"
            +            ],
            +            "alt": "5 points horizontally staggered mid-canvas. mid 3 are grey, outer black",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 316,
            +            "description": "<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n",
            +            "itemtype": "method",
            +            "name": "log",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number greater than 0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "natural logarithm of n",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves along a curve with mouse x. natural logarithm of n displayed.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 371,
            +            "description": "<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "magnitude of vector from (0,0) to (a,b)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"
            +            ],
            +            "alt": "4 lines of different length radiate from top left of canvas.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 409,
            +            "description": "<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n",
            +            "itemtype": "method",
            +            "name": "map",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the incoming value to be converted</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start1",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop1",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start2",
            +                    "description": "<p>lower bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop2",
            +                    "description": "<p>upper bound of the value's target range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "withinBounds",
            +                    "description": "<p>constrain the value to the newly mapped range</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "remapped number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"
            +            ],
            +            "alt": "10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 464,
            +            "description": "<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "max",
            +            "return": {
            +                "description": "maximum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 464,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "maximum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 499,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 512,
            +            "description": "<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n",
            +            "itemtype": "method",
            +            "name": "min",
            +            "return": {
            +                "description": "minimum Number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"
            +            ],
            +            "alt": "Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation",
            +            "overloads": [
            +                {
            +                    "line": 512,
            +                    "params": [
            +                        {
            +                            "name": "n0",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "n1",
            +                            "description": "<p>Number to compare</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "minimum Number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 547,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>Numbers to compare</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 560,
            +            "description": "<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n",
            +            "itemtype": "method",
            +            "name": "norm",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>incoming value to be normalized</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>lower bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "stop",
            +                    "description": "<p>upper bound of the value's current range</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "normalized number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"
            +            ],
            +            "alt": "ellipse moves with mouse. 0 shown left & 100 right and updating values center",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 612,
            +            "description": "<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n",
            +            "itemtype": "method",
            +            "name": "pow",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>base of the exponential expression</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "e",
            +                    "description": "<p>power by which to raise the base</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "n^e",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"
            +            ],
            +            "alt": "small to large ellipses radiating from top left of canvas",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 646,
            +            "description": "<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n",
            +            "itemtype": "method",
            +            "name": "round",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to round</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decimals",
            +                    "description": "<p>number of decimal places to round to, default is 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "rounded number",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"
            +            ],
            +            "alt": "\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 701,
            +            "description": "<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sq",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>number to square</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "squared number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squared values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 745,
            +            "description": "<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n",
            +            "itemtype": "method",
            +            "name": "sqrt",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>non-negative number to square root</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "square root of number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"
            +            ],
            +            "alt": "horizontal center line squareroot values displayed on top and regular on bottom.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/calculation.js",
            +            "line": 832,
            +            "description": "<p>Calculates the fractional part of a number.</p>\n",
            +            "itemtype": "method",
            +            "name": "fract",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>Number whose fractional part needs to be found out</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "fractional part of x, i.e, {x}",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"
            +            ],
            +            "alt": "first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Calculation"
            +        },
            +        {
            +            "file": "src/math/math.js",
            +            "line": 10,
            +            "description": "<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n",
            +            "itemtype": "method",
            +            "name": "createVector",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z component of the vector</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"
            +            ],
            +            "alt": "draws a line from center of canvas to mouse pointer position.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 36,
            +            "description": "<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n",
            +            "itemtype": "method",
            +            "name": "noise",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate in noise space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z-coordinate in noise space</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Perlin noise value (between 0 and 1) at specified\n                     coordinates",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 178,
            +            "description": "<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseDetail",
            +            "params": [
            +                {
            +                    "name": "lod",
            +                    "description": "<p>number of octaves to be used by the noise</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "falloff",
            +                    "description": "<p>falloff factor for each octave</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "2 vertical grey smokey patterns affected my mouse x-position and noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/noise.js",
            +            "line": 243,
            +            "description": "<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "noiseSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical grey lines drawing in pattern affected by noise.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Noise"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 69,
            +            "description": "<p>The x component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "x",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 74,
            +            "description": "<p>The y component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "y",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 79,
            +            "description": "<p>The z component of the vector</p>\n",
            +            "itemtype": "property",
            +            "name": "z",
            +            "type": "Number",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 86,
            +            "description": "<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n",
            +            "itemtype": "method",
            +            "name": "toString",
            +            "return": {
            +                "description": "",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 136,
            +            "description": "<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 136,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 195,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to set</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 219,
            +            "description": "<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n",
            +            "itemtype": "method",
            +            "name": "copy",
            +            "return": {
            +                "description": "the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 248,
            +            "description": "<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 248,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to be added</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to be added</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 325,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to add</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2059,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 372,
            +            "description": "<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "rem",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 372,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of divisor vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 401,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>divisor vector</p>\n",
            +                            "type": "p5.Vector | Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2085,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2091,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 461,
            +            "description": "<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "sub",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 461,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector to subtract</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector to subtract</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 538,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to subtract</p>\n",
            +                            "type": "p5.Vector|Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2110,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the resulting <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 562,
            +            "description": "<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 562,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to multiply with the vector</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 655,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to multiply with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to multiply with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to multiply with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 663,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to multiply with the components of the vector</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 669,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to multiply with the components of the original vector</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2139,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2148,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2156,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2164,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 754,
            +            "description": "<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "div",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 754,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>The number to divide the vector by</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 847,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>The number to divide with the x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>The number to divide with the y component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>The number to divide with the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 855,
            +                    "params": [
            +                        {
            +                            "name": "arr",
            +                            "description": "<p>The array to divide the components of the vector by</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 861,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>The vector to divide the components of the original vector by</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2218,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2227,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "n",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2235,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                },
            +                {
            +                    "line": 2243,
            +                    "params": [
            +                        {
            +                            "name": "v0",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "arr",
            +                            "description": "",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 959,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "itemtype": "method",
            +            "name": "mag",
            +            "return": {
            +                "description": "magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 959,
            +                    "params": [],
            +                    "return": {
            +                        "description": "magnitude of the vector",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2343,
            +                    "params": [
            +                        {
            +                            "name": "vecT",
            +                            "description": "<p>the vector to return the magnitude of</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the magnitude of vecT",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1007,
            +            "description": "<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n",
            +            "itemtype": "method",
            +            "name": "magSq",
            +            "return": {
            +                "description": "squared magnitude of the vector",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1061,
            +            "description": "<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "dot",
            +            "return": {
            +                "description": "the dot product",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1061,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x component of the vector</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 1091,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2270,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the dot product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1103,
            +            "description": "<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n",
            +            "itemtype": "method",
            +            "name": "cross",
            +            "return": {
            +                "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1103,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2284,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the cross product",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1145,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "dist",
            +            "return": {
            +                "description": "the distance",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1145,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 2299,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the distance",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1217,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "return": {
            +                "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1217,
            +                    "params": [],
            +                    "return": {
            +                        "description": "normalized <a href=\"#/p5.Vector\">p5.Vector</a>",
            +                        "type": "p5.Vector"
            +                    }
            +                },
            +                {
            +                    "line": 2360,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the vector to normalize</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "v normalized to a length of 1",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1287,
            +            "description": "<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "limit",
            +            "params": [
            +                {
            +                    "name": "max",
            +                    "description": "<p>the maximum magnitude for the vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1345,
            +            "description": "<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "setMag",
            +            "params": [
            +                {
            +                    "name": "len",
            +                    "description": "<p>the new length for this vector</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1401,
            +            "description": "<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "heading",
            +            "return": {
            +                "description": "the angle of rotation",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1473,
            +            "description": "<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "setHeading",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle of rotation</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1498,
            +            "description": "<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n",
            +            "itemtype": "method",
            +            "name": "rotate",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1498,
            +                    "params": [
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>the angle of rotation</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2191,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1567,
            +            "description": "<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleBetween",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "return": {
            +                "description": "the angle between (in radians)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1647,
            +            "description": "<p>Linear interpolate the vector to another vector</p>\n",
            +            "itemtype": "method",
            +            "name": "lerp",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1647,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 1720,
            +                    "params": [
            +                        {
            +                            "name": "v",
            +                            "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 2314,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "amt",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "target",
            +                            "description": "<p>the vector to receive the result</p>\n",
            +                            "type": "p5.Vector",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "static": 1,
            +                    "return": {
            +                        "description": "the lerped value",
            +                        "type": "p5.Vector"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1736,
            +            "description": "<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n",
            +            "itemtype": "method",
            +            "name": "reflect",
            +            "params": [
            +                {
            +                    "name": "surfaceNormal",
            +                    "description": "<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n",
            +                    "type": "p5.Vector"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1791,
            +            "description": "<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n",
            +            "itemtype": "method",
            +            "name": "array",
            +            "return": {
            +                "description": "an Array with the 3 values",
            +                "type": "Number[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1823,
            +            "description": "<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n",
            +            "itemtype": "method",
            +            "name": "equals",
            +            "return": {
            +                "description": "whether the vectors are equals",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector",
            +            "overloads": [
            +                {
            +                    "line": 1823,
            +                    "params": [
            +                        {
            +                            "name": "x",
            +                            "description": "<p>the x component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>the y component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>the z component of the vector</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "whether the vectors are equals",
            +                        "type": "Boolean"
            +                    }
            +                },
            +                {
            +                    "line": 1853,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>the vector to compare</p>\n",
            +                            "type": "p5.Vector|Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Boolean"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1878,
            +            "description": "<p>Make a new 2D vector from an angle</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngle",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1929,
            +            "description": "<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n",
            +            "itemtype": "method",
            +            "name": "fromAngles",
            +            "static": 1,
            +            "params": [
            +                {
            +                    "name": "theta",
            +                    "description": "<p>the polar angle, in radians (zero is up)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "phi",
            +                    "description": "<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "length",
            +                    "description": "<p>the length of the new vector (defaults to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 1978,
            +            "description": "<p>Make a new 2D unit vector from a random angle</p>\n",
            +            "itemtype": "method",
            +            "name": "random2D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2031,
            +            "description": "<p>Make a new random 3D unit vector.</p>\n",
            +            "itemtype": "method",
            +            "name": "random3D",
            +            "static": 1,
            +            "return": {
            +                "description": "the new <a href=\"#/p5.Vector\">p5.Vector</a> object",
            +                "type": "p5.Vector"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"
            +            ],
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2135,
            +            "description": "<p>Multiplies a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2187,
            +            "description": "<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2214,
            +            "description": "<p>Divides a vector by a scalar and returns a new vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2267,
            +            "description": "<p>Calculates the dot product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2281,
            +            "description": "<p>Calculates the cross product of two vectors.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2295,
            +            "description": "<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2310,
            +            "description": "<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2339,
            +            "description": "<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/p5.Vector.js",
            +            "line": 2357,
            +            "description": "<p>Normalize the vector to length 1 (make it a unit vector).</p>\n",
            +            "class": "p5.Vector",
            +            "module": "Math",
            +            "submodule": "Vector"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 37,
            +            "description": "<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomSeed",
            +            "params": [
            +                {
            +                    "name": "seed",
            +                    "description": "<p>the seed value</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "many vertical lines drawn in white, black or grey.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 66,
            +            "description": "<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n",
            +            "itemtype": "method",
            +            "name": "random",
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"
            +            ],
            +            "alt": "100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random",
            +            "overloads": [
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "min",
            +                            "description": "<p>the lower bound (inclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "max",
            +                            "description": "<p>the upper bound (exclusive)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random number",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 119,
            +                    "params": [
            +                        {
            +                            "name": "choices",
            +                            "description": "<p>the array to choose from</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the random element from the array",
            +                        "type": "*"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/math/random.js",
            +            "line": 153,
            +            "description": "<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n",
            +            "itemtype": "method",
            +            "name": "randomGaussian",
            +            "params": [
            +                {
            +                    "name": "mean",
            +                    "description": "<p>the mean</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sd",
            +                    "description": "<p>the standard deviation</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the random number",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"
            +            ],
            +            "alt": "100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Random"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 18,
            +            "description": "<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "acos",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc cosine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc cosine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 53,
            +            "description": "<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "asin",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc sine is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc sine of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 88,
            +            "description": "<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the value whose arc tangent is to be returned</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 123,
            +            "description": "<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n",
            +            "itemtype": "method",
            +            "name": "atan2",
            +            "params": [
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of the point</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the arc tangent of the given point",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "60 by 10 rect at center of canvas rotates with mouse movements",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 159,
            +            "description": "<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "cos",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the cosine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines form wave patterns, extend-down on left and right side",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 186,
            +            "description": "<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "sin",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the sine of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "vertical black lines extend down and up from center to form wave pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 213,
            +            "description": "<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n",
            +            "itemtype": "method",
            +            "name": "tan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>the angle</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the tangent of the angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"
            +            ],
            +            "alt": "vertical black lines end down and up from center to form spike pattern",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 239,
            +            "description": "<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "degrees",
            +            "params": [
            +                {
            +                    "name": "radians",
            +                    "description": "<p>the radians value to convert to degrees</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 262,
            +            "description": "<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "radians",
            +            "params": [
            +                {
            +                    "name": "degrees",
            +                    "description": "<p>the degree value to convert to radians</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "the converted angle",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/math/trigonometry.js",
            +            "line": 285,
            +            "description": "<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n",
            +            "itemtype": "method",
            +            "name": "angleMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either RADIANS or DEGREES</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"
            +            ],
            +            "alt": "40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.",
            +            "class": "p5",
            +            "module": "Math",
            +            "submodule": "Trigonometry"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 11,
            +            "description": "<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAlign",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"
            +            ],
            +            "alt": "Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "horizAlign",
            +                            "description": "<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "vertAlign",
            +                            "description": "<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n",
            +                            "type": "Constant",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 72,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Object"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 81,
            +            "description": "<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n",
            +            "itemtype": "method",
            +            "name": "textLeading",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"
            +            ],
            +            "alt": "A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 81,
            +                    "params": [
            +                        {
            +                            "name": "leading",
            +                            "description": "<p>the size in pixels for spacing between lines</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 109,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 118,
            +            "description": "<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n",
            +            "itemtype": "method",
            +            "name": "textSize",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 118,
            +                    "params": [
            +                        {
            +                            "name": "theSize",
            +                            "description": "<p>the size of the letters in units of pixels</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 141,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "Number"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 150,
            +            "description": "<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n",
            +            "itemtype": "method",
            +            "name": "textStyle",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"
            +            ],
            +            "alt": "Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes",
            +            "overloads": [
            +                {
            +                    "line": 150,
            +                    "params": [
            +                        {
            +                            "name": "theStyle",
            +                            "description": "<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 178,
            +                    "params": [],
            +                    "return": {
            +                        "description": "",
            +                        "type": "String"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 187,
            +            "description": "<p>Calculates and returns the width of any character or text string.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWidth",
            +            "params": [
            +                {
            +                    "name": "theText",
            +                    "description": "<p>the String of characters to measure</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "the calculated width",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"
            +            ],
            +            "alt": "Letter P and p5.js are displayed with vertical lines at end.",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 222,
            +            "description": "<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textAscent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 251,
            +            "description": "<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n",
            +            "itemtype": "method",
            +            "name": "textDescent",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 280,
            +            "description": "<p>Helper function to measure ascent and descent.</p>\n",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/attributes.js",
            +            "line": 287,
            +            "description": "<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "textWrap",
            +            "params": [
            +                {
            +                    "name": "wrapStyle",
            +                    "description": "<p>text wrapping style, either WORD or CHAR</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "return": {
            +                "description": "wrapStyle",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Attributes"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 16,
            +            "description": "<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadFont",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>name of the file or url to load</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "onError",
            +                    "description": "<p>function to be executed if\n                                   an error occurs</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "<a href=\"#/p5.Font\">p5.Font</a> object",
            +                "type": "p5.Font"
            +            },
            +            "example": [
            +                "\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"
            +            ],
            +            "alt": "p5*js in p5's theme dark pink\np5*js in p5's theme dark pink",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 140,
            +            "description": "<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "text",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the alphanumeric\n                                            symbols to be displayed</p>\n",
            +                    "type": "String|Object|Array|Number|Boolean"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-coordinate of text</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "x2",
            +                    "description": "<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y2",
            +                    "description": "<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/loading_displaying.js",
            +            "line": 231,
            +            "description": "<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n",
            +            "itemtype": "method",
            +            "name": "textFont",
            +            "return": {
            +                "description": "the current font / p5 Object",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold",
            +            "class": "p5",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying",
            +            "overloads": [
            +                {
            +                    "line": 231,
            +                    "params": [],
            +                    "return": {
            +                        "description": "the current font / p5 Object",
            +                        "type": "Object"
            +                    }
            +                },
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "font",
            +                            "description": "<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n",
            +                            "type": "Object|String"
            +                        },
            +                        {
            +                            "name": "size",
            +                            "description": "<p>the font size to use</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 24,
            +            "description": "<p>Underlying opentype font implementation</p>\n",
            +            "itemtype": "property",
            +            "name": "font",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 31,
            +            "description": "<p>Returns a tight bounding box for the given text string using this\nfont</p>\n",
            +            "itemtype": "method",
            +            "name": "textBounds",
            +            "params": [
            +                {
            +                    "name": "line",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional) Default is 12.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a rectangle object with properties: x, y, w, h",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "words Lorem ipsum dol go off canvas and contained by white bounding box",
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/typography/p5.Font.js",
            +            "line": 175,
            +            "description": "<p>Computes an array of points following the path for specified text</p>\n",
            +            "itemtype": "method",
            +            "name": "textToPoints",
            +            "params": [
            +                {
            +                    "name": "txt",
            +                    "description": "<p>a line of text</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "x",
            +                    "description": "<p>x-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y-position</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fontSize",
            +                    "description": "<p>font size to use (optional)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "options",
            +                    "description": "<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "an array of points, each with x, y, alpha (the path angle)",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.Font",
            +            "module": "Typography",
            +            "submodule": "Loading & Displaying"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 10,
            +            "description": "<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n",
            +            "itemtype": "method",
            +            "name": "append",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to append</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>to be added to the Array</p>\n",
            +                    "type": "Any"
            +                }
            +            ],
            +            "return": {
            +                "description": "the array that was appended to",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 35,
            +            "description": "<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n",
            +            "itemtype": "method",
            +            "name": "arrayCopy",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions",
            +            "overloads": [
            +                {
            +                    "line": 35,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "<p>the source Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "srcPosition",
            +                            "description": "<p>starting position in the source Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "<p>the destination Array</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dstPosition",
            +                            "description": "<p>starting position in the destination Array</p>\n",
            +                            "type": "Integer"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "<p>number of Array elements to be copied</p>\n",
            +                            "type": "Integer"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 73,
            +                    "params": [
            +                        {
            +                            "name": "src",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "dst",
            +                            "description": "",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "length",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 112,
            +            "description": "<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n",
            +            "itemtype": "method",
            +            "name": "concat",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.",
            +            "params": [
            +                {
            +                    "name": "a",
            +                    "description": "<p>first Array to concatenate</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "b",
            +                    "description": "<p>second Array to concatenate</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "concatenated array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 141,
            +            "description": "<p>Reverses the order of an array, maps to Array.reverse()</p>\n",
            +            "itemtype": "method",
            +            "name": "reverse",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to reverse</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "the reversed list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 161,
            +            "description": "<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n",
            +            "itemtype": "method",
            +            "name": "shorten",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to shorten</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "shortened Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 185,
            +            "description": "<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "shuffle",
            +            "params": [
            +                {
            +                    "name": "array",
            +                    "description": "<p>Array to shuffle</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "bool",
            +                    "description": "<p>modify passed array</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "shuffled Array",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 227,
            +            "description": "<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n",
            +            "itemtype": "method",
            +            "name": "sort",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to sort</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of elements to sort, starting from 0</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "the sorted list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 273,
            +            "description": "<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n",
            +            "itemtype": "method",
            +            "name": "splice",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to splice into</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>value to be spliced in</p>\n",
            +                    "type": "Any"
            +                },
            +                {
            +                    "name": "position",
            +                    "description": "<p>in the array from which to insert data</p>\n",
            +                    "type": "Integer"
            +                }
            +            ],
            +            "return": {
            +                "description": "the list",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/array_functions.js",
            +            "line": 308,
            +            "description": "<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n",
            +            "itemtype": "method",
            +            "name": "subset",
            +            "deprecated": true,
            +            "deprecationMessage": "Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>Array to extract from</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "start",
            +                    "description": "<p>position to begin</p>\n",
            +                    "type": "Integer"
            +                },
            +                {
            +                    "name": "count",
            +                    "description": "<p>number of values to extract</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of extracted elements",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Array Functions"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 10,
            +            "description": "<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "float",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>float string to parse</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "floating point representation of string",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "alt": "20 by 20 white ellipse in the center of the canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 44,
            +            "description": "<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "int",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 44,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "<p>the radix to convert to (default: 10)</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 66,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "radix",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 88,
            +            "description": "<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "str",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 114,
            +            "description": "<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n",
            +            "itemtype": "method",
            +            "name": "boolean",
            +            "params": [
            +                {
            +                    "name": "n",
            +                    "description": "<p>value to parse</p>\n",
            +                    "type": "String|Boolean|Number|Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "boolean representation of value",
            +                "type": "Boolean"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion"
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 146,
            +            "description": "<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "byte",
            +            "return": {
            +                "description": "byte representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 146,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Boolean|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "byte representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 168,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of byte representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 182,
            +            "description": "<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "char",
            +            "return": {
            +                "description": "string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 182,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String|Number"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 201,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "array of string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 216,
            +            "description": "<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unchar",
            +            "return": {
            +                "description": "integer representation of value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 216,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 232,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of values",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 245,
            +            "description": "<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "hex",
            +            "return": {
            +                "description": "hexadecimal string representation of value",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 245,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of value",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 265,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>array of values to parse</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "digits",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "hexadecimal string representation of values",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/conversion.js",
            +            "line": 295,
            +            "description": "<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n",
            +            "itemtype": "method",
            +            "name": "unhex",
            +            "return": {
            +                "description": "integer representation of hexadecimal value",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "Conversion",
            +            "overloads": [
            +                {
            +                    "line": 295,
            +                    "params": [
            +                        {
            +                            "name": "n",
            +                            "description": "<p>value to parse</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representation of hexadecimal value",
            +                        "type": "Number"
            +                    }
            +                },
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "ns",
            +                            "description": "<p>values to parse</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "integer representations of hexadecimal value",
            +                        "type": "Number[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 15,
            +            "description": "<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n",
            +            "itemtype": "method",
            +            "name": "join",
            +            "params": [
            +                {
            +                    "name": "list",
            +                    "description": "<p>array of Strings to be joined</p>\n",
            +                    "type": "Array"
            +                },
            +                {
            +                    "name": "separator",
            +                    "description": "<p>String to be placed between each item</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "joined String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"hello world!\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 43,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "match",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"p5js*\" displayed middle left of canvas.",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 83,
            +            "description": "<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n",
            +            "itemtype": "method",
            +            "name": "matchAll",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>the String to be searched</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "regexp",
            +                    "description": "<p>the regexp to be used for matching</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "2d Array of Strings found",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 130,
            +            "description": "<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nf",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" middle top, -1321.00\" middle bottom canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 130,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 176,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 237,
            +            "description": "<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfc",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 237,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number|String"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                                 decimal point</p>\n",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 275,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer|String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 311,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfp",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 311,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 352,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Number[]"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 373,
            +            "description": "<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n",
            +            "itemtype": "method",
            +            "name": "nfs",
            +            "return": {
            +                "description": "formatted String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "\"0321.00\" top middle and \"-1321.00\" displayed bottom middle",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 373,
            +                    "params": [
            +                        {
            +                            "name": "num",
            +                            "description": "<p>the Number to format</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "<p>number of digits to the left of the decimal\n                               point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "<p>number of digits to the right of the\n                               decimal point</p>\n",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 430,
            +                    "params": [
            +                        {
            +                            "name": "nums",
            +                            "description": "<p>the Numbers to format</p>\n",
            +                            "type": "Array"
            +                        },
            +                        {
            +                            "name": "left",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "right",
            +                            "description": "",
            +                            "type": "Integer",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "formatted Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 451,
            +            "description": "<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n",
            +            "itemtype": "method",
            +            "name": "split",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>the String used to separate the data</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"
            +            ],
            +            "alt": "\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 484,
            +            "description": "<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n",
            +            "itemtype": "method",
            +            "name": "splitTokens",
            +            "params": [
            +                {
            +                    "name": "value",
            +                    "description": "<p>the String to be split</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "delim",
            +                    "description": "<p>list of individual Strings that will be used as\n                         separators</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of Strings",
            +                "type": "String[]"
            +            },
            +            "example": [
            +                "\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions"
            +        },
            +        {
            +            "file": "src/utilities/string_functions.js",
            +            "line": 537,
            +            "description": "<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n",
            +            "itemtype": "method",
            +            "name": "trim",
            +            "return": {
            +                "description": "a trimmed String",
            +                "type": "String"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "\"No new lines here\" displayed center canvas",
            +            "class": "p5",
            +            "module": "Data",
            +            "submodule": "String Functions",
            +            "overloads": [
            +                {
            +                    "line": 537,
            +                    "params": [
            +                        {
            +                            "name": "str",
            +                            "description": "<p>a String to be trimmed</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "a trimmed String",
            +                        "type": "String"
            +                    }
            +                },
            +                {
            +                    "line": 557,
            +                    "params": [
            +                        {
            +                            "name": "strs",
            +                            "description": "<p>an Array of Strings to be trimmed</p>\n",
            +                            "type": "Array"
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "an Array of trimmed Strings",
            +                        "type": "String[]"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 10,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n",
            +            "itemtype": "method",
            +            "name": "day",
            +            "return": {
            +                "description": "the current day",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current day is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 31,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n",
            +            "itemtype": "method",
            +            "name": "hour",
            +            "return": {
            +                "description": "the current hour",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current hour is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 52,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "minute",
            +            "return": {
            +                "description": "the current minute",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current minute is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 73,
            +            "description": "<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n",
            +            "itemtype": "method",
            +            "name": "millis",
            +            "return": {
            +                "description": "the number of milliseconds since starting the sketch",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"
            +            ],
            +            "alt": "number of milliseconds since sketch has started displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 100,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n",
            +            "itemtype": "method",
            +            "name": "month",
            +            "return": {
            +                "description": "the current month",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current month is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 122,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n",
            +            "itemtype": "method",
            +            "name": "second",
            +            "return": {
            +                "description": "the current second",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current second is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/utilities/time_date.js",
            +            "line": 143,
            +            "description": "<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n",
            +            "itemtype": "method",
            +            "name": "year",
            +            "return": {
            +                "description": "the current year",
            +                "type": "Integer"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"
            +            ],
            +            "alt": "Current year is displayed",
            +            "class": "p5",
            +            "module": "IO",
            +            "submodule": "Time & Date"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 13,
            +            "description": "<p>Draw a plane with given a width and height</p>\n",
            +            "itemtype": "method",
            +            "name": "plane",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 97,
            +            "description": "<p>Draw a box with given width, height and depth</p>\n",
            +            "itemtype": "method",
            +            "name": "box",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>width of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "Height",
            +                    "description": "<p>height of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "depth",
            +                    "description": "<p>depth of the box</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 215,
            +            "description": "<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "sphere",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of circle</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>optional number of subdivisions in x-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>optional number of subdivisions in y-dimension</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 419,
            +            "description": "<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cylinder",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cylinder</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottomCap",
            +                    "description": "<p>whether to draw the bottom of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "topCap",
            +                    "description": "<p>whether to draw the top of the cylinder</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 554,
            +            "description": "<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "cone",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the bottom surface</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "height",
            +                    "description": "<p>height of the cone</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cap",
            +                    "description": "<p>whether to draw the base of the cone</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 669,
            +            "description": "<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n",
            +            "itemtype": "method",
            +            "name": "ellipsoid",
            +            "params": [
            +                {
            +                    "name": "radiusx",
            +                    "description": "<p>x-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusy",
            +                    "description": "<p>y-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "radiusz",
            +                    "description": "<p>z-radius of ellipsoid</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/3d_primitives.js",
            +            "line": 804,
            +            "description": "<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n",
            +            "itemtype": "method",
            +            "name": "torus",
            +            "params": [
            +                {
            +                    "name": "radius",
            +                    "description": "<p>radius of the whole ring</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tubeRadius",
            +                    "description": "<p>radius of the tube</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailX",
            +                    "description": "<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "detailY",
            +                    "description": "<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n",
            +                    "type": "Integer",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 11,
            +            "description": "<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n",
            +            "itemtype": "method",
            +            "name": "orbitControl",
            +            "params": [
            +                {
            +                    "name": "sensitivityX",
            +                    "description": "<p>sensitivity to mouse movement along X axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityY",
            +                    "description": "<p>sensitivity to mouse movement along Y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sensitivityZ",
            +                    "description": "<p>sensitivity to scroll movement along Z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Camera orbits around a box when mouse is hold-clicked & then moved.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 145,
            +            "description": "<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n",
            +            "itemtype": "method",
            +            "name": "debugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction",
            +            "overloads": [
            +                {
            +                    "line": 145,
            +                    "params": []
            +                },
            +                {
            +                    "line": 278,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "<p>either GRID or AXES</p>\n",
            +                            "type": "Constant"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 283,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "gridSize",
            +                            "description": "<p>size of one side of the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "<p>number of divisions in the grid</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "<p>X axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "<p>Y axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "<p>Z axis offset from origin (0,0,0)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 293,
            +                    "params": [
            +                        {
            +                            "name": "mode",
            +                            "description": "",
            +                            "type": "Constant"
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "<p>size of axes icon</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "xOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "yOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "zOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 302,
            +                    "params": [
            +                        {
            +                            "name": "gridSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridDivisions",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "gridZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesSize",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesXOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesYOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "axesZOff",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/interaction.js",
            +            "line": 353,
            +            "description": "<p>Turns off debugMode() in a 3D sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noDebugMode",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Interaction"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 11,
            +            "description": "<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "evenly distributed light across a sphere\nevenly distributed light across a rotating sphere",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 11,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>the alpha value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 51,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 57,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 64,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 71,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 92,
            +            "description": "<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularColor",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "different specular light sources from top and bottom of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 92,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 139,
            +                    "params": [
            +                        {
            +                            "name": "value",
            +                            "description": "<p>a color string</p>\n",
            +                            "type": "String"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 145,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>a gray value</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 151,
            +                    "params": [
            +                        {
            +                            "name": "values",
            +                            "description": "<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n",
            +                            "type": "Number[]"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 158,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>the ambient light color</p>\n",
            +                            "type": "p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 177,
            +            "description": "<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "directionalLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "light source on canvas changeable with mouse position",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 177,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 210,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis direction</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis direction</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 220,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 227,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 280,
            +            "description": "<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "pointLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "spot light on canvas changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 280,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 322,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 331,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 341,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 387,
            +            "description": "<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "lights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "the light is partially ambient and partially directional",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 425,
            +            "description": "<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n",
            +            "itemtype": "method",
            +            "name": "lightFalloff",
            +            "params": [
            +                {
            +                    "name": "constant",
            +                    "description": "<p>constant value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "linear",
            +                    "description": "<p>linear value for determining falloff</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "quadratic",
            +                    "description": "<p>quadratic value for determining falloff</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two spheres with different falloff values show different intensity of light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 519,
            +            "description": "<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n",
            +            "itemtype": "method",
            +            "name": "spotLight",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Spot light on a sphere which changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights",
            +            "overloads": [
            +                {
            +                    "line": 519,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value (depending on the current\ncolor mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "<p>x axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "<p>y axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "<p>z axis position</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "<p>x axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "<p>y axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "<p>z axis direction of light</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "<p>optional parameter for angle. Defaults to PI/3</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "<p>optional parameter for concentration. Defaults to 100</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 571,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "<p>the position of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "<p>the direction of the light</p>\n",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 580,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 590,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 600,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 610,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "direction",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 622,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "position",
            +                            "description": "",
            +                            "type": "p5.Vector"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 634,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "",
            +                            "type": "Number[]|String|p5.Color"
            +                        },
            +                        {
            +                            "name": "x",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "y",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "z",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rx",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "ry",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "rz",
            +                            "description": "",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "angle",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "conc",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/light.js",
            +            "line": 859,
            +            "description": "<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLights",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Three white spheres. Each appears as a different\ncolor due to lighting.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Lights"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 12,
            +            "description": "<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadModel",
            +            "return": {
            +                "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                "type": "p5.Geometry"
            +            },
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d teapot with red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models",
            +            "overloads": [
            +                {
            +                    "line": 12,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "<p>Path of the model to be loaded</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "normalize",
            +                            "description": "<p>If true, scale the model to a\n                                     standardized size when loading</p>\n",
            +                            "type": "Boolean"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "<p>called with event error if\n                                        the model fails to load.</p>\n",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                },
            +                {
            +                    "line": 96,
            +                    "params": [
            +                        {
            +                            "name": "path",
            +                            "description": "",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "successCallback",
            +                            "description": "",
            +                            "type": "function(p5.Geometry)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "failureCallback",
            +                            "description": "",
            +                            "type": "Function(Event)",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "fileType",
            +                            "description": "",
            +                            "type": "String",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "return": {
            +                        "description": "the <a href=\"#/p5.Geometry\">p5.Geometry</a> object",
            +                        "type": "p5.Geometry"
            +                    }
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 179,
            +            "description": "<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 290,
            +            "description": "<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 317,
            +            "description": "<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 344,
            +            "description": "<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 356,
            +            "description": "<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 444,
            +            "description": "<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/loading.js",
            +            "line": 588,
            +            "description": "<p>Render a 3d model to the screen.</p>\n",
            +            "itemtype": "method",
            +            "name": "model",
            +            "params": [
            +                {
            +                    "name": "model",
            +                    "description": "<p>Loaded 3d model to be rendered</p>\n",
            +                    "type": "p5.Geometry"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Vertically rotating 3-d octahedron.",
            +            "class": "p5",
            +            "module": "Shape",
            +            "submodule": "3D Models"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 12,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadShader",
            +            "params": [
            +                {
            +                    "name": "vertFilename",
            +                    "description": "<p>path to file containing vertex shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragFilename",
            +                    "description": "<p>path to file containing fragment shader\nsource code</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shader files.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 111,
            +            "description": "<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "createShader",
            +            "params": [
            +                {
            +                    "name": "vertSrc",
            +                    "description": "<p>source code for the vertex shader</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "fragSrc",
            +                    "description": "<p>source code for the fragment shader</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "return": {
            +                "description": "a shader object created from the provided\nvertex and fragment shaders.",
            +                "type": "p5.Shader"
            +            },
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "zooming Mandelbrot set. a colorful, infinitely detailed fractal.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 184,
            +            "description": "<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "shader",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "s",
            +                    "description": "<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n",
            +                    "type": "p5.Shader"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 282,
            +            "description": "<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "resetShader",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 368,
            +            "description": "<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "texture",
            +            "params": [
            +                {
            +                    "name": "tex",
            +                    "description": "<p>image to use as texture</p>\n",
            +                    "type": "p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using normalized coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 511,
            +            "description": "<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n",
            +            "itemtype": "method",
            +            "name": "textureMode",
            +            "params": [
            +                {
            +                    "name": "mode",
            +                    "description": "<p>either IMAGE or NORMAL</p>\n",
            +                    "type": "Constant"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "quad with a texture, mapped using image coordinates",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 587,
            +            "description": "<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n",
            +            "itemtype": "method",
            +            "name": "textureWrap",
            +            "params": [
            +                {
            +                    "name": "wrapX",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant"
            +                },
            +                {
            +                    "name": "wrapY",
            +                    "description": "<p>either CLAMP, REPEAT, or MIRROR</p>\n",
            +                    "type": "Constant",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "an image of the rocky mountains repeated in mirrored tiles",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 659,
            +            "description": "<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Red, green and blue gradient.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 697,
            +            "description": "<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "ambientMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 697,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 757,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 777,
            +            "description": "<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n",
            +            "itemtype": "method",
            +            "name": "emissiveMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "radiating light source from top right of canvas",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 777,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        },
            +                        {
            +                            "name": "a",
            +                            "description": "<p>opacity</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 809,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color, color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 829,
            +            "description": "<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "specularMaterial",
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "torus with specular material",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material",
            +            "overloads": [
            +                {
            +                    "line": 829,
            +                    "params": [
            +                        {
            +                            "name": "gray",
            +                            "description": "<p>number specifying value between white and black.</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 870,
            +                    "params": [
            +                        {
            +                            "name": "v1",
            +                            "description": "<p>red or hue value relative to\n                                the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v2",
            +                            "description": "<p>green or saturation value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "v3",
            +                            "description": "<p>blue or brightness value\n                                relative to the current color range</p>\n",
            +                            "type": "Number"
            +                        },
            +                        {
            +                            "name": "alpha",
            +                            "description": "",
            +                            "type": "Number",
            +                            "optional": true
            +                        }
            +                    ],
            +                    "chainable": 1
            +                },
            +                {
            +                    "line": 882,
            +                    "params": [
            +                        {
            +                            "name": "color",
            +                            "description": "<p>color Array, or CSS color string</p>\n",
            +                            "type": "Number[]|String|p5.Color"
            +                        }
            +                    ],
            +                    "chainable": 1
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/material.js",
            +            "line": 902,
            +            "description": "<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n",
            +            "itemtype": "method",
            +            "name": "shininess",
            +            "params": [
            +                {
            +                    "name": "shine",
            +                    "description": "<p>Degree of Shininess.\n                      Defaults to 1.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Shininess on Camera changes position with mouse",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 13,
            +            "description": "<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "is_constructor": 1,
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>camera position value on x axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>camera position value on y axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>camera position value on z axis</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerX",
            +                    "description": "<p>x coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerY",
            +                    "description": "<p>y coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "centerZ",
            +                    "description": "<p>z coordinate representing center of the sketch</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upX",
            +                    "description": "<p>x component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upY",
            +                    "description": "<p>y component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "upZ",
            +                    "description": "<p>z component of direction 'up' from camera</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 115,
            +            "description": "<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "params": [
            +                {
            +                    "name": "fovy",
            +                    "description": "<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "aspect",
            +                    "description": "<p>camera frustum aspect ratio</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>frustum near plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>frustum far plane length</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 176,
            +            "description": "<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 236,
            +            "description": "<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "params": [
            +                {
            +                    "name": "left",
            +                    "description": "<p>camera frustum left plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "right",
            +                    "description": "<p>camera frustum right plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "bottom",
            +                    "description": "<p>camera frustum bottom plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "top",
            +                    "description": "<p>camera frustum top plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "near",
            +                    "description": "<p>camera frustum near plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "far",
            +                    "description": "<p>camera frustum far plane</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "chainable": 1,
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 303,
            +            "description": "<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n",
            +            "itemtype": "method",
            +            "name": "createCamera",
            +            "return": {
            +                "description": "The newly created camera object.",
            +                "type": "p5.Camera"
            +            },
            +            "example": [
            +                "\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"
            +            ],
            +            "alt": "An example that creates a camera and moves it around the box.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 444,
            +            "description": "<p>camera position value on x axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 472,
            +            "description": "<p>camera position value on y axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 499,
            +            "description": "<p>camera position value on z axis</p>\n",
            +            "itemtype": "property",
            +            "name": "eyeZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 526,
            +            "description": "<p>x coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 554,
            +            "description": "<p>y coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 582,
            +            "description": "<p>z coordinate representing center of the sketch</p>\n",
            +            "itemtype": "property",
            +            "name": "centerZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 610,
            +            "description": "<p>x component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upX",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 633,
            +            "description": "<p>y component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upY",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 656,
            +            "description": "<p>z component of direction 'up' from camera</p>\n",
            +            "itemtype": "property",
            +            "name": "upZ",
            +            "type": "Number",
            +            "readonly": "",
            +            "example": [
            +                "\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"
            +            ],
            +            "alt": "An example showing the use of camera object properties",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 683,
            +            "description": "<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "perspective",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two colored 3D boxes move back and forth, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 801,
            +            "description": "<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "ortho",
            +            "example": [
            +                "\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 897,
            +            "description": "<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "frustum",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"
            +            ],
            +            "alt": "two 3D boxes move back and forth along same plane, rotating as mouse is dragged.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1040,
            +            "description": "<p>Panning rotates the camera view to the left and right.</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view pans left and right across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1098,
            +            "description": "<p>Tilting rotates the camera view up and down.</p>\n",
            +            "itemtype": "method",
            +            "name": "tilt",
            +            "params": [
            +                {
            +                    "name": "angle",
            +                    "description": "<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view tilts up and down across a series of rotating 3D boxes.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1156,
            +            "description": "<p>Reorients the camera to look at a position in world space.</p>\n",
            +            "itemtype": "method",
            +            "name": "lookAt",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view of rotating 3D cubes changes to look at a new random\npoint every second .",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1223,
            +            "description": "<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n",
            +            "itemtype": "method",
            +            "name": "camera",
            +            "example": [
            +                "\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>",
            +                "\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1386,
            +            "description": "<p>Move camera along its local axes while maintaining current camera orientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "move",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>amount to move along camera's left-right axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>amount to move along camera's up-down axis</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>amount to move along camera's forward-backward axis</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1458,
            +            "description": "<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n",
            +            "itemtype": "method",
            +            "name": "setPosition",
            +            "params": [
            +                {
            +                    "name": "x",
            +                    "description": "<p>x position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "y",
            +                    "description": "<p>y position of a point in world space</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "z",
            +                    "description": "<p>z position of a point in world space</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "camera position changes as the user presses keys, altering view of a 3D box",
            +            "class": "p5.Camera",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Camera.js",
            +            "line": 1723,
            +            "description": "<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n",
            +            "itemtype": "method",
            +            "name": "setCamera",
            +            "params": [
            +                {
            +                    "name": "cam",
            +                    "description": "<p>p5.Camera object</p>\n",
            +                    "type": "p5.Camera"
            +                }
            +            ],
            +            "example": [
            +                "\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "Canvas switches between two camera views, each showing a series of spinning\n3D boxes.",
            +            "class": "p5",
            +            "module": "3D",
            +            "submodule": "Camera"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 71,
            +            "description": "<p>computes faces for geometry objects based on the vertices.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeFaces",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 114,
            +            "description": "<p>computes smooth normals per vertex as an average of each\nface.</p>\n",
            +            "itemtype": "method",
            +            "name": "computeNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 153,
            +            "description": "<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n",
            +            "itemtype": "method",
            +            "name": "averageNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 174,
            +            "description": "<p>Averages pole normals.  Used in spherical primitives</p>\n",
            +            "itemtype": "method",
            +            "name": "averagePoleNormals",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.Geometry.js",
            +            "line": 267,
            +            "description": "<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n",
            +            "itemtype": "method",
            +            "name": "normalize",
            +            "chainable": 1,
            +            "class": "p5.Geometry",
            +            "module": "Shape",
            +            "submodule": "3D Primitives"
            +        },
            +        {
            +            "file": "src/webgl/p5.RendererGL.js",
            +            "line": 334,
            +            "description": "<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n",
            +            "itemtype": "method",
            +            "name": "setAttributes",
            +            "example": [
            +                "\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"
            +            ],
            +            "alt": "a rotating cube with smoother edges",
            +            "class": "p5",
            +            "module": "Rendering",
            +            "submodule": "Rendering",
            +            "overloads": [
            +                {
            +                    "line": 334,
            +                    "params": [
            +                        {
            +                            "name": "key",
            +                            "description": "<p>Name of attribute</p>\n",
            +                            "type": "String"
            +                        },
            +                        {
            +                            "name": "value",
            +                            "description": "<p>New value of named attribute</p>\n",
            +                            "type": "Boolean"
            +                        }
            +                    ]
            +                },
            +                {
            +                    "line": 473,
            +                    "params": [
            +                        {
            +                            "name": "obj",
            +                            "description": "<p>object with key-value pairs</p>\n",
            +                            "type": "Object"
            +                        }
            +                    ]
            +                }
            +            ]
            +        },
            +        {
            +            "file": "src/webgl/p5.Shader.js",
            +            "line": 306,
            +            "description": "<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n",
            +            "itemtype": "method",
            +            "name": "setUniform",
            +            "chainable": 1,
            +            "params": [
            +                {
            +                    "name": "uniformName",
            +                    "description": "<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "data",
            +                    "description": "<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n",
            +                    "type": "Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"
            +                }
            +            ],
            +            "example": [
            +                "\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"
            +            ],
            +            "alt": "canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.",
            +            "class": "p5.Shader",
            +            "module": "3D",
            +            "submodule": "Material"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1,
            +            "class": "p5.sound",
            +            "module": "3D"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 52,
            +            "description": "<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n",
            +            "class": "p5.sound",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 159,
            +            "description": "<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>",
            +            "itemtype": "method",
            +            "name": "getAudioContext",
            +            "return": {
            +                "description": "AudioContext for this sketch",
            +                "type": "Object"
            +            },
            +            "example": [
            +                "\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 198,
            +            "description": "<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>",
            +            "params": [
            +                {
            +                    "name": "element(s)",
            +                    "description": "<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n",
            +                    "type": "Element|Array",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback to invoke when the AudioContext\n                              has started</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that resolves when\n                                     the AudioContext state is 'running'",
            +                "type": "Promise"
            +            },
            +            "itemtype": "method",
            +            "name": "userStartAudio",
            +            "example": [
            +                "\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 401,
            +            "description": "<p>This module has shims</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 536,
            +            "description": "<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 726,
            +            "description": "<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOutputVolume",
            +            "return": {
            +                "description": "Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 738,
            +            "description": "<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>",
            +            "itemtype": "method",
            +            "name": "outputVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 782,
            +            "description": "<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n",
            +            "itemtype": "property",
            +            "name": "soundOut",
            +            "type": "Object",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 807,
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 811,
            +            "description": "<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "samplerate samples per second",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 825,
            +            "description": "<p>Returns the closest MIDI note value for\na given frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "freqToMidi",
            +            "params": [
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "MIDI note value",
            +                "type": "Number"
            +            },
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 841,
            +            "description": "<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n",
            +            "itemtype": "method",
            +            "name": "midiToFreq",
            +            "params": [
            +                {
            +                    "name": "midiNote",
            +                    "description": "<p>The number of a MIDI note</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency value of the given MIDI note",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 925,
            +            "description": "<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n",
            +            "itemtype": "method",
            +            "name": "soundFormats",
            +            "params": [
            +                {
            +                    "name": "formats",
            +                    "description": "<p>i.e. 'mp3', 'wav', 'ogg'</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1040,
            +            "description": "<p>Used by Osc and Envelope to chain signal math</p>\n",
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1145,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "saveSound",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile that you wish to save</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1662,
            +            "description": "<p>Returns true if the sound file finished loading successfully.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLoaded",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1679,
            +            "description": "<p>Play the p5.SoundFile</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule playback to start (in seconds from now).</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) amplitude (volume)\n                                    of playback</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueStart",
            +                    "description": "<p>(optional) cue start time in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) duration of playback in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1787,
            +            "description": "<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n",
            +            "itemtype": "method",
            +            "name": "playMode",
            +            "params": [
            +                {
            +                    "name": "str",
            +                    "description": "<p>'restart' or 'sustain' or 'untilDone'</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1847,
            +            "description": "<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                             seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1905,
            +            "description": "<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rate",
            +                    "description": "<p>(optional) playback rate</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "amp",
            +                    "description": "<p>(optional) playback volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "cueLoopStart",
            +                    "description": "<p>(optional) startTime in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>(optional) loop duration in seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1950,
            +            "description": "<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "setLoop",
            +            "params": [
            +                {
            +                    "name": "Boolean",
            +                    "description": "<p>set looping to true or false</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1976,
            +            "description": "<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n",
            +            "itemtype": "method",
            +            "name": "isLooping",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 1997,
            +            "description": "<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPlaying",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2011,
            +            "description": "<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n",
            +            "itemtype": "method",
            +            "name": "isPaused",
            +            "return": {
            +                "description": "",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2025,
            +            "description": "<p>Stop soundfile playback.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>(optional) schedule event to occur\n                            in seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2087,
            +            "description": "<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panValue",
            +                    "description": "<p>Set the stereo panner</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                                seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2131,
            +            "description": "<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2146,
            +            "description": "<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "rate",
            +            "params": [
            +                {
            +                    "name": "playbackRate",
            +                    "description": "<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2239,
            +            "description": "<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "setVolume",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Fade for t seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen at\n                               t seconds in the future</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2276,
            +            "description": "<p>Returns the duration of a sound file in seconds.</p>\n",
            +            "itemtype": "method",
            +            "name": "duration",
            +            "return": {
            +                "description": "The duration of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2293,
            +            "description": "<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n",
            +            "itemtype": "method",
            +            "name": "currentTime",
            +            "return": {
            +                "description": "currentTime of the soundFile in seconds.",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2308,
            +            "description": "<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n",
            +            "itemtype": "method",
            +            "name": "jump",
            +            "params": [
            +                {
            +                    "name": "cueTime",
            +                    "description": "<p>cueTime of the soundFile in seconds.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>duration in seconds.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2340,
            +            "description": "<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n",
            +            "itemtype": "method",
            +            "name": "channels",
            +            "return": {
            +                "description": "[channels]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2354,
            +            "description": "<p>Return the sample rate of the sound file.</p>\n",
            +            "itemtype": "method",
            +            "name": "sampleRate",
            +            "return": {
            +                "description": "[sampleRate]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2367,
            +            "description": "<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n",
            +            "itemtype": "method",
            +            "name": "frames",
            +            "return": {
            +                "description": "[sampleCount]",
            +                "type": "Number"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2381,
            +            "description": "<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPeaks",
            +            "params": [
            +                {
            +                    "name": "length",
            +                    "description": "<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array of peaks.",
            +                "type": "Float32Array"
            +            },
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2443,
            +            "description": "<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n",
            +            "itemtype": "method",
            +            "name": "reverseBuffer",
            +            "example": [
            +                "\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2497,
            +            "description": "<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n",
            +            "itemtype": "method",
            +            "name": "onended",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call when the\n                            soundfile has ended.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2565,
            +            "description": "<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "object",
            +                    "description": "<p>Audio object that accepts an input</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2590,
            +            "description": "<p>Disconnects the output of this p5sound object.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2604,
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2612,
            +            "description": "<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n",
            +            "itemtype": "method",
            +            "name": "setPath",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to audio file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Callback</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2630,
            +            "description": "<p>Replace the current Audio Buffer with a new Buffer.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBuffer",
            +            "params": [
            +                {
            +                    "name": "buf",
            +                    "description": "<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2719,
            +            "description": "<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n",
            +            "itemtype": "method",
            +            "name": "addCue",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "value",
            +                    "description": "<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "id ID of this cue,\n                    useful for removeCue(id)",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2790,
            +            "description": "<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "removeCue",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>ID of the cue, as returned by addCue</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2817,
            +            "description": "<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n",
            +            "itemtype": "method",
            +            "name": "clearCues",
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2850,
            +            "description": "<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n",
            +            "itemtype": "method",
            +            "name": "save",
            +            "params": [
            +                {
            +                    "name": "fileName",
            +                    "description": "<p>name of the resulting .wav file.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2882,
            +            "description": "<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBlob",
            +            "return": {
            +                "description": "A file-like data object",
            +                "type": "Blob"
            +            },
            +            "example": [
            +                "\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"
            +            ],
            +            "class": "p5.SoundFile",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 2946,
            +            "description": "<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n",
            +            "itemtype": "method",
            +            "name": "loadSound",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n",
            +                    "type": "String|Array"
            +                },
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call once file loads</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "whileLoading",
            +                    "description": "<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a p5.SoundFile",
            +                "type": "SoundFile"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3117,
            +            "description": "<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "snd",
            +                    "description": "<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n",
            +                    "type": "SoundObject|undefined",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n",
            +                    "type": "Number|undefined",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3209,
            +            "description": "<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "channel",
            +                    "description": "<p>Optionally return only channel 0 (left) or 1 (right)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Amplitude as a number between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3264,
            +            "description": "<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleNormalize",
            +            "params": [
            +                {
            +                    "name": "boolean",
            +                    "description": "<p>set normalize to true (1) or false (0)</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3293,
            +            "description": "<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "set",
            +                    "description": "<p>smoothing from 0.0 <= 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Amplitude",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3476,
            +            "description": "<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "source",
            +                    "description": "<p>p5.sound object (or web audio API source node)</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3501,
            +            "description": "<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n",
            +            "itemtype": "method",
            +            "name": "waveform",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "precision",
            +                    "description": "<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3553,
            +            "description": "<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "analyze",
            +            "params": [
            +                {
            +                    "name": "bins",
            +                    "description": "<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "scale",
            +                    "description": "<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.",
            +                "type": "Array"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3650,
            +            "description": "<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getEnergy",
            +            "params": [
            +                {
            +                    "name": "frequency1",
            +                    "description": "<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n",
            +                    "type": "Number|String"
            +                },
            +                {
            +                    "name": "frequency2",
            +                    "description": "<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Energy   Energy (volume/amplitude) from\n                            0 and 255.",
            +                "type": "Number"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3739,
            +            "description": "<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "getCentroid",
            +            "return": {
            +                "description": "Spectral Centroid Frequency  of the spectral centroid in Hz.",
            +                "type": "Number"
            +            },
            +            "example": [
            +                "\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3826,
            +            "description": "<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n",
            +            "itemtype": "method",
            +            "name": "smooth",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3854,
            +            "description": "<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "linAverages",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Number of returned frequency groups</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "linearAverages   Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3889,
            +            "description": "<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n",
            +            "itemtype": "method",
            +            "name": "logAverages",
            +            "params": [
            +                {
            +                    "name": "octaveBands",
            +                    "description": "<p>Array of Octave Bands objects for grouping</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "return": {
            +                "description": "logAverages    Array of average amplitude values for each group",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 3925,
            +            "description": "<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOctaveBands",
            +            "params": [
            +                {
            +                    "name": "N",
            +                    "description": "<p>Specifies the 1/N type of generated octave bands</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "fCtr0",
            +                    "description": "<p>Minimum central frequency for the lowest band</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "octaveBands   Array of octave band objects with their bounds",
            +                "type": "Array"
            +            },
            +            "class": "p5.FFT",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4168,
            +            "description": "<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>startTime in seconds from now.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "frequency",
            +                    "description": "<p>frequency in Hz.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4218,
            +            "description": "<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>Time, in seconds from now.</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4238,
            +            "description": "<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)",
            +                "type": "AudioParam"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4271,
            +            "description": "<p>Returns the value of output gain</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmp",
            +            "return": {
            +                "description": "Amplitude value between 0.0 and 1.0",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4285,
            +            "description": "<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "Frequency",
            +                    "description": "<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Ramp time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Schedule this event to happen\n                                 at x seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency",
            +                "type": "AudioParam"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4360,
            +            "description": "<p>Returns the value of frequency of oscillator</p>\n",
            +            "itemtype": "method",
            +            "name": "getFreq",
            +            "return": {
            +                "description": "Frequency of oscillator in Hertz",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4373,
            +            "description": "<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4386,
            +            "description": "<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n",
            +            "itemtype": "method",
            +            "name": "getType",
            +            "return": {
            +                "description": "type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4399,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4420,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4444,
            +            "description": "<p>Pan between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "pan",
            +            "params": [
            +                {
            +                    "name": "panning",
            +                    "description": "<p>Number between -1 and 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4460,
            +            "description": "<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n",
            +            "itemtype": "method",
            +            "name": "getPan",
            +            "return": {
            +                "description": "panPosition of oscillator , between Left (-1) and Right (1)",
            +                "type": "Number"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4494,
            +            "description": "<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "phase",
            +            "params": [
            +                {
            +                    "name": "phase",
            +                    "description": "<p>float between 0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4522,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4543,
            +            "description": "<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with multiplied output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4563,
            +            "description": "<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Oscillator Returns this oscillator\n                                   with scaled output",
            +                "type": "p5.Oscillator"
            +            },
            +            "class": "p5.Oscillator",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4767,
            +            "description": "<p>Time until envelope reaches attackLevel</p>\n",
            +            "itemtype": "property",
            +            "name": "attackTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4772,
            +            "description": "<p>Level once attack is complete.</p>\n",
            +            "itemtype": "property",
            +            "name": "attackLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4778,
            +            "description": "<p>Time until envelope reaches decayLevel.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4784,
            +            "description": "<p>Level after decay. The envelope will sustain here until it is released.</p>\n",
            +            "itemtype": "property",
            +            "name": "decayLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4790,
            +            "description": "<p>Duration of the release portion of the envelope.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseTime",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4796,
            +            "description": "<p>Level at the end of the release.</p>\n",
            +            "itemtype": "property",
            +            "name": "releaseLevel",
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4833,
            +            "description": "<p>Reset the envelope with a series of time/value pairs.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "attackLevel",
            +                    "description": "<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayLevel",
            +                    "description": "<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Release Time (in seconds)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "releaseLevel",
            +                    "description": "<p>Amplitude</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4895,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 4964,
            +            "description": "<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setRange",
            +            "params": [
            +                {
            +                    "name": "aLevel",
            +                    "description": "<p>attack level (defaults to 1)</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rLevel",
            +                    "description": "<p>release level (defaults to 0)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5037,
            +            "description": "<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "inputs",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object",
            +                    "optional": true,
            +                    "multiple": true
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5055,
            +            "description": "<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n",
            +            "itemtype": "method",
            +            "name": "setExp",
            +            "params": [
            +                {
            +                    "name": "isExp",
            +                    "description": "<p>true is exponential, false is linear</p>\n",
            +                    "type": "Boolean"
            +                }
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5078,
            +            "description": "<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound object or\n                              Web Audio Param.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "startTime",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5148,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5256,
            +            "description": "<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5350,
            +            "description": "<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n",
            +            "itemtype": "method",
            +            "name": "ramp",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound Object or Web Audio Param</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>When to trigger the ramp</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v",
            +                    "description": "<p>Target value</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "v2",
            +                    "description": "<p>Second target value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"
            +            ],
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5460,
            +            "description": "<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "add",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to add</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5479,
            +            "description": "<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "mult",
            +            "params": [
            +                {
            +                    "name": "number",
            +                    "description": "<p>Constant number to multiply</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5498,
            +            "description": "<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n",
            +            "itemtype": "method",
            +            "name": "scale",
            +            "params": [
            +                {
            +                    "name": "inMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "inMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMin",
            +                    "description": "<p>input range minumum</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "outMax",
            +                    "description": "<p>input range maximum</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Envelope Returns this envelope\n                                   with scaled output",
            +                "type": "p5.Envelope"
            +            },
            +            "class": "p5.Envelope",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5657,
            +            "description": "<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'white', 'pink' or 'brown'</p>\n",
            +                    "type": "String",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Noise",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 5871,
            +            "description": "<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n",
            +            "itemtype": "method",
            +            "name": "width",
            +            "params": [
            +                {
            +                    "name": "width",
            +                    "description": "<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Pulse",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6066,
            +            "itemtype": "property",
            +            "name": "input",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6070,
            +            "itemtype": "property",
            +            "name": "output",
            +            "type": "GainNode",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6075,
            +            "itemtype": "property",
            +            "name": "stream",
            +            "type": "MediaStream|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6080,
            +            "itemtype": "property",
            +            "name": "mediaStream",
            +            "type": "MediaStreamAudioSourceNode|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6085,
            +            "itemtype": "property",
            +            "name": "currentSource",
            +            "type": "Number|null",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6090,
            +            "description": "<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n",
            +            "itemtype": "property",
            +            "name": "enabled",
            +            "type": "Boolean",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6098,
            +            "description": "<p>Input amplitude, connect to it by default but not to master out</p>\n",
            +            "itemtype": "property",
            +            "name": "amplitude",
            +            "type": "p5.Amplitude",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6114,
            +            "description": "<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>Name of a function to call on\n                                  success.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6171,
            +            "description": "<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6191,
            +            "description": "<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>An object that accepts audio input,\n                        such as an FFT</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6216,
            +            "description": "<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6234,
            +            "description": "<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n",
            +            "itemtype": "method",
            +            "name": "getLevel",
            +            "params": [
            +                {
            +                    "name": "smoothing",
            +                    "description": "<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Volume level (between 0.0 and 1.0)",
            +                "type": "Number"
            +            },
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6257,
            +            "description": "<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>ramp time (optional)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6280,
            +            "description": "<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n",
            +            "itemtype": "method",
            +            "name": "getSources",
            +            "params": [
            +                {
            +                    "name": "successCallback",
            +                    "description": "<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>This optional callback receives the error\n                                   message as its argument.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method",
            +                "type": "Promise"
            +            },
            +            "example": [
            +                "\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6340,
            +            "description": "<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n",
            +            "itemtype": "method",
            +            "name": "setSource",
            +            "params": [
            +                {
            +                    "name": "num",
            +                    "description": "<p>position of input source in the array</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"
            +            ],
            +            "class": "p5.AudioIn",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6462,
            +            "description": "<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6478,
            +            "description": "<p>Set the output volume of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts until rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "tFromNow",
            +                    "description": "<p>schedule this event to happen in tFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6502,
            +            "description": "<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n",
            +            "itemtype": "method",
            +            "name": "chain",
            +            "params": [
            +                {
            +                    "name": "arguments",
            +                    "description": "<p>Chain together multiple sound objects</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6525,
            +            "description": "<p>Adjust the dry/wet value.</p>\n",
            +            "itemtype": "method",
            +            "name": "drywet",
            +            "params": [
            +                {
            +                    "name": "fade",
            +                    "description": "<p>The desired drywet value (0 - 1.0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6542,
            +            "description": "<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6557,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Effect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6719,
            +            "description": "<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "biquadFilter",
            +            "type": "DelayNode",
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6742,
            +            "description": "<p>Filter an audio signal according to a set\nof filter parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6760,
            +            "description": "<p>Set the frequency and the resonance of the filter.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Frequency in Hz, from 10 to 22050</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance (Q) from 0.001 to 1000</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6781,
            +            "description": "<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n",
            +            "itemtype": "method",
            +            "name": "freq",
            +            "params": [
            +                {
            +                    "name": "freq",
            +                    "description": "<p>Filter Frequency</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value  Returns the current frequency value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6811,
            +            "description": "<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "res",
            +            "params": [
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "value Returns the current res value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6838,
            +            "description": "<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n",
            +            "itemtype": "method",
            +            "name": "gain",
            +            "params": [
            +                {
            +                    "name": "gain",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Returns the current or updated gain value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6864,
            +            "description": "<p>Toggle function. Switches between the specified type and allpass</p>\n",
            +            "itemtype": "method",
            +            "name": "toggle",
            +            "return": {
            +                "description": "[Toggle value]",
            +                "type": "Boolean"
            +            },
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 6884,
            +            "description": "<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "t",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Filter",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7198,
            +            "description": "<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n",
            +            "itemtype": "property",
            +            "name": "bands",
            +            "type": "Array",
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7239,
            +            "description": "<p>Process an input by connecting it to the EQ</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Audio source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.EQ",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7629,
            +            "description": "<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n",
            +            "itemtype": "property",
            +            "name": "panner",
            +            "type": "AudioNode",
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7654,
            +            "description": "<p>Connect an audio sorce</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Input source</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7668,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7687,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7694,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7701,
            +            "description": "<p>Getter and setter methods for position coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "positionZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7753,
            +            "description": "<p>Set the X,Y,Z position of the Panner</p>\n",
            +            "itemtype": "method",
            +            "name": "orient",
            +            "params": [
            +                {
            +                    "name": "xVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "yVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "zVal",
            +                    "description": "",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "Updated x, y, z values as an array",
            +                "type": "Array"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7772,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientX",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7779,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientY",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7786,
            +            "description": "<p>Getter and setter methods for orient coordinates</p>\n",
            +            "itemtype": "method",
            +            "name": "orientZ",
            +            "return": {
            +                "description": "updated coordinate value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7838,
            +            "description": "<p>Set the rolloff factor and max distance</p>\n",
            +            "itemtype": "method",
            +            "name": "setFalloff",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7852,
            +            "description": "<p>Maxium distance between the source and the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "maxDist",
            +            "params": [
            +                {
            +                    "name": "maxDistance",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7869,
            +            "description": "<p>How quickly the volume is reduced as the source moves away from the listener</p>\n",
            +            "itemtype": "method",
            +            "name": "rollof",
            +            "params": [
            +                {
            +                    "name": "rolloffFactor",
            +                    "description": "",
            +                    "type": "Number"
            +                }
            +            ],
            +            "return": {
            +                "description": "updated value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Panner3D",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7989,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "leftDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 7999,
            +            "description": "<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n",
            +            "itemtype": "property",
            +            "name": "rightDelay",
            +            "type": "DelayNode",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8049,
            +            "description": "<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "Signal",
            +                    "description": "<p>An object that outputs audio</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "lowPass",
            +                    "description": "<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8094,
            +            "description": "<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n",
            +            "itemtype": "method",
            +            "name": "delayTime",
            +            "params": [
            +                {
            +                    "name": "delayTime",
            +                    "description": "<p>Time (in seconds) of the delay</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8116,
            +            "description": "<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n",
            +            "itemtype": "method",
            +            "name": "feedback",
            +            "params": [
            +                {
            +                    "name": "feedback",
            +                    "description": "<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "return": {
            +                "description": "Feedback value",
            +                "type": "Number"
            +            },
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8148,
            +            "description": "<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n",
            +            "itemtype": "method",
            +            "name": "filter",
            +            "params": [
            +                {
            +                    "name": "cutoffFreq",
            +                    "description": "<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n",
            +                    "type": "Number|Object"
            +                },
            +                {
            +                    "name": "res",
            +                    "description": "<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n",
            +                    "type": "Number|Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8170,
            +            "description": "<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n",
            +            "itemtype": "method",
            +            "name": "setType",
            +            "params": [
            +                {
            +                    "name": "type",
            +                    "description": "<p>'pingPong' (1) or 'default' (0)</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8223,
            +            "description": "<p>Set the output level of the delay effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8234,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8242,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Delay",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8409,
            +            "description": "<p>Connect a source to the reverb, and assign reverb parameters.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8446,
            +            "description": "<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "seconds",
            +                    "description": "<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayRate",
            +                    "description": "<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "reverse",
            +                    "description": "<p>Play the reverb backwards or forwards.</p>\n",
            +                    "type": "Boolean",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8482,
            +            "description": "<p>Set the output level of the reverb effect.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8493,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8501,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Reverb",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8621,
            +            "description": "<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "convolverNode",
            +            "type": "ConvolverNode",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8645,
            +            "description": "<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n",
            +            "itemtype": "property",
            +            "name": "impulses",
            +            "type": "Array",
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8737,
            +            "description": "<p>Connect a source to the convolver.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8786,
            +            "description": "<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n",
            +            "itemtype": "method",
            +            "name": "addImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8808,
            +            "description": "<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n",
            +            "itemtype": "method",
            +            "name": "resetImpulse",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function (optional)</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8831,
            +            "description": "<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n",
            +            "itemtype": "method",
            +            "name": "toggleImpulse",
            +            "params": [
            +                {
            +                    "name": "id",
            +                    "description": "<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n",
            +                    "type": "String|Number"
            +                }
            +            ],
            +            "class": "p5.Convolver",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 8885,
            +            "description": "<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n",
            +            "itemtype": "method",
            +            "name": "createConvolver",
            +            "params": [
            +                {
            +                    "name": "path",
            +                    "description": "<p>path to a sound file</p>\n",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "errorCallback",
            +                    "description": "<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "",
            +                "type": "p5.Convolver"
            +            },
            +            "example": [
            +                "\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9084,
            +            "description": "<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9173,
            +            "description": "<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n",
            +            "itemtype": "property",
            +            "name": "sequence",
            +            "type": "Array",
            +            "class": "p5.Phrase",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9263,
            +            "description": "<p>Set the tempo of this part, in Beats Per Minute.</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9278,
            +            "description": "<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n",
            +            "itemtype": "method",
            +            "name": "getBPM",
            +            "return": {
            +                "description": "",
            +                "type": "Number"
            +            },
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9291,
            +            "description": "<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9311,
            +            "description": "<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9333,
            +            "description": "<p>Tell the part to stop looping.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9349,
            +            "description": "<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9363,
            +            "description": "<p>Pause the part. Playback will resume\nfrom the current step.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "time",
            +                    "description": "<p>seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9379,
            +            "description": "<p>Add a p5.Phrase to this Part.</p>\n",
            +            "itemtype": "method",
            +            "name": "addPhrase",
            +            "params": [
            +                {
            +                    "name": "phrase",
            +                    "description": "<p>reference to a p5.Phrase</p>\n",
            +                    "type": "p5.Phrase"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9406,
            +            "description": "<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n",
            +            "itemtype": "method",
            +            "name": "removePhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9424,
            +            "description": "<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n",
            +            "itemtype": "method",
            +            "name": "getPhrase",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9442,
            +            "description": "<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n",
            +            "itemtype": "method",
            +            "name": "replaceSequence",
            +            "params": [
            +                {
            +                    "name": "phraseName",
            +                    "description": "",
            +                    "type": "String"
            +                },
            +                {
            +                    "name": "sequence",
            +                    "description": "<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n",
            +                    "type": "Array"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9473,
            +            "description": "<p>Set the function that will be called at every step. This will clear the previous function.</p>\n",
            +            "itemtype": "method",
            +            "name": "onStep",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n",
            +                    "type": "Function"
            +                }
            +            ],
            +            "class": "p5.Part",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9542,
            +            "description": "<p>Start playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9555,
            +            "description": "<p>Stop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9569,
            +            "description": "<p>Pause playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9581,
            +            "description": "<p>Loop playback of the score.</p>\n",
            +            "itemtype": "method",
            +            "name": "loop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9594,
            +            "description": "<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noLoop",
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9628,
            +            "description": "<p>Set the tempo for all parts in the score</p>\n",
            +            "itemtype": "method",
            +            "name": "setBPM",
            +            "params": [
            +                {
            +                    "name": "BPM",
            +                    "description": "<p>Beats Per Minute</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Seconds from now</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Score",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9729,
            +            "description": "<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n",
            +            "itemtype": "property",
            +            "name": "bpm",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9750,
            +            "description": "<p>number of quarter notes in a measure (defaults to 4)</p>\n",
            +            "itemtype": "property",
            +            "name": "timeSignature",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9770,
            +            "description": "<p>length of the loops interval</p>\n",
            +            "itemtype": "property",
            +            "name": "interval",
            +            "type": "Number|String",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9787,
            +            "description": "<p>how many times the callback has been called so far</p>\n",
            +            "itemtype": "property",
            +            "name": "iterations",
            +            "type": "Number",
            +            "readonly": "",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9800,
            +            "description": "<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n",
            +            "itemtype": "property",
            +            "name": "musicalTimeMode",
            +            "type": "Boolean",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9808,
            +            "description": "<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9816,
            +            "description": "<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n",
            +            "itemtype": "property",
            +            "name": "maxIterations",
            +            "type": "Number",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9826,
            +            "description": "<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n",
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9841,
            +            "description": "<p>Start the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "start",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a starting time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9860,
            +            "description": "<p>Stop the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a stopping time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9878,
            +            "description": "<p>Pause the loop</p>\n",
            +            "itemtype": "method",
            +            "name": "pause",
            +            "params": [
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule a pausing time</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 9896,
            +            "description": "<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n",
            +            "itemtype": "method",
            +            "name": "syncedStart",
            +            "params": [
            +                {
            +                    "name": "otherLoop",
            +                    "description": "<p>a p5.SoundLoop to sync with</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>Start the loops in sync after timeFromNow seconds</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundLoop",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10068,
            +            "description": "<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n",
            +            "itemtype": "property",
            +            "name": "compressor",
            +            "type": "AudioNode",
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10084,
            +            "description": "<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>Sound source to be connected</p>\n",
            +                    "type": "Object"
            +                },
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10112,
            +            "description": "<p>Set the paramters of a compressor.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10152,
            +            "description": "<p>Get current attack or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "attack",
            +            "params": [
            +                {
            +                    "name": "attack",
            +                    "description": "<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10178,
            +            "description": "<p>Get current knee or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "knee",
            +            "params": [
            +                {
            +                    "name": "knee",
            +                    "description": "<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10204,
            +            "description": "<p>Get current ratio or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "ratio",
            +            "params": [
            +                {
            +                    "name": "ratio",
            +                    "description": "<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10228,
            +            "description": "<p>Get current threshold or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "threshold",
            +            "params": [
            +                {
            +                    "name": "threshold",
            +                    "description": "<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10252,
            +            "description": "<p>Get current release or set value w/ time ramp</p>\n",
            +            "itemtype": "method",
            +            "name": "release",
            +            "params": [
            +                {
            +                    "name": "release",
            +                    "description": "<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "time",
            +                    "description": "<p>Assign time value to schedule the change in value</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10277,
            +            "description": "<p>Return the current reduction value</p>\n",
            +            "itemtype": "method",
            +            "name": "reduction",
            +            "return": {
            +                "description": "Value of the amount of gain reduction that is applied to the signal",
            +                "type": "Number"
            +            },
            +            "class": "p5.Compressor",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10419,
            +            "description": "<p>isDetected is set to true when a peak is detected.</p>\n",
            +            "itemtype": "attribute",
            +            "name": "isDetected",
            +            "type": "Boolean",
            +            "default": "false",
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10432,
            +            "description": "<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n",
            +            "itemtype": "method",
            +            "name": "update",
            +            "params": [
            +                {
            +                    "name": "fftObject",
            +                    "description": "<p>A p5.FFT object</p>\n",
            +                    "type": "p5.FFT"
            +                }
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10470,
            +            "description": "<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n",
            +            "itemtype": "method",
            +            "name": "onPeak",
            +            "params": [
            +                {
            +                    "name": "callback",
            +                    "description": "<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n",
            +                    "type": "Function"
            +                },
            +                {
            +                    "name": "val",
            +                    "description": "<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"
            +            ],
            +            "class": "p5.PeakDetect",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10676,
            +            "description": "<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n",
            +                    "type": "Object",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10703,
            +            "description": "<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n",
            +            "itemtype": "method",
            +            "name": "record",
            +            "params": [
            +                {
            +                    "name": "soundFile",
            +                    "description": "<p>p5.SoundFile</p>\n",
            +                    "type": "p5.SoundFile"
            +                },
            +                {
            +                    "name": "duration",
            +                    "description": "<p>Time (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "callback",
            +                    "description": "<p>The name of a function that will be\n                              called once the recording completes</p>\n",
            +                    "type": "Function",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10739,
            +            "description": "<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n",
            +            "itemtype": "method",
            +            "name": "stop",
            +            "class": "p5.SoundRecorder",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10864,
            +            "description": "<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n",
            +            "itemtype": "property",
            +            "name": "WaveShaperNode",
            +            "type": "AudioNode",
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10883,
            +            "description": "<p>Process a sound source, optionally specify amount and oversample values.</p>\n",
            +            "itemtype": "method",
            +            "name": "process",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10900,
            +            "description": "<p>Set the amount and oversample of the waveshaper distortion.</p>\n",
            +            "itemtype": "method",
            +            "name": "set",
            +            "params": [
            +                {
            +                    "name": "amount",
            +                    "description": "<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n",
            +                    "type": "Number",
            +                    "optional": true,
            +                    "optdefault": "0.25"
            +                },
            +                {
            +                    "name": "oversample",
            +                    "description": "<p>'none', '2x', or '4x'.</p>\n",
            +                    "type": "String",
            +                    "optional": true,
            +                    "optdefault": "'none'"
            +                }
            +            ],
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10923,
            +            "description": "<p>Return the distortion amount, typically between 0-1.</p>\n",
            +            "itemtype": "method",
            +            "name": "getAmount",
            +            "return": {
            +                "description": "Unbounded distortion amount.\n                 Normal values range from 0-1.",
            +                "type": "Number"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 10937,
            +            "description": "<p>Return the oversampling.</p>\n",
            +            "itemtype": "method",
            +            "name": "getOversample",
            +            "return": {
            +                "description": "Oversample can either be 'none', '2x', or '4x'.",
            +                "type": "String"
            +            },
            +            "class": "p5.Distortion",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11055,
            +            "description": "<p>Connect a source to the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "setInput",
            +            "params": [
            +                {
            +                    "name": "src",
            +                    "description": "<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11070,
            +            "description": "<p>Send output to a p5.sound or web audio object</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11084,
            +            "description": "<p>Disconnect all output.</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11098,
            +            "description": "<p>Set the output level of the gain node.</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "volume",
            +                    "description": "<p>amplitude between 0 and 1.0</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>create a fade that lasts rampTime</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "timeFromNow",
            +                    "description": "<p>schedule this event to happen\n                              seconds from now</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.Gain",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11181,
            +            "description": "<p>Connect to p5 objects or Web Audio Nodes</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11194,
            +            "description": "<p>Disconnect from soundOut</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.AudioVoice",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11322,
            +            "description": "<p>Getters and Setters</p>\n",
            +            "itemtype": "property",
            +            "name": "attack",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11328,
            +            "itemtype": "property",
            +            "name": "decay",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11333,
            +            "itemtype": "property",
            +            "name": "sustain",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11338,
            +            "itemtype": "property",
            +            "name": "release",
            +            "type": "Number",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11379,
            +            "description": "<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11431,
            +            "description": "<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n",
            +                    "type": "String | Number"
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerAttack",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11478,
            +            "description": "<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "params": [
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number"
            +                }
            +            ],
            +            "itemtype": "method",
            +            "name": "triggerRelease",
            +            "example": [
            +                "\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11516,
            +            "description": "<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11544,
            +            "description": "<p>MonoSynth amp</p>\n",
            +            "itemtype": "method",
            +            "name": "amp",
            +            "params": [
            +                {
            +                    "name": "vol",
            +                    "description": "<p>desired volume</p>\n",
            +                    "type": "Number"
            +                },
            +                {
            +                    "name": "rampTime",
            +                    "description": "<p>Time to reach new volume</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "return": {
            +                "description": "new volume value",
            +                "type": "Number"
            +            },
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11564,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11578,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11592,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.MonoSynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11742,
            +            "description": "<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n",
            +            "itemtype": "property",
            +            "name": "notes",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11755,
            +            "description": "<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n",
            +            "itemtype": "property",
            +            "name": "polyvalue",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11761,
            +            "description": "<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n",
            +            "itemtype": "property",
            +            "name": "AudioVoice",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11800,
            +            "description": "<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n",
            +            "itemtype": "method",
            +            "name": "play",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds) at which to play</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "sustainTime",
            +                    "description": "<p>time to sustain before releasing the envelope</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11849,
            +            "description": "<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteADSR",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>Midi note on which ADSR should be set.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11881,
            +            "description": "<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n",
            +            "itemtype": "method",
            +            "name": "setADSR",
            +            "params": [
            +                {
            +                    "name": "attackTime",
            +                    "description": "<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "decayTime",
            +                    "description": "<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "susRatio",
            +                    "description": "<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "releaseTime",
            +                    "description": "<p>Time in seconds from now (defaults to 0)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 11909,
            +            "description": "<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteAttack",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "velocity",
            +                    "description": "<p>velocity of the note to play (ranging from 0 to 1)/</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time from now (in seconds)</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12021,
            +            "description": "<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n",
            +            "itemtype": "method",
            +            "name": "noteRelease",
            +            "params": [
            +                {
            +                    "name": "note",
            +                    "description": "<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                },
            +                {
            +                    "name": "secondsFromNow",
            +                    "description": "<p>time to trigger the release</p>\n",
            +                    "type": "Number",
            +                    "optional": true
            +                }
            +            ],
            +            "example": [
            +                "\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12105,
            +            "description": "<p>Connect to a p5.sound / Web Audio object.</p>\n",
            +            "itemtype": "method",
            +            "name": "connect",
            +            "params": [
            +                {
            +                    "name": "unit",
            +                    "description": "<p>A p5.sound or Web Audio object</p>\n",
            +                    "type": "Object"
            +                }
            +            ],
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12119,
            +            "description": "<p>Disconnect all outputs</p>\n",
            +            "itemtype": "method",
            +            "name": "disconnect",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        },
            +        {
            +            "file": "lib/addons/p5.sound.js",
            +            "line": 12133,
            +            "description": "<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n",
            +            "itemtype": "method",
            +            "name": "dispose",
            +            "class": "p5.PolySynth",
            +            "module": "p5.sound",
            +            "submodule": "p5.sound"
            +        }
            +    ],
            +    "warnings": [
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:120"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:216"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:316"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:457"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/fes_core.js:1001"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:223"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/sketch_reader.js:248"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/friendly_errors/validate_params.js:336"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:219"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:259"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/attributes.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:185"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:264"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:358"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:398"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/curves.js:493"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:67"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:293"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:460"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:524"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:583"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:668"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:733"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/shape/vertex.js:826"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:84"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:120"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/constants.js:138"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:79"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:129"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:160"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:228"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:372"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:390"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:405"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:421"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:500"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:550"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:586"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:605"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:660"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:691"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/environment.js:713"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/core/internationalization.js:105"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:42"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/main.js:415"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:47"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:114"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:154"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:189"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:246"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:292"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:354"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:403"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:454"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:510"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:551"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:639"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:678"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:725"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Element.js:763"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:70"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/p5.Graphics.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:7"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:34"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:87"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:137"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:158"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:179"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:200"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:267"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:309"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:331"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:379"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:408"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:448"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:490"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/reference.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/rendering.js:326"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:83"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:134"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:192"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:290"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:391"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/structure.js:497"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:193"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:232"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:304"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:342"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:416"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:455"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/core/transform.js:494"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/data/local_storage.js:101"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:204"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1560"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1622"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1726"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1765"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/dom/dom.js:1885"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2268"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/dom/dom.js:2778"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:23"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:46"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:69"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:135"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:168"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:201"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:285"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:330"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:428"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:515"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:546"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/acceleration.js:604"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:64"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:103"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/keyboard.js:308"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:106"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:132"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:164"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:233"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:271"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:351"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:389"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:615"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:696"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:772"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:841"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:926"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:979"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/mouse.js:1025"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:71"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:151"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/events/touch.js:223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:94"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/image.js:413"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:18"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:301"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:471"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:569"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/loading_displaying.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:88"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:152"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:261"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:296"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:346"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:400"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:437"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:548"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:665"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:738"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:900"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:941"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:972"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1017"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1052"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1089"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/p5.Image.js:1125"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:80"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:173"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:307"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:481"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:566"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:602"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/image/pixels.js:674"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:20"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:183"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:583"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:693"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1393"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1535"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1592"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/files.js:1656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:85"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:148"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:195"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:240"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:288"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:352"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:545"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:597"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:638"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:896"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:960"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1009"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1055"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1190"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1242"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.Table.js:1305"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:40"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:102"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:146"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:191"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:239"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.TableRow.js:295"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/io/p5.XML.js:9"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:33"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:72"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:116"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:182"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:269"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:316"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:371"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:409"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:464"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:512"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:560"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:612"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:646"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:701"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:745"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/calculation.js:832"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/math.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:36"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:178"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/noise.js:243"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/p5.Vector.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:37"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:66"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/random.js:153"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:123"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:159"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:186"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:213"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/math/trigonometry.js:285"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:320"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:335"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/math/trigonometry.js:350"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:81"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:118"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:150"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/attributes.js:187"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:16"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:140"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/loading_displaying.js:231"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/typography/p5.Font.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/conversion.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:15"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:43"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:130"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:237"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:311"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:373"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:451"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/string_functions.js:537"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:10"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:31"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:52"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:73"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:100"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:122"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/utilities/time_date.js:143"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/3d_primitives.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:145"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/interaction.js:353"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:11"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:92"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:177"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:280"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:387"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:425"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:519"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/light.js:859"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:12"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/loading.js:588"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:12"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:111"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:184"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:282"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:368"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:511"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:587"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:659"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:697"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:777"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:829"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/material.js:902"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:13"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:115"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:176"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:236"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:303"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:357"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:444"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:472"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:499"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:526"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:554"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:582"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:610"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:633"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:656"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:683"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:801"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:897"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1040"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1098"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1156"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1223"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1386"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1458"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Camera.js:1723"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:334"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:603"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:644"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.RendererGL.js:749"
            +        },
            +        {
            +            "message": "unknown tag: alt",
            +            "line": " src/webgl/p5.Shader.js:306"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:115"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:158"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:191"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:203"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:236"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:250"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " src/webgl/text.js:388"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:456"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:471"
            +        },
            +        {
            +            "message": "replacing incorrect tag: function with method",
            +            "line": " src/webgl/text.js:556"
            +        },
            +        {
            +            "message": "replacing incorrect tag: params with param",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2381"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:2882"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4271"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4360"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4386"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:4460"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:6280"
            +        },
            +        {
            +            "message": "replacing incorrect tag: returns with return",
            +            "line": " lib/addons/p5.sound.js:8116"
            +        },
            +        {
            +            "message": "Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.",
            +            "line": " src/color/color_conversion.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:19"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSBA array to RGBA.",
            +            "line": " src/color/color_conversion.js:45"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to HSBA.",
            +            "line": " src/color/color_conversion.js:100"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.",
            +            "line": " src/color/color_conversion.js:123"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSBA.",
            +            "line": " src/color/color_conversion.js:187"
            +        },
            +        {
            +            "message": "Missing item type\nConvert an RGBA array to HSLA.",
            +            "line": " src/color/color_conversion.js:226"
            +        },
            +        {
            +            "message": "Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.",
            +            "line": " src/color/p5.Color.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.",
            +            "line": " src/color/p5.Color.js:427"
            +        },
            +        {
            +            "message": "Missing item type\nCSS named colors.",
            +            "line": " src/color/p5.Color.js:446"
            +        },
            +        {
            +            "message": "Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.",
            +            "line": " src/color/p5.Color.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nFull color string patterns. The capture groups are necessary.",
            +            "line": " src/color/p5.Color.js:613"
            +        },
            +        {
            +            "message": "Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.",
            +            "line": " src/color/p5.Color.js:750"
            +        },
            +        {
            +            "message": "Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.",
            +            "line": " src/color/p5.Color.js:960"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/fes_core.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.",
            +            "line": " src/core/friendly_errors/fes_core.js:915"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/file_errors.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/sketch_reader.js:1"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/stacktrace.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nGiven an Error object, extract the most information from it.",
            +            "line": " src/core/friendly_errors/stacktrace.js:34"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/friendly_errors/validate_params.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).",
            +            "line": " src/core/shape/2d_primitives.js:16"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current framerate.",
            +            "line": " src/core/environment.js:305"
            +        },
            +        {
            +            "message": "Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.",
            +            "line": " src/core/environment.js:315"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/helpers.js:1"
            +        },
            +        {
            +            "message": "Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing",
            +            "line": " src/core/init.js:4"
            +        },
            +        {
            +            "message": "Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.",
            +            "line": " src/core/internationalization.js:30"
            +        },
            +        {
            +            "message": "Missing item type\nSet up our translation function, with loaded languages",
            +            "line": " src/core/internationalization.js:126"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a list of languages we have translations loaded for",
            +            "line": " src/core/internationalization.js:171"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the current language selected for translation",
            +            "line": " src/core/internationalization.js:178"
            +        },
            +        {
            +            "message": "Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.",
            +            "line": " src/core/internationalization.js:185"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/core/legacy.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/core/p5.Element.js:827"
            +        },
            +        {
            +            "message": "Missing item type\nResize our canvas element.",
            +            "line": " src/core/p5.Renderer.js:99"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to check font type (system or otf)",
            +            "line": " src/core/p5.Renderer.js:415"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178",
            +            "line": " src/core/p5.Renderer.js:467"
            +        },
            +        {
            +            "message": "Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer",
            +            "line": " src/core/p5.Renderer2D.js:7"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.",
            +            "line": " src/core/p5.Renderer2D.js:402"
            +        },
            +        {
            +            "message": "Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.",
            +            "line": " src/core/shim.js:18"
            +        },
            +        {
            +            "message": "Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign",
            +            "line": " src/core/shim.js:39"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()",
            +            "line": " src/data/p5.TypedDict.js:197"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:387"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type",
            +            "line": " src/data/p5.TypedDict.js:425"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:536"
            +        },
            +        {
            +            "message": "Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'",
            +            "line": " src/data/p5.TypedDict.js:600"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for select and selectAll",
            +            "line": " src/dom/dom.js:127"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for getElement and getElements.",
            +            "line": " src/dom/dom.js:142"
            +        },
            +        {
            +            "message": "Missing item type\nHelpers for create methods.",
            +            "line": " src/dom/dom.js:309"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:450"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1164"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1257"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:1296"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3232"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3298"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/dom/dom.js:3360"
            +        },
            +        {
            +            "message": "Missing item type\n_updatePAccelerations updates the pAcceleration values",
            +            "line": " src/events/acceleration.js:124"
            +        },
            +        {
            +            "message": "Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.",
            +            "line": " src/events/keyboard.js:298"
            +        },
            +        {
            +            "message": "Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.",
            +            "line": " src/events/keyboard.js:384"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.",
            +            "line": " src/image/filters.js:3"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the pixel buffer for a canvas",
            +            "line": " src/image/filters.js:24"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.",
            +            "line": " src/image/filters.js:60"
            +        },
            +        {
            +            "message": "Missing item type\nModifies pixels RGBA values to values contained in the data object.",
            +            "line": " src/image/filters.js:81"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData",
            +            "line": " src/image/filters.js:101"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a blank ImageData object.",
            +            "line": " src/image/filters.js:121"
            +        },
            +        {
            +            "message": "Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.",
            +            "line": " src/image/filters.js:136"
            +        },
            +        {
            +            "message": "Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:189"
            +        },
            +        {
            +            "message": "Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/",
            +            "line": " src/image/filters.js:223"
            +        },
            +        {
            +            "message": "Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.",
            +            "line": " src/image/filters.js:246"
            +        },
            +        {
            +            "message": "Missing item type\nSets each pixel to its inverse value. No parameter is used.",
            +            "line": " src/image/filters.js:262"
            +        },
            +        {
            +            "message": "Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation",
            +            "line": " src/image/filters.js:277"
            +        },
            +        {
            +            "message": "Missing item type\nreduces the bright areas in an image",
            +            "line": " src/image/filters.js:309"
            +        },
            +        {
            +            "message": "Missing item type\nincreases the bright areas in an image",
            +            "line": " src/image/filters.js:396"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.",
            +            "line": " src/image/image.js:8"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for loading GIF-based images",
            +            "line": " src/image/loading_displaying.js:162"
            +        },
            +        {
            +            "message": "Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height",
            +            "line": " src/image/loading_displaying.js:284"
            +        },
            +        {
            +            "message": "Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.",
            +            "line": " src/image/loading_displaying.js:597"
            +        },
            +        {
            +            "message": "Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.",
            +            "line": " src/image/p5.Image.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function for animating GIF-based images with time",
            +            "line": " src/image/p5.Image.js:222"
            +        },
            +        {
            +            "message": "Missing item type\nHelper fxn for sharing pixel methods",
            +            "line": " src/image/p5.Image.js:253"
            +        },
            +        {
            +            "message": "Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.",
            +            "line": " src/io/files.js:1789"
            +        },
            +        {
            +            "message": "Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.",
            +            "line": " src/io/files.js:1857"
            +        },
            +        {
            +            "message": "Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.",
            +            "line": " src/io/files.js:1890"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.",
            +            "line": " src/io/files.js:1902"
            +        },
            +        {
            +            "message": "Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>",
            +            "line": " src/io/p5.Table.js:9"
            +        },
            +        {
            +            "message": "Missing item type\nMultiplies a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2135"
            +        },
            +        {
            +            "message": "Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2187"
            +        },
            +        {
            +            "message": "Missing item type\nDivides a vector by a scalar and returns a new vector.",
            +            "line": " src/math/p5.Vector.js:2214"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the dot product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2267"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the cross product of two vectors.",
            +            "line": " src/math/p5.Vector.js:2281"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).",
            +            "line": " src/math/p5.Vector.js:2295"
            +        },
            +        {
            +            "message": "Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.",
            +            "line": " src/math/p5.Vector.js:2310"
            +        },
            +        {
            +            "message": "Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)",
            +            "line": " src/math/p5.Vector.js:2339"
            +        },
            +        {
            +            "message": "Missing item type\nNormalize the vector to length 1 (make it a unit vector).",
            +            "line": " src/math/p5.Vector.js:2357"
            +        },
            +        {
            +            "message": "Missing item type\nHelper function to measure ascent and descent.",
            +            "line": " src/typography/attributes.js:280"
            +        },
            +        {
            +            "message": "Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.",
            +            "line": " src/typography/p5.Font.js:273"
            +        },
            +        {
            +            "message": "Missing item type\nReturns an opentype path for the supplied string and position.",
            +            "line": " src/typography/p5.Font.js:288"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/3d_primitives.js:301"
            +        },
            +        {
            +            "message": "Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.",
            +            "line": " src/webgl/3d_primitives.js:955"
            +        },
            +        {
            +            "message": "Missing item type\nDraw a line given two points",
            +            "line": " src/webgl/3d_primitives.js:1393"
            +        },
            +        {
            +            "message": "Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1",
            +            "line": " src/webgl/loading.js:179"
            +        },
            +        {
            +            "message": "Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.",
            +            "line": " src/webgl/loading.js:290"
            +        },
            +        {
            +            "message": "Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.",
            +            "line": " src/webgl/loading.js:317"
            +        },
            +        {
            +            "message": "Missing item type\nThis function matches the `query` at the provided `offset`",
            +            "line": " src/webgl/loading.js:344"
            +        },
            +        {
            +            "message": "Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.",
            +            "line": " src/webgl/loading.js:356"
            +        },
            +        {
            +            "message": "Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`",
            +            "line": " src/webgl/loading.js:444"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:947"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/material.js:978"
            +        },
            +        {
            +            "message": "Missing item type\nCreate a 2D array for establishing stroke connections",
            +            "line": " src/webgl/p5.Geometry.js:212"
            +        },
            +        {
            +            "message": "Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU",
            +            "line": " src/webgl/p5.Geometry.js:233"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " src/webgl/p5.Matrix.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nPRIVATE",
            +            "line": " src/webgl/p5.Matrix.js:722"
            +        },
            +        {
            +            "message": "Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.",
            +            "line": " src/webgl/p5.RenderBuffer.js:12"
            +        },
            +        {
            +            "message": "Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:1"
            +        },
            +        {
            +            "message": "Missing item type\nEnd shape drawing and render vertices to screen.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:129"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:169"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:203"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:248"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:268"
            +        },
            +        {
            +            "message": "Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.",
            +            "line": " src/webgl/p5.RendererGL.Immediate.js:302"
            +        },
            +        {
            +            "message": "Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:8"
            +        },
            +        {
            +            "message": "Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:59"
            +        },
            +        {
            +            "message": "Missing item type\nDraws buffers given a geometry key ID",
            +            "line": " src/webgl/p5.RendererGL.Retained.js:110"
            +        },
            +        {
            +            "message": "Missing item type\nmodel view, projection, & normal\nmatrices",
            +            "line": " src/webgl/p5.RendererGL.js:117"
            +        },
            +        {
            +            "message": "Missing item type\n[background description]",
            +            "line": " src/webgl/p5.RendererGL.js:586"
            +        },
            +        {
            +            "message": "Missing item type\n[resize description]",
            +            "line": " src/webgl/p5.RendererGL.js:860"
            +        },
            +        {
            +            "message": "Missing item type\nclears color and depth buffers\nwith r,g,b,a",
            +            "line": " src/webgl/p5.RendererGL.js:890"
            +        },
            +        {
            +            "message": "Missing item type\n[translate description]",
            +            "line": " src/webgl/p5.RendererGL.js:924"
            +        },
            +        {
            +            "message": "Missing item type\nScales the Model View Matrix by a vector",
            +            "line": " src/webgl/p5.RendererGL.js:943"
            +        },
            +        {
            +            "message": "Missing item type\nturn a two dimensional array into one dimensional array",
            +            "line": " src/webgl/p5.RendererGL.js:1366"
            +        },
            +        {
            +            "message": "Missing item type\nturn a p5.Vector Array into a one dimensional number array",
            +            "line": " src/webgl/p5.RendererGL.js:1403"
            +        },
            +        {
            +            "message": "Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.",
            +            "line": " src/webgl/p5.RendererGL.js:1421"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:1"
            +        },
            +        {
            +            "message": "Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/",
            +            "line": " lib/addons/p5.sound.js:52"
            +        },
            +        {
            +            "message": "Missing item type\nThis module has shims",
            +            "line": " lib/addons/p5.sound.js:401"
            +        },
            +        {
            +            "message": "Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats",
            +            "line": " lib/addons/p5.sound.js:536"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:807"
            +        },
            +        {
            +            "message": "Missing item type\nUsed by Osc and Envelope to chain signal math",
            +            "line": " lib/addons/p5.sound.js:1040"
            +        },
            +        {
            +            "message": "Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.",
            +            "line": " lib/addons/p5.sound.js:1542"
            +        },
            +        {
            +            "message": "Missing item type\nStop playback on all of this soundfile's sources.",
            +            "line": " lib/addons/p5.sound.js:2056"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.js:2604"
            +        },
            +        {
            +            "message": "Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade",
            +            "line": " lib/addons/p5.sound.js:6455"
            +        },
            +        {
            +            "message": "Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter",
            +            "line": " lib/addons/p5.sound.js:6462"
            +        },
            +        {
            +            "message": "Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ",
            +            "line": " lib/addons/p5.sound.js:7009"
            +        },
            +        {
            +            "message": "Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.",
            +            "line": " lib/addons/p5.sound.js:8508"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.",
            +            "line": " lib/addons/p5.sound.js:8659"
            +        },
            +        {
            +            "message": "Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string",
            +            "line": " lib/addons/p5.sound.js:9808"
            +        },
            +        {
            +            "message": "Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached",
            +            "line": " lib/addons/p5.sound.js:9826"
            +        },
            +        {
            +            "message": "Missing item type\ncallback invoked when the recording is over",
            +            "line": " lib/addons/p5.sound.js:10660"
            +        },
            +        {
            +            "message": "Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release",
            +            "line": " lib/addons/p5.sound.js:11995"
            +        },
            +        {
            +            "message": "Missing item type",
            +            "line": " lib/addons/p5.sound.min.js:1"
            +        }
            +    ],
            +    "consts": {
            +        "LABEL": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "FALLBACK": [
            +            "p5.describe",
            +            "p5.describeElement",
            +            "p5.textOutput",
            +            "p5.gridOutput"
            +        ],
            +        "RGB": [
            +            "p5.colorMode"
            +        ],
            +        "HSB": [
            +            "p5.colorMode"
            +        ],
            +        "HSL": [
            +            "p5.colorMode"
            +        ],
            +        "CHORD": [
            +            "p5.arc"
            +        ],
            +        "PIE": [
            +            "p5.arc"
            +        ],
            +        "OPEN": [
            +            "p5.arc"
            +        ],
            +        "CENTER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode",
            +            "p5.textAlign"
            +        ],
            +        "RADIUS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode"
            +        ],
            +        "CORNER": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "CORNERS": [
            +            "p5.ellipseMode",
            +            "p5.rectMode",
            +            "p5.imageMode"
            +        ],
            +        "ROUND": [
            +            "p5.strokeCap",
            +            "p5.strokeJoin"
            +        ],
            +        "SQUARE": [
            +            "p5.strokeCap"
            +        ],
            +        "PROJECT": [
            +            "p5.strokeCap"
            +        ],
            +        "MITER": [
            +            "p5.strokeJoin"
            +        ],
            +        "BEVEL": [
            +            "p5.strokeJoin"
            +        ],
            +        "POINTS": [
            +            "p5.beginShape"
            +        ],
            +        "LINES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLES": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_FAN": [
            +            "p5.beginShape"
            +        ],
            +        "TRIANGLE_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "QUADS": [
            +            "p5.beginShape"
            +        ],
            +        "QUAD_STRIP": [
            +            "p5.beginShape"
            +        ],
            +        "TESS": [
            +            "p5.beginShape"
            +        ],
            +        "CLOSE": [
            +            "p5.endShape"
            +        ],
            +        "ARROW": [
            +            "p5.cursor"
            +        ],
            +        "CROSS": [
            +            "p5.cursor"
            +        ],
            +        "HAND": [
            +            "p5.cursor"
            +        ],
            +        "MOVE": [
            +            "p5.cursor"
            +        ],
            +        "TEXT": [
            +            "p5.cursor"
            +        ],
            +        "P2D": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "WEBGL": [
            +            "p5.createCanvas",
            +            "p5.createGraphics"
            +        ],
            +        "BLEND": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DARKEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "LIGHTEST": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DIFFERENCE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "MULTIPLY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "EXCLUSION": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SCREEN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REPLACE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "OVERLAY": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "HARD_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "SOFT_LIGHT": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "DODGE": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "BURN": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "ADD": [
            +            "p5.blendMode",
            +            "p5.Image.blend",
            +            "p5.blend"
            +        ],
            +        "REMOVE": [
            +            "p5.blendMode"
            +        ],
            +        "SUBTRACT": [
            +            "p5.blendMode"
            +        ],
            +        "VIDEO": [
            +            "p5.createCapture"
            +        ],
            +        "AUDIO": [
            +            "p5.createCapture"
            +        ],
            +        "THRESHOLD": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "GRAY": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "OPAQUE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "INVERT": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "POSTERIZE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "ERODE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "DILATE": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "BLUR": [
            +            "p5.Image.filter",
            +            "p5.filter"
            +        ],
            +        "NORMAL": [
            +            "p5.Image.blend",
            +            "p5.blend",
            +            "p5.textStyle",
            +            "p5.textureMode"
            +        ],
            +        "RADIANS": [
            +            "p5.angleMode"
            +        ],
            +        "DEGREES": [
            +            "p5.angleMode"
            +        ],
            +        "LEFT": [
            +            "p5.textAlign"
            +        ],
            +        "RIGHT": [
            +            "p5.textAlign"
            +        ],
            +        "TOP": [
            +            "p5.textAlign"
            +        ],
            +        "BOTTOM": [
            +            "p5.textAlign"
            +        ],
            +        "BASELINE": [
            +            "p5.textAlign"
            +        ],
            +        "ITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "BOLD": [
            +            "p5.textStyle"
            +        ],
            +        "BOLDITALIC": [
            +            "p5.textStyle"
            +        ],
            +        "WORD": [
            +            "p5.textWrap"
            +        ],
            +        "CHAR": [
            +            "p5.textWrap"
            +        ],
            +        "IMAGE": [
            +            "p5.textureMode"
            +        ],
            +        "CLAMP": [
            +            "p5.textureWrap"
            +        ],
            +        "REPEAT": [
            +            "p5.textureWrap"
            +        ],
            +        "MIRROR": [
            +            "p5.textureWrap"
            +        ]
            +    }
            +}
            \ No newline at end of file
            diff --git a/dist/zh-Hans/reference/data.min.json b/dist/zh-Hans/reference/data.min.json
            new file mode 100644
            index 0000000000..b719e76314
            --- /dev/null
            +++ b/dist/zh-Hans/reference/data.min.json
            @@ -0,0 +1 @@
            +{"project":{"name":"p5","description":"[![npm version](https://badge.fury.io/js/p5.svg)](https://www.npmjs.com/package/p5)","version":"1.4.1","url":"https://github.com/processing/p5.js#readme"},"files":{"src/accessibility/color_namer.js":{"name":"src/accessibility/color_namer.js","modules":{"Environment":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/describe.js":{"name":"src/accessibility/describe.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/gridOutput.js":{"name":"src/accessibility/gridOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/outputs.js":{"name":"src/accessibility/outputs.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/accessibility/textOutput.js":{"name":"src/accessibility/textOutput.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/color_conversion.js":{"name":"src/color/color_conversion.js","modules":{"Color Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/creating_reading.js":{"name":"src/color/creating_reading.js","modules":{"Creating & Reading":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/color/p5.Color.js":{"name":"src/color/p5.Color.js","modules":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{}},"src/color/setting.js":{"name":"src/color/setting.js","modules":{"Setting":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/fes_core.js":{"name":"src/core/friendly_errors/fes_core.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/file_errors.js":{"name":"src/core/friendly_errors/file_errors.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/sketch_reader.js":{"name":"src/core/friendly_errors/sketch_reader.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/stacktrace.js":{"name":"src/core/friendly_errors/stacktrace.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/friendly_errors/validate_params.js":{"name":"src/core/friendly_errors/validate_params.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/2d_primitives.js":{"name":"src/core/shape/2d_primitives.js","modules":{"2D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/attributes.js":{"name":"src/core/shape/attributes.js","modules":{"Attributes":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/curves.js":{"name":"src/core/shape/curves.js","modules":{"Curves":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shape/vertex.js":{"name":"src/core/shape/vertex.js","modules":{"Vertex":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/constants.js":{"name":"src/core/constants.js","modules":{"Constants":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/environment.js":{"name":"src/core/environment.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/helpers.js":{"name":"src/core/helpers.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/init.js":{"name":"src/core/init.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/internationalization.js":{"name":"src/core/internationalization.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/legacy.js":{"name":"src/core/legacy.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/main.js":{"name":"src/core/main.js","modules":{"Structure":1},"classes":{"p5":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Element.js":{"name":"src/core/p5.Element.js","modules":{"DOM":1},"classes":{"p5.Element":1},"fors":{"p5.Element":1},"namespaces":{}},"src/core/p5.Graphics.js":{"name":"src/core/p5.Graphics.js","modules":{"Rendering":1},"classes":{"p5.Graphics":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer.js":{"name":"src/core/p5.Renderer.js","modules":{},"classes":{"p5.Renderer":1},"fors":{"p5":1},"namespaces":{}},"src/core/p5.Renderer2D.js":{"name":"src/core/p5.Renderer2D.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/reference.js":{"name":"src/core/reference.js","modules":{"Foundation":1},"classes":{},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{}},"src/core/rendering.js":{"name":"src/core/rendering.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/shim.js":{"name":"src/core/shim.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/core/structure.js":{"name":"src/core/structure.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/core/transform.js":{"name":"src/core/transform.js","modules":{"Transform":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/local_storage.js":{"name":"src/data/local_storage.js","modules":{"LocalStorage":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/data/p5.TypedDict.js":{"name":"src/data/p5.TypedDict.js","modules":{"Dictionary":1},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"namespaces":{}},"src/dom/dom.js":{"name":"src/dom/dom.js","modules":{},"classes":{"p5.MediaElement":1,"p5.File":1},"fors":{"p5":1,"p5.Element":1},"namespaces":{}},"src/events/acceleration.js":{"name":"src/events/acceleration.js","modules":{"Acceleration":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/keyboard.js":{"name":"src/events/keyboard.js","modules":{"Keyboard":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/mouse.js":{"name":"src/events/mouse.js","modules":{"Mouse":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/events/touch.js":{"name":"src/events/touch.js","modules":{"Touch":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/filters.js":{"name":"src/image/filters.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/image/image.js":{"name":"src/image/image.js","modules":{"Image":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/loading_displaying.js":{"name":"src/image/loading_displaying.js","modules":{"Loading & Displaying":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/image/p5.Image.js":{"name":"src/image/p5.Image.js","modules":{},"classes":{"p5.Image":1},"fors":{},"namespaces":{}},"src/image/pixels.js":{"name":"src/image/pixels.js","modules":{"Pixels":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/io/files.js":{"name":"src/io/files.js","modules":{"Input":1,"Output":1},"classes":{"p5.PrintWriter":1},"fors":{"p5":1},"namespaces":{}},"src/io/p5.Table.js":{"name":"src/io/p5.Table.js","modules":{"Table":1},"classes":{"p5.Table":1},"fors":{},"namespaces":{}},"src/io/p5.TableRow.js":{"name":"src/io/p5.TableRow.js","modules":{},"classes":{"p5.TableRow":1},"fors":{},"namespaces":{}},"src/io/p5.XML.js":{"name":"src/io/p5.XML.js","modules":{},"classes":{"p5.XML":1},"fors":{},"namespaces":{}},"src/math/calculation.js":{"name":"src/math/calculation.js","modules":{"Calculation":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/math.js":{"name":"src/math/math.js","modules":{"Vector":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/noise.js":{"name":"src/math/noise.js","modules":{"Noise":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/p5.Vector.js":{"name":"src/math/p5.Vector.js","modules":{},"classes":{"p5.Vector":1},"fors":{},"namespaces":{}},"src/math/random.js":{"name":"src/math/random.js","modules":{"Random":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/math/trigonometry.js":{"name":"src/math/trigonometry.js","modules":{"Trigonometry":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/attributes.js":{"name":"src/typography/attributes.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/loading_displaying.js":{"name":"src/typography/loading_displaying.js","modules":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/typography/p5.Font.js":{"name":"src/typography/p5.Font.js","modules":{},"classes":{"p5.Font":1},"fors":{},"namespaces":{}},"src/utilities/array_functions.js":{"name":"src/utilities/array_functions.js","modules":{"Array Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/conversion.js":{"name":"src/utilities/conversion.js","modules":{"Conversion":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/string_functions.js":{"name":"src/utilities/string_functions.js","modules":{"String Functions":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/utilities/time_date.js":{"name":"src/utilities/time_date.js","modules":{"Time & Date":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/3d_primitives.js":{"name":"src/webgl/3d_primitives.js","modules":{"3D Primitives":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/interaction.js":{"name":"src/webgl/interaction.js","modules":{"Interaction":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/light.js":{"name":"src/webgl/light.js","modules":{"Lights":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/loading.js":{"name":"src/webgl/loading.js","modules":{"3D Models":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/material.js":{"name":"src/webgl/material.js","modules":{"Material":1},"classes":{},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Camera.js":{"name":"src/webgl/p5.Camera.js","modules":{"Camera":1},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{}},"src/webgl/p5.Geometry.js":{"name":"src/webgl/p5.Geometry.js","modules":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Matrix.js":{"name":"src/webgl/p5.Matrix.js","modules":{},"classes":{"p5.Matrix":1},"fors":{},"namespaces":{}},"src/webgl/p5.RenderBuffer.js":{"name":"src/webgl/p5.RenderBuffer.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Immediate.js":{"name":"src/webgl/p5.RendererGL.Immediate.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.Retained.js":{"name":"src/webgl/p5.RendererGL.Retained.js","modules":{},"classes":{},"fors":{},"namespaces":{}},"src/webgl/p5.RendererGL.js":{"name":"src/webgl/p5.RendererGL.js","modules":{},"classes":{"p5.RendererGL":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Shader.js":{"name":"src/webgl/p5.Shader.js","modules":{},"classes":{"p5.Shader":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/p5.Texture.js":{"name":"src/webgl/p5.Texture.js","modules":{},"classes":{"p5.Texture":1},"fors":{"p5":1},"namespaces":{}},"src/webgl/text.js":{"name":"src/webgl/text.js","modules":{},"classes":{"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{},"namespaces":{}},"lib/addons/p5.sound.js":{"name":"lib/addons/p5.sound.js","modules":{"p5.sound":1},"classes":{"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{}},"lib/addons/p5.sound.min.js":{"name":"lib/addons/p5.sound.min.js","modules":{},"classes":{},"fors":{},"namespaces":{}}},"modules":{"Environment":{"name":"Environment","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Environment","file":"src/accessibility/color_namer.js","line":1,"requires":["core"]},"Color":{"name":"Color","submodules":{"Color Conversion":1,"Creating & Reading":1,"Setting":1},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"namespaces":{},"file":"src/color/p5.Color.js","line":14},"Color Conversion":{"name":"Color Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/color_conversion.js","line":1,"requires":["core"]},"Creating & Reading":{"name":"Creating & Reading","submodules":{},"elements":{},"classes":{"p5.Color":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/p5.Color.js","line":14,"requires":["core","constants"],"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n"},"Setting":{"name":"Setting","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Color","namespace":"","file":"src/color/setting.js","line":1,"requires":["core","constants"]},"Shape":{"name":"Shape","submodules":{"2D Primitives":1,"Curves":1,"Vertex":1,"3D Primitives":1,"3D Models":1},"elements":{},"classes":{"p5.Geometry":1,"p5.Matrix":1},"fors":{"p5":1},"namespaces":{},"file":"src/webgl/p5.Matrix.js","line":19},"2D Primitives":{"name":"2D Primitives","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/2d_primitives.js","line":1,"requires":["core","constants"]},"Attributes":{"name":"Attributes","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/core/shape/attributes.js","line":1,"requires":["core","constants"]},"Curves":{"name":"Curves","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/curves.js","line":1,"requires":["core"]},"Vertex":{"name":"Vertex","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/core/shape/vertex.js","line":1,"requires":["core","constants"]},"Constants":{"name":"Constants","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Constants","file":"src/core/constants.js","line":1},"Structure":{"name":"Structure","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"IO","file":"src/core/main.js","line":1,"requires":["constants"]},"DOM":{"name":"DOM","submodules":{},"elements":{},"classes":{"p5.Element":1,"p5.MediaElement":1,"p5.File":1},"fors":{"p5.Element":1,"p5":1},"namespaces":{},"module":"DOM","file":"src/dom/dom.js","line":3533,"description":"<p>The web is much more than just canvas and the DOM functionality makes it easy to interact\nwith other HTML5 objects, including text, hyperlink, image, input, video,\naudio, and webcam.\nThere is a set of creation methods, DOM manipulation methods, and\nan extended <a href=\"#/p5.Element\">p5.Element</a> that supports a range of HTML elements. See the\n<a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>\nbeyond the canvas tutorial</a> for a full overview of how this addon works.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Beyond-the-canvas'>tutorial: beyond the canvas</a>\nfor more info on how to use this library.</a></p>\n","requires":["p5"]},"Rendering":{"name":"Rendering","submodules":{"undefined":1},"elements":{},"classes":{"p5.RendererGL":1,"p5.Graphics":1,"p5.Renderer":1},"fors":{"p5":1},"namespaces":{},"module":"Rendering","file":"src/webgl/p5.RendererGL.js","line":603,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n"},"Foundation":{"name":"Foundation","submodules":{},"elements":{},"classes":{"JSON":1,"console":1},"fors":{"p5":1,"JSON":1,"console":1},"namespaces":{},"module":"Foundation","file":"src/core/reference.js","line":1},"Transform":{"name":"Transform","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{},"module":"Transform","file":"src/core/transform.js","line":1,"requires":["core","constants"]},"Data":{"name":"Data","submodules":{"LocalStorage":1,"Dictionary":1,"Array Functions":1,"Conversion":1,"String Functions":1},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5":1,"p5.TypedDict":1},"namespaces":{},"file":"src/data/p5.TypedDict.js","line":410},"LocalStorage":{"name":"LocalStorage","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/local_storage.js","line":1,"requires":["core\n\nThis module defines the p5 methods for working with local storage"]},"Dictionary":{"name":"Dictionary","submodules":{},"elements":{},"classes":{"p5.TypedDict":1,"p5.StringDict":1,"p5.NumberDict":1},"fors":{"p5.TypedDict":1,"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"requires":["core\n\nThis module defines the p5 methods for the p5 Dictionary classes.\nThe classes StringDict and NumberDict are for storing and working\nwith key-value pairs."],"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n"},"Events":{"name":"Events","submodules":{"Acceleration":1,"Keyboard":1,"Mouse":1,"Touch":1},"elements":{},"classes":{},"fors":{"p5":1},"namespaces":{}},"Acceleration":{"name":"Acceleration","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/acceleration.js","line":1,"requires":["core"]},"Keyboard":{"name":"Keyboard","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/keyboard.js","line":1,"requires":["core"]},"Mouse":{"name":"Mouse","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/mouse.js","line":1,"requires":["core","constants"]},"Touch":{"name":"Touch","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Events","namespace":"","file":"src/events/touch.js","line":1,"requires":["core"]},"Image":{"name":"Image","submodules":{"Pixels":1},"elements":{},"classes":{"p5.Image":1},"fors":{"p5":1},"namespaces":{},"module":"Image","file":"src/image/p5.Image.js","line":21,"requires":["core"],"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n"},"Loading & Displaying":{"name":"Loading & Displaying","submodules":{},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Typography","namespace":"","file":"src/typography/p5.Font.js","line":13,"requires":["core"],"description":"<p>This module defines the <a href=\"#/p5.Font\">p5.Font</a> class and functions for\ndrawing text to the display canvas.</p>\n"},"Pixels":{"name":"Pixels","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Image","namespace":"","file":"src/image/pixels.js","line":1,"requires":["core"]},"IO":{"name":"IO","submodules":{"Structure":1,"Input":1,"Output":1,"Table":1,"Time & Date":1},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1,"p5.Table":1,"p5.TableRow":1,"p5.XML":1},"fors":{"p5":1},"namespaces":{},"file":"src/io/p5.XML.js","line":9},"Input":{"name":"Input","submodules":{},"elements":{},"classes":{"p5.XML":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.XML.js","line":9,"requires":["core"],"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n"},"Output":{"name":"Output","submodules":{},"elements":{},"classes":{"p5":1,"p5.PrintWriter":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/files.js","line":1200,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n"},"Table":{"name":"Table","submodules":{},"elements":{},"classes":{"p5.Table":1,"p5.TableRow":1},"fors":{},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/io/p5.TableRow.js","line":9,"requires":["core"],"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n"},"Math":{"name":"Math","submodules":{"Calculation":1,"Vector":1,"Noise":1,"Random":1,"Trigonometry":1},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"namespaces":{},"file":"src/math/p5.Vector.js","line":10},"Calculation":{"name":"Calculation","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/calculation.js","line":1,"requires":["core"]},"Vector":{"name":"Vector","submodules":{},"elements":{},"classes":{"p5.Vector":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/p5.Vector.js","line":10,"requires":["core"],"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n"},"Noise":{"name":"Noise","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/noise.js","line":14,"requires":["core"]},"Random":{"name":"Random","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/random.js","line":1,"requires":["core"]},"Trigonometry":{"name":"Trigonometry","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Math","namespace":"","file":"src/math/trigonometry.js","line":1,"requires":["core","constants"]},"Typography":{"name":"Typography","submodules":{"Attributes":1,"Loading & Displaying":1},"elements":{},"classes":{"p5.Font":1},"fors":{"p5":1},"namespaces":{},"file":"src/typography/p5.Font.js","line":13},"Array Functions":{"name":"Array Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/array_functions.js","line":1,"requires":["core"]},"Conversion":{"name":"Conversion","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/conversion.js","line":1,"requires":["core"]},"String Functions":{"name":"String Functions","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Data","namespace":"","file":"src/utilities/string_functions.js","line":1,"requires":["core"]},"Time & Date":{"name":"Time & Date","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"IO","namespace":"","file":"src/utilities/time_date.js","line":1,"requires":["core"]},"3D Primitives":{"name":"3D Primitives","submodules":{},"elements":{},"classes":{"p5.Geometry":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"requires":["core","p5.Geometry"],"description":"<p>p5 Geometry class</p>\n"},"3D":{"name":"3D","submodules":{"Interaction":1,"Lights":1,"Material":1,"Camera":1},"elements":{},"classes":{"p5.Camera":1,"p5.Shader":1,"p5.Texture":1,"ImageInfos":1,"FontInfo":1,"Cubic":1},"fors":{"p5":1,"p5.Camera":1},"namespaces":{},"file":"src/webgl/text.js","line":260},"Interaction":{"name":"Interaction","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/interaction.js","line":1,"requires":["core"]},"Lights":{"name":"Lights","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/light.js","line":1,"requires":["core"]},"3D Models":{"name":"3D Models","submodules":{},"elements":{},"classes":{},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"Shape","namespace":"","file":"src/webgl/loading.js","line":1,"requires":["core","p5.Geometry"]},"Material":{"name":"Material","submodules":{},"elements":{},"classes":{"p5.Shader":1,"p5.Texture":1},"fors":{"p5":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Texture.js","line":12,"requires":["core"],"description":"<p>This module defines the p5.Shader class</p>\n"},"Camera":{"name":"Camera","submodules":{},"elements":{},"classes":{"p5.Camera":1},"fors":{"p5":1,"p5.Camera":1},"is_submodule":1,"namespaces":{},"module":"3D","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"requires":["core"],"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n"},"p5.sound":{"name":"p5.sound","submodules":{},"elements":{},"classes":{"p5.sound":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.SinOsc":1,"p5.TriOsc":1,"p5.SawOsc":1,"p5.SqrOsc":1,"p5.Envelope":1,"p5.Noise":1,"p5.Pulse":1,"p5.AudioIn":1,"p5.Effect":1,"p5.Filter":1,"p5.LowPass":1,"p5.HighPass":1,"p5.BandPass":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Phrase":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.PeakDetect":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.OnsetDetect":1,"p5.PolySynth":1},"fors":{"p5.sound":1,"p5":1,"p5.SoundFile":1,"p5.Amplitude":1,"p5.FFT":1,"p5.Oscillator":1,"p5.Envelope":1,"p5.AudioIn":1,"p5.Effect":1,"p5.EQ":1,"p5.Panner3D":1,"p5.Delay":1,"p5.Reverb":1,"p5.Convolver":1,"p5.Part":1,"p5.Score":1,"p5.SoundLoop":1,"p5.Compressor":1,"p5.SoundRecorder":1,"p5.Distortion":1,"p5.Gain":1,"p5.AudioVoice":1,"p5.MonoSynth":1,"p5.PolySynth":1},"namespaces":{},"module":"p5.sound","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>p5.sound extends p5 with <a href=\"http://caniuse.com/audio-api\"\ntarget=\"_blank\">Web Audio</a> functionality including audio input,\nplayback, analysis and synthesis.\n</p>\n<ul>\n<li><a href=\"#/p5.SoundFile\"><b>p5.SoundFile</b></a>: Load and play sound files.</li>\n<li><a href=\"#/p5.Amplitude\"><b>p5.Amplitude</b></a>: Get the current volume of a sound.</li>\n<li><a href=\"#/p5.AudioIn\"><b>p5.AudioIn</b></a>: Get sound from an input source, typically\n  a computer microphone.</li>\n<li><a href=\"#/p5.FFT\"><b>p5.FFT</b></a>: Analyze the frequency of sound. Returns\n  results from the frequency spectrum or time domain (waveform).</li>\n<li><a href=\"#/p5.Oscillator\"><b>p5.Oscillator</b></a>: Generate Sine,\n  Triangle, Square and Sawtooth waveforms. Base class of\n  <li><a href=\"#/p5.Noise\">p5.Noise</a> and <a href=\"#/p5.Pulse\">p5.Pulse</a>.\n  </li>\n<li>\n  <a href=\"#/p5.MonoSynth\">p5.MonoSynth</a> and <a href=\"#/p5.PolySynth\">p5.PolySynth</a>: Play musical notes\n</li>\n<li><a href=\"#/p5.Envelope\"><b>p5.Envelope</b></a>: An Envelope is a series\n  of fades over time. Often used to control an object's\n  output gain level as an \"ADSR Envelope\" (Attack, Decay,\n  Sustain, Release). Can also modulate other parameters.</li>\n<li><a href=\"#/p5.Delay\"><b>p5.Delay</b></a>: A delay effect with\n  parameters for feedback, delayTime, and lowpass filter.</li>\n<li><a href=\"#/p5.Filter\"><b>p5.Filter</b></a>: Filter the frequency range of a\n  sound.\n</li>\n<li><a href=\"#/p5.Reverb\"><b>p5.Reverb</b></a>: Add reverb to a sound by specifying\n  duration and decay. </li>\n<b><li><a href=\"#/p5.Convolver\">p5.Convolver</a>:</b> Extends\n<a href=\"#/p5.Reverb\">p5.Reverb</a> to simulate the sound of real\n  physical spaces through convolution.</li>\n<b><li><a href=\"#/p5.SoundRecorder\">p5.SoundRecorder</a></b>: Record sound for playback\n  / save the .wav file.\n<b><li><a href=\"#/p5.SoundLoop\">p5.SoundLoop</a>, <a href=\"#/p5.Phrase\">p5.Phrase</a></b>, <b><a href=\"#/p5.Part\">p5.Part</a></b> and\n<b><a href=\"#/p5.Score\">p5.Score</a></b>: Compose musical sequences.\n</li>\n<li><a href=\"#/p5/userStartAudio\">userStartAudio</a>: Enable audio in a\nbrowser- and user-friendly way.</a>\n<p>p5.sound is on <a href=\"https://github.com/processing/p5.js-sound/\">GitHub</a>.\nDownload the latest version\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/lib/p5.sound.js\">here</a>.</p>","tag":"main","itemtype":"main"}},"classes":{"p5":{"name":"p5","shortname":"p5","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/core/main.js","line":13,"description":"<p>This is the p5 instance constructor.</p>\n<p>A p5 instance holds all the properties and methods related to\na p5 sketch.  It expects an incoming sketch closure and it can also\ntake an optional node parameter for attaching the generated p5 canvas\nto a node.  The sketch closure takes the newly created p5 instance as\nits sole argument and may optionally set <a href=\"#/p5/preload\">preload()</a>,\n<a href=\"#/p5/setup\">setup()</a>, and/or\n<a href=\"#/p5/draw\">draw()</a> properties on it for running a sketch.</p>\n<p>A p5 sketch can run in \"global\" or \"instance\" mode:\n\"global\"   - all properties and methods are attached to the window\n\"instance\" - all properties and methods are bound to this p5 object</p>\n","is_constructor":1,"params":[{"name":"sketch","description":"<p>a closure that can set optional <a href=\"#/p5/preload\">preload()</a>,\n                             <a href=\"#/p5/setup\">setup()</a>, and/or <a href=\"#/p5/draw\">draw()</a> properties on the\n                             given p5 instance</p>\n","type":"Function"},{"name":"node","description":"<p>element to attach canvas to</p>\n","type":"HTMLElement","optional":true}],"return":{"description":"a p5 instance","type":"P5"}},"p5.Color":{"name":"p5.Color","shortname":"p5.Color","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Color","submodule":"Creating & Reading","namespace":"","file":"src/color/p5.Color.js","line":14,"description":"<p>Each color stores the color mode and level maxes that was applied at the\ntime of its construction. These are used to interpret the input arguments\n(at construction and later for that instance of color) and to format the\noutput e.g. when <a href=\"#/p5/saturation\">saturation()</a> is requested.</p>\n<p>Internally, we store an array representing the ideal RGBA values in floating\npoint form, normalized from 0 to 1. From this we calculate the closest\nscreen color (RGBA levels from 0 to 255) and expose this to the renderer.</p>\n<p>We also cache normalized, floating point components of the color in various\nrepresentations as they are calculated. This is done to prevent repeating a\nconversion that has already been performed.</p>\n","is_constructor":1},"p5.Element":{"name":"p5.Element","shortname":"p5.Element","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/core/p5.Element.js","line":9,"description":"<p>Base class for all elements added to a sketch, including canvas,\ngraphics buffers, and other HTML elements. It is not called directly, but <a href=\"#/p5.Element\">p5.Element</a>\nobjects are created by calling <a href=\"#/p5/createCanvas\">createCanvas</a>, <a href=\"#/p5/createGraphics\">createGraphics</a>,\n<a href=\"#/p5/createDiv\">createDiv</a>, <a href=\"#/p5/createImg\">createImg</a>, <a href=\"#/p5/createInput\">createInput</a>, etc.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Graphics":{"name":"p5.Graphics","shortname":"p5.Graphics","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Graphics.js","line":10,"description":"<p>Thin wrapper around a renderer, to be used for creating a\ngraphics buffer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels. The fields and methods for this class are\nextensive, but mirror the normal drawing API for p5.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"},{"name":"renderer","description":"<p>the renderer to use, either P2D or WEBGL</p>\n","type":"Constant"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Renderer":{"name":"p5.Renderer","shortname":"p5.Renderer","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Rendering","submodule":"Rendering","namespace":"","file":"src/core/p5.Renderer.js","line":10,"description":"<p>Main graphics and rendering context, as well as the base API\nimplementation for p5.js \"core\". To be used as the superclass for\nRenderer2D and Renderer3D classes, respectively.</p>\n","is_constructor":1,"extends":"p5.Element","params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"},{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true},{"name":"isMainCanvas","description":"<p>whether we're using it as main canvas</p>\n","type":"Boolean","optional":true}]},"JSON":{"name":"JSON","shortname":"JSON","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"console":{"name":"console","shortname":"console","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Foundation","submodule":"Foundation","namespace":""},"p5.TypedDict":{"name":"p5.TypedDict","shortname":"p5.TypedDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":82,"description":"<p>Base class for all p5.Dictionary types. Specifically\n typed Dictionary classes inherit from this class.</p>\n","is_constructor":1},"p5.StringDict":{"name":"p5.StringDict","shortname":"p5.StringDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":394,"description":"<p>A simple Dictionary class for Strings.</p>\n","extends":"p5.TypedDict"},"p5.NumberDict":{"name":"p5.NumberDict","shortname":"p5.NumberDict","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Data","submodule":"Dictionary","namespace":"","file":"src/data/p5.TypedDict.js","line":410,"description":"<p>A simple Dictionary class for Numbers.</p>\n","is_constructor":1,"extends":"p5.TypedDict"},"p5.MediaElement":{"name":"p5.MediaElement","shortname":"p5.MediaElement","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":2377,"description":"<p>Extends <a href=\"#/p5.Element\">p5.Element</a> to handle audio and video. In addition to the methods\nof <a href=\"#/p5.Element\">p5.Element</a>, it also contains methods for controlling media. It is not\ncalled directly, but <a href=\"#/p5.MediaElement\">p5.MediaElement</a>s are created by calling <a href=\"#/p5/createVideo\">createVideo</a>,\n<a href=\"#/p5/createAudio\">createAudio</a>, and <a href=\"#/p5/createCapture\">createCapture</a>.</p>\n","is_constructor":1,"params":[{"name":"elt","description":"<p>DOM node that is wrapped</p>\n","type":"String"}]},"p5.File":{"name":"p5.File","shortname":"p5.File","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"DOM","submodule":"DOM","namespace":"","file":"src/dom/dom.js","line":3533,"description":"<p>Base class for a file.\nUsed for Element.drop and createFileInput.</p>\n","is_constructor":1,"params":[{"name":"file","description":"<p>File that is wrapped</p>\n","type":"File"}]},"p5.Image":{"name":"p5.Image","shortname":"p5.Image","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Image","submodule":"Image","namespace":"","file":"src/image/p5.Image.js","line":21,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a>. A <a href=\"#/p5.Image\">p5.Image</a> is a canvas backed representation of an\nimage.</p>\n<p>p5 can display .gif, .jpg and .png images. Images may be displayed\nin 2D and 3D space. Before an image is used, it must be loaded with the\n<a href=\"#/p5/loadImage\">loadImage()</a> function. The <a href=\"#/p5.Image\">p5.Image</a> class contains fields for the width and\nheight of the image, as well as an array called <a href=\"#/p5.Image/pixels\">pixels[]</a> that contains the\nvalues for every pixel in the image.</p>\n<p>The methods described below allow easy access to the image's pixels and\nalpha channel and simplify the process of compositing.</p>\n<p>Before using the <a href=\"#/p5.Image/pixels\">pixels[]</a> array, be sure to use the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a> method on\nthe image to make sure that the pixel data is properly loaded.</p>\n","example":["\n<div><code>\nfunction setup() {\n  let img = createImage(100, 100); // same as new p5.Image(100, 100);\n  img.loadPixels();\n  createCanvas(100, 100);\n  background(0);\n\n  // helper for writing color to array\n  function writeColor(image, x, y, red, green, blue, alpha) {\n    let index = (x + y * width) * 4;\n    image.pixels[index] = red;\n    image.pixels[index + 1] = green;\n    image.pixels[index + 2] = blue;\n    image.pixels[index + 3] = alpha;\n  }\n\n  let x, y;\n  // fill with random colors\n  for (y = 0; y < img.height; y++) {\n    for (x = 0; x < img.width; x++) {\n      let red = random(255);\n      let green = random(255);\n      let blue = random(255);\n      let alpha = 255;\n      writeColor(img, x, y, red, green, blue, alpha);\n    }\n  }\n\n  // draw a red line\n  y = 0;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 255, 0, 0, 255);\n  }\n\n  // draw a green line\n  y = img.height - 1;\n  for (x = 0; x < img.width; x++) {\n    writeColor(img, x, y, 0, 255, 0, 255);\n  }\n\n  img.updatePixels();\n  image(img, 0, 0);\n}\n</code></div>"],"is_constructor":1,"params":[{"name":"width","description":"","type":"Number"},{"name":"height","description":"","type":"Number"}]},"p5.PrintWriter":{"name":"p5.PrintWriter","shortname":"p5.PrintWriter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Output","namespace":"","file":"src/io/files.js","line":1200,"params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"","type":"String","optional":true}]},"p5.Table":{"name":"p5.Table","shortname":"p5.Table","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.Table.js","line":33,"description":"<p><a href=\"#/p5.Table\">Table</a> objects store data with multiple rows and columns, much\nlike in a traditional spreadsheet. Tables can be generated from\nscratch, dynamically, or using data from an existing file.</p>\n","is_constructor":1,"params":[{"name":"rows","description":"<p>An array of p5.TableRow objects</p>\n","type":"p5.TableRow[]","optional":true}]},"p5.TableRow":{"name":"p5.TableRow","shortname":"p5.TableRow","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Table","namespace":"","file":"src/io/p5.TableRow.js","line":9,"description":"<p>A TableRow object represents a single row of data values,\nstored in columns, from a table.</p>\n<p>A Table Row contains both an ordered array, and an unordered\nJSON object.</p>\n","is_constructor":1,"params":[{"name":"str","description":"<p>optional: populate the row with a\n                            string of values, separated by the\n                            separator</p>\n","type":"String","optional":true},{"name":"separator","description":"<p>comma separated values (csv) by default</p>\n","type":"String","optional":true}]},"p5.XML":{"name":"p5.XML","shortname":"p5.XML","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"IO","submodule":"Input","namespace":"","file":"src/io/p5.XML.js","line":9,"description":"<p>XML is a representation of an XML object, able to parse XML code. Use\n<a href=\"#/p5/loadXML\">loadXML()</a> to load external XML files and create XML objects.</p>\n","is_constructor":1,"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed"},"p5.Vector":{"name":"p5.Vector","shortname":"p5.Vector","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Math","submodule":"Vector","namespace":"","file":"src/math/p5.Vector.js","line":10,"description":"<p>A class to describe a two or three dimensional vector, specifically\na Euclidean (also known as geometric) vector. A vector is an entity\nthat has both magnitude and direction. The datatype, however, stores\nthe components of the vector (x, y for 2D, and x, y, z for 3D). The magnitude\nand direction can be accessed via the methods <a href=\"#/p5.Vector/mag\">mag()</a> and <a href=\"#/p5.Vector/heading\">heading()</a>.</p>\n<p>In many of the p5.js examples, you will see <a href=\"#/p5.Vector\">p5.Vector</a> used to describe a\nposition, velocity, or acceleration. For example, if you consider a rectangle\nmoving across the screen, at any given instant it has a position (a vector\nthat points from the origin to its location), a velocity (the rate at which\nthe object's position changes per time unit, expressed as a vector), and\nacceleration (the rate at which the object's velocity changes per time\nunit, expressed as a vector).</p>\n<p>Since vectors represent groupings of values, we cannot simply use\ntraditional addition/multiplication/etc. Instead, we'll need to do some\n\"vector\" math, which is made easy by the methods inside the <a href=\"#/p5.Vector\">p5.Vector</a> class.</p>\n","is_constructor":1,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet v1 = createVector(40, 50);\nlet v2 = createVector(40, 50);\n\nellipse(v1.x, v1.y, 50, 50);\nellipse(v2.x, v2.y, 50, 50);\nv1.add(v2);\nellipse(v1.x, v1.y, 50, 50);\n</code>\n</div>"],"alt":"2 white ellipses. One center-left the other bottom right and off canvas"},"p5.Font":{"name":"p5.Font","shortname":"p5.Font","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Typography","submodule":"Loading & Displaying","namespace":"","file":"src/typography/p5.Font.js","line":13,"description":"<p>Base class for font handling</p>\n","is_constructor":1,"params":[{"name":"pInst","description":"<p>pointer to p5 instance</p>\n","type":"P5","optional":true}]},"p5.Camera":{"name":"p5.Camera","shortname":"p5.Camera","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Camera","namespace":"","file":"src/webgl/p5.Camera.js","line":357,"description":"<p>This class describes a camera for use in p5's\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5\">\nWebGL mode</a>. It contains camera position, orientation, and projection\ninformation necessary for rendering a 3D scene.</p>\n<p>New p5.Camera objects can be made through the\n<a href=\"#/p5/createCamera\">createCamera()</a> function and controlled through\nthe methods described below. A camera created in this way will use a default\nposition in the scene and a default perspective projection until these\nproperties are changed through the various methods available. It is possible\nto create multiple cameras, in which case the current camera\ncan be set through the <a href=\"#/p5/setCamera\">setCamera()</a> method.</p>\n<p>Note:\nThe methods below operate in two coordinate systems: the 'world' coordinate\nsystem describe positions in terms of their relationship to the origin along\nthe X, Y and Z axes whereas the camera's 'local' coordinate system\ndescribes positions from the camera's point of view: left-right, up-down,\nand forward-backward. The <a href=\"#/p5.Camera/move\">move()</a> method,\nfor instance, moves the camera along its own axes, whereas the\n<a href=\"#/p5.Camera/setPosition\">setPosition()</a>\nmethod sets the camera's position in world-space.</p>\n<p>The camera object propreties\n<code>eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ</code>\nwhich describes camera position, orientation, and projection\nare also accessible via the camera object generated using\n<a href=\"#/p5/createCamera\">createCamera()</a></p>\n","params":[{"name":"rendererGL","description":"<p>instance of WebGL renderer</p>\n","type":"RendererGL"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes."},"p5.Geometry":{"name":"p5.Geometry","shortname":"p5.Geometry","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"Shape","submodule":"3D Primitives","namespace":"","file":"src/webgl/p5.Geometry.js","line":12,"description":"<p>p5 Geometry class</p>\n","is_constructor":1,"params":[{"name":"detailX","description":"<p>number of vertices along the x-axis.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of vertices along the y-axis.</p>\n","type":"Integer","optional":true},{"name":"callback","description":"<p>function to call upon object instantiation.</p>\n","type":"Function","optional":true}]},"p5.Shader":{"name":"p5.Shader","shortname":"p5.Shader","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"3D","submodule":"Material","namespace":"","file":"src/webgl/p5.Shader.js","line":11,"description":"<p>Shader class for WEBGL Mode</p>\n","is_constructor":1,"params":[{"name":"renderer","description":"<p>an instance of p5.RendererGL that\nwill provide the GL context for this new p5.Shader</p>\n","type":"p5.RendererGL"},{"name":"vertSrc","description":"<p>source code for the vertex shader (as a string)</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader (as a string)</p>\n","type":"String"}]},"p5.sound":{"name":"p5.sound","shortname":"p5.sound","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":""},"p5.SoundFile":{"name":"p5.SoundFile","shortname":"p5.SoundFile","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":1405,"description":"<p>SoundFile object with a path to a file.</p>\n\n<p>The p5.SoundFile may not be available immediately because\nit loads the file information asynchronously.</p>\n\n<p>To do something with the sound as soon as it loads\npass the name of a function as the second parameter.</p>\n\n<p>Only one file path is required. However, audio file formats\n(i.e. mp3, ogg, wav and m4a/aac) are not supported by all\nweb browsers. If you want to ensure compatability, instead of a single\nfile path, you may include an Array of filepaths, and the browser will\nchoose a format that works.</p>","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file (String). Optionally,\n                             you may include multiple file formats in\n                             an array. Alternately, accepts an object\n                             from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if file fails to\n                                    load. This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true},{"name":"whileLoadingCallback","description":"<p>Name of a function to call while file\n                                           is loading. That function will\n                                           receive progress of the request to\n                                           load the sound file\n                                           (between 0 and 1) as its first\n                                           parameter. This progress\n                                           does not account for the additional\n                                           time needed to decode the audio data.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n </code></div>"]},"p5.Amplitude":{"name":"p5.Amplitude","shortname":"p5.Amplitude","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3022,"description":"<p>Amplitude measures volume between 0.0 and 1.0.\nListens to all p5sound by default, or use setInput()\nto listen to a specific sound source. Accepts an optional\nsmoothing value, which defaults to 0.</p>\n","is_constructor":1,"params":[{"name":"smoothing","description":"<p>between 0.0 and .999 to smooth\n                           amplitude readings (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet sound, amplitude;\n\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying() ){\n    sound.pause();\n  } else {\n    sound.loop();\n\t\tamplitude = new p5.Amplitude();\n\t\tamplitude.setInput(sound);\n  }\n}\n\n</code></div>"]},"p5.FFT":{"name":"p5.FFT","shortname":"p5.FFT","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":3347,"description":"<p>FFT (Fast Fourier Transform) is an analysis algorithm that\nisolates individual\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\">\naudio frequencies</a> within a waveform.</p>\n\n<p>Once instantiated, a p5.FFT object can return an array based on\ntwo types of analyses: <br> • <code>FFT.waveform()</code> computes\namplitude values along the time domain. The array indices correspond\nto samples across a brief moment in time. Each value represents\namplitude of the waveform at that sample of time.<br>\n• <code>FFT.analyze() </code> computes amplitude values along the\nfrequency domain. The array indices correspond to frequencies (i.e.\npitches), from the lowest to the highest that humans can hear. Each\nvalue represents amplitude at that slice of the frequency spectrum.\nUse with <code>getEnergy()</code> to measure amplitude at specific\nfrequencies, or within a range of frequencies. </p>\n\n<p>FFT analyzes a very short snapshot of sound called a sample\nbuffer. It returns an array of amplitude measurements, referred\nto as <code>bins</code>. The array is 1024 bins long by default.\nYou can change the bin array length, but it must be a power of 2\nbetween 16 and 1024 in order for the FFT algorithm to function\ncorrectly. The actual size of the FFT buffer is twice the\nnumber of bins, so given a standard sample rate, the buffer is\n2048/44100 seconds long.</p>","is_constructor":1,"params":[{"name":"smoothing","description":"<p>Smooth results of Freq Spectrum.\n                              0.0 < smoothing < 1.0.\n                              Defaults to 0.8.</p>\n","type":"Number","optional":true},{"name":"bins","description":"<p>Length of resulting array.\n                          Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mouseClicked(togglePlay);\n  fft = new p5.FFT();\n  sound.amp(0.2);\n}\n\nfunction draw(){\n  background(220);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h )\n  }\n\n  let waveform = fft.waveform();\n  noFill();\n  beginShape();\n  stroke(20);\n  for (let i = 0; i < waveform.length; i++){\n    let x = map(i, 0, waveform.length, 0, width);\n    let y = map( waveform[i], -1, 1, 0, height);\n    vertex(x,y);\n  }\n  endShape();\n\n  text('tap to play', 20, 20);\n}\n\nfunction togglePlay() {\n  if (sound.isPlaying()) {\n    sound.pause();\n  } else {\n    sound.loop();\n  }\n}\n</code></div>"]},"p5.Oscillator":{"name":"p5.Oscillator","shortname":"p5.Oscillator","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4060,"description":"<p>Creates a signal that oscillates between -1.0 and 1.0.\nBy default, the oscillation takes the form of a sinusoidal\nshape ('sine'). Additional types include 'triangle',\n'sawtooth' and 'square'. The frequency defaults to\n440 oscillations per second (440Hz, equal to the pitch of an\n'A' note).</p>\n\n<p>Set the type of oscillation with setType(), or by instantiating a\nspecific oscillator: <a href=\"/reference/#/p5.SinOsc\">p5.SinOsc</a>, <a\nhref=\"/reference/#/p5.TriOsc\">p5.TriOsc</a>, <a\nhref=\"/reference/#/p5.SqrOsc\">p5.SqrOsc</a>, or <a\nhref=\"/reference/#/p5.SawOsc\">p5.SawOsc</a>.\n</p>","is_constructor":1,"params":[{"name":"freq","description":"<p>frequency defaults to 440Hz</p>\n","type":"Number","optional":true},{"name":"type","description":"<p>type of oscillator. Options:\n                       'sine' (default), 'triangle',\n                       'sawtooth', 'square'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet osc, playing, freq, amp;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator('sine');\n}\n\nfunction draw() {\n  background(220)\n  freq = constrain(map(mouseX, 0, width, 100, 500), 100, 500);\n  amp = constrain(map(mouseY, height, 0, 0, 1), 0, 1);\n\n  text('tap to play', 20, 20);\n  text('freq: ' + freq, 20, 40);\n  text('amp: ' + amp, 20, 60);\n\n  if (playing) {\n    // smooth the transitions by 0.1 seconds\n    osc.freq(freq, 0.1);\n    osc.amp(amp, 0.1);\n  }\n}\n\nfunction playOscillator() {\n  // starting an oscillator on a user gesture will enable audio\n  // in browsers that have a strict autoplay policy.\n  // See also: userStartAudio();\n  osc.start();\n  playing = true;\n}\n\nfunction mouseReleased() {\n  // ramp amplitude to 0 over 0.5 seconds\n  osc.amp(0, 0.5);\n  playing = false;\n}\n</code> </div>"]},"p5.SinOsc":{"name":"p5.SinOsc","shortname":"p5.SinOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4602,"description":"<p>Constructor: <code>new p5.SinOsc()</code>.\nThis creates a Sine Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sine')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sine')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.TriOsc":{"name":"p5.TriOsc","shortname":"p5.TriOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4629,"description":"<p>Constructor: <code>new p5.TriOsc()</code>.\nThis creates a Triangle Wave Oscillator and is\nequivalent to <code>new p5.Oscillator('triangle')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('triangle')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SawOsc":{"name":"p5.SawOsc","shortname":"p5.SawOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4656,"description":"<p>Constructor: <code>new p5.SawOsc()</code>.\nThis creates a SawTooth Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('sawtooth')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('sawtooth')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.SqrOsc":{"name":"p5.SqrOsc","shortname":"p5.SqrOsc","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4683,"description":"<p>Constructor: <code>new p5.SqrOsc()</code>.\nThis creates a Square Wave Oscillator and is\nequivalent to <code> new p5.Oscillator('square')\n</code> or creating a p5.Oscillator and then calling\nits method <code>setType('square')</code>.\nSee p5.Oscillator for methods.</p>\n","is_constructor":1,"extends":"p5.Oscillator","params":[{"name":"freq","description":"<p>Set the frequency</p>\n","type":"Number","optional":true}]},"p5.Envelope":{"name":"p5.Envelope","shortname":"p5.Envelope","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":4721,"description":"<p>Envelopes are pre-defined amplitude distribution over time.\nTypically, envelopes are used to control the output volume\nof an object, a series of fades referred to as Attack, Decay,\nSustain and Release (\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg\">ADSR</a>\n). Envelopes can also control other Web Audio Parameters—for example, a p5.Envelope can\ncontrol an Oscillator's frequency like this: <code>osc.freq(env)</code>.</p>\n<p>Use <code><a href=\"#/p5.Envelope/setRange\">setRange</a></code> to change the attack/release level.\nUse <code><a href=\"#/p5.Envelope/setADSR\">setADSR</a></code> to change attackTime, decayTime, sustainPercent and releaseTime.</p>\n<p>Use the <code><a href=\"#/p5.Envelope/play\">play</a></code> method to play the entire envelope,\nthe <code><a href=\"#/p5.Envelope/ramp\">ramp</a></code> method for a pingable trigger,\nor <code><a href=\"#/p5.Envelope/triggerAttack\">triggerAttack</a></code>/\n<code><a href=\"#/p5.Envelope/triggerRelease\">triggerRelease</a></code> to trigger noteOn/noteOff.</p>","is_constructor":1,"example":["\n<div><code>\nlet t1 = 0.1; // attack time in seconds\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\n\nlet env;\nlet triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  text('tap to play', 20, 20);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope(t1, l1, t2, l2);\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction playSound() {\n  // starting the oscillator ensures that audio is enabled.\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>"]},"p5.Noise":{"name":"p5.Noise","shortname":"p5.Noise","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5620,"description":"<p>Noise is a type of oscillator that generates a buffer with random values.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"type","description":"<p>Type of noise can be 'white' (default),\n                     'brown' or 'pink'.</p>\n","type":"String"}]},"p5.Pulse":{"name":"p5.Pulse","shortname":"p5.Pulse","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":5779,"description":"<p>Creates a Pulse object, an oscillator that implements\nPulse Width Modulation.\nThe pulse is created with two oscillators.\nAccepts a parameter for frequency, and to set the\nwidth between the pulses. See <a href=\"\nhttp://p5js.org/reference/#/p5.Oscillator\">\n<code>p5.Oscillator</code> for a full list of methods.</p>\n","extends":"p5.Oscillator","is_constructor":1,"params":[{"name":"freq","description":"<p>Frequency in oscillations per second (Hz)</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet pulse;\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startPulse);\n  background(220);\n\n  pulse = new p5.Pulse();\n  pulse.amp(0.5);\n  pulse.freq(220);\n}\nfunction startPulse() {\n  pulse.start();\n  pulse.amp(0.5, 0.02);\n}\nfunction mouseReleased() {\n  pulse.amp(0, 0.2);\n}\nfunction draw() {\n  background(220);\n  text('tap to play', 5, 20, width - 20);\n  let w = map(mouseX, 0, width, 0, 1);\n  w = constrain(w, 0, 1);\n  pulse.width(w);\n  text('pulse width: ' + w, 5, height - 20);\n}\n</code></div>"]},"p5.AudioIn":{"name":"p5.AudioIn","shortname":"p5.AudioIn","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6015,"description":"<p>Get audio from an input, i.e. your computer's microphone.</p>\n\n<p>Turn the mic on/off with the start() and stop() methods. When the mic\nis on, its volume can be measured with getLevel or by connecting an\nFFT object.</p>\n\n<p>If you want to hear the AudioIn, use the .connect() method.\nAudioIn does not connect to p5.sound output by default to prevent\nfeedback.</p>\n\n<p><em>Note: This uses the <a href=\"http://caniuse.com/stream\">getUserMedia/\nStream</a> API, which is not supported by certain browsers. Access in Chrome browser\nis limited to localhost and https, but access over http may be limited.</em></p>","is_constructor":1,"params":[{"name":"errorCallback","description":"<p>A function to call if there is an error\n                                  accessing the AudioIn. For example,\n                                  Safari and iOS devices do not\n                                  currently allow microphone access.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet mic;\n\n function setup(){\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(userStartAudio);\n  textAlign(CENTER);\n  mic = new p5.AudioIn();\n  mic.start();\n}\n\nfunction draw(){\n  background(0);\n  fill(255);\n  text('tap to start', width/2, 20);\n\n  micLevel = mic.getLevel();\n  let y = height - micLevel * height;\n  ellipse(width/2, y, 10, 10);\n}\n</code></div>"]},"p5.Effect":{"name":"p5.Effect","shortname":"p5.Effect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6423,"description":"<p>Effect is a base class for audio effects in p5. <br>\nThis module handles the nodes and methods that are\ncommon and useful for current and future effects.</p>\n<p>This class is extended by <a href=\"/reference/#/p5.Distortion\">p5.Distortion</a>,\n<a href=\"/reference/#/p5.Compressor\">p5.Compressor</a>,\n<a href=\"/reference/#/p5.Delay\">p5.Delay</a>,\n<a href=\"/reference/#/p5.Filter\">p5.Filter</a>,\n<a href=\"/reference/#/p5.Reverb\">p5.Reverb</a>.</p>\n","is_constructor":1,"params":[{"name":"ac","description":"<p>Reference to the audio context of the p5 object</p>\n","type":"Object","optional":true},{"name":"input","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"output","description":"<p>Gain Node effect wrapper</p>\n","type":"AudioNode","optional":true},{"name":"_drywet","description":"<p>Tone.JS CrossFade node (defaults to value: 1)</p>\n","type":"Object","optional":true},{"name":"wet","description":"<p>Effects that extend this class should connect\n                             to the wet signal to this gain node, so that dry and wet\n                             signals are mixed properly.</p>\n","type":"AudioNode","optional":true}]},"p5.Filter":{"name":"p5.Filter","shortname":"p5.Filter","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6628,"description":"<p>A p5.Filter uses a Web Audio Biquad Filter to filter\nthe frequency response of an input source. Subclasses\ninclude:</p>\n<a href=\"/reference/#/p5.LowPass\"><code>p5.LowPass</code></a>:\nAllows frequencies below the cutoff frequency to pass through,\nand attenuates frequencies above the cutoff.<br/>\n<a href=\"/reference/#/p5.HighPass\"><code>p5.HighPass</code></a>:\nThe opposite of a lowpass filter. <br/>\n<a href=\"/reference/#/p5.BandPass\"><code>p5.BandPass</code></a>:\nAllows a range of frequencies to pass through and attenuates\nthe frequencies below and above this frequency range.<br/>\n\n<p>The <code>.res()</code> method controls either width of the\nbandpass, or resonance of the low/highpass cutoff frequency.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"type","description":"<p>'lowpass' (default), 'highpass', 'bandpass'</p>\n","type":"String","optional":true}],"example":["\n<div><code>\nlet fft, noise, filter;\n\nfunction setup() {\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(makeNoise);\n  fill(255, 0, 255);\n\n  filter = new p5.BandPass();\n  noise = new p5.Noise();\n  noise.disconnect();\n  noise.connect(filter);\n\n  fft = new p5.FFT();\n}\n\nfunction draw() {\n  background(220);\n\n  // set the BandPass frequency based on mouseX\n  let freq = map(mouseX, 0, width, 20, 10000);\n  freq = constrain(freq, 0, 22050);\n  filter.freq(freq);\n  // give the filter a narrow band (lower res = wider bandpass)\n  filter.res(50);\n\n  // draw filtered spectrum\n  let spectrum = fft.analyze();\n  noStroke();\n  for (let i = 0; i < spectrum.length; i++) {\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width/spectrum.length, h);\n  }\n  if (!noise.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text('Frequency: ' + round(freq)+'Hz', 20, 20, width - 20);\n  }\n}\n\nfunction makeNoise() {\n  // see also: `userStartAudio()`\n  noise.start();\n  noise.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  noise.amp(0, 0.2);\n}\n\n</code></div>"]},"p5.LowPass":{"name":"p5.LowPass","shortname":"p5.LowPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6914,"description":"<p>Constructor: <code>new p5.LowPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('lowpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.HighPass":{"name":"p5.HighPass","shortname":"p5.HighPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6938,"description":"<p>Constructor: <code>new p5.HighPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('highpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.BandPass":{"name":"p5.BandPass","shortname":"p5.BandPass","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":6962,"description":"<p>Constructor: <code>new p5.BandPass()</code> Filter.\nThis is the same as creating a p5.Filter and then calling\nits method <code>setType('bandpass')</code>.\nSee p5.Filter for methods.</p>\n","is_constructor":1,"extends":"p5.Filter"},"p5.EQ":{"name":"p5.EQ","shortname":"p5.EQ","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7105,"description":"<p>p5.EQ is an audio effect that performs the function of a multiband\naudio equalizer. Equalization is used to adjust the balance of\nfrequency compoenents of an audio signal. This process is commonly used\nin sound production and recording to change the waveform before it reaches\na sound output device. EQ can also be used as an audio effect to create\ninteresting distortions by filtering out parts of the spectrum. p5.EQ is\nbuilt using a chain of Web Audio Biquad Filter Nodes and can be\ninstantiated with 3 or 8 bands. Bands can be added or removed from\nthe EQ by directly modifying p5.EQ.bands (the array that stores filters).</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect","params":[{"name":"_eqsize","description":"<p>Constructor will accept 3 or 8, defaults to 3</p>\n","type":"Number","optional":true}],"return":{"description":"p5.EQ object","type":"Object"},"example":["\n<div><code>\nlet eq, soundFile\nlet eqBandIndex = 0;\nlet eqBandNames = ['lows', 'mids', 'highs'];\n\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  soundFile = loadSound('assets/beat');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(toggleSound);\n\n  eq = new p5.EQ(eqBandNames.length);\n  soundFile.disconnect();\n  eq.process(soundFile);\n}\n\nfunction draw() {\n  background(30);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n  text('filtering ', 50, 25);\n\n  fill(255, 40, 255);\n  textSize(26);\n  text(eqBandNames[eqBandIndex], 50, 55);\n\n  fill(255);\n  textSize(9);\n\n  if (!soundFile.isPlaying()) {\n    text('tap to play', 50, 80);\n  } else {\n    text('tap to filter next band', 50, 80)\n  }\n}\n\nfunction toggleSound() {\n  if (!soundFile.isPlaying()) {\n    soundFile.play();\n  } else {\n    eqBandIndex = (eqBandIndex + 1) % eq.bands.length;\n  }\n\n  for (let i = 0; i < eq.bands.length; i++) {\n    eq.bands[i].gain(0);\n  }\n  // filter the band we want to filter\n  eq.bands[eqBandIndex].gain(-40);\n}\n</code></div>"]},"p5.Panner3D":{"name":"p5.Panner3D","shortname":"p5.Panner3D","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7602,"description":"<p>Panner3D is based on the <a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a>.\nThis panner is a spatial processing node that allows audio to be positioned\nand oriented in 3D space.</p>\n<p>The position is relative to an <a title=\"Web Audio Listener docs\" href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/AudioListener\">\nAudio Context Listener</a>, which can be accessed\nby <code>p5.soundOut.audiocontext.listener</code></p>\n","is_constructor":1},"p5.Delay":{"name":"p5.Delay","shortname":"p5.Delay","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":7926,"description":"<p>Delay is an echo effect. It processes an existing sound source,\nand outputs a delayed version of that sound. The p5.Delay can\nproduce different effects depending on the delayTime, feedback,\nfilter, and type. In the example below, a feedback of 0.5 (the\ndefault value) will produce a looping delay that decreases in\nvolume by 50% each repeat. A filter will cut out the high\nfrequencies so that the delay does not sound as piercing as the\noriginal source.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  osc = new p5.Oscillator('square');\n  osc.amp(0.5);\n  delay = new p5.Delay();\n\n  // delay.process() accepts 4 parameters:\n  // source, delayTime (in seconds), feedback, filter frequency\n  delay.process(osc, 0.12, .7, 2300);\n\n  cnv.mousePressed(oscStart);\n}\n\nfunction oscStart() {\n  osc.start();\n}\n\nfunction mouseReleased() {\n  osc.stop();\n}\n</code></div>"]},"p5.Reverb":{"name":"p5.Reverb","shortname":"p5.Reverb","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8308,"description":"<p>Reverb adds depth to a sound through a large number of decaying\nechoes. It creates the perception that sound is occurring in a\nphysical space. The p5.Reverb has paramters for Time (how long does the\nreverb last) and decayRate (how much the sound decays with each echo)\nthat can be set with the .set() or .process() methods. The p5.Convolver\nextends p5.Reverb allowing you to recreate the sound of actual physical\nspaces through convolution.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"example":["\n<div><code>\nlet soundFile, reverb;\nfunction preload() {\n  soundFile = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  reverb = new p5.Reverb();\n  soundFile.disconnect(); // so we'll only hear reverb...\n\n  // connect soundFile to reverb, process w/\n  // 3 second reverbTime, decayRate of 2%\n  reverb.process(soundFile, 3, 2);\n}\n\nfunction draw() {\n  let dryWet = constrain(map(mouseX, 0, width, 0, 1), 0, 1);\n  // 1 = all reverb, 0 = no reverb\n  reverb.drywet(dryWet);\n\n  background(220);\n  text('tap to play', 10, 20);\n  text('dry/wet: ' + round(dryWet * 100) + '%', 10, height - 20);\n}\n\nfunction playSound() {\n  soundFile.play();\n}\n</code></div>"]},"p5.Convolver":{"name":"p5.Convolver","shortname":"p5.Convolver","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":8549,"description":"<p>p5.Convolver extends p5.Reverb. It can emulate the sound of real\nphysical spaces through a process called <a href=\"\nhttps://en.wikipedia.org/wiki/Convolution_reverb#Real_space_simulation\">\nconvolution</a>.</p>\n\n<p>Convolution multiplies any audio input by an \"impulse response\"\nto simulate the dispersion of sound over time. The impulse response is\ngenerated from an audio file that you provide. One way to\ngenerate an impulse response is to pop a balloon in a reverberant space\nand record the echo. Convolution can also be used to experiment with\nsound.</p>\n\n<p>Use the method <code>createConvolution(path)</code> to instantiate a\np5.Convolver with a path to your impulse response audio file.</p>","extends":"p5.Effect","is_constructor":1,"params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call when loading succeeds</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading fails.\n                                   This function will receive an error or\n                                   XMLHttpRequest object with information\n                                   about what went wrong.</p>\n","type":"Function","optional":true}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"]},"p5.Phrase":{"name":"p5.Phrase","shortname":"p5.Phrase","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9103,"description":"<p>A phrase is a pattern of musical events over time, i.e.\na series of notes and rests.</p>\n\n<p>Phrases must be added to a p5.Part for playback, and\neach part can play multiple phrases at the same time.\nFor example, one Phrase might be a kick drum, another\ncould be a snare, and another could be the bassline.</p>\n\n<p>The first parameter is a name so that the phrase can be\nmodified or deleted later. The callback is a a function that\nthis phrase will call at every step—for example it might be\ncalled <code>playNote(value){}</code>. The array determines\nwhich value is passed into the callback at each step of the\nphrase. It can be numbers, an object with multiple numbers,\nor a zero (0) indicates a rest so the callback won't be called).</p>","is_constructor":1,"params":[{"name":"name","description":"<p>Name so that you can access the Phrase.</p>\n","type":"String"},{"name":"callback","description":"<p>The name of a function that this phrase\n                           will call. Typically it will play a sound,\n                           and accept two parameters: a time at which\n                           to play the sound (in seconds from now),\n                           and a value from the sequence array. The\n                           time should be passed into the play() or\n                           start() method to ensure precision.</p>\n","type":"Function"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"example":["\n<div><code>\nlet mySound, myPhrase, myPart;\nlet pattern = [1,0,0,2,0,2,0,0];\n\nfunction preload() {\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  text('tap to play', width/2, height/2);\n  textAlign(CENTER, CENTER);\n\n  myPhrase = new p5.Phrase('bbox', onEachStep, pattern);\n  myPart = new p5.Part();\n  myPart.addPhrase(myPhrase);\n  myPart.setBPM(60);\n}\n\nfunction onEachStep(time, playbackRate) {\n  mySound.rate(playbackRate);\n  mySound.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n  myPart.start();\n}\n</code></div>"]},"p5.Part":{"name":"p5.Part","shortname":"p5.Part","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9185,"description":"<p>A p5.Part plays back one or more p5.Phrases. Instantiate a part\nwith steps and tatums. By default, each step represents a 1/16th note.</p>\n\n<p>See p5.Phrase for more about musical timing.</p>","is_constructor":1,"params":[{"name":"steps","description":"<p>Steps in the part</p>\n","type":"Number","optional":true},{"name":"tatums","description":"<p>Divisions of a beat, e.g. use 1/4, or 0.25 for a quater note (default is 1/16, a sixteenth note)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet box, drum, myPart;\nlet boxPat = [1,0,0,2,0,2,0,0];\nlet drumPat = [0,1,1,0,2,0,1,0];\n\nfunction preload() {\n  box = loadSound('assets/beatbox.mp3');\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playMyPart);\n  background(220);\n  textAlign(CENTER, CENTER);\n  text('tap to play', width/2, height/2);\n\n  let boxPhrase = new p5.Phrase('box', playBox, boxPat);\n  let drumPhrase = new p5.Phrase('drum', playDrum, drumPat);\n  myPart = new p5.Part();\n  myPart.addPhrase(boxPhrase);\n  myPart.addPhrase(drumPhrase);\n  myPart.setBPM(60);\n}\n\nfunction playBox(time, playbackRate) {\n  box.rate(playbackRate);\n  box.play(time);\n}\n\nfunction playDrum(time, playbackRate) {\n  drum.rate(playbackRate);\n  drum.play(time);\n}\n\nfunction playMyPart() {\n  userStartAudio();\n\n  myPart.start();\n}\n</code></div>"]},"p5.Score":{"name":"p5.Score","shortname":"p5.Score","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9493,"description":"<p>A Score consists of a series of Parts. The parts will\nbe played back in order. For example, you could have an\nA part, a B part, and a C part, and play them back in this order\n<code>new p5.Score(a, a, b, a, c)</code></p>\n","is_constructor":1,"params":[{"name":"parts","description":"<p>One or multiple parts, to be played in sequence.</p>\n","type":"p5.Part","optional":true,"multiple":true}]},"p5.SoundLoop":{"name":"p5.SoundLoop","shortname":"p5.SoundLoop","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":9673,"description":"<p>SoundLoop</p>\n","is_constructor":1,"params":[{"name":"callback","description":"<p>this function will be called on each iteration of theloop</p>\n","type":"Function"},{"name":"interval","description":"<p>amount of time (if a number) or beats (if a string, following <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention) for each iteration of the loop. Defaults to 1 second.</p>\n","type":"Number|String","optional":true}],"example":["\n<div><code>\n let synth, soundLoop;\n let notePattern = [60, 62, 64, 67, 69, 72];\n\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   colorMode(HSB);\n   background(0, 0, 86);\n   text('tap to start/stop', 10, 20);\n\n   //the looper's callback is passed the timeFromNow\n   //this value should be used as a reference point from\n   //which to schedule sounds\n   let intervalInSeconds = 0.2;\n   soundLoop = new p5.SoundLoop(onSoundLoop, intervalInSeconds);\n\n   synth = new p5.MonoSynth();\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  if (soundLoop.isPlaying) {\n    soundLoop.stop();\n  } else {\n    // start the loop\n    soundLoop.start();\n  }\n}\n\nfunction onSoundLoop(timeFromNow) {\n  let noteIndex = (soundLoop.iterations - 1) % notePattern.length;\n  let note = midiToFreq(notePattern[noteIndex]);\n  synth.play(note, 0.5, timeFromNow);\n  background(noteIndex * 360 / notePattern.length, 50, 100);\n}\n</code></div>"]},"p5.Compressor":{"name":"p5.Compressor","shortname":"p5.Compressor","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10036,"description":"<p>Compressor is an audio effect class that performs dynamics compression\non an audio input source. This is a very commonly used technique in music\nand sound production. Compression creates an overall louder, richer,\nand fuller sound by lowering the volume of louds and raising that of softs.\nCompression can be used to avoid clipping (sound distortion due to\npeaks in volume) and is especially useful when many sounds are played\nat once. Compression can be used on indivudal sound sources in addition\nto the main output.</p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","is_constructor":1,"extends":"p5.Effect"},"p5.PeakDetect":{"name":"p5.PeakDetect","shortname":"p5.PeakDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10312,"description":"<p>PeakDetect works in conjunction with p5.FFT to\nlook for onsets in some or all of the frequency spectrum.\n</p>\n<p>\nTo use p5.PeakDetect, call <code>update</code> in the draw loop\nand pass in a p5.FFT object.\n</p>\n<p>\nYou can listen for a specific part of the frequency spectrum by\nsetting the range between <code>freq1</code> and <code>freq2</code>.\n</p>\n\n<p><code>threshold</code> is the threshold for detecting a peak,\nscaled between 0 and 1. It is logarithmic, so 0.1 is half as loud\nas 1.0.</p>\n\n<p>\nThe update method is meant to be run in the draw loop, and\n<b>frames</b> determines how many loops must pass before\nanother peak can be detected.\nFor example, if the frameRate() = 60, you could detect the beat of a\n120 beat-per-minute song with this equation:\n<code> framesPerPeak = 60 / (estimatedBPM / 60 );</code>\n</p>\n\n<p>\nBased on example contribtued by @b2renger, and a simple beat detection\nexplanation by <a\nhref=\"http://www.airtightinteractive.com/2013/10/making-audio-reactive-visuals/\"\ntarget=\"_blank\">Felix Turner</a>.\n</p>","is_constructor":1,"params":[{"name":"freq1","description":"<p>lowFrequency - defaults to 20Hz</p>\n","type":"Number","optional":true},{"name":"freq2","description":"<p>highFrequency - defaults to 20000 Hz</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>Threshold for detecting a beat between 0 and 1\n                          scaled logarithmically where 0.1 is 1/2 the loudness\n                          of 1.0. Defaults to 0.35.</p>\n","type":"Number","optional":true},{"name":"framesPerPeak","description":"<p>Defaults to 20.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 10;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(255);\n  textAlign(CENTER);\n\n  // p5.PeakDetect requires a p5.FFT\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n}\n\nfunction draw() {\n  background(0);\n  text('click to play/pause', width/2, height/2);\n\n  // peakDetect accepts an fft post-analysis\n  fft.analyze();\n  peakDetect.update(fft);\n\n  if ( peakDetect.isDetected ) {\n    ellipseWidth = 50;\n  } else {\n    ellipseWidth *= 0.95;\n  }\n\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// toggle play/stop when canvas is clicked\nfunction mouseClicked() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  }\n}\n</code></div>"]},"p5.SoundRecorder":{"name":"p5.SoundRecorder","shortname":"p5.SoundRecorder","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10559,"description":"<p>Record sounds for playback and/or to save as a .wav file.\nThe p5.SoundRecorder records all sound output from your sketch,\nor can be assigned a specific source with setInput().</p>\n<p>The record() method accepts a p5.SoundFile as a parameter.\nWhen playback is stopped (either after the given amount of time,\nor with the stop() method), the p5.SoundRecorder will send its\nrecording to that p5.SoundFile for playback.</p>","is_constructor":1,"example":["\n<div><code>\nlet mic, recorder, soundFile;\nlet state = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  textAlign(CENTER, CENTER);\n\n  // create an audio in\n  mic = new p5.AudioIn();\n\n  // prompts user to enable their browser mic\n  mic.start();\n\n  // create a sound recorder\n  recorder = new p5.SoundRecorder();\n\n  // connect the mic to the recorder\n  recorder.setInput(mic);\n\n  // this sound file will be used to\n  // playback & save the recording\n  soundFile = new p5.SoundFile();\n\n  text('tap to record', width/2, height/2);\n}\n\nfunction canvasPressed() {\n  // ensure audio is enabled\n  userStartAudio();\n\n  // make sure user enabled the mic\n  if (state === 0 && mic.enabled) {\n\n    // record to our p5.SoundFile\n    recorder.record(soundFile);\n\n    background(255,0,0);\n    text('Recording!', width/2, height/2);\n    state++;\n  }\n  else if (state === 1) {\n    background(0,255,0);\n\n    // stop recorder and\n    // send result to soundFile\n    recorder.stop();\n\n    text('Done! Tap to play and download', width/2, height/2, width - 20);\n    state++;\n  }\n\n  else if (state === 2) {\n    soundFile.play(); // play the result!\n    save(soundFile, 'mySound.wav');\n    state++;\n  }\n}\n</div></code>"]},"p5.Distortion":{"name":"p5.Distortion","shortname":"p5.Distortion","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10816,"description":"<p>A Distortion effect created with a Waveshaper Node,\nwith an approach adapted from\n<a href=\"http://stackoverflow.com/questions/22312841/waveshaper-node-in-webaudio-how-to-emulate-distortion\">Kevin Ennis</a></p>\n<p>This class extends <a href = \"/reference/#/p5.Effect\">p5.Effect</a>.\nMethods <a href = \"/reference/#/p5.Effect/amp\">amp()</a>, <a href = \"/reference/#/p5.Effect/chain\">chain()</a>,\n<a href = \"/reference/#/p5.Effect/drywet\">drywet()</a>, <a href = \"/reference/#/p5.Effect/connect\">connect()</a>, and\n<a href = \"/reference/#/p5.Effect/disconnect\">disconnect()</a> are available.</p>\n","extends":"p5.Effect","is_constructor":1,"params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}]},"p5.Gain":{"name":"p5.Gain","shortname":"p5.Gain","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":10973,"description":"<p>A gain node is usefull to set the relative volume of sound.\nIt's typically used to build mixers.</p>\n","is_constructor":1,"example":["\n<div><code>\n\n// load two soundfile and crossfade beetween them\nlet sound1,sound2;\nlet sound1Gain, sound2Gain, mixGain;\nfunction preload(){\n  soundFormats('ogg', 'mp3');\n  sound1 = loadSound('assets/Damscray_-_Dancing_Tiger_01');\n  sound2 = loadSound('assets/beat');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  // create a 'mix' gain bus to which we will connect both soundfiles\n  mixGain = new p5.Gain();\n  mixGain.connect();\n  sound1.disconnect(); // diconnect from p5 output\n  sound1Gain = new p5.Gain(); // setup a gain node\n  sound1Gain.setInput(sound1); // connect the first sound to its input\n  sound1Gain.connect(mixGain); // connect its output to the final mix bus\n  sound2.disconnect();\n  sound2Gain = new p5.Gain();\n  sound2Gain.setInput(sound2);\n  sound2Gain.connect(mixGain);\n}\nfunction startSound() {\n  sound1.loop();\n  sound2.loop();\n  loop();\n}\nfunction mouseReleased() {\n  sound1.stop();\n  sound2.stop();\n}\nfunction draw(){\n  background(220);\n  textAlign(CENTER);\n  textSize(11);\n  fill(0);\n  if (!sound1.isPlaying()) {\n    text('tap and drag to play', width/2, height/2);\n    return;\n  }\n  // map the horizontal position of the mouse to values useable for volume    *  control of sound1\n  var sound1Volume = constrain(map(mouseX,width,0,0,1), 0, 1);\n  var sound2Volume = 1-sound1Volume;\n  sound1Gain.amp(sound1Volume);\n  sound2Gain.amp(sound2Volume);\n  // map the vertical position of the mouse to values useable for 'output    *  volume control'\n  var outputVolume = constrain(map(mouseY,height,0,0,1), 0, 1);\n  mixGain.amp(outputVolume);\n  text('output', width/2, height - outputVolume * height * 0.9)\n  fill(255, 0, 255);\n  textAlign(LEFT);\n  text('sound1', 5, height - sound1Volume * height * 0.9);\n  textAlign(RIGHT);\n  text('sound2', width - 5, height - sound2Volume * height * 0.9);\n}\n</code></div>"]},"p5.AudioVoice":{"name":"p5.AudioVoice","shortname":"p5.AudioVoice","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11149,"description":"<p>Base class for monophonic synthesizers. Any extensions of this class\nshould follow the API and implement the methods below in order to\nremain compatible with p5.PolySynth();</p>\n","is_constructor":1},"p5.MonoSynth":{"name":"p5.MonoSynth","shortname":"p5.MonoSynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11247,"description":"<p>A MonoSynth is used as a single voice for sound synthesis.\nThis is a class to be used in conjunction with the PolySynth\nclass. Custom synthetisers should be built inheriting from\nthis class.</p>\n","is_constructor":1,"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>"]},"p5.OnsetDetect":{"name":"p5.OnsetDetect","shortname":"p5.OnsetDetect","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11624,"description":"<p>Listen for onsets (a sharp increase in volume) within a given\nfrequency range.</p>\n","is_constructor":1,"params":[{"name":"freqLow","description":"<p>Low frequency</p>\n","type":"Number"},{"name":"freqHigh","description":"<p>High frequency</p>\n","type":"Number"},{"name":"threshold","description":"<p>Amplitude threshold between 0 (no energy) and 1 (maximum)</p>\n","type":"Number"},{"name":"callback","description":"<p>Function to call when an onset is detected</p>\n","type":"Function"}]},"p5.PolySynth":{"name":"p5.PolySynth","shortname":"p5.PolySynth","classitems":[],"plugins":[],"extensions":[],"plugin_for":[],"extension_for":[],"module":"p5.sound","submodule":"p5.sound","namespace":"","file":"lib/addons/p5.sound.js","line":11691,"description":"<p>An AudioVoice is used as a single voice for sound synthesis.\nThe PolySynth class holds an array of AudioVoice, and deals\nwith voices allocations, with setting notes to be played, and\nparameters to be set.</p>\n","is_constructor":1,"params":[{"name":"synthVoice","description":"<p>A monophonic synth voice inheriting\n                               the AudioVoice class. Defaults to p5.MonoSynth</p>\n","type":"Number","optional":true},{"name":"maxVoices","description":"<p>Number of voices, defaults to 8;</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"]}},"elements":{},"classitems":[{"file":"src/accessibility/describe.js","line":18,"description":"<p>Creates a screen reader accessible description for the canvas.\nThe first parameter should be a string with a description of the canvas.\nThe second parameter is optional. If specified, it determines how the\ndescription is displayed.</p>\n<p><code class=\"language-javascript\">describe(text, LABEL)</code> displays\nthe description to all users as a <a\nhref=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describe(text, FALLBACK)</code> makes the\ndescription accessible to screen-reader users only, in\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the description will only be available to\nscreen-reader users.</p>\n","itemtype":"method","name":"describe","params":[{"name":"text","description":"<p>description of the canvas</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('pink square with red heart in the bottom right corner');\nbackground('pink');\nfill('red');\nnoStroke();\nellipse(67, 67, 20, 20);\nellipse(83, 67, 20, 20);\ntriangle(91, 73, 75, 95, 59, 73);\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  if (x > 100) {\n    x = 0;\n  }\n  background(220);\n  fill(0, 255, 0);\n  ellipse(x, 50, 40, 40);\n  x = x + 0.1;\n  describe('green circle at x pos ' + round(x) + ' moving to the right');\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/describe.js","line":114,"description":"<p>This function creates a screen-reader accessible\ndescription for elements —shapes or groups of shapes that create\nmeaning together— in the canvas. The first paramater should\nbe the name of the element. The second parameter should be a string\nwith a description of the element. The third parameter is optional.\nIf specified, it determines how the element description is displayed.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, LABEL)</code>\ndisplays the element description to all users as a\n<a href=\"https://en.wikipedia.org/wiki/Museum_label\" target=\"_blank\">\ntombstone or exhibit label/caption</a> in a div\nadjacent to the canvas. You can style it as you wish in your CSS.</p>\n<p><code class=\"language-javascript\">describeElement(name, text, FALLBACK)</code>\nmakes the element description accessible to screen-reader users\nonly, in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a>. If a second parameter is not\nspecified, by default, the element description will only be available\nto screen-reader users.</p>\n","itemtype":"method","name":"describeElement","params":[{"name":"name","description":"<p>name of the element</p>\n","type":"String"},{"name":"text","description":"<p>description of the element</p>\n","type":"String"},{"name":"display","description":"<p>either LABEL or FALLBACK</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ndescribe('Heart and yellow circle over pink background');\nnoStroke();\nbackground('pink');\ndescribeElement('Circle', 'Yellow circle in the top left corner');\nfill('yellow');\nellipse(25, 25, 40, 40);\ndescribeElement('Heart', 'red heart in the bottom right corner');\nfill('red');\nellipse(66.6, 66.6, 20, 20);\nellipse(83.2, 66.6, 20, 20);\ntriangle(91.2, 72.6, 75, 95, 58.6, 72.6);\n</code>\n</div>"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":10,"description":"<p><code class=\"language-javascript\">textOutput()</code> creates a screenreader\naccessible output that describes the shapes present on the canvas.\nThe general description of the canvas includes canvas size,\ncanvas color, and number of elements in the canvas\n(example: 'Your output is a, 400 by 400 pixels, lavender blue\ncanvas containing the following 4 shapes:'). This description\nis followed by a list of shapes where the color, position, and area\nof each shape are described (example: \"orange ellipse at top left\ncovering 1% of the canvas\"). Each element can be selected to get\nmore details. A table of elements is also provided. In this table,\nshape, color, location, coordinates and area are described\n(example: \"orange ellipse location=top left area=2\").</p>\n<p><code class=\"language-javascript\">textOutput()</code> and <code class=\"language-javascript\">textOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">textOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"textOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ntextOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  textOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/accessibility/outputs.js","line":88,"description":"<p><code class=\"language-javascript\">gridOutput()</code> lays out the\ncontent of the canvas in the form of a grid (html table) based\non the spatial location of each shape. A brief\ndescription of the canvas is available before the table output.\nThis description includes: color of the background, size of the canvas,\nnumber of objects, and object types (example: \"lavender blue canvas is\n200 by 200 and contains 4 objects - 3 ellipses 1 rectangle\"). The grid\ndescribes the content spatially, each element is placed on a cell of the\ntable depending on its position. Within each cell an element the color\nand type of shape of that element are available (example: \"orange ellipse\").\nThese descriptions can be selected individually to get more details.\nA list of elements where shape, color, location, and area are described\n(example: \"orange ellipse location=top left area=1%\") is also available.</p>\n<p><code class=\"language-javascript\">gridOutput()</code> and <code class=\"language-javascript\">gridOutput(FALLBACK)</code>\nmake the output available in <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility\" target=\"_blank\">\na sub DOM inside the canvas element</a> which is accessible to screen readers.\n<code class=\"language-javascript\">gridOutput(LABEL)</code> creates an\nadditional div with the output adjacent to the canvas, this is useful\nfor non-screen reader users that might want to display the output outside\nof the canvas' sub DOM as they code. However, using LABEL will create\nunnecessary redundancy for screen reader users. We recommend using LABEL\nonly as part of the development process of a sketch and removing it before\npublishing or sharing with screen reader users.</p>\n","itemtype":"method","name":"gridOutput","params":[{"name":"display","description":"<p>either FALLBACK or LABEL</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\ngridOutput();\nbackground(148, 196, 0);\nfill(255, 0, 0);\nellipse(20, 20, 20, 20);\nfill(0, 0, 255);\nrect(50, 50, 50, 50);\n</code>\n</div>\n\n\n<div>\n<code>\nlet x = 0;\nfunction draw() {\n  gridOutput();\n  background(148, 196, 0);\n  fill(255, 0, 0);\n  ellipse(x, 20, 20, 20);\n  fill(0, 0, 255);\n  rect(50, 50, 50, 50);\n  ellipse(20, 20, 20, 20);\n  x += 0.1;\n}\n</code>\n</div>\n"],"class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/color/color_conversion.js","line":8,"description":"<p>Conversions adapted from <a href=\"http://www.easyrgb.com/en/math.php\">http://www.easyrgb.com/en/math.php</a>.</p>\n<p>In these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":19,"description":"<p>Convert an HSBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":45,"description":"<p>Convert an HSBA array to RGBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":100,"description":"<p>Convert an HSLA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":123,"description":"<p>Convert an HSLA array to RGBA.</p>\n<p>We need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":187,"description":"<p>Convert an RGBA array to HSBA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/color_conversion.js","line":226,"description":"<p>Convert an RGBA array to HSLA.</p>\n","class":"p5","module":"Color","submodule":"Color Conversion"},{"file":"src/color/creating_reading.js","line":16,"description":"<p>Extracts the alpha value from a color or pixel array.</p>\n","itemtype":"method","name":"alpha","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the alpha value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\nlet c = color(0, 126, 255, 102);\nfill(c);\nrect(15, 15, 35, 70);\nlet value = alpha(c); // Sets 'value' to 102\nfill(value);\nrect(50, 15, 35, 70);\ndescribe('Left half of canvas light blue and right half light charcoal grey.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":43,"description":"<p>Extracts the blue value from a color or pixel array.</p>\n","itemtype":"method","name":"blue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the blue value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(175, 100, 220);\nfill(c);\nrect(15, 20, 35, 60); // Draw left rectangle\nlet blueValue = blue(c);\nfill(0, 0, blueValue);\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe('Left half of canvas light purple and right half a royal blue.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":69,"description":"<p>Extracts the HSB brightness value from a color or pixel array.</p>\n","itemtype":"method","name":"brightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the brightness value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // Sets 'value' to 255\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas salmon pink and the right half with its\nbrightness colored white.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color('hsb(60, 100%, 50%)');\nfill(c);\nrect(15, 20, 35, 60);\nlet value = brightness(c); // A 'value' of 50% is 127.5\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`Left half of canvas olive colored and the right half with its\nbrightness color gray.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":113,"description":"<p>Creates colors for storing in variables of the color datatype. The\nparameters are interpreted as RGB or HSB values depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a>. The default mode is RGB values from 0 to 255\nand, therefore, the function call color(255, 204, 0) will return a\nbright yellow color.</p>\n<p>Note that if only one value is provided to <a href=\"#/p5/color\">color()</a>, it will be interpreted\nas a grayscale value. Add a second value, and it will be used for alpha\ntransparency. When three values are specified, they are interpreted as\neither RGB or HSB values. Adding a fourth value applies alpha\ntransparency.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n","itemtype":"method","name":"color","return":{"description":"resulting color","type":"p5.Color"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nrect(30, 20, 55, 55);\ndescribe(`Yellow rect in middle right of canvas,\nwith 55 pixel width and height.`);\n</code>\n</div>\n\n<div>\n<code>\nlet c = color(255, 204, 0);\nfill(c);\nnoStroke();\nellipse(25, 25, 80, 80); // Draw left circle\n// Using only one value generates a grayscale value.\nc = color(65);\nfill(c);\nellipse(75, 75, 80, 80);\ndescribe(`Yellow ellipse in top left of canvas, black ellipse in bottom\nright, both 80×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// You can use named SVG & CSS colors\nlet c = color('magenta');\nfill(c);\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('Bright fuchsia rect in middle of canvas, 60 pixel width and height.');\n</code>\n</div>\n\n<div>\n<code>\n// Example of hex color codes\nnoStroke();\nlet c = color('#0f0');\nfill(c);\nrect(0, 10, 45, 80);\nc = color('#00ff00');\nfill(c);\nrect(55, 10, 45, 80);\ndescribe('Two bright green rects on opposite sides of the canvas, both 45×80.');\n</code>\n</div>\n\n<div>\n<code>\n// RGB and RGBA color strings are also supported\n// these all set to the same color (solid blue)\nlet c;\nnoStroke();\nc = color('rgb(0,0,255)');\nfill(c);\nrect(10, 10, 35, 35); // Draw rectangle\nc = color('rgb(0%, 0%, 100%)');\nfill(c);\nrect(55, 10, 35, 35); // Draw rectangle\nc = color('rgba(0, 0, 255, 1)');\nfill(c);\nrect(10, 55, 35, 35); // Draw rectangle\nc = color('rgba(0%, 0%, 100%, 1)');\nfill(c);\nrect(55, 55, 35, 35); // Draw rectangle\ndescribe('Four blue rects in each corner of the canvas, each are 35×35.');\n</code>\n</div>\n\n<div>\n<code>\n// HSL color can also be specified by value\nlet c = color('hsl(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsla(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Bright sea green rect on left and darker rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\n// HSB color can also be specified\nlet c = color('hsb(160, 100%, 50%)');\nnoStroke();\nfill(c);\nrect(0, 10, 45, 80); // Draw rectangle\nc = color('hsba(160, 100%, 50%, 0.5)');\nfill(c);\nrect(55, 10, 45, 80); // Draw rectangle\ndescribe(`Dark green rect on left and lighter green rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\nlet c = color(50, 55, 100);\nfill(c);\nrect(0, 10, 45, 80); // Draw left rect\ncolorMode(HSB, 100);\nc = color(50, 55, 100);\nfill(c);\nrect(55, 10, 45, 80);\ndescribe(`Dark blue rect on left and light teal rect on right of canvas,\nboth 45×80.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading","overloads":[{"line":113,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"return":{"description":"resulting color","type":"p5.Color"}},{"line":257,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"return":{"description":"","type":"p5.Color"}},{"line":269,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"return":{"description":"","type":"p5.Color"}},{"line":275,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"return":{"description":"","type":"p5.Color"}},{"line":282,"params":[{"name":"color","description":"","type":"p5.Color"}],"return":{"description":"","type":"p5.Color"}}]},{"file":"src/color/creating_reading.js","line":297,"description":"<p>Extracts the green value from a color or pixel array.</p>\n","itemtype":"method","name":"green","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the green value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(20, 75, 200); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet greenValue = green(c); // Get green in 'c'\nprint(greenValue); // Print \"75.0\"\nfill(0, greenValue, 0); // Use 'greenValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`blue rect on left and green on right, both with black outlines\n& 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":325,"description":"<p>Extracts the hue value from a color or pixel array.</p>\n<p>Hue exists in both HSB and HSL. This function will return the\nHSB-normalized hue when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL-normalized hue otherwise. (The values will only be different if the\nmaximum hue setting for each system is different.)</p>\n","itemtype":"method","name":"hue","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the hue","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = hue(c); // Sets 'value' to \"0\"\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('salmon pink rect on left and black on right, both 35×60.');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":359,"description":"<p>Blends two colors to find a third color somewhere between them. The amt\nparameter is the amount to interpolate between the two values where 0.0\nis equal to the first color, 0.1 is very near the first color, 0.5 is halfway\nin between, etc. An amount below 0 will be treated as 0. Likewise, amounts\nabove 1 will be capped at 1. This is different from the behavior of <a href=\"#/p5/lerp\">lerp()</a>,\nbut necessary because otherwise numbers outside the range will produce\nstrange and unexpected colors.</p>\n<p>The way that colors are interpolated depends on the current color mode.</p>\n","itemtype":"method","name":"lerpColor","params":[{"name":"c1","description":"<p>interpolate from this color</p>\n","type":"p5.Color"},{"name":"c2","description":"<p>interpolate to this color</p>\n","type":"p5.Color"},{"name":"amt","description":"<p>number between 0 and 1</p>\n","type":"Number"}],"return":{"description":"interpolated color","type":"p5.Color"},"example":["\n<div>\n<code>\ncolorMode(RGB);\nstroke(255);\nbackground(51);\nlet from = color(218, 165, 32);\nlet to = color(72, 61, 139);\ncolorMode(RGB); // Try changing to HSB.\nlet interA = lerpColor(from, to, 0.33);\nlet interB = lerpColor(from, to, 0.66);\nfill(from);\nrect(10, 20, 20, 60);\nfill(interA);\nrect(30, 20, 20, 60);\nfill(interB);\nrect(50, 20, 20, 60);\nfill(to);\nrect(70, 20, 20, 60);\ndescribe(`4 rects one tan, brown, brownish purple, purple, with white\noutlines & 20×60`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":449,"description":"<p>Extracts the HSL lightness value from a color or pixel array.</p>\n","itemtype":"method","name":"lightness","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the lightness","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSL);\nlet c = color(156, 100, 50, 1);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = lightness(c); // Sets 'value' to 50\nfill(value);\nrect(50, 20, 35, 60);\ndescribe(`light pastel green rect on left and dark grey rect on right,\nboth 35×60.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":478,"description":"<p>Extracts the red value from a color or pixel array.</p>\n","itemtype":"method","name":"red","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the red value","type":"Number"},"example":["\n<div>\n<code>\nlet c = color(255, 204, 0); // Define color 'c'\nfill(c); // Use color variable 'c' as fill color\nrect(15, 20, 35, 60); // Draw left rectangle\n\nlet redValue = red(c); // Get red in 'c'\nprint(redValue); // Print \"255.0\"\nfill(redValue, 0, 0); // Use 'redValue' in new fill\nrect(50, 20, 35, 60); // Draw right rectangle\ndescribe(`yellow rect on left and red rect on right, both with black\noutlines and 35×60.`);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\ncolorMode(RGB, 255); // Sets the range for red, green, and blue to 255\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1); // Sets the range for red, green, and blue to 1\nlet myColor = red(c);\nprint(myColor); // 0.4980392156862745\ndescribe('grey canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/creating_reading.js","line":517,"description":"<p>Extracts the saturation value from a color or pixel array.</p>\n<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object (or when supplied\nwith a pixel array while the color mode is HSB), but will default to the\nHSL saturation otherwise.</p>\n","itemtype":"method","name":"saturation","params":[{"name":"color","description":"<p><a href=\"#/p5.Color\">p5.Color</a> object, color components,\n                                        or CSS color</p>\n","type":"p5.Color|Number[]|String"}],"return":{"description":"the saturation value","type":"Number"},"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 255);\nlet c = color(0, 126, 255);\nfill(c);\nrect(15, 20, 35, 60);\nlet value = saturation(c); // Sets 'value' to 126\nfill(value);\nrect(50, 20, 35, 60);\ndescribe('deep pink rect on left and grey rect on right, both 35×60.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":51,"description":"<p>This function returns the color formatted as a string. This can be useful\nfor debugging, or for using p5.js with other libraries.</p>\n","itemtype":"method","name":"toString","params":[{"name":"format","description":"<p>How the color string will be formatted.\nLeaving this empty formats the string as rgba(r, g, b, a).\n'#rgb' '#rgba' '#rrggbb' and '#rrggbbaa' format as hexadecimal color codes.\n'rgb' 'hsb' and 'hsl' return the color formatted in the specified color mode.\n'rgba' 'hsba' and 'hsla' are the same as above but with alpha channels.\n'rgb%' 'hsb%' 'hsl%' 'rgba%' 'hsba%' and 'hsla%' format as percentages.</p>\n","type":"String","optional":true}],"return":{"description":"the formatted string","type":"String"},"example":["\n<div>\n<code>\ncreateCanvas(200, 100);\nlet myColor;\nstroke(255);\nmyColor = color(100, 100, 250);\nfill(myColor);\nrotate(HALF_PI);\ntext(myColor.toString(), 0, -5);\ntext(myColor.toString('#rrggbb'), 0, -30);\ntext(myColor.toString('rgba%'), 0, -55);\ndescribe('A canvas with 3 text representation of their color.');\n</code>\n</div>\n\n<div>\n<code>\nlet myColor = color(100, 130, 250);\ntext(myColor.toString('#rrggbb'), 25, 25);\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":254,"description":"<p>The setRed function sets the red component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setRed","params":[{"name":"red","description":"<p>the new red value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor;\n\nfunction setup() {\n  backgroundColor = color(100, 50, 150);\n}\n\nfunction draw() {\n  backgroundColor.setRed(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":281,"description":"<p>The setGreen function sets the green component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setGreen","params":[{"name":"green","description":"<p>the new green value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setGreen(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":304,"description":"<p>The setBlue function sets the blue component of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setBlue","params":[{"name":"blue","description":"<p>the new blue value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet backgroundColor = color(100, 50, 150);\nfunction draw() {\n  backgroundColor.setBlue(128 + 128 * sin(millis() / 1000));\n  background(backgroundColor);\n  describe('canvas with gradually changing background color');\n}\n</code>\n</div>\n"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":327,"description":"<p>The setAlpha function sets the transparency (alpha) value of a color.\nThe range depends on your color mode, in the default RGB mode it's between 0 and 255.</p>\n","itemtype":"method","name":"setAlpha","params":[{"name":"alpha","description":"<p>the new alpha value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nfunction draw() {\n  clear();\n  background(200);\n  squareColor = color(100, 50, 100);\n  squareColor.setAlpha(128 + 128 * sin(millis() / 1000));\n  fill(squareColor);\n  rect(13, 13, width - 26, height - 26);\n  describe('a square with gradually changing opacity on a gray background');\n}\n</code>\n</div>"],"class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":396,"description":"<p>Hue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":427,"description":"<p>Saturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":446,"description":"<p>CSS named colors.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":600,"description":"<p>These regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.</p>\n<p>Note that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":613,"description":"<p>Full color string patterns. The capture groups are necessary.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/p5.Color.js","line":960,"description":"<p>For HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.</p>\n","class":"p5.Color","module":"Color","submodule":"Creating & Reading"},{"file":"src/color/setting.js","line":13,"description":"<p>The <a href=\"#/p5/background\">background()</a> function sets the color used\nfor the background of the p5.js canvas. The default background is transparent.\nThis function is typically used within <a href=\"#/p5/draw\">draw()</a> to clear\nthe display window at the beginning of each frame, but it can be used inside\n<a href=\"#/p5/setup\">setup()</a> to set the background on the first frame of\nanimation or if the background need only be set once.</p>\n<p>The color is either specified in terms of the RGB, HSB, or HSL color depending\non the current <a href=\"#/p5/colorMode\">colorMode</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.<br><br></p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A <a href=\"#/p5.Color\">p5.Color</a> object can also be provided to set the background color.</p>\n<p>A <a href=\"#/p5.Image\">p5.Image</a> can also be provided to set the background image.</p>\n","itemtype":"method","name":"background","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nbackground(51);\ndescribe('canvas with darkest charcoal grey background');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nbackground(255, 204, 0);\ndescribe('canvas with yellow background');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nbackground(255, 204, 100);\ndescribe('canvas with royal blue background');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nbackground('red');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nbackground('#fae');\ndescribe('canvas with pink background');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nbackground('#222222');\ndescribe('canvas with black background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nbackground('rgb(0,255,0)');\ndescribe('canvas with bright green background');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nbackground('rgba(0,255,0, 0.25)');\ndescribe('canvas with soft green background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nbackground('rgb(100%,0%,10%)');\ndescribe('canvas with red background');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nbackground('rgba(100%,0%,100%,0.5)');\ndescribe('canvas with light purple background');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nbackground(color(0, 0, 255));\ndescribe('canvas with blue background');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":13,"params":[{"name":"color","description":"<p>any value created by the <a href=\"#/p5/color\">color()</a> function</p>\n","type":"p5.Color"}],"chainable":1},{"line":130,"params":[{"name":"colorstring","description":"<p>color string, possible formats include: integer\n                        rgb() or rgba(), percentage rgb() or rgba(),\n                        3-digit hex, 6-digit hex</p>\n","type":"String"},{"name":"a","description":"<p>opacity of the background relative to current\n                            color range (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":140,"params":[{"name":"gray","description":"<p>specifies a value between white and black</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":147,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current color\n                       mode)</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value (depending on the current\n                       color mode)</p>\n","type":"Number"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1},{"line":159,"params":[{"name":"values","description":"<p>an array containing the red, green, blue\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":166,"params":[{"name":"image","description":"<p>image created with <a href=\"#/p5/loadImage\">loadImage()</a> or <a href=\"#/p5/createImage\">createImage()</a>,\n                            to set as background\n                            (must be same size as the sketch window)</p>\n","type":"p5.Image"},{"name":"a","description":"","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":179,"description":"<p>Clears the pixels within a buffer. This function only clears the canvas.\nIt will not clear objects created by createX() methods such as\n<a href=\"#/p5/createVideo\">createVideo()</a> or <a href=\"#/p5/createDiv\">createDiv()</a>.\nUnlike the main graphics context, pixels in additional graphics areas created\nwith <a href=\"#/p5/createGraphics\">createGraphics()</a> can be entirely\nor partially transparent. This function clears everything to make all of\nthe pixels 100% transparent.</p>\n<p>Note: In WebGL mode, this function can be passed normalized RGBA color values in\norder to clear the screen to a specific color. In addition to color, it will also\nclear the depth buffer. If you are not using the webGL renderer\nthese color values will have no effect.</p>\n","itemtype":"method","name":"clear","chainable":1,"example":["\n<div>\n<code>\n// Clear the screen on mouse press.\nfunction draw() {\n  ellipse(mouseX, mouseY, 20, 20);\n  describe(`small white ellipses are continually drawn at mouse’s x and y\n  coordinates.`);\n}\nfunction mousePressed() {\n  clear();\n  background(128);\n  describe(\n    'canvas is cleared, small white ellipse is drawn at mouse X and mouse Y'\n  );\n}\n</code>\n</div>"],"params":[{"name":"r","description":"<p>normalized red val.</p>\n","type":"Number"},{"name":"g","description":"<p>normalized green val.</p>\n","type":"Number"},{"name":"b","description":"<p>normalized blue val.</p>\n","type":"Number"},{"name":"a","description":"<p>normalized alpha val.</p>\n","type":"Number"}],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":229,"description":"<p><a href=\"#/p5/colorMode\">colorMode()</a> changes the way p5.js interprets\ncolor data. By default, the parameters for <a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>, <a href=\"#/p5/background\">background()</a>,\nand <a href=\"#/p5/color\">color()</a> are defined by values between 0 and 255\nusing the RGB color model. This is equivalent to setting colorMode(RGB, 255).\nSetting colorMode(HSB) lets you use the HSB system instead. By default, this\nis colorMode(HSB, 360, 100, 100, 1). You can also use HSL.</p>\n<p>Note: existing color objects remember the mode that they were created in,\nso you can change modes as you like without affecting their appearance.</p>\n","itemtype":"method","name":"colorMode","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\ncolorMode(RGB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 0);\n    point(i, j);\n  }\n}\ndescribe(\n  'Green to red gradient from bottom left to top right with shading from top left'\n);\n</code>\n</div>\n\n<div>\n<code>\nnoStroke();\ncolorMode(HSB, 100);\nfor (let i = 0; i < 100; i++) {\n  for (let j = 0; j < 100; j++) {\n    stroke(i, j, 100);\n    point(i, j);\n  }\n}\ndescribe(`Rainbow gradient from left to right.\nBrightness increasing to white at top.`);\n</code>\n</div>\n\n<div>\n<code>\ncolorMode(RGB, 255);\nlet c = color(127, 255, 0);\ncolorMode(RGB, 1);\nlet myColor = c._getRed();\ntext(myColor, 10, 10, 80, 80);\ndescribe('value of color red 0.4980... written on canvas');\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\ncolorMode(RGB, 255, 255, 255, 1);\nbackground(255);\nstrokeWeight(4);\nstroke(255, 0, 10, 0.3);\nellipse(40, 40, 50, 50);\nellipse(50, 50, 40, 40);\ndescribe('two translucent pink ellipse outlines at middle left and at center');\n</code>\n</div>\n"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":229,"params":[{"name":"mode","description":"<p>either RGB, HSB or HSL, corresponding to\n                         Red/Green/Blue and Hue/Saturation/Brightness\n                         (or Lightness)</p>\n","type":"Constant"},{"name":"max","description":"<p>range for all values</p>\n","type":"Number","optional":true}],"chainable":1},{"line":306,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"max1","description":"<p>range for the red or hue depending on the\n                             current color mode</p>\n","type":"Number"},{"name":"max2","description":"<p>range for the green or saturation depending\n                             on the current color mode</p>\n","type":"Number"},{"name":"max3","description":"<p>range for the blue or brightness/lightness\n                             depending on the current color mode</p>\n","type":"Number"},{"name":"maxA","description":"<p>range for the alpha</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/color/setting.js","line":350,"description":"<p>Sets the color used to fill shapes. For example, if you run fill(204, 102, 0),\nall shapes drawn after the fill command will be filled with the color orange.\nThis color is either specified in terms of the RGB or HSB color depending on\nthe current <a href=\"#/p5/colorMode\">colorMode()</a>. (The default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by default\nis also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color strings\nand all named color strings are supported. In this case, an alpha number\nvalue as a second argument is not supported, the RGBA form should be used.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the fill color.</p>\n","itemtype":"method","name":"fill","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nfill(51);\nrect(20, 20, 60, 60);\ndescribe('dark charcoal grey rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nfill(255, 204, 0);\nrect(20, 20, 60, 60);\ndescribe('yellow rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nfill(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('royal blue rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nfill('red');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nfill('#fae');\nrect(20, 20, 60, 60);\ndescribe('pink rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nfill('#222222');\nrect(20, 20, 60, 60);\ndescribe('black rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nfill('rgb(0,255,0)');\nrect(20, 20, 60, 60);\ndescribe('bright green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nfill('rgba(0,255,0, 0.25)');\nrect(20, 20, 60, 60);\ndescribe('soft green rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nfill('rgb(100%,0%,10%)');\nrect(20, 20, 60, 60);\ndescribe('red rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nfill('rgba(100%,0%,100%,0.5)');\nrect(20, 20, 60, 60);\ndescribe('dark fuchsia rect with black outline in center of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nfill(color(0, 0, 255));\nrect(20, 20, 60, 60);\ndescribe('blue rect with black outline in center of canvas');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":350,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":475,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":481,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":488,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":495,"params":[{"name":"color","description":"<p>the fill color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":507,"description":"<p>Disables filling geometry. If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a> are called,\nnothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noFill","chainable":1,"example":["\n<div>\n<code>\nrect(15, 10, 55, 55);\nnoFill();\nrect(20, 20, 60, 60);\ndescribe(`White rect at top middle and noFill rect center,\nboth with black outlines.`);\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noFill();\n  stroke(100, 100, 240);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with purple cube wireframe spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":547,"description":"<p>Disables drawing the stroke (outline). If both <a href=\"#/p5/noStroke\">noStroke()</a> and <a href=\"#/p5/noFill\">noFill()</a>\nare called, nothing will be drawn to the screen.</p>\n","itemtype":"method","name":"noStroke","chainable":1,"example":["\n<div>\n<code>\nnoStroke();\nrect(20, 20, 60, 60);\ndescribe('White rect at center; no outline.');\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  noStroke();\n  fill(240, 150, 150);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(45, 45, 45);\n  describe('black canvas with pink cube spinning');\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":585,"description":"<p>Sets the color used to draw lines and borders around shapes. This color\nis either specified in terms of the RGB or HSB color depending on the\ncurrent <a href=\"#/p5/colorMode\">colorMode()</a> (the default color space\nis RGB, with each value in the range from 0 to 255). The alpha range by\ndefault is also 0 to 255.</p>\n<p>If a single string argument is provided, RGB, RGBA and Hex CSS color\nstrings and all named color strings are supported. In this case, an alpha\nnumber value as a second argument is not supported, the RGBA form should be\nused.</p>\n<p>A p5 <a href=\"#/p5.Color\">Color</a> object can also be provided to set the stroke color.</p>\n","itemtype":"method","name":"stroke","chainable":1,"example":["\n<div>\n<code>\n// Grayscale integer value\nstrokeWeight(4);\nstroke(51);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark charcoal grey outline.');\n</code>\n</div>\n\n<div>\n<code>\n// R, G & B integer values\nstroke(255, 204, 0);\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with yellow outline.');\n</code>\n</div>\n\n<div>\n<code>\n// H, S & B integer values\ncolorMode(HSB);\nstrokeWeight(4);\nstroke(255, 204, 100);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with royal blue outline.');\n</code>\n</div>\n\n<div>\n<code>\n// Named SVG/CSS color string\nstroke('red');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// three-digit hexadecimal RGB notation\nstroke('#fae');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with pink outline.');\n</code>\n</div>\n\n<div>\n<code>\n// six-digit hexadecimal RGB notation\nstroke('#222222');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with black outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGB notation\nstroke('rgb(0,255,0)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with bright green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// integer RGBA notation\nstroke('rgba(0,255,0,0.25)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with soft green outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGB notation\nstroke('rgb(100%,0%,10%)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with red outline.');\n</code>\n</div>\n\n<div>\n<code>\n// percentage RGBA notation\nstroke('rgba(100%,0%,100%,0.5)');\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with dark fuchsia outline.');\n</code>\n</div>\n\n<div>\n<code>\n// p5 Color object\nstroke(color(0, 0, 255));\nstrokeWeight(4);\nrect(20, 20, 60, 60);\ndescribe('White rect at center with blue outline.');\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting","overloads":[{"line":585,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":722,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":728,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":735,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":742,"params":[{"name":"color","description":"<p>the stroke color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/color/setting.js","line":755,"description":"<p>All drawing that follows <a href=\"#/p5/erase\">erase()</a> will subtract from\nthe canvas.Erased areas will reveal the web page underneath the canvas.Erasing\ncan be canceled with <a href=\"#/p5/noErase\">noErase()</a>.</p>\n<p>Drawing done with <a href=\"#/p5/image\">image()</a> and <a href=\"#/p5/background\">\nbackground()</a> in between <a href=\"#/p5/erase\">erase()</a> and\n<a href=\"#/p5/noErase\">noErase()</a> will not erase the canvas but works as usual.</p>\n","itemtype":"method","name":"erase","params":[{"name":"strengthFill","description":"<p>A number (0-255) for the strength of erasing for a shape's fill.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true},{"name":"strengthStroke","description":"<p>A number (0-255) for the strength of erasing for a shape's stroke.\n                                       This will default to 255 when no argument is given, which\n                                       is full strength.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbackground(100, 100, 250);\nfill(250, 100, 100);\nrect(20, 20, 60, 60);\nerase();\nellipse(25, 30, 30);\nnoErase();\ndescribe(`60×60 centered pink rect, purple background.\nElliptical area in top-left of rect is erased white.`);\n</code>\n</div>\n\n<div>\n<code>\nbackground(150, 250, 150);\nfill(100, 100, 250);\nrect(20, 20, 60, 60);\nstrokeWeight(5);\nerase(150, 255);\ntriangle(50, 10, 70, 50, 90, 10);\nnoErase();\ndescribe(`60×60 centered purple rect, mint green background.\nTriangle in top-right is partially erased with fully erased outline.`);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  smooth();\n  createCanvas(100, 100, WEBGL);\n  // Make a &lt;p&gt; element and put it behind the canvas\n  let p = createP('I am a dom element');\n  p.center();\n  p.style('font-size', '20px');\n  p.style('text-align', 'center');\n  p.style('z-index', '-9999');\n}\n\nfunction draw() {\n  background(250, 250, 150);\n  fill(15, 195, 185);\n  noStroke();\n  sphere(30);\n  erase();\n  rotateY(frameCount * 0.02);\n  translate(0, 0, 40);\n  torus(15, 5);\n  noErase();\n  describe(`60×60 centered teal sphere, yellow background.\n  Torus rotating around sphere erases to reveal black text underneath.`);\n}\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/color/setting.js","line":836,"description":"<p>Ends erasing that was started with <a href=\"#/p5/erase\">erase()</a>.\nThe <a href=\"#/p5/fill\">fill()</a>, <a href=\"#/p5/stroke\">stroke()</a>, and\n<a href=\"#/p5/blendMode\">blendMode()</a> settings will return to what they were\nprior to calling <a href=\"#/p5/erase\">erase()</a>.</p>\n","itemtype":"method","name":"noErase","chainable":1,"example":["\n<div>\n<code>\nbackground(235, 145, 15);\nnoStroke();\nfill(30, 45, 220);\nrect(30, 10, 10, 80);\nerase();\nellipse(50, 50, 60);\nnoErase();\nrect(70, 10, 10, 80);\ndescribe(`Orange background, with two tall blue rectangles.\nA centered ellipse erased the first blue rect but not the second.`);\n</code>\n</div>"],"class":"p5","module":"Color","submodule":"Setting"},{"file":"src/core/friendly_errors/fes_core.js","line":1,"requires":["core\n\nThis is the main file for the Friendly Error System (FES)","containing\nthe core as well as miscellaneous functionality of the FES. Here is a\nbrief outline of the functions called in this system.\n\nThe FES may be invoked by a call to either\n(1) _validateParameters","(2) _friendlyFileLoadError","(3) _friendlyError","(4) helpForMisusedAtTopLevelCode","or (5) _fesErrorMontitor.\n\n_validateParameters is located in validate_params.js along with other code\nused for parameter validation.\n_friendlyFileLoadError is located in file_errors.js along with other code\nused for dealing with file load errors.\nApart from this","there's also a file stacktrace.js","which contains the code\nto parse the error stack","borrowed from:\nhttps://github.com/stacktracejs/stacktrace.js\n\nFor more detailed information on the FES functions","including the call\nsequence of each function","please look at the FES Reference + Dev Notes:\nhttps://github.com/processing/p5.js/blob/main/contributor_docs/fes_reference_dev_notes.md"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/fes_core.js","line":915,"description":"<p>Prints out all the colors in the color pallete with white text.\nFor color blindness testing.</p>\n","class":"p5","module":"Color"},{"file":"src/core/friendly_errors/file_errors.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/sketch_reader.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/stacktrace.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/friendly_errors/validate_params.js","line":1,"requires":["core"],"class":"p5","module":"Color"},{"file":"src/core/shape/2d_primitives.js","line":16,"description":"<p>This function does 3 things:</p>\n<ol>\n<li><p>Bounds the desired start/stop angles for an arc (in radians) so that:</p>\n<pre><code>0 <= start < TWO_PI ;    start <= stop < start + TWO_PI</code></pre><p>This means that the arc rendering functions don't have to be concerned\nwith what happens if stop is smaller than start, or if the arc 'goes\nround more than once', etc.: they can just start at start and increase\nuntil stop and the correct arc will be drawn.</p>\n</li>\n<li><p>Optionally adjusts the angles within each quadrant to counter the naive\nscaling of the underlying ellipse up from the unit circle.  Without\nthis, the angles become arbitrary when width != height: 45 degrees\nmight be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\na 'tall' ellipse.</p>\n</li>\n<li><p>Flags up when start and stop correspond to the same place on the\nunderlying ellipse.  This is useful if you want to do something special\nthere (like rendering a whole ellipse instead).</p>\n</li>\n</ol>\n","class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":102,"description":"<p>Draw an arc to the screen. If called with only x, y, w, h, start and stop,\nthe arc will be drawn and filled as an open pie segment. If a mode parameter\nis provided, the arc will be filled like an open semi-circle (OPEN), a closed\nsemi-circle (CHORD), or as a closed pie segment (PIE). The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n<p>The arc is always drawn clockwise from wherever start falls to wherever stop\nfalls on the ellipse. Adding or subtracting TWO_PI to either angle does not\nchange where they fall. If both start and stop fall at the same place, a full\nellipse will be drawn. Be aware that the y-axis increases in the downward\ndirection, therefore angles are measured clockwise from the positive\nx-direction (\"3 o'clock\").</p>\n","itemtype":"method","name":"arc","params":[{"name":"x","description":"<p>x-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the arc's ellipse</p>\n","type":"Number"},{"name":"w","description":"<p>width of the arc's ellipse by default</p>\n","type":"Number"},{"name":"h","description":"<p>height of the arc's ellipse by default</p>\n","type":"Number"},{"name":"start","description":"<p>angle to start the arc, specified in radians</p>\n","type":"Number"},{"name":"stop","description":"<p>angle to stop the arc, specified in radians</p>\n","type":"Number"},{"name":"mode","description":"<p>optional parameter to determine the way of drawing\n                        the arc. either CHORD, PIE or OPEN</p>\n","type":"Constant","optional":true},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the arc. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\narc(50, 55, 50, 50, 0, HALF_PI);\nnoFill();\narc(50, 55, 60, 60, HALF_PI, PI);\narc(50, 55, 70, 70, PI, PI + QUARTER_PI);\narc(50, 55, 80, 80, PI + QUARTER_PI, TWO_PI);\ndescribe(\n  'shattered outline of ellipse with a quarter of a white circle bottom-right'\n);\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI);\ndescribe('white ellipse with top right quarter missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);\ndescribe('white ellipse with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, CHORD);\ndescribe('white open arc with black outline with top right missing');\n</code>\n</div>\n\n<div>\n<code>\narc(50, 50, 80, 80, 0, PI + QUARTER_PI, PIE);\ndescribe(\n  'white ellipse with top right quarter missing with black outline around the shape'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":235,"description":"<p>Draws an ellipse (oval) to the screen. By default, the first two parameters\nset the location of the center of the ellipse, and the third and fourth\nparameters set the shape's width and height. If no height is specified, the\nvalue of width is used for both the width and height. If a negative height or\nwidth is specified, the absolute value is taken.</p>\n<p>An ellipse with equal width and height is a circle. The origin may be changed\nwith the <a href=\"#/p5/ellipseMode\">ellipseMode()</a> function.</p>\n","itemtype":"method","name":"ellipse","chainable":1,"example":["\n<div>\n<code>\nellipse(56, 46, 55, 55);\ndescribe('white ellipse with black outline in middle of a gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":235,"params":[{"name":"x","description":"<p>x-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the center of ellipse.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the ellipse.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the ellipse.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":261,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detail","description":"<p>optional parameter for WebGL mode only. This is to\n                        specify the number of vertices that makes up the\n                        perimeter of the ellipse. Default value is 25. Won't\n                        draw a stroke for a detail of more than 50.</p>\n","type":"Integer","optional":true}]}]},{"file":"src/core/shape/2d_primitives.js","line":277,"description":"<p>Draws a circle to the screen. A circle is a simple closed shape. It is the set\nof all points in a plane that are at a given distance from a given point,\nthe centre. This function is a special case of the ellipse() function, where\nthe width and height of the ellipse are the same. Height and width of the\nellipse correspond to the diameter of the circle. By default, the first two\nparameters set the location of the centre of the circle, the third sets the\ndiameter of the circle.</p>\n","itemtype":"method","name":"circle","params":[{"name":"x","description":"<p>x-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the centre of the circle.</p>\n","type":"Number"},{"name":"d","description":"<p>diameter of the circle.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a circle at location (30, 30) with a diameter of 20.\ncircle(30, 30, 20);\ndescribe('white circle with black outline in mid of gray canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":340,"description":"<p>Draws a line (a direct path between two points) to the screen. If called with\nonly 4 parameters, it will draw a line in 2D with a default width of 1 pixel.\nThis width can be modified by using the <a href=\"#/p5/strokeWeight\">\nstrokeWeight()</a> function. A line cannot be filled, therefore the <a\nhref=\"#/p5/fill\">fill()</a> function will not affect the color of a line. So to\ncolor a line, use the <a href=\"#/p5/stroke\">stroke()</a> function.</p>\n","itemtype":"method","name":"line","chainable":1,"example":["\n<div>\n<code>\nline(30, 20, 85, 75);\ndescribe(\n  'a 78 pixels long line running from mid-top to bottom-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\nline(30, 20, 85, 20);\nstroke(126);\nline(85, 20, 85, 75);\nstroke(255);\nline(85, 75, 30, 75);\ndescribe(\n  '3 lines of various stroke sizes. Form top, bottom and right sides of a square'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":340,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"}],"chainable":1},{"line":379,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":404,"description":"<p>Draws a point, a coordinate in space at the dimension of one pixel.\nThe first parameter is the horizontal value for the point, the second\nparam is the vertical value for the point. The color of the point is\nchanged with the <a href=\"#/p5/stroke\">stroke()</a> function. The size of the point\ncan be changed with the <a href=\"#/p5/strokeWeight\">strokeWeight()</a> function.</p>\n","itemtype":"method","name":"point","chainable":1,"example":["\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\npoint(85, 75);\npoint(30, 75);\ndescribe('4 points create the corners of a square');\n</code>\n</div>\n\n<div>\n<code>\npoint(30, 20);\npoint(85, 20);\nstroke('purple'); // Change the color\nstrokeWeight(10); // Make the points 10 pixels in size\npoint(85, 75);\npoint(30, 75);\ndescribe('2 points and 2 large purple points in middle-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\nlet a = createVector(10, 10);\npoint(a);\nlet b = createVector(10, 20);\npoint(b);\npoint(createVector(20, 10));\npoint(createVector(20, 20));\ndescribe(\n  'four points create vertices of 10x10 pixel square on top-left of canvas'\n);\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":404,"params":[{"name":"x","description":"<p>the x-coordinate</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate</p>\n","type":"Number"},{"name":"z","description":"<p>the z-coordinate (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":455,"params":[{"name":"coordinate_vector","description":"<p>the coordinate vector</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":483,"description":"<p>Draws a quad on the canvas. A quad is a quadrilateral, a four sided polygon. It is\nsimilar to a rectangle, but the angles between its edges are not\nconstrained to ninety degrees. The first pair of parameters (x1,y1)\nsets the first vertex and the subsequent pairs should proceed\nclockwise or counter-clockwise around the defined shape.\nz-arguments only work when quad() is used in WEBGL mode.</p>\n","itemtype":"method","name":"quad","chainable":1,"example":["\n<div>\n<code>\nquad(38, 31, 86, 20, 69, 63, 30, 76);\ndescribe('irregular white quadrilateral with black outline');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":483,"params":[{"name":"x1","description":"<p>the x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>the y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>the x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>the y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>the x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>the y-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"<p>the x-coordinate of the fourth point</p>\n","type":"Number"},{"name":"y4","description":"<p>the y-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction</p>\n","type":"Integer","optional":true}],"chainable":1},{"line":512,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>the z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>the z-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>the z-coordinate of the third point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>the z-coordinate of the fourth point</p>\n","type":"Number"},{"name":"detailX","description":"","type":"Integer","optional":true},{"name":"detailY","description":"","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":556,"description":"<p>Draws a rectangle on the canvas. A rectangle is a four-sided closed shape with\nevery angle at ninety degrees. By default, the first two parameters set\nthe location of the upper-left corner, the third sets the width, and the\nfourth sets the height. The way these parameters are interpreted, may be\nchanged with the <a href=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fifth, sixth, seventh and eighth parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"rect","chainable":1,"example":["\n<div>\n<code>\n// Draw a rectangle at location (30, 20) with a width and height of 55.\nrect(30, 20, 55, 55);\ndescribe('white rect with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners, each having a radius of 20.\nrect(30, 20, 55, 55, 20);\ndescribe(\n  'white rect with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a rectangle with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nrect(30, 20, 55, 55, 20, 15, 10, 5);\ndescribe('white rect with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives","overloads":[{"line":556,"params":[{"name":"x","description":"<p>x-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the rectangle.</p>\n","type":"Number"},{"name":"w","description":"<p>width of the rectangle.</p>\n","type":"Number"},{"name":"h","description":"<p>height of the rectangle.</p>\n","type":"Number","optional":true},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1},{"line":608,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"w","description":"","type":"Number"},{"name":"h","description":"","type":"Number"},{"name":"detailX","description":"<p>number of segments in the x-direction (for WebGL mode)</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in the y-direction (for WebGL mode)</p>\n","type":"Integer","optional":true}],"chainable":1}]},{"file":"src/core/shape/2d_primitives.js","line":623,"description":"<p>Draws a square to the screen. A square is a four-sided shape with every angle\nat ninety degrees, and equal side size. This function is a special case of the\nrect() function, where the width and height are the same, and the parameter\nis called \"s\" for side size. By default, the first two parameters set the\nlocation of the upper-left corner, the third sets the side size of the square.\nThe way these parameters are interpreted, may be changed with the <a\nhref=\"#/p5/rectMode\">rectMode()</a> function.</p>\n<p>The fourth, fifth, sixth and seventh parameters, if specified,\ndetermine corner radius for the top-left, top-right, lower-right and\nlower-left corners, respectively. An omitted corner radius parameter is set\nto the value of the previously specified radius value in the parameter list.</p>\n","itemtype":"method","name":"square","params":[{"name":"x","description":"<p>x-coordinate of the square.</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the square.</p>\n","type":"Number"},{"name":"s","description":"<p>side size of the square.</p>\n","type":"Number"},{"name":"tl","description":"<p>optional radius of top-left corner.</p>\n","type":"Number","optional":true},{"name":"tr","description":"<p>optional radius of top-right corner.</p>\n","type":"Number","optional":true},{"name":"br","description":"<p>optional radius of bottom-right corner.</p>\n","type":"Number","optional":true},{"name":"bl","description":"<p>optional radius of bottom-left corner.</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// Draw a square at location (30, 20) with a side size of 55.\nsquare(30, 20, 55);\ndescribe('white square with black outline in mid-right of canvas');\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners, each having a radius of 20.\nsquare(30, 20, 55, 20);\ndescribe(\n  'white square with black outline and round edges in mid-right of canvas'\n);\n</code>\n</div>\n\n<div>\n<code>\n// Draw a square with rounded corners having the following radii:\n// top-left = 20, top-right = 15, bottom-right = 10, bottom-left = 5.\nsquare(30, 20, 55, 20, 15, 10, 5);\ndescribe('white square with black outline and round edges of different radii');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/2d_primitives.js","line":713,"description":"<p>Draws a triangle to the canvas. A triangle is a plane created by connecting\nthree points. The first two arguments specify the first point, the middle two\narguments specify the second point, and the last two arguments specify the\nthird point.</p>\n","itemtype":"method","name":"triangle","params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate of the third point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate of the third point</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntriangle(30, 75, 58, 20, 86, 75);\ndescribe('white triangle with black outline in mid-right of canvas');\n</code>\n</div>\n"],"class":"p5","module":"Shape","submodule":"2D Primitives"},{"file":"src/core/shape/attributes.js","line":12,"description":"<p>Modifies the location from which ellipses are drawn by changing the way in\nwhich parameters given to <a href=\"#/p5/ellipse\">ellipse()</a>,\n<a href=\"#/p5/circle\">circle()</a> and <a href=\"#/p5/arc\">arc()</a> are interpreted.</p>\n<p>The default mode is CENTER, in which the first two parameters are interpreted\nas the shape's center point's x and y coordinates respectively, while the third\nand fourth parameters are its width and height.</p>\n<p>ellipseMode(RADIUS) also uses the first two parameters as the shape's center\npoint's x and y coordinates, but uses the third and fourth parameters to\nspecify half of the shapes's width and height.</p>\n<p>ellipseMode(CORNER) interprets the first two parameters as the upper-left\ncorner of the shape, while the third and fourth parameters are its width\nand height.</p>\n<p>ellipseMode(CORNERS) interprets the first two parameters as the location of\none corner of the ellipse's bounding box, and the third and fourth parameters\nas the location of the opposite corner.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"ellipseMode","params":[{"name":"mode","description":"<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example showing RADIUS and CENTER ellipsemode with 2 overlaying ellipses\nellipseMode(RADIUS);\nfill(255);\nellipse(50, 50, 30, 30); // Outer white ellipse\nellipseMode(CENTER);\nfill(100);\nellipse(50, 50, 30, 30); // Inner gray ellipse\n</code>\n</div>\n\n<div>\n<code>\n// Example showing CORNER and CORNERS ellipseMode with 2 overlaying ellipses\nellipseMode(CORNER);\nfill(255);\nellipse(25, 25, 50, 50); // Outer white ellipse\nellipseMode(CORNERS);\nfill(100);\nellipse(25, 25, 50, 50); // Inner gray ellipse\n</code>\n</div>"],"alt":"60×60 white ellipse and 30×30 grey ellipse with black outlines at center.\n60×60 white ellipse and 30×30 grey ellipse top-right with black outlines.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":81,"description":"<p>Draws all geometry with jagged (aliased) edges. Note that <a href=\"#/p5/smooth\">smooth()</a> is\nactive by default in 2D mode, so it is necessary to call <a href=\"#/p5/noSmooth\">noSmooth()</a> to disable\nsmoothing of geometry, images, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"noSmooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses to left & right of center, black background","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":115,"description":"<p>Modifies the location from which rectangles are drawn by changing the way\nin which parameters given to <a href=\"#/p5/rect\">rect()</a> are interpreted.</p>\n<p>The default mode is CORNER, which interprets the first two parameters as the\nupper-left corner of the shape, while the third and fourth parameters are its\nwidth and height.</p>\n<p>rectMode(CORNERS) interprets the first two parameters as the location of\none of the corners, and the third and fourth parameters as the location of\nthe diagonally opposite corner. Note, the rectangle is drawn between the\ncoordinates, so it is not neccesary that the first corner be the upper left\ncorner.</p>\n<p>rectMode(CENTER) interprets the first two parameters as the shape's center\npoint, while the third and fourth parameters are its width and height.</p>\n<p>rectMode(RADIUS) also uses the first two parameters as the shape's center\npoint, but uses the third and fourth parameters to specify half of the shape's\nwidth and height respectively.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"rectMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\nrectMode(CORNER);\nfill(255);\nrect(25, 25, 50, 50); // Draw white rectangle using CORNER mode\n\nrectMode(CORNERS);\nfill(100);\nrect(25, 25, 50, 50); // Draw gray rectangle using CORNERS mode\n</code>\n</div>\n\n<div>\n<code>\nrectMode(RADIUS);\nfill(255);\nrect(50, 50, 30, 30); // Draw white rectangle using RADIUS mode\n\nrectMode(CENTER);\nfill(100);\nrect(50, 50, 30, 30); // Draw gray rectangle using CENTER mode\n</code>\n</div>"],"alt":"50×50 white rect at center and 25×25 grey rect in the top left of the other.\n50×50 white rect at center and 25×25 grey rect in the center of the other.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":184,"description":"<p>Draws all geometry with smooth (anti-aliased) edges. <a href=\"#/p5/smooth\">smooth()</a> will also\nimprove image quality of resized images. Note that <a href=\"#/p5/smooth\">smooth()</a> is active by\ndefault in 2D mode; <a href=\"#/p5/noSmooth\">noSmooth()</a> can be used to disable smoothing of geometry,\nimages, and fonts. In 3D mode, <a href=\"#/p5/noSmooth\">noSmooth()</a> is enabled\nby default, so it is necessary to call <a href=\"#/p5/smooth\">smooth()</a> if you would like\nsmooth (antialiased) edges on your geometry.</p>\n","itemtype":"method","name":"smooth","chainable":1,"example":["\n<div>\n<code>\nbackground(0);\nnoStroke();\nsmooth();\nellipse(30, 48, 36, 36);\nnoSmooth();\nellipse(70, 48, 36, 36);\n</code>\n</div>"],"alt":"2 pixelated 36×36 white ellipses one left one right of center. On black.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":219,"description":"<p>Sets the style for rendering line endings. These ends are either rounded,\nsquared or extended, each of which specified with the corresponding\nparameters: ROUND, SQUARE and PROJECT. The default cap is ROUND.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeCap","params":[{"name":"cap","description":"<p>either ROUND, SQUARE or PROJECT</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different strokeCaps\nstrokeWeight(12.0);\nstrokeCap(ROUND);\nline(20, 30, 80, 30);\nstrokeCap(SQUARE);\nline(20, 50, 80, 50);\nstrokeCap(PROJECT);\nline(20, 70, 80, 70);\n</code>\n</div>"],"alt":"3 lines. Top line: rounded ends, mid: squared, bottom:longer squared ends.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":259,"description":"<p>Sets the style of the joints which connect line segments. These joints\nare either mitered, beveled or rounded and specified with the\ncorresponding parameters MITER, BEVEL and ROUND. The default joint is\nMITER.</p>\n<p>The parameter to this method must be written in ALL CAPS because they are\npredefined as constants in ALL CAPS and Javascript is a case-sensitive language.</p>\n","itemtype":"method","name":"strokeJoin","params":[{"name":"join","description":"<p>either MITER, BEVEL, ROUND</p>\n","type":"Constant"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of MITER type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(MITER);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of BEVEL type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(BEVEL);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Example of ROUND type of joints\nnoFill();\nstrokeWeight(10.0);\nstrokeJoin(ROUND);\nbeginShape();\nvertex(35, 20);\nvertex(65, 50);\nvertex(35, 80);\nendShape();\n</code>\n</div>"],"alt":"Right-facing arrowhead shape with pointed tip in center of canvas.\nRight-facing arrowhead shape with flat tip in center of canvas.\nRight-facing arrowhead shape with rounded tip in center of canvas.","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/attributes.js","line":331,"description":"<p>Sets the width of the stroke used for lines, points and the border around\nshapes. All widths are set in units of pixels.</p>\n<p>Note that it is affected by any transformation or scaling that has\nbeen applied previously.</p>\n","itemtype":"method","name":"strokeWeight","params":[{"name":"weight","description":"<p>the weight of the stroke (in pixels)</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Example of different stroke weights\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nstrokeWeight(4); // Thicker\nline(20, 40, 80, 40);\nstrokeWeight(10); // Beastly\nline(20, 70, 80, 70);\n</code>\n</div>\n\n<div>\n<code>\n//Example of stroke weights\n//after transformations\nstrokeWeight(1); // Default\nline(20, 20, 80, 20);\nscale(5); // Adding scale transformation\nstrokeWeight(1); // Resulting strokeweight is 5\nline(4, 8, 16, 8); // Coordinates adjusted for scaling\n</code>\n</div>"],"alt":"3 horizontal black lines. Top line: thin, mid: medium, bottom:thick.\n2 horizontal black line. Top line: thin, botton line: 5 times thicker than top","class":"p5","module":"Shape","submodule":"Attributes"},{"file":"src/core/shape/curves.js","line":13,"description":"<p>Draws a cubic Bezier curve on the screen. These curves are defined by a\nseries of anchor and control points. The first two parameters specify\nthe first anchor point and the last two parameters specify the other\nanchor point, which become the first and last points on the curve. The\nmiddle parameters specify the two control points which define the shape\nof the curve. Approximately speaking, control points \"pull\" the curve\ntowards them.</p>\n<p>Bezier curves were developed by French automotive engineer Pierre Bezier,\nand are commonly used in computer graphics to define gently sloping curves.\nSee also <a href=\"#/p5/curve\">curve()</a>.</p>\n","itemtype":"method","name":"bezier","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\nline(85, 20, 10, 10);\nline(90, 90, 15, 80);\nstroke(0, 0, 0);\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\n</code>\n</div>\n\n<div>\n<code>\nbackground(0, 0, 0);\nnoFill();\nstroke(255);\nbezier(250, 250, 0, 100, 100, 0, 100, 0, 0, 0, 100, 0);\n</code>\n</div>"],"alt":"stretched black s-shape in center with orange lines extending from end points.\na white colored curve on black background from the upper-right corner to the lower right corner.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":13,"params":[{"name":"x1","description":"<p>x-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the second anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1},{"line":62,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the first anchor point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the second anchor point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":92,"description":"<p>Sets the resolution at which Bezier's curve is displayed. The default value is 20.</p>\n<p>Note, This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this information.</p>\n","itemtype":"method","name":"bezierDetail","params":[{"name":"detail","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n  bezierDetail(5);\n}\n\nfunction draw() {\n  background(200);\n  bezier(-40, -40, 0,\n          90, -40, 0,\n         -90,  40, 0,\n          40,  40, 0);\n}\n</code>\n</div>"],"alt":"stretched black s-shape with a low level of bezier detail","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":130,"description":"<p>Given the x or y co-ordinate values of control and anchor points of a bezier\ncurve, it evaluates the x or y coordinate of the bezier at position t. The\nparameters a and d are the x or y coordinates of first and last points on the\ncurve while b and c are of the control points.The final parameter t is the\nposition of the resultant point which is given between 0 and 1.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a bezier curve at t.</p>\n","itemtype":"method","name":"bezierPoint","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the value of the Bezier at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nlet x1 = 85,\n x2 = 10,\n x3 = 90,\n x4 = 15;\nlet y1 = 20,\n y2 = 10,\n y3 = 90,\n y4 = 80;\nbezier(x1, y1, x2, y2, x3, y3, x4, y4);\nfill(255);\nlet steps = 10;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(x1, x2, x3, x4, t);\n  let y = bezierPoint(y1, y2, y3, y4, t);\n  circle(x, y, 5);\n}\n</code>\n</div>"],"alt":"10 points plotted on a given bezier at equal distances.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":185,"description":"<p>Evaluates the tangent to the Bezier at position t for points a, b, c, d.\nThe parameters a and d are the first and last points\non the curve, and b and c are the control points.\nThe final parameter t varies between 0 and 1.</p>\n","itemtype":"method","name":"bezierTangent","params":[{"name":"a","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nlet steps = 6;\nfill(255);\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  // Get the location of the point\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  // Get the tangent points\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  // Calculate an angle from the tangent points\n  let a = atan2(ty, tx);\n  a += PI;\n  stroke(255, 102, 0);\n  line(x, y, cos(a) * 30 + x, sin(a) * 30 + y);\n  // The following line of code makes a line\n  // inverse of the above line\n  //line(x, y, cos(a)*-30 + x, sin(a)*-30 + y);\n  stroke(0);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbezier(85, 20, 10, 10, 90, 90, 15, 80);\nstroke(255, 102, 0);\nlet steps = 16;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = bezierPoint(85, 10, 90, 15, t);\n  let y = bezierPoint(20, 10, 90, 80, t);\n  let tx = bezierTangent(85, 10, 90, 15, t);\n  let ty = bezierTangent(20, 10, 90, 80, t);\n  let a = atan2(ty, tx);\n  a -= HALF_PI;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"s-shaped line with 6 short orange lines showing the tangents at those points.\ns-shaped line with 6 short orange lines showing lines coming out the underside of the bezier.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":264,"description":"<p>Draws a curved line on the screen between two points, given as the\nmiddle four parameters. The first two parameters are a control point, as\nif the curve came from this point even though it's not drawn. The last\ntwo parameters similarly describe the other control point. <br /><br />\nLonger curves can be created by putting a series of <a href=\"#/p5/curve\">curve()</a> functions\ntogether or using <a href=\"#/p5/curveVertex\">curveVertex()</a>. An additional function called\n<a href=\"#/p5/curveTightness\">curveTightness()</a> provides control for the visual quality of the curve.\nThe <a href=\"#/p5/curve\">curve()</a> function is an implementation of Catmull-Rom splines.</p>\n","itemtype":"method","name":"curve","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\nstroke(0);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nstroke(255, 102, 0);\ncurve(73, 24, 73, 61, 15, 65, 15, 65);\n</code>\n</div>\n\n<div>\n<code>\n// Define the curve points as JavaScript objects\nlet p1 = { x: 5, y: 26 };\nlet p2 = { x: 73, y: 24 };\nlet p3 = { x: 73, y: 61 };\nlet p4 = { x: 15, y: 65 };\nnoFill();\nstroke(255, 102, 0);\ncurve(p1.x, p1.y, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);\nstroke(0);\ncurve(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\nstroke(255, 102, 0);\ncurve(p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, p4.x, p4.y);\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nstroke(255, 102, 0);\ncurve(5, 26, 0, 5, 26, 0, 73, 24, 0, 73, 61, 0);\nstroke(0);\ncurve(5, 26, 0, 73, 24, 0, 73, 61, 0, 15, 65, 0);\nstroke(255, 102, 0);\ncurve(73, 24, 0, 73, 61, 0, 15, 65, 0, 15, 65, 0);\n</code>\n</div>"],"alt":"horseshoe shape with orange ends facing left and black curved center.\nhorseshoe shape with orange ends facing left and black curved center.\ncurving black and orange lines.","class":"p5","module":"Shape","submodule":"Curves","overloads":[{"line":264,"params":[{"name":"x1","description":"<p>x-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate for the first point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the ending control point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1},{"line":332,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate for the beginning control point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first point</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second point</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the ending control point</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/curves.js","line":358,"description":"<p>Sets the resolution at which curves display. The default value is 20 while\nthe minimum value is 3.</p>\n<p>This function is only useful when using the WEBGL renderer\nas the default canvas renderer does not use this\ninformation.</p>\n","itemtype":"method","name":"curveDetail","params":[{"name":"resolution","description":"<p>resolution of the curves</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  curveDetail(5);\n}\nfunction draw() {\n  background(200);\n\n  curve(250, 600, 0, -30, 40, 0, 30, 30, 0, -250, 600, 0);\n}\n</code>\n</div>"],"alt":"white arch shape with a low level of curve detail.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":398,"description":"<p>Modifies the quality of forms created with <a href=\"#/p5/curve\">curve()</a>\nand <a href=\"#/p5/curveVertex\">curveVertex()</a>.The parameter tightness\ndetermines how the curve fits to the vertex points. The value 0.0 is the\ndefault value for tightness (this value defines the curves to be Catmull-Rom\nsplines) and the value 1.0 connects all the points with straight lines.\nValues within the range -5.0 and 5.0 will deform the curves but will leave\nthem recognizable and as values increase in magnitude, they will continue to deform.</p>\n","itemtype":"method","name":"curveTightness","params":[{"name":"amount","description":"<p>amount of deformation from the original vertices</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\n// Move the mouse left and right to see the curve change\nfunction setup() {\n  createCanvas(100, 100);\n  noFill();\n}\n\nfunction draw() {\n  background(204);\n  let t = map(mouseX, 0, width, -5, 5);\n  curveTightness(t);\n  beginShape();\n  curveVertex(10, 26);\n  curveVertex(10, 26);\n  curveVertex(83, 24);\n  curveVertex(83, 61);\n  curveVertex(25, 65);\n  curveVertex(25, 65);\n  endShape();\n}\n</code>\n</div>"],"alt":"Line shaped like right-facing arrow,points move with mouse-x and warp shape.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":444,"description":"<p>Evaluates the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are control points\nof the curve, and b and c are the start and end points of the curve.\nThis can be done once with the x coordinates and a second time\nwith the y coordinates to get the location of a curve at t.</p>\n","itemtype":"method","name":"curvePoint","params":[{"name":"a","description":"<p>coordinate of first control point of the curve</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second control point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"bezier value at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 5, 26, 73, 24, 73, 61);\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nfill(255);\nellipseMode(CENTER);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 5, 73, 73, t);\n  let y = curvePoint(26, 26, 24, 61, t);\n  ellipse(x, y, 5, 5);\n  x = curvePoint(5, 73, 73, 15, t);\n  y = curvePoint(26, 24, 61, 65, t);\n  ellipse(x, y, 5, 5);\n}\n</code>\n</div>\n\nline hooking down to right-bottom with 13 5×5 white ellipse points"],"class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/curves.js","line":493,"description":"<p>Evaluates the tangent to the curve at position t for points a, b, c, d.\nThe parameter t varies between 0 and 1, a and d are points on the curve,\nand b and c are the control points.</p>\n","itemtype":"method","name":"curveTangent","params":[{"name":"a","description":"<p>coordinate of first control point</p>\n","type":"Number"},{"name":"b","description":"<p>coordinate of first point on the curve</p>\n","type":"Number"},{"name":"c","description":"<p>coordinate of second point on the curve</p>\n","type":"Number"},{"name":"d","description":"<p>coordinate of second conrol point</p>\n","type":"Number"},{"name":"t","description":"<p>value between 0 and 1</p>\n","type":"Number"}],"return":{"description":"the tangent at position t","type":"Number"},"example":["\n<div>\n<code>\nnoFill();\ncurve(5, 26, 73, 24, 73, 61, 15, 65);\nlet steps = 6;\nfor (let i = 0; i <= steps; i++) {\n  let t = i / steps;\n  let x = curvePoint(5, 73, 73, 15, t);\n  let y = curvePoint(26, 24, 61, 65, t);\n  //ellipse(x, y, 5, 5);\n  let tx = curveTangent(5, 73, 73, 15, t);\n  let ty = curveTangent(26, 24, 61, 65, t);\n  let a = atan2(ty, tx);\n  a -= PI / 2.0;\n  line(x, y, cos(a) * 8 + x, sin(a) * 8 + y);\n}\n</code>\n</div>"],"alt":"right curving line mid-right of canvas with 7 short lines radiating from it.","class":"p5","module":"Shape","submodule":"Curves"},{"file":"src/core/shape/vertex.js","line":20,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and\n<a href=\"#/p5/endContour\">endContour()</a> functions to create negative shapes\nwithin shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite direction\nfrom the exterior shape. First draw vertices for the exterior clockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"beginContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":67,"description":"<p>Using the <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> functions allow creating more\ncomplex forms. <a href=\"#/p5/beginShape\">beginShape()</a> begins recording vertices for a shape and\n<a href=\"#/p5/endShape\">endShape()</a> stops recording. The value of the kind parameter tells it which\ntypes of shapes to create from the provided vertices. With no mode\nspecified, the shape can be any irregular polygon.</p>\n<p>The parameters available for <a href=\"#/p5/beginShape\">beginShape()</a> are:</p>\n<p>POINTS\nDraw a series of points</p>\n<p>LINES\nDraw a series of unconnected line segments (individual lines)</p>\n<p>TRIANGLES\nDraw a series of separate triangles</p>\n<p>TRIANGLE_FAN\nDraw a series of connected triangles sharing the first vertex in a fan-like fashion</p>\n<p>TRIANGLE_STRIP\nDraw a series of connected triangles in strip fashion</p>\n<p>QUADS\nDraw a series of separate quad</p>\n<p>QUAD_STRIP\nDraw quad strip using adjacent edges to form the next quad</p>\n<p>TESS (WebGl only)\nHandle irregular polygon for filling curve by explicit tessellation</p>\n<p>After calling the <a href=\"#/p5/beginShape\">beginShape()</a> function, a series of <a href=\"#/p5/vertex\">vertex()</a> commands must follow. To stop\ndrawing the shape, call <a href=\"#/p5/endShape\">endShape()</a>. Each shape will be outlined with the\ncurrent stroke color and filled with the fill color.</p>\n<p>Transformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin <a href=\"#/p5/beginShape\">beginShape()</a>. It is also not possible to use other shapes, such as\n<a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within <a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"beginShape","params":[{"name":"kind","description":"<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n                               TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(LINES);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape(CLOSE);\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLES);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_STRIP);\nvertex(30, 75);\nvertex(40, 20);\nvertex(50, 75);\nvertex(60, 20);\nvertex(70, 75);\nvertex(80, 20);\nvertex(90, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TRIANGLE_FAN);\nvertex(57.5, 50);\nvertex(57.5, 15);\nvertex(92, 50);\nvertex(57.5, 85);\nvertex(22, 50);\nvertex(57.5, 15);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUADS);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 75);\nvertex(50, 20);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 75);\nvertex(85, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(QUAD_STRIP);\nvertex(30, 20);\nvertex(30, 75);\nvertex(50, 20);\nvertex(50, 75);\nvertex(65, 20);\nvertex(65, 75);\nvertex(85, 20);\nvertex(85, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape(TESS);\nvertex(20, 20);\nvertex(80, 20);\nvertex(80, 40);\nvertex(40, 40);\nvertex(40, 60);\nvertex(80, 60);\nvertex(80, 80);\nvertex(20, 80);\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white square-shape with black outline in middle-right of canvas.\n4 black points in a square shape in middle-right of canvas.\n2 horizontal black lines. In the top-right and bottom-right of canvas.\n3 line shape with horizontal on top, vertical in middle and horizontal bottom.\nsquare line shape in middle-right of canvas.\n2 white triangle shapes mid-right canvas. left one pointing up and right down.\n5 horizontal interlocking and alternating white triangles in mid-right canvas.\n4 interlocking white triangles in 45 degree rotated square-shape.\n2 white rectangle shapes in mid-right canvas. Both 20×55.\n3 side-by-side white rectangles center rect is smaller in mid-right canvas.\nThick white l-shape with black outline mid-top-left of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":293,"description":"<p>Specifies vertex coordinates for Bezier curves. Each call to\nbezierVertex() defines the position of two control points and\none anchor point of a Bezier curve, adding a new segment to a\nline or shape. For WebGL mode bezierVertex() can be used in 2D\nas well as 3D mode. 2D mode expects 6 parameters, while 3D mode\nexpects 9 parameters (including z coordinates).</p>\n<p>The first time bezierVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a>\ncall, it must be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor\npoint. This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"bezierVertex","chainable":1,"example":["\n<div>\n<code>\nnoFill();\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nbeginShape();\nvertex(30, 20);\nbezierVertex(80, 0, 80, 75, 30, 75);\nbezierVertex(50, 80, 60, 25, 30, 20);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n}\nfunction draw() {\n  orbitControl();\n  background(50);\n  strokeWeight(4);\n  stroke(255);\n  point(-25, 30);\n  point(25, 30);\n  point(25, -30);\n  point(-25, -30);\n\n  strokeWeight(1);\n  noFill();\n\n  beginShape();\n  vertex(-25, 30);\n  bezierVertex(25, 30, 25, -30, -25, -30);\n  endShape();\n\n  beginShape();\n  vertex(-25, 30, 20);\n  bezierVertex(25, 30, 20, 25, -30, 20, -25, -30, 20);\n  endShape();\n}\n</code>\n</div>"],"alt":"crescent-shaped line in middle of canvas. Points facing left.\nwhite crescent shape in middle of canvas. Points facing left.\ncrescent shape in middle of canvas with another crescent shape on positive z-axis.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":293,"params":[{"name":"x2","description":"<p>x-coordinate for the first control point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate for the first control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the second control point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the second control point</p>\n","type":"Number"},{"name":"x4","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y4","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":375,"params":[{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate for the first control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the second control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x4","description":"","type":"Number"},{"name":"y4","description":"","type":"Number"},{"name":"z4","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":415,"description":"<p>Specifies vertex coordinates for curves. This function may only\nbe used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a> and only when there\nis no MODE parameter specified to <a href=\"#/p5/beginShape\">beginShape()</a>.\nFor WebGL mode curveVertex() can be used in 2D as well as 3D mode.\n2D mode expects 2 parameters, while 3D mode expects 3 parameters.</p>\n<p>The first and last points in a series of curveVertex() lines will be used to\nguide the beginning and end of the curve. A minimum of four\npoints is required to draw a tiny curve between the second and\nthird points. Adding a fifth point with curveVertex() will draw\nthe curve between the second, third, and fourth points. The\ncurveVertex() function is an implementation of Catmull-Rom\nsplines.</p>\n","itemtype":"method","name":"curveVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(84, 91);\npoint(68, 19);\npoint(21, 17);\npoint(32, 91);\nstrokeWeight(1);\n\nnoFill();\nbeginShape();\ncurveVertex(84, 91);\ncurveVertex(84, 91);\ncurveVertex(68, 19);\ncurveVertex(21, 17);\ncurveVertex(32, 91);\ncurveVertex(32, 91);\nendShape();\n</code>\n</div>"],"alt":"Upside-down u-shape line, mid canvas. left point extends beyond canvas view.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":415,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":460,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex (for WebGL mode)</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":524,"description":"<p>Use the <a href=\"#/p5/beginContour\">beginContour()</a> and <a href=\"#/p5/endContour\">endContour()</a> functions to create negative\nshapes within shapes such as the center of the letter 'O'. <a href=\"#/p5/beginContour\">beginContour()</a>\nbegins recording vertices for the shape and <a href=\"#/p5/endContour\">endContour()</a> stops recording.\nThe vertices that define a negative shape must \"wind\" in the opposite\ndirection from the exterior shape. First draw vertices for the exterior\nclockwise order, then for internal shapes, draw vertices\nshape in counter-clockwise.</p>\n<p>These functions can only be used within a <a href=\"#/p5/beginShape\">beginShape()</a>/<a href=\"#/p5/endShape\">endShape()</a> pair and\ntransformations such as <a href=\"#/p5/translate\">translate()</a>, <a href=\"#/p5/rotate\">rotate()</a>, and <a href=\"#/p5/scale\">scale()</a> do not work\nwithin a <a href=\"#/p5/beginContour\">beginContour()</a>/<a href=\"#/p5/endContour\">endContour()</a> pair. It is also not possible to use\nother shapes, such as <a href=\"#/p5/ellipse\">ellipse()</a> or <a href=\"#/p5/rect\">rect()</a> within.</p>\n","itemtype":"method","name":"endContour","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\nstroke(255, 0, 0);\nbeginShape();\n// Exterior part of shape, clockwise winding\nvertex(-40, -40);\nvertex(40, -40);\nvertex(40, 40);\nvertex(-40, 40);\n// Interior part of shape, counter-clockwise winding\nbeginContour();\nvertex(-20, -20);\nvertex(-20, 20);\nvertex(20, 20);\nvertex(20, -20);\nendContour();\nendShape(CLOSE);\n</code>\n</div>"],"alt":"white rect and smaller grey rect with red outlines in center of canvas.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":583,"description":"<p>The <a href=\"#/p5/endShape\">endShape()</a> function is the companion to <a href=\"#/p5/beginShape\">beginShape()</a> and may only be\ncalled after <a href=\"#/p5/beginShape\">beginShape()</a>. When <a href=\"#/p5/endshape\">endShape()</a> is called, all of image data\ndefined since the previous call to <a href=\"#/p5/beginShape\">beginShape()</a> is written into the image\nbuffer. The constant CLOSE as the value for the MODE parameter to close\nthe shape (to connect the beginning and the end).</p>\n","itemtype":"method","name":"endShape","params":[{"name":"mode","description":"<p>use CLOSE to close the shape</p>\n","type":"Constant","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nnoFill();\n\nbeginShape();\nvertex(20, 20);\nvertex(45, 20);\nvertex(45, 80);\nendShape(CLOSE);\n\nbeginShape();\nvertex(50, 20);\nvertex(75, 20);\nvertex(75, 80);\nendShape();\n</code>\n</div>"],"alt":"Triangle line shape with smallest interior angle on bottom and upside-down L.","class":"p5","module":"Shape","submodule":"Vertex"},{"file":"src/core/shape/vertex.js","line":668,"description":"<p>Specifies vertex coordinates for quadratic Bezier curves. Each call to\nquadraticVertex() defines the position of one control points and one\nanchor point of a Bezier curve, adding a new segment to a line or shape.\nThe first time quadraticVertex() is used within a <a href=\"#/p5/beginShape\">beginShape()</a> call, it\nmust be prefaced with a call to <a href=\"#/p5/vertex\">vertex()</a> to set the first anchor point.\nFor WebGL mode quadraticVertex() can be used in 2D as well as 3D mode.\n2D mode expects 4 parameters, while 3D mode expects 6 parameters\n(including z coordinates).</p>\n<p>This function must be used between <a href=\"#/p5/beginShape\">beginShape()</a> and <a href=\"#/p5/endShape\">endShape()</a>\nand only when there is no MODE or POINTS parameter specified to\n<a href=\"#/p5/beginShape\">beginShape()</a>.</p>\n","itemtype":"method","name":"quadraticVertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(5);\npoint(20, 20);\npoint(80, 20);\npoint(50, 50);\n\npoint(20, 80);\npoint(80, 80);\npoint(80, 60);\n\nnoFill();\nstrokeWeight(1);\nbeginShape();\nvertex(20, 20);\nquadraticVertex(80, 20, 50, 50);\nquadraticVertex(20, 80, 80, 80);\nvertex(80, 60);\nendShape();\n</code>\n</div>"],"alt":"arched-shaped black line with 4 pixel thick stroke weight.\nbackwards s-shaped black line with 4 pixel thick stroke weight.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":668,"params":[{"name":"cx","description":"<p>x-coordinate for the control point</p>\n","type":"Number"},{"name":"cy","description":"<p>y-coordinate for the control point</p>\n","type":"Number"},{"name":"x3","description":"<p>x-coordinate for the anchor point</p>\n","type":"Number"},{"name":"y3","description":"<p>y-coordinate for the anchor point</p>\n","type":"Number"}],"chainable":1},{"line":733,"params":[{"name":"cx","description":"","type":"Number"},{"name":"cy","description":"","type":"Number"},{"name":"cz","description":"<p>z-coordinate for the control point (for WebGL mode)</p>\n","type":"Number"},{"name":"x3","description":"","type":"Number"},{"name":"y3","description":"","type":"Number"},{"name":"z3","description":"<p>z-coordinate for the anchor point (for WebGL mode)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":826,"description":"<p>All shapes are constructed by connecting a series of vertices. <a href=\"#/p5/vertex\">vertex()</a>\nis used to specify the vertex coordinates for points, lines, triangles,\nquads, and polygons. It is used exclusively within the <a href=\"#/p5/beginShape\">beginShape()</a> and\n<a href=\"#/p5/endShape\">endShape()</a> functions.</p>\n","itemtype":"method","name":"vertex","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(3);\nbeginShape(POINTS);\nvertex(30, 20);\nvertex(85, 20);\nvertex(85, 75);\nvertex(30, 75);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(0, 35);\nvertex(35, 0);\nvertex(0, -35);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nbackground(240, 240, 240);\nfill(237, 34, 93);\nnoStroke();\nbeginShape();\nvertex(-10, 10);\nvertex(0, 35);\nvertex(10, 10);\nvertex(35, 0);\nvertex(10, -8);\nvertex(0, -35);\nvertex(-10, -8);\nvertex(-35, 0);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\nstrokeWeight(3);\nstroke(237, 34, 93);\nbeginShape(LINES);\nvertex(10, 35);\nvertex(90, 35);\nvertex(10, 65);\nvertex(90, 65);\nvertex(35, 10);\nvertex(35, 90);\nvertex(65, 10);\nvertex(65, 90);\nendShape();\n</code>\n</div>\n\n<div>\n<code>\n// Click to change the number of sides.\n// In WebGL mode, custom shapes will only\n// display hollow fill sections when\n// all calls to vertex() use the same z-value.\n\nlet sides = 3;\nlet angle, px, py;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  fill(237, 34, 93);\n  strokeWeight(3);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  ngon(sides, 0, 0, 80);\n}\n\nfunction mouseClicked() {\n  if (sides > 6) {\n    sides = 3;\n  } else {\n    sides++;\n  }\n}\n\nfunction ngon(n, x, y, d) {\n  beginShape(TESS);\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 2;\n    py = y - cos(angle) * d / 2;\n    vertex(px, py, 0);\n  }\n  for (let i = 0; i < n + 1; i++) {\n    angle = TWO_PI / n * i;\n    px = x + sin(angle) * d / 4;\n    py = y - cos(angle) * d / 4;\n    vertex(px, py, 0);\n  }\n  endShape();\n}\n</code>\n</div>"],"alt":"4 black points in a square shape in middle-right of canvas.\n4 points making a diamond shape.\n8 points making a star.\n8 points making 4 lines.\nA rotating 3D shape with a hollow section in the middle.","class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":826,"params":[{"name":"x","description":"<p>x-coordinate of the vertex</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the vertex</p>\n","type":"Number"}],"chainable":1},{"line":957,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"<p>z-coordinate of the vertex.\n                      Defaults to 0 if not specified.</p>\n","type":"Number"}],"chainable":1},{"line":965,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true},{"name":"u","description":"<p>the vertex's texture u-coordinate</p>\n","type":"Number"},{"name":"v","description":"<p>the vertex's texture v-coordinate</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/shape/vertex.js","line":1003,"description":"<p>Sets the 3d vertex normal to use for subsequent vertices drawn with\n<a href=\"#/p5/vertex\">vertex()</a>. A normal is a vector that is generally\nnearly perpendicular to a shape's surface which controls how much light will\nbe reflected from that part of the surface.</p>\n","itemtype":"method","name":"normal","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(255);\n  rotateY(frameCount / 100);\n  normalMaterial();\n  beginShape(TRIANGLE_STRIP);\n  normal(-0.4, 0.4, 0.8);\n  vertex(-30, 30, 0);\n\n  normal(0, 0, 1);\n  vertex(-30, -30, 30);\n  vertex(30, 30, 30);\n\n  normal(0.4, -0.4, 0.8);\n  vertex(30, -30, 0);\n  endShape();\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"Vertex","overloads":[{"line":1003,"params":[{"name":"vector","description":"<p>A p5.Vector representing the vertex normal.</p>\n","type":"Vector"}],"chainable":1},{"line":1040,"params":[{"name":"x","description":"<p>The x component of the vertex normal.</p>\n","type":"Number"},{"name":"y","description":"<p>The y component of the vertex normal.</p>\n","type":"Number"},{"name":"z","description":"<p>The z component of the vertex normal.</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/core/constants.js","line":9,"description":"<p>Version of this p5.js.</p>\n","itemtype":"property","name":"VERSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":18,"description":"<p>The default, two-dimensional renderer.</p>\n","itemtype":"property","name":"P2D","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":24,"description":"<p>One of the two render modes in p5.js: P2D (default renderer) and WEBGL\nEnables 3D render by introducing the third dimension: Z</p>\n","itemtype":"property","name":"WEBGL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":33,"itemtype":"property","name":"ARROW","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":38,"itemtype":"property","name":"CROSS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":43,"itemtype":"property","name":"HAND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":48,"itemtype":"property","name":"MOVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":53,"itemtype":"property","name":"TEXT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":58,"itemtype":"property","name":"WAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":66,"description":"<p>HALF_PI is a mathematical constant with the value\n1.57079632679489661923. It is half the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"HALF_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, HALF_PI);\n</code></div>"],"alt":"80×80 white quarter-circle with curve toward bottom right of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":84,"description":"<p>PI is a mathematical constant with the value\n3.14159265358979323846. It is the ratio of the circumference\nof a circle to its diameter. It is useful in combination with\nthe trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, PI);\n</code></div>"],"alt":"white half-circle with curve toward bottom of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":102,"description":"<p>QUARTER_PI is a mathematical constant with the value 0.7853982.\nIt is one quarter the ratio of the circumference of a circle to\nits diameter. It is useful in combination with the trigonometric\nfunctions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"QUARTER_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, QUARTER_PI);\n</code></div>"],"alt":"white eighth-circle rotated about 40 degrees with curve bottom right canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":120,"description":"<p>TAU is an alias for TWO_PI, a mathematical constant with the\nvalue 6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TAU","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TAU);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":138,"description":"<p>TWO_PI is a mathematical constant with the value\n6.28318530717958647693. It is twice the ratio of the\ncircumference of a circle to its diameter. It is useful in\ncombination with the trigonometric functions <a href=\"#/p5/sin\">sin()</a> and <a href=\"#/p5/cos\">cos()</a>.</p>\n","itemtype":"property","name":"TWO_PI","type":"Number","final":1,"example":["\n<div><code>\narc(50, 50, 80, 80, 0, TWO_PI);\n</code></div>"],"alt":"80×80 white ellipse shape in center of canvas.","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":156,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either DEGREES or RADIANS).</p>\n","itemtype":"property","name":"DEGREES","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(DEGREES);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":170,"description":"<p>Constant to be used with <a href=\"#/p5/angleMode\">angleMode()</a> function, to set the mode which\np5.js interprets and calculates angles (either RADIANS or DEGREES).</p>\n","itemtype":"property","name":"RADIANS","type":"String","final":1,"example":["\n<div class='norender'><code>\nfunction setup() {\n  angleMode(RADIANS);\n}\n</code></div>"],"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":188,"itemtype":"property","name":"CORNER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":193,"itemtype":"property","name":"CORNERS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":198,"itemtype":"property","name":"RADIUS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":203,"itemtype":"property","name":"RIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":208,"itemtype":"property","name":"LEFT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":213,"itemtype":"property","name":"CENTER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":218,"itemtype":"property","name":"TOP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":223,"itemtype":"property","name":"BOTTOM","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":228,"itemtype":"property","name":"BASELINE","type":"String","final":1,"default":"alphabetic","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":234,"itemtype":"property","name":"POINTS","type":"Number","final":1,"default":"0x0000","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":240,"itemtype":"property","name":"LINES","type":"Number","final":1,"default":"0x0001","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":246,"itemtype":"property","name":"LINE_STRIP","type":"Number","final":1,"default":"0x0003","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":252,"itemtype":"property","name":"LINE_LOOP","type":"Number","final":1,"default":"0x0002","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":258,"itemtype":"property","name":"TRIANGLES","type":"Number","final":1,"default":"0x0004","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":264,"itemtype":"property","name":"TRIANGLE_FAN","type":"Number","final":1,"default":"0x0006","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":270,"itemtype":"property","name":"TRIANGLE_STRIP","type":"Number","final":1,"default":"0x0005","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":276,"itemtype":"property","name":"QUADS","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":281,"itemtype":"property","name":"QUAD_STRIP","type":"String","final":1,"default":"quad_strip","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":287,"itemtype":"property","name":"TESS","type":"String","final":1,"default":"tess","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":293,"itemtype":"property","name":"CLOSE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":298,"itemtype":"property","name":"OPEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":303,"itemtype":"property","name":"CHORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":308,"itemtype":"property","name":"PIE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":313,"itemtype":"property","name":"PROJECT","type":"String","final":1,"default":"square","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":319,"itemtype":"property","name":"SQUARE","type":"String","final":1,"default":"butt","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":325,"itemtype":"property","name":"ROUND","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":330,"itemtype":"property","name":"BEVEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":335,"itemtype":"property","name":"MITER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":342,"itemtype":"property","name":"RGB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":347,"description":"<p>HSB (hue, saturation, brightness) is a type of color model.\nYou can learn more about it at\n<a href=\"https://learnui.design/blog/the-hsb-color-system-practicioners-primer.html\">HSB</a>.</p>\n","itemtype":"property","name":"HSB","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":356,"itemtype":"property","name":"HSL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":363,"description":"<p>AUTO allows us to automatically set the width or height of an element (but not both),\nbased on the current height and width of the element. Only one parameter can\nbe passed to the <a href=\"/#/p5.Element/size\">size</a> function as AUTO, at a time.</p>\n","itemtype":"property","name":"AUTO","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":373,"itemtype":"property","name":"ALT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":379,"itemtype":"property","name":"BACKSPACE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":384,"itemtype":"property","name":"CONTROL","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":389,"itemtype":"property","name":"DELETE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":394,"itemtype":"property","name":"DOWN_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":399,"itemtype":"property","name":"ENTER","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":404,"itemtype":"property","name":"ESCAPE","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":409,"itemtype":"property","name":"LEFT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":414,"itemtype":"property","name":"OPTION","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":419,"itemtype":"property","name":"RETURN","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":424,"itemtype":"property","name":"RIGHT_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":429,"itemtype":"property","name":"SHIFT","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":434,"itemtype":"property","name":"TAB","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":439,"itemtype":"property","name":"UP_ARROW","type":"Number","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":446,"itemtype":"property","name":"BLEND","type":"String","final":1,"default":"source-over","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":452,"itemtype":"property","name":"REMOVE","type":"String","final":1,"default":"destination-out","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":458,"itemtype":"property","name":"ADD","type":"String","final":1,"default":"lighter","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":466,"itemtype":"property","name":"DARKEST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":471,"itemtype":"property","name":"LIGHTEST","type":"String","final":1,"default":"lighten","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":477,"itemtype":"property","name":"DIFFERENCE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":482,"itemtype":"property","name":"SUBTRACT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":487,"itemtype":"property","name":"EXCLUSION","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":492,"itemtype":"property","name":"MULTIPLY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":497,"itemtype":"property","name":"SCREEN","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":502,"itemtype":"property","name":"REPLACE","type":"String","final":1,"default":"copy","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":508,"itemtype":"property","name":"OVERLAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":513,"itemtype":"property","name":"HARD_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":518,"itemtype":"property","name":"SOFT_LIGHT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":523,"itemtype":"property","name":"DODGE","type":"String","final":1,"default":"color-dodge","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":529,"itemtype":"property","name":"BURN","type":"String","final":1,"default":"color-burn","class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":537,"itemtype":"property","name":"THRESHOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":542,"itemtype":"property","name":"GRAY","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":547,"itemtype":"property","name":"OPAQUE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":552,"itemtype":"property","name":"INVERT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":557,"itemtype":"property","name":"POSTERIZE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":562,"itemtype":"property","name":"DILATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":567,"itemtype":"property","name":"ERODE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":572,"itemtype":"property","name":"BLUR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":579,"itemtype":"property","name":"NORMAL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":584,"itemtype":"property","name":"ITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":589,"itemtype":"property","name":"BOLD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":594,"itemtype":"property","name":"BOLDITALIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":599,"itemtype":"property","name":"CHAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":604,"itemtype":"property","name":"WORD","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":616,"itemtype":"property","name":"LINEAR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":621,"itemtype":"property","name":"QUADRATIC","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":626,"itemtype":"property","name":"BEZIER","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":631,"itemtype":"property","name":"CURVE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":638,"itemtype":"property","name":"STROKE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":643,"itemtype":"property","name":"FILL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":648,"itemtype":"property","name":"TEXTURE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":653,"itemtype":"property","name":"IMMEDIATE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":661,"itemtype":"property","name":"IMAGE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":669,"itemtype":"property","name":"NEAREST","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":674,"itemtype":"property","name":"REPEAT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":679,"itemtype":"property","name":"CLAMP","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":684,"itemtype":"property","name":"MIRROR","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":691,"itemtype":"property","name":"LANDSCAPE","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":696,"itemtype":"property","name":"PORTRAIT","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":706,"itemtype":"property","name":"GRID","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":712,"itemtype":"property","name":"AXES","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":718,"itemtype":"property","name":"LABEL","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/constants.js","line":723,"itemtype":"property","name":"FALLBACK","type":"String","final":1,"class":"p5","module":"Constants","submodule":"Constants"},{"file":"src/core/environment.js","line":20,"description":"<p>The <a href=\"#/p5/print\">print()</a> function writes to the console area of\nyour browser. This function is often helpful for looking at the data a program\nis producing. This function creates a new line of text for each call to\nthe function. Individual elements can be separated with quotes (\"\") and joined\nwith the addition operator (+).</p>\n<p>Note that calling print() without any arguments invokes the window.print()\nfunction which opens the browser's print dialog. To print a blank line\nto console you can write print('\\n').</p>\n","itemtype":"method","name":"print","params":[{"name":"contents","description":"<p>any combination of Number, String, Object, Boolean,\n                      Array to print</p>\n","type":"Any"}],"example":["\n<div><code class='norender'>\nlet x = 10;\nprint('The value of x is ' + x);\n// prints \"The value of x is 10\"\n</code></div>"],"alt":"default grey canvas","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":52,"description":"<p>The system variable <a href=\"#/p5/frameCount\">frameCount</a> contains the\nnumber of frames that have been displayed since the program started. Inside\n<a href=\"#/p5/setup\">setup()</a> the value is 0, after the first iteration\nof draw it is 1, etc.</p>\n","itemtype":"property","name":"frameCount","type":"Integer","readonly":"","example":["\n<div><code>\nfunction setup() {\n  frameRate(30);\n  textSize(30);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  text(frameCount, width / 2, height / 2);\n}\n</code></div>"],"alt":"numbers rapidly counting upward with frame count set to 30.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":79,"description":"<p>The system variable <a href=\"#/p5/deltaTime\">deltaTime</a> contains the time\ndifference between the beginning of the previous frame and the beginning\nof the current frame in milliseconds.</p>\n<p>This variable is useful for creating time sensitive animation or physics\ncalculation that should stay constant regardless of frame rate.</p>\n","itemtype":"property","name":"deltaTime","type":"Integer","readonly":"","example":["\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX + 1 * (deltaTime / 50); // Move Rectangle in relation to deltaTime\n\n  if (rectX >= width) {\n    // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"red rect moves left to right, followed by blue rect moving at the same speed\nwith a lower frame rate. Loops.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":129,"description":"<p>Confirms if the window a p5.js program is in is \"focused,\" meaning that\nthe sketch will accept mouse or keyboard input. This variable is\n\"true\" if the window is focused and \"false\" if not.</p>\n","itemtype":"property","name":"focused","type":"Boolean","readonly":"","example":["\n<div><code>\n// To demonstrate, put two windows side by side.\n// Click on the window that the p5 sketch isn't in!\nfunction draw() {\n  background(200);\n  noStroke();\n  fill(0, 200, 0);\n  ellipse(25, 25, 50, 50);\n\n  if (!focused) {\n   // or \"if (focused === false)\"\n    stroke(200, 0, 0);\n    line(0, 0, 100, 100);\n    line(100, 0, 0, 100);\n  }\n}\n</code></div>"],"alt":"green 50×50 ellipse at top left. Red X covers canvas when page focus changes","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":160,"description":"<p>Sets the cursor to a predefined symbol or an image, or makes it visible\nif already hidden. If you are trying to set an image as the cursor, the\nrecommended size is 16×16 or 32×32 pixels. The values for parameters x and y\nmust be less than the dimensions of the image.</p>\n","itemtype":"method","name":"cursor","params":[{"name":"type","description":"<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n                              Native CSS properties: 'grab', 'progress', 'cell' etc.\n                              External: path for cursor's images\n                              (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n                              For more information on Native CSS cursors and url visit:\n                              <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n","type":"String|Constant"},{"name":"x","description":"<p>the horizontal active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the vertical active spot of the cursor (must be less than 32)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n// Move the mouse across the quadrants\n// to see the cursor change\nfunction draw() {\n  line(width / 2, 0, width / 2, height);\n  line(0, height / 2, width, height / 2);\n  if (mouseX < 50 && mouseY < 50) {\n    cursor(CROSS);\n  } else if (mouseX > 50 && mouseY < 50) {\n    cursor('progress');\n  } else if (mouseX > 50 && mouseY > 50) {\n    cursor('https://avatars0.githubusercontent.com/u/1617169?s=16');\n  } else {\n    cursor('grab');\n  }\n}\n</code></div>"],"alt":"canvas is divided into four quadrants. cursor on first is a cross, second is a progress,\nthird is a custom cursor using path to the cursor and fourth is a grab.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":228,"description":"<p>Specifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within\n<a href=\"#/p5/setup\">setup()</a> is recommended. The default frame rate is\nbased on the frame rate of the display (here also called \"refresh rate\"),\nwhich is set to 60 frames per second on most computers. A frame rate of 24\nframes per second (usual for movies) or above will be enough for smooth\nanimations. This is the same as setFrameRate(val).</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns\nthe current framerate. The draw function must run at least once before it will\nreturn a value. This is the same as <a href=\"#/p5/getFrameRate\">getFrameRate()</a>.</p>\n<p>Calling <a href=\"#/p5/frameRate\">frameRate()</a> with arguments that are not\nof the type numbers or are non positive also returns current framerate.</p>\n","itemtype":"method","name":"frameRate","chainable":1,"example":["\n\n<div><code>\nlet rectX = 0;\nlet fr = 30; //starting FPS\nlet clr;\n\nfunction setup() {\n  background(200);\n  frameRate(fr); // Attempt to refresh at starting FPS\n  clr = color(255, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  rectX = rectX += 1; // Move Rectangle\n\n  if (rectX >= width) {\n   // If you go off screen.\n    if (fr === 30) {\n      clr = color(0, 0, 255);\n      fr = 10;\n      frameRate(fr); // make frameRate 10 FPS\n    } else {\n      clr = color(255, 0, 0);\n      fr = 30;\n      frameRate(fr); // make frameRate 30 FPS\n    }\n    rectX = 0;\n  }\n  fill(clr);\n  rect(rectX, 40, 20, 20);\n}\n</code></div>"],"alt":"blue rect moves left to right, followed by red rect moving faster. Loops.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":228,"params":[{"name":"fps","description":"<p>number of frames to be displayed every second</p>\n","type":"Number"}],"chainable":1},{"line":288,"params":[],"return":{"description":"current frameRate","type":"Number"}}]},{"file":"src/core/environment.js","line":331,"description":"<p>Hides the cursor from view.</p>\n","itemtype":"method","name":"noCursor","example":["\n<div><code>\nfunction setup() {\n  noCursor();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(mouseX, mouseY, 10, 10);\n}\n</code></div>"],"alt":"cursor becomes 10×10 white ellipse the moves with mouse x and y.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":354,"description":"<p>System variable that stores the width of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":372,"description":"<p>System variable that stores the height of the screen display according to The\ndefault <a href=\"#/p5/pixelDensity\">pixelDensity</a>. This is used to run a\nfull-screen program on any display size. To return actual screen size,\nmultiply this by pixelDensity.</p>\n","itemtype":"property","name":"displayHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(displayWidth, displayHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":390,"description":"<p>System variable that stores the width of the inner window, it maps to\nwindow.innerWidth.</p>\n","itemtype":"property","name":"windowWidth","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":405,"description":"<p>System variable that stores the height of the inner window, it maps to\nwindow.innerHeight.</p>\n","itemtype":"property","name":"windowHeight","type":"Number","readonly":"","example":["\n<div class=\"norender\"><code>\ncreateCanvas(windowWidth, windowHeight);\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":421,"description":"<p>The <a href=\"#/p5/windowResized\">windowResized()</a> function is called once\nevery time the browser window is resized. This is a good place to resize the\ncanvas or do any other adjustments to accommodate the new window size.</p>\n","itemtype":"method","name":"windowResized","params":[{"name":"event","description":"<p>optional Event callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":476,"description":"<p>System variable that stores the width of the drawing canvas. This value\nis set by the first parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function.\nFor example, the function call createCanvas(320, 240) sets the width\nvariable to the value 320. The value of width defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":488,"description":"<p>System variable that stores the height of the drawing canvas. This value\nis set by the second parameter of the <a href=\"#/p5/createCanvas\">createCanvas()</a> function. For\nexample, the function call createCanvas(320, 240) sets the height\nvariable to the value 240. The value of height defaults to 100 if\n<a href=\"#/p5/createCanvas\">createCanvas()</a> is not used in a program.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":500,"description":"<p>If argument is given, sets the sketch to fullscreen or not based on the\nvalue of the argument. If no argument is given, returns the current\nfullscreen state. Note that due to browser restrictions this can only\nbe called on user input, for example, on mouse press like the example\nbelow.</p>\n","itemtype":"method","name":"fullscreen","params":[{"name":"val","description":"<p>whether the sketch should be in fullscreen mode\nor not</p>\n","type":"Boolean","optional":true}],"return":{"description":"current fullscreen state","type":"Boolean"},"example":["\n<div>\n<code>\n// Clicking in the box toggles fullscreen on and off.\nfunction setup() {\n  background(200);\n}\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < 100 && mouseY > 0 && mouseY < 100) {\n    let fs = fullscreen();\n    fullscreen(!fs);\n  }\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":550,"description":"<p>Sets the pixel scaling for high pixel density displays. By default\npixel density is set to match display density, call pixelDensity(1)\nto turn this off. Calling <a href=\"#/p5/pixelDensity\">pixelDensity()</a> with no arguments returns\nthe current pixel density of the sketch.</p>\n","itemtype":"method","name":"pixelDensity","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  pixelDensity(3.0);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"fuzzy 50×50 white ellipse with black outline in center of canvas.\nsharp 50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment","overloads":[{"line":550,"params":[{"name":"val","description":"<p>whether or how much the sketch should scale</p>\n","type":"Number"}],"chainable":1},{"line":586,"params":[],"return":{"description":"current pixel density of the sketch","type":"Number"}}]},{"file":"src/core/environment.js","line":605,"description":"<p>Returns the pixel density of the current display the sketch is running on.</p>\n","itemtype":"method","name":"displayDensity","return":{"description":"current pixel density of the display","type":"Number"},"example":["\n<div>\n<code>\nfunction setup() {\n  let density = displayDensity();\n  pixelDensity(density);\n  createCanvas(100, 100);\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white ellipse with black outline in center of canvas.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":660,"description":"<p>Gets the current URL. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURL","return":{"description":"url","type":"String"},"example":["\n<div>\n<code>\nlet url;\nlet x = 100;\n\nfunction setup() {\n  fill(0);\n  noStroke();\n  url = getURL();\n}\n\nfunction draw() {\n  background(200);\n  text(url, x, height / 2);\n  x--;\n}\n</code>\n</div>"],"alt":"current url (http://p5js.org/reference/#/p5/getURL) moves right to left.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":691,"description":"<p>Gets the current URL path as an array. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLPath","return":{"description":"path components","type":"String[]"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let urlPath = getURLPath();\n  for (let i = 0; i < urlPath.length; i++) {\n    text(urlPath[i], 10, i * 20 + 20);\n  }\n}\n</code></div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/environment.js","line":713,"description":"<p>Gets the current URL params as an Object. Note: when using the\np5 Editor, this will return an empty object because the sketch\nis embedded in an iframe. It will work correctly if you view the\nsketch using the editor's present or share URLs.</p>\n","itemtype":"method","name":"getURLParams","return":{"description":"URL params","type":"Object"},"example":["\n<div class='norender notest'>\n<code>\n// Example: http://p5js.org?year=2014&month=May&day=15\n\nfunction setup() {\n  let params = getURLParams();\n  text(params.day, 10, 20);\n  text(params.month, 10, 40);\n  text(params.year, 10, 60);\n}\n</code>\n</div>"],"alt":"This example does not render anything.","class":"p5","module":"Environment","submodule":"Environment"},{"file":"src/core/helpers.js","line":1,"requires":["constants"],"class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":30,"description":"<p>This is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":126,"description":"<p>Set up our translation function, with loaded languages</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":171,"description":"<p>Returns a list of languages we have translations loaded for</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":178,"description":"<p>Returns the current language selected for translation</p>\n","class":"p5","module":"Environment"},{"file":"src/core/internationalization.js","line":185,"description":"<p>Sets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.</p>\n","class":"p5","module":"Environment"},{"file":"src/core/legacy.js","line":1,"requires":["core\nThese are functions that are part of the Processing API but are not part of\nthe p5.js API. In some cases they have a new name","in others","they are\nremoved completely. Not all unsupported Processing functions are listed here\nbut we try to include ones that a user coming from Processing might likely\ncall."],"class":"p5","module":"Environment"},{"file":"src/core/main.js","line":42,"description":"<p>Called directly before <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/preload\">preload()</a> function is used to handle\nasynchronous loading of external files in a blocking way. If a preload\nfunction is defined, <a href=\"#/p5/setup\">setup()</a> will wait until any load calls within have\nfinished. Nothing besides load calls (<a href=\"#/p5/loadImage\">loadImage</a>, <a href=\"#/p5/loadJSON\">loadJSON</a>, <a href=\"#/p5/loadFont\">loadFont</a>,\n<a href=\"#/p5/loadStrings\">loadStrings</a>, etc.) should be inside the preload function. If asynchronous\nloading is preferred, the load methods can instead be called in <a href=\"#/p5/setup\">setup()</a>\nor anywhere else with the use of a callback parameter.</p>\n<p>By default the text \"loading...\" will be displayed. To make your own\nloading page, include an HTML element with id \"p5_loading\" in your\npage. More information <a href=\"http://bit.ly/2kQ6Nio\">here</a>.</p>\n","itemtype":"method","name":"preload","example":["\n<div><code>\nlet img;\nlet c;\nfunction preload() {\n  // preload() runs once\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  // setup() waits until preload() is done\n  img.loadPixels();\n  // get color of middle pixel\n  c = img.get(img.width / 2, img.height / 2);\n}\n\nfunction draw() {\n  background(c);\n  image(img, 25, 25, 50, 50);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":83,"description":"<p>The <a href=\"#/p5/setup\">setup()</a> function is called once when the program starts. It's used to\ndefine initial environment properties such as screen size and background\ncolor and to load media such as images and fonts as the program starts.\nThere can only be one <a href=\"#/p5/setup\">setup()</a> function for each program and it shouldn't\nbe called again after its initial execution.</p>\n<p>Note: Variables declared within <a href=\"#/p5/setup\">setup()</a> are not accessible within other\nfunctions, including <a href=\"#/p5/draw\">draw()</a>.</p>\n","itemtype":"method","name":"setup","example":["\n<div><code>\nlet a = 0;\n\nfunction setup() {\n  background(0);\n  noStroke();\n  fill(102);\n}\n\nfunction draw() {\n  rect(a++ % width, 10, 2, 80);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":114,"description":"<p>Called directly after <a href=\"#/p5/setup\">setup()</a>, the <a href=\"#/p5/draw\">draw()</a> function continuously executes\nthe lines of code contained inside its block until the program is stopped\nor <a href=\"#/p5/noLoop\">noLoop()</a> is called. Note if <a href=\"#/p5/noLoop\">noLoop()</a> is called in <a href=\"#/p5/setup\">setup()</a>, <a href=\"#/p5/draw\">draw()</a> will\nstill be executed once before stopping. <a href=\"#/p5/draw\">draw()</a> is called automatically and\nshould never be called explicitly.</p>\n<p>It should always be controlled with <a href=\"#/p5/noLoop\">noLoop()</a>, <a href=\"#/p5/redraw\">redraw()</a> and <a href=\"#/p5/loop\">loop()</a>. After\n<a href=\"#/p5/noLoop\">noLoop()</a> stops the code in <a href=\"#/p5/draw\">draw()</a> from executing, <a href=\"#/p5/redraw\">redraw()</a> causes the\ncode inside <a href=\"#/p5/draw\">draw()</a> to execute once, and <a href=\"#/p5/loop\">loop()</a> will cause the code\ninside <a href=\"#/p5/draw\">draw()</a> to resume executing continuously.</p>\n<p>The number of times <a href=\"#/p5/draw\">draw()</a> executes in each second may be controlled with\nthe <a href=\"#/p5/frameRate\">frameRate()</a> function.</p>\n<p>There can only be one <a href=\"#/p5/draw\">draw()</a> function for each sketch, and <a href=\"#/p5/draw\">draw()</a> must\nexist if you want the code to run continuously, or to process events such\nas <a href=\"#/p5/mousePressed\">mousePressed()</a>. Sometimes, you might have an empty call to <a href=\"#/p5/draw\">draw()</a> in\nyour program, as shown in the above example.</p>\n<p>It is important to note that the drawing coordinate system will be reset\nat the beginning of each <a href=\"#/p5/draw\">draw()</a> call. If any transformations are performed\nwithin <a href=\"#/p5/draw\">draw()</a> (ex: scale, rotate, translate), their effects will be\nundone at the beginning of <a href=\"#/p5/draw\">draw()</a>, so transformations will not accumulate\nover time. On the other hand, styling applied (ex: fill, stroke, etc) will\nremain in effect.</p>\n","itemtype":"method","name":"draw","example":["\n<div><code>\nlet yPos = 0;\nfunction setup() {\n  // setup() runs once\n  frameRate(30);\n}\nfunction draw() {\n  // draw() loops forever, until stopped\n  background(204);\n  yPos = yPos - 1;\n  if (yPos < 0) {\n    yPos = height;\n  }\n  line(0, yPos, width, yPos);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":415,"description":"<p>Removes the entire p5 sketch. This will remove the canvas and any\nelements created by p5.js. It will also stop the draw loop and unbind\nany properties or methods from the window global scope. It will\nleave a variable p5 in case you wanted to create a new p5 sketch.\nIf you like, you can set p5 = null to erase it. While all functions and\nvariables and objects created by the p5 library will be removed, any\nother global variables created by your code will remain.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nfunction draw() {\n  ellipse(50, 50, 10, 10);\n}\n\nfunction mousePressed() {\n  remove(); // remove whole sketch on mouse press\n}\n</code></div>"],"alt":"nothing displayed","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/main.js","line":693,"description":"<p>Turn off some features of the friendly error system (FES), which can give\na significant boost to performance when needed.</p>\n<p>Note that this will disable the parts of the FES that cause performance\nslowdown (like argument checking). Friendly errors that have no performance\ncost (like giving an descriptive error if a file load fails, or warning you\nif you try to override p5.js functions in the global space),\nwill remain in place.</p>\n<p>See <a href='https://github.com/processing/p5.js/wiki/Optimizing-p5.js-Code-for-Performance#disable-the-friendly-error-system-fes'>\ndisabling the friendly error system</a>.</p>\n","itemtype":"property","name":"disableFriendlyErrors","type":"Boolean","example":["\n<div class=\"norender notest\"><code>\np5.disableFriendlyErrors = true;\n\nfunction setup() {\n  createCanvas(100, 50);\n}\n</code></div>"],"class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/p5.Element.js","line":21,"description":"<p>Underlying HTML element. All normal HTML methods can be called on this.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  let c = createCanvas(50, 50);\n  c.elt.style.border = '5px solid red';\n}\n\nfunction draw() {\n  background(220);\n}\n</code>\n</div>"],"itemtype":"property","name":"elt","readonly":"","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":47,"description":"<p>Attaches the element to the parent specified. A way of setting\n the container for the element. Accepts either a string ID, DOM\n node, or <a href=\"#/p5.Element\">p5.Element</a>. If no arguments given, parent node is returned.\n For more ways to position the canvas, see the\n <a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\n positioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"parent","chainable":1,"example":["\n <div class=\"norender notest\"><code>\n // Add the following comment to html file.\n // &lt;div id=\"myContainer\">&lt;/div>\n// The js code\n let cnv = createCanvas(100, 100);\n cnv.parent('myContainer');\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.parent(div0); // use p5.Element\n </code></div>\n<div class='norender'><code>\n let div0 = createDiv('this is the parent');\n div0.id('apples');\n let div1 = createDiv('this is the child');\n div1.parent('apples'); // use id\n </code></div>\n<div class='norender notest'><code>\n let elt = document.getElementById('myParentDiv');\n let div1 = createDiv('this is the child');\n div1.parent(elt); // use element from page\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":47,"params":[{"name":"parent","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                         of desired parent element</p>\n","type":"String|p5.Element|Object"}],"chainable":1},{"line":93,"params":[],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/core/p5.Element.js","line":114,"description":"<p>Sets the ID of the element. If no ID argument is passed in, it instead\n returns the current ID of the element.\n Note that only one element can have a particular id in a page.\n The <a href=\"#/p5.Element/class\">.class()</a> function can be used\n to identify multiple elements with the same class name.</p>\n","itemtype":"method","name":"id","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector ID to\n   // the canvas element.\n   cnv.id('mycanvas');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":114,"params":[{"name":"id","description":"<p>ID of the element</p>\n","type":"String"}],"chainable":1},{"line":139,"params":[],"return":{"description":"the id of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":154,"description":"<p>Adds given class to the element. If no class argument is passed in, it\n instead returns a string containing the current class(es) of the element.</p>\n","itemtype":"method","name":"class","chainable":1,"example":["\n <div class='norender'><code>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // Assigns a CSS selector class 'small'\n   // to the canvas element.\n   cnv.class('small');\n }\n </code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":154,"params":[{"name":"class","description":"<p>class to add</p>\n","type":"String"}],"chainable":1},{"line":176,"params":[],"return":{"description":"the class of the element","type":"String"}}]},{"file":"src/core/p5.Element.js","line":189,"description":"<p>The .<a href=\"#/p5.Element/mousePressed\">mousePressed()</a> function is called\nonce after every time a mouse button is pressed over the element. Some mobile\nbrowsers may also trigger this event on a touch screen, if the user performs\na quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               pressed over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mousePressed(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any click anywhere\nfunction mousePressed() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":246,"description":"<p>The .<a href=\"#/p5.Element/doubleClicked\">doubleClicked()</a> function is called once after every time a\nmouse button is pressed twice over the element. This can be used to\nattach element and action specific event listeners.</p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               double clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"return":{"description":"","type":"p5.Element"},"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.doubleClicked(changeGray); // attach listener for\n  // canvas double click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any double click anywhere\nfunction doubleClicked() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is double clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":292,"description":"<p>The <a href=\"#/p5.Element/mouseWheel\">mouseWheel()</a> function is called\nonce after every time a mouse wheel is scrolled over the element. This can\nbe used to attach element specific event listeners.</p>\n<p>The function accepts a callback function as argument which will be executed\nwhen the <code>wheel</code> event is triggered on the element, the callback function is\npassed one argument <code>event</code>. The <code>event.deltaY</code> property returns negative\nvalues if the mouse wheel is rotated up or away from the user and positive\nin the other direction. The <code>event.deltaX</code> does the same as <code>event.deltaY</code>\nexcept it reads the horizontal wheel scroll of the mouse wheel.</p>\n<p>On OS X with \"natural\" scrolling enabled, the <code>event.deltaY</code> values are\nreversed.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               scrolled over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseWheel(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with mousewheel movement\n// anywhere on screen\nfunction mouseWheel() {\n  g = g + 10;\n}\n\n// this function fires with mousewheel movement\n// over canvas only\nfunction changeSize(event) {\n  if (event.deltaY > 0) {\n    d = d + 10;\n  } else {\n    d = d - 10;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":354,"description":"<p>The <a href=\"#/p5.Element/mouseReleased\">mouseReleased()</a> function is\ncalled once after every time a mouse button is released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               released over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseReleased(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// released\nfunction mouseReleased() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// released while on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":403,"description":"<p>The .<a href=\"#/p5.Element/mouseClicked\">mouseClicked()</a> function is\ncalled once after a mouse button is pressed and released over the element.\nSome mobile browsers may also trigger this event on a touch screen, if the\nuser performs a quick tap.This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"fxn","description":"<p>function to be fired when mouse is\n                               clicked over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet cnv, d, g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(changeGray); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires after the mouse has been\n// clicked anywhere\nfunction mouseClicked() {\n  d = d + 10;\n}\n\n// this function fires after the mouse has been\n// clicked on canvas\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code>\n</div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":454,"description":"<p>The .<a href=\"#/p5.Element/mouseMoved\">mouseMoved()</a> function is called once every time a\nmouse moves over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d = 30;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseMoved(changeSize); // attach listener for\n  // activity on canvas only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  fill(200);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires when mouse moves anywhere on\n// page\nfunction mouseMoved() {\n  g = g + 5;\n  if (g > 255) {\n    g = 0;\n  }\n}\n\n// this function fires when mouse moves over canvas\nfunction changeSize() {\n  d = d + 2;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":510,"description":"<p>The .<a href=\"#/p5.Element/mouseOver\">mouseOver()</a> function is called once after every time a\nmouse moves onto the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOver","params":[{"name":"fxn","description":"<p>function to be fired when a mouse moves\n                               onto the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOver(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":551,"description":"<p>The .<a href=\"#/p5.Element/mouseOut\">mouseOut()</a> function is called once after every time a\nmouse moves off the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"mouseOut","params":[{"name":"fxn","description":"<p>function to be fired when a mouse\n                               moves off of an element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.mouseOut(changeGray);\n  d = 10;\n}\n\nfunction draw() {\n  ellipse(width / 2, height / 2, d, d);\n}\n\nfunction changeGray() {\n  d = d + 10;\n  if (d > 100) {\n    d = 0;\n  }\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":592,"description":"<p>The .<a href=\"#/p5.Element/touchStarted\">touchStarted()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"fxn","description":"<p>function to be fired when a touch\n                               starts over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchStarted(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchStarted() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":639,"description":"<p>The .<a href=\"#/p5.Element/touchMoved\">touchMoved()</a> function is called once after every time a touch move is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"fxn","description":"<p>function to be fired when a touch moves over\n                               the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchMoved(changeGray); // attach listener for\n  // canvas click only\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":678,"description":"<p>The .<a href=\"#/p5.Element/touchEnded\">touchEnded()</a> function is called once after every time a touch is\nregistered. This can be used to attach element specific event listeners.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"fxn","description":"<p>function to be fired when a touch ends\n                               over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div class='norender'><code>\nlet cnv;\nlet d;\nlet g;\nfunction setup() {\n  cnv = createCanvas(100, 100);\n  cnv.touchEnded(changeGray); // attach listener for\n  // canvas click only\n  d = 10;\n  g = 100;\n}\n\nfunction draw() {\n  background(g);\n  ellipse(width / 2, height / 2, d, d);\n}\n\n// this function fires with any touch anywhere\nfunction touchEnded() {\n  d = d + 10;\n}\n\n// this function fires only when cnv is clicked\nfunction changeGray() {\n  g = random(0, 255);\n}\n</code></div>"],"alt":"no display.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":725,"description":"<p>The .<a href=\"#/p5.Element/dragOver\">dragOver()</a> function is called once after every time a\nfile is dragged over the element. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragOver","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged over the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a\n// file over the canvas\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragOver(dragOverCallback);\n}\n\n// This function will be called whenever\n// a file is dragged over the canvas\nfunction dragOverCallback() {\n  background(240);\n  text('Dragged over', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":763,"description":"<p>The .dragLeave() function is called once after every time a\ndragged file leaves the element area. This can be used to attach an\nelement specific event listener.</p>\n","itemtype":"method","name":"dragLeave","params":[{"name":"fxn","description":"<p>function to be fired when a file is\n                               dragged off the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// To test this sketch, simply drag a file\n// over and then out of the canvas area\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('Drag file', width / 2, height / 2);\n  c.dragLeave(dragLeaveCallback);\n}\n\n// This function will be called whenever\n// a file is dragged out of the canvas\nfunction dragLeaveCallback() {\n  background(240);\n  text('Dragged off', width / 2, height / 2);\n}\n</code></div>"],"alt":"nothing displayed","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Element.js","line":827,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/core/p5.Graphics.js","line":70,"description":"<p>Resets certain values such as those modified by functions in the Transform category\nand in the Lights category that are not automatically reset\nwith graphics buffer objects. Calling this in <a href='#/p5/draw'>draw()</a> will copy the behavior\nof the standard canvas.</p>\n","itemtype":"method","name":"reset","example":["\n\n<div><code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  pg = createGraphics(50, 100);\n  pg.fill(0);\n  frameRate(5);\n}\n\nfunction draw() {\n  image(pg, width / 2, 0);\n  pg.background(255);\n  // p5.Graphics object behave a bit differently in some cases\n  // The normal canvas on the left resets the translate\n  // with every loop through draw()\n  // the graphics object on the right doesn't automatically reset\n  // so translate() is additive and it moves down the screen\n  rect(0, 0, width / 2, 5);\n  pg.rect(0, 0, width / 2, 5);\n  translate(0, 5, 0);\n  pg.translate(0, 5, 0);\n}\nfunction mouseClicked() {\n  // if you click you will see that\n  // reset() resets the translate back to the initial state\n  // of the Graphics object\n  pg.reset();\n}\n</code></div>"],"alt":"A white line on a black background stays still on the top-left half.\nA black line animates from top to bottom on a white background on the right half.\nWhen clicked, the black line starts back over at the top.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Graphics.js","line":122,"description":"<p>Removes a Graphics object from the page and frees any resources\nassociated with it.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet bg;\nfunction setup() {\n  bg = createCanvas(100, 100);\n  bg.background(0);\n  image(bg, 0, 0);\n  bg.remove();\n}\n</code></div>\n\n<div><code>\nlet bg;\nfunction setup() {\n  pixelDensity(1);\n  createCanvas(100, 100);\n  stroke(255);\n  fill(0);\n\n  // create and draw the background image\n  bg = createGraphics(100, 100);\n  bg.background(200);\n  bg.ellipse(50, 50, 80, 80);\n}\nfunction draw() {\n  let t = millis() / 1000;\n  // draw the background\n  if (bg) {\n    image(bg, frameCount % 100, 0);\n    image(bg, frameCount % 100 - 100, 0);\n  }\n  // draw the foreground\n  let p = p5.Vector.fromAngle(t, 35).add(50, 50);\n  ellipse(p.x, p.y, 30);\n}\nfunction mouseClicked() {\n  // remove the background\n  if (bg) {\n    bg.remove();\n    bg = null;\n  }\n}\n</code></div>"],"alt":"no image\na multi-colored circle moving back and forth over a scrolling background.","class":"p5.Graphics","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":99,"description":"<p>Resize our canvas element.</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":415,"description":"<p>Helper function to check font type (system or otf)</p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer.js","line":467,"description":"<p>Helper fxn to measure ascent and descent.\nAdapted from <a href=\"http://stackoverflow.com/a/25355178\">http://stackoverflow.com/a/25355178</a></p>\n","class":"p5.Renderer","module":"Rendering","submodule":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":7,"description":"<p>p5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/p5.Renderer2D.js","line":402,"description":"<p>Generate a cubic Bezier representing an arc on the unit circle of total\nangle <code>size</code> radians, beginning <code>start</code> radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.</p>\n<p>See <a href=\"http://www.joecridge.me/bezier.pdf\">www.joecridge.me/bezier.pdf</a> for an explanation of the method.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/reference.js","line":7,"description":"<p>Creates and names a new variable. A variable is a container for a value.</p>\n<p>Variables that are declared with <a href=\"#/p5/let\">let</a> will have block-scope.\nThis means that the variable only exists within the\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let\">the MDN entry</a>:\nDeclares a block scope local variable, optionally initializing it to a value.</p>\n","itemtype":"property","name":"let","example":["\n<div class='norender'>\n<code>\nlet x = 2;\nconsole.log(x); // prints 2 to the console\nx = 1;\nconsole.log(x); // prints 1 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":34,"description":"<p>Creates and names a new constant. Like a variable created with <a href=\"#/p5/let\">let</a>,\na constant that is created with <a href=\"#/p5/const\">const</a> is a container for a value,\nhowever constants cannot be reassigned once they are declared. Although it is\nnoteworthy that for non-primitive data types like objects & arrays, their\nelements can still be changeable. So if a variable is assigned an array, you\ncan still add or remove elements from the array but cannot reassign another\narray to it. Also unlike <code>let</code>, you cannot declare variables without value\nusing const.</p>\n<p>Constants have block-scope. This means that the constant only exists within\nthe <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/block\">\nblock</a> that it is created within. A constant cannot be redeclared within a scope in which it\nalready exists.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const\">the MDN entry</a>:\nDeclares a read-only named constant.\nConstants are block-scoped, much like variables defined using the 'let' statement.\nThe value of a constant can't be changed through reassignment, and it can't be redeclared.</p>\n","itemtype":"property","name":"const","example":["\n<div class='norender'>\n<code>\n// define myFavNumber as a constant and give it the value 7\nconst myFavNumber = 7;\nconsole.log('my favorite number is: ' + myFavNumber);\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst bigCats = ['lion', 'tiger', 'panther'];\nbigCats.push('leopard');\nconsole.log(bigCats);\n// bigCats = ['cat']; // throws error as re-assigning not allowed for const\n</code>\n</div>\n\n<div class='norender'>\n<code>\nconst wordFrequency = {};\nwordFrequency['hello'] = 2;\nwordFrequency['bye'] = 1;\nconsole.log(wordFrequency);\n// wordFrequency = { 'a': 2, 'b': 3}; // throws error here\n</code>\n</div>"],"alt":"These examples do not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":87,"description":"<p>The strict equality operator <a href=\"#/p5/===\">===</a>\nchecks to see if two values are equal and of the same type.</p>\n<p>A comparison expression always evaluates to a <a href=\"#/p5/boolean\">boolean</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">the MDN entry</a>:\nThe non-identity operator returns true if the operands are not equal and/or not of the same type.</p>\n<p>Note: In some examples around the web you may see a double-equals-sign\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators#Equality\">==</a>,\nused for comparison instead. This is the non-strict equality operator in Javascript.\nThis will convert the two values being compared to the same type before comparing them.</p>\n","itemtype":"property","name":"===","example":["\n<div class='norender'>\n<code>\nconsole.log(1 === 1); // prints true to the console\nconsole.log(1 === '1'); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":115,"description":"<p>The greater than operator <a href=\"#/p5/>\">></a>\nevaluates to true if the left value is greater than\nthe right value.</p>\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">\nThere is more info on comparison operators on MDN.</a>","itemtype":"property","name":">","example":["\n<div class='norender'>\n<code>\nconsole.log(100 > 1); // prints true to the console\nconsole.log(1 > 100); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":137,"description":"<p>The greater than or equal to operator <a href=\"#/p5/>=\">>=</a>\nevaluates to true if the left value is greater than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":">=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 >= 100); // prints true to the console\nconsole.log(101 >= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":158,"description":"<p>The less than operator <a href=\"#/p5/<\"><</a>\nevaluates to true if the left value is less than\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<","example":["\n<div class='norender'>\n<code>\nconsole.log(1 < 100); // prints true to the console\nconsole.log(100 < 99); // prints false to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":179,"description":"<p>The less than or equal to operator <a href=\"#/p5/<=\"><=</a>\nevaluates to true if the left value is less than or equal to\nthe right value.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators\">There is more info on comparison operators on MDN.</a></p>\n","itemtype":"property","name":"<=","example":["\n<div class='norender'>\n<code>\nconsole.log(100 <= 100); // prints true to the console\nconsole.log(99 <= 100); // prints true to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":200,"description":"<p>The <a href=\"#/p5/if-else\">if-else</a> statement helps control the flow of your code.</p>\n<p>A condition is placed between the parenthesis following 'if',\nwhen that condition evalues to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/truthy\">truthy</a>,\nthe code between the following curly braces is run.\nAlternatively, when the condition evaluates to <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Falsy\">falsy</a>,\nthe code between the curly braces of 'else' block is run instead. Writing an\nelse block is optional.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else\">the MDN entry</a>:\nThe 'if' statement executes a statement if a specified condition is truthy.\nIf the condition is falsy, another statement can be executed</p>\n","itemtype":"property","name":"if-else","example":["\n<div class='norender'>\n<code>\nlet a = 4;\nif (a > 0) {\n  console.log('positive');\n} else {\n  console.log('negative');\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":231,"description":"<p>Creates and names a <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions\">function</a>.\nA <a href=\"#/p5/function\">function</a> is a set of statements that perform a task.</p>\n<p>Optionally, functions can have parameters. <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/Parameter\">Parameters</a>\nare variables that are scoped to the function, that can be assigned a value\nwhen calling the function.Multiple parameters can be given by seperating them\nwith commmas.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function\">the MDN entry</a>:\nDeclares a function with the specified parameters.</p>\n","itemtype":"property","name":"function","example":["\n<div class='norender'>\n<code>\nlet myName = 'Hridi';\nfunction sayHello(name) {\n  console.log('Hello ' + name + '!');\n}\nsayHello(myName); // calling the function, prints \"Hello Hridi!\" to console.\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet square = number => number * number;\nconsole.log(square(5));\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":267,"description":"<p>Specifies the value to be returned by a function.\nFor more info checkout <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/return\">\nthe MDN entry for return</a>.</p>\n","itemtype":"property","name":"return","example":["\n<div class='norender'>\n<code>\nfunction calculateSquare(x) {\n  return x * x;\n}\nconst result = calculateSquare(4); // returns 16\nconsole.log(result); // prints '16' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":288,"description":"<p>A <a href=\"#/p5/boolean\">boolean</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA boolean can only be <code>true</code> or <code>false</code>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type\">the MDN entry</a>:\nBoolean represents a logical entity and can have two values: true, and false.</p>\n","itemtype":"property","name":"boolean","example":["\n<div class='norender'>\n<code>\nlet myBoolean = false;\nconsole.log(typeof myBoolean); // prints 'boolean' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":309,"description":"<p>A <a href=\"#/p5/string\">string</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA string is a series of text characters. In Javascript, a string value must\nbe surrounded by either single-quotation marks(') or double-quotation marks(\").</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Glossary/string\">the MDN entry</a>:\nA string is a sequence of characters used to represent text.</p>\n","itemtype":"property","name":"string","example":["\n<div class='norender'>\n<code>\nlet mood = 'chill';\nconsole.log(typeof mood); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":331,"description":"<p>A <a href=\"#/p5/number\">number</a> is one of the 7 <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values\">primitive data types</a> in Javascript.\nA number can be a whole number or a decimal number.</p>\n<p><a href=\"https://developer.mozilla.org/en-US/docs/Glossary/number\">The MDN entry for number</a></p>\n","itemtype":"property","name":"number","example":["\n<div class='norender'>\n<code>\nlet num = 46.5;\nconsole.log(typeof num); // prints 'number' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":351,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics\">MDN's object basics</a>:\n An <a href=\"#/p5/object\">object</a> is a collection of related data and/or\n functionality (which usually consists of several variables and functions —\n which are called properties and methods when they are inside objects.)</p>\n","itemtype":"property","name":"object","example":["\n <div class='norender'>\n <code>\n let author = {\n   name: 'Ursula K Le Guin',\n   books: [\n     'The Left Hand of Darkness',\n     'The Dispossessed',\n     'A Wizard of Earthsea'\n   ]\n };\n console.log(author.name); // prints 'Ursula K Le Guin' to the console\n </code>\n </div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":379,"description":"<p>Creates and names a <a href=\"#/p5/class\">class</a> which is a template for\nthe creation of <a href=\"#/p5/object\">objects</a>.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class\">the MDN entry</a>:\nThe class declaration creates a new Class with a given name using\nprototype-based inheritance.</p>\n","itemtype":"property","name":"class","example":["\n<div class='norender'>\n<code>\nclass Rectangle {\n  constructor(name, height, width) {\n    this.name = name;\n    this.height = height;\n    this.width = width;\n  }\n}\nlet square = new Rectangle('square', 1, 1); // creating new instance of Polygon Class.\nconsole.log(square.width); // prints '1' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":408,"description":"<p><a href=\"#/p5/for\">for</a> creates a loop that is useful for executing one\nsection of code multiple times.</p>\n<p>A 'for loop' consists of three different expressions inside of a parenthesis,\nall of which are optional.These expressions are used to control the number of\ntimes the loop is run.The first expression is a statement that is used to set\nthe initial state for the loop.The second expression is a condition that you\nwould like to check before each loop. If this expression returns false then\nthe loop will exit.The third expression is executed at the end of each loop.\nThese expression are separated by ; (semi-colon).In case of an empty expression,\nonly a semi-colon is written.</p>\n<p>The code inside of the loop body (in between the curly braces) is executed between the evaluation of the second\nand third expression.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. The test condition with a <a href=\"#/p5/for\">for</a> loop\nis the second expression detailed above. Ensuring that this expression can eventually\nbecome false ensures that your loop doesn't attempt to run an infinite amount of times,\nwhich can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for\">the MDN entry</a>:\nCreates a loop that executes a specified statement until the test condition evaluates to false.\nThe condition is evaluated after executing the statement, resulting in the specified statement executing at least once.</p>\n","itemtype":"property","name":"for","example":["\n<div class='norender'>\n<code>\nfor (let i = 0; i < 9; i++) {\n  console.log(i);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":448,"description":"<p><a href=\"#/p5/while\">while</a> creates a loop that is useful for executing\none section of code multiple times.</p>\n<p>With a 'while loop', the code inside of the loop body (between the curly\nbraces) is run repeatedly until the test condition (inside of the parenthesis)\nevaluates to false. The condition is tested before executing the code body\nwith <a href=\"#/p5/while\">while</a>, so if the condition is initially false\nthe loop body, or statement, will never execute.</p>\n<p>As with any loop, it is important to ensure that the loop can 'exit', or that\nthe test condition will eventually evaluate to false. This is to keep your loop\nfrom trying to run an infinite amount of times, which can crash your browser.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/while\">the MDN entry</a>:\nThe while statement creates a loop that executes a specified statement as long\nas the test condition evaluates to true.The condition is evaluated before\nexecuting the statement.</p>\n","itemtype":"property","name":"while","example":["\n<div class='norender'>\n<code>\n// This example logs the lines below to the console\n// 4\n// 3\n// 2\n// 1\n// 0\nlet num = 5;\nwhile (num > 0) {\n  num = num - 1;\n  console.log(num);\n}\n</code>\n</div>"],"alt":"This example does not render anything","class":"p5","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":490,"description":"<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify\">the MDN entry</a>:\nThe JSON.stringify() method converts a JavaScript object or value to a JSON <a href=\"#/p5/string\">string</a>.</p>\n","itemtype":"method","name":"stringify","static":1,"params":[{"name":"object","description":"<p>:Javascript object that you would like to convert to JSON</p>\n","type":"Object"}],"example":["\n<div class='norender'>\n<code>\nlet myObject = { x: 5, y: 6 };\nlet myObjectAsString = JSON.stringify(myObject);\nconsole.log(myObjectAsString); // prints \"{\"x\":5,\"y\":6}\" to the console\nconsole.log(typeof myObjectAsString); // prints 'string' to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"JSON","module":"Foundation","submodule":"Foundation"},{"file":"src/core/reference.js","line":512,"description":"<p>Prints a message to your browser's web console. When using p5, you can use <a href=\"#/p5/print\">print</a>\nand <a href=\"#/p5/console/log\">console.log</a> interchangeably.</p>\n<p>The console is opened differently depending on which browser you are using.\nHere are links on how to open the console in <a href=\"https://developer.mozilla.org/en-US/docs/Tools/Web_Console/Opening_the_Web_Console\">Firefox</a>\n, <a href=\"https://developers.google.com/web/tools/chrome-devtools/open\">Chrome</a>, <a href=\"https://docs.microsoft.com/en-us/microsoft-edge/devtools-guide/console\">Edge</a>,\nand <a href=\"https://support.apple.com/en-ca/guide/safari/sfri20948/mac\">Safari</a>.\nWith the <a href=\"https://editor.p5js.org/\">online p5 editor</a> the console\nis embedded directly in the page underneath the code editor.</p>\n<p>From <a href=\"https://developer.mozilla.org/en-US/docs/Web/API/Console/log\">the MDN entry</a>:\nThe Console method log() outputs a message to the web console. The message may\nbe a single <a href=\"#/p5/string\">string</a> (with optional substitution values),\nor it may be any one or more JavaScript <a href=\"#/p5/object\">objects</a>.</p>\n","itemtype":"method","name":"log","static":1,"params":[{"name":"message","description":"<p>:Message that you would like to print to the console</p>\n","type":"String|Expression|Object"}],"example":["\n<div class='norender'>\n<code>\nlet myNum = 5;\nconsole.log(myNum); // prints 5 to the console\nconsole.log(myNum + 12); // prints 17 to the console\n</code>\n</div>"],"alt":"This example does not render anything","class":"console","module":"Foundation","submodule":"Foundation"},{"file":"src/core/rendering.js","line":15,"description":"<p>Creates a canvas element in the document, and sets the dimensions of it\nin pixels. This method should be called only once at the start of setup.\nCalling <a href=\"#/p5/createCanvas\">createCanvas</a> more than once in a\nsketch will result in very unpredictable behavior. If you want more than\none drawing canvas you could use <a href=\"#/p5/createGraphics\">createGraphics</a>\n(hidden by default but it can be shown).</p>\n<p>Important note: in 2D mode (i.e. when <code>p5.Renderer</code> is not set) the origin (0,0)\nis positioned at the top left of the screen. In 3D mode (i.e. when <code>p5.Renderer</code>\nis set to <code>WEBGL</code>), the origin is positioned at the center of the canvas.\nSee <a href=\"https://github.com/processing/p5.js/issues/1545\">this issue</a> for more information.</p>\n<p>The system variables width and height are set by the parameters passed to this\nfunction. If <a href=\"#/p5/createCanvas\">createCanvas()</a> is not used, the\nwindow will be given a default size of 100×100 pixels.</p>\n<p>For more ways to position the canvas, see the\n<a href='https://github.com/processing/p5.js/wiki/Positioning-your-canvas'>\npositioning the canvas</a> wiki page.</p>\n","itemtype":"method","name":"createCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL</p>\n","type":"Constant","optional":true}],"return":{"description":"","type":"p5.Renderer"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 50);\n  background(153);\n  line(0, 0, width, height);\n}\n</code>\n</div>"],"alt":"Black line extending from top-left of canvas to bottom right.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":125,"description":"<p>Resizes the canvas to given width and height. The canvas will be cleared\nand draw will be called immediately, allowing the sketch to re-render itself\nin the resized canvas.</p>\n","itemtype":"method","name":"resizeCanvas","params":[{"name":"w","description":"<p>width of the canvas</p>\n","type":"Number"},{"name":"h","description":"<p>height of the canvas</p>\n","type":"Number"},{"name":"noRedraw","description":"<p>don't redraw the canvas immediately</p>\n","type":"Boolean","optional":true}],"example":["\n<div class=\"norender\"><code>\nfunction setup() {\n  createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n  background(0, 100, 200);\n}\n\nfunction windowResized() {\n  resizeCanvas(windowWidth, windowHeight);\n}\n</code></div>"],"alt":"No image displayed.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":183,"description":"<p>Removes the default canvas for a p5 sketch that doesn't require a canvas</p>\n","itemtype":"method","name":"noCanvas","example":["\n<div>\n<code>\nfunction setup() {\n  noCanvas();\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":204,"description":"<p>Creates and returns a new p5.Renderer object. Use this class if you need\nto draw into an off-screen graphics buffer. The two parameters define the\nwidth and height in pixels.</p>\n","itemtype":"method","name":"createGraphics","params":[{"name":"w","description":"<p>width of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"h","description":"<p>height of the offscreen graphics buffer</p>\n","type":"Number"},{"name":"renderer","description":"<p>either P2D or WEBGL\n                              undefined defaults to p2d</p>\n","type":"Constant","optional":true}],"return":{"description":"offscreen graphics buffer","type":"p5.Graphics"},"example":["\n<div>\n<code>\nlet pg;\nfunction setup() {\n  createCanvas(100, 100);\n  pg = createGraphics(100, 100);\n}\n\nfunction draw() {\n  background(200);\n  pg.background(100);\n  pg.noStroke();\n  pg.ellipse(pg.width / 2, pg.height / 2, 50, 50);\n  image(pg, 50, 50);\n  image(pg, 0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"4 grey squares alternating light and dark grey. White quarter circle mid-left.","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":243,"description":"<p>Blends the pixels in the display window according to the defined mode.\nThere is a choice of the following modes to blend the source pixels (A)\nwith the ones of pixels already in the display window (B):</p>\n<ul>\n<li><code>BLEND</code> - linear interpolation of colours: C =\nA*factor + B. <b>This is the default blending mode.</b></li>\n<li><code>ADD</code> - sum of A and B</li>\n<li><code>DARKEST</code> - only the darkest colour succeeds: C =\nmin(A*factor, B).</li>\n<li><code>LIGHTEST</code> - only the lightest colour succeeds: C =\nmax(A*factor, B).</li>\n<li><code>DIFFERENCE</code> - subtract colors from underlying image.</li>\n<li><code>EXCLUSION</code> - similar to <code>DIFFERENCE</code>, but less\nextreme.</li>\n<li><code>MULTIPLY</code> - multiply the colors, result will always be\ndarker.</li>\n<li><code>SCREEN</code> - opposite multiply, uses inverse values of the\ncolors.</li>\n<li><code>REPLACE</code> - the pixels entirely replace the others and\ndon't utilize alpha (transparency) values.</li>\n<li><code>REMOVE</code> - removes pixels from B with the alpha strength of A.</li>\n<li><code>OVERLAY</code> - mix of <code>MULTIPLY</code> and <code>SCREEN\n</code>. Multiplies dark values, and screens light values. <em>(2D)</em></li>\n<li><code>HARD_LIGHT</code> - <code>SCREEN</code> when greater than 50%\ngray, <code>MULTIPLY</code> when lower. <em>(2D)</em></li>\n<li><code>SOFT_LIGHT</code> - mix of <code>DARKEST</code> and\n<code>LIGHTEST</code>. Works like <code>OVERLAY</code>, but not as harsh. <em>(2D)</em>\n</li>\n<li><code>DODGE</code> - lightens light tones and increases contrast,\nignores darks. <em>(2D)</em></li>\n<li><code>BURN</code> - darker areas are applied, increasing contrast,\nignores lights. <em>(2D)</em></li>\n<li><code>SUBTRACT</code> - remainder of A and B <em>(3D)</em></li>\n</ul>\n\n<p><em>(2D)</em> indicates that this blend mode <b>only</b> works in the 2D renderer.<br>\n<em>(3D)</em> indicates that this blend mode <b>only</b> works in the WEBGL renderer.</p>\n","itemtype":"method","name":"blendMode","params":[{"name":"mode","description":"<p>blend mode to set for canvas.\n               either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n               EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n               SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nblendMode(LIGHTEST);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>\n\n<div>\n<code>\nblendMode(MULTIPLY);\nstrokeWeight(30);\nstroke(80, 150, 255);\nline(25, 25, 75, 75);\nstroke(255, 50, 50);\nline(75, 25, 25, 75);\n</code>\n</div>"],"alt":"translucent image thick red & blue diagonal rounded lines intersecting center\nThick red & blue diagonal rounded lines intersecting center. dark at overlap","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/rendering.js","line":326,"description":"<p>The p5.js API provides a lot of functionality for creating graphics, but there is\nsome native HTML5 Canvas functionality that is not exposed by p5. You can still call\nit directly using the variable <code>drawingContext</code>, as in the example shown. This is\nthe equivalent of calling <code>canvas.getContext('2d');</code> or <code>canvas.getContext('webgl');</code>.\nSee this\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D\">\nreference for the native canvas API</a> for possible drawing functions you can call.</p>\n","itemtype":"property","name":"drawingContext","example":["\n<div>\n<code>\nfunction setup() {\n  drawingContext.shadowOffsetX = 5;\n  drawingContext.shadowOffsetY = -5;\n  drawingContext.shadowBlur = 10;\n  drawingContext.shadowColor = 'black';\n  background(200);\n  ellipse(width / 2, height / 2, 50, 50);\n}\n</code>\n</div>"],"alt":"white ellipse with shadow blur effect around edges","class":"p5","module":"Rendering","submodule":"Rendering"},{"file":"src/core/shim.js","line":18,"description":"<p>shim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to <a href=\"http://halfpapstudios.com/blog/tag/html5-canvas/\">http://halfpapstudios.com/blog/tag/html5-canvas/</a>\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.</p>\n","class":"p5","module":"Rendering"},{"file":"src/core/shim.js","line":39,"description":"<p>this is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from <a href=\"https://github.com/ljharb/object.assign\">https://github.com/ljharb/object.assign</a></p>\n","class":"p5","module":"Rendering"},{"file":"src/core/structure.js","line":10,"description":"<p>Stops p5.js from continuously executing the code within <a href=\"#/p5/draw\">draw()</a>.\nIf <a href=\"#/p5/loop\">loop()</a> is called, the code in <a href=\"#/p5/draw\">draw()</a>\nbegins to run continuously again. If using <a href=\"#/p5/noLoop\">noLoop()</a>\nin <a href=\"#/p5/setup\">setup()</a>, it should be the last line inside the block.</p>\n<p>When <a href=\"#/p5/noLoop\">noLoop()</a> is used, it's not possible to manipulate\nor access the screen inside event handling functions such as\n<a href=\"#/p5/mousePressed\">mousePressed()</a> or\n<a href=\"#/p5/keyPressed\">keyPressed()</a>. Instead, use those functions to\ncall <a href=\"#/p5/redraw\">redraw()</a> or <a href=\"#/p5/loop\">loop()</a>,\nwhich will run <a href=\"#/p5/draw\">draw()</a>, which can update the screen\nproperly. This means that when <a href=\"#/p5/noLoop\">noLoop()</a> has been\ncalled, no drawing can happen, and functions like <a href=\"#/p5/saveFrames\">saveFrames()</a>\nor <a href=\"#/p5/loadPixels\">loadPixels()</a> may not be used.</p>\n<p>Note that if the sketch is resized, <a href=\"#/p5/redraw\">redraw()</a> will\nbe called to update the sketch, even after <a href=\"#/p5/noLoop\">noLoop()</a>\nhas been specified. Otherwise, the sketch would enter an odd state until\n<a href=\"#/p5/loop\">loop()</a> was called.</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"noLoop","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  noLoop();\n}\n\nfunction draw() {\n  line(10, 10, 90, 90);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  noLoop();\n}\n\nfunction mouseReleased() {\n  loop();\n}\n</code>\n</div>"],"alt":"113 pixel long line extending from top-left to bottom right of canvas.\nhorizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":83,"description":"<p>By default, p5.js loops through draw() continuously, executing the code within\nit. However, the <a href=\"#/p5/draw\">draw()</a> loop may be stopped by calling\n<a href=\"#/p5/noLoop\">noLoop()</a>. In that case, the <a href=\"#/p5/draw\">draw()</a>\nloop can be resumed with loop().</p>\n<p>Avoid calling loop() from inside setup().</p>\n<p>Use <a href=\"#/p5/isLooping\">isLooping()</a> to check current state of loop().</p>\n","itemtype":"method","name":"loop","example":["\n<div>\n<code>\nlet x = 0;\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x = x + 0.1;\n  if (x > width) {\n    x = 0;\n  }\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  loop();\n}\n\nfunction mouseReleased() {\n  noLoop();\n}\n</code>\n</div>"],"alt":"horizontal line moves slowly from left. Loops but stops on mouse press.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":134,"description":"<p>By default, p5.js loops through <a href=\"#/p5/draw\">draw()</a> continuously,\nexecuting the code within it. If the sketch is stopped with\n<a href=\"#/p5/noLoop\">noLoop()</a> or resumed with <a href=\"#/p5/loop\">loop()</a>,\nisLooping() returns the current state for use within custom event handlers.</p>\n","itemtype":"method","name":"isLooping","example":["\n<div>\n<code>\nlet checkbox, button, colBG, colFill;\n\nfunction setup() {\n  createCanvas(100, 100);\n\n  button = createButton('Colorize if loop()');\n  button.position(0, 120);\n  button.mousePressed(changeBG);\n\n  checkbox = createCheckbox('loop()', true);\n  checkbox.changed(checkLoop);\n\n  colBG = color(0);\n  colFill = color(255);\n}\n\nfunction changeBG() {\n  if (isLooping()) {\n    colBG = color(random(255), random(255), random(255));\n    colFill = color(random(255), random(255), random(255));\n  }\n}\n\nfunction checkLoop() {\n  if (this.checked()) {\n    loop();\n  } else {\n    noLoop();\n  }\n}\n\nfunction draw() {\n  background(colBG);\n  fill(colFill);\n  ellipse(frameCount % width, height / 2, 50);\n}\n</code>\n</div>"],"alt":"Ellipse moves slowly from left. Checkbox toggles loop()/noLoop().\nButton colorizes sketch if isLooping().","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":192,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores these\nsettings. Note that these functions are always used together. They allow you to\nchange the style and transformation settings and later return to what you had.\nWhen a new state is started with <a href=\"#/p5/push\">push()</a>, it builds on\nthe current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by the\nfollowing functions: <a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>, <a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a>\nand <a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"push","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\ntranslate(50, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":290,"description":"<p>The <a href=\"#/p5/push\">push()</a> function saves the current drawing style\nsettings and transformations, while <a href=\"#/p5/pop\">pop()</a> restores\nthese settings. Note that these functions are always used together. They allow\nyou to change the style and transformation settings and later return to what\nyou had. When a new state is started with <a href=\"#/p5/push\">push()</a>, it\nbuilds on the current style and transform information. The <a href=\"#/p5/push\">push()</a>\nand <a href=\"#/p5/pop\">pop()</a> functions can be embedded to provide more\ncontrol. (See the second example for a demonstration.)</p>\n<p><a href=\"#/p5/push\">push()</a> stores information related to the current transformation state\nand style settings controlled by the following functions:\n<a href=\"#/p5/fill\">fill()</a>,\n<a href=\"#/p5/noFill\">noFill()</a>,\n<a href=\"#/p5/noStroke\">noStroke()</a>,\n<a href=\"#/p5/stroke\">stroke()</a>,\n<a href=\"#/p5/tint\">tint()</a>,\n<a href=\"#/p5/noTint\">noTint()</a>,\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a>,\n<a href=\"#/p5/strokeCap\">strokeCap()</a>,\n<a href=\"#/p5/strokeJoin\">strokeJoin()</a>,\n<a href=\"#/p5/imageMode\">imageMode()</a>,\n<a href=\"#/p5/rectMode\">rectMode()</a>,\n<a href=\"#/p5/ellipseMode\">ellipseMode()</a>,\n<a href=\"#/p5/colorMode\">colorMode()</a>,\n<a href=\"#/p5/textAlign\">textAlign()</a>,\n<a href=\"#/p5/textFont\">textFont()</a>,\n<a href=\"#/p5/textSize\">textSize()</a>,\n<a href=\"#/p5/textLeading\">textLeading()</a>,\n<a href=\"#/p5/applyMatrix\">applyMatrix()</a>,\n<a href=\"#/p5/resetMatrix\">resetMatrix()</a>,\n<a href=\"#/p5/rotate\">rotate()</a>,\n<a href=\"#/p5/scale\">scale()</a>,\n<a href=\"#/p5/shearX\">shearX()</a>,\n<a href=\"#/p5/shearY\">shearY()</a>,\n<a href=\"#/p5/translate\">translate()</a>,\n<a href=\"#/p5/noiseSeed\">noiseSeed()</a>.</p>\n<p>In WEBGL mode additional style settings are stored. These are controlled by\nthe following functions:\n<a href=\"#/p5/setCamera\">setCamera()</a>,\n<a href=\"#/p5/ambientLight\">ambientLight()</a>,\n<a href=\"#/p5/directionalLight\">directionalLight()</a>,\n<a href=\"#/p5/pointLight\">pointLight()</a>,\n<a href=\"#/p5/texture\">texture()</a>,\n<a href=\"#/p5/specularMaterial\">specularMaterial()</a>,\n<a href=\"#/p5/shininess\">shininess()</a>,\n<a href=\"#/p5/normalMaterial\">normalMaterial()</a> and\n<a href=\"#/p5/shader\">shader()</a>.</p>\n","itemtype":"method","name":"pop","example":["\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\ntranslate(50, 0);\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(0, 50, 33, 33); // Middle circle\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>\n\n<div>\n<code>\nellipse(0, 50, 33, 33); // Left circle\n\npush(); // Start a new drawing state\nstrokeWeight(10);\nfill(204, 153, 0);\nellipse(33, 50, 33, 33); // Left-middle circle\n\npush(); // Start another new drawing state\nstroke(0, 102, 153);\nellipse(66, 50, 33, 33); // Right-middle circle\npop(); // Restore previous state\n\npop(); // Restore original state\n\nellipse(100, 50, 33, 33); // Right circle\n</code>\n</div>"],"alt":"Gold ellipse + thick black outline @center 2 white ellipses on left and right.\n2 Gold ellipses left black right blue stroke. 2 white ellipses on left+right.","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":391,"description":"<p>Executes the code within <a href=\"#/p5/draw\">draw()</a> one time. This\nfunction allows the program to update the display window only when necessary,\nfor example when an event registered by <a href=\"#/p5/mousePressed\">mousePressed()</a>\nor <a href=\"#/p5/keyPressed\">keyPressed()</a> occurs.</p>\n<p>In structuring a program, it only makes sense to call <a href=\"#/p5/redraw\">redraw()</a>\nwithin events such as <a href=\"#/p5/mousePressed\">mousePressed()</a>. This\nis because <a href=\"#/p5/redraw\">redraw()</a> does not run\n<a href=\"#/p5/draw\">draw()</a> immediately (it only sets a flag that indicates\nan update is needed).</p>\n<p>The <a href=\"#/p5/redraw\">redraw()</a> function does not work properly when\ncalled inside <a href=\"#/p5/draw\">draw()</a>.To enable/disable animations,\nuse <a href=\"#/p5/loop\">loop()</a> and <a href=\"#/p5/noLoop\">noLoop()</a>.</p>\n<p>In addition you can set the number of redraws per method call. Just\nadd an integer as single parameter for the number of redraws.</p>\n","itemtype":"method","name":"redraw","params":[{"name":"n","description":"<p>Redraw for n-times. The default value is 1.</p>\n","type":"Integer","optional":true}],"example":["\n<div><code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  x += 1;\n  redraw();\n}\n</code>\n</div>\n\n<div class='norender'>\n<code>\nlet x = 0;\n\nfunction setup() {\n  createCanvas(100, 100);\n  noLoop();\n}\n\nfunction draw() {\n  background(204);\n  x += 1;\n  line(x, 0, x, height);\n}\n\nfunction mousePressed() {\n  redraw(5);\n}\n</code>\n</div>"],"alt":"black line on far left of canvas\nblack line on far left of canvas","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/structure.js","line":497,"description":"<p>The <code>p5()</code> constructor enables you to activate \"instance mode\" instead of normal\n\"global mode\". This is an advanced topic. A short description and example is\nincluded below. Please see\n<a target=\"blank\" href=\"https://www.youtube.com/watch?v=Su792jEauZg&feature=youtu.be\">\nDan Shiffman's Coding Train video tutorial</a> or this\n<a target=\"blank\" href=\"https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace\">tutorial page</a>\nfor more info.</p>\n<p>By default, all p5.js functions are in the global namespace (i.e. bound to the window\nobject), meaning you can call them simply <code>ellipse()</code>, <code>fill()</code>, etc. However, this\nmight be inconvenient if you are mixing with other JS libraries (synchronously or\nasynchronously) or writing long programs of your own. p5.js currently supports a\nway around this problem called \"instance mode\". In instance mode, all p5 functions\nare bound up in a single variable instead of polluting your global namespace.</p>\n<p>Optionally, you can specify a default container for the canvas and any other elements\nto append to with a second argument. You can give the ID of an element in your html,\nor an html node itself.</p>\n<p>Note that creating instances like this also allows you to have more than one p5 sketch on\na single web page, as they will each be wrapped up with their own set up variables. Of\ncourse, you could also use iframes to have multiple sketches in global mode.</p>\n","itemtype":"method","name":"p5","params":[{"name":"sketch","description":"<p>a function containing a p5.js sketch</p>\n","type":"Object"},{"name":"node","description":"<p>ID or pointer to HTML DOM node to contain sketch in</p>\n","type":"String|Object"}],"example":["\n<div class='norender'><code>\nconst s = p => {\n  let x = 100;\n  let y = 100;\n\n  p.setup = function() {\n    p.createCanvas(700, 410);\n  };\n\n  p.draw = function() {\n    p.background(0);\n    p.fill(255);\n    p.rect(x, y, 50, 50);\n  };\n};\n\nnew p5(s); // invoke p5\n</code></div>"],"alt":"white rectangle on black background","class":"p5","module":"Structure","submodule":"Structure"},{"file":"src/core/transform.js","line":11,"description":"<p>Multiplies the current matrix by the one specified through the parameters.\nThis is a powerful operation that can perform the equivalent of translate,\nscale, shear and rotate all at once. You can learn more about transformation\nmatrices on <a href=\"https://en.wikipedia.org/wiki/Transformation_matrix\">\nWikipedia</a>.</p>\n<p>The naming of the arguments here follows the naming of the <a href=\n\"https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform\">\nWHATWG specification</a> and corresponds to a\ntransformation matrix of the\nform:</p>\n<blockquote>\n<p><img style=\"max-width: 150px\" src=\"assets/transformation-matrix.png\"\nalt=\"The transformation matrix used when applyMatrix is called\"/></p>\n</blockquote>\n","itemtype":"method","name":"applyMatrix","params":[{"name":"a","description":"<p>numbers which define the 2×3 matrix to be multiplied, or an array of numbers</p>\n","type":"Number|Array"},{"name":"b","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"c","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"d","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"e","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"},{"name":"f","description":"<p>numbers which define the 2×3 matrix to be multiplied</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  // Equivalent to translate(x, y);\n  applyMatrix(1, 0, 0, 1, 40 + step, 50);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  background(200);\n  translate(50, 50);\n  // Equivalent to scale(x, y);\n  applyMatrix(1 / step, 0, 0, 1 / step, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, 0, TWO_PI);\n  let cos_a = cos(angle);\n  let sin_a = sin(angle);\n  background(200);\n  translate(50, 50);\n  // Equivalent to rotate(angle);\n  applyMatrix(cos_a, sin_a, -sin_a, cos_a, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(10);\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  let step = frameCount % 20;\n  let angle = map(step, 0, 20, -PI / 4, PI / 4);\n  background(200);\n  translate(50, 50);\n  // equivalent to shearX(angle);\n  let shear_factor = 1 / tan(PI / 2 - angle);\n  applyMatrix(1, 0, shear_factor, 1, 0, 0);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  rotateY(PI / 6);\n  stroke(153);\n  box(35);\n  let rad = millis() / 1000;\n  // Set rotation angles\n  let ct = cos(rad);\n  let st = sin(rad);\n  // Matrix for rotation around the Y axis\n  applyMatrix(  ct, 0.0,  st,  0.0,\n               0.0, 1.0, 0.0,  0.0,\n               -st, 0.0,  ct,  0.0,\n               0.0, 0.0, 0.0,  1.0);\n  stroke(255);\n  box(50);\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  let testMatrix = [1, 0, 0, 1, 0, 0];\n  applyMatrix(testMatrix);\n  rect(0, 0, 50, 50);\n}\n</code>\n</div>"],"alt":"A rectangle translating to the right\nA rectangle shrinking to the center\nA rectangle rotating clockwise about the center\nA rectangle shearing\nA rectangle in the upper left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":168,"description":"<p>Replaces the current matrix with the identity matrix.</p>\n","itemtype":"method","name":"resetMatrix","chainable":1,"example":["\n<div>\n<code>\ntranslate(50, 50);\napplyMatrix(0.5, 0.5, -0.5, 0.5, 0, 0);\nrect(0, 0, 20, 20);\n// Note that the translate is also reset.\nresetMatrix();\nrect(0, 0, 20, 20);\n</code>\n</div>"],"alt":"A rotated rectangle in the center with another at the top left corner","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":193,"description":"<p>Rotates a shape by the amount specified by the angle parameter. This\nfunction accounts for <a href=\"#/p5/angleMode\">angleMode</a>, so angles\ncan be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nTransformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nrotate(HALF_PI) and then rotate(HALF_PI) is the same as rotate(PI).\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n<p>Technically, <a href=\"#/p5/rotate\">rotate()</a> multiplies the current transformation matrix\nby a rotation matrix. This function can be further controlled by\nthe <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"rotate","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"},{"name":"axis","description":"<p>(in 3d) the axis to rotate around</p>\n","type":"p5.Vector|Number[]","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 2, height / 2);\nrotate(PI / 3.0);\nrect(-26, -26, 52, 52);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":232,"description":"<p>Rotates a shape around X axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateX","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateX(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the x axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":268,"description":"<p>Rotates a shape around Y axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateY","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateY(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the y axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":304,"description":"<p>Rotates a shape around Z axis by the amount specified in angle parameter.\nThe angles can be entered in either RADIANS or DEGREES.</p>\n<p>This method works in WEBGL mode only.</p>\n<p>Objects are always rotated around their relative position to the\norigin and positive numbers rotate objects in a clockwise direction.\nAll transformations are reset when <a href=\"#/p5/draw\">draw()</a> begins again.</p>\n","itemtype":"method","name":"rotateZ","params":[{"name":"angle","description":"<p>the angle of rotation, specified in radians\n                       or degrees, depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(255);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"3d box rotating around the z axis.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":342,"description":"<p>Increases or decreases the size of a shape by expanding or contracting\nvertices. Objects always scale from their relative origin to the\ncoordinate system. Scale values are specified as decimal percentages.\nFor example, the function call scale(2.0) increases the dimension of a\nshape by 200%.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function multiply the effect. For example, calling scale(2.0)\nand then scale(1.5) is the same as scale(3.0). If <a href=\"#/p5/scale\">scale()</a> is called\nwithin <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when the loop begins again.</p>\n<p>Using this function with the z parameter is only available in WEBGL mode.\nThis function can be further controlled with <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"scale","chainable":1,"example":["\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5);\nrect(30, 20, 50, 50);\n</code>\n</div>\n\n<div>\n<code>\nrect(30, 20, 50, 50);\nscale(0.5, 1.3);\nrect(30, 20, 50, 50);\n</code>\n</div>"],"alt":"white 52×52 rect with black outline at center rotated counter 45 degrees\n2 white rects with black outline- 1 50×50 at center. other 25×65 bottom left","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":342,"params":[{"name":"s","description":"<p>percent to scale the object, or percentage to\n                     scale the object in the x-axis if multiple arguments\n                     are given</p>\n","type":"Number|p5.Vector|Number[]"},{"name":"y","description":"<p>percent to scale the object in the y-axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>percent to scale the object in the z-axis (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":386,"params":[{"name":"scales","description":"<p>per-axis percents to scale the object</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/core/transform.js","line":416,"description":"<p>Shears a shape around the x-axis by the amount specified by the angle\nparameter. Angles should be specified in the current angleMode.\nObjects are always sheared around their relative position to the origin\nand positive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearX(PI/2) and then shearX(PI/2) is the same as shearX(PI).\nIf <a href=\"#/p5/shearX\">shearX()</a> is called within the <a href=\"#/p5/draw\">draw()</a>,\nthe transformation is reset when the loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearX\">shearX()</a> multiplies the current\ntransformation matrix by a rotation matrix. This function can be further\ncontrolled by the <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearX","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearX(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at top middle.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":455,"description":"<p>Shears a shape around the y-axis the amount specified by the angle\nparameter. Angles should be specified in the current angleMode. Objects\nare always sheared around their relative position to the origin and\npositive numbers shear objects in a clockwise direction.</p>\n<p>Transformations apply to everything that happens after and subsequent\ncalls to the function accumulates the effect. For example, calling\nshearY(PI/2) and then shearY(PI/2) is the same as shearY(PI). If\n<a href=\"#/p5/shearY\">shearY()</a> is called within the <a href=\"#/p5/draw\">draw()</a>, the transformation is reset when\nthe loop begins again.</p>\n<p>Technically, <a href=\"#/p5/shearY\">shearY()</a> multiplies the current transformation matrix by a\nrotation matrix. This function can be further controlled by the\n<a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a> functions.</p>\n","itemtype":"method","name":"shearY","params":[{"name":"angle","description":"<p>angle of shear specified in radians or degrees,\n                       depending on current angleMode</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\ntranslate(width / 4, height / 4);\nshearY(PI / 4.0);\nrect(0, 0, 30, 30);\n</code>\n</div>"],"alt":"white irregular quadrilateral with black outline at middle bottom.","class":"p5","module":"Transform","submodule":"Transform"},{"file":"src/core/transform.js","line":494,"description":"<p>Specifies an amount to displace objects within the display window.\nThe x parameter specifies left/right translation, the y parameter\nspecifies up/down translation.</p>\n<p>Transformations are cumulative and apply to everything that happens after\nand subsequent calls to the function accumulates the effect. For example,\ncalling translate(50, 0) and then translate(20, 0) is the same as\ntranslate(70, 0). If <a href=\"#/p5/translate\">translate()</a> is called within <a href=\"#/p5/draw\">draw()</a>, the\ntransformation is reset when the loop begins again. This function can be\nfurther controlled by using <a href=\"#/p5/push\">push()</a> and <a href=\"#/p5/pop\">pop()</a>.</p>\n","itemtype":"method","name":"translate","chainable":1,"example":["\n<div>\n<code>\ntranslate(30, 20);\nrect(0, 0, 55, 55);\n</code>\n</div>\n\n<div>\n<code>\nrect(0, 0, 55, 55); // Draw rect at original 0,0\ntranslate(30, 20);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\ntranslate(14, 14);\nrect(0, 0, 55, 55); // Draw rect at new 0,0\n</code>\n</div>\n\n\n<div>\n<code>\nfunction draw() {\n  background(200);\n  rectMode(CENTER);\n  translate(width / 2, height / 2);\n  translate(p5.Vector.fromAngle(millis() / 1000, 40));\n  rect(0, 0, 20, 20);\n}\n</code>\n</div>"],"alt":"white 55×55 rect with black outline at center right.\n3 white 55×55 rects with black outlines at top-l, center-r and bottom-r.\na 20×20 white rect moving in a circle around the canvas","class":"p5","module":"Transform","submodule":"Transform","overloads":[{"line":494,"params":[{"name":"x","description":"<p>left/right translation</p>\n","type":"Number"},{"name":"y","description":"<p>up/down translation</p>\n","type":"Number"},{"name":"z","description":"<p>forward/backward translation (webgl only)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":547,"params":[{"name":"vector","description":"<p>the vector to translate by</p>\n","type":"p5.Vector"}],"chainable":1}]},{"file":"src/data/local_storage.js","line":10,"description":"<p>Stores a value in local storage under the key name.\n Local storage is saved in the browser and persists\n between browsing sessions and page reloads.\n The key can be the name of the variable but doesn't\n have to be. To retrieve stored items\n see <a href=\"#/p5/getItem\">getItem</a>.\nSensitive data such as passwords or personal information\n should not be stored in local storage.</p>\n","itemtype":"method","name":"storeItem","params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String|Number|Object|Boolean|p5.Color|p5.Vector"}],"example":["\n <div><code>\n // Type to change the letter in the\n // center of the canvas.\n // If you reload the page, it will\n // still display the last key you entered\nlet myText;\nfunction setup() {\n   createCanvas(100, 100);\n   myText = getItem('myText');\n   if (myText === null) {\n     myText = '';\n   }\n }\nfunction draw() {\n   textSize(40);\n   background(255);\n   text(myText, width / 2, height / 2);\n }\nfunction keyPressed() {\n   myText = key;\n   storeItem('myText', myText);\n }\n </code></div>"],"alt":"When you type the key name is displayed as black text on white background.\n If you reload the page, the last letter typed is still displaying.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":101,"description":"<p>Returns the value of an item that was stored in local storage\n using storeItem()</p>\n","itemtype":"method","name":"getItem","params":[{"name":"key","description":"<p>name that you wish to use to store in local storage</p>\n","type":"String"}],"return":{"description":"Value of stored item","type":"Number|Object|String|Boolean|p5.Color|p5.Vector"},"example":["\n <div><code>\n // Click the mouse to change\n // the color of the background\n // Once you have changed the color\n // it will stay changed even when you\n // reload the page.\nlet myColor;\nfunction setup() {\n   createCanvas(100, 100);\n   myColor = getItem('myColor');\n }\nfunction draw() {\n   if (myColor !== null) {\n     background(myColor);\n   }\n }\nfunction mousePressed() {\n   myColor = color(random(255), random(255), random(255));\n   storeItem('myColor', myColor);\n }\n </code></div>"],"alt":"If you click, the canvas changes to a random color.\n If you reload the page, the canvas is still the color it\n was when the page was previously loaded.","class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":177,"description":"<p>Clears all local storage items set with storeItem()\n for the current domain.</p>\n","itemtype":"method","name":"clearStorage","example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myNum = 10;\n   let myBool = false;\n   storeItem('myNum', myNum);\n   storeItem('myBool', myBool);\n   print(getItem('myNum')); // logs 10 to the console\n   print(getItem('myBool')); // logs false to the console\n   clearStorage();\n   print(getItem('myNum')); // logs null to the console\n   print(getItem('myBool')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/local_storage.js","line":205,"description":"<p>Removes an item that was stored with storeItem()</p>\n","itemtype":"method","name":"removeItem","params":[{"name":"key","description":"","type":"String"}],"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myVar = 10;\n   storeItem('myVar', myVar);\n   print(getItem('myVar')); // logs 10 to the console\n   removeItem('myVar');\n   print(getItem('myVar')); // logs null to the console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"LocalStorage"},{"file":"src/data/p5.TypedDict.js","line":14,"description":"<p>Creates a new instance of p5.StringDict using the key-value pair\n or the object you provide.</p>\n","itemtype":"method","name":"createStringDict","return":{"description":"","type":"p5.StringDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createStringDict('p5', 'js');\n   print(myDictionary.hasKey('p5')); // logs true to console\n  let anotherDictionary = createStringDict({ happy: 'coding' });\n   print(anotherDictionary.hasKey('happy')); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":14,"params":[{"name":"key","description":"","type":"String"},{"name":"value","description":"","type":"String"}],"return":{"description":"","type":"p5.StringDict"}},{"line":37,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.StringDict"}}]},{"file":"src/data/p5.TypedDict.js","line":48,"description":"<p>Creates a new instance of <a href=\"#/p5.NumberDict\">p5.NumberDict</a> using the key-value pair\n or object you provide.</p>\n","itemtype":"method","name":"createNumberDict","return":{"description":"","type":"p5.NumberDict"},"example":["\n <div class=\"norender\">\n <code>\n function setup() {\n   let myDictionary = createNumberDict(100, 42);\n   print(myDictionary.hasKey(100)); // logs true to console\n  let anotherDictionary = createNumberDict({ 200: 84 });\n   print(anotherDictionary.hasKey(200)); // logs true to console\n }\n </code></div>"],"class":"p5","module":"Data","submodule":"Dictionary","overloads":[{"line":48,"params":[{"name":"key","description":"","type":"Number"},{"name":"value","description":"","type":"Number"}],"return":{"description":"","type":"p5.NumberDict"}},{"line":71,"params":[{"name":"object","description":"<p>object</p>\n","type":"Object"}],"return":{"description":"","type":"p5.NumberDict"}}]},{"file":"src/data/p5.TypedDict.js","line":101,"description":"<p>Returns the number of key-value pairs currently stored in the Dictionary.</p>\n","itemtype":"method","name":"size","return":{"description":"the number of key-value pairs in the Dictionary","type":"Integer"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(1, 10);\n  myDictionary.create(2, 20);\n  myDictionary.create(3, 30);\n  print(myDictionary.size()); // logs 3 to the console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":122,"description":"<p>Returns true if the given key exists in the Dictionary,\notherwise returns false.</p>\n","itemtype":"method","name":"hasKey","params":[{"name":"key","description":"<p>that you want to look up</p>\n","type":"Number|String"}],"return":{"description":"whether that key exists in Dictionary","type":"Boolean"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":144,"description":"<p>Returns the value stored at the given key.</p>\n","itemtype":"method","name":"get","params":[{"name":"the","description":"<p>key you want to access</p>\n","type":"Number|String"}],"return":{"description":"the value stored at that key","type":"Number|String"},"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  let myValue = myDictionary.get('p5');\n  print(myValue === 'js'); // logs true to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":170,"description":"<p>Updates the value associated with the given key in case it already exists\nin the Dictionary. Otherwise a new key-value pair is added.</p>\n","itemtype":"method","name":"set","params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.set('p5', 'JS');\n  myDictionary.print(); // logs \"key: p5 - value: JS\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":197,"description":"<p>private helper function to handle the user passing in objects\nduring construction or calls to create()</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":208,"description":"<p>Creates a new key-value pair in the Dictionary.</p>\n","itemtype":"method","name":"create","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary","overloads":[{"line":208,"params":[{"name":"key","description":"","type":"Number|String"},{"name":"value","description":"","type":"Number|String"}]},{"line":226,"params":[{"name":"obj","description":"<p>key/value pair</p>\n","type":"Object"}]}]},{"file":"src/data/p5.TypedDict.js","line":244,"description":"<p>Removes all previously stored key-value pairs from the Dictionary.</p>\n","itemtype":"method","name":"clear","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  print(myDictionary.hasKey('p5')); // prints 'true'\n  myDictionary.clear();\n  print(myDictionary.hasKey('p5')); // prints 'false'\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":265,"description":"<p>Removes the key-value pair stored at the given key from the Dictionary.</p>\n","itemtype":"method","name":"remove","params":[{"name":"key","description":"<p>for the pair to remove</p>\n","type":"Number|String"}],"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n  myDictionary.remove('p5');\n  myDictionary.print();\n  // above logs \"key: happy value: coding\" to console\n}\n</code></div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":294,"description":"<p>Logs the set of items currently stored in the Dictionary to the console.</p>\n","itemtype":"method","name":"print","example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let myDictionary = createStringDict('p5', 'js');\n  myDictionary.create('happy', 'coding');\n  myDictionary.print();\n  // above logs \"key: p5 - value: js, key: happy - value: coding\" to console\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":318,"description":"<p>Converts the Dictionary into a CSV file for local download.</p>\n","itemtype":"method","name":"saveTable","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveTable('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":356,"description":"<p>Converts the Dictionary into a JSON file for local download.</p>\n","itemtype":"method","name":"saveJSON","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    createStringDict({\n      john: 1940,\n      paul: 1942,\n      george: 1943,\n      ringo: 1940\n    }).saveJSON('beatles');\n  }\n}\n</code>\n</div>"],"class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":387,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.TypedDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":425,"description":"<p>private helper function to ensure that the user passed in valid\nvalues for the Dictionary type</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":432,"description":"<p>Add the given number to the value currently stored at the given key.\nThe sum then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"add","params":[{"name":"Key","description":"<p>for the value you wish to add to</p>\n","type":"Number"},{"name":"Number","description":"<p>to add to the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.add(2, 2);\n  print(myDictionary.get(2)); // logs 7 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":459,"description":"<p>Subtract the given number from the value currently stored at the given key.\nThe difference then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"sub","params":[{"name":"Key","description":"<p>for the value you wish to subtract from</p>\n","type":"Number"},{"name":"Number","description":"<p>to subtract from the value</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 5);\n  myDictionary.sub(2, 2);\n  print(myDictionary.get(2)); // logs 3 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":482,"description":"<p>Multiply the given number with the value currently stored at the given key.\nThe product then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"mult","params":[{"name":"Key","description":"<p>for value you wish to multiply</p>\n","type":"Number"},{"name":"Amount","description":"<p>to multiply the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 4);\n  myDictionary.mult(2, 2);\n  print(myDictionary.get(2)); // logs 8 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":509,"description":"<p>Divide the given number with the value currently stored at the given key.\nThe quotient then replaces the value previously stored in the Dictionary.</p>\n","itemtype":"method","name":"div","params":[{"name":"Key","description":"<p>for value you wish to divide</p>\n","type":"Number"},{"name":"Amount","description":"<p>to divide the value by</p>\n","type":"Number"}],"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict(2, 8);\n  myDictionary.div(2, 2);\n  print(myDictionary.get(2)); // logs 4 to console.\n}\n</code></div>\n"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":536,"description":"<p>private helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":560,"description":"<p>Return the lowest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"minValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let lowestValue = myDictionary.minValue(); // value is -10\n  print(lowestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":580,"description":"<p>Return the highest number currently stored in the Dictionary.</p>\n","itemtype":"method","name":"maxValue","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: -10, 4: 0.65, 1.2: 3 });\n  let highestValue = myDictionary.maxValue(); // value is 3\n  print(highestValue);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":600,"description":"<p>private helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'</p>\n","class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":622,"description":"<p>Return the lowest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"minKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let lowestKey = myDictionary.minKey(); // value is 1.2\n  print(lowestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/data/p5.TypedDict.js","line":642,"description":"<p>Return the highest key currently used in the Dictionary.</p>\n","itemtype":"method","name":"maxKey","return":{"description":"","type":"Number"},"example":["\n<div class='norender'>\n<code>\nfunction setup() {\n  let myDictionary = createNumberDict({ 2: 4, 4: 6, 1.2: 3 });\n  let highestKey = myDictionary.maxKey(); // value is 4\n  print(highestKey);\n}\n</code></div>"],"class":"p5.NumberDict","module":"Data","submodule":"Dictionary"},{"file":"src/dom/dom.js","line":21,"description":"<p>Searches the page for the first element that matches the given CSS selector string (can be an\nID, class, tag name or a combination) and returns it as a <a href=\"#/p5.Element\">p5.Element</a>.\nThe DOM node itself can be accessed with .elt.\nReturns null if none found. You can also specify a container to search within.</p>\n","itemtype":"method","name":"select","params":[{"name":"selectors","description":"<p>CSS selector string of element to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>, or\n                                            HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"<a href=\"#/p5.Element\">p5.Element</a> containing node found","type":"p5.Element|null"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(50, 50);\n  background(30);\n  // move canvas down and right\n  select('canvas').position(10, 30);\n}\n</code></div>\n\n<div class=\"norender\"><code>\n// select using ID\nlet a = select('#container');\nlet b = select('#beep', '#container');\nlet c;\nif (a) {\n  // select using class\n  c = select('.boop', a);\n}\n// select using CSS selector string\nlet d = select('#container #bleep');\nlet e = select('#container p');\n[a, b, c, d, e]; // unused\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":68,"description":"<p>Searches the page for elements that match the given CSS selector string (can be an ID a class,\ntag name or a combination) and returns them as <a href=\"#/p5.Element\">p5.Element</a>s in\nan array.\nThe DOM node itself can be accessed with .elt.\nReturns an empty array if none found.\nYou can also specify a container to search within.</p>\n","itemtype":"method","name":"selectAll","params":[{"name":"selectors","description":"<p>CSS selector string of elements to search for</p>\n","type":"String"},{"name":"container","description":"<p>CSS selector string, <a href=\"#/p5.Element\">p5.Element</a>\n                                            , or HTML element to search within</p>\n","type":"String|p5.Element|HTMLElement","optional":true}],"return":{"description":"Array of <a href=\"#/p5.Element\">p5.Element</a>s containing nodes found","type":"p5.Element[]"},"example":["\n<div><code>\nfunction setup() {\n  createButton('btn');\n  createButton('2nd btn');\n  createButton('3rd btn');\n  let buttons = selectAll('button');\n\n  for (let i = 0; i < 3; i++) {\n    buttons[i].size(100);\n    buttons[i].position(0, i * 30);\n  }\n}\n</code></div>\n<div><code>\n// these are all valid calls to selectAll()\nlet a = selectAll('.beep');\na = selectAll('div');\na = selectAll('button', '#container');\n\nlet b = createDiv();\nb.id('container');\nlet c = select('#container');\na = selectAll('p', c);\na = selectAll('#container p');\n\nlet d = document.getElementById('container');\na = selectAll('.boop', d);\na = selectAll('#container .boop');\nconsole.log(a);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":127,"description":"<p>Helper function for select and selectAll</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":142,"description":"<p>Helper function for getElement and getElements.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":176,"description":"<p>Removes all elements created by p5, except any canvas / graphics\nelements created by <a href=\"#/p5/createCanvas\">createCanvas</a> or <a href=\"#/p5/createGraphics\">createGraphics</a>.\nEvent handlers are removed, and element is removed from the DOM.</p>\n","itemtype":"method","name":"removeElements","example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let div = createDiv('this is some text');\n  let p = createP('this is a paragraph');\n  div.style('font-size', '16px');\n  p.style('font-size', '16px');\n}\nfunction mousePressed() {\n  removeElements(); // this will remove the div and p, not canvas\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":204,"description":"<p>The .<a href=\"#/p5.Element/changed\">changed()</a> function is called when the value of an\nelement changes.\nThis can be used to attach an element specific event listener.</p>\n","itemtype":"method","name":"changed","params":[{"name":"fxn","description":"<p>function to be fired when the value of\n                               an element changes.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text(\"it's a \" + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet checkbox;\nlet cnv;\n\nfunction setup() {\n  checkbox = createCheckbox(' fill');\n  checkbox.changed(changeFill);\n  cnv = createCanvas(100, 100);\n  cnv.position(0, 30);\n  noFill();\n}\n\nfunction draw() {\n  background(200);\n  ellipse(50, 50, 50, 50);\n}\n\nfunction changeFill() {\n  if (checkbox.checked()) {\n    fill(0);\n  } else {\n    noFill();\n  }\n}\n</code></div>"],"alt":"dropdown: pear, kiwi, grape. When selected text \"it's a\" + selection shown.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":271,"description":"<p>The .<a href=\"#/p5.Element/input\">input()</a> function is called when any user input is\ndetected with an element. The input event is often used\nto detect keystrokes in a input element, or changes on a\nslider element. This can be used to attach an element specific\nevent listener.</p>\n","itemtype":"method","name":"input","params":[{"name":"fxn","description":"<p>function to be fired when any user input is\n                               detected within the element.\n                               if <code>false</code> is passed instead, the previously\n                               firing function will no longer fire.</p>\n","type":"Function|Boolean"}],"chainable":1,"example":["\n<div><code>\n// Open your console to see the output\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"alt":"no display.","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":309,"description":"<p>Helpers for create methods.</p>\n","class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":322,"description":"<p>Creates a <code>&lt;div&gt;&lt;/div&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createDiv","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet div = createDiv('this is some text');\ndiv.style('font-size', '16px');\ndiv.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":341,"description":"<p>Creates a <code>&lt;p&gt;&lt;/p&gt;</code> element in the DOM with given inner HTML. Used\nfor paragraph length text.</p>\n","itemtype":"method","name":"createP","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet p = createP('this is some text');\np.style('font-size', '16px');\np.position(10, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":361,"description":"<p>Creates a <code>&lt;span&gt;&lt;/span&gt;</code> element in the DOM with given inner HTML.</p>\n","itemtype":"method","name":"createSpan","params":[{"name":"html","description":"<p>inner HTML for element created</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet span = createSpan('this is some text');\nspan.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":379,"description":"<p>Creates an <code>&lt;img&gt;</code> element in the DOM with given src and\nalternate text.</p>\n","itemtype":"method","name":"createImg","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n <div><code>\nlet img = createImg(\n  'https://p5js.org/assets/img/asterisk-01.png',\n  'the p5 magenta asterisk'\n);\nimg.position(0, -10);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":379,"params":[{"name":"src","description":"<p>src path or url for image</p>\n","type":"String"},{"name":"alt","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes\">alternate text</a> to be used if image does not load. You can use also an empty string (<code>\"\"</code>) if that an image is not intended to be viewed.</p>\n","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":396,"params":[{"name":"src","description":"","type":"String"},{"name":"alt","description":"","type":"String"},{"name":"crossOrigin","description":"<p><a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes\">crossOrigin property</a> of the <code>img</code> element; use either 'anonymous' or 'use-credentials' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>\"\"</code>) is passed, CORS is not used</p>\n","type":"String"},{"name":"successCallback","description":"<p>callback to be called once image data is loaded with the <a href=\"#/p5.Element\">p5.Element</a> as argument</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":426,"description":"<p>Creates an <code>&lt;a&gt;&lt;/a&gt;</code> element in the DOM for including a hyperlink.</p>\n","itemtype":"method","name":"createA","params":[{"name":"href","description":"<p>url of page to link to</p>\n","type":"String"},{"name":"html","description":"<p>inner html of link element to display</p>\n","type":"String"},{"name":"target","description":"<p>target where new link should open,\n                            could be _blank, _self, _parent, _top.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet a = createA('http://p5js.org/', 'this is a link');\na.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":450,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":452,"description":"<p>Creates a slider <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nUse .size() to set the display length of the slider.</p>\n","itemtype":"method","name":"createSlider","params":[{"name":"min","description":"<p>minimum value of the slider</p>\n","type":"Number"},{"name":"max","description":"<p>maximum value of the slider</p>\n","type":"Number"},{"name":"value","description":"<p>default value of the slider</p>\n","type":"Number","optional":true},{"name":"step","description":"<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n","type":"Number","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet slider;\nfunction setup() {\n  slider = createSlider(0, 255, 100);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val);\n}\n</code></div>\n\n<div><code>\nlet slider;\nfunction setup() {\n  colorMode(HSB);\n  slider = createSlider(0, 360, 60, 40);\n  slider.position(10, 10);\n  slider.style('width', '80px');\n}\n\nfunction draw() {\n  let val = slider.value();\n  background(val, 100, 100, 1);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":507,"description":"<p>Creates a <code>&lt;button&gt;&lt;/button&gt;</code> element in the DOM.\nUse .size() to set the display size of the button.\nUse .mousePressed() to specify behavior on press.</p>\n","itemtype":"method","name":"createButton","params":[{"name":"label","description":"<p>label displayed on the button</p>\n","type":"String"},{"name":"value","description":"<p>value of the button</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet button;\nfunction setup() {\n  createCanvas(100, 100);\n  background(0);\n  button = createButton('click me');\n  button.position(0, 0);\n  button.mousePressed(changeBG);\n}\n\nfunction changeBG() {\n  let val = random(255);\n  background(val);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":541,"description":"<p>Creates a checkbox <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM.\nCalling .checked() on a checkbox returns if it is checked or not</p>\n","itemtype":"method","name":"createCheckbox","params":[{"name":"label","description":"<p>label displayed after checkbox</p>\n","type":"String","optional":true},{"name":"value","description":"<p>value of the checkbox; checked is true, unchecked is false</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet checkbox;\n\nfunction setup() {\n  checkbox = createCheckbox('label', false);\n  checkbox.changed(myCheckedEvent);\n}\n\nfunction myCheckedEvent() {\n  if (checkbox.checked()) {\n    console.log('Checking!');\n  } else {\n    console.log('Unchecking!');\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":622,"description":"<p>Creates a dropdown menu <code>&lt;select&gt;&lt;/select&gt;</code> element in the DOM.\nIt also helps to assign select-box methods to <a href=\"#/p5.Element\">p5.Element</a> when selecting existing select box.</p>\n<ul>\n<li><code>.option(name, [value])</code> can be used to set options for the select after it is created.</li>\n<li><code>.value()</code> will return the currently selected option.</li>\n<li><code>.selected()</code> will return current dropdown element which is an instance of <a href=\"#/p5.Element\">p5.Element</a></li>\n<li><code>.selected(value)</code> can be used to make given option selected by default when the page first loads.</li>\n<li><code>.disable()</code> marks whole of dropdown element as disabled.</li>\n<li><code>.disable(value)</code> marks given option as disabled</li>\n</ul>\n","itemtype":"method","name":"createSelect","return":{"description":"","type":"p5.Element"},"example":["\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('pear');\n  sel.option('kiwi');\n  sel.option('grape');\n  sel.selected('kiwi');\n  sel.changed(mySelectEvent);\n}\n\nfunction mySelectEvent() {\n  let item = sel.value();\n  background(200);\n  text('It is a ' + item + '!', 50, 50);\n}\n</code></div>\n\n<div><code>\nlet sel;\n\nfunction setup() {\n  textAlign(CENTER);\n  background(200);\n  sel = createSelect();\n  sel.position(10, 10);\n  sel.option('oil');\n  sel.option('milk');\n  sel.option('bread');\n  sel.disable('milk');\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":622,"params":[{"name":"multiple","description":"<p>true if dropdown should support multiple selections</p>\n","type":"Boolean","optional":true}],"return":{"description":"","type":"p5.Element"}},{"line":673,"params":[{"name":"existing","description":"<p>DOM select element</p>\n","type":"Object"}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":770,"description":"<p>Creates a radio button element in the DOM.It also helps existing radio buttons\nassign methods of <a href=\"#/p5.Element/\">p5.Element</a>.</p>\n<ul>\n<li><code>.option(value, [label])</code> can be used to create a new option for the\nelement. If an option with a value already exists, it will be returned.\nIt is recommended to use string values as input for <code>value</code>.\nOptionally, a label can be provided as second argument for the option.</li>\n<li><code>.remove(value)</code> can be used to remove an option for the element. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.value()</code> method will return the currently selected value.</li>\n<li><code>.selected()</code> method will return the currently selected input element.</li>\n<li><code>.selected(value)</code> method will select the option and return it. String\nvalues recommended as input for <code>value</code>.</li>\n<li><code>.disable(Boolean)</code> method will enable/disable the whole radio button element.</li>\n</ul>\n","itemtype":"method","name":"createRadio","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('black');\n  radio.option('white');\n  radio.option('gray');\n  radio.style('width', '60px');\n  textAlign(CENTER);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  let val = radio.value();\n  background(val);\n  text(val, width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet radio;\n\nfunction setup() {\n  radio = createRadio();\n  radio.option('1', 'apple');\n  radio.option('2', 'bread');\n  radio.option('3', 'juice');\n  radio.style('width', '30px');\n  radio.selected('2');\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  background(200);\n  let val = radio.value();\n  if (val) {\n    text('item cost is $' + val, width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":770,"params":[{"name":"containerElement","description":"<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n","type":"Object"},{"name":"name","description":"<p>A name parameter for each Input Element.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":832,"params":[{"name":"name","description":"","type":"String"}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":837,"params":[],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":978,"description":"<p>Creates a colorPicker element in the DOM for color input.\nThe .value() method will return a hex string (#rrggbb) of the color.\nThe .color() method will return a p5.Color object with the current chosen color.</p>\n","itemtype":"method","name":"createColorPicker","params":[{"name":"value","description":"<p>default color of element</p>\n","type":"String|p5.Color","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet colorPicker;\nfunction setup() {\n  createCanvas(100, 100);\n  colorPicker = createColorPicker('#ed225d');\n  colorPicker.position(0, height + 5);\n}\n\nfunction draw() {\n  background(colorPicker.color());\n}\n</code></div>\n<div><code>\nlet inp1, inp2;\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  inp1 = createColorPicker('#ff0000');\n  inp1.position(0, height + 5);\n  inp1.input(setShade1);\n  inp2 = createColorPicker(color('yellow'));\n  inp2.position(0, height + 30);\n  inp2.input(setShade2);\n  setMidShade();\n}\n\nfunction setMidShade() {\n  // Finding a shade between the two\n  let commonShade = lerpColor(inp1.color(), inp2.color(), 0.5);\n  fill(commonShade);\n  rect(20, 20, 60, 60);\n}\n\nfunction setShade1() {\n  setMidShade();\n  console.log('You are choosing shade 1 to be : ', this.value());\n}\nfunction setShade2() {\n  setMidShade();\n  console.log('You are choosing shade 2 to be : ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1066,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM for text input.\nUse .<a href=\"#/p5.Element/size\">size()</a> to set the display length of the box.</p>\n","itemtype":"method","name":"createInput","return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nfunction setup() {\n  createCanvas(100, 100);\n  background('grey');\n  let inp = createInput('');\n  inp.position(0, 0);\n  inp.size(100);\n  inp.input(myInputEvent);\n}\n\nfunction myInputEvent() {\n  console.log('you are typing: ', this.value());\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM","overloads":[{"line":1066,"params":[{"name":"value","description":"<p>default value of the input box</p>\n","type":"String"},{"name":"type","description":"<p>type of text, ie text, password etc. Defaults to text.\n  Needs a value to be specified first.</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"}},{"line":1091,"params":[{"name":"value","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.Element"}}]},{"file":"src/dom/dom.js","line":1104,"description":"<p>Creates an <code>&lt;input&gt;&lt;/input&gt;</code> element in the DOM of type 'file'.\nThis allows users to select local files for use in a sketch.</p>\n","itemtype":"method","name":"createFileInput","params":[{"name":"callback","description":"<p>callback function for when a file is loaded</p>\n","type":"Function"},{"name":"multiple","description":"<p>optional, to allow multiple files to be selected</p>\n","type":"Boolean","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created DOM element","type":"p5.Element"},"example":["\n<div><code>\nlet input;\nlet img;\n\nfunction setup() {\n  input = createFileInput(handleFile);\n  input.position(0, 0);\n}\n\nfunction draw() {\n  background(255);\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction handleFile(file) {\n  print(file);\n  if (file.type === 'image') {\n    img = createImg(file.data, '');\n    img.hide();\n  } else {\n    img = null;\n  }\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1164,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1211,"description":"<p>Creates an HTML5 <code>&lt;video&gt;</code> element in the DOM for simple playback\nof audio/video. Shown by default, can be hidden with .<a href=\"#/p5.Element/hide\">hide()</a>\nand drawn into canvas using <a href=\"#/p5/image\">image()</a>. The first parameter\ncan be either a single string path to a video file, or an array of string\npaths to different formats of the same video. This is useful for ensuring\nthat your video can play across different browsers, as each supports\ndifferent formats. See <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage</a> for further information about supported formats.</p>\n","itemtype":"method","name":"createVideo","params":[{"name":"src","description":"<p>path to a video file, or array of paths for\n                            supporting different browsers</p>\n","type":"String|String[]"},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to video <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet vid;\nfunction setup() {\n  noCanvas();\n\n  vid = createVideo(\n    ['assets/small.mp4', 'assets/small.ogv', 'assets/small.webm'],\n    vidLoad\n  );\n\n  vid.size(100, 100);\n}\n\n// This function is called when the video loads\nfunction vidLoad() {\n  vid.loop();\n  vid.volume(0);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1257,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1259,"description":"<p>Creates a hidden HTML5 <code>&lt;audio&gt;</code> element in the DOM for simple audio\nplayback. The first parameter can be either a single string path to a\naudio file, or an array of string paths to different formats of the same\naudio. This is useful for ensuring that your audio can play across\ndifferent browsers, as each supports different formats.\nSee <a href='https://developer.mozilla.org/en-US/docs/Web/HTML/Supported_media_formats'>this\npage for further information about supported formats</a>.</p>\n","itemtype":"method","name":"createAudio","params":[{"name":"src","description":"<p>path to an audio file, or array of paths\n                            for supporting different browsers</p>\n","type":"String|String[]","optional":true},{"name":"callback","description":"<p>callback function to be called upon\n                            'canplaythrough' event fire, that is, when the\n                            browser can play the media, and estimates that\n                            enough data has been loaded to play the media\n                            up to its end without having to stop for\n                            further buffering of content</p>\n","type":"Function","optional":true}],"return":{"description":"pointer to audio <a href=\"#/p5.MediaElement\">p5.MediaElement</a>","type":"p5.MediaElement"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  ele = createAudio('assets/beat.mp3');\n\n  // here we set the element to autoplay\n  // The element will play as soon\n  // as it is able to do so.\n  ele.autoplay(true);\n}\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1296,"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1298,"itemtype":"property","name":"VIDEO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1304,"itemtype":"property","name":"AUDIO","type":"String","final":1,"category":["Constants"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1341,"description":"<p>Creates a new HTML5 <code>&lt;video&gt;</code> element that contains the audio/video feed\nfrom a webcam. The element is separate from the canvas and is displayed by\ndefault. The element can be hidden using .<a href=\"#/p5.Element/hide\">hide()</a>.\nThe feed can be drawn onto the canvas using <a href=\"#/p5/image\">image()</a>.\nThe loadedmetadata property can be used to detect when the element has fully\nloaded (see second example).</p>\n<p>More specific properties of the feed can be passing in a Constraints object.\nSee the <a href='http://w3c.github.io/mediacapture-main/getusermedia.html#media-track-constraints'>\nW3C spec</a> for possible properties. Note that not all of these are supported\nby all browsers.</p>\n<p><em>Security note</em>: A new browser security specification requires that\ngetUserMedia, which is behind <a href=\"#/p5/createCapture\">createCapture()</a>,\nonly works when you're running the code locally, or on HTTPS. Learn more\n<a href='http://stackoverflow.com/questions/34197653/getusermedia-in-chrome-47-without-using-https'>here</a>\nand <a href='https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia'>here</a>.</p>\n","itemtype":"method","name":"createCapture","params":[{"name":"type","description":"<p>type of capture, either VIDEO or\n                                  AUDIO if none specified, default both,\n                                  or a Constraints object</p>\n","type":"String|Constant|Object"},{"name":"callback","description":"<p>function to be called once\n                                  stream has loaded</p>\n","type":"Function","optional":true}],"return":{"description":"capture video <a href=\"#/p5.Element\">p5.Element</a>","type":"p5.Element"},"example":["\n<div class='notest'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(100, 100);\n  capture = createCapture(VIDEO);\n  capture.hide();\n}\n\nfunction draw() {\n  image(capture, 0, 0, width, width * capture.height / capture.width);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div class='notest norender'>\n<code>\nfunction setup() {\n  createCanvas(480, 120);\n  let constraints = {\n    video: {\n      mandatory: {\n        minWidth: 1280,\n        minHeight: 720\n      },\n      optional: [{ maxFrameRate: 10 }]\n    },\n    audio: true\n  };\n  createCapture(constraints, function(stream) {\n    console.log(stream);\n  });\n}\n</code>\n</div>\n<div class='notest norender'>\n<code>\nlet capture;\n\nfunction setup() {\n  createCanvas(640, 480);\n  capture = createCapture(VIDEO);\n}\nfunction draw() {\n  background(0);\n  if (capture.loadedmetadata) {\n    let c = capture.get(0, 0, 100, 100);\n    image(c, 0, 0);\n  }\n}\n</code>\n</div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1478,"description":"<p>Creates element with given tag in the DOM with given content.</p>\n","itemtype":"method","name":"createElement","params":[{"name":"tag","description":"<p>tag for the new element</p>\n","type":"String"},{"name":"content","description":"<p>html content to be inserted into the element</p>\n","type":"String","optional":true}],"return":{"description":"pointer to <a href=\"#/p5.Element\">p5.Element</a> holding created node","type":"p5.Element"},"example":["\n<div><code>\nlet h5 = createElement('h5', 'im an h5 p5.element!');\nh5.style('color', '#00a1d3');\nh5.position(0, 0);\n</code></div>"],"class":"p5","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1504,"description":"<p>Adds specified class to the element.</p>\n","itemtype":"method","name":"addClass","params":[{"name":"class","description":"<p>name of class to add</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.addClass('myClass');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1529,"description":"<p>Removes specified class from the element.</p>\n","itemtype":"method","name":"removeClass","params":[{"name":"class","description":"<p>name of class to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n // In this example, a class is set when the div is created\n // and removed when mouse is pressed. This could link up\n // with a CSS style rule to toggle style properties.\nlet div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('myClass');\n }\nfunction mousePressed() {\n   div.removeClass('myClass');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1560,"description":"<p>Checks if specified class already set to element</p>\n","itemtype":"method","name":"hasClass","return":{"description":"a boolean value if element has specified class","type":"Boolean"},"params":[{"name":"c","description":"<p>class name of class to check</p>\n","type":"String"}],"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   if (div.hasClass('show')) {\n     div.addClass('show');\n   } else {\n     div.removeClass('show');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1589,"description":"<p>Toggles element class</p>\n","itemtype":"method","name":"toggleClass","params":[{"name":"c","description":"<p>class name to toggle</p>\n","type":"String"}],"chainable":1,"example":["\n <div class='norender'><code>\n let div;\nfunction setup() {\n   div = createDiv('div');\n   div.addClass('show');\n }\nfunction mousePressed() {\n   div.toggleClass('show');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1622,"description":"<p>Attaches the element  as a child to the parent specified.\n Accepts either a string ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>.\n If no argument is specified, an array of children DOM nodes is returned.</p>\n","itemtype":"method","name":"child","return":{"description":"an array of child nodes","type":"Node[]"},"example":["\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div0.child(div1); // use p5.Element\n </code></div>\n <div class='norender'><code>\n let div0 = createDiv('this is the parent');\n let div1 = createDiv('this is the child');\n div1.id('apples');\n div0.child('apples'); // use id\n </code></div>\n <div class='norender notest'><code>\n // this example assumes there is a div already on the page\n // with id \"myChildDiv\"\n let div0 = createDiv('this is the parent');\n let elt = document.getElementById('myChildDiv');\n div0.child(elt); // use element from page\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1622,"params":[],"return":{"description":"an array of child nodes","type":"Node[]"}},{"line":1650,"params":[{"name":"child","description":"<p>the ID, DOM node, or <a href=\"#/p5.Element\">p5.Element</a>\n                        to add to the current element</p>\n","type":"String|p5.Element","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1675,"description":"<p>Centers a p5 Element either vertically, horizontally,\nor both, relative to its parent or according to\nthe body if the Element has no parent. If no argument is passed\nthe Element is aligned both vertically and horizontally.</p>\n","itemtype":"method","name":"center","params":[{"name":"align","description":"<p>passing 'vertical', 'horizontal' aligns element accordingly</p>\n","type":"String","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let div = createDiv('').size(10, 10);\n  div.style('background-color', 'orange');\n  div.center();\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":1726,"description":"<p>If an argument is given, sets the inner HTML of the element,\n replacing any existing html. If true is included as a second\n argument, html is appended instead of replacing existing html.\n If no arguments are given, returns\n the inner HTML of the element.</p>\n","itemtype":"method","name":"html","return":{"description":"the inner HTML of the element","type":"String"},"example":["\n <div class='norender'><code>\n let div = createDiv('').size(100, 100);\n div.html('hi');\n </code></div>\n <div class='norender'><code>\n let div = createDiv('Hello ').size(100, 100);\n div.html('World', true);\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1726,"params":[],"return":{"description":"the inner HTML of the element","type":"String"}},{"line":1747,"params":[{"name":"html","description":"<p>the HTML to be placed inside the element</p>\n","type":"String","optional":true},{"name":"append","description":"<p>whether to append HTML to existing</p>\n","type":"Boolean","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1765,"description":"<p>Sets the position of the element. If no position type argument is given, the\n position will be relative to (0, 0) of the window.\n Essentially, this sets position:absolute and left and top\n properties of style. If an optional third argument specifying position type is given,\n the x and y coordinates will be interpreted based on the <a target=\"_blank\"\n href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/position\">positioning scheme</a>.\n If no arguments given, the function returns the x and y position of the element.\nfound documentation on how to be more specific with object type\n <a href=\"https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc\">https://stackoverflow.com/questions/14714314/how-do-i-comment-object-literals-in-yuidoc</a></p>\n","itemtype":"method","name":"position","return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"},"example":["\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas 50px to the right and 100px\n   // below upper left corner of the window\n   cnv.position(50, 100);\n }\n </code></div>\n <div><code class='norender'>\n function setup() {\n   let cnv = createCanvas(100, 100);\n   // positions canvas at upper left corner of the window\n   // with a 'fixed' position type\n   cnv.position(0, 0, 'fixed');\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1765,"params":[],"return":{"description":"object of form { x: 0, y: 0 } containing the position of the element in an object","type":"Object"}},{"line":1798,"params":[{"name":"x","description":"<p>x-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-position relative to upper left of window (optional)</p>\n","type":"Number","optional":true},{"name":"positionType","description":"<p>it can be static, fixed, relative, sticky, initial or inherit (optional)</p>\n","type":"String","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":1885,"description":"<p>Sets the given style (css) property (1st arg) of the element with the\ngiven value (2nd arg). If a single argument is given, .style()\nreturns the value of the given property; however, if the single argument\nis given in css syntax ('text-align:center'), .style() sets the css\nappropriately.</p>\n","itemtype":"method","name":"style","return":{"description":"value of property","type":"String"},"example":["\n<div><code class='norender'>\nlet myDiv = createDiv('I like pandas.');\nmyDiv.style('font-size', '18px');\nmyDiv.style('color', '#ff0000');\nmyDiv.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet col = color(25, 23, 200, 50);\nlet button = createButton('button');\nbutton.style('background-color', col);\nbutton.position(0, 0);\n</code></div>\n<div><code class='norender'>\nlet myDiv, fontSize;\nfunction setup() {\n  background(200);\n  myDiv = createDiv('I like gray.');\n  myDiv.position(0, 0);\n  myDiv.style('z-index', 10);\n}\n\nfunction draw() {\n  fontSize = min(mouseX, 90);\n  myDiv.style('font-size', fontSize + 'px');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1885,"params":[{"name":"property","description":"<p>property to be set</p>\n","type":"String"}],"return":{"description":"value of property","type":"String"}},{"line":1923,"params":[{"name":"property","description":"","type":"String"},{"name":"value","description":"<p>value to assign to property</p>\n","type":"String|p5.Color"}],"chainable":1,"return":{"description":"current value of property, if no value is given as second argument","type":"String"}}]},{"file":"src/dom/dom.js","line":1980,"description":"<p>Adds a new attribute or changes the value of an existing attribute\n on the specified element. If no value is specified, returns the\n value of the given attribute, or null if attribute is not set.</p>\n","itemtype":"method","name":"attribute","return":{"description":"value of attribute","type":"String"},"example":["\n <div class='norender'><code>\n let myDiv = createDiv('I like pandas.');\n myDiv.attribute('align', 'center');\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":1980,"params":[],"return":{"description":"value of attribute","type":"String"}},{"line":1995,"params":[{"name":"attr","description":"<p>attribute to set</p>\n","type":"String"},{"name":"value","description":"<p>value to assign to attribute</p>\n","type":"String"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2024,"description":"<p>Removes an attribute on the specified element.</p>\n","itemtype":"method","name":"removeAttribute","params":[{"name":"attr","description":"<p>attribute to remove</p>\n","type":"String"}],"chainable":1,"example":["\n <div><code>\n let button;\n let checkbox;\nfunction setup() {\n   checkbox = createCheckbox('enable', true);\n   checkbox.changed(enableButton);\n   button = createButton('button');\n   button.position(10, 10);\n }\nfunction enableButton() {\n   if (this.checked()) {\n     // Re-enable the button\n     button.removeAttribute('disabled');\n   } else {\n     // Disable the button\n     button.attribute('disabled', '');\n   }\n }\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2069,"description":"<p>Either returns the value of the element if no arguments\ngiven, or sets the value of the element.</p>\n","itemtype":"method","name":"value","return":{"description":"value of the element","type":"String|Number"},"example":["\n<div class='norender'><code>\n// gets the value\nlet inp;\nfunction setup() {\n  inp = createInput('');\n}\n\nfunction mousePressed() {\n  print(inp.value());\n}\n</code></div>\n<div class='norender'><code>\n// sets the value\nlet inp;\nfunction setup() {\n  inp = createInput('myValue');\n}\n\nfunction mousePressed() {\n  inp.value('myValue');\n}\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2069,"params":[],"return":{"description":"value of the element","type":"String|Number"}},{"line":2099,"params":[{"name":"value","description":"","type":"String|Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2115,"description":"<p>Shows the current element. Essentially, setting display:block for the style.</p>\n","itemtype":"method","name":"show","chainable":1,"example":["\n <div class='norender'><code>\n let div = createDiv('div');\n div.style('display', 'none');\n div.show(); // turns display to block\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2133,"description":"<p>Hides the current element. Essentially, setting display:none for the style.</p>\n","itemtype":"method","name":"hide","chainable":1,"example":["\n<div class='norender'><code>\nlet div = createDiv('this is a div');\ndiv.hide();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2149,"description":"<p>Sets the width and height of the element. AUTO can be used to\n only adjust one dimension at a time. If no arguments are given, it\n returns the width and height of the element in an object. In case of\n elements which need to be loaded, such as images, it is recommended\n to call the function after the element has finished loading.</p>\n","itemtype":"method","name":"size","return":{"description":"the width and height of the element in an object","type":"Object"},"example":["\n <div class='norender'><code>\n let div = createDiv('this is a div');\n div.size(100, 100);\n let img = createImg(\n   'assets/rockies.jpg',\n   'A tall mountain with a small forest and field in front of it on a sunny day',\n   '',\n   () => {\n     img.size(10, AUTO);\n   }\n );\n </code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM","overloads":[{"line":2149,"params":[],"return":{"description":"the width and height of the element in an object","type":"Object"}},{"line":2173,"params":[{"name":"w","description":"<p>width of the element, either AUTO, or a number</p>\n","type":"Number|Constant"},{"name":"h","description":"<p>height of the element, either AUTO, or a number</p>\n","type":"Number|Constant","optional":true}],"chainable":1}]},{"file":"src/dom/dom.js","line":2230,"description":"<p>Removes the element, stops all media streams, and deregisters all listeners.</p>\n","itemtype":"method","name":"remove","example":["\n<div class='norender'><code>\nlet myDiv = createDiv('this is some text');\nmyDiv.remove();\n</code></div>"],"class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2268,"description":"<p>Registers a callback that gets called every time a file that is\ndropped on the element has been loaded.\np5 will load every dropped file into memory and pass it as a p5.File object to the callback.\nMultiple files dropped at the same time will result in multiple calls to the callback.</p>\n<p>You can optionally pass a second callback which will be registered to the raw\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/drop\">drop</a> event.\nThe callback will thus be provided the original\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/DragEvent\">DragEvent</a>.\nDropping multiple files at the same time will trigger the second callback once per drop,\nwhereas the first callback will trigger for each loaded file.</p>\n","itemtype":"method","name":"drop","params":[{"name":"callback","description":"<p>callback to receive loaded file, called for each file dropped.</p>\n","type":"Function"},{"name":"fxn","description":"<p>callback triggered once when files are dropped with the drop event.</p>\n","type":"Function","optional":true}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop file', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction gotFile(file) {\n  background(200);\n  text('received file:', width / 2, height / 2);\n  text(file.name, width / 2, height / 2 + 50);\n}\n</code></div>\n\n<div><code>\nlet img;\n\nfunction setup() {\n  let c = createCanvas(100, 100);\n  background(200);\n  textAlign(CENTER);\n  text('drop image', width / 2, height / 2);\n  c.drop(gotFile);\n}\n\nfunction draw() {\n  if (img) {\n    image(img, 0, 0, width, height);\n  }\n}\n\nfunction gotFile(file) {\n  img = createImg(file.data, '').hide();\n}\n</code></div>"],"alt":"Canvas turns into whatever image is dragged/dropped onto it.","class":"p5.Element","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2400,"description":"<p>Path to the media element source.</p>\n","itemtype":"property","name":"src","return":{"description":"src","type":"String"},"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  background(250);\n\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  //We'll set up our example so that\n  //when you click on the text,\n  //an alert box displays the MediaElement's\n  //src field.\n  textAlign(CENTER);\n  text('Click Me!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Show our p5.MediaElement's src field\n    alert(ele.src);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2466,"description":"<p>Play an HTML5 media element.</p>\n","itemtype":"method","name":"play","chainable":1,"example":["\n<div><code>\nlet ele;\n\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/beat.mp3');\n\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    //Here we call the play() function on\n    //the p5.MediaElement we created above.\n    //This will start the audio sample.\n    ele.play();\n\n    background(200);\n    text('You clicked Play!', width / 2, height / 2);\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2530,"description":"<p>Stops an HTML5 media element (sets current time to zero).</p>\n","itemtype":"method","name":"stop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //if the sample is currently playing\n      //calling the stop() function on\n      //our p5.MediaElement will stop\n      //it and reset its current\n      //time to 0 (i.e. it will start\n      //at the beginning the next time\n      //you play it)\n      ele.stop();\n\n      sampleIsPlaying = false;\n      text('Click to play!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to stop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2594,"description":"<p>Pauses an HTML5 media element.</p>\n","itemtype":"method","name":"pause","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and pauses a sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      //Calling pause() on our\n      //p5.MediaElement will stop it\n      //playing, but when we call the\n      //loop() or play() functions\n      //the sample will start from\n      //where we paused it.\n      ele.pause();\n\n      sampleIsPlaying = false;\n      text('Click to resume!', width / 2, height / 2);\n    } else {\n      //loop our sound element until we\n      //call ele.pause() on it.\n      ele.loop();\n\n      sampleIsPlaying = true;\n      text('Click to pause!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2656,"description":"<p>Set 'loop' to true for an HTML5 media element, and starts playing.</p>\n","itemtype":"method","name":"loop","chainable":1,"example":["\n<div><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n\n//while our audio is playing,\n//this will be set to true\nlet sampleIsLooping = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to loop!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (!sampleIsLooping) {\n      //loop our sound element until we\n      //call ele.stop() on it.\n      ele.loop();\n\n      sampleIsLooping = true;\n      text('Click to stop!', width / 2, height / 2);\n    } else {\n      ele.stop();\n\n      sampleIsLooping = false;\n      text('Click to loop!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2712,"description":"<p>Set 'loop' to false for an HTML5 media element. Element will stop\nwhen it reaches the end.</p>\n","itemtype":"method","name":"noLoop","chainable":1,"example":["\n<div><code>\n//This example both starts\n//and stops loop of sound sample\n//when the user clicks the canvas\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\n//while our audio is playing,\n//this will be set to true\nlet sampleIsPlaying = false;\n\nfunction setup() {\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to play!', width / 2, height / 2);\n}\n\nfunction mouseClicked() {\n  //here we test if the mouse is over the\n  //canvas element when it's clicked\n  if (mouseX >= 0 && mouseX <= width && mouseY >= 0 && mouseY <= height) {\n    background(200);\n\n    if (sampleIsPlaying) {\n      ele.noLoop();\n      sampleIsPlaying = false;\n      text('No more Loops!', width / 2, height / 2);\n    } else {\n      ele.loop();\n      sampleIsPlaying = true;\n      text('Click to stop looping!', width / 2, height / 2);\n    }\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2778,"description":"<p>Set HTML5 media element to autoplay or not. If no argument is specified, by\ndefault it will autoplay.</p>\n","itemtype":"method","name":"autoplay","params":[{"name":"shouldAutoplay","description":"<p>whether the element should autoplay</p>\n","type":"Boolean"}],"chainable":1,"example":["\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will play as soon as it is loaded.\n  videoElement.autoplay();\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n</code></div>\n\n<div><code>\nlet videoElement;\nfunction setup() {\n  noCanvas();\n  videoElement = createVideo(['assets/small.mp4'], onVideoLoad);\n}\nfunction onVideoLoad() {\n  // The media will not play until some explicitly triggered.\n  videoElement.autoplay(false);\n  videoElement.volume(0);\n  videoElement.size(100, 100);\n}\n\nfunction mouseClicked() {\n  videoElement.play();\n}\n</code></div>"],"alt":"An example of a video element which autoplays after it is loaded.\nAn example of a video element which waits for a trigger for playing.","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":2845,"description":"<p>Sets volume for this HTML5 media element. If no argument is given,\nreturns the current volume.</p>\n","itemtype":"method","name":"volume","return":{"description":"current volume","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  // p5.MediaElement objects are usually created\n  // by calling the createAudio(), createVideo(),\n  // and createCapture() functions.\n  // In this example we create\n  // a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to Play!', width / 2, height / 2);\n}\nfunction mouseClicked() {\n  // Here we call the volume() function\n  // on the sound element to set its volume\n  // Volume must be between 0.0 and 1.0\n  ele.volume(0.2);\n  ele.play();\n  background(200);\n  text('You clicked Play!', width / 2, height / 2);\n}\n</code></div>\n<div><code>\nlet audio;\nlet counter = 0;\n\nfunction loaded() {\n  audio.play();\n}\n\nfunction setup() {\n  audio = createAudio('assets/lucky_dragons.mp3', loaded);\n  textAlign(CENTER);\n}\n\nfunction draw() {\n  if (counter === 0) {\n    background(0, 255, 0);\n    text('volume(0.9)', width / 2, height / 2);\n  } else if (counter === 1) {\n    background(255, 255, 0);\n    text('volume(0.5)', width / 2, height / 2);\n  } else if (counter === 2) {\n    background(255, 0, 0);\n    text('volume(0.1)', width / 2, height / 2);\n  }\n}\n\nfunction mousePressed() {\n  counter++;\n  if (counter === 0) {\n    audio.volume(0.9);\n  } else if (counter === 1) {\n    audio.volume(0.5);\n  } else if (counter === 2) {\n    audio.volume(0.1);\n  } else {\n    counter = 0;\n    audio.volume(0.9);\n  }\n}\n</code>\n</div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2845,"params":[],"return":{"description":"current volume","type":"Number"}},{"line":2918,"params":[{"name":"val","description":"<p>volume between 0.0 and 1.0</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":2931,"description":"<p>If no arguments are given, returns the current playback speed of the\nelement. The speed parameter sets the speed where 2.0 will play the\nelement twice as fast, 0.5 will play at half the speed, and -1 will play\nthe element in normal speed in reverse.(Note that not all browsers support\nbackward playback and even if they do, playback might not be smooth.)</p>\n","itemtype":"method","name":"speed","return":{"description":"current playback speed of the element","type":"Number"},"example":["\n<div class='norender notest'><code>\n//Clicking the canvas will loop\n//the audio sample until the user\n//clicks again to stop it\n\n//We will store the p5.MediaElement\n//object in here\nlet ele;\nlet button;\n\nfunction setup() {\n  createCanvas(710, 400);\n  //Here we create a p5.MediaElement object\n  //using the createAudio() function.\n  ele = createAudio('assets/beat.mp3');\n  ele.loop();\n  background(200);\n\n  button = createButton('2x speed');\n  button.position(100, 68);\n  button.mousePressed(twice_speed);\n\n  button = createButton('half speed');\n  button.position(200, 68);\n  button.mousePressed(half_speed);\n\n  button = createButton('reverse play');\n  button.position(300, 68);\n  button.mousePressed(reverse_speed);\n\n  button = createButton('STOP');\n  button.position(400, 68);\n  button.mousePressed(stop_song);\n\n  button = createButton('PLAY!');\n  button.position(500, 68);\n  button.mousePressed(play_speed);\n}\n\nfunction twice_speed() {\n  ele.speed(2);\n}\n\nfunction half_speed() {\n  ele.speed(0.5);\n}\n\nfunction reverse_speed() {\n  ele.speed(-1);\n}\n\nfunction stop_song() {\n  ele.stop();\n}\n\nfunction play_speed() {\n  ele.play();\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":2931,"params":[],"return":{"description":"current playback speed of the element","type":"Number"}},{"line":3003,"params":[{"name":"speed","description":"<p>speed multiplier for element playback</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3020,"description":"<p>If no arguments are given, returns the current time of the element.\nIf an argument is given the current time of the element is set to it.</p>\n","itemtype":"method","name":"time","return":{"description":"current time (in seconds)","type":"Number"},"example":["\n<div><code>\nlet ele;\nlet beginning = true;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('start at beginning', width / 2, height / 2);\n}\n\n// this function fires with click anywhere\nfunction mousePressed() {\n  if (beginning === true) {\n    // here we start the sound at the beginning\n    // time(0) is not necessary here\n    // as this produces the same result as\n    // play()\n    ele.play().time(0);\n    background(200);\n    text('jump 2 sec in', width / 2, height / 2);\n    beginning = false;\n  } else {\n    // here we jump 2 seconds into the sound\n    ele.play().time(2);\n    background(250);\n    text('start at beginning', width / 2, height / 2);\n    beginning = true;\n  }\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM","overloads":[{"line":3020,"params":[],"return":{"description":"current time (in seconds)","type":"Number"}},{"line":3065,"params":[{"name":"time","description":"<p>time to jump to (in seconds)</p>\n","type":"Number"}],"chainable":1}]},{"file":"src/dom/dom.js","line":3079,"description":"<p>Returns the duration of the HTML5 media element.</p>\n","itemtype":"method","name":"duration","return":{"description":"duration","type":"Number"},"example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio().\n  ele = createAudio('assets/doorbell.mp3');\n  background(250);\n  textAlign(CENTER);\n  text('Click to know the duration!', 10, 25, 70, 80);\n}\nfunction mouseClicked() {\n  ele.play();\n  background(200);\n  //ele.duration dislpays the duration\n  text(ele.duration() + ' seconds', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3201,"description":"<p>Schedule an event to be called when the audio or video\nelement reaches the end. If the element is looping,\nthis will not be called. The element is passed in\nas the argument to the onended callback.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended. The\n                            media element will be passed\n                            in as the argument to the\n                            callback.</p>\n","type":"Function"}],"chainable":1,"example":["\n<div><code>\nfunction setup() {\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  audioEl.onended(sayDone);\n}\n\nfunction sayDone(elt) {\n  alert('done playing ' + elt.src);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3232,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3234,"description":"<p>Send the audio output of this element to a specified audioNode or\np5.sound object. If no element is provided, connects to p5's main\noutput. That connection is established when this method is first called.\nAll connections are removed by the .disconnect() method.</p>\n<p>This method is meant to be used with the p5.sound.js addon library.</p>\n","itemtype":"method","name":"connect","params":[{"name":"audioNode","description":"<p>AudioNode from the Web Audio API,\nor an object from the p5.sound library</p>\n","type":"AudioNode|Object"}],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3283,"description":"<p>Disconnect all Web Audio routing, including to main output.\nThis is useful if you want to re-route the output through\naudio effects, for example.</p>\n","itemtype":"method","name":"disconnect","class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3298,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3300,"description":"<p>Show the default MediaElement controls, as determined by the web browser.</p>\n","itemtype":"method","name":"showControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  background(200);\n  textAlign(CENTER);\n  text('Click to Show Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.showControls();\n  background(200);\n  text('Controls Shown', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3331,"description":"<p>Hide the default mediaElement controls.</p>\n","itemtype":"method","name":"hideControls","example":["\n<div><code>\nlet ele;\nfunction setup() {\n  //p5.MediaElement objects are usually created\n  //by calling the createAudio(), createVideo(),\n  //and createCapture() functions.\n  //In this example we create\n  //a new p5.MediaElement via createAudio()\n  ele = createAudio('assets/lucky_dragons.mp3');\n  ele.showControls();\n  background(200);\n  textAlign(CENTER);\n  text('Click to hide Controls!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  ele.hideControls();\n  background(200);\n  text('Controls hidden', width / 2, height / 2);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3360,"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3371,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                            element's playback. For example, to trigger\n                            an event every time playback reaches two\n                            seconds, pass in the number 2. This will be\n                            passed as the first parameter to\n                            the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                            called at the given time. The callback will\n                            receive time and (optionally) param as its\n                            two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                            second parameter to the\n                            callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\n//\n//\nfunction setup() {\n  createCanvas(200, 200);\n\n  let audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n\n  // schedule three calls to changeBackground\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  audioEl.addCue(5.0, changeBackground, color(255, 255, 0));\n}\n\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3434,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl, id1, id2;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  audioEl.showControls();\n  // schedule five calls to changeBackground\n  id1 = audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  id2 = audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n  text('Click to remove first and last Cue!', 10, 25, 70, 80);\n}\nfunction mousePressed() {\n  audioEl.removeCue(id1);\n  audioEl.removeCue(id2);\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3476,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioEl;\nfunction setup() {\n  background(255, 255, 255);\n  audioEl = createAudio('assets/beat.mp3');\n  //Show the default MediaElement controls, as determined by the web browser\n  audioEl.showControls();\n  // schedule calls to changeBackground\n  background(200);\n  text('Click to change Cue!', 10, 25, 70, 80);\n  audioEl.addCue(0.5, changeBackground, color(255, 0, 0));\n  audioEl.addCue(1.0, changeBackground, color(0, 255, 0));\n  audioEl.addCue(2.5, changeBackground, color(0, 0, 255));\n  audioEl.addCue(3.0, changeBackground, color(0, 255, 255));\n  audioEl.addCue(4.2, changeBackground, color(255, 255, 0));\n}\nfunction mousePressed() {\n  // here we clear the scheduled callbacks\n  audioEl.clearCues();\n  // then we add some more callbacks\n  audioEl.addCue(1, changeBackground, color(2, 2, 2));\n  audioEl.addCue(3, changeBackground, color(255, 255, 0));\n}\nfunction changeBackground(val) {\n  background(val);\n}\n</code></div>"],"class":"p5.MediaElement","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3542,"description":"<p>Underlying File object. All normal File methods can be called on this.</p>\n","itemtype":"property","name":"file","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3554,"description":"<p>File type (image, text, etc.)</p>\n","itemtype":"property","name":"type","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3560,"description":"<p>File subtype (usually the file extension jpg, png, xml, etc.)</p>\n","itemtype":"property","name":"subtype","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3566,"description":"<p>File name</p>\n","itemtype":"property","name":"name","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3572,"description":"<p>File size</p>\n","itemtype":"property","name":"size","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/dom/dom.js","line":3579,"description":"<p>URL string containing either image data, the text contents of the file or\na parsed object if file is JSON and p5.XML if XML</p>\n","itemtype":"property","name":"data","class":"p5.File","module":"DOM","submodule":"DOM"},{"file":"src/events/acceleration.js","line":11,"description":"<p>The system variable deviceOrientation always contains the orientation of\nthe device. The value of this variable will either be set 'landscape'\nor 'portrait'. If no data is available it will be set to 'undefined'.\neither LANDSCAPE or PORTRAIT.</p>\n","itemtype":"property","name":"deviceOrientation","type":"Constant","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":23,"description":"<p>The system variable accelerationX always contains the acceleration of the\ndevice along the x axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationX);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":46,"description":"<p>The system variable accelerationY always contains the acceleration of the\ndevice along the y axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationY);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":69,"description":"<p>The system variable accelerationZ always contains the acceleration of the\ndevice along the z axis. Value is represented as meters per second squared.</p>\n","itemtype":"property","name":"accelerationZ","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move a touchscreen device to register\n// acceleration changes.\nfunction draw() {\n  background(220, 50);\n  fill('magenta');\n  ellipse(width / 2, height / 2, accelerationZ);\n}\n</code>\n</div>"],"alt":"Magnitude of device acceleration is displayed as ellipse size","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":94,"description":"<p>The system variable pAccelerationX always contains the acceleration of the\ndevice along the x axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":104,"description":"<p>The system variable pAccelerationY always contains the acceleration of the\ndevice along the y axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":114,"description":"<p>The system variable pAccelerationZ always contains the acceleration of the\ndevice along the z axis in the frame previous to the current frame. Value\nis represented as meters per second squared.</p>\n","itemtype":"property","name":"pAccelerationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":135,"description":"<p>The system variable rotationX always contains the rotation of the\ndevice along the x axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -180 to 180. If\nit is set to RADIANS, the value will be -PI to PI.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationX","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":168,"description":"<p>The system variable rotationY always contains the rotation of the\ndevice along the y axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be -90 to 90. If\nit is set to RADIANS, the value will be -PI/2 to PI/2.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","itemtype":"property","name":"rotationY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  //rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":201,"description":"<p>The system variable rotationZ always contains the rotation of the\ndevice along the z axis. If the sketch <a href=\"#/p5/angleMode\">\nangleMode()</a> is set to DEGREES, the value will be 0 to 360. If\nit is set to RADIANS, the value will be 0 to 2*PI.</p>\n<p>Unlike rotationX and rotationY, this variable is available for devices\nwith a built-in compass only.</p>\n<p>Note: The order the rotations are called is important, ie. if used\ntogether, it must be called in the order Z-X-Y or there might be\nunexpected behaviour.</p>\n","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateZ(radians(rotationZ));\n  //rotateX(radians(rotationX));\n  //rotateY(radians(rotationY));\n  box(200, 200, 200);\n}\n</code>\n</div>"],"itemtype":"property","name":"rotationZ","type":"Number","readonly":"","alt":"red horizontal line right, green vertical line bottom. black background.","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":239,"description":"<p>The system variable pRotationX always contains the rotation of the\ndevice along the x axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -180 to 180. If it is set to RADIANS, the value will\nbe -PI to PI.</p>\n<p>pRotationX can also be used with rotationX to determine the rotate\ndirection of the device along the X-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationX - pRotationX < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rX = rotationX + 180;\nlet pRX = pRotationX + 180;\n\nif ((rX - pRX > 0 && rX - pRX < 270) || rX - pRX < -270) {\n  rotateDirection = 'clockwise';\n} else if (rX - pRX < 0 || rX - pRX > 270) {\n  rotateDirection = 'counter-clockwise';\n}\n\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationX","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":285,"description":"<p>The system variable pRotationY always contains the rotation of the\ndevice along the y axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be -90 to 90. If it is set to RADIANS, the value will\nbe -PI/2 to PI/2.</p>\n<p>pRotationY can also be used with rotationY to determine the rotate\ndirection of the device along the Y-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationY - pRotationY < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\n// Simple range conversion to make things simpler.\n// This is not absolutely necessary but the logic\n// will be different in that case.\n\nlet rY = rotationY + 180;\nlet pRY = pRotationY + 180;\n\nif ((rY - pRY > 0 && rY - pRY < 270) || rY - pRY < -270) {\n  rotateDirection = 'clockwise';\n} else if (rY - pRY < 0 || rY - pRY > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationY","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":330,"description":"<p>The system variable pRotationZ always contains the rotation of the\ndevice along the z axis in the frame previous to the current frame.\nIf the sketch <a href=\"#/p5/angleMode\"> angleMode()</a> is set to DEGREES,\nthe value will be 0 to 360. If it is set to RADIANS, the value will\nbe 0 to 2*PI.</p>\n<p>pRotationZ can also be used with rotationZ to determine the rotate\ndirection of the device along the Z-axis.</p>\n","example":["\n<div class='norender'>\n<code>\n// A simple if statement looking at whether\n// rotationZ - pRotationZ < 0 is true or not will be\n// sufficient for determining the rotate direction\n// in most cases.\n\n// Some extra logic is needed to account for cases where\n// the angles wrap around.\nlet rotateDirection = 'clockwise';\n\nif (\n  (rotationZ - pRotationZ > 0 && rotationZ - pRotationZ < 270) ||\n  rotationZ - pRotationZ < -270\n) {\n  rotateDirection = 'clockwise';\n} else if (rotationZ - pRotationZ < 0 || rotationZ - pRotationZ > 270) {\n  rotateDirection = 'counter-clockwise';\n}\nprint(rotateDirection);\n</code>\n</div>"],"alt":"no image to display.","itemtype":"property","name":"pRotationZ","type":"Number","readonly":"","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":389,"description":"<p>When a device is rotated, the axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a>\nmethod is stored in the turnAxis variable. The turnAxis variable is only defined within\nthe scope of deviceTurned().</p>\n","itemtype":"property","name":"turnAxis","type":"String","readonly":"","example":["\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":428,"description":"<p>The <a href=\"#/p5/setMoveThreshold\">setMoveThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function. The default threshold is set to 0.5.</p>\n","itemtype":"method","name":"setMoveThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to move the device incrementally further\n// the closer the square's color gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 0.5;\nfunction setup() {\n  setMoveThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 0.1;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setMoveThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":471,"description":"<p>The <a href=\"#/p5/setShakeThreshold\">setShakeThreshold()</a> function is used to set the movement threshold for\nthe <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function. The default threshold is set to 30.</p>\n","itemtype":"method","name":"setShakeThreshold","params":[{"name":"value","description":"<p>The threshold value</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// You will need to shake the device more firmly\n// the closer the box's fill gets to white in order to change the value.\n\nlet value = 0;\nlet threshold = 30;\nfunction setup() {\n  setShakeThreshold(threshold);\n}\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  threshold = threshold + 5;\n  if (value > 255) {\n    value = 0;\n    threshold = 30;\n  }\n  setShakeThreshold(threshold);\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device\nis being shaked","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":515,"description":"<p>The <a href=\"#/p5/deviceMoved\">deviceMoved()</a> function is called when the device is moved by more than\nthe threshold value along X, Y or Z axis. The default threshold is set to 0.5.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setMoveThreshold\">setMoveThreshold()</a>.</p>\n","itemtype":"method","name":"deviceMoved","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Move the device around\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device moves","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":546,"description":"<p>The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> function is called when the device rotates by\nmore than 90 degrees continuously.</p>\n<p>The axis that triggers the <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method is stored in the turnAxis\nvariable. The <a href=\"#/p5/deviceTurned\">deviceTurned()</a> method can be locked to trigger on any axis:\nX, Y or Z by comparing the turnAxis variable to 'X', 'Y' or 'Z'.</p>\n","itemtype":"method","name":"deviceTurned","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees\n// to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (value === 0) {\n    value = 255;\n  } else if (value === 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\n// Run this example on a mobile device\n// Rotate the device by 90 degrees in the\n// X-axis to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceTurned() {\n  if (turnAxis === 'X') {\n    if (value === 0) {\n      value = 255;\n    } else if (value === 255) {\n      value = 0;\n    }\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device turns\n50×50 black rect in center of canvas. turns white on mobile when x-axis turns","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/acceleration.js","line":604,"description":"<p>The <a href=\"#/p5/deviceShaken\">deviceShaken()</a> function is called when the device total acceleration\nchanges of accelerationX and accelerationY values is more than\nthe threshold value. The default threshold is set to 30.\nThe threshold value can be changed using <a href=\"https://p5js.org/reference/#/p5/setShakeThreshold\">setShakeThreshold()</a>.</p>\n","itemtype":"method","name":"deviceShaken","example":["\n<div class=\"norender\">\n<code>\n// Run this example on a mobile device\n// Shake the device to change the value.\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction deviceShaken() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>"],"alt":"50×50 black rect in center of canvas. turns white on mobile when device shakes","class":"p5","module":"Events","submodule":"Acceleration"},{"file":"src/events/keyboard.js","line":10,"description":"<p>The boolean system variable <a href=\"#/p5/keyIsPressed\">keyIsPressed</a> is true if any key is pressed\nand false if no keys are pressed.</p>\n","itemtype":"property","name":"keyIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  if (keyIsPressed === true) {\n    fill(0);\n  } else {\n    fill(255);\n  }\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"50×50 white rect that turns black on keypress.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":36,"description":"<p>The system variable key always contains the value of the most recent\nkey on the keyboard that was typed. To get the proper capitalization, it\nis best to use it within <a href=\"#/p5/keyTyped\">keyTyped()</a>. For non-ASCII keys, use the <a href=\"#/p5/keyCode\">keyCode</a>\nvariable.</p>\n","itemtype":"property","name":"key","type":"String","readonly":"","example":["\n<div><code>\n// Click any key to display it!\n// (Not Guaranteed to be Case Sensitive)\nfunction setup() {\n  fill(245, 123, 158);\n  textSize(50);\n}\n\nfunction draw() {\n  background(200);\n  text(key, 33, 65); // Display last key pressed.\n}\n</code></div>"],"alt":"canvas displays any key value that is pressed in pink font.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":64,"description":"<p>The variable keyCode is used to detect special keys such as BACKSPACE,\nDELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL, OPTION, ALT, UP_ARROW,\nDOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.\nYou can also check for custom keys by looking up the keyCode of any key\non a site like this: <a href=\"http://keycode.info/\">keycode.info</a>.</p>\n","itemtype":"property","name":"keyCode","type":"Integer","readonly":"","example":["\n<div><code>\nlet fillVal = 126;\nfunction draw() {\n  fill(fillVal);\n  rect(25, 25, 50, 50);\n}\n\nfunction keyPressed() {\n  if (keyCode === UP_ARROW) {\n    fillVal = 255;\n  } else if (keyCode === DOWN_ARROW) {\n    fillVal = 0;\n  }\n}\n</code></div>\n<div><code>\nfunction draw() {}\nfunction keyPressed() {\n  background('yellow');\n  text(`${key} ${keyCode}`, 10, 40);\n  print(key, ' ', keyCode);\n}\n</code></div>"],"alt":"Grey rect center. turns white when up arrow pressed and black when down\nDisplay key pressed and its keyCode in a yellow box","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":103,"description":"<p>The <a href=\"#/p5/keyPressed\">keyPressed()</a> function is called once every time a key is pressed. The\nkeyCode for the key that was pressed is stored in the <a href=\"#/p5/keyCode\">keyCode</a> variable.</p>\n<p>For non-ASCII keys, use the keyCode variable. You can check if the keyCode\nequals BACKSPACE, DELETE, ENTER, RETURN, TAB, ESCAPE, SHIFT, CONTROL,\nOPTION, ALT, UP_ARROW, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW.</p>\n<p>For ASCII keys, the key that was pressed is stored in the key variable. However, it\ndoes not distinguish between uppercase and lowercase. For this reason, it\nis recommended to use <a href=\"#/p5/keyTyped\">keyTyped()</a> to read the key variable, in which the\ncase of the variable will be distinguished.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nmay cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyPressed","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyPressed() {\n  if (keyCode === LEFT_ARROW) {\n    value = 255;\n  } else if (keyCode === RIGHT_ARROW) {\n    value = 0;\n  }\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nfunction keyPressed() {\n  // Do something\n  return false; // prevent any default behaviour\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when released\nblack rect center. turns white when left arrow pressed and black when right.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":190,"description":"<p>The <a href=\"#/p5/keyReleased\">keyReleased()</a> function is called once every time a key is released.\nSee <a href=\"#/p5/key\">key</a> and <a href=\"#/p5/keyCode\">keyCode</a> for more information.<br><br>\nBrowsers may have different default\nbehaviors attached to various key events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"keyReleased","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n  return false; // prevent any default behavior\n}\n</code>\n</div>"],"alt":"black rect center. turns white when key pressed and black when pressed again","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":243,"description":"<p>The <a href=\"#/p5/keyTyped\">keyTyped()</a> function is called once every time a key is pressed, but\naction keys such as Backspace, Delete, Ctrl, Shift, and Alt are ignored. If you are trying to detect\na keyCode for one of these keys, use the <a href=\"#/p5/keyPressed\">keyPressed()</a> function instead.\nThe most recent key typed will be stored in the key variable.</p>\n<p>Because of how operating systems handle key repeats, holding down a key\nwill cause multiple calls to <a href=\"#/p5/keyTyped\">keyTyped()</a> (and <a href=\"#/p5/keyReleased\">keyReleased()</a> as well). The\nrate of repeat is set by the operating system and how each computer is\nconfigured.<br><br>\nBrowsers may have different default behaviors attached to various key\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"keyTyped","params":[{"name":"event","description":"<p>optional KeyboardEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction keyTyped() {\n  if (key === 'a') {\n    value = 255;\n  } else if (key === 'b') {\n    value = 0;\n  }\n  // uncomment to prevent any default behavior\n  // return false;\n}\n</code>\n</div>"],"alt":"black rect center. turns white when 'a' key typed and black when 'b' pressed","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":298,"description":"<p>The onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.</p>\n","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/keyboard.js","line":308,"description":"<p>The <a href=\"#/p5/keyIsDown\">keyIsDown()</a> function checks if the key is currently down, i.e. pressed.\nIt can be used if you have an object that moves, and you want several keys\nto be able to affect its behaviour simultaneously, such as moving a\nsprite diagonally. You can put in any number representing the keyCode of\nthe key, or use any of the variable <a href=\"#/p5/keyCode\">keyCode</a> names listed\n<a href=\"http://p5js.org/reference/#p5/keyCode\">here</a>.</p>\n","itemtype":"method","name":"keyIsDown","params":[{"name":"code","description":"<p>The key to check for.</p>\n","type":"Number"}],"return":{"description":"whether key is down or not","type":"Boolean"},"example":["\n<div><code>\nlet x = 100;\nlet y = 100;\n\nfunction setup() {\n  createCanvas(512, 512);\n  fill(255, 0, 0);\n}\n\nfunction draw() {\n  if (keyIsDown(LEFT_ARROW)) {\n    x -= 5;\n  }\n\n  if (keyIsDown(RIGHT_ARROW)) {\n    x += 5;\n  }\n\n  if (keyIsDown(UP_ARROW)) {\n    y -= 5;\n  }\n\n  if (keyIsDown(DOWN_ARROW)) {\n    y += 5;\n  }\n\n  clear();\n  ellipse(x, y, 50, 50);\n}\n</code></div>\n\n<div><code>\nlet diameter = 50;\n\nfunction setup() {\n  createCanvas(512, 512);\n}\n\nfunction draw() {\n  // 107 and 187 are keyCodes for \"+\"\n  if (keyIsDown(107) || keyIsDown(187)) {\n    diameter += 1;\n  }\n\n  // 109 and 189 are keyCodes for \"-\"\n  if (keyIsDown(109) || keyIsDown(189)) {\n    diameter -= 1;\n  }\n\n  clear();\n  fill(255, 0, 0);\n  ellipse(50, 50, diameter, diameter);\n}\n</code></div>"],"alt":"50×50 red ellipse moves left, right, up and down with arrow presses.\n50×50 red ellipse gets bigger or smaller when + or - are pressed.","class":"p5","module":"Events","submodule":"Keyboard"},{"file":"src/events/mouse.js","line":12,"description":"<p>The variable movedX contains the horizontal movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedX","type":"Number","readonly":"","example":["\n <div class=\"notest\">\n <code>\n let x = 50;\n function setup() {\n   rectMode(CENTER);\n }\nfunction draw() {\n   if (x > 48) {\n     x -= 2;\n   } else if (x < 48) {\n     x += 2;\n   }\n   x += floor(movedX / 5);\n   background(237, 34, 93);\n   fill(0);\n   rect(x, 50, 50, 50);\n }\n </code>\n </div>"],"alt":"box moves left and right according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":43,"description":"<p>The variable movedY contains the vertical movement of the mouse since the last frame</p>\n","itemtype":"property","name":"movedY","type":"Number","readonly":"","example":["\n<div class=\"notest\">\n<code>\nlet y = 50;\nfunction setup() {\n  rectMode(CENTER);\n}\n\nfunction draw() {\n  if (y > 48) {\n    y -= 2;\n  } else if (y < 48) {\n    y += 2;\n  }\n  y += floor(movedY / 5);\n  background(237, 34, 93);\n  fill(0);\n  rect(y, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"box moves up and down according to mouse movement then slowly back towards the center","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":80,"description":"<p>The system variable mouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseX will hold the x value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, 0, mouseX, 100);\n}\n</code>\n</div>"],"alt":"horizontal black line moves left and right with mouse x-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":106,"description":"<p>The system variable mouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the canvas. The value at\nthe top-left corner is (0, 0) for 2-D and (-width/2, -height/2) for WebGL.\nIf touch is used instead of mouse input, mouseY will hold the y value\nof the most recent touch point.</p>\n","itemtype":"property","name":"mouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas\nfunction draw() {\n  background(244, 248, 252);\n  line(0, mouseY, 100, mouseY);\n}\n</code>\n</div>"],"alt":"vertical black line moves up and down with mouse y-position","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":132,"description":"<p>The system variable pmouseX always contains the horizontal position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseX will be reset to the current mouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\n// Move the mouse across the canvas to leave a trail\nfunction setup() {\n  //slow down the frameRate to make it more visible\n  frameRate(10);\n}\n\nfunction draw() {\n  background(244, 248, 252);\n  line(mouseX, mouseY, pmouseX, pmouseY);\n  print(pmouseX + ' -> ' + mouseX);\n}\n</code>\n</div>"],"alt":"line trail is created from cursor movements. faster movement make longer line.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":164,"description":"<p>The system variable pmouseY always contains the vertical position of\nthe mouse or finger in the frame previous to the current frame, relative to\n(0, 0) of the canvas. The value at the top-left corner is (0, 0) for 2-D and\n(-width/2, -height/2) for WebGL. Note: pmouseY will be reset to the current mouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pmouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  //draw a square only if the mouse is not moving\n  if (mouseY === pmouseY && mouseX === pmouseX) {\n    rect(20, 20, 60, 60);\n  }\n\n  print(pmouseY + ' -> ' + mouseY);\n}\n</code>\n</div>"],"alt":"60×60 black rect center, fuchsia background. rect flickers on mouse movement","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":195,"description":"<p>The system variable winMouseX always contains the current horizontal\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the horizontal mouse position\n  //relative to the window\n  myCanvas.position(winMouseX + 1, windowHeight / 2);\n\n  //the y of the square is relative to the canvas\n  rect(20, mouseY, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect y moves with mouse y and fuchsia canvas moves with mouse x","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":233,"description":"<p>The system variable winMouseY always contains the current vertical\nposition of the mouse, relative to (0, 0) of the window.</p>\n","itemtype":"property","name":"winMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  let body = document.getElementsByTagName('body')[0];\n  myCanvas.parent(body);\n}\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  //move the canvas to the vertical mouse position\n  //relative to the window\n  myCanvas.position(windowWidth / 2, winMouseY + 1);\n\n  //the x of the square is relative to the canvas\n  rect(mouseX, 20, 60, 60);\n}\n</code>\n</div>"],"alt":"60×60 black rect x moves with mouse x and fuchsia canvas y moves with mouse y","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":271,"description":"<p>The system variable pwinMouseX always contains the horizontal position\nof the mouse in the frame previous to the current frame, relative to\n(0, 0) of the window. Note: pwinMouseX will be reset to the current winMouseX\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseX","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current x position is the horizontal mouse speed\n  let speed = abs(winMouseX - pwinMouseX);\n  //change the size of the circle\n  //according to the horizontal speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":311,"description":"<p>The system variable pwinMouseY always contains the vertical position of\nthe mouse in the frame previous to the current frame, relative to (0, 0)\nof the window. Note: pwinMouseY will be reset to the current winMouseY\nvalue at the start of each touch event.</p>\n","itemtype":"property","name":"pwinMouseY","type":"Number","readonly":"","example":["\n<div>\n<code>\nlet myCanvas;\n\nfunction setup() {\n  //use a variable to store a pointer to the canvas\n  myCanvas = createCanvas(100, 100);\n  noStroke();\n  fill(237, 34, 93);\n}\n\nfunction draw() {\n  clear();\n  //the difference between previous and\n  //current y position is the vertical mouse speed\n  let speed = abs(winMouseY - pwinMouseY);\n  //change the size of the circle\n  //according to the vertical speed\n  ellipse(50, 50, 10 + speed * 5, 10 + speed * 5);\n  //move the canvas to the mouse position\n  myCanvas.position(winMouseX + 1, winMouseY + 1);\n}\n</code>\n</div>"],"alt":"fuchsia ellipse moves with mouse x and y. Grows and shrinks with mouse speed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":351,"description":"<p>p5 automatically tracks if the mouse button is pressed and which\nbutton is pressed. The value of the system variable mouseButton is either\nLEFT, RIGHT, or CENTER depending on which button was pressed last.\nWarning: different browsers may track mouseButton differently.</p>\n","itemtype":"property","name":"mouseButton","type":"Constant","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    if (mouseButton === LEFT) {\n      ellipse(50, 50, 50, 50);\n    }\n    if (mouseButton === RIGHT) {\n      rect(25, 25, 50, 50);\n    }\n    if (mouseButton === CENTER) {\n      triangle(23, 75, 50, 20, 78, 75);\n    }\n  }\n\n  print(mouseButton);\n}\n</code>\n</div>"],"alt":"50×50 black ellipse appears on center of fuchsia canvas on mouse click/press.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":389,"description":"<p>The boolean system variable mouseIsPressed is true if the mouse is pressed\nand false if not.</p>\n","itemtype":"property","name":"mouseIsPressed","type":"Boolean","readonly":"","example":["\n<div>\n<code>\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n\n  if (mouseIsPressed === true) {\n    ellipse(50, 50, 50, 50);\n  } else {\n    rect(25, 25, 50, 50);\n  }\n\n  print(mouseIsPressed);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes ellipse with mouse click/press. fuchsia background.","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":481,"description":"<p>The <a href=\"#/p5/mouseMoved\">mouseMoved()</a> function is called every time the mouse moves and a mouse\nbutton is not pressed.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseMoved","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect becomes lighter with mouse movements until white then resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":535,"description":"<p>The <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is called once every time the mouse moves and\na mouse button is pressed. If no <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function is defined, the\n<a href=\"#/p5/touchMoved\">touchMoved()</a> function will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseDragged","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Drag the mouse across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseDragged() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseDragged() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseDragged(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns lighter with mouse click and drag until white, resets\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":615,"description":"<p>The <a href=\"#/p5/mousePressed\">mousePressed()</a> function is called once after every time a mouse button\nis pressed. The mouseButton variable (see the related reference entry)\ncan be used to determine which button has been pressed. If no\n<a href=\"#/p5/mousePressed\">mousePressed()</a> function is defined, the <a href=\"#/p5/touchStarted\">touchStarted()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mousePressed","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mousePressed() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mousePressed() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mousePressed(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":696,"description":"<p>The <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is called every time a mouse button is\nreleased. If no <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function is defined, the <a href=\"#/p5/touchEnded\">touchEnded()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseReleased","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction mouseReleased() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseReleased() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseReleased(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":772,"description":"<p>The <a href=\"#/p5/mouseClicked\">mouseClicked()</a> function is called once after a mouse button has been\npressed and then released.<br><br>\nBrowsers handle clicks differently, so this function is only guaranteed to be\nrun when the left mouse button is clicked. To handle other mouse buttons\nbeing pressed or released, see <a href=\"#/p5/mousePressed\">mousePressed()</a> or <a href=\"#/p5/mouseReleased\">mouseReleased()</a>.<br><br>\nBrowsers may have different default\nbehaviors attached to various mouse events. To prevent any default\nbehavior for this event, add \"return false\" to the end of the method.</p>\n","itemtype":"method","name":"mouseClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction mouseClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction mouseClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction mouseClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse click/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":841,"description":"<p>The <a href=\"#/p5/doubleClicked\">doubleClicked()</a> function is executed every time a event\nlistener has detected a dblclick event which is a part of the\nDOM L3 specification. The doubleClicked event is fired when a\npointing device button (usually a mouse's primary button)\nis clicked twice on a single element. For more info on the\ndblclick event refer to mozilla's documentation here:\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/Events/dblclick\">https://developer.mozilla.org/en-US/docs/Web/Events/dblclick</a></p>\n","itemtype":"method","name":"doubleClicked","params":[{"name":"event","description":"<p>optional MouseEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Click within the image to change\n// the value of the rectangle\n// after the mouse has been double clicked\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\n\nfunction doubleClicked() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction doubleClicked() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a MouseEvent object\n// as a callback argument\nfunction doubleClicked(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"black 50×50 rect turns white with mouse doubleClick/press.\nno image displayed","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":926,"description":"<p>The function <a href=\"#/p5/mouseWheel\">mouseWheel()</a> is executed every time a vertical mouse wheel\nevent is detected either triggered by an actual mouse wheel or by a\ntouchpad.<br><br>\nThe event.delta property returns the amount the mouse wheel\nhave scrolled. The values can be positive or negative depending on the\nscroll direction (on OS X with \"natural\" scrolling enabled, the signs\nare inverted).<br><br>\nBrowsers may have different default behaviors attached to various\nmouse events. To prevent any default behavior for this event, add\n\"return false\" to the end of the method.<br><br>\nDue to the current support of the \"wheel\" event on Safari, the function\nmay only work as expected if \"return false\" is included while using Safari.</p>\n","itemtype":"method","name":"mouseWheel","params":[{"name":"event","description":"<p>optional WheelEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\nlet pos = 25;\n\nfunction draw() {\n  background(237, 34, 93);\n  fill(0);\n  rect(25, pos, 50, 50);\n}\n\nfunction mouseWheel(event) {\n  print(event.delta);\n  //move the square according to the vertical scroll amount\n  pos += event.delta;\n  //uncomment to block page scrolling\n  //return false;\n}\n</code>\n</div>"],"alt":"black 50×50 rect moves up and down with vertical scroll. fuchsia background","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":979,"description":"<p>The function <a href=\"#/p5/requestPointerLock\">requestPointerLock()</a>\nlocks the pointer to its current position and makes it invisible.\nUse <a href=\"#/p5/movedX\">movedX</a> and <a href=\"#/p5/movedY\">movedY</a> to get the difference the mouse was moved since\nthe last call of draw.\nNote that not all browsers support this feature.\nThis enables you to create experiences that aren't limited by the mouse moving out of the screen\neven if it is repeatedly moved into one direction.\nFor example, a first person perspective experience.</p>\n","itemtype":"method","name":"requestPointerLock","example":["\n<div class=\"notest\">\n<code>\nlet cam;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  requestPointerLock();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(255);\n  cam.pan(-movedX * 0.001);\n  cam.tilt(movedY * 0.001);\n  sphere(25);\n}\n</code>\n</div>"],"alt":"3D scene moves according to mouse mouse movement in a first person perspective","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/mouse.js","line":1025,"description":"<p>The function <a href=\"#/p5/exitPointerLock\">exitPointerLock()</a>\nexits a previously triggered <a href=\"#/p5/requestPointerLock\">pointer Lock</a>\nfor example to make ui elements usable etc</p>\n","itemtype":"method","name":"exitPointerLock","example":["\n<div class=\"notest\">\n<code>\n//click the canvas to lock the pointer\n//click again to exit (otherwise escape)\nlet locked = false;\nfunction draw() {\n  background(237, 34, 93);\n}\nfunction mouseClicked() {\n  if (!locked) {\n    locked = true;\n    requestPointerLock();\n  } else {\n    exitPointerLock();\n    locked = false;\n  }\n}\n</code>\n</div>"],"alt":"cursor gets locked / unlocked on mouse-click","class":"p5","module":"Events","submodule":"Mouse"},{"file":"src/events/touch.js","line":10,"description":"<p>The system variable touches[] contains an array of the positions of all\ncurrent touch points, relative to (0, 0) of the canvas, and IDs identifying a\nunique touch as it moves. Each element in the array is an object with x, y,\nand id properties.</p>\n<p>The touches[] array is not supported on Safari and IE on touch-based\ndesktops (laptops).</p>\n","itemtype":"property","name":"touches","type":"Object[]","readonly":"","example":["\n<div>\n<code>\n// On a touchscreen device, touch\n// the canvas using one or more fingers\n// at the same time\nfunction draw() {\n  clear();\n  let display = touches.length + ' touches';\n  text(display, 5, 10);\n}\n</code>\n</div>"],"alt":"Number of touches currently registered are displayed on the canvas","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":71,"description":"<p>The touchStarted() function is called once after every time a touch is\nregistered. If no <a href=\"#/p5/touchStarted\">touchStarted()</a> function is defined, the <a href=\"#/p5/mousePressed\">mousePressed()</a>\nfunction will be called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchStarted","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Touch within the image to change\n// the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchStarted() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchStarted() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchStarted(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch event.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":151,"description":"<p>The <a href=\"#/p5/touchMoved\">touchMoved()</a> function is called every time a touch move is registered.\nIf no <a href=\"#/p5/touchMoved\">touchMoved()</a> function is defined, the <a href=\"#/p5/mouseDragged\">mouseDragged()</a> function will\nbe called instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchMoved","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Move your finger across the page\n// to change its value\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchMoved() {\n  value = value + 5;\n  if (value > 255) {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchMoved() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchMoved(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns lighter with touch until white. resets\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/events/touch.js","line":223,"description":"<p>The <a href=\"#/p5/touchEnded\">touchEnded()</a> function is called every time a touch ends. If no\n<a href=\"#/p5/touchEnded\">touchEnded()</a> function is defined, the <a href=\"#/p5/mouseReleased\">mouseReleased()</a> function will be\ncalled instead if it is defined.<br><br>\nBrowsers may have different default behaviors attached to various touch\nevents. To prevent any default behavior for this event, add \"return false\"\nto the end of the method.</p>\n","itemtype":"method","name":"touchEnded","params":[{"name":"event","description":"<p>optional TouchEvent callback argument.</p>\n","type":"Object","optional":true}],"example":["\n<div>\n<code>\n// Release touch within the image to\n// change the value of the rectangle\n\nlet value = 0;\nfunction draw() {\n  fill(value);\n  rect(25, 25, 50, 50);\n}\nfunction touchEnded() {\n  if (value === 0) {\n    value = 255;\n  } else {\n    value = 0;\n  }\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nfunction touchEnded() {\n  ellipse(mouseX, mouseY, 5, 5);\n  // prevent default\n  return false;\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// returns a TouchEvent object\n// as a callback argument\nfunction touchEnded(event) {\n  console.log(event);\n}\n</code>\n</div>"],"alt":"50×50 black rect turns white with touch.\nno image displayed","class":"p5","module":"Events","submodule":"Touch"},{"file":"src/image/filters.js","line":3,"description":"<p>This module defines the filters for use with image buffers.</p>\n<p>This module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.</p>\n<p>Generally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.</p>\n<p>A number of functions are borrowed/adapted from\n<a href=\"http://www.html5rocks.com/en/tutorials/canvas/imagefilters/\">http://www.html5rocks.com/en/tutorials/canvas/imagefilters/</a>\nor the java processing implementation.</p>\n","class":"p5","module":"Events"},{"file":"src/image/image.js","line":8,"description":"<p>This module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.</p>\n","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":15,"description":"<p>Creates a new <a href=\"#/p5.Image\">p5.Image</a> (the datatype for storing images). This provides a\nfresh buffer of pixels to play with. Set the size of the buffer with the\nwidth and height parameters.</p>\n<p>.<a href=\"#/p5.Image/pixels\">pixels</a> gives access to an array containing the values for all the pixels\nin the display window.\nThese values are numbers. This array is the size (including an appropriate\nfactor for the <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. See .<a href=\"#/p5.Image/pixels\">pixels</a> for\nmore info. It may also be simpler to use <a href=\"#/p5.Image/set\">set()</a> or <a href=\"#/p5.Image/get\">get()</a>.</p>\n<p>Before accessing the pixels of an image, the data must loaded with the\n<a href=\"#/p5.Image/loadPixels\">loadPixels()</a> function. After the array data has been modified, the\n<a href=\"#/p5.Image/updatePixels\">updatePixels()</a> function must be run to update the changes.</p>\n","itemtype":"method","name":"createImage","params":[{"name":"width","description":"<p>width in pixels</p>\n","type":"Integer"},{"name":"height","description":"<p>height in pixels</p>\n","type":"Integer"}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>\n\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (img.width * d) * (img.height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 dark turquoise rect in center of canvas.\n2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas\nno image displayed","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/image.js","line":94,"description":"<p>Save the current canvas as an image. The browser will either save the\nfile immediately, or prompt the user with a dialogue window.</p>\n","itemtype":"method","name":"saveCanvas","example":["\n <div class='norender notest'><code>\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas(c, 'myCanvas', 'jpg');\n }\n </code></div>\n <div class='norender notest'><code>\n // note that this example has the same result as above\n // if no canvas is specified, defaults to main canvas\n function setup() {\n let c = createCanvas(100, 100);\n background(255, 0, 0);\n saveCanvas('myCanvas', 'jpg');\n\n // all of the following are valid\n saveCanvas(c, 'myCanvas', 'jpg');\n saveCanvas(c, 'myCanvas.jpg');\n saveCanvas(c, 'myCanvas');\n saveCanvas(c);\n saveCanvas('myCanvas', 'png');\n saveCanvas('myCanvas');\n saveCanvas();\n }\n </code></div>"],"alt":"no image displayed\n no image displayed\n no image displayed","class":"p5","module":"Image","submodule":"Image","overloads":[{"line":94,"params":[{"name":"selectedCanvas","description":"<p>a variable\n                                representing a specific html5 canvas (optional)</p>\n","type":"p5.Element|HTMLCanvasElement"},{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String","optional":true}]},{"line":136,"params":[{"name":"filename","description":"","type":"String","optional":true},{"name":"extension","description":"","type":"String","optional":true}]}]},{"file":"src/image/image.js","line":413,"description":"<p>Capture a sequence of frames that can be used to create a movie.\nAccepts a callback. For example, you may wish to send the frames\nto a server where they can be stored or converted into a movie.\nIf no callback is provided, the browser will pop up save dialogues in an\nattempt to download all of the images that have just been created. With the\ncallback provided the image data isn't saved by default but instead passed\nas an argument to the callback function as an array of objects, with the\nsize of array equal to the total number of frames.</p>\n<p>Note that <a href=\"#/p5.Image/saveFrames\">saveFrames()</a> will only save the first 15 frames of an animation.\nTo export longer animations, you might look into a library like\n<a href=\"https://github.com/spite/ccapture.js/\">ccapture.js</a>.</p>\n","itemtype":"method","name":"saveFrames","params":[{"name":"filename","description":"","type":"String"},{"name":"extension","description":"<p>'jpg' or 'png'</p>\n","type":"String"},{"name":"duration","description":"<p>Duration in seconds to save the frames for.</p>\n","type":"Number"},{"name":"framerate","description":"<p>Framerate to save the frames in.</p>\n","type":"Number"},{"name":"callback","description":"<p>A callback function that will be executed\n                                to handle the image data. This function\n                                should accept an array as argument. The\n                                array will contain the specified number of\n                                frames of objects. Each object has three\n                                properties: imageData - an\n                                image/octet-stream, filename and extension.</p>\n","type":"Function(Array)","optional":true}],"example":["\n<div><code>\n function draw() {\n background(mouseX);\n }\n\n function mousePressed() {\n saveFrames('out', 'png', 1, 25, data => {\n   print(data);\n });\n }\n</code></div>"],"alt":"canvas background goes from light to dark with mouse x.","class":"p5","module":"Image","submodule":"Image"},{"file":"src/image/loading_displaying.js","line":18,"description":"<p>Loads an image from a path and creates a <a href=\"#/p5.Image\">p5.Image</a> from it.</p>\n<p>The image may not be immediately available for rendering.\nIf you want to ensure that the image is ready before doing\nanything with it, place the <a href=\"#/p5/loadImage\">loadImage()</a> call in <a href=\"#/p5/preload\">preload()</a>.\nYou may also supply a callback function to handle the image when it's ready.</p>\n<p>The path to the image should be relative to the HTML file\nthat links in your sketch. Loading an image from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n<p>You can also pass in a string of a base64 encoded image as an alternative to the file path.\nRemember to add \"data:image/png;base64,\" in front of the string.</p>\n","itemtype":"method","name":"loadImage","params":[{"name":"path","description":"<p>Path of the image to be loaded</p>\n","type":"String"},{"name":"successCallback","description":"<p>Function to be called once\n                               the image is loaded. Will be passed the\n                               <a href=\"#/p5.Image\">p5.Image</a>.</p>\n","type":"function(p5.Image)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                               the image fails to load.</p>\n","type":"Function(Event)","optional":true}],"return":{"description":"the <a href=\"#/p5.Image\">p5.Image</a> object","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // here we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and grided ceililng above\nimage of the underside of a white umbrella and grided ceililng above","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":162,"description":"<p>Helper function for loading GIF-based images</p>\n","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":301,"description":"<p>Draw an image to the p5.js canvas.</p>\n<p>This function can be used with different numbers of parameters. The\nsimplest use requires only three parameters: img, x, and y—where (x, y) is\nthe position of the image. Two more parameters can optionally be added to\nspecify the width and height of the image.</p>\n<p>This function can also be used with all eight Number parameters. To\ndifferentiate between all these parameters, p5.js uses the language of\n\"destination rectangle\" (which corresponds to \"dx\", \"dy\", etc.) and \"source\nimage\" (which corresponds to \"sx\", \"sy\", etc.) below. Specifying the\n\"source image\" dimensions can be useful when you want to display a\nsubsection of the source image instead of the whole thing. Here's a diagram\nto explain further:\n<img src=\"assets/drawImage.png\"></img></p>\n","itemtype":"method","name":"image","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height\n  image(img, 0, 0);\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  background(50);\n  // Top-left corner of the img is at (10, 10)\n  // Width and height are 50×50\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  // Here, we use a callback to display the image after loading\n  loadImage('assets/laDefense.jpg', img => {\n    image(img, 0, 0);\n  });\n}\n</code>\n</div>\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/gradient.png');\n}\nfunction setup() {\n  // 1. Background image\n  // Top-left corner of the img is at (0, 0)\n  // Width and height are the img's original width and height, 100×100\n  image(img, 0, 0);\n  // 2. Top right image\n  // Top-left corner of destination rectangle is at (50, 0)\n  // Destination rectangle width and height are 40×20\n  // The next parameters are relative to the source image:\n  // - Starting at position (50, 50) on the source image, capture a 50×50\n  // subsection\n  // - Draw this subsection to fill the dimensions of the destination rectangle\n  image(img, 50, 0, 40, 20, 50, 50, 50, 50);\n}\n</code>\n</div>"],"alt":"image of the underside of a white umbrella and gridded ceiling above\nimage of the underside of a white umbrella and gridded ceiling above","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":301,"params":[{"name":"img","description":"<p>the image to display</p>\n","type":"p5.Image|p5.Element|p5.Texture"},{"name":"x","description":"<p>the x-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"y","description":"<p>the y-coordinate of the top-left corner of the image</p>\n","type":"Number"},{"name":"width","description":"<p>the width to draw the image</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>the height to draw the image</p>\n","type":"Number","optional":true}]},{"line":388,"params":[{"name":"img","description":"","type":"p5.Image|p5.Element|p5.Texture"},{"name":"dx","description":"<p>the x-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dy","description":"<p>the y-coordinate of the destination\n                          rectangle in which to draw the source image</p>\n","type":"Number"},{"name":"dWidth","description":"<p>the width of the destination rectangle</p>\n","type":"Number"},{"name":"dHeight","description":"<p>the height of the destination rectangle</p>\n","type":"Number"},{"name":"sx","description":"<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sy","description":"<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n","type":"Number"},{"name":"sWidth","description":"<p>the width of the subsection of the\n                          source image to draw into the destination\n                          rectangle</p>\n","type":"Number","optional":true},{"name":"sHeight","description":"<p>the height of the subsection of the\n                           source image to draw into the destination rectangle</p>\n","type":"Number","optional":true}]}]},{"file":"src/image/loading_displaying.js","line":471,"description":"<p>Sets the fill value for displaying images. Images can be tinted to\nspecified colors or made transparent by including an alpha value.</p>\n<p>To apply transparency to an image without affecting its color, use\nwhite as the tint color and specify an alpha value. For instance,\ntint(255, 128) will make an image 50% transparent (assuming the default\nalpha range of 0-255, which can be changed with <a href=\"#/p5/colorMode\">colorMode()</a>).</p>\n<p>The value for the gray parameter must be less than or equal to the current\nmaximum value as specified by <a href=\"#/p5/colorMode\">colorMode()</a>. The default maximum value is\n255.</p>\n","itemtype":"method","name":"tint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204); // Tint blue\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(0, 153, 204, 126); // Tint blue and set transparency\n  image(img, 50, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  tint(255, 126); // Apply transparency without changing color\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of umbrella and ceiling, one image with blue tint\nImages of umbrella and ceiling, one half of image with blue tint\n2 side by side images of umbrella and ceiling, one image translucent","class":"p5","module":"Image","submodule":"Loading & Displaying","overloads":[{"line":471,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":542,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}]},{"line":547,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}]},{"line":553,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}]},{"line":559,"params":[{"name":"color","description":"<p>the tint color</p>\n","type":"p5.Color"}]}]},{"file":"src/image/loading_displaying.js","line":569,"description":"<p>Removes the current fill value for displaying images and reverts to\ndisplaying images with their original hues.</p>\n","itemtype":"method","name":"noTint","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  tint(0, 153, 204); // Tint blue\n  image(img, 0, 0);\n  noTint(); // Disable tint\n  image(img, 50, 0);\n}\n</code>\n</div>"],"alt":"2 side by side images of bricks, left image with blue tint","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/loading_displaying.js","line":633,"description":"<p>Set image mode. Modifies the location from which images are drawn by\nchanging the way in which parameters given to <a href=\"#/p5/image\">image()</a> are interpreted.\nThe default mode is imageMode(CORNER), which interprets the second and\nthird parameters of <a href=\"#/p5/image\">image()</a> as the upper-left corner of the image. If\ntwo additional parameters are specified, they are used to set the image's\nwidth and height.</p>\n<p>imageMode(CORNERS) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the location of one corner, and the fourth and fifth parameters as the\nopposite corner.</p>\n<p>imageMode(CENTER) interprets the second and third parameters of <a href=\"#/p5/image\">image()</a>\nas the image's center point. If two additional parameters are specified,\nthey are used to set the image's width and height.</p>\n","itemtype":"method","name":"imageMode","params":[{"name":"mode","description":"<p>either CORNER, CORNERS, or CENTER</p>\n","type":"Constant"}],"example":["\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNER);\n  image(img, 10, 10, 50, 50);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CORNERS);\n  image(img, 10, 10, 90, 40);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  imageMode(CENTER);\n  image(img, 50, 50, 80, 80);\n}\n</code>\n</div>"],"alt":"small square image of bricks\nhorizontal rectangle image of bricks\nlarge square image of bricks","class":"p5","module":"Image","submodule":"Loading & Displaying"},{"file":"src/image/p5.Image.js","line":9,"description":"<p>This module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":88,"description":"<p>Image width.</p>\n","itemtype":"property","name":"width","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.width; i++) {\n    let c = img.get(i, img.height / 2);\n    stroke(c);\n    line(i, height / 2, i, height);\n  }\n}\n</code></div>"],"alt":"rocky mountains in top and horizontal lines in corresponding colors in bottom.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":115,"description":"<p>Image height.</p>\n","itemtype":"property","name":"height","type":"Number","readonly":"","example":["\n<div><code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  image(img, 0, 0);\n  for (let i = 0; i < img.height; i++) {\n    let c = img.get(img.width / 2, i);\n    stroke(c);\n    line(0, i, width / 2, i);\n  }\n}\n</code></div>"],"alt":"rocky mountains on right and vertical lines in corresponding colors on left.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":152,"description":"<p>Array containing the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for pixelDensity) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays may have more pixels (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. With\npixelDensity = 2, there will be 160,000. The first four values\n(indices 0-3) in the array will be the R, G, B, A values of the pixel at\n(0, 0). The second four values (indices 4-7) will contain the R, G, B, A\nvalues of the pixel at (1, 0). More generally, to set values for a pixel\nat (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5.Image/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>\n<div>\n<code>\nlet pink = color(255, 102, 204);\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < 4 * (width * height / 2); i += 4) {\n  img.pixels[i] = red(pink);\n  img.pixels[i + 1] = green(pink);\n  img.pixels[i + 2] = blue(pink);\n  img.pixels[i + 3] = alpha(pink);\n}\nimg.updatePixels();\nimage(img, 17, 17);\n</code>\n</div>"],"alt":"66×66 turquoise rect in center of canvas\n66×66 pink rect in center of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":222,"description":"<p>Helper function for animating GIF-based images with time</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":253,"description":"<p>Helper fxn for sharing pixel methods</p>\n","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":261,"description":"<p>Loads the pixels data for this image into the [pixels] attribute.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":296,"description":"<p>Updates the backing canvas for this image with the contents of\nthe [pixels] array.</p>\n<p>If this image is an animated GIF then the pixels will be updated\nin the frame that is currently displayed.</p>\n","itemtype":"method","name":"updatePixels","example":["\n<div><code>\nlet myImage;\nlet halfImage;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  myImage.loadPixels();\n  halfImage = 4 * myImage.width * myImage.height / 2;\n  for (let i = 0; i < halfImage; i++) {\n    myImage.pixels[i + halfImage] = myImage.pixels[i];\n  }\n  myImage.updatePixels();\n}\n\nfunction draw() {\n  image(myImage, 0, 0, width, height);\n}\n</code></div>"],"alt":"2 images of rocky mountains vertically stacked","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":296,"params":[{"name":"x","description":"<p>x-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"y","description":"<p>y-offset of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"w","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"},{"name":"h","description":"<p>height of the target update area for the\n                             underlying canvas</p>\n","type":"Integer"}]},{"line":338,"params":[]}]},{"file":"src/image/p5.Image.js","line":346,"description":"<p>Get a region of pixels from an image.</p>\n<p>If no params are passed, the whole image is returned.\nIf x and y are the only params passed a single pixel is extracted.\nIf all params are passed a rectangle region is extracted and a <a href=\"#/p5.Image\">p5.Image</a>\nis returned.</p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div><code>\nlet myImage;\nlet c;\n\nfunction preload() {\n  myImage = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(myImage);\n  noStroke();\n  c = myImage.get(60, 90);\n  fill(c);\n  rect(25, 25, 50, 50);\n}\n\n//get() returns color here\n</code></div>"],"alt":"image of rocky mountains with 50×50 green rect in front","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":346,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":383,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":387,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/p5.Image.js","line":400,"description":"<p>Set the color of a single pixel or write an image into\nthis <a href=\"#/p5.Image\">p5.Image</a>.</p>\n<p>Note that for a large number of pixels this will\nbe slower than directly manipulating the pixels array\nand then calling <a href=\"#/p5.Image/updatePixels\">updatePixels()</a>.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"a","description":"<p>grayscale value | pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> | image to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet img = createImage(66, 66);\nimg.loadPixels();\nfor (let i = 0; i < img.width; i++) {\n  for (let j = 0; j < img.height; j++) {\n    img.set(i, j, color(0, 90, 102, (i % img.width) * 2));\n  }\n}\nimg.updatePixels();\nimage(img, 17, 17);\nimage(img, 34, 34);\n</code>\n</div>"],"alt":"2 gradated dark turquoise rects fade left. 1 center 1 bottom right of canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":437,"description":"<p>Resize the image to a new width and height. To make the image scale\nproportionally, use 0 as the value for the wide or high parameter.\nFor instance, to make the width of an image 150 pixels, and change\nthe height using the same proportion, use resize(150, 0).</p>\n","itemtype":"method","name":"resize","params":[{"name":"width","description":"<p>the resized image width</p>\n","type":"Number"},{"name":"height","description":"<p>the resized image height</p>\n","type":"Number"}],"example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(img, 0, 0);\n}\n\nfunction mousePressed() {\n  img.resize(50, 100);\n}\n</code></div>"],"alt":"image of rocky mountains. zoomed in","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":548,"description":"<p>Copies a region of pixels from one image to another. If no\nsrcImage is specified this is used as the source. If the source\nand destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet photo;\nlet bricks;\nlet x;\nlet y;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks.jpg');\n}\n\nfunction setup() {\n  x = bricks.width / 2;\n  y = bricks.height / 2;\n  photo.copy(bricks, 0, 0, x, y, 0, 0, x, y);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains and smaller image on top of bricks at top left","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":548,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":588,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/p5.Image.js","line":603,"description":"<p>Masks part of an image from displaying by loading another\nimage and using its alpha channel as an alpha channel for\nthis image. Masks are cumulative, one applied to an image\nobject, they cannot be removed.</p>\n","itemtype":"method","name":"mask","params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"}],"example":["\n<div><code>\nlet photo, maskImage;\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n  maskImage = loadImage('assets/mask2.png');\n}\n\nfunction setup() {\n  createCanvas(100, 100);\n  photo.mask(maskImage);\n  image(photo, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains with white at right\n\nhttp://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":665,"description":"<p>Applies an image filter to a <a href=\"#/p5.Image\">p5.Image</a></p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet photo1;\nlet photo2;\n\nfunction preload() {\n  photo1 = loadImage('assets/rockies.jpg');\n  photo2 = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  photo2.filter(GRAY);\n  image(photo1, 0, 0);\n  image(photo2, width / 2, 0);\n}\n</code></div>"],"alt":"2 images of rocky mountains left one in color, right in black and white","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":738,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>\n<div><code>\nlet mountains;\nlet bricks;\n\nfunction preload() {\n  mountains = loadImage('assets/rockies.jpg');\n  bricks = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  mountains.blend(bricks, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n  image(mountains, 0, 0);\n  image(bricks, 0, 0);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5.Image","module":"Image","submodule":"Image","overloads":[{"line":738,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n<p>Available blend modes are: normal | multiply | screen | overlay |\n           darken | lighten | color-dodge | color-burn | hard-light |\n           soft-light | difference | exclusion | hue | saturation |\n           color | luminosity</p>\n<p><a href=\"http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/\">http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/</a></p>\n","type":"Constant"}]},{"line":815,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/p5.Image.js","line":859,"description":"<p>Saves the image to a file and force the browser to download it.\nAccepts two strings for filename and file extension\nSupports png (default), jpg, and gif\n<br><br>\nNote that the file will only be downloaded as an animated GIF\nif the p5.Image was loaded from a GIF file.</p>\n","itemtype":"method","name":"save","params":[{"name":"filename","description":"<p>give your file a name</p>\n","type":"String"},{"name":"extension","description":"<p>'png' or 'jpg'</p>\n","type":"String"}],"example":["\n<div><code>\nlet photo;\n\nfunction preload() {\n  photo = loadImage('assets/rockies.jpg');\n}\n\nfunction draw() {\n  image(photo, 0, 0);\n}\n\nfunction keyTyped() {\n  if (key === 's') {\n    photo.save('photo', 'png');\n  }\n}\n</code></div>"],"alt":"image of rocky mountains.","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":900,"description":"<p>Starts an animated GIF over at the beginning state.</p>\n","itemtype":"method","name":"reset","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-wink-loop-once.gif');\n}\n\nfunction draw() {\n  background(255);\n  // The GIF file that we loaded only loops once\n  // so it freezes on the last frame after playing through\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  // Click to reset the GIF and begin playback from start\n  gif.reset();\n}\n</code></div>"],"alt":"Animated image of a cartoon face that winks once and then freezes\nWhen you click it animates again, winks once and freezes","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":941,"description":"<p>Gets the index for the frame that is currently visible in an animated GIF.</p>\n","itemtype":"method","name":"getCurrentFrame","return":{"description":"The index for the currently displaying frame in animated GIF","type":"Number"},"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction draw() {\n  let frame = gif.getCurrentFrame();\n  image(gif, 0, 0);\n  text(frame, 10, 90);\n}\n</code></div>"],"alt":"Animated image of a cartoon eye looking around and then\nlooking outwards, in the lower-left hand corner a number counts\nup quickly to 124 and then starts back over at 0","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":972,"description":"<p>Sets the index of the frame that is currently visible in an animated GIF</p>\n","itemtype":"method","name":"setFrame","params":[{"name":"index","description":"<p>the index for the frame that should be displayed</p>\n","type":"Number"}],"example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1017,"description":"<p>Returns the number of frames in an animated GIF</p>\n","itemtype":"method","name":"numFrames","return":{"description":"","type":"Number"},"example":["     The number of frames in the animated GIF\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\n// Move your mouse up and down over canvas to see the GIF\n// frames animate\nfunction draw() {\n  gif.pause();\n  image(gif, 0, 0);\n  // Get the highest frame number which is the number of frames - 1\n  let maxFrame = gif.numFrames() - 1;\n  // Set the current frame that is mapped to be relative to mouse position\n  let frameNumber = floor(map(mouseY, 0, height, 0, maxFrame, true));\n  gif.setFrame(frameNumber);\n}\n</code></div>"],"alt":"A still image of a cartoon eye that looks around when you move your mouse\nup and down over the canvas","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1052,"description":"<p>Plays an animated GIF that was paused with\n<a href=\"#/p5.Image/pause\">pause()</a></p>\n","itemtype":"method","name":"play","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1089,"description":"<p>Pauses an animated GIF.</p>\n","itemtype":"method","name":"pause","example":["\n<div><code>\nlet gif;\n\nfunction preload() {\n  gif = loadImage('assets/nancy-liang-wind-loop-forever.gif');\n}\n\nfunction draw() {\n  background(255);\n  image(gif, 0, 0);\n}\n\nfunction mousePressed() {\n  gif.pause();\n}\n\nfunction mouseReleased() {\n  gif.play();\n}\n</code></div>"],"alt":"An animated GIF of a drawing of small child with\nhair blowing in the wind, when you click the image\nfreezes when you release it animates again","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/p5.Image.js","line":1125,"description":"<p>Changes the delay between frames in an animated GIF. There is an optional second parameter that\nindicates an index for a specific frame that should have its delay modified. If no index is given, all frames\nwill have the new delay.</p>\n","itemtype":"method","name":"delay","params":[{"name":"d","description":"<p>the amount in milliseconds to delay between switching frames</p>\n","type":"Number"},{"name":"index","description":"<p>the index of the frame that should have the new delay value {optional}</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet gifFast, gifSlow;\n\nfunction preload() {\n  gifFast = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n  gifSlow = loadImage('assets/arnott-wallace-eye-loop-forever.gif');\n}\n\nfunction setup() {\n  gifFast.resize(width / 2, height / 2);\n  gifSlow.resize(width / 2, height / 2);\n\n  //Change the delay here\n  gifFast.delay(10);\n  gifSlow.delay(100);\n}\n\nfunction draw() {\n  background(255);\n  image(gifFast, 0, 0);\n  image(gifSlow, width / 2, 0);\n}\n</code></div>"],"alt":"Two animated gifs of cartoon eyes looking around\nThe gif on the left animates quickly, on the right\nthe animation is much slower","class":"p5.Image","module":"Image","submodule":"Image"},{"file":"src/image/pixels.js","line":12,"description":"<p><a href='https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference\n/Global_Objects/Uint8ClampedArray' target='_blank'>Uint8ClampedArray</a>\ncontaining the values for all the pixels in the display window.\nThese values are numbers. This array is the size (include an appropriate\nfactor for <a href=\"#/p5/pixelDensity\">pixelDensity</a>) of the display window x4,\nrepresenting the R, G, B, A values in order for each pixel, moving from\nleft to right across each row, then down each column. Retina and other\nhigh density displays will have more pixels[] (by a factor of\npixelDensity^2).\nFor example, if the image is 100×100 pixels, there will be 40,000. On a\nretina display, there will be 160,000.</p>\n<p>The first four values (indices 0-3) in the array will be the R, G, B, A\nvalues of the pixel at (0, 0). The second four values (indices 4-7) will\ncontain the R, G, B, A values of the pixel at (1, 0). More generally, to\nset values for a pixel at (x, y):</p>\n<pre><code class=\"language-javascript\">let d = pixelDensity();\nfor (let i = 0; i < d; i++) {\n  for (let j = 0; j < d; j++) {\n    // loop over\n    index = 4 * ((y * d + j) * width * d + (x * d + i));\n    pixels[index] = r;\n    pixels[index+1] = g;\n    pixels[index+2] = b;\n    pixels[index+3] = a;\n  }\n}</code></pre>\n<p>While the above method is complex, it is flexible enough to work with\nany pixelDensity. Note that <a href=\"#/p5/set\">set()</a> will automatically take care of\nsetting all the appropriate values in <a href=\"#/p5/pixels\">pixels[]</a> for a given (x, y) at\nany pixelDensity, but the performance may not be as fast when lots of\nmodifications are made to the pixel array.</p>\n<p>Before accessing this array, the data must loaded with the <a href=\"#/p5/loadPixels\">loadPixels()</a>\nfunction. After the array data has been modified, the <a href=\"#/p5/updatePixels\">updatePixels()</a>\nfunction must be run to update the changes.</p>\n<p>Note that this is not a standard javascript array.  This means that\nstandard javascript functions such as <a href=\"#/p5/slice\">slice()</a> or\n<a href=\"#/p5/arrayCopy\">arrayCopy()</a> do not\nwork.</p>\n","itemtype":"property","name":"pixels","type":"Number[]","example":["\n<div>\n<code>\nlet pink = color(255, 102, 204);\nloadPixels();\nlet d = pixelDensity();\nlet halfImage = 4 * (width * d) * (height / 2 * d);\nfor (let i = 0; i < halfImage; i += 4) {\n  pixels[i] = red(pink);\n  pixels[i + 1] = green(pink);\n  pixels[i + 2] = blue(pink);\n  pixels[i + 3] = alpha(pink);\n}\nupdatePixels();\n</code>\n</div>"],"alt":"top half of canvas pink, bottom grey","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":80,"description":"<p>Copies a region of pixels from one image to another, using a specified\nblend mode to do the operation.</p>\n","itemtype":"method","name":"blend","example":["\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, LIGHTEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, DARKEST);\n}\n</code></div>\n<div><code>\nlet img0;\nlet img1;\n\nfunction preload() {\n  img0 = loadImage('assets/rockies.jpg');\n  img1 = loadImage('assets/bricks_third.jpg');\n}\n\nfunction setup() {\n  background(img0);\n  image(img1, 0, 0);\n  blend(img1, 0, 0, 33, 100, 67, 0, 33, 100, ADD);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":80,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"},{"name":"blendMode","description":"<p>the blend mode. either\n    BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n    MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n    SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n","type":"Constant"}]},{"line":152,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"},{"name":"blendMode","description":"","type":"Constant"}]}]},{"file":"src/image/pixels.js","line":173,"description":"<p>Copies a region of the canvas to another region of the canvas\nand copies a region of pixels from an image used as the srcImg parameter\ninto the canvas srcImage is specified this is used as the source. If\nthe source and destination regions aren't the same size, it will\nautomatically resize source pixels to fit the specified\ntarget region.</p>\n","itemtype":"method","name":"copy","example":["\n<div><code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  background(img);\n  copy(img, 7, 22, 10, 10, 35, 25, 50, 50);\n  stroke(255);\n  noFill();\n  // Rectangle shows area being copied\n  rect(7, 22, 10, 10);\n}\n</code></div>"],"alt":"image of rocky mountains. Brick images on left and right. Right overexposed\nimage of rockies. Brickwall images on left and right. Right mortar transparent\nimage of rockies. Brickwall images on left and right. Right translucent","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":173,"params":[{"name":"srcImage","description":"<p>source image</p>\n","type":"p5.Image|p5.Element"},{"name":"sx","description":"<p>X coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sy","description":"<p>Y coordinate of the source's upper left corner</p>\n","type":"Integer"},{"name":"sw","description":"<p>source image width</p>\n","type":"Integer"},{"name":"sh","description":"<p>source image height</p>\n","type":"Integer"},{"name":"dx","description":"<p>X coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dy","description":"<p>Y coordinate of the destination's upper left corner</p>\n","type":"Integer"},{"name":"dw","description":"<p>destination image width</p>\n","type":"Integer"},{"name":"dh","description":"<p>destination image height</p>\n","type":"Integer"}]},{"line":215,"params":[{"name":"sx","description":"","type":"Integer"},{"name":"sy","description":"","type":"Integer"},{"name":"sw","description":"","type":"Integer"},{"name":"sh","description":"","type":"Integer"},{"name":"dx","description":"","type":"Integer"},{"name":"dy","description":"","type":"Integer"},{"name":"dw","description":"","type":"Integer"},{"name":"dh","description":"","type":"Integer"}]}]},{"file":"src/image/pixels.js","line":307,"description":"<p>Applies a filter to the canvas. The presets options are:</p>\n<p>THRESHOLD\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.</p>\n<p>GRAY\nConverts any colors in the image to grayscale equivalents. No parameter\nis used.</p>\n<p>OPAQUE\nSets the alpha channel to entirely opaque. No parameter is used.</p>\n<p>INVERT\nSets each pixel to its inverse value. No parameter is used.</p>\n<p>POSTERIZE\nLimits each channel of the image to the number of colors specified as the\nparameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.</p>\n<p>BLUR\nExecutes a Gaussian blur with the level parameter specifying the extent\nof the blurring. If no parameter is used, the blur is equivalent to\nGaussian blur of radius 1. Larger values increase the blur.</p>\n<p>ERODE\nReduces the light areas. No parameter is used.</p>\n<p>DILATE\nIncreases the light areas. No parameter is used.</p>\n<p>filter() does not work in WEBGL mode.\nA similar effect can be achieved in WEBGL mode using custom\nshaders. Adam Ferriss has written\na <a href=\"https://github.com/aferriss/p5jsShaderExamples\"\ntarget='_blank'>selection of shader examples</a> that contains many\nof the effects present in the filter examples.</p>\n","itemtype":"method","name":"filter","params":[{"name":"filterType","description":"<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n                               POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n                               See Filters.js for docs on\n                               each available filter</p>\n","type":"Constant"},{"name":"filterParam","description":"<p>an optional parameter unique\n                               to each filter, see above</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(THRESHOLD);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(GRAY);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(OPAQUE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(INVERT);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(POSTERIZE, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(DILATE);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(BLUR, 3);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/bricks.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  filter(ERODE);\n}\n</code>\n</div>"],"alt":"black and white image of a brick wall.\ngreyscale image of a brickwall\nimage of a brickwall\njade colored image of a brickwall\nred and pink image of a brickwall\nimage of a brickwall\nblurry image of a brickwall\nimage of a brickwall\nimage of a brickwall with less detail","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":481,"description":"<p>Get a region of pixels, or a single pixel, from the canvas.</p>\n<p>Returns an array of [R,G,B,A] values for any pixel or grabs a section of\nan image. If no parameters are specified, the entire image is returned.\nUse the x and y parameters to get the value of one pixel. Get a section of\nthe display window by specifying additional w and h parameters. When\ngetting an image, the x and y parameters define the coordinates for the\nupper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>Getting the color of a single pixel with get(x, y) is easy, but not as fast\nas grabbing the data directly from <a href=\"#/p5/pixels\">pixels[]</a>. The equivalent statement to\nget(x, y) using <a href=\"#/p5/pixels\">pixels[]</a> with pixel density d is</p>\n<pre><code class=\"language-javascript\">let x, y, d; // set these to the coordinates\nlet off = (y * width + x) * d * 4;\nlet components = [\n  pixels[off],\n  pixels[off + 1],\n  pixels[off + 2],\n  pixels[off + 3]\n];\nprint(components);</code></pre>\n<p>See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n<p>If you want to extract an array of colors or a subimage from an p5.Image object,\ntake a look at <a href=\"#/p5.Image/get\">p5.Image.get()</a></p>\n","itemtype":"method","name":"get","return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"},"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get();\n  image(c, width / 2, 0);\n}\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\nfunction setup() {\n  image(img, 0, 0);\n  let c = get(50, 90);\n  fill(c);\n  noStroke();\n  rect(25, 25, 50, 50);\n}\n</code>\n</div>"],"alt":"2 images of the rocky mountains, side-by-side\nImage of the rocky mountains with 50×50 green rect in center of canvas","class":"p5","module":"Image","submodule":"Pixels","overloads":[{"line":481,"params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"w","description":"<p>width</p>\n","type":"Number"},{"name":"h","description":"<p>height</p>\n","type":"Number"}],"return":{"description":"the rectangle <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":551,"params":[],"return":{"description":"the whole <a href=\"#/p5.Image\">p5.Image</a>","type":"p5.Image"}},{"line":555,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"}],"return":{"description":"color of pixel at x,y in array format [R, G, B, A]","type":"Number[]"}}]},{"file":"src/image/pixels.js","line":566,"description":"<p>Loads the pixel data for the display window into the <a href=\"#/p5/pixels\">pixels[]</a> array. This\nfunction must always be called before reading from or writing to <a href=\"#/p5/pixels\">pixels[]</a>.\nNote that only changes made with <a href=\"#/p5/set\">set()</a> or direct manipulation of <a href=\"#/p5/pixels\">pixels[]</a>\nwill occur.</p>\n","itemtype":"method","name":"loadPixels","example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":602,"description":"<p>Changes the color of any pixel, or writes an image directly to the\ndisplay window.\nThe x and y parameters specify the pixel to change and the c parameter\nspecifies the color value. This can be a <a href=\"#/p5.Color\">p5.Color</a> object, or [R, G, B, A]\npixel array. It can also be a single grayscale value.\nWhen setting an image, the x and y parameters define the coordinates for\nthe upper-left corner of the image, regardless of the current <a href=\"#/p5/imageMode\">imageMode()</a>.</p>\n<p>After using <a href=\"#/p5/set\">set()</a>, you must call <a href=\"#/p5/updatePixels\">updatePixels()</a> for your changes to appear.\nThis should be called once all pixels have been set, and must be called before\ncalling .<a href=\"#/p5/get\">get()</a> or drawing the image.</p>\n<p>Setting the color of a single pixel with set(x, y) is easy, but not as\nfast as putting the data directly into <a href=\"#/p5/pixels\">pixels[]</a>. Setting the <a href=\"#/p5/pixels\">pixels[]</a>\nvalues directly may be complicated when working with a retina display,\nbut will perform better when lots of pixels need to be set directly on\nevery loop. See the reference for <a href=\"#/p5/pixels\">pixels[]</a> for more information.</p>\n","itemtype":"method","name":"set","params":[{"name":"x","description":"<p>x-coordinate of the pixel</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of the pixel</p>\n","type":"Number"},{"name":"c","description":"<p>insert a grayscale value | a pixel array |\n                               a <a href=\"#/p5.Color\">p5.Color</a> object | a <a href=\"#/p5.Image\">p5.Image</a> to copy</p>\n","type":"Number|Number[]|Object"}],"example":["\n<div>\n<code>\nlet black = color(0);\nset(30, 20, black);\nset(85, 20, black);\nset(85, 75, black);\nset(30, 75, black);\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nfor (let i = 30; i < width - 15; i++) {\n  for (let j = 20; j < height - 25; j++) {\n    let c = color(204 - j, 153 - i, 0);\n    set(i, j, c);\n  }\n}\nupdatePixels();\n</code>\n</div>\n\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  set(0, 0, img);\n  updatePixels();\n  line(0, 0, width, height);\n  line(0, height, width, 0);\n}\n</code>\n</div>"],"alt":"4 black points in the shape of a square middle-right of canvas.\nsquare with orangey-brown gradient lightening at bottom right.\nimage of the rocky mountains. with lines like an 'x' through the center.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/image/pixels.js","line":674,"description":"<p>Updates the display window with the data in the <a href=\"#/p5/pixels\">pixels[]</a> array.\nUse in conjunction with <a href=\"#/p5/loadPixels\">loadPixels()</a>. If you're only reading pixels from\nthe array, there's no need to call <a href=\"#/p5/updatePixels\">updatePixels()</a> — updating is only\nnecessary to apply changes. <a href=\"#/p5/updatePixels\">updatePixels()</a> should be called anytime the\npixels array is manipulated or <a href=\"#/p5/set\">set()</a> is called, and only changes made with\n<a href=\"#/p5/set\">set()</a> or direct changes to <a href=\"#/p5/pixels\">pixels[]</a> will occur.</p>\n","itemtype":"method","name":"updatePixels","params":[{"name":"x","description":"<p>x-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y-coordinate of the upper-left corner of region\n                        to update</p>\n","type":"Number","optional":true},{"name":"w","description":"<p>width of region to update</p>\n","type":"Number","optional":true},{"name":"h","description":"<p>height of region to update</p>\n","type":"Number","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies.jpg');\n}\n\nfunction setup() {\n  image(img, 0, 0, width, height);\n  let d = pixelDensity();\n  let halfImage = 4 * (width * d) * (height * d / 2);\n  loadPixels();\n  for (let i = 0; i < halfImage; i++) {\n    pixels[i + halfImage] = pixels[i];\n  }\n  updatePixels();\n}\n</code>\n</div>"],"alt":"two images of the rocky mountains. one on top, one on bottom of canvas.","class":"p5","module":"Image","submodule":"Pixels"},{"file":"src/io/files.js","line":20,"description":"<p>Loads a JSON file from a file or a URL, and returns an Object.\nNote that even if the JSON file contains an Array, an Object will be\nreturned with index numbers as keys.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. JSONP is supported via a polyfill and you\ncan pass in as the second argument an object with definitions of the json\ncallback following the syntax specified <a href=\"https://github.com/camsong/\nfetch-jsonp\">here</a>.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadJSON","return":{"description":"JSON data","type":"Object|Array"},"example":["\n\nCalling <a href=\"#/p5/loadJSON\">loadJSON()</a> inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  earthquakes = loadJSON(url);\n}\n\nfunction setup() {\n  noLoop();\n}\n\nfunction draw() {\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n<div><code>\nfunction setup() {\n  noLoop();\n  let url =\n   'https://earthquake.usgs.gov/earthquakes/feed/v1.0/' +\n    'summary/all_day.geojson';\n  loadJSON(url, drawEarthquake);\n}\n\nfunction draw() {\n  background(200);\n}\n\nfunction drawEarthquake(earthquakes) {\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n}\n</code></div>"],"alt":"50×50 ellipse that changes from black to white depending on the current humidity\n50×50 ellipse that changes from black to white depending on the current humidity","class":"p5","module":"IO","submodule":"Input","overloads":[{"line":20,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"jsonpOptions","description":"<p>options object for jsonp related settings</p>\n","type":"Object","optional":true},{"name":"datatype","description":"<p>\"json\" or \"jsonp\"</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadJSON\">loadJSON()</a> completes, data is passed\n                                   in as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"JSON data","type":"Object|Array"}},{"line":104,"params":[{"name":"path","description":"","type":"String"},{"name":"datatype","description":"","type":"String"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}},{"line":112,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Object|Array"}}]},{"file":"src/io/files.js","line":183,"description":"<p>Reads the contents of a file and creates a String array of its individual\nlines. If the name of the file is used as the parameter, as in the above\nexample, the file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadStrings","params":[{"name":"filename","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadStrings\">loadStrings()</a>\n                              completes, Array is passed in as first\n                              argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n\nCalling loadStrings() inside <a href=\"#/p5/preload\">preload()</a> guarantees to complete the\noperation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet result;\nfunction preload() {\n  result = loadStrings('assets/test.txt');\n}\n\nfunction setup() {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>\n\nOutside of preload(), you may supply a callback function to handle the\nobject:\n\n<div><code>\nfunction setup() {\n  loadStrings('assets/test.txt', pickString);\n}\n\nfunction pickString(result) {\n  background(200);\n  text(random(result), 10, 10, 80, 80);\n}\n</code></div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":303,"description":"<p>Reads the contents of a file or URL and creates a <a href=\"#/p5.Table\">p5.Table</a> object with\nits values. If a file is specified, it must be located in the sketch's\n\"data\" folder. The filename parameter can also be a URL to a file found\nonline. By default, the file is assumed to be comma-separated (in CSV\nformat). Table only looks for a header row if the 'header' option is\nincluded.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadTable\">loadTable()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject:</p>\n<p>All files loaded and saved use UTF-8 encoding. This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadTable","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"extension","description":"<p>parse the table by comma-separated values \"csv\", semicolon-separated\n                                     values \"ssv\", or tab-separated values \"tsv\"</p>\n","type":"String","optional":true},{"name":"header","description":"<p>\"header\" to indicate table has header row</p>\n","type":"String","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                     <a href=\"#/p5/loadTable\">loadTable()</a> completes. On success, the\n                                     <a href=\"#/p5.Table\">Table</a> object is passed in as the\n                                     first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                     there is an error, response is passed\n                                     in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Table\">Table</a> object containing data","type":"Object"},"example":["\n<div class='norender'>\n<code>\n// Given the following CSV file called \"mammals.csv\"\n// located in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n  //the file can be remote\n  //table = loadTable(\"http://p5js.org/reference/assets/mammals.csv\",\n  //                  \"csv\", \"header\");\n}\n\nfunction setup() {\n  //count the columns\n  print(table.getRowCount() + ' total rows in table');\n  print(table.getColumnCount() + ' total columns in table');\n\n  print(table.getColumn('name'));\n  //[\"Goat\", \"Leopard\", \"Zebra\"]\n\n  //cycle through the table\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++) {\n      print(table.getString(r, c));\n    }\n}\n</code>\n</div>"],"alt":"randomly generated text from a file, for example \"i smell like butter\"\nrandomly generated text from a file, for example \"i have three feet\"","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":583,"description":"<p>Reads the contents of a file and creates an XML object with its values.\nIf the name of the file is used as the parameter, as in the above example,\nthe file must be located in the sketch directory/folder.</p>\n<p>Alternatively, the file maybe be loaded from anywhere on the local\ncomputer using an absolute path (something that starts with / on Unix and\nLinux, or a drive letter on Windows), or the filename parameter can be a\nURL for a file found on a network.</p>\n<p>This method is asynchronous, meaning it may not finish before the next\nline in your sketch is executed. Calling <a href=\"#/p5/loadXML\">loadXML()</a> inside <a href=\"#/p5/preload\">preload()</a>\nguarantees to complete the operation before <a href=\"#/p5/setup\">setup()</a> and <a href=\"#/p5/draw\">draw()</a> are called.</p>\n<p>Outside of <a href=\"#/p5/preload\">preload()</a>, you may supply a callback function to handle the\nobject.</p>\n<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadXML","params":[{"name":"filename","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadXML\">loadXML()</a>\n                              completes, XML object is passed in as\n                              first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                              there is an error, response is passed\n                              in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"XML object containing data","type":"Object"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n\n  for (let i = 0; i < children.length; i++) {\n    let id = children[i].getNum('id');\n    let coloring = children[i].getString('species');\n    let name = children[i].getContent();\n    print(id + ', ' + coloring + ', ' + name);\n  }\n}\n\n// Sketch prints:\n// 0, Capra hircus, Goat\n// 1, Panthera pardus, Leopard\n// 2, Equus zebra, Zebra\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":693,"description":"<p>This method is suitable for fetching files up to size of 64MB.</p>\n","itemtype":"method","name":"loadBytes","params":[{"name":"file","description":"<p>name of the file or URL to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after <a href=\"#/p5/loadBytes\">loadBytes()</a>\n                                   completes</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if there\n                                   is an error</p>\n","type":"Function","optional":true}],"return":{"description":"an object whose 'bytes' property will be the loaded buffer","type":"Object"},"example":["\n<div class='norender'><code>\nlet data;\n\nfunction preload() {\n  data = loadBytes('assets/mammals.xml');\n}\n\nfunction setup() {\n  for (let i = 0; i < 5; i++) {\n    console.log(data.bytes[i].toString(16));\n  }\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Input"},{"file":"src/io/files.js","line":752,"description":"<p>Method for executing an HTTP GET request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'GET')</code>. The 'binary' datatype will return\na Blob object, and the 'arrayBuffer' datatype will return an ArrayBuffer\nwhich can be used to initialize typed arrays (such as Uint8Array).</p>\n","itemtype":"method","name":"httpGet","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div class='norender'><code>\n// Examples use USGS Earthquake API:\n//   https://earthquake.usgs.gov/fdsnws/event/1/#methods\nlet earthquakes;\nfunction preload() {\n  // Get the most recent earthquake in the database\n  let url =\n   'https://earthquake.usgs.gov/fdsnws/event/1/query?' +\n    'format=geojson&limit=1&orderby=time';\n  httpGet(url, 'jsonp', false, function(response) {\n    // when the HTTP request completes, populate the variable that holds the\n    // earthquake data used in the visualization.\n    earthquakes = response;\n  });\n}\n\nfunction draw() {\n  if (!earthquakes) {\n    // Wait until the earthquake data has loaded before drawing.\n    return;\n  }\n  background(200);\n  // Get the magnitude and name of the earthquake out of the loaded JSON\n  let earthquakeMag = earthquakes.features[0].properties.mag;\n  let earthquakeName = earthquakes.features[0].properties.place;\n  ellipse(width / 2, height / 2, earthquakeMag * 10, earthquakeMag * 10);\n  textAlign(CENTER);\n  text(earthquakeName, 0, height - 30, width, 30);\n  noLoop();\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":752,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"binary\", \"arrayBuffer\",\n                                   \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":806,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":814,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":829,"description":"<p>Method for executing an HTTP POST request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text. This is equivalent to\ncalling <code>httpDo(path, 'POST')</code>.</p>\n","itemtype":"method","name":"httpPost","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use jsonplaceholder.typicode.com for a Mock Data API\n\nlet url = 'https://jsonplaceholder.typicode.com/posts';\nlet postData = { userId: 1, title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(url, 'json', postData, function(result) {\n    strokeWeight(2);\n    text(result.body, mouseX, mouseY);\n  });\n}\n</code>\n</div>\n\n<div><code>\nlet url = 'ttps://invalidURL'; // A bad URL that will cause errors\nlet postData = { title: 'p5 Clicked!', body: 'p5.js is very cool.' };\n\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n}\n\nfunction mousePressed() {\n  httpPost(\n    url,\n    'json',\n    postData,\n    function(result) {\n      // ... won't be called\n    },\n    function(error) {\n      strokeWeight(2);\n      text(error.toString(), mouseX, mouseY);\n    }\n  );\n}\n</code></div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":829,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\".\n                                   If omitted, <a href=\"#/p5/httpPost\">httpPost()</a> will guess.</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object|Boolean","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpPost\">httpPost()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":896,"params":[{"name":"path","description":"","type":"String"},{"name":"data","description":"","type":"Object|Boolean"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}},{"line":904,"params":[{"name":"path","description":"","type":"String"},{"name":"callback","description":"","type":"Function"},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":919,"description":"<p>Method for executing an HTTP request. If data type is not specified,\np5 will try to guess based on the URL, defaulting to text.<br><br>\nFor more advanced use, you may also pass in the path as the first argument\nand a object as the second argument, the signature follows the one specified\nin the Fetch API specification.\nThis method is suitable for fetching files up to size of 64MB when \"GET\" is used.</p>\n","itemtype":"method","name":"httpDo","return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"},"example":["\n<div>\n<code>\n// Examples use USGS Earthquake API:\n// https://earthquake.usgs.gov/fdsnws/event/1/#methods\n\n// displays an animation of all USGS earthquakes\nlet earthquakes;\nlet eqFeatureIndex = 0;\n\nfunction preload() {\n  let url = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson';\n  httpDo(\n    url,\n    {\n      method: 'GET',\n      // Other Request options, like special headers for apis\n      headers: { authorization: 'Bearer secretKey' }\n    },\n    function(res) {\n      earthquakes = res;\n    }\n  );\n}\n\nfunction draw() {\n  // wait until the data is loaded\n  if (!earthquakes || !earthquakes.features[eqFeatureIndex]) {\n    return;\n  }\n  clear();\n\n  let feature = earthquakes.features[eqFeatureIndex];\n  let mag = feature.properties.mag;\n  let rad = mag / 11 * ((width + height) / 2);\n  fill(255, 0, 0, 100);\n  ellipse(width / 2 + random(-2, 2), height / 2 + random(-2, 2), rad, rad);\n\n  if (eqFeatureIndex >= earthquakes.features.length) {\n    eqFeatureIndex = 0;\n  } else {\n    eqFeatureIndex += 1;\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Input","overloads":[{"line":919,"params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"method","description":"<p>either \"GET\", \"POST\", or \"PUT\",\n                                   defaults to \"GET\"</p>\n","type":"String","optional":true},{"name":"datatype","description":"<p>\"json\", \"jsonp\", \"xml\", or \"text\"</p>\n","type":"String","optional":true},{"name":"data","description":"<p>param data passed sent with request</p>\n","type":"Object","optional":true},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/httpGet\">httpGet()</a> completes, data is passed in\n                                   as first argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to be executed if\n                                   there is an error, response is passed\n                                   in as first argument</p>\n","type":"Function","optional":true}],"return":{"description":"A promise that resolves with the data when the operation\n                  completes successfully or rejects with the error after\n                  one occurs.","type":"Promise"}},{"line":990,"params":[{"name":"path","description":"","type":"String"},{"name":"options","description":"<p>Request object options as documented in the\n                                   \"fetch\" API\n<a href=\"https://developer.mozilla.org/en/docs/Web/API/Fetch_API\">reference</a></p>\n","type":"Object"},{"name":"callback","description":"","type":"Function","optional":true},{"name":"errorCallback","description":"","type":"Function","optional":true}],"return":{"description":"","type":"Promise"}}]},{"file":"src/io/files.js","line":1155,"itemtype":"method","name":"createWriter","params":[{"name":"name","description":"<p>name of the file to be created</p>\n","type":"String"},{"name":"extension","description":"","type":"String","optional":true}],"return":{"description":"","type":"p5.PrintWriter"},"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  background(200);\n  text('click here to save', 10, 10, 70, 80);\n}\n\nfunction mousePressed() {\n  if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n    const writer = createWriter('squares.txt');\n    for (let i = 0; i < 10; i++) {\n      writer.print(i * i);\n    }\n    writer.close();\n    writer.clear();\n  }\n}\n</code>\n</div>"],"class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1210,"description":"<p>Writes data to the PrintWriter stream</p>\n","itemtype":"method","name":"write","params":[{"name":"data","description":"<p>all data to be written by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class=\"norender notest\">\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// write 'Hello world!'' to the file\nwriter.write(['Hello world!']);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write 'apples,bananas,123' to the file\nwriter.write(['apples', 'bananas', 123]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile3.txt'\nlet writer = createWriter('newFile3.txt');\n// write 'My name is: Teddy' to the file\nwriter.write('My name is:');\nwriter.write(' Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100);\n  button = createButton('SAVE FILE');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  // creates a file called 'newFile.txt'\n  let writer = createWriter('newFile.txt');\n  // write 'Hello world!'' to the file\n  writer.write(['Hello world!']);\n  // close the PrintWriter and save the file\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1269,"description":"<p>Writes data to the PrintWriter stream, and adds a new line at the end</p>\n","itemtype":"method","name":"print","params":[{"name":"data","description":"<p>all data to be printed by the PrintWriter</p>\n","type":"Array"}],"example":["\n<div class='norender notest'>\n<code>\n// creates a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// creates a file containing\n//  My name is:\n//  Teddy\nwriter.print('My name is:');\nwriter.print('Teddy');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\nlet writer;\n\nfunction setup() {\n  createCanvas(400, 400);\n  // create a PrintWriter\n  writer = createWriter('newFile.txt');\n}\n\nfunction draw() {\n  writer.print([mouseX, mouseY]);\n}\n\nfunction mouseClicked() {\n  writer.close();\n}\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1310,"description":"<p>Clears the data already written to the PrintWriter object</p>\n","itemtype":"method","name":"clear","example":["\n<div class =\"norender notest\"><code>\n// create writer object\nlet writer = createWriter('newFile.txt');\nwriter.write(['clear me']);\n// clear writer object here\nwriter.clear();\n// close writer\nwriter.close();\n</code></div>\n<div>\n<code>\nfunction setup() {\n  button = createButton('CLEAR ME');\n  button.position(21, 40);\n  button.mousePressed(createFile);\n}\n\nfunction createFile() {\n  let writer = createWriter('newFile.txt');\n  writer.write(['clear me']);\n  writer.clear();\n  writer.close();\n}\n</code>\n</div>\n"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1344,"description":"<p>Closes the PrintWriter</p>\n","itemtype":"method","name":"close","example":["\n<div class=\"norender notest\">\n<code>\n// create a file called 'newFile.txt'\nlet writer = createWriter('newFile.txt');\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>\n<div class='norender notest'>\n<code>\n// create a file called 'newFile2.txt'\nlet writer = createWriter('newFile2.txt');\n// write some data to the file\nwriter.write([100, 101, 102]);\n// close the PrintWriter and save the file\nwriter.close();\n</code>\n</div>"],"class":"p5.PrintWriter","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1393,"description":"<p>Saves a given element(image, text, json, csv, wav, or html) to the client's\ncomputer. The first parameter can be a pointer to element we want to save.\nThe element can be one of <a href=\"#/p5.Element\">p5.Element</a>,an Array of\nStrings, an Array of JSON, a JSON object, a <a href=\"#/p5.Table\">p5.Table\n</a>, a <a href=\"#/p5.Image\">p5.Image</a>, or a p5.SoundFile (requires\np5.sound). The second parameter is a filename (including extension).The\nthird parameter is for options specific to this type of object. This method\nwill save a file that fits the given parameters.\nIf it is called without specifying an element, by default it will save the\nwhole canvas as an image file. You can optionally specify a filename as\nthe first parameter in such a case.\n<strong>Note that it is not recommended to\ncall this method within draw, as it will open a new save dialog on every\nrender.</strong></p>\n","itemtype":"method","name":"save","params":[{"name":"objectOrFilename","description":"<p>If filename is provided, will\n                                           save canvas as an image with\n                                           either png or jpg extension\n                                           depending on the filename.\n                                           If object is provided, will\n                                           save depending on the object\n                                           and filename (see examples\n                                           above).</p>\n","type":"Object|String","optional":true},{"name":"filename","description":"<p>If an object is provided as the first\n                             parameter, then the second parameter\n                             indicates the filename,\n                             and should include an appropriate\n                             file extension (see examples above).</p>\n","type":"String","optional":true},{"name":"options","description":"<p>Additional options depend on\n                          filetype. For example, when saving JSON,\n                          <code>true</code> indicates that the\n                          output will be optimized for filesize,\n                          rather than readability.</p>\n","type":"Boolean|String","optional":true}],"example":["\n <div class=\"norender\"><code>\n // Saves the canvas as an image\n cnv = createCanvas(300, 300);\n save(cnv, 'myCanvas.jpg');\n\n // Saves the canvas as an image by default\n save('myCanvas.jpg');\n </code></div>\n\n<div class=\"norender\"><code>\n // Saves p5.Image as an image\n img = createImage(10, 10);\n save(img, 'myImage.png');\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves p5.Renderer object as an image\n obj = createGraphics(100, 100);\n save(obj, 'myObject.png');\n </code></div>\n\n <div class=\"norender\"><code>\n let myTable = new p5.Table();\n // Saves table as html file\n save(myTable, 'myTable.html');\n\n // Comma Separated Values\n save(myTable, 'myTable.csv');\n\n // Tab Separated Values\n save(myTable, 'myTable.tsv');\n </code></div>\n\n <div class=\"norender\"><code>\n let myJSON = { a: 1, b: true };\n\n // Saves pretty JSON\n save(myJSON, 'my.json');\n\n // Optimizes JSON filesize\n save(myJSON, 'my.json', true);\n </code></div>\n\n <div class=\"norender\"><code>\n // Saves array of strings to text file with line breaks after each item\n let arrayOfStrings = ['a', 'b'];\n save(arrayOfStrings, 'my.txt');\n </code></div>"],"alt":"An example for saving a canvas as an image.\n An example for saving a p5.Image element as an image.\n An example for saving a p5.Renderer element.\n An example showing how to save a table in formats of HTML, CSV and TSV.\n An example for saving JSON to a txt file with some extra arguments.\n An example for saving an array of strings to text file with line breaks.","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1535,"description":"<p>Writes the contents of an Array or a JSON object to a .json file.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveJSON","params":[{"name":"json","description":"","type":"Array|Object"},{"name":"filename","description":"","type":"String"},{"name":"optimize","description":"<p>If true, removes line breaks\n                               and spaces from the output\n                               file to optimize filesize\n                               (but not readability).</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let json = {}; // new  JSON Object\n\n json.id = 0;\n json.species = 'Panthera leo';\n json.name = 'Lion';\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveJSON(json, 'lion.json');\n }\n }\n\n // saves the following to a file called \"lion.json\":\n // {\n //   \"id\": 0,\n //   \"species\": \"Panthera leo\",\n //   \"name\": \"Lion\"\n // }\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1592,"description":"<p>Writes an array of Strings to a text file, one line per String.\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveStrings","params":[{"name":"list","description":"<p>string array to be written</p>\n","type":"String[]"},{"name":"filename","description":"<p>filename for output</p>\n","type":"String"},{"name":"extension","description":"<p>the filename's extension</p>\n","type":"String","optional":true},{"name":"isCRLF","description":"<p>if true, change line-break to CRLF</p>\n","type":"Boolean","optional":true}],"example":["\n <div><code>\n let words = 'apple bear cat dog';\n\n // .split() outputs an Array\n let list = split(words, ' ');\n\n function setup() {\n createCanvas(100, 100);\n background(200);\n text('click here to save', 10, 10, 70, 80);\n }\n\n function mousePressed() {\n if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {\n   saveStrings(list, 'nouns.txt');\n }\n }\n\n // Saves the following to a file called 'nouns.txt':\n //\n // apple\n // bear\n // cat\n // dog\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/files.js","line":1656,"description":"<p>Writes the contents of a <a href=\"#/p5.Table\">Table</a> object to a file. Defaults to a\ntext file with comma-separated-values ('csv') but can also\nuse tab separation ('tsv'), or generate an HTML table ('html').\nThe file saving process and location of the saved file will\nvary between web browsers.</p>\n","itemtype":"method","name":"saveTable","params":[{"name":"Table","description":"<p>the <a href=\"#/p5.Table\">Table</a> object to save to a file</p>\n","type":"p5.Table"},{"name":"filename","description":"<p>the filename to which the Table should be saved</p>\n","type":"String"},{"name":"options","description":"<p>can be one of \"tsv\", \"csv\", or \"html\"</p>\n","type":"String","optional":true}],"example":["\n<div><code>\n let table;\n\n function setup() {\n table = new p5.Table();\n\n table.addColumn('id');\n table.addColumn('species');\n table.addColumn('name');\n\n let newRow = table.addRow();\n newRow.setNum('id', table.getRowCount() - 1);\n newRow.setString('species', 'Panthera leo');\n newRow.setString('name', 'Lion');\n\n // To save, un-comment next line then click 'run'\n // saveTable(table, 'new.csv');\n }\n\n // Saves the following to a file called 'new.csv':\n // id,species,name\n // 0,Panthera leo,Lion\n </code></div>"],"alt":"no image displayed","class":"p5","module":"IO","submodule":"Output"},{"file":"src/io/p5.Table.js","line":9,"description":"<p>Table Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.</p>\n<p>Possible options include:</p>\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":43,"description":"<p>An array containing the names of the columns in the table, if the \"header\" the table is\nloaded with the \"header\" parameter.</p>\n","itemtype":"property","name":"columns","type":"String[]","example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //print the column names\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print('column ' + c + ' is named ' + table.columns[c]);\n  }\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":77,"description":"<p>An array containing the <a href=\"#/p5.Table\">p5.TableRow</a> objects that make up the\nrows of the table. The same result as calling <a href=\"#/p5/getRows\">getRows()</a></p>\n","itemtype":"property","name":"rows","type":"p5.TableRow[]","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":85,"description":"<p>Use <a href=\"#/p5/addRow\">addRow()</a> to add a new row of data to a <a href=\"#/p5.Table\">p5.Table</a> object. By default,\nan empty row is created. Typically, you would store a reference to\nthe new row in a TableRow object (see newRow in the example above),\nand then set individual values using <a href=\"#/p5/set\">set()</a>.</p>\n<p>If a <a href=\"#/p5.TableRow\">p5.TableRow</a> object is included as a parameter, then that row is\nduplicated and added to the table.</p>\n","itemtype":"method","name":"addRow","params":[{"name":"row","description":"<p>row to be added to the table</p>\n","type":"p5.TableRow","optional":true}],"return":{"description":"the row that was added","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add a row\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Canis Lupus');\n newRow.setString('name', 'Wolf');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":148,"description":"<p>Removes a row from the table object.</p>\n","itemtype":"method","name":"removeRow","params":[{"name":"id","description":"<p>ID number of the row to remove</p>\n","type":"Integer"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //remove the first row\n  table.removeRow(0);\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":195,"description":"<p>Returns a reference to the specified <a href=\"#/p5.TableRow\">p5.TableRow</a>. The reference\ncan then be used to get and set values of the selected row.</p>\n","itemtype":"method","name":"getRow","params":[{"name":"rowID","description":"<p>ID number of the row to get</p>\n","type":"Integer"}],"return":{"description":"<a href=\"#/p5.TableRow\">p5.TableRow</a> object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let row = table.getRow(1);\n  //print it column by column\n  //note: a row is an object, not an array\n  for (let c = 0; c < table.getColumnCount(); c++) {\n    print(row.getString(c));\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":240,"description":"<p>Gets all rows from the table. Returns an array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s.</p>\n","itemtype":"method","name":"getRows","return":{"description":"Array of <a href=\"#/p5.TableRow\">p5.TableRow</a>s","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n\n //warning: rows is an array of objects\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":288,"description":"<p>Finds the first row in the Table that contains the value\nprovided, and returns a reference to that row. Even if\nmultiple rows are possible matches, only the first matching\nrow is returned. The column to search may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"findRow","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"","type":"p5.TableRow"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //find the animal named zebra\n let row = table.findRow('Zebra', 'name');\n //find the corresponding species\n print(row.getString('species'));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":352,"description":"<p>Finds the rows in the Table that contain the value\nprovided, and returns references to those rows. Returns an\nArray, so for must be used to iterate through all the rows,\nas shown in the example above. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"findRows","params":[{"name":"value","description":"<p>The value to match</p>\n","type":"String"},{"name":"column","description":"<p>ID number or title of the\n                               column to search</p>\n","type":"Integer|String"}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //add another goat\n let newRow = table.addRow();\n newRow.setString('id', table.getRowCount() - 1);\n newRow.setString('species', 'Scape Goat');\n newRow.setString('name', 'Goat');\n\n //find the rows containing animals named Goat\n let rows = table.findRows('Goat', 'name');\n print(rows.length + ' Goats found');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":420,"description":"<p>Finds the first row in the Table that matches the regular\nexpression provided, and returns a reference to that row.\nEven if multiple rows are possible matches, only the first\nmatching row is returned. The column to search may be\nspecified by either its ID or title.</p>\n","itemtype":"method","name":"matchRow","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String|RegExp"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer"}],"return":{"description":"TableRow object","type":"p5.TableRow"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //Search using specified regex on a given column, return TableRow object\n  let mammal = table.matchRow(new RegExp('ant'), 1);\n  print(mammal.getString(1));\n  //Output \"Panthera pardus\"\n}\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":478,"description":"<p>Finds the rows in the Table that match the regular expression provided,\nand returns references to those rows. Returns an array, so for must be\nused to iterate through all the rows, as shown in the example. The\ncolumn to search may be specified by either its ID or title.</p>\n","itemtype":"method","name":"matchRows","params":[{"name":"regexp","description":"<p>The regular expression to match</p>\n","type":"String"},{"name":"column","description":"<p>The column ID (number) or\n                                 title (string)</p>\n","type":"String|Integer","optional":true}],"return":{"description":"An Array of TableRow objects","type":"p5.TableRow[]"},"example":["\n<div class=\"norender\">\n<code>\nlet table;\n\nfunction setup() {\n  table = new p5.Table();\n\n  table.addColumn('name');\n  table.addColumn('type');\n\n  let newRow = table.addRow();\n  newRow.setString('name', 'Lion');\n  newRow.setString('type', 'Mammal');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Snake');\n  newRow.setString('type', 'Reptile');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Mosquito');\n  newRow.setString('type', 'Insect');\n\n  newRow = table.addRow();\n  newRow.setString('name', 'Lizard');\n  newRow.setString('type', 'Reptile');\n\n  let rows = table.matchRows('R.*', 'type');\n  for (let i = 0; i < rows.length; i++) {\n    print(rows[i].getString('name') + ': ' + rows[i].getString('type'));\n  }\n}\n// Sketch prints:\n// Snake: Reptile\n// Lizard: Reptile\n</code>\n</div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":545,"description":"<p>Retrieves all values in the specified column, and returns them\nas an array. The column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"getColumn","params":[{"name":"column","description":"<p>String or Number of the column to return</p>\n","type":"String|Number"}],"return":{"description":"Array of column values","type":"Array"},"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n //getColumn returns an array that can be printed directly\n print(table.getColumn('species'));\n //outputs [\"Capra hircus\", \"Panthera pardus\", \"Equus zebra\"]\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":597,"description":"<p>Removes all rows from a Table. While all rows are removed,\ncolumns and column titles are maintained.</p>\n","itemtype":"method","name":"clearRows","example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.clearRows();\n print(table.getRowCount() + ' total rows in table');\n print(table.getColumnCount() + ' total columns in table');\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":638,"description":"<p>Use <a href=\"#/p5/addColumn\">addColumn()</a> to add a new column to a <a href=\"#/p5.Table\">Table</a> object.\nTypically, you will want to specify a title, so the column\nmay be easily referenced later by name. (If no title is\nspecified, the new column's title will be null.)</p>\n","itemtype":"method","name":"addColumn","params":[{"name":"title","description":"<p>title of the given column</p>\n","type":"String","optional":true}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.addColumn('carnivore');\n table.set(0, 'carnivore', 'no');\n table.set(1, 'carnivore', 'yes');\n table.set(2, 'carnivore', 'no');\n\n //print the results\n for (let r = 0; r < table.getRowCount(); r++)\n   for (let c = 0; c < table.getColumnCount(); c++)\n     print(table.getString(r, c));\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":688,"description":"<p>Returns the total number of columns in a Table.</p>\n","itemtype":"method","name":"getColumnCount","return":{"description":"Number of columns in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n let numOfColumn = table.getColumnCount();\n text('There are ' + numOfColumn + ' columns in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":724,"description":"<p>Returns the total number of rows in a Table.</p>\n","itemtype":"method","name":"getRowCount","return":{"description":"Number of rows in this table","type":"Integer"},"example":["\n <div>\n <code>\n // given the cvs file \"blobs.csv\" in /assets directory\n //\n // ID, Name, Flavor, Shape, Color\n // Blob1, Blobby, Sweet, Blob, Pink\n // Blob2, Saddy, Savory, Blob, Blue\n\n let table;\n\n function preload() {\n table = loadTable('assets/blobs.csv');\n }\n\n function setup() {\n createCanvas(200, 100);\n textAlign(CENTER);\n background(255);\n }\n\n function draw() {\n text('There are ' + table.getRowCount() + ' rows in the table.', 100, 50);\n }\n </code>\n </div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":760,"description":"<p>Removes any of the specified characters (or \"tokens\").</p>\n<p>If no column is specified, then the values in all columns and\nrows are processed. A specific column may be referenced by\neither its ID or title.</p>\n","itemtype":"method","name":"removeTokens","params":[{"name":"chars","description":"<p>String listing characters to be removed</p>\n","type":"String"},{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   $Lion  ,');\n newRow.setString('type', ',,,Mammal');\n\n newRow = table.addRow();\n newRow.setString('name', '$Snake  ');\n newRow.setString('type', ',,,Reptile');\n\n table.removeTokens(',$ ');\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":832,"description":"<p>Trims leading and trailing whitespace, such as spaces and tabs,\nfrom String table values. If no column is specified, then the\nvalues in all columns and rows are trimmed. A specific column\nmay be referenced by either its ID or title.</p>\n","itemtype":"method","name":"trim","params":[{"name":"column","description":"<p>Column ID (number)\n                                 or name (string)</p>\n","type":"String|Integer","optional":true}],"example":["\n <div class=\"norender\"><code>\n function setup() {\n let table = new p5.Table();\n\n table.addColumn('name');\n table.addColumn('type');\n\n let newRow = table.addRow();\n newRow.setString('name', '   Lion  ,');\n newRow.setString('type', ' Mammal  ');\n\n newRow = table.addRow();\n newRow.setString('name', '  Snake  ');\n newRow.setString('type', '  Reptile  ');\n\n table.trim();\n print(table.getArray());\n }\n\n // prints:\n //  0  \"Lion\"   \"Mamal\"\n //  1  \"Snake\"  \"Reptile\"\n </code></div>"],"class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":896,"description":"<p>Use <a href=\"#/p5/removeColumn\">removeColumn()</a> to remove an existing column from a Table\nobject. The column to be removed may be identified by either\nits title (a String) or its index value (an int).\nremoveColumn(0) would remove the first column, removeColumn(1)\nwould remove the second column, and so on.</p>\n","itemtype":"method","name":"removeColumn","params":[{"name":"column","description":"<p>columnName (string) or ID (number)</p>\n","type":"String|Integer"}],"example":["\n <div class=\"norender\">\n <code>\n // Given the CSV file \"mammals.csv\"\n // in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n table.removeColumn('id');\n print(table.getColumnCount());\n }\n </code>\n </div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":960,"description":"<p>Stores a value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String|Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.set(0, 'species', 'Canis Lupus');\n  table.set(0, 'name', 'Wolf');\n\n  //print the results\n  for (let r = 0; r < table.getRowCount(); r++)\n    for (let c = 0; c < table.getColumnCount(); c++)\n      print(table.getString(r, c));\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1009,"description":"<p>Stores a Float value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"Number"}],"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  table.setNum(1, 'id', 1);\n\n  print(table.getColumn(0));\n  //[\"0\", 1, \"2\"]\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1055,"description":"<p>Stores a String value in the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified\nby either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>column ID (Number)\n                              or title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>value to assign</p>\n","type":"String"}],"example":["\n<div class=\"norender\"><code>\n// Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  //add a row\n  let newRow = table.addRow();\n  newRow.setString('id', table.getRowCount() - 1);\n  newRow.setString('species', 'Canis Lupus');\n  newRow.setString('name', 'Wolf');\n\n  print(table.getArray());\n}\n</code></div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1100,"description":"<p>Retrieves a value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.get(0, 1));\n  //Capra hircus\n  print(table.get(0, 'species'));\n  //Capra hircus\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1146,"description":"<p>Retrieves a Float value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getNum(1, 0) + 100);\n  //id 1 + 100 = 101\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1190,"description":"<p>Retrieves a String value from the Table's specified row and column.\nThe row is specified by its ID, while the column may be specified by\neither its ID or title.</p>\n","itemtype":"method","name":"getString","params":[{"name":"row","description":"<p>row ID</p>\n","type":"Integer"},{"name":"column","description":"<p>columnName (string) or\n                                  ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  print(table.getString(0, 0)); // 0\n  print(table.getString(0, 1)); // Capra hircus\n  print(table.getString(0, 2)); // Goat\n  print(table.getString(1, 0)); // 1\n  print(table.getString(1, 1)); // Panthera pardus\n  print(table.getString(1, 2)); // Leopard\n  print(table.getString(2, 0)); // 2\n  print(table.getString(2, 1)); // Equus zebra\n  print(table.getString(2, 2)); // Zebra\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1242,"description":"<p>Retrieves all table data and returns as an object. If a column name is\npassed in, each row object will be stored with that attribute as its\ntitle.</p>\n","itemtype":"method","name":"getObject","params":[{"name":"headerColumn","description":"<p>Name of the column which should be used to\n                             title each row object (optional)</p>\n","type":"String","optional":true}],"return":{"description":"","type":"Object"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder:\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leopard\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  //my table is comma separated value \"csv\"\n  //and has a header specifying the columns labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableObject = table.getObject();\n\n  print(tableObject);\n  //outputs an object\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.Table.js","line":1305,"description":"<p>Retrieves all table data and returns it as a multidimensional array.</p>\n","itemtype":"method","name":"getArray","return":{"description":"","type":"Array"},"example":["\n<div class=\"norender\">\n<code>\n// Given the CSV file \"mammals.csv\"\n// in the project's \"assets\" folder\n//\n// id,species,name\n// 0,Capra hircus,Goat\n// 1,Panthera pardus,Leoperd\n// 2,Equus zebra,Zebra\n\nlet table;\n\nfunction preload() {\n  // table is comma separated value \"CSV\"\n  // and has specifiying header for column labels\n  table = loadTable('assets/mammals.csv', 'csv', 'header');\n}\n\nfunction setup() {\n  let tableArray = table.getArray();\n  for (let i = 0; i < tableArray.length; i++) {\n    print(tableArray[i]);\n  }\n}\n</code>\n</div>"],"alt":"no image displayed","class":"p5.Table","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":40,"description":"<p>Stores a value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"set","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored</p>\n","type":"String|Number"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].set('name', 'Unicorn');\n }\n\n //print the results\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":102,"description":"<p>Stores a Float value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setNum","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a Float</p>\n","type":"Number|String"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   rows[r].setNum('id', r + 10);\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":146,"description":"<p>Stores a String value in the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"setString","params":[{"name":"column","description":"<p>Column ID (Number)\n                              or Title (String)</p>\n","type":"String|Integer"},{"name":"value","description":"<p>The value to be stored\n                              as a String</p>\n","type":"String|Number|Boolean|Object"}],"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   let name = rows[r].getString('name');\n   rows[r].setString('name', 'A ' + name + ' named George');\n }\n\n print(table.getArray());\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":191,"description":"<p>Retrieves a value from the TableRow's specified column.\nThe column may be specified by either its ID or title.</p>\n","itemtype":"method","name":"get","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"","type":"String|Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let names = [];\n let rows = table.getRows();\n for (let r = 0; r < rows.length; r++) {\n   names.push(rows[r].get('name'));\n }\n\n print(names);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":239,"description":"<p>Retrieves a Float value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"Float Floating point number","type":"Number"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let minId = Infinity;\n let maxId = -Infinity;\n for (let r = 0; r < rows.length; r++) {\n   let id = rows[r].getNum('id');\n   minId = min(minId, id);\n   maxId = min(maxId, id);\n }\n print('minimum id = ' + minId + ', maximum id = ' + maxId);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.TableRow.js","line":295,"description":"<p>Retrieves an String value from the TableRow's specified\ncolumn. The column may be specified by either its ID or\ntitle.</p>\n","itemtype":"method","name":"getString","params":[{"name":"column","description":"<p>columnName (string) or\n                                 ID (number)</p>\n","type":"String|Integer"}],"return":{"description":"String","type":"String"},"example":["\n <div class=\"norender\"><code>\n // Given the CSV file \"mammals.csv\" in the project's \"assets\" folder:\n //\n // id,species,name\n // 0,Capra hircus,Goat\n // 1,Panthera pardus,Leopard\n // 2,Equus zebra,Zebra\n\n let table;\n\n function preload() {\n //my table is comma separated value \"csv\"\n //and has a header specifying the columns labels\n table = loadTable('assets/mammals.csv', 'csv', 'header');\n }\n\n function setup() {\n let rows = table.getRows();\n let longest = '';\n for (let r = 0; r < rows.length; r++) {\n   let species = rows[r].getString('species');\n   if (longest.length < species.length) {\n     longest = species;\n   }\n }\n\n print('longest: ' + longest);\n }\n </code></div>"],"alt":"no image displayed","class":"p5.TableRow","module":"IO","submodule":"Table"},{"file":"src/io/p5.XML.js","line":62,"description":"<p>Gets a copy of the element's parent. Returns the parent as another\n<a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"getParent","return":{"description":"element parent","type":"p5.XML"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let children = xml.getChildren('animal');\n  let parent = children[1].getParent();\n  print(parent.getName());\n}\n\n// Sketch prints:\n// mammals\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":100,"description":"<p>Gets the element's full name, which is returned as a String.</p>\n","itemtype":"method","name":"getName","return":{"description":"the name of the node","type":"String"},"example":["&lt;animal\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n print(xml.getName());\n }\n\n // Sketch prints:\n // mammals\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":135,"description":"<p>Sets the element's name, which is specified as a String.</p>\n","itemtype":"method","name":"setName","params":[{"name":"the","description":"<p>new name of the node</p>\n","type":"String"}],"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.getName());\n  xml.setName('fish');\n  print(xml.getName());\n}\n\n// Sketch prints:\n// mammals\n// fish\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":181,"description":"<p>Checks whether or not the element has any children, and returns the result\nas a boolean.</p>\n","itemtype":"method","name":"hasChildren","return":{"description":"","type":"Boolean"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.hasChildren());\n}\n\n// Sketch prints:\n// true\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":217,"description":"<p>Get the names of all of the element's children, and returns the names as an\narray of Strings. This is the same as looping through and calling <a href=\"#/p5.XML/getName\">getName()</a>\non each child element individually.</p>\n","itemtype":"method","name":"listChildren","return":{"description":"names of the children of the element","type":"String[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.listChildren());\n}\n\n// Sketch prints:\n// [\"animal\", \"animal\", \"animal\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":258,"description":"<p>Returns all of the element's children as an array of <a href=\"#/p5.XML\">p5.XML</a> objects. When\nthe name parameter is specified, then it will return all children that match\nthat name.</p>\n","itemtype":"method","name":"getChildren","params":[{"name":"name","description":"<p>element name</p>\n","type":"String","optional":true}],"return":{"description":"children of the element","type":"p5.XML[]"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let animals = xml.getChildren('animal');\n\n  for (let i = 0; i < animals.length; i++) {\n    print(animals[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":314,"description":"<p>Returns the first of the element's children that matches the name parameter\nor the child of the given index.It returns undefined if no matching\nchild is found.</p>\n","itemtype":"method","name":"getChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"return":{"description":"","type":"p5.XML"},"example":["&lt;animal\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let secondChild = xml.getChild(1);\n  print(secondChild.getContent());\n}\n\n// Sketch prints:\n// \"Leopard\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":374,"description":"<p>Appends a new child to the element. The child can be specified with\neither a String, which will be used as the new tag's name, or as a\nreference to an existing <a href=\"#/p5.XML\">p5.XML</a> object.\nA reference to the newly created child is returned as an <a href=\"#/p5.XML\">p5.XML</a> object.</p>\n","itemtype":"method","name":"addChild","params":[{"name":"node","description":"<p>a <a href=\"#/p5.XML\">p5.XML</a> Object which will be the child to be added</p>\n","type":"p5.XML"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let child = new p5.XML();\n  child.setName('animal');\n  child.setAttribute('id', '3');\n  child.setAttribute('species', 'Ornithorhynchus anatinus');\n  child.setContent('Platypus');\n  xml.addChild(child);\n\n  let animals = xml.getChildren('animal');\n  print(animals[animals.length - 1].getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Leopard\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":426,"description":"<p>Removes the element specified by name or index.</p>\n","itemtype":"method","name":"removeChild","params":[{"name":"name","description":"<p>element name or index</p>\n","type":"String|Integer"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild('animal');\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Leopard\"\n// \"Zebra\"\n</code></div>\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  xml.removeChild(1);\n  let children = xml.getChildren();\n  for (let i = 0; i < children.length; i++) {\n    print(children[i].getContent());\n  }\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":498,"description":"<p>Counts the specified element's number of attributes, returned as an Number.</p>\n","itemtype":"method","name":"getAttributeCount","return":{"description":"","type":"Integer"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getAttributeCount());\n}\n\n// Sketch prints:\n// 2\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":534,"description":"<p>Gets all of the specified element's attributes, and returns them as an\narray of Strings.</p>\n","itemtype":"method","name":"listAttributes","return":{"description":"an array of strings containing the names of attributes","type":"String[]"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.listAttributes());\n}\n\n// Sketch prints:\n// [\"id\", \"species\"]\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":577,"description":"<p>Checks whether or not an element has the specified attribute.</p>\n","itemtype":"method","name":"hasAttribute","params":[{"name":"the","description":"<p>attribute to be checked</p>\n","type":"String"}],"return":{"description":"true if attribute found else false","type":"Boolean"},"example":["\n <div class='norender'><code>\n // The following short XML file called \"mammals.xml\" is parsed\n // in the code below.\n //\n // <?xml version=\"1.0\"?>\n // &lt;mammals&gt;\n //   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n //   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n //   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n // &lt;/mammals&gt;\n\n let xml;\n\n function preload() {\n xml = loadXML('assets/mammals.xml');\n }\n\n function setup() {\n let firstChild = xml.getChild('animal');\n print(firstChild.hasAttribute('species'));\n print(firstChild.hasAttribute('color'));\n }\n\n // Sketch prints:\n // true\n // false\n </code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":622,"description":"<p>Returns an attribute value of the element as an Number. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, the value 0 is returned.</p>\n","itemtype":"method","name":"getNum","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"Number"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getNum('id'));\n}\n\n// Sketch prints:\n// 0\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":669,"description":"<p>Returns an attribute value of the element as an String. If the defaultValue\nparameter is specified and the attribute doesn't exist, then defaultValue\nis returned. If no defaultValue is specified and the attribute doesn't\nexist, null is returned.</p>\n","itemtype":"method","name":"getString","params":[{"name":"name","description":"<p>the non-null full name of the attribute</p>\n","type":"String"},{"name":"defaultValue","description":"<p>the default value of the attribute</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":716,"description":"<p>Sets the content of an element's attribute. The first parameter specifies\nthe attribute name, while the second specifies the new content.</p>\n","itemtype":"method","name":"setAttribute","params":[{"name":"name","description":"<p>the full name of the attribute</p>\n","type":"String"},{"name":"value","description":"<p>the value of the attribute</p>\n","type":"Number|String|Boolean"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getString('species'));\n  firstChild.setAttribute('species', 'Jamides zebra');\n  print(firstChild.getString('species'));\n}\n\n// Sketch prints:\n// \"Capra hircus\"\n// \"Jamides zebra\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":757,"description":"<p>Returns the content of an element. If there is no such content,\ndefaultValue is returned if specified, otherwise null is returned.</p>\n","itemtype":"method","name":"getContent","params":[{"name":"defaultValue","description":"<p>value returned if no content is found</p>\n","type":"String","optional":true}],"return":{"description":"","type":"String"},"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":798,"description":"<p>Sets the element's content.</p>\n","itemtype":"method","name":"setContent","params":[{"name":"text","description":"<p>the new content</p>\n","type":"String"}],"example":["\n<div class='norender'><code>\n// The following short XML file called \"mammals.xml\" is parsed\n// in the code below.\n//\n// <?xml version=\"1.0\"?>\n// &lt;mammals&gt;\n//   &lt;animal id=\"0\" species=\"Capra hircus\">Goat&lt;/animal&gt;\n//   &lt;animal id=\"1\" species=\"Panthera pardus\">Leopard&lt;/animal&gt;\n//   &lt;animal id=\"2\" species=\"Equus zebra\">Zebra&lt;/animal&gt;\n// &lt;/mammals&gt;\n\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  let firstChild = xml.getChild('animal');\n  print(firstChild.getContent());\n  firstChild.setContent('Mountain Goat');\n  print(firstChild.getContent());\n}\n\n// Sketch prints:\n// \"Goat\"\n// \"Mountain Goat\"\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/io/p5.XML.js","line":839,"description":"<p>Serializes the element into a string. This function is useful for preparing\nthe content to be sent over a http request or saved to file.</p>\n","itemtype":"method","name":"serialize","return":{"description":"Serialized string of the element","type":"String"},"example":["\n<div class='norender'><code>\nlet xml;\n\nfunction preload() {\n  xml = loadXML('assets/mammals.xml');\n}\n\nfunction setup() {\n  print(xml.serialize());\n}\n\n// Sketch prints:\n// <mammals>\n//   <animal id=\"0\" species=\"Capra hircus\">Goat</animal>\n//   <animal id=\"1\" species=\"Panthera pardus\">Leopard</animal>\n//   <animal id=\"2\" species=\"Equus zebra\">Zebra</animal>\n// </mammals>\n</code></div>"],"class":"p5.XML","module":"IO","submodule":"Input"},{"file":"src/math/calculation.js","line":10,"description":"<p>Calculates the absolute value (magnitude) of a number. Maps to Math.abs().\nThe absolute value of a number is always positive.</p>\n","itemtype":"method","name":"abs","params":[{"name":"n","description":"<p>number to compute</p>\n","type":"Number"}],"return":{"description":"absolute value of given number","type":"Number"},"example":["\n<div class = \"norender\"><code>\nfunction setup() {\n  let x = -3;\n  let y = abs(x);\n\n  print(x); // -3\n  print(y); // 3\n}\n</code></div>"],"alt":"no image displayed","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":33,"description":"<p>Calculates the closest int value that is greater than or equal to the\nvalue of the parameter. Maps to Math.ceil(). For example, ceil(9.03)\nreturns the value 10.</p>\n","itemtype":"method","name":"ceil","params":[{"name":"n","description":"<p>number to round up</p>\n","type":"Number"}],"return":{"description":"rounded up number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  // map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the ceiling of the mapped number.\n  let bx = ceil(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":72,"description":"<p>Constrains a value between a minimum and maximum value.</p>\n","itemtype":"method","name":"constrain","params":[{"name":"n","description":"<p>number to constrain</p>\n","type":"Number"},{"name":"low","description":"<p>minimum limit</p>\n","type":"Number"},{"name":"high","description":"<p>maximum limit</p>\n","type":"Number"}],"return":{"description":"constrained number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  let leftWall = 25;\n  let rightWall = 75;\n\n  // xm is just the mouseX, while\n  // xc is the mouseX, but constrained\n  // between the leftWall and rightWall!\n  let xm = mouseX;\n  let xc = constrain(mouseX, leftWall, rightWall);\n\n  // Draw the walls.\n  stroke(150);\n  line(leftWall, 0, leftWall, height);\n  line(rightWall, 0, rightWall, height);\n\n  // Draw xm and xc as circles.\n  noStroke();\n  fill(150);\n  ellipse(xm, 33, 9, 9); // Not Constrained\n  fill(0);\n  ellipse(xc, 66, 9, 9); // Constrained\n}\n</code></div>"],"alt":"2 vertical lines. 2 ellipses move with mouse X 1 does not move passed lines","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":116,"description":"<p>Calculates the distance between two points, in either two or three dimensions.\nIf you looking for distance between two vectors see <a herf=\"#/p5.Vector/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"distance between the two points","type":"Number"},"example":["\n<div><code>\n// Move your mouse inside the canvas to see the\n// change in distance between two points!\nfunction draw() {\n  background(200);\n  fill(0);\n\n  let x1 = 10;\n  let y1 = 90;\n  let x2 = mouseX;\n  let y2 = mouseY;\n\n  line(x1, y1, x2, y2);\n  ellipse(x1, y1, 7, 7);\n  ellipse(x2, y2, 7, 7);\n\n  // d is the length of the line\n  // the distance from point 1 to point 2.\n  let d = dist(x1, y1, x2, y2);\n\n  // Let's write d along the line we are drawing!\n  push();\n  translate((x1 + x2) / 2, (y1 + y2) / 2);\n  rotate(atan2(y2 - y1, x2 - x1));\n  text(nfc(d, 1), 0, -5);\n  pop();\n  // Fancy!\n}\n</code></div>"],"alt":"2 ellipses joined by line. 1 ellipse moves with mouse X&Y. Distance displayed.","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":116,"params":[{"name":"x1","description":"<p>x-coordinate of the first point</p>\n","type":"Number"},{"name":"y1","description":"<p>y-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"<p>x-coordinate of the second point</p>\n","type":"Number"},{"name":"y2","description":"<p>y-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}},{"line":161,"params":[{"name":"x1","description":"","type":"Number"},{"name":"y1","description":"","type":"Number"},{"name":"z1","description":"<p>z-coordinate of the first point</p>\n","type":"Number"},{"name":"x2","description":"","type":"Number"},{"name":"y2","description":"","type":"Number"},{"name":"z2","description":"<p>z-coordinate of the second point</p>\n","type":"Number"}],"return":{"description":"distance between the two points","type":"Number"}}]},{"file":"src/math/calculation.js","line":182,"description":"<p>Returns Euler's number e (2.71828...) raised to the power of the n\nparameter. Maps to Math.exp().</p>\n","itemtype":"method","name":"exp","params":[{"name":"n","description":"<p>exponent to raise</p>\n","type":"Number"}],"return":{"description":"e^n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n\n  // Compute the exp() function with a value between 0 and 2\n  let xValue = map(mouseX, 0, width, 0, 2);\n  let yValue = exp(xValue);\n\n  let y = map(yValue, 0, 8, height, 0);\n\n  let legend = 'exp (' + nfc(xValue, 3) + ')\\n= ' + nf(yValue, 1, 4);\n  stroke(150);\n  line(mouseX, y, mouseX, height);\n  fill(0);\n  text(legend, 5, 15);\n  noStroke();\n  ellipse(mouseX, y, 7, 7);\n\n  // Draw the exp(x) curve,\n  // over the domain of x from 0 to 2\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, 2);\n    yValue = exp(xValue);\n    y = map(yValue, 0, 8, height, 0);\n    vertex(x, y);\n  }\n\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height - 1, width, height - 1);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. e^n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":231,"description":"<p>Calculates the closest int value that is less than or equal to the\nvalue of the parameter. Maps to Math.floor().</p>\n","itemtype":"method","name":"floor","params":[{"name":"n","description":"<p>number to round down</p>\n","type":"Number"}],"return":{"description":"rounded down number","type":"Integer"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  //Get the floor of the mapped number.\n  let bx = floor(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"2 horizontal lines & number sets. increase with mouse x. bottom to 2 decimals","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":269,"description":"<p>Calculates a number between two numbers at a specific increment. The amt\nparameter is the amount to interpolate between the two values where 0.0\nequal to the first point, 0.1 is very near the first point, 0.5 is\nhalf-way in between, and 1.0 is equal to the second point. If the\nvalue of amt is more than 1.0 or less than 0.0, the number will be\ncalculated accordingly in the ratio of the two given numbers. The lerp\nfunction is convenient for creating motion along a straight\npath and for drawing dotted lines.</p>\n","itemtype":"method","name":"lerp","params":[{"name":"start","description":"<p>first value</p>\n","type":"Number"},{"name":"stop","description":"<p>second value</p>\n","type":"Number"},{"name":"amt","description":"<p>number</p>\n","type":"Number"}],"return":{"description":"lerped value","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  background(200);\n  let a = 20;\n  let b = 80;\n  let c = lerp(a, b, 0.2);\n  let d = lerp(a, b, 0.5);\n  let e = lerp(a, b, 0.8);\n\n  let y = 50;\n\n  strokeWeight(5);\n  stroke(0); // Draw the original points in black\n  point(a, y);\n  point(b, y);\n\n  stroke(100); // Draw the lerp points in gray\n  point(c, y);\n  point(d, y);\n  point(e, y);\n}\n</code></div>"],"alt":"5 points horizontally staggered mid-canvas. mid 3 are grey, outer black","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":316,"description":"<p>Calculates the natural logarithm (the base-e logarithm) of a number. This\nfunction expects the n parameter to be a value greater than 0.0. Maps to\nMath.log().</p>\n","itemtype":"method","name":"log","params":[{"name":"n","description":"<p>number greater than 0</p>\n","type":"Number"}],"return":{"description":"natural logarithm of n","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let maxX = 2.8;\n  let maxY = 1.5;\n\n  // Compute the natural log of a value between 0 and maxX\n  let xValue = map(mouseX, 0, width, 0, maxX);\n  let yValue, y;\n  if (xValue > 0) {\n   // Cannot take the log of a negative number.\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n\n    // Display the calculation occurring.\n    let legend = 'log(' + nf(xValue, 1, 2) + ')\\n= ' + nf(yValue, 1, 3);\n    stroke(150);\n    line(mouseX, y, mouseX, height);\n    fill(0);\n    text(legend, 5, 15);\n    noStroke();\n    ellipse(mouseX, y, 7, 7);\n  }\n\n  // Draw the log(x) curve,\n  // over the domain of x from 0 to maxX\n  noFill();\n  stroke(0);\n  beginShape();\n  for (let x = 0; x < width; x++) {\n    xValue = map(x, 0, width, 0, maxX);\n    yValue = log(xValue);\n    y = map(yValue, -maxY, maxY, height, 0);\n    vertex(x, y);\n  }\n  endShape();\n  line(0, 0, 0, height);\n  line(0, height / 2, width, height / 2);\n}\n</code></div>"],"alt":"ellipse moves along a curve with mouse x. natural logarithm of n displayed.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":371,"description":"<p>Calculates the magnitude (or length) of a vector. A vector is a direction\nin space commonly used in computer graphics and linear algebra. Because it\nhas no \"start\" position, the magnitude of a vector can be thought of as\nthe distance from the coordinate 0,0 to its x,y value. Therefore, <a href=\"#/p5/mag\">mag()</a> is\na shortcut for writing dist(0, 0, x, y).</p>\n","itemtype":"method","name":"mag","params":[{"name":"a","description":"<p>first value</p>\n","type":"Number"},{"name":"b","description":"<p>second value</p>\n","type":"Number"}],"return":{"description":"magnitude of vector from (0,0) to (a,b)","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  let x1 = 20;\n  let x2 = 80;\n  let y1 = 30;\n  let y2 = 70;\n\n  line(0, 0, x1, y1);\n  print(mag(x1, y1)); // Prints \"36.05551275463989\"\n  line(0, 0, x2, y1);\n  print(mag(x2, y1)); // Prints \"85.44003745317531\"\n  line(0, 0, x1, y2);\n  print(mag(x1, y2)); // Prints \"72.80109889280519\"\n  line(0, 0, x2, y2);\n  print(mag(x2, y2)); // Prints \"106.3014581273465\"\n}\n</code></div>"],"alt":"4 lines of different length radiate from top left of canvas.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":409,"description":"<p>Re-maps a number from one range to another.</p>\n<p>In the first example above, the number 25 is converted from a value in the\nrange of 0 to 100 into a value that ranges from the left edge of the\nwindow (0) to the right edge (width).</p>\n","itemtype":"method","name":"map","params":[{"name":"value","description":"<p>the incoming value to be converted</p>\n","type":"Number"},{"name":"start1","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop1","description":"<p>upper bound of the value's current range</p>\n","type":"Number"},{"name":"start2","description":"<p>lower bound of the value's target range</p>\n","type":"Number"},{"name":"stop2","description":"<p>upper bound of the value's target range</p>\n","type":"Number"},{"name":"withinBounds","description":"<p>constrain the value to the newly mapped range</p>\n","type":"Boolean","optional":true}],"return":{"description":"remapped number","type":"Number"},"example":["\n  <div><code>\nlet value = 25;\nlet m = map(value, 0, 100, 0, width);\nellipse(m, 50, 10, 10);\n</code></div>\n\n  <div><code>\nfunction setup() {\n  noStroke();\n}\n\nfunction draw() {\n  background(204);\n  let x1 = map(mouseX, 0, width, 25, 75);\n  ellipse(x1, 25, 25, 25);\n  //This ellipse is constrained to the 0-100 range\n  //after setting withinBounds to true\n  let x2 = map(mouseX, 0, width, 0, 100, true);\n  ellipse(x2, 75, 25, 25);\n}\n</code></div>"],"alt":"10 by 10 white ellipse with in mid left canvas\n2 25 by 25 white ellipses move with mouse x. Bottom has more range from X","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":464,"description":"<p>Determines the largest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/max\">max()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"max","return":{"description":"maximum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how max() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Maximum value in the array.\n  textSize(32);\n  text(max(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 9","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":464,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"maximum Number","type":"Number"}},{"line":499,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":512,"description":"<p>Determines the smallest value in a sequence of numbers, and then returns\nthat value. <a href=\"#/p5/min\">min()</a> accepts any number of Number parameters, or an Array\nof any length.</p>\n","itemtype":"method","name":"min","return":{"description":"minimum Number","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  // Change the elements in the array and run the sketch\n  // to show how min() works!\n  let numArray = [2, 1, 5, 4, 8, 9];\n  fill(0);\n  noStroke();\n  text('Array Elements', 0, 10);\n  // Draw all numbers in the array\n  let spacing = 15;\n  let elemsY = 25;\n  for (let i = 0; i < numArray.length; i++) {\n    text(numArray[i], i * spacing, elemsY);\n  }\n  let maxX = 33;\n  let maxY = 80;\n  // Draw the Minimum value in the array.\n  textSize(32);\n  text(min(numArray), maxX, maxY);\n}\n</code></div>"],"alt":"Small text at top reads: Array Elements 2 1 5 4 8 9. Large text at center: 1","class":"p5","module":"Math","submodule":"Calculation","overloads":[{"line":512,"params":[{"name":"n0","description":"<p>Number to compare</p>\n","type":"Number"},{"name":"n1","description":"<p>Number to compare</p>\n","type":"Number"}],"return":{"description":"minimum Number","type":"Number"}},{"line":547,"params":[{"name":"nums","description":"<p>Numbers to compare</p>\n","type":"Number[]"}],"return":{"description":"","type":"Number"}}]},{"file":"src/math/calculation.js","line":560,"description":"<p>Normalizes a number from another range into a value between 0 and 1.\nIdentical to map(value, low, high, 0, 1).\nNumbers outside of the range are not clamped to 0 and 1, because\nout-of-range values are often intentional and useful. (See the example above.)</p>\n","itemtype":"method","name":"norm","params":[{"name":"value","description":"<p>incoming value to be normalized</p>\n","type":"Number"},{"name":"start","description":"<p>lower bound of the value's current range</p>\n","type":"Number"},{"name":"stop","description":"<p>upper bound of the value's current range</p>\n","type":"Number"}],"return":{"description":"normalized number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let currentNum = mouseX;\n  let lowerBound = 0;\n  let upperBound = width; //100;\n  let normalized = norm(currentNum, lowerBound, upperBound);\n  let lineY = 70;\n  stroke(3);\n  line(0, lineY, width, lineY);\n  //Draw an ellipse mapped to the non-normalized value.\n  noStroke();\n  fill(50);\n  let s = 7; // ellipse size\n  ellipse(currentNum, lineY, s, s);\n\n  // Draw the guide\n  let guideY = lineY + 15;\n  text('0', 0, guideY);\n  textAlign(RIGHT);\n  text('100', width, guideY);\n\n  // Draw the normalized value\n  textAlign(LEFT);\n  fill(0);\n  textSize(32);\n  let normalY = 40;\n  let normalX = 20;\n  text(normalized, normalX, normalY);\n}\n</code></div>"],"alt":"ellipse moves with mouse. 0 shown left & 100 right and updating values center","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":612,"description":"<p>Facilitates exponential expressions. The <a href=\"#/p5/pow\">pow()</a> function is an efficient\nway of multiplying numbers by themselves (or their reciprocals) in large\nquantities. For example, pow(3, 5) is equivalent to the expression\n3 × 3 × 3 × 3 × 3 and pow(3, -5) is equivalent to 1 /\n3 × 3 × 3 × 3 × 3. Maps to\nMath.pow().</p>\n","itemtype":"method","name":"pow","params":[{"name":"n","description":"<p>base of the exponential expression</p>\n","type":"Number"},{"name":"e","description":"<p>power by which to raise the base</p>\n","type":"Number"}],"return":{"description":"n^e","type":"Number"},"example":["\n<div><code>\nfunction setup() {\n  //Exponentially increase the size of an ellipse.\n  let eSize = 3; // Original Size\n  let eLoc = 10; // Original Location\n\n  ellipse(eLoc, eLoc, eSize, eSize);\n\n  ellipse(eLoc * 2, eLoc * 2, pow(eSize, 2), pow(eSize, 2));\n\n  ellipse(eLoc * 4, eLoc * 4, pow(eSize, 3), pow(eSize, 3));\n\n  ellipse(eLoc * 8, eLoc * 8, pow(eSize, 4), pow(eSize, 4));\n}\n</code></div>"],"alt":"small to large ellipses radiating from top left of canvas","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":646,"description":"<p>Calculates the integer closest to the n parameter. For example,\nround(133.8) returns the value 134. Maps to Math.round().</p>\n","itemtype":"method","name":"round","params":[{"name":"n","description":"<p>number to round</p>\n","type":"Number"},{"name":"decimals","description":"<p>number of decimal places to round to, default is 0</p>\n","type":"Number","optional":true}],"return":{"description":"rounded number","type":"Integer"},"example":["\n<div><code>\nlet x = round(3.7);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nlet x = round(12.782383, 2);\ntext(x, width / 2, height / 2);\n</code></div>\n<div><code>\nfunction draw() {\n  background(200);\n  //map, mouseX between 0 and 5.\n  let ax = map(mouseX, 0, 100, 0, 5);\n  let ay = 66;\n\n  // Round the mapped number.\n  let bx = round(map(mouseX, 0, 100, 0, 5));\n  let by = 33;\n\n  // Multiply the mapped numbers by 20 to more easily\n  // see the changes.\n  stroke(0);\n  fill(0);\n  line(0, ay, ax * 20, ay);\n  line(0, by, bx * 20, by);\n\n  // Reformat the float returned by map and draw it.\n  noStroke();\n  text(nfc(ax, 2), ax, ay - 5);\n  text(nfc(bx, 1), bx, by - 5);\n}\n</code></div>"],"alt":"\"4\" written in middle of canvas\n\"12.78\" written in middle of canvas\ntwo horizontal lines rounded values displayed on top.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":701,"description":"<p>Squares a number (multiplies a number by itself). The result is always a\npositive number, as multiplying two negative numbers always yields a\npositive result. For example, -1 * -1 = 1.</p>\n","itemtype":"method","name":"sq","params":[{"name":"n","description":"<p>number to square</p>\n","type":"Number"}],"return":{"description":"squared number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = map(mouseX, 0, width, 0, 10);\n  let y1 = 80;\n  let x2 = sq(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  let spacing = 15;\n  noStroke();\n  fill(0);\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sq(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squared values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":745,"description":"<p>Calculates the square root of a number. The square root of a number is\nalways positive, even though there may be a valid negative root. The\nsquare root s of number a is such that s*s = a. It is the opposite of\nsquaring. Maps to Math.sqrt().</p>\n","itemtype":"method","name":"sqrt","params":[{"name":"n","description":"<p>non-negative number to square root</p>\n","type":"Number"}],"return":{"description":"square root of number","type":"Number"},"example":["\n<div><code>\nfunction draw() {\n  background(200);\n  let eSize = 7;\n  let x1 = mouseX;\n  let y1 = 80;\n  let x2 = sqrt(x1);\n  let y2 = 20;\n\n  // Draw the non-squared.\n  line(0, y1, width, y1);\n  ellipse(x1, y1, eSize, eSize);\n\n  // Draw the squared.\n  line(0, y2, width, y2);\n  ellipse(x2, y2, eSize, eSize);\n\n  // Draw dividing line.\n  stroke(100);\n  line(0, height / 2, width, height / 2);\n\n  // Draw text.\n  noStroke();\n  fill(0);\n  let spacing = 15;\n  text('x = ' + x1, 0, y1 + spacing);\n  text('sqrt(x) = ' + x2, 0, y2 + spacing);\n}\n</code></div>"],"alt":"horizontal center line squareroot values displayed on top and regular on bottom.","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/calculation.js","line":832,"description":"<p>Calculates the fractional part of a number.</p>\n","itemtype":"method","name":"fract","params":[{"name":"num","description":"<p>Number whose fractional part needs to be found out</p>\n","type":"Number"}],"return":{"description":"fractional part of x, i.e, {x}","type":"Number"},"example":["\n<div><code>\ntext(7345.73472742, 10, 25);\ntext(fract(7345.73472742), 10, 75);\n</code></div>\n\n<div><code>\ntext(1.4215e-15, 10, 25);\ntext(fract(1.4215e-15), 10, 75);\n</code></div>"],"alt":"first row having a number and the second having the fractional part of the number\nfirst row having a number expressed in scientific notation and the second having the fractional part of the number","class":"p5","module":"Math","submodule":"Calculation"},{"file":"src/math/math.js","line":10,"description":"<p>Creates a new <a href=\"#/p5.Vector\">p5.Vector</a> (the datatype for storing vectors). This provides a\ntwo or three dimensional vector, specifically a Euclidean (also known as\ngeometric) vector. A vector is an entity that has both magnitude and\ndirection.</p>\n","itemtype":"method","name":"createVector","params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"","type":"p5.Vector"},"example":["\n<div><code>\nlet v1;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(255, 0, 255);\n  v1 = createVector(width / 2, height / 2);\n}\n\nfunction draw() {\n  background(255);\n  line(v1.x, v1.y, mouseX, mouseY);\n}\n</code></div>"],"alt":"draws a line from center of canvas to mouse pointer position.","class":"p5","module":"Math","submodule":"Vector"},{"file":"src/math/noise.js","line":36,"description":"<p>Returns the Perlin noise value at specified coordinates. Perlin noise is\na random sequence generator producing a more naturally ordered, harmonic\nsuccession of numbers compared to the standard <b>random()</b> function.\nIt was invented by Ken Perlin in the 1980s and been used since in\ngraphical applications to produce procedural textures, natural motion,\nshapes, terrains etc.<br /><br /> The main difference to the\n<b>random()</b> function is that Perlin noise is defined in an infinite\nn-dimensional space where each pair of coordinates corresponds to a\nfixed semi-random value (fixed only for the lifespan of the program; see\nthe <a href=\"#/p5/noiseSeed\">noiseSeed()</a> function). p5.js can compute 1D, 2D and 3D noise,\ndepending on the number of coordinates given. The resulting value will\nalways be between 0.0 and 1.0. The noise value can be animated by moving\nthrough the noise space as demonstrated in the example above. The 2nd\nand 3rd dimension can also be interpreted as time.<br /><br />The actual\nnoise is structured similar to an audio signal, in respect to the\nfunction's use of frequencies. Similar to the concept of harmonics in\nphysics, perlin noise is computed over several octaves which are added\ntogether for the final result. <br /><br />Another way to adjust the\ncharacter of the resulting sequence is the scale of the input\ncoordinates. As the function works within an infinite space the value of\nthe coordinates doesn't matter as such, only the distance between\nsuccessive coordinates does (eg. when using <b>noise()</b> within a\nloop). As a general rule the smaller the difference between coordinates,\nthe smoother the resulting noise sequence will be. Steps of 0.005-0.03\nwork best for most applications, but this will differ depending on use.</p>\n","itemtype":"method","name":"noise","params":[{"name":"x","description":"<p>x-coordinate in noise space</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate in noise space</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z-coordinate in noise space</p>\n","type":"Number","optional":true}],"return":{"description":"Perlin noise value (between 0 and 1) at specified\n                     coordinates","type":"Number"},"example":["\n<div>\n<code>\nlet xoff = 0.0;\n\nfunction draw() {\n  background(204);\n  xoff = xoff + 0.01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>\n<div>\n<code>let noiseScale=0.02;\n\nfunction draw() {\n  background(0);\n  for (let x=0; x < width; x++) {\n    let noiseVal = noise((mouseX+x)*noiseScale, mouseY*noiseScale);\n    stroke(noiseVal*255);\n    line(x, mouseY+noiseVal*80, x, height);\n  }\n}\n</code>\n</div>"],"alt":"vertical line moves left to right with updating noise values.\nhorizontal wave pattern effected by mouse x-position & updating noise values.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":178,"description":"<p>Adjusts the character and level of detail produced by the Perlin noise\n function. Similar to harmonics in physics, noise is computed over\n several octaves. Lower octaves contribute more to the output signal and\n as such define the overall intensity of the noise, whereas higher octaves\n create finer grained details in the noise sequence.\nBy default, noise is computed over 4 octaves with each octave contributing\n exactly half than its predecessor, starting at 50% strength for the 1st\n octave. This falloff amount can be changed by adding an additional function\n parameter. Eg. a falloff factor of 0.75 means each octave will now have\n 75% impact (25% less) of the previous lower octave. Any value between\n 0.0 and 1.0 is valid, however note that values greater than 0.5 might\n result in greater than 1.0 values returned by <b>noise()</b>.\nBy changing these parameters, the signal created by the <b>noise()</b>\n function can be adapted to fit very specific needs and characteristics.</p>\n","itemtype":"method","name":"noiseDetail","params":[{"name":"lod","description":"<p>number of octaves to be used by the noise</p>\n","type":"Number"},{"name":"falloff","description":"<p>falloff factor for each octave</p>\n","type":"Number"}],"example":["\n <div>\n <code>\n let noiseVal;\n let noiseScale = 0.02;\nfunction setup() {\n   createCanvas(100, 100);\n }\nfunction draw() {\n   background(0);\n   for (let y = 0; y < height; y++) {\n     for (let x = 0; x < width / 2; x++) {\n       noiseDetail(2, 0.2);\n       noiseVal = noise((mouseX + x) * noiseScale, (mouseY + y) * noiseScale);\n       stroke(noiseVal * 255);\n       point(x, y);\n       noiseDetail(8, 0.65);\n       noiseVal = noise(\n         (mouseX + x + width / 2) * noiseScale,\n         (mouseY + y) * noiseScale\n       );\n       stroke(noiseVal * 255);\n       point(x + width / 2, y);\n     }\n   }\n }\n </code>\n </div>"],"alt":"2 vertical grey smokey patterns affected my mouse x-position and noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/noise.js","line":243,"description":"<p>Sets the seed value for <b>noise()</b>. By default, <b>noise()</b>\nproduces different results each time the program is run. Set the\n<b>value</b> parameter to a constant to return the same pseudo-random\nnumbers each time the software is run.</p>\n","itemtype":"method","name":"noiseSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>let xoff = 0.0;\n\nfunction setup() {\n  noiseSeed(99);\n  stroke(0, 10);\n}\n\nfunction draw() {\n  xoff = xoff + .01;\n  let n = noise(xoff) * width;\n  line(n, 0, n, height);\n}\n</code>\n</div>"],"alt":"vertical grey lines drawing in pattern affected by noise.","class":"p5","module":"Math","submodule":"Noise"},{"file":"src/math/p5.Vector.js","line":69,"description":"<p>The x component of the vector</p>\n","itemtype":"property","name":"x","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":74,"description":"<p>The y component of the vector</p>\n","itemtype":"property","name":"y","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":79,"description":"<p>The z component of the vector</p>\n","itemtype":"property","name":"z","type":"Number","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":86,"description":"<p>Returns a string representation of a vector v by calling String(v)\nor v.toString(). This method is useful for logging vectors in the\nconsole.</p>\n","itemtype":"method","name":"toString","return":{"description":"","type":"String"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(String(v)); // prints \"p5.Vector Object : [20, 30, 0]\"\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text(v1.toString(), 10, 25, 90, 75);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":136,"description":"<p>Sets the x, y, and z component of the vector using two or three separate\nvariables, the data from a <a href=\"#/p5.Vector\">p5.Vector</a>, or the values from a float array.</p>\n","itemtype":"method","name":"set","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nfunction setup() {\n  let v = createVector(1, 2, 3);\n  v.set(4, 5, 6); // Sets vector to [4, 5, 6]\n\n  let v1 = createVector(0, 0, 0);\n  let arr = [1, 2, 3];\n  v1.set(arr); // Sets vector to [1, 2, 3]\n}\n</code>\n</div>\n\n<div>\n<code>\nlet v0, v1;\nfunction setup() {\n  createCanvas(100, 100);\n\n  v0 = createVector(0, 0);\n  v1 = createVector(50, 50);\n}\n\nfunction draw() {\n  background(240);\n\n  drawArrow(v0, v1, 'black');\n  v1.set(v1.x + random(-1, 1), v1.y + random(-1, 1));\n\n  noStroke();\n  text('x: ' + round(v1.x) + ' y: ' + round(v1.y), 20, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":136,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":195,"params":[{"name":"value","description":"<p>the vector to set</p>\n","type":"p5.Vector|Number[]"}],"chainable":1}]},{"file":"src/math/p5.Vector.js","line":219,"description":"<p>Gets a copy of the vector, returns a <a href=\"#/p5.Vector\">p5.Vector</a> object.</p>\n","itemtype":"method","name":"copy","return":{"description":"the copy of the <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = v1.copy();\nprint(v1.x === v2.x && v1.y === v2.y && v1.z === v2.z);\n// Prints \"true\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":248,"description":"<p>Adds x, y, and z components to a vector, adds one vector to another, or\nadds two independent vectors together. The version of the method that adds\ntwo vectors together is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the others\nacts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"add","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.add(4, 5, 6);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [4, 5, 6];\nv.add(arr);\n// v's components are set to [5, 7, 9]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.add(v1, v2);\n// v3 has components [3, 5, 7]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector + blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(-30, 20);\n  drawArrow(v1, v2, 'blue');\n\n  let v3 = p5.Vector.add(v1, v2);\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":248,"params":[{"name":"x","description":"<p>the x component of the vector to be added</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to be added</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to be added</p>\n","type":"Number","optional":true}],"chainable":1},{"line":325,"params":[{"name":"value","description":"<p>the vector to add</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2059,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to add</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":372,"description":"<p>Gives remainder of a vector when it is divided by another vector.\nSee examples for more context.</p>\n","itemtype":"method","name":"rem","chainable":1,"example":["\n<div class='norender'>\n<code>\nlet v = createVector(3, 4, 5);\nv.rem(2, 3, 4);\n// v's components are set to [1, 1, 1]\n</code>\n</div>\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(3, 4, 5);\nlet v2 = createVector(2, 3, 4);\n\nlet v3 = p5.Vector.rem(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":372,"params":[{"name":"x","description":"<p>the x component of divisor vector</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of divisor vector</p>\n","type":"Number"},{"name":"z","description":"<p>the z component of divisor vector</p>\n","type":"Number"}],"chainable":1},{"line":401,"params":[{"name":"value","description":"<p>divisor vector</p>\n","type":"p5.Vector | Number[]"}],"chainable":1},{"line":2085,"params":[{"name":"v1","description":"<p>dividend <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>divisor <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1},{"line":2091,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":461,"description":"<p>Subtracts x, y, and z components from a vector, subtracts one vector from\nanother, or subtracts two independent vectors. The version of the method\nthat subtracts two vectors is a static method and returns a <a href=\"#/p5.Vector\">p5.Vector</a>, the\nother acts directly on the vector. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"sub","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\nv.sub(1, 1, 1);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 5, 6);\n// Provide arguments as an array\nlet arr = [1, 1, 1];\nv.sub(arr);\n// v's components are set to [3, 4, 5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(2, 3, 4);\nlet v2 = createVector(1, 2, 3);\n\nlet v3 = p5.Vector.sub(v1, v2);\n// v3 has components [1, 1, 1]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\n// red vector - blue vector = purple vector\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  let v3 = p5.Vector.sub(v1, v2);\n  drawArrow(v2, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":461,"params":[{"name":"x","description":"<p>the x component of the vector to subtract</p>\n","type":"Number"},{"name":"y","description":"<p>the y component of the vector to subtract</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector to subtract</p>\n","type":"Number","optional":true}],"chainable":1},{"line":538,"params":[{"name":"value","description":"<p>the vector to subtract</p>\n","type":"p5.Vector|Number[]"}],"chainable":1},{"line":2110,"params":[{"name":"v1","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract from</p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>a <a href=\"#/p5.Vector\">p5.Vector</a> to subtract</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the resulting <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":562,"description":"<p>Multiplies the vector by a scalar, multiplies the x, y, and z components from a vector, or multiplies\nthe x, y, and z components of two independent vectors. When multiplying a vector by a scalar, the x, y,\nand z components of the vector are all multiplied by the scalar. When multiplying a vector by a vector,\nthe x, y, z components of both vectors are multiplied by each other\n(for example, with two vectors a and b: a.x * b.x, a.y * b.y, a.z * b.z). The static version of this method\ncreates a new <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector\ndirectly. Additionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"mult","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 2, 3);\nv.mult(2);\n// v's components are set to [2, 4, 6]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nv0.mult(v1); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\n// Provide arguments as an array\nlet arr = [2, 3, 4];\nv0.mult(arr); // v0's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(1, 2, 3);\nlet v1 = createVector(2, 3, 4);\nconst result = p5.Vector.mult(v0, v1);\nprint(result); // result's components are set to [2, 6, 12]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = p5.Vector.mult(v1, 2);\n// v2 has components [2, 4, 6]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(25, -25);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, -2, 2, true);\n  let v2 = p5.Vector.mult(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('multiplied by ' + num.toFixed(2), 5, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":562,"params":[{"name":"n","description":"<p>The number to multiply with the vector</p>\n","type":"Number"}],"chainable":1},{"line":655,"params":[{"name":"x","description":"<p>The number to multiply with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to multiply with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to multiply with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":663,"params":[{"name":"arr","description":"<p>The array to multiply with the components of the vector</p>\n","type":"Number[]"}],"chainable":1},{"line":669,"params":[{"name":"v","description":"<p>The vector to multiply with the components of the original vector</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2139,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2148,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2156,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2164,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":754,"description":"<p>Divides the vector by a scalar, divides a vector by the x, y, and z arguments, or divides the x, y, and\nz components of two vectors against each other. When dividing a vector by a scalar, the x, y,\nand z components of the vector are all divided by the scalar. When dividing a vector by a vector,\nthe x, y, z components of the source vector are treated as the dividend, and the x, y, z components\nof the argument is treated as the divisor (for example with two vectors a and b: a.x / b.x, a.y / b.y, a.z / b.z).\nThe static version of this method creates a\nnew <a href=\"#/p5.Vector\">p5.Vector</a> while the non static version acts on the vector directly.\nAdditionally, you may provide arguments to this function as an array.\nSee the examples for more context.</p>\n","itemtype":"method","name":"div","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(6, 4, 2);\nv.div(2); //v's components are set to [3, 2, 1]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nv0.div(v1); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\n// Provide arguments as an array\nlet arr = [3, 2, 4];\nv0.div(arr); // v0's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v0 = createVector(9, 4, 2);\nlet v1 = createVector(3, 2, 4);\nlet result = p5.Vector.div(v0, v1);\nprint(result); // result's components are set to [3, 2, 0.5]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nlet v2 = p5.Vector.div(v1, 2);\n// v2 has components [3, 2, 1]\nprint(v2);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 100);\n  let v1 = createVector(50, -50);\n  drawArrow(v0, v1, 'red');\n\n  let num = map(mouseX, 0, width, 10, 0.5, true);\n  let v2 = p5.Vector.div(v1, num);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('divided by ' + num.toFixed(2), 10, 90);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":754,"params":[{"name":"n","description":"<p>The number to divide the vector by</p>\n","type":"Number"}],"chainable":1},{"line":847,"params":[{"name":"x","description":"<p>The number to divide with the x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>The number to divide with the y component of the vector</p>\n","type":"Number"},{"name":"z","description":"<p>The number to divide with the z component of the vector</p>\n","type":"Number","optional":true}],"chainable":1},{"line":855,"params":[{"name":"arr","description":"<p>The array to divide the components of the vector by</p>\n","type":"Number[]"}],"chainable":1},{"line":861,"params":[{"name":"v","description":"<p>The vector to divide the components of the original vector by</p>\n","type":"p5.Vector"}],"chainable":1},{"line":2218,"params":[{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number","optional":true}],"static":1,"return":{"description":"The resulting new <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2227,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"n","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1},{"line":2235,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"v1","description":"","type":"p5.Vector"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1},{"line":2243,"params":[{"name":"v0","description":"","type":"p5.Vector"},{"name":"arr","description":"","type":"Number[]"},{"name":"target","description":"","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":959,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","itemtype":"method","name":"mag","return":{"description":"magnitude of the vector","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length: ' + v1.mag().toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>\n<div class=\"norender\">\n<code>\nlet v = createVector(20.0, 30.0, 40.0);\nlet m = v.mag();\nprint(m); // Prints \"53.85164807134504\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":959,"params":[],"return":{"description":"magnitude of the vector","type":"Number"}},{"line":2343,"params":[{"name":"vecT","description":"<p>the vector to return the magnitude of</p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the magnitude of vecT","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1007,"description":"<p>Calculates the squared magnitude of the vector and returns the result\nas a float (this is simply the equation <em>(x*x + y*y + z*z)</em>.)\nFaster if the real length is not required in the\ncase of comparing vectors, etc.</p>\n","itemtype":"method","name":"magSq","return":{"description":"squared magnitude of the vector","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(6, 4, 2);\nprint(v1.magSq()); // Prints \"56\"\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'black');\n\n  noStroke();\n  text('vector length squared: ' + v1.magSq().toFixed(2), 10, 45, 90, 55);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1061,"description":"<p>Calculates the dot product of two vectors. The version of the method\nthat computes the dot product of two independent vectors is a static\nmethod. See the examples for more context.</p>\n","itemtype":"method","name":"dot","return":{"description":"the dot product","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(2, 3, 4);\n\nprint(v1.dot(v2)); // Prints \"20\"\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n//Static method\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(3, 2, 1);\nprint(p5.Vector.dot(v1, v2)); // Prints \"10\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1061,"params":[{"name":"x","description":"<p>x component of the vector</p>\n","type":"Number"},{"name":"y","description":"<p>y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"the dot product","type":"Number"}},{"line":1091,"params":[{"name":"value","description":"<p>value component of the vector or a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"","type":"Number"}},{"line":2270,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the dot product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1103,"description":"<p>Calculates and returns a vector composed of the cross product between\ntwo vectors. Both the static and non static methods return a new <a href=\"#/p5.Vector\">p5.Vector</a>.\nSee the examples for more context.</p>\n","itemtype":"method","name":"cross","return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 2, 3);\nlet v2 = createVector(1, 2, 3);\n\nlet v = v1.cross(v2); // v's components are [0, 0, 0]\nprint(v);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet crossProduct = p5.Vector.cross(v1, v2);\n// crossProduct has components [0, 0, 1]\nprint(crossProduct);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1103,"params":[{"name":"v","description":"<p><a href=\"#/p5.Vector\">p5.Vector</a> to be crossed</p>\n","type":"p5.Vector"}],"return":{"description":"<a href=\"#/p5.Vector\">p5.Vector</a> composed of cross product","type":"p5.Vector"}},{"line":2284,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the cross product","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1145,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).\nIf you are looking to calculate distance with 2 points see <a href=\"#/p5/dist\">dist()</a></p>\n","itemtype":"method","name":"dist","return":{"description":"the distance","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = v1.dist(v2); // distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet distance = p5.Vector.dist(v1, v2);\n// distance is 1.4142...\nprint(distance);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(70, 50);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX, mouseY);\n  drawArrow(v0, v2, 'blue');\n\n  noStroke();\n  text('distance between vectors: ' + v2.dist(v1).toFixed(2), 5, 50, 95, 50);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1145,"params":[{"name":"v","description":"<p>the x, y, and z coordinates of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the distance","type":"Number"}},{"line":2299,"params":[{"name":"v1","description":"<p>the first <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"},{"name":"v2","description":"<p>the second <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"static":1,"return":{"description":"the distance","type":"Number"}}]},{"file":"src/math/p5.Vector.js","line":1217,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","itemtype":"method","name":"normalize","return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.normalize();\n// v's components are set to\n// [0.4454354, 0.8908708, 0.089087084]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// Static method\nlet v_initial = createVector(10, 20, 2);\n// v_initial has components [10.0, 20.0, 2.0]\nlet v_normalized = p5.Vector.normalize(v_initial);\nprint(v_normalized);\n// returns a new vector with components set to\n// [0.4454354, 0.8908708, 0.089087084]\n// v_initial remains unchanged\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  v1.normalize();\n  drawArrow(v0, v1.mult(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1217,"params":[],"return":{"description":"normalized <a href=\"#/p5.Vector\">p5.Vector</a>","type":"p5.Vector"}},{"line":2360,"params":[{"name":"v","description":"<p>the vector to normalize</p>\n","type":"p5.Vector"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"v normalized to a length of 1","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1287,"description":"<p>Limit the magnitude of this vector to the value used for the <b>max</b>\nparameter.</p>\n","itemtype":"method","name":"limit","params":[{"name":"max","description":"<p>the maximum magnitude for the vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10, 20, 2);\n// v has components [10.0, 20.0, 2.0]\nv.limit(5);\n// v's components are set to\n// [2.2271771, 4.4543543, 0.4454354]\n</code>\n</div>\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'red');\n  drawArrow(v0, v1.limit(35), 'blue');\n\n  noFill();\n  ellipse(50, 50, 35 * 2);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1345,"description":"<p>Set the magnitude of this vector to the value used for the <b>len</b>\nparameter.</p>\n","itemtype":"method","name":"setMag","params":[{"name":"len","description":"<p>the new length for this vector</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(3, 4, 0);\n// v has components [3.0, 4.0, 0.0]\nv.setMag(10);\n// v's components are set to [6.0, 8.0, 0.0]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(50, 50);\n\n  drawArrow(v0, v1, 'red');\n\n  let length = map(mouseX, 0, width, 0, 141, true);\n  v1.setMag(length);\n  drawArrow(v0, v1, 'blue');\n\n  noStroke();\n  text('magnitude set to: ' + length.toFixed(2), 10, 70, 90, 30);\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1401,"description":"<p>Calculate the angle of rotation for this vector(only 2D vectors).\np5.Vectors created using <a href=\"#/p5/createVector\">createVector()</a>\nwill take the current <a href=\"#/p5/angleMode\">angleMode</a> into\nconsideration, and give the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"heading","return":{"description":"the angle of rotation","type":"Number"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v1 = createVector(30, 50);\n  print(v1.heading()); // 1.0303768265243125\n\n  v1 = createVector(40, 50);\n  print(v1.heading()); // 0.8960553845713439\n\n  v1 = createVector(30, 70);\n  print(v1.heading()); // 1.1659045405098132\n}\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(mouseX - 50, mouseY - 50);\n\n  drawArrow(v0, v1, 'black');\n\n  let myHeading = v1.heading();\n  noStroke();\n  text(\n    'vector heading: ' +\n      myHeading.toFixed(2) +\n      ' radians or ' +\n      degrees(myHeading).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1473,"description":"<p>Rotate the vector to a specific angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"setHeading","params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// result of v.heading() is 1.1071487177940904\nv.setHeading(Math.PI);\n// result of v.heading() is now 3.141592653589793\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1498,"description":"<p>Rotate the vector by an angle (only 2D vectors), magnitude remains the\nsame</p>\n","itemtype":"method","name":"rotate","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nv.rotate(HALF_PI);\n// v's components are set to [-20.0, 9.999999, 0.0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\n// static function implementation\nlet v = createVector(10.0, 20.0);\n// v has components [10.0, 20.0, 0.0]\nlet rotated_v = p5.Vector.rotate(v, HALF_PI);\nconsole.log(rotated_v);\n// rotated_v's components are set to [-20.0, 9.999999, 0.0]\nconsole.log(v);\n// v's components remains the same (i.e, [10.0, 20.0, 0.0])\n</code>\n</div>\n\n<div>\n<code>\nlet angle = 0;\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = createVector(50, 0);\n\n  drawArrow(v0, v1.rotate(angle), 'black');\n  angle += 0.01;\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1498,"params":[{"name":"angle","description":"<p>the angle of rotation</p>\n","type":"Number"}],"chainable":1},{"line":2191,"params":[{"name":"v","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1}]},{"file":"src/math/p5.Vector.js","line":1567,"description":"<p>Calculates and returns the angle between two vectors. This function will take\nthe current <a href=\"#/p5/angleMode\">angleMode</a> into consideration, and\ngive the angle in radians or degree accordingly.</p>\n","itemtype":"method","name":"angleBetween","params":[{"name":"value","description":"<p>the x, y, and z components of a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","type":"p5.Vector"}],"return":{"description":"the angle between (in radians)","type":"Number"},"example":["\n<div class=\"norender\">\n<code>\nlet v1 = createVector(1, 0, 0);\nlet v2 = createVector(0, 1, 0);\n\nlet angle = v1.angleBetween(v2);\n// angle is PI/2\nprint(angle);\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n  let v0 = createVector(50, 50);\n\n  let v1 = createVector(50, 0);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(mouseX - 50, mouseY - 50);\n  drawArrow(v0, v2, 'blue');\n\n  let angleBetween = v1.angleBetween(v2);\n  noStroke();\n  text(\n    'angle between: ' +\n      angleBetween.toFixed(2) +\n      ' radians or ' +\n      degrees(angleBetween).toFixed(2) +\n      ' degrees',\n    10,\n    50,\n    90,\n    50\n  );\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1647,"description":"<p>Linear interpolate the vector to another vector</p>\n","itemtype":"method","name":"lerp","chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(1, 1, 0);\n\nv.lerp(3, 3, 0, 0.5); // v now has components [2,2,0]\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(0, 0, 0);\nlet v2 = createVector(100, 100, 0);\n\nlet v3 = p5.Vector.lerp(v1, v2, 0.5);\n// v3 has components [50,50,0]\nprint(v3);\n</code>\n</div>\n\n<div>\n<code>\nlet step = 0.01;\nlet amount = 0;\n\nfunction draw() {\n  background(240);\n  let v0 = createVector(0, 0);\n\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let v2 = createVector(90, 90);\n  drawArrow(v0, v2, 'blue');\n\n  if (amount > 1 || amount < 0) {\n    step *= -1;\n  }\n  amount += step;\n  let v3 = p5.Vector.lerp(v1, v2, amount);\n\n  drawArrow(v0, v3, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1647,"params":[{"name":"x","description":"<p>the x component</p>\n","type":"Number"},{"name":"y","description":"<p>the y component</p>\n","type":"Number"},{"name":"z","description":"<p>the z component</p>\n","type":"Number"},{"name":"amt","description":"<p>the amount of interpolation; some value between 0.0\n                        (old vector) and 1.0 (new vector). 0.9 is very near\n                        the new vector. 0.5 is halfway in between.</p>\n","type":"Number"}],"chainable":1},{"line":1720,"params":[{"name":"v","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to lerp to</p>\n","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"}],"chainable":1},{"line":2314,"params":[{"name":"v1","description":"","type":"p5.Vector"},{"name":"v2","description":"","type":"p5.Vector"},{"name":"amt","description":"","type":"Number"},{"name":"target","description":"<p>the vector to receive the result</p>\n","type":"p5.Vector","optional":true}],"static":1,"return":{"description":"the lerped value","type":"p5.Vector"}}]},{"file":"src/math/p5.Vector.js","line":1736,"description":"<p>Reflect the incoming vector about a normal to a line in 2D, or about a normal to a plane in 3D\nThis method acts on the vector directly</p>\n","itemtype":"method","name":"reflect","params":[{"name":"surfaceNormal","description":"<p>the <a href=\"#/p5.Vector\">p5.Vector</a> to reflect about, will be normalized by this method</p>\n","type":"p5.Vector"}],"chainable":1,"example":["\n<div class=\"norender\">\n<code>\nlet v = createVector(4, 6); // incoming vector, this example vector is heading to the right and downward\nlet n = createVector(0, -1); // surface normal to a plane (this example normal points directly upwards)\nv.reflect(n); // v is reflected about the surface normal n.  v's components are now set to [4, -6]\n</code>\n</div>\n\n<div>\n<code>\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(0, 0);\n  let v1 = createVector(mouseX, mouseY);\n  drawArrow(v0, v1, 'red');\n\n  let n = createVector(0, -30);\n  drawArrow(v1, n, 'blue');\n\n  let r = v1.copy();\n  r.reflect(n);\n  drawArrow(v1, r, 'purple');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1791,"description":"<p>Return a representation of this vector as a float array. This is only\nfor temporary use. If used in any other fashion, the contents should be\ncopied by using the <b>p5.Vector.<a href=\"#/p5.Vector/copy\">copy()</a></b> method to copy into your own\narray.</p>\n","itemtype":"method","name":"array","return":{"description":"an Array with the 3 values","type":"Number[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let v = createVector(20, 30);\n  print(v.array()); // Prints : Array [20, 30, 0]\n}\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v = createVector(10.0, 20.0, 30.0);\nlet f = v.array();\nprint(f[0]); // Prints \"10.0\"\nprint(f[1]); // Prints \"20.0\"\nprint(f[2]); // Prints \"30.0\"\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1823,"description":"<p>Equality check against a <a href=\"#/p5.Vector\">p5.Vector</a></p>\n","itemtype":"method","name":"equals","return":{"description":"whether the vectors are equals","type":"Boolean"},"example":["\n<div class = \"norender\">\n<code>\nlet v1 = createVector(5, 10, 20);\nlet v2 = createVector(5, 10, 20);\nlet v3 = createVector(13, 10, 19);\n\nprint(v1.equals(v2.x, v2.y, v2.z)); // true\nprint(v1.equals(v3.x, v3.y, v3.z)); // false\n</code>\n</div>\n\n<div class=\"norender\">\n<code>\nlet v1 = createVector(10.0, 20.0, 30.0);\nlet v2 = createVector(10.0, 20.0, 30.0);\nlet v3 = createVector(0.0, 0.0, 0.0);\nprint(v1.equals(v2)); // true\nprint(v1.equals(v3)); // false\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector","overloads":[{"line":1823,"params":[{"name":"x","description":"<p>the x component of the vector</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>the y component of the vector</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>the z component of the vector</p>\n","type":"Number","optional":true}],"return":{"description":"whether the vectors are equals","type":"Boolean"}},{"line":1853,"params":[{"name":"value","description":"<p>the vector to compare</p>\n","type":"p5.Vector|Array"}],"return":{"description":"","type":"Boolean"}}]},{"file":"src/math/p5.Vector.js","line":1878,"description":"<p>Make a new 2D vector from an angle</p>\n","itemtype":"method","name":"fromAngle","static":1,"params":[{"name":"angle","description":"<p>the desired angle, in radians (unaffected by <a href=\"#/p5/angleMode\">angleMode</a>)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(200);\n\n  // Create a variable, proportional to the mouseX,\n  // varying from 0-360, to represent an angle in degrees.\n  let myDegrees = map(mouseX, 0, width, 0, 360);\n\n  // Display that variable in an onscreen text.\n  // (Note the nfc() function to truncate additional decimal places,\n  // and the \"\\xB0\" character for the degree symbol.)\n  let readout = 'angle = ' + nfc(myDegrees, 1) + '\\xB0';\n  noStroke();\n  fill(0);\n  text(readout, 5, 15);\n\n  // Create a p5.Vector using the fromAngle function,\n  // and extract its x and y components.\n  let v = p5.Vector.fromAngle(radians(myDegrees), 30);\n  let vx = v.x;\n  let vy = v.y;\n\n  push();\n  translate(width / 2, height / 2);\n  noFill();\n  stroke(150);\n  line(0, 0, 30, 0);\n  stroke(0);\n  line(0, 0, vx, vy);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1929,"description":"<p>Make a new 3D vector from a pair of ISO spherical angles</p>\n","itemtype":"method","name":"fromAngles","static":1,"params":[{"name":"theta","description":"<p>the polar angle, in radians (zero is up)</p>\n","type":"Number"},{"name":"phi","description":"<p>the azimuthal angle, in radians\n                              (zero is out of the screen)</p>\n","type":"Number"},{"name":"length","description":"<p>the length of the new vector (defaults to 1)</p>\n","type":"Number","optional":true}],"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div modernizr='webgl'>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  fill(255);\n  noStroke();\n}\nfunction draw() {\n  background(255);\n\n  let t = millis() / 1000;\n\n  // add three point lights\n  pointLight(color('#f00'), p5.Vector.fromAngles(t * 1.0, t * 1.3, 100));\n  pointLight(color('#0f0'), p5.Vector.fromAngles(t * 1.1, t * 1.2, 100));\n  pointLight(color('#00f'), p5.Vector.fromAngles(t * 1.2, t * 1.1, 100));\n\n  sphere(35);\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":1978,"description":"<p>Make a new 2D unit vector from a random angle</p>\n","itemtype":"method","name":"random2D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random2D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.0] or\n// [-0.4695841, -0.14366731, 0.0] or\n// [0.6091097, -0.22805278, 0.0]\nprint(v);\n</code>\n</div>\n\n<div>\n<code>\nfunction setup() {\n  frameRate(1);\n}\n\nfunction draw() {\n  background(240);\n\n  let v0 = createVector(50, 50);\n  let v1 = p5.Vector.random2D();\n  drawArrow(v0, v1.mult(50), 'black');\n}\n\n// draw an arrow for a vector at a given base position\nfunction drawArrow(base, vec, myColor) {\n  push();\n  stroke(myColor);\n  strokeWeight(3);\n  fill(myColor);\n  translate(base.x, base.y);\n  line(0, 0, vec.x, vec.y);\n  rotate(vec.heading());\n  let arrowSize = 7;\n  translate(vec.mag() - arrowSize, 0);\n  triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0);\n  pop();\n}\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2031,"description":"<p>Make a new random 3D unit vector.</p>\n","itemtype":"method","name":"random3D","static":1,"return":{"description":"the new <a href=\"#/p5.Vector\">p5.Vector</a> object","type":"p5.Vector"},"example":["\n<div class=\"norender\">\n<code>\nlet v = p5.Vector.random3D();\n// May make v's attributes something like:\n// [0.61554617, -0.51195765, 0.599168] or\n// [-0.4695841, -0.14366731, -0.8711202] or\n// [0.6091097, -0.22805278, -0.7595902]\nprint(v);\n</code>\n</div>"],"class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2135,"description":"<p>Multiplies a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2187,"description":"<p>Rotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2214,"description":"<p>Divides a vector by a scalar and returns a new vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2267,"description":"<p>Calculates the dot product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2281,"description":"<p>Calculates the cross product of two vectors.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2295,"description":"<p>Calculates the Euclidean distance between two points (considering a\npoint as a vector object).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2310,"description":"<p>Linear interpolate a vector to another vector and return the result as a\nnew vector.</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2339,"description":"<p>Calculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x*x + y*y + z*z).)</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/p5.Vector.js","line":2357,"description":"<p>Normalize the vector to length 1 (make it a unit vector).</p>\n","class":"p5.Vector","module":"Math","submodule":"Vector"},{"file":"src/math/random.js","line":37,"description":"<p>Sets the seed value for <a href=\"#/p5/random\">random()</a>.</p>\n<p>By default, <a href=\"#/p5/random\">random()</a> produces different results each time the program\nis run. Set the seed parameter to a constant to return the same\npseudo-random numbers each time the software is run.</p>\n","itemtype":"method","name":"randomSeed","params":[{"name":"seed","description":"<p>the seed value</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nrandomSeed(99);\nfor (let i = 0; i < 100; i++) {\n  let r = random(0, 255);\n  stroke(r);\n  line(i, 0, i, 100);\n}\n</code>\n</div>"],"alt":"many vertical lines drawn in white, black or grey.","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/random.js","line":66,"description":"<p>Return a random floating-point number.</p>\n<p>Takes either 0, 1 or 2 arguments.</p>\n<p>If no argument is given, returns a random number from 0\nup to (but not including) 1.</p>\n<p>If one argument is given and it is a number, returns a random number from 0\nup to (but not including) the number.</p>\n<p>If one argument is given and it is an array, returns a random element from\nthat array.</p>\n<p>If two arguments are given, returns a random number from the\nfirst argument up to (but not including) the second argument.</p>\n","itemtype":"method","name":"random","return":{"description":"the random number","type":"Number"},"example":["\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(50);\n  stroke(r * 5);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\nfor (let i = 0; i < 100; i++) {\n  let r = random(-50, 50);\n  line(50, i, 50 + r, i);\n}\n</code>\n</div>\n<div>\n<code>\n// Get a random element from an array using the random(Array) syntax\nlet words = ['apple', 'bear', 'cat', 'dog'];\nlet word = random(words); // select random word\ntext(word, 10, 50); // draw the word\n</code>\n</div>"],"alt":"100 horizontal lines from center canvas to right. size+fill change each time\n100 horizontal lines from center of canvas. height & side change each render\nword displayed at random. Either apple, bear, cat, or dog","class":"p5","module":"Math","submodule":"Random","overloads":[{"line":66,"params":[{"name":"min","description":"<p>the lower bound (inclusive)</p>\n","type":"Number","optional":true},{"name":"max","description":"<p>the upper bound (exclusive)</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"}},{"line":119,"params":[{"name":"choices","description":"<p>the array to choose from</p>\n","type":"Array"}],"return":{"description":"the random element from the array","type":"*"}}]},{"file":"src/math/random.js","line":153,"description":"<p>Returns a random number fitting a Gaussian, or\n normal, distribution. There is theoretically no minimum or maximum\n value that <a href=\"#/p5/randomGaussian\">randomGaussian()</a> might return. Rather, there is\n just a very low probability that values far from the mean will be\n returned; and a higher probability that numbers near the mean will\n be returned.\nTakes either 0, 1 or 2 arguments.<br>\n If no args, returns a mean of 0 and standard deviation of 1.<br>\n If one arg, that arg is the mean (standard deviation is 1).<br>\n If two args, first is mean, second is standard deviation.</p>\n","itemtype":"method","name":"randomGaussian","params":[{"name":"mean","description":"<p>the mean</p>\n","type":"Number","optional":true},{"name":"sd","description":"<p>the standard deviation</p>\n","type":"Number","optional":true}],"return":{"description":"the random number","type":"Number"},"example":["\n <div>\n <code>\n for (let y = 0; y < 100; y++) {\n   let x = randomGaussian(50, 15);\n   line(50, y, x, y);\n }\n </code>\n </div>\n <div>\n <code>\n let distribution = new Array(360);\nfunction setup() {\n   createCanvas(100, 100);\n   for (let i = 0; i < distribution.length; i++) {\n     distribution[i] = floor(randomGaussian(0, 15));\n   }\n }\nfunction draw() {\n   background(204);\n  translate(width / 2, width / 2);\n  for (let i = 0; i < distribution.length; i++) {\n     rotate(TWO_PI / distribution.length);\n     stroke(0);\n     let dist = abs(distribution[i]);\n     line(0, 0, dist, 0);\n   }\n }\n </code>\n </div>"],"alt":"100 horizontal lines from center of canvas. height & side change each render\n black lines radiate from center of canvas. size determined each render","class":"p5","module":"Math","submodule":"Random"},{"file":"src/math/trigonometry.js","line":18,"description":"<p>The inverse of <a href=\"#/p5/cos\">cos()</a>, returns the arc cosine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned in\nthe range 0 to PI (3.1415927) if the angleMode is RADIANS or 0 to 180 if the\nangle mode is DEGREES.</p>\n","itemtype":"method","name":"acos","params":[{"name":"value","description":"<p>the value whose arc cosine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc cosine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.1415927 : -1.0 : 3.1415927\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 4.0;\nlet c = cos(a);\nlet ac = acos(c);\n// Prints: \"3.926991 : -0.70710665 : 2.3561943\"\nprint(a + ' : ' + c + ' : ' + ac);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":53,"description":"<p>The inverse of <a href=\"#/p5/sin\">sin()</a>, returns the arc sine of a value.\nThis function expects the values in the range of -1 to 1 and values are returned\nin the range -PI/2 to PI/2 if the angleMode is RADIANS or -90 to 90 if the angle\nmode is DEGREES.</p>\n","itemtype":"method","name":"asin","params":[{"name":"value","description":"<p>the value whose arc sine is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc sine of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"1.0471975 : 0.86602540 : 1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet s = sin(a);\nlet as = asin(s);\n// Prints: \"4.1887902 : -0.86602540 : -1.0471975\"\nprint(a + ' : ' + s + ' : ' + as);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":88,"description":"<p>The inverse of <a href=\"#/p5/tan\">tan()</a>, returns the arc tangent of a value.\nThis function expects the values in the range of -Infinity to Infinity (exclusive) and\nvalues are returned in the range -PI/2 to PI/2 if the angleMode is RADIANS or\n-90 to 90 if the angle mode is DEGREES.</p>\n","itemtype":"method","name":"atan","params":[{"name":"value","description":"<p>the value whose arc tangent is to be returned</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given value","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet a = PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"1.0471975 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>\n\n<div class= “norender\">\n<code>\nlet a = PI + PI / 3.0;\nlet t = tan(a);\nlet at = atan(t);\n// Prints: \"4.1887902 : 1.7320508 : 1.0471975\"\nprint(a + ' : ' + t + ' : ' + at);\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":123,"description":"<p>Calculates the angle (in radians) from a specified point to the coordinate\norigin as measured from the positive x-axis. Values are returned as a\nfloat in the range from PI to -PI if the angleMode is RADIANS or 180 to\n-180 if the angleMode is DEGREES. The atan2<a href=\"#/p5/\">()</a> function is\nmost often used for orienting geometry to the position of the cursor.</p>\n<p>Note: The y-coordinate of the point is the first parameter, and the\nx-coordinate is the second parameter, due the the structure of calculating\nthe tangent.</p>\n","itemtype":"method","name":"atan2","params":[{"name":"y","description":"<p>y-coordinate of the point</p>\n","type":"Number"},{"name":"x","description":"<p>x-coordinate of the point</p>\n","type":"Number"}],"return":{"description":"the arc tangent of the given point","type":"Number"},"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  translate(width / 2, height / 2);\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  rotate(a);\n  rect(-30, -5, 60, 10);\n}\n</code>\n</div>"],"alt":"60 by 10 rect at center of canvas rotates with mouse movements","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":159,"description":"<p>Calculates the cosine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"cos","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the cosine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + cos(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines form wave patterns, extend-down on left and right side","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":186,"description":"<p>Calculates the sine of an angle. This function takes into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range -1 to 1.</p>\n","itemtype":"method","name":"sin","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the sine of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 25.0;\nfor (let i = 0; i < 25; i++) {\n  line(i * 4, 50, i * 4, 50 + sin(a) * 40.0);\n  a = a + inc;\n}\n</code>\n</div>"],"alt":"vertical black lines extend down and up from center to form wave pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":213,"description":"<p>Calculates the tangent of an angle. This function takes into account\nthe current <a href=\"#/p5/angleMode\">angleMode</a>. Values are returned in the range of all real numbers.</p>\n","itemtype":"method","name":"tan","params":[{"name":"angle","description":"<p>the angle</p>\n","type":"Number"}],"return":{"description":"the tangent of the angle","type":"Number"},"example":["\n<div>\n<code>\nlet a = 0.0;\nlet inc = TWO_PI / 50.0;\nfor (let i = 0; i < 100; i = i + 2) {\n  line(i, 50, i, 50 + tan(a) * 2.0);\n  a = a + inc;\n}\n</code>"],"alt":"vertical black lines end down and up from center to form spike pattern","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":239,"description":"<p>Converts a radian measurement to its corresponding value in degrees.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"degrees","params":[{"name":"radians","description":"<p>the radians value to convert to degrees</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet rad = PI / 4;\nlet deg = degrees(rad);\nprint(rad + ' radians is ' + deg + ' degrees');\n// Prints: 0.7853981633974483 radians is 45 degrees\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":262,"description":"<p>Converts a degree measurement to its corresponding value in radians.\nRadians and degrees are two ways of measuring the same thing. There are\n360 degrees in a circle and 2*PI radians in a circle. For example,\n90° = PI/2 = 1.5707964. This function does not take into account the\ncurrent <a href=\"#/p5/angleMode\">angleMode</a>.</p>\n","itemtype":"method","name":"radians","params":[{"name":"degrees","description":"<p>the degree value to convert to radians</p>\n","type":"Number"}],"return":{"description":"the converted angle","type":"Number"},"example":["\n<div class= “norender\">\n<code>\nlet deg = 45.0;\nlet rad = radians(deg);\nprint(deg + ' degrees is ' + rad + ' radians');\n// Prints: 45 degrees is 0.7853981633974483 radians\n</code>\n</div>"],"class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/math/trigonometry.js","line":285,"description":"<p>Sets the current mode of p5 to given mode. Default mode is RADIANS.</p>\n","itemtype":"method","name":"angleMode","params":[{"name":"mode","description":"<p>either RADIANS or DEGREES</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nfunction draw() {\n  background(204);\n  angleMode(DEGREES); // Change the mode to DEGREES\n  let a = atan2(mouseY - height / 2, mouseX - width / 2);\n  translate(width / 2, height / 2);\n  push();\n  rotate(a);\n  rect(-20, -5, 40, 10); // Larger rectangle is rotating in degrees\n  pop();\n  angleMode(RADIANS); // Change the mode to RADIANS\n  rotate(a); // variable a stays the same\n  rect(-40, -5, 20, 10); // Smaller rectangle is rotating in radians\n}\n</code>\n</div>"],"alt":"40 by 10 rect in center rotates with mouse moves. 20 by 10 rect moves faster.","class":"p5","module":"Math","submodule":"Trigonometry"},{"file":"src/typography/attributes.js","line":11,"description":"<p>Sets the current alignment for drawing text. Accepts two\narguments: horizAlign (LEFT, CENTER, or RIGHT) and\nvertAlign (TOP, BOTTOM, CENTER, or BASELINE).</p>\n<p>The horizAlign parameter is in reference to the x value\nof the <a href=\"#/p5/text\">text()</a> function, while the vertAlign parameter\nis in reference to the y value.</p>\n<p>So if you write textAlign(LEFT), you are aligning the left\nedge of your text to the x value you give in <a href=\"#/p5/text\">text()</a>.\nIf you write textAlign(RIGHT, TOP), you are aligning the right edge\nof your text to the x value and the top of edge of the text\nto the y value.</p>\n","itemtype":"method","name":"textAlign","chainable":1,"example":["\n<div>\n<code>\ntextSize(16);\ntextAlign(RIGHT);\ntext('ABCD', 50, 30);\ntextAlign(CENTER);\ntext('EFGH', 50, 50);\ntextAlign(LEFT);\ntext('IJKL', 50, 70);\n</code>\n</div>\n\n<div>\n<code>\ntextSize(16);\nstrokeWeight(0.5);\n\nline(0, 12, width, 12);\ntextAlign(CENTER, TOP);\ntext('TOP', 0, 12, width);\n\nline(0, 37, width, 37);\ntextAlign(CENTER, CENTER);\ntext('CENTER', 0, 37, width);\n\nline(0, 62, width, 62);\ntextAlign(CENTER, BASELINE);\ntext('BASELINE', 0, 62, width);\n\nline(0, 87, width, 87);\ntextAlign(CENTER, BOTTOM);\ntext('BOTTOM', 0, 87, width);\n</code>\n</div>"],"alt":"Letters ABCD displayed at top left, EFGH at center and IJKL at bottom right.\nThe names of the four vertical alignments (TOP, CENTER, BASELINE & BOTTOM) rendered each showing that alignment's placement relative to a horizontal line.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":11,"params":[{"name":"horizAlign","description":"<p>horizontal alignment, either LEFT,\n                           CENTER, or RIGHT</p>\n","type":"Constant"},{"name":"vertAlign","description":"<p>vertical alignment, either TOP,\n                           BOTTOM, CENTER, or BASELINE</p>\n","type":"Constant","optional":true}],"chainable":1},{"line":72,"params":[],"return":{"description":"","type":"Object"}}]},{"file":"src/typography/attributes.js","line":81,"description":"<p>Sets/gets the spacing, in pixels, between lines of text. This setting will be\nused in all subsequent calls to the <a href=\"#/p5/text\">text()</a> function.</p>\n","itemtype":"method","name":"textLeading","chainable":1,"example":["\n<div>\n<code>\nlet lines = 'L1\\nL2\\nL3'; // \"\\n\" is a \"new line\" character\ntextSize(12);\n\ntextLeading(10);\ntext(lines, 10, 25);\n\ntextLeading(20);\ntext(lines, 40, 25);\n\ntextLeading(30);\ntext(lines, 70, 25);\n</code>\n</div>"],"alt":"A set of L1 L2 & L3 displayed vertically 3 times. spacing increases for each set","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":81,"params":[{"name":"leading","description":"<p>the size in pixels for spacing between lines</p>\n","type":"Number"}],"chainable":1},{"line":109,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":118,"description":"<p>Sets/gets the current font size. This size will be used in all subsequent\ncalls to the <a href=\"#/p5/text\">text()</a> function. Font size is measured in pixels.</p>\n","itemtype":"method","name":"textSize","chainable":1,"example":["\n<div>\n<code>\ntextSize(12);\ntext('Font Size 12', 10, 30);\ntextSize(14);\ntext('Font Size 14', 10, 60);\ntextSize(16);\ntext('Font Size 16', 10, 90);\n</code>\n</div>"],"alt":"'Font Size 12' displayed small, 'Font Size 14' medium & 'Font Size 16' large","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":118,"params":[{"name":"theSize","description":"<p>the size of the letters in units of pixels</p>\n","type":"Number"}],"chainable":1},{"line":141,"params":[],"return":{"description":"","type":"Number"}}]},{"file":"src/typography/attributes.js","line":150,"description":"<p>Sets/gets the style of the text for system fonts to NORMAL, ITALIC, BOLD or BOLDITALIC.\nNote: this may be is overridden by CSS styling. For non-system fonts\n(opentype, truetype, etc.) please load styled fonts instead.</p>\n","itemtype":"method","name":"textStyle","chainable":1,"example":["\n<div>\n<code>\nstrokeWeight(0);\ntextSize(12);\ntextStyle(NORMAL);\ntext('Font Style Normal', 10, 15);\ntextStyle(ITALIC);\ntext('Font Style Italic', 10, 40);\ntextStyle(BOLD);\ntext('Font Style Bold', 10, 65);\ntextStyle(BOLDITALIC);\ntext('Font Style Bold Italic', 10, 90);\n</code>\n</div>"],"alt":"Words Font Style Normal displayed normally, Italic in italic, bold in bold and bold italic in bold italics.","class":"p5","module":"Typography","submodule":"Attributes","overloads":[{"line":150,"params":[{"name":"theStyle","description":"<p>styling for text, either NORMAL,\n                           ITALIC, BOLD or BOLDITALIC</p>\n","type":"Constant"}],"chainable":1},{"line":178,"params":[],"return":{"description":"","type":"String"}}]},{"file":"src/typography/attributes.js","line":187,"description":"<p>Calculates and returns the width of any character or text string.</p>\n","itemtype":"method","name":"textWidth","params":[{"name":"theText","description":"<p>the String of characters to measure</p>\n","type":"String"}],"return":{"description":"the calculated width","type":"Number"},"example":["\n<div>\n<code>\ntextSize(28);\n\nlet aChar = 'P';\nlet cWidth = textWidth(aChar);\ntext(aChar, 0, 40);\nline(cWidth, 0, cWidth, 50);\n\nlet aString = 'p5.js';\nlet sWidth = textWidth(aString);\ntext(aString, 0, 85);\nline(sWidth, 50, sWidth, 100);\n</code>\n</div>"],"alt":"Letter P and p5.js are displayed with vertical lines at end.","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":222,"description":"<p>Returns the ascent of the current font at its current size. The ascent\nrepresents the distance, in pixels, of the tallest character above\nthe baseline.</p>\n","itemtype":"method","name":"textAscent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet asc = textAscent() * scalar; // Calc ascent\nline(0, base - asc, width, base - asc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\nasc = textAscent() * scalar; // Recalc ascent\nline(40, base - asc, width, base - asc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":251,"description":"<p>Returns the descent of the current font at its current size. The descent\nrepresents the distance, in pixels, of the character with the longest\ndescender below the baseline.</p>\n","itemtype":"method","name":"textDescent","return":{"description":"","type":"Number"},"example":["\n<div>\n<code>\nlet base = height * 0.75;\nlet scalar = 0.8; // Different for each font\n\ntextSize(32); // Set initial text size\nlet desc = textDescent() * scalar; // Calc descent\nline(0, base + desc, width, base + desc);\ntext('dp', 0, base); // Draw text on baseline\n\ntextSize(64); // Increase text size\ndesc = textDescent() * scalar; // Recalc descent\nline(40, base + desc, width, base + desc);\ntext('dp', 40, base); // Draw text on baseline\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":280,"description":"<p>Helper function to measure ascent and descent.</p>\n","class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/attributes.js","line":287,"description":"<p>Specifies how lines of text are wrapped within a text box. This requires a max-width set on the text area, specified in <a href=\"#/p5/text\">text()</a> as parameter <code>x2</code>.</p>\n<p>WORD wrap style only breaks lines at spaces. A single string without spaces that exceeds the boundaries of the canvas or text area is not truncated, and will overflow the desired area, disappearing at the canvas edge.</p>\n<p>CHAR wrap style breaks lines wherever needed to stay within the text box.</p>\n<p>WORD is the default wrap style, and both styles will still break lines at any line breaks (<code>\\n</code>) specified in the original text. The text area max-height parameter (<code>y2</code>) also still applies to wrapped text in both styles, lines of text that do not fit within the text area will not be drawn to the screen.</p>\n","itemtype":"method","name":"textWrap","params":[{"name":"wrapStyle","description":"<p>text wrapping style, either WORD or CHAR</p>\n","type":"Constant"}],"return":{"description":"wrapStyle","type":"String"},"example":["\n<div>\n<code>\ntextSize(20);\ntextWrap(WORD);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('Have a wonderful day', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\ntextSize(20);\ntextWrap(CHAR);\ntext('祝你有美好的一天', 0, 10, 100);\n</code>\n</div>\n<div>\n<code>\nconst scream = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\ntextSize(20);\ntextWrap(WORD);\ntext(scream, 0, 0, 100);\nfill(0, 0, 0, 75);\ntext(scream, 0, 20, 100);\nfill(0, 0, 0, 50);\ntext(scream, 0, 40, 100);\nfill(0, 0, 0, 25);\ntext(scream, 0, 60, 100);\nstrokeWeight(2);\nellipseMode(CENTER);\nfill(255);\nellipse(15, 50, 15, 15);\nfill(0);\nellipse(11, 47, 1, 1);\nellipse(19, 47, 1, 1);\nellipse(15, 52, 5, 5);\nline(15, 60, 15, 70);\nline(15, 65, 5, 55);\nline(15, 65, 25, 55);\nline(15, 70, 10, 80);\nline(15, 70, 20, 80);\n</code>\n</div>"],"class":"p5","module":"Typography","submodule":"Attributes"},{"file":"src/typography/loading_displaying.js","line":16,"description":"<p>Loads an opentype font file (.otf, .ttf) from a file or a URL,\nand returns a PFont Object. This method is asynchronous,\nmeaning it may not finish before the next line in your sketch\nis executed.</p>\n<p>The path to the font should be relative to the HTML file\nthat links in your sketch. Loading fonts from a URL or other\nremote location may be blocked due to your browser's built-in\nsecurity.</p>\n","itemtype":"method","name":"loadFont","params":[{"name":"path","description":"<p>name of the file or url to load</p>\n","type":"String"},{"name":"callback","description":"<p>function to be executed after\n                                   <a href=\"#/p5/loadFont\">loadFont()</a> completes</p>\n","type":"Function","optional":true},{"name":"onError","description":"<p>function to be executed if\n                                   an error occurs</p>\n","type":"Function","optional":true}],"return":{"description":"<a href=\"#/p5.Font\">p5.Font</a> object","type":"p5.Font"},"example":["\n\nCalling loadFont() inside <a href=\"#/p5/preload\">preload()</a> guarantees\nthat the load operation will have completed before <a href=\"#/p5/setup\">setup()</a>\nand <a href=\"#/p5/draw\">draw()</a> are called.\n\n<div><code>\nlet myFont;\nfunction preload() {\n  myFont = loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  fill('#ED225D');\n  textFont(myFont);\n  textSize(36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nOutside of <a href=\"#/p5/preload\">preload()</a>, you may supply a\ncallback function to handle the object:\n\n<div><code>\nfunction setup() {\n  loadFont('assets/inconsolata.otf', drawText);\n}\n\nfunction drawText(font) {\n  fill('#ED225D');\n  textFont(font, 36);\n  text('p5*js', 10, 50);\n}\n</code></div>\n\nYou can also use the font filename string (without the file extension) to\nstyle other HTML elements.\n\n<div><code>\nfunction preload() {\n  loadFont('assets/inconsolata.otf');\n}\n\nfunction setup() {\n  let myDiv = createDiv('hello there');\n  myDiv.style('font-family', 'Inconsolata');\n}\n</code></div>"],"alt":"p5*js in p5's theme dark pink\np5*js in p5's theme dark pink","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":140,"description":"<p>Draws text to the screen. Displays the information specified in the first\nparameter on the screen in the position specified by the additional\nparameters. A default font will be used unless a font is set with the\n<a href=\"#/p5/textFont\">textFont()</a> function and a default size will be\nused unless a font is set with <a href=\"#/p5/textSize\">textSize()</a>. Change\nthe color of the text with the <a href=\"#/p5/fill\">fill()</a> function. Change\nthe outline of the text with the <a href=\"#/p5/stroke\">stroke()</a> and\n<a href=\"#/p5/strokeWeight\">strokeWeight()</a> functions.</p>\n<p>The text displays in relation to the <a href=\"#/p5/textAlign\">textAlign()</a>\nfunction, which gives the option to draw to the left, right, and center of the\ncoordinates.</p>\n<p>The x2 and y2 parameters define a rectangular area to display within and\nmay only be used with string data. When these parameters are specified,\nthey are interpreted based on the current <a href=\"#/p5/rectMode\">rectMode()</a>\nsetting. Text that does not fit completely within the rectangle specified will\nnot be drawn to the screen. If x2 and y2 are not specified, the baseline\nalignment is the default, which means that the text will be drawn upwards\nfrom x and y.</p>\n<p><b>WEBGL</b>: Only opentype/truetype fonts are supported. You must load a font\nusing the <a href=\"#/p5/loadFont\">loadFont()</a> method (see the example above).\n<a href=\"#/p5/stroke\">stroke()</a> currently has no effect in webgl mode.\nLearn more about working with text in webgl mode on the\n<a href=\"https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5#text\">wiki</a>.</p>\n","itemtype":"method","name":"text","params":[{"name":"str","description":"<p>the alphanumeric\n                                            symbols to be displayed</p>\n","type":"String|Object|Array|Number|Boolean"},{"name":"x","description":"<p>x-coordinate of text</p>\n","type":"Number"},{"name":"y","description":"<p>y-coordinate of text</p>\n","type":"Number"},{"name":"x2","description":"<p>by default, the width of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true},{"name":"y2","description":"<p>by default, the height of the text box,\n                    see <a href=\"#/p5/rectMode\">rectMode()</a> for more info</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\ntextSize(32);\ntext('word', 10, 30);\nfill(0, 102, 153);\ntext('word', 10, 60);\nfill(0, 102, 153, 51);\ntext('word', 10, 90);\n</code>\n</div>\n<div>\n<code>\nlet s = 'The quick brown fox jumped over the lazy dog.';\nfill(50);\ntext(s, 10, 10, 70, 80); // Text wraps within text box\n</code>\n</div>\n\n<div modernizr='webgl'>\n<code>\nlet inconsolata;\nfunction preload() {\n  inconsolata = loadFont('assets/inconsolata.otf');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textFont(inconsolata);\n  textSize(width / 3);\n  textAlign(CENTER, CENTER);\n}\nfunction draw() {\n  background(0);\n  let time = millis();\n  rotateX(time / 1000);\n  rotateZ(time / 1234);\n  text('p5.js', 0, 0);\n}\n</code>\n</div>"],"alt":"'word' displayed 3 times going from black, blue to translucent blue\nThe text 'The quick brown fox jumped over the lazy dog' displayed.\nThe text 'p5.js' spinning in 3d","class":"p5","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/loading_displaying.js","line":231,"description":"<p>Sets the current font that will be drawn with the <a href=\"#/p5/text\">text()</a> function.\nIf textFont() is called without any argument, it will return the current font if one has\nbeen set already. If not, it will return the name of the default font as a string.\nIf textFont() is called with a font to use, it will return the p5 object.</p>\n<p><b>WEBGL</b>: Only fonts loaded via <a href=\"#/p5/loadFont\">loadFont()</a> are supported.</p>\n","itemtype":"method","name":"textFont","return":{"description":"the current font / p5 Object","type":"Object"},"example":["\n<div>\n<code>\nfill(0);\ntextSize(12);\ntextFont('Georgia');\ntext('Georgia', 12, 30);\ntextFont('Helvetica');\ntext('Helvetica', 12, 60);\n</code>\n</div>\n<div>\n<code>\nlet fontRegular, fontItalic, fontBold;\nfunction preload() {\n  fontRegular = loadFont('assets/Regular.otf');\n  fontItalic = loadFont('assets/Italic.ttf');\n  fontBold = loadFont('assets/Bold.ttf');\n}\nfunction setup() {\n  background(210);\n  fill(0)\n   .strokeWeight(0)\n   .textSize(10);\n  textFont(fontRegular);\n  text('Font Style Normal', 10, 30);\n  textFont(fontItalic);\n  text('Font Style Italic', 10, 50);\n  textFont(fontBold);\n  text('Font Style Bold', 10, 70);\n}\n</code>\n</div>"],"alt":"word 'Georgia' displayed in font Georgia and 'Helvetica' in font Helvetica\nwords Font Style Normal displayed normally, Italic in italic and bold in bold","class":"p5","module":"Typography","submodule":"Loading & Displaying","overloads":[{"line":231,"params":[],"return":{"description":"the current font / p5 Object","type":"Object"}},{"line":280,"params":[{"name":"font","description":"<p>a font loaded via <a href=\"#/p5/loadFont\">loadFont()</a>,\nor a String representing a <a href=\"https://mzl.la/2dOw8WD\">web safe font</a>\n(a font that is generally available across all systems)</p>\n","type":"Object|String"},{"name":"size","description":"<p>the font size to use</p>\n","type":"Number","optional":true}],"chainable":1}]},{"file":"src/typography/p5.Font.js","line":24,"description":"<p>Underlying opentype font implementation</p>\n","itemtype":"property","name":"font","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":31,"description":"<p>Returns a tight bounding box for the given text string using this\nfont</p>\n","itemtype":"method","name":"textBounds","params":[{"name":"line","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional) Default is 12.</p>\n","type":"Number","optional":true},{"name":"options","description":"<p>opentype options (optional)\n                           opentype fonts contains alignment and baseline options.\n                           Default is 'LEFT' and 'alphabetic'</p>\n","type":"Object","optional":true}],"return":{"description":"a rectangle object with properties: x, y, w, h","type":"Object"},"example":["\n<div>\n<code>\nlet font;\nlet textString = 'Lorem ipsum dolor sit amet.';\nfunction preload() {\n  font = loadFont('./assets/Regular.otf');\n}\nfunction setup() {\n  background(210);\n\n  let bbox = font.textBounds(textString, 10, 30, 12);\n  fill(255);\n  stroke(0);\n  rect(bbox.x, bbox.y, bbox.w, bbox.h);\n  fill(0);\n  noStroke();\n\n  textFont(font);\n  textSize(12);\n  text(textString, 10, 30);\n}\n</code>\n</div>"],"alt":"words Lorem ipsum dol go off canvas and contained by white bounding box","class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/typography/p5.Font.js","line":175,"description":"<p>Computes an array of points following the path for specified text</p>\n","itemtype":"method","name":"textToPoints","params":[{"name":"txt","description":"<p>a line of text</p>\n","type":"String"},{"name":"x","description":"<p>x-position</p>\n","type":"Number"},{"name":"y","description":"<p>y-position</p>\n","type":"Number"},{"name":"fontSize","description":"<p>font size to use (optional)</p>\n","type":"Number"},{"name":"options","description":"<p>an (optional) object that can contain:</p>\n<p><br>sampleFactor - the ratio of path-length to number of samples\n(default=.1); higher values yield more points and are therefore\nmore precise</p>\n<p><br>simplifyThreshold - if set to a non-zero value, collinear points will be\nbe removed from the polygon; the value represents the threshold angle to use\nwhen determining whether two edges are collinear</p>\n","type":"Object","optional":true}],"return":{"description":"an array of points, each with x, y, alpha (the path angle)","type":"Array"},"example":["\n<div>\n<code>\nlet font;\nfunction preload() {\n  font = loadFont('assets/inconsolata.otf');\n}\n\nlet points;\nlet bounds;\nfunction setup() {\n  createCanvas(100, 100);\n  stroke(0);\n  fill(255, 104, 204);\n\n  points = font.textToPoints('p5', 0, 0, 10, {\n    sampleFactor: 5,\n    simplifyThreshold: 0\n  });\n  bounds = font.textBounds(' p5 ', 0, 0, 10);\n}\n\nfunction draw() {\n  background(255);\n  beginShape();\n  translate(-bounds.x * width / bounds.w, -bounds.y * height / bounds.h);\n  for (let i = 0; i < points.length; i++) {\n    let p = points[i];\n    vertex(\n      p.x * width / bounds.w +\n        sin(20 * p.y / bounds.h + millis() / 1000) * width / 30,\n      p.y * height / bounds.h\n    );\n  }\n  endShape(CLOSE);\n}\n</code>\n</div>"],"class":"p5.Font","module":"Typography","submodule":"Loading & Displaying"},{"file":"src/utilities/array_functions.js","line":10,"description":"<p>Adds a value to the end of an array. Extends the length of\nthe array by one. Maps to Array.push().</p>\n","itemtype":"method","name":"append","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push\">array.push(value)</a> instead.","params":[{"name":"array","description":"<p>Array to append</p>\n","type":"Array"},{"name":"value","description":"<p>to be added to the Array</p>\n","type":"Any"}],"return":{"description":"the array that was appended to","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['Mango', 'Apple', 'Papaya'];\n  print(myArray); // ['Mango', 'Apple', 'Papaya']\n\n  append(myArray, 'Peach');\n  print(myArray); // ['Mango', 'Apple', 'Papaya', 'Peach']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":35,"description":"<p>Copies an array (or part of an array) to another array. The src array is\ncopied to the dst array, beginning at the position specified by\nsrcPosition and into the position specified by dstPosition. The number of\nelements to copy is determined by length. Note that copying values\noverwrites existing values in the destination array. To append values\ninstead of overwriting them, use <a href=\"#/p5/concat\">concat()</a>.</p>\n<p>The simplified version with only two arguments, arrayCopy(src, dst),\ncopies an entire array to another of the same size. It is equivalent to\narrayCopy(src, 0, dst, 0, src.length).</p>\n<p>Using this function is far more efficient for copying array data than\niterating through a for() loop and copying each element individually.</p>\n","itemtype":"method","name":"arrayCopy","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin\">arr1.copyWithin(arr2)</a> instead.","example":["\n<div class='norender'><code>\nlet src = ['A', 'B', 'C'];\nlet dst = [1, 2, 3];\nlet srcPosition = 1;\nlet dstPosition = 0;\nlet length = 2;\n\nprint(src); // ['A', 'B', 'C']\nprint(dst); // [ 1 ,  2 ,  3 ]\n\narrayCopy(src, srcPosition, dst, dstPosition, length);\nprint(dst); // ['B', 'C', 3]\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions","overloads":[{"line":35,"params":[{"name":"src","description":"<p>the source Array</p>\n","type":"Array"},{"name":"srcPosition","description":"<p>starting position in the source Array</p>\n","type":"Integer"},{"name":"dst","description":"<p>the destination Array</p>\n","type":"Array"},{"name":"dstPosition","description":"<p>starting position in the destination Array</p>\n","type":"Integer"},{"name":"length","description":"<p>number of Array elements to be copied</p>\n","type":"Integer"}]},{"line":73,"params":[{"name":"src","description":"","type":"Array"},{"name":"dst","description":"","type":"Array"},{"name":"length","description":"","type":"Integer","optional":true}]}]},{"file":"src/utilities/array_functions.js","line":112,"description":"<p>Concatenates two arrays, maps to Array.concat(). Does not modify the\ninput arrays.</p>\n","itemtype":"method","name":"concat","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat\">arr1.concat(arr2)</a> instead.","params":[{"name":"a","description":"<p>first Array to concatenate</p>\n","type":"Array"},{"name":"b","description":"<p>second Array to concatenate</p>\n","type":"Array"}],"return":{"description":"concatenated array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let arr1 = ['A', 'B', 'C'];\n  let arr2 = [1, 2, 3];\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1,2,3]\n\n  let arr3 = concat(arr1, arr2);\n\n  print(arr1); // ['A','B','C']\n  print(arr2); // [1, 2, 3]\n  print(arr3); // ['A','B','C', 1, 2, 3]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":141,"description":"<p>Reverses the order of an array, maps to Array.reverse()</p>\n","itemtype":"method","name":"reverse","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse\">array.reverse()</a> instead.","params":[{"name":"list","description":"<p>Array to reverse</p>\n","type":"Array"}],"return":{"description":"the reversed list","type":"Array"},"example":["\n<div class='norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A','B','C']\n\n  reverse(myArray);\n  print(myArray); // ['C','B','A']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":161,"description":"<p>Decreases an array by one element and returns the shortened array,\nmaps to Array.pop().</p>\n","itemtype":"method","name":"shorten","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/pop\">array.pop()</a> instead.","params":[{"name":"list","description":"<p>Array to shorten</p>\n","type":"Array"}],"return":{"description":"shortened Array","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = ['A', 'B', 'C'];\n  print(myArray); // ['A', 'B', 'C']\n  let newArray = shorten(myArray);\n  print(myArray); // ['A','B','C']\n  print(newArray); // ['A','B']\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":185,"description":"<p>Randomizes the order of the elements of an array. Implements\n<a href='http://Bost.Ocks.org/mike/shuffle/' target=_blank>\nFisher-Yates Shuffle Algorithm</a>.</p>\n","itemtype":"method","name":"shuffle","params":[{"name":"array","description":"<p>Array to shuffle</p>\n","type":"Array"},{"name":"bool","description":"<p>modify passed array</p>\n","type":"Boolean","optional":true}],"return":{"description":"shuffled Array","type":"Array"},"example":["\n<div><code>\nfunction setup() {\n  let regularArr = ['ABC', 'def', createVector(), TAU, Math.E];\n  print(regularArr);\n  shuffle(regularArr, true); // force modifications to passed array\n  print(regularArr);\n\n  // By default shuffle() returns a shuffled cloned array:\n  let newArr = shuffle(regularArr);\n  print(regularArr);\n  print(newArr);\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":227,"description":"<p>Sorts an array of numbers from smallest to largest, or puts an array of\nwords in alphabetical order. The original array is not modified; a\nre-ordered array is returned. The count parameter states the number of\nelements to sort. For example, if there are 12 elements in an array and\ncount is set to 5, only the first 5 elements in the array will be sorted.</p>\n","itemtype":"method","name":"sort","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\">array.sort()</a> instead.","params":[{"name":"list","description":"<p>Array to sort</p>\n","type":"Array"},{"name":"count","description":"<p>number of elements to sort, starting from 0</p>\n","type":"Integer","optional":true}],"return":{"description":"the sorted list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let words = ['banana', 'apple', 'pear', 'lime'];\n  print(words); // ['banana', 'apple', 'pear', 'lime']\n  let count = 4; // length of array\n\n  words = sort(words, count);\n  print(words); // ['apple', 'banana', 'lime', 'pear']\n}\n</code></div>\n<div class = 'norender'><code>\nfunction setup() {\n  let numbers = [2, 6, 1, 5, 14, 9, 8, 12];\n  print(numbers); // [2, 6, 1, 5, 14, 9, 8, 12]\n  let count = 5; // Less than the length of the array\n\n  numbers = sort(numbers, count);\n  print(numbers); // [1,2,5,6,14,9,8,12]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":273,"description":"<p>Inserts a value or an array of values into an existing array. The first\nparameter specifies the initial array to be modified, and the second\nparameter defines the data to be inserted. The third parameter is an index\nvalue which specifies the array position from which to insert data.\n(Remember that array index numbering starts at zero, so the first position\nis 0, the second position is 1, and so on.)</p>\n","itemtype":"method","name":"splice","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice\">array.splice()</a> instead.","params":[{"name":"list","description":"<p>Array to splice into</p>\n","type":"Array"},{"name":"value","description":"<p>value to be spliced in</p>\n","type":"Any"},{"name":"position","description":"<p>in the array from which to insert data</p>\n","type":"Integer"}],"return":{"description":"the list","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [0, 1, 2, 3, 4];\n  let insArray = ['A', 'B', 'C'];\n  print(myArray); // [0, 1, 2, 3, 4]\n  print(insArray); // ['A','B','C']\n\n  splice(myArray, insArray, 3);\n  print(myArray); // [0,1,2,'A','B','C',3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/array_functions.js","line":308,"description":"<p>Extracts an array of elements from an existing array. The list parameter\ndefines the array from which the elements will be copied, and the start\nand count parameters specify which elements to extract. If no count is\ngiven, elements will be extracted from the start to the end of the array.\nWhen specifying the start, remember that the first array element is 0.\nThis function does not change the source array.</p>\n","itemtype":"method","name":"subset","deprecated":true,"deprecationMessage":"Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice\">array.slice()</a> instead.","params":[{"name":"list","description":"<p>Array to extract from</p>\n","type":"Array"},{"name":"start","description":"<p>position to begin</p>\n","type":"Integer"},{"name":"count","description":"<p>number of values to extract</p>\n","type":"Integer","optional":true}],"return":{"description":"Array of extracted elements","type":"Array"},"example":["\n<div class = 'norender'><code>\nfunction setup() {\n  let myArray = [1, 2, 3, 4, 5];\n  print(myArray); // [1, 2, 3, 4, 5]\n\n  let sub1 = subset(myArray, 0, 3);\n  let sub2 = subset(myArray, 2, 2);\n  print(sub1); // [1,2,3]\n  print(sub2); // [3,4]\n}\n</code></div>"],"class":"p5","module":"Data","submodule":"Array Functions"},{"file":"src/utilities/conversion.js","line":10,"description":"<p>Converts a string to its floating point representation. The contents of a\nstring must resemble a number, or NaN (not a number) will be returned.\nFor example, float(\"1234.56\") evaluates to 1234.56, but float(\"giraffe\")\nwill return NaN.</p>\n<p>When an array of values is passed in, then an array of floats of the same\nlength is returned.</p>\n","itemtype":"method","name":"float","params":[{"name":"str","description":"<p>float string to parse</p>\n","type":"String"}],"return":{"description":"floating point representation of string","type":"Number"},"example":["\n<div><code>\nlet str = '20';\nlet diameter = float(str);\nellipse(width / 2, height / 2, diameter, diameter);\n</code></div>\n<div class='norender'><code>\nprint(float('10.31')); // 10.31\nprint(float('Infinity')); // Infinity\nprint(float('-Infinity')); // -Infinity\n</code></div>"],"alt":"20 by 20 white ellipse in the center of the canvas","class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":44,"description":"<p>Converts a boolean, string, or float to its integer representation.\nWhen an array of values is passed in, then an int array of the same length\nis returned.</p>\n","itemtype":"method","name":"int","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(int('10')); // 10\nprint(int(10.31)); // 10\nprint(int(-10)); // -10\nprint(int(true)); // 1\nprint(int(false)); // 0\nprint(int([false, true, '10.3', 9.8])); // [0, 1, 10, 9]\nprint(int(Infinity)); // Infinity\nprint(int('-Infinity')); // -Infinity\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":44,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"},{"name":"radix","description":"<p>the radix to convert to (default: 10)</p>\n","type":"Integer","optional":true}],"return":{"description":"integer representation of value","type":"Number"}},{"line":66,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"},{"name":"radix","description":"","type":"Integer","optional":true}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":88,"description":"<p>Converts a boolean, string or number to its string representation.\nWhen an array of values is passed in, then an array of strings of the same\nlength is returned.</p>\n","itemtype":"method","name":"str","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(str('10')); // \"10\"\nprint(str(10.31)); // \"10.31\"\nprint(str(-10)); // \"-10\"\nprint(str(true)); // \"true\"\nprint(str(false)); // \"false\"\nprint(str([true, '10.3', 9.8])); // [ \"true\", \"10.3\", \"9.8\" ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":114,"description":"<p>Converts a number or string to its boolean representation.\nFor a number, any non-zero value (positive or negative) evaluates to true,\nwhile zero evaluates to false. For a string, the value \"true\" evaluates to\ntrue, while any other value evaluates to false. When an array of number or\nstring values is passed in, then a array of booleans of the same length is\nreturned.</p>\n","itemtype":"method","name":"boolean","params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number|Array"}],"return":{"description":"boolean representation of value","type":"Boolean"},"example":["\n<div class='norender'><code>\nprint(boolean(0)); // false\nprint(boolean(1)); // true\nprint(boolean('true')); // true\nprint(boolean('abcd')); // false\nprint(boolean([0, 12, 'true'])); // [false, true, true]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion"},{"file":"src/utilities/conversion.js","line":146,"description":"<p>Converts a number, string representation of a number, or boolean to its byte\nrepresentation. A byte can be only a whole number between -128 and 127, so\nwhen a value outside of this range is converted, it wraps around to the\ncorresponding byte representation. When an array of number, string or boolean\nvalues is passed in, then an array of bytes the same length is returned.</p>\n","itemtype":"method","name":"byte","return":{"description":"byte representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(byte(127)); // 127\nprint(byte(128)); // -128\nprint(byte(23.4)); // 23\nprint(byte('23.4')); // 23\nprint(byte('hello')); // NaN\nprint(byte(true)); // 1\nprint(byte([0, 255, '100'])); // [0, -1, 100]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":146,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Boolean|Number"}],"return":{"description":"byte representation of value","type":"Number"}},{"line":168,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of byte representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":182,"description":"<p>Converts a number or string to its corresponding single-character\nstring representation. If a string parameter is provided, it is first\nparsed as an integer and then translated into a single-character string.\nWhen an array of number or string values is passed in, then an array of\nsingle-character strings of the same length is returned.</p>\n","itemtype":"method","name":"char","return":{"description":"string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(char(65)); // \"A\"\nprint(char('65')); // \"A\"\nprint(char([65, 66, 67])); // [ \"A\", \"B\", \"C\" ]\nprint(join(char([65, 66, 67]), '')); // \"ABC\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":182,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String|Number"}],"return":{"description":"string representation of value","type":"String"}},{"line":201,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"array of string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":216,"description":"<p>Converts a single-character string to its corresponding integer\nrepresentation. When an array of single-character string values is passed\nin, then an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unchar","return":{"description":"integer representation of value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unchar('A')); // 65\nprint(unchar(['A', 'B', 'C'])); // [ 65, 66, 67 ]\nprint(unchar(split('ABC', ''))); // [ 65, 66, 67 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":216,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of value","type":"Number"}},{"line":232,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representation of values","type":"Number[]"}}]},{"file":"src/utilities/conversion.js","line":245,"description":"<p>Converts a number to a string in its equivalent hexadecimal notation. If a\nsecond parameter is passed, it is used to set the number of characters to\ngenerate in the hexadecimal notation. When an array is passed in, an\narray of strings in hexadecimal notation of the same length is returned.</p>\n","itemtype":"method","name":"hex","return":{"description":"hexadecimal string representation of value","type":"String"},"example":["\n<div class='norender'><code>\nprint(hex(255)); // \"000000FF\"\nprint(hex(255, 6)); // \"0000FF\"\nprint(hex([0, 127, 255], 6)); // [ \"000000\", \"00007F\", \"0000FF\" ]\nprint(Infinity); // \"FFFFFFFF\"\nprint(-Infinity); // \"00000000\"\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":245,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"Number"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of value","type":"String"}},{"line":265,"params":[{"name":"ns","description":"<p>array of values to parse</p>\n","type":"Number[]"},{"name":"digits","description":"","type":"Number","optional":true}],"return":{"description":"hexadecimal string representation of values","type":"String[]"}}]},{"file":"src/utilities/conversion.js","line":295,"description":"<p>Converts a string representation of a hexadecimal number to its equivalent\ninteger value. When an array of strings in hexadecimal notation is passed\nin, an array of integers of the same length is returned.</p>\n","itemtype":"method","name":"unhex","return":{"description":"integer representation of hexadecimal value","type":"Number"},"example":["\n<div class='norender'><code>\nprint(unhex('A')); // 10\nprint(unhex('FF')); // 255\nprint(unhex(['FF', 'AA', '00'])); // [ 255, 170, 0 ]\n</code></div>"],"class":"p5","module":"Data","submodule":"Conversion","overloads":[{"line":295,"params":[{"name":"n","description":"<p>value to parse</p>\n","type":"String"}],"return":{"description":"integer representation of hexadecimal value","type":"Number"}},{"line":311,"params":[{"name":"ns","description":"<p>values to parse</p>\n","type":"Array"}],"return":{"description":"integer representations of hexadecimal value","type":"Number[]"}}]},{"file":"src/utilities/string_functions.js","line":15,"description":"<p>Combines an array of Strings into one String, each separated by the\ncharacter(s) used for the separator parameter. To join arrays of ints or\nfloats, it's necessary to first convert them to Strings using <a href=\"#/p5/nf\">nf()</a> or\nnfs().</p>\n","itemtype":"method","name":"join","params":[{"name":"list","description":"<p>array of Strings to be joined</p>\n","type":"Array"},{"name":"separator","description":"<p>String to be placed between each item</p>\n","type":"String"}],"return":{"description":"joined String","type":"String"},"example":["\n<div>\n<code>\nlet array = ['Hello', 'world!'];\nlet separator = ' ';\nlet message = join(array, separator);\ntext(message, 5, 50);\n</code>\n</div>"],"alt":"\"hello world!\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":43,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return matching groups (elements found inside parentheses) as a\nString array. If there are no matches, a null value will be returned.\nIf no groups are specified in the regular expression, but the sequence\nmatches, an array of length 1 (with the matched text as the first element\nof the array) will be returned.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, an array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nElement [0] of a regular expression match returns the entire matching\nstring, and the match groups start at element [1] (the first group is [1],\nthe second [2], and so on).</p>\n","itemtype":"method","name":"match","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"Array of Strings found","type":"String[]"},"example":["\n<div>\n<code>\nlet string = 'Hello p5js*!';\nlet regexp = 'p5js\\\\*';\nlet m = match(string, regexp);\ntext(m, 5, 50);\n</code>\n</div>"],"alt":"\"p5js*\" displayed middle left of canvas.","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":83,"description":"<p>This function is used to apply a regular expression to a piece of text,\nand return a list of matching groups (elements found inside parentheses)\nas a two-dimensional String array. If there are no matches, a null value\nwill be returned. If no groups are specified in the regular expression,\nbut the sequence matches, a two dimensional array is still returned, but\nthe second dimension is only of length one.</p>\n<p>To use the function, first check to see if the result is null. If the\nresult is null, then the sequence did not match at all. If the sequence\ndid match, a 2D array is returned.</p>\n<p>If there are groups (specified by sets of parentheses) in the regular\nexpression, then the contents of each will be returned in the array.\nAssuming a loop with counter variable i, element [i][0] of a regular\nexpression match returns the entire matching string, and the match groups\nstart at element [i][1] (the first group is [i][1], the second [i][2],\nand so on).</p>\n","itemtype":"method","name":"matchAll","params":[{"name":"str","description":"<p>the String to be searched</p>\n","type":"String"},{"name":"regexp","description":"<p>the regexp to be used for matching</p>\n","type":"String"}],"return":{"description":"2d Array of Strings found","type":"String[]"},"example":["\n<div class=\"norender\">\n<code>\nlet string = 'Hello p5js*! Hello world!';\nlet regexp = 'Hello';\nmatchAll(string, regexp);\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":130,"description":"<p>Utility function for formatting numbers into strings. There are two\nversions: one for formatting floats, and one for formatting ints.</p>\n<p>The values for the digits, left, and right parameters should always\nbe positive integers.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nf","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  text(nf(num1, 4, 2), 10, 30);\n  text(nf(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" middle top, -1321.00\" middle bottom canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":130,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"left","description":"<p>number of digits to the left of the\n                               decimal point</p>\n","type":"Integer|String","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":176,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer|String","optional":true},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":237,"description":"<p>Utility function for formatting numbers into strings and placing\nappropriate commas to mark units of 1000. There are two versions: one\nfor formatting ints, and one for formatting an array of ints. The value\nfor the right parameter should always be a positive integer.</p>\n","itemtype":"method","name":"nfc","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num = 11253106.115;\n  let numArr = [1, 1, 2];\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfc(num, 4), 10, 30);\n  text(nfc(numArr, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"11,253,106.115\" top middle and \"1.00,1.00,2.00\" displayed bottom mid","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":237,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number|String"},{"name":"right","description":"<p>number of digits to the right of the\n                                 decimal point</p>\n","type":"Integer|String","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":275,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"right","description":"","type":"Integer|String","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":311,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs a \"+\" in front of positive numbers and a \"-\" in front of negative\nnumbers. There are two versions: one for formatting floats, and one for\nformatting ints. The values for left, and right parameters\nshould always be positive integers.</p>\n","itemtype":"method","name":"nfp","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 11253106.115;\n  let num2 = -11253106.115;\n\n  noStroke();\n  fill(0);\n  textSize(12);\n\n  // Draw formatted numbers\n  text(nfp(num1, 4, 2), 10, 30);\n  text(nfp(num2, 4, 2), 10, 80);\n\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"+11253106.11\" top middle and \"-11253106.11\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":311,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":352,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Number[]"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":373,"description":"<p>Utility function for formatting numbers into strings. Similar to <a href=\"#/p5/nf\">nf()</a> but\nputs an additional \"_\" (space) in front of positive numbers just in case to align it with negative\nnumbers which includes \"-\" (minus) sign.</p>\n<p>The main usecase of nfs() can be seen when one wants to align the digits (place values) of a non-negative\nnumber with some negative number (See the example to get a clear picture).\nThere are two versions: one for formatting float, and one for formatting int.</p>\n<p>The values for the digits, left, and right parameters should always be positive integers.</p>\n<p>(IMP): The result on the canvas basically the expected alignment can vary based on the typeface you are using.</p>\n<p>(NOTE): Be cautious when using left and right parameters as it prepends numbers of 0's if the parameter\nif greater than the current length of the number.</p>\n<p>For example if number is 123.2 and left parameter passed is 4 which is greater than length of 123\n(integer part) i.e 3 than result will be 0123.2. Same case for right parameter i.e. if right is 3 than\nthe result will be 123.200.</p>\n","itemtype":"method","name":"nfs","return":{"description":"formatted String","type":"String"},"example":["\n<div>\n<code>\nfunction setup() {\n  background(200);\n  let num1 = 321;\n  let num2 = -1321;\n\n  noStroke();\n  fill(0);\n  textSize(16);\n\n  // nfs() aligns num1 (positive number) with num2 (negative number) by\n  // adding a blank space in front of the num1 (positive number)\n  // [left = 4] in num1 add one 0 in front, to align the digits with num2\n  // [right = 2] in num1 and num2 adds two 0's after both numbers\n  // To see the differences check the example of nf() too.\n  text(nfs(num1, 4, 2), 10, 30);\n  text(nfs(num2, 4, 2), 10, 80);\n  // Draw dividing line\n  stroke(120);\n  line(0, 50, width, 50);\n}\n</code>\n</div>"],"alt":"\"0321.00\" top middle and \"-1321.00\" displayed bottom middle","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":373,"params":[{"name":"num","description":"<p>the Number to format</p>\n","type":"Number"},{"name":"left","description":"<p>number of digits to the left of the decimal\n                               point</p>\n","type":"Integer","optional":true},{"name":"right","description":"<p>number of digits to the right of the\n                               decimal point</p>\n","type":"Integer","optional":true}],"return":{"description":"formatted String","type":"String"}},{"line":430,"params":[{"name":"nums","description":"<p>the Numbers to format</p>\n","type":"Array"},{"name":"left","description":"","type":"Integer","optional":true},{"name":"right","description":"","type":"Integer","optional":true}],"return":{"description":"formatted Strings","type":"String[]"}}]},{"file":"src/utilities/string_functions.js","line":451,"description":"<p>The <a href=\"#/p5/split\">split()</a> function maps to String.split(), it breaks a String into\npieces using a character or string as the delimiter. The delim parameter\nspecifies the character or characters that mark the boundaries between\neach piece. A String[] array is returned that contains each of the pieces.</p>\n<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function works in a similar fashion, except that it\nsplits using a range of characters instead of a specific character or\nsequence.</p>\n","itemtype":"method","name":"split","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>the String used to separate the data</p>\n","type":"String"}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div>\n<code>\nlet names = 'Pat,Xio,Alex';\nlet splitString = split(names, ',');\ntext(splitString[0], 5, 30);\ntext(splitString[1], 5, 50);\ntext(splitString[2], 5, 70);\n</code>\n</div>"],"alt":"\"pat\" top left, \"Xio\" mid left and \"Alex\" displayed bottom left","class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":484,"description":"<p>The <a href=\"#/p5/splitTokens\">splitTokens()</a> function splits a String at one or many character\ndelimiters or \"tokens.\" The delim parameter specifies the character or\ncharacters to be used as a boundary.</p>\n<p>If no delim characters are specified, any whitespace character is used to\nsplit. Whitespace characters include tab (\\t), line feed (\\n), carriage\nreturn (\\r), form feed (\\f), and space.</p>\n","itemtype":"method","name":"splitTokens","params":[{"name":"value","description":"<p>the String to be split</p>\n","type":"String"},{"name":"delim","description":"<p>list of individual Strings that will be used as\n                         separators</p>\n","type":"String","optional":true}],"return":{"description":"Array of Strings","type":"String[]"},"example":["\n<div class = \"norender\">\n<code>\nfunction setup() {\n  let myStr = 'Mango, Banana, Lime';\n  let myStrArr = splitTokens(myStr, ',');\n\n  print(myStrArr); // prints : [\"Mango\",\" Banana\",\" Lime\"]\n}\n</code>\n</div>"],"class":"p5","module":"Data","submodule":"String Functions"},{"file":"src/utilities/string_functions.js","line":537,"description":"<p>Removes whitespace characters from the beginning and end of a String. In\naddition to standard whitespace characters such as space, carriage return,\nand tab, this function also removes the Unicode \"nbsp\" character.</p>\n","itemtype":"method","name":"trim","return":{"description":"a trimmed String","type":"String"},"example":["\n<div>\n<code>\nlet string = trim('  No new lines\\n   ');\ntext(string + ' here', 2, 50);\n</code>\n</div>"],"alt":"\"No new lines here\" displayed center canvas","class":"p5","module":"Data","submodule":"String Functions","overloads":[{"line":537,"params":[{"name":"str","description":"<p>a String to be trimmed</p>\n","type":"String"}],"return":{"description":"a trimmed String","type":"String"}},{"line":557,"params":[{"name":"strs","description":"<p>an Array of Strings to be trimmed</p>\n","type":"Array"}],"return":{"description":"an Array of trimmed Strings","type":"String[]"}}]},{"file":"src/utilities/time_date.js","line":10,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/day\">day()</a> function\nreturns the current day as a value from 1 - 31.</p>\n","itemtype":"method","name":"day","return":{"description":"the current day","type":"Integer"},"example":["\n<div>\n<code>\nlet d = day();\ntext('Current day: \\n' + d, 5, 50);\n</code>\n</div>"],"alt":"Current day is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":31,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/hour\">hour()</a> function\nreturns the current hour as a value from 0 - 23.</p>\n","itemtype":"method","name":"hour","return":{"description":"the current hour","type":"Integer"},"example":["\n<div>\n<code>\nlet h = hour();\ntext('Current hour:\\n' + h, 5, 50);\n</code>\n</div>"],"alt":"Current hour is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":52,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/minute\">minute()</a> function\nreturns the current minute as a value from 0 - 59.</p>\n","itemtype":"method","name":"minute","return":{"description":"the current minute","type":"Integer"},"example":["\n<div>\n<code>\nlet m = minute();\ntext('Current minute: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current minute is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":73,"description":"<p>Returns the number of milliseconds (thousandths of a second) since\nstarting the sketch (when <code>setup()</code> is called). This information is often\nused for timing events and animation sequences.</p>\n","itemtype":"method","name":"millis","return":{"description":"the number of milliseconds since starting the sketch","type":"Number"},"example":["\n<div>\n<code>\nlet millisecond = millis();\ntext('Milliseconds \\nrunning: \\n' + millisecond, 5, 40);\n</code>\n</div>"],"alt":"number of milliseconds since sketch has started displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":100,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/month\">month()</a> function\nreturns the current month as a value from 1 - 12.</p>\n","itemtype":"method","name":"month","return":{"description":"the current month","type":"Integer"},"example":["\n<div>\n<code>\nlet m = month();\ntext('Current month: \\n' + m, 5, 50);\n</code>\n</div>"],"alt":"Current month is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":122,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/second\">second()</a> function\nreturns the current second as a value from 0 - 59.</p>\n","itemtype":"method","name":"second","return":{"description":"the current second","type":"Integer"},"example":["\n<div>\n<code>\nlet s = second();\ntext('Current second: \\n' + s, 5, 50);\n</code>\n</div>"],"alt":"Current second is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/utilities/time_date.js","line":143,"description":"<p>p5.js communicates with the clock on your computer. The <a href=\"#/p5/year\">year()</a> function\nreturns the current year as an integer (2014, 2015, 2016, etc).</p>\n","itemtype":"method","name":"year","return":{"description":"the current year","type":"Integer"},"example":["\n<div>\n<code>\nlet y = year();\ntext('Current year: \\n' + y, 5, 50);\n</code>\n</div>"],"alt":"Current year is displayed","class":"p5","module":"IO","submodule":"Time & Date"},{"file":"src/webgl/3d_primitives.js","line":13,"description":"<p>Draw a plane with given a width and height</p>\n","itemtype":"method","name":"plane","params":[{"name":"width","description":"<p>width of the plane</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the plane</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                            subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                            subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a plane\n// with width 50 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  plane(50, 50);\n}\n</code>\n</div>"],"alt":"Nothing displayed on canvas\nRotating interior view of a box with sides that change color.\n3d red and green gradient.\nRotating interior view of a cylinder with sides that change color.\nRotating view of a cylinder with sides that change color.\n3d red and green gradient.\nrotating view of a multi-colored cylinder with concave sides.","class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":97,"description":"<p>Draw a box with given width, height and depth</p>\n","itemtype":"method","name":"box","params":[{"name":"width","description":"<p>width of the box</p>\n","type":"Number","optional":true},{"name":"Height","description":"<p>height of the box</p>\n","type":"Number","optional":true},{"name":"depth","description":"<p>depth of the box</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>Optional number of triangle\n                           subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>Optional number of triangle\n                           subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning box\n// with width, height and depth of 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  box(50);\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":215,"description":"<p>Draw a sphere with given radius.</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a sphere. More subdivisions make the sphere seem\nsmoother. The recommended maximum values are both 24. Using a value greater\nthan 24 may cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"sphere","params":[{"name":"radius","description":"<p>radius of circle</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>optional number of subdivisions in x-dimension</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>optional number of subdivisions in y-dimension</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a sphere with radius 40\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  sphere(40);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailX;\n// slide to see how detailX works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\nlet detailY;\n// slide to see how detailY works\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  sphere(40, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":419,"description":"<p>Draw a cylinder with given radius and height</p>\n<p>DetailX and detailY determines the number of subdivisions in the x-dimension\nand the y-dimension of a cylinder. More subdivisions make the cylinder seem smoother.\nThe recommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cylinder","params":[{"name":"radius","description":"<p>radius of the surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cylinder</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of subdivisions in x-dimension;\n                              default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of subdivisions in y-dimension;\n                              default is 1</p>\n","type":"Integer","optional":true},{"name":"bottomCap","description":"<p>whether to draw the bottom of the cylinder</p>\n","type":"Boolean","optional":true},{"name":"topCap","description":"<p>whether to draw the top of the cylinder</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cylinder\n// with radius 20 and height 50\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cylinder(20, 50);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, detailX.value(), 1);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(1, 16, 1);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  cylinder(20, 75, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":554,"description":"<p>Draw a cone with given radius and height</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the cone seem smoother. The\nrecommended maximum value for detailX is 24. Using a value greater than 24\nmay cause a warning or slow down the browser.</p>\n","itemtype":"method","name":"cone","params":[{"name":"radius","description":"<p>radius of the bottom surface</p>\n","type":"Number","optional":true},{"name":"height","description":"<p>height of the cone</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                            the more segments the smoother geometry\n                            default is 1</p>\n","type":"Integer","optional":true},{"name":"cap","description":"<p>whether to draw the base of the cone</p>\n","type":"Boolean","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning cone\n// with radius 40 and height 70\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateZ(frameCount * 0.01);\n  cone(40, 70);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailx works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 16, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, detailX.value(), 16);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  cone(30, 65, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":669,"description":"<p>Draw an ellipsoid with given radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a cone. More subdivisions make the ellipsoid appear to be smoother.\nAvoid detail number above 150, it may crash the browser.</p>\n","itemtype":"method","name":"ellipsoid","params":[{"name":"radiusx","description":"<p>x-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusy","description":"<p>y-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"radiusz","description":"<p>z-radius of ellipsoid</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 24. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments,\n                                   the more segments the smoother geometry\n                                   default is 16. Avoid detail number above\n                                   150, it may crash the browser.</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw an ellipsoid\n// with radius 30, 40 and 40.\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  ellipsoid(30, 40, 40);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(2, 24, 12);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 94);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, detailX.value(), 8);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(2, 24, 6);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 105, 9);\n  rotateY(millis() / 1000);\n  ellipsoid(30, 40, 40, 12, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/3d_primitives.js","line":804,"description":"<p>Draw a torus with given radius and tube radius</p>\n<p>DetailX and detailY determine the number of subdivisions in the x-dimension and\nthe y-dimension of a torus. More subdivisions make the torus appear to be smoother.\nThe default and maximum values for detailX and detailY are 24 and 16, respectively.\nSetting them to relatively small values like 4 and 6 allows you to create new\nshapes other than a torus.</p>\n","itemtype":"method","name":"torus","params":[{"name":"radius","description":"<p>radius of the whole ring</p>\n","type":"Number","optional":true},{"name":"tubeRadius","description":"<p>radius of the tube</p>\n","type":"Number","optional":true},{"name":"detailX","description":"<p>number of segments in x-dimension,\n                               the more segments the smoother geometry\n                               default is 24</p>\n","type":"Integer","optional":true},{"name":"detailY","description":"<p>number of segments in y-dimension,\n                               the more segments the smoother geometry\n                               default is 16</p>\n","type":"Integer","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n// draw a spinning torus\n// with ring radius 30 and tube radius 15\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  torus(30, 15);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailX works\nlet detailX;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailX = createSlider(3, 24, 3);\n  detailX.position(10, height + 5);\n  detailX.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, detailX.value(), 12);\n}\n</code>\n</div>","\n<div>\n<code>\n// slide to see how detailY works\nlet detailY;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  detailY = createSlider(3, 16, 3);\n  detailY.position(10, height + 5);\n  detailY.style('width', '80px');\n}\n\nfunction draw() {\n  background(205, 102, 94);\n  rotateY(millis() / 1000);\n  torus(30, 15, 16, detailY.value());\n}\n</code>\n</div>"],"class":"p5","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/interaction.js","line":11,"description":"<p>Allows movement around a 3D sketch using a mouse or trackpad.  Left-clicking\nand dragging will rotate the camera position about the center of the sketch,\nright-clicking and dragging will pan the camera position without rotation,\nand using the mouse wheel (scrolling) will move the camera closer or further\nfrom the center of the sketch. This function can be called with parameters\ndictating sensitivity to mouse movement along the X and Y axes.  Calling\nthis function without parameters is equivalent to calling orbitControl(1,1).\nTo reverse direction of movement in either axis, enter a negative number\nfor sensitivity.</p>\n","itemtype":"method","name":"orbitControl","params":[{"name":"sensitivityX","description":"<p>sensitivity to mouse movement along X axis</p>\n","type":"Number","optional":true},{"name":"sensitivityY","description":"<p>sensitivity to mouse movement along Y axis</p>\n","type":"Number","optional":true},{"name":"sensitivityZ","description":"<p>sensitivity to scroll movement along Z axis</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  rotateY(0.5);\n  box(30, 50);\n}\n</code>\n</div>"],"alt":"Camera orbits around a box when mouse is hold-clicked & then moved.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/interaction.js","line":145,"description":"<p>debugMode() helps visualize 3D space by adding a grid to indicate where the\n‘ground’ is in a sketch and an axes icon which indicates the +X, +Y, and +Z\ndirections. This function can be called without parameters to create a\ndefault grid and axes icon, or it can be called according to the examples\nabove to customize the size and position of the grid and/or axes icon.  The\ngrid is drawn using the most recently set stroke color and weight.  To\nspecify these parameters, add a call to stroke() and strokeWeight()\njust before the end of the draw() loop.</p>\n<p>By default, the grid will run through the origin (0,0,0) of the sketch\nalong the XZ plane\nand the axes icon will be offset from the origin.  Both the grid and axes\nicon will be sized according to the current canvas size.  Note that because the\ngrid runs parallel to the default camera view, it is often helpful to use\ndebugMode along with orbitControl to allow full view of the grid.</p>\n","itemtype":"method","name":"debugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(AXES);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(GRID, 100, 10, 0, 0, 0);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n}\n</code>\n</div>","\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode(100, 10, 0, 0, 0, 20, 0, -40, 0);\n}\n\nfunction draw() {\n  noStroke();\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // set the stroke color and weight for the grid!\n  stroke(255, 0, 150);\n  strokeWeight(0.8);\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z.","class":"p5","module":"3D","submodule":"Interaction","overloads":[{"line":145,"params":[]},{"line":278,"params":[{"name":"mode","description":"<p>either GRID or AXES</p>\n","type":"Constant"}]},{"line":283,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"gridSize","description":"<p>size of one side of the grid</p>\n","type":"Number","optional":true},{"name":"gridDivisions","description":"<p>number of divisions in the grid</p>\n","type":"Number","optional":true},{"name":"xOff","description":"<p>X axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"yOff","description":"<p>Y axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true},{"name":"zOff","description":"<p>Z axis offset from origin (0,0,0)</p>\n","type":"Number","optional":true}]},{"line":293,"params":[{"name":"mode","description":"","type":"Constant"},{"name":"axesSize","description":"<p>size of axes icon</p>\n","type":"Number","optional":true},{"name":"xOff","description":"","type":"Number","optional":true},{"name":"yOff","description":"","type":"Number","optional":true},{"name":"zOff","description":"","type":"Number","optional":true}]},{"line":302,"params":[{"name":"gridSize","description":"","type":"Number","optional":true},{"name":"gridDivisions","description":"","type":"Number","optional":true},{"name":"gridXOff","description":"","type":"Number","optional":true},{"name":"gridYOff","description":"","type":"Number","optional":true},{"name":"gridZOff","description":"","type":"Number","optional":true},{"name":"axesSize","description":"","type":"Number","optional":true},{"name":"axesXOff","description":"","type":"Number","optional":true},{"name":"axesYOff","description":"","type":"Number","optional":true},{"name":"axesZOff","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/interaction.js","line":353,"description":"<p>Turns off debugMode() in a 3D sketch.</p>\n","itemtype":"method","name":"noDebugMode","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  camera(0, -30, 100, 0, 0, 0, 0, 1, 0);\n  normalMaterial();\n  debugMode();\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  box(15, 30);\n  // Press the spacebar to turn debugMode off!\n  if (keyIsDown(32)) {\n    noDebugMode();\n  }\n}\n</code>\n</div>"],"alt":"a 3D box is centered on a grid in a 3D sketch. an icon\nindicates the direction of each axis: a red line points +X,\na green line +Y, and a blue line +Z. the grid and icon disappear when the\nspacebar is pressed.","class":"p5","module":"3D","submodule":"Interaction"},{"file":"src/webgl/light.js","line":11,"description":"<p>Creates an ambient light with a color. Ambient light is light that comes from everywhere on the canvas.\nIt has no particular source.</p>\n","itemtype":"method","name":"ambientLight","chainable":1,"example":["\n<div>\n<code>\ncreateCanvas(100, 100, WEBGL);\nambientLight(0);\nambientMaterial(250);\nsphere(40);\n</code>\n</div>\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(51);\n  ambientLight(100); // white light\n  ambientMaterial(255, 102, 94); // magenta material\n  box(30);\n}\n</code>\n</div>"],"alt":"evenly distributed light across a sphere\nevenly distributed light across a rotating sphere","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":11,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"<p>the alpha value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":51,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":57,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":64,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":71,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":92,"description":"<p>Set's the color of the specular highlight when using a specular material and\nspecular light.</p>\n<p>This method can be combined with specularMaterial() and shininess()\nfunctions to set specular highlights. The default color is white, ie\n(255, 255, 255), which is used if this method is not called before\nspecularMaterial(). If this method is called without specularMaterial(),\nThere will be no effect.</p>\n<p>Note: specularColor is equivalent to the processing function\n<a href=\"https://processing.org/reference/lightSpecular_.html\">lightSpecular</a>.</p>\n","itemtype":"method","name":"specularColor","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n  shininess(20);\n  ambientLight(50);\n  specularColor(255, 0, 0);\n  pointLight(255, 0, 0, 0, -50, 50);\n  specularColor(0, 255, 0);\n  pointLight(0, 255, 0, 0, 50, 50);\n  specularMaterial(255);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"different specular light sources from top and bottom of canvas","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":92,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"}],"chainable":1},{"line":139,"params":[{"name":"value","description":"<p>a color string</p>\n","type":"String"}],"chainable":1},{"line":145,"params":[{"name":"gray","description":"<p>a gray value</p>\n","type":"Number"}],"chainable":1},{"line":151,"params":[{"name":"values","description":"<p>an array containing the red,green,blue &\n                                and alpha components of the color</p>\n","type":"Number[]"}],"chainable":1},{"line":158,"params":[{"name":"color","description":"<p>the ambient light color</p>\n","type":"p5.Color"}],"chainable":1}]},{"file":"src/webgl/light.js","line":177,"description":"<p>Creates a directional light with a color and a direction</p>\n<p>A maximum of 5 directionalLight can be active at one time</p>\n","itemtype":"method","name":"directionalLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light direction\n  let dirX = (mouseX / width - 0.5) * 2;\n  let dirY = (mouseY / height - 0.5) * 2;\n  directionalLight(250, 250, 250, -dirX, -dirY, -1);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"light source on canvas changeable with mouse position","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":177,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"position","description":"<p>the direction of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":210,"params":[{"name":"color","description":"<p>color Array, CSS color string,\n                                            or <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"<p>x axis direction</p>\n","type":"Number"},{"name":"y","description":"<p>y axis direction</p>\n","type":"Number"},{"name":"z","description":"<p>z axis direction</p>\n","type":"Number"}],"chainable":1},{"line":220,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1},{"line":227,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1}]},{"file":"src/webgl/light.js","line":280,"description":"<p>Creates a point light with a color and a light position</p>\n<p>A maximum of 5 pointLight can be active at one time</p>\n","itemtype":"method","name":"pointLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  pointLight(250, 250, 250, locX, locY, 50);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"spot light on canvas changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":280,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"}],"chainable":1},{"line":322,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"}],"chainable":1},{"line":331,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"}],"chainable":1},{"line":341,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"}],"chainable":1}]},{"file":"src/webgl/light.js","line":387,"description":"<p>Sets the default ambient and directional light. The defaults are <a href=\"#/p5/ambientLight\">ambientLight(128, 128, 128)</a> and <a href=\"#/p5/directionalLight\">directionalLight(128, 128, 128, 0, 0, -1)</a>. Lights need to be included in the <a href=\"#/p5/draw\">draw()</a> to remain persistent in a looping program. Placing them in the <a href=\"#/p5/setup\">setup()</a> of a looping program will cause them to only have an effect the first time through the loop.</p>\n","itemtype":"method","name":"lights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  lights();\n  rotateX(millis() / 1000);\n  rotateY(millis() / 1000);\n  rotateZ(millis() / 1000);\n  box();\n}\n</code>\n</div>"],"alt":"the light is partially ambient and partially directional","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":425,"description":"<p>Sets the falloff rates for point lights. It affects only the elements which are created after it in the code.\nThe default value is lightFalloff(1.0, 0.0, 0.0), and the parameters are used to calculate the falloff with the following equation:</p>\n<p>d = distance from light position to vertex position</p>\n<p>falloff = 1 / (CONSTANT + d * LINEAR + ( d * d ) * QUADRATIC)</p>\n","itemtype":"method","name":"lightFalloff","params":[{"name":"constant","description":"<p>constant value for determining falloff</p>\n","type":"Number"},{"name":"linear","description":"<p>linear value for determining falloff</p>\n","type":"Number"},{"name":"quadratic","description":"<p>quadratic value for determining falloff</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\nfunction draw() {\n  ortho();\n  background(0);\n\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  locX /= 2; // half scale\n\n  lightFalloff(1, 0, 0);\n  push();\n  translate(-25, 0, 0);\n  pointLight(250, 250, 250, locX - 25, locY, 50);\n  sphere(20);\n  pop();\n\n  lightFalloff(0.97, 0.03, 0);\n  push();\n  translate(25, 0, 0);\n  pointLight(250, 250, 250, locX + 25, locY, 50);\n  sphere(20);\n  pop();\n}\n</code>\n</div>"],"alt":"Two spheres with different falloff values show different intensity of light","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/light.js","line":519,"description":"<p>Creates a spotlight with a given color, position, direction of light,\nangle and concentration. Here, angle refers to the opening or aperture\nof the cone of the spotlight, and concentration is used to focus the\nlight towards the center. Both angle and concentration are optional, but if\nyou want to provide concentration, you will also have to specify the angle.</p>\n<p>A maximum of 5 spotLight can be active at one time</p>\n","itemtype":"method","name":"spotLight","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  //move your mouse to change light position\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  // to set the light position,\n  // think of the world's coordinate as:\n  // -width/2,-height/2 -------- width/2,-height/2\n  //                |            |\n  //                |     0,0    |\n  //                |            |\n  // -width/2,height/2--------width/2,height/2\n  ambientLight(50);\n  spotLight(0, 250, 0, locX, locY, 100, 0, 0, -1, Math.PI / 16);\n  noStroke();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Spot light on a sphere which changes position with mouse","class":"p5","module":"3D","submodule":"Lights","overloads":[{"line":519,"params":[{"name":"v1","description":"<p>red or hue value (depending on the current\ncolor mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number"},{"name":"x","description":"<p>x axis position</p>\n","type":"Number"},{"name":"y","description":"<p>y axis position</p>\n","type":"Number"},{"name":"z","description":"<p>z axis position</p>\n","type":"Number"},{"name":"rx","description":"<p>x axis direction of light</p>\n","type":"Number"},{"name":"ry","description":"<p>y axis direction of light</p>\n","type":"Number"},{"name":"rz","description":"<p>z axis direction of light</p>\n","type":"Number"},{"name":"angle","description":"<p>optional parameter for angle. Defaults to PI/3</p>\n","type":"Number","optional":true},{"name":"conc","description":"<p>optional parameter for concentration. Defaults to 100</p>\n","type":"Number","optional":true}],"chainable":1},{"line":571,"params":[{"name":"color","description":"<p>color Array, CSS color string,\nor <a href=\"#/p5.Color\">p5.Color</a> value</p>\n","type":"Number[]|String|p5.Color"},{"name":"position","description":"<p>the position of the light</p>\n","type":"p5.Vector"},{"name":"direction","description":"<p>the direction of the light</p>\n","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":580,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":590,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":600,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":610,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"direction","description":"","type":"p5.Vector"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":622,"params":[{"name":"v1","description":"","type":"Number"},{"name":"v2","description":"","type":"Number"},{"name":"v3","description":"","type":"Number"},{"name":"position","description":"","type":"p5.Vector"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]},{"line":634,"params":[{"name":"color","description":"","type":"Number[]|String|p5.Color"},{"name":"x","description":"","type":"Number"},{"name":"y","description":"","type":"Number"},{"name":"z","description":"","type":"Number"},{"name":"rx","description":"","type":"Number"},{"name":"ry","description":"","type":"Number"},{"name":"rz","description":"","type":"Number"},{"name":"angle","description":"","type":"Number","optional":true},{"name":"conc","description":"","type":"Number","optional":true}]}]},{"file":"src/webgl/light.js","line":859,"description":"<p>This function will remove all the lights from the sketch for the\nsubsequent materials rendered. It affects all the subsequent methods.\nCalls to lighting methods made after noLights() will re-enable lights\nin the sketch.</p>\n","itemtype":"method","name":"noLights","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(200);\n  noStroke();\n\n  ambientLight(255, 0, 0);\n  translate(-30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  noLights();\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n\n  ambientLight(0, 255, 0);\n  translate(30, 0, 0);\n  ambientMaterial(255);\n  sphere(13);\n}\n</code>\n</div>"],"alt":"Three white spheres. Each appears as a different\ncolor due to lighting.","class":"p5","module":"3D","submodule":"Lights"},{"file":"src/webgl/loading.js","line":12,"description":"<p>Load a 3d model from an OBJ or STL file.</p>\n<p><a href=\"#/p5/loadModel\">loadModel()</a> should be placed inside of <a href=\"#/p5/preload\">preload()</a>.\nThis allows the model to load fully before the rest of your code is run.</p>\n<p>One of the limitations of the OBJ and STL format is that it doesn't have a built-in\nsense of scale. This means that models exported from different programs might\nbe very different sizes. If your model isn't displaying, try calling\n<a href=\"#/p5/loadModel\">loadModel()</a> with the normalized parameter set to true. This will resize the\nmodel to a scale appropriate for p5. You can also make additional changes to\nthe final size of your model with the <a href=\"#/p5/scale\">scale()</a> function.</p>\n<p>Also, the support for colored STL files is not present. STL files with color will be\nrendered without color properties.</p>\n","itemtype":"method","name":"loadModel","return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"},"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>","\n<div>\n<code>\n//draw a spinning teapot\nlet teapot;\n\nfunction preload() {\n  // Load model with normalise parameter set to true\n  teapot = loadModel('assets/teapot.obj', true);\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  scale(0.4); // Scaled to make model fit into canvas\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  normalMaterial(); // For effect\n  model(teapot);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d teapot with red, green and blue gradient.","class":"p5","module":"Shape","submodule":"3D Models","overloads":[{"line":12,"params":[{"name":"path","description":"<p>Path of the model to be loaded</p>\n","type":"String"},{"name":"normalize","description":"<p>If true, scale the model to a\n                                     standardized size when loading</p>\n","type":"Boolean"},{"name":"successCallback","description":"<p>Function to be called\n                                    once the model is loaded. Will be passed\n                                    the 3D model object.</p>\n","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"<p>called with event error if\n                                        the model fails to load.</p>\n","type":"Function(Event)","optional":true},{"name":"fileType","description":"<p>The file extension of the model\n                                     (<code>.stl</code>, <code>.obj</code>).</p>\n","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}},{"line":96,"params":[{"name":"path","description":"","type":"String"},{"name":"successCallback","description":"","type":"function(p5.Geometry)","optional":true},{"name":"failureCallback","description":"","type":"Function(Event)","optional":true},{"name":"fileType","description":"","type":"String","optional":true}],"return":{"description":"the <a href=\"#/p5.Geometry\">p5.Geometry</a> object","type":"p5.Geometry"}}]},{"file":"src/webgl/loading.js","line":179,"description":"<p>Parse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:</p>\n<p>v -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5</p>\n<p>f 4 3 2 1</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":290,"description":"<p>STL files can be of two types, ASCII and Binary,</p>\n<p>We need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":317,"description":"<p>This function checks if the file is in ASCII format or in Binary format</p>\n<p>It is done by searching keyword <code>solid</code> at the start of the file.</p>\n<p>An ASCII STL data must begin with <code>solid</code> as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the <code>d</code> are known to be\nplentiful. So, check the first 5 bytes for <code>solid</code>.</p>\n<p>Several encodings, such as UTF-8, precede the text with up to 5 bytes:\n<a href=\"https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\">https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding</a>\nSearch for <code>solid</code> to start anywhere after those prefixes.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":344,"description":"<p>This function matches the <code>query</code> at the provided <code>offset</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":356,"description":"<p>This function parses the Binary STL files.\n<a href=\"https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\">https://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL</a></p>\n<p>Currently there is no support for the colors provided in STL files.</p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":444,"description":"<p>ASCII STL file starts with <code>solid 'nameOfFile'</code>\nThen contain the normal of the face, starting with <code>facet normal</code>\nNext contain a keyword indicating the start of face vertex, <code>outer loop</code>\nNext comes the three vertex, starting with <code>vertex x y z</code>\nVertices ends with <code>endloop</code>\nFace ends with <code>endfacet</code>\nNext face starts with <code>facet normal</code>\nThe end of the file is indicated by <code>endsolid</code></p>\n","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/loading.js","line":588,"description":"<p>Render a 3d model to the screen.</p>\n","itemtype":"method","name":"model","params":[{"name":"model","description":"<p>Loaded 3d model to be rendered</p>\n","type":"p5.Geometry"}],"example":["\n<div>\n<code>\n//draw a spinning octahedron\nlet octahedron;\n\nfunction preload() {\n  octahedron = loadModel('assets/octahedron.obj');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  model(octahedron);\n}\n</code>\n</div>"],"alt":"Vertically rotating 3-d octahedron.","class":"p5","module":"Shape","submodule":"3D Models"},{"file":"src/webgl/material.js","line":12,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader files.</p>\n<p>The shader files are loaded asynchronously in the\nbackground, so this method should be used in <a href=\"#/p5/preload\">preload()</a>.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"loadShader","params":[{"name":"vertFilename","description":"<p>path to file containing vertex shader\nsource code</p>\n","type":"String"},{"name":"fragFilename","description":"<p>path to file containing fragment shader\nsource code</p>\n","type":"String"},{"name":"callback","description":"<p>callback to be executed after loadShader\ncompletes. On success, the p5.Shader object is passed as the first argument.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>callback to be executed when an error\noccurs inside loadShader. On error, the error is passed as the first\nargument.</p>\n","type":"Function","optional":true}],"return":{"description":"a shader object created from the provided\nvertex and fragment shader files.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\nlet mandel;\nfunction preload() {\n  // load the shader definitions from files\n  mandel = loadShader('assets/shader.vert', 'assets/shader.frag');\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // use the shader\n  shader(mandel);\n  noStroke();\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":111,"description":"<p>Creates a new <a href=\"#/p5.Shader\">p5.Shader</a> object\nfrom the provided vertex and fragment shader code.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"createShader","params":[{"name":"vertSrc","description":"<p>source code for the vertex shader</p>\n","type":"String"},{"name":"fragSrc","description":"<p>source code for the fragment shader</p>\n","type":"String"}],"return":{"description":"a shader object created from the provided\nvertex and fragment shaders.","type":"p5.Shader"},"example":["\n<div modernizr='webgl'>\n<code>\n// the 'varying's are shared between both vertex & fragment shaders\nlet varying = 'precision highp float; varying vec2 vPos;';\n\n// the vertex shader is called for each vertex\nlet vs =\n  varying +\n  'attribute vec3 aPosition;' +\n  'void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; }';\n\n// the fragment shader is called for each pixel\nlet fs =\n  varying +\n  'uniform vec2 p;' +\n  'uniform float r;' +\n  'const int I = 500;' +\n  'void main() {' +\n  '  vec2 c = p + vPos * r, z = c;' +\n  '  float n = 0.0;' +\n  '  for (int i = I; i > 0; i --) {' +\n  '    if(z.x*z.x+z.y*z.y > 4.0) {' +\n  '      n = float(i)/float(I);' +\n  '      break;' +\n  '    }' +\n  '    z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c;' +\n  '  }' +\n  '  gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0);' +\n  '}';\n\nlet mandel;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // create and initialize the shader\n  mandel = createShader(vs, fs);\n  shader(mandel);\n  noStroke();\n\n  // 'p' is the center point of the Mandelbrot image\n  mandel.setUniform('p', [-0.74364388703, 0.13182590421]);\n}\n\nfunction draw() {\n  // 'r' is the size of the image in Mandelbrot-space\n  mandel.setUniform('r', 1.5 * exp(-6.5 * (1 + sin(millis() / 2000))));\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n</code>\n</div>"],"alt":"zooming Mandelbrot set. a colorful, infinitely detailed fractal.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":184,"description":"<p>Sets the <a href=\"#/p5.Shader\">p5.Shader</a> object to\nbe used to render subsequent shapes.</p>\n<p>Custom shaders can be created using the\n<a href=\"#/p5/createShader\">createShader()</a> and\n<a href=\"#/p5/loadShader\">loadShader()</a> functions.</p>\n<p>Use <a href=\"#/p5/resetShader\">resetShader()</a> to\nrestore the default shaders.</p>\n<p>Note, shaders can only be used in WEBGL mode.</p>\n","itemtype":"method","name":"shader","chainable":1,"params":[{"name":"s","description":"<p>the <a href=\"#/p5.Shader\">p5.Shader</a> object\nto use for rendering shapes.</p>\n","type":"p5.Shader"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle\n// the shader used by the quad shape\n// Note: for an alternative approach to the same example,\n// involving changing uniforms please refer to:\n// https://p5js.org/reference/#/p5.Shader/setUniform\n\nlet redGreen;\nlet orangeBlue;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  redGreen = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n  orangeBlue = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n\n  // initialize the colors for redGreen shader\n  shader(redGreen);\n  redGreen.setUniform('colorCenter', [1.0, 0.0, 0.0]);\n  redGreen.setUniform('colorBackground', [0.0, 1.0, 0.0]);\n\n  // initialize the colors for orangeBlue shader\n  shader(orangeBlue);\n  orangeBlue.setUniform('colorCenter', [1.0, 0.5, 0.0]);\n  orangeBlue.setUniform('colorBackground', [0.226, 0.0, 0.615]);\n\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each shader,\n  // moving orangeBlue in vertical and redGreen\n  // in horizontal direction\n  orangeBlue.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  redGreen.setUniform('offset', [sin(millis() / 2000), 1]);\n\n  if (showRedGreen === true) {\n    shader(redGreen);\n  } else {\n    shader(orangeBlue);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":282,"description":"<p>Restores the default shaders. Code that runs after resetShader()\nwill not be affected by the shader previously set by\n<a href=\"#/p5/shader\">shader()</a></p>\n","itemtype":"method","name":"resetShader","chainable":1,"example":["\n<div>\n<code>\n// This variable will hold our shader object\nlet shaderProgram;\n\n// This variable will hold our vertex shader source code\nlet vertSrc = `\n   attribute vec3 aPosition;\n   attribute vec2 aTexCoord;\n   uniform mat4 uProjectionMatrix;\n   uniform mat4 uModelViewMatrix;\n   varying vec2 vTexCoord;\n\n   void main() {\n     vTexCoord = aTexCoord;\n     vec4 position = vec4(aPosition, 1.0);\n     gl_Position = uProjectionMatrix * uModelViewMatrix * position;\n   }\n`;\n\n// This variable will hold our fragment shader source code\nlet fragSrc = `\n   precision mediump float;\n\n   varying vec2 vTexCoord;\n\n   void main() {\n     vec2 uv = vTexCoord;\n     vec3 color = vec3(uv.x, uv.y, min(uv.x + uv.y, 1.0));\n     gl_FragColor = vec4(color, 1.0);\n   }\n`;\n\nfunction setup() {\n  // Shaders require WEBGL mode to work\n  createCanvas(100, 100, WEBGL);\n\n  // Create our shader\n  shaderProgram = createShader(vertSrc, fragSrc);\n}\n\nfunction draw() {\n  // Clear the scene\n  background(200);\n\n  // Draw a box using our shader\n    // shader() sets the active shader with our shader\n    shader(shaderProgram);\n    push();\n    translate(-width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n\n  // Draw a box using the default fill shader\n    // resetShader() restores the default fill shader\n    resetShader();\n    fill(255, 0, 0);\n    push();\n    translate(width / 4, 0, 0);\n    rotateX(millis() * 0.00025);\n    rotateY(millis() * 0.0005);\n    box(width / 4);\n    pop();\n}\n</code>\n</div>"],"alt":"Two rotating cubes. The left one is painted using a custom (user-defined) shader,\nwhile the right one is painted using the default fill shader.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":368,"description":"<p>Sets the texture that will be used to render subsequent shapes.</p>\n<p>A texture is like a \"skin\" that wraps around a 3D geometry. Currently\nsupported textures are images, video, and offscreen renders.</p>\n<p>To texture a geometry created with <a href=\"#/p5/beginShape\">beginShape()</a>,\nyou will need to specify uv coordinates in <a href=\"#/p5/vertex\">vertex()</a>.</p>\n<p>Note, texture() can only be used in WEBGL mode.</p>\n<p>You can view more materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"texture","params":[{"name":"tex","description":"<p>image to use as texture</p>\n","type":"p5.Image|p5.MediaElement|p5.Graphics|p5.Texture"}],"chainable":1,"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  rotateZ(frameCount * 0.01);\n  rotateX(frameCount * 0.01);\n  rotateY(frameCount * 0.01);\n  //pass image as texture\n  texture(img);\n  box(width / 2);\n}\n</code>\n</div>","\n<div>\n<code>\nlet pg;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  pg = createGraphics(200, 200);\n  pg.textSize(75);\n}\n\nfunction draw() {\n  background(0);\n  pg.background(255);\n  pg.text('hello!', 0, 100);\n  //pass image as texture\n  texture(pg);\n  rotateX(0.5);\n  noStroke();\n  plane(50);\n}\n</code>\n</div>","\n<div>\n<code>\nlet vid;\nfunction preload() {\n  vid = createVideo('assets/fingers.mov');\n  vid.hide();\n}\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  //pass video frame as texture\n  texture(vid);\n  rect(-40, -40, 80, 80);\n}\n\nfunction mousePressed() {\n  vid.loop();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(0);\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-40, -40, 0, 0);\n  vertex(40, -40, 1, 0);\n  vertex(40, 40, 1, 1);\n  vertex(-40, 40, 0, 1);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using normalized coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":511,"description":"<p>Sets the coordinate space for texture mapping. The default mode is IMAGE\nwhich refers to the actual coordinates of the image.\nNORMAL refers to a normalized space of values ranging from 0 to 1.</p>\n<p>With IMAGE, if an image is 100×200 pixels, mapping the image onto the entire\nsize of a quad would require the points (0,0) (100, 0) (100,200) (0,200).\nThe same mapping in NORMAL is (0,0) (1,0) (1,1) (0,1).</p>\n","itemtype":"method","name":"textureMode","params":[{"name":"mode","description":"<p>either IMAGE or NORMAL</p>\n","type":"Constant"}],"example":["\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(NORMAL);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, 1, 0);\n  vertex(50, 50, 1, 1);\n  vertex(-50, 50, 0, 1);\n  endShape();\n}\n</code>\n</div>","\n<div>\n<code>\nlet img;\n\nfunction preload() {\n  img = loadImage('assets/laDefense.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  texture(img);\n  textureMode(IMAGE);\n  beginShape();\n  vertex(-50, -50, 0, 0);\n  vertex(50, -50, img.width, 0);\n  vertex(50, 50, img.width, img.height);\n  vertex(-50, 50, 0, img.height);\n  endShape();\n}\n</code>\n</div>"],"alt":"quad with a texture, mapped using image coordinates","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":587,"description":"<p>Sets the global texture wrapping mode. This controls how textures behave\nwhen their uv's go outside of the 0 to 1 range. There are three options:\nCLAMP, REPEAT, and MIRROR.</p>\n<p>CLAMP causes the pixels at the edge of the texture to extend to the bounds.\nREPEAT causes the texture to tile repeatedly until reaching the bounds.\nMIRROR works similarly to REPEAT but it flips the texture with every new tile.</p>\n<p>REPEAT & MIRROR are only available if the texture\nis a power of two size (128, 256, 512, 1024, etc.).</p>\n<p>This method will affect all textures in your sketch until a subsequent\ntextureWrap() call is made.</p>\n<p>If only one argument is provided, it will be applied to both the\nhorizontal and vertical axes.</p>\n","itemtype":"method","name":"textureWrap","params":[{"name":"wrapX","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant"},{"name":"wrapY","description":"<p>either CLAMP, REPEAT, or MIRROR</p>\n","type":"Constant","optional":true}],"example":["\n<div>\n<code>\nlet img;\nfunction preload() {\n  img = loadImage('assets/rockies128.jpg');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  textureWrap(MIRROR);\n}\n\nfunction draw() {\n  background(0);\n\n  let dX = mouseX;\n  let dY = mouseY;\n\n  let u = lerp(1.0, 2.0, dX);\n  let v = lerp(1.0, 2.0, dY);\n\n  scale(width / 2);\n\n  texture(img);\n\n  beginShape(TRIANGLES);\n  vertex(-1, -1, 0, 0, 0);\n  vertex(1, -1, 0, u, 0);\n  vertex(1, 1, 0, u, v);\n\n  vertex(1, 1, 0, u, v);\n  vertex(-1, 1, 0, 0, v);\n  vertex(-1, -1, 0, 0, 0);\n  endShape();\n}\n</code>\n</div>"],"alt":"an image of the rocky mountains repeated in mirrored tiles","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":659,"description":"<p>Normal material for geometry is a material that is not affected by light.\nIt is not reflective and is a placeholder material often used for debugging.\nSurfaces facing the X-axis, become red, those facing the Y-axis, become green and those facing the Z-axis, become blue.\nYou can view all possible materials in this\n<a href=\"https://p5js.org/examples/3d-materials.html\">example</a>.</p>\n","itemtype":"method","name":"normalMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(200);\n  normalMaterial();\n  sphere(40);\n}\n</code>\n</div>"],"alt":"Red, green and blue gradient.","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/material.js","line":697,"description":"<p>Ambient material for geometry with a given color. Ambient material defines the color the object reflects under any lighting.\nFor example, if the ambient material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"ambientMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(200);\n  ambientMaterial(70, 130, 230);\n  sphere(40);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is both red and blue (magenta),\n// so object only reflects it's red and blue components\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(100); // white light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>\n<div>\n<code>\n// ambientLight is green. Since object does not contain\n// green, it does not reflect any light\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(70);\n  ambientLight(0, 255, 0); // green light\n  ambientMaterial(255, 0, 255); // pink material\n  box(30);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas\nbox reflecting only red and blue light\nbox reflecting no light","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":697,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true}],"chainable":1},{"line":757,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":777,"description":"<p>Sets the emissive color of the material used for geometry drawn to\nthe screen. This is a misnomer in the sense that the material does not\nactually emit light that effects surrounding polygons. Instead,\nit gives the appearance that the object is glowing. An emissive material\nwill display at full strength even if there is no light for it to reflect.</p>\n","itemtype":"method","name":"emissiveMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  ambientLight(0);\n  emissiveMaterial(130, 230, 0);\n  sphere(40);\n}\n</code>\n</div>"],"alt":"radiating light source from top right of canvas","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":777,"params":[{"name":"v1","description":"<p>gray value, red or hue value\n                        (depending on the current color mode),</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value</p>\n","type":"Number","optional":true},{"name":"v3","description":"<p>blue or brightness value</p>\n","type":"Number","optional":true},{"name":"a","description":"<p>opacity</p>\n","type":"Number","optional":true}],"chainable":1},{"line":809,"params":[{"name":"color","description":"<p>color, color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":829,"description":"<p>Specular material for geometry with a given color. Specular material is a shiny reflective material.\nLike ambient material it also defines the color the object reflects under ambient lighting.\nFor example, if the specular material of an object is pure red, but the ambient lighting only contains green, the object will not reflect any light.\nFor all other types of light like point and directional light, a specular material will reflect the color of the light source to the viewer.\nHere's an <a href=\"https://p5js.org/examples/3d-materials.html\">example containing all possible materials</a>.</p>\n","itemtype":"method","name":"specularMaterial","chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n}\n\nfunction draw() {\n  background(0);\n\n  ambientLight(60);\n\n  // add point light to showcase specular material\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  pointLight(255, 255, 255, locX, locY, 50);\n\n  specularMaterial(250);\n  shininess(50);\n  torus(30, 10, 64, 64);\n}\n</code>\n</div>"],"alt":"torus with specular material","class":"p5","module":"3D","submodule":"Material","overloads":[{"line":829,"params":[{"name":"gray","description":"<p>number specifying value between white and black.</p>\n","type":"Number"},{"name":"alpha","description":"<p>alpha value relative to current color range\n                                (default is 0-255)</p>\n","type":"Number","optional":true}],"chainable":1},{"line":870,"params":[{"name":"v1","description":"<p>red or hue value relative to\n                                the current color range</p>\n","type":"Number"},{"name":"v2","description":"<p>green or saturation value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"v3","description":"<p>blue or brightness value\n                                relative to the current color range</p>\n","type":"Number"},{"name":"alpha","description":"","type":"Number","optional":true}],"chainable":1},{"line":882,"params":[{"name":"color","description":"<p>color Array, or CSS color string</p>\n","type":"Number[]|String|p5.Color"}],"chainable":1}]},{"file":"src/webgl/material.js","line":902,"description":"<p>Sets the amount of gloss in the surface of shapes.\nUsed in combination with specularMaterial() in setting\nthe material properties of shapes. The default and minimum value is 1.</p>\n","itemtype":"method","name":"shininess","params":[{"name":"shine","description":"<p>Degree of Shininess.\n                      Defaults to 1.</p>\n","type":"Number"}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(0);\n  noStroke();\n  let locX = mouseX - width / 2;\n  let locY = mouseY - height / 2;\n  ambientLight(60, 60, 60);\n  pointLight(255, 255, 255, locX, locY, 50);\n  specularMaterial(250);\n  translate(-25, 0, 0);\n  shininess(1);\n  sphere(20);\n  translate(50, 0, 0);\n  shininess(20);\n  sphere(20);\n}\n</code>\n</div>"],"alt":"Shininess on Camera changes position with mouse","class":"p5","module":"3D","submodule":"Material"},{"file":"src/webgl/p5.Camera.js","line":13,"description":"<p>Sets the position of the current camera in a 3D sketch.\nParameters for this function define the camera's position,\nthe center of the sketch (where the camera is pointing),\nand an up direction (the orientation of the camera).</p>\n<p>This function simulates the movements of the camera, allowing objects to be\nviewed from various angles. Remember, it does not move the objects themselves\nbut the camera instead. For example when the centerX value is positive,\nand the camera is rotating to the right side of the sketch,\nthe object will seem like it's moving to the left.</p>\n<p>See this <a href = \"https://www.openprocessing.org/sketch/740258\">example</a>\nto view the position of your camera.</p>\n<p>If no parameters are given, the following default is used:\ncamera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, 1, 0)</p>\n","itemtype":"method","name":"camera","is_constructor":1,"params":[{"name":"x","description":"<p>camera position value on x axis</p>\n","type":"Number","optional":true},{"name":"y","description":"<p>camera position value on y axis</p>\n","type":"Number","optional":true},{"name":"z","description":"<p>camera position value on z axis</p>\n","type":"Number","optional":true},{"name":"centerX","description":"<p>x coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerY","description":"<p>y coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"centerZ","description":"<p>z coordinate representing center of the sketch</p>\n","type":"Number","optional":true},{"name":"upX","description":"<p>x component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upY","description":"<p>y component of direction 'up' from camera</p>\n","type":"Number","optional":true},{"name":"upZ","description":"<p>z component of direction 'up' from camera</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\nfunction draw() {\n  background(204);\n  //move the camera away from the plane by a sin wave\n  camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n//move slider to see changes!\n//sliders control the first 6 parameters of camera()\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  //create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"White square repeatedly grows to fill canvas and then shrinks.\nAn interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":115,"description":"<p>Sets a perspective projection for the current camera in a 3D sketch.\nThis projection represents depth through foreshortening: objects\nthat are close to the camera appear their actual size while those\nthat are further away from the camera appear smaller.</p>\n<p>The parameters to this function define the viewing frustum\n(the truncated pyramid within which objects are seen by the camera) through\nvertical field of view, aspect ratio (usually width/height), and near and far\nclipping planes.</p>\n<p>If no parameters are given, the following default is used:\nperspective(PI/3, width/height, eyeZ/10, eyeZ*10),\nwhere eyeZ is equal to ((height/2) / tan(PI/6)).</p>\n","itemtype":"method","name":"perspective","params":[{"name":"fovy","description":"<p>camera frustum vertical field of view,\n                          from bottom to top of view, in <a href=\"#/p5/angleMode\">angleMode</a> units</p>\n","type":"Number","optional":true},{"name":"aspect","description":"<p>camera frustum aspect ratio</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>frustum near plane length</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>frustum far plane length</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  perspective(PI / 3.0, width / height, 0.1, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":176,"description":"<p>Sets an orthographic projection for the current camera in a 3D sketch\nand defines a box-shaped viewing frustum within which objects are seen.\nIn this projection, all objects with the same dimension appear the same\nsize, regardless of whether they are near or far from the camera.</p>\n<p>The parameters to this function specify the viewing frustum where\nleft and right are the minimum and maximum x values, top and bottom are\nthe minimum and maximum y values, and near and far are the minimum and\nmaximum z values.</p>\n<p>If no parameters are given, the following default is used:\northo(-width/2, width/2, -height/2, height/2).</p>\n","itemtype":"method","name":"ortho","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\n//drag the mouse to look around!\n//there's no vanishing point\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":236,"description":"<p>Sets the frustum of the current camera as defined by\nthe parameters.</p>\n<p>A frustum is a geometric form: a pyramid with its top\ncut off. With the viewer's eye at the imaginary top of\nthe pyramid, the six planes of the frustum act as clipping\nplanes when rendering a 3D view. Thus, any form inside the\nclipping planes is visible; anything outside\nthose planes is not visible.</p>\n<p>Setting the frustum changes the perspective of the scene being rendered.\nThis can be achieved more simply in many cases by using\n<a href=\"https://p5js.org/reference/#/p5/perspective\">perspective()</a>.</p>\n<p>If no parameters are given, the following default is used:\nfrustum(-width/2, width/2, -height/2, height/2, 0, max(width, height)).</p>\n","itemtype":"method","name":"frustum","params":[{"name":"left","description":"<p>camera frustum left plane</p>\n","type":"Number","optional":true},{"name":"right","description":"<p>camera frustum right plane</p>\n","type":"Number","optional":true},{"name":"bottom","description":"<p>camera frustum bottom plane</p>\n","type":"Number","optional":true},{"name":"top","description":"<p>camera frustum top plane</p>\n","type":"Number","optional":true},{"name":"near","description":"<p>camera frustum near plane</p>\n","type":"Number","optional":true},{"name":"far","description":"<p>camera frustum far plane</p>\n","type":"Number","optional":true}],"chainable":1,"example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":303,"description":"<p>Creates a new <a href=\"#/p5.Camera\">p5.Camera</a> object and sets it\nas the current (active) camera.</p>\n<p>The new camera is initialized with a default position\n(see <a href=\"#/p5.Camera/camera\">camera()</a>)\nand a default perspective projection\n(see <a href=\"#/p5.Camera/perspective\">perspective()</a>).\nIts properties can be controlled with the <a href=\"#/p5.Camera\">p5.Camera</a>\nmethods.</p>\n<p>Note: Every 3D sketch starts with a default camera initialized.\nThis camera can be controlled with the global methods\n<a href=\"#/p5/camera\">camera()</a>,\n<a href=\"#/p5/perspective\">perspective()</a>, <a href=\"#/p5/ortho\">ortho()</a>,\nand <a href=\"#/p5/frustum\">frustum()</a> if it is the only camera\nin the scene.</p>\n","itemtype":"method","name":"createCamera","return":{"description":"The newly created camera object.","type":"p5.Camera"},"example":["\n<div><code>\n// Creates a camera object and animates it around a box.\nlet camera;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  camera = createCamera();\n}\n\nfunction draw() {\n  camera.lookAt(0, 0, 0);\n  camera.setPosition(sin(frameCount / 60) * 200, 0, 100);\n  box(20);\n}\n</code></div>"],"alt":"An example that creates a camera and moves it around the box.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":444,"description":"<p>camera position value on x axis</p>\n","itemtype":"property","name":"eyeX","type":"Number","readonly":"","example":["\n\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeX = ' + cam.eyeX);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":472,"description":"<p>camera position value on y axis</p>\n","itemtype":"property","name":"eyeY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeY = ' + cam.eyeY);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":499,"description":"<p>camera position value on z axis</p>\n","itemtype":"property","name":"eyeZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(0);\n  cam = createCamera();\n  div = createDiv();\n  div.position(0, 0);\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n  div.html('eyeZ = ' + cam.eyeZ);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":526,"description":"<p>x coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(1, 0, 0);\n  div = createDiv('centerX = ' + cam.centerX);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":554,"description":"<p>y coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 1, 0);\n  div = createDiv('centerY = ' + cam.centerY);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":582,"description":"<p>z coordinate representing center of the sketch</p>\n","itemtype":"property","name":"centerZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  cam.lookAt(0, 0, 1);\n  div = createDiv('centerZ = ' + cam.centerZ);\n  div.position(0, 0);\n  div.style('color', 'white');\n}\n\nfunction draw() {\n  orbitControl();\n  box(10);\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":610,"description":"<p>x component of direction 'up' from camera</p>\n","itemtype":"property","name":"upX","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upX = ' + cam.upX);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":633,"description":"<p>y component of direction 'up' from camera</p>\n","itemtype":"property","name":"upY","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upY = ' + cam.upY);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":656,"description":"<p>z component of direction 'up' from camera</p>\n","itemtype":"property","name":"upZ","type":"Number","readonly":"","example":["\n<div class='norender'><code>\nlet cam, div;\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  background(255);\n  cam = createCamera();\n  div = createDiv('upZ = ' + cam.upZ);\n  div.position(0, 0);\n  div.style('color', 'blue');\n  div.style('font-size', '18px');\n}\n</code></div>"],"alt":"An example showing the use of camera object properties","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":683,"description":"<p>Sets a perspective projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/perspective\">perspective()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"perspective","example":["\n<div>\n<code>\n// drag the mouse to look around!\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it a perspective projection\n  cam.perspective(PI / 3.0, width / height, 0.1, 500);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(-0.3);\n  rotateY(-0.2);\n  translate(0, 0, -50);\n\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 95);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 95);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two colored 3D boxes move back and forth, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":801,"description":"<p>Sets an orthographic projection.\nAccepts the same parameters as the global\n<a href=\"#/p5/ortho\">ortho()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"ortho","example":["\n<div>\n<code>\n// drag the mouse to look around!\n// there's no vanishing point\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // give it an orthographic projection\n  cam.ortho(-width / 2, width / 2, height / 2, -height / 2, 0, 500);\n}\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateX(0.2);\n  rotateY(-0.2);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 65);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 65);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":897,"description":"<p>Sets the camera's frustum.\nAccepts the same parameters as the global\n<a href=\"#/p5/frustum\">frustum()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"frustum","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  x = createCanvas(100, 100, WEBGL);\n  setAttributes('antialias', true);\n  // create a camera\n  cam = createCamera();\n  // set its frustum\n  cam.frustum(-0.1, 0.1, -0.1, 0.1, 0.1, 200);\n}\n\nfunction draw() {\n  background(200);\n  orbitControl();\n  normalMaterial();\n\n  rotateY(-0.2);\n  rotateX(-0.3);\n  push();\n  translate(-15, 0, sin(frameCount / 30) * 25);\n  box(30);\n  pop();\n  push();\n  translate(15, 0, sin(frameCount / 30 + PI) * 25);\n  box(30);\n  pop();\n}\n</code>\n</div>"],"alt":"two 3D boxes move back and forth along same plane, rotating as mouse is dragged.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1040,"description":"<p>Panning rotates the camera view to the left and right.</p>\n","itemtype":"method","name":"pan","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial pan angle\n  cam.pan(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.pan(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view pans left and right across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1098,"description":"<p>Tilting rotates the camera view up and down.</p>\n","itemtype":"method","name":"tilt","params":[{"name":"angle","description":"<p>amount to rotate camera in current\n<a href=\"#/p5/angleMode\">angleMode</a> units.\nGreater than 0 values rotate counterclockwise (to the left).</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\nlet delta = 0.01;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n  // set initial tilt\n  cam.tilt(-0.8);\n}\n\nfunction draw() {\n  background(200);\n\n  // pan camera according to angle 'delta'\n  cam.tilt(delta);\n\n  // every 160 frames, switch direction\n  if (frameCount % 160 === 0) {\n    delta *= -1;\n  }\n\n  rotateY(frameCount * 0.01);\n  translate(0, -100, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n  translate(0, 35, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view tilts up and down across a series of rotating 3D boxes.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1156,"description":"<p>Reorients the camera to look at a position in world space.</p>\n","itemtype":"method","name":"lookAt","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // look at a new random point every 60 frames\n  if (frameCount % 60 === 0) {\n    cam.lookAt(random(-100, 100), random(-50, 50), 0);\n  }\n\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"camera view of rotating 3D cubes changes to look at a new random\npoint every second .","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1223,"description":"<p>Sets the camera's position and orientation.\nAccepts the same parameters as the global\n<a href=\"#/p5/camera\">camera()</a>.\nMore information on this function can be found there.</p>\n","itemtype":"method","name":"camera","example":["\n<div>\n<code>\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // Create a camera.\n  // createCamera() sets the newly created camera as\n  // the current (active) camera.\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(204);\n  // Move the camera away from the plane by a sin wave\n  cam.camera(0, 0, 20 + sin(frameCount * 0.01) * 10, 0, 0, 0, 0, 1, 0);\n  plane(10, 10);\n}\n</code>\n</div>","\n<div>\n<code>\n// move slider to see changes!\n// sliders control the first 6 parameters of camera()\n\nlet sliderGroup = [];\nlet X;\nlet Y;\nlet Z;\nlet centerX;\nlet centerY;\nlet centerZ;\nlet h = 20;\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  // create a camera\n  cam = createCamera();\n  // create sliders\n  for (var i = 0; i < 6; i++) {\n    if (i === 2) {\n      sliderGroup[i] = createSlider(10, 400, 200);\n    } else {\n      sliderGroup[i] = createSlider(-400, 400, 0);\n    }\n    h = map(i, 0, 6, 5, 85);\n    sliderGroup[i].position(10, height + h);\n    sliderGroup[i].style('width', '80px');\n  }\n}\n\nfunction draw() {\n  background(60);\n  // assigning sliders' value to each parameters\n  X = sliderGroup[0].value();\n  Y = sliderGroup[1].value();\n  Z = sliderGroup[2].value();\n  centerX = sliderGroup[3].value();\n  centerY = sliderGroup[4].value();\n  centerZ = sliderGroup[5].value();\n  cam.camera(X, Y, Z, centerX, centerY, centerZ, 0, 1, 0);\n  stroke(255);\n  fill(255, 102, 94);\n  box(85);\n}\n</code>\n</div>"],"alt":"An interactive example of a red cube with 3 sliders for moving it across x, y,\nz axis and 3 sliders for shifting its center.","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1386,"description":"<p>Move camera along its local axes while maintaining current camera orientation.</p>\n","itemtype":"method","name":"move","params":[{"name":"x","description":"<p>amount to move along camera's left-right axis</p>\n","type":"Number"},{"name":"y","description":"<p>amount to move along camera's up-down axis</p>\n","type":"Number"},{"name":"z","description":"<p>amount to move along camera's forward-backward axis</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// see the camera move along its own axes while maintaining its orientation\nlet cam;\nlet delta = 0.5;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // move the camera along its local axes\n  cam.move(delta, delta, 0);\n\n  // every 100 frames, switch direction\n  if (frameCount % 150 === 0) {\n    delta *= -1;\n  }\n\n  translate(-10, -10, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n  translate(15, 15, 0);\n  box(50, 8, 50);\n}\n</code>\n</div>"],"alt":"camera view moves along a series of 3D boxes, maintaining the same\norientation throughout the move","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1458,"description":"<p>Set camera position in world-space while maintaining current camera\norientation.</p>\n","itemtype":"method","name":"setPosition","params":[{"name":"x","description":"<p>x position of a point in world space</p>\n","type":"Number"},{"name":"y","description":"<p>y position of a point in world space</p>\n","type":"Number"},{"name":"z","description":"<p>z position of a point in world space</p>\n","type":"Number"}],"example":["\n<div>\n<code>\n// press '1' '2' or '3' keys to set camera position\n\nlet cam;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n  cam = createCamera();\n}\n\nfunction draw() {\n  background(200);\n\n  // '1' key\n  if (keyIsDown(49)) {\n    cam.setPosition(30, 0, 80);\n  }\n  // '2' key\n  if (keyIsDown(50)) {\n    cam.setPosition(0, 0, 80);\n  }\n  // '3' key\n  if (keyIsDown(51)) {\n    cam.setPosition(-30, 0, 80);\n  }\n\n  box(20);\n}\n</code>\n</div>"],"alt":"camera position changes as the user presses keys, altering view of a 3D box","class":"p5.Camera","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Camera.js","line":1723,"description":"<p>Sets the current (active) camera of a 3D sketch.\nAllows for switching between multiple cameras.</p>\n","itemtype":"method","name":"setCamera","params":[{"name":"cam","description":"<p>p5.Camera object</p>\n","type":"p5.Camera"}],"example":["\n<div>\n<code>\nlet cam1, cam2;\nlet currentCamera;\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  normalMaterial();\n\n  cam1 = createCamera();\n  cam2 = createCamera();\n  cam2.setPosition(30, 0, 50);\n  cam2.lookAt(0, 0, 0);\n  cam2.ortho();\n\n  // set variable for previously active camera:\n  currentCamera = 1;\n}\n\nfunction draw() {\n  background(200);\n\n  // camera 1:\n  cam1.lookAt(0, 0, 0);\n  cam1.setPosition(sin(frameCount / 60) * 200, 0, 100);\n\n  // every 100 frames, switch between the two cameras\n  if (frameCount % 100 === 0) {\n    if (currentCamera === 1) {\n      setCamera(cam1);\n      currentCamera = 0;\n    } else {\n      setCamera(cam2);\n      currentCamera = 1;\n    }\n  }\n\n  drawBoxes();\n}\n\nfunction drawBoxes() {\n  rotateX(frameCount * 0.01);\n  translate(-100, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n  translate(35, 0, 0);\n  box(20);\n}\n</code>\n</div>"],"alt":"Canvas switches between two camera views, each showing a series of spinning\n3D boxes.","class":"p5","module":"3D","submodule":"Camera"},{"file":"src/webgl/p5.Geometry.js","line":71,"description":"<p>computes faces for geometry objects based on the vertices.</p>\n","itemtype":"method","name":"computeFaces","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":114,"description":"<p>computes smooth normals per vertex as an average of each\nface.</p>\n","itemtype":"method","name":"computeNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":153,"description":"<p>Averages the vertex normals. Used in curved\nsurfaces</p>\n","itemtype":"method","name":"averageNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":174,"description":"<p>Averages pole normals.  Used in spherical primitives</p>\n","itemtype":"method","name":"averagePoleNormals","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.Geometry.js","line":267,"description":"<p>Modifies all vertices to be centered within the range -100 to 100.</p>\n","itemtype":"method","name":"normalize","chainable":1,"class":"p5.Geometry","module":"Shape","submodule":"3D Primitives"},{"file":"src/webgl/p5.RendererGL.js","line":334,"description":"<p>Set attributes for the WebGL Drawing context.\nThis is a way of adjusting how the WebGL\nrenderer works to fine-tune the display and performance.</p>\n<p>Note that this will reinitialize the drawing context\nif called after the WebGL canvas is made.</p>\n<p>If an object is passed as the parameter, all attributes\nnot declared in the object will be set to defaults.</p>\n<p>The available attributes are:\n<br>\nalpha - indicates if the canvas contains an alpha buffer\ndefault is false</p>\n<p>depth - indicates whether the drawing buffer has a depth buffer\nof at least 16 bits - default is true</p>\n<p>stencil - indicates whether the drawing buffer has a stencil buffer\nof at least 8 bits</p>\n<p>antialias - indicates whether or not to perform anti-aliasing\ndefault is false (true in Safari)</p>\n<p>premultipliedAlpha - indicates that the page compositor will assume\nthe drawing buffer contains colors with pre-multiplied alpha\ndefault is false</p>\n<p>preserveDrawingBuffer - if true the buffers will not be cleared and\nand will preserve their values until cleared or overwritten by author\n(note that p5 clears automatically on draw loop)\ndefault is true</p>\n<p>perPixelLighting - if true, per-pixel lighting will be used in the\nlighting shader otherwise per-vertex lighting is used.\ndefault is true.</p>\n","itemtype":"method","name":"setAttributes","example":["\n<div>\n<code>\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n<br>\nNow with the antialias attribute set to true.\n<br>\n<div>\n<code>\nfunction setup() {\n  setAttributes('antialias', true);\n  createCanvas(100, 100, WEBGL);\n}\n\nfunction draw() {\n  background(255);\n  push();\n  rotateZ(frameCount * 0.02);\n  rotateX(frameCount * 0.02);\n  rotateY(frameCount * 0.02);\n  fill(0, 0, 0);\n  box(50);\n  pop();\n}\n</code>\n</div>\n\n<div>\n<code>\n// press the mouse button to disable perPixelLighting\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  noStroke();\n  fill(255);\n}\n\nlet lights = [\n  { c: '#f00', t: 1.12, p: 1.91, r: 0.2 },\n  { c: '#0f0', t: 1.21, p: 1.31, r: 0.2 },\n  { c: '#00f', t: 1.37, p: 1.57, r: 0.2 },\n  { c: '#ff0', t: 1.12, p: 1.91, r: 0.7 },\n  { c: '#0ff', t: 1.21, p: 1.31, r: 0.7 },\n  { c: '#f0f', t: 1.37, p: 1.57, r: 0.7 }\n];\n\nfunction draw() {\n  let t = millis() / 1000 + 1000;\n  background(0);\n  directionalLight(color('#222'), 1, 1, 1);\n\n  for (let i = 0; i < lights.length; i++) {\n    let light = lights[i];\n    pointLight(\n      color(light.c),\n      p5.Vector.fromAngles(t * light.t, t * light.p, width * light.r)\n    );\n  }\n\n  specularMaterial(255);\n  sphere(width * 0.1);\n\n  rotateX(t * 0.77);\n  rotateY(t * 0.83);\n  rotateZ(t * 0.91);\n  torus(width * 0.3, width * 0.07, 24, 10);\n}\n\nfunction mousePressed() {\n  setAttributes('perPixelLighting', false);\n  noStroke();\n  fill(255);\n}\nfunction mouseReleased() {\n  setAttributes('perPixelLighting', true);\n  noStroke();\n  fill(255);\n}\n</code>\n</div>"],"alt":"a rotating cube with smoother edges","class":"p5","module":"Rendering","submodule":"Rendering","overloads":[{"line":334,"params":[{"name":"key","description":"<p>Name of attribute</p>\n","type":"String"},{"name":"value","description":"<p>New value of named attribute</p>\n","type":"Boolean"}]},{"line":473,"params":[{"name":"obj","description":"<p>object with key-value pairs</p>\n","type":"Object"}]}]},{"file":"src/webgl/p5.Shader.js","line":306,"description":"<p>Used to set the uniforms of a\n<a href=\"#/p5.Shader\">p5.Shader</a> object.</p>\n<p>Uniforms are used as a way to provide shader programs\n(which run on the GPU) with values from a sketch\n(which runs on the CPU).</p>\n","itemtype":"method","name":"setUniform","chainable":1,"params":[{"name":"uniformName","description":"<p>the name of the uniform.\nMust correspond to the name used in the vertex and fragment shaders</p>\n","type":"String"},{"name":"data","description":"<p>the data to associate with the uniform. The type can be\na boolean (true/false), a number, an array of numbers, or\nan image (p5.Image, p5.Graphics, p5.MediaElement, p5.Texture)</p>\n","type":"Boolean|Number|Number[]|p5.Image|p5.Graphics|p5.MediaElement|p5.Texture"}],"example":["\n<div modernizr='webgl'>\n<code>\n// Click within the image to toggle the value of uniforms\n// Note: for an alternative approach to the same example,\n// involving toggling between shaders please refer to:\n// https://p5js.org/reference/#/p5/shader\n\nlet grad;\nlet showRedGreen = false;\n\nfunction preload() {\n  // note that we are using two instances\n  // of the same vertex and fragment shaders\n  grad = loadShader('assets/shader.vert', 'assets/shader-gradient.frag');\n}\n\nfunction setup() {\n  createCanvas(100, 100, WEBGL);\n  shader(grad);\n  noStroke();\n}\n\nfunction draw() {\n  // update the offset values for each scenario,\n  // moving the \"grad\" shader in either vertical or\n  // horizontal direction each with differing colors\n\n  if (showRedGreen === true) {\n    grad.setUniform('colorCenter', [1, 0, 0]);\n    grad.setUniform('colorBackground', [0, 1, 0]);\n    grad.setUniform('offset', [sin(millis() / 2000), 1]);\n  } else {\n    grad.setUniform('colorCenter', [1, 0.5, 0]);\n    grad.setUniform('colorBackground', [0.226, 0, 0.615]);\n    grad.setUniform('offset', [0, sin(millis() / 2000) + 1]);\n  }\n  quad(-1, -1, 1, -1, 1, 1, -1, 1);\n}\n\nfunction mouseClicked() {\n  showRedGreen = !showRedGreen;\n}\n</code>\n</div>"],"alt":"canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed.","class":"p5.Shader","module":"3D","submodule":"Material"},{"file":"lib/addons/p5.sound.js","line":1,"class":"p5.sound","module":"3D"},{"file":"lib/addons/p5.sound.js","line":52,"description":"<p>p5.sound \n<a href=\"https://p5js.org/reference/#/libraries/p5.sound\">https://p5js.org/reference/#/libraries/p5.sound</a></p>\n<p>From the Processing Foundation and contributors\n<a href=\"https://github.com/processing/p5.js-sound/graphs/contributors\">https://github.com/processing/p5.js-sound/graphs/contributors</a></p>\n<p>MIT License (MIT)\n<a href=\"https://github.com/processing/p5.js-sound/blob/master/LICENSE\">https://github.com/processing/p5.js-sound/blob/master/LICENSE</a></p>\n<p>Some of the many audio libraries & resources that inspire p5.sound:</p>\n<ul>\n<li><p>TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). <a href=\"https://github.com/TONEnoTONE/Tone.js\">https://github.com/TONEnoTONE/Tone.js</a></p>\n</li>\n<li><p>buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). <a href=\"http://buzz.jaysalvat.com/\">http://buzz.jaysalvat.com/</a></p>\n</li>\n<li><p>Boris Smus Web Audio API book, 2013. Licensed under the Apache License <a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a></p>\n</li>\n<li><p>wavesurfer.js <a href=\"https://github.com/katspaugh/wavesurfer.js\">https://github.com/katspaugh/wavesurfer.js</a></p>\n</li>\n<li><p>Web Audio Components by Jordan Santell <a href=\"https://github.com/web-audio-components\">https://github.com/web-audio-components</a></p>\n</li>\n<li><p>Wilm Thoben's Sound library for Processing <a href=\"https://github.com/processing/processing/tree/master/java/libraries/sound\">https://github.com/processing/processing/tree/master/java/libraries/sound</a></p>\n<p>Web Audio API: <a href=\"http://w3.org/TR/webaudio/\">http://w3.org/TR/webaudio/</a></p>\n</li>\n</ul>\n","class":"p5.sound","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":159,"description":"<p>Returns the Audio Context for this sketch. Useful for users\nwho would like to dig deeper into the <a target='_blank' href=\n'http://webaudio.github.io/web-audio-api/'>Web Audio API\n</a>.</p>\n\n<p>Some browsers require users to startAudioContext\nwith a user gesture, such as touchStarted in the example below.</p>","itemtype":"method","name":"getAudioContext","return":{"description":"AudioContext for this sketch","type":"Object"},"example":["\n<div><code>\n function draw() {\n   background(255);\n   textAlign(CENTER);\n\n   if (getAudioContext().state !== 'running') {\n     text('click to start audio', width/2, height/2);\n   } else {\n     text('audio is enabled', width/2, height/2);\n   }\n }\n\n function touchStarted() {\n   if (getAudioContext().state !== 'running') {\n     getAudioContext().resume();\n   }\n   var synth = new p5.MonoSynth();\n   synth.play('A4', 0.5, 0, 0.2);\n }\n\n</div></code>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":198,"description":"<p>It is not only a good practice to give users control over starting\naudio. This policy is enforced by many web browsers, including iOS and\n<a href=\"https://goo.gl/7K7WLu\" title=\"Google Chrome's autoplay\npolicy\">Google Chrome</a>, which create the Web Audio API's\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/AudioContext\"\ntitle=\"Audio Context @ MDN\">Audio Context</a>\nin a suspended state.</p>\n\n<p>In these browser-specific policies, sound will not play until a user\ninteraction event (i.e. <code>mousePressed()</code>) explicitly resumes\nthe AudioContext, or starts an audio node. This can be accomplished by\ncalling <code>start()</code> on a <code>p5.Oscillator</code>,\n<code> play()</code> on a <code>p5.SoundFile</code>, or simply\n<code>userStartAudio()</code>.</p>\n\n<p><code>userStartAudio()</code> starts the AudioContext on a user\ngesture. The default behavior will enable audio on any\nmouseUp or touchEnd event. It can also be placed in a specific\ninteraction function, such as <code>mousePressed()</code> as in the\nexample below. This method utilizes\n<a href=\"https://github.com/tambien/StartAudioContext\">StartAudioContext\n</a>, a library by Yotam Mann (MIT Licence, 2016).</p>","params":[{"name":"element(s)","description":"<p>This argument can be an Element,\n                              Selector String, NodeList, p5.Element,\n                              jQuery Element, or an Array of any of those.</p>\n","type":"Element|Array","optional":true},{"name":"callback","description":"<p>Callback to invoke when the AudioContext\n                              has started</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that resolves when\n                                     the AudioContext state is 'running'","type":"Promise"},"itemtype":"method","name":"userStartAudio","example":["\n<div><code>\nfunction setup() {\n  // mimics the autoplay policy\n  getAudioContext().suspend();\n\n  let mySynth = new p5.MonoSynth();\n\n  // This won't play until the context has resumed\n  mySynth.play('A6');\n}\nfunction draw() {\n  background(220);\n  textAlign(CENTER, CENTER);\n  text(getAudioContext().state, width/2, height/2);\n}\nfunction mousePressed() {\n  userStartAudio();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":401,"description":"<p>This module has shims</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":536,"description":"<p>Determine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":726,"description":"<p>Returns a number representing the output volume for sound\nin this sketch.</p>\n","itemtype":"method","name":"getOutputVolume","return":{"description":"Output volume for sound in this sketch.\n                 Should be between 0.0 (silence) and 1.0.","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":738,"description":"<p>Scale the output of all sound in this sketch</p>\nScaled between 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.\n\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n<p><b>How This Works</b>: When you load the p5.sound module, it\ncreates a single instance of p5sound. All sound objects in this\nmodule output to p5sound before reaching your computer's output.\nSo if you change the amplitude of p5sound, it impacts all of the\nsound in this module.</p>\n\n<p>If no value is provided, returns a Web Audio API Gain Node</p>","itemtype":"method","name":"outputVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":782,"description":"<p><code>p5.soundOut</code> is the p5.sound final output bus. It sends output to\nthe destination of this window's web audio context. It contains\nWeb Audio API nodes including a dyanmicsCompressor (<code>.limiter</code>),\nand Gain Nodes for <code>.input</code> and <code>.output</code>.</p>\n","itemtype":"property","name":"soundOut","type":"Object","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":807,"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":811,"description":"<p>Returns a number representing the sample rate, in samples per second,\nof all sound objects in this audio context. It is determined by the\nsampling rate of your operating system's sound card, and it is not\ncurrently possile to change.\nIt is often 44100, or twice the range of human hearing.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"samplerate samples per second","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":825,"description":"<p>Returns the closest MIDI note value for\na given frequency.</p>\n","itemtype":"method","name":"freqToMidi","params":[{"name":"frequency","description":"<p>A freqeuncy, for example, the \"A\"\n                           above Middle C is 440Hz</p>\n","type":"Number"}],"return":{"description":"MIDI note value","type":"Number"},"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":841,"description":"<p>Returns the frequency value of a MIDI note value.\nGeneral MIDI treats notes as integers where middle C\nis 60, C# is 61, D is 62 etc. Useful for generating\nmusical frequencies with oscillators.</p>\n","itemtype":"method","name":"midiToFreq","params":[{"name":"midiNote","description":"<p>The number of a MIDI note</p>\n","type":"Number"}],"return":{"description":"Frequency value of the given MIDI note","type":"Number"},"example":["\n<div><code>\nlet midiNotes = [60, 64, 67, 72];\nlet noteIndex = 0;\nlet midiVal, freq;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(startSound);\n  osc = new p5.TriOsc();\n  env = new p5.Envelope();\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 10, 20);\n  if (midiVal) {\n    text('MIDI: ' + midiVal, 10, 40);\n    text('Freq: ' + freq, 10, 60);\n  }\n}\n\nfunction startSound() {\n  // see also: userStartAudio();\n  osc.start();\n\n  midiVal = midiNotes[noteIndex % midiNotes.length];\n  freq = midiToFreq(midiVal);\n  osc.freq(freq);\n  env.ramp(osc, 0, 1.0, 0);\n\n  noteIndex++;\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":925,"description":"<p>List the SoundFile formats that you will include. LoadSound\nwill search your directory for these extensions, and will pick\na format that is compatable with the client's web browser.\n<a href=\"http://media.io/\">Here</a> is a free online file\nconverter.</p>\n","itemtype":"method","name":"soundFormats","params":[{"name":"formats","description":"<p>i.e. 'mp3', 'wav', 'ogg'</p>\n","type":"String","optional":true,"multiple":true}],"example":["\n<div><code>\nfunction preload() {\n  // set the global sound formats\n  soundFormats('mp3', 'ogg');\n\n  // load either beatbox.mp3, or .ogg, depending on browser\n  mySound = loadSound('assets/beatbox.mp3');\n}\n\nfunction setup() {\n     let cnv = createCanvas(100, 100);\n     background(220);\n     text('sound loaded! tap to play', 10, 20, width - 20);\n     cnv.mousePressed(function() {\n       mySound.play();\n     });\n   }\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1040,"description":"<p>Used by Osc and Envelope to chain signal math</p>\n","class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1145,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device.\nFor uploading audio to a server, use\n<a href=\"/docs/reference/#/p5.SoundFile/saveBlob\"><code>p5.SoundFile.saveBlob</code></a>.</p>\n","itemtype":"method","name":"saveSound","params":[{"name":"soundFile","description":"<p>p5.SoundFile that you wish to save</p>\n","type":"p5.SoundFile"},{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1662,"description":"<p>Returns true if the sound file finished loading successfully.</p>\n","itemtype":"method","name":"isLoaded","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1679,"description":"<p>Play the p5.SoundFile</p>\n","itemtype":"method","name":"play","params":[{"name":"startTime","description":"<p>(optional) schedule playback to start (in seconds from now).</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) amplitude (volume)\n                                    of playback</p>\n","type":"Number","optional":true},{"name":"cueStart","description":"<p>(optional) cue start time in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) duration of playback in seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1787,"description":"<p>p5.SoundFile has two play modes: <code>restart</code> and\n<code>sustain</code>. Play Mode determines what happens to a\np5.SoundFile if it is triggered while in the middle of playback.\nIn sustain mode, playback will continue simultaneous to the\nnew playback. In restart mode, play() will stop playback\nand start over. With untilDone, a sound will play only if it's\nnot already playing. Sustain is the default mode.</p>\n","itemtype":"method","name":"playMode","params":[{"name":"str","description":"<p>'restart' or 'sustain' or 'untilDone'</p>\n","type":"String"}],"example":["\n<div><code>\nlet mySound;\nfunction preload(){\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  noFill();\n  rect(0, height/2, width - 1, height/2 - 1);\n  rect(0, 0, width - 1, height/2);\n  textAlign(CENTER, CENTER);\n  fill(20);\n  text('restart', width/2, 1 * height/4);\n  text('sustain', width/2, 3 * height/4);\n}\nfunction canvasPressed() {\n  if (mouseX < height/2) {\n    mySound.playMode('restart');\n  } else {\n    mySound.playMode('sustain');\n  }\n  mySound.play();\n}\n\n </code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1847,"description":"<p>Pauses a file that is currently playing. If the file is not\nplaying, then nothing will happen.</p>\n<p>After pausing, .play() will resume from the paused\nposition.\nIf p5.SoundFile had been set to loop before it was paused,\nit will continue to loop after it is unpaused with .play().</p>\n","itemtype":"method","name":"pause","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                             seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet soundFile;\nfunction preload() {\n  soundFormats('ogg', 'mp3');\n  soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n}\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play, release to pause', 10, 20, width - 20);\n}\nfunction canvasPressed() {\n  soundFile.loop();\n  background(0, 200, 50);\n}\nfunction mouseReleased() {\n  soundFile.pause();\n  background(220);\n}\n</code>\n</div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1905,"description":"<p>Loop the p5.SoundFile. Accepts optional parameters to set the\nplayback rate, playback volume, loopStart, loopEnd.</p>\n","itemtype":"method","name":"loop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            seconds from now</p>\n","type":"Number","optional":true},{"name":"rate","description":"<p>(optional) playback rate</p>\n","type":"Number","optional":true},{"name":"amp","description":"<p>(optional) playback volume</p>\n","type":"Number","optional":true},{"name":"cueLoopStart","description":"<p>(optional) startTime in seconds</p>\n","type":"Number","optional":true},{"name":"duration","description":"<p>(optional) loop duration in seconds</p>\n","type":"Number","optional":true}],"example":["\n <div><code>\n let soundFile;\n let loopStart = 0.5;\n let loopDuration = 0.2;\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/Damscray_-_Dancing_Tiger_02.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to play, release to pause', 10, 20, width - 20);\n }\n function canvasPressed() {\n   soundFile.loop();\n   background(0, 200, 50);\n }\n function mouseReleased() {\n   soundFile.pause();\n   background(220);\n }\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1950,"description":"<p>Set a p5.SoundFile's looping flag to true or false. If the sound\nis currently playing, this change will take effect when it\nreaches the end of the current playback.</p>\n","itemtype":"method","name":"setLoop","params":[{"name":"Boolean","description":"<p>set looping to true or false</p>\n","type":"Boolean"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1976,"description":"<p>Returns 'true' if a p5.SoundFile is currently looping and playing, 'false' if not.</p>\n","itemtype":"method","name":"isLooping","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":1997,"description":"<p>Returns true if a p5.SoundFile is playing, false if not (i.e.\npaused or stopped).</p>\n","itemtype":"method","name":"isPlaying","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2011,"description":"<p>Returns true if a p5.SoundFile is paused, false if not (i.e.\nplaying or stopped).</p>\n","itemtype":"method","name":"isPaused","return":{"description":"","type":"Boolean"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2025,"description":"<p>Stop soundfile playback.</p>\n","itemtype":"method","name":"stop","params":[{"name":"startTime","description":"<p>(optional) schedule event to occur\n                            in seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2087,"description":"<p>Set the stereo panning of a p5.sound object to\na floating point number between -1.0 (left) and 1.0 (right).\nDefault is 0.0 (center).</p>\n","itemtype":"method","name":"pan","params":[{"name":"panValue","description":"<p>Set the stereo panner</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                                seconds from now</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\n let ballX = 0;\n let soundFile;\n\n function preload() {\n   soundFormats('ogg', 'mp3');\n   soundFile = loadSound('assets/beatbox.mp3');\n }\n\n function draw() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   ballX = constrain(mouseX, 0, width);\n   ellipse(ballX, height/2, 20, 20);\n }\n\n function canvasPressed(){\n   // map the ball's x location to a panning degree\n   // between -1.0 (left) and 1.0 (right)\n   let panning = map(ballX, 0., width,-1.0, 1.0);\n   soundFile.pan(panning);\n   soundFile.play();\n }\n </div></code>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2131,"description":"<p>Returns the current stereo pan position (-1.0 to 1.0)</p>\n","itemtype":"method","name":"getPan","return":{"description":"Returns the stereo pan setting of the Oscillator\n                         as a number between -1.0 (left) and 1.0 (right).\n                         0.0 is center and default.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2146,"description":"<p>Set the playback rate of a sound file. Will change the speed and the pitch.\nValues less than zero will reverse the audio buffer.</p>\n","itemtype":"method","name":"rate","params":[{"name":"playbackRate","description":"<p>Set the playback rate. 1.0 is normal,\n                                   .5 is half-speed, 2.0 is twice as fast.\n                                   Values less than zero play backwards.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet mySound;\n\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n}\nfunction canvasPressed() {\n  mySound.loop();\n}\nfunction mouseReleased() {\n  mySound.pause();\n}\nfunction draw() {\n  background(220);\n\n  // Set the rate to a range between 0.1 and 4\n  // Changing the rate also alters the pitch\n  let playbackRate = map(mouseY, 0.1, height, 2, 0);\n  playbackRate = constrain(playbackRate, 0.01, 4);\n  mySound.rate(playbackRate);\n\n  line(0, mouseY, width, mouseY);\n  text('rate: ' + round(playbackRate * 100) + '%', 10, 20);\n}\n\n </code>\n </div>\n"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2239,"description":"<p>Multiply the output volume (amplitude) of a sound file\nbetween 0.0 (silence) and 1.0 (full volume).\n1.0 is the maximum amplitude of a digital sound, so multiplying\nby greater than 1.0 may cause digital distortion. To\nfade, provide a <code>rampTime</code> parameter. For more\ncomplex fades, see the Envelope class.</p>\n<p>Alternately, you can pass in a signal source such as an\noscillator to modulate the amplitude with an audio signal.</p>\n","itemtype":"method","name":"setVolume","params":[{"name":"volume","description":"<p>Volume (amplitude) between 0.0\n                                   and 1.0 or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Fade for t seconds</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen at\n                               t seconds in the future</p>\n","type":"Number","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2276,"description":"<p>Returns the duration of a sound file in seconds.</p>\n","itemtype":"method","name":"duration","return":{"description":"The duration of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2293,"description":"<p>Return the current position of the p5.SoundFile playhead, in seconds.\nTime is relative to the normal buffer direction, so if <code>reverseBuffer</code>\nhas been called, currentTime will count backwards.</p>\n","itemtype":"method","name":"currentTime","return":{"description":"currentTime of the soundFile in seconds.","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2308,"description":"<p>Move the playhead of a soundfile that is currently playing to a\nnew position and a new duration, in seconds.\nIf none are given, will reset the file to play entire duration\nfrom start to finish. To set the position of a soundfile that is\nnot currently playing, use the <code>play</code> or <code>loop</code> methods.</p>\n","itemtype":"method","name":"jump","params":[{"name":"cueTime","description":"<p>cueTime of the soundFile in seconds.</p>\n","type":"Number"},{"name":"duration","description":"<p>duration in seconds.</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2340,"description":"<p>Return the number of channels in a sound file.\nFor example, Mono = 1, Stereo = 2.</p>\n","itemtype":"method","name":"channels","return":{"description":"[channels]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2354,"description":"<p>Return the sample rate of the sound file.</p>\n","itemtype":"method","name":"sampleRate","return":{"description":"[sampleRate]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2367,"description":"<p>Return the number of samples in a sound file.\nEqual to sampleRate * duration.</p>\n","itemtype":"method","name":"frames","return":{"description":"[sampleCount]","type":"Number"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2381,"description":"<p>Returns an array of amplitude peaks in a p5.SoundFile that can be\nused to draw a static waveform. Scans through the p5.SoundFile's\naudio buffer to find the greatest amplitudes. Accepts one\nparameter, 'length', which determines size of the array.\nLarger arrays result in more precise waveform visualizations.</p>\n<p>Inspired by Wavesurfer.js.</p>\n","itemtype":"method","name":"getPeaks","params":[{"name":"length","description":"<p>length is the size of the returned array.\n                         Larger length results in more precision.\n                         Defaults to 5*width of the browser window.</p>\n","type":"Number","optional":true}],"return":{"description":"Array of peaks.","type":"Float32Array"},"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2443,"description":"<p>Reverses the p5.SoundFile's buffer source.\nPlayback must be handled separately (see example).</p>\n","itemtype":"method","name":"reverseBuffer","example":["\n<div><code>\nlet drum;\nfunction preload() {\n  drum = loadSound('assets/drum.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction canvasPressed() {\n  drum.stop();\n  drum.reverseBuffer();\n  drum.play();\n}\n </code>\n </div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2497,"description":"<p>Schedule an event to be called when the soundfile\nreaches the end of a buffer. If the soundfile is\nplaying through once, this will be called when it\nends. If it is looping, it will be called when\nstop is called.</p>\n","itemtype":"method","name":"onended","params":[{"name":"callback","description":"<p>function to call when the\n                            soundfile has ended.</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2565,"description":"<p>Connects the output of a p5sound object to input of another\np5.sound object. For example, you may connect a p5.SoundFile to an\nFFT or an Effect. If no parameter is given, it will connect to\nthe main output. Most p5sound objects connect to the master\noutput when they are created.</p>\n","itemtype":"method","name":"connect","params":[{"name":"object","description":"<p>Audio object that accepts an input</p>\n","type":"Object","optional":true}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2590,"description":"<p>Disconnects the output of this p5sound object.</p>\n","itemtype":"method","name":"disconnect","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2604,"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2612,"description":"<p>Reset the source for this SoundFile to a\nnew path (URL).</p>\n","itemtype":"method","name":"setPath","params":[{"name":"path","description":"<p>path to audio file</p>\n","type":"String"},{"name":"callback","description":"<p>Callback</p>\n","type":"Function"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2630,"description":"<p>Replace the current Audio Buffer with a new Buffer.</p>\n","itemtype":"method","name":"setBuffer","params":[{"name":"buf","description":"<p>Array of Float32 Array(s). 2 Float32 Arrays\n                   will create a stereo source. 1 will create\n                   a mono source.</p>\n","type":"Array"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2719,"description":"<p>Schedule events to trigger every time a MediaElement\n(audio/video) reaches a playback cue point.</p>\n<p>Accepts a callback function, a time (in seconds) at which to trigger\nthe callback, and an optional parameter for the callback.</p>\n<p>Time will be passed as the first parameter to the callback function,\nand param will be the second parameter.</p>\n","itemtype":"method","name":"addCue","params":[{"name":"time","description":"<p>Time in seconds, relative to this media\n                           element's playback. For example, to trigger\n                           an event every time playback reaches two\n                           seconds, pass in the number 2. This will be\n                           passed as the first parameter to\n                           the callback function.</p>\n","type":"Number"},{"name":"callback","description":"<p>Name of a function that will be\n                           called at the given time. The callback will\n                           receive time and (optionally) param as its\n                           two parameters.</p>\n","type":"Function"},{"name":"value","description":"<p>An object to be passed as the\n                           second parameter to the\n                           callback function.</p>\n","type":"Object","optional":true}],"return":{"description":"id ID of this cue,\n                    useful for removeCue(id)","type":"Number"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  mySound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap to play', 10, 20);\n\n  // schedule calls to changeText\n  mySound.addCue(0, changeText, \"hello\" );\n  mySound.addCue(0.5, changeText, \"hello,\" );\n  mySound.addCue(1, changeText, \"hello, p5!\");\n  mySound.addCue(1.5, changeText, \"hello, p5!!\");\n  mySound.addCue(2, changeText, \"hello, p5!!!!!\");\n}\n\nfunction changeText(val) {\n  background(220);\n  text(val, 10, 20);\n}\n\nfunction canvasPressed() {\n  mySound.play();\n}\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2790,"description":"<p>Remove a callback based on its ID. The ID is returned by the\naddCue method.</p>\n","itemtype":"method","name":"removeCue","params":[{"name":"id","description":"<p>ID of the cue, as returned by addCue</p>\n","type":"Number"}],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2817,"description":"<p>Remove all of the callbacks that had originally been scheduled\nvia the addCue method.</p>\n","itemtype":"method","name":"clearCues","class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2850,"description":"<p>Save a p5.SoundFile as a .wav file. The browser will prompt the user\nto download the file to their device. To upload a file to a server, see\n<a href=\"/reference/#/p5.SoundFile/getBlob\">getBlob</a></p>\n","itemtype":"method","name":"save","params":[{"name":"fileName","description":"<p>name of the resulting .wav file.</p>\n","type":"String","optional":true}],"example":["\n <div><code>\n let mySound;\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n function setup() {\n   let cnv = createCanvas(100, 100);\n   cnv.mousePressed(canvasPressed);\n   background(220);\n   text('tap to download', 10, 20);\n }\n\n function canvasPressed() {\n   mySound.save('my cool filename');\n }\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2882,"description":"<p>This method is useful for sending a SoundFile to a server. It returns the\n.wav-encoded audio data as a \"<a target=\"_blank\" title=\"Blob reference at\nMDN\" href=\"https://developer.mozilla.org/en-US/docs/Web/API/Blob\">Blob</a>\".\nA Blob is a file-like data object that can be uploaded to a server\nwith an <a href=\"/reference/#/p5/httpDo\">http</a> request. We'll\nuse the <code>httpDo</code> options object to send a POST request with some\nspecific options: we encode the request as <code>multipart/form-data</code>,\nand attach the blob as one of the form values using <code>FormData</code>.</p>\n","itemtype":"method","name":"getBlob","return":{"description":"A file-like data object","type":"Blob"},"example":["\n <div><code>\n function preload() {\n   mySound = loadSound('assets/doorbell.mp3');\n }\n\n function setup() {\n   noCanvas();\n   let soundBlob = mySound.getBlob();\n\n   // Now we can send the blob to a server...\n   let serverUrl = 'https://jsonplaceholder.typicode.com/posts';\n   let httpRequestOptions = {\n     method: 'POST',\n     body: new FormData().append('soundBlob', soundBlob),\n     headers: new Headers({\n       'Content-Type': 'multipart/form-data'\n     })\n   };\n   httpDo(serverUrl, httpRequestOptions);\n\n   // We can also create an `ObjectURL` pointing to the Blob\n   let blobUrl = URL.createObjectURL(soundBlob);\n\n   // The `<Audio>` Element accepts Object URL's\n   createAudio(blobUrl).showControls();\n\n   createDiv();\n\n   // The ObjectURL exists as long as this tab is open\n   let input = createInput(blobUrl);\n   input.attribute('readonly', true);\n   input.mouseClicked(function() { input.elt.select() });\n }\n\n</code></div>"],"class":"p5.SoundFile","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":2946,"description":"<p>loadSound() returns a new p5.SoundFile from a specified\npath. If called during preload(), the p5.SoundFile will be ready\nto play in time for setup() and draw(). If called outside of\npreload, the p5.SoundFile will not be ready immediately, so\nloadSound accepts a callback as the second parameter. Using a\n<a href=\"https://github.com/processing/p5.js/wiki/Local-server\">\nlocal server</a> is recommended when loading external files.</p>\n","itemtype":"method","name":"loadSound","params":[{"name":"path","description":"<p>Path to the sound file, or an array with\n                                  paths to soundfiles in multiple formats\n                                  i.e. ['sound.ogg', 'sound.mp3'].\n                                  Alternately, accepts an object: either\n                                  from the HTML5 File API, or a p5.File.</p>\n","type":"String|Array"},{"name":"successCallback","description":"<p>Name of a function to call once file loads</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if there is\n                                    an error loading the file.</p>\n","type":"Function","optional":true},{"name":"whileLoading","description":"<p>Name of a function to call while file is loading.\n                               This function will receive the percentage loaded\n                               so far, from 0.0 to 1.0.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a p5.SoundFile","type":"SoundFile"},"example":["\n<div><code>\nlet mySound;\nfunction preload() {\n  soundFormats('mp3', 'ogg');\n  mySound = loadSound('assets/doorbell');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(canvasPressed);\n  background(220);\n  text('tap here to play', 10, 20);\n}\n\nfunction canvasPressed() {\n  // playing a sound file on a user gesture\n  // is equivalent to `userStartAudio()`\n  mySound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3117,"description":"<p>Connects to the p5sound instance (main output) by default.\nOptionally, you can pass in a specific source (i.e. a soundfile).</p>\n","itemtype":"method","name":"setInput","params":[{"name":"snd","description":"<p>set the sound source\n                                     (optional, defaults to\n                                     main output)</p>\n","type":"SoundObject|undefined","optional":true},{"name":"smoothing","description":"<p>a range between 0.0 and 1.0\n                                      to smooth amplitude readings</p>\n","type":"Number|undefined","optional":true}],"example":["\n<div><code>\nfunction preload(){\n  sound1 = loadSound('assets/beat.mp3');\n  sound2 = loadSound('assets/drum.mp3');\n}\nfunction setup(){\n  cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n\n  amplitude = new p5.Amplitude();\n  amplitude.setInput(sound2);\n}\n\nfunction draw() {\n  background(220);\n  text('tap to play', 20, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound1.isPlaying() && sound2.isPlaying()) {\n    sound1.stop();\n    sound2.stop();\n  } else {\n    sound1.play();\n    sound2.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3209,"description":"<p>Returns a single Amplitude reading at the moment it is called.\nFor continuous readings, run in the draw loop.</p>\n","itemtype":"method","name":"getLevel","params":[{"name":"channel","description":"<p>Optionally return only channel 0 (left) or 1 (right)</p>\n","type":"Number","optional":true}],"return":{"description":"Amplitude as a number between 0.0 and 1.0","type":"Number"},"example":["\n<div><code>\nfunction preload(){\n  sound = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mouseClicked(toggleSound);\n  amplitude = new p5.Amplitude();\n}\n\nfunction draw() {\n  background(220, 150);\n  textAlign(CENTER);\n  text('tap to play', width/2, 20);\n\n  let level = amplitude.getLevel();\n  let size = map(level, 0, 1, 0, 200);\n  ellipse(width/2, height/2, size, size);\n}\n\nfunction toggleSound(){\n  if (sound.isPlaying()) {\n    sound.stop();\n  } else {\n    sound.play();\n  }\n}\n</code></div>"],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3264,"description":"<p>Determines whether the results of Amplitude.process() will be\nNormalized. To normalize, Amplitude finds the difference the\nloudest reading it has processed and the maximum amplitude of\n1.0. Amplitude adds this difference to all values to produce\nresults that will reliably map between 0.0 and 1.0. However,\nif a louder moment occurs, the amount that Normalize adds to\nall the values will change. Accepts an optional boolean parameter\n(true or false). Normalizing is off by default.</p>\n","itemtype":"method","name":"toggleNormalize","params":[{"name":"boolean","description":"<p>set normalize to true (1) or false (0)</p>\n","type":"Boolean","optional":true}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3293,"description":"<p>Smooth Amplitude analysis by averaging with the last analysis\nframe. Off by default.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"set","description":"<p>smoothing from 0.0 <= 1</p>\n","type":"Number"}],"class":"p5.Amplitude","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3476,"description":"<p>Set the input source for the FFT analysis. If no source is\nprovided, FFT will analyze all sound in the sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"source","description":"<p>p5.sound object (or web audio API source node)</p>\n","type":"Object","optional":true}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3501,"description":"<p>Returns an array of amplitude values (between -1.0 and +1.0) that represent\na snapshot of amplitude readings in a single buffer. Length will be\nequal to bins (defaults to 1024). Can be used to draw the waveform\nof a sound.</p>\n","itemtype":"method","name":"waveform","params":[{"name":"bins","description":"<p>Must be a power of two between\n                          16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"precision","description":"<p>If any value is provided, will return results\n                            in a Float32 Array which is more precise\n                            than a regular array.</p>\n","type":"String","optional":true}],"return":{"description":"Array    Array of amplitude values (-1 to 1)\n                          over time. Array length = bins.","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3553,"description":"<p>Returns an array of amplitude values (between 0 and 255)\nacross the frequency spectrum. Length is equal to FFT bins\n(1024 by default). The array indices correspond to frequencies\n(i.e. pitches), from the lowest to the highest that humans can\nhear. Each value represents amplitude at that slice of the\nfrequency spectrum. Must be called prior to using\n<code>getEnergy()</code>.</p>\n","itemtype":"method","name":"analyze","params":[{"name":"bins","description":"<p>Must be a power of two between\n                           16 and 1024. Defaults to 1024.</p>\n","type":"Number","optional":true},{"name":"scale","description":"<p>If \"dB,\" returns decibel\n                           float measurements between\n                           -140 and 0 (max).\n                           Otherwise returns integers from 0-255.</p>\n","type":"Number","optional":true}],"return":{"description":"spectrum    Array of energy (amplitude/volume)\n                            values across the frequency spectrum.\n                            Lowest energy (silence) = 0, highest\n                            possible is 255.","type":"Array"},"example":["\n<div><code>\nlet osc, fft;\n\nfunction setup(){\n  let cnv = createCanvas(100,100);\n  cnv.mousePressed(startSound);\n  osc = new p5.Oscillator();\n  osc.amp(0);\n  fft = new p5.FFT();\n}\n\nfunction draw(){\n  background(220);\n\n  let freq = map(mouseX, 0, windowWidth, 20, 10000);\n  freq = constrain(freq, 1, 20000);\n  osc.freq(freq);\n\n  let spectrum = fft.analyze();\n  noStroke();\n  fill(255, 0, 255);\n  for (let i = 0; i< spectrum.length; i++){\n    let x = map(i, 0, spectrum.length, 0, width);\n    let h = -height + map(spectrum[i], 0, 255, height, 0);\n    rect(x, height, width / spectrum.length, h );\n  }\n\n  stroke(255);\n  if (!osc.started) {\n    text('tap here and drag to change frequency', 10, 20, width - 20);\n  } else {\n    text(round(freq)+'Hz', 10, 20);\n  }\n}\n\nfunction startSound() {\n  osc.start();\n  osc.amp(0.5, 0.2);\n}\n\nfunction mouseReleased() {\n  osc.amp(0, 0.2);\n}\n</code></div>\n\n"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3650,"description":"<p>Returns the amount of energy (volume) at a specific\n<a href=\"https://en.wikipedia.org/wiki/Audio_frequency\" target=\"_blank\">\nfrequency</a>, or the average amount of energy between two\nfrequencies. Accepts Number(s) corresponding\nto frequency (in Hz), or a \"string\" corresponding to predefined\nfrequency ranges (\"bass\", \"lowMid\", \"mid\", \"highMid\", \"treble\").\nReturns a range between 0 (no energy/volume at that frequency) and\n255 (maximum energy).\n<em>NOTE: analyze() must be called prior to getEnergy(). analyze()\ntells the FFT to analyze frequency data, and getEnergy() uses\nthe results to determine the value at a specific frequency or\nrange of frequencies.</em></p></p>\n","itemtype":"method","name":"getEnergy","params":[{"name":"frequency1","description":"<p>Will return a value representing\n                              energy at this frequency. Alternately,\n                              the strings \"bass\", \"lowMid\" \"mid\",\n                              \"highMid\", and \"treble\" will return\n                              predefined frequency ranges.</p>\n","type":"Number|String"},{"name":"frequency2","description":"<p>If a second frequency is given,\n                              will return average amount of\n                              energy that exists between the\n                              two frequencies.</p>\n","type":"Number","optional":true}],"return":{"description":"Energy   Energy (volume/amplitude) from\n                            0 and 255.","type":"Number"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3739,"description":"<p>Returns the\n<a href=\"http://en.wikipedia.org/wiki/Spectral_centroid\" target=\"_blank\">\nspectral centroid</a> of the input signal.\n<em>NOTE: analyze() must be called prior to getCentroid(). Analyze()\ntells the FFT to analyze frequency data, and getCentroid() uses\nthe results determine the spectral centroid.</em></p></p>\n","itemtype":"method","name":"getCentroid","return":{"description":"Spectral Centroid Frequency  of the spectral centroid in Hz.","type":"Number"},"example":["\n<div><code>\n function setup(){\ncnv = createCanvas(100,100);\ncnv.mousePressed(userStartAudio);\nsound = new p5.AudioIn();\nsound.start();\nfft = new p5.FFT();\nsound.connect(fft);\n}\n\nfunction draw() {\nif (getAudioContext().state !== 'running') {\n  background(220);\n  text('tap here and enable mic to begin', 10, 20, width - 20);\n  return;\n}\nlet centroidplot = 0.0;\nlet spectralCentroid = 0;\n\nbackground(0);\nstroke(0,255,0);\nlet spectrum = fft.analyze();\nfill(0,255,0); // spectrum is green\n\n//draw the spectrum\nfor (let i = 0; i < spectrum.length; i++){\n  let x = map(log(i), 0, log(spectrum.length), 0, width);\n  let h = map(spectrum[i], 0, 255, 0, height);\n  let rectangle_width = (log(i+1)-log(i))*(width/log(spectrum.length));\n  rect(x, height, rectangle_width, -h )\n}\nlet nyquist = 22050;\n\n// get the centroid\nspectralCentroid = fft.getCentroid();\n\n// the mean_freq_index calculation is for the display.\nlet mean_freq_index = spectralCentroid/(nyquist/spectrum.length);\n\ncentroidplot = map(log(mean_freq_index), 0, log(spectrum.length), 0, width);\n\nstroke(255,0,0); // the line showing where the centroid is will be red\n\nrect(centroidplot, 0, width / spectrum.length, height)\nnoStroke();\nfill(255,255,255);  // text is white\ntext('centroid: ', 10, 20);\ntext(round(spectralCentroid)+' Hz', 10, 40);\n}\n </code></div>"],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3826,"description":"<p>Smooth FFT analysis by averaging with the last analysis frame.</p>\n","itemtype":"method","name":"smooth","params":[{"name":"smoothing","description":"<p>0.0 < smoothing < 1.0.\n                             Defaults to 0.8.</p>\n","type":"Number"}],"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3854,"description":"<p>Returns an array of average amplitude values for a given number\nof frequency bands split equally. N defaults to 16.\n<em>NOTE: analyze() must be called prior to linAverages(). Analyze()\ntells the FFT to analyze frequency data, and linAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"linAverages","params":[{"name":"N","description":"<p>Number of returned frequency groups</p>\n","type":"Number"}],"return":{"description":"linearAverages   Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3889,"description":"<p>Returns an array of average amplitude values of the spectrum, for a given\nset of <a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">\nOctave Bands</a>\n<em>NOTE: analyze() must be called prior to logAverages(). Analyze()\ntells the FFT to analyze frequency data, and logAverages() uses\nthe results to group them into a smaller set of averages.</em></p></p>\n","itemtype":"method","name":"logAverages","params":[{"name":"octaveBands","description":"<p>Array of Octave Bands objects for grouping</p>\n","type":"Array"}],"return":{"description":"logAverages    Array of average amplitude values for each group","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":3925,"description":"<p>Calculates and Returns the 1/N\n<a href=\"https://en.wikipedia.org/wiki/Octave_band\" target=\"_blank\">Octave Bands</a>\nN defaults to 3 and minimum central frequency to 15.625Hz.\n(1/3 Octave Bands ~= 31 Frequency Bands)\nSetting fCtr0 to a central value of a higher octave will ignore the lower bands\nand produce less frequency groups.</p>\n","itemtype":"method","name":"getOctaveBands","params":[{"name":"N","description":"<p>Specifies the 1/N type of generated octave bands</p>\n","type":"Number"},{"name":"fCtr0","description":"<p>Minimum central frequency for the lowest band</p>\n","type":"Number"}],"return":{"description":"octaveBands   Array of octave band objects with their bounds","type":"Array"},"class":"p5.FFT","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4168,"description":"<p>Start an oscillator.</p>\n<p>Starting an oscillator on a user gesture will enable audio in browsers\nthat have a strict autoplay policy, including Chrome and most mobile\ndevices. See also: <code>userStartAudio()</code>.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>startTime in seconds from now.</p>\n","type":"Number","optional":true},{"name":"frequency","description":"<p>frequency in Hz.</p>\n","type":"Number","optional":true}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4218,"description":"<p>Stop an oscillator. Accepts an optional parameter\nto determine how long (in seconds from now) until the\noscillator stops.</p>\n","itemtype":"method","name":"stop","params":[{"name":"secondsFromNow","description":"<p>Time, in seconds from now.</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4238,"description":"<p>Set the amplitude between 0 and 1.0. Or, pass in an object\nsuch as an oscillator to modulate amplitude with an audio signal.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0\n                            or a modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"gain  If no value is provided,\n                            returns the Web Audio API\n                            AudioParam that controls\n                            this oscillator's\n                            gain/amplitude/volume)","type":"AudioParam"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4271,"description":"<p>Returns the value of output gain</p>\n","itemtype":"method","name":"getAmp","return":{"description":"Amplitude value between 0.0 and 1.0","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4285,"description":"<p>Set frequency of an oscillator to a value. Or, pass in an object\nsuch as an oscillator to modulate the frequency with an audio signal.</p>\n","itemtype":"method","name":"freq","params":[{"name":"Frequency","description":"<p>Frequency in Hz\n                                      or modulating signal/oscillator</p>\n","type":"Number|Object"},{"name":"rampTime","description":"<p>Ramp time (in seconds)</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>Schedule this event to happen\n                                 at x seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"Frequency If no value is provided,\n                                returns the Web Audio API\n                                AudioParam that controls\n                                this oscillator's frequency","type":"AudioParam"},"example":["\n<div><code>\nlet osc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playOscillator);\n  osc = new p5.Oscillator(300);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playOscillator() {\n  osc.start();\n  osc.amp(0.5);\n  // start at 700Hz\n  osc.freq(700);\n  // ramp to 60Hz over 0.7 seconds\n  osc.freq(60, 0.7);\n  osc.amp(0, 0.1, 0.7);\n}\n</code></div>"],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4360,"description":"<p>Returns the value of frequency of oscillator</p>\n","itemtype":"method","name":"getFreq","return":{"description":"Frequency of oscillator in Hertz","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4373,"description":"<p>Set type to 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","type":"String"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4386,"description":"<p>Returns  current type of oscillator eg. 'sine', 'triangle', 'sawtooth' or 'square'.</p>\n","itemtype":"method","name":"getType","return":{"description":"type of oscillator  eg . 'sine', 'triangle', 'sawtooth' or 'square'.","type":"String"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4399,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4420,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4444,"description":"<p>Pan between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"pan","params":[{"name":"panning","description":"<p>Number between -1 and 1</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4460,"description":"<p>Returns the current value of panPosition , between Left (-1) and Right (1)</p>\n","itemtype":"method","name":"getPan","return":{"description":"panPosition of oscillator , between Left (-1) and Right (1)","type":"Number"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4494,"description":"<p>Set the phase of an oscillator between 0.0 and 1.0.\nIn this implementation, phase is a delay time\nbased on the oscillator's current frequency.</p>\n","itemtype":"method","name":"phase","params":[{"name":"phase","description":"<p>float between 0.0 and 1.0</p>\n","type":"Number"}],"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4522,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method again\nwill override the initial add() with a new value.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4543,"description":"<p>Multiply the p5.Oscillator's output amplitude\nby a fixed value (i.e. turn it up!). Calling this method\nagain will override the initial mult() with a new value.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with multiplied output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4563,"description":"<p>Scale this oscillator's amplitude values to a given\nrange, and return the oscillator. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Oscillator Returns this oscillator\n                                   with scaled output","type":"p5.Oscillator"},"class":"p5.Oscillator","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4767,"description":"<p>Time until envelope reaches attackLevel</p>\n","itemtype":"property","name":"attackTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4772,"description":"<p>Level once attack is complete.</p>\n","itemtype":"property","name":"attackLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4778,"description":"<p>Time until envelope reaches decayLevel.</p>\n","itemtype":"property","name":"decayTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4784,"description":"<p>Level after decay. The envelope will sustain here until it is released.</p>\n","itemtype":"property","name":"decayLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4790,"description":"<p>Duration of the release portion of the envelope.</p>\n","itemtype":"property","name":"releaseTime","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4796,"description":"<p>Level at the end of the release.</p>\n","itemtype":"property","name":"releaseLevel","class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4833,"description":"<p>Reset the envelope with a series of time/value pairs.</p>\n","itemtype":"method","name":"set","params":[{"name":"attackTime","description":"<p>Time (in seconds) before level\n                               reaches attackLevel</p>\n","type":"Number"},{"name":"attackLevel","description":"<p>Typically an amplitude between\n                               0.0 and 1.0</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time</p>\n","type":"Number"},{"name":"decayLevel","description":"<p>Amplitude (In a standard ADSR envelope,\n                               decayLevel = sustainLevel)</p>\n","type":"Number"},{"name":"releaseTime","description":"<p>Release Time (in seconds)</p>\n","type":"Number"},{"name":"releaseLevel","description":"<p>Amplitude</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime;\nlet l1 = 0.7; // attack level 0.0 to 1.0\nlet t2 = 0.3; // decay time in seconds\nlet l2 = 0.1; // decay level  0.0 to 1.0\nlet l3 = 0.2; // release time in seconds\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n\n  attackTime = map(mouseX, 0, width, 0.0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 20);\n}\n\n// mouseClick triggers envelope if over canvas\nfunction playSound() {\n  env.set(attackTime, l1, t2, l2, l3);\n\n  triOsc.start();\n  env.play(triOsc);\n}\n</code></div>\n"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4895,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":4964,"description":"<p>Set max (attackLevel) and min (releaseLevel) of envelope.</p>\n","itemtype":"method","name":"setRange","params":[{"name":"aLevel","description":"<p>attack level (defaults to 1)</p>\n","type":"Number"},{"name":"rLevel","description":"<p>release level (defaults to 0)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  triOsc.start();\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5037,"description":"<p>Assign a parameter to be controlled by this envelope.\nIf a p5.Sound object is given, then the p5.Envelope will control its\noutput gain. If multiple inputs are provided, the env will\ncontrol all of them.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"inputs","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object","optional":true,"multiple":true}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5055,"description":"<p>Set whether the envelope ramp is linear (default) or exponential.\nExponential ramps can be useful because we perceive amplitude\nand frequency logarithmically.</p>\n","itemtype":"method","name":"setExp","params":[{"name":"isExp","description":"<p>true is exponential, false is linear</p>\n","type":"Boolean"}],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5078,"description":"<p>Play tells the envelope to start acting on a given input.\nIf the input is a p5.sound object (i.e. AudioIn, Oscillator,\nSoundFile), then Envelope will control its output volume.\nEnvelopes can also be used to control any <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Audio Param.</a></p>","itemtype":"method","name":"play","params":[{"name":"unit","description":"<p>A p5.sound object or\n                              Web Audio Param.</p>\n","type":"Object"},{"name":"startTime","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet attackLevel = 1.0;\nlet releaseLevel = 0;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.2;\nlet releaseTime = 0.5;\n\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playEnv);\n\n  env = new p5.Envelope();\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.amp(env);\n  triOsc.freq(220);\n  triOsc.start();\n}\n\nfunction draw() {\n  background(220);\n  text('tap here to play', 5, 20);\n  attackTime = map(mouseX, 0, width, 0, 1.0);\n  attackLevel = map(mouseY, height, 0, 0, 1.0);\n  text('attack time: ' + attackTime, 5, height - 40);\n  text('attack level: ' + attackLevel, 5, height - 20);\n}\n\nfunction playEnv() {\n  // ensure that audio is enabled\n  userStartAudio();\n\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(attackLevel, releaseLevel);\n  env.play();\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5148,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go. Input can be\nany p5.sound object, or a <a href=\"\nhttp://docs.webplatform.org/wiki/apis/webaudio/AudioParam\">\nWeb Audio Param</a>.</p>\n","itemtype":"method","name":"triggerAttack","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5256,"description":"<p>Trigger the Release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"triggerRelease","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"example":["\n<div><code>\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet susPercent = 0.3;\nlet releaseTime = 0.4;\nlet env, triOsc;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  background(220);\n  textAlign(CENTER);\n  textSize(10);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime, susPercent, releaseTime);\n  env.setRange(1.0, 0.0);\n  triOsc = new p5.Oscillator('triangle');\n  triOsc.freq(220);\n\n  cnv.mousePressed(envAttack);\n}\n\nfunction envAttack()  {\n  background(0, 255, 255);\n  text('release to release', width/2, height/2);\n\n  // ensures audio is enabled. See also: `userStartAudio`\n  triOsc.start();\n\n  env.triggerAttack(triOsc);\n}\n\nfunction mouseReleased() {\n  background(220);\n  text('tap to triggerAttack', width/2, height/2);\n\n  env.triggerRelease(triOsc);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5350,"description":"<p>Exponentially ramp to a value using the first two\nvalues from <code><a href=\"#/p5.Envelope/setADSR\">setADSR(attackTime, decayTime)</a></code>\nas <a href=\"https://en.wikipedia.org/wiki/RC_time_constant\">\ntime constants</a> for simple exponential ramps.\nIf the value is higher than current value, it uses attackTime,\nwhile a decrease uses decayTime.</p>\n","itemtype":"method","name":"ramp","params":[{"name":"unit","description":"<p>p5.sound Object or Web Audio Param</p>\n","type":"Object"},{"name":"secondsFromNow","description":"<p>When to trigger the ramp</p>\n","type":"Number"},{"name":"v","description":"<p>Target value</p>\n","type":"Number"},{"name":"v2","description":"<p>Second target value</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet env, osc, amp;\n\nlet attackTime = 0.001;\nlet decayTime = 0.2;\nlet attackLevel = 1;\nlet decayLevel = 0;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  fill(0,255,0);\n  noStroke();\n\n  env = new p5.Envelope();\n  env.setADSR(attackTime, decayTime);\n  osc = new p5.Oscillator();\n  osc.amp(env);\n  amp = new p5.Amplitude();\n\n  cnv.mousePressed(triggerRamp);\n}\n\nfunction triggerRamp() {\n  // ensures audio is enabled. See also: `userStartAudio`\n  osc.start();\n\n  env.ramp(osc, 0, attackLevel, decayLevel);\n}\n\nfunction draw() {\n  background(20);\n  text('tap to play', 10, 20);\n  let h = map(amp.getLevel(), 0, 0.4, 0, height);;\n  rect(0, height, width, -h);\n}\n</code></div>"],"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5460,"description":"<p>Add a value to the p5.Oscillator's output amplitude,\nand return the oscillator. Calling this method\nagain will override the initial add() with new values.</p>\n","itemtype":"method","name":"add","params":[{"name":"number","description":"<p>Constant number to add</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5479,"description":"<p>Multiply the p5.Envelope's output amplitude\nby a fixed value. Calling this method\nagain will override the initial mult() with new values.</p>\n","itemtype":"method","name":"mult","params":[{"name":"number","description":"<p>Constant number to multiply</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5498,"description":"<p>Scale this envelope's amplitude values to a given\nrange, and return the envelope. Calling this method\nagain will override the initial scale() with new values.</p>\n","itemtype":"method","name":"scale","params":[{"name":"inMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"inMax","description":"<p>input range maximum</p>\n","type":"Number"},{"name":"outMin","description":"<p>input range minumum</p>\n","type":"Number"},{"name":"outMax","description":"<p>input range maximum</p>\n","type":"Number"}],"return":{"description":"Envelope Returns this envelope\n                                   with scaled output","type":"p5.Envelope"},"class":"p5.Envelope","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5657,"description":"<p>Set type of noise to 'white', 'pink' or 'brown'.\nWhite is the default.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'white', 'pink' or 'brown'</p>\n","type":"String","optional":true}],"class":"p5.Noise","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":5871,"description":"<p>Set the width of a Pulse object (an oscillator that implements\nPulse Width Modulation).</p>\n","itemtype":"method","name":"width","params":[{"name":"width","description":"<p>Width between the pulses (0 to 1.0,\n                       defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.Pulse","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6066,"itemtype":"property","name":"input","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6070,"itemtype":"property","name":"output","type":"GainNode","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6075,"itemtype":"property","name":"stream","type":"MediaStream|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6080,"itemtype":"property","name":"mediaStream","type":"MediaStreamAudioSourceNode|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6085,"itemtype":"property","name":"currentSource","type":"Number|null","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6090,"description":"<p>Client must allow browser to access their microphone / audioin source.\nDefault: false. Will become true when the client enables access.</p>\n","itemtype":"property","name":"enabled","type":"Boolean","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6098,"description":"<p>Input amplitude, connect to it by default but not to master out</p>\n","itemtype":"property","name":"amplitude","type":"p5.Amplitude","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6114,"description":"<p>Start processing audio input. This enables the use of other\nAudioIn methods like getLevel(). Note that by default, AudioIn\nis not connected to p5.sound's output. So you won't hear\nanything unless you use the connect() method.<br/></p>\n<p>Certain browsers limit access to the user's microphone. For example,\nChrome only allows access from localhost and over https. For this reason,\nyou may want to include an errorCallback—a function that is called in case\nthe browser won't provide mic access.</p>\n","itemtype":"method","name":"start","params":[{"name":"successCallback","description":"<p>Name of a function to call on\n                                  success.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>Name of a function to call if\n                                  there was an error. For example,\n                                  some browsers do not support\n                                  getUserMedia.</p>\n","type":"Function","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6171,"description":"<p>Turn the AudioIn off. If the AudioIn is stopped, it cannot getLevel().\nIf re-starting, the user may be prompted for permission access.</p>\n","itemtype":"method","name":"stop","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6191,"description":"<p>Connect to an audio unit. If no parameter is provided, will\nconnect to the main output (i.e. your speakers).<br/></p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>An object that accepts audio input,\n                        such as an FFT</p>\n","type":"Object","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6216,"description":"<p>Disconnect the AudioIn from all audio units. For example, if\nconnect() had been called, disconnect() will stop sending\nsignal to your speakers.<br/></p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6234,"description":"<p>Read the Amplitude (volume level) of an AudioIn. The AudioIn\nclass contains its own instance of the Amplitude class to help\nmake it easy to get a microphone's volume level. Accepts an\noptional smoothing value (0.0 < 1.0). <em>NOTE: AudioIn must\n.start() before using .getLevel().</em><br/></p>\n","itemtype":"method","name":"getLevel","params":[{"name":"smoothing","description":"<p>Smoothing is 0.0 by default.\n                             Smooths values based on previous values.</p>\n","type":"Number","optional":true}],"return":{"description":"Volume level (between 0.0 and 1.0)","type":"Number"},"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6257,"description":"<p>Set amplitude (volume) of a mic input between 0 and 1.0. <br/></p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>between 0 and 1.0</p>\n","type":"Number"},{"name":"time","description":"<p>ramp time (optional)</p>\n","type":"Number","optional":true}],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6280,"description":"<p>Returns a list of available input sources. This is a wrapper\nfor <a href=\"https://developer.mozilla.org/\nen-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\nMediaDevices.enumerateDevices() - Web APIs | MDN</a>\nand it returns a Promise.</p>\n","itemtype":"method","name":"getSources","params":[{"name":"successCallback","description":"<p>This callback function handles the sources when they\n                                     have been enumerated. The callback function\n                                     receives the deviceList array as its only argument</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>This optional callback receives the error\n                                   message as its argument.</p>\n","type":"Function","optional":true}],"return":{"description":"Returns a Promise that can be used in place of the callbacks, similar\n                           to the enumerateDevices() method","type":"Promise"},"example":["\n <div><code>\n let audioIn;\n\n function setup(){\n   text('getting sources...', 0, 20);\n   audioIn = new p5.AudioIn();\n   audioIn.getSources(gotSources);\n }\n\n function gotSources(deviceList) {\n   if (deviceList.length > 0) {\n     //set the source to the first item in the deviceList array\n     audioIn.setSource(0);\n     let currentSource = deviceList[audioIn.currentSource];\n     text('set source to: ' + currentSource.deviceId, 5, 20, width);\n   }\n }\n </code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6340,"description":"<p>Set the input source. Accepts a number representing a\nposition in the array returned by getSources().\nThis is only available in browsers that support\n <a href=\"https://developer.mozilla.org/\n en-US/docs/Web/API/MediaDevices/enumerateDevices\" target=\"_blank\">\n navigator.mediaDevices.enumerateDevices()</a></p>\n","itemtype":"method","name":"setSource","params":[{"name":"num","description":"<p>position of input source in the array</p>\n","type":"Number"}],"example":["\n<div><code>\nlet audioIn;\n\nfunction setup(){\n  text('getting sources...', 0, 20);\n  audioIn = new p5.AudioIn();\n  audioIn.getSources(gotSources);\n}\n\nfunction gotSources(deviceList) {\n  if (deviceList.length > 0) {\n    //set the source to the first item in the deviceList array\n    audioIn.setSource(0);\n    let currentSource = deviceList[audioIn.currentSource];\n    text('set source to: ' + currentSource.deviceId, 5, 20, width);\n  }\n}\n</code></div>"],"class":"p5.AudioIn","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6462,"description":"<p>In classes that extend\np5.Effect, connect effect nodes\nto the wet parameter</p>\n","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6478,"description":"<p>Set the output volume of the filter.</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number","optional":true},{"name":"rampTime","description":"<p>create a fade that lasts until rampTime</p>\n","type":"Number","optional":true},{"name":"tFromNow","description":"<p>schedule this event to happen in tFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6502,"description":"<p>Link effects together in a chain\nExample usage: filter.chain(reverb, delay, panner);\nMay be used with an open-ended number of arguments</p>\n","itemtype":"method","name":"chain","params":[{"name":"arguments","description":"<p>Chain together multiple sound objects</p>\n","type":"Object","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6525,"description":"<p>Adjust the dry/wet value.</p>\n","itemtype":"method","name":"drywet","params":[{"name":"fade","description":"<p>The desired drywet value (0 - 1.0)</p>\n","type":"Number","optional":true}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6542,"description":"<p>Send output to a p5.js-sound, Web Audio Node, or use signal to\ncontrol an AudioParam</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6557,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Effect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6719,"description":"<p>The p5.Filter is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#BiquadFilterNode\">\nWeb Audio BiquadFilter Node</a>.</p>\n","itemtype":"property","name":"biquadFilter","type":"DelayNode","class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6742,"description":"<p>Filter an audio signal according to a set\nof filter parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance/Width of the filter frequency\n                      from 0.001 to 1000</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6760,"description":"<p>Set the frequency and the resonance of the filter.</p>\n","itemtype":"method","name":"set","params":[{"name":"freq","description":"<p>Frequency in Hz, from 10 to 22050</p>\n","type":"Number","optional":true},{"name":"res","description":"<p>Resonance (Q) from 0.001 to 1000</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6781,"description":"<p>Set the filter frequency, in Hz, from 10 to 22050 (the range of\nhuman hearing, although in reality most people hear in a narrower\nrange).</p>\n","itemtype":"method","name":"freq","params":[{"name":"freq","description":"<p>Filter Frequency</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value  Returns the current frequency value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6811,"description":"<p>Controls either width of a bandpass frequency,\nor the resonance of a low/highpass cutoff frequency.</p>\n","itemtype":"method","name":"res","params":[{"name":"res","description":"<p>Resonance/Width of filter freq\n                     from 0.001 to 1000</p>\n","type":"Number"},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"return":{"description":"value Returns the current res value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6838,"description":"<p>Controls the gain attribute of a Biquad Filter.\nThis is distinctly different from .amp() which is inherited from p5.Effect\n.amp() controls the volume via the output gain node\np5.Filter.gain() controls the gain parameter of a Biquad Filter node.</p>\n","itemtype":"method","name":"gain","params":[{"name":"gain","description":"","type":"Number"}],"return":{"description":"Returns the current or updated gain value","type":"Number"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6864,"description":"<p>Toggle function. Switches between the specified type and allpass</p>\n","itemtype":"method","name":"toggle","return":{"description":"[Toggle value]","type":"Boolean"},"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":6884,"description":"<p>Set the type of a p5.Filter. Possible types include:\n\"lowpass\" (default), \"highpass\", \"bandpass\",\n\"lowshelf\", \"highshelf\", \"peaking\", \"notch\",\n\"allpass\".</p>\n","itemtype":"method","name":"setType","params":[{"name":"t","description":"","type":"String"}],"class":"p5.Filter","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7198,"description":"<p>The p5.EQ is built with abstracted p5.Filter objects.\nTo modify any bands, use methods of the <a\nhref=\"/reference/#/p5.Filter\" title=\"p5.Filter reference\">\np5.Filter</a> API, especially <code>gain</code> and <code>freq</code>.\nBands are stored in an array, with indices 0 - 3, or 0 - 7</p>\n","itemtype":"property","name":"bands","type":"Array","class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7239,"description":"<p>Process an input by connecting it to the EQ</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Audio source</p>\n","type":"Object"}],"class":"p5.EQ","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7629,"description":"<p><a title=\"Web Audio Panner docs\"  href=\n\"https://developer.mozilla.org/en-US/docs/Web/API/PannerNode\">\nWeb Audio Spatial Panner Node</a></p>\n<p>Properties include<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-PanningModelType\">Panning Model</a>\n : \"equal power\" or \"HRTF\"<br>\n <a href=\"https://www.w3.org/TR/webaudio/#idl-def-DistanceModelType\">DistanceModel</a>\n: \"linear\", \"inverse\", or \"exponential\"</p>\n","itemtype":"property","name":"panner","type":"AudioNode","class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7654,"description":"<p>Connect an audio sorce</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Input source</p>\n","type":"Object"}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7668,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"set","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7687,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7694,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7701,"description":"<p>Getter and setter methods for position coordinates</p>\n","itemtype":"method","name":"positionZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7753,"description":"<p>Set the X,Y,Z position of the Panner</p>\n","itemtype":"method","name":"orient","params":[{"name":"xVal","description":"","type":"Number"},{"name":"yVal","description":"","type":"Number"},{"name":"zVal","description":"","type":"Number"},{"name":"time","description":"","type":"Number"}],"return":{"description":"Updated x, y, z values as an array","type":"Array"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7772,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientX","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7779,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientY","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7786,"description":"<p>Getter and setter methods for orient coordinates</p>\n","itemtype":"method","name":"orientZ","return":{"description":"updated coordinate value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7838,"description":"<p>Set the rolloff factor and max distance</p>\n","itemtype":"method","name":"setFalloff","params":[{"name":"maxDistance","description":"","type":"Number","optional":true},{"name":"rolloffFactor","description":"","type":"Number","optional":true}],"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7852,"description":"<p>Maxium distance between the source and the listener</p>\n","itemtype":"method","name":"maxDist","params":[{"name":"maxDistance","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7869,"description":"<p>How quickly the volume is reduced as the source moves away from the listener</p>\n","itemtype":"method","name":"rollof","params":[{"name":"rolloffFactor","description":"","type":"Number"}],"return":{"description":"updated value","type":"Number"},"class":"p5.Panner3D","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7989,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"leftDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":7999,"description":"<p>The p5.Delay is built with two\n<a href=\"http://www.w3.org/TR/webaudio/#DelayNode\">\nWeb Audio Delay Nodes</a>, one for each stereo channel.</p>\n","itemtype":"property","name":"rightDelay","type":"DelayNode","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8049,"description":"<p>Add delay to an audio signal according to a set\nof delay parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"Signal","description":"<p>An object that outputs audio</p>\n","type":"Object"},{"name":"delayTime","description":"<p>Time (in seconds) of the delay/echo.\n                             Some browsers limit delayTime to\n                             1 second.</p>\n","type":"Number","optional":true},{"name":"feedback","description":"<p>sends the delay back through itself\n                             in a loop that decreases in volume\n                             each time.</p>\n","type":"Number","optional":true},{"name":"lowPass","description":"<p>Cutoff frequency. Only frequencies\n                             below the lowPass will be part of the\n                             delay.</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8094,"description":"<p>Set the delay (echo) time, in seconds. Usually this value will be\na floating point number between 0.0 and 1.0.</p>\n","itemtype":"method","name":"delayTime","params":[{"name":"delayTime","description":"<p>Time (in seconds) of the delay</p>\n","type":"Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8116,"description":"<p>Feedback occurs when Delay sends its signal back through its input\nin a loop. The feedback amount determines how much signal to send each\ntime through the loop. A feedback greater than 1.0 is not desirable because\nit will increase the overall output each time through the loop,\ncreating an infinite feedback loop. The default value is 0.5</p>\n","itemtype":"method","name":"feedback","params":[{"name":"feedback","description":"<p>0.0 to 1.0, or an object such as an\n                                Oscillator that can be used to\n                                modulate this param</p>\n","type":"Number|Object"}],"return":{"description":"Feedback value","type":"Number"},"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8148,"description":"<p>Set a lowpass filter frequency for the delay. A lowpass filter\nwill cut off any frequencies higher than the filter frequency.</p>\n","itemtype":"method","name":"filter","params":[{"name":"cutoffFreq","description":"<p>A lowpass filter will cut off any\n                            frequencies higher than the filter frequency.</p>\n","type":"Number|Object"},{"name":"res","description":"<p>Resonance of the filter frequency\n                            cutoff, or an object (i.e. a p5.Oscillator)\n                            that can be used to modulate this parameter.\n                            High numbers (i.e. 15) will produce a resonance,\n                            low numbers (i.e. .2) will produce a slope.</p>\n","type":"Number|Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8170,"description":"<p>Choose a preset type of delay. 'pingPong' bounces the signal\nfrom the left to the right channel to produce a stereo effect.\nAny other parameter will revert to the default delay setting.</p>\n","itemtype":"method","name":"setType","params":[{"name":"type","description":"<p>'pingPong' (1) or 'default' (0)</p>\n","type":"String|Number"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8223,"description":"<p>Set the output level of the delay effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8234,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8242,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Delay","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8409,"description":"<p>Connect a source to the reverb, and assign reverb parameters.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"},{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8446,"description":"<p>Set the reverb settings. Similar to .process(), but without\nassigning a new input.</p>\n","itemtype":"method","name":"set","params":[{"name":"seconds","description":"<p>Duration of the reverb, in seconds.\n                         Min: 0, Max: 10. Defaults to 3.</p>\n","type":"Number","optional":true},{"name":"decayRate","description":"<p>Percentage of decay with each echo.\n                          Min: 0, Max: 100. Defaults to 2.</p>\n","type":"Number","optional":true},{"name":"reverse","description":"<p>Play the reverb backwards or forwards.</p>\n","type":"Boolean","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8482,"description":"<p>Set the output level of the reverb effect.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8493,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8501,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Reverb","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8621,"description":"<p>Internally, the p5.Convolver uses the a\n<a href=\"http://www.w3.org/TR/webaudio/#ConvolverNode\">\nWeb Audio Convolver Node</a>.</p>\n","itemtype":"property","name":"convolverNode","type":"ConvolverNode","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8645,"description":"<p>If you load multiple impulse files using the .addImpulse method,\nthey will be stored as Objects in this Array. Toggle between them\nwith the <code>toggleImpulse(id)</code> method.</p>\n","itemtype":"property","name":"impulses","type":"Array","class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8737,"description":"<p>Connect a source to the convolver.</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n\n</code></div>"],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8786,"description":"<p>Load and assign a new Impulse Response to the p5.Convolver.\nThe impulse is added to the <code>.impulses</code> array. Previous\nimpulses can be accessed with the <code>.toggleImpulse(id)</code>\nmethod.</p>\n","itemtype":"method","name":"addImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8808,"description":"<p>Similar to .addImpulse, except that the <code>.impulses</code>\nArray is reset to save memory. A new <code>.impulses</code>\narray is created with this impulse as the only item.</p>\n","itemtype":"method","name":"resetImpulse","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function (optional)</p>\n","type":"Function"},{"name":"errorCallback","description":"<p>function (optional)</p>\n","type":"Function"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8831,"description":"<p>If you have used <code>.addImpulse()</code> to add multiple impulses\nto a p5.Convolver, then you can use this method to toggle between\nthe items in the <code>.impulses</code> Array. Accepts a parameter\nto identify which impulse you wish to use, identified either by its\noriginal filename (String) or by its position in the <code>.impulses\n</code> Array (Number).<br/>\nYou can access the objects in the .impulses Array directly. Each\nObject has two attributes: an <code>.audioBuffer</code> (type:\nWeb Audio <a href=\"\nhttp://webaudio.github.io/web-audio-api/#the-audiobuffer-interface\">\nAudioBuffer)</a> and a <code>.name</code>, a String that corresponds\nwith the original filename.</p>\n","itemtype":"method","name":"toggleImpulse","params":[{"name":"id","description":"<p>Identify the impulse by its original filename\n                          (String), or by its position in the\n                          <code>.impulses</code> Array (Number).</p>\n","type":"String|Number"}],"class":"p5.Convolver","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":8885,"description":"<p>Create a p5.Convolver. Accepts a path to a soundfile\nthat will be used to generate an impulse response.</p>\n","itemtype":"method","name":"createConvolver","params":[{"name":"path","description":"<p>path to a sound file</p>\n","type":"String"},{"name":"callback","description":"<p>function to call if loading is successful.\n                              The object will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true},{"name":"errorCallback","description":"<p>function to call if loading is not successful.\n                              A custom error will be passed in as the argument\n                              to the callback function.</p>\n","type":"Function","optional":true}],"return":{"description":"","type":"p5.Convolver"},"example":["\n<div><code>\nlet cVerb, sound;\nfunction preload() {\n  // We have both MP3 and OGG versions of all sound assets\n  soundFormats('ogg', 'mp3');\n\n  // Try replacing 'bx-spring' with other soundfiles like\n  // 'concrete-tunnel' 'small-plate' 'drum' 'beatbox'\n  cVerb = createConvolver('assets/bx-spring.mp3');\n\n  // Try replacing 'Damscray_DancingTiger' with\n  // 'beat', 'doorbell', lucky_dragons_-_power_melody'\n  sound = loadSound('assets/Damscray_DancingTiger.mp3');\n}\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSound);\n  background(220);\n  text('tap to play', 20, 20);\n\n  // disconnect from main output...\n  sound.disconnect();\n\n  // ...and process with cVerb\n  // so that we only hear the convolution\n  cVerb.process(sound);\n}\n\nfunction playSound() {\n  sound.play();\n}\n</code></div>"],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9084,"description":"<p>Set the global tempo, in beats per minute, for all\np5.Parts. This method will impact all active p5.Parts.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9173,"description":"<p>Array of values to pass into the callback\nat each step of the phrase. Depending on the callback\nfunction's requirements, these values may be numbers,\nstrings, or an object with multiple parameters.\nZero (0) indicates a rest.</p>\n","itemtype":"property","name":"sequence","type":"Array","class":"p5.Phrase","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9263,"description":"<p>Set the tempo of this part, in Beats Per Minute.</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9278,"description":"<p>Returns the tempo, in Beats Per Minute, of this part.</p>\n","itemtype":"method","name":"getBPM","return":{"description":"","type":"Number"},"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9291,"description":"<p>Start playback of this part. It will play\nthrough all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"start","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9311,"description":"<p>Loop playback of this part. It will begin\nlooping through all of its phrases at a speed\ndetermined by setBPM.</p>\n","itemtype":"method","name":"loop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9333,"description":"<p>Tell the part to stop looping.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9349,"description":"<p>Stop the part and cue it to step 0. Playback will resume from the begining of the Part when it is played again.</p>\n","itemtype":"method","name":"stop","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9363,"description":"<p>Pause the part. Playback will resume\nfrom the current step.</p>\n","itemtype":"method","name":"pause","params":[{"name":"time","description":"<p>seconds from now</p>\n","type":"Number"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9379,"description":"<p>Add a p5.Phrase to this Part.</p>\n","itemtype":"method","name":"addPhrase","params":[{"name":"phrase","description":"<p>reference to a p5.Phrase</p>\n","type":"p5.Phrase"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9406,"description":"<p>Remove a phrase from this part, based on the name it was\ngiven when it was created.</p>\n","itemtype":"method","name":"removePhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9424,"description":"<p>Get a phrase from this part, based on the name it was\ngiven when it was created. Now you can modify its array.</p>\n","itemtype":"method","name":"getPhrase","params":[{"name":"phraseName","description":"","type":"String"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9442,"description":"<p>Find all sequences with the specified name, and replace their patterns with the specified array.</p>\n","itemtype":"method","name":"replaceSequence","params":[{"name":"phraseName","description":"","type":"String"},{"name":"sequence","description":"<p>Array of values to pass into the callback\n                          at each step of the phrase.</p>\n","type":"Array"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9473,"description":"<p>Set the function that will be called at every step. This will clear the previous function.</p>\n","itemtype":"method","name":"onStep","params":[{"name":"callback","description":"<p>The name of the callback\n                            you want to fire\n                            on every beat/tatum.</p>\n","type":"Function"}],"class":"p5.Part","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9542,"description":"<p>Start playback of the score.</p>\n","itemtype":"method","name":"start","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9555,"description":"<p>Stop playback of the score.</p>\n","itemtype":"method","name":"stop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9569,"description":"<p>Pause playback of the score.</p>\n","itemtype":"method","name":"pause","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9581,"description":"<p>Loop playback of the score.</p>\n","itemtype":"method","name":"loop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9594,"description":"<p>Stop looping playback of the score. If it\nis currently playing, this will go into effect\nafter the current round of playback completes.</p>\n","itemtype":"method","name":"noLoop","class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9628,"description":"<p>Set the tempo for all parts in the score</p>\n","itemtype":"method","name":"setBPM","params":[{"name":"BPM","description":"<p>Beats Per Minute</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Seconds from now</p>\n","type":"Number"}],"class":"p5.Score","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9729,"description":"<p>Getters and Setters, setting any paramter will result in a change in the clock's\nfrequency, that will be reflected after the next callback\nbeats per minute (defaults to 60)</p>\n","itemtype":"property","name":"bpm","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9750,"description":"<p>number of quarter notes in a measure (defaults to 4)</p>\n","itemtype":"property","name":"timeSignature","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9770,"description":"<p>length of the loops interval</p>\n","itemtype":"property","name":"interval","type":"Number|String","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9787,"description":"<p>how many times the callback has been called so far</p>\n","itemtype":"property","name":"iterations","type":"Number","readonly":"","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9800,"description":"<p>musicalTimeMode uses <a href = \"https://github.com/Tonejs/Tone.js/wiki/Time\">Tone.Time</a> convention\ntrue if string, false if number</p>\n","itemtype":"property","name":"musicalTimeMode","type":"Boolean","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9808,"description":"<p>musicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9816,"description":"<p>Set a limit to the number of loops to play. defaults to Infinity</p>\n","itemtype":"property","name":"maxIterations","type":"Number","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9826,"description":"<p>Do not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded</p>\n<p>The callback should only be called until maxIterations is reached</p>\n","class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9841,"description":"<p>Start the loop</p>\n","itemtype":"method","name":"start","params":[{"name":"timeFromNow","description":"<p>schedule a starting time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9860,"description":"<p>Stop the loop</p>\n","itemtype":"method","name":"stop","params":[{"name":"timeFromNow","description":"<p>schedule a stopping time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9878,"description":"<p>Pause the loop</p>\n","itemtype":"method","name":"pause","params":[{"name":"timeFromNow","description":"<p>schedule a pausing time</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":9896,"description":"<p>Synchronize loops. Use this method to start two or more loops in synchronization\nor to start a loop in synchronization with a loop that is already playing\nThis method will schedule the implicit loop in sync with the explicit master loop\ni.e. loopToStart.syncedStart(loopToSyncWith)</p>\n","itemtype":"method","name":"syncedStart","params":[{"name":"otherLoop","description":"<p>a p5.SoundLoop to sync with</p>\n","type":"Object"},{"name":"timeFromNow","description":"<p>Start the loops in sync after timeFromNow seconds</p>\n","type":"Number","optional":true}],"class":"p5.SoundLoop","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10068,"description":"<p>The p5.Compressor is built with a <a href=\"https://www.w3.org/TR/webaudio/#the-dynamicscompressornode-interface\"\n   target=\"_blank\" title=\"W3 spec for Dynamics Compressor Node\">Web Audio Dynamics Compressor Node\n   </a></p>\n","itemtype":"property","name":"compressor","type":"AudioNode","class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10084,"description":"<p>Performs the same function as .connect, but also accepts\noptional parameters to set compressor's audioParams</p>\n","itemtype":"method","name":"process","params":[{"name":"src","description":"<p>Sound source to be connected</p>\n","type":"Object"},{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number","optional":true},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10112,"description":"<p>Set the paramters of a compressor.</p>\n","itemtype":"method","name":"set","params":[{"name":"attack","description":"<p>The amount of time (in seconds) to reduce the gain by 10dB,\n                           default = .003, range 0 - 1</p>\n","type":"Number"},{"name":"knee","description":"<p>A decibel value representing the range above the\n                           threshold where the curve smoothly transitions to the \"ratio\" portion.\n                           default = 30, range 0 - 40</p>\n","type":"Number"},{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number"},{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10152,"description":"<p>Get current attack or set value w/ time ramp</p>\n","itemtype":"method","name":"attack","params":[{"name":"attack","description":"<p>Attack is the amount of time (in seconds) to reduce the gain by 10dB,\n                         default = .003, range 0 - 1</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10178,"description":"<p>Get current knee or set value w/ time ramp</p>\n","itemtype":"method","name":"knee","params":[{"name":"knee","description":"<p>A decibel value representing the range above the\n                       threshold where the curve smoothly transitions to the \"ratio\" portion.\n                       default = 30, range 0 - 40</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10204,"description":"<p>Get current ratio or set value w/ time ramp</p>\n","itemtype":"method","name":"ratio","params":[{"name":"ratio","description":"<p>The amount of dB change in input for a 1 dB change in output\n                           default = 12, range 1 - 20</p>\n","type":"Number","optional":true},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10228,"description":"<p>Get current threshold or set value w/ time ramp</p>\n","itemtype":"method","name":"threshold","params":[{"name":"threshold","description":"<p>The decibel value above which the compression will start taking effect\n                           default = -24, range -100 - 0</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10252,"description":"<p>Get current release or set value w/ time ramp</p>\n","itemtype":"method","name":"release","params":[{"name":"release","description":"<p>The amount of time (in seconds) to increase the gain by 10dB\n                           default = .25, range 0 - 1</p>\n","type":"Number"},{"name":"time","description":"<p>Assign time value to schedule the change in value</p>\n","type":"Number","optional":true}],"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10277,"description":"<p>Return the current reduction value</p>\n","itemtype":"method","name":"reduction","return":{"description":"Value of the amount of gain reduction that is applied to the signal","type":"Number"},"class":"p5.Compressor","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10419,"description":"<p>isDetected is set to true when a peak is detected.</p>\n","itemtype":"attribute","name":"isDetected","type":"Boolean","default":"false","class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10432,"description":"<p>The update method is run in the draw loop.</p>\n<p>Accepts an FFT object. You must call .analyze()\non the FFT object prior to updating the peakDetect\nbecause it relies on a completed FFT analysis.</p>\n","itemtype":"method","name":"update","params":[{"name":"fftObject","description":"<p>A p5.FFT object</p>\n","type":"p5.FFT"}],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10470,"description":"<p>onPeak accepts two arguments: a function to call when\na peak is detected. The value of the peak,\nbetween 0.0 and 1.0, is passed to the callback.</p>\n","itemtype":"method","name":"onPeak","params":[{"name":"callback","description":"<p>Name of a function that will\n                            be called when a peak is\n                            detected.</p>\n","type":"Function"},{"name":"val","description":"<p>Optional value to pass\n                            into the function when\n                            a peak is detected.</p>\n","type":"Object","optional":true}],"example":["\n<div><code>\nvar cnv, soundFile, fft, peakDetect;\nvar ellipseWidth = 0;\n\nfunction preload() {\n  soundFile = loadSound('assets/beat.mp3');\n}\n\nfunction setup() {\n  cnv = createCanvas(100,100);\n  textAlign(CENTER);\n\n  fft = new p5.FFT();\n  peakDetect = new p5.PeakDetect();\n\n  setupSound();\n\n  // when a beat is detected, call triggerBeat()\n  peakDetect.onPeak(triggerBeat);\n}\n\nfunction draw() {\n  background(0);\n  fill(255);\n  text('click to play', width/2, height/2);\n\n  fft.analyze();\n  peakDetect.update(fft);\n\n  ellipseWidth *= 0.95;\n  ellipse(width/2, height/2, ellipseWidth, ellipseWidth);\n}\n\n// this function is called by peakDetect.onPeak\nfunction triggerBeat() {\n  ellipseWidth = 50;\n}\n\n// mouseclick starts/stops sound\nfunction setupSound() {\n  cnv.mouseClicked( function() {\n    if (soundFile.isPlaying() ) {\n      soundFile.stop();\n    } else {\n      soundFile.play();\n    }\n  });\n}\n</code></div>"],"class":"p5.PeakDetect","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10676,"description":"<p>Connect a specific device to the p5.SoundRecorder.\nIf no parameter is given, p5.SoundRecorer will record\nall audible p5.sound from your sketch.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"unit","description":"<p>p5.sound object or a web audio unit\n                       that outputs sound</p>\n","type":"Object","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10703,"description":"<p>Start recording. To access the recording, provide\na p5.SoundFile as the first parameter. The p5.SoundRecorder\nwill send its recording to that p5.SoundFile for playback once\nrecording is complete. Optional parameters include duration\n(in seconds) of the recording, and a callback function that\nwill be called once the complete recording has been\ntransfered to the p5.SoundFile.</p>\n","itemtype":"method","name":"record","params":[{"name":"soundFile","description":"<p>p5.SoundFile</p>\n","type":"p5.SoundFile"},{"name":"duration","description":"<p>Time (in seconds)</p>\n","type":"Number","optional":true},{"name":"callback","description":"<p>The name of a function that will be\n                              called once the recording completes</p>\n","type":"Function","optional":true}],"class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10739,"description":"<p>Stop the recording. Once the recording is stopped,\nthe results will be sent to the p5.SoundFile that\nwas given on .record(), and if a callback function\nwas provided on record, that function will be called.</p>\n","itemtype":"method","name":"stop","class":"p5.SoundRecorder","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10864,"description":"<p>The p5.Distortion is built with a\n<a href=\"http://www.w3.org/TR/webaudio/#WaveShaperNode\">\nWeb Audio WaveShaper Node</a>.</p>\n","itemtype":"property","name":"WaveShaperNode","type":"AudioNode","class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10883,"description":"<p>Process a sound source, optionally specify amount and oversample values.</p>\n","itemtype":"method","name":"process","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10900,"description":"<p>Set the amount and oversample of the waveshaper distortion.</p>\n","itemtype":"method","name":"set","params":[{"name":"amount","description":"<p>Unbounded distortion amount.\n                               Normal values range from 0-1.</p>\n","type":"Number","optional":true,"optdefault":"0.25"},{"name":"oversample","description":"<p>'none', '2x', or '4x'.</p>\n","type":"String","optional":true,"optdefault":"'none'"}],"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10923,"description":"<p>Return the distortion amount, typically between 0-1.</p>\n","itemtype":"method","name":"getAmount","return":{"description":"Unbounded distortion amount.\n                 Normal values range from 0-1.","type":"Number"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":10937,"description":"<p>Return the oversampling.</p>\n","itemtype":"method","name":"getOversample","return":{"description":"Oversample can either be 'none', '2x', or '4x'.","type":"String"},"class":"p5.Distortion","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11055,"description":"<p>Connect a source to the gain node.</p>\n","itemtype":"method","name":"setInput","params":[{"name":"src","description":"<p>p5.sound / Web Audio object with a sound\n                         output.</p>\n","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11070,"description":"<p>Send output to a p5.sound or web audio object</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11084,"description":"<p>Disconnect all output.</p>\n","itemtype":"method","name":"disconnect","class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11098,"description":"<p>Set the output level of the gain node.</p>\n","itemtype":"method","name":"amp","params":[{"name":"volume","description":"<p>amplitude between 0 and 1.0</p>\n","type":"Number"},{"name":"rampTime","description":"<p>create a fade that lasts rampTime</p>\n","type":"Number","optional":true},{"name":"timeFromNow","description":"<p>schedule this event to happen\n                              seconds from now</p>\n","type":"Number","optional":true}],"class":"p5.Gain","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11181,"description":"<p>Connect to p5 objects or Web Audio Nodes</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"","type":"Object"}],"class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11194,"description":"<p>Disconnect from soundOut</p>\n","itemtype":"method","name":"disconnect","class":"p5.AudioVoice","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11322,"description":"<p>Getters and Setters</p>\n","itemtype":"property","name":"attack","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11328,"itemtype":"property","name":"decay","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11333,"itemtype":"property","name":"sustain","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11338,"itemtype":"property","name":"release","type":"Number","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11379,"description":"<p>Play tells the MonoSynth to start playing a note. This method schedules\nthe calling of .triggerAttack and .triggerRelease.</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz.</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope. Defaults to 0.15 seconds.</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  textAlign(CENTER);\n  text('tap to play', width/2, height/2);\n\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  let note = random(['Fb4', 'G4']);\n  // note velocity (volume, from 0 to 1)\n  let velocity = random();\n  // time from now (in seconds)\n  let time = 0;\n  // note duration (in seconds)\n  let dur = 1/6;\n\n  monoSynth.play(note, velocity, time, dur);\n}\n</code></div>\n"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11431,"description":"<p>Trigger the Attack, and Decay portion of the Envelope.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","params":[{"name":"note","description":"<p>the note you want to play, specified as a\n                               frequency in Hertz (Number) or as a midi\n                               value in Note/Octave format (\"C4\", \"Eb3\"...etc\")\n                               See <a href = \"https://github.com/Tonejs/Tone.js/wiki/Instruments\">\n                               Tone</a>. Defaults to 440 hz</p>\n","type":"String | Number"},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true}],"itemtype":"method","name":"triggerAttack","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11478,"description":"<p>Trigger the release of the Envelope. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","params":[{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number"}],"itemtype":"method","name":"triggerRelease","example":["\n<div><code>\nlet monoSynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(triggerAttack);\n  background(220);\n  text('tap here for attack, let go to release', 5, 20, width - 20);\n  monoSynth = new p5.MonoSynth();\n}\n\nfunction triggerAttack() {\n  userStartAudio();\n\n  monoSynth.triggerAttack(\"E3\");\n}\n\nfunction mouseReleased() {\n  monoSynth.triggerRelease();\n}\n</code></div>"],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11516,"description":"<p>Set values like a traditional\n<a href=\"https://en.wikipedia.org/wiki/Synthesizer#/media/File:ADSR_parameter.svg\">\nADSR envelope\n</a>.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number"},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11544,"description":"<p>MonoSynth amp</p>\n","itemtype":"method","name":"amp","params":[{"name":"vol","description":"<p>desired volume</p>\n","type":"Number"},{"name":"rampTime","description":"<p>Time to reach new volume</p>\n","type":"Number","optional":true}],"return":{"description":"new volume value","type":"Number"},"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11564,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11578,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11592,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.MonoSynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11742,"description":"<p>An object that holds information about which notes have been played and\nwhich notes are currently being played. New notes are added as keys\non the fly. While a note has been attacked, but not released, the value of the\nkey is the audiovoice which is generating that note. When notes are released,\nthe value of the key becomes undefined.</p>\n","itemtype":"property","name":"notes","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11755,"description":"<p>A PolySynth must have at least 1 voice, defaults to 8</p>\n","itemtype":"property","name":"polyvalue","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11761,"description":"<p>Monosynth that generates the sound for each note that is triggered. The\np5.PolySynth defaults to using the p5.MonoSynth as its voice.</p>\n","itemtype":"property","name":"AudioVoice","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11800,"description":"<p>Play a note by triggering noteAttack and noteRelease with sustain time</p>\n","itemtype":"method","name":"play","params":[{"name":"note","description":"<p>midi note to play (ranging from 0 to 127 - 60 being a middle C)</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds) at which to play</p>\n","type":"Number","optional":true},{"name":"sustainTime","description":"<p>time to sustain before releasing the envelope</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth;\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playSynth);\n  background(220);\n  text('click to play', 20, 20);\n\n  polySynth = new p5.PolySynth();\n}\n\nfunction playSynth() {\n  userStartAudio();\n\n  // note duration (in seconds)\n  let dur = 1.5;\n\n  // time from now (in seconds)\n  let time = 0;\n\n  // velocity (volume, from 0 to 1)\n  let vel = 0.1;\n\n  // notes can overlap with each other\n  polySynth.play('G2', vel, 0, dur);\n  polySynth.play('C3', vel, time += 1/3, dur);\n  polySynth.play('G3', vel, time += 1/3, dur);\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11849,"description":"<p>noteADSR sets the envelope for a specific note that has just been triggered.\nUsing this method modifies the envelope of whichever audiovoice is being used\nto play the desired note. The envelope should be reset before noteRelease is called\nin order to prevent the modified envelope from being used on other notes.</p>\n","itemtype":"method","name":"noteADSR","params":[{"name":"note","description":"<p>Midi note on which ADSR should be set.</p>\n","type":"Number","optional":true},{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                              reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                              reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                              where 1.0 = attackLevel, 0.0 = releaseLevel.\n                              The susRatio determines the decayLevel and the level at which the\n                              sustain portion of the envelope will sustain.\n                              For example, if attackLevel is 0.4, releaseLevel is 0,\n                              and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                              increased to 1.0 (using <code>setRange</code>),\n                              then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11881,"description":"<p>Set the PolySynths global envelope. This method modifies the envelopes of each\nmonosynth so that all notes are played with this envelope.</p>\n","itemtype":"method","name":"setADSR","params":[{"name":"attackTime","description":"<p>Time (in seconds before envelope\n                               reaches Attack Level</p>\n","type":"Number","optional":true},{"name":"decayTime","description":"<p>Time (in seconds) before envelope\n                               reaches Decay/Sustain Level</p>\n","type":"Number","optional":true},{"name":"susRatio","description":"<p>Ratio between attackLevel and releaseLevel, on a scale from 0 to 1,\n                               where 1.0 = attackLevel, 0.0 = releaseLevel.\n                               The susRatio determines the decayLevel and the level at which the\n                               sustain portion of the envelope will sustain.\n                               For example, if attackLevel is 0.4, releaseLevel is 0,\n                               and susAmt is 0.5, the decayLevel would be 0.2. If attackLevel is\n                               increased to 1.0 (using <code>setRange</code>),\n                               then decayLevel would increase proportionally, to become 0.5.</p>\n","type":"Number","optional":true},{"name":"releaseTime","description":"<p>Time in seconds from now (defaults to 0)</p>\n","type":"Number","optional":true}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":11909,"description":"<p>Trigger the Attack, and Decay portion of a MonoSynth.\nSimilar to holding down a key on a piano, but it will\nhold the sustain level until you let go.</p>\n","itemtype":"method","name":"noteAttack","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.</p>\n","type":"Number","optional":true},{"name":"velocity","description":"<p>velocity of the note to play (ranging from 0 to 1)/</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time from now (in seconds)</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12021,"description":"<p>Trigger the Release of an AudioVoice note. This is similar to releasing\nthe key on a piano and letting the sound fade according to the\nrelease level and release time.</p>\n","itemtype":"method","name":"noteRelease","params":[{"name":"note","description":"<p>midi note on which attack should be triggered.\n                                  If no value is provided, all notes will be released.</p>\n","type":"Number","optional":true},{"name":"secondsFromNow","description":"<p>time to trigger the release</p>\n","type":"Number","optional":true}],"example":["\n<div><code>\nlet polySynth = new p5.PolySynth();\nlet pitches = ['G', 'D', 'G', 'C'];\nlet octaves = [2, 3, 4];\n\nfunction setup() {\n  let cnv = createCanvas(100, 100);\n  cnv.mousePressed(playChord);\n  background(220);\n  text('tap to play', 20, 20);\n}\n\nfunction playChord() {\n  userStartAudio();\n\n  // play a chord: multiple notes at the same time\n  for (let i = 0; i < 4; i++) {\n    let note = random(pitches) + random(octaves);\n    polySynth.noteAttack(note, 0.1);\n  }\n}\n\nfunction mouseReleased() {\n  // release all voices\n  polySynth.noteRelease();\n}\n</code></div>\n"],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12105,"description":"<p>Connect to a p5.sound / Web Audio object.</p>\n","itemtype":"method","name":"connect","params":[{"name":"unit","description":"<p>A p5.sound or Web Audio object</p>\n","type":"Object"}],"class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12119,"description":"<p>Disconnect all outputs</p>\n","itemtype":"method","name":"disconnect","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"},{"file":"lib/addons/p5.sound.js","line":12133,"description":"<p>Get rid of the MonoSynth and free up its resources / memory.</p>\n","itemtype":"method","name":"dispose","class":"p5.PolySynth","module":"p5.sound","submodule":"p5.sound"}],"warnings":[{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:120"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:216"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:316"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:457"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/fes_core.js:1001"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:223"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/sketch_reader.js:248"},{"message":"replacing incorrect tag: returns with return","line":" src/core/friendly_errors/validate_params.js:336"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:12"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:81"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:115"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:184"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:219"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:259"},{"message":"unknown tag: alt","line":" src/core/shape/attributes.js:331"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:13"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:92"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:130"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:185"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:264"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:358"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:398"},{"message":"unknown tag: alt","line":" src/core/shape/curves.js:493"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:20"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:67"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:293"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:415"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:460"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:524"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:583"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:668"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:733"},{"message":"unknown tag: alt","line":" src/core/shape/vertex.js:826"},{"message":"unknown tag: alt","line":" src/core/constants.js:66"},{"message":"unknown tag: alt","line":" src/core/constants.js:84"},{"message":"unknown tag: alt","line":" src/core/constants.js:102"},{"message":"unknown tag: alt","line":" src/core/constants.js:120"},{"message":"unknown tag: alt","line":" src/core/constants.js:138"},{"message":"unknown tag: alt","line":" src/core/environment.js:20"},{"message":"unknown tag: alt","line":" src/core/environment.js:52"},{"message":"unknown tag: alt","line":" src/core/environment.js:79"},{"message":"unknown tag: alt","line":" src/core/environment.js:129"},{"message":"unknown tag: alt","line":" src/core/environment.js:160"},{"message":"unknown tag: alt","line":" src/core/environment.js:228"},{"message":"unknown tag: alt","line":" src/core/environment.js:331"},{"message":"unknown tag: alt","line":" src/core/environment.js:354"},{"message":"unknown tag: alt","line":" src/core/environment.js:372"},{"message":"unknown tag: alt","line":" src/core/environment.js:390"},{"message":"unknown tag: alt","line":" src/core/environment.js:405"},{"message":"unknown tag: alt","line":" src/core/environment.js:421"},{"message":"unknown tag: alt","line":" src/core/environment.js:500"},{"message":"unknown tag: alt","line":" src/core/environment.js:550"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:586"},{"message":"replacing incorrect tag: returns with return","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:605"},{"message":"unknown tag: alt","line":" src/core/environment.js:660"},{"message":"unknown tag: alt","line":" src/core/environment.js:691"},{"message":"unknown tag: alt","line":" src/core/environment.js:713"},{"message":"replacing incorrect tag: function with method","line":" src/core/internationalization.js:105"},{"message":"replacing incorrect tag: returns with return","line":" src/core/internationalization.js:105"},{"message":"unknown tag: alt","line":" src/core/main.js:42"},{"message":"unknown tag: alt","line":" src/core/main.js:83"},{"message":"unknown tag: alt","line":" src/core/main.js:114"},{"message":"unknown tag: alt","line":" src/core/main.js:415"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:47"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:114"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:154"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:189"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:246"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:292"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:354"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:403"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:454"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:510"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:551"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:592"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:639"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:678"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:725"},{"message":"unknown tag: alt","line":" src/core/p5.Element.js:763"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:70"},{"message":"unknown tag: alt","line":" src/core/p5.Graphics.js:122"},{"message":"unknown tag: alt","line":" src/core/reference.js:7"},{"message":"unknown tag: alt","line":" src/core/reference.js:34"},{"message":"unknown tag: alt","line":" src/core/reference.js:87"},{"message":"unknown tag: alt","line":" src/core/reference.js:115"},{"message":"unknown tag: alt","line":" src/core/reference.js:137"},{"message":"unknown tag: alt","line":" src/core/reference.js:158"},{"message":"unknown tag: alt","line":" src/core/reference.js:179"},{"message":"unknown tag: alt","line":" src/core/reference.js:200"},{"message":"unknown tag: alt","line":" src/core/reference.js:231"},{"message":"unknown tag: alt","line":" src/core/reference.js:267"},{"message":"unknown tag: alt","line":" src/core/reference.js:288"},{"message":"unknown tag: alt","line":" src/core/reference.js:309"},{"message":"unknown tag: alt","line":" src/core/reference.js:331"},{"message":"unknown tag: alt","line":" src/core/reference.js:351"},{"message":"unknown tag: alt","line":" src/core/reference.js:379"},{"message":"unknown tag: alt","line":" src/core/reference.js:408"},{"message":"unknown tag: alt","line":" src/core/reference.js:448"},{"message":"unknown tag: alt","line":" src/core/reference.js:490"},{"message":"unknown tag: alt","line":" src/core/reference.js:512"},{"message":"unknown tag: alt","line":" src/core/rendering.js:15"},{"message":"unknown tag: alt","line":" src/core/rendering.js:125"},{"message":"unknown tag: alt","line":" src/core/rendering.js:183"},{"message":"unknown tag: alt","line":" src/core/rendering.js:204"},{"message":"unknown tag: alt","line":" src/core/rendering.js:243"},{"message":"unknown tag: alt","line":" src/core/rendering.js:326"},{"message":"unknown tag: alt","line":" src/core/structure.js:10"},{"message":"unknown tag: alt","line":" src/core/structure.js:83"},{"message":"unknown tag: alt","line":" src/core/structure.js:134"},{"message":"unknown tag: alt","line":" src/core/structure.js:192"},{"message":"unknown tag: alt","line":" src/core/structure.js:290"},{"message":"unknown tag: alt","line":" src/core/structure.js:391"},{"message":"unknown tag: alt","line":" src/core/structure.js:497"},{"message":"unknown tag: alt","line":" src/core/transform.js:11"},{"message":"unknown tag: alt","line":" src/core/transform.js:168"},{"message":"unknown tag: alt","line":" src/core/transform.js:193"},{"message":"unknown tag: alt","line":" src/core/transform.js:232"},{"message":"unknown tag: alt","line":" src/core/transform.js:268"},{"message":"unknown tag: alt","line":" src/core/transform.js:304"},{"message":"unknown tag: alt","line":" src/core/transform.js:342"},{"message":"unknown tag: alt","line":" src/core/transform.js:416"},{"message":"unknown tag: alt","line":" src/core/transform.js:455"},{"message":"unknown tag: alt","line":" src/core/transform.js:494"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:10"},{"message":"unknown tag: alt","line":" src/data/local_storage.js:101"},{"message":"unknown tag: alt","line":" src/dom/dom.js:204"},{"message":"unknown tag: alt","line":" src/dom/dom.js:271"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1560"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1622"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1726"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1765"},{"message":"replacing incorrect tag: returns with return","line":" src/dom/dom.js:1885"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2268"},{"message":"unknown tag: alt","line":" src/dom/dom.js:2778"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:23"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:46"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:69"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:135"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:168"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:201"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:239"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:285"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:330"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:389"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:428"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:471"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:515"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:546"},{"message":"unknown tag: alt","line":" src/events/acceleration.js:604"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:10"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:36"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:64"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:103"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:190"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:243"},{"message":"unknown tag: alt","line":" src/events/keyboard.js:308"},{"message":"unknown tag: alt","line":" src/events/mouse.js:12"},{"message":"unknown tag: alt","line":" src/events/mouse.js:43"},{"message":"unknown tag: alt","line":" src/events/mouse.js:80"},{"message":"unknown tag: alt","line":" src/events/mouse.js:106"},{"message":"unknown tag: alt","line":" src/events/mouse.js:132"},{"message":"unknown tag: alt","line":" src/events/mouse.js:164"},{"message":"unknown tag: alt","line":" src/events/mouse.js:195"},{"message":"unknown tag: alt","line":" src/events/mouse.js:233"},{"message":"unknown tag: alt","line":" src/events/mouse.js:271"},{"message":"unknown tag: alt","line":" src/events/mouse.js:311"},{"message":"unknown tag: alt","line":" src/events/mouse.js:351"},{"message":"unknown tag: alt","line":" src/events/mouse.js:389"},{"message":"unknown tag: alt","line":" src/events/mouse.js:481"},{"message":"unknown tag: alt","line":" src/events/mouse.js:535"},{"message":"unknown tag: alt","line":" src/events/mouse.js:615"},{"message":"unknown tag: alt","line":" src/events/mouse.js:696"},{"message":"unknown tag: alt","line":" src/events/mouse.js:772"},{"message":"unknown tag: alt","line":" src/events/mouse.js:841"},{"message":"unknown tag: alt","line":" src/events/mouse.js:926"},{"message":"unknown tag: alt","line":" src/events/mouse.js:979"},{"message":"unknown tag: alt","line":" src/events/mouse.js:1025"},{"message":"unknown tag: alt","line":" src/events/touch.js:10"},{"message":"unknown tag: alt","line":" src/events/touch.js:71"},{"message":"unknown tag: alt","line":" src/events/touch.js:151"},{"message":"unknown tag: alt","line":" src/events/touch.js:223"},{"message":"unknown tag: alt","line":" src/image/image.js:15"},{"message":"unknown tag: alt","line":" src/image/image.js:94"},{"message":"unknown tag: alt","line":" src/image/image.js:413"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:18"},{"message":"replacing incorrect tag: returns with return","line":" src/image/loading_displaying.js:284"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:301"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:471"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:569"},{"message":"unknown tag: alt","line":" src/image/loading_displaying.js:633"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:88"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:115"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:152"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:261"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:296"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:346"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:400"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:437"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:548"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:603"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:665"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:738"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:859"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:900"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:941"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:972"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1017"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1052"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1089"},{"message":"unknown tag: alt","line":" src/image/p5.Image.js:1125"},{"message":"unknown tag: alt","line":" src/image/pixels.js:12"},{"message":"unknown tag: alt","line":" src/image/pixels.js:80"},{"message":"unknown tag: alt","line":" src/image/pixels.js:173"},{"message":"unknown tag: alt","line":" src/image/pixels.js:307"},{"message":"unknown tag: alt","line":" src/image/pixels.js:481"},{"message":"unknown tag: alt","line":" src/image/pixels.js:566"},{"message":"unknown tag: alt","line":" src/image/pixels.js:602"},{"message":"unknown tag: alt","line":" src/image/pixels.js:674"},{"message":"unknown tag: alt","line":" src/io/files.js:20"},{"message":"unknown tag: alt","line":" src/io/files.js:183"},{"message":"unknown tag: alt","line":" src/io/files.js:303"},{"message":"unknown tag: alt","line":" src/io/files.js:583"},{"message":"replacing incorrect tag: returns with return","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:693"},{"message":"unknown tag: alt","line":" src/io/files.js:1393"},{"message":"unknown tag: alt","line":" src/io/files.js:1535"},{"message":"unknown tag: alt","line":" src/io/files.js:1592"},{"message":"unknown tag: alt","line":" src/io/files.js:1656"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:85"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:148"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:195"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:240"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:288"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:352"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:545"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:597"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:638"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:896"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:960"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1009"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1055"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1100"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1146"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1190"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1242"},{"message":"unknown tag: alt","line":" src/io/p5.Table.js:1305"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:40"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:102"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:146"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:191"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:239"},{"message":"unknown tag: alt","line":" src/io/p5.TableRow.js:295"},{"message":"unknown tag: alt","line":" src/io/p5.XML.js:9"},{"message":"unknown tag: alt","line":" src/math/calculation.js:10"},{"message":"unknown tag: alt","line":" src/math/calculation.js:33"},{"message":"unknown tag: alt","line":" src/math/calculation.js:72"},{"message":"unknown tag: alt","line":" src/math/calculation.js:116"},{"message":"unknown tag: alt","line":" src/math/calculation.js:182"},{"message":"unknown tag: alt","line":" src/math/calculation.js:231"},{"message":"unknown tag: alt","line":" src/math/calculation.js:269"},{"message":"unknown tag: alt","line":" src/math/calculation.js:316"},{"message":"unknown tag: alt","line":" src/math/calculation.js:371"},{"message":"unknown tag: alt","line":" src/math/calculation.js:409"},{"message":"unknown tag: alt","line":" src/math/calculation.js:464"},{"message":"unknown tag: alt","line":" src/math/calculation.js:512"},{"message":"unknown tag: alt","line":" src/math/calculation.js:560"},{"message":"unknown tag: alt","line":" src/math/calculation.js:612"},{"message":"unknown tag: alt","line":" src/math/calculation.js:646"},{"message":"unknown tag: alt","line":" src/math/calculation.js:701"},{"message":"unknown tag: alt","line":" src/math/calculation.js:745"},{"message":"replacing incorrect tag: returns with return","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/calculation.js:832"},{"message":"unknown tag: alt","line":" src/math/math.js:10"},{"message":"unknown tag: alt","line":" src/math/noise.js:36"},{"message":"unknown tag: alt","line":" src/math/noise.js:178"},{"message":"unknown tag: alt","line":" src/math/noise.js:243"},{"message":"unknown tag: alt","line":" src/math/p5.Vector.js:10"},{"message":"unknown tag: alt","line":" src/math/random.js:37"},{"message":"unknown tag: alt","line":" src/math/random.js:66"},{"message":"unknown tag: alt","line":" src/math/random.js:153"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:123"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:159"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:186"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:213"},{"message":"unknown tag: alt","line":" src/math/trigonometry.js:285"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:320"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:335"},{"message":"replacing incorrect tag: returns with return","line":" src/math/trigonometry.js:350"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:11"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:81"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:118"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:150"},{"message":"unknown tag: alt","line":" src/typography/attributes.js:187"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:16"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:140"},{"message":"unknown tag: alt","line":" src/typography/loading_displaying.js:231"},{"message":"unknown tag: alt","line":" src/typography/p5.Font.js:31"},{"message":"unknown tag: alt","line":" src/utilities/conversion.js:10"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:15"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:43"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:130"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:237"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:311"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:373"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:451"},{"message":"unknown tag: alt","line":" src/utilities/string_functions.js:537"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:10"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:31"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:52"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:73"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:100"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:122"},{"message":"unknown tag: alt","line":" src/utilities/time_date.js:143"},{"message":"unknown tag: alt","line":" src/webgl/3d_primitives.js:13"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:11"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:145"},{"message":"unknown tag: alt","line":" src/webgl/interaction.js:353"},{"message":"unknown tag: alt","line":" src/webgl/light.js:11"},{"message":"unknown tag: alt","line":" src/webgl/light.js:92"},{"message":"unknown tag: alt","line":" src/webgl/light.js:177"},{"message":"unknown tag: alt","line":" src/webgl/light.js:280"},{"message":"unknown tag: alt","line":" src/webgl/light.js:387"},{"message":"unknown tag: alt","line":" src/webgl/light.js:425"},{"message":"unknown tag: alt","line":" src/webgl/light.js:519"},{"message":"unknown tag: alt","line":" src/webgl/light.js:859"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:12"},{"message":"unknown tag: alt","line":" src/webgl/loading.js:588"},{"message":"unknown tag: alt","line":" src/webgl/material.js:12"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:111"},{"message":"unknown tag: alt","line":" src/webgl/material.js:184"},{"message":"unknown tag: alt","line":" src/webgl/material.js:282"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:368"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:511"},{"message":"unknown tag: alt","line":" src/webgl/material.js:587"},{"message":"unknown tag: alt","line":" src/webgl/material.js:659"},{"message":"unknown tag: alt","line":" src/webgl/material.js:697"},{"message":"unknown tag: alt","line":" src/webgl/material.js:777"},{"message":"unknown tag: alt","line":" src/webgl/material.js:829"},{"message":"unknown tag: alt","line":" src/webgl/material.js:902"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:13"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:115"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:176"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:236"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:303"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:357"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:444"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:472"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:499"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:526"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:554"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:582"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:610"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:633"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:656"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:683"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:801"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:897"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1040"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1098"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1156"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1223"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1386"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1458"},{"message":"unknown tag: alt","line":" src/webgl/p5.Camera.js:1723"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:334"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:603"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:644"},{"message":"unknown tag: alt","line":" src/webgl/p5.RendererGL.js:749"},{"message":"unknown tag: alt","line":" src/webgl/p5.Shader.js:306"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:115"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:158"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:191"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:203"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:236"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:250"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: returns with return","line":" src/webgl/text.js:388"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:456"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:471"},{"message":"replacing incorrect tag: function with method","line":" src/webgl/text.js:556"},{"message":"replacing incorrect tag: params with param","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2381"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:2882"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4271"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4360"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4386"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:4460"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:6280"},{"message":"replacing incorrect tag: returns with return","line":" lib/addons/p5.sound.js:8116"},{"message":"Missing item type\nConversions adapted from <http://www.easyrgb.com/en/math.php>.\n\nIn these functions, hue is always in the range [0, 1], just like all other\ncomponents are in the range [0, 1]. 'Brightness' and 'value' are used\ninterchangeably.","line":" src/color/color_conversion.js:8"},{"message":"Missing item type\nConvert an HSBA array to HSLA.","line":" src/color/color_conversion.js:19"},{"message":"Missing item type\nConvert an HSBA array to RGBA.","line":" src/color/color_conversion.js:45"},{"message":"Missing item type\nConvert an HSLA array to HSBA.","line":" src/color/color_conversion.js:100"},{"message":"Missing item type\nConvert an HSLA array to RGBA.\n\nWe need to change basis from HSLA to something that can be more easily be\nprojected onto RGBA. We will choose hue and brightness as our first two\ncomponents, and pick a convenient third one ('zest') so that we don't need\nto calculate formal HSBA saturation.","line":" src/color/color_conversion.js:123"},{"message":"Missing item type\nConvert an RGBA array to HSBA.","line":" src/color/color_conversion.js:187"},{"message":"Missing item type\nConvert an RGBA array to HSLA.","line":" src/color/color_conversion.js:226"},{"message":"Missing item type\nHue is the same in HSB and HSL, but the maximum value may be different.\nThis function will return the HSB-normalized saturation when supplied with\nan HSB color object, but will default to the HSL-normalized saturation\notherwise.","line":" src/color/p5.Color.js:396"},{"message":"Missing item type\nSaturation is scaled differently in HSB and HSL. This function will return\nthe HSB saturation when supplied with an HSB color object, but will default\nto the HSL saturation otherwise.","line":" src/color/p5.Color.js:427"},{"message":"Missing item type\nCSS named colors.","line":" src/color/p5.Color.js:446"},{"message":"Missing item type\nThese regular expressions are used to build up the patterns for matching\nviable CSS color strings: fragmenting the regexes in this way increases the\nlegibility and comprehensibility of the code.\n\nNote that RGB values of .9 are not parsed by IE, but are supported here for\ncolor string consistency.","line":" src/color/p5.Color.js:600"},{"message":"Missing item type\nFull color string patterns. The capture groups are necessary.","line":" src/color/p5.Color.js:613"},{"message":"Missing item type\nFor a number of different inputs, returns a color formatted as [r, g, b, a]\narrays, with each component normalized between 0 and 1.","line":" src/color/p5.Color.js:750"},{"message":"Missing item type\nFor HSB and HSL, interpret the gray level as a brightness/lightness\nvalue (they are equivalent when chroma is zero). For RGB, normalize the\ngray level according to the blue maximum.","line":" src/color/p5.Color.js:960"},{"message":"Missing item type","line":" src/core/friendly_errors/fes_core.js:1"},{"message":"Missing item type\nPrints out all the colors in the color pallete with white text.\nFor color blindness testing.","line":" src/core/friendly_errors/fes_core.js:915"},{"message":"Missing item type","line":" src/core/friendly_errors/file_errors.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/sketch_reader.js:1"},{"message":"Missing item type","line":" src/core/friendly_errors/stacktrace.js:1"},{"message":"Missing item type\nGiven an Error object, extract the most information from it.","line":" src/core/friendly_errors/stacktrace.js:34"},{"message":"Missing item type","line":" src/core/friendly_errors/validate_params.js:1"},{"message":"Missing item type\nThis function does 3 things:\n\n  1. Bounds the desired start/stop angles for an arc (in radians) so that:\n\n         0 <= start < TWO_PI ;    start <= stop < start + TWO_PI\n\n     This means that the arc rendering functions don't have to be concerned\n     with what happens if stop is smaller than start, or if the arc 'goes\n     round more than once', etc.: they can just start at start and increase\n     until stop and the correct arc will be drawn.\n\n  2. Optionally adjusts the angles within each quadrant to counter the naive\n     scaling of the underlying ellipse up from the unit circle.  Without\n     this, the angles become arbitrary when width != height: 45 degrees\n     might be drawn at 5 degrees on a 'wide' ellipse, or at 85 degrees on\n     a 'tall' ellipse.\n\n  3. Flags up when start and stop correspond to the same place on the\n     underlying ellipse.  This is useful if you want to do something special\n     there (like rendering a whole ellipse instead).","line":" src/core/shape/2d_primitives.js:16"},{"message":"Missing item type\nReturns the current framerate.","line":" src/core/environment.js:305"},{"message":"Missing item type\nSpecifies the number of frames to be displayed every second. For example,\nthe function call frameRate(30) will attempt to refresh 30 times a second.\nIf the processor is not fast enough to maintain the specified rate, the\nframe rate will not be achieved. Setting the frame rate within <a href=\"#/p5/setup\">setup()</a> is\nrecommended. The default rate is 60 frames per second.\n\nCalling <a href=\"#/p5/frameRate\">frameRate()</a> with no arguments returns the current framerate.","line":" src/core/environment.js:315"},{"message":"Missing item type","line":" src/core/helpers.js:1"},{"message":"Missing item type\n_globalInit\n\nTODO: ???\nif sketch is on window\nassume \"global\" mode\nand instantiate p5 automatically\notherwise do nothing","line":" src/core/init.js:4"},{"message":"Missing item type\nThis is our i18next \"backend\" plugin. It tries to fetch languages\nfrom a CDN.","line":" src/core/internationalization.js:30"},{"message":"Missing item type\nSet up our translation function, with loaded languages","line":" src/core/internationalization.js:126"},{"message":"Missing item type\nReturns a list of languages we have translations loaded for","line":" src/core/internationalization.js:171"},{"message":"Missing item type\nReturns the current language selected for translation","line":" src/core/internationalization.js:178"},{"message":"Missing item type\nSets the current language for translation\nReturns a promise that resolved when loading is finished,\nor rejects if it fails.","line":" src/core/internationalization.js:185"},{"message":"Missing item type","line":" src/core/legacy.js:1"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/core/p5.Element.js:827"},{"message":"Missing item type\nResize our canvas element.","line":" src/core/p5.Renderer.js:99"},{"message":"Missing item type\nHelper function to check font type (system or otf)","line":" src/core/p5.Renderer.js:415"},{"message":"Missing item type\nHelper fxn to measure ascent and descent.\nAdapted from http://stackoverflow.com/a/25355178","line":" src/core/p5.Renderer.js:467"},{"message":"Missing item type\np5.Renderer2D\nThe 2D graphics canvas renderer class.\nextends p5.Renderer","line":" src/core/p5.Renderer2D.js:7"},{"message":"Missing item type\nGenerate a cubic Bezier representing an arc on the unit circle of total\nangle `size` radians, beginning `start` radians above the x-axis. Up to\nfour of these curves are combined to make a full arc.\n\nSee www.joecridge.me/bezier.pdf for an explanation of the method.","line":" src/core/p5.Renderer2D.js:402"},{"message":"Missing item type\nshim for Uint8ClampedArray.slice\n(allows arrayCopy to work with pixels[])\nwith thanks to http://halfpapstudios.com/blog/tag/html5-canvas/\nEnumerable set to false to protect for...in from\nUint8ClampedArray.prototype pollution.","line":" src/core/shim.js:18"},{"message":"Missing item type\nthis is implementation of Object.assign() which is unavailable in\nIE11 and (non-Chrome) Android browsers.\nThe assign() method is used to copy the values of all enumerable\nown properties from one or more source objects to a target object.\nIt will return the target object.\nModified from https://github.com/ljharb/object.assign","line":" src/core/shim.js:39"},{"message":"Missing item type\nprivate helper function to handle the user passing in objects\nduring construction or calls to create()","line":" src/data/p5.TypedDict.js:197"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:387"},{"message":"Missing item type\nprivate helper function to ensure that the user passed in valid\nvalues for the Dictionary type","line":" src/data/p5.TypedDict.js:425"},{"message":"Missing item type\nprivate helper function for finding lowest or highest value\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:536"},{"message":"Missing item type\nprivate helper function for finding lowest or highest key\nthe argument 'flip' is used to flip the comparison arrow\nfrom 'less than' to 'greater than'","line":" src/data/p5.TypedDict.js:600"},{"message":"Missing item type\nHelper function for select and selectAll","line":" src/dom/dom.js:127"},{"message":"Missing item type\nHelper function for getElement and getElements.","line":" src/dom/dom.js:142"},{"message":"Missing item type\nHelpers for create methods.","line":" src/dom/dom.js:309"},{"message":"Missing item type","line":" src/dom/dom.js:450"},{"message":"Missing item type","line":" src/dom/dom.js:1164"},{"message":"Missing item type","line":" src/dom/dom.js:1257"},{"message":"Missing item type","line":" src/dom/dom.js:1296"},{"message":"Missing item type","line":" src/dom/dom.js:3232"},{"message":"Missing item type","line":" src/dom/dom.js:3298"},{"message":"Missing item type","line":" src/dom/dom.js:3360"},{"message":"Missing item type\n_updatePAccelerations updates the pAcceleration values","line":" src/events/acceleration.js:124"},{"message":"Missing item type\nThe onblur function is called when the user is no longer focused\non the p5 element. Because the keyup events will not fire if the user is\nnot focused on the element we must assume all keys currently down have\nbeen released.","line":" src/events/keyboard.js:298"},{"message":"Missing item type\nThe _areDownKeys function returns a boolean true if any keys pressed\nand a false if no keys are currently pressed.\n\nHelps avoid instances where multiple keys are pressed simultaneously and\nreleasing a single key will then switch the\nkeyIsPressed property to true.","line":" src/events/keyboard.js:384"},{"message":"Missing item type\nThis module defines the filters for use with image buffers.\n\nThis module is basically a collection of functions stored in an object\nas opposed to modules. The functions are destructive, modifying\nthe passed in canvas rather than creating a copy.\n\nGenerally speaking users of this module will use the Filters.apply method\non a canvas to create an effect.\n\nA number of functions are borrowed/adapted from\nhttp://www.html5rocks.com/en/tutorials/canvas/imagefilters/\nor the java processing implementation.","line":" src/image/filters.js:3"},{"message":"Missing item type\nReturns the pixel buffer for a canvas","line":" src/image/filters.js:24"},{"message":"Missing item type\nReturns a 32 bit number containing ARGB data at ith pixel in the\n1D array containing pixels data.","line":" src/image/filters.js:60"},{"message":"Missing item type\nModifies pixels RGBA values to values contained in the data object.","line":" src/image/filters.js:81"},{"message":"Missing item type\nReturns the ImageData object for a canvas\nhttps://developer.mozilla.org/en-US/docs/Web/API/ImageData","line":" src/image/filters.js:101"},{"message":"Missing item type\nReturns a blank ImageData object.","line":" src/image/filters.js:121"},{"message":"Missing item type\nApplys a filter function to a canvas.\n\nThe difference between this and the actual filter functions defined below\nis that the filter functions generally modify the pixel buffer but do\nnot actually put that data back to the canvas (where it would actually\nupdate what is visible). By contrast this method does make the changes\nactually visible in the canvas.\n\nThe apply method is the method that callers of this module would generally\nuse. It has been separated from the actual filters to support an advanced\nuse case of creating a filter chain that executes without actually updating\nthe canvas in between everystep.","line":" src/image/filters.js:136"},{"message":"Missing item type\nConverts the image to black and white pixels depending if they are above or\nbelow the threshold defined by the level parameter. The parameter must be\nbetween 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:189"},{"message":"Missing item type\nConverts any colors in the image to grayscale equivalents.\nNo parameter is used.\n\nBorrowed from http://www.html5rocks.com/en/tutorials/canvas/imagefilters/","line":" src/image/filters.js:223"},{"message":"Missing item type\nSets the alpha channel to entirely opaque. No parameter is used.","line":" src/image/filters.js:246"},{"message":"Missing item type\nSets each pixel to its inverse value. No parameter is used.","line":" src/image/filters.js:262"},{"message":"Missing item type\nLimits each channel of the image to the number of colors specified as\nthe parameter. The parameter can be set to values between 2 and 255, but\nresults are most noticeable in the lower ranges.\n\nAdapted from java based processing implementation","line":" src/image/filters.js:277"},{"message":"Missing item type\nreduces the bright areas in an image","line":" src/image/filters.js:309"},{"message":"Missing item type\nincreases the bright areas in an image","line":" src/image/filters.js:396"},{"message":"Missing item type\nThis module defines the p5 methods for the <a href=\"#/p5.Image\">p5.Image</a> class\nfor drawing images to the main display canvas.","line":" src/image/image.js:8"},{"message":"Missing item type\nHelper function for loading GIF-based images","line":" src/image/loading_displaying.js:162"},{"message":"Missing item type\nValidates clipping params. Per drawImage spec sWidth and sHight cannot be\nnegative or greater than image intrinsic width and height","line":" src/image/loading_displaying.js:284"},{"message":"Missing item type\nApply the current tint color to the input image, return the resulting\ncanvas.","line":" src/image/loading_displaying.js:597"},{"message":"Missing item type\nThis module defines the <a href=\"#/p5.Image\">p5.Image</a> class and P5 methods for\ndrawing images to the main display canvas.","line":" src/image/p5.Image.js:9"},{"message":"Missing item type\nHelper function for animating GIF-based images with time","line":" src/image/p5.Image.js:222"},{"message":"Missing item type\nHelper fxn for sharing pixel methods","line":" src/image/p5.Image.js:253"},{"message":"Missing item type\nGenerate a blob of file data as a url to prepare for download.\nAccepts an array of data, a filename, and an extension (optional).\nThis is a private function because it does not do any formatting,\nbut it is used by <a href=\"#/p5/saveStrings\">saveStrings</a>, <a href=\"#/p5/saveJSON\">saveJSON</a>, <a href=\"#/p5/saveTable\">saveTable</a> etc.","line":" src/io/files.js:1789"},{"message":"Missing item type\nReturns a file extension, or another string\nif the provided parameter has no extension.","line":" src/io/files.js:1857"},{"message":"Missing item type\nReturns true if the browser is Safari, false if not.\nSafari makes trouble for downloading files.","line":" src/io/files.js:1890"},{"message":"Missing item type\nHelper function, a callback for download that deletes\nan invisible anchor element from the DOM once the file\nhas been automatically downloaded.","line":" src/io/files.js:1902"},{"message":"Missing item type\nTable Options\nGeneric class for handling tabular data, typically from a\nCSV, TSV, or other sort of spreadsheet file.\nCSV files are\n<a href=\"http://en.wikipedia.org/wiki/Comma-separated_values\">\ncomma separated values</a>, often with the data in quotes. TSV\nfiles use tabs as separators, and usually don't bother with the\nquotes.\nFile names should end with .csv if they're comma separated.\nA rough \"spec\" for CSV can be found\n<a href=\"http://tools.ietf.org/html/rfc4180\">here</a>.\nTo load files, use the <a href=\"#/p5/loadTable\">loadTable</a> method.\nTo save tables to your computer, use the <a href=\"#/p5/save\">save</a> method\n or the <a href=\"#/p5/saveTable\">saveTable</a> method.\n\nPossible options include:\n<ul>\n<li>csv - parse the table as comma-separated values\n<li>tsv - parse the table as tab-separated values\n<li>header - this table has a header (title) row\n</ul>","line":" src/io/p5.Table.js:9"},{"message":"Missing item type\nMultiplies a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2135"},{"message":"Missing item type\nRotates the vector (only 2D vectors) by the given angle, magnitude remains the same and returns a new vector.","line":" src/math/p5.Vector.js:2187"},{"message":"Missing item type\nDivides a vector by a scalar and returns a new vector.","line":" src/math/p5.Vector.js:2214"},{"message":"Missing item type\nCalculates the dot product of two vectors.","line":" src/math/p5.Vector.js:2267"},{"message":"Missing item type\nCalculates the cross product of two vectors.","line":" src/math/p5.Vector.js:2281"},{"message":"Missing item type\nCalculates the Euclidean distance between two points (considering a\npoint as a vector object).","line":" src/math/p5.Vector.js:2295"},{"message":"Missing item type\nLinear interpolate a vector to another vector and return the result as a\nnew vector.","line":" src/math/p5.Vector.js:2310"},{"message":"Missing item type\nCalculates the magnitude (length) of the vector and returns the result as\na float (this is simply the equation sqrt(x\\*x + y\\*y + z\\*z).)","line":" src/math/p5.Vector.js:2339"},{"message":"Missing item type\nNormalize the vector to length 1 (make it a unit vector).","line":" src/math/p5.Vector.js:2357"},{"message":"Missing item type\nHelper function to measure ascent and descent.","line":" src/typography/attributes.js:280"},{"message":"Missing item type\nReturns the set of opentype glyphs for the supplied string.\n\nNote that there is not a strict one-to-one mapping between characters\nand glyphs, so the list of returned glyphs can be larger or smaller\n than the length of the given string.","line":" src/typography/p5.Font.js:273"},{"message":"Missing item type\nReturns an opentype path for the supplied string and position.","line":" src/typography/p5.Font.js:288"},{"message":"Missing item type","line":" src/webgl/3d_primitives.js:301"},{"message":"Missing item type\nDraws a point, a coordinate in space at the dimension of one pixel,\ngiven x, y and z coordinates. The color of the point is determined\nby the current stroke, while the point size is determined by current\nstroke weight.","line":" src/webgl/3d_primitives.js:955"},{"message":"Missing item type\nDraw a line given two points","line":" src/webgl/3d_primitives.js:1393"},{"message":"Missing item type\nParse OBJ lines into model. For reference, this is what a simple model of a\nsquare might look like:\n\nv -0.5 -0.5 0.5\nv -0.5 -0.5 -0.5\nv -0.5 0.5 -0.5\nv -0.5 0.5 0.5\n\nf 4 3 2 1","line":" src/webgl/loading.js:179"},{"message":"Missing item type\nSTL files can be of two types, ASCII and Binary,\n\nWe need to convert the arrayBuffer to an array of strings,\nto parse it as an ASCII file.","line":" src/webgl/loading.js:290"},{"message":"Missing item type\nThis function checks if the file is in ASCII format or in Binary format\n\nIt is done by searching keyword `solid` at the start of the file.\n\nAn ASCII STL data must begin with `solid` as the first six bytes.\nHowever, ASCII STLs lacking the SPACE after the `d` are known to be\nplentiful. So, check the first 5 bytes for `solid`.\n\nSeveral encodings, such as UTF-8, precede the text with up to 5 bytes:\nhttps://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding\nSearch for `solid` to start anywhere after those prefixes.","line":" src/webgl/loading.js:317"},{"message":"Missing item type\nThis function matches the `query` at the provided `offset`","line":" src/webgl/loading.js:344"},{"message":"Missing item type\nThis function parses the Binary STL files.\nhttps://en.wikipedia.org/wiki/STL_%28file_format%29#Binary_STL\n\nCurrently there is no support for the colors provided in STL files.","line":" src/webgl/loading.js:356"},{"message":"Missing item type\nASCII STL file starts with `solid 'nameOfFile'`\nThen contain the normal of the face, starting with `facet normal`\nNext contain a keyword indicating the start of face vertex, `outer loop`\nNext comes the three vertex, starting with `vertex x y z`\nVertices ends with `endloop`\nFace ends with `endfacet`\nNext face starts with `facet normal`\nThe end of the file is indicated by `endsolid`","line":" src/webgl/loading.js:444"},{"message":"Missing item type","line":" src/webgl/material.js:947"},{"message":"Missing item type","line":" src/webgl/material.js:978"},{"message":"Missing item type\nCreate a 2D array for establishing stroke connections","line":" src/webgl/p5.Geometry.js:212"},{"message":"Missing item type\nCreate 4 vertices for each stroke line, two at the beginning position\nand two at the end position. These vertices are displaced relative to\nthat line's normal on the GPU","line":" src/webgl/p5.Geometry.js:233"},{"message":"Missing item type","line":" src/webgl/p5.Matrix.js:1"},{"message":"Missing item type\nPRIVATE","line":" src/webgl/p5.Matrix.js:722"},{"message":"Missing item type\nEnables and binds the buffers used by shader when the appropriate data exists in geometry.\nMust always be done prior to drawing geometry in WebGL.","line":" src/webgl/p5.RenderBuffer.js:12"},{"message":"Missing item type\nWelcome to RendererGL Immediate Mode.\nImmediate mode is used for drawing custom shapes\nfrom a set of vertices.  Immediate Mode is activated\nwhen you call <a href=\"#/p5/beginShape\">beginShape()</a> & de-activated when you call <a href=\"#/p5/endShape\">endShape()</a>.\nImmediate mode is a style of programming borrowed\nfrom OpenGL's (now-deprecated) immediate mode.\nIt differs from p5.js' default, Retained Mode, which caches\ngeometries and buffers on the CPU to reduce the number of webgl\ndraw calls. Retained mode is more efficient & performative,\nhowever, Immediate Mode is useful for sketching quick\ngeometric ideas.","line":" src/webgl/p5.RendererGL.Immediate.js:1"},{"message":"Missing item type\nEnd shape drawing and render vertices to screen.","line":" src/webgl/p5.RendererGL.Immediate.js:129"},{"message":"Missing item type\nCalled from endShape(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:169"},{"message":"Missing item type\nCalled from _processVertices(). This function calculates the stroke vertices for custom shapes and\ntesselates shapes when applicable.","line":" src/webgl/p5.RendererGL.Immediate.js:203"},{"message":"Missing item type\nCalled from _processVertices() when applicable. This function tesselates immediateMode.geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:248"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the fill geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:268"},{"message":"Missing item type\nCalled from endShape(). Responsible for calculating normals, setting shader uniforms,\nenabling all appropriate buffers, applying color blend, and drawing the stroke geometry.","line":" src/webgl/p5.RendererGL.Immediate.js:302"},{"message":"Missing item type\ninitializes buffer defaults. runs each time a new geometry is\nregistered","line":" src/webgl/p5.RendererGL.Retained.js:8"},{"message":"Missing item type\ncreates a buffers object that holds the WebGL render buffers\nfor a geometry.","line":" src/webgl/p5.RendererGL.Retained.js:59"},{"message":"Missing item type\nDraws buffers given a geometry key ID","line":" src/webgl/p5.RendererGL.Retained.js:110"},{"message":"Missing item type\nmodel view, projection, & normal\nmatrices","line":" src/webgl/p5.RendererGL.js:117"},{"message":"Missing item type\n[background description]","line":" src/webgl/p5.RendererGL.js:586"},{"message":"Missing item type\n[resize description]","line":" src/webgl/p5.RendererGL.js:860"},{"message":"Missing item type\nclears color and depth buffers\nwith r,g,b,a","line":" src/webgl/p5.RendererGL.js:890"},{"message":"Missing item type\n[translate description]","line":" src/webgl/p5.RendererGL.js:924"},{"message":"Missing item type\nScales the Model View Matrix by a vector","line":" src/webgl/p5.RendererGL.js:943"},{"message":"Missing item type\nturn a two dimensional array into one dimensional array","line":" src/webgl/p5.RendererGL.js:1366"},{"message":"Missing item type\nturn a p5.Vector Array into a one dimensional number array","line":" src/webgl/p5.RendererGL.js:1403"},{"message":"Missing item type\nensures that p5 is using a 3d renderer. throws an error if not.","line":" src/webgl/p5.RendererGL.js:1421"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:1"},{"message":"Missing item type\np5.sound \nhttps://p5js.org/reference/#/libraries/p5.sound\n\nFrom the Processing Foundation and contributors\nhttps://github.com/processing/p5.js-sound/graphs/contributors\n\nMIT License (MIT)\nhttps://github.com/processing/p5.js-sound/blob/master/LICENSE\n\nSome of the many audio libraries & resources that inspire p5.sound:\n - TONE.js (c) Yotam Mann. Licensed under The MIT License (MIT). https://github.com/TONEnoTONE/Tone.js\n - buzz.js (c) Jay Salvat. Licensed under The MIT License (MIT). http://buzz.jaysalvat.com/\n - Boris Smus Web Audio API book, 2013. Licensed under the Apache License http://www.apache.org/licenses/LICENSE-2.0\n - wavesurfer.js https://github.com/katspaugh/wavesurfer.js\n - Web Audio Components by Jordan Santell https://github.com/web-audio-components\n - Wilm Thoben's Sound library for Processing https://github.com/processing/processing/tree/master/java/libraries/sound\n\n Web Audio API: http://w3.org/TR/webaudio/","line":" lib/addons/p5.sound.js:52"},{"message":"Missing item type\nThis module has shims","line":" lib/addons/p5.sound.js:401"},{"message":"Missing item type\nDetermine which filetypes are supported (inspired by buzz.js)\nThe audio element (el) will only be used to test browser support for various audio formats","line":" lib/addons/p5.sound.js:536"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:807"},{"message":"Missing item type\nUsed by Osc and Envelope to chain signal math","line":" lib/addons/p5.sound.js:1040"},{"message":"Missing item type\nThis is a helper function that the p5.SoundFile calls to load\nitself. Accepts a callback (the name of another function)\nas an optional parameter.","line":" lib/addons/p5.sound.js:1542"},{"message":"Missing item type\nStop playback on all of this soundfile's sources.","line":" lib/addons/p5.sound.js:2056"},{"message":"Missing item type","line":" lib/addons/p5.sound.js:2604"},{"message":"Missing item type\nThe p5.Effect class is built\n \tusing Tone.js CrossFade","line":" lib/addons/p5.sound.js:6455"},{"message":"Missing item type\nIn classes that extend\np5.Effect, connect effect nodes\nto the wet parameter","line":" lib/addons/p5.sound.js:6462"},{"message":"Missing item type\nEQFilter extends p5.Filter with constraints\nnecessary for the p5.EQ","line":" lib/addons/p5.sound.js:7009"},{"message":"Missing item type\nInspired by Simple Reverb by Jordan Santell\nhttps://github.com/web-audio-components/simple-reverb/blob/master/index.js\n\nUtility function for building an impulse response\nbased on the module parameters.","line":" lib/addons/p5.sound.js:8508"},{"message":"Missing item type\nPrivate method to load a buffer as an Impulse Response,\nassign it to the convolverNode, and add to the Array of .impulses.","line":" lib/addons/p5.sound.js:8659"},{"message":"Missing item type\nmusicalTimeMode variables\nmodify these only when the interval is specified in musicalTime format as a string","line":" lib/addons/p5.sound.js:9808"},{"message":"Missing item type\nDo not initiate the callback if timeFromNow is < 0\nThis ususually occurs for a few milliseconds when the page\nis not fully loaded\n\nThe callback should only be called until maxIterations is reached","line":" lib/addons/p5.sound.js:9826"},{"message":"Missing item type\ncallback invoked when the recording is over","line":" lib/addons/p5.sound.js:10660"},{"message":"Missing item type\nPrivate method to ensure accurate values of this._voicesInUse\nAny time a new value is scheduled, it is necessary to increment all subsequent\nscheduledValues after attack, and decrement all subsequent\nscheduledValues after release","line":" lib/addons/p5.sound.js:11995"},{"message":"Missing item type","line":" lib/addons/p5.sound.min.js:1"}],"consts":{"LABEL":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"FALLBACK":["p5.describe","p5.describeElement","p5.textOutput","p5.gridOutput"],"RGB":["p5.colorMode"],"HSB":["p5.colorMode"],"HSL":["p5.colorMode"],"CHORD":["p5.arc"],"PIE":["p5.arc"],"OPEN":["p5.arc"],"CENTER":["p5.ellipseMode","p5.rectMode","p5.imageMode","p5.textAlign"],"RADIUS":["p5.ellipseMode","p5.rectMode"],"CORNER":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"CORNERS":["p5.ellipseMode","p5.rectMode","p5.imageMode"],"ROUND":["p5.strokeCap","p5.strokeJoin"],"SQUARE":["p5.strokeCap"],"PROJECT":["p5.strokeCap"],"MITER":["p5.strokeJoin"],"BEVEL":["p5.strokeJoin"],"POINTS":["p5.beginShape"],"LINES":["p5.beginShape"],"TRIANGLES":["p5.beginShape"],"TRIANGLE_FAN":["p5.beginShape"],"TRIANGLE_STRIP":["p5.beginShape"],"QUADS":["p5.beginShape"],"QUAD_STRIP":["p5.beginShape"],"TESS":["p5.beginShape"],"CLOSE":["p5.endShape"],"ARROW":["p5.cursor"],"CROSS":["p5.cursor"],"HAND":["p5.cursor"],"MOVE":["p5.cursor"],"TEXT":["p5.cursor"],"P2D":["p5.createCanvas","p5.createGraphics"],"WEBGL":["p5.createCanvas","p5.createGraphics"],"BLEND":["p5.blendMode","p5.Image.blend","p5.blend"],"DARKEST":["p5.blendMode","p5.Image.blend","p5.blend"],"LIGHTEST":["p5.blendMode","p5.Image.blend","p5.blend"],"DIFFERENCE":["p5.blendMode","p5.Image.blend","p5.blend"],"MULTIPLY":["p5.blendMode","p5.Image.blend","p5.blend"],"EXCLUSION":["p5.blendMode","p5.Image.blend","p5.blend"],"SCREEN":["p5.blendMode","p5.Image.blend","p5.blend"],"REPLACE":["p5.blendMode","p5.Image.blend","p5.blend"],"OVERLAY":["p5.blendMode","p5.Image.blend","p5.blend"],"HARD_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"SOFT_LIGHT":["p5.blendMode","p5.Image.blend","p5.blend"],"DODGE":["p5.blendMode","p5.Image.blend","p5.blend"],"BURN":["p5.blendMode","p5.Image.blend","p5.blend"],"ADD":["p5.blendMode","p5.Image.blend","p5.blend"],"REMOVE":["p5.blendMode"],"SUBTRACT":["p5.blendMode"],"VIDEO":["p5.createCapture"],"AUDIO":["p5.createCapture"],"THRESHOLD":["p5.Image.filter","p5.filter"],"GRAY":["p5.Image.filter","p5.filter"],"OPAQUE":["p5.Image.filter","p5.filter"],"INVERT":["p5.Image.filter","p5.filter"],"POSTERIZE":["p5.Image.filter","p5.filter"],"ERODE":["p5.Image.filter","p5.filter"],"DILATE":["p5.Image.filter","p5.filter"],"BLUR":["p5.Image.filter","p5.filter"],"NORMAL":["p5.Image.blend","p5.blend","p5.textStyle","p5.textureMode"],"RADIANS":["p5.angleMode"],"DEGREES":["p5.angleMode"],"LEFT":["p5.textAlign"],"RIGHT":["p5.textAlign"],"TOP":["p5.textAlign"],"BOTTOM":["p5.textAlign"],"BASELINE":["p5.textAlign"],"ITALIC":["p5.textStyle"],"BOLD":["p5.textStyle"],"BOLDITALIC":["p5.textStyle"],"WORD":["p5.textWrap"],"CHAR":["p5.textWrap"],"IMAGE":["p5.textureMode"],"CLAMP":["p5.textureWrap"],"REPEAT":["p5.textureWrap"],"MIRROR":["p5.textureWrap"]}}
            \ No newline at end of file
            diff --git a/dist/zh-Hans/reference/index.html b/dist/zh-Hans/reference/index.html
            new file mode 100644
            index 0000000000..934e20b317
            --- /dev/null
            +++ b/dist/zh-Hans/reference/index.html
            @@ -0,0 +1,295 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">reference | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="reference-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <div class="column-span">
            +
            +    <main id="content" >
            +      <h1>Reference</h1>
            +
            +      <div id="search" class="search-wrapper" role="search"></div>
            +      <div id="collection-list-nav"></div>
            +
            +          <!--class="container-fluid"-->
            +      <div id="list" tabindex="2" class="list-wrapper allItems-collection"></div>
            +      <div id="item" tabindex="1" class="item-wrapper apidocs"></div>
            +      <div id="file" class="file-wrapper"></div>
            +
            +    </main>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </div> <!-- end column-span -->
            +
            +  <script src='/assets/js/p5.min.js?v=fbf148'></script>
            +  <script src='/assets/js/p5.sound.min.js?v=53b7c5'></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
            +  <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
            +  <script src="/assets/js/vendor/require.min.js"></script>
            +  <script src="/assets/js/render.js?v=56ab24"></script>
            +  <script src="/assets/js/reference.js?v=c69268"></script>
            +
            +  <script>
            +
            +    var translations;
            +
            +    $(document).ready(function() {
            +      var routes = window.location.pathname.split('/');
            +      var lang = routes[1];
            +      if (langs.indexOf(lang) != -1) {
            +        $.getJSON('/assets/reference/'+lang+'.json', function(data) {
            +          translations = data;
            +
            +          window.addEventListener('reference-rendered', function() {
            +            console.log("rendered");
            +            updateLanguage();
            +          }, false);
            +        });
            +      }
            +    });
            +
            +    function removePlaceholder() {
            +      $('#search input').attr('placeholder', '');
            +    }
            +
            +    function updateLanguage() {
            +      if (translations) {
            +        // reference title
            +        $('h1').html(translations['h1']);
            +        $('#search input').attr('placeholder', translations['reference-search']);
            +        $('#search input').on('focus', removePlaceholder);
            +        $('#search input').focusout(function () {
            +          $('#search input').attr('placeholder', translations['reference-search']);
            +        })
            +        $('#search input').attr('title', translations['reference-search']);
            +        // reference description
            +        $('#reference-description1').html(translations['reference-description1']);
            +        $('#reference-description2').html(translations['reference-description2']);
            +        $('#reference-description3').html(translations['reference-description3']);
            +        $('#reference-description4').html(translations['reference-description4']);
            +        // reference contribute
            +        $('#reference-contribute1').html(translations['reference-contribute1']);
            +        $('#reference-contribute2').html(translations['reference-contribute2']);
            +        // reference error
            +        $('#reference-error1').html(translations['reference-error1']);
            +        $('#reference-error2').html(translations['reference-error2']);
            +        $('#reference-error3').html(translations['reference-error3']);
            +        $('#reference-error4').html(translations['reference-error4']);
            +        $('#reference-error5').html(translations['reference-error5']);
            +        // reference texts
            +        $('#reference-example').html(translations['reference-example']);
            +        $('#reference-description').html(translations['reference-description'])
            +        $('#reference-extends').html(translations['reference-extends']);
            +        $('#reference-parameters').html(translations['reference-parameters']);
            +        $('#reference-syntax').html(translations['reference-syntax']);
            +        $('#reference-returns').html(translations['reference-returns']);
            +        $('.group-name, .subgroup-name').each(function() {
            +          $(this).text(translations[$(this).text()]);
            +        });
            +        var routes = window.location.hash.split('/');
            +        var obj = routes[1];
            +        var name = routes[2];
            +
            +        // class page
            +        if (routes.length == 2) {
            +          var entry = translations[obj];
            +          for (var k in entry) {
            +            if (k == 'description') {
            +              $('.description-text').html('');
            +              entry.description.forEach(function (p) {
            +                $('.description-text').append('<p>' + p + '</p>');
            +              });
            +            }
            +            else if (k == 'params') {
            +              $('.params').find('ul').children('li').each(function () {
            +                var paramname = $(this).children('.paramname').text();
            +                $(this).children('.paramtype').text(entry.params[paramname]);
            +              });
            +            }
            +            else if (k == 'returns') {
            +              $('.returns').text(entry.returns);
            +            }
            +            // fields and methods sections
            +            else {
            +              // field
            +              $("[aria-labelledby='reference-fields']").children('li').each(function (i) {
            +                var fieldName = $(this).children('.paramname').children('a').text();
            +                let descr = '';
            +                var paragraphs = entry[fieldName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +              // method
            +              $("[aria-labelledby='reference-methods']").children('li').each(function (i) {
            +                var method = $(this).children('.paramname').children('a').text();
            +                // removes the brackets
            +                var methodName = method.substring(0, method.length - 2);
            +                let descr = '';
            +                var paragraphs = entry[methodName].description;
            +                for (var i in paragraphs) {
            +                  descr += '<p>' + paragraphs[i] + '</p> ';
            +                }
            +                $(this).children('.paramtype').html(descr);
            +              });
            +            }
            +          }
            +        }
            +
            +        // method/field page
            +        if (routes.length == 3) {
            +          if (translations[obj] && translations[obj][name]) {
            +            var entry = translations[obj][name];
            +
            +            $('.description-text').html('');
            +            entry.description.forEach(function (p) {
            +              $('.description-text').append('<p>' + p + '</p>');
            +            });
            +            $('.returns').html(entry.returns);
            +            $('.params').find('ul').children('li').each(function () {
            +              var paramname = $(this).children('.paramname').text();
            +              $(this).children('.paramtype').html(entry.params[paramname]);
            +            });
            +          }
            +        }
            +      }
            +    }
            +    </script>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div><!-- end id="reference-page"  -->
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/reference/staticStrings.json b/dist/zh-Hans/reference/staticStrings.json
            new file mode 100644
            index 0000000000..4ba85d3402
            --- /dev/null
            +++ b/dist/zh-Hans/reference/staticStrings.json
            @@ -0,0 +1,16 @@
            +{
            +  "h1": "Reference",
            +  "reference-search": "Search reference",
            +  "reference-description1": "Can't find what you're looking for? You may want to check out",
            +  "reference-description3": "You can also download an offline version of the reference.",
            +  "reference-contribute2": "Please let us know.",
            +  "reference-error1": "Notice any errors or typos?",
            +  "reference-error3": "Please feel free to edit ",
            +  "reference-error5": "and issue a pull request!",
            +  "reference-example": "Example",
            +  "reference-description": "Description",
            +  "reference-extends": "Extends",
            +  "reference-parameters": "Parameters",
            +  "reference-syntax": "Syntax",
            +  "reference-returns": "Returns"
            +}
            diff --git a/dist/zh-Hans/showcase/featuring/casey-louise.html b/dist/zh-Hans/showcase/featuring/casey-louise.html
            new file mode 100644
            index 0000000000..96bfc97156
            --- /dev/null
            +++ b/dist/zh-Hans/showcase/featuring/casey-louise.html
            @@ -0,0 +1,241 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>p5.js Shaders</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <div class="glitch-embed-wrap" style="height: 420px; width: 100%;">
            +        <iframe src="https://glitch.com/embed/#!/embed/shader-on-vertex?path=&previewSize=100"
            +          title="A Glitch project showing how to apply shaders to a vertex shape in p5.js."
            +          style="height: 100%; width: 100%; border: 0;">
            +        </iframe>
            +      </div>
            +    </section>
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Casey Conchinha <span class="note">(he/him)</span></p>
            +        <p>Louise Lessél <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From New York, New York</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class='links' aria-labelledby="resources">
            +          <li><a href="https://bit.ly/p5shaders" target="_blank">p5.js Shaders guide</a></li>
            +          <li><a href="https://bit.ly/p5shadersexamples" target="_blank">Glitch collection of p5.js shader examples</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>Casey: I'm a student at NYU ITP who's interested in computer graphics and interactive spaces, physical and digital.</p>
            +        <p class='project-a'>Louise: I'm a student at NYU ITP who's interested in computer graphics and interactive spaces based on sensor technologies.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>Casey: I started learning p5.js in 2018 in my first semester at ITP, though I had been dabbling in<a href="https://processing.org/"
            +            target="_blank">Processing</a> since 2012. I was introduced to Processing by my friend Pedro while I was studying graphic design, and it blew my mind. The idea of making my own tools for creating graphics and interactive art piqued my interest, but once I actually tried it, I was hooked. The first project I can remember was an eye that followed you around the screen, and it was sad when you left it alone.</p>
            +        <p class='project-a'>Louise: I initially learned p5.js to make a website I was creating more playful. I’m a C# programmer, so this was a good segway into JavaScript for me.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>Casey: I was putting off learning shaders for a long time, and I was also curious if I could use them in p5.js. Then I heard about a grant for open source, storytelling, and learning resource projects at ITP called<a href="https://www.itpxstory.com/"
            +            target="_blank">xStory</a>. Since I wasn't finding much in the way of p5.js + shader documentation, I decided to figure out how they're implemented in p5.js and create a resource for others to learn. When I told Louise about the project, she was immediately excited about learning and teaching shaders in p5.js. She's been great about making sure the project is a learning resource and not just a collection of examples.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>Casey: Does <a href="https://thecodingtrain.com/"
            +            target="_blank">Shiffman</a> count as a feature? I also love having the ability to share my programs on the web so that people don't have to install special software or come to NYC to see my work.</p>
            +        <p class='project-a'>
            +          Louise: My favorite feature is <code><a href="https://p5js.org/reference/#/p5/push" target="_blank">push()</a></code> and <code><a href="https://p5js.org/reference/#/p5/pop" target="_blank">pop()</a></code> for transformation of the coordinate system to make generative visuals.
            +        </p>
            +
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>Casey: The beginning of the project (figuring out how things work) was us reaching out to amazing people, asking questions, and asking for permission to use their examples in our project.<a
            +            href="https://github.com/aferriss/p5jsShaderExamples"
            +            target="_blank">Adam Ferriss' GitHub repo</a> really laid the groundwork for us in understanding how shaders work in p5.js and provided a framework of approachable examples for us to build on. For some specific p5.js-related issues we were having, we reached out to <a
            +            href="http://www.katehollenbach.com/" target="_blank">Kate
            +            Hollenbach</a> and <a href="https://stalgiagrigg.name/"
            +            target="_blank">Stalgia Grigg</a> (who worked on the <a
            +            href="https://github.com/processing/p5.js/issues?q=is%3Aissue+is%3Aopen+webgl+label%3Aarea%3Awebgl"
            +            target="_blank">WebGL implementation in p5.js</a>), and they were super helpful.
            +        </p>
            +        <p class='project-a'>Louise: The learning curve was pretty steep for getting shaders into p5. Luckily, there were some very well-documented examples on GitHub by Adam Ferriss. Our aim was to do so in a way that a complete beginner can understand how to implement it, so it was as much a technical challenge as it was a challenge in teaching code to strangers and beginners. Here we drew inspiration from the way the<a
            +            href="https://openframeworks.cc/ofBook/chapters/foreword.html"
            +            target="_blank">openFrameworks book</a> is written. A fun "hey, it’s not hard and you can do it too" approach is what we believe in.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out the <a href="https://github.com/ITP-xStory"
            +            target="_blank">xStory GitHub</a> to see our peers' amazing grant projects!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'>Casey: <a href="https://cargocollective.com/kcconch"
            +            target="_blank">cargocollective.com/kcconch</a>, <a href="https://github.com/kcconch"
            +            target="_blank">@kcconch</a> (GitHub)</p>
            +        <p class='project-a'>Louise: <a href="http://www.louiselessel.com/" target="_blank">louiselessel.com</a>, <a
            +            href="https://github.com/louiselessel" target="_blank">@louiselessel</a> (GitHub)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/showcase/featuring/daein-chung.html b/dist/zh-Hans/showcase/featuring/daein-chung.html
            new file mode 100644
            index 0000000000..2988d5f806
            --- /dev/null
            +++ b/dist/zh-Hans/showcase/featuring/daein-chung.html
            @@ -0,0 +1,226 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Chillin'</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only' id="info">Project Info</h2>
            +      <img src="../../../assets/img/showcase/daein-chung/daein-chung_chillin.png" alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device.
            +        At the top, there is a text input box to enter a message and download your own poster.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Dae In Chung <span class="note">(he/him)</span></p>
            +        <p class="creator-from">From Baltimore, Maryland</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class="links">
            +          <li><a href="https://exp.paperdove.com/chillin/" target="_blank">View Chillin'</a></li>
            +          <li><a href="https://github.com/cdaein/exp/tree/gh-pages/chillin"
            +              target="_blank">Code for Chillin' on GitHub</a></li>
            +          <li><a href="https://paperdove.com/work/2019-chillin/" target="_blank">More info in Dae In Chung's Portfolio</a>
            +          </li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I am a graphic designer and a faculty member at Maryland Institute College of Art, where I mainly teach coding (with p5.js and Processing, of course) and motion graphics.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I have been using <a href="https://processing.org/"
            +            target="_blank">Processing</a> for some time, and when p5.js came along, I started using it without a second thought because it was easy to convert existing Processing code and share projects online.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>This summer, I gave myself a challenge of making typographic posters with coding, and this is one of the posters I made. I didn’t know until very recently that I could use motion sensor data with p5.js. I was also watching<a
            +            href="https://www.youtube.com/playlist?list=PLRqwX-V7Uu6bLh3T_4wtrmVHOrOEM1ig_"
            +            target="_blank">Dan Shiffman’s matter.js tutorial videos</a>, so I thought why not combine the two and practice what I was learning?
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>There are many things I love about p5.js such as the online community and beginner friendliness. What I really like right now is the<a href="https://editor.p5js.org/"
            +            target="_blank">online editor</a>, with which I can not only work online for myself but also share URLs quickly in the present mode. For this project in particular, I had to do a lot of testing on my phone, and it was much easier and quicker than committing to GitHub.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>I had some troubles with handling font, alpha channel and z-depth in <a
            +            href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5"
            +            target="_blank">WebGL</a> mode. I am still not happy with all my decisions. But in general, it was helpful to search the forum and not to forget to break down problems into smaller ones and iterate little by little. Also, I had issues with rendering out video files directly out of p5.js. Screen recording was not an option because of intermittent frame rate drops (my laptop is pretty slow). After doing some research, I decided to learn some basics of <a href="https://electronjs.org/"
            +            target="_blank">Electron</a> and build a tool for myself.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>As mentioned above, if you want to render out frames and video files out of p5.js sketches, check out my<a
            +            href="https://github.com/cdaein/p5js-electron-canvas-saver-boilerplate" target="_blank">Canvas Saver
            +            boilerplate</a> and let me know what you think.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/cdaein/" target="_blank">@cdaein</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/showcase/featuring/moon-xin.html b/dist/zh-Hans/showcase/featuring/moon-xin.html
            new file mode 100644
            index 0000000000..985736a6ab
            --- /dev/null
            +++ b/dist/zh-Hans/showcase/featuring/moon-xin.html
            @@ -0,0 +1,233 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Moving Responsive Posters</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png"
            +        alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Moon Jang <span class="note">(she/her)</span></p>
            +        <p>Xin Xin <span class="note">(they/them)</span></p>
            +        <p class="creator-from">From Athens, Georgia</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Posters By</h3>
            +        <ul class="links">
            +          <li><a href="https://editor.p5js.org/avezray/present/JTjhOdGRB" target="_blank">Avery Ray</a></li>
            +          <li><a href="https://editor.p5js.org/carcarw/present/DyKJHUtCN" target="_blank">Carlee Wooddell</a></li>
            +          <li><a href="https://editor.p5js.org/mdh54215/present/h5wp4EYen" target="_blank">Mia Hofmann</a></li>
            +          <li><a href="https://editor.p5js.org/katiehuang1998@gmail.com/present/1GhSDw-Og" target="_blank">Katie
            +              Huang</a></li>
            +          <li><a href="https://editor.p5js.org/borderrider@gmail.com/present/Lg_pSPRHF" target="_blank">Lila
            +              Mitchell</a></li>
            +          <li><a href="https://editor.p5js.org/wallacekd/present/GqWZOYUSN" target="_blank">Kathryn Wallace</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>Moon: I'm a graphic designer, visual artist, and design educator. This summer, I taught a graphic design course in the University of Georgia Cortona program in Italy, introducing some basics of p5.js. This fall, I am planning to teach and to study digital platforms at UGA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>My former colleague, <a href="https://xin-xin.info/" target="_blank">Xin
            +            Xin</a>, invited me to <a href="https://medium.com/processing-foundation/pcd/home"
            +            target="_blank">Processing Community Day</a> in <a
            +            href="https://day.processing.org/pcd-la.html"
            +            target="_blank">LA in January 2019</a>. They helped me with the tools and logics of p5.js. It was an excellent teaching and learning experience.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>We followed basic tutorials, <a href="https://thecodingtrain.com/"
            +            target="_blank">Daniel's videos on YouTube</a>, and <a
            +            href="https://p5js.org/reference/"
            +            target="_blank">Reference on the p5.js website</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>My favorite function is related to <a
            +            href="https://p5js.org/reference/#group-Typography"
            +            target="_blank">type</a> and <a
            +            href="https://p5js.org/reference/#group-Transform"
            +            target="_blank">transformation</a>: <code><a href="https://p5js.org/reference/#/p5/rotate" target="_blank">rotate()</a></code>. I was able to use and to teach this tool to visualize various ideas about time in motion.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>It was challenging for me, a beginner, to understand the overall structure of p5.js and how code works in general. I had to repeat the p5.js basics a couple of times, and then I drew a chart to memorize and to teach the way I understood the p5.js structure and code with strong constraints I set up. It was an excellent teaching and learning experience.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out the <a href="http://www.brokennature.org/"
            +            target="_blank">Design Triennale</a> in Milan, Italy.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="http://www.moonjang.com/" target="_blank">moonjang.com</a>
            +          <br><a href="https://www.instagram.com/borderrider/" target="_blank">@borderrider</a> (Instagram)
            +        </p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/showcase/featuring/phuong-ngo.html b/dist/zh-Hans/showcase/featuring/phuong-ngo.html
            new file mode 100644
            index 0000000000..b9023564e1
            --- /dev/null
            +++ b/dist/zh-Hans/showcase/featuring/phuong-ngo.html
            @@ -0,0 +1,233 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Airi Flies</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" alt="A screenshot of a poster of Airi Flies, a game to help Airi fly by saying pew.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Phuong Ngo <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From Kyiv, Ukraine</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://www.yonaymoris.me/AiriFlies/" target="_blank">Play Airi Flies!</a></li>
            +          <li><a href="https://github.com/yonaymoris/AiriFlies" target="_blank">Code for AiriFlies on GitHub</a>
            +          </li>
            +          <li><a href="https://www.yonaymoris.me/projects/airiflies"
            +              target="_blank">More info in Phuong Ngo's portfolio</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I'm a creative coder and designer, a <a href="https://schoolofma.org/"
            +            target="_blank">School of Machines, Making & Make-Believe</a> diversity scholarship recipient, and just a curious creature.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I was taking a course at the School of Machines in Berlin this summer called! "<a href="https://schoolofma.org/bots.html"
            +            target="_blank">Bots and Machine Learning</a>," mainly taught by <a
            +            href="https://1023.io/" target="_blank">Yining Shi</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>I used p5.js to work on the visual part of the game. The animation sprites for Airi and the ghosts were drawn on an iPad app called<a href="https://rizer.co/pixaki/"
            +            target="_blank">Pixaki</a> and then integrated into <a
            +            href="http://molleindustria.github.io/p5.play/"
            +            target="_blank">p5.play</a> code. I mainly used examples at p5.play as a reference.</p>
            +        <p class='project-a'>For the endless scrolling background, I found a <a
            +            href="https://editor.p5js.org/chjno/sketches/ByZlypKWM"
            +            target="_blank">p5 sketch by chjno</a>. I set a condition so whenever the word "pew" or a mouse click was detected, the scrolling speed would change to make an illusion of Airi flying up. When the user does not do anything, the scrolling speed is negative, which makes it look like Airi is falling down.
            +        </p>
            +        <p class='project-a'>For sound recognition, I used <a
            +            href="https://teachablemachine.withgoogle.com/io19" target="_blank">Google's Teachable Machine
            +            2</a> (currently, there is a beta version not available in public yet, but it will be very soon!). I added around 120 samples of my classmates saying the word "pew" with different intonations and 80 samples of background noise to train it. Then I integrated the model into the game with <a href="https://ml5js.org/" target="_blank">ml5.js</a>.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>I really love how easily you can create, manipulate, and delete HTML blocks and classes with the<a href="https://p5js.org/reference/"
            +            target="_blank">p5.js
            +            library</a> via <code><a href="https://p5js.org/reference/#/p5/createDiv" target="_blank">createDiv()</a></code>,
            +          <code><a href="https://p5js.org/reference/#/p5.Element/addClass" target="_blank">addClass()</a></code> etc. But my most favorite function is <code><a href="https://p5js.org/reference/#/p5/draw" target="_blank">draw()</a></code>, since this is where you create magic.
            +        </p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>There were a lot of challenges simply because p5.js was something new to me. I did not work much with JavaScript in general before. Reading documentation and searching for similar examples helped a lot.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>Check out <a href="https://schoolofma.org/programs"
            +            target="_blank">School of Machines' courses</a>! They try hard to connect the most creative people in the world and they do it well so far. ❤️
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://www.yonaymoris.me/" target="_blank">yonaymoris.me</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/showcase/featuring/qianqian-ye.html b/dist/zh-Hans/showcase/featuring/qianqian-ye.html
            new file mode 100644
            index 0000000000..ca459691d1
            --- /dev/null
            +++ b/dist/zh-Hans/showcase/featuring/qianqian-ye.html
            @@ -0,0 +1,222 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Qtv</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img src="../../../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" alt="A guest talk video (Guest Talk #1) on Qtv by Qianqian Ye, featuring Kaikai and Cheng Xu.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Qianqian Ye <span class="note">(she/her)</span></p>
            +        <p class="creator-from">Los Angeles, California</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Resources</h3>
            +
            +        <ul class="links">
            +          <li><a href="https://bit.ly/2XVzPAv" target="_blank">Qtv YouTube</a></li>
            +          <li><a href="https://www.instagram.com/q_tv_/" target="_blank">Qtv Instagram</a></li>
            +          <li><a href="https://space.bilibili.com/442343394" target="_blank">Qtv Bilibili</a></li>
            +          <li><a href='https://v.douyin.com/sopAGk/' target='_blank'>@Q_tv TikTok</a></li>
            +          <li><a href="https://medium.com/processing-foundation/interview-with-2019-fellow-qianqian-ye-799c0115c295"
            +              target="_blank">Processing Foundation interview with Qianqian Ye</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I am a Chinese artist and designer based in Los Angeles.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>My partner introduced me to p5.js, which I learned mainly by watching free online video tutorials. My first p5.js project was drawing some shapes with different colors.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>This project started with an idea of teaching my mom, who lives in China and doesn’t speak English, to code with p5.js. This project was difficult on multiple levels, and I wanted to start by identifying the main reasons why it’s more challenging for someone like my mother to learn to code—primarily due to the lack of free creative coding education resources. Most of the free resources to learn creative coding are unavailable in China. The p5.js tutorials on YouTube as well as the p5.js Twitter and Instagram accounts are inaccessible in China because of internet censorship.</p>
            +        <p class='project-a'>I learned a lot from YouTube videos such as the <a href="https://thecodingtrain.com/"
            +            target="_blank">Coding Train</a>, but the more I watched coding tutorials online, the more I realized how difficult it is to find other womxn and people of color teaching coding, especially in Mandarin. I wanted to help other Chinese womxn relate to creative coding.</p>
            +        <p class='project-a'>I am working on opening up the video channels to other Chinese creatives who want to contribute to the educational resource together, like interviews and guest tutorials. If you are interested in teaching/talking about creative coding in Mandarin, HMU!</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>The <a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a> is my favorite feature. It makes web-based creative coding seamless.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>Learning to code in a second language was difficult and the lack of community made this process even harder. I hope to speak from my experience as a beginner and someone who once felt like an outsider to the creative coding and video tutorial world.</p>
            +        <p class='project-a'>I spend a lot of time researching the latest technology for my videos. In the end, I decided on using my phone to record and iMovie to edit. I hope to encourage others that it doesn’t take a lot of expensive gears to get started making instructional videos.</p>
            +        <p class='project-a'>Another issue I came across was my own fear of putting myself online. I first had to get over my anxiety of making mistakes in the videos or receiving negative comments online. Often womxn and people of color are targets for online harassment. I’m hoping to help set an example for other womxn and people of color that it’s ok to put yourselves online and strengthen your communities by sharing your knowledge. Eventually, we will be able to stop online harassment by creating strong diverse communities.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'>I am very excited about <a href="http://tinytechzines.org/"
            +            target="_blank">Tiny Tech Zines</a> in LA.</p>
            +      </div>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="http://www.qianqian-ye.com/" target="_blank">qianqian-ye.com</a></p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/showcase/featuring/roni-cantor.html b/dist/zh-Hans/showcase/featuring/roni-cantor.html
            new file mode 100644
            index 0000000000..7c7efa7fd1
            --- /dev/null
            +++ b/dist/zh-Hans/showcase/featuring/roni-cantor.html
            @@ -0,0 +1,222 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main id="content" class="column-span project-page">
            +    <h1>Programmed Plotter Drawings</h1>
            +
            +    <section class="project-info">
            +      <h2 class='sr-only'>Project Info</h2>
            +      <img class='half-image' src="../../../assets/img/showcase/roni-cantor/roni-cantor_plotter-turquoise.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a turquoise gel pen.">
            +      <img class='half-image' src="../../../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg"
            +        alt="A drawing of a sine wave lerp plotted on black paper with an AxiDraw V3 and a white gel pen.">
            +    </section>
            +
            +    <section class="project-metadata">
            +      <h2 class='sr-only'>Project Authors and Links</h2>
            +      <section class="project-credit">
            +        <h3>Created By</h3>
            +        <p>Roni Cantor <span class="note">(she/her)</span></p>
            +        <p class="creator-from">From Toronto, Canada</p>
            +      </section>
            +
            +      <section class="project-resources">
            +        <h3 id="resources">Project Links</h3>
            +        <ul class="links" aria-labelledby="resources">
            +          <li><a href="https://editor.p5js.org/ronicantor/sketches/eq2bIhmh2"
            +              target="_blank">Example sketch in p5.js Web Editor</a></li>
            +          <li><a href="https://drive.google.com/file/d/1UJy6q5cDl6Hg79O9mX1ZN7NFp0NXSYCs/view?usp=sharing"
            +              target="_blank">AxiDraw V3 demo video</a></li>
            +        </ul>
            +      </section>
            +    </section>
            +
            +    <section>
            +      <h2 id="qa">Q&amp;A</h2>
            +
            +      <div class="qa-group">
            +        <h3 class='project-q'>What are you up to?</h3>
            +        <p class='project-a'>I just graduated from Ryerson University's New Media program. Coming from 4 years of coding and making robots, I decided to take a break and play with some more traditional forms of art—while still coding and playing with robots.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you get started with p5.js?</h3>
            +        <p class='project-a'>I first started using p5.js at <a href="https://itp.nyu.edu/camp2019/"
            +            target="_blank">NYU ITP Camp</a>! After using <a
            +            href="https://processing.org/" target="_blank">Processing</a> for many years, I wanted to try something new.
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>How did you use p5.js in this project?</h3>
            +        <p class='project-a'>I used p5.js in this project to generate the sine wave and lerp (linear interpolation) formulas and display the visuals in the<a href="https://editor.p5js.org/"
            +            target="_blank">p5.js Web Editor</a>. I then used a feature in my code that exported my programmed graphic into an<a
            +            href="https://developer.mozilla.org/en-US/docs/Web/SVG"
            +            target="_blank">SVG</a> file. I needed an SVG file to give to the plotter—an <a
            +            href="https://shop.evilmadscientist.com/productsmenu/846" target="_blank">AxiDraw
            +            V3</a>—so that it understood where to draw the lines that I programmed. I sent this information to the plotter with a program called<a href="https://inkscape.org/"
            +            target="_blank">Inkscape</a>!</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's your favorite p5.js feature?</h3>
            +        <p class='project-a'>
            +          <code><a href="https://p5js.org/reference/#/p5/lerp" target="_blank">lerp()</a></code> because lines are fun and "lerp" is a fun word to say!
            +        </p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Did you face any challenges working on this project? If so, how did you overcome them?</h3>
            +        <p class='project-a'>It was my first time using p5.js, Inkscape, and a plotter! I really benefited from the people around me who had used p5 before, as well as online guides and forums.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>What's a cool thing we should check out?</h3>
            +        <p class='project-a'><a href="https://www.instagram.com/gandyworks/"
            +            target="_blank">@gandyworks</a> on Instagram—super cool analog plotter stuff.</p>
            +      </div>
            +      <div class="qa-group">
            +        <h3 class='project-q'>Where can people learn more about you?</h3>
            +        <p class='project-a'><a href="https://ronicantor.com/" target="_blank">ronicantor.com</a>
            +          <br><a href="https://www.instagram.com/roni.cantor/"
            +            target="_blank">@roni.cantor</a> (Instagram)</p>
            +      </div>
            +    </section>
            +    <div style='clear:both'></div>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/showcase/index.html b/dist/zh-Hans/showcase/index.html
            new file mode 100644
            index 0000000000..76e99248e9
            --- /dev/null
            +++ b/dist/zh-Hans/showcase/index.html
            @@ -0,0 +1,246 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">showcase | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="showcase-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            +  <main  id="content" class="column-span">
            +    <section class="showcase-intro">
            +      <h1>Showcase</h1>
            +      
            +      <p>这是p5.js展示区,由<a href="https://ashleykang.dev" target="_blank">Ashley Kang</a>
            +      在2019年建立,目前由<a href="https://katiechan.cargo.site/" target="_blank">Katie Chan</a>.
            +      策划。我们在展示人们如何使用p5.js使创意工作,学习和开源变得更加有趣和包容。我们在一起,共同建立社区。在2019年夏季,我们邀请了一些创作者来分享更多有关他们如何通过不同项目和作品使用p5.js。</p>
            +      <p>2020年夏季展示区现已开始接受报名,提名某人的p5.js作品或您自己的作品在这里进行展示!</p>
            +
            +      <span id="nominate" class="nominate"><a href="https://forms.gle/ETP7kjAocBcfGTuj8" target="_blank">提名作品</a></span>
            +    </section>
            +
            +    <section class="showcase-featured">
            +      <h2 class="featuring">Featuring</h2>
            +
            +      <div class="left-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/roni-cantor.html">Programmed Plotter Drawings</a></h3>
            +          <p class="credit">Roni Cantor</p>
            +          <a href="./featuring/roni-cantor.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/roni-cantor/roni-cantor_plotter-white.jpg" 
            +            alt="A drawing of a sine wave lerp plotted on black paper using an AxiDraw V3 and a white gel pen.">
            +          </a>
            +          <p class="description">Sine waves and lerps generated in p5.js, exported as SVG, and drawn with a plotter and pens.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5/lerp">lerp()</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/daein-chung.html">Chillin'</a></h3>
            +          <p class="credit">Dae In Chung</p>
            +          <a href="./featuring/daein-chung.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/daein-chung/daein-chung_chillin.png" 
            +              alt="A screenshot of a poster with red and yellow circles of letters from the word chillin against a blue tile background that changes perspective on a mobile device. 
            +              At the top, there is a text input box to enter a message and download your own poster">
            +          </a>
            +          <p class="description">An interactive typographic poster that uses a mobile device's motion sensor with p5.js.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="https://brm.io/matter-js/">matter.js</a></li>
            +            <li><a class="tag" href="https://github.com/processing/p5.js/wiki/Getting-started-with-WebGL-in-p5">p5 WebGL</a></li>
            +            <li><a class="tag" href="https://p5js.org/reference/#/p5.Camera">p5.Camera</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/casey-louise.html">p5.js Shaders</a></h3>
            +          <p class="credit">Casey Conchinha, Louise Lessél</p>
            +          <a href="./featuring/casey-louise.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/casey-louise/casey-louise_p5js-shaders.png" 
            +              alt="A screenshot of the Introduction page of the p5.js Shaders guide website">
            +          </a>
            +          <p class="description">A resource for learning the what, why, and how of using shaders in p5.js.</p>
            +          <ul class="project-tags">
            +         </ul>
            +        </div>
            +      </div>
            +
            +      <div class="right-column">
            +        <div>
            +        <h3 class="title"><a href="./featuring/phuong-ngo.html">Airi Flies</a></h3>
            +          <p class="credit">Phuong Ngo</p>
            +          <a href="./featuring/phuong-ngo.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/phuong-ngo/phuong-ngo_airi-flies.png" 
            +              alt="A screenshot of the instructions and scoreboard for the online game Airi Flies">
            +          </a>
            +          <p class="description">In this game developed with p5.play, help Airi fly by saying PEW. Created to encourage people to get out of their comfort zone and feel more confident about themselves regardless of what they do and how they look or sound.</p>
            +          <ul class="project-tags">
            +            <li><a class="tag" href="http://molleindustria.github.io/p5.play/">p5.play</a></li>
            +            <li><a class="tag" href="https://ml5js.org/">ml5.js</a></li>
            +          </ul>
            +        </div>
            +
            +        <div>
            +          <h3 class="title"><a href="./featuring/qianqian-ye.html">Qtv</a></h3>
            +          <p class="credit">Qianqian Ye</p>
            +          <a href="./featuring/qianqian-ye.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/qianqian-ye/qianqian-ye_qtv.png" 
            +              alt="A screenshot of a Qtv video (Guest Talk #1) featuring Chinese womxn designers and artists Kaikai and Cheng Xu">
            +          </a>
            +          <p class="description">A video channel with 1-minute videos in Mandarin about creative coding, art, and technology, including p5.js tutorials for beginners. Available on YouTube, Instagram, Bilibili, and TikTok.</p>
            +          <ul class="project-tags">
            +          </ul>
            +        </div>
            +
            +        <div>
            +        <h3 class="title"><a href="./featuring/moon-xin.html">Moving Responsive Posters</a></h3>
            +          <p class="credit">Moon Jang, Xin Xin, and students</p>
            +          <a href="./featuring/moon-xin.html" class="no-arrow-link">
            +            <img src="../../assets/img/showcase/moon-xin/moon-xin_poster-carlee.png" 
            +              alt="A screenshot of student Carlee Wooddell's poster that interprets the word zigzag using letters that bounce left and right">
            +          </a>
            +          <p class="description">Browser-based moving posters that use graphical systems, transformation methods, and p5.js to address the connotations of a word less than 8 letters. Designed by students for a graphic design course (Visual Narrative Systems) at the University of Georgia.</p>
            +          <ul class="project-tags">
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/rect">rect()</a></li>
            +              <li><a class="tag" href="https://p5js.org/reference/#/p5/translate">translate()</a></li>
            +          </ul>
            +        </div>
            +      </div>
            +    </section>
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/dist/zh-Hans/teach/index.html b/dist/zh-Hans/teach/index.html
            new file mode 100644
            index 0000000000..59a55c5b99
            --- /dev/null
            +++ b/dist/zh-Hans/teach/index.html
            @@ -0,0 +1,857 @@
            +<!DOCTYPE html>
            +<html class="no-js" lang="zh-Hans">
            +  <head>
            +    <meta charset="utf-8">
            +    <meta http-equiv="X-UA-Compatible" content="IE=edge">
            +    <meta name="viewport" content="width=device-width, initial-scale=1">
            +    <meta name="description" content="p5.js a JS client-side library for creating graphic and interactive experiences, based on the core principles of Processing.">
            +    <title tabindex="1">teach | p5.js</title>
            +    <link rel="stylesheet" href="/assets/css/all.css?v=fd72a4">
            +    <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">
            +    <link href="https://fonts.googleapis.com/css2?family=Inconsolata&display=swap" rel="stylesheet">
            +
            +    <link rel="shortcut icon" href="/../../assets/img/favicon.ico">
            +    <link rel="icon" href="/../../assets/img/favicon.ico">
            +
            +
            +    <script src="/../../assets/js/vendor/jquery-1.12.4.min.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/ace.js"></script>
            +    <script src="/../../assets/js/vendor/ace-nc/mode-javascript.js"></script>
            +    <script src="/../../assets/js/vendor/prism.js"></script>
            +    <script src="/assets/js/init.js?v=6be92f"></script>
            +
            +    <script src="/../../assets/js/vendor/pangu.min.js"></script>
            +
            +  </head>
            +  <body>
            +
            +    <a href="#content" class="sr-only">跳到内容</a>
            +    
            +    <!-- p5*js language buttons -->
            +    <div id="i18n-btn">
            +      <h2 id="i18n-settings" class="sr-only">语言设定</h2>
            +      <ul id="i18n-buttons" aria-labelledby="i18n-settings">
            +        <li><a href='#' lang='en' data-lang='en'>English</a></li>
            +        <li><a href='#' lang='es' data-lang='es'>Español</a></li>
            +        <li><a href='#' lang='zh-Hans' data-lang='zh-Hans'>简体中文</a></li>
            +        <li><a href='#' lang='ko' data-lang='ko'>한국어</a></li>
            +        <li><a href='#' lang='hi' data-lang='hi'>हिन्दी</a></li>
            +      </ul>
            +    </div>    <!-- .container -->
            +    <div class="container">
            +
            +      <!-- logo -->
            +      <header id="lockup">
            +        <a href="/zh-Hans/">
            +          <img src="/../../assets/img/p5js.svg" alt="p5 homepage" id="logo_image" class="logo" />
            +          <div id="p5_logo"></div>
            +        </a>
            +      </header>
            +      <!-- close logo -->
            +
            +      
            +
            +<div id="teach-page">
            +
            +  
            +  <!-- site navigation -->
            +  <div class="column-span">
            +    <nav class="sidebar-menu-nav-element">
            +      <h2 id="menu-title" class="sr-only">网站导航</h2>
            +      <input class="sidebar-menu-btn" type="checkbox" id="sidebar-menu-btn" />
            +      <label class="sidebar-menu-icon" for="sidebar-menu-btn"><span class="sidebar-nav-icon"></span></label>
            +      <ul id="menu" class="sidebar-menu" aria-labelledby="menu-title">
            +        <li><a href="/zh-Hans/">主页</a></li>
            +        <li><a href="https://editor.p5js.org">编辑器</a></li>
            +        <li><a href="/zh-Hans/download/">下载</a></li>
            +        <li><a href="/zh-Hans/download/support.html">捐赠</a></li>
            +        <li><a href="/zh-Hans/get-started/">入门</a></li>
            +        <li><a href="/zh-Hans/reference/">参考文献</a></li>
            +        <li><a href="/zh-Hans/libraries/">程式库</a></li>
            +        <li><a href="/zh-Hans/learn/">学习</a></li>
            +        <li><a href="/zh-Hans/teach/">教学</a></li>
            +        <li><a href="/zh-Hans/examples/">范例</a></li>
            +        <li><a href="/zh-Hans/books/">书籍</a></li>
            +        <li><a href="/zh-Hans/community/">社群</a></li>
            +        <li><a href="https://showcase.p5js.org">案例展示</a></li>
            +        <li><a href="https://discourse.processing.org/c/p5js" target=_blank class="other-link">论坛</a></li>
            +        <li><a href="http://github.com/processing/p5.js" target=_blank class="other-link">GitHub</a></li>
            +        <li><a href="http://twitter.com/p5xjs" target=_blank class="other-link">Twitter</a></li>
            +        <li><a href="https://www.instagram.com/p5xjs/" target=_blank class="other-link">Instagram</a></li>
            +        <li><a href="https://discord.gg/SHQ8dH25r9" target=_blank class="other-link">Discord</a></li>
            +      </ul>
            +    </nav>
            +  </div>
            +
            + <main id="content" class="column-span">
            +  	<section class= "teach-intro">
            +      <h1>Teach</h1>
            +
            +	      <p>Every teaching has its own unique goals, messages, conditions, and environments.By documenting and sharing p5 workshops, classes, and materials, we hope to better connect the p5.js learner and educator communities around the world.<a href="" onclick= "window.open('https://docs.google.com/forms/d/e/1FAIpQLSei8yHX2BROMnMQeZT_tsSXJOH13TPRG6CB4GVHH1oL1hzkZg/viewform?usp=sf_link', '_blank')">Share or recommend</a> your own teaching experiences, too!</p>
            +						
            +    </section>
            +
            +	<section>
            +
            +		<div id="resources"></div>
            +			<h2 class = "heading">p5 Teaching Resources</h2> 
            +			
            +			<div class="search-filter"><input type="checkbox"><label> Search Filter &#x2192;</label></div>
            +
            +     		<!-- search-results -->
            +
            +     		<div class="filter-panel">
            +
            +							
            +				<ul class="filters" id="filters">
            +
            +					<li><p class = "filter-title">&#x1F33A; Diversity & Inclusion : </p></li>
            +					<li><input type="checkbox" id="gender" value="gender"><label for="gender">Gender</label></li>
            +					<li><input type="checkbox" id="race-ethnicity" value="race-ethnicity"><label for="race-ethnicity">Race & Ethnicity</label></li>
            +					<li><input type="checkbox" id="language" value="language"><label for="language">Language</label></li>
            +					<li><input type="checkbox" id="neuro-type" value="neuro-type"><label for="neuro-type">Neuro-Type</label></li>
            +					<li><input type="checkbox" id="ability" value="ability"><label for="ability">Ability</label></li>
            +					<li><input type="checkbox" id="class" value="class"><label for="class">Class</label></li>
            +					<li><input type="checkbox" id="religion" value="religion"><label for="religion">Religion</label></li>
            +					<li><input type="checkbox" id="subculture" value="subculture"><label for="subculture">(Sub-)Culture</label></li>
            +					<li><input type="checkbox" id="political-opinion" value="political-opinion"><label for="political-opinion">Political Opinion</label></li>
            +					<li><input type="checkbox" id="age" value="age"><label for="age">Age</label></li>
            +					<li><input type="checkbox" id="skill-level" value="skill-level"><label for="skill-level">Skill Level</label></li>
            +					<li><input type="checkbox" id="occupation" value="occupation"><label for="occupation">Occupation</label></li>
            +					<li><input type="checkbox" id="noCodeSnobs" value="noCodeSnobs"><label for="noCodeSnobs">#noCodeSnobs</label></li>
            +					<li><input type="checkbox" id="newKidLove" value="newKidLove"><label for="newKidLove">#newKidLove</label></li>
            +					<li><input type="checkbox" id="unassumeCore" value="unassumeCore"><label for="unassumeCore">#unassumeCore</label></li>
            +					<li><input type="checkbox" id="BlackLivesMatter" value="BlackLivesMatter"><label for="BlackLivesMatter">#BlackLivesMatter</label></li>
            +							
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CD; Venue : </p></li>
            +
            +					<li><input type="checkbox" id="africa" value="africa"><label for="africa">Africa</label></li>
            +					<li><input type="checkbox" id="asia" value="asia"><label for="asia">Asia</label></li>
            +					<li><input type="checkbox" id="europe" value="europe"><label for="europe">Europe</label></li>
            +					<li><input type="checkbox" id="north-america" value="north-america"><label for="north-america">North America</label></li>
            +					<li><input type="checkbox" id="oceania" value="oceania"><label for="oceania">Oceania</label></li>
            +					<li><input type="checkbox" id="south-america" value="south-america"><label for="south-america">South America</label></li>
            +					<li><input type="checkbox" id="virtual-online" value="virtual-online"><label for="virtual-online">Virtual-Online  &#x1F310;</label></li>
            +
            +
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4C5; Year : </p></li>
            +					<li><input type="checkbox" id="2014" value="2014"><label for="2014">~2014</label></li>
            +					<li><input type="checkbox" id="2015" value="2015"><label for="2015">2015</label></li>
            +					<li><input type="checkbox" id="2016" value="2016"><label for="2016">2016</label></li>
            +					<li><input type="checkbox" id="2017" value="2017"><label for="2017">2017</label></li>
            +					<li><input type="checkbox" id="2018" value="2018"><label for="2018">2018</label></li>
            +					<li><input type="checkbox" id="2019" value="2019"><label for="2019">2019</label></li>
            +					<li><input type="checkbox" id="2020" value="2020"><label for="2020">2020</label></li>
            +
            +					<li class="clear"></li>
            +					<li><p class = "filter-title">&#x1F4CA; Level of Difficulty : </p></li>
            +					<li><input type="checkbox" id="elementary" value="elementary"><label for="elementary">Elementary</label></li>
            +					<li><input type="checkbox" id="intermediate" value="intermediate"><label for="intermediate">Intermediate</label></li>
            +					<li><input type="checkbox" id="advanced" value="advanced"><label for="advanced">Advanced</label></li>
            +				 </ul>
            +
            +						  <br>
            +								
            +
            +			</div>
            +												
            +			<div class = "results-wrapper">
            +
            +						
            +				<div class="results" id="search-results">
            +					<ul>
            +				  		<li class="case-list" data-category="2019 europe gender race-ethnicity age skill-level BlackLivesMatter advanced"><a href="#case1" class="caseBtn" >"p5.js à l'Ubuntu Party!", Basile Pesin</a></li>
            +
            +				  		 <li class="case-list" data-category="2020 asia age skill-level occupation elementary advanced"><a href="#case2" class="caseBtn">"Making The Thing that Makes the Thing: Exploring Generative Art &#x0026; Design with p5.js", Priti Pandurangan &#x0026; Ajith Ranka</a></li>
            +
            +						  <li class="case-list" data-category="2016 2019 2020 elementary intermediate advanced north-america gender race-ethnicity language neuro-type ability subculture occupation north-america"><a href="#case3" class="caseBtn">CC Fest (Creative Coding Festival), Saber</a></li>
            +
            +						  <li class="case-list" data-category="2018 virtual-online south-america gender race-ethnicity language neuro-type religion subculture age noCodeSnobs newKidLove unassumeCore elementary intermediate advanced"><a href="#case4" class="caseBtn" >"Taller Introducci&#x00F3;n a la Programaci&#x00F3;n Creativa con p5.js", Aar&#x00F3;n Montoya-Moraga</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america gender race-ethnicity class subculture age skill-level elementary"><a href="#case5" class="caseBtn" >"Introduction to Generative Drawing", Adam Herst</a></li>
            +
            +						  <li class="case-list" data-category="2020 asia virtual-online gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation elementary"><a href="#case6" class="caseBtn" >Open Lecture "Creative Coding: 2020", Shunsuke Takawo</a></li>
            +
            +
            +						  <li class="case-list" data-category="2020 asia gender race-ethnicity language neuro-type Size skill-level ability class religion subculture political-opinion age skill-level occupation intermediate"><a href="#case7" class="caseBtn" >"Creative Coding for Static Graphics", Shunsuke Takawo</a></li>
            +
            +						  <li class="case-list" data-category="2020 north-america virtual-online race-ethnicity language subculture skill-level"><a href="#case8" class="caseBtn" >"Generative Typography", Dae In Chung</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity language age skill-level occupation noCodeSnobs new unassumeCore BlackLivesMatter elementary intermediate"><a href="#case9" class="caseBtn" >"Machine Learning for the Web", Yining Shi</a></li>
            +
            +
            +						  <li class="case-list" data-category="europe virtual-online gender elementary"><a href="#case10" class="caseBtn" >"Introduction to p5.js and JavaScript", Nico Reski</a></li>
            +
            +						  <li class="case-list" data-category="2019 north-america gender race-ethnicity skill-level occupation"><a href="#case11" class="caseBtn">"Digital Weaving &#x0026; Physical Computing Workshop Series", Qianqian Ye &#x0026; Evelyn Masso</a></li>
            +
            +						  <li class="case-list" data-category="2015 2020 north-america asia gender race-ethnicity language neuro-type ability class skill-level"><a href="#case12" class="caseBtn">"Signing Coders", Taeyoon Choi</a></li>
            +	    			</ul>
            +						<br>
            +				</div> 
            +			</div>
            +						
            +
            +						
            +
            +		<!--modal box section-->
            +		
            +			<!--modal boxes-->
            +
            +			<div id="caseModals" class="modal">
            +
            +				<!--modal box #1-->
            +
            +				  <div class="modal-content" id="case1"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>p5.js à l'Ubuntu Party!</span></li>
            +				        	<li class = "case"><p class="lead-name">Basile Pesin</p></li>
            +
            +				          	<li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date<p><a href="https://ubuntu-paris.org/">2020 Ubuntu Party, </a>Cité des Sciences et de l'Industrie, Paris, France</p></li> 
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Any age, including children and parents, young and older adults.
            +				            </p></li>		         
            +
            +				            <li class = "clear"></li>  				
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To introduce a new public to programming through fun and compelling examples.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Method: in-person workshop, 1 hour per session, with different participant each times. The students were using (Ubuntu) machines with the p5.js web editor. I was teaching using a video projector as well as a board.</p><p>Materials: The exercises I gave where accessible through p5.js web-editor links available in<a href = "https://vertmo.github.io/ubuntu-party-p5/">GitHub</a>.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Age</label><label>Skill Level</label><label>#BlackLivesMatter</label>
            +				            </li>
            +		             
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				<!--modal box #2-->
            +	
            +				  <div class="modal-content" id="case2"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Making The Thing that Makes the Thing: Exploring Generative Art & Design with p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Priti Pandurangan & Ajith Ranka</p></li>
            +				        	
            +				        	<li class = "clear"></li>
            +             				<li class = "clear"></li>
            +             				<li class = "case"><img src="https://drive.google.com/uc?id=1udID-B1qADY7QxDkYkAh6ZYX7D8BfrnD" alt="A group of participants collaborating to create some designs using the p5.js web editor on their laptops."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date<p>&#x1F4CD; National Institute of Design, Bangalore</p><p>&#x1F4C5; 2020 February 8, 2:30-4:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Priti: Intermediate & Ajith: Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To explore generative art &#x0026; design and recreate some classical works with p5.js.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: In-person, collaborative, hands-on workshop.</p><p>Materials: <a href="https://musingswithcode.studio/generative-design-workshop">course page </a> linking to sketches on the p5 editor, <a href="https://musingswithcode.studio/generative-design-workshop/explainers">interactive reference guide </a>to p5 basics</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Skill Level</label><label>Occupation</label></li>			    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +				  <!--modal box #3-->
            +	
            +				  <div class="modal-content" id="case3"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>CC Fest (Creative Coding Festival)</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Saber</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Love p5.js. It has meant so much to me, my students, and this community."</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; New York, Los Angeles, San Francisco, Virtual-Online &#x1F310;</p><p>&#x1F4C5; Twice a year in NYC for four years; once a year in LA for three years; once a year in SF for two years; now virtual</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Our participants included art/design students & professionals, creative coding enthusiasts. We had close to 50 participants.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To build a teacher and student community around p5 for middle and high school.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>A half-day of workshop led by volunteer teachers. We saw lots of different methods and materials. Most used some sort of slides or documentation, some live coding using an editor, with work time for participant to remix.</p><p>&#x1F517; <a href="https://http://ccfest.rocks/lessons">CC Fest Lessons page</a> for teaching materials</p><p>&#x1F4F8; <a href="http://ccfest.rocks/pictures">More photos</a></li>
            +
            +              				<!--<li class = "case"><iframe src="http://ccfest.rocks/pictures" height= "200" alt="Pictures of CC Fest"></iframe></li>-->
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>(Sub-)Culture</label><label>Occupation</label></li>	
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #4-->
            +	
            +				  <div class="modal-content" id="case4"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Taller Introducción a la Programación Creativa con p5.js</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Aarón Montoya-Moraga</p></li>
            +
            +				        	<li class = "case"><p class = speech>"p5.js is my happy place &#x1F495; "</p></li>
            +
            +				        	<li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://miro.medium.com/max/1000/1*OIn_NKGuKyto9-_h6CAmmw.jpeg" alt="A group of 20 people sitting on a large shared table with their laptops looking at a projected screen."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD;  PlusCode Media Arts Festival, Buenos Aires, Argentina & Virtual-Online  &#x1F310;</p><p>&#x1F4C5; 2018 November 14, 3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>I had around 16 students in the workshop, and a team including 3 people from the PlusCode festival, and one person at the venue.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary, Intermediate, Advanced</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Introduction to beginners and artists of graphic web programming and open source, using p5.js, in Spanish :)</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>I used the material on this <a href="https://github.com/montoyamoraga/workshop-p5js-pluscode-2018">GitHub repo</a>, we used the p5.js web editor, we had a three hour long workshop</p><p>&#x1F517; <a href="https://medium.com/processing-foundation/code-electronic-art-festival-2018-argentina-803d3ca8092c">+CODE electronic art festival 2018, Argentina</a>, Medium</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Religion</label><label>(Sub-)Culture</label><label>Age</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label></li>
            +				    
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +				  <!--modal box #5-->
            +	
            +				  <div class="modal-content" id="case5"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to Generative Drawing</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Adam Herst</p></li>
            +
            +				        	<li class = "case"><p class = speech>"My greatest source of uncertainty in developing the workshop was whether it was trying to teach art to programmers or to teach programming to artists."</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; <a href="https://interaccess.org/studio">Inter/Access</a> (artist-run centre), Toronto, Ontario, Canada</p><p>In-person with a self-paced workbook for remote work</p><p>&#x1F4C5; 2020 February 12, 7PM-9PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>15 artists
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To introduce p5.js to artists with little or no programming experience and to suggest one way an analogue practice can migrate to a digital form.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD;Method & Materials</p><p>A printed workbook with activities that used the p5.js web editor to show how translate an physical drawing into a digital drawing.</p><p>&#x1F517;<a href="https://interaccess.org/event/2019/processing-community-day-generative-drawing">Processing Community Day 2019: Generative Drawing at Inter/Access</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Letter PDF</a></p><p>&#x1F517;<a href="https://adamherst.art/introduction_to_generative_drawing_letter.pdf">Introduction to Generative Drawing Booklet PDF</a></p></li>		
            +
            +				    		<li class = "clear"></li>
            +				        	<li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Class</label><label>(Sub-)Culture</label><label>Age</label><label>Skill Level</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #6-->
            +	
            +				  <div class="modal-content" id="case6"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Open Lecture, Creative Coding: 2020</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I love p5.js because it's so easy to read and write code in p5.js. Coding in your everyday life!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				          	<li class = "clear"></li>	
            +				          	<li class = "case"><img src="https://lh3.googleusercontent.com/pw/ACtC-3eYswa6tJH5pvfvvAAfXQJO71ncsdgpwDBvbPAL-qcwnLkkpuoAVpggOb2-LYSLqo0Htd8cgnv5i8yLJg6Wh7J_rW2MMy6y8XZRznRByjj2mGJHf8XFmDI-8W6mH7urrEQC2tyUMF1HWaamLTNBqmIyeQ=w1560-h878-no?authuser=0" alt="A table on which there is a laptop, some sheets of papers, colorful pens and two automatic machines drawing something with a pen on a sheet."></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Kyoto University of Art and Design, Kyoto, Japan & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2020 March 16-18, 1-7 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Students of Kyoto University of Art and Design, and anyone.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Making code as a tool for artistic expression.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/Day1-1-p5.js-i15dvmUETr4ef1xnydzru">Syllabus</a><p>&#x1F517; <a href="https://youtu.be/aS5CvADPdk0">Day 1</a>, <a href="https://youtu.be/ZCO-8CubifI">Day 2</a>, <a href="https://youtu.be/nbcckC5iwIcsyllabus">Day 3</a>, YouTube</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Religion</label><label>(Sub-)Culture</label><label>Political Opinion</label><label>Age</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #7-->
            +	
            +				  <div class="modal-content" id="case7"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Creative Coding for Static Graphics</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Shunsuke Takawo</p></li>
            +
            +				        	<li class = "case"><p class = speech>"Coding in p5.js is a lot of fun. If you haven't started yet, I encourage you to give it a try!"</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://uc6d9323e0272069edcf30e9c501.previews.dropboxusercontent.com/p/thumb/AA5dvRUhxkQ9wLU6mHcrEmLvXnV7gbapPG2PvVf5K8K9ktlC59RCtvbSCP7YfEgPcFtnsgQekujWSD8iEfc6UT2pouzLdZUElblXhh9wg_b2UKDU-OO1u8VaiuC91g73tQX9S9mTHIgvm4h_Jw9-P4F6-iyjqBz57CvFWhilM5CpNbiPIjVRX6NsMkSYA3IexYreShT6Bt2hOWnorsocCsaafJiAd3cZbplWnGiuZmCn5R7BJ4u770YRjqX-AKh6AaoOb3kZHwBBnPQSU7zxiHqZbrWirjwLprw5D5UKW4bMI6We85Yn8cDPlJ6CktIqwpepAhdRi7scaxLxGnpIE4XjnoxK6T1jHkWZXGkvPplV1qlvrC7qz2jTY1_cULKcAcV8F-I-xvAL5I0n3rRHCZqr/p.jpeg?fv_content=true&size_mode=5" alt=""></li>
            +
            +				            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; FabCafe MTRL, Tokyo, Japan</p><p>&#x1F4C5; 2019 September 15, 4-7 PM </p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Anyone who wants to try coding in p5.js.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To code from the graphic design's perspective.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Dropbox Paper, p5.js web editor.</p><p>&#x1F517; <a href="https://paper.dropbox.com/doc/--A6IUdC5pD_0QfbWt1PQ5u~PiAg-Fk8qxFWjaJWeH1cAc8FT0">Syllabus & Material</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Religion</label><label>(Sub-)Culture</label><label>Political Opinion</label><label>Age</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #8-->
            +	
            +				  <div class="modal-content" id="case8"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Generative Typography</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Dae In Chung</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +				        	<li class = "case"><img src="https://drive.google.com/uc?id=1TqcLurMLFioe8EcoJGtdK9_gs9bZ5odW" alt="A image with black background displaying the letter 'b' in 5 different styles along with a menu with various styling options to choose."></li>
            +
            +            	            <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Baltimore, Maryland, USA & Virtual-Online &#x1F310;</p><p>&#x1F4C5; 2019 January 21 - May 08, every Wednesday, 4-10 PM</p></li>  
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>14 undergrads and grad students who had little to no experience in coding.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Experiment with typographic forms and structures through computation.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: online/offline lectures and critiques.</p><p>Materials: p5js online editor, Github, youtube tutorials.</p><p>&#x1F517; <a href="https://drive.google.com/drive/folders/15aFXijbqworOoLpc0fD283YOgi7UIHMA?usp=sharing">Works of participants</a></p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Race & Ethnicity</label><label>Language</label><label>(Sub-)Culture</label><label>Skill Level</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div> 
            +			        
            +				  </div>
            +
            +
            +				  <!--modal box #9-->
            +	
            +				  <div class="modal-content" id="case9"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Machine Learning for the Web</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Yining Shi</p></li>
            +
            +				            <li class = "clear"></li>
            +              				<li class = "clear"></li>
            +              				<li class = "case"><img src="https://drive.google.com/uc?id=1pO3s4lraBwtLcZoCIeHGVncuwtzHqN6o" alt="A group of 16 people sitting around tables with their laptops, mobile phones and some other accessories, facing towards a large television screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; ITP, NYU, 370 Jay St, Brooklyn, NY 11201, USA</p><p>&#x1F4C5;2019 March 09 - October 12, every Tuesday, 6:30-9:00 PM</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Students at Interactive Telecommunications Program, New York University. 16 people.
            +				            </p></li>		            				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary, Intermediate</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>The goal of this class is to learn and understand common machine learning techniques and apply them to generate creative outputs in the browser using ml5.js and p5.js.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>This class is a mix of lectures, coding sessions, group discussions, and presentations. I used<a href="https://github.com/yining1023/machine-learning-for-the-web">GitHub</a> to host class syllabus and all the coding materials, Google Slides for lectures and p5.js Web Editor for live coding sessions. Every week, there were one-on-one office hours to talk about any difficulties of coming up with an idea for the homework or any coding changes.</p><p>Methods: online/offline lectures and critiques.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Age</label><label>Skill Level</label><label>Occupation</label><label>#noCodeSnobs</label><label>#newKidLove</label><label>#unassumeCore</label><label>#BlackLivesMatter</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #10-->
            +	
            +				  <div class="modal-content" id="case10"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Introduction to p5.js and JavaScript</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Nico Reski</p></li>
            +
            +				        	<li class = "clear"></li>
            +				        	<li class = "clear"></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date<p>&#x1F4CD; Currently available as self-study at own pace with accompanying slides, linked below.</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Beginner, Elementary</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Introduce learners (potentially with no coding experiences at all) to the very basics of p5.js (and JavaScript), in order to encourage creative coding and enable them to pursue own projects in a safe environment.</p></li>
            +
            +				            <li class = "clear"></li>
            +				          
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>p5.js source code (for the introductory project), JavaScript source code (illustrating some basic JavaScript functionalities), accompanying slides in .pdf format, all hosted publicly on GitHub.</p><p>&#x1F517; <a href="https://reski.nicoversity.com/ws_cc_p5js_introduction.html">Overview</a> of the workshop and its contents (including all links to the material hosted on GitHub) on my academic webpage.</p></li>	
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +				  <!--modal box #11-->
            +	
            +				  <div class="modal-content" id="case11"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Digital Weaving & Physical Computing Workshop Series</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Qianqian Ye & Evelyn Masso</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +				            <li class = "case"><img src="https://drive.google.com/uc?id=1QXtrew8S2YQ-_6R0H1FhwiEJj9_LLcpU" alt="This image is divided in two parts. The left part shows a group of 15 women sitting on chairs with their laptops and looking at a presentor who is explaining a code on a projected screen. The right part of the image shows a person learning weaving using a physical pattern and a weaving tool."></li>
            +
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD; Womens Center for Creative Work (WCCW), Los Angeles, CA, US</p><p>&#x1F4C5; 2019 October 19 - November 02, every Saturday 3-6 PM</p></li>  		
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>15 women and non-binary artists, designer, makers, programers. </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary
            +				            </p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>Over the course of three workshops, we will draw and create patterns using p5.js, an open-source graphical library; we will learn and apply computational concepts to transform patterns and finally, we will bring a weaving to life with electronic microcontrollers.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>Methods: small team session</p><p>Materials: slides, p5.js web editor, pen and paper to draw pattern, physical pattern weaving tool.</p><p>&#x1F517; <a href="https://docs.google.com/presentation/d/1gJ67aKVGydSNoeUraS7U_QevcnOuxnSFQ_4640Qlifo/edit?usp=sharing">Workshop Slide #1</a>, <a href="https://docs.google.com/presentation/d/1nuje9-j_o5HbCoxXR_EJhAYmSEjTQOkAHmBsuKRlwwA/edit?usp=sharing">Workshop Slide #2</a></p><p>&#x1F517; <a href="https://womenscenterforcreativework.com/events/digital-weaving-physical-computing/">Workshop Information</a> on WCCW website.</p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Skill Level</label><label>Occupation</label></li>
            +				         
            +				            </ul>
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +  				  <!--modal box #12-->
            +	
            +				  <div class="modal-content" id="case12"><div class="close"><span>&#215;</span></div>
            +			            <div class="modal-header">
            +			            	<br>
            +			               <!-- <h2 class="modal-title"></h2>--> 
            +			            </div> 
            +				        <div class="modal-body">
            +				        	<ul class= "cases">
            +
            +				        	<li class = "case"><span>Signing Coders</span></li>
            +
            +				        	<li class = "case"><p class = "lead-name">Taeyoon Choi</p></li>
            +
            +				        	<li class = "case"><p class = speech>"I'm working on a new series of coding class for Disabled students in South Korea. I'm researching about the pedagogy and translation. I plan to hold workshops in December 2020. The project is supported by the Open Society Foundation Human Rights Initiative and Korea Disability Arts & Culture Center."</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "clear"></li>
            +
            +				            <li class = "case"><img src="http://taeyoonchoi.com/wp-content/uploads/2016/04/day1-7852-768x512.jpg" alt="Two volunteers explaining concepts using a white board and a screen to a bunch of deaf and hard of hearing students, each student facing a computer screen."></li>
            +
            +              			    <li class = "case"><p class = "subtitle">Venue & Date</p><p>&#x1F4CD;  WRIC, New York City, USA & Seoul Museum of Art, Seoul, South Korea.</p><p>5 Sessions, each 2~3 hours</p></li>  				
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Participants</p><p>Deaf and Hard of Hearing students age 10~50 who live in NYC.
            +				            </p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Level of Difficulty</p><p>Elementary</p></li>		
            +				            
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class = "subtitle">Goals</p><p>To help Deaf and Hard of Hearing students learn about computer programming through playful exercises. To make ASL tutorial of basic coding concepts.</p></li>
            +
            +				            <li class = "clear"></li>
            +				            <li class = "case"><p class="subtitle">&#x1F4DD; Method & Materials</p><p>We used p5.js Web editor and code examples on the website. We also used dice, playing cards and various paper tools to help students learn about coding concepts.</p><p>&#x1F517; <a href="http://taeyoonchoi.com/soft-care/signing-coders/">Syllabus & Material</a></p><p>&#x1F4F8; <a href="http://taeyoonchoi.com/soft-care/signing-coders/signing-coders-1/">More photos</a></p></li>
            +
            +							<li class = "clear"></li>
            +				            <li class = "case"><label>Gender</label><label>Race & Ethnicity</label><label>Language</label><label>Neuro-Type</label><label>Ability</label><label>Class</label><label>Skill Level</label></li>
            +				         
            +
            +
            +				            </ul>
            +				        
            +				        </div> 
            +			            <div class="modal-footer"></div>
            +			        
            +				  </div>
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +
            +			</div> <!--modal boxes end-->
            +
            +			
            +			
            +
            +	</section>
            +
            +
            +	<!--modal-->
            +
            +
            +    
            +    <footer>
            +      <h2 class="sr-only">归功于</h2>
            +      <p>
            +        p5.js 目前由<a href='http://qianqian-ye.com/' target="_blank">Qianqian Ye</a>与<a href='http://www.outofambit.com/' target="_blank">evelyn masso</a>领导,原创者为<a href='https://lauren-mccarthy.com' target="_blank">Lauren Lee McCarthy</a>。p5.js 是在<a href="https://processingfoundation.org/" target="_blank">Processing Foundation</a>和<a href="https://itp.nyu.edu/itp/" target="_blank">NYU ITP</a>的支持下由其合作社群所开发。形象及平面设计<a href="https://jereljohnson.com/" target="_blank">Jerel Johnson</a>。<a href="/zh-Hans/copyright.html">&copy; 版权信息</a>。
            +      </p>
            +    </footer>
            +
            +  </main>
            +
            +  
            +  <!-- outside of column for footer to go across both -->
            +  
            +  <p class="clearfix"> &nbsp; </p>
            +  
            +  <object type="image/svg+xml" data="../../assets/img/thick-asterisk-alone.svg" id="asterisk-design-element" aria-hidden="true">
            +  </object>
            +
            +</div>
            +
            +
            +<!--jquery script-->
            +
            +<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
            +<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
            +<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
            +
            +
            +<!--filter search-->
            +
            +
            +<script>
            +    $("#filters :checkbox").click(function() {
            +
            +       var re = new RegExp($("#filters :checkbox:checked").map(function() {
            +                              return this.value;
            +                           }).get().join("|") ); //.join("|")
            +       $(".case-list").each(function() {
            +          var $this = $(this);
            +          $this[re.source!="" && re.test($this.attr("data-category")) ? "fadeIn" : "hide"]();
            +       });
            +    });
            +</script>
            +
            +
            +<!--modal box-->
            +
            +
            +<script>
            +$(document).on('click','.caseBtn',function(){
            +	var openModal =  $(this).attr('href');
            +	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +	
            +	$('#caseModals').fadeIn();
            +	$(openModal).fadeIn();
            +  return false;
            +});
            +
            +$("body" ).on( "click",".close", function() {
            +  	$('#caseModals').hide();
            +	$('.modal-content').hide();
            +});
            +
            +</script>
            +
            +<!--search accordion menu-->
            +
            +<script>
            +
            +
            +var acc = document.getElementsByClassName("search-filter");
            +var i;
            +
            +for (i = 0; i < acc.length; i++) {
            +  acc[i].addEventListener("click", function() {
            +    this.classList.toggle("active");
            +    var panel = this.nextElementSibling;
            +    if (panel.style.maxHeight) {
            +      panel.style.maxHeight = null;
            +    } else {
            +      panel.style.maxHeight = panel.scrollHeight + "px";
            +    } 
            +
            +  });
            +}
            +</script>
            +
            +
            +    </div> <!-- close class='container'-->
            +
            +    
            +    <nav id="family" aria-labelledby="processing-sites-heading">
            +      <h2 id="processing-sites-heading" class="sr-only">Processing Sister Sites</h2>
            +      <ul id="processing-sites" aria-labelledby="processing-sites-heading">
            +        <li><a href="https://processing.org">Processing</a></li>
            +        <li><a class="here" href="/zh-Hans/">p5.js</a></li>
            +        <li><a href="https://py.processing.org/">Processing.py</a></li>
            +        <li><a href="https://android.processing.org/">Processing for Android</a></li>
            +        <li><a href="https://pi.processing.org/">Processing for Pi</a></li>
            +        <li><a href="https://processingfoundation.org/">Processing Foundation</a></li>
            +      </ul>
            +      <a tabindex="1" href="#content" id="skip-to-content">Skip to main content</a>
            +    
            +    
            +    </nav>
            +    <script>
            +    var langs = ["en","es","hi","ko","zh-Hans"];
            +
            +      (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
            +    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            +    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
            +    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
            +    ga('create', 'UA-53383000-1', 'auto');
            +    ga('send', 'pageview');
            +
            +    $(window).ready(function() {
            +      if (window.location.pathname !== '/' && window.location.pathname !== '/index.html') {
            +        $('#top').remove();
            +      } else {
            +        $('#top').show();
            +      }
            +    });
            +    </script>
            +
            +
            +  </body>
            +</html>
            diff --git a/package-lock.json b/package-lock.json
            index 0725d967a9..63986a730d 100644
            --- a/package-lock.json
            +++ b/package-lock.json
            @@ -1,8 +1,25794 @@
             {
               "name": "p5js",
               "version": "0.1.0",
            -  "lockfileVersion": 1,
            +  "lockfileVersion": 2,
               "requires": true,
            +  "packages": {
            +    "": {
            +      "name": "p5js",
            +      "version": "0.1.0",
            +      "dependencies": {
            +        "upath": "^1.2.0"
            +      },
            +      "devDependencies": {
            +        "@fluent/syntax": "^0.17.0",
            +        "assemble": "^0.24.3",
            +        "assemble-contrib-i18n": "^0.1.6",
            +        "assemble-contrib-permalinks": "*",
            +        "autoprefixer": "^6.7.7",
            +        "cssnano": "^4.1.11",
            +        "ejs": "^2.7.4",
            +        "eslint": "^4.19.1",
            +        "eslint-config-prettier": "^2.10.0",
            +        "eslint-plugin-prettier": "^2.7.0",
            +        "flat": "^5.0.2",
            +        "fs-extra": "^9.1.0",
            +        "glob": "^5.0.15",
            +        "grunt": "^1.4.1",
            +        "grunt-assemble": "^0.6.3",
            +        "grunt-cli": "^1.4.3",
            +        "grunt-contrib-clean": "^0.6.0",
            +        "grunt-contrib-compress": "^1.6.0",
            +        "grunt-contrib-concat": "^1.0.1",
            +        "grunt-contrib-connect": "^2.1.0",
            +        "grunt-contrib-copy": "^0.5.0",
            +        "grunt-contrib-imagemin": "^3.1.0",
            +        "grunt-contrib-requirejs": "^1.0.0",
            +        "grunt-contrib-uglify": "^3.4.0",
            +        "grunt-contrib-watch": "^1.1.0",
            +        "grunt-exec": "^1.0.1",
            +        "grunt-file-append": "0.0.7",
            +        "grunt-html": "^11.1.1",
            +        "grunt-newer": "^1.3.0",
            +        "grunt-postcss": "^0.9.0",
            +        "grunt-serve": "^0.1.6",
            +        "grunt-shell": "^3.0.1",
            +        "grunt-uncss": "^0.8.6",
            +        "handlebars": "^4.7.7",
            +        "husky": "^0.14.3",
            +        "imagemin-mozjpeg": "^9.0.0",
            +        "imagemin-pngquant": "^9.0.2",
            +        "js-yaml": "^3.14.1",
            +        "lint-staged": "^9.5.0",
            +        "load-grunt-tasks": "^5.1.0",
            +        "lodash": "^4.17.21",
            +        "marked": "^0.8.2",
            +        "mkdirp": "^0.5.5",
            +        "moment": "^2.29.1",
            +        "ms": "^0.7.3",
            +        "prettier": "^1.19.1",
            +        "qs": "^6.10.1",
            +        "send": "^0.16.2",
            +        "serve-index": "^1.9.1",
            +        "simple-git": "^1.132.0",
            +        "time-grunt": "^1.4.0",
            +        "uglify-js": "^2.8.29",
            +        "yaml": "^1.10.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10"
            +      }
            +    },
            +    "node_modules/@fluent/syntax": {
            +      "version": "0.17.0",
            +      "resolved": "https://registry.npmjs.org/@fluent/syntax/-/syntax-0.17.0.tgz",
            +      "integrity": "sha512-fgJNUZRBk/n5MO5AxZ7Vvv8aCzMF6NanGBS1GFR2HG2lnsGqHLAe9OeHpyg+FkKfP5SvOtbyk3Nkza5iIwN/Ug==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=10.0.0"
            +      }
            +    },
            +    "node_modules/@mrmlnc/readdir-enhanced": {
            +      "version": "2.2.1",
            +      "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
            +      "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
            +      "dev": true,
            +      "dependencies": {
            +        "call-me-maybe": "^1.0.1",
            +        "glob-to-regexp": "^0.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/@nodelib/fs.scandir": {
            +      "version": "2.1.3",
            +      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
            +      "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
            +      "dev": true,
            +      "dependencies": {
            +        "@nodelib/fs.stat": "2.0.3",
            +        "run-parallel": "^1.1.9"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/@nodelib/fs.scandir/node_modules/@nodelib/fs.stat": {
            +      "version": "2.0.3",
            +      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
            +      "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/@nodelib/fs.stat": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
            +      "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 6"
            +      }
            +    },
            +    "node_modules/@nodelib/fs.walk": {
            +      "version": "1.2.4",
            +      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
            +      "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "@nodelib/fs.scandir": "2.1.3",
            +        "fastq": "^1.6.0"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/@samverschueren/stream-to-observable": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz",
            +      "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==",
            +      "dev": true,
            +      "dependencies": {
            +        "any-observable": "^0.3.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/@sindresorhus/is": {
            +      "version": "0.7.0",
            +      "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
            +      "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/@types/events": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
            +      "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
            +      "dev": true
            +    },
            +    "node_modules/@types/glob": {
            +      "version": "7.1.1",
            +      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
            +      "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
            +      "dev": true,
            +      "dependencies": {
            +        "@types/events": "*",
            +        "@types/minimatch": "*",
            +        "@types/node": "*"
            +      }
            +    },
            +    "node_modules/@types/minimatch": {
            +      "version": "3.0.3",
            +      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
            +      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
            +      "dev": true
            +    },
            +    "node_modules/@types/node": {
            +      "version": "13.1.4",
            +      "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.4.tgz",
            +      "integrity": "sha512-Lue/mlp2egZJoHXZr4LndxDAd7i/7SQYhV0EjWfb/a4/OZ6tuVwMCVPiwkU5nsEipxEf7hmkSU7Em5VQ8P5NGA==",
            +      "dev": true
            +    },
            +    "node_modules/@types/q": {
            +      "version": "1.5.2",
            +      "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
            +      "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
            +      "dev": true
            +    },
            +    "node_modules/abab": {
            +      "version": "2.0.3",
            +      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
            +      "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==",
            +      "dev": true
            +    },
            +    "node_modules/abbrev": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
            +      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
            +      "dev": true
            +    },
            +    "node_modules/acorn": {
            +      "version": "5.7.4",
            +      "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
            +      "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==",
            +      "dev": true,
            +      "bin": {
            +        "acorn": "bin/acorn"
            +      },
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/acorn-globals": {
            +      "version": "4.3.4",
            +      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
            +      "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
            +      "dev": true,
            +      "dependencies": {
            +        "acorn": "^6.0.1",
            +        "acorn-walk": "^6.0.1"
            +      }
            +    },
            +    "node_modules/acorn-globals/node_modules/acorn": {
            +      "version": "6.4.1",
            +      "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
            +      "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
            +      "dev": true,
            +      "bin": {
            +        "acorn": "bin/acorn"
            +      },
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/acorn-jsx": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
            +      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
            +      "dev": true,
            +      "dependencies": {
            +        "acorn": "^3.0.4"
            +      }
            +    },
            +    "node_modules/acorn-jsx/node_modules/acorn": {
            +      "version": "3.3.0",
            +      "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
            +      "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
            +      "dev": true,
            +      "bin": {
            +        "acorn": "bin/acorn"
            +      },
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/acorn-walk": {
            +      "version": "6.2.0",
            +      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
            +      "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/aggregate-error": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
            +      "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
            +      "dev": true,
            +      "dependencies": {
            +        "clean-stack": "^2.0.0",
            +        "indent-string": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/aggregate-error/node_modules/indent-string": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
            +      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/ajv": {
            +      "version": "5.5.2",
            +      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
            +      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
            +      "dev": true,
            +      "dependencies": {
            +        "co": "^4.6.0",
            +        "fast-deep-equal": "^1.0.0",
            +        "fast-json-stable-stringify": "^2.0.0",
            +        "json-schema-traverse": "^0.3.0"
            +      }
            +    },
            +    "node_modules/ajv-keywords": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
            +      "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
            +      "dev": true,
            +      "peerDependencies": {
            +        "ajv": "^5.0.0"
            +      }
            +    },
            +    "node_modules/align-text": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
            +      "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2",
            +        "longest": "^1.0.1",
            +        "repeat-string": "^1.5.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/align-text/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/alphanum-sort": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
            +      "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
            +      "dev": true
            +    },
            +    "node_modules/ansi": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz",
            +      "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=",
            +      "dev": true
            +    },
            +    "node_modules/ansi-bgblack": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-bgblack/-/ansi-bgblack-0.1.1.tgz",
            +      "integrity": "sha1-poulAHiHcBtqr74/oNrf36juPKI=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-bgblue": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-bgblue/-/ansi-bgblue-0.1.1.tgz",
            +      "integrity": "sha1-Z73ATtybm1J4lp2hlt6j11yMNhM=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-bgcyan": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-bgcyan/-/ansi-bgcyan-0.1.1.tgz",
            +      "integrity": "sha1-WEiUJWAL3p9VBwaN2Wnr/bUP52g=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-bggreen": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-bggreen/-/ansi-bggreen-0.1.1.tgz",
            +      "integrity": "sha1-TjGRJIUplD9DIelr8THRwTgWr0k=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-bgmagenta": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-bgmagenta/-/ansi-bgmagenta-0.1.1.tgz",
            +      "integrity": "sha1-myhDLAduqpmUGGcqPvvhk5HCx6E=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-bgred": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-bgred/-/ansi-bgred-0.1.1.tgz",
            +      "integrity": "sha1-p2+Sg4OCukMpCmwXeEJPmE1vEEE=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-bgwhite": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-bgwhite/-/ansi-bgwhite-0.1.1.tgz",
            +      "integrity": "sha1-ZQRlE3elim7OzQMxmU5IAljhG6g=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-bgyellow": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-bgyellow/-/ansi-bgyellow-0.1.1.tgz",
            +      "integrity": "sha1-w/4usIzUdmSAKeaHTRWgs49h1E8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-black": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-black/-/ansi-black-0.1.1.tgz",
            +      "integrity": "sha1-9hheiJNgslRaHsUMC/Bj/EMDJFM=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-blue": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-blue/-/ansi-blue-0.1.1.tgz",
            +      "integrity": "sha1-FbgEmQ6S/JyoxUds6PaZd3wh7b8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-bold": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-bold/-/ansi-bold-0.1.1.tgz",
            +      "integrity": "sha1-PmOVCvWswq4uZw5vZ96xFdGl9QU=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-colors": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-0.2.0.tgz",
            +      "integrity": "sha1-csMd4qDZoszQysMMyYI+6y9kNLU=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-bgblack": "^0.1.1",
            +        "ansi-bgblue": "^0.1.1",
            +        "ansi-bgcyan": "^0.1.1",
            +        "ansi-bggreen": "^0.1.1",
            +        "ansi-bgmagenta": "^0.1.1",
            +        "ansi-bgred": "^0.1.1",
            +        "ansi-bgwhite": "^0.1.1",
            +        "ansi-bgyellow": "^0.1.1",
            +        "ansi-black": "^0.1.1",
            +        "ansi-blue": "^0.1.1",
            +        "ansi-bold": "^0.1.1",
            +        "ansi-cyan": "^0.1.1",
            +        "ansi-dim": "^0.1.1",
            +        "ansi-gray": "^0.1.1",
            +        "ansi-green": "^0.1.1",
            +        "ansi-grey": "^0.1.1",
            +        "ansi-hidden": "^0.1.1",
            +        "ansi-inverse": "^0.1.1",
            +        "ansi-italic": "^0.1.1",
            +        "ansi-magenta": "^0.1.1",
            +        "ansi-red": "^0.1.1",
            +        "ansi-reset": "^0.1.1",
            +        "ansi-strikethrough": "^0.1.1",
            +        "ansi-underline": "^0.1.1",
            +        "ansi-white": "^0.1.1",
            +        "ansi-yellow": "^0.1.1",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-cyan": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz",
            +      "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-dim": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-dim/-/ansi-dim-0.1.1.tgz",
            +      "integrity": "sha1-QN5MYDqoCG2Oeoa4/5mNXDbu/Ww=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-escapes": {
            +      "version": "1.4.0",
            +      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
            +      "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-gray": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
            +      "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-green": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-green/-/ansi-green-0.1.1.tgz",
            +      "integrity": "sha1-il2al55FjVfEDjNYCzc5C44Q0Pc=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-grey": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-grey/-/ansi-grey-0.1.1.tgz",
            +      "integrity": "sha1-WdmLasK6GfilF5jphT+6eDOaM8E=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-hidden": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-hidden/-/ansi-hidden-0.1.1.tgz",
            +      "integrity": "sha1-7WpMSY0rt8uyidvyqNHcyFZ/rg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-inverse": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-inverse/-/ansi-inverse-0.1.1.tgz",
            +      "integrity": "sha1-tq9Fgm/oJr+1KKbHmIV5Q1XM0mk=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-italic": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-italic/-/ansi-italic-0.1.1.tgz",
            +      "integrity": "sha1-EEdDRj9iXBQqA2c5z4XtpoiYbyM=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-magenta": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-magenta/-/ansi-magenta-0.1.1.tgz",
            +      "integrity": "sha1-BjtboW+z8j4c/aKwfAqJ3hHkMK4=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-red": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz",
            +      "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-regex": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
            +      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-reset": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-reset/-/ansi-reset-0.1.1.tgz",
            +      "integrity": "sha1-5+cSksPH3c1NYu9KbHwFmAkRw7c=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-strikethrough": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-strikethrough/-/ansi-strikethrough-0.1.1.tgz",
            +      "integrity": "sha1-2Eh3FAss/wfRyT685pkE9oiF5Wg=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-styles": {
            +      "version": "2.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
            +      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-underline": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-underline/-/ansi-underline-0.1.1.tgz",
            +      "integrity": "sha1-38kg9Ml7WXfqFi34/7mIMIqqcaQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-white": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-white/-/ansi-white-0.1.1.tgz",
            +      "integrity": "sha1-nHe3wZPF7pkuYBHTbsTJIbRXiUQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-wrap": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
            +      "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ansi-yellow": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/ansi-yellow/-/ansi-yellow-0.1.1.tgz",
            +      "integrity": "sha1-y5NW8vRscy8OMZnmEClVp32oPB0=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-wrap": "0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/any-observable": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz",
            +      "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/aproba": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
            +      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/arch": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz",
            +      "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==",
            +      "dev": true
            +    },
            +    "node_modules/archive-type": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz",
            +      "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=",
            +      "dev": true,
            +      "dependencies": {
            +        "file-type": "^4.2.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/archive-type/node_modules/file-type": {
            +      "version": "4.4.0",
            +      "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
            +      "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/archiver": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz",
            +      "integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=",
            +      "dev": true,
            +      "dependencies": {
            +        "archiver-utils": "^1.3.0",
            +        "async": "^2.0.0",
            +        "buffer-crc32": "^0.2.1",
            +        "glob": "^7.0.0",
            +        "lodash": "^4.8.0",
            +        "readable-stream": "^2.0.0",
            +        "tar-stream": "^1.5.0",
            +        "walkdir": "^0.0.11",
            +        "zip-stream": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/archiver-utils": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz",
            +      "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "glob": "^7.0.0",
            +        "graceful-fs": "^4.1.0",
            +        "lazystream": "^1.0.0",
            +        "lodash": "^4.8.0",
            +        "normalize-path": "^2.0.0",
            +        "readable-stream": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/archiver-utils/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/archiver/node_modules/async": {
            +      "version": "2.6.3",
            +      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
            +      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash": "^4.17.14"
            +      }
            +    },
            +    "node_modules/archiver/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/are-we-there-yet": {
            +      "version": "1.1.5",
            +      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
            +      "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "delegates": "^1.0.0",
            +        "readable-stream": "^2.0.6"
            +      }
            +    },
            +    "node_modules/argparse": {
            +      "version": "1.0.10",
            +      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
            +      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
            +      "dev": true,
            +      "dependencies": {
            +        "sprintf-js": "~1.0.2"
            +      }
            +    },
            +    "node_modules/arr-diff": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
            +      "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/arr-filter": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
            +      "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
            +      "dev": true,
            +      "dependencies": {
            +        "make-iterator": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/arr-flatten": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
            +      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/arr-map": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
            +      "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "make-iterator": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/arr-pluck": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-pluck/-/arr-pluck-0.1.0.tgz",
            +      "integrity": "sha1-+K1tcI+HkAiB4jr9gw1SKQp2Z3U=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-map": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/arr-union": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz",
            +      "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-each": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
            +      "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-equal": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
            +      "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
            +      "dev": true
            +    },
            +    "node_modules/array-find-index": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
            +      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-flatten": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
            +      "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
            +      "dev": true
            +    },
            +    "node_modules/array-initial": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
            +      "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-slice": "^1.0.0",
            +        "is-number": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-initial/node_modules/array-slice": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
            +      "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-initial/node_modules/is-number": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
            +      "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-last": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
            +      "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-last/node_modules/is-number": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
            +      "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-slice": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
            +      "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-sort": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-0.1.4.tgz",
            +      "integrity": "sha512-BNcM+RXxndPxiZ2rd76k6nyQLRZr2/B/sdi8pQ+Joafr5AH279L40dfokSUTp8O+AaqYjXWhblBWa2st2nc4fQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "default-compare": "^1.0.0",
            +        "get-value": "^2.0.6",
            +        "kind-of": "^5.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-union": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
            +      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-uniq": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-uniq": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
            +      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/array-unique": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
            +      "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/arrayify-compact": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/arrayify-compact/-/arrayify-compact-0.2.0.tgz",
            +      "integrity": "sha1-RZFw4VXKErtRRISDnJ1xUHyA7E0=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/arrify": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
            +      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/asn1": {
            +      "version": "0.2.4",
            +      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
            +      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
            +      "dev": true,
            +      "dependencies": {
            +        "safer-buffer": "~2.1.0"
            +      }
            +    },
            +    "node_modules/assemble": {
            +      "version": "0.24.3",
            +      "resolved": "https://registry.npmjs.org/assemble/-/assemble-0.24.3.tgz",
            +      "integrity": "sha1-lSp3S3iAl6TW9Iw6QrpW9ouNZS8=",
            +      "dev": true,
            +      "dependencies": {
            +        "assemble-core": "^0.31.0",
            +        "assemble-loader": "^1.0.5",
            +        "base-argv": "^0.5.0",
            +        "base-cli-process": "^0.1.19",
            +        "base-config": "^0.5.2",
            +        "base-questions": "^0.9.1",
            +        "base-runtimes": "^0.2.0",
            +        "cross-spawn": "^5.1.0",
            +        "engine-handlebars": "^0.8.2",
            +        "expand-front-matter": "^1.0.0",
            +        "export-files": "^2.1.1",
            +        "global-modules": "^0.2.3",
            +        "is-valid-app": "^0.3.0",
            +        "lazy-cache": "^2.0.2",
            +        "log-utils": "^0.2.1",
            +        "minimist": "^1.2.0",
            +        "parser-front-matter": "^1.6.3",
            +        "resolve-dir": "^1.0.0"
            +      },
            +      "bin": {
            +        "assemble": "bin/cli.js"
            +      },
            +      "engines": {
            +        "node": ">=4.0"
            +      }
            +    },
            +    "node_modules/assemble-contrib-i18n": {
            +      "version": "0.1.6",
            +      "resolved": "https://registry.npmjs.org/assemble-contrib-i18n/-/assemble-contrib-i18n-0.1.6.tgz",
            +      "integrity": "sha1-R6oeFD5qDNJ7BT6s7681eTCcbT8=",
            +      "dev": true,
            +      "dependencies": {
            +        "fs-utils": "~0.3.6",
            +        "gray-matter": "~0.2.8",
            +        "handlebars-helper-i18n": "^0.1.0",
            +        "lodash": "~2.4.1"
            +      }
            +    },
            +    "node_modules/assemble-contrib-i18n/node_modules/argparse": {
            +      "version": "0.1.16",
            +      "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz",
            +      "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=",
            +      "dev": true,
            +      "dependencies": {
            +        "underscore": "~1.7.0",
            +        "underscore.string": "~2.4.0"
            +      }
            +    },
            +    "node_modules/assemble-contrib-i18n/node_modules/async": {
            +      "version": "0.2.10",
            +      "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
            +      "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
            +      "dev": true
            +    },
            +    "node_modules/assemble-contrib-i18n/node_modules/esprima": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
            +      "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=",
            +      "dev": true,
            +      "bin": {
            +        "esparse": "bin/esparse.js",
            +        "esvalidate": "bin/esvalidate.js"
            +      },
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/assemble-contrib-i18n/node_modules/gray-matter": {
            +      "version": "0.2.8",
            +      "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-0.2.8.tgz",
            +      "integrity": "sha1-Oh75q2aSbGU8whUNHrW5PaODMUQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "coffee-script": "~1.6.3",
            +        "delims": "~0.1.0",
            +        "fs-utils": "~0.1.6",
            +        "js-yaml": "~3.0.1",
            +        "lodash": "~2.4.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/assemble-contrib-i18n/node_modules/gray-matter/node_modules/fs-utils": {
            +      "version": "0.1.11",
            +      "resolved": "https://registry.npmjs.org/fs-utils/-/fs-utils-0.1.11.tgz",
            +      "integrity": "sha1-zsxa3MTt78xWA6Z1WEwOFAx6pTc=",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "~0.2.9",
            +        "globule": "~0.2.0",
            +        "iconv-lite": "~0.2.11",
            +        "js-yaml": "~3.0.1",
            +        "lodash": "~2.4.1",
            +        "mkdirp": "~0.3.5",
            +        "rimraf": "~2.2.6"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/assemble-contrib-i18n/node_modules/js-yaml": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.0.2.tgz",
            +      "integrity": "sha1-mTeGX46Jel6JTnPCxc8uibMut3E=",
            +      "dev": true,
            +      "dependencies": {
            +        "argparse": "~ 0.1.11",
            +        "esprima": "~ 1.0.2"
            +      },
            +      "bin": {
            +        "js-yaml": "bin/js-yaml.js"
            +      }
            +    },
            +    "node_modules/assemble-contrib-i18n/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/assemble-contrib-i18n/node_modules/mkdirp": {
            +      "version": "0.3.5",
            +      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
            +      "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=",
            +      "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
            +      "dev": true
            +    },
            +    "node_modules/assemble-contrib-i18n/node_modules/rimraf": {
            +      "version": "2.2.8",
            +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
            +      "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
            +      "dev": true,
            +      "bin": {
            +        "rimraf": "bin.js"
            +      }
            +    },
            +    "node_modules/assemble-contrib-permalinks": {
            +      "version": "0.3.6",
            +      "resolved": "https://registry.npmjs.org/assemble-contrib-permalinks/-/assemble-contrib-permalinks-0.3.6.tgz",
            +      "integrity": "sha1-vhxrHMjYu0Qx4XLL8Rejtb0fya4=",
            +      "deprecated": "renaming to assemble-middleware-permalinks",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "~0.2.9",
            +        "digits": "~0.1.2",
            +        "lodash": "~2.4.0",
            +        "strings": "~0.2.0",
            +        "underscore.string": "~2.3.3"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      },
            +      "peerDependencies": {
            +        "assemble": "~0.4.12"
            +      }
            +    },
            +    "node_modules/assemble-contrib-permalinks/node_modules/async": {
            +      "version": "0.2.10",
            +      "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
            +      "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
            +      "dev": true
            +    },
            +    "node_modules/assemble-contrib-permalinks/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/assemble-contrib-permalinks/node_modules/underscore.string": {
            +      "version": "2.3.3",
            +      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
            +      "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/assemble-core": {
            +      "version": "0.31.0",
            +      "resolved": "https://registry.npmjs.org/assemble-core/-/assemble-core-0.31.0.tgz",
            +      "integrity": "sha1-Rih0H2UX5/dJMYTDij44iPAlY+Q=",
            +      "dev": true,
            +      "dependencies": {
            +        "assemble-fs": "^1.0.0",
            +        "assemble-render-file": "^1.0.0",
            +        "assemble-streams": "^1.0.0",
            +        "base-task": "^0.7.0",
            +        "define-property": "^0.2.5",
            +        "lazy-cache": "^2.0.2",
            +        "templates": "^1.2.6"
            +      },
            +      "engines": {
            +        "node": ">=4.0"
            +      }
            +    },
            +    "node_modules/assemble-fs": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/assemble-fs/-/assemble-fs-1.0.1.tgz",
            +      "integrity": "sha1-eAvMJ+itGVaqhQFyNEjjWcPdI88=",
            +      "dev": true,
            +      "dependencies": {
            +        "assemble-handle": "^0.1.3",
            +        "extend-shallow": "^2.0.1",
            +        "file-is-binary": "^1.0.0",
            +        "fs-exists-sync": "^0.1.0",
            +        "is-valid-app": "^0.3.0",
            +        "lazy-cache": "^2.0.2",
            +        "stream-combiner": "^0.2.2",
            +        "through2": "^2.0.3",
            +        "vinyl-fs": "^2.4.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assemble-handle": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/assemble-handle/-/assemble-handle-0.1.4.tgz",
            +      "integrity": "sha1-6De1uyPnXJsFJX2AfhYvaSzOIW4=",
            +      "dev": true,
            +      "dependencies": {
            +        "through2": "^2.0.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assemble-handlebars": {
            +      "version": "0.4.1",
            +      "resolved": "https://registry.npmjs.org/assemble-handlebars/-/assemble-handlebars-0.4.1.tgz",
            +      "integrity": "sha1-6jN3GX8IYbg3AIGdiwVaN2LH7jk=",
            +      "dev": true,
            +      "dependencies": {
            +        "handlebars": "^4.0.6",
            +        "handlebars-helpers": "^0.8.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/assemble-loader": {
            +      "version": "1.0.5",
            +      "resolved": "https://registry.npmjs.org/assemble-loader/-/assemble-loader-1.0.5.tgz",
            +      "integrity": "sha1-qOplRNXsl/ljVrKeAIPwfUVx4Z8=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "file-contents": "^1.0.1",
            +        "is-registered": "^0.1.5",
            +        "is-valid-glob": "^0.3.0",
            +        "is-valid-instance": "^0.2.0",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.2",
            +        "load-templates": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assemble-loader/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assemble-loader/node_modules/is-valid-instance/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assemble-render-file": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/assemble-render-file/-/assemble-render-file-1.0.3.tgz",
            +      "integrity": "sha1-0vwcPUPp8nkE/xS4rOExvKLzzJ4=",
            +      "dev": true,
            +      "dependencies": {
            +        "async-array-reduce": "^0.2.1",
            +        "debug": "^2.6.8",
            +        "file-is-binary": "^1.0.0",
            +        "is-valid-app": "^0.3.0",
            +        "lazy-cache": "^2.0.2",
            +        "mixin-deep": "^1.2.0",
            +        "plugin-error": "^0.1.2",
            +        "through2": "^2.0.3"
            +      },
            +      "engines": {
            +        "node": ">=4.7.0"
            +      }
            +    },
            +    "node_modules/assemble-streams": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/assemble-streams/-/assemble-streams-1.0.1.tgz",
            +      "integrity": "sha1-pxrY0yscVovmkr++KmWgMWB6eGU=",
            +      "dev": true,
            +      "dependencies": {
            +        "assemble-handle": "^0.1.3",
            +        "define-property": "^0.2.5",
            +        "is-valid-app": "^0.2.1",
            +        "kind-of": "^3.1.0",
            +        "lazy-cache": "^2.0.2",
            +        "match-file": "^0.2.1",
            +        "src-stream": "^0.1.1",
            +        "through2": "^2.0.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assemble-streams/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assemble-streams/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assemble-streams/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assemble-streams/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assert": {
            +      "version": "1.4.1",
            +      "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
            +      "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
            +      "dev": true,
            +      "dependencies": {
            +        "util": "0.10.3"
            +      }
            +    },
            +    "node_modules/assert-plus": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
            +      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/assign-deep": {
            +      "version": "0.4.8",
            +      "resolved": "https://registry.npmjs.org/assign-deep/-/assign-deep-0.4.8.tgz",
            +      "integrity": "sha512-uxqXJCnNZDEjPnsaLKVzmh/ST5+Pqoz0wi06HDfHKx1ASNpSbbvz2qW2Gl8ZyHwr5jnm11X2S5eMQaP1lMZmCg==",
            +      "dev": true,
            +      "dependencies": {
            +        "assign-symbols": "^0.1.1",
            +        "is-primitive": "^2.0.0",
            +        "kind-of": "^5.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assign-deep/node_modules/assign-symbols": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-0.1.1.tgz",
            +      "integrity": "sha1-ywJZRO9OyKNpPwhunhEsdOOg/tk=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/assign-symbols": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
            +      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/async": {
            +      "version": "1.5.2",
            +      "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
            +      "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
            +      "dev": true
            +    },
            +    "node_modules/async-array-reduce": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/async-array-reduce/-/async-array-reduce-0.2.1.tgz",
            +      "integrity": "sha1-yL4BCitc0A3qlsgRFgNGk9/dgtE=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/async-done": {
            +      "version": "1.3.2",
            +      "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz",
            +      "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==",
            +      "dev": true,
            +      "dependencies": {
            +        "end-of-stream": "^1.1.0",
            +        "once": "^1.3.2",
            +        "process-nextick-args": "^2.0.0",
            +        "stream-exhaust": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/async-each": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
            +      "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
            +      "dev": true
            +    },
            +    "node_modules/async-each-series": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-1.1.0.tgz",
            +      "integrity": "sha1-9C/YFV048hpbjqB8KOBj7RcAsTg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/async-helpers": {
            +      "version": "0.3.17",
            +      "resolved": "https://registry.npmjs.org/async-helpers/-/async-helpers-0.3.17.tgz",
            +      "integrity": "sha512-LfgCyvmK6ZiC7pyqOgli2zfkWL4HYbEb+HXvGgdmqVBgsOOtQz5rSF8Ii/H/1cNNtrfj1KsdZE/lUMeIY3Qcwg==",
            +      "dev": true,
            +      "dependencies": {
            +        "co": "^4.6.0",
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/async-helpers/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/async-limiter": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
            +      "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
            +      "dev": true
            +    },
            +    "node_modules/async-settle": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
            +      "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
            +      "dev": true,
            +      "dependencies": {
            +        "async-done": "^1.2.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/asynckit": {
            +      "version": "0.4.0",
            +      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
            +      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
            +      "dev": true
            +    },
            +    "node_modules/at-least-node": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
            +      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 4.0.0"
            +      }
            +    },
            +    "node_modules/atob": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
            +      "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
            +      "dev": true,
            +      "bin": {
            +        "atob": "bin/atob.js"
            +      },
            +      "engines": {
            +        "node": ">= 4.5.0"
            +      }
            +    },
            +    "node_modules/autolinker": {
            +      "version": "0.28.1",
            +      "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-0.28.1.tgz",
            +      "integrity": "sha1-BlK0kYgYefB3XazgzcoyM5QqTkc=",
            +      "dev": true,
            +      "dependencies": {
            +        "gulp-header": "^1.7.1"
            +      }
            +    },
            +    "node_modules/autoprefixer": {
            +      "version": "6.7.7",
            +      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
            +      "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "browserslist": "^1.7.6",
            +        "caniuse-db": "^1.0.30000634",
            +        "normalize-range": "^0.1.2",
            +        "num2fraction": "^1.2.2",
            +        "postcss": "^5.2.16",
            +        "postcss-value-parser": "^3.2.3"
            +      }
            +    },
            +    "node_modules/aws-sign2": {
            +      "version": "0.7.0",
            +      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
            +      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/aws4": {
            +      "version": "1.9.1",
            +      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
            +      "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
            +      "dev": true
            +    },
            +    "node_modules/babel-code-frame": {
            +      "version": "6.26.0",
            +      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
            +      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.1.3",
            +        "esutils": "^2.0.2",
            +        "js-tokens": "^3.0.2"
            +      }
            +    },
            +    "node_modules/bach": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
            +      "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-filter": "^1.1.1",
            +        "arr-flatten": "^1.0.1",
            +        "arr-map": "^2.0.0",
            +        "array-each": "^1.0.0",
            +        "array-initial": "^1.0.0",
            +        "array-last": "^1.1.1",
            +        "async-done": "^1.2.2",
            +        "async-settle": "^1.0.0",
            +        "now-and-later": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/balanced-match": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
            +      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
            +      "dev": true
            +    },
            +    "node_modules/base": {
            +      "version": "0.11.2",
            +      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
            +      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
            +      "dev": true,
            +      "dependencies": {
            +        "cache-base": "^1.0.1",
            +        "class-utils": "^0.3.5",
            +        "component-emitter": "^1.2.1",
            +        "define-property": "^1.0.0",
            +        "isobject": "^3.0.1",
            +        "mixin-deep": "^1.2.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-argv": {
            +      "version": "0.5.0",
            +      "resolved": "https://registry.npmjs.org/base-argv/-/base-argv-0.5.0.tgz",
            +      "integrity": "sha1-Ru4luprtVA6UUF2rHbKQXhqH2Fg=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-diff": "^3.0.0",
            +        "arr-union": "^3.1.0",
            +        "debug": "^2.2.0",
            +        "define-property": "^0.2.5",
            +        "expand-args": "^0.4.2",
            +        "extend-shallow": "^2.0.1",
            +        "is-registered": "^0.1.4",
            +        "is-valid-instance": "^0.1.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-argv/node_modules/arr-diff": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-3.0.0.tgz",
            +      "integrity": "sha1-ORJuZE8dZ/R96S17cCjWCjeXYVI=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-argv/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-argv/node_modules/is-valid-instance": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.1.0.tgz",
            +      "integrity": "sha1-etXGo4ht/ffZzHgEnO/yFxqZB7M=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-argv/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli": {
            +      "version": "0.5.0",
            +      "resolved": "https://registry.npmjs.org/base-cli/-/base-cli-0.5.0.tgz",
            +      "integrity": "sha1-U+Zdjg9bKKoRBo/sjdTpXXLvPOg=",
            +      "dev": true,
            +      "dependencies": {
            +        "base-argv": "^0.4.2",
            +        "base-config": "^0.5.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli-process": {
            +      "version": "0.1.19",
            +      "resolved": "https://registry.npmjs.org/base-cli-process/-/base-cli-process-0.1.19.tgz",
            +      "integrity": "sha1-Mg08gVTfcQltSBgY52/m1+R5NjY=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "arrayify-compact": "^0.2.0",
            +        "base-cli": "^0.5.0",
            +        "base-cli-schema": "^0.1.19",
            +        "base-config-process": "^0.1.9",
            +        "base-cwd": "^0.3.4",
            +        "base-option": "^0.8.4",
            +        "base-pkg": "^0.2.4",
            +        "debug": "^2.6.2",
            +        "export-files": "^2.1.1",
            +        "fs-exists-sync": "^0.1.0",
            +        "is-valid-app": "^0.2.1",
            +        "kind-of": "^3.1.0",
            +        "lazy-cache": "^2.0.2",
            +        "log-utils": "^0.2.1",
            +        "merge-deep": "^3.0.0",
            +        "mixin-deep": "^1.2.0",
            +        "object.pick": "^1.2.0",
            +        "pad-right": "^0.2.2",
            +        "union-value": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0"
            +      }
            +    },
            +    "node_modules/base-cli-process/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli-process/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli-process/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli-process/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli-process/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli-schema": {
            +      "version": "0.1.19",
            +      "resolved": "https://registry.npmjs.org/base-cli-schema/-/base-cli-schema-0.1.19.tgz",
            +      "integrity": "sha1-gfQYL0zwu4NnHxF2PknLBbkugkE=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "array-unique": "^0.2.1",
            +        "debug": "^2.2.0",
            +        "define-property": "^0.2.5",
            +        "export-files": "^2.1.1",
            +        "extend-shallow": "^2.0.1",
            +        "falsey": "^0.3.0",
            +        "fs-exists-sync": "^0.1.0",
            +        "has-glob": "^0.1.1",
            +        "has-value": "^0.3.1",
            +        "kind-of": "^3.0.3",
            +        "lazy-cache": "^2.0.1",
            +        "map-schema": "^0.2.3",
            +        "merge-deep": "^3.0.0",
            +        "mixin-deep": "^1.1.3",
            +        "resolve": "^1.1.7",
            +        "tableize-object": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0"
            +      }
            +    },
            +    "node_modules/base-cli-schema/node_modules/has-glob": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-0.1.1.tgz",
            +      "integrity": "sha1-omHEwqbGZ+DHe3AKfyl8Oe86pYk=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli-schema/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli-schema/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli-schema/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli/node_modules/base-argv": {
            +      "version": "0.4.5",
            +      "resolved": "https://registry.npmjs.org/base-argv/-/base-argv-0.4.5.tgz",
            +      "integrity": "sha1-BalXHNwnaUDeGW/8h07uuJnLED0=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-diff": "^2.0.0",
            +        "arr-union": "^3.1.0",
            +        "debug": "^2.2.0",
            +        "define-property": "^0.2.5",
            +        "expand-args": "^0.4.1",
            +        "extend-shallow": "^2.0.1",
            +        "lazy-cache": "^1.0.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cli/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config": {
            +      "version": "0.5.2",
            +      "resolved": "https://registry.npmjs.org/base-config/-/base-config-0.5.2.tgz",
            +      "integrity": "sha1-q2A8AdExWL4uYux3/7Ix4o9Ijh8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.0.0",
            +        "lazy-cache": "^1.0.3",
            +        "map-config": "^0.5.0",
            +        "resolve-dir": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-process": {
            +      "version": "0.1.9",
            +      "resolved": "https://registry.npmjs.org/base-config-process/-/base-config-process-0.1.9.tgz",
            +      "integrity": "sha1-imOmGYnuY1UMyM/cP2wCdf2gtG4=",
            +      "dev": true,
            +      "dependencies": {
            +        "base-config": "^0.5.2",
            +        "base-config-schema": "^0.1.18",
            +        "base-cwd": "^0.3.4",
            +        "base-option": "^0.8.4",
            +        "debug": "^2.2.0",
            +        "export-files": "^2.1.1",
            +        "is-valid-app": "^0.2.0",
            +        "lazy-cache": "^2.0.1",
            +        "micromatch": "^2.3.10",
            +        "mixin-deep": "^1.1.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-process/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-process/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-process/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema": {
            +      "version": "0.1.24",
            +      "resolved": "https://registry.npmjs.org/base-config-schema/-/base-config-schema-0.1.24.tgz",
            +      "integrity": "sha1-T74UvsVtwa7ef+3QaSjpGfhyH6k=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.3",
            +        "array-unique": "^0.3.2",
            +        "base-pkg": "^0.2.4",
            +        "camel-case": "^3.0.0",
            +        "debug": "^2.6.6",
            +        "define-property": "^1.0.0",
            +        "export-files": "^2.1.1",
            +        "extend-shallow": "^2.0.1",
            +        "has-glob": "^1.0.0",
            +        "has-value": "^0.3.1",
            +        "inflection": "^1.12.0",
            +        "kind-of": "^3.2.0",
            +        "lazy-cache": "^2.0.2",
            +        "load-templates": "^1.0.2",
            +        "map-schema": "^0.2.4",
            +        "matched": "^0.4.4",
            +        "mixin-deep": "^1.2.0",
            +        "resolve": "^1.3.3"
            +      },
            +      "engines": {
            +        "node": ">=0.12.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/array-unique": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
            +      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/define-property": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
            +      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/expand-tilde": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
            +      "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
            +      "dev": true,
            +      "dependencies": {
            +        "os-homedir": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/is-accessor-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/is-accessor-descriptor/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/is-data-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/is-data-descriptor/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/is-descriptor": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
            +      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^1.0.0",
            +        "is-data-descriptor": "^1.0.0",
            +        "kind-of": "^6.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/is-descriptor/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/matched": {
            +      "version": "0.4.4",
            +      "resolved": "https://registry.npmjs.org/matched/-/matched-0.4.4.tgz",
            +      "integrity": "sha1-Vte36xgDPwz5vFLrIJD6x9weifo=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "async-array-reduce": "^0.2.0",
            +        "extend-shallow": "^2.0.1",
            +        "fs-exists-sync": "^0.1.0",
            +        "glob": "^7.0.5",
            +        "has-glob": "^0.1.1",
            +        "is-valid-glob": "^0.3.0",
            +        "lazy-cache": "^2.0.1",
            +        "resolve-dir": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.12.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/matched/node_modules/has-glob": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-0.1.1.tgz",
            +      "integrity": "sha1-omHEwqbGZ+DHe3AKfyl8Oe86pYk=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config-schema/node_modules/resolve-dir": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
            +      "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^1.2.2",
            +        "global-modules": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config/node_modules/expand-tilde": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
            +      "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
            +      "dev": true,
            +      "dependencies": {
            +        "os-homedir": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-config/node_modules/resolve-dir": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
            +      "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^1.2.2",
            +        "global-modules": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cwd": {
            +      "version": "0.3.4",
            +      "resolved": "https://registry.npmjs.org/base-cwd/-/base-cwd-0.3.4.tgz",
            +      "integrity": "sha1-TQCrY1CgRuGtSrnCMm2heUs+TwE=",
            +      "dev": true,
            +      "dependencies": {
            +        "empty-dir": "^0.2.0",
            +        "find-pkg": "^0.1.2",
            +        "is-valid-app": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cwd/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cwd/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-cwd/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-data": {
            +      "version": "0.6.2",
            +      "resolved": "https://registry.npmjs.org/base-data/-/base-data-0.6.2.tgz",
            +      "integrity": "sha512-wH2ViG6CUO2AaeHSEt6fJTyQAk5gl0oY456DoSC5h8mnHrWUbvdctMCuF53CXgBmi0oalZQppKNH0iamG5+uqw==",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.1.0",
            +        "cache-base": "^1.0.0",
            +        "extend-shallow": "^2.0.1",
            +        "get-value": "^2.0.6",
            +        "has-glob": "^1.0.0",
            +        "has-value": "^1.0.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-app": "^0.3.0",
            +        "kind-of": "^5.0.0",
            +        "lazy-cache": "^2.0.2",
            +        "merge-value": "^1.0.0",
            +        "mixin-deep": "^1.2.0",
            +        "read-file": "^0.2.0",
            +        "resolve-glob": "^1.0.0",
            +        "set-value": "^2.0.0",
            +        "union-value": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-data/node_modules/has-value": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
            +      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
            +      "dev": true,
            +      "dependencies": {
            +        "get-value": "^2.0.6",
            +        "has-values": "^1.0.0",
            +        "isobject": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-data/node_modules/set-value": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
            +      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "is-extendable": "^0.1.1",
            +        "is-plain-object": "^2.0.3",
            +        "split-string": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-engines": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/base-engines/-/base-engines-0.2.1.tgz",
            +      "integrity": "sha1-aXgAyoq4iKM3iXONv6zLgYoqWns=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "define-property": "^0.2.5",
            +        "engine-cache": "^0.19.0",
            +        "is-valid-app": "^0.1.2",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-engines/node_modules/is-valid-app": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.1.2.tgz",
            +      "integrity": "sha1-L2fLs7r2TWWccNBD/JETm1qLlZA=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.1.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-engines/node_modules/is-valid-instance": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.1.0.tgz",
            +      "integrity": "sha1-etXGo4ht/ffZzHgEnO/yFxqZB7M=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-engines/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-helpers": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/base-helpers/-/base-helpers-0.2.0.tgz",
            +      "integrity": "sha1-dalJS7jAWf89eUOCnPdVBHv+ENc=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.6.0",
            +        "define-property": "^0.2.5",
            +        "is-valid-app": "^0.2.1",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.2",
            +        "load-helpers": "^0.3.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-helpers/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-helpers/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-helpers/node_modules/is-valid-instance/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-option": {
            +      "version": "0.8.4",
            +      "resolved": "https://registry.npmjs.org/base-option/-/base-option-0.8.4.tgz",
            +      "integrity": "sha1-EUF/qSRPInpNU3tNKRcjRieH1cc=",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^0.2.5",
            +        "get-value": "^2.0.6",
            +        "is-valid-app": "^0.2.0",
            +        "isobject": "^2.1.0",
            +        "lazy-cache": "^2.0.1",
            +        "mixin-deep": "^1.1.3",
            +        "option-cache": "^3.4.0",
            +        "set-value": "^0.3.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-option/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-option/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-option/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-option/node_modules/set-value": {
            +      "version": "0.3.3",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.3.3.tgz",
            +      "integrity": "sha1-uBIjaBY4oQiP2IpDW4qdMtro2bo=",
            +      "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "isobject": "^2.0.0",
            +        "to-object-path": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-option/node_modules/to-object-path": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.2.0.tgz",
            +      "integrity": "sha1-FjThtSqIugDjlJYZ/ACB3Jo7B8o=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "is-arguments": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-pkg": {
            +      "version": "0.2.5",
            +      "resolved": "https://registry.npmjs.org/base-pkg/-/base-pkg-0.2.5.tgz",
            +      "integrity": "sha512-/POxajlgBhVsknwLXnqnbp//bAMh7SkDgHF+z/uoYnFqk46e05c3MxSEmn5vFCB8g4rHHKxAPLKrU/4Yb3vUdA==",
            +      "dev": true,
            +      "dependencies": {
            +        "cache-base": "^1.0.0",
            +        "debug": "^2.6.8",
            +        "define-property": "^1.0.0",
            +        "expand-pkg": "^0.1.8",
            +        "extend-shallow": "^2.0.1",
            +        "is-valid-app": "^0.3.0",
            +        "log-utils": "^0.2.1",
            +        "pkg-store": "^0.2.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-pkg/node_modules/define-property": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
            +      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-pkg/node_modules/is-accessor-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-pkg/node_modules/is-data-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-pkg/node_modules/is-descriptor": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
            +      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^1.0.0",
            +        "is-data-descriptor": "^1.0.0",
            +        "kind-of": "^6.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-pkg/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-plugins": {
            +      "version": "0.4.13",
            +      "resolved": "https://registry.npmjs.org/base-plugins/-/base-plugins-0.4.13.tgz",
            +      "integrity": "sha1-kd8XjcN/hoQt6ihteeSPuGtarD0=",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^0.2.5",
            +        "is-registered": "^0.1.5",
            +        "isobject": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-plugins/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-questions": {
            +      "version": "0.9.1",
            +      "resolved": "https://registry.npmjs.org/base-questions/-/base-questions-0.9.1.tgz",
            +      "integrity": "sha1-j/QX9ghiV2e+gCkn8fsR5daRQy4=",
            +      "dev": true,
            +      "dependencies": {
            +        "base-store": "^0.4.4",
            +        "clone-deep": "^0.2.4",
            +        "debug": "^2.2.0",
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "get-value": "^2.0.6",
            +        "is-valid-app": "^0.2.1",
            +        "isobject": "^2.1.0",
            +        "lazy-cache": "^2.0.1",
            +        "mixin-deep": "^1.1.3",
            +        "question-store": "^0.13.0",
            +        "set-value": "^0.4.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-questions/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-questions/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-questions/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-routes": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/base-routes/-/base-routes-0.2.2.tgz",
            +      "integrity": "sha1-CmFNFy1JBF2Mk4dxP4YN88QFNB4=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "en-route": "^0.7.5",
            +        "is-valid-app": "^0.2.0",
            +        "lazy-cache": "^2.0.1",
            +        "template-error": "^0.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-routes/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-routes/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-routes/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-runtimes": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/base-runtimes/-/base-runtimes-0.2.0.tgz",
            +      "integrity": "sha1-GI4+ZoJMyxWYsyh7TqW5NaG4UEU=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "is-valid-app": "^0.2.0",
            +        "lazy-cache": "^2.0.1",
            +        "log-utils": "^0.1.4",
            +        "micromatch": "^2.3.10",
            +        "time-diff": "^0.3.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-runtimes/node_modules/ansi-colors": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-0.1.0.tgz",
            +      "integrity": "sha1-M0rDbNPq1wjeXGnhmpjRhkImtD8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-bgblack": "^0.1.1",
            +        "ansi-bgblue": "^0.1.1",
            +        "ansi-bgcyan": "^0.1.1",
            +        "ansi-bggreen": "^0.1.1",
            +        "ansi-bgmagenta": "^0.1.1",
            +        "ansi-bgred": "^0.1.1",
            +        "ansi-bgwhite": "^0.1.1",
            +        "ansi-bgyellow": "^0.1.1",
            +        "ansi-black": "^0.1.1",
            +        "ansi-blue": "^0.1.1",
            +        "ansi-bold": "^0.1.1",
            +        "ansi-cyan": "^0.1.1",
            +        "ansi-dim": "^0.1.1",
            +        "ansi-gray": "^0.1.1",
            +        "ansi-green": "^0.1.1",
            +        "ansi-grey": "^0.1.1",
            +        "ansi-hidden": "^0.1.1",
            +        "ansi-inverse": "^0.1.1",
            +        "ansi-italic": "^0.1.1",
            +        "ansi-magenta": "^0.1.1",
            +        "ansi-red": "^0.1.1",
            +        "ansi-reset": "^0.1.1",
            +        "ansi-strikethrough": "^0.1.1",
            +        "ansi-underline": "^0.1.1",
            +        "ansi-white": "^0.1.1",
            +        "ansi-yellow": "^0.1.1",
            +        "lazy-cache": "^0.2.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-runtimes/node_modules/ansi-colors/node_modules/lazy-cache": {
            +      "version": "0.2.7",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
            +      "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-runtimes/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-runtimes/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-runtimes/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-runtimes/node_modules/log-utils": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/log-utils/-/log-utils-0.1.5.tgz",
            +      "integrity": "sha1-3g84+Vf0zW69Xctoddijua4HT3c=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-colors": "^0.1.0",
            +        "error-symbol": "^0.1.0",
            +        "info-symbol": "^0.1.0",
            +        "log-ok": "^0.1.1",
            +        "success-symbol": "^0.1.0",
            +        "time-stamp": "^1.0.1",
            +        "warning-symbol": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-store": {
            +      "version": "0.4.4",
            +      "resolved": "https://registry.npmjs.org/base-store/-/base-store-0.4.4.tgz",
            +      "integrity": "sha1-JY32uKYu4G/xUADJSdD9fCi68mY=",
            +      "dev": true,
            +      "dependencies": {
            +        "data-store": "^0.16.0",
            +        "debug": "^2.2.0",
            +        "extend-shallow": "^2.0.1",
            +        "is-registered": "^0.1.4",
            +        "is-valid-instance": "^0.1.0",
            +        "lazy-cache": "^2.0.1",
            +        "project-name": "^0.2.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-store/node_modules/is-valid-instance": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.1.0.tgz",
            +      "integrity": "sha1-etXGo4ht/ffZzHgEnO/yFxqZB7M=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-store/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base-task": {
            +      "version": "0.7.1",
            +      "resolved": "https://registry.npmjs.org/base-task/-/base-task-0.7.1.tgz",
            +      "integrity": "sha1-m26qObA4CmHYMIpmVSV7CzghFCk=",
            +      "dev": true,
            +      "dependencies": {
            +        "composer": "^0.14.0",
            +        "is-valid-app": "^0.3.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base/node_modules/define-property": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
            +      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base/node_modules/is-accessor-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base/node_modules/is-data-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base/node_modules/is-descriptor": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
            +      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^1.0.0",
            +        "is-data-descriptor": "^1.0.0",
            +        "kind-of": "^6.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base/node_modules/kind-of": {
            +      "version": "6.0.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
            +      "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/base64-js": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
            +      "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
            +      "dev": true
            +    },
            +    "node_modules/basic-auth": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
            +      "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
            +      "dev": true,
            +      "dependencies": {
            +        "safe-buffer": "5.1.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.8"
            +      }
            +    },
            +    "node_modules/batch": {
            +      "version": "0.5.0",
            +      "resolved": "https://registry.npmjs.org/batch/-/batch-0.5.0.tgz",
            +      "integrity": "sha1-/S4Fp6XWlrTbkxQBPihdj/NVfsM=",
            +      "dev": true
            +    },
            +    "node_modules/bcrypt-pbkdf": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
            +      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
            +      "dev": true,
            +      "dependencies": {
            +        "tweetnacl": "^0.14.3"
            +      }
            +    },
            +    "node_modules/benchmark": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-1.0.0.tgz",
            +      "integrity": "sha1-Lx4vpMNZ8REiqhgwgiGOlX45DHM=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/benchmarked": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/benchmarked/-/benchmarked-0.1.5.tgz",
            +      "integrity": "sha1-hxPRaOC87Hy73z8JPDT7USPofkk=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi": "^0.3.0",
            +        "benchmark": "^1.0.0",
            +        "chalk": "^1.0.0",
            +        "extend-shallow": "^1.1.2",
            +        "file-reader": "^1.0.0",
            +        "for-own": "^0.1.3",
            +        "has-values": "^0.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/benchmarked/node_modules/extend-shallow": {
            +      "version": "1.1.4",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
            +      "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/benchmarked/node_modules/has-values": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
            +      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/benchmarked/node_modules/kind-of": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
            +      "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/bin-build": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/bin-build/-/bin-build-3.0.0.tgz",
            +      "integrity": "sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA==",
            +      "dev": true,
            +      "dependencies": {
            +        "decompress": "^4.0.0",
            +        "download": "^6.2.2",
            +        "execa": "^0.7.0",
            +        "p-map-series": "^1.0.0",
            +        "tempfile": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/bin-check": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz",
            +      "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==",
            +      "dev": true,
            +      "dependencies": {
            +        "execa": "^0.7.0",
            +        "executable": "^4.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/bin-version": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-3.1.0.tgz",
            +      "integrity": "sha512-Mkfm4iE1VFt4xd4vH+gx+0/71esbfus2LsnCGe8Pi4mndSPyT+NGES/Eg99jx8/lUGWfu3z2yuB/bt5UB+iVbQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "execa": "^1.0.0",
            +        "find-versions": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/bin-version-check": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-4.0.0.tgz",
            +      "integrity": "sha512-sR631OrhC+1f8Cvs8WyVWOA33Y8tgwjETNPyyD/myRBXLkfS/vl74FmH/lFcRl9KY3zwGh7jFhvyk9vV3/3ilQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "bin-version": "^3.0.0",
            +        "semver": "^5.6.0",
            +        "semver-truncate": "^1.1.2"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/bin-version-check/node_modules/semver": {
            +      "version": "5.7.1",
            +      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
            +      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
            +      "dev": true,
            +      "bin": {
            +        "semver": "bin/semver"
            +      }
            +    },
            +    "node_modules/bin-version/node_modules/cross-spawn": {
            +      "version": "6.0.5",
            +      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
            +      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "nice-try": "^1.0.4",
            +        "path-key": "^2.0.1",
            +        "semver": "^5.5.0",
            +        "shebang-command": "^1.2.0",
            +        "which": "^1.2.9"
            +      },
            +      "engines": {
            +        "node": ">=4.8"
            +      }
            +    },
            +    "node_modules/bin-version/node_modules/execa": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
            +      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
            +      "dev": true,
            +      "dependencies": {
            +        "cross-spawn": "^6.0.0",
            +        "get-stream": "^4.0.0",
            +        "is-stream": "^1.1.0",
            +        "npm-run-path": "^2.0.0",
            +        "p-finally": "^1.0.0",
            +        "signal-exit": "^3.0.0",
            +        "strip-eof": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/bin-version/node_modules/get-stream": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
            +      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
            +      "dev": true,
            +      "dependencies": {
            +        "pump": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/bin-version/node_modules/pump": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
            +      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
            +      "dev": true,
            +      "dependencies": {
            +        "end-of-stream": "^1.1.0",
            +        "once": "^1.3.1"
            +      }
            +    },
            +    "node_modules/bin-wrapper": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/bin-wrapper/-/bin-wrapper-4.1.0.tgz",
            +      "integrity": "sha512-hfRmo7hWIXPkbpi0ZltboCMVrU+0ClXR/JgbCKKjlDjQf6igXa7OwdqNcFWQZPZTgiY7ZpzE3+LjjkLiTN2T7Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "bin-check": "^4.1.0",
            +        "bin-version-check": "^4.0.0",
            +        "download": "^7.1.0",
            +        "import-lazy": "^3.1.0",
            +        "os-filter-obj": "^2.0.0",
            +        "pify": "^4.0.1"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/download": {
            +      "version": "7.1.0",
            +      "resolved": "https://registry.npmjs.org/download/-/download-7.1.0.tgz",
            +      "integrity": "sha512-xqnBTVd/E+GxJVrX5/eUJiLYjCGPwMpdL+jGhGU57BvtcA7wwhtHVbXBeUk51kOpW3S7Jn3BQbN9Q1R1Km2qDQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "archive-type": "^4.0.0",
            +        "caw": "^2.0.1",
            +        "content-disposition": "^0.5.2",
            +        "decompress": "^4.2.0",
            +        "ext-name": "^5.0.0",
            +        "file-type": "^8.1.0",
            +        "filenamify": "^2.0.0",
            +        "get-stream": "^3.0.0",
            +        "got": "^8.3.1",
            +        "make-dir": "^1.2.0",
            +        "p-event": "^2.1.0",
            +        "pify": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/download/node_modules/pify": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
            +      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/file-type": {
            +      "version": "8.1.0",
            +      "resolved": "https://registry.npmjs.org/file-type/-/file-type-8.1.0.tgz",
            +      "integrity": "sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/got": {
            +      "version": "8.3.2",
            +      "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
            +      "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
            +      "dev": true,
            +      "dependencies": {
            +        "@sindresorhus/is": "^0.7.0",
            +        "cacheable-request": "^2.1.1",
            +        "decompress-response": "^3.3.0",
            +        "duplexer3": "^0.1.4",
            +        "get-stream": "^3.0.0",
            +        "into-stream": "^3.1.0",
            +        "is-retry-allowed": "^1.1.0",
            +        "isurl": "^1.0.0-alpha5",
            +        "lowercase-keys": "^1.0.0",
            +        "mimic-response": "^1.0.0",
            +        "p-cancelable": "^0.4.0",
            +        "p-timeout": "^2.0.1",
            +        "pify": "^3.0.0",
            +        "safe-buffer": "^5.1.1",
            +        "timed-out": "^4.0.1",
            +        "url-parse-lax": "^3.0.0",
            +        "url-to-options": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/got/node_modules/pify": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
            +      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/p-cancelable": {
            +      "version": "0.4.1",
            +      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
            +      "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/p-event": {
            +      "version": "2.3.1",
            +      "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz",
            +      "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==",
            +      "dev": true,
            +      "dependencies": {
            +        "p-timeout": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/p-timeout": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
            +      "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
            +      "dev": true,
            +      "dependencies": {
            +        "p-finally": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/pify": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
            +      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/prepend-http": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
            +      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/bin-wrapper/node_modules/url-parse-lax": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
            +      "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
            +      "dev": true,
            +      "dependencies": {
            +        "prepend-http": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/bl": {
            +      "version": "1.2.3",
            +      "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
            +      "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
            +      "dev": true,
            +      "dependencies": {
            +        "readable-stream": "^2.3.5",
            +        "safe-buffer": "^5.1.1"
            +      }
            +    },
            +    "node_modules/body": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz",
            +      "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=",
            +      "dev": true,
            +      "dependencies": {
            +        "continuable-cache": "^0.3.1",
            +        "error": "^7.0.0",
            +        "raw-body": "~1.1.0",
            +        "safe-json-parse": "~1.0.1"
            +      }
            +    },
            +    "node_modules/boolbase": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
            +      "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
            +      "dev": true
            +    },
            +    "node_modules/brace-expansion": {
            +      "version": "1.1.11",
            +      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
            +      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
            +      "dev": true,
            +      "dependencies": {
            +        "balanced-match": "^1.0.0",
            +        "concat-map": "0.0.1"
            +      }
            +    },
            +    "node_modules/braces": {
            +      "version": "1.8.5",
            +      "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
            +      "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-range": "^1.8.1",
            +        "preserve": "^0.2.0",
            +        "repeat-element": "^1.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/browser-process-hrtime": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
            +      "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
            +      "dev": true
            +    },
            +    "node_modules/browserslist": {
            +      "version": "1.7.7",
            +      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
            +      "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
            +      "deprecated": "Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.",
            +      "dev": true,
            +      "dependencies": {
            +        "caniuse-db": "^1.0.30000639",
            +        "electron-to-chromium": "^1.2.7"
            +      },
            +      "bin": {
            +        "browserslist": "cli.js"
            +      }
            +    },
            +    "node_modules/buffer": {
            +      "version": "5.6.0",
            +      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
            +      "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
            +      "dev": true,
            +      "dependencies": {
            +        "base64-js": "^1.0.2",
            +        "ieee754": "^1.1.4"
            +      }
            +    },
            +    "node_modules/buffer-alloc": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
            +      "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
            +      "dev": true,
            +      "dependencies": {
            +        "buffer-alloc-unsafe": "^1.1.0",
            +        "buffer-fill": "^1.0.0"
            +      }
            +    },
            +    "node_modules/buffer-alloc-unsafe": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
            +      "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
            +      "dev": true
            +    },
            +    "node_modules/buffer-crc32": {
            +      "version": "0.2.13",
            +      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
            +      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/buffer-fill": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
            +      "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
            +      "dev": true
            +    },
            +    "node_modules/buffer-from": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz",
            +      "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==",
            +      "dev": true
            +    },
            +    "node_modules/builtin-modules": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
            +      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/bytes": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz",
            +      "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=",
            +      "dev": true
            +    },
            +    "node_modules/cache-base": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
            +      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "collection-visit": "^1.0.0",
            +        "component-emitter": "^1.2.1",
            +        "get-value": "^2.0.6",
            +        "has-value": "^1.0.0",
            +        "isobject": "^3.0.1",
            +        "set-value": "^2.0.0",
            +        "to-object-path": "^0.3.0",
            +        "union-value": "^1.0.0",
            +        "unset-value": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cache-base/node_modules/has-value": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
            +      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
            +      "dev": true,
            +      "dependencies": {
            +        "get-value": "^2.0.6",
            +        "has-values": "^1.0.0",
            +        "isobject": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cache-base/node_modules/set-value": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
            +      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "is-extendable": "^0.1.1",
            +        "is-plain-object": "^2.0.3",
            +        "split-string": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cacheable-request": {
            +      "version": "2.1.4",
            +      "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
            +      "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=",
            +      "dev": true,
            +      "dependencies": {
            +        "clone-response": "1.0.2",
            +        "get-stream": "3.0.0",
            +        "http-cache-semantics": "3.8.1",
            +        "keyv": "3.0.0",
            +        "lowercase-keys": "1.0.0",
            +        "normalize-url": "2.0.1",
            +        "responselike": "1.0.2"
            +      }
            +    },
            +    "node_modules/cacheable-request/node_modules/lowercase-keys": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
            +      "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cacheable-request/node_modules/normalize-url": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
            +      "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
            +      "dev": true,
            +      "dependencies": {
            +        "prepend-http": "^2.0.0",
            +        "query-string": "^5.0.1",
            +        "sort-keys": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cacheable-request/node_modules/prepend-http": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
            +      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cacheable-request/node_modules/query-string": {
            +      "version": "5.1.1",
            +      "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
            +      "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
            +      "dev": true,
            +      "dependencies": {
            +        "decode-uri-component": "^0.2.0",
            +        "object-assign": "^4.1.0",
            +        "strict-uri-encode": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cacheable-request/node_modules/sort-keys": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
            +      "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-obj": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/call-bind": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
            +      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
            +      "dev": true,
            +      "dependencies": {
            +        "function-bind": "^1.1.1",
            +        "get-intrinsic": "^1.0.2"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/call-me-maybe": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
            +      "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
            +      "dev": true
            +    },
            +    "node_modules/caller-callsite": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
            +      "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "callsites": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/caller-callsite/node_modules/callsites": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
            +      "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/caller-path": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
            +      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
            +      "dev": true,
            +      "dependencies": {
            +        "callsites": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/callsites": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
            +      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/camel-case": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
            +      "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
            +      "dev": true,
            +      "dependencies": {
            +        "no-case": "^2.2.0",
            +        "upper-case": "^1.1.1"
            +      }
            +    },
            +    "node_modules/camelcase": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
            +      "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/camelcase-keys": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
            +      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
            +      "dev": true,
            +      "dependencies": {
            +        "camelcase": "^2.0.0",
            +        "map-obj": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/camelcase-keys/node_modules/camelcase": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
            +      "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/caniuse-api": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
            +      "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
            +      "dev": true,
            +      "dependencies": {
            +        "browserslist": "^4.0.0",
            +        "caniuse-lite": "^1.0.0",
            +        "lodash.memoize": "^4.1.2",
            +        "lodash.uniq": "^4.5.0"
            +      }
            +    },
            +    "node_modules/caniuse-api/node_modules/browserslist": {
            +      "version": "4.16.6",
            +      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
            +      "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "caniuse-lite": "^1.0.30001219",
            +        "colorette": "^1.2.2",
            +        "electron-to-chromium": "^1.3.723",
            +        "escalade": "^3.1.1",
            +        "node-releases": "^1.1.71"
            +      },
            +      "bin": {
            +        "browserslist": "cli.js"
            +      },
            +      "engines": {
            +        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/browserslist"
            +      }
            +    },
            +    "node_modules/caniuse-api/node_modules/electron-to-chromium": {
            +      "version": "1.3.752",
            +      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz",
            +      "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==",
            +      "dev": true
            +    },
            +    "node_modules/caniuse-db": {
            +      "version": "1.0.30000870",
            +      "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000870.tgz",
            +      "integrity": "sha1-85fNZJIsJPhdDOeAPJvVxaFXGxY=",
            +      "dev": true
            +    },
            +    "node_modules/caniuse-lite": {
            +      "version": "1.0.30001239",
            +      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001239.tgz",
            +      "integrity": "sha512-cyBkXJDMeI4wthy8xJ2FvDU6+0dtcZSJW3voUF8+e9f1bBeuvyZfc3PNbkOETyhbR+dGCPzn9E7MA3iwzusOhQ==",
            +      "dev": true,
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/browserslist"
            +      }
            +    },
            +    "node_modules/caseless": {
            +      "version": "0.12.0",
            +      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
            +      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
            +      "dev": true
            +    },
            +    "node_modules/caw": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz",
            +      "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==",
            +      "dev": true,
            +      "dependencies": {
            +        "get-proxy": "^2.0.0",
            +        "isurl": "^1.0.0-alpha5",
            +        "tunnel-agent": "^0.6.0",
            +        "url-to-options": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/center-align": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
            +      "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
            +      "dev": true,
            +      "dependencies": {
            +        "align-text": "^0.1.3",
            +        "lazy-cache": "^1.0.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/center-align/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/chalk": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
            +      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^2.2.1",
            +        "escape-string-regexp": "^1.0.2",
            +        "has-ansi": "^2.0.0",
            +        "strip-ansi": "^3.0.0",
            +        "supports-color": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/chardet": {
            +      "version": "0.4.2",
            +      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
            +      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
            +      "dev": true
            +    },
            +    "node_modules/chownr": {
            +      "version": "1.1.4",
            +      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
            +      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/ci-info": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.3.tgz",
            +      "integrity": "sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg==",
            +      "dev": true
            +    },
            +    "node_modules/circular-json": {
            +      "version": "0.3.3",
            +      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
            +      "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
            +      "deprecated": "CircularJSON is in maintenance only, flatted is its successor.",
            +      "dev": true
            +    },
            +    "node_modules/class-utils": {
            +      "version": "0.3.6",
            +      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
            +      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "define-property": "^0.2.5",
            +        "isobject": "^3.0.0",
            +        "static-extend": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/class-utils/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/clean-stack": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
            +      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/cli-cursor": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
            +      "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
            +      "dev": true,
            +      "dependencies": {
            +        "restore-cursor": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cli-truncate": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
            +      "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "slice-ansi": "0.0.4",
            +        "string-width": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cli-truncate/node_modules/slice-ansi": {
            +      "version": "0.0.4",
            +      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
            +      "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cli-truncate/node_modules/string-width": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
            +      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
            +      "dev": true,
            +      "dependencies": {
            +        "code-point-at": "^1.0.0",
            +        "is-fullwidth-code-point": "^1.0.0",
            +        "strip-ansi": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cli-width": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz",
            +      "integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0=",
            +      "dev": true
            +    },
            +    "node_modules/cliui": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
            +      "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
            +      "dev": true,
            +      "dependencies": {
            +        "center-align": "^0.1.1",
            +        "right-align": "^0.1.1",
            +        "wordwrap": "0.0.2"
            +      }
            +    },
            +    "node_modules/cliui/node_modules/wordwrap": {
            +      "version": "0.0.2",
            +      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
            +      "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/clone": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
            +      "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/clone-buffer": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
            +      "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/clone-deep": {
            +      "version": "0.2.4",
            +      "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz",
            +      "integrity": "sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY=",
            +      "dev": true,
            +      "dependencies": {
            +        "for-own": "^0.1.3",
            +        "is-plain-object": "^2.0.1",
            +        "kind-of": "^3.0.2",
            +        "lazy-cache": "^1.0.3",
            +        "shallow-clone": "^0.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/clone-deep/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/clone-deep/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/clone-response": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
            +      "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
            +      "dev": true,
            +      "dependencies": {
            +        "mimic-response": "^1.0.0"
            +      }
            +    },
            +    "node_modules/clone-stats": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
            +      "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=",
            +      "dev": true
            +    },
            +    "node_modules/cloneable-readable": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
            +      "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "inherits": "^2.0.1",
            +        "process-nextick-args": "^2.0.0",
            +        "readable-stream": "^2.3.5"
            +      }
            +    },
            +    "node_modules/co": {
            +      "version": "4.6.0",
            +      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
            +      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
            +      "dev": true,
            +      "engines": {
            +        "iojs": ">= 1.0.0",
            +        "node": ">= 0.12.0"
            +      }
            +    },
            +    "node_modules/coa": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
            +      "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==",
            +      "dev": true,
            +      "dependencies": {
            +        "@types/q": "^1.5.1",
            +        "chalk": "^2.4.1",
            +        "q": "^1.1.2"
            +      },
            +      "engines": {
            +        "node": ">= 4.0"
            +      }
            +    },
            +    "node_modules/coa/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/coa/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/coa/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/coa/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/code-point-at": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
            +      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/coffee-script": {
            +      "version": "1.6.3",
            +      "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.3.tgz",
            +      "integrity": "sha1-Y1XTLPGwTN/2tITl5xF4Ky8MOb4=",
            +      "deprecated": "CoffeeScript on NPM has moved to \"coffeescript\" (no hyphen)",
            +      "dev": true,
            +      "bin": {
            +        "cake": "bin/cake",
            +        "coffee": "bin/coffee"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/collection-visit": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
            +      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
            +      "dev": true,
            +      "dependencies": {
            +        "map-visit": "^1.0.0",
            +        "object-visit": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/color": {
            +      "version": "3.1.3",
            +      "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
            +      "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.1",
            +        "color-string": "^1.5.4"
            +      }
            +    },
            +    "node_modules/color-convert": {
            +      "version": "1.9.2",
            +      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz",
            +      "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-name": "1.1.1"
            +      }
            +    },
            +    "node_modules/color-name": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz",
            +      "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=",
            +      "dev": true
            +    },
            +    "node_modules/color-string": {
            +      "version": "1.5.5",
            +      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz",
            +      "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-name": "^1.0.0",
            +        "simple-swizzle": "^0.2.2"
            +      }
            +    },
            +    "node_modules/colorette": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
            +      "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
            +      "dev": true
            +    },
            +    "node_modules/colors": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
            +      "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.1.90"
            +      }
            +    },
            +    "node_modules/combined-stream": {
            +      "version": "1.0.8",
            +      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
            +      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
            +      "dev": true,
            +      "dependencies": {
            +        "delayed-stream": "~1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.8"
            +      }
            +    },
            +    "node_modules/commander": {
            +      "version": "2.8.1",
            +      "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
            +      "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "graceful-readlink": ">= 1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.6.x"
            +      }
            +    },
            +    "node_modules/common-config": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/common-config/-/common-config-0.1.1.tgz",
            +      "integrity": "sha512-mDp+nqoFbYsHKZfjg8OSb0CYfdPkuoGTMCVKy4ceYHR0EACTLV/qG8Q4cih2c/0IleQ7SISiqWqLMLXXZnJ2FA==",
            +      "dev": true,
            +      "dependencies": {
            +        "composer": "^0.13.0",
            +        "data-store": "^0.16.1",
            +        "get-value": "^2.0.6",
            +        "lazy-cache": "^2.0.1",
            +        "log-utils": "^0.2.0",
            +        "object.pick": "^1.1.2",
            +        "omit-empty": "^0.4.1",
            +        "question-cache": "^0.4.0",
            +        "set-value": "^3.0.1",
            +        "strip-color": "^0.1.0",
            +        "tableize-object": "^0.1.0",
            +        "text-table": "^0.2.0",
            +        "yargs-parser": "^2.4.0"
            +      },
            +      "bin": {
            +        "common-config": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/async-settle": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-0.2.1.tgz",
            +      "integrity": "sha1-dnRi1XOACNx16sQkYiNSjyE3E5Y=",
            +      "dev": true,
            +      "dependencies": {
            +        "async-done": "^0.4.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/async-settle/node_modules/async-done": {
            +      "version": "0.4.0",
            +      "resolved": "https://registry.npmjs.org/async-done/-/async-done-0.4.0.tgz",
            +      "integrity": "sha1-q4BT9fYikPi/xY83zZtzBwszB7k=",
            +      "dev": true,
            +      "dependencies": {
            +        "end-of-stream": "^0.1.4",
            +        "next-tick": "^0.2.2",
            +        "once": "^1.3.0",
            +        "stream-exhaust": "^1.0.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/bach": {
            +      "version": "0.5.0",
            +      "resolved": "https://registry.npmjs.org/bach/-/bach-0.5.0.tgz",
            +      "integrity": "sha1-P/pqN0F3PrwNJL5f2kvF6FtbHaE=",
            +      "dev": true,
            +      "dependencies": {
            +        "async-done": "^1.1.1",
            +        "async-settle": "^0.2.1",
            +        "lodash.filter": "^4.1.0",
            +        "lodash.flatten": "^4.0.0",
            +        "lodash.foreach": "^4.0.0",
            +        "lodash.initial": "^4.0.1",
            +        "lodash.last": "^3.0.0",
            +        "lodash.map": "^4.1.0",
            +        "now-and-later": "0.0.6"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/composer": {
            +      "version": "0.13.0",
            +      "resolved": "https://registry.npmjs.org/composer/-/composer-0.13.0.tgz",
            +      "integrity": "sha1-HbyxXxmpBt7uSanD0TfmVLvG0OI=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-unique": "^0.2.1",
            +        "bach": "^0.5.0",
            +        "co": "^4.6.0",
            +        "component-emitter": "^1.2.1",
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "is-generator": "^1.0.3",
            +        "is-glob": "^2.0.1",
            +        "isobject": "^2.1.0",
            +        "lazy-cache": "^2.0.1",
            +        "micromatch": "^2.3.8",
            +        "nanoseconds": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/end-of-stream": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz",
            +      "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=",
            +      "dev": true,
            +      "dependencies": {
            +        "once": "~1.3.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/end-of-stream/node_modules/once": {
            +      "version": "1.3.3",
            +      "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
            +      "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=",
            +      "dev": true,
            +      "dependencies": {
            +        "wrappy": "1"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/has-values": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
            +      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/now-and-later": {
            +      "version": "0.0.6",
            +      "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-0.0.6.tgz",
            +      "integrity": "sha1-GKFNw/xJXcBs++Ao8AvhbdrE+uo=",
            +      "dev": true,
            +      "dependencies": {
            +        "once": "^1.3.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/question-cache": {
            +      "version": "0.4.0",
            +      "resolved": "https://registry.npmjs.org/question-cache/-/question-cache-0.4.0.tgz",
            +      "integrity": "sha1-4rmTf8X7fcYPu58QXx+iVLM96n0=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "arr-union": "^3.1.0",
            +        "async": "1.5.2",
            +        "debug": "^2.2.0",
            +        "define-property": "^0.2.5",
            +        "get-value": "^2.0.5",
            +        "has-value": "^0.3.1",
            +        "inquirer2": "^0.1.1",
            +        "is-answer": "^0.1.0",
            +        "isobject": "^2.0.0",
            +        "lazy-cache": "^1.0.3",
            +        "mixin-deep": "^1.1.3",
            +        "omit-empty": "^0.3.6",
            +        "option-cache": "^3.3.5",
            +        "os-homedir": "^1.0.1",
            +        "project-name": "^0.2.4",
            +        "set-value": "^0.3.3",
            +        "to-choices": "^0.2.0",
            +        "use": "^1.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/question-cache/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/question-cache/node_modules/omit-empty": {
            +      "version": "0.3.6",
            +      "resolved": "https://registry.npmjs.org/omit-empty/-/omit-empty-0.3.6.tgz",
            +      "integrity": "sha1-bThAXyqmHJEetQT+aIBcVm2FwxY=",
            +      "dev": true,
            +      "dependencies": {
            +        "has-values": "^0.1.4",
            +        "is-date-object": "^1.0.1",
            +        "isobject": "^2.0.0",
            +        "reduce-object": "^0.1.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/question-cache/node_modules/set-value": {
            +      "version": "0.3.3",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.3.3.tgz",
            +      "integrity": "sha1-uBIjaBY4oQiP2IpDW4qdMtro2bo=",
            +      "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "isobject": "^2.0.0",
            +        "to-object-path": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/set-value": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-3.0.2.tgz",
            +      "integrity": "sha512-npjkVoz+ank0zjlV9F47Fdbjfj/PfXyVhZvGALWsyIYU/qrMzpi6avjKW3/7KeSU2Df3I46BrN1xOI1+6vW0hA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-object": "^2.0.4"
            +      },
            +      "engines": {
            +        "node": ">=6.0"
            +      }
            +    },
            +    "node_modules/common-config/node_modules/to-object-path": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.2.0.tgz",
            +      "integrity": "sha1-FjThtSqIugDjlJYZ/ACB3Jo7B8o=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "is-arguments": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/component-emitter": {
            +      "version": "1.2.1",
            +      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
            +      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
            +      "dev": true
            +    },
            +    "node_modules/composer": {
            +      "version": "0.14.2",
            +      "resolved": "https://registry.npmjs.org/composer/-/composer-0.14.2.tgz",
            +      "integrity": "sha1-ex11489plXnQKj6RX+XQvv6Yuac=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-unique": "^0.3.2",
            +        "bach": "^1.1.0",
            +        "co": "^4.6.0",
            +        "component-emitter": "^1.2.1",
            +        "define-property": "^1.0.0",
            +        "extend-shallow": "^2.0.1",
            +        "is-generator": "^1.0.3",
            +        "is-glob": "^3.1.0",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.2",
            +        "micromatch": "^2.3.11",
            +        "nanoseconds": "^0.1.0",
            +        "pretty-time": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/composer/node_modules/array-unique": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
            +      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/composer/node_modules/define-property": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
            +      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/composer/node_modules/is-accessor-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/composer/node_modules/is-data-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/composer/node_modules/is-descriptor": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
            +      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^1.0.0",
            +        "is-data-descriptor": "^1.0.0",
            +        "kind-of": "^6.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/composer/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/compress-commons": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz",
            +      "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=",
            +      "dev": true,
            +      "dependencies": {
            +        "buffer-crc32": "^0.2.1",
            +        "crc32-stream": "^2.0.0",
            +        "normalize-path": "^2.0.0",
            +        "readable-stream": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/compressible": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/compressible/-/compressible-1.0.0.tgz",
            +      "integrity": "sha1-+D5JwcthQhdTVFElqAEdaLSSQn0=",
            +      "dev": true
            +    },
            +    "node_modules/concat-map": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
            +      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
            +      "dev": true
            +    },
            +    "node_modules/concat-stream": {
            +      "version": "1.6.2",
            +      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
            +      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
            +      "dev": true,
            +      "engines": [
            +        "node >= 0.8"
            +      ],
            +      "dependencies": {
            +        "buffer-from": "^1.0.0",
            +        "inherits": "^2.0.3",
            +        "readable-stream": "^2.2.2",
            +        "typedarray": "^0.0.6"
            +      }
            +    },
            +    "node_modules/concat-with-sourcemaps": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz",
            +      "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==",
            +      "dev": true,
            +      "dependencies": {
            +        "source-map": "^0.6.1"
            +      }
            +    },
            +    "node_modules/config-chain": {
            +      "version": "1.1.12",
            +      "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
            +      "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
            +      "dev": true,
            +      "dependencies": {
            +        "ini": "^1.3.4",
            +        "proto-list": "~1.2.1"
            +      }
            +    },
            +    "node_modules/connect": {
            +      "version": "3.7.0",
            +      "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
            +      "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "2.6.9",
            +        "finalhandler": "1.1.2",
            +        "parseurl": "~1.3.3",
            +        "utils-merge": "1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/connect-livereload": {
            +      "version": "0.6.1",
            +      "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.6.1.tgz",
            +      "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/console-control-strings": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
            +      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/console-stream": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/console-stream/-/console-stream-0.1.1.tgz",
            +      "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=",
            +      "dev": true
            +    },
            +    "node_modules/content-disposition": {
            +      "version": "0.5.3",
            +      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
            +      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
            +      "dev": true,
            +      "dependencies": {
            +        "safe-buffer": "5.1.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/continuable-cache": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz",
            +      "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=",
            +      "dev": true
            +    },
            +    "node_modules/convert-source-map": {
            +      "version": "1.7.0",
            +      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
            +      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
            +      "dev": true,
            +      "dependencies": {
            +        "safe-buffer": "~5.1.1"
            +      }
            +    },
            +    "node_modules/cookie": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz",
            +      "integrity": "sha1-kOtGndzpBchm3mh+/EMTHYgB+dA=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/cookie-signature": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.1.tgz",
            +      "integrity": "sha1-ROByFIrwHm6OJK+/EmkNaK5pjss=",
            +      "dev": true
            +    },
            +    "node_modules/copy-descriptor": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
            +      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/core-util-is": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
            +      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
            +      "dev": true
            +    },
            +    "node_modules/cosmiconfig": {
            +      "version": "5.2.1",
            +      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
            +      "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
            +      "dev": true,
            +      "dependencies": {
            +        "import-fresh": "^2.0.0",
            +        "is-directory": "^0.3.1",
            +        "js-yaml": "^3.13.1",
            +        "parse-json": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cosmiconfig/node_modules/parse-json": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
            +      "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
            +      "dev": true,
            +      "dependencies": {
            +        "error-ex": "^1.3.1",
            +        "json-parse-better-errors": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/crc": {
            +      "version": "3.8.0",
            +      "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
            +      "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "buffer": "^5.1.0"
            +      }
            +    },
            +    "node_modules/crc32-stream": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz",
            +      "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "crc": "^3.4.4",
            +        "readable-stream": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/create-frame": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/create-frame/-/create-frame-1.0.0.tgz",
            +      "integrity": "sha1-i5XyaR4ySbYIBEPjPQutn49pdao=",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cross-spawn": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
            +      "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
            +      "dev": true,
            +      "dependencies": {
            +        "lru-cache": "^4.0.1",
            +        "shebang-command": "^1.2.0",
            +        "which": "^1.2.9"
            +      }
            +    },
            +    "node_modules/css-color-names": {
            +      "version": "0.0.4",
            +      "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
            +      "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/css-declaration-sorter": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz",
            +      "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.1",
            +        "timsort": "^0.3.0"
            +      },
            +      "engines": {
            +        "node": ">4"
            +      }
            +    },
            +    "node_modules/css-declaration-sorter/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/css-declaration-sorter/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/css-declaration-sorter/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/css-declaration-sorter/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/css-declaration-sorter/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/css-declaration-sorter/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/css-select": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
            +      "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "boolbase": "^1.0.0",
            +        "css-what": "^3.2.1",
            +        "domutils": "^1.7.0",
            +        "nth-check": "^1.0.2"
            +      }
            +    },
            +    "node_modules/css-select-base-adapter": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
            +      "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
            +      "dev": true
            +    },
            +    "node_modules/css-tree": {
            +      "version": "1.0.0-alpha.37",
            +      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
            +      "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==",
            +      "dev": true,
            +      "dependencies": {
            +        "mdn-data": "2.0.4",
            +        "source-map": "^0.6.1"
            +      },
            +      "engines": {
            +        "node": ">=8.0.0"
            +      }
            +    },
            +    "node_modules/css-what": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz",
            +      "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 6"
            +      }
            +    },
            +    "node_modules/cssesc": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
            +      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
            +      "dev": true,
            +      "bin": {
            +        "cssesc": "bin/cssesc"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano": {
            +      "version": "4.1.11",
            +      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz",
            +      "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==",
            +      "dev": true,
            +      "dependencies": {
            +        "cosmiconfig": "^5.0.0",
            +        "cssnano-preset-default": "^4.0.8",
            +        "is-resolvable": "^1.0.0",
            +        "postcss": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/cssnano-preset-default": {
            +      "version": "4.0.8",
            +      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz",
            +      "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "css-declaration-sorter": "^4.0.1",
            +        "cssnano-util-raw-cache": "^4.0.1",
            +        "postcss": "^7.0.0",
            +        "postcss-calc": "^7.0.1",
            +        "postcss-colormin": "^4.0.3",
            +        "postcss-convert-values": "^4.0.1",
            +        "postcss-discard-comments": "^4.0.2",
            +        "postcss-discard-duplicates": "^4.0.2",
            +        "postcss-discard-empty": "^4.0.1",
            +        "postcss-discard-overridden": "^4.0.1",
            +        "postcss-merge-longhand": "^4.0.11",
            +        "postcss-merge-rules": "^4.0.3",
            +        "postcss-minify-font-values": "^4.0.2",
            +        "postcss-minify-gradients": "^4.0.2",
            +        "postcss-minify-params": "^4.0.2",
            +        "postcss-minify-selectors": "^4.0.2",
            +        "postcss-normalize-charset": "^4.0.1",
            +        "postcss-normalize-display-values": "^4.0.2",
            +        "postcss-normalize-positions": "^4.0.2",
            +        "postcss-normalize-repeat-style": "^4.0.2",
            +        "postcss-normalize-string": "^4.0.2",
            +        "postcss-normalize-timing-functions": "^4.0.2",
            +        "postcss-normalize-unicode": "^4.0.1",
            +        "postcss-normalize-url": "^4.0.1",
            +        "postcss-normalize-whitespace": "^4.0.2",
            +        "postcss-ordered-values": "^4.1.2",
            +        "postcss-reduce-initial": "^4.0.3",
            +        "postcss-reduce-transforms": "^4.0.2",
            +        "postcss-svgo": "^4.0.3",
            +        "postcss-unique-selectors": "^4.0.1"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/cssnano-preset-default/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano-preset-default/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano-preset-default/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano-preset-default/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano-preset-default/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/cssnano-preset-default/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/cssnano-util-get-arguments": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz",
            +      "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/cssnano-util-get-match": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz",
            +      "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/cssnano-util-raw-cache": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz",
            +      "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/cssnano-util-raw-cache/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano-util-raw-cache/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano-util-raw-cache/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano-util-raw-cache/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano-util-raw-cache/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/cssnano-util-raw-cache/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/cssnano-util-same-parent": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz",
            +      "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/cssnano/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/cssnano/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/cssnano/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/csso": {
            +      "version": "4.2.0",
            +      "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
            +      "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
            +      "dev": true,
            +      "dependencies": {
            +        "css-tree": "^1.1.2"
            +      },
            +      "engines": {
            +        "node": ">=8.0.0"
            +      }
            +    },
            +    "node_modules/csso/node_modules/css-tree": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
            +      "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "mdn-data": "2.0.14",
            +        "source-map": "^0.6.1"
            +      },
            +      "engines": {
            +        "node": ">=8.0.0"
            +      }
            +    },
            +    "node_modules/csso/node_modules/mdn-data": {
            +      "version": "2.0.14",
            +      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
            +      "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
            +      "dev": true
            +    },
            +    "node_modules/cssom": {
            +      "version": "0.3.8",
            +      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
            +      "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
            +      "dev": true
            +    },
            +    "node_modules/cssstyle": {
            +      "version": "1.4.0",
            +      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz",
            +      "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
            +      "dev": true,
            +      "dependencies": {
            +        "cssom": "0.3.x"
            +      }
            +    },
            +    "node_modules/currently-unhandled": {
            +      "version": "0.4.1",
            +      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
            +      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-find-index": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/cwd": {
            +      "version": "0.9.1",
            +      "resolved": "https://registry.npmjs.org/cwd/-/cwd-0.9.1.tgz",
            +      "integrity": "sha1-QeEKfhq4M9xZwuyoOBTH3ne1pP0=",
            +      "dev": true,
            +      "dependencies": {
            +        "find-pkg": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/dashdash": {
            +      "version": "1.14.1",
            +      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
            +      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
            +      "dev": true,
            +      "dependencies": {
            +        "assert-plus": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10"
            +      }
            +    },
            +    "node_modules/data-store": {
            +      "version": "0.16.1",
            +      "resolved": "https://registry.npmjs.org/data-store/-/data-store-0.16.1.tgz",
            +      "integrity": "sha1-5pwDpcrBXR/zPwJUyWeDZT5ogwQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "cache-base": "^0.8.4",
            +        "clone-deep": "^0.2.4",
            +        "debug": "^2.2.0",
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "graceful-fs": "^4.1.4",
            +        "has-own-deep": "^0.1.4",
            +        "lazy-cache": "^2.0.1",
            +        "mkdirp": "^0.5.1",
            +        "project-name": "^0.2.5",
            +        "resolve-dir": "^0.1.0",
            +        "rimraf": "^2.5.3",
            +        "union-value": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/cache-base": {
            +      "version": "0.8.5",
            +      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-0.8.5.tgz",
            +      "integrity": "sha1-YM6zUEAh7O7HAR/TOEt/TpVym/o=",
            +      "dev": true,
            +      "dependencies": {
            +        "collection-visit": "^0.2.1",
            +        "component-emitter": "^1.2.1",
            +        "get-value": "^2.0.5",
            +        "has-value": "^0.3.1",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.1",
            +        "set-value": "^0.4.2",
            +        "to-object-path": "^0.3.0",
            +        "union-value": "^0.2.3",
            +        "unset-value": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/collection-visit": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-0.2.3.tgz",
            +      "integrity": "sha1-L2JIPK7MlfCDuaRUo+6eYTmteVc=",
            +      "dev": true,
            +      "dependencies": {
            +        "lazy-cache": "^2.0.1",
            +        "map-visit": "^0.1.5",
            +        "object-visit": "^0.3.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/expand-tilde": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
            +      "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
            +      "dev": true,
            +      "dependencies": {
            +        "os-homedir": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/map-visit": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-0.1.5.tgz",
            +      "integrity": "sha1-2+Q5J85VJbgN/BVzpE1oxR8mgWs=",
            +      "dev": true,
            +      "dependencies": {
            +        "lazy-cache": "^2.0.1",
            +        "object-visit": "^0.3.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/object-visit": {
            +      "version": "0.3.4",
            +      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-0.3.4.tgz",
            +      "integrity": "sha1-rhXPhvCy/dVRdxY2RIRSxUw9qCk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/object-visit/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/resolve-dir": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
            +      "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^1.2.2",
            +        "global-modules": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/union-value": {
            +      "version": "0.2.4",
            +      "resolved": "https://registry.npmjs.org/union-value/-/union-value-0.2.4.tgz",
            +      "integrity": "sha1-c3UVJ4ZnkFfns3qmdug0aPwCdPA=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "get-value": "^2.0.6",
            +        "is-extendable": "^0.1.1",
            +        "set-value": "^0.4.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-store/node_modules/unset-value": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz",
            +      "integrity": "sha1-UGgQuGfyfCpabpsEgzYx9t5Y0xA=",
            +      "dev": true,
            +      "dependencies": {
            +        "has-value": "^0.3.1",
            +        "isobject": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/data-urls": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
            +      "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "abab": "^2.0.0",
            +        "whatwg-mimetype": "^2.2.0",
            +        "whatwg-url": "^7.0.0"
            +      }
            +    },
            +    "node_modules/data-urls/node_modules/whatwg-url": {
            +      "version": "7.1.0",
            +      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
            +      "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash.sortby": "^4.7.0",
            +        "tr46": "^1.0.1",
            +        "webidl-conversions": "^4.0.2"
            +      }
            +    },
            +    "node_modules/date-fns": {
            +      "version": "1.30.1",
            +      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
            +      "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
            +      "dev": true
            +    },
            +    "node_modules/date-time": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/date-time/-/date-time-1.1.0.tgz",
            +      "integrity": "sha1-GIdtC9pMGf5w3Tv0sDTygbEqQLY=",
            +      "dev": true,
            +      "dependencies": {
            +        "time-zone": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/date.js": {
            +      "version": "0.3.3",
            +      "resolved": "https://registry.npmjs.org/date.js/-/date.js-0.3.3.tgz",
            +      "integrity": "sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw==",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "~3.1.0"
            +      }
            +    },
            +    "node_modules/date.js/node_modules/debug": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
            +      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
            +      "dev": true,
            +      "dependencies": {
            +        "ms": "2.0.0"
            +      }
            +    },
            +    "node_modules/date.js/node_modules/ms": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
            +      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
            +      "dev": true
            +    },
            +    "node_modules/dateformat": {
            +      "version": "3.0.3",
            +      "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
            +      "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/debug": {
            +      "version": "2.6.9",
            +      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
            +      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
            +      "dev": true,
            +      "dependencies": {
            +        "ms": "2.0.0"
            +      }
            +    },
            +    "node_modules/debug/node_modules/ms": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
            +      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
            +      "dev": true
            +    },
            +    "node_modules/decamelize": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
            +      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/decode-uri-component": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
            +      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10"
            +      }
            +    },
            +    "node_modules/decompress": {
            +      "version": "4.2.1",
            +      "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz",
            +      "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "decompress-tar": "^4.0.0",
            +        "decompress-tarbz2": "^4.0.0",
            +        "decompress-targz": "^4.0.0",
            +        "decompress-unzip": "^4.0.1",
            +        "graceful-fs": "^4.1.10",
            +        "make-dir": "^1.0.0",
            +        "pify": "^2.3.0",
            +        "strip-dirs": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/decompress-response": {
            +      "version": "3.3.0",
            +      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
            +      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
            +      "dev": true,
            +      "dependencies": {
            +        "mimic-response": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/decompress-tar": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
            +      "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "file-type": "^5.2.0",
            +        "is-stream": "^1.1.0",
            +        "tar-stream": "^1.5.2"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/decompress-tar/node_modules/file-type": {
            +      "version": "5.2.0",
            +      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
            +      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/decompress-tarbz2": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
            +      "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
            +      "dev": true,
            +      "dependencies": {
            +        "decompress-tar": "^4.1.0",
            +        "file-type": "^6.1.0",
            +        "is-stream": "^1.1.0",
            +        "seek-bzip": "^1.0.5",
            +        "unbzip2-stream": "^1.0.9"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/decompress-tarbz2/node_modules/file-type": {
            +      "version": "6.2.0",
            +      "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
            +      "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/decompress-targz": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
            +      "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
            +      "dev": true,
            +      "dependencies": {
            +        "decompress-tar": "^4.1.1",
            +        "file-type": "^5.2.0",
            +        "is-stream": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/decompress-targz/node_modules/file-type": {
            +      "version": "5.2.0",
            +      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
            +      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/decompress-unzip": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
            +      "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=",
            +      "dev": true,
            +      "dependencies": {
            +        "file-type": "^3.8.0",
            +        "get-stream": "^2.2.0",
            +        "pify": "^2.3.0",
            +        "yauzl": "^2.4.2"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/decompress-unzip/node_modules/file-type": {
            +      "version": "3.9.0",
            +      "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
            +      "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/decompress-unzip/node_modules/get-stream": {
            +      "version": "2.3.1",
            +      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
            +      "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=",
            +      "dev": true,
            +      "dependencies": {
            +        "object-assign": "^4.0.1",
            +        "pinkie-promise": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/dedent": {
            +      "version": "0.7.0",
            +      "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
            +      "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
            +      "dev": true
            +    },
            +    "node_modules/deep-bind": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/deep-bind/-/deep-bind-0.3.0.tgz",
            +      "integrity": "sha1-lcMd2Eoc0bOBEZosQu25DbSFvDM=",
            +      "dev": true,
            +      "dependencies": {
            +        "mixin-deep": "^1.1.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/deep-extend": {
            +      "version": "0.6.0",
            +      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
            +      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
            +      "dev": true,
            +      "optional": true,
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/deep-is": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
            +      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
            +      "dev": true
            +    },
            +    "node_modules/default-compare": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
            +      "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^5.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/defaults-deep": {
            +      "version": "0.2.4",
            +      "resolved": "https://registry.npmjs.org/defaults-deep/-/defaults-deep-0.2.4.tgz",
            +      "integrity": "sha512-V6BtqzcMvn0EPOy7f+SfMhfmTawq+7UQdt9yZH0EBK89+IHo5f+Hse/qzTorAXOBrQpxpwb6cB/8OgtaMrT+Fg==",
            +      "dev": true,
            +      "dependencies": {
            +        "for-own": "^0.1.3",
            +        "is-extendable": "^0.1.1",
            +        "lazy-cache": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/defaults-deep/node_modules/lazy-cache": {
            +      "version": "0.2.7",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
            +      "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/define-properties": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
            +      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "object-keys": "^1.0.12"
            +      },
            +      "engines": {
            +        "node": ">= 0.4"
            +      }
            +    },
            +    "node_modules/define-property": {
            +      "version": "0.2.5",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
            +      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/del": {
            +      "version": "2.2.2",
            +      "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
            +      "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
            +      "dev": true,
            +      "dependencies": {
            +        "globby": "^5.0.0",
            +        "is-path-cwd": "^1.0.0",
            +        "is-path-in-cwd": "^1.0.0",
            +        "object-assign": "^4.0.1",
            +        "pify": "^2.0.0",
            +        "pinkie-promise": "^2.0.0",
            +        "rimraf": "^2.2.8"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/delayed-stream": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
            +      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/delegates": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
            +      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/delimiter-regex": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/delimiter-regex/-/delimiter-regex-2.0.0.tgz",
            +      "integrity": "sha1-DQ9vYdmRVZH9Qwh6jpWF0+IRWnU=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^1.1.2",
            +        "isobject": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/delimiter-regex/node_modules/extend-shallow": {
            +      "version": "1.1.4",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
            +      "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/delimiter-regex/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/delimiter-regex/node_modules/kind-of": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
            +      "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/delims": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/delims/-/delims-0.1.4.tgz",
            +      "integrity": "sha1-If6EbxakBWr4caZIYaHhYPGgQfc=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash": "~2.4.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/delims/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/depd": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
            +      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/destroy": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
            +      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
            +      "dev": true
            +    },
            +    "node_modules/detect-file": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
            +      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/detect-libc": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
            +      "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
            +      "dev": true,
            +      "optional": true,
            +      "bin": {
            +        "detect-libc": "bin/detect-libc.js"
            +      },
            +      "engines": {
            +        "node": ">=0.10"
            +      }
            +    },
            +    "node_modules/diff": {
            +      "version": "3.5.0",
            +      "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
            +      "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.3.1"
            +      }
            +    },
            +    "node_modules/digits": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/digits/-/digits-0.1.4.tgz",
            +      "integrity": "sha1-Uw8Tp3A1CLoCbBZagvDmiwojGIw=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/dir-glob": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz",
            +      "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==",
            +      "dev": true,
            +      "dependencies": {
            +        "arrify": "^1.0.1",
            +        "path-type": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/dir-glob/node_modules/path-type": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
            +      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
            +      "dev": true,
            +      "dependencies": {
            +        "pify": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/dir-glob/node_modules/pify": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
            +      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/doctrine": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
            +      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
            +      "dev": true,
            +      "dependencies": {
            +        "esutils": "^2.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/dom-serializer": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
            +      "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
            +      "dev": true,
            +      "dependencies": {
            +        "domelementtype": "^2.0.1",
            +        "entities": "^2.0.0"
            +      }
            +    },
            +    "node_modules/dom-serializer/node_modules/domelementtype": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
            +      "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
            +      "dev": true
            +    },
            +    "node_modules/domelementtype": {
            +      "version": "1.3.1",
            +      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
            +      "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
            +      "dev": true
            +    },
            +    "node_modules/domexception": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
            +      "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
            +      "dev": true,
            +      "dependencies": {
            +        "webidl-conversions": "^4.0.2"
            +      }
            +    },
            +    "node_modules/domutils": {
            +      "version": "1.7.0",
            +      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
            +      "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
            +      "dev": true,
            +      "dependencies": {
            +        "dom-serializer": "0",
            +        "domelementtype": "1"
            +      }
            +    },
            +    "node_modules/dot": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/dot/-/dot-1.0.3.tgz",
            +      "integrity": "sha1-+HUL+2sDx2ZOsObLHrTGZBmvlCc=",
            +      "dev": true,
            +      "engines": [
            +        "node >=0.2.6"
            +      ],
            +      "bin": {
            +        "dottojs": "bin/dot-packer"
            +      }
            +    },
            +    "node_modules/dot-prop": {
            +      "version": "5.3.0",
            +      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
            +      "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-obj": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/dot-prop/node_modules/is-obj": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
            +      "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/download": {
            +      "version": "6.2.5",
            +      "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz",
            +      "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==",
            +      "dev": true,
            +      "dependencies": {
            +        "caw": "^2.0.0",
            +        "content-disposition": "^0.5.2",
            +        "decompress": "^4.0.0",
            +        "ext-name": "^5.0.0",
            +        "file-type": "5.2.0",
            +        "filenamify": "^2.0.0",
            +        "get-stream": "^3.0.0",
            +        "got": "^7.0.0",
            +        "make-dir": "^1.0.0",
            +        "p-event": "^1.0.0",
            +        "pify": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/download/node_modules/file-type": {
            +      "version": "5.2.0",
            +      "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
            +      "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/download/node_modules/pify": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
            +      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/duplexer": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
            +      "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
            +      "dev": true
            +    },
            +    "node_modules/duplexer3": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
            +      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
            +      "dev": true
            +    },
            +    "node_modules/duplexify": {
            +      "version": "3.6.0",
            +      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz",
            +      "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "end-of-stream": "^1.0.0",
            +        "inherits": "^2.0.1",
            +        "readable-stream": "^2.0.0",
            +        "stream-shift": "^1.0.0"
            +      }
            +    },
            +    "node_modules/ecc-jsbn": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
            +      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
            +      "dev": true,
            +      "dependencies": {
            +        "jsbn": "~0.1.0",
            +        "safer-buffer": "^2.1.0"
            +      }
            +    },
            +    "node_modules/ejs": {
            +      "version": "2.7.4",
            +      "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz",
            +      "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==",
            +      "dev": true,
            +      "hasInstallScript": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/electron-to-chromium": {
            +      "version": "1.3.52",
            +      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.52.tgz",
            +      "integrity": "sha1-0tnxJwuko7lnuDHEDvcftNmrXOA=",
            +      "dev": true
            +    },
            +    "node_modules/elegant-spinner": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
            +      "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/empty-dir": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/empty-dir/-/empty-dir-0.2.1.tgz",
            +      "integrity": "sha1-gJ7kih60rRy1EMJXLWb9DthNAas=",
            +      "dev": true,
            +      "dependencies": {
            +        "fs-exists-sync": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/en-route": {
            +      "version": "0.7.5",
            +      "resolved": "https://registry.npmjs.org/en-route/-/en-route-0.7.5.tgz",
            +      "integrity": "sha1-6CMOc4NsXpXGdX4EQtPBExJL3Zg=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "debug": "^2.2.0",
            +        "extend-shallow": "^2.0.1",
            +        "kind-of": "^3.0.2",
            +        "lazy-cache": "^1.0.3",
            +        "path-to-regexp": "^1.2.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/en-route/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/en-route/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/encodeurl": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
            +      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8"
            +      }
            +    },
            +    "node_modules/end-of-stream": {
            +      "version": "1.4.1",
            +      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
            +      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "once": "^1.4.0"
            +      }
            +    },
            +    "node_modules/engine": {
            +      "version": "0.1.12",
            +      "resolved": "https://registry.npmjs.org/engine/-/engine-0.1.12.tgz",
            +      "integrity": "sha1-+H6MkLuAzT9YWXrFaVk+5G2idC0=",
            +      "dev": true,
            +      "dependencies": {
            +        "assign-deep": "^0.4.3",
            +        "collection-visit": "^0.2.0",
            +        "get-value": "^1.2.1",
            +        "kind-of": "^2.0.1",
            +        "lazy-cache": "^0.2.3",
            +        "object.omit": "^2.0.0",
            +        "set-value": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine-base": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/engine-base/-/engine-base-0.1.3.tgz",
            +      "integrity": "sha1-1ZycxS591t0rSa579ftEmU9wFqU=",
            +      "dev": true,
            +      "dependencies": {
            +        "component-emitter": "^1.2.1",
            +        "delimiter-regex": "^2.0.0",
            +        "engine": "^0.1.12",
            +        "engine-utils": "^0.1.1",
            +        "lazy-cache": "^2.0.2",
            +        "mixin-deep": "^1.1.3",
            +        "object.omit": "^2.0.1",
            +        "object.pick": "^1.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine-cache": {
            +      "version": "0.19.4",
            +      "resolved": "https://registry.npmjs.org/engine-cache/-/engine-cache-0.19.4.tgz",
            +      "integrity": "sha1-giSWb732pl54Dsed+HtrLLgjlbI=",
            +      "dev": true,
            +      "dependencies": {
            +        "async-helpers": "^0.3.9",
            +        "extend-shallow": "^2.0.1",
            +        "helper-cache": "^0.7.2",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.2",
            +        "mixin-deep": "^1.1.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine-handlebars": {
            +      "version": "0.8.2",
            +      "resolved": "https://registry.npmjs.org/engine-handlebars/-/engine-handlebars-0.8.2.tgz",
            +      "integrity": "sha1-qnCdhpSdNTMaFdZQAj2cvkIVqfk=",
            +      "dev": true,
            +      "dependencies": {
            +        "engine-utils": "^0.1.1",
            +        "extend-shallow": "^2.0.1",
            +        "handlebars": "^4.0.6"
            +      },
            +      "engines": {
            +        "node": ">=4.7"
            +      }
            +    },
            +    "node_modules/engine-utils": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/engine-utils/-/engine-utils-0.1.1.tgz",
            +      "integrity": "sha1-rd9HCN2FoFoyF6l3l+q4oBPE+A4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/collection-visit": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-0.2.3.tgz",
            +      "integrity": "sha1-L2JIPK7MlfCDuaRUo+6eYTmteVc=",
            +      "dev": true,
            +      "dependencies": {
            +        "lazy-cache": "^2.0.1",
            +        "map-visit": "^0.1.5",
            +        "object-visit": "^0.3.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/collection-visit/node_modules/lazy-cache": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
            +      "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "set-getter": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/get-value": {
            +      "version": "1.3.1",
            +      "resolved": "https://registry.npmjs.org/get-value/-/get-value-1.3.1.tgz",
            +      "integrity": "sha1-isfvTyA4I5KyZGVI+bmtLcbIlkI=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "is-extendable": "^0.1.1",
            +        "lazy-cache": "^0.2.4",
            +        "noncharacters": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/kind-of": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz",
            +      "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/lazy-cache": {
            +      "version": "0.2.7",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
            +      "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/map-visit": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-0.1.5.tgz",
            +      "integrity": "sha1-2+Q5J85VJbgN/BVzpE1oxR8mgWs=",
            +      "dev": true,
            +      "dependencies": {
            +        "lazy-cache": "^2.0.1",
            +        "object-visit": "^0.3.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/map-visit/node_modules/lazy-cache": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
            +      "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "set-getter": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/object-visit": {
            +      "version": "0.3.4",
            +      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-0.3.4.tgz",
            +      "integrity": "sha1-rhXPhvCy/dVRdxY2RIRSxUw9qCk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/set-value": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.2.0.tgz",
            +      "integrity": "sha1-c7CmglwVjGoWqCu9yVd1vyqCX6s=",
            +      "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^1.0.0",
            +        "noncharacters": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/engine/node_modules/set-value/node_modules/isobject": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-1.0.2.tgz",
            +      "integrity": "sha1-8Pm4zpLdVA+gdAiC44NaLgIux4o=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ent": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
            +      "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
            +      "dev": true
            +    },
            +    "node_modules/entities": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
            +      "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==",
            +      "dev": true
            +    },
            +    "node_modules/error": {
            +      "version": "7.2.1",
            +      "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz",
            +      "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==",
            +      "dev": true,
            +      "dependencies": {
            +        "string-template": "~0.2.1"
            +      }
            +    },
            +    "node_modules/error-ex": {
            +      "version": "1.3.2",
            +      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
            +      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-arrayish": "^0.2.1"
            +      }
            +    },
            +    "node_modules/error-symbol": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/error-symbol/-/error-symbol-0.1.0.tgz",
            +      "integrity": "sha1-Ck2uN9YA0VopukU9jvkg8YRDM/Y=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/es-abstract": {
            +      "version": "1.17.0",
            +      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.0.tgz",
            +      "integrity": "sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==",
            +      "dev": true,
            +      "dependencies": {
            +        "es-to-primitive": "^1.2.1",
            +        "function-bind": "^1.1.1",
            +        "has": "^1.0.3",
            +        "has-symbols": "^1.0.1",
            +        "is-callable": "^1.1.5",
            +        "is-regex": "^1.0.5",
            +        "object-inspect": "^1.7.0",
            +        "object-keys": "^1.1.1",
            +        "object.assign": "^4.1.0",
            +        "string.prototype.trimleft": "^2.1.1",
            +        "string.prototype.trimright": "^2.1.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.4"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/es-to-primitive": {
            +      "version": "1.2.1",
            +      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
            +      "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-callable": "^1.1.4",
            +        "is-date-object": "^1.0.1",
            +        "is-symbol": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.4"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/escalade": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
            +      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/escape-html": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
            +      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
            +      "dev": true
            +    },
            +    "node_modules/escape-string-regexp": {
            +      "version": "1.0.5",
            +      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
            +      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/escodegen": {
            +      "version": "1.14.1",
            +      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz",
            +      "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "esprima": "^4.0.1",
            +        "estraverse": "^4.2.0",
            +        "esutils": "^2.0.2",
            +        "optionator": "^0.8.1"
            +      },
            +      "bin": {
            +        "escodegen": "bin/escodegen.js",
            +        "esgenerate": "bin/esgenerate.js"
            +      },
            +      "engines": {
            +        "node": ">=4.0"
            +      },
            +      "optionalDependencies": {
            +        "source-map": "~0.6.1"
            +      }
            +    },
            +    "node_modules/eslint": {
            +      "version": "4.19.1",
            +      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
            +      "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ajv": "^5.3.0",
            +        "babel-code-frame": "^6.22.0",
            +        "chalk": "^2.1.0",
            +        "concat-stream": "^1.6.0",
            +        "cross-spawn": "^5.1.0",
            +        "debug": "^3.1.0",
            +        "doctrine": "^2.1.0",
            +        "eslint-scope": "^3.7.1",
            +        "eslint-visitor-keys": "^1.0.0",
            +        "espree": "^3.5.4",
            +        "esquery": "^1.0.0",
            +        "esutils": "^2.0.2",
            +        "file-entry-cache": "^2.0.0",
            +        "functional-red-black-tree": "^1.0.1",
            +        "glob": "^7.1.2",
            +        "globals": "^11.0.1",
            +        "ignore": "^3.3.3",
            +        "imurmurhash": "^0.1.4",
            +        "inquirer": "^3.0.6",
            +        "is-resolvable": "^1.0.0",
            +        "js-yaml": "^3.9.1",
            +        "json-stable-stringify-without-jsonify": "^1.0.1",
            +        "levn": "^0.3.0",
            +        "lodash": "^4.17.4",
            +        "minimatch": "^3.0.2",
            +        "mkdirp": "^0.5.1",
            +        "natural-compare": "^1.4.0",
            +        "optionator": "^0.8.2",
            +        "path-is-inside": "^1.0.2",
            +        "pluralize": "^7.0.0",
            +        "progress": "^2.0.0",
            +        "regexpp": "^1.0.1",
            +        "require-uncached": "^1.0.3",
            +        "semver": "^5.3.0",
            +        "strip-ansi": "^4.0.0",
            +        "strip-json-comments": "~2.0.1",
            +        "table": "4.0.2",
            +        "text-table": "~0.2.0"
            +      },
            +      "bin": {
            +        "eslint": "bin/eslint.js"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/eslint-config-prettier": {
            +      "version": "2.10.0",
            +      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-2.10.0.tgz",
            +      "integrity": "sha512-Mhl90VLucfBuhmcWBgbUNtgBiK955iCDK1+aHAz7QfDQF6wuzWZ6JjihZ3ejJoGlJWIuko7xLqNm8BA5uenKhA==",
            +      "dev": true,
            +      "dependencies": {
            +        "get-stdin": "^5.0.1"
            +      },
            +      "bin": {
            +        "eslint-config-prettier-check": "bin/cli.js"
            +      },
            +      "peerDependencies": {
            +        "eslint": ">=3.14.1"
            +      }
            +    },
            +    "node_modules/eslint-plugin-prettier": {
            +      "version": "2.7.0",
            +      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz",
            +      "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fast-diff": "^1.1.1",
            +        "jest-docblock": "^21.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0.0"
            +      },
            +      "peerDependencies": {
            +        "prettier": ">= 0.11.0"
            +      }
            +    },
            +    "node_modules/eslint-scope": {
            +      "version": "3.7.3",
            +      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz",
            +      "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==",
            +      "dev": true,
            +      "dependencies": {
            +        "esrecurse": "^4.1.0",
            +        "estraverse": "^4.1.1"
            +      },
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/eslint-visitor-keys": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
            +      "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/eslint/node_modules/ansi-regex": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
            +      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/eslint/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/eslint/node_modules/chalk": {
            +      "version": "2.4.1",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
            +      "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/eslint/node_modules/debug": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
            +      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
            +      "dev": true,
            +      "dependencies": {
            +        "ms": "2.0.0"
            +      }
            +    },
            +    "node_modules/eslint/node_modules/glob": {
            +      "version": "7.1.2",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
            +      "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/eslint/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/eslint/node_modules/ms": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
            +      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
            +      "dev": true
            +    },
            +    "node_modules/eslint/node_modules/strip-ansi": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
            +      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-regex": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/eslint/node_modules/supports-color": {
            +      "version": "5.4.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
            +      "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/espree": {
            +      "version": "3.5.4",
            +      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
            +      "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
            +      "dev": true,
            +      "dependencies": {
            +        "acorn": "^5.5.0",
            +        "acorn-jsx": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/esprima": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
            +      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
            +      "dev": true,
            +      "bin": {
            +        "esparse": "bin/esparse.js",
            +        "esvalidate": "bin/esvalidate.js"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/esquery": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
            +      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
            +      "dev": true,
            +      "dependencies": {
            +        "estraverse": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.6"
            +      }
            +    },
            +    "node_modules/esrecurse": {
            +      "version": "4.2.1",
            +      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
            +      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "estraverse": "^4.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0"
            +      }
            +    },
            +    "node_modules/estraverse": {
            +      "version": "4.2.0",
            +      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
            +      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/esutils": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
            +      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/etag": {
            +      "version": "1.8.1",
            +      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
            +      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/eventemitter2": {
            +      "version": "0.4.14",
            +      "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
            +      "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
            +      "dev": true
            +    },
            +    "node_modules/events": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
            +      "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.x"
            +      }
            +    },
            +    "node_modules/exec-buffer": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz",
            +      "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "execa": "^0.7.0",
            +        "p-finally": "^1.0.0",
            +        "pify": "^3.0.0",
            +        "rimraf": "^2.5.4",
            +        "tempfile": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/exec-buffer/node_modules/pify": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
            +      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
            +      "dev": true,
            +      "optional": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/execa": {
            +      "version": "0.7.0",
            +      "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
            +      "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
            +      "dev": true,
            +      "dependencies": {
            +        "cross-spawn": "^5.0.1",
            +        "get-stream": "^3.0.0",
            +        "is-stream": "^1.1.0",
            +        "npm-run-path": "^2.0.0",
            +        "p-finally": "^1.0.0",
            +        "signal-exit": "^3.0.0",
            +        "strip-eof": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/executable": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz",
            +      "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==",
            +      "dev": true,
            +      "dependencies": {
            +        "pify": "^2.2.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/exit": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
            +      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/exit-hook": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
            +      "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand": {
            +      "version": "0.4.3",
            +      "resolved": "https://registry.npmjs.org/expand/-/expand-0.4.3.tgz",
            +      "integrity": "sha1-0HawaUWkGp3h9+FRsiVMtz6IXVA=",
            +      "dev": true,
            +      "dependencies": {
            +        "engine": "^0.1.11",
            +        "get-value": "^2.0.6",
            +        "is-primitive": "^2.0.0",
            +        "kind-of": "^3.0.3",
            +        "lazy-cache": "^2.0.1",
            +        "regex-flags": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-args": {
            +      "version": "0.4.3",
            +      "resolved": "https://registry.npmjs.org/expand-args/-/expand-args-0.4.3.tgz",
            +      "integrity": "sha1-OoZiJBxYF1fIzTf7d2d6xgL/nZg=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-object": "^0.4.2",
            +        "kind-of": "^3.0.3",
            +        "lazy-cache": "^2.0.1",
            +        "minimist": "^1.2.0",
            +        "mixin-deep": "^1.1.3",
            +        "omit-empty": "^0.4.1",
            +        "set-value": "^0.3.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-args/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-args/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-args/node_modules/set-value": {
            +      "version": "0.3.3",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.3.3.tgz",
            +      "integrity": "sha1-uBIjaBY4oQiP2IpDW4qdMtro2bo=",
            +      "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "isobject": "^2.0.0",
            +        "to-object-path": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-args/node_modules/to-object-path": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.2.0.tgz",
            +      "integrity": "sha1-FjThtSqIugDjlJYZ/ACB3Jo7B8o=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "is-arguments": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-brackets": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
            +      "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-posix-bracket": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-front-matter": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/expand-front-matter/-/expand-front-matter-1.0.0.tgz",
            +      "integrity": "sha1-gjHKjY669r9rCPa04GQg01rKAmg=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand": "^0.4.3",
            +        "extend-shallow": "^2.0.1",
            +        "is-valid-app": "^0.2.1",
            +        "isobject": "^3.0.0",
            +        "mixin-deep": "^1.1.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-front-matter/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-front-matter/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-front-matter/node_modules/is-valid-instance/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-object": {
            +      "version": "0.4.2",
            +      "resolved": "https://registry.npmjs.org/expand-object/-/expand-object-0.4.2.tgz",
            +      "integrity": "sha1-t/J+9pwv3MYrD5OQwMtHvAa7Buo=",
            +      "dev": true,
            +      "dependencies": {
            +        "get-stdin": "^5.0.1",
            +        "is-number": "^2.1.0",
            +        "minimist": "^1.2.0",
            +        "set-value": "^0.3.3"
            +      },
            +      "bin": {
            +        "expand-object": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-object/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-object/node_modules/set-value": {
            +      "version": "0.3.3",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.3.3.tgz",
            +      "integrity": "sha1-uBIjaBY4oQiP2IpDW4qdMtro2bo=",
            +      "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "isobject": "^2.0.0",
            +        "to-object-path": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-object/node_modules/to-object-path": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.2.0.tgz",
            +      "integrity": "sha1-FjThtSqIugDjlJYZ/ACB3Jo7B8o=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "is-arguments": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-pkg": {
            +      "version": "0.1.9",
            +      "resolved": "https://registry.npmjs.org/expand-pkg/-/expand-pkg-0.1.9.tgz",
            +      "integrity": "sha512-Qqtqzx/e8tODrDr0H8HtO7+nftN0wH9bsk3948KpKBZLrc86Cm3/8mRKJmDfNSDWWcuKsilMmFlKPhYx5gHYuA==",
            +      "dev": true,
            +      "dependencies": {
            +        "component-emitter": "^1.2.1",
            +        "debug": "^2.4.1",
            +        "defaults-deep": "^0.2.4",
            +        "export-files": "^2.1.1",
            +        "get-value": "^2.0.6",
            +        "kind-of": "^3.1.0",
            +        "lazy-cache": "^2.0.2",
            +        "load-pkg": "^3.0.1",
            +        "mixin-deep": "^1.1.3",
            +        "normalize-pkg": "^0.3.20",
            +        "omit-empty": "^0.4.1",
            +        "parse-author": "^1.0.0",
            +        "parse-git-config": "^1.1.1",
            +        "repo-utils": "^0.3.7"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/expand-pkg/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-range": {
            +      "version": "1.8.2",
            +      "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
            +      "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
            +      "dev": true,
            +      "dependencies": {
            +        "fill-range": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand-template": {
            +      "version": "2.0.3",
            +      "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
            +      "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
            +      "dev": true,
            +      "optional": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/expand-tilde": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
            +      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
            +      "dev": true,
            +      "dependencies": {
            +        "homedir-polyfill": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/expand/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/export-files": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/export-files/-/export-files-2.1.1.tgz",
            +      "integrity": "sha1-u/ZFdAU6CeTrmOX0NQHVcrLDzn8=",
            +      "dev": true,
            +      "dependencies": {
            +        "lazy-cache": "^1.0.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/export-files/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ext-list": {
            +      "version": "2.2.2",
            +      "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
            +      "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
            +      "dev": true,
            +      "dependencies": {
            +        "mime-db": "^1.28.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ext-name": {
            +      "version": "5.0.0",
            +      "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
            +      "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ext-list": "^2.0.0",
            +        "sort-keys-length": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/extend": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
            +      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
            +      "dev": true
            +    },
            +    "node_modules/extend-shallow": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
            +      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extendable": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/external-editor": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
            +      "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
            +      "dev": true,
            +      "dependencies": {
            +        "chardet": "^0.4.0",
            +        "iconv-lite": "^0.4.17",
            +        "tmp": "^0.0.33"
            +      },
            +      "engines": {
            +        "node": ">=0.12"
            +      }
            +    },
            +    "node_modules/external-editor/node_modules/iconv-lite": {
            +      "version": "0.4.23",
            +      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
            +      "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
            +      "dev": true,
            +      "dependencies": {
            +        "safer-buffer": ">= 2.1.2 < 3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/extglob": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
            +      "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/extglob/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/extsprintf": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
            +      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
            +      "dev": true,
            +      "engines": [
            +        "node >=0.6.0"
            +      ]
            +    },
            +    "node_modules/falsey": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/falsey/-/falsey-0.3.2.tgz",
            +      "integrity": "sha512-lxEuefF5MBIVDmE6XeqCdM4BWk1+vYmGZtkbKZ/VFcg6uBBw6fXNEbWmxCjDdQlFc9hy450nkiWwM3VAW6G1qg==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^5.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-deep-equal": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
            +      "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
            +      "dev": true
            +    },
            +    "node_modules/fast-diff": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
            +      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
            +      "dev": true
            +    },
            +    "node_modules/fast-glob": {
            +      "version": "2.2.7",
            +      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
            +      "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
            +      "dev": true,
            +      "dependencies": {
            +        "@mrmlnc/readdir-enhanced": "^2.2.1",
            +        "@nodelib/fs.stat": "^1.1.2",
            +        "glob-parent": "^3.1.0",
            +        "is-glob": "^4.0.0",
            +        "merge2": "^1.2.3",
            +        "micromatch": "^3.1.10"
            +      },
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/arr-diff": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
            +      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/array-unique": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
            +      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/braces": {
            +      "version": "2.3.2",
            +      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
            +      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.1.0",
            +        "array-unique": "^0.3.2",
            +        "extend-shallow": "^2.0.1",
            +        "fill-range": "^4.0.0",
            +        "isobject": "^3.0.1",
            +        "repeat-element": "^1.1.2",
            +        "snapdragon": "^0.8.1",
            +        "snapdragon-node": "^2.0.1",
            +        "split-string": "^3.0.2",
            +        "to-regex": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/braces/node_modules/extend-shallow": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
            +      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extendable": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/define-property": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
            +      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^1.0.2",
            +        "isobject": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/expand-brackets": {
            +      "version": "2.1.4",
            +      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
            +      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.3.3",
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "posix-character-classes": "^0.1.0",
            +        "regex-not": "^1.0.0",
            +        "snapdragon": "^0.8.1",
            +        "to-regex": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/expand-brackets/node_modules/define-property": {
            +      "version": "0.2.5",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
            +      "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/expand-brackets/node_modules/extend-shallow": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
            +      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extendable": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/expand-brackets/node_modules/is-accessor-descriptor": {
            +      "version": "0.1.6",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
            +      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/expand-brackets/node_modules/is-data-descriptor": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
            +      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/expand-brackets/node_modules/is-descriptor": {
            +      "version": "0.1.6",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
            +      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^0.1.6",
            +        "is-data-descriptor": "^0.1.4",
            +        "kind-of": "^5.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/expand-brackets/node_modules/kind-of": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
            +      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/extend-shallow": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
            +      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
            +      "dev": true,
            +      "dependencies": {
            +        "assign-symbols": "^1.0.0",
            +        "is-extendable": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/extend-shallow/node_modules/is-extendable": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
            +      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-object": "^2.0.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/extglob": {
            +      "version": "2.0.4",
            +      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
            +      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
            +      "dev": true,
            +      "dependencies": {
            +        "array-unique": "^0.3.2",
            +        "define-property": "^1.0.0",
            +        "expand-brackets": "^2.1.4",
            +        "extend-shallow": "^2.0.1",
            +        "fragment-cache": "^0.2.1",
            +        "regex-not": "^1.0.0",
            +        "snapdragon": "^0.8.1",
            +        "to-regex": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/extglob/node_modules/define-property": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
            +      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/extglob/node_modules/extend-shallow": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
            +      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extendable": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/fill-range": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
            +      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "is-number": "^3.0.0",
            +        "repeat-string": "^1.6.1",
            +        "to-regex-range": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/fill-range/node_modules/extend-shallow": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
            +      "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extendable": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/is-accessor-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/is-data-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/is-descriptor": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
            +      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^1.0.0",
            +        "is-data-descriptor": "^1.0.0",
            +        "kind-of": "^6.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/is-glob": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
            +      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^2.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/is-number": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
            +      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/is-number/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-glob/node_modules/micromatch": {
            +      "version": "3.1.10",
            +      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
            +      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-diff": "^4.0.0",
            +        "array-unique": "^0.3.2",
            +        "braces": "^2.3.1",
            +        "define-property": "^2.0.2",
            +        "extend-shallow": "^3.0.2",
            +        "extglob": "^2.0.4",
            +        "fragment-cache": "^0.2.1",
            +        "kind-of": "^6.0.2",
            +        "nanomatch": "^1.2.9",
            +        "object.pick": "^1.3.0",
            +        "regex-not": "^1.0.0",
            +        "snapdragon": "^0.8.1",
            +        "to-regex": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fast-json-stable-stringify": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
            +      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
            +      "dev": true
            +    },
            +    "node_modules/fast-levenshtein": {
            +      "version": "2.0.6",
            +      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
            +      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
            +      "dev": true
            +    },
            +    "node_modules/fastq": {
            +      "version": "1.6.0",
            +      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
            +      "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==",
            +      "dev": true,
            +      "dependencies": {
            +        "reusify": "^1.0.0"
            +      }
            +    },
            +    "node_modules/faye-websocket": {
            +      "version": "0.10.0",
            +      "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
            +      "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "websocket-driver": ">=0.5.1"
            +      },
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/fd-slicer": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
            +      "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
            +      "dev": true,
            +      "dependencies": {
            +        "pend": "~1.2.0"
            +      }
            +    },
            +    "node_modules/figures": {
            +      "version": "1.7.0",
            +      "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
            +      "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
            +      "dev": true,
            +      "dependencies": {
            +        "escape-string-regexp": "^1.0.5",
            +        "object-assign": "^4.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/file-contents": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/file-contents/-/file-contents-1.0.1.tgz",
            +      "integrity": "sha1-ryW7/T00RjhPrYBmSdiAi8/uHsg=",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "is-buffer": "^1.1.4",
            +        "kind-of": "^3.1.0",
            +        "lazy-cache": "^2.0.2",
            +        "strip-bom-buffer": "^0.1.1",
            +        "strip-bom-string": "^0.1.2",
            +        "through2": "^2.0.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/file-contents/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/file-entry-cache": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
            +      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
            +      "dev": true,
            +      "dependencies": {
            +        "flat-cache": "^1.2.1",
            +        "object-assign": "^4.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/file-is-binary": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/file-is-binary/-/file-is-binary-1.0.0.tgz",
            +      "integrity": "sha1-XkGAbRvK5FjI/sMv484SLbu8Q1Y=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-binary-buffer": "^1.0.0",
            +        "isobject": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/file-name": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/file-name/-/file-name-0.1.0.tgz",
            +      "integrity": "sha1-ErEi8SD5w028F2wauBpUis7W3vc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/file-reader": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/file-reader/-/file-reader-1.1.1.tgz",
            +      "integrity": "sha1-OD0TG0p9WMd+w1Nm3Nrb1HV96NY=",
            +      "dev": true,
            +      "dependencies": {
            +        "camel-case": "^1.2.2",
            +        "extend-shallow": "^2.0.1",
            +        "lazy-cache": "^1.0.4",
            +        "map-files": "^0.8.0",
            +        "read-yaml": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/file-reader/node_modules/camel-case": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-1.2.2.tgz",
            +      "integrity": "sha1-Gsp8TRlTWaLOmVV5NDPG5VQlEfI=",
            +      "dev": true,
            +      "dependencies": {
            +        "sentence-case": "^1.1.1",
            +        "upper-case": "^1.1.1"
            +      }
            +    },
            +    "node_modules/file-reader/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/file-type": {
            +      "version": "10.11.0",
            +      "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz",
            +      "integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/filename-regex": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
            +      "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/filename-reserved-regex": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
            +      "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/filenamify": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.1.0.tgz",
            +      "integrity": "sha512-ICw7NTT6RsDp2rnYKVd8Fu4cr6ITzGy3+u4vUujPkabyaz+03F24NWEX7fs5fp+kBonlaqPH8fAO2NM+SXt/JA==",
            +      "dev": true,
            +      "dependencies": {
            +        "filename-reserved-regex": "^2.0.0",
            +        "strip-outer": "^1.0.0",
            +        "trim-repeated": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/fill-range": {
            +      "version": "2.2.4",
            +      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
            +      "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^2.1.0",
            +        "isobject": "^2.0.0",
            +        "randomatic": "^3.0.0",
            +        "repeat-element": "^1.1.2",
            +        "repeat-string": "^1.5.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fill-range/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/finalhandler": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
            +      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "2.6.9",
            +        "encodeurl": "~1.0.2",
            +        "escape-html": "~1.0.3",
            +        "on-finished": "~2.3.0",
            +        "parseurl": "~1.3.3",
            +        "statuses": "~1.5.0",
            +        "unpipe": "~1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.8"
            +      }
            +    },
            +    "node_modules/finalhandler/node_modules/statuses": {
            +      "version": "1.5.0",
            +      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
            +      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/find-file-up": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/find-file-up/-/find-file-up-0.1.3.tgz",
            +      "integrity": "sha1-z2gJG8+fMApA2kEbN9pczlovvqA=",
            +      "dev": true,
            +      "dependencies": {
            +        "fs-exists-sync": "^0.1.0",
            +        "resolve-dir": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/find-file-up/node_modules/expand-tilde": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
            +      "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
            +      "dev": true,
            +      "dependencies": {
            +        "os-homedir": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/find-file-up/node_modules/resolve-dir": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
            +      "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^1.2.2",
            +        "global-modules": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/find-pkg": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/find-pkg/-/find-pkg-0.1.2.tgz",
            +      "integrity": "sha1-G9wiwG42NlUy4qJIBGhUuXiNpVc=",
            +      "dev": true,
            +      "dependencies": {
            +        "find-file-up": "^0.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/find-up": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
            +      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
            +      "dev": true,
            +      "dependencies": {
            +        "path-exists": "^2.0.0",
            +        "pinkie-promise": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/find-versions": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz",
            +      "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==",
            +      "dev": true,
            +      "dependencies": {
            +        "semver-regex": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/findup-sync": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz",
            +      "integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=",
            +      "dev": true,
            +      "dependencies": {
            +        "glob": "~3.2.9",
            +        "lodash": "~2.4.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.6.0"
            +      }
            +    },
            +    "node_modules/findup-sync/node_modules/glob": {
            +      "version": "3.2.11",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
            +      "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
            +      "dev": true,
            +      "dependencies": {
            +        "inherits": "2",
            +        "minimatch": "0.3"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/findup-sync/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/findup-sync/node_modules/lru-cache": {
            +      "version": "2.7.3",
            +      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
            +      "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
            +      "dev": true
            +    },
            +    "node_modules/findup-sync/node_modules/minimatch": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
            +      "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
            +      "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue",
            +      "dev": true,
            +      "dependencies": {
            +        "lru-cache": "2",
            +        "sigmund": "~1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/fined": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
            +      "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^2.0.2",
            +        "is-plain-object": "^2.0.3",
            +        "object.defaults": "^1.1.0",
            +        "object.pick": "^1.2.0",
            +        "parse-filepath": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/first-chunk-stream": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz",
            +      "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/flagged-respawn": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
            +      "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/flat": {
            +      "version": "5.0.2",
            +      "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
            +      "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
            +      "dev": true,
            +      "bin": {
            +        "flat": "cli.js"
            +      }
            +    },
            +    "node_modules/flat-cache": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
            +      "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
            +      "dev": true,
            +      "dependencies": {
            +        "circular-json": "^0.3.1",
            +        "del": "^2.0.2",
            +        "graceful-fs": "^4.1.2",
            +        "write": "^0.2.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/for-in": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
            +      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/for-own": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
            +      "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
            +      "dev": true,
            +      "dependencies": {
            +        "for-in": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/forever-agent": {
            +      "version": "0.6.1",
            +      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
            +      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/form-data": {
            +      "version": "2.3.3",
            +      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
            +      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "asynckit": "^0.4.0",
            +        "combined-stream": "^1.0.6",
            +        "mime-types": "^2.1.12"
            +      },
            +      "engines": {
            +        "node": ">= 0.12"
            +      }
            +    },
            +    "node_modules/fragment-cache": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
            +      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
            +      "dev": true,
            +      "dependencies": {
            +        "map-cache": "^0.2.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/frep": {
            +      "version": "0.1.8",
            +      "resolved": "https://registry.npmjs.org/frep/-/frep-0.1.8.tgz",
            +      "integrity": "sha1-tRhe+lZi5qxvQgak4Y0JZ/ISGdo=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash": "~2.4.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/frep/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/fresh": {
            +      "version": "0.5.2",
            +      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
            +      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/from2": {
            +      "version": "2.3.0",
            +      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
            +      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
            +      "dev": true,
            +      "dependencies": {
            +        "inherits": "^2.0.1",
            +        "readable-stream": "^2.0.0"
            +      }
            +    },
            +    "node_modules/fs-constants": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
            +      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
            +      "dev": true
            +    },
            +    "node_modules/fs-exists-sync": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
            +      "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/fs-extra": {
            +      "version": "9.1.0",
            +      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
            +      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "at-least-node": "^1.0.0",
            +        "graceful-fs": "^4.2.0",
            +        "jsonfile": "^6.0.1",
            +        "universalify": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/fs-extra/node_modules/graceful-fs": {
            +      "version": "4.2.6",
            +      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
            +      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
            +      "dev": true
            +    },
            +    "node_modules/fs-utils": {
            +      "version": "0.3.10",
            +      "resolved": "https://registry.npmjs.org/fs-utils/-/fs-utils-0.3.10.tgz",
            +      "integrity": "sha1-6x5j2niBbNzouM6xyHQxT5Hn2JI=",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "~0.2.10",
            +        "globule": "~0.2.0",
            +        "graceful-fs": "~2.0.3",
            +        "js-yaml": "~3.0.2",
            +        "lodash": "~2.4.1",
            +        "mkdirp": "~0.3.5",
            +        "rimraf": "~2.2.6",
            +        "template": "~0.1.5"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/fs-utils/node_modules/argparse": {
            +      "version": "0.1.16",
            +      "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz",
            +      "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=",
            +      "dev": true,
            +      "dependencies": {
            +        "underscore": "~1.7.0",
            +        "underscore.string": "~2.4.0"
            +      }
            +    },
            +    "node_modules/fs-utils/node_modules/async": {
            +      "version": "0.2.10",
            +      "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
            +      "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
            +      "dev": true
            +    },
            +    "node_modules/fs-utils/node_modules/esprima": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
            +      "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=",
            +      "dev": true,
            +      "bin": {
            +        "esparse": "bin/esparse.js",
            +        "esvalidate": "bin/esvalidate.js"
            +      },
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/fs-utils/node_modules/graceful-fs": {
            +      "version": "2.0.3",
            +      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz",
            +      "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=",
            +      "deprecated": "please upgrade to graceful-fs 4 for compatibility with current and future versions of Node.js",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/fs-utils/node_modules/js-yaml": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.0.2.tgz",
            +      "integrity": "sha1-mTeGX46Jel6JTnPCxc8uibMut3E=",
            +      "dev": true,
            +      "dependencies": {
            +        "argparse": "~ 0.1.11",
            +        "esprima": "~ 1.0.2"
            +      },
            +      "bin": {
            +        "js-yaml": "bin/js-yaml.js"
            +      }
            +    },
            +    "node_modules/fs-utils/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/fs-utils/node_modules/mkdirp": {
            +      "version": "0.3.5",
            +      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
            +      "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=",
            +      "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
            +      "dev": true
            +    },
            +    "node_modules/fs-utils/node_modules/rimraf": {
            +      "version": "2.2.8",
            +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
            +      "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
            +      "dev": true,
            +      "bin": {
            +        "rimraf": "bin.js"
            +      }
            +    },
            +    "node_modules/fs.realpath": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
            +      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
            +      "dev": true
            +    },
            +    "node_modules/function-bind": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
            +      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
            +      "dev": true
            +    },
            +    "node_modules/functional-red-black-tree": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
            +      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
            +      "dev": true
            +    },
            +    "node_modules/gauge": {
            +      "version": "2.7.4",
            +      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
            +      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "aproba": "^1.0.3",
            +        "console-control-strings": "^1.0.0",
            +        "has-unicode": "^2.0.0",
            +        "object-assign": "^4.1.0",
            +        "signal-exit": "^3.0.0",
            +        "string-width": "^1.0.1",
            +        "strip-ansi": "^3.0.1",
            +        "wide-align": "^1.1.0"
            +      }
            +    },
            +    "node_modules/gauge/node_modules/string-width": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
            +      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "code-point-at": "^1.0.0",
            +        "is-fullwidth-code-point": "^1.0.0",
            +        "strip-ansi": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/gaze": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
            +      "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
            +      "dev": true,
            +      "dependencies": {
            +        "globule": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 4.0.0"
            +      }
            +    },
            +    "node_modules/gaze/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/gaze/node_modules/globule": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.0.tgz",
            +      "integrity": "sha512-YlD4kdMqRCQHrhVdonet4TdRtv1/sZKepvoxNT4Nrhrp5HI8XFfc8kFlGlBn2myBo80aGp8Eft259mbcUJhgSg==",
            +      "dev": true,
            +      "dependencies": {
            +        "glob": "~7.1.1",
            +        "lodash": "~4.17.10",
            +        "minimatch": "~3.0.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/get-intrinsic": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
            +      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "function-bind": "^1.1.1",
            +        "has": "^1.0.3",
            +        "has-symbols": "^1.0.1"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/get-object": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/get-object/-/get-object-0.2.0.tgz",
            +      "integrity": "sha1-2S/31RkMZFMM2gVD2sY6PUf+jAw=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^2.0.2",
            +        "isobject": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/get-object/node_modules/isobject": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-0.2.0.tgz",
            +      "integrity": "sha1-o0MhkvObkQtfAsyYlIeDbscKqF4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/get-own-enumerable-property-symbols": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
            +      "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==",
            +      "dev": true
            +    },
            +    "node_modules/get-proxy": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz",
            +      "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==",
            +      "dev": true,
            +      "dependencies": {
            +        "npm-conf": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/get-stdin": {
            +      "version": "5.0.1",
            +      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
            +      "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.12.0"
            +      }
            +    },
            +    "node_modules/get-stream": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
            +      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/get-value": {
            +      "version": "2.0.6",
            +      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
            +      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/get-view": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/get-view/-/get-view-0.1.3.tgz",
            +      "integrity": "sha1-NmCsBYuhPfl0nKvKpry5bUGqDqA=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^3.0.0",
            +        "match-file": "^0.2.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/getobject": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.1.tgz",
            +      "integrity": "sha512-tj18lLe+917AACr6BdVoUuHnBPTVd9BEJp1vxnMZ58ztNvuxz9Ufa+wf3g37tlGITH35jggwZ2d9lcgHJJgXfQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/getpass": {
            +      "version": "0.1.7",
            +      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
            +      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
            +      "dev": true,
            +      "dependencies": {
            +        "assert-plus": "^1.0.0"
            +      }
            +    },
            +    "node_modules/gifsicle": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-4.0.1.tgz",
            +      "integrity": "sha512-A/kiCLfDdV+ERV/UB+2O41mifd+RxH8jlRG8DMxZO84Bma/Fw0htqZ+hY2iaalLRNyUu7tYZQslqUBJxBggxbg==",
            +      "dev": true,
            +      "hasInstallScript": true,
            +      "optional": true,
            +      "dependencies": {
            +        "bin-build": "^3.0.0",
            +        "bin-wrapper": "^4.0.0",
            +        "execa": "^1.0.0",
            +        "logalot": "^2.0.0"
            +      },
            +      "bin": {
            +        "gifsicle": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/gifsicle/node_modules/cross-spawn": {
            +      "version": "6.0.5",
            +      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
            +      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "nice-try": "^1.0.4",
            +        "path-key": "^2.0.1",
            +        "semver": "^5.5.0",
            +        "shebang-command": "^1.2.0",
            +        "which": "^1.2.9"
            +      },
            +      "engines": {
            +        "node": ">=4.8"
            +      }
            +    },
            +    "node_modules/gifsicle/node_modules/execa": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
            +      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "cross-spawn": "^6.0.0",
            +        "get-stream": "^4.0.0",
            +        "is-stream": "^1.1.0",
            +        "npm-run-path": "^2.0.0",
            +        "p-finally": "^1.0.0",
            +        "signal-exit": "^3.0.0",
            +        "strip-eof": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/gifsicle/node_modules/get-stream": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
            +      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "pump": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/gifsicle/node_modules/pump": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
            +      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "end-of-stream": "^1.1.0",
            +        "once": "^1.3.1"
            +      }
            +    },
            +    "node_modules/git-config-path": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz",
            +      "integrity": "sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "fs-exists-sync": "^0.1.0",
            +        "homedir-polyfill": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/git-repo-name": {
            +      "version": "0.6.0",
            +      "resolved": "https://registry.npmjs.org/git-repo-name/-/git-repo-name-0.6.0.tgz",
            +      "integrity": "sha1-rwmIRlaqU37GJccIcAgXXNYSKP8=",
            +      "dev": true,
            +      "dependencies": {
            +        "cwd": "^0.9.1",
            +        "file-name": "^0.1.0",
            +        "lazy-cache": "^1.0.4",
            +        "remote-origin-url": "^0.5.1"
            +      },
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/git-repo-name/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/github-from-package": {
            +      "version": "0.0.0",
            +      "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
            +      "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/glob": {
            +      "version": "5.0.15",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
            +      "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
            +      "dev": true,
            +      "dependencies": {
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "2 || 3",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/glob-base": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
            +      "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
            +      "dev": true,
            +      "dependencies": {
            +        "glob-parent": "^2.0.0",
            +        "is-glob": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/glob-base/node_modules/glob-parent": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
            +      "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^2.0.0"
            +      }
            +    },
            +    "node_modules/glob-base/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/glob-base/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/glob-parent": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
            +      "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^3.1.0",
            +        "path-dirname": "^1.0.0"
            +      }
            +    },
            +    "node_modules/glob-path-regex": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/glob-path-regex/-/glob-path-regex-1.0.0.tgz",
            +      "integrity": "sha1-E4OpjJ7fDv84Dth3qIcqrl6UB50=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/glob-stream": {
            +      "version": "5.3.5",
            +      "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz",
            +      "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend": "^3.0.0",
            +        "glob": "^5.0.3",
            +        "glob-parent": "^3.0.0",
            +        "micromatch": "^2.3.7",
            +        "ordered-read-streams": "^0.3.0",
            +        "through2": "^0.6.0",
            +        "to-absolute-glob": "^0.1.1",
            +        "unique-stream": "^2.0.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/glob-stream/node_modules/isarray": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
            +      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
            +      "dev": true
            +    },
            +    "node_modules/glob-stream/node_modules/readable-stream": {
            +      "version": "1.0.34",
            +      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
            +      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
            +      "dev": true,
            +      "dependencies": {
            +        "core-util-is": "~1.0.0",
            +        "inherits": "~2.0.1",
            +        "isarray": "0.0.1",
            +        "string_decoder": "~0.10.x"
            +      }
            +    },
            +    "node_modules/glob-stream/node_modules/string_decoder": {
            +      "version": "0.10.31",
            +      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
            +      "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
            +      "dev": true
            +    },
            +    "node_modules/glob-stream/node_modules/through2": {
            +      "version": "0.6.5",
            +      "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
            +      "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
            +      "dev": true,
            +      "dependencies": {
            +        "readable-stream": ">=1.0.33-1 <1.1.0-0",
            +        "xtend": ">=4.0.0 <4.1.0-0"
            +      }
            +    },
            +    "node_modules/glob-to-regexp": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
            +      "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
            +      "dev": true
            +    },
            +    "node_modules/global-modules": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz",
            +      "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=",
            +      "dev": true,
            +      "dependencies": {
            +        "global-prefix": "^0.1.4",
            +        "is-windows": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/global-modules/node_modules/global-prefix": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz",
            +      "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=",
            +      "dev": true,
            +      "dependencies": {
            +        "homedir-polyfill": "^1.0.0",
            +        "ini": "^1.3.4",
            +        "is-windows": "^0.2.0",
            +        "which": "^1.2.12"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/global-modules/node_modules/is-windows": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
            +      "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/global-prefix": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
            +      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^2.0.2",
            +        "homedir-polyfill": "^1.0.1",
            +        "ini": "^1.3.4",
            +        "is-windows": "^1.0.1",
            +        "which": "^1.2.14"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/globals": {
            +      "version": "11.7.0",
            +      "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz",
            +      "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/globby": {
            +      "version": "5.0.0",
            +      "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
            +      "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-union": "^1.0.1",
            +        "arrify": "^1.0.0",
            +        "glob": "^7.0.3",
            +        "object-assign": "^4.0.1",
            +        "pify": "^2.0.0",
            +        "pinkie-promise": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/globby/node_modules/glob": {
            +      "version": "7.1.2",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
            +      "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/globule": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/globule/-/globule-0.2.0.tgz",
            +      "integrity": "sha1-JrZNEOHtyrYJjY/gC9K3PMoIqPs=",
            +      "dev": true,
            +      "dependencies": {
            +        "glob": "~3.2.7",
            +        "lodash": "~2.4.1",
            +        "minimatch": "~0.2.11"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/globule/node_modules/glob": {
            +      "version": "3.2.11",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
            +      "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
            +      "dev": true,
            +      "dependencies": {
            +        "inherits": "2",
            +        "minimatch": "0.3"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/globule/node_modules/glob/node_modules/minimatch": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
            +      "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
            +      "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue",
            +      "dev": true,
            +      "dependencies": {
            +        "lru-cache": "2",
            +        "sigmund": "~1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/globule/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/globule/node_modules/lru-cache": {
            +      "version": "2.7.3",
            +      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
            +      "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
            +      "dev": true
            +    },
            +    "node_modules/globule/node_modules/minimatch": {
            +      "version": "0.2.14",
            +      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
            +      "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
            +      "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue",
            +      "dev": true,
            +      "dependencies": {
            +        "lru-cache": "2",
            +        "sigmund": "~1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/got": {
            +      "version": "7.1.0",
            +      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
            +      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
            +      "dev": true,
            +      "dependencies": {
            +        "decompress-response": "^3.2.0",
            +        "duplexer3": "^0.1.4",
            +        "get-stream": "^3.0.0",
            +        "is-plain-obj": "^1.1.0",
            +        "is-retry-allowed": "^1.0.0",
            +        "is-stream": "^1.0.0",
            +        "isurl": "^1.0.0-alpha5",
            +        "lowercase-keys": "^1.0.0",
            +        "p-cancelable": "^0.3.0",
            +        "p-timeout": "^1.1.1",
            +        "safe-buffer": "^5.0.1",
            +        "timed-out": "^4.0.0",
            +        "url-parse-lax": "^1.0.0",
            +        "url-to-options": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/graceful-fs": {
            +      "version": "4.1.11",
            +      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
            +      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/graceful-readlink": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
            +      "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
            +      "dev": true
            +    },
            +    "node_modules/gray-matter": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-3.1.1.tgz",
            +      "integrity": "sha512-nZ1qjLmayEv0/wt3sHig7I0s3/sJO0dkAaKYQ5YAOApUtYEOonXSFdWvL1khvnZMTvov4UufkqlFsilPnejEXA==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "js-yaml": "^3.10.0",
            +        "kind-of": "^5.0.2",
            +        "strip-bom-string": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/gray-matter/node_modules/strip-bom-string": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
            +      "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/group-array": {
            +      "version": "0.3.4",
            +      "resolved": "https://registry.npmjs.org/group-array/-/group-array-0.3.4.tgz",
            +      "integrity": "sha512-YAmNsgsi1uQ7Ai3T4FFkMoskqbLEUPRajAmrn8FclwZQQnV98NLrNWjQ3n2+i1pANxdO3n6wsNEkKq5XrYy0Ow==",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "for-own": "^0.1.4",
            +        "get-value": "^2.0.6",
            +        "kind-of": "^3.1.0",
            +        "split-string": "^1.0.1",
            +        "union-value": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/group-array/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/group-array/node_modules/split-string": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/split-string/-/split-string-1.0.1.tgz",
            +      "integrity": "sha1-vLqz9BUqzuOg1qskecDSh5w9s84=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/grunt": {
            +      "version": "1.4.1",
            +      "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.4.1.tgz",
            +      "integrity": "sha512-ZXIYXTsAVrA7sM+jZxjQdrBOAg7DyMUplOMhTaspMRExei+fD0BTwdWXnn0W5SXqhb/Q/nlkzXclSi3IH55PIA==",
            +      "dev": true,
            +      "dependencies": {
            +        "dateformat": "~3.0.3",
            +        "eventemitter2": "~0.4.13",
            +        "exit": "~0.1.2",
            +        "findup-sync": "~0.3.0",
            +        "glob": "~7.1.6",
            +        "grunt-cli": "~1.4.2",
            +        "grunt-known-options": "~2.0.0",
            +        "grunt-legacy-log": "~3.0.0",
            +        "grunt-legacy-util": "~2.0.1",
            +        "iconv-lite": "~0.4.13",
            +        "js-yaml": "~3.14.0",
            +        "minimatch": "~3.0.4",
            +        "mkdirp": "~1.0.4",
            +        "nopt": "~3.0.6",
            +        "rimraf": "~3.0.2"
            +      },
            +      "bin": {
            +        "grunt": "bin/grunt"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/grunt-assemble": {
            +      "version": "0.6.3",
            +      "resolved": "https://registry.npmjs.org/grunt-assemble/-/grunt-assemble-0.6.3.tgz",
            +      "integrity": "sha1-JRZzK8e4T9juPWJwl9OyvJNAz5A=",
            +      "dev": true,
            +      "dependencies": {
            +        "assemble-handlebars": "^0.4.1",
            +        "async": "^0.9.0",
            +        "gray-matter": "^0.4.2",
            +        "inflection": "^1.3.6",
            +        "lodash": "^2.4.1",
            +        "resolve-dep": "^0.5.3"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/grunt-assemble/node_modules/argparse": {
            +      "version": "0.1.16",
            +      "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz",
            +      "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=",
            +      "dev": true,
            +      "dependencies": {
            +        "underscore": "~1.7.0",
            +        "underscore.string": "~2.4.0"
            +      }
            +    },
            +    "node_modules/grunt-assemble/node_modules/async": {
            +      "version": "0.9.2",
            +      "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
            +      "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
            +      "dev": true
            +    },
            +    "node_modules/grunt-assemble/node_modules/esprima": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
            +      "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=",
            +      "dev": true,
            +      "bin": {
            +        "esparse": "bin/esparse.js",
            +        "esvalidate": "bin/esvalidate.js"
            +      },
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/grunt-assemble/node_modules/fs-utils": {
            +      "version": "0.4.3",
            +      "resolved": "https://registry.npmjs.org/fs-utils/-/fs-utils-0.4.3.tgz",
            +      "integrity": "sha1-ZBdm/lQV0RZEHexkdpjBPWz5z3c=",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "~0.6.2",
            +        "globule": "~0.2.0",
            +        "graceful-fs": "~2.0.3",
            +        "js-yaml": "~3.0.2",
            +        "lodash": "~2.4.1",
            +        "mkdirp": "~0.3.5",
            +        "rimraf": "~2.2.6"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/grunt-assemble/node_modules/fs-utils/node_modules/async": {
            +      "version": "0.6.2",
            +      "resolved": "https://registry.npmjs.org/async/-/async-0.6.2.tgz",
            +      "integrity": "sha1-Qf0DijgSwKi8GELs8IumPrA5K+8=",
            +      "dev": true
            +    },
            +    "node_modules/grunt-assemble/node_modules/fs-utils/node_modules/js-yaml": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.0.2.tgz",
            +      "integrity": "sha1-mTeGX46Jel6JTnPCxc8uibMut3E=",
            +      "dev": true,
            +      "dependencies": {
            +        "argparse": "~ 0.1.11",
            +        "esprima": "~ 1.0.2"
            +      },
            +      "bin": {
            +        "js-yaml": "bin/js-yaml.js"
            +      }
            +    },
            +    "node_modules/grunt-assemble/node_modules/graceful-fs": {
            +      "version": "2.0.3",
            +      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz",
            +      "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=",
            +      "deprecated": "please upgrade to graceful-fs 4 for compatibility with current and future versions of Node.js",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/grunt-assemble/node_modules/gray-matter": {
            +      "version": "0.4.2",
            +      "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-0.4.2.tgz",
            +      "integrity": "sha1-I/GQrJhlycCtsE0xnMIw+rdZ1wg=",
            +      "dev": true,
            +      "dependencies": {
            +        "delims": "^0.1.4",
            +        "fs-utils": "^0.4.3",
            +        "js-yaml": "^3.0.2",
            +        "lodash": "^2.4.1",
            +        "verbalize": "^0.1.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/grunt-assemble/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/grunt-assemble/node_modules/mkdirp": {
            +      "version": "0.3.5",
            +      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
            +      "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=",
            +      "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
            +      "dev": true
            +    },
            +    "node_modules/grunt-assemble/node_modules/rimraf": {
            +      "version": "2.2.8",
            +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
            +      "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
            +      "dev": true,
            +      "bin": {
            +        "rimraf": "bin.js"
            +      }
            +    },
            +    "node_modules/grunt-cli": {
            +      "version": "1.4.3",
            +      "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz",
            +      "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "grunt-known-options": "~2.0.0",
            +        "interpret": "~1.1.0",
            +        "liftup": "~3.0.1",
            +        "nopt": "~4.0.1",
            +        "v8flags": "~3.2.0"
            +      },
            +      "bin": {
            +        "grunt": "bin/grunt"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/grunt-cli/node_modules/nopt": {
            +      "version": "4.0.3",
            +      "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
            +      "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
            +      "dev": true,
            +      "dependencies": {
            +        "abbrev": "1",
            +        "osenv": "^0.1.4"
            +      },
            +      "bin": {
            +        "nopt": "bin/nopt.js"
            +      }
            +    },
            +    "node_modules/grunt-contrib-clean": {
            +      "version": "0.6.0",
            +      "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.6.0.tgz",
            +      "integrity": "sha1-9TLbpLghJnTHwBPhRr2mY4uQSPY=",
            +      "dev": true,
            +      "dependencies": {
            +        "rimraf": "~2.2.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      },
            +      "peerDependencies": {
            +        "grunt": "~0.4.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-clean/node_modules/rimraf": {
            +      "version": "2.2.8",
            +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
            +      "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
            +      "dev": true,
            +      "bin": {
            +        "rimraf": "bin.js"
            +      }
            +    },
            +    "node_modules/grunt-contrib-compress": {
            +      "version": "1.6.0",
            +      "resolved": "https://registry.npmjs.org/grunt-contrib-compress/-/grunt-contrib-compress-1.6.0.tgz",
            +      "integrity": "sha512-wIFuvk+/Ny4E+OgEfJYFZgoH7KcU/nnNFbYasB7gRvrcRyW6vmTp3Pj8a4rFSR3tbFMjrGvTUszdO6fgLajgZQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "archiver": "^1.3.0",
            +        "chalk": "^1.1.1",
            +        "lodash": "^4.7.0",
            +        "pretty-bytes": "^4.0.2",
            +        "stream-buffers": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0"
            +      },
            +      "optionalDependencies": {
            +        "iltorb": "^2.4.3"
            +      }
            +    },
            +    "node_modules/grunt-contrib-concat": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz",
            +      "integrity": "sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.0.0",
            +        "source-map": "^0.5.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-concat/node_modules/source-map": {
            +      "version": "0.5.7",
            +      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
            +      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-connect": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/grunt-contrib-connect/-/grunt-contrib-connect-2.1.0.tgz",
            +      "integrity": "sha512-yeCHdz5zqoibhQDyw/X+E/wTzYPpim+C2p+xYyXUsXVEkfxnKVIWYOWrAKkFHlz9//nIC0S3JbUDd3mVvJcxVA==",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "^2.6.1",
            +        "connect": "^3.6.6",
            +        "connect-livereload": "^0.6.0",
            +        "morgan": "^1.9.1",
            +        "node-http2": "^4.0.1",
            +        "opn": "^5.3.0",
            +        "portscanner": "^2.2.0",
            +        "serve-index": "^1.9.1",
            +        "serve-static": "^1.13.2"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-connect/node_modules/async": {
            +      "version": "2.6.3",
            +      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
            +      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash": "^4.17.14"
            +      }
            +    },
            +    "node_modules/grunt-contrib-copy": {
            +      "version": "0.5.0",
            +      "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-0.5.0.tgz",
            +      "integrity": "sha1-QQB1rEWlhWuhkbHMclclRQ1KAhU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      },
            +      "peerDependencies": {
            +        "grunt": "~0.4.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-imagemin": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/grunt-contrib-imagemin/-/grunt-contrib-imagemin-3.1.0.tgz",
            +      "integrity": "sha512-c0duAb018eowVVfqNMN0S5Esx8mRZ1OP/hkEoKnJkOCaD9/DywKGvLuhschF+DByPSs4k1u1y38w9Bt+ihJG8A==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.1",
            +        "imagemin": "^6.0.0",
            +        "p-map": "^1.2.0",
            +        "plur": "^3.0.1",
            +        "pretty-bytes": "^5.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "optionalDependencies": {
            +        "imagemin-gifsicle": "^6.0.1",
            +        "imagemin-jpegtran": "^6.0.0",
            +        "imagemin-optipng": "^6.0.0",
            +        "imagemin-svgo": "^7.0.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-imagemin/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-contrib-imagemin/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-contrib-imagemin/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-contrib-imagemin/node_modules/pretty-bytes": {
            +      "version": "5.3.0",
            +      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz",
            +      "integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/grunt-contrib-imagemin/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-contrib-requirejs": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/grunt-contrib-requirejs/-/grunt-contrib-requirejs-1.0.0.tgz",
            +      "integrity": "sha1-7BZwyvwycTkC7lNWlFRxWy48utU=",
            +      "dev": true,
            +      "dependencies": {
            +        "requirejs": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-uglify": {
            +      "version": "3.4.0",
            +      "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-3.4.0.tgz",
            +      "integrity": "sha512-UXsTpeP0pytpTYlmll3RDndsRXfdwmrf1tI/AtD/PrArQAzGmKMvj83aVt3D8egWlE6KqPjsJBLCCvfC52LI/A==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.0.0",
            +        "maxmin": "^2.1.0",
            +        "uglify-js": "~3.4.0",
            +        "uri-path": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-uglify/node_modules/commander": {
            +      "version": "2.19.0",
            +      "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
            +      "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
            +      "dev": true
            +    },
            +    "node_modules/grunt-contrib-uglify/node_modules/uglify-js": {
            +      "version": "3.4.10",
            +      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
            +      "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==",
            +      "dev": true,
            +      "dependencies": {
            +        "commander": "~2.19.0",
            +        "source-map": "~0.6.1"
            +      },
            +      "bin": {
            +        "uglifyjs": "bin/uglifyjs"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-watch": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz",
            +      "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "^2.6.0",
            +        "gaze": "^1.1.0",
            +        "lodash": "^4.17.10",
            +        "tiny-lr": "^1.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/grunt-contrib-watch/node_modules/async": {
            +      "version": "2.6.3",
            +      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
            +      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash": "^4.17.14"
            +      }
            +    },
            +    "node_modules/grunt-exec": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-1.0.1.tgz",
            +      "integrity": "sha1-5dU6OcXzRpATBe3uXIfbDyr5mcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8.0"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">=0.4"
            +      }
            +    },
            +    "node_modules/grunt-file-append": {
            +      "version": "0.0.7",
            +      "resolved": "https://registry.npmjs.org/grunt-file-append/-/grunt-file-append-0.0.7.tgz",
            +      "integrity": "sha1-P376M2lvoFdwsoCU9EUIyvxdLto=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">0.4.1"
            +      }
            +    },
            +    "node_modules/grunt-html": {
            +      "version": "11.1.1",
            +      "resolved": "https://registry.npmjs.org/grunt-html/-/grunt-html-11.1.1.tgz",
            +      "integrity": "sha512-YAurPMB/GUsy8UZdNYZ38pTTGYKoXuTxi6CkIYtxSRfxKEJCCK0JSDJn5UbAvA0MK86CMhOsMeO+4qcu9KnPHw==",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "^3.1.0",
            +        "chalk": "^2.4.2",
            +        "vnu-jar": "19.9.4"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/grunt-html/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-html/node_modules/async": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
            +      "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==",
            +      "dev": true
            +    },
            +    "node_modules/grunt-html/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-html/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-html/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-known-options": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz",
            +      "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/grunt-legacy-log": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz",
            +      "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==",
            +      "dev": true,
            +      "dependencies": {
            +        "colors": "~1.1.2",
            +        "grunt-legacy-log-utils": "~2.1.0",
            +        "hooker": "~0.2.3",
            +        "lodash": "~4.17.19"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/grunt-legacy-log-utils": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz",
            +      "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "~4.1.0",
            +        "lodash": "~4.17.19"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/grunt-legacy-log-utils/node_modules/ansi-styles": {
            +      "version": "4.3.0",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
            +      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      },
            +      "funding": {
            +        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
            +      }
            +    },
            +    "node_modules/grunt-legacy-log-utils/node_modules/chalk": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
            +      "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^4.1.0",
            +        "supports-color": "^7.1.0"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      },
            +      "funding": {
            +        "url": "https://github.com/chalk/chalk?sponsor=1"
            +      }
            +    },
            +    "node_modules/grunt-legacy-log-utils/node_modules/color-convert": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
            +      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-name": "~1.1.4"
            +      },
            +      "engines": {
            +        "node": ">=7.0.0"
            +      }
            +    },
            +    "node_modules/grunt-legacy-log-utils/node_modules/color-name": {
            +      "version": "1.1.4",
            +      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
            +      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
            +      "dev": true
            +    },
            +    "node_modules/grunt-legacy-log-utils/node_modules/has-flag": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
            +      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/grunt-legacy-log-utils/node_modules/supports-color": {
            +      "version": "7.2.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
            +      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/grunt-legacy-util": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz",
            +      "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "~3.2.0",
            +        "exit": "~0.1.2",
            +        "getobject": "~1.0.0",
            +        "hooker": "~0.2.3",
            +        "lodash": "~4.17.21",
            +        "underscore.string": "~3.3.5",
            +        "which": "~2.0.2"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/grunt-legacy-util/node_modules/async": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
            +      "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==",
            +      "dev": true
            +    },
            +    "node_modules/grunt-legacy-util/node_modules/underscore.string": {
            +      "version": "3.3.5",
            +      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
            +      "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
            +      "dev": true,
            +      "dependencies": {
            +        "sprintf-js": "^1.0.3",
            +        "util-deprecate": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/grunt-legacy-util/node_modules/which": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
            +      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
            +      "dev": true,
            +      "dependencies": {
            +        "isexe": "^2.0.0"
            +      },
            +      "bin": {
            +        "node-which": "bin/node-which"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/grunt-newer": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/grunt-newer/-/grunt-newer-1.3.0.tgz",
            +      "integrity": "sha1-g8y3od2ny9irI7BZAk6+YUrS80I=",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "^1.5.2",
            +        "rimraf": "^2.5.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">=0.4.1"
            +      }
            +    },
            +    "node_modules/grunt-postcss": {
            +      "version": "0.9.0",
            +      "resolved": "https://registry.npmjs.org/grunt-postcss/-/grunt-postcss-0.9.0.tgz",
            +      "integrity": "sha512-lglLcVaoOIqH0sFv7RqwUKkEFGQwnlqyAKbatxZderwZGV1nDyKHN7gZS9LUiTx1t5GOvRBx0BEalHMyVwFAIA==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.1.0",
            +        "diff": "^3.0.0",
            +        "postcss": "^6.0.11"
            +      },
            +      "engines": {
            +        "node": ">= 0.12.0"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">=0.4.5"
            +      }
            +    },
            +    "node_modules/grunt-postcss/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-postcss/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-postcss/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-postcss/node_modules/postcss": {
            +      "version": "6.0.23",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
            +      "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.1",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^5.4.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/grunt-postcss/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-serve": {
            +      "version": "0.1.6",
            +      "resolved": "https://registry.npmjs.org/grunt-serve/-/grunt-serve-0.1.6.tgz",
            +      "integrity": "sha1-mGhKulH5JyrpvTT1l5iWLO7U7SM=",
            +      "dev": true,
            +      "dependencies": {
            +        "connect": "~2.13.0",
            +        "dot": "~1.0.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      },
            +      "peerDependencies": {
            +        "grunt": "~0.4.0"
            +      }
            +    },
            +    "node_modules/grunt-serve/node_modules/buffer-crc32": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz",
            +      "integrity": "sha1-vj5TgvwCttYySVasGvmKqYsIU0w=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/grunt-serve/node_modules/bytes": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/bytes/-/bytes-0.2.1.tgz",
            +      "integrity": "sha1-VVsIq8sGP4l1kFMCUj5M1P/f3zE=",
            +      "dev": true
            +    },
            +    "node_modules/grunt-serve/node_modules/connect": {
            +      "version": "2.13.1",
            +      "resolved": "https://registry.npmjs.org/connect/-/connect-2.13.1.tgz",
            +      "integrity": "sha1-qrgr6fB2WkI6qZQxq5IqqoCBqiI=",
            +      "deprecated": "connect 2.x series is deprecated",
            +      "dev": true,
            +      "dependencies": {
            +        "batch": "0.5.0",
            +        "buffer-crc32": "0.2.1",
            +        "bytes": "0.2.1",
            +        "compressible": "1.0.0",
            +        "cookie": "0.1.0",
            +        "cookie-signature": "1.0.1",
            +        "debug": ">= 0.7.3 < 1",
            +        "fresh": "0.2.0",
            +        "methods": "0.1.0",
            +        "multiparty": "2.2.0",
            +        "negotiator": "0.3.0",
            +        "pause": "0.0.1",
            +        "qs": "0.6.6",
            +        "raw-body": "1.1.3",
            +        "send": "0.1.4",
            +        "uid2": "0.0.3"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/grunt-serve/node_modules/connect/node_modules/debug": {
            +      "version": "0.8.1",
            +      "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz",
            +      "integrity": "sha1-IP9NJvXkIstoobrLu2EDmtjBwTA=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/grunt-serve/node_modules/debug": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
            +      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
            +      "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
            +      "dev": true,
            +      "dependencies": {
            +        "ms": "^2.1.1"
            +      }
            +    },
            +    "node_modules/grunt-serve/node_modules/fresh": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.0.tgz",
            +      "integrity": "sha1-v9lALPPfEsSkwxDHn5mj3eE9NKc=",
            +      "dev": true
            +    },
            +    "node_modules/grunt-serve/node_modules/mime": {
            +      "version": "1.2.11",
            +      "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
            +      "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=",
            +      "dev": true
            +    },
            +    "node_modules/grunt-serve/node_modules/ms": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
            +      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
            +      "dev": true
            +    },
            +    "node_modules/grunt-serve/node_modules/qs": {
            +      "version": "0.6.6",
            +      "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz",
            +      "integrity": "sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/grunt-serve/node_modules/range-parser": {
            +      "version": "0.0.4",
            +      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-0.0.4.tgz",
            +      "integrity": "sha1-wEJ//vUcEKy6B4KkbJYC50T/Ygs=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/grunt-serve/node_modules/raw-body": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.3.tgz",
            +      "integrity": "sha1-PS+R4kSSWcxnuMPOnwYdtbmHk1s=",
            +      "dev": true,
            +      "dependencies": {
            +        "bytes": "~0.2.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/grunt-serve/node_modules/send": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/send/-/send-0.1.4.tgz",
            +      "integrity": "sha1-vnDY0b4B3mGCGvE3gLUDRaT3Gr0=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "*",
            +        "fresh": "0.2.0",
            +        "mime": "~1.2.9",
            +        "range-parser": "0.0.4"
            +      }
            +    },
            +    "node_modules/grunt-shell": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-3.0.1.tgz",
            +      "integrity": "sha512-C8eR4frw/NmIFIwSvzSLS4wOQBUzC+z6QhrKPzwt/tlaIqlzH35i/O2MggVOBj2Sh1tbaAqpASWxGiGsi4JMIQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.1",
            +        "npm-run-path": "^2.0.0",
            +        "strip-ansi": "^5.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">=1"
            +      }
            +    },
            +    "node_modules/grunt-shell/node_modules/ansi-regex": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
            +      "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/grunt-shell/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-shell/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-shell/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-shell/node_modules/strip-ansi": {
            +      "version": "5.2.0",
            +      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
            +      "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-regex": "^4.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/grunt-shell/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-uncss": {
            +      "version": "0.8.6",
            +      "resolved": "https://registry.npmjs.org/grunt-uncss/-/grunt-uncss-0.8.6.tgz",
            +      "integrity": "sha512-qidOnSszeErZl6roX+DxZ/N1HsbACbDEQsCBDkA9Vd/kkNG4F5k2TZodxKw758UjiPngjRto+9cQsmdhgfpgMA==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "maxmin": "^2.1.0",
            +        "uncss": "^0.16.2"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/grunt-uncss/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-uncss/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-uncss/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt-uncss/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/grunt/node_modules/findup-sync": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
            +      "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
            +      "dev": true,
            +      "dependencies": {
            +        "glob": "~5.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.6.0"
            +      }
            +    },
            +    "node_modules/grunt/node_modules/findup-sync/node_modules/glob": {
            +      "version": "5.0.15",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
            +      "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
            +      "dev": true,
            +      "dependencies": {
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "2 || 3",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/grunt/node_modules/glob": {
            +      "version": "7.1.7",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
            +      "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/grunt/node_modules/iconv-lite": {
            +      "version": "0.4.24",
            +      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
            +      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
            +      "dev": true,
            +      "dependencies": {
            +        "safer-buffer": ">= 2.1.2 < 3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/grunt/node_modules/mkdirp": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
            +      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
            +      "dev": true,
            +      "bin": {
            +        "mkdirp": "bin/cmd.js"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/grunt/node_modules/rimraf": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
            +      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
            +      "dev": true,
            +      "dependencies": {
            +        "glob": "^7.1.3"
            +      },
            +      "bin": {
            +        "rimraf": "bin.js"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/gulp-header": {
            +      "version": "1.8.12",
            +      "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz",
            +      "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==",
            +      "deprecated": "Removed event-stream from gulp-header",
            +      "dev": true,
            +      "dependencies": {
            +        "concat-with-sourcemaps": "*",
            +        "lodash.template": "^4.4.0",
            +        "through2": "^2.0.0"
            +      }
            +    },
            +    "node_modules/gulp-sourcemaps": {
            +      "version": "1.6.0",
            +      "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz",
            +      "integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=",
            +      "dev": true,
            +      "dependencies": {
            +        "convert-source-map": "^1.1.1",
            +        "graceful-fs": "^4.1.2",
            +        "strip-bom": "^2.0.0",
            +        "through2": "^2.0.0",
            +        "vinyl": "^1.0.0"
            +      }
            +    },
            +    "node_modules/gzip-size": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz",
            +      "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=",
            +      "dev": true,
            +      "dependencies": {
            +        "duplexer": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.12.0"
            +      }
            +    },
            +    "node_modules/handlebars": {
            +      "version": "4.7.7",
            +      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
            +      "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
            +      "dev": true,
            +      "dependencies": {
            +        "minimist": "^1.2.5",
            +        "neo-async": "^2.6.0",
            +        "source-map": "^0.6.1",
            +        "wordwrap": "^1.0.0"
            +      },
            +      "bin": {
            +        "handlebars": "bin/handlebars"
            +      },
            +      "engines": {
            +        "node": ">=0.4.7"
            +      },
            +      "optionalDependencies": {
            +        "uglify-js": "^3.1.4"
            +      }
            +    },
            +    "node_modules/handlebars-helper-i18n": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/handlebars-helper-i18n/-/handlebars-helper-i18n-0.1.0.tgz",
            +      "integrity": "sha1-YymyxjJkskUe6l+eJvr3tlavntU=",
            +      "dev": true
            +    },
            +    "node_modules/handlebars-helpers": {
            +      "version": "0.8.4",
            +      "resolved": "https://registry.npmjs.org/handlebars-helpers/-/handlebars-helpers-0.8.4.tgz",
            +      "integrity": "sha1-+YgLeujYkOYxoxRvAZBQAFxU7RI=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-filter": "^1.1.1",
            +        "arr-flatten": "^1.0.1",
            +        "array-sort": "^0.1.2",
            +        "create-frame": "^1.0.0",
            +        "define-property": "^0.2.5",
            +        "for-in": "^0.1.6",
            +        "for-own": "^0.1.4",
            +        "get-object": "^0.2.0",
            +        "get-value": "^2.0.6",
            +        "handlebars": "^4.0.6",
            +        "helper-date": "^0.2.3",
            +        "helper-markdown": "^0.2.1",
            +        "helper-md": "^0.2.2",
            +        "html-tag": "^1.0.0",
            +        "index-of": "^0.2.0",
            +        "is-even": "^0.1.1",
            +        "is-glob": "^3.1.0",
            +        "is-number": "^3.0.0",
            +        "is-odd": "^0.1.1",
            +        "kind-of": "^3.1.0",
            +        "lazy-cache": "^2.0.2",
            +        "logging-helpers": "^0.4.0",
            +        "make-iterator": "^0.3.0",
            +        "micromatch": "^2.3.11",
            +        "mixin-deep": "^1.1.3",
            +        "normalize-path": "^2.0.1",
            +        "relative": "^3.0.2",
            +        "striptags": "^2.1.1",
            +        "to-gfm-code-block": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/handlebars-helpers/node_modules/for-in": {
            +      "version": "0.1.8",
            +      "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz",
            +      "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/handlebars-helpers/node_modules/is-number": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
            +      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/handlebars-helpers/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/handlebars-helpers/node_modules/make-iterator": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-0.3.1.tgz",
            +      "integrity": "sha1-4calMrVGon8TlIoG+CUJsz25gRI=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/handlebars/node_modules/uglify-js": {
            +      "version": "3.13.9",
            +      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.9.tgz",
            +      "integrity": "sha512-wZbyTQ1w6Y7fHdt8sJnHfSIuWeDgk6B5rCb4E/AM6QNNPbOMIZph21PW5dRB3h7Df0GszN+t7RuUH6sWK5bF0g==",
            +      "dev": true,
            +      "optional": true,
            +      "bin": {
            +        "uglifyjs": "bin/uglifyjs"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/har-schema": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
            +      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/har-validator": {
            +      "version": "5.1.3",
            +      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
            +      "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
            +      "deprecated": "this library is no longer supported",
            +      "dev": true,
            +      "dependencies": {
            +        "ajv": "^6.5.5",
            +        "har-schema": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/har-validator/node_modules/ajv": {
            +      "version": "6.12.2",
            +      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
            +      "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "fast-deep-equal": "^3.1.1",
            +        "fast-json-stable-stringify": "^2.0.0",
            +        "json-schema-traverse": "^0.4.1",
            +        "uri-js": "^4.2.2"
            +      }
            +    },
            +    "node_modules/har-validator/node_modules/fast-deep-equal": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
            +      "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
            +      "dev": true
            +    },
            +    "node_modules/har-validator/node_modules/json-schema-traverse": {
            +      "version": "0.4.1",
            +      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
            +      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
            +      "dev": true
            +    },
            +    "node_modules/has": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
            +      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
            +      "dev": true,
            +      "dependencies": {
            +        "function-bind": "^1.1.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.4.0"
            +      }
            +    },
            +    "node_modules/has-ansi": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
            +      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-regex": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-color": {
            +      "version": "0.1.7",
            +      "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
            +      "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-flag": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
            +      "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-glob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-1.0.0.tgz",
            +      "integrity": "sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-own-deep": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/has-own-deep/-/has-own-deep-0.1.4.tgz",
            +      "integrity": "sha1-kesM2ieAgxWPgEKigxZDTpr+eHY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-symbol-support-x": {
            +      "version": "1.4.2",
            +      "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
            +      "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/has-symbols": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
            +      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.4"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/has-to-string-tag-x": {
            +      "version": "1.4.1",
            +      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
            +      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-symbol-support-x": "^1.4.1"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/has-unicode": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
            +      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/has-value": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
            +      "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
            +      "dev": true,
            +      "dependencies": {
            +        "get-value": "^2.0.3",
            +        "has-values": "^0.1.4",
            +        "isobject": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-value/node_modules/has-values": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
            +      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-value/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-values": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
            +      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^3.0.0",
            +        "kind-of": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-values/node_modules/is-number": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
            +      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/has-values/node_modules/kind-of": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
            +      "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/helper-cache": {
            +      "version": "0.7.2",
            +      "resolved": "https://registry.npmjs.org/helper-cache/-/helper-cache-0.7.2.tgz",
            +      "integrity": "sha1-AkVixLS4sqsqtTHQC+FuxJZRi5A=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "lazy-cache": "^0.2.3",
            +        "lodash.bind": "^3.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/helper-cache/node_modules/lazy-cache": {
            +      "version": "0.2.7",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
            +      "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/helper-date": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/helper-date/-/helper-date-0.2.3.tgz",
            +      "integrity": "sha1-2HDKu6BB0ynMhW2yC7jElnTj7yg=",
            +      "dev": true,
            +      "dependencies": {
            +        "date.js": "^0.3.1",
            +        "extend-shallow": "^2.0.1",
            +        "kind-of": "^3.1.0",
            +        "moment": "^2.17.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/helper-date/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/helper-markdown": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/helper-markdown/-/helper-markdown-0.2.2.tgz",
            +      "integrity": "sha1-ONt/dxhJ4wrpXJL8AhuutT8uMEA=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.0.0",
            +        "mixin-deep": "^1.1.3",
            +        "remarkable": "^1.6.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/helper-markdown/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/helper-md": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/helper-md/-/helper-md-0.2.2.tgz",
            +      "integrity": "sha1-wfWdflW7riM2L9ig6XFgeuxp1B8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ent": "^2.2.0",
            +        "extend-shallow": "^2.0.1",
            +        "fs-exists-sync": "^0.1.0",
            +        "remarkable": "^1.6.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/hex-color-regex": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
            +      "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
            +      "dev": true
            +    },
            +    "node_modules/homedir-polyfill": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
            +      "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
            +      "dev": true,
            +      "dependencies": {
            +        "parse-passwd": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/hooker": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
            +      "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/hosted-git-info": {
            +      "version": "2.7.1",
            +      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
            +      "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
            +      "dev": true
            +    },
            +    "node_modules/hsl-regex": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz",
            +      "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=",
            +      "dev": true
            +    },
            +    "node_modules/hsla-regex": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
            +      "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
            +      "dev": true
            +    },
            +    "node_modules/html-comment-regex": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
            +      "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/html-encoding-sniffer": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
            +      "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
            +      "dev": true,
            +      "dependencies": {
            +        "whatwg-encoding": "^1.0.1"
            +      }
            +    },
            +    "node_modules/html-tag": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/html-tag/-/html-tag-1.0.0.tgz",
            +      "integrity": "sha1-leVhKuyCvqko7URZX4VBRen34LU=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^3.0.0",
            +        "void-elements": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/html-tags": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-1.2.0.tgz",
            +      "integrity": "sha1-x43mW1Zjqll5id0rerSSANfk25g=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/http-cache-semantics": {
            +      "version": "3.8.1",
            +      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
            +      "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
            +      "dev": true
            +    },
            +    "node_modules/http-errors": {
            +      "version": "1.6.3",
            +      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
            +      "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
            +      "dev": true,
            +      "dependencies": {
            +        "depd": "~1.1.2",
            +        "inherits": "2.0.3",
            +        "setprototypeof": "1.1.0",
            +        "statuses": ">= 1.4.0 < 2"
            +      },
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/http-parser-js": {
            +      "version": "0.4.10",
            +      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz",
            +      "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=",
            +      "dev": true
            +    },
            +    "node_modules/http-signature": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
            +      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
            +      "dev": true,
            +      "dependencies": {
            +        "assert-plus": "^1.0.0",
            +        "jsprim": "^1.2.2",
            +        "sshpk": "^1.7.0"
            +      },
            +      "engines": {
            +        "node": ">=0.8",
            +        "npm": ">=1.3.7"
            +      }
            +    },
            +    "node_modules/https-browserify": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz",
            +      "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=",
            +      "dev": true
            +    },
            +    "node_modules/human-signals": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
            +      "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8.12.0"
            +      }
            +    },
            +    "node_modules/husky": {
            +      "version": "0.14.3",
            +      "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz",
            +      "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==",
            +      "dev": true,
            +      "hasInstallScript": true,
            +      "dependencies": {
            +        "is-ci": "^1.0.10",
            +        "normalize-path": "^1.0.0",
            +        "strip-indent": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/husky/node_modules/normalize-path": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz",
            +      "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/husky/node_modules/strip-indent": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
            +      "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/iconv-lite": {
            +      "version": "0.2.11",
            +      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz",
            +      "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/ieee754": {
            +      "version": "1.1.12",
            +      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz",
            +      "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==",
            +      "dev": true
            +    },
            +    "node_modules/ignore": {
            +      "version": "3.3.10",
            +      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
            +      "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
            +      "dev": true
            +    },
            +    "node_modules/iltorb": {
            +      "version": "2.4.5",
            +      "resolved": "https://registry.npmjs.org/iltorb/-/iltorb-2.4.5.tgz",
            +      "integrity": "sha512-EMCMl3LnnNSZJS5QrxyZmMTaAC4+TJkM5woD+xbpm9RB+mFYCr7C05GFE3TEGCsVQSVHmjX+3sf5AiwsylNInQ==",
            +      "deprecated": "The zlib module provides APIs for brotli compression/decompression starting with Node.js v10.16.0, please use it over iltorb",
            +      "dev": true,
            +      "hasInstallScript": true,
            +      "optional": true,
            +      "dependencies": {
            +        "detect-libc": "^1.0.3",
            +        "nan": "^2.14.0",
            +        "npmlog": "^4.1.2",
            +        "prebuild-install": "^5.3.3",
            +        "which-pm-runs": "^1.0.0"
            +      }
            +    },
            +    "node_modules/imagemin": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-6.1.0.tgz",
            +      "integrity": "sha512-8ryJBL1CN5uSHpiBMX0rJw79C9F9aJqMnjGnrd/1CafegpNuA81RBAAru/jQQEOWlOJJlpRnlcVFF6wq+Ist0A==",
            +      "dev": true,
            +      "dependencies": {
            +        "file-type": "^10.7.0",
            +        "globby": "^8.0.1",
            +        "make-dir": "^1.0.0",
            +        "p-pipe": "^1.1.0",
            +        "pify": "^4.0.1",
            +        "replace-ext": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/imagemin-gifsicle": {
            +      "version": "6.0.1",
            +      "resolved": "https://registry.npmjs.org/imagemin-gifsicle/-/imagemin-gifsicle-6.0.1.tgz",
            +      "integrity": "sha512-kuu47c6iKDQ6R9J10xCwL0lgs0+sMz3LRHqRcJ2CRBWdcNmo3T5hUaM8hSZfksptZXJLGKk8heSAvwtSdB1Fng==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "exec-buffer": "^3.0.0",
            +        "gifsicle": "^4.0.0",
            +        "is-gif": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/imagemin-jpegtran": {
            +      "version": "6.0.0",
            +      "resolved": "https://registry.npmjs.org/imagemin-jpegtran/-/imagemin-jpegtran-6.0.0.tgz",
            +      "integrity": "sha512-Ih+NgThzqYfEWv9t58EItncaaXIHR0u9RuhKa8CtVBlMBvY0dCIxgQJQCfwImA4AV1PMfmUKlkyIHJjb7V4z1g==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "exec-buffer": "^3.0.0",
            +        "is-jpg": "^2.0.0",
            +        "jpegtran-bin": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg": {
            +      "version": "9.0.0",
            +      "resolved": "https://registry.npmjs.org/imagemin-mozjpeg/-/imagemin-mozjpeg-9.0.0.tgz",
            +      "integrity": "sha512-TwOjTzYqCFRgROTWpVSt5UTT0JeCuzF1jswPLKALDd89+PmrJ2PdMMYeDLYZ1fs9cTovI9GJd68mRSnuVt691w==",
            +      "dev": true,
            +      "dependencies": {
            +        "execa": "^4.0.0",
            +        "is-jpg": "^2.0.0",
            +        "mozjpeg": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/cross-spawn": {
            +      "version": "7.0.3",
            +      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
            +      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-key": "^3.1.0",
            +        "shebang-command": "^2.0.0",
            +        "which": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/execa": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
            +      "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
            +      "dev": true,
            +      "dependencies": {
            +        "cross-spawn": "^7.0.0",
            +        "get-stream": "^5.0.0",
            +        "human-signals": "^1.1.1",
            +        "is-stream": "^2.0.0",
            +        "merge-stream": "^2.0.0",
            +        "npm-run-path": "^4.0.0",
            +        "onetime": "^5.1.0",
            +        "signal-exit": "^3.0.2",
            +        "strip-final-newline": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sindresorhus/execa?sponsor=1"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/get-stream": {
            +      "version": "5.2.0",
            +      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
            +      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
            +      "dev": true,
            +      "dependencies": {
            +        "pump": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/is-stream": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
            +      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/merge-stream": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
            +      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
            +      "dev": true
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/mimic-fn": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
            +      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/npm-run-path": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
            +      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-key": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/onetime": {
            +      "version": "5.1.2",
            +      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
            +      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
            +      "dev": true,
            +      "dependencies": {
            +        "mimic-fn": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/path-key": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
            +      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/shebang-command": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
            +      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
            +      "dev": true,
            +      "dependencies": {
            +        "shebang-regex": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/shebang-regex": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
            +      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-mozjpeg/node_modules/which": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
            +      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
            +      "dev": true,
            +      "dependencies": {
            +        "isexe": "^2.0.0"
            +      },
            +      "bin": {
            +        "node-which": "bin/node-which"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/imagemin-optipng": {
            +      "version": "6.0.0",
            +      "resolved": "https://registry.npmjs.org/imagemin-optipng/-/imagemin-optipng-6.0.0.tgz",
            +      "integrity": "sha512-FoD2sMXvmoNm/zKPOWdhKpWdFdF9qiJmKC17MxZJPH42VMAp17/QENI/lIuP7LCUnLVAloO3AUoTSNzfhpyd8A==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "exec-buffer": "^3.0.0",
            +        "is-png": "^1.0.0",
            +        "optipng-bin": "^5.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant": {
            +      "version": "9.0.2",
            +      "resolved": "https://registry.npmjs.org/imagemin-pngquant/-/imagemin-pngquant-9.0.2.tgz",
            +      "integrity": "sha512-cj//bKo8+Frd/DM8l6Pg9pws1pnDUjgb7ae++sUX1kUVdv2nrngPykhiUOgFeE0LGY/LmUbCf4egCHC4YUcZSg==",
            +      "dev": true,
            +      "dependencies": {
            +        "execa": "^4.0.0",
            +        "is-png": "^2.0.0",
            +        "is-stream": "^2.0.0",
            +        "ow": "^0.17.0",
            +        "pngquant-bin": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/cross-spawn": {
            +      "version": "7.0.3",
            +      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
            +      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-key": "^3.1.0",
            +        "shebang-command": "^2.0.0",
            +        "which": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/execa": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
            +      "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
            +      "dev": true,
            +      "dependencies": {
            +        "cross-spawn": "^7.0.0",
            +        "get-stream": "^5.0.0",
            +        "human-signals": "^1.1.1",
            +        "is-stream": "^2.0.0",
            +        "merge-stream": "^2.0.0",
            +        "npm-run-path": "^4.0.0",
            +        "onetime": "^5.1.0",
            +        "signal-exit": "^3.0.2",
            +        "strip-final-newline": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sindresorhus/execa?sponsor=1"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/get-stream": {
            +      "version": "5.2.0",
            +      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
            +      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
            +      "dev": true,
            +      "dependencies": {
            +        "pump": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/is-png": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-png/-/is-png-2.0.0.tgz",
            +      "integrity": "sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/is-stream": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
            +      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/merge-stream": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
            +      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
            +      "dev": true
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/mimic-fn": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
            +      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/npm-run-path": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
            +      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-key": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/onetime": {
            +      "version": "5.1.2",
            +      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
            +      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
            +      "dev": true,
            +      "dependencies": {
            +        "mimic-fn": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/path-key": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
            +      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/shebang-command": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
            +      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
            +      "dev": true,
            +      "dependencies": {
            +        "shebang-regex": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/shebang-regex": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
            +      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/imagemin-pngquant/node_modules/which": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
            +      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
            +      "dev": true,
            +      "dependencies": {
            +        "isexe": "^2.0.0"
            +      },
            +      "bin": {
            +        "node-which": "bin/node-which"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/imagemin-svgo": {
            +      "version": "7.0.0",
            +      "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-7.0.0.tgz",
            +      "integrity": "sha512-+iGJFaPIMx8TjFW6zN+EkOhlqcemdL7F3N3Y0wODvV2kCUBuUtZK7DRZc1+Zfu4U2W/lTMUyx2G8YMOrZntIWg==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "is-svg": "^3.0.0",
            +        "svgo": "^1.0.5"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/imagemin-svgo/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/imagemin-svgo/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/imagemin-svgo/node_modules/coa": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
            +      "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "@types/q": "^1.5.1",
            +        "chalk": "^2.4.1",
            +        "q": "^1.1.2"
            +      },
            +      "engines": {
            +        "node": ">= 4.0"
            +      }
            +    },
            +    "node_modules/imagemin-svgo/node_modules/csso": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.2.tgz",
            +      "integrity": "sha512-kS7/oeNVXkHWxby5tHVxlhjizRCSv8QdU7hB2FpdAibDU8FjTAolhNjKNTiLzXtUrKT6HwClE81yXwEk1309wg==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "css-tree": "1.0.0-alpha.37"
            +      },
            +      "engines": {
            +        "node": ">=8.0.0"
            +      }
            +    },
            +    "node_modules/imagemin-svgo/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "optional": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/imagemin-svgo/node_modules/is-svg": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
            +      "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "html-comment-regex": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/imagemin-svgo/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/imagemin-svgo/node_modules/svgo": {
            +      "version": "1.3.2",
            +      "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
            +      "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==",
            +      "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "chalk": "^2.4.1",
            +        "coa": "^2.0.2",
            +        "css-select": "^2.0.0",
            +        "css-select-base-adapter": "^0.1.1",
            +        "css-tree": "1.0.0-alpha.37",
            +        "csso": "^4.0.2",
            +        "js-yaml": "^3.13.1",
            +        "mkdirp": "~0.5.1",
            +        "object.values": "^1.1.0",
            +        "sax": "~1.2.4",
            +        "stable": "^0.1.8",
            +        "unquote": "~1.1.1",
            +        "util.promisify": "~1.0.0"
            +      },
            +      "bin": {
            +        "svgo": "bin/svgo"
            +      },
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/imagemin/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/imagemin/node_modules/globby": {
            +      "version": "8.0.2",
            +      "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz",
            +      "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==",
            +      "dev": true,
            +      "dependencies": {
            +        "array-union": "^1.0.1",
            +        "dir-glob": "2.0.0",
            +        "fast-glob": "^2.0.2",
            +        "glob": "^7.1.2",
            +        "ignore": "^3.3.5",
            +        "pify": "^3.0.0",
            +        "slash": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/imagemin/node_modules/globby/node_modules/pify": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
            +      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/imagemin/node_modules/pify": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
            +      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/imagemin/node_modules/replace-ext": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
            +      "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/import-fresh": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
            +      "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
            +      "dev": true,
            +      "dependencies": {
            +        "caller-path": "^2.0.0",
            +        "resolve-from": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/import-fresh/node_modules/caller-path": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
            +      "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "caller-callsite": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/import-fresh/node_modules/resolve-from": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
            +      "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/import-lazy": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz",
            +      "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/imurmurhash": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
            +      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8.19"
            +      }
            +    },
            +    "node_modules/indent-string": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
            +      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
            +      "dev": true,
            +      "dependencies": {
            +        "repeating": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/index-of": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/index-of/-/index-of-0.2.0.tgz",
            +      "integrity": "sha1-OMHiNn6lXf+tO261kuwcwwkNfWU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/indexes-of": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
            +      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
            +      "dev": true
            +    },
            +    "node_modules/inflection": {
            +      "version": "1.12.0",
            +      "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz",
            +      "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=",
            +      "dev": true,
            +      "engines": [
            +        "node >= 0.4.0"
            +      ]
            +    },
            +    "node_modules/inflight": {
            +      "version": "1.0.6",
            +      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
            +      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
            +      "dev": true,
            +      "dependencies": {
            +        "once": "^1.3.0",
            +        "wrappy": "1"
            +      }
            +    },
            +    "node_modules/info-symbol": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/info-symbol/-/info-symbol-0.1.0.tgz",
            +      "integrity": "sha1-J4QdcoZ920JCzWEtecEGM4gcang=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/inherits": {
            +      "version": "2.0.3",
            +      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
            +      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
            +      "dev": true
            +    },
            +    "node_modules/ini": {
            +      "version": "1.3.8",
            +      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
            +      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
            +      "dev": true
            +    },
            +    "node_modules/inquirer": {
            +      "version": "3.3.0",
            +      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
            +      "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-escapes": "^3.0.0",
            +        "chalk": "^2.0.0",
            +        "cli-cursor": "^2.1.0",
            +        "cli-width": "^2.0.0",
            +        "external-editor": "^2.0.4",
            +        "figures": "^2.0.0",
            +        "lodash": "^4.3.0",
            +        "mute-stream": "0.0.7",
            +        "run-async": "^2.2.0",
            +        "rx-lite": "^4.0.8",
            +        "rx-lite-aggregates": "^4.0.8",
            +        "string-width": "^2.1.0",
            +        "strip-ansi": "^4.0.0",
            +        "through": "^2.3.6"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/ansi-escapes": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
            +      "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/ansi-regex": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
            +      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/chalk": {
            +      "version": "2.4.1",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
            +      "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/cli-cursor": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
            +      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
            +      "dev": true,
            +      "dependencies": {
            +        "restore-cursor": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/cli-width": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
            +      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
            +      "dev": true
            +    },
            +    "node_modules/inquirer/node_modules/figures": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
            +      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
            +      "dev": true,
            +      "dependencies": {
            +        "escape-string-regexp": "^1.0.5"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/mute-stream": {
            +      "version": "0.0.7",
            +      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
            +      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
            +      "dev": true
            +    },
            +    "node_modules/inquirer/node_modules/onetime": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
            +      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "mimic-fn": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/restore-cursor": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
            +      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
            +      "dev": true,
            +      "dependencies": {
            +        "onetime": "^2.0.0",
            +        "signal-exit": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/run-async": {
            +      "version": "2.3.0",
            +      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
            +      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-promise": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.12.0"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/strip-ansi": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
            +      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-regex": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer/node_modules/supports-color": {
            +      "version": "5.4.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
            +      "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/inquirer2": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/inquirer2/-/inquirer2-0.1.1.tgz",
            +      "integrity": "sha1-vFQkqBQ1fEHmXi6Vf+U2ruqb8fY=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-escapes": "^1.1.1",
            +        "ansi-regex": "^2.0.0",
            +        "arr-flatten": "^1.0.1",
            +        "arr-pluck": "^0.1.0",
            +        "array-unique": "^0.2.1",
            +        "chalk": "^1.1.1",
            +        "cli-cursor": "^1.0.2",
            +        "cli-width": "^1.1.0",
            +        "extend-shallow": "^2.0.1",
            +        "figures": "^1.4.0",
            +        "is-number": "^2.1.0",
            +        "is-plain-object": "^2.0.1",
            +        "lazy-cache": "^1.0.3",
            +        "lodash.where": "^3.1.0",
            +        "readline2": "^1.0.1",
            +        "run-async": "^0.1.0",
            +        "rx-lite": "^4.0.7",
            +        "strip-color": "^0.1.0",
            +        "through2": "^2.0.0"
            +      }
            +    },
            +    "node_modules/inquirer2/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/interpret": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
            +      "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
            +      "dev": true
            +    },
            +    "node_modules/into-stream": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
            +      "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
            +      "dev": true,
            +      "dependencies": {
            +        "from2": "^2.1.1",
            +        "p-is-promise": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/irregular-plurals": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz",
            +      "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/is-absolute": {
            +      "version": "0.2.6",
            +      "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz",
            +      "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-relative": "^0.2.1",
            +        "is-windows": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-absolute-url": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
            +      "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-absolute/node_modules/is-windows": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
            +      "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-accessor-descriptor": {
            +      "version": "0.1.6",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
            +      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-accessor-descriptor/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-answer": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/is-answer/-/is-answer-0.1.1.tgz",
            +      "integrity": "sha1-zBwvGG+FzyZQIgveNZ2GIYfUnLY=",
            +      "dev": true,
            +      "dependencies": {
            +        "has-values": "^0.1.4",
            +        "is-primitive": "^2.0.0",
            +        "omit-empty": "^0.4.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-answer/node_modules/has-values": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
            +      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-arguments": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
            +      "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.4"
            +      }
            +    },
            +    "node_modules/is-arrayish": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
            +      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
            +      "dev": true
            +    },
            +    "node_modules/is-binary-buffer": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-binary-buffer/-/is-binary-buffer-1.0.0.tgz",
            +      "integrity": "sha1-vGAxKQtly/eZudlQK1D9U3VSQAc=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/is-buffer": {
            +      "version": "1.1.6",
            +      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
            +      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
            +      "dev": true
            +    },
            +    "node_modules/is-builtin-module": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
            +      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
            +      "dev": true,
            +      "dependencies": {
            +        "builtin-modules": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-callable": {
            +      "version": "1.1.5",
            +      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
            +      "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.4"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/is-ci": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
            +      "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
            +      "dev": true,
            +      "dependencies": {
            +        "ci-info": "^1.0.0"
            +      },
            +      "bin": {
            +        "is-ci": "bin.js"
            +      }
            +    },
            +    "node_modules/is-color-stop": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
            +      "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=",
            +      "dev": true,
            +      "dependencies": {
            +        "css-color-names": "^0.0.4",
            +        "hex-color-regex": "^1.1.0",
            +        "hsl-regex": "^1.0.0",
            +        "hsla-regex": "^1.0.0",
            +        "rgb-regex": "^1.0.1",
            +        "rgba-regex": "^1.0.0"
            +      }
            +    },
            +    "node_modules/is-core-module": {
            +      "version": "2.4.0",
            +      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
            +      "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
            +      "dev": true,
            +      "dependencies": {
            +        "has": "^1.0.3"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/is-data-descriptor": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
            +      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-data-descriptor/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-date-object": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
            +      "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.4"
            +      }
            +    },
            +    "node_modules/is-descriptor": {
            +      "version": "0.1.6",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
            +      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^0.1.6",
            +        "is-data-descriptor": "^0.1.4",
            +        "kind-of": "^5.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-directory": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
            +      "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-dotfile": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
            +      "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-equal-shallow": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
            +      "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-primitive": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-even": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/is-even/-/is-even-0.1.2.tgz",
            +      "integrity": "sha1-4EMqc3ny0gtuu8LLEeab6q8xzWM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-odd": "^0.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-extendable": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
            +      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-extglob": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
            +      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-finite": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
            +      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
            +      "dev": true,
            +      "dependencies": {
            +        "number-is-nan": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-fullwidth-code-point": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
            +      "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
            +      "dev": true,
            +      "dependencies": {
            +        "number-is-nan": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-generator": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/is-generator/-/is-generator-1.0.3.tgz",
            +      "integrity": "sha1-wUwhBX7TbjKNuANHlmxpP4hjifM=",
            +      "dev": true
            +    },
            +    "node_modules/is-gif": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/is-gif/-/is-gif-3.0.0.tgz",
            +      "integrity": "sha512-IqJ/jlbw5WJSNfwQ/lHEDXF8rxhRgF6ythk2oiEvhpG29F704eX9NO6TvPfMiq9DrbwgcEDnETYNcZDPewQoVw==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "file-type": "^10.4.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/is-glob": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
            +      "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-html": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/is-html/-/is-html-1.1.0.tgz",
            +      "integrity": "sha1-4E8cGNOUhRETlvmgJz6rUa8hhGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "html-tags": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-jpg": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-jpg/-/is-jpg-2.0.0.tgz",
            +      "integrity": "sha1-LhmX+m6RZuqsAkLarkQ0A+TvHZc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/is-natural-number": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
            +      "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=",
            +      "dev": true
            +    },
            +    "node_modules/is-number": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
            +      "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-number-like": {
            +      "version": "1.0.8",
            +      "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz",
            +      "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash.isfinite": "^3.3.2"
            +      }
            +    },
            +    "node_modules/is-number/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-obj": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
            +      "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-object": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
            +      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
            +      "dev": true
            +    },
            +    "node_modules/is-observable": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz",
            +      "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==",
            +      "dev": true,
            +      "dependencies": {
            +        "symbol-observable": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/is-odd": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-0.1.2.tgz",
            +      "integrity": "sha1-vFc7XONx7yqtbm9JeZtyvvE5eKc=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-odd/node_modules/is-number": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
            +      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-odd/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-path-cwd": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
            +      "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-path-in-cwd": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
            +      "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-path-inside": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-path-inside": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
            +      "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
            +      "dev": true,
            +      "dependencies": {
            +        "path-is-inside": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-plain-obj": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
            +      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-plain-object": {
            +      "version": "2.0.4",
            +      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
            +      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-png": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/is-png/-/is-png-1.1.0.tgz",
            +      "integrity": "sha1-1XSxK/J1wDUEVVcLDltXqwYgd84=",
            +      "dev": true,
            +      "optional": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-posix-bracket": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
            +      "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-primitive": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
            +      "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-promise": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
            +      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
            +      "dev": true
            +    },
            +    "node_modules/is-regex": {
            +      "version": "1.0.5",
            +      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
            +      "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has": "^1.0.3"
            +      },
            +      "engines": {
            +        "node": ">= 0.4"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/is-regexp": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
            +      "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-registered": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/is-registered/-/is-registered-0.1.5.tgz",
            +      "integrity": "sha1-HTRpd0GdZl4qxshAE1NWheb3b38=",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^0.2.5",
            +        "isobject": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-registered/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-relative": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz",
            +      "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-unc-path": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-resolvable": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
            +      "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
            +      "dev": true
            +    },
            +    "node_modules/is-retry-allowed": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
            +      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-stream": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
            +      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-symbol": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
            +      "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-symbols": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.4"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/is-typedarray": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
            +      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
            +      "dev": true
            +    },
            +    "node_modules/is-unc-path": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz",
            +      "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=",
            +      "dev": true,
            +      "dependencies": {
            +        "unc-path-regex": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-utf8": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
            +      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
            +      "dev": true
            +    },
            +    "node_modules/is-valid-app": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.3.0.tgz",
            +      "integrity": "sha1-eBBrdR88oyOF+0VJK/KUF7WZPIA=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.6.3",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.3.0",
            +        "lazy-cache": "^2.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-valid-glob": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz",
            +      "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-valid-instance": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.3.0.tgz",
            +      "integrity": "sha1-9KxzAjxNTYubw7PsPmZjBRbijp4=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^3.0.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-whitespace": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz",
            +      "integrity": "sha1-Fjnssb4DauxppUy7QBz77XEUq38=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-windows": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
            +      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/is-wsl": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
            +      "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/isarray": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
            +      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
            +      "dev": true
            +    },
            +    "node_modules/isexe": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
            +      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
            +      "dev": true
            +    },
            +    "node_modules/isobject": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
            +      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/isstream": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
            +      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
            +      "dev": true
            +    },
            +    "node_modules/isurl": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
            +      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-to-string-tag-x": "^1.2.0",
            +        "is-object": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 4"
            +      }
            +    },
            +    "node_modules/jest-docblock": {
            +      "version": "21.2.0",
            +      "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz",
            +      "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==",
            +      "dev": true
            +    },
            +    "node_modules/jpegtran-bin": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/jpegtran-bin/-/jpegtran-bin-4.0.0.tgz",
            +      "integrity": "sha512-2cRl1ism+wJUoYAYFt6O/rLBfpXNWG2dUWbgcEkTt5WGMnqI46eEro8T4C5zGROxKRqyKpCBSdHPvt5UYCtxaQ==",
            +      "dev": true,
            +      "hasInstallScript": true,
            +      "optional": true,
            +      "dependencies": {
            +        "bin-build": "^3.0.0",
            +        "bin-wrapper": "^4.0.0",
            +        "logalot": "^2.0.0"
            +      },
            +      "bin": {
            +        "jpegtran": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/js-base64": {
            +      "version": "2.4.8",
            +      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.8.tgz",
            +      "integrity": "sha512-hm2nYpDrwoO/OzBhdcqs/XGT6XjSuSSCVEpia+Kl2J6x4CYt5hISlVL/AYU1khoDXv0AQVgxtdJySb9gjAn56Q==",
            +      "dev": true
            +    },
            +    "node_modules/js-tokens": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
            +      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
            +      "dev": true
            +    },
            +    "node_modules/js-yaml": {
            +      "version": "3.14.1",
            +      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
            +      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
            +      "dev": true,
            +      "dependencies": {
            +        "argparse": "^1.0.7",
            +        "esprima": "^4.0.0"
            +      },
            +      "bin": {
            +        "js-yaml": "bin/js-yaml.js"
            +      }
            +    },
            +    "node_modules/jsbn": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
            +      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
            +      "dev": true
            +    },
            +    "node_modules/jsdom": {
            +      "version": "11.12.0",
            +      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz",
            +      "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==",
            +      "dev": true,
            +      "dependencies": {
            +        "abab": "^2.0.0",
            +        "acorn": "^5.5.3",
            +        "acorn-globals": "^4.1.0",
            +        "array-equal": "^1.0.0",
            +        "cssom": ">= 0.3.2 < 0.4.0",
            +        "cssstyle": "^1.0.0",
            +        "data-urls": "^1.0.0",
            +        "domexception": "^1.0.1",
            +        "escodegen": "^1.9.1",
            +        "html-encoding-sniffer": "^1.0.2",
            +        "left-pad": "^1.3.0",
            +        "nwsapi": "^2.0.7",
            +        "parse5": "4.0.0",
            +        "pn": "^1.1.0",
            +        "request": "^2.87.0",
            +        "request-promise-native": "^1.0.5",
            +        "sax": "^1.2.4",
            +        "symbol-tree": "^3.2.2",
            +        "tough-cookie": "^2.3.4",
            +        "w3c-hr-time": "^1.0.1",
            +        "webidl-conversions": "^4.0.2",
            +        "whatwg-encoding": "^1.0.3",
            +        "whatwg-mimetype": "^2.1.0",
            +        "whatwg-url": "^6.4.1",
            +        "ws": "^5.2.0",
            +        "xml-name-validator": "^3.0.0"
            +      }
            +    },
            +    "node_modules/json-buffer": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
            +      "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
            +      "dev": true
            +    },
            +    "node_modules/json-parse-better-errors": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
            +      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
            +      "dev": true
            +    },
            +    "node_modules/json-schema": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
            +      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
            +      "dev": true
            +    },
            +    "node_modules/json-schema-traverse": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
            +      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
            +      "dev": true
            +    },
            +    "node_modules/json-stable-stringify-without-jsonify": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
            +      "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
            +      "dev": true
            +    },
            +    "node_modules/json-stringify-safe": {
            +      "version": "5.0.1",
            +      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
            +      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
            +      "dev": true
            +    },
            +    "node_modules/jsonfile": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
            +      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "universalify": "^2.0.0"
            +      },
            +      "optionalDependencies": {
            +        "graceful-fs": "^4.1.6"
            +      }
            +    },
            +    "node_modules/jsprim": {
            +      "version": "1.4.1",
            +      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
            +      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
            +      "dev": true,
            +      "engines": [
            +        "node >=0.6.0"
            +      ],
            +      "dependencies": {
            +        "assert-plus": "1.0.0",
            +        "extsprintf": "1.3.0",
            +        "json-schema": "0.2.3",
            +        "verror": "1.10.0"
            +      }
            +    },
            +    "node_modules/keyv": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
            +      "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
            +      "dev": true,
            +      "dependencies": {
            +        "json-buffer": "3.0.0"
            +      }
            +    },
            +    "node_modules/kind-of": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
            +      "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/layouts": {
            +      "version": "0.12.1",
            +      "resolved": "https://registry.npmjs.org/layouts/-/layouts-0.12.1.tgz",
            +      "integrity": "sha1-a5mz8apT5eeMkOx11PSRpuD1cEM=",
            +      "dev": true,
            +      "dependencies": {
            +        "delimiter-regex": "^1.3.1",
            +        "falsey": "^0.3.0",
            +        "get-view": "^0.1.1",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/layouts/node_modules/delimiter-regex": {
            +      "version": "1.3.1",
            +      "resolved": "https://registry.npmjs.org/delimiter-regex/-/delimiter-regex-1.3.1.tgz",
            +      "integrity": "sha1-Y4XK4UAE28DBzY3//+uGPVGZnv8=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^1.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/layouts/node_modules/extend-shallow": {
            +      "version": "1.1.4",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
            +      "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/layouts/node_modules/kind-of": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
            +      "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/lazy-cache": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
            +      "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "set-getter": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/lazystream": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
            +      "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "readable-stream": "^2.0.5"
            +      },
            +      "engines": {
            +        "node": ">= 0.6.3"
            +      }
            +    },
            +    "node_modules/left-pad": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
            +      "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
            +      "deprecated": "use String.prototype.padStart()",
            +      "dev": true
            +    },
            +    "node_modules/levn": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
            +      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
            +      "dev": true,
            +      "dependencies": {
            +        "prelude-ls": "~1.1.2",
            +        "type-check": "~0.3.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/liftup": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz",
            +      "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend": "^3.0.2",
            +        "findup-sync": "^4.0.0",
            +        "fined": "^1.2.0",
            +        "flagged-respawn": "^1.0.1",
            +        "is-plain-object": "^2.0.4",
            +        "object.map": "^1.0.1",
            +        "rechoir": "^0.7.0",
            +        "resolve": "^1.19.0"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/liftup/node_modules/braces": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
            +      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
            +      "dev": true,
            +      "dependencies": {
            +        "fill-range": "^7.0.1"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/liftup/node_modules/fill-range": {
            +      "version": "7.0.1",
            +      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
            +      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "to-regex-range": "^5.0.1"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/liftup/node_modules/findup-sync": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz",
            +      "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "detect-file": "^1.0.0",
            +        "is-glob": "^4.0.0",
            +        "micromatch": "^4.0.2",
            +        "resolve-dir": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/liftup/node_modules/is-glob": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
            +      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^2.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/liftup/node_modules/is-number": {
            +      "version": "7.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
            +      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.12.0"
            +      }
            +    },
            +    "node_modules/liftup/node_modules/micromatch": {
            +      "version": "4.0.4",
            +      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
            +      "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
            +      "dev": true,
            +      "dependencies": {
            +        "braces": "^3.0.1",
            +        "picomatch": "^2.2.3"
            +      },
            +      "engines": {
            +        "node": ">=8.6"
            +      }
            +    },
            +    "node_modules/liftup/node_modules/picomatch": {
            +      "version": "2.3.0",
            +      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
            +      "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8.6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/jonschlinkert"
            +      }
            +    },
            +    "node_modules/liftup/node_modules/resolve": {
            +      "version": "1.20.0",
            +      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
            +      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-core-module": "^2.2.0",
            +        "path-parse": "^1.0.6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/liftup/node_modules/to-regex-range": {
            +      "version": "5.0.1",
            +      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
            +      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8.0"
            +      }
            +    },
            +    "node_modules/lint-staged": {
            +      "version": "9.5.0",
            +      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz",
            +      "integrity": "sha512-nawMob9cb/G1J98nb8v3VC/E8rcX1rryUYXVZ69aT9kde6YWX+uvNOEHY5yf2gcWcTJGiD0kqXmCnS3oD75GIA==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "commander": "^2.20.0",
            +        "cosmiconfig": "^5.2.1",
            +        "debug": "^4.1.1",
            +        "dedent": "^0.7.0",
            +        "del": "^5.0.0",
            +        "execa": "^2.0.3",
            +        "listr": "^0.14.3",
            +        "log-symbols": "^3.0.0",
            +        "micromatch": "^4.0.2",
            +        "normalize-path": "^3.0.0",
            +        "please-upgrade-node": "^3.1.1",
            +        "string-argv": "^0.3.0",
            +        "stringify-object": "^3.3.0"
            +      },
            +      "bin": {
            +        "lint-staged": "bin/lint-staged"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/@nodelib/fs.stat": {
            +      "version": "2.0.3",
            +      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
            +      "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/array-union": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
            +      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/braces": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
            +      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
            +      "dev": true,
            +      "dependencies": {
            +        "fill-range": "^7.0.1"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/commander": {
            +      "version": "2.20.3",
            +      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
            +      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
            +      "dev": true
            +    },
            +    "node_modules/lint-staged/node_modules/cosmiconfig": {
            +      "version": "5.2.1",
            +      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
            +      "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
            +      "dev": true,
            +      "dependencies": {
            +        "import-fresh": "^2.0.0",
            +        "is-directory": "^0.3.1",
            +        "js-yaml": "^3.13.1",
            +        "parse-json": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/cross-spawn": {
            +      "version": "7.0.1",
            +      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
            +      "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-key": "^3.1.0",
            +        "shebang-command": "^2.0.0",
            +        "which": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/debug": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
            +      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
            +      "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
            +      "dev": true,
            +      "dependencies": {
            +        "ms": "^2.1.1"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/del": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz",
            +      "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==",
            +      "dev": true,
            +      "dependencies": {
            +        "globby": "^10.0.1",
            +        "graceful-fs": "^4.2.2",
            +        "is-glob": "^4.0.1",
            +        "is-path-cwd": "^2.2.0",
            +        "is-path-inside": "^3.0.1",
            +        "p-map": "^3.0.0",
            +        "rimraf": "^3.0.0",
            +        "slash": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/dir-glob": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
            +      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-type": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/execa": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz",
            +      "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==",
            +      "dev": true,
            +      "dependencies": {
            +        "cross-spawn": "^7.0.0",
            +        "get-stream": "^5.0.0",
            +        "is-stream": "^2.0.0",
            +        "merge-stream": "^2.0.0",
            +        "npm-run-path": "^3.0.0",
            +        "onetime": "^5.1.0",
            +        "p-finally": "^2.0.0",
            +        "signal-exit": "^3.0.2",
            +        "strip-final-newline": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": "^8.12.0 || >=9.7.0"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/fast-glob": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz",
            +      "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==",
            +      "dev": true,
            +      "dependencies": {
            +        "@nodelib/fs.stat": "^2.0.2",
            +        "@nodelib/fs.walk": "^1.2.3",
            +        "glob-parent": "^5.1.0",
            +        "merge2": "^1.3.0",
            +        "micromatch": "^4.0.2"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/fill-range": {
            +      "version": "7.0.1",
            +      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
            +      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "to-regex-range": "^5.0.1"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/get-stream": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
            +      "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
            +      "dev": true,
            +      "dependencies": {
            +        "pump": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/glob-parent": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
            +      "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^4.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 6"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/globby": {
            +      "version": "10.0.2",
            +      "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
            +      "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
            +      "dev": true,
            +      "dependencies": {
            +        "@types/glob": "^7.1.1",
            +        "array-union": "^2.1.0",
            +        "dir-glob": "^3.0.1",
            +        "fast-glob": "^3.0.3",
            +        "glob": "^7.1.3",
            +        "ignore": "^5.1.1",
            +        "merge2": "^1.2.3",
            +        "slash": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/graceful-fs": {
            +      "version": "4.2.3",
            +      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
            +      "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
            +      "dev": true
            +    },
            +    "node_modules/lint-staged/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/ignore": {
            +      "version": "5.1.4",
            +      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
            +      "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 4"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/is-glob": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
            +      "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^2.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/is-number": {
            +      "version": "7.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
            +      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.12.0"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/is-path-cwd": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
            +      "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/is-path-inside": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
            +      "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/is-stream": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
            +      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/merge-stream": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
            +      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
            +      "dev": true
            +    },
            +    "node_modules/lint-staged/node_modules/micromatch": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
            +      "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "braces": "^3.0.1",
            +        "picomatch": "^2.0.5"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/mimic-fn": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
            +      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/ms": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
            +      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
            +      "dev": true
            +    },
            +    "node_modules/lint-staged/node_modules/normalize-path": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
            +      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/npm-run-path": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz",
            +      "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-key": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/onetime": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
            +      "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "mimic-fn": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/p-finally": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
            +      "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/p-map": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
            +      "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "aggregate-error": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/parse-json": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
            +      "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
            +      "dev": true,
            +      "dependencies": {
            +        "error-ex": "^1.3.1",
            +        "json-parse-better-errors": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/path-key": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
            +      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/path-type": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
            +      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/pump": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
            +      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
            +      "dev": true,
            +      "dependencies": {
            +        "end-of-stream": "^1.1.0",
            +        "once": "^1.3.1"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/rimraf": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
            +      "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
            +      "dev": true,
            +      "dependencies": {
            +        "glob": "^7.1.3"
            +      },
            +      "bin": {
            +        "rimraf": "bin.js"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/shebang-command": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
            +      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
            +      "dev": true,
            +      "dependencies": {
            +        "shebang-regex": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/shebang-regex": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
            +      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/slash": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
            +      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/to-regex-range": {
            +      "version": "5.0.1",
            +      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
            +      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8.0"
            +      }
            +    },
            +    "node_modules/lint-staged/node_modules/which": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
            +      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
            +      "dev": true,
            +      "dependencies": {
            +        "isexe": "^2.0.0"
            +      },
            +      "bin": {
            +        "node-which": "bin/node-which"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/listr": {
            +      "version": "0.14.3",
            +      "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz",
            +      "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==",
            +      "dev": true,
            +      "dependencies": {
            +        "@samverschueren/stream-to-observable": "^0.3.0",
            +        "is-observable": "^1.1.0",
            +        "is-promise": "^2.1.0",
            +        "is-stream": "^1.1.0",
            +        "listr-silent-renderer": "^1.1.1",
            +        "listr-update-renderer": "^0.5.0",
            +        "listr-verbose-renderer": "^0.5.0",
            +        "p-map": "^2.0.0",
            +        "rxjs": "^6.3.3"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/listr-silent-renderer": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz",
            +      "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-update-renderer": {
            +      "version": "0.5.0",
            +      "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz",
            +      "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.1.3",
            +        "cli-truncate": "^0.2.1",
            +        "elegant-spinner": "^1.0.1",
            +        "figures": "^1.7.0",
            +        "indent-string": "^3.0.0",
            +        "log-symbols": "^1.0.2",
            +        "log-update": "^2.3.0",
            +        "strip-ansi": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "peerDependencies": {
            +        "listr": "^0.14.2"
            +      }
            +    },
            +    "node_modules/listr-update-renderer/node_modules/indent-string": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
            +      "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-update-renderer/node_modules/log-symbols": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
            +      "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/listr-verbose-renderer": {
            +      "version": "0.5.0",
            +      "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz",
            +      "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.1",
            +        "cli-cursor": "^2.1.0",
            +        "date-fns": "^1.27.2",
            +        "figures": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-verbose-renderer/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-verbose-renderer/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-verbose-renderer/node_modules/cli-cursor": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
            +      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
            +      "dev": true,
            +      "dependencies": {
            +        "restore-cursor": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-verbose-renderer/node_modules/figures": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
            +      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
            +      "dev": true,
            +      "dependencies": {
            +        "escape-string-regexp": "^1.0.5"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-verbose-renderer/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-verbose-renderer/node_modules/onetime": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
            +      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "mimic-fn": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-verbose-renderer/node_modules/restore-cursor": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
            +      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
            +      "dev": true,
            +      "dependencies": {
            +        "onetime": "^2.0.0",
            +        "signal-exit": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr-verbose-renderer/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/listr/node_modules/p-map": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
            +      "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/livereload-js": {
            +      "version": "2.4.0",
            +      "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz",
            +      "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==",
            +      "dev": true
            +    },
            +    "node_modules/load-grunt-tasks": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-5.1.0.tgz",
            +      "integrity": "sha512-oNj0Jlka1TsfDe+9He0kcA1cRln+TMoTsEByW7ij6kyktNLxBKJtslCFEvFrLC2Dj0S19IWJh3fOCIjLby2Xrg==",
            +      "dev": true,
            +      "dependencies": {
            +        "arrify": "^2.0.1",
            +        "multimatch": "^4.0.0",
            +        "pkg-up": "^3.1.0",
            +        "resolve-pkg": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      },
            +      "peerDependencies": {
            +        "grunt": ">=1"
            +      }
            +    },
            +    "node_modules/load-grunt-tasks/node_modules/arrify": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
            +      "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/load-helpers": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/load-helpers/-/load-helpers-0.3.1.tgz",
            +      "integrity": "sha1-mai6BzYpAYJ8jmLJWwsLH+mDBUk=",
            +      "dev": true,
            +      "dependencies": {
            +        "component-emitter": "^1.2.1",
            +        "extend-shallow": "^2.0.1",
            +        "is-valid-glob": "^0.3.0",
            +        "lazy-cache": "^2.0.1",
            +        "matched": "^0.4.3",
            +        "resolve-dir": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-helpers/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-helpers/node_modules/expand-tilde": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
            +      "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
            +      "dev": true,
            +      "dependencies": {
            +        "os-homedir": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-helpers/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/load-helpers/node_modules/has-glob": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-0.1.1.tgz",
            +      "integrity": "sha1-omHEwqbGZ+DHe3AKfyl8Oe86pYk=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-helpers/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-helpers/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-helpers/node_modules/matched": {
            +      "version": "0.4.4",
            +      "resolved": "https://registry.npmjs.org/matched/-/matched-0.4.4.tgz",
            +      "integrity": "sha1-Vte36xgDPwz5vFLrIJD6x9weifo=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "async-array-reduce": "^0.2.0",
            +        "extend-shallow": "^2.0.1",
            +        "fs-exists-sync": "^0.1.0",
            +        "glob": "^7.0.5",
            +        "has-glob": "^0.1.1",
            +        "is-valid-glob": "^0.3.0",
            +        "lazy-cache": "^2.0.1",
            +        "resolve-dir": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.12.0"
            +      }
            +    },
            +    "node_modules/load-helpers/node_modules/resolve-dir": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
            +      "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^1.2.2",
            +        "global-modules": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-json-file": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
            +      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
            +      "dev": true,
            +      "dependencies": {
            +        "graceful-fs": "^4.1.2",
            +        "parse-json": "^2.2.0",
            +        "pify": "^2.0.0",
            +        "pinkie-promise": "^2.0.0",
            +        "strip-bom": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-pkg": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/load-pkg/-/load-pkg-3.0.1.tgz",
            +      "integrity": "sha1-kjCzfsBOVpADBgvFiVHj7VCNWU8=",
            +      "dev": true,
            +      "dependencies": {
            +        "find-pkg": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-templates": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/load-templates/-/load-templates-1.0.2.tgz",
            +      "integrity": "sha1-CfOOlcjvS/t4W9f8qOv9MrIwvIc=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "file-contents": "^1.0.0",
            +        "glob-parent": "^3.1.0",
            +        "is-glob": "^3.1.0",
            +        "kind-of": "^3.1.0",
            +        "lazy-cache": "^2.0.2",
            +        "matched": "^0.4.4",
            +        "vinyl": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/clone": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
            +      "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/clone-stats": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
            +      "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
            +      "dev": true
            +    },
            +    "node_modules/load-templates/node_modules/expand-tilde": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
            +      "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
            +      "dev": true,
            +      "dependencies": {
            +        "os-homedir": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/has-glob": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-0.1.1.tgz",
            +      "integrity": "sha1-omHEwqbGZ+DHe3AKfyl8Oe86pYk=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/has-glob/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/matched": {
            +      "version": "0.4.4",
            +      "resolved": "https://registry.npmjs.org/matched/-/matched-0.4.4.tgz",
            +      "integrity": "sha1-Vte36xgDPwz5vFLrIJD6x9weifo=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "async-array-reduce": "^0.2.0",
            +        "extend-shallow": "^2.0.1",
            +        "fs-exists-sync": "^0.1.0",
            +        "glob": "^7.0.5",
            +        "has-glob": "^0.1.1",
            +        "is-valid-glob": "^0.3.0",
            +        "lazy-cache": "^2.0.1",
            +        "resolve-dir": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.12.0"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/replace-ext": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
            +      "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/resolve-dir": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
            +      "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^1.2.2",
            +        "global-modules": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/load-templates/node_modules/vinyl": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
            +      "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
            +      "dev": true,
            +      "dependencies": {
            +        "clone": "^2.1.1",
            +        "clone-buffer": "^1.0.0",
            +        "clone-stats": "^1.0.0",
            +        "cloneable-readable": "^1.0.0",
            +        "remove-trailing-separator": "^1.0.1",
            +        "replace-ext": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/locate-path": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
            +      "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
            +      "dev": true,
            +      "dependencies": {
            +        "p-locate": "^3.0.0",
            +        "path-exists": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/locate-path/node_modules/path-exists": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
            +      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/lodash": {
            +      "version": "4.17.21",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
            +      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
            +      "dev": true
            +    },
            +    "node_modules/lodash._arrayfilter": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/lodash._arrayfilter/-/lodash._arrayfilter-3.0.0.tgz",
            +      "integrity": "sha1-LevhHuxp5dzG9LhhNxKKSPFSQjc=",
            +      "dev": true
            +    },
            +    "node_modules/lodash._basecallback": {
            +      "version": "3.3.1",
            +      "resolved": "https://registry.npmjs.org/lodash._basecallback/-/lodash._basecallback-3.3.1.tgz",
            +      "integrity": "sha1-t7K7Q9whYEJKIczybFfkQ3cqjic=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._baseisequal": "^3.0.0",
            +        "lodash._bindcallback": "^3.0.0",
            +        "lodash.isarray": "^3.0.0",
            +        "lodash.pairs": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash._baseeach": {
            +      "version": "3.0.4",
            +      "resolved": "https://registry.npmjs.org/lodash._baseeach/-/lodash._baseeach-3.0.4.tgz",
            +      "integrity": "sha1-z4cGVyyhROjZ11InyZDamC+TKvM=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash.keys": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash._basefilter": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/lodash._basefilter/-/lodash._basefilter-3.0.0.tgz",
            +      "integrity": "sha1-S3ZAPfDihtA9Xg9yle00QeEB0SE=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._baseeach": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash._baseisequal": {
            +      "version": "3.0.7",
            +      "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz",
            +      "integrity": "sha1-2AJfdjOdKTQnZ9zIh85cuVpbUfE=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash.isarray": "^3.0.0",
            +        "lodash.istypedarray": "^3.0.0",
            +        "lodash.keys": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash._baseismatch": {
            +      "version": "3.1.3",
            +      "resolved": "https://registry.npmjs.org/lodash._baseismatch/-/lodash._baseismatch-3.1.3.tgz",
            +      "integrity": "sha1-Byj8SO+hFpnT1fLXMEnyqxPED9U=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._baseisequal": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash._basematches": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/lodash._basematches/-/lodash._basematches-3.2.0.tgz",
            +      "integrity": "sha1-9H4D8H7CB4SrCWjQy2y1l+IQEVg=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._baseismatch": "^3.0.0",
            +        "lodash.pairs": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash._bindcallback": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
            +      "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=",
            +      "dev": true
            +    },
            +    "node_modules/lodash._createwrapper": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/lodash._createwrapper/-/lodash._createwrapper-3.2.0.tgz",
            +      "integrity": "sha1-30U+ZkFjIXuJWkVAZa8cR6DqPE0=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._root": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash._getnative": {
            +      "version": "3.9.1",
            +      "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
            +      "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
            +      "dev": true
            +    },
            +    "node_modules/lodash._reinterpolate": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
            +      "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
            +      "dev": true
            +    },
            +    "node_modules/lodash._replaceholders": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/lodash._replaceholders/-/lodash._replaceholders-3.0.0.tgz",
            +      "integrity": "sha1-iru3EmxDH37XRPe6rznwi8m9nVg=",
            +      "dev": true
            +    },
            +    "node_modules/lodash._root": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
            +      "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.assign": {
            +      "version": "4.2.0",
            +      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
            +      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.bind": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-3.1.0.tgz",
            +      "integrity": "sha1-+V9IY419i7tYVPkIJmUnmZ+/pLs=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._createwrapper": "^3.0.0",
            +        "lodash._replaceholders": "^3.0.0",
            +        "lodash.restparam": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash.filter": {
            +      "version": "4.6.0",
            +      "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz",
            +      "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.flatten": {
            +      "version": "4.4.0",
            +      "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
            +      "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.foreach": {
            +      "version": "4.5.0",
            +      "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
            +      "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.initial": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/lodash.initial/-/lodash.initial-4.1.1.tgz",
            +      "integrity": "sha1-5T9kiRJl3cQE6YbSwo93vtlDWRo=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.isarguments": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
            +      "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.isarray": {
            +      "version": "3.0.4",
            +      "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
            +      "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.isequal": {
            +      "version": "4.5.0",
            +      "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
            +      "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.isfinite": {
            +      "version": "3.3.2",
            +      "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz",
            +      "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.istypedarray": {
            +      "version": "3.0.6",
            +      "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz",
            +      "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.keys": {
            +      "version": "3.1.2",
            +      "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
            +      "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._getnative": "^3.0.0",
            +        "lodash.isarguments": "^3.0.0",
            +        "lodash.isarray": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash.last": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/lodash.last/-/lodash.last-3.0.0.tgz",
            +      "integrity": "sha1-JC9mMRLdTG5jcoxgo8kJ0b2tvUw=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.map": {
            +      "version": "4.6.0",
            +      "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
            +      "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.memoize": {
            +      "version": "4.1.2",
            +      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
            +      "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.pairs": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/lodash.pairs/-/lodash.pairs-3.0.1.tgz",
            +      "integrity": "sha1-u+CNV4bu6qCaFckevw3LfSvjJqk=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash.keys": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash.restparam": {
            +      "version": "3.6.1",
            +      "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
            +      "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.sortby": {
            +      "version": "4.7.0",
            +      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
            +      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.template": {
            +      "version": "4.5.0",
            +      "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
            +      "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._reinterpolate": "^3.0.0",
            +        "lodash.templatesettings": "^4.0.0"
            +      }
            +    },
            +    "node_modules/lodash.templatesettings": {
            +      "version": "4.2.0",
            +      "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
            +      "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._reinterpolate": "^3.0.0"
            +      }
            +    },
            +    "node_modules/lodash.uniq": {
            +      "version": "4.5.0",
            +      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
            +      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
            +      "dev": true
            +    },
            +    "node_modules/lodash.where": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/lodash.where/-/lodash.where-3.1.0.tgz",
            +      "integrity": "sha1-LnhLnJM2jV11qu4zLOF2Ai8rlVM=",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash._arrayfilter": "^3.0.0",
            +        "lodash._basecallback": "^3.0.0",
            +        "lodash._basefilter": "^3.0.0",
            +        "lodash._basematches": "^3.0.0",
            +        "lodash.isarray": "^3.0.0"
            +      }
            +    },
            +    "node_modules/log-ok": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/log-ok/-/log-ok-0.1.1.tgz",
            +      "integrity": "sha1-vqPdNqzQuKckDXhza1uXxlREozQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-green": "^0.1.1",
            +        "success-symbol": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/log-symbols": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
            +      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/log-symbols/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/log-symbols/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/log-symbols/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/log-symbols/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/log-update": {
            +      "version": "2.3.0",
            +      "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz",
            +      "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-escapes": "^3.0.0",
            +        "cli-cursor": "^2.0.0",
            +        "wrap-ansi": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/log-update/node_modules/ansi-escapes": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
            +      "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/log-update/node_modules/cli-cursor": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
            +      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
            +      "dev": true,
            +      "dependencies": {
            +        "restore-cursor": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/log-update/node_modules/onetime": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
            +      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "mimic-fn": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/log-update/node_modules/restore-cursor": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
            +      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
            +      "dev": true,
            +      "dependencies": {
            +        "onetime": "^2.0.0",
            +        "signal-exit": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/log-utils": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/log-utils/-/log-utils-0.2.1.tgz",
            +      "integrity": "sha1-pMIXoN2aUFFdm5ICBgkas9TgMc8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-colors": "^0.2.0",
            +        "error-symbol": "^0.1.0",
            +        "info-symbol": "^0.1.0",
            +        "log-ok": "^0.1.1",
            +        "success-symbol": "^0.1.0",
            +        "time-stamp": "^1.0.1",
            +        "warning-symbol": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/logalot": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/logalot/-/logalot-2.1.0.tgz",
            +      "integrity": "sha1-X46MkNME7fElMJUaVVSruMXj9VI=",
            +      "dev": true,
            +      "dependencies": {
            +        "figures": "^1.3.5",
            +        "squeak": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/logging-helpers": {
            +      "version": "0.4.0",
            +      "resolved": "https://registry.npmjs.org/logging-helpers/-/logging-helpers-0.4.0.tgz",
            +      "integrity": "sha1-AObVMWwjdn7BLhIA5PEsXgM+frA=",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/longest": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
            +      "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/lookup-path": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/lookup-path/-/lookup-path-0.3.1.tgz",
            +      "integrity": "sha1-pO8kEK4yZpr3AMTLfhsBCVCc8rg=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-absolute": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/loud-rejection": {
            +      "version": "1.6.0",
            +      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
            +      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
            +      "dev": true,
            +      "dependencies": {
            +        "currently-unhandled": "^0.4.1",
            +        "signal-exit": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/lower-case": {
            +      "version": "1.1.4",
            +      "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
            +      "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
            +      "dev": true
            +    },
            +    "node_modules/lowercase-keys": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
            +      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/lpad-align": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/lpad-align/-/lpad-align-1.1.2.tgz",
            +      "integrity": "sha1-IfYArBwwlcPG5JfuZyce4ISB/p4=",
            +      "dev": true,
            +      "dependencies": {
            +        "get-stdin": "^4.0.1",
            +        "indent-string": "^2.1.0",
            +        "longest": "^1.0.0",
            +        "meow": "^3.3.0"
            +      },
            +      "bin": {
            +        "lpad-align": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/lpad-align/node_modules/get-stdin": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
            +      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/lru-cache": {
            +      "version": "4.1.3",
            +      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
            +      "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
            +      "dev": true,
            +      "dependencies": {
            +        "pseudomap": "^1.0.2",
            +        "yallist": "^2.1.2"
            +      }
            +    },
            +    "node_modules/make-dir": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
            +      "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "pify": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/make-dir/node_modules/pify": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
            +      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/make-iterator": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
            +      "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/make-iterator/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-cache": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
            +      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-config": {
            +      "version": "0.5.0",
            +      "resolved": "https://registry.npmjs.org/map-config/-/map-config-0.5.0.tgz",
            +      "integrity": "sha1-FwJgfiZ696NwyKnQxiumUk/rb+U=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-unique": "^0.2.1",
            +        "async": "^1.5.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files": {
            +      "version": "0.8.2",
            +      "resolved": "https://registry.npmjs.org/map-files/-/map-files-0.8.2.tgz",
            +      "integrity": "sha1-wb8wAX7l9ZSPJZdAdqOvllOXg4E=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.0.0",
            +        "lazy-cache": "^1.0.4",
            +        "matched": "^0.4.1",
            +        "vinyl": "^1.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/expand-tilde": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
            +      "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
            +      "dev": true,
            +      "dependencies": {
            +        "os-homedir": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/has-glob": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-0.1.1.tgz",
            +      "integrity": "sha1-omHEwqbGZ+DHe3AKfyl8Oe86pYk=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/matched": {
            +      "version": "0.4.4",
            +      "resolved": "https://registry.npmjs.org/matched/-/matched-0.4.4.tgz",
            +      "integrity": "sha1-Vte36xgDPwz5vFLrIJD6x9weifo=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "async-array-reduce": "^0.2.0",
            +        "extend-shallow": "^2.0.1",
            +        "fs-exists-sync": "^0.1.0",
            +        "glob": "^7.0.5",
            +        "has-glob": "^0.1.1",
            +        "is-valid-glob": "^0.3.0",
            +        "lazy-cache": "^2.0.1",
            +        "resolve-dir": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.12.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/matched/node_modules/lazy-cache": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
            +      "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "set-getter": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-files/node_modules/resolve-dir": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
            +      "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^1.2.2",
            +        "global-modules": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-obj": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
            +      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-schema": {
            +      "version": "0.2.4",
            +      "resolved": "https://registry.npmjs.org/map-schema/-/map-schema-0.2.4.tgz",
            +      "integrity": "sha1-wZVRg0/DwHoEWXt6WvtEpHWvlbQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "collection-visit": "^0.2.3",
            +        "component-emitter": "^1.2.1",
            +        "debug": "^2.6.0",
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "get-value": "^2.0.6",
            +        "is-primitive": "^2.0.0",
            +        "kind-of": "^3.1.0",
            +        "lazy-cache": "^2.0.2",
            +        "log-utils": "^0.2.1",
            +        "longest": "^1.0.1",
            +        "mixin-deep": "^1.1.3",
            +        "object.omit": "^2.0.1",
            +        "object.pick": "^1.2.0",
            +        "omit-empty": "^0.4.1",
            +        "pad-right": "^0.2.2",
            +        "set-value": "^0.4.0",
            +        "sort-object-arrays": "^0.1.1",
            +        "union-value": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-schema/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-schema/node_modules/collection-visit": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-0.2.3.tgz",
            +      "integrity": "sha1-L2JIPK7MlfCDuaRUo+6eYTmteVc=",
            +      "dev": true,
            +      "dependencies": {
            +        "lazy-cache": "^2.0.1",
            +        "map-visit": "^0.1.5",
            +        "object-visit": "^0.3.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-schema/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-schema/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-schema/node_modules/map-visit": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-0.1.5.tgz",
            +      "integrity": "sha1-2+Q5J85VJbgN/BVzpE1oxR8mgWs=",
            +      "dev": true,
            +      "dependencies": {
            +        "lazy-cache": "^2.0.1",
            +        "object-visit": "^0.3.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-schema/node_modules/object-visit": {
            +      "version": "0.3.4",
            +      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-0.3.4.tgz",
            +      "integrity": "sha1-rhXPhvCy/dVRdxY2RIRSxUw9qCk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-schema/node_modules/union-value": {
            +      "version": "0.2.4",
            +      "resolved": "https://registry.npmjs.org/union-value/-/union-value-0.2.4.tgz",
            +      "integrity": "sha1-c3UVJ4ZnkFfns3qmdug0aPwCdPA=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "get-value": "^2.0.6",
            +        "is-extendable": "^0.1.1",
            +        "set-value": "^0.4.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/map-visit": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
            +      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
            +      "dev": true,
            +      "dependencies": {
            +        "object-visit": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/marked": {
            +      "version": "0.8.2",
            +      "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz",
            +      "integrity": "sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==",
            +      "dev": true,
            +      "bin": {
            +        "marked": "bin/marked"
            +      },
            +      "engines": {
            +        "node": ">= 8.16.2"
            +      }
            +    },
            +    "node_modules/match-file": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/match-file/-/match-file-0.2.2.tgz",
            +      "integrity": "sha1-Jua88bOQpmH2Em+visUB4z7M+uk=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^3.1.0",
            +        "isobject": "^3.0.0",
            +        "micromatch": "^2.3.11"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/matched": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/matched/-/matched-1.0.2.tgz",
            +      "integrity": "sha512-7ivM1jFZVTOOS77QsR+TtYHH0ecdLclMkqbf5qiJdX2RorqfhsL65QHySPZgDE0ZjHoh+mQUNHTanNXIlzXd0Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "async-array-reduce": "^0.2.1",
            +        "glob": "^7.1.2",
            +        "has-glob": "^1.0.0",
            +        "is-valid-glob": "^1.0.0",
            +        "resolve-dir": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.12.0"
            +      }
            +    },
            +    "node_modules/matched/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/matched/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/matched/node_modules/is-valid-glob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
            +      "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/math-random": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
            +      "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==",
            +      "dev": true
            +    },
            +    "node_modules/maxmin": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-2.1.0.tgz",
            +      "integrity": "sha1-TTsiCQPZXu5+t6x/qGTnLcCaMWY=",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.0.0",
            +        "figures": "^1.0.1",
            +        "gzip-size": "^3.0.0",
            +        "pretty-bytes": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.12"
            +      }
            +    },
            +    "node_modules/maxmin/node_modules/pretty-bytes": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz",
            +      "integrity": "sha1-J9AAjXeAY6C0gRuzXHnxvV1fvM8=",
            +      "dev": true,
            +      "dependencies": {
            +        "number-is-nan": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/mdn-data": {
            +      "version": "2.0.4",
            +      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
            +      "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
            +      "dev": true
            +    },
            +    "node_modules/meow": {
            +      "version": "3.7.0",
            +      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
            +      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
            +      "dev": true,
            +      "dependencies": {
            +        "camelcase-keys": "^2.0.0",
            +        "decamelize": "^1.1.2",
            +        "loud-rejection": "^1.0.0",
            +        "map-obj": "^1.0.1",
            +        "minimist": "^1.1.3",
            +        "normalize-package-data": "^2.3.4",
            +        "object-assign": "^4.0.1",
            +        "read-pkg-up": "^1.0.1",
            +        "redent": "^1.0.0",
            +        "trim-newlines": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/merge-deep": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.2.tgz",
            +      "integrity": "sha512-T7qC8kg4Zoti1cFd8Cr0M+qaZfOwjlPDEdZIIPPB2JZctjaPM4fX+i7HOId69tAti2fvO6X5ldfYUONDODsrkA==",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "clone-deep": "^0.2.4",
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/merge-deep/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/merge-deep/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/merge-stream": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz",
            +      "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=",
            +      "dev": true,
            +      "dependencies": {
            +        "readable-stream": "^2.0.1"
            +      }
            +    },
            +    "node_modules/merge-value": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/merge-value/-/merge-value-1.0.0.tgz",
            +      "integrity": "sha512-fJMmvat4NeKz63Uv9iHWcPDjCWcCkoiRoajRTEO8hlhUC6rwaHg0QCF9hBOTjZmm4JuglPckPSTtcuJL5kp0TQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "get-value": "^2.0.6",
            +        "is-extendable": "^1.0.0",
            +        "mixin-deep": "^1.2.0",
            +        "set-value": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/merge-value/node_modules/is-extendable": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
            +      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-object": "^2.0.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/merge-value/node_modules/set-value": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
            +      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "is-extendable": "^0.1.1",
            +        "is-plain-object": "^2.0.3",
            +        "split-string": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/merge-value/node_modules/set-value/node_modules/is-extendable": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
            +      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/merge2": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
            +      "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 6"
            +      }
            +    },
            +    "node_modules/methods": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz",
            +      "integrity": "sha1-M11Cnu/SG3us8unJIqjSvRSjDk8=",
            +      "dev": true
            +    },
            +    "node_modules/micromatch": {
            +      "version": "2.3.11",
            +      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
            +      "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-diff": "^2.0.0",
            +        "array-unique": "^0.2.1",
            +        "braces": "^1.8.2",
            +        "expand-brackets": "^0.1.4",
            +        "extglob": "^0.3.1",
            +        "filename-regex": "^2.0.0",
            +        "is-extglob": "^1.0.0",
            +        "is-glob": "^2.0.1",
            +        "kind-of": "^3.0.2",
            +        "normalize-path": "^2.0.1",
            +        "object.omit": "^2.0.0",
            +        "parse-glob": "^3.0.4",
            +        "regex-cache": "^0.4.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/micromatch/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/micromatch/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/micromatch/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/mime": {
            +      "version": "1.6.0",
            +      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
            +      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
            +      "dev": true,
            +      "bin": {
            +        "mime": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/mime-db": {
            +      "version": "1.35.0",
            +      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz",
            +      "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/mime-types": {
            +      "version": "2.1.19",
            +      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz",
            +      "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==",
            +      "dev": true,
            +      "dependencies": {
            +        "mime-db": "~1.35.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/mimic-fn": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
            +      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/mimic-response": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
            +      "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/minimatch": {
            +      "version": "3.0.4",
            +      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
            +      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
            +      "dev": true,
            +      "dependencies": {
            +        "brace-expansion": "^1.1.7"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/minimist": {
            +      "version": "1.2.5",
            +      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
            +      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
            +      "dev": true
            +    },
            +    "node_modules/mixin-deep": {
            +      "version": "1.3.2",
            +      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
            +      "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
            +      "dev": true,
            +      "dependencies": {
            +        "for-in": "^1.0.2",
            +        "is-extendable": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/mixin-deep/node_modules/is-extendable": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
            +      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-object": "^2.0.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/mixin-object": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz",
            +      "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=",
            +      "dev": true,
            +      "dependencies": {
            +        "for-in": "^0.1.3",
            +        "is-extendable": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/mixin-object/node_modules/for-in": {
            +      "version": "0.1.8",
            +      "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz",
            +      "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/mkdirp": {
            +      "version": "0.5.5",
            +      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
            +      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "minimist": "^1.2.5"
            +      },
            +      "bin": {
            +        "mkdirp": "bin/cmd.js"
            +      }
            +    },
            +    "node_modules/mkdirp-classic": {
            +      "version": "0.5.2",
            +      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz",
            +      "integrity": "sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g==",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/moment": {
            +      "version": "2.29.1",
            +      "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
            +      "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/morgan": {
            +      "version": "1.9.1",
            +      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
            +      "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
            +      "dev": true,
            +      "dependencies": {
            +        "basic-auth": "~2.0.0",
            +        "debug": "2.6.9",
            +        "depd": "~1.1.2",
            +        "on-finished": "~2.3.0",
            +        "on-headers": "~1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/mozjpeg": {
            +      "version": "7.0.0",
            +      "resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-7.0.0.tgz",
            +      "integrity": "sha512-mH7atSbIusVTO3A4H43sEdmveN3aWn54k6V0edefzCEvOsTrbjg5murY2TsNznaztWnIgaRbWxeLVp4IgKdedQ==",
            +      "dev": true,
            +      "hasInstallScript": true,
            +      "dependencies": {
            +        "bin-build": "^3.0.0",
            +        "bin-wrapper": "^4.0.0",
            +        "logalot": "^2.1.0"
            +      },
            +      "bin": {
            +        "mozjpeg": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/ms": {
            +      "version": "0.7.3",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz",
            +      "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=",
            +      "dev": true
            +    },
            +    "node_modules/multimatch": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
            +      "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "@types/minimatch": "^3.0.3",
            +        "array-differ": "^3.0.0",
            +        "array-union": "^2.1.0",
            +        "arrify": "^2.0.1",
            +        "minimatch": "^3.0.4"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/multimatch/node_modules/array-differ": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
            +      "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/multimatch/node_modules/array-union": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
            +      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/multimatch/node_modules/arrify": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
            +      "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/multiparty": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-2.2.0.tgz",
            +      "integrity": "sha1-pWfCrwAK0i3I8qZT2Rl4rh9TFvQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "readable-stream": "~1.1.9",
            +        "stream-counter": "~0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/multiparty/node_modules/isarray": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
            +      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
            +      "dev": true
            +    },
            +    "node_modules/multiparty/node_modules/readable-stream": {
            +      "version": "1.1.14",
            +      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
            +      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
            +      "dev": true,
            +      "dependencies": {
            +        "core-util-is": "~1.0.0",
            +        "inherits": "~2.0.1",
            +        "isarray": "0.0.1",
            +        "string_decoder": "~0.10.x"
            +      }
            +    },
            +    "node_modules/multiparty/node_modules/string_decoder": {
            +      "version": "0.10.31",
            +      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
            +      "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
            +      "dev": true
            +    },
            +    "node_modules/mute-stream": {
            +      "version": "0.0.5",
            +      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
            +      "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=",
            +      "dev": true
            +    },
            +    "node_modules/nan": {
            +      "version": "2.14.1",
            +      "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
            +      "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/nanomatch": {
            +      "version": "1.2.13",
            +      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
            +      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-diff": "^4.0.0",
            +        "array-unique": "^0.3.2",
            +        "define-property": "^2.0.2",
            +        "extend-shallow": "^3.0.2",
            +        "fragment-cache": "^0.2.1",
            +        "is-windows": "^1.0.2",
            +        "kind-of": "^6.0.2",
            +        "object.pick": "^1.3.0",
            +        "regex-not": "^1.0.0",
            +        "snapdragon": "^0.8.1",
            +        "to-regex": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanomatch/node_modules/arr-diff": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
            +      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanomatch/node_modules/array-unique": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
            +      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanomatch/node_modules/define-property": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
            +      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^1.0.2",
            +        "isobject": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanomatch/node_modules/extend-shallow": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
            +      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
            +      "dev": true,
            +      "dependencies": {
            +        "assign-symbols": "^1.0.0",
            +        "is-extendable": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanomatch/node_modules/is-accessor-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanomatch/node_modules/is-data-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanomatch/node_modules/is-descriptor": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
            +      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^1.0.0",
            +        "is-data-descriptor": "^1.0.0",
            +        "kind-of": "^6.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanomatch/node_modules/is-extendable": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
            +      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-object": "^2.0.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanomatch/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nanoseconds": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/nanoseconds/-/nanoseconds-0.1.0.tgz",
            +      "integrity": "sha1-aew5/NAOd6s6ct4KQzQoJM15Izo=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/napi-build-utils": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
            +      "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/natural-compare": {
            +      "version": "1.4.0",
            +      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
            +      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
            +      "dev": true
            +    },
            +    "node_modules/negotiator": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.3.0.tgz",
            +      "integrity": "sha1-cG1pLv7d9XTVfqn7GriaT6fuj2A=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/neo-async": {
            +      "version": "2.6.2",
            +      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
            +      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
            +      "dev": true
            +    },
            +    "node_modules/next-tick": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz",
            +      "integrity": "sha1-ddpKkn7liH45BliABltzNkE7MQ0=",
            +      "dev": true
            +    },
            +    "node_modules/nice-try": {
            +      "version": "1.0.5",
            +      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
            +      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
            +      "dev": true
            +    },
            +    "node_modules/no-case": {
            +      "version": "2.3.2",
            +      "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
            +      "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "lower-case": "^1.1.1"
            +      }
            +    },
            +    "node_modules/node-abi": {
            +      "version": "2.16.0",
            +      "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.16.0.tgz",
            +      "integrity": "sha512-+sa0XNlWDA6T+bDLmkCUYn6W5k5W6BPRL6mqzSCs6H/xUgtl4D5x2fORKDzopKiU6wsyn/+wXlRXwXeSp+mtoA==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "semver": "^5.4.1"
            +      }
            +    },
            +    "node_modules/node-http2": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/node-http2/-/node-http2-4.0.1.tgz",
            +      "integrity": "sha1-Fk/1O13SLITwrxQrh3xerraAmVk=",
            +      "dev": true,
            +      "dependencies": {
            +        "assert": "1.4.1",
            +        "events": "1.1.1",
            +        "https-browserify": "0.0.1",
            +        "setimmediate": "^1.0.5",
            +        "stream-browserify": "2.0.1",
            +        "timers-browserify": "2.0.2",
            +        "url": "^0.11.0",
            +        "websocket-stream": "^5.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.12.0"
            +      }
            +    },
            +    "node_modules/node-releases": {
            +      "version": "1.1.73",
            +      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz",
            +      "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==",
            +      "dev": true
            +    },
            +    "node_modules/noncharacters": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/noncharacters/-/noncharacters-1.1.0.tgz",
            +      "integrity": "sha1-rzPfMP1Q7TxTzSAiWPJa2pC1QNI=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/noop-logger": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
            +      "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/nopt": {
            +      "version": "3.0.6",
            +      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
            +      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
            +      "dev": true,
            +      "dependencies": {
            +        "abbrev": "1"
            +      },
            +      "bin": {
            +        "nopt": "bin/nopt.js"
            +      }
            +    },
            +    "node_modules/normalize-package-data": {
            +      "version": "2.4.0",
            +      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
            +      "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
            +      "dev": true,
            +      "dependencies": {
            +        "hosted-git-info": "^2.1.4",
            +        "is-builtin-module": "^1.0.0",
            +        "semver": "2 || 3 || 4 || 5",
            +        "validate-npm-package-license": "^3.0.1"
            +      }
            +    },
            +    "node_modules/normalize-path": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
            +      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
            +      "dev": true,
            +      "dependencies": {
            +        "remove-trailing-separator": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/normalize-pkg": {
            +      "version": "0.3.20",
            +      "resolved": "https://registry.npmjs.org/normalize-pkg/-/normalize-pkg-0.3.20.tgz",
            +      "integrity": "sha1-Luc3FJUXhQ2c7/WmI0r174nFFag=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "array-unique": "^0.3.2",
            +        "component-emitter": "^1.2.1",
            +        "export-files": "^2.1.1",
            +        "extend-shallow": "^2.0.1",
            +        "fs-exists-sync": "^0.1.0",
            +        "get-value": "^2.0.6",
            +        "kind-of": "^3.0.4",
            +        "lazy-cache": "^2.0.1",
            +        "map-schema": "^0.2.3",
            +        "minimist": "^1.2.0",
            +        "mixin-deep": "^1.1.3",
            +        "omit-empty": "^0.4.1",
            +        "parse-git-config": "^1.0.2",
            +        "repo-utils": "^0.3.6",
            +        "semver": "^5.3.0",
            +        "stringify-author": "^0.1.3",
            +        "write-json": "^0.2.2"
            +      },
            +      "bin": {
            +        "normalize-pkg": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/normalize-pkg/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/normalize-pkg/node_modules/array-unique": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
            +      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/normalize-pkg/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/normalize-range": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
            +      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/normalize-url": {
            +      "version": "3.3.0",
            +      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
            +      "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/now-and-later": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
            +      "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "once": "^1.3.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/npm-conf": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
            +      "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
            +      "dev": true,
            +      "dependencies": {
            +        "config-chain": "^1.1.11",
            +        "pify": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/npm-conf/node_modules/pify": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
            +      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/npm-run-path": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
            +      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
            +      "dev": true,
            +      "dependencies": {
            +        "path-key": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/npmlog": {
            +      "version": "4.1.2",
            +      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
            +      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "are-we-there-yet": "~1.1.2",
            +        "console-control-strings": "~1.1.0",
            +        "gauge": "~2.7.3",
            +        "set-blocking": "~2.0.0"
            +      }
            +    },
            +    "node_modules/nth-check": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
            +      "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
            +      "dev": true,
            +      "dependencies": {
            +        "boolbase": "~1.0.0"
            +      }
            +    },
            +    "node_modules/num2fraction": {
            +      "version": "1.2.2",
            +      "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
            +      "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
            +      "dev": true
            +    },
            +    "node_modules/number-is-nan": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
            +      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/nwsapi": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
            +      "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
            +      "dev": true
            +    },
            +    "node_modules/oauth-sign": {
            +      "version": "0.9.0",
            +      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
            +      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/object-assign": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
            +      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object-copy": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
            +      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
            +      "dev": true,
            +      "dependencies": {
            +        "copy-descriptor": "^0.1.0",
            +        "define-property": "^0.2.5",
            +        "kind-of": "^3.0.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object-copy/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object-inspect": {
            +      "version": "1.7.0",
            +      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
            +      "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
            +      "dev": true,
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/object-keys": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
            +      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.4"
            +      }
            +    },
            +    "node_modules/object-visit": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
            +      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object.assign": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
            +      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
            +      "dev": true,
            +      "dependencies": {
            +        "define-properties": "^1.1.2",
            +        "function-bind": "^1.1.1",
            +        "has-symbols": "^1.0.0",
            +        "object-keys": "^1.0.11"
            +      },
            +      "engines": {
            +        "node": ">= 0.4"
            +      }
            +    },
            +    "node_modules/object.defaults": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
            +      "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-each": "^1.0.1",
            +        "array-slice": "^1.0.0",
            +        "for-own": "^1.0.0",
            +        "isobject": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object.defaults/node_modules/array-slice": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
            +      "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object.defaults/node_modules/for-own": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
            +      "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
            +      "dev": true,
            +      "dependencies": {
            +        "for-in": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object.getownpropertydescriptors": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
            +      "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
            +      "dev": true,
            +      "dependencies": {
            +        "define-properties": "^1.1.3",
            +        "es-abstract": "^1.17.0-next.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/object.map": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
            +      "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
            +      "dev": true,
            +      "dependencies": {
            +        "for-own": "^1.0.0",
            +        "make-iterator": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object.map/node_modules/for-own": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
            +      "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
            +      "dev": true,
            +      "dependencies": {
            +        "for-in": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object.omit": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
            +      "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
            +      "dev": true,
            +      "dependencies": {
            +        "for-own": "^0.1.4",
            +        "is-extendable": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object.pick": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
            +      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/object.values": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz",
            +      "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==",
            +      "dev": true,
            +      "dependencies": {
            +        "define-properties": "^1.1.3",
            +        "es-abstract": "^1.17.0-next.1",
            +        "function-bind": "^1.1.1",
            +        "has": "^1.0.3"
            +      },
            +      "engines": {
            +        "node": ">= 0.4"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/omit-empty": {
            +      "version": "0.4.1",
            +      "resolved": "https://registry.npmjs.org/omit-empty/-/omit-empty-0.4.1.tgz",
            +      "integrity": "sha1-KUo3gvLLIMdJfEEitiN8ncwMY6s=",
            +      "dev": true,
            +      "dependencies": {
            +        "has-values": "^0.1.4",
            +        "kind-of": "^3.0.3",
            +        "reduce-object": "^0.1.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/omit-empty/node_modules/has-values": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
            +      "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/omit-empty/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/on-finished": {
            +      "version": "2.3.0",
            +      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
            +      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
            +      "dev": true,
            +      "dependencies": {
            +        "ee-first": "1.1.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8"
            +      }
            +    },
            +    "node_modules/on-finished/node_modules/ee-first": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
            +      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
            +      "dev": true
            +    },
            +    "node_modules/on-headers": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
            +      "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8"
            +      }
            +    },
            +    "node_modules/once": {
            +      "version": "1.4.0",
            +      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
            +      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
            +      "dev": true,
            +      "dependencies": {
            +        "wrappy": "1"
            +      }
            +    },
            +    "node_modules/onetime": {
            +      "version": "1.1.0",
            +      "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
            +      "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/opn": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
            +      "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-wsl": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/option-cache": {
            +      "version": "3.5.0",
            +      "resolved": "https://registry.npmjs.org/option-cache/-/option-cache-3.5.0.tgz",
            +      "integrity": "sha1-y3ZRVboqhhwRCf8m4qIOqgZhKys=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.3",
            +        "collection-visit": "^1.0.0",
            +        "component-emitter": "^1.2.1",
            +        "get-value": "^2.0.6",
            +        "has-value": "^0.3.1",
            +        "kind-of": "^3.2.2",
            +        "lazy-cache": "^2.0.2",
            +        "set-value": "^0.4.3",
            +        "to-object-path": "^0.3.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/option-cache/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/optionator": {
            +      "version": "0.8.2",
            +      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
            +      "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
            +      "dev": true,
            +      "dependencies": {
            +        "deep-is": "~0.1.3",
            +        "fast-levenshtein": "~2.0.4",
            +        "levn": "~0.3.0",
            +        "prelude-ls": "~1.1.2",
            +        "type-check": "~0.3.2",
            +        "wordwrap": "~1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/optionator/node_modules/wordwrap": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
            +      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
            +      "dev": true
            +    },
            +    "node_modules/optipng-bin": {
            +      "version": "5.1.0",
            +      "resolved": "https://registry.npmjs.org/optipng-bin/-/optipng-bin-5.1.0.tgz",
            +      "integrity": "sha512-9baoqZTNNmXQjq/PQTWEXbVV3AMO2sI/GaaqZJZ8SExfAzjijeAP7FEeT+TtyumSw7gr0PZtSUYB/Ke7iHQVKA==",
            +      "dev": true,
            +      "hasInstallScript": true,
            +      "optional": true,
            +      "dependencies": {
            +        "bin-build": "^3.0.0",
            +        "bin-wrapper": "^4.0.0",
            +        "logalot": "^2.0.0"
            +      },
            +      "bin": {
            +        "optipng": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/ordered-read-streams": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz",
            +      "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-stream": "^1.0.1",
            +        "readable-stream": "^2.0.1"
            +      }
            +    },
            +    "node_modules/os-filter-obj": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz",
            +      "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==",
            +      "dev": true,
            +      "dependencies": {
            +        "arch": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/os-homedir": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
            +      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/os-tmpdir": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
            +      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/osenv": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
            +      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
            +      "dev": true,
            +      "dependencies": {
            +        "os-homedir": "^1.0.0",
            +        "os-tmpdir": "^1.0.0"
            +      }
            +    },
            +    "node_modules/ow": {
            +      "version": "0.17.0",
            +      "resolved": "https://registry.npmjs.org/ow/-/ow-0.17.0.tgz",
            +      "integrity": "sha512-i3keDzDQP5lWIe4oODyDFey1qVrq2hXKTuTH2VpqwpYtzPiKZt2ziRI4NBQmgW40AnV5Euz17OyWweCb+bNEQA==",
            +      "dev": true,
            +      "dependencies": {
            +        "type-fest": "^0.11.0"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/p-cancelable": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
            +      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/p-event": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz",
            +      "integrity": "sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU=",
            +      "dev": true,
            +      "dependencies": {
            +        "p-timeout": "^1.1.1"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/p-finally": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
            +      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/p-is-promise": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
            +      "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/p-limit": {
            +      "version": "2.2.2",
            +      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
            +      "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "p-try": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/p-locate": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
            +      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "p-limit": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/p-map": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
            +      "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/p-map-series": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz",
            +      "integrity": "sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco=",
            +      "dev": true,
            +      "dependencies": {
            +        "p-reduce": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/p-pipe": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-1.2.0.tgz",
            +      "integrity": "sha1-SxoROZoRUgpneQ7loMHViB1r7+k=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/p-reduce": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz",
            +      "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/p-timeout": {
            +      "version": "1.2.1",
            +      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
            +      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
            +      "dev": true,
            +      "dependencies": {
            +        "p-finally": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/p-try": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
            +      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/pad-right": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz",
            +      "integrity": "sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=",
            +      "dev": true,
            +      "dependencies": {
            +        "repeat-string": "^1.5.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/paginationator": {
            +      "version": "0.1.4",
            +      "resolved": "https://registry.npmjs.org/paginationator/-/paginationator-0.1.4.tgz",
            +      "integrity": "sha1-hHht04UKrh8Ru7kRsMHghRtTgQY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-author": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-1.0.0.tgz",
            +      "integrity": "sha1-XsFZAGKXe9nLOWLpFzuHWGQ39d8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-filepath": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
            +      "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-absolute": "^1.0.0",
            +        "map-cache": "^0.2.0",
            +        "path-root": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/parse-filepath/node_modules/is-absolute": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
            +      "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-relative": "^1.0.0",
            +        "is-windows": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-filepath/node_modules/is-relative": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
            +      "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-unc-path": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-filepath/node_modules/is-unc-path": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
            +      "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "unc-path-regex": "^0.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-git-config": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-1.1.1.tgz",
            +      "integrity": "sha1-06mYQxcTL1c5hxK7pDjhKVkN34w=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "fs-exists-sync": "^0.1.0",
            +        "git-config-path": "^1.0.1",
            +        "ini": "^1.3.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-github-url": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-0.3.2.tgz",
            +      "integrity": "sha1-du8B6/4LHpwPSTZylSzGpM2csmA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-glob": {
            +      "version": "3.0.4",
            +      "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
            +      "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
            +      "dev": true,
            +      "dependencies": {
            +        "glob-base": "^0.3.0",
            +        "is-dotfile": "^1.0.0",
            +        "is-extglob": "^1.0.0",
            +        "is-glob": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-glob/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-glob/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-json": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
            +      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
            +      "dev": true,
            +      "dependencies": {
            +        "error-ex": "^1.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-ms": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
            +      "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse-passwd": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
            +      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parse5": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
            +      "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
            +      "dev": true
            +    },
            +    "node_modules/parser-front-matter": {
            +      "version": "1.6.4",
            +      "resolved": "https://registry.npmjs.org/parser-front-matter/-/parser-front-matter-1.6.4.tgz",
            +      "integrity": "sha512-eqtUnI5+COkf1CQOYo8FmykN5Zs+5Yr60f/7GcPgQDZEEjdE/VZ4WMaMo9g37foof8h64t/TH2Uvk2Sq0fDy/g==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "file-is-binary": "^1.0.0",
            +        "gray-matter": "^3.0.2",
            +        "isobject": "^3.0.1",
            +        "lazy-cache": "^2.0.2",
            +        "mixin-deep": "^1.2.0",
            +        "trim-leading-lines": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/parseurl": {
            +      "version": "1.3.3",
            +      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
            +      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8"
            +      }
            +    },
            +    "node_modules/pascalcase": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
            +      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/path-dirname": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
            +      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
            +      "dev": true
            +    },
            +    "node_modules/path-exists": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
            +      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
            +      "dev": true,
            +      "dependencies": {
            +        "pinkie-promise": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/path-is-absolute": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
            +      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/path-is-inside": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
            +      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
            +      "dev": true
            +    },
            +    "node_modules/path-key": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
            +      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/path-parse": {
            +      "version": "1.0.6",
            +      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
            +      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
            +      "dev": true
            +    },
            +    "node_modules/path-root": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
            +      "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
            +      "dev": true,
            +      "dependencies": {
            +        "path-root-regex": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/path-root-regex": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
            +      "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/path-to-regexp": {
            +      "version": "1.8.0",
            +      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
            +      "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "0.0.1"
            +      }
            +    },
            +    "node_modules/path-to-regexp/node_modules/isarray": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
            +      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
            +      "dev": true
            +    },
            +    "node_modules/path-type": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
            +      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
            +      "dev": true,
            +      "dependencies": {
            +        "graceful-fs": "^4.1.2",
            +        "pify": "^2.0.0",
            +        "pinkie-promise": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pause": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
            +      "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=",
            +      "dev": true
            +    },
            +    "node_modules/pend": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
            +      "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
            +      "dev": true
            +    },
            +    "node_modules/performance-now": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
            +      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
            +      "dev": true
            +    },
            +    "node_modules/picomatch": {
            +      "version": "2.2.1",
            +      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz",
            +      "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8.6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/jonschlinkert"
            +      }
            +    },
            +    "node_modules/pify": {
            +      "version": "2.3.0",
            +      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
            +      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pinkie": {
            +      "version": "2.0.4",
            +      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
            +      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pinkie-promise": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
            +      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
            +      "dev": true,
            +      "dependencies": {
            +        "pinkie": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/pkg-store/-/pkg-store-0.2.2.tgz",
            +      "integrity": "sha1-sfXA+GIKWf1mWGrMXiVvTCw3oNg=",
            +      "dev": true,
            +      "dependencies": {
            +        "cache-base": "^0.8.2",
            +        "kind-of": "^3.0.2",
            +        "lazy-cache": "^1.0.3",
            +        "union-value": "^0.2.3",
            +        "write-json": "^0.2.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/cache-base": {
            +      "version": "0.8.5",
            +      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-0.8.5.tgz",
            +      "integrity": "sha1-YM6zUEAh7O7HAR/TOEt/TpVym/o=",
            +      "dev": true,
            +      "dependencies": {
            +        "collection-visit": "^0.2.1",
            +        "component-emitter": "^1.2.1",
            +        "get-value": "^2.0.5",
            +        "has-value": "^0.3.1",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.1",
            +        "set-value": "^0.4.2",
            +        "to-object-path": "^0.3.0",
            +        "union-value": "^0.2.3",
            +        "unset-value": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/cache-base/node_modules/lazy-cache": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
            +      "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "set-getter": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/collection-visit": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-0.2.3.tgz",
            +      "integrity": "sha1-L2JIPK7MlfCDuaRUo+6eYTmteVc=",
            +      "dev": true,
            +      "dependencies": {
            +        "lazy-cache": "^2.0.1",
            +        "map-visit": "^0.1.5",
            +        "object-visit": "^0.3.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/collection-visit/node_modules/lazy-cache": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
            +      "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "set-getter": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/lazy-cache": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
            +      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/map-visit": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-0.1.5.tgz",
            +      "integrity": "sha1-2+Q5J85VJbgN/BVzpE1oxR8mgWs=",
            +      "dev": true,
            +      "dependencies": {
            +        "lazy-cache": "^2.0.1",
            +        "object-visit": "^0.3.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/map-visit/node_modules/lazy-cache": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz",
            +      "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "set-getter": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/object-visit": {
            +      "version": "0.3.4",
            +      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-0.3.4.tgz",
            +      "integrity": "sha1-rhXPhvCy/dVRdxY2RIRSxUw9qCk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/object-visit/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/union-value": {
            +      "version": "0.2.4",
            +      "resolved": "https://registry.npmjs.org/union-value/-/union-value-0.2.4.tgz",
            +      "integrity": "sha1-c3UVJ4ZnkFfns3qmdug0aPwCdPA=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "get-value": "^2.0.6",
            +        "is-extendable": "^0.1.1",
            +        "set-value": "^0.4.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-store/node_modules/unset-value": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-0.1.2.tgz",
            +      "integrity": "sha1-UGgQuGfyfCpabpsEgzYx9t5Y0xA=",
            +      "dev": true,
            +      "dependencies": {
            +        "has-value": "^0.3.1",
            +        "isobject": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pkg-up": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz",
            +      "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==",
            +      "dev": true,
            +      "dependencies": {
            +        "find-up": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/pkg-up/node_modules/find-up": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
            +      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
            +      "dev": true,
            +      "dependencies": {
            +        "locate-path": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/please-upgrade-node": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
            +      "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
            +      "dev": true,
            +      "dependencies": {
            +        "semver-compare": "^1.0.0"
            +      }
            +    },
            +    "node_modules/plugin-error": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz",
            +      "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-cyan": "^0.1.1",
            +        "ansi-red": "^0.1.1",
            +        "arr-diff": "^1.0.1",
            +        "arr-union": "^2.0.1",
            +        "extend-shallow": "^1.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/plugin-error/node_modules/arr-diff": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz",
            +      "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "array-slice": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/plugin-error/node_modules/extend-shallow": {
            +      "version": "1.1.4",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
            +      "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/plugin-error/node_modules/kind-of": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
            +      "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/plur": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz",
            +      "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==",
            +      "dev": true,
            +      "dependencies": {
            +        "irregular-plurals": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/pluralize": {
            +      "version": "7.0.0",
            +      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
            +      "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/pn": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
            +      "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
            +      "dev": true
            +    },
            +    "node_modules/pngquant-bin": {
            +      "version": "6.0.0",
            +      "resolved": "https://registry.npmjs.org/pngquant-bin/-/pngquant-bin-6.0.0.tgz",
            +      "integrity": "sha512-oXWAS9MQ9iiDAJRdAZ9KO1mC5UwhzKkJsmetiu0iqIjJuW7JsuLhmc4JdRm7uJkIWRzIAou/Vq2VcjfJwz30Ow==",
            +      "dev": true,
            +      "hasInstallScript": true,
            +      "dependencies": {
            +        "bin-build": "^3.0.0",
            +        "bin-wrapper": "^4.0.1",
            +        "execa": "^4.0.0",
            +        "logalot": "^2.0.0"
            +      },
            +      "bin": {
            +        "pngquant": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/cross-spawn": {
            +      "version": "7.0.3",
            +      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
            +      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-key": "^3.1.0",
            +        "shebang-command": "^2.0.0",
            +        "which": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/execa": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
            +      "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
            +      "dev": true,
            +      "dependencies": {
            +        "cross-spawn": "^7.0.0",
            +        "get-stream": "^5.0.0",
            +        "human-signals": "^1.1.1",
            +        "is-stream": "^2.0.0",
            +        "merge-stream": "^2.0.0",
            +        "npm-run-path": "^4.0.0",
            +        "onetime": "^5.1.0",
            +        "signal-exit": "^3.0.2",
            +        "strip-final-newline": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=10"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sindresorhus/execa?sponsor=1"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/get-stream": {
            +      "version": "5.2.0",
            +      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
            +      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
            +      "dev": true,
            +      "dependencies": {
            +        "pump": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/is-stream": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
            +      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/merge-stream": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
            +      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
            +      "dev": true
            +    },
            +    "node_modules/pngquant-bin/node_modules/mimic-fn": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
            +      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/npm-run-path": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
            +      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-key": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/onetime": {
            +      "version": "5.1.2",
            +      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
            +      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
            +      "dev": true,
            +      "dependencies": {
            +        "mimic-fn": "^2.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/path-key": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
            +      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/shebang-command": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
            +      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
            +      "dev": true,
            +      "dependencies": {
            +        "shebang-regex": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/shebang-regex": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
            +      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/pngquant-bin/node_modules/which": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
            +      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
            +      "dev": true,
            +      "dependencies": {
            +        "isexe": "^2.0.0"
            +      },
            +      "bin": {
            +        "node-which": "bin/node-which"
            +      },
            +      "engines": {
            +        "node": ">= 8"
            +      }
            +    },
            +    "node_modules/portscanner": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz",
            +      "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "^2.6.0",
            +        "is-number-like": "^1.0.3"
            +      },
            +      "engines": {
            +        "node": ">=0.4",
            +        "npm": ">=1.0.0"
            +      }
            +    },
            +    "node_modules/portscanner/node_modules/async": {
            +      "version": "2.6.3",
            +      "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
            +      "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash": "^4.17.14"
            +      }
            +    },
            +    "node_modules/posix-character-classes": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
            +      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/postcss": {
            +      "version": "5.2.18",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
            +      "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.1.3",
            +        "js-base64": "^2.1.9",
            +        "source-map": "^0.5.6",
            +        "supports-color": "^3.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.12"
            +      }
            +    },
            +    "node_modules/postcss-calc": {
            +      "version": "7.0.5",
            +      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz",
            +      "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.27",
            +        "postcss-selector-parser": "^6.0.2",
            +        "postcss-value-parser": "^4.0.2"
            +      }
            +    },
            +    "node_modules/postcss-calc/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-calc/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-calc/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-calc/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-calc/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-calc/node_modules/postcss-value-parser": {
            +      "version": "4.1.0",
            +      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
            +      "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
            +      "dev": true
            +    },
            +    "node_modules/postcss-calc/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-colormin": {
            +      "version": "4.0.3",
            +      "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz",
            +      "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==",
            +      "dev": true,
            +      "dependencies": {
            +        "browserslist": "^4.0.0",
            +        "color": "^3.0.0",
            +        "has": "^1.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-colormin/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-colormin/node_modules/browserslist": {
            +      "version": "4.16.6",
            +      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
            +      "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "caniuse-lite": "^1.0.30001219",
            +        "colorette": "^1.2.2",
            +        "electron-to-chromium": "^1.3.723",
            +        "escalade": "^3.1.1",
            +        "node-releases": "^1.1.71"
            +      },
            +      "bin": {
            +        "browserslist": "cli.js"
            +      },
            +      "engines": {
            +        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/browserslist"
            +      }
            +    },
            +    "node_modules/postcss-colormin/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-colormin/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-colormin/node_modules/electron-to-chromium": {
            +      "version": "1.3.752",
            +      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz",
            +      "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==",
            +      "dev": true
            +    },
            +    "node_modules/postcss-colormin/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-colormin/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-colormin/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-convert-values": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz",
            +      "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-convert-values/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-convert-values/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-convert-values/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-convert-values/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-convert-values/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-convert-values/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-discard-comments": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz",
            +      "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-discard-comments/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-comments/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-comments/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-comments/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-comments/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-discard-comments/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-discard-duplicates": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz",
            +      "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-discard-duplicates/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-duplicates/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-duplicates/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-duplicates/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-duplicates/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-discard-duplicates/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-discard-empty": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz",
            +      "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-discard-empty/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-empty/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-empty/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-empty/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-empty/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-discard-empty/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-discard-overridden": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz",
            +      "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-discard-overridden/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-overridden/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-overridden/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-overridden/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-discard-overridden/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-discard-overridden/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-merge-longhand": {
            +      "version": "4.0.11",
            +      "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz",
            +      "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==",
            +      "dev": true,
            +      "dependencies": {
            +        "css-color-names": "0.0.4",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0",
            +        "stylehacks": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-merge-longhand/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-merge-longhand/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-merge-longhand/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-merge-longhand/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-merge-longhand/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-merge-longhand/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-merge-rules": {
            +      "version": "4.0.3",
            +      "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz",
            +      "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "browserslist": "^4.0.0",
            +        "caniuse-api": "^3.0.0",
            +        "cssnano-util-same-parent": "^4.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-selector-parser": "^3.0.0",
            +        "vendors": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-merge-rules/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-merge-rules/node_modules/browserslist": {
            +      "version": "4.16.6",
            +      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
            +      "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "caniuse-lite": "^1.0.30001219",
            +        "colorette": "^1.2.2",
            +        "electron-to-chromium": "^1.3.723",
            +        "escalade": "^3.1.1",
            +        "node-releases": "^1.1.71"
            +      },
            +      "bin": {
            +        "browserslist": "cli.js"
            +      },
            +      "engines": {
            +        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/browserslist"
            +      }
            +    },
            +    "node_modules/postcss-merge-rules/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-merge-rules/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-merge-rules/node_modules/electron-to-chromium": {
            +      "version": "1.3.752",
            +      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz",
            +      "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==",
            +      "dev": true
            +    },
            +    "node_modules/postcss-merge-rules/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-merge-rules/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": {
            +      "version": "3.1.2",
            +      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
            +      "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
            +      "dev": true,
            +      "dependencies": {
            +        "dot-prop": "^5.2.0",
            +        "indexes-of": "^1.0.1",
            +        "uniq": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/postcss-merge-rules/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-minify-font-values": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz",
            +      "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-minify-font-values/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-font-values/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-font-values/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-font-values/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-font-values/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-minify-font-values/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-minify-gradients": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz",
            +      "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "cssnano-util-get-arguments": "^4.0.0",
            +        "is-color-stop": "^1.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-minify-gradients/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-gradients/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-gradients/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-gradients/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-gradients/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-minify-gradients/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-minify-params": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz",
            +      "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==",
            +      "dev": true,
            +      "dependencies": {
            +        "alphanum-sort": "^1.0.0",
            +        "browserslist": "^4.0.0",
            +        "cssnano-util-get-arguments": "^4.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0",
            +        "uniqs": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-minify-params/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-params/node_modules/browserslist": {
            +      "version": "4.16.6",
            +      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
            +      "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "caniuse-lite": "^1.0.30001219",
            +        "colorette": "^1.2.2",
            +        "electron-to-chromium": "^1.3.723",
            +        "escalade": "^3.1.1",
            +        "node-releases": "^1.1.71"
            +      },
            +      "bin": {
            +        "browserslist": "cli.js"
            +      },
            +      "engines": {
            +        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/browserslist"
            +      }
            +    },
            +    "node_modules/postcss-minify-params/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-params/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-params/node_modules/electron-to-chromium": {
            +      "version": "1.3.752",
            +      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz",
            +      "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==",
            +      "dev": true
            +    },
            +    "node_modules/postcss-minify-params/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-params/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-minify-params/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-minify-selectors": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz",
            +      "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==",
            +      "dev": true,
            +      "dependencies": {
            +        "alphanum-sort": "^1.0.0",
            +        "has": "^1.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-selector-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-minify-selectors/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-selectors/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-selectors/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-selectors/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-minify-selectors/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": {
            +      "version": "3.1.2",
            +      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
            +      "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
            +      "dev": true,
            +      "dependencies": {
            +        "dot-prop": "^5.2.0",
            +        "indexes-of": "^1.0.1",
            +        "uniq": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/postcss-minify-selectors/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-normalize-charset": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz",
            +      "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-normalize-charset/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-charset/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-charset/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-charset/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-charset/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-normalize-charset/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-normalize-display-values": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz",
            +      "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "cssnano-util-get-match": "^4.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-normalize-display-values/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-display-values/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-display-values/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-display-values/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-display-values/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-normalize-display-values/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-normalize-positions": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz",
            +      "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==",
            +      "dev": true,
            +      "dependencies": {
            +        "cssnano-util-get-arguments": "^4.0.0",
            +        "has": "^1.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-normalize-positions/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-positions/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-positions/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-positions/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-positions/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-normalize-positions/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-normalize-repeat-style": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz",
            +      "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "cssnano-util-get-arguments": "^4.0.0",
            +        "cssnano-util-get-match": "^4.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-normalize-repeat-style/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-repeat-style/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-repeat-style/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-repeat-style/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-repeat-style/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-normalize-repeat-style/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-normalize-string": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz",
            +      "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==",
            +      "dev": true,
            +      "dependencies": {
            +        "has": "^1.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-normalize-string/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-string/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-string/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-string/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-string/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-normalize-string/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-normalize-timing-functions": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz",
            +      "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==",
            +      "dev": true,
            +      "dependencies": {
            +        "cssnano-util-get-match": "^4.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-normalize-timing-functions/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-timing-functions/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-timing-functions/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-timing-functions/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-timing-functions/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-normalize-timing-functions/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-normalize-unicode": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz",
            +      "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==",
            +      "dev": true,
            +      "dependencies": {
            +        "browserslist": "^4.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-normalize-unicode/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-unicode/node_modules/browserslist": {
            +      "version": "4.16.6",
            +      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
            +      "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "caniuse-lite": "^1.0.30001219",
            +        "colorette": "^1.2.2",
            +        "electron-to-chromium": "^1.3.723",
            +        "escalade": "^3.1.1",
            +        "node-releases": "^1.1.71"
            +      },
            +      "bin": {
            +        "browserslist": "cli.js"
            +      },
            +      "engines": {
            +        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/browserslist"
            +      }
            +    },
            +    "node_modules/postcss-normalize-unicode/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-unicode/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-unicode/node_modules/electron-to-chromium": {
            +      "version": "1.3.752",
            +      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz",
            +      "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==",
            +      "dev": true
            +    },
            +    "node_modules/postcss-normalize-unicode/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-unicode/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-normalize-unicode/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-normalize-url": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz",
            +      "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-absolute-url": "^2.0.0",
            +        "normalize-url": "^3.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-normalize-url/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-url/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-url/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-url/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-url/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-normalize-url/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-normalize-whitespace": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz",
            +      "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-normalize-whitespace/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-whitespace/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-whitespace/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-whitespace/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-normalize-whitespace/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-normalize-whitespace/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-ordered-values": {
            +      "version": "4.1.2",
            +      "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz",
            +      "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==",
            +      "dev": true,
            +      "dependencies": {
            +        "cssnano-util-get-arguments": "^4.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-ordered-values/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-ordered-values/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-ordered-values/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-ordered-values/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-ordered-values/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-ordered-values/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-reduce-initial": {
            +      "version": "4.0.3",
            +      "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz",
            +      "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==",
            +      "dev": true,
            +      "dependencies": {
            +        "browserslist": "^4.0.0",
            +        "caniuse-api": "^3.0.0",
            +        "has": "^1.0.0",
            +        "postcss": "^7.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-reduce-initial/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-reduce-initial/node_modules/browserslist": {
            +      "version": "4.16.6",
            +      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
            +      "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "caniuse-lite": "^1.0.30001219",
            +        "colorette": "^1.2.2",
            +        "electron-to-chromium": "^1.3.723",
            +        "escalade": "^3.1.1",
            +        "node-releases": "^1.1.71"
            +      },
            +      "bin": {
            +        "browserslist": "cli.js"
            +      },
            +      "engines": {
            +        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/browserslist"
            +      }
            +    },
            +    "node_modules/postcss-reduce-initial/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-reduce-initial/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-reduce-initial/node_modules/electron-to-chromium": {
            +      "version": "1.3.752",
            +      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz",
            +      "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==",
            +      "dev": true
            +    },
            +    "node_modules/postcss-reduce-initial/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-reduce-initial/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-reduce-initial/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-reduce-transforms": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz",
            +      "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==",
            +      "dev": true,
            +      "dependencies": {
            +        "cssnano-util-get-match": "^4.0.0",
            +        "has": "^1.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-reduce-transforms/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-reduce-transforms/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-reduce-transforms/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-reduce-transforms/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-reduce-transforms/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-reduce-transforms/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-selector-parser": {
            +      "version": "6.0.6",
            +      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz",
            +      "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==",
            +      "dev": true,
            +      "dependencies": {
            +        "cssesc": "^3.0.0",
            +        "util-deprecate": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-svgo": {
            +      "version": "4.0.3",
            +      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz",
            +      "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==",
            +      "dev": true,
            +      "dependencies": {
            +        "postcss": "^7.0.0",
            +        "postcss-value-parser": "^3.0.0",
            +        "svgo": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-svgo/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-svgo/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-svgo/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-svgo/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-svgo/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-svgo/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-unique-selectors": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz",
            +      "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==",
            +      "dev": true,
            +      "dependencies": {
            +        "alphanum-sort": "^1.0.0",
            +        "postcss": "^7.0.0",
            +        "uniqs": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/postcss-unique-selectors/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-unique-selectors/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-unique-selectors/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-unique-selectors/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/postcss-unique-selectors/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/postcss-unique-selectors/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/postcss-value-parser": {
            +      "version": "3.3.0",
            +      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
            +      "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
            +      "dev": true
            +    },
            +    "node_modules/postcss/node_modules/source-map": {
            +      "version": "0.5.7",
            +      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
            +      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/postcss/node_modules/supports-color": {
            +      "version": "3.2.3",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
            +      "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/prebuild-install": {
            +      "version": "5.3.3",
            +      "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz",
            +      "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "detect-libc": "^1.0.3",
            +        "expand-template": "^2.0.3",
            +        "github-from-package": "0.0.0",
            +        "minimist": "^1.2.0",
            +        "mkdirp": "^0.5.1",
            +        "napi-build-utils": "^1.0.1",
            +        "node-abi": "^2.7.0",
            +        "noop-logger": "^0.1.1",
            +        "npmlog": "^4.0.1",
            +        "pump": "^3.0.0",
            +        "rc": "^1.2.7",
            +        "simple-get": "^3.0.3",
            +        "tar-fs": "^2.0.0",
            +        "tunnel-agent": "^0.6.0",
            +        "which-pm-runs": "^1.0.0"
            +      },
            +      "bin": {
            +        "prebuild-install": "bin.js"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/prelude-ls": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
            +      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/prepend-http": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
            +      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/preserve": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
            +      "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/prettier": {
            +      "version": "1.19.1",
            +      "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
            +      "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
            +      "dev": true,
            +      "bin": {
            +        "prettier": "bin-prettier.js"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/pretty-bytes": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz",
            +      "integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/pretty-ms": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz",
            +      "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-finite": "^1.0.1",
            +        "parse-ms": "^1.0.0",
            +        "plur": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pretty-ms/node_modules/plur": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
            +      "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/pretty-time": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-0.2.0.tgz",
            +      "integrity": "sha1-ejvexAScYgzXxCt/NCt01W5z104=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^2.0.2",
            +        "nanoseconds": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/process-nextick-args": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
            +      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
            +      "dev": true
            +    },
            +    "node_modules/progress": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
            +      "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/project-name": {
            +      "version": "0.2.6",
            +      "resolved": "https://registry.npmjs.org/project-name/-/project-name-0.2.6.tgz",
            +      "integrity": "sha1-Pk94H+HulLB4apuuU1BjdsN5r2k=",
            +      "dev": true,
            +      "dependencies": {
            +        "find-pkg": "^0.1.2",
            +        "git-repo-name": "^0.6.0",
            +        "minimist": "^1.2.0"
            +      },
            +      "bin": {
            +        "project-name": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/proto-list": {
            +      "version": "1.2.4",
            +      "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
            +      "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
            +      "dev": true
            +    },
            +    "node_modules/pseudomap": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
            +      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
            +      "dev": true
            +    },
            +    "node_modules/psl": {
            +      "version": "1.8.0",
            +      "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
            +      "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
            +      "dev": true
            +    },
            +    "node_modules/pump": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
            +      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
            +      "dev": true,
            +      "dependencies": {
            +        "end-of-stream": "^1.1.0",
            +        "once": "^1.3.1"
            +      }
            +    },
            +    "node_modules/punycode": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
            +      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/q": {
            +      "version": "1.5.1",
            +      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
            +      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.6.0",
            +        "teleport": ">=0.2.0"
            +      }
            +    },
            +    "node_modules/qs": {
            +      "version": "6.10.1",
            +      "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
            +      "integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
            +      "dev": true,
            +      "dependencies": {
            +        "side-channel": "^1.0.4"
            +      },
            +      "engines": {
            +        "node": ">=0.6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/querystring": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
            +      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
            +      "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.x"
            +      }
            +    },
            +    "node_modules/question-cache": {
            +      "version": "0.7.0",
            +      "resolved": "https://registry.npmjs.org/question-cache/-/question-cache-0.7.0.tgz",
            +      "integrity": "sha1-KcX30pCInafGuzlTQutx9x6BPU0=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "arr-union": "^3.1.0",
            +        "async-each-series": "^1.1.0",
            +        "clone-deep": "^0.2.4",
            +        "debug": "^2.2.0",
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "get-value": "^2.0.6",
            +        "has-value": "^0.3.1",
            +        "inquirer2": "^0.1.1",
            +        "is-answer": "^0.1.0",
            +        "isobject": "^2.1.0",
            +        "lazy-cache": "^2.0.1",
            +        "log-utils": "^0.2.1",
            +        "mixin-deep": "^1.1.3",
            +        "omit-empty": "^0.4.1",
            +        "option-cache": "^3.4.0",
            +        "project-name": "^0.2.6",
            +        "set-value": "^0.3.3",
            +        "to-choices": "^0.2.0",
            +        "use": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/question-cache/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/question-cache/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/question-cache/node_modules/set-value": {
            +      "version": "0.3.3",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.3.3.tgz",
            +      "integrity": "sha1-uBIjaBY4oQiP2IpDW4qdMtro2bo=",
            +      "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "isobject": "^2.0.0",
            +        "to-object-path": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/question-cache/node_modules/to-object-path": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.2.0.tgz",
            +      "integrity": "sha1-FjThtSqIugDjlJYZ/ACB3Jo7B8o=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "is-arguments": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/question-cache/node_modules/use": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz",
            +      "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^0.2.5",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/question-cache/node_modules/use/node_modules/isobject": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
            +      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/question-store": {
            +      "version": "0.13.1",
            +      "resolved": "https://registry.npmjs.org/question-store/-/question-store-0.13.1.tgz",
            +      "integrity": "sha1-x10lV0KNcS5+CPNUE0IV+zqc768=",
            +      "dev": true,
            +      "dependencies": {
            +        "common-config": "^0.1.0",
            +        "data-store": "^0.16.1",
            +        "debug": "^2.2.0",
            +        "is-answer": "^0.1.0",
            +        "lazy-cache": "^2.0.1",
            +        "project-name": "^0.2.6",
            +        "question-cache": "^0.7.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/randomatic": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz",
            +      "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^4.0.0",
            +        "kind-of": "^6.0.0",
            +        "math-random": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/randomatic/node_modules/is-number": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
            +      "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/randomatic/node_modules/kind-of": {
            +      "version": "6.0.3",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
            +      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/range-parser": {
            +      "version": "1.2.1",
            +      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
            +      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/raw-body": {
            +      "version": "1.1.7",
            +      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
            +      "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=",
            +      "dev": true,
            +      "dependencies": {
            +        "bytes": "1",
            +        "string_decoder": "0.10"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/raw-body/node_modules/string_decoder": {
            +      "version": "0.10.31",
            +      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
            +      "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
            +      "dev": true
            +    },
            +    "node_modules/rc": {
            +      "version": "1.2.8",
            +      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
            +      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "deep-extend": "^0.6.0",
            +        "ini": "~1.3.0",
            +        "minimist": "^1.2.0",
            +        "strip-json-comments": "~2.0.1"
            +      },
            +      "bin": {
            +        "rc": "cli.js"
            +      }
            +    },
            +    "node_modules/read-file": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/read-file/-/read-file-0.2.0.tgz",
            +      "integrity": "sha1-cMa6+IQux9FUD5gf0Oau1Mgb1UU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/read-pkg": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
            +      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
            +      "dev": true,
            +      "dependencies": {
            +        "load-json-file": "^1.0.0",
            +        "normalize-package-data": "^2.3.2",
            +        "path-type": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/read-pkg-up": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
            +      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
            +      "dev": true,
            +      "dependencies": {
            +        "find-up": "^1.0.0",
            +        "read-pkg": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/read-yaml": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/read-yaml/-/read-yaml-1.1.0.tgz",
            +      "integrity": "sha1-DSc6wMlb6SIw3A1MTE9biWCjNtY=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "js-yaml": "^3.8.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/readable-stream": {
            +      "version": "2.3.6",
            +      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
            +      "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
            +      "dev": true,
            +      "dependencies": {
            +        "core-util-is": "~1.0.0",
            +        "inherits": "~2.0.3",
            +        "isarray": "~1.0.0",
            +        "process-nextick-args": "~2.0.0",
            +        "safe-buffer": "~5.1.1",
            +        "string_decoder": "~1.1.1",
            +        "util-deprecate": "~1.0.1"
            +      }
            +    },
            +    "node_modules/readline2": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
            +      "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
            +      "dev": true,
            +      "dependencies": {
            +        "code-point-at": "^1.0.0",
            +        "is-fullwidth-code-point": "^1.0.0",
            +        "mute-stream": "0.0.5"
            +      }
            +    },
            +    "node_modules/rechoir": {
            +      "version": "0.7.0",
            +      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz",
            +      "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "resolve": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/redent": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
            +      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
            +      "dev": true,
            +      "dependencies": {
            +        "indent-string": "^2.1.0",
            +        "strip-indent": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/reduce-object": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/reduce-object/-/reduce-object-0.1.3.tgz",
            +      "integrity": "sha1-1UnUCmwpNvpOPpt4yonJMxRZQhg=",
            +      "dev": true,
            +      "dependencies": {
            +        "for-own": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/regex-cache": {
            +      "version": "0.4.4",
            +      "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
            +      "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-equal-shallow": "^0.1.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/regex-flags": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/regex-flags/-/regex-flags-0.1.0.tgz",
            +      "integrity": "sha1-NEJ5hCj6rtU7DP7ef1cEQRDtHpQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/regex-flags/node_modules/kind-of": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz",
            +      "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/regex-not": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
            +      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^3.0.2",
            +        "safe-regex": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/regex-not/node_modules/extend-shallow": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
            +      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
            +      "dev": true,
            +      "dependencies": {
            +        "assign-symbols": "^1.0.0",
            +        "is-extendable": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/regex-not/node_modules/is-extendable": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
            +      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-object": "^2.0.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/regexpp": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
            +      "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/relative": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/relative/-/relative-3.0.2.tgz",
            +      "integrity": "sha1-Dc2OxUpdNaPBXhBFA9ZTdbWlNn8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/relative/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/remarkable": {
            +      "version": "1.7.4",
            +      "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-1.7.4.tgz",
            +      "integrity": "sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==",
            +      "dev": true,
            +      "dependencies": {
            +        "argparse": "^1.0.10",
            +        "autolinker": "~0.28.0"
            +      },
            +      "bin": {
            +        "remarkable": "bin/remarkable.js"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/remote-origin-url": {
            +      "version": "0.5.3",
            +      "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-0.5.3.tgz",
            +      "integrity": "sha512-crQ7Xk1m/F2IiwBx5oTqk/c0hjoumrEz+a36+ZoVupskQRE/q7pAwHKsTNeiZ31sbSTELvVlVv4h1W0Xo5szKg==",
            +      "dev": true,
            +      "dependencies": {
            +        "parse-git-config": "^1.1.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/remove-trailing-separator": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
            +      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
            +      "dev": true
            +    },
            +    "node_modules/repeat-element": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
            +      "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/repeat-string": {
            +      "version": "1.6.1",
            +      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
            +      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10"
            +      }
            +    },
            +    "node_modules/repeating": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
            +      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-finite": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/replace-ext": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz",
            +      "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.4"
            +      }
            +    },
            +    "node_modules/repo-utils": {
            +      "version": "0.3.7",
            +      "resolved": "https://registry.npmjs.org/repo-utils/-/repo-utils-0.3.7.tgz",
            +      "integrity": "sha1-SrZq80DLEfp+XPgFgekr6Xwb964=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "get-value": "^2.0.6",
            +        "git-config-path": "^1.0.1",
            +        "is-absolute": "^0.2.6",
            +        "kind-of": "^3.0.4",
            +        "lazy-cache": "^2.0.1",
            +        "mixin-deep": "^1.1.3",
            +        "omit-empty": "^0.4.1",
            +        "parse-author": "^1.0.0",
            +        "parse-git-config": "^1.0.2",
            +        "parse-github-url": "^0.3.2",
            +        "project-name": "^0.2.6"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/repo-utils/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/request": {
            +      "version": "2.88.2",
            +      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
            +      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
            +      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
            +      "dev": true,
            +      "dependencies": {
            +        "aws-sign2": "~0.7.0",
            +        "aws4": "^1.8.0",
            +        "caseless": "~0.12.0",
            +        "combined-stream": "~1.0.6",
            +        "extend": "~3.0.2",
            +        "forever-agent": "~0.6.1",
            +        "form-data": "~2.3.2",
            +        "har-validator": "~5.1.3",
            +        "http-signature": "~1.2.0",
            +        "is-typedarray": "~1.0.0",
            +        "isstream": "~0.1.2",
            +        "json-stringify-safe": "~5.0.1",
            +        "mime-types": "~2.1.19",
            +        "oauth-sign": "~0.9.0",
            +        "performance-now": "^2.1.0",
            +        "qs": "~6.5.2",
            +        "safe-buffer": "^5.1.2",
            +        "tough-cookie": "~2.5.0",
            +        "tunnel-agent": "^0.6.0",
            +        "uuid": "^3.3.2"
            +      },
            +      "engines": {
            +        "node": ">= 6"
            +      }
            +    },
            +    "node_modules/request-promise-core": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
            +      "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash": "^4.17.15"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      },
            +      "peerDependencies": {
            +        "request": "^2.34"
            +      }
            +    },
            +    "node_modules/request-promise-native": {
            +      "version": "1.0.8",
            +      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz",
            +      "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==",
            +      "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
            +      "dev": true,
            +      "dependencies": {
            +        "request-promise-core": "1.1.3",
            +        "stealthy-require": "^1.1.1",
            +        "tough-cookie": "^2.3.3"
            +      },
            +      "engines": {
            +        "node": ">=0.12.0"
            +      },
            +      "peerDependencies": {
            +        "request": "^2.34"
            +      }
            +    },
            +    "node_modules/request/node_modules/qs": {
            +      "version": "6.5.2",
            +      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
            +      "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.6"
            +      }
            +    },
            +    "node_modules/require-uncached": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
            +      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
            +      "dev": true,
            +      "dependencies": {
            +        "caller-path": "^0.1.0",
            +        "resolve-from": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/requirejs": {
            +      "version": "2.3.5",
            +      "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.5.tgz",
            +      "integrity": "sha512-svnO+aNcR/an9Dpi44C7KSAy5fFGLtmPbaaCeQaklUz8BQhS64tWWIIlvEA5jrWICzlO/X9KSzSeXFnZdBu8nw==",
            +      "dev": true,
            +      "bin": {
            +        "r_js": "bin/r.js",
            +        "r.js": "bin/r.js"
            +      },
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/resolve": {
            +      "version": "1.15.1",
            +      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
            +      "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
            +      "dev": true,
            +      "dependencies": {
            +        "path-parse": "^1.0.6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/resolve-dep": {
            +      "version": "0.5.4",
            +      "resolved": "https://registry.npmjs.org/resolve-dep/-/resolve-dep-0.5.4.tgz",
            +      "integrity": "sha1-L1LSAjz+guw/GY1K8ry2SSXSdU8=",
            +      "dev": true,
            +      "dependencies": {
            +        "arrayify-compact": "^0.1.0",
            +        "cwd": "^0.3.7",
            +        "extend-shallow": "^0.2.0",
            +        "globby": "^1.1.0",
            +        "load-pkg": "^3.0.1",
            +        "lookup-path": "^0.3.0",
            +        "micromatch": "^1.2.2",
            +        "resolve": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.16"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/ansi-regex": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
            +      "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/ansi-styles": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
            +      "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/arr-diff": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz",
            +      "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-flatten": "^1.0.1",
            +        "array-slice": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/arrayify-compact": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/arrayify-compact/-/arrayify-compact-0.1.1.tgz",
            +      "integrity": "sha512-3R2V/8ixAhDXxyeWZ9aVzncUscrASg1TPrVsUgkxaMb0/WJLo5u769wYYf916OKqRCF+GKXaosouk1ixIfX89g==",
            +      "dev": true,
            +      "dependencies": {
            +        "array-flatten": "^2.1.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/async": {
            +      "version": "0.9.2",
            +      "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
            +      "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
            +      "dev": true
            +    },
            +    "node_modules/resolve-dep/node_modules/chalk": {
            +      "version": "0.5.1",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
            +      "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^1.1.0",
            +        "escape-string-regexp": "^1.0.0",
            +        "has-ansi": "^0.1.0",
            +        "strip-ansi": "^0.3.0",
            +        "supports-color": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/cwd": {
            +      "version": "0.3.7",
            +      "resolved": "https://registry.npmjs.org/cwd/-/cwd-0.3.7.tgz",
            +      "integrity": "sha1-+mq8GIlgdw9rE2+xmEBsjikfsoE=",
            +      "dev": true,
            +      "dependencies": {
            +        "findup-sync": "~0.1.3",
            +        "normalize-path": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/extend-shallow": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-0.2.0.tgz",
            +      "integrity": "sha1-DJignyfYPLQ++vztrIydFJ3rWZw=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-slice": "^0.2.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/extglob": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.2.0.tgz",
            +      "integrity": "sha1-MWtr7G4bM1cxOMoEyh48sJNm8Nc=",
            +      "dev": true,
            +      "dependencies": {
            +        "micromatch": "^1.2.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/glob": {
            +      "version": "4.5.3",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz",
            +      "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=",
            +      "dev": true,
            +      "dependencies": {
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^2.0.1",
            +        "once": "^1.3.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/glob-base": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.1.1.tgz",
            +      "integrity": "sha1-87LcQGRnztJWfxlldFD7jgNvjG0=",
            +      "dev": true,
            +      "dependencies": {
            +        "glob-parent": "^1.2.0",
            +        "is-glob": "^1.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/glob-parent": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-1.3.0.tgz",
            +      "integrity": "sha1-lx7dgW7V21hwW1gHlkemTQrveWg=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-glob": "^2.0.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/glob-parent/node_modules/is-glob": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
            +      "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extglob": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/globby": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/globby/-/globby-1.2.0.tgz",
            +      "integrity": "sha1-x8l60cxvhZSBHaHrgpBqhSukfaQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-union": "^1.0.1",
            +        "async": "^0.9.0",
            +        "glob": "^4.4.0",
            +        "object-assign": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/has-ansi": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
            +      "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-regex": "^0.2.0"
            +      },
            +      "bin": {
            +        "has-ansi": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/is-extglob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
            +      "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/is-glob": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-1.1.3.tgz",
            +      "integrity": "sha1-tMZLgwPTkRRJKkYNNkzPsNPAoEU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/isobject": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-0.2.0.tgz",
            +      "integrity": "sha1-o0MhkvObkQtfAsyYlIeDbscKqF4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/kind-of": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
            +      "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/micromatch": {
            +      "version": "1.6.2",
            +      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-1.6.2.tgz",
            +      "integrity": "sha1-OPq0cHaqzs5urXfvOEcjkve0v7k=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-diff": "^1.0.1",
            +        "braces": "^1.7.0",
            +        "debug": "^2.1.2",
            +        "expand-brackets": "^0.1.1",
            +        "extglob": "^0.2.0",
            +        "filename-regex": "^2.0.0",
            +        "is-glob": "^1.1.1",
            +        "kind-of": "^1.1.0",
            +        "object.omit": "^0.2.1",
            +        "parse-glob": "^2.1.1",
            +        "regex-cache": "^0.3.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/minimatch": {
            +      "version": "2.0.10",
            +      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
            +      "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
            +      "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue",
            +      "dev": true,
            +      "dependencies": {
            +        "brace-expansion": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/normalize-path": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-0.1.1.tgz",
            +      "integrity": "sha1-bHASSP25iW0f7hqmYg2nf+7U02c=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/object-assign": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
            +      "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/object.omit": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-0.2.1.tgz",
            +      "integrity": "sha1-ypr2Yx32iD/mG65034Kk+8nfLpI=",
            +      "dev": true,
            +      "dependencies": {
            +        "for-own": "^0.1.1",
            +        "isobject": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/parse-glob": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-2.1.1.tgz",
            +      "integrity": "sha1-WxNouudnoisTWitQBGs09O75B/Y=",
            +      "dev": true,
            +      "dependencies": {
            +        "glob-base": "^0.1.0",
            +        "glob-path-regex": "^1.0.0",
            +        "is-glob": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/regex-cache": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.3.0.tgz",
            +      "integrity": "sha1-PqA2YnF5ECv7GiNkqyZ5oPMpZMA=",
            +      "dev": true,
            +      "dependencies": {
            +        "benchmarked": "^0.1.3",
            +        "chalk": "^0.5.1",
            +        "micromatch": "^1.2.2",
            +        "to-key": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/strip-ansi": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
            +      "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-regex": "^0.2.1"
            +      },
            +      "bin": {
            +        "strip-ansi": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dep/node_modules/supports-color": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
            +      "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
            +      "dev": true,
            +      "bin": {
            +        "supports-color": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dir": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
            +      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
            +      "dev": true,
            +      "dependencies": {
            +        "expand-tilde": "^2.0.0",
            +        "global-modules": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-dir/node_modules/global-modules": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
            +      "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
            +      "dev": true,
            +      "dependencies": {
            +        "global-prefix": "^1.0.1",
            +        "is-windows": "^1.0.1",
            +        "resolve-dir": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-from": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
            +      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-glob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/resolve-glob/-/resolve-glob-1.0.0.tgz",
            +      "integrity": "sha512-wSW9pVGJRs89k0wEXhM7C6+va9998NsDhgc0Y+6Nv8hrHsu0hUS7Ug10J1EiVtU6N2tKlSNvx9wLihL8Ao22Lg==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "is-valid-glob": "^1.0.0",
            +        "matched": "^1.0.2",
            +        "relative": "^3.0.2",
            +        "resolve-dir": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-glob/node_modules/is-valid-glob": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
            +      "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/resolve-pkg": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-2.0.0.tgz",
            +      "integrity": "sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "resolve-from": "^5.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/resolve-pkg/node_modules/resolve-from": {
            +      "version": "5.0.0",
            +      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
            +      "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/resolve-url": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
            +      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
            +      "deprecated": "https://github.com/lydell/resolve-url#deprecated",
            +      "dev": true
            +    },
            +    "node_modules/responselike": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
            +      "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
            +      "dev": true,
            +      "dependencies": {
            +        "lowercase-keys": "^1.0.0"
            +      }
            +    },
            +    "node_modules/restore-cursor": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
            +      "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
            +      "dev": true,
            +      "dependencies": {
            +        "exit-hook": "^1.0.0",
            +        "onetime": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ret": {
            +      "version": "0.1.15",
            +      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
            +      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.12"
            +      }
            +    },
            +    "node_modules/rethrow": {
            +      "version": "0.2.3",
            +      "resolved": "https://registry.npmjs.org/rethrow/-/rethrow-0.2.3.tgz",
            +      "integrity": "sha1-xVKPGQ6J7HU1iJRSob5omWtfZhY=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-bgred": "^0.1.1",
            +        "ansi-red": "^0.1.1",
            +        "ansi-yellow": "^0.1.1",
            +        "extend-shallow": "^1.1.4",
            +        "lazy-cache": "^0.2.3",
            +        "right-align": "^0.1.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/rethrow/node_modules/extend-shallow": {
            +      "version": "1.1.4",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
            +      "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/rethrow/node_modules/kind-of": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
            +      "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/rethrow/node_modules/lazy-cache": {
            +      "version": "0.2.7",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
            +      "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/reusify": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
            +      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
            +      "dev": true,
            +      "engines": {
            +        "iojs": ">=1.0.0",
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/rgb-regex": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
            +      "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=",
            +      "dev": true
            +    },
            +    "node_modules/rgba-regex": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz",
            +      "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
            +      "dev": true
            +    },
            +    "node_modules/right-align": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
            +      "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
            +      "dev": true,
            +      "dependencies": {
            +        "align-text": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/rimraf": {
            +      "version": "2.6.2",
            +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
            +      "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
            +      "dev": true,
            +      "dependencies": {
            +        "glob": "^7.0.5"
            +      },
            +      "bin": {
            +        "rimraf": "bin.js"
            +      }
            +    },
            +    "node_modules/rimraf/node_modules/glob": {
            +      "version": "7.1.2",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
            +      "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/run-async": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
            +      "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
            +      "dev": true,
            +      "dependencies": {
            +        "once": "^1.3.0"
            +      }
            +    },
            +    "node_modules/run-parallel": {
            +      "version": "1.1.9",
            +      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
            +      "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
            +      "dev": true
            +    },
            +    "node_modules/rx-lite": {
            +      "version": "4.0.8",
            +      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
            +      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
            +      "dev": true
            +    },
            +    "node_modules/rx-lite-aggregates": {
            +      "version": "4.0.8",
            +      "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
            +      "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
            +      "dev": true,
            +      "dependencies": {
            +        "rx-lite": "*"
            +      }
            +    },
            +    "node_modules/rxjs": {
            +      "version": "6.5.4",
            +      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
            +      "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
            +      "dev": true,
            +      "dependencies": {
            +        "tslib": "^1.9.0"
            +      },
            +      "engines": {
            +        "npm": ">=2.0.0"
            +      }
            +    },
            +    "node_modules/safe-buffer": {
            +      "version": "5.1.2",
            +      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
            +      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
            +      "dev": true
            +    },
            +    "node_modules/safe-json-parse": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz",
            +      "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=",
            +      "dev": true
            +    },
            +    "node_modules/safe-regex": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
            +      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
            +      "dev": true,
            +      "dependencies": {
            +        "ret": "~0.1.10"
            +      }
            +    },
            +    "node_modules/safer-buffer": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
            +      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
            +      "dev": true
            +    },
            +    "node_modules/sax": {
            +      "version": "1.2.4",
            +      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
            +      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
            +      "dev": true
            +    },
            +    "node_modules/seek-bzip": {
            +      "version": "1.0.5",
            +      "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz",
            +      "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=",
            +      "dev": true,
            +      "dependencies": {
            +        "commander": "~2.8.1"
            +      },
            +      "bin": {
            +        "seek-bunzip": "bin/seek-bunzip",
            +        "seek-table": "bin/seek-bzip-table"
            +      }
            +    },
            +    "node_modules/semver": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
            +      "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
            +      "dev": true,
            +      "bin": {
            +        "semver": "bin/semver"
            +      }
            +    },
            +    "node_modules/semver-compare": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
            +      "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
            +      "dev": true
            +    },
            +    "node_modules/semver-regex": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz",
            +      "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/semver-truncate": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-1.1.2.tgz",
            +      "integrity": "sha1-V/Qd5pcHpicJp+AQS6IRcQnqR+g=",
            +      "dev": true,
            +      "dependencies": {
            +        "semver": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/send": {
            +      "version": "0.16.2",
            +      "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
            +      "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "2.6.9",
            +        "depd": "~1.1.2",
            +        "destroy": "~1.0.4",
            +        "encodeurl": "~1.0.2",
            +        "escape-html": "~1.0.3",
            +        "etag": "~1.8.1",
            +        "fresh": "0.5.2",
            +        "http-errors": "~1.6.2",
            +        "mime": "1.4.1",
            +        "ms": "2.0.0",
            +        "on-finished": "~2.3.0",
            +        "range-parser": "~1.2.0",
            +        "statuses": "~1.4.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/send/node_modules/escape-html": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
            +      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
            +      "dev": true
            +    },
            +    "node_modules/send/node_modules/fresh": {
            +      "version": "0.5.2",
            +      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
            +      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/send/node_modules/mime": {
            +      "version": "1.4.1",
            +      "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
            +      "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
            +      "dev": true,
            +      "bin": {
            +        "mime": "cli.js"
            +      }
            +    },
            +    "node_modules/send/node_modules/ms": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
            +      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
            +      "dev": true
            +    },
            +    "node_modules/send/node_modules/range-parser": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
            +      "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/sentence-case": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-1.1.3.tgz",
            +      "integrity": "sha1-gDSq/CFFdy06vhUJqkLJ4QQtwTk=",
            +      "dev": true,
            +      "dependencies": {
            +        "lower-case": "^1.1.1"
            +      }
            +    },
            +    "node_modules/serve-index": {
            +      "version": "1.9.1",
            +      "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
            +      "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
            +      "dev": true,
            +      "dependencies": {
            +        "accepts": "~1.3.4",
            +        "batch": "0.6.1",
            +        "debug": "2.6.9",
            +        "escape-html": "~1.0.3",
            +        "http-errors": "~1.6.2",
            +        "mime-types": "~2.1.17",
            +        "parseurl": "~1.3.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/serve-index/node_modules/accepts": {
            +      "version": "1.3.5",
            +      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
            +      "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
            +      "dev": true,
            +      "dependencies": {
            +        "mime-types": "~2.1.18",
            +        "negotiator": "0.6.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/serve-index/node_modules/batch": {
            +      "version": "0.6.1",
            +      "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
            +      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
            +      "dev": true
            +    },
            +    "node_modules/serve-index/node_modules/escape-html": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
            +      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
            +      "dev": true
            +    },
            +    "node_modules/serve-index/node_modules/negotiator": {
            +      "version": "0.6.1",
            +      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
            +      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/serve-index/node_modules/parseurl": {
            +      "version": "1.3.2",
            +      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
            +      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8"
            +      }
            +    },
            +    "node_modules/serve-static": {
            +      "version": "1.14.1",
            +      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
            +      "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
            +      "dev": true,
            +      "dependencies": {
            +        "encodeurl": "~1.0.2",
            +        "escape-html": "~1.0.3",
            +        "parseurl": "~1.3.3",
            +        "send": "0.17.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/serve-static/node_modules/http-errors": {
            +      "version": "1.7.3",
            +      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
            +      "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==",
            +      "dev": true,
            +      "dependencies": {
            +        "depd": "~1.1.2",
            +        "inherits": "2.0.4",
            +        "setprototypeof": "1.1.1",
            +        "statuses": ">= 1.5.0 < 2",
            +        "toidentifier": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/serve-static/node_modules/inherits": {
            +      "version": "2.0.4",
            +      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
            +      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
            +      "dev": true
            +    },
            +    "node_modules/serve-static/node_modules/ms": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
            +      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
            +      "dev": true
            +    },
            +    "node_modules/serve-static/node_modules/send": {
            +      "version": "0.17.1",
            +      "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
            +      "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "2.6.9",
            +        "depd": "~1.1.2",
            +        "destroy": "~1.0.4",
            +        "encodeurl": "~1.0.2",
            +        "escape-html": "~1.0.3",
            +        "etag": "~1.8.1",
            +        "fresh": "0.5.2",
            +        "http-errors": "~1.7.2",
            +        "mime": "1.6.0",
            +        "ms": "2.1.1",
            +        "on-finished": "~2.3.0",
            +        "range-parser": "~1.2.1",
            +        "statuses": "~1.5.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/serve-static/node_modules/setprototypeof": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
            +      "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
            +      "dev": true
            +    },
            +    "node_modules/serve-static/node_modules/statuses": {
            +      "version": "1.5.0",
            +      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
            +      "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/set-blocking": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
            +      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/set-getter": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz",
            +      "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=",
            +      "dev": true,
            +      "dependencies": {
            +        "to-object-path": "^0.3.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/set-value": {
            +      "version": "0.4.3",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
            +      "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
            +      "deprecated": "Critical bug fixed in v3.0.1, please upgrade to the latest version.",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "is-extendable": "^0.1.1",
            +        "is-plain-object": "^2.0.1",
            +        "to-object-path": "^0.3.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/setimmediate": {
            +      "version": "1.0.5",
            +      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
            +      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
            +      "dev": true
            +    },
            +    "node_modules/setprototypeof": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
            +      "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
            +      "dev": true
            +    },
            +    "node_modules/shallow-clone": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz",
            +      "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-extendable": "^0.1.1",
            +        "kind-of": "^2.0.1",
            +        "lazy-cache": "^0.2.3",
            +        "mixin-object": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/shallow-clone/node_modules/kind-of": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz",
            +      "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/shallow-clone/node_modules/lazy-cache": {
            +      "version": "0.2.7",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
            +      "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/shebang-command": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
            +      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
            +      "dev": true,
            +      "dependencies": {
            +        "shebang-regex": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/shebang-regex": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
            +      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/side-channel": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
            +      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
            +      "dev": true,
            +      "dependencies": {
            +        "call-bind": "^1.0.0",
            +        "get-intrinsic": "^1.0.2",
            +        "object-inspect": "^1.9.0"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/side-channel/node_modules/object-inspect": {
            +      "version": "1.10.3",
            +      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz",
            +      "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",
            +      "dev": true,
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/sigmund": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
            +      "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
            +      "dev": true
            +    },
            +    "node_modules/signal-exit": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
            +      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
            +      "dev": true
            +    },
            +    "node_modules/simple-concat": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
            +      "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/simple-get": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
            +      "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "decompress-response": "^4.2.0",
            +        "once": "^1.3.1",
            +        "simple-concat": "^1.0.0"
            +      }
            +    },
            +    "node_modules/simple-get/node_modules/decompress-response": {
            +      "version": "4.2.1",
            +      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
            +      "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "mimic-response": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/simple-get/node_modules/mimic-response": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
            +      "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
            +      "dev": true,
            +      "optional": true,
            +      "engines": {
            +        "node": ">=8"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/simple-git": {
            +      "version": "1.132.0",
            +      "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.132.0.tgz",
            +      "integrity": "sha512-xauHm1YqCTom1sC9eOjfq3/9RKiUA9iPnxBbrY2DdL8l4ADMu0jjM5l5lphQP5YWNqAL2aXC/OeuQ76vHtW5fg==",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^4.0.1"
            +      }
            +    },
            +    "node_modules/simple-git/node_modules/debug": {
            +      "version": "4.1.1",
            +      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
            +      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
            +      "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
            +      "dev": true,
            +      "dependencies": {
            +        "ms": "^2.1.1"
            +      }
            +    },
            +    "node_modules/simple-git/node_modules/ms": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
            +      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
            +      "dev": true
            +    },
            +    "node_modules/simple-swizzle": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
            +      "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-arrayish": "^0.3.1"
            +      }
            +    },
            +    "node_modules/simple-swizzle/node_modules/is-arrayish": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
            +      "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
            +      "dev": true
            +    },
            +    "node_modules/slash": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
            +      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/slice-ansi": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
            +      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-fullwidth-code-point": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
            +      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/snapdragon": {
            +      "version": "0.8.2",
            +      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
            +      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
            +      "dev": true,
            +      "dependencies": {
            +        "base": "^0.11.1",
            +        "debug": "^2.2.0",
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "map-cache": "^0.2.2",
            +        "source-map": "^0.5.6",
            +        "source-map-resolve": "^0.5.0",
            +        "use": "^3.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon-node": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
            +      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^1.0.0",
            +        "isobject": "^3.0.0",
            +        "snapdragon-util": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon-node/node_modules/define-property": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
            +      "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon-node/node_modules/is-data-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon-node/node_modules/is-descriptor": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
            +      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^1.0.0",
            +        "is-data-descriptor": "^1.0.0",
            +        "kind-of": "^6.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon-node/node_modules/kind-of": {
            +      "version": "6.0.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
            +      "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon-util": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
            +      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon-util/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon/node_modules/source-map": {
            +      "version": "0.5.7",
            +      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
            +      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/snapdragon/node_modules/use": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
            +      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/sort-keys": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
            +      "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-obj": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/sort-keys-length": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
            +      "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
            +      "dev": true,
            +      "dependencies": {
            +        "sort-keys": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/sort-object-arrays": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/sort-object-arrays/-/sort-object-arrays-0.1.1.tgz",
            +      "integrity": "sha1-mfVc8gWkkd3h9S8Jajaiawm0gy8=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/sort-object-arrays/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/source-map": {
            +      "version": "0.6.1",
            +      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
            +      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/source-map-resolve": {
            +      "version": "0.5.2",
            +      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
            +      "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
            +      "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
            +      "dev": true,
            +      "dependencies": {
            +        "atob": "^2.1.1",
            +        "decode-uri-component": "^0.2.0",
            +        "resolve-url": "^0.2.1",
            +        "source-map-url": "^0.4.0",
            +        "urix": "^0.1.0"
            +      }
            +    },
            +    "node_modules/source-map-url": {
            +      "version": "0.4.0",
            +      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
            +      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
            +      "deprecated": "See https://github.com/lydell/source-map-url#deprecated",
            +      "dev": true
            +    },
            +    "node_modules/spdx-correct": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
            +      "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
            +      "dev": true,
            +      "dependencies": {
            +        "spdx-expression-parse": "^3.0.0",
            +        "spdx-license-ids": "^3.0.0"
            +      }
            +    },
            +    "node_modules/spdx-exceptions": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
            +      "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
            +      "dev": true
            +    },
            +    "node_modules/spdx-expression-parse": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
            +      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
            +      "dev": true,
            +      "dependencies": {
            +        "spdx-exceptions": "^2.1.0",
            +        "spdx-license-ids": "^3.0.0"
            +      }
            +    },
            +    "node_modules/spdx-license-ids": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
            +      "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==",
            +      "dev": true
            +    },
            +    "node_modules/split-string": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
            +      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/split-string/node_modules/extend-shallow": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
            +      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
            +      "dev": true,
            +      "dependencies": {
            +        "assign-symbols": "^1.0.0",
            +        "is-extendable": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/split-string/node_modules/is-extendable": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
            +      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-object": "^2.0.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/sprintf-js": {
            +      "version": "1.0.3",
            +      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
            +      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
            +      "dev": true
            +    },
            +    "node_modules/squeak": {
            +      "version": "1.3.0",
            +      "resolved": "https://registry.npmjs.org/squeak/-/squeak-1.3.0.tgz",
            +      "integrity": "sha1-MwRQN7ZDiLVnZ0uEMiplIQc5FsM=",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.0.0",
            +        "console-stream": "^0.1.1",
            +        "lpad-align": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/src-stream": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/src-stream/-/src-stream-0.1.1.tgz",
            +      "integrity": "sha1-2T9G0oGjcAKB7A8wszoDFDiUpoE=",
            +      "dev": true,
            +      "dependencies": {
            +        "duplexify": "^3.4.2",
            +        "merge-stream": "^0.1.8",
            +        "through2": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/src-stream/node_modules/isarray": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
            +      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
            +      "dev": true
            +    },
            +    "node_modules/src-stream/node_modules/merge-stream": {
            +      "version": "0.1.8",
            +      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-0.1.8.tgz",
            +      "integrity": "sha1-SKB7O0oSHXSj7b/c20sIrb8CQLE=",
            +      "dev": true,
            +      "dependencies": {
            +        "through2": "^0.6.1"
            +      }
            +    },
            +    "node_modules/src-stream/node_modules/merge-stream/node_modules/through2": {
            +      "version": "0.6.5",
            +      "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
            +      "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
            +      "dev": true,
            +      "dependencies": {
            +        "readable-stream": ">=1.0.33-1 <1.1.0-0",
            +        "xtend": ">=4.0.0 <4.1.0-0"
            +      }
            +    },
            +    "node_modules/src-stream/node_modules/readable-stream": {
            +      "version": "1.0.34",
            +      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
            +      "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
            +      "dev": true,
            +      "dependencies": {
            +        "core-util-is": "~1.0.0",
            +        "inherits": "~2.0.1",
            +        "isarray": "0.0.1",
            +        "string_decoder": "~0.10.x"
            +      }
            +    },
            +    "node_modules/src-stream/node_modules/string_decoder": {
            +      "version": "0.10.31",
            +      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
            +      "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
            +      "dev": true
            +    },
            +    "node_modules/sshpk": {
            +      "version": "1.16.1",
            +      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
            +      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
            +      "dev": true,
            +      "dependencies": {
            +        "asn1": "~0.2.3",
            +        "assert-plus": "^1.0.0",
            +        "bcrypt-pbkdf": "^1.0.0",
            +        "dashdash": "^1.12.0",
            +        "ecc-jsbn": "~0.1.1",
            +        "getpass": "^0.1.1",
            +        "jsbn": "~0.1.0",
            +        "safer-buffer": "^2.0.2",
            +        "tweetnacl": "~0.14.0"
            +      },
            +      "bin": {
            +        "sshpk-conv": "bin/sshpk-conv",
            +        "sshpk-sign": "bin/sshpk-sign",
            +        "sshpk-verify": "bin/sshpk-verify"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/stable": {
            +      "version": "0.1.8",
            +      "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
            +      "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
            +      "dev": true
            +    },
            +    "node_modules/static-extend": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
            +      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^0.2.5",
            +        "object-copy": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/statuses": {
            +      "version": "1.4.0",
            +      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
            +      "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.6"
            +      }
            +    },
            +    "node_modules/stealthy-require": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
            +      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/stream-browserify": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
            +      "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
            +      "dev": true,
            +      "dependencies": {
            +        "inherits": "~2.0.1",
            +        "readable-stream": "^2.0.2"
            +      }
            +    },
            +    "node_modules/stream-buffers": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
            +      "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    },
            +    "node_modules/stream-combiner": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
            +      "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=",
            +      "dev": true,
            +      "dependencies": {
            +        "duplexer": "~0.1.1",
            +        "through": "~2.3.4"
            +      }
            +    },
            +    "node_modules/stream-counter": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/stream-counter/-/stream-counter-0.2.0.tgz",
            +      "integrity": "sha1-3tJmVWMZyLDiIoErnPOyb6fZR94=",
            +      "dev": true,
            +      "dependencies": {
            +        "readable-stream": "~1.1.8"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/stream-counter/node_modules/isarray": {
            +      "version": "0.0.1",
            +      "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
            +      "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
            +      "dev": true
            +    },
            +    "node_modules/stream-counter/node_modules/readable-stream": {
            +      "version": "1.1.14",
            +      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
            +      "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
            +      "dev": true,
            +      "dependencies": {
            +        "core-util-is": "~1.0.0",
            +        "inherits": "~2.0.1",
            +        "isarray": "0.0.1",
            +        "string_decoder": "~0.10.x"
            +      }
            +    },
            +    "node_modules/stream-counter/node_modules/string_decoder": {
            +      "version": "0.10.31",
            +      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
            +      "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
            +      "dev": true
            +    },
            +    "node_modules/stream-exhaust": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
            +      "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==",
            +      "dev": true
            +    },
            +    "node_modules/stream-shift": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
            +      "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
            +      "dev": true
            +    },
            +    "node_modules/strict-uri-encode": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
            +      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/string_decoder": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
            +      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            +      "dev": true,
            +      "dependencies": {
            +        "safe-buffer": "~5.1.0"
            +      }
            +    },
            +    "node_modules/string-argv": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
            +      "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.6.19"
            +      }
            +    },
            +    "node_modules/string-template": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
            +      "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=",
            +      "dev": true
            +    },
            +    "node_modules/string-width": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
            +      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-fullwidth-code-point": "^2.0.0",
            +        "strip-ansi": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/string-width/node_modules/ansi-regex": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
            +      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/string-width/node_modules/is-fullwidth-code-point": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
            +      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/string-width/node_modules/strip-ansi": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
            +      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-regex": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/string.prototype.trimleft": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
            +      "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
            +      "dev": true,
            +      "dependencies": {
            +        "define-properties": "^1.1.3",
            +        "function-bind": "^1.1.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.4"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/string.prototype.trimright": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
            +      "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
            +      "dev": true,
            +      "dependencies": {
            +        "define-properties": "^1.1.3",
            +        "function-bind": "^1.1.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.4"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/stringify-author": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/stringify-author/-/stringify-author-0.1.3.tgz",
            +      "integrity": "sha1-1YHgLOC1XNo8lT5irdIR+uSw72Y=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/stringify-object": {
            +      "version": "3.3.0",
            +      "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
            +      "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
            +      "dev": true,
            +      "dependencies": {
            +        "get-own-enumerable-property-symbols": "^3.0.0",
            +        "is-obj": "^1.0.1",
            +        "is-regexp": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/strings": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/strings/-/strings-0.2.1.tgz",
            +      "integrity": "sha1-eVW5KSsyX1s/NNkW0X7wN7VBUVQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "frep": "~0.1.2",
            +        "lodash": "~2.4.1",
            +        "moment": "~2.5.0",
            +        "underscore.string": "~2.3.3"
            +      }
            +    },
            +    "node_modules/strings/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/strings/node_modules/moment": {
            +      "version": "2.5.1",
            +      "resolved": "https://registry.npmjs.org/moment/-/moment-2.5.1.tgz",
            +      "integrity": "sha1-cUajkAUzBkynmdXnkvTkgO4Ogrw=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/strings/node_modules/underscore.string": {
            +      "version": "2.3.3",
            +      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
            +      "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/strip-ansi": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
            +      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-regex": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-bom": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
            +      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-utf8": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-bom-buffer": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/strip-bom-buffer/-/strip-bom-buffer-0.1.1.tgz",
            +      "integrity": "sha1-yj3cSRnBP5/d8wsd/xAKmDUki00=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.0",
            +        "is-utf8": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-bom-stream": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz",
            +      "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=",
            +      "dev": true,
            +      "dependencies": {
            +        "first-chunk-stream": "^1.0.0",
            +        "strip-bom": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-bom-string": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-0.1.2.tgz",
            +      "integrity": "sha1-nG5yCjE7qYNliVGEBcz7iKX0G5w=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-color": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz",
            +      "integrity": "sha1-EG9l09PmotlAHKwOsM6LinArT3s=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-dirs": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
            +      "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-natural-number": "^4.0.1"
            +      }
            +    },
            +    "node_modules/strip-eof": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
            +      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-final-newline": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
            +      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/strip-indent": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
            +      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
            +      "dev": true,
            +      "dependencies": {
            +        "get-stdin": "^4.0.1"
            +      },
            +      "bin": {
            +        "strip-indent": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-indent/node_modules/get-stdin": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
            +      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-json-comments": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
            +      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/strip-outer": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
            +      "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
            +      "dev": true,
            +      "dependencies": {
            +        "escape-string-regexp": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/striptags": {
            +      "version": "2.2.1",
            +      "resolved": "https://registry.npmjs.org/striptags/-/striptags-2.2.1.tgz",
            +      "integrity": "sha1-TEULcI1BuL85zyTEn/I0/Gqr/TI=",
            +      "dev": true
            +    },
            +    "node_modules/stylehacks": {
            +      "version": "4.0.3",
            +      "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
            +      "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==",
            +      "dev": true,
            +      "dependencies": {
            +        "browserslist": "^4.0.0",
            +        "postcss": "^7.0.0",
            +        "postcss-selector-parser": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6.9.0"
            +      }
            +    },
            +    "node_modules/stylehacks/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/stylehacks/node_modules/browserslist": {
            +      "version": "4.16.6",
            +      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
            +      "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "caniuse-lite": "^1.0.30001219",
            +        "colorette": "^1.2.2",
            +        "electron-to-chromium": "^1.3.723",
            +        "escalade": "^3.1.1",
            +        "node-releases": "^1.1.71"
            +      },
            +      "bin": {
            +        "browserslist": "cli.js"
            +      },
            +      "engines": {
            +        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/browserslist"
            +      }
            +    },
            +    "node_modules/stylehacks/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/stylehacks/node_modules/chalk/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/stylehacks/node_modules/electron-to-chromium": {
            +      "version": "1.3.752",
            +      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.752.tgz",
            +      "integrity": "sha512-2Tg+7jSl3oPxgsBsWKh5H83QazTkmWG/cnNwJplmyZc7KcN61+I10oUgaXSVk/NwfvN3BdkKDR4FYuRBQQ2v0A==",
            +      "dev": true
            +    },
            +    "node_modules/stylehacks/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/stylehacks/node_modules/postcss": {
            +      "version": "7.0.36",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
            +      "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.2",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^6.1.0"
            +      },
            +      "engines": {
            +        "node": ">=6.0.0"
            +      },
            +      "funding": {
            +        "type": "opencollective",
            +        "url": "https://opencollective.com/postcss/"
            +      }
            +    },
            +    "node_modules/stylehacks/node_modules/postcss-selector-parser": {
            +      "version": "3.1.2",
            +      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
            +      "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
            +      "dev": true,
            +      "dependencies": {
            +        "dot-prop": "^5.2.0",
            +        "indexes-of": "^1.0.1",
            +        "uniq": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=8"
            +      }
            +    },
            +    "node_modules/stylehacks/node_modules/supports-color": {
            +      "version": "6.1.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
            +      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=6"
            +      }
            +    },
            +    "node_modules/success-symbol": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/success-symbol/-/success-symbol-0.1.0.tgz",
            +      "integrity": "sha1-JAIuSG878c3KCUKDt2nEctO3KJc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/supports-color": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
            +      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/svgo": {
            +      "version": "1.3.2",
            +      "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
            +      "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==",
            +      "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.1",
            +        "coa": "^2.0.2",
            +        "css-select": "^2.0.0",
            +        "css-select-base-adapter": "^0.1.1",
            +        "css-tree": "1.0.0-alpha.37",
            +        "csso": "^4.0.2",
            +        "js-yaml": "^3.13.1",
            +        "mkdirp": "~0.5.1",
            +        "object.values": "^1.1.0",
            +        "sax": "~1.2.4",
            +        "stable": "^0.1.8",
            +        "unquote": "~1.1.1",
            +        "util.promisify": "~1.0.0"
            +      },
            +      "bin": {
            +        "svgo": "bin/svgo"
            +      },
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/svgo/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/svgo/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/svgo/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/svgo/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/symbol-observable": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
            +      "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/symbol-tree": {
            +      "version": "3.2.4",
            +      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
            +      "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
            +      "dev": true
            +    },
            +    "node_modules/table": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
            +      "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
            +      "dev": true,
            +      "dependencies": {
            +        "ajv": "^5.2.3",
            +        "ajv-keywords": "^2.1.0",
            +        "chalk": "^2.1.0",
            +        "lodash": "^4.17.4",
            +        "slice-ansi": "1.0.0",
            +        "string-width": "^2.1.1"
            +      }
            +    },
            +    "node_modules/table/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/table/node_modules/chalk": {
            +      "version": "2.4.1",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
            +      "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/table/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/table/node_modules/supports-color": {
            +      "version": "5.4.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
            +      "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/tableize-object": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/tableize-object/-/tableize-object-0.1.0.tgz",
            +      "integrity": "sha1-fCngEzsn1ItWuedtOijSQd8bOiQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/tableize-object/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/tar-fs": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz",
            +      "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "chownr": "^1.1.1",
            +        "mkdirp-classic": "^0.5.2",
            +        "pump": "^3.0.0",
            +        "tar-stream": "^2.0.0"
            +      }
            +    },
            +    "node_modules/tar-fs/node_modules/bl": {
            +      "version": "4.0.3",
            +      "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
            +      "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "buffer": "^5.5.0",
            +        "inherits": "^2.0.4",
            +        "readable-stream": "^3.4.0"
            +      }
            +    },
            +    "node_modules/tar-fs/node_modules/bl/node_modules/inherits": {
            +      "version": "2.0.4",
            +      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
            +      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/tar-fs/node_modules/readable-stream": {
            +      "version": "3.6.0",
            +      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
            +      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "inherits": "^2.0.3",
            +        "string_decoder": "^1.1.1",
            +        "util-deprecate": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 6"
            +      }
            +    },
            +    "node_modules/tar-fs/node_modules/tar-stream": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz",
            +      "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "bl": "^4.0.1",
            +        "end-of-stream": "^1.4.1",
            +        "fs-constants": "^1.0.0",
            +        "inherits": "^2.0.3",
            +        "readable-stream": "^3.1.1"
            +      }
            +    },
            +    "node_modules/tar-stream": {
            +      "version": "1.6.1",
            +      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz",
            +      "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==",
            +      "dev": true,
            +      "dependencies": {
            +        "bl": "^1.0.0",
            +        "buffer-alloc": "^1.1.0",
            +        "end-of-stream": "^1.0.0",
            +        "fs-constants": "^1.0.0",
            +        "readable-stream": "^2.3.0",
            +        "to-buffer": "^1.1.0",
            +        "xtend": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/temp-dir": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
            +      "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/tempfile": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz",
            +      "integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=",
            +      "dev": true,
            +      "dependencies": {
            +        "temp-dir": "^1.0.0",
            +        "uuid": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/template": {
            +      "version": "0.1.8",
            +      "resolved": "https://registry.npmjs.org/template/-/template-0.1.8.tgz",
            +      "integrity": "sha1-F8rA7noO/1jda48Y6msFoHEXT8I=",
            +      "dev": true,
            +      "dependencies": {
            +        "delims": "~0.1.4",
            +        "fs-utils": "~0.4.1",
            +        "lodash": "~2.4.1",
            +        "underscore.string": "~2.3.3"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/template-error": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/template-error/-/template-error-0.1.2.tgz",
            +      "integrity": "sha1-GMn2ANkPLz37oIM+N/fLb0E1QtQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "engine": "^0.1.5",
            +        "kind-of": "^2.0.1",
            +        "lazy-cache": "^0.2.3",
            +        "rethrow": "^0.2.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/template-error/node_modules/kind-of": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz",
            +      "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/template-error/node_modules/lazy-cache": {
            +      "version": "0.2.7",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
            +      "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/template/node_modules/argparse": {
            +      "version": "0.1.16",
            +      "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz",
            +      "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=",
            +      "dev": true,
            +      "dependencies": {
            +        "underscore": "~1.7.0",
            +        "underscore.string": "~2.4.0"
            +      }
            +    },
            +    "node_modules/template/node_modules/argparse/node_modules/underscore.string": {
            +      "version": "2.4.0",
            +      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz",
            +      "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/template/node_modules/async": {
            +      "version": "0.6.2",
            +      "resolved": "https://registry.npmjs.org/async/-/async-0.6.2.tgz",
            +      "integrity": "sha1-Qf0DijgSwKi8GELs8IumPrA5K+8=",
            +      "dev": true
            +    },
            +    "node_modules/template/node_modules/esprima": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
            +      "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=",
            +      "dev": true,
            +      "bin": {
            +        "esparse": "bin/esparse.js",
            +        "esvalidate": "bin/esvalidate.js"
            +      },
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/template/node_modules/fs-utils": {
            +      "version": "0.4.3",
            +      "resolved": "https://registry.npmjs.org/fs-utils/-/fs-utils-0.4.3.tgz",
            +      "integrity": "sha1-ZBdm/lQV0RZEHexkdpjBPWz5z3c=",
            +      "dev": true,
            +      "dependencies": {
            +        "async": "~0.6.2",
            +        "globule": "~0.2.0",
            +        "graceful-fs": "~2.0.3",
            +        "js-yaml": "~3.0.2",
            +        "lodash": "~2.4.1",
            +        "mkdirp": "~0.3.5",
            +        "rimraf": "~2.2.6"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/template/node_modules/graceful-fs": {
            +      "version": "2.0.3",
            +      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz",
            +      "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=",
            +      "deprecated": "please upgrade to graceful-fs 4 for compatibility with current and future versions of Node.js",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4.0"
            +      }
            +    },
            +    "node_modules/template/node_modules/js-yaml": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.0.2.tgz",
            +      "integrity": "sha1-mTeGX46Jel6JTnPCxc8uibMut3E=",
            +      "dev": true,
            +      "dependencies": {
            +        "argparse": "~ 0.1.11",
            +        "esprima": "~ 1.0.2"
            +      },
            +      "bin": {
            +        "js-yaml": "bin/js-yaml.js"
            +      }
            +    },
            +    "node_modules/template/node_modules/lodash": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
            +      "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=",
            +      "dev": true,
            +      "engines": [
            +        "node",
            +        "rhino"
            +      ]
            +    },
            +    "node_modules/template/node_modules/mkdirp": {
            +      "version": "0.3.5",
            +      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
            +      "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=",
            +      "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
            +      "dev": true
            +    },
            +    "node_modules/template/node_modules/rimraf": {
            +      "version": "2.2.8",
            +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
            +      "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
            +      "dev": true,
            +      "bin": {
            +        "rimraf": "bin.js"
            +      }
            +    },
            +    "node_modules/template/node_modules/underscore.string": {
            +      "version": "2.3.3",
            +      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz",
            +      "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/templates": {
            +      "version": "1.2.9",
            +      "resolved": "https://registry.npmjs.org/templates/-/templates-1.2.9.tgz",
            +      "integrity": "sha1-2LDecdaTMa91XLCVM7TswtpkmAE=",
            +      "dev": true,
            +      "dependencies": {
            +        "array-sort": "^0.1.2",
            +        "async-each": "^1.0.1",
            +        "base": "^0.11.1",
            +        "base-data": "^0.6.0",
            +        "base-engines": "^0.2.0",
            +        "base-helpers": "^0.2.0",
            +        "base-option": "^0.8.4",
            +        "base-plugins": "^0.4.13",
            +        "base-routes": "^0.2.2",
            +        "debug": "^2.6.0",
            +        "deep-bind": "^0.3.0",
            +        "define-property": "^0.2.5",
            +        "engine-base": "^0.1.2",
            +        "export-files": "^2.1.1",
            +        "extend-shallow": "^2.0.1",
            +        "falsey": "^0.3.0",
            +        "get-value": "^2.0.6",
            +        "get-view": "^0.1.3",
            +        "group-array": "^0.3.1",
            +        "has-glob": "^1.0.0",
            +        "has-value": "^0.3.1",
            +        "inflection": "^1.12.0",
            +        "is-valid-app": "^0.2.1",
            +        "layouts": "^0.12.1",
            +        "lazy-cache": "^2.0.2",
            +        "match-file": "^0.2.1",
            +        "mixin-deep": "^1.1.3",
            +        "paginationator": "^0.1.4",
            +        "pascalcase": "^0.1.1",
            +        "set-value": "^0.4.0",
            +        "template-error": "^0.1.2",
            +        "vinyl-item": "^1.0.0",
            +        "vinyl-view": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/templates/node_modules/is-valid-app": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/is-valid-app/-/is-valid-app-0.2.1.tgz",
            +      "integrity": "sha1-Zc8ZW71xvXdssWGZHGhCSNZd/4k=",
            +      "dev": true,
            +      "dependencies": {
            +        "debug": "^2.2.0",
            +        "is-registered": "^0.1.5",
            +        "is-valid-instance": "^0.2.0",
            +        "lazy-cache": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/templates/node_modules/is-valid-instance": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/is-valid-instance/-/is-valid-instance-0.2.0.tgz",
            +      "integrity": "sha1-4an/EQa4y64AB+pqIPidVGoqWg8=",
            +      "dev": true,
            +      "dependencies": {
            +        "isobject": "^2.1.0",
            +        "pascalcase": "^0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/templates/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/text-table": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
            +      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
            +      "dev": true
            +    },
            +    "node_modules/through": {
            +      "version": "2.3.8",
            +      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
            +      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
            +      "dev": true
            +    },
            +    "node_modules/through2": {
            +      "version": "2.0.5",
            +      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
            +      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "readable-stream": "~2.3.6",
            +        "xtend": "~4.0.1"
            +      }
            +    },
            +    "node_modules/through2-filter": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz",
            +      "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=",
            +      "dev": true,
            +      "dependencies": {
            +        "through2": "~2.0.0",
            +        "xtend": "~4.0.0"
            +      }
            +    },
            +    "node_modules/time-diff": {
            +      "version": "0.3.1",
            +      "resolved": "https://registry.npmjs.org/time-diff/-/time-diff-0.3.1.tgz",
            +      "integrity": "sha1-Jej7c07qnmy15LA5TwWBC5yHwtg=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "is-number": "^2.1.0",
            +        "log-utils": "^0.1.0",
            +        "pretty-time": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/time-diff/node_modules/ansi-colors": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-0.1.0.tgz",
            +      "integrity": "sha1-M0rDbNPq1wjeXGnhmpjRhkImtD8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-bgblack": "^0.1.1",
            +        "ansi-bgblue": "^0.1.1",
            +        "ansi-bgcyan": "^0.1.1",
            +        "ansi-bggreen": "^0.1.1",
            +        "ansi-bgmagenta": "^0.1.1",
            +        "ansi-bgred": "^0.1.1",
            +        "ansi-bgwhite": "^0.1.1",
            +        "ansi-bgyellow": "^0.1.1",
            +        "ansi-black": "^0.1.1",
            +        "ansi-blue": "^0.1.1",
            +        "ansi-bold": "^0.1.1",
            +        "ansi-cyan": "^0.1.1",
            +        "ansi-dim": "^0.1.1",
            +        "ansi-gray": "^0.1.1",
            +        "ansi-green": "^0.1.1",
            +        "ansi-grey": "^0.1.1",
            +        "ansi-hidden": "^0.1.1",
            +        "ansi-inverse": "^0.1.1",
            +        "ansi-italic": "^0.1.1",
            +        "ansi-magenta": "^0.1.1",
            +        "ansi-red": "^0.1.1",
            +        "ansi-reset": "^0.1.1",
            +        "ansi-strikethrough": "^0.1.1",
            +        "ansi-underline": "^0.1.1",
            +        "ansi-white": "^0.1.1",
            +        "ansi-yellow": "^0.1.1",
            +        "lazy-cache": "^0.2.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/time-diff/node_modules/lazy-cache": {
            +      "version": "0.2.7",
            +      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
            +      "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/time-diff/node_modules/log-utils": {
            +      "version": "0.1.5",
            +      "resolved": "https://registry.npmjs.org/log-utils/-/log-utils-0.1.5.tgz",
            +      "integrity": "sha1-3g84+Vf0zW69Xctoddijua4HT3c=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-colors": "^0.1.0",
            +        "error-symbol": "^0.1.0",
            +        "info-symbol": "^0.1.0",
            +        "log-ok": "^0.1.1",
            +        "success-symbol": "^0.1.0",
            +        "time-stamp": "^1.0.1",
            +        "warning-symbol": "^0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/time-grunt": {
            +      "version": "1.4.0",
            +      "resolved": "https://registry.npmjs.org/time-grunt/-/time-grunt-1.4.0.tgz",
            +      "integrity": "sha1-BiIT5mDJB+hvRAVWwB6mWXtxJCA=",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^1.0.0",
            +        "date-time": "^1.1.0",
            +        "figures": "^1.0.0",
            +        "hooker": "^0.2.3",
            +        "number-is-nan": "^1.0.0",
            +        "pretty-ms": "^2.1.0",
            +        "text-table": "^0.2.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/time-stamp": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
            +      "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/time-zone": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-0.1.0.tgz",
            +      "integrity": "sha1-Sncotqwo2w4Aj1FAQ/1VW9VXO0Y=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/timed-out": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
            +      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/timers-browserify": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.2.tgz",
            +      "integrity": "sha1-q0iDz1l9zVCvIRNJoA+8pWrIa4Y=",
            +      "dev": true,
            +      "dependencies": {
            +        "setimmediate": "^1.0.4"
            +      },
            +      "engines": {
            +        "node": ">=0.6.0"
            +      }
            +    },
            +    "node_modules/timsort": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
            +      "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
            +      "dev": true
            +    },
            +    "node_modules/tiny-lr": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz",
            +      "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==",
            +      "dev": true,
            +      "dependencies": {
            +        "body": "^5.1.0",
            +        "debug": "^3.1.0",
            +        "faye-websocket": "~0.10.0",
            +        "livereload-js": "^2.3.0",
            +        "object-assign": "^4.1.0",
            +        "qs": "^6.4.0"
            +      }
            +    },
            +    "node_modules/tiny-lr/node_modules/debug": {
            +      "version": "3.2.6",
            +      "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
            +      "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
            +      "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
            +      "dev": true,
            +      "dependencies": {
            +        "ms": "^2.1.1"
            +      }
            +    },
            +    "node_modules/tiny-lr/node_modules/ms": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
            +      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
            +      "dev": true
            +    },
            +    "node_modules/tiny-lr/node_modules/qs": {
            +      "version": "6.9.1",
            +      "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz",
            +      "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.6"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/ljharb"
            +      }
            +    },
            +    "node_modules/tmp": {
            +      "version": "0.0.33",
            +      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
            +      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
            +      "dev": true,
            +      "dependencies": {
            +        "os-tmpdir": "~1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.6.0"
            +      }
            +    },
            +    "node_modules/to-absolute-glob": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz",
            +      "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-buffer": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
            +      "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
            +      "dev": true
            +    },
            +    "node_modules/to-choices": {
            +      "version": "0.2.0",
            +      "resolved": "https://registry.npmjs.org/to-choices/-/to-choices-0.2.0.tgz",
            +      "integrity": "sha1-IufnWgfWl9fkzsvVaxvwPBVlTXM=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-gray": "^0.1.1",
            +        "mixin-deep": "^1.1.3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-gfm-code-block": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/to-gfm-code-block/-/to-gfm-code-block-0.1.1.tgz",
            +      "integrity": "sha1-JdBFpfrlUxielje1kJANpzLYqoI=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-key": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/to-key/-/to-key-1.0.0.tgz",
            +      "integrity": "sha1-I5D8drsqo/VnWZhcp2O7RRV4nyo=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-map": "^1.0.0",
            +        "for-in": "^0.1.3",
            +        "kind-of": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-key/node_modules/arr-map": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-1.0.0.tgz",
            +      "integrity": "sha1-JFLm19Az++vqnGVkgfwplU+ufGU=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-key/node_modules/for-in": {
            +      "version": "0.1.8",
            +      "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz",
            +      "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-key/node_modules/kind-of": {
            +      "version": "1.1.0",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
            +      "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-object-path": {
            +      "version": "0.3.0",
            +      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
            +      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-object-path/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
            +      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^2.0.2",
            +        "extend-shallow": "^3.0.2",
            +        "regex-not": "^1.0.2",
            +        "safe-regex": "^1.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex-range": {
            +      "version": "2.1.1",
            +      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
            +      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-number": "^3.0.0",
            +        "repeat-string": "^1.6.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex-range/node_modules/is-number": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
            +      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^3.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex-range/node_modules/kind-of": {
            +      "version": "3.2.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
            +      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-buffer": "^1.1.5"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex/node_modules/define-property": {
            +      "version": "2.0.2",
            +      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
            +      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-descriptor": "^1.0.2",
            +        "isobject": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex/node_modules/extend-shallow": {
            +      "version": "3.0.2",
            +      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
            +      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
            +      "dev": true,
            +      "dependencies": {
            +        "assign-symbols": "^1.0.0",
            +        "is-extendable": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex/node_modules/is-accessor-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex/node_modules/is-data-descriptor": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
            +      "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "kind-of": "^6.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex/node_modules/is-descriptor": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
            +      "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-accessor-descriptor": "^1.0.0",
            +        "is-data-descriptor": "^1.0.0",
            +        "kind-of": "^6.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex/node_modules/is-extendable": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
            +      "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-plain-object": "^2.0.4"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/to-regex/node_modules/kind-of": {
            +      "version": "6.0.2",
            +      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
            +      "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/toidentifier": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
            +      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.6"
            +      }
            +    },
            +    "node_modules/tough-cookie": {
            +      "version": "2.5.0",
            +      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
            +      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
            +      "dev": true,
            +      "dependencies": {
            +        "psl": "^1.1.28",
            +        "punycode": "^2.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/tr46": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
            +      "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
            +      "dev": true,
            +      "dependencies": {
            +        "punycode": "^2.1.0"
            +      }
            +    },
            +    "node_modules/trim-leading-lines": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/trim-leading-lines/-/trim-leading-lines-0.1.1.tgz",
            +      "integrity": "sha1-DnysPoMELc+Vp07TaWbxd0TVwWk=",
            +      "dev": true,
            +      "dependencies": {
            +        "is-whitespace": "^0.3.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/trim-newlines": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
            +      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/trim-repeated": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
            +      "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
            +      "dev": true,
            +      "dependencies": {
            +        "escape-string-regexp": "^1.0.2"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/tslib": {
            +      "version": "1.10.0",
            +      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
            +      "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
            +      "dev": true
            +    },
            +    "node_modules/tunnel-agent": {
            +      "version": "0.6.0",
            +      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
            +      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
            +      "dev": true,
            +      "dependencies": {
            +        "safe-buffer": "^5.0.1"
            +      },
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/tweetnacl": {
            +      "version": "0.14.5",
            +      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
            +      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
            +      "dev": true
            +    },
            +    "node_modules/type-check": {
            +      "version": "0.3.2",
            +      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
            +      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
            +      "dev": true,
            +      "dependencies": {
            +        "prelude-ls": "~1.1.2"
            +      },
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/type-fest": {
            +      "version": "0.11.0",
            +      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
            +      "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=8"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/sindresorhus"
            +      }
            +    },
            +    "node_modules/typedarray": {
            +      "version": "0.0.6",
            +      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
            +      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
            +      "dev": true
            +    },
            +    "node_modules/uglify-js": {
            +      "version": "2.8.29",
            +      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
            +      "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
            +      "dev": true,
            +      "dependencies": {
            +        "source-map": "~0.5.1",
            +        "yargs": "~3.10.0"
            +      },
            +      "bin": {
            +        "uglifyjs": "bin/uglifyjs"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      },
            +      "optionalDependencies": {
            +        "uglify-to-browserify": "~1.0.0"
            +      }
            +    },
            +    "node_modules/uglify-js/node_modules/source-map": {
            +      "version": "0.5.7",
            +      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
            +      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/uglify-to-browserify": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
            +      "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/uid2": {
            +      "version": "0.0.3",
            +      "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
            +      "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=",
            +      "dev": true
            +    },
            +    "node_modules/ultron": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
            +      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
            +      "dev": true
            +    },
            +    "node_modules/unbzip2-stream": {
            +      "version": "1.3.3",
            +      "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz",
            +      "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==",
            +      "dev": true,
            +      "dependencies": {
            +        "buffer": "^5.2.1",
            +        "through": "^2.3.8"
            +      }
            +    },
            +    "node_modules/unbzip2-stream/node_modules/buffer": {
            +      "version": "5.4.3",
            +      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
            +      "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==",
            +      "dev": true,
            +      "dependencies": {
            +        "base64-js": "^1.0.2",
            +        "ieee754": "^1.1.4"
            +      }
            +    },
            +    "node_modules/unc-path-regex": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
            +      "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/uncss": {
            +      "version": "0.16.2",
            +      "resolved": "https://registry.npmjs.org/uncss/-/uncss-0.16.2.tgz",
            +      "integrity": "sha1-OyJpxZAS2nxmy+mPvt3e75TwZJw=",
            +      "dev": true,
            +      "dependencies": {
            +        "commander": "^2.9.0",
            +        "glob": "^7.0.3",
            +        "is-absolute-url": "^2.0.0",
            +        "is-html": "^1.0.0",
            +        "jsdom": "^11.3.0",
            +        "lodash": "^4.13.1",
            +        "postcss": "^6.0.14",
            +        "postcss-selector-parser": "3.1.1",
            +        "request": "^2.72.0"
            +      },
            +      "bin": {
            +        "uncss": "bin/uncss"
            +      },
            +      "engines": {
            +        "node": ">=6.0"
            +      }
            +    },
            +    "node_modules/uncss/node_modules/ansi-styles": {
            +      "version": "3.2.1",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
            +      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
            +      "dev": true,
            +      "dependencies": {
            +        "color-convert": "^1.9.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/uncss/node_modules/chalk": {
            +      "version": "2.4.2",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
            +      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "^3.2.1",
            +        "escape-string-regexp": "^1.0.5",
            +        "supports-color": "^5.3.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/uncss/node_modules/commander": {
            +      "version": "2.20.3",
            +      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
            +      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
            +      "dev": true
            +    },
            +    "node_modules/uncss/node_modules/glob": {
            +      "version": "7.1.6",
            +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
            +      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
            +      "dev": true,
            +      "dependencies": {
            +        "fs.realpath": "^1.0.0",
            +        "inflight": "^1.0.4",
            +        "inherits": "2",
            +        "minimatch": "^3.0.4",
            +        "once": "^1.3.0",
            +        "path-is-absolute": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": "*"
            +      },
            +      "funding": {
            +        "url": "https://github.com/sponsors/isaacs"
            +      }
            +    },
            +    "node_modules/uncss/node_modules/has-flag": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
            +      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/uncss/node_modules/postcss": {
            +      "version": "6.0.23",
            +      "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
            +      "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "^2.4.1",
            +        "source-map": "^0.6.1",
            +        "supports-color": "^5.4.0"
            +      },
            +      "engines": {
            +        "node": ">=4.0.0"
            +      }
            +    },
            +    "node_modules/uncss/node_modules/postcss-selector-parser": {
            +      "version": "3.1.1",
            +      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
            +      "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
            +      "dev": true,
            +      "dependencies": {
            +        "dot-prop": "^4.1.1",
            +        "indexes-of": "^1.0.1",
            +        "uniq": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/uncss/node_modules/postcss-selector-parser/node_modules/dot-prop": {
            +      "version": "4.2.1",
            +      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz",
            +      "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "is-obj": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/uncss/node_modules/supports-color": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
            +      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
            +      "dev": true,
            +      "dependencies": {
            +        "has-flag": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/underscore": {
            +      "version": "1.7.0",
            +      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
            +      "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=",
            +      "dev": true
            +    },
            +    "node_modules/underscore.string": {
            +      "version": "2.4.0",
            +      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz",
            +      "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=",
            +      "dev": true,
            +      "engines": {
            +        "node": "*"
            +      }
            +    },
            +    "node_modules/union-value": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
            +      "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "get-value": "^2.0.6",
            +        "is-extendable": "^0.1.1",
            +        "set-value": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/union-value/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/union-value/node_modules/set-value": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
            +      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
            +      "dev": true,
            +      "dependencies": {
            +        "extend-shallow": "^2.0.1",
            +        "is-extendable": "^0.1.1",
            +        "is-plain-object": "^2.0.3",
            +        "split-string": "^3.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/uniq": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
            +      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
            +      "dev": true
            +    },
            +    "node_modules/uniqs": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
            +      "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
            +      "dev": true
            +    },
            +    "node_modules/unique-stream": {
            +      "version": "2.3.1",
            +      "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
            +      "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
            +      "dev": true,
            +      "dependencies": {
            +        "json-stable-stringify-without-jsonify": "^1.0.1",
            +        "through2-filter": "^3.0.0"
            +      }
            +    },
            +    "node_modules/unique-stream/node_modules/through2-filter": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
            +      "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
            +      "dev": true,
            +      "dependencies": {
            +        "through2": "~2.0.0",
            +        "xtend": "~4.0.0"
            +      }
            +    },
            +    "node_modules/universalify": {
            +      "version": "2.0.0",
            +      "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
            +      "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 10.0.0"
            +      }
            +    },
            +    "node_modules/unpipe": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
            +      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8"
            +      }
            +    },
            +    "node_modules/unquote": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
            +      "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=",
            +      "dev": true
            +    },
            +    "node_modules/unset-value": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
            +      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
            +      "dev": true,
            +      "dependencies": {
            +        "has-value": "^0.3.1",
            +        "isobject": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/upath": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
            +      "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
            +      "engines": {
            +        "node": ">=4",
            +        "yarn": "*"
            +      }
            +    },
            +    "node_modules/upper-case": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
            +      "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=",
            +      "dev": true
            +    },
            +    "node_modules/uri-js": {
            +      "version": "4.2.2",
            +      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
            +      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "punycode": "^2.1.0"
            +      }
            +    },
            +    "node_modules/uri-path": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz",
            +      "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/urix": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
            +      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
            +      "deprecated": "Please see https://github.com/lydell/urix#deprecated",
            +      "dev": true
            +    },
            +    "node_modules/url": {
            +      "version": "0.11.0",
            +      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
            +      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
            +      "dev": true,
            +      "dependencies": {
            +        "punycode": "1.3.2",
            +        "querystring": "0.2.0"
            +      }
            +    },
            +    "node_modules/url-parse-lax": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
            +      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
            +      "dev": true,
            +      "dependencies": {
            +        "prepend-http": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/url-to-options": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
            +      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 4"
            +      }
            +    },
            +    "node_modules/url/node_modules/punycode": {
            +      "version": "1.3.2",
            +      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
            +      "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
            +      "dev": true
            +    },
            +    "node_modules/use": {
            +      "version": "1.1.2",
            +      "resolved": "https://registry.npmjs.org/use/-/use-1.1.2.tgz",
            +      "integrity": "sha1-bjgy/rholXNJSsanrLX++zd7LNE=",
            +      "dev": true,
            +      "dependencies": {
            +        "define-property": "^0.2.5",
            +        "isobject": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/use/node_modules/isobject": {
            +      "version": "2.1.0",
            +      "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
            +      "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
            +      "dev": true,
            +      "dependencies": {
            +        "isarray": "1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/util": {
            +      "version": "0.10.3",
            +      "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
            +      "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
            +      "dev": true,
            +      "dependencies": {
            +        "inherits": "2.0.1"
            +      }
            +    },
            +    "node_modules/util-deprecate": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
            +      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
            +      "dev": true
            +    },
            +    "node_modules/util.promisify": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
            +      "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
            +      "dev": true,
            +      "dependencies": {
            +        "define-properties": "^1.1.2",
            +        "object.getownpropertydescriptors": "^2.0.3"
            +      }
            +    },
            +    "node_modules/util/node_modules/inherits": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
            +      "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
            +      "dev": true
            +    },
            +    "node_modules/utils-merge": {
            +      "version": "1.0.1",
            +      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
            +      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.4.0"
            +      }
            +    },
            +    "node_modules/uuid": {
            +      "version": "3.3.2",
            +      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
            +      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
            +      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
            +      "dev": true,
            +      "bin": {
            +        "uuid": "bin/uuid"
            +      }
            +    },
            +    "node_modules/v8flags": {
            +      "version": "3.2.0",
            +      "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz",
            +      "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
            +      "dev": true,
            +      "dependencies": {
            +        "homedir-polyfill": "^1.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/vali-date": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz",
            +      "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/validate-npm-package-license": {
            +      "version": "3.0.3",
            +      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
            +      "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==",
            +      "dev": true,
            +      "dependencies": {
            +        "spdx-correct": "^3.0.0",
            +        "spdx-expression-parse": "^3.0.0"
            +      }
            +    },
            +    "node_modules/vendors": {
            +      "version": "1.0.4",
            +      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
            +      "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==",
            +      "dev": true,
            +      "funding": {
            +        "type": "github",
            +        "url": "https://github.com/sponsors/wooorm"
            +      }
            +    },
            +    "node_modules/verbalize": {
            +      "version": "0.1.2",
            +      "resolved": "https://registry.npmjs.org/verbalize/-/verbalize-0.1.2.tgz",
            +      "integrity": "sha1-Fl/aRkAzFUj46ZCx1+FDletyAgc=",
            +      "dev": true,
            +      "dependencies": {
            +        "chalk": "~0.4.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0",
            +        "npm": ">=1.2.10"
            +      }
            +    },
            +    "node_modules/verbalize/node_modules/ansi-styles": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz",
            +      "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/verbalize/node_modules/chalk": {
            +      "version": "0.4.0",
            +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz",
            +      "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-styles": "~1.0.0",
            +        "has-color": "~0.1.0",
            +        "strip-ansi": "~0.1.0"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/verbalize/node_modules/strip-ansi": {
            +      "version": "0.1.1",
            +      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz",
            +      "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=",
            +      "dev": true,
            +      "bin": {
            +        "strip-ansi": "cli.js"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/verror": {
            +      "version": "1.10.0",
            +      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
            +      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
            +      "dev": true,
            +      "engines": [
            +        "node >=0.6.0"
            +      ],
            +      "dependencies": {
            +        "assert-plus": "^1.0.0",
            +        "core-util-is": "1.0.2",
            +        "extsprintf": "^1.2.0"
            +      }
            +    },
            +    "node_modules/vinyl": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz",
            +      "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "clone": "^1.0.0",
            +        "clone-stats": "^0.0.1",
            +        "replace-ext": "0.0.1"
            +      },
            +      "engines": {
            +        "node": ">= 0.9"
            +      }
            +    },
            +    "node_modules/vinyl-fs": {
            +      "version": "2.4.4",
            +      "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.4.tgz",
            +      "integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=",
            +      "dev": true,
            +      "dependencies": {
            +        "duplexify": "^3.2.0",
            +        "glob-stream": "^5.3.2",
            +        "graceful-fs": "^4.0.0",
            +        "gulp-sourcemaps": "1.6.0",
            +        "is-valid-glob": "^0.3.0",
            +        "lazystream": "^1.0.0",
            +        "lodash.isequal": "^4.0.0",
            +        "merge-stream": "^1.0.0",
            +        "mkdirp": "^0.5.0",
            +        "object-assign": "^4.0.0",
            +        "readable-stream": "^2.0.4",
            +        "strip-bom": "^2.0.0",
            +        "strip-bom-stream": "^1.0.0",
            +        "through2": "^2.0.0",
            +        "through2-filter": "^2.0.0",
            +        "vali-date": "^1.0.0",
            +        "vinyl": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10"
            +      }
            +    },
            +    "node_modules/vinyl-item": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/vinyl-item/-/vinyl-item-1.0.0.tgz",
            +      "integrity": "sha1-5BiPq3lRVN6edFiOqtPfS6UVFpI=",
            +      "dev": true,
            +      "dependencies": {
            +        "base": "^0.11.1",
            +        "base-option": "^0.8.4",
            +        "base-plugins": "^0.4.13",
            +        "clone": "^2.1.0",
            +        "clone-stats": "^1.0.0",
            +        "define-property": "^0.2.5",
            +        "extend-shallow": "^2.0.1",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.2",
            +        "vinyl": "^2.0.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/vinyl-item/node_modules/clone": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
            +      "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8"
            +      }
            +    },
            +    "node_modules/vinyl-item/node_modules/clone-stats": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
            +      "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
            +      "dev": true
            +    },
            +    "node_modules/vinyl-item/node_modules/replace-ext": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
            +      "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/vinyl-item/node_modules/vinyl": {
            +      "version": "2.2.0",
            +      "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
            +      "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
            +      "dev": true,
            +      "dependencies": {
            +        "clone": "^2.1.1",
            +        "clone-buffer": "^1.0.0",
            +        "clone-stats": "^1.0.0",
            +        "cloneable-readable": "^1.0.0",
            +        "remove-trailing-separator": "^1.0.1",
            +        "replace-ext": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10"
            +      }
            +    },
            +    "node_modules/vinyl-view": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/vinyl-view/-/vinyl-view-2.0.1.tgz",
            +      "integrity": "sha1-RqTZn6hoi/N5EoaPkSZloVtmgWo=",
            +      "dev": true,
            +      "dependencies": {
            +        "arr-union": "^3.1.0",
            +        "define-property": "^0.2.5",
            +        "engine-base": "^0.1.2",
            +        "extend-shallow": "^2.0.1",
            +        "isobject": "^3.0.0",
            +        "lazy-cache": "^2.0.2",
            +        "vinyl-item": "^1.0.0"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/vinyl-view/node_modules/arr-union": {
            +      "version": "3.1.0",
            +      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
            +      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/vnu-jar": {
            +      "version": "19.9.4",
            +      "resolved": "https://registry.npmjs.org/vnu-jar/-/vnu-jar-19.9.4.tgz",
            +      "integrity": "sha512-x91WyaNr1oPJaYZkbyMElRyV60BUaxPuhm3zXXjlFOpW3E2KavPWlyohX0LTf6gX7/tujIMgLE5UGc0jn7o4XQ==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10"
            +      }
            +    },
            +    "node_modules/void-elements": {
            +      "version": "2.0.1",
            +      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
            +      "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/w3c-hr-time": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
            +      "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "browser-process-hrtime": "^1.0.0"
            +      }
            +    },
            +    "node_modules/walkdir": {
            +      "version": "0.0.11",
            +      "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz",
            +      "integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.6.0"
            +      }
            +    },
            +    "node_modules/warning-symbol": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/warning-symbol/-/warning-symbol-0.1.0.tgz",
            +      "integrity": "sha1-uzHdEbeg+dZ6su2V9Fe2WCW7rSE=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/webidl-conversions": {
            +      "version": "4.0.2",
            +      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
            +      "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
            +      "dev": true
            +    },
            +    "node_modules/websocket-driver": {
            +      "version": "0.7.3",
            +      "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz",
            +      "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==",
            +      "dev": true,
            +      "dependencies": {
            +        "http-parser-js": ">=0.4.0 <0.4.11",
            +        "safe-buffer": ">=5.1.0",
            +        "websocket-extensions": ">=0.1.1"
            +      },
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/websocket-extensions": {
            +      "version": "0.1.3",
            +      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
            +      "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.8.0"
            +      }
            +    },
            +    "node_modules/websocket-stream": {
            +      "version": "5.5.0",
            +      "resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-5.5.0.tgz",
            +      "integrity": "sha512-EXy/zXb9kNHI07TIMz1oIUIrPZxQRA8aeJ5XYg5ihV8K4kD1DuA+FY6R96HfdIHzlSzS8HiISAfrm+vVQkZBug==",
            +      "dev": true,
            +      "dependencies": {
            +        "duplexify": "^3.5.1",
            +        "inherits": "^2.0.1",
            +        "readable-stream": "^2.3.3",
            +        "safe-buffer": "^5.1.2",
            +        "ws": "^3.2.0",
            +        "xtend": "^4.0.0"
            +      }
            +    },
            +    "node_modules/websocket-stream/node_modules/ws": {
            +      "version": "3.3.3",
            +      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
            +      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
            +      "dev": true,
            +      "dependencies": {
            +        "async-limiter": "~1.0.0",
            +        "safe-buffer": "~5.1.0",
            +        "ultron": "~1.1.0"
            +      }
            +    },
            +    "node_modules/whatwg-encoding": {
            +      "version": "1.0.5",
            +      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
            +      "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
            +      "dev": true,
            +      "dependencies": {
            +        "iconv-lite": "0.4.24"
            +      }
            +    },
            +    "node_modules/whatwg-encoding/node_modules/iconv-lite": {
            +      "version": "0.4.24",
            +      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
            +      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
            +      "dev": true,
            +      "dependencies": {
            +        "safer-buffer": ">= 2.1.2 < 3"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/whatwg-mimetype": {
            +      "version": "2.3.0",
            +      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
            +      "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
            +      "dev": true
            +    },
            +    "node_modules/whatwg-url": {
            +      "version": "6.5.0",
            +      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
            +      "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "lodash.sortby": "^4.7.0",
            +        "tr46": "^1.0.1",
            +        "webidl-conversions": "^4.0.2"
            +      }
            +    },
            +    "node_modules/which": {
            +      "version": "1.3.1",
            +      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
            +      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
            +      "dev": true,
            +      "dependencies": {
            +        "isexe": "^2.0.0"
            +      },
            +      "bin": {
            +        "which": "bin/which"
            +      }
            +    },
            +    "node_modules/which-pm-runs": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
            +      "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
            +      "dev": true,
            +      "optional": true
            +    },
            +    "node_modules/wide-align": {
            +      "version": "1.1.3",
            +      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
            +      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
            +      "dev": true,
            +      "optional": true,
            +      "dependencies": {
            +        "string-width": "^1.0.2 || 2"
            +      }
            +    },
            +    "node_modules/window-size": {
            +      "version": "0.1.0",
            +      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
            +      "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 0.8.0"
            +      }
            +    },
            +    "node_modules/wordwrap": {
            +      "version": "1.0.0",
            +      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
            +      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
            +      "dev": true
            +    },
            +    "node_modules/wrap-ansi": {
            +      "version": "3.0.1",
            +      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz",
            +      "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=",
            +      "dev": true,
            +      "dependencies": {
            +        "string-width": "^2.1.1",
            +        "strip-ansi": "^4.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/wrap-ansi/node_modules/ansi-regex": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
            +      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/wrap-ansi/node_modules/strip-ansi": {
            +      "version": "4.0.0",
            +      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
            +      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
            +      "dev": true,
            +      "dependencies": {
            +        "ansi-regex": "^3.0.0"
            +      },
            +      "engines": {
            +        "node": ">=4"
            +      }
            +    },
            +    "node_modules/wrappy": {
            +      "version": "1.0.2",
            +      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
            +      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
            +      "dev": true
            +    },
            +    "node_modules/write": {
            +      "version": "0.2.1",
            +      "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
            +      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
            +      "dev": true,
            +      "dependencies": {
            +        "mkdirp": "^0.5.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/write-json": {
            +      "version": "0.2.2",
            +      "resolved": "https://registry.npmjs.org/write-json/-/write-json-0.2.2.tgz",
            +      "integrity": "sha1-+k4VKennY6T5LwfZhBMX49JI2vM=",
            +      "dev": true,
            +      "dependencies": {
            +        "write": "^0.2.1"
            +      },
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/ws": {
            +      "version": "5.2.2",
            +      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
            +      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
            +      "dev": true,
            +      "dependencies": {
            +        "async-limiter": "~1.0.0"
            +      }
            +    },
            +    "node_modules/xml-name-validator": {
            +      "version": "3.0.0",
            +      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
            +      "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
            +      "dev": true
            +    },
            +    "node_modules/xtend": {
            +      "version": "4.0.1",
            +      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
            +      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.4"
            +      }
            +    },
            +    "node_modules/yallist": {
            +      "version": "2.1.2",
            +      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
            +      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
            +      "dev": true
            +    },
            +    "node_modules/yaml": {
            +      "version": "1.10.2",
            +      "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
            +      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
            +      "dev": true,
            +      "engines": {
            +        "node": ">= 6"
            +      }
            +    },
            +    "node_modules/yargs": {
            +      "version": "3.10.0",
            +      "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
            +      "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
            +      "dev": true,
            +      "dependencies": {
            +        "camelcase": "^1.0.2",
            +        "cliui": "^2.1.0",
            +        "decamelize": "^1.0.0",
            +        "window-size": "0.1.0"
            +      }
            +    },
            +    "node_modules/yargs-parser": {
            +      "version": "2.4.1",
            +      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
            +      "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "camelcase": "^3.0.0",
            +        "lodash.assign": "^4.0.6"
            +      }
            +    },
            +    "node_modules/yargs/node_modules/camelcase": {
            +      "version": "1.2.1",
            +      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
            +      "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
            +      "dev": true,
            +      "engines": {
            +        "node": ">=0.10.0"
            +      }
            +    },
            +    "node_modules/yauzl": {
            +      "version": "2.10.0",
            +      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
            +      "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
            +      "dev": true,
            +      "dependencies": {
            +        "buffer-crc32": "~0.2.3",
            +        "fd-slicer": "~1.1.0"
            +      }
            +    },
            +    "node_modules/zip-stream": {
            +      "version": "1.2.0",
            +      "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz",
            +      "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=",
            +      "dev": true,
            +      "dependencies": {
            +        "archiver-utils": "^1.3.0",
            +        "compress-commons": "^1.2.0",
            +        "lodash": "^4.8.0",
            +        "readable-stream": "^2.0.0"
            +      },
            +      "engines": {
            +        "node": ">= 0.10.0"
            +      }
            +    }
            +  },
               "dependencies": {
                 "@fluent/syntax": {
                   "version": "0.17.0",
            @@ -197,7 +25983,8 @@
                   "version": "2.1.1",
                   "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
                   "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
            -      "dev": true
            +      "dev": true,
            +      "requires": {}
                 },
                 "align-text": {
                   "version": "0.1.4",
            @@ -7945,7 +33732,8 @@
                   "version": "0.5.0",
                   "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-0.5.0.tgz",
                   "integrity": "sha1-QQB1rEWlhWuhkbHMclclRQ1KAhU=",
            -      "dev": true
            +      "dev": true,
            +      "requires": {}
                 },
                 "grunt-contrib-imagemin": {
                   "version": "3.1.0",
            @@ -8073,13 +33861,15 @@
                   "version": "1.0.1",
                   "resolved": "https://registry.npmjs.org/grunt-exec/-/grunt-exec-1.0.1.tgz",
                   "integrity": "sha1-5dU6OcXzRpATBe3uXIfbDyr5mcQ=",
            -      "dev": true
            +      "dev": true,
            +      "requires": {}
                 },
                 "grunt-file-append": {
                   "version": "0.0.7",
                   "resolved": "https://registry.npmjs.org/grunt-file-append/-/grunt-file-append-0.0.7.tgz",
                   "integrity": "sha1-P376M2lvoFdwsoCU9EUIyvxdLto=",
            -      "dev": true
            +      "dev": true,
            +      "requires": {}
                 },
                 "grunt-html": {
                   "version": "11.1.1",
            @@ -18472,6 +44262,15 @@
                   "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
                   "dev": true
                 },
            +    "string_decoder": {
            +      "version": "1.1.1",
            +      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
            +      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            +      "dev": true,
            +      "requires": {
            +        "safe-buffer": "~5.1.0"
            +      }
            +    },
                 "string-argv": {
                   "version": "0.3.1",
                   "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
            @@ -18537,15 +44336,6 @@
                     "function-bind": "^1.1.1"
                   }
                 },
            -    "string_decoder": {
            -      "version": "1.1.1",
            -      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
            -      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
            -      "dev": true,
            -      "requires": {
            -        "safe-buffer": "~5.1.0"
            -      }
            -    },
                 "stringify-author": {
                   "version": "0.1.3",
                   "resolved": "https://registry.npmjs.org/stringify-author/-/stringify-author-0.1.3.tgz",
            diff --git a/src/assets/img/books/book.png b/src/assets/img/books/book.png
            new file mode 100644
            index 0000000000..4e65fed410
            Binary files /dev/null and b/src/assets/img/books/book.png differ
            diff --git a/src/assets/img/books/book2.png b/src/assets/img/books/book2.png
            new file mode 100644
            index 0000000000..7c43f2f931
            Binary files /dev/null and b/src/assets/img/books/book2.png differ
            diff --git a/src/assets/img/books/book3.png b/src/assets/img/books/book3.png
            new file mode 100644
            index 0000000000..0300f51fc1
            Binary files /dev/null and b/src/assets/img/books/book3.png differ
            diff --git a/src/assets/img/books/book4.png b/src/assets/img/books/book4.png
            new file mode 100644
            index 0000000000..a93ea669a7
            Binary files /dev/null and b/src/assets/img/books/book4.png differ
            diff --git a/src/assets/js/reference.js b/src/assets/js/reference.js
            index 785e171d4b..b7dfe488c8 100644
            --- a/src/assets/js/reference.js
            +++ b/src/assets/js/reference.js
            @@ -448,10 +448,10 @@ define('text',['module'], function (module) {
             });
             
             
            -define('text!tpl/search.html',[],function () { return '<h2 class="sr-only">search</h2>\n<form>\n  <input id="search_reference_field" type="text" class="<%=className%>" value="" placeholder="<%=placeholder%>" aria-label="search reference">\n  <label class="sr-only" for="search_reference_field">Search reference</label>\n</form>\n\n';});
            +define('text!tpl/search.html',[],function () { return '<h2 class="sr-only">search</h2>\r\n<form>\r\n  <input id="search_reference_field" type="text" class="<%=className%>" value="" placeholder="<%=placeholder%>" aria-label="search reference">\r\n  <label class="sr-only" for="search_reference_field">Search reference</label>\r\n</form>\r\n\r\n';});
             
             
            -define('text!tpl/search_suggestion.html',[],function () { return '<p id="index-<%=idx%>" class="search-suggestion">\n\n  <strong><%=name%></strong>\n\n  <span class="small">\n    <% if (final) { %>\n    constant\n    <% } else if (itemtype) { %>\n    <%=itemtype%> \n    <% } %>\n\n    <% if (className) { %>\n    in <strong><%=className%></strong>\n    <% } %>\n\n    <% if (typeof is_constructor !== \'undefined\' && is_constructor) { %>\n    <strong><span class="glyphicon glyphicon-star"></span> constructor</strong>\n    <% } %>\n  </span>\n\n</p>';});
            +define('text!tpl/search_suggestion.html',[],function () { return '<p id="index-<%=idx%>" class="search-suggestion">\r\n\r\n  <strong><%=name%></strong>\r\n\r\n  <span class="small">\r\n    <% if (final) { %>\r\n    constant\r\n    <% } else if (itemtype) { %>\r\n    <%=itemtype%> \r\n    <% } %>\r\n\r\n    <% if (className) { %>\r\n    in <strong><%=className%></strong>\r\n    <% } %>\r\n\r\n    <% if (typeof is_constructor !== \'undefined\' && is_constructor) { %>\r\n    <strong><span class="glyphicon glyphicon-star"></span> constructor</strong>\r\n    <% } %>\r\n  </span>\r\n\r\n</p>';});
             
             /*!
              * typeahead.js 0.10.2
            @@ -2303,7 +2303,7 @@ define('searchView',[
             });
             
             
            -define('text!tpl/list.html',[],function () { return '<% _.each(groups, function(group){ %>\n  <div class="reference-group clearfix main-ref-page">  \n    <h2 class="group-name" id="group-<%=group.name%>" tab-index="-1"><%=group.name%></h2>\n    <div class="reference-subgroups clearfix main-ref-page">  \n    <% _.each(group.subgroups, function(subgroup, ind) { %>\n      <div class="reference-subgroup">\n        <% if (subgroup.name !== \'0\') { %>\n          <h3 id="<%=group.name%><%=ind%>" class="subgroup-name subgroup-<%=subgroup.name%>"><%=subgroup.name%></h3>\n        <% } %>\n        <ul aria-labelledby="<%=group.name%> <%=ind%>">\n        <% _.each(subgroup.items, function(item) { %>\n        <li><a href="<%=item.hash%>"><%=item.name%><% if (item.itemtype === \'method\') { %>()<%}%></a></li>\n        <% }); %>\n        </ul>\n      </div>\n    <% }); %>\n    </div>\n  </div>\n<% }); %>\n';});
            +define('text!tpl/list.html',[],function () { return '<% _.each(groups, function(group){ %>\r\n  <div class="reference-group clearfix main-ref-page">  \r\n    <h2 class="group-name" id="group-<%=group.name%>" tab-index="-1"><%=group.name%></h2>\r\n    <div class="reference-subgroups clearfix main-ref-page">  \r\n    <% _.each(group.subgroups, function(subgroup, ind) { %>\r\n      <div class="reference-subgroup">\r\n        <% if (subgroup.name !== \'0\') { %>\r\n          <h3 id="<%=group.name%><%=ind%>" class="subgroup-name subgroup-<%=subgroup.name%>"><%=subgroup.name%></h3>\r\n        <% } %>\r\n        <ul aria-labelledby="<%=group.name%> <%=ind%>">\r\n        <% _.each(subgroup.items, function(item) { %>\r\n        <li><a href="<%=item.hash%>"><%=item.name%><% if (item.itemtype === \'method\') { %>()<%}%></a></li>\r\n        <% }); %>\r\n        </ul>\r\n      </div>\r\n    <% }); %>\r\n    </div>\r\n  </div>\r\n<% }); %>\r\n';});
             
             define('listView',[
               'App',
            @@ -2445,13 +2445,13 @@ define('listView',[
             });
             
             
            -define('text!tpl/item.html',[],function () { return '<h2><%=item.name%><% if (item.isMethod) { %>()<% } %></h2>\n\n<% if (item.example) { %>\n<div class="example">\n  <h3 id="reference-example">Examples</h3>\n\n  <div class="example-content" data-alt="<%= item.alt %>">\n    <% _.each(item.example, function(example, i){ %>\n      <%= example %>\n    <% }); %>\n  </div>\n</div>\n<% } %>\n\n<div class="description">\n\n  <h3 id="reference-description">Description</h3>\n\n  <% if (item.deprecated) { %>\n    <p>\n      Deprecated: <%=item.name%><% if (item.isMethod) { %>()<% } %> is deprecated and will be removed in a future version of p5. <% if (item.deprecationMessage) { %><%=item.deprecationMessage%><% } %>\n    </p>\n  <% } %>\n\n\n  <span class=\'description-text\'><%= item.description %></span>\n\n  <% if (item.extends) { %>\n    <p><span id="reference-extends">Extends</span> <a href="/reference/#/<%=item.extends%>" title="<%=item.extends%> reference"><%=item.extends%></a></p>\n  <% } %>\n\n  <% if (item.module === \'p5.sound\') { %>\n    <p>This function requires you include the p5.sound library.  Add the following into the head of your index.html file:\n      <pre><code class="language-javascript">&lt;script src="path/to/p5.sound.js"&gt;&lt;/script&gt;</code></pre>\n    </p>\n  <% } %>\n\n  <% if (item.constRefs) { %>\n    <p>Used by:\n  <%\n      var refs = item.constRefs;\n      for (var i = 0; i < refs.length; i ++) {\n        var ref = refs[i];\n        var name = ref;\n        if (name.substr(0, 3) === \'p5.\') {\n          name = name.substr(3);\n        }\n  if (i !== 0) {\n          if (i == refs.length - 1) {\n            %> and <%\n          } else {\n            %>, <%\n          }\n        }\n        %><a href="./#/<%= ref.replace(\'.\', \'/\') %>"><%= name %>()</a><%\n      }\n  %>\n    </p>\n  <% } %>\n</div>\n\n<% if (isConstructor || !isClass) { %>\n\n<div class="syntax">\n  <h3 id="reference-syntax">Syntax</h3>\n  <p>\n    <% syntaxes.forEach(function(syntax) { %>\n    <pre class="language-javascript"><%= syntax %></pre>\n    <% }) %>\n  </p>\n</div>\n\n\n<% if (item.params) { %>\n  <div class="params">\n    <h3 id="reference-parameters">Parameters</h3>\n    <ul aria-labelledby=\'reference-parameters\'>\n    <% for (var i=0; i<item.params.length; i++) { %>\n      <% var p = item.params[i] %>\n      <li>\n        <div class=\'paramname\'><%=p.name%></div>\n        <% if (p.type) { %>\n          <div class=\'paramtype\'>\n          <% var type = p.type.replace(/(p5\\.[A-Z][A-Za-z]*)/, \'<a href="#/$1">$1</a>\'); %>\n          <span class="param-type label label-info"><%=type%></span>: <%=p.description%>\n          <% if (p.optional) { %> (Optional)<% } %>\n          </div>\n        <% } %>\n      </li>\n    <% } %>\n    </ul>\n  </div>\n<% } %>\n\n<% if (item.return && item.return.type) { %>\n  <div>\n    <h3 id="reference-returns">Returns</h3>\n    <p class=\'returns\'><span class="param-type label label-info"><%=item.return.type%></span>: <%= item.return.description %></p>\n  </div>\n<% } %>\n\n<% } %>\n';});
            +define('text!tpl/item.html',[],function () { return '<h2><%=item.name%><% if (item.isMethod) { %>()<% } %></h2>\r\n\r\n<% if (item.example) { %>\r\n<div class="example">\r\n  <h3 id="reference-example">Examples</h3>\r\n\r\n  <div class="example-content" data-alt="<%= item.alt %>">\r\n    <% _.each(item.example, function(example, i){ %>\r\n      <%= example %>\r\n    <% }); %>\r\n  </div>\r\n</div>\r\n<% } %>\r\n\r\n<div class="description">\r\n\r\n  <h3 id="reference-description">Description</h3>\r\n\r\n  <% if (item.deprecated) { %>\r\n    <p>\r\n      Deprecated: <%=item.name%><% if (item.isMethod) { %>()<% } %> is deprecated and will be removed in a future version of p5. <% if (item.deprecationMessage) { %><%=item.deprecationMessage%><% } %>\r\n    </p>\r\n  <% } %>\r\n\r\n\r\n  <span class=\'description-text\'><%= item.description %></span>\r\n\r\n  <% if (item.extends) { %>\r\n    <p><span id="reference-extends">Extends</span> <a href="/reference/#/<%=item.extends%>" title="<%=item.extends%> reference"><%=item.extends%></a></p>\r\n  <% } %>\r\n\r\n  <% if (item.module === \'p5.sound\') { %>\r\n    <p>This function requires you include the p5.sound library.  Add the following into the head of your index.html file:\r\n      <pre><code class="language-javascript">&lt;script src="path/to/p5.sound.js"&gt;&lt;/script&gt;</code></pre>\r\n    </p>\r\n  <% } %>\r\n\r\n  <% if (item.constRefs) { %>\r\n    <p>Used by:\r\n  <%\r\n      var refs = item.constRefs;\r\n      for (var i = 0; i < refs.length; i ++) {\r\n        var ref = refs[i];\r\n        var name = ref;\r\n        if (name.substr(0, 3) === \'p5.\') {\r\n          name = name.substr(3);\r\n        }\r\n  if (i !== 0) {\r\n          if (i == refs.length - 1) {\r\n            %> and <%\r\n          } else {\r\n            %>, <%\r\n          }\r\n        }\r\n        %><a href="./#/<%= ref.replace(\'.\', \'/\') %>"><%= name %>()</a><%\r\n      }\r\n  %>\r\n    </p>\r\n  <% } %>\r\n</div>\r\n\r\n<% if (isConstructor || !isClass) { %>\r\n\r\n<div class="syntax">\r\n  <h3 id="reference-syntax">Syntax</h3>\r\n  <p>\r\n    <% syntaxes.forEach(function(syntax) { %>\r\n    <pre class="language-javascript"><%= syntax %></pre>\r\n    <% }) %>\r\n  </p>\r\n</div>\r\n\r\n\r\n<% if (item.params) { %>\r\n  <div class="params">\r\n    <h3 id="reference-parameters">Parameters</h3>\r\n    <ul aria-labelledby=\'reference-parameters\'>\r\n    <% for (var i=0; i<item.params.length; i++) { %>\r\n      <% var p = item.params[i] %>\r\n      <li>\r\n        <div class=\'paramname\'><%=p.name%></div>\r\n        <% if (p.type) { %>\r\n          <div class=\'paramtype\'>\r\n          <% var type = p.type.replace(/(p5\\.[A-Z][A-Za-z]*)/, \'<a href="#/$1">$1</a>\'); %>\r\n          <span class="param-type label label-info"><%=type%></span>: <%=p.description%>\r\n          <% if (p.optional) { %> (Optional)<% } %>\r\n          </div>\r\n        <% } %>\r\n      </li>\r\n    <% } %>\r\n    </ul>\r\n  </div>\r\n<% } %>\r\n\r\n<% if (item.return && item.return.type) { %>\r\n  <div>\r\n    <h3 id="reference-returns">Returns</h3>\r\n    <p class=\'returns\'><span class="param-type label label-info"><%=item.return.type%></span>: <%= item.return.description %></p>\r\n  </div>\r\n<% } %>\r\n\r\n<% } %>\r\n';});
             
             
            -define('text!tpl/class.html',[],function () { return '\n<% if (typeof constructor !== \'undefined\') { %>\n<div class="constructor">\n  <%=constructor%>\n</div>\n<% } %>\n\n<% let fields = _.filter(things, function(item) { return item.itemtype === \'property\' && item.access !== \'private\' }); %>\n<% if (fields.length > 0) { %>\n  <h3 id=\'reference-fields\'>Fields</h3>\n  <ul aria-labelledby=\'reference-fields\'>\n  <% _.each(fields, function(item) { %>\n    <li>\n      <div class=\'paramname\'><a href="<%=item.hash%>" <% if (item.module !== module) { %>class="addon"<% } %>><%=item.name%></a></div>\n      <div class=\'paramtype\'><%= item.description %></div>\n    </li>\n  <% }); %>\n  </ul>\n<% } %>\n\n<% let methods = _.filter(things, function(item) { return item.itemtype === \'method\' && item.access !== \'private\' }); %>\n<% if (methods.length > 0) { %>\n  <h3 id=\'reference-methods\'>Methods</h3>\n  <ul aria-labelledby=\'reference-methods\'>\n    <% _.each(methods, function(item) { %>\n      <li>\n        <div class=\'paramname\'><a href="<%=item.hash%>" <% if (item.module !== module) { %>class="addon"<% } %>><%=item.name%><% if (item.itemtype === \'method\') { %>()<%}%></a></div>\n        <div class=\'paramtype\'><%= item.description %></div>\n      </li>\n    <% }); %>\n  </ul>\n<% } %>\n';});
            +define('text!tpl/class.html',[],function () { return '\r\n<% if (typeof constructor !== \'undefined\') { %>\r\n<div class="constructor">\r\n  <%=constructor%>\r\n</div>\r\n<% } %>\r\n\r\n<% let fields = _.filter(things, function(item) { return item.itemtype === \'property\' && item.access !== \'private\' }); %>\r\n<% if (fields.length > 0) { %>\r\n  <h3 id=\'reference-fields\'>Fields</h3>\r\n  <ul aria-labelledby=\'reference-fields\'>\r\n  <% _.each(fields, function(item) { %>\r\n    <li>\r\n      <div class=\'paramname\'><a href="<%=item.hash%>" <% if (item.module !== module) { %>class="addon"<% } %>><%=item.name%></a></div>\r\n      <div class=\'paramtype\'><%= item.description %></div>\r\n    </li>\r\n  <% }); %>\r\n  </ul>\r\n<% } %>\r\n\r\n<% let methods = _.filter(things, function(item) { return item.itemtype === \'method\' && item.access !== \'private\' }); %>\r\n<% if (methods.length > 0) { %>\r\n  <h3 id=\'reference-methods\'>Methods</h3>\r\n  <ul aria-labelledby=\'reference-methods\'>\r\n    <% _.each(methods, function(item) { %>\r\n      <li>\r\n        <div class=\'paramname\'><a href="<%=item.hash%>" <% if (item.module !== module) { %>class="addon"<% } %>><%=item.name%><% if (item.itemtype === \'method\') { %>()<%}%></a></div>\r\n        <div class=\'paramtype\'><%= item.description %></div>\r\n      </li>\r\n    <% }); %>\r\n  </ul>\r\n<% } %>\r\n';});
             
             
            -define('text!tpl/itemEnd.html',[],function () { return '\n<br><br>\n\n<div>\n<% if (item.file && item.line) { %>\n<span id="reference-error1">Notice any errors or typos?</span> <a href="https://github.com/processing/p5.js/issues"><span id="reference-contribute2">Please let us know.</span></a> <span id="reference-error3">Please feel free to edit</span> <a href="https://github.com/processing/p5.js/blob/v<%= appVersion %>/<%= item.file %>#L<%= item.line %>" target="_blank" ><%= item.file %></a> <span id="reference-error5">and issue a pull request!</span>\n<% } %>\n</div>\n\n<a style="border-bottom:none !important;" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" target=_blank><img src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" style="width:88px" alt="creative commons logo"/></a>\n<br><br>\n';});
            +define('text!tpl/itemEnd.html',[],function () { return '\r\n<br><br>\r\n\r\n<div>\r\n<% if (item.file && item.line) { %>\r\n<span id="reference-error1">Notice any errors or typos?</span> <a href="https://github.com/processing/p5.js/issues"><span id="reference-contribute2">Please let us know.</span></a> <span id="reference-error3">Please feel free to edit</span> <a href="https://github.com/processing/p5.js/blob/v<%= appVersion %>/<%= item.file %>#L<%= item.line %>" target="_blank" ><%= item.file %></a> <span id="reference-error5">and issue a pull request!</span>\r\n<% } %>\r\n</div>\r\n\r\n<a style="border-bottom:none !important;" href="http://creativecommons.org/licenses/by-nc-sa/4.0/" target=_blank><img src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" style="width:88px" alt="creative commons logo"/></a>\r\n<br><br>\r\n';});
             
             // Copyright (C) 2006 Google Inc.
             //
            @@ -4335,7 +4335,7 @@ define('itemView',[
             });
             
             
            -define('text!tpl/menu.html',[],function () { return '<div>\n  <br>\n  <span id="reference-description1">Can\'t find what you\'re looking for? You may want to check out</span>\n  <a href="#/libraries/p5.sound">p5.sound</a>.<br><a href=\'https://p5js.org/offline-reference/p5-reference.zip\' target=_blank><span id="reference-description3">You can also download an offline version of the reference.</span></a>\n</div>\n\n<div id=\'collection-list-categories\'>\n<h2 class="sr-only" id="categories">Categories</h2>\n<% var i=0; %>\n<% var max=Math.floor(groups.length/4); %>\n<% var rem=groups.length%4; %>\n\n<% _.each(groups, function(group){ %>\n  <% var m = rem > 0 ? 1 : 0 %>\n  <% if (i === 0) { %>\n    <ul aria-labelledby="categories">\n    <% } %>\n    <li><a href="#group-<%=group%>"><%=group%></a></li>\n    <% if (i === (max+m-1)) { %>\n    </ul>\n  \t<% rem-- %>\n  \t<% i=0 %>\n  <% } else { %>\n  \t<% i++ %>\n  <% } %>\n<% }); %>\n</div>\n';});
            +define('text!tpl/menu.html',[],function () { return '<div>\r\n  <br>\r\n  <span id="reference-description1">Can\'t find what you\'re looking for? You may want to check out</span>\r\n  <a href="#/libraries/p5.sound">p5.sound</a>.<br><a href=\'https://p5js.org/offline-reference/p5-reference.zip\' target=_blank><span id="reference-description3">You can also download an offline version of the reference.</span></a>\r\n</div>\r\n\r\n<div id=\'collection-list-categories\'>\r\n<h2 class="sr-only" id="categories">Categories</h2>\r\n<% var i=0; %>\r\n<% var max=Math.floor(groups.length/4); %>\r\n<% var rem=groups.length%4; %>\r\n\r\n<% _.each(groups, function(group){ %>\r\n  <% var m = rem > 0 ? 1 : 0 %>\r\n  <% if (i === 0) { %>\r\n    <ul aria-labelledby="categories">\r\n    <% } %>\r\n    <li><a href="#group-<%=group%>"><%=group%></a></li>\r\n    <% if (i === (max+m-1)) { %>\r\n    </ul>\r\n  \t<% rem-- %>\r\n  \t<% i=0 %>\r\n  <% } else { %>\r\n  \t<% i++ %>\r\n  <% } %>\r\n<% }); %>\r\n</div>\r\n';});
             
             define('menuView',[
               'App',
            @@ -4404,7 +4404,7 @@ define('menuView',[
             });
             
             
            -define('text!tpl/library.html',[],function () { return '<h3><%= module.name %> library</h3>\n\n<p><%= module.description %></p>\n\n<div id="library-page" class="reference-group clearfix">  \n\n<% var t = 0; col = 0; %>\n\n<% _.each(groups, function(group){ %>\n  <% if (t == 0) { %> \n    <div class="column_<%=col%>">\n  <% } %>\n  <% if (group.name !== module.name && group.name !== \'p5\') { %>\n    <% if (group.hash) { %> <a href="<%=group.hash%>" <% if (group.module !== module.name) { %>class="core"<% } %>><% } %>  \n    <h2 class="group-name <% if (t == 0) { %> first<%}%>"><%=group.name%></h2>\n    <% if (group.hash) { %> </a><br> <% } %>\n  <% } %>\n  <% _.each(group.items.filter(function(item) {return item.access !== \'private\'}), function(item) { %>\n    <a href="<%=item.hash%>" <% if (item.module !== module.name) { %>class="core"<% } %>><%=item.name%><% if (item.itemtype === \'method\') { %>()<%}%></a><br>\n    <% t++; %>\n  <% }); %>\n  <% if (t >= Math.floor(totalItems/4)) { col++; t = 0; %>\n    </div>\n  <% } %>\n<% }); %>\n</div>\n';});
            +define('text!tpl/library.html',[],function () { return '<h3><%= module.name %> library</h3>\r\n\r\n<p><%= module.description %></p>\r\n\r\n<div id="library-page" class="reference-group clearfix">  \r\n\r\n<% var t = 0; col = 0; %>\r\n\r\n<% _.each(groups, function(group){ %>\r\n  <% if (t == 0) { %> \r\n    <div class="column_<%=col%>">\r\n  <% } %>\r\n  <% if (group.name !== module.name && group.name !== \'p5\') { %>\r\n    <% if (group.hash) { %> <a href="<%=group.hash%>" <% if (group.module !== module.name) { %>class="core"<% } %>><% } %>  \r\n    <h2 class="group-name <% if (t == 0) { %> first<%}%>"><%=group.name%></h2>\r\n    <% if (group.hash) { %> </a><br> <% } %>\r\n  <% } %>\r\n  <% _.each(group.items.filter(function(item) {return item.access !== \'private\'}), function(item) { %>\r\n    <a href="<%=item.hash%>" <% if (item.module !== module.name) { %>class="core"<% } %>><%=item.name%><% if (item.itemtype === \'method\') { %>()<%}%></a><br>\r\n    <% t++; %>\r\n  <% }); %>\r\n  <% if (t >= Math.floor(totalItems/4)) { col++; t = 0; %>\r\n    </div>\r\n  <% } %>\r\n<% }); %>\r\n</div>\r\n';});
             
             define(
               'libraryView',[
            diff --git a/src/data/data.yml b/src/data/data.yml
            index 3cfb1745e0..a47ed87baf 100644
            --- a/src/data/data.yml
            +++ b/src/data/data.yml
            @@ -1,2 +1,2 @@
             title: p5.js
            -version: 1.4.0
            +version: 1.4.1
            diff --git a/src/templates/pages/books/index.hbs b/src/templates/pages/books/index.hbs
            index 19863c7cbf..d2e6bde7e1 100644
            --- a/src/templates/pages/books/index.hbs
            +++ b/src/templates/pages/books/index.hbs
            @@ -161,8 +161,93 @@ slug: books/
             
                     </div>
                   </div>
            -      <br>
            +      
                   <div style='clear:both; height: 2em'></div>
            +
            +        <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/book.png" alt="book cover learn javascript">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>The joy of coding and creating shapes and movements in p5.js:BOOK 1</h2>
            +
            +                            <p>by happy coder </p>
            +                            <p>
            +                                Kindle Edition
            +                            </p>
            +
            +                            <p>$298</p>
            +
            +                            <p>Available instantly</p>
            +
            +                        </div>
            +                    </div>
            +                    <div style='clear:both; height: 2em'></div>
            +
            +                    <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/book2.png" alt="book cover learn javascript">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>Fun Art Projects in P5.js:for beginners</h2>
            +
            +                            <p>by Nazia Fakhrudin </p>
            +                            <p>
            +                                Kindle Edition
            +                            </p>
            +
            +                            <p>$0 Kindle unlimited</p>
            +                            <p>Free with kindle unlimited membership</p>
            +
            +                            <p>Available instantly</p>
            +
            +                        </div>
            +                    </div>
            +                    <div style='clear:both; height: 2em'></div>
            +
            +                    <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/book3.png" alt="book cover learn javascript">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>Creative coding and data visualization in P5.js</h2>
            +
            +                            <p>by Scott murray </p>
            +                            <p>
            +                                paperback
            +                            </p>
            +
            +                            <p>Currently unavailable</p>
            +
            +
            +                        </div>
            +                    </div>
            +                    <div style='clear:both; height: 2em'></div>
            +
            +                    <div>
            +                        <div class="narrow-left-column">
            +                            <img src="../assets/img/books/book4.png" alt="book cover learn javascript">
            +                        </div>
            +
            +                        <div class="wide-right-column book">
            +                            <h2>Superfun P5.js Projects:for beginners</h2>
            +
            +                            <p>by Nazia Fakhruddin </p>
            +                            <p>
            +                                Kindle Edition
            +                            </p>
            +
            +                            <p>$141</p>
            +
            +                            <p>Available instantly</p>
            +
            +                        </div>
            +                    </div>
            +                    <br>
            +                    <div style='clear:both; height: 2em'></div>
                 </main>
             
                 {{> footer}}